@cardenelabs/cdl 0.121.0 → 0.123.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 (69) hide show
  1. package/CHANGELOG.md +51 -1
  2. package/README.md +137 -0
  3. package/SPEC.md +1 -1
  4. package/dist/index.cjs +1513 -667
  5. package/dist/index.cjs.map +1 -1
  6. package/dist/index.d.cts +51 -33
  7. package/dist/index.d.ts +51 -33
  8. package/dist/index.js +1513 -668
  9. package/dist/index.js.map +1 -1
  10. package/dist/react.cjs +1271 -444
  11. package/dist/react.cjs.map +1 -1
  12. package/dist/react.d.cts +1 -1
  13. package/dist/react.d.ts +1 -1
  14. package/dist/react.js +1271 -444
  15. package/dist/react.js.map +1 -1
  16. package/dist/{render-A5AKjNuy.d.cts → render-CVczwfRb.d.cts} +40 -7
  17. package/dist/{render-A5AKjNuy.d.ts → render-CVczwfRb.d.ts} +40 -7
  18. package/package.json +9 -12
  19. package/src/builder.ts +8 -2
  20. package/src/index.ts +3 -0
  21. package/src/kinds/box-lines.ts +17 -4
  22. package/src/kinds/chart-bar.tsx +4 -0
  23. package/src/kinds/chart-gauge.tsx +20 -9
  24. package/src/kinds/chart-pie.tsx +67 -17
  25. package/src/kinds/chart-radial.tsx +7 -2
  26. package/src/kinds/chart-slope.tsx +26 -7
  27. package/src/kinds/chart-stacked-bar.tsx +8 -4
  28. package/src/kinds/chart-stat.tsx +19 -4
  29. package/src/kinds/chart-waffle.tsx +7 -2
  30. package/src/kinds/dyn-shape.tsx +22 -9
  31. package/src/kinds/funnel.tsx +9 -2
  32. package/src/kinds/generic.tsx +5 -2
  33. package/src/kinds/mind-map.tsx +26 -10
  34. package/src/kinds/quadrant.tsx +14 -4
  35. package/src/kinds/row-align.ts +19 -7
  36. package/src/kinds/sequence-board-metrics.ts +13 -3
  37. package/src/kinds/sequence-board.tsx +4 -2
  38. package/src/kinds/shape-basement.tsx +57 -32
  39. package/src/kinds/shape-blockchain.tsx +83 -34
  40. package/src/kinds/shape-commerce.tsx +65 -24
  41. package/src/kinds/shape-finance.tsx +90 -26
  42. package/src/kinds/shape-hardware.tsx +48 -17
  43. package/src/kinds/shape-region.tsx +16 -6
  44. package/src/kinds/shape-software.tsx +30 -8
  45. package/src/kinds/station.tsx +29 -0
  46. package/src/kinds/text-width.ts +17 -3
  47. package/src/kinds/tree.tsx +25 -7
  48. package/src/layout/collisions.ts +50 -28
  49. package/src/layout/curve-path.ts +126 -0
  50. package/src/layout/edges.ts +271 -58
  51. package/src/layout/head-label.ts +11 -5
  52. package/src/layout/lanes.ts +3 -2
  53. package/src/layout/metro-path.ts +185 -0
  54. package/src/layout/nodes.ts +14 -6
  55. package/src/layout/predict-bbox.ts +6 -3
  56. package/src/layout/self-loop.ts +10 -4
  57. package/src/layout/spec.ts +36 -7
  58. package/src/layout/text-width.ts +25 -8
  59. package/src/layout/tokens.ts +2 -0
  60. package/src/layout-with-validation.ts +10 -5
  61. package/src/layout.ts +55 -21
  62. package/src/presets.ts +69 -43
  63. package/src/render/edges.tsx +19 -3
  64. package/src/render/interactive-panel.tsx +34 -7
  65. package/src/render/nodes.tsx +100 -48
  66. package/src/render/stage.tsx +3 -0
  67. package/src/text-metrics.ts +9 -0
  68. package/src/types.ts +41 -4
  69. package/src/visual-validate.ts +91 -21
package/dist/index.js CHANGED
@@ -710,6 +710,11 @@ function \u5B57\u3092\u5DEE\u3057\u8FBC\u3080(template, values) {
710
710
  return template.replace(/\{(\w+)\}/g, (whole, name) => name in values ? String(values[name]) : whole);
711
711
  }
712
712
 
713
+ // src/text-metrics.ts
714
+ function resolveTextMetrics(value) {
715
+ return value === "monospace" ? "monospace" : "proportional";
716
+ }
717
+
713
718
  // src/formula/ast.ts
714
719
  var ALLOWED_MATH_FNS = /* @__PURE__ */ new Set([
715
720
  "min",
@@ -1648,13 +1653,215 @@ function \u5024\u3092\u540D\u524D\u3067\u8AAD\u3080(\u5165\u529B\u6B04, \u5024)
1648
1653
  return \u5024.split(",").map((v) => \u5165\u529B\u6B04.\u540D\u524D.get(v) ?? v).join(",");
1649
1654
  }
1650
1655
 
1656
+ // src/layout/text-width.ts
1657
+ var INTER_BOLD_ADVANCE_EM = {
1658
+ // uppercase (実測係数化、 Inter Bold 仕様 × 1.20)
1659
+ A: 0.86,
1660
+ B: 0.86,
1661
+ C: 0.88,
1662
+ D: 0.93,
1663
+ E: 0.82,
1664
+ F: 0.79,
1665
+ G: 0.94,
1666
+ H: 0.92,
1667
+ I: 0.44,
1668
+ J: 0.66,
1669
+ K: 0.86,
1670
+ L: 0.74,
1671
+ M: 1.12,
1672
+ N: 0.94,
1673
+ O: 0.94,
1674
+ P: 0.85,
1675
+ Q: 0.94,
1676
+ R: 0.87,
1677
+ S: 0.79,
1678
+ T: 0.82,
1679
+ U: 0.91,
1680
+ V: 0.85,
1681
+ W: 1.22,
1682
+ X: 0.85,
1683
+ Y: 0.82,
1684
+ Z: 0.82,
1685
+ // lowercase (実測係数化、 Inter Bold 仕様 × 1.22)
1686
+ a: 0.73,
1687
+ b: 0.77,
1688
+ c: 0.68,
1689
+ d: 0.77,
1690
+ e: 0.73,
1691
+ f: 0.51,
1692
+ g: 0.76,
1693
+ h: 0.77,
1694
+ i: 0.39,
1695
+ j: 0.41,
1696
+ k: 0.73,
1697
+ l: 0.39,
1698
+ m: 1.15,
1699
+ n: 0.77,
1700
+ o: 0.76,
1701
+ p: 0.77,
1702
+ q: 0.77,
1703
+ r: 0.54,
1704
+ s: 0.65,
1705
+ t: 0.54,
1706
+ u: 0.77,
1707
+ v: 0.71,
1708
+ w: 1.05,
1709
+ x: 0.71,
1710
+ y: 0.71,
1711
+ z: 0.66,
1712
+ // digits (Inter Bold tabular-nums、 実測係数化 × 1.20)
1713
+ "0": 0.72,
1714
+ "1": 0.72,
1715
+ "2": 0.72,
1716
+ "3": 0.72,
1717
+ "4": 0.72,
1718
+ "5": 0.72,
1719
+ "6": 0.72,
1720
+ "7": 0.72,
1721
+ "8": 0.72,
1722
+ "9": 0.72,
1723
+ // ascii symbols (実測係数化 × 1.15、 punct 系は kerning が広く効くため 1.20)
1724
+ " ": 0.35,
1725
+ "!": 0.44,
1726
+ '"': 0.59,
1727
+ "#": 0.78,
1728
+ "$": 0.72,
1729
+ "%": 1,
1730
+ "&": 0.86,
1731
+ "'": 0.32,
1732
+ "(": 0.46,
1733
+ ")": 0.46,
1734
+ "*": 0.63,
1735
+ "+": 0.78,
1736
+ ",": 0.36,
1737
+ "-": 0.5,
1738
+ ".": 0.36,
1739
+ "/": 0.51,
1740
+ ":": 0.36,
1741
+ ";": 0.36,
1742
+ "<": 0.78,
1743
+ "=": 0.78,
1744
+ ">": 0.78,
1745
+ "?": 0.63,
1746
+ "@": 1.17,
1747
+ "[": 0.48,
1748
+ "\\": 0.51,
1749
+ "]": 0.48,
1750
+ "^": 0.63,
1751
+ "_": 0.63,
1752
+ "`": 0.48,
1753
+ "{": 0.52,
1754
+ "|": 0.37,
1755
+ "}": 0.52,
1756
+ "~": 0.78
1757
+ };
1758
+ var JETBRAINS_MONO_ADVANCE_EM = 0.63;
1759
+ function isCJK(code) {
1760
+ return code >= 12288 && code <= 12543 || // CJK symbols / hiragana / katakana
1761
+ code >= 13312 && code <= 40959 || // CJK ideographs
1762
+ code >= 63744 && code <= 64255 || // CJK compat ideographs
1763
+ code >= 65281 && code <= 65376 || // fullwidth ASCII
1764
+ code >= 65504 && code <= 65510;
1765
+ }
1766
+ function isHalfwidthKana(code) {
1767
+ return code >= 65377 && code <= 65500;
1768
+ }
1769
+ var EMOJI_ADVANCE_EM = 1.05;
1770
+ var MONO_EMOJI_ADVANCE_EM = 1.16;
1771
+ var DRAWN_CJK_RATIO = 1.08;
1772
+ var DRAWN_ASCII_RATIO = 1.16;
1773
+ function isAscii(code) {
1774
+ return code < 128;
1775
+ }
1776
+ var WIDE_SYMBOL_ADVANCE_EM = 0.95;
1777
+ function isEmoji(code) {
1778
+ return code >= 126976 && code <= 129791 || // 絵文字の主要面
1779
+ code >= 9728 && code <= 10175 || // 記号と絵文字 (♻ ✅ ❤ 等)
1780
+ code >= 127462 && code <= 127487;
1781
+ }
1782
+ function isEmojiGrapheme(grapheme, firstCode) {
1783
+ return isEmoji(firstCode) || grapheme.includes("\uFE0F");
1784
+ }
1785
+ function isWideSymbol(code) {
1786
+ return code >= 8592 && code <= 8703 || // 矢印
1787
+ code >= 9472 && code <= 9599 || // 罫線
1788
+ code >= 9632 && code <= 9727 || // 幾何図形
1789
+ code >= 11008 && code <= 11263;
1790
+ }
1791
+ var CLUSTER_JOINER_RE = /\u200d|\ufe0f|[\u{1f000}-\u{1faff}]|[\u{2600}-\u{27bf}]/u;
1792
+ var \u66F8\u8A18\u7D20\u3067\u5206\u3051\u308B;
1793
+ function segmentGraphemes(text) {
1794
+ if (typeof Intl === "undefined" || typeof Intl.Segmenter !== "function") {
1795
+ return [...text];
1796
+ }
1797
+ \u66F8\u8A18\u7D20\u3067\u5206\u3051\u308B ??= new Intl.Segmenter(void 0, { granularity: "grapheme" });
1798
+ return [...\u66F8\u8A18\u7D20\u3067\u5206\u3051\u308B.segment(text)].map((s) => s.segment);
1799
+ }
1800
+ function defaultAdvanceEm(ch, code) {
1801
+ if (isEmoji(code)) return EMOJI_ADVANCE_EM;
1802
+ if (isWideSymbol(code)) return WIDE_SYMBOL_ADVANCE_EM;
1803
+ if (isCJK(code)) return 1.08;
1804
+ if (isHalfwidthKana(code)) return 0.72;
1805
+ if (ch >= "a" && ch <= "z") return 0.73;
1806
+ if (ch >= "A" && ch <= "Z") return 0.86;
1807
+ if (ch >= "0" && ch <= "9") return 0.72;
1808
+ return 0.65;
1809
+ }
1810
+ function measureAdvanceWidth(text, opts = {}) {
1811
+ const fontSize = opts.fontSize ?? 22;
1812
+ const letterSpacing = opts.letterSpacing ?? 0;
1813
+ const fontFamily = opts.textMetrics === "monospace" ? "mono" : opts.fontFamily ?? "sans";
1814
+ const bound = opts.bound ?? "layout";
1815
+ let advanceEmSum = 0;
1816
+ let charCount = 0;
1817
+ const \u6587\u5B57\u5217 = CLUSTER_JOINER_RE.test(text) ? segmentGraphemes(text) : [...text];
1818
+ for (const ch of \u6587\u5B57\u5217) {
1819
+ charCount++;
1820
+ const code = ch.codePointAt(0) ?? 0;
1821
+ const \u5272\u308A\u623B\u3057 = bound === "drawn" && !isEmojiGrapheme(ch, code) ? isAscii(code) && fontFamily !== "mono" ? DRAWN_ASCII_RATIO : isCJK(code) ? DRAWN_CJK_RATIO : 1 : 1;
1822
+ if (isEmojiGrapheme(ch, code)) {
1823
+ advanceEmSum += fontFamily === "mono" ? MONO_EMOJI_ADVANCE_EM : EMOJI_ADVANCE_EM;
1824
+ continue;
1825
+ }
1826
+ if (fontFamily === "mono") {
1827
+ advanceEmSum += (isCJK(code) ? 1.08 : JETBRAINS_MONO_ADVANCE_EM) / \u5272\u308A\u623B\u3057;
1828
+ continue;
1829
+ }
1830
+ if (isCJK(code)) {
1831
+ advanceEmSum += 1.08 / \u5272\u308A\u623B\u3057;
1832
+ continue;
1833
+ }
1834
+ const table = ch.length === 1 ? INTER_BOLD_ADVANCE_EM[ch] : void 0;
1835
+ advanceEmSum += (table !== void 0 ? table : defaultAdvanceEm(ch, code)) / \u5272\u308A\u623B\u3057;
1836
+ }
1837
+ return advanceEmSum * fontSize + letterSpacing * charCount;
1838
+ }
1839
+ function measureTextWidth(text, opts = {}) {
1840
+ const fontSize = opts.fontSize ?? 22;
1841
+ const bound = opts.bound ?? "layout";
1842
+ const w = measureAdvanceWidth(text, opts);
1843
+ return bound === "drawn" ? w : Math.max(w, fontSize * 1.2);
1844
+ }
1845
+ function \u53CE\u3081\u308B\u500D\u7387(text, opts, \u5E45) {
1846
+ if (!(\u5E45 > 0) || !(opts.fontSize > 0)) return 1;
1847
+ const \u5B9F\u5E45 = measureTextWidth(text, { ...opts, letterSpacing: 0 });
1848
+ return \u5B9F\u5E45 > \u5E45 ? \u5E45 / \u5B9F\u5E45 : 1;
1849
+ }
1850
+
1651
1851
  // src/kinds/text-width.ts
1652
1852
  var WIDE_RATIO = 1.04;
1653
1853
  var NARROW_RATIO = 0.37;
1654
1854
  var ASCII_RATIO = 0.86;
1655
1855
  var WIDE_CHARS = "W@%Mm";
1656
1856
  var NARROW_CHARS = "ijlI.,:;'! ";
1657
- function textWidth(s, size, \u5B57\u9001\u308A = 0) {
1857
+ function textWidth(s, size, \u5B57\u9001\u308A = 0, textMetrics = "proportional") {
1858
+ if (textMetrics === "monospace") {
1859
+ return measureAdvanceWidth(s, {
1860
+ fontSize: size,
1861
+ letterSpacing: \u5B57\u9001\u308A,
1862
+ fontFamily: "mono"
1863
+ });
1864
+ }
1658
1865
  let \u5E45 = 0;
1659
1866
  let \u5B57\u6570 = 0;
1660
1867
  for (const c of s) {
@@ -1691,8 +1898,8 @@ function splitRow(row) {
1691
1898
  }
1692
1899
  return { left: row.trim(), right: "", split: false };
1693
1900
  }
1694
- function rowColumnWidth(text, size, mono) {
1695
- return mono ? displayWidth(text) * size * MONO_ADVANCE_RATIO : textWidth(text, size);
1901
+ function rowColumnWidth(text, size, mono, textMetrics = "proportional") {
1902
+ return mono ? displayWidth(text) * size * MONO_ADVANCE_RATIO : textWidth(text, size, 0, textMetrics);
1696
1903
  }
1697
1904
  function displayWidth(text) {
1698
1905
  let w = 0;
@@ -1718,12 +1925,12 @@ function \u6841\u3067\u7701\u304F(text, \u4E0A\u9650) {
1718
1925
  if (displayWidth(text) <= \u4E0A\u9650) return text;
1719
1926
  return `${\u6841\u3067\u5272\u308B(text, \u4E0A\u9650 - 1)[0]}\u2026`;
1720
1927
  }
1721
- function requiredRowsWidth(rows, kind) {
1928
+ function requiredRowsWidth(rows, kind, textMetrics = "proportional") {
1722
1929
  if (!rows || rows.length === 0) return 0;
1723
1930
  const splits = rows.map(splitRow);
1724
1931
  const \u4E00\u756A\u5E83\u3044 = (\u53D6\u308B) => splits.reduce((m, s) => Math.max(m, \u53D6\u308B(s)), 0);
1725
- const storage = ROW_PAD_X_PX + \u4E00\u756A\u5E83\u3044((s) => rowColumnWidth(s.left, 26, true)) + STORAGE_COL_GAP_PX + \u4E00\u756A\u5E83\u3044((s) => rowColumnWidth(s.right, 26, true)) + ROW_RIGHT_PAD_PX;
1726
- const generic = ROW_PAD_X_PX + \u4E00\u756A\u5E83\u3044((s) => rowColumnWidth(s.left, GENERIC_ROW_LEFT_SIZE_PX, false)) + ROW_COL_GAP_PX + \u4E00\u756A\u5E83\u3044((s) => rowColumnWidth(s.right, GENERIC_ROW_RIGHT_SIZE_PX, true)) + ROW_RIGHT_PAD_PX;
1932
+ const storage = ROW_PAD_X_PX + \u4E00\u756A\u5E83\u3044((s) => rowColumnWidth(s.left, 26, true, textMetrics)) + STORAGE_COL_GAP_PX + \u4E00\u756A\u5E83\u3044((s) => rowColumnWidth(s.right, 26, true, textMetrics)) + ROW_RIGHT_PAD_PX;
1933
+ const generic = ROW_PAD_X_PX + \u4E00\u756A\u5E83\u3044((s) => rowColumnWidth(s.left, GENERIC_ROW_LEFT_SIZE_PX, false, textMetrics)) + ROW_COL_GAP_PX + \u4E00\u756A\u5E83\u3044((s) => rowColumnWidth(s.right, GENERIC_ROW_RIGHT_SIZE_PX, true, textMetrics)) + ROW_RIGHT_PAD_PX;
1727
1934
  if (kind === void 0) return Math.ceil(Math.max(storage, generic));
1728
1935
  return Math.ceil(kind === "storage" ? storage : generic);
1729
1936
  }
@@ -1788,7 +1995,10 @@ var \u5DE6\u53F3\u306E\u4F59\u767D = 8;
1788
1995
  function \u4F7F\u3048\u308B\u5E45(\u7BB1\u306E\u5E45) {
1789
1996
  return \u7BB1\u306E\u5E45 - \u5DE6\u53F3\u306E\u4F59\u767D * 2;
1790
1997
  }
1791
- function \u5E45\u3067\u5207\u308B(text, fontSize, \u4F7F\u3048\u308B\u5E452, \u6E2C\u308B = textWidth) {
1998
+ function \u7BB1\u306E\u5B57\u3092\u6E2C\u308B(textMetrics = "proportional") {
1999
+ return (text, fontSize) => textWidth(text, fontSize, 0, textMetrics);
2000
+ }
2001
+ function \u5E45\u3067\u5207\u308B(text, fontSize, \u4F7F\u3048\u308B\u5E452, \u6E2C\u308B) {
1792
2002
  if (\u4F7F\u3048\u308B\u5E452 <= 0) return "";
1793
2003
  if (\u6E2C\u308B(text, fontSize) <= \u4F7F\u3048\u308B\u5E452) return text;
1794
2004
  const \u7701\u7565 = "\u2026";
@@ -1805,7 +2015,7 @@ function \u5E45\u3067\u5207\u308B(text, fontSize, \u4F7F\u3048\u308B\u5E452, \u6
1805
2015
  return `${\u51FA}${\u7701\u7565}`;
1806
2016
  }
1807
2017
  var \u7E2E\u3081\u306E\u4E0B\u9650 = MIN_TEXT_SIZE;
1808
- function \u5E45\u306B\u53CE\u3081\u308B(text, fontSize, \u4F7F\u3048\u308B\u5E452, \u6E2C\u308B = textWidth) {
2018
+ function \u5E45\u306B\u53CE\u3081\u308B(text, fontSize, \u4F7F\u3048\u308B\u5E452, \u6E2C\u308B) {
1809
2019
  let size = fontSize;
1810
2020
  while (size > \u7E2E\u3081\u306E\u4E0B\u9650 && \u6E2C\u308B(text, size) > \u4F7F\u3048\u308B\u5E452) size -= 1;
1811
2021
  return { text: \u5E45\u3067\u5207\u308B(text, size, \u4F7F\u3048\u308B\u5E452, \u6E2C\u308B), fontSize: size };
@@ -1815,7 +2025,7 @@ function \u66F8\u8A18\u7D20\u306B\u5206\u3051\u308B(text) {
1815
2025
  if (typeof \u533A\u5207\u308A !== "function") return [...text];
1816
2026
  return [...new \u533A\u5207\u308A(void 0, { granularity: "grapheme" }).segment(text)].map((g) => g.segment);
1817
2027
  }
1818
- function \u7BB1\u306B\u7A4D\u3080(\u884C, \u7BB1\u306E\u5E45, \u7BB1\u306E\u9AD8\u30553) {
2028
+ function \u7BB1\u306B\u7A4D\u3080(\u884C, \u7BB1\u306E\u5E45, \u7BB1\u306E\u9AD8\u30553, \u6E2C\u308B) {
1819
2029
  const \u5019\u88DC = \u884C.filter((r, i) => i === 0 || r.text.trim() !== "");
1820
2030
  if (\u5019\u88DC.length === 0) return [];
1821
2031
  const \u4F7F\u3048\u308B\u9AD8\u3055 = \u7BB1\u306E\u9AD8\u30553 - \u4E0A\u4E0B\u306E\u4F59\u767D * 2;
@@ -1823,7 +2033,7 @@ function \u7BB1\u306B\u7A4D\u3080(\u884C, \u7BB1\u306E\u5E45, \u7BB1\u306E\u9AD8
1823
2033
  const \u6B8B\u3059 = [...\u5019\u88DC];
1824
2034
  while (\u6B8B\u3059.length > 1 && \u9AD8\u3055(\u6B8B\u3059) > \u4F7F\u3048\u308B\u9AD8\u3055) \u6B8B\u3059.pop();
1825
2035
  const \u5E45 = \u4F7F\u3048\u308B\u5E45(\u7BB1\u306E\u5E45);
1826
- const \u53CE\u3081\u305F = \u6B8B\u3059.map((r) => ({ ...r, ...\u5E45\u306B\u53CE\u3081\u308B(r.text, r.fontSize, \u5E45) }));
2036
+ const \u53CE\u3081\u305F = \u6B8B\u3059.map((r) => ({ ...r, ...\u5E45\u306B\u53CE\u3081\u308B(r.text, r.fontSize, \u5E45, \u6E2C\u308B) }));
1827
2037
  const \u7DCF\u9AD8 = \u9AD8\u3055(\u53CE\u3081\u305F);
1828
2038
  let \u7A4D\u307F = -\u7DCF\u9AD8 / 2;
1829
2039
  return \u53CE\u3081\u305F.map((r) => {
@@ -2180,7 +2390,15 @@ function useInteractiveIntegration(diagram2, options = {}) {
2180
2390
  f.id
2181
2391
  )) }),
2182
2392
  scrolls.length > 0 && /* @__PURE__ */ jsx("div", { className: "cdl-ip-group", children: scrolls.map((s) => /* @__PURE__ */ jsx(ScrollReadout, { id: s.id, name: s.label || s.id, progress: stateOverrides[s.id] }, s.id)) }),
2183
- readouts.length > 0 && /* @__PURE__ */ jsx("div", { className: "cdl-ip-group", children: readouts.map((r) => /* @__PURE__ */ jsx(ReadoutWidget, { readout: r, stateOverrides: mergedStateValues }, r.id)) })
2393
+ readouts.length > 0 && /* @__PURE__ */ jsx("div", { className: "cdl-ip-group", children: readouts.map((r) => /* @__PURE__ */ jsx(
2394
+ ReadoutWidget,
2395
+ {
2396
+ readout: r,
2397
+ stateOverrides: mergedStateValues,
2398
+ textMetrics: resolveTextMetrics(diagram2.textMetrics)
2399
+ },
2400
+ r.id
2401
+ )) })
2184
2402
  ] }) })
2185
2403
  );
2186
2404
  }, [diagram2, signals, stateOverrides, mergedStateValues]);
@@ -2601,7 +2819,8 @@ function StepperWidget({
2601
2819
  }
2602
2820
  function ReadoutWidget({
2603
2821
  readout,
2604
- stateOverrides
2822
+ stateOverrides,
2823
+ textMetrics = "proportional"
2605
2824
  }) {
2606
2825
  const rawValue = "source" in readout ? stateOverrides[readout.source] : void 0;
2607
2826
  const numericValue = typeof rawValue === "number" ? rawValue : typeof rawValue === "string" ? Number(rawValue) : Number.NaN;
@@ -2849,7 +3068,8 @@ function ReadoutWidget({
2849
3068
  max: readout.max,
2850
3069
  viewW: readout.viewW ?? 280,
2851
3070
  viewH: readout.viewH ?? 60,
2852
- color: readout.color ?? "#2563eb"
3071
+ color: readout.color ?? "#2563eb",
3072
+ textMetrics
2853
3073
  }
2854
3074
  );
2855
3075
  case "radar": {
@@ -3665,7 +3885,8 @@ function ReadoutWidget({
3665
3885
  { status: "idle", color: "#94a3b8" },
3666
3886
  { status: "error", color: "#ef4444" }
3667
3887
  ],
3668
- max: readout.max ?? 10
3888
+ max: readout.max ?? 10,
3889
+ textMetrics
3669
3890
  }
3670
3891
  );
3671
3892
  case "calendar-week":
@@ -4809,8 +5030,8 @@ function ProgressGroupReadout({
4809
5030
  }) })
4810
5031
  ] });
4811
5032
  }
4812
- function sequenceLabelAnchor(x, name, fontSize, viewW) {
4813
- const half = textWidth(name, fontSize) / 2;
5033
+ function sequenceLabelAnchor(x, name, fontSize, viewW, textMetrics = "proportional") {
5034
+ const half = textWidth(name, fontSize, 0, textMetrics) / 2;
4814
5035
  if (x - half < 0) return "start";
4815
5036
  if (x + half > viewW) return "end";
4816
5037
  return "middle";
@@ -4823,7 +5044,8 @@ function SequenceTimelineReadout({
4823
5044
  max,
4824
5045
  viewW,
4825
5046
  viewH,
4826
- color
5047
+ color,
5048
+ textMetrics = "proportional"
4827
5049
  }) {
4828
5050
  const events = [];
4829
5051
  const trimmed = value.trim();
@@ -4866,7 +5088,17 @@ function SequenceTimelineReadout({
4866
5088
  const x = xFor(e.t);
4867
5089
  return /* @__PURE__ */ jsxs("g", { "data-cdl-event-marker": e.name, children: [
4868
5090
  /* @__PURE__ */ jsx("circle", { cx: x, cy: trackY, r: 5, fill: color, stroke: "#fff", strokeWidth: 1.5, children: /* @__PURE__ */ jsx(\u5B57\u306E\u898B\u51FA\u3057, { k: "readout.sequenceTimeline.title", v: { name: e.name, t: e.t } }) }),
4869
- /* @__PURE__ */ jsx("text", { x, y: trackY - 12, textAnchor: sequenceLabelAnchor(x, e.name, 10, viewW), fontSize: 10, fill: "var(--v4-ink, #1a1f2a)", children: e.name }),
5091
+ /* @__PURE__ */ jsx(
5092
+ "text",
5093
+ {
5094
+ x,
5095
+ y: trackY - 12,
5096
+ textAnchor: sequenceLabelAnchor(x, e.name, 10, viewW, textMetrics),
5097
+ fontSize: 10,
5098
+ fill: "var(--v4-ink, #1a1f2a)",
5099
+ children: e.name
5100
+ }
5101
+ ),
4870
5102
  /* @__PURE__ */ jsx("text", { x, y: trackY + 18, textAnchor: "middle", fontSize: 9, fill: "var(--v4-mute, #64748b)", children: e.t })
4871
5103
  ] }, i);
4872
5104
  })
@@ -7943,7 +8175,8 @@ function StatusTimelineReadout({
7943
8175
  label,
7944
8176
  value,
7945
8177
  colorMap,
7946
- max
8178
+ max,
8179
+ textMetrics = "proportional"
7947
8180
  }) {
7948
8181
  const events = [];
7949
8182
  const trimmed = value.trim();
@@ -7968,6 +8201,7 @@ function StatusTimelineReadout({
7968
8201
  const cellW = shown.length > 0 ? (width - 20) / shown.length : 0;
7969
8202
  const height = stripHeight + 40;
7970
8203
  const \u533A\u9593\u306E\u5B57 = (status) => status === "active" || status === "idle" || status === "error" ? \u5F15\u304F(`readout.statusTimeline.${status}`) : status.toUpperCase();
8204
+ const \u6E2C\u308B = \u7BB1\u306E\u5B57\u3092\u6E2C\u308B(textMetrics);
7971
8205
  return /* @__PURE__ */ jsxs("div", { className: "cdl-ip-item cdl-ip-readout-status-timeline", "data-cdl-readout": id, children: [
7972
8206
  /* @__PURE__ */ jsx("span", { className: "cdl-ip-label", children: label }),
7973
8207
  /* @__PURE__ */ jsx(
@@ -7981,7 +8215,7 @@ function StatusTimelineReadout({
7981
8215
  const x = 10 + i * cellW;
7982
8216
  const c = colorLookup.get(ev.status) ?? "#cbd5e1";
7983
8217
  const \u5B572 = \u533A\u9593\u306E\u5B57(ev.status);
7984
- const \u63CF\u304F\u5B57 = \u5E45\u3067\u5207\u308B(\u5B572, 10, cellW - 8);
8218
+ const \u63CF\u304F\u5B57 = \u5E45\u3067\u5207\u308B(\u5B572, 10, cellW - 8, \u6E2C\u308B);
7985
8219
  return /* @__PURE__ */ jsxs("g", { "data-cdl-status-event": i, "data-cdl-status": ev.status, children: [
7986
8220
  /* @__PURE__ */ jsx("rect", { x, y: 10, width: cellW - 2, height: stripHeight, fill: c, rx: 2 }),
7987
8221
  /* @__PURE__ */ jsxs(
@@ -12092,6 +12326,8 @@ function diagram(id, options) {
12092
12326
  ...options.palette !== void 0 ? { palette: options.palette } : {},
12093
12327
  // 言語も素通しする。 型の外の値を既定に落とすのは `layout` の 1 箇所に置く
12094
12328
  ...options.lang !== void 0 ? { lang: options.lang } : {},
12329
+ // 字幅の測り方も素通しする。型の外の値を既定に落とすのは `layout` の 1 箇所に置く
12330
+ ...options.textMetrics !== void 0 ? { textMetrics: options.textMetrics } : {},
12095
12331
  // 種類の名前も同じ経路で渡し、空文字の扱いを `layout` の 1 箇所に揃える
12096
12332
  ...options.type !== void 0 ? { type: options.type } : {},
12097
12333
  // inputs / formulas / scrollTriggers / eventBindings は空なら省略 (static diagram の JSON 形状維持)
@@ -12124,196 +12360,6 @@ var ARROW_ANGLE_MAX_DEG = 100;
12124
12360
  var FAN_GAP = 120;
12125
12361
  var DETOUR_GAP = 94;
12126
12362
 
12127
- // src/layout/text-width.ts
12128
- var INTER_BOLD_ADVANCE_EM = {
12129
- // uppercase (実測係数化、 Inter Bold 仕様 × 1.20)
12130
- A: 0.86,
12131
- B: 0.86,
12132
- C: 0.88,
12133
- D: 0.93,
12134
- E: 0.82,
12135
- F: 0.79,
12136
- G: 0.94,
12137
- H: 0.92,
12138
- I: 0.44,
12139
- J: 0.66,
12140
- K: 0.86,
12141
- L: 0.74,
12142
- M: 1.12,
12143
- N: 0.94,
12144
- O: 0.94,
12145
- P: 0.85,
12146
- Q: 0.94,
12147
- R: 0.87,
12148
- S: 0.79,
12149
- T: 0.82,
12150
- U: 0.91,
12151
- V: 0.85,
12152
- W: 1.22,
12153
- X: 0.85,
12154
- Y: 0.82,
12155
- Z: 0.82,
12156
- // lowercase (実測係数化、 Inter Bold 仕様 × 1.22)
12157
- a: 0.73,
12158
- b: 0.77,
12159
- c: 0.68,
12160
- d: 0.77,
12161
- e: 0.73,
12162
- f: 0.51,
12163
- g: 0.76,
12164
- h: 0.77,
12165
- i: 0.39,
12166
- j: 0.41,
12167
- k: 0.73,
12168
- l: 0.39,
12169
- m: 1.15,
12170
- n: 0.77,
12171
- o: 0.76,
12172
- p: 0.77,
12173
- q: 0.77,
12174
- r: 0.54,
12175
- s: 0.65,
12176
- t: 0.54,
12177
- u: 0.77,
12178
- v: 0.71,
12179
- w: 1.05,
12180
- x: 0.71,
12181
- y: 0.71,
12182
- z: 0.66,
12183
- // digits (Inter Bold tabular-nums、 実測係数化 × 1.20)
12184
- "0": 0.72,
12185
- "1": 0.72,
12186
- "2": 0.72,
12187
- "3": 0.72,
12188
- "4": 0.72,
12189
- "5": 0.72,
12190
- "6": 0.72,
12191
- "7": 0.72,
12192
- "8": 0.72,
12193
- "9": 0.72,
12194
- // ascii symbols (実測係数化 × 1.15、 punct 系は kerning が広く効くため 1.20)
12195
- " ": 0.35,
12196
- "!": 0.44,
12197
- '"': 0.59,
12198
- "#": 0.78,
12199
- "$": 0.72,
12200
- "%": 1,
12201
- "&": 0.86,
12202
- "'": 0.32,
12203
- "(": 0.46,
12204
- ")": 0.46,
12205
- "*": 0.63,
12206
- "+": 0.78,
12207
- ",": 0.36,
12208
- "-": 0.5,
12209
- ".": 0.36,
12210
- "/": 0.51,
12211
- ":": 0.36,
12212
- ";": 0.36,
12213
- "<": 0.78,
12214
- "=": 0.78,
12215
- ">": 0.78,
12216
- "?": 0.63,
12217
- "@": 1.17,
12218
- "[": 0.48,
12219
- "\\": 0.51,
12220
- "]": 0.48,
12221
- "^": 0.63,
12222
- "_": 0.63,
12223
- "`": 0.48,
12224
- "{": 0.52,
12225
- "|": 0.37,
12226
- "}": 0.52,
12227
- "~": 0.78
12228
- };
12229
- var JETBRAINS_MONO_ADVANCE_EM = 0.63;
12230
- function isCJK(code) {
12231
- return code >= 12288 && code <= 12543 || // CJK symbols / hiragana / katakana
12232
- code >= 13312 && code <= 40959 || // CJK ideographs
12233
- code >= 63744 && code <= 64255 || // CJK compat ideographs
12234
- code >= 65281 && code <= 65376 || // fullwidth ASCII
12235
- code >= 65504 && code <= 65510;
12236
- }
12237
- function isHalfwidthKana(code) {
12238
- return code >= 65377 && code <= 65500;
12239
- }
12240
- var EMOJI_ADVANCE_EM = 1.05;
12241
- var MONO_EMOJI_ADVANCE_EM = 1.16;
12242
- var DRAWN_CJK_RATIO = 1.08;
12243
- var DRAWN_ASCII_RATIO = 1.16;
12244
- function isAscii(code) {
12245
- return code < 128;
12246
- }
12247
- var WIDE_SYMBOL_ADVANCE_EM = 0.95;
12248
- function isEmoji(code) {
12249
- return code >= 126976 && code <= 129791 || // 絵文字の主要面
12250
- code >= 9728 && code <= 10175 || // 記号と絵文字 (♻ ✅ ❤ 等)
12251
- code >= 127462 && code <= 127487;
12252
- }
12253
- function isEmojiGrapheme(grapheme, firstCode) {
12254
- return isEmoji(firstCode) || grapheme.includes("\uFE0F");
12255
- }
12256
- function isWideSymbol(code) {
12257
- return code >= 8592 && code <= 8703 || // 矢印
12258
- code >= 9472 && code <= 9599 || // 罫線
12259
- code >= 9632 && code <= 9727 || // 幾何図形
12260
- code >= 11008 && code <= 11263;
12261
- }
12262
- var CLUSTER_JOINER_RE = /\u200d|\ufe0f|[\u{1f000}-\u{1faff}]|[\u{2600}-\u{27bf}]/u;
12263
- var \u66F8\u8A18\u7D20\u3067\u5206\u3051\u308B;
12264
- function segmentGraphemes(text) {
12265
- if (typeof Intl === "undefined" || typeof Intl.Segmenter !== "function") {
12266
- return [...text];
12267
- }
12268
- \u66F8\u8A18\u7D20\u3067\u5206\u3051\u308B ??= new Intl.Segmenter(void 0, { granularity: "grapheme" });
12269
- return [...\u66F8\u8A18\u7D20\u3067\u5206\u3051\u308B.segment(text)].map((s) => s.segment);
12270
- }
12271
- function defaultAdvanceEm(ch, code) {
12272
- if (isEmoji(code)) return EMOJI_ADVANCE_EM;
12273
- if (isWideSymbol(code)) return WIDE_SYMBOL_ADVANCE_EM;
12274
- if (isCJK(code)) return 1.08;
12275
- if (isHalfwidthKana(code)) return 0.72;
12276
- if (ch >= "a" && ch <= "z") return 0.73;
12277
- if (ch >= "A" && ch <= "Z") return 0.86;
12278
- if (ch >= "0" && ch <= "9") return 0.72;
12279
- return 0.65;
12280
- }
12281
- function measureTextWidth(text, opts = {}) {
12282
- const fontSize = opts.fontSize ?? 22;
12283
- const letterSpacing = opts.letterSpacing ?? 0;
12284
- const fontFamily = opts.fontFamily ?? "sans";
12285
- const bound = opts.bound ?? "layout";
12286
- let advanceEmSum = 0;
12287
- let charCount = 0;
12288
- const \u6587\u5B57\u5217 = CLUSTER_JOINER_RE.test(text) ? segmentGraphemes(text) : [...text];
12289
- for (const ch of \u6587\u5B57\u5217) {
12290
- charCount++;
12291
- const code = ch.codePointAt(0) ?? 0;
12292
- const \u5272\u308A\u623B\u3057 = bound === "drawn" && !isEmojiGrapheme(ch, code) ? isAscii(code) ? DRAWN_ASCII_RATIO : isCJK(code) ? DRAWN_CJK_RATIO : 1 : 1;
12293
- if (isEmojiGrapheme(ch, code)) {
12294
- advanceEmSum += fontFamily === "mono" ? MONO_EMOJI_ADVANCE_EM : EMOJI_ADVANCE_EM;
12295
- continue;
12296
- }
12297
- if (fontFamily === "mono") {
12298
- advanceEmSum += (isCJK(code) ? 1.08 : JETBRAINS_MONO_ADVANCE_EM) / \u5272\u308A\u623B\u3057;
12299
- continue;
12300
- }
12301
- if (isCJK(code)) {
12302
- advanceEmSum += 1.08 / \u5272\u308A\u623B\u3057;
12303
- continue;
12304
- }
12305
- const table = ch.length === 1 ? INTER_BOLD_ADVANCE_EM[ch] : void 0;
12306
- advanceEmSum += (table !== void 0 ? table : defaultAdvanceEm(ch, code)) / \u5272\u308A\u623B\u3057;
12307
- }
12308
- const w = advanceEmSum * fontSize + letterSpacing * charCount;
12309
- return bound === "drawn" ? w : Math.max(w, fontSize * 1.2);
12310
- }
12311
- function \u53CE\u3081\u308B\u500D\u7387(text, opts, \u5E45) {
12312
- if (!(\u5E45 > 0) || !(opts.fontSize > 0)) return 1;
12313
- const \u5B9F\u5E45 = measureTextWidth(text, { ...opts, letterSpacing: 0 });
12314
- return \u5B9F\u5E45 > \u5E45 ? \u5E45 / \u5B9F\u5E45 : 1;
12315
- }
12316
-
12317
12363
  // src/label-text.ts
12318
12364
  var EDGE_LABEL_TEXT = {
12319
12365
  // main 行は family を指定せず、 host 側の指定を継承する。
@@ -12388,6 +12434,7 @@ var KINDS_DRAWING_TITLE_OUTSIDE = /* @__PURE__ */ new Set([
12388
12434
  "dyn-arc",
12389
12435
  "dyn-wave",
12390
12436
  "dyn-polygon",
12437
+ "station",
12391
12438
  ...KINDS_DRAWING_OWN_PAYLOAD
12392
12439
  ]);
12393
12440
  function drawsTitleOutsideBox(kind) {
@@ -12395,7 +12442,7 @@ function drawsTitleOutsideBox(kind) {
12395
12442
  }
12396
12443
  var TITLE_FONT_SIZE_DEFAULT = 18;
12397
12444
  var TITLE_FONT_SIZE = new Map([
12398
- ...["dyn-rect", "dyn-circle", "dyn-arc", "dyn-wave", "dyn-polygon"].map(
12445
+ ...["dyn-rect", "dyn-circle", "dyn-arc", "dyn-wave", "dyn-polygon", "station"].map(
12399
12446
  (k) => [k, 13]
12400
12447
  ),
12401
12448
  ...[
@@ -12446,6 +12493,10 @@ var TITLE_FONT_SIZE = new Map([
12446
12493
  function titleFontSize(kind) {
12447
12494
  return TITLE_FONT_SIZE.get(kind ?? "") ?? TITLE_FONT_SIZE_DEFAULT;
12448
12495
  }
12496
+ var KINDS_WITH_TITLE_WIDTH_OUTSIDE_NODE = /* @__PURE__ */ new Set(["station"]);
12497
+ function skipsNodeTitleWidthCheck(kind) {
12498
+ return KINDS_WITH_TITLE_WIDTH_OUTSIDE_NODE.has(kind ?? "");
12499
+ }
12449
12500
  var TITLE_BOX_PADDING = 52;
12450
12501
  var KINDS_SCALING_TITLE_WHEN_LOW = /* @__PURE__ */ new Set(["actor", "event", "function", "storage"]);
12451
12502
  var KINDS_SCALING_TITLE_ALWAYS = /* @__PURE__ */ new Set([
@@ -12528,7 +12579,8 @@ var KINDS_DRAWING_ONLY_SHAPE = [
12528
12579
  "dyn-circle",
12529
12580
  "dyn-arc",
12530
12581
  "dyn-wave",
12531
- "dyn-polygon"
12582
+ "dyn-polygon",
12583
+ "station"
12532
12584
  ];
12533
12585
  var KINDS_WITHOUT_EYEBROW_TEXT = /* @__PURE__ */ new Set([
12534
12586
  ...KINDS_DRAWING_ONLY_SHAPE,
@@ -12667,15 +12719,22 @@ function requiredVerticalLabelGap(pillHs) {
12667
12719
  const step = parallelLabelStepY(pillHs);
12668
12720
  return (pillHs.length - 1) * step + Math.max(first, last) + CLEARANCE_NODE_LABEL * 2;
12669
12721
  }
12670
- function computeLabelBoxW(label, sub) {
12671
- const mainW = measureTextWidth(label ?? "", { fontSize: EDGE_LABEL_TEXT.main.fontSize });
12672
- const subW = sub ? measureTextWidth(sub, { fontSize: EDGE_LABEL_TEXT.sub.fontSize, fontFamily: "mono" }) : 0;
12722
+ function computeLabelBoxW(label, sub, textMetrics = "proportional") {
12723
+ const mainW = measureTextWidth(label ?? "", {
12724
+ fontSize: EDGE_LABEL_TEXT.main.fontSize,
12725
+ textMetrics
12726
+ });
12727
+ const subW = sub ? measureTextWidth(sub, {
12728
+ fontSize: EDGE_LABEL_TEXT.sub.fontSize,
12729
+ fontFamily: "mono",
12730
+ textMetrics
12731
+ }) : 0;
12673
12732
  const raw = Math.max(mainW, subW) + LABEL_PILL_PAD_X * 2;
12674
12733
  const EPSILON = 1e-6;
12675
12734
  return Math.ceil((raw - EPSILON) / 2) * 2;
12676
12735
  }
12677
- function computeLabelBBoxWorld(edge) {
12678
- const boxW = computeLabelBoxW(edge.label, edge.sub);
12736
+ function computeLabelBBoxWorld(edge, textMetrics = "proportional") {
12737
+ const boxW = computeLabelBoxW(edge.label, edge.sub, textMetrics);
12679
12738
  const boxH = edge.sub ? LABEL_PILL_H_WITH_SUB : LABEL_PILL_H_MAIN_ONLY;
12680
12739
  const anchor = edge.labelAnchor;
12681
12740
  const boxLeftX = anchor === "start" ? 0 : anchor === "end" ? -boxW : -boxW / 2;
@@ -12914,7 +12973,7 @@ function footerShapeDrawTop(node) {
12914
12973
  // src/layout/collisions.ts
12915
12974
  var LANE_LABEL_CLEARANCE_MARGIN = 2;
12916
12975
  var NEAR_MISS_MARGIN = LANE_LABEL_CLEARANCE_MARGIN;
12917
- function collectBBoxes(lanes, nodes, edges) {
12976
+ function collectBBoxes(lanes, nodes, edges, textMetrics = "proportional") {
12918
12977
  const out = [];
12919
12978
  for (const lane of lanes) {
12920
12979
  if (!lane.label) continue;
@@ -12923,7 +12982,7 @@ function collectBBoxes(lanes, nodes, edges) {
12923
12982
  id: lane.id,
12924
12983
  x: lane.x + 16,
12925
12984
  y: lane.y + 8,
12926
- w: measureTextWidth(lane.label, { fontSize: 20, letterSpacing: 2 }) + 24,
12985
+ w: measureTextWidth(lane.label, { fontSize: 20, letterSpacing: 2, textMetrics }) + 24,
12927
12986
  h: 28
12928
12987
  });
12929
12988
  }
@@ -12941,7 +13000,7 @@ function collectBBoxes(lanes, nodes, edges) {
12941
13000
  }
12942
13001
  for (const e of edges) {
12943
13002
  if (!hasRenderedLabel(e)) continue;
12944
- const bbox = computeLabelBBoxWorld(e);
13003
+ const bbox = computeLabelBBoxWorld(e, textMetrics);
12945
13004
  out.push({
12946
13005
  kind: "edge-label",
12947
13006
  id: e.id,
@@ -13308,13 +13367,13 @@ function detectCollisions(bboxes, edges) {
13308
13367
  }
13309
13368
  function extractPathSegments(d) {
13310
13369
  const segs = [];
13311
- const commandRegex = /([MLCQZmlcqz])([^MLCQZmlcqz]*)/g;
13370
+ const commandRegex = /([MLCQAZmlcqaz])([^MLCQAZmlcqaz]*)/g;
13312
13371
  let cur = { x: 0, y: 0 };
13313
13372
  let m;
13314
13373
  while ((m = commandRegex.exec(d)) !== null) {
13315
13374
  const cmd = m[1];
13316
13375
  const args = (m[2] ?? "").trim().split(/[\s,]+/).filter(Boolean).map(parseFloat);
13317
- const need = cmd === "M" || cmd === "L" ? 2 : cmd === "Q" ? 4 : cmd === "C" ? 6 : 0;
13376
+ const need = cmd === "M" || cmd === "L" ? 2 : cmd === "Q" ? 4 : cmd === "C" ? 6 : cmd === "A" ? 7 : 0;
13318
13377
  if (need > 0 && (args.length < need || !args.slice(0, need).every(Number.isFinite))) continue;
13319
13378
  if (cmd === "M") {
13320
13379
  cur = { x: args[0], y: args[1] };
@@ -13344,6 +13403,10 @@ function extractPathSegments(d) {
13344
13403
  ctrl: [{ x: args[0], y: args[1] }, { x: args[2], y: args[3] }]
13345
13404
  });
13346
13405
  cur = next;
13406
+ } else if (cmd === "A") {
13407
+ const next = { x: args[5], y: args[6] };
13408
+ segs.push({ x1: cur.x, y1: cur.y, x2: next.x, y2: next.y, cmd: "A" });
13409
+ cur = next;
13347
13410
  }
13348
13411
  }
13349
13412
  return segs;
@@ -13635,10 +13698,10 @@ function forEachCandidatePair(bboxes, margin, visit) {
13635
13698
  }
13636
13699
  }
13637
13700
  }
13638
- function resolveEdgeLabelOverlapsWithChain(edges, fixedObstacles, minClearance = 16, maxIter = 20) {
13701
+ function resolveEdgeLabelOverlapsWithChain(edges, fixedObstacles, minClearance = 16, maxIter = 20, textMetrics = "proportional") {
13639
13702
  if (edges.length === 0) return edges;
13640
13703
  const labelBBox = (e, offsetX, offsetY) => {
13641
- const base = computeLabelBBoxWorld(e);
13704
+ const base = computeLabelBBoxWorld(e, textMetrics);
13642
13705
  return {
13643
13706
  kind: "edge-label",
13644
13707
  id: e.id,
@@ -13739,7 +13802,7 @@ function clampShiftMagnitude(shift, maxMagnitude) {
13739
13802
  };
13740
13803
  return { dx: clampAxis(shift.dx), dy: clampAxis(shift.dy) };
13741
13804
  }
13742
- function resolveEdgeLabelOverlapsWithChainAndPropagate(edges, obstacles, minClearance = 16, maxIter = 20, pathLabelClearance = LABEL_TO_PATH_CLEARANCE) {
13805
+ function resolveEdgeLabelOverlapsWithChainAndPropagate(edges, obstacles, minClearance = 16, maxIter = 20, pathLabelClearance = LABEL_TO_PATH_CLEARANCE, textMetrics = "proportional") {
13743
13806
  if (edges.length === 0) {
13744
13807
  return {
13745
13808
  edges,
@@ -13750,7 +13813,7 @@ function resolveEdgeLabelOverlapsWithChainAndPropagate(edges, obstacles, minClea
13750
13813
  }
13751
13814
  const MAX_ACCUMULATED_SHIFT = CHAIN_SHIFT_MAX_ACCUMULATED;
13752
13815
  const labelBBox = (e, offsetX, offsetY) => {
13753
- const base = computeLabelBBoxWorld(e);
13816
+ const base = computeLabelBBoxWorld(e, textMetrics);
13754
13817
  return {
13755
13818
  kind: "edge-label",
13756
13819
  id: e.id,
@@ -14351,11 +14414,15 @@ var \u5411\u304D\u306E\u9806 = [
14351
14414
  { axis: "x", sign: -1, \u540D\u524D: "\u5DE6" },
14352
14415
  { axis: "x", sign: 1, \u540D\u524D: "\u53F3" }
14353
14416
  ];
14354
- function \u672D\u304C\u52D5\u3051\u306A\u3044\u7406\u7531(labelId, \u76F8\u624B, edges, obstacles) {
14417
+ function \u672D\u304C\u52D5\u3051\u306A\u3044\u7406\u7531(labelId, \u76F8\u624B, edges, obstacles, textMetrics = "proportional") {
14355
14418
  const edgeById = new Map(edges.map((e) => [e.id, e]));
14356
14419
  const \u81EA\u5206 = edgeById.get(labelId);
14357
14420
  if (!\u81EA\u5206) return null;
14358
- const labels = edges.filter((e) => e.label?.trim() || e.sub?.trim()).map((e) => ({ kind: "edge-label", id: e.id, ...computeLabelBBoxWorld(e) }));
14421
+ const labels = edges.filter((e) => e.label?.trim() || e.sub?.trim()).map((e) => ({
14422
+ kind: "edge-label",
14423
+ id: e.id,
14424
+ ...computeLabelBBoxWorld(e, textMetrics)
14425
+ }));
14359
14426
  const label = labels.find((l) => l.id === labelId);
14360
14427
  if (!label) return null;
14361
14428
  const \u6E2C\u308A\u65B9 = \u7DDA\u306E\u6E2C\u308A\u65B9\u3092\u4F5C\u308B();
@@ -14397,7 +14464,7 @@ function \u672D\u304C\u52D5\u3051\u306A\u3044\u7406\u7531(labelId, \u76F8\u624B,
14397
14464
  }
14398
14465
  return `\u9003\u3052\u5834\u306A\u3057: ${\u7406\u7531.sort((a, b) => a.\u9806 - b.\u9806).map((r) => r.\u6587).join(" / ")}`;
14399
14466
  }
14400
- function resolveLabelClearanceAfterPathPasses(edges, obstacles, maxIter = 8) {
14467
+ function resolveLabelClearanceAfterPathPasses(edges, obstacles, maxIter = 8, textMetrics = "proportional") {
14401
14468
  if (edges.length === 0) return edges;
14402
14469
  const labeledIds = new Set(
14403
14470
  edges.filter((e) => e.label?.trim() || e.sub?.trim()).map((e) => e.id)
@@ -14415,7 +14482,7 @@ function resolveLabelClearanceAfterPathPasses(edges, obstacles, maxIter = 8) {
14415
14482
  const out = [];
14416
14483
  for (const e of edges) {
14417
14484
  if (!labeledIds.has(e.id)) continue;
14418
- const base = computeLabelBBoxWorld(e);
14485
+ const base = computeLabelBBoxWorld(e, textMetrics);
14419
14486
  const s = getShift(e.id);
14420
14487
  out.push({ kind: "edge-label", id: e.id, x: base.x + s.dx, y: base.y + s.dy, w: base.w, h: base.h });
14421
14488
  }
@@ -14546,6 +14613,232 @@ function applyEdgeLabelAndPathShifts(edges, labelShiftMap, edgePathShiftMap) {
14546
14613
  });
14547
14614
  }
14548
14615
 
14616
+ // src/layout/curve-path.ts
14617
+ var SAME_HEIGHT_THRESHOLD = 1;
14618
+ function curvePath(from, to, edge, labelMarginExtra = 0, textMetrics = "proportional") {
14619
+ const fromLeft = from.cx - from.w / 2;
14620
+ const fromRight = from.cx + from.w / 2;
14621
+ const toLeft = to.cx - to.w / 2;
14622
+ const toRight = to.cx + to.w / 2;
14623
+ let fromSide;
14624
+ let toSide;
14625
+ let x1;
14626
+ let x2;
14627
+ if (toLeft >= fromRight) {
14628
+ fromSide = "right";
14629
+ toSide = "left";
14630
+ x1 = fromRight;
14631
+ x2 = toLeft;
14632
+ } else if (toRight <= fromLeft) {
14633
+ fromSide = "left";
14634
+ toSide = "right";
14635
+ x1 = fromLeft;
14636
+ x2 = toRight;
14637
+ } else {
14638
+ fromSide = "right";
14639
+ toSide = "right";
14640
+ x1 = fromRight;
14641
+ x2 = toRight;
14642
+ }
14643
+ const y1 = from.cy;
14644
+ const y2 = to.cy;
14645
+ const sameHeight = Math.abs(y2 - y1) < SAME_HEIGHT_THRESHOLD;
14646
+ let d;
14647
+ let midX;
14648
+ let midY;
14649
+ let tangentX;
14650
+ let tangentY;
14651
+ if (sameHeight) {
14652
+ d = `M ${x1} ${y1} L ${x2} ${y2}`;
14653
+ midX = (x1 + x2) / 2;
14654
+ midY = (y1 + y2) / 2;
14655
+ tangentX = x2 - x1;
14656
+ tangentY = y2 - y1;
14657
+ } else {
14658
+ let c1x;
14659
+ let c2x;
14660
+ if (fromSide !== toSide) {
14661
+ const direction = x2 > x1 ? 1 : -1;
14662
+ const bulge = Math.max(Math.abs(x2 - x1) / 2, EDGE_STUB_OUT);
14663
+ c1x = x1 + direction * bulge;
14664
+ c2x = x2 - direction * bulge;
14665
+ } else {
14666
+ const bulgeX = Math.max(x1, x2) + EDGE_STUB_OUT;
14667
+ c1x = bulgeX;
14668
+ c2x = bulgeX;
14669
+ }
14670
+ d = `M ${x1} ${y1} C ${c1x} ${y1}, ${c2x} ${y2}, ${x2} ${y2}`;
14671
+ midX = (x1 + 3 * c1x + 3 * c2x + x2) / 8;
14672
+ midY = (y1 + 3 * y1 + 3 * y2 + y2) / 8;
14673
+ tangentX = x2 + c2x - c1x - x1;
14674
+ tangentY = y2 + y2 - y1 - y1;
14675
+ }
14676
+ if (edge?.overlay) {
14677
+ return { d, fromSide, toSide, labelX: midX, labelY: midY, labelAnchor: "middle" };
14678
+ }
14679
+ const tangentLength = Math.hypot(tangentX, tangentY);
14680
+ let normalX = tangentY / tangentLength;
14681
+ let normalY = -tangentX / tangentLength;
14682
+ if (normalY > Number.EPSILON || Math.abs(normalY) <= Number.EPSILON && normalX < 0) {
14683
+ normalX *= -1;
14684
+ normalY *= -1;
14685
+ }
14686
+ const labelW = computeLabelBoxW(edge?.label, edge?.sub, textMetrics);
14687
+ const labelH = labelPillH(edge?.sub);
14688
+ const distance = labelPathClearanceHorizontal(edge) + (Math.abs(normalX) * labelW + Math.abs(normalY) * labelH) / 2 + labelMarginExtra;
14689
+ return {
14690
+ d,
14691
+ fromSide,
14692
+ toSide,
14693
+ labelX: midX + normalX * distance,
14694
+ labelY: midY + normalY * distance,
14695
+ labelAnchor: "middle"
14696
+ };
14697
+ }
14698
+
14699
+ // src/layout/metro-path.ts
14700
+ var METRO_CORNER_RADIUS = 24;
14701
+ var T = Math.SQRT2 - 1;
14702
+ function round2(v) {
14703
+ return Math.round(v * 100) / 100;
14704
+ }
14705
+ function point(p) {
14706
+ return `${round2(p.x)} ${round2(p.y)}`;
14707
+ }
14708
+ function add(p, v, scale) {
14709
+ return { x: p.x + v.x * scale, y: p.y + v.y * scale };
14710
+ }
14711
+ function polyline(points) {
14712
+ const distinct = points.filter((p, i) => {
14713
+ const previous = points[i - 1];
14714
+ return previous === void 0 || p.x !== previous.x || p.y !== previous.y;
14715
+ });
14716
+ return distinct.map((p, i) => `${i === 0 ? "M" : "L"} ${point(p)}`).join(" ");
14717
+ }
14718
+ function metroPath(from, to, edge, labelMarginExtra = 0, textMetrics = "proportional") {
14719
+ const fromLeft = from.cx - from.w / 2;
14720
+ const fromRight = from.cx + from.w / 2;
14721
+ const toLeft = to.cx - to.w / 2;
14722
+ const toRight = to.cx + to.w / 2;
14723
+ let fromSide;
14724
+ let toSide;
14725
+ let x1;
14726
+ let x2;
14727
+ let dir;
14728
+ if (toLeft >= fromRight) {
14729
+ fromSide = "right";
14730
+ toSide = "left";
14731
+ x1 = fromRight;
14732
+ x2 = toLeft;
14733
+ dir = 1;
14734
+ } else if (toRight <= fromLeft) {
14735
+ fromSide = "left";
14736
+ toSide = "right";
14737
+ x1 = fromLeft;
14738
+ x2 = toRight;
14739
+ dir = -1;
14740
+ } else {
14741
+ fromSide = "right";
14742
+ toSide = "right";
14743
+ x1 = fromRight;
14744
+ x2 = toRight;
14745
+ dir = 1;
14746
+ }
14747
+ const y1 = from.cy;
14748
+ const y2 = to.cy;
14749
+ const dy = y2 - y1;
14750
+ const sgn = Math.sign(dy);
14751
+ let d;
14752
+ let mid;
14753
+ let tangent;
14754
+ if (Math.abs(dy) < SAME_HEIGHT_THRESHOLD) {
14755
+ d = `M ${point({ x: x1, y: y1 })} L ${point({ x: x2, y: y2 })}`;
14756
+ mid = { x: (x1 + x2) / 2, y: (y1 + y2) / 2 };
14757
+ tangent = { x: x2 - x1, y: y2 - y1 };
14758
+ } else if (fromSide !== toSide && Math.abs(x2 - x1) >= Math.abs(dy)) {
14759
+ const horizontal = Math.abs(x2 - x1);
14760
+ const s = (horizontal - Math.abs(dy)) / 2;
14761
+ const p0 = { x: x1, y: y1 };
14762
+ const p1 = { x: x1 + dir * s, y: y1 };
14763
+ const p2 = { x: x2 - dir * s, y: y2 };
14764
+ const p3 = { x: x2, y: y2 };
14765
+ const u = { x: dir, y: 0 };
14766
+ const w = { x: dir / Math.SQRT2, y: sgn / Math.SQRT2 };
14767
+ const r = Math.min(
14768
+ METRO_CORNER_RADIUS,
14769
+ s / T,
14770
+ Math.SQRT2 * Math.abs(dy) / (2 * T)
14771
+ );
14772
+ const t = r * T;
14773
+ if (r >= 0.5) {
14774
+ const f1 = dir * sgn > 0 ? 1 : 0;
14775
+ d = [
14776
+ `M ${point(p0)}`,
14777
+ `L ${point(add(p1, u, -t))}`,
14778
+ `A ${round2(r)} ${round2(r)} 0 0 ${f1} ${point(add(p1, w, t))}`,
14779
+ `L ${point(add(p2, w, -t))}`,
14780
+ `A ${round2(r)} ${round2(r)} 0 0 ${1 - f1} ${point(add(p2, u, t))}`,
14781
+ `L ${point(p3)}`
14782
+ ].join(" ");
14783
+ } else {
14784
+ d = polyline([p0, p1, p2, p3]);
14785
+ }
14786
+ mid = { x: (x1 + x2) / 2, y: (y1 + y2) / 2 };
14787
+ tangent = w;
14788
+ } else {
14789
+ fromSide = "right";
14790
+ toSide = "right";
14791
+ x1 = fromRight;
14792
+ x2 = toRight;
14793
+ const xa = Math.max(x1, x2) + EDGE_STUB_OUT;
14794
+ const h = Math.abs(dy) / 2;
14795
+ const p0 = { x: x1, y: y1 };
14796
+ const p1 = { x: xa, y: y1 };
14797
+ const p2 = { x: xa + h, y: y1 + sgn * h };
14798
+ const p3 = { x: xa, y: y2 };
14799
+ const p4 = { x: x2, y: y2 };
14800
+ const u = { x: 1, y: 0 };
14801
+ const w1 = { x: 1 / Math.SQRT2, y: sgn / Math.SQRT2 };
14802
+ const w2 = { x: -1 / Math.SQRT2, y: sgn / Math.SQRT2 };
14803
+ const r = Math.min(METRO_CORNER_RADIUS, h);
14804
+ const t = r * T;
14805
+ const sweep = sgn > 0 ? 1 : 0;
14806
+ d = [
14807
+ `M ${point(p0)}`,
14808
+ `L ${point(add(p1, u, -t))}`,
14809
+ `A ${round2(r)} ${round2(r)} 0 0 ${sweep} ${point(add(p1, w1, t))}`,
14810
+ `L ${point(add(p2, w1, -r))}`,
14811
+ `A ${round2(r)} ${round2(r)} 0 0 ${sweep} ${point(add(p2, w2, r))}`,
14812
+ `L ${point(add(p3, w2, -t))}`,
14813
+ `A ${round2(r)} ${round2(r)} 0 0 ${sweep} ${point(add(p3, u, -t))}`,
14814
+ `L ${point(p4)}`
14815
+ ].join(" ");
14816
+ mid = { x: p2.x - T * r, y: p2.y };
14817
+ tangent = { x: 0, y: sgn };
14818
+ }
14819
+ if (edge?.overlay) {
14820
+ return { d, fromSide, toSide, labelX: mid.x, labelY: mid.y, labelAnchor: "middle" };
14821
+ }
14822
+ const tangentLength = Math.hypot(tangent.x, tangent.y);
14823
+ let normalX = tangent.y / tangentLength;
14824
+ let normalY = -tangent.x / tangentLength;
14825
+ if (normalY > Number.EPSILON || Math.abs(normalY) <= Number.EPSILON && normalX < 0) {
14826
+ normalX *= -1;
14827
+ normalY *= -1;
14828
+ }
14829
+ const labelW = computeLabelBoxW(edge?.label, edge?.sub, textMetrics);
14830
+ const labelH = labelPillH(edge?.sub);
14831
+ const distance = labelPathClearanceHorizontal(edge) + (Math.abs(normalX) * labelW + Math.abs(normalY) * labelH) / 2 + labelMarginExtra;
14832
+ return {
14833
+ d,
14834
+ fromSide,
14835
+ toSide,
14836
+ labelX: mid.x + normalX * distance,
14837
+ labelY: mid.y + normalY * distance,
14838
+ labelAnchor: "middle"
14839
+ };
14840
+ }
14841
+
14549
14842
  // src/types.ts
14550
14843
  var TONES = ["accent", "teal", "success", "error", "warning", "info"];
14551
14844
  var NODE_KINDS = [
@@ -14673,6 +14966,8 @@ var NODE_KINDS = [
14673
14966
  // 状態遷移図が使う。 印そのものが意味を持つので文字は描かない
14674
14967
  "mark-start",
14675
14968
  "mark-end",
14969
+ // 路線図の駅 (#996) ... 線路上の点を小さな丸で示し、名前と説明は丸の外に置く
14970
+ "station",
14676
14971
  // 時系列のやり取り (#578) ... 1 つの箱が図を丸ごと描く。 縦が時間で、参加者は箱を持たない
14677
14972
  "sequence-board"
14678
14973
  ];
@@ -14700,9 +14995,9 @@ function \u66F8\u3044\u305F\u5024\u304B\u63A7\u3048(\u66F8\u3044\u305F, \u63A7\u
14700
14995
  const v = (\u66F8\u3044\u305F ?? "").trim();
14701
14996
  return v === "" ? \u63A7\u3048 : v;
14702
14997
  }
14703
- function \u5E45\u306E\u500D\u7387(text, size, letterSpacing, \u5E45) {
14998
+ function \u5E45\u306E\u500D\u7387(text, size, letterSpacing, \u5E45, textMetrics = "proportional") {
14704
14999
  if (!(\u5E45 > 0) || !(size > 0)) return 1;
14705
- const \u5B9F\u5E45 = textWidth(text, size, letterSpacing);
15000
+ const \u5B9F\u5E45 = textWidth(text, size, letterSpacing, textMetrics);
14706
15001
  return \u5B9F\u5E45 > \u5E45 ? \u5E45 / \u5B9F\u5E45 : 1;
14707
15002
  }
14708
15003
  function \u8AAD\u3081\u308B\u4E0B\u9650\u306E\u500D\u7387(\u5927\u304D\u3055) {
@@ -14917,13 +15212,13 @@ function fitArt(region, extent, art) {
14917
15212
  );
14918
15213
  }
14919
15214
  var \u5E2F\u306E\u9AD8\u3055\u306B\u5BFE\u3059\u308B\u4E0A\u9650 = 0.8;
14920
- function \u7D75\u306E\u4E2D\u306E\u5B57\u306E\u5E45(text, size, letterSpacing = 0) {
15215
+ function \u7D75\u306E\u4E2D\u306E\u5B57\u306E\u5E45(text, size, letterSpacing = 0, textMetrics = "proportional") {
14921
15216
  return Math.max(
14922
15217
  displayWidth(text) * size * MONO_ADVANCE_RATIO,
14923
- textWidth(text, size, letterSpacing)
15218
+ textWidth(text, size, letterSpacing, textMetrics)
14924
15219
  );
14925
15220
  }
14926
- function \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u5B57\u3089) {
15221
+ function \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u5B57\u3089, textMetrics = "proportional") {
14927
15222
  const \u623B\u3057 = Number.isFinite(\u500D\u7387) && \u500D\u7387 > 0 ? 1 / \u500D\u7387 : 1;
14928
15223
  let \u4E0A\u9650 = Number.POSITIVE_INFINITY;
14929
15224
  for (const \u5B572 of \u5B57\u3089) {
@@ -14932,7 +15227,7 @@ function \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u5B57\u3089)
14932
15227
  if (Number.isFinite(\u9AD8\u3055) && \u9AD8\u3055 > 0) {
14933
15228
  \u4E0A\u9650 = Math.min(\u4E0A\u9650, \u9AD8\u3055 * \u5E2F\u306E\u9AD8\u3055\u306B\u5BFE\u3059\u308B\u4E0A\u9650 / \u5B572.size);
14934
15229
  }
14935
- const \u5B9F\u5E45 = \u7D75\u306E\u4E2D\u306E\u5B57\u306E\u5E45(\u5B572.text, \u5B572.size, \u5B572.letterSpacing ?? 0);
15230
+ const \u5B9F\u5E45 = \u7D75\u306E\u4E2D\u306E\u5B57\u306E\u5E45(\u5B572.text, \u5B572.size, \u5B572.letterSpacing ?? 0, textMetrics);
14936
15231
  if (Number.isFinite(\u5E45) && \u5E45 > 0 && \u5B9F\u5E45 > 0) {
14937
15232
  \u4E0A\u9650 = Math.min(\u4E0A\u9650, \u5E45 / \u5B9F\u5E45);
14938
15233
  }
@@ -15788,9 +16083,14 @@ function \u6728\u306E\u5F62(treeNodes) {
15788
16083
  return { \u8449\u306E\u6570, \u6BB5\u6570 };
15789
16084
  }
15790
16085
  var \u6728\u306E\u679D\u306E\u592A\u3055 = (\u6BB5) => Math.max(1.1, 2.6 - \u6BB5 * 0.45);
15791
- function \u6728\u306E\u4E2D\u8EAB(node, stateValues = {}) {
16086
+ function \u6728\u306E\u4E2D\u8EAB(node, stateValues = {}, textMetrics = "proportional") {
15792
16087
  const treeNodes = resolveTreeData(node.treeData ?? [], stateValues);
15793
- return computeTreeLayout(treeNodes, node.w - PAD_LEFT - PAD_RIGHT, node.h - PAD_TOP - PAD_BOTTOM);
16088
+ return computeTreeLayout(
16089
+ treeNodes,
16090
+ node.w - PAD_LEFT - PAD_RIGHT,
16091
+ node.h - PAD_TOP - PAD_BOTTOM,
16092
+ textMetrics
16093
+ );
15794
16094
  }
15795
16095
  function \u6728\u306E\u884C(n) {
15796
16096
  return [
@@ -15803,12 +16103,14 @@ function TreeNode({
15803
16103
  active,
15804
16104
  stateValues = {},
15805
16105
  drawing = false,
15806
- progress = 1
16106
+ progress = 1,
16107
+ textMetrics = "proportional"
15807
16108
  }) {
15808
16109
  const x0 = node.cx - node.w / 2;
15809
16110
  const y0 = node.cy - node.h / 2;
15810
16111
  const gradientId = `tree-root-grad-${node.id}`;
15811
- const layout2 = \u6728\u306E\u4E2D\u8EAB(node, stateValues);
16112
+ const layout2 = \u6728\u306E\u4E2D\u8EAB(node, stateValues, textMetrics);
16113
+ const \u6E2C\u308B = \u7BB1\u306E\u5B57\u3092\u6E2C\u308B(textMetrics);
15812
16114
  const \u4F38\u3073 = \u9032\u307F\u3092\u7573\u3080(drawing, progress);
15813
16115
  const \u6700\u5927\u6DF1\u3055 = layout2.nodes.reduce((m, n) => Math.max(m, n.depth), 0);
15814
16116
  const \u7BB1\u304C\u51FA\u308B = (\u6DF1\u3055) => !drawing || \u6BB5\u306E\u4F38\u3073(\u4F38\u3073, \u6DF1\u3055, \u6700\u5927\u6DF1\u3055) >= 1;
@@ -15862,10 +16164,10 @@ function TreeNode({
15862
16164
  const accent = depthColors[Math.min(n.depth, depthColors.length - 1)] ?? depthColors[0];
15863
16165
  const isRoot = n.depth === 0;
15864
16166
  const \u6750\u6599 = \u6728\u306E\u884C(n);
15865
- const \u884C = \u7BB1\u306B\u7A4D\u3080(\u6750\u6599, n.w, n.h);
16167
+ const \u884C = \u7BB1\u306B\u7A4D\u3080(\u6750\u6599, n.w, n.h, \u6E2C\u308B);
15866
16168
  const \u88DC\u8DB3\u3042\u308A = (n.subtitle ?? "").trim() !== "";
15867
16169
  const \u540D\u524D = \u6750\u6599[0];
15868
- const \u53CE\u3081\u305F\u540D\u524D = \u88DC\u8DB3\u3042\u308A ? void 0 : \u5E45\u306B\u53CE\u3081\u308B(\u540D\u524D.text, \u540D\u524D.fontSize, \u4F7F\u3048\u308B\u5E45(n.w));
16170
+ const \u53CE\u3081\u305F\u540D\u524D = \u88DC\u8DB3\u3042\u308A ? void 0 : \u5E45\u306B\u53CE\u3081\u308B(\u540D\u524D.text, \u540D\u524D.fontSize, \u4F7F\u3048\u308B\u5E45(n.w), \u6E2C\u308B);
15869
16171
  return /* @__PURE__ */ jsx(
15870
16172
  "g",
15871
16173
  {
@@ -15947,7 +16249,7 @@ function TreeNode({
15947
16249
  })
15948
16250
  ] });
15949
16251
  }
15950
- function computeTreeLayout(treeNodes, canvasW, canvasH) {
16252
+ function computeTreeLayout(treeNodes, canvasW, canvasH, textMetrics = "proportional") {
15951
16253
  const ids = new Set(treeNodes.map((n) => n.id));
15952
16254
  const childrenOf = /* @__PURE__ */ new Map();
15953
16255
  for (const n of treeNodes) {
@@ -15995,7 +16297,7 @@ function computeTreeLayout(treeNodes, canvasW, canvasH) {
15995
16297
  const \u7BB1\u306E\u5E45 = (n, depth) => {
15996
16298
  const \u6750\u6599 = \u6728\u306E\u884C({ ...n, depth });
15997
16299
  const \u540D\u524D = \u6750\u6599[0];
15998
- const \u8981\u308B = measureTextWidth(\u540D\u524D.text, { fontSize: \u540D\u524D.fontSize}) + (nodeW - \u4F7F\u3048\u308B\u5E45(nodeW));
16300
+ const \u8981\u308B = measureTextWidth(\u540D\u524D.text, { fontSize: \u540D\u524D.fontSize, textMetrics }) + (nodeW - \u4F7F\u3048\u308B\u5E45(nodeW));
15999
16301
  return Math.min(Math.max(\u8981\u308B, nodeW), slotW * 0.92);
16000
16302
  };
16001
16303
  const \u8449\u306E\u4E26\u3073 = [];
@@ -16099,7 +16401,7 @@ var BRANCH_BOX_H_MAX = 48;
16099
16401
  var SUB_BOX_H_MAX = 40;
16100
16402
  var \u7E26\u306E\u9593\u9694\u306E\u4E0A\u9650 = (\u679D\u306E\u6A2A\u306E\u4F38\u3073) => \u679D\u306E\u6A2A\u306E\u4F38\u3073;
16101
16403
  var MIND_PAD = 40;
16102
- function \u653E\u5C04\u306E\u4E2D\u8EAB(node, stateValues = {}) {
16404
+ function \u653E\u5C04\u306E\u4E2D\u8EAB(node, stateValues = {}, textMetrics = "proportional") {
16103
16405
  const mindData = node.mindData ? resolveMindData(node.mindData, stateValues) : void 0;
16104
16406
  if (!mindData) return void 0;
16105
16407
  return computeMindMapLayout(
@@ -16107,7 +16409,8 @@ function \u653E\u5C04\u306E\u4E2D\u8EAB(node, stateValues = {}) {
16107
16409
  node.w / 2,
16108
16410
  node.h / 2,
16109
16411
  node.w - MIND_PAD * 2,
16110
- node.h - MIND_PAD * 2
16412
+ node.h - MIND_PAD * 2,
16413
+ textMetrics
16111
16414
  );
16112
16415
  }
16113
16416
  function \u653E\u5C04\u306E\u884C(n) {
@@ -16121,12 +16424,14 @@ function MindMapNode({
16121
16424
  active,
16122
16425
  stateValues = {},
16123
16426
  drawing = false,
16124
- progress = 1
16427
+ progress = 1,
16428
+ textMetrics = "proportional"
16125
16429
  }) {
16126
16430
  const x0 = node.cx - node.w / 2;
16127
16431
  const y0 = node.cy - node.h / 2;
16128
- const layout2 = \u653E\u5C04\u306E\u4E2D\u8EAB(node, stateValues);
16432
+ const layout2 = \u653E\u5C04\u306E\u4E2D\u8EAB(node, stateValues, textMetrics);
16129
16433
  if (!layout2) return /* @__PURE__ */ jsx("g", { transform: `translate(${x0} ${y0})` });
16434
+ const \u6E2C\u308B = \u7BB1\u306E\u5B57\u3092\u6E2C\u308B(textMetrics);
16130
16435
  const \u4F38\u3073 = \u9032\u307F\u3092\u7573\u3080(drawing, progress);
16131
16436
  const \u6700\u5927\u6DF1\u3055 = layout2.nodes.reduce((m, n) => Math.max(m, n.depth), 0);
16132
16437
  const \u7BB1\u304C\u51FA\u308B = (\u6DF1\u3055) => !drawing || \u6BB5\u306E\u4F38\u3073(\u4F38\u3073, \u6DF1\u3055, \u6700\u5927\u6DF1\u3055) >= 1;
@@ -16173,8 +16478,13 @@ function MindMapNode({
16173
16478
  const \u6587\u5B57\u306E\u5BC4\u305B = \u67A0\u306A\u3057 ? \u5916\u3078 ? "start" : "end" : "middle";
16174
16479
  const \u63CF\u753B\u57DF\u306E\u7AEF = \u5916\u3078 ? node.w - MIND_PAD : MIND_PAD;
16175
16480
  const \u4F7F\u3048\u308B = \u67A0\u306A\u3057 ? Math.abs(\u63CF\u753B\u57DF\u306E\u7AEF - \u6587\u5B57\u306Ex) : \u4F7F\u3048\u308B\u5E45(n.w);
16176
- const \u53CE\u3081\u305F\u540D\u524D = \u88DC\u8DB3\u3042\u308A ? void 0 : \u5E45\u306B\u53CE\u3081\u308B(\u540D\u524D.text, \u540D\u524D.fontSize, \u4F7F\u3048\u308B);
16177
- const \u884C = \u7BB1\u306B\u7A4D\u3080(\u6750\u6599, \u67A0\u306A\u3057 ? \u4F7F\u3048\u308B + (n.w - \u4F7F\u3048\u308B\u5E45(n.w)) : n.w, n.h);
16481
+ const \u53CE\u3081\u305F\u540D\u524D = \u88DC\u8DB3\u3042\u308A ? void 0 : \u5E45\u306B\u53CE\u3081\u308B(\u540D\u524D.text, \u540D\u524D.fontSize, \u4F7F\u3048\u308B, \u6E2C\u308B);
16482
+ const \u884C = \u7BB1\u306B\u7A4D\u3080(
16483
+ \u6750\u6599,
16484
+ \u67A0\u306A\u3057 ? \u4F7F\u3048\u308B + (n.w - \u4F7F\u3048\u308B\u5E45(n.w)) : n.w,
16485
+ n.h,
16486
+ \u6E2C\u308B
16487
+ );
16178
16488
  const \u6587\u5B57\u306E\u8272 = n.isRoot ? "var(--cdl-text-on-tone, #ffffff)" : "var(--cdl-chip-text, #1a1f2a)";
16179
16489
  return /* @__PURE__ */ jsxs("g", { "data-cdl-unresolved": n.unresolved ? "true" : void 0, children: [
16180
16490
  \u67A0\u306A\u3057 ? null : /* @__PURE__ */ jsx(
@@ -16226,14 +16536,14 @@ function MindMapNode({
16226
16536
  })
16227
16537
  ] });
16228
16538
  }
16229
- function \u63CF\u304F\u6A2A\u306E\u7AEF(n) {
16539
+ function \u63CF\u304F\u6A2A\u306E\u7AEF(n, textMetrics = "proportional") {
16230
16540
  if (n.isRoot || !n.isLeaf) return [n.x - n.w / 2, n.x + n.w / 2];
16231
16541
  const \u8D77\u70B9 = n.x + (n.side === "right" ? -n.w / 2 : n.w / 2);
16232
16542
  const \u540D\u524D = \u653E\u5C04\u306E\u884C(n)[0];
16233
- const \u5E45 = textWidth(\u540D\u524D.text, \u540D\u524D.fontSize);
16543
+ const \u5E45 = textWidth(\u540D\u524D.text, \u540D\u524D.fontSize, 0, textMetrics);
16234
16544
  return n.side === "right" ? [\u8D77\u70B9, \u8D77\u70B9 + \u5E45] : [\u8D77\u70B9 - \u5E45, \u8D77\u70B9];
16235
16545
  }
16236
- function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
16546
+ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH, textMetrics = "proportional") {
16237
16547
  const nodes = [];
16238
16548
  const edges = [];
16239
16549
  const rootW = 120;
@@ -16311,7 +16621,7 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
16311
16621
  const PREFERRED_GAP = MIND_BOX_GAP;
16312
16622
  const \u679D\u306E\u540D\u524D\u306E\u5E45 = (title) => {
16313
16623
  const \u540D\u524D = \u653E\u5C04\u306E\u884C({ title, isRoot: false })[0];
16314
- return textWidth(\u540D\u524D.text, \u540D\u524D.fontSize);
16624
+ return textWidth(\u540D\u524D.text, \u540D\u524D.fontSize, 0, textMetrics);
16315
16625
  };
16316
16626
  const \u679D\u306E\u6A2A\u3092\u6C7A\u3081\u308B = (br) => {
16317
16627
  const maxSubDepth = subDepthOf(br.id, /* @__PURE__ */ new Set());
@@ -16429,7 +16739,7 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
16429
16739
  let maxExtentX = rootW / 2;
16430
16740
  let maxExtentY = rootH / 2;
16431
16741
  for (const n of nodes) {
16432
- const [\u5DE6, \u53F3] = \u63CF\u304F\u6A2A\u306E\u7AEF(n);
16742
+ const [\u5DE6, \u53F3] = \u63CF\u304F\u6A2A\u306E\u7AEF(n, textMetrics);
16433
16743
  maxExtentX = Math.max(maxExtentX, Math.abs(\u5DE6 - cx), Math.abs(\u53F3 - cx));
16434
16744
  maxExtentY = Math.max(maxExtentY, Math.abs(n.y - cy) + n.h / 2);
16435
16745
  }
@@ -16449,7 +16759,7 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
16449
16759
  let \u5DE6\u7AEF = Number.POSITIVE_INFINITY;
16450
16760
  let \u53F3\u7AEF = Number.NEGATIVE_INFINITY;
16451
16761
  for (const n of nodes) {
16452
- const [l, r] = \u63CF\u304F\u6A2A\u306E\u7AEF(n);
16762
+ const [l, r] = \u63CF\u304F\u6A2A\u306E\u7AEF(n, textMetrics);
16453
16763
  \u5DE6\u7AEF = Math.min(\u5DE6\u7AEF, l);
16454
16764
  \u53F3\u7AEF = Math.max(\u53F3\u7AEF, r);
16455
16765
  }
@@ -16692,10 +17002,16 @@ function emptyCounts() {
16692
17002
  "validation-interrupted": 0
16693
17003
  };
16694
17004
  }
16695
- function \u7A4D\u3080\u7BB1\u3092\u96C6\u3081\u308B(n) {
16696
- const \u7BB1 = (b, \u884C) => ({ \u884C, w: b.w, h: b.h });
16697
- if (n.kind === "tree-hierarchy") return \u6728\u306E\u4E2D\u8EAB(n).nodes.map((b) => \u7BB1(b, \u6728\u306E\u884C(b)));
16698
- if (n.kind === "mind-map") return (\u653E\u5C04\u306E\u4E2D\u8EAB(n)?.nodes ?? []).map((b) => \u7BB1(b, \u653E\u5C04\u306E\u884C(b)));
17005
+ function \u7A4D\u3080\u7BB1\u3092\u96C6\u3081\u308B(n, textMetrics = "proportional") {
17006
+ const \u7BB1 = (b, \u884C, \u6E2C\u308B) => ({ \u884C, w: b.w, h: b.h, \u6E2C\u308B });
17007
+ if (n.kind === "tree-hierarchy") {
17008
+ const \u6E2C\u308B = \u7BB1\u306E\u5B57\u3092\u6E2C\u308B(textMetrics);
17009
+ return \u6728\u306E\u4E2D\u8EAB(n, {}, textMetrics).nodes.map((b) => \u7BB1(b, \u6728\u306E\u884C(b), \u6E2C\u308B));
17010
+ }
17011
+ if (n.kind === "mind-map") {
17012
+ const \u6E2C\u308B = \u7BB1\u306E\u5B57\u3092\u6E2C\u308B(textMetrics);
17013
+ return (\u653E\u5C04\u306E\u4E2D\u8EAB(n, {}, textMetrics)?.nodes ?? []).map((b) => \u7BB1(b, \u653E\u5C04\u306E\u884C(b), \u6E2C\u308B));
17014
+ }
16699
17015
  return [];
16700
17016
  }
16701
17017
  function measureStubOut(segs) {
@@ -17381,9 +17697,11 @@ function \u4F4D\u7F6E\u3092\u624B\u3067\u66F8\u3044\u305F(n) {
17381
17697
  return n.posX !== void 0 && n.posY !== void 0;
17382
17698
  }
17383
17699
  function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5668) {
17700
+ const textMetrics = laid.textMetrics ?? "proportional";
17384
17701
  const LIFELINE_W_THRESHOLD = 8;
17385
17702
  for (const n of laid.nodes) {
17386
17703
  if (n.w < LIFELINE_W_THRESHOLD) continue;
17704
+ if (n.kind === "station") continue;
17387
17705
  if (n.w < MIN_NODE_W || n.h < MIN_NODE_H) {
17388
17706
  push(
17389
17707
  "node-visibility",
@@ -17391,7 +17709,7 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
17391
17709
  );
17392
17710
  }
17393
17711
  }
17394
- const bboxes = collectBBoxes(laid.lanes, laid.nodes, laid.edges);
17712
+ const bboxes = collectBBoxes(laid.lanes, laid.nodes, laid.edges, textMetrics);
17395
17713
  const collisions = detectCollisions(bboxes, laid.edges);
17396
17714
  for (const c of collisions) {
17397
17715
  const involvesEdgeLabel = c.a.kind === "edge-label" || c.b.kind === "edge-label";
@@ -17405,12 +17723,17 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
17405
17723
  if (n.id.endsWith("-spacer")) continue;
17406
17724
  if (!rendersTitleText(n.kind)) continue;
17407
17725
  if (fitsOwnTitleWidth(n.kind)) continue;
17726
+ if (skipsNodeTitleWidthCheck(n.kind)) continue;
17408
17727
  if (!isRenderedNode(n)) continue;
17409
17728
  const titleTrimmed = n.title?.trim() ?? "";
17410
17729
  if (!titleTrimmed) continue;
17411
17730
  const \u4F59\u767D = drawsTitleOutsideBox(n.kind) ? 0 : TITLE_BOX_PADDING;
17412
17731
  const \u4F7F\u3048\u308B\u5E452 = n.w - \u4F59\u767D;
17413
- const \u5B9F\u5E45 = measureTextWidth(titleTrimmed, { fontSize: titleFontSize(n.kind), bound: "drawn" });
17732
+ const \u5B9F\u5E45 = measureTextWidth(titleTrimmed, {
17733
+ fontSize: titleFontSize(n.kind),
17734
+ bound: "drawn",
17735
+ textMetrics
17736
+ });
17414
17737
  if (titleScalesToFit(n.kind, n.h)) {
17415
17738
  const \u7E2E\u3081\u305F\u5927\u304D\u3055 = \u5B9F\u5E45 > 0 ? titleFontSize(n.kind) * Math.min(1, \u4F7F\u3048\u308B\u5E452 / \u5B9F\u5E45) : titleFontSize(n.kind);
17416
17739
  if (\u7E2E\u3081\u305F\u5927\u304D\u3055 < MIN_TITLE_FONT_SIZE) {
@@ -17478,7 +17801,13 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
17478
17801
  const b\u306F\u672D = n.b.kind === "edge-label";
17479
17802
  const \u52D5\u304B\u3059 = a\u306F\u672D && b\u306F\u672D ? (\u8FBA\u306E\u9806.get(n.a.id) ?? 0) > (\u8FBA\u306E\u9806.get(n.b.id) ?? 0) ? n.a : n.b : a\u306F\u672D ? n.a : b\u306F\u672D ? n.b : null;
17480
17803
  const \u76F8\u624B = \u52D5\u304B\u3059 === n.a ? n.b : n.a;
17481
- const reason = \u52D5\u304B\u3059 !== null ? \u672D\u304C\u52D5\u3051\u306A\u3044\u7406\u7531(\u52D5\u304B\u3059.id, \u76F8\u624B, laid.edges, \u672D\u306E\u969C\u5BB3\u7269) ?? void 0 : void 0;
17804
+ const reason = \u52D5\u304B\u3059 !== null ? \u672D\u304C\u52D5\u3051\u306A\u3044\u7406\u7531(
17805
+ \u52D5\u304B\u3059.id,
17806
+ \u76F8\u624B,
17807
+ laid.edges,
17808
+ \u672D\u306E\u969C\u5BB3\u7269,
17809
+ textMetrics
17810
+ ) ?? void 0 : void 0;
17482
17811
  push(
17483
17812
  "clearance",
17484
17813
  `${n.a.kind}:${n.a.id} \u2194 ${n.b.kind}:${n.b.id} gap=${n.gap.toFixed(1)}px (need ${n.required}px)`,
@@ -17492,7 +17821,10 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
17492
17821
  if (!hasRenderedLabel(e)) continue;
17493
17822
  const segs = extractPathSegments(e.d);
17494
17823
  if (segs.length === 0) continue;
17495
- const minDist = measurePathLabelGapSegs(flattenPathSegments(segs), computeLabelBBoxWorld(e));
17824
+ const minDist = measurePathLabelGapSegs(
17825
+ flattenPathSegments(segs),
17826
+ computeLabelBBoxWorld(e, textMetrics)
17827
+ );
17496
17828
  if (!Number.isFinite(minDist)) continue;
17497
17829
  if (minDist > PROXIMITY_ERROR_THRESHOLD) {
17498
17830
  push(
@@ -17542,8 +17874,15 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
17542
17874
  }
17543
17875
  for (const e of laid.edges) {
17544
17876
  if (!hasRenderedLabel(e)) continue;
17545
- const mainW = measureTextWidth(e.label ?? "", { fontSize: EDGE_LABEL_TEXT.main.fontSize });
17546
- const subW = e.sub ? measureTextWidth(e.sub, { fontSize: EDGE_LABEL_TEXT.sub.fontSize, fontFamily: "mono" }) : 0;
17877
+ const mainW = measureTextWidth(e.label ?? "", {
17878
+ fontSize: EDGE_LABEL_TEXT.main.fontSize,
17879
+ textMetrics
17880
+ });
17881
+ const subW = e.sub ? measureTextWidth(e.sub, {
17882
+ fontSize: EDGE_LABEL_TEXT.sub.fontSize,
17883
+ fontFamily: "mono",
17884
+ textMetrics
17885
+ }) : 0;
17547
17886
  const expectedBoxW = Math.max(mainW, subW) + LABEL_PILL_PAD_X * 2;
17548
17887
  const bbox = bboxes.find((b) => b.kind === "edge-label" && b.id === e.id);
17549
17888
  if (!bbox) continue;
@@ -17685,7 +18024,9 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
17685
18024
  }
17686
18025
  }
17687
18026
  for (const n of laid.nodes) {
17688
- const \u843D\u3068\u3057\u305F = labelPlan(n).\u843D\u3068\u3057\u305F.filter((line) => droppedLineIsHidden(n.kind, line));
18027
+ const \u843D\u3068\u3057\u305F = labelPlan(n).\u843D\u3068\u3057\u305F.filter(
18028
+ (line) => droppedLineIsHidden(n.kind, line)
18029
+ );
17689
18030
  if (\u843D\u3068\u3057\u305F.length === 0) continue;
17690
18031
  push(
17691
18032
  "shape-label-dropped",
@@ -17694,7 +18035,7 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
17694
18035
  );
17695
18036
  }
17696
18037
  for (const n of laid.nodes) {
17697
- const \u7BB1 = \u7A4D\u3080\u7BB1\u3092\u96C6\u3081\u308B(n);
18038
+ const \u7BB1 = \u7A4D\u3080\u7BB1\u3092\u96C6\u3081\u308B(n, textMetrics);
17698
18039
  if (\u7BB1.length === 0) continue;
17699
18040
  let \u5BFE\u8C61 = 0;
17700
18041
  const \u843D\u3061\u305F = [];
@@ -17702,7 +18043,7 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
17702
18043
  const \u5BA3\u8A00 = b.\u884C.slice(1).filter((r) => r.text.trim() !== "");
17703
18044
  if (\u5BA3\u8A00.length === 0) continue;
17704
18045
  \u5BFE\u8C61 += 1;
17705
- const \u6B8B\u3063\u305F = new Set(\u7BB1\u306B\u7A4D\u3080(b.\u884C, b.w, b.h).map((r) => r.\u5F79\u5272));
18046
+ const \u6B8B\u3063\u305F = new Set(\u7BB1\u306B\u7A4D\u3080(b.\u884C, b.w, b.h, b.\u6E2C\u308B).map((r) => r.\u5F79\u5272));
17706
18047
  if (\u5BA3\u8A00.every((r) => \u6B8B\u3063\u305F.has(r.\u5F79\u5272))) continue;
17707
18048
  \u843D\u3061\u305F.push({ title: b.\u884C[0]?.text ?? "", h: b.h });
17708
18049
  }
@@ -18009,6 +18350,9 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
18009
18350
  for (let i = 0; i + 1 < sorted.length; i++) {
18010
18351
  const upper = sorted[i];
18011
18352
  const lower = sorted[i + 1];
18353
+ if (upper.cx + upper.w / 2 <= lower.cx - lower.w / 2 || lower.cx + lower.w / 2 <= upper.cx - upper.w / 2) {
18354
+ continue;
18355
+ }
18012
18356
  const upperBottom = upper.cy + upper.h / 2;
18013
18357
  const lowerTop = lower.cy - lower.h / 2;
18014
18358
  const gap = lowerTop - upperBottom;
@@ -18640,11 +18984,18 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
18640
18984
  {
18641
18985
  const crestSpans = (segs, peakY) => {
18642
18986
  const out = [];
18987
+ let \u5186\u5F27\u306E\u59CB\u70B9 = null;
18643
18988
  for (const s of segs) {
18644
- if (Math.abs(s.y1 - s.y2) > 1) continue;
18645
- if (Math.abs(s.y1 - peakY) > 1) continue;
18989
+ if (s.cmd === "A") {
18990
+ \u5186\u5F27\u306E\u59CB\u70B9 ??= { x: s.x1, y: s.y1 };
18991
+ continue;
18992
+ }
18993
+ const \u59CB\u70B9 = \u5186\u5F27\u306E\u59CB\u70B9 ?? { x: s.x1, y: s.y1 };
18994
+ \u5186\u5F27\u306E\u59CB\u70B9 = null;
18995
+ if (Math.abs(\u59CB\u70B9.y - s.y2) > 1) continue;
18996
+ if (Math.abs(\u59CB\u70B9.y - peakY) > 1) continue;
18646
18997
  if (s.cmd !== "L" && !(s.ctrl ?? []).every((c) => Math.abs(c.y - peakY) <= 1)) continue;
18647
- out.push({ minX: Math.min(s.x1, s.x2), maxX: Math.max(s.x1, s.x2) });
18998
+ out.push({ minX: Math.min(\u59CB\u70B9.x, s.x2), maxX: Math.max(\u59CB\u70B9.x, s.x2) });
18648
18999
  }
18649
19000
  return out;
18650
19001
  };
@@ -18755,7 +19106,7 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
18755
19106
  const allowedLanes = /* @__PURE__ */ new Set();
18756
19107
  if (fromNode) allowedLanes.add(fromNode.lane);
18757
19108
  if (toNode) allowedLanes.add(toNode.lane);
18758
- const box = computeLabelBBoxWorld(e);
19109
+ const box = computeLabelBBoxWorld(e, textMetrics);
18759
19110
  for (const lane of laid.lanes) {
18760
19111
  if (allowedLanes.has(lane.id)) continue;
18761
19112
  const side = rectCrossesLaneBorder(box, lane, rangeByLane.get(lane.id));
@@ -19133,7 +19484,7 @@ function pickFreeSides(occupied, count) {
19133
19484
  const \u4F7F\u3046 = \u7A7A\u304D.length > 0 ? \u7A7A\u304D : [SELF_LOOP_SIDE_FALLBACK];
19134
19485
  return Array.from({ length: count }, (_, i) => \u4F7F\u3046[i % \u4F7F\u3046.length]);
19135
19486
  }
19136
- function routeSelfLoopGroup(edges, node, side) {
19487
+ function routeSelfLoopGroup(edges, node, side, textMetrics = "proportional") {
19137
19488
  const horizontal = side === "left" || side === "right";
19138
19489
  const g = sideGeometry(node, side);
19139
19490
  const span = fitSpan(horizontal ? node.h : node.w, SELF_LOOP_SPAN);
@@ -19142,7 +19493,7 @@ function routeSelfLoopGroup(edges, node, side) {
19142
19493
  const \u6700\u5916 = controlOffset(SELF_LOOP_OUT + (edges.length - 1) * SELF_LOOP_STAGGER);
19143
19494
  const \u8A9E\u307E\u3067 = \u6700\u5916 + LABEL_TO_PATH_CLEARANCE;
19144
19495
  const \u8A9E\u5E45 = edges.map(
19145
- (e) => horizontal ? labelPillH(e.sub) : computeLabelBoxW(e.label, e.sub)
19496
+ (e) => horizontal ? labelPillH(e.sub) : computeLabelBoxW(e.label, e.sub, textMetrics)
19146
19497
  );
19147
19498
  const \u4F4D\u7F6E = [];
19148
19499
  let \u7A4D = 0;
@@ -19172,7 +19523,7 @@ function routeSelfLoopGroup(edges, node, side) {
19172
19523
  function isSelfLoop(e) {
19173
19524
  return e.from === e.to;
19174
19525
  }
19175
- function layoutSelfLoops(edges, nodes, occupiedBySide) {
19526
+ function layoutSelfLoops(edges, nodes, occupiedBySide, textMetrics = "proportional") {
19176
19527
  const \u5272\u5F53 = /* @__PURE__ */ new Map();
19177
19528
  for (const edge of edges) {
19178
19529
  if (edge.side) continue;
@@ -19199,7 +19550,7 @@ function layoutSelfLoops(edges, nodes, occupiedBySide) {
19199
19550
  if (\u65E2) \u65E2.edges.push(edge);
19200
19551
  else \u675F.set(key, { node, side, edges: [edge] });
19201
19552
  }
19202
- return [...\u675F.values()].flatMap((b) => routeSelfLoopGroup(b.edges, b.node, b.side));
19553
+ return [...\u675F.values()].flatMap((b) => routeSelfLoopGroup(b.edges, b.node, b.side, textMetrics));
19203
19554
  }
19204
19555
 
19205
19556
  // src/layout/tokens.ts
@@ -19335,6 +19686,8 @@ var TOKENS = {
19335
19686
  // 箱としての最小 (80x40) より大きく、名前を持つ箱 (card 320x150) よりは明らかに小さい
19336
19687
  "mark-start": { w: 96, h: 96 },
19337
19688
  "mark-end": { w: 96, h: 96 },
19689
+ // 路線図の駅 (#996) ... 正方形にして小さな丸が縦横どちらにも歪まないようにする。
19690
+ station: { w: 24, h: 24 },
19338
19691
  // 時系列のやり取り (#578)。 実寸は中身から決まる (`sequenceBoardMetrics`) ので、
19339
19692
  // ここは書かなかった時の受け皿
19340
19693
  "sequence-board": { w: 960, h: 640 }
@@ -19359,6 +19712,7 @@ var LANE_PAD_MIN = 25;
19359
19712
  // src/layout/edges.ts
19360
19713
  var VERTICAL_DETOUR_GAP = 50;
19361
19714
  var VERTICAL_DETOUR_CORNER = 14;
19715
+ var OVERLAY_LABEL_ON_PATH_TOLERANCE = 1;
19362
19716
  function verticalCornerDir(from, to) {
19363
19717
  return to < from ? -1 : 1;
19364
19718
  }
@@ -19414,7 +19768,7 @@ function verticalDetourBlockers(A, B, obstacles) {
19414
19768
  function detourColumnFor(blockers, side) {
19415
19769
  return side === "left" ? Math.min(...blockers.map((n) => n.cx - n.w / 2)) - VERTICAL_DETOUR_GAP : Math.max(...blockers.map((n) => n.cx + n.w / 2)) + VERTICAL_DETOUR_GAP;
19416
19770
  }
19417
- function layoutEdges(diag, nodes, lanes = []) {
19771
+ function layoutEdges(diag, nodes, lanes = [], textMetrics = "proportional") {
19418
19772
  const labelMarginExtra = (diag.viewport?.labelMargin ?? diag.viewport?.gap ?? DEFAULT_LABEL_MARGIN) - DEFAULT_LABEL_MARGIN;
19419
19773
  const nmap = new Map(nodes.map((n) => [n.id, n]));
19420
19774
  const lmap = new Map(lanes.map((l) => [l.id, l]));
@@ -19442,6 +19796,36 @@ function layoutEdges(diag, nodes, lanes = []) {
19442
19796
  });
19443
19797
  } else if (isSelfLoop(e)) {
19444
19798
  selfLoopEdges.push(e);
19799
+ } else if (e.routing === "curve") {
19800
+ const from = nmap.get(e.from);
19801
+ const to = nmap.get(e.to);
19802
+ if (!from) throw new Error(`cdl layout: edge "${e.id}" \u306E from "${e.from}" \u304C node \u306B\u7121\u3044`);
19803
+ if (!to) throw new Error(`cdl layout: edge "${e.id}" \u306E to "${e.to}" \u304C node \u306B\u7121\u3044`);
19804
+ const c = curvePath(from, to, e, labelMarginExtra, textMetrics);
19805
+ positionedEdges.push({
19806
+ ...e,
19807
+ d: c.d,
19808
+ fromSide: c.fromSide,
19809
+ toSide: c.toSide,
19810
+ labelX: c.labelX + (e.labelOffsetX ?? 0),
19811
+ labelY: c.labelY + (e.labelOffsetY ?? 0),
19812
+ labelAnchor: c.labelAnchor
19813
+ });
19814
+ } else if (e.routing === "metro") {
19815
+ const from = nmap.get(e.from);
19816
+ const to = nmap.get(e.to);
19817
+ if (!from) throw new Error(`cdl layout: edge "${e.id}" \u306E from "${e.from}" \u304C node \u306B\u7121\u3044`);
19818
+ if (!to) throw new Error(`cdl layout: edge "${e.id}" \u306E to "${e.to}" \u304C node \u306B\u7121\u3044`);
19819
+ const m = metroPath(from, to, e, labelMarginExtra, textMetrics);
19820
+ positionedEdges.push({
19821
+ ...e,
19822
+ d: m.d,
19823
+ fromSide: m.fromSide,
19824
+ toSide: m.toSide,
19825
+ labelX: m.labelX + (e.labelOffsetX ?? 0),
19826
+ labelY: m.labelY + (e.labelOffsetY ?? 0),
19827
+ labelAnchor: m.labelAnchor
19828
+ });
19445
19829
  } else {
19446
19830
  autoEdges.push(e);
19447
19831
  }
@@ -19480,7 +19864,7 @@ function layoutEdges(diag, nodes, lanes = []) {
19480
19864
  \u4F7F\u3046(le.from, le.fromSide);
19481
19865
  \u4F7F\u3046(le.to, le.toSide);
19482
19866
  }
19483
- const loopEdges = layoutSelfLoops(selfLoopEdges, nmap, occupiedBySide);
19867
+ const loopEdges = layoutSelfLoops(selfLoopEdges, nmap, occupiedBySide, textMetrics);
19484
19868
  const labelOffsetsByEdgeId = /* @__PURE__ */ new Map();
19485
19869
  const parallelKey = (p) => p.e.from < p.e.to ? `${p.e.from}::${p.e.to}` : `${p.e.to}::${p.e.from}`;
19486
19870
  const byParallel = /* @__PURE__ */ new Map();
@@ -19634,7 +20018,7 @@ function layoutEdges(diag, nodes, lanes = []) {
19634
20018
  const others = nodes.filter((n) => n.id !== c.from && n.id !== c.to);
19635
20019
  if (others.some((n) => segmentsCrossRect(segs, nodeRect(n)))) return true;
19636
20020
  if (!hasRenderedLabel(c.e)) return false;
19637
- const boxW = computeLabelBoxW(c.e.label, c.e.sub);
20021
+ const boxW = computeLabelBoxW(c.e.label, c.e.sub, textMetrics);
19638
20022
  const boxH = labelPillH(c.e.sub);
19639
20023
  const centerX = columnX - (labelPathClearanceHorizontal(c.e) + boxW / 2);
19640
20024
  const pill = { x: centerX - boxW / 2, y: (exitY + returnY) / 2 - boxH / 2, w: boxW, h: boxH };
@@ -19749,7 +20133,8 @@ function layoutEdges(diag, nodes, lanes = []) {
19749
20133
  allOtherNodes,
19750
20134
  { x: endpointOffset.fromDx, y: endpointOffset.fromDy },
19751
20135
  { x: endpointOffset.toDx, y: endpointOffset.toDy },
19752
- avoidRects
20136
+ avoidRects,
20137
+ textMetrics
19753
20138
  );
19754
20139
  const routed1 = route([]);
19755
20140
  const { d, labelX, labelY, labelAnchor, labelAltX } = routed1;
@@ -19805,13 +20190,13 @@ function layoutEdges(diag, nodes, lanes = []) {
19805
20190
  const pillById = /* @__PURE__ */ new Map();
19806
20191
  for (const r of list) {
19807
20192
  if (!hasRenderedLabel(r.e)) continue;
19808
- const w = computeLabelBoxW(r.e.label, r.e.sub);
20193
+ const w = computeLabelBoxW(r.e.label, r.e.sub, textMetrics);
19809
20194
  const h = labelPillH(r.e.sub);
19810
20195
  pillById.set(r.e.id, { x: r.baseLabelX - w / 2, y: r.baseLabelY - h / 2, w, h });
19811
20196
  }
19812
20197
  for (const le of positionedEdges) {
19813
20198
  if (!hasRenderedLabel(le)) continue;
19814
- const w = computeLabelBoxW(le.label, le.sub);
20199
+ const w = computeLabelBoxW(le.label, le.sub, textMetrics);
19815
20200
  const h = labelPillH(le.sub);
19816
20201
  pillById.set(le.id, { x: le.labelX - w / 2, y: le.labelY - h / 2, w, h });
19817
20202
  }
@@ -19841,7 +20226,7 @@ function layoutEdges(diag, nodes, lanes = []) {
19841
20226
  const laneOfNode = new Map(nodes.map((n) => [n.id, n.lane]));
19842
20227
  for (const r of flippable) {
19843
20228
  const ownSegs = segsByEdgeId.get(r.e.id);
19844
- const boxW = computeLabelBoxW(r.e.label, r.e.sub);
20229
+ const boxW = computeLabelBoxW(r.e.label, r.e.sub, textMetrics);
19845
20230
  const boxH = labelPillH(r.e.sub);
19846
20231
  const pillAt = (centerX) => ({
19847
20232
  x: centerX - boxW / 2,
@@ -19886,7 +20271,7 @@ function layoutEdges(diag, nodes, lanes = []) {
19886
20271
  if (list.length < 2) continue;
19887
20272
  const boxes = list.map((r) => ({
19888
20273
  cx: r.baseLabelX,
19889
- halfW: computeLabelBoxW(r.e.label, r.e.sub) / 2
20274
+ halfW: computeLabelBoxW(r.e.label, r.e.sub, textMetrics) / 2
19890
20275
  }));
19891
20276
  const overlapsX = (i, j) => Math.abs(boxes[i].cx - boxes[j].cx) < boxes[i].halfW + boxes[j].halfW + CLEARANCE_LABEL_LABEL;
19892
20277
  const componentOf = list.map((_, i) => i);
@@ -19936,7 +20321,7 @@ function layoutEdges(diag, nodes, lanes = []) {
19936
20321
  r,
19937
20322
  baseX: r.baseLabelX,
19938
20323
  baseY: r.baseLabelY,
19939
- w: computeLabelBoxW(r.e.label, r.e.sub),
20324
+ w: computeLabelBoxW(r.e.label, r.e.sub, textMetrics),
19940
20325
  h: labelPillH(r.e.sub)
19941
20326
  }));
19942
20327
  items.sort((a, b) => a.baseX - b.baseX);
@@ -20048,7 +20433,7 @@ function singleStraightSegment(d) {
20048
20433
  if (x1 === x2 && y1 === y2) return null;
20049
20434
  return { x1, y1, x2, y2 };
20050
20435
  }
20051
- function bowSharedStraightPaths(edges, nodes, skipIds) {
20436
+ function bowSharedStraightPaths(edges, nodes, skipIds, textMetrics = "proportional") {
20052
20437
  const groups = /* @__PURE__ */ new Map();
20053
20438
  for (const e of edges) {
20054
20439
  if (skipIds.has(e.id)) continue;
@@ -20084,7 +20469,7 @@ function bowSharedStraightPaths(edges, nodes, skipIds) {
20084
20469
  )
20085
20470
  );
20086
20471
  const groupIds = new Set(group.map((g) => g.e.id));
20087
- const labelRects = edges.filter((x) => hasRenderedLabel(x) && !groupIds.has(x.id)).map((x) => computeLabelBBoxWorld(x));
20472
+ const labelRects = edges.filter((x) => hasRenderedLabel(x) && !groupIds.has(x.id)).map((x) => computeLabelBBoxWorld(x, textMetrics));
20088
20473
  const nodeRects = nodes.map((n) => ({ x: n.cx - n.w / 2, y: n.cy - n.h / 2, w: n.w, h: n.h }));
20089
20474
  const build = (seg, offset) => {
20090
20475
  const cx = midX + nx * offset * 2;
@@ -20204,8 +20589,8 @@ function sidePoint(n, side) {
20204
20589
  return { x: n.cx + n.w / 2, y: n.cy };
20205
20590
  }
20206
20591
  }
20207
- function routePath(from, to, fromSide, toSide, obstacles = [], detourSide, _fromLane, _toLane, edge, labelObstacles = obstacles, fromOffset = { x: 0, y: 0 }, toOffset = { x: 0, y: 0 }, avoidRects = []) {
20208
- const labelBoxW = edge ? computeLabelBoxW(edge.label, edge.sub) : 0;
20592
+ function routePath(from, to, fromSide, toSide, obstacles = [], detourSide, _fromLane, _toLane, edge, labelObstacles = obstacles, fromOffset = { x: 0, y: 0 }, toOffset = { x: 0, y: 0 }, avoidRects = [], textMetrics = "proportional") {
20593
+ const labelBoxW = edge ? computeLabelBoxW(edge.label, edge.sub, textMetrics) : 0;
20209
20594
  const labelHalfW = labelBoxW / 2;
20210
20595
  const labelInit = labelInitClearance(edge);
20211
20596
  const verticalPair = fromSide === "bottom" && toSide === "top" || fromSide === "top" && toSide === "bottom";
@@ -20604,7 +20989,7 @@ function routePath(from, to, fromSide, toSide, obstacles = [], detourSide, _from
20604
20989
  labelAnchor: "middle"
20605
20990
  };
20606
20991
  }
20607
- function repositionParallelLabels(edges, nodes) {
20992
+ function repositionParallelLabels(edges, nodes, textMetrics = "proportional") {
20608
20993
  const allSegs = new Map(
20609
20994
  edges.map((e) => [e.id, flattenPathSegments(extractPathSegments(e.d))])
20610
20995
  );
@@ -20629,7 +21014,7 @@ function repositionParallelLabels(edges, nodes) {
20629
21014
  for (const pair of byPair.values()) {
20630
21015
  if (pair.length < 2) continue;
20631
21016
  const pairOrder = [...pair].sort(compareSharedPairOrder);
20632
- const boxes = pair.map((e) => computeLabelBBoxWorld(e));
21017
+ const boxes = pair.map((e) => computeLabelBBoxWorld(e, textMetrics));
20633
21018
  const componentOf = pair.map((_, i) => i);
20634
21019
  for (let i = 0; i < pair.length; i++) {
20635
21020
  for (let j = i + 1; j < pair.length; j++) {
@@ -20654,17 +21039,27 @@ function repositionParallelLabels(edges, nodes) {
20654
21039
  nodes,
20655
21040
  allEdges: edges,
20656
21041
  allSegs,
20657
- xRange
21042
+ xRange,
21043
+ textMetrics
20658
21044
  });
20659
21045
  for (let i = 0; i < members.length; i++) members[i].labelY = placed[i];
20660
21046
  }
20661
21047
  }
20662
21048
  }
20663
21049
  function placeAvoidingSiblingPaths(args) {
20664
- const { members, pair, pairOrder, nodes, allEdges, allSegs, xRange } = args;
21050
+ const {
21051
+ members,
21052
+ pair,
21053
+ pairOrder,
21054
+ nodes,
21055
+ allEdges,
21056
+ allSegs,
21057
+ xRange,
21058
+ textMetrics = "proportional"
21059
+ } = args;
20665
21060
  const sizes = members.map((e) => labelPillH(e.sub));
20666
21061
  const wants = members.map((e) => e.labelY);
20667
- const boxes = members.map((e) => computeLabelBBoxWorld(e));
21062
+ const boxes = members.map((e) => computeLabelBBoxWorld(e, textMetrics));
20668
21063
  const all = members.map((_, i) => i);
20669
21064
  const spread = (idx) => spreadWithMinimalShift(
20670
21065
  idx.map((i) => ({ want: wants[i], size: sizes[i] })),
@@ -20855,14 +21250,14 @@ function labelRectAt(cx, cy, w, h) {
20855
21250
  function inflate(r, pad) {
20856
21251
  return { x: r.x - pad, y: r.y - pad, w: r.w + pad * 2, h: r.h + pad * 2 };
20857
21252
  }
20858
- function slideLabelsAlongOwnPath(edges, nodes) {
21253
+ function slideLabelsAlongOwnPath(edges, nodes, textMetrics = "proportional") {
20859
21254
  const withLabel = edges.filter((e) => hasRenderedLabel(e));
20860
21255
  if (withLabel.length === 0) return;
20861
21256
  const segsById = /* @__PURE__ */ new Map();
20862
21257
  for (const e of edges) segsById.set(e.id, flattenPathSegments(extractPathSegments(e.d)));
20863
21258
  const nodeRects = nodes.map(nodeRect);
20864
21259
  for (const e of withLabel) {
20865
- const w = computeLabelBoxW(e.label, e.sub);
21260
+ const w = computeLabelBoxW(e.label, e.sub, textMetrics);
20866
21261
  const h = labelPillH(e.sub);
20867
21262
  if (w === 0 || h === 0) continue;
20868
21263
  const own = segsById.get(e.id) ?? [];
@@ -20946,9 +21341,11 @@ function hopEdgeCrossings(edges) {
20946
21341
  ends.set(e.id, pathEnds(segs));
20947
21342
  }
20948
21343
  for (const e of edges) {
21344
+ if (e.routing === "metro") continue;
20949
21345
  if ((e.d.match(/M/g) ?? []).length !== 1) continue;
20950
21346
  const own = extractPathSegments(e.d);
20951
21347
  if (own.length === 0) continue;
21348
+ if (own.some((s) => s.cmd === "A")) continue;
20952
21349
  const myEnds = ends.get(e.id) ?? [];
20953
21350
  const hops = /* @__PURE__ */ new Map();
20954
21351
  for (let i = 0; i < own.length; i++) {
@@ -21036,7 +21433,7 @@ function pathVertices(d) {
21036
21433
  const out = [{ x: first.x1, y: first.y1 }];
21037
21434
  for (let i = 0; i < segs.length; i++) {
21038
21435
  const s = segs[i];
21039
- if (s.cmd === "C") return null;
21436
+ if (s.cmd === "C" || s.cmd === "A") return null;
21040
21437
  if (s.cmd === "Q") {
21041
21438
  const c = s.ctrl?.[0];
21042
21439
  if (!c) return null;
@@ -21099,7 +21496,7 @@ function separateSharedStraightRuns(edges, nodes) {
21099
21496
  const v = pathVertices(e.d);
21100
21497
  if (v && v.length >= 2) verts.set(e.id, v);
21101
21498
  }
21102
- if (verts.size < 2) return;
21499
+ if (verts.size === 0) return;
21103
21500
  const moved = /* @__PURE__ */ new Set();
21104
21501
  const fits = (e, pts, k, ax, delta) => {
21105
21502
  const \u8A66\u3057 = pts.map(
@@ -21117,33 +21514,40 @@ function separateSharedStraightRuns(edges, nodes) {
21117
21514
  for (let j = i + 1; j < edges.length; j++) {
21118
21515
  const \u524D = edges[i];
21119
21516
  const \u5F8C = edges[j];
21120
- const A = verts.get(\u524D.id);
21121
- const B = verts.get(\u5F8C.id);
21122
- if (!A || !B) continue;
21123
- if (\u524D.from === \u5F8C.from) continue;
21517
+ if (\u524D.routing === "metro" && \u5F8C.routing === "metro") continue;
21518
+ const \u56FA\u5B9A = \u5F8C.routing === "metro" ? \u5F8C : \u524D;
21519
+ const \u52D5\u304B\u3059 = \u5F8C.routing === "metro" ? \u524D : \u5F8C;
21520
+ const B = verts.get(\u52D5\u304B\u3059.id);
21521
+ if (!B) continue;
21522
+ const \u56FA\u5B9A\u306E\u89D2 = verts.get(\u56FA\u5B9A.id);
21523
+ const \u56FA\u5B9A\u306E\u7D4C\u8DEF = \u56FA\u5B9A\u306E\u89D2 ? [\u56FA\u5B9A\u306E\u89D2] : \u56FA\u5B9A.routing === "metro" ? extractPathSegments(\u56FA\u5B9A.d).filter((s) => s.cmd === "L").map((s) => [{ x: s.x1, y: s.y1 }, { x: s.x2, y: s.y2 }]) : [];
21524
+ if (\u56FA\u5B9A\u306E\u7D4C\u8DEF.length === 0) continue;
21525
+ if (\u56FA\u5B9A.from === \u52D5\u304B\u3059.from) continue;
21124
21526
  for (const ax of [0, 1]) {
21125
- for (let ka = 0; ka + 1 < A.length; ka++) {
21126
- if (!runIsAligned(A, ka, ax)) continue;
21127
- for (let kb = 0; kb + 1 < B.length; kb++) {
21128
- if (!runIsAligned(B, kb, ax)) continue;
21129
- if (kb === 0 || kb + 1 === B.length - 1) continue;
21130
- const \u5EA7\u6A19A = ax === 0 ? A[ka].x : A[ka].y;
21131
- const \u5EA7\u6A19B = ax === 0 ? B[kb].x : B[kb].y;
21132
- if (Math.abs(\u5EA7\u6A19A - \u5EA7\u6A19B) > SHARED_RUN_EPS) continue;
21133
- const sa = runSpan(A, ka, ax);
21134
- const sb = runSpan(B, kb, ax);
21135
- if (Math.min(sa.hi, sb.hi) - Math.max(sa.lo, sb.lo) < SHARED_RUN_MIN) continue;
21136
- for (const delta of [SHARED_RUN_SEPARATION, -SHARED_RUN_SEPARATION]) {
21137
- if (!fits(\u5F8C, B, kb, ax, delta)) continue;
21138
- if (ax === 0) {
21139
- B[kb].x += delta;
21140
- B[kb + 1].x += delta;
21141
- } else {
21142
- B[kb].y += delta;
21143
- B[kb + 1].y += delta;
21527
+ for (const A of \u56FA\u5B9A\u306E\u7D4C\u8DEF) {
21528
+ for (let ka = 0; ka + 1 < A.length; ka++) {
21529
+ if (!runIsAligned(A, ka, ax)) continue;
21530
+ for (let kb = 0; kb + 1 < B.length; kb++) {
21531
+ if (!runIsAligned(B, kb, ax)) continue;
21532
+ if (kb === 0 || kb + 1 === B.length - 1) continue;
21533
+ const \u5EA7\u6A19A = ax === 0 ? A[ka].x : A[ka].y;
21534
+ const \u5EA7\u6A19B = ax === 0 ? B[kb].x : B[kb].y;
21535
+ if (Math.abs(\u5EA7\u6A19A - \u5EA7\u6A19B) > SHARED_RUN_EPS) continue;
21536
+ const sa = runSpan(A, ka, ax);
21537
+ const sb = runSpan(B, kb, ax);
21538
+ if (Math.min(sa.hi, sb.hi) - Math.max(sa.lo, sb.lo) < SHARED_RUN_MIN) continue;
21539
+ for (const delta of [SHARED_RUN_SEPARATION, -SHARED_RUN_SEPARATION]) {
21540
+ if (!fits(\u52D5\u304B\u3059, B, kb, ax, delta)) continue;
21541
+ if (ax === 0) {
21542
+ B[kb].x += delta;
21543
+ B[kb + 1].x += delta;
21544
+ } else {
21545
+ B[kb].y += delta;
21546
+ B[kb + 1].y += delta;
21547
+ }
21548
+ moved.add(\u52D5\u304B\u3059.id);
21549
+ break;
21144
21550
  }
21145
- moved.add(\u5F8C.id);
21146
- break;
21147
21551
  }
21148
21552
  }
21149
21553
  }
@@ -21155,7 +21559,7 @@ function separateSharedStraightRuns(edges, nodes) {
21155
21559
  e.d = verticesToPath(verts.get(e.id));
21156
21560
  }
21157
21561
  }
21158
- function pullOutgoingFirstCorner(edges, nodes) {
21562
+ function pullOutgoingFirstCorner(edges, nodes, textMetrics = "proportional") {
21159
21563
  if (edges.length < 2) return;
21160
21564
  const \u675F = /* @__PURE__ */ new Map();
21161
21565
  const \u540C\u3058\u7D44\u306E\u6570 = /* @__PURE__ */ new Map();
@@ -21170,12 +21574,19 @@ function pullOutgoingFirstCorner(edges, nodes) {
21170
21574
  let \u672D\u3092\u65E7\u7D4C\u8DEF\u3078\u8FFD\u5F93\u6E08\u307F = false;
21171
21575
  for (const list of \u675F.values()) {
21172
21576
  if (list.length < 2) continue;
21173
- const \u4E26\u3073 = list.flatMap((e) => {
21577
+ const \u4E26\u3073 = list.map((e) => {
21174
21578
  const pts = pathVertices(e.d);
21175
- if (!pts || pts.length < 2) return [];
21176
- return [{ e, pts, \u6700\u521D\u306E\u9577\u3055: Math.hypot(pts[1].x - pts[0].x, pts[1].y - pts[0].y) }];
21177
- }).sort((a, b) => b.\u6700\u521D\u306E\u9577\u3055 - a.\u6700\u521D\u306E\u9577\u3055);
21579
+ if (pts && pts.length >= 2) {
21580
+ return { e, pts, \u6700\u521D\u306E\u9577\u3055: Math.hypot(pts[1].x - pts[0].x, pts[1].y - pts[0].y) };
21581
+ }
21582
+ if (e.routing !== "metro") return null;
21583
+ const first = extractPathSegments(e.d)[0];
21584
+ if (!first) return null;
21585
+ return { e, pts: null, \u6700\u521D\u306E\u9577\u3055: Math.hypot(first.x2 - first.x1, first.y2 - first.y1) };
21586
+ }).filter((x) => x !== null).sort((a, b) => b.\u6700\u521D\u306E\u9577\u3055 - a.\u6700\u521D\u306E\u9577\u3055);
21178
21587
  for (const { e, pts, \u6700\u521D\u306E\u9577\u3055 } of \u4E26\u3073.slice(1)) {
21588
+ if (e.routing === "metro") continue;
21589
+ if (!pts) continue;
21179
21590
  if ((\u540C\u3058\u7D44\u306E\u6570.get(`${e.from}->${e.to}`) ?? 0) > 1) continue;
21180
21591
  if (pts.length < 3 || \u6700\u521D\u306E\u9577\u3055 <= EDGE_STUB_OUT + VERTICAL_DETOUR_CORNER) continue;
21181
21592
  const \u6A2A = e.fromSide === "left" || e.fromSide === "right";
@@ -21202,10 +21613,10 @@ function pullOutgoingFirstCorner(edges, nodes) {
21202
21613
  }
21203
21614
  e.d = \u524D;
21204
21615
  if (!\u672D\u3092\u65E7\u7D4C\u8DEF\u3078\u8FFD\u5F93\u6E08\u307F) {
21205
- slideLabelsAlongOwnPath(edges, nodes);
21616
+ slideLabelsAlongOwnPath(edges, nodes, textMetrics);
21206
21617
  \u672D\u3092\u65E7\u7D4C\u8DEF\u3078\u8FFD\u5F93\u6E08\u307F = true;
21207
21618
  }
21208
- const labelBox = computeLabelBBoxWorld(e);
21619
+ const labelBox = computeLabelBBoxWorld(e, textMetrics);
21209
21620
  const label = { x: labelBox.x + labelBox.w / 2, y: labelBox.y + labelBox.h / 2 };
21210
21621
  const \u7DDA\u5206\u307E\u3067\u306E\u8DDD\u96E22 = (a, b) => {
21211
21622
  const dx = b.x - a.x;
@@ -21229,7 +21640,8 @@ var ENDPOINT_FAN_MIN = 20;
21229
21640
  var ENDPOINT_FAN_RUNUP = 40;
21230
21641
  var MIXED_ROOT_OVERLAP_MIN = 24;
21231
21642
  function fanIncomingEndpoints(edges, nodes) {
21232
- if (edges.length < 2) return;
21643
+ const \u7D42\u70B9\u306E\u79FB\u52D5 = /* @__PURE__ */ new Map();
21644
+ if (edges.length < 2) return \u7D42\u70B9\u306E\u79FB\u52D5;
21233
21645
  const nmap = new Map(nodes.map((n) => [n.id, n]));
21234
21646
  const \u5E73\u5766\u306A\u533A\u9593 = new Map(edges.map((e) => [e.id, flattenPathSegments(extractPathSegments(e.d))]));
21235
21647
  const \u8EF8\u306B\u5E73\u884C\u306A\u91CD\u306A\u308A\u9577\u3055 = (\u4E00\u65B9, \u4ED6\u65B9) => {
@@ -21299,6 +21711,7 @@ function fanIncomingEndpoints(edges, nodes) {
21299
21711
  const d = \u4E2D\u592E\u304C\u585E\u304C\u3063\u3066\u3044\u308B ? \u4E26\u3073[k].\u6DF1\u3055 < \u8FBA\u306E\u4E2D\u5FC3 ? -(++\u8CA0\u5074\u306E\u5E2D * \u9593\u9694) : ++\u6B63\u5074\u306E\u5E2D * \u9593\u9694 : k * \u9593\u9694 - \u4E2D\u5FC3;
21300
21712
  if (Math.abs(d) < 1e-3) continue;
21301
21713
  const e = \u4E26\u3073[k].e;
21714
+ if (e.routing === "metro") continue;
21302
21715
  const \u524D = e.d;
21303
21716
  const \u524D\u306E\u4EA4\u5DEE = countEdgeCrossings(edges).count;
21304
21717
  const \u9577\u3044\u52A9\u8D70 = \u4E26\u3073[k].\u9577\u3044\u52A9\u8D70;
@@ -21310,6 +21723,72 @@ function fanIncomingEndpoints(edges, nodes) {
21310
21723
  if (countEdgeCrossings(edges).count <= \u524D\u306E\u4EA4\u5DEE) break;
21311
21724
  e.d = \u524D;
21312
21725
  }
21726
+ if (e.d !== \u524D) \u7D42\u70B9\u306E\u79FB\u52D5.set(e.id, \u6A2A ? { dx: 0, dy: d } : { dx: d, dy: 0 });
21727
+ }
21728
+ }
21729
+ return \u7D42\u70B9\u306E\u79FB\u52D5;
21730
+ }
21731
+ function followLabelsToFannedTails(edges, obstacles, shifts, textMetrics = "proportional") {
21732
+ if (shifts.size === 0) return;
21733
+ const \u6E2C\u308A\u65B9 = \u7DDA\u306E\u6E2C\u308A\u65B9\u3092\u4F5C\u308B();
21734
+ const labels = edges.filter(hasRenderedLabel).map((e) => ({
21735
+ kind: "edge-label",
21736
+ id: e.id,
21737
+ ...computeLabelBBoxWorld(e, textMetrics)
21738
+ }));
21739
+ const labelIndexByEdgeId = new Map(labels.map((label, index) => [label.id, index]));
21740
+ const edgeById = new Map(edges.map((e) => [e.id, e]));
21741
+ const \u5468\u308A = {
21742
+ \u7BB1\u305F\u3061: obstacles.filter((o) => o.kind === "node" || o.kind === "lane-label"),
21743
+ labels,
21744
+ edges,
21745
+ edgeById,
21746
+ \u6E2C\u308A\u65B9
21747
+ };
21748
+ for (const e of edges) {
21749
+ const \u79FB\u52D5 = shifts.get(e.id);
21750
+ if (!\u79FB\u52D5 || !hasRenderedLabel(e)) continue;
21751
+ const labelIndex = labelIndexByEdgeId.get(e.id);
21752
+ if (labelIndex === void 0) continue;
21753
+ const \u5143\u306E\u672D = labels[labelIndex];
21754
+ const \u81EA\u5206\u306E\u533A\u9593 = \u6E2C\u308A\u65B9.\u533A\u9593(e.id, e.d);
21755
+ if (e.overlay && measurePathLabelGapSegs(\u81EA\u5206\u306E\u533A\u9593, {
21756
+ x: \u5143\u306E\u672D.x + \u5143\u306E\u672D.w / 2,
21757
+ y: \u5143\u306E\u672D.y + \u5143\u306E\u672D.h / 2,
21758
+ w: 0,
21759
+ h: 0
21760
+ }) <= OVERLAY_LABEL_ON_PATH_TOLERANCE) continue;
21761
+ const \u6700\u5F8C = \u81EA\u5206\u306E\u533A\u9593.at(-1);
21762
+ if (!\u6700\u5F8C) continue;
21763
+ if (!segmentsCrossRect([\u6700\u5F8C], \u5143\u306E\u672D)) continue;
21764
+ const \u5019\u88DCa = {
21765
+ labelX: e.labelX + \u79FB\u52D5.dx,
21766
+ labelY: e.labelY + \u79FB\u52D5.dy,
21767
+ labelAnchor: e.labelAnchor
21768
+ };
21769
+ const \u5019\u88DCa\u306E\u7BB1 = computeLabelBBoxWorld({ ...e, ...\u5019\u88DCa }, textMetrics);
21770
+ const \u6700\u5F8C\u306F\u7E26 = Math.abs(\u6700\u5F8C.x2 - \u6700\u5F8C.x1) <= Math.abs(\u6700\u5F8C.y2 - \u6700\u5F8C.y1);
21771
+ const \u5019\u88DC = [
21772
+ \u5019\u88DCa,
21773
+ {
21774
+ labelX: \u6700\u5F8C\u306F\u7E26 ? \u6700\u5F8C.x1 * 2 - (\u5019\u88DCa\u306E\u7BB1.x + \u5019\u88DCa\u306E\u7BB1.w / 2) : \u5019\u88DCa\u306E\u7BB1.x + \u5019\u88DCa\u306E\u7BB1.w / 2,
21775
+ labelY: \u6700\u5F8C\u306F\u7E26 ? \u5019\u88DCa\u306E\u7BB1.y + \u5019\u88DCa\u306E\u7BB1.h / 2 : \u6700\u5F8C.y1 * 2 - (\u5019\u88DCa\u306E\u7BB1.y + \u5019\u88DCa\u306E\u7BB1.h / 2),
21776
+ labelAnchor: "middle"
21777
+ }
21778
+ ];
21779
+ for (const c of \u5019\u88DC) {
21780
+ const \u672D = {
21781
+ kind: "edge-label",
21782
+ id: e.id,
21783
+ ...computeLabelBBoxWorld({ ...e, ...c }, textMetrics)
21784
+ };
21785
+ if (segmentsCrossRect([\u6700\u5F8C], \u672D)) continue;
21786
+ if (\u672D\u306E\u79FB\u52D5\u3092\u585E\u3050\u76F8\u624B\u3092\u63A2\u3059(\u5468\u308A, \u5143\u306E\u672D, \u672D) !== null) continue;
21787
+ e.labelX = c.labelX;
21788
+ e.labelY = c.labelY;
21789
+ e.labelAnchor = c.labelAnchor;
21790
+ labels[labelIndex] = \u672D;
21791
+ break;
21313
21792
  }
21314
21793
  }
21315
21794
  }
@@ -21326,7 +21805,7 @@ function \u672B\u5C3E\u3092\u8FBA\u306B\u6CBF\u3063\u3066\u305A\u3089\u3059(e, \
21326
21805
  if ((e.d.match(/M/g) ?? []).length !== 1) return null;
21327
21806
  const segs = extractPathSegments(e.d);
21328
21807
  if (segs.length === 0) return null;
21329
- if (segs.some((s) => s.cmd === "C")) return null;
21808
+ if (segs.some((s) => s.cmd === "C" || s.cmd === "A")) return null;
21330
21809
  const last = segs[segs.length - 1];
21331
21810
  if (last.cmd !== "L") return null;
21332
21811
  const \u5782\u76F4\u306B\u5165\u308B = \u6A2A ? Math.abs(last.y2 - last.y1) < 0.5 && Math.abs(last.x2 - last.x1) > 0.5 : Math.abs(last.x2 - last.x1) < 0.5 && Math.abs(last.y2 - last.y1) > 0.5;
@@ -21496,7 +21975,7 @@ function expandLanesForNodes(lanes, nodes) {
21496
21975
  };
21497
21976
  });
21498
21977
  }
21499
- function expandLaneGapsForEdgeLabels(lanes, nodes, edges) {
21978
+ function expandLaneGapsForEdgeLabels(lanes, nodes, edges, textMetrics = "proportional") {
21500
21979
  if (lanes.length < 2) return lanes;
21501
21980
  const layoutedLanes = lanes.filter((l) => !(l.posX !== void 0 && l.posY !== void 0));
21502
21981
  if (layoutedLanes.length < 2) return lanes;
@@ -21512,7 +21991,7 @@ function expandLaneGapsForEdgeLabels(lanes, nodes, edges) {
21512
21991
  const fi = laneIndexById.get(fromLane);
21513
21992
  const ti = laneIndexById.get(toLane);
21514
21993
  if (fi === void 0 || ti === void 0 || fi === ti) continue;
21515
- const labelBoxW = computeLabelBoxW(edge.label, edge.sub);
21994
+ const labelBoxW = computeLabelBoxW(edge.label, edge.sub, textMetrics);
21516
21995
  if (labelBoxW === 0) continue;
21517
21996
  const lo = Math.min(fi, ti);
21518
21997
  const hi = Math.max(fi, ti);
@@ -21617,13 +22096,16 @@ function \u5411\u304D\u3092\u53D6\u308B(end, \u5019\u88DC) {
21617
22096
  }
21618
22097
  return null;
21619
22098
  }
21620
- function \u7AEF\u3067\u306E\u5411\u304D(d, \u7AEF) {
22099
+ function \u7DDA\u306E\u7AEF\u306E\u5411\u304D(d, \u7AEF) {
21621
22100
  const segs = extractPathSegments(d);
21622
22101
  if (segs.length === 0) return null;
21623
22102
  if (\u7AEF === "head") {
21624
22103
  const last = segs[segs.length - 1];
21625
22104
  const end2 = { x: last.x2, y: last.y2 };
21626
- const \u5019\u88DC2 = segs.slice().reverse().flatMap((s) => [s.cmd === "Q" ? s.ctrl?.[0] : s.cmd === "C" ? s.ctrl?.[1] : void 0, { x: s.x1, y: s.y1 }]);
22105
+ const \u5019\u88DC2 = segs.slice().reverse().flatMap((s) => {
22106
+ const \u5236\u5FA1\u70B9 = s.cmd === "C" ? [s.ctrl?.[1], s.ctrl?.[0]] : s.cmd === "Q" ? [s.ctrl?.[0]] : [];
22107
+ return [...\u5236\u5FA1\u70B9, { x: s.x1, y: s.y1 }];
22108
+ });
21627
22109
  return \u5411\u304D\u3092\u53D6\u308B(end2, \u5019\u88DC2);
21628
22110
  }
21629
22111
  const first = segs[0];
@@ -21631,10 +22113,10 @@ function \u7AEF\u3067\u306E\u5411\u304D(d, \u7AEF) {
21631
22113
  const \u5019\u88DC = segs.flatMap((s) => [...s.ctrl ?? [], { x: s.x2, y: s.y2 }]);
21632
22114
  return \u5411\u304D\u3092\u53D6\u308B(end, \u5019\u88DC);
21633
22115
  }
21634
- function \u7AEF\u306E\u5B57\u3092\u7F6E\u304F(edge, \u7AEF = "head") {
22116
+ function \u7AEF\u306E\u5B57\u3092\u7F6E\u304F(edge, \u7AEF = "head", textMetrics = "proportional") {
21635
22117
  const text = (\u7AEF === "head" ? edge.headLabel : edge.tailLabel)?.trim();
21636
22118
  if (!text) return null;
21637
- const \u5411\u304D = \u7AEF\u3067\u306E\u5411\u304D(edge.d, \u7AEF);
22119
+ const \u5411\u304D = \u7DDA\u306E\u7AEF\u306E\u5411\u304D(edge.d, \u7AEF);
21638
22120
  if (!\u5411\u304D) return null;
21639
22121
  const { end, ux, uy } = \u5411\u304D;
21640
22122
  const bx = end.x - ux * \u7AEF\u306E\u5B57\u3092\u623B\u3059\u8DDD\u96E2;
@@ -21642,7 +22124,8 @@ function \u7AEF\u306E\u5B57\u3092\u7F6E\u304F(edge, \u7AEF = "head") {
21642
22124
  const w = measureTextWidth(text, {
21643
22125
  fontSize: \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055,
21644
22126
  fontWeight: EDGE_LABEL_TEXT.sub.fontWeight,
21645
- fontFamily: "mono"
22127
+ fontFamily: "mono",
22128
+ textMetrics
21646
22129
  });
21647
22130
  const h = \u7BB1\u306E\u9AD8\u3055;
21648
22131
  const \u672D = hasRenderedLabel(edge) && edge.labelX !== void 0 && edge.labelY !== void 0 ? { x: edge.labelX, y: edge.labelY } : null;
@@ -21691,10 +22174,10 @@ function autoStorageHeight(n, defaultH) {
21691
22174
  }
21692
22175
  return Math.max(defaultH, \u5FC5\u8981);
21693
22176
  }
21694
- function autoRowsWidth(n, defaultW) {
22177
+ function autoRowsWidth(n, defaultW, textMetrics = "proportional") {
21695
22178
  if (n.w != null) return n.w;
21696
22179
  if (!n.rows || n.rows.length === 0) return defaultW;
21697
- const required = requiredRowsWidth(n.rows, n.kind);
22180
+ const required = requiredRowsWidth(n.rows, n.kind, textMetrics);
21698
22181
  return Math.max(defaultW, required);
21699
22182
  }
21700
22183
  function \u7BB1\u306E\u9AD8\u30552(n, \u65E2\u5B9Ah) {
@@ -21732,7 +22215,7 @@ function requiredStackGapForEdgeLabels(diag, allStacks) {
21732
22215
  }
21733
22216
  return required;
21734
22217
  }
21735
- function layoutNodes(diag, lanes) {
22218
+ function layoutNodes(diag, lanes, textMetrics) {
21736
22219
  const laneMap = new Map(lanes.map((l) => [l.id, l]));
21737
22220
  const allStacks = Array.from(new Set(diag.nodes.map((n) => n.stack))).sort((a, b) => a - b);
21738
22221
  const rowH = /* @__PURE__ */ new Map();
@@ -21776,7 +22259,7 @@ function layoutNodes(diag, lanes) {
21776
22259
  }
21777
22260
  const size = NODE_SIZE[n.kind];
21778
22261
  if (n.posX !== void 0 && n.posY !== void 0) {
21779
- const w2 = n.posW ?? n.w ?? autoRowsWidth(n, size.w);
22262
+ const w2 = n.posW ?? n.w ?? autoRowsWidth(n, size.w, textMetrics);
21780
22263
  const h2 = n.posH ?? n.h ?? rowH.get(n.stack) ?? size.h;
21781
22264
  out.push({
21782
22265
  ...n,
@@ -21794,7 +22277,7 @@ function layoutNodes(diag, lanes) {
21794
22277
  const \u81EA\u524D\u306E\u9AD8\u3055 = n.rowMarks !== void 0;
21795
22278
  const h = n.h ?? (\u81EA\u524D\u306E\u9AD8\u3055 ? \u7BB1\u306E\u9AD8\u30552(n, size.h) : \u6BB5\u306E\u9AD8\u3055);
21796
22279
  const cy = \u6BB5\u306E\u82AF;
21797
- const w = autoRowsWidth(n, size.w);
22280
+ const w = autoRowsWidth(n, size.w, textMetrics);
21798
22281
  out.push({
21799
22282
  ...n,
21800
22283
  cx,
@@ -21914,10 +22397,16 @@ function applyRowLevelNodeShifts(nodes, lanes, nodeShifts) {
21914
22397
  return moved ? { nodes: outNodes, lanes: outLanes } : null;
21915
22398
  }
21916
22399
  function layout(diag) {
22400
+ const textMetrics = resolveTextMetrics(diag.textMetrics);
21917
22401
  const lanes = layoutLanes(diag);
21918
- const rawNodes = applyFooterShapeDrops(lanes, layoutNodes(diag, lanes));
22402
+ const rawNodes = applyFooterShapeDrops(lanes, layoutNodes(diag, lanes, textMetrics));
21919
22403
  const expandedLanes = expandLanesForNodes(lanes, rawNodes);
21920
- const gapExpandedLanes = expandLaneGapsForEdgeLabels(expandedLanes, rawNodes, diag.edges);
22404
+ const gapExpandedLanes = expandLaneGapsForEdgeLabels(
22405
+ expandedLanes,
22406
+ rawNodes,
22407
+ diag.edges,
22408
+ textMetrics
22409
+ );
21921
22410
  const nodes = rawNodes.map((n) => {
21922
22411
  if (n.posX !== void 0 && n.posY !== void 0) return n;
21923
22412
  const oldLane = lanes.find((l) => l.id === n.lane);
@@ -21926,13 +22415,13 @@ function layout(diag) {
21926
22415
  return { ...n, cx: newLane.x + newLane.width / 2 };
21927
22416
  });
21928
22417
  const containedLanesPre = recomputeContainedLanes(gapExpandedLanes, nodes);
21929
- const edgesPre = layoutEdges(diag, nodes, containedLanesPre);
21930
- const bboxesPre = collectBBoxes(containedLanesPre, nodes, edgesPre);
22418
+ const edgesPre = layoutEdges(diag, nodes, containedLanesPre, textMetrics);
22419
+ const bboxesPre = collectBBoxes(containedLanesPre, nodes, edgesPre, textMetrics);
21931
22420
  const collisionsPre = detectCollisions(bboxesPre, edgesPre);
21932
22421
  const nodesResolved = resolveOverlaps(nodes, collisionsPre);
21933
22422
  const moved = nodesResolved !== nodes;
21934
22423
  const containedLanes = moved ? recomputeContainedLanes(gapExpandedLanes, nodesResolved) : containedLanesPre;
21935
- const edgesAfterMove = moved ? layoutEdges(diag, nodesResolved, containedLanes) : edgesPre;
22424
+ const edgesAfterMove = moved ? layoutEdges(diag, nodesResolved, containedLanes, textMetrics) : edgesPre;
21936
22425
  const chainShiftClearance = Math.max(CLEARANCE_LABEL_LABEL, CLEARANCE_NODE_LABEL);
21937
22426
  let edges;
21938
22427
  let nodesFinal = nodesResolved;
@@ -21943,10 +22432,13 @@ function layout(diag) {
21943
22432
  } else {
21944
22433
  const propagateResult = resolveEdgeLabelOverlapsWithChainAndPropagate(
21945
22434
  edgesAfterMove,
21946
- collectBBoxes(containedLanes, nodesResolved, []).filter(
22435
+ collectBBoxes(containedLanes, nodesResolved, [], textMetrics).filter(
21947
22436
  (b) => b.kind === "node" || b.kind === "lane-label"
21948
22437
  ),
21949
- chainShiftClearance
22438
+ chainShiftClearance,
22439
+ void 0,
22440
+ void 0,
22441
+ textMetrics
21950
22442
  );
21951
22443
  edges = propagateResult.edges;
21952
22444
  if (propagateResult.nodeShifts.size > 0) {
@@ -21958,28 +22450,39 @@ function layout(diag) {
21958
22450
  }
21959
22451
  if (nodesFinal !== nodesResolved) {
21960
22452
  containedLanesFinal = recomputeContainedLanes(laneShiftedBase, nodesFinal);
21961
- edges = layoutEdges(diag, nodesFinal, containedLanesFinal);
22453
+ edges = layoutEdges(diag, nodesFinal, containedLanesFinal, textMetrics);
21962
22454
  }
21963
22455
  }
21964
22456
  const positionedEdgeIds = new Set(
21965
- diag.edges.filter((e) => e.posX1 !== void 0 && e.posY1 !== void 0 && e.posX2 !== void 0 && e.posY2 !== void 0).map((e) => e.id)
22457
+ diag.edges.filter(
22458
+ (e) => e.routing === "curve" || e.routing === "metro" || e.posX1 !== void 0 && e.posY1 !== void 0 && e.posX2 !== void 0 && e.posY2 !== void 0
22459
+ ).map((e) => e.id)
21966
22460
  );
21967
- bowSharedStraightPaths(edges, nodesFinal, positionedEdgeIds);
21968
- pullOutgoingFirstCorner(edges, nodesFinal);
21969
- fanIncomingEndpoints(edges, nodesFinal);
22461
+ bowSharedStraightPaths(edges, nodesFinal, positionedEdgeIds, textMetrics);
22462
+ pullOutgoingFirstCorner(edges, nodesFinal, textMetrics);
22463
+ const fannedTailShifts = fanIncomingEndpoints(edges, nodesFinal);
21970
22464
  separateSharedStraightRuns(edges, nodesFinal);
21971
22465
  hopEdgeCrossings(edges);
21972
- repositionParallelLabels(edges, nodesFinal);
21973
- slideLabelsAlongOwnPath(edges, nodesFinal);
22466
+ const labelClearanceObstacles = collectBBoxes(
22467
+ containedLanesFinal,
22468
+ nodesFinal,
22469
+ [],
22470
+ textMetrics
22471
+ ).filter(
22472
+ (b) => b.kind === "node" || b.kind === "lane-label"
22473
+ );
22474
+ followLabelsToFannedTails(edges, labelClearanceObstacles, fannedTailShifts, textMetrics);
22475
+ repositionParallelLabels(edges, nodesFinal, textMetrics);
22476
+ slideLabelsAlongOwnPath(edges, nodesFinal, textMetrics);
21974
22477
  if (!isChainEdgeLabelDisabled()) {
21975
22478
  edges = resolveLabelClearanceAfterPathPasses(
21976
22479
  edges,
21977
- collectBBoxes(containedLanesFinal, nodesFinal, []).filter(
21978
- (b) => b.kind === "node" || b.kind === "lane-label"
21979
- )
22480
+ labelClearanceObstacles,
22481
+ void 0,
22482
+ textMetrics
21980
22483
  );
21981
22484
  }
21982
- const bboxes = collectBBoxes(containedLanesFinal, nodesFinal, edges);
22485
+ const bboxes = collectBBoxes(containedLanesFinal, nodesFinal, edges, textMetrics);
21983
22486
  const collisions = detectCollisions(bboxes, edges);
21984
22487
  const nearCollisions = detectNearCollisions(bboxes, edges);
21985
22488
  if (collisions.length > 0) {
@@ -22019,6 +22522,8 @@ function layout(diag) {
22019
22522
  // 描画側の固定の字の言語 (#847)。 既定 (`en`) と型の外の値は持たせない = 配置の結果の形を
22020
22523
  // 変更前と揃え、記法の書き損じで一部の字だけ日本語になる形を作らない
22021
22524
  ...resolveLang(diag.lang) === "ja" ? { lang: "ja" } : {},
22525
+ // 既定は持ち越さない。既存の LaidDiagram の形を変えず、等幅の図だけ描画へ伝える
22526
+ ...textMetrics === "monospace" ? { textMetrics: "monospace" } : {},
22022
22527
  // 種類も配色と同じく空の目印を出さない。 遮断をここに揃えると手書きの図にも効く
22023
22528
  ...diag.type ? { type: diag.type } : {},
22024
22529
  bboxes,
@@ -22586,11 +23091,13 @@ function applyHeuristics(diag, laid, violations, applied) {
22586
23091
  violations.filter((v) => v.axis === "edge-node-cross").map((v) => extractEdgeId(v.detail)).filter((id) => id !== null)
22587
23092
  );
22588
23093
  if (h3Edges.size > 0) {
22589
- const originalEdges = edges;
22590
- edges = edges.map(
22591
- (e) => h3Edges.has(e.id) && e.routing !== "back-detour" ? { ...e, routing: "back-detour" } : e
23094
+ const eligibleEdges = new Set(
23095
+ edges.filter((e) => h3Edges.has(e.id) && (e.routing === void 0 || e.routing === "default")).map((e) => e.id)
22592
23096
  );
22593
- if (edges !== originalEdges) {
23097
+ if (eligibleEdges.size > 0) {
23098
+ edges = edges.map(
23099
+ (e) => eligibleEdges.has(e.id) ? { ...e, routing: "back-detour" } : e
23100
+ );
22594
23101
  applied.push("h3-edge-back-detour");
22595
23102
  mutated = true;
22596
23103
  }
@@ -22910,15 +23417,15 @@ function extractPathEndpoints(d) {
22910
23417
  if (!start || !end) return null;
22911
23418
  return { start, end };
22912
23419
  }
22913
- function isPointOnNodeBoundary(point, node, tol) {
23420
+ function isPointOnNodeBoundary(point2, node, tol) {
22914
23421
  const left = node.cx - node.w / 2;
22915
23422
  const right = node.cx + node.w / 2;
22916
23423
  const top = node.cy - node.h / 2;
22917
23424
  const bot = node.cy + node.h / 2;
22918
- if (Math.abs(point.x - left) <= tol && point.y >= top - tol && point.y <= bot + tol) return true;
22919
- if (Math.abs(point.x - right) <= tol && point.y >= top - tol && point.y <= bot + tol) return true;
22920
- if (Math.abs(point.y - top) <= tol && point.x >= left - tol && point.x <= right + tol) return true;
22921
- if (Math.abs(point.y - bot) <= tol && point.x >= left - tol && point.x <= right + tol) return true;
23425
+ if (Math.abs(point2.x - left) <= tol && point2.y >= top - tol && point2.y <= bot + tol) return true;
23426
+ if (Math.abs(point2.x - right) <= tol && point2.y >= top - tol && point2.y <= bot + tol) return true;
23427
+ if (Math.abs(point2.y - top) <= tol && point2.x >= left - tol && point2.x <= right + tol) return true;
23428
+ if (Math.abs(point2.y - bot) <= tol && point2.x >= left - tol && point2.x <= right + tol) return true;
22922
23429
  return false;
22923
23430
  }
22924
23431
  async function verifyBoundingBoxes(page, laid, options) {
@@ -24130,6 +24637,7 @@ function CdlEdgeView({
24130
24637
  "g",
24131
24638
  {
24132
24639
  "data-cdl-edge": edge.id,
24640
+ "data-cdl-routing": edge.routing === "metro" ? "metro" : void 0,
24133
24641
  "data-cdl-from": edge.from,
24134
24642
  "data-cdl-to": edge.to,
24135
24643
  "data-cdl-active": active ? "true" : "false",
@@ -24141,6 +24649,7 @@ function CdlEdgeView({
24141
24649
  "data-cdl-edge-label": edge.label,
24142
24650
  "data-cdl-edge-sub": edge.sub ?? "",
24143
24651
  "data-cdl-tone": edge.tone,
24652
+ "data-cdl-edge-role": edge.role,
24144
24653
  children: [
24145
24654
  isDotted ? /* @__PURE__ */ jsxs("g", { children: [
24146
24655
  /* @__PURE__ */ jsx("path", { id: glowPathId, d: glowPathD, fill: "none", stroke: "none" }),
@@ -24292,11 +24801,12 @@ function CdlEdgeGlowView({
24292
24801
  }
24293
24802
  function CdlEdgeLabelView({
24294
24803
  edge,
24295
- active
24804
+ active,
24805
+ textMetrics = "proportional"
24296
24806
  }) {
24297
24807
  if (!hasRenderedLabel(edge)) return null;
24298
24808
  const color = edgeColor(edge);
24299
- const bbox = computeLabelBBoxWorld(edge);
24809
+ const bbox = computeLabelBBoxWorld(edge, textMetrics);
24300
24810
  const boxW = bbox.w;
24301
24811
  const boxH = bbox.h;
24302
24812
  const boxLeftX = bbox.x - edge.labelX;
@@ -24312,6 +24822,8 @@ function CdlEdgeLabelView({
24312
24822
  "data-cdl-edge-label-for": edge.id,
24313
24823
  "data-cdl-edge-label-text": edge.label,
24314
24824
  "data-cdl-edge-sub-text": edge.sub ?? "",
24825
+ "data-cdl-tone": edge.tone,
24826
+ "data-cdl-edge-role": edge.role,
24315
24827
  children: [
24316
24828
  edge.labelPlate !== false && /* @__PURE__ */ jsx(
24317
24829
  "rect",
@@ -24365,9 +24877,10 @@ function CdlEdgeLabelView({
24365
24877
  function CdlEdgeEndLabelView({
24366
24878
  edge,
24367
24879
  active,
24368
- \u7AEF
24880
+ \u7AEF,
24881
+ textMetrics = "proportional"
24369
24882
  }) {
24370
- const \u7F6E\u304D\u5834\u6240 = \u7AEF\u306E\u5B57\u3092\u7F6E\u304F(edge, \u7AEF);
24883
+ const \u7F6E\u304D\u5834\u6240 = \u7AEF\u306E\u5B57\u3092\u7F6E\u304F(edge, \u7AEF, textMetrics);
24371
24884
  if (!\u7F6E\u304D\u5834\u6240) return null;
24372
24885
  const color = edgeColor(edge);
24373
24886
  return /* @__PURE__ */ jsx(
@@ -24376,6 +24889,8 @@ function CdlEdgeEndLabelView({
24376
24889
  "data-cdl-role": "edge-end-label",
24377
24890
  "data-cdl-edge-end-label-for": edge.id,
24378
24891
  "data-cdl-edge-end": \u7AEF,
24892
+ "data-cdl-tone": edge.tone,
24893
+ "data-cdl-edge-role": edge.role,
24379
24894
  x: \u7F6E\u304D\u5834\u6240.x,
24380
24895
  y: \u7F6E\u304D\u5834\u6240.y,
24381
24896
  fontSize: \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055,
@@ -24623,12 +25138,18 @@ var g4 = (v) => Math.round(v / 4) * 4;
24623
25138
  function sequenceStepId() {
24624
25139
  return "seq_step";
24625
25140
  }
24626
- function sequenceBoardMetrics(data) {
25141
+ function sequenceBoardMetrics(data, textMetrics = "proportional") {
24627
25142
  const \u540D\u5E45 = data.actors.map(
24628
- (a) => Math.max(textWidth(a.name, SEQ_NAME), a.subtitle ? textWidth(a.subtitle, SEQ_SUB) : 0)
25143
+ (a) => Math.max(
25144
+ textWidth(a.name, SEQ_NAME, 0, textMetrics),
25145
+ a.subtitle ? textWidth(a.subtitle, SEQ_SUB, 0, textMetrics) : 0
25146
+ )
24629
25147
  );
24630
25148
  const colW = g4(Math.max(SEQ_COL_MIN, Math.max(0, ...\u540D\u5E45) + SEQ_COL_PAD));
24631
- const \u8A9E\u5E45 = Math.max(0, ...data.messages.map((m) => textWidth(m.label, SEQ_LABEL)));
25149
+ const \u8A9E\u5E45 = Math.max(
25150
+ 0,
25151
+ ...data.messages.map((m) => textWidth(m.label, SEQ_LABEL, 0, textMetrics))
25152
+ );
24632
25153
  const gutter = g4(SEQ_EDGE + SEQ_GUTTER_PAD + \u8A9E\u5E45 + SEQ_GUTTER_GAP);
24633
25154
  const headY = SEQ_EDGE + SEQ_HEAD;
24634
25155
  const rowY = (i) => headY + SEQ_ROW_PAD + i * SEQ_ROW;
@@ -24641,11 +25162,12 @@ function sequenceBoardMetrics(data) {
24641
25162
  }
24642
25163
  function SequenceBoardNode({
24643
25164
  node,
24644
- stateValues
25165
+ stateValues,
25166
+ textMetrics = "proportional"
24645
25167
  }) {
24646
25168
  const data = node.sequenceData;
24647
25169
  if (!data) return /* @__PURE__ */ jsx("g", { "data-cdl-role": "sequence-board" });
24648
- const m = sequenceBoardMetrics(data);
25170
+ const m = sequenceBoardMetrics(data, textMetrics);
24649
25171
  const x = node.cx - node.w / 2;
24650
25172
  const y = node.cy - node.h / 2;
24651
25173
  const \u73FE\u5728 = (() => {
@@ -25296,7 +25818,8 @@ function GenericNode({
25296
25818
  active,
25297
25819
  value,
25298
25820
  stateValues,
25299
- \u5024\u306E\u540D\u524D
25821
+ \u5024\u306E\u540D\u524D,
25822
+ textMetrics = "proportional"
25300
25823
  }) {
25301
25824
  const base = STYLES[node.kind] ?? FALLBACK;
25302
25825
  const toned = toneColor3(node.tone);
@@ -25435,7 +25958,7 @@ function GenericNode({
25435
25958
  const resolved = node.rows.map((row) => interpolate(row, stateValues, \u5024\u306E\u540D\u524D));
25436
25959
  const splits = resolved.map(splitRow);
25437
25960
  const leftMaxWidth = splits.reduce(
25438
- (m, s) => Math.max(m, rowColumnWidth(s.left, GENERIC_ROW_LEFT_SIZE_PX, false)),
25961
+ (m, s) => Math.max(m, rowColumnWidth(s.left, GENERIC_ROW_LEFT_SIZE_PX, false, textMetrics)),
25439
25962
  0
25440
25963
  );
25441
25964
  const rightColX = ROW_PAD_X_PX + leftMaxWidth + ROW_COL_GAP_PX;
@@ -25561,17 +26084,22 @@ function DynShapeNode({
25561
26084
  return renderPolygon(shape, cx, cy, stateValues, fillColor, strokeColor, activeOpacity);
25562
26085
  }
25563
26086
  })();
26087
+ const \u63C3\u3048 = \u7BB1\u3044\u3063\u3071\u3044\u306B\u63CF\u304F2(shape.kind) ? "start" : "middle";
26088
+ return renderShapeWithOutsideLabels(\u5F62, node, \u63C3\u3048);
26089
+ }
26090
+ function renderShapeWithOutsideLabels(\u5F62, node, \u63C3\u3048) {
26091
+ const cx = node.cx;
26092
+ const y = node.cy - node.h / 2;
25564
26093
  const \u540D\u524D = (node.title ?? "").trim();
25565
26094
  const \u5024 = (node.subtitle ?? "").trim();
25566
26095
  if (\u540D\u524D === "" && \u5024 === "") return \u5F62;
25567
- const \u63C3\u3048 = \u7BB1\u3044\u3063\u3071\u3044\u306B\u63CF\u304F2(shape.kind) ? "start" : "middle";
25568
26096
  return /* @__PURE__ */ jsxs("g", { children: [
25569
26097
  \u5F62,
25570
26098
  \u540D\u524D !== "" && /* @__PURE__ */ jsx(
25571
26099
  "text",
25572
26100
  {
25573
26101
  "data-cdl-role": "shape-name",
25574
- x: \u63C3\u3048 === "start" ? x : cx,
26102
+ x: \u63C3\u3048 === "start" ? node.cx - node.w / 2 : cx,
25575
26103
  y: y - NAME_GAP,
25576
26104
  textAnchor: \u63C3\u3048,
25577
26105
  fontSize: 13,
@@ -25585,7 +26113,7 @@ function DynShapeNode({
25585
26113
  {
25586
26114
  "data-cdl-role": "shape-value",
25587
26115
  x: cx,
25588
- y: y + h + VALUE_GAP,
26116
+ y: y + node.h + VALUE_GAP,
25589
26117
  textAnchor: "middle",
25590
26118
  fontSize: 12,
25591
26119
  fill: "var(--cdl-text-dim, #5a6270)",
@@ -25835,6 +26363,27 @@ function interpolateColor(template, stateValues, fallback) {
25835
26363
  if (!template) return fallback;
25836
26364
  return interpolate(template, stateValues);
25837
26365
  }
26366
+ var STATION_STROKE_ACTIVE = 4;
26367
+ var STATION_STROKE_IDLE = 3;
26368
+ var STATION_DEFAULT = "var(--cdl-tone-accent, #2d6a8f)";
26369
+ function StationNode({ node, active }) {
26370
+ const strokeWidth = active ? STATION_STROKE_ACTIVE : STATION_STROKE_IDLE;
26371
+ const radius = Math.max(0, Math.min(node.w, node.h) / 2 - strokeWidth / 2);
26372
+ const \u5F62 = /* @__PURE__ */ jsx(
26373
+ "circle",
26374
+ {
26375
+ "data-cdl-role": "node-body",
26376
+ "data-cdl-mark": "station",
26377
+ cx: node.cx,
26378
+ cy: node.cy,
26379
+ r: radius,
26380
+ fill: "var(--cdl-node-fill, #ffffff)",
26381
+ stroke: nodeAccent(node, STATION_DEFAULT),
26382
+ strokeWidth
26383
+ }
26384
+ );
26385
+ return renderShapeWithOutsideLabels(\u5F62, node, "middle");
26386
+ }
25838
26387
 
25839
26388
  // src/kinds/label-stack.ts
25840
26389
  function \u540D\u672D\u306E\u6BB5\u3092\u307B\u3069\u304F(\u771F\u306Ey, \u9593\u9694, \u4E0A\u9650, \u4E0B\u9650) {
@@ -25893,8 +26442,8 @@ function \u5024\u3068\u5272\u5408\u306E\u6587\u5B57(\u5024, \u5272\u5408, \u5408
25893
26442
  return \u7D44.\u5024 === null ? \u7D44.\u5272\u5408 : `${\u7D44.\u5024} ${\u7D44.\u5272\u5408}`;
25894
26443
  }
25895
26444
  var \u7A74\u306B\u5BFE\u3059\u308B\u4E0A\u9650 = 0.8;
25896
- function \u4E2D\u592E\u306E\u5B57(\u6BD4\u4F8B\u3057\u305F\u5927\u304D\u3055, \u7A74\u306E\u534A\u5F84, \u6587) {
25897
- const \u5165\u308B\u5927\u304D\u3055 = \u7A74\u306E\u534A\u5F84 * 2 * \u7A74\u306B\u5BFE\u3059\u308B\u4E0A\u9650 / Math.max(textWidth(\u6587, 1), 1e-6);
26445
+ function \u4E2D\u592E\u306E\u5B57(\u6BD4\u4F8B\u3057\u305F\u5927\u304D\u3055, \u7A74\u306E\u534A\u5F84, \u6587, textMetrics = "proportional") {
26446
+ const \u5165\u308B\u5927\u304D\u3055 = \u7A74\u306E\u534A\u5F84 * 2 * \u7A74\u306B\u5BFE\u3059\u308B\u4E0A\u9650 / Math.max(textWidth(\u6587, 1, 0, textMetrics), 1e-6);
25898
26447
  return Math.min(Math.max(\u6BD4\u4F8B\u3057\u305F\u5927\u304D\u3055, \u7E2E\u3093\u3060\u7D75\u306E\u5B57\u306E\u4E0B\u9650), \u5165\u308B\u5927\u304D\u3055);
25899
26448
  }
25900
26449
  function ChartPieNode({
@@ -25902,7 +26451,8 @@ function ChartPieNode({
25902
26451
  active,
25903
26452
  stateValues = {},
25904
26453
  drawing = false,
25905
- progress = 1
26454
+ progress = 1,
26455
+ textMetrics = "proportional"
25906
26456
  }) {
25907
26457
  const instanceId = useId().replace(/[^A-Za-z0-9_-]/g, "");
25908
26458
  const x0 = node.cx - node.w / 2;
@@ -25933,15 +26483,26 @@ function ChartPieNode({
25933
26483
  return `${\u5B9F\u5024\u8868\u8A18(d.value)}%` === \u5272\u5408\u306E\u6587\u5B57[i] ? \u540D : `${\u540D} ${\u5B9F\u5024\u8868\u8A18(d.value)}`;
25934
26484
  });
25935
26485
  if (\u5F62 !== "ring") {
25936
- const \u5171\u901A = { node, active, data, \u5272\u5408: \u4ECA\u306E\u5272\u5408, x0, y0, drawing, progress, instanceId };
26486
+ const \u5171\u901A = {
26487
+ node,
26488
+ active,
26489
+ data,
26490
+ \u5272\u5408: \u4ECA\u306E\u5272\u5408,
26491
+ x0,
26492
+ y0,
26493
+ drawing,
26494
+ progress,
26495
+ instanceId,
26496
+ textMetrics
26497
+ };
25937
26498
  return \u5F62 === "arcs" ? \u5F27\u306E\u5F62(\u5171\u901A) : \u8868\u306E\u5F62(\u5171\u901A);
25938
26499
  }
25939
26500
  const \u540D\u672D\u5E45 = Math.max(
25940
26501
  0,
25941
26502
  ...data.map(
25942
26503
  (_d, i) => Math.max(
25943
- textWidth(\u5272\u5408\u306E\u6587\u5B57[i] ?? "", \u5272\u5408\u306E\u7D1A),
25944
- textWidth(\u540D\u524D\u306E\u6587\u5B57[i] ?? "", \u540D\u524D\u306E\u7D1A)
26504
+ textWidth(\u5272\u5408\u306E\u6587\u5B57[i] ?? "", \u5272\u5408\u306E\u7D1A, 0, textMetrics),
26505
+ textWidth(\u540D\u524D\u306E\u6587\u5B57[i] ?? "", \u540D\u524D\u306E\u7D1A, 0, textMetrics)
25945
26506
  )
25946
26507
  )
25947
26508
  );
@@ -25956,8 +26517,8 @@ function ChartPieNode({
25956
26517
  const \u524D\u306Eslices = \u524D\u3042\u308A ? \u8F2A\u3092\u7D44\u3080(data, cx, cy, \u524D\u306E\u5916\u534A\u5F84, \u524D\u306E\u5185\u534A\u5F84, \u524D\u306E\u5272\u5408) : [];
25957
26518
  const \u7A74 = \u524D\u3042\u308A ? \u524D\u306E\u5185\u534A\u5F84 : \u5916\u306E\u5185\u534A\u5F84;
25958
26519
  const \u5408\u8A08\u306E\u6587 = \u5B9F\u5024\u8868\u8A18(Math.round(\u524D\u3042\u308A ? \u4ECA\u306E\u5408\u8A08 : total));
25959
- const \u5408\u8A08\u306E\u5B57 = \u4E2D\u592E\u306E\u5B57(Math.round(radius * 0.26), \u7A74, \u5408\u8A08\u306E\u6587);
25960
- const \u898B\u51FA\u3057\u306E\u5B572 = \u4E2D\u592E\u306E\u5B57(Math.round(radius * 0.12), \u7A74, "\u5408\u8A08");
26520
+ const \u5408\u8A08\u306E\u5B57 = \u4E2D\u592E\u306E\u5B57(Math.round(radius * 0.26), \u7A74, \u5408\u8A08\u306E\u6587, textMetrics);
26521
+ const \u898B\u51FA\u3057\u306E\u5B572 = \u4E2D\u592E\u306E\u5B57(Math.round(radius * 0.12), \u7A74, "\u5408\u8A08", textMetrics);
25961
26522
  const \u5408\u8A08\u306E\u4E0B = Math.max(Math.round(radius * 0.2), \u5408\u8A08\u306E\u5B57 * 0.25 + \u898B\u51FA\u3057\u306E\u5B572 * 0.8);
25962
26523
  const slices = \u8F2A\u3092\u7D44\u3080(data, cx, cy, radius, \u5916\u306E\u5185\u534A\u5F84, \u4ECA\u306E\u5272\u5408);
25963
26524
  const \u958B\u304D = \u9032\u307F\u3092\u7573\u3080(drawing, progress);
@@ -26140,14 +26701,24 @@ function \u67A0(node, active) {
26140
26701
  }
26141
26702
  );
26142
26703
  }
26143
- function \u5F27\u306E\u5F62({ node, active, data, \u5272\u5408, x0, y0, drawing, progress }) {
26704
+ function \u5F27\u306E\u5F62({
26705
+ node,
26706
+ active,
26707
+ data,
26708
+ \u5272\u5408,
26709
+ x0,
26710
+ y0,
26711
+ drawing,
26712
+ progress,
26713
+ textMetrics
26714
+ }) {
26144
26715
  const PAD = 20;
26145
26716
  const \u540D\u524D\u306E\u7D1A = 14;
26146
26717
  const \u5272\u5408\u306E\u7D1A = 24;
26147
26718
  const \u5370\u304B\u3089\u540D\u524D\u307E\u30672 = 18;
26148
26719
  const \u540D\u524D\u304B\u3089\u5272\u5408\u307E\u3067 = 24;
26149
26720
  const \u5272\u5408\u306E\u6587\u5B57 = \u5272\u5408.map(\u5272\u5408\u8868\u8A18);
26150
- const \u4E00\u89A7\u5E45 = 10 + \u5370\u304B\u3089\u540D\u524D\u307E\u30672 + Math.max(0, ...data.map((d) => textWidth(d.label ?? "", \u540D\u524D\u306E\u7D1A))) + \u540D\u524D\u304B\u3089\u5272\u5408\u307E\u3067 + Math.max(0, ...\u5272\u5408\u306E\u6587\u5B57.map((t) => textWidth(t, \u5272\u5408\u306E\u7D1A)));
26721
+ const \u4E00\u89A7\u5E45 = 10 + \u5370\u304B\u3089\u540D\u524D\u307E\u30672 + Math.max(0, ...data.map((d) => textWidth(d.label ?? "", \u540D\u524D\u306E\u7D1A, 0, textMetrics))) + \u540D\u524D\u304B\u3089\u5272\u5408\u307E\u3067 + Math.max(0, ...\u5272\u5408\u306E\u6587\u5B57.map((t) => textWidth(t, \u5272\u5408\u306E\u7D1A, 0, textMetrics)));
26151
26722
  const \u7E26\u304B\u3089 = (node.h - PAD * 2) / 2;
26152
26723
  const \u6A2A\u304B\u3089 = (node.w - PAD * 2 - \u4E00\u89A7\u5E45 - 28) / 2;
26153
26724
  const R = Math.max(24, Math.min(\u7E26\u304B\u3089, \u6A2A\u304B\u3089));
@@ -26233,7 +26804,18 @@ function \u5F27\u306E\u5F62({ node, active, data, \u5272\u5408, x0, y0, drawing,
26233
26804
  })
26234
26805
  ] });
26235
26806
  }
26236
- function \u8868\u306E\u5F62({ node, active, data, \u5272\u5408, x0, y0, drawing, progress, instanceId }) {
26807
+ function \u8868\u306E\u5F62({
26808
+ node,
26809
+ active,
26810
+ data,
26811
+ \u5272\u5408,
26812
+ x0,
26813
+ y0,
26814
+ drawing,
26815
+ progress,
26816
+ instanceId,
26817
+ textMetrics
26818
+ }) {
26237
26819
  const PAD = 20;
26238
26820
  const \u898B\u51FA\u3057\u306E\u7D1A = 11;
26239
26821
  const \u540D\u524D\u306E\u7D1A = 15;
@@ -26242,9 +26824,18 @@ function \u8868\u306E\u5F62({ node, active, data, \u5272\u5408, x0, y0, drawing,
26242
26824
  const \u5370\u304B\u3089\u540D\u524D\u307E\u30672 = 18;
26243
26825
  const \u5272\u5408\u306E\u6587\u5B57 = \u5272\u5408.map(\u5272\u5408\u8868\u8A18);
26244
26826
  const \u5B9F\u6570\u306E\u6587\u5B57 = data.map((d) => \u5B9F\u5024\u8868\u8A18(d.value));
26245
- const \u540D\u524D\u5E45 = Math.max(0, ...data.map((d) => textWidth(d.label ?? "", \u540D\u524D\u306E\u7D1A)));
26246
- const \u5272\u5408\u5E45 = Math.max(textWidth("\u5272\u5408", \u898B\u51FA\u3057\u306E\u7D1A), ...\u5272\u5408\u306E\u6587\u5B57.map((t) => textWidth(t, \u5272\u5408\u306E\u7D1A)));
26247
- const \u5B9F\u6570\u5E45 = Math.max(textWidth("\u5024", \u898B\u51FA\u3057\u306E\u7D1A), ...\u5B9F\u6570\u306E\u6587\u5B57.map((t) => textWidth(t, \u5B9F\u6570\u306E\u7D1A)));
26827
+ const \u540D\u524D\u5E45 = Math.max(
26828
+ 0,
26829
+ ...data.map((d) => textWidth(d.label ?? "", \u540D\u524D\u306E\u7D1A, 0, textMetrics))
26830
+ );
26831
+ const \u5272\u5408\u5E45 = Math.max(
26832
+ textWidth("\u5272\u5408", \u898B\u51FA\u3057\u306E\u7D1A, 0, textMetrics),
26833
+ ...\u5272\u5408\u306E\u6587\u5B57.map((t) => textWidth(t, \u5272\u5408\u306E\u7D1A, 0, textMetrics))
26834
+ );
26835
+ const \u5B9F\u6570\u5E45 = Math.max(
26836
+ textWidth("\u5024", \u898B\u51FA\u3057\u306E\u7D1A, 0, textMetrics),
26837
+ ...\u5B9F\u6570\u306E\u6587\u5B57.map((t) => textWidth(t, \u5B9F\u6570\u306E\u7D1A, 0, textMetrics))
26838
+ );
26248
26839
  const \u8868\u5E45 = 10 + \u5370\u304B\u3089\u540D\u524D\u307E\u30672 + \u540D\u524D\u5E45 + 28 + \u5272\u5408\u5E45 + 24 + \u5B9F\u6570\u5E45;
26249
26840
  const \u7E26\u304B\u3089 = (node.h - PAD * 2) / 2;
26250
26841
  const \u6A2A\u304B\u3089 = (node.w - PAD * 2 - \u8868\u5E45 - 28) / 2;
@@ -26253,8 +26844,8 @@ function \u8868\u306E\u5F62({ node, active, data, \u5272\u5408, x0, y0, drawing,
26253
26844
  const cx = PAD + R;
26254
26845
  const cy = node.h / 2;
26255
26846
  const \u5408\u8A08\u306E\u6587 = \u5B9F\u5024\u8868\u8A18(Math.round(data.reduce((acc, d) => acc + d.value, 0)));
26256
- const \u5408\u8A08\u306E\u5B57 = \u4E2D\u592E\u306E\u5B57(Math.round(R * 0.26), \u5185\u534A\u5F84, \u5408\u8A08\u306E\u6587);
26257
- const \u898B\u51FA\u3057\u306E\u5B572 = \u4E2D\u592E\u306E\u5B57(Math.round(R * 0.12), \u5185\u534A\u5F84, "\u5408\u8A08");
26847
+ const \u5408\u8A08\u306E\u5B57 = \u4E2D\u592E\u306E\u5B57(Math.round(R * 0.26), \u5185\u534A\u5F84, \u5408\u8A08\u306E\u6587, textMetrics);
26848
+ const \u898B\u51FA\u3057\u306E\u5B572 = \u4E2D\u592E\u306E\u5B57(Math.round(R * 0.12), \u5185\u534A\u5F84, "\u5408\u8A08", textMetrics);
26258
26849
  const \u5408\u8A08\u306E\u4E0B = Math.max(Math.round(R * 0.2), \u5408\u8A08\u306E\u5B57 * 0.25 + \u898B\u51FA\u3057\u306E\u5B572 * 0.8);
26259
26850
  const \u8868\u5DE6 = node.w - PAD - \u8868\u5E45;
26260
26851
  const \u53F3\u7AEF = node.w - PAD;
@@ -26385,7 +26976,8 @@ function ChartGaugeNode({
26385
26976
  active,
26386
26977
  stateValues = {},
26387
26978
  drawing = false,
26388
- progress = 1
26979
+ progress = 1,
26980
+ textMetrics = "proportional"
26389
26981
  }) {
26390
26982
  const x0 = node.cx - node.w / 2;
26391
26983
  const y0 = node.cy - node.h / 2;
@@ -26404,7 +26996,10 @@ function ChartGaugeNode({
26404
26996
  const \u533A\u753B\u306E\u9593 = 12;
26405
26997
  const \u6570\u5024\u306E\u884C = (d) => \u5024\u3068\u5272\u5408\u306E\u6587\u5B57(\u5B9F\u5024\u8868\u8A18(d.value), \u5272\u5408\u8868\u8A18(d.value / total), total);
26406
26998
  const \u5272\u308A\u4ED8\u3051\u308B = (\u4EF6\u305F\u3061) => {
26407
- const \u5E45 = Math.max(\u5370\u306E\u5E452, ...\u4EF6\u305F\u3061.map((d) => textWidth(\u6570\u5024\u306E\u884C(d), \u6570\u5024\u306E\u7D1A))) + \u533A\u753B\u306E\u9593;
26999
+ const \u5E45 = Math.max(
27000
+ \u5370\u306E\u5E452,
27001
+ ...\u4EF6\u305F\u3061.map((d) => textWidth(\u6570\u5024\u306E\u884C(d), \u6570\u5024\u306E\u7D1A, 0, textMetrics))
27002
+ ) + \u533A\u753B\u306E\u9593;
26408
27003
  const \u884C\u306E\u4EF6\u65702 = Math.min(
26409
27004
  Math.max(1, Math.floor(\u4F7F\u3048\u308B\u5E452 / Math.max(\u5E45, 1))),
26410
27005
  Math.max(\u4EF6\u305F\u3061.length, 1)
@@ -26479,7 +27074,7 @@ function ChartGaugeNode({
26479
27074
  return { d, frac, path: \u6247\u306E\u9053(a0, a1, \u524D\u306E\u5185\u534A\u5F84, \u524D\u306E\u5916\u534A\u5F84) };
26480
27075
  });
26481
27076
  const \u5408\u8A08\u306E\u6587\u5B57 = \u5B9F\u5024\u8868\u8A18(Math.round(total));
26482
- const \u5358\u4F4D\u5E45 = Math.max(textWidth(\u5408\u8A08\u306E\u6587\u5B57, 100), 1) / 100;
27077
+ const \u5358\u4F4D\u5E45 = Math.max(textWidth(\u5408\u8A08\u306E\u6587\u5B57, 100, 0, textMetrics), 1) / 100;
26483
27078
  const \u7D1A\u306E\u5019\u88DC = Math.min(
26484
27079
  // 横 = 字の上の角が内側の円に入る大きさ
26485
27080
  \u5185\u534A\u5F84 / Math.sqrt((\u5358\u4F4D\u5E45 / 2) ** 2 + 1.25 ** 2),
@@ -26572,7 +27167,7 @@ function ChartGaugeNode({
26572
27167
  const y = \u5185\u8A33\u306Ey + \u6BB5\u306E\u9AD8\u3055 * \u6BB5;
26573
27168
  const \u53CE\u307E\u308B\u5E45 = \u5185\u8A33\u306E\u5E45 - \u533A\u753B\u306E\u9593;
26574
27169
  const \u6570\u306E\u884C = \u5185\u8A33\u306E\u6570\u5024[idx] ?? "";
26575
- const \u5207\u3063\u305F\u6570\u306E\u884C = \u5207\u308A\u8A70\u3081\u308B(\u6570\u306E\u884C, \u53CE\u307E\u308B\u5E45, \u6570\u5024\u306E\u7D1A);
27170
+ const \u5207\u3063\u305F\u6570\u306E\u884C = \u5207\u308A\u8A70\u3081\u308B(\u6570\u306E\u884C, \u53CE\u307E\u308B\u5E45, \u6570\u5024\u306E\u7D1A, textMetrics);
26576
27171
  return /* @__PURE__ */ jsxs("g", { "data-cdl-role": "chart-gauge-item", children: [
26577
27172
  /* @__PURE__ */ jsx(
26578
27173
  "rect",
@@ -26593,7 +27188,7 @@ function ChartGaugeNode({
26593
27188
  fontSize: \u540D\u524D\u306E\u7D1A,
26594
27189
  fontWeight: 700,
26595
27190
  fill: "var(--cdl-text, #1a1f2a)",
26596
- children: \u5207\u308A\u8A70\u3081\u308B(d.label ?? "", \u53CE\u307E\u308B\u5E45, \u540D\u524D\u306E\u7D1A)
27191
+ children: \u5207\u308A\u8A70\u3081\u308B(d.label ?? "", \u53CE\u307E\u308B\u5E45, \u540D\u524D\u306E\u7D1A, textMetrics)
26597
27192
  }
26598
27193
  ),
26599
27194
  /* @__PURE__ */ jsx("text", { x, y: y + 46, fontSize: \u6570\u5024\u306E\u7D1A, fill: "var(--cdl-text-dim, #5a6270)", children: \u5207\u3063\u305F\u6570\u306E\u884C === \u6570\u306E\u884C ? /* @__PURE__ */ jsx(
@@ -26611,12 +27206,12 @@ function ChartGaugeNode({
26611
27206
  function \u6975(cx, cy, r, a) {
26612
27207
  return { x: cx + r * Math.cos(a), y: cy + r * Math.sin(a) };
26613
27208
  }
26614
- function \u5207\u308A\u8A70\u3081\u308B(s, \u4E0A\u9650, \u7D1A) {
26615
- if (\u4E0A\u9650 <= 0 || textWidth(s, \u7D1A) <= \u4E0A\u9650) return s;
26616
- const \u8A18\u53F7\u5E45 = textWidth("\u2026", \u7D1A);
27209
+ function \u5207\u308A\u8A70\u3081\u308B(s, \u4E0A\u9650, \u7D1A, textMetrics = "proportional") {
27210
+ if (\u4E0A\u9650 <= 0 || textWidth(s, \u7D1A, 0, textMetrics) <= \u4E0A\u9650) return s;
27211
+ const \u8A18\u53F7\u5E45 = textWidth("\u2026", \u7D1A, 0, textMetrics);
26617
27212
  let out = "";
26618
27213
  for (const c of s) {
26619
- if (textWidth(out + c, \u7D1A) + \u8A18\u53F7\u5E45 > \u4E0A\u9650) break;
27214
+ if (textWidth(out + c, \u7D1A, 0, textMetrics) + \u8A18\u53F7\u5E45 > \u4E0A\u9650) break;
26620
27215
  out += c;
26621
27216
  }
26622
27217
  return `${out}\u2026`;
@@ -26630,7 +27225,8 @@ function ChartRadialNode({
26630
27225
  active,
26631
27226
  stateValues = {},
26632
27227
  drawing = false,
26633
- progress = 1
27228
+ progress = 1,
27229
+ textMetrics = "proportional"
26634
27230
  }) {
26635
27231
  const x0 = node.cx - node.w / 2;
26636
27232
  const y0 = node.cy - node.h / 2;
@@ -26648,7 +27244,10 @@ function ChartRadialNode({
26648
27244
  const \u4E00\u89A7\u306E\u5E45 = \u5370\u306E\u5E45 + Math.max(
26649
27245
  0,
26650
27246
  ...data.map(
26651
- (d, i) => Math.max(textWidth(d.label ?? "", \u540D\u524D\u306E\u7D1A), textWidth(\u6570\u5024\u306E\u6587\u5B57[i] ?? "", \u6570\u5024\u306E\u7D1A))
27247
+ (d, i) => Math.max(
27248
+ textWidth(d.label ?? "", \u540D\u524D\u306E\u7D1A, 0, textMetrics),
27249
+ textWidth(\u6570\u5024\u306E\u6587\u5B57[i] ?? "", \u6570\u5024\u306E\u7D1A, 0, textMetrics)
27250
+ )
26652
27251
  )
26653
27252
  );
26654
27253
  const \u5F27\u306B\u4F7F\u3048\u308B\u5E45 = node.w - PAD * 2 - \u4E00\u89A7\u306E\u5E45 - \u4E00\u89A7\u3068\u5F27\u306E\u9593;
@@ -26795,7 +27394,8 @@ function arcColor2(tone, idx) {
26795
27394
  function ChartStatNode({
26796
27395
  node,
26797
27396
  active,
26798
- stateValues = {}
27397
+ stateValues = {},
27398
+ textMetrics = "proportional"
26799
27399
  }) {
26800
27400
  const x0 = node.cx - node.w / 2;
26801
27401
  const y0 = node.cy - node.h / 2;
@@ -26824,7 +27424,13 @@ function ChartStatNode({
26824
27424
  const frac = total > 0 ? d.value / total : 0;
26825
27425
  const \u8272 = \u5370\u306E\u8272(d.tone, idx);
26826
27426
  const \u6570\u5024 = \u5B9F\u5024\u8868\u8A18(d.value);
26827
- const \u6570\u5024\u306E\u7D1A = \u53CE\u3081\u308B\u7D1A(\u6570\u5024, \u67A02.w - \u533A\u753B.\u4F59\u767D * 2, \u533A\u753B.\u6570\u5024\u306E\u7D1A, \u533A\u753B.\u540D\u524D\u306E\u7D1A + 1);
27427
+ const \u6570\u5024\u306E\u7D1A = \u53CE\u3081\u308B\u7D1A(
27428
+ \u6570\u5024,
27429
+ \u67A02.w - \u533A\u753B.\u4F59\u767D * 2,
27430
+ \u533A\u753B.\u6570\u5024\u306E\u7D1A,
27431
+ \u533A\u753B.\u540D\u524D\u306E\u7D1A + 1,
27432
+ textMetrics
27433
+ );
26828
27434
  return /* @__PURE__ */ jsxs(
26829
27435
  "g",
26830
27436
  {
@@ -26881,7 +27487,8 @@ function ChartStatNode({
26881
27487
  `\u524D ${\u5B9F\u5024\u8868\u8A18(d.previous)}`,
26882
27488
  \u67A02.w - \u533A\u753B.\u4F59\u767D * 2,
26883
27489
  \u533A\u753B.\u524D\u306E\u7D1A,
26884
- 8
27490
+ 8,
27491
+ textMetrics
26885
27492
  ),
26886
27493
  textAnchor: "middle",
26887
27494
  fill: "var(--cdl-text-dim, #5a6270)",
@@ -26970,9 +27577,9 @@ function \u533A\u753B\u306E\u5272\u4ED8(w, h, \u4EF6\u6570, \u524D\u3092\u51FA\u
26970
27577
  \u67A0: (idx) => ({ x: \u5E45 * idx, y: 0, w: \u5E45, h })
26971
27578
  };
26972
27579
  }
26973
- function \u53CE\u3081\u308B\u7D1A(\u5B572, \u4F7F\u3048\u308B\u5E452, \u521D\u671F, \u4E0B\u9650) {
27580
+ function \u53CE\u3081\u308B\u7D1A(\u5B572, \u4F7F\u3048\u308B\u5E452, \u521D\u671F, \u4E0B\u9650, textMetrics = "proportional") {
26974
27581
  let \u7D1A = \u521D\u671F;
26975
- while (\u7D1A > \u4E0B\u9650 && textWidth(\u5B572, \u7D1A) > \u4F7F\u3048\u308B\u5E452) \u7D1A -= 1;
27582
+ while (\u7D1A > \u4E0B\u9650 && textWidth(\u5B572, \u7D1A, 0, textMetrics) > \u4F7F\u3048\u308B\u5E452) \u7D1A -= 1;
26976
27583
  return \u7D1A;
26977
27584
  }
26978
27585
  function \u5F27\u306E\u90533(cx, cy, r, \u5272\u5408) {
@@ -27007,7 +27614,8 @@ function ChartWaffleNode({
27007
27614
  active,
27008
27615
  stateValues = {},
27009
27616
  drawing = false,
27010
- progress = 1
27617
+ progress = 1,
27618
+ textMetrics = "proportional"
27011
27619
  }) {
27012
27620
  const x0 = node.cx - node.w / 2;
27013
27621
  const y0 = node.cy - node.h / 2;
@@ -27026,7 +27634,10 @@ function ChartWaffleNode({
27026
27634
  const \u4E00\u89A7\u306E\u5E45 = \u5370\u306E\u5E452 + Math.max(
27027
27635
  0,
27028
27636
  ...data.map(
27029
- (d, i) => Math.max(textWidth(d.label ?? "", \u540D\u524D\u306E\u7D1A), textWidth(\u6570\u5024\u306E\u6587\u5B57[i] ?? "", \u6570\u5024\u306E\u7D1A))
27637
+ (d, i) => Math.max(
27638
+ textWidth(d.label ?? "", \u540D\u524D\u306E\u7D1A, 0, textMetrics),
27639
+ textWidth(\u6570\u5024\u306E\u6587\u5B57[i] ?? "", \u6570\u5024\u306E\u7D1A, 0, textMetrics)
27640
+ )
27030
27641
  )
27031
27642
  );
27032
27643
  const \u4F7F\u3048\u308B\u9AD8\u3055 = node.h - PAD * 2;
@@ -27128,7 +27739,8 @@ function ChartStackedBarNode({
27128
27739
  active,
27129
27740
  stateValues = {},
27130
27741
  drawing = false,
27131
- progress = 1
27742
+ progress = 1,
27743
+ textMetrics = "proportional"
27132
27744
  }) {
27133
27745
  const x0 = node.cx - node.w / 2;
27134
27746
  const y0 = node.cy - node.h / 2;
@@ -27138,7 +27750,7 @@ function ChartStackedBarNode({
27138
27750
  const \u540D\u524D\u306E\u7D1A = 13;
27139
27751
  const \u533A\u753B\u306E\u7D1A = 12;
27140
27752
  const \u6642\u70B9\u306E\u7D1A = 13;
27141
- const \u6642\u70B9\u306E\u5E45 = Math.max(0, ...\u5E2F\u305F\u3061.map((b) => textWidth(b.\u540D\u524D, \u6642\u70B9\u306E\u7D1A))) + (\u5E2F\u305F\u3061.length > 1 ? 16 : 0);
27753
+ const \u6642\u70B9\u306E\u5E45 = Math.max(0, ...\u5E2F\u305F\u3061.map((b) => textWidth(b.\u540D\u524D, \u6642\u70B9\u306E\u7D1A, 0, textMetrics))) + (\u5E2F\u305F\u3061.length > 1 ? 16 : 0);
27142
27754
  const \u5E2F\u306E\u5DE6 = PAD + \u6642\u70B9\u306E\u5E45;
27143
27755
  const \u5E2F\u306E\u5E45 = Math.max(40, node.w - \u5E2F\u306E\u5DE6 - PAD);
27144
27756
  const \u5E2F\u306E\u9AD8\u3055 = 44;
@@ -27231,7 +27843,7 @@ function ChartStackedBarNode({
27231
27843
  })()
27232
27844
  ] }, `bar-${\u6BB5}`);
27233
27845
  }),
27234
- \u4E00\u89A7\u306E\u4E26\u3073(data, \u5E2F\u306E\u5DE6, node.w - PAD, \u540D\u524D\u306E\u7D1A).map(({ d, idx, x, \u884C }) => {
27846
+ \u4E00\u89A7\u306E\u4E26\u3073(data, \u5E2F\u306E\u5DE6, node.w - PAD, \u540D\u524D\u306E\u7D1A, textMetrics).map(({ d, idx, x, \u884C }) => {
27235
27847
  const y = \u4E0A\u7AEF + \u5E2F\u305F\u3061.length * (\u5E2F\u306E\u9AD8\u3055 + \u5E2F\u306E\u9593) - \u5E2F\u306E\u9593 + 16 + \u4E00\u89A7\u306E\u9AD8\u3055 / 2 + \u884C * \u4E00\u89A7\u306E\u9AD8\u3055;
27236
27848
  return /* @__PURE__ */ jsxs("g", { "data-cdl-role": "chart-stacked-bar-legend", children: [
27237
27849
  /* @__PURE__ */ jsx("rect", { x, y: y - 5, width: 10, height: 10, rx: 2, fill: \u5370\u306E\u82723(d.tone, idx) }),
@@ -27266,12 +27878,12 @@ function \u5370\u306E\u82723(tone, idx) {
27266
27878
  }
27267
27879
  var \u5370\u304B\u3089\u540D\u524D\u307E\u3067 = 16;
27268
27880
  var \u4EF6\u306E\u9593 = 10;
27269
- function \u4E00\u89A7\u306E\u4E26\u3073(data, \u5DE6, \u53F3\u7AEF, \u7D1A) {
27881
+ function \u4E00\u89A7\u306E\u4E26\u3073(data, \u5DE6, \u53F3\u7AEF, \u7D1A, textMetrics = "proportional") {
27270
27882
  const out = [];
27271
27883
  let x = \u5DE6;
27272
27884
  let \u884C = 0;
27273
27885
  data.forEach((d, idx) => {
27274
- const \u5E45 = \u5370\u304B\u3089\u540D\u524D\u307E\u3067 + textWidth(d.label ?? "", \u7D1A);
27886
+ const \u5E45 = \u5370\u304B\u3089\u540D\u524D\u307E\u3067 + textWidth(d.label ?? "", \u7D1A, 0, textMetrics);
27275
27887
  if (x > \u5DE6 && x + \u5E45 > \u53F3\u7AEF) {
27276
27888
  \u884C += 1;
27277
27889
  x = \u5DE6;
@@ -27287,7 +27899,8 @@ function ChartSlopeNode({
27287
27899
  active,
27288
27900
  stateValues = {},
27289
27901
  drawing = false,
27290
- progress = 1
27902
+ progress = 1,
27903
+ textMetrics = "proportional"
27291
27904
  }) {
27292
27905
  const x0 = node.cx - node.w / 2;
27293
27906
  const y0 = node.cy - node.h / 2;
@@ -27330,16 +27943,22 @@ function ChartSlopeNode({
27330
27943
  const \u53F3\u306E\u5B57 = \u7CFB\u5217\u305F\u3061.map(
27331
27944
  (s) => \u5F62 === "delta" ? \u5897\u6E1B\u8868\u8A18(s.\u524D, s.\u4ECA) : \u5B9F\u5024\u8868\u8A18(s.\u4ECA)
27332
27945
  );
27333
- const \u5DE6\u5024\u5E45 = Math.max(0, ...\u5DE6\u306E\u5B57.map((t) => textWidth(t, \u5024\u306E\u7D1A)));
27334
- const \u53F3\u5024\u5E45 = Math.max(0, ...\u53F3\u306E\u5B57.map((t) => textWidth(t, \u5024\u306E\u7D1A)));
27946
+ const \u5DE6\u5024\u5E45 = Math.max(0, ...\u5DE6\u306E\u5B57.map((t) => textWidth(t, \u5024\u306E\u7D1A, 0, textMetrics)));
27947
+ const \u53F3\u5024\u5E45 = Math.max(0, ...\u53F3\u306E\u5B57.map((t) => textWidth(t, \u5024\u306E\u7D1A, 0, textMetrics)));
27335
27948
  const \u540D\u524D\u306B\u4F7F\u3048\u308B = Math.max(
27336
27949
  0,
27337
27950
  (node.w - PAD * 2 - \u7DDA\u306E\u6700\u5C0F\u5E45 - (\u5DE6\u5024\u5E45 + \u8EF8\u304B\u3089\u5024\u307E\u3067 + \u5024\u304B\u3089\u540D\u524D\u307E\u3067) - (\u53F3\u5024\u5E45 + \u8EF8\u304B\u3089\u5024\u307E\u3067 + \u5024\u304B\u3089\u540D\u524D\u307E\u3067)) / 2
27338
27951
  );
27339
- const \u540D\u524D\u306E\u7D1A = \u53CE\u3081\u308B\u7D1A2(\u7CFB\u5217\u305F\u3061.map((s) => s.\u540D\u524D), \u540D\u524D\u306B\u4F7F\u3048\u308B, \u540D\u524D\u306E\u4E0A\u9650\u7D1A, \u540D\u524D\u306E\u4E0B\u9650\u7D1A);
27952
+ const \u540D\u524D\u306E\u7D1A = \u53CE\u3081\u308B\u7D1A2(
27953
+ \u7CFB\u5217\u305F\u3061.map((s) => s.\u540D\u524D),
27954
+ \u540D\u524D\u306B\u4F7F\u3048\u308B,
27955
+ \u540D\u524D\u306E\u4E0A\u9650\u7D1A,
27956
+ \u540D\u524D\u306E\u4E0B\u9650\u7D1A,
27957
+ textMetrics
27958
+ );
27340
27959
  const \u540D\u524D\u5E45 = Math.min(
27341
27960
  \u540D\u524D\u306B\u4F7F\u3048\u308B,
27342
- Math.max(0, ...\u7CFB\u5217\u305F\u3061.map((s) => textWidth(s.\u540D\u524D, \u540D\u524D\u306E\u7D1A)))
27961
+ Math.max(0, ...\u7CFB\u5217\u305F\u3061.map((s) => textWidth(s.\u540D\u524D, \u540D\u524D\u306E\u7D1A, 0, textMetrics)))
27343
27962
  );
27344
27963
  const \u5DE6\u306E\u4F59\u767D = \u540D\u524D\u5E45 + \u5024\u304B\u3089\u540D\u524D\u307E\u3067 + \u5DE6\u5024\u5E45 + \u8EF8\u304B\u3089\u5024\u307E\u3067;
27345
27964
  const \u53F3\u306E\u4F59\u767D = \u8EF8\u304B\u3089\u5024\u307E\u3067 + \u53F3\u5024\u5E45 + \u5024\u304B\u3089\u540D\u524D\u307E\u3067 + \u540D\u524D\u5E45;
@@ -27525,10 +28144,12 @@ function \u5370\u306E\u82724(tone, idx) {
27525
28144
  if (tone) return TONE[tone];
27526
28145
  return chartSeriesColor(idx);
27527
28146
  }
27528
- function \u53CE\u3081\u308B\u7D1A2(\u540D\u524D\u305F\u3061, \u5E45, \u4E0A\u9650, \u4E0B\u9650) {
28147
+ function \u53CE\u3081\u308B\u7D1A2(\u540D\u524D\u305F\u3061, \u5E45, \u4E0A\u9650, \u4E0B\u9650, textMetrics = "proportional") {
27529
28148
  if (\u540D\u524D\u305F\u3061.length === 0) return \u4E0A\u9650;
27530
28149
  let \u7D1A = \u4E0A\u9650;
27531
- while (\u7D1A > \u4E0B\u9650 && Math.max(...\u540D\u524D\u305F\u3061.map((n) => textWidth(n, \u7D1A))) > \u5E45) \u7D1A -= 1;
28150
+ while (\u7D1A > \u4E0B\u9650 && Math.max(...\u540D\u524D\u305F\u3061.map((n) => textWidth(n, \u7D1A, 0, textMetrics))) > \u5E45) {
28151
+ \u7D1A -= 1;
28152
+ }
27532
28153
  return \u7D1A;
27533
28154
  }
27534
28155
  function \u5C0F\u6570\u306E\u6841(n) {
@@ -27576,6 +28197,7 @@ function ChartBarNode({
27576
28197
  return { y: yAt(v), value: v };
27577
28198
  });
27578
28199
  const \u6FC3\u3055 = (v) => vMax > 0 ? v >= vMax ? 1 : 0.45 : 0.9;
28200
+ const \u4E3B\u5F79\u306E\u68D2\u304B = (v) => vMax > 0 && v >= vMax;
27579
28201
  const \u89D2\u4E38 = Math.min(barW * 0.06, 8);
27580
28202
  const \u4F38\u3073 = \u9032\u307F\u3092\u7573\u3080(drawing, progress);
27581
28203
  const \u6A2A\u8EF8\u306Ey = PAD_TOP2 + canvasH;
@@ -27642,6 +28264,7 @@ function ChartBarNode({
27642
28264
  {
27643
28265
  "data-cdl-role": "chart-bar",
27644
28266
  "data-cdl-unresolved": d.unresolved ? "true" : void 0,
28267
+ "data-cdl-emphasis": \u4E3B\u5F79\u306E\u68D2\u304B(d.value) ? "primary" : void 0,
27645
28268
  x: bx,
27646
28269
  y: by,
27647
28270
  width: barW,
@@ -27988,7 +28611,8 @@ function FunnelNode({
27988
28611
  active,
27989
28612
  stateValues = {},
27990
28613
  drawing = false,
27991
- progress = 1
28614
+ progress = 1,
28615
+ textMetrics = "proportional"
27992
28616
  }) {
27993
28617
  const x0 = node.cx - node.w / 2;
27994
28618
  const y0 = node.cy - node.h / 2;
@@ -28037,7 +28661,11 @@ function FunnelNode({
28037
28661
  const \u540D\u524D\u306E\u5B9F\u5B57 = \u540D\u524D\u306E\u5B57 * \u7E26\u500D;
28038
28662
  const \u88DC\u8DB3\u306E\u67A0\u5B57 = \u88DC\u8DB3\u306E\u5B57 * \u7E26\u500D;
28039
28663
  const \u53CE\u307E\u308B\u5E45 = Math.max(0, bottomW - 16);
28040
- const \u88DC\u8DB3\u306E\u5B9F\u5B57 = \u88DC\u8DB3\u306E\u67A0\u5B57 * \u53CE\u3081\u308B\u500D\u7387(\u88DC\u8DB3, { fontSize: \u88DC\u8DB3\u306E\u67A0\u5B57, fontWeight: 500 }, \u53CE\u307E\u308B\u5E45);
28664
+ const \u88DC\u8DB3\u306E\u5B9F\u5B57 = \u88DC\u8DB3\u306E\u67A0\u5B57 * \u53CE\u3081\u308B\u500D\u7387(
28665
+ \u88DC\u8DB3,
28666
+ { fontSize: \u88DC\u8DB3\u306E\u67A0\u5B57, fontWeight: 500, textMetrics },
28667
+ \u53CE\u307E\u308B\u5E45
28668
+ );
28041
28669
  const \u584A\u306E\u4E0A = y + stageH / 2 - (\u540D\u524D\u306E\u5B9F\u5B57 * 1.2 + \u88DC\u8DB3\u306E\u67A0\u5B57 * 1.25) / 2;
28042
28670
  const \u540D\u524D\u306Ey = \u88DC\u8DB3\u3042\u308A ? \u584A\u306E\u4E0A + \u540D\u524D\u306E\u5B9F\u5B57 * 0.95 : y + stageH / 2 + 5;
28043
28671
  const \u88DC\u8DB3\u306Ey = \u584A\u306E\u4E0A + \u540D\u524D\u306E\u5B9F\u5B57 * 1.2 + \u88DC\u8DB3\u306E\u67A0\u5B57 * 0.95;
@@ -28140,7 +28768,8 @@ function \u7573\u3093\u3060\u6587(\u4EF6\u6570) {
28140
28768
  function QuadrantNode({
28141
28769
  node,
28142
28770
  active,
28143
- stateValues = {}
28771
+ stateValues = {},
28772
+ textMetrics = "proportional"
28144
28773
  }) {
28145
28774
  const x0 = node.cx - node.w / 2;
28146
28775
  const y0 = node.cy - node.h / 2;
@@ -28159,7 +28788,10 @@ function QuadrantNode({
28159
28788
  const SUB_FONT = 10;
28160
28789
  const axisLabelPad = (text) => Math.max(
28161
28790
  PAD_MIN,
28162
- measureTextWidth(`\u2190 ${text}`, { fontSize: AXIS_LABEL_FONT}) + 12
28791
+ measureTextWidth(`\u2190 ${text}`, {
28792
+ fontSize: AXIS_LABEL_FONT,
28793
+ textMetrics
28794
+ }) + 12
28163
28795
  );
28164
28796
  const padBudget = Math.max(0, node.w * 0.5 - PAD_MIN * 2);
28165
28797
  const wantLeft = axisLabelPad(data.xAxis.left) - PAD_MIN;
@@ -28413,7 +29045,11 @@ function QuadrantNode({
28413
29045
  ITEM_MIN_W,
28414
29046
  Math.max(
28415
29047
  ...\u884C\u30892.map(
28416
- (r) => measureTextWidth(r.text, { fontSize: r.size, fontWeight: r.weight })
29048
+ (r) => measureTextWidth(r.text, {
29049
+ fontSize: r.size,
29050
+ fontWeight: r.weight,
29051
+ textMetrics
29052
+ })
28417
29053
  )
28418
29054
  ) + ITEM_PAD_X * 2
28419
29055
  )
@@ -28439,7 +29075,7 @@ function QuadrantNode({
28439
29075
  const \u88DC\u8DB3 = (it.subtitle ?? "").trim();
28440
29076
  const \u88DC\u8DB3\u306E\u5B57 = SUB_FONT * \u53CE\u3081\u308B\u500D\u7387(
28441
29077
  \u88DC\u8DB3,
28442
- { fontSize: SUB_FONT, fontWeight: 500 },
29078
+ { fontSize: SUB_FONT, fontWeight: 500, textMetrics },
28443
29079
  Math.max(0, \u5E45 - ITEM_PAD_X * 2)
28444
29080
  );
28445
29081
  return /* @__PURE__ */ jsxs("g", { children: [
@@ -28843,24 +29479,30 @@ var EYEBROW_GAP2 = 8;
28843
29479
  var EYEBROW_TRACKING = 2;
28844
29480
  var SUB_SIZE = 11;
28845
29481
  var SUB_GAP = 4;
28846
- function labelBlock(node, pos, size, band) {
29482
+ function labelBlock(node, pos, size, band, textMetrics = "proportional") {
28847
29483
  const \u4E0A = node.eyebrow ? size + EYEBROW_GAP2 + EYEBROW_SIZE2 * ASCENT2 : size * ASCENT2;
28848
29484
  const \u4E0B = node.subtitle ? size + SUB_GAP + SUB_SIZE * DESCENT2 : size * DESCENT2;
28849
29485
  const \u5E45 = Math.max(
28850
- textWidth(node.title ?? "", size),
28851
- node.eyebrow ? textWidth(node.eyebrow, EYEBROW_SIZE2, EYEBROW_TRACKING) : 0,
28852
- node.subtitle ? textWidth(node.subtitle, SUB_SIZE) : 0
29486
+ textWidth(node.title ?? "", size, 0, textMetrics),
29487
+ node.eyebrow ? textWidth(node.eyebrow, EYEBROW_SIZE2, EYEBROW_TRACKING, textMetrics) : 0,
29488
+ node.subtitle ? textWidth(node.subtitle, SUB_SIZE, 0, textMetrics) : 0
28853
29489
  );
28854
- const \u984C\u5E45 = textWidth(node.title ?? "", size);
28855
- const \u4E0B\u9650 = \u984C\u5E45 >= \u5E45 ? \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(node.title ?? "", size, 0, band.w, textWidth) : 0;
29490
+ const \u984C\u5E45 = textWidth(node.title ?? "", size, 0, textMetrics);
29491
+ const \u6E2C\u308B = (t, s, ls) => textWidth(t, s, ls, textMetrics);
29492
+ const \u4E0B\u9650 = \u984C\u5E45 >= \u5E45 ? \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(node.title ?? "", size, 0, band.w, \u6E2C\u308B) : 0;
28856
29493
  const { k, x, y: baseline } = fitLabel(band, { \u4E0A, \u4E0B, \u5E45 }, pos, \u4E0B\u9650);
28857
29494
  return { k, x, baseline, \u4E0A\u7AEF: baseline - \u4E0A * k, \u4E0B\u7AEF: baseline + \u4E0B * k };
28858
29495
  }
28859
- function commonLabel(node, pos, size, band) {
28860
- const \u584A = labelBlock(node, pos, size, band);
29496
+ function commonLabel(node, pos, size, band, textMetrics = "proportional") {
29497
+ const \u584A = labelBlock(node, pos, size, band, textMetrics);
28861
29498
  const k = \u584A.k;
28862
29499
  const x = \u584A.x;
28863
- const \u5207\u308B = (t, \u5927\u304D\u3055, \u5B57\u9593 = 0) => \u5E2F\u3067\u5207\u308B(t, \u5927\u304D\u3055 * k, band.w, (u, f) => textWidth(u, f, \u5B57\u9593 * k));
29500
+ const \u5207\u308B = (t, \u5927\u304D\u3055, \u5B57\u9593 = 0) => \u5E2F\u3067\u5207\u308B(
29501
+ t,
29502
+ \u5927\u304D\u3055 * k,
29503
+ band.w,
29504
+ (u, f) => textWidth(u, f, \u5B57\u9593 * k, textMetrics)
29505
+ );
28864
29506
  return /* @__PURE__ */ jsxs(Fragment, { children: [
28865
29507
  node.eyebrow && /* @__PURE__ */ jsx(
28866
29508
  "text",
@@ -28911,7 +29553,7 @@ var RULE_GAP_RATIO = 0.1;
28911
29553
  var RULE_PAD_MAX = 20;
28912
29554
  var RULE_PAD_RATIO = 0.14;
28913
29555
  var RULE_SHRINK_RATIO = 0.055;
28914
- function ShapeFileNode({ node, active }) {
29556
+ function ShapeFileNode({ node, active, textMetrics = "proportional" }) {
28915
29557
  const \u5E2F = bodyBand(node, { \u5F71ry: SHADOW_RY });
28916
29558
  const \u7D19h = \u5E2F.h;
28917
29559
  const \u7D19w = Math.min(\u5E2F.w, \u7D19h * 0.72);
@@ -28931,7 +29573,7 @@ function ShapeFileNode({ node, active }) {
28931
29573
  const foldTriangle = `M ${x + \u7D19w - fold} ${y} L ${x + \u7D19w} ${y + fold} L ${x + \u7D19w - fold} ${y + fold} Z`;
28932
29574
  const \u540D\u524D\u5E2F = { x, y, w: \u7D19w, h: \u7D19h };
28933
29575
  const \u540D\u524D\u4F4D\u7F6E = { x: \u5E2F.cx, y: node.cy + node.h * 0.12 };
28934
- const \u540D\u524D = labelBlock(node, \u540D\u524D\u4F4D\u7F6E, 16, \u540D\u524D\u5E2F);
29576
+ const \u540D\u524D = labelBlock(node, \u540D\u524D\u4F4D\u7F6E, 16, \u540D\u524D\u5E2F, textMetrics);
28935
29577
  const \u9593\u9694 = Math.min(RULE_GAP_MAX, \u7D19h * RULE_GAP_RATIO);
28936
29578
  const \u7DDA\u4F59\u767D = Math.min(RULE_PAD_MAX, \u7D19w * RULE_PAD_RATIO);
28937
29579
  const textLines = [0, 1, 2].map((i) => ({ i, ly: y + fold + \u9593\u9694 * (i + 1) })).filter(({ ly }) => ly < \u540D\u524D.\u4E0A\u7AEF);
@@ -28963,12 +29605,12 @@ function ShapeFileNode({ node, active }) {
28963
29605
  i
28964
29606
  );
28965
29607
  }),
28966
- commonLabel(node, \u540D\u524D\u4F4D\u7F6E, 16, \u540D\u524D\u5E2F)
29608
+ commonLabel(node, \u540D\u524D\u4F4D\u7F6E, 16, \u540D\u524D\u5E2F, textMetrics)
28967
29609
  ] });
28968
29610
  }
28969
29611
  var TAB_H_MAX = 22;
28970
29612
  var TAB_H_RATIO = 0.3;
28971
- function ShapeFolderNode({ node, active }) {
29613
+ function ShapeFolderNode({ node, active, textMetrics = "proportional" }) {
28972
29614
  const \u5E2F = bodyBand(node, { \u5F71ry: SHADOW_RY });
28973
29615
  const x = \u5E2F.x;
28974
29616
  const y = \u5E2F.y;
@@ -28989,7 +29631,7 @@ function ShapeFolderNode({ node, active }) {
28989
29631
  const \u5883\u754Cy = y + tabH + Math.min(8, (\u5E2F.h - tabH) * 0.2);
28990
29632
  const \u7AEF = Math.min(6, \u5E2F.w * 0.1);
28991
29633
  const \u540D\u524D\u4F4D\u7F6E = { x: \u5E2F.cx, y: node.cy + 18 };
28992
- const \u540D\u524D = labelBlock(node, \u540D\u524D\u4F4D\u7F6E, 16, \u5E2F);
29634
+ const \u540D\u524D = labelBlock(node, \u540D\u524D\u4F4D\u7F6E, 16, \u5E2F, textMetrics);
28993
29635
  return /* @__PURE__ */ jsxs("g", { children: [
28994
29636
  dropShadow(\u5E2F.cx, \u5E2F.\u5E95, \u5E2F.w * 0.44),
28995
29637
  /* @__PURE__ */ jsx("path", { "data-cdl-role": "node-body", d: bodyPath, ...frame, strokeLinejoin: "round" }),
@@ -29005,13 +29647,13 @@ function ShapeFolderNode({ node, active }) {
29005
29647
  opacity: 0.35
29006
29648
  }
29007
29649
  ),
29008
- commonLabel(node, \u540D\u524D\u4F4D\u7F6E, 16, \u5E2F)
29650
+ commonLabel(node, \u540D\u524D\u4F4D\u7F6E, 16, \u5E2F, textMetrics)
29009
29651
  ] });
29010
29652
  }
29011
29653
  var CLOUD_VB_W = 640;
29012
29654
  var CLOUD_VB_H = 512;
29013
29655
  var CLOUD_W_RATIO = 0.9;
29014
- function ShapeCloudNode({ node, active }) {
29656
+ function ShapeCloudNode({ node, active, textMetrics = "proportional" }) {
29015
29657
  const \u5E2F = bodyBand(node, { \u5F71ry: SHADOW_RY });
29016
29658
  const frame = commonFrame(active);
29017
29659
  const \u7D20\u306E\u500D\u7387 = Math.min(\u5E2F.h / CLOUD_VB_H, \u5E2F.w * CLOUD_W_RATIO / CLOUD_VB_W);
@@ -29034,13 +29676,13 @@ function ShapeCloudNode({ node, active }) {
29034
29676
  strokeLinejoin: "round"
29035
29677
  }
29036
29678
  ) }),
29037
- commonLabel(node, { x: \u5E2F.cx, y: node.cy + node.h * 0.05 }, 16, \u5E2F)
29679
+ commonLabel(node, { x: \u5E2F.cx, y: node.cy + node.h * 0.05 }, 16, \u5E2F, textMetrics)
29038
29680
  ] });
29039
29681
  }
29040
29682
  var CYLINDER_RY_MAX = 18;
29041
29683
  var CYLINDER_RY_RATIO = 0.1;
29042
29684
  var CYLINDER_DISKS = [0.3, 0.55, 0.8];
29043
- function ShapeCylinderNode({ node, active }) {
29685
+ function ShapeCylinderNode({ node, active, textMetrics = "proportional" }) {
29044
29686
  const \u5E2F = bodyBand(node, { \u5F71ry: CYLINDER_SHADOW_RY });
29045
29687
  const x = \u5E2F.x;
29046
29688
  const y = \u5E2F.y;
@@ -29057,7 +29699,7 @@ function ShapeCylinderNode({ node, active }) {
29057
29699
  const \u84CB\u5E95 = y + ry * 2;
29058
29700
  const \u540D\u524D\u4F4D\u7F6E = { x: \u5E2F.cx, y: node.cy + 6 };
29059
29701
  const \u540D\u524D\u5E2F = { x: \u5E2F.x, y: \u84CB\u5E95, w: \u5E2F.w, h: Math.max(0, \u5E2F.\u5E95 - \u84CB\u5E95) };
29060
- const \u540D\u524D = labelBlock(node, \u540D\u524D\u4F4D\u7F6E, 15, \u540D\u524D\u5E2F);
29702
+ const \u540D\u524D = labelBlock(node, \u540D\u524D\u4F4D\u7F6E, 15, \u540D\u524D\u5E2F, textMetrics);
29061
29703
  return /* @__PURE__ */ jsxs("g", { children: [
29062
29704
  dropShadow(\u5E2F.cx, \u5E2F.\u5E95, rx * 0.85, CYLINDER_SHADOW_RY),
29063
29705
  /* @__PURE__ */ jsx("path", { "data-cdl-role": "node-body", d: bodyPath, ...frame, strokeLinejoin: "round" }),
@@ -29081,11 +29723,11 @@ function ShapeCylinderNode({ node, active }) {
29081
29723
  },
29082
29724
  i
29083
29725
  )),
29084
- commonLabel(node, \u540D\u524D\u4F4D\u7F6E, 15, \u540D\u524D\u5E2F)
29726
+ commonLabel(node, \u540D\u524D\u4F4D\u7F6E, 15, \u540D\u524D\u5E2F, textMetrics)
29085
29727
  ] });
29086
29728
  }
29087
29729
  var HEX_DOT_R = 2.5;
29088
- function ShapeHexagonNode({ node, active }) {
29730
+ function ShapeHexagonNode({ node, active, textMetrics = "proportional" }) {
29089
29731
  const \u5E2F = bodyBand(node, { \u5F71ry: SHADOW_RY, \u5916: Math.max(HEX_DOT_R, FRAME_HALF) });
29090
29732
  const cx = \u5E2F.cx;
29091
29733
  const cy = \u5E2F.cy;
@@ -29108,11 +29750,12 @@ function ShapeHexagonNode({ node, active }) {
29108
29750
  node,
29109
29751
  { x: cx, y: node.cy + 6 },
29110
29752
  16,
29111
- { x: \u5E2F.x + cut, y: \u5E2F.y, w: Math.max(0, \u5E2F.w - cut * 2), h: \u5E2F.h }
29753
+ { x: \u5E2F.x + cut, y: \u5E2F.y, w: Math.max(0, \u5E2F.w - cut * 2), h: \u5E2F.h },
29754
+ textMetrics
29112
29755
  )
29113
29756
  ] });
29114
29757
  }
29115
- function ShapeDiamondNode({ node, active }) {
29758
+ function ShapeDiamondNode({ node, active, textMetrics = "proportional" }) {
29116
29759
  const \u5E2F = bodyBand(node, { \u5F71ry: SHADOW_RY });
29117
29760
  const cx = \u5E2F.cx;
29118
29761
  const cy = \u5E2F.cy;
@@ -29153,13 +29796,14 @@ function ShapeDiamondNode({ node, active }) {
29153
29796
  y: cy - \u5E2F.h * innerScale / 4,
29154
29797
  w: \u5E2F.w * innerScale / 2,
29155
29798
  h: \u5E2F.h * innerScale / 2
29156
- }
29799
+ },
29800
+ textMetrics
29157
29801
  )
29158
29802
  ] });
29159
29803
  }
29160
29804
  var STACK_OFFSET_MAX = 12;
29161
29805
  var STACK_OFFSET_RATIO = 0.15;
29162
- function ShapeStackNode({ node, active }) {
29806
+ function ShapeStackNode({ node, active, textMetrics = "proportional" }) {
29163
29807
  const \u5E2F = bodyBand(node, { \u5F71ry: SHADOW_RY });
29164
29808
  const x = \u5E2F.x;
29165
29809
  const y = \u5E2F.y;
@@ -29213,7 +29857,8 @@ function ShapeStackNode({ node, active }) {
29213
29857
  node,
29214
29858
  { x: \u624B\u524Dcx, y: node.cy + \u305A\u308C + 6 },
29215
29859
  15,
29216
- { x, y: y + \u305A\u308C * 2, w: cardW, h: cardH }
29860
+ { x, y: y + \u305A\u308C * 2, w: cardW, h: cardH },
29861
+ textMetrics
29217
29862
  )
29218
29863
  ] });
29219
29864
  }
@@ -29225,16 +29870,22 @@ var PERSON_BODY_LEN = 90;
29225
29870
  var PERSON_SHADOW_DY = 20;
29226
29871
  var PERSON_SHADOW_RY = 4;
29227
29872
  var PERSON_SHADOW_RX = 55;
29228
- function planLabel(node, cx, \u5E45\u4E0A\u9650, plan) {
29873
+ function planLabel(node, cx, \u5E45\u4E0A\u9650, plan, textMetrics = "proportional") {
29229
29874
  const \u5E45 = Math.max(
29230
- textWidth(node.title ?? "", plan.\u540D\u524D.size),
29231
- node.eyebrow && plan.\u80A9\u66F8 ? textWidth(node.eyebrow, plan.\u80A9\u66F8.size, EYEBROW_TRACKING) : 0,
29232
- node.subtitle && plan.\u8AAC\u660E ? textWidth(node.subtitle, plan.\u8AAC\u660E.size) : 0
29875
+ textWidth(node.title ?? "", plan.\u540D\u524D.size, 0, textMetrics),
29876
+ node.eyebrow && plan.\u80A9\u66F8 ? textWidth(node.eyebrow, plan.\u80A9\u66F8.size, EYEBROW_TRACKING, textMetrics) : 0,
29877
+ node.subtitle && plan.\u8AAC\u660E ? textWidth(node.subtitle, plan.\u8AAC\u660E.size, 0, textMetrics) : 0
29233
29878
  );
29234
- const \u984C\u5E45 = textWidth(node.title ?? "", plan.\u540D\u524D.size);
29235
- const \u4E0B\u9650 = \u984C\u5E45 >= \u5E45 ? \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(node.title ?? "", plan.\u540D\u524D.size, 0, \u5E45\u4E0A\u9650, textWidth) : 0;
29879
+ const \u984C\u5E45 = textWidth(node.title ?? "", plan.\u540D\u524D.size, 0, textMetrics);
29880
+ const \u6E2C\u308B = (t, s, ls) => textWidth(t, s, ls, textMetrics);
29881
+ const \u4E0B\u9650 = \u984C\u5E45 >= \u5E45 ? \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(node.title ?? "", plan.\u540D\u524D.size, 0, \u5E45\u4E0A\u9650, \u6E2C\u308B) : 0;
29236
29882
  const k = \u5E45 > 0 && \u5E45\u4E0A\u9650 > 0 ? Math.min(1, Math.max(\u5E45\u4E0A\u9650 / \u5E45, \u4E0B\u9650)) : 1;
29237
- const \u5207\u308B = (t, \u5927\u304D\u3055, \u5B57\u9593 = 0) => \u5E2F\u3067\u5207\u308B(t, \u5927\u304D\u3055 * k, \u5E45\u4E0A\u9650, (u, f) => textWidth(u, f, \u5B57\u9593 * k));
29883
+ const \u5207\u308B = (t, \u5927\u304D\u3055, \u5B57\u9593 = 0) => \u5E2F\u3067\u5207\u308B(
29884
+ t,
29885
+ \u5927\u304D\u3055 * k,
29886
+ \u5E45\u4E0A\u9650,
29887
+ (u, f) => textWidth(u, f, \u5B57\u9593 * k, textMetrics)
29888
+ );
29238
29889
  return /* @__PURE__ */ jsxs(Fragment, { children: [
29239
29890
  node.eyebrow && plan.\u80A9\u66F8 && /* @__PURE__ */ jsx(
29240
29891
  "text",
@@ -29275,7 +29926,7 @@ function planLabel(node, cx, \u5E45\u4E0A\u9650, plan) {
29275
29926
  )
29276
29927
  ] });
29277
29928
  }
29278
- function ShapePersonNode({ node, active }) {
29929
+ function ShapePersonNode({ node, active, textMetrics = "proportional" }) {
29279
29930
  const r = shapeRegion(node);
29280
29931
  const cx = r.cx;
29281
29932
  const strokeColor = active ? "var(--cdl-tone-accent, #2d6a8f)" : "var(--cdl-divider, #d4d4d8)";
@@ -29337,7 +29988,7 @@ function ShapePersonNode({ node, active }) {
29337
29988
  )
29338
29989
  ] })
29339
29990
  ),
29340
- planLabel(node, r.cx, Math.max(0, node.w), r.label)
29991
+ planLabel(node, r.cx, Math.max(0, node.w), r.label, textMetrics)
29341
29992
  ] });
29342
29993
  }
29343
29994
  var commonFrame2 = (active) => ({
@@ -29587,7 +30238,12 @@ function ShapeTerminalNode({ node, active, lang }) {
29587
30238
  )
29588
30239
  ] });
29589
30240
  }
29590
- function ShapeCodeBlockNode({ node, active, lang }) {
30241
+ function ShapeCodeBlockNode({
30242
+ node,
30243
+ active,
30244
+ lang,
30245
+ textMetrics = "proportional"
30246
+ }) {
29591
30247
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
29592
30248
  const frame = commonFrame2(active);
29593
30249
  const \u7DDA = frame.strokeWidth / 2;
@@ -29598,7 +30254,10 @@ function ShapeCodeBlockNode({ node, active, lang }) {
29598
30254
  const lineFont = "ui-monospace, SFMono-Regular, Menlo, monospace";
29599
30255
  const \u672D = \u66F8\u3044\u305F\u5024\u304B\u63A7\u3048(node.subtitle, \u5B57\u5F15("codeBlock.fileName"));
29600
30256
  const \u672D\u306E\u5B57 = 11;
29601
- const \u30BF\u30D6\u5E45 = Math.min(Math.max(100, textWidth(\u672D, \u672D\u306E\u5B57, 0) + 24), Math.max(0, w));
30257
+ const \u30BF\u30D6\u5E45 = Math.min(
30258
+ Math.max(100, textWidth(\u672D, \u672D\u306E\u5B57, 0, textMetrics) + 24),
30259
+ Math.max(0, w)
30260
+ );
29602
30261
  const \u30BF\u30D6\u9AD8 = 24;
29603
30262
  const \u89D2 = 10;
29604
30263
  const \u6E9D = 32;
@@ -29638,7 +30297,7 @@ function ShapeCodeBlockNode({ node, active, lang }) {
29638
30297
  { text: \u672D, size: \u672D\u306E\u5B57, \u5E2F: { \u5E45: \u30BF\u30D6\u5E45, \u9AD8\u3055: \u30BF\u30D6\u9AD8 } },
29639
30298
  { text: "1", size: \u884C\u756A\u53F7\u306E\u5B57, \u5E2F: { \u5E45: \u6E9D - \u6301\u3061\u4E0A\u3052, \u9AD8\u3055: \u884C\u9593 } }
29640
30299
  ];
29641
- const \u500D\u8FD4\u3057 = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D, \u6253\u3061\u6D88\u3059\u5B57\u3089);
30300
+ const \u500D\u8FD4\u3057 = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D, \u6253\u3061\u6D88\u3059\u5B57\u3089, textMetrics);
29642
30301
  const tabW = \u30BF\u30D6\u5E45 * \u500D;
29643
30302
  const tabH = \u30BF\u30D6\u9AD8 * \u500D;
29644
30303
  const \u4E38 = \u89D2 * \u500D;
@@ -29677,7 +30336,7 @@ function ShapeCodeBlockNode({ node, active, lang }) {
29677
30336
  "data-cdl-counter-scaled": "1",
29678
30337
  x: x + tabW / 2,
29679
30338
  y: y + tabH / 2 + 4 * \u500D,
29680
- fontSize: \u672D\u306E\u5B57 * \u500D * \u500D\u8FD4\u3057 * \u5E45\u306E\u500D\u7387(\u672D, \u672D\u306E\u5B57 * \u500D * \u500D\u8FD4\u3057, 0, tabW),
30339
+ fontSize: \u672D\u306E\u5B57 * \u500D * \u500D\u8FD4\u3057 * \u5E45\u306E\u500D\u7387(\u672D, \u672D\u306E\u5B57 * \u500D * \u500D\u8FD4\u3057, 0, tabW, textMetrics),
29681
30340
  fontFamily: lineFont,
29682
30341
  textAnchor: "middle",
29683
30342
  fill: "#e6edf3",
@@ -29759,7 +30418,12 @@ function ShapeCodeBlockNode({ node, active, lang }) {
29759
30418
  )
29760
30419
  ] });
29761
30420
  }
29762
- function ShapeKanbanCardNode({ node, active, lang }) {
30421
+ function ShapeKanbanCardNode({
30422
+ node,
30423
+ active,
30424
+ lang,
30425
+ textMetrics = "proportional"
30426
+ }) {
29763
30427
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
29764
30428
  const frame = commonFrame2(active);
29765
30429
  const \u7DDA = frame.strokeWidth / 2;
@@ -29813,7 +30477,7 @@ function ShapeKanbanCardNode({ node, active, lang }) {
29813
30477
  );
29814
30478
  const \u8AAC\u660E = \u66F8\u3044\u305F\u5024\u304B\u63A7\u3048(node.subtitle, \u5B57\u5F15("kanbanCard.task"));
29815
30479
  const \u72B6\u614B = \u66F8\u3044\u305F\u5024\u304B\u63A7\u3048(node.eyebrow, \u5B57\u5F15("kanbanCard.status"));
29816
- const \u72B6\u614B\u306E\u500D\u7387 = \u5E45\u306E\u500D\u7387(\u72B6\u614B, PILL\u5B57, PILL\u5B57\u9593, PILL\u5B57\u5E45);
30480
+ const \u72B6\u614B\u306E\u500D\u7387 = \u5E45\u306E\u500D\u7387(\u72B6\u614B, PILL\u5B57, PILL\u5B57\u9593, PILL\u5B57\u5E45, textMetrics);
29817
30481
  const \u8AAC\u660E\u306E\u5B57 = \u540D\u524D.size * \u8AAC\u660E\u5B57\u6BD4;
29818
30482
  const \u4F7F\u3048\u308B\u5E452 = Math.max(0, w - \u5DE6\u53F3\u4F59\u767D * \u500D * 2);
29819
30483
  return /* @__PURE__ */ jsxs("g", { children: [
@@ -29900,7 +30564,7 @@ function ShapeKanbanCardNode({ node, active, lang }) {
29900
30564
  {
29901
30565
  x: x + w / 2,
29902
30566
  y: \u540D\u524D.y + \u540D\u524D.size * \u8AAC\u660E\u57FA\u6E96\u6BD4,
29903
- fontSize: \u8AAC\u660E\u306E\u5B57 * \u5E45\u306E\u500D\u7387(\u8AAC\u660E, \u8AAC\u660E\u306E\u5B57, 0, \u4F7F\u3048\u308B\u5E452),
30567
+ fontSize: \u8AAC\u660E\u306E\u5B57 * \u5E45\u306E\u500D\u7387(\u8AAC\u660E, \u8AAC\u660E\u306E\u5B57, 0, \u4F7F\u3048\u308B\u5E452, textMetrics),
29904
30568
  textAnchor: "middle",
29905
30569
  fill: "var(--cdl-text-dim, #5a6270)",
29906
30570
  children: \u8AAC\u660E
@@ -30191,18 +30855,33 @@ var externalLabel = (node, cx, bottomY) => /* @__PURE__ */ jsxs(Fragment, { chil
30191
30855
  )
30192
30856
  ] });
30193
30857
  var LABEL_EYEBROW_SPACING = 2;
30194
- function \u5E45\u306B\u53CE\u3081\u308B2(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, \u984C\u304B = false) {
30195
- const \u5E45 = textWidth(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593);
30196
- const \u4E0B\u9650 = \u984C\u304B ? \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, textWidth) : 0;
30858
+ function \u5E45\u306B\u53CE\u3081\u308B2(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, \u984C\u304B = false, textMetrics = "proportional") {
30859
+ const \u6E2C\u308B = (t, s, ls) => textWidth(t, s, ls, textMetrics);
30860
+ const \u5E45 = \u6E2C\u308B(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593);
30861
+ const \u4E0B\u9650 = \u984C\u304B ? \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, \u6E2C\u308B) : 0;
30197
30862
  const \u500D\u7387 = \u5E45 > 0 && \u7BB1\u5E45 > 0 ? Math.min(1, Math.max(\u7BB1\u5E45 / \u5E45, \u4E0B\u9650)) : 1;
30198
30863
  const size = \u5927\u304D\u3055 * \u500D\u7387;
30199
30864
  const spacing = \u5B57\u9593 * \u500D\u7387;
30200
- return { size, spacing, text: \u5E2F\u3067\u5207\u308B(\u6587\u5B57\u5217, size, \u7BB1\u5E45, (u, f) => textWidth(u, f, spacing)) };
30201
- }
30202
- function bottomLabel(node, cx, plan) {
30203
- const \u80A9 = \u5E45\u306B\u53CE\u3081\u308B2(node.eyebrow ?? "", plan.\u80A9\u66F8?.size ?? 0, LABEL_EYEBROW_SPACING, node.w);
30204
- const \u540D = \u5E45\u306B\u53CE\u3081\u308B2(node.title ?? "", plan.\u540D\u524D.size, 0, node.w, true);
30205
- const \u8AAC = \u5E45\u306B\u53CE\u3081\u308B2(node.subtitle ?? "", plan.\u8AAC\u660E?.size ?? 0, 0, node.w);
30865
+ return { size, spacing, text: \u5E2F\u3067\u5207\u308B(\u6587\u5B57\u5217, size, \u7BB1\u5E45, (u, f) => \u6E2C\u308B(u, f, spacing)) };
30866
+ }
30867
+ function bottomLabel(node, cx, plan, textMetrics = "proportional") {
30868
+ const \u80A9 = \u5E45\u306B\u53CE\u3081\u308B2(
30869
+ node.eyebrow ?? "",
30870
+ plan.\u80A9\u66F8?.size ?? 0,
30871
+ LABEL_EYEBROW_SPACING,
30872
+ node.w,
30873
+ false,
30874
+ textMetrics
30875
+ );
30876
+ const \u540D = \u5E45\u306B\u53CE\u3081\u308B2(node.title ?? "", plan.\u540D\u524D.size, 0, node.w, true, textMetrics);
30877
+ const \u8AAC = \u5E45\u306B\u53CE\u3081\u308B2(
30878
+ node.subtitle ?? "",
30879
+ plan.\u8AAC\u660E?.size ?? 0,
30880
+ 0,
30881
+ node.w,
30882
+ false,
30883
+ textMetrics
30884
+ );
30206
30885
  return /* @__PURE__ */ jsxs(Fragment, { children: [
30207
30886
  node.eyebrow && plan.\u80A9\u66F8 && /* @__PURE__ */ jsx("text", { x: cx, y: plan.\u80A9\u66F8.y, fontSize: \u80A9.size, fontWeight: 700, letterSpacing: \u80A9.spacing, textAnchor: "middle", fill: "var(--cdl-tone-accent, #2d6a8f)", children: \u80A9.text }),
30208
30887
  /* @__PURE__ */ jsx("text", { "data-cdl-role": "node-label", x: cx, y: plan.\u540D\u524D.y, fontSize: \u540D.size, fontWeight: 700, textAnchor: "middle", fill: "var(--cdl-text, #1a1f2a)", children: \u540D.text }),
@@ -30216,7 +30895,7 @@ var RACK_SLOT_N = 4;
30216
30895
  var RACK_BOTTOM = 8;
30217
30896
  var RACK_H = RACK_SLOT_TOP + RACK_SLOT_N * RACK_SLOT_H + (RACK_SLOT_N - 1) * RACK_SLOT_GAP + RACK_BOTTOM;
30218
30897
  var RACK_W_MIN = 120;
30219
- function ShapeServerRackNode({ node, active }) {
30898
+ function ShapeServerRackNode({ node, active, textMetrics = "proportional" }) {
30220
30899
  const r = shapeRegion(node);
30221
30900
  const frame = commonFrame3(active);
30222
30901
  const \u7DDA = frame.strokeWidth / 2;
@@ -30298,7 +30977,7 @@ function ShapeServerRackNode({ node, active }) {
30298
30977
  ] }, i);
30299
30978
  })
30300
30979
  ] })),
30301
- bottomLabel(node, r.cx, r.label)
30980
+ bottomLabel(node, r.cx, r.label, textMetrics)
30302
30981
  ] });
30303
30982
  }
30304
30983
  var HUB_R = 30;
@@ -30306,7 +30985,7 @@ var ARM_LEN = 68;
30306
30985
  var END_R = 7;
30307
30986
  var WIFI_ARC_R = [10, 16, 22];
30308
30987
  var WIFI_BASE_Y = 5;
30309
- function ShapeNetworkNodeNode({ node, active }) {
30988
+ function ShapeNetworkNodeNode({ node, active, textMetrics = "proportional" }) {
30310
30989
  const r = shapeRegion(node);
30311
30990
  const cx = r.cx;
30312
30991
  const cy = r.cy;
@@ -30382,12 +31061,12 @@ function ShapeNetworkNodeNode({ node, active }) {
30382
31061
  )),
30383
31062
  /* @__PURE__ */ jsx("circle", { cx, cy: cy + WIFI_BASE_Y + 3, r: 2.5, fill: "var(--cdl-tone-accent, #2d6a8f)", stroke: "none" })
30384
31063
  ] })),
30385
- bottomLabel(node, r.cx, r.label)
31064
+ bottomLabel(node, r.cx, r.label, textMetrics)
30386
31065
  ] });
30387
31066
  }
30388
31067
  var PHONE_H = 240;
30389
31068
  var PHONE_W = 110;
30390
- function ShapeMobileDeviceNode({ node, active }) {
31069
+ function ShapeMobileDeviceNode({ node, active, textMetrics = "proportional" }) {
30391
31070
  const r = shapeRegion(node);
30392
31071
  const frame = commonFrame3(active);
30393
31072
  const \u7DDA = frame.strokeWidth / 2;
@@ -30454,7 +31133,7 @@ function ShapeMobileDeviceNode({ node, active }) {
30454
31133
  }
30455
31134
  )
30456
31135
  ] })),
30457
- bottomLabel(node, r.cx, r.label)
31136
+ bottomLabel(node, r.cx, r.label, textMetrics)
30458
31137
  ] });
30459
31138
  }
30460
31139
  function ShapeIotSensorNode({ node, active }) {
@@ -30725,7 +31404,7 @@ var SAT_DISH_R = 12;
30725
31404
  var SAT_DISH_STEM = 12;
30726
31405
  var SAT_MAST_LEN = 22;
30727
31406
  var SAT_MAST_TIP_R = 4;
30728
- function ShapeSatelliteNode({ node, active }) {
31407
+ function ShapeSatelliteNode({ node, active, textMetrics = "proportional" }) {
30729
31408
  const r = shapeRegion(node);
30730
31409
  const cx = r.cx;
30731
31410
  const cy = r.cy;
@@ -30914,7 +31593,7 @@ function ShapeSatelliteNode({ node, active }) {
30914
31593
  ),
30915
31594
  /* @__PURE__ */ jsx("circle", { cx, cy: cy - bodyH / 2 - SAT_MAST_LEN, r: 2, fill: "#ff5f56", stroke: "none", children: /* @__PURE__ */ jsx("animate", { attributeName: "opacity", values: "0.4;1;0.4", dur: "1.4s", repeatCount: "indefinite" }) })
30916
31595
  ] })),
30917
- bottomLabel(node, r.cx, r.label)
31596
+ bottomLabel(node, r.cx, r.label, textMetrics)
30918
31597
  ] });
30919
31598
  }
30920
31599
  var FRAME_SW_ACTIVE = 3;
@@ -31000,9 +31679,9 @@ function blockchainNodeExtent(strokeWidth) {
31000
31679
  const \u6A2A = (NODE_PEER_DIST + NODE_PEER_R) * Math.cos(Math.PI / 6) + \u7DDA;
31001
31680
  return { \u4E0A: \u7E26, \u4E0B: \u7E26, \u5DE6: \u6A2A, \u53F3: \u6A2A };
31002
31681
  }
31003
- function bottomLabel2(node, cx, plan) {
31682
+ function bottomLabel2(node, cx, plan, textMetrics = "proportional") {
31004
31683
  const \u53CE\u3081\u308B = (t, \u5927\u304D\u3055, \u5B57\u9593, \u984C\u304B = false) => {
31005
- const \u6E2C\u308B = (u, f, ls) => \u5B57\u306E\u5E45(u, f) + ls * [...u].length;
31684
+ const \u6E2C\u308B = (u, f, ls) => \u5B57\u306E\u5E45(u, f, textMetrics) + ls * [...u].length;
31006
31685
  const \u7D20\u306E\u5E45 = \u6E2C\u308B(t, \u5927\u304D\u3055, \u5B57\u9593);
31007
31686
  const \u53CE\u307E\u308B = \u7D20\u306E\u5E45 > node.w && node.w > 0 ? node.w / \u7D20\u306E\u5E45 : 1;
31008
31687
  const \u4E0B\u9650 = \u984C\u304B ? \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(t, \u5927\u304D\u3055, \u5B57\u9593, node.w, \u6E2C\u308B) : 0;
@@ -31035,7 +31714,12 @@ function EthereumDiamond({ cx, cy, h, colors }) {
31035
31714
  /* @__PURE__ */ jsx("path", { d: `M ${cx} ${midY} L ${cx + w} ${cy + h * 0.05} L ${cx} ${lowerBotY} Z`, fill: c.dark, stroke: c.stroke, strokeWidth: 0.6, strokeLinejoin: "round" })
31036
31715
  ] });
31037
31716
  }
31038
- function ShapeSmartContractNode({ node, active, lang }) {
31717
+ function ShapeSmartContractNode({
31718
+ node,
31719
+ active,
31720
+ lang,
31721
+ textMetrics = "proportional"
31722
+ }) {
31039
31723
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
31040
31724
  const frame = commonFrame4(active);
31041
31725
  const r = shapeRegion(node);
@@ -31076,7 +31760,7 @@ function ShapeSmartContractNode({ node, active, lang }) {
31076
31760
  }
31077
31761
  ];
31078
31762
  const art = (\u500D\u7387) => {
31079
- const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089);
31763
+ const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089, textMetrics);
31080
31764
  return /* @__PURE__ */ jsxs("g", { children: [
31081
31765
  /* @__PURE__ */ jsx("path", { "data-cdl-role": "node-body", d: path, ...frame, strokeLinejoin: "round" }),
31082
31766
  /* @__PURE__ */ jsx("path", { d: foldPath, fill: "none", stroke: frame.stroke, strokeWidth: frame.strokeWidth, strokeLinejoin: "round" }),
@@ -31098,10 +31782,10 @@ function ShapeSmartContractNode({ node, active, lang }) {
31098
31782
  };
31099
31783
  return /* @__PURE__ */ jsxs("g", { children: [
31100
31784
  fitArt(r, smartContractExtent(frame.strokeWidth), art),
31101
- bottomLabel2(node, r.cx, r.label)
31785
+ bottomLabel2(node, r.cx, r.label, textMetrics)
31102
31786
  ] });
31103
31787
  }
31104
- var \u5B57\u306E\u5E45 = (text, size) => \u7D75\u306E\u4E2D\u306E\u5B57\u306E\u5E45(text, size);
31788
+ var \u5B57\u306E\u5E45 = (text, size, textMetrics = "proportional") => \u7D75\u306E\u4E2D\u306E\u5B57\u306E\u5E45(text, size, 0, textMetrics);
31105
31789
  var BLOCK_DEFAULT_FIELDS = [
31106
31790
  { key: "hash", label: "blockchainBlock.hash", value: { text: "0xaf31..." } },
31107
31791
  { key: "prev", label: "blockchainBlock.prev", value: { text: "0x7b3f..." } },
@@ -31109,10 +31793,16 @@ var BLOCK_DEFAULT_FIELDS = [
31109
31793
  { key: "nonce", label: "blockchainBlock.nonce", value: { text: "82,914" } },
31110
31794
  { key: "tx", label: "blockchainBlock.tx", value: { \u8F9E\u66F8: "blockchainBlock.txCount" } }
31111
31795
  ];
31112
- function ShapeBlockchainBlockNode({ node, active, lang }) {
31796
+ function ShapeBlockchainBlockNode({
31797
+ node,
31798
+ active,
31799
+ lang,
31800
+ textMetrics = "proportional"
31801
+ }) {
31113
31802
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
31114
31803
  const frame = commonFrame4(active);
31115
31804
  const r = shapeRegion(node);
31805
+ const \u6E2C\u308B\u5B57 = (text, size) => \u5B57\u306E\u5E45(text, size, textMetrics);
31116
31806
  const bw = BLOCK_W;
31117
31807
  const bh = BLOCK_H;
31118
31808
  const cx = r.cx;
@@ -31133,9 +31823,9 @@ function ShapeBlockchainBlockNode({ node, active, lang }) {
31133
31823
  const \u5E2F\u306E\u6B8B\u308A = bw - 14 - 30;
31134
31824
  const \u80A9\u66F8\u306E\u9699\u9593 = 8;
31135
31825
  const \u80A9\u66F8\u306E\u4E0A\u9650 = (\u5E2F\u306E\u6B8B\u308A - \u80A9\u66F8\u306E\u9699\u9593) / 2;
31136
- const \u80A9\u66F8\u306E\u500D\u7387 = \u80A9\u66F8 === "" ? 1 : \u5E45\u306E\u500D\u7387(\u80A9\u66F8, \u80A9\u66F8\u306E\u5B57, 0, \u80A9\u66F8\u306E\u4E0A\u9650);
31826
+ const \u80A9\u66F8\u306E\u500D\u7387 = \u80A9\u66F8 === "" ? 1 : \u5E45\u306E\u500D\u7387(\u80A9\u66F8, \u80A9\u66F8\u306E\u5B57, 0, \u80A9\u66F8\u306E\u4E0A\u9650, textMetrics);
31137
31827
  const \u80A9\u66F8\u306E\u6307\u5B9A = \u80A9\u66F8\u306E\u5B57 * \u80A9\u66F8\u306E\u500D\u7387;
31138
- const \u80A9\u66F8\u306E\u5E45 = \u80A9\u66F8 === "" ? 0 : \u5B57\u306E\u5E45(\u80A9\u66F8, \u80A9\u66F8\u306E\u6307\u5B9A);
31828
+ const \u80A9\u66F8\u306E\u5E45 = \u80A9\u66F8 === "" ? 0 : \u6E2C\u308B\u5B57(\u80A9\u66F8, \u80A9\u66F8\u306E\u6307\u5B9A);
31139
31829
  const \u898B\u51FA\u3057\u306E\u5E45 = \u5E2F\u306E\u6B8B\u308A - (\u80A9\u66F8 === "" ? 0 : \u80A9\u66F8\u306E\u5E45 + \u80A9\u66F8\u306E\u9699\u9593);
31140
31830
  const \u6253\u3061\u6D88\u3059\u5B57\u3089 = [
31141
31831
  { text: \u898B\u51FA\u3057, size: \u898B\u51FA\u3057\u306E\u5B57, \u5E2F: { \u5E45: \u898B\u51FA\u3057\u306E\u5E45, \u9AD8\u3055: \u898B\u51FA\u3057\u306E\u5E2F } },
@@ -31146,12 +31836,12 @@ function ShapeBlockchainBlockNode({ node, active, lang }) {
31146
31836
  {
31147
31837
  text: f.value,
31148
31838
  size: \u5024\u306E\u5B57,
31149
- \u5E2F: { \u5E45: bw - 28 - \u5B57\u306E\u5E45(f.label, \u540D\u306E\u5B57) - 8, \u9AD8\u3055: \u884C\u306E\u9593\u9694 }
31839
+ \u5E2F: { \u5E45: bw - 28 - \u6E2C\u308B\u5B57(f.label, \u540D\u306E\u5B57) - 8, \u9AD8\u3055: \u884C\u306E\u9593\u9694 }
31150
31840
  }
31151
31841
  ])
31152
31842
  ];
31153
31843
  const art = (\u500D\u7387) => {
31154
- const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089);
31844
+ const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089, textMetrics);
31155
31845
  const \u984C\u306E\u5927\u304D\u3055 = \u898B\u51FA\u3057\u306E\u5B57 * \u500D;
31156
31846
  const \u80A9\u66F8\u306E\u5927\u304D\u3055 = \u80A9\u66F8\u306E\u6307\u5B9A * \u500D;
31157
31847
  const \u540D\u306E\u5927\u304D\u3055 = \u540D\u306E\u5B57 * \u500D;
@@ -31160,7 +31850,7 @@ function ShapeBlockchainBlockNode({ node, active, lang }) {
31160
31850
  /* @__PURE__ */ jsx("rect", { x: x + 6, y: y + 6, width: bw, height: bh, rx: 8, fill: frame.stroke, opacity: 0.2, stroke: "none" }),
31161
31851
  /* @__PURE__ */ jsx("rect", { "data-cdl-role": "node-body", x, y, width: bw, height: bh, rx: 8, ...frame }),
31162
31852
  /* @__PURE__ */ jsx("path", { d: `M ${x} ${y + 32} L ${x} ${y + 8} Q ${x} ${y}, ${x + 8} ${y} L ${x + bw - 8} ${y} Q ${x + bw} ${y}, ${x + bw} ${y + 8} L ${x + bw} ${y + 32} Z`, fill: "var(--cdl-tone-accent, #2d6a8f)", fillOpacity: 0.9, stroke: "none" }),
31163
- /* @__PURE__ */ jsx("text", { "data-cdl-role": "blockchain-block-title", "data-cdl-counter-scaled": "1", x: x + 14, y: y + 22, fontSize: \u984C\u306E\u5927\u304D\u3055, fontWeight: 700, fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace", fill: "#ffffff", children: \u5E45\u3067\u5207\u308B(\u898B\u51FA\u3057, \u984C\u306E\u5927\u304D\u3055, \u898B\u51FA\u3057\u306E\u5E45, \u5B57\u306E\u5E45) }),
31853
+ /* @__PURE__ */ jsx("text", { "data-cdl-role": "blockchain-block-title", "data-cdl-counter-scaled": "1", x: x + 14, y: y + 22, fontSize: \u984C\u306E\u5927\u304D\u3055, fontWeight: 700, fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace", fill: "#ffffff", children: \u5E45\u3067\u5207\u308B(\u898B\u51FA\u3057, \u984C\u306E\u5927\u304D\u3055, \u898B\u51FA\u3057\u306E\u5E45, \u6E2C\u308B\u5B57) }),
31164
31854
  \u80A9\u66F8 !== "" && /* @__PURE__ */ jsx(
31165
31855
  "text",
31166
31856
  {
@@ -31180,7 +31870,12 @@ function ShapeBlockchainBlockNode({ node, active, lang }) {
31180
31870
  /* @__PURE__ */ jsx("circle", { cx: x + bw - 16, cy: y + 16, r: 5.5, fill: "#7cd88f", stroke: "#ffffff", strokeWidth: 1.5 }),
31181
31871
  fields.map((f, i) => /* @__PURE__ */ jsxs("g", { children: [
31182
31872
  /* @__PURE__ */ jsx("text", { "data-cdl-counter-scaled": "1", x: x + 14, y: y + 54 + i * \u884C\u306E\u9593\u9694, fontSize: \u540D\u306E\u5927\u304D\u3055, fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace", fill: "var(--cdl-text-dim, #5a6270)", children: f.label }),
31183
- /* @__PURE__ */ jsx("text", { "data-cdl-role": `blockchain-block-${f.key}`, "data-cdl-counter-scaled": "1", x: x + bw - 14, y: y + 54 + i * \u884C\u306E\u9593\u9694, fontSize: \u5024\u306E\u5927\u304D\u3055, fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace", fontWeight: 600, textAnchor: "end", fill: "var(--cdl-text, #1a1f2a)", children: \u5E45\u3067\u5207\u308B(f.value, \u5024\u306E\u5927\u304D\u3055, bw - 28 - \u5B57\u306E\u5E45(f.label, \u540D\u306E\u5927\u304D\u3055) - 8, \u5B57\u306E\u5E45) }),
31873
+ /* @__PURE__ */ jsx("text", { "data-cdl-role": `blockchain-block-${f.key}`, "data-cdl-counter-scaled": "1", x: x + bw - 14, y: y + 54 + i * \u884C\u306E\u9593\u9694, fontSize: \u5024\u306E\u5927\u304D\u3055, fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace", fontWeight: 600, textAnchor: "end", fill: "var(--cdl-text, #1a1f2a)", children: \u5E45\u3067\u5207\u308B(
31874
+ f.value,
31875
+ \u5024\u306E\u5927\u304D\u3055,
31876
+ bw - 28 - \u6E2C\u308B\u5B57(f.label, \u540D\u306E\u5927\u304D\u3055) - 8,
31877
+ \u6E2C\u308B\u5B57
31878
+ ) }),
31184
31879
  /* @__PURE__ */ jsx("line", { x1: x + 14, y1: y + 60 + i * \u884C\u306E\u9593\u9694, x2: x + bw - 14, y2: y + 60 + i * \u884C\u306E\u9593\u9694, stroke: "var(--cdl-divider, #d4d4d8)", strokeWidth: 0.5, opacity: 0.5 })
31185
31880
  ] }, i)),
31186
31881
  /* @__PURE__ */ jsxs("g", { transform: `translate(${cx - 32}, ${y + bh - 26})`, children: [
@@ -31192,7 +31887,11 @@ function ShapeBlockchainBlockNode({ node, active, lang }) {
31192
31887
  };
31193
31888
  return /* @__PURE__ */ jsx("g", { children: fitArt(r, blockchainBlockExtent(frame.strokeWidth), art) });
31194
31889
  }
31195
- function ShapeBlockchainNode({ node, active }) {
31890
+ function ShapeBlockchainNode({
31891
+ node,
31892
+ active,
31893
+ textMetrics = "proportional"
31894
+ }) {
31196
31895
  const frame = commonFrame4(active);
31197
31896
  const r = shapeRegion(node);
31198
31897
  const cx = r.cx;
@@ -31208,7 +31907,7 @@ function ShapeBlockchainNode({ node, active }) {
31208
31907
  { text: "0x\u2026", size: CHAIN_HASH_SIZE, \u5E2F: { \u5E45: CHAIN_TEXT_W, \u9AD8\u3055: CHAIN_ROW_GAP } }
31209
31908
  ];
31210
31909
  const art = (\u500D\u7387) => {
31211
- const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089);
31910
+ const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089, textMetrics);
31212
31911
  return /* @__PURE__ */ jsx("g", { children: Array.from({ length: blockCount }, (_, i) => i).map((i) => {
31213
31912
  const bx = startX + i * (blockW + linkW);
31214
31913
  const isCurrent = i === blockCount - 1;
@@ -31244,10 +31943,14 @@ function ShapeBlockchainNode({ node, active }) {
31244
31943
  };
31245
31944
  return /* @__PURE__ */ jsxs("g", { children: [
31246
31945
  fitArt(r, chainExtent(), art),
31247
- bottomLabel2(node, r.cx, r.label)
31946
+ bottomLabel2(node, r.cx, r.label, textMetrics)
31248
31947
  ] });
31249
31948
  }
31250
- function ShapeBitcoinChainNode({ node, active }) {
31949
+ function ShapeBitcoinChainNode({
31950
+ node,
31951
+ active,
31952
+ textMetrics = "proportional"
31953
+ }) {
31251
31954
  const frame = commonFrame4(active);
31252
31955
  const r = shapeRegion(node);
31253
31956
  const cx = r.cx;
@@ -31263,7 +31966,7 @@ function ShapeBitcoinChainNode({ node, active }) {
31263
31966
  { text: "#820", size: BTC_NO_SIZE, \u5E2F: { \u5E45: CHAIN_TEXT_W, \u9AD8\u3055: 20 } }
31264
31967
  ];
31265
31968
  const art = (\u500D\u7387) => {
31266
- const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089);
31969
+ const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089, textMetrics);
31267
31970
  return /* @__PURE__ */ jsx("g", { children: Array.from({ length: blockCount }, (_, i) => i).map((i) => {
31268
31971
  const bx = startX + i * (blockW + linkW);
31269
31972
  const isCurrent = i === blockCount - 1;
@@ -31294,10 +31997,14 @@ function ShapeBitcoinChainNode({ node, active }) {
31294
31997
  };
31295
31998
  return /* @__PURE__ */ jsxs("g", { children: [
31296
31999
  fitArt(r, chainExtent(), art),
31297
- bottomLabel2(node, r.cx, r.label)
32000
+ bottomLabel2(node, r.cx, r.label, textMetrics)
31298
32001
  ] });
31299
32002
  }
31300
- function ShapeEthereumChainNode({ node, active }) {
32003
+ function ShapeEthereumChainNode({
32004
+ node,
32005
+ active,
32006
+ textMetrics = "proportional"
32007
+ }) {
31301
32008
  const frame = commonFrame4(active);
31302
32009
  const r = shapeRegion(node);
31303
32010
  const cx = r.cx;
@@ -31313,7 +32020,7 @@ function ShapeEthereumChainNode({ node, active }) {
31313
32020
  { text: "#214", size: ETH_NO_SIZE, \u5E2F: { \u5E45: CHAIN_TEXT_W, \u9AD8\u3055: 20 } }
31314
32021
  ];
31315
32022
  const art = (\u500D\u7387) => {
31316
- const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089);
32023
+ const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089, textMetrics);
31317
32024
  return /* @__PURE__ */ jsx("g", { children: Array.from({ length: blockCount }, (_, i) => i).map((i) => {
31318
32025
  const bx = startX + i * (blockW + linkW);
31319
32026
  const isCurrent = i === blockCount - 1;
@@ -31345,10 +32052,14 @@ function ShapeEthereumChainNode({ node, active }) {
31345
32052
  };
31346
32053
  return /* @__PURE__ */ jsxs("g", { children: [
31347
32054
  fitArt(r, chainExtent(), art),
31348
- bottomLabel2(node, r.cx, r.label)
32055
+ bottomLabel2(node, r.cx, r.label, textMetrics)
31349
32056
  ] });
31350
32057
  }
31351
- function ShapeBlockchainNodeNode({ node, active }) {
32058
+ function ShapeBlockchainNodeNode({
32059
+ node,
32060
+ active,
32061
+ textMetrics = "proportional"
32062
+ }) {
31352
32063
  const frame = commonFrame4(active);
31353
32064
  const r = shapeRegion(node);
31354
32065
  const cx = r.cx;
@@ -31402,10 +32113,15 @@ function ShapeBlockchainNodeNode({ node, active }) {
31402
32113
  ] });
31403
32114
  return /* @__PURE__ */ jsxs("g", { children: [
31404
32115
  fitArt(r, blockchainNodeExtent(frame.strokeWidth), art),
31405
- bottomLabel2(node, r.cx, r.label)
32116
+ bottomLabel2(node, r.cx, r.label, textMetrics)
31406
32117
  ] });
31407
32118
  }
31408
- function ShapeRpcNodeNode({ node, active, lang }) {
32119
+ function ShapeRpcNodeNode({
32120
+ node,
32121
+ active,
32122
+ lang,
32123
+ textMetrics = "proportional"
32124
+ }) {
31409
32125
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
31410
32126
  const frame = commonFrame4(active);
31411
32127
  const r = shapeRegion(node);
@@ -31424,10 +32140,10 @@ function ShapeRpcNodeNode({ node, active, lang }) {
31424
32140
  /* @__PURE__ */ jsx("text", { x: cx, y: cy + 26, fontSize: 11, textAnchor: "middle", fill: "#7a8290", fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace", children: "JSON-RPC 2.0" }),
31425
32141
  /* @__PURE__ */ jsx("rect", { x: x + 16, y: y + bh - 24, width: bw - 32, height: 8, rx: 4, fill: "#0f1419", stroke: "none" }),
31426
32142
  /* @__PURE__ */ jsx("rect", { x: x + 16, y: y + bh - 24, width: (bw - 32) * 0.92, height: 8, rx: 4, fill: "#27c93f", stroke: "none", children: /* @__PURE__ */ jsx("animate", { attributeName: "width", values: `${(bw - 32) * 0.86};${(bw - 32) * 0.96};${(bw - 32) * 0.86}`, dur: "3s", repeatCount: "indefinite" }) }),
31427
- bottomLabel2(node, r.cx, r.label)
32143
+ bottomLabel2(node, r.cx, r.label, textMetrics)
31428
32144
  ] });
31429
32145
  }
31430
- function ShapeWalletNode({ node, active }) {
32146
+ function ShapeWalletNode({ node, active, textMetrics = "proportional" }) {
31431
32147
  const frame = commonFrame4(active);
31432
32148
  const r = shapeRegion(node);
31433
32149
  const cx = r.cx;
@@ -31501,10 +32217,10 @@ function ShapeWalletNode({ node, active }) {
31501
32217
  /* @__PURE__ */ jsx("text", { x: cx, y: foldY + 3, fontSize: 9, fontWeight: 700, fill: "#5a3a10", textAnchor: "middle", opacity: 0.8, children: "\u039E" }),
31502
32218
  /* @__PURE__ */ jsx("path", { d: `M ${x + 2} ${y + 6} L ${x + w - 2} ${y + 6}`, fill: "none", stroke: "#ffffff", strokeWidth: 1, opacity: 0.4 })
31503
32219
  ] }),
31504
- bottomLabel2(node, r.cx, r.label)
32220
+ bottomLabel2(node, r.cx, r.label, textMetrics)
31505
32221
  ] });
31506
32222
  }
31507
- function ShapeNftNode({ node, active }) {
32223
+ function ShapeNftNode({ node, active, textMetrics = "proportional" }) {
31508
32224
  const frame = commonFrame4(active);
31509
32225
  const r = shapeRegion(node);
31510
32226
  const cx = r.cx;
@@ -31520,7 +32236,7 @@ function ShapeNftNode({ node, active }) {
31520
32236
  { text: "#1024", size: NFT_ID_SIZE, \u5E2F: { \u5E45: cardW - 16 - 34, \u9AD8\u3055: cardH - artH } }
31521
32237
  ];
31522
32238
  const art = (\u500D\u7387) => {
31523
- const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089);
32239
+ const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089, textMetrics);
31524
32240
  return /* @__PURE__ */ jsxs("g", { children: [
31525
32241
  /* @__PURE__ */ jsx("rect", { x: x + 4, y: y + 4, width: cardW, height: cardH, rx: 14, fill: frame.stroke, opacity: 0.2, stroke: "none" }),
31526
32242
  /* @__PURE__ */ jsx("rect", { "data-cdl-role": "node-body", x, y, width: cardW, height: cardH, rx: 14, ...frame }),
@@ -31558,10 +32274,10 @@ function ShapeNftNode({ node, active }) {
31558
32274
  };
31559
32275
  return /* @__PURE__ */ jsxs("g", { children: [
31560
32276
  fitArt(r, nftExtent(frame.strokeWidth), art),
31561
- bottomLabel2(node, r.cx, r.label)
32277
+ bottomLabel2(node, r.cx, r.label, textMetrics)
31562
32278
  ] });
31563
32279
  }
31564
- function ShapeTokenNode({ node, active }) {
32280
+ function ShapeTokenNode({ node, active, textMetrics = "proportional" }) {
31565
32281
  const frame = commonFrame4(active);
31566
32282
  const r = shapeRegion(node);
31567
32283
  const cx = r.cx;
@@ -31598,7 +32314,7 @@ function ShapeTokenNode({ node, active }) {
31598
32314
  }
31599
32315
  }
31600
32316
  ),
31601
- bottomLabel2(node, r.cx, r.label)
32317
+ bottomLabel2(node, r.cx, r.label, textMetrics)
31602
32318
  ] });
31603
32319
  }
31604
32320
  var commonFrame5 = (active) => ({
@@ -31617,7 +32333,8 @@ function \u5B57\u306E\u6BD4(c) {
31617
32333
  if (\u5E83\u5B57.has(c)) return \u5E83\u5B57\u6BD4;
31618
32334
  return (c.codePointAt(0) ?? 0) < 128 ? \u4E26\u5B57\u6BD4 : \u5E83\u5B57\u6BD4;
31619
32335
  }
31620
- function \u5B57\u5E45(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593) {
32336
+ function \u5B57\u5E45(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, textMetrics = "proportional") {
32337
+ if (textMetrics === "monospace") return textWidth(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, textMetrics);
31621
32338
  let \u5E45 = 0;
31622
32339
  let \u5B57\u6570 = 0;
31623
32340
  for (const c of \u6587\u5B57\u5217) {
@@ -31626,18 +32343,33 @@ function \u5B57\u5E45(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593) {
31626
32343
  }
31627
32344
  return \u5E45 + \u5B57\u9593 * \u5B57\u6570;
31628
32345
  }
31629
- function \u5E45\u306B\u53CE\u3081\u308B3(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, \u984C\u304B = false) {
31630
- const \u5E45 = \u5B57\u5E45(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593);
31631
- const \u4E0B\u9650 = \u984C\u304B ? \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, \u5B57\u5E45) : 0;
32346
+ function \u5E45\u306B\u53CE\u3081\u308B3(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, \u984C\u304B = false, textMetrics = "proportional") {
32347
+ const \u6E2C\u308B = (t, s, ls) => \u5B57\u5E45(t, s, ls, textMetrics);
32348
+ const \u5E45 = \u6E2C\u308B(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593);
32349
+ const \u4E0B\u9650 = \u984C\u304B ? \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, \u6E2C\u308B) : 0;
31632
32350
  const \u500D\u7387 = \u5E45 > 0 && \u7BB1\u5E45 > 0 ? Math.min(1, Math.max(\u7BB1\u5E45 / \u5E45, \u4E0B\u9650)) : 1;
31633
32351
  const size = \u5927\u304D\u3055 * \u500D\u7387;
31634
32352
  const spacing = \u5B57\u9593 * \u500D\u7387;
31635
- return { size, spacing, text: \u5E2F\u3067\u5207\u308B(\u6587\u5B57\u5217, size, \u7BB1\u5E45, (u, f) => \u5B57\u5E45(u, f, spacing)) };
31636
- }
31637
- function bottomLabel3(node, cx, plan) {
31638
- const \u80A9 = \u5E45\u306B\u53CE\u3081\u308B3(node.eyebrow ?? "", plan.\u80A9\u66F8?.size ?? 0, LABEL_EYEBROW_SPACING2, node.w);
31639
- const \u540D = \u5E45\u306B\u53CE\u3081\u308B3(node.title ?? "", plan.\u540D\u524D.size, 0, node.w, true);
31640
- const \u8AAC = \u5E45\u306B\u53CE\u3081\u308B3(node.subtitle ?? "", plan.\u8AAC\u660E?.size ?? 0, 0, node.w);
32353
+ return { size, spacing, text: \u5E2F\u3067\u5207\u308B(\u6587\u5B57\u5217, size, \u7BB1\u5E45, (u, f) => \u6E2C\u308B(u, f, spacing)) };
32354
+ }
32355
+ function bottomLabel3(node, cx, plan, textMetrics = "proportional") {
32356
+ const \u80A9 = \u5E45\u306B\u53CE\u3081\u308B3(
32357
+ node.eyebrow ?? "",
32358
+ plan.\u80A9\u66F8?.size ?? 0,
32359
+ LABEL_EYEBROW_SPACING2,
32360
+ node.w,
32361
+ false,
32362
+ textMetrics
32363
+ );
32364
+ const \u540D = \u5E45\u306B\u53CE\u3081\u308B3(node.title ?? "", plan.\u540D\u524D.size, 0, node.w, true, textMetrics);
32365
+ const \u8AAC = \u5E45\u306B\u53CE\u3081\u308B3(
32366
+ node.subtitle ?? "",
32367
+ plan.\u8AAC\u660E?.size ?? 0,
32368
+ 0,
32369
+ node.w,
32370
+ false,
32371
+ textMetrics
32372
+ );
31641
32373
  return /* @__PURE__ */ jsxs(Fragment, { children: [
31642
32374
  node.eyebrow && plan.\u80A9\u66F8 && /* @__PURE__ */ jsx("text", { x: cx, y: plan.\u80A9\u66F8.y, fontSize: \u80A9.size, fontWeight: 700, letterSpacing: \u80A9.spacing, textAnchor: "middle", fill: "var(--cdl-tone-accent, #2d6a8f)", children: \u80A9.text }),
31643
32375
  /* @__PURE__ */ jsx("text", { "data-cdl-role": "node-label", x: cx, y: plan.\u540D\u524D.y, fontSize: \u540D.size, fontWeight: 700, textAnchor: "middle", fill: "var(--cdl-text, #1a1f2a)", children: \u540D.text }),
@@ -31656,7 +32388,7 @@ var BANK_STEP_SW = 1;
31656
32388
  var BANK_COLUMN_MIN = 24;
31657
32389
  var BANK_BLD_W_MIN = 120;
31658
32390
  var BANK_BLD_W_MAX = 280;
31659
- function ShapeBankNode({ node, active }) {
32391
+ function ShapeBankNode({ node, active, textMetrics = "proportional" }) {
31660
32392
  const frame = commonFrame5(active);
31661
32393
  const r = shapeRegion(node);
31662
32394
  const \u7DDA = frame.strokeWidth / 2;
@@ -31703,7 +32435,7 @@ function ShapeBankNode({ node, active }) {
31703
32435
  ] });
31704
32436
  return /* @__PURE__ */ jsxs("g", { children: [
31705
32437
  fitArt(r, \u5E83\u304C\u308A, \u7D75),
31706
- bottomLabel3(node, r.cx, r.label)
32438
+ bottomLabel3(node, r.cx, r.label, textMetrics)
31707
32439
  ] });
31708
32440
  }
31709
32441
  var TRUST_CROWN_RISE = 4;
@@ -31715,7 +32447,12 @@ var TRUST_BASE_H = 14;
31715
32447
  var TRUST_BODY_OUT = 8;
31716
32448
  var TRUST_BLD_W_MIN = 140;
31717
32449
  var TRUST_BLD_W_MAX = 280;
31718
- function ShapeTrustBankNode({ node, active, lang }) {
32450
+ function ShapeTrustBankNode({
32451
+ node,
32452
+ active,
32453
+ lang,
32454
+ textMetrics = "proportional"
32455
+ }) {
31719
32456
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
31720
32457
  const frame = commonFrame5(active);
31721
32458
  const r = shapeRegion(node);
@@ -31769,10 +32506,15 @@ function ShapeTrustBankNode({ node, active, lang }) {
31769
32506
  ] });
31770
32507
  return /* @__PURE__ */ jsxs("g", { children: [
31771
32508
  fitArt(r, \u5E83\u304C\u308A, \u7D75),
31772
- bottomLabel3(node, r.cx, r.label)
32509
+ bottomLabel3(node, r.cx, r.label, textMetrics)
31773
32510
  ] });
31774
32511
  }
31775
- function ShapePaymentProviderNode({ node, active, lang }) {
32512
+ function ShapePaymentProviderNode({
32513
+ node,
32514
+ active,
32515
+ lang,
32516
+ textMetrics = "proportional"
32517
+ }) {
31776
32518
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
31777
32519
  const frame = commonFrame5(active);
31778
32520
  const r = shapeRegion(node);
@@ -31797,10 +32539,14 @@ function ShapePaymentProviderNode({ node, active, lang }) {
31797
32539
  /* @__PURE__ */ jsx("text", { x: cx, y: cy + 9, fontSize: 13, fontWeight: 700, textAnchor: "middle", fill: accentDarker, fontFamily: "Georgia, serif", children: "$" })
31798
32540
  ] }),
31799
32541
  /* @__PURE__ */ jsx("text", { x: cx, y: y + boxH - 16, fontSize: 11, fontWeight: 700, letterSpacing: 2, textAnchor: "middle", fill: "#a4b5f2", children: \u5B57\u5F15("paymentProvider.status") }),
31800
- bottomLabel3(node, r.cx, r.label)
32542
+ bottomLabel3(node, r.cx, r.label, textMetrics)
31801
32543
  ] });
31802
32544
  }
31803
- function ShapeCreditCardNode({ node, active }) {
32545
+ function ShapeCreditCardNode({
32546
+ node,
32547
+ active,
32548
+ textMetrics = "proportional"
32549
+ }) {
31804
32550
  const frame = commonFrame5(active);
31805
32551
  const r = shapeRegion(node);
31806
32552
  const cardW = Math.min(r.availW - 30, 260);
@@ -31822,7 +32568,7 @@ function ShapeCreditCardNode({ node, active }) {
31822
32568
  [0, 1, 2, 3].map((block) => /* @__PURE__ */ jsx("g", { children: [0, 1, 2, 3].map((dot) => /* @__PURE__ */ jsx("circle", { cx: x + 32 + block * (cardW - 64) / 4 + dot * 8, cy: y + cardH - 40, r: 2.8, fill: "#ffffff", stroke: "none" }, dot)) }, block)),
31823
32569
  /* @__PURE__ */ jsx("circle", { cx: x + cardW - 48, cy: y + cardH - 24, r: 15, fill: "#c9302c", opacity: 0.9, stroke: "none" }),
31824
32570
  /* @__PURE__ */ jsx("circle", { cx: x + cardW - 30, cy: y + cardH - 24, r: 15, fill: "#e5c07b", opacity: 0.9, stroke: "none" }),
31825
- bottomLabel3(node, r.cx, r.label)
32571
+ bottomLabel3(node, r.cx, r.label, textMetrics)
31826
32572
  ] });
31827
32573
  }
31828
32574
  var BROKERAGE_TICK_H = 18;
@@ -31847,7 +32593,12 @@ var BROKERAGE_SHADE_OUT = 2;
31847
32593
  var BROKERAGE_W_MIN = BROKERAGE_COLS * BROKERAGE_CELL_W + (BROKERAGE_COLS - 1) * BROKERAGE_GAP_X + 6;
31848
32594
  var BROKERAGE_W_MAX = 140;
31849
32595
  var BROKERAGE_H_MIN = BROKERAGE_TICK_H + BROKERAGE_LOGO_H + BROKERAGE_BASE_H;
31850
- function ShapeBrokerageNode({ node, active, lang }) {
32596
+ function ShapeBrokerageNode({
32597
+ node,
32598
+ active,
32599
+ lang,
32600
+ textMetrics = "proportional"
32601
+ }) {
31851
32602
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
31852
32603
  const frame = commonFrame5(active);
31853
32604
  const r = shapeRegion(node);
@@ -31886,7 +32637,7 @@ function ShapeBrokerageNode({ node, active, lang }) {
31886
32637
  }
31887
32638
  ];
31888
32639
  const \u7D75 = (\u500D\u7387) => {
31889
- const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089);
32640
+ const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089, textMetrics);
31890
32641
  return /* @__PURE__ */ jsxs("g", { children: [
31891
32642
  /* @__PURE__ */ jsx("ellipse", { cx, cy: y + h + BROKERAGE_SHADOW_DY, rx: w * BROKERAGE_SHADOW_RX_RATIO, ry: BROKERAGE_SHADOW_RY, fill: frame.stroke, opacity: 0.2, stroke: "none" }),
31892
32643
  /* @__PURE__ */ jsx("rect", { "data-cdl-role": "node-body", x, y, width: w, height: h, fill: "#255a7a", stroke: accentDarker, strokeWidth: frame.strokeWidth }),
@@ -31914,12 +32665,17 @@ function ShapeBrokerageNode({ node, active, lang }) {
31914
32665
  };
31915
32666
  return /* @__PURE__ */ jsxs("g", { children: [
31916
32667
  fitArt(r, \u5E83\u304C\u308A, \u7D75),
31917
- bottomLabel3(node, r.cx, r.label)
32668
+ bottomLabel3(node, r.cx, r.label, textMetrics)
31918
32669
  ] });
31919
32670
  }
31920
32671
  var EXCHANGE_SUB_SIZE = 11;
31921
32672
  var EXCHANGE_HEX_R = 52;
31922
- function ShapeExchangeNode({ node, active, lang }) {
32673
+ function ShapeExchangeNode({
32674
+ node,
32675
+ active,
32676
+ lang,
32677
+ textMetrics = "proportional"
32678
+ }) {
31923
32679
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
31924
32680
  const frame = commonFrame5(active);
31925
32681
  const r = shapeRegion(node);
@@ -31964,7 +32720,7 @@ function ShapeExchangeNode({ node, active, lang }) {
31964
32720
  }
31965
32721
  ];
31966
32722
  const \u7D75 = (\u500D\u7387) => {
31967
- const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089);
32723
+ const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089, textMetrics);
31968
32724
  return /* @__PURE__ */ jsxs("g", { children: [
31969
32725
  nodes.map((n, i) => /* @__PURE__ */ jsx("line", { x1: cx, y1: cy, x2: n.cx, y2: n.cy, stroke: accentDarker, strokeWidth: 1.5, strokeDasharray: "3 2" }, `l${i}`)),
31970
32726
  nodes.map((n, i) => {
@@ -31983,7 +32739,7 @@ function ShapeExchangeNode({ node, active, lang }) {
31983
32739
  };
31984
32740
  return /* @__PURE__ */ jsxs("g", { children: [
31985
32741
  fitArt(r, \u5E83\u304C\u308A, \u7D75),
31986
- bottomLabel3(node, r.cx, r.label)
32742
+ bottomLabel3(node, r.cx, r.label, textMetrics)
31987
32743
  ] });
31988
32744
  }
31989
32745
  var ATM_SIGN_H = 26;
@@ -32000,7 +32756,12 @@ var ATM_PANEL_H = 146;
32000
32756
  var ATM_W_MIN = 100;
32001
32757
  var ATM_W_MAX = ATM_PANEL_W;
32002
32758
  var ATM_H_MIN = ATM_SIGN_H + ATM_SIGN_GAP + 30 + ATM_FLOOR_RESERVE;
32003
- function ShapeAtmNode({ node, active, lang }) {
32759
+ function ShapeAtmNode({
32760
+ node,
32761
+ active,
32762
+ lang,
32763
+ textMetrics = "proportional"
32764
+ }) {
32004
32765
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
32005
32766
  const frame = commonFrame5(active);
32006
32767
  const r = shapeRegion(node);
@@ -32084,7 +32845,7 @@ function ShapeAtmNode({ node, active, lang }) {
32084
32845
  ] });
32085
32846
  return /* @__PURE__ */ jsxs("g", { children: [
32086
32847
  fitArt(r, \u5E83\u304C\u308A, \u7D75),
32087
- bottomLabel3(node, r.cx, r.label)
32848
+ bottomLabel3(node, r.cx, r.label, textMetrics)
32088
32849
  ] });
32089
32850
  }
32090
32851
  var commonFrame6 = (active) => ({
@@ -32103,7 +32864,8 @@ function \u5B57\u306E\u6BD42(c) {
32103
32864
  if (\u5E83\u5B572.has(c)) return \u5E83\u5B57\u6BD42;
32104
32865
  return (c.codePointAt(0) ?? 0) < 128 ? \u4E26\u5B57\u6BD42 : \u5E83\u5B57\u6BD42;
32105
32866
  }
32106
- function \u5B57\u5E452(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593) {
32867
+ function \u5B57\u5E452(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, textMetrics = "proportional") {
32868
+ if (textMetrics === "monospace") return textWidth(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, textMetrics);
32107
32869
  let \u5E45 = 0;
32108
32870
  let \u5B57\u6570 = 0;
32109
32871
  for (const c of \u6587\u5B57\u5217) {
@@ -32112,18 +32874,33 @@ function \u5B57\u5E452(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593) {
32112
32874
  }
32113
32875
  return \u5E45 + \u5B57\u9593 * \u5B57\u6570;
32114
32876
  }
32115
- function \u5E45\u306B\u53CE\u3081\u308B4(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, \u984C\u304B = false) {
32116
- const \u5E45 = \u5B57\u5E452(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593);
32117
- const \u4E0B\u9650 = \u984C\u304B ? \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, \u5B57\u5E452) : 0;
32877
+ function \u5E45\u306B\u53CE\u3081\u308B4(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, \u984C\u304B = false, textMetrics = "proportional") {
32878
+ const \u6E2C\u308B = (t, s, ls) => \u5B57\u5E452(t, s, ls, textMetrics);
32879
+ const \u5E45 = \u6E2C\u308B(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593);
32880
+ const \u4E0B\u9650 = \u984C\u304B ? \u5207\u3063\u3066\u53CE\u307E\u308B\u4E0B\u9650(\u6587\u5B57\u5217, \u5927\u304D\u3055, \u5B57\u9593, \u7BB1\u5E45, \u6E2C\u308B) : 0;
32118
32881
  const \u500D\u7387 = \u5E45 > 0 && \u7BB1\u5E45 > 0 ? Math.min(1, Math.max(\u7BB1\u5E45 / \u5E45, \u4E0B\u9650)) : 1;
32119
32882
  const size = \u5927\u304D\u3055 * \u500D\u7387;
32120
32883
  const spacing = \u5B57\u9593 * \u500D\u7387;
32121
- return { size, spacing, text: \u5E2F\u3067\u5207\u308B(\u6587\u5B57\u5217, size, \u7BB1\u5E45, (u, f) => \u5B57\u5E452(u, f, spacing)) };
32122
- }
32123
- function bottomLabel4(node, cx, plan) {
32124
- const \u80A9 = \u5E45\u306B\u53CE\u3081\u308B4(node.eyebrow ?? "", plan.\u80A9\u66F8?.size ?? 0, LABEL_EYEBROW_SPACING3, node.w);
32125
- const \u540D = \u5E45\u306B\u53CE\u3081\u308B4(node.title ?? "", plan.\u540D\u524D.size, 0, node.w, true);
32126
- const \u8AAC = \u5E45\u306B\u53CE\u3081\u308B4(node.subtitle ?? "", plan.\u8AAC\u660E?.size ?? 0, 0, node.w);
32884
+ return { size, spacing, text: \u5E2F\u3067\u5207\u308B(\u6587\u5B57\u5217, size, \u7BB1\u5E45, (u, f) => \u6E2C\u308B(u, f, spacing)) };
32885
+ }
32886
+ function bottomLabel4(node, cx, plan, textMetrics = "proportional") {
32887
+ const \u80A9 = \u5E45\u306B\u53CE\u3081\u308B4(
32888
+ node.eyebrow ?? "",
32889
+ plan.\u80A9\u66F8?.size ?? 0,
32890
+ LABEL_EYEBROW_SPACING3,
32891
+ node.w,
32892
+ false,
32893
+ textMetrics
32894
+ );
32895
+ const \u540D = \u5E45\u306B\u53CE\u3081\u308B4(node.title ?? "", plan.\u540D\u524D.size, 0, node.w, true, textMetrics);
32896
+ const \u8AAC = \u5E45\u306B\u53CE\u3081\u308B4(
32897
+ node.subtitle ?? "",
32898
+ plan.\u8AAC\u660E?.size ?? 0,
32899
+ 0,
32900
+ node.w,
32901
+ false,
32902
+ textMetrics
32903
+ );
32127
32904
  return /* @__PURE__ */ jsxs(Fragment, { children: [
32128
32905
  node.eyebrow && plan.\u80A9\u66F8 && /* @__PURE__ */ jsx("text", { x: cx, y: plan.\u80A9\u66F8.y, fontSize: \u80A9.size, fontWeight: 700, letterSpacing: \u80A9.spacing, textAnchor: "middle", fill: "var(--cdl-tone-accent, #2d6a8f)", children: \u80A9.text }),
32129
32906
  /* @__PURE__ */ jsx("text", { "data-cdl-role": "node-label", x: cx, y: plan.\u540D\u524D.y, fontSize: \u540D.size, fontWeight: 700, textAnchor: "middle", fill: "var(--cdl-text, #1a1f2a)", children: \u540D.text }),
@@ -32135,7 +32912,7 @@ var WEBSITE_BAR_H = 32;
32135
32912
  var WEBSITE_H_MIN = WEBSITE_BAR_H + 98;
32136
32913
  var WEBSITE_W_MIN = 160;
32137
32914
  var WEBSITE_W_MAX = 280;
32138
- function ShapeWebsiteNode({ node, active }) {
32915
+ function ShapeWebsiteNode({ node, active, textMetrics = "proportional" }) {
32139
32916
  const frame = commonFrame6(active);
32140
32917
  const r = shapeRegion(node);
32141
32918
  const cx = r.cx;
@@ -32161,10 +32938,10 @@ function ShapeWebsiteNode({ node, active }) {
32161
32938
  ] });
32162
32939
  return /* @__PURE__ */ jsxs("g", { children: [
32163
32940
  fitArt(r, \u5E83\u304C\u308A, \u7D75),
32164
- bottomLabel4(node, r.cx, r.label)
32941
+ bottomLabel4(node, r.cx, r.label, textMetrics)
32165
32942
  ] });
32166
32943
  }
32167
- function ShapeStorefrontNode({ node, active, lang }) {
32944
+ function ShapeStorefrontNode({ node, active, lang, textMetrics = "proportional" }) {
32168
32945
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
32169
32946
  const frame = commonFrame6(active);
32170
32947
  const r = shapeRegion(node);
@@ -32209,7 +32986,7 @@ function ShapeStorefrontNode({ node, active, lang }) {
32209
32986
  /* @__PURE__ */ jsx("text", { x: doorX + doorW / 2, y: doorY + doorH * 0.85 + 11, fontSize: 11, fontWeight: 700, letterSpacing: 1, textAnchor: "middle", fill: "#5a3a10", children: \u5B57\u5F15("storefront.open") }),
32210
32987
  /* @__PURE__ */ jsx("circle", { cx: doorX + 6, cy: doorY + doorH * 0.55, r: 1.5, fill: "#c15a4a" }),
32211
32988
  /* @__PURE__ */ jsx("rect", { x: x - 6, y: y + bh - 6, width: bw + 12, height: 8, fill: "#5a6270", stroke: "none" }),
32212
- bottomLabel4(node, r.cx, r.label)
32989
+ bottomLabel4(node, r.cx, r.label, textMetrics)
32213
32990
  ] });
32214
32991
  }
32215
32992
  var WAREHOUSE_ROOF_H = 18;
@@ -32223,7 +33000,7 @@ var WAREHOUSE_SHADOW_RX_RATIO = 0.5;
32223
33000
  var WAREHOUSE_H_MIN = WAREHOUSE_ROOF_H + WAREHOUSE_SIGN_H + 68;
32224
33001
  var WAREHOUSE_W_MIN = 160;
32225
33002
  var WAREHOUSE_W_MAX = 240;
32226
- function ShapeWarehouseNode({ node, active, lang }) {
33003
+ function ShapeWarehouseNode({ node, active, lang, textMetrics = "proportional" }) {
32227
33004
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
32228
33005
  const frame = commonFrame6(active);
32229
33006
  const r = shapeRegion(node);
@@ -32276,13 +33053,13 @@ function ShapeWarehouseNode({ node, active, lang }) {
32276
33053
  ] });
32277
33054
  return /* @__PURE__ */ jsxs("g", { children: [
32278
33055
  fitArt(r, \u5E83\u304C\u308A, \u7D75),
32279
- bottomLabel4(node, r.cx, r.label)
33056
+ bottomLabel4(node, r.cx, r.label, textMetrics)
32280
33057
  ] });
32281
33058
  }
32282
33059
  var HANDLE_GRIP_X = 118;
32283
33060
  var HANDLE_GRIP_R = 4;
32284
33061
  var CART_SHADOW_RX = 80;
32285
- function ShapeOnlineShopNode({ node, active }) {
33062
+ function ShapeOnlineShopNode({ node, active, textMetrics = "proportional" }) {
32286
33063
  const frame = commonFrame6(active);
32287
33064
  const r = shapeRegion(node);
32288
33065
  const cy = r.cy + 10;
@@ -32338,10 +33115,10 @@ function ShapeOnlineShopNode({ node, active }) {
32338
33115
  /* @__PURE__ */ jsx("circle", { cx: wheelR, cy: wheelY, r: 16 * s, fill: "#0f1830", stroke: "#000", strokeWidth: 2 * s }),
32339
33116
  /* @__PURE__ */ jsx("circle", { cx: wheelR, cy: wheelY, r: 8 * s, fill: "#5a6270", stroke: "#0f1830", strokeWidth: 1.5 * s }),
32340
33117
  /* @__PURE__ */ jsx("circle", { cx: wheelR, cy: wheelY, r: 2 * s, fill: "#0f1830" }),
32341
- bottomLabel4(node, r.cx, r.label)
33118
+ bottomLabel4(node, r.cx, r.label, textMetrics)
32342
33119
  ] });
32343
33120
  }
32344
- function ShapeCdnEdgeNode({ node, active }) {
33121
+ function ShapeCdnEdgeNode({ node, active, textMetrics = "proportional" }) {
32345
33122
  const frame = commonFrame6(active);
32346
33123
  const r = shapeRegion(node);
32347
33124
  const cx = r.cx;
@@ -32404,7 +33181,7 @@ function ShapeCdnEdgeNode({ node, active }) {
32404
33181
  ] });
32405
33182
  return /* @__PURE__ */ jsxs("g", { children: [
32406
33183
  fitArt(r, { \u4E0A: \u5E83\u304C\u308A, \u4E0B: \u5E83\u304C\u308A, \u5DE6: \u5E83\u304C\u308A, \u53F3: \u5E83\u304C\u308A }, \u7D75),
32407
- bottomLabel4(node, r.cx, r.label)
33184
+ bottomLabel4(node, r.cx, r.label, textMetrics)
32408
33185
  ] });
32409
33186
  }
32410
33187
  var API_ROW_TOP = 52;
@@ -32419,7 +33196,7 @@ var API_METHOD_BOX_W = 54;
32419
33196
  var API_METHOD_TEXT_W = 48;
32420
33197
  var API_W_MIN = 200;
32421
33198
  var API_W_MAX = 300;
32422
- function ShapeApiGatewayNode({ node, active, lang }) {
33199
+ function ShapeApiGatewayNode({ node, active, lang, textMetrics = "proportional" }) {
32423
33200
  const \u5B57\u5F15 = \u5B57\u5F15\u304D\u3092\u4F5C\u308B(lang);
32424
33201
  const frame = commonFrame6(active);
32425
33202
  const r = shapeRegion(node);
@@ -32431,7 +33208,13 @@ function ShapeApiGatewayNode({ node, active, lang }) {
32431
33208
  const x = cx - bw / 2;
32432
33209
  const y = r.cy - \u7E26 / 2 + \u4F59\u767D;
32433
33210
  const \u5E83\u304C\u308A = { \u4E0A: \u7E26 / 2, \u4E0B: \u7E26 / 2, \u5DE6: bw / 2 + \u4F59\u767D, \u53F3: bw / 2 + \u4F59\u767D };
32434
- const \u7A2E\u985E\u306E\u5B57 = (s) => Math.min(11, 11 * API_METHOD_TEXT_W / Math.max(displayWidth(s) * 11 * MONO_ADVANCE_RATIO, textWidth(s, 11)));
33211
+ const \u7A2E\u985E\u306E\u5B57 = (s) => Math.min(
33212
+ 11,
33213
+ 11 * API_METHOD_TEXT_W / Math.max(
33214
+ displayWidth(s) * 11 * MONO_ADVANCE_RATIO,
33215
+ textWidth(s, 11, 0, textMetrics)
33216
+ )
33217
+ );
32435
33218
  const rowPitch = Math.max(
32436
33219
  API_ROW_PITCH_MIN,
32437
33220
  (bh - API_ROW_TOP - API_ROW_H - API_ROW_BOTTOM_PAD) / (API_ROWS - 1)
@@ -32447,7 +33230,7 @@ function ShapeApiGatewayNode({ node, active, lang }) {
32447
33230
  \u5E2F: { \u5E45: bw - 32 - 64 - 16, \u9AD8\u3055: API_ROW_H }
32448
33231
  }));
32449
33232
  const \u7D75 = (\u500D\u7387) => {
32450
- const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089);
33233
+ const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089, textMetrics);
32451
33234
  return /* @__PURE__ */ jsxs("g", { children: [
32452
33235
  /* @__PURE__ */ jsx("rect", { x: x + DROP_SHADOW_D, y: y + DROP_SHADOW_D, width: bw, height: bh, rx: 10, fill: frame.stroke, opacity: 0.2, stroke: "none" }),
32453
33236
  /* @__PURE__ */ jsx("rect", { "data-cdl-role": "node-body", x, y, width: bw, height: bh, rx: 10, fill: "#1a2332", stroke: frame.stroke, strokeWidth: frame.strokeWidth }),
@@ -32464,7 +33247,7 @@ function ShapeApiGatewayNode({ node, active, lang }) {
32464
33247
  };
32465
33248
  return /* @__PURE__ */ jsxs("g", { children: [
32466
33249
  fitArt(r, \u5E83\u304C\u308A, \u7D75),
32467
- bottomLabel4(node, r.cx, r.label)
33250
+ bottomLabel4(node, r.cx, r.label, textMetrics)
32468
33251
  ] });
32469
33252
  }
32470
33253
  function bottomLabel5(node, cx, plan) {
@@ -32764,6 +33547,7 @@ function CdlNodeView({
32764
33547
  chartLineScale,
32765
33548
  \u95A2\u4FC2\u306E\u53D7\u3051\u53E3,
32766
33549
  lang,
33550
+ textMetrics,
32767
33551
  \u5024\u306E\u540D\u524D
32768
33552
  }) {
32769
33553
  const value = node.value ? interpolate(node.value, stateValues, \u5024\u306E\u540D\u524D) : void 0;
@@ -32808,7 +33592,14 @@ function CdlNodeView({
32808
33592
  return /* @__PURE__ */ jsx(CardNode, { node: resolvedNode, active });
32809
33593
  // 時系列のやり取り (#578)。 1 つの箱が図を丸ごと描く = 縦が時間で、参加者は箱を持たない
32810
33594
  case "sequence-board":
32811
- return /* @__PURE__ */ jsx(SequenceBoardNode, { node: resolvedNode, stateValues });
33595
+ return /* @__PURE__ */ jsx(
33596
+ SequenceBoardNode,
33597
+ {
33598
+ node: resolvedNode,
33599
+ stateValues,
33600
+ textMetrics
33601
+ }
33602
+ );
32812
33603
  // 図表 9 種は payload が `{signal}` を取れるので stateValues を渡す
32813
33604
  // (`render/payload-binding.ts` が描画直前に解決する)。 取れる欄は種別で違い、
32814
33605
  // 数と語を取る 7 種に対し、mind-map / tree-hierarchy は **名前だけ** を取る (#467)。
@@ -32833,7 +33624,8 @@ function CdlNodeView({
32833
33624
  active,
32834
33625
  stateValues,
32835
33626
  drawing,
32836
- progress
33627
+ progress,
33628
+ textMetrics
32837
33629
  }
32838
33630
  );
32839
33631
  case "chart-gauge":
@@ -32844,7 +33636,8 @@ function CdlNodeView({
32844
33636
  active,
32845
33637
  stateValues,
32846
33638
  drawing,
32847
- progress
33639
+ progress,
33640
+ textMetrics
32848
33641
  }
32849
33642
  );
32850
33643
  case "chart-stacked-bar":
@@ -32855,7 +33648,8 @@ function CdlNodeView({
32855
33648
  active,
32856
33649
  stateValues,
32857
33650
  drawing,
32858
- progress
33651
+ progress,
33652
+ textMetrics
32859
33653
  }
32860
33654
  );
32861
33655
  case "chart-slope":
@@ -32866,7 +33660,8 @@ function CdlNodeView({
32866
33660
  active,
32867
33661
  stateValues,
32868
33662
  drawing,
32869
- progress
33663
+ progress,
33664
+ textMetrics
32870
33665
  }
32871
33666
  );
32872
33667
  case "chart-waffle":
@@ -32877,11 +33672,20 @@ function CdlNodeView({
32877
33672
  active,
32878
33673
  stateValues,
32879
33674
  drawing,
32880
- progress
33675
+ progress,
33676
+ textMetrics
32881
33677
  }
32882
33678
  );
32883
33679
  case "chart-stat":
32884
- return /* @__PURE__ */ jsx(ChartStatNode, { node: resolvedNode, active, stateValues });
33680
+ return /* @__PURE__ */ jsx(
33681
+ ChartStatNode,
33682
+ {
33683
+ node: resolvedNode,
33684
+ active,
33685
+ stateValues,
33686
+ textMetrics
33687
+ }
33688
+ );
32885
33689
  case "chart-radial":
32886
33690
  return /* @__PURE__ */ jsx(
32887
33691
  ChartRadialNode,
@@ -32890,7 +33694,8 @@ function CdlNodeView({
32890
33694
  active,
32891
33695
  stateValues,
32892
33696
  drawing,
32893
- progress
33697
+ progress,
33698
+ textMetrics
32894
33699
  }
32895
33700
  );
32896
33701
  case "chart-bar":
@@ -32923,7 +33728,8 @@ function CdlNodeView({
32923
33728
  active,
32924
33729
  stateValues,
32925
33730
  drawing,
32926
- progress
33731
+ progress,
33732
+ textMetrics
32927
33733
  }
32928
33734
  );
32929
33735
  case "funnel-stages":
@@ -32934,11 +33740,20 @@ function CdlNodeView({
32934
33740
  active,
32935
33741
  stateValues,
32936
33742
  drawing,
32937
- progress
33743
+ progress,
33744
+ textMetrics
32938
33745
  }
32939
33746
  );
32940
33747
  case "quadrant-matrix":
32941
- return /* @__PURE__ */ jsx(QuadrantNode, { node: resolvedNode, active, stateValues });
33748
+ return /* @__PURE__ */ jsx(
33749
+ QuadrantNode,
33750
+ {
33751
+ node: resolvedNode,
33752
+ active,
33753
+ stateValues,
33754
+ textMetrics
33755
+ }
33756
+ );
32942
33757
  case "tree-hierarchy":
32943
33758
  return /* @__PURE__ */ jsx(
32944
33759
  TreeNode,
@@ -32947,7 +33762,8 @@ function CdlNodeView({
32947
33762
  active,
32948
33763
  stateValues,
32949
33764
  drawing,
32950
- progress
33765
+ progress,
33766
+ textMetrics
32951
33767
  }
32952
33768
  );
32953
33769
  case "journey-map":
@@ -32962,91 +33778,91 @@ function CdlNodeView({
32962
33778
  }
32963
33779
  );
32964
33780
  case "shape-file":
32965
- return /* @__PURE__ */ jsx(ShapeFileNode, { node: resolvedNode, active });
33781
+ return /* @__PURE__ */ jsx(ShapeFileNode, { node: resolvedNode, active, textMetrics });
32966
33782
  case "shape-folder":
32967
- return /* @__PURE__ */ jsx(ShapeFolderNode, { node: resolvedNode, active });
33783
+ return /* @__PURE__ */ jsx(ShapeFolderNode, { node: resolvedNode, active, textMetrics });
32968
33784
  case "shape-cloud":
32969
- return /* @__PURE__ */ jsx(ShapeCloudNode, { node: resolvedNode, active });
33785
+ return /* @__PURE__ */ jsx(ShapeCloudNode, { node: resolvedNode, active, textMetrics });
32970
33786
  case "shape-cylinder":
32971
- return /* @__PURE__ */ jsx(ShapeCylinderNode, { node: resolvedNode, active });
33787
+ return /* @__PURE__ */ jsx(ShapeCylinderNode, { node: resolvedNode, active, textMetrics });
32972
33788
  case "shape-hexagon":
32973
- return /* @__PURE__ */ jsx(ShapeHexagonNode, { node: resolvedNode, active });
33789
+ return /* @__PURE__ */ jsx(ShapeHexagonNode, { node: resolvedNode, active, textMetrics });
32974
33790
  case "shape-diamond":
32975
- return /* @__PURE__ */ jsx(ShapeDiamondNode, { node: resolvedNode, active });
33791
+ return /* @__PURE__ */ jsx(ShapeDiamondNode, { node: resolvedNode, active, textMetrics });
32976
33792
  case "shape-stack":
32977
- return /* @__PURE__ */ jsx(ShapeStackNode, { node: resolvedNode, active });
33793
+ return /* @__PURE__ */ jsx(ShapeStackNode, { node: resolvedNode, active, textMetrics });
32978
33794
  case "shape-person":
32979
- return /* @__PURE__ */ jsx(ShapePersonNode, { node: resolvedNode, active });
33795
+ return /* @__PURE__ */ jsx(ShapePersonNode, { node: resolvedNode, active, textMetrics });
32980
33796
  case "shape-window":
32981
33797
  return /* @__PURE__ */ jsx(ShapeWindowNode, { node: resolvedNode, active });
32982
33798
  case "shape-terminal":
32983
33799
  return /* @__PURE__ */ jsx(ShapeTerminalNode, { node: resolvedNode, active, lang });
32984
33800
  case "shape-code-block":
32985
- return /* @__PURE__ */ jsx(ShapeCodeBlockNode, { node: resolvedNode, active, lang });
33801
+ return /* @__PURE__ */ jsx(ShapeCodeBlockNode, { node: resolvedNode, active, lang, textMetrics });
32986
33802
  case "shape-kanban-card":
32987
- return /* @__PURE__ */ jsx(ShapeKanbanCardNode, { node: resolvedNode, active, lang });
33803
+ return /* @__PURE__ */ jsx(ShapeKanbanCardNode, { node: resolvedNode, active, lang, textMetrics });
32988
33804
  case "shape-message-bubble":
32989
33805
  return /* @__PURE__ */ jsx(ShapeMessageBubbleNode, { node: resolvedNode, active });
32990
33806
  case "shape-gear":
32991
33807
  return /* @__PURE__ */ jsx(ShapeGearNode, { node: resolvedNode, active });
32992
33808
  case "shape-server-rack":
32993
- return /* @__PURE__ */ jsx(ShapeServerRackNode, { node: resolvedNode, active });
33809
+ return /* @__PURE__ */ jsx(ShapeServerRackNode, { node: resolvedNode, active, textMetrics });
32994
33810
  case "shape-network-node":
32995
- return /* @__PURE__ */ jsx(ShapeNetworkNodeNode, { node: resolvedNode, active });
33811
+ return /* @__PURE__ */ jsx(ShapeNetworkNodeNode, { node: resolvedNode, active, textMetrics });
32996
33812
  case "shape-mobile-device":
32997
- return /* @__PURE__ */ jsx(ShapeMobileDeviceNode, { node: resolvedNode, active });
33813
+ return /* @__PURE__ */ jsx(ShapeMobileDeviceNode, { node: resolvedNode, active, textMetrics });
32998
33814
  case "shape-iot-sensor":
32999
33815
  return /* @__PURE__ */ jsx(ShapeIotSensorNode, { node: resolvedNode, active });
33000
33816
  case "shape-robot-arm":
33001
33817
  return /* @__PURE__ */ jsx(ShapeRobotArmNode, { node: resolvedNode, active });
33002
33818
  case "shape-satellite":
33003
- return /* @__PURE__ */ jsx(ShapeSatelliteNode, { node: resolvedNode, active });
33819
+ return /* @__PURE__ */ jsx(ShapeSatelliteNode, { node: resolvedNode, active, textMetrics });
33004
33820
  case "shape-smart-contract":
33005
- return /* @__PURE__ */ jsx(ShapeSmartContractNode, { node: resolvedNode, active, lang });
33821
+ return /* @__PURE__ */ jsx(ShapeSmartContractNode, { node: resolvedNode, active, lang, textMetrics });
33006
33822
  case "shape-blockchain-block":
33007
- return /* @__PURE__ */ jsx(ShapeBlockchainBlockNode, { node: resolvedNode, active, lang });
33823
+ return /* @__PURE__ */ jsx(ShapeBlockchainBlockNode, { node: resolvedNode, active, lang, textMetrics });
33008
33824
  case "shape-rpc-node":
33009
- return /* @__PURE__ */ jsx(ShapeRpcNodeNode, { node: resolvedNode, active, lang });
33825
+ return /* @__PURE__ */ jsx(ShapeRpcNodeNode, { node: resolvedNode, active, lang, textMetrics });
33010
33826
  case "shape-wallet":
33011
- return /* @__PURE__ */ jsx(ShapeWalletNode, { node: resolvedNode, active });
33827
+ return /* @__PURE__ */ jsx(ShapeWalletNode, { node: resolvedNode, active, textMetrics });
33012
33828
  case "shape-nft":
33013
- return /* @__PURE__ */ jsx(ShapeNftNode, { node: resolvedNode, active });
33829
+ return /* @__PURE__ */ jsx(ShapeNftNode, { node: resolvedNode, active, textMetrics });
33014
33830
  case "shape-token":
33015
- return /* @__PURE__ */ jsx(ShapeTokenNode, { node: resolvedNode, active });
33831
+ return /* @__PURE__ */ jsx(ShapeTokenNode, { node: resolvedNode, active, textMetrics });
33016
33832
  case "shape-blockchain":
33017
- return /* @__PURE__ */ jsx(ShapeBlockchainNode, { node: resolvedNode, active });
33833
+ return /* @__PURE__ */ jsx(ShapeBlockchainNode, { node: resolvedNode, active, textMetrics });
33018
33834
  case "shape-bitcoin-chain":
33019
- return /* @__PURE__ */ jsx(ShapeBitcoinChainNode, { node: resolvedNode, active });
33835
+ return /* @__PURE__ */ jsx(ShapeBitcoinChainNode, { node: resolvedNode, active, textMetrics });
33020
33836
  case "shape-ethereum-chain":
33021
- return /* @__PURE__ */ jsx(ShapeEthereumChainNode, { node: resolvedNode, active });
33837
+ return /* @__PURE__ */ jsx(ShapeEthereumChainNode, { node: resolvedNode, active, textMetrics });
33022
33838
  case "shape-blockchain-node":
33023
- return /* @__PURE__ */ jsx(ShapeBlockchainNodeNode, { node: resolvedNode, active });
33839
+ return /* @__PURE__ */ jsx(ShapeBlockchainNodeNode, { node: resolvedNode, active, textMetrics });
33024
33840
  case "shape-bank":
33025
- return /* @__PURE__ */ jsx(ShapeBankNode, { node: resolvedNode, active });
33841
+ return /* @__PURE__ */ jsx(ShapeBankNode, { node: resolvedNode, active, textMetrics });
33026
33842
  case "shape-trust-bank":
33027
- return /* @__PURE__ */ jsx(ShapeTrustBankNode, { node: resolvedNode, active, lang });
33843
+ return /* @__PURE__ */ jsx(ShapeTrustBankNode, { node: resolvedNode, active, lang, textMetrics });
33028
33844
  case "shape-payment-provider":
33029
- return /* @__PURE__ */ jsx(ShapePaymentProviderNode, { node: resolvedNode, active, lang });
33845
+ return /* @__PURE__ */ jsx(ShapePaymentProviderNode, { node: resolvedNode, active, lang, textMetrics });
33030
33846
  case "shape-credit-card":
33031
- return /* @__PURE__ */ jsx(ShapeCreditCardNode, { node: resolvedNode, active });
33847
+ return /* @__PURE__ */ jsx(ShapeCreditCardNode, { node: resolvedNode, active, textMetrics });
33032
33848
  case "shape-brokerage":
33033
- return /* @__PURE__ */ jsx(ShapeBrokerageNode, { node: resolvedNode, active, lang });
33849
+ return /* @__PURE__ */ jsx(ShapeBrokerageNode, { node: resolvedNode, active, lang, textMetrics });
33034
33850
  case "shape-exchange":
33035
- return /* @__PURE__ */ jsx(ShapeExchangeNode, { node: resolvedNode, active, lang });
33851
+ return /* @__PURE__ */ jsx(ShapeExchangeNode, { node: resolvedNode, active, lang, textMetrics });
33036
33852
  case "shape-atm":
33037
- return /* @__PURE__ */ jsx(ShapeAtmNode, { node: resolvedNode, active, lang });
33853
+ return /* @__PURE__ */ jsx(ShapeAtmNode, { node: resolvedNode, active, lang, textMetrics });
33038
33854
  case "shape-website":
33039
- return /* @__PURE__ */ jsx(ShapeWebsiteNode, { node: resolvedNode, active });
33855
+ return /* @__PURE__ */ jsx(ShapeWebsiteNode, { node: resolvedNode, active, textMetrics });
33040
33856
  case "shape-storefront":
33041
- return /* @__PURE__ */ jsx(ShapeStorefrontNode, { node: resolvedNode, active, lang });
33857
+ return /* @__PURE__ */ jsx(ShapeStorefrontNode, { node: resolvedNode, active, lang, textMetrics });
33042
33858
  case "shape-warehouse":
33043
- return /* @__PURE__ */ jsx(ShapeWarehouseNode, { node: resolvedNode, active, lang });
33859
+ return /* @__PURE__ */ jsx(ShapeWarehouseNode, { node: resolvedNode, active, lang, textMetrics });
33044
33860
  case "shape-online-shop":
33045
- return /* @__PURE__ */ jsx(ShapeOnlineShopNode, { node: resolvedNode, active });
33861
+ return /* @__PURE__ */ jsx(ShapeOnlineShopNode, { node: resolvedNode, active, textMetrics });
33046
33862
  case "shape-cdn-edge":
33047
- return /* @__PURE__ */ jsx(ShapeCdnEdgeNode, { node: resolvedNode, active });
33863
+ return /* @__PURE__ */ jsx(ShapeCdnEdgeNode, { node: resolvedNode, active, textMetrics });
33048
33864
  case "shape-api-gateway":
33049
- return /* @__PURE__ */ jsx(ShapeApiGatewayNode, { node: resolvedNode, active, lang });
33865
+ return /* @__PURE__ */ jsx(ShapeApiGatewayNode, { node: resolvedNode, active, lang, textMetrics });
33050
33866
  case "shape-auditor":
33051
33867
  return /* @__PURE__ */ jsx(ShapeAuditorNode, { node: resolvedNode, active });
33052
33868
  case "shape-regulator":
@@ -33063,8 +33879,20 @@ function CdlNodeView({
33063
33879
  return /* @__PURE__ */ jsx(MarkStartNode, { node: resolvedNode, active });
33064
33880
  case "mark-end":
33065
33881
  return /* @__PURE__ */ jsx(MarkEndNode, { node: resolvedNode, active });
33882
+ case "station":
33883
+ return /* @__PURE__ */ jsx(StationNode, { node: resolvedNode, active });
33066
33884
  default:
33067
- return /* @__PURE__ */ jsx(GenericNode, { node: resolvedNode, active, value: node.value, stateValues, \u5024\u306E\u540D\u524D });
33885
+ return /* @__PURE__ */ jsx(
33886
+ GenericNode,
33887
+ {
33888
+ node: resolvedNode,
33889
+ active,
33890
+ value: node.value,
33891
+ stateValues,
33892
+ \u5024\u306E\u540D\u524D,
33893
+ textMetrics
33894
+ }
33895
+ );
33068
33896
  }
33069
33897
  })();
33070
33898
  const offsetX = node.renderOffsetX !== void 0 ? resolveNumericAttr(node.renderOffsetX, stateValues, 0) : 0;
@@ -33125,7 +33953,7 @@ function CdlNodeView({
33125
33953
  }
33126
33954
  ),
33127
33955
  inner,
33128
- \u7BB1\u306E\u4E0A\u306E\u8A9E(resolvedNode)
33956
+ \u7BB1\u306E\u4E0A\u306E\u8A9E(resolvedNode, textMetrics ?? "proportional")
33129
33957
  ]
33130
33958
  }
33131
33959
  );
@@ -33134,17 +33962,17 @@ var FIGURE_TITLE_GAP = 10;
33134
33962
  var FIGURE_TITLE_SIZE = 15;
33135
33963
  var FIGURE_EYEBROW_SIZE = 11;
33136
33964
  var FIGURE_EYEBROW_LIFT = 1.1;
33137
- function \u5E45\u306B\u53CE\u3081\u305F\u5927\u304D\u3055(\u8A9E, \u7D20\u306E\u5927\u304D\u3055, \u5E45) {
33138
- const \u5B9F\u5E45 = textWidth(\u8A9E, \u7D20\u306E\u5927\u304D\u3055, 0);
33965
+ function \u5E45\u306B\u53CE\u3081\u305F\u5927\u304D\u3055(\u8A9E, \u7D20\u306E\u5927\u304D\u3055, \u5E45, textMetrics = "proportional") {
33966
+ const \u5B9F\u5E45 = textWidth(\u8A9E, \u7D20\u306E\u5927\u304D\u3055, 0, textMetrics);
33139
33967
  return \u5B9F\u5E45 > \u5E45 ? \u7D20\u306E\u5927\u304D\u3055 * \u5E45 / \u5B9F\u5E45 : \u7D20\u306E\u5927\u304D\u3055;
33140
33968
  }
33141
- function \u7BB1\u306E\u4E0A\u306E\u8A9E(node) {
33969
+ function \u7BB1\u306E\u4E0A\u306E\u8A9E(node, textMetrics = "proportional") {
33142
33970
  if (!drawsFigureTitle(node.kind)) return null;
33143
33971
  const \u540D\u524D = (node.title ?? "").trim();
33144
33972
  const \u5C0F\u898B\u51FA\u3057 = (node.eyebrow ?? "").trim();
33145
33973
  if (\u540D\u524D === "" && \u5C0F\u898B\u51FA\u3057 === "") return null;
33146
33974
  const \u984C\u306Ey = node.cy - node.h / 2 - FIGURE_TITLE_GAP;
33147
- const \u984C\u306E\u5927\u304D\u3055 = \u5E45\u306B\u53CE\u3081\u305F\u5927\u304D\u3055(\u540D\u524D, FIGURE_TITLE_SIZE, node.w);
33975
+ const \u984C\u306E\u5927\u304D\u3055 = \u5E45\u306B\u53CE\u3081\u305F\u5927\u304D\u3055(\u540D\u524D, FIGURE_TITLE_SIZE, node.w, textMetrics);
33148
33976
  const \u5C0F\u898B\u51FA\u3057\u306Ey = \u540D\u524D === "" ? \u984C\u306Ey : \u984C\u306Ey - \u984C\u306E\u5927\u304D\u3055 * FIGURE_EYEBROW_LIFT;
33149
33977
  return /* @__PURE__ */ jsxs(Fragment, { children: [
33150
33978
  \u5C0F\u898B\u51FA\u3057 !== "" && /* @__PURE__ */ jsx(
@@ -33154,7 +33982,7 @@ function \u7BB1\u306E\u4E0A\u306E\u8A9E(node) {
33154
33982
  x: node.cx,
33155
33983
  y: \u5C0F\u898B\u51FA\u3057\u306Ey,
33156
33984
  textAnchor: "middle",
33157
- fontSize: \u5E45\u306B\u53CE\u3081\u305F\u5927\u304D\u3055(\u5C0F\u898B\u51FA\u3057, FIGURE_EYEBROW_SIZE, node.w),
33985
+ fontSize: \u5E45\u306B\u53CE\u3081\u305F\u5927\u304D\u3055(\u5C0F\u898B\u51FA\u3057, FIGURE_EYEBROW_SIZE, node.w, textMetrics),
33158
33986
  fontWeight: 600,
33159
33987
  letterSpacing: 0.6,
33160
33988
  fill: "var(--cdl-text-dim, #5a6270)",
@@ -33295,15 +34123,15 @@ function CdlStage({
33295
34123
  }, [laid]);
33296
34124
  const edgeHeadMarkers = useMemo(() => {
33297
34125
  const referenced = /* @__PURE__ */ new Set();
33298
- const add = (tone, head, fill) => {
34126
+ const add2 = (tone, head, fill) => {
33299
34127
  for (const small of [false, true]) {
33300
34128
  const id = edgeHeadMarkerName(tone, head, small, fill);
33301
34129
  if (id !== void 0) referenced.add(id);
33302
34130
  }
33303
34131
  };
33304
34132
  for (const edge of laid.edges) {
33305
- add(edge.tone, edge.head, edge.headFill);
33306
- if (edge.tailHead !== void 0) add(edge.tone, edge.tailHead, edge.tailHeadFill);
34133
+ add2(edge.tone, edge.head, edge.headFill);
34134
+ if (edge.tailHead !== void 0) add2(edge.tone, edge.tailHead, edge.tailHeadFill);
33307
34135
  }
33308
34136
  return Object.entries(TONE).flatMap(
33309
34137
  ([tone, color]) => [
@@ -33479,6 +34307,7 @@ function CdlStage({
33479
34307
  node,
33480
34308
  active: activeSet.has(node.id),
33481
34309
  lang: laid.lang,
34310
+ textMetrics: laid.textMetrics,
33482
34311
  \u95A2\u4FC2\u306E\u53D7\u3051\u53E3: \u7BB1\u306E\u53D7\u3051\u53E3,
33483
34312
  drawing: \u63CF\u304F,
33484
34313
  progress: \u63CF\u304F ? \u63CF\u304F\u9032\u307F : progress,
@@ -33495,7 +34324,8 @@ function CdlStage({
33495
34324
  CdlEdgeLabelView,
33496
34325
  {
33497
34326
  edge,
33498
- active: activeSet.has(edge.id)
34327
+ active: activeSet.has(edge.id),
34328
+ textMetrics: laid.textMetrics
33499
34329
  },
33500
34330
  `label-${edge.id}`
33501
34331
  )),
@@ -33505,7 +34335,8 @@ function CdlStage({
33505
34335
  {
33506
34336
  edge,
33507
34337
  active: activeSet.has(edge.id),
33508
- \u7AEF
34338
+ \u7AEF,
34339
+ textMetrics: laid.textMetrics
33509
34340
  },
33510
34341
  `${\u7AEF}-label-${edge.id}`
33511
34342
  ))
@@ -33950,8 +34781,8 @@ function pointToSegmentDistance2(px, py, seg) {
33950
34781
  }
33951
34782
 
33952
34783
  // src/layout/predict-bbox.ts
33953
- function predictLabelBBoxWorld(edge) {
33954
- return computeLabelBBoxWorld(edge);
34784
+ function predictLabelBBoxWorld(edge, textMetrics = "proportional") {
34785
+ return computeLabelBBoxWorld(edge, textMetrics);
33955
34786
  }
33956
34787
  function predictNodeBBoxWorld(n) {
33957
34788
  return {
@@ -34011,12 +34842,12 @@ function resolveStorageBoxW(width, presetName, optionName) {
34011
34842
  }
34012
34843
  return width;
34013
34844
  }
34014
- function fitRowsWidth(boxW, rows) {
34015
- return Math.max(boxW, requiredRowsWidth(rows ? [...rows] : void 0, "storage"));
34845
+ function fitRowsWidth(boxW, rows, textMetrics = "proportional") {
34846
+ return Math.max(boxW, requiredRowsWidth(rows ? [...rows] : void 0, "storage", textMetrics));
34016
34847
  }
34017
34848
  function swimlane(preset) {
34018
34849
  const w = preset.laneWidth ?? 400;
34019
- const b = diagram(preset.id, { topic: preset.topic, type: "swimlane" });
34850
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "swimlane" });
34020
34851
  const labelToId = /* @__PURE__ */ new Map();
34021
34852
  const idsInOrder = [];
34022
34853
  for (const label of preset.lanes) {
@@ -34036,7 +34867,7 @@ function swimlane(preset) {
34036
34867
  }
34037
34868
  function flow(preset) {
34038
34869
  const w = preset.laneWidth ?? 400;
34039
- const b = diagram(preset.id, { topic: preset.topic, type: "flow" });
34870
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "flow" });
34040
34871
  b.lane("flow", { width: w, ...preset.laneLabel ? { label: preset.laneLabel } : {} });
34041
34872
  const tone = preset.defaultTone ?? "accent";
34042
34873
  const style = preset.defaultStyle ?? "dotted-flow";
@@ -34097,7 +34928,7 @@ var SEQUENCE_MESSAGE_LOOK = {
34097
34928
  };
34098
34929
  function sequence(preset) {
34099
34930
  const tone = preset.defaultTone ?? "accent";
34100
- const b = diagram(preset.id, { topic: preset.topic, type: "sequence" });
34931
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "sequence" });
34101
34932
  const \u9762\u3005 = preset.actors.map(
34102
34933
  (a) => typeof a === "string" ? { name: a } : { name: a.name, ...a.subtitle ? { subtitle: a.subtitle } : {} }
34103
34934
  );
@@ -34123,7 +34954,7 @@ function sequence(preset) {
34123
34954
  return \u51FA\u756A.length > 0 ? { actor: i, from: \u51FA\u756A[0], to: \u51FA\u756A[\u51FA\u756A.length - 1] } : null;
34124
34955
  }).filter((x) => x !== null);
34125
34956
  const data = { actors: \u9762\u3005, messages: \u8A00\u3065\u3066, bands: \u5E2F };
34126
- const m = sequenceBoardMetrics(data);
34957
+ const m = sequenceBoardMetrics(data, resolveTextMetrics(preset.textMetrics));
34127
34958
  const laneId = "seq";
34128
34959
  b.lane(laneId, { width: m.w + LANE_PAD_MIN * 2 });
34129
34960
  b.node(preset.id, {
@@ -34152,7 +34983,7 @@ function topology(preset) {
34152
34983
  const groupW = preset.groupWidth ?? 460;
34153
34984
  const tone = preset.defaultTone ?? "accent";
34154
34985
  const style = preset.defaultStyle ?? "solid";
34155
- const b = diagram(preset.id, { topic: preset.topic, type: "topology" });
34986
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "topology" });
34156
34987
  const groupOrder = [];
34157
34988
  const groupStackCount = /* @__PURE__ */ new Map();
34158
34989
  const phaseActivate = [];
@@ -34221,7 +35052,12 @@ function er(preset) {
34221
35052
  const entityW = resolveStorageBoxW(preset.entityWidth, "er", "entityWidth");
34222
35053
  const tone = preset.defaultTone ?? "info";
34223
35054
  const \u7E1E\u3092\u6577\u304F = preset.rowStripe ?? true;
34224
- const b = diagram(preset.id, { topic: preset.topic, palette: preset.palette, type: "er" });
35055
+ const b = diagram(preset.id, {
35056
+ topic: preset.topic,
35057
+ palette: preset.palette,
35058
+ textMetrics: preset.textMetrics,
35059
+ type: "er"
35060
+ });
34225
35061
  const entities = [];
34226
35062
  const phaseActivate = [];
34227
35063
  let relIdx = 0;
@@ -34244,7 +35080,7 @@ function er(preset) {
34244
35080
  \u5024.forEach(\u8DB3\u3059);
34245
35081
  const \u8A2D\u8A08\u306E\u5F62 = \u884C.length > 0;
34246
35082
  const rows = \u8A2D\u8A08\u306E\u5F62 ? \u884C : e.rows ?? [];
34247
- const boxW = fitRowsWidth(entityW, rows);
35083
+ const boxW = fitRowsWidth(entityW, rows, resolveTextMetrics(preset.textMetrics));
34248
35084
  b.lane(laneId, { width: boxLaneW(boxW) });
34249
35085
  b.node(e.id, {
34250
35086
  lane: laneId,
@@ -34308,7 +35144,7 @@ function stateMachine(preset) {
34308
35144
  const stateW = resolveStateW(preset.stateWidth, "stateMachine");
34309
35145
  const tone = preset.defaultTone ?? "accent";
34310
35146
  const diagramType = "state";
34311
- const b = diagram(preset.id, { topic: preset.topic, type: diagramType });
35147
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: diagramType });
34312
35148
  const phaseActivate = [];
34313
35149
  const stateOrder = /* @__PURE__ */ new Map();
34314
35150
  const \u72B6\u614B = [];
@@ -34339,7 +35175,7 @@ function stateMachine(preset) {
34339
35175
  const \u884C = (s.actions ?? []).map((a) => a.note ? `${a.label}: ${a.note}` : a.label);
34340
35176
  const \u5370 = (s.actions ?? []).map((a) => FSM_ACTION_MARK[a.when]);
34341
35177
  const laneId = \u683C\u5B50 && s.col !== void 0 ? `col-${s.col}` : `lane-${s.id}`;
34342
- const boxW = \u8A2D\u8A08\u306E\u5F62 ? fitRowsWidth(stateW, \u884C) : stateW;
35178
+ const boxW = \u8A2D\u8A08\u306E\u5F62 ? fitRowsWidth(stateW, \u884C, resolveTextMetrics(preset.textMetrics)) : stateW;
34343
35179
  return { s, \u884C, \u5370, laneId, boxW, stack: \u683C\u5B50 ? s.row ?? 0 : 0 };
34344
35180
  });
34345
35181
  const \u7BC0\u70B9\u306E\u4E2D\u8EAB = \u7BC0\u70B9.map((m) => ({
@@ -34420,7 +35256,11 @@ function infrastructure(preset) {
34420
35256
  const laneW = preset.laneWidth ?? 380;
34421
35257
  const tone = preset.defaultTone ?? "accent";
34422
35258
  const style = preset.defaultStyle ?? "solid";
34423
- const b = diagram(preset.id, { topic: preset.topic, type: "infrastructure" });
35259
+ const b = diagram(preset.id, {
35260
+ topic: preset.topic,
35261
+ textMetrics: preset.textMetrics,
35262
+ type: "infrastructure"
35263
+ });
34424
35264
  const colLaneIds = /* @__PURE__ */ new Map();
34425
35265
  const phaseActivate = [];
34426
35266
  let connIdx = 0;
@@ -34501,7 +35341,12 @@ function classDiagram(preset) {
34501
35341
  const classW = resolveStorageBoxW(preset.classWidth, "classDiagram", "classWidth");
34502
35342
  const \u56F3\u306E\u65E2\u5B9A = preset.defaultTone;
34503
35343
  const \u7E1E\u3092\u6577\u304F = preset.rowStripe ?? true;
34504
- const b = diagram(preset.id, { topic: preset.topic, palette: preset.palette, type: "class" });
35344
+ const b = diagram(preset.id, {
35345
+ topic: preset.topic,
35346
+ palette: preset.palette,
35347
+ textMetrics: preset.textMetrics,
35348
+ type: "class"
35349
+ });
34505
35350
  const classes = [];
34506
35351
  const phaseActivate = [];
34507
35352
  const \u7BB1 = [];
@@ -34527,7 +35372,7 @@ function classDiagram(preset) {
34527
35372
  rows.push(stripAccess(m));
34528
35373
  rowMarks.push({ shape: "chevron", filled: isPublic(m) });
34529
35374
  }
34530
- const boxW = fitRowsWidth(classW, rows);
35375
+ const boxW = fitRowsWidth(classW, rows, resolveTextMetrics(preset.textMetrics));
34531
35376
  const laneId = c.col !== void 0 ? `col-${c.col}` : `lane-${c.id}`;
34532
35377
  return { c, rows, rowMarks, boxW, laneId, stack: c.col !== void 0 ? c.row ?? 0 : 0 };
34533
35378
  });
@@ -34590,7 +35435,7 @@ function classDiagram(preset) {
34590
35435
  }
34591
35436
  function tree(preset) {
34592
35437
  const canvasH = 480;
34593
- const b = diagram(preset.id, { topic: preset.topic, type: "tree" });
35438
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "tree" });
34594
35439
  const treeNodes = [];
34595
35440
  const api = {
34596
35441
  node(n) {
@@ -34629,7 +35474,7 @@ function tree(preset) {
34629
35474
  function userJourney(preset) {
34630
35475
  const canvasW = preset.stepWidth ? preset.stepWidth * 2 : 720;
34631
35476
  const canvasH = 480;
34632
- const b = diagram(preset.id, { topic: preset.topic, type: "journey" });
35477
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "journey" });
34633
35478
  const steps = [];
34634
35479
  const api = {
34635
35480
  step(s) {
@@ -34669,7 +35514,7 @@ function mindMap(preset) {
34669
35514
  const canvasW = preset.branchWidth ? preset.branchWidth * 2 : 720;
34670
35515
  const canvasH = 480;
34671
35516
  const diagramType = "mind";
34672
- const b = diagram(preset.id, { topic: preset.topic, type: diagramType });
35517
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: diagramType });
34673
35518
  const branches = [];
34674
35519
  const api = {
34675
35520
  branch(br) {
@@ -34713,7 +35558,7 @@ function mindMap(preset) {
34713
35558
  function funnel(preset) {
34714
35559
  const canvasW = toGridSize(preset.stageWidth ?? 560);
34715
35560
  const canvasH = 480;
34716
- const b = diagram(preset.id, { topic: preset.topic, type: "funnel" });
35561
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "funnel" });
34717
35562
  const stages = [];
34718
35563
  const api = {
34719
35564
  stage(s) {
@@ -34751,7 +35596,7 @@ function funnel(preset) {
34751
35596
  function quadrant(preset) {
34752
35597
  const canvasW = 640;
34753
35598
  const canvasH = 480;
34754
- const b = diagram(preset.id, { topic: preset.topic, type: "quadrant" });
35599
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "quadrant" });
34755
35600
  const items = [];
34756
35601
  const api = {
34757
35602
  item(it) {
@@ -34802,7 +35647,7 @@ function chart(preset) {
34802
35647
  const canvasH = toGridSize(
34803
35648
  preset.type === "pie" || preset.type === "gauge" || preset.type === "radial" || preset.type === "stat" || preset.type === "waffle" || preset.type === "stacked-bar" ? 320 : 360
34804
35649
  );
34805
- const b = diagram(preset.id, { topic: preset.topic, type: "chart" });
35650
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "chart" });
34806
35651
  const data = [];
34807
35652
  const kindMap = {
34808
35653
  line: "chart-line",
@@ -34852,7 +35697,7 @@ function gantt(preset) {
34852
35697
  const canvasW = preset.laneWidth ? preset.laneWidth * 2 : 720;
34853
35698
  const canvasH = 360;
34854
35699
  const tone = preset.defaultTone ?? "teal";
34855
- const b = diagram(preset.id, { topic: preset.topic, type: "gantt" });
35700
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "gantt" });
34856
35701
  const tasks = [];
34857
35702
  const api = {
34858
35703
  task(t) {
@@ -34920,7 +35765,7 @@ function flowchart(preset) {
34920
35765
  const laneW = preset.laneWidth ?? 380;
34921
35766
  const tone = preset.defaultTone ?? "accent";
34922
35767
  const \u7E26\u306B\u7A4D\u3080 = (preset.direction ?? "horizontal") === "vertical";
34923
- const b = diagram(preset.id, { topic: preset.topic, type: "flowchart" });
35768
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "flowchart" });
34924
35769
  const laneToId = /* @__PURE__ */ new Map();
34925
35770
  const laneStackCount = /* @__PURE__ */ new Map();
34926
35771
  if (\u7E26\u306B\u7A4D\u3080) {
@@ -34995,7 +35840,7 @@ var NET_KIND_LABEL = {
34995
35840
  function network(preset) {
34996
35841
  const laneW = preset.laneWidth ?? 320;
34997
35842
  const tone = preset.defaultTone ?? "info";
34998
- const b = diagram(preset.id, { topic: preset.topic, type: "network" });
35843
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "network" });
34999
35844
  const colLaneIds = /* @__PURE__ */ new Map();
35000
35845
  const phaseActivate = [];
35001
35846
  let edgeIdx = 0;
@@ -35046,7 +35891,7 @@ function stateMachine2(preset) {
35046
35891
  const laneW = boxLaneW(stateW);
35047
35892
  const tone = preset.defaultTone ?? "accent";
35048
35893
  const diagramType = "state";
35049
- const b = diagram(preset.id, { topic: preset.topic, type: diagramType });
35894
+ const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: diagramType });
35050
35895
  const stateOrder = /* @__PURE__ */ new Map();
35051
35896
  const phaseActivate = [];
35052
35897
  let transIdx = 0;
@@ -35125,6 +35970,6 @@ function slugify(s) {
35125
35970
  return s.toLowerCase().replace(/[^a-z0-9぀-ゟ゠-ヿ一-龯]+/g, "-").replace(/^-|-$/g, "");
35126
35971
  }
35127
35972
 
35128
- export { ARROW_ANGLE_MAX_DEG, ARROW_ENDPOINT_CENTER_TOL, CHAIN_MIN_CLEARANCE, CHAIN_SHIFT_MAX_ACCUMULATED, CHAIN_SHIFT_MAX_ITER, CLASS_RELATION_LOOK, CLEARANCE_LABEL_LABEL, CLEARANCE_LANE_LABEL, CLEARANCE_NODE_LABEL, CLEARANCE_PATH_LABEL, COLUMN_GAP_VARIANCE_TOL, CdlDiagramThumbnail, CdlDiagramView, DETOUR_GAP, DETOUR_SLOT_GAP, DIST_LABEL_PATH_MAX, DIST_LABEL_PATH_MIN, EDGE_HEADS, EDGE_HEAD_DEFAULT, EDGE_HEAD_FILLS, EDGE_HEAD_FILL_DEFAULT, EDGE_LABEL_TEXT, EDGE_REVEALS, EDGE_REVEAL_DEFAULT, EDGE_STUB_OUT, EDGE_STYLES, ER_CARDINALITY_HEAD, FAN_GAP, FONT_RENDER_TOLERANCE_WORLD, FSM_ACTION_MARK, LABEL_INIT_CLEARANCE, LABEL_INIT_CLEARANCE_DOTTED_FLOW, LABEL_SIZE_TOLERANCE_WORLD, LABEL_TO_PATH_CLEARANCE, LANE_BORDER_CLEARANCE_TOL, MARKER_GLOW_RADIUS, MIN_COLUMN_ALIGNMENT_TOLERANCE, MIN_ROW_ALIGNMENT_TOLERANCE, NEAR_COLLISION_DEFAULT_MIN, NEAR_COLLISION_POLICY, NODE_FRAME_SELECTOR, NODE_KINDS, PERF_BUDGET_TOTAL_MS, PERF_SLOWEST_SAMPLE, RELATION_FOCUSES, RELATION_FOCUS_DEFAULT, ROW_GAP_VARIANCE_TOL, SEQUENCE_MESSAGE_LOOK, SPEC_CLEARANCE_POLICY, STAGE_SVG_SELECTOR, TARGET_LABEL_PATH_DIST, TONES, WCAG_AA_LARGE, WCAG_AA_NORMAL, applyDerivedValues, assertNever, attachEventHandlers, batch, bboxClearance, bboxDiffWorld, cdlAdapter, chart, classDiagram, compile, computeEventBindingKey, computeFormulaKey, computeInputSignalKey, computeScrollProgress, computeScrollTriggerKey, computeStateValues, computeViewportScale, computed, countEdgeCrossings, countOrderCrossings, createFormulaComputeds, createInputSignals, createInteractiveSignalsAccessor, createScrollProgressHandle, createScrollProgressSignals, diagram, drawsFigureTitle, effect, er, evaluate as evaluateFormula, extractIdentifiers, flow, flowchart, funnel, gantt, hasInteractivePrimitives, infrastructure, inputDefaultValue, interpolate, isLargeText, labelInitClearance, layout, layoutWithValidation, mindMap, network, orderNodes, parseFormula, pointRectEdgeDistance, pointToSegmentDistance2 as pointToSegmentDistance, predictLabelBBoxWorld, predictNodeBBoxWorld, projectEdgeLabel, projectNode, projectPathSegment, pxToWorld, quadrant, rectRectClearance, rectRectOverlapArea, relatedFocusSet, rendersRows, requiredContrastRatio, requiredNearClearance, requiredRowsHeight, requiredRowsWidth, requiredSpecClearance, resolveEdgeLabelOverlapsWithChain, resolveEdgeLabelOverlapsWithChainAndPropagate, resolveLabelClearanceAfterPathPasses, resolveLang, resolveOverlapsWithChain, resolveTarget, resolveTargetAll, segmentsIntersect2 as segmentsIntersect, sequence, sequenceBoardMetrics, sequenceStepId, signal, stateMachine, stateMachine2, swimlane, topology, tree, untrack, userJourney, validate, verifyAllDiagramsDom, verifyAuthorIntent, verifyAuthorIntentAll, verifyDiagramDom, visualValidate, visualValidateAll, visualValidateLaid, withDerivedValues, worldToPx, 木の札の幅 };
35973
+ export { ARROW_ANGLE_MAX_DEG, ARROW_ENDPOINT_CENTER_TOL, CHAIN_MIN_CLEARANCE, CHAIN_SHIFT_MAX_ACCUMULATED, CHAIN_SHIFT_MAX_ITER, CLASS_RELATION_LOOK, CLEARANCE_LABEL_LABEL, CLEARANCE_LANE_LABEL, CLEARANCE_NODE_LABEL, CLEARANCE_PATH_LABEL, COLUMN_GAP_VARIANCE_TOL, CdlDiagramThumbnail, CdlDiagramView, DETOUR_GAP, DETOUR_SLOT_GAP, DIST_LABEL_PATH_MAX, DIST_LABEL_PATH_MIN, EDGE_HEADS, EDGE_HEAD_DEFAULT, EDGE_HEAD_FILLS, EDGE_HEAD_FILL_DEFAULT, EDGE_LABEL_TEXT, EDGE_REVEALS, EDGE_REVEAL_DEFAULT, EDGE_STUB_OUT, EDGE_STYLES, ER_CARDINALITY_HEAD, FAN_GAP, FONT_RENDER_TOLERANCE_WORLD, FSM_ACTION_MARK, LABEL_INIT_CLEARANCE, LABEL_INIT_CLEARANCE_DOTTED_FLOW, LABEL_SIZE_TOLERANCE_WORLD, LABEL_TO_PATH_CLEARANCE, LANE_BORDER_CLEARANCE_TOL, MARKER_GLOW_RADIUS, MIN_COLUMN_ALIGNMENT_TOLERANCE, MIN_ROW_ALIGNMENT_TOLERANCE, NEAR_COLLISION_DEFAULT_MIN, NEAR_COLLISION_POLICY, NODE_FRAME_SELECTOR, NODE_KINDS, PERF_BUDGET_TOTAL_MS, PERF_SLOWEST_SAMPLE, RELATION_FOCUSES, RELATION_FOCUS_DEFAULT, ROW_GAP_VARIANCE_TOL, SEQUENCE_MESSAGE_LOOK, SPEC_CLEARANCE_POLICY, STAGE_SVG_SELECTOR, TARGET_LABEL_PATH_DIST, TONES, WCAG_AA_LARGE, WCAG_AA_NORMAL, applyDerivedValues, assertNever, attachEventHandlers, batch, bboxClearance, bboxDiffWorld, cdlAdapter, chart, classDiagram, compile, computeEventBindingKey, computeFormulaKey, computeInputSignalKey, computeScrollProgress, computeScrollTriggerKey, computeStateValues, computeViewportScale, computed, countEdgeCrossings, countOrderCrossings, createFormulaComputeds, createInputSignals, createInteractiveSignalsAccessor, createScrollProgressHandle, createScrollProgressSignals, diagram, drawsFigureTitle, effect, er, evaluate as evaluateFormula, extractIdentifiers, flow, flowchart, funnel, gantt, hasInteractivePrimitives, infrastructure, inputDefaultValue, interpolate, isLargeText, labelInitClearance, layout, layoutWithValidation, mindMap, network, orderNodes, parseFormula, pointRectEdgeDistance, pointToSegmentDistance2 as pointToSegmentDistance, predictLabelBBoxWorld, predictNodeBBoxWorld, projectEdgeLabel, projectNode, projectPathSegment, pxToWorld, quadrant, rectRectClearance, rectRectOverlapArea, relatedFocusSet, rendersRows, requiredContrastRatio, requiredNearClearance, requiredRowsHeight, requiredRowsWidth, requiredSpecClearance, resolveEdgeLabelOverlapsWithChain, resolveEdgeLabelOverlapsWithChainAndPropagate, resolveLabelClearanceAfterPathPasses, resolveLang, resolveOverlapsWithChain, resolveTarget, resolveTargetAll, resolveTextMetrics, segmentsIntersect2 as segmentsIntersect, sequence, sequenceBoardMetrics, sequenceStepId, signal, stateMachine, stateMachine2, swimlane, topology, tree, untrack, userJourney, validate, verifyAllDiagramsDom, verifyAuthorIntent, verifyAuthorIntentAll, verifyDiagramDom, visualValidate, visualValidateAll, visualValidateLaid, withDerivedValues, worldToPx, 木の札の幅 };
35129
35974
  //# sourceMappingURL=index.js.map
35130
35975
  //# sourceMappingURL=index.js.map