schematex 0.2.0 → 0.2.2

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 (106) hide show
  1. package/README.md +1 -1
  2. package/dist/browser.cjs +19 -19
  3. package/dist/browser.js +17 -17
  4. package/dist/{chunk-TIGP2OEJ.js → chunk-2VNMKOUO.js} +20 -5
  5. package/dist/chunk-2VNMKOUO.js.map +1 -0
  6. package/dist/{chunk-TPA36ULU.js → chunk-4KYW63IK.js} +3 -3
  7. package/dist/{chunk-TPA36ULU.js.map → chunk-4KYW63IK.js.map} +1 -1
  8. package/dist/{chunk-HKRYKEOV.cjs → chunk-4S2WILLW.cjs} +4 -4
  9. package/dist/{chunk-HKRYKEOV.cjs.map → chunk-4S2WILLW.cjs.map} +1 -1
  10. package/dist/{chunk-YO4GU6JX.js → chunk-5UV5VQ7J.js} +3 -3
  11. package/dist/{chunk-YO4GU6JX.js.map → chunk-5UV5VQ7J.js.map} +1 -1
  12. package/dist/{chunk-SPIW4VWP.js → chunk-5YYAYW67.js} +3 -3
  13. package/dist/{chunk-SPIW4VWP.js.map → chunk-5YYAYW67.js.map} +1 -1
  14. package/dist/{chunk-IQIJ6WW6.js → chunk-6YMQSTFF.js} +3 -3
  15. package/dist/{chunk-IQIJ6WW6.js.map → chunk-6YMQSTFF.js.map} +1 -1
  16. package/dist/{chunk-VP54YPOX.cjs → chunk-7HKXU7J2.cjs} +456 -162
  17. package/dist/chunk-7HKXU7J2.cjs.map +1 -0
  18. package/dist/{chunk-IY52OWPG.cjs → chunk-7IRT3LOY.cjs} +4 -4
  19. package/dist/{chunk-IY52OWPG.cjs.map → chunk-7IRT3LOY.cjs.map} +1 -1
  20. package/dist/{chunk-RQX53J6M.js → chunk-CJ2A3UEQ.js} +3 -3
  21. package/dist/{chunk-RQX53J6M.js.map → chunk-CJ2A3UEQ.js.map} +1 -1
  22. package/dist/{chunk-HAIBAF6J.cjs → chunk-CXHPP5BL.cjs} +4 -4
  23. package/dist/{chunk-HAIBAF6J.cjs.map → chunk-CXHPP5BL.cjs.map} +1 -1
  24. package/dist/{chunk-S6VPECM3.cjs → chunk-D7EHZFK4.cjs} +20 -5
  25. package/dist/chunk-D7EHZFK4.cjs.map +1 -0
  26. package/dist/{chunk-LKHWBDWZ.cjs → chunk-ISACNVFE.cjs} +4 -4
  27. package/dist/{chunk-LKHWBDWZ.cjs.map → chunk-ISACNVFE.cjs.map} +1 -1
  28. package/dist/{chunk-MXJ6FHSY.js → chunk-JDTB7IKL.js} +3 -3
  29. package/dist/{chunk-MXJ6FHSY.js.map → chunk-JDTB7IKL.js.map} +1 -1
  30. package/dist/{chunk-7WXAAVR3.js → chunk-LCR3KOJV.js} +3 -3
  31. package/dist/{chunk-7WXAAVR3.js.map → chunk-LCR3KOJV.js.map} +1 -1
  32. package/dist/{chunk-IMHR3S5H.cjs → chunk-LKOBOVNL.cjs} +5 -5
  33. package/dist/{chunk-IMHR3S5H.cjs.map → chunk-LKOBOVNL.cjs.map} +1 -1
  34. package/dist/{chunk-MRGS54WN.js → chunk-M5B2UUNW.js} +3 -3
  35. package/dist/{chunk-MRGS54WN.js.map → chunk-M5B2UUNW.js.map} +1 -1
  36. package/dist/{chunk-2OIW3MAE.js → chunk-PGALHQFF.js} +3 -3
  37. package/dist/{chunk-2OIW3MAE.js.map → chunk-PGALHQFF.js.map} +1 -1
  38. package/dist/{chunk-ULERCTGS.cjs → chunk-QR7VTCI4.cjs} +27 -27
  39. package/dist/chunk-QR7VTCI4.cjs.map +1 -0
  40. package/dist/{chunk-3M7QWADF.cjs → chunk-QSQX77S2.cjs} +4 -4
  41. package/dist/{chunk-3M7QWADF.cjs.map → chunk-QSQX77S2.cjs.map} +1 -1
  42. package/dist/{chunk-M6AMNXQ7.js → chunk-UUPYTUGR.js} +438 -144
  43. package/dist/chunk-UUPYTUGR.js.map +1 -0
  44. package/dist/{chunk-4HPT4BOI.cjs → chunk-WYFXOXVK.cjs} +4 -4
  45. package/dist/{chunk-4HPT4BOI.cjs.map → chunk-WYFXOXVK.cjs.map} +1 -1
  46. package/dist/{chunk-A74ZCP5I.js → chunk-X2BQKXMA.js} +27 -27
  47. package/dist/chunk-X2BQKXMA.js.map +1 -0
  48. package/dist/{chunk-YKO7DY2F.cjs → chunk-X7RPFTTR.cjs} +13 -13
  49. package/dist/{chunk-YKO7DY2F.cjs.map → chunk-X7RPFTTR.cjs.map} +1 -1
  50. package/dist/{chunk-ZGKEFVJQ.cjs → chunk-XHZ7GXP2.cjs} +12 -12
  51. package/dist/{chunk-ZGKEFVJQ.cjs.map → chunk-XHZ7GXP2.cjs.map} +1 -1
  52. package/dist/{chunk-AMP2FFES.cjs → chunk-XVCAOGFL.cjs} +10 -10
  53. package/dist/{chunk-AMP2FFES.cjs.map → chunk-XVCAOGFL.cjs.map} +1 -1
  54. package/dist/{chunk-HLYA4QBB.js → chunk-YN467EEQ.js} +3 -3
  55. package/dist/{chunk-HLYA4QBB.js.map → chunk-YN467EEQ.js.map} +1 -1
  56. package/dist/{chunk-4TS5NB7L.js → chunk-YQANC7HQ.js} +3 -3
  57. package/dist/{chunk-4TS5NB7L.js.map → chunk-YQANC7HQ.js.map} +1 -1
  58. package/dist/{chunk-DTMCQXXC.cjs → chunk-YXIIWLLB.cjs} +12 -12
  59. package/dist/{chunk-DTMCQXXC.cjs.map → chunk-YXIIWLLB.cjs.map} +1 -1
  60. package/dist/{chunk-JZGFSRVT.js → chunk-Z3WOHHG3.js} +3 -3
  61. package/dist/{chunk-JZGFSRVT.js.map → chunk-Z3WOHHG3.js.map} +1 -1
  62. package/dist/{chunk-CEV3GZA3.cjs → chunk-Z63XPA2V.cjs} +11 -11
  63. package/dist/{chunk-CEV3GZA3.cjs.map → chunk-Z63XPA2V.cjs.map} +1 -1
  64. package/dist/{chunk-PIQG2Z5N.cjs → chunk-ZNOD4VZT.cjs} +4 -4
  65. package/dist/{chunk-PIQG2Z5N.cjs.map → chunk-ZNOD4VZT.cjs.map} +1 -1
  66. package/dist/{chunk-L6IHSTPP.js → chunk-ZNZIL244.js} +3 -3
  67. package/dist/{chunk-L6IHSTPP.js.map → chunk-ZNZIL244.js.map} +1 -1
  68. package/dist/diagrams/circuit/index.cjs +8 -8
  69. package/dist/diagrams/circuit/index.js +2 -2
  70. package/dist/diagrams/ecomap/index.cjs +7 -7
  71. package/dist/diagrams/ecomap/index.js +2 -2
  72. package/dist/diagrams/entity/index.cjs +6 -6
  73. package/dist/diagrams/entity/index.js +2 -2
  74. package/dist/diagrams/fishbone/index.cjs +8 -8
  75. package/dist/diagrams/fishbone/index.js +2 -2
  76. package/dist/diagrams/flowchart/index.cjs +8 -8
  77. package/dist/diagrams/flowchart/index.js +2 -2
  78. package/dist/diagrams/genogram/index.cjs +9 -9
  79. package/dist/diagrams/genogram/index.js +2 -2
  80. package/dist/diagrams/ladder/index.cjs +6 -6
  81. package/dist/diagrams/ladder/index.js +2 -2
  82. package/dist/diagrams/logic/index.cjs +6 -6
  83. package/dist/diagrams/logic/index.js +2 -2
  84. package/dist/diagrams/orgchart/index.cjs +7 -7
  85. package/dist/diagrams/orgchart/index.js +2 -2
  86. package/dist/diagrams/pedigree/index.cjs +7 -7
  87. package/dist/diagrams/pedigree/index.js +2 -2
  88. package/dist/diagrams/phylo/index.cjs +7 -7
  89. package/dist/diagrams/phylo/index.js +2 -2
  90. package/dist/diagrams/sld/index.cjs +6 -6
  91. package/dist/diagrams/sld/index.js +2 -2
  92. package/dist/diagrams/sociogram/index.cjs +6 -6
  93. package/dist/diagrams/sociogram/index.js +2 -2
  94. package/dist/diagrams/venn/index.cjs +9 -9
  95. package/dist/diagrams/venn/index.js +2 -2
  96. package/dist/index.cjs +45 -45
  97. package/dist/index.js +16 -16
  98. package/dist/react.cjs +17 -17
  99. package/dist/react.js +16 -16
  100. package/package.json +4 -3
  101. package/dist/chunk-A74ZCP5I.js.map +0 -1
  102. package/dist/chunk-M6AMNXQ7.js.map +0 -1
  103. package/dist/chunk-S6VPECM3.cjs.map +0 -1
  104. package/dist/chunk-TIGP2OEJ.js.map +0 -1
  105. package/dist/chunk-ULERCTGS.cjs.map +0 -1
  106. package/dist/chunk-VP54YPOX.cjs.map +0 -1
