@diagrammo/dgmo 0.86.0 → 0.87.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/advanced.d.ts +0 -18
  2. package/dist/advanced.js +36 -35
  3. package/dist/block.js +5 -17
  4. package/dist/{chunk-FAV4RDVT.js → chunk-2A4DQAXG.js} +1 -1
  5. package/dist/{chunk-JIPUBFAM.js → chunk-5KGM44TG.js} +2 -2
  6. package/dist/{chunk-QJ2JOLFN.js → chunk-6I5UN4FD.js} +2 -2
  7. package/dist/{chunk-PKXKWHDW.js → chunk-AUS7V54P.js} +1 -1
  8. package/dist/{chunk-BF7JAFJI.js → chunk-B7CU2HW5.js} +2 -2
  9. package/dist/{chunk-X2VEJ5NT.js → chunk-BMUWF77V.js} +2 -2
  10. package/dist/{chunk-BP4BT5TH.js → chunk-CLQIXD2C.js} +1 -1
  11. package/dist/{chunk-QJFT5MAH.js → chunk-DSG6GBUQ.js} +2 -2
  12. package/dist/{chunk-EWSESGC2.js → chunk-EJS3K44P.js} +117 -78
  13. package/dist/{chunk-VEE777MD.js → chunk-FBKPSU3A.js} +3 -3
  14. package/dist/{chunk-5JO443MB.js → chunk-HAH5X345.js} +1 -1
  15. package/dist/{chunk-HBCAY3KR.js → chunk-HTNLLT34.js} +1 -1
  16. package/dist/{chunk-HUMQIRJK.js → chunk-HTPZDZKQ.js} +2 -2
  17. package/dist/{chunk-VPVWG2GH.js → chunk-J7Q4VPBJ.js} +1 -1
  18. package/dist/{chunk-3CQS3CIO.js → chunk-LL6D3MES.js} +1 -1
  19. package/dist/{chunk-QPE646M2.js → chunk-LPXC4I4R.js} +18 -1
  20. package/dist/{chunk-ERYHC4KJ.js → chunk-LSQGJN5H.js} +1 -1
  21. package/dist/{chunk-E6S2K6O2.js → chunk-N7XRBWXA.js} +2 -2
  22. package/dist/{chunk-WMIKC5XO.js → chunk-NPWVOFB3.js} +1 -1
  23. package/dist/{chunk-MYHPRQHR.js → chunk-O6MMQQLF.js} +3 -3
  24. package/dist/{chunk-GYORDNOM.js → chunk-P5V63L35.js} +1 -1
  25. package/dist/{chunk-4YA5XW43.js → chunk-PJQZWJ5I.js} +50 -28
  26. package/dist/{chunk-BHZE36F7.js → chunk-PUVTFUNH.js} +1 -1
  27. package/dist/{chunk-ETBXIKK6.js → chunk-Q2U5635V.js} +1 -1
  28. package/dist/{chunk-TW6WMZFW.js → chunk-QT3KDDXK.js} +156 -7
  29. package/dist/{chunk-ZGHV4QLK.js → chunk-RJNZHFNG.js} +1 -1
  30. package/dist/{chunk-FWNJDD4U.js → chunk-S7W75MIM.js} +3 -20
  31. package/dist/{chunk-C6FZZFYD.js → chunk-WZ23JJ7U.js} +1 -1
  32. package/dist/{chunk-LIYWJ6DV.js → chunk-XIFK423U.js} +108 -13
  33. package/dist/{chunk-4ELXLATB.js → chunk-XUDGZJTJ.js} +2 -2
  34. package/dist/{chunk-H6AFNCN3.js → chunk-XVSJYAK7.js} +1 -1
  35. package/dist/{chunk-LHBMQJC3.js → chunk-XWYR5T52.js} +2 -2
  36. package/dist/{chunk-QNKHJ5CK.js → chunk-YK4N6TBN.js} +4 -2
  37. package/dist/{chunk-XFMQSFS4.js → chunk-YMG7JDEY.js} +16 -6
  38. package/dist/chunk-Z6DXWULM.js +23 -0
  39. package/dist/{chunk-PBEH52A2.js → chunk-ZNNVI5SR.js} +1 -1
  40. package/dist/{flowchart-renderer-H72L7BEC.js → flowchart-renderer-THC6Y7EH.js} +7 -6
  41. package/dist/index.d.ts +68 -1
  42. package/dist/index.js +75 -7
  43. package/dist/{layout-QIPCNUSB.js → layout-BOVTLAOT.js} +7 -6
  44. package/dist/{layout-6JARW64V.js → layout-EHTYSMV4.js} +6 -5
  45. package/dist/{layout-YELNBVPC.js → layout-P6DTD4RT.js} +6 -5
  46. package/dist/{layout-T6TAB5OI.js → layout-RANVNAKI.js} +3 -3
  47. package/dist/{layout-FMKSENGL.js → layout-XUW444O5.js} +5 -4
  48. package/dist/{layout-search-AW5VBDCV.js → layout-search-VKSBUCDM.js} +57 -28
  49. package/dist/{renderer-AI2MD52D.js → renderer-222OTVQV.js} +3 -2
  50. package/dist/{renderer-UUWR7NGF.js → renderer-2KVQGGTT.js} +4 -3
  51. package/dist/{renderer-E5EKGIX2.js → renderer-2OOPQ4CH.js} +4 -3
  52. package/dist/{renderer-RLSR7N6I.js → renderer-3CTUWCO7.js} +5 -4
  53. package/dist/{renderer-CZJ4AMYV.js → renderer-3FF4QVGW.js} +3 -2
  54. package/dist/{renderer-R6VJDZFO.js → renderer-4BHOELCE.js} +4 -3
  55. package/dist/{renderer-425QUIYO.js → renderer-4BIMRO4X.js} +4 -3
  56. package/dist/{renderer-5JVVJBAS.js → renderer-A4LMOBZL.js} +8 -7
  57. package/dist/{renderer-3AOOLHJU.js → renderer-A6ACVK4X.js} +3 -2
  58. package/dist/{renderer-ML2CLU25.js → renderer-DCFQDBGJ.js} +4 -3
  59. package/dist/{renderer-ADX4DWRJ.js → renderer-ELYPDPNF.js} +3 -2
  60. package/dist/{renderer-RH4U3UVM.js → renderer-LODEVN3V.js} +3 -2
  61. package/dist/{renderer-E7WF75GY.js → renderer-NHPKNNBD.js} +5 -4
  62. package/dist/{renderer-JEEGPLMM.js → renderer-R34GJL7U.js} +8 -7
  63. package/dist/{renderer-2BWRW23Z.js → renderer-RENDISO5.js} +1 -1
  64. package/dist/{renderer-VKAJ52UO.js → renderer-SDUSBCJI.js} +3 -2
  65. package/dist/{renderer-RUGMKHX5.js → renderer-WH2HWE5Z.js} +3 -2
  66. package/dist/{renderer-V6LLASGN.js → renderer-X5A5VIRD.js} +5 -4
  67. package/dist/{renderer-EWJS2RAZ.js → renderer-YDAVCRTP.js} +3 -2
  68. package/dist/{state-renderer-DDVJ43HR.js → state-renderer-5IQ4OJUI.js} +7 -6
  69. package/gallery/fixtures/journey-map.dgmo +28 -0
  70. package/gallery/fixtures/mindmap.dgmo +31 -0
  71. package/gallery/fixtures/pert.dgmo +27 -0
  72. package/gallery/fixtures/wireframe.dgmo +30 -0
  73. package/package.json +2 -2
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  layoutERDiagram
3
- } from "./chunk-FAV4RDVT.js";
3
+ } from "./chunk-2A4DQAXG.js";
4
4
  import {
5
5
  NOTE_BADGE_RADIUS,
6
6
  noteConnectorPoints,
7
7
  renderNoteBadge,
8
8
  renderNoteBox,
9
9
  renderNoteConnector
10
- } from "./chunk-5JO443MB.js";
10
+ } from "./chunk-HAH5X345.js";
11
11
  import {
12
12
  ScaleContext
13
13
  } from "./chunk-24YPR5EH.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  renderInlineText
