@cardenelabs/dragon 0.13.0 → 0.14.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.
package/dist/index.cjs CHANGED
@@ -1754,6 +1754,135 @@ var \u90E8\u54C1\u306E\u7D44\u306E\u8868 = {
1754
1754
  }
1755
1755
  };
1756
1756
 
1757
+ // src/v05/input-table.generated.ts
1758
+ var \u3064\u307E\u307F\u306E\u8868 = {
1759
+ color: {
1760
+ \u5FC5\u9808: ["defaultValue"],
1761
+ \u6B04: {
1762
+ defaultValue: "\u6587\u5B57\u5217",
1763
+ label: "\u6587\u5B57\u5217"
1764
+ }
1765
+ },
1766
+ datetime: {
1767
+ \u5FC5\u9808: ["defaultValue"],
1768
+ \u6B04: {
1769
+ defaultValue: "\u6587\u5B57\u5217",
1770
+ label: "\u6587\u5B57\u5217"
1771
+ }
1772
+ },
1773
+ dropdown: {
1774
+ \u5FC5\u9808: ["options", "defaultValue"],
1775
+ \u6B04: {
1776
+ options: "\u6587\u5B57\u5217\u306E\u4E26\u3073",
1777
+ defaultValue: "\u6587\u5B57\u5217",
1778
+ label: "\u6587\u5B57\u5217"
1779
+ }
1780
+ },
1781
+ "multi-select": {
1782
+ \u5FC5\u9808: ["options", "defaultValues"],
1783
+ \u6B04: {
1784
+ options: "\u6587\u5B57\u5217\u306E\u4E26\u3073",
1785
+ defaultValues: "\u6587\u5B57\u5217\u306E\u4E26\u3073",
1786
+ label: "\u6587\u5B57\u5217"
1787
+ }
1788
+ },
1789
+ number: {
1790
+ \u5FC5\u9808: ["defaultValue"],
1791
+ \u6B04: {
1792
+ min: "\u6570",
1793
+ max: "\u6570",
1794
+ defaultValue: "\u6570",
1795
+ label: "\u6587\u5B57\u5217"
1796
+ }
1797
+ },
1798
+ radio: {
1799
+ \u5FC5\u9808: ["options", "defaultValue"],
1800
+ \u6B04: {
1801
+ options: "\u6587\u5B57\u5217\u306E\u4E26\u3073",
1802
+ defaultValue: "\u6587\u5B57\u5217",
1803
+ label: "\u6587\u5B57\u5217"
1804
+ }
1805
+ },
1806
+ range: {
1807
+ \u5FC5\u9808: ["min", "max", "defaultLo", "defaultHi"],
1808
+ \u6B04: {
1809
+ min: "\u6570",
1810
+ max: "\u6570",
1811
+ step: "\u6570",
1812
+ defaultLo: "\u6570",
1813
+ defaultHi: "\u6570",
1814
+ label: "\u6587\u5B57\u5217"
1815
+ }
1816
+ },
1817
+ slider: {
1818
+ \u5FC5\u9808: ["min", "max", "defaultValue"],
1819
+ \u6B04: {
1820
+ min: "\u6570",
1821
+ max: "\u6570",
1822
+ step: "\u6570",
1823
+ defaultValue: "\u6570",
1824
+ label: "\u6587\u5B57\u5217"
1825
+ }
1826
+ },
1827
+ stepper: {
1828
+ \u5FC5\u9808: ["defaultValue"],
1829
+ \u6B04: {
1830
+ min: "\u6570",
1831
+ max: "\u6570",
1832
+ step: "\u6570",
1833
+ defaultValue: "\u6570",
1834
+ label: "\u6587\u5B57\u5217"
1835
+ }
1836
+ },
1837
+ tabs: {
1838
+ \u5FC5\u9808: ["options", "defaultValue"],
1839
+ \u6B04: {
1840
+ options: "\u6587\u5B57\u5217\u306E\u4E26\u3073",
1841
+ defaultValue: "\u6587\u5B57\u5217",
1842
+ label: "\u6587\u5B57\u5217"
1843
+ }
1844
+ },
1845
+ text: {
1846
+ \u5FC5\u9808: ["defaultValue"],
1847
+ \u6B04: {
1848
+ defaultValue: "\u6587\u5B57\u5217",
1849
+ placeholder: "\u6587\u5B57\u5217",
1850
+ maxLength: "\u6570",
1851
+ label: "\u6587\u5B57\u5217"
1852
+ }
1853
+ },
1854
+ timeline: {
1855
+ \u5FC5\u9808: ["duration"],
1856
+ \u6B04: {
1857
+ duration: "\u6570",
1858
+ autoplay: "\u771F\u507D",
1859
+ loop: "\u771F\u507D",
1860
+ speeds: "\u6570\u306E\u4E26\u3073",
1861
+ defaultSpeedIdx: "\u6570",
1862
+ label: "\u6587\u5B57\u5217"
1863
+ }
1864
+ },
1865
+ toggle: {
1866
+ \u5FC5\u9808: ["defaultValue"],
1867
+ \u6B04: {
1868
+ defaultValue: "\u771F\u507D",
1869
+ label: "\u6587\u5B57\u5217"
1870
+ }
1871
+ },
1872
+ xypad: {
1873
+ \u5FC5\u9808: ["xMin", "xMax", "yMin", "yMax", "defaultX", "defaultY"],
1874
+ \u6B04: {
1875
+ xMin: "\u6570",
1876
+ xMax: "\u6570",
1877
+ yMin: "\u6570",
1878
+ yMax: "\u6570",
1879
+ defaultX: "\u6570",
1880
+ defaultY: "\u6570",
1881
+ label: "\u6587\u5B57\u5217"
1882
+ }
1883
+ }
1884
+ };
1885
+
1757
1886
  // src/v05/parser.ts
1758
1887
  var EDGE_SIDE_VALUES = ["top", "right", "bottom", "left"];
1759
1888
  var TOP_LEVEL_KEYS = [
@@ -1772,7 +1901,15 @@ var TOP_LEVEL_KEYS = [
1772
1901
  // 2 軸で仕分ける図の軸の名前 (#1251)
1773
1902
  "axes",
1774
1903
  // 値を見せる部品 (#1374)
1775
- "readouts"
1904
+ "readouts",
1905
+ // 読む人が動かすつまみ (#1389)
1906
+ "inputs",
1907
+ // つまみの値から決まる値 (#1391)
1908
+ "formulas",
1909
+ // 押下などの出来事で動く仕掛け (#1393)
1910
+ "events",
1911
+ // 巻き上げに応じて進む値 (#1393)
1912
+ "scrolls"
1776
1913
  ];
1777
1914
  var LANE_ID_ENTRY = /^([\p{L}\p{N}_-]+)\s*:\s*\{([^}]*)\}\s*$/u;
1778
1915
  function \u540D\u524D\u3068\u4E2D\u62EC\u5F27\u306B\u5272\u308B(\u884C) {
@@ -1810,6 +1947,39 @@ function \u540D\u524D\u3068\u4E2D\u62EC\u5F27\u306B\u5272\u308B(\u884C) {
1810
1947
  }
1811
1948
  return void 0;
1812
1949
  }
1950
+ function \u672B\u5C3E\u306E\u4E2D\u62EC\u5F27\u3092\u5207\u308A\u51FA\u3059(rest) {
1951
+ const t = rest.trimEnd();
1952
+ if (!t.endsWith("}")) return void 0;
1953
+ let \u6DF1\u3055 = 0;
1954
+ let \u5F15\u7528 = null;
1955
+ let \u76F4\u524D = null;
1956
+ let \u59CB = -1;
1957
+ for (let i = 0; i < t.length; i += 1) {
1958
+ const c = t[i];
1959
+ if (\u5F15\u7528 !== null) {
1960
+ if (\u5F15\u7528 === '"' && c === "\\" && i + 1 < t.length) {
1961
+ i += 1;
1962
+ continue;
1963
+ }
1964
+ if (c === \u5F15\u7528) \u5F15\u7528 = null;
1965
+ continue;
1966
+ }
1967
+ if ((c === '"' || c === "'") && (\u76F4\u524D === null || ":,{[".includes(\u76F4\u524D))) {
1968
+ \u5F15\u7528 = c;
1969
+ \u76F4\u524D = c;
1970
+ continue;
1971
+ }
1972
+ if (c === "{") {
1973
+ if (\u6DF1\u3055 === 0) \u59CB = i;
1974
+ \u6DF1\u3055 += 1;
1975
+ } else if (c === "}") {
1976
+ \u6DF1\u3055 -= 1;
1977
+ if (\u6DF1\u3055 === 0 && i === t.length - 1) return { \u524D: t.slice(0, \u59CB), \u4E2D\u8EAB: t.slice(\u59CB + 1, i) };
1978
+ }
1979
+ if (!/\s/u.test(c)) \u76F4\u524D = c;
1980
+ }
1981
+ return void 0;
1982
+ }
1813
1983
  function isTopLevelKey(key) {
1814
1984
  return TOP_LEVEL_KEYS.includes(key);
1815
1985
  }