@@ -1,20 +1,20 @@
1
- import { orgchart } from './chunk-7WXAAVR3.js';
2
- import { circuit } from './chunk-2OIW3MAE.js';
1
+ import { orgchart } from './chunk-LCR3KOJV.js';
2
+ import { circuit } from './chunk-PGALHQFF.js';
3
3
  import { blockdiagram } from './chunk-5SH5NUDW.js';
4
- import { ladder } from './chunk-L6IHSTPP.js';
5
- import { sld } from './chunk-A74ZCP5I.js';
6
- import { entity } from './chunk-MRGS54WN.js';
7
- import { fishbone } from './chunk-IQIJ6WW6.js';
8
- import { venn } from './chunk-MXJ6FHSY.js';
9
- import { flowchart } from './chunk-JZGFSRVT.js';
10
- import { genogram } from './chunk-HLYA4QBB.js';
11
- import { ecomap } from './chunk-RQX53J6M.js';
12
- import { pedigree } from './chunk-TPA36ULU.js';
13
- import { phylo } from './chunk-4TS5NB7L.js';
14
- import { sociogram } from './chunk-YO4GU6JX.js';
4
+ import { ladder } from './chunk-ZNZIL244.js';
5
+ import { sld } from './chunk-X2BQKXMA.js';
6
+ import { entity } from './chunk-M5B2UUNW.js';
7
+ import { fishbone } from './chunk-6YMQSTFF.js';
8
+ import { venn } from './chunk-JDTB7IKL.js';
9
+ import { flowchart } from './chunk-Z3WOHHG3.js';
10
+ import { genogram } from './chunk-YN467EEQ.js';
11
+ import { ecomap } from './chunk-CJ2A3UEQ.js';
12
+ import { pedigree } from './chunk-4KYW63IK.js';
13
+ import { phylo } from './chunk-YQANC7HQ.js';
14
+ import { sociogram } from './chunk-5UV5VQ7J.js';
15
15
  import { timing } from './chunk-GEPBET4L.js';
