@diagrammo/dgmo 0.89.0 → 0.90.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 (208) hide show
  1. package/README.md +1 -1
  2. package/dist/advanced.d.ts +435 -15
  3. package/dist/advanced.js +356 -197
  4. package/dist/block.d.ts +1 -1
  5. package/dist/block.js +86 -63
  6. package/dist/{calculator-35YVW4QO.js → calculator-PX3JHKAS.js} +2 -2
  7. package/dist/{chart-meta-Bev5Ebjr.d.ts → chart-meta-B_WTMP0y.d.ts} +1 -1
  8. package/dist/chart-meta.d.ts +2 -2
  9. package/dist/chart-meta.js +17 -16
  10. package/dist/{chart-types-Bf8C5QQW.d.ts → chart-types-V2NcgN5O.d.ts} +4 -0
  11. package/dist/{charts-d3-KEQSUWKP.js → charts-d3-QW4ERNUE.js} +8 -7
  12. package/dist/{chunk-ECMA6XE2.js → chunk-2EDJPHXQ.js} +9 -9
  13. package/dist/{chunk-7WGCQE2E.js → chunk-2ZVLI6GQ.js} +1 -1
  14. package/dist/{chunk-UWKRPQZO.js → chunk-3BQCSQQJ.js} +16 -13
  15. package/dist/{chunk-7C2RAGPT.js → chunk-3HBR3YAN.js} +12 -12
  16. package/dist/chunk-3UR4F7FE.js +14 -0
  17. package/dist/{chunk-NIUO2TNR.js → chunk-4HG4PYHM.js} +197 -203
  18. package/dist/{chunk-NSR2CGV6.js → chunk-4IYJOXGS.js} +10 -10
  19. package/dist/{chunk-BOO24UMJ.js → chunk-4YO7VJTP.js} +1 -1
  20. package/dist/{chunk-YMFQLWZ2.js → chunk-54YUDXGP.js} +1 -1
  21. package/dist/{chunk-UG2XG57E.js → chunk-5M52RPAS.js} +2 -2
  22. package/dist/{chunk-QIOYTQDZ.js → chunk-5M6PMV5Z.js} +9 -9
  23. package/dist/{chunk-S2WE7TVK.js → chunk-5MDQMB6A.js} +1 -1
  24. package/dist/{chunk-WPL5PFXE.js → chunk-5TZPIKNV.js} +5 -5
  25. package/dist/{chunk-LFKSHDVI.js → chunk-62VWZ3SE.js} +5 -4
  26. package/dist/{chunk-PMNITNPR.js → chunk-64KSPLU2.js} +2 -1
  27. package/dist/{chunk-VEPIAUSK.js → chunk-6BQSDF77.js} +1 -5
  28. package/dist/{chunk-HUNDJTTH.js → chunk-A5EE66RQ.js} +1 -1
  29. package/dist/{chunk-JVZ7KFAX.js → chunk-AAC3XQWV.js} +2 -2
  30. package/dist/{chunk-7KPHRTND.js → chunk-AHWA36O7.js} +1 -1
  31. package/dist/{chunk-FKZ2Y3Q5.js → chunk-C4W62JZO.js} +2 -2
  32. package/dist/{chunk-C4FRGZGX.js → chunk-CDT33RHG.js} +1 -1
  33. package/dist/{chunk-B3S76BZO.js → chunk-COPSI54O.js} +3 -3
  34. package/dist/{chunk-GUTZCRBT.js → chunk-CUY56BK4.js} +2 -2
  35. package/dist/{chunk-HSRQDWV7.js → chunk-CYF2X3CG.js} +2 -11
  36. package/dist/{chunk-NGC3IZRY.js → chunk-DNMICILX.js} +2 -2
  37. package/dist/{chunk-N4BBSDWI.js → chunk-DXPT2HPH.js} +140 -151
  38. package/dist/{chunk-TAP2NZEU.js → chunk-EB7AEM2H.js} +13 -13
  39. package/dist/{chunk-3AQJNY65.js → chunk-EEYQFJVK.js} +149 -43
  40. package/dist/{chunk-SLQT3JP3.js → chunk-EK7JYFCL.js} +1 -1
  41. package/dist/{chunk-3C2FWS2J.js → chunk-EWERNTOX.js} +1 -1
  42. package/dist/{chunk-4AJKOUBO.js → chunk-FDRHBQUG.js} +17 -15
  43. package/dist/{chunk-FJNXXGTR.js → chunk-FS2LZBHG.js} +2 -2
  44. package/dist/{chunk-LPYYZCSI.js → chunk-G5BGW4BX.js} +1 -1
  45. package/dist/{chunk-IQ6P3HDE.js → chunk-GQVXYRPC.js} +2 -2
  46. package/dist/{chunk-MHAYUS65.js → chunk-GXP344YZ.js} +3 -3
  47. package/dist/{chunk-HAMF4F3P.js → chunk-GYBKG4Z6.js} +5 -5
  48. package/dist/{chunk-Q6SQISHT.js → chunk-HIVJBESO.js} +306 -68
  49. package/dist/{chunk-ID2K3IHI.js → chunk-HLE5QGZJ.js} +1 -1
  50. package/dist/{chunk-L5AFONQU.js → chunk-HX2KJEPD.js} +1 -1
  51. package/dist/{chunk-SOPM5PLO.js → chunk-I6FWHICD.js} +13 -13
  52. package/dist/{chunk-3RYBTEF5.js → chunk-I74AQRVD.js} +6 -12
  53. package/dist/{chunk-NRPELUB6.js → chunk-ICYPGWOV.js} +2 -2
  54. package/dist/chunk-IHK3Y2HG.js +781 -0
  55. package/dist/{chunk-RXIKESRI.js → chunk-IMHNZITR.js} +2 -2
  56. package/dist/{chunk-DPSMX4EY.js → chunk-IRVQT4GR.js} +3 -3
  57. package/dist/{chunk-AZ24RI5L.js → chunk-J3ODKAWN.js} +2 -2
  58. package/dist/{chunk-BB6QKWHZ.js → chunk-JRQ4LBQI.js} +10 -10
  59. package/dist/{chunk-MY6GUH26.js → chunk-JX4RCC6B.js} +2 -2
  60. package/dist/{chunk-XUCQVKLQ.js → chunk-K4GUO7FV.js} +4 -4
  61. package/dist/{chunk-J64NZ6NF.js → chunk-KSZHIAI2.js} +1 -1
  62. package/dist/{chunk-CUYHST3B.js → chunk-LBRHDWEA.js} +1 -1
  63. package/dist/{chunk-GSYZZFI5.js → chunk-LC5LY5V2.js} +2 -2
  64. package/dist/{chunk-WP22MHH6.js → chunk-LNQDICFJ.js} +9 -9
  65. package/dist/{chunk-PIXJL77H.js → chunk-M6J25PAZ.js} +1 -1
  66. package/dist/{chunk-UQLHKLF4.js → chunk-MIVSVEK4.js} +8 -8
  67. package/dist/{chunk-6K7RODXG.js → chunk-MKFQ5E7J.js} +1 -1
  68. package/dist/{chunk-44GP7PD5.js → chunk-MPJQMMBZ.js} +12 -0
  69. package/dist/{chunk-WQ6G6FFM.js → chunk-NFWRIC2V.js} +1 -1
  70. package/dist/{chunk-7SX4IY6T.js → chunk-NJYA4QSN.js} +1 -1
  71. package/dist/{chunk-RU725VCJ.js → chunk-NMKLX57Y.js} +10 -35
  72. package/dist/{chunk-RPKBWJBB.js → chunk-NP2SE6MQ.js} +1 -1
  73. package/dist/{chunk-ITSBBQTH.js → chunk-NUYWNKHH.js} +2 -2
  74. package/dist/{chunk-DV2VEJCC.js → chunk-NWSPPGIE.js} +6 -6
  75. package/dist/{chunk-AYOVY75O.js → chunk-NY56FM55.js} +3 -3
  76. package/dist/{chunk-MFW6P7WH.js → chunk-OSIUWQ3N.js} +3 -3
  77. package/dist/{chunk-2GM7N5TV.js → chunk-OWJVSJLA.js} +9 -9
  78. package/dist/{chunk-GDJW64XE.js → chunk-OYKNMFUY.js} +1 -1
  79. package/dist/{chunk-4R6OMKXB.js → chunk-PIHAUVA4.js} +5 -5
  80. package/dist/{chunk-C7QRRTAW.js → chunk-PNCKZFPE.js} +2 -2
  81. package/dist/{chunk-DDPGEGHB.js → chunk-POBNN5DP.js} +2 -2
  82. package/dist/{chunk-XJ2TBXHA.js → chunk-PQ5NW3QZ.js} +8 -8
  83. package/dist/{chunk-FKLE6QA3.js → chunk-PXEUQ7EG.js} +12 -12
  84. package/dist/{chunk-WEF6MXFG.js → chunk-QOZ4RVQY.js} +8 -8
  85. package/dist/{chunk-LR6RRDWN.js → chunk-QRIW46LR.js} +5 -5
  86. package/dist/{chunk-7W4XLIVH.js → chunk-R2PTZ6QM.js} +10 -10
  87. package/dist/{chunk-M2BCY7H3.js → chunk-RCBHL2B5.js} +189 -136
  88. package/dist/{chunk-66YFDTT6.js → chunk-RJYFHEP4.js} +3 -3
  89. package/dist/{chunk-P3SKSKJI.js → chunk-RNXX2GOQ.js} +2 -2
  90. package/dist/{chunk-RGWYZR3S.js → chunk-RRBV4HIM.js} +2 -2
  91. package/dist/{chunk-44FTCIRI.js → chunk-RY5RRKYN.js} +8 -8
  92. package/dist/{chunk-Y7PSAHAY.js → chunk-S4LLHDGK.js} +3 -3
  93. package/dist/chunk-S7C32S2T.js +825 -0
  94. package/dist/{chunk-JRUEIRJB.js → chunk-SLO22FPS.js} +2 -2
  95. package/dist/{chunk-47E5UTXE.js → chunk-SMEVBJJJ.js} +2 -2
  96. package/dist/{chunk-QFHWYWQL.js → chunk-SVQDLYX7.js} +1 -1
  97. package/dist/{chunk-WP2RLGDI.js → chunk-TCX5PMEY.js} +1 -1
  98. package/dist/{chunk-EXKCRXPO.js → chunk-TQ644YGV.js} +12 -12
  99. package/dist/{chunk-WRCAH3UO.js → chunk-U762HK4D.js} +15 -15
  100. package/dist/{chunk-LYLNMN77.js → chunk-VCHYS3RD.js} +8 -3
  101. package/dist/{chunk-7UDAIP6W.js → chunk-WHRIN7N3.js} +1 -1
  102. package/dist/{chunk-ZUCXFXLD.js → chunk-X3WYJ5T7.js} +2 -2
  103. package/dist/{chunk-UKJLPA7R.js → chunk-X6IZP2BD.js} +1 -1
  104. package/dist/{chunk-LCJURK7L.js → chunk-Y6GQQ4Y2.js} +1 -1
  105. package/dist/{chunk-HTWH2XQL.js → chunk-YE7D2S75.js} +2 -2
  106. package/dist/{chunk-DZPHN2WN.js → chunk-YKGUSW6D.js} +10 -10
  107. package/dist/{chunk-K5XT7NHD.js → chunk-YWRZG6GN.js} +10 -10
  108. package/dist/{chunk-JQ57AWDL.js → chunk-ZJ4PYTCK.js} +1 -1
  109. package/dist/completion-registry.d.ts +6 -0
  110. package/dist/completion-registry.js +62 -6
  111. package/dist/{d3-B6524aaP.d.ts → d3-2S3PrXik.d.ts} +11 -0
  112. package/dist/dgmo-router-BJBXSZMV.js +94 -0
  113. package/dist/{dimensions-7MF7VSGS.js → dimensions-AMA2S7RO.js} +5 -5
  114. package/dist/editor.js +12 -0
  115. package/dist/{flowchart-parser-GG7XBLQH.js → flowchart-parser-ADZIFVCH.js} +3 -3
  116. package/dist/{flowchart-renderer-DZQZRL2F.js → flowchart-renderer-CAG6ZNJ6.js} +5 -5
  117. package/dist/highlight.js +12 -0
  118. package/dist/index.d.ts +26 -5
  119. package/dist/index.js +83 -56
  120. package/dist/{layout-EFEZ533S.js → layout-6OSF2UGP.js} +3 -3
  121. package/dist/{layout-IGAVGDME.js → layout-C6MKMOBI.js} +1 -1
  122. package/dist/{layout-XUW444O5.js → layout-QS2SESBU.js} +2 -2
  123. package/dist/{layout-PP36LUTA.js → layout-T2PGKQUQ.js} +3 -3
  124. package/dist/{layout-Q3RYSODA.js → layout-UFB2O4AO.js} +3 -3
  125. package/dist/{layout-MSSHF45T.js → layout-UPQGIT3N.js} +2 -2
  126. package/dist/{layout-6L3BIFEZ.js → layout-VQ2USZJ3.js} +3 -3
  127. package/dist/{layout-DXVAYF6W.js → layout-VRJ5YFUE.js} +2 -2
  128. package/dist/{palettes-WZAIQTEG.js → palettes-WQHELGVQ.js} +2 -1
  129. package/dist/{parser-KYPP2DX6.js → parser-223VOHSB.js} +4 -4
  130. package/dist/{parser-JOOAVBJI.js → parser-2PNV7UI3.js} +3 -3
  131. package/dist/{parser-GZ3LVF72.js → parser-3MGA2MTM.js} +2 -2
  132. package/dist/{parser-NOANDFJ4.js → parser-4AR25MAS.js} +2 -2
  133. package/dist/{parser-337TACHB.js → parser-4B2PIXHI.js} +3 -3
  134. package/dist/{parser-KZMJNKDW.js → parser-57YQEEMC.js} +2 -2
  135. package/dist/{parser-J4DVNL4W.js → parser-5ZD2NKGU.js} +4 -4
  136. package/dist/{parser-LANGKWRG.js → parser-6LMB7BQQ.js} +2 -2
  137. package/dist/parser-AL6YL7KM.js +12 -0
  138. package/dist/{parser-5655XSOR.js → parser-B2FWP7ZO.js} +3 -3
  139. package/dist/{parser-GEKPWSSK.js → parser-BJDQX4KV.js} +3 -3
  140. package/dist/{parser-UTXFJG4X.js → parser-CA5WC5HF.js} +3 -3
  141. package/dist/{parser-KZMALSB2.js → parser-E5HFYL7B.js} +4 -4
  142. package/dist/{parser-GCCWMBTU.js → parser-ESZ5J5IJ.js} +5 -4
  143. package/dist/{parser-256EIWB2.js → parser-FDXUQ5TI.js} +2 -2
  144. package/dist/{parser-AN3MGHRL.js → parser-FV6RGALQ.js} +3 -3
  145. package/dist/{parser-DGF3ZEO6.js → parser-HPR7G7F6.js} +3 -3
  146. package/dist/{parser-OKB64MMN.js → parser-I4HZVIHX.js} +3 -3
  147. package/dist/{parser-P4TOQYNN.js → parser-J3BM2AP2.js} +3 -3
  148. package/dist/{parser-NPXPJHWN.js → parser-JFNDS5E5.js} +3 -3
  149. package/dist/{parser-TL3JA4RI.js → parser-KFIK3EOO.js} +3 -3
  150. package/dist/{parser-IMM2JJX3.js → parser-LGUT7KKH.js} +4 -4
  151. package/dist/{parser-KFYRTGTC.js → parser-MYRGCK7Q.js} +4 -4
  152. package/dist/{parser-ZLKYDFI5.js → parser-NAUUUCI3.js} +3 -3
  153. package/dist/{parser-DHSFIUPU.js → parser-NJ5VEZA3.js} +3 -3
  154. package/dist/{parser-OVQTTTUJ.js → parser-OFTMA36M.js} +2 -2
  155. package/dist/{parser-AKBVJHMK.js → parser-OV2WDSEV.js} +3 -3
  156. package/dist/{parser-LGS65QPN.js → parser-Q3UAOLEZ.js} +2 -2
  157. package/dist/{parser-XYY5NHP4.js → parser-R6OETHWM.js} +2 -2
  158. package/dist/{parser-7OEE7QT6.js → parser-RARXAHC7.js} +2 -2
  159. package/dist/{parser-NGHQQGD2.js → parser-T2RVIRDG.js} +3 -3
  160. package/dist/{parser-WEVTMBJ5.js → parser-W2DWCCLO.js} +3 -3
  161. package/dist/{parser-HCGXNHHL.js → parser-WFY4ZJUW.js} +3 -3
  162. package/dist/{parser-SA3RAJFS.js → parser-WSONWDFN.js} +2 -2
  163. package/dist/{renderer-CHQZES6G.js → renderer-3N64GVNM.js} +2 -2
  164. package/dist/{renderer-JR2XNZAH.js → renderer-3QM2DK7I.js} +5 -5
  165. package/dist/{renderer-XHEMXBQM.js → renderer-3W5T3IU6.js} +5 -5
  166. package/dist/{renderer-2ZQ6DPVD.js → renderer-4Z7FRQ2A.js} +2 -2
  167. package/dist/{renderer-EAORWLVK.js → renderer-52CHSV6S.js} +7 -7
  168. package/dist/{renderer-ZXQXRNDR.js → renderer-6OOJNEQE.js} +6 -6
  169. package/dist/{renderer-IR5GGAPB.js → renderer-A3PMPUO6.js} +11 -7
  170. package/dist/{renderer-3AD4NDF5.js → renderer-AM4VZSBQ.js} +6 -6
  171. package/dist/{renderer-P4XCRNCY.js → renderer-B3CPMS5R.js} +6 -6
  172. package/dist/{renderer-VGQMJC5K.js → renderer-B4KE3NM4.js} +11 -10
  173. package/dist/renderer-COSJM7UG.js +80 -0
  174. package/dist/{renderer-NAA7D33G.js → renderer-FXCVH2M5.js} +10 -9
  175. package/dist/{renderer-J4OS77PK.js → renderer-GWH5ACJ5.js} +3 -3
  176. package/dist/{renderer-7HOSI6JJ.js → renderer-IG72UJHW.js} +4 -4
  177. package/dist/{renderer-QQHQY3GT.js → renderer-IO3D5E4E.js} +5 -5
  178. package/dist/{renderer-6OQM32X3.js → renderer-IPDCAACY.js} +3 -3
  179. package/dist/{renderer-VYWCMRWA.js → renderer-KK5BU5K2.js} +5 -5
  180. package/dist/{renderer-7MCC6GKH.js → renderer-LD2H7WGP.js} +2 -2
  181. package/dist/{renderer-DCJ4AQ3N.js → renderer-MK47ESCB.js} +5 -5
  182. package/dist/{renderer-BLHN3RCY.js → renderer-MRMFYYZT.js} +2 -2
  183. package/dist/{renderer-XFEZ5UBE.js → renderer-O5RQHGK2.js} +6 -6
  184. package/dist/{renderer-43ESBXVY.js → renderer-OA5D3ZKB.js} +6 -6
  185. package/dist/{renderer-YTEZK3GC.js → renderer-ON4PTUHJ.js} +7 -7
  186. package/dist/{renderer-JRVY7HAD.js → renderer-OPDSKCQS.js} +4 -4
  187. package/dist/{renderer-FCXRDYSJ.js → renderer-PLRMST57.js} +7 -7
  188. package/dist/{renderer-WB75JME5.js → renderer-PSMRAL72.js} +6 -6
  189. package/dist/{renderer-7L7J4DHO.js → renderer-PXGCR7N4.js} +7 -6
  190. package/dist/{renderer-CEIX5JPA.js → renderer-R7OYCJEA.js} +2 -2
  191. package/dist/{renderer-DBNDLKPE.js → renderer-SBXCPA3S.js} +7 -7
  192. package/dist/{renderer-4JE5ORRO.js → renderer-TMQNTUQS.js} +7 -7
  193. package/dist/renderer-TTKTBB4C.js +46 -0
  194. package/dist/{renderer-5GZNGZU5.js → renderer-UVFGW2O6.js} +9 -7
  195. package/dist/{renderer-7VQOKAII.js → renderer-W22GX72R.js} +6 -6
  196. package/dist/{renderer-radial-NA5DVBG4.js → renderer-radial-42LVSG74.js} +5 -5
  197. package/dist/{state-parser-FE3RF6XY.js → state-parser-ROKY5KSI.js} +4 -4
  198. package/dist/{state-renderer-4S2C2CHB.js → state-renderer-MMG23G4W.js} +8 -8
  199. package/dist/{themes-CzuBdx1T.d.ts → themes-Cm2YBcT8.d.ts} +38 -2
  200. package/docs/ai-integration.md +4 -3
  201. package/docs/language-reference.md +162 -12
  202. package/gallery/fixtures/sketch.dgmo +2 -2
  203. package/gallery/fixtures/whiteboard.dgmo +18 -0
  204. package/package.json +2 -1
  205. package/dist/dgmo-router-7WANZOBD.js +0 -92
  206. package/dist/renderer-TJJGFQGT.js +0 -78
  207. package/dist/{chunk-CX6OH5WP.js → chunk-A5PUOHIS.js} +3 -3
  208. package/dist/{chunk-5LE2CTLS.js → chunk-NTJ5HVV6.js} +3 -3
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  resolveTagColor,
3
3
  tagAttrKey
