@cardenelabs/dragon 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +111 -0
- package/dist/index.cjs +2365 -277
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +240 -3
- package/dist/index.d.ts +240 -3
- package/dist/index.js +2366 -279
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/compile.ts +2895 -258
- package/src/index.ts +4 -1
- package/src/input-size.ts +8 -1
- package/src/json-parser.ts +480 -30
- package/src/notation-lint.ts +27 -4
- package/src/schemas/diagram.json +56 -5
- package/src/types.ts +125 -0
- package/src/v05/parser.ts +341 -41
- package/src/value-syntax.ts +313 -0
package/dist/index.cjs
CHANGED
|
@@ -610,7 +610,7 @@ function countDocElements(doc) {
|
|
|
610
610
|
(acc, p) => acc + (p.highlight?.length ?? 0) + (p.tweens?.length ?? 0) + (p.sets?.length ?? 0),
|
|
611
611
|
0
|
|
612
612
|
);
|
|
613
|
-
return doc.actors.length + doc.flow.length + phases.length + phaseChildren + (doc.animate?.states.length ?? 0) + (doc.groups ? Object.keys(doc.groups).length : 0) + (doc.lanes ? Object.keys(doc.lanes).length : 0);
|
|
613
|
+
return doc.actors.length + doc.flow.length + phases.length + phaseChildren + (doc.animate?.states.length ?? 0) + (doc.values?.length ?? 0) + (doc.groups ? Object.keys(doc.groups).length : 0) + (doc.lanes ? Object.keys(doc.lanes).length : 0);
|
|
614
614
|
}
|
|
615
615
|
function countDiagramElements(diagram2) {
|
|
616
616
|
const phases = Array.isArray(diagram2.phases) ? diagram2.phases : [];
|
|
@@ -619,7 +619,8 @@ function countDiagramElements(diagram2) {
|
|
|
619
619
|
return acc + (Array.isArray(ph?.activate) ? ph.activate.length : 0) + (Array.isArray(ph?.highlight) ? ph.highlight.length : 0) + (Array.isArray(ph?.tweens) ? ph.tweens.length : 0) + (Array.isArray(ph?.sets) ? ph.sets.length : 0);
|
|
620
620
|
}, 0);
|
|
621
621
|
return (diagram2.nodes?.length ?? 0) + (diagram2.edges?.length ?? 0) + (diagram2.lanes?.length ?? 0) + (diagram2.states?.length ?? 0) + phases.length + phaseChildren + // 図が持てる並びは全部数える。 1 つでも外すと、そこに寄せた図が素通りする
|
|
622
|
-
(diagram2.readouts?.length ?? 0) + (diagram2.inputs?.length ?? 0) + (diagram2.formulas?.length ?? 0) + (diagram2.scrollTriggers?.length ?? 0) + (diagram2.eventBindings?.length ?? 0)
|
|
622
|
+
(diagram2.readouts?.length ?? 0) + (diagram2.inputs?.length ?? 0) + (diagram2.formulas?.length ?? 0) + (diagram2.scrollTriggers?.length ?? 0) + (diagram2.eventBindings?.length ?? 0) + // 他の値から決まる値 (#1162)。 記法側 (`countDocElements`) が数えるので、こちらも揃える
|
|
623
|
+
(diagram2.derived?.length ?? 0);
|
|
623
624
|
}
|
|
624
625
|
function countBytes(src) {
|
|
625
626
|
return new TextEncoder().encode(src).length;
|
|
@@ -725,6 +726,12 @@ function orderByDependency(items) {
|
|
|
725
726
|
function compileToCdl(doc, opts) {
|
|
726
727
|
const oversize = describeOversize({ elements: countDocElements(doc), bytes: 0 });
|
|
727
728
|
if (oversize) throw new Error(oversize);
|
|
729
|
+
doc = canonicalizeFlowActors(doc);
|
|
730
|
+
const \u66F8\u3044\u305F\u307E\u307E = doc;
|
|
731
|
+
doc = dropUnresolvedFlow(doc);
|
|
732
|
+
doc = dropSelfLoopFlow(doc);
|
|
733
|
+
const \u5206\u3051\u305F = disambiguateActorIds(doc, opts?.onNotice);
|
|
734
|
+
doc = \u5206\u3051\u305F.doc;
|
|
728
735
|
let diagram2;
|
|
729
736
|
switch (doc.type) {
|
|
730
737
|
case "sequence":
|
|
@@ -755,27 +762,64 @@ function compileToCdl(doc, opts) {
|
|
|
755
762
|
diagram2 = compileClass(doc);
|
|
756
763
|
break;
|
|
757
764
|
case "pie":
|
|
758
|
-
diagram2 =
|
|
765
|
+
diagram2 = compileValueChart(doc, "pie", "chart-pie", opts?.onNotice);
|
|
766
|
+
break;
|
|
767
|
+
case "bar":
|
|
768
|
+
diagram2 = compileValueChart(doc, "bar", "chart-bar", opts?.onNotice);
|
|
769
|
+
break;
|
|
770
|
+
case "line":
|
|
771
|
+
diagram2 = compileValueChart(doc, "line", "chart-line", opts?.onNotice);
|
|
772
|
+
break;
|
|
773
|
+
case "funnel":
|
|
774
|
+
diagram2 = compileFunnel(doc, opts?.onNotice);
|
|
775
|
+
break;
|
|
776
|
+
case "tree":
|
|
777
|
+
diagram2 = compileTree(doc, opts?.onNotice);
|
|
778
|
+
break;
|
|
779
|
+
case "journey":
|
|
780
|
+
diagram2 = compileJourney(doc, opts?.onNotice);
|
|
781
|
+
break;
|
|
782
|
+
case "quadrant":
|
|
783
|
+
diagram2 = compileQuadrant(doc, opts?.onNotice);
|
|
759
784
|
break;
|
|
760
785
|
case "c4":
|
|
761
786
|
diagram2 = compileC4(doc);
|
|
762
787
|
break;
|
|
763
788
|
case "mind":
|
|
764
|
-
diagram2 = compileMind(doc);
|
|
789
|
+
diagram2 = compileMind(doc, opts?.onNotice);
|
|
765
790
|
break;
|
|
766
791
|
default:
|
|
767
792
|
throw new Error(`unknown type: ${String(doc.type)}`);
|
|
768
793
|
}
|
|
794
|
+
const \u4F5C\u308A\u66FF\u3048\u305F\u5BFE\u8C61 = collectRenamedTargets(diagram2, \u5206\u3051\u305F.\u5143\u306E\u540D\u524D);
|
|
769
795
|
const edgeSourceLines = opts?.onEdgeSource ? /* @__PURE__ */ new Map() : void 0;
|
|
770
796
|
applyEdgeInlineOptions(diagram2, doc, edgeSourceLines);
|
|
771
|
-
if (edgeSourceLines) fillFlowEdgeSources(diagram2, doc, edgeSourceLines);
|
|
772
797
|
applyGroupContainers(diagram2, doc);
|
|
773
798
|
applyNodeTones(diagram2, doc);
|
|
774
|
-
reportMissingFocusTargets(
|
|
799
|
+
reportMissingFocusTargets(\u66F8\u3044\u305F\u307E\u307E, opts?.onNotice);
|
|
800
|
+
reportMissingFlowActors(\u66F8\u3044\u305F\u307E\u307E, opts?.onNotice);
|
|
801
|
+
reportSelfLoopFlow(\u66F8\u3044\u305F\u307E\u307E, opts?.onNotice);
|
|
802
|
+
reportFlowEndpointNotHonored(doc, \u5206\u3051\u305F.\u5143\u306E\u540D\u524D, opts?.onNotice);
|
|
803
|
+
reportLaneNotHonored(\u66F8\u3044\u305F\u307E\u307E, opts?.onNotice);
|
|
804
|
+
reportDocEyebrowNotHonored(\u66F8\u3044\u305F\u307E\u307E, opts?.onNotice);
|
|
805
|
+
reportChartFieldsNotHonored(\u66F8\u3044\u305F\u307E\u307E, opts?.onNotice);
|
|
806
|
+
reportAxesNotHonored(\u66F8\u3044\u305F\u307E\u307E, opts?.onNotice);
|
|
775
807
|
const placed = resolveRelativeDoc(diagram2, doc, opts?.onNotice, opts?.partsCatalog);
|
|
776
808
|
applyCanvasPivotPositions(diagram2, placed);
|
|
777
|
-
const
|
|
778
|
-
const
|
|
809
|
+
const \u8FFD\u52A0\u3057\u305F\u7E26\u5217 = [];
|
|
810
|
+
const extended = applyV05Extensions(diagram2, placed, \u8FFD\u52A0\u3057\u305F\u7E26\u5217);
|
|
811
|
+
const inheritedDerivedSourceLines = opts?.onNotice ? /* @__PURE__ */ new Map() : void 0;
|
|
812
|
+
for (const value of extended.derived ?? []) {
|
|
813
|
+
recordDerivedSourceLine(inheritedDerivedSourceLines, value.id, 0);
|
|
814
|
+
}
|
|
815
|
+
const merged = mergePartsFromActors(
|
|
816
|
+
extended,
|
|
817
|
+
placed,
|
|
818
|
+
opts?.partsCatalog,
|
|
819
|
+
opts?.onNotice,
|
|
820
|
+
inheritedDerivedSourceLines
|
|
821
|
+
);
|
|
822
|
+
reportEmptyDeclaredLanes(merged, \u8FFD\u52A0\u3057\u305F\u7E26\u5217, opts?.onNotice);
|
|
779
823
|
if (edgeSourceLines && opts?.onEdgeSource) {
|
|
780
824
|
const alive = new Set(merged.edges.map((e) => e.id));
|
|
781
825
|
for (const [id, line] of edgeSourceLines) {
|
|
@@ -783,6 +827,10 @@ function compileToCdl(doc, opts) {
|
|
|
783
827
|
}
|
|
784
828
|
}
|
|
785
829
|
injectStaticPhase(merged);
|
|
830
|
+
materializeStates(merged, doc);
|
|
831
|
+
\u8A9E\u306E\u72B6\u614B\u3092\u56F3\u306E\u8A9E\u3078\u76F4\u3059(merged);
|
|
832
|
+
const \u7573\u3093\u3060\u304D\u3063\u304B\u3051 = foldValueTriggers(merged, doc, opts?.onNotice);
|
|
833
|
+
attachDerivedValues(merged, doc, opts?.onNotice, inheritedDerivedSourceLines, \u7573\u3093\u3060\u304D\u3063\u304B\u3051);
|
|
786
834
|
for (const dropped of stripExternalPaint(merged)) {
|
|
787
835
|
opts?.onNotice?.({
|
|
788
836
|
kind: "external-paint-dropped",
|
|
@@ -792,8 +840,17 @@ function compileToCdl(doc, opts) {
|
|
|
792
840
|
hint: "\u8272\u306F `#ff0000` \u306E\u3088\u3046\u306A\u8272\u756A\u53F7\u304B\u3001 `red` \u306E\u3088\u3046\u306A\u8272\u540D\u3067\u66F8\u304F"
|
|
793
841
|
});
|
|
794
842
|
}
|
|
843
|
+
restoreActorNames(merged, \u5206\u3051\u305F.\u5143\u306E\u540D\u524D, \u4F5C\u308A\u66FF\u3048\u305F\u5BFE\u8C61);
|
|
795
844
|
return merged;
|
|
796
845
|
}
|
|
846
|
+
function materializeStates(diagram2, doc) {
|
|
847
|
+
const \u8F09\u3063\u3066\u3044\u308B = new Set(diagram2.states.map((s) => s.id));
|
|
848
|
+
for (const st of doc.animate?.states ?? []) {
|
|
849
|
+
if (\u8F09\u3063\u3066\u3044\u308B.has(st.name)) continue;
|
|
850
|
+
diagram2.states.push({ id: st.name, initial: st.initial });
|
|
851
|
+
\u8F09\u3063\u3066\u3044\u308B.add(st.name);
|
|
852
|
+
}
|
|
853
|
+
}
|
|
797
854
|
function injectStaticPhase(diagram2) {
|
|
798
855
|
if (diagram2.phases.length > 0) return;
|
|
799
856
|
const activate = [...diagram2.nodes.map((n) => n.id), ...diagram2.edges.map((e) => e.id)];
|
|
@@ -811,6 +868,314 @@ function truncateForMessage(v) {
|
|
|
811
868
|
const s = v.trim();
|
|
812
869
|
return s.length <= 40 ? s : `${s.slice(0, 37)}...`;
|
|
813
870
|
}
|
|
871
|
+
function actorRefTable(doc) {
|
|
872
|
+
const \u8868 = /* @__PURE__ */ new Map();
|
|
873
|
+
const slug\u6570 = /* @__PURE__ */ new Map();
|
|
874
|
+
for (const a of doc.actors) {
|
|
875
|
+
const sl = slugify(a.name);
|
|
876
|
+
slug\u6570.set(sl, (slug\u6570.get(sl) ?? 0) + 1);
|
|
877
|
+
}
|
|
878
|
+
for (const a of doc.actors) {
|
|
879
|
+
\u8868.set(a.name, a.name);
|
|
880
|
+
const sl = slugify(a.name);
|
|
881
|
+
if ((slug\u6570.get(sl) ?? 0) === 1) \u8868.set(sl, a.name);
|
|
882
|
+
}
|
|
883
|
+
return \u8868;
|
|
884
|
+
}
|
|
885
|
+
function canonicalizeFlowActors(doc) {
|
|
886
|
+
const \u8868 = actorRefTable(doc);
|
|
887
|
+
let \u5909\u3048\u305F = false;
|
|
888
|
+
const flow2 = doc.flow.map((s) => {
|
|
889
|
+
const from = \u8868.get(s.from) ?? s.from;
|
|
890
|
+
const to = \u8868.get(s.to) ?? s.to;
|
|
891
|
+
if (from === s.from && to === s.to) return s;
|
|
892
|
+
\u5909\u3048\u305F = true;
|
|
893
|
+
return { ...s, from, to };
|
|
894
|
+
});
|
|
895
|
+
return \u5909\u3048\u305F ? { ...doc, flow: flow2 } : doc;
|
|
896
|
+
}
|
|
897
|
+
var \u56F3\u7A2E\u306E\u4F5C\u308A = {
|
|
898
|
+
// 矢印の端と登場人物の名前が、 そのまま箱や枠の id になる
|
|
899
|
+
sequence: "\u767B\u5834\u4EBA\u7269\u3054\u3068\u306B\u7BB1",
|
|
900
|
+
flow: "\u767B\u5834\u4EBA\u7269\u3054\u3068\u306B\u7BB1",
|
|
901
|
+
swimlane: "\u767B\u5834\u4EBA\u7269\u3054\u3068\u306B\u7BB1",
|
|
902
|
+
er: "\u767B\u5834\u4EBA\u7269\u3054\u3068\u306B\u7BB1",
|
|
903
|
+
state: "\u767B\u5834\u4EBA\u7269\u3054\u3068\u306B\u7BB1",
|
|
904
|
+
topology: "\u767B\u5834\u4EBA\u7269\u3054\u3068\u306B\u7BB1",
|
|
905
|
+
solidity: "\u767B\u5834\u4EBA\u7269\u3054\u3068\u306B\u7BB1",
|
|
906
|
+
class: "\u767B\u5834\u4EBA\u7269\u3054\u3068\u306B\u7BB1",
|
|
907
|
+
c4: "\u767B\u5834\u4EBA\u7269\u3054\u3068\u306B\u7BB1",
|
|
908
|
+
// 中身は payload が持ち、 図そのものは 1 箱。 矢印は描かず本数を数えて知らせる
|
|
909
|
+
gantt: "\u56F3\u5168\u4F53\u3092 1 \u7BB1",
|
|
910
|
+
pie: "\u56F3\u5168\u4F53\u3092 1 \u7BB1",
|
|
911
|
+
bar: "\u56F3\u5168\u4F53\u3092 1 \u7BB1",
|
|
912
|
+
line: "\u56F3\u5168\u4F53\u3092 1 \u7BB1",
|
|
913
|
+
funnel: "\u56F3\u5168\u4F53\u3092 1 \u7BB1",
|
|
914
|
+
tree: "\u56F3\u5168\u4F53\u3092 1 \u7BB1",
|
|
915
|
+
journey: "\u56F3\u5168\u4F53\u3092 1 \u7BB1",
|
|
916
|
+
quadrant: "\u56F3\u5168\u4F53\u3092 1 \u7BB1",
|
|
917
|
+
mind: "\u56F3\u5168\u4F53\u3092 1 \u7BB1"
|
|
918
|
+
};
|
|
919
|
+
function dropUnresolvedFlow(doc) {
|
|
920
|
+
if (\u56F3\u7A2E\u306E\u4F5C\u308A[doc.type] === "\u56F3\u5168\u4F53\u3092 1 \u7BB1") return doc;
|
|
921
|
+
const \u8868 = actorRefTable(doc);
|
|
922
|
+
const flow2 = doc.flow.filter((s) => \u8868.has(s.from) && \u8868.has(s.to));
|
|
923
|
+
return flow2.length === doc.flow.length ? doc : { ...doc, flow: flow2 };
|
|
924
|
+
}
|
|
925
|
+
function dropSelfLoopFlow(doc) {
|
|
926
|
+
if (\u56F3\u7A2E\u306E\u4F5C\u308A[doc.type] === "\u56F3\u5168\u4F53\u3092 1 \u7BB1") return doc;
|
|
927
|
+
const flow2 = doc.flow.filter((s) => s.from !== s.to);
|
|
928
|
+
return flow2.length === doc.flow.length ? doc : { ...doc, flow: flow2 };
|
|
929
|
+
}
|
|
930
|
+
function reportSelfLoopFlow(doc, onNotice) {
|
|
931
|
+
if (!onNotice) return;
|
|
932
|
+
if (\u56F3\u7A2E\u306E\u4F5C\u308A[doc.type] === "\u56F3\u5168\u4F53\u3092 1 \u7BB1") return;
|
|
933
|
+
const \u77E5\u3089\u305B\u305F = /* @__PURE__ */ new Set();
|
|
934
|
+
for (const s of doc.flow) {
|
|
935
|
+
if (s.from !== s.to || \u77E5\u3089\u305B\u305F.has(s.from)) continue;
|
|
936
|
+
\u77E5\u3089\u305B\u305F.add(s.from);
|
|
937
|
+
onNotice({
|
|
938
|
+
kind: "flow-self-loop",
|
|
939
|
+
actor: s.from,
|
|
940
|
+
line: s.pos.line,
|
|
941
|
+
message: `"${truncateForMessage(s.from)}" \u304B\u3089\u81EA\u5206\u3078\u623B\u308B\u77E2\u5370\u306F\u63CF\u3051\u307E\u305B\u3093 (\u7D44\u307F\u7ACB\u3066\u304B\u3089\u5916\u3057\u307E\u3057\u305F)`,
|
|
942
|
+
hint: "\u9014\u4E2D\u306E\u7BB1\u3092 1 \u3064\u8DB3\u3057\u3066 2 \u672C\u306B\u5206\u3051\u308B\u304B\u3001 \u6BB5 (animation) \u3067\u72B6\u614B\u304C\u5909\u308F\u308B\u69D8\u5B50\u3068\u3057\u3066\u898B\u305B\u308B"
|
|
943
|
+
});
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
function \u56F3\u306E\u5C0F\u898B\u51FA\u3057(doc) {
|
|
947
|
+
return doc.eyebrow === void 0 ? {} : { eyebrow: doc.eyebrow };
|
|
948
|
+
}
|
|
949
|
+
function reportDocEyebrowNotHonored(doc, onNotice) {
|
|
950
|
+
if (!onNotice) return;
|
|
951
|
+
if (doc.eyebrow === void 0) return;
|
|
952
|
+
if (\u56F3\u7A2E\u306E\u4F5C\u308A[doc.type] === "\u56F3\u5168\u4F53\u3092 1 \u7BB1") return;
|
|
953
|
+
onNotice({
|
|
954
|
+
kind: "eyebrow-not-honored",
|
|
955
|
+
actor: doc.title,
|
|
956
|
+
// 図の `pos` は常に 1 行目を指す。 書いた行に辿り着けるよう `eyebrowPos` を優先する
|
|
957
|
+
line: doc.eyebrowPos?.line ?? doc.pos?.line ?? 0,
|
|
958
|
+
message: `\u6700\u4E0A\u4F4D\u306B\u66F8\u3044\u305F eyebrow \u306F\u52B9\u304D\u307E\u305B\u3093 (type: ${doc.type} \u306F\u7BB1\u3054\u3068\u306B\u5206\u304B\u308C\u308B\u305F\u3081\u76F8\u624B\u304C\u6C7A\u307E\u308A\u307E\u305B\u3093)`,
|
|
959
|
+
hint: '\u7BB1\u3054\u3068\u306B\u66F8\u3044\u3066\u304F\u3060\u3055\u3044 (`- A: { eyebrow: "..." }`)'
|
|
960
|
+
});
|
|
961
|
+
}
|
|
962
|
+
function reportLaneMixed(doc, onNotice) {
|
|
963
|
+
const \u5BFE\u8C61 = doc.actors.filter((a) => a.partId === void 0);
|
|
964
|
+
const \u66F8\u3044\u305F = \u5BFE\u8C61.filter((a) => a.lane !== void 0);
|
|
965
|
+
if (\u66F8\u3044\u305F.length === 0 || \u66F8\u3044\u305F.length === \u5BFE\u8C61.length) return;
|
|
966
|
+
const \u66F8\u3044\u3066\u3044\u306A\u3044 = \u5BFE\u8C61.filter((a) => a.lane === void 0);
|
|
967
|
+
onNotice({
|
|
968
|
+
kind: "lane-not-honored",
|
|
969
|
+
actor: \u66F8\u3044\u3066\u3044\u306A\u3044[0]?.name ?? "",
|
|
970
|
+
line: \u66F8\u3044\u3066\u3044\u306A\u3044[0]?.pos?.line ?? 0,
|
|
971
|
+
message: `type: ${doc.type} \u3067\u306F\u7E26\u5217\u3092\u66F8\u304F\u306A\u3089\u5168\u3066\u306E\u7BB1\u306B\u66F8\u304D\u307E\u3059 (\u66F8\u3044\u3066\u3044\u306A\u3044\u7BB1: ${\u66F8\u3044\u3066\u3044\u306A\u3044.map((a) => truncateForMessage(a.name)).join(" / ")})`,
|
|
972
|
+
hint: "\u66F8\u304B\u306A\u304B\u3063\u305F\u7BB1\u3092\u3069\u306E\u7E26\u5217\u306B\u7F6E\u304F\u304B\u3092\u6C7A\u3081\u3089\u308C\u306A\u3044\u305F\u3081\u3001\u5168\u90E8\u66F8\u304F\u304B 1 \u3064\u3082\u66F8\u304B\u306A\u3044\u304B\u306B\u3057\u3066\u304F\u3060\u3055\u3044"
|
|
973
|
+
});
|
|
974
|
+
}
|
|
975
|
+
function reportFlowEndpointNotHonored(doc, \u5143\u306E\u540D\u524D, onNotice) {
|
|
976
|
+
if (!onNotice) return;
|
|
977
|
+
if (!\u9396\u3067\u3064\u306A\u3050\u5F62\u304B(doc)) return;
|
|
978
|
+
const \u66F8\u3044\u305F\u540D\u524D = (name) => \u5143\u306E\u540D\u524D.get(name) ?? name;
|
|
979
|
+
const \u9396\u306E\u7D44 = /* @__PURE__ */ new Set();
|
|
980
|
+
doc.actors.forEach((a, i) => {
|
|
981
|
+
const \u6B21 = doc.actors[i + 1];
|
|
982
|
+
if (\u6B21 === void 0) return;
|
|
983
|
+
\u9396\u306E\u7D44.add(`${a.name}\0${\u6B21.name}`);
|
|
984
|
+
});
|
|
985
|
+
for (const s of doc.flow) {
|
|
986
|
+
if (\u9396\u306E\u7D44.has(`${s.from}\0${s.to}`)) continue;
|
|
987
|
+
onNotice({
|
|
988
|
+
kind: "flow-endpoint-not-honored",
|
|
989
|
+
actor: \u66F8\u3044\u305F\u540D\u524D(s.from),
|
|
990
|
+
line: s.pos.line,
|
|
991
|
+
message: `"${truncateForMessage(\u66F8\u3044\u305F\u540D\u524D(s.from))} -> ${truncateForMessage(\u66F8\u3044\u305F\u540D\u524D(s.to))}" \u306E\u7AEF\u306F\u4F7F\u308F\u308C\u307E\u305B\u3093 (type: flow \u306F\u767B\u5834\u4EBA\u7269\u3092\u66F8\u3044\u305F\u9806\u306B\u7E4B\u304E\u307E\u3059)`,
|
|
992
|
+
hint: "\u66F8\u3044\u305F\u7AEF\u3069\u304A\u308A\u306B\u7E4B\u3050\u306B\u306F\u3001\u7BB1\u306B lane: \u3092\u66F8\u3044\u3066\u304F\u3060\u3055\u3044 (\u7E26\u5217\u3092\u66F8\u3044\u305F\u5F62\u306F\u66F8\u3044\u305F\u7AEF\u304C\u305D\u306E\u307E\u307E\u77E2\u5370\u306B\u306A\u308A\u307E\u3059)"
|
|
993
|
+
});
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
function reportLaneNotHonored(doc, onNotice) {
|
|
997
|
+
if (!onNotice) return;
|
|
998
|
+
if (doc.type === "mind") return;
|
|
999
|
+
const \u52B9\u304F\u56F3\u7A2E = \u7E26\u5217\u3092\u9078\u3079\u308B\u56F3\u7A2E.has(doc.type);
|
|
1000
|
+
if (\u52B9\u304F\u56F3\u7A2E && \u66F8\u3044\u305F\u7E26\u5217\u306B\u7F6E\u304F(doc.type, doc)) return;
|
|
1001
|
+
if (\u52B9\u304F\u56F3\u7A2E) {
|
|
1002
|
+
reportLaneMixed(doc, onNotice);
|
|
1003
|
+
return;
|
|
1004
|
+
}
|
|
1005
|
+
for (const a of doc.actors) {
|
|
1006
|
+
if (a.partId !== void 0) continue;
|
|
1007
|
+
if (a.lane === void 0) continue;
|
|
1008
|
+
onNotice({
|
|
1009
|
+
kind: "lane-not-honored",
|
|
1010
|
+
actor: a.name,
|
|
1011
|
+
line: a.pos?.line ?? 0,
|
|
1012
|
+
message: `"${truncateForMessage(a.name)}" \u306B\u66F8\u3044\u305F lane \u306F\u52B9\u304D\u307E\u305B\u3093 (\u7E26\u5217\u306F type: ${doc.type} \u304C\u6C7A\u3081\u307E\u3059)`,
|
|
1013
|
+
hint: "\u7E26\u5217\u306F\u56F3\u7A2E\u304C\u6C7A\u3081\u308B\u305F\u3081\u7BB1\u304B\u3089\u306F\u9078\u3079\u307E\u305B\u3093\u3002 lane \u3092\u6D88\u3057\u3066\u304F\u3060\u3055\u3044 (\u898B\u672C\u3067\u306F\u5F35\u66FF\u3048\u5148\u3068\u3057\u3066\u4F7F\u3048\u307E\u3059)"
|
|
1014
|
+
});
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
function \u540D\u524D\u306E\u5C3E(name) {
|
|
1018
|
+
let h = 2166136261;
|
|
1019
|
+
for (const c of name) {
|
|
1020
|
+
h ^= c.codePointAt(0) ?? 0;
|
|
1021
|
+
h = Math.imul(h, 16777619) >>> 0;
|
|
1022
|
+
}
|
|
1023
|
+
return h.toString(16).padStart(8, "0").slice(0, 6);
|
|
1024
|
+
}
|
|
1025
|
+
function cdl\u5074\u306Eslug(s) {
|
|
1026
|
+
return s.toLowerCase().replace(/[^a-z0-9-ゟ゠-ヿ一-龯]+/g, "-").replace(/^-|-$/g, "");
|
|
1027
|
+
}
|
|
1028
|
+
var \u7A7A\u306E\u5F62\u306E\u9003\u3052\u5148 = {
|
|
1029
|
+
sequence: ["actor-"],
|
|
1030
|
+
solidity: ["actor-"],
|
|
1031
|
+
swimlane: ["lane-"],
|
|
1032
|
+
flow: [],
|
|
1033
|
+
er: [],
|
|
1034
|
+
state: [],
|
|
1035
|
+
topology: [],
|
|
1036
|
+
class: [],
|
|
1037
|
+
c4: [],
|
|
1038
|
+
// 図全体を 1 箱で描く群 (作り替えないのでここは使わない)
|
|
1039
|
+
gantt: [],
|
|
1040
|
+
pie: [],
|
|
1041
|
+
bar: [],
|
|
1042
|
+
line: [],
|
|
1043
|
+
funnel: [],
|
|
1044
|
+
tree: [],
|
|
1045
|
+
journey: [],
|
|
1046
|
+
quadrant: [],
|
|
1047
|
+
mind: []
|
|
1048
|
+
};
|
|
1049
|
+
function id\u306B\u306A\u308B\u5F62(name, \u4F4D\u7F6E, \u9003\u3052\u5148\u306E\u982D = []) {
|
|
1050
|
+
const cdl = cdl\u5074\u306Eslug(name);
|
|
1051
|
+
const out = [slugify(name), cdl];
|
|
1052
|
+
if (cdl === "" && \u4F4D\u7F6E !== void 0) {
|
|
1053
|
+
for (const \u982D of \u9003\u3052\u5148\u306E\u982D) out.push(`${\u982D}${\u4F4D\u7F6E}`);
|
|
1054
|
+
}
|
|
1055
|
+
return out;
|
|
1056
|
+
}
|
|
1057
|
+
function disambiguateActorIds(doc, onNotice) {
|
|
1058
|
+
const \u5143\u306E\u540D\u524D = /* @__PURE__ */ new Map();
|
|
1059
|
+
if (\u56F3\u7A2E\u306E\u4F5C\u308A[doc.type] !== "\u767B\u5834\u4EBA\u7269\u3054\u3068\u306B\u7BB1") return { doc, \u5143\u306E\u540D\u524D };
|
|
1060
|
+
const \u898B\u305F = /* @__PURE__ */ new Set();
|
|
1061
|
+
const \u6B8B\u3059 = [];
|
|
1062
|
+
for (const a of doc.actors) {
|
|
1063
|
+
if (\u898B\u305F.has(a.name)) {
|
|
1064
|
+
onNotice?.({
|
|
1065
|
+
kind: "chart-value-unreadable",
|
|
1066
|
+
actor: a.name,
|
|
1067
|
+
line: a.pos?.line ?? 0,
|
|
1068
|
+
message: `"${truncateForMessage(a.name)}" \u3092 2 \u5EA6\u66F8\u3044\u3066\u3044\u307E\u3059 (\u5148\u306B\u66F8\u3044\u305F\u65B9\u3060\u3051\u63CF\u304D\u307E\u3059)`,
|
|
1069
|
+
hint: "\u9055\u3046\u540D\u524D\u306B\u3059\u308B\u304B\u3001 1 \u3064\u306B\u307E\u3068\u3081\u308B"
|
|
1070
|
+
});
|
|
1071
|
+
continue;
|
|
1072
|
+
}
|
|
1073
|
+
\u898B\u305F.add(a.name);
|
|
1074
|
+
\u6B8B\u3059.push(a);
|
|
1075
|
+
}
|
|
1076
|
+
const \u5F62\u3054\u3068\u306E\u540D\u524D = /* @__PURE__ */ new Map();
|
|
1077
|
+
const \u4F4D\u7F6E = /* @__PURE__ */ new Map();
|
|
1078
|
+
\u6B8B\u3059.forEach((a, i) => \u4F4D\u7F6E.set(a.name, i));
|
|
1079
|
+
const \u52D5\u304D\u3092\u66F8\u3044\u305F = (doc.animate?.phases.length ?? 0) > 0;
|
|
1080
|
+
const \u9003\u3052\u5148\u306E\u982D = \u52D5\u304D\u3092\u66F8\u3044\u305F ? [] : \u7A7A\u306E\u5F62\u306E\u9003\u3052\u5148[doc.type];
|
|
1081
|
+
for (const a of \u6B8B\u3059) {
|
|
1082
|
+
for (const \u5F62 of id\u306B\u306A\u308B\u5F62(a.name, \u4F4D\u7F6E.get(a.name), \u9003\u3052\u5148\u306E\u982D)) {
|
|
1083
|
+
const \u7FA4 = \u5F62\u3054\u3068\u306E\u540D\u524D.get(\u5F62) ?? /* @__PURE__ */ new Set();
|
|
1084
|
+
\u7FA4.add(a.name);
|
|
1085
|
+
\u5F62\u3054\u3068\u306E\u540D\u524D.set(\u5F62, \u7FA4);
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
const \u91CD\u306A\u308B = (name) => id\u306B\u306A\u308B\u5F62(name, \u4F4D\u7F6E.get(name), \u9003\u3052\u5148\u306E\u982D).some(
|
|
1089
|
+
(\u5F62) => (\u5F62\u3054\u3068\u306E\u540D\u524D.get(\u5F62)?.size ?? 0) > 1
|
|
1090
|
+
);
|
|
1091
|
+
const \u4F5C\u308A\u66FF\u3048\u308B = \u6B8B\u3059.filter((a) => a.partId === void 0 && \u91CD\u306A\u308B(a.name));
|
|
1092
|
+
const \u4F7F\u3046\u5F62 = /* @__PURE__ */ new Set();
|
|
1093
|
+
for (const a of \u6B8B\u3059) {
|
|
1094
|
+
if (\u4F5C\u308A\u66FF\u3048\u308B.some((b) => b.name === a.name)) continue;
|
|
1095
|
+
for (const \u5F62 of id\u306B\u306A\u308B\u5F62(a.name)) \u4F7F\u3046\u5F62.add(\u5F62);
|
|
1096
|
+
}
|
|
1097
|
+
const \u65B0\u3057\u3044\u540D\u524D = /* @__PURE__ */ new Map();
|
|
1098
|
+
for (const a of [...\u4F5C\u308A\u66FF\u3048\u308B].sort((x, y) => x.name < y.name ? -1 : x.name > y.name ? 1 : 0)) {
|
|
1099
|
+
const \u5C3E = \u540D\u524D\u306E\u5C3E(a.name);
|
|
1100
|
+
const \u4F59\u5730 = ID_MAX - (\u5C3E.length + 1);
|
|
1101
|
+
const \u57FA\u5E95 = a.name.slice(0, \u4F59\u5730);
|
|
1102
|
+
let \u5019\u88DC = `${\u57FA\u5E95} ${\u5C3E}`;
|
|
1103
|
+
let n = 0;
|
|
1104
|
+
while (id\u306B\u306A\u308B\u5F62(\u5019\u88DC).some((\u5F62) => \u4F7F\u3046\u5F62.has(\u5F62))) {
|
|
1105
|
+
n += 1;
|
|
1106
|
+
\u5019\u88DC = `${\u57FA\u5E95.slice(0, \u4F59\u5730 - String(n).length)} ${\u5C3E}${n}`;
|
|
1107
|
+
}
|
|
1108
|
+
for (const \u5F62 of id\u306B\u306A\u308B\u5F62(\u5019\u88DC)) \u4F7F\u3046\u5F62.add(\u5F62);
|
|
1109
|
+
\u65B0\u3057\u3044\u540D\u524D.set(a.name, \u5019\u88DC);
|
|
1110
|
+
\u5143\u306E\u540D\u524D.set(\u5019\u88DC, a.name);
|
|
1111
|
+
}
|
|
1112
|
+
if (\u65B0\u3057\u3044\u540D\u524D.size === 0 && \u6B8B\u3059.length === doc.actors.length) return { doc, \u5143\u306E\u540D\u524D };
|
|
1113
|
+
const \u76F4\u3059 = (\u540D) => \u65B0\u3057\u3044\u540D\u524D.get(\u540D) ?? \u540D;
|
|
1114
|
+
const \u6B21 = {
|
|
1115
|
+
...doc,
|
|
1116
|
+
actors: \u6B8B\u3059.map((a) => \u65B0\u3057\u3044\u540D\u524D.has(a.name) ? { ...a, name: \u76F4\u3059(a.name) } : a),
|
|
1117
|
+
flow: doc.flow.map((s) => {
|
|
1118
|
+
const from = \u76F4\u3059(s.from);
|
|
1119
|
+
const to = \u76F4\u3059(s.to);
|
|
1120
|
+
return from === s.from && to === s.to ? s : { ...s, from, to };
|
|
1121
|
+
})
|
|
1122
|
+
};
|
|
1123
|
+
if (\u6B21.animate) {
|
|
1124
|
+
\u6B21.animate = {
|
|
1125
|
+
...\u6B21.animate,
|
|
1126
|
+
phases: \u6B21.animate.phases.map(
|
|
1127
|
+
(ph) => ph.highlight ? { ...ph, highlight: ph.highlight.map((h) => \u76F4\u3059(h)) } : ph
|
|
1128
|
+
)
|
|
1129
|
+
};
|
|
1130
|
+
}
|
|
1131
|
+
\u6B21.actors = \u6B21.actors.map(
|
|
1132
|
+
(a) => a.posRel ? { ...a, posRel: { ...a.posRel, anchor: \u76F4\u3059(a.posRel.anchor) } } : a
|
|
1133
|
+
);
|
|
1134
|
+
return { doc: \u6B21, \u5143\u306E\u540D\u524D };
|
|
1135
|
+
}
|
|
1136
|
+
function collectRenamedTargets(diagram2, \u5143\u306E\u540D\u524D) {
|
|
1137
|
+
const \u7BB1 = /* @__PURE__ */ new Set();
|
|
1138
|
+
const \u67A0 = /* @__PURE__ */ new Set();
|
|
1139
|
+
if (\u5143\u306E\u540D\u524D.size === 0) return { \u7BB1, \u67A0 };
|
|
1140
|
+
for (const n of diagram2.nodes) if (\u5143\u306E\u540D\u524D.has(n.title)) \u7BB1.add(n.id);
|
|
1141
|
+
for (const l of diagram2.lanes) if (l.label !== void 0 && \u5143\u306E\u540D\u524D.has(l.label)) \u67A0.add(l.id);
|
|
1142
|
+
return { \u7BB1, \u67A0 };
|
|
1143
|
+
}
|
|
1144
|
+
function restoreActorNames(diagram2, \u5143\u306E\u540D\u524D, \u5BFE\u8C61) {
|
|
1145
|
+
if (\u5143\u306E\u540D\u524D.size === 0) return;
|
|
1146
|
+
for (const n of diagram2.nodes) {
|
|
1147
|
+
if (!\u5BFE\u8C61.\u7BB1.has(n.id)) continue;
|
|
1148
|
+
const \u5143 = \u5143\u306E\u540D\u524D.get(n.title);
|
|
1149
|
+
if (\u5143 !== void 0) n.title = \u5143;
|
|
1150
|
+
}
|
|
1151
|
+
for (const l of diagram2.lanes) {
|
|
1152
|
+
if (!\u5BFE\u8C61.\u67A0.has(l.id) || l.label === void 0) continue;
|
|
1153
|
+
const \u5143 = \u5143\u306E\u540D\u524D.get(l.label);
|
|
1154
|
+
if (\u5143 !== void 0) l.label = \u5143;
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
function reportMissingFlowActors(doc, onNotice) {
|
|
1158
|
+
if (!onNotice) return;
|
|
1159
|
+
const \u8868 = actorRefTable(doc);
|
|
1160
|
+
const \u898B\u305B\u308B\u6570 = 8;
|
|
1161
|
+
const \u540D\u524D\u4E00\u89A7 = doc.actors.slice(0, \u898B\u305B\u308B\u6570).map((a) => truncateForMessage(a.name)).join(" / ");
|
|
1162
|
+
const \u6B8B\u308A = doc.actors.length - \u898B\u305B\u308B\u6570;
|
|
1163
|
+
const hint = doc.actors.length > 0 ? `actors \u306B\u66F8\u3044\u305F\u540D\u524D\u3067\u6307\u3059 (${\u540D\u524D\u4E00\u89A7}${\u6B8B\u308A > 0 ? ` \u307B\u304B ${\u6B8B\u308A} \u4EF6` : ""})` : "actors \u306B\u767B\u5834\u4EBA\u7269\u3092\u66F8\u304F";
|
|
1164
|
+
const \u77E5\u3089\u305B\u305F = /* @__PURE__ */ new Set();
|
|
1165
|
+
for (const s of doc.flow) {
|
|
1166
|
+
for (const ref of [s.from, s.to]) {
|
|
1167
|
+
if (\u8868.has(ref) || \u77E5\u3089\u305B\u305F.has(ref)) continue;
|
|
1168
|
+
\u77E5\u3089\u305B\u305F.add(ref);
|
|
1169
|
+
onNotice({
|
|
1170
|
+
kind: "flow-actor-missing",
|
|
1171
|
+
actor: ref,
|
|
1172
|
+
line: s.pos.line,
|
|
1173
|
+
message: `\u77E2\u5370\u304C "${truncateForMessage(ref)}" \u3092\u6307\u3057\u3066\u3044\u307E\u3059\u304C\u3001 actors \u306B\u66F8\u304B\u308C\u3066\u3044\u307E\u305B\u3093`,
|
|
1174
|
+
hint
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
814
1179
|
function reportMissingFocusTargets(doc, onNotice) {
|
|
815
1180
|
if (!onNotice || !doc.animate) return;
|
|
816
1181
|
const names = new Set(doc.actors.map((a) => a.name));
|
|
@@ -827,10 +1192,12 @@ function reportMissingFocusTargets(doc, onNotice) {
|
|
|
827
1192
|
tos.add(st.to);
|
|
828
1193
|
steps.set(st.from, tos);
|
|
829
1194
|
}
|
|
1195
|
+
const \u540D\u524D\u3078 = actorRefTable(doc);
|
|
1196
|
+
const \u63C3\u3048\u308B = (ref) => \u540D\u524D\u3078.get(ref) ?? ref;
|
|
830
1197
|
for (const phase of doc.animate.phases) {
|
|
831
1198
|
for (const raw of phase.highlight ?? []) {
|
|
832
1199
|
const entry = parseFocusEntry(raw, names);
|
|
833
|
-
const found = entry.kind === "edge" ? steps.get(entry.from)?.has(entry.to) ?? false : accepted.has(entry.name);
|
|
1200
|
+
const found = entry.kind === "edge" ? steps.get(\u63C3\u3048\u308B(entry.from))?.has(\u63C3\u3048\u308B(entry.to)) ?? false : accepted.has(entry.name);
|
|
834
1201
|
if (found) continue;
|
|
835
1202
|
onNotice({
|
|
836
1203
|
kind: "focus-target-missing",
|
|
@@ -1418,9 +1785,10 @@ function cleanupPlaceholderActor(target, doc, a) {
|
|
|
1418
1785
|
phase.activate = phase.activate.filter((id) => !relatedToActor(id) && !removedEdgeIds.has(id));
|
|
1419
1786
|
}
|
|
1420
1787
|
}
|
|
1421
|
-
function mergePartsFromActors(target, doc, partsCatalog, onNotice) {
|
|
1788
|
+
function mergePartsFromActors(target, doc, partsCatalog, onNotice, derivedSourceLines) {
|
|
1422
1789
|
const partsActors = doc.actors.filter((a) => a.partId !== void 0);
|
|
1423
1790
|
if (partsActors.length === 0) return target;
|
|
1791
|
+
const \u5024\u306E\u524D\u7F6E\u304D = \u5024\u306E\u524D\u7F6E\u304D\u3092\u4F5C\u308B(partsActors.map((a) => a.name));
|
|
1424
1792
|
if (!partsCatalog) {
|
|
1425
1793
|
if (typeof console !== "undefined" && console.warn) {
|
|
1426
1794
|
const names = partsActors.map((a) => `${a.name} (kind: ${a.partId ?? "?"})`).join(", ");
|
|
@@ -1476,7 +1844,21 @@ function mergePartsFromActors(target, doc, partsCatalog, onNotice) {
|
|
|
1476
1844
|
}
|
|
1477
1845
|
}
|
|
1478
1846
|
const t = partTargetSize(part, actor.posW, actor.posH, actor.scale);
|
|
1479
|
-
mergePartIntoDiagram(
|
|
1847
|
+
mergePartIntoDiagram(
|
|
1848
|
+
target,
|
|
1849
|
+
part,
|
|
1850
|
+
actor.name,
|
|
1851
|
+
merged,
|
|
1852
|
+
actor.lane,
|
|
1853
|
+
placeX,
|
|
1854
|
+
placeY,
|
|
1855
|
+
t.w,
|
|
1856
|
+
t.h,
|
|
1857
|
+
onNotice,
|
|
1858
|
+
actor.pos?.line ?? 0,
|
|
1859
|
+
derivedSourceLines,
|
|
1860
|
+
\u5024\u306E\u524D\u7F6E\u304D.get(actor.name)
|
|
1861
|
+
);
|
|
1480
1862
|
}
|
|
1481
1863
|
return target;
|
|
1482
1864
|
}
|
|
@@ -1495,15 +1877,47 @@ function applyColorHex(part, colorHex, stateOverride) {
|
|
|
1495
1877
|
}
|
|
1496
1878
|
return out;
|
|
1497
1879
|
}
|
|
1498
|
-
function
|
|
1880
|
+
function \u5024\u306E\u524D\u7F6E\u304D\u3092\u4F5C\u308B(\u540D\u524D\u305F\u3061) {
|
|
1881
|
+
const \u51FA\u529B = /* @__PURE__ */ new Map();
|
|
1882
|
+
const \u4F7F\u7528\u4E2D = /* @__PURE__ */ new Set();
|
|
1883
|
+
const \u6B21\u306E\u756A\u53F7 = /* @__PURE__ */ new Map();
|
|
1884
|
+
for (const \u540D\u524D of \u540D\u524D\u305F\u3061) {
|
|
1885
|
+
if (\u51FA\u529B.has(\u540D\u524D)) continue;
|
|
1886
|
+
let \u7D20 = \u540D\u524D.normalize("NFKC").replace(/[^A-Za-z0-9_]+/g, "_").replace(/^_+|_+$/g, "");
|
|
1887
|
+
if (\u7D20 === "" || /^[0-9]/.test(\u7D20)) \u7D20 = `p${\u7D20}`;
|
|
1888
|
+
let \u5019\u88DC = \u7D20;
|
|
1889
|
+
let \u756A\u53F7 = \u6B21\u306E\u756A\u53F7.get(\u7D20) ?? 2;
|
|
1890
|
+
while (\u4F7F\u7528\u4E2D.has(\u5019\u88DC)) {
|
|
1891
|
+
\u5019\u88DC = `${\u7D20}_${\u756A\u53F7}`;
|
|
1892
|
+
\u756A\u53F7 += 1;
|
|
1893
|
+
}
|
|
1894
|
+
\u6B21\u306E\u756A\u53F7.set(\u7D20, \u756A\u53F7);
|
|
1895
|
+
\u4F7F\u7528\u4E2D.add(\u5019\u88DC);
|
|
1896
|
+
\u51FA\u529B.set(\u540D\u524D, \u5019\u88DC);
|
|
1897
|
+
}
|
|
1898
|
+
return \u51FA\u529B;
|
|
1899
|
+
}
|
|
1900
|
+
function mergePartIntoDiagram(target, part, alias, stateOverride, laneMapping, offsetX, offsetY, targetW, targetH, onNotice, noticeLine = 0, derivedSourceLines, valueAlias) {
|
|
1499
1901
|
const prefix = (id) => `${alias}__${id}`;
|
|
1500
|
-
const
|
|
1902
|
+
const \u5024\u524D\u7F6E\u304D = valueAlias ?? alias;
|
|
1903
|
+
const valuePrefix = (id) => `${\u5024\u524D\u7F6E\u304D}__${id}`;
|
|
1904
|
+
const ownIdSet = /* @__PURE__ */ new Set([
|
|
1905
|
+
...part.states.map((s) => s.id),
|
|
1906
|
+
...(part.derived ?? []).map((d) => d.id)
|
|
1907
|
+
]);
|
|
1501
1908
|
const rewriteTemplate = (s) => {
|
|
1502
1909
|
if (!s) return s;
|
|
1503
|
-
return s.replace(/\{(
|
|
1504
|
-
return
|
|
1910
|
+
return s.replace(/\{(\w+)\}/g, (m, name) => {
|
|
1911
|
+
return ownIdSet.has(name) ? `{${valuePrefix(name)}}` : m;
|
|
1505
1912
|
});
|
|
1506
1913
|
};
|
|
1914
|
+
const rewriteDerivedExpression = (expression) => {
|
|
1915
|
+
try {
|
|
1916
|
+
return writeFormula(renameFormulaIdentifiers(cdl.parseFormula(expression), valuePrefix));
|
|
1917
|
+
} catch {
|
|
1918
|
+
return expression;
|
|
1919
|
+
}
|
|
1920
|
+
};
|
|
1507
1921
|
const targetLaneId = laneMapping;
|
|
1508
1922
|
const laneIdMap = /* @__PURE__ */ new Map();
|
|
1509
1923
|
const PARTS_LANE_GAP = 300;
|
|
@@ -1621,7 +2035,16 @@ function mergePartIntoDiagram(target, part, alias, stateOverride, laneMapping, o
|
|
|
1621
2035
|
hint: "\u8272\u306F `#ff0000` \u306E\u3088\u3046\u306A\u8272\u756A\u53F7\u304B\u3001 `red` \u306E\u3088\u3046\u306A\u8272\u540D\u3067\u66F8\u304F"
|
|
1622
2036
|
});
|
|
1623
2037
|
}
|
|
1624
|
-
target.states.push({ id:
|
|
2038
|
+
target.states.push({ id: valuePrefix(stateOrig.id), initial });
|
|
2039
|
+
}
|
|
2040
|
+
for (const derivedOrig of part.derived ?? []) {
|
|
2041
|
+
if (!target.derived) target.derived = [];
|
|
2042
|
+
const id = valuePrefix(derivedOrig.id);
|
|
2043
|
+
target.derived.push({
|
|
2044
|
+
id,
|
|
2045
|
+
expression: rewriteDerivedExpression(derivedOrig.expression)
|
|
2046
|
+
});
|
|
2047
|
+
recordDerivedSourceLine(derivedSourceLines, id, noticeLine);
|
|
1625
2048
|
}
|
|
1626
2049
|
for (const edgeOrig of part.edges) {
|
|
1627
2050
|
target.edges.push({
|
|
@@ -1651,8 +2074,8 @@ function mergePartIntoDiagram(target, part, alias, stateOverride, laneMapping, o
|
|
|
1651
2074
|
...phaseOrig,
|
|
1652
2075
|
id: prefix(phaseOrig.id),
|
|
1653
2076
|
activate: phaseOrig.activate.map(prefix),
|
|
1654
|
-
tweens: phaseOrig.tweens.map((t) => ({ ...t, stateId:
|
|
1655
|
-
sets: phaseOrig.sets.map((s) => ({ ...s, stateId:
|
|
2077
|
+
tweens: phaseOrig.tweens.map((t) => ({ ...t, stateId: valuePrefix(t.stateId) })),
|
|
2078
|
+
sets: phaseOrig.sets.map((s) => ({ ...s, stateId: valuePrefix(s.stateId) }))
|
|
1656
2079
|
});
|
|
1657
2080
|
}
|
|
1658
2081
|
} else {
|
|
@@ -1664,8 +2087,8 @@ function mergePartIntoDiagram(target, part, alias, stateOverride, laneMapping, o
|
|
|
1664
2087
|
const partPhase = part.phases[i];
|
|
1665
2088
|
targetPhase.duration = Math.max(targetPhase.duration, partPhase.duration);
|
|
1666
2089
|
targetPhase.activate = [...targetPhase.activate, ...partPhase.activate.map(prefix)];
|
|
1667
|
-
targetPhase.tweens = [...targetPhase.tweens, ...partPhase.tweens.map((t) => ({ ...t, stateId:
|
|
1668
|
-
targetPhase.sets = [...targetPhase.sets, ...partPhase.sets.map((s) => ({ ...s, stateId:
|
|
2090
|
+
targetPhase.tweens = [...targetPhase.tweens, ...partPhase.tweens.map((t) => ({ ...t, stateId: valuePrefix(t.stateId) }))];
|
|
2091
|
+
targetPhase.sets = [...targetPhase.sets, ...partPhase.sets.map((s) => ({ ...s, stateId: valuePrefix(s.stateId) }))];
|
|
1669
2092
|
}
|
|
1670
2093
|
for (let i = commonLen; i < partsLen; i++) {
|
|
1671
2094
|
const phaseOrig = part.phases[i];
|
|
@@ -1673,8 +2096,8 @@ function mergePartIntoDiagram(target, part, alias, stateOverride, laneMapping, o
|
|
|
1673
2096
|
...phaseOrig,
|
|
1674
2097
|
id: prefix(phaseOrig.id),
|
|
1675
2098
|
activate: phaseOrig.activate.map(prefix),
|
|
1676
|
-
tweens: phaseOrig.tweens.map((t) => ({ ...t, stateId:
|
|
1677
|
-
sets: phaseOrig.sets.map((s) => ({ ...s, stateId:
|
|
2099
|
+
tweens: phaseOrig.tweens.map((t) => ({ ...t, stateId: valuePrefix(t.stateId) })),
|
|
2100
|
+
sets: phaseOrig.sets.map((s) => ({ ...s, stateId: valuePrefix(s.stateId) }))
|
|
1678
2101
|
});
|
|
1679
2102
|
}
|
|
1680
2103
|
}
|
|
@@ -1694,6 +2117,15 @@ function deepRewriteStrings(value, rewrite, seen = /* @__PURE__ */ new WeakSet()
|
|
|
1694
2117
|
return out;
|
|
1695
2118
|
}
|
|
1696
2119
|
function applyEdgeInlineOptions(diagram2, doc, sourceLines) {
|
|
2120
|
+
if (\u9396\u3067\u3064\u306A\u3050\u5F62\u304B(doc)) {
|
|
2121
|
+
diagram2.edges.forEach((e, idx) => {
|
|
2122
|
+
const s = \u9396\u306E\u3069\u306E\u884C\u304B\u3089\u6765\u305F\u304B(doc, idx);
|
|
2123
|
+
if (s === void 0) return;
|
|
2124
|
+
sourceLines?.set(e.id, s.pos.line);
|
|
2125
|
+
\u77E2\u5370\u3078\u66F8\u304D\u5199\u3059(e, s, doc);
|
|
2126
|
+
});
|
|
2127
|
+
return;
|
|
2128
|
+
}
|
|
1697
2129
|
const used = /* @__PURE__ */ new Set();
|
|
1698
2130
|
const isSeqLike = doc.type === "sequence" || doc.type === "solidity";
|
|
1699
2131
|
doc.flow.forEach((s, stepIdx) => {
|
|
@@ -1709,20 +2141,35 @@ function applyEdgeInlineOptions(diagram2, doc, sourceLines) {
|
|
|
1709
2141
|
if (!target) return;
|
|
1710
2142
|
used.add(target.id);
|
|
1711
2143
|
sourceLines?.set(target.id, s.pos.line);
|
|
1712
|
-
|
|
1713
|
-
target.guard = s.guard;
|
|
1714
|
-
if (doc.type === "state" && target.sub === void 0) target.sub = s.guard;
|
|
1715
|
-
}
|
|
1716
|
-
if (s.cardinality !== void 0) {
|
|
1717
|
-
target.cardinality = s.cardinality;
|
|
1718
|
-
if (doc.type === "er" && !target.label.includes(s.cardinality)) {
|
|
1719
|
-
target.label = target.label ? `${target.label} (${s.cardinality})` : `(${s.cardinality})`;
|
|
1720
|
-
}
|
|
1721
|
-
}
|
|
1722
|
-
if (s.labelOffsetX !== void 0) target.labelOffsetX = s.labelOffsetX;
|
|
1723
|
-
if (s.labelOffsetY !== void 0) target.labelOffsetY = s.labelOffsetY;
|
|
2144
|
+
\u77E2\u5370\u3078\u66F8\u304D\u5199\u3059(target, s, doc);
|
|
1724
2145
|
});
|
|
1725
2146
|
}
|
|
2147
|
+
function \u77E2\u5370\u3078\u66F8\u304D\u5199\u3059(target, s, doc) {
|
|
2148
|
+
if (s.sub !== void 0) target.sub = s.sub;
|
|
2149
|
+
if (s.guard !== void 0) {
|
|
2150
|
+
target.guard = s.guard;
|
|
2151
|
+
if (doc.type === "state" && target.sub === void 0) target.sub = s.guard;
|
|
2152
|
+
}
|
|
2153
|
+
if (s.cardinality !== void 0) {
|
|
2154
|
+
target.cardinality = s.cardinality;
|
|
2155
|
+
if (doc.type === "er" && !target.label.includes(s.cardinality)) {
|
|
2156
|
+
target.label = target.label ? `${target.label} (${s.cardinality})` : `(${s.cardinality})`;
|
|
2157
|
+
}
|
|
2158
|
+
}
|
|
2159
|
+
if (s.labelOffsetX !== void 0) target.labelOffsetX = s.labelOffsetX;
|
|
2160
|
+
if (s.labelOffsetY !== void 0) target.labelOffsetY = s.labelOffsetY;
|
|
2161
|
+
if (s.overlay !== void 0) target.overlay = s.overlay;
|
|
2162
|
+
}
|
|
2163
|
+
function \u9396\u3067\u3064\u306A\u3050\u5F62\u304B(doc) {
|
|
2164
|
+
if (doc.type !== "flow") return false;
|
|
2165
|
+
if (doc.animate && doc.animate.phases.length > 0) return false;
|
|
2166
|
+
return !\u66F8\u3044\u305F\u7E26\u5217\u306B\u7F6E\u304F("flow", doc);
|
|
2167
|
+
}
|
|
2168
|
+
function \u9396\u306E\u3069\u306E\u884C\u304B\u3089\u6765\u305F\u304B(doc, edgeIndex) {
|
|
2169
|
+
const to = doc.actors[edgeIndex + 1];
|
|
2170
|
+
if (to === void 0) return void 0;
|
|
2171
|
+
return doc.flow.find((s) => s.to === to.name);
|
|
2172
|
+
}
|
|
1726
2173
|
var DRAWABLE_KINDS = new Set(cdl.NODE_KINDS);
|
|
1727
2174
|
var KIND_ALIAS = {
|
|
1728
2175
|
eoa: "shape-wallet",
|
|
@@ -1733,13 +2180,312 @@ var KIND_ALIAS = {
|
|
|
1733
2180
|
library: "shape-code-block",
|
|
1734
2181
|
interface: "shape-code-block"
|
|
1735
2182
|
};
|
|
2183
|
+
function \u5F0F\u306B\u66F8\u304F\u6570(n) {
|
|
2184
|
+
if (!Number.isFinite(n)) return "0";
|
|
2185
|
+
const text = String(n);
|
|
2186
|
+
if (!/[eE]/.test(text)) return text;
|
|
2187
|
+
const [coefficient = "0", exponentText = "0"] = text.toLowerCase().split("e");
|
|
2188
|
+
const negative = coefficient.startsWith("-");
|
|
2189
|
+
const unsigned = negative ? coefficient.slice(1) : coefficient;
|
|
2190
|
+
const [whole = "0", fraction = ""] = unsigned.split(".");
|
|
2191
|
+
const digits = `${whole}${fraction}`;
|
|
2192
|
+
const decimalAt = whole.length + Number(exponentText);
|
|
2193
|
+
let expanded;
|
|
2194
|
+
if (decimalAt <= 0) expanded = `0.${"0".repeat(-decimalAt)}${digits}`;
|
|
2195
|
+
else if (decimalAt >= digits.length) expanded = `${digits}${"0".repeat(decimalAt - digits.length)}`;
|
|
2196
|
+
else expanded = `${digits.slice(0, decimalAt)}.${digits.slice(decimalAt)}`;
|
|
2197
|
+
return negative ? `-${expanded}` : expanded;
|
|
2198
|
+
}
|
|
2199
|
+
function \u5883\u76EE\u3092\u901A\u308B\u6642\u523B(\u533A\u9593, op, \u5883\u76EE) {
|
|
2200
|
+
const \u6E80\u305F\u3059 = (x) => {
|
|
2201
|
+
switch (op) {
|
|
2202
|
+
case ">=":
|
|
2203
|
+
return x >= \u5883\u76EE;
|
|
2204
|
+
case ">":
|
|
2205
|
+
return x > \u5883\u76EE;
|
|
2206
|
+
case "<=":
|
|
2207
|
+
return x <= \u5883\u76EE;
|
|
2208
|
+
case "<":
|
|
2209
|
+
return x < \u5883\u76EE;
|
|
2210
|
+
case "==":
|
|
2211
|
+
return x === \u5883\u76EE;
|
|
2212
|
+
case "!=":
|
|
2213
|
+
return x !== \u5883\u76EE;
|
|
2214
|
+
default:
|
|
2215
|
+
return false;
|
|
2216
|
+
}
|
|
2217
|
+
};
|
|
2218
|
+
if (\u6E80\u305F\u3059(\u533A\u9593.from)) return \u533A\u9593.start;
|
|
2219
|
+
if (op === "==") {
|
|
2220
|
+
const min = Math.min(\u533A\u9593.from, \u533A\u9593.to);
|
|
2221
|
+
const max = Math.max(\u533A\u9593.from, \u533A\u9593.to);
|
|
2222
|
+
if (\u5883\u76EE < min || \u5883\u76EE > max) return null;
|
|
2223
|
+
} else if (!\u6E80\u305F\u3059(\u533A\u9593.to)) {
|
|
2224
|
+
return null;
|
|
2225
|
+
}
|
|
2226
|
+
if (\u533A\u9593.to === \u533A\u9593.from) return null;
|
|
2227
|
+
const t = \u533A\u9593.start + \u533A\u9593.dur * (\u5883\u76EE - \u533A\u9593.from) / (\u533A\u9593.to - \u533A\u9593.from);
|
|
2228
|
+
if (!Number.isFinite(t)) return null;
|
|
2229
|
+
return Math.min(Math.max(t, \u533A\u9593.start), \u533A\u9593.end);
|
|
2230
|
+
}
|
|
2231
|
+
function foldValueTriggers(diagram2, doc, onNotice) {
|
|
2232
|
+
const \u51FA\u529B = /* @__PURE__ */ new Map();
|
|
2233
|
+
const \u304D\u3063\u304B\u3051\u4ED8\u304D = (doc.values ?? []).filter((v) => v.trigger !== void 0);
|
|
2234
|
+
if (\u304D\u3063\u304B\u3051\u4ED8\u304D.length === 0) return \u51FA\u529B;
|
|
2235
|
+
const \u5BA3\u8A00 = /* @__PURE__ */ new Map();
|
|
2236
|
+
for (const v of \u304D\u3063\u304B\u3051\u4ED8\u304D) if (!\u5BA3\u8A00.has(v.name)) \u5BA3\u8A00.set(v.name, v);
|
|
2237
|
+
const \u521D\u671F\u5024 = /* @__PURE__ */ new Map();
|
|
2238
|
+
for (const s of diagram2.states) {
|
|
2239
|
+
const n = Number(s.initial);
|
|
2240
|
+
if (Number.isFinite(n)) \u521D\u671F\u5024.set(s.id, n);
|
|
2241
|
+
}
|
|
2242
|
+
const \u6BB5\u306E\u756A\u53F7 = /* @__PURE__ */ new Map();
|
|
2243
|
+
diagram2.phases.forEach((p, i) => {
|
|
2244
|
+
if (!\u6BB5\u306E\u756A\u53F7.has(p.title)) \u6BB5\u306E\u756A\u53F7.set(p.title, i);
|
|
2245
|
+
if (!\u6BB5\u306E\u756A\u53F7.has(p.id)) \u6BB5\u306E\u756A\u53F7.set(p.id, i);
|
|
2246
|
+
});
|
|
2247
|
+
const \u89E3\u3051\u305F = /* @__PURE__ */ new Map();
|
|
2248
|
+
const \u89E3\u3051\u306A\u3044 = /* @__PURE__ */ new Set();
|
|
2249
|
+
const \u89E3\u6C7A\u4E2D = /* @__PURE__ */ new Set();
|
|
2250
|
+
const \u77E5\u3089\u305B\u308B = (v, message, hint) => {
|
|
2251
|
+
onNotice?.({ kind: "value-trigger-unresolved", actor: v.name, line: v.pos?.line ?? 0, message, hint });
|
|
2252
|
+
};
|
|
2253
|
+
const \u89E3\u304F = (name) => {
|
|
2254
|
+
const \u65E2\u51FA = \u89E3\u3051\u305F.get(name);
|
|
2255
|
+
if (\u65E2\u51FA) return \u65E2\u51FA;
|
|
2256
|
+
if (\u89E3\u3051\u306A\u3044.has(name)) return null;
|
|
2257
|
+
const v = \u5BA3\u8A00.get(name);
|
|
2258
|
+
if (!v || !v.trigger) return null;
|
|
2259
|
+
if (\u89E3\u6C7A\u4E2D.has(name)) {
|
|
2260
|
+
\u89E3\u3051\u306A\u3044.add(name);
|
|
2261
|
+
\u77E5\u3089\u305B\u308B(v, `"${name}" \u306E\u304D\u3063\u304B\u3051\u304C\u4E00\u5468\u3057\u3066\u3044\u307E\u3059`, "\u3069\u308C\u304B 1 \u3064\u3092 `trigger: step ...` \u306B\u5909\u3048\u308B");
|
|
2262
|
+
return null;
|
|
2263
|
+
}
|
|
2264
|
+
\u89E3\u6C7A\u4E2D.add(name);
|
|
2265
|
+
const \u533A\u9593 = \u7D44\u307F\u7ACB\u3066\u308B(v);
|
|
2266
|
+
\u89E3\u6C7A\u4E2D.delete(name);
|
|
2267
|
+
if (!\u533A\u9593) {
|
|
2268
|
+
\u89E3\u3051\u306A\u3044.add(name);
|
|
2269
|
+
return null;
|
|
2270
|
+
}
|
|
2271
|
+
\u89E3\u3051\u305F.set(name, \u533A\u9593);
|
|
2272
|
+
return \u533A\u9593;
|
|
2273
|
+
};
|
|
2274
|
+
const \u7D44\u307F\u7ACB\u3066\u308B = (v) => {
|
|
2275
|
+
const trigger = v.trigger;
|
|
2276
|
+
const from = \u521D\u671F\u5024.get(v.name) ?? 0;
|
|
2277
|
+
const to = v.to ?? 0;
|
|
2278
|
+
const dur = v.durationMs ?? 0;
|
|
2279
|
+
let \u6BB5 = 0;
|
|
2280
|
+
let start = 0;
|
|
2281
|
+
if (trigger.kind === "step") {
|
|
2282
|
+
const idx = \u6BB5\u306E\u756A\u53F7.get(trigger.step);
|
|
2283
|
+
if (idx === void 0) {
|
|
2284
|
+
\u77E5\u3089\u305B\u308B(v, `"${trigger.step}" \u3068\u3044\u3046\u6BB5\u304C\u3042\u308A\u307E\u305B\u3093`, "`animation:` \u306B\u305D\u306E\u540D\u524D\u306E\u6BB5\u3092\u66F8\u304F\u304B\u3001 \u6BB5\u306E\u540D\u524D\u306B\u5408\u308F\u305B\u308B");
|
|
2285
|
+
return null;
|
|
2286
|
+
}
|
|
2287
|
+
\u6BB5 = idx;
|
|
2288
|
+
start = 0;
|
|
2289
|
+
} else {
|
|
2290
|
+
const \u76F8\u624B = \u89E3\u304F(trigger.source);
|
|
2291
|
+
if (!\u76F8\u624B) {
|
|
2292
|
+
\u77E5\u3089\u305B\u308B(
|
|
2293
|
+
v,
|
|
2294
|
+
`"${trigger.source}" \u304C\u52D5\u304F\u5024\u3067\u306A\u3044\u305F\u3081\u3001 \u304D\u3063\u304B\u3051\u306E\u6642\u523B\u3092\u6C7A\u3081\u3089\u308C\u307E\u305B\u3093`,
|
|
2295
|
+
"\u898B\u5F35\u308B\u76F8\u624B\u3082 `trigger:` \u3092\u6301\u3064\u5024\u306B\u3059\u308B"
|
|
2296
|
+
);
|
|
2297
|
+
return null;
|
|
2298
|
+
}
|
|
2299
|
+
const at = \u5883\u76EE\u3092\u901A\u308B\u6642\u523B(\u76F8\u624B, trigger.op, trigger.threshold);
|
|
2300
|
+
if (at === null) {
|
|
2301
|
+
\u77E5\u3089\u305B\u308B(
|
|
2302
|
+
v,
|
|
2303
|
+
`"${trigger.source}" \u306F ${trigger.op} ${trigger.threshold} \u3092\u6E80\u305F\u3057\u307E\u305B\u3093`,
|
|
2304
|
+
"\u76F8\u624B\u304C\u901A\u308B\u5024\u3092\u5883\u76EE\u306B\u3059\u308B\u304B\u3001 \u76F8\u624B\u306E `to` \u3092\u898B\u76F4\u3059"
|
|
2305
|
+
);
|
|
2306
|
+
return null;
|
|
2307
|
+
}
|
|
2308
|
+
\u6BB5 = \u76F8\u624B.\u6BB5;
|
|
2309
|
+
start = at;
|
|
2310
|
+
}
|
|
2311
|
+
const \u6BB5\u306E\u9577\u3055 = diagram2.phases[\u6BB5]?.duration ?? 0;
|
|
2312
|
+
if (start + dur > \u6BB5\u306E\u9577\u3055) {
|
|
2313
|
+
\u77E5\u3089\u305B\u308B(
|
|
2314
|
+
v,
|
|
2315
|
+
`\u6BB5 "${diagram2.phases[\u6BB5]?.title ?? ""}" (${\u6BB5\u306E\u9577\u3055}ms) \u306B\u53CE\u307E\u308A\u307E\u305B\u3093 (${Math.round(start + dur)}ms \u5FC5\u8981)`,
|
|
2316
|
+
"\u6BB5\u3092\u9577\u304F\u3059\u308B\u304B `dur` \u3092\u77ED\u304F\u3059\u308B"
|
|
2317
|
+
);
|
|
2318
|
+
return null;
|
|
2319
|
+
}
|
|
2320
|
+
return { \u6BB5, start, end: start + dur, dur, from, to };
|
|
2321
|
+
};
|
|
2322
|
+
for (const v of \u5BA3\u8A00.values()) \u89E3\u304F(v.name);
|
|
2323
|
+
if (\u89E3\u3051\u305F.size === 0) return \u51FA\u529B;
|
|
2324
|
+
const \u4F7F\u7528\u4E2D = new Set(diagram2.states.map((s) => s.id));
|
|
2325
|
+
for (const v of doc.values ?? []) \u4F7F\u7528\u4E2D.add(v.name);
|
|
2326
|
+
const \u6BB5\u3054\u3068\u306E\u6642\u8A08 = /* @__PURE__ */ new Map();
|
|
2327
|
+
const \u6642\u8A08\u3092\u7528\u610F\u3059\u308B = (\u6BB5) => {
|
|
2328
|
+
const \u65E2\u51FA = \u6BB5\u3054\u3068\u306E\u6642\u8A08.get(\u6BB5);
|
|
2329
|
+
if (\u65E2\u51FA) return \u65E2\u51FA;
|
|
2330
|
+
let \u540D\u524D = `__step_clock_${\u6BB5}`;
|
|
2331
|
+
let \u9023\u756A = 2;
|
|
2332
|
+
while (\u4F7F\u7528\u4E2D.has(\u540D\u524D)) \u540D\u524D = `__step_clock_${\u6BB5}_${\u9023\u756A++}`;
|
|
2333
|
+
\u4F7F\u7528\u4E2D.add(\u540D\u524D);
|
|
2334
|
+
\u6BB5\u3054\u3068\u306E\u6642\u8A08.set(\u6BB5, \u540D\u524D);
|
|
2335
|
+
diagram2.states.push({ id: \u540D\u524D, initial: 0 });
|
|
2336
|
+
const \u6BB5\u306E\u4E2D\u8EAB = diagram2.phases[\u6BB5];
|
|
2337
|
+
if (\u6BB5\u306E\u4E2D\u8EAB) \u6BB5\u306E\u4E2D\u8EAB.tweens = [...\u6BB5\u306E\u4E2D\u8EAB.tweens, { stateId: \u540D\u524D, from: 0, to: \u6BB5\u306E\u4E2D\u8EAB.duration }];
|
|
2338
|
+
return \u540D\u524D;
|
|
2339
|
+
};
|
|
2340
|
+
for (const [name, \u533A\u9593] of \u89E3\u3051\u305F) {
|
|
2341
|
+
const \u6642\u8A08 = \u6642\u8A08\u3092\u7528\u610F\u3059\u308B(\u533A\u9593.\u6BB5);
|
|
2342
|
+
const \u9032\u307F = `min(max(({${\u6642\u8A08}} - ${\u5F0F\u306B\u66F8\u304F\u6570(\u533A\u9593.start)}) / ${\u5F0F\u306B\u66F8\u304F\u6570(\u533A\u9593.dur)}, 0), 1)`;
|
|
2343
|
+
\u51FA\u529B.set(name, `((${\u9032\u307F} * ${\u5F0F\u306B\u66F8\u304F\u6570(\u533A\u9593.to - \u533A\u9593.from)}) + ${\u5F0F\u306B\u66F8\u304F\u6570(\u533A\u9593.from)})`);
|
|
2344
|
+
}
|
|
2345
|
+
return \u51FA\u529B;
|
|
2346
|
+
}
|
|
2347
|
+
function attachDerivedValues(diagram2, doc, onNotice, inheritedSourceLines, foldedTriggers) {
|
|
2348
|
+
const values = doc.values ?? [];
|
|
2349
|
+
if (values.length === 0) {
|
|
2350
|
+
if ((diagram2.derived?.length ?? 0) > 0) {
|
|
2351
|
+
reportUnresolvedValues(diagram2, doc, onNotice, inheritedSourceLines);
|
|
2352
|
+
}
|
|
2353
|
+
return;
|
|
2354
|
+
}
|
|
2355
|
+
const \u72B6\u614B\u306E\u540D\u524D = new Set(diagram2.states.map((s) => s.id));
|
|
2356
|
+
for (const v of values) {
|
|
2357
|
+
if (!\u72B6\u614B\u306E\u540D\u524D.has(v.name)) continue;
|
|
2358
|
+
if (v.trigger !== void 0) continue;
|
|
2359
|
+
onNotice?.({
|
|
2360
|
+
kind: "value-shadows-state",
|
|
2361
|
+
actor: v.name,
|
|
2362
|
+
line: v.pos?.line ?? 0,
|
|
2363
|
+
message: `"${v.name}" \u3092 states \u3068 values \u306E\u4E21\u65B9\u306B\u66F8\u3044\u3066\u3044\u307E\u3059\u3002 values \u3092\u4F7F\u3044\u307E\u3059`,
|
|
2364
|
+
hint: "states \u304B\u3089\u5916\u3059\u304B\u3001 values \u306E\u540D\u524D\u3092\u5909\u3048\u308B"
|
|
2365
|
+
});
|
|
2366
|
+
}
|
|
2367
|
+
const \u8F09\u305B\u308B = [];
|
|
2368
|
+
for (const v of values) {
|
|
2369
|
+
const expression = v.expression ?? foldedTriggers?.get(v.name);
|
|
2370
|
+
if (expression === void 0) continue;
|
|
2371
|
+
\u8F09\u305B\u308B.push({ id: v.name, expression });
|
|
2372
|
+
}
|
|
2373
|
+
diagram2.derived = [...\u8F09\u305B\u308B, ...diagram2.derived ?? []];
|
|
2374
|
+
reportUnresolvedValues(diagram2, doc, onNotice, inheritedSourceLines);
|
|
2375
|
+
}
|
|
2376
|
+
function renameFormulaIdentifiers(ast, rename) {
|
|
2377
|
+
switch (ast.type) {
|
|
2378
|
+
case "number":
|
|
2379
|
+
return ast;
|
|
2380
|
+
case "identifier":
|
|
2381
|
+
return { type: "identifier", name: rename(ast.name) };
|
|
2382
|
+
case "unaryOp":
|
|
2383
|
+
return { ...ast, operand: renameFormulaIdentifiers(ast.operand, rename) };
|
|
2384
|
+
case "binaryOp":
|
|
2385
|
+
return {
|
|
2386
|
+
...ast,
|
|
2387
|
+
left: renameFormulaIdentifiers(ast.left, rename),
|
|
2388
|
+
right: renameFormulaIdentifiers(ast.right, rename)
|
|
2389
|
+
};
|
|
2390
|
+
case "ternary":
|
|
2391
|
+
return {
|
|
2392
|
+
type: "ternary",
|
|
2393
|
+
condition: renameFormulaIdentifiers(ast.condition, rename),
|
|
2394
|
+
whenTrue: renameFormulaIdentifiers(ast.whenTrue, rename),
|
|
2395
|
+
whenFalse: renameFormulaIdentifiers(ast.whenFalse, rename)
|
|
2396
|
+
};
|
|
2397
|
+
case "call":
|
|
2398
|
+
return { ...ast, args: ast.args.map((a) => renameFormulaIdentifiers(a, rename)) };
|
|
2399
|
+
}
|
|
2400
|
+
}
|
|
2401
|
+
function writeNumber(value) {
|
|
2402
|
+
if (!Number.isFinite(value)) throw new Error(`cannot write non-finite number: ${String(value)}`);
|
|
2403
|
+
const s = String(value);
|
|
2404
|
+
if (!/[eE]/.test(s)) return s;
|
|
2405
|
+
const m = /^(-?)(\d+)(?:\.(\d+))?[eE]([+-]?\d+)$/.exec(s);
|
|
2406
|
+
if (!m) throw new Error(`cannot write number: ${s}`);
|
|
2407
|
+
const sign = m[1] ?? "";
|
|
2408
|
+
const int = m[2] ?? "";
|
|
2409
|
+
const frac = m[3] ?? "";
|
|
2410
|
+
const digits = int + frac;
|
|
2411
|
+
const point = int.length + Number(m[4] ?? "0");
|
|
2412
|
+
if (point <= 0) return `${sign}0.${"0".repeat(-point)}${digits}`;
|
|
2413
|
+
if (point >= digits.length) return `${sign}${digits}${"0".repeat(point - digits.length)}`;
|
|
2414
|
+
return `${sign}${digits.slice(0, point)}.${digits.slice(point)}`;
|
|
2415
|
+
}
|
|
2416
|
+
function writeFormula(ast) {
|
|
2417
|
+
switch (ast.type) {
|
|
2418
|
+
case "number":
|
|
2419
|
+
return writeNumber(ast.value);
|
|
2420
|
+
case "identifier":
|
|
2421
|
+
return /^[A-Za-z_$][\w$]*$/.test(ast.name) ? ast.name : `{${ast.name}}`;
|
|
2422
|
+
case "unaryOp":
|
|
2423
|
+
return `(${ast.op}${writeFormula(ast.operand)})`;
|
|
2424
|
+
case "binaryOp":
|
|
2425
|
+
return `(${writeFormula(ast.left)} ${ast.op} ${writeFormula(ast.right)})`;
|
|
2426
|
+
case "ternary":
|
|
2427
|
+
return `(${writeFormula(ast.condition)} ? ${writeFormula(ast.whenTrue)} : ${writeFormula(ast.whenFalse)})`;
|
|
2428
|
+
case "call":
|
|
2429
|
+
return `${ast.fn}(${ast.args.map(writeFormula).join(", ")})`;
|
|
2430
|
+
}
|
|
2431
|
+
}
|
|
2432
|
+
function recordDerivedSourceLine(sourceLines, id, line) {
|
|
2433
|
+
if (!sourceLines) return;
|
|
2434
|
+
const lines = sourceLines.get(id) ?? [];
|
|
2435
|
+
lines.push(line);
|
|
2436
|
+
sourceLines.set(id, lines);
|
|
2437
|
+
}
|
|
2438
|
+
function reportUnresolvedValues(diagram2, doc, onNotice, inheritedSourceLines) {
|
|
2439
|
+
if (!onNotice) return;
|
|
2440
|
+
const \u521D\u671F\u5024 = /* @__PURE__ */ Object.create(null);
|
|
2441
|
+
for (const s of diagram2.states) \u521D\u671F\u5024[s.id] = String(s.initial);
|
|
2442
|
+
const \u6700\u521D\u306E\u884C = /* @__PURE__ */ new Map();
|
|
2443
|
+
const \u91CD\u8907\u3057\u305F\u884C = /* @__PURE__ */ new Map();
|
|
2444
|
+
for (const v of doc.values ?? []) {
|
|
2445
|
+
if (!\u6700\u521D\u306E\u884C.has(v.name)) {
|
|
2446
|
+
\u6700\u521D\u306E\u884C.set(v.name, v.pos?.line ?? 0);
|
|
2447
|
+
continue;
|
|
2448
|
+
}
|
|
2449
|
+
const \u540C\u3058\u540D\u524D\u306E\u884C = \u91CD\u8907\u3057\u305F\u884C.get(v.name) ?? [];
|
|
2450
|
+
\u540C\u3058\u540D\u524D\u306E\u884C.push(v.pos?.line ?? 0);
|
|
2451
|
+
\u91CD\u8907\u3057\u305F\u884C.set(v.name, \u540C\u3058\u540D\u524D\u306E\u884C);
|
|
2452
|
+
}
|
|
2453
|
+
for (const [id, lines] of inheritedSourceLines ?? []) {
|
|
2454
|
+
for (const line of lines) {
|
|
2455
|
+
if (!\u6700\u521D\u306E\u884C.has(id)) {
|
|
2456
|
+
\u6700\u521D\u306E\u884C.set(id, line);
|
|
2457
|
+
continue;
|
|
2458
|
+
}
|
|
2459
|
+
const \u540C\u3058\u540D\u524D\u306E\u884C = \u91CD\u8907\u3057\u305F\u884C.get(id) ?? [];
|
|
2460
|
+
\u540C\u3058\u540D\u524D\u306E\u884C.push(line);
|
|
2461
|
+
\u91CD\u8907\u3057\u305F\u884C.set(id, \u540C\u3058\u540D\u524D\u306E\u884C);
|
|
2462
|
+
}
|
|
2463
|
+
}
|
|
2464
|
+
for (const n of cdl.applyDerivedValues(\u521D\u671F\u5024, diagram2.derived).notices) {
|
|
2465
|
+
onNotice({
|
|
2466
|
+
kind: n.kind === "duplicate-id" ? "value-duplicate" : "value-unresolved",
|
|
2467
|
+
actor: n.id,
|
|
2468
|
+
// 重複は後から書いた宣言そのものを、式の問題は engine が使う最初の宣言を指す
|
|
2469
|
+
line: n.kind === "duplicate-id" ? \u91CD\u8907\u3057\u305F\u884C.get(n.id)?.shift() ?? \u6700\u521D\u306E\u884C.get(n.id) ?? 0 : \u6700\u521D\u306E\u884C.get(n.id) ?? 0,
|
|
2470
|
+
message: n.message,
|
|
2471
|
+
hint: VALUE_NOTICE_HINT[n.kind]
|
|
2472
|
+
});
|
|
2473
|
+
}
|
|
2474
|
+
}
|
|
2475
|
+
var VALUE_NOTICE_HINT = {
|
|
2476
|
+
cycle: "\u53C2\u7167\u304C\u4E00\u5468\u3057\u3066\u3044\u307E\u3059\u3002 \u3069\u308C\u304B 1 \u3064\u3092 states \u306E\u521D\u671F\u5024\u306B\u5909\u3048\u308B",
|
|
2477
|
+
"unknown-reference": "\u305D\u306E\u540D\u524D\u306E states / values \u3092\u8DB3\u3059\u304B\u3001\u7DB4\u308A\u3092\u76F4\u3059",
|
|
2478
|
+
"parse-error": "\u5F0F\u306B\u66F8\u3051\u308B\u306E\u306F\u56DB\u5247 (+ - * /) \u3068\u62EC\u5F27\u3001\u6BD4\u8F03\u3001min / max \u3060\u3051",
|
|
2479
|
+
"eval-error": "\u521D\u671F\u5024\u3067\u8A08\u7B97\u3067\u304D\u306A\u3044\u5F62\u3067\u3059\u3002 \u5272\u308B\u6570\u3084\u3001\u6570\u3068\u3057\u3066\u8AAD\u3081\u306A\u3044\u521D\u671F\u5024\u3092\u898B\u76F4\u3059",
|
|
2480
|
+
"duplicate-id": "\u540C\u3058\u540D\u524D\u304C 2 \u5EA6\u3042\u308A\u307E\u3059\u3002 \u7247\u65B9\u3092\u6D88\u3059\u304B\u540D\u524D\u3092\u5909\u3048\u308B",
|
|
2481
|
+
"invalid-id": "\u540D\u524D\u306B\u4F7F\u3048\u308B\u306E\u306F\u82F1\u6570\u5B57\u3068 _ \u3060\u3051"
|
|
2482
|
+
};
|
|
1736
2483
|
var SINGLE_BOX_KINDS = /* @__PURE__ */ new Set([
|
|
1737
2484
|
"chart-pie",
|
|
1738
2485
|
"chart-line",
|
|
1739
2486
|
"chart-bar",
|
|
1740
2487
|
"gantt-timeline",
|
|
1741
2488
|
"mind-map",
|
|
1742
|
-
"mind-radial",
|
|
1743
2489
|
"funnel-stages",
|
|
1744
2490
|
"quadrant-matrix",
|
|
1745
2491
|
"tree-hierarchy",
|
|
@@ -1838,17 +2584,6 @@ function dropUnfittableEndKinds(diagram2, doc) {
|
|
|
1838
2584
|
}
|
|
1839
2585
|
}
|
|
1840
2586
|
}
|
|
1841
|
-
function fillFlowEdgeSources(diagram2, doc, sourceLines) {
|
|
1842
|
-
if (doc.type !== "flow") return;
|
|
1843
|
-
if (doc.animate && doc.animate.phases.length > 0) return;
|
|
1844
|
-
diagram2.edges.forEach((e, idx) => {
|
|
1845
|
-
const to = doc.actors[idx + 1];
|
|
1846
|
-
if (to === void 0) return;
|
|
1847
|
-
const step = doc.flow.find((s) => s.to === to.name);
|
|
1848
|
-
if (step === void 0) return;
|
|
1849
|
-
sourceLines.set(e.id, step.pos.line);
|
|
1850
|
-
});
|
|
1851
|
-
}
|
|
1852
2587
|
function applyGroupContainers(diagram2, doc) {
|
|
1853
2588
|
if (!doc.groups || Object.keys(doc.groups).length === 0) return;
|
|
1854
2589
|
for (const [id, g] of Object.entries(doc.groups)) {
|
|
@@ -1885,10 +2620,57 @@ function compileSolidity(doc) {
|
|
|
1885
2620
|
const sortedDoc = { ...doc, actors: sorted };
|
|
1886
2621
|
return compileSequence(sortedDoc);
|
|
1887
2622
|
}
|
|
2623
|
+
function \u72B6\u614B\u304C\u53D6\u308B\u5024(\u53C2\u7167, doc) {
|
|
2624
|
+
const \u540D = \u53C2\u7167.slice(1, -1);
|
|
2625
|
+
const out = [];
|
|
2626
|
+
const \u6570\u306B\u3059\u308B = (v) => {
|
|
2627
|
+
if (typeof v === "number") {
|
|
2628
|
+
if (Number.isFinite(v)) out.push(v);
|
|
2629
|
+
return;
|
|
2630
|
+
}
|
|
2631
|
+
const \u6587\u5B57 = String(v).trim();
|
|
2632
|
+
if (\u6587\u5B57 === "") return;
|
|
2633
|
+
const n = Number(\u6587\u5B57);
|
|
2634
|
+
if (Number.isFinite(n)) out.push(n);
|
|
2635
|
+
};
|
|
2636
|
+
for (const st of doc.animate?.states ?? []) if (st.name === \u540D) \u6570\u306B\u3059\u308B(st.initial);
|
|
2637
|
+
for (const p of doc.animate?.phases ?? []) {
|
|
2638
|
+
for (const t of p.tweens ?? []) {
|
|
2639
|
+
if (t.state !== \u540D) continue;
|
|
2640
|
+
\u6570\u306B\u3059\u308B(t.from);
|
|
2641
|
+
\u6570\u306B\u3059\u308B(t.to);
|
|
2642
|
+
}
|
|
2643
|
+
for (const v of p.sets ?? []) if (v.state === \u540D) \u6570\u306B\u3059\u308B(v.value);
|
|
2644
|
+
}
|
|
2645
|
+
return out;
|
|
2646
|
+
}
|
|
2647
|
+
function \u7D42\u308F\u308B\u4F4D\u7F6E(end, \u59CB\u307E\u308A, \u76EE\u76DB\u308A, \u540D\u524D, \u4F1D\u3048\u308B, doc) {
|
|
2648
|
+
if (end === void 0) return { idx: \u59CB\u307E\u308A };
|
|
2649
|
+
if (/^\{\w+\}$/.test(end)) {
|
|
2650
|
+
const \u4F4E\u3044 = \u72B6\u614B\u304C\u53D6\u308B\u5024(end, doc).filter((v) => v < \u59CB\u307E\u308A);
|
|
2651
|
+
if (\u4F4E\u3044.length > 0) {
|
|
2652
|
+
\u4F1D\u3048\u308B(
|
|
2653
|
+
\u540D\u524D,
|
|
2654
|
+
`type: gantt \u3067 ${truncateForMessage(\u540D\u524D)} \u306E\u7D42\u308F\u308A (${truncateForMessage(end)}) \u304C\u59CB\u307E\u308A\u3088\u308A\u524D\u306B\u306A\u308B\u5024\u3092\u53D6\u308A\u307E\u3059 (${[...new Set(\u4F4E\u3044)].join(", ")})\u3002 \u59CB\u307E\u308A\u306F ${\u59CB\u307E\u308A} \u756A\u76EE\u3067\u3059`
|
|
2655
|
+
);
|
|
2656
|
+
}
|
|
2657
|
+
return { idx: end };
|
|
2658
|
+
}
|
|
2659
|
+
const i = \u76EE\u76DB\u308A.indexOf(end);
|
|
2660
|
+
if (i < 0) return { idx: \u59CB\u307E\u308A };
|
|
2661
|
+
if (i < \u59CB\u307E\u308A) {
|
|
2662
|
+
\u4F1D\u3048\u308B(
|
|
2663
|
+
\u540D\u524D,
|
|
2664
|
+
`type: gantt \u3067 ${truncateForMessage(\u540D\u524D)} \u306E\u7D42\u308F\u308A (${truncateForMessage(end)}) \u304C\u59CB\u307E\u308A\u3088\u308A\u524D\u3067\u3059 (\u59CB\u307E\u308A\u3068\u540C\u3058\u306B\u5012\u3057\u307E\u3057\u305F)`
|
|
2665
|
+
);
|
|
2666
|
+
return { idx: \u59CB\u307E\u308A };
|
|
2667
|
+
}
|
|
2668
|
+
return { idx: i, label: end };
|
|
2669
|
+
}
|
|
1888
2670
|
function compileGantt(doc) {
|
|
1889
2671
|
const b = cdl.diagram(slugify(doc.title), { topic: doc.title });
|
|
1890
2672
|
const CHART_W = 720;
|
|
1891
|
-
b.lane("gantt", { width: CHART_W
|
|
2673
|
+
b.lane("gantt", { width: CHART_W });
|
|
1892
2674
|
const \u76EE\u76DB\u308A = [];
|
|
1893
2675
|
const \u76EE\u76DB\u308A\u306A\u3057 = [];
|
|
1894
2676
|
const \u30BF\u30B9\u30AF = [];
|
|
@@ -1899,7 +2681,13 @@ function compileGantt(doc) {
|
|
|
1899
2681
|
continue;
|
|
1900
2682
|
}
|
|
1901
2683
|
if (!\u76EE\u76DB\u308A.includes(label)) \u76EE\u76DB\u308A.push(label);
|
|
1902
|
-
\u30BF\u30B9\u30AF.push({
|
|
2684
|
+
\u30BF\u30B9\u30AF.push({
|
|
2685
|
+
name: a.name,
|
|
2686
|
+
label,
|
|
2687
|
+
...a.tone !== void 0 ? { tone: a.tone } : {},
|
|
2688
|
+
...a.owner !== void 0 ? { owner: a.owner } : {},
|
|
2689
|
+
...a.end !== void 0 ? { end: a.end } : {}
|
|
2690
|
+
});
|
|
1903
2691
|
}
|
|
1904
2692
|
if (\u76EE\u76DB\u308A\u306A\u3057.length > 0 && typeof console !== "undefined" && console.warn) {
|
|
1905
2693
|
console.warn(
|
|
@@ -1930,24 +2718,30 @@ function compileGantt(doc) {
|
|
|
1930
2718
|
`[dragon] type: gantt \u306E\u77E2\u5370\u306F\u524D\u5F8C\u306E\u95A2\u4FC2\u3060\u3051\u3092\u4F7F\u3044\u307E\u3059 (\u6587\u5B57 / \u8272 / \u7DDA\u7A2E\u306F\u63CF\u3051\u307E\u305B\u3093): ${\u88C5\u98FE\u3064\u304D.join(", ")}`
|
|
1931
2719
|
);
|
|
1932
2720
|
}
|
|
2721
|
+
const \u9006\u5411\u304D\u3092\u4F1D\u3048\u308B = (_\u540D, message) => {
|
|
2722
|
+
if (typeof console !== "undefined" && console.warn) console.warn(`[dragon] ${message}`);
|
|
2723
|
+
};
|
|
1933
2724
|
const CHART_H = Math.max(360, 48 * \u30BF\u30B9\u30AF.length + 96);
|
|
1934
2725
|
b.node(`${slugify(doc.title)}-chart`, {
|
|
1935
2726
|
lane: "gantt",
|
|
1936
2727
|
stack: 0,
|
|
1937
2728
|
kind: "gantt-timeline",
|
|
1938
2729
|
title: doc.title,
|
|
2730
|
+
...\u56F3\u306E\u5C0F\u898B\u51FA\u3057(doc),
|
|
1939
2731
|
w: CHART_W,
|
|
1940
2732
|
h: CHART_H,
|
|
1941
2733
|
ganttData: \u30BF\u30B9\u30AF.map((t) => {
|
|
1942
2734
|
const idx = \u76EE\u76DB\u308A.indexOf(t.label);
|
|
1943
2735
|
const from = \u4F9D\u5B58\u5143.get(t.name);
|
|
2736
|
+
const \u7D42\u308F\u308A = \u7D42\u308F\u308B\u4F4D\u7F6E(t.end, idx, \u76EE\u76DB\u308A, t.name, \u9006\u5411\u304D\u3092\u4F1D\u3048\u308B, doc);
|
|
1944
2737
|
return {
|
|
1945
2738
|
id: slugify(t.name),
|
|
1946
2739
|
title: t.name,
|
|
1947
2740
|
startIdx: idx,
|
|
1948
|
-
endIdx: idx,
|
|
2741
|
+
endIdx: \u7D42\u308F\u308A.idx,
|
|
1949
2742
|
startLabel: t.label,
|
|
1950
|
-
endLabel: t.label,
|
|
2743
|
+
endLabel: \u7D42\u308F\u308A.label ?? t.label,
|
|
2744
|
+
...t.owner !== void 0 ? { owner: t.owner } : {},
|
|
1951
2745
|
...from !== void 0 ? { dependsOn: slugify(from) } : {},
|
|
1952
2746
|
...t.tone !== void 0 ? { tone: t.tone } : {}
|
|
1953
2747
|
};
|
|
@@ -1958,13 +2752,15 @@ function compileGantt(doc) {
|
|
|
1958
2752
|
function compileClass(doc) {
|
|
1959
2753
|
const b = cdl.diagram(slugify(doc.title), { topic: doc.title });
|
|
1960
2754
|
const CLASS_W = 400;
|
|
2755
|
+
const CLASS_LANE_W = 450;
|
|
1961
2756
|
if (doc.actors.length === 0) return b.build();
|
|
1962
|
-
b.lane("class-stack", { width: CLASS_W, label: doc.title });
|
|
1963
2757
|
doc.actors.forEach((a, idx) => {
|
|
1964
2758
|
const nodeId = slugify(a.name);
|
|
2759
|
+
const laneId = `lane-${nodeId}`;
|
|
2760
|
+
b.lane(laneId, { width: CLASS_LANE_W });
|
|
1965
2761
|
b.node(nodeId, {
|
|
1966
|
-
lane:
|
|
1967
|
-
stack:
|
|
2762
|
+
lane: laneId,
|
|
2763
|
+
stack: 0,
|
|
1968
2764
|
kind: "storage",
|
|
1969
2765
|
title: a.name,
|
|
1970
2766
|
w: CLASS_W
|
|
@@ -1984,47 +2780,474 @@ function compileClass(doc) {
|
|
|
1984
2780
|
}
|
|
1985
2781
|
function parseShareValue(raw) {
|
|
1986
2782
|
if (raw === void 0) return null;
|
|
1987
|
-
const m = raw.trim().match(/^(
|
|
2783
|
+
const m = raw.trim().match(/^(-?\d+(?:\.\d+)?)\s*%?$/);
|
|
1988
2784
|
if (m === null) return null;
|
|
1989
2785
|
const v = Number(m[1]);
|
|
1990
2786
|
return Number.isFinite(v) ? v : null;
|
|
1991
2787
|
}
|
|
1992
|
-
function
|
|
2788
|
+
function parseBoundValue(raw) {
|
|
2789
|
+
if (raw === void 0) return null;
|
|
2790
|
+
const t = raw.trim();
|
|
2791
|
+
return /^\{\w+(?:\.(?:length|sum|max|min|avg)|\[\d+\])?\}$/.test(t) ? t : null;
|
|
2792
|
+
}
|
|
2793
|
+
function parseChartValue(raw) {
|
|
2794
|
+
const n = parseShareValue(raw);
|
|
2795
|
+
if (n !== null) return n;
|
|
2796
|
+
return parseBoundValue(raw);
|
|
2797
|
+
}
|
|
2798
|
+
function \u53C2\u7167\u3059\u308B\u540D\u524D(value) {
|
|
2799
|
+
if (typeof value !== "string") return null;
|
|
2800
|
+
const m = value.match(/^\{(\w+)/);
|
|
2801
|
+
return m ? m[1] : null;
|
|
2802
|
+
}
|
|
2803
|
+
function compileValueChart(doc, \u578B, kind, onNotice) {
|
|
1993
2804
|
const b = cdl.diagram(slugify(doc.title), { topic: doc.title });
|
|
1994
2805
|
const CHART_W = 640;
|
|
1995
|
-
const CHART_H = 320;
|
|
1996
|
-
b.lane("chart", { width: CHART_W + 64
|
|
2806
|
+
const CHART_H = \u578B === "pie" ? 320 : 368;
|
|
2807
|
+
b.lane("chart", { width: CHART_W + 64 });
|
|
1997
2808
|
const data = [];
|
|
1998
2809
|
const \u8AAD\u3081\u306A\u3044 = [];
|
|
2810
|
+
const \u672A\u5BA3\u8A00 = [];
|
|
2811
|
+
let \u672A\u5BA3\u8A00\u884C = 0;
|
|
2812
|
+
const \u53C2\u7167\u3067\u304D\u308B = \u6570\u306E\u6B04\u304B\u3089\u53C2\u7167\u3067\u304D\u308B\u540D\u524D(doc);
|
|
2813
|
+
let \u8AAD\u3081\u306A\u3044\u884C = 0;
|
|
1999
2814
|
for (const a of doc.actors) {
|
|
2000
|
-
const value =
|
|
2001
|
-
if (value === null) {
|
|
2815
|
+
const value = parseChartValue(a.value ?? a.subtitle);
|
|
2816
|
+
if (value === null || typeof value === "number" && value < 0 && \u578B !== "line") {
|
|
2817
|
+
if (\u8AAD\u3081\u306A\u3044.length === 0) \u8AAD\u3081\u306A\u3044\u884C = a.pos?.line ?? 0;
|
|
2002
2818
|
\u8AAD\u3081\u306A\u3044.push(a.name);
|
|
2003
2819
|
continue;
|
|
2004
2820
|
}
|
|
2821
|
+
const \u540D\u524D = \u53C2\u7167\u3059\u308B\u540D\u524D(value);
|
|
2822
|
+
if (\u540D\u524D !== null && !\u53C2\u7167\u3067\u304D\u308B.has(\u540D\u524D)) {
|
|
2823
|
+
if (\u672A\u5BA3\u8A00.length === 0) \u672A\u5BA3\u8A00\u884C = a.pos?.line ?? 0;
|
|
2824
|
+
\u672A\u5BA3\u8A00.push(a.name);
|
|
2825
|
+
continue;
|
|
2826
|
+
}
|
|
2005
2827
|
data.push({ label: a.name, value, ...a.tone !== void 0 ? { tone: a.tone } : {} });
|
|
2006
2828
|
}
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2829
|
+
const \u8A9E = \u578B === "pie" ? { \u91CF: "\u5272\u5408", \u56F3: "\u5186", \u4F8B: '"45%"' } : \u578B === "bar" ? { \u91CF: "\u5024", \u56F3: "\u68D2", \u4F8B: '"420"' } : { \u91CF: "\u5024", \u56F3: "\u6298\u308C\u7DDA", \u4F8B: '"180"' };
|
|
2830
|
+
const \u4F1D\u3048\u308B = (\u7A2E\u985E, \u540D\u524D, message, line = 0) => {
|
|
2831
|
+
onNotice?.({ kind: \u7A2E\u985E, actor: \u540D\u524D, line, message });
|
|
2832
|
+
if (typeof console !== "undefined" && console.warn) console.warn(`[dragon] ${message}`);
|
|
2833
|
+
};
|
|
2834
|
+
if (\u8AAD\u3081\u306A\u3044.length > 0) {
|
|
2835
|
+
\u4F1D\u3048\u308B(
|
|
2836
|
+
"chart-value-unreadable",
|
|
2837
|
+
\u8AAD\u3081\u306A\u3044[0],
|
|
2838
|
+
`type: ${\u578B} \u3067${\u8A9E.\u91CF}\u3092\u8AAD\u3081\u306A\u3044\u9805\u76EE\u304C\u3042\u308A\u307E\u3059 (${\u8A9E.\u56F3}\u306B\u8F09\u305B\u307E\u305B\u3093): ${\u8AAD\u3081\u306A\u3044.join(", ")}\u3002 \`- \u540D\u524D: ${\u8A9E.\u4F8B}\` \u306E\u5F62\u3067\u66F8\u3044\u3066\u304F\u3060\u3055\u3044`,
|
|
2839
|
+
\u8AAD\u3081\u306A\u3044\u884C
|
|
2010
2840
|
);
|
|
2011
2841
|
}
|
|
2012
|
-
if (
|
|
2013
|
-
|
|
2014
|
-
|
|
2842
|
+
if (\u672A\u5BA3\u8A00.length > 0) {
|
|
2843
|
+
\u4F1D\u3048\u308B(
|
|
2844
|
+
"chart-value-unreadable",
|
|
2845
|
+
\u672A\u5BA3\u8A00[0],
|
|
2846
|
+
`type: ${\u578B} \u3067\u6570\u306B\u306A\u3089\u306A\u3044\u5024\u3092\u53C2\u7167\u3057\u305F\u9805\u76EE\u304C\u3042\u308A\u307E\u3059 (${\u8A9E.\u56F3}\u306B\u8F09\u305B\u307E\u305B\u3093): ${\u672A\u5BA3\u8A00.join(", ")}\u3002 \`states:\` \u306B\u305D\u306E\u540D\u524D\u3092\u6570\u3067\u66F8\u3044\u3066\u304F\u3060\u3055\u3044`,
|
|
2847
|
+
\u672A\u5BA3\u8A00\u884C
|
|
2848
|
+
);
|
|
2849
|
+
}
|
|
2850
|
+
if (doc.flow.length > 0) {
|
|
2851
|
+
\u4F1D\u3048\u308B(
|
|
2852
|
+
"chart-edge-dropped",
|
|
2853
|
+
doc.flow[0]?.from ?? "",
|
|
2854
|
+
`type: ${\u578B} \u3067\u306F\u77E2\u5370\u3092\u63CF\u3051\u307E\u305B\u3093 (${doc.flow.length} \u672C\u3092\u7121\u8996\u3057\u307E\u3057\u305F)\u3002 \u95A2\u4FC2\u3092\u63CF\u304F\u306A\u3089 type: flow \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044`,
|
|
2855
|
+
doc.flow[0]?.pos?.line ?? 0
|
|
2015
2856
|
);
|
|
2016
2857
|
}
|
|
2017
2858
|
b.node(`${slugify(doc.title)}-chart`, {
|
|
2018
2859
|
lane: "chart",
|
|
2019
2860
|
stack: 0,
|
|
2020
|
-
kind
|
|
2861
|
+
kind,
|
|
2021
2862
|
title: doc.title,
|
|
2863
|
+
...\u56F3\u306E\u5C0F\u898B\u51FA\u3057(doc),
|
|
2022
2864
|
w: CHART_W,
|
|
2023
2865
|
h: CHART_H,
|
|
2024
2866
|
chartData: data
|
|
2025
2867
|
});
|
|
2026
2868
|
return b.build();
|
|
2027
2869
|
}
|
|
2870
|
+
var \u56F3\u8868\u306E\u5927\u304D\u3055 = {
|
|
2871
|
+
funnel: { w: 560, h: 480 },
|
|
2872
|
+
tree: { w: 720, h: 480 },
|
|
2873
|
+
mind: { w: 720, h: 480 },
|
|
2874
|
+
journey: { w: 720, h: 480 },
|
|
2875
|
+
quadrant: { w: 640, h: 480 }
|
|
2876
|
+
};
|
|
2877
|
+
var \u6C17\u6301\u3061 = /* @__PURE__ */ new Map([
|
|
2878
|
+
["\u6700\u9AD8", "delighted"],
|
|
2879
|
+
["\u6E80\u8DB3", "happy"],
|
|
2880
|
+
["\u666E\u901A", "neutral"],
|
|
2881
|
+
["\u4E0D\u6E80", "frustrated"],
|
|
2882
|
+
["\u6012\u308A", "angry"]
|
|
2883
|
+
]);
|
|
2884
|
+
var \u533A\u753B = /* @__PURE__ */ new Map([
|
|
2885
|
+
["\u5DE6\u4E0A", "topLeft"],
|
|
2886
|
+
["\u53F3\u4E0A", "topRight"],
|
|
2887
|
+
["\u5DE6\u4E0B", "bottomLeft"],
|
|
2888
|
+
["\u53F3\u4E0B", "bottomRight"]
|
|
2889
|
+
]);
|
|
2890
|
+
function \u56F3\u8868\u306E\u6B04\u304B\u3089\u53C2\u7167\u3067\u304D\u308B\u540D\u524D(doc, \u6B04) {
|
|
2891
|
+
const \u5B9F\u52B9 = /* @__PURE__ */ new Map();
|
|
2892
|
+
for (const s of doc.animate?.states ?? []) \u5B9F\u52B9.set(s.name, s.initial);
|
|
2893
|
+
const \u58CA\u308C\u308B = /* @__PURE__ */ new Set();
|
|
2894
|
+
for (const p of doc.animate?.phases ?? []) {
|
|
2895
|
+
for (const st of p.sets ?? []) if (!\u6B04.\u8AAD\u3081\u308B\u304B(st.value)) \u58CA\u308C\u308B.add(st.state);
|
|
2896
|
+
if (\u6B04.\u88DC\u9593\u3067\u58CA\u308C\u308B\u304B) for (const tw of p.tweens ?? []) \u58CA\u308C\u308B.add(tw.state);
|
|
2897
|
+
}
|
|
2898
|
+
const out = /* @__PURE__ */ new Set();
|
|
2899
|
+
for (const [\u540D\u524D, \u5024] of \u5B9F\u52B9) {
|
|
2900
|
+
if (!\u6B04.\u8AAD\u3081\u308B\u304B(\u5024)) continue;
|
|
2901
|
+
if (\u58CA\u308C\u308B.has(\u540D\u524D)) continue;
|
|
2902
|
+
out.add(\u540D\u524D);
|
|
2903
|
+
}
|
|
2904
|
+
if (\u6B04.\u81EA\u52D5\u306E\u5024\u3092\u8A31\u3059\u304B) for (const v of doc.values ?? []) out.add(v.name);
|
|
2905
|
+
return out;
|
|
2906
|
+
}
|
|
2907
|
+
function \u6570\u3068\u3057\u3066\u8AAD\u3081\u308B\u304B(v) {
|
|
2908
|
+
if (typeof v === "number") return Number.isFinite(v);
|
|
2909
|
+
const t = v.trim();
|
|
2910
|
+
if (t === "") return false;
|
|
2911
|
+
return Number.isFinite(Number(t));
|
|
2912
|
+
}
|
|
2913
|
+
function \u6570\u306E\u6B04\u304B\u3089\u53C2\u7167\u3067\u304D\u308B\u540D\u524D(doc) {
|
|
2914
|
+
return \u56F3\u8868\u306E\u6B04\u304B\u3089\u53C2\u7167\u3067\u304D\u308B\u540D\u524D(doc, {
|
|
2915
|
+
\u8AAD\u3081\u308B\u304B: \u6570\u3068\u3057\u3066\u8AAD\u3081\u308B\u304B,
|
|
2916
|
+
// 補間の行き先は数なので、数の欄では壊れない
|
|
2917
|
+
\u88DC\u9593\u3067\u58CA\u308C\u308B\u304B: false,
|
|
2918
|
+
\u81EA\u52D5\u306E\u5024\u3092\u8A31\u3059\u304B: true
|
|
2919
|
+
});
|
|
2920
|
+
}
|
|
2921
|
+
function \u8A9E\u306E\u6B04\u304B\u3089\u53C2\u7167\u3067\u304D\u308B\u540D\u524D(doc, \u8A9E\u8868) {
|
|
2922
|
+
return \u56F3\u8868\u306E\u6B04\u304B\u3089\u53C2\u7167\u3067\u304D\u308B\u540D\u524D(doc, {
|
|
2923
|
+
\u8AAD\u3081\u308B\u304B: (v) => \u8A9E\u8868.has(String(v).trim()),
|
|
2924
|
+
// 補間の行き先は数。 語の欄が読む状態を補間すると、その段で語が数に変わる
|
|
2925
|
+
\u88DC\u9593\u3067\u58CA\u308C\u308B\u304B: true,
|
|
2926
|
+
// 式の評価結果は数になるため、語の欄からは読めない
|
|
2927
|
+
\u81EA\u52D5\u306E\u5024\u3092\u8A31\u3059\u304B: false
|
|
2928
|
+
});
|
|
2929
|
+
}
|
|
2930
|
+
function \u8A9E\u306E\u72B6\u614B\u3092\u56F3\u306E\u8A9E\u3078\u76F4\u3059(diagram2) {
|
|
2931
|
+
const \u5BFE\u8C61 = /* @__PURE__ */ new Map();
|
|
2932
|
+
const \u6570\u306E\u6B04\u304B\u3089 = /* @__PURE__ */ new Set();
|
|
2933
|
+
const \u62FE\u3046 = (v, \u8A9E\u8868) => {
|
|
2934
|
+
const m = typeof v === "string" ? v.match(/^\{(\w+)/) : null;
|
|
2935
|
+
if (m) \u5BFE\u8C61.set(m[1], \u8A9E\u8868);
|
|
2936
|
+
};
|
|
2937
|
+
for (const n of diagram2.nodes) {
|
|
2938
|
+
for (const st of n.journeyData ?? []) \u62FE\u3046(st.emotion, \u6C17\u6301\u3061);
|
|
2939
|
+
for (const it of n.quadrantData?.items ?? []) \u62FE\u3046(it.quadrant, \u533A\u753B);
|
|
2940
|
+
for (const d of n.chartData ?? []) {
|
|
2941
|
+
const m = typeof d.value === "string" ? d.value.match(/^\{(\w+)/) : null;
|
|
2942
|
+
if (m) \u6570\u306E\u6B04\u304B\u3089.add(m[1]);
|
|
2943
|
+
}
|
|
2944
|
+
for (const f of n.funnelData ?? []) {
|
|
2945
|
+
const m = typeof f.count === "string" ? f.count.match(/^\{(\w+)/) : null;
|
|
2946
|
+
if (m) \u6570\u306E\u6B04\u304B\u3089.add(m[1]);
|
|
2947
|
+
}
|
|
2948
|
+
}
|
|
2949
|
+
if (\u5BFE\u8C61.size === 0) return;
|
|
2950
|
+
const \u76F4\u3059 = (\u540D\u524D, \u5024) => {
|
|
2951
|
+
const \u8A9E\u8868 = \u5BFE\u8C61.get(\u540D\u524D);
|
|
2952
|
+
if (!\u8A9E\u8868 || \u6570\u306E\u6B04\u304B\u3089.has(\u540D\u524D)) return \u5024;
|
|
2953
|
+
return \u8A9E\u8868.get(String(\u5024).trim()) ?? \u5024;
|
|
2954
|
+
};
|
|
2955
|
+
for (const s of diagram2.states) s.initial = \u76F4\u3059(s.id, s.initial);
|
|
2956
|
+
for (const p of diagram2.phases) {
|
|
2957
|
+
for (const st of p.sets) st.value = \u76F4\u3059(st.stateId, st.value);
|
|
2958
|
+
}
|
|
2959
|
+
}
|
|
2960
|
+
function compileFunnel(doc, onNotice) {
|
|
2961
|
+
const b = cdl.diagram(slugify(doc.title), { topic: doc.title });
|
|
2962
|
+
const { w: W, h: H } = \u56F3\u8868\u306E\u5927\u304D\u3055.funnel;
|
|
2963
|
+
b.lane("chart", { width: W + 64 });
|
|
2964
|
+
const data = [];
|
|
2965
|
+
const \u8AAD\u3081\u306A\u3044 = [];
|
|
2966
|
+
const \u672A\u5BA3\u8A00 = [];
|
|
2967
|
+
const \u53C2\u7167\u3067\u304D\u308B = \u6570\u306E\u6B04\u304B\u3089\u53C2\u7167\u3067\u304D\u308B\u540D\u524D(doc);
|
|
2968
|
+
for (const a of doc.actors) {
|
|
2969
|
+
const v = parseChartValue(a.value ?? a.subtitle);
|
|
2970
|
+
if (v === null || typeof v === "number" && v < 0) {
|
|
2971
|
+
\u8AAD\u3081\u306A\u3044.push(a.name);
|
|
2972
|
+
continue;
|
|
2973
|
+
}
|
|
2974
|
+
const \u540D\u524D = \u53C2\u7167\u3059\u308B\u540D\u524D(v);
|
|
2975
|
+
if (\u540D\u524D !== null && !\u53C2\u7167\u3067\u304D\u308B.has(\u540D\u524D)) {
|
|
2976
|
+
\u672A\u5BA3\u8A00.push(a.name);
|
|
2977
|
+
continue;
|
|
2978
|
+
}
|
|
2979
|
+
data.push({ id: slugify(a.name), title: a.name, count: v });
|
|
2980
|
+
}
|
|
2981
|
+
if (\u672A\u5BA3\u8A00.length > 0) {
|
|
2982
|
+
const m3 = `type: funnel \u3067\u6570\u306B\u306A\u3089\u306A\u3044\u5024\u3092\u53C2\u7167\u3057\u305F\u9805\u76EE\u304C\u3042\u308A\u307E\u3059 (\u6BB5\u306B\u8F09\u305B\u307E\u305B\u3093): ${\u672A\u5BA3\u8A00.join(", ")}\u3002 \`states:\` \u306B\u305D\u306E\u540D\u524D\u3092\u6570\u3067\u66F8\u3044\u3066\u304F\u3060\u3055\u3044`;
|
|
2983
|
+
onNotice?.({ kind: "chart-value-unreadable", actor: \u672A\u5BA3\u8A00[0], line: 0, message: m3 });
|
|
2984
|
+
if (typeof console !== "undefined" && console.warn) console.warn(`[dragon] ${m3}`);
|
|
2985
|
+
}
|
|
2986
|
+
if (\u8AAD\u3081\u306A\u3044.length > 0) {
|
|
2987
|
+
const m = `type: funnel \u3067\u6570\u3092\u8AAD\u3081\u306A\u3044\u9805\u76EE\u304C\u3042\u308A\u307E\u3059 (\u6BB5\u306B\u8F09\u305B\u307E\u305B\u3093): ${\u8AAD\u3081\u306A\u3044.join(", ")}\u3002 \`- \u8A2A\u554F: "12000"\` \u306E\u5F62\u3067\u66F8\u3044\u3066\u304F\u3060\u3055\u3044`;
|
|
2988
|
+
onNotice?.({ kind: "chart-value-unreadable", actor: \u8AAD\u3081\u306A\u3044[0], line: 0, message: m });
|
|
2989
|
+
if (typeof console !== "undefined" && console.warn) console.warn(`[dragon] ${m}`);
|
|
2990
|
+
}
|
|
2991
|
+
if (doc.flow.length > 0) {
|
|
2992
|
+
const m2 = `type: funnel \u3067\u306F\u77E2\u5370\u3092\u63CF\u3051\u307E\u305B\u3093 (${doc.flow.length} \u672C\u3092\u7121\u8996\u3057\u307E\u3057\u305F)\u3002 \u95A2\u4FC2\u3092\u63CF\u304F\u306A\u3089 type: flow \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044`;
|
|
2993
|
+
onNotice?.({ kind: "chart-edge-dropped", actor: doc.flow[0]?.from ?? "", line: doc.flow[0]?.pos?.line ?? 0, message: m2 });
|
|
2994
|
+
if (typeof console !== "undefined" && console.warn) console.warn(`[dragon] ${m2}`);
|
|
2995
|
+
}
|
|
2996
|
+
b.node(`${slugify(doc.title)}-chart`, {
|
|
2997
|
+
lane: "chart",
|
|
2998
|
+
stack: 0,
|
|
2999
|
+
kind: "funnel-stages",
|
|
3000
|
+
title: doc.title,
|
|
3001
|
+
...\u56F3\u306E\u5C0F\u898B\u51FA\u3057(doc),
|
|
3002
|
+
w: W,
|
|
3003
|
+
h: H,
|
|
3004
|
+
funnelData: data
|
|
3005
|
+
});
|
|
3006
|
+
return b.build();
|
|
3007
|
+
}
|
|
3008
|
+
function \u77E2\u5370\u304B\u3089\u89AA\u3092\u6C7A\u3081\u308B(doc, \u56F3\u7A2E, \u540D\u524D, \u4F1D\u3048\u308B) {
|
|
3009
|
+
const \u89AA = /* @__PURE__ */ new Map();
|
|
3010
|
+
for (const f of doc.flow) {
|
|
3011
|
+
const \u5B50 = slugify(f.to);
|
|
3012
|
+
const \u89AA\u540D = slugify(f.from);
|
|
3013
|
+
if (!\u540D\u524D.has(\u89AA\u540D)) {
|
|
3014
|
+
\u4F1D\u3048\u308B(f.from, `type: ${\u56F3\u7A2E} \u3067\u66F8\u3044\u3066\u3044\u306A\u3044\u540D\u524D\u3092\u89AA\u306B\u3057\u3066\u3044\u307E\u3059: ${f.from} -> ${f.to}`, f.pos?.line ?? 0);
|
|
3015
|
+
continue;
|
|
3016
|
+
}
|
|
3017
|
+
if (!\u540D\u524D.has(\u5B50)) {
|
|
3018
|
+
\u4F1D\u3048\u308B(f.to, `type: ${\u56F3\u7A2E} \u3067\u66F8\u3044\u3066\u3044\u306A\u3044\u540D\u524D\u3092\u5B50\u306B\u3057\u3066\u3044\u307E\u3059: ${f.from} -> ${f.to}`, f.pos?.line ?? 0);
|
|
3019
|
+
continue;
|
|
3020
|
+
}
|
|
3021
|
+
if (\u5B50 === \u89AA\u540D) {
|
|
3022
|
+
\u4F1D\u3048\u308B(f.to, `type: ${\u56F3\u7A2E} \u3067\u81EA\u5206\u3092\u89AA\u306B\u3057\u3066\u3044\u307E\u3059: ${f.to}`, f.pos?.line ?? 0);
|
|
3023
|
+
continue;
|
|
3024
|
+
}
|
|
3025
|
+
const \u65E2\u5B58 = \u89AA.get(\u5B50);
|
|
3026
|
+
if (\u65E2\u5B58 !== void 0 && \u65E2\u5B58 !== \u89AA\u540D) {
|
|
3027
|
+
\u4F1D\u3048\u308B(f.to, `type: ${\u56F3\u7A2E} \u3067 ${f.to} \u306B\u89AA\u304C 2 \u3064\u3042\u308A\u307E\u3059 (\u5F8C\u306E ${f.from} \u306F\u4F7F\u3044\u307E\u305B\u3093)`, f.pos?.line ?? 0);
|
|
3028
|
+
continue;
|
|
3029
|
+
}
|
|
3030
|
+
\u89AA.set(\u5B50, \u89AA\u540D);
|
|
3031
|
+
}
|
|
3032
|
+
for (const \u5B50 of [...\u89AA.keys()]) {
|
|
3033
|
+
const \u898B\u305F = /* @__PURE__ */ new Set([\u5B50]);
|
|
3034
|
+
let p2 = \u89AA.get(\u5B50);
|
|
3035
|
+
while (p2 !== void 0) {
|
|
3036
|
+
if (\u898B\u305F.has(p2)) {
|
|
3037
|
+
\u4F1D\u3048\u308B(\u5B50, `type: ${\u56F3\u7A2E} \u3067\u89AA\u3092\u8FBF\u308B\u3068\u8F2A\u306B\u306A\u308A\u307E\u3059 (${\u5B50} \u306E\u89AA\u3092\u5916\u3057\u307E\u3057\u305F)`);
|
|
3038
|
+
\u89AA.delete(\u5B50);
|
|
3039
|
+
break;
|
|
3040
|
+
}
|
|
3041
|
+
\u898B\u305F.add(p2);
|
|
3042
|
+
p2 = \u89AA.get(p2);
|
|
3043
|
+
}
|
|
3044
|
+
}
|
|
3045
|
+
return \u89AA;
|
|
3046
|
+
}
|
|
3047
|
+
function compileTree(doc, onNotice) {
|
|
3048
|
+
const b = cdl.diagram(slugify(doc.title), { topic: doc.title });
|
|
3049
|
+
const { w: W, h: H } = \u56F3\u8868\u306E\u5927\u304D\u3055.tree;
|
|
3050
|
+
b.lane("chart", { width: W + 64 });
|
|
3051
|
+
const slug\u5225 = /* @__PURE__ */ new Map();
|
|
3052
|
+
for (const a of doc.actors) {
|
|
3053
|
+
const k = slugify(a.name);
|
|
3054
|
+
slug\u5225.set(k, [...slug\u5225.get(k) ?? [], a.name]);
|
|
3055
|
+
}
|
|
3056
|
+
const \u540D\u524D = new Set(slug\u5225.keys());
|
|
3057
|
+
const \u4F1D\u3048\u308B = (\u540D, message, line = 0) => {
|
|
3058
|
+
onNotice?.({ kind: "chart-value-unreadable", actor: \u540D, line, message });
|
|
3059
|
+
if (typeof console !== "undefined" && console.warn) console.warn(`[dragon] ${message}`);
|
|
3060
|
+
};
|
|
3061
|
+
for (const [k, \u7FA4] of slug\u5225) {
|
|
3062
|
+
if (\u7FA4.length > 1) {
|
|
3063
|
+
\u4F1D\u3048\u308B(\u7FA4[0], `type: tree \u3067 ${\u7FA4.join(" / ")} \u304C\u540C\u3058 id (${k}) \u306B\u306A\u308A\u307E\u3059\u3002 \u540D\u524D\u3092\u5909\u3048\u3066\u304F\u3060\u3055\u3044`);
|
|
3064
|
+
}
|
|
3065
|
+
}
|
|
3066
|
+
const \u89AA = \u77E2\u5370\u304B\u3089\u89AA\u3092\u6C7A\u3081\u308B(doc, "tree", \u540D\u524D, \u4F1D\u3048\u308B);
|
|
3067
|
+
const data = doc.actors.map((a) => {
|
|
3068
|
+
const id = slugify(a.name);
|
|
3069
|
+
const p3 = \u89AA.get(id);
|
|
3070
|
+
return { id, title: a.name, ...p3 !== void 0 ? { parent: p3 } : {} };
|
|
3071
|
+
});
|
|
3072
|
+
b.node(`${slugify(doc.title)}-chart`, {
|
|
3073
|
+
lane: "chart",
|
|
3074
|
+
stack: 0,
|
|
3075
|
+
kind: "tree-hierarchy",
|
|
3076
|
+
title: doc.title,
|
|
3077
|
+
...\u56F3\u306E\u5C0F\u898B\u51FA\u3057(doc),
|
|
3078
|
+
w: W,
|
|
3079
|
+
h: H,
|
|
3080
|
+
treeData: data
|
|
3081
|
+
});
|
|
3082
|
+
return b.build();
|
|
3083
|
+
}
|
|
3084
|
+
function \u9053\u7B4B\u306E\u6B04(a) {
|
|
3085
|
+
return {
|
|
3086
|
+
...a.touchpoint !== void 0 ? { touchpoint: a.touchpoint } : {},
|
|
3087
|
+
...a.opportunity !== void 0 ? { opportunity: a.opportunity } : {}
|
|
3088
|
+
};
|
|
3089
|
+
}
|
|
3090
|
+
function reportChartFieldsNotHonored(doc, onNotice) {
|
|
3091
|
+
if (!onNotice) return;
|
|
3092
|
+
if (doc.type === "mind") return;
|
|
3093
|
+
for (const a of doc.actors) {
|
|
3094
|
+
if (a.partId !== void 0) continue;
|
|
3095
|
+
const \u9053\u7B4B = doc.type === "journey" ? [] : [
|
|
3096
|
+
...a.touchpoint !== void 0 ? ["touchpoint"] : [],
|
|
3097
|
+
...a.opportunity !== void 0 ? ["opportunity"] : []
|
|
3098
|
+
];
|
|
3099
|
+
const \u5DE5\u7A0B = doc.type === "gantt" ? [] : [
|
|
3100
|
+
...a.owner !== void 0 ? ["owner"] : [],
|
|
3101
|
+
...a.end !== void 0 ? ["end"] : []
|
|
3102
|
+
];
|
|
3103
|
+
if (\u9053\u7B4B.length > 0) {
|
|
3104
|
+
onNotice({
|
|
3105
|
+
kind: "chart-value-unreadable",
|
|
3106
|
+
actor: a.name,
|
|
3107
|
+
line: a.pos?.line ?? 0,
|
|
3108
|
+
message: `"${truncateForMessage(a.name)}" \u306B\u66F8\u3044\u305F ${\u9053\u7B4B.join(" / ")} \u306F\u52B9\u304D\u307E\u305B\u3093 (type: ${doc.type} \u306B\u306F\u4F53\u9A13\u306E\u9053\u7B4B\u306E\u6B04\u304C\u3042\u308A\u307E\u305B\u3093)`,
|
|
3109
|
+
hint: "\u4F53\u9A13\u306E\u9053\u7B4B\u3092\u63CF\u304F\u306A\u3089 type: journey \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044"
|
|
3110
|
+
});
|
|
3111
|
+
}
|
|
3112
|
+
if (\u5DE5\u7A0B.length > 0) {
|
|
3113
|
+
onNotice({
|
|
3114
|
+
kind: "chart-value-unreadable",
|
|
3115
|
+
actor: a.name,
|
|
3116
|
+
line: a.pos?.line ?? 0,
|
|
3117
|
+
message: `"${truncateForMessage(a.name)}" \u306B\u66F8\u3044\u305F ${\u5DE5\u7A0B.join(" / ")} \u306F\u52B9\u304D\u307E\u305B\u3093 (type: ${doc.type} \u306B\u306F\u5DE5\u7A0B\u306E\u4E26\u3073\u306E\u6B04\u304C\u3042\u308A\u307E\u305B\u3093)`,
|
|
3118
|
+
hint: "\u5DE5\u7A0B\u306E\u4E26\u3073\u3092\u63CF\u304F\u306A\u3089 type: gantt \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044"
|
|
3119
|
+
});
|
|
3120
|
+
}
|
|
3121
|
+
}
|
|
3122
|
+
}
|
|
3123
|
+
function compileJourney(doc, onNotice) {
|
|
3124
|
+
const b = cdl.diagram(slugify(doc.title), { topic: doc.title });
|
|
3125
|
+
const { w: W, h: H } = \u56F3\u8868\u306E\u5927\u304D\u3055.journey;
|
|
3126
|
+
b.lane("chart", { width: W + 64 });
|
|
3127
|
+
const data = [];
|
|
3128
|
+
const \u8AAD\u3081\u306A\u3044 = [];
|
|
3129
|
+
const \u53C2\u7167\u3067\u304D\u308B = \u8A9E\u306E\u6B04\u304B\u3089\u53C2\u7167\u3067\u304D\u308B\u540D\u524D(doc, \u6C17\u6301\u3061);
|
|
3130
|
+
for (const a of doc.actors) {
|
|
3131
|
+
const \u8A9E = (a.value ?? a.subtitle ?? "").trim();
|
|
3132
|
+
const \u53C2\u7167 = \u8A9E.match(/^\{(\w+)\}$/);
|
|
3133
|
+
if (\u53C2\u7167) {
|
|
3134
|
+
if (!\u53C2\u7167\u3067\u304D\u308B.has(\u53C2\u7167[1])) {
|
|
3135
|
+
\u8AAD\u3081\u306A\u3044.push(a.name);
|
|
3136
|
+
continue;
|
|
3137
|
+
}
|
|
3138
|
+
data.push({ id: slugify(a.name), title: a.name, emotion: \u8A9E, ...\u9053\u7B4B\u306E\u6B04(a) });
|
|
3139
|
+
continue;
|
|
3140
|
+
}
|
|
3141
|
+
const e = \u6C17\u6301\u3061.get(\u8A9E);
|
|
3142
|
+
if (e === void 0) {
|
|
3143
|
+
\u8AAD\u3081\u306A\u3044.push(a.name);
|
|
3144
|
+
continue;
|
|
3145
|
+
}
|
|
3146
|
+
data.push({ id: slugify(a.name), title: a.name, emotion: e, ...\u9053\u7B4B\u306E\u6B04(a) });
|
|
3147
|
+
}
|
|
3148
|
+
if (\u8AAD\u3081\u306A\u3044.length > 0) {
|
|
3149
|
+
const m = `type: journey \u3067\u6C17\u6301\u3061\u3092\u8AAD\u3081\u306A\u3044\u9805\u76EE\u304C\u3042\u308A\u307E\u3059 (\u9053\u7B4B\u306B\u8F09\u305B\u307E\u305B\u3093): ${\u8AAD\u3081\u306A\u3044.join(", ")}\u3002 \`- \u767B\u9332: "\u4E0D\u6E80"\` \u306E\u5F62\u3067\u3001 ${[...\u6C17\u6301\u3061.keys()].join(" / ")} \u306E\u3069\u308C\u304B\u3092\u66F8\u3044\u3066\u304F\u3060\u3055\u3044`;
|
|
3150
|
+
onNotice?.({ kind: "chart-value-unreadable", actor: \u8AAD\u3081\u306A\u3044[0], line: 0, message: m });
|
|
3151
|
+
if (typeof console !== "undefined" && console.warn) console.warn(`[dragon] ${m}`);
|
|
3152
|
+
}
|
|
3153
|
+
if (doc.flow.length > 0) {
|
|
3154
|
+
const m2 = `type: journey \u3067\u306F\u77E2\u5370\u3092\u63CF\u3051\u307E\u305B\u3093 (${doc.flow.length} \u672C\u3092\u7121\u8996\u3057\u307E\u3057\u305F)\u3002 \u95A2\u4FC2\u3092\u63CF\u304F\u306A\u3089 type: flow \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044`;
|
|
3155
|
+
onNotice?.({ kind: "chart-edge-dropped", actor: doc.flow[0]?.from ?? "", line: doc.flow[0]?.pos?.line ?? 0, message: m2 });
|
|
3156
|
+
if (typeof console !== "undefined" && console.warn) console.warn(`[dragon] ${m2}`);
|
|
3157
|
+
}
|
|
3158
|
+
b.node(`${slugify(doc.title)}-chart`, {
|
|
3159
|
+
lane: "chart",
|
|
3160
|
+
stack: 0,
|
|
3161
|
+
kind: "journey-map",
|
|
3162
|
+
title: doc.title,
|
|
3163
|
+
...\u56F3\u306E\u5C0F\u898B\u51FA\u3057(doc),
|
|
3164
|
+
w: W,
|
|
3165
|
+
h: H,
|
|
3166
|
+
journeyData: data
|
|
3167
|
+
});
|
|
3168
|
+
return b.build();
|
|
3169
|
+
}
|
|
3170
|
+
var \u8EF8\u306E\u65E2\u5B9A = {
|
|
3171
|
+
xAxis: { left: "\u5C0F\u3055\u3044", right: "\u5927\u304D\u3044" },
|
|
3172
|
+
yAxis: { bottom: "\u5C0F\u3055\u3044", top: "\u5927\u304D\u3044" },
|
|
3173
|
+
quadrantLabels: { topLeft: "\u5DE6\u4E0A", topRight: "\u53F3\u4E0A", bottomLeft: "\u5DE6\u4E0B", bottomRight: "\u53F3\u4E0B" }
|
|
3174
|
+
};
|
|
3175
|
+
function \u8EF8\u3068\u533A\u753B\u306E\u540D\u524D(doc) {
|
|
3176
|
+
if (doc.axes === void 0) return \u8EF8\u306E\u65E2\u5B9A;
|
|
3177
|
+
const left = doc.axes.x?.left ?? \u8EF8\u306E\u65E2\u5B9A.xAxis.left;
|
|
3178
|
+
const right = doc.axes.x?.right ?? \u8EF8\u306E\u65E2\u5B9A.xAxis.right;
|
|
3179
|
+
const bottom = doc.axes.y?.bottom ?? \u8EF8\u306E\u65E2\u5B9A.yAxis.bottom;
|
|
3180
|
+
const top = doc.axes.y?.top ?? \u8EF8\u306E\u65E2\u5B9A.yAxis.top;
|
|
3181
|
+
return {
|
|
3182
|
+
xAxis: { left, right },
|
|
3183
|
+
yAxis: { bottom, top },
|
|
3184
|
+
quadrantLabels: {
|
|
3185
|
+
topLeft: `${top} \xD7 ${left}`,
|
|
3186
|
+
topRight: `${top} \xD7 ${right}`,
|
|
3187
|
+
bottomLeft: `${bottom} \xD7 ${left}`,
|
|
3188
|
+
bottomRight: `${bottom} \xD7 ${right}`
|
|
3189
|
+
}
|
|
3190
|
+
};
|
|
3191
|
+
}
|
|
3192
|
+
function reportAxesNotHonored(doc, onNotice) {
|
|
3193
|
+
if (!onNotice) return;
|
|
3194
|
+
if (doc.axes === void 0) return;
|
|
3195
|
+
if (doc.type === "quadrant") return;
|
|
3196
|
+
onNotice({
|
|
3197
|
+
kind: "chart-value-unreadable",
|
|
3198
|
+
actor: doc.title,
|
|
3199
|
+
line: doc.axesPos?.line ?? doc.pos?.line ?? 0,
|
|
3200
|
+
message: `\u6700\u4E0A\u4F4D\u306B\u66F8\u3044\u305F axes \u306F\u52B9\u304D\u307E\u305B\u3093 (type: ${doc.type} \u306B\u306F\u8EF8\u304C\u3042\u308A\u307E\u305B\u3093)`,
|
|
3201
|
+
hint: "2 \u3064\u306E\u8EF8\u3067\u4ED5\u5206\u3051\u308B\u56F3\u3092\u63CF\u304F\u306A\u3089 type: quadrant \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044"
|
|
3202
|
+
});
|
|
3203
|
+
}
|
|
3204
|
+
function compileQuadrant(doc, onNotice) {
|
|
3205
|
+
const b = cdl.diagram(slugify(doc.title), { topic: doc.title });
|
|
3206
|
+
const { w: W, h: H } = \u56F3\u8868\u306E\u5927\u304D\u3055.quadrant;
|
|
3207
|
+
b.lane("chart", { width: W + 64 });
|
|
3208
|
+
const items = [];
|
|
3209
|
+
const \u8AAD\u3081\u306A\u3044 = [];
|
|
3210
|
+
const \u53C2\u7167\u3067\u304D\u308B = \u8A9E\u306E\u6B04\u304B\u3089\u53C2\u7167\u3067\u304D\u308B\u540D\u524D(doc, \u533A\u753B);
|
|
3211
|
+
for (const a of doc.actors) {
|
|
3212
|
+
const \u8A9E = (a.value ?? a.subtitle ?? "").trim();
|
|
3213
|
+
const \u53C2\u7167 = \u8A9E.match(/^\{(\w+)\}$/);
|
|
3214
|
+
if (\u53C2\u7167) {
|
|
3215
|
+
if (!\u53C2\u7167\u3067\u304D\u308B.has(\u53C2\u7167[1])) {
|
|
3216
|
+
\u8AAD\u3081\u306A\u3044.push(a.name);
|
|
3217
|
+
continue;
|
|
3218
|
+
}
|
|
3219
|
+
items.push({ id: slugify(a.name), title: a.name, quadrant: \u8A9E });
|
|
3220
|
+
continue;
|
|
3221
|
+
}
|
|
3222
|
+
const q = \u533A\u753B.get(\u8A9E);
|
|
3223
|
+
if (q === void 0) {
|
|
3224
|
+
\u8AAD\u3081\u306A\u3044.push(a.name);
|
|
3225
|
+
continue;
|
|
3226
|
+
}
|
|
3227
|
+
items.push({ id: slugify(a.name), title: a.name, quadrant: q });
|
|
3228
|
+
}
|
|
3229
|
+
if (\u8AAD\u3081\u306A\u3044.length > 0) {
|
|
3230
|
+
const m = `type: quadrant \u3067\u533A\u753B\u3092\u8AAD\u3081\u306A\u3044\u9805\u76EE\u304C\u3042\u308A\u307E\u3059 (\u56F3\u306B\u8F09\u305B\u307E\u305B\u3093): ${\u8AAD\u3081\u306A\u3044.join(", ")}\u3002 \`- \u91CD\u8907\u524A\u9664: "\u5DE6\u4E0A"\` \u306E\u5F62\u3067\u3001 ${[...\u533A\u753B.keys()].join(" / ")} \u306E\u3069\u308C\u304B\u3092\u66F8\u3044\u3066\u304F\u3060\u3055\u3044`;
|
|
3231
|
+
onNotice?.({ kind: "chart-value-unreadable", actor: \u8AAD\u3081\u306A\u3044[0], line: 0, message: m });
|
|
3232
|
+
if (typeof console !== "undefined" && console.warn) console.warn(`[dragon] ${m}`);
|
|
3233
|
+
}
|
|
3234
|
+
if (doc.flow.length > 0) {
|
|
3235
|
+
const m2 = `type: quadrant \u3067\u306F\u77E2\u5370\u3092\u63CF\u3051\u307E\u305B\u3093 (${doc.flow.length} \u672C\u3092\u7121\u8996\u3057\u307E\u3057\u305F)\u3002 \u95A2\u4FC2\u3092\u63CF\u304F\u306A\u3089 type: flow \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044`;
|
|
3236
|
+
onNotice?.({ kind: "chart-edge-dropped", actor: doc.flow[0]?.from ?? "", line: doc.flow[0]?.pos?.line ?? 0, message: m2 });
|
|
3237
|
+
if (typeof console !== "undefined" && console.warn) console.warn(`[dragon] ${m2}`);
|
|
3238
|
+
}
|
|
3239
|
+
b.node(`${slugify(doc.title)}-chart`, {
|
|
3240
|
+
lane: "chart",
|
|
3241
|
+
stack: 0,
|
|
3242
|
+
kind: "quadrant-matrix",
|
|
3243
|
+
title: doc.title,
|
|
3244
|
+
...\u56F3\u306E\u5C0F\u898B\u51FA\u3057(doc),
|
|
3245
|
+
w: W,
|
|
3246
|
+
h: H,
|
|
3247
|
+
quadrantData: { ...\u8EF8\u3068\u533A\u753B\u306E\u540D\u524D(doc), items }
|
|
3248
|
+
});
|
|
3249
|
+
return b.build();
|
|
3250
|
+
}
|
|
2028
3251
|
function \u6BB5\u3092\u8AAD\u307F\u53D6\u308B(subtitle) {
|
|
2029
3252
|
const \u5143 = (subtitle ?? "").trim();
|
|
2030
3253
|
const m = \u5143.match(/^L([123])(?![0-9A-Za-z])/i);
|
|
@@ -2076,74 +3299,196 @@ function compileC4(doc) {
|
|
|
2076
3299
|
}
|
|
2077
3300
|
return b.build();
|
|
2078
3301
|
}
|
|
2079
|
-
|
|
3302
|
+
var \u653E\u5C04\u3067\u63CF\u3051\u306A\u3044\u6B04\u306E\u540D\u524D = {
|
|
3303
|
+
kind: "\u7A2E\u985E",
|
|
3304
|
+
eyebrow: "\u4E0A\u306E\u5C0F\u898B\u51FA\u3057",
|
|
3305
|
+
touchpoint: "\u5834\u6240 (\u4F53\u9A13\u306E\u9053\u7B4B\u306E\u6B04)",
|
|
3306
|
+
opportunity: "\u6539\u5584\u306E\u4F59\u5730 (\u4F53\u9A13\u306E\u9053\u7B4B\u306E\u6B04)",
|
|
3307
|
+
owner: "\u62C5\u5F53 (\u5DE5\u7A0B\u306E\u4E26\u3073\u306E\u6B04)",
|
|
3308
|
+
end: "\u7D42\u308F\u308B\u6642\u671F (\u5DE5\u7A0B\u306E\u4E26\u3073\u306E\u6B04)",
|
|
3309
|
+
rows: "\u884C",
|
|
3310
|
+
lane: "\u67A0\u306E\u6307\u5B9A",
|
|
3311
|
+
stack: "\u7A4D\u3080\u9806",
|
|
3312
|
+
initial: "\u59CB\u307E\u308A / \u7D42\u308F\u308A \u306E\u5370",
|
|
3313
|
+
final: "\u59CB\u307E\u308A / \u7D42\u308F\u308A \u306E\u5370",
|
|
3314
|
+
colorHex: "\u8272\u756A\u53F7",
|
|
3315
|
+
stateOverride: "\u72B6\u614B\u306E\u4E0A\u66F8\u304D",
|
|
3316
|
+
// 位置は「登場人物ごとの箱をどこに置くか」 の指定で、 箱が 1 つの図では置く先が無い
|
|
3317
|
+
posX: "\u4F4D\u7F6E (\u5EA7\u6A19)",
|
|
3318
|
+
posY: "\u4F4D\u7F6E (\u5EA7\u6A19)",
|
|
3319
|
+
posW: "\u5927\u304D\u3055",
|
|
3320
|
+
posH: "\u5927\u304D\u3055",
|
|
3321
|
+
scale: "\u500D\u7387",
|
|
3322
|
+
scaleKeys: "\u500D\u7387",
|
|
3323
|
+
posRel: "\u4F4D\u7F6E (\u76F8\u5BFE)",
|
|
3324
|
+
nodes: "\u4E2D\u306E\u7BB1\u3054\u3068\u306E\u6307\u5B9A",
|
|
3325
|
+
layoutPos: "\u914D\u7F6E\u306E\u305A\u3089\u3057"
|
|
3326
|
+
};
|
|
3327
|
+
function \u653E\u5C04\u3067\u63CF\u3051\u306A\u3044\u6B04\u3092\u66F8\u3044\u305F\u304B(a, \u6B04) {
|
|
3328
|
+
if (\u6B04 === "kind") return a.kindWritten === true;
|
|
3329
|
+
const v = a[\u6B04];
|
|
3330
|
+
if (typeof v === "boolean") return v;
|
|
3331
|
+
return v !== void 0;
|
|
3332
|
+
}
|
|
3333
|
+
function \u653E\u5C04\u306B\u51FA\u3059\u6587\u5B57(a) {
|
|
3334
|
+
const \u7D9A\u304D = [a.subtitle, a.value].map((x) => x?.trim()).filter((x) => !!x);
|
|
3335
|
+
return \u7D9A\u304D.length > 0 ? `${a.name} ${\u7D9A\u304D.join(" ")}` : a.name;
|
|
3336
|
+
}
|
|
3337
|
+
function compileMind(doc, onNotice) {
|
|
2080
3338
|
const b = cdl.diagram(slugify(doc.title), { topic: doc.title });
|
|
2081
|
-
const
|
|
2082
|
-
const
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
const \
|
|
2087
|
-
const
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
3339
|
+
const { w: W, h: H } = \u56F3\u8868\u306E\u5927\u304D\u3055.mind;
|
|
3340
|
+
const \u4F1D\u3048\u308B = (kind, \u540D, message, line = 0) => {
|
|
3341
|
+
onNotice?.({ kind, actor: \u540D, line, message });
|
|
3342
|
+
if (typeof console !== "undefined" && console.warn) console.warn(`[dragon] ${message}`);
|
|
3343
|
+
};
|
|
3344
|
+
const \u898B\u672C\u3067\u306A\u3044 = [];
|
|
3345
|
+
for (const a of doc.actors) {
|
|
3346
|
+
if (a.partId !== void 0) {
|
|
3347
|
+
\u4F1D\u3048\u308B(
|
|
3348
|
+
"part-not-drawn",
|
|
3349
|
+
a.name,
|
|
3350
|
+
`type: mind \u3067\u306F\u898B\u672C (${a.partId}) \u3092\u4E2D\u5FC3\u306B\u3082\u679D\u306B\u3082\u3067\u304D\u307E\u305B\u3093\u3002 \u898B\u672C\u306F\u305D\u306E\u307E\u307E\u63CF\u304D\u3001 \u653E\u5C04\u306B\u306F\u8F09\u305B\u307E\u305B\u3093`,
|
|
3351
|
+
a.pos?.line ?? 0
|
|
3352
|
+
);
|
|
3353
|
+
continue;
|
|
3354
|
+
}
|
|
3355
|
+
\u898B\u672C\u3067\u306A\u3044.push(a);
|
|
3356
|
+
}
|
|
3357
|
+
const \u679D\u306E\u540D\u524D = new Set(\u898B\u672C\u3067\u306A\u3044.map((a) => slugify(a.name)));
|
|
3358
|
+
const \u89AA = \u77E2\u5370\u304B\u3089\u89AA\u3092\u6C7A\u3081\u308B(
|
|
3359
|
+
doc,
|
|
3360
|
+
"mind",
|
|
3361
|
+
\u679D\u306E\u540D\u524D,
|
|
3362
|
+
(\u540D, message, line) => (
|
|
3363
|
+
// 親にできなかった矢印は描かれない。 知らせの種別も「矢印を落とした」 にする
|
|
3364
|
+
\u4F1D\u3048\u308B("chart-edge-dropped", \u540D, message, line ?? 0)
|
|
3365
|
+
)
|
|
3366
|
+
);
|
|
3367
|
+
if (\u898B\u672C\u3067\u306A\u3044.length === 0) return b.build();
|
|
3368
|
+
b.lane("chart", { width: W + 64 });
|
|
3369
|
+
const slug\u5225 = /* @__PURE__ */ new Map();
|
|
3370
|
+
for (const a of \u898B\u672C\u3067\u306A\u3044) {
|
|
3371
|
+
const k = slugify(a.name);
|
|
3372
|
+
slug\u5225.set(k, [...slug\u5225.get(k) ?? [], a.name]);
|
|
3373
|
+
}
|
|
3374
|
+
for (const [k, \u7FA4] of slug\u5225) {
|
|
3375
|
+
if (\u7FA4.length > 1) {
|
|
3376
|
+
\u4F1D\u3048\u308B(
|
|
3377
|
+
"chart-value-unreadable",
|
|
3378
|
+
\u7FA4[0],
|
|
3379
|
+
`type: mind \u3067 ${\u7FA4.join(" / ")} \u304C\u540C\u3058 id (${k}) \u306B\u306A\u308A\u307E\u3059\u3002 \u540D\u524D\u3092\u5909\u3048\u3066\u304F\u3060\u3055\u3044`
|
|
3380
|
+
);
|
|
3381
|
+
}
|
|
2099
3382
|
}
|
|
2100
|
-
const root =
|
|
3383
|
+
const root = \u898B\u672C\u3067\u306A\u3044[0];
|
|
2101
3384
|
const rootId = slugify(root.name);
|
|
2102
|
-
const
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
}
|
|
2111
|
-
const
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
3385
|
+
for (const f of doc.flow) {
|
|
3386
|
+
if (slugify(f.to) !== rootId) continue;
|
|
3387
|
+
\u4F1D\u3048\u308B(
|
|
3388
|
+
"chart-edge-dropped",
|
|
3389
|
+
f.to,
|
|
3390
|
+
`type: mind \u3067\u4E2D\u5FC3 (${truncateForMessage(f.to)}) \u3092\u5B50\u306B\u306F\u3067\u304D\u307E\u305B\u3093 (${truncateForMessage(f.from)} -> ${truncateForMessage(f.to)} \u3092\u4F7F\u3044\u307E\u305B\u3093)\u3002 \u4E2D\u5FC3\u306F\u653E\u5C04\u306E\u771F\u3093\u4E2D\u306B\u7F6E\u304F 1 \u3064\u3060\u3051\u3067\u3059`,
|
|
3391
|
+
f.pos?.line ?? 0
|
|
3392
|
+
);
|
|
3393
|
+
}
|
|
3394
|
+
const \u63CF\u3051\u306A\u3044\u6B04 = (a) => {
|
|
3395
|
+
const out = [];
|
|
3396
|
+
for (const \u6B04 of Object.keys(\u653E\u5C04\u3067\u63CF\u3051\u306A\u3044\u6B04\u306E\u540D\u524D)) {
|
|
3397
|
+
if (!\u653E\u5C04\u3067\u63CF\u3051\u306A\u3044\u6B04\u3092\u66F8\u3044\u305F\u304B(a, \u6B04)) continue;
|
|
3398
|
+
const \u540D\u524D = \u653E\u5C04\u3067\u63CF\u3051\u306A\u3044\u6B04\u306E\u540D\u524D[\u6B04];
|
|
3399
|
+
if (!out.includes(\u540D\u524D)) out.push(\u540D\u524D);
|
|
3400
|
+
}
|
|
3401
|
+
return out;
|
|
3402
|
+
};
|
|
3403
|
+
const \u6D88\u3048\u305F\u6B04 = /* @__PURE__ */ new Map();
|
|
3404
|
+
const \u8A18\u9332\u3059\u308B = (a) => {
|
|
3405
|
+
const \u6B04 = \u63CF\u3051\u306A\u3044\u6B04(a);
|
|
3406
|
+
if (\u6B04.length > 0) \u6D88\u3048\u305F\u6B04.set(a.name, \u6B04);
|
|
3407
|
+
};
|
|
3408
|
+
const branches = [];
|
|
3409
|
+
const \u4F7F\u3063\u305F = /* @__PURE__ */ new Set([rootId]);
|
|
3410
|
+
\u8A18\u9332\u3059\u308B(root);
|
|
3411
|
+
if (root.tone) \u6D88\u3048\u305F\u6B04.set(root.name, [...\u6D88\u3048\u305F\u6B04.get(root.name) ?? [], "\u8272 (\u4E2D\u5FC3\u306F\u6301\u3066\u306A\u3044)"]);
|
|
3412
|
+
\u898B\u672C\u3067\u306A\u3044.slice(1).forEach((a, i) => {
|
|
3413
|
+
const id = slugify(a.name);
|
|
3414
|
+
if (\u4F7F\u3063\u305F.has(id)) {
|
|
3415
|
+
\u4F1D\u3048\u308B(
|
|
3416
|
+
"chart-value-unreadable",
|
|
3417
|
+
a.name,
|
|
3418
|
+
`type: mind \u3067 ${a.name} \u304C\u65E2\u306B\u3042\u308B id (${id}) \u3068\u91CD\u306A\u308A\u307E\u3059 (\u679D\u306B\u8F09\u305B\u307E\u305B\u3093)`,
|
|
3419
|
+
a.pos?.line ?? 0
|
|
3420
|
+
);
|
|
3421
|
+
return;
|
|
3422
|
+
}
|
|
3423
|
+
\u4F7F\u3063\u305F.add(id);
|
|
3424
|
+
\u8A18\u9332\u3059\u308B(a);
|
|
3425
|
+
branches.push({
|
|
3426
|
+
id,
|
|
3427
|
+
title: \u653E\u5C04\u306B\u51FA\u3059\u6587\u5B57(a),
|
|
3428
|
+
parent: \u89AA.get(id) ?? rootId,
|
|
3429
|
+
...a.tone ? { tone: a.tone } : {}
|
|
2124
3430
|
});
|
|
2125
|
-
counter.v += 1;
|
|
2126
3431
|
});
|
|
2127
|
-
if (
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
const fromId = slugify(s.from);
|
|
2135
|
-
const toId = slugify(s.to);
|
|
2136
|
-
b.edge(fromId, toId, {
|
|
2137
|
-
label: s.label,
|
|
2138
|
-
...s.sub ? { sub: s.sub } : {},
|
|
2139
|
-
...s.tone ? { tone: s.tone } : {},
|
|
2140
|
-
...s.style ? { style: s.style } : {}
|
|
2141
|
-
});
|
|
2142
|
-
}
|
|
3432
|
+
if (\u6D88\u3048\u305F\u6B04.size > 0) {
|
|
3433
|
+
const \u4E00\u89A7 = [...\u6D88\u3048\u305F\u6B04].map(([\u540D, \u6B04]) => `${\u540D} \u306E${\u6B04.join(" / ")}`).join("\u3001 ");
|
|
3434
|
+
\u4F1D\u3048\u308B(
|
|
3435
|
+
"chart-value-unreadable",
|
|
3436
|
+
[...\u6D88\u3048\u305F\u6B04.keys()][0],
|
|
3437
|
+
`type: mind \u306F\u540D\u524D\u3068\u526F\u984C / \u5024\u3001 \u679D\u306E\u8272\u3057\u304B\u63CF\u3051\u307E\u305B\u3093 (\u63CF\u304B\u306A\u3044\u6B04: ${\u4E00\u89A7})\u3002 \u3053\u308C\u3089\u3092\u63CF\u304F\u306A\u3089 type: tree \u304B type: flow \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044`
|
|
3438
|
+
);
|
|
2143
3439
|
}
|
|
3440
|
+
b.node(`${slugify(doc.title)}-chart`, {
|
|
3441
|
+
lane: "chart",
|
|
3442
|
+
stack: 0,
|
|
3443
|
+
kind: "mind-map",
|
|
3444
|
+
title: doc.title,
|
|
3445
|
+
...\u56F3\u306E\u5C0F\u898B\u51FA\u3057(doc),
|
|
3446
|
+
w: W,
|
|
3447
|
+
h: H,
|
|
3448
|
+
mindData: { rootId, rootTitle: \u653E\u5C04\u306B\u51FA\u3059\u6587\u5B57(root), branches }
|
|
3449
|
+
});
|
|
2144
3450
|
return b.build();
|
|
2145
3451
|
}
|
|
2146
|
-
function
|
|
3452
|
+
function mergeDuplicateDeclaredLanes(diagram2, \u8FFD\u52A0\u3057\u305F\u7E26\u5217) {
|
|
3453
|
+
for (const \u5BA3\u8A00 of \u8FFD\u52A0\u3057\u305F\u7E26\u5217) {
|
|
3454
|
+
const { id } = \u5BA3\u8A00;
|
|
3455
|
+
const \u540C\u4E00id\u306E\u7E26\u5217 = diagram2.lanes.filter((l) => l.id === id);
|
|
3456
|
+
if (\u540C\u4E00id\u306E\u7E26\u5217.length < 2) continue;
|
|
3457
|
+
const \u6B8B\u3059 = \u540C\u4E00id\u306E\u7E26\u5217.at(-1);
|
|
3458
|
+
if (\u6B8B\u3059 === void 0) continue;
|
|
3459
|
+
const \u5143\u306E\u4E2D\u5FC3X = (\u6B8B\u3059.x ?? 0) + \u6B8B\u3059.width / 2;
|
|
3460
|
+
if (\u5BA3\u8A00.x !== void 0) \u6B8B\u3059.x = \u5BA3\u8A00.x;
|
|
3461
|
+
if (\u5BA3\u8A00.width !== void 0) \u6B8B\u3059.width = \u5BA3\u8A00.width;
|
|
3462
|
+
if (\u5BA3\u8A00.label !== void 0) \u6B8B\u3059.label = \u5BA3\u8A00.label;
|
|
3463
|
+
if (\u5BA3\u8A00.contain !== void 0) \u6B8B\u3059.contain = \u5BA3\u8A00.contain;
|
|
3464
|
+
if (\u5BA3\u8A00.lifeline !== void 0) \u6B8B\u3059.lifeline = \u5BA3\u8A00.lifeline;
|
|
3465
|
+
const \u79FB\u52D5X = (\u6B8B\u3059.x ?? 0) + \u6B8B\u3059.width / 2 - \u5143\u306E\u4E2D\u5FC3X;
|
|
3466
|
+
for (const node of diagram2.nodes) {
|
|
3467
|
+
if (node.lane === id && node.posX !== void 0) node.posX += \u79FB\u52D5X;
|
|
3468
|
+
}
|
|
3469
|
+
for (let i = diagram2.lanes.length - 1; i >= 0; i -= 1) {
|
|
3470
|
+
if (diagram2.lanes[i]?.id === id && diagram2.lanes[i] !== \u6B8B\u3059) diagram2.lanes.splice(i, 1);
|
|
3471
|
+
}
|
|
3472
|
+
}
|
|
3473
|
+
}
|
|
3474
|
+
function reportEmptyDeclaredLanes(diagram2, \u8FFD\u52A0\u3057\u305F\u7E26\u5217, onNotice) {
|
|
3475
|
+
if (\u8FFD\u52A0\u3057\u305F\u7E26\u5217.length === 0) return;
|
|
3476
|
+
mergeDuplicateDeclaredLanes(diagram2, \u8FFD\u52A0\u3057\u305F\u7E26\u5217);
|
|
3477
|
+
if (!onNotice) return;
|
|
3478
|
+
const \u4F7F\u308F\u308C\u3066\u3044\u308B = new Set(diagram2.nodes.map((n) => n.lane));
|
|
3479
|
+
const \u3042\u308B\u7E26\u5217 = diagram2.lanes.map((l) => l.id).filter((x) => \u4F7F\u308F\u308C\u3066\u3044\u308B.has(x));
|
|
3480
|
+
for (const { id, pos } of \u8FFD\u52A0\u3057\u305F\u7E26\u5217) {
|
|
3481
|
+
if (\u4F7F\u308F\u308C\u3066\u3044\u308B.has(id)) continue;
|
|
3482
|
+
onNotice({
|
|
3483
|
+
kind: "lane-declared-empty",
|
|
3484
|
+
actor: id,
|
|
3485
|
+
line: pos?.line ?? 0,
|
|
3486
|
+
message: `lanes \u306B\u66F8\u3044\u305F ${truncateForMessage(id)} \u306F\u3069\u306E\u7BB1\u3082\u5165\u3089\u306A\u3044\u7E26\u5217\u3067\u3059 (\u65B0\u3057\u304F\u4F5C\u308A\u307E\u3057\u305F)`,
|
|
3487
|
+
hint: \u3042\u308B\u7E26\u5217.length > 0 ? `\u3053\u306E\u56F3\u304C\u6301\u3064\u7E26\u5217 = ${\u3042\u308B\u7E26\u5217.join(" / ")}` : "\u3053\u306E\u56F3\u306F\u7BB1\u306E\u5165\u3063\u305F\u7E26\u5217\u3092\u6301\u3061\u307E\u305B\u3093"
|
|
3488
|
+
});
|
|
3489
|
+
}
|
|
3490
|
+
}
|
|
3491
|
+
function applyV05Extensions(diagram2, doc, \u8FFD\u52A0\u3057\u305F\u7E26\u5217out) {
|
|
2147
3492
|
const isSeqLike = doc.type === "sequence" || doc.type === "solidity";
|
|
2148
3493
|
for (const a of doc.actors) {
|
|
2149
3494
|
const dragonSlug = slugify(a.name);
|
|
@@ -2162,6 +3507,10 @@ function applyV05Extensions(diagram2, doc) {
|
|
|
2162
3507
|
if (a.eyebrow !== void 0) node.eyebrow = a.eyebrow;
|
|
2163
3508
|
if (a.value !== void 0) node.value = a.value;
|
|
2164
3509
|
if (a.rows !== void 0) node.rows = a.rows;
|
|
3510
|
+
if (!isSeqLike) {
|
|
3511
|
+
if (a.posW !== void 0) node.w = a.posW;
|
|
3512
|
+
if (a.posH !== void 0) node.h = a.posH;
|
|
3513
|
+
}
|
|
2165
3514
|
const drawn = isSeqLike && a.kindWritten !== false ? drawableKind(a.kind) : void 0;
|
|
2166
3515
|
if (drawn !== void 0) {
|
|
2167
3516
|
node.kind = drawn;
|
|
@@ -2185,6 +3534,7 @@ function applyV05Extensions(diagram2, doc) {
|
|
|
2185
3534
|
if (doc.animate && doc.animate.phases.length > 0 && diagram2.phases.length === 0) {
|
|
2186
3535
|
injectPhasesFallback(diagram2, doc);
|
|
2187
3536
|
}
|
|
3537
|
+
const \u8FFD\u52A0\u3057\u305F\u7E26\u5217 = \u8FFD\u52A0\u3057\u305F\u7E26\u5217out ?? [];
|
|
2188
3538
|
if (doc.lanes) {
|
|
2189
3539
|
for (const [id, laneOpt] of Object.entries(doc.lanes)) {
|
|
2190
3540
|
const lane = diagram2.lanes.find((l) => l.id === id);
|
|
@@ -2203,6 +3553,7 @@ function applyV05Extensions(diagram2, doc) {
|
|
|
2203
3553
|
contain: laneOpt.contain,
|
|
2204
3554
|
lifeline: laneOpt.lifeline
|
|
2205
3555
|
});
|
|
3556
|
+
\u8FFD\u52A0\u3057\u305F\u7E26\u5217.push(laneOpt);
|
|
2206
3557
|
}
|
|
2207
3558
|
}
|
|
2208
3559
|
}
|
|
@@ -2323,8 +3674,9 @@ function compileSequenceWithAnimate(doc) {
|
|
|
2323
3674
|
b.node(spacerId, { lane: id, stack: 1, kind: "card", title: "", w: 2, h: 40 });
|
|
2324
3675
|
});
|
|
2325
3676
|
doc.flow.forEach((s, idx) => {
|
|
2326
|
-
const fromLaneId = actorIds.get(s.from)
|
|
2327
|
-
const toLaneId = actorIds.get(s.to)
|
|
3677
|
+
const fromLaneId = actorIds.get(s.from);
|
|
3678
|
+
const toLaneId = actorIds.get(s.to);
|
|
3679
|
+
if (fromLaneId === void 0 || toLaneId === void 0) return;
|
|
2328
3680
|
const stack = idx + 2;
|
|
2329
3681
|
const fromBoxId = `s${idx}-${fromLaneId}`;
|
|
2330
3682
|
const toBoxId = `s${idx}-${toLaneId}`;
|
|
@@ -2338,11 +3690,7 @@ function compileSequenceWithAnimate(doc) {
|
|
|
2338
3690
|
label: s.label,
|
|
2339
3691
|
...s.sub ? { sub: s.sub } : {},
|
|
2340
3692
|
...s.tone ? { tone: s.tone } : {},
|
|
2341
|
-
...s.style ? { style: s.style } : {}
|
|
2342
|
-
...s.guard ? { guard: s.guard } : {},
|
|
2343
|
-
...s.cardinality ? { cardinality: s.cardinality } : {},
|
|
2344
|
-
...s.labelOffsetX !== void 0 ? { labelOffsetX: s.labelOffsetX } : {},
|
|
2345
|
-
...s.labelOffsetY !== void 0 ? { labelOffsetY: s.labelOffsetY } : {}
|
|
3693
|
+
...s.style ? { style: s.style } : {}
|
|
2346
3694
|
});
|
|
2347
3695
|
});
|
|
2348
3696
|
const footerStack = doc.flow.length + 2;
|
|
@@ -2350,12 +3698,20 @@ function compileSequenceWithAnimate(doc) {
|
|
|
2350
3698
|
const laneId = actorIds.get(a.name) ?? slugify(a.name);
|
|
2351
3699
|
const footerId = `${laneId}-footer`;
|
|
2352
3700
|
const actorW = Math.max(140, a.name.length * 22 + 52);
|
|
2353
|
-
b.node(footerId, {
|
|
3701
|
+
b.node(footerId, {
|
|
3702
|
+
lane: laneId,
|
|
3703
|
+
stack: footerStack,
|
|
3704
|
+
kind: "card",
|
|
3705
|
+
title: a.name,
|
|
3706
|
+
w: actorW,
|
|
3707
|
+
h: 72,
|
|
3708
|
+
role: "lifeline-footer"
|
|
3709
|
+
});
|
|
2354
3710
|
});
|
|
2355
|
-
for (const st of doc.animate
|
|
3711
|
+
for (const st of doc.animate?.states ?? []) {
|
|
2356
3712
|
b.state(st.name, { initial: st.initial });
|
|
2357
3713
|
}
|
|
2358
|
-
for (const p of doc.animate
|
|
3714
|
+
for (const p of doc.animate?.phases ?? []) {
|
|
2359
3715
|
b.phase(
|
|
2360
3716
|
slugify(p.name),
|
|
2361
3717
|
{
|
|
@@ -2434,7 +3790,7 @@ function slugLookup(byName, wanted) {
|
|
|
2434
3790
|
return hit;
|
|
2435
3791
|
}
|
|
2436
3792
|
function compileFlow(doc) {
|
|
2437
|
-
if (doc.animate && doc.animate.phases.length > 0) {
|
|
3793
|
+
if (doc.animate && doc.animate.phases.length > 0 || \u66F8\u3044\u305F\u7E26\u5217\u306B\u7F6E\u304F("flow", doc)) {
|
|
2438
3794
|
return compileGenericWithAnimate(doc, { kind: "flow", laneId: "main", laneWidth: 400 });
|
|
2439
3795
|
}
|
|
2440
3796
|
if (doc.actors.length === 0) {
|
|
@@ -2460,7 +3816,7 @@ function compileFlow(doc) {
|
|
|
2460
3816
|
return flowBuilder.build();
|
|
2461
3817
|
}
|
|
2462
3818
|
function compileSwimlane(doc) {
|
|
2463
|
-
if (doc.animate && doc.animate.phases.length > 0) {
|
|
3819
|
+
if (doc.animate && doc.animate.phases.length > 0 || \u66F8\u3044\u305F\u7E26\u5217\u306B\u7F6E\u304F("swimlane", doc)) {
|
|
2464
3820
|
return compileGenericWithAnimate(doc, { kind: "swimlane", laneWidth: 400 });
|
|
2465
3821
|
}
|
|
2466
3822
|
const swim = cdl.swimlane({
|
|
@@ -2494,11 +3850,17 @@ function compileSwimlane(doc) {
|
|
|
2494
3850
|
label: s.label,
|
|
2495
3851
|
...s.sub ? { sub: s.sub } : {},
|
|
2496
3852
|
...s.tone ? { tone: s.tone } : {},
|
|
2497
|
-
...s.style ? { style: s.style } : {}
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
3853
|
+
...s.style ? { style: s.style } : {}
|
|
3854
|
+
});
|
|
3855
|
+
}
|
|
3856
|
+
if (placedNodes.size === 0) {
|
|
3857
|
+
doc.actors.forEach((a, i) => {
|
|
3858
|
+
swim.node(slugify(a.name), {
|
|
3859
|
+
lane: swim.laneId(a.name),
|
|
3860
|
+
stack: 0,
|
|
3861
|
+
kind: a.kind ?? "actor",
|
|
3862
|
+
title: a.name
|
|
3863
|
+
});
|
|
2502
3864
|
});
|
|
2503
3865
|
}
|
|
2504
3866
|
return swim.build();
|
|
@@ -2530,6 +3892,14 @@ function compileEr(doc) {
|
|
|
2530
3892
|
}
|
|
2531
3893
|
return erBuilder.build();
|
|
2532
3894
|
}
|
|
3895
|
+
function \u59CB\u307E\u308A\u3068\u7D42\u308F\u308A\u306E\u6C7A\u3081\u65B9(doc) {
|
|
3896
|
+
const \u66F8\u3044\u305F\u59CB\u307E\u308A = doc.actors.some((a) => a.initial === true);
|
|
3897
|
+
const \u66F8\u3044\u305F\u7D42\u308F\u308A = doc.actors.some((a) => a.final === true);
|
|
3898
|
+
return {
|
|
3899
|
+
\u59CB\u307E\u308A: (a, idx) => \u66F8\u3044\u305F\u59CB\u307E\u308A ? a.initial === true : idx === 0,
|
|
3900
|
+
\u7D42\u308F\u308A: (a, idx) => \u66F8\u3044\u305F\u7D42\u308F\u308A ? a.final === true : idx === doc.actors.length - 1 && doc.actors.length > 1
|
|
3901
|
+
};
|
|
3902
|
+
}
|
|
2533
3903
|
function compileState(doc) {
|
|
2534
3904
|
if (doc.animate && doc.animate.phases.length > 0) {
|
|
2535
3905
|
return compileGenericWithAnimate(doc, { kind: "state", laneWidth: 360 });
|
|
@@ -2538,10 +3908,11 @@ function compileState(doc) {
|
|
|
2538
3908
|
id: slugify(doc.title),
|
|
2539
3909
|
topic: doc.title
|
|
2540
3910
|
});
|
|
3911
|
+
const \u6C7A\u3081\u65B9 = \u59CB\u307E\u308A\u3068\u7D42\u308F\u308A\u306E\u6C7A\u3081\u65B9(doc);
|
|
2541
3912
|
for (let i = 0; i < doc.actors.length; i++) {
|
|
2542
3913
|
const a = doc.actors[i];
|
|
2543
|
-
const initial = i
|
|
2544
|
-
const final = i
|
|
3914
|
+
const initial = \u6C7A\u3081\u65B9.\u59CB\u307E\u308A(a, i);
|
|
3915
|
+
const final = \u6C7A\u3081\u65B9.\u7D42\u308F\u308A(a, i);
|
|
2545
3916
|
fsm.state({
|
|
2546
3917
|
id: slugify(a.name),
|
|
2547
3918
|
title: a.name,
|
|
@@ -2561,7 +3932,7 @@ function compileState(doc) {
|
|
|
2561
3932
|
return fsm.build();
|
|
2562
3933
|
}
|
|
2563
3934
|
function compileTopology(doc) {
|
|
2564
|
-
if (doc.animate && doc.animate.phases.length > 0) {
|
|
3935
|
+
if (doc.animate && doc.animate.phases.length > 0 || \u66F8\u3044\u305F\u7E26\u5217\u306B\u7F6E\u304F("topology", doc)) {
|
|
2565
3936
|
return compileGenericWithAnimate(doc, { kind: "topology", laneWidth: 460 });
|
|
2566
3937
|
}
|
|
2567
3938
|
if (doc.actors.length === 0) {
|
|
@@ -2590,11 +3961,42 @@ function compileTopology(doc) {
|
|
|
2590
3961
|
}
|
|
2591
3962
|
return topo.build();
|
|
2592
3963
|
}
|
|
3964
|
+
function \u5F8C\u308D\u3078\u623B\u308B\u77E2\u5370\u304B(kind, fromId, toId, \u7BB1\u306E\u4E26\u3073) {
|
|
3965
|
+
if (kind !== "state") return false;
|
|
3966
|
+
const \u5143 = \u7BB1\u306E\u4E26\u3073.get(fromId);
|
|
3967
|
+
const \u5148 = \u7BB1\u306E\u4E26\u3073.get(toId);
|
|
3968
|
+
if (\u5143 === void 0 || \u5148 === void 0) return false;
|
|
3969
|
+
return \u5148 < \u5143;
|
|
3970
|
+
}
|
|
3971
|
+
var \u7E26\u5217\u3092\u9078\u3079\u308B\u56F3\u7A2E = /* @__PURE__ */ new Set(["flow", "topology", "swimlane"]);
|
|
3972
|
+
function \u66F8\u3044\u305F\u7E26\u5217\u306B\u7F6E\u304F(kind, doc) {
|
|
3973
|
+
if (!\u7E26\u5217\u3092\u9078\u3079\u308B\u56F3\u7A2E.has(kind)) return false;
|
|
3974
|
+
const \u5BFE\u8C61 = doc.actors.filter((a) => a.partId === void 0);
|
|
3975
|
+
return \u5BFE\u8C61.length > 0 && \u5BFE\u8C61.every((a) => a.lane !== void 0);
|
|
3976
|
+
}
|
|
2593
3977
|
function compileGenericWithAnimate(doc, opts) {
|
|
2594
3978
|
const b = cdl.diagram(slugify(doc.title), { topic: doc.title });
|
|
2595
3979
|
const { kind, laneWidth } = opts;
|
|
2596
3980
|
const actorToNodeId = /* @__PURE__ */ new Map();
|
|
2597
|
-
if (kind
|
|
3981
|
+
if (\u66F8\u3044\u305F\u7E26\u5217\u306B\u7F6E\u304F(kind, doc)) {
|
|
3982
|
+
const \u4E26\u3073 = [];
|
|
3983
|
+
for (const a of doc.actors) {
|
|
3984
|
+
const lid = a.lane;
|
|
3985
|
+
if (lid !== void 0 && !\u4E26\u3073.includes(lid)) \u4E26\u3073.push(lid);
|
|
3986
|
+
}
|
|
3987
|
+
for (const lid of \u4E26\u3073) {
|
|
3988
|
+
b.lane(lid, { width: laneWidth, ...kind === "topology" ? { contain: true } : {} });
|
|
3989
|
+
}
|
|
3990
|
+
const \u7A4D\u3093\u3060\u6570 = /* @__PURE__ */ new Map();
|
|
3991
|
+
doc.actors.forEach((a, idx) => {
|
|
3992
|
+
const id = slugify(a.name);
|
|
3993
|
+
actorToNodeId.set(a.name, id);
|
|
3994
|
+
const lid = a.lane;
|
|
3995
|
+
const stack = \u7A4D\u3093\u3060\u6570.get(lid) ?? 0;
|
|
3996
|
+
\u7A4D\u3093\u3060\u6570.set(lid, stack + 1);
|
|
3997
|
+
b.node(id, { lane: lid, stack, kind: a.kind, title: a.name });
|
|
3998
|
+
});
|
|
3999
|
+
} else if (kind === "flow" || kind === "topology") {
|
|
2598
4000
|
const lid = opts.laneId ?? "main";
|
|
2599
4001
|
b.lane(lid, { width: laneWidth, label: doc.title, ...kind === "topology" ? { contain: true } : {} });
|
|
2600
4002
|
doc.actors.forEach((a, idx) => {
|
|
@@ -2603,13 +4005,15 @@ function compileGenericWithAnimate(doc, opts) {
|
|
|
2603
4005
|
b.node(id, { lane: lid, stack: idx, kind: a.kind, title: a.name });
|
|
2604
4006
|
});
|
|
2605
4007
|
} else {
|
|
4008
|
+
const \u898B\u51FA\u3057\u3092\u4ED8\u3051\u308B = kind === "swimlane";
|
|
4009
|
+
const \u6C7A\u3081\u65B92 = \u59CB\u307E\u308A\u3068\u7D42\u308F\u308A\u306E\u6C7A\u3081\u65B9(doc);
|
|
2606
4010
|
doc.actors.forEach((a, idx) => {
|
|
2607
4011
|
const lid = `lane-${slugify(a.name)}`;
|
|
2608
|
-
b.lane(lid, { width: laneWidth, label: a.name });
|
|
4012
|
+
b.lane(lid, { width: laneWidth, ...\u898B\u51FA\u3057\u3092\u4ED8\u3051\u308B ? { label: a.name } : {} });
|
|
2609
4013
|
const id = slugify(a.name);
|
|
2610
4014
|
actorToNodeId.set(a.name, id);
|
|
2611
|
-
const isInitial = kind === "state" && idx
|
|
2612
|
-
const isFinal = kind === "state" && idx
|
|
4015
|
+
const isInitial = kind === "state" && \u6C7A\u3081\u65B92.\u59CB\u307E\u308A(a, idx);
|
|
4016
|
+
const isFinal = kind === "state" && \u6C7A\u3081\u65B92.\u7D42\u308F\u308A(a, idx);
|
|
2613
4017
|
b.node(id, {
|
|
2614
4018
|
lane: lid,
|
|
2615
4019
|
stack: 0,
|
|
@@ -2620,29 +4024,28 @@ function compileGenericWithAnimate(doc, opts) {
|
|
|
2620
4024
|
});
|
|
2621
4025
|
});
|
|
2622
4026
|
}
|
|
4027
|
+
const \u7BB1\u306E\u4E26\u3073 = new Map([...actorToNodeId.values()].map((id, i) => [id, i]));
|
|
2623
4028
|
const edgeIds = [];
|
|
2624
4029
|
doc.flow.forEach((s, idx) => {
|
|
2625
|
-
const fromId = actorToNodeId.get(s.from)
|
|
2626
|
-
const toId = actorToNodeId.get(s.to)
|
|
4030
|
+
const fromId = actorToNodeId.get(s.from);
|
|
4031
|
+
const toId = actorToNodeId.get(s.to);
|
|
4032
|
+
if (fromId === void 0 || toId === void 0) return;
|
|
2627
4033
|
const edgeId = `e${idx}-${fromId}-${toId}`;
|
|
2628
4034
|
const labelWithCard = kind === "er" && s.cardinality && !s.label.includes(s.cardinality) ? s.label ? `${s.label} (${s.cardinality})` : `(${s.cardinality})` : s.label;
|
|
2629
4035
|
b.edge(fromId, toId, {
|
|
2630
4036
|
id: edgeId,
|
|
2631
4037
|
label: labelWithCard,
|
|
4038
|
+
...\u5F8C\u308D\u3078\u623B\u308B\u77E2\u5370\u304B(kind, fromId, toId, \u7BB1\u306E\u4E26\u3073) ? { routing: "back-detour" } : {},
|
|
2632
4039
|
...s.sub ? { sub: s.sub } : {},
|
|
2633
4040
|
...s.tone ? { tone: s.tone } : {},
|
|
2634
|
-
...s.style ? { style: s.style } : {}
|
|
2635
|
-
...s.guard ? { guard: s.guard } : {},
|
|
2636
|
-
...s.cardinality ? { cardinality: s.cardinality } : {},
|
|
2637
|
-
...s.labelOffsetX !== void 0 ? { labelOffsetX: s.labelOffsetX } : {},
|
|
2638
|
-
...s.labelOffsetY !== void 0 ? { labelOffsetY: s.labelOffsetY } : {}
|
|
4041
|
+
...s.style ? { style: s.style } : {}
|
|
2639
4042
|
});
|
|
2640
4043
|
edgeIds.push(edgeId);
|
|
2641
4044
|
});
|
|
2642
|
-
for (const st of doc.animate
|
|
4045
|
+
for (const st of doc.animate?.states ?? []) {
|
|
2643
4046
|
b.state(st.name, { initial: st.initial });
|
|
2644
4047
|
}
|
|
2645
|
-
for (const p of doc.animate
|
|
4048
|
+
for (const p of doc.animate?.phases ?? []) {
|
|
2646
4049
|
b.phase(
|
|
2647
4050
|
slugify(p.name),
|
|
2648
4051
|
{
|
|
@@ -2685,51 +4088,284 @@ function resolveHighlightGeneric(phase, doc, actorToNodeId, edgeIds) {
|
|
|
2685
4088
|
}
|
|
2686
4089
|
continue;
|
|
2687
4090
|
}
|
|
2688
|
-
const nodeId = actorToNodeId.get(entry.name) ?? slugLookup(actorToNodeId, entry.name);
|
|
2689
|
-
if (nodeId) {
|
|
2690
|
-
out.push(nodeId);
|
|
4091
|
+
const nodeId = actorToNodeId.get(entry.name) ?? slugLookup(actorToNodeId, entry.name);
|
|
4092
|
+
if (nodeId) {
|
|
4093
|
+
out.push(nodeId);
|
|
4094
|
+
}
|
|
4095
|
+
}
|
|
4096
|
+
return out;
|
|
4097
|
+
}
|
|
4098
|
+
var ID_MAX = 64;
|
|
4099
|
+
function slugify(s) {
|
|
4100
|
+
return s.toLowerCase().normalize("NFKC").replace(/[^a-z0-9ぁ-んァ-ヶ一-龯\-_]+/g, "-").replace(/^-+|-+$/g, "").slice(0, ID_MAX) || "n";
|
|
4101
|
+
}
|
|
4102
|
+
var CARDINALITY_PATTERNS = [
|
|
4103
|
+
[/1:1/, "1:1"],
|
|
4104
|
+
[/1:N/i, "1:N"],
|
|
4105
|
+
[/N:1/i, "N:1"],
|
|
4106
|
+
[/N:M/i, "N:M"],
|
|
4107
|
+
[/0\.\.1/, "0..1"],
|
|
4108
|
+
[/1\.\.\*/, "1..*"]
|
|
4109
|
+
];
|
|
4110
|
+
function boundedCardinalityRegExp(pattern, extraFlags = "") {
|
|
4111
|
+
const base = pattern.flags.includes("i") ? "i" : "";
|
|
4112
|
+
return new RegExp(`(?<![A-Za-z0-9_])(?:${pattern.source})(?![A-Za-z0-9_])`, base + extraFlags);
|
|
4113
|
+
}
|
|
4114
|
+
function parseCardinalityFromLabel(label) {
|
|
4115
|
+
for (const [pattern, card] of CARDINALITY_PATTERNS) {
|
|
4116
|
+
if (boundedCardinalityRegExp(pattern).test(label)) return card;
|
|
4117
|
+
}
|
|
4118
|
+
return null;
|
|
4119
|
+
}
|
|
4120
|
+
var HORIZONTAL_WS = " \\t\\u3000";
|
|
4121
|
+
var HWS = `[${HORIZONTAL_WS}]`;
|
|
4122
|
+
function stripCardinality(label) {
|
|
4123
|
+
let r = label;
|
|
4124
|
+
let removed = false;
|
|
4125
|
+
for (const [pattern] of CARDINALITY_PATTERNS) {
|
|
4126
|
+
const src = pattern.source;
|
|
4127
|
+
const flags = pattern.flags.includes("i") ? "gi" : "g";
|
|
4128
|
+
const before = r;
|
|
4129
|
+
r = r.replace(new RegExp(`\\(${HWS}*${src}${HWS}*\\)`, flags), "");
|
|
4130
|
+
r = r.replace(boundedCardinalityRegExp(pattern, "g"), "");
|
|
4131
|
+
if (r !== before) removed = true;
|
|
4132
|
+
}
|
|
4133
|
+
if (!removed) return label;
|
|
4134
|
+
r = r.replace(new RegExp(`${HWS}{2,}`, "g"), " ").replace(new RegExp(`${HWS}*([\\r\\n])${HWS}*`, "g"), "$1").replace(new RegExp(`^${HWS}+|${HWS}+$`, "g"), "");
|
|
4135
|
+
const hasVisible = /[^\p{White_Space}\p{Cf}\p{Cc}\p{Default_Ignorable_Code_Point}]/u.test(r);
|
|
4136
|
+
return hasVisible ? r : label;
|
|
4137
|
+
}
|
|
4138
|
+
|
|
4139
|
+
// src/value-syntax.ts
|
|
4140
|
+
var VALUE_NAME_RE = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
4141
|
+
var VALUE_FNS = /* @__PURE__ */ new Set(["min", "max"]);
|
|
4142
|
+
function isValueName(name) {
|
|
4143
|
+
return VALUE_NAME_RE.test(name);
|
|
4144
|
+
}
|
|
4145
|
+
function valueNameIssue(name) {
|
|
4146
|
+
return {
|
|
4147
|
+
message: `invalid value name: "${name}"`,
|
|
4148
|
+
hint: "\u82F1\u5B57\u304B _ \u3067\u59CB\u3081\u3001 \u82F1\u6570\u5B57\u3068 _ \u3060\u3051\u3092\u4F7F\u3046 (states \u3068\u540C\u3058\u898F\u5247)"
|
|
4149
|
+
};
|
|
4150
|
+
}
|
|
4151
|
+
var TRIGGER_OPS = [">=", "<=", "==", "!=", ">", "<"];
|
|
4152
|
+
function parseDurationMs(text) {
|
|
4153
|
+
const m = text.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s)?$/);
|
|
4154
|
+
if (!m) return null;
|
|
4155
|
+
const n = parseFloat(m[1] ?? "0");
|
|
4156
|
+
if (!Number.isFinite(n) || n <= 0) return null;
|
|
4157
|
+
const unit = m[2] ?? "s";
|
|
4158
|
+
const durationMs = unit === "ms" ? Math.round(n) : Math.round(n * 1e3);
|
|
4159
|
+
return durationMs > 0 ? durationMs : null;
|
|
4160
|
+
}
|
|
4161
|
+
function splitOutsideQuotes(body) {
|
|
4162
|
+
const out = [];
|
|
4163
|
+
let cur = "";
|
|
4164
|
+
let quote = null;
|
|
4165
|
+
for (const ch of body) {
|
|
4166
|
+
if (quote) {
|
|
4167
|
+
if (ch === quote) quote = null;
|
|
4168
|
+
cur += ch;
|
|
4169
|
+
continue;
|
|
4170
|
+
}
|
|
4171
|
+
if (ch === '"' || ch === "'") {
|
|
4172
|
+
quote = ch;
|
|
4173
|
+
cur += ch;
|
|
4174
|
+
continue;
|
|
4175
|
+
}
|
|
4176
|
+
if (ch === ",") {
|
|
4177
|
+
out.push(cur);
|
|
4178
|
+
cur = "";
|
|
4179
|
+
continue;
|
|
4180
|
+
}
|
|
4181
|
+
cur += ch;
|
|
4182
|
+
}
|
|
4183
|
+
out.push(cur);
|
|
4184
|
+
return out.map((s) => s.trim()).filter((s) => s !== "");
|
|
4185
|
+
}
|
|
4186
|
+
function unquote(s) {
|
|
4187
|
+
const t = s.trim();
|
|
4188
|
+
if (t.length >= 2 && (t[0] === '"' || t[0] === "'") && t[t.length - 1] === t[0]) {
|
|
4189
|
+
return t.slice(1, -1);
|
|
4190
|
+
}
|
|
4191
|
+
return t;
|
|
4192
|
+
}
|
|
4193
|
+
function parseTriggerExpression(raw, name) {
|
|
4194
|
+
const text = raw.trim();
|
|
4195
|
+
const stepMatch = text.match(/^step\s+(.+)$/);
|
|
4196
|
+
if (stepMatch) {
|
|
4197
|
+
const step = unquote(stepMatch[1] ?? "");
|
|
4198
|
+
if (step === "") {
|
|
4199
|
+
return { message: `trigger \u306E\u6BB5\u540D\u304C\u7A7A\u3067\u3059 ("${name}")`, hint: '`trigger: step "\u53D6\u8FBC\u307F"` \u306E\u5F62\u3067\u6BB5\u306E\u540D\u524D\u3092\u66F8\u304F' };
|
|
4200
|
+
}
|
|
4201
|
+
return { kind: "step", step };
|
|
4202
|
+
}
|
|
4203
|
+
for (const op of TRIGGER_OPS) {
|
|
4204
|
+
const at = text.indexOf(op);
|
|
4205
|
+
if (at < 0) continue;
|
|
4206
|
+
const source = text.slice(0, at).trim();
|
|
4207
|
+
const rhs = text.slice(at + op.length).trim();
|
|
4208
|
+
if (!isValueName(source)) {
|
|
4209
|
+
return {
|
|
4210
|
+
message: `trigger \u304C\u898B\u5F35\u308B\u5024\u306E\u540D\u524D\u304C\u4F7F\u3048\u307E\u305B\u3093: "${source}" ("${name}")`,
|
|
4211
|
+
hint: "\u82F1\u5B57\u304B _ \u3067\u59CB\u3081\u3001 \u82F1\u6570\u5B57\u3068 _ \u3060\u3051\u3092\u4F7F\u3046"
|
|
4212
|
+
};
|
|
4213
|
+
}
|
|
4214
|
+
const threshold = Number(rhs);
|
|
4215
|
+
if (rhs === "" || !Number.isFinite(threshold)) {
|
|
4216
|
+
return {
|
|
4217
|
+
message: `trigger \u306E\u5883\u76EE\u304C\u6570\u3067\u306F\u3042\u308A\u307E\u305B\u3093: "${rhs}" ("${name}")`,
|
|
4218
|
+
hint: "`trigger: vDone >= 100` \u306E\u3088\u3046\u306B\u6570\u3067\u66F8\u304F"
|
|
4219
|
+
};
|
|
4220
|
+
}
|
|
4221
|
+
return { kind: "reaches", source, op, threshold };
|
|
4222
|
+
}
|
|
4223
|
+
return {
|
|
4224
|
+
message: `trigger \u306E\u5F62\u304C\u8AAD\u3081\u307E\u305B\u3093: "${text}" ("${name}")`,
|
|
4225
|
+
hint: '`step "\u53D6\u8FBC\u307F"` \u304B `vDone >= 100` \u306E\u5F62\u3067\u66F8\u304F'
|
|
4226
|
+
};
|
|
4227
|
+
}
|
|
4228
|
+
function isTriggerBody(raw) {
|
|
4229
|
+
const t = raw.trim();
|
|
4230
|
+
if (!t.startsWith("{") || !t.endsWith("}") || t.length < 2) return false;
|
|
4231
|
+
const inner = t.slice(1, -1);
|
|
4232
|
+
let quote = null;
|
|
4233
|
+
for (const ch of inner) {
|
|
4234
|
+
if (quote) {
|
|
4235
|
+
if (ch === quote) quote = null;
|
|
4236
|
+
continue;
|
|
4237
|
+
}
|
|
4238
|
+
if (ch === '"' || ch === "'") {
|
|
4239
|
+
quote = ch;
|
|
4240
|
+
continue;
|
|
2691
4241
|
}
|
|
4242
|
+
if (ch === ":") return true;
|
|
2692
4243
|
}
|
|
2693
|
-
return
|
|
2694
|
-
}
|
|
2695
|
-
function slugify(s) {
|
|
2696
|
-
return s.toLowerCase().normalize("NFKC").replace(/[^a-z0-9ぁ-んァ-ヶ一-龯\-_]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "n";
|
|
2697
|
-
}
|
|
2698
|
-
var CARDINALITY_PATTERNS = [
|
|
2699
|
-
[/1:1/, "1:1"],
|
|
2700
|
-
[/1:N/i, "1:N"],
|
|
2701
|
-
[/N:1/i, "N:1"],
|
|
2702
|
-
[/N:M/i, "N:M"],
|
|
2703
|
-
[/0\.\.1/, "0..1"],
|
|
2704
|
-
[/1\.\.\*/, "1..*"]
|
|
2705
|
-
];
|
|
2706
|
-
function boundedCardinalityRegExp(pattern, extraFlags = "") {
|
|
2707
|
-
const base = pattern.flags.includes("i") ? "i" : "";
|
|
2708
|
-
return new RegExp(`(?<![A-Za-z0-9_])(?:${pattern.source})(?![A-Za-z0-9_])`, base + extraFlags);
|
|
4244
|
+
return false;
|
|
2709
4245
|
}
|
|
2710
|
-
function
|
|
2711
|
-
|
|
2712
|
-
|
|
4246
|
+
function parseValueTriggerBody(body, name) {
|
|
4247
|
+
const issues = [];
|
|
4248
|
+
const seen = /* @__PURE__ */ new Map();
|
|
4249
|
+
for (const part of splitOutsideQuotes(body)) {
|
|
4250
|
+
const at = part.indexOf(":");
|
|
4251
|
+
if (at < 0) {
|
|
4252
|
+
issues.push({ message: `"${part}" \u306F key: value \u306E\u5F62\u3067\u306F\u3042\u308A\u307E\u305B\u3093 ("${name}")`, hint: "`trigger: ... , to: 100, dur: 2s` \u306E\u5F62\u3067\u66F8\u304F" });
|
|
4253
|
+
continue;
|
|
4254
|
+
}
|
|
4255
|
+
const key = part.slice(0, at).trim().toLowerCase();
|
|
4256
|
+
const value = part.slice(at + 1).trim();
|
|
4257
|
+
if (seen.has(key)) {
|
|
4258
|
+
issues.push({ message: `"${key}" \u3092 2 \u5EA6\u66F8\u3044\u3066\u3044\u307E\u3059 ("${name}")`, hint: "\u540C\u3058\u9805\u76EE\u306F 1 \u5EA6\u3060\u3051\u66F8\u304F" });
|
|
4259
|
+
continue;
|
|
4260
|
+
}
|
|
4261
|
+
seen.set(key, value);
|
|
2713
4262
|
}
|
|
2714
|
-
|
|
4263
|
+
const known = /* @__PURE__ */ new Set(["trigger", "to", "dur"]);
|
|
4264
|
+
for (const key of seen.keys()) {
|
|
4265
|
+
if (known.has(key)) continue;
|
|
4266
|
+
issues.push({
|
|
4267
|
+
message: `"${key}" \u306F values \u306B\u66F8\u3051\u307E\u305B\u3093 ("${name}")`,
|
|
4268
|
+
hint: `\u66F8\u3051\u308B\u306E\u306F ${[...known].join(" / ")} \u3060\u3051`
|
|
4269
|
+
});
|
|
4270
|
+
}
|
|
4271
|
+
const triggerRaw = seen.get("trigger");
|
|
4272
|
+
let trigger = null;
|
|
4273
|
+
if (triggerRaw === void 0) {
|
|
4274
|
+
issues.push({ message: `trigger \u304C\u3042\u308A\u307E\u305B\u3093 ("${name}")`, hint: '`trigger: step "\u53D6\u8FBC\u307F"` \u304B `trigger: vDone >= 100` \u3092\u66F8\u304F' });
|
|
4275
|
+
} else {
|
|
4276
|
+
const parsed = parseTriggerExpression(triggerRaw, name);
|
|
4277
|
+
if ("message" in parsed) issues.push(parsed);
|
|
4278
|
+
else trigger = parsed;
|
|
4279
|
+
}
|
|
4280
|
+
const toRaw = seen.get("to");
|
|
4281
|
+
let to = 0;
|
|
4282
|
+
if (toRaw === void 0) {
|
|
4283
|
+
issues.push({ message: `to \u304C\u3042\u308A\u307E\u305B\u3093 ("${name}")`, hint: "`to: 100` \u306E\u3088\u3046\u306B\u52D5\u3044\u305F\u5148\u306E\u5024\u3092\u66F8\u304F" });
|
|
4284
|
+
} else {
|
|
4285
|
+
to = Number(unquote(toRaw));
|
|
4286
|
+
if (!Number.isFinite(to)) {
|
|
4287
|
+
issues.push({ message: `to \u304C\u6570\u3067\u306F\u3042\u308A\u307E\u305B\u3093: "${toRaw}" ("${name}")`, hint: "`to: 100` \u306E\u3088\u3046\u306B\u6570\u3067\u66F8\u304F" });
|
|
4288
|
+
}
|
|
4289
|
+
}
|
|
4290
|
+
const durRaw = seen.get("dur");
|
|
4291
|
+
let durationMs = 0;
|
|
4292
|
+
if (durRaw === void 0) {
|
|
4293
|
+
issues.push({ message: `dur \u304C\u3042\u308A\u307E\u305B\u3093 ("${name}")`, hint: "`dur: 2s` \u306E\u3088\u3046\u306B\u52D5\u304F\u9577\u3055\u3092\u66F8\u304F" });
|
|
4294
|
+
} else {
|
|
4295
|
+
const parsedDur = parseDurationMs(unquote(durRaw));
|
|
4296
|
+
if (parsedDur === null) {
|
|
4297
|
+
issues.push({ message: `dur \u304C\u8AAD\u3081\u307E\u305B\u3093: "${durRaw}" ("${name}")`, hint: "`2s` / `1.5s` / `500ms` \u306E\u5F62\u3067\u3001 0 \u3088\u308A\u5927\u304D\u3044\u9577\u3055\u3092\u66F8\u304F" });
|
|
4298
|
+
} else {
|
|
4299
|
+
durationMs = parsedDur;
|
|
4300
|
+
}
|
|
4301
|
+
}
|
|
4302
|
+
if (issues.length > 0 || trigger === null) return { spec: null, issues };
|
|
4303
|
+
return { spec: { trigger, to, durationMs }, issues: [] };
|
|
2715
4304
|
}
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
let
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
4305
|
+
function checkValueExpression(expression, name) {
|
|
4306
|
+
const issues = [];
|
|
4307
|
+
const refRe = /\{([^}]*)\}/g;
|
|
4308
|
+
let m;
|
|
4309
|
+
while ((m = refRe.exec(expression)) !== null) {
|
|
4310
|
+
const ref = (m[1] ?? "").trim();
|
|
4311
|
+
if (!VALUE_NAME_RE.test(ref)) {
|
|
4312
|
+
issues.push({
|
|
4313
|
+
message: `invalid reference "{${ref}}" in "${name}"`,
|
|
4314
|
+
hint: "\u82F1\u5B57\u304B _ \u3067\u59CB\u3081\u3001 \u82F1\u6570\u5B57\u3068 _ \u3060\u3051\u3092\u4F7F\u3046"
|
|
4315
|
+
});
|
|
4316
|
+
}
|
|
2728
4317
|
}
|
|
2729
|
-
if (!
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
4318
|
+
if (expression.includes("{") && !expression.includes("}")) {
|
|
4319
|
+
issues.push({ message: `unclosed "{" in "${name}"`, hint: "`{\u540D\u524D}` \u306E\u5F62\u3067\u9589\u3058\u308B" });
|
|
4320
|
+
}
|
|
4321
|
+
const outside = expression.replace(/\{[^}]*\}/g, " ");
|
|
4322
|
+
if (outside.includes("%")) {
|
|
4323
|
+
issues.push({ message: `"%" \u306F\u5F0F\u306B\u66F8\u3051\u306A\u3044 ("${name}")`, hint: "\u56DB\u5247 (+ - * /) \u3060\u3051\u3092\u4F7F\u3046" });
|
|
4324
|
+
}
|
|
4325
|
+
if (outside.includes("?")) {
|
|
4326
|
+
issues.push({
|
|
4327
|
+
message: `\u6761\u4EF6\u5206\u5C90 (?:) \u306F\u5F0F\u306B\u66F8\u3051\u306A\u3044 ("${name}")`,
|
|
4328
|
+
hint: "\u6BD4\u8F03\u306E\u7D50\u679C\u306F\u771F = 1 / \u507D = 0 \u306E\u6570\u306B\u306A\u308B\u306E\u3067\u3001 \u639B\u3051\u7B97\u3067\u5207\u308A\u66FF\u3048\u308B"
|
|
4329
|
+
});
|
|
4330
|
+
}
|
|
4331
|
+
for (const fn of outside.matchAll(/[a-zA-Z_][a-zA-Z0-9_.]*/g)) {
|
|
4332
|
+
const word = fn[0];
|
|
4333
|
+
if (VALUE_FNS.has(word)) continue;
|
|
4334
|
+
issues.push({
|
|
4335
|
+
message: `"${word}" \u306F\u5F0F\u306B\u66F8\u3051\u306A\u3044 ("${name}")`,
|
|
4336
|
+
hint: word.startsWith("Math.") ? "min / max \u306F Math. \u3092\u4ED8\u3051\u305A\u306B\u66F8\u304F" : `\u4F7F\u3048\u308B\u306E\u306F ${[...VALUE_FNS].join(" / ")} \u3060\u3051\u3002 \u5024\u306F {\u540D\u524D} \u3067\u8AAD\u3080`
|
|
4337
|
+
});
|
|
4338
|
+
}
|
|
4339
|
+
const stray = outside.replace(/[a-zA-Z_][a-zA-Z0-9_.]*/g, " ").match(/[^0-9.,+\-*/()<>=!\s]/g);
|
|
4340
|
+
if (stray) {
|
|
4341
|
+
issues.push({
|
|
4342
|
+
message: `"${[...new Set(stray)].join("")}" \u306F\u5F0F\u306B\u66F8\u3051\u306A\u3044 ("${name}")`,
|
|
4343
|
+
hint: "\u56DB\u5247 (+ - * /) / \u62EC\u5F27 / \u6BD4\u8F03 (> >= < <= == !=) / min / max \u3060\u3051\u3092\u4F7F\u3046"
|
|
4344
|
+
});
|
|
4345
|
+
}
|
|
4346
|
+
return issues;
|
|
4347
|
+
}
|
|
4348
|
+
|
|
4349
|
+
// src/v05/parser.ts
|
|
4350
|
+
var TOP_LEVEL_KEYS = [
|
|
4351
|
+
"title",
|
|
4352
|
+
"type",
|
|
4353
|
+
"actors",
|
|
4354
|
+
"flow",
|
|
4355
|
+
"states",
|
|
4356
|
+
"values",
|
|
4357
|
+
"animation",
|
|
4358
|
+
"viewport",
|
|
4359
|
+
"lanes",
|
|
4360
|
+
"groups",
|
|
4361
|
+
// 図全体を 1 箱にする図種で、 その箱の上に出す小見出し (#1247)
|
|
4362
|
+
"eyebrow",
|
|
4363
|
+
// 2 軸で仕分ける図の軸の名前 (#1251)
|
|
4364
|
+
"axes"
|
|
4365
|
+
];
|
|
4366
|
+
var LANE_ID_ENTRY = /^([\p{L}\p{N}_-]+)\s*:\s*\{([^}]*)\}\s*$/u;
|
|
4367
|
+
function isTopLevelKey(key) {
|
|
4368
|
+
return TOP_LEVEL_KEYS.includes(key);
|
|
2733
4369
|
}
|
|
2734
4370
|
var PRESET_TYPES = /* @__PURE__ */ new Set([
|
|
2735
4371
|
"sequence",
|
|
@@ -2742,6 +4378,12 @@ var PRESET_TYPES = /* @__PURE__ */ new Set([
|
|
|
2742
4378
|
"gantt",
|
|
2743
4379
|
"class",
|
|
2744
4380
|
"pie",
|
|
4381
|
+
"bar",
|
|
4382
|
+
"line",
|
|
4383
|
+
"funnel",
|
|
4384
|
+
"tree",
|
|
4385
|
+
"journey",
|
|
4386
|
+
"quadrant",
|
|
2745
4387
|
"c4",
|
|
2746
4388
|
"mind"
|
|
2747
4389
|
]);
|
|
@@ -2792,9 +4434,14 @@ function parseTextDslV05(src) {
|
|
|
2792
4434
|
const lines = tokenize(src);
|
|
2793
4435
|
let title = null;
|
|
2794
4436
|
let type = null;
|
|
4437
|
+
let eyebrow = null;
|
|
4438
|
+
let eyebrowLine = 0;
|
|
4439
|
+
let axes = void 0;
|
|
4440
|
+
let axesLine = 0;
|
|
2795
4441
|
let actors = [];
|
|
2796
4442
|
const flow2 = [];
|
|
2797
4443
|
let animate = void 0;
|
|
4444
|
+
const values = [];
|
|
2798
4445
|
let viewport = void 0;
|
|
2799
4446
|
let lanesMap = void 0;
|
|
2800
4447
|
let groupsMap = void 0;
|
|
@@ -2806,11 +4453,11 @@ function parseTextDslV05(src) {
|
|
|
2806
4453
|
continue;
|
|
2807
4454
|
}
|
|
2808
4455
|
const head = matchTopHeader(line.trimmed);
|
|
2809
|
-
if (!head) {
|
|
4456
|
+
if (!head || !isTopLevelKey(head.key)) {
|
|
2810
4457
|
errors.push({
|
|
2811
4458
|
line: line.no,
|
|
2812
4459
|
message: `unknown top-level key: "${line.trimmed}"`,
|
|
2813
|
-
hint:
|
|
4460
|
+
hint: `expected one of: ${TOP_LEVEL_KEYS.join(", ")}`
|
|
2814
4461
|
});
|
|
2815
4462
|
i += 1;
|
|
2816
4463
|
continue;
|
|
@@ -2823,6 +4470,13 @@ function parseTextDslV05(src) {
|
|
|
2823
4470
|
i += 1;
|
|
2824
4471
|
continue;
|
|
2825
4472
|
}
|
|
4473
|
+
if (head.key === "eyebrow") {
|
|
4474
|
+
const v = (head.value ?? "").trim();
|
|
4475
|
+
eyebrow = v.length > 0 ? v : null;
|
|
4476
|
+
eyebrowLine = line.no;
|
|
4477
|
+
i += 1;
|
|
4478
|
+
continue;
|
|
4479
|
+
}
|
|
2826
4480
|
if (head.key === "type") {
|
|
2827
4481
|
const v = (head.value ?? "").trim().toLowerCase();
|
|
2828
4482
|
if (!PRESET_TYPES.has(v)) {
|
|
@@ -2897,6 +4551,25 @@ function parseTextDslV05(src) {
|
|
|
2897
4551
|
i = next;
|
|
2898
4552
|
continue;
|
|
2899
4553
|
}
|
|
4554
|
+
if (head.key === "values") {
|
|
4555
|
+
const inline = head.value?.trim();
|
|
4556
|
+
if (inline) {
|
|
4557
|
+
errors.push({
|
|
4558
|
+
line: line.no,
|
|
4559
|
+
message: "values \u306F 1 \u884C\u306B\u307E\u3068\u3081\u3066\u66F8\u3051\u306A\u3044",
|
|
4560
|
+
hint: '\u5F0F\u306B `,` \u304C\u5165\u308B\u305F\u3081\u3002 \u6B21\u306E\u884C\u304B\u3089\u5B57\u4E0B\u3052\u3057\u3066 `waiting: "{inflow} - {done}"` \u306E\u5F62\u3067\u4E26\u3079\u308B'
|
|
4561
|
+
});
|
|
4562
|
+
i += 1;
|
|
4563
|
+
continue;
|
|
4564
|
+
}
|
|
4565
|
+
const { items, next } = collectIndentedRaw(lines, i + 1, line.indent);
|
|
4566
|
+
for (const it of items) {
|
|
4567
|
+
const v = parseValueEntry(it.trimmed.replace(/^-\s*/, ""), it.no, errors);
|
|
4568
|
+
if (v) values.push(v);
|
|
4569
|
+
}
|
|
4570
|
+
i = next;
|
|
4571
|
+
continue;
|
|
4572
|
+
}
|
|
2900
4573
|
if (head.key === "animation") {
|
|
2901
4574
|
const { items: stepBlocks, next } = collectAnimationSteps(lines, i + 1, line.indent);
|
|
2902
4575
|
animate = ensureAnimate(animate, line.no);
|
|
@@ -2945,11 +4618,42 @@ function parseTextDslV05(src) {
|
|
|
2945
4618
|
i = next;
|
|
2946
4619
|
continue;
|
|
2947
4620
|
}
|
|
4621
|
+
if (head.key === "axes") {
|
|
4622
|
+
if (head.value !== null && head.value.trim() !== "") {
|
|
4623
|
+
errors.push({
|
|
4624
|
+
line: line.no,
|
|
4625
|
+
message: "axes \u306F 1 \u884C\u306B\u307E\u3068\u3081\u3066\u66F8\u3051\u306A\u3044",
|
|
4626
|
+
hint: '\u6B21\u306E\u884C\u304B\u3089\u5B57\u4E0B\u3052\u3057\u3066 `x: { left: "...", right: "..." }` \u306E\u5F62\u3067\u4E26\u3079\u308B'
|
|
4627
|
+
});
|
|
4628
|
+
i += 1;
|
|
4629
|
+
continue;
|
|
4630
|
+
}
|
|
4631
|
+
const { items, next } = collectIndentedRaw(lines, i + 1, line.indent);
|
|
4632
|
+
axesLine = line.no;
|
|
4633
|
+
const \u7D44\u307F\u7ACB\u3066 = {};
|
|
4634
|
+
for (const it of items) {
|
|
4635
|
+
const m = it.trimmed.match(/^(x|y)\s*:\s*\{([^}]*)\}\s*$/);
|
|
4636
|
+
if (!m) {
|
|
4637
|
+
errors.push({
|
|
4638
|
+
line: it.no,
|
|
4639
|
+
message: `invalid axes entry: "${it.trimmed}"`,
|
|
4640
|
+
hint: 'use `x: { left: "...", right: "..." }` or `y: { bottom: "...", top: "..." }`'
|
|
4641
|
+
});
|
|
4642
|
+
continue;
|
|
4643
|
+
}
|
|
4644
|
+
const opts = parseInlineMapping(m[2] ?? "");
|
|
4645
|
+
if (m[1] === "x") \u7D44\u307F\u7ACB\u3066.x = { left: opts.left, right: opts.right };
|
|
4646
|
+
else \u7D44\u307F\u7ACB\u3066.y = { bottom: opts.bottom, top: opts.top };
|
|
4647
|
+
}
|
|
4648
|
+
axes = \u7D44\u307F\u7ACB\u3066.x !== void 0 || \u7D44\u307F\u7ACB\u3066.y !== void 0 ? \u7D44\u307F\u7ACB\u3066 : void 0;
|
|
4649
|
+
i = next;
|
|
4650
|
+
continue;
|
|
4651
|
+
}
|
|
2948
4652
|
if (head.key === "lanes") {
|
|
2949
4653
|
const { items, next } = collectIndentedList(lines, i + 1, line.indent);
|
|
2950
4654
|
lanesMap = {};
|
|
2951
4655
|
for (const it of items) {
|
|
2952
|
-
const m = it.trimmed.match(
|
|
4656
|
+
const m = it.trimmed.match(LANE_ID_ENTRY);
|
|
2953
4657
|
if (m) {
|
|
2954
4658
|
const id = m[1];
|
|
2955
4659
|
const opts = parseInlineMapping(m[2]);
|
|
@@ -2977,7 +4681,7 @@ function parseTextDslV05(src) {
|
|
|
2977
4681
|
const { items, next } = collectIndentedList(lines, i + 1, line.indent);
|
|
2978
4682
|
groupsMap = {};
|
|
2979
4683
|
for (const it of items) {
|
|
2980
|
-
const m = it.trimmed.match(
|
|
4684
|
+
const m = it.trimmed.match(LANE_ID_ENTRY);
|
|
2981
4685
|
if (m) {
|
|
2982
4686
|
const id = m[1];
|
|
2983
4687
|
const opts = parseInlineMapping(m[2]);
|
|
@@ -3009,9 +4713,12 @@ function parseTextDslV05(src) {
|
|
|
3009
4713
|
doc: {
|
|
3010
4714
|
title,
|
|
3011
4715
|
type,
|
|
4716
|
+
...eyebrow !== null ? { eyebrow, eyebrowPos: { line: eyebrowLine } } : {},
|
|
4717
|
+
...axes !== void 0 ? { axes, axesPos: { line: axesLine } } : {},
|
|
3012
4718
|
actors,
|
|
3013
4719
|
flow: flow2,
|
|
3014
4720
|
animate,
|
|
4721
|
+
...values.length > 0 ? { values } : {},
|
|
3015
4722
|
viewport,
|
|
3016
4723
|
lanes: lanesMap,
|
|
3017
4724
|
groups: groupsMap,
|
|
@@ -3276,6 +4983,7 @@ function applyContinuationLines(actor, rest, errors) {
|
|
|
3276
4983
|
const state = { ...actor.stateOverride ?? {} };
|
|
3277
4984
|
let touchedState = false;
|
|
3278
4985
|
const scaleWritten = /* @__PURE__ */ new Map();
|
|
4986
|
+
const \u56F3\u7A2E\u3054\u3068\u306E\u6B04 = /* @__PURE__ */ new Map();
|
|
3279
4987
|
const unknownKeys = [];
|
|
3280
4988
|
for (const ln of rest) {
|
|
3281
4989
|
const idx = ln.trimmed.indexOf(":");
|
|
@@ -3364,6 +5072,12 @@ function applyContinuationLines(actor, rest, errors) {
|
|
|
3364
5072
|
});
|
|
3365
5073
|
break;
|
|
3366
5074
|
}
|
|
5075
|
+
case "touchpoint":
|
|
5076
|
+
case "opportunity":
|
|
5077
|
+
case "owner":
|
|
5078
|
+
case "end":
|
|
5079
|
+
\u56F3\u7A2E\u3054\u3068\u306E\u6B04.set(key, stripQuotes(raw));
|
|
5080
|
+
break;
|
|
3367
5081
|
case "lane":
|
|
3368
5082
|
out.lane = stripQuotes(raw);
|
|
3369
5083
|
break;
|
|
@@ -3382,6 +5096,17 @@ function applyContinuationLines(actor, rest, errors) {
|
|
|
3382
5096
|
out.scale = s.scale;
|
|
3383
5097
|
out.scaleKeys = [.../* @__PURE__ */ new Set([...actor.scaleKeys ?? [], ...s.keys])];
|
|
3384
5098
|
}
|
|
5099
|
+
for (const [key, v] of \u56F3\u7A2E\u3054\u3068\u306E\u6B04) {
|
|
5100
|
+
if (out.partId !== void 0) {
|
|
5101
|
+
state[key] = coerceStateValue(v);
|
|
5102
|
+
touchedState = true;
|
|
5103
|
+
continue;
|
|
5104
|
+
}
|
|
5105
|
+
if (key === "touchpoint") out.touchpoint = v;
|
|
5106
|
+
else if (key === "opportunity") out.opportunity = v;
|
|
5107
|
+
else if (key === "owner") out.owner = v;
|
|
5108
|
+
else out.end = v;
|
|
5109
|
+
}
|
|
3385
5110
|
if (out.partId !== void 0) {
|
|
3386
5111
|
if (touchedState) out.stateOverride = state;
|
|
3387
5112
|
return out;
|
|
@@ -3414,7 +5139,13 @@ var ACTOR_ITEM_KEYS = /* @__PURE__ */ new Set([
|
|
|
3414
5139
|
"\u500D\u7387",
|
|
3415
5140
|
"scale",
|
|
3416
5141
|
"lane",
|
|
3417
|
-
"stack"
|
|
5142
|
+
"stack",
|
|
5143
|
+
// 体験の道筋の欄 (#1251)
|
|
5144
|
+
"touchpoint",
|
|
5145
|
+
"opportunity",
|
|
5146
|
+
// 工程の並びの欄 (#1251)
|
|
5147
|
+
"owner",
|
|
5148
|
+
"end"
|
|
3418
5149
|
]);
|
|
3419
5150
|
function validateRelativePositions(actors, errors) {
|
|
3420
5151
|
const named = new Set(actors.map((a) => a.name));
|
|
@@ -3513,6 +5244,9 @@ var ACTOR_RESERVED_FIELDS = /* @__PURE__ */ new Set([
|
|
|
3513
5244
|
"initial",
|
|
3514
5245
|
"final",
|
|
3515
5246
|
"state",
|
|
5247
|
+
// 体験の道筋の欄 (`touchpoint` / `opportunity`) はここに載せない (#1251 Round 1 の指摘)。
|
|
5248
|
+
// 載せるとパーツで同じ名前の状態を書いた時に横取りされる = 既に動いている見本が静かに変わる。
|
|
5249
|
+
// パーツでない箱でだけ道筋の欄として読む (`parseActor` / `applyContinuationLines` が分岐する)
|
|
3516
5250
|
// canvas pivot 新 spec = 絶対座標 4 field (dragon canvas pivot spec §layout-role-conversion)
|
|
3517
5251
|
"posX",
|
|
3518
5252
|
"posY",
|
|
@@ -3619,6 +5353,12 @@ var INLINE_ACTOR_KEYS = /* @__PURE__ */ new Set([
|
|
|
3619
5353
|
"final",
|
|
3620
5354
|
"tone",
|
|
3621
5355
|
"nodes",
|
|
5356
|
+
// 体験の道筋の欄 (#1251)。 他の図種では組み立て側が知らせる
|
|
5357
|
+
"touchpoint",
|
|
5358
|
+
"opportunity",
|
|
5359
|
+
// 工程の並びの欄 (#1251)
|
|
5360
|
+
"owner",
|
|
5361
|
+
"end",
|
|
3622
5362
|
"posX",
|
|
3623
5363
|
"posY",
|
|
3624
5364
|
"posW",
|
|
@@ -3628,6 +5368,15 @@ var INLINE_ACTOR_KEYS = /* @__PURE__ */ new Set([
|
|
|
3628
5368
|
"scale",
|
|
3629
5369
|
"\u500D\u7387"
|
|
3630
5370
|
]);
|
|
5371
|
+
var FLOW_INLINE_READERS = {
|
|
5372
|
+
sub: (v) => v,
|
|
5373
|
+
guard: (v) => v,
|
|
5374
|
+
cardinality: (v) => v,
|
|
5375
|
+
labelOffsetX: (v) => numberOrUndef(v),
|
|
5376
|
+
labelOffsetY: (v) => numberOrUndef(v),
|
|
5377
|
+
overlay: (v) => boolOrUndef(v)
|
|
5378
|
+
};
|
|
5379
|
+
var FLOW_INLINE_KEYS = Object.keys(FLOW_INLINE_READERS);
|
|
3631
5380
|
function reportUnknownInlineKeys(isPart, inner, line, errors) {
|
|
3632
5381
|
if (isPart) return;
|
|
3633
5382
|
for (const field of splitInlineFields(inner)) {
|
|
@@ -3665,6 +5414,12 @@ function parseActor2(line, errors) {
|
|
|
3665
5414
|
kindWritten: kindRaw !== "" && !isPart,
|
|
3666
5415
|
subtitle: opts.subtitle,
|
|
3667
5416
|
eyebrow: opts.eyebrow,
|
|
5417
|
+
// パーツでは状態の上書きとして意味を持つため、道筋の欄として横取りしない (#1251)
|
|
5418
|
+
touchpoint: isPart ? void 0 : opts.touchpoint,
|
|
5419
|
+
opportunity: isPart ? void 0 : opts.opportunity,
|
|
5420
|
+
// 見本では状態の上書きとして意味を持つため横取りしない (#1251)
|
|
5421
|
+
owner: isPart ? void 0 : opts.owner,
|
|
5422
|
+
end: isPart ? void 0 : opts.end,
|
|
3668
5423
|
value: opts.value,
|
|
3669
5424
|
rows: opts.rows ? opts.rows.replace(/^\[|\]$/g, "").split(/,(?![^[]*\])/).map((x) => stripQuotes(x.trim())).filter(Boolean) : void 0,
|
|
3670
5425
|
lane: opts.lane,
|
|
@@ -3730,21 +5485,19 @@ function parseFlowStep(line, no) {
|
|
|
3730
5485
|
let label = "";
|
|
3731
5486
|
let tone;
|
|
3732
5487
|
let style;
|
|
3733
|
-
|
|
3734
|
-
let guard;
|
|
3735
|
-
let cardinality;
|
|
3736
|
-
let labelOffsetX;
|
|
3737
|
-
let labelOffsetY;
|
|
5488
|
+
const \u4E2D\u62EC\u5F27 = {};
|
|
3738
5489
|
const mapMatch = rest.match(/\s*\{([^}]*)\}\s*$/);
|
|
3739
5490
|
if (mapMatch) {
|
|
3740
5491
|
const opts = parseInlineMapping(mapMatch[1]);
|
|
3741
|
-
|
|
3742
|
-
guard = opts.guard;
|
|
3743
|
-
cardinality = opts.cardinality;
|
|
3744
|
-
labelOffsetX = numberOrUndef(opts.labelOffsetX);
|
|
3745
|
-
labelOffsetY = numberOrUndef(opts.labelOffsetY);
|
|
5492
|
+
for (const k of FLOW_INLINE_KEYS) \u4E2D\u62EC\u5F27[k] = FLOW_INLINE_READERS[k](opts[k]);
|
|
3746
5493
|
rest = rest.slice(0, mapMatch.index ?? 0).trim();
|
|
3747
5494
|
}
|
|
5495
|
+
const sub = \u4E2D\u62EC\u5F27.sub;
|
|
5496
|
+
const guard = \u4E2D\u62EC\u5F27.guard;
|
|
5497
|
+
const cardinality = \u4E2D\u62EC\u5F27.cardinality;
|
|
5498
|
+
const labelOffsetX = \u4E2D\u62EC\u5F27.labelOffsetX;
|
|
5499
|
+
const labelOffsetY = \u4E2D\u62EC\u5F27.labelOffsetY;
|
|
5500
|
+
const overlay = \u4E2D\u62EC\u5F27.overlay;
|
|
3748
5501
|
const optMatch = rest.match(/\s*\(([^)]*)\)\s*$/);
|
|
3749
5502
|
if (optMatch) {
|
|
3750
5503
|
const opts = (optMatch[1] ?? "").split(",").map((s) => s.trim());
|
|
@@ -3793,19 +5546,72 @@ function parseFlowStep(line, no) {
|
|
|
3793
5546
|
cardinality,
|
|
3794
5547
|
labelOffsetX,
|
|
3795
5548
|
labelOffsetY,
|
|
5549
|
+
overlay,
|
|
3796
5550
|
pos: { line: line.no }
|
|
3797
5551
|
};
|
|
3798
5552
|
}
|
|
3799
5553
|
function parseStateEntry(text, lineNo) {
|
|
3800
|
-
const m = text.match(/^([
|
|
5554
|
+
const m = text.match(/^([^:]+?)\s*:\s*(.+)$/);
|
|
3801
5555
|
if (!m) return null;
|
|
3802
|
-
const name = m[1] ?? "";
|
|
5556
|
+
const name = (m[1] ?? "").trim();
|
|
5557
|
+
if (!isValueName(name)) return null;
|
|
3803
5558
|
const raw = (m[2] ?? "").trim();
|
|
3804
5559
|
const stripped = stripQuotes(raw);
|
|
3805
5560
|
const asNum = Number(stripped);
|
|
3806
5561
|
const initial = Number.isFinite(asNum) && stripped !== "" && !isNaN(asNum) ? asNum : stripped;
|
|
3807
5562
|
return { name, initial, pos: { line: lineNo } };
|
|
3808
5563
|
}
|
|
5564
|
+
function collectIndentedRaw(lines, start, parentIndent) {
|
|
5565
|
+
const items = [];
|
|
5566
|
+
let i = start;
|
|
5567
|
+
while (i < lines.length) {
|
|
5568
|
+
const ln = lines[i];
|
|
5569
|
+
if (!ln || !ln.trimmed || ln.trimmed.startsWith("#")) {
|
|
5570
|
+
i += 1;
|
|
5571
|
+
continue;
|
|
5572
|
+
}
|
|
5573
|
+
if (ln.indent <= parentIndent) break;
|
|
5574
|
+
items.push(ln);
|
|
5575
|
+
i += 1;
|
|
5576
|
+
}
|
|
5577
|
+
return { items, next: i };
|
|
5578
|
+
}
|
|
5579
|
+
function parseValueEntry(text, lineNo, errors) {
|
|
5580
|
+
const m = text.match(/^([^:]+?)\s*:\s*(.+)$/);
|
|
5581
|
+
if (!m) {
|
|
5582
|
+
errors.push({
|
|
5583
|
+
line: lineNo,
|
|
5584
|
+
message: `invalid value entry: "${text}"`,
|
|
5585
|
+
hint: '`waiting: "{inflow} - {done}"` \u306E\u5F62\u3067\u66F8\u304F'
|
|
5586
|
+
});
|
|
5587
|
+
return null;
|
|
5588
|
+
}
|
|
5589
|
+
const name = (m[1] ?? "").trim();
|
|
5590
|
+
if (!isValueName(name)) {
|
|
5591
|
+
errors.push({ line: lineNo, ...valueNameIssue(name) });
|
|
5592
|
+
return null;
|
|
5593
|
+
}
|
|
5594
|
+
const rest = (m[2] ?? "").trim();
|
|
5595
|
+
if (isTriggerBody(rest)) {
|
|
5596
|
+
const { spec, issues: issues2 } = parseValueTriggerBody(rest.slice(1, -1), name);
|
|
5597
|
+
if (spec === null) {
|
|
5598
|
+
for (const issue of issues2) errors.push({ line: lineNo, ...issue });
|
|
5599
|
+
return null;
|
|
5600
|
+
}
|
|
5601
|
+
return { name, trigger: spec.trigger, to: spec.to, durationMs: spec.durationMs, pos: { line: lineNo } };
|
|
5602
|
+
}
|
|
5603
|
+
const expression = stripQuotes(rest);
|
|
5604
|
+
if (expression === "") {
|
|
5605
|
+
errors.push({ line: lineNo, message: `empty expression for "${name}"`, hint: '`"{a} + {b}"` \u306E\u3088\u3046\u306B\u5F0F\u3092\u66F8\u304F' });
|
|
5606
|
+
return null;
|
|
5607
|
+
}
|
|
5608
|
+
const issues = checkValueExpression(expression, name);
|
|
5609
|
+
if (issues.length > 0) {
|
|
5610
|
+
for (const issue of issues) errors.push({ line: lineNo, ...issue });
|
|
5611
|
+
return null;
|
|
5612
|
+
}
|
|
5613
|
+
return { name, expression, pos: { line: lineNo } };
|
|
5614
|
+
}
|
|
3809
5615
|
function splitTopLevelCommas(s) {
|
|
3810
5616
|
return s.split(",").map((x) => x.trim()).filter(Boolean);
|
|
3811
5617
|
}
|
|
@@ -3929,12 +5735,23 @@ function parseStepHead(s) {
|
|
|
3929
5735
|
function parseFocusList(s) {
|
|
3930
5736
|
let body = s.trim();
|
|
3931
5737
|
if (body.startsWith("[") && body.endsWith("]")) body = body.slice(1, -1);
|
|
3932
|
-
const
|
|
5738
|
+
const groups = [];
|
|
5739
|
+
let group = [];
|
|
3933
5740
|
let buf = "";
|
|
3934
5741
|
let quote = null;
|
|
5742
|
+
const pushFragment = (quoted) => {
|
|
5743
|
+
if (buf.trim()) group.push({ text: buf, quoted });
|
|
5744
|
+
buf = "";
|
|
5745
|
+
};
|
|
5746
|
+
const pushGroup = () => {
|
|
5747
|
+
pushFragment(false);
|
|
5748
|
+
if (group.length > 0) groups.push(group);
|
|
5749
|
+
group = [];
|
|
5750
|
+
};
|
|
3935
5751
|
for (const ch of body) {
|
|
3936
5752
|
if (quote) {
|
|
3937
5753
|
if (ch === quote) {
|
|
5754
|
+
pushFragment(true);
|
|
3938
5755
|
quote = null;
|
|
3939
5756
|
continue;
|
|
3940
5757
|
}
|
|
@@ -3942,41 +5759,49 @@ function parseFocusList(s) {
|
|
|
3942
5759
|
continue;
|
|
3943
5760
|
}
|
|
3944
5761
|
if (ch === '"' || ch === "'") {
|
|
3945
|
-
|
|
3946
|
-
|
|
5762
|
+
if (!buf || /\s$/.test(buf)) {
|
|
5763
|
+
pushFragment(false);
|
|
5764
|
+
quote = ch;
|
|
5765
|
+
continue;
|
|
5766
|
+
}
|
|
3947
5767
|
}
|
|
3948
5768
|
if (ch === ",") {
|
|
3949
|
-
|
|
3950
|
-
if (t) parts.push(t);
|
|
3951
|
-
buf = "";
|
|
5769
|
+
pushGroup();
|
|
3952
5770
|
continue;
|
|
3953
5771
|
}
|
|
3954
5772
|
buf += ch;
|
|
3955
5773
|
}
|
|
3956
|
-
|
|
3957
|
-
if (
|
|
5774
|
+
pushFragment(quote !== null);
|
|
5775
|
+
if (group.length > 0) groups.push(group);
|
|
3958
5776
|
const out = [];
|
|
3959
|
-
for (const
|
|
3960
|
-
|
|
3961
|
-
|
|
5777
|
+
for (const fragments of groups) {
|
|
5778
|
+
const whole = fragments.map(({ text }) => text).join("").trim();
|
|
5779
|
+
if (fragments.every(({ quoted }) => !quoted) && /[-→][>]?/.test(whole) && /\s/.test(whole)) {
|
|
5780
|
+
out.push(whole);
|
|
3962
5781
|
continue;
|
|
3963
5782
|
}
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
5783
|
+
for (const { text, quoted } of fragments) {
|
|
5784
|
+
const p = text.trim();
|
|
5785
|
+
if (!p) continue;
|
|
5786
|
+
if (quoted) {
|
|
5787
|
+
out.push(p);
|
|
5788
|
+
} else {
|
|
5789
|
+
for (const x of p.split(/\s+/)) {
|
|
5790
|
+
if (x) out.push(x);
|
|
5791
|
+
}
|
|
3967
5792
|
}
|
|
3968
|
-
continue;
|
|
3969
5793
|
}
|
|
3970
|
-
out.push(p);
|
|
3971
5794
|
}
|
|
3972
5795
|
return out;
|
|
3973
5796
|
}
|
|
3974
5797
|
function parseTweenLine(s, lineNo) {
|
|
3975
5798
|
const cleaned = s.replace(/^-\s*/, "").trim();
|
|
3976
|
-
const m = cleaned.match(/^([
|
|
5799
|
+
const m = cleaned.match(/^([^:\s]+)\s*[:\s]\s*(-?\d+(?:\.\d+)?)\s*->\s*(-?\d+(?:\.\d+)?)$/);
|
|
3977
5800
|
if (!m) return null;
|
|
5801
|
+
const state = m[1] ?? "";
|
|
5802
|
+
if (!isValueName(state)) return null;
|
|
3978
5803
|
return {
|
|
3979
|
-
state
|
|
5804
|
+
state,
|
|
3980
5805
|
from: parseFloat(m[2] ?? "0"),
|
|
3981
5806
|
to: parseFloat(m[3] ?? "0"),
|
|
3982
5807
|
pos: { line: lineNo }
|
|
@@ -3984,13 +5809,15 @@ function parseTweenLine(s, lineNo) {
|
|
|
3984
5809
|
}
|
|
3985
5810
|
function parseSetLine(s, lineNo) {
|
|
3986
5811
|
const cleaned = s.replace(/^-\s*/, "").trim();
|
|
3987
|
-
const m = cleaned.match(/^([
|
|
5812
|
+
const m = cleaned.match(/^([^:\s]+)\s*[:\s]\s*(.+)$/);
|
|
3988
5813
|
if (!m) return null;
|
|
5814
|
+
const state = m[1] ?? "";
|
|
5815
|
+
if (!isValueName(state)) return null;
|
|
3989
5816
|
const raw = (m[2] ?? "").trim();
|
|
3990
5817
|
const stripped = stripQuotes(raw);
|
|
3991
5818
|
const asNum = Number(stripped);
|
|
3992
5819
|
const value = Number.isFinite(asNum) && stripped !== "" && !isNaN(asNum) ? asNum : stripped;
|
|
3993
|
-
return { state
|
|
5820
|
+
return { state, value, pos: { line: lineNo } };
|
|
3994
5821
|
}
|
|
3995
5822
|
|
|
3996
5823
|
// src/notation-lint.ts
|
|
@@ -4040,7 +5867,6 @@ var KIND_TO_JA = {
|
|
|
4040
5867
|
tree: "\u968E\u5C64\u30C4\u30EA\u30FC",
|
|
4041
5868
|
userJourney: "\u30E6\u30FC\u30B6\u30FC\u30B8\u30E3\u30FC\u30CB\u30FC",
|
|
4042
5869
|
mindMap: "\u30DE\u30A4\u30F3\u30C9\u30DE\u30C3\u30D7",
|
|
4043
|
-
mindMapRadial: "\u653E\u5C04\u72B6\u30DE\u30A4\u30F3\u30C9\u30DE\u30C3\u30D7",
|
|
4044
5870
|
funnel: "\u30D5\u30A1\u30CD\u30EB (\u6BB5\u968E\u5225\u96E2\u8131)",
|
|
4045
5871
|
quadrant: "\u56DB\u8C61\u9650\u30DE\u30C8\u30EA\u30AF\u30B9",
|
|
4046
5872
|
gantt: "\u30AC\u30F3\u30C8\u30C1\u30E3\u30FC\u30C8",
|
|
@@ -4049,7 +5875,7 @@ var KIND_TO_JA = {
|
|
|
4049
5875
|
};
|
|
4050
5876
|
function applyTopicAutoFix(topic) {
|
|
4051
5877
|
const kindMatch = topic.match(
|
|
4052
|
-
/^\s*(chart|flow|swimlane|sequence|topology|er|stateMachine2?|infrastructure|classDiagram|tree|userJourney|mindMap
|
|
5878
|
+
/^\s*(chart|flow|swimlane|sequence|topology|er|stateMachine2?|infrastructure|classDiagram|tree|userJourney|mindMap|funnel|quadrant|gantt|flowchart|network|line chart|pie chart|bar chart)\b/i
|
|
4053
5879
|
);
|
|
4054
5880
|
if (kindMatch) {
|
|
4055
5881
|
const kind = kindMatch[1].toLowerCase();
|
|
@@ -4135,7 +5961,7 @@ function ruleGanttUnknownDependsOn(d) {
|
|
|
4135
5961
|
function ruleMindMapParentReference(d) {
|
|
4136
5962
|
const out = [];
|
|
4137
5963
|
for (const n of d.nodes) {
|
|
4138
|
-
if (
|
|
5964
|
+
if (n.kind === "mind-map" && n.mindData) {
|
|
4139
5965
|
const known = /* @__PURE__ */ new Set([n.mindData.rootId]);
|
|
4140
5966
|
for (const b of n.mindData.branches) known.add(b.id);
|
|
4141
5967
|
for (const b of n.mindData.branches) {
|
|
@@ -4211,7 +6037,10 @@ function ruleFunnelMonotonicCount(d) {
|
|
|
4211
6037
|
if (n.kind === "funnel-stages" && n.funnelData) {
|
|
4212
6038
|
const stages = n.funnelData;
|
|
4213
6039
|
for (let i = 1; i < stages.length; i++) {
|
|
4214
|
-
|
|
6040
|
+
const \u4ECA = stages[i].count;
|
|
6041
|
+
const \u524D = stages[i - 1].count;
|
|
6042
|
+
if (typeof \u4ECA !== "number" || typeof \u524D !== "number") continue;
|
|
6043
|
+
if (\u4ECA > \u524D) {
|
|
4215
6044
|
out.push({
|
|
4216
6045
|
rule: "funnel-increasing-count",
|
|
4217
6046
|
severity: "warn",
|
|
@@ -4299,7 +6128,7 @@ function matchActorHead(line) {
|
|
|
4299
6128
|
indentText: indentText2,
|
|
4300
6129
|
indent: indentText2.length,
|
|
4301
6130
|
rawName: rawName2,
|
|
4302
|
-
name:
|
|
6131
|
+
name: unquote2(rawName2),
|
|
4303
6132
|
hasColon: true,
|
|
4304
6133
|
rest: rest.trimEnd()
|
|
4305
6134
|
};
|
|
@@ -4312,21 +6141,21 @@ function matchActorHead(line) {
|
|
|
4312
6141
|
indentText,
|
|
4313
6142
|
indent: indentText.length,
|
|
4314
6143
|
rawName,
|
|
4315
|
-
name:
|
|
6144
|
+
name: unquote2(rawName),
|
|
4316
6145
|
hasColon: false,
|
|
4317
6146
|
rest: ""
|
|
4318
6147
|
};
|
|
4319
6148
|
}
|
|
4320
|
-
function
|
|
6149
|
+
function unquote2(raw) {
|
|
4321
6150
|
if (!raw.startsWith('"') || !raw.endsWith('"') || raw.length < 2) return raw;
|
|
4322
6151
|
return raw.slice(1, -1).replace(/\\(.)/g, "$1");
|
|
4323
6152
|
}
|
|
4324
6153
|
function upsertAtToken(rest, x, y) {
|
|
4325
|
-
const kept =
|
|
6154
|
+
const kept = splitOutsideQuotes2(rest).filter((t) => !/^@-?\d+(\.\d+)?\s*[,、]\s*-?\d+(\.\d+)?$/.test(t));
|
|
4326
6155
|
kept.push(`@${x},${y}`);
|
|
4327
6156
|
return kept.join(" ");
|
|
4328
6157
|
}
|
|
4329
|
-
function
|
|
6158
|
+
function splitOutsideQuotes2(s) {
|
|
4330
6159
|
const out = [];
|
|
4331
6160
|
let buf = "";
|
|
4332
6161
|
let quote = null;
|
|
@@ -4453,20 +6282,7 @@ var VALID_KIND_SET = /* @__PURE__ */ new Set([
|
|
|
4453
6282
|
"library",
|
|
4454
6283
|
"interface"
|
|
4455
6284
|
]);
|
|
4456
|
-
var VALID_PRESETS = [
|
|
4457
|
-
"sequence",
|
|
4458
|
-
"flow",
|
|
4459
|
-
"swimlane",
|
|
4460
|
-
"er",
|
|
4461
|
-
"state",
|
|
4462
|
-
"topology",
|
|
4463
|
-
"solidity",
|
|
4464
|
-
"gantt",
|
|
4465
|
-
"class",
|
|
4466
|
-
"pie",
|
|
4467
|
-
"c4",
|
|
4468
|
-
"mind"
|
|
4469
|
-
];
|
|
6285
|
+
var VALID_PRESETS = [...PRESET_TYPES];
|
|
4470
6286
|
function validateLayoutPos(v, path, errors) {
|
|
4471
6287
|
if (v === void 0) return;
|
|
4472
6288
|
if (!v || typeof v !== "object" || Array.isArray(v)) {
|
|
@@ -4481,15 +6297,122 @@ function validateLayoutPos(v, path, errors) {
|
|
|
4481
6297
|
errors.push({ path: `${path}.y`, message: "pos.y must be a finite number" });
|
|
4482
6298
|
}
|
|
4483
6299
|
}
|
|
6300
|
+
var \u5199\u3057\u306E\u6700\u5927\u306E\u6DF1\u3055 = 64;
|
|
6301
|
+
var \u5199\u3057\u306E\u6700\u5927\u306E\u9805\u76EE\u6570 = 5e6;
|
|
6302
|
+
var \u5199\u305B\u306A\u3044 = class extends Error {
|
|
6303
|
+
constructor(path, \u7406\u7531) {
|
|
6304
|
+
super(`${path}: ${\u7406\u7531}`);
|
|
6305
|
+
this.path = path;
|
|
6306
|
+
this.\u7406\u7531 = \u7406\u7531;
|
|
6307
|
+
}
|
|
6308
|
+
path;
|
|
6309
|
+
\u7406\u7531;
|
|
6310
|
+
};
|
|
6311
|
+
function \u7D20\u306E\u30C7\u30FC\u30BF\u306B\u5199\u3059(root) {
|
|
6312
|
+
const \u5199\u3057\u6E08 = /* @__PURE__ */ new WeakMap();
|
|
6313
|
+
let \u9805\u76EE\u6570 = 0;
|
|
6314
|
+
let \u8AAD\u3093\u3067\u3044\u308B\u5834\u6240 = "$";
|
|
6315
|
+
const \u5668\u3092\u4F5C\u308B = (v, \u6DF1\u3055, path) => {
|
|
6316
|
+
\u9805\u76EE\u6570 += 1;
|
|
6317
|
+
if (\u9805\u76EE\u6570 > \u5199\u3057\u306E\u6700\u5927\u306E\u9805\u76EE\u6570) {
|
|
6318
|
+
throw new \u5199\u305B\u306A\u3044(path, `\u9805\u76EE\u304C\u591A\u3059\u304E\u308B (\u4E0A\u9650 ${\u5199\u3057\u306E\u6700\u5927\u306E\u9805\u76EE\u6570})`);
|
|
6319
|
+
}
|
|
6320
|
+
if (v === null || typeof v !== "object") return { \u5024: v, \u67A0: null };
|
|
6321
|
+
const \u65E2\u306B\u3042\u308B = \u5199\u3057\u6E08.get(v);
|
|
6322
|
+
if (\u65E2\u306B\u3042\u308B !== void 0) return { \u5024: \u65E2\u306B\u3042\u308B, \u67A0: null };
|
|
6323
|
+
if (\u6DF1\u3055 >= \u5199\u3057\u306E\u6700\u5927\u306E\u6DF1\u3055) {
|
|
6324
|
+
throw new \u5199\u305B\u306A\u3044(path, `\u5165\u308C\u5B50\u304C\u6DF1\u3059\u304E\u308B (\u4E0A\u9650 ${\u5199\u3057\u306E\u6700\u5927\u306E\u6DF1\u3055})`);
|
|
6325
|
+
}
|
|
6326
|
+
\u8AAD\u3093\u3067\u3044\u308B\u5834\u6240 = path;
|
|
6327
|
+
const \u4E26\u3073\u304B = Array.isArray(v);
|
|
6328
|
+
const \u5668 = \u4E26\u3073\u304B ? [] : {};
|
|
6329
|
+
\u5199\u3057\u6E08.set(v, \u5668);
|
|
6330
|
+
if (\u4E26\u3073\u304B) {
|
|
6331
|
+
const \u751F\u306E\u9577\u3055 = +v.length;
|
|
6332
|
+
const \u9577\u3055 = Number.isNaN(\u751F\u306E\u9577\u3055) ? 0 : Math.min(Math.max(Math.trunc(\u751F\u306E\u9577\u3055), 0), Number.MAX_SAFE_INTEGER);
|
|
6333
|
+
\u9805\u76EE\u6570 += \u9577\u3055;
|
|
6334
|
+
if (\u9805\u76EE\u6570 > \u5199\u3057\u306E\u6700\u5927\u306E\u9805\u76EE\u6570) {
|
|
6335
|
+
throw new \u5199\u305B\u306A\u3044(path, `\u9805\u76EE\u304C\u591A\u3059\u304E\u308B (\u4E0A\u9650 ${\u5199\u3057\u306E\u6700\u5927\u306E\u9805\u76EE\u6570})`);
|
|
6336
|
+
}
|
|
6337
|
+
return { \u5024: \u5668, \u67A0: { \u5143: v, \u5668, \u540D\u524D\u306E\u4E26\u3073: null, \u9577\u3055, \u6B21: 0, \u6DF1\u3055, path } };
|
|
6338
|
+
}
|
|
6339
|
+
const \u540D\u524D\u306E\u4E26\u3073 = Object.keys(v);
|
|
6340
|
+
\u9805\u76EE\u6570 += \u540D\u524D\u306E\u4E26\u3073.length;
|
|
6341
|
+
if (\u9805\u76EE\u6570 > \u5199\u3057\u306E\u6700\u5927\u306E\u9805\u76EE\u6570) {
|
|
6342
|
+
throw new \u5199\u305B\u306A\u3044(path, `\u9805\u76EE\u304C\u591A\u3059\u304E\u308B (\u4E0A\u9650 ${\u5199\u3057\u306E\u6700\u5927\u306E\u9805\u76EE\u6570})`);
|
|
6343
|
+
}
|
|
6344
|
+
return { \u5024: \u5668, \u67A0: { \u5143: v, \u5668, \u540D\u524D\u306E\u4E26\u3073, \u9577\u3055: \u540D\u524D\u306E\u4E26\u3073.length, \u6B21: 0, \u6DF1\u3055, path } };
|
|
6345
|
+
};
|
|
6346
|
+
try {
|
|
6347
|
+
const \u5148\u982D = \u5668\u3092\u4F5C\u308B(root, 0, "$");
|
|
6348
|
+
const \u7A4D\u307F = \u5148\u982D.\u67A0 ? [\u5148\u982D.\u67A0] : [];
|
|
6349
|
+
while (\u7A4D\u307F.length > 0) {
|
|
6350
|
+
const \u4ECA = \u7A4D\u307F[\u7A4D\u307F.length - 1];
|
|
6351
|
+
if (\u4ECA.\u6B21 >= \u4ECA.\u9577\u3055) {
|
|
6352
|
+
\u7A4D\u307F.pop();
|
|
6353
|
+
continue;
|
|
6354
|
+
}
|
|
6355
|
+
const key = \u4ECA.\u540D\u524D\u306E\u4E26\u3073 === null ? String(\u4ECA.\u6B21) : \u4ECA.\u540D\u524D\u306E\u4E26\u3073[\u4ECA.\u6B21];
|
|
6356
|
+
\u4ECA.\u6B21 += 1;
|
|
6357
|
+
const \u5B50\u306Epath = \u4ECA.\u540D\u524D\u306E\u4E26\u3073 === null ? `${\u4ECA.path}[${key}]` : `${\u4ECA.path}.${key}`;
|
|
6358
|
+
\u8AAD\u3093\u3067\u3044\u308B\u5834\u6240 = \u5B50\u306Epath;
|
|
6359
|
+
const \u751F\u306E\u5024 = \u4ECA.\u5143[key];
|
|
6360
|
+
const \u5B50 = \u5668\u3092\u4F5C\u308B(\u751F\u306E\u5024, \u4ECA.\u6DF1\u3055 + 1, \u5B50\u306Epath);
|
|
6361
|
+
if (Array.isArray(\u4ECA.\u5668)) \u4ECA.\u5668.push(\u5B50.\u5024);
|
|
6362
|
+
else {
|
|
6363
|
+
Object.defineProperty(\u4ECA.\u5668, key, {
|
|
6364
|
+
value: \u5B50.\u5024,
|
|
6365
|
+
enumerable: true,
|
|
6366
|
+
writable: true,
|
|
6367
|
+
configurable: true
|
|
6368
|
+
});
|
|
6369
|
+
}
|
|
6370
|
+
if (\u5B50.\u67A0) \u7A4D\u307F.push(\u5B50.\u67A0);
|
|
6371
|
+
}
|
|
6372
|
+
return { ok: true, value: \u5148\u982D.\u5024 };
|
|
6373
|
+
} catch (e) {
|
|
6374
|
+
if (e instanceof \u5199\u305B\u306A\u3044) {
|
|
6375
|
+
return { ok: false, error: { path: e.path, message: e.\u7406\u7531 } };
|
|
6376
|
+
}
|
|
6377
|
+
return {
|
|
6378
|
+
ok: false,
|
|
6379
|
+
error: {
|
|
6380
|
+
path: \u8AAD\u3093\u3067\u3044\u308B\u5834\u6240,
|
|
6381
|
+
message: "\u5165\u529B\u3092\u8AAD\u307F\u53D6\u308C\u306A\u3044",
|
|
6382
|
+
hint: e instanceof Error ? e.message : String(e)
|
|
6383
|
+
}
|
|
6384
|
+
};
|
|
6385
|
+
}
|
|
6386
|
+
}
|
|
4484
6387
|
function validateJson(json) {
|
|
4485
6388
|
const errors = [];
|
|
4486
|
-
|
|
6389
|
+
let root\u304Cobject\u304B;
|
|
6390
|
+
try {
|
|
6391
|
+
root\u304Cobject\u304B = !!json && typeof json === "object" && !Array.isArray(json);
|
|
6392
|
+
} catch (e) {
|
|
6393
|
+
return {
|
|
6394
|
+
ok: false,
|
|
6395
|
+
errors: [
|
|
6396
|
+
{
|
|
6397
|
+
path: "$",
|
|
6398
|
+
message: "\u5165\u529B\u3092\u8AAD\u307F\u53D6\u308C\u306A\u3044",
|
|
6399
|
+
hint: e instanceof Error ? e.message : String(e)
|
|
6400
|
+
}
|
|
6401
|
+
]
|
|
6402
|
+
};
|
|
6403
|
+
}
|
|
6404
|
+
if (!root\u304Cobject\u304B) {
|
|
4487
6405
|
return { ok: false, errors: [{ path: "$", message: "root must be a JSON object" }] };
|
|
4488
6406
|
}
|
|
4489
|
-
const
|
|
6407
|
+
const \u5199\u3057 = \u7D20\u306E\u30C7\u30FC\u30BF\u306B\u5199\u3059(json);
|
|
6408
|
+
if (!\u5199\u3057.ok) return { ok: false, errors: [\u5199\u3057.error] };
|
|
6409
|
+
const j = \u5199\u3057.value;
|
|
4490
6410
|
if (typeof j.title !== "string" || j.title.length === 0) {
|
|
4491
6411
|
errors.push({ path: "$.title", message: "title must be a non-empty string" });
|
|
4492
6412
|
}
|
|
6413
|
+
if (j.eyebrow !== void 0 && typeof j.eyebrow !== "string") {
|
|
6414
|
+
errors.push({ path: "$.eyebrow", message: "eyebrow must be a string if present" });
|
|
6415
|
+
}
|
|
4493
6416
|
if (j.layout !== void 0 && j.layout !== "auto" && j.layout !== "manual") {
|
|
4494
6417
|
errors.push({ path: "$.layout", message: 'layout must be "auto" or "manual" if present' });
|
|
4495
6418
|
}
|
|
@@ -4569,12 +6492,109 @@ function validateJson(json) {
|
|
|
4569
6492
|
if (typeof po.step !== "string" || po.step.length === 0) {
|
|
4570
6493
|
errors.push({ path: `$.animation[${i}].step`, message: "phase.step must be a non-empty string" });
|
|
4571
6494
|
}
|
|
6495
|
+
validatePhaseMotion(po, i, errors);
|
|
4572
6496
|
});
|
|
4573
6497
|
}
|
|
4574
6498
|
}
|
|
6499
|
+
validateStates(j.states, errors);
|
|
6500
|
+
validateValues(j.values, errors);
|
|
4575
6501
|
if (errors.length > 0) return { ok: false, errors };
|
|
4576
6502
|
return { ok: true, data: j };
|
|
4577
6503
|
}
|
|
6504
|
+
function validatePhaseMotion(po, i, errors) {
|
|
6505
|
+
if (po.tween !== void 0) {
|
|
6506
|
+
if (!po.tween || typeof po.tween !== "object" || Array.isArray(po.tween)) {
|
|
6507
|
+
errors.push({
|
|
6508
|
+
path: `$.animation[${i}].tween`,
|
|
6509
|
+
message: "tween must be a plain object of state -> [from, to]"
|
|
6510
|
+
});
|
|
6511
|
+
} else {
|
|
6512
|
+
for (const [name, range] of Object.entries(po.tween)) {
|
|
6513
|
+
const path = `$.animation[${i}].tween.${name}`;
|
|
6514
|
+
if (!isValueName(name)) errors.push({ path, ...valueNameIssue(name) });
|
|
6515
|
+
if (!Array.isArray(range) || range.length !== 2) {
|
|
6516
|
+
errors.push({ path, message: "tween value must be [from, to]" });
|
|
6517
|
+
continue;
|
|
6518
|
+
}
|
|
6519
|
+
for (const v of range) {
|
|
6520
|
+
if (typeof v !== "number" || !Number.isFinite(v)) {
|
|
6521
|
+
errors.push({ path, message: "tween value must be finite numbers", hint: `got ${typeof v}` });
|
|
6522
|
+
break;
|
|
6523
|
+
}
|
|
6524
|
+
}
|
|
6525
|
+
}
|
|
6526
|
+
}
|
|
6527
|
+
}
|
|
6528
|
+
if (po.set !== void 0) {
|
|
6529
|
+
if (!po.set || typeof po.set !== "object" || Array.isArray(po.set)) {
|
|
6530
|
+
errors.push({
|
|
6531
|
+
path: `$.animation[${i}].set`,
|
|
6532
|
+
message: "set must be a plain object of state -> value"
|
|
6533
|
+
});
|
|
6534
|
+
} else {
|
|
6535
|
+
for (const [name, value] of Object.entries(po.set)) {
|
|
6536
|
+
const path = `$.animation[${i}].set.${name}`;
|
|
6537
|
+
if (!isValueName(name)) errors.push({ path, ...valueNameIssue(name) });
|
|
6538
|
+
const t = typeof value;
|
|
6539
|
+
if (t !== "number" && t !== "string") {
|
|
6540
|
+
errors.push({ path, message: "set value must be a number or string", hint: `got ${t}` });
|
|
6541
|
+
} else if (t === "number" && !Number.isFinite(value)) {
|
|
6542
|
+
errors.push({ path, message: "set value must be a finite number" });
|
|
6543
|
+
}
|
|
6544
|
+
}
|
|
6545
|
+
}
|
|
6546
|
+
}
|
|
6547
|
+
}
|
|
6548
|
+
function validateStates(v, errors) {
|
|
6549
|
+
if (v === void 0) return;
|
|
6550
|
+
if (!v || typeof v !== "object" || Array.isArray(v)) {
|
|
6551
|
+
errors.push({ path: "$.states", message: "states must be a plain object of name -> initial value" });
|
|
6552
|
+
return;
|
|
6553
|
+
}
|
|
6554
|
+
for (const [name, initial] of Object.entries(v)) {
|
|
6555
|
+
if (!isValueName(name)) {
|
|
6556
|
+
errors.push({ path: `$.states.${name}`, ...valueNameIssue(name) });
|
|
6557
|
+
}
|
|
6558
|
+
const t = typeof initial;
|
|
6559
|
+
if (t !== "number" && t !== "string") {
|
|
6560
|
+
errors.push({
|
|
6561
|
+
path: `$.states.${name}`,
|
|
6562
|
+
message: "state initial must be a number or string",
|
|
6563
|
+
hint: `got ${t}`
|
|
6564
|
+
});
|
|
6565
|
+
} else if (t === "number" && !Number.isFinite(initial)) {
|
|
6566
|
+
errors.push({ path: `$.states.${name}`, message: "state initial must be a finite number" });
|
|
6567
|
+
}
|
|
6568
|
+
}
|
|
6569
|
+
}
|
|
6570
|
+
function validateValues(v, errors) {
|
|
6571
|
+
if (v === void 0) return;
|
|
6572
|
+
if (!v || typeof v !== "object" || Array.isArray(v)) {
|
|
6573
|
+
errors.push({ path: "$.values", message: "values must be a plain object of name -> expression" });
|
|
6574
|
+
return;
|
|
6575
|
+
}
|
|
6576
|
+
for (const [name, expression] of Object.entries(v)) {
|
|
6577
|
+
if (!isValueName(name)) {
|
|
6578
|
+
errors.push({ path: `$.values.${name}`, ...valueNameIssue(name) });
|
|
6579
|
+
}
|
|
6580
|
+
if (typeof expression !== "string" || expression.trim() === "") {
|
|
6581
|
+
errors.push({
|
|
6582
|
+
path: `$.values.${name}`,
|
|
6583
|
+
message: "value expression must be a non-empty string",
|
|
6584
|
+
hint: '`"{inflow} - {done}"` \u306E\u5F62\u3067\u66F8\u304F'
|
|
6585
|
+
});
|
|
6586
|
+
continue;
|
|
6587
|
+
}
|
|
6588
|
+
for (const issue of checkValueExpression(expression, name)) {
|
|
6589
|
+
errors.push({ path: `$.values.${name}`, ...issue });
|
|
6590
|
+
}
|
|
6591
|
+
}
|
|
6592
|
+
}
|
|
6593
|
+
function \u6574\u3048\u305F\u5C0F\u898B\u51FA\u3057(v) {
|
|
6594
|
+
if (v === void 0) return void 0;
|
|
6595
|
+
const t = v.trim();
|
|
6596
|
+
return t.length > 0 ? t : void 0;
|
|
6597
|
+
}
|
|
4578
6598
|
function jsonToDoc(json) {
|
|
4579
6599
|
const p0 = { line: 0 };
|
|
4580
6600
|
const actors = json.actors.map((a) => {
|
|
@@ -4616,28 +6636,44 @@ function jsonToDoc(json) {
|
|
|
4616
6636
|
cardinality: s.cardinality,
|
|
4617
6637
|
labelOffsetX: s.labelOffsetX,
|
|
4618
6638
|
labelOffsetY: s.labelOffsetY,
|
|
6639
|
+
overlay: s.overlay,
|
|
4619
6640
|
// CAR-1693 Phase 1: DSL 表面 pos → 内部 AST layoutPos
|
|
4620
6641
|
layoutPos: s.pos,
|
|
4621
6642
|
pos: p0
|
|
4622
6643
|
}));
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4626
|
-
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
|
|
6644
|
+
const states = Object.entries(json.states ?? {}).map(([name, initial]) => ({
|
|
6645
|
+
name,
|
|
6646
|
+
initial,
|
|
6647
|
+
pos: p0
|
|
6648
|
+
}));
|
|
6649
|
+
const phases = (json.animation ?? []).map((p) => ({
|
|
6650
|
+
name: p.step,
|
|
6651
|
+
durationMs: Math.round((p.duration ?? 1.4) * 1e3),
|
|
6652
|
+
highlight: p.focus,
|
|
6653
|
+
body: p.body,
|
|
6654
|
+
badge: p.badge,
|
|
6655
|
+
// 段の中で動かす分 (#1186)。 記法側の `tweens` / `sets` と同じ形に写す。
|
|
6656
|
+
// 空の配列を置かないのは、記法側が「無ければ field ごと持たない」 形だから
|
|
6657
|
+
...p.tween && Object.keys(p.tween).length > 0 ? {
|
|
6658
|
+
tweens: Object.entries(p.tween).map(([state, [from, to]]) => ({ state, from, to, pos: p0 }))
|
|
6659
|
+
} : {},
|
|
6660
|
+
...p.set && Object.keys(p.set).length > 0 ? { sets: Object.entries(p.set).map(([state, value]) => ({ state, value, pos: p0 })) } : {},
|
|
6661
|
+
pos: p0
|
|
6662
|
+
}));
|
|
6663
|
+
const animate = states.length > 0 || phases.length > 0 ? { states, phases, pos: p0 } : void 0;
|
|
4635
6664
|
return {
|
|
4636
6665
|
title: json.title,
|
|
4637
6666
|
type: json.type,
|
|
6667
|
+
// 前後の空白を落としてから見る。 記法側 (`v05/parser.ts`) が `trim()` してから
|
|
6668
|
+
// 空かどうかを判定するため、 揃えないと **空白だけの値で入口ごとに図が変わる**
|
|
6669
|
+
// (記法は書かなかった扱い、 JSON は中身のない帯を描く。 Round 2 の指摘で実測)
|
|
6670
|
+
...\u6574\u3048\u305F\u5C0F\u898B\u51FA\u3057(json.eyebrow) !== void 0 ? { eyebrow: \u6574\u3048\u305F\u5C0F\u898B\u51FA\u3057(json.eyebrow), eyebrowPos: p0 } : {},
|
|
4638
6671
|
actors,
|
|
4639
6672
|
flow: flow2,
|
|
4640
6673
|
animate,
|
|
6674
|
+
// 他の値から決まる値 (#1181)。 書いた順に並べる = 解く順は参照から決まるので順序に
|
|
6675
|
+
// 意味は無いが、知らせの並びが書いた順になる
|
|
6676
|
+
values: json.values ? Object.entries(json.values).map(([name, expression]) => ({ name, expression, pos: p0 })) : void 0,
|
|
4641
6677
|
viewport: json.viewport ? { ...json.viewport, pos: p0 } : void 0,
|
|
4642
6678
|
lanes: json.lanes ? Object.fromEntries(
|
|
4643
6679
|
Object.entries(json.lanes).map(([id, l]) => {
|
|
@@ -4684,8 +6720,12 @@ var diagram_default = {
|
|
|
4684
6720
|
},
|
|
4685
6721
|
type: {
|
|
4686
6722
|
type: "string",
|
|
4687
|
-
enum: ["sequence", "flow", "swimlane", "er", "state", "topology", "solidity", "gantt", "class", "pie", "c4", "mind"],
|
|
4688
|
-
description:
|
|
6723
|
+
enum: ["sequence", "flow", "swimlane", "er", "state", "topology", "solidity", "gantt", "class", "pie", "bar", "line", "funnel", "tree", "journey", "quadrant", "c4", "mind"],
|
|
6724
|
+
description: '\u56F3\u306E\u7A2E\u985E\u3002 \u578B\u3054\u3068\u306B actors \u306E\u66F8\u304D\u65B9\u304C\u9055\u3046\u3002 [\u95A2\u4FC2\u3092\u63CF\u304F] sequence (\u6642\u7CFB\u5217\u306E\u547C\u3073\u51FA\u3057) / flow (\u51E6\u7406\u306E\u6D41\u308C) / swimlane (\u8CAC\u52D9\u3054\u3068\u306E\u6D41\u308C) / er (DB \u306E schema) / state (\u72B6\u614B\u306E\u9077\u79FB) / topology (network) / solidity (contract) / class (UML \u306E class) / c4 (architecture) / mind (\u767A\u60F3\u306E\u679D\u5206\u304B\u308C) \u306F actors \u306B\u540D\u524D\u3092\u4E26\u3079 flow \u306B\u77E2\u5370\u3092\u66F8\u304F\u3002 [\u5024\u3092\u63CF\u304F] pie (\u5272\u5408) / bar (\u68D2\u306E\u9AD8\u3055) / line (\u7DDA\u306E\u9AD8\u3055\u3001 \u66F8\u3044\u305F\u9806\u306B\u4E26\u3076) \u306F actors \u306B `- \u540D\u524D: "45"` \u306E\u5F62\u3067\u6570\u3092\u66F8\u304F\u3002 funnel (\u6BB5\u3054\u3068\u306B\u6E1B\u308B\u6570) \u3082\u540C\u3058\u5F62\u3002 [\u8A9E\u3092\u63CF\u304F] journey (\u4F53\u9A13\u306E\u8D77\u4F0F) \u306F `- \u767B\u9332: "\u4E0D\u6E80"` \u306E\u5F62\u3067 \u6700\u9AD8 / \u6E80\u8DB3 / \u666E\u901A / \u4E0D\u6E80 / \u6012\u308A \u306E\u3069\u308C\u304B\u3092\u66F8\u304F\u3002 quadrant (2 \u8EF8\u306E\u4ED5\u5206\u3051) \u306F `- \u91CD\u8907\u524A\u9664: "\u5DE6\u4E0A"` \u306E\u5F62\u3067 \u5DE6\u4E0A / \u53F3\u4E0A / \u5DE6\u4E0B / \u53F3\u4E0B \u306E\u3069\u308C\u304B\u3092\u66F8\u304F\u3002 [\u6642\u671F\u3092\u63CF\u304F] gantt (\u5DE5\u7A0B\u306E\u4E26\u3073) \u306F `- \u8A2D\u8A08: "1\u6708"` \u306E\u5F62\u3067\u59CB\u307E\u308A\u306E\u6642\u671F\u3092\u66F8\u304D\u3001 flow \u306E\u77E2\u5370\u3067\u524D\u5F8C\u95A2\u4FC2\u3092\u66F8\u304F\u3002 [\u89AA\u5B50\u3092\u63CF\u304F] tree (\u89AA\u5B50\u306E\u5165\u308C\u5B50) \u306F actors \u306B\u540D\u524D\u3092\u4E26\u3079 flow \u306E\u77E2\u5370\u3067\u89AA\u5B50\u3092\u66F8\u304F (\u77E2\u5370\u306E\u5148\u304C\u5B50)'
|
|
6725
|
+
},
|
|
6726
|
+
eyebrow: {
|
|
6727
|
+
type: "string",
|
|
6728
|
+
description: "\u56F3\u8868\u306E\u7BB1\u306E\u4E0A\u306B\u51FA\u3059\u5C0F\u898B\u51FA\u3057 (\u7701\u7565\u53EF)\u3002 \u52B9\u304F\u306E\u306F\u56F3\u5168\u4F53\u3092 1 \u7BB1\u306B\u3059\u308B\u578B (pie / bar / line / funnel / tree / journey / quadrant / mind / gantt) \u3060\u3051\u3002 \u7BB1\u3054\u3068\u306B\u5206\u304B\u308C\u308B\u578B\u3067\u306F\u76F8\u624B\u304C\u6C7A\u307E\u3089\u306A\u3044\u305F\u3081\u3001 actors[].eyebrow \u306B\u66F8\u304F"
|
|
4689
6729
|
},
|
|
4690
6730
|
actors: {
|
|
4691
6731
|
type: "array",
|
|
@@ -4737,13 +6777,39 @@ var diagram_default = {
|
|
|
4737
6777
|
guard: { type: "string", description: "state \u9077\u79FB\u306E\u6761\u4EF6 (kind: state \u7528)" },
|
|
4738
6778
|
cardinality: { type: "string", description: "ER \u306E\u591A\u91CD\u5EA6 (1..N \u7B49\u3001 kind: er \u7528)" },
|
|
4739
6779
|
labelOffsetX: { type: "number", description: "\u30E9\u30D9\u30EB\u4F4D\u7F6E x \u8ABF\u6574" },
|
|
4740
|
-
labelOffsetY: { type: "number", description: "\u30E9\u30D9\u30EB\u4F4D\u7F6E y \u8ABF\u6574" }
|
|
6780
|
+
labelOffsetY: { type: "number", description: "\u30E9\u30D9\u30EB\u4F4D\u7F6E y \u8ABF\u6574" },
|
|
6781
|
+
overlay: { type: "boolean", description: "true \u3067\u8AAC\u660E\u6587\u3092\u77E2\u5370\u306E\u7DDA\u306E\u4E0A\u306B\u91CD\u306D\u308B (\u5206\u5C90\u56F3\u306E\u6761\u4EF6\u30E9\u30D9\u30EB\u7528)" }
|
|
4741
6782
|
}
|
|
4742
6783
|
}
|
|
4743
6784
|
},
|
|
6785
|
+
states: {
|
|
6786
|
+
type: "object",
|
|
6787
|
+
description: "\u72B6\u614B\u306E\u521D\u671F\u5024\u3002 \u540D\u524D -> \u521D\u671F\u5024 \u306E object\u3002 optional\u3002 \u7BB1\u306E\u6587\u5B57\u306B `{\u540D\u524D}` \u3092\u7F6E\u304F\u3068\u3001 \u3053\u3053\u306B\u66F8\u3044\u305F\u5024\u304C\u63CF\u753B\u6642\u306B\u7F6E\u304D\u63DB\u308F\u308B\u3002 \u6BB5\u3067\u52D5\u304B\u3059\u306B\u306F animation[].tween / animation[].set \u3092\u4F7F\u3046\u3002",
|
|
6788
|
+
additionalProperties: false,
|
|
6789
|
+
patternProperties: {
|
|
6790
|
+
"^[a-zA-Z_][a-zA-Z0-9_]*$": {
|
|
6791
|
+
type: ["number", "string"],
|
|
6792
|
+
description: "\u521D\u671F\u5024\u3002 \u6570\u304B\u6587\u5B57\u5217\u3002 \u540D\u524D\u306F\u82F1\u5B57\u304B _ \u3067\u59CB\u3081\u3001 \u82F1\u6570\u5B57\u3068 _ \u3060\u3051\u3092\u4F7F\u3046"
|
|
6793
|
+
}
|
|
6794
|
+
},
|
|
6795
|
+
examples: [{ inflow: 0, done: 0 }]
|
|
6796
|
+
},
|
|
6797
|
+
values: {
|
|
6798
|
+
type: "object",
|
|
6799
|
+
description: "\u4ED6\u306E\u5024\u304B\u3089\u81EA\u52D5\u3067\u6C7A\u307E\u308B\u5024\u3002 \u540D\u524D -> \u5F0F \u306E object\u3002 optional\u3002 \u5F0F\u306B\u306F\u56DB\u5247 (+ - * /) \u3068\u62EC\u5F27\u3001 \u6BD4\u8F03 (> >= < <= == !=)\u3001 min / max \u304C\u66F8\u3051\u308B\u3002 \u4ED6\u306E\u5024\u306F {\u540D\u524D} \u3067\u8AAD\u3080\u3002 \u89E3\u304F\u306E\u306F\u63CF\u753B\u5074\u3067\u3001 \u53C2\u7167\u3057\u305F\u5024\u304C\u52D5\u3051\u3070\u8FFD\u968F\u3059\u308B\u3002",
|
|
6800
|
+
additionalProperties: false,
|
|
6801
|
+
patternProperties: {
|
|
6802
|
+
"^[a-zA-Z_][a-zA-Z0-9_]*$": {
|
|
6803
|
+
type: "string",
|
|
6804
|
+
minLength: 1,
|
|
6805
|
+
description: "\u5F0F\u3002 \u4F8B `{inflow} - {done}`"
|
|
6806
|
+
}
|
|
6807
|
+
},
|
|
6808
|
+
examples: [{ waiting: "{inflow} - {done}", busy: "{waiting} > 80" }]
|
|
6809
|
+
},
|
|
4744
6810
|
animation: {
|
|
4745
6811
|
type: "array",
|
|
4746
|
-
description: "\u30A2\u30CB\u30E1\u30FC\u30B7\u30E7\u30F3 phase \u914D\u5217\u3002 \u5404 phase \u3067 focus \u5BFE\u8C61\u3092 highlight \u3059\
|
|
6812
|
+
description: "\u30A2\u30CB\u30E1\u30FC\u30B7\u30E7\u30F3 phase \u914D\u5217\u3002 \u5404 phase \u3067 focus \u5BFE\u8C61\u3092 highlight \u3057\u3001 tween / set \u3067 states \u306E\u5024\u3092\u52D5\u304B\u3059\u3002 optional\u3002",
|
|
4747
6813
|
items: {
|
|
4748
6814
|
type: "object",
|
|
4749
6815
|
required: ["step"],
|
|
@@ -4753,7 +6819,28 @@ var diagram_default = {
|
|
|
4753
6819
|
duration: { type: "number", minimum: 0.1, description: "phase \u6642\u9593 (\u79D2\u3001 default 1.4)" },
|
|
4754
6820
|
focus: { type: "array", items: { type: "string" }, description: "\u3053\u306E phase \u3067 active \u5316\u3059\u308B actor \u540D or edge 'A -> B' \u306E\u914D\u5217" },
|
|
4755
6821
|
body: { type: "string", description: "phase \u8AAC\u660E\u6587" },
|
|
4756
|
-
badge: { type: "string", description: "phase \u4E2D\u306B\u8868\u793A\u3059\u308B badge label" }
|
|
6822
|
+
badge: { type: "string", description: "phase \u4E2D\u306B\u8868\u793A\u3059\u308B badge label" },
|
|
6823
|
+
tween: {
|
|
6824
|
+
type: "object",
|
|
6825
|
+
description: "\u3053\u306E phase \u3067\u88DC\u9593\u3059\u308B\u72B6\u614B\u3002 \u72B6\u614B\u540D -> [\u958B\u59CB\u5024, \u7D42\u4E86\u5024]\u3002 \u540D\u524D\u306F\u82F1\u5B57\u304B _ \u3067\u59CB\u3081\u3001 \u82F1\u6570\u5B57\u3068 _ \u3060\u3051\u3092\u4F7F\u3046",
|
|
6826
|
+
additionalProperties: false,
|
|
6827
|
+
patternProperties: {
|
|
6828
|
+
"^[a-zA-Z_][a-zA-Z0-9_]*$": {
|
|
6829
|
+
type: "array",
|
|
6830
|
+
items: { type: "number" },
|
|
6831
|
+
minItems: 2,
|
|
6832
|
+
maxItems: 2
|
|
6833
|
+
}
|
|
6834
|
+
}
|
|
6835
|
+
},
|
|
6836
|
+
set: {
|
|
6837
|
+
type: "object",
|
|
6838
|
+
description: "\u3053\u306E phase \u306E\u5207\u66FF\u3067\u5DEE\u3057\u66FF\u3048\u308B\u72B6\u614B\u3002 \u72B6\u614B\u540D -> \u5024\u3002 \u540D\u524D\u306F\u82F1\u5B57\u304B _ \u3067\u59CB\u3081\u3001 \u82F1\u6570\u5B57\u3068 _ \u3060\u3051\u3092\u4F7F\u3046",
|
|
6839
|
+
additionalProperties: false,
|
|
6840
|
+
patternProperties: {
|
|
6841
|
+
"^[a-zA-Z_][a-zA-Z0-9_]*$": { type: ["number", "string"] }
|
|
6842
|
+
}
|
|
6843
|
+
}
|
|
4757
6844
|
}
|
|
4758
6845
|
}
|
|
4759
6846
|
},
|
|
@@ -4876,6 +6963,7 @@ exports.NODE_KIND_VALID = NODE_KIND_VALID;
|
|
|
4876
6963
|
exports.PRESET_TYPES = PRESET_TYPES;
|
|
4877
6964
|
exports.RELATIVE_GAP_DEFAULT = RELATIVE_GAP_DEFAULT;
|
|
4878
6965
|
exports.TONE_ALIAS = TONE_ALIAS;
|
|
6966
|
+
exports.TOP_LEVEL_KEYS = TOP_LEVEL_KEYS;
|
|
4879
6967
|
exports.autoFix = autoFix;
|
|
4880
6968
|
exports.compileToCdl = compileToCdl;
|
|
4881
6969
|
exports.computeDiagramBoundingBox = computeDiagramBoundingBox;
|