16
- import { logic } from './chunk-SPIW4VWP.js';
17
- import { resolveBaseTheme, resolveTimelineTheme, cssCustomProperties, resolveMindmapTheme } from './chunk-TIGP2OEJ.js';
16
+ import { logic } from './chunk-5YYAYW67.js';
17
+ import { resolveBaseTheme, resolveTimelineTheme, cssCustomProperties, resolveMindmapTheme } from './chunk-2VNMKOUO.js';
18
18
  import { title, desc, el, text, path, rect, group, svgRoot, escapeXml, defs, circle, polygon, line } from './chunk-KLJEK547.js';
19
19
 
20
20
  // src/diagrams/decisiontree/parser.ts
@@ -2618,8 +2618,181 @@ var timeline = {
2618
2618
  }
2619
2619
  };
2620
2620
 
2621
+ // src/diagrams/mindmap/inline.ts
2622
+ var RE_TASK = /^\[( |x|X)\]\s+(.*)$/;
2623
+ function tokenizeInline(raw) {
2624
+ const tokens = [];
2625
+ let text2 = raw;
2626
+ const task = text2.match(RE_TASK);
2627
+ if (task) {
2628
+ tokens.push({ kind: "checkbox", checked: task[1].toLowerCase() === "x" });
2629
+ text2 = task[2];
2630
+ }
2631
+ parseInto(text2, tokens, { bold: false, italic: false });
2632
+ return tokens;
2633
+ }
2634
+ function parseInto(src, out, style) {
2635
+ let i = 0;
2636
+ let plain = "";
2637
+ const flushPlain = () => {
2638
+ if (plain.length === 0) return;
2639
+ out.push({ kind: "text", value: plain, bold: style.bold || void 0, italic: style.italic || void 0 });
2640
+ plain = "";
2641
+ };
2642
+ while (i < src.length) {
2643
+ const ch = src[i];
2644
+ if (ch === "`") {
2645
+ const end = src.indexOf("`", i + 1);
2646
+ if (end > i) {
2647
+ flushPlain();
2648
+ out.push({ kind: "code", value: src.slice(i + 1, end) });
2649
+ i = end + 1;
2650
+ continue;
2651
+ }
2652
+ }
2653
+ if (ch === "[") {
2654
+ const closeBracket = findUnescaped(src, "]", i + 1);
2655
+ if (closeBracket > 0 && src[closeBracket + 1] === "(") {
2656
+ const closeParen = findUnescaped(src, ")", closeBracket + 2);
2657
+ if (closeParen > 0) {
2658
+ flushPlain();
2659
+ const inner = [];
2660
+ parseInto(src.slice(i + 1, closeBracket), inner, style);
2661
+ out.push({ kind: "link", href: src.slice(closeBracket + 2, closeParen), value: inner });
2662
+ i = closeParen + 1;
2663
+ continue;
2664
+ }
2665
+ }
2666
+ }
2667
+ if (ch === "*" && src[i + 1] === "*") {
2668
+ const end = src.indexOf("**", i + 2);
2669
+ if (end > i) {
2670
+ flushPlain();
2671
+ parseInto(src.slice(i + 2, end), out, { ...style, bold: true });
2672
+ i = end + 2;
2673
+ continue;
2674
+ }
2675
+ }
2676
+ if (ch === "*") {
2677
+ const end = src.indexOf("*", i + 1);
2678
+ if (end > i && src[end + 1] !== "*") {
2679
+ flushPlain();
2680
+ parseInto(src.slice(i + 1, end), out, { ...style, italic: true });
2681
+ i = end + 1;
2682
+ continue;
2683
+ }
2684
+ }
2685
+ plain += ch;
2686
+ i++;
2687
+ }
2688
+ flushPlain();
2689
+ }
2690
+ function findUnescaped(s, ch, from) {
2691
+ for (let i = from; i < s.length; i++) {
2692
+ if (s[i] === "\\") {
2693
+ i++;
2694
+ continue;
2695
+ }
2696
+ if (s[i] === ch) return i;
2697
+ }
2698
+ return -1;
2699
+ }
2700
+ var EM_REGULAR = 0.58;
2701
+ var EM_BOLD = 0.62;
2702
+ var EM_CODE = 0.62;
2703
+ var CHECKBOX_EM = 1.05;
2704
+ function measureTokens(tokens, fontSize) {
2705
+ let w = 0;
2706
+ for (const t of tokens) {
2707
+ w += tokenWidth(t, fontSize);
2708
+ }
2709
+ return w;
2710
+ }
2711
+ function tokenWidth(t, fs) {
2712
+ switch (t.kind) {
2713
+ case "text": {
2714
+ const em = t.bold ? EM_BOLD : EM_REGULAR;
2715
+ return t.value.length * fs * em;
2716
+ }
2717
+ case "code":
2718
+ return t.value.length * fs * EM_CODE + 4;
2719
+ case "link":
2720
+ return measureTokens(t.value, fs);
2721
+ case "checkbox":
2722
+ return fs * CHECKBOX_EM;
2723
+ }
2724
+ }
2725
+ function tokensToPlainText(tokens) {
2726
+ let out = "";
2727
+ for (const t of tokens) {
2728
+ switch (t.kind) {
2729
+ case "text":
2730
+ case "code":
2731
+ out += t.value;
2732
+ break;
2733
+ case "link":
2734
+ out += tokensToPlainText(t.value);
2735
+ break;
2736
+ case "checkbox":
2737
+ out += t.checked ? "[x] " : "[ ] ";
2738
+ break;
2739
+ }
2740
+ }
2741
+ return out;
2742
+ }
2743
+ function wrapTokens(tokens, maxWidth, fontSize) {
2744
+ const lines = [];
2745
+ let line2 = [];
2746
+ let lineW = 0;
2747
+ const pushLine = () => {
2748
+ lines.push({ tokens: line2, width: lineW });
2749
+ line2 = [];
2750
+ lineW = 0;
2751
+ };
2752
+ const pushAtomic = (t, w) => {
2753
+ if (lineW > 0 && lineW + w > maxWidth) pushLine();
2754
+ line2.push(t);
2755
+ lineW += w;
2756
+ };
2757
+ for (const t of tokens) {
2758
+ if (t.kind === "text") {
2759
+ const words = splitWordsWithTrailingSpace(t.value);
2760
+ for (const w of words) {
2761
+ const wt = { kind: "text", value: w, bold: t.bold, italic: t.italic };
2762
+ const ww = tokenWidth(wt, fontSize);
2763
+ if (lineW > 0 && lineW + ww > maxWidth) {
2764
+ pushLine();
2765
+ const trimmed = w.replace(/^ +/, "");
2766
+ if (trimmed.length === 0) continue;
2767
+ const tt = { kind: "text", value: trimmed, bold: t.bold, italic: t.italic };
2768
+ line2.push(tt);
2769
+ lineW = tokenWidth(tt, fontSize);
2770
+ } else {
2771
+ line2.push(wt);
2772
+ lineW += ww;
2773
+ }
2774
+ }
2775
+ } else {
2776
+ pushAtomic(t, tokenWidth(t, fontSize));
2777
+ }
2778
+ }
2779
+ pushLine();
2780
+ return lines;
2781
+ }
2782
+ function splitWordsWithTrailingSpace(s) {
2783
+ if (s.length === 0) return [];
2784
+ const out = [];
2785
+ const re = /(\S+\s*)|(\s+)/g;
2786
+ let m;
2787
+ while ((m = re.exec(s)) !== null) {
2788
+ out.push(m[0]);
2789
+ }
2790
+ return out.length > 0 ? out : [s];
2791
+ }
2792
+
2621
2793
  // src/diagrams/mindmap/parser.ts