4
- } from "./chunk-L5AFONQU.js";
4
+ } from "./chunk-HX2KJEPD.js";
5
5
  import {
6
6
  mix
7
7
  } from "./chunk-L24LESXF.js";
@@ -21,7 +21,7 @@ import {
21
21
  tagAttrKey,
22
22
  validateTagGroupNames,
23
23
  validateTagValues
24
- } from "./chunk-L5AFONQU.js";
24
+ } from "./chunk-HX2KJEPD.js";
25
25
  import {
26
26
  PERT_REGISTRY,
27
27
  extractColor,
@@ -31,7 +31,7 @@ import {
31
31
  splitNameAndMeta,
32
32
  warnUnknownMetaKeys,
33
33
  withTagAliases
34
- } from "./chunk-44GP7PD5.js";
34
+ } from "./chunk-MPJQMMBZ.js";
35
35
  import {
36
36
  emit,
37
37
  makeDgmoError,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  buildMapProjection
3
- } from "./chunk-LR6RRDWN.js";
3
+ } from "./chunk-QRIW46LR.js";
4
4
  import {
5
5
  TITLE_FONT_SIZE,
6
6
  TITLE_Y
@@ -11,7 +11,7 @@ import {
11
11
  matchTagBlockHeading,
12
12
  stripDefaultModifier,
13
13
  tagAttrKey
14
- } from "./chunk-L5AFONQU.js";
14
+ } from "./chunk-HX2KJEPD.js";
15
15
  import {
16
16
  FAMILY_PERSON_REGISTRY,
17
17
  FAMILY_UNION_REGISTRY,
@@ -26,7 +26,7 @@ import {
26
26
  tokenizeQuoteAware,
27
27
  tryParseSharedOption,
28
28
  withTagAliases
29
- } from "./chunk-44GP7PD5.js";
29
+ } from "./chunk-MPJQMMBZ.js";
30
30
  import {
31
31
  nord,
32
32
  resolveColor
@@ -17,7 +17,7 @@ import {
17
17
  } from "./chunk-ICLB27PZ.js";
18
18
  import {
19
19
  fillModeFromOptions
20
- } from "./chunk-44GP7PD5.js";
20
+ } from "./chunk-MPJQMMBZ.js";
21
21
  import {
22
22
  CHAR_WIDTH_RATIO,
23
23
  measureText
@@ -9,7 +9,7 @@ import {
9
9
  stripDefaultModifier,
10
10
  tagAttrKey,
11
11
  validateTagGroupNames
12
- } from "./chunk-L5AFONQU.js";
12
+ } from "./chunk-HX2KJEPD.js";
13
13
  import {
14
14
  JOURNEY_MAP_REGISTRY,
15
15
  OPTION_NOCOLON_RE,
@@ -20,7 +20,7 @@ import {
20
20
  splitNameAndMeta,
21
21
  warnUnknownMetaKeys,
22
22
  withTagAliases
23
- } from "./chunk-44GP7PD5.js";
23
+ } from "./chunk-MPJQMMBZ.js";
24
24
  import {
25
25
  resolveColorWithDiagnostic
26
26
  } from "./chunk-2M4IGSCY.js";