3
- } from "./chunk-FWNJDD4U.js";
3
+ } from "./chunk-S7W75MIM.js";
4
4
  import {
5
5
  ScaleContext
6
6
  } from "./chunk-24YPR5EH.js";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-UIUXIDBX.js";
5
5
  import {
6
6
  renderInlineText
7
- } from "./chunk-FWNJDD4U.js";
7
+ } from "./chunk-S7W75MIM.js";
8
8
  import {
9
9
  ScaleContext
10
10
  } from "./chunk-24YPR5EH.js";
@@ -54,6 +54,21 @@ import {
54
54
  themeBaseBg
55
55
  } from "./chunk-7HWY4QAJ.js";
56
56
 
57
+ // src/embed/escape.ts
58
+ var HTML_ENTITIES = {
59
+ "&": "&",
60
+ "<": "&lt;",
61
+ ">": "&gt;",
62
+ '"': "&quot;",
63
+ "'": "&#39;"
64
+ };
65
+ function escapeHtml(s) {
66
+ return s.replace(/[&<>"']/g, (ch) => HTML_ENTITIES[ch] ?? ch);
67
+ }
68
+ function escapeAttr(s) {
69
+ return s.replace(/[&<>"']/g, (ch) => HTML_ENTITIES[ch] ?? ch);
70
+ }
71
+
57
72
  // src/timeline/renderer.ts
58
73
  import * as d3Scale from "d3-scale";
59
74
  import * as d3Selection from "d3-selection";
@@ -281,7 +296,7 @@ function hideEventDatesOnScale(g) {
281
296
  }
282
297
  function buildEventTooltipHtml(ev) {
283
298
  const datePart = ev.endDate ? `${formatDateLabel(ev.date)} \u2192 ${formatDateLabel(ev.endDate)}` : formatDateLabel(ev.date);
284
- return `<strong>${ev.label}</strong><br>${datePart}`;
299
+ return `<strong>${escapeHtml(ev.label)}</strong><br>${datePart}`;
285
300
  }
286
301
  function renderTimelineGroupLegend(g, groups, groupColorMap, textColor, palette, isDark, legendY, onHover, onLeave) {
287
302
  const PILL_H = 22;
@@ -1672,6 +1687,8 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
1672
1687
  }
1673
1688
 
1674
1689
  export {
1690
+ escapeHtml,
1691
+ escapeAttr,
1675
1692
  formatDateLabel,
1676
1693
  renderTimeline
1677
1694
  };
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-XBJJP2HN.js";
10
10
  import {
11
11
  renderInlineText
12
- } from "./chunk-FWNJDD4U.js";
12
+ } from "./chunk-S7W75MIM.js";
13
13
  import {
14
14
  ScaleContext
15
15
  } from "./chunk-24YPR5EH.js";
@@ -6,13 +6,13 @@ import {
6
6
  } from "./chunk-DOXBS7F5.js";
7
7
  import {
8
8
  wrapNoteBody
9
- } from "./chunk-ZGHV4QLK.js";
9
+ } from "./chunk-RJNZHFNG.js";
10
10
  import {
11
11
  NOTE_BULLET_INDENT
12
12
  } from "./chunk-5DH3KYFH.js";
13
13
  import {
14
14
  renderInlineText
15
- } from "./chunk-FWNJDD4U.js";
15
+ } from "./chunk-S7W75MIM.js";
16
16
  import {
17
17
  ScaleContext
18
18
  } from "./chunk-24YPR5EH.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  stripInlineMarkdown
3
- } from "./chunk-FWNJDD4U.js";
3
+ } from "./chunk-S7W75MIM.js";
4
4
 
