schematex 0.6.5 → 0.6.6

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 (164) hide show
  1. package/dist/ai/ai-sdk.cjs +22 -22
  2. package/dist/ai/ai-sdk.d.cts +3 -3
  3. package/dist/ai/ai-sdk.d.ts +3 -3
  4. package/dist/ai/ai-sdk.js +17 -17
  5. package/dist/ai/index.cjs +28 -28
  6. package/dist/ai/index.d.cts +3 -3
  7. package/dist/ai/index.d.ts +3 -3
  8. package/dist/ai/index.js +17 -17
  9. package/dist/{api-BXkOT7GL.d.cts → api-DA4-U-jn.d.cts} +2 -2
  10. package/dist/{api-BIqZjEDf.d.ts → api-QFMTlIi7.d.ts} +2 -2
  11. package/dist/browser.cjs +23 -23
  12. package/dist/browser.d.cts +3 -3
  13. package/dist/browser.d.ts +3 -3
  14. package/dist/browser.js +17 -17
  15. package/dist/{chunk-3C5DKCBJ.cjs → chunk-2SZJQVPN.cjs} +12 -12
  16. package/dist/{chunk-3C5DKCBJ.cjs.map → chunk-2SZJQVPN.cjs.map} +1 -1
  17. package/dist/{chunk-RVHOCGHT.js → chunk-3GAPHXCE.js} +3 -3
  18. package/dist/{chunk-RVHOCGHT.js.map → chunk-3GAPHXCE.js.map} +1 -1
  19. package/dist/{chunk-ZZHQBAC3.js → chunk-3HZW6K5I.js} +130 -4
  20. package/dist/chunk-3HZW6K5I.js.map +1 -0
  21. package/dist/{chunk-HCBXTBFA.cjs → chunk-5FYPSIGD.cjs} +12 -12
  22. package/dist/{chunk-HCBXTBFA.cjs.map → chunk-5FYPSIGD.cjs.map} +1 -1
  23. package/dist/{chunk-B7ATOBL7.js → chunk-6NUAGU6O.js} +3 -3
  24. package/dist/{chunk-B7ATOBL7.js.map → chunk-6NUAGU6O.js.map} +1 -1
  25. package/dist/{chunk-WZ5QBGPZ.cjs → chunk-77GPD4YQ.cjs} +4 -4
  26. package/dist/{chunk-WZ5QBGPZ.cjs.map → chunk-77GPD4YQ.cjs.map} +1 -1
  27. package/dist/{chunk-IPEHLRTI.js → chunk-7DAIEDQP.js} +3 -3
  28. package/dist/{chunk-IPEHLRTI.js.map → chunk-7DAIEDQP.js.map} +1 -1
  29. package/dist/{chunk-S2CHBZ4A.cjs → chunk-BL57NQKN.cjs} +13 -13
  30. package/dist/{chunk-S2CHBZ4A.cjs.map → chunk-BL57NQKN.cjs.map} +1 -1
  31. package/dist/{chunk-T3ZN5P32.cjs → chunk-CMZKAASF.cjs} +132 -6
  32. package/dist/{chunk-ZZHQBAC3.js.map → chunk-CMZKAASF.cjs.map} +1 -1
  33. package/dist/{chunk-XJJUJ2EF.cjs → chunk-DO2DDHTQ.cjs} +4 -4
  34. package/dist/{chunk-XJJUJ2EF.cjs.map → chunk-DO2DDHTQ.cjs.map} +1 -1
  35. package/dist/{chunk-I6UJR4SG.cjs → chunk-DR3DDDQY.cjs} +4 -4
  36. package/dist/{chunk-I6UJR4SG.cjs.map → chunk-DR3DDDQY.cjs.map} +1 -1
  37. package/dist/{chunk-W3IXH6BN.cjs → chunk-EUVUO3CL.cjs} +4 -4
  38. package/dist/chunk-EUVUO3CL.cjs.map +1 -0
  39. package/dist/{chunk-MI77LY6A.js → chunk-FOPOOV2P.js} +991 -377
  40. package/dist/chunk-FOPOOV2P.js.map +1 -0
  41. package/dist/{chunk-GV5QLYTW.js → chunk-HL5PS6MG.js} +3 -3
  42. package/dist/{chunk-GV5QLYTW.js.map → chunk-HL5PS6MG.js.map} +1 -1
  43. package/dist/{chunk-MKECYIWN.js → chunk-HPEAE3JM.js} +3 -3
  44. package/dist/{chunk-MKECYIWN.js.map → chunk-HPEAE3JM.js.map} +1 -1
  45. package/dist/{chunk-KPKGMOTS.js → chunk-JN6FHUC6.js} +3 -3
  46. package/dist/{chunk-KPKGMOTS.js.map → chunk-JN6FHUC6.js.map} +1 -1
  47. package/dist/{chunk-OHLNH7IO.js → chunk-K2D6VFLP.js} +3 -3
  48. package/dist/{chunk-OHLNH7IO.js.map → chunk-K2D6VFLP.js.map} +1 -1
  49. package/dist/{chunk-OANWVUBA.js → chunk-KCHUQXS3.js} +3 -3
  50. package/dist/chunk-KCHUQXS3.js.map +1 -0
  51. package/dist/{chunk-ZZFPXCAK.cjs → chunk-KGOZBABH.cjs} +12 -12
  52. package/dist/{chunk-ZZFPXCAK.cjs.map → chunk-KGOZBABH.cjs.map} +1 -1
  53. package/dist/{chunk-35XCP2E4.js → chunk-KJZCRHNR.js} +3 -3
  54. package/dist/{chunk-35XCP2E4.js.map → chunk-KJZCRHNR.js.map} +1 -1
  55. package/dist/{chunk-XO7WW3I6.cjs → chunk-LPAWZYDU.cjs} +4 -4
  56. package/dist/{chunk-XO7WW3I6.cjs.map → chunk-LPAWZYDU.cjs.map} +1 -1
  57. package/dist/{chunk-624UQ5R6.cjs → chunk-MLLARXOI.cjs} +1050 -435
  58. package/dist/chunk-MLLARXOI.cjs.map +1 -0
  59. package/dist/{chunk-ROX5KEZM.cjs → chunk-NFZMNKOR.cjs} +15 -15
  60. package/dist/{chunk-ROX5KEZM.cjs.map → chunk-NFZMNKOR.cjs.map} +1 -1
  61. package/dist/{chunk-R5E2LSN2.cjs → chunk-NZT5P2XZ.cjs} +73 -2
  62. package/dist/chunk-NZT5P2XZ.cjs.map +1 -0
  63. package/dist/{chunk-GPC5BWLI.js → chunk-OFKRELZK.js} +3 -3
  64. package/dist/{chunk-GPC5BWLI.js.map → chunk-OFKRELZK.js.map} +1 -1
  65. package/dist/{chunk-XEIVA2CT.js → chunk-T3FV73LM.js} +3 -3
  66. package/dist/{chunk-XEIVA2CT.js.map → chunk-T3FV73LM.js.map} +1 -1
  67. package/dist/{chunk-4THUHX2D.cjs → chunk-T5KHNJ67.cjs} +5 -5
  68. package/dist/{chunk-4THUHX2D.cjs.map → chunk-T5KHNJ67.cjs.map} +1 -1
  69. package/dist/{chunk-FXPOHPBE.cjs → chunk-TACTEF2N.cjs} +4 -4
  70. package/dist/{chunk-FXPOHPBE.cjs.map → chunk-TACTEF2N.cjs.map} +1 -1
  71. package/dist/{chunk-AORGFBEH.js → chunk-UK6HF6PE.js} +73 -3
  72. package/dist/chunk-UK6HF6PE.js.map +1 -0
  73. package/dist/{chunk-LGFB4H5B.js → chunk-WU2N6ZVM.js} +3 -3
  74. package/dist/{chunk-LGFB4H5B.js.map → chunk-WU2N6ZVM.js.map} +1 -1
  75. package/dist/{chunk-BXNOXOE4.cjs → chunk-XYHCAJMI.cjs} +4 -4
  76. package/dist/{chunk-BXNOXOE4.cjs.map → chunk-XYHCAJMI.cjs.map} +1 -1
  77. package/dist/{chunk-FHZTWWI6.js → chunk-YMZTXOUG.js} +3 -3
  78. package/dist/{chunk-FHZTWWI6.js.map → chunk-YMZTXOUG.js.map} +1 -1
  79. package/dist/{chunk-XSPENTEG.js → chunk-YTGOLTLJ.js} +3 -3
  80. package/dist/{chunk-XSPENTEG.js.map → chunk-YTGOLTLJ.js.map} +1 -1
  81. package/dist/{chunk-VZO2SX6Q.cjs → chunk-Z3A2UNK2.cjs} +4 -4
  82. package/dist/{chunk-VZO2SX6Q.cjs.map → chunk-Z3A2UNK2.cjs.map} +1 -1
  83. package/dist/{diagnostics-CzHW0RCo.d.cts → diagnostics-CSznf_sl.d.cts} +1 -1
  84. package/dist/{diagnostics-CzHW0RCo.d.ts → diagnostics-CSznf_sl.d.ts} +1 -1
  85. package/dist/diagrams/blockdiagram/index.d.cts +1 -1
  86. package/dist/diagrams/blockdiagram/index.d.ts +1 -1
  87. package/dist/diagrams/circuit/index.cjs +8 -8
  88. package/dist/diagrams/circuit/index.d.cts +1 -1
  89. package/dist/diagrams/circuit/index.d.ts +1 -1
  90. package/dist/diagrams/circuit/index.js +2 -2
  91. package/dist/diagrams/ecomap/index.cjs +7 -7
  92. package/dist/diagrams/ecomap/index.d.cts +1 -1
  93. package/dist/diagrams/ecomap/index.d.ts +1 -1
  94. package/dist/diagrams/ecomap/index.js +2 -2
  95. package/dist/diagrams/entity/index.cjs +6 -6
  96. package/dist/diagrams/entity/index.d.cts +1 -1
  97. package/dist/diagrams/entity/index.d.ts +1 -1
  98. package/dist/diagrams/entity/index.js +2 -2
  99. package/dist/diagrams/fishbone/index.cjs +8 -8
  100. package/dist/diagrams/fishbone/index.d.cts +1 -1
  101. package/dist/diagrams/fishbone/index.d.ts +1 -1
  102. package/dist/diagrams/fishbone/index.js +2 -2
  103. package/dist/diagrams/flowchart/index.cjs +8 -8
  104. package/dist/diagrams/flowchart/index.d.cts +2 -2
  105. package/dist/diagrams/flowchart/index.d.ts +2 -2
  106. package/dist/diagrams/flowchart/index.js +2 -2
  107. package/dist/diagrams/genogram/index.cjs +9 -9
  108. package/dist/diagrams/genogram/index.d.cts +1 -1
  109. package/dist/diagrams/genogram/index.d.ts +1 -1
  110. package/dist/diagrams/genogram/index.js +2 -2
  111. package/dist/diagrams/ladder/index.cjs +6 -6
  112. package/dist/diagrams/ladder/index.d.cts +1 -1
  113. package/dist/diagrams/ladder/index.d.ts +1 -1
  114. package/dist/diagrams/ladder/index.js +2 -2
  115. package/dist/diagrams/logic/index.cjs +8 -8
  116. package/dist/diagrams/logic/index.d.cts +1 -1
  117. package/dist/diagrams/logic/index.d.ts +1 -1
  118. package/dist/diagrams/logic/index.js +2 -2
  119. package/dist/diagrams/orgchart/index.cjs +7 -7
  120. package/dist/diagrams/orgchart/index.d.cts +1 -1
  121. package/dist/diagrams/orgchart/index.d.ts +1 -1
  122. package/dist/diagrams/orgchart/index.js +2 -2
  123. package/dist/diagrams/pedigree/index.cjs +7 -7
  124. package/dist/diagrams/pedigree/index.d.cts +1 -1
  125. package/dist/diagrams/pedigree/index.d.ts +1 -1
  126. package/dist/diagrams/pedigree/index.js +2 -2
  127. package/dist/diagrams/phylo/index.cjs +7 -7
  128. package/dist/diagrams/phylo/index.d.cts +1 -1
  129. package/dist/diagrams/phylo/index.d.ts +1 -1
  130. package/dist/diagrams/phylo/index.js +2 -2
  131. package/dist/diagrams/sld/index.cjs +8 -8
  132. package/dist/diagrams/sld/index.d.cts +1 -1
  133. package/dist/diagrams/sld/index.d.ts +1 -1
  134. package/dist/diagrams/sld/index.js +2 -2
  135. package/dist/diagrams/sociogram/index.cjs +6 -6
  136. package/dist/diagrams/sociogram/index.d.cts +1 -1
  137. package/dist/diagrams/sociogram/index.d.ts +1 -1
  138. package/dist/diagrams/sociogram/index.js +2 -2
  139. package/dist/diagrams/timing/index.d.cts +1 -1
  140. package/dist/diagrams/timing/index.d.ts +1 -1
  141. package/dist/diagrams/venn/index.cjs +9 -9
  142. package/dist/diagrams/venn/index.d.cts +1 -1
  143. package/dist/diagrams/venn/index.d.ts +1 -1
  144. package/dist/diagrams/venn/index.js +2 -2
  145. package/dist/{index-R0IwpG20.d.cts → index-CDpYuU7l.d.cts} +1 -1
  146. package/dist/{index-DdR1Auby.d.ts → index-jTwjudTW.d.ts} +1 -1
  147. package/dist/index.cjs +77 -73
  148. package/dist/index.d.cts +7 -5
  149. package/dist/index.d.ts +7 -5
  150. package/dist/index.js +21 -21
  151. package/dist/react.cjs +17 -17
  152. package/dist/react.d.cts +2 -2
  153. package/dist/react.d.ts +2 -2
  154. package/dist/react.js +16 -16
  155. package/dist/{tools-DHSVXHM9.d.cts → tools-CbuSbW6B.d.cts} +2 -2
  156. package/dist/{tools-B7EqXLgD.d.ts → tools-D344vOzR.d.ts} +2 -2
  157. package/package.json +1 -1
  158. package/dist/chunk-624UQ5R6.cjs.map +0 -1
  159. package/dist/chunk-AORGFBEH.js.map +0 -1
  160. package/dist/chunk-MI77LY6A.js.map +0 -1
  161. package/dist/chunk-OANWVUBA.js.map +0 -1
  162. package/dist/chunk-R5E2LSN2.cjs.map +0 -1
  163. package/dist/chunk-T3ZN5P32.cjs.map +0 -1
  164. package/dist/chunk-W3IXH6BN.cjs.map +0 -1
@@ -1,21 +1,21 @@
1
- import { orgchart } from './chunk-IPEHLRTI.js';
2
- import { circuit } from './chunk-35XCP2E4.js';
1
+ import { orgchart } from './chunk-7DAIEDQP.js';
2
+ import { circuit } from './chunk-KJZCRHNR.js';
3
3
  import { blockdiagram } from './chunk-EPKIJEH7.js';
4
- import { ladder } from './chunk-LGFB4H5B.js';
5
- import { sld } from './chunk-OANWVUBA.js';
6
- import { entity } from './chunk-FHZTWWI6.js';
7
- import { fishbone } from './chunk-XSPENTEG.js';
8
- import { venn } from './chunk-XEIVA2CT.js';
9
- import { flowchart, layoutFlowchart } from './chunk-MKECYIWN.js';
10
- import { genogram } from './chunk-B7ATOBL7.js';
11
- import { ecomap } from './chunk-OHLNH7IO.js';
12
- import { pedigree } from './chunk-KPKGMOTS.js';
4
+ import { ladder } from './chunk-WU2N6ZVM.js';
5
+ import { sld } from './chunk-KCHUQXS3.js';
6
+ import { entity } from './chunk-YMZTXOUG.js';
7
+ import { fishbone } from './chunk-YTGOLTLJ.js';
8
+ import { venn } from './chunk-T3FV73LM.js';
9
+ import { flowchart, layoutFlowchart } from './chunk-HPEAE3JM.js';
10
+ import { genogram } from './chunk-6NUAGU6O.js';
11
+ import { ecomap } from './chunk-K2D6VFLP.js';
12
+ import { pedigree } from './chunk-JN6FHUC6.js';
13
13
  import { parseFrontmatter } from './chunk-2KTQ75LN.js';
14
- import { phylo } from './chunk-GV5QLYTW.js';
15
- import { sociogram } from './chunk-GPC5BWLI.js';
14
+ import { phylo } from './chunk-HL5PS6MG.js';
15
+ import { sociogram } from './chunk-OFKRELZK.js';
16
16
  import { timing } from './chunk-P26FCZP3.js';
17
- import { logic } from './chunk-RVHOCGHT.js';
18
- import { resolveBaseTheme, resolveTimelineTheme, cssCustomProperties, resolvePetriTheme, resolveNetworkTheme, resolveUmlClassTheme, DEFAULT_FONT_FAMILY, FONT_SIZE, resolveReliabilityTheme, STROKE_WIDTH, resolveMindmapTheme } from './chunk-AORGFBEH.js';
17
+ import { logic } from './chunk-3GAPHXCE.js';
18
+ import { resolveBaseTheme, resolveTimelineTheme, cssCustomProperties, resolvePetriTheme, resolveNetworkTheme, resolveUmlClassTheme, DEFAULT_FONT_FAMILY, FONT_SIZE, resolveReliabilityTheme, STROKE_WIDTH, resolveBowtieTheme, resolveMindmapTheme } from './chunk-UK6HF6PE.js';
19
19
  import { matchQuotedTitle, stripQuotes } from './chunk-5IKOLUWK.js';
20
20
  import { el, escapeXml, group, rect, text, line, path, circle, polygon, title, desc, svgRoot, defs, multilineText } from './chunk-SYYBKDL7.js';
21
21
 
