@diagrammo/dgmo 0.48.2 → 0.50.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 (244) hide show
  1. package/.cursorrules +12 -3
  2. package/.github/copilot-instructions.md +12 -3
  3. package/.windsurfrules +12 -3
  4. package/SKILL.md +12 -3
  5. package/dist/advanced.d.ts +851 -1
  6. package/dist/advanced.js +601 -177
  7. package/dist/auto.css +63 -0
  8. package/dist/auto.js +220 -110
  9. package/dist/auto.mjs +45920 -33167
  10. package/dist/block.css +63 -0
  11. package/dist/block.d.ts +13 -5
  12. package/dist/block.js +239 -62
  13. package/dist/{charts-d3-QOZHKTCT.js → charts-d3-DKUD7MQE.js} +9 -8
  14. package/dist/{chunk-3MQQNXPD.js → chunk-2C56LEML.js} +3 -3
  15. package/dist/{chunk-L66GEFB6.js → chunk-2JJ2KNPI.js} +4 -4
  16. package/dist/{chunk-6SM5NJQH.js → chunk-2QYTMIRR.js} +4 -4
  17. package/dist/{chunk-RJE5JTVK.js → chunk-3G6TMNVF.js} +7 -7
  18. package/dist/{chunk-MO5YHHMQ.js → chunk-3LKM6FMW.js} +2 -2
  19. package/dist/{chunk-76OWZ3BA.js → chunk-3P2DKJCG.js} +2 -2
  20. package/dist/chunk-3TDRHT4J.js +1043 -0
  21. package/dist/chunk-3XPUDB7B.js +420 -0
  22. package/dist/{chunk-2LACINWN.js → chunk-3ZPC476N.js} +7 -7
  23. package/dist/{chunk-G2H74XJZ.js → chunk-4BMJQFNK.js} +8 -8
  24. package/dist/{chunk-THXCFRTU.js → chunk-4S723I74.js} +9 -9
  25. package/dist/{chunk-6NYWYNBI.js → chunk-4XK3FLFB.js} +3 -3
  26. package/dist/chunk-5JSWBPZZ.js +607 -0
  27. package/dist/{chunk-WCT3NYCV.js → chunk-5LWQH6QV.js} +1 -1
  28. package/dist/{chunk-7DTWEFUE.js → chunk-5Z736BSU.js} +8 -8
  29. package/dist/{chunk-ERLBPDGU.js → chunk-6BFZKBGD.js} +2 -2
  30. package/dist/{chunk-6HO5ZTXK.js → chunk-6IAA2QQ2.js} +2 -2
  31. package/dist/{chunk-H6PI3KJT.js → chunk-6IUAK7RZ.js} +2 -2
  32. package/dist/{chunk-RTLBSQ3G.js → chunk-6M5PJFQG.js} +3 -3
  33. package/dist/{chunk-Z5CGSFJB.js → chunk-6X4AKWLF.js} +4 -4
  34. package/dist/{chunk-OJR3MQYV.js → chunk-6ZT4U37Q.js} +291 -52
  35. package/dist/{chunk-5QXL4NYS.js → chunk-7G2ER4CY.js} +10 -5
  36. package/dist/chunk-7PQYTZMA.js +681 -0
  37. package/dist/{chunk-OURHMODR.js → chunk-7RB5Q6MB.js} +11 -11
  38. package/dist/{chunk-YAA6IID3.js → chunk-7UEMZREK.js} +2 -2
  39. package/dist/{chunk-AN2MOO5T.js → chunk-A3WQVFBS.js} +3 -3
  40. package/dist/{chunk-VOKGH627.js → chunk-AHGF2YYA.js} +13 -3
  41. package/dist/{chunk-CI2G3OEB.js → chunk-ASS5YYIZ.js} +12 -12
  42. package/dist/{chunk-TYS6CSS5.js → chunk-BCYVE3N5.js} +2 -2
  43. package/dist/chunk-BDXC7MDK.js +2395 -0
  44. package/dist/chunk-BTUTZMPT.js +482 -0
  45. package/dist/{chunk-YGJTDXVR.js → chunk-C4GQDB5L.js} +2 -2
  46. package/dist/{chunk-Y2ZE3MSG.js → chunk-C63UWAKM.js} +2 -2
  47. package/dist/{chunk-725LDASD.js → chunk-CLD2OKV7.js} +2 -2
  48. package/dist/{chunk-WBRZJOEC.js → chunk-CMCR5WBW.js} +3 -3
  49. package/dist/{chunk-IZMRON6C.js → chunk-CVV36CWI.js} +2 -2
  50. package/dist/chunk-DMJJ3CEQ.js +254 -0
  51. package/dist/{chunk-MZSBFAPJ.js → chunk-EJTKV7CY.js} +9 -9
  52. package/dist/{chunk-FITOLXSX.js → chunk-EOFPYPAU.js} +26 -2
  53. package/dist/{chunk-X5LCYCL5.js → chunk-ER5SCQWQ.js} +5 -5
  54. package/dist/{chunk-4OHACBGX.js → chunk-F2L5GCQ4.js} +2 -2
  55. package/dist/{chunk-FCIIHT24.js → chunk-F5UDBSJY.js} +7 -7
  56. package/dist/{chunk-3JLKYGBQ.js → chunk-F7BFXWNQ.js} +2 -2
  57. package/dist/{chunk-FANX6UJR.js → chunk-FAL7NOK3.js} +11 -11
  58. package/dist/{chunk-BUPDIHML.js → chunk-FB2WHOEQ.js} +4 -4
  59. package/dist/chunk-FL4IOQ37.js +379 -0
  60. package/dist/{chunk-LIOHW36Z.js → chunk-GBE54KY6.js} +6 -5
  61. package/dist/{chunk-RUNNI6VE.js → chunk-GL5UZ6NY.js} +3 -3
  62. package/dist/{chunk-4GRI7MEB.js → chunk-GPWHQ5FJ.js} +6 -6
  63. package/dist/chunk-GROQGHCT.js +960 -0
  64. package/dist/{chunk-SGZYXELT.js → chunk-H73FP42Q.js} +9 -6
  65. package/dist/{chunk-PBAHEPLQ.js → chunk-HGN652MU.js} +7 -6
  66. package/dist/{chunk-3SMGIJDD.js → chunk-HHXOONLX.js} +13 -1
  67. package/dist/{chunk-QOOUC2J5.js → chunk-HQCHYB5F.js} +2 -2
  68. package/dist/{chunk-AELOBFW5.js → chunk-I4IFRCUB.js} +3 -3
  69. package/dist/{chunk-GMR5MFHJ.js → chunk-I7F2A35O.js} +2 -2
  70. package/dist/{chunk-T2OE3YQB.js → chunk-IA3FJYWR.js} +3 -3
  71. package/dist/chunk-IAEC4KLA.js +492 -0
  72. package/dist/chunk-IVKC4GID.js +32 -0
  73. package/dist/{chunk-HSH73DP6.js → chunk-JFYIP7XU.js} +139 -39
  74. package/dist/{chunk-CKNVO24D.js → chunk-JZNMXEIV.js} +2 -2
  75. package/dist/chunk-KJXIHOVL.js +940 -0
  76. package/dist/chunk-L2ZTFHAY.js +331 -0
  77. package/dist/{chunk-B7JUCQUA.js → chunk-M5RXSRO2.js} +4 -4
  78. package/dist/{chunk-ULOEATBZ.js → chunk-NFFIKVNO.js} +106 -29
  79. package/dist/{chunk-PZMETGLY.js → chunk-NISQC5KW.js} +358 -122
  80. package/dist/chunk-O4VUFXIH.js +574 -0
  81. package/dist/{chunk-RVMRZAPB.js → chunk-O76UD6VJ.js} +3 -3
  82. package/dist/{chunk-JM4LEPY3.js → chunk-O7NUCTFU.js} +2 -2
  83. package/dist/{chunk-JED6ZDEE.js → chunk-O7WP4ZD4.js} +2 -2
  84. package/dist/{chunk-EVCVDTXE.js → chunk-OHQEMBLI.js} +3 -3
  85. package/dist/{chunk-ZBWMSD5N.js → chunk-ONA5KPV3.js} +4 -4
  86. package/dist/{chunk-Y3J7VR52.js → chunk-OTAL43EH.js} +34 -2
  87. package/dist/{chunk-WCSOJFU3.js → chunk-OTP5KVLO.js} +3 -3
  88. package/dist/{chunk-RYEGFMUO.js → chunk-PGEGPSCZ.js} +2 -2
  89. package/dist/{chunk-ZO27FGJS.js → chunk-PH5X4GIP.js} +2 -2
  90. package/dist/{chunk-ZJEL4H2R.js → chunk-PJUGRJHJ.js} +9 -9
  91. package/dist/{chunk-ZGR7ULFJ.js → chunk-PLZI6KPM.js} +26 -14
  92. package/dist/{chunk-3R5POCTZ.js → chunk-PMN3Q7RJ.js} +6 -6
  93. package/dist/{chunk-YGJZWZTY.js → chunk-PZFVK3IH.js} +2 -2
  94. package/dist/chunk-Q4V4XQWV.js +158 -0
  95. package/dist/chunk-QDFNCATJ.js +325 -0
  96. package/dist/{chunk-QEBUY5NY.js → chunk-QFQ35BTO.js} +4 -4
  97. package/dist/chunk-QQJUTGQH.js +135 -0
  98. package/dist/{chunk-PWIHZ6NJ.js → chunk-QUJGFNFN.js} +4 -4
  99. package/dist/{chunk-J5FIXQRT.js → chunk-R56LASIN.js} +4 -4
  100. package/dist/{chunk-SRTU6HMQ.js → chunk-RV26LTUU.js} +8 -8
  101. package/dist/chunk-RV6A2B5S.js +354 -0
  102. package/dist/{chunk-EB6FPQUP.js → chunk-S5GRONXL.js} +3 -3
  103. package/dist/{chunk-5MLYVTYM.js → chunk-SCHXJTZL.js} +2 -2
  104. package/dist/{chunk-T3UBLACL.js → chunk-SCQ5VPUF.js} +19 -5
  105. package/dist/{chunk-PBHE5UG6.js → chunk-SGFZZAUO.js} +46 -12
  106. package/dist/{chunk-BUVJFRPY.js → chunk-SU2VBK4L.js} +4 -4
  107. package/dist/{chunk-SML67VPV.js → chunk-T4BRO3Z6.js} +3 -3
  108. package/dist/{chunk-NURGB5Z4.js → chunk-TSA237IM.js} +2 -2
  109. package/dist/chunk-TWCLK2GA.js +273 -0
  110. package/dist/{chunk-IJZFN3HM.js → chunk-TWQUYVP3.js} +4 -4
  111. package/dist/{chunk-DKEPS5LH.js → chunk-U2HGPLZS.js} +36 -2
  112. package/dist/{chunk-B65G5DNL.js → chunk-URSQLCTR.js} +3 -3
  113. package/dist/{chunk-ILKORZ3H.js → chunk-UUS2GIJZ.js} +7 -7
  114. package/dist/{chunk-XAKEUMEJ.js → chunk-UXOSVCLJ.js} +4 -4
  115. package/dist/{chunk-QLCCJEJI.js → chunk-WCUHAQKB.js} +2 -2
  116. package/dist/{chunk-WVAJFAIA.js → chunk-WWN566I7.js} +257 -101
  117. package/dist/{chunk-IPWPWM6R.js → chunk-X2NMFTG3.js} +111 -10
  118. package/dist/{chunk-UWN33VNX.js → chunk-XCLHOZAM.js} +10 -10
  119. package/dist/{chunk-P235SVAH.js → chunk-XDXNDSKO.js} +2 -2
  120. package/dist/chunk-XHVV4NVW.js +51 -0
  121. package/dist/{chunk-33LCUH4H.js → chunk-XMVQ5F4M.js} +4 -4
  122. package/dist/{chunk-MITI6NOL.js → chunk-YA7D2N2O.js} +11 -11
  123. package/dist/{chunk-7JEGTRLD.js → chunk-YB3FW24O.js} +3 -3
  124. package/dist/chunk-YNRDWYZP.js +295 -0
  125. package/dist/{chunk-44CM72SQ.js → chunk-YZLMKW4T.js} +3 -3
  126. package/dist/chunk-Z6XJQ6KO.js +452 -0
  127. package/dist/cli.cjs +179 -133
  128. package/dist/clock.d.ts +10 -0
  129. package/dist/clock.js +235 -0
  130. package/dist/countdown.d.ts +12 -0
  131. package/dist/countdown.js +450 -0
  132. package/dist/dgmo-router-QOMFCOOV.js +84 -0
  133. package/dist/dimensions-P5FSX2QN.js +22 -0
  134. package/dist/editor.js +43 -2
  135. package/dist/element.js +220 -110
  136. package/dist/element.mjs +45920 -33167
  137. package/dist/{flowchart-parser-ZNSKIBVR.js → flowchart-parser-OE4WHLTF.js} +4 -4
  138. package/dist/{flowchart-renderer-SNDSII4D.js → flowchart-renderer-GPCSMTOR.js} +8 -8
  139. package/dist/highlight.d.ts +17 -1
  140. package/dist/highlight.js +163 -6
  141. package/dist/index.d.ts +5 -1
  142. package/dist/index.js +199 -233
  143. package/dist/{layout-HRBZPFCN.js → layout-34CLNICW.js} +5 -5
  144. package/dist/layout-46366KBT.js +10 -0
  145. package/dist/{layout-HWDSRX5E.js → layout-5BG6DFCU.js} +6 -6
  146. package/dist/layout-6RDJHS6E.js +9 -0
  147. package/dist/{layout-7QXCNOVS.js → layout-7H4H46CS.js} +3 -3
  148. package/dist/{layout-46N4JJYK.js → layout-7SKMFYHL.js} +5 -5
  149. package/dist/{layout-EE6GE46Y.js → layout-DC4TVXER.js} +5 -5
  150. package/dist/layout-FGQWRYYW.js +14 -0
  151. package/dist/{layout-S2QBYSK2.js → layout-NXG63LWH.js} +3 -3
  152. package/dist/{layout-N76NR4ZO.js → layout-PUQCB6AN.js} +7 -7
  153. package/dist/{layout-HYZPWAK5.js → layout-QNUQLEHU.js} +3 -3
  154. package/dist/{layout-UM5F4DJB.js → layout-T3OZU5QW.js} +5 -5
  155. package/dist/layout-TJIWF7EM.js +14 -0
  156. package/dist/layout-VYELEAW7.js +14 -0
  157. package/dist/{layout-5RA6QWR6.js → layout-WZHNDT2O.js} +6 -6
  158. package/dist/{layout-search-OYV77HHS.js → layout-search-QS44PI5R.js} +6 -6
  159. package/dist/{parser-6BTRLKRZ.js → parser-45DENHFZ.js} +4 -4
  160. package/dist/{parser-TFZFBVWN.js → parser-4AI5ZN5F.js} +3 -3
  161. package/dist/{parser-XDVELHRK.js → parser-4P36TUVD.js} +4 -4
  162. package/dist/{parser-ZSDPZYQP.js → parser-5AURY4A6.js} +4 -4
  163. package/dist/{parser-N5O4IHUN.js → parser-A2BEFMGK.js} +4 -4
  164. package/dist/parser-B5FVS7O6.js +11 -0
  165. package/dist/{parser-NGU3ETO6.js → parser-C2HF2C2E.js} +4 -4
  166. package/dist/parser-CSFUN3CT.js +14 -0
  167. package/dist/{parser-TRTHDFPP.js → parser-D3QT6GWN.js} +5 -5
  168. package/dist/parser-D5637H5H.js +15 -0
  169. package/dist/{parser-VQP2UJ6W.js → parser-DFFEDKHH.js} +3 -3
  170. package/dist/parser-DOKMZXVZ.js +13 -0
  171. package/dist/parser-FMPCVFRK.js +15 -0
  172. package/dist/{parser-Y6WTBU76.js → parser-HYRTF3DO.js} +3 -3
  173. package/dist/{parser-I6KXEYFK.js → parser-I2UIJKVQ.js} +4 -4
  174. package/dist/{parser-O5J4VBII.js → parser-IBWNAPY4.js} +3 -3
  175. package/dist/{parser-PQ3POX45.js → parser-KUQWRPIT.js} +4 -4
  176. package/dist/{parser-2MFP2H2E.js → parser-LWKKBNSA.js} +3 -3
  177. package/dist/{parser-OV7NOBW6.js → parser-O4QFCUW7.js} +5 -5
  178. package/dist/{parser-IXSZZQHY.js → parser-PGMQDD4G.js} +4 -4
  179. package/dist/{parser-3STE62GB.js → parser-Q4QKCIWQ.js} +4 -4
  180. package/dist/parser-QTOB4KFL.js +14 -0
  181. package/dist/{parser-2EWECDSA.js → parser-QYYM4QVW.js} +4 -4
  182. package/dist/{parser-4OGOBJJ4.js → parser-RZMQP7MM.js} +4 -4
  183. package/dist/parser-RZPVAQVX.js +11 -0
  184. package/dist/parser-SOUJOEYI.js +13 -0
  185. package/dist/{parser-4FL2CMDG.js → parser-UQE5OWZI.js} +5 -5
  186. package/dist/{parser-NRAI6O25.js → parser-WAV5JRPT.js} +4 -4
  187. package/dist/{parser-KNSQSKQO.js → parser-YLKYBRIT.js} +5 -5
  188. package/dist/{parser-XKRP7QKP.js → parser-YS7TOS2K.js} +3 -3
  189. package/dist/{parser-AQETEVRW.js → parser-ZSOWUBML.js} +5 -5
  190. package/dist/{parser-CFZD5IBL.js → parser-ZTBATMLX.js} +4 -4
  191. package/dist/{renderer-VACVQYML.js → renderer-35HSIDMZ.js} +8 -8
  192. package/dist/{renderer-5MYBMBYO.js → renderer-4ITCHBT7.js} +5 -5
  193. package/dist/{renderer-CLJHQPBJ.js → renderer-67NPCBIS.js} +11 -11
  194. package/dist/{renderer-5NDVNDAZ.js → renderer-6GHYK7DX.js} +9 -9
  195. package/dist/{renderer-Z7I3W2PP.js → renderer-6RNGHC5Z.js} +8 -8
  196. package/dist/renderer-72LGR2YF.js +14 -0
  197. package/dist/{renderer-KQB7UGDS.js → renderer-7RH2SI3B.js} +3 -3
  198. package/dist/renderer-7SWMIFMM.js +21 -0
  199. package/dist/renderer-BBCEFILK.js +24 -0
  200. package/dist/{renderer-JGBKUCZD.js → renderer-BSW7SRIZ.js} +4 -4
  201. package/dist/{renderer-BYCNMBF7.js → renderer-BY533UWU.js} +11 -11
  202. package/dist/{renderer-6W5462RB.js → renderer-BZSBPTZJ.js} +9 -9
  203. package/dist/{renderer-7MVLWWQD.js → renderer-CXUC4KAD.js} +9 -9
  204. package/dist/{renderer-QIWVHWZO.js → renderer-DAXMXIKD.js} +3 -3
  205. package/dist/renderer-FZUKFUNZ.js +23 -0
  206. package/dist/renderer-G2NLGNKF.js +17 -0
  207. package/dist/renderer-GO3FE3RA.js +24 -0
  208. package/dist/{renderer-ZGNTUWC4.js → renderer-HPGR6USK.js} +8 -8
  209. package/dist/{renderer-UV6MI64M.js → renderer-HVCU2C3Z.js} +3 -3
  210. package/dist/renderer-ICJN2SA2.js +24 -0
  211. package/dist/{renderer-AWWAF6XD.js → renderer-INEXO7B6.js} +10 -10
  212. package/dist/{renderer-YY2OSF6E.js → renderer-KDYCFRBX.js} +8 -8
  213. package/dist/renderer-KY4KQBTF.js +19 -0
  214. package/dist/{renderer-B2OMQIQG.js → renderer-LBN65V45.js} +13 -13
  215. package/dist/{renderer-N43WR5GV.js → renderer-MGBWOCXG.js} +10 -10
  216. package/dist/{renderer-PGX2TKVS.js → renderer-O4JKUGKO.js} +8 -8
  217. package/dist/{renderer-4JHRUBE6.js → renderer-OOGFODWP.js} +10 -10
  218. package/dist/{renderer-6EEZHMH4.js → renderer-Q6ZKPLS6.js} +9 -9
  219. package/dist/{renderer-RPOA5YPZ.js → renderer-SZQ326M5.js} +12 -12
  220. package/dist/{renderer-ZRNG54CW.js → renderer-TKG6LS4U.js} +11 -11
  221. package/dist/{renderer-W4M6QLIJ.js → renderer-TQMZGDAX.js} +13 -13
  222. package/dist/renderer-radial-JELMHQ24.js +21 -0
  223. package/dist/{resolver-NOAA7ID7.js → resolver-FHBCO3PL.js} +3 -3
  224. package/dist/{state-parser-Z2V23ATR.js → state-parser-3REXRK3R.js} +4 -4
  225. package/dist/{state-renderer-B4DQBM6M.js → state-renderer-XYLNRWXR.js} +8 -8
  226. package/docs/ai-integration.md +12 -3
  227. package/docs/language-reference.md +429 -24
  228. package/gallery/fixtures/body.dgmo +17 -0
  229. package/gallery/fixtures/bracket.dgmo +30 -0
  230. package/gallery/fixtures/clock.dgmo +8 -0
  231. package/gallery/fixtures/countdown.dgmo +3 -0
  232. package/gallery/fixtures/family.dgmo +23 -0
  233. package/gallery/fixtures/goal.dgmo +4 -0
  234. package/gallery/fixtures/sketch.dgmo +22 -0
  235. package/package.json +12 -4
  236. package/dist/chunk-ODZVHU3R.js +0 -153
  237. package/dist/dgmo-router-X35VLZLM.js +0 -73
  238. package/dist/dimensions-J3FHIMJ6.js +0 -22
  239. package/dist/layout-5T6RH5M6.js +0 -14
  240. package/dist/layout-G23F7LDH.js +0 -9
  241. package/dist/layout-OB3RI63S.js +0 -14
  242. package/dist/parser-JAL2HD4I.js +0 -13
  243. package/dist/renderer-SMIBCRVB.js +0 -24
  244. package/dist/renderer-radial-C32GPJQ7.js +0 -21
