@diagrammo/dgmo 0.53.0 → 0.55.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 (212) hide show
  1. package/dist/advanced.d.ts +112 -9
  2. package/dist/advanced.js +188 -160
  3. package/dist/auto.js +147 -132
  4. package/dist/auto.mjs +2352 -746
  5. package/dist/block.js +65 -62
  6. package/dist/chart-meta.js +52 -49
  7. package/dist/{charts-d3-DH2XA45I.js → charts-d3-KZ6V4OP2.js} +10 -8
  8. package/dist/chunk-2CW5ZTNH.js +58 -0
  9. package/dist/{chunk-MA3HJZHB.js → chunk-2HX6ZGY7.js} +7 -7
  10. package/dist/{chunk-YG2BEIQU.js → chunk-2R6HG6D5.js} +11 -11
  11. package/dist/{chunk-65V6IRFN.js → chunk-2ZJXKJSI.js} +106 -60
  12. package/dist/{chunk-PYO4TJJ3.js → chunk-32HUNA33.js} +60 -18
  13. package/dist/{chunk-UK6DKJLD.js → chunk-3BFXELBL.js} +51 -4
  14. package/dist/{chunk-RW5PEJ7D.js → chunk-3BZJ5KD5.js} +7 -3
  15. package/dist/{chunk-FT7TPPZ5.js → chunk-3FUTFYSP.js} +65 -26
  16. package/dist/{chunk-QAALSCKI.js → chunk-4MZCJV4M.js} +12 -12
  17. package/dist/{chunk-ZXUAPTCK.js → chunk-4R5KIPNX.js} +2 -2
  18. package/dist/{chunk-QWIBT6DS.js → chunk-5D5VHDJM.js} +49 -14
  19. package/dist/{chunk-U7NKYLX2.js → chunk-5H5GWWA4.js} +55 -19
  20. package/dist/{chunk-P3H7QVDH.js → chunk-5K5XBEXT.js} +11 -6
  21. package/dist/{chunk-PT4SW76W.js → chunk-6NJWBMJV.js} +49 -14
  22. package/dist/{chunk-I46X5VUA.js → chunk-7TF3QOOD.js} +25 -1
  23. package/dist/{chunk-6DCOIN4W.js → chunk-A2ARDILY.js} +783 -3
  24. package/dist/{chunk-CK2GMDXD.js → chunk-A2PTRSAO.js} +2 -2
  25. package/dist/{chunk-APKUAJ2L.js → chunk-A2RUBBVT.js} +14 -1
  26. package/dist/{chunk-GMIJ35PW.js → chunk-A4UJP4IS.js} +68 -20
  27. package/dist/{chunk-LQHVDZYC.js → chunk-AKE6C2D7.js} +4 -4
  28. package/dist/{chunk-W5KMNC5U.js → chunk-ASPS5O6F.js} +9 -10
  29. package/dist/{chunk-FLDC7ZAK.js → chunk-AU75JHSR.js} +6 -3
  30. package/dist/chunk-BEOAKGNA.js +484 -0
  31. package/dist/{chunk-XY3UDKKH.js → chunk-COVYNAKJ.js} +4 -4
  32. package/dist/{chunk-4ASVFYB2.js → chunk-DS4MDEQ7.js} +5 -5
  33. package/dist/{chunk-7JDTNFAK.js → chunk-EFUQENO5.js} +76 -32
  34. package/dist/{chunk-BULHGPHK.js → chunk-EMSOFHEN.js} +2 -2
  35. package/dist/{chunk-3BEKKRH5.js → chunk-ETTDF3S2.js} +49 -11
  36. package/dist/{chunk-JHOAH4TI.js → chunk-ETYF5QZR.js} +2 -2
  37. package/dist/{chunk-AHXIMHDQ.js → chunk-F5ZNUMSY.js} +53 -14
  38. package/dist/{chunk-I64ECJX3.js → chunk-FBP33UM6.js} +3 -3
  39. package/dist/{chunk-VIRANCNY.js → chunk-FGAMFJNJ.js} +58 -20
  40. package/dist/{chunk-774C2FF3.js → chunk-GRXPFBYC.js} +24 -3
  41. package/dist/{chunk-NNYFQOTK.js → chunk-GTO5VCYG.js} +10 -8
  42. package/dist/{chunk-RJ5LBZ5U.js → chunk-HES4K6DV.js} +13 -13
  43. package/dist/{chunk-AZNXGWDC.js → chunk-HGKOVKAX.js} +7 -7
  44. package/dist/{chunk-DWUMPMV2.js → chunk-HLGOG44K.js} +2 -2
  45. package/dist/{chunk-VJHBSPGF.js → chunk-HUTP35XT.js} +5 -4
  46. package/dist/{chunk-3CZLWOCI.js → chunk-HX7QNHC6.js} +3 -3
  47. package/dist/{chunk-R5NH5BZG.js → chunk-IALX52TR.js} +6 -6
  48. package/dist/{chunk-A44USUV7.js → chunk-ICZ7M6IZ.js} +23 -17
  49. package/dist/{chunk-27STWBOK.js → chunk-IF4KYSJZ.js} +10 -8
  50. package/dist/{chunk-HORZ5H2L.js → chunk-IG6J7JWH.js} +61 -22
  51. package/dist/{chunk-VRRDUYOK.js → chunk-IIUYKQ5J.js} +3 -3
  52. package/dist/{chunk-GMAH572Z.js → chunk-INTAQV2Y.js} +2 -2
  53. package/dist/{chunk-6AUZPPAV.js → chunk-ITXL2KU5.js} +2 -2
  54. package/dist/{chunk-KKHCNSKK.js → chunk-IWG2ECAO.js} +5 -5
  55. package/dist/{chunk-GQ644SPD.js → chunk-JGCEFKZP.js} +14 -14
  56. package/dist/{chunk-HNBY6CNV.js → chunk-JQLSFZZP.js} +2 -2
  57. package/dist/{chunk-CMVZWP32.js → chunk-JR7Q6GHE.js} +2 -2
  58. package/dist/{chunk-LHILKFDP.js → chunk-KC3WBBI7.js} +9 -9
  59. package/dist/{chunk-GABSL6TH.js → chunk-KK3L5NVK.js} +3 -3
  60. package/dist/{chunk-LC3FFD43.js → chunk-L2DIXZUT.js} +98 -48
  61. package/dist/{chunk-4WGMGKCZ.js → chunk-LCRPGGGS.js} +11 -11
  62. package/dist/{chunk-6KY7OCZC.js → chunk-LKGQ46P4.js} +3 -3
  63. package/dist/{chunk-HE5J53SZ.js → chunk-LW7STMYZ.js} +3 -3
  64. package/dist/{chunk-BD3WGY4T.js → chunk-M53MDBIW.js} +2 -2
  65. package/dist/{chunk-AN2DQB3G.js → chunk-MEH4TJEX.js} +12 -12
  66. package/dist/{chunk-SGPFVDUL.js → chunk-MNS2ENXF.js} +6 -6
  67. package/dist/{chunk-FXCB7H5O.js → chunk-MSWIBF6J.js} +2 -2
  68. package/dist/{chunk-BR7AYN76.js → chunk-NL7FUIVD.js} +12 -12
  69. package/dist/{chunk-AIMLCDAO.js → chunk-NN5TF4OV.js} +2 -2
  70. package/dist/{chunk-7GUF6SDR.js → chunk-NPPUZ4SK.js} +9 -9
  71. package/dist/{chunk-4K42RUGC.js → chunk-NYOOPQFD.js} +47 -12
  72. package/dist/{chunk-FFXCKZOU.js → chunk-O4CZDTQA.js} +3 -3
  73. package/dist/{chunk-6HTRCTAS.js → chunk-P5XXIVEU.js} +6 -4
  74. package/dist/{chunk-XEAQDIMF.js → chunk-PC4YLEKA.js} +6 -6
  75. package/dist/{chunk-Q7AH665U.js → chunk-PCVXXPYU.js} +121 -38
  76. package/dist/{chunk-W2DINCHL.js → chunk-PKUWYPI5.js} +207 -24
  77. package/dist/{chunk-PV2QO7QL.js → chunk-PSIDVCBA.js} +2 -2
  78. package/dist/{chunk-YR43LJT5.js → chunk-PV7ND5WL.js} +58 -15
  79. package/dist/{chunk-QI3BOLQB.js → chunk-Q5CMQVWF.js} +4 -4
  80. package/dist/{chunk-4RGZFA7H.js → chunk-Q5IHQ4NW.js} +11 -1
  81. package/dist/{chunk-SG4PRYO3.js → chunk-QQXFYTLC.js} +391 -60
  82. package/dist/{chunk-GWQJKTFS.js → chunk-QZYGRDMM.js} +118 -99
  83. package/dist/{chunk-CQFNIIQN.js → chunk-RKBCKCSF.js} +2 -2
  84. package/dist/{chunk-FUKNRLIJ.js → chunk-RSBH2C7O.js} +6 -6
  85. package/dist/{chunk-2QC4HXCY.js → chunk-RYNCWA5X.js} +11 -10
  86. package/dist/{chunk-NNUMX6WX.js → chunk-RZWIPDZ2.js} +40 -15
  87. package/dist/{chunk-VKNCC2GX.js → chunk-S52F62GW.js} +13 -13
  88. package/dist/{chunk-UQRIKAMH.js → chunk-SCOHNGPG.js} +59 -18
  89. package/dist/{chunk-VGNIDAPQ.js → chunk-SSHS42QG.js} +4 -4
  90. package/dist/chunk-TGOMHUOV.js +218 -0
  91. package/dist/{chunk-UKP5HWB5.js → chunk-UBQU2BY6.js} +4 -4
  92. package/dist/{chunk-IQJCVREL.js → chunk-UES4P7FN.js} +6 -6
  93. package/dist/chunk-US3P2DQO.js +87 -0
  94. package/dist/{chunk-GAWKIIPO.js → chunk-UXXLE6AH.js} +8 -8
  95. package/dist/{chunk-22OQWBWD.js → chunk-VMWSZCAK.js} +12 -11
  96. package/dist/{chunk-XG4NWFPY.js → chunk-VVIRAGID.js} +13 -13
  97. package/dist/{chunk-X3RXGSCZ.js → chunk-VXTUWXFB.js} +54 -15
  98. package/dist/{chunk-J7HI6G3G.js → chunk-W4TSD3IP.js} +6 -6
  99. package/dist/{chunk-FGDSTT3F.js → chunk-WB3NA3JJ.js} +2 -2
  100. package/dist/{chunk-KUSAVOWZ.js → chunk-WITOJZGL.js} +8 -4
  101. package/dist/{chunk-UVDCHR4E.js → chunk-WVGNXDEE.js} +2 -2
  102. package/dist/{chunk-HOXKNRON.js → chunk-X3X4LZDC.js} +2 -2
  103. package/dist/{chunk-SQCBSFT5.js → chunk-XKKH2DPG.js} +51 -263
  104. package/dist/{chunk-NR5HCAUD.js → chunk-XSVWUOUZ.js} +1 -1
  105. package/dist/{chunk-BFDVEO5R.js → chunk-Y4BBGFKY.js} +2 -2
  106. package/dist/{chunk-VAO6ANGC.js → chunk-YP2T5YUP.js} +14 -9
  107. package/dist/{chunk-PKNNHU7H.js → chunk-YXKNXIWA.js} +19 -11
  108. package/dist/{chunk-UFQJMOVZ.js → chunk-ZGIBV36U.js} +6 -6
  109. package/dist/{chunk-XQ4KN6JQ.js → chunk-ZP265ICS.js} +16 -15
  110. package/dist/{chunk-JTMSWEIW.js → chunk-ZWVKTWK6.js} +4 -4
  111. package/dist/{chunk-ALYZ3MAA.js → chunk-ZXNHHO6D.js} +8 -476
  112. package/dist/cli.cjs +166 -149
  113. package/dist/clock.js +34 -1
  114. package/dist/completion-registry.d.ts +129 -0
  115. package/dist/completion-registry.js +1278 -0
  116. package/dist/{compute-G55RG53N.js → compute-JAP5E2E4.js} +2 -2
  117. package/dist/dgmo-router-T4HGLIGA.js +88 -0
  118. package/dist/{dimensions-K6PGYYGT.js → dimensions-3JINHSYK.js} +8 -8
  119. package/dist/editor.js +28 -1
  120. package/dist/element.js +148 -133
  121. package/dist/element.mjs +2352 -746
  122. package/dist/{flowchart-parser-LALR6J6F.js → flowchart-parser-M7KKTLX7.js} +5 -5
  123. package/dist/{flowchart-renderer-DXYB5YRF.js → flowchart-renderer-FFEQFQEU.js} +9 -9
  124. package/dist/highlight.js +28 -1
  125. package/dist/index.js +77 -64
  126. package/dist/{layout-ZE5DRJWX.js → layout-3ZZBKUQC.js} +4 -4
  127. package/dist/{layout-3BVDMKXI.js → layout-AUKTWGYL.js} +4 -4
  128. package/dist/{layout-4IHCMWZN.js → layout-CRLTSFYQ.js} +4 -4
  129. package/dist/{layout-WCAIKGZG.js → layout-FNZDJGKF.js} +5 -5
  130. package/dist/layout-GHWRJKZQ.js +15 -0
  131. package/dist/{layout-3V2A4MUE.js → layout-LGXOKUCD.js} +6 -5
  132. package/dist/{layout-WSMPBQ4Q.js → layout-NF4EWFLT.js} +3 -3
  133. package/dist/{layout-OL2XFJXA.js → layout-SP7HJWKA.js} +3 -3
  134. package/dist/{layout-E6HR6PXH.js → layout-UR7CYAHL.js} +3 -3
  135. package/dist/layout-UTMEVFHN.js +15 -0
  136. package/dist/{layout-search-34DPZD43.js → layout-search-U2H4ORFJ.js} +14 -7
  137. package/dist/{legend-constants-P5EQWRQQ.js → legend-constants-B77VKB3R.js} +7 -2
  138. package/dist/{parser-6PPHAXXH.js → parser-2AXPSKWB.js} +5 -5
  139. package/dist/{parser-5HQXCNOS.js → parser-2AZ2KQTO.js} +4 -4
  140. package/dist/{parser-3KIGEEJM.js → parser-2LF33IS2.js} +4 -4
  141. package/dist/{parser-NNIL3HXU.js → parser-3QJ2Z4H4.js} +3 -3
  142. package/dist/parser-5GCQFSTQ.js +13 -0
  143. package/dist/{parser-6B6SSZT7.js → parser-62OHBRU5.js} +3 -3
  144. package/dist/{parser-VOERD6XR.js → parser-7LYJFZCP.js} +4 -4
  145. package/dist/{parser-ZGNXYFPS.js → parser-BMOTF72G.js} +3 -3
  146. package/dist/{parser-IVGHXLZP.js → parser-CIFLYZYP.js} +4 -3
  147. package/dist/{parser-GN2MM5CC.js → parser-D2UL2G5U.js} +3 -3
  148. package/dist/{parser-GKP2MHHL.js → parser-DM2APTKB.js} +3 -3
  149. package/dist/{parser-27Z76SN3.js → parser-DYYTPLBL.js} +4 -4
  150. package/dist/{parser-5FGJSQNS.js → parser-GOUGUTPU.js} +4 -4
  151. package/dist/{parser-G26MTBFS.js → parser-HGVUVD6J.js} +3 -3
  152. package/dist/{parser-EXNBDNGY.js → parser-IEJD3CZB.js} +3 -3
  153. package/dist/{parser-ZQDQTB4X.js → parser-JBEWNLAV.js} +5 -5
  154. package/dist/{parser-5QPFOB5F.js → parser-JMXPHNZD.js} +4 -4
  155. package/dist/{parser-4E4I3GNT.js → parser-JMXSQY3K.js} +4 -4
  156. package/dist/{parser-FF4BMRSB.js → parser-LUXS7J32.js} +4 -4
  157. package/dist/{parser-3VSWEKBF.js → parser-M5BUHULF.js} +4 -4
  158. package/dist/{parser-IKWK2ZU3.js → parser-MESRHUS4.js} +4 -5
  159. package/dist/{parser-3CODK6RG.js → parser-OOYNI2UT.js} +4 -4
  160. package/dist/{parser-YSLNDFLV.js → parser-PVBUAVRR.js} +4 -5
  161. package/dist/{parser-CKA3QMAG.js → parser-QKRBSQLJ.js} +5 -5
  162. package/dist/{parser-UWRX52PC.js → parser-S6NWSIJO.js} +4 -4
  163. package/dist/{parser-RNLTBIJ6.js → parser-SFEK6Q7Z.js} +4 -4
  164. package/dist/{parser-7JVIDLLR.js → parser-SUV52NQW.js} +4 -4
  165. package/dist/{parser-CRKLXGW7.js → parser-SZHGLOOZ.js} +4 -4
  166. package/dist/{parser-275KP7JO.js → parser-TO7IENWL.js} +5 -6
  167. package/dist/{parser-XNKJCMMA.js → parser-TVAMC7CQ.js} +4 -4
  168. package/dist/{parser-FOOFEJQU.js → parser-VAW46R57.js} +4 -4
  169. package/dist/{parser-XVPTRWZ4.js → parser-XDSPOXSE.js} +4 -4
  170. package/dist/pert.d.ts +2 -0
  171. package/dist/{renderer-D3BRNOMV.js → renderer-3PWLOJPD.js} +11 -11
  172. package/dist/{renderer-7NQSTQMQ.js → renderer-5EMHIQL5.js} +4 -4
  173. package/dist/{renderer-ZBTEX2JK.js → renderer-5PODNLYP.js} +4 -4
  174. package/dist/{renderer-6WRYVM5R.js → renderer-AQJIQ2XU.js} +9 -8
  175. package/dist/{renderer-JCZG6AYU.js → renderer-BEW3AYFT.js} +10 -10
  176. package/dist/{renderer-YUKPS27O.js → renderer-C3UYAXA6.js} +10 -8
  177. package/dist/{renderer-AK2WO4EI.js → renderer-CENXCMWG.js} +4 -4
  178. package/dist/{renderer-HIFQVEJA.js → renderer-CXM3ARYN.js} +10 -9
  179. package/dist/{renderer-JTCX6PCG.js → renderer-DW6TEBLA.js} +10 -9
  180. package/dist/{renderer-VMH6L6CP.js → renderer-FE5M6SEZ.js} +10 -9
  181. package/dist/{renderer-TYHGXAVT.js → renderer-FXK6ZL3P.js} +4 -4
  182. package/dist/{renderer-UPF7NRTI.js → renderer-G5ESLCJB.js} +12 -11
  183. package/dist/{renderer-CWEFGEIC.js → renderer-HTDS4FED.js} +14 -13
  184. package/dist/{renderer-XTXSOK3L.js → renderer-IO4KCFVL.js} +10 -10
  185. package/dist/{renderer-SQ54MDSA.js → renderer-IRAFJNTK.js} +10 -9
  186. package/dist/{renderer-JWGQSTMR.js → renderer-MFTTFW32.js} +15 -14
  187. package/dist/{renderer-2C6DJRYN.js → renderer-MPXI4FVL.js} +8 -8
  188. package/dist/{renderer-5MPN7CXZ.js → renderer-NVBEMQ6L.js} +5 -5
  189. package/dist/{renderer-7ZNVOVFG.js → renderer-OOGDCR6K.js} +3 -3
  190. package/dist/{renderer-COLQFSFV.js → renderer-Q5P72O4A.js} +9 -9
  191. package/dist/{renderer-WCWI4I6A.js → renderer-QZESC66H.js} +2 -2
  192. package/dist/{renderer-NE5W7CQP.js → renderer-RDBUXW7P.js} +6 -5
  193. package/dist/{renderer-6EN5XXJZ.js → renderer-S4XB3JR2.js} +11 -11
  194. package/dist/{renderer-WFSUBKUL.js → renderer-SIWEEWJ5.js} +9 -8
  195. package/dist/{renderer-LVZAHRP6.js → renderer-TKTM2SL4.js} +12 -12
  196. package/dist/{renderer-QD2SJF2I.js → renderer-TXTTV4HA.js} +10 -9
  197. package/dist/{renderer-YUXGXGSW.js → renderer-UZIU4AHK.js} +10 -9
  198. package/dist/{renderer-RLMOTXZ6.js → renderer-V72VJIGG.js} +14 -13
  199. package/dist/{renderer-UKXW2QPE.js → renderer-VEGOEZOI.js} +10 -8
  200. package/dist/{renderer-WNFXYYGL.js → renderer-W6I6T2TA.js} +8 -8
  201. package/dist/{renderer-KARQF3F3.js → renderer-WSHJRR2T.js} +8 -8
  202. package/dist/{renderer-radial-WF6VOUOD.js → renderer-radial-AG75PBYD.js} +9 -9
  203. package/dist/{resolver-WFKZYBJ2.js → resolver-ZSFQQRTH.js} +3 -3
  204. package/dist/{state-parser-L7DHZIQO.js → state-parser-KIPZGIB4.js} +5 -5
  205. package/dist/{state-renderer-TFEUOP4H.js → state-renderer-U6OSJG52.js} +13 -12
  206. package/docs/language-reference.md +2 -1
  207. package/package.json +5 -1
  208. package/dist/chunk-YJVA3QUU.js +0 -734
  209. package/dist/dgmo-router-B4S23EBH.js +0 -86
  210. package/dist/layout-3M5UYJHY.js +0 -14
  211. package/dist/layout-KPQWJNAG.js +0 -14
  212. package/dist/parser-7JHWEWXM.js +0 -13