5
5
  // src/utils/wrapped-desc.ts
6
6
  var BULLET_PREFIX = "\u2022 ";
@@ -4,18 +4,18 @@ import {
4
4
  renderNoteBadge,
5
5
  renderNoteBox,
6
6
  renderNoteConnector
7
- } from "./chunk-5JO443MB.js";
7
+ } from "./chunk-HAH5X345.js";
8
8
  import {
9
9
  appendArrowheadMarkers,
10
10
  appendReverseArrowheadMarkers
11
11
  } from "./chunk-XBJJP2HN.js";
12
12
  import {
13
13
  wrapDescriptionLines
14
- } from "./chunk-WMIKC5XO.js";
14
+ } from "./chunk-NPWVOFB3.js";
15
15
  import {
16
16
  renderInlineText,
17
17
  stripInlineMarkdown
18
- } from "./chunk-FWNJDD4U.js";
18
+ } from "./chunk-S7W75MIM.js";
19
19
  import {
20
20
  ScaleContext
21
21
  } from "./chunk-24YPR5EH.js";
@@ -1579,7 +1579,7 @@ function renderScurveBlock(svg, data, args) {
1579
1579
  }));
1580
1580
  const curve = d3Shape.line().x((d) => d.x).y((d) => d.y).curve(d3Shape.curveMonotoneX)(points);
1581
1581
  if (curve) {
1582
- const clipId = `pert-scurve-clip-${Math.random().toString(36).slice(2, 10)}`;
1582
+ const clipId = `pert-scurve-clip-${[plotLeft, plotTop, plotW, plotH].map((v) => Math.round(v)).join("-")}`;
1583
1583
  block.append("clipPath").attr("id", clipId).append("rect").attr("x", plotLeft).attr("y", plotTop).attr("width", plotW).attr("height", plotH);
1584
1584
  block.append("path").attr("class", "pert-scurve-line").attr("d", curve).attr("fill", "none").attr("stroke", palette.colors.red).attr("stroke-width", 2).attr("clip-path", `url(#${clipId})`);
1585
1585
  }
@@ -20,7 +20,7 @@ import {
20
20
  } from "./chunk-KMU65FYM.js";
21
21
  import {
22
22
  renderTimeline
23
- } from "./chunk-QPE646M2.js";
23
+ } from "./chunk-LPXC4I4R.js";
24
24
  import {
25
25
  ScaleContext
26
26
  } from "./chunk-24YPR5EH.js";