@@ -4,12 +4,12 @@ import {
4
4
  matchTagBlockHeading,
5
5
  stripDefaultModifier,
6
6
  tagAttrKey
7
- } from "./chunk-QLCCJEJI.js";
7
+ } from "./chunk-WCUHAQKB.js";
8
8
  import {
9
9
  extractColor,
10
10
  measureIndent,
11
11
  parseFirstLine
12
- } from "./chunk-Y3J7VR52.js";
12
+ } from "./chunk-OTAL43EH.js";
13
13
  import {
14
14
  emit
15
15
  } from "./chunk-CXK4DZH3.js";
@@ -22,10 +22,9 @@ var SWIMLANE_DX = {
22
22
  chartType: "swimlane",
23
23
  title: "Duplicate node",
24
24
  message: (p) => `Duplicate node name '${p.name ?? "Foo"}'`,
25
- hint: "Every node name must be unique across the diagram \u2014 rename or remove the second declaration.",
25
+ hint: "Within a lane a node name must be unique \u2014 rename or remove the second declaration (different lanes may reuse a name).",
26
26
  example: `swimlane T
27
27
  lane L
28
- L
29
28
  Foo
30
29
  Foo`
31
30
  },
@@ -35,12 +34,23 @@ L
35
34
  chartType: "swimlane",