@@ -1903,6 +2073,11 @@ function parseTextDslV05(src) {
1903
2073
  let viewport = void 0;
1904
2074
  let lanesMap = void 0;
1905
2075
  let readoutsList = void 0;
2076
+ let inputsList = void 0;
2077
+ let formulasList = void 0;
2078
+ let eventsList = void 0;
2079
+ let scrollsList = void 0;
2080
+ let scrollLines = /* @__PURE__ */ new Map();
1906
2081
  let groupsMap = void 0;
1907
2082
  let i = 0;
1908
2083
  while (i < lines.length) {
@@ -2162,6 +2337,112 @@ function parseTextDslV05(src) {
2162
2337
  i = next;
2163
2338
  continue;
2164
2339
  }
2340
+ if (head.key === "inputs") {
2341
+ if (head.value !== null && head.value.trim() !== "") {
2342
+ errors.push({
2343
+ line: line.no,
2344
+ message: "inputs \u306F 1 \u884C\u306B\u307E\u3068\u3081\u3066\u66F8\u3051\u306A\u3044",
2345
+ hint: "\u6B21\u306E\u884C\u304B\u3089\u5B57\u4E0B\u3052\u3057\u3066 `value: { kind: slider, min: 0, max: 100, defaultValue: 50 }` \u306E\u5F62\u3067\u4E26\u3079\u308B"
2346
+ });
2347
+ i += 1;
2348
+ continue;
2349
+ }
2350
+ const { items, next } = collectIndentedRaw(lines, i + 1, line.indent);
2351
+ inputsList = [];
2352
+ for (const it of items) {
2353
+ const m = \u540D\u524D\u3068\u4E2D\u62EC\u5F27\u306B\u5272\u308B(it.trimmed);
2354
+ if (m) {
2355
+ const \u8AAD\u3081\u305F = \u3064\u307E\u307F\u3068\u3057\u3066\u8AAD\u3080(m[0], m[1], it.no, errors);
2356
+ if (\u8AAD\u3081\u305F) inputsList.push(\u8AAD\u3081\u305F);
2357
+ } else {
2358
+ errors.push({
2359
+ line: it.no,
2360
+ message: `invalid input entry: "${it.trimmed}"`,
2361
+ hint: "use `id: { kind: slider, min: 0, max: 100, defaultValue: 50 }`"
2362
+ });
2363
+ }
2364
+ }
2365
+ i = next;
2366
+ continue;
2367
+ }
2368
+ if (head.key === "formulas") {
2369
+ if (head.value !== null && head.value.trim() !== "") {
2370
+ errors.push({
2371
+ line: line.no,
2372
+ message: "formulas \u306F 1 \u884C\u306B\u307E\u3068\u3081\u3066\u66F8\u3051\u306A\u3044",
2373
+ hint: '\u5F0F\u306B `,` \u304C\u5165\u308B\u305F\u3081\u3002 \u6B21\u306E\u884C\u304B\u3089\u5B57\u4E0B\u3052\u3057\u3066 `doubled: "input * 2"` \u306E\u5F62\u3067\u4E26\u3079\u308B'
2374
+ });
2375
+ i += 1;
2376
+ continue;
2377
+ }
2378
+ const { items, next } = collectIndentedRaw(lines, i + 1, line.indent);
2379
+ formulasList = [];
2380
+ for (const it of items) {
2381
+ const f = \u5F0F\u3068\u3057\u3066\u8AAD\u3080(it.trimmed.replace(/^-\s*/, ""), it.no, errors);
2382
+ if (f) formulasList.push(f);
2383
+ }
2384
+ i = next;
2385
+ continue;
2386
+ }
2387
+ if (head.key === "events") {
2388
+ if (head.value !== null && head.value.trim() !== "") {
2389
+ errors.push({
2390
+ line: line.no,
2391
+ message: "events \u306F 1 \u884C\u306B\u307E\u3068\u3081\u3066\u66F8\u3051\u306A\u3044",
2392
+ hint: "\u6B21\u306E\u884C\u304B\u3089\u5B57\u4E0B\u3052\u3057\u3066 `- { on: click, box: Button, handler: toggle }` \u306E\u5F62\u3067\u4E26\u3079\u308B"
2393
+ });
2394
+ i += 1;
2395
+ continue;
2396
+ }
2397
+ const { items, next } = collectIndentedRaw(lines, i + 1, line.indent);
2398
+ eventsList = [];
2399
+ for (const it of items) {
2400
+ const e = \u51FA\u6765\u4E8B\u3068\u3057\u3066\u8AAD\u3080(it.trimmed.replace(/^-\s*/, ""), it.no, errors);
2401
+ if (e) eventsList.push(e);
2402
+ }
2403
+ i = next;
2404
+ continue;
2405
+ }
2406
+ if (head.key === "scrolls") {
2407
+ if (head.value !== null && head.value.trim() !== "") {
2408
+ errors.push({
2409
+ line: line.no,
2410
+ message: "scrolls \u306F 1 \u884C\u306B\u307E\u3068\u3081\u3066\u66F8\u3051\u306A\u3044",
2411
+ hint: "\u6B21\u306E\u884C\u304B\u3089\u5B57\u4E0B\u3052\u3057\u3066 `intro: { start: 0.9, end: 0.1 }` \u306E\u5F62\u3067\u4E26\u3079\u308B"
2412
+ });
2413
+ i += 1;
2414
+ continue;
2415
+ }
2416
+ const { items, next } = collectIndentedRaw(lines, i + 1, line.indent);
2417
+ scrollsList = [];
2418
+ scrollLines = /* @__PURE__ */ new Map();
2419
+ for (const it of items) {
2420
+ const m = \u540D\u524D\u3068\u4E2D\u62EC\u5F27\u306B\u5272\u308B(it.trimmed);
2421
+ if (m) {
2422
+ const \u8AAD\u3081\u305F = \u5DFB\u304D\u4E0A\u3052\u3068\u3057\u3066\u8AAD\u3080(m[0], m[1], it.no, errors);
2423
+ if (\u8AAD\u3081\u305F) {
2424
+ if (scrollLines.has(\u8AAD\u3081\u305F.id)) {
2425
+ errors.push({
2426
+ line: it.no,
2427
+ message: `\u5DFB\u304D\u4E0A\u3052\u306E\u540D\u524D "${\u8AAD\u3081\u305F.id}" \u304C\u91CD\u8907\u3057\u3066\u3044\u307E\u3059`,
2428
+ hint: "scrolls \u306E\u540D\u524D\u306F 1 \u5EA6\u3060\u3051\u66F8\u304F"
2429
+ });
2430
+ } else {
2431
+ scrollsList.push(\u8AAD\u3081\u305F);
2432
+ scrollLines.set(\u8AAD\u3081\u305F.id, it.no);
2433
+ }
2434
+ }
2435
+ } else {
2436
+ errors.push({
2437
+ line: it.no,
2438
+ message: `invalid scroll entry: "${it.trimmed}"`,
2439
+ hint: "use `id: { start: 0.9, end: 0.1, scrub: 1 }`"
2440
+ });
2441
+ }
2442
+ }
2443
+ i = next;
2444
+ continue;
2445
+ }
2165
2446
  if (head.key === "groups") {
2166
2447
  const { items, next } = collectIndentedList(lines, i + 1, line.indent);
2167
2448
  groupsMap = {};
@@ -2198,6 +2479,18 @@ function parseTextDslV05(src) {
2198
2479
  message: "type is required",
2199
2480
  hint: "add `type: sequence|flow|swimlane|er|state|topology|solidity|gantt|class|pie|c4|mind`"
2200
2481
  });
2482
+ const \u65E2\u306B\u5024\u3092\u4F5C\u308B\u540D\u524D = /* @__PURE__ */ new Set([
2483
+ ...(inputsList ?? []).map((input) => input.id),
2484
+ ...(formulasList ?? []).map((formula) => formula.id)
2485
+ ]);
2486
+ for (const scroll of scrollsList ?? []) {
2487
+ if (!\u65E2\u306B\u5024\u3092\u4F5C\u308B\u540D\u524D.has(scroll.id)) continue;
2488
+ errors.push({
2489
+ line: scrollLines.get(scroll.id) ?? 1,
2490
+ message: `\u5DFB\u304D\u4E0A\u3052\u306E\u540D\u524D "${scroll.id}" \u304C inputs \u307E\u305F\u306F formulas \u3068\u91CD\u306A\u3063\u3066\u3044\u307E\u3059`,
2491
+ hint: "inputs / formulas / scrolls \u3067\u306F\u91CD\u306A\u3089\u306A\u3044\u540D\u524D\u3092\u4F7F\u3046"
2492
+ });
2493
+ }
2201
2494
  if (errors.length > 0) return { ok: false, errors };
2202
2495
  return {
2203
2496
  ok: true,
@@ -2213,6 +2506,10 @@ function parseTextDslV05(src) {
2213
2506
  viewport,
2214
2507
  lanes: lanesMap,
2215
2508
  readouts: readoutsList,
2509
+ inputs: inputsList,
2510
+ formulas: formulasList,
2511
+ events: eventsList,
2512
+ scrolls: scrollsList,
2216
2513
  groups: groupsMap,
2217
2514
  pos: { line: 1 }
2218
2515
  }
@@ -2565,6 +2862,18 @@ function \u8868\u306B\u5F93\u3063\u3066\u8AAD\u3080(\u5B9A\u7FA9, opts, \u63A5\u
2565
2862
  out[\u6B04] = n !== void 0 ? n : \u5024;
2566
2863
  } else if (\u5F62 === "\u6587\u5B57\u5217\u306E\u4E26\u3073") {
2567
2864
  out[\u6B04] = \u4E26\u3073\u3068\u3057\u3066\u8AAD\u3080(\u5024);
2865
+ } else if (\u5F62 === "\u6570\u306E\u4E26\u3073") {
2866
+ const \u751F = \u4E26\u3073\u3068\u3057\u3066\u8AAD\u3080(\u5024);
2867
+ const \u6570 = \u751F.map((x) => numberOrUndef(x));
2868
+ if (\u6570.some((n) => n === void 0)) {
2869
+ errors.push({
2870
+ line,
2871
+ message: `${\u63A5\u982D}${\u6B04} \u306B\u6570\u3067\u306A\u3044\u5024\u304C\u3042\u308A\u307E\u3059: "${\u5024}"`,
2872
+ hint: "`[0.5, 1, 2, 4]` \u306E\u5F62\u3067\u6570\u3060\u3051\u3092\u4E26\u3079\u308B"
2873
+ });
2874
+ } else {
2875
+ out[\u6B04] = \u6570;
2876
+ }
2568
2877
  } else if (\u5F62 === "\u7D44\u306E\u4E26\u3073") {
2569
2878
  const \u7D44 = \u7D44\u306E\u4E26\u3073\u3068\u3057\u3066\u8AAD\u3080(\u5024);
2570
2879
  if (\u7D44 !== void 0) out[\u6B04] = \u7D44;
@@ -2621,11 +2930,49 @@ function \u51FA\u3059\u6761\u4EF6\u3068\u3057\u3066\u8AAD\u3080(raw, line, error
2621
2930
  }
2622
2931
  return \u5024;
2623
2932
  }
2933
+ function \u5024\u306B\u8FFD\u968F\u3059\u308B\u6B04\u3068\u3057\u3066\u8AAD\u3080(raw, \u63A5\u982D, line, errors) {
2934
+ if (raw === void 0) return void 0;
2935
+ const \u5024 = raw.trim();
2936
+ if (\u5024 === "") {
2937
+ errors.push({
2938
+ line,
2939
+ message: `${\u63A5\u982D}\u304C\u7A7A\u3067\u3059`,
2940
+ hint: '`{\u72B6\u614B\u306E\u540D\u524D}` \u304B\u6570\u3092\u66F8\u304F (\u4F8B `opacity: "{fade}"` / `opacity: 0.5`)'
2941
+ });
2942
+ return void 0;
2943
+ }
2944
+ const n = numberOrUndef(\u5024);
2945
+ return n !== void 0 ? n : \u5024;
2946
+ }
2947
+ function \u8FFD\u968F\u3059\u308B\u5927\u304D\u3055\u3068\u3057\u3066\u8AAD\u3080(raw, \u63A5\u982D, line, errors) {
2948
+ if (raw === void 0) return void 0;
2949
+ const \u5024 = raw.trim();
2950
+ if (\u5024 === "") {
2951
+ errors.push({
2952
+ line,
2953
+ message: `${\u63A5\u982D}\u304C\u7A7A\u3067\u3059`,
2954
+ hint: '`{\u72B6\u614B\u306E\u540D\u524D}` \u3092\u66F8\u304F (\u4F8B `wBind: "{barW}"`)'
2955
+ });
2956
+ return void 0;
2957
+ }
2958
+ return \u5024;
2959
+ }
2960
+ var \u5024\u306B\u8FFD\u968F\u3059\u308B\u7BB1\u306E\u6B04 = [
2961
+ "wBind",
2962
+ "hBind",
2963
+ "opacity",
2964
+ "renderOffsetX",
2965
+ "renderOffsetY"
2966
+ ];
2967
+ var \u7A7A\u3092\u77E5\u3089\u305B\u308B\u7BB1\u306E\u6B04 = new Set(\u5024\u306B\u8FFD\u968F\u3059\u308B\u7BB1\u306E\u6B04);
2968
+ function \u8868\u304B\u3089\u5B9A\u7FA9\u3092\u5F15\u304F(\u8868, kind) {
2969
+ return Object.hasOwn(\u8868, kind) ? \u8868[kind] : void 0;
2970
+ }
2624
2971
  function \u56F3\u5F62\u3068\u3057\u3066\u8AAD\u3080(raw, line, errors) {
2625
2972
  const \u4E2D\u8EAB = raw.trim().replace(/^\{|\}$/g, "");
2626
2973
  const opts = parseInlineMapping(\u4E2D\u8EAB);
2627
2974
  const kind = (opts.kind ?? "").toLowerCase();
2628
- const \u5B9A\u7FA9 = \u56F3\u5F62\u306E\u8868[kind];
2975
+ const \u5B9A\u7FA9 = \u8868\u304B\u3089\u5B9A\u7FA9\u3092\u5F15\u304F(\u56F3\u5F62\u306E\u8868, kind);
2629
2976
  if (\u5B9A\u7FA9 === void 0) {
2630
2977
  errors.push({
2631
2978
  line,
@@ -2641,7 +2988,7 @@ function \u56F3\u5F62\u3068\u3057\u3066\u8AAD\u3080(raw, line, errors) {
2641
2988
  function \u90E8\u54C1\u3068\u3057\u3066\u8AAD\u3080(id, raw, line, errors) {
2642
2989
  const opts = parseInlineMapping(raw);
2643
2990
  const kind = (opts.kind ?? "").toLowerCase();
2644
- const \u5B9A\u7FA9 = \u90E8\u54C1\u306E\u8868[kind];
2991
+ const \u5B9A\u7FA9 = \u8868\u304B\u3089\u5B9A\u7FA9\u3092\u5F15\u304F(\u90E8\u54C1\u306E\u8868, kind);
2645
2992
  if (\u5B9A\u7FA9 === void 0) {
2646
2993
  errors.push({
2647
2994
  line,
@@ -2655,6 +3002,194 @@ function \u90E8\u54C1\u3068\u3057\u3066\u8AAD\u3080(id, raw, line, errors) {
2655
3002
  for (const \u6B04 of \u5B9A\u7FA9.\u5FC5\u9808) if (\u8AAD\u3081\u305F[\u6B04] === void 0) return void 0;
2656
3003
  return { id, kind, ...\u8AAD\u3081\u305F };
2657
3004
  }
3005
+ var EVENT_KINDS = [
3006
+ "click",
3007
+ "hover",
3008
+ "double-click",
3009
+ "long-press",
3010
+ "drag",
3011
+ "drop",
3012
+ "keydown",
3013
+ "focus",
3014
+ "blur"
3015
+ ];
3016
+ var EVENT_TARGET_KEYS = ["box", "lane", "arrow", "diagram"];
3017
+ function \u51FA\u6765\u4E8B\u3068\u3057\u3066\u8AAD\u3080(raw, line, errors) {
3018
+ const t = raw.trim();
3019
+ if (!t.startsWith("{") || !t.endsWith("}")) {
3020
+ errors.push({
3021
+ line,
3022
+ message: `\u51FA\u6765\u4E8B\u306E\u884C\u304C\u8AAD\u3081\u307E\u305B\u3093: "${t}"`,
3023
+ hint: "`- { on: click, box: Button, handler: toggle }` \u306E\u5F62\u3067\u66F8\u304F"
3024
+ });
3025
+ return void 0;
3026
+ }
3027
+ const opts = parseInlineMapping(t.slice(1, -1));
3028
+ for (const k of Object.keys(opts)) {
3029
+ if (k === "on" || k === "handler" || EVENT_TARGET_KEYS.includes(k))
3030
+ continue;
3031
+ errors.push({
3032
+ line,
3033
+ message: `\u51FA\u6765\u4E8B\u306E\u9805\u76EE\u540D\u304C\u8AAD\u3081\u307E\u305B\u3093: "${k}"`,
3034
+ hint: `\u4F7F\u3048\u308B\u9805\u76EE = on, handler, ${EVENT_TARGET_KEYS.join(", ")}`
3035
+ });
3036
+ return void 0;
3037
+ }
3038
+ const on = opts.on ?? "";
3039
+ if (!EVENT_KINDS.includes(on)) {
3040
+ errors.push({
3041
+ line,
3042
+ message: `\u51FA\u6765\u4E8B\u306E\u7A2E\u985E\u304C\u8AAD\u3081\u307E\u305B\u3093: "${on}"`,
3043
+ hint: `\u4F7F\u3048\u308B\u7A2E\u985E = ${EVENT_KINDS.join(", ")}`
3044
+ });
3045
+ return void 0;
3046
+ }
3047
+ const handlerId = (opts.handler ?? "").trim();
3048
+ if (handlerId === "") {
3049
+ errors.push({
3050
+ line,
3051
+ message: "\u51FA\u6765\u4E8B\u306E handler \u304C\u7A7A\u3067\u3059",
3052
+ hint: "`handler: toggle-active` \u306E\u3088\u3046\u306B\u3001\u547C\u3073\u51FA\u3059\u4ED5\u639B\u3051\u306E\u540D\u524D\u3092\u66F8\u304F"
3053
+ });
3054
+ return void 0;
3055
+ }
3056
+ const \u66F8\u3044\u305F\u76F8\u624B = EVENT_TARGET_KEYS.filter((k) => opts[k] !== void 0);
3057
+ if (\u66F8\u3044\u305F\u76F8\u624B.length !== 1) {
3058
+ errors.push({
3059
+ line,
3060
+ message: \u66F8\u3044\u305F\u76F8\u624B.length === 0 ? "\u51FA\u6765\u4E8B\u306E\u76F8\u624B\u304C\u66F8\u304B\u308C\u3066\u3044\u307E\u305B\u3093" : `\u51FA\u6765\u4E8B\u306E\u76F8\u624B\u3092 2 \u3064\u4EE5\u4E0A\u66F8\u3044\u3066\u3044\u307E\u3059: ${\u66F8\u3044\u305F\u76F8\u624B.join(", ")}`,
3061
+ hint: `${EVENT_TARGET_KEYS.join(" / ")} \u306E\u3069\u308C\u304B 1 \u3064\u3060\u3051\u3092\u66F8\u304F`
3062
+ });
3063
+ return void 0;
3064
+ }
3065
+ const \u9375 = \u66F8\u3044\u305F\u76F8\u624B[0];
3066
+ const \u5024 = (opts[\u9375] ?? "").trim();
3067
+ let target;
3068
+ if (\u9375 === "diagram") {
3069
+ if (\u5024 !== "true") {
3070
+ errors.push({
3071
+ line,
3072
+ message: `\u51FA\u6765\u4E8B\u306E diagram \u304C\u8AAD\u3081\u307E\u305B\u3093: "${\u5024}"`,
3073
+ hint: "\u56F3\u5168\u4F53\u3092\u6307\u3059\u6642\u306F `diagram: true` \u3068\u66F8\u304F"
3074
+ });
3075
+ return void 0;
3076
+ }
3077
+ target = { kind: "diagram" };
3078
+ } else if (\u9375 === "arrow") {
3079
+ const m = \u5024.split("->");
3080
+ if (m.length !== 2 || m[0].trim() === "" || m[1].trim() === "") {
3081
+ errors.push({
3082
+ line,
3083
+ message: `\u51FA\u6765\u4E8B\u306E\u77E2\u5370\u304C\u8AAD\u3081\u307E\u305B\u3093: "${\u5024}"`,
3084
+ hint: "`arrow: A -> B` \u306E\u5F62\u3067\u3001\u77E2\u5370\u306E\u4E21\u7AEF\u306E\u540D\u524D\u3092\u66F8\u304F"
3085
+ });
3086
+ return void 0;
3087
+ }
3088
+ target = { kind: "edge", from: stripQuotes(m[0].trim()), to: stripQuotes(m[1].trim()) };
3089
+ } else {
3090
+ if (\u5024 === "") {
3091
+ errors.push({
3092
+ line,
3093
+ message: `\u51FA\u6765\u4E8B\u306E ${\u9375} \u304C\u7A7A\u3067\u3059`,
3094
+ hint: "\u6307\u3059\u76F8\u624B\u306E\u540D\u524D\u3092\u66F8\u304F"
3095
+ });
3096
+ return void 0;
3097
+ }
3098
+ target = { kind: \u9375 === "box" ? "node" : "lane", name: stripQuotes(\u5024) };
3099
+ }
3100
+ return { event: on, target, handlerId, pos: { line } };
3101
+ }
3102
+ var SCROLL_VALUE_KINDS = {
3103
+ start: "\u6570",
3104
+ end: "\u6570",
3105
+ scrub: "\u6570"
3106
+ };
3107
+ function \u5DFB\u304D\u4E0A\u3052\u3068\u3057\u3066\u8AAD\u3080(id, raw, line, errors) {
3108
+ if (!isValueName(id)) {
3109
+ errors.push({ line, ...valueNameIssue(id) });
3110
+ return void 0;
3111
+ }
3112
+ const opts = parseInlineMapping(raw);
3113
+ const \u4F7F\u3048\u308B = [...Object.keys(SCROLL_VALUE_KINDS), "label"];
3114
+ for (const k of Object.keys(opts)) {
3115
+ if (\u4F7F\u3048\u308B.includes(k)) continue;
3116
+ errors.push({
3117
+ line,
3118
+ message: `\u5DFB\u304D\u4E0A\u3052 ${id} \u306E\u9805\u76EE\u540D\u304C\u8AAD\u3081\u307E\u305B\u3093: "${k}"`,
3119
+ hint: `\u4F7F\u3048\u308B\u9805\u76EE = ${\u4F7F\u3048\u308B.join(", ")}`
3120
+ });
3121
+ return void 0;
3122
+ }
3123
+ const \u6570 = \u8868\u3067\u8AAD\u3080(SCROLL_VALUE_KINDS, opts, `\u5DFB\u304D\u4E0A\u3052 ${id} \u306E `, line, errors);
3124
+ for (const \u6B04 of ["start", "end", "scrub"]) {
3125
+ const \u5024 = \u6570[\u6B04];
3126
+ if (\u5024 === void 0 || \u5024 >= 0 && \u5024 <= 1) continue;
3127
+ errors.push({
3128
+ line,
3129
+ message: `\u5DFB\u304D\u4E0A\u3052 ${id} \u306E ${\u6B04} \u306F 0 \u304B\u3089 1 \u306E\u9593\u3067\u66F8\u304D\u307E\u3059: "${\u5024}"`,
3130
+ hint: "0 \u306F\u753B\u9762\u306E\u4E0A\u7AEF\u307E\u305F\u306F\u6BB5\u968E\u7684\u306A\u8FFD\u968F\u30011 \u306F\u4E0B\u7AEF\u307E\u305F\u306F\u9023\u7D9A\u8FFD\u968F"
3131
+ });
3132
+ }
3133
+ return {
3134
+ id,
3135
+ ...\u6570.start !== void 0 ? { start: \u6570.start } : {},
3136
+ ...\u6570.end !== void 0 ? { end: \u6570.end } : {},
3137
+ ...\u6570.scrub !== void 0 ? { scrub: \u6570.scrub } : {},
3138
+ ...opts.label !== void 0 ? { label: opts.label } : {}
3139
+ };
3140
+ }
3141
+ function \u5F0F\u3068\u3057\u3066\u8AAD\u3080(\u884C, line, errors) {
3142
+ const c = \u884C.indexOf(":");
3143
+ if (c < 0) {
3144
+ errors.push({
3145
+ line,
3146
+ message: `\u5F0F\u306E\u884C\u304C\u8AAD\u3081\u307E\u305B\u3093: "${\u884C}"`,
3147
+ hint: '`\u540D\u524D: "\u5F0F"` \u306E\u5F62\u3067\u66F8\u304F (\u4F8B `doubled: "input * 2"`)'
3148
+ });
3149
+ return void 0;
3150
+ }
3151
+ const \u540D\u524D = \u884C.slice(0, c).trim();
3152
+ const \u5F0F = stripQuotes(\u884C.slice(c + 1).trim());
3153
+ if (!isValueName(\u540D\u524D)) {
3154
+ errors.push({ line, ...valueNameIssue(\u540D\u524D) });
3155
+ return void 0;
3156
+ }
3157
+ if (\u5F0F === "") {
3158
+ errors.push({
3159
+ line,
3160
+ message: `\u5F0F "${\u540D\u524D}" \u304C\u7A7A\u3067\u3059`,
3161
+ hint: '`doubled: "input * 2"` \u306E\u3088\u3046\u306B\u5F0F\u3092\u66F8\u304F'
3162
+ });
3163
+ return void 0;
3164
+ }
3165
+ try {
3166
+ cdl.parseFormula(\u5F0F);
3167
+ } catch (e) {
3168
+ errors.push({
3169
+ line,
3170
+ message: `\u5F0F "${\u540D\u524D}" \u3092\u8AAD\u3081\u307E\u305B\u3093: ${e.message}`,
3171
+ hint: "\u4F7F\u3048\u308B\u306E\u306F\u56DB\u5247\u3068\u62EC\u5F27\u3001\u6BD4\u8F03\u3001\u4E09\u9805 (`a > 1 ? 2 : 3`)\u3001`Math.min` \u306A\u3069\u306E\u95A2\u6570"
3172
+ });
3173
+ return void 0;
3174
+ }
3175
+ return { id: \u540D\u524D, expression: \u5F0F, pos: { line } };
3176
+ }
3177
+ function \u3064\u307E\u307F\u3068\u3057\u3066\u8AAD\u3080(id, raw, line, errors) {
3178
+ const opts = parseInlineMapping(raw);
3179
+ const kind = (opts.kind ?? "").toLowerCase();
3180
+ const \u5B9A\u7FA9 = \u8868\u304B\u3089\u5B9A\u7FA9\u3092\u5F15\u304F(\u3064\u307E\u307F\u306E\u8868, kind);
3181
+ if (\u5B9A\u7FA9 === void 0) {
3182
+ errors.push({
3183
+ line,
3184
+ message: `\u3064\u307E\u307F\u306E\u7A2E\u985E\u304C\u8AAD\u3081\u307E\u305B\u3093: "${opts.kind ?? ""}"`,
3185
+ hint: `\u4F7F\u3048\u308B\u7A2E\u985E = ${Object.keys(\u3064\u307E\u307F\u306E\u8868).join(", ")}`
3186
+ });
3187
+ return void 0;
3188
+ }
3189
+ const \u8AAD\u3081\u305F = \u8868\u306B\u5F93\u3063\u3066\u8AAD\u3080(\u5B9A\u7FA9, opts, `\u3064\u307E\u307F ${id} \u306E `, line, errors);
3190
+ for (const \u6B04 of \u5B9A\u7FA9.\u5FC5\u9808) if (\u8AAD\u3081\u305F[\u6B04] === void 0) return void 0;
3191
+ return { id, kind, ...\u8AAD\u3081\u305F };
3192
+ }
2658
3193
  var ACTOR_NODE_VALUE_KINDS = {
2659
3194
  posX: "\u6570",
2660
3195
  posY: "\u6570",
@@ -2854,6 +3389,7 @@ function applyContinuationLines(actor, rest, errors) {
2854
3389
  const scaleLines = /* @__PURE__ */ new Map();
2855
3390
  const \u56F3\u7A2E\u3054\u3068\u306E\u6B04 = /* @__PURE__ */ new Map();
2856
3391
  const unknownKeys = [];
3392
+ const \u8FFD\u968F\u3059\u308B\u6B04\u306E\u751F\u5024 = /* @__PURE__ */ new Map();
2857
3393
  for (const ln of rest) {
2858
3394
  const idx = ln.trimmed.indexOf(":");
2859
3395
  if (idx < 0) continue;
@@ -2866,7 +3402,7 @@ function applyContinuationLines(actor, rest, errors) {
2866
3402
  unknownKeys.push({ key, line: ln.no });
2867
3403
  continue;
2868
3404
  }
2869
- if (!raw) continue;
3405
+ if (!raw && !\u7A7A\u3092\u77E5\u3089\u305B\u308B\u7BB1\u306E\u6B04.has(key)) continue;
2870
3406
  if (COLOR_KEYS.has(key)) {
2871
3407
  const { tone, hex } = splitColorValue(raw);
2872
3408
  if (tone) out.tone = tone;
@@ -2905,6 +3441,23 @@ function applyContinuationLines(actor, rest, errors) {
2905
3441
  case "\u984C":
2906
3442
  out.title = stripQuotes(raw);
2907
3443
  break;
3444
+ /*
3445
+ * 値に追随する 5 欄 (#1392)。 日本語の別名は置かない = 描画側の欄名がそのまま
3446
+ * 状態の名前と並ぶ場所なので、英字 1 種に絞って書き方の揺れを作らない。
3447
+ *
3448
+ * **ここでは読まずに書かれた字だけを控える**。 見本 (parts) では同じ名前が状態の
3449
+ * 上書きになり、中括弧の形は生の字を `coerceStateValue` に通す。 ここで先に読むと
3450
+ * `wBind: 120` が中括弧では数、縦に並べると文字列になって書き方で割れる。
3451
+ * 見本かどうかは `kind` で決まり、それが後ろの行に書かれることがあるため、
3452
+ * 全行を読み終えてから振り分ける。
3453
+ */
3454
+ case "wBind":
3455
+ case "hBind":
3456
+ case "opacity":
3457
+ case "renderOffsetX":
3458
+ case "renderOffsetY":
3459
+ \u8FFD\u968F\u3059\u308B\u6B04\u306E\u751F\u5024.set(key, { \u5024: stripQuotes(raw), line: ln.no });
3460
+ break;
2908
3461
  case "rows":
2909
3462
  case "\u884C":
2910
3463
  out.rows = raw.replace(/^\[|\]$/g, "").split(/,(?![^[]*\])/).map((x) => stripQuotes(x.trim())).filter(Boolean);
@@ -2992,9 +3545,20 @@ function applyContinuationLines(actor, rest, errors) {
2992
3545
  else out.end = v;
2993
3546
  }
2994
3547
  if (out.partId !== void 0) {
3548
+ for (const [\u6B04, { \u5024 }] of \u8FFD\u968F\u3059\u308B\u6B04\u306E\u751F\u5024) {
3549
+ state[\u6B04] = coerceStateValue(\u5024);
3550
+ touchedState = true;
3551
+ }
2995
3552
  if (touchedState) out.stateOverride = state;
2996
3553
  return out;
2997
3554
  }
3555
+ for (const [\u6B04, { \u5024, line }] of \u8FFD\u968F\u3059\u308B\u6B04\u306E\u751F\u5024) {
3556
+ if (\u6B04 === "wBind" || \u6B04 === "hBind") {
3557
+ out[\u6B04] = \u8FFD\u968F\u3059\u308B\u5927\u304D\u3055\u3068\u3057\u3066\u8AAD\u3080(\u5024, `\u7BB1\u306E ${\u6B04} `, line, errors);
3558
+ } else if (\u6B04 === "opacity" || \u6B04 === "renderOffsetX" || \u6B04 === "renderOffsetY") {
3559
+ out[\u6B04] = \u5024\u306B\u8FFD\u968F\u3059\u308B\u6B04\u3068\u3057\u3066\u8AAD\u3080(\u5024, `\u7BB1\u306E ${\u6B04} `, line, errors);
3560
+ }
3561
+ }
2998
3562
  for (const u of unknownKeys) {
2999
3563
  errors.push({
3000
3564
  line: u.line,
@@ -3023,6 +3587,12 @@ var ACTOR_ITEM_KEYS = /* @__PURE__ */ new Set([
3023
3587
  // 箱に出す題 (#1381)
3024
3588
  "title",
3025
3589
  "\u984C",
3590
+ // 値に追随する 5 欄 (#1392)
3591
+ "wBind",
3592
+ "hBind",
3593
+ "opacity",
3594
+ "renderOffsetX",
3595
+ "renderOffsetY",
3026
3596
  "\u4F4D\u7F6E",
3027
3597
  "pos",
3028
3598
  "posX",
@@ -3274,6 +3844,12 @@ var INLINE_ACTOR_KEYS = /* @__PURE__ */ new Set([
3274
3844
  "visibleIf",
3275
3845
  // 箱に出す題 (#1381)。 名前と切り離して書ける
3276
3846
  "title",
3847
+ // 値に追随する 5 欄 (#1392)
3848
+ "wBind",
3849
+ "hBind",
3850
+ "opacity",
3851
+ "renderOffsetX",
3852
+ "renderOffsetY",
3277
3853
  // 倍率は別経路 (`reportScaleOnNonPart`) が知らせる。 ここでも読める扱いにしないと
3278
3854
  // 同じ名前で 2 度知らせることになる
3279
3855
  "scale",
@@ -3281,12 +3857,24 @@ var INLINE_ACTOR_KEYS = /* @__PURE__ */ new Set([
3281
3857
  // 英語が読める欄の日本語別名 (#1301)。 一覧は `INLINE_ACTOR_ALIASES` が持つ
3282
3858
  ...Object.keys(INLINE_ACTOR_ALIASES)
3283
3859
  ]);
3860
+ var EDGE_BIND_INLINE_READERS = {
3861
+ widthBind: (v) => v,
3862
+ strokeBind: (v) => v,
3863
+ dashOffsetBind: (v) => v
3864
+ };
3284
3865
  var FLOW_INLINE_READERS = {
3285
3866
  sub: (v) => v,
3286
3867
  guard: (v) => v,
3287
3868
  cardinality: (v) => v,
3288
3869
  // 矢印がどの辺から出るか (#1385)。 描画側は 4 方向を取り、書かなければ自動で選ぶ
3289
3870
  side: (v) => v !== void 0 && EDGE_SIDE_VALUES.includes(v) ? v : void 0,
3871
+ /*
3872
+ * 矢印を値に追随させる 3 欄 (#1396)。 箱の `wBind` (#1392) と同じく文字列だけを取る。
3873
+ *
3874
+ * ここでは字をそのまま通し、空かどうかは呼出側が知らせる (表の読み手は行番号を
3875
+ * 持たないため、知らせを出せる場所で見る)。
3876
+ */
3877
+ ...EDGE_BIND_INLINE_READERS,
3290
3878
  // 数と真偽の欄は `FLOW_INLINE_VALUE_KINDS` の表が読む (#1306)。 ここでは名前だけを持つ =
3291
3879
  // 読める欄の一覧 (`FLOW_INLINE_KEYS`) は本表から導くため、載せないと欄ごと消える
3292
3880
  labelOffsetX: null,
@@ -3352,6 +3940,13 @@ function parseActor2(line, errors) {
3352
3940
  visibleIf: isPart ? void 0 : \u51FA\u3059\u6761\u4EF6\u3068\u3057\u3066\u8AAD\u3080(opts.visibleIf, line.no, errors),
3353
3941
  // 箱に出す題 (#1381)。 空文字も意味を持つ (題を出さない箱) ため undefined と分ける
3354
3942
  title: isPart ? void 0 : opts.title,
3943
+ // 値に追随する 5 欄 (#1392)。 図形や出す条件と同じく、パーツでは状態の上書きとして
3944
+ // 意味を持つため横取りしない
3945
+ wBind: isPart ? void 0 : \u8FFD\u968F\u3059\u308B\u5927\u304D\u3055\u3068\u3057\u3066\u8AAD\u3080(opts.wBind, "\u7BB1\u306E wBind ", line.no, errors),
3946
+ hBind: isPart ? void 0 : \u8FFD\u968F\u3059\u308B\u5927\u304D\u3055\u3068\u3057\u3066\u8AAD\u3080(opts.hBind, "\u7BB1\u306E hBind ", line.no, errors),
3947
+ opacity: isPart ? void 0 : \u5024\u306B\u8FFD\u968F\u3059\u308B\u6B04\u3068\u3057\u3066\u8AAD\u3080(opts.opacity, "\u7BB1\u306E opacity ", line.no, errors),
3948
+ renderOffsetX: isPart ? void 0 : \u5024\u306B\u8FFD\u968F\u3059\u308B\u6B04\u3068\u3057\u3066\u8AAD\u3080(opts.renderOffsetX, "\u7BB1\u306E renderOffsetX ", line.no, errors),
3949
+ renderOffsetY: isPart ? void 0 : \u5024\u306B\u8FFD\u968F\u3059\u308B\u6B04\u3068\u3057\u3066\u8AAD\u3080(opts.renderOffsetY, "\u7BB1\u306E renderOffsetY ", line.no, errors),
3355
3950
  ...\u8868\u3067\u8AAD\u3080(ACTOR_INLINE_VALUE_KINDS, opts, "\u7BB1\u306E ", line.no, errors),
3356
3951
  // parts では `tone` を状態の上書きとして従来から使えるため、 色として横取りしない
3357
3952
  tone: isPart ? void 0 : resolveTone(opts.tone),
@@ -3410,10 +4005,17 @@ function parseFlowStep(line, no, errors) {
3410
4005
  let tone;
3411
4006
  let style;
3412
4007
  const \u4E2D\u62EC\u5F27 = {};
3413
- const mapMatch = rest.match(/\s*\{([^}]*)\}\s*$/);
4008
+ const \u584A = \u672B\u5C3E\u306E\u4E2D\u62EC\u5F27\u3092\u5207\u308A\u51FA\u3059(rest);
3414
4009
  let \u6570\u3068\u771F\u507D;
3415
- if (mapMatch) {
3416
- const opts = parseInlineMapping(mapMatch[1]);
4010
+ if (\u584A) {
4011
+ const opts = parseInlineMapping(\u584A.\u4E2D\u8EAB);
4012
+ for (const field of splitInlineFields(\u584A.\u4E2D\u8EAB)) {
4013
+ const idx = field.indexOf(":");
4014
+ if (idx < 0) continue;
4015
+ const key = field.slice(0, idx).trim();
4016
+ if (!Object.hasOwn(EDGE_BIND_INLINE_READERS, key)) continue;
4017
+ opts[key] = stripQuotes(field.slice(idx + 1).trim());
4018
+ }
3417
4019
  for (const k of FLOW_INLINE_KEYS) {
3418
4020
  const \u8AAD\u307F\u624B = FLOW_INLINE_READERS[k];
3419
4021
  if (\u8AAD\u307F\u624B === null) continue;
@@ -3427,12 +4029,30 @@ function parseFlowStep(line, no, errors) {
3427
4029
  });
3428
4030
  }
3429
4031
  \u6570\u3068\u771F\u507D = \u8868\u3067\u8AAD\u3080(FLOW_INLINE_VALUE_KINDS, opts, "\u77E2\u5370\u306E ", line.no, errors);
3430
- rest = rest.slice(0, mapMatch.index ?? 0).trim();
4032
+ rest = \u584A.\u524D.trim();
3431
4033
  }
3432
4034
  const sub = \u4E2D\u62EC\u5F27.sub;
3433
4035
  const guard = \u4E2D\u62EC\u5F27.guard;
3434
4036
  const cardinality = \u4E2D\u62EC\u5F27.cardinality;
3435
4037
  const side = \u4E2D\u62EC\u5F27.side;
4038
+ const widthBind = \u8FFD\u968F\u3059\u308B\u5927\u304D\u3055\u3068\u3057\u3066\u8AAD\u3080(
4039
+ \u4E2D\u62EC\u5F27.widthBind,
4040
+ "\u77E2\u5370\u306E widthBind ",
4041
+ line.no,
4042
+ errors
4043
+ );
4044
+ const strokeBind = \u8FFD\u968F\u3059\u308B\u5927\u304D\u3055\u3068\u3057\u3066\u8AAD\u3080(
4045
+ \u4E2D\u62EC\u5F27.strokeBind,
4046
+ "\u77E2\u5370\u306E strokeBind ",
4047
+ line.no,
4048
+ errors
4049
+ );
4050
+ const dashOffsetBind = \u8FFD\u968F\u3059\u308B\u5927\u304D\u3055\u3068\u3057\u3066\u8AAD\u3080(
4051
+ \u4E2D\u62EC\u5F27.dashOffsetBind,
4052
+ "\u77E2\u5370\u306E dashOffsetBind ",
4053
+ line.no,
4054
+ errors
4055
+ );
3436
4056
  const labelOffsetX = \u6570\u3068\u771F\u507D?.labelOffsetX;
3437
4057
  const labelOffsetY = \u6570\u3068\u771F\u507D?.labelOffsetY;
3438
4058
  const overlay = \u6570\u3068\u771F\u507D?.overlay;
@@ -3484,6 +4104,9 @@ function parseFlowStep(line, no, errors) {
3484
4104
  guard,
3485
4105
  cardinality,
3486
4106
  side,
4107
+ widthBind,
4108
+ strokeBind,
4109
+ dashOffsetBind,
3487
4110
  labelOffsetX,
3488
4111
  labelOffsetY,
3489
4112
  overlay,
@@ -4041,14 +4664,22 @@ var PAINT_KEYS = /* @__PURE__ */ new Set([
4041
4664
  var SAFE_PAINT = "none";
4042
4665
  function stripExternalPaint(diagram2) {
4043
4666
  const stripped = [];
4044
- walk(diagram2, "", false, stripped);
4667
+ walk(diagram2, "", false, stripped, false);
4045
4668
  return stripped;
4046
4669
  }
4047
- function walk(node, path, inStateValue, out) {
4670
+ var INPUT_VALUE_KEYS = /* @__PURE__ */ new Set(["defaultvalue", "defaultvalues", "options"]);
4671
+ function walk(node, path, inStateValue, out, inInputs) {
4048
4672
  if (node === null || typeof node !== "object") return;
4049
4673
  if (Array.isArray(node)) {
4050
4674
  for (let i = 0; i < node.length; i++) {
4051
- walk(node[i], `${path}[${i}]`, inStateValue, out);
4675
+ const here = `${path}[${i}]`;
4676
+ const value = node[i];
4677
+ if (inStateValue && typeof value === "string" && pointsOutside(value)) {
4678
+ node[i] = SAFE_PAINT;
4679
+ out.push({ path: here, value });
4680
+ } else {
4681
+ walk(value, here, inStateValue, out, inInputs);
4682
+ }
4052
4683
  }
4053
4684
  return;
4054
4685
  }
@@ -4056,7 +4687,8 @@ function walk(node, path, inStateValue, out) {
4056
4687
  for (const [key, value] of Object.entries(obj)) {
4057
4688
  const here = path ? `${path}.${key}` : key;
4058
4689
  const lower = key.toLowerCase();
4059
- const nextInState = inStateValue || lower === "states" || lower === "sets" || lower === "tweens";
4690
+ const nextInState = inStateValue || lower === "states" || lower === "sets" || lower === "tweens" || inInputs && INPUT_VALUE_KEYS.has(lower);
4691
+ const nextInInputs = inInputs || lower === "inputs";
4060
4692
  if (typeof value === "string") {
4061
4693
  const isPaint = PAINT_KEYS.has(lower) || nextInState && (lower === "initial" || lower === "to" || lower === "from" || !isReservedStateKey(lower));
4062
4694
  if (isPaint && pointsOutside(value)) {
@@ -4065,7 +4697,7 @@ function walk(node, path, inStateValue, out) {
4065
4697
  }
4066
4698
  continue;
4067
4699
  }
4068
- walk(value, here, nextInState, out);
4700
+ walk(value, here, nextInState, out, nextInInputs);
4069
4701
  }
4070
4702
  }
4071
4703
  function isReservedStateKey(lowerKey) {
@@ -4083,7 +4715,15 @@ function countDocElements(doc) {
4083
4715
  );
4084
4716
  return doc.actors.length + doc.flow.length + phases.length + phaseChildren + (doc.animate?.states.length ?? 0) + (doc.values?.length ?? 0) + // 値を見せる部品も描画時に 1 widget ずつ展開される (#1374)。 数えないと、 actors が
4085
4717
  // 少ないまま readouts だけを大量に並べた入力が組み立て前の上限をすり抜ける。
4086
- (doc.readouts?.length ?? 0) + (doc.groups ? Object.keys(doc.groups).length : 0) + (doc.lanes ? Object.keys(doc.lanes).length : 0);
4718
+ (doc.readouts?.length ?? 0) + // 読む人が動かすつまみも 1 widget ずつ展開される (#1389) readouts と同じ上限で守る。
4719
+ (doc.inputs?.length ?? 0) + /*
4720
+ * 式 (#1391) と、押下 / 巻き上げ (#1393) も数える。
4721
+ *
4722
+ * **図の側 (`countDiagramElements`) は既に数えている**。 記法側だけ数えないと、
4723
+ * 箱が少ないままこれらを大量に並べた入力が組み立て前の上限をすり抜け、
4724
+ * 組み立て終わってから (= 時間をかけてから) 図の側で弾かれる。
4725
+ */
4726
+ (doc.formulas?.length ?? 0) + (doc.events?.length ?? 0) + (doc.scrolls?.length ?? 0) + (doc.groups ? Object.keys(doc.groups).length : 0) + (doc.lanes ? Object.keys(doc.lanes).length : 0);
4087
4727
  }
4088
4728
  function countDiagramElements(diagram2) {
4089
4729
  const phases = Array.isArray(diagram2.phases) ? diagram2.phases : [];
@@ -4229,6 +4869,100 @@ function compileToCdl(doc, opts) {
4229
4869
  );
4230
4870
  merged.readouts = [...merged.readouts ?? [], ...ownReadouts];
4231
4871
  }
4872
+ if (doc.inputs && doc.inputs.length > 0) {
4873
+ const ownInputs = doc.inputs.map(
4874
+ (input) => deepRewriteStrings(input, (value) => value)
4875
+ );
4876
+ merged.inputs = [...merged.inputs ?? [], ...ownInputs];
4877
+ }
4878
+ if (doc.formulas && doc.formulas.length > 0) {
4879
+ const ownFormulas = doc.formulas.map((formula) => ({
4880
+ id: formula.id,
4881
+ expression: formula.expression,
4882
+ line: formula.pos?.line ?? 0
4883
+ }));
4884
+ const \u3064\u307E\u307F = new Map((merged.inputs ?? []).map((input) => [input.id, input]));
4885
+ const \u5148\u306B\u66F8\u304B\u308C\u305F\u5F0F = new Set((merged.formulas ?? []).map((formula) => formula.id));
4886
+ const \u8F09\u305B\u308B\u5F0F = [...merged.formulas ?? []];
4887
+ for (const formula of ownFormulas) {
4888
+ if (\u3064\u307E\u307F.has(formula.id) || \u5148\u306B\u66F8\u304B\u308C\u305F\u5F0F.has(formula.id)) {
4889
+ opts?.onNotice?.({
4890
+ kind: "formula-unresolved",
4891
+ actor: formula.id,
4892
+ line: formula.line,
4893
+ message: `\u5F0F "${formula.id}" \u306E\u540D\u524D\u304C\u3001\u5148\u306B\u66F8\u304B\u308C\u305F\u3064\u307E\u307F\u307E\u305F\u306F\u5F0F\u3068\u91CD\u306A\u3063\u3066\u3044\u307E\u3059`,
4894
+ hint: "`inputs:` \u3068 `formulas:` \u3067\u306F\u91CD\u306A\u3089\u306A\u3044\u540D\u524D\u3092\u4F7F\u3046"
4895
+ });
4896
+ continue;
4897
+ }
4898
+ let \u540D\u524D\u305F\u3061;
4899
+ try {
4900
+ \u540D\u524D\u305F\u3061 = cdl.extractIdentifiers(cdl.parseFormula(formula.expression));
4901
+ } catch {
4902
+ continue;
4903
+ }
4904
+ let \u89E3\u3051\u306A\u3044 = false;
4905
+ for (const \u540D of \u540D\u524D\u305F\u3061) {
4906
+ if (\u5148\u306B\u66F8\u304B\u308C\u305F\u5F0F.has(\u540D)) continue;
4907
+ const input = \u3064\u307E\u307F.get(\u540D);
4908
+ if (input) {
4909
+ const \u521D\u671F\u5024 = cdl.inputDefaultValue(input);
4910
+ if (typeof \u521D\u671F\u5024 === "number" || typeof \u521D\u671F\u5024 === "boolean") continue;
4911
+ \u89E3\u3051\u306A\u3044 = true;
4912
+ opts?.onNotice?.({
4913
+ kind: "formula-unresolved",
4914
+ actor: formula.id,
4915
+ line: formula.line,
4916
+ message: `\u5F0F "${formula.id}" \u304C\u3001\u6570\u3067\u3082\u771F\u507D\u3067\u3082\u306A\u3044\u3064\u307E\u307F "${\u540D}" \u3092\u8AAD\u3093\u3067\u3044\u307E\u3059`,
4917
+ hint: "\u5F0F\u304C\u8AAD\u3081\u308B\u3064\u307E\u307F\u306F slider / number / stepper / timeline / toggle"
4918
+ });
4919
+ continue;
4920
+ }
4921
+ \u89E3\u3051\u306A\u3044 = true;
4922
+ opts?.onNotice?.({
4923
+ kind: "formula-unresolved",
4924
+ actor: formula.id,
4925
+ line: formula.line,
4926
+ message: `\u5F0F "${formula.id}" \u304C\u3001\u3064\u307E\u307F\u307E\u305F\u306F\u5148\u306B\u66F8\u304B\u308C\u305F\u5F0F\u3067\u306F\u306A\u3044\u540D\u524D "${\u540D}" \u3092\u8AAD\u3093\u3067\u3044\u307E\u3059`,
4927
+ hint: "`inputs:` \u306B\u66F8\u304F\u304B\u3001\u53C2\u7167\u3055\u308C\u308B\u5F0F\u3092\u3053\u306E\u5F0F\u3088\u308A\u524D\u306B\u66F8\u304F"
4928
+ });
4929
+ }
4930
+ if (\u89E3\u3051\u306A\u3044) continue;
4931
+ \u8F09\u305B\u308B\u5F0F.push({ id: formula.id, expression: formula.expression });
4932
+ \u5148\u306B\u66F8\u304B\u308C\u305F\u5F0F.add(formula.id);
4933
+ }
4934
+ if (\u8F09\u305B\u308B\u5F0F.length > 0) merged.formulas = \u8F09\u305B\u308B\u5F0F;
4935
+ else delete merged.formulas;
4936
+ }
4937
+ if (doc.events && doc.events.length > 0) {
4938
+ const \u8F09\u305B\u308B = [...merged.eventBindings ?? []];
4939
+ for (const e of doc.events) {
4940
+ const \u76F8\u624B = \u51FA\u6765\u4E8B\u306E\u76F8\u624B\u3092\u89E3\u304F(merged, doc, e);
4941
+ if (\u76F8\u624B === void 0) {
4942
+ opts?.onNotice?.({
4943
+ kind: "event-target-missing",
4944
+ actor: e.handlerId,
4945
+ line: e.pos.line,
4946
+ message: `\u51FA\u6765\u4E8B "${e.handlerId}" \u304C\u6307\u3059\u76F8\u624B\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093`,
4947
+ hint: "box \u306F\u7BB1\u306E\u540D\u524D\u3001 lane \u306F\u7E26\u5217\u306E\u540D\u524D\u3001 arrow \u306F `A -> B` \u3067\u66F8\u304F"
4948
+ });
4949
+ continue;
4950
+ }
4951
+ \u8F09\u305B\u308B.push({
4952
+ id: `evt-${\u8F09\u305B\u308B.length + 1}`,
4953
+ event: e.event,
4954
+ target: \u76F8\u624B,
4955
+ handlerId: e.handlerId
4956
+ });
4957
+ }
4958
+ if (\u8F09\u305B\u308B.length > 0) merged.eventBindings = \u8F09\u305B\u308B;
4959
+ }
4960
+ if (doc.scrolls && doc.scrolls.length > 0) {
4961
+ merged.scrollTriggers = [
4962
+ ...merged.scrollTriggers ?? [],
4963
+ ...doc.scrolls.map((x) => ({ ...x }))
4964
+ ];
4965
+ }
4232
4966
  const \u5916\u3057\u305F\u90E8\u54C1\u306E\u914D\u8272 = stripExternalReadoutPalettes(merged);
4233
4967
  for (const dropped of [...stripExternalPaint(merged), ...\u5916\u3057\u305F\u90E8\u54C1\u306E\u914D\u8272]) {
4234
4968
  opts?.onNotice?.({
@@ -4563,6 +5297,23 @@ function disambiguateActorIds(doc, onNotice) {
4563
5297
  const from = \u76F4\u3059(s.from);
4564
5298
  const to = \u76F4\u3059(s.to);
4565
5299
  return from === s.from && to === s.to ? s : { ...s, from, to };
5300
+ }),
5301
+ events: doc.events?.map((event) => {
5302
+ const target = event.target;
5303
+ if (target.kind === "node") {
5304
+ const name = \u76F4\u3059(target.name);
5305
+ return name === target.name ? event : { ...event, target: { ...target, name } };
5306
+ }
5307
+ if (target.kind === "edge") {
5308
+ const from = \u76F4\u3059(target.from);
5309
+ const to = \u76F4\u3059(target.to);
5310
+ return from === target.from && to === target.to ? event : { ...event, target: { ...target, from, to } };
5311
+ }
5312
+ if (target.kind === "lane" && (doc.type === "sequence" || doc.type === "solidity")) {
5313
+ const name = \u76F4\u3059(target.name);
5314
+ return name === target.name ? event : { ...event, target: { ...target, name } };
5315
+ }
5316
+ return event;
4566
5317
  })
4567
5318
  };
4568
5319
  if (\u6B21.animate) {
@@ -5604,6 +6355,35 @@ function applyEdgeInlineOptions(diagram2, doc, sourceLines) {
5604
6355
  \u77E2\u5370\u3078\u66F8\u304D\u5199\u3059(target, s, doc);
5605
6356
  });
5606
6357
  }
6358
+ function \u51FA\u6765\u4E8B\u306E\u76F8\u624B\u3092\u89E3\u304F(diagram2, doc, e) {
6359
+ if (e.target.kind === "diagram") return { kind: "diagram" };
6360
+ if (e.target.kind === "edge") {
6361
+ const from = slugify(e.target.from);
6362
+ const to = slugify(e.target.to);
6363
+ let \u77E2\u5370;
6364
+ if (doc.type === "sequence" || doc.type === "solidity") {
6365
+ const stepIdx = doc.flow.findIndex(
6366
+ (step) => slugify(step.from) === from && slugify(step.to) === to
6367
+ );
6368
+ if (stepIdx >= 0) {
6369
+ \u77E2\u5370 = diagram2.edges.find(
6370
+ (x) => (x.from === `s${stepIdx}-${from}` || x.from === from) && (x.to === `s${stepIdx}-${to}` || x.from === x.to)
6371
+ );
6372
+ }
6373
+ } else {
6374
+ \u77E2\u5370 = diagram2.edges.find((x) => x.from === from && x.to === to);
6375
+ }
6376
+ return \u77E2\u5370 ? { kind: "edge", id: \u77E2\u5370.id } : void 0;
6377
+ }
6378
+ const \u540D = e.target.name;
6379
+ const slug = slugify(\u540D);
6380
+ if (e.target.kind === "node") {
6381
+ const \u7BB1 = diagram2.nodes.find((n) => n.id === slug || n.id === \u540D || n.title === \u540D);
6382
+ return \u7BB1 ? { kind: "node", id: \u7BB1.id } : void 0;
6383
+ }
6384
+ const \u5217 = (diagram2.lanes ?? []).find((l) => l.id === slug || l.id === \u540D || l.label === \u540D);
6385
+ return \u5217 ? { kind: "lane", id: \u5217.id } : void 0;
6386
+ }
5607
6387
  function \u77E2\u5370\u3078\u66F8\u304D\u5199\u3059(target, s, doc) {
5608
6388
  if (s.sub !== void 0) target.sub = s.sub;
5609
6389
  if (s.guard !== void 0) {
@@ -5620,6 +6400,9 @@ function \u77E2\u5370\u3078\u66F8\u304D\u5199\u3059(target, s, doc) {
5620
6400
  if (s.labelOffsetX !== void 0) target.labelOffsetX = s.labelOffsetX;
5621
6401
  if (s.labelOffsetY !== void 0) target.labelOffsetY = s.labelOffsetY;
5622
6402
  if (s.overlay !== void 0) target.overlay = s.overlay;
6403
+ if (s.widthBind !== void 0) target.widthBind = s.widthBind;
6404
+ if (s.strokeBind !== void 0) target.strokeBind = s.strokeBind;
6405
+ if (s.dashOffsetBind !== void 0) target.dashOffsetBind = s.dashOffsetBind;
5623
6406
  }
5624
6407
  function \u9396\u3067\u3064\u306A\u3050\u5F62\u304B(doc) {
5625
6408
  if (doc.type !== "flow") return false;
@@ -6834,7 +7617,12 @@ var \u653E\u5C04\u3067\u63CF\u3051\u306A\u3044\u6B04\u306E\u540D\u524D = {
6834
7617
  nodes: "\u4E2D\u306E\u7BB1\u3054\u3068\u306E\u6307\u5B9A",
6835
7618
  layoutPos: "\u914D\u7F6E\u306E\u305A\u3089\u3057",
6836
7619
  shape: "\u7BB1\u306E\u4E2D\u306E\u56F3\u5F62",
6837
- visibleIf: "\u51FA\u3059\u6761\u4EF6"
7620
+ visibleIf: "\u51FA\u3059\u6761\u4EF6",
7621
+ wBind: "\u5024\u306B\u8FFD\u968F\u3059\u308B\u5927\u304D\u3055",
7622
+ hBind: "\u5024\u306B\u8FFD\u968F\u3059\u308B\u5927\u304D\u3055",
7623
+ opacity: "\u6FC3\u3055",
7624
+ renderOffsetX: "\u63CF\u304F\u6642\u306E\u305A\u3089\u3057",
7625
+ renderOffsetY: "\u63CF\u304F\u6642\u306E\u305A\u3089\u3057"
6838
7626
  };
6839
7627
  function \u653E\u5C04\u3067\u63CF\u3051\u306A\u3044\u6B04\u3092\u66F8\u3044\u305F\u304B(a, \u6B04) {
6840
7628
  if (\u6B04 === "kind") return a.kindWritten === true;
@@ -7079,6 +7867,11 @@ function applyV05Extensions(diagram2, doc, \u8FFD\u52A0\u3057\u305F\u7E26\u5217o
7079
7867
  if (footer) footer.visibleIf = a.visibleIf;
7080
7868
  }
7081
7869
  }
7870
+ if (a.wBind !== void 0) node.wBind = a.wBind;
7871
+ if (a.hBind !== void 0) node.hBind = a.hBind;
7872
+ if (a.opacity !== void 0) node.opacity = a.opacity;
7873
+ if (a.renderOffsetX !== void 0) node.renderOffsetX = a.renderOffsetX;
7874
+ if (a.renderOffsetY !== void 0) node.renderOffsetY = a.renderOffsetY;
7082
7875
  }
7083
7876
  }
7084
7877
  alignSeqHeaderHeights(diagram2, doc);
@@ -7537,21 +8330,39 @@ function compileGenericWithAnimate(doc, opts) {
7537
8330
  const { kind, laneWidth } = opts;
7538
8331
  const actorToNodeId = /* @__PURE__ */ new Map();
7539
8332
  if (\u66F8\u3044\u305F\u7E26\u5217\u306B\u7F6E\u304F(kind, doc)) {
7540
- const \u4E26\u3073 = [];
8333
+ const \u4F7F\u3063\u305F = [];
7541
8334
  for (const a of doc.actors) {
7542
8335
  const lid = a.lane;
7543
- if (lid !== void 0 && !\u4E26\u3073.includes(lid)) \u4E26\u3073.push(lid);
8336
+ if (lid !== void 0 && !\u4F7F\u3063\u305F.includes(lid)) \u4F7F\u3063\u305F.push(lid);
7544
8337
  }
8338
+ const \u66F8\u3044\u305F\u9806 = doc.lanes ? Object.keys(doc.lanes) : [];
8339
+ const \u4E26\u3073 = [
8340
+ ...\u66F8\u3044\u305F\u9806.filter((lid) => \u4F7F\u3063\u305F.includes(lid)),
8341
+ ...\u4F7F\u3063\u305F.filter((lid) => !\u66F8\u3044\u305F\u9806.includes(lid))
8342
+ ];
7545
8343
  for (const lid of \u4E26\u3073) {
7546
8344
  b.lane(lid, { width: laneWidth, ...kind === "topology" ? { contain: true } : {} });
7547
8345
  }
7548
- const \u7A4D\u3093\u3060\u6570 = /* @__PURE__ */ new Map();
8346
+ const \u57CB\u307E\u3063\u305F\u6BB5 = /* @__PURE__ */ new Map();
8347
+ const \u57CB\u3081\u308B = (lid, stack) => {
8348
+ const \u96C6\u5408 = \u57CB\u307E\u3063\u305F\u6BB5.get(lid) ?? /* @__PURE__ */ new Set();
8349
+ \u96C6\u5408.add(stack);
8350
+ \u57CB\u307E\u3063\u305F\u6BB5.set(lid, \u96C6\u5408);
8351
+ };
8352
+ for (const a of doc.actors) {
8353
+ if (a.lane !== void 0 && a.stack !== void 0) \u57CB\u3081\u308B(a.lane, a.stack);
8354
+ }
7549
8355
  doc.actors.forEach((a, idx) => {
7550
8356
  const id = slugify(a.name);
7551
8357
  actorToNodeId.set(a.name, id);
7552
8358
  const lid = a.lane;
7553
- const stack = \u7A4D\u3093\u3060\u6570.get(lid) ?? 0;
7554
- \u7A4D\u3093\u3060\u6570.set(lid, stack + 1);
8359
+ let stack = a.stack;
8360
+ if (stack === void 0) {
8361
+ stack = 0;
8362
+ const \u96C6\u5408 = \u57CB\u307E\u3063\u305F\u6BB5.get(lid);
8363
+ while (\u96C6\u5408?.has(stack)) stack += 1;
8364
+ \u57CB\u3081\u308B(lid, stack);
8365
+ }
7555
8366
  b.node(id, { lane: lid, stack, kind: a.kind, title: \u7BB1\u306E\u984C(a) });
7556
8367
  });
7557
8368
  } else if (kind === "flow" || kind === "topology") {
@@ -8269,8 +9080,6 @@ function \u533A\u9593\u306B\u5E83\u3052\u308B(src, tokens) {
8269
9080
  if (\u4F4D\u7F6E < src.length) out.push({ \u6587\u5B57: src.slice(\u4F4D\u7F6E) });
8270
9081
  return out;
8271
9082
  }
8272
-
8273
- // src/json-parser.ts
8274
9083
  var VALID_KIND_SET = NODE_KIND_VALID;
8275
9084
  var VALID_PRESETS = [...PRESET_TYPES];
8276
9085
  var ACCEPTED_KEYS = {
@@ -8288,7 +9097,14 @@ var ACCEPTED_KEYS = {
8288
9097
  "lanes",
8289
9098
  "groups",
8290
9099
  // 値を見せる部品 (#1374)
8291
- "readouts"
9100
+ "readouts",
9101
+ // 読む人が動かすつまみ (#1389)
9102
+ "inputs",
9103
+ // つまみの値から決まる値 (#1391)
9104
+ "formulas",
9105
+ // 押下などの出来事で動く仕掛けと、巻き上げに応じて進む値 (#1393)
9106
+ "events",
9107
+ "scrolls"
8292
9108
  ],
8293
9109
  actor: [
8294
9110
  "name",
@@ -8320,7 +9136,13 @@ var ACCEPTED_KEYS = {
8320
9136
  // その箱を出すかどうかの条件 (#1381)
8321
9137
  "visibleIf",
8322
9138
  // 箱に出す題 (#1381)
8323
- "title"
9139
+ "title",
9140
+ // 値に追随する 5 欄 (#1392)
9141
+ "wBind",
9142
+ "hBind",
9143
+ "opacity",
9144
+ "renderOffsetX",
9145
+ "renderOffsetY"
8324
9146
  ],
8325
9147
  step: [
8326
9148
  "from",
@@ -8333,6 +9155,10 @@ var ACCEPTED_KEYS = {
8333
9155
  "style",
8334
9156
  "guard",
8335
9157
  "cardinality",
9158
+ // 値に追随する 3 欄 (#1396)
9159
+ "widthBind",
9160
+ "strokeBind",
9161
+ "dashOffsetBind",
8336
9162
  "labelOffsetX",
8337
9163
  "labelOffsetY",
8338
9164
  "overlay",
@@ -8363,7 +9189,14 @@ var \u6B04\u306E\u578B\u8868 = {
8363
9189
  lanes: "object",
8364
9190
  groups: "object",
8365
9191
  // 値を見せる部品 (#1374)。 中身は下の検査が種類ごとに見る
8366
- readouts: "\u4E26\u3073"
9192
+ readouts: "\u4E26\u3073",
9193
+ // 読む人が動かすつまみ (#1389)。 部品と同じく中身は下の検査が種類ごとに見る
9194
+ inputs: "\u4E26\u3073",
9195
+ // つまみの値から決まる値 (#1391)。 中身は下の検査が式ごとに見る
9196
+ formulas: "object",
9197
+ // 押下と巻き上げ (#1393)。 中身は下の検査が 1 件ずつ見る
9198
+ events: "\u4E26\u3073",
9199
+ scrolls: "object"
8367
9200
  },
8368
9201
  actor: {
8369
9202
  name: "\u5FC5\u9808\u306E\u975E\u7A7A\u6587\u5B57\u5217",
@@ -8395,7 +9228,13 @@ var \u6B04\u306E\u578B\u8868 = {
8395
9228
  // その箱を出すかどうかの条件 (#1381)
8396
9229
  visibleIf: "\u6587\u5B57\u5217",
8397
9230
  // 箱に出す題 (#1381)
8398
- title: "\u6587\u5B57\u5217"
9231
+ title: "\u6587\u5B57\u5217",
9232
+ // 値に追随する 5 欄 (#1392)。 大きさは文字列だけ、濃さとずらしは数も受ける
9233
+ wBind: "\u975E\u7A7A\u306E\u6587\u5B57\u5217",
9234
+ hBind: "\u975E\u7A7A\u306E\u6587\u5B57\u5217",
9235
+ opacity: "\u6570\u304B\u6587\u5B57\u5217",
9236
+ renderOffsetX: "\u6570\u304B\u6587\u5B57\u5217",
9237
+ renderOffsetY: "\u6570\u304B\u6587\u5B57\u5217"
8399
9238
  },
8400
9239
  step: {
8401
9240
  from: "\u5FC5\u9808\u306E\u6587\u5B57\u5217",
@@ -8408,6 +9247,10 @@ var \u6B04\u306E\u578B\u8868 = {
8408
9247
  style: "\u7DDA\u7A2E",
8409
9248
  guard: "\u6587\u5B57\u5217",
8410
9249
  cardinality: "\u6587\u5B57\u5217",
9250
+ // 値に追随する 3 欄 (#1396)。 描画側は文字列だけを取る
9251
+ widthBind: "\u975E\u7A7A\u306E\u6587\u5B57\u5217",
9252
+ strokeBind: "\u975E\u7A7A\u306E\u6587\u5B57\u5217",
9253
+ dashOffsetBind: "\u975E\u7A7A\u306E\u6587\u5B57\u5217",
8411
9254
  labelOffsetX: "\u6570",
8412
9255
  labelOffsetY: "\u6570",
8413
9256
  overlay: "\u771F\u507D",
@@ -8468,7 +9311,13 @@ var \u898B\u672C\u306B\u52B9\u304B\u306A\u3044\u6B04 = [
8468
9311
  // その箱を出すかどうかの条件 (#1381)。 見本は自分の出方を持つ
8469
9312
  "visibleIf",
8470
9313
  // 箱に出す題 (#1381)。 見本は自分の題を持つ
8471
- "title"
9314
+ "title",
9315
+ // 値に追随する 5 欄 (#1392)。 見本は自分の大きさと出方を持つ
9316
+ "wBind",
9317
+ "hBind",
9318
+ "opacity",
9319
+ "renderOffsetX",
9320
+ "renderOffsetY"
8472
9321
  ];
8473
9322
  function \u5024\u3092\u691C\u67FB(v, \u578B, path, \u540D\u524D, errors) {
8474
9323
  const \u578B\u9055\u3044 = (\u671F\u5F85, \u88DC\u8DB3) => {
@@ -8487,7 +9336,7 @@ function \u5024\u3092\u691C\u67FB(v, \u578B, path, \u540D\u524D, errors) {
8487
9336
  return;
8488
9337
  case "\u975E\u7A7A\u306E\u6587\u5B57\u5217":
8489
9338
  if (v === void 0) return;
8490
- if (typeof v !== "string" || v.length === 0) \u578B\u9055\u3044("a non-empty string if present");
9339
+ if (typeof v !== "string" || v.trim().length === 0) \u578B\u9055\u3044("a non-empty string if present");
8491
9340
  return;
8492
9341
  case "\u6587\u5B57\u5217":
8493
9342
  if (v === void 0) return;
@@ -8523,6 +9372,19 @@ function \u5024\u3092\u691C\u67FB(v, \u578B, path, \u540D\u524D, errors) {
8523
9372
  \u578B\u9055\u3044("a finite number", typeof v === "number" ? `got ${String(v)}` : void 0);
8524
9373
  }
8525
9374
  return;
9375
+ case "\u6570\u304B\u6587\u5B57\u5217":
9376
+ if (v === void 0) return;
9377
+ if (typeof v === "string") {
9378
+ if (v.trim().length === 0) \u578B\u9055\u3044("a non-empty string if present");
9379
+ return;
9380
+ }
9381
+ if (typeof v !== "number" || !Number.isFinite(v)) {
9382
+ \u578B\u9055\u3044(
9383
+ "a finite number or a non-empty string if present",
9384
+ typeof v === "number" ? `got ${String(v)}` : void 0
9385
+ );
9386
+ }
9387
+ return;
8526
9388
  case "\u771F\u507D":
8527
9389
  if (v === void 0) return;
8528
9390
  if (typeof v !== "boolean") \u578B\u9055\u3044("true or false if present");
@@ -8700,7 +9562,7 @@ function validateViewport(v, errors) {
8700
9562
  }
8701
9563
  function \u8868\u3067\u4E2D\u8EAB\u3092\u691C\u67FB\u3059\u308B(o, \u8868, path, \u4F55, errors) {
8702
9564
  const kind = typeof o.kind === "string" ? o.kind : "";
8703
- const \u5B9A\u7FA9 = \u8868[kind];
9565
+ const \u5B9A\u7FA9 = Object.hasOwn(\u8868, kind) ? \u8868[kind] : void 0;
8704
9566
  if (\u5B9A\u7FA9 === void 0) {
8705
9567
  errors.push({
8706
9568
  path: `${path}.kind`,
@@ -8722,7 +9584,7 @@ function \u8868\u3067\u4E2D\u8EAB\u3092\u691C\u67FB\u3059\u308B(o, \u8868, path,
8722
9584
  });
8723
9585
  continue;
8724
9586
  }
8725
- const \u578B\u304C\u5408\u3046 = \u5F62 === "\u6570" ? typeof \u5024 === "number" && Number.isFinite(\u5024) : \u5F62 === "\u6570\u304B\u6587\u5B57\u5217" ? typeof \u5024 === "number" && Number.isFinite(\u5024) || typeof \u5024 === "string" : \u5F62 === "\u6587\u5B57\u5217\u306E\u4E26\u3073" ? Array.isArray(\u5024) && \u5024.every((x) => typeof x === "string") : \u5F62 === "\u771F\u507D" ? typeof \u5024 === "boolean" : \u5F62 === "\u7D44\u306E\u4E26\u3073" ? Array.isArray(\u5024) && \u5024.length > 0 && \u5024.every(
9587
+ const \u578B\u304C\u5408\u3046 = \u5F62 === "\u6570" ? typeof \u5024 === "number" && Number.isFinite(\u5024) : \u5F62 === "\u6570\u304B\u6587\u5B57\u5217" ? typeof \u5024 === "number" && Number.isFinite(\u5024) || typeof \u5024 === "string" : \u5F62 === "\u6587\u5B57\u5217\u306E\u4E26\u3073" ? Array.isArray(\u5024) && \u5024.every((x) => typeof x === "string") : \u5F62 === "\u6570\u306E\u4E26\u3073" ? Array.isArray(\u5024) && \u5024.every((x) => typeof x === "number" && Number.isFinite(x)) : \u5F62 === "\u771F\u507D" ? typeof \u5024 === "boolean" : \u5F62 === "\u7D44\u306E\u4E26\u3073" ? Array.isArray(\u5024) && \u5024.length > 0 && \u5024.every(
8726
9588
  (x) => typeof x === "object" && x !== null && !Array.isArray(x) && Object.keys(x).length > 0 && Object.values(x).every(
8727
9589
  (y) => typeof y === "string" || typeof y === "number" && Number.isFinite(y)
8728
9590
  )
@@ -8803,6 +9665,238 @@ function validateReadouts(v, errors) {
8803
9665
  }
8804
9666
  });
8805
9667
  }
9668
+ function validateInputs(v, errors) {
9669
+ if (v === void 0) return;
9670
+ if (!Array.isArray(v)) {
9671
+ errors.push({
9672
+ path: "$.inputs",
9673
+ message: "inputs must be an array of input objects",
9674
+ hint: `got ${v === null ? "null" : typeof v}`
9675
+ });
9676
+ return;
9677
+ }
9678
+ v.forEach((r, i) => {
9679
+ const path = `$.inputs[${i}]`;
9680
+ if (!r || typeof r !== "object" || Array.isArray(r)) {
9681
+ errors.push({ path, message: "input must be a plain object", hint: `got ${typeof r}` });
9682
+ return;
9683
+ }
9684
+ const o = r;
9685
+ if (typeof o.id !== "string" || o.id === "") {
9686
+ errors.push({ path: `${path}.id`, message: "id is required", hint: "\u7A7A\u3067\u306A\u3044\u6587\u5B57\u5217\u3067\u66F8\u304F" });
9687
+ }
9688
+ \u8868\u3067\u4E2D\u8EAB\u3092\u691C\u67FB\u3059\u308B(o, \u3064\u307E\u307F\u306E\u8868, path, "input", errors);
9689
+ });
9690
+ }
9691
+ function validateFormulas(v, inputs, errors) {
9692
+ if (v === void 0) return;
9693
+ if (!v || typeof v !== "object" || Array.isArray(v)) {
9694
+ errors.push({
9695
+ path: "$.formulas",
9696
+ message: "formulas must be an object of name to expression",
9697
+ hint: `got ${v === null ? "null" : Array.isArray(v) ? "array" : typeof v}`
9698
+ });
9699
+ return;
9700
+ }
9701
+ const \u3064\u307E\u307F = /* @__PURE__ */ new Map();
9702
+ if (Array.isArray(inputs)) {
9703
+ for (const input of inputs) {
9704
+ if (input && typeof input === "object" && !Array.isArray(input)) {
9705
+ const candidate = input;
9706
+ if (typeof candidate.id === "string" && typeof candidate.kind === "string") {
9707
+ \u3064\u307E\u307F.set(candidate.id, candidate.kind);
9708
+ }
9709
+ }
9710
+ }
9711
+ }
9712
+ const \u5148\u306B\u66F8\u304B\u308C\u305F\u5F0F = /* @__PURE__ */ new Set();
9713
+ for (const [\u540D\u524D, \u5F0F] of Object.entries(v)) {
9714
+ const path = `$.formulas.${\u540D\u524D}`;
9715
+ if (!isValueName(\u540D\u524D)) {
9716
+ errors.push({ path, ...valueNameIssue(\u540D\u524D) });
9717
+ continue;
9718
+ }
9719
+ if (typeof \u5F0F !== "string" || \u5F0F.trim() === "") {
9720
+ errors.push({
9721
+ path,
9722
+ message: `${\u540D\u524D} must be a non-empty expression string`,
9723
+ hint: `got ${Array.isArray(\u5F0F) ? "array" : \u5F0F === null ? "null" : typeof \u5F0F}`
9724
+ });
9725
+ continue;
9726
+ }
9727
+ try {
9728
+ const names = cdl.extractIdentifiers(cdl.parseFormula(\u5F0F));
9729
+ if (\u3064\u307E\u307F.has(\u540D\u524D) || \u5148\u306B\u66F8\u304B\u308C\u305F\u5F0F.has(\u540D\u524D)) {
9730
+ errors.push({
9731
+ path,
9732
+ message: `${\u540D\u524D} collides with an input or an earlier formula`,
9733
+ hint: "inputs \u3068 formulas \u3067\u306F\u91CD\u306A\u3089\u306A\u3044\u540D\u524D\u3092\u4F7F\u3046"
9734
+ });
9735
+ continue;
9736
+ }
9737
+ let valid = true;
9738
+ for (const name of names) {
9739
+ if (\u5148\u306B\u66F8\u304B\u308C\u305F\u5F0F.has(name)) continue;
9740
+ const kind = \u3064\u307E\u307F.get(name);
9741
+ if (["slider", "number", "stepper", "timeline", "toggle"].includes(kind ?? "")) continue;
9742
+ valid = false;
9743
+ errors.push({
9744
+ path,
9745
+ message: `${\u540D\u524D} references an unavailable formula identifier`,
9746
+ hint: `${name} \u306F\u6570\u5024/\u771F\u507D\u306E input \u306B\u3059\u308B\u304B\u3001\u3053\u306E\u5F0F\u3088\u308A\u524D\u306E formula \u306B\u66F8\u304F`
9747
+ });
9748
+ }
9749
+ if (valid) \u5148\u306B\u66F8\u304B\u308C\u305F\u5F0F.add(\u540D\u524D);
9750
+ } catch (e) {
9751
+ errors.push({
9752
+ path,
9753
+ message: `${\u540D\u524D} is not a readable expression`,
9754
+ hint: e.message
9755
+ });
9756
+ }
9757
+ }
9758
+ }
9759
+ function validateEvents(v, errors) {
9760
+ if (v === void 0) return;
9761
+ if (!Array.isArray(v)) {
9762
+ errors.push({
9763
+ path: "$.events",
9764
+ message: "events must be an array of event objects",
9765
+ hint: `got ${v === null ? "null" : typeof v}`
9766
+ });
9767
+ return;
9768
+ }
9769
+ const \u76F8\u624B\u306E\u9375 = ["box", "lane", "arrow", "diagram"];
9770
+ v.forEach((e, i) => {
9771
+ const path = `$.events[${i}]`;
9772
+ if (!e || typeof e !== "object" || Array.isArray(e)) {
9773
+ errors.push({ path, message: "event must be a plain object", hint: `got ${typeof e}` });
9774
+ return;
9775
+ }
9776
+ const o = e;
9777
+ for (const k of Object.keys(o)) {
9778
+ if (k === "on" || k === "handler" || \u76F8\u624B\u306E\u9375.includes(k)) continue;
9779
+ errors.push({
9780
+ path: `${path}.${k}`,
9781
+ message: `unknown key "${k}"`,
9782
+ hint: `\u4F7F\u3048\u308B\u9805\u76EE = on, handler, ${\u76F8\u624B\u306E\u9375.join(", ")}`
9783
+ });
9784
+ }
9785
+ if (typeof o.on !== "string" || !EVENT_KINDS.includes(o.on)) {
9786
+ errors.push({
9787
+ path: `${path}.on`,
9788
+ message: "on must be a known event kind",
9789
+ hint: `\u4F7F\u3048\u308B\u7A2E\u985E = ${EVENT_KINDS.join(", ")}`
9790
+ });
9791
+ }
9792
+ if (typeof o.handler !== "string" || o.handler.trim() === "") {
9793
+ errors.push({
9794
+ path: `${path}.handler`,
9795
+ message: "handler is required",
9796
+ hint: "\u7A7A\u3067\u306A\u3044\u6587\u5B57\u5217\u3067\u66F8\u304F"
9797
+ });
9798
+ }
9799
+ const \u66F8\u3044\u305F = \u76F8\u624B\u306E\u9375.filter((k) => o[k] !== void 0);
9800
+ if (\u66F8\u3044\u305F.length !== 1) {
9801
+ errors.push({
9802
+ path,
9803
+ message: \u66F8\u3044\u305F.length === 0 ? "event target is required" : "event target must be written once",
9804
+ hint: `${\u76F8\u624B\u306E\u9375.join(" / ")} \u306E\u3069\u308C\u304B 1 \u3064\u3060\u3051\u3092\u66F8\u304F`
9805
+ });
9806
+ return;
9807
+ }
9808
+ const \u9375 = \u66F8\u3044\u305F[0];
9809
+ if (\u9375 === "diagram") {
9810
+ if (o.diagram !== true) {
9811
+ errors.push({
9812
+ path: `${path}.diagram`,
9813
+ message: "diagram must be true",
9814
+ hint: "\u56F3\u5168\u4F53\u3092\u6307\u3059\u6642\u3060\u3051\u66F8\u304F"
9815
+ });
9816
+ }
9817
+ return;
9818
+ }
9819
+ if (typeof o[\u9375] !== "string" || o[\u9375].trim() === "") {
9820
+ errors.push({ path: `${path}.${\u9375}`, message: `${\u9375} must be a non-empty string` });
9821
+ return;
9822
+ }
9823
+ if (\u9375 === "arrow") {
9824
+ const \u4E21\u7AEF = o.arrow.split("->");
9825
+ if (\u4E21\u7AEF.length !== 2 || \u4E21\u7AEF.some((x) => x.trim() === "")) {
9826
+ errors.push({
9827
+ path: `${path}.arrow`,
9828
+ message: "arrow must be `A -> B`",
9829
+ hint: "\u77E2\u5370\u306E\u4E21\u7AEF\u306E\u540D\u524D\u3092\u66F8\u304F"
9830
+ });
9831
+ }
9832
+ }
9833
+ });
9834
+ }
9835
+ function validateScrolls(v, inputs, formulas, errors) {
9836
+ if (v === void 0) return;
9837
+ if (!v || typeof v !== "object" || Array.isArray(v)) {
9838
+ errors.push({
9839
+ path: "$.scrolls",
9840
+ message: "scrolls must be an object of name to spec",
9841
+ hint: `got ${v === null ? "null" : Array.isArray(v) ? "array" : typeof v}`
9842
+ });
9843
+ return;
9844
+ }
9845
+ const \u65E2\u306B\u5024\u3092\u4F5C\u308B\u540D\u524D = /* @__PURE__ */ new Set();
9846
+ if (Array.isArray(inputs)) {
9847
+ for (const input of inputs) {
9848
+ if (!input || typeof input !== "object" || Array.isArray(input)) continue;
9849
+ const id = input.id;
9850
+ if (typeof id === "string") \u65E2\u306B\u5024\u3092\u4F5C\u308B\u540D\u524D.add(id);
9851
+ }
9852
+ }
9853
+ if (formulas && typeof formulas === "object" && !Array.isArray(formulas)) {
9854
+ for (const id of Object.keys(formulas)) \u65E2\u306B\u5024\u3092\u4F5C\u308B\u540D\u524D.add(id);
9855
+ }
9856
+ for (const [\u540D\u524D, spec] of Object.entries(v)) {
9857
+ const path = `$.scrolls.${\u540D\u524D}`;
9858
+ if (!isValueName(\u540D\u524D)) {
9859
+ errors.push({ path, ...valueNameIssue(\u540D\u524D) });
9860
+ continue;
9861
+ }
9862
+ if (\u65E2\u306B\u5024\u3092\u4F5C\u308B\u540D\u524D.has(\u540D\u524D)) {
9863
+ errors.push({
9864
+ path,
9865
+ message: `${\u540D\u524D} collides with an input or formula`,
9866
+ hint: "inputs / formulas / scrolls \u3067\u306F\u91CD\u306A\u3089\u306A\u3044\u540D\u524D\u3092\u4F7F\u3046"
9867
+ });
9868
+ }
9869
+ if (!spec || typeof spec !== "object" || Array.isArray(spec)) {
9870
+ errors.push({ path, message: `${\u540D\u524D} must be a plain object`, hint: `got ${typeof spec}` });
9871
+ continue;
9872
+ }
9873
+ for (const [k, x] of Object.entries(spec)) {
9874
+ if (k === "label") {
9875
+ if (typeof x !== "string") {
9876
+ errors.push({ path: `${path}.label`, message: "label must be a string" });
9877
+ }
9878
+ continue;
9879
+ }
9880
+ if (k !== "start" && k !== "end" && k !== "scrub") {
9881
+ errors.push({
9882
+ path: `${path}.${k}`,
9883
+ message: `unknown key "${k}"`,
9884
+ hint: "\u4F7F\u3048\u308B\u9805\u76EE = start, end, scrub, label"
9885
+ });
9886
+ continue;
9887
+ }
9888
+ if (typeof x !== "number" || !Number.isFinite(x)) {
9889
+ errors.push({ path: `${path}.${k}`, message: `${k} must be a finite number` });
9890
+ } else if (x < 0 || x > 1) {
9891
+ errors.push({
9892
+ path: `${path}.${k}`,
9893
+ message: `${k} must be between 0 and 1`,
9894
+ hint: "0 \u3068 1 \u3092\u542B\u3080\u7BC4\u56F2\u3067\u66F8\u304F"
9895
+ });
9896
+ }
9897
+ }
9898
+ }
9899
+ }
8806
9900
  function validateActorShape(v, path, errors) {
8807
9901
  if (v === void 0) return;
8808
9902
  if (!v || typeof v !== "object" || Array.isArray(v)) {
@@ -8977,6 +10071,10 @@ function validateJson(json) {
8977
10071
  const j = \u5199\u3057.value;
8978
10072
  checkUnknownKeys(j, "root", "$", errors);
8979
10073
  validateReadouts(j.readouts, errors);
10074
+ validateInputs(j.inputs, errors);
10075
+ validateFormulas(j.formulas, j.inputs, errors);
10076
+ validateEvents(j.events, errors);
10077
+ validateScrolls(j.scrolls, j.inputs, j.formulas, errors);
8980
10078
  \u8868\u3067\u691C\u67FB(j, "root", "$", "", errors);
8981
10079
  if (!Array.isArray(j.actors) || j.actors.length === 0) {
8982
10080
  errors.push({ path: "$.actors", message: "actors must be a non-empty array" });
@@ -9213,6 +10311,12 @@ function jsonToDoc(json) {
9213
10311
  shape: isPart ? void 0 : a.shape,
9214
10312
  visibleIf: isPart ? void 0 : a.visibleIf,
9215
10313
  title: isPart ? void 0 : a.title,
10314
+ // 値に追随する 5 欄 (#1392)。 記法と同じく見本には渡さない
10315
+ wBind: isPart ? void 0 : a.wBind,
10316
+ hBind: isPart ? void 0 : a.hBind,
10317
+ opacity: isPart ? void 0 : a.opacity,
10318
+ renderOffsetX: isPart ? void 0 : a.renderOffsetX,
10319
+ renderOffsetY: isPart ? void 0 : a.renderOffsetY,
9216
10320
  // 普通の箱にしか効かない欄は見本では落とす。 落とす欄の一覧は `見本に効かない欄` が
9217
10321
  // 唯一の出どころで、検査 (#1308) も同じ表を見る = 「検査は通すが組み立てが捨てる」
9218
10322
  // 状態が作れない
@@ -9260,6 +10364,10 @@ function jsonToDoc(json) {
9260
10364
  style: s.style,
9261
10365
  guard: s.guard,
9262
10366
  cardinality: s.cardinality,
10367
+ // 値に追随する 3 欄 (#1396)
10368
+ widthBind: s.widthBind,
10369
+ strokeBind: s.strokeBind,
10370
+ dashOffsetBind: s.dashOffsetBind,
9263
10371
  labelOffsetX: s.labelOffsetX,
9264
10372
  labelOffsetY: s.labelOffsetY,
9265
10373
  overlay: s.overlay,
@@ -9268,6 +10376,19 @@ function jsonToDoc(json) {
9268
10376
  pos: p0
9269
10377
  }));
9270
10378
  const readouts = json.readouts ? [...json.readouts] : void 0;
10379
+ const inputs = json.inputs ? [...json.inputs] : void 0;
10380
+ const events = json.events?.map((e) => ({
10381
+ event: e.on,
10382
+ target: e.diagram === true ? { kind: "diagram" } : e.arrow !== void 0 ? {
10383
+ kind: "edge",
10384
+ from: e.arrow.split("->")[0]?.trim() ?? "",
10385
+ to: e.arrow.split("->")[1]?.trim() ?? ""
10386
+ } : e.lane !== void 0 ? { kind: "lane", name: e.lane } : { kind: "node", name: e.box ?? "" },
10387
+ handlerId: e.handler.trim(),
10388
+ pos: p0
10389
+ }));
10390
+ const scrolls = json.scrolls ? Object.entries(json.scrolls).map(([id, spec]) => ({ id, ...spec })) : void 0;
10391
+ const formulas = json.formulas ? Object.entries(json.formulas).map(([id, expression]) => ({ id, expression, pos: p0 })) : void 0;
9271
10392
  const states = Object.entries(json.states ?? {}).map(([name, initial]) => ({
9272
10393
  name,
9273
10394
  initial,
@@ -9325,6 +10446,10 @@ function jsonToDoc(json) {
9325
10446
  ])
9326
10447
  ) : void 0,
9327
10448
  readouts,
10449
+ inputs,
10450
+ formulas,
10451
+ events,
10452
+ scrolls,
9328
10453
  pos: p0
9329
10454
  };
9330
10455
  }
@@ -9713,6 +10838,36 @@ var diagram_default = {
9713
10838
  required: ["sides"]
9714
10839
  }
9715
10840
  ]
10841
+ },
10842
+ wBind: {
10843
+ type: "string",
10844
+ minLength: 1,
10845
+ pattern: "\\S",
10846
+ description: "\u7BB1\u306E\u5E45\u3092\u5024\u306B\u8FFD\u968F\u3055\u305B\u308B\u3002 \u72B6\u614B\u306E\u540D\u524D\u3092 {\u540D\u524D} \u306E\u5F62\u3067\u66F8\u304F\u3002 \u914D\u7F6E\u8A08\u7B97\u306F\u8FFD\u968F\u524D\u306E\u5927\u304D\u3055\u3092\u4F7F\u3046"
10847
+ },
10848
+ hBind: {
10849
+ type: "string",
10850
+ minLength: 1,
10851
+ pattern: "\\S",
10852
+ description: "\u7BB1\u306E\u9AD8\u3055\u3092\u5024\u306B\u8FFD\u968F\u3055\u305B\u308B\u3002 wBind \u3068\u540C\u3058\u8AAD\u307F\u65B9"
10853
+ },
10854
+ opacity: {
10855
+ type: ["number", "string"],
10856
+ minLength: 1,
10857
+ pattern: "\\S",
10858
+ description: "\u7BB1\u306E\u6FC3\u3055\u3002 0 \u304B\u3089 1 \u306E\u6570\u304B\u3001\u72B6\u614B\u306E\u540D\u524D\u3002 \u66F8\u304B\u306A\u3051\u308C\u3070\u5B8C\u5168\u306B\u898B\u3048\u308B"
10859
+ },
10860
+ renderOffsetX: {
10861
+ type: ["number", "string"],
10862
+ minLength: 1,
10863
+ pattern: "\\S",
10864
+ description: "\u63CF\u304F\u6642\u3060\u3051\u7BB1\u3092\u6A2A\u3078\u305A\u3089\u3059\u91CF\u3002 \u914D\u7F6E\u8A08\u7B97\u3068\u77E2\u5370\u306F\u305A\u3089\u3059\u524D\u306E\u4F4D\u7F6E\u3092\u4F7F\u3046"
10865
+ },
10866
+ renderOffsetY: {
10867
+ type: ["number", "string"],
10868
+ minLength: 1,
10869
+ pattern: "\\S",
10870
+ description: "\u63CF\u304F\u6642\u3060\u3051\u7BB1\u3092\u7E26\u3078\u305A\u3089\u3059\u91CF\u3002 renderOffsetX \u3068\u540C\u3058\u8AAD\u307F\u65B9"
9716
10871
  }
9717
10872
  }
9718
10873
  }
@@ -9804,6 +10959,24 @@ var diagram_default = {
9804
10959
  type: "number"
9805
10960
  }
9806
10961
  }
10962
+ },
10963
+ widthBind: {
10964
+ type: "string",
10965
+ minLength: 1,
10966
+ pattern: "\\S",
10967
+ description: "\u7DDA\u306E\u592A\u3055\u3092\u5024\u306B\u8FFD\u968F\u3055\u305B\u308B\u3002 \u72B6\u614B\u3084\u3064\u307E\u307F\u306E\u540D\u524D\u3092 {\u540D\u524D} \u306E\u5F62\u3067\u66F8\u304F"
10968
+ },
10969
+ strokeBind: {
10970
+ type: "string",
10971
+ minLength: 1,
10972
+ pattern: "\\S",
10973
+ description: "\u7DDA\u306E\u8272\u3092\u5024\u306B\u8FFD\u968F\u3055\u305B\u308B\u3002 widthBind \u3068\u540C\u3058\u8AAD\u307F\u65B9"
10974
+ },
10975
+ dashOffsetBind: {
10976
+ type: "string",
10977
+ minLength: 1,
10978
+ pattern: "\\S",
10979
+ description: "\u7834\u7DDA\u306E\u4F4D\u7F6E\u3092\u5024\u306B\u8FFD\u968F\u3055\u305B\u308B (\u6D41\u308C\u3066\u3044\u308B\u3088\u3046\u306B\u898B\u305B\u308B)\u3002 widthBind \u3068\u540C\u3058\u8AAD\u307F\u65B9"
9807
10980
  }
9808
10981
  }
9809
10982
  }
@@ -10830,6 +12003,314 @@ var diagram_default = {
10830
12003
  }
10831
12004
  ]
10832
12005
  }
12006
+ },
12007
+ inputs: {
12008
+ type: "array",
12009
+ description: "\u8AAD\u3080\u4EBA\u304C\u52D5\u304B\u3059\u3064\u307E\u307F\u3002 \u5024\u3092\u63E1\u308A\u3001\u7BB1\u306E\u6587\u5B57\u3084\u90E8\u54C1\u304C\u305D\u306E\u5024\u3092\u8FFD\u3044\u304B\u3051\u308B\u3002 \u7BB1\u3067\u306F\u306A\u3044\u306E\u3067\u7E26\u5217\u306B\u8F09\u3089\u305A\u3001\u56F3\u5168\u4F53\u306B 1 \u3064\u306E\u4E26\u3073\u3068\u3057\u3066\u6301\u3064\u3002",
12010
+ items: {
12011
+ type: "object",
12012
+ required: ["id", "kind"],
12013
+ additionalProperties: false,
12014
+ properties: {
12015
+ id: {
12016
+ type: "string",
12017
+ minLength: 1
12018
+ },
12019
+ kind: {
12020
+ type: "string",
12021
+ enum: [
12022
+ "color",
12023
+ "datetime",
12024
+ "dropdown",
12025
+ "multi-select",
12026
+ "number",
12027
+ "radio",
12028
+ "range",
12029
+ "slider",
12030
+ "stepper",
12031
+ "tabs",
12032
+ "text",
12033
+ "timeline",
12034
+ "toggle",
12035
+ "xypad"
12036
+ ]
12037
+ },
12038
+ autoplay: {
12039
+ type: "boolean"
12040
+ },
12041
+ defaultHi: {
12042
+ type: "number"
12043
+ },
12044
+ defaultLo: {
12045
+ type: "number"
12046
+ },
12047
+ defaultSpeedIdx: {
12048
+ type: "number"
12049
+ },
12050
+ defaultValue: {
12051
+ type: ["boolean", "number", "string"]
12052
+ },
12053
+ defaultValues: {
12054
+ type: "array",
12055
+ items: {
12056
+ type: "string"
12057
+ }
12058
+ },
12059
+ defaultX: {
12060
+ type: "number"
12061
+ },
12062
+ defaultY: {
12063
+ type: "number"
12064
+ },
12065
+ duration: {
12066
+ type: "number"
12067
+ },
12068
+ label: {
12069
+ type: "string"
12070
+ },
12071
+ loop: {
12072
+ type: "boolean"
12073
+ },
12074
+ max: {
12075
+ type: "number"
12076
+ },
12077
+ maxLength: {
12078
+ type: "number"
12079
+ },
12080
+ min: {
12081
+ type: "number"
12082
+ },
12083
+ options: {
12084
+ type: "array",
12085
+ items: {
12086
+ type: "string"
12087
+ }
12088
+ },
12089
+ placeholder: {
12090
+ type: "string"
12091
+ },
12092
+ speeds: {
12093
+ type: "array",
12094
+ items: {
12095
+ type: "number"
12096
+ }
12097
+ },
12098
+ step: {
12099
+ type: "number"
12100
+ },
12101
+ xMax: {
12102
+ type: "number"
12103
+ },
12104
+ xMin: {
12105
+ type: "number"
12106
+ },
12107
+ yMax: {
12108
+ type: "number"
12109
+ },
12110
+ yMin: {
12111
+ type: "number"
12112
+ }
12113
+ },
12114
+ oneOf: [
12115
+ {
12116
+ properties: {
12117
+ kind: {
12118
+ enum: ["color", "datetime", "text"]
12119
+ },
12120
+ defaultValue: {
12121
+ type: "string"
12122
+ }
12123
+ },
12124
+ required: ["defaultValue"]
12125
+ },
12126
+ {
12127
+ properties: {
12128
+ kind: {
12129
+ enum: ["dropdown", "radio", "tabs"]
12130
+ },
12131
+ defaultValue: {
12132
+ type: "string"
12133
+ }
12134
+ },
12135
+ required: ["options", "defaultValue"]
12136
+ },
12137
+ {
12138
+ properties: {
12139
+ kind: {
12140
+ enum: ["multi-select"]
12141
+ }
12142
+ },
12143
+ required: ["options", "defaultValues"]
12144
+ },
12145
+ {
12146
+ properties: {
12147
+ kind: {
12148
+ enum: ["number", "stepper"]
12149
+ },
12150
+ defaultValue: {
12151
+ type: "number"
12152
+ }
12153
+ },
12154
+ required: ["defaultValue"]
12155
+ },
12156
+ {
12157
+ properties: {
12158
+ kind: {
12159
+ enum: ["range"]
12160
+ }
12161
+ },
12162
+ required: ["min", "max", "defaultLo", "defaultHi"]
12163
+ },
12164
+ {
12165
+ properties: {
12166
+ kind: {
12167
+ enum: ["slider"]
12168
+ },
12169
+ defaultValue: {
12170
+ type: "number"
12171
+ }
12172
+ },
12173
+ required: ["min", "max", "defaultValue"]
12174
+ },
12175
+ {
12176
+ properties: {
12177
+ kind: {
12178
+ enum: ["timeline"]
12179
+ }
12180
+ },
12181
+ required: ["duration"]
12182
+ },
12183
+ {
12184
+ properties: {
12185
+ kind: {
12186
+ enum: ["toggle"]
12187
+ },
12188
+ defaultValue: {
12189
+ type: "boolean"
12190
+ }
12191
+ },
12192
+ required: ["defaultValue"]
12193
+ },
12194
+ {
12195
+ properties: {
12196
+ kind: {
12197
+ enum: ["xypad"]
12198
+ }
12199
+ },
12200
+ required: ["xMin", "xMax", "yMin", "yMax", "defaultX", "defaultY"]
12201
+ }
12202
+ ]
12203
+ }
12204
+ },
12205
+ formulas: {
12206
+ type: "object",
12207
+ description: '\u3064\u307E\u307F\u306E\u5024\u304B\u3089\u6C7A\u307E\u308B\u5024\u3002 \u540D\u524D\u3092\u9375\u3001\u5F0F\u3092\u5024\u306B\u66F8\u304F\u3002 `values` \u3068\u306F\u7D4C\u8DEF\u304C\u5225\u3067\u3001\u5F0F\u306F\u540D\u524D\u3092\u4E2D\u62EC\u5F27\u3067\u56F2\u308F\u306A\u3044 (\u4F8B "input * 2")\u3002',
12208
+ additionalProperties: {
12209
+ type: "string",
12210
+ minLength: 1,
12211
+ pattern: "\\S"
12212
+ },
12213
+ propertyNames: {
12214
+ pattern: "^[A-Za-z_][A-Za-z0-9_]*$"
12215
+ }
12216
+ },
12217
+ events: {
12218
+ type: "array",
12219
+ description: "\u62BC\u4E0B\u306A\u3069\u306E\u51FA\u6765\u4E8B\u3067\u52D5\u304F\u4ED5\u639B\u3051\u3002 \u76F8\u624B\u306F\u540D\u524D\u3067\u6307\u3059 (box / lane / arrow / diagram \u306E\u3069\u308C\u304B 1 \u3064)\u3002",
12220
+ items: {
12221
+ type: "object",
12222
+ required: ["on", "handler"],
12223
+ additionalProperties: false,
12224
+ properties: {
12225
+ on: {
12226
+ type: "string",
12227
+ enum: [
12228
+ "click",
12229
+ "hover",
12230
+ "double-click",
12231
+ "long-press",
12232
+ "drag",
12233
+ "drop",
12234
+ "keydown",
12235
+ "focus",
12236
+ "blur"
12237
+ ]
12238
+ },
12239
+ handler: {
12240
+ type: "string",
12241
+ minLength: 1,
12242
+ pattern: "\\S"
12243
+ },
12244
+ box: {
12245
+ type: "string",
12246
+ minLength: 1,
12247
+ description: "\u7BB1\u306E\u540D\u524D"
12248
+ },
12249
+ lane: {
12250
+ type: "string",
12251
+ minLength: 1,
12252
+ description: "\u7E26\u5217\u306E\u540D\u524D"
12253
+ },
12254
+ arrow: {
12255
+ type: "string",
12256
+ minLength: 1,
12257
+ pattern: "^(?!.*->.*->)\\s*\\S(?:.*\\S)?\\s*->\\s*\\S(?:.*\\S)?\\s*$",
12258
+ description: "\u77E2\u5370\u3002 `A -> B` \u306E\u5F62\u3067\u4E21\u7AEF\u306E\u540D\u524D\u3092\u66F8\u304F"
12259
+ },
12260
+ diagram: {
12261
+ const: true,
12262
+ description: "\u56F3\u5168\u4F53\u3092\u6307\u3059"
12263
+ }
12264
+ },
12265
+ oneOf: [
12266
+ {
12267
+ required: ["box"]
12268
+ },
12269
+ {
12270
+ required: ["lane"]
12271
+ },
12272
+ {
12273
+ required: ["arrow"]
12274
+ },
12275
+ {
12276
+ required: ["diagram"]
12277
+ }
12278
+ ]
12279
+ }
12280
+ },
12281
+ scrolls: {
12282
+ type: "object",
12283
+ description: "\u5DFB\u304D\u4E0A\u3052\u306B\u5FDC\u3058\u3066\u9032\u3080\u5024\u3002 \u753B\u9762\u3092\u5DFB\u304D\u4E0A\u3052\u305F\u91CF\u304B\u3089 0 \u304B\u3089 1 \u306E\u9032\u307F\u5177\u5408\u3092\u4F5C\u308B\u3002",
12284
+ propertyNames: {
12285
+ pattern: "^[A-Za-z_][A-Za-z0-9_]*$"
12286
+ },
12287
+ additionalProperties: {
12288
+ type: "object",
12289
+ additionalProperties: false,
12290
+ properties: {
12291
+ start: {
12292
+ type: "number",
12293
+ minimum: 0,
12294
+ maximum: 1,
12295
+ description: "\u9032\u307F\u5177\u5408\u304C 0 \u306B\u306A\u308B\u753B\u9762\u4E0A\u306E\u4F4D\u7F6E (0 \u304C\u4E0A\u7AEF\u30011 \u304C\u4E0B\u7AEF)"
12296
+ },
12297
+ end: {
12298
+ type: "number",
12299
+ minimum: 0,
12300
+ maximum: 1,
12301
+ description: "\u9032\u307F\u5177\u5408\u304C 1 \u306B\u306A\u308B\u753B\u9762\u4E0A\u306E\u4F4D\u7F6E"
12302
+ },
12303
+ scrub: {
12304
+ type: "number",
12305
+ minimum: 0,
12306
+ maximum: 1,
12307
+ description: "\u5DFB\u304D\u4E0A\u3052\u3078\u306E\u8FFD\u968F\u5EA6\u5408\u3044 (0 \u304C\u6BB5\u968E\u7684\u30011 \u304C\u9023\u7D9A)"
12308
+ },
12309
+ label: {
12310
+ type: "string"
12311
+ }
12312
+ }
12313
+ }
10833
12314
  }
10834
12315
  }
10835
12316
  };