@@ -317,7 +317,7 @@ function parseJourneyMap(content, palette) {
317
317
  const groupKey = aliasMap.get(tagKey.toLowerCase()) ?? tagKey.toLowerCase();
318
318
  const validValues = tagValueSets.get(groupKey);
319
319
  if (validValues && !validValues.has(tagValue.toLowerCase())) {
320
- const entries = result.tagGroups.find((g) => g.name.toLowerCase() === groupKey)?.entries.map((e) => e.value);
320
+ const entries = result.tagGroups.find((g) => tagAttrKey(g.name) === groupKey)?.entries.map((e) => e.value);
321
321
  let msg = `Unknown tag value "${tagValue}" for group "${groupKey}"`;
322
322
  if (entries) {
323
323
  const hint = suggest(tagValue, entries);
@@ -17,7 +17,7 @@ import {
17
17
  stripDefaultModifier,
18
18
  tagAttrKey,
19
19
  validateTagGroupNames
20
- } from "./chunk-L5AFONQU.js";
20
+ } from "./chunk-HX2KJEPD.js";
21
21
  import {
22
22
  AliasRegistry,
23
23
  INFRA_BEHAVIOR_KEY_SET,
@@ -31,7 +31,7 @@ import {
31
31
  tryParseSharedOption,
32
32
  warnUnknownMetaKeys,
33
33
  withTagAliases
34
- } from "./chunk-44GP7PD5.js";
34
+ } from "./chunk-MPJQMMBZ.js";
35
35
  import {
36
36
  isRecognizedColorName
37
37
  } from "./chunk-2M4IGSCY.js";
@@ -1,19 +1,18 @@
1
1
  import {
2
2
  isTagBlockHeading
3
- } from "./chunk-L5AFONQU.js";
3
+ } from "./chunk-HX2KJEPD.js";
4
4
  import {
5
5
  OPTION_NOCOLON_RE,
6
6
  measureIndent,
7
7
  parseFirstLine,
8
8
  tryParseSharedOption
9
- } from "./chunk-44GP7PD5.js";
9
+ } from "./chunk-MPJQMMBZ.js";
10
10
  import {
11
11
  formatDgmoError,
12
12
  makeDgmoError
13
13
  } from "./chunk-BYU54C3S.js";