@@ -1,12 +1,18 @@
1
1
  import {
2
+ isEmphasisToken,
3
+ parseEmphasisDirective
4
+ } from "./chunk-2CW5ZTNH.js";
5
+ import {
6
+ GLOBAL_BOOLEANS,
2
7
  collectIndentedValues,
8
+ detectBadChartTypeDeclaration,
3
9
  extractColor,
4
10
  fillModeFromToken,
5
11
  measureIndent,
6
12
  normalizeNumericToken,
7
13
  parseFirstLine,
8
14
  parseSeriesNames
9
- } from "./chunk-YJVA3QUU.js";
15
+ } from "./chunk-A2ARDILY.js";
10
16
  import {
11
17
  RECOGNIZED_COLOR_NAMES,
12
18
  resolveColorWithDiagnostic
@@ -51,10 +57,16 @@ var KNOWN_BOOLEANS = /* @__PURE__ */ new Set([
51
57
  "fill-outline",
52
58
  "no-title",
53
59
  "no-legend",
60
+ "legend-inline",
54
61
  "no-auto-y",
55
62
  "fill",
56
63
  "hole"
57
64
  ]);
65
+ var KNOWN_FIRST_TOKENS = /* @__PURE__ */ new Set([
66
+ ...KNOWN_OPTIONS,
67
+ ...KNOWN_BOOLEANS,
68
+ ...GLOBAL_BOOLEANS
69
+ ]);
58
70
  function rejectSeriesHeader(result, keyword, lineNumber) {
59
71
  if (result.type === "bar" && keyword === "series") {
60
72
  const diag = makeDgmoError(
@@ -141,9 +153,13 @@ function parseChart(content, palette) {
141
153
  return fail(lineNumber, msg2);
142
154
  }
143
155
  }
144
- if (!trimmed.includes(" ") && !trimmed.includes(":") && !/\d/.test(trimmed)) {
145
- let msg2 = `Unsupported chart type: ${trimmed}. Supported types: ${[...VALID_TYPES].join(", ")}.`;
146
- const hint2 = suggest(trimmed.toLowerCase(), [...VALID_TYPES]);
156
+ const badType = detectBadChartTypeDeclaration(
157
+ trimmed,
158
+ KNOWN_FIRST_TOKENS
159
+ );
160
+ if (badType) {
161
+ let msg2 = `Unsupported chart type: ${badType}. Supported types: ${[...VALID_TYPES].join(", ")}.`;
162
+ const hint2 = suggest(badType.toLowerCase(), [...VALID_TYPES]);
147
163
  if (hint2) msg2 += ` ${hint2}`;
148
164
  return fail(lineNumber, msg2);
149
165
  }
@@ -187,6 +203,8 @@ function parseChart(content, palette) {
187
203
  result.noTitle = true;
188
204
  } else if (firstToken === "no-legend") {
189
205
  result.noLegend = true;
206
+ } else if (firstToken === "legend-inline") {
207
+ result.legendInline = true;
190
208
  } else if (firstToken === "no-auto-y") {
191
209
  result.noAutoY = true;
192
210
  } else if (firstToken === "fill") {
@@ -329,6 +347,14 @@ function parseChart(content, palette) {
329
347
  ...multiValue && { expectedValues: seriesCount }
330
348
  });
331
349
  if (dataValues) {
350
+ if (multiValue) {
351
+ const surplus = surplusValueDiagnostic(
352
+ dataValues,
353
+ seriesCount,
354
+ lineNumber
355
+ );
356
+ if (surplus) result.diagnostics.push(surplus);
357
+ }
332
358
  const { label: rawLabel, color: pointColor } = extractColor(
333
359
  dataValues.label,
334
360
  palette,
@@ -420,32 +446,72 @@ function parseChart(content, palette) {
420
446
  return result;
421
447
  }
422
448
  function parseDataRowValues(line, options) {
449
+ const quoted = line.match(/^(["'])(.*?)\1\s+(\S.*)$/);
450
+ if (quoted) {
451
+ const label2 = quoted[2].trim();
452
+ if (!label2) return null;
453
+ const valueTokens = quoted[3].trim().split(/\s+/);
454
+ const numeric2 = trailingNumerics(valueTokens, 0);
455
+ if (numeric2.length !== valueTokens.length) return null;
456
+ const limit = options?.multiValue ? options.expectedValues ?? Infinity : 1;
457
+ return {
458
+ label: label2,
459
+ values: numeric2.slice(0, limit),
460
+ bareLabel: label2,
461
+ trailingNumericCount: numeric2.length,
462
+ quotedLabel: true
463
+ };
464
+ }
423
465
  const tokens = line.split(/\s+/);
424
466
  if (tokens.length < 2) return null;
467
+ const numeric = trailingNumerics(tokens, 1);
468
+ if (numeric.length === 0) return null;
469
+ const bareLabel = tokens.slice(0, tokens.length - numeric.length).join(" ");
425
470
  if (options?.multiValue) {
426
471
  const limit = options.expectedValues ?? Infinity;
427
- const values = [];
428
- let idx = tokens.length - 1;
429
- while (idx >= 1 && values.length < limit) {
430
- const tok = tokens[idx];
431
- const normTok = normalizeNumericToken(tok) ?? tok;
432
- const num2 = parseFloat(normTok);
433
- if (isNaN(num2) || !isFinite(Number(normTok))) break;
434
- values.unshift(num2);
435
- idx--;
436
- }
437
- if (values.length === 0) return null;
438
- const label2 = tokens.slice(0, idx + 1).join(" ");
472
+ const take = Math.min(numeric.length, limit);
473
+ const values = numeric.slice(numeric.length - take);
474
+ const label2 = tokens.slice(0, tokens.length - take).join(" ");
439
475
  if (!label2) return null;
440
- return { label: label2, values };
476
+ return {
477
+ label: label2,
478
+ values,
479
+ bareLabel,
480
+ trailingNumericCount: numeric.length,
481
+ quotedLabel: false
482
+ };
441
483
  }
442
- const lastToken = tokens[tokens.length - 1];
443
- const normalizedLast = normalizeNumericToken(lastToken) ?? lastToken;
444
- const num = parseFloat(normalizedLast);
445
- if (isNaN(num) || !isFinite(Number(normalizedLast))) return null;
446
484
  const label = tokens.slice(0, -1).join(" ");
447
485
  if (!label) return null;
448
- return { label, values: [num] };
486
+ return {
487
+ label,
488
+ // numeric.length >= 1 by the guard above.
489
+ values: [numeric[numeric.length - 1]],
490
+ bareLabel,
491
+ trailingNumericCount: numeric.length,
492
+ quotedLabel: false
493
+ };
494
+ }
495
+ function surplusValueDiagnostic(row, expectedValues, lineNumber) {
496
+ if (row.quotedLabel || row.trailingNumericCount <= expectedValues)
497
+ return null;
498
+ const expectation = expectedValues === 1 ? "but only 1 value is expected" : `but ${expectedValues} series defined`;
499
+ return makeDgmoError(
500
+ lineNumber,
501
+ `Data point "${row.bareLabel}" has ${row.trailingNumericCount} value(s), ${expectation}. If the label ends in a number, quote it: "${row.label}" ${row.values.join(" ")}`,
502
+ "warning"
503
+ );
504
+ }
505
+ function trailingNumerics(tokens, minIndex) {
506
+ const values = [];
507
+ for (let idx = tokens.length - 1; idx >= minIndex; idx--) {
508
+ const tok = tokens[idx];
509
+ const normTok = normalizeNumericToken(tok) ?? tok;
510
+ const num = parseFloat(normTok);
511
+ if (isNaN(num) || !isFinite(Number(normTok))) break;
512
+ values.unshift(num);
513
+ }
514
+ return values;
449
515
  }
450
516
 
451
517
  // src/data-chart-parser.ts
@@ -470,7 +536,13 @@ var KNOWN_EXTENDED_OPTIONS = /* @__PURE__ */ new Set([
470
536
  "no-percent",
471
537
  "columns",
472
538
  "rows",
473
- "x"
539
+ "x",
540
+ "highlight",
541
+ "dim"
542
+ ]);
543
+ var KNOWN_EXTENDED_FIRST_TOKENS = /* @__PURE__ */ new Set([
544
+ ...KNOWN_EXTENDED_OPTIONS,
545
+ ...GLOBAL_BOOLEANS
474
546
  ]);
475
547
  function parseScatterRow(line, palette, currentCategory, lineNumber, diagnostics) {
476
548
  const dataRow = parseDataRowValues(line, { multiValue: true });
@@ -594,10 +666,14 @@ function parseExtendedChartFull(content, palette) {
594
666
  return result;
595
667
  }
596
668
  }
597
- if (!trimmed.includes(" ") && !trimmed.includes(":") && !/\d/.test(trimmed)) {
669
+ const badType = detectBadChartTypeDeclaration(
670
+ trimmed,
671
+ KNOWN_EXTENDED_FIRST_TOKENS
672
+ );
673
+ if (badType) {
598
674
  const validTypes = [...VALID_EXTENDED_TYPES];
599
- let msg = `Unsupported chart type: ${trimmed}. Supported types: ${validTypes.join(", ")}.`;
600
- const hint = suggest(trimmed.toLowerCase(), validTypes);
675
+ let msg = `Unsupported chart type: ${badType}. Supported types: ${validTypes.join(", ")}.`;
676
+ const hint = suggest(badType.toLowerCase(), validTypes);
601
677
  if (hint) msg += ` ${hint}`;
602
678
  const diag = makeDgmoError(lineNumber, msg);
603
679
  result.diagnostics.push(diag);
@@ -625,7 +701,7 @@ function parseExtendedChartFull(content, palette) {
625
701
  continue;
626
702
  }
627
703
  const arrowMatch = trimmed.match(
628
- /^(.+?)\s*(->|--)\s*(.+?)\s+(-?[\d_]+(?:\.[\d]+)?)(?:\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white))?\s*$/
704
+ /^(.+?)\s*(->|--)\s*(.+?)\s+(-?[\d,_]+(?:\.[\d]+)?)(?:\s+([A-Za-z][A-Za-z0-9_-]*))?\s*$/
629
705
  );
630
706
  if (arrowMatch) {
631
707
  const [, rawSource, arrow, rawTarget, rawVal, rawLinkColor] = arrowMatch;
@@ -674,12 +750,9 @@ function parseExtendedChartFull(content, palette) {
674
750
  }
675
751
  if (sankeyStack.length > 0) {
676
752
  const valColorMatch = trimmed.match(
677
- /(-?[\d_]+(?:\.[\d]+)?)\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white)\s*$/
753
+ /(-?[\d,_]+(?:\.[\d]+)?)\s+([A-Za-z][A-Za-z0-9_-]*)\s*$/
678
754
  );
679
- const strippedLine = valColorMatch ? trimmed.replace(
680
- /\s+(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white)\s*$/,
681
- ""
682
- ) : trimmed;
755
+ const strippedLine = valColorMatch ? trimmed.replace(/\s+[A-Za-z][A-Za-z0-9_-]*\s*$/, "") : trimmed;
683
756
  const dataRow2 = parseDataRowValues(strippedLine);
684
757
  if (dataRow2?.values.length === 1) {
685
758
  const source = sankeyStack.at(-1).name;
@@ -717,11 +790,12 @@ function parseExtendedChartFull(content, palette) {
717
790
  const spaceIdx2 = trimmed.indexOf(" ");
718
791
  const lastTok = trimmed.substring(trimmed.lastIndexOf(" ") + 1);
719
792
  const hasNumericSuffix = spaceIdx2 >= 0 && !isNaN(parseFloat(normalizeNumericToken(lastTok) ?? lastTok));
720
- const isBareKeywordOption = spaceIdx2 < 0 && /^(fill-tint|fill-solid|fill-outline|no-name|no-value|no-percent|shade|no-title)$/i.test(
793
+ const isBareKeywordOption = spaceIdx2 < 0 && /^(fill|fill-tint|fill-solid|fill-outline|no-name|no-value|no-percent|no-title)$/i.test(
721
794
  trimmed
722
795
  );
723
- const isLayoutDirective = spaceIdx2 >= 0 && trimmed.substring(0, spaceIdx2).toLowerCase() === "layout";
724
- if (!hasNumericSuffix && !isBareKeywordOption && !isLayoutDirective) {
796
+ const leadToken = spaceIdx2 >= 0 ? trimmed.substring(0, spaceIdx2).toLowerCase() : "";
797
+ const isValuedDirective = spaceIdx2 >= 0 && (leadToken === "layout" || isEmphasisToken(leadToken));
798
+ if (!hasNumericSuffix && !isBareKeywordOption && !isValuedDirective) {
725
799
  while (sankeyStack.length && sankeyStack.at(-1).indent >= indent) {
726
800
  sankeyStack.pop();
727
801
  }
@@ -760,6 +834,11 @@ function parseExtendedChartFull(content, palette) {
760
834
  }
761
835
  continue;
762
836
  }
837
+ if (isEmphasisToken(firstToken)) {
838
+ const directive = parseEmphasisDirective(trimmed, lineNumber);
839
+ if (directive) result.emphasis = directive;
840
+ continue;
841
+ }
763
842
  if (firstToken === "title") {
764
843
  result.diagnostics.push(emit(TITLE_DIRECTIVE_DX, lineNumber));
765
844
  continue;
@@ -843,8 +922,8 @@ function parseExtendedChartFull(content, palette) {
843
922
  result.noPercent = true;
844
923
  continue;
845
924
  }
846
- if (firstToken === "shade") {
847
- result.shade = true;
925
+ if (firstToken === "fill" && spaceIdx < 0) {
926
+ result.fill = true;
848
927
  continue;
849
928
  }
850
929
  const fillFamily = fillModeFromToken(firstToken);
@@ -861,6 +940,10 @@ function parseExtendedChartFull(content, palette) {
861
940
  result.noLegend = true;
862
941
  continue;
863
942
  }
943
+ if (firstToken === "legend-inline" && spaceIdx < 0) {
944
+ result.legendInline = true;
945
+ continue;
946
+ }
864
947
  if (firstToken.startsWith("no-") && spaceIdx < 0) {
865
948
  continue;
866
949
  }
@@ -1071,4 +1154,4 @@ export {
1071
1154
  getSimpleChartLegendGroups,
1072
1155
  getExtendedChartLegendGroups
1073
1156
  };
1074
- //# sourceMappingURL=chunk-Q7AH665U.js.map
1157
+ //# sourceMappingURL=chunk-PCVXXPYU.js.map
@@ -1,12 +1,9 @@
1
- import {
2
- renderInlineText
3
- } from "./chunk-3HDBAXF5.js";
4
- import {
5
- wrapDescriptionLines
6
- } from "./chunk-BMR4CIEO.js";
7
1
  import {
8
2
  renderNodeCard
9
3
  } from "./chunk-H3HFC3SQ.js";
4
+ import {
5
+ renderInlineText
6
+ } from "./chunk-3HDBAXF5.js";
10
7
  import {
11
8
  CARD_RADIUS,
12
9
  HEADER_HEIGHT,
@@ -14,12 +11,21 @@ import {
14
11
  NODE_STROKE_WIDTH,
15
12
  SEPARATOR_GAP
16
13
  } from "./chunk-3CIOJ5YJ.js";
14
+ import {
15
+ wrapDescriptionLines
16
+ } from "./chunk-BMR4CIEO.js";
17
17
  import {
18
18
  formatDateLabel
19
- } from "./chunk-XQ4KN6JQ.js";
19
+ } from "./chunk-ZP265ICS.js";
20
+ import {
21
+ layoutInlineHeader
22
+ } from "./chunk-US3P2DQO.js";
20
23
  import {
21
24
  renderIntegratedLegend
22
- } from "./chunk-W5KMNC5U.js";
25
+ } from "./chunk-ASPS5O6F.js";
26
+ import {
27
+ getLegendExtent
28
+ } from "./chunk-GRXPFBYC.js";
23
29
  import {
24
30
  TITLE_FONT_SIZE,
25
31
  TITLE_FONT_WEIGHT,
@@ -28,6 +34,13 @@ import {
28
34
  import {
29
35
  FONT_FAMILY
30
36
  } from "./chunk-6KFWC4CO.js";
37
+ import {
38
+ parseTimelineDate
39
+ } from "./chunk-ITXL2KU5.js";
40
+ import {
41
+ CHAR_WIDTH_RATIO,
42
+ wrapTextToWidth
43
+ } from "./chunk-4ASYQ347.js";
31
44
  import {
32
45
  contrastText,
33
46
  getSeriesColors,
@@ -35,14 +48,10 @@ import {
35
48
  shapeFill,
36
49
  themeBaseBg
37
50
  } from "./chunk-JYDMBWRP.js";
38
- import {
39
- CHAR_WIDTH_RATIO,
40
- wrapTextToWidth
41
- } from "./chunk-4ASYQ347.js";
42
51
  import {
43
52
  resolveActiveTagGroup,
44
53
  resolveTagColor
45
- } from "./chunk-CMVZWP32.js";
54
+ } from "./chunk-JR7Q6GHE.js";
46
55
  import {
47
56
  resolveColor
48
57
  } from "./chunk-ZKPPI6BF.js";
@@ -71,6 +80,8 @@ var DATE_SUBTITLE_H = 15;
71
80
  var DATE_SUBTITLE_FONT = 10;
72
81
  var SHELF_TINT = 13;
73
82
  var SHELF_EDGE = 4;
83
+ var SHELF_EDGE_STYLE = "spine";
84
+ var SHELF_LIP = 2;
74
85
  var ERA_BLOCK = 30;
75
86
  var ERA_BRACKET_CAP = 8;
76
87
  var ERA_BRACKET_PAD = 14;
@@ -87,7 +98,7 @@ var COLLAPSED = "dgmo-evt-collapsed";
87
98
  var OFF = "dgmo-evt-off";
88
99
  var HIDDEN_ATTR = "data-evt-hidden";
89
100
  var HOVER_CSS = `.dgmo-event-dot{transition:transform .12s ease;transform-box:fill-box;transform-origin:center}.dgmo-event-leader,.dgmo-event-card,.dgmo-event-era{transition:opacity .12s ease,filter .12s ease}.dgmo-event-dot,.dgmo-event-card,.dgmo-event-era{cursor:default}[data-legend-entry]{cursor:pointer}.${DIM}{opacity:.2}.dgmo-event-dot.${HL}{transform:scale(1.55)}.dgmo-event-leader.${HL}{stroke-opacity:1;stroke-width:2.5}.dgmo-event-card.${HL}{filter:drop-shadow(0 2px 5px rgba(0,0,0,.22))}.dgmo-event-era.${ERA_HL}{filter:drop-shadow(0 1px 2px rgba(0,0,0,.28))}.dgmo-event-card.${COLLAPSED},.dgmo-event-leader.${COLLAPSED}{opacity:0;pointer-events:none}.dgmo-event-card.${COLLAPSED}.${HL},.dgmo-event-leader.${COLLAPSED}.${HL}{opacity:1;pointer-events:auto}[data-legend-entry].${OFF} text{opacity:.5}`;
90
- function renderEventLine(container, parsed, palette, isDark, onClickItem, exportDims, tagOverride) {
101
+ function renderEventLine(container, parsed, palette, isDark, onClickItem, exportDims, tagOverride, nowDate) {
91
102
  if (parsed.events.length === 0) return;
92
103
  d3Selection.select(container).selectAll(":not([data-d3-tooltip])").remove();
93
104
  const width = exportDims?.width ?? container.clientWidth;
@@ -106,7 +117,32 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
106
117
  const hasLegend = parsed.tagGroups.length > 0 && activeGroup !== null && !parsed.options.noLegend;
107
118
  const titleH = showTitle ? TITLE_AREA : 0;
108
119
  const legendH = hasLegend ? LEGEND_BAND : 0;
109
- const topUsed = titleH + legendH;
120
+ const inlineRequested = parsed.options.legendInline === true;
121
+ const legendExtent = inlineRequested && hasLegend ? getLegendExtent(
122
+ {
123
+ groups: parsed.tagGroups,
124
+ position: {
125
+ placement: "top-center",
126
+ titleRelation: "inline-with-title"
127
+ },
128
+ mode: exportMode ? "export" : "preview"
129
+ },
130
+ { activeGroup: activeGroup ?? null },
131
+ width
132
+ ) : { width: 0, height: 0 };
133
+ const header = layoutInlineHeader({
134
+ requested: inlineRequested,
135
+ title: parsed.title ?? "",
136
+ hasLegend,
137
+ legendWidth: legendExtent.width,
138
+ legendHeight: legendExtent.height,
139
+ containerWidth: width,
140
+ titleBandHeight: titleH,
141
+ legendReserve: legendH,
142
+ titleBaselineY: TITLE_Y,
143
+ titleFontSize: TITLE_FONT_SIZE
144
+ });
145
+ const topUsed = header.inline ? titleH : titleH + legendH;
110
146
  const eraByName = new Map(parsed.eras.map((e) => [e.name, e]));
111
147
  const collapsedSet = new Set(
112
148
  parsed.eras.filter((e) => e.collapsed).map((e) => e.name)
@@ -449,14 +485,17 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
449
485
  }
450
486
  if (!exportMode) svg.append("style").text(HOVER_CSS);
451
487
  if (showTitle) {
452
- const t = svg.append("text").attr("class", "chart-title").attr("x", contentW / 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);
488
+ const t = svg.append("text").attr("class", "chart-title").attr("x", header.inline ? header.titleX : contentW / 2).attr("y", TITLE_Y).attr("text-anchor", header.inline ? header.titleAnchor : "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);
453
489
  if (onClickItem && parsed.titleLineNumber) {
454
490
  const ln = parsed.titleLineNumber;
455
491
  t.style("cursor", "pointer").on("click", () => onClickItem(ln));
456
492
  }
457
493
  }
458
494
  if (hasLegend) {
459
- const legendG = svg.append("g").attr("transform", `translate(0, ${titleH})`);
495
+ const legendG = svg.append("g").attr(
496
+ "transform",
497
+ header.inline ? `translate(${header.legendX}, ${header.legendY})` : `translate(0, ${titleH})`
498
+ );
460
499
  const groups = parsed.tagGroups.map((g) => ({
461
500
  name: g.name,
462
501
  entries: g.entries.map((e) => ({
@@ -470,7 +509,14 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
470
509
  isDark,
471
510
  width: contentW,
472
511
  mode: exportMode ? "export" : "preview",
473
- activeGroup
512
+ activeGroup,
513
+ // Inline → left-origin so the wrapper's right-flush translate lands the
514
+ // legend at the header's right edge; stacked → centered below the title
515
+ // (== DEFAULT_POSITION, so the stacked output is byte-identical).
516
+ position: {
517
+ placement: "top-center",
518
+ titleRelation: header.inline ? "inline-with-title" : "below-title"
519
+ }
474
520
  });
475
521
  if (!exportMode) addLegendEntryHitAreas(legendG);
476
522
  }
@@ -535,8 +581,21 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
535
581
  "fill",
536
582
  parsed.options.fillMode ? p.color : mix(p.color, themeBaseBg(palette, isDark), SHELF_TINT)
537
583
  );
538
- const edgeY = titleNearTop ? shelfTop : shelfTop + shelfH - SHELF_EDGE;
539
- cardG.append("rect").attr("x", 0).attr("y", edgeY).attr("width", CARD_W).attr("height", SHELF_EDGE).attr("clip-path", `url(#${clipId})`).attr("fill", p.color).attr("fill-opacity", p.future ? 0.4 : 1);
584
+ if (SHELF_EDGE_STYLE !== "none" && !parsed.options.fillMode) {
585
+ const lip = SHELF_EDGE_STYLE === "left" ? {
586
+ // vertical lip on the spine-relative leading edge
587
+ x: 0,
588
+ y: shelfTop,
589
+ width: SHELF_LIP,
590
+ height: shelfH
591
+ } : {
592
+ x: 0,
593
+ y: titleNearTop ? shelfTop : shelfTop + shelfH - SHELF_LIP,
594
+ width: CARD_W,
595
+ height: SHELF_LIP
596
+ };
597
+ cardG.append("rect").attr("x", lip.x).attr("y", lip.y).attr("width", lip.width).attr("height", lip.height).attr("clip-path", `url(#${clipId})`).attr("fill", p.color).attr("fill-opacity", p.future ? 0.4 : 1);
598
+ }
540
599
  const shelfText = parsed.options.fillMode ? contrastText(p.color, palette.textOnFillLight, palette.textOnFillDark) : p.color;
541
600
  const titleMid = headBandTop + p.headerH / 2;
542
601
  const titleTop = titleMid - (p.titleLines.length - 1) * TITLE_LINE_H / 2;
@@ -683,6 +742,111 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
683
742
  }
684
743
  }
685
744
  }
745
+ if (parsed.now && scaled) {
746
+ let nowValue = parsed.now.dateValue;
747
+ if (parsed.now.computed) {
748
+ const d = nowDate ?? /* @__PURE__ */ new Date();
749
+ const iso = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
750
+ const v = parseTimelineDate(iso);
751
+ nowValue = Number.isFinite(v) ? v : null;
752
+ }
753
+ const dated = placed.filter((p) => p.kind !== "era" && !p.future && p.dateValue !== null).sort((a, b) => a.dateValue - b.dateValue);
754
+ let nowX = nowValue === null ? null : valueToSpineX(nowValue, dated);
755
+ const lastReal = dated[dated.length - 1];
756
+ if (nowX !== null && nowValue !== null && lastReal && nowValue > lastReal.dateValue) {
757
+ const trailing = placed.filter((p) => p.future && !p.futureSpan).map((p) => p.x);
758
+ if (trailing.length) nowX = Math.min(...trailing);
759
+ }
760
+ if (nowX !== null) {
761
+ const base = themeBaseBg(palette, isDark);
762
+ const nowColor = palette.destructive;
763
+ const fillMode = parsed.options.fillMode;
764
+ const pillFill = shapeFill(palette, nowColor, isDark, { mode: fillMode });
765
+ const pillStroke = fillMode === "solid" ? "none" : fillMode === "outline" ? nowColor : mix(nowColor, base, 55);
766
+ const pillStrokeW = fillMode === "solid" ? 0 : fillMode === "outline" ? 1.3 : 1;
767
+ const pillText = fillMode === "solid" ? contrastText(
768
+ pillFill,
769
+ palette.textOnFillLight,
770
+ palette.textOnFillDark
771
+ ) : nowColor;
772
+ const label = parsed.now.label;
773
+ const pillH = 18;
774
+ const pillW = Math.max(28, label.length * 6.6 + 16);
775
+ const PIN_GAP = 6;
776
+ const xHalf = pillW / 2 + 4;
777
+ const xLo = nowX - xHalf;
778
+ const xHi = nowX + xHalf;
779
+ const boxes = geo.map((g) => ({
780
+ side: g.p.side,
781
+ top: g.top,
782
+ bot: g.top + g.p.cardH,
783
+ left: g.p.left,
784
+ right: g.p.left + CARD_W
785
+ }));
786
+ const overlapsX = (b) => b.left < xHi && b.right > xLo;
787
+ const cands = [];
788
+ const addAbove = (pillBottom) => {
789
+ const y0 = pillBottom - pillH;
790
+ if (y0 > topUsed + 1)
791
+ cands.push({ y0, y1: pillBottom, stem: spineY - pillBottom });
792
+ };
793
+ const addBelow = (pillTop) => {
794
+ const y1 = pillTop + pillH;
795
+ if (y1 < totalH - 1)
796
+ cands.push({ y0: pillTop, y1, stem: pillTop - spineY });
797
+ };
798
+ addAbove(spineY - LEADER_ABOVE / 2 + pillH / 2);
799
+ addBelow(spineY + LEADER_BELOW / 2 - pillH / 2);
800
+ for (const b of boxes) {
801
+ if (!overlapsX(b)) continue;
802
+ if (b.side === "above") addAbove(b.top - PIN_GAP);
803
+ else addBelow(b.bot + PIN_GAP);
804
+ }
805
+ const isClear = (c) => !boxes.some((b) => overlapsX(b) && b.bot > c.y0 && b.top < c.y1);
806
+ const byStem = (a, b) => a.stem - b.stem;
807
+ const slot = cands.filter(isClear).sort(byStem)[0] ?? cands.sort(byStem)[0] ?? {
808
+ y0: spineY - PIN_GAP - pillH,
809
+ y1: spineY - PIN_GAP,
810
+ stem: PIN_GAP + pillH
811
+ };
812
+ const above = slot.y1 <= spineY;
813
+ const stemFrom = above ? spineY - DOT_R : spineY + DOT_R;
814
+ const stemTo = above ? slot.y1 : slot.y0;
815
+ const pillCX = Math.max(
816
+ pillW / 2 + 2,
817
+ Math.min(nowX, contentW - pillW / 2 - 2)
818
+ );
819
+ const nowG = svg.append("g").attr("class", "evt-now").attr("data-now-x", nowX.toFixed(2));
820
+ const FADE_SPAN = Math.min(LEADER_ABOVE, LEADER_BELOW);
821
+ const ruleTop = spineY - FADE_SPAN;
822
+ const ruleBot = spineY + FADE_SPAN;
823
+ const gradId = `evt-now-fade-${nowX.toFixed(0)}`;
824
+ const grad = nowG.append("defs").append("linearGradient").attr("id", gradId).attr("gradientUnits", "userSpaceOnUse").attr("x1", 0).attr("y1", ruleTop).attr("x2", 0).attr("y2", ruleBot);
825
+ grad.append("stop").attr("offset", "0%").attr("stop-color", nowColor).attr("stop-opacity", 0);
826
+ grad.append("stop").attr("offset", "50%").attr("stop-color", nowColor).attr("stop-opacity", 0.9);
827
+ grad.append("stop").attr("offset", "100%").attr("stop-color", nowColor).attr("stop-opacity", 0);
828
+ nowG.append("line").attr("x1", nowX).attr("y1", ruleTop).attr("x2", nowX).attr("y2", ruleBot).attr("stroke", `url(#${gradId})`).attr("stroke-width", 1.6).attr("stroke-dasharray", "1 4").attr("stroke-linecap", "round");
829
+ nowG.append("path").attr("d", `M${nowX} ${spineY - 5} l5 5 l-5 5 l-5 -5 z`).attr("fill", nowColor);
830
+ nowG.append("line").attr("x1", nowX).attr("y1", stemFrom).attr("x2", nowX).attr("y2", stemTo).attr("stroke", nowColor).attr("stroke-width", 1.6);
831
+ nowG.append("rect").attr("x", pillCX - pillW / 2).attr("y", slot.y0).attr("width", pillW).attr("height", pillH).attr("rx", pillH / 2).attr("fill", pillFill).attr("stroke", pillStroke).attr("stroke-width", pillStrokeW);
832
+ nowG.append("text").attr("x", pillCX).attr("y", slot.y0 + pillH / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-family", FONT_FAMILY).attr("font-size", 10.5).attr("font-weight", 600).attr("fill", pillText).text(label);
833
+ if (!exportMode) {
834
+ const hoverRule = nowG.append("line").attr("class", "evt-now-rule-full").attr("x1", nowX).attr("y1", Math.max(topUsed, 2)).attr("x2", nowX).attr("y2", totalH - 2).attr("stroke", nowColor).attr("stroke-width", 1.4).attr("stroke-dasharray", "1 4").attr("stroke-linecap", "round").attr("opacity", 0).style("transition", "opacity 120ms ease").style("pointer-events", "none");
835
+ hoverRule.lower();
836
+ const nowNode = nowG.node();
837
+ if (nowNode) {
838
+ nowNode.addEventListener(
839
+ "mouseenter",
840
+ () => hoverRule.attr("opacity", 0.5)
841
+ );
842
+ nowNode.addEventListener(
843
+ "mouseleave",
844
+ () => hoverRule.attr("opacity", 0)
845
+ );
846
+ }
847
+ }
848
+ }
849
+ }
686
850
  if (!exportMode) {
687
851
  const root = svg.node();
688
852
  wireEventLineHover(root);
@@ -697,7 +861,8 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
697
861
  isDark,
698
862
  onClickItem,
699
863
  exportDims,
700
- tagOverride
864
+ tagOverride,
865
+ nowDate
701
866
  )
702
867
  );
703
868
  applyEvtHidden(container, root);
@@ -907,7 +1072,7 @@ function wireEventLineHover(root) {
907
1072
  if (!to || !root.contains(to)) applyEvtFocus(root, readPin(root));
908
1073
  });
909
1074
  }
910
- function renderEventLineForExport(container, parsed, palette, isDark, exportDims, tagOverride) {
1075
+ function renderEventLineForExport(container, parsed, palette, isDark, exportDims, tagOverride, nowDate) {
911
1076
  renderEventLine(
912
1077
  container,
913
1078
  parsed,
@@ -915,9 +1080,27 @@ function renderEventLineForExport(container, parsed, palette, isDark, exportDims
915
1080
  isDark,
916
1081
  void 0,
917
1082
  exportDims,
918
- tagOverride
1083
+ tagOverride,
1084
+ nowDate
919
1085
  );
920
1086
  }
1087
+ function valueToSpineX(v, dated) {
1088
+ if (!dated.length) return null;
1089
+ const first = dated[0];
1090
+ const last = dated[dated.length - 1];
1091
+ if (v <= first.dateValue) return first.x;
1092
+ if (v >= last.dateValue) return last.x;
1093
+ for (let i = 0; i < dated.length - 1; i++) {
1094
+ const a = dated[i];
1095
+ const b = dated[i + 1];
1096
+ if (v >= a.dateValue && v <= b.dateValue) {
1097
+ const span = b.dateValue - a.dateValue;
1098
+ if (span <= 0) return a.x;
1099
+ return a.x + (v - a.dateValue) / span * (b.x - a.x);
1100
+ }
1101
+ }
1102
+ return last.x;
1103
+ }
921
1104
  function axisBreakPaths(cx, cy) {
922
1105
  const HUMPS = 2;
923
1106
  const STEPS = 48;
@@ -982,4 +1165,4 @@ export {
982
1165
  focusEventLine,
983
1166
  renderEventLineForExport
984
1167
  };
985
- //# sourceMappingURL=chunk-W2DINCHL.js.map
1168
+ //# sourceMappingURL=chunk-PKUWYPI5.js.map
@@ -5,7 +5,7 @@ import {
5
5
  splitNameAndMeta,
6
6
  tryParseSharedOption,
7
7
  warnUnknownMetaKeys
8
- } from "./chunk-YJVA3QUU.js";
8
+ } from "./chunk-A2ARDILY.js";
9
9
  import {
10
10
  RECOGNIZED_COLOR_NAMES,
11
11
  resolveColor
@@ -165,4 +165,4 @@ function parseRing(content) {
165
165
  export {
166
166
  parseRing
167
167
  };
168
- //# sourceMappingURL=chunk-PV2QO7QL.js.map
168
+ //# sourceMappingURL=chunk-PSIDVCBA.js.map