@@ -2257,8 +2257,8 @@ function renderEras(layout, theme) {
2257
2257
  layout.eras.forEach((e, i) => {
2258
2258
  const l = leftmostOnRow.get(e.bandRow);
2259
2259
  if (l === void 0 || e.x < layout.eras[l].x) leftmostOnRow.set(e.bandRow, i);
2260
- const r3 = rightmostOnRow.get(e.bandRow);
2261
- if (r3 === void 0 || e.x + e.width > layout.eras[r3].x + layout.eras[r3].width) rightmostOnRow.set(e.bandRow, i);
2260
+ const r5 = rightmostOnRow.get(e.bandRow);
2261
+ if (r5 === void 0 || e.x + e.width > layout.eras[r5].x + layout.eras[r5].width) rightmostOnRow.set(e.bandRow, i);
2262
2262
  });
2263
2263
  const plotEnd = layout.plotX + layout.plotW;
2264
2264
  const items = layout.eras.map((e, i) => {
@@ -2384,20 +2384,20 @@ function renderSwimlanePoints(layout, theme) {
2384
2384
  function renderMarker(ev, color, shape, isMilestone) {
2385
2385
  const x = ev.x;
2386
2386
  const y = ev.y;
2387
- const r3 = isMilestone ? 8 : 5;
2387
+ const r5 = isMilestone ? 8 : 5;
2388
2388
  const klass = isMilestone ? "st-milestone" : "st-event-dot";
2389
2389
  switch (shape) {
2390
2390
  case "square":
2391
- return rect({ x: x - r3, y: y - r3, width: r3 * 2, height: r3 * 2, fill: color, class: klass, "data-event-id": ev.event.id });
2391
+ return rect({ x: x - r5, y: y - r5, width: r5 * 2, height: r5 * 2, fill: color, class: klass, "data-event-id": ev.event.id });
2392
2392
  case "diamond":
2393
- return path({ d: `M ${x},${y - r3} L ${x + r3},${y} L ${x},${y + r3} L ${x - r3},${y} Z`, fill: color, class: klass, "data-event-id": ev.event.id });
2393
+ return path({ d: `M ${x},${y - r5} L ${x + r5},${y} L ${x},${y + r5} L ${x - r5},${y} Z`, fill: color, class: klass, "data-event-id": ev.event.id });
2394
2394
  case "star":
2395
- return path({ d: starPath(x, y, r3 + 2, (r3 + 2) / 2.5, 5), fill: color, class: klass, "data-event-id": ev.event.id });
2395
+ return path({ d: starPath(x, y, r5 + 2, (r5 + 2) / 2.5, 5), fill: color, class: klass, "data-event-id": ev.event.id });
2396
2396
  case "flag":
2397
- return path({ d: `M ${x - r3},${y + r3} L ${x - r3},${y - r3 - 4} L ${x + r3 + 4},${y - r3 - 1} L ${x - r3},${y + 2}`, fill: color, class: klass, "data-event-id": ev.event.id });
2397
+ return path({ d: `M ${x - r5},${y + r5} L ${x - r5},${y - r5 - 4} L ${x + r5 + 4},${y - r5 - 1} L ${x - r5},${y + 2}`, fill: color, class: klass, "data-event-id": ev.event.id });
2398
2398
  case "circle":
2399
2399
  default:
2400
- return circle({ cx: x, cy: y, r: r3, fill: color, class: klass, "data-event-id": ev.event.id });
2400
+ return circle({ cx: x, cy: y, r: r5, fill: color, class: klass, "data-event-id": ev.event.id });
2401
2401
  }
2402
2402
  }
2403
2403
  function renderLabels(layout) {
@@ -2653,10 +2653,10 @@ function starPath(cx, cy, rOuter, rInner, points) {
2653
2653
  const step = Math.PI / points;
2654
2654
  let d = "";
2655
2655
  for (let i = 0; i < points * 2; i++) {
2656
- const r3 = i % 2 === 0 ? rOuter : rInner;
2656
+ const r5 = i % 2 === 0 ? rOuter : rInner;
2657
2657
  const a = i * step - Math.PI / 2;
2658
- const x = cx + r3 * Math.cos(a);
2659
- const y = cy + r3 * Math.sin(a);
2658
+ const x = cx + r5 * Math.cos(a);
2659
+ const y = cy + r5 * Math.sin(a);
2660
2660
  d += (i === 0 ? "M" : "L") + x.toFixed(2) + "," + y.toFixed(2) + " ";
2661
2661
  }
2662
2662
  return d + "Z";
@@ -2927,7 +2927,7 @@ function parseStateDiagram(src) {
2927
2927
  }
2928
2928
  ctxTop.regionMode = true;
2929
2929
  if (!parent.regions) parent.regions = [];
2930
- const lastIdx = parent.regions.reduce((s, r3) => s + r3.length, 0);
2930
+ const lastIdx = parent.regions.reduce((s, r5) => s + r5.length, 0);
2931
2931
  const slice = parent.children.slice(lastIdx);
2932
2932
  parent.regions.push(slice);
2933
2933
  i++;
@@ -3131,7 +3131,7 @@ function parseStateDiagram(src) {
3131
3131
  }
3132
3132
  function finalizeRegions(node) {
3133
3133
  if (node.regions) {
3134
- const consumed = node.regions.reduce((s, r3) => s + r3.length, 0);
3134
+ const consumed = node.regions.reduce((s, r5) => s + r5.length, 0);
3135
3135
  if (node.children.length > consumed) {
3136
3136
  node.regions.push(node.children.slice(consumed));
3137
3137
  }
@@ -3576,33 +3576,33 @@ function pointsToPath(pts) {
3576
3576
  const rest = pts.slice(1).map((p) => `L ${p.x} ${p.y}`).join(" ");
3577
3577
  return rest ? `${head} ${rest}` : head;
3578
3578
  }
3579
- function trimPathStart(d, cx, cy, r3) {
3579
+ function trimPathStart(d, cx, cy, r5) {
3580
3580
  const pts = parsePathPoints(d);
3581
3581
  if (!pts || pts.length < 2) return d;
3582
3582
  const p0 = pts[0];
3583
3583
  const p1 = pts[1];
3584
- const newP0 = projectOnPerimeter(p0, p1, cx, cy, r3);
3584
+ const newP0 = projectOnPerimeter(p0, p1, cx, cy, r5);
3585
3585
  pts[0] = newP0;
3586
3586
  return pointsToPath(pts);
3587
3587
  }
3588
- function trimPathEnd(d, cx, cy, r3) {
3588
+ function trimPathEnd(d, cx, cy, r5) {
3589
3589
  const pts = parsePathPoints(d);
3590
3590
  if (!pts || pts.length < 2) return d;
3591
3591
  const last = pts[pts.length - 1];
3592
3592
  const prev = pts[pts.length - 2];
3593
- const newLast = projectOnPerimeter(last, prev, cx, cy, r3);
3593
+ const newLast = projectOnPerimeter(last, prev, cx, cy, r5);
3594
3594
  pts[pts.length - 1] = newLast;
3595
3595
  return pointsToPath(pts);
3596
3596
  }
3597
- function projectOnPerimeter(endpoint, neighbor, cx, cy, r3) {
3597
+ function projectOnPerimeter(endpoint, neighbor, cx, cy, r5) {
3598
3598
  const dx = endpoint.x - neighbor.x;
3599
3599
  const dy = endpoint.y - neighbor.y;
3600
3600
  if (Math.abs(dx) > Math.abs(dy)) {
3601
3601
  const sign2 = dx >= 0 ? 1 : -1;
3602
- return { x: cx - sign2 * r3, y: cy };
3602
+ return { x: cx - sign2 * r5, y: cy };
3603
3603
  }
3604
3604
  const sign = dy >= 0 ? 1 : -1;
3605
- return { x: cx, y: cy - sign * r3 };
3605
+ return { x: cx, y: cy - sign * r5 };
3606
3606
  }
3607
3607
  function shiftPathX(d, dx) {
3608
3608
  return d.replace(/([MLCQ])\s*((?:-?\d+(?:\.\d+)?\s+){1,5}-?\d+(?:\.\d+)?)/g, (_, cmd, args) => {
@@ -3778,12 +3778,12 @@ function renderPseudo(node) {
3778
3778
  ]
3779
3779
  );
3780
3780
  case "choice": {
3781
- const r3 = 14;
3781
+ const r5 = 14;
3782
3782
  return group(
3783
3783
  { class: "lt-state lt-pseudo", "data-id": node.id, "data-kind": "choice" },
3784
3784
  [
3785
3785
  polygon({
3786
- points: `${cx},${cy - r3} ${cx + r3},${cy} ${cx},${cy + r3} ${cx - r3},${cy}`,
3786
+ points: `${cx},${cy - r5} ${cx + r5},${cy} ${cx},${cy + r5} ${cx - r5},${cy}`,
3787
3787
  class: "lt-ps-choice"
3788
3788
  })
3789
3789
  ]
@@ -4781,27 +4781,27 @@ function renderEquip(type, label, rawType) {
4781
4781
  ]);
4782
4782
  }
4783
4783
  case "pump_centrifugal": {
4784
- const r3 = 22;
4784
+ const r5 = 22;
4785
4785
  return group({}, [
4786
- circle({ cx: 0, cy: 0, r: r3, class: "lt-pid-equip" }),
4786
+ circle({ cx: 0, cy: 0, r: r5, class: "lt-pid-equip" }),
4787
4787
  polygon({
4788
- points: `${r3 * 0.4},${-r3 * 0.9} ${r3 + 6},${-r3 * 0.9} ${r3 * 0.4},${0}`,
4788
+ points: `${r5 * 0.4},${-r5 * 0.9} ${r5 + 6},${-r5 * 0.9} ${r5 * 0.4},${0}`,
4789
4789
  class: "lt-pid-equip"
4790
4790
  }),
4791
4791
  text(
4792
- { x: 0, y: r3 + 14, "text-anchor": "middle", class: "lt-pid-equip-tag" },
4792
+ { x: 0, y: r5 + 14, "text-anchor": "middle", class: "lt-pid-equip-tag" },
4793
4793
  label
4794
4794
  )
4795
4795
  ]);
4796
4796
  }
4797
4797
  case "pump_pd": {
4798
- const r3 = 22;
4798
+ const r5 = 22;
4799
4799
  return group({}, [
4800
- circle({ cx: 0, cy: 0, r: r3, class: "lt-pid-equip" }),
4800
+ circle({ cx: 0, cy: 0, r: r5, class: "lt-pid-equip" }),
4801
4801
  circle({ cx: -8, cy: 0, r: 6, class: "lt-pid-tray-line", fill: "none" }),
4802
4802
  circle({ cx: 8, cy: 0, r: 6, class: "lt-pid-tray-line", fill: "none" }),
4803
4803
  text(
4804
- { x: 0, y: r3 + 14, "text-anchor": "middle", class: "lt-pid-equip-tag" },
4804
+ { x: 0, y: r5 + 14, "text-anchor": "middle", class: "lt-pid-equip-tag" },
4805
4805
  label
4806
4806
  )
4807
4807
  ]);
@@ -4816,14 +4816,14 @@ function renderEquip(type, label, rawType) {
4816
4816
  ]);
4817
4817
  }
4818
4818
  case "blower": {
4819
- const r3 = 22;
4819
+ const r5 = 22;
4820
4820
  return group({}, [
4821
- circle({ cx: 0, cy: 0, r: r3, class: "lt-pid-equip" }),
4821
+ circle({ cx: 0, cy: 0, r: r5, class: "lt-pid-equip" }),
4822
4822
  path({
4823
- d: `M 0 0 L ${r3 * 0.8} ${-r3 * 0.5} M 0 0 L ${-r3 * 0.6} ${-r3 * 0.6} M 0 0 L 0 ${r3 * 0.8}`,
4823
+ d: `M 0 0 L ${r5 * 0.8} ${-r5 * 0.5} M 0 0 L ${-r5 * 0.6} ${-r5 * 0.6} M 0 0 L 0 ${r5 * 0.8}`,
4824
4824
  class: "lt-pid-tray-line"
4825
4825
  }),
4826
- text({ x: 0, y: r3 + 14, "text-anchor": "middle", class: "lt-pid-equip-tag" }, label)
4826
+ text({ x: 0, y: r5 + 14, "text-anchor": "middle", class: "lt-pid-equip-tag" }, label)
4827
4827
  ]);
4828
4828
  }
4829
4829
  case "reactor_cstr": {
@@ -4999,7 +4999,7 @@ function renderEquip(type, label, rawType) {
4999
4999
  }
5000
5000
  }
5001
5001
  function renderInstrument(category, letterCode, loopNumber) {
5002
- const r3 = 14;
5002
+ const r5 = 14;
5003
5003
  const isComputer = category.endsWith("computer");
5004
5004
  const isPlc = category.endsWith("plc");
5005
5005
  const isShared = category.endsWith("shared");
@@ -5007,17 +5007,17 @@ function renderInstrument(category, letterCode, loopNumber) {
5007
5007
  const isLocal = category.startsWith("local_");
5008
5008
  const parts = [];
5009
5009
  if (isComputer) {
5010
- parts.push(circle({ cx: 0, cy: 0, r: r3, class: "lt-inst-body" }));
5010
+ parts.push(circle({ cx: 0, cy: 0, r: r5, class: "lt-inst-body" }));
5011
5011
  parts.push(
5012
5012
  polygon({
5013
- points: `0,${-r3 + 1} ${r3 - 1},0 0,${r3 - 1} ${ -13},0`,
5013
+ points: `0,${-r5 + 1} ${r5 - 1},0 0,${r5 - 1} ${ -13},0`,
5014
5014
  class: "lt-inst-body",
5015
5015
  fill: "none"
5016
5016
  })
5017
5017
  );
5018
5018
  } else if (isPlc) {
5019
- parts.push(circle({ cx: 0, cy: 0, r: r3, class: "lt-inst-body" }));
5020
- const side = r3 * Math.SQRT1_2 * 2 - 2;
5019
+ parts.push(circle({ cx: 0, cy: 0, r: r5, class: "lt-inst-body" }));
5020
+ const side = r5 * Math.SQRT1_2 * 2 - 2;
5021
5021
  parts.push(
5022
5022
  rect({
5023
5023
  x: -side / 2,
@@ -5029,11 +5029,11 @@ function renderInstrument(category, letterCode, loopNumber) {
5029
5029
  })
5030
5030
  );
5031
5031
  } else if (isShared) {
5032
- parts.push(circle({ cx: 0, cy: 0, r: r3, class: "lt-inst-body" }));
5032
+ parts.push(circle({ cx: 0, cy: 0, r: r5, class: "lt-inst-body" }));
5033
5033
  const hex = [];
5034
5034
  for (let i = 0; i < 6; i++) {
5035
5035
  const a = Math.PI / 3 * i - Math.PI / 2;
5036
- hex.push(`${(r3 - 2) * Math.cos(a)},${(r3 - 2) * Math.sin(a)}`);
5036
+ hex.push(`${(r5 - 2) * Math.cos(a)},${(r5 - 2) * Math.sin(a)}`);
5037
5037
  }
5038
5038
  parts.push(
5039
5039
  polygon({
@@ -5043,12 +5043,12 @@ function renderInstrument(category, letterCode, loopNumber) {
5043
5043
  })
5044
5044
  );
5045
5045
  } else {
5046
- parts.push(circle({ cx: 0, cy: 0, r: r3, class: "lt-inst-body" }));
5046
+ parts.push(circle({ cx: 0, cy: 0, r: r5, class: "lt-inst-body" }));
5047
5047
  }
5048
5048
  if (isControlRoom) {
5049
- parts.push(line({ x1: -r3, y1: 0, x2: r3, y2: 0, class: "lt-inst-cr-line" }));
5049
+ parts.push(line({ x1: -r5, y1: 0, x2: r5, y2: 0, class: "lt-inst-cr-line" }));
5050
5050
  } else if (isLocal) {
5051
- parts.push(line({ x1: -r3, y1: 0, x2: r3, y2: 0, class: "lt-inst-local-line" }));
5051
+ parts.push(line({ x1: -r5, y1: 0, x2: r5, y2: 0, class: "lt-inst-local-line" }));
5052
5052
  }
5053
5053
  parts.push(
5054
5054
  text(
@@ -5756,19 +5756,19 @@ function readScalar(map, key) {
5756
5756
  return { value, line: entry.header.line };
5757
5757
  }
5758
5758
  function readInt(map, key) {
5759
- const r3 = readScalar(map, key);
5760
- if (r3 === void 0) return void 0;
5761
- return parseInt10(r3.value, r3.line);
5759
+ const r5 = readScalar(map, key);
5760
+ if (r5 === void 0) return void 0;
5761
+ return parseInt10(r5.value, r5.line);
5762
5762
  }
5763
5763
  function readSources(map, key) {
5764
- const r3 = readScalar(map, key);
5765
- if (r3 === void 0) return void 0;
5766
- return parsePairs(r3.value, r3.line);
5764
+ const r5 = readScalar(map, key);
5765
+ if (r5 === void 0) return void 0;
5766
+ return parsePairs(r5.value, r5.line);
5767
5767
  }
5768
5768
  function readReasons(map, key) {
5769
- const r3 = readScalar(map, key);
5770
- if (r3 === void 0) return void 0;
5771
- return parsePairs(r3.value, r3.line);
5769
+ const r5 = readScalar(map, key);
5770
+ if (r5 === void 0) return void 0;
5771
+ return parsePairs(r5.value, r5.line);
5772
5772
  }
5773
5773
  function readBlock(map, key) {
5774
5774
  const entry = map.get(key);
@@ -6096,7 +6096,7 @@ function runArithmeticValidation(ast) {
6096
6096
  }
6097
6097
  }
6098
6098
  if (ast.screening.excluded.reasons && ast.screening.excluded.reasons.length > 0) {
6099
- const sum = ast.screening.excluded.reasons.reduce((a, r3) => a + r3.count, 0);
6099
+ const sum = ast.screening.excluded.reasons.reduce((a, r5) => a + r5.count, 0);
6100
6100
  if (sum !== screenedExcluded) {
6101
6101
  issues.push(
6102
6102
  `screening.excluded reasons sum to ${formatN(sum)} but n = ${formatN(screenedExcluded)}`
@@ -6104,7 +6104,7 @@ function runArithmeticValidation(ast) {
6104
6104
  }
6105
6105
  }
6106
6106
  if (ast.eligibility.excluded.reasons && ast.eligibility.excluded.reasons.length > 0) {
6107
- const sum = ast.eligibility.excluded.reasons.reduce((a, r3) => a + r3.count, 0);
6107
+ const sum = ast.eligibility.excluded.reasons.reduce((a, r5) => a + r5.count, 0);
6108
6108
  if (sum !== eligExcluded) {
6109
6109
  issues.push(
6110
6110
  `eligibility.excluded reasons sum to ${formatN(sum)} but n = ${formatN(eligExcluded)}`
@@ -6197,7 +6197,7 @@ function aggregateReasons(reasons) {
6197
6197
  const sorted = [...reasons].sort((a, b) => b.count - a.count);
6198
6198
  const head = sorted.slice(0, PRISMA_CONST.MAX_REASON_LINES - 1);
6199
6199
  const tail = sorted.slice(PRISMA_CONST.MAX_REASON_LINES - 1);
6200
- const otherSum = tail.reduce((a, r3) => a + r3.count, 0);
6200
+ const otherSum = tail.reduce((a, r5) => a + r5.count, 0);
6201
6201
  return {
6202
6202
  lines: [...head, { name: `Other (${tail.length} reasons)`, count: otherSum }],
6203
6203
  truncated: tail.length
@@ -6254,8 +6254,8 @@ function buildIdentificationRemovedBox(id, kind) {
6254
6254
  }
6255
6255
  if (removed.length === 0) return null;
6256
6256
  const lines = [{ text: v.recordsRemovedLabel, style: "label" }];
6257
- for (const r3 of removed) {
6258
- lines.push({ text: r3, style: "reason", indent: 1 });
6257
+ for (const r5 of removed) {
6258
+ lines.push({ text: r5, style: "reason", indent: 1 });
6259
6259
  }
6260
6260
  return {
6261
6261
  role: "id-removed",
@@ -6311,8 +6311,8 @@ function buildScreeningExcludedBox(n, reasons, kind) {
6311
6311
  { text: v.recordsExcluded, style: "label" },
6312
6312
  { text: `n = ${nFmt(n)}`, style: "count" }
6313
6313
  ];
6314
- for (const r3 of items) {
6315
- out.push({ text: `${r3.name} (n = ${nFmt(r3.count)})`, style: "reason", indent: 1 });
6314
+ for (const r5 of items) {
6315
+ out.push({ text: `${r5.name} (n = ${nFmt(r5.count)})`, style: "reason", indent: 1 });
6316
6316
  }
6317
6317
  return {
6318
6318
  role: "screening-excluded",
@@ -6342,8 +6342,8 @@ function buildEligibilityExcludedBox(n, reasons, kind) {
6342
6342
  { text: v.reportsExcluded, style: "label" },
6343
6343
  { text: `n = ${nFmt(n)}`, style: "count" }
6344
6344
  ];
6345
- for (const r3 of items) {
6346
- out.push({ text: `${r3.name} (n = ${nFmt(r3.count)})`, style: "reason", indent: 1 });
6345
+ for (const r5 of items) {
6346
+ out.push({ text: `${r5.name} (n = ${nFmt(r5.count)})`, style: "reason", indent: 1 });
6347
6347
  }
6348
6348
  return {
6349
6349
  role: "eligibility-excluded",
@@ -6944,7 +6944,7 @@ function classForEdge(kind) {
6944
6944
  }
6945
6945
  }
6946
6946
  function renderBand(band) {
6947
- const r3 = rect({
6947
+ const r5 = rect({
6948
6948
  x: band.x,
6949
6949
  y: band.y,
6950
6950
  width: band.width,
@@ -6967,10 +6967,10 @@ function renderBand(band) {
6967
6967
  },
6968
6968
  band.label
6969
6969
  );
6970
- return group({ "data-band": band.stage }, [r3, txt]);
6970
+ return group({ "data-band": band.stage }, [r5, txt]);
6971
6971
  }
6972
6972
  function renderHeader(h) {
6973
- const r3 = rect({
6973
+ const r5 = rect({
6974
6974
  x: h.x,
6975
6975
  y: h.y,
6976
6976
  width: h.width,
@@ -6995,10 +6995,10 @@ function renderHeader(h) {
6995
6995
  ln
6996
6996
  )
6997
6997
  );
6998
- return group({ "data-header": h.column }, [r3, ...lines]);
6998
+ return group({ "data-header": h.column }, [r5, ...lines]);
6999
6999
  }
7000
7000
  function renderBox(box) {
7001
- const r3 = rect({
7001
+ const r5 = rect({
7002
7002
  x: box.x,
7003
7003
  y: box.y,
7004
7004
  width: box.width,
@@ -7056,7 +7056,7 @@ function renderBox(box) {
7056
7056
  "data-prisma-variant": box.variant,
7057
7057
  "data-prisma-stage": box.stage
7058
7058
  },
7059
- [r3, ...textEls]
7059
+ [r5, ...textEls]
7060
7060
  );
7061
7061
  }
7062
7062
  function approxLineWidth(line2) {
@@ -7765,14 +7765,14 @@ function sizeEllipse(uc) {
7765
7765
  }
7766
7766
  function buildDeepEdges(ast, ucIds) {
7767
7767
  const edges = [];
7768
- for (const r3 of ast.relations) {
7769
- if (!ucIds.has(r3.source) || !ucIds.has(r3.target)) continue;
7770
- if (r3.kind === "include") {
7771
- edges.push({ from: r3.source, to: r3.target });
7772
- } else if (r3.kind === "extend") {
7773
- edges.push({ from: r3.target, to: r3.source });
7774
- } else if (r3.kind === "generalization") {
7775
- edges.push({ from: r3.source, to: r3.target });
7768
+ for (const r5 of ast.relations) {
7769
+ if (!ucIds.has(r5.source) || !ucIds.has(r5.target)) continue;
7770
+ if (r5.kind === "include") {
7771
+ edges.push({ from: r5.source, to: r5.target });
7772
+ } else if (r5.kind === "extend") {
7773
+ edges.push({ from: r5.target, to: r5.source });
7774
+ } else if (r5.kind === "generalization") {
7775
+ edges.push({ from: r5.source, to: r5.target });
7776
7776
  }
7777
7777
  }
7778
7778
  return edges;
@@ -7800,15 +7800,15 @@ function classifyActorSides(ast) {
7800
7800
  ast.actors.forEach((a, i) => idx.set(a.id, i));
7801
7801
  const parent = /* @__PURE__ */ new Map();
7802
7802
  const find = (x) => {
7803
- let r3 = x;
7804
- while ((parent.get(r3) ?? r3) !== r3) r3 = parent.get(r3) ?? r3;
7803
+ let r5 = x;
7804
+ while ((parent.get(r5) ?? r5) !== r5) r5 = parent.get(r5) ?? r5;
7805
7805
  let c = x;
7806
7806
  while ((parent.get(c) ?? c) !== c) {
7807
7807
  const next = parent.get(c) ?? c;
7808
- parent.set(c, r3);
7808
+ parent.set(c, r5);
7809
7809
  c = next;
7810
7810
  }
7811
- return r3;
7811
+ return r5;
7812
7812
  };
7813
7813
  const union = (a, b) => {
7814
7814
  const ra = find(a);
@@ -7818,9 +7818,9 @@ function classifyActorSides(ast) {
7818
7818
  else parent.set(ra, rb);
7819
7819
  };
7820
7820
  for (const a of ast.actors) parent.set(a.id, a.id);
7821
- for (const r3 of ast.relations) {
7822
- if (r3.kind === "generalization" && actorIds.has(r3.source) && actorIds.has(r3.target)) {
7823
- union(r3.source, r3.target);
7821
+ for (const r5 of ast.relations) {
7822
+ if (r5.kind === "generalization" && actorIds.has(r5.source) && actorIds.has(r5.target)) {
7823
+ union(r5.source, r5.target);
7824
7824
  }
7825
7825
  }
7826
7826
  const baseSide = (a, i) => a.side === "left" ? "left" : a.side === "right" ? "right" : i === 0 ? "left" : "right";
@@ -7855,10 +7855,10 @@ function layoutUsecase(ast) {
7855
7855
  const sides = classifyActorSides(ast);
7856
7856
  const connectedActors = /* @__PURE__ */ new Map();
7857
7857
  for (const u of ast.usecases) connectedActors.set(u.id, []);
7858
- for (const r3 of ast.relations) {
7859
- if (r3.kind !== "association" && r3.kind !== "directed") continue;
7860
- const aId = actorById.has(r3.source) ? r3.source : actorById.has(r3.target) ? r3.target : null;
7861
- const uId = ucIds.has(r3.source) ? r3.source : ucIds.has(r3.target) ? r3.target : null;
7858
+ for (const r5 of ast.relations) {
7859
+ if (r5.kind !== "association" && r5.kind !== "directed") continue;
7860
+ const aId = actorById.has(r5.source) ? r5.source : actorById.has(r5.target) ? r5.target : null;
7861
+ const uId = ucIds.has(r5.source) ? r5.source : ucIds.has(r5.target) ? r5.target : null;
7862
7862
  if (aId && uId) connectedActors.get(uId).push(aId);
7863
7863
  }
7864
7864
  const columns = [];
@@ -7897,10 +7897,10 @@ function layoutUsecase(ast) {
7897
7897
  });
7898
7898
  let prev = -Infinity;
7899
7899
  for (const u of col) {
7900
- let r3 = rowPos.get(u.id);
7901
- if (r3 <= prev) r3 = prev + 1;
7902
- rowPos.set(u.id, r3);
7903
- prev = r3;
7900
+ let r5 = rowPos.get(u.id);
7901
+ if (r5 <= prev) r5 = prev + 1;
7902
+ rowPos.set(u.id, r5);
7903
+ prev = r5;
7904
7904
  }
7905
7905
  }
7906
7906
  const colMaxRx = columns.map(
@@ -8046,10 +8046,10 @@ function layoutUsecase(ast) {
8046
8046
  const edges = [];
8047
8047
  const trees = [];
8048
8048
  const genByParent = /* @__PURE__ */ new Map();
8049
- for (const r3 of ast.relations) {
8050
- if (r3.kind !== "generalization") continue;
8051
- if (!genByParent.has(r3.target)) genByParent.set(r3.target, []);
8052
- genByParent.get(r3.target).push(r3);
8049
+ for (const r5 of ast.relations) {
8050
+ if (r5.kind !== "generalization") continue;
8051
+ if (!genByParent.has(r5.target)) genByParent.set(r5.target, []);
8052
+ genByParent.get(r5.target).push(r5);
8053
8053
  }
8054
8054
  const handledGen = /* @__PURE__ */ new Set();
8055
8055
  function nodeCenter(id) {
@@ -8083,11 +8083,11 @@ function layoutUsecase(ast) {
8083
8083
  }
8084
8084
  for (const [parentId, rels] of genByParent) {
8085
8085
  const useTree = ast.generalizationTree && rels.length >= C2.GEN_TREE_THRESHOLD;
8086
- const allActors = actorById2.has(parentId) && rels.every((r3) => actorById2.has(r3.source));
8086
+ const allActors = actorById2.has(parentId) && rels.every((r5) => actorById2.has(r5.source));
8087
8087
  if (allActors) {
8088
8088
  const side = sides.get(parentId) ?? "left";
8089
8089
  const pAnchor = actorGenAnchor(parentId, side);
8090
- const childAnchors = rels.map((r3) => ({ r: r3, p: actorGenAnchor(r3.source, side) }));
8090
+ const childAnchors = rels.map((r5) => ({ r: r5, p: actorGenAnchor(r5.source, side) }));
8091
8091
  const xs = [pAnchor.x, ...childAnchors.map((c) => c.p.x)];
8092
8092
  const ys = [pAnchor.y, ...childAnchors.map((c) => c.p.y)];
8093
8093
  const busX = side === "left" ? Math.min(...xs) - 20 : Math.max(...xs) + 20;
@@ -8103,7 +8103,7 @@ function layoutUsecase(ast) {
8103
8103
  }
8104
8104
  trees.push({
8105
8105
  parentId,
8106
- childIds: rels.map((r3) => r3.source),
8106
+ childIds: rels.map((r5) => r5.source),
8107
8107
  stemX: busX,
8108
8108
  stemTop: minY2,
8109
8109
  stemBottom: maxY2,
@@ -8126,7 +8126,7 @@ function layoutUsecase(ast) {
8126
8126
  if (!useTree) continue;
8127
8127
  const parent = nodeCenter(parentId);
8128
8128
  if (!parent) continue;
8129
- const childCenters = rels.map((r3) => nodeCenter(r3.source)).filter((c) => c !== null);
8129
+ const childCenters = rels.map((r5) => nodeCenter(r5.source)).filter((c) => c !== null);
8130
8130
  if (childCenters.length === 0) continue;
8131
8131
  const avgX = childCenters.reduce((s, c) => s + c.cx, 0) / childCenters.length;
8132
8132
  const avgY = childCenters.reduce((s, c) => s + c.cy, 0) / childCenters.length;
@@ -8137,14 +8137,14 @@ function layoutUsecase(ast) {
8137
8137
  const jx = pPt.x + dirX / len * C2.GEN_JUNCTION_OFFSET;
8138
8138
  const jy = pPt.y + dirY / len * C2.GEN_JUNCTION_OFFSET;
8139
8139
  const legPaths = [];
8140
- for (const r3 of rels) {
8141
- const cPt = perimeter(r3.source, jx, jy);
8140
+ for (const r5 of rels) {
8141
+ const cPt = perimeter(r5.source, jx, jy);
8142
8142
  legPaths.push(`M ${round(cPt.x)} ${round(cPt.y)} L ${round(jx)} ${round(jy)}`);
8143
- handledGen.add(r3);
8143
+ handledGen.add(r5);
8144
8144
  }
8145
8145
  trees.push({
8146
8146
  parentId,
8147
- childIds: rels.map((r3) => r3.source),
8147
+ childIds: rels.map((r5) => r5.source),
8148
8148
  stemX: jx,
8149
8149
  stemTop: jy,
8150
8150
  stemBottom: jy,
@@ -8152,72 +8152,72 @@ function layoutUsecase(ast) {
8152
8152
  legPaths
8153
8153
  });
8154
8154
  }
8155
- for (const r3 of ast.relations) {
8156
- if (handledGen.has(r3)) continue;
8157
- const a = nodeCenter(r3.source);
8158
- const b = nodeCenter(r3.target);
8155
+ for (const r5 of ast.relations) {
8156
+ if (handledGen.has(r5)) continue;
8157
+ const a = nodeCenter(r5.source);
8158
+ const b = nodeCenter(r5.target);
8159
8159
  if (!a || !b) continue;
8160
- if (r3.kind === "generalization" && actorById2.has(r3.source) && actorById2.has(r3.target)) {
8161
- const side = sides.get(r3.target) ?? "left";
8162
- const pAnchor = actorGenAnchor(r3.target, side);
8163
- const cAnchor = actorGenAnchor(r3.source, side);
8160
+ if (r5.kind === "generalization" && actorById2.has(r5.source) && actorById2.has(r5.target)) {
8161
+ const side = sides.get(r5.target) ?? "left";
8162
+ const pAnchor = actorGenAnchor(r5.target, side);
8163
+ const cAnchor = actorGenAnchor(r5.source, side);
8164
8164
  const busX = side === "left" ? Math.min(pAnchor.x, cAnchor.x) - 20 : Math.max(pAnchor.x, cAnchor.x) + 20;
8165
8165
  edges.push({
8166
- relation: r3,
8166
+ relation: r5,
8167
8167
  d: `M ${round(cAnchor.x)} ${round(cAnchor.y)} L ${round(busX)} ${round(cAnchor.y)} L ${round(busX)} ${round(pAnchor.y)} L ${round(pAnchor.x)} ${round(pAnchor.y)}`,
8168
8168
  arrowKind: "hollow",
8169
8169
  dashed: false
8170
8170
  });
8171
8171
  continue;
8172
8172
  }
8173
- const srcActor = actorById2.get(r3.source);
8174
- const tgtActor = actorById2.get(r3.target);
8173
+ const srcActor = actorById2.get(r5.source);
8174
+ const tgtActor = actorById2.get(r5.target);
8175
8175
  let pa;
8176
8176
  let pb;
8177
8177
  if (srcActor && !tgtActor) {
8178
8178
  pa = { x: srcActor.anchorX, y: srcActor.anchorY };
8179
- pb = perimeter(r3.target, pa.x, pa.y);
8179
+ pb = perimeter(r5.target, pa.x, pa.y);
8180
8180
  } else if (tgtActor && !srcActor) {
8181
8181
  pb = { x: tgtActor.anchorX, y: tgtActor.anchorY };
8182
- pa = perimeter(r3.source, pb.x, pb.y);
8182
+ pa = perimeter(r5.source, pb.x, pb.y);
8183
8183
  } else {
8184
- pa = perimeter(r3.source, b.cx, b.cy);
8185
- pb = perimeter(r3.target, a.cx, a.cy);
8184
+ pa = perimeter(r5.source, b.cx, b.cy);
8185
+ pb = perimeter(r5.target, a.cx, a.cy);
8186
8186
  }
8187
- const dashed = r3.kind === "include" || r3.kind === "extend";
8187
+ const dashed = r5.kind === "include" || r5.kind === "extend";
8188
8188
  let arrowKind2 = "none";
8189
- if (r3.kind === "directed" || r3.kind === "include" || r3.kind === "extend") arrowKind2 = "open";
8190
- else if (r3.kind === "generalization") arrowKind2 = "hollow";
8189
+ if (r5.kind === "directed" || r5.kind === "include" || r5.kind === "extend") arrowKind2 = "open";
8190
+ else if (r5.kind === "generalization") arrowKind2 = "hollow";
8191
8191
  const edge = {
8192
- relation: r3,
8192
+ relation: r5,
8193
8193
  d: `M ${round(pa.x)} ${round(pa.y)} L ${round(pb.x)} ${round(pb.y)}`,
8194
8194
  arrowKind: arrowKind2,
8195
8195
  dashed
8196
8196
  };
8197
- if (r3.kind === "include" || r3.kind === "extend") {
8197
+ if (r5.kind === "include" || r5.kind === "extend") {
8198
8198
  const rows = [];
8199
- const keyword = r3.kind === "include" ? "include" : "extend";
8200
- rows.push(`\xAB${r3.stereotype ?? keyword}\xBB`);
8201
- if (r3.condition) rows.push(`[${r3.condition}]`);
8202
- if (r3.extensionPointRef) rows.push(`(extension point: ${r3.extensionPointRef})`);
8199
+ const keyword = r5.kind === "include" ? "include" : "extend";
8200
+ rows.push(`\xAB${r5.stereotype ?? keyword}\xBB`);
8201
+ if (r5.condition) rows.push(`[${r5.condition}]`);
8202
+ if (r5.extensionPointRef) rows.push(`(extension point: ${r5.extensionPointRef})`);
8203
8203
  const label = {
8204
8204
  rows,
8205
8205
  cx: (pa.x + pb.x) / 2,
8206
8206
  cy: (pa.y + pb.y) / 2
8207
8207
  };
8208
8208
  edge.label = label;
8209
- } else if ((r3.kind === "association" || r3.kind === "directed") && r3.stereotype) {
8209
+ } else if ((r5.kind === "association" || r5.kind === "directed") && r5.stereotype) {
8210
8210
  edge.label = {
8211
- rows: [`\xAB${r3.stereotype}\xBB`],
8211
+ rows: [`\xAB${r5.stereotype}\xBB`],
8212
8212
  cx: (pa.x + pb.x) / 2,
8213
8213
  cy: (pa.y + pb.y) / 2
8214
8214
  };
8215
8215
  }
8216
- if (r3.sourceMultiplicity) {
8217
- edge.multiplicityFrom = placeMultiplicity(pa, pb, r3.sourceMultiplicity);
8216
+ if (r5.sourceMultiplicity) {
8217
+ edge.multiplicityFrom = placeMultiplicity(pa, pb, r5.sourceMultiplicity);
8218
8218
  }
8219
- if (r3.targetMultiplicity) {
8220
- edge.multiplicityTo = placeMultiplicity(pb, pa, r3.targetMultiplicity);
8219
+ if (r5.targetMultiplicity) {
8220
+ edge.multiplicityTo = placeMultiplicity(pb, pa, r5.targetMultiplicity);
8221
8221
  }
8222
8222
  edges.push(edge);
8223
8223
  }
@@ -8472,7 +8472,7 @@ function renderEdgeLabel(e) {
8472
8472
  const rows = e.label.rows;
8473
8473
  const lineH = 12;
8474
8474
  const totalH = rows.length * lineH;
8475
- const widest = rows.reduce((m, r3) => Math.max(m, r3.length), 0);
8475
+ const widest = rows.reduce((m, r5) => Math.max(m, r5.length), 0);
8476
8476
  const pillW = widest * 6 + 8;
8477
8477
  const pillH = totalH + 4;
8478
8478
  const startY = e.label.cy - totalH / 2 + 9;
@@ -8488,7 +8488,7 @@ function renderEdgeLabel(e) {
8488
8488
  ry: 4
8489
8489
  })
8490
8490
  ];
8491
- rows.forEach((r3, i) => {
8491
+ rows.forEach((r5, i) => {
8492
8492
  parts.push(
8493
8493
  text(
8494
8494
  {
@@ -8497,7 +8497,7 @@ function renderEdgeLabel(e) {
8497
8497
  y: startY + i * lineH,
8498
8498
  "text-anchor": "middle"
8499
8499
  },
8500
- r3
8500
+ r5
8501
8501
  )
8502
8502
  );
8503
8503
  });
@@ -8537,8 +8537,8 @@ function renderTree(tr) {
8537
8537
  function renderUsecaseLayout(layout, config) {
8538
8538
  const t = resolveBaseTheme(config?.theme ?? "default");
8539
8539
  const children = [];
8540
- const nInclude = layout.ast.relations.filter((r3) => r3.kind === "include").length;
8541
- const nExtend = layout.ast.relations.filter((r3) => r3.kind === "extend").length;
8540
+ const nInclude = layout.ast.relations.filter((r5) => r5.kind === "include").length;
8541
+ const nExtend = layout.ast.relations.filter((r5) => r5.kind === "extend").length;
8542
8542
  children.push(title(`Use Case Diagram${layout.title ? " \u2014 " + layout.title : ""}`));
8543
8543
  children.push(
8544
8544
  desc(
@@ -9286,12 +9286,12 @@ function layoutAoa(ast, schedule) {
9286
9286
  const predEvents = (e) => inAdj[e].map((ai) => arcs[ai].from);
9287
9287
  const succEvents = (e) => outAdj[e].map((ai) => arcs[ai].to);
9288
9288
  for (let iter = 0; iter < 4; iter++) {
9289
- for (let r3 = 1; r3 <= maxRank; r3++) {
9290
- layers[r3] = sortByBary(layers[r3], predEvents, pos);
9289
+ for (let r5 = 1; r5 <= maxRank; r5++) {
9290
+ layers[r5] = sortByBary(layers[r5], predEvents, pos);
9291
9291
  refresh(layers, pos);
9292
9292
  }
9293
- for (let r3 = maxRank - 1; r3 >= 0; r3--) {
9294
- layers[r3] = sortByBary(layers[r3], succEvents, pos);
9293
+ for (let r5 = maxRank - 1; r5 >= 0; r5--) {
9294
+ layers[r5] = sortByBary(layers[r5], succEvents, pos);
9295
9295
  refresh(layers, pos);
9296
9296
  }
9297
9297
  }
@@ -9301,12 +9301,12 @@ function layoutAoa(ast, schedule) {
9301
9301
  const contentH = (maxRows - 1) * AOA.VGAP + 2 * AOA.R;
9302
9302
  const cx = new Array(nEvents).fill(0);
9303
9303
  const cy = new Array(nEvents).fill(0);
9304
- for (let r3 = 0; r3 <= maxRank; r3++) {
9305
- const layer = layers[r3];
9304
+ for (let r5 = 0; r5 <= maxRank; r5++) {
9305
+ const layer = layers[r5];
9306
9306
  const colH = (layer.length - 1) * AOA.VGAP;
9307
9307
  const y0 = topY + AOA.R + (contentH - 2 * AOA.R - colH) / 2;
9308
9308
  layer.forEach((e, i) => {
9309
- cx[e] = AOA.PAD + AOA.R + r3 * AOA.COL;
9309
+ cx[e] = AOA.PAD + AOA.R + r5 * AOA.COL;
9310
9310
  cy[e] = y0 + i * AOA.VGAP;
9311
9311
  });
9312
9312
  }
@@ -9368,16 +9368,16 @@ function sortByBary(layer, neighbors, pos) {
9368
9368
  return { e, i, bary };
9369
9369
  }).sort((a, b) => a.bary !== b.bary ? a.bary - b.bary : a.i - b.i).map((x) => x.e);
9370
9370
  }
9371
- function arcGeometry(tx, ty, hx, hy, r3) {
9371
+ function arcGeometry(tx, ty, hx, hy, r5) {
9372
9372
  const dx = hx - tx;
9373
9373
  const dy = hy - ty;
9374
9374
  const len = Math.hypot(dx, dy) || 1;
9375
9375
  const ux = dx / len;
9376
9376
  const uy = dy / len;
9377
- const sx = tx + ux * r3;
9378
- const sy = ty + uy * r3;
9379
- const ex = hx - ux * r3;
9380
- const ey = hy - uy * r3;
9377
+ const sx = tx + ux * r5;
9378
+ const sy = ty + uy * r5;
9379
+ const ex = hx - ux * r5;
9380
+ const ey = hy - uy * r5;
9381
9381
  return { d: `M ${round3(sx)} ${round3(sy)} L ${round3(ex)} ${round3(ey)}`, mx: (sx + ex) / 2, my: (sy + ey) / 2 };
9382
9382
  }
9383
9383
  function buildAoaSummary(ast, sched) {
@@ -9450,11 +9450,11 @@ function assignRanks(ast) {
9450
9450
  if (visiting.has(id)) return 0;
9451
9451
  visiting.add(id);
9452
9452
  const t = byId.get(id);
9453
- let r3 = 0;
9454
- for (const dep of t.deps) r3 = Math.max(r3, compute(dep.pred) + 1);
9453
+ let r5 = 0;
9454
+ for (const dep of t.deps) r5 = Math.max(r5, compute(dep.pred) + 1);
9455
9455
  visiting.delete(id);
9456
- rank.set(id, r3);
9457
- return r3;
9456
+ rank.set(id, r5);
9457
+ return r5;
9458
9458
  };
9459
9459
  let maxRank = 0;
9460
9460
  for (const t of ast.tasks) maxRank = Math.max(maxRank, compute(t.id));
@@ -9500,15 +9500,15 @@ function orderLayers(ast, schedule, rank, maxRank) {
9500
9500
  return s / neighbors.length;
9501
9501
  };
9502
9502
  for (let iter = 0; iter < 4; iter++) {
9503
- for (let r3 = 1; r3 <= maxRank; r3++) {
9504
- layers[r3] = stableSortByKey(layers[r3], (id) => {
9503
+ for (let r5 = 1; r5 <= maxRank; r5++) {
9504
+ layers[r5] = stableSortByKey(layers[r5], (id) => {
9505
9505
  const bc = barycenter(id, pred.get(id));
9506
9506
  return crit(id) ? bc - 0.4 : bc;
9507
9507
  });
9508
9508
  refreshPos();
9509
9509
  }
9510
- for (let r3 = maxRank - 1; r3 >= 0; r3--) {
9511
- layers[r3] = stableSortByKey(layers[r3], (id) => {
9510
+ for (let r5 = maxRank - 1; r5 >= 0; r5--) {
9511
+ layers[r5] = stableSortByKey(layers[r5], (id) => {
9512
9512
  const bc = barycenter(id, succ.get(id));
9513
9513
  return crit(id) ? bc - 0.4 : bc;
9514
9514
  });
@@ -9560,9 +9560,9 @@ function layoutNetwork(ast, schedule) {
9560
9560
  const originCross = dir === "TB" ? C2.PAD : C2.PAD + titleH;
9561
9561
  const boxes = [];
9562
9562
  const boxById = /* @__PURE__ */ new Map();
9563
- for (let r3 = 0; r3 <= maxRank; r3++) {
9564
- const layer = layers[r3];
9565
- const extent = colExtent[r3];
9563
+ for (let r5 = 0; r5 <= maxRank; r5++) {
9564
+ const layer = layers[r5];
9565
+ const extent = colExtent[r5];
9566
9566
  const crossStart = originCross + (maxExtent - extent) / 2;
9567
9567
  let cursor = crossStart;
9568
9568
  for (const id of layer) {
@@ -9573,12 +9573,12 @@ function layoutNetwork(ast, schedule) {
9573
9573
  let x;
9574
9574
  let y;
9575
9575
  if (dir === "TB") {
9576
- const rankPos = originPrimary + r3 * (C2.BOX_H + C2.H_GAP);
9576
+ const rankPos = originPrimary + r5 * (C2.BOX_H + C2.H_GAP);
9577
9577
  x = cursor + (C2.BOX_W - w) / 2;
9578
9578
  y = rankPos;
9579
9579
  cursor += C2.BOX_W + C2.H_GAP;
9580
9580
  } else {
9581
- const rankPos = originPrimary + r3 * (C2.BOX_W + C2.H_GAP);
9581
+ const rankPos = originPrimary + r5 * (C2.BOX_W + C2.H_GAP);
9582
9582
  x = rankPos + (C2.BOX_W - w) / 2;
9583
9583
  y = cursor;
9584
9584
  cursor += C2.BOX_H + C2.V_GAP;
@@ -9592,7 +9592,7 @@ function layoutNetwork(ast, schedule) {
9592
9592
  width: w,
9593
9593
  height: h,
9594
9594
  milestone: t.milestone,
9595
- rank: r3
9595
+ rank: r5
9596
9596
  };
9597
9597
  boxes.push(box);
9598
9598
  boxById.set(id, box);
@@ -9752,7 +9752,7 @@ function layoutSwimlane2(ast, schedule) {
9752
9752
  const crit = (id) => schedule.computed.get(id).critical;
9753
9753
  const es = (id) => schedule.computed.get(id).es;
9754
9754
  const cell = /* @__PURE__ */ new Map();
9755
- const key = (lane, r3) => `${lane}\0${r3}`;
9755
+ const key = (lane, r5) => `${lane}\0${r5}`;
9756
9756
  for (const t of ast.tasks) {
9757
9757
  const k = key(laneOf.get(t.id), rank.get(t.id));
9758
9758
  if (!cell.has(k)) cell.set(k, []);
@@ -9769,15 +9769,15 @@ function layoutSwimlane2(ast, schedule) {
9769
9769
  }
9770
9770
  const titleH = ast.title ? C2.TITLE_H : 0;
9771
9771
  const topY = C2.PAD + titleH;
9772
- const colX = (r3) => C2.LANE_LABEL_W + C2.PAD + r3 * (C2.BOX_W + C2.H_GAP);
9772
+ const colX = (r5) => C2.LANE_LABEL_W + C2.PAD + r5 * (C2.BOX_W + C2.H_GAP);
9773
9773
  const lanes = [];
9774
9774
  const laneY = /* @__PURE__ */ new Map();
9775
9775
  const laneH = /* @__PURE__ */ new Map();
9776
9776
  let cursor = topY;
9777
9777
  laneOrder.forEach((lane, i) => {
9778
9778
  let stack = 1;
9779
- for (let r3 = 0; r3 <= maxRank; r3++) {
9780
- const arr = cell.get(key(lane, r3));
9779
+ for (let r5 = 0; r5 <= maxRank; r5++) {
9780
+ const arr = cell.get(key(lane, r5));
9781
9781
  if (arr) stack = Math.max(stack, arr.length);
9782
9782
  }
9783
9783
  const bandH = stack * C2.BOX_H + (stack - 1) * C2.V_GAP + 2 * C2.LANE_PAD;
@@ -9792,15 +9792,15 @@ function layoutSwimlane2(ast, schedule) {
9792
9792
  for (const lane of laneOrder) {
9793
9793
  const bandTop = laneY.get(lane);
9794
9794
  const bandH = laneH.get(lane);
9795
- for (let r3 = 0; r3 <= maxRank; r3++) {
9796
- const arr = cell.get(key(lane, r3));
9795
+ for (let r5 = 0; r5 <= maxRank; r5++) {
9796
+ const arr = cell.get(key(lane, r5));
9797
9797
  if (!arr) continue;
9798
9798
  const colInnerH = arr.length * C2.BOX_H + (arr.length - 1) * C2.V_GAP;
9799
9799
  const y0 = bandTop + (bandH - colInnerH) / 2;
9800
9800
  arr.forEach((id, idx) => {
9801
9801
  const t = byId.get(id);
9802
9802
  const w = t.milestone ? C2.MS_W : C2.BOX_W;
9803
- const x = colX(r3) + (C2.BOX_W - w) / 2;
9803
+ const x = colX(r5) + (C2.BOX_W - w) / 2;
9804
9804
  const y = y0 + idx * (C2.BOX_H + C2.V_GAP);
9805
9805
  const box = {
9806
9806
  id,
@@ -9811,7 +9811,7 @@ function layoutSwimlane2(ast, schedule) {
9811
9811
  width: w,
9812
9812
  height: C2.BOX_H,
9813
9813
  milestone: t.milestone,
9814
- rank: r3
9814
+ rank: r5
9815
9815
  };
9816
9816
  boxes.push(box);
9817
9817
  boxById.set(id, box);
@@ -11478,18 +11478,18 @@ function renderFragmentTab(f) {
11478
11478
  });
11479
11479
  return group({ class: "sx-seq-fragment-tab-g", "data-op": f.op }, parts);
11480
11480
  }
11481
- function renderRef(r3) {
11481
+ function renderRef(r5) {
11482
11482
  const tabW = 40;
11483
11483
  const tabH = 18;
11484
11484
  const fold = 6;
11485
- const tab = `M ${r3.x} ${r3.y} H ${r3.x + tabW} V ${r3.y + tabH - fold} L ${r3.x + tabW - fold} ${r3.y + tabH} H ${r3.x} Z`;
11485
+ const tab = `M ${r5.x} ${r5.y} H ${r5.x + tabW} V ${r5.y + tabH - fold} L ${r5.x + tabW - fold} ${r5.y + tabH} H ${r5.x} Z`;
11486
11486
  return group({ class: "sx-seq-fragment", "data-op": "ref" }, [
11487
- rect({ class: "sx-seq-frame", x: r3.x, y: r3.y, width: r3.width, height: r3.height, rx: 2, ry: 2 }),
11487
+ rect({ class: "sx-seq-frame", x: r5.x, y: r5.y, width: r5.width, height: r5.height, rx: 2, ry: 2 }),
11488
11488
  path({ class: "sx-seq-frame-tab", d: tab }),
11489
- text({ class: "sx-seq-frame-op", x: r3.x + 8, y: r3.y + 13 }, "ref"),
11489
+ text({ class: "sx-seq-frame-op", x: r5.x + 8, y: r5.y + 13 }, "ref"),
11490
11490
  text(
11491
- { class: "sx-seq-ref-name", x: r3.x + r3.width / 2, y: r3.y + r3.height / 2 + 8, "text-anchor": "middle" },
11492
- r3.text
11491
+ { class: "sx-seq-ref-name", x: r5.x + r5.width / 2, y: r5.y + r5.height / 2 + 8, "text-anchor": "middle" },
11492
+ r5.text
11493
11493
  )
11494
11494
  ]);
11495
11495
  }
@@ -11526,10 +11526,10 @@ function renderInvariant(iv) {
11526
11526
  ]);
11527
11527
  }
11528
11528
  function renderDestroy(d) {
11529
- const r3 = 7;
11529
+ const r5 = 7;
11530
11530
  return group({ class: "sx-seq-destroy-g" }, [
11531
- line({ class: "sx-seq-destroy", x1: d.x - r3, y1: d.y - r3, x2: d.x + r3, y2: d.y + r3 }),
11532
- line({ class: "sx-seq-destroy", x1: d.x - r3, y1: d.y + r3, x2: d.x + r3, y2: d.y - r3 })
11531
+ line({ class: "sx-seq-destroy", x1: d.x - r5, y1: d.y - r5, x2: d.x + r5, y2: d.y + r5 }),
11532
+ line({ class: "sx-seq-destroy", x1: d.x - r5, y1: d.y + r5, x2: d.x + r5, y2: d.y - r5 })
11533
11533
  ]);
11534
11534
  }
11535
11535
  function renderSequenceLayout(layout, config) {
@@ -12372,10 +12372,10 @@ function renderArc(ag) {
12372
12372
  const dx = last.x - prev.x;
12373
12373
  const dy = last.y - prev.y;
12374
12374
  const len = Math.hypot(dx, dy) || 1;
12375
- const r3 = 4;
12376
- const cx = last.x - dx / len * r3;
12377
- const cy = last.y - dy / len * r3;
12378
- parts.push(circle({ class: "sx-petri-inhibitor-dot", cx, cy, r: r3 }));
12375
+ const r5 = 4;
12376
+ const cx = last.x - dx / len * r5;
12377
+ const cy = last.y - dy / len * r5;
12378
+ parts.push(circle({ class: "sx-petri-inhibitor-dot", cx, cy, r: r5 }));
12379
12379
  }
12380
12380
  if (ag.weight > 1) {
12381
12381
  parts.push(
@@ -12773,10 +12773,10 @@ function parseNetwork(text2) {
12773
12773
  if (rest[0]) ast.title = rest[0].value;
12774
12774
  break;
12775
12775
  case "spines":
12776
- ast.spines.push(...rest.filter((r3) => !r3.str).map((r3) => r3.value));
12776
+ ast.spines.push(...rest.filter((r5) => !r5.str).map((r5) => r5.value));
12777
12777
  break;
12778
12778
  case "leaves":
12779
- ast.leaves.push(...rest.filter((r3) => !r3.str).map((r3) => r3.value));
12779
+ ast.leaves.push(...rest.filter((r5) => !r5.str).map((r5) => r5.value));
12780
12780
  break;
12781
12781
  case "legend":
12782
12782
  break;
@@ -13345,29 +13345,29 @@ function placeBanded(ast, ranks) {
13345
13345
  const lr = ast.direction === "lr";
13346
13346
  const byRank = /* @__PURE__ */ new Map();
13347
13347
  for (const d of ast.devices) {
13348
- const r3 = ranks.get(d.id) ?? 0;
13349
- if (!byRank.has(r3)) byRank.set(r3, []);
13350
- byRank.get(r3).push(d);
13348
+ const r5 = ranks.get(d.id) ?? 0;
13349
+ if (!byRank.has(r5)) byRank.set(r5, []);
13350
+ byRank.get(r5).push(d);
13351
13351
  }
13352
13352
  const rankValues = [...byRank.keys()].sort((a, b) => a - b);
13353
13353
  const pos = /* @__PURE__ */ new Map();
13354
13354
  let maxRowSpan = 0;
13355
13355
  const rowSpans = /* @__PURE__ */ new Map();
13356
- for (const r3 of rankValues) {
13357
- const devs = byRank.get(r3);
13356
+ for (const r5 of rankValues) {
13357
+ const devs = byRank.get(r5);
13358
13358
  let span = 0;
13359
13359
  devs.forEach((d, i) => {
13360
13360
  const fp = deviceFootprint(d);
13361
13361
  const cross = lr ? fp.h + labelExtra(d) : Math.max(fp.w, labelText(d).length * NET_CONST.CHAR_W + 6);
13362
13362
  span += cross + (i > 0 ? NET_CONST.SIBLING_GAP : 0);
13363
13363
  });
13364
- rowSpans.set(r3, span);
13364
+ rowSpans.set(r5, span);
13365
13365
  maxRowSpan = Math.max(maxRowSpan, span);
13366
13366
  }
13367
- rankValues.forEach((r3, rowIdx) => {
13368
- const devs = byRank.get(r3);
13367
+ rankValues.forEach((r5, rowIdx) => {
13368
+ const devs = byRank.get(r5);
13369
13369
  const along = rowIdx * NET_CONST.TIER_BAND_GAP;
13370
- let cursor = (maxRowSpan - rowSpans.get(r3)) / 2;
13370
+ let cursor = (maxRowSpan - rowSpans.get(r5)) / 2;
13371
13371
  for (const d of devs) {
13372
13372
  const fp = deviceFootprint(d);
13373
13373
  const cross = lr ? fp.h + labelExtra(d) : Math.max(fp.w, labelText(d).length * NET_CONST.CHAR_W + 6);
@@ -13402,8 +13402,8 @@ function tieredRanks(ast, links) {
13402
13402
  if (rank.has(d.id)) continue;
13403
13403
  const known = [];
13404
13404
  for (const n of adj.get(d.id) ?? []) {
13405
- const r3 = rank.get(n);
13406
- if (r3 !== void 0) known.push(r3);
13405
+ const r5 = rank.get(n);
13406
+ if (r5 !== void 0) known.push(r5);
13407
13407
  }
13408
13408
  if (known.length === 0) continue;
13409
13409
  const next = ENDPOINT_KINDS.has(d.kind) ? Math.max(...known) + 1 : Math.min(...known) + 1;
@@ -13437,10 +13437,10 @@ function treeRanks(ast, links) {
13437
13437
  rank.set(root.id, 0);
13438
13438
  while (queue.length) {
13439
13439
  const id = queue.shift();
13440
- const r3 = rank.get(id);
13440
+ const r5 = rank.get(id);
13441
13441
  for (const n of adj.get(id) ?? []) {
13442
13442
  if (!rank.has(n)) {
13443
- rank.set(n, r3 + 1);
13443
+ rank.set(n, r5 + 1);
13444
13444
  queue.push(n);
13445
13445
  }
13446
13446
  }
@@ -13624,11 +13624,11 @@ function layoutNetwork2(ast) {
13624
13624
  };
13625
13625
  const groupsByDepth = [...ast.groups].sort((a, b) => depthOf(b.id) - depthOf(a.id));
13626
13626
  for (const g of groupsByDepth) {
13627
- let l = Infinity, t = Infinity, r3 = -Infinity, bm = -Infinity;
13627
+ let l = Infinity, t = Infinity, r5 = -Infinity, bm = -Infinity;
13628
13628
  const addBox = (e) => {
13629
13629
  l = Math.min(l, e.left);
13630
13630
  t = Math.min(t, e.top);
13631
- r3 = Math.max(r3, e.right);
13631
+ r5 = Math.max(r5, e.right);
13632
13632
  bm = Math.max(bm, e.bottom);
13633
13633
  };
13634
13634
  for (const mid of g.members) {
@@ -13645,7 +13645,7 @@ function layoutNetwork2(ast) {
13645
13645
  groupBoxesRaw.set(g.id, {
13646
13646
  left: l - pad,
13647
13647
  top: t - pad - NET_CONST.GROUP_HEADER,
13648
- right: r3 + pad,
13648
+ right: r5 + pad,
13649
13649
  bottom: bm + pad,
13650
13650
  depth
13651
13651
  });
@@ -14065,10 +14065,10 @@ function parseUmlClass(text2) {
14065
14065
  }
14066
14066
  const rels = tryParseRelationship(t, i + 1);
14067
14067
  if (rels) {
14068
- for (const r3 of rels) {
14069
- ast.relationships.push(r3);
14070
- ensureClassifier(ast, r3.from);
14071
- ensureClassifier(ast, r3.to);
14068
+ for (const r5 of rels) {
14069
+ ast.relationships.push(r5);
14070
+ ensureClassifier(ast, r5.from);
14071
+ ensureClassifier(ast, r5.to);
14072
14072
  }
14073
14073
  i++;
14074
14074
  continue;
@@ -14623,11 +14623,11 @@ function findConnector(line2, glyph) {
14623
14623
  }
14624
14624
  function validateGeneralizationAcyclicity(ast) {
14625
14625
  const adj = /* @__PURE__ */ new Map();
14626
- for (const r3 of ast.relationships) {
14627
- if (r3.kind === "generalization" || r3.kind === "realization") {
14628
- const list = adj.get(r3.from) ?? [];
14629
- list.push(r3.to);
14630
- adj.set(r3.from, list);
14626
+ for (const r5 of ast.relationships) {
14627
+ if (r5.kind === "generalization" || r5.kind === "realization") {
14628
+ const list = adj.get(r5.from) ?? [];
14629
+ list.push(r5.to);
14630
+ adj.set(r5.from, list);
14631
14631
  }
14632
14632
  }
14633
14633
  const WHITE = 0, GREY = 1, BLACK = 2;
@@ -14660,12 +14660,12 @@ function validateGeneralizationAcyclicity(ast) {
14660
14660
  }
14661
14661
  }
14662
14662
  function validateRealizationTargets(ast) {
14663
- for (const r3 of ast.relationships) {
14664
- if (r3.kind !== "realization") continue;
14665
- const target = ast.classifiers.find((c) => c.id === r3.to);
14663
+ for (const r5 of ast.relationships) {
14664
+ if (r5.kind !== "realization") continue;
14665
+ const target = ast.classifiers.find((c) => c.id === r5.to);
14666
14666
  if (target && target.kind !== "interface") {
14667
14667
  ast.warnings.push(
14668
- `Realization target "${r3.to}" is not an \xABinterface\xBB \u2014 consider marking it so.`
14668
+ `Realization target "${r5.to}" is not an \xABinterface\xBB \u2014 consider marking it so.`
14669
14669
  );
14670
14670
  }
14671
14671
  }
@@ -15143,16 +15143,16 @@ function memberLineText(m) {
15143
15143
  const props = m.properties && m.properties.length > 0 ? ` {${m.properties.join(", ")}}` : "";
15144
15144
  return `${v}${m.name}(${params})${ret}${props}`;
15145
15145
  }
15146
- function rankEnds(r3) {
15147
- switch (r3.kind) {
15146
+ function rankEnds(r5) {
15147
+ switch (r5.kind) {
15148
15148
  case "generalization":
15149
15149
  case "realization":
15150
- return { parent: r3.to, child: r3.from };
15150
+ return { parent: r5.to, child: r5.from };
15151
15151
  case "composition":
15152
15152
  case "aggregation":
15153
15153
  case "directed":
15154
15154
  case "dependency":
15155
- return { parent: r3.from, child: r3.to };
15155
+ return { parent: r5.from, child: r5.to };
15156
15156
  case "association":
15157
15157
  return null;
15158
15158
  }
@@ -15160,8 +15160,8 @@ function rankEnds(r3) {
15160
15160
  function computeRanks(ast, boxes) {
15161
15161
  const parentsOf = /* @__PURE__ */ new Map();
15162
15162
  for (const b of boxes) parentsOf.set(b.classifier.id, /* @__PURE__ */ new Set());
15163
- for (const r3 of ast.relationships) {
15164
- const ends = rankEnds(r3);
15163
+ for (const r5 of ast.relationships) {
15164
+ const ends = rankEnds(r5);
15165
15165
  if (ends) parentsOf.get(ends.child)?.add(ends.parent);
15166
15166
  }
15167
15167
  const rank = /* @__PURE__ */ new Map();
@@ -15203,19 +15203,19 @@ function buildLayeredGraph(rels, boxes, rankByID) {
15203
15203
  byID.set(n.id, n);
15204
15204
  }
15205
15205
  const chains = [];
15206
- for (const r3 of rels) {
15207
- const a = byID.get(r3.from);
15208
- const b = byID.get(r3.to);
15206
+ for (const r5 of rels) {
15207
+ const a = byID.get(r5.from);
15208
+ const b = byID.get(r5.to);
15209
15209
  if (!a || !b) continue;
15210
15210
  if (a.rank === b.rank) {
15211
- chains.push({ rel: r3, chain: [a.id, b.id], sameRank: true });
15211
+ chains.push({ rel: r5, chain: [a.id, b.id], sameRank: true });
15212
15212
  continue;
15213
15213
  }
15214
15214
  const lo = a.rank < b.rank ? a : b;
15215
15215
  const hi = a.rank < b.rank ? b : a;
15216
15216
  const diff = hi.rank - lo.rank;
15217
15217
  if (diff === 1) {
15218
- chains.push({ rel: r3, chain: [r3.from, r3.to], sameRank: false });
15218
+ chains.push({ rel: r5, chain: [r5.from, r5.to], sameRank: false });
15219
15219
  continue;
15220
15220
  }
15221
15221
  const innerDummies = [];
@@ -15236,7 +15236,7 @@ function buildLayeredGraph(rels, boxes, rankByID) {
15236
15236
  }
15237
15237
  const lowToHigh = [lo.id, ...innerDummies, hi.id];
15238
15238
  const chain = a.rank < b.rank ? lowToHigh : [...lowToHigh].reverse();
15239
- chains.push({ rel: r3, chain, sameRank: false });
15239
+ chains.push({ rel: r5, chain, sameRank: false });
15240
15240
  }
15241
15241
  return { nodes, chains };
15242
15242
  }
@@ -15276,12 +15276,12 @@ function orderRanks(ranks, chains) {
15276
15276
  for (let iter = 0; iter < UMLCLASS_CONST.ORDER_ITERATIONS; iter++) {
15277
15277
  const downward = iter % 2 === 0;
15278
15278
  if (downward) {
15279
- for (let r3 = 1; r3 < ranks.length; r3++) {
15280
- applyBarycenter(ranks[r3], ranks[r3 - 1], up);
15279
+ for (let r5 = 1; r5 < ranks.length; r5++) {
15280
+ applyBarycenter(ranks[r5], ranks[r5 - 1], up);
15281
15281
  }
15282
15282
  } else {
15283
- for (let r3 = ranks.length - 2; r3 >= 0; r3--) {
15284
- applyBarycenter(ranks[r3], ranks[r3 + 1], down);
15283
+ for (let r5 = ranks.length - 2; r5 >= 0; r5--) {
15284
+ applyBarycenter(ranks[r5], ranks[r5 + 1], down);
15285
15285
  }
15286
15286
  }
15287
15287
  }
@@ -15420,22 +15420,22 @@ function routeEdges(chains, nodes, boxByID, vertical) {
15420
15420
  const handled = /* @__PURE__ */ new Set();
15421
15421
  const groups = /* @__PURE__ */ new Map();
15422
15422
  for (const c of chains) {
15423
- const r3 = c.rel;
15424
- if (r3.kind !== "generalization" && r3.kind !== "realization") continue;
15425
- const k = `${r3.kind}::${r3.to}`;
15426
- if (!groups.has(k)) groups.set(k, { kind: r3.kind, parentId: r3.to, rels: [] });
15427
- groups.get(k).rels.push(r3);
15423
+ const r5 = c.rel;
15424
+ if (r5.kind !== "generalization" && r5.kind !== "realization") continue;
15425
+ const k = `${r5.kind}::${r5.to}`;
15426
+ if (!groups.has(k)) groups.set(k, { kind: r5.kind, parentId: r5.to, rels: [] });
15427
+ groups.get(k).rels.push(r5);
15428
15428
  }
15429
15429
  for (const [, group2] of groups) {
15430
15430
  if (group2.rels.length < UMLCLASS_CONST.TREE_MERGE_THRESHOLD) continue;
15431
15431
  const parent = boxByID.get(group2.parentId);
15432
15432
  if (!parent) continue;
15433
- const children = group2.rels.map((r3) => ({ r: r3, box: boxByID.get(r3.from) })).filter((c) => !!c.box);
15433
+ const children = group2.rels.map((r5) => ({ r: r5, box: boxByID.get(r5.from) })).filter((c) => !!c.box);
15434
15434
  if (children.length < UMLCLASS_CONST.TREE_MERGE_THRESHOLD) continue;
15435
15435
  const tree = buildTree2(group2.kind, parent, children, vertical);
15436
15436
  if (tree) {
15437
15437
  trees.push(tree);
15438
- for (const r3 of group2.rels) handled.add(r3);
15438
+ for (const r5 of group2.rels) handled.add(r5);
15439
15439
  }
15440
15440
  }
15441
15441
  const liftLanes = /* @__PURE__ */ new Map();
@@ -15888,8 +15888,8 @@ function escapeXmlText(s) {
15888
15888
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
15889
15889
  }
15890
15890
  function renderEdge4(e) {
15891
- const r3 = e.rel;
15892
- const dashed = r3.kind === "realization" || r3.kind === "dependency";
15891
+ const r5 = e.rel;
15892
+ const dashed = r5.kind === "realization" || r5.kind === "dependency";
15893
15893
  const parts = [];
15894
15894
  parts.push(
15895
15895
  path({
@@ -15898,15 +15898,15 @@ function renderEdge4(e) {
15898
15898
  "data-dashed": dashed ? "true" : void 0
15899
15899
  })
15900
15900
  );
15901
- parts.push(renderTargetAdornment(r3.kind, e.targetEnd));
15902
- if (r3.kind === "composition" || r3.kind === "aggregation") {
15903
- parts.push(renderSourceDiamond(r3.kind, e.sourceEnd));
15904
- }
15905
- if (r3.sourceMult) parts.push(renderEndLabel(e.sourceEnd, r3.sourceMult, false));
15906
- if (r3.targetMult) parts.push(renderEndLabel(e.targetEnd, r3.targetMult, false));
15907
- if (r3.sourceRole) parts.push(renderEndLabel(e.sourceEnd, r3.sourceRole, true));
15908
- if (r3.targetRole) parts.push(renderEndLabel(e.targetEnd, r3.targetRole, true));
15909
- if (r3.label && e.labelAnchor) {
15901
+ parts.push(renderTargetAdornment(r5.kind, e.targetEnd));
15902
+ if (r5.kind === "composition" || r5.kind === "aggregation") {
15903
+ parts.push(renderSourceDiamond(r5.kind, e.sourceEnd));
15904
+ }
15905
+ if (r5.sourceMult) parts.push(renderEndLabel(e.sourceEnd, r5.sourceMult, false));
15906
+ if (r5.targetMult) parts.push(renderEndLabel(e.targetEnd, r5.targetMult, false));
15907
+ if (r5.sourceRole) parts.push(renderEndLabel(e.sourceEnd, r5.sourceRole, true));
15908
+ if (r5.targetRole) parts.push(renderEndLabel(e.targetEnd, r5.targetRole, true));
15909
+ if (r5.label && e.labelAnchor) {
15910
15910
  parts.push(
15911
15911
  text(
15912
15912
  {
@@ -15915,7 +15915,7 @@ function renderEdge4(e) {
15915
15915
  class: "sx-umlclass-edge-name sx-umlclass-edge-name-halo",
15916
15916
  "text-anchor": "middle"
15917
15917
  },
15918
- r3.label
15918
+ r5.label
15919
15919
  )
15920
15920
  );
15921
15921
  parts.push(
@@ -15926,19 +15926,19 @@ function renderEdge4(e) {
15926
15926
  class: "sx-umlclass-edge-name",
15927
15927
  "text-anchor": "middle"
15928
15928
  },
15929
- r3.label
15929
+ r5.label
15930
15930
  )
15931
15931
  );
15932
15932
  }
15933
15933
  return group(
15934
15934
  {
15935
15935
  class: "sx-umlclass-rel",
15936
- "data-from": r3.from,
15937
- "data-to": r3.to,
15938
- "data-kind": r3.kind,
15939
- "data-source-mult": r3.sourceMult,
15940
- "data-target-mult": r3.targetMult,
15941
- "data-name": r3.label
15936
+ "data-from": r5.from,
15937
+ "data-to": r5.to,
15938
+ "data-kind": r5.kind,
15939
+ "data-source-mult": r5.sourceMult,
15940
+ "data-target-mult": r5.targetMult,
15941
+ "data-name": r5.label
15942
15942
  },
15943
15943
  parts
15944
15944
  );
@@ -16093,8 +16093,8 @@ function summariseDiagram(ast, treeCount) {
16093
16093
  byKind[k] = (byKind[k] ?? 0) + 1;
16094
16094
  }
16095
16095
  const relsByKind = {};
16096
- for (const r3 of ast.relationships) {
16097
- relsByKind[r3.kind] = (relsByKind[r3.kind] ?? 0) + 1;
16096
+ for (const r5 of ast.relationships) {
16097
+ relsByKind[r5.kind] = (relsByKind[r5.kind] ?? 0) + 1;
16098
16098
  }
16099
16099
  const classifierStr = Object.entries(byKind).map(([k, n]) => `${n} ${k}`).join(", ");
16100
16100
  const relStr = Object.entries(relsByKind).map(([k, n]) => `${n} ${k}`).join(", ");
@@ -16326,9 +16326,9 @@ function validate(ast) {
16326
16326
  if (!e.gate) continue;
16327
16327
  const refs = [...e.gate.inputs];
16328
16328
  if (e.gate.condition && isId(e.gate.condition)) refs.push(e.gate.condition);
16329
- for (const r3 of refs) {
16330
- if (!byId.has(r3)) {
16331
- throw new FaultTreeParseError(`gate ${e.id} references undefined event '${r3}'`);
16329
+ for (const r5 of refs) {
16330
+ if (!byId.has(r5)) {
16331
+ throw new FaultTreeParseError(`gate ${e.id} references undefined event '${r5}'`);
16332
16332
  }
16333
16333
  }
16334
16334
  if (e.gate.kind === "voting") {
@@ -16400,9 +16400,9 @@ function parseProb(s, lineNo) {
16400
16400
  return n;
16401
16401
  }
16402
16402
  function splitRefs(s, lineNo) {
16403
- const refs = s.split(",").map((r3) => r3.trim()).filter(Boolean);
16404
- for (const r3 of refs) {
16405
- if (!isId(r3)) throw new FaultTreeParseError(`invalid event reference "${r3}"`, lineNo);
16403
+ const refs = s.split(",").map((r5) => r5.trim()).filter(Boolean);
16404
+ for (const r5 of refs) {
16405
+ if (!isId(r5)) throw new FaultTreeParseError(`invalid event reference "${r5}"`, lineNo);
16406
16406
  }
16407
16407
  if (refs.length === 0) throw new FaultTreeParseError(`empty input list`, lineNo);
16408
16408
  return refs;
@@ -17120,10 +17120,10 @@ function renderEvent(e, showProb) {
17120
17120
  parts.push(text({ x: e.cx, y: cy + 3, class: "sx-ft-id", "text-anchor": "middle" }, e.event.id));
17121
17121
  parts.push(...leafCaption(e, cy + FAULTTREE_CONST.BASIC_R, label, showProb));
17122
17122
  } else if (e.role === "undeveloped") {
17123
- const r3 = FAULTTREE_CONST.DIAMOND_W / 2;
17124
- parts.push(path({ d: `M ${e.cx} ${cy - r3} L ${e.cx + r3} ${cy} L ${e.cx} ${cy + r3} L ${e.cx - r3} ${cy} Z`, class: "sx-ft-undeveloped" }));
17123
+ const r5 = FAULTTREE_CONST.DIAMOND_W / 2;
17124
+ parts.push(path({ d: `M ${e.cx} ${cy - r5} L ${e.cx + r5} ${cy} L ${e.cx} ${cy + r5} L ${e.cx - r5} ${cy} Z`, class: "sx-ft-undeveloped" }));
17125
17125
  parts.push(text({ x: e.cx, y: cy + 3, class: "sx-ft-id", "text-anchor": "middle" }, e.event.id));
17126
- parts.push(...leafCaption(e, cy + r3, label, showProb));
17126
+ parts.push(...leafCaption(e, cy + r5, label, showProb));
17127
17127
  } else if (e.role === "house") {
17128
17128
  const w = FAULTTREE_CONST.HOUSE_W, h = FAULTTREE_CONST.HOUSE_H, roofH = h * 0.34;
17129
17129
  const top = cy - h / 2, bottom = cy + h / 2, L = e.cx - w / 2, R = e.cx + w / 2;
@@ -17270,6 +17270,619 @@ var faulttree = {
17270
17270
  }
17271
17271
  };
17272
17272
 
17273
+ // src/diagrams/bowtie/parser.ts
17274
+ var BowtieParseError = class extends Error {
17275
+ constructor(message, line2) {
17276
+ super(line2 ? `Line ${line2}: ${message}` : message);
17277
+ this.line = line2;
17278
+ this.name = "BowtieParseError";
17279
+ }
17280
+ line;
17281
+ };
17282
+ function parseBowtie(text2) {
17283
+ const ast = {
17284
+ type: "bowtie",
17285
+ layout: "symmetric",
17286
+ topEvent: "",
17287
+ threats: [],
17288
+ consequences: [],
17289
+ warnings: []
17290
+ };
17291
+ const rawLines = text2.split(/\r?\n/);
17292
+ let i = 0;
17293
+ let topEventCount = 0;
17294
+ let hazardCount = 0;
17295
+ let headerSeen = false;
17296
+ while (i < rawLines.length) {
17297
+ const t = stripComment5(rawLines[i] ?? "").trim();
17298
+ if (t === "") {
17299
+ i++;
17300
+ continue;
17301
+ }
17302
+ const h = /^bowtie\b(.*)$/i.exec(t);
17303
+ if (h) {
17304
+ const q = matchQuoted3(h[1].trim());
17305
+ if (q) ast.title = q.value;
17306
+ headerSeen = true;
17307
+ i++;
17308
+ break;
17309
+ }
17310
+ headerSeen = true;
17311
+ break;
17312
+ }
17313
+ if (!headerSeen) return ast;
17314
+ let curThreat = null;
17315
+ let curConsequence = null;
17316
+ let curBarrier = null;
17317
+ let curEscalation = null;
17318
+ let tCount = 0, cCount = 0;
17319
+ for (; i < rawLines.length; i++) {
17320
+ const t = stripComment5(rawLines[i] ?? "").trim();
17321
+ if (t === "") continue;
17322
+ const lineNo = i + 1;
17323
+ if (/^layout\s*:/i.test(t)) {
17324
+ const v = afterColon3(t).toLowerCase();
17325
+ if (v === "symmetric" || v === "compact") ast.layout = v;
17326
+ continue;
17327
+ }
17328
+ if (/^legend\s*:/i.test(t)) {
17329
+ const v = afterColon3(t).toLowerCase();
17330
+ if (v === "on" || v === "off" || v === "bottom" || v === "bottom-right" || v === "top") {
17331
+ ast.legend = v;
17332
+ }
17333
+ continue;
17334
+ }
17335
+ if (/^theme\s*:/i.test(t)) {
17336
+ continue;
17337
+ }
17338
+ const kw = /^(hazard|topevent|threat|consequence|prevent|mitigate|escalation|barrier)\b/i.exec(t);
17339
+ if (!kw) {
17340
+ ast.warnings.push(`Line ${lineNo}: unrecognised line: "${truncate4(t, 80)}"`);
17341
+ continue;
17342
+ }
17343
+ const keyword = kw[1].toLowerCase();
17344
+ const label = requireLabel(t.slice(kw[0].length).trim(), keyword, lineNo);
17345
+ switch (keyword) {
17346
+ case "hazard": {
17347
+ hazardCount++;
17348
+ if (hazardCount > 1) throw new BowtieParseError(`a bowtie has at most one hazard header \u2014 found a second: "${label}"`, lineNo);
17349
+ ast.hazard = label;
17350
+ break;
17351
+ }
17352
+ case "topevent": {
17353
+ topEventCount++;
17354
+ if (topEventCount > 1) throw new BowtieParseError(`a bowtie has exactly one top event \u2014 found a second: "${label}"`, lineNo);
17355
+ ast.topEvent = label;
17356
+ break;
17357
+ }
17358
+ case "threat": {
17359
+ curThreat = { id: `T${++tCount}`, label, barriers: [] };
17360
+ ast.threats.push(curThreat);
17361
+ curConsequence = null;
17362
+ curBarrier = null;
17363
+ curEscalation = null;
17364
+ break;
17365
+ }
17366
+ case "consequence": {
17367
+ curConsequence = { id: `C${++cCount}`, label, barriers: [] };
17368
+ ast.consequences.push(curConsequence);
17369
+ curThreat = null;
17370
+ curBarrier = null;
17371
+ curEscalation = null;
17372
+ break;
17373
+ }
17374
+ case "prevent": {
17375
+ if (!curThreat) {
17376
+ throw new BowtieParseError(`preventative barrier "${label}" is not under a threat \u2014 a \`prevent\` line must follow a \`threat\``, lineNo);
17377
+ }
17378
+ curBarrier = {
17379
+ id: `${curThreat.id}-b${curThreat.barriers.length}`,
17380
+ label,
17381
+ side: "prevent",
17382
+ escalations: []
17383
+ };
17384
+ curThreat.barriers.push(curBarrier);
17385
+ curEscalation = null;
17386
+ break;
17387
+ }
17388
+ case "mitigate": {
17389
+ if (!curConsequence) {
17390
+ throw new BowtieParseError(`mitigative barrier "${label}" is not under a consequence \u2014 a \`mitigate\` line must follow a \`consequence\``, lineNo);
17391
+ }
17392
+ curBarrier = {
17393
+ id: `${curConsequence.id}-b${curConsequence.barriers.length}`,
17394
+ label,
17395
+ side: "mitigate",
17396
+ escalations: []
17397
+ };
17398
+ curConsequence.barriers.push(curBarrier);
17399
+ curEscalation = null;
17400
+ break;
17401
+ }
17402
+ case "escalation": {
17403
+ if (!curBarrier) {
17404
+ throw new BowtieParseError(`escalation factor "${label}" is not attached to a barrier \u2014 escalation factors must degrade a specific named barrier (add it under a \`prevent\`/\`mitigate\` line)`, lineNo);
17405
+ }
17406
+ curEscalation = {
17407
+ id: `${curBarrier.id}-x${curBarrier.escalations.length}`,
17408
+ label,
17409
+ barriers: []
17410
+ };
17411
+ curBarrier.escalations.push(curEscalation);
17412
+ break;
17413
+ }
17414
+ case "barrier": {
17415
+ if (!curEscalation) {
17416
+ throw new BowtieParseError(`escalation-factor barrier "${label}" is not under an escalation factor \u2014 a \`barrier\` line must follow an \`escalation\``, lineNo);
17417
+ }
17418
+ const ef = {
17419
+ id: `${curEscalation.id}-b${curEscalation.barriers.length}`,
17420
+ label
17421
+ };
17422
+ curEscalation.barriers.push(ef);
17423
+ break;
17424
+ }
17425
+ }
17426
+ }
17427
+ validate2(ast);
17428
+ return ast;
17429
+ }
17430
+ function validate2(ast) {
17431
+ if (!ast.topEvent) {
17432
+ throw new BowtieParseError(`a bowtie has exactly one top event \u2014 declare it with a \`topevent "\u2026"\` line`);
17433
+ }
17434
+ if (ast.threats.length === 0) {
17435
+ throw new BowtieParseError(`a bowtie needs at least one threat \u2014 a diagram with no left wing is a fault tree (see faulttree), not a bowtie`);
17436
+ }
17437
+ if (ast.consequences.length === 0) {
17438
+ throw new BowtieParseError(`a bowtie needs at least one consequence \u2014 a diagram with no right wing is an event tree, not a bowtie`);
17439
+ }
17440
+ for (const th of ast.threats) {
17441
+ if (th.barriers.length === 0) {
17442
+ throw new BowtieParseError(
17443
+ `Threat "${th.label}" has no preventative barrier \u2014 every threat must reach the top event through at least one barrier (CCPS/EI barrier rule). Add a \`prevent\` line under it.`
17444
+ );
17445
+ }
17446
+ }
17447
+ for (const co of ast.consequences) {
17448
+ if (co.barriers.length === 0) {
17449
+ throw new BowtieParseError(
17450
+ `Consequence "${co.label}" has no mitigative barrier \u2014 every consequence must be limited by at least one barrier (CCPS/EI barrier rule). Add a \`mitigate\` line under it.`
17451
+ );
17452
+ }
17453
+ }
17454
+ }
17455
+ function requireLabel(s, keyword, lineNo) {
17456
+ const q = matchQuoted3(s);
17457
+ if (q) return q.value;
17458
+ const bare = s.trim();
17459
+ if (!bare) throw new BowtieParseError(`\`${keyword}\` needs a label`, lineNo);
17460
+ if (/\s/.test(bare)) {
17461
+ throw new BowtieParseError(`\`${keyword}\` label with spaces must be quoted: ${keyword} "${bare}"`, lineNo);
17462
+ }
17463
+ return bare;
17464
+ }
17465
+ function matchQuoted3(s) {
17466
+ if (!s) return void 0;
17467
+ const open = s[0];
17468
+ if (open !== '"' && open !== "\u300C" && open !== "\u201C" && open !== "\u300E") return void 0;
17469
+ const close = closingQuote3(open);
17470
+ const end = s.indexOf(close, 1);
17471
+ if (end < 0) return void 0;
17472
+ return { value: s.slice(1, end), length: end + 1 };
17473
+ }
17474
+ function closingQuote3(open) {
17475
+ return open === "\u300C" ? "\u300D" : open === "\u300E" ? "\u300F" : open === "\u201C" ? "\u201D" : '"';
17476
+ }
17477
+ function afterColon3(s) {
17478
+ const i = s.indexOf(":");
17479
+ return i < 0 ? "" : s.slice(i + 1).trim();
17480
+ }
17481
+ function stripComment5(line2) {
17482
+ let inQ = false, qc = "";
17483
+ for (let i = 0; i < line2.length; i++) {
17484
+ const ch = line2[i];
17485
+ if (inQ) {
17486
+ if (ch === qc) inQ = false;
17487
+ continue;
17488
+ }
17489
+ if (ch === '"' || ch === "\u300C" || ch === "\u201C" || ch === "\u300E") {
17490
+ inQ = true;
17491
+ qc = closingQuote3(ch);
17492
+ continue;
17493
+ }
17494
+ if (ch === "#") return line2.slice(0, i);
17495
+ if (ch === "/" && line2[i + 1] === "/") return line2.slice(0, i);
17496
+ }
17497
+ return line2;
17498
+ }
17499
+ function truncate4(s, n) {
17500
+ return s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
17501
+ }
17502
+
17503
+ // src/diagrams/bowtie/layout.ts
17504
+ var BOWTIE_CONST = {
17505
+ TOPEVENT_R: 52,
17506
+ NODE_W: 132,
17507
+ NODE_H: 44,
17508
+ BARRIER_W: 120,
17509
+ WING_X_STEP: 168,
17510
+ ROW_BAND_H: 96,
17511
+ ROW_GAP: 24,
17512
+ EF_DROP: 72,
17513
+ EF_GAP: 16,
17514
+ CENTER_GUTTER: 40,
17515
+ HAZARD_GAP: 40,
17516
+ HAZARD_W: 220,
17517
+ PAGE_PAD: 32,
17518
+ TITLE_H: 34,
17519
+ LEGEND_H: 30
17520
+ };
17521
+ function dropBottom(barrier) {
17522
+ const C2 = BOWTIE_CONST;
17523
+ if (barrier.escalations.length === 0) return C2.NODE_H / 2;
17524
+ let cursor = C2.EF_DROP;
17525
+ let lastBottom = C2.NODE_H / 2;
17526
+ for (const esc of barrier.escalations) {
17527
+ lastBottom = cursor + C2.NODE_H / 2;
17528
+ cursor += C2.NODE_H + C2.EF_GAP;
17529
+ for (const _ef of esc.barriers) {
17530
+ lastBottom = cursor + C2.NODE_H / 2;
17531
+ cursor += C2.NODE_H + C2.EF_GAP;
17532
+ }
17533
+ }
17534
+ return lastBottom;
17535
+ }
17536
+ function bandLayout(lines) {
17537
+ const C2 = BOWTIE_CONST;
17538
+ const below = lines.map((l) => Math.max(...l.barriers.map(dropBottom), C2.NODE_H / 2));
17539
+ const rel = [];
17540
+ for (let k = 0; k < lines.length; k++) {
17541
+ if (k === 0) {
17542
+ rel.push(0);
17543
+ continue;
17544
+ }
17545
+ const pitch = Math.max(C2.ROW_BAND_H, below[k - 1] + C2.ROW_GAP + C2.NODE_H / 2);
17546
+ rel.push(rel[k - 1] + pitch);
17547
+ }
17548
+ const last = lines.length - 1;
17549
+ const blockMid = lines.length ? rel[last] / 2 : 0;
17550
+ const aboveExtent = lines.length ? blockMid + C2.NODE_H / 2 : 0;
17551
+ const belowExtent = lines.length ? rel[last] - blockMid + below[last] : 0;
17552
+ return { rel, below, blockMid, aboveExtent, belowExtent };
17553
+ }
17554
+ function layoutBowtie(ast) {
17555
+ const C2 = BOWTIE_CONST;
17556
+ const boxes = [];
17557
+ const lines = [];
17558
+ const escalationLines = [];
17559
+ const threatLines = ast.threats.map((t) => ({ id: t.id, label: t.label, barriers: t.barriers }));
17560
+ const conseqLines = ast.consequences.map((c) => ({ id: c.id, label: c.label, barriers: c.barriers }));
17561
+ const left = bandLayout(threatLines);
17562
+ const right = bandLayout(conseqLines);
17563
+ const aboveCy = Math.max(left.aboveExtent, right.aboveExtent, C2.TOPEVENT_R);
17564
+ const maxLeftChain = Math.max(0, ...threatLines.map((l) => l.barriers.length));
17565
+ const innerOffset = C2.TOPEVENT_R + C2.CENTER_GUTTER + C2.BARRIER_W / 2;
17566
+ const cx = C2.PAGE_PAD + C2.NODE_W / 2 + maxLeftChain * C2.WING_X_STEP + innerOffset;
17567
+ const titleZone = ast.title ? C2.TITLE_H : 0;
17568
+ const hazardReserve = ast.hazard ? C2.NODE_H + C2.HAZARD_GAP : 0;
17569
+ const cy = C2.PAGE_PAD + titleZone + hazardReserve + aboveCy;
17570
+ const topEvent = { cx, cy, r: C2.TOPEVENT_R, label: ast.topEvent };
17571
+ let hazardTie;
17572
+ if (ast.hazard) {
17573
+ const hcy = C2.PAGE_PAD + titleZone + C2.NODE_H / 2;
17574
+ boxes.push({ id: "hazard", role: "hazard", label: ast.hazard, cx, cy: hcy, width: C2.HAZARD_W, height: C2.NODE_H });
17575
+ hazardTie = { x: cx, y1: hcy + C2.NODE_H / 2, y2: cy - C2.TOPEVENT_R };
17576
+ }
17577
+ const emitWing = (wing, band, side) => {
17578
+ const innerX = side === "prevent" ? cx - C2.TOPEVENT_R - C2.CENTER_GUTTER - C2.BARRIER_W / 2 : cx + C2.TOPEVENT_R + C2.CENTER_GUTTER + C2.BARRIER_W / 2;
17579
+ wing.forEach((line2, k) => {
17580
+ const by = cy + (band.rel[k] - band.blockMid);
17581
+ const n = line2.barriers.length;
17582
+ const barrierX = line2.barriers.map((_b, j) => {
17583
+ if (side === "prevent") {
17584
+ const stepsFromInner = n - 1 - j;
17585
+ return innerX - stepsFromInner * C2.WING_X_STEP;
17586
+ }
17587
+ return innerX + j * C2.WING_X_STEP;
17588
+ });
17589
+ const outerBarrierX = side === "prevent" ? Math.min(...barrierX) : Math.max(...barrierX);
17590
+ const headX = side === "prevent" ? outerBarrierX - C2.WING_X_STEP : outerBarrierX + C2.WING_X_STEP;
17591
+ boxes.push({
17592
+ id: line2.id,
17593
+ role: side === "prevent" ? "threat" : "consequence",
17594
+ label: line2.label,
17595
+ cx: headX,
17596
+ cy: by,
17597
+ width: C2.NODE_W,
17598
+ height: C2.NODE_H
17599
+ });
17600
+ line2.barriers.forEach((b, j) => {
17601
+ const bx = barrierX[j];
17602
+ boxes.push({
17603
+ id: b.id,
17604
+ role: "barrier",
17605
+ label: b.label,
17606
+ cx: bx,
17607
+ cy: by,
17608
+ width: C2.BARRIER_W,
17609
+ height: C2.NODE_H,
17610
+ side,
17611
+ lineId: line2.id,
17612
+ order: j
17613
+ });
17614
+ if (b.escalations.length) {
17615
+ let cursor = C2.EF_DROP;
17616
+ let connectFromY = by + C2.NODE_H / 2;
17617
+ for (const esc of b.escalations) {
17618
+ const escCy = by + cursor;
17619
+ escalationLines.push({ x: bx, y1: connectFromY, y2: escCy - C2.NODE_H / 2 });
17620
+ boxes.push({
17621
+ id: esc.id,
17622
+ role: "escalation",
17623
+ label: esc.label,
17624
+ cx: bx,
17625
+ cy: escCy,
17626
+ width: C2.NODE_W,
17627
+ height: C2.NODE_H,
17628
+ lineId: line2.id,
17629
+ barrierId: b.id
17630
+ });
17631
+ connectFromY = escCy + C2.NODE_H / 2;
17632
+ cursor += C2.NODE_H + C2.EF_GAP;
17633
+ for (const ef of esc.barriers) {
17634
+ const efCy = by + cursor;
17635
+ escalationLines.push({ x: bx, y1: connectFromY, y2: efCy - C2.NODE_H / 2 });
17636
+ boxes.push({
17637
+ id: ef.id,
17638
+ role: "ef-barrier",
17639
+ label: ef.label,
17640
+ cx: bx,
17641
+ cy: efCy,
17642
+ width: C2.BARRIER_W,
17643
+ height: C2.NODE_H,
17644
+ lineId: line2.id,
17645
+ escalationId: esc.id
17646
+ });
17647
+ connectFromY = efCy + C2.NODE_H / 2;
17648
+ cursor += C2.NODE_H + C2.EF_GAP;
17649
+ }
17650
+ }
17651
+ }
17652
+ });
17653
+ const dy = by - cy;
17654
+ const clampedDy = Math.max(-48, Math.min(C2.TOPEVENT_R - 4, dy));
17655
+ const knotDx = Math.sqrt(Math.max(0, C2.TOPEVENT_R * C2.TOPEVENT_R - clampedDy * clampedDy));
17656
+ const pts = [];
17657
+ if (side === "prevent") {
17658
+ pts.push([headX + C2.NODE_W / 2, by]);
17659
+ const ordered = [...line2.barriers].map((_b, j) => barrierX[j]).sort((a, b) => a - b);
17660
+ for (const bx of ordered) {
17661
+ pts.push([bx - C2.BARRIER_W / 2, by]);
17662
+ pts.push([bx + C2.BARRIER_W / 2, by]);
17663
+ }
17664
+ pts.push([cx - knotDx, cy + clampedDy]);
17665
+ } else {
17666
+ pts.push([cx + knotDx, cy + clampedDy]);
17667
+ const ordered = [...line2.barriers].map((_b, j) => barrierX[j]).sort((a, b) => a - b);
17668
+ for (const bx of ordered) {
17669
+ pts.push([bx - C2.BARRIER_W / 2, by]);
17670
+ pts.push([bx + C2.BARRIER_W / 2, by]);
17671
+ }
17672
+ pts.push([headX - C2.NODE_W / 2, by]);
17673
+ }
17674
+ const path2 = pts.map((p, idx) => `${idx === 0 ? "M" : "L"} ${r3(p[0])} ${r3(p[1])}`).join(" ");
17675
+ const ax = side === "prevent" ? cx - knotDx : cx + knotDx;
17676
+ lines.push({ lineId: line2.id, side, path: path2, arrow: { x: ax, y: cy + clampedDy, angle: 0 } });
17677
+ });
17678
+ };
17679
+ emitWing(threatLines, left, "prevent");
17680
+ emitWing(conseqLines, right, "mitigate");
17681
+ let maxX = 0, maxY = 0;
17682
+ const bump = (x, y) => {
17683
+ maxX = Math.max(maxX, x);
17684
+ maxY = Math.max(maxY, y);
17685
+ };
17686
+ for (const b of boxes) bump(b.cx + b.width / 2, b.cy + b.height / 2);
17687
+ bump(cx + C2.TOPEVENT_R, cy + C2.TOPEVENT_R);
17688
+ if (ast.title) bump(C2.PAGE_PAD + ast.title.length * 9, 0);
17689
+ const legendBand = ast.legend === "off" ? 0 : C2.LEGEND_H;
17690
+ return {
17691
+ ast,
17692
+ topEvent,
17693
+ boxes,
17694
+ lines,
17695
+ escalationLines,
17696
+ ...hazardTie ? { hazardTie } : {},
17697
+ width: Math.ceil(maxX + C2.PAGE_PAD),
17698
+ height: Math.ceil(maxY + C2.PAGE_PAD + legendBand)
17699
+ };
17700
+ }
17701
+ function r3(n) {
17702
+ return Math.round(n * 10) / 10;
17703
+ }
17704
+
17705
+ // src/diagrams/bowtie/renderer.ts
17706
+ function renderBowtie(text2, config) {
17707
+ const layout = layoutBowtie(parseBowtie(text2));
17708
+ return renderBowtieLayout(layout, config);
17709
+ }
17710
+ function renderBowtieLayout(layout, config) {
17711
+ const themeName = config?.theme ?? "default";
17712
+ const theme = resolveBowtieTheme(themeName);
17713
+ const fontFamily = config?.fontFamily ?? DEFAULT_FONT_FAMILY;
17714
+ const pad = config?.padding ?? 0;
17715
+ const { ast, topEvent } = layout;
17716
+ const mono = themeName === "monochrome";
17717
+ const width = layout.width + pad * 2;
17718
+ const height = layout.height + pad * 2;
17719
+ const a11y = ast.title ?? "Bowtie risk diagram";
17720
+ const styleBlock = el(
17721
+ "style",
17722
+ {},
17723
+ `
17724
+ .sx-bowtie-bg { fill: ${theme.bg}; }
17725
+ .sx-bowtie-line { fill: none; stroke: ${theme.lineStroke}; stroke-width: ${STROKE_WIDTH.normal}; }
17726
+ .sx-bowtie-arrow { fill: ${theme.lineStroke}; stroke: none; }
17727
+ .sx-bowtie-escalation-line { fill: none; stroke: ${theme.escalationLineStroke}; stroke-width: ${STROKE_WIDTH.thin};${mono ? " stroke-dasharray: 4 3;" : ""} }
17728
+ .sx-bowtie-hazard { fill: ${theme.hazardFill}; stroke: ${theme.hazardStroke}; stroke-width: ${STROKE_WIDTH.normal}; }
17729
+ .sx-bowtie-topevent { fill: ${theme.topEventFill}; stroke: ${theme.topEventStroke}; stroke-width: ${STROKE_WIDTH.thick}; }
17730
+ .sx-bowtie-topevent-ring { fill: none; stroke: ${theme.topEventStroke}; stroke-width: ${STROKE_WIDTH.thin}; }
17731
+ .sx-bowtie-threat { fill: ${theme.threatFill}; stroke: ${theme.threatStroke}; stroke-width: ${STROKE_WIDTH.normal}; }
17732
+ .sx-bowtie-barrier { fill: ${theme.barrierFill}; stroke: ${theme.barrierStroke}; stroke-width: ${STROKE_WIDTH.normal}; }
17733
+ .sx-bowtie-consequence { fill: ${theme.consequenceFill}; stroke: ${theme.consequenceStroke}; stroke-width: ${STROKE_WIDTH.normal}; }
17734
+ .sx-bowtie-escalation { fill: ${theme.escalationFill}; stroke: ${theme.escalationStroke}; stroke-width: ${STROKE_WIDTH.normal};${mono ? " stroke-dasharray: 5 3;" : ""} }
17735
+ .sx-bowtie-ef-barrier { fill: ${theme.efBarrierFill}; stroke: ${theme.barrierStroke}; stroke-width: ${STROKE_WIDTH.normal}; }
17736
+ .sx-bowtie-label { fill: ${theme.labelText}; stroke: none; font-size: ${FONT_SIZE.label}px; }
17737
+ .sx-bowtie-elabel { fill: ${theme.labelText}; stroke: none; font-size: ${FONT_SIZE.small}px; }
17738
+ .sx-bowtie-topevent-label { fill: ${theme.labelText}; stroke: none; font-size: 11px; font-weight: 700; }
17739
+ .sx-bowtie-title { fill: ${theme.labelText}; stroke: none; font-size: ${FONT_SIZE.title}px; font-weight: 700; }
17740
+ .sx-bowtie-legend-label { fill: ${theme.labelText}; stroke: none; font-size: ${FONT_SIZE.small}px; }
17741
+ `.trim()
17742
+ );
17743
+ const children = [
17744
+ title(a11y),
17745
+ desc(summarise2(layout)),
17746
+ styleBlock,
17747
+ rect({ x: 0, y: 0, width, height, class: "sx-bowtie-bg" })
17748
+ ];
17749
+ const inner = [];
17750
+ if (ast.title) {
17751
+ inner.push(text({ x: BOWTIE_CONST.PAGE_PAD, y: BOWTIE_CONST.PAGE_PAD + 6, class: "sx-bowtie-title", "font-family": fontFamily }, ast.title));
17752
+ }
17753
+ if (layout.hazardTie) {
17754
+ inner.push(line({ x1: layout.hazardTie.x, y1: layout.hazardTie.y1, x2: layout.hazardTie.x, y2: layout.hazardTie.y2, class: "sx-bowtie-line" }));
17755
+ }
17756
+ for (const ln of layout.lines) {
17757
+ inner.push(
17758
+ group({ class: "sx-bowtie-line-g", "data-line": ln.lineId, "data-side": ln.side }, [
17759
+ path({ d: ln.path, class: "sx-bowtie-line" }),
17760
+ rightArrow(ln.arrow.x, ln.arrow.y)
17761
+ ])
17762
+ );
17763
+ }
17764
+ for (const e of layout.escalationLines) {
17765
+ inner.push(line({ x1: e.x, y1: e.y1, x2: e.x, y2: e.y2, class: "sx-bowtie-escalation-line" }));
17766
+ }
17767
+ inner.push(
17768
+ group({ class: "sx-bowtie-topevent-g", "data-role": "topevent" }, [
17769
+ circle({ cx: topEvent.cx, cy: topEvent.cy, r: topEvent.r, class: "sx-bowtie-topevent" }),
17770
+ ...mono ? [circle({ cx: topEvent.cx, cy: topEvent.cy, r: topEvent.r - 4, class: "sx-bowtie-topevent-ring" })] : [],
17771
+ multilineText(
17772
+ { x: topEvent.cx, y: topEvent.cy, class: "sx-bowtie-topevent-label", "text-anchor": "middle", "dominant-baseline": "middle" },
17773
+ wrap3(topEvent.label, 11, 4).join("<br/>"),
17774
+ 12
17775
+ )
17776
+ ])
17777
+ );
17778
+ for (const b of layout.boxes) {
17779
+ inner.push(renderBox4(b));
17780
+ }
17781
+ if (ast.legend !== "off") {
17782
+ inner.push(renderLegend2(layout, fontFamily));
17783
+ }
17784
+ children.push(group({ transform: pad ? `translate(${pad}, ${pad})` : void 0, "font-family": fontFamily }, inner));
17785
+ return svgRoot(
17786
+ { width, height, viewBox: `0 0 ${width} ${height}`, role: "img", "aria-label": a11y, "data-diagram-type": "bowtie" },
17787
+ children
17788
+ );
17789
+ }
17790
+ function renderBox4(b) {
17791
+ const cls = b.role === "hazard" ? "sx-bowtie-hazard" : b.role === "threat" ? "sx-bowtie-threat" : b.role === "consequence" ? "sx-bowtie-consequence" : b.role === "escalation" ? "sx-bowtie-escalation" : b.role === "ef-barrier" ? "sx-bowtie-ef-barrier" : "sx-bowtie-barrier";
17792
+ const labelCls = b.role === "escalation" || b.role === "ef-barrier" ? "sx-bowtie-elabel" : "sx-bowtie-label";
17793
+ const perLine = b.role === "escalation" ? 18 : b.role === "hazard" ? 30 : 17;
17794
+ const lh = b.role === "escalation" || b.role === "ef-barrier" ? 12 : 14;
17795
+ const attrs = { class: `${cls}-g`, "data-role": b.role, "data-id": b.id };
17796
+ if (b.side) attrs["data-side"] = b.side;
17797
+ if (b.lineId) attrs["data-line"] = b.lineId;
17798
+ if (b.order !== void 0) attrs["data-order"] = String(b.order);
17799
+ if (b.barrierId) attrs["data-barrier"] = b.barrierId;
17800
+ if (b.escalationId) attrs["data-escalation"] = b.escalationId;
17801
+ return group(attrs, [
17802
+ rect({ x: b.cx - b.width / 2, y: b.cy - b.height / 2, width: b.width, height: b.height, rx: 5, class: cls }),
17803
+ multilineText(
17804
+ { x: b.cx, y: b.cy, class: labelCls, "text-anchor": "middle", "dominant-baseline": "middle" },
17805
+ wrap3(b.label, perLine, 3).join("<br/>"),
17806
+ lh
17807
+ )
17808
+ ]);
17809
+ }
17810
+ function rightArrow(tx, ty) {
17811
+ const s = 9, h = 5;
17812
+ return path({ d: `M ${r4(tx)} ${r4(ty)} L ${r4(tx - s)} ${r4(ty - h)} L ${r4(tx - s)} ${r4(ty + h)} Z`, class: "sx-bowtie-arrow" });
17813
+ }
17814
+ function renderLegend2(layout, fontFamily) {
17815
+ const hasEscalation = layout.boxes.some((b) => b.role === "escalation");
17816
+ const entries = [
17817
+ { cls: "sx-bowtie-threat", text: "Threat" },
17818
+ { cls: "sx-bowtie-barrier", text: "Barrier (prevent / mitigate)" },
17819
+ { cls: "sx-bowtie-topevent", text: "Top event" },
17820
+ { cls: "sx-bowtie-consequence", text: "Consequence" }
17821
+ ];
17822
+ if (hasEscalation) entries.push({ cls: "sx-bowtie-escalation", text: "Escalation factor" });
17823
+ const sw = 14, gap = 6;
17824
+ let x = BOWTIE_CONST.PAGE_PAD;
17825
+ const y = layout.height - 12;
17826
+ const parts = [];
17827
+ for (const e of entries) {
17828
+ parts.push(rect({ x, y: y - sw + 2, width: sw, height: sw, rx: 3, class: e.cls }));
17829
+ const tx = x + sw + gap;
17830
+ parts.push(text({ x: tx, y: y - 1, class: "sx-bowtie-legend-label", "font-family": fontFamily }, e.text));
17831
+ x = tx + e.text.length * 6.4 + 22;
17832
+ }
17833
+ return group({ class: "sx-bowtie-legend", "data-role": "legend" }, parts);
17834
+ }
17835
+ function summarise2(layout) {
17836
+ const { ast } = layout;
17837
+ const barrierCount = layout.boxes.filter((b) => b.role === "barrier").length;
17838
+ const escCount = layout.boxes.filter((b) => b.role === "escalation").length;
17839
+ const parts = [];
17840
+ parts.push(
17841
+ `Bowtie:${ast.hazard ? ` hazard "${ast.hazard}",` : ""} top event "${ast.topEvent}"; ${ast.threats.length} threat${plural(ast.threats.length)}, ${ast.consequences.length} consequence${plural(ast.consequences.length)}, ${barrierCount} barrier${plural(barrierCount)}${escCount ? `, ${escCount} escalation factor${plural(escCount)}` : ""}.`
17842
+ );
17843
+ for (const w of ast.warnings) parts.push(w);
17844
+ return parts.join(" ");
17845
+ }
17846
+ function plural(n) {
17847
+ return n === 1 ? "" : "s";
17848
+ }
17849
+ function wrap3(s, perLine, maxLines) {
17850
+ const words = s.split(/\s+/).filter(Boolean);
17851
+ const lines = [];
17852
+ let cur = "";
17853
+ for (const w of words) {
17854
+ if (cur && cur.length + 1 + w.length > perLine) {
17855
+ lines.push(cur);
17856
+ cur = w;
17857
+ if (lines.length === maxLines) break;
17858
+ } else {
17859
+ cur = cur ? `${cur} ${w}` : w;
17860
+ }
17861
+ }
17862
+ if (cur && lines.length < maxLines) lines.push(cur);
17863
+ else if (cur && lines.length === maxLines) lines[maxLines - 1] = clip2(`${lines[maxLines - 1]} ${cur}`, perLine);
17864
+ if (lines.length === 0) lines.push(s);
17865
+ return lines;
17866
+ }
17867
+ function clip2(s, n) {
17868
+ return s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
17869
+ }
17870
+ function r4(n) {
17871
+ return Math.round(n * 10) / 10;
17872
+ }
17873
+
17874
+ // src/diagrams/bowtie/index.ts
17875
+ var bowtie2 = {
17876
+ type: "bowtie",
17877
+ detect(text2) {
17878
+ return /^\s*bowtie\b/i.test(text2);
17879
+ },
17880
+ parse: parseBowtie,
17881
+ render(text2, config) {
17882
+ return renderBowtie(text2, config);
17883
+ }
17884
+ };
17885
+
17273
17886
  // src/core/diagnostics.ts
17274
17887
  var ENGINE_BUG_NAMES = /* @__PURE__ */ new Set([
17275
17888
  "ReferenceError",
@@ -17741,7 +18354,7 @@ function computeMaxLW(subtreeRoots, maxLabelWidth) {
17741
18354
  if (maxLW[n.depth] === void 0 || m.width > maxLW[n.depth]) maxLW[n.depth] = m.width;
17742
18355
  for (const c of n.children) walk(c);
17743
18356
  };
17744
- for (const r3 of subtreeRoots) walk(r3);
18357
+ for (const r5 of subtreeRoots) walk(r5);
17745
18358
  return maxLW;
17746
18359
  }
17747
18360
  function buildColumns(maxLW, firstColStartX, rootDepth) {
@@ -18105,9 +18718,9 @@ function renderNode2(n, color, theme, fontFamily) {
18105
18718
  for (let i = 0; i < lineCount; i++) {
18106
18719
  const line2 = n.lines[i];
18107
18720
  const cy = topY + (i + 0.5) * lh;
18108
- const r3 = renderLine2(line2, textLeft, cy, fs, fontFamily, weight, theme);
18109
- decorations.push(...r3.decorations);
18110
- children.push(r3.textElement);
18721
+ const r5 = renderLine2(line2, textLeft, cy, fs, fontFamily, weight, theme);
18722
+ decorations.push(...r5.decorations);
18723
+ children.push(r5.textElement);
18111
18724
  }
18112
18725
  const ux1 = n.x - n.labelWidth / 2;
18113
18726
  const ux2 = n.x + n.labelWidth / 2;
@@ -18627,11 +19240,11 @@ function parseMatrix(text2) {
18627
19240
  const gm = v.match(/^(\d+)\s*x\s*(\d+)$/);
18628
19241
  if (gm) {
18629
19242
  const c = Number(gm[1]);
18630
- const r3 = Number(gm[2]);
19243
+ const r5 = Number(gm[2]);
18631
19244
  st.ast.cols = c;
18632
- st.ast.rows = r3;
18633
- if (c === 2 && r3 === 2) st.ast.grid = "2x2";
18634
- else if (c === 3 && r3 === 3) st.ast.grid = "3x3";
19245
+ st.ast.rows = r5;
19246
+ if (c === 2 && r5 === 2) st.ast.grid = "2x2";
19247
+ else if (c === 3 && r5 === 3) st.ast.grid = "3x3";
18635
19248
  else st.ast.grid = "NxM";
18636
19249
  }
18637
19250
  continue;
@@ -18755,8 +19368,8 @@ function computeRadius(p, maxSize, plot, scale) {
18755
19368
  }
18756
19369
  const maxArea = Math.PI * maxRadius * maxRadius;
18757
19370
  const area = ratio * maxArea;
18758
- const r3 = Math.sqrt(area / Math.PI);
18759
- return Math.max(minRadius, r3);
19371
+ const r5 = Math.sqrt(area / Math.PI);
19372
+ return Math.max(minRadius, r5);
18760
19373
  }
18761
19374
  function resolveLabelCollisions(points, plot, mode) {
18762
19375
  if (mode === "off") {
@@ -18850,20 +19463,20 @@ function layoutMatrix(ast) {
18850
19463
  }
18851
19464
  for (const p of ast.points) {
18852
19465
  const { px, py } = placePoint(p, plot);
18853
- const r3 = computeRadius(p, maxSize, plot, ast.config.bubbleScale);
19466
+ const r5 = computeRadius(p, maxSize, plot, ast.config.bubbleScale);
18854
19467
  const width = estimateWidth(p.label);
18855
19468
  const label = {
18856
19469
  text: p.label,
18857
19470
  ax: px,
18858
19471
  ay: py,
18859
- lx: px + r3 + 4 + width / 2,
18860
- ly: py - r3 - 4,
19472
+ lx: px + r5 + 4 + width / 2,
19473
+ ly: py - r5 - 4,
18861
19474
  width,
18862
19475
  height: LABEL_H,
18863
19476
  external: false,
18864
19477
  textAnchor: "middle"
18865
19478
  };
18866
- points.push({ point: p, px, py, r: r3, label });
19479
+ points.push({ point: p, px, py, r: r5, label });
18867
19480
  if (p.category) categoriesSet.add(p.category);
18868
19481
  }
18869
19482
  resolveLabelCollisions(points, plot, ast.config.labelCollision);
@@ -18970,7 +19583,7 @@ function renderQuadrantBackground(ast, lay) {
18970
19583
  return group(
18971
19584
  { id: "sx-matrix-quad-bg" },
18972
19585
  rects.map(
18973
- (r3) => rect({ x: r3.x, y: r3.y, width: r3.w, height: r3.h, fill: r3.fill, "fill-opacity": 0.55 })
19586
+ (r5) => rect({ x: r5.x, y: r5.y, width: r5.w, height: r5.h, fill: r5.fill, "fill-opacity": 0.55 })
18974
19587
  )
18975
19588
  );
18976
19589
  }
@@ -19622,9 +20235,9 @@ function renderOnePoint(pl, categories) {
19622
20235
  class: "sx-matrix-bubble"
19623
20236
  });
19624
20237
  } else if (shape === "diamond") {
19625
- const r3 = pl.r;
20238
+ const r5 = pl.r;
19626
20239
  shapeEl = polygon({
19627
- points: `${pl.px},${pl.py - r3} ${pl.px + r3},${pl.py} ${pl.px},${pl.py + r3} ${pl.px - r3},${pl.py}`,
20240
+ points: `${pl.px},${pl.py - r5} ${pl.px + r5},${pl.py} ${pl.px},${pl.py + r5} ${pl.px - r5},${pl.py}`,
19628
20241
  fill: color,
19629
20242
  "fill-opacity": fillOpacity,
19630
20243
  stroke,
@@ -19632,9 +20245,9 @@ function renderOnePoint(pl, categories) {
19632
20245
  class: "sx-matrix-bubble"
19633
20246
  });
19634
20247
  } else {
19635
- const r3 = pl.r;
20248
+ const r5 = pl.r;
19636
20249
  shapeEl = polygon({
19637
- points: `${pl.px},${pl.py - r3} ${pl.px + r3},${pl.py + r3 * 0.8} ${pl.px - r3},${pl.py + r3 * 0.8}`,
20250
+ points: `${pl.px},${pl.py - r5} ${pl.px + r5},${pl.py + r5 * 0.8} ${pl.px - r5},${pl.py + r5 * 0.8}`,
19638
20251
  fill: color,
19639
20252
  "fill-opacity": fillOpacity,
19640
20253
  stroke,
@@ -19673,7 +20286,7 @@ function renderOnePoint(pl, categories) {
19673
20286
  [title(titleStr), shapeEl, leader, label, badge].filter((s) => s.length > 0)
19674
20287
  );
19675
20288
  }
19676
- function renderLegend2(ast, lay) {
20289
+ function renderLegend3(ast, lay) {
19677
20290
  if (ast.config.legendPosition === "none") return "";
19678
20291
  if (ast.mode === "heatmap") {
19679
20292
  const x = lay.plot.x0 + lay.plot.w - 220;
@@ -19733,7 +20346,7 @@ function renderMatrixAST(ast) {
19733
20346
  renderCorrelation(ast, lay),
19734
20347
  renderAxes(ast, lay),
19735
20348
  renderPoints(ast, lay),
19736
- renderLegend2(ast, lay),
20349
+ renderLegend3(ast, lay),
19737
20350
  renderCorrelationLegend(ast, lay)
19738
20351
  ].filter((s) => s.length > 0);
19739
20352
  return svgRoot(
@@ -19783,7 +20396,7 @@ var ErdParseError = class extends Error {
19783
20396
  }
19784
20397
  lineNumber;
19785
20398
  };
19786
- function stripComment5(s) {
20399
+ function stripComment6(s) {
19787
20400
  let out = "";
19788
20401
  let inQuote = false;
19789
20402
  for (let i = 0; i < s.length; i++) {
@@ -19837,7 +20450,7 @@ function parseCardToken(raw, side) {
19837
20450
  }
19838
20451
  function lex(text2) {
19839
20452
  return text2.split(/\r?\n/).map((raw, i) => ({
19840
- text: stripComment5(raw).trim(),
20453
+ text: stripComment6(raw).trim(),
19841
20454
  lineNumber: i + 1
19842
20455
  })).filter((l) => l.text.length > 0);
19843
20456
  }
@@ -20238,12 +20851,12 @@ function buildColumnAssignment(ast) {
20238
20851
  const ids = ast.entities.map((e) => e.id);
20239
20852
  const idToIdx = new Map(ids.map((id, i) => [id, i]));
20240
20853
  const pairs = [];
20241
- for (const r3 of ast.refs) {
20242
- const f = parseRefSide(r3.from);
20243
- const t = parseRefSide(r3.to);
20854
+ for (const r5 of ast.refs) {
20855
+ const f = parseRefSide(r5.from);
20856
+ const t = parseRefSide(r5.to);
20244
20857
  if (idToIdx.has(f.table) && idToIdx.has(t.table)) {
20245
- const oneIsTo = isOne(r3.toCard) && !isOne(r3.fromCard);
20246
- const oneIsFrom = isOne(r3.fromCard) && !isOne(r3.toCard);
20858
+ const oneIsTo = isOne(r5.toCard) && !isOne(r5.fromCard);
20859
+ const oneIsFrom = isOne(r5.fromCard) && !isOne(r5.toCard);
20247
20860
  if (oneIsTo) pairs.push({ from: t.table, to: f.table });
20248
20861
  else if (oneIsFrom) pairs.push({ from: f.table, to: t.table });
20249
20862
  else pairs.push({ from: f.table, to: t.table });
@@ -20278,9 +20891,9 @@ function isOne(c) {
20278
20891
  function reorderByBarycenter(layerToEnts, layers, refs) {
20279
20892
  if (layers.length < 2) return;
20280
20893
  const neighbors = /* @__PURE__ */ new Map();
20281
- for (const r3 of refs) {
20282
- const a = parseRefSide(r3.from).table;
20283
- const b = parseRefSide(r3.to).table;
20894
+ for (const r5 of refs) {
20895
+ const a = parseRefSide(r5.from).table;
20896
+ const b = parseRefSide(r5.to).table;
20284
20897
  if (!neighbors.has(a)) neighbors.set(a, /* @__PURE__ */ new Set());
20285
20898
  if (!neighbors.has(b)) neighbors.set(b, /* @__PURE__ */ new Set());
20286
20899
  neighbors.get(a).add(b);
@@ -20410,9 +21023,9 @@ function layoutErd(ast) {
20410
21023
  const layers = Array.from(layerToEnts.keys()).sort((a, b) => a - b);
20411
21024
  reorderByBarycenter(layerToEnts, layers, ast.refs);
20412
21025
  const neighbors = /* @__PURE__ */ new Map();
20413
- for (const r3 of ast.refs) {
20414
- const a = parseRefSide(r3.from).table;
20415
- const b = parseRefSide(r3.to).table;
21026
+ for (const r5 of ast.refs) {
21027
+ const a = parseRefSide(r5.from).table;
21028
+ const b = parseRefSide(r5.to).table;
20416
21029
  if (!neighbors.has(a)) neighbors.set(a, /* @__PURE__ */ new Set());
20417
21030
  if (!neighbors.has(b)) neighbors.set(b, /* @__PURE__ */ new Set());
20418
21031
  neighbors.get(a).add(b);
@@ -20490,17 +21103,17 @@ function layoutErd(ast) {
20490
21103
  const placedById = new Map(placed.map((p) => [p.entity.id, p]));
20491
21104
  const edges = [];
20492
21105
  const bendBucketUses = /* @__PURE__ */ new Map();
20493
- for (const r3 of ast.refs) {
20494
- const fromTable = parseRefSide(r3.from).table;
20495
- const toTable = parseRefSide(r3.to).table;
21106
+ for (const r5 of ast.refs) {
21107
+ const fromTable = parseRefSide(r5.from).table;
21108
+ const toTable = parseRefSide(r5.to).table;
20496
21109
  const a = placedById.get(fromTable);
20497
21110
  const b = placedById.get(toTable);
20498
21111
  if (!a || !b) continue;
20499
- const fromCol = parseRefSide(r3.from).column;
20500
- const toCol = parseRefSide(r3.to).column;
21112
+ const fromCol = parseRefSide(r5.from).column;
21113
+ const toCol = parseRefSide(r5.to).column;
20501
21114
  const route = routeOrthogonal(a, b, fromCol, toCol, bendBucketUses);
20502
21115
  edges.push({
20503
- ref: r3,
21116
+ ref: r5,
20504
21117
  path: route.path,
20505
21118
  fromAnchor: route.fromAnchor,
20506
21119
  toAnchor: route.toAnchor,
@@ -20517,7 +21130,7 @@ function layoutErd(ast) {
20517
21130
  }
20518
21131
  function rowYByColumn(e, col) {
20519
21132
  if (col) {
20520
- const idx = e.rows.findIndex((r3) => r3.attribute.name.toLowerCase() === col.toLowerCase());
21133
+ const idx = e.rows.findIndex((r5) => r5.attribute.name.toLowerCase() === col.toLowerCase());
20521
21134
  if (idx >= 0) return e.y + e.rows[idx].yCenter;
20522
21135
  }
20523
21136
  return e.y + e.height / 2;
@@ -20964,7 +21577,7 @@ var BreadboardParseError = class extends Error {
20964
21577
  }
20965
21578
  lineNumber;
20966
21579
  };
20967
- function stripComment6(s) {
21580
+ function stripComment7(s) {
20968
21581
  let out = "";
20969
21582
  let inQuote = false;
20970
21583
  for (let i = 0; i < s.length; i++) {
@@ -20985,7 +21598,7 @@ function unquote6(v) {
20985
21598
  }
20986
21599
  function lex2(text2) {
20987
21600
  return text2.split(/\r?\n/).map((raw, i) => ({
20988
- text: stripComment6(raw).trimEnd().replace(/^\s+/, ""),
21601
+ text: stripComment7(raw).trimEnd().replace(/^\s+/, ""),
20989
21602
  lineNumber: i + 1
20990
21603
  })).filter((l) => l.text.length > 0);
20991
21604
  }
@@ -21297,8 +21910,8 @@ var PITCH = 14;
21297
21910
  function rectShape(x, y, w, h, attrs) {
21298
21911
  return el("rect", { x, y, width: w, height: h, ...attrs });
21299
21912
  }
21300
- function circShape(cx, cy, r3, attrs) {
21301
- return el("circle", { cx, cy, r: r3, ...attrs });
21913
+ function circShape(cx, cy, r5, attrs) {
21914
+ return el("circle", { cx, cy, r: r5, ...attrs });
21302
21915
  }
21303
21916
  function lineShape(x1, y1, x2, y2, attrs) {
21304
21917
  return el("line", { x1, y1, x2, y2, ...attrs });
@@ -22019,13 +22632,13 @@ function renderSubstrate(sub) {
22019
22632
  { y: sub.y + BB_CONST.BOARD_PAD_Y, type: "top" },
22020
22633
  { y: sub.y + sub.height - BB_CONST.BOARD_PAD_Y - BB_CONST.RAIL_HEIGHT, type: "bottom" }
22021
22634
  ];
22022
- for (const r3 of rails) {
22635
+ for (const r5 of rails) {
22023
22636
  elements.push(path({
22024
- d: `M ${sub.x + BB_CONST.BOARD_PAD_X} ${r3.y + 4} L ${sub.x + sub.width - BB_CONST.BOARD_PAD_X} ${r3.y + 4}`,
22637
+ d: `M ${sub.x + BB_CONST.BOARD_PAD_X} ${r5.y + 4} L ${sub.x + sub.width - BB_CONST.BOARD_PAD_X} ${r5.y + 4}`,
22025
22638
  class: "lt-bb-rail-stripe-pos"
22026
22639
  }));
22027
22640
  elements.push(path({
22028
- d: `M ${sub.x + BB_CONST.BOARD_PAD_X} ${r3.y + BB_CONST.RAIL_HEIGHT - 4} L ${sub.x + sub.width - BB_CONST.BOARD_PAD_X} ${r3.y + BB_CONST.RAIL_HEIGHT - 4}`,
22641
+ d: `M ${sub.x + BB_CONST.BOARD_PAD_X} ${r5.y + BB_CONST.RAIL_HEIGHT - 4} L ${sub.x + sub.width - BB_CONST.BOARD_PAD_X} ${r5.y + BB_CONST.RAIL_HEIGHT - 4}`,
22029
22642
  class: "lt-bb-rail-stripe-neg"
22030
22643
  }));
22031
22644
  if (sub.railsBreak) {
@@ -22033,7 +22646,7 @@ function renderSubstrate(sub) {
22033
22646
  const breakX2 = breakX1 + PITCH2;
22034
22647
  elements.push(rect({
22035
22648
  x: breakX1,
22036
- y: r3.y,
22649
+ y: r5.y,
22037
22650
  width: breakX2 - breakX1,
22038
22651
  height: BB_CONST.RAIL_HEIGHT,
22039
22652
  fill: "#e7d8b6"
@@ -22041,8 +22654,8 @@ function renderSubstrate(sub) {
22041
22654
  }
22042
22655
  for (let c = 1; c <= sub.cols; c++) {
22043
22656
  const cx = sub.x + BB_CONST.BOARD_PAD_X + BB_CONST.ROW_LABEL_W + PITCH2 / 2 + (c - 1) * PITCH2;
22044
- elements.push(circle({ cx, cy: r3.y + 4, r: 1.4, class: "lt-bb-hole-rail" }));
22045
- elements.push(circle({ cx, cy: r3.y + BB_CONST.RAIL_HEIGHT - 4, r: 1.4, class: "lt-bb-hole-rail" }));
22657
+ elements.push(circle({ cx, cy: r5.y + 4, r: 1.4, class: "lt-bb-hole-rail" }));
22658
+ elements.push(circle({ cx, cy: r5.y + BB_CONST.RAIL_HEIGHT - 4, r: 1.4, class: "lt-bb-hole-rail" }));
22046
22659
  }
22047
22660
  }
22048
22661
  }
@@ -22069,10 +22682,10 @@ function renderSubstrate(sub) {
22069
22682
  elements.push(text({ x: sub.x + sub.width - BB_CONST.BOARD_PAD_X - 4, y: yBot, class: "lt-bb-row-label" }, rowsBot[i]));
22070
22683
  }
22071
22684
  for (let c = 1; c <= sub.cols; c++) {
22072
- for (let r3 = 0; r3 < 10; r3++) {
22685
+ for (let r5 = 0; r5 < 10; r5++) {
22073
22686
  const cx = sub.x + BB_CONST.BOARD_PAD_X + BB_CONST.ROW_LABEL_W + PITCH2 / 2 + (c - 1) * PITCH2;
22074
- let cy = gridY0 + r3 * PITCH2;
22075
- if (r3 >= 5) cy += BB_CONST.TROUGH;
22687
+ let cy = gridY0 + r5 * PITCH2;
22688
+ if (r5 >= 5) cy += BB_CONST.TROUGH;
22076
22689
  elements.push(circle({ cx, cy, r: 1.6, class: "lt-bb-hole" }));
22077
22690
  }
22078
22691
  }
@@ -22574,34 +23187,34 @@ function parseFlowLine(ln, flows, objectOwner, poolByLabel) {
22574
23187
  connectorLen = 3;
22575
23188
  } else if (rest.startsWith("--?")) {
22576
23189
  kind = "conditional";
22577
- let r3 = rest.slice(3).trimStart();
22578
- const q = takeQuoted(r3);
23190
+ let r5 = rest.slice(3).trimStart();
23191
+ const q = takeQuoted(r5);
22579
23192
  if (q) {
22580
23193
  connectorLabel = q.value;
22581
- r3 = q.rest.trimStart();
23194
+ r5 = q.rest.trimStart();
22582
23195
  }
22583
- if (!r3.startsWith("-->")) {
23196
+ if (!r5.startsWith("-->")) {
22584
23197
  throw new BpmnParseError(
22585
- `conditional flow must end with --> (got '${r3.slice(0, 20)}')`,
23198
+ `conditional flow must end with --> (got '${r5.slice(0, 20)}')`,
22586
23199
  ln.no
22587
23200
  );
22588
23201
  }
22589
- connectorLen = rest.length - r3.length + 3;
23202
+ connectorLen = rest.length - r5.length + 3;
22590
23203
  } else if (rest.startsWith("--*")) {
22591
23204
  kind = "default";
22592
- let r3 = rest.slice(3).trimStart();
22593
- const q = takeQuoted(r3);
23205
+ let r5 = rest.slice(3).trimStart();
23206
+ const q = takeQuoted(r5);
22594
23207
  if (q) {
22595
23208
  connectorLabel = q.value;
22596
- r3 = q.rest.trimStart();
23209
+ r5 = q.rest.trimStart();
22597
23210
  }
22598
- if (!r3.startsWith("-->")) {
23211
+ if (!r5.startsWith("-->")) {
22599
23212
  throw new BpmnParseError(
22600
- `default flow must end with --> (got '${r3.slice(0, 20)}')`,
23213
+ `default flow must end with --> (got '${r5.slice(0, 20)}')`,
22601
23214
  ln.no
22602
23215
  );
22603
23216
  }
22604
- connectorLen = rest.length - r3.length + 3;
23217
+ connectorLen = rest.length - r5.length + 3;
22605
23218
  } else if (rest.startsWith("-->")) {
22606
23219
  kind = "sequence";
22607
23220
  connectorLen = 3;
@@ -22694,8 +23307,8 @@ function objBox(o) {
22694
23307
  if ("gatewayKind" in o) {
22695
23308
  return { w: BPMN_CONST.gatewaySize, h: BPMN_CONST.gatewaySize };
22696
23309
  }
22697
- const r3 = BPMN_CONST.eventRadius;
22698
- return { w: r3 * 2, h: r3 * 2 };
23310
+ const r5 = BPMN_CONST.eventRadius;
23311
+ return { w: r5 * 2, h: r5 * 2 };
22699
23312
  }
22700
23313
  function layoutBpmn(ast) {
22701
23314
  const allObjects = [
@@ -23313,11 +23926,11 @@ function renderGateway(ol) {
23313
23926
  const g = ol.obj;
23314
23927
  const cx = ol.x + ol.width / 2;
23315
23928
  const cy = ol.y + ol.height / 2;
23316
- const r3 = ol.width / 2;
23317
- const points = `${cx},${cy - r3} ${cx + r3},${cy} ${cx},${cy + r3} ${cx - r3},${cy}`;
23929
+ const r5 = ol.width / 2;
23930
+ const points = `${cx},${cy - r5} ${cx + r5},${cy} ${cx},${cy + r5} ${cx - r5},${cy}`;
23318
23931
  const inner = [];
23319
23932
  if (g.gatewayKind === "xor") {
23320
- const a = r3 * 0.42;
23933
+ const a = r5 * 0.42;
23321
23934
  inner.push(
23322
23935
  el("path", {
23323
23936
  d: `M ${cx - a} ${cy - a} L ${cx + a} ${cy + a} M ${cx + a} ${cy - a} L ${cx - a} ${cy + a}`,
@@ -23327,7 +23940,7 @@ function renderGateway(ol) {
23327
23940
  })
23328
23941
  );
23329
23942
  } else if (g.gatewayKind === "and") {
23330
- const a = r3 * 0.5;
23943
+ const a = r5 * 0.5;
23331
23944
  inner.push(
23332
23945
  el("path", {
23333
23946
  d: `M ${cx - a} ${cy} L ${cx + a} ${cy} M ${cx} ${cy - a} L ${cx} ${cy + a}`,
@@ -23341,7 +23954,7 @@ function renderGateway(ol) {
23341
23954
  el("circle", {
23342
23955
  cx,
23343
23956
  cy,
23344
- r: r3 * 0.45,
23957
+ r: r5 * 0.45,
23345
23958
  fill: "none",
23346
23959
  stroke: STROKE,
23347
23960
  "stroke-width": 2
@@ -23352,13 +23965,13 @@ function renderGateway(ol) {
23352
23965
  el("circle", {
23353
23966
  cx,
23354
23967
  cy,
23355
- r: r3 * 0.55,
23968
+ r: r5 * 0.55,
23356
23969
  fill: "none",
23357
23970
  stroke: STROKE,
23358
23971
  "stroke-width": 1
23359
23972
  })
23360
23973
  );
23361
- const pr = r3 * 0.32;
23974
+ const pr = r5 * 0.32;
23362
23975
  const pts = [];
23363
23976
  for (let k = 0; k < 5; k++) {
23364
23977
  const ang = -Math.PI / 2 + k * 2 * Math.PI / 5;
@@ -23400,7 +24013,7 @@ function renderEvent2(ol) {
23400
24013
  const e = ol.obj;
23401
24014
  const cx = ol.x + ol.width / 2;
23402
24015
  const cy = ol.y + ol.height / 2;
23403
- const r3 = ol.width / 2;
24016
+ const r5 = ol.width / 2;
23404
24017
  const isEnd = e.kind === "end";
23405
24018
  const isIntermediate = e.kind === "intermediate";
23406
24019
  const strokeW = isEnd ? 3 : 1.2;
@@ -23409,7 +24022,7 @@ function renderEvent2(ol) {
23409
24022
  el("circle", {
23410
24023
  cx,
23411
24024
  cy,
23412
- r: r3,
24025
+ r: r5,
23413
24026
  fill: EVENT_FILL,
23414
24027
  stroke: STROKE,
23415
24028
  "stroke-width": strokeW
@@ -23420,7 +24033,7 @@ function renderEvent2(ol) {
23420
24033
  el("circle", {
23421
24034
  cx,
23422
24035
  cy,
23423
- r: r3 - 3,
24036
+ r: r5 - 3,
23424
24037
  fill: "none",
23425
24038
  stroke: STROKE,
23426
24039
  "stroke-width": 1.2
@@ -23429,9 +24042,9 @@ function renderEvent2(ol) {
23429
24042
  }
23430
24043
  const filled = e.throwCatch === "throw" && (isIntermediate || isEnd);
23431
24044
  if (e.trigger === "message") {
23432
- children.push(messageGlyph(cx, cy, r3 * 0.55, filled));
24045
+ children.push(messageGlyph(cx, cy, r5 * 0.55, filled));
23433
24046
  } else if (e.trigger === "timer") {
23434
- children.push(timerGlyph(cx, cy, r3 * 0.55));
24047
+ children.push(timerGlyph(cx, cy, r5 * 0.55));
23435
24048
  }
23436
24049
  if (e.label) {
23437
24050
  children.push(
@@ -23474,22 +24087,22 @@ function messageGlyph(cx, cy, size, filled) {
23474
24087
  ]);
23475
24088
  }
23476
24089
  function timerGlyph(cx, cy, size) {
23477
- const r3 = size / 2;
24090
+ const r5 = size / 2;
23478
24091
  const ticks = [];
23479
24092
  for (let k = 0; k < 12; k++) {
23480
24093
  const ang = k * Math.PI / 6 - Math.PI / 2;
23481
- const t1x = cx + (r3 - 1.5) * Math.cos(ang);
23482
- const t1y = cy + (r3 - 1.5) * Math.sin(ang);
23483
- const t2x = cx + r3 * Math.cos(ang);
23484
- const t2y = cy + r3 * Math.sin(ang);
24094
+ const t1x = cx + (r5 - 1.5) * Math.cos(ang);
24095
+ const t1y = cy + (r5 - 1.5) * Math.sin(ang);
24096
+ const t2x = cx + r5 * Math.cos(ang);
24097
+ const t2y = cy + r5 * Math.sin(ang);
23485
24098
  ticks.push(`M ${t1x} ${t1y} L ${t2x} ${t2y}`);
23486
24099
  }
23487
24100
  return el("g", { class: "trigger-timer" }, [
23488
- el("circle", { cx, cy, r: r3, fill: "none", stroke: STROKE, "stroke-width": 1 }),
24101
+ el("circle", { cx, cy, r: r5, fill: "none", stroke: STROKE, "stroke-width": 1 }),
23489
24102
  el("path", { d: ticks.join(" "), stroke: STROKE, "stroke-width": 0.8 }),
23490
24103
  // Hands
23491
24104
  el("path", {
23492
- d: `M ${cx} ${cy} L ${cx} ${cy - r3 * 0.7} M ${cx} ${cy} L ${cx + r3 * 0.5} ${cy}`,
24105
+ d: `M ${cx} ${cy} L ${cx} ${cy - r5 * 0.7} M ${cx} ${cy} L ${cx + r5 * 0.5} ${cy}`,
23493
24106
  stroke: STROKE,
23494
24107
  "stroke-width": 1.2,
23495
24108
  "stroke-linecap": "round"
@@ -23560,8 +24173,8 @@ function parseStart(d) {
23560
24173
  if (!m) return null;
23561
24174
  return { x: parseFloat(m[1]), y: parseFloat(m[2]) };
23562
24175
  }
23563
- function diamondPoints(cx, cy, r3) {
23564
- return `${cx - r3},${cy} ${cx},${cy - r3} ${cx + r3},${cy} ${cx},${cy + r3}`;
24176
+ function diamondPoints(cx, cy, r5) {
24177
+ return `${cx - r5},${cy} ${cx},${cy - r5} ${cx + r5},${cy} ${cx},${cy + r5}`;
23565
24178
  }
23566
24179
 
23567
24180
  // src/diagrams/bpmn/index.ts
@@ -25902,7 +26515,8 @@ var plugins = [
25902
26515
  petri,
25903
26516
  network,
25904
26517
  umlclass,
25905
- faulttree
26518
+ faulttree,
26519
+ bowtie2
25906
26520
  ];
25907
26521
  function detectPlugin(text2, config) {
25908
26522
  if (config?.type) {
@@ -25913,7 +26527,7 @@ function detectPlugin(text2, config) {
25913
26527
  if (plugin.detect(text2)) return plugin;
25914
26528
  }
25915
26529
  throw new Error(
25916
- "Cannot detect diagram type. Start your text with 'genogram', 'ecomap', 'pedigree', 'phylo', 'sociogram', 'timing', 'logic', 'circuit', 'blockdiagram', 'ladder', 'sld', 'entity-structure', 'fishbone', 'venn', 'flowchart', 'mindmap', 'matrix', 'orgchart', 'state', 'pid', 'erd', 'breadboard', 'bpmn', 'fbd', 'sfc', 'prisma', 'usecase', 'pert', 'sequence', 'petri', 'network', or 'umlclass'."
26530
+ "Cannot detect diagram type. Start your text with 'genogram', 'ecomap', 'pedigree', 'phylo', 'sociogram', 'timing', 'logic', 'circuit', 'blockdiagram', 'ladder', 'sld', 'entity-structure', 'fishbone', 'venn', 'flowchart', 'mindmap', 'matrix', 'orgchart', 'state', 'pid', 'erd', 'breadboard', 'bpmn', 'fbd', 'sfc', 'prisma', 'usecase', 'pert', 'sequence', 'petri', 'network', 'umlclass', 'faulttree', or 'bowtie'."
25917
26531
  );
25918
26532
  }
25919
26533
  function preprocess8(text2) {
@@ -26021,6 +26635,6 @@ function renderWithPlugin(prepared, plugin, config) {
26021
26635
  return plugin.render(prepared, renderConfig);
26022
26636
  }
26023
26637
 
26024
- export { GEOMETRY, decisiontree, drawDeviceIcon, faulttree, iconSize, network, parse, parseResult, pert, petri, pid, prisma, render, renderEquip, renderPreview, renderResult, sequence, state, timeline, umlclass, usecase };
26025
- //# sourceMappingURL=chunk-MI77LY6A.js.map
26026
- //# sourceMappingURL=chunk-MI77LY6A.js.map
26638
+ export { GEOMETRY, bowtie2 as bowtie, decisiontree, drawDeviceIcon, faulttree, iconSize, network, parse, parseResult, pert, petri, pid, prisma, render, renderEquip, renderPreview, renderResult, sequence, state, timeline, umlclass, usecase };
26639
+ //# sourceMappingURL=chunk-FOPOOV2P.js.map
26640
+ //# sourceMappingURL=chunk-FOPOOV2P.js.map