14
14
 
15
15
  // src/wireframe/parser.ts
16
- var KNOWN_OPTIONS = /* @__PURE__ */ new Set(["palette", "theme"]);
17
16
  var INERT_OPTIONS = {
18
17
  "active-tag": '"active-tag" does nothing on a wireframe \u2014 it has no tag groups. Element appearance comes from the trailing state keywords (primary, disabled, selected, \u2026).'
19
18
  };
@@ -517,10 +516,6 @@ function parseWireframe(content) {
517
516
  pushWarning(lineNumber, inertMsg);
518
517
  continue;
519
518
  }
520
- if (KNOWN_OPTIONS.has(key)) {
521
- options[key] = optMatch[2] || "";
522
- continue;
523
- }
524
519
  }
525
520
  if (isTagBlockHeading(trimmed)) {
526
521
  refuseTagBlock(lineNumber);
@@ -544,10 +539,6 @@ function parseWireframe(content) {
544
539
  pushWarning(lineNumber, inertMsg);
545
540
  continue;
546
541
  }
547
- if (KNOWN_OPTIONS.has(key)) {
548
- options[key] = optMatch[2] || "";
549
- continue;
550
- }
551
542
  }
552
543
  }
553
544
  if (isTagBlockHeading(trimmed)) {
@@ -11,7 +11,7 @@ import {
11
11
  tagAttrKey,
12
12
  validateTagGroupNames,
13
13
  validateTagValues
14
- } from "./chunk-L5AFONQU.js";
14
+ } from "./chunk-HX2KJEPD.js";
15
15
  import {
16
16
  MINDMAP_REGISTRY,
17
17
  OPTION_NOCOLON_RE,
@@ -23,7 +23,7 @@ import {
23
23
  tryParseSharedOption,
24
24
  warnUnknownMetaKeys,
25
25
  withTagAliases
26
- } from "./chunk-44GP7PD5.js";
26
+ } from "./chunk-MPJQMMBZ.js";
27
27
  import {
28
28
  formatDgmoError,
29
29
  makeDgmoError,
@@ -9,6 +9,9 @@ import {
9
9
  import {
10
10
  ScaleContext
11
11
  } from "./chunk-24YPR5EH.js";
12
+ import {
13
+ renderIntegratedLegend
14
+ } from "./chunk-NJYA4QSN.js";
12
15
  import {
13
16
  ARROWHEAD_HEIGHT,
14
17
  ARROWHEAD_WIDTH,
@@ -27,18 +30,15 @@ import {
27
30
  import {
28
31
  layoutInlineHeader
29
32
  } from "./chunk-CNUN5GO6.js";
33
+ import {
34
+ getLegendExtent,
35
+ getMaxLegendReservedHeight
36
+ } from "./chunk-NS7L7YKH.js";
30
37
  import {
31
38
  TITLE_FONT_SIZE,
32
39
  TITLE_FONT_WEIGHT,
33
40
  TITLE_Y
34
41
  } from "./chunk-VLC6WNRD.js";
35
- import {
36
- renderIntegratedLegend
37
- } from "./chunk-7SX4IY6T.js";
38
- import {
39
- getLegendExtent,
40
- getMaxLegendReservedHeight
41
- } from "./chunk-NS7L7YKH.js";
42
42
  import {
43
43
  FONT_FAMILY
44
44
  } from "./chunk-ICLB27PZ.js";
@@ -48,11 +48,10 @@ import {
48
48
  resolveGroupTagColor,
49
49
  resolveTagColor,
50
50
  tagAttrKey
51
- } from "./chunk-L5AFONQU.js";
51
+ } from "./chunk-HX2KJEPD.js";
52
52
  import {
53
53
  fitWrapped,
54
- measureText,
55
- wrapTextToWidth
54
+ measureText
56
55
  } from "./chunk-KAO7JL4I.js";
57
56
  import {
58
57
  contrastText,
@@ -424,41 +423,10 @@ var DASH = SKETCH_VISUALS.dash;
424
423
  var BAND_LABEL_FONT_SIZE = SKETCH_VISUALS.bandLabelFontSize;
425
424
  var BAND_LABEL_OPACITY = SKETCH_VISUALS.bandLabelOpacity;
426
425
  var BAND_LABEL_WEIGHT = SKETCH_VISUALS.bandLabelFontWeight;
427
- var NOTE_FONT_SIZE = 11;
428
426
  var COLLAPSE_BAR_HEIGHT2 = COLLAPSE_BAR_HEIGHT;
429
427
  var EDGE_LABEL_FONT_SIZE = SKETCH_VISUALS.edgeLabelFontSize;
430
428
  var CURVE_HANDLE_MIN = 24;
431
429
  var CURVE_HANDLE_MAX = 90;
432
- function drawNoteBody(g, w, h, colors, strokeWidth) {
433
- const f = 14;
434
- g.append("path").attr(
435
- "d",
436
- `M0 2 a2 2 0 0 1 2 -2 h${w - f - 2} l${f} ${f} v${h - f - 2} a2 2 0 0 1 -2 2 h-${w - 4} a2 2 0 0 1 -2 -2 Z`
437
- ).attr("fill", colors.fill).attr("stroke", colors.stroke).attr("stroke-width", strokeWidth);
438
- g.append("path").attr("d", `M${w - f} 0 v${f} h${f}`).attr("fill", "none").attr("stroke", colors.stroke).attr("stroke-width", 1.2);
439
- }
440
- function drawTypeBadge(g, kind, color, bx, by) {
441
- const b = g.append("g").attr("transform", `translate(${bx},${by})`).attr("fill", "none").attr("stroke", color).attr("stroke-width", 1.3).attr("stroke-linejoin", "round").attr("stroke-linecap", "round");
442
- switch (kind) {
443
- case "database":
444
- b.append("ellipse").attr("cx", 8).attr("cy", 3).attr("rx", 6).attr("ry", 2.4);
445
- b.append("path").attr("d", "M2 3 v10 a6 2.4 0 0 0 12 0 v-10");
446
- return;
447
- case "queue":
448
- b.append("path").attr("d", "M3 1 h8 a3 6.5 0 0 1 0 13 h-8 Z");
449
- b.append("ellipse").attr("cx", 3).attr("cy", 7.5).attr("rx", 3).attr("ry", 6.5);
450
- return;
451
- case "document":
452
- b.append("path").attr("d", "M2 1 h9 v11 q-4.5 2 -9 0 q0 0 0 0 Z");
453
- return;
454
- case "person":
455
- b.append("circle").attr("cx", 8).attr("cy", 5).attr("r", 3);
456
- b.append("path").attr("d", "M2 15 a6 5 0 0 1 12 0");
457
- return;
458
- default:
459
- return;
460
- }
461
- }
462
430
  var CARD_HEADER_H = SKETCH_VISUALS.cardHeaderHeight;
463
431
  var CARD_LABEL_MAX = SKETCH_VISUALS.nodeLabelFontSize;
464
432
  var CARD_LABEL_MIN = SKETCH_VISUALS.nodeLabelFontSizeMin;
@@ -476,7 +444,6 @@ function renderSketch(container, parsed, layout, palette, isDark, options = {})
476
444
  const sTitleFontSize = sctx.text(TITLE_FONT_SIZE2);
477
445
  const sEdgeLabelFontSize = sctx.text(EDGE_LABEL_FONT_SIZE);
478
446
  const sBandLabelFontSize = sctx.text(BAND_LABEL_FONT_SIZE);
479
- const sNoteFontSize = sctx.text(NOTE_FONT_SIZE);
480
447
  const sCardLabelMax = sctx.text(CARD_LABEL_MAX);
481
448
  const sCardLabelMin = sctx.text(CARD_LABEL_MIN);
482
449
  const sCardMetaFont = sctx.text(CARD_META_FONT);
@@ -497,8 +464,7 @@ function renderSketch(container, parsed, layout, palette, isDark, options = {})
497
464
  cardLabelMin: sCardLabelMin,
498
465
  cardMetaFont: sCardMetaFont,
499
466
  cardTitleMax: sCardTitleMax,
500
- bandLabelFontSize: sBandLabelFontSize,
501
- noteFontSize: sNoteFontSize
467
+ bandLabelFontSize: sBandLabelFontSize
502
468
  };
503
469
  const tagGroups = [...parsed.tagGroups];
504
470
  const activeName = resolveActiveTagGroup(
@@ -817,75 +783,20 @@ function drawNode(layer, node, colors, palette, isDark, splitCard, s) {
817
783
  void isDark;
818
784
  const g = layer.append("g").attr("class", node.isCollapsedBox ? "sk-node sk-box-collapsed" : "sk-node").attr("transform", `translate(${node.x},${node.y})`).attr("data-node-id", node.id).attr("data-line-number", node.lineNumber);
819
785
  for (const [k, v] of Object.entries(node.metadata)) {
820
- g.attr(`data-tag-${k}`, v);
786
+ g.attr(`data-tag-${tagAttrKey(k)}`, v);
821
787
  }
822
788
  if (node.isCollapsedBox) {
823
789
  g.attr("data-group-toggle", node.label);
824
790
  }
825
- if (node.shape === "note") {
826
- drawNoteBody(g, node.w, node.h, colors, s.nodeStrokeWidth);
827
- const lines = wrapTextToWidth(node.label, s.noteFontSize, node.w - 34);
828
- const lineHeight = s.noteFontSize + 4;
829
- lines.slice(0, 5).forEach((line, i) => {
830
- g.append("text").attr("x", 10).attr("y", 20 + i * lineHeight).attr("font-size", s.noteFontSize).attr("fill", colors.text).text(line);
831
- });
832
- } else {
833
- const badge = node.shape !== "rectangle";
834
- const labelInset = badge ? 22 : 0;
835
- const solidLike = colors.stroke === colors.fill;
836
- const ruleColor = solidLike ? colors.text : colors.stroke;
837
- if (!node.isCollapsedBox && (node.description || splitCard)) {
838
- const fitH = fitWrapped(
839
- node.label,
840
- node.w - 24 - labelInset,
841
- s.cardLabelMax,
842
- s.cardLabelMin,
843
- 1
844
- );
845
- renderNodeCard(g, {
846
- width: node.w,
847
- height: node.h,
848
- rx: s.cardRadius,
849
- fill: colors.fill,
850
- stroke: colors.stroke,
851
- strokeWidth: s.nodeStrokeWidth,
852
- label: fitH.lines[0] ?? node.label,
853
- labelColor: colors.text,
854
- labelFontSize: fitH.fontSize,
855
- headerHeight: s.cardHeaderH
856
- });
857
- g.append("line").attr("x1", 0).attr("y1", s.cardHeaderH).attr("x2", node.w).attr("y2", s.cardHeaderH).attr("stroke", ruleColor).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
858
- if (node.description) {
859
- const inset = 12;
860
- const bodyGap = 8;
861
- const lh = s.cardMetaFont + 4;
862
- const avail = node.h - s.cardHeaderH - bodyGap - 8;
863
- const body = g.append("g").attr("class", "sk-desc").attr("transform", `translate(${inset} ${s.cardHeaderH + bodyGap})`);
864
- const block = drawMarkdownBlock(body, node.description, {
865
- width: node.w - inset * 2,
866
- fontSize: s.cardMetaFont,
867
- lineHeight: lh,
868
- color: colors.text,
869
- // match the header label (contrast-aware in solid)
870
- linkColor: colors.text,
871
- maxLines: Math.max(1, Math.floor(avail / lh)),
872
- noEllipsis: true
873
- });
874
- if (block.total > block.shown) {
875
- g.append("text").attr("class", "sk-desc-more").attr("x", node.w - 8).attr("y", node.h - 5).attr("text-anchor", "end").attr("font-size", 9).attr("fill", palette.textMuted).attr("data-line-number", node.lineNumber).style("cursor", "pointer").text(`+${block.total - block.shown} more in source`);
876
- }
877
- }
878
- if (badge) {
879
- drawTypeBadge(g, node.shape, colors.text, 10, (s.cardHeaderH - 16) / 2);
880
- }
881
- return;
882
- }
883
- const fit = fitWrapped(
791
+ const solidLike = colors.stroke === colors.fill;
792
+ const ruleColor = solidLike ? colors.text : colors.stroke;
793
+ if (!node.isCollapsedBox && (node.description || splitCard)) {
794
+ const fitH = fitWrapped(
884
795
  node.label,
885
- node.w - 24 - labelInset,
886
- s.cardTitleMax,
796
+ node.w - 24,
797
+ s.cardLabelMax,
887
798
  s.cardLabelMin,
888
- 3
799
+ 1
889
800
  );
890
801
  renderNodeCard(g, {
891
802
  width: node.w,
@@ -894,16 +805,54 @@ function drawNode(layer, node, colors, palette, isDark, splitCard, s) {
894
805
  fill: colors.fill,
895
806
  stroke: colors.stroke,
896
807
  strokeWidth: s.nodeStrokeWidth,
897
- label: fit.lines.join(" "),
898
- labelLines: fit.lines,
808
+ label: fitH.lines[0] ?? node.label,
899
809
  labelColor: colors.text,
900
- labelFontSize: fit.fontSize,
901
- headerHeight: node.h
810
+ labelFontSize: fitH.fontSize,
811
+ headerHeight: s.cardHeaderH
902
812
  });
903
- if (badge) {
904
- drawTypeBadge(g, node.shape, colors.text, 10, (s.cardHeaderH - 16) / 2);
813
+ g.append("line").attr("x1", 0).attr("y1", s.cardHeaderH).attr("x2", node.w).attr("y2", s.cardHeaderH).attr("stroke", ruleColor).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
814
+ if (node.description) {
815
+ const inset = 12;
816
+ const bodyGap = 8;
817
+ const lh = s.cardMetaFont + 4;
818
+ const avail = node.h - s.cardHeaderH - bodyGap - 8;
819
+ const body = g.append("g").attr("class", "sk-desc").attr("transform", `translate(${inset} ${s.cardHeaderH + bodyGap})`);
820
+ const block = drawMarkdownBlock(body, node.description, {
821
+ width: node.w - inset * 2,
822
+ fontSize: s.cardMetaFont,
823
+ lineHeight: lh,
824
+ color: colors.text,
825
+ // match the header label (contrast-aware in solid)
826
+ linkColor: colors.text,
827
+ maxLines: Math.max(1, Math.floor(avail / lh)),
828
+ noEllipsis: true
829
+ });
830
+ if (block.total > block.shown) {
831
+ g.append("text").attr("class", "sk-desc-more").attr("x", node.w - 8).attr("y", node.h - 5).attr("text-anchor", "end").attr("font-size", 9).attr("fill", palette.textMuted).attr("data-line-number", node.lineNumber).style("cursor", "pointer").text(`+${block.total - block.shown} more in source`);
832
+ }
905
833
  }
834
+ return;
906
835
  }
836
+ const fit = fitWrapped(
837
+ node.label,
838
+ node.w - 24,
839
+ s.cardTitleMax,
840
+ s.cardLabelMin,
841
+ 3
842
+ );
843
+ renderNodeCard(g, {
844
+ width: node.w,
845
+ height: node.h,
846
+ rx: s.cardRadius,
847
+ fill: colors.fill,
848
+ stroke: colors.stroke,
849
+ strokeWidth: s.nodeStrokeWidth,
850
+ label: fit.lines.join(" "),
851
+ labelLines: fit.lines,
852
+ labelColor: colors.text,
853
+ labelFontSize: fit.fontSize,
854
+ headerHeight: node.h
855
+ });
907
856
  if (node.isCollapsedBox) {
908
857
  renderCollapseBar(g, {
909
858
  width: node.w,
@@ -1048,57 +997,70 @@ function hoppedPath(g, hops) {
1048
997
  const N = 49;
1049
998
  const pts = [];
1050
999
  for (let s = 0; s <= N; s++) pts.push(cubicAt(g, s / N));
1051
- const onSeg = /* @__PURE__ */ new Map();
1000
+ const cum = [0];
1001
+ for (let k2 = 1; k2 <= N; k2++) {
1002
+ const a = pts[k2 - 1];
1003
+ const b = pts[k2];
1004
+ cum.push(cum[k2 - 1] + Math.hypot(b.x - a.x, b.y - a.y));
1005
+ }
1006
+ const total = cum[N];
1007
+ const at = (len) => {
1008
+ let k2 = 1;
1009
+ while (k2 < N && cum[k2] < len) k2++;
1010
+ const a = pts[k2 - 1];
1011
+ const b = pts[k2];
1012
+ const span = cum[k2] - cum[k2 - 1] || 1;
1013
+ const f = Math.max(0, Math.min(1, (len - cum[k2 - 1]) / span));
1014
+ return { x: a.x + f * (b.x - a.x), y: a.y + f * (b.y - a.y) };
1015
+ };
1016
+ const centres = [];
1052
1017
  for (const hp of hops) {
1053
- let bestSeg = -1;
1054
1018
  let bestD = Infinity;
1055
- let bestPt = null;
1056
- for (let k = 1; k <= N; k++) {
1057
- const a = pts[k - 1];
1058
- const b = pts[k];
1019
+ let bestLen = 0;
1020
+ for (let k2 = 1; k2 <= N; k2++) {
1021
+ const a = pts[k2 - 1];
1022
+ const b = pts[k2];
1059
1023
  const dx = b.x - a.x;
1060
1024
  const dy = b.y - a.y;
1061
1025
  const len2 = dx * dx + dy * dy || 1;
1062
1026
  let f = ((hp.x - a.x) * dx + (hp.y - a.y) * dy) / len2;
1063
1027
  f = Math.max(0, Math.min(1, f));
1064
- const px = a.x + f * dx;
1065
- const py = a.y + f * dy;
1066
- const d2 = Math.hypot(hp.x - px, hp.y - py);
1028
+ const d2 = Math.hypot(hp.x - (a.x + f * dx), hp.y - (a.y + f * dy));
1067
1029
  if (d2 < bestD) {
1068
1030
  bestD = d2;
1069
- bestSeg = k;
1070
- bestPt = { x: px, y: py };
1031
+ bestLen = cum[k2 - 1] + f * (cum[k2] - cum[k2 - 1]);
1071
1032
  }
1072
1033
  }
1073
- if (bestSeg >= 3 && bestSeg <= N - 3 && bestPt && !onSeg.has(bestSeg))
1074
- onSeg.set(bestSeg, bestPt);
1034
+ centres.push(bestLen);
1035
+ }
1036
+ const clear = Math.max(2 * HOP_R, 3 * total / N);
1037
+ const kept = [];
1038
+ for (const c of centres.sort((x, y) => x - y)) {
1039
+ if (c < clear || c > total - clear) continue;
1040
+ if (kept.length > 0 && c - kept[kept.length - 1] < 2 * HOP_R) continue;
1041
+ kept.push(c);
1075
1042
  }
1076
- if (onSeg.size === 0) return null;
1043
+ if (kept.length === 0) return null;
1077
1044
  let d = `M ${pts[0].x} ${pts[0].y}`;
1078
- for (let k = 1; k <= N; k++) {
1079
- const a = pts[k - 1];
1080
- const b = pts[k];
1081
- const hp = onSeg.get(k);
1082
- if (hp) {
1083
- const segLen = Math.hypot(b.x - a.x, b.y - a.y) || 1;
1084
- const dir = { x: (b.x - a.x) / segLen, y: (b.y - a.y) / segLen };
1085
- let perp = { x: dir.y, y: -dir.x };
1086
- if (perp.y > 0) perp = { x: -perp.x, y: -perp.y };
1087
- const A = { x: hp.x - dir.x * HOP_R, y: hp.y - dir.y * HOP_R };
1088
- const B = { x: hp.x + dir.x * HOP_R, y: hp.y + dir.y * HOP_R };
1089
- const k1 = {
1090
- x: A.x + perp.x * HOP_R * 1.33,
1091
- y: A.y + perp.y * HOP_R * 1.33
1092
- };
1093
- const k2 = {
1094
- x: B.x + perp.x * HOP_R * 1.33,
1095
- y: B.y + perp.y * HOP_R * 1.33
1096
- };
1097
- d += ` L ${A.x} ${A.y} C ${k1.x} ${k1.y}, ${k2.x} ${k2.y}, ${B.x} ${B.y} L ${b.x} ${b.y}`;
1098
- } else {
1099
- d += ` L ${b.x} ${b.y}`;
1045
+ let k = 1;
1046
+ for (const c of kept) {
1047
+ const s0 = c - HOP_R;
1048
+ const s1 = c + HOP_R;
1049
+ while (k <= N && cum[k] < s0) {
1050
+ d += ` L ${pts[k].x} ${pts[k].y}`;
1051
+ k++;
1100
1052
  }
1053
+ const A = at(s0);
1054
+ const B = at(s1);
1055
+ const chord = Math.hypot(B.x - A.x, B.y - A.y) || 1;
1056
+ const dir = { x: (B.x - A.x) / chord, y: (B.y - A.y) / chord };
1057
+ let perp = { x: dir.y, y: -dir.x };
1058
+ if (perp.y > 0) perp = { x: -perp.x, y: -perp.y };
1059
+ const lift = chord / 2 * 1.33;
1060
+ d += ` L ${A.x} ${A.y} C ${A.x + perp.x * lift} ${A.y + perp.y * lift}, ${B.x + perp.x * lift} ${B.y + perp.y * lift}, ${B.x} ${B.y}`;
1061
+ while (k <= N && cum[k] <= s1) k++;
1101
1062
  }
1063
+ for (; k <= N; k++) d += ` L ${pts[k].x} ${pts[k].y}`;
1102
1064
  return d;
1103
1065
  }
1104
1066
  function pathCrossings(g, obstacles) {
@@ -1411,6 +1373,7 @@ function sketchEdgeGeometry(layout, offsets) {
1411
1373
  return out;
1412
1374
  };
1413
1375
  const hopsFor = layout.edges.map(() => []);
1376
+ const hopsOn = layout.edges.map(() => []);
1414
1377
  for (let i = 0; i < polys.length; i++) {
1415
1378
  for (let j = i + 1; j < polys.length; j++) {
1416
1379
  const a = polys[i];
@@ -1418,7 +1381,11 @@ function sketchEdgeGeometry(layout, offsets) {
1418
1381
  if (!a || !b) continue;
1419
1382
  if (!ctx[i]?.adjacent.has(j)) {
1420
1383
  const pt2 = polyIntersections(a, b)[0];
1421
- if (pt2) hopsFor[j].push(pt2);
1384
+ if (pt2) {
1385
+ hopsFor[j].push(pt2);
1386
+ hopsOn[i].push(pt2);
1387
+ hopsOn[j].push(pt2);
1388
+ }
1422
1389
  continue;
1423
1390
  }
1424
1391
  const ei = layout.edges[i];
@@ -1435,7 +1402,11 @@ function sketchEdgeGeometry(layout, offsets) {
1435
1402
  (q) => Math.hypot(p.x - q.x, p.y - q.y) > SHARED_END_CLEAR
1436
1403
  )
1437
1404
  );
1438
- if (pt) hopsFor[j].push(pt);
1405
+ if (pt) {
1406
+ hopsFor[j].push(pt);
1407
+ hopsOn[i].push(pt);
1408
+ hopsOn[j].push(pt);
1409
+ }
1439
1410
  }
1440
1411
  }
1441
1412
  return layout.edges.map((edge, i) => {
@@ -1448,6 +1419,7 @@ function sketchEdgeGeometry(layout, offsets) {
1448
1419
  d: g.d,
1449
1420
  mid: g.mid,
1450
1421
  ...dRender && { dRender },
1422
+ ...hopsOn[i].length > 0 && { hops: hopsOn[i] },
1451
1423
  p0: g.p0,
1452
1424
  h0: g.h0,
1453
1425
  h1: g.h1,
@@ -1455,6 +1427,22 @@ function sketchEdgeGeometry(layout, offsets) {
1455
1427
  };
1456
1428
  });
1457
1429
  }
1430
+ var HOP_LABEL_CLEAR = HOP_R + 2;
1431
+ function sketchLabelSpot(g, halfW, halfH) {
1432
+ const hops = g.hops ?? [];
1433
+ if (hops.length === 0) return g.mid;
1434
+ const clear = (p) => hops.every(
1435
+ (h) => Math.abs(p.x - h.x) >= halfW + HOP_LABEL_CLEAR || Math.abs(p.y - h.y) >= halfH + HOP_LABEL_CLEAR
1436
+ );
1437
+ if (clear(g.mid)) return g.mid;
1438
+ for (let step = 1; step <= 18; step++) {
1439
+ for (const t of [0.5 - step * 0.02, 0.5 + step * 0.02]) {
1440
+ const p = cubicAt(g, t);
1441
+ if (clear(p)) return p;
1442
+ }
1443
+ }
1444
+ return g.mid;
1445
+ }
1458
1446
  function renderSketchForExport(container, parsed, layout, palette, isDark, options = {}) {
1459
1447
  renderSketch(container, parsed, layout, palette, isDark, {
1460
1448
  ...options,
@@ -1472,5 +1460,6 @@ export {
1472
1460
  SKETCH_VISUALS,
1473
1461
  renderSketch,
1474
1462
  sketchEdgeGeometry,
1463
+ sketchLabelSpot,
1475
1464
  renderSketchForExport
1476
1465
  };
@@ -4,37 +4,37 @@ import {
4
4
  import {
5
5
  ScaleContext
6
6
  } from "./chunk-24YPR5EH.js";
7
+ import {
8
+ keepSwimlaneToggleFocus,
9
+ renderIntegratedLegend,
10
+ wireSwimlaneToggle
11
+ } from "./chunk-NJYA4QSN.js";
7
12
  import {
8
13
  CARD_RADIUS
9
14
  } from "./chunk-XCKNFFKM.js";
10
15
  import {
11
16
  serializeSvg
12
17
  } from "./chunk-OOCVGX4W.js";
18
+ import {
19
+ getMaxLegendReservedHeight
20
+ } from "./chunk-NS7L7YKH.js";
13
21
  import {
14
22
  TITLE_FONT_SIZE,
15
23
  TITLE_FONT_WEIGHT
16
24
  } from "./chunk-VLC6WNRD.js";
17
- import {
18
- keepSwimlaneToggleFocus,
19
- renderIntegratedLegend,
20
- wireSwimlaneToggle
21
- } from "./chunk-7SX4IY6T.js";
22
- import {
23
- getMaxLegendReservedHeight
24
- } from "./chunk-NS7L7YKH.js";
25
25
  import {
26
26
  FONT_FAMILY
27
27
  } from "./chunk-ICLB27PZ.js";
28
28
  import {
29
29
  parseKanban
30
- } from "./chunk-DPSMX4EY.js";
30
+ } from "./chunk-IRVQT4GR.js";
31
31
  import {
32
32
  tagAttrKey
33
- } from "./chunk-L5AFONQU.js";
33
+ } from "./chunk-HX2KJEPD.js";
34
34
  import {
35
35
  fillModeFromOptions,
36
36
  legendSuppressed
37
- } from "./chunk-44GP7PD5.js";
37
+ } from "./chunk-MPJQMMBZ.js";
38
38
  import {
39
39
  LEGEND_HEIGHT,
40
40
  measureLegendText
@@ -670,7 +670,7 @@ function drawKanban(container, parsed, palette, isDark, options) {
670
670
  const tagKey = tagAttrKey(activeTagGroup);
671
671
  const tagValue = card.tags[tagKey];
672
672
  const group = parsed.tagGroups.find(
673
- (tg) => tg.name.toLowerCase() === tagKey
673
+ (tg) => tagAttrKey(tg.name) === tagKey
674
674
  );
675
675
  const value = tagValue ?? group?.defaultValue;
676
676
  if (value) {
@@ -1137,7 +1137,7 @@ function renderSwimlaneCard(parent, cardLayout, tagGroups, activeTagGroup, palet
1137
1137
  const cg = parent.append("g").attr("class", "kanban-card").attr("data-card-id", card.id).attr("data-line-number", card.lineNumber);
1138
1138
  if (activeTagGroup) {
1139
1139
  const tagKey = tagAttrKey(activeTagGroup);
1140
- const group = tagGroups.find((tg) => tg.name.toLowerCase() === tagKey);
1140
+ const group = tagGroups.find((tg) => tagAttrKey(tg.name) === tagKey);
1141
1141
  const value = card.tags[tagKey] ?? group?.defaultValue;
1142
1142
  if (value) {
1143
1143
  cg.attr(`data-tag-${tagKey}`, value.toLowerCase());