2622
2794
  var VALID_STYLES = ["map", "logic-right"];
2795
+ var DEFAULT_MAX_LABEL_WIDTH = 240;
2623
2796
  function parseDirective(line2, out) {
2624
2797
  const body = line2.replace(/^%%\s*/, "").trim();
2625
2798
  const idx = body.indexOf(":");
@@ -2630,12 +2803,18 @@ function parseDirective(line2, out) {
2630
2803
  out.style = val;
2631
2804
  } else if (key === "theme") {
2632
2805
  out.themeOverride = val;
2806
+ } else if (key === "maxlabelwidth") {
2807
+ const n = Number(val);
2808
+ if (Number.isFinite(n) && n >= 80 && n <= 1e3) out.maxLabelWidth = n;
2633
2809
  }
2634
2810
  }
2811
+ function makeNode(id, label, depth) {
2812
+ return { id, label, tokens: tokenizeInline(label), depth, children: [] };
2813
+ }
2635
2814
  function parseMindmap(text2) {
2636
2815
  const lines = text2.split(/\r?\n/);
2637
2816
  if (lines[0]?.trim().toLowerCase() === "mindmap") lines.shift();
2638
- const directives = { style: "map" };
2817
+ const directives = { style: "map", maxLabelWidth: DEFAULT_MAX_LABEL_WIDTH };
2639
2818
  let root = null;
2640
2819
  let idCounter2 = 0;
2641
2820
  const nextId2 = () => `n${idCounter2++}`;
@@ -2661,7 +2840,7 @@ function parseMindmap(text2) {
2661
2840
  if (heading) {
2662
2841
  const depth = heading[1].length - 1;
2663
2842
  const label = heading[2].trim();
2664
- const node = { id: nextId2(), label, depth, children: [] };
2843
+ const node = makeNode(nextId2(), label, depth);
2665
2844
  if (depth === 0) {
2666
2845
  if (root) throw new Error("Mindmap: multiple `#` center nodes not allowed");
2667
2846
  root = node;
@@ -2678,7 +2857,7 @@ function parseMindmap(text2) {
2678
2857
  const indent = bullet[1].length;
2679
2858
  const depth = lastHeadingDepth + 1 + Math.floor(indent / 2);
2680
2859
  const label = bullet[2].trim();
2681
- const node = { id: nextId2(), label, depth, children: [] };
2860
+ const node = makeNode(nextId2(), label, depth);
2682
2861
  attach(node, depth);
2683
2862
  continue;
2684
2863
  }
@@ -2687,7 +2866,8 @@ function parseMindmap(text2) {
2687
2866
  const ast = {
2688
2867
  type: "mindmap",
2689
2868
  style: directives.style,
2690
- root
2869
+ root,
2870
+ maxLabelWidth: directives.maxLabelWidth
2691
2871
  };
2692
2872
  if (directives.themeOverride) ast.themeOverride = directives.themeOverride;
2693
2873
  return ast;
@@ -2695,10 +2875,10 @@ function parseMindmap(text2) {
2695
2875
 
2696
2876
  // src/diagrams/mindmap/layout.ts
2697
2877
  var PADDING = 40;
2698
- var SIBLING_GAP = 20;
2878
+ var SIBLING_GAP = 18;
2699
2879
  var MAIN_GAP = 44;
2700
- var ROOT_CAPSULE_PAD_X = 10;
2701
- var ROOT_CAPSULE_PAD_Y = 10;
2880
+ var UNDERLINE_GAP = 4;
2881
+ var LINE_GAP = 4;
2702
2882
  function bezierGapFor(childDepth) {
2703
2883
  if (childDepth <= 1) return 90;
2704
2884
  if (childDepth === 2) return 60;
@@ -2712,47 +2892,68 @@ function fontSizeOf(depth) {
2712
2892
  if (depth === 1) return FONT_MAIN;
2713
2893
  return FONT_SUB;
2714
2894
  }
2715
- function estimateLabelWidth2(label, depth) {
2716
- return Math.max(32, label.length * fontSizeOf(depth) * 0.58);
2895
+ function lineHeightOf(fs) {
2896
+ return fs + LINE_GAP;
2897
+ }
2898
+ function widthBudget(depth, maxLabelWidth) {
2899
+ if (depth === 0) return maxLabelWidth * 1.5;
2900
+ return maxLabelWidth;
2717
2901
  }
2718
- function rowHeightOf(depth) {
2719
- return fontSizeOf(depth) + 14;
2902
+ function measureLabel(node, maxWidth) {
2903
+ const fs = fontSizeOf(node.depth);
2904
+ const raw = measureTokens(node.tokens, fs);
2905
+ let lines;
2906
+ if (raw <= maxWidth) {
2907
+ lines = [{ tokens: node.tokens.slice(), width: raw }];
2908
+ } else {
2909
+ lines = wrapTokens(node.tokens, maxWidth, fs);
2910
+ }
2911
+ let maxW = 0;
2912
+ for (const ln of lines) if (ln.width > maxW) maxW = ln.width;
2913
+ const lh = lineHeightOf(fs);
2914
+ const height = lines.length * lh + UNDERLINE_GAP;
2915
+ return { lines, width: Math.max(32, maxW), height };
2720
2916
  }
2721
- function computeColumns(subtreeRoots, firstColStartX) {
2917
+ function computeMaxLW(subtreeRoots, maxLabelWidth) {
2722
2918
  const maxLW = [];
2723
2919
  const walk = (n) => {
2724
- const lw = estimateLabelWidth2(n.label, n.depth);
2725
- if (maxLW[n.depth] === void 0 || lw > maxLW[n.depth]) maxLW[n.depth] = lw;
2920
+ const m = measureLabel(n, widthBudget(n.depth, maxLabelWidth));
2921
+ if (maxLW[n.depth] === void 0 || m.width > maxLW[n.depth]) maxLW[n.depth] = m.width;
2726
2922
  for (const c of n.children) walk(c);
2727
2923
  };
2728
2924
  for (const r of subtreeRoots) walk(r);
2925
+ return maxLW;
2926
+ }
2927
+ function buildColumns(maxLW, firstColStartX, rootDepth) {
2729
2928
  const center = [];
2730
- if (subtreeRoots.length === 0) return { center };
2731
- const rootDepth = subtreeRoots[0].depth;
2929
+ if (maxLW[rootDepth] === void 0) return { center };
2732
2930
  let slotLeft = firstColStartX;
2733
2931
  center[rootDepth] = slotLeft + maxLW[rootDepth] / 2;
2734
2932
  for (let d = rootDepth + 1; d < maxLW.length; d++) {
2735
2933
  slotLeft = slotLeft + maxLW[d - 1] + bezierGapFor(d);
2736
- center[d] = slotLeft + maxLW[d] / 2;
2934
+ center[d] = slotLeft + (maxLW[d] ?? 0) / 2;
2737
2935
  }
2738
2936
  return { center };
2739
2937
  }
2740
- function tidyRight(node, yTop, branchIdx, columns, out) {
2741
- const rowH = rowHeightOf(node.depth);
2742
- const lw = estimateLabelWidth2(node.label, node.depth);
2938
+ function tidyRight(node, yTop, branchIdx, columns, maxLabelWidth, maxLW, out) {
2939
+ const m = measureLabel(node, widthBudget(node.depth, maxLabelWidth));
2743
2940
  const x = columns.center[node.depth];
2941
+ const fs = fontSizeOf(node.depth);
2942
+ const labelWidth = Math.max(m.width, maxLW[node.depth] ?? m.width);
2744
2943
  if (node.children.length === 0) {
2745
2944
  const ln2 = {
2746
2945
  node,
2747
2946
  x,
2748
- y: yTop + rowH / 2,
2947
+ y: yTop + m.height / 2,
2749
2948
  side: "right",
2750
2949
  branchIndex: branchIdx,
2751
- labelWidth: lw,
2752
- labelHeight: rowH
2950
+ labelWidth,
2951
+ labelHeight: m.height,
2952
+ fontSize: fs,
2953
+ lines: m.lines
2753
2954
  };
2754
2955
  out.push(ln2);
2755
- return { layoutNode: ln2, height: rowH };
2956
+ return { layoutNode: ln2, height: m.height };
2756
2957
  }
2757
2958
  let cursor = yTop;
2758
2959
  const childLayouts = [];
@@ -2763,12 +2964,14 @@ function tidyRight(node, yTop, branchIdx, columns, out) {
2763
2964
  cursor,
2764
2965
  branchIdx,
2765
2966
  columns,
2967
+ maxLabelWidth,
2968
+ maxLW,
2766
2969
  out
2767
2970
  );
2768
2971
  childLayouts.push(cln);
2769
2972
  cursor += height;
2770
2973
  }
2771
- const totalH = Math.max(rowH, cursor - yTop);
2974
+ const totalH = Math.max(m.height, cursor - yTop);
2772
2975
  const firstY = childLayouts[0].y;
2773
2976
  const lastY = childLayouts[childLayouts.length - 1].y;
2774
2977
  const parentY = (firstY + lastY) / 2;
@@ -2778,8 +2981,10 @@ function tidyRight(node, yTop, branchIdx, columns, out) {
2778
2981
  y: parentY,
2779
2982
  side: "right",
2780
2983
  branchIndex: branchIdx,
2781
- labelWidth: lw,
2782
- labelHeight: rowH
2984
+ labelWidth,
2985
+ labelHeight: m.height,
2986
+ fontSize: fs,
2987
+ lines: m.lines
2783
2988
  };
2784
2989
  out.push(ln);
2785
2990
  return { layoutNode: ln, height: totalH };
@@ -2794,7 +2999,15 @@ function bezierH(x1, y1, x2, y2) {
2794
2999
  return `M ${x1.toFixed(1)} ${y1.toFixed(1)} C ${(x1 + k).toFixed(1)} ${y1.toFixed(1)}, ${(x2 - k).toFixed(1)} ${y2.toFixed(1)}, ${x2.toFixed(1)} ${y2.toFixed(1)}`;
2795
3000
  }
2796
3001
  function edgeWidthFor(depth) {
2797
- return depth <= 1 ? 2.2 : 1.4;
3002
+ if (depth <= 1) return 2.2;
3003
+ if (depth === 2) return 1.6;
3004
+ return 1.2;
3005
+ }
3006
+ function underlineWidthFor(depth) {
3007
+ if (depth === 0) return 2.4;
3008
+ if (depth === 1) return 2.2;
3009
+ if (depth === 2) return 1.6;
3010
+ return 1.2;
2798
3011
  }
2799
3012
  function normalize(nodes) {
2800
3013
  let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
@@ -2805,8 +3018,8 @@ function normalize(nodes) {
2805
3018
  const rightX = n.x + lw / 2;
2806
3019
  minX = Math.min(minX, leftX);
2807
3020
  maxX = Math.max(maxX, rightX);
2808
- minY = Math.min(minY, n.y - lh);
2809
- maxY = Math.max(maxY, n.y + lh);
3021
+ minY = Math.min(minY, n.y - lh / 2);
3022
+ maxY = Math.max(maxY, n.y + lh / 2);
2810
3023
  }
2811
3024
  const dx = PADDING - minX;
2812
3025
  const dy = PADDING - minY;
@@ -2816,10 +3029,14 @@ function normalize(nodes) {
2816
3029
  }
2817
3030
  return { width: maxX - minX + PADDING * 2, height: maxY - minY + PADDING * 2 };
2818
3031
  }
3032
+ function underlineY(n) {
3033
+ return n.y + n.labelHeight / 2 - UNDERLINE_GAP / 2;
3034
+ }
2819
3035
  function buildEdges(root, byId) {
2820
3036
  const edges = [];
2821
3037
  const walk = (parent) => {
2822
3038
  const pln = byId.get(parent.id);
3039
+ const pUY = underlineY(pln);
2823
3040
  for (const c of parent.children) {
2824
3041
  const cln = byId.get(c.id);
2825
3042
  let fromX;
@@ -2833,7 +3050,7 @@ function buildEdges(root, byId) {
2833
3050
  edges.push({
2834
3051
  from: parent.id,
2835
3052
  to: c.id,
2836
- path: bezierH(fromX, pln.y, toX, cln.y),
3053
+ path: bezierH(fromX, pUY, toX, underlineY(cln)),
2837
3054
  color: "",
2838
3055
  width: edgeWidthFor(c.depth)
2839
3056
  });
@@ -2850,24 +3067,23 @@ function layoutMap(ast) {
2850
3067
  const rightMains = mains.slice(0, rightCount);
2851
3068
  const leftMains = mains.slice(rightCount);
2852
3069
  const nodes = [];
2853
- const rootLabelW = estimateLabelWidth2(root.label, 0);
2854
- const rootCapsuleW = rootLabelW + ROOT_CAPSULE_PAD_X * 2;
2855
- const rootCapsuleH = rowHeightOf(0) + ROOT_CAPSULE_PAD_Y;
2856
- const firstColLeft = rootCapsuleW / 2 + bezierGapFor(1);
2857
- const rightCols = computeColumns(rightMains, firstColLeft);
3070
+ const mw = ast.maxLabelWidth;
3071
+ const rootM = measureLabel(root, widthBudget(0, mw));
3072
+ const firstColLeft = rootM.width / 2 + bezierGapFor(1);
3073
+ const maxLW = computeMaxLW([...rightMains, ...leftMains], mw);
3074
+ const cols = buildColumns(maxLW, firstColLeft, 1);
2858
3075
  let rightCursor = 0;
2859
3076
  for (let i = 0; i < rightMains.length; i++) {
2860
3077
  if (i > 0) rightCursor += MAIN_GAP;
2861
- const { height: height2 } = tidyRight(rightMains[i], rightCursor, i, rightCols, nodes);
3078
+ const { height: height2 } = tidyRight(rightMains[i], rightCursor, i, cols, mw, maxLW, nodes);
2862
3079
  rightCursor += height2;
2863
3080
  }
2864
3081
  const rightHeight = rightCursor;
2865
- const leftCols = computeColumns(leftMains, firstColLeft);
2866
3082
  const leftStart = nodes.length;
2867
3083
  let leftCursor = 0;
2868
3084
  for (let i = 0; i < leftMains.length; i++) {
2869
3085
  if (i > 0) leftCursor += MAIN_GAP;
2870
- const { height: height2 } = tidyRight(leftMains[i], leftCursor, rightCount + i, leftCols, nodes);
3086
+ const { height: height2 } = tidyRight(leftMains[i], leftCursor, rightCount + i, cols, mw, maxLW, nodes);
2871
3087
  leftCursor += height2;
2872
3088
  }
2873
3089
  const leftHeight = leftCursor;
@@ -2882,8 +3098,10 @@ function layoutMap(ast) {
2882
3098
  y: rootY,
2883
3099
  side: "center",
2884
3100
  branchIndex: -1,
2885
- labelWidth: rootCapsuleW,
2886
- labelHeight: rootCapsuleH
3101
+ labelWidth: rootM.width,
3102
+ labelHeight: rootM.height,
3103
+ fontSize: fontSizeOf(0),
3104
+ lines: rootM.lines
2887
3105
  };
2888
3106
  nodes.push(rootNode);
2889
3107
  const { width, height } = normalize(nodes);
@@ -2894,15 +3112,15 @@ function layoutMap(ast) {
2894
3112
  function layoutLogicRight(ast) {
2895
3113
  const root = ast.root;
2896
3114
  const nodes = [];
2897
- const rootLabelW = estimateLabelWidth2(root.label, 0);
2898
- const rootCapsuleW = rootLabelW + ROOT_CAPSULE_PAD_X * 2;
2899
- const rootCapsuleH = rowHeightOf(0) + ROOT_CAPSULE_PAD_Y;
2900
- const firstColLeft = rootCapsuleW / 2 + bezierGapFor(1);
2901
- const cols = computeColumns(root.children, firstColLeft);
3115
+ const mw = ast.maxLabelWidth;
3116
+ const rootM = measureLabel(root, widthBudget(0, mw));
3117
+ const firstColLeft = rootM.width / 2 + bezierGapFor(1);
3118
+ const maxLW = computeMaxLW(root.children, mw);
3119
+ const cols = buildColumns(maxLW, firstColLeft, 1);
2902
3120
  let cursor = 0;
2903
3121
  for (let i = 0; i < root.children.length; i++) {
2904
3122
  if (i > 0) cursor += MAIN_GAP;
2905
- const { height: height2 } = tidyRight(root.children[i], cursor, i, cols, nodes);
3123
+ const { height: height2 } = tidyRight(root.children[i], cursor, i, cols, mw, maxLW, nodes);
2906
3124
  cursor += height2;
2907
3125
  }
2908
3126
  const totalHeight = cursor;
@@ -2912,8 +3130,10 @@ function layoutLogicRight(ast) {
2912
3130
  y: totalHeight / 2,
2913
3131
  side: "center",
2914
3132
  branchIndex: -1,
2915
- labelWidth: rootCapsuleW,
2916
- labelHeight: rootCapsuleH
3133
+ labelWidth: rootM.width,
3134
+ labelHeight: rootM.height,
3135
+ fontSize: fontSizeOf(0),
3136
+ lines: rootM.lines
2917
3137
  };
2918
3138
  nodes.push(rootNode);
2919
3139
  const { width, height } = normalize(nodes);
@@ -2928,91 +3148,170 @@ function layoutMindmap(ast) {
2928
3148
  }
2929
3149
 
2930
3150
  // src/diagrams/mindmap/renderer.ts
2931
- var UNDERLINE_MAIN = 2.2;
2932
- var UNDERLINE_MAIN_MONO = 1.5;
3151
+ function strokeScale(theme) {
3152
+ return theme.branchPalette.length <= 1 ? 0.7 : 1;
3153
+ }
2933
3154
  function paletteColor(theme, branchIndex) {
2934
3155
  if (branchIndex < 0) return theme.centralFill;
2935
3156
  return theme.branchPalette[branchIndex % theme.branchPalette.length];
2936
3157
  }
2937
- function underlineMain(theme) {
2938
- return theme.branchPalette.length <= 1 ? UNDERLINE_MAIN_MONO : UNDERLINE_MAIN;
3158
+ function renderLine(line2, cx, cy, fontSize, fontFamily, fontWeight, theme) {
3159
+ const leftX = cx - line2.width / 2;
3160
+ const baselineY = cy + fontSize * 0.35;
3161
+ const tspans = [];
3162
+ const decorations = [];
3163
+ let cursor = leftX;
3164
+ const emit = (tok, inheritedHref) => {
3165
+ switch (tok.kind) {
3166
+ case "text": {
3167
+ const w = measureToken(tok, fontSize);
3168
+ tspans.push(
3169
+ tspan({
3170
+ x: cursor,
3171
+ y: baselineY,
3172
+ fill: inheritedHref ? theme.linkColor : theme.text,
3173
+ "font-weight": tok.bold ? 700 : fontWeight,
3174
+ "font-style": tok.italic ? "italic" : void 0,
3175
+ "text-decoration": inheritedHref ? "underline" : void 0
3176
+ }, tok.value)
3177
+ );
3178
+ cursor += w;
3179
+ break;
3180
+ }
3181
+ case "code": {
3182
+ const w = measureToken(tok, fontSize);
3183
+ decorations.push(rect({
3184
+ x: cursor,
3185
+ y: cy - fontSize * 0.6,
3186
+ width: w,
3187
+ height: fontSize * 1.2,
3188
+ rx: 3,
3189
+ ry: 3,
3190
+ fill: theme.codeBg
3191
+ }));
3192
+ tspans.push(
3193
+ tspan({
3194
+ x: cursor + 2,
3195
+ y: baselineY,
3196
+ fill: theme.codeFg,
3197
+ "font-family": "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",
3198
+ "font-size": fontSize * 0.92
3199
+ }, tok.value)
3200
+ );
3201
+ cursor += w;
3202
+ break;
3203
+ }
3204
+ case "link": {
3205
+ const aStart = `<a href="${escapeXml(tok.href)}" target="_blank" rel="noopener">`;
3206
+ const innerStart = tspans.length;
3207
+ for (const inner of tok.value) emit(inner, tok.href);
3208
+ const innerTspans = tspans.splice(innerStart).join("");
3209
+ tspans.push(aStart + innerTspans + "</a>");
3210
+ break;
3211
+ }
3212
+ case "checkbox": {
3213
+ const size = fontSize * 0.85;
3214
+ const boxX = cursor;
3215
+ const boxY = cy - size / 2;
3216
+ decorations.push(rect({
3217
+ x: boxX,
3218
+ y: boxY,
3219
+ width: size,
3220
+ height: size,
3221
+ rx: 2,
3222
+ ry: 2,
3223
+ fill: tok.checked ? theme.checkboxFill : "none",
3224
+ stroke: tok.checked ? theme.checkboxFill : theme.checkboxStroke,
3225
+ "stroke-width": 1.5
3226
+ }));
3227
+ if (tok.checked) {
3228
+ const p = `M ${(boxX + size * 0.2).toFixed(1)} ${(boxY + size * 0.5).toFixed(1)} L ${(boxX + size * 0.42).toFixed(1)} ${(boxY + size * 0.72).toFixed(1)} L ${(boxX + size * 0.82).toFixed(1)} ${(boxY + size * 0.28).toFixed(1)}`;
3229
+ decorations.push(path({
3230
+ d: p,
3231
+ fill: "none",
3232
+ stroke: "#ffffff",
3233
+ "stroke-width": 2,
3234
+ "stroke-linecap": "round",
3235
+ "stroke-linejoin": "round"
3236
+ }));
3237
+ }
3238
+ cursor += size + fontSize * 0.25;
3239
+ break;
3240
+ }
3241
+ }
3242
+ };
3243
+ for (const tok of line2.tokens) emit(tok);
3244
+ const textElement = el("text", {
3245
+ "font-family": fontFamily,
3246
+ "font-size": fontSize,
3247
+ "font-weight": fontWeight
3248
+ }, tspans.join(""));
3249
+ return { textElement, decorations };
3250
+ }
3251
+ function measureToken(tok, fs) {
3252
+ switch (tok.kind) {
3253
+ case "text":
3254
+ return tok.value.length * fs * (tok.bold ? 0.62 : 0.58);
3255
+ case "code":
3256
+ return tok.value.length * fs * 0.62 + 4;
3257
+ case "link": {
3258
+ let w = 0;
3259
+ for (const t of tok.value) w += measureToken(t, fs);
3260
+ return w;
3261
+ }
3262
+ case "checkbox":
3263
+ return fs * 0.85 + fs * 0.25;
3264
+ }
2939
3265
  }
2940
- function renderCentral(n, theme, fontFamily) {
2941
- const fs = fontSizeOf(0);
2942
- const pillW = n.labelWidth;
2943
- const pillH = n.labelHeight;
2944
- return group(
2945
- { class: "schematex-mindmap-central", "data-node-id": n.node.id },
2946
- [
2947
- rect({
2948
- x: n.x - pillW / 2,
2949
- y: n.y - pillH / 2,
2950
- width: pillW,
2951
- height: pillH,
2952
- rx: pillH / 2,
2953
- ry: pillH / 2,
2954
- fill: "none",
2955
- stroke: theme.textMuted,
2956
- "stroke-width": underlineMain(theme)
2957
- }),
2958
- text(
2959
- {
2960
- x: n.x,
2961
- y: n.y + fs * 0.35,
2962
- "text-anchor": "middle",
2963
- "font-family": fontFamily,
2964
- "font-size": fs,
2965
- "font-weight": 700,
2966
- fill: theme.text
2967
- },
2968
- n.node.label
2969
- )
2970
- ]
2971
- );
3266
+ function tspan(attrs, content) {
3267
+ const pairs = [];
3268
+ for (const [k, v] of Object.entries(attrs)) {
3269
+ if (v === void 0) continue;
3270
+ pairs.push(`${k}="${typeof v === "number" ? String(v) : escapeXml(String(v))}"`);
3271
+ }
3272
+ return `<tspan ${pairs.join(" ")}>${escapeXml(content)}</tspan>`;
2972
3273
  }
2973
- function renderBranchNode(n, color, theme, fontFamily) {
3274
+ function renderNode(n, color, theme, fontFamily) {
3275
+ const isRoot = n.node.depth === 0;
2974
3276
  const isMain = n.node.depth === 1;
2975
- const fs = fontSizeOf(n.node.depth);
2976
- const tx = n.x;
2977
- const ty = isMain ? n.y - 3 : n.y + fs * 0.35;
3277
+ const fs = n.fontSize;
3278
+ const lh = lineHeightOf(fs);
3279
+ const lineCount = n.lines.length;
3280
+ const topY = n.y - n.labelHeight / 2;
3281
+ const underlineY2 = n.y + n.labelHeight / 2 - UNDERLINE_GAP / 2;
3282
+ const children = [];
3283
+ const decorations = [];
3284
+ const weight = isRoot ? 700 : isMain ? 600 : 400;
3285
+ for (let i = 0; i < lineCount; i++) {
3286
+ const line2 = n.lines[i];
3287
+ const cy = topY + (i + 0.5) * lh;
3288
+ const r = renderLine(line2, n.x, cy, fs, fontFamily, weight, theme);
3289
+ decorations.push(...r.decorations);
3290
+ children.push(r.textElement);
3291
+ }
2978
3292
  const ux1 = n.x - n.labelWidth / 2;
2979
3293
  const ux2 = n.x + n.labelWidth / 2;
2980
- const uy = n.y;
2981
- const children = [
2982
- text(
2983
- {
2984
- x: tx,
2985
- y: ty,
2986
- "text-anchor": "middle",
2987
- "font-family": fontFamily,
2988
- "font-size": fs,
2989
- "font-weight": isMain ? 600 : 400,
2990
- fill: theme.text
2991
- },
2992
- n.node.label
2993
- )
2994
- ];
2995
- if (isMain) {
2996
- children.push(
2997
- el("line", {
2998
- x1: ux1,
2999
- y1: uy,
3000
- x2: ux2,
3001
- y2: uy,
3002
- stroke: color,
3003
- "stroke-width": underlineMain(theme),
3004
- "stroke-linecap": "round"
3005
- })
3006
- );
3007
- }
3294
+ const sw = underlineWidthFor(n.node.depth) * strokeScale(theme);
3295
+ children.push(
3296
+ el("line", {
3297
+ x1: ux1,
3298
+ y1: underlineY2,
3299
+ x2: ux2,
3300
+ y2: underlineY2,
3301
+ stroke: color,
3302
+ "stroke-width": sw,
3303
+ "stroke-linecap": "round"
3304
+ })
3305
+ );
3306
+ const cls = isRoot ? "schematex-mindmap-central" : isMain ? "schematex-mindmap-main" : "schematex-mindmap-leaf";
3008
3307
  return group(
3009
3308
  {
3010
- class: isMain ? "schematex-mindmap-main" : "schematex-mindmap-leaf",
3309
+ class: cls,
3011
3310
  "data-node-id": n.node.id,
3012
3311
  "data-depth": n.node.depth,
3013
3312
  "data-branch-idx": n.branchIndex
3014
3313
  },
3015
- children
3314
+ [...decorations, ...children]
3016
3315
  );
3017
3316
  }
3018
3317
  function renderMindmapAST(ast, themeName = "default", fontFamily = "system-ui, -apple-system, sans-serif") {
@@ -3036,15 +3335,10 @@ function renderMindmapAST(ast, themeName = "default", fontFamily = "system-ui, -
3036
3335
  }
3037
3336
  const nodeSvgs = [];
3038
3337
  for (const n of layout.nodes) {
3039
- if (n.node.depth === 0) {
3040
- nodeSvgs.push(renderCentral(n, theme, fontFamily));
3041
- } else {
3042
- nodeSvgs.push(
3043
- renderBranchNode(n, paletteColor(theme, n.branchIndex), theme, fontFamily)
3044
- );
3045
- }
3338
+ const color = n.node.depth === 0 ? theme.centralFill : paletteColor(theme, n.branchIndex);
3339
+ nodeSvgs.push(renderNode(n, color, theme, fontFamily));
3046
3340
  }
3047
- const title2 = ast.title ?? ast.root.label;
3341
+ const title2 = ast.title ?? tokensToPlainText(ast.root.tokens);
3048
3342
  return svgRoot(
3049
3343
  {
3050
3344
  viewBox: `0 0 ${layout.width.toFixed(1)} ${layout.height.toFixed(1)}`,
@@ -4535,5 +4829,5 @@ function render(text2, config) {
4535
4829
  }
4536
4830
 
4537
4831
  export { decisiontree, parse, render, timeline };
4538
- //# sourceMappingURL=chunk-M6AMNXQ7.js.map
4539
- //# sourceMappingURL=chunk-M6AMNXQ7.js.map
4832
+ //# sourceMappingURL=chunk-UUPYTUGR.js.map
4833
+ //# sourceMappingURL=chunk-UUPYTUGR.js.map