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