@cardenelabs/cdl 0.82.0 → 0.102.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 (43) hide show
  1. package/CHANGELOG.md +874 -1
  2. package/dist/index.cjs +882 -187
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +17 -3
  5. package/dist/index.d.ts +17 -3
  6. package/dist/index.js +882 -187
  7. package/dist/index.js.map +1 -1
  8. package/dist/react.cjs +869 -178
  9. package/dist/react.cjs.map +1 -1
  10. package/dist/react.d.cts +1 -1
  11. package/dist/react.d.ts +1 -1
  12. package/dist/react.js +869 -178
  13. package/dist/react.js.map +1 -1
  14. package/dist/{render-DfXCs3Eh.d.cts → render-oEmwYN-q.d.cts} +21 -3
  15. package/dist/{render-DfXCs3Eh.d.ts → render-oEmwYN-q.d.ts} +21 -3
  16. package/package.json +1 -1
  17. package/src/kinds/chart-gauge.tsx +20 -3
  18. package/src/kinds/chart-legend-number.tsx +33 -0
  19. package/src/kinds/chart-number.ts +33 -0
  20. package/src/kinds/chart-radial.tsx +24 -7
  21. package/src/kinds/chart-stat.tsx +35 -5
  22. package/src/kinds/chart-waffle.tsx +25 -7
  23. package/src/kinds/dyn-shape.tsx +72 -12
  24. package/src/kinds/funnel.tsx +50 -2
  25. package/src/kinds/mind-map.tsx +206 -64
  26. package/src/kinds/quadrant.tsx +318 -45
  27. package/src/kinds/shape-blockchain.tsx +50 -18
  28. package/src/kinds/shape-commerce.tsx +27 -4
  29. package/src/kinds/shape-region.tsx +42 -1
  30. package/src/kinds/shape-software.tsx +51 -12
  31. package/src/kinds/storage.tsx +16 -8
  32. package/src/kinds/tree.tsx +46 -10
  33. package/src/lang.ts +5 -5
  34. package/src/layout/nodes.ts +3 -1
  35. package/src/layout/spec.ts +154 -25
  36. package/src/layout/text-width.ts +25 -0
  37. package/src/layout/viewbox.ts +32 -0
  38. package/src/presets.ts +24 -7
  39. package/src/render/nodes.tsx +77 -0
  40. package/src/render/payload-binding.ts +108 -25
  41. package/src/render/stage.tsx +24 -2
  42. package/src/types.ts +117 -38
  43. package/src/visual-validate.ts +61 -1
package/dist/index.js CHANGED
@@ -356,22 +356,22 @@ function resolveLang(value) {
356
356
  return value === "ja" ? "ja" : "en";
357
357
  }