@@ -1991,7 +1991,7 @@ function ctxTagOverride(ctx) {
1991
1991
  async function exportEventLine(ctx) {
1992
1992
  const { content, theme, palette } = ctx;
1993
1993
  const { parseEventLine } = await import("./parser-KFYRTGTC.js");
1994
- const { renderEventLineForExport } = await import("./renderer-RLSR7N6I.js");
1994
+ const { renderEventLineForExport } = await import("./renderer-3CTUWCO7.js");
1995
1995
  const effectivePalette = await resolveExportPalette(theme, palette);
1996
1996
  const parsed = parseEventLine(content, effectivePalette);
1997
1997
  if (parsed.error || parsed.events.length === 0) return "";
@@ -2119,7 +2119,7 @@ async function exportSitemap(ctx) {
2119
2119
  const { parseSitemap } = await import("./parser-OKB64MMN.js");
2120
2120
  const { layoutSitemap } = await import("./layout-LUQKAGGT.js");
2121
2121
  const { collapseSitemapTree } = await import("./collapse-ZWUFFCK2.js");
2122
- const { renderSitemap } = await import("./renderer-RUGMKHX5.js");
2122
+ const { renderSitemap } = await import("./renderer-WH2HWE5Z.js");
2123
2123
  const isDark = ctx.isDark;
2124
2124
  const effectivePalette = await resolveExportPalette(theme, palette);
2125
2125
  const sitemapParsed = parseSitemap(content, effectivePalette);
@@ -2169,7 +2169,7 @@ async function exportSitemap(ctx) {
2169
2169
  async function exportKanban(ctx) {
2170
2170
  const { content, theme, palette, viewState, exportMode } = ctx;
2171
2171
  const { parseKanban } = await import("./parser-ACW6C6OY.js");
2172
- const { renderKanban } = await import("./renderer-CZJ4AMYV.js");
2172
+ const { renderKanban } = await import("./renderer-3FF4QVGW.js");
2173
2173
  const effectivePalette = await resolveExportPalette(theme, palette);
2174
2174
  const kanbanParsed = parseKanban(content, effectivePalette);
2175
2175
  if (kanbanParsed.error || kanbanParsed.columns.length === 0) return "";
@@ -2201,8 +2201,8 @@ async function exportKanban(ctx) {
2201
2201
  async function exportClass(ctx) {
2202
2202
  const { content, theme, palette, exportMode } = ctx;
2203
2203
  const { parseClassDiagram } = await import("./parser-GPW4ZHPQ.js");
2204
- const { layoutClassDiagram } = await import("./layout-YELNBVPC.js");
2205
- const { renderClassDiagram } = await import("./renderer-5JVVJBAS.js");
2204
+ const { layoutClassDiagram } = await import("./layout-P6DTD4RT.js");
2205
+ const { renderClassDiagram } = await import("./renderer-A4LMOBZL.js");
2206
2206
  const effectivePalette = await resolveExportPalette(theme, palette);
2207
2207
  const classParsed = parseClassDiagram(content, effectivePalette);
2208
2208
  if (classParsed.error || classParsed.classes.length === 0) return "";
@@ -2228,8 +2228,8 @@ async function exportClass(ctx) {
2228
2228
  async function exportEr(ctx) {
2229
2229
  const { content, theme, palette, viewState, exportMode } = ctx;
2230
2230
  const { parseERDiagram } = await import("./parser-J4DVNL4W.js");
2231
- const { layoutERDiagram } = await import("./layout-6JARW64V.js");
2232
- const { renderERDiagram } = await import("./renderer-JEEGPLMM.js");
2231
+ const { layoutERDiagram } = await import("./layout-EHTYSMV4.js");
2232
+ const { renderERDiagram } = await import("./renderer-R34GJL7U.js");
2233
2233
  const effectivePalette = await resolveExportPalette(theme, palette);
2234
2234
  const erParsed = parseERDiagram(content, effectivePalette);
2235
2235
  if (erParsed.error || erParsed.tables.length === 0) return "";
@@ -2306,8 +2306,8 @@ async function exportBoxesAndLines(ctx) {
2306
2306
  blHiddenTagValues.set(k, new Set(v));
2307
2307
  }
2308
2308
  }
2309
- const { renderBoxesAndLinesForExport } = await import("./renderer-V6LLASGN.js");
2310
- const { layoutBoxesAndLines } = await import("./layout-QIPCNUSB.js");
2309
+ const { renderBoxesAndLinesForExport } = await import("./renderer-X5A5VIRD.js");
2310
+ const { layoutBoxesAndLines } = await import("./layout-BOVTLAOT.js");
2311
2311
  const blLayout = await layoutBoxesAndLines(blParsed);
2312
2312
  const PADDING = 20;
2313
2313
  const titleOffset = blParsed.title ? 40 : 0;
@@ -2337,7 +2337,7 @@ async function exportBoxesAndLines(ctx) {
2337
2337
  async function exportSwimlane(ctx) {
2338
2338
  const { content, theme, palette } = ctx;
2339
2339
  const { parseSwimlane } = await import("./parser-ZLKYDFI5.js");
2340
- const { layoutSwimlane } = await import("./layout-T6TAB5OI.js");
2340
+ const { layoutSwimlane } = await import("./layout-RANVNAKI.js");
2341
2341
  const { renderSwimlaneForExport } = await import("./renderer-QM23SWAM.js");
2342
2342
  const effectivePalette = await resolveExportPalette(theme, palette);
2343
2343
  const swimParsed = parseSwimlane(content, effectivePalette);
@@ -2403,7 +2403,7 @@ async function exportMindmap(ctx) {
2403
2403
  const { parseMindmap } = await import("./parser-NGHQQGD2.js");
2404
2404
  const { layoutMindmap } = await import("./layout-5NPBHV5F.js");
2405
2405
  const { collapseMindmapTree } = await import("./collapse-SLINJQW6.js");
2406
- const { renderMindmap } = await import("./renderer-RH4U3UVM.js");
2406
+ const { renderMindmap } = await import("./renderer-LODEVN3V.js");
2407
2407
  const isDark = ctx.isDark;
2408
2408
  const effectivePalette = await resolveExportPalette(theme, palette);
2409
2409
  const mmParsed = parseMindmap(content, effectivePalette);
@@ -2485,7 +2485,7 @@ async function exportC4(ctx) {
2485
2485
  layoutC4Components,
2486
2486
  layoutC4Deployment
2487
2487
  } = await import("./layout-CUFA7XJD.js");
2488
- const { renderC4Context, renderC4Containers } = await import("./renderer-EWJS2RAZ.js");
2488
+ const { renderC4Context, renderC4Containers } = await import("./renderer-YDAVCRTP.js");
2489
2489
  const effectivePalette = await resolveExportPalette(theme, palette);
2490
2490
  const c4Parsed = parseC4(content, effectivePalette);
2491
2491
  if (c4Parsed.error || c4Parsed.elements.length === 0) return "";
@@ -2520,8 +2520,8 @@ async function exportC4(ctx) {
2520
2520
  async function exportFlowchart(ctx) {
2521
2521
  const { content, theme, palette } = ctx;
2522
2522
  const { parseFlowchart } = await import("./flowchart-parser-GG7XBLQH.js");
2523
- const { layoutGraph } = await import("./layout-FMKSENGL.js");
2524
- const { renderFlowchart } = await import("./flowchart-renderer-H72L7BEC.js");
2523
+ const { layoutGraph } = await import("./layout-XUW444O5.js");
2524
+ const { renderFlowchart } = await import("./flowchart-renderer-THC6Y7EH.js");
2525
2525
  const effectivePalette = await resolveExportPalette(theme, palette);
2526
2526
  const fcParsed = parseFlowchart(content, effectivePalette);
2527
2527
  if (fcParsed.error || fcParsed.nodes.length === 0) return "";
@@ -2543,7 +2543,7 @@ async function exportInfra(ctx) {
2543
2543
  const { parseInfra } = await import("./parser-DGF3ZEO6.js");
2544
2544
  const { computeInfra } = await import("./compute-JAP5E2E4.js");
2545
2545
  const { layoutInfra } = await import("./layout-SW3XWYKC.js");
2546
- const { renderInfra, computeInfraLegendGroups } = await import("./renderer-VKAJ52UO.js");
2546
+ const { renderInfra, computeInfraLegendGroups } = await import("./renderer-SDUSBCJI.js");
2547
2547
  const effectivePalette = await resolveExportPalette(theme, palette);
2548
2548
  const infraParsed = parseInfra(content);
2549
2549
  if (infraParsed.error || infraParsed.nodes.length === 0) return "";
@@ -2593,7 +2593,7 @@ async function exportPert(ctx) {
2593
2593
  const { parsePert } = await import("./parser-JXS4426S.js");
2594
2594
  const { analyzePert } = await import("./analyzer-R5UBTRO2.js");
2595
2595
  const { layoutPert } = await import("./layout-AM57TGN5.js");
2596
- const { renderPert, measurePertAnalysisBlock } = await import("./renderer-2BWRW23Z.js");
2596
+ const { renderPert, measurePertAnalysisBlock } = await import("./renderer-RENDISO5.js");
2597
2597
  const effectivePalette = await resolveExportPalette(theme, palette);
2598
2598
  const pertParsed = parsePert(content, { palette: effectivePalette });
2599
2599
  if (pertParsed.error || pertParsed.activities.length === 0) return "";
@@ -2680,8 +2680,8 @@ async function exportGantt(ctx) {
2680
2680
  async function exportState(ctx) {
2681
2681
  const { content, theme, palette, viewState } = ctx;
2682
2682
  const { parseState } = await import("./state-parser-FE3RF6XY.js");
2683
- const { layoutGraph } = await import("./layout-FMKSENGL.js");
2684
- const { renderState } = await import("./state-renderer-DDVJ43HR.js");
2683
+ const { layoutGraph } = await import("./layout-XUW444O5.js");
2684
+ const { renderState } = await import("./state-renderer-5IQ4OJUI.js");
2685
2685
  const { collapseStateGroups } = await import("./state-collapse-HCGD6IVJ.js");
2686
2686
  const effectivePalette = await resolveExportPalette(theme, palette);
2687
2687
  const stateParsed = parseState(content, effectivePalette);
@@ -2719,7 +2719,7 @@ async function exportState(ctx) {
2719
2719
  async function exportTechRadar(ctx) {
2720
2720
  const { content, theme, palette, viewState, exportMode } = ctx;
2721
2721
  const { parseTechRadar } = await import("./parser-NOANDFJ4.js");
2722
- const { renderTechRadarForExport } = await import("./renderer-3AOOLHJU.js");
2722
+ const { renderTechRadarForExport } = await import("./renderer-A6ACVK4X.js");
2723
2723
  const effectivePalette = await resolveExportPalette(theme, palette);
2724
2724
  const radarParsed = parseTechRadar(content);
2725
2725
  if (radarParsed.error || radarParsed.quadrants.length === 0) return "";
@@ -2740,7 +2740,7 @@ async function exportTechRadar(ctx) {
2740
2740
  async function exportJourneyMap(ctx) {
2741
2741
  const { content, theme, palette, exportMode } = ctx;
2742
2742
  const { parseJourneyMap } = await import("./parser-C327BBE3.js");
2743
- const { renderJourneyMap } = await import("./renderer-E7WF75GY.js");
2743
+ const { renderJourneyMap } = await import("./renderer-NHPKNNBD.js");
2744
2744
  const { layoutJourneyMap } = await import("./layout-SOPAVXIH.js");
2745
2745
  const effectivePalette = await resolveExportPalette(theme, palette);
2746
2746
  const jmParsed = parseJourneyMap(content, effectivePalette);
@@ -2762,7 +2762,7 @@ async function exportJourneyMap(ctx) {
2762
2762
  async function exportCycle(ctx) {
2763
2763
  const { content, theme, palette, viewState, exportMode } = ctx;
2764
2764
  const { parseCycle } = await import("./parser-7OEE7QT6.js");
2765
- const { renderCycleForExport } = await import("./renderer-425QUIYO.js");
2765
+ const { renderCycleForExport } = await import("./renderer-4BIMRO4X.js");
2766
2766
  const effectivePalette = await resolveExportPalette(theme, palette);
2767
2767
  const cycleParsed = parseCycle(content);
2768
2768
  if (cycleParsed.error || cycleParsed.nodes.length === 0) return "";
@@ -2817,7 +2817,7 @@ async function exportMap(ctx) {
2817
2817
  async function exportPyramid(ctx) {
2818
2818
  const { content, theme, palette } = ctx;
2819
2819
  const { parsePyramid } = await import("./parser-OVQTTTUJ.js");
2820
- const { renderPyramidForExport } = await import("./renderer-R6VJDZFO.js");
2820
+ const { renderPyramidForExport } = await import("./renderer-4BHOELCE.js");
2821
2821
  const effectivePalette = await resolveExportPalette(theme, palette);
2822
2822
  const pyramidParsed = parsePyramid(content);
2823
2823
  if (pyramidParsed.error || pyramidParsed.layers.length === 0) return "";
@@ -2834,7 +2834,7 @@ async function exportPyramid(ctx) {
2834
2834
  async function exportRing(ctx) {
2835
2835
  const { content, theme, palette } = ctx;
2836
2836
  const { parseRing } = await import("./parser-GZ3LVF72.js");
2837
- const { renderRingForExport } = await import("./renderer-E5EKGIX2.js");
2837
+ const { renderRingForExport } = await import("./renderer-2OOPQ4CH.js");
2838
2838
  const effectivePalette = await resolveExportPalette(theme, palette);
2839
2839
  const ringParsed = parseRing(content);
2840
2840
  if (ringParsed.error || ringParsed.layers.length === 0) return "";
@@ -2898,7 +2898,7 @@ async function exportBlock(ctx) {
2898
2898
  async function exportGoal(ctx) {
2899
2899
  const { content, theme, palette } = ctx;
2900
2900
  const { parseGoal } = await import("./parser-SA3RAJFS.js");
2901
- const { renderGoalForExport } = await import("./renderer-AI2MD52D.js");
2901
+ const { renderGoalForExport } = await import("./renderer-222OTVQV.js");
2902
2902
  const effectivePalette = await resolveExportPalette(theme, palette);
2903
2903
  const parsed = parseGoal(content, effectivePalette);
2904
2904
  if (parsed.error) return "";
@@ -2912,7 +2912,7 @@ async function exportGoal(ctx) {
2912
2912
  async function exportCountdown(ctx) {
2913
2913
  const { content, theme, palette } = ctx;
2914
2914
  const { parseCountdown } = await import("./parser-LGS65QPN.js");
2915
- const { renderCountdownForExport } = await import("./renderer-ML2CLU25.js");
2915
+ const { renderCountdownForExport } = await import("./renderer-DCFQDBGJ.js");
2916
2916
  const effectivePalette = await resolveExportPalette(theme, palette);
2917
2917
  const parsed = parseCountdown(content, effectivePalette);
2918
2918
  if (parsed.error) return "";
@@ -2940,7 +2940,7 @@ async function exportClock(ctx) {
2940
2940
  async function exportBracket(ctx) {
2941
2941
  const { content, theme, palette } = ctx;
2942
2942
  const { parseBracket } = await import("./parser-DHSFIUPU.js");
2943
- const { renderBracketForExport, bracketExportDimensions } = await import("./renderer-ADX4DWRJ.js");
2943
+ const { renderBracketForExport, bracketExportDimensions } = await import("./renderer-ELYPDPNF.js");
2944
2944
  const effectivePalette = await resolveExportPalette(theme, palette);
2945
2945
  const parsed = parseBracket(content, effectivePalette);
2946
2946
  if (parsed.error) return "";
@@ -3088,7 +3088,7 @@ async function exportVisualization(ctx) {
3088
3088
  const isDark = ctx.isDark;
3089
3089
  const container = createExportContainer(ctx.width, ctx.height);
3090
3090
  const { parseSequenceDgmo } = await import("./parser-PVIWHVGY.js");
3091
- const { renderSequenceDiagram } = await import("./renderer-UUWR7NGF.js");
3091
+ const { renderSequenceDiagram } = await import("./renderer-2KVQGGTT.js");
3092
3092
  const seqParsed = parseSequenceDgmo(content, effectivePalette);
3093
3093
  if (seqParsed.error || seqParsed.participants.length === 0) return "";
3094
3094
  const collapsedSections = viewState?.cs ? new Set(viewState.cs) : void 0;
@@ -3145,6 +3145,14 @@ function legendRule(mark, attr, v, emphasis, dimOpacity) {
3145
3145
  const trigger = `svg:has([data-legend-entry="${entryLit}"]:hover)`;
3146
3146
  return emphasis === "lift" ? `${trigger} ${mark}[${attr}="${attrLit}"]{${LIFT_DECL}}` : `${trigger} ${mark}:not([${attr}="${attrLit}"]){opacity:${dimOpacity}}`;
3147
3147
  }
3148
+ function legendReverseRule(mark, attr, v, emphasis, dimOpacity) {
3149
+ const entryLit = escCssString(v.toLowerCase());
3150
+ const attrLit = escCssString(v);
3151
+ const trigger = `svg:has(${mark}[${attr}="${attrLit}"]:hover)`;
3152
+ if (emphasis === "lift")
3153
+ return `${trigger} [data-legend-entry="${entryLit}"]{${LIFT_DECL}}`;
3154
+ return `${trigger}:has([data-legend-entry="${entryLit}"]) [data-legend-entry]:not([data-legend-entry="${entryLit}"]){opacity:${dimOpacity}}`;
3155
+ }
3148
3156
  function connectionRule(spec, id, dimOpacity) {
3149
3157
  const lit = escCssString(id);
3150
3158
  const { hoverSelector, hoverAttr, edgeSelector, fromAttr, toAttr } = spec;
@@ -3197,6 +3205,13 @@ function buildHoverCss(spec, derived = {}, emphasisOverride) {
3197
3205
  v,
3198
3206
  emphasis,
3199
3207
  dimOpacity
3208
+ ),
3209
+ legendReverseRule(
3210
+ spec.markSelector,
3211
+ spec.groupAttr,
3212
+ v,
3213
+ emphasis,
3214
+ dimOpacity
3200
3215
  )
3201
3216
  );
3202
3217
  }
@@ -3226,6 +3241,13 @@ function buildHoverCss(spec, derived = {}, emphasisOverride) {
3226
3241
  v,
3227
3242
  emphasis,
3228
3243
  dimOpacity
3244
+ ),
3245
+ legendReverseRule(
3246
+ spec.markSelector,
3247
+ derived.legendAttr,
3248
+ v,
3249
+ emphasis,
3250
+ dimOpacity
3229
3251
  )
3230
3252
  );
3231
3253
  }
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-R2K5L4UA.js";
4
4
  import {
5
5
  renderInlineText
6
- } from "./chunk-FWNJDD4U.js";
6
+ } from "./chunk-S7W75MIM.js";
7
7
  import {
8
8
  ScaleContext
9
9
  } from "./chunk-24YPR5EH.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  renderInlineText
3
- } from "./chunk-FWNJDD4U.js";
3
+ } from "./chunk-S7W75MIM.js";
4
4
  import {
5
5
  layoutInlineHeader
6
6
  } from "./chunk-3DOQOXXI.js";
@@ -10,6 +10,7 @@ var NODE_HEIGHT = 60;
10
10
  var NODE_WIDTH = Math.round(NODE_HEIGHT * PHI);
11
11
 
12
12
  // src/boxes-and-lines/label-placement.ts
13
+ import { curveBasis } from "d3-shape";
13
14
  var EDGE_LABEL_FONT_SIZE = 11;
14
15
  var LABEL_MAX_WIDTH = 160;
15
16
  var MAX_LABEL_LINES = 3;
@@ -21,6 +22,12 @@ var PERP_STEP = 8;
21
22
  var LABEL_REACH_NEAR = 40;
22
23
  var LABEL_REACH_WIDE = 56;
23
24
  var SLIDE_SAMPLES = 9;
25
+ var CURVE_STEP = 4;
26
+ var EDGE_CLEAR_PAD = 2;
27
+ var GROUP_BORDER_BAND = 4;
28
+ var GROUP_TITLE_FONT_SIZE = 14;
29
+ var GROUP_TITLE_DEPTH = 24;
30
+ var GROUP_LABEL_ZONE = 32;
24
31
  function measureEdgeLabel(label, fontSize = EDGE_LABEL_FONT_SIZE, maxWidth = LABEL_MAX_WIDTH) {
25
32
  let lines = wrapTextToWidth(label, fontSize, maxWidth, { hardBreak: true });
26
33
  if (lines.length > MAX_LABEL_LINES) {
@@ -108,24 +115,69 @@ function slideFractions() {
108
115
  }
109
116
  return out;
110
117
  }
111
- function findClearPosition(w, h, points, obstacles, perpMax) {
118
+ function findClearPosition(points, blocked, perpMax, firstSide = -1) {
112
119
  const ts = slideFractions();
113
120
  for (const t of ts) {
114
121
  const { p } = pointAtArcFraction(points, t);
115
- if (!overlapsAny(p.x, p.y, w, h, obstacles, BOX_CLEAR_PAD)) return p;
122
+ if (!blocked(p.x, p.y)) return p;
116
123
  }
117
124
  for (let mag = PERP_STEP; mag <= perpMax; mag += PERP_STEP) {
118
125
  for (const t of ts) {
119
126
  const { p, nx, ny } = pointAtArcFraction(points, t);
120
- for (const sign of [-1, 1]) {
127
+ for (const sign of [firstSide, -firstSide]) {
121
128
  const x = p.x + nx * mag * sign;
122
129
  const y = p.y + ny * mag * sign;
123
- if (!overlapsAny(x, y, w, h, obstacles, BOX_CLEAR_PAD)) return { x, y };
130
+ if (!blocked(x, y)) return { x, y };
124
131
  }
125
132
  }
126
133
  }
127
134
  return null;
128
135
  }
136
+ function sampleDrawnCurve(points) {
137
+ const out = [];
138
+ if (points.length < 2) return out;
139
+ let cx = 0;
140
+ let cy = 0;
141
+ const ctx = {
142
+ moveTo(x, y) {
143
+ out.push({ x, y });
144
+ cx = x;
145
+ cy = y;
146
+ },
147
+ lineTo(x, y) {
148
+ const n = Math.max(1, Math.ceil(Math.hypot(x - cx, y - cy) / CURVE_STEP));
149
+ for (let k = 1; k <= n; k++)
150
+ out.push({ x: cx + (x - cx) * k / n, y: cy + (y - cy) * k / n });
151
+ cx = x;
152
+ cy = y;
153
+ },
154
+ bezierCurveTo(x1, y1, x2, y2, x, y) {
155
+ const n = Math.max(
156
+ 1,
157
+ Math.ceil(
158
+ (Math.hypot(x1 - cx, y1 - cy) + Math.hypot(x2 - x1, y2 - y1) + Math.hypot(x - x2, y - y2)) / CURVE_STEP
159
+ )
160
+ );
161
+ for (let k = 1; k <= n; k++) {
162
+ const t = k / n;
163
+ const u = 1 - t;
164
+ out.push({
165
+ x: u * u * u * cx + 3 * u * u * t * x1 + 3 * u * t * t * x2 + t * t * t * x,
166
+ y: u * u * u * cy + 3 * u * u * t * y1 + 3 * u * t * t * y2 + t * t * t * y
167
+ });
168
+ }
169
+ cx = x;
170
+ cy = y;
171
+ },
172
+ closePath() {
173
+ }
174
+ };
175
+ const curve = curveBasis(ctx);
176
+ curve.lineStart();
177
+ for (const p of points) curve.point(p.x, p.y);
178
+ curve.lineEnd();
179
+ return out;
180
+ }
129
181
  function buildGroupContainers(groups) {
130
182
  const byLabel = new Map(groups.map((g) => [g.label, g]));
131
183
  const parent = /* @__PURE__ */ new Map();
@@ -218,6 +270,81 @@ function placeEdgeLabels(layout, opts) {
218
270
  obstacleCache.set(edgeIdx, out);
219
271
  return out;
220
272
  };
273
+ const curves = layout.edges.map((e) => {
274
+ const pts = sampleDrawnCurve(e.points);
275
+ let minX = Infinity;
276
+ let minY = Infinity;
277
+ let maxX = -Infinity;
278
+ let maxY = -Infinity;
279
+ for (const p of pts) {
280
+ if (p.x < minX) minX = p.x;
281
+ if (p.y < minY) minY = p.y;
282
+ if (p.x > maxX) maxX = p.x;
283
+ if (p.y > maxY) maxY = p.y;
284
+ }
285
+ return { pts, minX, minY, maxX, maxY };
286
+ });
287
+ const crossesOtherEdge = (edgeIdx, cx, cy, w, h) => {
288
+ const minX = cx - w / 2 - EDGE_CLEAR_PAD;
289
+ const minY = cy - h / 2 - EDGE_CLEAR_PAD;
290
+ const maxX = cx + w / 2 + EDGE_CLEAR_PAD;
291
+ const maxY = cy + h / 2 + EDGE_CLEAR_PAD;
292
+ for (let j = 0; j < curves.length; j++) {
293
+ if (j === edgeIdx) continue;
294
+ const c = curves[j];
295
+ if (c.maxX < minX || c.minX > maxX || c.maxY < minY || c.minY > maxY)
296
+ continue;
297
+ for (const p of c.pts)
298
+ if (p.x > minX && p.x < maxX && p.y > minY && p.y < maxY) return true;
299
+ }
300
+ return false;
301
+ };
302
+ const hasSubGroup = new Set(
303
+ (opts?.groups ?? []).flatMap((g) => g.parentGroup ? [g.parentGroup] : [])
304
+ );
305
+ const drawnTop = (g) => g.y - g.height / 2 - (hasSubGroup.has(g.label) ? GROUP_LABEL_ZONE : 0);
306
+ const titleRects = layout.groups.filter((g) => !g.collapsed).map((g) => {
307
+ const tw = measureText(g.label, GROUP_TITLE_FONT_SIZE, { bold: true });
308
+ const top = drawnTop(g);
309
+ return {
310
+ minX: g.x - tw / 2,
311
+ minY: top,
312
+ maxX: g.x + tw / 2,
313
+ maxY: top + GROUP_TITLE_DEPTH
314
+ };
315
+ });
316
+ const borderBands = (g) => {
317
+ const B = GROUP_BORDER_BAND;
318
+ const l = g.x - g.width / 2;
319
+ const r = g.x + g.width / 2;
320
+ const t = drawnTop(g);
321
+ const b = g.y + g.height / 2;
322
+ return [
323
+ { minX: l - B, minY: t - B, maxX: r + B, maxY: t + B },
324
+ { minX: l - B, minY: b - B, maxX: r + B, maxY: b + B },
325
+ { minX: l - B, minY: t - B, maxX: l + B, maxY: b + B },
326
+ { minX: r - B, minY: t - B, maxX: r + B, maxY: b + B }
327
+ ];
328
+ };
329
+ const preferredCache = /* @__PURE__ */ new Map();
330
+ const preferredFor = (edgeIdx) => {
331
+ const cached = preferredCache.get(edgeIdx);
332
+ if (cached !== void 0) return cached;
333
+ const e = layout.edges[edgeIdx];
334
+ const src = containers.get(e.source) ?? noContainers;
335
+ const tgt = containers.get(e.target) ?? noContainers;
336
+ const own = layout.groups.filter(
337
+ (g) => !g.collapsed && src.has(g.label) && tgt.has(g.label)
338
+ );
339
+ const out = [
340
+ ...obstaclesFor(edgeIdx),
341
+ ...titleRects,
342
+ ...own.flatMap(borderBands)
343
+ ];
344
+ preferredCache.set(edgeIdx, out);
345
+ return out;
346
+ };
347
+ const clearOfAll = (edgeIdx, cx, cy, w, h) => !overlapsAny(cx, cy, w, h, preferredFor(edgeIdx), BOX_CLEAR_PAD) && !crossesOtherEdge(edgeIdx, cx, cy, w, h);
221
348
  const boxes = [];
222
349
  layout.edges.forEach((e, idx) => {
223
350
  if (!e.label || e.points.length < 2) return;
@@ -238,10 +365,32 @@ function placeEdgeLabels(layout, opts) {
238
365
  });
239
366
  for (const box of boxes) {
240
367
  const obstacles = obstaclesFor(box.edgeIdx);
241
- if (!overlapsAny(box.cx, box.cy, box.w, box.h, obstacles, BOX_CLEAR_PAD))
242
- continue;
368
+ if (clearOfAll(box.edgeIdx, box.cx, box.cy, box.w, box.h)) continue;
243
369
  const e = layout.edges[box.edgeIdx];
244
- const clear = findClearPosition(box.w, box.h, e.points, obstacles, perpMax) ?? findClearPosition(box.w, box.h, e.points, baseObstacles, perpMax);
370
+ const { w, h } = box;
371
+ const mid = pointAtArcFraction(e.points, 0.5);
372
+ const side = (box.cx - mid.p.x) * mid.nx + (box.cy - mid.p.y) * mid.ny > 0 ? 1 : -1;
373
+ const ideal = findClearPosition(
374
+ e.points,
375
+ (x, y) => !clearOfAll(box.edgeIdx, x, y, w, h),
376
+ perpMax,
377
+ side
378
+ );
379
+ if (ideal) {
380
+ box.cx = ideal.x;
381
+ box.cy = ideal.y;
382
+ continue;
383
+ }
384
+ if (!overlapsAny(box.cx, box.cy, w, h, obstacles, BOX_CLEAR_PAD)) continue;
385
+ const clear = findClearPosition(
386
+ e.points,
387
+ (x, y) => overlapsAny(x, y, w, h, obstacles, BOX_CLEAR_PAD),
388
+ perpMax
389
+ ) ?? findClearPosition(
390
+ e.points,
391
+ (x, y) => overlapsAny(x, y, w, h, baseObstacles, BOX_CLEAR_PAD),
392
+ perpMax
393
+ );
245
394
  if (clear) {
246
395
  box.cx = clear.x;
247
396
  box.cy = clear.y;
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-5DH3KYFH.js";
10
10
  import {
11
11
  wrapDescriptionLines
12
- } from "./chunk-WMIKC5XO.js";
12
+ } from "./chunk-NPWVOFB3.js";
13
13
  import {
14
14
  measureText
15
15
  } from "./chunk-KAO7JL4I.js";