36
35
  title: "Unknown node in edge",
37
36
  message: (p) => `Edge references unknown node '${p.node ?? "Bar"}'`,
38
- hint: "Declare the node under a lane before referencing it in a flow arrow.",
37
+ hint: "A bare-task target must be declared as a line-head in some lane; delimited endpoints ((\u2026)/<\u2026>/[[\u2026]]) auto-create. Check for a typo, or qualify a cross-lane name as Lane.Node.",
39
38
  example: `swimlane T
40
39
  lane L
41
- L
42
- Foo
43
- Foo -> Bar`
40
+ Foo -> Bar`
41
+ },
42
+ AMBIGUOUS_NODE: {
43
+ code: "E_SWIMLANE_AMBIGUOUS_NODE",
44
+ severity: "warning",
45
+ chartType: "swimlane",
46
+ title: "Ambiguous node reference",
47
+ message: (p) => `Node '${p.node ?? "Review"}' is declared in more than one lane${p.lanes ? ` (${p.lanes})` : ""} \u2014 qualify it as Lane.${p.node ?? "Review"}`,
48
+ hint: "Two lanes hold a node with this name. Prefix the reference with its lane (`Customs.Inspect`) to pick one; resolved to the first match otherwise.",
49
+ example: `swimlane T
50
+ lane Customs
51
+ Customs.Inspect -> Harbor.Inspect
52
+ lane Harbor
53
+ Harbor.Inspect`
44
54
  },
45
55
  UNKNOWN_LANE: {
46
56
  code: "E_SWIMLANE_UNKNOWN_LANE",
@@ -205,7 +215,6 @@ function parseSwimlane(content, palette) {
205
215
  const tagGroups = [];
206
216
  const laneByKey = /* @__PURE__ */ new Map();
207
217
  const phaseByKey = /* @__PURE__ */ new Map();
208
- const nodeByKey = /* @__PURE__ */ new Map();
209
218
  const metaAliasMap = /* @__PURE__ */ new Map();
210
219
  const options = {};
211
220
  let direction = "LR";
@@ -299,7 +308,7 @@ function parseSwimlane(content, palette) {
299
308
  }
300
309
  continue;
301
310
  }
302
- if (indent === 0 && /^lane\s+/i.test(trimmed)) {
311
+ if (/^lane\s+/i.test(trimmed)) {
303
312
  const rest = trimmed.replace(/^lane\s+/i, "").trim();
304
313
  const { label, color } = extractColor(
305
314
  rest,
@@ -321,39 +330,22 @@ function parseSwimlane(content, palette) {
321
330
  }
322
331
  if (indent === 0 && !trimmed.startsWith("tag ")) sawContent = true;
323
332
  }
324
- let currentPhase = null;
325
- let currentLane = null;
326
- let laneIndent = -1;
327
- let currentFlowSource = null;
328
- const declareNode = (token, meta, lineNum) => {
329
- const parsed = parseNodeToken(token);
330
- if (parsed.unsupported) {
331
- diagnostics.push(
332
- emit(SWIMLANE_DX.UNSUPPORTED, lineNum, { reason: parsed.unsupported })
333
- );
334
- return;
335
- }
336
- if (!parsed.label) return;
337
- if (!currentLane) {
338
- diagnostics.push(
339
- emit(SWIMLANE_DX.UNKNOWN_LANE, lineNum, { node: parsed.label })
340
- );
341
- return;
333
+ const drafts = [];
334
+ const draftByKey = /* @__PURE__ */ new Map();
335
+ const draftsByLabel = /* @__PURE__ */ new Map();
336
+ const rawEdges = [];
337
+ const laneKey = (laneId, label) => `${normKey(laneId)}\0${normKey(label)}`;
338
+ const splitQualifier = (token) => {
339
+ const t = token.trim();
340
+ if (/^[<([]/.test(t)) return { rest: t };
341
+ const dot = t.indexOf(".");
342
+ if (dot > 0) {
343
+ const lane = laneByKey.get(normKey(t.slice(0, dot)));
344
+ if (lane) return { laneId: lane.id, rest: t.slice(dot + 1).trim() };
342
345
  }
343
- const { label: cleanLabel, color } = extractColor(
344
- parsed.label,
345
- palette,
346
- diagnostics,
347
- lineNum
348
- );
349
- const key = normKey(cleanLabel);
350
- if (nodeByKey.has(key)) {
351
- diagnostics.push(
352
- emit(SWIMLANE_DX.DUPLICATE_NODE, lineNum, { name: cleanLabel })
353
- );
354
- return;
355
- }
356
- const tags = {};
346
+ return { rest: t };
347
+ };
348
+ const applyMeta = (draft, meta, lineNum) => {
357
349
  for (const [k, v] of Object.entries(meta)) {
358
350
  if (k === "note") {
359
351
  diagnostics.push(
@@ -380,75 +372,147 @@ function parseSwimlane(content, palette) {
380
372
  continue;
381
373
  }
382
374
  const canonical = metaAliasMap.get(k) ?? k;
383
- tags[canonical] = v;
375
+ draft.tags[canonical] = v;
384
376
  }
385
- const node = {
377
+ };
378
+ const registerDraft = (draft) => {
379
+ draftByKey.set(laneKey(draft.laneId, draft.label), draft);
380
+ const nk = normKey(draft.label);
381
+ (draftsByLabel.get(nk) ?? draftsByLabel.set(nk, []).get(nk)).push(draft);
382
+ drafts.push(draft);
383
+ };
384
+ const mergeDraft = (draft, parsed, color) => {
385
+ if (draft.shape === "task" && parsed.shape !== "task")
386
+ draft.shape = parsed.shape;
387
+ if (draft.event === "none" && parsed.event !== "none")
388
+ draft.event = parsed.event;
389
+ if (draft.color === void 0 && color !== void 0) draft.color = color;
390
+ };
391
+ const declareInLane = (rawText, laneId, phaseId, bare, lineNum) => {
392
+ const { token, meta } = splitNodeMeta(rawText);
393
+ const { rest } = splitQualifier(token);
394
+ const parsed = parseNodeToken(rest);
395
+ if (parsed.unsupported) {
396
+ diagnostics.push(
397
+ emit(SWIMLANE_DX.UNSUPPORTED, lineNum, { reason: parsed.unsupported })
398
+ );
399
+ return null;
400
+ }
401
+ if (!parsed.label) return null;
402
+ const { label: cleanLabel, color } = extractColor(
403
+ parsed.label,
404
+ palette,
405
+ diagnostics,
406
+ lineNum
407
+ );
408
+ const key = laneKey(laneId, cleanLabel);
409
+ const existing = draftByKey.get(key);
410
+ if (existing) {
411
+ if (bare && existing.hasBareDecl) {
412
+ diagnostics.push(
413
+ emit(SWIMLANE_DX.DUPLICATE_NODE, lineNum, { name: cleanLabel })
414
+ );
415
+ return existing;
416
+ }
417
+ mergeDraft(existing, parsed, color);
418
+ if (bare) existing.hasBareDecl = true;
419
+ if (existing.phaseId === void 0 && phaseId !== void 0)
420
+ existing.phaseId = phaseId;
421
+ applyMeta(existing, meta, lineNum);
422
+ return existing;
423
+ }
424
+ const draft = {
386
425
  id: cleanLabel,
387
426
  label: cleanLabel,
427
+ laneId,
428
+ ...phaseId !== void 0 && { phaseId },
388
429
  shape: parsed.shape,
389
430
  event: parsed.event,
390
- lane: currentLane.id,
391
- ...currentPhase && { phase: currentPhase.id },
392
431
  ...color !== void 0 && { color },
393
- tags,
394
- lineNumber: lineNum
432
+ tags: {},
433
+ lineNumber: lineNum,
434
+ hasBareDecl: bare
395
435
  };
396
- nodes.push(node);
397
- nodeByKey.set(key, node);
436
+ applyMeta(draft, meta, lineNum);
437
+ registerDraft(draft);
438
+ return draft;
398
439
  };
399
- const resolveRef = (token, lineNum) => {
400
- const parsed = parseNodeToken(token);
440
+ const resolveEndpoint = (rawText, laneId, phaseId, lineNum) => {
441
+ const { token, meta } = splitNodeMeta(rawText);
442
+ const { laneId: qLane, rest } = splitQualifier(token);
443
+ const parsed = parseNodeToken(rest);
401
444
  if (parsed.unsupported) {
402
445
  diagnostics.push(
403
446
  emit(SWIMLANE_DX.UNSUPPORTED, lineNum, { reason: parsed.unsupported })
404
447
  );
405
448
  return null;
406
449
  }
407
- const { label } = extractColor(parsed.label, palette);
408
- const key = normKey(label);
409
- const node = nodeByKey.get(key);
410
- if (!node) {
450
+ const { label: cleanLabel } = extractColor(parsed.label, palette);
451
+ const nk = normKey(cleanLabel);
452
+ const delimited = parsed.shape !== "task";
453
+ const finish = (d) => {
454
+ applyMeta(d, meta, lineNum);
455
+ return d;
456
+ };
457
+ const implicit = (owner) => {
458
+ const draft = {
459
+ id: cleanLabel,
460
+ label: cleanLabel,
461
+ laneId: owner,
462
+ ...phaseId !== void 0 && { phaseId },
463
+ shape: parsed.shape,
464
+ event: parsed.event,
465
+ tags: {},
466
+ lineNumber: lineNum,
467
+ hasBareDecl: false
468
+ };
469
+ applyMeta(draft, meta, lineNum);
470
+ registerDraft(draft);
471
+ return draft;
472
+ };
473
+ if (qLane) {
474
+ const hit = draftByKey.get(laneKey(qLane, cleanLabel));
475
+ if (hit) return finish(hit);
476
+ if (delimited) return implicit(qLane);
411
477
  diagnostics.push(
412
- emit(SWIMLANE_DX.UNKNOWN_NODE, lineNum, { node: parsed.label })
478
+ emit(SWIMLANE_DX.UNKNOWN_NODE, lineNum, {
479
+ node: `${qLane}.${cleanLabel}`
480
+ })
413
481
  );
414
482
  return null;
415
483
  }
416
- return node.id;
417
- };
418
- const addChain = (line, lineNum) => {
419
- if (line.includes("~>")) {
484
+ if (laneId) {
485
+ const own = draftByKey.get(laneKey(laneId, cleanLabel));
486
+ if (own) return finish(own);
487
+ }
488
+ const cands = draftsByLabel.get(nk) ?? [];
489
+ if (cands.length === 1) return finish(cands[0]);
490
+ if (cands.length > 1) {
420
491
  diagnostics.push(
421
- emit(SWIMLANE_DX.UNSUPPORTED, lineNum, {
422
- reason: "message flow (~>) is fast-follow"
492
+ emit(SWIMLANE_DX.AMBIGUOUS_NODE, lineNum, {
493
+ node: cleanLabel,
494
+ lanes: cands.map((c) => c.laneId).join(", ")
423
495
  })
424
496
  );
425
- return;
426
- }
427
- const parts = splitChain(line);
428
- if (parts.length < 2) return;
429
- const resolved = [];
430
- for (let p = 0; p < parts.length; p++) {
431
- const text = parts[p].text;
432
- if (p === 0 && text === "") {
433
- resolved.push(currentFlowSource);
434
- continue;
435
- }
436
- resolved.push(resolveRef(text, lineNum));
437
- }
438
- for (let p = 0; p < parts.length - 1; p++) {
439
- const src = resolved[p];
440
- const tgt = resolved[p + 1];
441
- const label = parts[p].labelAfter;
442
- if (!src || !tgt) continue;
443
- edges.push({
444
- source: src,
445
- target: tgt,
446
- ...label !== void 0 && { label },
447
- lineNumber: lineNum
448
- });
497
+ return finish(cands[0]);
449
498
  }
499
+ if (delimited && laneId) return implicit(laneId);
500
+ diagnostics.push(
501
+ emit(SWIMLANE_DX.UNKNOWN_NODE, lineNum, { node: parsed.label })
502
+ );
503
+ return null;
450
504
  };
505
+ let currentPhase = null;
506
+ let currentLane = null;
507
+ let laneIndent = -1;
508
+ let flowSource = null;
451
509
  let inTagBlock = false;
510
+ const openLane = (lane, indent, phased) => {
511
+ currentLane = lane;
512
+ laneIndent = indent;
513
+ if (!phased) currentPhase = null;
514
+ flowSource = null;
515
+ };
452
516
  for (let i = startIdx; i < rawLines.length; i++) {
453
517
  const raw = rawLines[i];
454
518
  const lineNum = i + 1;
@@ -458,10 +522,7 @@ function parseSwimlane(content, palette) {
458
522
  if (cIdx > 0) trimmed = trimmed.slice(0, cIdx).trim();
459
523
  if (!trimmed) continue;
460
524
  const indent = measureIndent(raw);
461
- if (indent === 0 && /^(lane|direction|tag)\s+/i.test(trimmed)) {
462
- inTagBlock = /^tag\s+/i.test(trimmed);
463
- continue;
464
- }
525
+ if (indent === 0 && /^direction\s+/i.test(trimmed)) continue;
465
526
  if (indent === 0 && /^solid-fill\s*$/i.test(trimmed)) continue;
466
527
  if (matchTagBlockHeading(trimmed) && indent === 0) {
467
528
  inTagBlock = true;
@@ -469,6 +530,13 @@ function parseSwimlane(content, palette) {
469
530
  }
470
531
  if (indent === 0) inTagBlock = false;
471
532
  if (inTagBlock && indent > 0) continue;
533
+ if (/^lane\s+/i.test(trimmed)) {
534
+ const rest = trimmed.replace(/^lane\s+/i, "").trim();
535
+ const { label } = extractColor(rest, palette);
536
+ const lane = laneByKey.get(normKey(label));
537
+ if (lane) openLane(lane, indent, indent > 0);
538
+ continue;
539
+ }
472
540
  if (indent === 0 && trimmed.startsWith("[") && trimmed.endsWith("]") && !trimmed.startsWith("[[")) {
473
541
  const label = trimmed.slice(1, -1).trim();
474
542
  if (lanes.length === 0) {
@@ -484,27 +552,115 @@ function parseSwimlane(content, palette) {
484
552
  currentPhase = phase;
485
553
  currentLane = null;
486
554
  laneIndent = -1;
487
- currentFlowSource = null;
555
+ flowSource = null;
488
556
  continue;
489
557
  }
558
+ const cl = currentLane;
559
+ const cp = currentPhase;
560
+ const laneCtx = cl?.id ?? null;
561
+ const phaseCtx = cp?.id;
562
+ const inLane = cl !== null && indent > laneIndent;
490
563
  if (trimmed.includes("->") || trimmed.includes("~>")) {
491
- addChain(trimmed, lineNum);
564
+ if (trimmed.includes("~>")) {
565
+ diagnostics.push(
566
+ emit(SWIMLANE_DX.UNSUPPORTED, lineNum, {
567
+ reason: "message flow (~>) is fast-follow"
568
+ })
569
+ );
570
+ continue;
571
+ }
572
+ const parts = splitChain(trimmed);
573
+ if (parts.length < 2) continue;
574
+ let headText;
575
+ if (parts[0].text === "") {
576
+ headText = flowSource;
577
+ } else {
578
+ headText = parts[0].text;
579
+ if (inLane) declareInLane(headText, laneCtx, phaseCtx, false, lineNum);
580
+ }
581
+ for (let p = 0; p < parts.length - 1; p++) {
582
+ const srcText = p === 0 ? headText : parts[p].text;
583
+ rawEdges.push({
584
+ srcText,
585
+ tgtText: parts[p + 1].text,
586
+ ...parts[p].labelAfter !== void 0 && {
587
+ label: parts[p].labelAfter
588
+ },
589
+ laneId: laneCtx,
590
+ ...phaseCtx !== void 0 && { phaseId: phaseCtx },
591
+ inLane,
592
+ lineNumber: lineNum
593
+ });
594
+ }
492
595
  continue;
493
596
  }
494
597
  const laneRef = laneByKey.get(normKey(trimmed));
495
598
  if (laneRef && (laneIndent < 0 || indent <= laneIndent)) {
496
- currentLane = laneRef;
497
- laneIndent = indent;
498
- currentFlowSource = null;
599
+ openLane(laneRef, indent, currentPhase !== null && indent > 0);
600
+ continue;
601
+ }
602
+ if (inLane) {
603
+ declareInLane(trimmed, laneCtx, phaseCtx, true, lineNum);
604
+ flowSource = trimmed;
499
605
  continue;
500
606
  }
501
607
  if (indent === 0) {
502
- const ref = resolveRef(trimmed, lineNum);
503
- if (ref) currentFlowSource = ref;
608
+ flowSource = trimmed;
504
609
  continue;
505
610
  }
506
- const { token, meta } = splitNodeMeta(trimmed);
507
- declareNode(token, meta, lineNum);
611
+ const { token } = splitNodeMeta(trimmed);
612
+ const nodeLabel = parseNodeToken(splitQualifier(token).rest).label;
613
+ diagnostics.push(
614
+ emit(SWIMLANE_DX.UNKNOWN_LANE, lineNum, { node: nodeLabel })
615
+ );
616
+ }
617
+ const resolvedPairs = [];
618
+ for (const e of rawEdges) {
619
+ if (e.srcText === null) continue;
620
+ const s = resolveEndpoint(e.srcText, e.laneId, e.phaseId, e.lineNumber);
621
+ const t = resolveEndpoint(e.tgtText, e.laneId, e.phaseId, e.lineNumber);
622
+ if (!s || !t) continue;
623
+ resolvedPairs.push({
624
+ s,
625
+ t,
626
+ ...e.label !== void 0 && { label: e.label },
627
+ lineNumber: e.lineNumber
628
+ });
629
+ }
630
+ const labelCounts = /* @__PURE__ */ new Map();
631
+ for (const d of drafts)
632
+ labelCounts.set(
633
+ normKey(d.label),
634
+ (labelCounts.get(normKey(d.label)) ?? 0) + 1
635
+ );
636
+ const usedIds = /* @__PURE__ */ new Set();
637
+ for (const d of drafts) {
638
+ let id = d.label;
639
+ if ((labelCounts.get(normKey(d.label)) ?? 0) > 1)
640
+ id = `${d.label}\u241F${d.laneId}`;
641
+ while (usedIds.has(id)) id = `${id}\u241F`;
642
+ usedIds.add(id);
643
+ d.id = id;
644
+ nodes.push({
645
+ id,
646
+ label: d.label,
647
+ shape: d.shape,
648
+ event: d.event,
649
+ lane: d.laneId,
650
+ ...d.phaseId !== void 0 && { phase: d.phaseId },
651
+ ...d.color !== void 0 && { color: d.color },
652
+ tags: d.tags,
653
+ lineNumber: d.lineNumber
654
+ });
655
+ }
656
+ for (const p of resolvedPairs) {
657
+ if (p.s.id === p.t.id) continue;
658
+ edges.push({
659
+ source: p.s.id,
660
+ target: p.t.id,
661
+ ...p.label !== void 0 && { label: p.label },
662
+ lineNumber: p.lineNumber
663
+ });
508
664
  }
509
665
  finalizeAutoTagColors(tagGroups, palette);
510
666
  return {
@@ -526,4 +682,4 @@ export {
526
682
  SWIMLANE_DIAGNOSTICS,
527
683
  parseSwimlane
528
684
  };
529
- //# sourceMappingURL=chunk-WVAJFAIA.js.map
685
+ //# sourceMappingURL=chunk-WWN566I7.js.map
@@ -8,18 +8,18 @@ import {
8
8
  rectsOverlap,
9
9
  segmentRectOverlap,
10
10
  segmentsCross
11
- } from "./chunk-PBAHEPLQ.js";
11
+ } from "./chunk-HGN652MU.js";
12
12
  import {
13
13
  compactNumber,
14
14
  computeLegendLayout
15
- } from "./chunk-YAA6IID3.js";
15
+ } from "./chunk-7UEMZREK.js";
16
16
  import {
17
17
  TITLE_FONT_SIZE,
18
18
  TITLE_Y
19
19
  } from "./chunk-A4GOY3PE.js";
20
20
  import {
21
21
  measureLegendText
22
- } from "./chunk-QOOUC2J5.js";
22
+ } from "./chunk-HQCHYB5F.js";
23
23
  import {
24
24
  contrastRatio,
25
25
  mix,
@@ -29,7 +29,7 @@ import {
29
29
  } from "./chunk-P6T66CCZ.js";
30
30
  import {
31
31
  tagAttrKey
32
- } from "./chunk-QLCCJEJI.js";
32
+ } from "./chunk-WCUHAQKB.js";
33
33
  import {
34
34
  resolveColor
35
35
  } from "./chunk-TLVIHFRO.js";
@@ -1820,6 +1820,94 @@ function layoutMap(resolvedIn, data, size, opts) {
1820
1820
  const off = bow * 0.5 + Math.sign(bow || 1) * 8;
1821
1821
  return { x: mx + nx * off, y: my + ny * off };
1822
1822
  };
1823
+ const LEG_SAMPLES = 25;
1824
+ const POI_CLEARANCE = 10;
1825
+ const LEG_CLEARANCE = 7;
1826
+ const SHARED_END_RADIUS = 36;
1827
+ const placedLegSamples = [];
1828
+ const sampleLeg = (a, b, curved, bow) => {
1829
+ const pts = [];
1830
+ const dx = b.cx - a.cx;
1831
+ const dy = b.cy - a.cy;
1832
+ const len = Math.hypot(dx, dy) || 1;
1833
+ const px = (a.cx + b.cx) / 2 + -dy / len * bow;
1834
+ const py = (a.cy + b.cy) / 2 + dx / len * bow;
1835
+ for (let i = 0; i < LEG_SAMPLES; i++) {
1836
+ const t = i / (LEG_SAMPLES - 1);
1837
+ if (!curved && bow === 0) {
1838
+ pts.push({ x: a.cx + dx * t, y: a.cy + dy * t });
1839
+ } else {
1840
+ const u = 1 - t;
1841
+ pts.push({
1842
+ x: u * u * a.cx + 2 * u * t * px + t * t * b.cx,
1843
+ y: u * u * a.cy + 2 * u * t * py + t * t * b.cy
1844
+ });
1845
+ }
1846
+ }
1847
+ return pts;
1848
+ };
1849
+ const legPenalty = (pts, fromId, toId) => {
1850
+ let pen = 0;
1851
+ for (const [id, p] of poiScreen) {
1852
+ if (id === fromId || id === toId) continue;
1853
+ let dmin = Infinity;
1854
+ for (const s of pts) {
1855
+ const d = Math.hypot(s.x - p.cx, s.y - p.cy);
1856
+ if (d < dmin) dmin = d;
1857
+ }
1858
+ const clear = p.r + POI_CLEARANCE;
1859
+ if (dmin < clear) pen += (clear - dmin) * 12;
1860
+ }
1861
+ for (const other of placedLegSamples) {
1862
+ const shared = [fromId, toId].filter((id) => id === other.fromId || id === other.toId).map((id) => poiScreen.get(id)).filter((p) => !!p);
1863
+ for (const s of pts) {
1864
+ if (shared.some(
1865
+ (sp) => Math.hypot(s.x - sp.cx, s.y - sp.cy) < SHARED_END_RADIUS
1866
+ )) {
1867
+ continue;
1868
+ }
1869
+ let dmin = Infinity;
1870
+ for (const o of other.pts) {
1871
+ const d = Math.hypot(s.x - o.x, s.y - o.y);
1872
+ if (d < dmin) dmin = d;
1873
+ }
1874
+ if (dmin < LEG_CLEARANCE) pen += 6;
1875
+ }
1876
+ }
1877
+ for (const s of pts) {
1878
+ if (s.x < 0 || s.x > width || s.y < 0 || s.y > height) pen += 20;
1879
+ }
1880
+ return pen;
1881
+ };
1882
+ const chooseArcBow = (a, b, fromId, toId, away) => {
1883
+ const mx = (a.cx + b.cx) / 2;
1884
+ const my = (a.cy + b.cy) / 2;
1885
+ const dx = b.cx - a.cx;
1886
+ const dy = b.cy - a.cy;
1887
+ const len = Math.hypot(dx, dy) || 1;
1888
+ const nx = -dy / len;
1889
+ const ny = dx / len;
1890
+ const def = bowMagnitude(mx, my, nx, ny, 0, len, away);
1891
+ const candidates = [
1892
+ def,
1893
+ -def,
1894
+ def * 1.6,
1895
+ -def * 1.6,
1896
+ def * 2.2,
1897
+ -def * 2.2
1898
+ ];
1899
+ let best = def;
1900
+ let bestPen = Infinity;
1901
+ for (const c of candidates) {
1902
+ const pen = legPenalty(sampleLeg(a, b, true, c), fromId, toId);
1903
+ if (pen < bestPen - 1e-6) {
1904
+ best = c;
1905
+ bestPen = pen;
1906
+ }
1907
+ if (bestPen === 0) break;
1908
+ }
1909
+ return best;
1910
+ };
1823
1911
  const routeLegVals = resolved.routes.flatMap((rt) => rt.legs).map((l) => Number(l.value)).filter((n) => Number.isFinite(n) && n > 0);
1824
1912
  const rlMin = routeLegVals.length ? Math.min(...routeLegVals) : 0;
1825
1913
  const rlMax = routeLegVals.length ? Math.max(...routeLegVals) : 0;
@@ -1838,14 +1926,21 @@ function layoutMap(resolvedIn, data, size, opts) {
1838
1926
  const a = poiScreen.get(leg.fromId);
1839
1927
  const b = poiScreen.get(leg.toId);
1840
1928
  if (!a || !b) continue;
1841
- const lp = legLabelPoint(a, b, leg.style === "arc", 0, center);
1929
+ const curvedLeg = leg.style === "arc";
1930
+ const chosenBow = curvedLeg ? chooseArcBow(a, b, leg.fromId, leg.toId, center) : 0;
1931
+ const lp = legLabelPoint(a, b, curvedLeg, chosenBow, center);
1842
1932
  const bow = {
1843
- curved: leg.style === "arc",
1844
- offset: 0,
1933
+ curved: curvedLeg,
1934
+ offset: chosenBow,
1845
1935
  center,
1846
1936
  labelX: lp.x,
1847
1937
  labelY: lp.y
1848
1938
  };
1939
+ placedLegSamples.push({
1940
+ fromId: leg.fromId,
1941
+ toId: leg.toId,
1942
+ pts: sampleLeg(a, b, curvedLeg, chosenBow)
1943
+ });
1849
1944
  const routeLabelStyle = leg.label !== void 0 ? labelOnFill(fillAt(bow.labelX, bow.labelY)) : void 0;
1850
1945
  const routeVal = Number(leg.value);
1851
1946
  legs.push({
@@ -1894,13 +1989,19 @@ function layoutMap(resolvedIn, data, size, opts) {
1894
1989
  if (!a || !b) return;
1895
1990
  const fanOffset = n > 1 ? (i - (n - 1) / 2) * FAN_STEP : 0;
1896
1991
  const curved = e.style === "arc" || n > 1;
1897
- const lp = legLabelPoint(a, b, curved, fanOffset);
1992
+ const edgeBow = curved && n === 1 ? chooseArcBow(a, b, e.fromId, e.toId) : fanOffset;
1993
+ const lp = legLabelPoint(a, b, curved, edgeBow);
1898
1994
  const bow = {
1899
1995
  curved,
1900
- offset: fanOffset,
1996
+ offset: edgeBow,
1901
1997
  labelX: lp.x,
1902
1998
  labelY: lp.y
1903
1999
  };
2000
+ placedLegSamples.push({
2001
+ fromId: e.fromId,
2002
+ toId: e.toId,
2003
+ pts: sampleLeg(a, b, curved, edgeBow)
2004
+ });
1904
2005
  const edgeLabelStyle = e.label !== void 0 ? labelOnFill(fillAt(bow.labelX, bow.labelY)) : void 0;
1905
2006
  const edgeVal = Number(e.meta["width"]);
1906
2007
  legs.push({
@@ -3076,4 +3177,4 @@ export {
3076
3177
  albersSkewFallback,
3077
3178
  layoutMap
3078
3179
  };
3079
- //# sourceMappingURL=chunk-IPWPWM6R.js.map
3180
+ //# sourceMappingURL=chunk-X2NMFTG3.js.map