358
358
  var en = {
359
- /** `shape-terminal` の 2 行目 (命令の出力) */
360
359
  /*
361
- * `shape-terminal` の出力の行。
360
+ * `shape-terminal` の出力の行を **書かない時** の控え (#927)。
362
361
  *
363
362
  * **いちばん長い行が絵の倍率を決める** (#891)。 端末の中身は自分の座標で組んでから箱へ
364
363
  * 収めるので、この行が長いほど全部の字が小さくなる。 120x110 の箱では 20 字の版で
365
- * 7.71 world まで落ちていた。
364
+ * 7.71 world まで落ちていた。 書いた説明を通すようになったので、長い説明を渡した図でも
365
+ * 同じことが起きる。
366
366
  */
367
367
  "terminal.output": "\u2192 12 chunks",
368
- /** `shape-code-block` の札の file 名 */
368
+ /** `shape-code-block` の札の file 名を **書かない時** の控え (#927) */
369
369
  "codeBlock.fileName": "utils.ts",
370
370
  /** `shape-kanban-card` の課題の番号 */
371
371
  "kanbanCard.id": "CAR-1111",
372
372
  /** `shape-kanban-card` の状態の札 */
373
373
  "kanbanCard.status": "IN PROG",
374
- /** `shape-kanban-card` の題の下の説明 */
374
+ /** `shape-kanban-card` の題の下の説明を **書かない時** の控え (#927) */
375
375
  "kanbanCard.task": "shape-driven kind \u5B9F\u88C5",
376
376
  /** `shape-kanban-card` の期日 */
377
377
  "kanbanCard.due": "Jul 10",
@@ -12301,6 +12301,11 @@ function measureTextWidth(text, opts = {}) {
12301
12301
  const w = advanceEmSum * fontSize + letterSpacing * charCount;
12302
12302
  return Math.max(w, fontSize * 1.2);
12303
12303
  }
12304
+ function \u53CE\u3081\u308B\u500D\u7387(text, opts, \u5E45) {
12305
+ if (!(\u5E45 > 0) || !(opts.fontSize > 0)) return 1;
12306
+ const \u5B9F\u5E45 = measureTextWidth(text, { ...opts, letterSpacing: 0 });
12307
+ return \u5B9F\u5E45 > \u5E45 ? \u5E45 / \u5B9F\u5E45 : 1;
12308
+ }
12304
12309
 
12305
12310
  // src/label-text.ts
12306
12311
  var EDGE_LABEL_TEXT = {
@@ -12335,17 +12340,7 @@ var LABEL_PILL_PAD_X = 18;
12335
12340
  function hasRenderedLabel(e) {
12336
12341
  return Boolean(e.label?.trim() || e.sub?.trim());
12337
12342
  }
12338
- var KINDS_WITHOUT_TITLE_TEXT = /* @__PURE__ */ new Set([
12339
- // 時系列のやり取り (#578)。 図を丸ごと描く種別で、描くのは面々の名前と言づての語。
12340
- // 箱の `title` は使わない
12341
- "sequence-board",
12342
- // 形だけを描く (DynShapeNode)
12343
- "dyn-rect",
12344
- "dyn-circle",
12345
- "dyn-arc",
12346
- "dyn-wave",
12347
- "dyn-polygon",
12348
- // payload を自前 layout して描く (label は payload 側が持つ)
12343
+ var KINDS_DRAWING_OWN_PAYLOAD = /* @__PURE__ */ new Set([
12349
12344
  "chart-pie",
12350
12345
  "chart-line",
12351
12346
  "chart-bar",
@@ -12360,22 +12355,27 @@ var KINDS_WITHOUT_TITLE_TEXT = /* @__PURE__ */ new Set([
12360
12355
  "funnel-stages",
12361
12356
  "quadrant-matrix",
12362
12357
  "tree-hierarchy",
12363
- "journey-map",
12364
- // 印そのものが意味を持つ (#560)
12358
+ "journey-map"
12359
+ ]);
12360
+ function drawsFigureTitle(kind) {
12361
+ return KINDS_DRAWING_OWN_PAYLOAD.has(kind ?? "");
12362
+ }
12363
+ var KINDS_WITHOUT_TITLE_TEXT = /* @__PURE__ */ new Set([
12364
+ "sequence-board",
12365
12365
  "mark-start",
12366
12366
  "mark-end"
12367
12367
  ]);
12368
12368
  function rendersTitleText(kind) {
12369
12369
  return !KINDS_WITHOUT_TITLE_TEXT.has(kind ?? "");
12370
12370
  }
12371
- var KINDS_FITTING_OWN_TITLE = /* @__PURE__ */ new Set(["shape-blockchain-block"]);
12371
+ var KINDS_FITTING_OWN_TITLE = /* @__PURE__ */ new Set([
12372
+ "shape-blockchain-block",
12373
+ ...KINDS_DRAWING_OWN_PAYLOAD
12374
+ ]);
12372
12375
  function fitsOwnTitleWidth(kind) {
12373
12376
  return KINDS_FITTING_OWN_TITLE.has(kind ?? "");
12374
12377
  }
12375
- var KINDS_WITH_ROW_TEXT = /* @__PURE__ */ new Set([
12376
- // 専用の表組み (StorageNode)
12377
- "storage",
12378
- // 汎用描画 (GenericNode)
12378
+ var KINDS_DRAWN_BY_GENERIC = [
12379
12379
  "person",
12380
12380
  "user-group",
12381
12381
  "admin",
@@ -12397,10 +12397,44 @@ var KINDS_WITH_ROW_TEXT = /* @__PURE__ */ new Set([
12397
12397
  "oracle",
12398
12398
  "merkle-tree",
12399
12399
  "decision"
12400
+ ];
12401
+ var KINDS_WITH_ROW_TEXT = /* @__PURE__ */ new Set([
12402
+ // 専用の表組み (StorageNode)
12403
+ "storage",
12404
+ ...KINDS_DRAWN_BY_GENERIC
12400
12405
  ]);
12401
12406
  function rendersRows(kind) {
12402
12407
  return KINDS_WITH_ROW_TEXT.has(kind ?? "");
12403
12408
  }
12409
+ var KINDS_DRAWING_ONLY_SHAPE = [
12410
+ "dyn-rect",
12411
+ "dyn-circle",
12412
+ "dyn-arc",
12413
+ "dyn-wave",
12414
+ "dyn-polygon"
12415
+ ];
12416
+ var KINDS_WITHOUT_EYEBROW_TEXT = /* @__PURE__ */ new Set([
12417
+ ...KINDS_DRAWING_ONLY_SHAPE,
12418
+ ...KINDS_WITHOUT_TITLE_TEXT
12419
+ ]);
12420
+ function rendersEyebrow(kind) {
12421
+ return !KINDS_WITHOUT_EYEBROW_TEXT.has(kind ?? "");
12422
+ }
12423
+ var KINDS_WITHOUT_SUBTITLE_TEXT = /* @__PURE__ */ new Set([
12424
+ ...KINDS_DRAWING_OWN_PAYLOAD,
12425
+ ...KINDS_WITHOUT_TITLE_TEXT
12426
+ ]);
12427
+ function rendersSubtitle(kind) {
12428
+ return !KINDS_WITHOUT_SUBTITLE_TEXT.has(kind ?? "");
12429
+ }
12430
+ var KINDS_WITH_VALUE_TEXT = /* @__PURE__ */ new Set([
12431
+ // 面々の絵 (ActorNode)
12432
+ "actor",
12433
+ ...KINDS_DRAWN_BY_GENERIC
12434
+ ]);
12435
+ function rendersValue(kind) {
12436
+ return KINDS_WITH_VALUE_TEXT.has(kind ?? "");
12437
+ }
12404
12438
  function rowBaselineY(kind, index) {
12405
12439
  if (!rendersRows(kind)) return null;
12406
12440
  return kind === "storage" ? ROW_TOP_STORAGE + index * ROW_PITCH_STORAGE : ROW_TOP_GENERIC + genericTextShift(kind) + index * ROW_PITCH_GENERIC;
@@ -14539,6 +14573,15 @@ var EDGE_REVEALS = ["phase", "all"];
14539
14573
  var RELATION_FOCUSES = ["off", "hover"];
14540
14574
  var RELATION_FOCUS_DEFAULT = "off";
14541
14575
  var EDGE_REVEAL_DEFAULT = "phase";
14576
+ function \u66F8\u3044\u305F\u5024\u304B\u63A7\u3048(\u66F8\u3044\u305F, \u63A7\u3048) {
14577
+ const v = (\u66F8\u3044\u305F ?? "").trim();
14578
+ return v === "" ? \u63A7\u3048 : v;
14579
+ }
14580
+ function \u5E45\u306E\u500D\u7387(text, size, letterSpacing, \u5E45) {
14581
+ if (!(\u5E45 > 0) || !(size > 0)) return 1;
14582
+ const \u5B9F\u5E45 = textWidth(text, size, letterSpacing);
14583
+ return \u5B9F\u5E45 > \u5E45 ? \u5E45 / \u5B9F\u5E45 : 1;
14584
+ }
14542
14585
  var TITLE_MAX = 18;
14543
14586
  var TITLE_MIN = 9;
14544
14587
  var TITLE_RATIO = 0.17;
@@ -14565,7 +14608,10 @@ var \u843D\u3068\u3057\u3066\u3082\u63CF\u304F\u7A2E\u5225 = {
14565
14608
  "shape-code-block",
14566
14609
  "shape-message-bubble",
14567
14610
  "shape-gear",
14568
- // hardware 系のうち固有 layout を持つもの
14611
+ // 絵の中の字の口に肩書を通す 2 種別 (#941)。 状態の札 / 見出しの帯の右 に描く
14612
+ "shape-kanban-card",
14613
+ "shape-blockchain-block",
14614
+ // hardware / blockchain 系のうち固有 layout を持つもの
14569
14615
  "shape-iot-sensor",
14570
14616
  "shape-robot-arm"
14571
14617
  ]),
@@ -14582,6 +14628,10 @@ var \u843D\u3068\u3057\u3066\u3082\u63CF\u304F\u7A2E\u5225 = {
14582
14628
  "shape-window",
14583
14629
  "shape-message-bubble",
14584
14630
  "shape-gear",
14631
+ // 絵の中の字の口に説明を通す 3 種別 (#927)。 札の file 名 / 出力の行 / 課題の 1 行 に描く
14632
+ "shape-terminal",
14633
+ "shape-code-block",
14634
+ "shape-kanban-card",
14585
14635
  // hardware / blockchain 系のうち固有 layout を持つもの
14586
14636
  "shape-iot-sensor",
14587
14637
  "shape-robot-arm",
@@ -15337,7 +15387,9 @@ function needsResolve(raw) {
15337
15387
  return typeof raw !== "number" || !Number.isFinite(raw);
15338
15388
  }
15339
15389
  function resolveChartData(data, values) {
15340
- if (!data.some((d) => needsResolve(d.value) || d.previous !== void 0 && needsResolve(d.previous)))
15390
+ if (!data.some(
15391
+ (d) => needsResolve(d.value) || d.previous !== void 0 && needsResolve(d.previous)
15392
+ ))
15341
15393
  return data;
15342
15394
  return data.map((d) => {
15343
15395
  const v = resolveBoundNumber(d.value, values, 0);
@@ -15348,14 +15400,24 @@ function resolveChartData(data, values) {
15348
15400
  });
15349
15401
  }
15350
15402
  function resolveFunnelData(stages, values) {
15351
- if (!stages.some((s) => needsResolve(s.count))) return stages;
15403
+ const \u8AAD\u3080 = stages.some(
15404
+ (s) => needsResolve(s.count) || (s.subtitle?.includes("{") ?? false)
15405
+ );
15406
+ if (!\u8AAD\u3080) return stages;
15352
15407
  return stages.map((s) => {
15353
15408
  const c = resolveBoundNumber(s.count, values, 0);
15354
- return c.ok ? { ...s, count: c.value } : { ...s, count: c.value, unresolved: true };
15409
+ const sub = s.subtitle === void 0 ? void 0 : resolveBoundText(s.subtitle, values);
15410
+ const \u7D20 = {
15411
+ ...s,
15412
+ count: c.value,
15413
+ ...sub ? { subtitle: sub.value } : {}
15414
+ };
15415
+ return c.ok && (sub?.ok ?? true) ? \u7D20 : { ...\u7D20, unresolved: true };
15355
15416
  });
15356
15417
  }
15357
15418
  function resolveGanttData(tasks, values) {
15358
- if (!tasks.some((t) => needsResolve(t.startIdx) || needsResolve(t.endIdx))) return tasks;
15419
+ if (!tasks.some((t) => needsResolve(t.startIdx) || needsResolve(t.endIdx)))
15420
+ return tasks;
15359
15421
  return tasks.map((t) => {
15360
15422
  const start = resolveBoundNumber(t.startIdx, values, 0);
15361
15423
  const end = resolveBoundNumber(t.endIdx, values, start.value);
@@ -15363,16 +15425,48 @@ function resolveGanttData(tasks, values) {
15363
15425
  return start.ok && end.ok ? next : { ...next, unresolved: true };
15364
15426
  });
15365
15427
  }
15428
+ function \u5EA7\u6A19\u306E\u8C61\u9650(x, y) {
15429
+ const \u53F3 = x >= 0.5;
15430
+ const \u4E0A = y >= 0.5;
15431
+ if (\u4E0A) return \u53F3 ? "topRight" : "topLeft";
15432
+ return \u53F3 ? "bottomRight" : "bottomLeft";
15433
+ }
15434
+ var \u57DF\u306B\u53CE\u3081\u308B = (v) => Math.min(1, Math.max(0, v));
15366
15435
  function resolveQuadrantData(data, values) {
15367
15436
  const items = data.items;
15368
- if (items.every((i) => QUADRANT_KEYS.includes(i.quadrant))) {
15369
- return data;
15370
- }
15437
+ const \u8FD1\u9053 = !items.some((i) => i.at !== void 0) && !items.some((i) => i.subtitle?.includes("{") ?? false) && items.every((i) => QUADRANT_KEYS.includes(i.quadrant ?? ""));
15438
+ if (\u8FD1\u9053) return data;
15371
15439
  return {
15372
15440
  ...data,
15373
15441
  items: items.map((i) => {
15374
- const q = resolveBoundEnum(i.quadrant, values, QUADRANT_KEYS, QUADRANT_FALLBACK);
15375
- return q.ok ? { ...i, quadrant: q.value } : { ...i, quadrant: q.value, unresolved: true };
15442
+ if (i.at !== void 0) {
15443
+ const x = resolveBoundNumber(i.at.x, values, 0.5);
15444
+ const y = resolveBoundNumber(i.at.y, values, 0.5);
15445
+ const \u7F6E\u304F = { x: \u57DF\u306B\u53CE\u3081\u308B(x.value), y: \u57DF\u306B\u53CE\u3081\u308B(y.value) };
15446
+ const sub2 = i.subtitle === void 0 ? void 0 : resolveBoundText(i.subtitle, values);
15447
+ const \u7D202 = {
15448
+ id: i.id,
15449
+ title: i.title,
15450
+ at: \u7F6E\u304F,
15451
+ quadrant: \u5EA7\u6A19\u306E\u8C61\u9650(\u7F6E\u304F.x, \u7F6E\u304F.y),
15452
+ ...sub2 ? { subtitle: sub2.value } : {}
15453
+ };
15454
+ return x.ok && y.ok && (sub2?.ok ?? true) ? \u7D202 : { ...\u7D202, unresolved: true };
15455
+ }
15456
+ const q = resolveBoundEnum(
15457
+ i.quadrant ?? "",
15458
+ values,
15459
+ QUADRANT_KEYS,
15460
+ QUADRANT_FALLBACK
15461
+ );
15462
+ const sub = i.subtitle === void 0 ? void 0 : resolveBoundText(i.subtitle, values);
15463
+ const \u7D20 = {
15464
+ id: i.id,
15465
+ title: i.title,
15466
+ quadrant: q.value,
15467
+ ...sub ? { subtitle: sub.value } : {}
15468
+ };
15469
+ return q.ok && (sub?.ok ?? true) ? \u7D20 : { ...\u7D20, unresolved: true };
15376
15470
  })
15377
15471
  };
15378
15472
  }
@@ -15492,13 +15586,10 @@ var PAD_TOP = 40;
15492
15586
  var PAD_RIGHT = 24;
15493
15587
  var PAD_BOTTOM = 40;
15494
15588
  var PAD_LEFT = 24;
15589
+ var \u6728\u306E\u679D\u306E\u592A\u3055 = (\u6BB5) => Math.max(1.1, 2.6 - \u6BB5 * 0.45);
15495
15590
  function \u6728\u306E\u4E2D\u8EAB(node, stateValues = {}) {
15496
15591
  const treeNodes = resolveTreeData(node.treeData ?? [], stateValues);
15497
- return computeTreeLayout(
15498
- treeNodes,
15499
- node.w - PAD_LEFT - PAD_RIGHT,
15500
- node.h - PAD_TOP - PAD_BOTTOM
15501
- );
15592
+ return computeTreeLayout(treeNodes, node.w - PAD_LEFT - PAD_RIGHT, node.h - PAD_TOP - PAD_BOTTOM);
15502
15593
  }
15503
15594
  function \u6728\u306E\u884C(n) {
15504
15595
  return [
@@ -15557,7 +15648,7 @@ function TreeNode({
15557
15648
  fill: "none",
15558
15649
  stroke: TONE.accent,
15559
15650
  strokeOpacity: 0.55,
15560
- strokeWidth: 1.5,
15651
+ strokeWidth: \u6728\u306E\u679D\u306E\u592A\u3055(e.depth),
15561
15652
  strokeLinejoin: "round",
15562
15653
  ...\u4F38\u3070\u3059dash(drawing, \u679D\u306E\u4F38\u3073)
15563
15654
  }
@@ -15692,11 +15783,20 @@ function computeTreeLayout(treeNodes, canvasW, canvasH) {
15692
15783
  if (kids.length === 0) return 1;
15693
15784
  return kids.reduce((sum, k) => sum + leafCount(k.id, seen), 0);
15694
15785
  };
15695
- const totalLeaves = Math.max(roots.reduce((sum, r) => sum + leafCount(r.id, /* @__PURE__ */ new Set()), 0), 1);
15786
+ const totalLeaves = Math.max(
15787
+ roots.reduce((sum, r) => sum + leafCount(r.id, /* @__PURE__ */ new Set()), 0),
15788
+ 1
15789
+ );
15696
15790
  const depthGap = canvasH / Math.max(maxDepth + 1, 1);
15697
15791
  const slotW = canvasW / totalLeaves;
15698
15792
  const nodeH = Math.min(38, depthGap * 0.7);
15699
15793
  const nodeW = Math.min(140, slotW * 0.85);
15794
+ const \u7BB1\u306E\u5E45 = (n, depth) => {
15795
+ const \u6750\u6599 = \u6728\u306E\u884C({ ...n, depth });
15796
+ const \u540D\u524D = \u6750\u6599[0];
15797
+ const \u8981\u308B = measureTextWidth(\u540D\u524D.text, { fontSize: \u540D\u524D.fontSize}) + (nodeW - \u4F7F\u3048\u308B\u5E45(nodeW));
15798
+ return Math.min(Math.max(\u8981\u308B, nodeW), slotW * 0.92);
15799
+ };
15700
15800
  const posOf = /* @__PURE__ */ new Map();
15701
15801
  const nodes = [];
15702
15802
  const placed = /* @__PURE__ */ new Set();
@@ -15720,7 +15820,7 @@ function computeTreeLayout(treeNodes, canvasW, canvasH) {
15720
15820
  ...n.subtitle !== void 0 ? { subtitle: n.subtitle } : {},
15721
15821
  x,
15722
15822
  y,
15723
- w: nodeW,
15823
+ w: \u7BB1\u306E\u5E45(n, depth),
15724
15824
  h: nodeH,
15725
15825
  depth,
15726
15826
  ...n.unresolved ? { unresolved: true } : {}
@@ -15771,6 +15871,10 @@ function computeTreeLayout(treeNodes, canvasW, canvasH) {
15771
15871
  }
15772
15872
  var MIND_TONES = ["accent", "teal", "success", "warning", "info", "error"];
15773
15873
  var MIND_BOX_GAP = 24;
15874
+ var \u679D\u306E\u592A\u3055 = (\u6BB5) => Math.max(1.2, 3.2 - \u6BB5 * 0.7);
15875
+ var BRANCH_BOX_H_MAX = 48;
15876
+ var SUB_BOX_H_MAX = 40;
15877
+ var ROW_GAP_MAX = 96;
15774
15878
  var MIND_PAD = 40;
15775
15879
  function \u653E\u5C04\u306E\u4E2D\u8EAB(node, stateValues = {}) {
15776
15880
  const mindData = node.mindData ? resolveMindData(node.mindData, stateValues) : void 0;
@@ -15827,7 +15931,7 @@ function MindMapNode({
15827
15931
  d: e.d,
15828
15932
  fill: "none",
15829
15933
  stroke: toneColor2(e.tone),
15830
- strokeWidth: 2.5,
15934
+ strokeWidth: \u679D\u306E\u592A\u3055(e.depth),
15831
15935
  strokeOpacity: 0.55,
15832
15936
  strokeLinecap: "round",
15833
15937
  ...\u4F38\u3070\u3059dash(drawing, \u679D\u306E\u4F38\u3073)
@@ -15838,13 +15942,19 @@ function MindMapNode({
15838
15942
  layout2.nodes.map((n) => {
15839
15943
  if (!\u7BB1\u304C\u51FA\u308B(n.depth)) return null;
15840
15944
  const \u6750\u6599 = \u653E\u5C04\u306E\u884C(n);
15841
- const \u884C = \u7BB1\u306B\u7A4D\u3080(\u6750\u6599, n.w, n.h);
15842
15945
  const \u88DC\u8DB3\u3042\u308A = (n.subtitle ?? "").trim() !== "";
15843
15946
  const \u540D\u524D = \u6750\u6599[0];
15844
- 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));
15947
+ const \u67A0\u306A\u3057 = !n.isRoot && n.isLeaf;
15948
+ const \u5916\u3078 = n.side === "right";
15949
+ const \u6587\u5B57\u306Ex = \u67A0\u306A\u3057 ? n.x + (\u5916\u3078 ? -n.w / 2 : n.w / 2) : n.x;
15950
+ const \u6587\u5B57\u306E\u5BC4\u305B = \u67A0\u306A\u3057 ? \u5916\u3078 ? "start" : "end" : "middle";
15951
+ const \u63CF\u753B\u57DF\u306E\u7AEF = \u5916\u3078 ? node.w - MIND_PAD : MIND_PAD;
15952
+ const \u4F7F\u3048\u308B = \u67A0\u306A\u3057 ? Math.abs(\u63CF\u753B\u57DF\u306E\u7AEF - \u6587\u5B57\u306Ex) : \u4F7F\u3048\u308B\u5E45(n.w);
15953
+ 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);
15954
+ 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);
15845
15955
  const \u6587\u5B57\u306E\u8272 = n.isRoot ? "var(--cdl-text-on-tone, #ffffff)" : "var(--cdl-chip-text, #1a1f2a)";
15846
15956
  return /* @__PURE__ */ jsxs("g", { "data-cdl-unresolved": n.unresolved ? "true" : void 0, children: [
15847
- /* @__PURE__ */ jsx(
15957
+ \u67A0\u306A\u3057 ? null : /* @__PURE__ */ jsx(
15848
15958
  "rect",
15849
15959
  {
15850
15960
  x: n.x - n.w / 2,
@@ -15861,11 +15971,11 @@ function MindMapNode({
15861
15971
  "text",
15862
15972
  {
15863
15973
  "data-cdl-role": r.\u5F79\u5272 === "subtitle" ? "mind-node-subtitle" : void 0,
15864
- x: n.x,
15974
+ x: \u6587\u5B57\u306Ex,
15865
15975
  y: n.y + r.dy,
15866
15976
  fontSize: r.fontSize,
15867
15977
  fontWeight: r.\u5F79\u5272 === "title" ? n.isRoot ? 700 : 600 : 500,
15868
- textAnchor: "middle",
15978
+ textAnchor: \u6587\u5B57\u306E\u5BC4\u305B,
15869
15979
  fill: \u6587\u5B57\u306E\u8272,
15870
15980
  opacity: r.\u5F79\u5272 === "subtitle" ? 0.85 : void 0,
15871
15981
  children: r.text
@@ -15879,11 +15989,11 @@ function MindMapNode({
15879
15989
  /* @__PURE__ */ jsx(
15880
15990
  "text",
15881
15991
  {
15882
- x: n.x,
15992
+ x: \u6587\u5B57\u306Ex,
15883
15993
  y: n.y + 5,
15884
15994
  fontSize: \u53CE\u3081\u305F\u540D\u524D.fontSize,
15885
15995
  fontWeight: n.isRoot ? 700 : 600,
15886
- textAnchor: "middle",
15996
+ textAnchor: \u6587\u5B57\u306E\u5BC4\u305B,
15887
15997
  fill: \u6587\u5B57\u306E\u8272,
15888
15998
  children: \u53CE\u3081\u305F\u540D\u524D.text
15889
15999
  }
@@ -15893,6 +16003,13 @@ function MindMapNode({
15893
16003
  })
15894
16004
  ] });
15895
16005
  }
16006
+ function \u63CF\u304F\u6A2A\u306E\u7AEF(n) {
16007
+ if (n.isRoot || !n.isLeaf) return [n.x - n.w / 2, n.x + n.w / 2];
16008
+ const \u8D77\u70B9 = n.x + (n.side === "right" ? -n.w / 2 : n.w / 2);
16009
+ const \u540D\u524D = \u653E\u5C04\u306E\u884C(n)[0];
16010
+ const \u5E45 = measureTextWidth(\u540D\u524D.text, { fontSize: \u540D\u524D.fontSize});
16011
+ return n.side === "right" ? [\u8D77\u70B9, \u8D77\u70B9 + \u5E45] : [\u8D77\u70B9 - \u5E45, \u8D77\u70B9];
16012
+ }
15896
16013
  function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
15897
16014
  const nodes = [];
15898
16015
  const edges = [];
@@ -15908,6 +16025,9 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
15908
16025
  w: rootW,
15909
16026
  h: rootH,
15910
16027
  isRoot: true,
16028
+ // 中心は枝を持たなくても枠を描く = 図の起点なので、無いと何から広がるのかが読めない
16029
+ isLeaf: false,
16030
+ side: "right",
15911
16031
  // 中心は起点なので段数 0 (cdl#520)
15912
16032
  depth: 0,
15913
16033
  ...mindData.unresolved ? { unresolved: true } : {}
@@ -15944,7 +16064,6 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
15944
16064
  const firstCount = firstLevel.length;
15945
16065
  const leftCount = Math.ceil(firstCount / 2);
15946
16066
  const branchW = 130;
15947
- const branchH = 38;
15948
16067
  const subBranchW = 100;
15949
16068
  const subBranchH = 30;
15950
16069
  const subDepthOf = (id, seen) => {
@@ -15978,22 +16097,27 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
15978
16097
  const subOffset = (subDepth) => subDepth <= 0 ? 0 : step1 + (subDepth - 1) * stepN;
15979
16098
  const leftBranches = firstLevel.slice(0, leftCount);
15980
16099
  const rightBranches = firstLevel.slice(leftCount);
15981
- const leavesOfSide = (brs) => Math.max(1, brs.reduce((sum, br) => sum + leafCountOf(br.id, /* @__PURE__ */ new Set()), 0));
16100
+ const leavesOfSide = (brs) => Math.max(
16101
+ 1,
16102
+ brs.reduce((sum, br) => sum + leafCountOf(br.id, /* @__PURE__ */ new Set()), 0)
16103
+ );
15982
16104
  const sideLaneCount = Math.max(leavesOfSide(leftBranches), leavesOfSide(rightBranches));
15983
- const laneBandH = Math.min(canvasH * 0.9, sideLaneCount * (subBranchH + 14));
15984
- const rowGap = sideLaneCount > 1 ? laneBandH / (sideLaneCount - 1) : subBranchH + 14;
15985
- const effSubH = Math.min(subBranchH, rowGap * 0.7);
15986
- const effBranchH = Math.min(branchH, rowGap * 0.7);
15987
- const laneTop = cy - canvasH / 2 + effSubH / 2;
15988
- const laneBottom = cy + canvasH / 2 - effSubH / 2;
16105
+ const laneBandH = Math.max(0, canvasH - BRANCH_BOX_H_MAX);
16106
+ const rowGap = sideLaneCount > 1 ? Math.min(laneBandH / (sideLaneCount - 1), ROW_GAP_MAX) : subBranchH + 14;
16107
+ const effSubH = Math.min(SUB_BOX_H_MAX, rowGap * 0.7);
16108
+ const effBranchH = Math.min(BRANCH_BOX_H_MAX, rowGap * 0.7);
16109
+ const \u7AEF\u306E\u4F59\u308A = Math.max(effSubH, effBranchH) / 2;
16110
+ const laneTop = cy - canvasH / 2 + \u7AEF\u306E\u4F59\u308A;
16111
+ const laneBottom = cy + canvasH / 2 - \u7AEF\u306E\u4F59\u308A;
16112
+ const \u4F7F\u3046\u9AD8\u3055 = (sideLaneCount - 1) * rowGap;
15989
16113
  const laneY = (lane) => {
15990
16114
  if (sideLaneCount <= 1) return cy;
15991
- const y = cy - laneBandH / 2 + lane * rowGap;
16115
+ const y = cy - \u4F7F\u3046\u9AD8\u3055 / 2 + lane * rowGap;
15992
16116
  return Math.max(laneTop, Math.min(laneBottom, y));
15993
16117
  };
15994
- const rootEdgeXFor = (isLeft) => {
16118
+ const rootEdgeXFor = (isLeft, \u4E2D\u5FC3\u306Ex) => {
15995
16119
  const half = nodeHalfW.get(mindData.rootId) ?? rootW / 2;
15996
- return cx + (isLeft ? -half : half);
16120
+ return \u4E2D\u5FC3\u306Ex + (isLeft ? -half : half);
15997
16121
  };
15998
16122
  const placeSubtree = (node, subDepth, isLeft, tone, placed, laneRef) => {
15999
16123
  placed.add(node.id);
@@ -16009,7 +16133,14 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
16009
16133
  laneRef.cursor += 1;
16010
16134
  } else {
16011
16135
  const ys = kids.map(
16012
- (k, i) => placeSubtree(k, subDepth + 1, isLeft, myTone ?? MIND_TONES[i % MIND_TONES.length], placed, laneRef)
16136
+ (k, i) => placeSubtree(
16137
+ k,
16138
+ subDepth + 1,
16139
+ isLeft,
16140
+ myTone ?? MIND_TONES[i % MIND_TONES.length],
16141
+ placed,
16142
+ laneRef
16143
+ )
16013
16144
  );
16014
16145
  y = (ys[0] + ys[ys.length - 1]) / 2;
16015
16146
  }
@@ -16025,6 +16156,8 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
16025
16156
  depth: subDepth + 1,
16026
16157
  tone: myTone,
16027
16158
  isRoot: false,
16159
+ isLeaf: kids.length === 0,
16160
+ side: isLeft ? "left" : "right",
16028
16161
  ...node.unresolved ? { unresolved: true } : {}
16029
16162
  });
16030
16163
  nodePos.set(node.id, { x, y });
@@ -16034,7 +16167,8 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
16034
16167
  return y;
16035
16168
  };
16036
16169
  const placeSide = (brs, isLeft, toneBase) => {
16037
- const laneRef = { cursor: 0 };
16170
+ const \u8449\u6570 = brs.reduce((sum, br) => sum + leafCountOf(br.id, /* @__PURE__ */ new Set()), 0);
16171
+ const laneRef = { cursor: Math.max(0, (sideLaneCount - \u8449\u6570) / 2) };
16038
16172
  const placed = /* @__PURE__ */ new Set();
16039
16173
  brs.forEach((br, i) => {
16040
16174
  const tone = br.tone ?? MIND_TONES[(toneBase + i) % MIND_TONES.length];
@@ -16064,6 +16198,23 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
16064
16198
  }
16065
16199
  }
16066
16200
  }
16201
+ {
16202
+ let \u5DE6\u7AEF = Number.POSITIVE_INFINITY;
16203
+ let \u53F3\u7AEF = Number.NEGATIVE_INFINITY;
16204
+ for (const n of nodes) {
16205
+ const [l, r] = \u63CF\u304F\u6A2A\u306E\u7AEF(n);
16206
+ \u5DE6\u7AEF = Math.min(\u5DE6\u7AEF, l);
16207
+ \u53F3\u7AEF = Math.max(\u53F3\u7AEF, r);
16208
+ }
16209
+ const \u5BC4\u305B = Math.round((cx - \u5DE6\u7AEF - (\u53F3\u7AEF - cx)) / 2);
16210
+ if (Number.isFinite(\u5BC4\u305B) && \u5BC4\u305B !== 0) {
16211
+ for (const n of nodes) {
16212
+ n.x += \u5BC4\u305B;
16213
+ nodePos.set(n.id, { x: n.x, y: n.y });
16214
+ }
16215
+ }
16216
+ }
16217
+ const rootX = nodePos.get(mindData.rootId)?.x ?? cx;
16067
16218
  const \u6BB5\u6570 = new Map(nodes.map((n) => [n.id, n.depth]));
16068
16219
  for (const br of mindData.branches) {
16069
16220
  const childPos = nodePos.get(br.id);
@@ -16074,7 +16225,7 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
16074
16225
  const childDepth = \u6BB5\u6570.get(br.id) ?? 1;
16075
16226
  const parentDepth = \u6BB5\u6570.get(br.parent) ?? 0;
16076
16227
  if (br.parent === mindData.rootId) {
16077
- const startX = rootEdgeXFor(isLeft);
16228
+ const startX = rootEdgeXFor(isLeft, rootX);
16078
16229
  const endX = childPos.x + (isLeft ? childHalfW : -childHalfW);
16079
16230
  edges.push({
16080
16231
  d: makeCurve(startX, cy, endX, childPos.y),
@@ -16275,6 +16426,7 @@ function emptyCounts() {
16275
16426
  "node-inside-lane": 0,
16276
16427
  "shape-label-dropped": 0,
16277
16428
  "box-line-dropped": 0,
16429
+ "node-field-unsupported": 0,
16278
16430
  "edge-inside-viewbox": 0,
16279
16431
  "lane-label-inside-viewbox": 0,
16280
16432
  "lane-label-overlap": 0,
@@ -17496,6 +17648,28 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
17496
17648
  `node "${n.id}" (kind=${n.kind ?? "\u672A\u6307\u5B9A"}) \u304C rows ${n.rows.length} \u884C\u3092\u6301\u3064\u304C\u3001 \u3053\u306E\u7A2E\u5225\u306F\u884C\u3092\u63CF\u304B\u306A\u3044 (\u66F8\u3044\u305F\u5185\u5BB9\u304C\u753B\u9762\u306B\u51FA\u306A\u3044)`
17497
17649
  );
17498
17650
  }
17651
+ const \u6B04\u306E\u63CF\u304D\u5206\u3051 = [
17652
+ { \u6B04: "eyebrow", \u8A9E: "\u80A9\u66F8", \u63CF\u304F\u304B: rendersEyebrow },
17653
+ { \u6B04: "subtitle", \u8A9E: "\u8AAC\u660E", \u63CF\u304F\u304B: rendersSubtitle },
17654
+ { \u6B04: "value", \u8A9E: "\u5024", \u63CF\u304F\u304B: rendersValue }
17655
+ ];
17656
+ for (const n of diag.nodes) {
17657
+ if (!isRenderedNode(n)) continue;
17658
+ for (const { \u6B04, \u8A9E, \u63CF\u304F\u304B } of \u6B04\u306E\u63CF\u304D\u5206\u3051) {
17659
+ const \u66F8\u3044\u305F = (n[\u6B04] ?? "").trim();
17660
+ if (\u66F8\u3044\u305F === "") continue;
17661
+ if (\u63CF\u304F\u304B(n.kind)) continue;
17662
+ push(
17663
+ "node-field-unsupported",
17664
+ `node "${n.id}" (kind=${n.kind ?? "\u672A\u6307\u5B9A"}) \u304C ${\u6B04} (${\u8A9E}) \u306B "${\u66F8\u3044\u305F}" \u3092\u6301\u3064\u304C\u3001 \u3053\u306E\u7A2E\u5225\u306F\u305D\u306E\u6B04\u3092\u63CF\u304B\u306A\u3044 (\u66F8\u3044\u305F\u8A9E\u304C\u753B\u9762\u306B\u51FA\u306A\u3044)`,
17665
+ // 図そのものは正しく描かれており、効かない語が書かれているだけなので警告にする。
17666
+ // 誤り扱いにすると、既に書いている図が 1 枚も通らなくなる (実測 = engine の検査
17667
+ // だけで 8 file が落ちた)。 `rows-not-rendered` は誤り扱いだが、あちらは行が
17668
+ // 箱の主な中身になる種別を相手にしており、落ちた時の図の壊れ方が違う
17669
+ "warn"
17670
+ );
17671
+ }
17672
+ }
17499
17673
  for (const n of diag.nodes) {
17500
17674
  if (!n.rows || n.rows.length === 0) continue;
17501
17675
  if (!rendersRows(n.kind)) continue;
@@ -18572,6 +18746,7 @@ function validateMetaAxes(totalCounts, diagrams = [], durations = [], reports =
18572
18746
  "column-gap-uniform"
18573
18747
  ];
18574
18748
  const allAxes = [
18749
+ "node-field-unsupported",
18575
18750
  "node-visibility",
18576
18751
  "edge-label-overlap",
18577
18752
  "edge-label-proximity",
@@ -18649,7 +18824,7 @@ function validateMetaAxes(totalCounts, diagrams = [], durations = [], reports =
18649
18824
  });
18650
18825
  }
18651
18826
  }
18652
- const EXPECTED_AXIS_COUNT = 66;
18827
+ const EXPECTED_AXIS_COUNT = 67;
18653
18828
  if (allAxes.length !== EXPECTED_AXIS_COUNT) {
18654
18829
  out.push({
18655
18830
  axis: "axis-documentation-completeness",
@@ -21238,7 +21413,7 @@ function autoStorageHeight(n, defaultH) {
21238
21413
  if (n.kind !== "storage") return n.h ?? defaultH;
21239
21414
  if (n.h != null) return n.h;
21240
21415
  const \u5370\u3042\u308A = n.rowMarks !== void 0;
21241
- const \u547C\u3073\u540D\u306E\u5206 = \u5370\u3042\u308A && n.subtitle ? SUBTITLE_ROW_SHIFT : 0;
21416
+ const \u547C\u3073\u540D\u306E\u5206 = n.subtitle ? SUBTITLE_ROW_SHIFT : 0;
21242
21417
  const \u7E70\u308A\u4E0A\u3052 = n.eyebrow ? 0 : \u76EE\u5370\u306A\u3057\u306E\u7E70\u308A\u4E0A\u3052("storage");
21243
21418
  if (!n.rows || n.rows.length === 0) return 115 + \u547C\u3073\u540D\u306E\u5206 - \u7E70\u308A\u4E0A\u3052;
21244
21419
  const \u5FC5\u8981 = requiredRowsHeight("storage", n.rows.length) ?? defaultH;
@@ -21365,22 +21540,33 @@ function layoutNodes(diag, lanes) {
21365
21540
  }
21366
21541
 
21367
21542
  // src/layout/viewbox.ts
21543
+ function \u7BB1\u3044\u3063\u3071\u3044\u306B\u63CF\u304F(lane) {
21544
+ return lane.contain === true || lane.lifeline === true;
21545
+ }
21368
21546
  function computeViewBox(lanes, nodes, edges, bboxes, viewport) {
21547
+ const \u5E38\u306B\u96A0\u308C\u308B\u7BC0 = new Set(nodes.filter((n) => !isRenderedNode(n)).map((n) => n.id));
21369
21548
  let maxX = 0;
21370
21549
  let maxY = 0;
21371
21550
  let minX = Number.POSITIVE_INFINITY;
21372
21551
  let minY = Number.POSITIVE_INFINITY;
21373
21552
  for (const bbox of bboxes) {
21553
+ if (bbox.kind === "node" && \u5E38\u306B\u96A0\u308C\u308B\u7BC0.has(bbox.id)) continue;
21374
21554
  maxX = Math.max(maxX, bbox.x + bbox.w);
21375
21555
  maxY = Math.max(maxY, bbox.y + bbox.h);
21376
21556
  minX = Math.min(minX, bbox.x);
21377
21557
  minY = Math.min(minY, bbox.y);
21378
21558
  }
21379
21559
  for (const lane of lanes) {
21560
+ if (!\u7BB1\u3044\u3063\u3071\u3044\u306B\u63CF\u304F(lane)) continue;
21561
+ minX = Math.min(minX, lane.x);
21562
+ minY = Math.min(minY, lane.y);
21380
21563
  maxX = Math.max(maxX, lane.x + lane.width);
21381
21564
  maxY = Math.max(maxY, lane.y + lane.height);
21382
21565
  }
21383
21566
  for (const n of nodes) {
21567
+ if (\u5E38\u306B\u96A0\u308C\u308B\u7BC0.has(n.id)) continue;
21568
+ minX = Math.min(minX, n.cx - n.w / 2);
21569
+ minY = Math.min(minY, n.cy - n.h / 2);
21384
21570
  maxX = Math.max(maxX, n.cx + n.w / 2);
21385
21571
  maxY = Math.max(maxY, n.cy + n.h / 2);
21386
21572
  }
@@ -24544,7 +24730,7 @@ function StorageNode({
24544
24730
  const columnDividerX = (leftEndDrawn + rightColX) / 2;
24545
24731
  const columnDividerFits = columnDividerX <= node.w - ROW_PAD_X_PX;
24546
24732
  const \u5370\u3067\u5206\u3051\u308B = node.rowMarks !== void 0;
24547
- const \u884C\u306E\u4E0B\u3052 = \u5370\u3067\u5206\u3051\u308B && node.subtitle ? SUBTITLE_ROW_SHIFT : 0;
24733
+ const \u884C\u306E\u4E0B\u3052 = node.subtitle ? SUBTITLE_ROW_SHIFT : 0;
24548
24734
  const lastRowBottom = Math.min(
24549
24735
  ROW_TOP_STORAGE + (rows.length - 1) * ROW_PITCH_STORAGE + (rowGlyphDepth("storage") ?? 0),
24550
24736
  node.h - ROW_PAD_X_PX
@@ -24584,8 +24770,7 @@ function StorageNode({
24584
24770
  );
24585
24771
  }),
24586
24772
  node.eyebrow && /* @__PURE__ */ jsx("text", { x: 26, y: 38, fontSize: 18, fontWeight: 700, letterSpacing: 2, fill: accent, children: node.eyebrow }),
24587
- \u5370\u3067\u5206\u3051\u308B && node.subtitle && // 呼び名は **印で分ける箱でだけ** 出す (#578)。 従来の箱は題の下に区切り線が来るので
24588
- // 置き場が無い
24773
+ node.subtitle && // 呼び名は書き方によらず出す (#937)。 区切り線を同じ分だけ下げて置き場を作る
24589
24774
  /* @__PURE__ */ jsx(
24590
24775
  "text",
24591
24776
  {
@@ -24616,9 +24801,9 @@ function StorageNode({
24616
24801
  {
24617
24802
  "data-cdl-role": "node-row-divider",
24618
24803
  x1: 26,
24619
- y1: STORAGE_ROW_DIVIDER_Y,
24804
+ y1: STORAGE_ROW_DIVIDER_Y + \u884C\u306E\u4E0B\u3052,
24620
24805
  x2: node.w - 26,
24621
- y2: STORAGE_ROW_DIVIDER_Y,
24806
+ y2: STORAGE_ROW_DIVIDER_Y + \u884C\u306E\u4E0B\u3052,
24622
24807
  stroke: "var(--cdl-row-divider, #7e848e)",
24623
24808
  strokeWidth: 1.25
24624
24809
  }
@@ -24628,7 +24813,7 @@ function StorageNode({
24628
24813
  {
24629
24814
  "data-cdl-role": "node-column-divider",
24630
24815
  x1: columnDividerX,
24631
- y1: STORAGE_ROW_DIVIDER_Y,
24816
+ y1: STORAGE_ROW_DIVIDER_Y + \u884C\u306E\u4E0B\u3052,
24632
24817
  x2: columnDividerX,
24633
24818
  y2: lastRowBottom,
24634
24819
  stroke: "var(--cdl-row-divider, #7e848e)",
@@ -25089,18 +25274,57 @@ function DynShapeNode({
25089
25274
  const strokeColor = shape.stroke ?? "var(--cdl-line, #a89d8f)";
25090
25275
  const fillColor = shape.fill ?? "var(--cdl-fill, #e0e6ef)";
25091
25276
  const activeOpacity = active ? 1 : 0.85;
25092
- switch (shape.kind) {
25093
- case "rect":
25094
- return renderRect(shape, x, y, w, h, stateValues, fillColor, strokeColor, activeOpacity, node);
25095
- case "circle":
25096
- return renderCircle(shape, cx, cy, w, h, stateValues, fillColor, strokeColor, activeOpacity);
25097
- case "arc":
25098
- return renderArc(shape, cx, cy, w, h, stateValues, fillColor, strokeColor, activeOpacity);
25099
- case "wave":
25100
- return /* @__PURE__ */ jsx(WaveShape, { shape, x, y, w, h, stateValues, fillColor, strokeColor, opacity: activeOpacity, node });
25101
- case "polygon":
25102
- return renderPolygon(shape, cx, cy, stateValues, fillColor, strokeColor, activeOpacity);
25103
- }
25277
+ const \u5F62 = (() => {
25278
+ switch (shape.kind) {
25279
+ case "rect":
25280
+ return renderRect(shape, x, y, w, h, stateValues, fillColor, strokeColor, activeOpacity, node);
25281
+ case "circle":
25282
+ return renderCircle(shape, cx, cy, w, h, stateValues, fillColor, strokeColor, activeOpacity);
25283
+ case "arc":
25284
+ return renderArc(shape, cx, cy, w, h, stateValues, fillColor, strokeColor, activeOpacity);
25285
+ case "wave":
25286
+ return /* @__PURE__ */ jsx(WaveShape, { shape, x, y, w, h, stateValues, fillColor, strokeColor, opacity: activeOpacity, node });
25287
+ case "polygon":
25288
+ return renderPolygon(shape, cx, cy, stateValues, fillColor, strokeColor, activeOpacity);
25289
+ }
25290
+ })();
25291
+ const \u540D\u524D = (node.title ?? "").trim();
25292
+ const \u5024 = (node.subtitle ?? "").trim();
25293
+ if (\u540D\u524D === "" && \u5024 === "") return \u5F62;
25294
+ const \u63C3\u3048 = \u7BB1\u3044\u3063\u3071\u3044\u306B\u63CF\u304F2(shape.kind) ? "start" : "middle";
25295
+ return /* @__PURE__ */ jsxs("g", { children: [
25296
+ \u5F62,
25297
+ \u540D\u524D !== "" && /* @__PURE__ */ jsx(
25298
+ "text",
25299
+ {
25300
+ "data-cdl-role": "shape-name",
25301
+ x: \u63C3\u3048 === "start" ? x : cx,
25302
+ y: y - NAME_GAP,
25303
+ textAnchor: \u63C3\u3048,
25304
+ fontSize: 13,
25305
+ fontWeight: 600,
25306
+ fill: "var(--cdl-text, #23201b)",
25307
+ children: \u540D\u524D
25308
+ }
25309
+ ),
25310
+ \u5024 !== "" && /* @__PURE__ */ jsx(
25311
+ "text",
25312
+ {
25313
+ "data-cdl-role": "shape-value",
25314
+ x: cx,
25315
+ y: y + h + VALUE_GAP,
25316
+ textAnchor: "middle",
25317
+ fontSize: 12,
25318
+ fill: "var(--cdl-text-dim, #5a6270)",
25319
+ children: \u5024
25320
+ }
25321
+ )
25322
+ ] });
25323
+ }
25324
+ var NAME_GAP = 6;
25325
+ var VALUE_GAP = 18;
25326
+ function \u7BB1\u3044\u3063\u3071\u3044\u306B\u63CF\u304F2(kind) {
25327
+ return kind === "rect" || kind === "wave";
25104
25328
  }
25105
25329
  function renderRect(shape, x, y, w, h, stateValues, fillColor, strokeColor, opacity, node) {
25106
25330
  const value = resolveNumericAttr(shape.source, stateValues, 0);
@@ -25388,6 +25612,13 @@ function \u5272\u5408\u8868\u8A18(frac) {
25388
25612
  const v = Math.round(frac * 1e3) / 10;
25389
25613
  return `${Number.isInteger(v) ? v : v.toFixed(1)}%`;
25390
25614
  }
25615
+ function \u5024\u3068\u5272\u5408\u306E\u7D44(\u5024, \u5272\u5408, \u5408\u8A08) {
25616
+ return Math.abs(\u5408\u8A08 - 100) < 1e-9 ? { \u5024: null, \u5272\u5408 } : { \u5024, \u5272\u5408 };
25617
+ }
25618
+ function \u5024\u3068\u5272\u5408\u306E\u6587\u5B57(\u5024, \u5272\u5408, \u5408\u8A08) {
25619
+ const \u7D44 = \u5024\u3068\u5272\u5408\u306E\u7D44(\u5024, \u5272\u5408, \u5408\u8A08);
25620
+ return \u7D44.\u5024 === null ? \u7D44.\u5272\u5408 : `${\u7D44.\u5024} ${\u7D44.\u5272\u5408}`;
25621
+ }
25391
25622
  var \u7A74\u306B\u5BFE\u3059\u308B\u4E0A\u9650 = 0.8;
25392
25623
  function \u4E2D\u592E\u306E\u5B57(\u6BD4\u4F8B\u3057\u305F\u5927\u304D\u3055, \u7A74\u306E\u534A\u5F84, \u6587) {
25393
25624
  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);
@@ -25864,6 +26095,18 @@ function sliceColor(tone, idx) {
25864
26095
  if (tone) return TONE[tone];
25865
26096
  return chartSeriesColor(idx);
25866
26097
  }
26098
+ function \u5024\u3068\u5272\u5408\u306E\u5B57({
26099
+ \u5024,
26100
+ \u5272\u5408,
26101
+ \u5408\u8A08
26102
+ }) {
26103
+ const \u7D44 = \u5024\u3068\u5272\u5408\u306E\u7D44(\u5024, \u5272\u5408, \u5408\u8A08);
26104
+ if (\u7D44.\u5024 === null) return /* @__PURE__ */ jsx("tspan", { "data-cdl-role": "chart-legend-share", children: \u7D44.\u5272\u5408 });
26105
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
26106
+ /* @__PURE__ */ jsx("tspan", { "data-cdl-role": "chart-legend-value", fill: "var(--cdl-text, #1a1f2a)", children: `${\u7D44.\u5024} ` }),
26107
+ /* @__PURE__ */ jsx("tspan", { "data-cdl-role": "chart-legend-share", children: \u7D44.\u5272\u5408 })
26108
+ ] });
26109
+ }
25867
26110
  function ChartGaugeNode({
25868
26111
  node,
25869
26112
  active,
@@ -25886,7 +26129,7 @@ function ChartGaugeNode({
25886
26129
  const \u5F27\u3068\u5185\u8A33\u306E\u9593 = 16;
25887
26130
  const \u5370\u306E\u5E452 = 30;
25888
26131
  const \u533A\u753B\u306E\u9593 = 12;
25889
- const \u6570\u5024\u306E\u884C = (d) => `${\u5B9F\u5024\u8868\u8A18(d.value)} ${\u5272\u5408\u8868\u8A18(d.value / total)}`;
26132
+ 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);
25890
26133
  const \u5272\u308A\u4ED8\u3051\u308B = (\u4EF6\u305F\u3061) => {
25891
26134
  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;
25892
26135
  const \u884C\u306E\u4EF6\u65702 = Math.min(
@@ -26055,6 +26298,8 @@ function ChartGaugeNode({
26055
26298
  const x = PAD_SIDE + \u5185\u8A33\u306E\u5E45 * \u5217;
26056
26299
  const y = \u5185\u8A33\u306Ey + \u6BB5\u306E\u9AD8\u3055 * \u6BB5;
26057
26300
  const \u53CE\u307E\u308B\u5E45 = \u5185\u8A33\u306E\u5E45 - \u533A\u753B\u306E\u9593;
26301
+ const \u6570\u306E\u884C = \u5185\u8A33\u306E\u6570\u5024[idx] ?? "";
26302
+ const \u5207\u3063\u305F\u6570\u306E\u884C = \u5207\u308A\u8A70\u3081\u308B(\u6570\u306E\u884C, \u53CE\u307E\u308B\u5E45, \u6570\u5024\u306E\u7D1A);
26058
26303
  return /* @__PURE__ */ jsxs("g", { "data-cdl-role": "chart-gauge-item", children: [
26059
26304
  /* @__PURE__ */ jsx(
26060
26305
  "rect",
@@ -26078,7 +26323,14 @@ function ChartGaugeNode({
26078
26323
  children: \u5207\u308A\u8A70\u3081\u308B(d.label ?? "", \u53CE\u307E\u308B\u5E45, \u540D\u524D\u306E\u7D1A)
26079
26324
  }
26080
26325
  ),
26081
- /* @__PURE__ */ jsx("text", { x, y: y + 46, fontSize: \u6570\u5024\u306E\u7D1A, fill: "var(--cdl-text-dim, #5a6270)", children: \u5207\u308A\u8A70\u3081\u308B(\u5185\u8A33\u306E\u6570\u5024[idx] ?? "", \u53CE\u307E\u308B\u5E45, \u6570\u5024\u306E\u7D1A) })
26326
+ /* @__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(
26327
+ \u5024\u3068\u5272\u5408\u306E\u5B57,
26328
+ {
26329
+ \u5024: \u5B9F\u5024\u8868\u8A18(d.value),
26330
+ \u5272\u5408: \u5272\u5408\u8868\u8A18(d.value / total),
26331
+ \u5408\u8A08: total
26332
+ }
26333
+ ) : \u5207\u3063\u305F\u6570\u306E\u884C })
26082
26334
  ] }, `legend-${idx}`);
26083
26335
  })
26084
26336
  ] });
@@ -26117,7 +26369,9 @@ function ChartRadialNode({
26117
26369
  const \u6570\u5024\u306E\u7D1A = 13;
26118
26370
  const \u884C\u306E\u9AD8\u3055 = 42;
26119
26371
  const \u4E00\u89A7\u3068\u5F27\u306E\u9593 = 28;
26120
- const \u6570\u5024\u306E\u6587\u5B57 = data.map((d) => `${\u5B9F\u5024\u8868\u8A18(d.value)} ${\u5272\u5408\u8868\u8A18(d.value / total)}`);
26372
+ const \u6570\u5024\u306E\u6587\u5B57 = data.map(
26373
+ (d) => \u5024\u3068\u5272\u5408\u306E\u6587\u5B57(\u5B9F\u5024\u8868\u8A18(d.value), \u5272\u5408\u8868\u8A18(d.value / total), total)
26374
+ );
26121
26375
  const \u4E00\u89A7\u306E\u5E45 = \u5370\u306E\u5E45 + Math.max(
26122
26376
  0,
26123
26377
  ...data.map(
@@ -26129,7 +26383,9 @@ function ChartRadialNode({
26129
26383
  const \u4F7F\u3048\u308B\u539A\u307F = \u5916\u534A\u5F84 * 0.7;
26130
26384
  const \u5E2F1\u672C = \u4F7F\u3048\u308B\u539A\u307F / Math.max(data.length, 1);
26131
26385
  const \u5E2F\u306E\u5E45 = \u5E2F1\u672C * 0.66;
26132
- const \u5F27\u306Ecx = PAD + \u4E00\u89A7\u306E\u5E45 + \u4E00\u89A7\u3068\u5F27\u306E\u9593 + \u5916\u534A\u5F84;
26386
+ const \u4E2D\u8EAB\u306E\u5E45 = \u4E00\u89A7\u306E\u5E45 + \u4E00\u89A7\u3068\u5F27\u306E\u9593 + \u5916\u534A\u5F84 * 2;
26387
+ const \u4E00\u89A7\u306E\u5DE6 = Math.max(PAD, (node.w - \u4E2D\u8EAB\u306E\u5E45) / 2);
26388
+ const \u5F27\u306Ecx = \u4E00\u89A7\u306E\u5DE6 + \u4E00\u89A7\u306E\u5E45 + \u4E00\u89A7\u3068\u5F27\u306E\u9593 + \u5916\u534A\u5F84;
26133
26389
  const cy = PAD + \u4F7F\u3048\u308B\u9AD8\u3055 / 2;
26134
26390
  const rings = data.map((d, idx) => {
26135
26391
  const frac = d.value / total;
@@ -26204,11 +26460,11 @@ function ChartRadialNode({
26204
26460
  data.map((d, idx) => {
26205
26461
  const y = \u4E00\u89A7\u306E\u59CB\u307E\u308A + \u884C\u306E\u9AD8\u3055 * idx;
26206
26462
  return /* @__PURE__ */ jsxs("g", { "data-cdl-role": "chart-radial-item", children: [
26207
- /* @__PURE__ */ jsx("rect", { x: PAD, y: y - 11, width: 4, height: 22, rx: 2, fill: arcColor2(d.tone, idx) }),
26463
+ /* @__PURE__ */ jsx("rect", { x: \u4E00\u89A7\u306E\u5DE6, y: y - 11, width: 4, height: 22, rx: 2, fill: arcColor2(d.tone, idx) }),
26208
26464
  /* @__PURE__ */ jsx(
26209
26465
  "text",
26210
26466
  {
26211
- x: PAD + \u5370\u306E\u5E45,
26467
+ x: \u4E00\u89A7\u306E\u5DE6 + \u5370\u306E\u5E45,
26212
26468
  y: y + 1,
26213
26469
  fontSize: \u540D\u524D\u306E\u7D1A,
26214
26470
  fontWeight: 700,
@@ -26219,11 +26475,18 @@ function ChartRadialNode({
26219
26475
  /* @__PURE__ */ jsx(
26220
26476
  "text",
26221
26477
  {
26222
- x: PAD + \u5370\u306E\u5E45,
26478
+ x: \u4E00\u89A7\u306E\u5DE6 + \u5370\u306E\u5E45,
26223
26479
  y: y + 20,
26224
26480
  fontSize: \u6570\u5024\u306E\u7D1A,
26225
26481
  fill: "var(--cdl-text-dim, #5a6270)",
26226
- children: \u6570\u5024\u306E\u6587\u5B57[idx]
26482
+ children: /* @__PURE__ */ jsx(
26483
+ \u5024\u3068\u5272\u5408\u306E\u5B57,
26484
+ {
26485
+ \u5024: \u5B9F\u5024\u8868\u8A18(d.value),
26486
+ \u5272\u5408: \u5272\u5408\u8868\u8A18(d.value / total),
26487
+ \u5408\u8A08: total
26488
+ }
26489
+ )
26227
26490
  }
26228
26491
  )
26229
26492
  ] }, `item-${idx}`);
@@ -26266,7 +26529,7 @@ function ChartStatNode({
26266
26529
  const data = resolveChartData(node.chartData ?? [], stateValues);
26267
26530
  const total = data.reduce((acc, d) => acc + d.value, 0) || 1;
26268
26531
  const \u524D\u3092\u51FA\u3059 = data.some((d) => d.previous !== void 0);
26269
- const \u533A\u753B = \u533A\u753B\u306E\u5272\u4ED8(node.w, node.h, data.length, \u524D\u3092\u51FA\u3059);
26532
+ const \u533A\u753B = \u533A\u753B\u306E\u5272\u4ED8(node.w, node.h, data.length, \u524D\u3092\u51FA\u3059, data.length > 1);
26270
26533
  const \u5272\u5408\u3092\u51FA\u3059 = data.length > 1;
26271
26534
  return /* @__PURE__ */ jsxs("g", { transform: `translate(${x0} ${y0})`, children: [
26272
26535
  /* @__PURE__ */ jsx(
@@ -26395,17 +26658,23 @@ function ChartStatNode({
26395
26658
  })
26396
26659
  ] });
26397
26660
  }
26398
- function \u533A\u753B\u306E\u5272\u4ED8(w, h, \u4EF6\u6570, \u524D\u3092\u51FA\u3059) {
26661
+ function \u533A\u753B\u306E\u5272\u4ED8(w, h, \u4EF6\u6570, \u524D\u3092\u51FA\u3059, \u5272\u5408\u3092\u51FA\u3059) {
26399
26662
  const \u4F59\u767D = 20;
26400
26663
  const \u5E45 = \u4EF6\u6570 > 0 ? w / \u4EF6\u6570 : w;
26401
26664
  const \u540D\u524D\u306E\u7D1A = 14;
26402
- const \u6570\u5024\u306E\u7D1A = 40;
26403
26665
  const \u524D\u306E\u7D1A = \u540D\u524D\u306E\u7D1A;
26404
26666
  const \u5272\u5408\u306E\u7D1A = 12;
26405
26667
  const \u5F27\u306E\u534A\u5F84 = 20;
26406
26668
  const \u5F27\u306E\u592A\u3055 = 4;
26669
+ const \u6570\u5024\u306E\u7D1A\u306E\u4E0B\u9650 = 40;
26670
+ const \u6570\u5024\u306E\u7D1A\u306E\u4E0A\u9650 = 112;
26407
26671
  const \u524D\u306E\u9AD8\u3055 = \u524D\u3092\u51FA\u3059 ? 8 + \u524D\u306E\u7D1A : 0;
26408
- const \u4E2D\u8EAB\u306E\u9AD8\u3055 = \u540D\u524D\u306E\u7D1A + 12 + \u6570\u5024\u306E\u7D1A + \u524D\u306E\u9AD8\u3055 + 16 + \u5F27\u306E\u534A\u5F84 * 2 + 8 + \u5272\u5408\u306E\u7D1A;
26672
+ const \u5F27\u3068\u5272\u5408\u306E\u9AD8\u3055 = \u5272\u5408\u3092\u51FA\u3059 ? 16 + \u5F27\u306E\u534A\u5F84 * 2 + 8 + \u5272\u5408\u306E\u7D1A : 0;
26673
+ const \u6570\u5024\u306E\u7D1A = \u5272\u5408\u3092\u51FA\u3059 ? \u6570\u5024\u306E\u7D1A\u306E\u4E0B\u9650 : Math.max(
26674
+ \u6570\u5024\u306E\u7D1A\u306E\u4E0B\u9650,
26675
+ Math.min(\u6570\u5024\u306E\u7D1A\u306E\u4E0A\u9650, Math.floor(h - \u4F59\u767D * 2 - \u540D\u524D\u306E\u7D1A - 12 - \u524D\u306E\u9AD8\u3055))
26676
+ );
26677
+ const \u4E2D\u8EAB\u306E\u9AD8\u3055 = \u540D\u524D\u306E\u7D1A + 12 + \u6570\u5024\u306E\u7D1A + \u524D\u306E\u9AD8\u3055 + \u5F27\u3068\u5272\u5408\u306E\u9AD8\u3055;
26409
26678
  const \u4E0A\u7AEF = Math.max(\u4F59\u767D, (h - \u4E2D\u8EAB\u306E\u9AD8\u3055) / 2);
26410
26679
  const \u540D\u524D\u306Ey = \u4E0A\u7AEF + \u540D\u524D\u306E\u7D1A;
26411
26680
  const \u6570\u5024\u306Ey = \u540D\u524D\u306Ey + 12 + \u6570\u5024\u306E\u7D1A * 0.78;
@@ -26477,7 +26746,10 @@ function ChartWaffleNode({
26477
26746
  const \u884C\u306E\u9AD8\u3055 = 40;
26478
26747
  const \u4E00\u89A7\u3068\u683C\u5B50\u306E\u9593 = 28;
26479
26748
  const \u5370\u306E\u5E452 = 18;
26480
- const \u6570\u5024\u306E\u6587\u5B57 = data.map((d, i) => `${\u5B9F\u5024\u8868\u8A18(d.value)} ${\u914D\u5206[i] ?? 0}%`);
26749
+ const \u5B9F\u5024\u306E\u5408\u8A08 = data.reduce((acc, d) => acc + d.value, 0);
26750
+ const \u6570\u5024\u306E\u6587\u5B57 = data.map(
26751
+ (d, i) => \u5024\u3068\u5272\u5408\u306E\u6587\u5B57(\u5B9F\u5024\u8868\u8A18(d.value), `${\u914D\u5206[i] ?? 0}%`, \u5B9F\u5024\u306E\u5408\u8A08)
26752
+ );
26481
26753
  const \u4E00\u89A7\u306E\u5E45 = \u5370\u306E\u5E452 + Math.max(
26482
26754
  0,
26483
26755
  ...data.map(
@@ -26488,7 +26760,9 @@ function ChartWaffleNode({
26488
26760
  const \u683C\u5B50\u306B\u4F7F\u3048\u308B\u5E45 = node.w - PAD * 2 - \u4E00\u89A7\u306E\u5E45 - \u4E00\u89A7\u3068\u683C\u5B50\u306E\u9593;
26489
26761
  const \u5347 = Math.max(4, Math.min(\u4F7F\u3048\u308B\u9AD8\u3055, \u683C\u5B50\u306B\u4F7F\u3048\u308B\u5E45) / WAFFLE_COLS);
26490
26762
  const \u5370 = \u5347 * 0.78;
26491
- const \u683C\u5B50\u306E\u5DE6 = PAD + \u4E00\u89A7\u306E\u5E45 + \u4E00\u89A7\u3068\u683C\u5B50\u306E\u9593;
26763
+ const \u4E2D\u8EAB\u306E\u5E45 = \u4E00\u89A7\u306E\u5E45 + \u4E00\u89A7\u3068\u683C\u5B50\u306E\u9593 + \u5347 * WAFFLE_COLS;
26764
+ const \u4E00\u89A7\u306E\u5DE6 = Math.max(PAD, (node.w - \u4E2D\u8EAB\u306E\u5E45) / 2);
26765
+ const \u683C\u5B50\u306E\u5DE6 = \u4E00\u89A7\u306E\u5DE6 + \u4E00\u89A7\u306E\u5E45 + \u4E00\u89A7\u3068\u683C\u5B50\u306E\u9593;
26492
26766
  const \u683C\u5B50\u306E\u4E0A = PAD + (\u4F7F\u3048\u308B\u9AD8\u3055 - \u5347 * WAFFLE_COLS) / 2;
26493
26767
  const \u6301\u3061\u4E3B = [];
26494
26768
  \u914D\u5206.forEach((n, idx) => {
@@ -26535,11 +26809,11 @@ function ChartWaffleNode({
26535
26809
  data.map((d, idx) => {
26536
26810
  const y = \u4E00\u89A7\u306E\u59CB\u307E\u308A + \u884C\u306E\u9AD8\u3055 * idx;
26537
26811
  return /* @__PURE__ */ jsxs("g", { "data-cdl-role": "chart-waffle-item", children: [
26538
- /* @__PURE__ */ jsx("rect", { x: PAD, y: y - 11, width: 4, height: 22, rx: 2, fill: \u5370\u306E\u82722(d.tone, idx) }),
26812
+ /* @__PURE__ */ jsx("rect", { x: \u4E00\u89A7\u306E\u5DE6, y: y - 11, width: 4, height: 22, rx: 2, fill: \u5370\u306E\u82722(d.tone, idx) }),
26539
26813
  /* @__PURE__ */ jsx(
26540
26814
  "text",
26541
26815
  {
26542
- x: PAD + \u5370\u306E\u5E452,
26816
+ x: \u4E00\u89A7\u306E\u5DE6 + \u5370\u306E\u5E452,
26543
26817
  y: y + 1,
26544
26818
  fontSize: \u540D\u524D\u306E\u7D1A,
26545
26819
  fontWeight: 700,
@@ -26552,11 +26826,18 @@ function ChartWaffleNode({
26552
26826
  {
26553
26827
  "data-cdl-role": "chart-waffle-count",
26554
26828
  "data-cdl-unresolved": d.unresolved ? "true" : void 0,
26555
- x: PAD + \u5370\u306E\u5E452,
26829
+ x: \u4E00\u89A7\u306E\u5DE6 + \u5370\u306E\u5E452,
26556
26830
  y: y + 20,
26557
26831
  fontSize: \u6570\u5024\u306E\u7D1A,
26558
26832
  fill: "var(--cdl-text-dim, #5a6270)",
26559
- children: \u6570\u5024\u306E\u6587\u5B57[idx]
26833
+ children: /* @__PURE__ */ jsx(
26834
+ \u5024\u3068\u5272\u5408\u306E\u5B57,
26835
+ {
26836
+ \u5024: \u5B9F\u5024\u8868\u8A18(d.value),
26837
+ \u5272\u5408: `${\u914D\u5206[idx] ?? 0}%`,
26838
+ \u5408\u8A08: \u5B9F\u5024\u306E\u5408\u8A08
26839
+ }
26840
+ )
26560
26841
  }
26561
26842
  )
26562
26843
  ] }, `item-${idx}`);
@@ -27462,6 +27743,8 @@ function FunnelNode({
27462
27743
  const t = step / stageCount;
27463
27744
  return canvasW * (topRatio + (bottomRatio - topRatio) * t);
27464
27745
  };
27746
+ const \u540D\u524D\u306E\u5B57 = 14;
27747
+ const \u88DC\u8DB3\u306E\u5B57 = 10.5;
27465
27748
  const \u6BB5 = stages.map((s, idx) => {
27466
27749
  const prev = idx > 0 ? stages[idx - 1] : null;
27467
27750
  const dropRate = prev && prev.count > 0 ? (prev.count - s.count) / prev.count * 100 : 0;
@@ -27474,6 +27757,17 @@ function FunnelNode({
27474
27757
  const points = `${topX},${y} ${topX + topW},${y} ${bottomX + bottomW},${y + stageH} ${bottomX},${y + stageH}`;
27475
27758
  const tone = toneByIndex(idx);
27476
27759
  const legendX = PAD_LEFT2 + canvasW + 24;
27760
+ const \u88DC\u8DB3 = (s.subtitle ?? "").trim();
27761
+ const \u88DC\u8DB3\u3042\u308A = \u88DC\u8DB3 !== "";
27762
+ const \u4E8C\u884C\u306E\u9AD8\u3055 = \u540D\u524D\u306E\u5B57 * 1.2 + \u88DC\u8DB3\u306E\u5B57 * 1.25;
27763
+ const \u7E26\u500D = \u88DC\u8DB3\u3042\u308A ? Math.min(1, Math.max(0, stageH - 8) / \u4E8C\u884C\u306E\u9AD8\u3055) : 1;
27764
+ const \u540D\u524D\u306E\u5B9F\u5B57 = \u540D\u524D\u306E\u5B57 * \u7E26\u500D;
27765
+ const \u88DC\u8DB3\u306E\u67A0\u5B57 = \u88DC\u8DB3\u306E\u5B57 * \u7E26\u500D;
27766
+ const \u53CE\u307E\u308B\u5E45 = Math.max(0, bottomW - 16);
27767
+ 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);
27768
+ const \u584A\u306E\u4E0A = y + stageH / 2 - (\u540D\u524D\u306E\u5B9F\u5B57 * 1.2 + \u88DC\u8DB3\u306E\u67A0\u5B57 * 1.25) / 2;
27769
+ const \u540D\u524D\u306Ey = \u88DC\u8DB3\u3042\u308A ? \u584A\u306E\u4E0A + \u540D\u524D\u306E\u5B9F\u5B57 * 0.95 : y + stageH / 2 + 5;
27770
+ const \u88DC\u8DB3\u306Ey = \u584A\u306E\u4E0A + \u540D\u524D\u306E\u5B9F\u5B57 * 1.2 + \u88DC\u8DB3\u306E\u67A0\u5B57 * 0.95;
27477
27771
  return /* @__PURE__ */ jsxs("g", { children: [
27478
27772
  /* @__PURE__ */ jsx(
27479
27773
  "polygon",
@@ -27491,14 +27785,29 @@ function FunnelNode({
27491
27785
  "text",
27492
27786
  {
27493
27787
  x: cx,
27494
- y: y + stageH / 2 + 5,
27495
- fontSize: 14,
27788
+ y: \u540D\u524D\u306Ey,
27789
+ fontSize: \u540D\u524D\u306E\u5B9F\u5B57,
27496
27790
  fontWeight: 700,
27497
27791
  textAnchor: "middle",
27498
27792
  fill: "var(--cdl-node-fill, #ffffff)",
27499
27793
  children: s.title
27500
27794
  }
27501
27795
  ),
27796
+ \u88DC\u8DB3\u3042\u308A && /* @__PURE__ */ jsx(
27797
+ "text",
27798
+ {
27799
+ "data-cdl-role": "funnel-stage-subtitle",
27800
+ x: cx,
27801
+ y: \u88DC\u8DB3\u306Ey,
27802
+ fontSize: \u88DC\u8DB3\u306E\u5B9F\u5B57,
27803
+ fontWeight: 500,
27804
+ letterSpacing: 0,
27805
+ textAnchor: "middle",
27806
+ fill: "var(--cdl-node-fill, #ffffff)",
27807
+ fillOpacity: 0.82,
27808
+ children: \u88DC\u8DB3
27809
+ }
27810
+ ),
27502
27811
  \u6BB5\u304C\u51FA\u5207\u3063\u305F(idx) && /* @__PURE__ */ jsx(
27503
27812
  "text",
27504
27813
  {
@@ -27552,6 +27861,9 @@ var TONE_ORDER = [
27552
27861
  function toneByIndex(idx) {
27553
27862
  return TONE_ORDER[idx % TONE_ORDER.length];
27554
27863
  }
27864
+ function \u7573\u3093\u3060\u6587(\u4EF6\u6570) {
27865
+ return `\u307B\u304B ${\u4EF6\u6570} \u4EF6`;
27866
+ }
27555
27867
  function QuadrantNode({
27556
27868
  node,
27557
27869
  active,
@@ -27569,7 +27881,13 @@ function QuadrantNode({
27569
27881
  const ITEM_FONT = 13;
27570
27882
  const ITEM_PAD_X = 12;
27571
27883
  const ITEM_MIN_W = 48;
27572
- const axisLabelPad = (text) => Math.max(PAD_MIN, measureTextWidth(`\u2190 ${text}`, { fontSize: AXIS_LABEL_FONT}) + 12);
27884
+ const POINT_R = 5;
27885
+ const POINT_GAP = 6;
27886
+ const SUB_FONT = 10;
27887
+ const axisLabelPad = (text) => Math.max(
27888
+ PAD_MIN,
27889
+ measureTextWidth(`\u2190 ${text}`, { fontSize: AXIS_LABEL_FONT}) + 12
27890
+ );
27573
27891
  const padBudget = Math.max(0, node.w * 0.5 - PAD_MIN * 2);
27574
27892
  const wantLeft = axisLabelPad(data.xAxis.left) - PAD_MIN;
27575
27893
  const wantRight = axisLabelPad(data.xAxis.right) - PAD_MIN;
@@ -27583,11 +27901,13 @@ function QuadrantNode({
27583
27901
  const cy = PAD_TOP2 + canvasH / 2;
27584
27902
  const halfW = canvasW / 2;
27585
27903
  const halfH = canvasH / 2;
27904
+ const \u70B9\u3067\u7F6E\u304F = data.items.filter((i) => i.at !== void 0);
27905
+ const \u7A4D\u3080 = data.items.filter((i) => i.at === void 0);
27586
27906
  const itemsBy = {
27587
- topLeft: data.items.filter((i) => i.quadrant === "topLeft"),
27588
- topRight: data.items.filter((i) => i.quadrant === "topRight"),
27589
- bottomLeft: data.items.filter((i) => i.quadrant === "bottomLeft"),
27590
- bottomRight: data.items.filter((i) => i.quadrant === "bottomRight")
27907
+ topLeft: \u7A4D\u3080.filter((i) => i.quadrant === "topLeft"),
27908
+ topRight: \u7A4D\u3080.filter((i) => i.quadrant === "topRight"),
27909
+ bottomLeft: \u7A4D\u3080.filter((i) => i.quadrant === "bottomLeft"),
27910
+ bottomRight: \u7A4D\u3080.filter((i) => i.quadrant === "bottomRight")
27591
27911
  };
27592
27912
  const quadrantColor = {
27593
27913
  topLeft: toneFill("success", 0.06),
@@ -27616,10 +27936,50 @@ function QuadrantNode({
27616
27936
  strokeWidth: active ? 3 : 1.25
27617
27937
  }
27618
27938
  ),
27619
- /* @__PURE__ */ jsx("rect", { "data-cdl-role": "quadrant-bg", x: PAD_LEFT2, y: PAD_TOP2, width: halfW, height: halfH, ...quadrantColor.topLeft }),
27620
- /* @__PURE__ */ jsx("rect", { "data-cdl-role": "quadrant-bg", x: cx, y: PAD_TOP2, width: halfW, height: halfH, ...quadrantColor.topRight }),
27621
- /* @__PURE__ */ jsx("rect", { "data-cdl-role": "quadrant-bg", x: PAD_LEFT2, y: cy, width: halfW, height: halfH, ...quadrantColor.bottomLeft }),
27622
- /* @__PURE__ */ jsx("rect", { "data-cdl-role": "quadrant-bg", x: cx, y: cy, width: halfW, height: halfH, ...quadrantColor.bottomRight }),
27939
+ /* @__PURE__ */ jsx(
27940
+ "rect",
27941
+ {
27942
+ "data-cdl-role": "quadrant-bg",
27943
+ x: PAD_LEFT2,
27944
+ y: PAD_TOP2,
27945
+ width: halfW,
27946
+ height: halfH,
27947
+ ...quadrantColor.topLeft
27948
+ }
27949
+ ),
27950
+ /* @__PURE__ */ jsx(
27951
+ "rect",
27952
+ {
27953
+ "data-cdl-role": "quadrant-bg",
27954
+ x: cx,
27955
+ y: PAD_TOP2,
27956
+ width: halfW,
27957
+ height: halfH,
27958
+ ...quadrantColor.topRight
27959
+ }
27960
+ ),
27961
+ /* @__PURE__ */ jsx(
27962
+ "rect",
27963
+ {
27964
+ "data-cdl-role": "quadrant-bg",
27965
+ x: PAD_LEFT2,
27966
+ y: cy,
27967
+ width: halfW,
27968
+ height: halfH,
27969
+ ...quadrantColor.bottomLeft
27970
+ }
27971
+ ),
27972
+ /* @__PURE__ */ jsx(
27973
+ "rect",
27974
+ {
27975
+ "data-cdl-role": "quadrant-bg",
27976
+ x: cx,
27977
+ y: cy,
27978
+ width: halfW,
27979
+ height: halfH,
27980
+ ...quadrantColor.bottomRight
27981
+ }
27982
+ ),
27623
27983
  /* @__PURE__ */ jsx(
27624
27984
  "rect",
27625
27985
  {
@@ -27634,28 +27994,136 @@ function QuadrantNode({
27634
27994
  rx: 8
27635
27995
  }
27636
27996
  ),
27637
- /* @__PURE__ */ jsx("line", { x1: cx, y1: PAD_TOP2, x2: cx, y2: PAD_TOP2 + canvasH, stroke: "var(--cdl-text-mute, #8a8678)", strokeWidth: 1.5 }),
27638
- /* @__PURE__ */ jsx("line", { x1: PAD_LEFT2, y1: cy, x2: PAD_LEFT2 + canvasW, y2: cy, stroke: "var(--cdl-text-mute, #8a8678)", strokeWidth: 1.5 }),
27639
- /* @__PURE__ */ jsx("text", { x: PAD_LEFT2 + halfW / 2, y: PAD_TOP2 + 22, fontSize: 13, fontWeight: 700, textAnchor: "middle", fill: quadrantAccent.topLeft, children: data.quadrantLabels.topLeft }),
27640
- /* @__PURE__ */ jsx("text", { x: cx + halfW / 2, y: PAD_TOP2 + 22, fontSize: 13, fontWeight: 700, textAnchor: "middle", fill: quadrantAccent.topRight, children: data.quadrantLabels.topRight }),
27641
- /* @__PURE__ */ jsx("text", { x: PAD_LEFT2 + halfW / 2, y: PAD_TOP2 + canvasH - 12, fontSize: 13, fontWeight: 700, textAnchor: "middle", fill: quadrantAccent.bottomLeft, children: data.quadrantLabels.bottomLeft }),
27642
- /* @__PURE__ */ jsx("text", { x: cx + halfW / 2, y: PAD_TOP2 + canvasH - 12, fontSize: 13, fontWeight: 700, textAnchor: "middle", fill: quadrantAccent.bottomRight, children: data.quadrantLabels.bottomRight }),
27643
- /* @__PURE__ */ jsxs("text", { x: cx, y: PAD_TOP2 - 12, fontSize: 12, fontWeight: 700, textAnchor: "middle", fill: "var(--cdl-text-dim, #5a6270)", children: [
27644
- "\u2191 ",
27645
- data.yAxis.top
27646
- ] }),
27647
- /* @__PURE__ */ jsxs("text", { x: cx, y: PAD_TOP2 + canvasH + 24, fontSize: 12, fontWeight: 700, textAnchor: "middle", fill: "var(--cdl-text-dim, #5a6270)", children: [
27648
- "\u2193 ",
27649
- data.yAxis.bottom
27650
- ] }),
27651
- /* @__PURE__ */ jsxs("text", { x: PAD_LEFT2 - 12, y: cy + 4, fontSize: AXIS_LABEL_FONT, fontWeight: 700, textAnchor: "end", fill: "var(--cdl-text-dim, #5a6270)", children: [
27652
- "\u2190 ",
27653
- data.xAxis.left
27654
- ] }),
27655
- /* @__PURE__ */ jsxs("text", { x: PAD_LEFT2 + canvasW + 12, y: cy + 4, fontSize: AXIS_LABEL_FONT, fontWeight: 700, textAnchor: "start", fill: "var(--cdl-text-dim, #5a6270)", children: [
27656
- data.xAxis.right,
27657
- " \u2192"
27658
- ] }),
27997
+ /* @__PURE__ */ jsx(
27998
+ "line",
27999
+ {
28000
+ x1: cx,
28001
+ y1: PAD_TOP2,
28002
+ x2: cx,
28003
+ y2: PAD_TOP2 + canvasH,
28004
+ stroke: "var(--cdl-text-mute, #8a8678)",
28005
+ strokeWidth: 1.5
28006
+ }
28007
+ ),
28008
+ /* @__PURE__ */ jsx(
28009
+ "line",
28010
+ {
28011
+ x1: PAD_LEFT2,
28012
+ y1: cy,
28013
+ x2: PAD_LEFT2 + canvasW,
28014
+ y2: cy,
28015
+ stroke: "var(--cdl-text-mute, #8a8678)",
28016
+ strokeWidth: 1.5
28017
+ }
28018
+ ),
28019
+ /* @__PURE__ */ jsx(
28020
+ "text",
28021
+ {
28022
+ x: PAD_LEFT2 + halfW / 2,
28023
+ y: PAD_TOP2 + 22,
28024
+ fontSize: 13,
28025
+ fontWeight: 700,
28026
+ textAnchor: "middle",
28027
+ fill: quadrantAccent.topLeft,
28028
+ children: data.quadrantLabels.topLeft
28029
+ }
28030
+ ),
28031
+ /* @__PURE__ */ jsx(
28032
+ "text",
28033
+ {
28034
+ x: cx + halfW / 2,
28035
+ y: PAD_TOP2 + 22,
28036
+ fontSize: 13,
28037
+ fontWeight: 700,
28038
+ textAnchor: "middle",
28039
+ fill: quadrantAccent.topRight,
28040
+ children: data.quadrantLabels.topRight
28041
+ }
28042
+ ),
28043
+ /* @__PURE__ */ jsx(
28044
+ "text",
28045
+ {
28046
+ x: PAD_LEFT2 + halfW / 2,
28047
+ y: PAD_TOP2 + canvasH - 12,
28048
+ fontSize: 13,
28049
+ fontWeight: 700,
28050
+ textAnchor: "middle",
28051
+ fill: quadrantAccent.bottomLeft,
28052
+ children: data.quadrantLabels.bottomLeft
28053
+ }
28054
+ ),
28055
+ /* @__PURE__ */ jsx(
28056
+ "text",
28057
+ {
28058
+ x: cx + halfW / 2,
28059
+ y: PAD_TOP2 + canvasH - 12,
28060
+ fontSize: 13,
28061
+ fontWeight: 700,
28062
+ textAnchor: "middle",
28063
+ fill: quadrantAccent.bottomRight,
28064
+ children: data.quadrantLabels.bottomRight
28065
+ }
28066
+ ),
28067
+ /* @__PURE__ */ jsxs(
28068
+ "text",
28069
+ {
28070
+ x: cx,
28071
+ y: PAD_TOP2 - 12,
28072
+ fontSize: 12,
28073
+ fontWeight: 700,
28074
+ textAnchor: "middle",
28075
+ fill: "var(--cdl-text-dim, #5a6270)",
28076
+ children: [
28077
+ "\u2191 ",
28078
+ data.yAxis.top
28079
+ ]
28080
+ }
28081
+ ),
28082
+ /* @__PURE__ */ jsxs(
28083
+ "text",
28084
+ {
28085
+ x: cx,
28086
+ y: PAD_TOP2 + canvasH + 24,
28087
+ fontSize: 12,
28088
+ fontWeight: 700,
28089
+ textAnchor: "middle",
28090
+ fill: "var(--cdl-text-dim, #5a6270)",
28091
+ children: [
28092
+ "\u2193 ",
28093
+ data.yAxis.bottom
28094
+ ]
28095
+ }
28096
+ ),
28097
+ /* @__PURE__ */ jsxs(
28098
+ "text",
28099
+ {
28100
+ x: PAD_LEFT2 - 12,
28101
+ y: cy + 4,
28102
+ fontSize: AXIS_LABEL_FONT,
28103
+ fontWeight: 700,
28104
+ textAnchor: "end",
28105
+ fill: "var(--cdl-text-dim, #5a6270)",
28106
+ children: [
28107
+ "\u2190 ",
28108
+ data.xAxis.left
28109
+ ]
28110
+ }
28111
+ ),
28112
+ /* @__PURE__ */ jsxs(
28113
+ "text",
28114
+ {
28115
+ x: PAD_LEFT2 + canvasW + 12,
28116
+ y: cy + 4,
28117
+ fontSize: AXIS_LABEL_FONT,
28118
+ fontWeight: 700,
28119
+ textAnchor: "start",
28120
+ fill: "var(--cdl-text-dim, #5a6270)",
28121
+ children: [
28122
+ data.xAxis.right,
28123
+ " \u2192"
28124
+ ]
28125
+ }
28126
+ ),
27659
28127
  Object.keys(itemsBy).map((q) => {
27660
28128
  const items = itemsBy[q];
27661
28129
  if (items.length === 0) return null;
@@ -27666,35 +28134,169 @@ function QuadrantNode({
27666
28134
  const qHalfW = halfW - 36;
27667
28135
  const \u67A0\u306E\u4F59\u5730 = qHalfW;
27668
28136
  if (\u67A0\u306E\u4F59\u5730 <= 0) return null;
27669
- const \u67A0\u306E\u5E45 = (title) => Math.min(
28137
+ const \u67A0\u306E\u5E45 = (\u884C\u30892) => Math.min(
27670
28138
  \u67A0\u306E\u4F59\u5730,
27671
- Math.max(ITEM_MIN_W, measureTextWidth(title, { fontSize: ITEM_FONT}) + ITEM_PAD_X * 2)
28139
+ Math.max(
28140
+ ITEM_MIN_W,
28141
+ Math.max(
28142
+ ...\u884C\u30892.map(
28143
+ (r) => measureTextWidth(r.text, { fontSize: r.size, fontWeight: r.weight })
28144
+ )
28145
+ ) + ITEM_PAD_X * 2
28146
+ )
27672
28147
  );
28148
+ const \u884C\u3089 = (it) => {
28149
+ const \u88DC\u8DB3 = (it.subtitle ?? "").trim();
28150
+ return [
28151
+ { text: it.title, size: ITEM_FONT, weight: 600 },
28152
+ ...\u88DC\u8DB3 === "" ? [] : [{ text: \u88DC\u8DB3, size: SUB_FONT, weight: 500 }]
28153
+ ];
28154
+ };
27673
28155
  const qHalfH = halfH - 60;
27674
28156
  const gap = 10;
27675
28157
  const rowH = 34;
27676
28158
  const maxRows = Math.max(1, Math.floor(qHalfH / (rowH + gap)));
27677
- return items.slice(0, maxRows).map((it, idx) => {
27678
- const py = qyStart + idx * (rowH + gap);
27679
- return /* @__PURE__ */ jsxs("g", { children: [
27680
- /* @__PURE__ */ jsx(
27681
- "rect",
27682
- {
27683
- "data-cdl-role": "quadrant-item",
27684
- "data-cdl-unresolved": it.unresolved ? "true" : void 0,
27685
- x: qxStart,
27686
- y: py,
27687
- width: \u67A0\u306E\u5E45(it.title),
27688
- height: rowH,
27689
- rx: 6,
27690
- fill: "var(--cdl-node-fill, #ffffff)",
27691
- stroke: quadrantAccent[q],
27692
- strokeWidth: 1.5
27693
- }
27694
- ),
27695
- /* @__PURE__ */ jsx("text", { x: qxStart + ITEM_PAD_X, y: py + rowH / 2 + 5, fontSize: ITEM_FONT, fontWeight: 600, letterSpacing: 0, fill: "var(--cdl-text, #1a1f2a)", children: it.title })
27696
- ] }, `item-${it.id}`);
27697
- });
28159
+ const \u7573\u3080 = items.length > maxRows;
28160
+ const \u540D\u524D\u3092\u51FA\u3059 = \u7573\u3080 ? items.slice(0, maxRows - 1) : items;
28161
+ const \u7573\u3093\u3060\u4EF6\u6570 = items.length - \u540D\u524D\u3092\u51FA\u3059.length;
28162
+ return /* @__PURE__ */ jsxs("g", { children: [
28163
+ \u540D\u524D\u3092\u51FA\u3059.map((it, idx) => {
28164
+ const py = qyStart + idx * (rowH + gap);
28165
+ const \u5E45 = \u67A0\u306E\u5E45(\u884C\u3089(it));
28166
+ const \u88DC\u8DB3 = (it.subtitle ?? "").trim();
28167
+ const \u88DC\u8DB3\u306E\u5B57 = SUB_FONT * \u53CE\u3081\u308B\u500D\u7387(
28168
+ \u88DC\u8DB3,
28169
+ { fontSize: SUB_FONT, fontWeight: 500 },
28170
+ Math.max(0, \u5E45 - ITEM_PAD_X * 2)
28171
+ );
28172
+ return /* @__PURE__ */ jsxs("g", { children: [
28173
+ /* @__PURE__ */ jsx(
28174
+ "rect",
28175
+ {
28176
+ "data-cdl-role": "quadrant-item",
28177
+ "data-cdl-unresolved": it.unresolved ? "true" : void 0,
28178
+ x: qxStart,
28179
+ y: py,
28180
+ width: \u5E45,
28181
+ height: rowH,
28182
+ rx: 6,
28183
+ fill: "var(--cdl-node-fill, #ffffff)",
28184
+ stroke: quadrantAccent[q],
28185
+ strokeWidth: 1.5
28186
+ }
28187
+ ),
28188
+ /* @__PURE__ */ jsx(
28189
+ "text",
28190
+ {
28191
+ x: qxStart + ITEM_PAD_X,
28192
+ y: \u88DC\u8DB3 === "" ? py + rowH / 2 + 5 : py + rowH / 2 - 2,
28193
+ fontSize: ITEM_FONT,
28194
+ fontWeight: 600,
28195
+ letterSpacing: 0,
28196
+ fill: "var(--cdl-text, #1a1f2a)",
28197
+ children: it.title
28198
+ }
28199
+ ),
28200
+ \u88DC\u8DB3 !== "" && /* @__PURE__ */ jsx(
28201
+ "text",
28202
+ {
28203
+ "data-cdl-role": "quadrant-item-subtitle",
28204
+ x: qxStart + ITEM_PAD_X,
28205
+ y: py + rowH / 2 + 11,
28206
+ fontSize: \u88DC\u8DB3\u306E\u5B57,
28207
+ fontWeight: 500,
28208
+ letterSpacing: 0,
28209
+ fill: "var(--cdl-text-dim, #5a6270)",
28210
+ children: \u88DC\u8DB3
28211
+ }
28212
+ )
28213
+ ] }, `item-${it.id}`);
28214
+ }),
28215
+ \u7573\u3080 ? (
28216
+ /*
28217
+ 畳んだ段は名前の段と見た目を分ける。 同じにすると「ほか 3 件」 という名前の
28218
+ 項目があるように読める。 枠を持たず、点線の下線と薄い字で「続きがある」 ことを表す。
28219
+ */
28220
+ /* @__PURE__ */ jsxs("g", { children: [
28221
+ /* @__PURE__ */ jsx(
28222
+ "line",
28223
+ {
28224
+ "data-cdl-role": "quadrant-more-rule",
28225
+ x1: qxStart,
28226
+ y1: qyStart + \u540D\u524D\u3092\u51FA\u3059.length * (rowH + gap) + rowH / 2 + 9,
28227
+ x2: qxStart + \u67A0\u306E\u5E45([{ text: \u7573\u3093\u3060\u6587(\u7573\u3093\u3060\u4EF6\u6570), size: ITEM_FONT, weight: 600 }]),
28228
+ y2: qyStart + \u540D\u524D\u3092\u51FA\u3059.length * (rowH + gap) + rowH / 2 + 9,
28229
+ stroke: quadrantAccent[q],
28230
+ strokeWidth: 1,
28231
+ strokeDasharray: "3 3",
28232
+ strokeOpacity: 0.6
28233
+ }
28234
+ ),
28235
+ /* @__PURE__ */ jsx(
28236
+ "text",
28237
+ {
28238
+ "data-cdl-role": "quadrant-more",
28239
+ x: qxStart + ITEM_PAD_X,
28240
+ y: qyStart + \u540D\u524D\u3092\u51FA\u3059.length * (rowH + gap) + rowH / 2 + 5,
28241
+ fontSize: ITEM_FONT,
28242
+ fontWeight: 600,
28243
+ letterSpacing: 0,
28244
+ fill: quadrantAccent[q],
28245
+ children: \u7573\u3093\u3060\u6587(\u7573\u3093\u3060\u4EF6\u6570)
28246
+ }
28247
+ )
28248
+ ] }, `more-${q}`)
28249
+ ) : null
28250
+ ] }, `q-${q}`);
28251
+ }),
28252
+ \u70B9\u3067\u7F6E\u304F.map((it) => {
28253
+ const at = it.at;
28254
+ const px = PAD_LEFT2 + at.x * canvasW;
28255
+ const py = PAD_TOP2 + (1 - at.y) * canvasH;
28256
+ const \u53F3\u5BC4\u308A = at.x >= 0.5;
28257
+ const \u540D\u524D\u306Ex = px + (\u53F3\u5BC4\u308A ? -11 : POINT_R + POINT_GAP);
28258
+ const \u5BC4\u305B = \u53F3\u5BC4\u308A ? "end" : "start";
28259
+ const \u88DC\u8DB3 = (it.subtitle ?? "").trim();
28260
+ return /* @__PURE__ */ jsxs("g", { "data-cdl-unresolved": it.unresolved ? "true" : void 0, children: [
28261
+ /* @__PURE__ */ jsx(
28262
+ "circle",
28263
+ {
28264
+ "data-cdl-role": "quadrant-point",
28265
+ cx: px,
28266
+ cy: py,
28267
+ r: POINT_R,
28268
+ fill: quadrantAccent[it.quadrant]
28269
+ }
28270
+ ),
28271
+ /* @__PURE__ */ jsx(
28272
+ "text",
28273
+ {
28274
+ "data-cdl-role": "quadrant-point-label",
28275
+ x: \u540D\u524D\u306Ex,
28276
+ y: \u88DC\u8DB3 === "" ? py + 4 : py - 1,
28277
+ fontSize: ITEM_FONT,
28278
+ fontWeight: 600,
28279
+ letterSpacing: 0,
28280
+ textAnchor: \u5BC4\u305B,
28281
+ fill: "var(--cdl-text, #1a1f2a)",
28282
+ children: it.title
28283
+ }
28284
+ ),
28285
+ \u88DC\u8DB3 !== "" && /* @__PURE__ */ jsx(
28286
+ "text",
28287
+ {
28288
+ "data-cdl-role": "quadrant-point-subtitle",
28289
+ x: \u540D\u524D\u306Ex,
28290
+ y: py + 11,
28291
+ fontSize: SUB_FONT,
28292
+ fontWeight: 500,
28293
+ letterSpacing: 0,
28294
+ textAnchor: \u5BC4\u305B,
28295
+ fill: "var(--cdl-text-dim, #5a6270)",
28296
+ children: \u88DC\u8DB3
28297
+ }
28298
+ )
28299
+ ] }, `at-${it.id}`);
27698
28300
  })
27699
28301
  ] });
27700
28302
  }
@@ -28587,12 +29189,13 @@ function ShapeTerminalNode({ node, active, lang }) {
28587
29189
  const \u5148\u982D = 26;
28588
29190
  const \u884C\u9593 = 22;
28589
29191
  const \u30AB\u30FC\u30BD\u30EB = { \u5DE6: 30, \u5E45: 9, \u9AD8: 14, \u4E0A: 11, \u4E0B: 3 };
29192
+ const \u51FA\u529B = \u66F8\u3044\u305F\u5024\u304B\u63A7\u3048(node.subtitle, \u5B57\u5F15("terminal.output"));
28590
29193
  const \u884C = [
28591
29194
  [
28592
29195
  { \u5DE6: 16, \u5B57: 12.5, \u8272: "#7cd88f", \u6587: "$" },
28593
29196
  { \u5DE6: 30, \u5B57: 12.5, \u8272: "#e6edf3", \u6587: "pnpm build" }
28594
29197
  ],
28595
- [{ \u5DE6: 16, \u5B57: 12.5, \u8272: "#8b95a5", \u6587: \u5B57\u5F15("terminal.output") }],
29198
+ [{ \u5DE6: 16, \u5B57: 12.5, \u8272: "#8b95a5", \u6587: \u51FA\u529B }],
28596
29199
  [{ \u5DE6: 16, \u5B57: 12.5, \u8272: "#7cd88f", \u6587: "$" }]
28597
29200
  ];
28598
29201
  const \u81EA\u7136\u5E45 = Math.max(...\u884C.flat().map((c) => c.\u5DE6 + \u7B49\u5E45\u306E\u6841(c.\u6587) * MONO_ADVANCE * c.\u5B57)) + \u4F59\u767D;
@@ -28714,7 +29317,9 @@ function ShapeCodeBlockNode({ node, active, lang }) {
28714
29317
  const w = Math.max(0, node.w - \u7DDA * 2);
28715
29318
  const bodyH = Math.max(0, node.h - 42 - \u7DDA * 2);
28716
29319
  const lineFont = "ui-monospace, SFMono-Regular, Menlo, monospace";
28717
- const \u30BF\u30D6\u5E45 = 100;
29320
+ const \u672D = \u66F8\u3044\u305F\u5024\u304B\u63A7\u3048(node.subtitle, \u5B57\u5F15("codeBlock.fileName"));
29321
+ const \u672D\u306E\u5B57 = 11;
29322
+ const \u30BF\u30D6\u5E45 = Math.min(Math.max(100, textWidth(\u672D, \u672D\u306E\u5B57, 0) + 24), Math.max(0, w));
28718
29323
  const \u30BF\u30D6\u9AD8 = 24;
28719
29324
  const \u89D2 = 10;
28720
29325
  const \u6E9D = 32;
@@ -28751,7 +29356,7 @@ function ShapeCodeBlockNode({ node, active, lang }) {
28751
29356
  const \u81EA\u7136\u9AD8 = \u30BF\u30D6\u9AD8 + \u884C\u982D + \u884C\u9593 * (lines.length - 1) + Math.max(\u592A\u3055 - \u6301\u3061\u4E0A\u3052, \u884C\u756A\u53F7\u306E\u5B57 * DESCENT3);
28752
29357
  const \u500D = Math.min(1, bodyH / \u81EA\u7136\u9AD8);
28753
29358
  const \u6253\u3061\u6D88\u3059\u5B57\u3089 = [
28754
- { text: \u5B57\u5F15("codeBlock.fileName"), size: 11, \u5E2F: { \u5E45: \u30BF\u30D6\u5E45, \u9AD8\u3055: \u30BF\u30D6\u9AD8 } },
29359
+ { text: \u672D, size: \u672D\u306E\u5B57, \u5E2F: { \u5E45: \u30BF\u30D6\u5E45, \u9AD8\u3055: \u30BF\u30D6\u9AD8 } },
28755
29360
  { text: "1", size: \u884C\u756A\u53F7\u306E\u5B57, \u5E2F: { \u5E45: \u6E9D - \u6301\u3061\u4E0A\u3052, \u9AD8\u3055: \u884C\u9593 } }
28756
29361
  ];
28757
29362
  const \u500D\u8FD4\u3057 = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D, \u6253\u3061\u6D88\u3059\u5B57\u3089);
@@ -28793,11 +29398,11 @@ function ShapeCodeBlockNode({ node, active, lang }) {
28793
29398
  "data-cdl-counter-scaled": "1",
28794
29399
  x: x + tabW / 2,
28795
29400
  y: y + tabH / 2 + 4 * \u500D,
28796
- fontSize: 11 * \u500D * \u500D\u8FD4\u3057,
29401
+ fontSize: \u672D\u306E\u5B57 * \u500D * \u500D\u8FD4\u3057 * \u5E45\u306E\u500D\u7387(\u672D, \u672D\u306E\u5B57 * \u500D * \u500D\u8FD4\u3057, 0, tabW),
28797
29402
  fontFamily: lineFont,
28798
29403
  textAnchor: "middle",
28799
29404
  fill: "#e6edf3",
28800
- children: \u5B57\u5F15("codeBlock.fileName")
29405
+ children: \u672D
28801
29406
  }
28802
29407
  ),
28803
29408
  /* @__PURE__ */ jsx("circle", { cx: x + tabW - \u4E38, cy: y + tabH / 2, r: 3 * \u500D, fill: "#7cd88f", stroke: "none" }),
@@ -28897,6 +29502,7 @@ function ShapeKanbanCardNode({ node, active, lang }) {
28897
29502
  const PILL\u9AD8 = 16;
28898
29503
  const PILL\u5B57 = 11;
28899
29504
  const PILL\u5B57\u9593 = 0;
29505
+ const PILL\u5B57\u5E45 = PILL\u5E45 - 6;
28900
29506
  const FOOTER\u4E0B = 22;
28901
29507
  const AVATAR\u4E2D\u5FC3Y = 4;
28902
29508
  const AVATAR\u534A\u5F84 = 9;
@@ -28926,6 +29532,11 @@ function ShapeKanbanCardNode({ node, active, lang }) {
28926
29532
  \u4E0B: size * \u8AAC\u660E\u57FA\u6E96\u6BD4 + size * \u8AAC\u660E\u5B57\u6BD4 * DESCENT3
28927
29533
  })
28928
29534
  );
29535
+ const \u8AAC\u660E = \u66F8\u3044\u305F\u5024\u304B\u63A7\u3048(node.subtitle, \u5B57\u5F15("kanbanCard.task"));
29536
+ const \u72B6\u614B = \u66F8\u3044\u305F\u5024\u304B\u63A7\u3048(node.eyebrow, \u5B57\u5F15("kanbanCard.status"));
29537
+ const \u72B6\u614B\u306E\u500D\u7387 = \u5E45\u306E\u500D\u7387(\u72B6\u614B, PILL\u5B57, PILL\u5B57\u9593, PILL\u5B57\u5E45);
29538
+ const \u8AAC\u660E\u306E\u5B57 = \u540D\u524D.size * \u8AAC\u660E\u5B57\u6BD4;
29539
+ const \u4F7F\u3048\u308B\u5E452 = Math.max(0, w - \u5DE6\u53F3\u4F59\u767D * \u500D * 2);
28929
29540
  return /* @__PURE__ */ jsxs("g", { children: [
28930
29541
  /* @__PURE__ */ jsx(
28931
29542
  "rect",
@@ -28980,15 +29591,16 @@ function ShapeKanbanCardNode({ node, active, lang }) {
28980
29591
  /* @__PURE__ */ jsx(
28981
29592
  "text",
28982
29593
  {
29594
+ "data-cdl-role": "kanban-status",
28983
29595
  x: x + w - (\u5DE6\u53F3\u4F59\u767D + PILL\u5E45 / 2) * \u500D,
28984
29596
  y: pillY + 12 * \u500D,
28985
- fontSize: PILL\u5B57 * \u500D,
29597
+ fontSize: PILL\u5B57 * \u500D * \u72B6\u614B\u306E\u500D\u7387,
28986
29598
  fontWeight: 700,
28987
- letterSpacing: PILL\u5B57\u9593 * \u500D,
29599
+ letterSpacing: PILL\u5B57\u9593 * \u500D * \u72B6\u614B\u306E\u500D\u7387,
28988
29600
  textAnchor: "middle",
28989
29601
  fill: "#5a4a1a",
28990
29602
  fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
28991
- children: \u5B57\u5F15("kanbanCard.status")
29603
+ children: \u72B6\u614B
28992
29604
  }
28993
29605
  ),
28994
29606
  /* @__PURE__ */ jsx(
@@ -29009,10 +29621,10 @@ function ShapeKanbanCardNode({ node, active, lang }) {
29009
29621
  {
29010
29622
  x: x + w / 2,
29011
29623
  y: \u540D\u524D.y + \u540D\u524D.size * \u8AAC\u660E\u57FA\u6E96\u6BD4,
29012
- fontSize: \u540D\u524D.size * \u8AAC\u660E\u5B57\u6BD4,
29624
+ fontSize: \u8AAC\u660E\u306E\u5B57 * \u5E45\u306E\u500D\u7387(\u8AAC\u660E, \u8AAC\u660E\u306E\u5B57, 0, \u4F7F\u3048\u308B\u5E452),
29013
29625
  textAnchor: "middle",
29014
29626
  fill: "var(--cdl-text-dim, #5a6270)",
29015
- children: \u5B57\u5F15("kanbanCard.task")
29627
+ children: \u8AAC\u660E
29016
29628
  }
29017
29629
  ),
29018
29630
  /* @__PURE__ */ jsxs("g", { transform: `translate(${x + \u5DE6\u53F3\u4F59\u767D * \u500D}, ${footY})`, children: [
@@ -30030,6 +30642,7 @@ var SMART_CONTRACT_H = 220;
30030
30642
  var BLOCK_W = 240;
30031
30643
  var BLOCK_H = 220;
30032
30644
  var \u898B\u51FA\u3057\u306E\u5B57 = 13;
30645
+ var \u80A9\u66F8\u306E\u5B57 = 10;
30033
30646
  var \u540D\u306E\u5B57 = 11;
30034
30647
  var \u5024\u306E\u5B57 = 11;
30035
30648
  var \u884C\u306E\u9593\u9694 = 22;
@@ -30105,11 +30718,6 @@ function blockchainNodeExtent(strokeWidth) {
30105
30718
  const \u6A2A = (NODE_PEER_DIST + NODE_PEER_R) * Math.cos(Math.PI / 6) + \u7DDA;
30106
30719
  return { \u4E0A: \u7E26, \u4E0B: \u7E26, \u5DE6: \u6A2A, \u53F3: \u6A2A };
30107
30720
  }
30108
- function \u5E45\u306E\u500D\u7387(text, size, letterSpacing, \u5E45) {
30109
- if (!(\u5E45 > 0) || !(size > 0)) return 1;
30110
- const \u5B9F\u5E45 = textWidth(text, size, letterSpacing);
30111
- return \u5B9F\u5E45 > \u5E45 ? \u5E45 / \u5B9F\u5E45 : 1;
30112
- }
30113
30721
  function bottomLabel2(node, cx, plan) {
30114
30722
  const \u80A9\u66F8\u500D\u7387 = node.eyebrow && plan.\u80A9\u66F8 ? \u5E45\u306E\u500D\u7387(node.eyebrow, plan.\u80A9\u66F8.size, 2, node.w) : 1;
30115
30723
  const \u540D\u524D\u500D\u7387 = \u5E45\u306E\u500D\u7387(node.title, plan.\u540D\u524D.size, 0, node.w);
@@ -30227,9 +30835,18 @@ function ShapeBlockchainBlockNode({ node, active, lang }) {
30227
30835
  value: f.key === "hash" ? \u6E21\u3055\u308C\u305F(node.subtitle) || \u65E2\u5B9A\u5024 : \u65E2\u5B9A\u5024
30228
30836
  };
30229
30837
  });
30230
- const \u898B\u51FA\u3057\u306E\u5E45 = bw - 14 - 30;
30838
+ const \u80A9\u66F8 = \u6E21\u3055\u308C\u305F(node.eyebrow);
30839
+ const \u5E2F\u306E\u6B8B\u308A = bw - 14 - 30;
30840
+ const \u80A9\u66F8\u306E\u9699\u9593 = 8;
30841
+ const \u80A9\u66F8\u306E\u4E0A\u9650 = (\u5E2F\u306E\u6B8B\u308A - \u80A9\u66F8\u306E\u9699\u9593) / 2;
30842
+ 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);
30843
+ const \u80A9\u66F8\u306E\u6307\u5B9A = \u80A9\u66F8\u306E\u5B57 * \u80A9\u66F8\u306E\u500D\u7387;
30844
+ const \u80A9\u66F8\u306E\u5E45 = \u80A9\u66F8 === "" ? 0 : \u5B57\u306E\u5E45(\u80A9\u66F8, \u80A9\u66F8\u306E\u6307\u5B9A);
30845
+ const \u898B\u51FA\u3057\u306E\u5E45 = \u5E2F\u306E\u6B8B\u308A - (\u80A9\u66F8 === "" ? 0 : \u80A9\u66F8\u306E\u5E45 + \u80A9\u66F8\u306E\u9699\u9593);
30231
30846
  const \u6253\u3061\u6D88\u3059\u5B57\u3089 = [
30232
30847
  { text: \u898B\u51FA\u3057, size: \u898B\u51FA\u3057\u306E\u5B57, \u5E2F: { \u5E45: \u898B\u51FA\u3057\u306E\u5E45, \u9AD8\u3055: \u898B\u51FA\u3057\u306E\u5E2F } },
30848
+ // 肩書も帯に入れる = 入れないと打ち消しの倍率が肩書を見ずに決まり、帯から横へ出る
30849
+ ...\u80A9\u66F8 === "" ? [] : [{ text: \u80A9\u66F8, size: \u80A9\u66F8\u306E\u6307\u5B9A, \u5E2F: { \u5E45: \u80A9\u66F8\u306E\u5E45, \u9AD8\u3055: \u898B\u51FA\u3057\u306E\u5E2F } }],
30233
30850
  ...fields.flatMap((f) => [
30234
30851
  { text: f.label, size: \u540D\u306E\u5B57, \u5E2F: { \u5E45: bw - 28, \u9AD8\u3055: \u884C\u306E\u9593\u9694 } },
30235
30852
  {
@@ -30242,6 +30859,7 @@ function ShapeBlockchainBlockNode({ node, active, lang }) {
30242
30859
  const art = (\u500D\u7387) => {
30243
30860
  const \u500D = \u6253\u3061\u6D88\u3057\u306E\u500D\u7387(\u500D\u7387, \u6253\u3061\u6D88\u3059\u5B57\u3089);
30244
30861
  const \u984C\u306E\u5927\u304D\u3055 = \u898B\u51FA\u3057\u306E\u5B57 * \u500D;
30862
+ const \u80A9\u66F8\u306E\u5927\u304D\u3055 = \u80A9\u66F8\u306E\u6307\u5B9A * \u500D;
30245
30863
  const \u540D\u306E\u5927\u304D\u3055 = \u540D\u306E\u5B57 * \u500D;
30246
30864
  const \u5024\u306E\u5927\u304D\u3055 = \u5024\u306E\u5B57 * \u500D;
30247
30865
  return /* @__PURE__ */ jsxs("g", { children: [
@@ -30249,6 +30867,22 @@ function ShapeBlockchainBlockNode({ node, active, lang }) {
30249
30867
  /* @__PURE__ */ jsx("rect", { "data-cdl-role": "node-body", x, y, width: bw, height: bh, rx: 8, ...frame }),
30250
30868
  /* @__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" }),
30251
30869
  /* @__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) }),
30870
+ \u80A9\u66F8 !== "" && /* @__PURE__ */ jsx(
30871
+ "text",
30872
+ {
30873
+ "data-cdl-role": "blockchain-block-eyebrow",
30874
+ "data-cdl-counter-scaled": "1",
30875
+ x: x + bw - 30,
30876
+ y: y + 21,
30877
+ fontSize: \u80A9\u66F8\u306E\u5927\u304D\u3055,
30878
+ fontWeight: 600,
30879
+ textAnchor: "end",
30880
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
30881
+ fill: "#ffffff",
30882
+ fillOpacity: 0.78,
30883
+ children: \u80A9\u66F8
30884
+ }
30885
+ ),
30252
30886
  /* @__PURE__ */ jsx("circle", { cx: x + bw - 16, cy: y + 16, r: 5.5, fill: "#7cd88f", stroke: "#ffffff", strokeWidth: 1.5 }),
30253
30887
  fields.map((f, i) => /* @__PURE__ */ jsxs("g", { children: [
30254
30888
  /* @__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 }),
@@ -30310,7 +30944,7 @@ function ShapeBlockchainNode({ node, active }) {
30310
30944
  420 + i
30311
30945
  ] }),
30312
30946
  /* @__PURE__ */ jsx("text", { "data-cdl-counter-scaled": "0", x: bx + blockW / 2, y: cy + 8, fontSize: 14, fontWeight: 700, textAnchor: "middle", fill: isCurrent ? "#ffffff" : "var(--cdl-tone-accent, #2d6a8f)", fontFamily: "Georgia, serif", children: "#" }),
30313
- /* @__PURE__ */ jsx("text", { "data-cdl-counter-scaled": "1", x: bx + blockW / 2, y: cy + 22, fontSize: CHAIN_HASH_SIZE * \u500D, fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace", textAnchor: "middle", fill: isCurrent ? "#ffffff" : "var(--cdl-text-dim, #5a6270)", opacity: 0.9, children: "0x\u2026" })
30947
+ /* @__PURE__ */ jsx("text", { "data-cdl-ellipsis": "written", "data-cdl-counter-scaled": "1", x: bx + blockW / 2, y: cy + 22, fontSize: CHAIN_HASH_SIZE * \u500D, fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace", textAnchor: "middle", fill: isCurrent ? "#ffffff" : "var(--cdl-text-dim, #5a6270)", opacity: 0.9, children: "0x\u2026" })
30314
30948
  ] }, i);
30315
30949
  }) });
30316
30950
  };
@@ -31345,13 +31979,18 @@ function ShapeWarehouseNode({ node, active, lang }) {
31345
31979
  bottomLabel4(node, r.cx, r.label)
31346
31980
  ] });
31347
31981
  }
31982
+ var HANDLE_GRIP_X = 118;
31983
+ var HANDLE_GRIP_R = 4;
31984
+ var CART_SHADOW_RX = 80;
31348
31985
  function ShapeOnlineShopNode({ node, active }) {
31349
31986
  const frame = commonFrame6(active);
31350
31987
  const r = shapeRegion(node);
31351
- const cx = r.cx;
31352
31988
  const cy = r.cy + 10;
31353
31989
  const scale = Math.min(r.availW / 260, r.availH / 320);
31354
31990
  const s = scale * 0.9;
31991
+ const \u5DE6\u3078\u51FA\u308B = HANDLE_GRIP_X + HANDLE_GRIP_R;
31992
+ const \u53F3\u3078\u51FA\u308B = CART_SHADOW_RX;
31993
+ const cx = r.cx + (\u5DE6\u3078\u51FA\u308B - \u53F3\u3078\u51FA\u308B) / 2 * s;
31355
31994
  const accent = "var(--cdl-tone-accent, #2d6a8f)";
31356
31995
  const accentDark = "#1a4a68";
31357
31996
  const accentDarker = "#0f3450";
@@ -31365,9 +32004,9 @@ function ShapeOnlineShopNode({ node, active }) {
31365
32004
  const wheelL = cx - 42 * s;
31366
32005
  const wheelR = cx + 42 * s;
31367
32006
  return /* @__PURE__ */ jsxs("g", { children: [
31368
- /* @__PURE__ */ jsx("ellipse", { cx, cy: wheelY + 22 * s, rx: 80 * s, ry: 5 * s, fill: frame.stroke, opacity: 0.25, stroke: "none" }),
31369
- /* @__PURE__ */ jsx("path", { d: `M ${cx - 118 * s} ${basketTopY - 60 * s} L ${cx - 90 * s} ${basketTopY - 60 * s} L ${cx - 80 * s} ${basketTopY - 30 * s} L ${basketTopL} ${basketTopY}`, fill: "none", stroke: accent, strokeWidth: 6 * s, strokeLinecap: "round", strokeLinejoin: "round" }),
31370
- /* @__PURE__ */ jsx("circle", { cx: cx - 118 * s, cy: basketTopY - 60 * s, r: 4 * s, fill: accent, stroke: accentDark, strokeWidth: 1.5 }),
32007
+ /* @__PURE__ */ jsx("ellipse", { cx, cy: wheelY + 22 * s, rx: CART_SHADOW_RX * s, ry: 5 * s, fill: frame.stroke, opacity: 0.25, stroke: "none" }),
32008
+ /* @__PURE__ */ jsx("path", { d: `M ${cx - HANDLE_GRIP_X * s} ${basketTopY - 60 * s} L ${cx - 90 * s} ${basketTopY - 60 * s} L ${cx - 80 * s} ${basketTopY - 30 * s} L ${basketTopL} ${basketTopY}`, fill: "none", stroke: accent, strokeWidth: 6 * s, strokeLinecap: "round", strokeLinejoin: "round" }),
32009
+ /* @__PURE__ */ jsx("circle", { cx: cx - HANDLE_GRIP_X * s, cy: basketTopY - 60 * s, r: HANDLE_GRIP_R * s, fill: accent, stroke: accentDark, strokeWidth: 1.5 }),
31371
32010
  /* @__PURE__ */ jsx(
31372
32011
  "path",
31373
32012
  {
@@ -32185,11 +32824,58 @@ function CdlNodeView({
32185
32824
  pointerEvents: "none"
32186
32825
  }
32187
32826
  ),
32188
- inner
32827
+ inner,
32828
+ \u7BB1\u306E\u4E0A\u306E\u8A9E(resolvedNode)
32189
32829
  ]
32190
32830
  }
32191
32831
  );
32192
32832
  }
32833
+ var FIGURE_TITLE_GAP = 10;
32834
+ var FIGURE_TITLE_SIZE = 15;
32835
+ var FIGURE_EYEBROW_SIZE = 11;
32836
+ var FIGURE_EYEBROW_LIFT = 1.1;
32837
+ function \u5E45\u306B\u53CE\u3081\u305F\u5927\u304D\u3055(\u8A9E, \u7D20\u306E\u5927\u304D\u3055, \u5E45) {
32838
+ const \u5B9F\u5E45 = textWidth(\u8A9E, \u7D20\u306E\u5927\u304D\u3055, 0);
32839
+ return \u5B9F\u5E45 > \u5E45 ? \u7D20\u306E\u5927\u304D\u3055 * \u5E45 / \u5B9F\u5E45 : \u7D20\u306E\u5927\u304D\u3055;
32840
+ }
32841
+ function \u7BB1\u306E\u4E0A\u306E\u8A9E(node) {
32842
+ if (!drawsFigureTitle(node.kind)) return null;
32843
+ const \u540D\u524D = (node.title ?? "").trim();
32844
+ const \u5C0F\u898B\u51FA\u3057 = (node.eyebrow ?? "").trim();
32845
+ if (\u540D\u524D === "" && \u5C0F\u898B\u51FA\u3057 === "") return null;
32846
+ const \u984C\u306Ey = node.cy - node.h / 2 - FIGURE_TITLE_GAP;
32847
+ const \u984C\u306E\u5927\u304D\u3055 = \u5E45\u306B\u53CE\u3081\u305F\u5927\u304D\u3055(\u540D\u524D, FIGURE_TITLE_SIZE, node.w);
32848
+ const \u5C0F\u898B\u51FA\u3057\u306Ey = \u540D\u524D === "" ? \u984C\u306Ey : \u984C\u306Ey - \u984C\u306E\u5927\u304D\u3055 * FIGURE_EYEBROW_LIFT;
32849
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
32850
+ \u5C0F\u898B\u51FA\u3057 !== "" && /* @__PURE__ */ jsx(
32851
+ "text",
32852
+ {
32853
+ "data-cdl-role": "figure-eyebrow",
32854
+ x: node.cx,
32855
+ y: \u5C0F\u898B\u51FA\u3057\u306Ey,
32856
+ textAnchor: "middle",
32857
+ fontSize: \u5E45\u306B\u53CE\u3081\u305F\u5927\u304D\u3055(\u5C0F\u898B\u51FA\u3057, FIGURE_EYEBROW_SIZE, node.w),
32858
+ fontWeight: 600,
32859
+ letterSpacing: 0.6,
32860
+ fill: "var(--cdl-text-dim, #5a6270)",
32861
+ children: \u5C0F\u898B\u51FA\u3057
32862
+ }
32863
+ ),
32864
+ \u540D\u524D !== "" && /* @__PURE__ */ jsx(
32865
+ "text",
32866
+ {
32867
+ "data-cdl-role": "figure-title",
32868
+ x: node.cx,
32869
+ y: \u984C\u306Ey,
32870
+ textAnchor: "middle",
32871
+ fontSize: \u984C\u306E\u5927\u304D\u3055,
32872
+ fontWeight: 600,
32873
+ fill: "var(--cdl-text, #23201b)",
32874
+ children: \u540D\u524D
32875
+ }
32876
+ )
32877
+ ] });
32878
+ }
32193
32879
 
32194
32880
  // src/render/relation-focus.ts
32195
32881
  function relatedFocusSet(edges, nodeId) {
@@ -32202,6 +32888,11 @@ function relatedFocusSet(edges, nodeId) {
32202
32888
  }
32203
32889
  return \u96C6\u5408;
32204
32890
  }
32891
+ function \u63CF\u304F\u3082\u306E\u304C\u3042\u308B(laid) {
32892
+ if (laid.edges.length > 0) return true;
32893
+ if (laid.nodes.some((n) => isRenderedNode(n))) return true;
32894
+ return laid.lanes.some((l) => l.contain === true || l.lifeline === true || Boolean(l.label));
32895
+ }
32205
32896
  function CdlStage({
32206
32897
  laid,
32207
32898
  currentPhase,
@@ -32360,6 +33051,7 @@ function CdlStage({
32360
33051
  );
32361
33052
  }, [laid]);
32362
33053
  const diagramScale = laid.diagramScale ?? 1;
33054
+ if (!\u63CF\u304F\u3082\u306E\u304C\u3042\u308B(laid)) return null;
32363
33055
  return /* @__PURE__ */ jsxs("div", { className: compact ? "px-3 py-3" : "px-6 py-6", style: compact ? void 0 : { minHeight: 460 }, children: [
32364
33056
  /* @__PURE__ */ jsxs(
32365
33057
  "svg",
@@ -33608,7 +34300,7 @@ function tree(preset) {
33608
34300
  stack: 0,
33609
34301
  kind: "tree-hierarchy",
33610
34302
  title: preset.topic,
33611
- eyebrow: "tree",
34303
+ ...preset.eyebrow ? { eyebrow: preset.eyebrow } : {},
33612
34304
  w: canvasW,
33613
34305
  h: canvasH,
33614
34306
  treeData: treeNodes.map((n) => ({
@@ -33646,7 +34338,7 @@ function userJourney(preset) {
33646
34338
  stack: 0,
33647
34339
  kind: "journey-map",
33648
34340
  title: preset.topic,
33649
- eyebrow: "userJourney",
34341
+ ...preset.eyebrow ? { eyebrow: preset.eyebrow } : {},
33650
34342
  w: canvasW,
33651
34343
  h: canvasH,
33652
34344
  journeyData: steps.map((s) => ({
@@ -33686,7 +34378,7 @@ function mindMap(preset) {
33686
34378
  stack: 0,
33687
34379
  kind: "mind-map",
33688
34380
  title: preset.topic,
33689
- eyebrow: "mindMap",
34381
+ ...preset.eyebrow ? { eyebrow: preset.eyebrow } : {},
33690
34382
  w: canvasW,
33691
34383
  h: canvasH,
33692
34384
  mindData: {
@@ -33730,7 +34422,7 @@ function funnel(preset) {
33730
34422
  stack: 0,
33731
34423
  kind: "funnel-stages",
33732
34424
  title: preset.topic,
33733
- eyebrow: "funnel",
34425
+ ...preset.eyebrow ? { eyebrow: preset.eyebrow } : {},
33734
34426
  w: canvasW,
33735
34427
  h: canvasH,
33736
34428
  funnelData: stages.map((s) => ({
@@ -33774,7 +34466,7 @@ function quadrant(preset) {
33774
34466
  stack: 0,
33775
34467
  kind: "quadrant-matrix",
33776
34468
  title: preset.topic,
33777
- eyebrow: "quadrant",
34469
+ ...preset.eyebrow ? { eyebrow: preset.eyebrow } : {},
33778
34470
  w: canvasW,
33779
34471
  h: canvasH,
33780
34472
  quadrantData: {
@@ -33830,7 +34522,7 @@ function chart(preset) {
33830
34522
  stack: 0,
33831
34523
  kind: kindMap[preset.type],
33832
34524
  title: preset.topic,
33833
- eyebrow: preset.type,
34525
+ ...preset.eyebrow ? { eyebrow: preset.eyebrow } : {},
33834
34526
  w: canvasW,
33835
34527
  h: canvasH,
33836
34528
  chartData: data.map((d) => ({
@@ -33876,7 +34568,7 @@ function gantt(preset) {
33876
34568
  stack: 0,
33877
34569
  kind: "gantt-timeline",
33878
34570
  title: preset.topic,
33879
- eyebrow: "gantt",
34571
+ ...preset.eyebrow ? { eyebrow: preset.eyebrow } : {},
33880
34572
  w: canvasW,
33881
34573
  h: canvasH,
33882
34574
  // 宣言していない図には欄自体を載せない = 自動で決める経路をそのまま通す
@@ -34091,7 +34783,10 @@ function stateMachine2(preset) {
34091
34783
  label: t.trigger,
34092
34784
  ...subParts.length ? { sub: subParts.join(" ") } : {},
34093
34785
  tone: t.tone ?? tone,
34094
- style: "solid"
34786
+ style: "solid",
34787
+ // 遷移の印は 1 種類だけ = 実線に開いた矢 (#578)。 stateMachine と同じ値を渡す
34788
+ // (渡さないと EDGE_HEAD_DEFAULT の三角に落ち、入口を選び直しただけで印が変わる)
34789
+ head: "open"
34095
34790
  });
34096
34791
  phaseActivate.push(edgeId);
34097
34792
  return api;