sysml-diagram 0.14.5 → 0.15.1
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/out/main.js +1055 -282
- package/out/main.js.map +3 -3
- package/package.json +1 -2
- package/resources/sysml.dimension-table.json +1 -1
package/out/main.js
CHANGED
|
@@ -133689,6 +133689,9 @@ function isExhibitStateDecl(item) {
|
|
|
133689
133689
|
var ExitAction = "ExitAction";
|
|
133690
133690
|
var ExposeMember = "ExposeMember";
|
|
133691
133691
|
var ExposePath = "ExposePath";
|
|
133692
|
+
function isExposePath(item) {
|
|
133693
|
+
return reflection2.isInstance(item, ExposePath);
|
|
133694
|
+
}
|
|
133692
133695
|
var ExpressionDecl = "ExpressionDecl";
|
|
133693
133696
|
var FeatureDecl = "FeatureDecl";
|
|
133694
133697
|
function isFeatureDecl(item) {
|
|
@@ -161748,6 +161751,12 @@ function keywordFor(node) {
|
|
|
161748
161751
|
const parallel = isParallelState(node) ? "parallel " : "";
|
|
161749
161752
|
const leadMods = [variability, temporal].filter(Boolean);
|
|
161750
161753
|
const prefix = leadMods.length ? leadMods.map((m) => `${m} `).join("") : parallel;
|
|
161754
|
+
if (t === "BareDefDecl")
|
|
161755
|
+
return `${prefix}def`.trim();
|
|
161756
|
+
if (t === "FeatureShorthand") {
|
|
161757
|
+
const kinds = (Array.isArray(n2.usageKinds) ? n2.usageKinds : []).join(" ");
|
|
161758
|
+
return `${prefix}${kinds}`.trim() || "feature";
|
|
161759
|
+
}
|
|
161751
161760
|
if (t === "ActorDecl" || t === "SubjectDecl" || t === "StakeholderDecl")
|
|
161752
161761
|
return `${prefix}${word}`;
|
|
161753
161762
|
return def ? `${prefix}${word} def` : `${prefix}${word}`;
|
|
@@ -161756,7 +161765,39 @@ var isDefinitionKind = (node) => isPartDecl(node) || isPortDecl(node) || isItemD
|
|
|
161756
161765
|
// genuine SysML definitions (FlowConnectionDefinition / AssociationStructure /
|
|
161757
161766
|
// AllocationDefinition) and belong in the General View like any other def.
|
|
161758
161767
|
isFlowStmt(node) || isConnectorDecl(node) || isAllocationDecl(node) || isConstraintDecl(node) || isEnumDecl(node) || isStateDecl(node) || isActionDecl(node) || isCalcDecl(node) || isConcernDecl(node) || isViewDecl(node) || isViewpointDecl(node) || isRenderingDecl(node) || isMetadataDecl(node);
|
|
161759
|
-
var
|
|
161768
|
+
var isBareDefDecl = (node) => node.$type === "BareDefDecl";
|
|
161769
|
+
var isDefinitionNode = (node) => isDefinitionKind(node) && node.isDef === true || isBareDefDecl(node);
|
|
161770
|
+
var modifiersOf = (node) => {
|
|
161771
|
+
const mods = node.modifiers;
|
|
161772
|
+
return Array.isArray(mods) ? mods : [];
|
|
161773
|
+
};
|
|
161774
|
+
var portionKindOf = (node) => modifiersOf(node).find((m) => m === "timeslice" || m === "snapshot");
|
|
161775
|
+
var isIndividualOccurrence = (node) => modifiersOf(node).includes("individual");
|
|
161776
|
+
var isOccurrenceModified = (node) => portionKindOf(node) !== void 0 || isIndividualOccurrence(node);
|
|
161777
|
+
var redefinedNameOf = (node) => {
|
|
161778
|
+
const n2 = node;
|
|
161779
|
+
for (const rel2 of [...n2.preRelationships ?? [], ...n2.relationships ?? []]) {
|
|
161780
|
+
if (rel2.kind === ":>>" || rel2.kind === "redefines") {
|
|
161781
|
+
const target = (rel2.targets ?? [])[0];
|
|
161782
|
+
if (target)
|
|
161783
|
+
return lastSeg(target);
|
|
161784
|
+
}
|
|
161785
|
+
}
|
|
161786
|
+
return void 0;
|
|
161787
|
+
};
|
|
161788
|
+
var portionLabelOf = (node) => nameOf2(node) ?? (isOccurrenceModified(node) ? redefinedNameOf(node) : void 0);
|
|
161789
|
+
function diagramNodeId(node) {
|
|
161790
|
+
const name = nameOf2(node);
|
|
161791
|
+
if (name)
|
|
161792
|
+
return qnameOf(node) || name;
|
|
161793
|
+
const label = portionLabelOf(node);
|
|
161794
|
+
if (!label)
|
|
161795
|
+
return void 0;
|
|
161796
|
+
const ownerQname = qnameOf(node);
|
|
161797
|
+
return ownerQname ? `${ownerQname}::${label}` : label;
|
|
161798
|
+
}
|
|
161799
|
+
var isDeclaredEventOccurrence = (m) => isEventDecl(m) && m.isOccurrence === true;
|
|
161800
|
+
var isFeatureUsageMember = (m, owner) => isPartDecl(m) || isPortDecl(m) || isItemDecl(m) || isAttributeDecl(m) || isOccurrenceDecl(m) || isDeclaredEventOccurrence(m) || isStateDecl(m) && !isExhibitStateDecl(m) || isActionDecl(m) || isCalcDecl(m) || isConstraintDecl(m) || isRequirementDecl(m) || isConcernDecl(m) || isViewDecl(m) || isViewpointDecl(m) || isRenderingDecl(m) || isUseCaseDecl(m) || isAnalysisCaseDecl(m) || isVerificationCaseDecl(m) || isCaseDecl(m) || isConnectionDecl(m) || isInterfaceDecl(m) || isAllocationDecl(m) || isEnumDecl(m) && !isEnumDecl(owner);
|
|
161760
161801
|
function specializationTargets(node) {
|
|
161761
161802
|
const n2 = node;
|
|
161762
161803
|
const out = [];
|
|
@@ -162316,7 +162357,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
162316
162357
|
return false;
|
|
162317
162358
|
}
|
|
162318
162359
|
const scope = this.packageScopeOf(node);
|
|
162319
|
-
return [...ast_utils_exports.streamAllContents(scope)].some((n2) =>
|
|
162360
|
+
return [...ast_utils_exports.streamAllContents(scope)].some((n2) => isDefinitionNode(n2) && nameOf2(n2) || this.isViewlessUsage(n2) && this.isDirectPackageMember(n2) || isPartDecl(n2) && n2.isDef !== true && !!nameOf2(n2) && this.isDirectPackageMember(n2));
|
|
162320
162361
|
}
|
|
162321
162362
|
case "iv":
|
|
162322
162363
|
if (isPartDecl(node)) {
|
|
@@ -162387,6 +162428,8 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
162387
162428
|
// they get their graphical home as General View usage nodes — previously a
|
|
162388
162429
|
// package-level `constraint massLimitation { … }` was invisible everywhere.
|
|
162389
162430
|
isViewlessUsage(n2) {
|
|
162431
|
+
if (n2.$type === "FeatureShorthand" && isOccurrenceModified(n2) && nameOf2(n2) !== void 0)
|
|
162432
|
+
return true;
|
|
162390
162433
|
return (isConstraintDecl(n2) || isCalcDecl(n2) || isOccurrenceDecl(n2) || isItemDecl(n2) || isAttributeDecl(n2)) && n2.isDef !== true && nameOf2(n2) !== void 0;
|
|
162391
162434
|
}
|
|
162392
162435
|
isDirectPackageMember(n2) {
|
|
@@ -162411,9 +162454,9 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
162411
162454
|
const { uri, index: index2 } = ctx;
|
|
162412
162455
|
const scope = this.packageScopeOf(ctx.anchor);
|
|
162413
162456
|
const all = [...ast_utils_exports.streamAllContents(scope)];
|
|
162414
|
-
const defNodes = all.filter((n2) =>
|
|
162457
|
+
const defNodes = all.filter((n2) => isDefinitionNode(n2) && nameOf2(n2));
|
|
162415
162458
|
const packageOverview = isPackage(ctx.anchor) || isDocument(ctx.anchor);
|
|
162416
|
-
const hasOwnedMemberNode = all.some((n2) => isPackage(n2) && !!nameOf2(n2) ||
|
|
162459
|
+
const hasOwnedMemberNode = all.some((n2) => isPackage(n2) && !!nameOf2(n2) || isDefinitionNode(n2) && !!nameOf2(n2) || this.isViewlessUsage(n2) && this.isDirectPackageMember(n2) || isPartDecl(n2) && n2.isDef !== true && !!nameOf2(n2) && this.isDirectPackageMember(n2));
|
|
162417
162460
|
const packageNodes = [
|
|
162418
162461
|
...packageOverview && hasOwnedMemberNode && isPackage(scope) && nameOf2(scope) ? [scope] : [],
|
|
162419
162462
|
...all.filter((p) => isPackage(p) && nameOf2(p))
|
|
@@ -162603,16 +162646,18 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
162603
162646
|
const boundReferences = [];
|
|
162604
162647
|
for (let w = 0; w < featureWork.length; w += 1) {
|
|
162605
162648
|
const d = featureWork[w];
|
|
162606
|
-
for (const
|
|
162649
|
+
for (const raw of membersOf(d)) {
|
|
162650
|
+
const m = this.thenActionMemberNode(raw) ?? raw;
|
|
162607
162651
|
const mm = m;
|
|
162608
|
-
|
|
162652
|
+
const label = portionLabelOf(m);
|
|
162653
|
+
if (mm.isDef === true || !label)
|
|
162609
162654
|
continue;
|
|
162610
162655
|
if (directionOf(m) !== void 0)
|
|
162611
162656
|
continue;
|
|
162612
|
-
if (!isFeatureUsageMember(m, d))
|
|
162657
|
+
if (!isFeatureUsageMember(m, d) && !isOccurrenceModified(m))
|
|
162613
162658
|
continue;
|
|
162614
162659
|
const isRefMembership = (mm.modifiers ?? []).includes("ref");
|
|
162615
|
-
if (!isPartDecl(m) && !isOccurrenceDecl(m))
|
|
162660
|
+
if (!isPartDecl(m) && !isOccurrenceDecl(m) && !isOccurrenceModified(m) && !isDeclaredEventOccurrence(m))
|
|
162616
162661
|
continue;
|
|
162617
162662
|
const boundTarget = isRefMembership ? boundPartTarget(m) : void 0;
|
|
162618
162663
|
const hasBoundPath = isRefMembership && isPathExpr(mm.value);
|
|
@@ -162625,14 +162670,16 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
162625
162670
|
}
|
|
162626
162671
|
const def = this.resolveType(m, index2);
|
|
162627
162672
|
const defOnCanvas = !!(def && ids.has(def));
|
|
162628
|
-
const uid =
|
|
162673
|
+
const uid = diagramNodeId(m) ?? label;
|
|
162629
162674
|
if (!ids.has(m)) {
|
|
162630
162675
|
ids.set(m, uid);
|
|
162631
|
-
if (!byName.has(
|
|
162632
|
-
byName.set(
|
|
162676
|
+
if (!byName.has(label))
|
|
162677
|
+
byName.set(label, m);
|
|
162678
|
+
if (!byQName.has(uid))
|
|
162679
|
+
byQName.set(uid, m);
|
|
162633
162680
|
nodes.push({
|
|
162634
162681
|
id: uid,
|
|
162635
|
-
name:
|
|
162682
|
+
name: label,
|
|
162636
162683
|
keyword: keywordFor(m),
|
|
162637
162684
|
isDef: false,
|
|
162638
162685
|
shape: "box",
|
|
@@ -162657,10 +162704,16 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
162657
162704
|
id: `e${e++}`,
|
|
162658
162705
|
from: ids.get(d),
|
|
162659
162706
|
to: uid,
|
|
162660
|
-
|
|
162707
|
+
// REQ-160 — a composed `timeslice`/`snapshot` is not ordinary
|
|
162708
|
+
// feature membership: it is the temporal decomposition of the
|
|
162709
|
+
// owner's life (OMG 8.2.3.9), drawn with the hollow triangle at
|
|
162710
|
+
// the whole end. A `ref` portion still reads as a reference — it
|
|
162711
|
+
// points at a portion owned elsewhere rather than carving up this
|
|
162712
|
+
// occurrence's own lifetime.
|
|
162713
|
+
kind: isRefMembership ? "reference" : portionKindOf(m) ? "portion" : "composition",
|
|
162661
162714
|
// No label — the usage name/type read inside the box; keep
|
|
162662
162715
|
// `name` for the stable route key and Properties.
|
|
162663
|
-
name:
|
|
162716
|
+
name: label,
|
|
162664
162717
|
type: typeText(m),
|
|
162665
162718
|
source: sourceOf2(m, uri)
|
|
162666
162719
|
});
|
|
@@ -162669,6 +162722,31 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
162669
162722
|
}
|
|
162670
162723
|
}
|
|
162671
162724
|
}
|
|
162725
|
+
for (const owner of [...ids.keys()]) {
|
|
162726
|
+
const from = ids.get(owner);
|
|
162727
|
+
for (const raw of membersOf(owner)) {
|
|
162728
|
+
const m = this.thenActionMemberNode(raw) ?? raw;
|
|
162729
|
+
if (!isEventDecl(m) || m.isOccurrence === true)
|
|
162730
|
+
continue;
|
|
162731
|
+
const ev = m;
|
|
162732
|
+
const path10 = [nameOf2(m), ...ev.chainSegs].filter(Boolean).join("::");
|
|
162733
|
+
if (!path10)
|
|
162734
|
+
continue;
|
|
162735
|
+
const target = resolveDrawnByText(path10);
|
|
162736
|
+
const to = target && ids.get(target);
|
|
162737
|
+
if (!to || to === from)
|
|
162738
|
+
continue;
|
|
162739
|
+
edges.push({
|
|
162740
|
+
id: `e${e++}`,
|
|
162741
|
+
from,
|
|
162742
|
+
to,
|
|
162743
|
+
kind: "referenceSubsetting",
|
|
162744
|
+
label: "event",
|
|
162745
|
+
name: lastSeg(path10),
|
|
162746
|
+
source: sourceOf2(m, uri)
|
|
162747
|
+
});
|
|
162748
|
+
}
|
|
162749
|
+
}
|
|
162672
162750
|
for (const binding of boundReferences) {
|
|
162673
162751
|
const from = ids.get(binding.owner);
|
|
162674
162752
|
const to = ids.get(binding.target);
|
|
@@ -165863,7 +165941,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
165863
165941
|
const related = this.relatedNodes(anchor, index2);
|
|
165864
165942
|
const keepIds = /* @__PURE__ */ new Set();
|
|
165865
165943
|
for (const n2 of related) {
|
|
165866
|
-
const id2 =
|
|
165944
|
+
const id2 = diagramNodeId(n2);
|
|
165867
165945
|
if (id2)
|
|
165868
165946
|
keepIds.add(id2);
|
|
165869
165947
|
}
|
|
@@ -166073,7 +166151,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
166073
166151
|
// One registry: each compartment is defined once with the member predicate
|
|
166074
166152
|
// that fills it, emitted in a single canonical order that satisfies the
|
|
166075
166153
|
// requirement order (doc → subject → attributes → assume → require →
|
|
166076
|
-
// actors → stakeholders →
|
|
166154
|
+
// actors → stakeholders → frames, REQ-183) and the use-case order
|
|
166077
166155
|
// (subject → actors → include use cases, REQ-184). Empty compartments are
|
|
166078
166156
|
// omitted (REQ-181) — except `subject`, which is mandatory on requirement /
|
|
166079
166157
|
// use-case / verification-case definitions (REQ-183/184) and shows a
|
|
@@ -166087,7 +166165,10 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
166087
166165
|
const t = typeText(m);
|
|
166088
166166
|
return `${dir ? `${dir} ` : ""}${derived}${nameOf2(m) ?? ""}${t ? ` : ${conj}${t}` : ""}`.trim();
|
|
166089
166167
|
}
|
|
166090
|
-
/** REQ-177/REQ-187 — inherited
|
|
166168
|
+
/** REQ-177/REQ-187 — inherited attributes, dropped when redefined locally.
|
|
166169
|
+
* Their textual home is selected later by the same classifier as local
|
|
166170
|
+
* members; retaining the AST member here prevents direction/variability
|
|
166171
|
+
* from being flattened into `attributes` before classification. */
|
|
166091
166172
|
inheritedItems(node, index2, uri) {
|
|
166092
166173
|
if (node.isDef === true)
|
|
166093
166174
|
return [];
|
|
@@ -166104,22 +166185,45 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
166104
166185
|
}
|
|
166105
166186
|
}
|
|
166106
166187
|
const localNames = new Set(membersOf(node).map((m) => nameOf2(m)).filter(Boolean));
|
|
166107
|
-
return membersOf(def).filter((m) => isAttributeDecl(m) && m.isDef !== true && nameOf2(m)).filter((m) => !localRedefined.has(nameOf2(m)) && !localNames.has(nameOf2(m))).map((
|
|
166188
|
+
return membersOf(def).filter((m) => isAttributeDecl(m) && m.isDef !== true && nameOf2(m)).filter((m) => !localRedefined.has(nameOf2(m)) && !localNames.has(nameOf2(m))).map((member) => ({ member, source: sourceOf2(member, uri) }));
|
|
166108
166189
|
}
|
|
166109
166190
|
compartmentsFor(node, uri, index2, featureRows = false, includeInherited = true) {
|
|
166110
166191
|
const members = membersOf(node);
|
|
166111
166192
|
const n2 = node;
|
|
166112
166193
|
const item = (m, text) => ({ text: text ?? this.featureText(m), source: sourceOf2(m, uri) });
|
|
166113
|
-
const
|
|
166194
|
+
const isVariantConfigMember = (m) => m.allVariants === true;
|
|
166195
|
+
const isVariantMember = (m) => modifiersOf(m).includes("variant") && !isVariantConfigMember(m);
|
|
166196
|
+
const isNonVariantMember = (m) => !isVariantMember(m) && !isVariantConfigMember(m);
|
|
166197
|
+
const isOrdinaryMember = (m) => directionOf(m) === void 0 && isNonVariantMember(m);
|
|
166198
|
+
const inherited = includeInherited ? this.inheritedItems(node, index2, uri) : [];
|
|
166199
|
+
const inheritedRows = (predicate, text = (member) => this.featureText(member)) => inherited.filter(({ member }) => predicate(member)).map(({ member, source }) => ({ text: `^${text(member)}`, source }));
|
|
166200
|
+
const usages = (guard) => members.filter((m) => guard(m) && m.isDef !== true && nameOf2(m) && isOrdinaryMember(m));
|
|
166114
166201
|
const exprText3 = (m) => (m.body?.$cstNode?.text ?? "").replace(/\s+/g, " ").trim();
|
|
166115
166202
|
const statementText = (m) => (m.$cstNode?.text ?? this.featureText(m)).replace(/\s+/g, " ").replace(/;$/, "").trim();
|
|
166203
|
+
const canonicalFeatureText = (m) => m.$type === "FeatureShorthand" || m.$type === "FeatureRedefinitionShorthand" ? statementText(m) : this.featureText(m);
|
|
166116
166204
|
const out = [];
|
|
166205
|
+
const claimedSources = /* @__PURE__ */ new Set();
|
|
166206
|
+
const sourceKey = (source) => `${source.uri}:${source.range.start.line}:${source.range.start.character}:${source.range.end.line}:${source.range.end.character}`;
|
|
166117
166207
|
const add = (title, items) => {
|
|
166118
|
-
|
|
166119
|
-
|
|
166208
|
+
const accepted = items.filter((candidate) => {
|
|
166209
|
+
if (!candidate.source)
|
|
166210
|
+
return true;
|
|
166211
|
+
const key = sourceKey(candidate.source);
|
|
166212
|
+
if (claimedSources.has(key))
|
|
166213
|
+
return false;
|
|
166214
|
+
claimedSources.add(key);
|
|
166215
|
+
return true;
|
|
166216
|
+
});
|
|
166217
|
+
if (!accepted.length)
|
|
166218
|
+
return;
|
|
166219
|
+
const existing = out.find((compartment) => compartment.title === title);
|
|
166220
|
+
if (existing)
|
|
166221
|
+
existing.items.push(...accepted);
|
|
166222
|
+
else
|
|
166223
|
+
out.push({ title, items: accepted });
|
|
166120
166224
|
};
|
|
166121
166225
|
add("doc", members.filter((m) => m.$type === "DocCommentMember").map((m) => item(m, notePreview(docCommentBody(m)) ?? "doc")));
|
|
166122
|
-
const subjects = members.filter(isSubjectDecl);
|
|
166226
|
+
const subjects = members.filter(isSubjectDecl).filter(isNonVariantMember);
|
|
166123
166227
|
const subjectMandatory = n2.isDef === true && (isRequirementDecl(node) || isUseCaseDecl(node) || isVerificationCaseDecl(node));
|
|
166124
166228
|
if (subjects.length) {
|
|
166125
166229
|
add("subject", subjects.map((s) => item(s)));
|
|
@@ -166128,34 +166232,53 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
166128
166232
|
}
|
|
166129
166233
|
add("attributes", [
|
|
166130
166234
|
...usages(isAttributeDecl).map((a2) => item(a2)),
|
|
166131
|
-
...
|
|
166235
|
+
...inheritedRows((member) => isAttributeDecl(member) && isOrdinaryMember(member))
|
|
166132
166236
|
]);
|
|
166237
|
+
const notPortion = (m) => portionKindOf(m) === void 0;
|
|
166133
166238
|
if (featureRows) {
|
|
166134
166239
|
add("ports", usages(isPortDecl).map((m) => item(m)));
|
|
166135
|
-
add("parts", usages(isPartDecl).map((m) => item(m)));
|
|
166240
|
+
add("parts", usages(isPartDecl).filter(notPortion).map((m) => item(m)));
|
|
166136
166241
|
}
|
|
166137
|
-
add("features", members.filter((m) => m.$type === "FeatureShorthand" || m.$type === "FeatureRedefinitionShorthand").map((m) => item(m,
|
|
166138
|
-
const undirected = (guard) => usages(guard)
|
|
166139
|
-
add("items", undirected(isItemDecl).map((m) => item(m)));
|
|
166140
|
-
|
|
166141
|
-
add("occurrences",
|
|
166242
|
+
add("features", members.filter((m) => m.$type === "FeatureShorthand" || m.$type === "FeatureRedefinitionShorthand").filter(isOrdinaryMember).filter((m) => !isOccurrenceModified(m)).map((m) => item(m, canonicalFeatureText(m))));
|
|
166243
|
+
const undirected = (guard) => usages(guard);
|
|
166244
|
+
add("items", undirected(isItemDecl).filter(notPortion).map((m) => item(m)));
|
|
166245
|
+
add("occurrences", undirected(isOccurrenceDecl).filter(notPortion).map((m) => item(m)));
|
|
166246
|
+
add("occurrences", members.map((m) => this.thenActionMemberNode(m) ?? m).filter(isNonVariantMember).filter((m) => isEventDecl(m) && m.isOccurrence === true && nameOf2(m)).map((m) => item(m)));
|
|
166142
166247
|
add("calcs", undirected(isCalcDecl).map((m) => item(m)));
|
|
166143
166248
|
add("constraints", undirected(isConstraintDecl).map((m) => item(m)));
|
|
166144
166249
|
add("assume constraints", members.filter((m) => m.$type === "AssumeConstraintStmt").map((m) => item(m, exprText3(m) || "assume constraint")));
|
|
166145
166250
|
add("require constraints", members.filter((m) => m.$type === "RequireConstraintStmt").map((m) => item(m, exprText3(m) || `require ${this.featurePath(m.target) ?? ""}`.trim())));
|
|
166146
|
-
add("actors", members.filter(isActorDecl).map((m) => item(m)));
|
|
166147
|
-
add("stakeholders", members.filter(isStakeholderDecl).map((m) => item(m)));
|
|
166148
|
-
add("
|
|
166251
|
+
add("actors", members.filter(isActorDecl).filter(isNonVariantMember).map((m) => item(m)));
|
|
166252
|
+
add("stakeholders", members.filter(isStakeholderDecl).filter(isNonVariantMember).map((m) => item(m)));
|
|
166253
|
+
add("frames", members.filter((m) => m.$type === "FrameMember").map((m) => item(m, this.refText(m.target) ?? "concern")));
|
|
166149
166254
|
add("include use cases", members.filter((m) => m.$type === "IncludeStmt").map((m) => item(m, this.refText(m.target) ?? "")));
|
|
166150
|
-
add("objective", members.filter(isObjectiveDecl).map((m) => item(m, nameOf2(m) ?? "objective")));
|
|
166255
|
+
add("objective", members.filter(isObjectiveDecl).filter(isNonVariantMember).map((m) => item(m, nameOf2(m) ?? "objective")));
|
|
166151
166256
|
add("verifies", members.filter((m) => m.$type === "VerifyStmt").map((m) => item(m, String(m.target ?? ""))));
|
|
166152
166257
|
add("verification methods", members.filter((m) => isMetadataDecl(m) && (typeText(m) ?? "").includes("VerificationMethod")).map((m) => item(m, typeText(m) ?? "method")));
|
|
166153
|
-
|
|
166154
|
-
|
|
166258
|
+
const behavioralParameterOwner = isActionDecl(node) || isCalcDecl(node) || isConstraintDecl(node) || isCaseDecl(node) || isAnalysisCaseDecl(node) || isVerificationCaseDecl(node) || isUseCaseDecl(node);
|
|
166259
|
+
const enclosingBehavioralParameterOwner = (() => {
|
|
166260
|
+
if (isPartDecl(node) || isPortDecl(node) || directionOf(node) === void 0)
|
|
166261
|
+
return false;
|
|
166262
|
+
let owner = node.$container;
|
|
166263
|
+
while (owner) {
|
|
166264
|
+
if (isActionDecl(owner) || isCalcDecl(owner) || isConstraintDecl(owner) || isCaseDecl(owner) || isAnalysisCaseDecl(owner) || isVerificationCaseDecl(owner) || isUseCaseDecl(owner))
|
|
166265
|
+
return true;
|
|
166266
|
+
if (isPartDecl(owner) || isPortDecl(owner))
|
|
166267
|
+
return false;
|
|
166268
|
+
owner = owner.$container;
|
|
166269
|
+
}
|
|
166270
|
+
return false;
|
|
166271
|
+
})();
|
|
166272
|
+
const directedTitle = behavioralParameterOwner || enclosingBehavioralParameterOwner ? "parameters" : "directed features";
|
|
166273
|
+
add(directedTitle, [
|
|
166274
|
+
...members.filter((m) => directionOf(m) !== void 0 && nameOf2(m)).filter((m) => !isVariantMember(m) && !isVariantConfigMember(m)).map((m) => item(m, canonicalFeatureText(m))),
|
|
166275
|
+
...inheritedRows((member) => directionOf(member) !== void 0 && isNonVariantMember(member))
|
|
166276
|
+
]);
|
|
166277
|
+
add("result", members.filter((m) => m.$type === "ReturnDecl").map((m) => item(m, `return${nameOf2(m) ? ` ${nameOf2(m)}` : ""}${typeText(m) ? ` : ${typeText(m)}` : ""}`)));
|
|
166155
166278
|
if (isConstraintDecl(node))
|
|
166156
166279
|
add("expression", exprText3(node) ? [{ text: exprText3(node), source: sourceOf2(node, uri) }] : []);
|
|
166157
|
-
const enumValueMembers = members.filter((m) => m.$type === "EnumValueDecl" && (isEnumDecl(node) || !m.typing) || isEnumDecl(node) && isEnumDecl(m) && m.isDef !== true);
|
|
166158
|
-
add("
|
|
166280
|
+
const enumValueMembers = members.filter(isNonVariantMember).filter((m) => m.$type === "EnumValueDecl" && (isEnumDecl(node) || !m.typing) || isEnumDecl(node) && isEnumDecl(m) && m.isDef !== true);
|
|
166281
|
+
add("enums", enumValueMembers.map((m) => {
|
|
166159
166282
|
const nm = nameOf2(m);
|
|
166160
166283
|
if (nm)
|
|
166161
166284
|
return item(m, nm);
|
|
@@ -166165,7 +166288,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
166165
166288
|
add("states", usages(isStateDecl).map((m) => item(m)));
|
|
166166
166289
|
const stateActions = members.map((m) => ({ m, kind: { EntryAction: "entry", DoAction: "do", ExitAction: "exit" }[m.$type] })).filter((x) => !!x.kind);
|
|
166167
166290
|
add("state actions", stateActions.map(({ m, kind }) => item(m, `${kind} ${nameOf2(m) ?? ""}`.trim())));
|
|
166168
|
-
add("
|
|
166291
|
+
add("state transition", members.filter((m) => m.$type === "TransitionDecl").map((m) => item(m, `${m.from ?? ""} \u2192 ${m.to ?? ""}`)));
|
|
166169
166292
|
add("assert constraints", members.filter((m) => m.$type === "AssertConstraintStmt").map((m) => item(m, exprText3(m) || nameOf2(m) || "assert constraint")));
|
|
166170
166293
|
add("invariants", members.filter((m) => m.$type === "InvShorthand").map((m) => {
|
|
166171
166294
|
const inv = m;
|
|
@@ -166173,15 +166296,22 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
166173
166296
|
const expr = exprText3(m);
|
|
166174
166297
|
return item(m, `${head2} { ${expr} }`.replace(/\s+/g, " ").trim());
|
|
166175
166298
|
}));
|
|
166176
|
-
add("
|
|
166299
|
+
add("actions", usages(isActionDecl).map((m) => item(m)));
|
|
166177
166300
|
add("concerns", usages(isConcernDecl).map((m) => item(m)));
|
|
166178
166301
|
add("viewpoints", usages(isViewpointDecl).map((m) => item(m)));
|
|
166179
|
-
add("exposes", members.filter((m) => m.$type === "ExposeMember").flatMap((m) => (m.paths ?? []).map((
|
|
166302
|
+
add("exposes", members.filter((m) => m.$type === "ExposeMember").flatMap((m) => (m.paths ?? []).map((path10) => item(path10, this.featurePath(path10) ?? (path10.$cstNode?.text ?? "").replace(/\s+/g, " ").trim()))));
|
|
166180
166303
|
add("filters", members.filter((m) => m.$type === "FilterMember").map((m) => item(m, (m.$cstNode?.text ?? "filter").replace(/\s+/g, " ").replace(/^filter\s*/, "").replace(/;$/, "").trim())));
|
|
166181
166304
|
add("rendering", members.filter((m) => m.$type === "RenderMember").map((m) => item(m, this.refText(m.target) ?? "")));
|
|
166182
|
-
const
|
|
166183
|
-
|
|
166184
|
-
|
|
166305
|
+
const portionMembers = members.map((m) => this.thenActionMemberNode(m) ?? m).filter(isNonVariantMember);
|
|
166306
|
+
const withPortionKind = (kind) => portionMembers.filter((m) => portionKindOf(m) === kind && portionLabelOf(m));
|
|
166307
|
+
const portionText = (m) => {
|
|
166308
|
+
const t = typeText(m);
|
|
166309
|
+
const mult = multText(m);
|
|
166310
|
+
return `${portionLabelOf(m)}${t ? ` : ${t}` : ""}${mult ? ` ${mult}` : ""}`;
|
|
166311
|
+
};
|
|
166312
|
+
add("timeslices", withPortionKind("timeslice").map((m) => item(m, portionText(m))));
|
|
166313
|
+
add("snapshots", withPortionKind("snapshot").map((m) => item(m, portionText(m))));
|
|
166314
|
+
add("individuals", portionMembers.filter((m) => m.$type === "FeatureShorthand" && isIndividualOccurrence(m) && portionKindOf(m) === void 0 && portionLabelOf(m)).map((m) => item(m, portionText(m))));
|
|
166185
166315
|
const metaBadges = [
|
|
166186
166316
|
...prefixTagsOf(node).map((t) => `#${t}`),
|
|
166187
166317
|
...members.filter((m) => m.$type === "MetadataAnnotation").map((m) => {
|
|
@@ -166192,8 +166322,15 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
166192
166322
|
})
|
|
166193
166323
|
];
|
|
166194
166324
|
add("metadata", metaBadges.map((text) => ({ text })));
|
|
166195
|
-
add("variants",
|
|
166196
|
-
|
|
166325
|
+
add("variants", [
|
|
166326
|
+
...members.filter((m) => isVariantMember(m) && nameOf2(m)).map((m) => item(m)),
|
|
166327
|
+
...inheritedRows((member) => isVariantMember(member) && !!nameOf2(member))
|
|
166328
|
+
]);
|
|
166329
|
+
const variantElementText = (member) => `${nameOf2(member) ?? ""} = all ${(member.value?.$cstNode?.text ?? "").trim()}`.trim();
|
|
166330
|
+
add("variant element usages", [
|
|
166331
|
+
...members.filter(isVariantConfigMember).map((m) => item(m, variantElementText(m))),
|
|
166332
|
+
...inheritedRows(isVariantConfigMember, variantElementText)
|
|
166333
|
+
]);
|
|
166197
166334
|
add("satisfies", members.filter((m) => m.$type === "SatisfyStmt").map((m) => item(m, String(m.target ?? ""))));
|
|
166198
166335
|
return out.length ? out : void 0;
|
|
166199
166336
|
}
|
|
@@ -166811,7 +166948,7 @@ function symbolNameFor(node) {
|
|
|
166811
166948
|
const redefined = redefinitionTargets(node)[0];
|
|
166812
166949
|
return redefined ? `:>> ${lastNameSegment(redefined)}` : void 0;
|
|
166813
166950
|
}
|
|
166814
|
-
function
|
|
166951
|
+
function isDefinitionNode2(node) {
|
|
166815
166952
|
return node.isDef === true;
|
|
166816
166953
|
}
|
|
166817
166954
|
function isInheritableFeature(node) {
|
|
@@ -166951,7 +167088,7 @@ function findNameLeaf(node, name) {
|
|
|
166951
167088
|
return void 0;
|
|
166952
167089
|
}
|
|
166953
167090
|
function inheritedFeatureSymbols(node, inheritedRange, context, seen = /* @__PURE__ */ new Set()) {
|
|
166954
|
-
if (!
|
|
167091
|
+
if (!isDefinitionNode2(node) || seen.has(node))
|
|
166955
167092
|
return [];
|
|
166956
167093
|
seen.add(node);
|
|
166957
167094
|
const symbols = [];
|
|
@@ -167876,6 +168013,13 @@ var DIAGNOSTIC_MESSAGES = {
|
|
|
167876
168013
|
// implicit-redefinition resolution this validator does not yet model.
|
|
167877
168014
|
RES017_DUPLICATE_MEMBER: (name) => `'${name}' is already declared in this namespace. Members must be distinguishable by name \u2014 rename or remove the duplicate.`,
|
|
167878
168015
|
RES017_DUPLICATE_SHORT_NAME: (name) => `Short name '<${name}>' is already used in this namespace. Members must be distinguishable \u2014 rename the short name.`,
|
|
168016
|
+
// issue #102 — REQ-387. The filter evaluator (`import-visibility.ts`,
|
|
168017
|
+
// `evaluateFilterCondition`) decides metadata-presence tests and the Boolean
|
|
168018
|
+
// operators over them; every other form fails OPEN, keeping the member. Failing
|
|
168019
|
+
// open is the right default — under-importing would manufacture spurious
|
|
168020
|
+
// RES001s — but an unevaluated filter produces a scope or view that looks
|
|
168021
|
+
// authoritative and is not, so the fail-open is stated rather than assumed.
|
|
168022
|
+
RES018_UNEVALUATED_FILTER: (subject, construct) => `${subject} filter is not evaluated: ${construct} is outside the metadata-filter evaluator, which decides '@'/'@@' metadata tests combined with 'not', 'and'/'&', and 'or'/'|'. The filter fails open \u2014 it is treated as pass-through and removes nothing.`,
|
|
167879
168023
|
// REQ-007 — SysML v1 → v2 migration guardrail.
|
|
167880
168024
|
MIG001_V1_KEYWORD: (keyword, v2, note) => `'${keyword}' is a SysML v1 construct, not a SysML v2 keyword. ${note} Use '${v2}'.`,
|
|
167881
168025
|
MIG002_V1_STEREOTYPE_KNOWN: (stereotype, v2, note) => `SysML v2 has no stereotypes. ${note} Replace \xAB${stereotype}\xBB with '${v2}'.`,
|
|
@@ -170333,14 +170477,14 @@ function evaluateFilterCondition(node, metadataTypes, resolveRefs) {
|
|
|
170333
170477
|
return node.items.length === 1 ? evaluateFilterCondition(node.items[0], metadataTypes, resolveRefs) : void 0;
|
|
170334
170478
|
}
|
|
170335
170479
|
if (isBinExpr(node)) {
|
|
170336
|
-
if (
|
|
170480
|
+
if (CONJUNCTION_OPERATORS.has(node.op)) {
|
|
170337
170481
|
const left = evaluateFilterCondition(node.left, metadataTypes, resolveRefs);
|
|
170338
170482
|
const right = evaluateFilterCondition(node.right, metadataTypes, resolveRefs);
|
|
170339
170483
|
if (left === false || right === false)
|
|
170340
170484
|
return false;
|
|
170341
170485
|
return left === void 0 || right === void 0 ? void 0 : true;
|
|
170342
170486
|
}
|
|
170343
|
-
if (
|
|
170487
|
+
if (DISJUNCTION_OPERATORS.has(node.op)) {
|
|
170344
170488
|
const left = evaluateFilterCondition(node.left, metadataTypes, resolveRefs);
|
|
170345
170489
|
const right = evaluateFilterCondition(node.right, metadataTypes, resolveRefs);
|
|
170346
170490
|
if (left === true || right === true)
|
|
@@ -170351,6 +170495,42 @@ function evaluateFilterCondition(node, metadataTypes, resolveRefs) {
|
|
|
170351
170495
|
}
|
|
170352
170496
|
return void 0;
|
|
170353
170497
|
}
|
|
170498
|
+
var CONJUNCTION_OPERATORS = /* @__PURE__ */ new Set(["and", "&"]);
|
|
170499
|
+
var DISJUNCTION_OPERATORS = /* @__PURE__ */ new Set(["or", "|"]);
|
|
170500
|
+
function undecidableFilterCondition(condition) {
|
|
170501
|
+
if (!condition)
|
|
170502
|
+
return void 0;
|
|
170503
|
+
if (isSelfClassifyExpr(condition)) {
|
|
170504
|
+
return condition.op === "@" || condition.op === "@@" ? void 0 : { node: condition, construct: `the '${condition.op}' classification operator` };
|
|
170505
|
+
}
|
|
170506
|
+
if (isNotExpr(condition) && condition.operand) {
|
|
170507
|
+
return undecidableFilterCondition(condition.operand);
|
|
170508
|
+
}
|
|
170509
|
+
if (condition.$type === "NotExpr")
|
|
170510
|
+
return void 0;
|
|
170511
|
+
if (isParenExpr(condition)) {
|
|
170512
|
+
return condition.items.length === 1 ? undecidableFilterCondition(condition.items[0]) : { node: condition, construct: "a parenthesized expression list" };
|
|
170513
|
+
}
|
|
170514
|
+
if (isBinExpr(condition)) {
|
|
170515
|
+
if (CONJUNCTION_OPERATORS.has(condition.op) || DISJUNCTION_OPERATORS.has(condition.op)) {
|
|
170516
|
+
return undecidableFilterCondition(condition.left) ?? undecidableFilterCondition(condition.right);
|
|
170517
|
+
}
|
|
170518
|
+
return { node: condition, construct: `the '${condition.op}' operator` };
|
|
170519
|
+
}
|
|
170520
|
+
return { node: condition, construct: describeFilterExpr(condition) };
|
|
170521
|
+
}
|
|
170522
|
+
function describeFilterExpr(node) {
|
|
170523
|
+
if (isPostfixOp(node)) {
|
|
170524
|
+
if ((node.dot || node.select) && node.field)
|
|
170525
|
+
return `the '.${node.field}' feature access`;
|
|
170526
|
+
if (node.arrow && node.invoke)
|
|
170527
|
+
return `the '->${node.invoke}' invocation`;
|
|
170528
|
+
return "this postfix expression";
|
|
170529
|
+
}
|
|
170530
|
+
if (isPathExpr(node))
|
|
170531
|
+
return "a plain feature reference";
|
|
170532
|
+
return "this expression form";
|
|
170533
|
+
}
|
|
170354
170534
|
function attachedMetadataTypes(node, resolveRefs) {
|
|
170355
170535
|
const siblings = node.$container?.members;
|
|
170356
170536
|
if (!Array.isArray(siblings))
|
|
@@ -170579,6 +170759,26 @@ function actionOnlyConstruct(node) {
|
|
|
170579
170759
|
const keyword = CONTROL_NODE_KEYWORDS[node.$type];
|
|
170580
170760
|
return keyword ? { construct: `A '${keyword}' control node`, clause: "7.17.3" } : void 0;
|
|
170581
170761
|
}
|
|
170762
|
+
function portionKindOf2(node) {
|
|
170763
|
+
const mods = node.modifiers;
|
|
170764
|
+
if (!Array.isArray(mods))
|
|
170765
|
+
return void 0;
|
|
170766
|
+
return mods.find((m) => m === "timeslice" || m === "snapshot");
|
|
170767
|
+
}
|
|
170768
|
+
var NAMESPACE_ONLY_TYPES = /* @__PURE__ */ new Set(["Package", "Document", "NamespaceDecl"]);
|
|
170769
|
+
function owningTypeOf(node) {
|
|
170770
|
+
let owner = node.$container;
|
|
170771
|
+
while (owner && (owner.$type === "PrefixMetadataMember" || owner.$type === "ThenActionMember")) {
|
|
170772
|
+
owner = owner.$container;
|
|
170773
|
+
}
|
|
170774
|
+
if (!owner)
|
|
170775
|
+
return void 0;
|
|
170776
|
+
return NAMESPACE_ONLY_TYPES.has(owner.$type) ? void 0 : owner;
|
|
170777
|
+
}
|
|
170778
|
+
function declLabel(node, kind) {
|
|
170779
|
+
const name = node.name;
|
|
170780
|
+
return name ? `'${name}'` : `this '${kind}'`;
|
|
170781
|
+
}
|
|
170582
170782
|
var SysmlValidator = class _SysmlValidator {
|
|
170583
170783
|
indexManager;
|
|
170584
170784
|
langiumDocuments;
|
|
@@ -170802,6 +171002,7 @@ var SysmlValidator = class _SysmlValidator {
|
|
|
170802
171002
|
this.checkLanguageDisjointness(node, accept);
|
|
170803
171003
|
this.checkKermlWellFormedness(node, accept);
|
|
170804
171004
|
this.checkFilterExpressions(node, accept);
|
|
171005
|
+
this.checkOccurrencePortions(node, accept);
|
|
170805
171006
|
this.checkCrossReferences(node, accept);
|
|
170806
171007
|
this.checkAutoImportSuggestions(node, accept);
|
|
170807
171008
|
this.checkUnits(node, accept);
|
|
@@ -171629,6 +171830,7 @@ ${baseIndent}}`;
|
|
|
171629
171830
|
checkCrossReferences(node, accept) {
|
|
171630
171831
|
const index2 = this.buildIndex();
|
|
171631
171832
|
const imports = [];
|
|
171833
|
+
const exposePaths = [];
|
|
171632
171834
|
const decls = [];
|
|
171633
171835
|
const verifyStmts = [];
|
|
171634
171836
|
const satisfyStmts = [];
|
|
@@ -171640,7 +171842,9 @@ ${baseIndent}}`;
|
|
|
171640
171842
|
const path10 = importedPath(child);
|
|
171641
171843
|
if (alias && path10 && importWildcard(child) === "none")
|
|
171642
171844
|
aliasMap.set(alias, path10);
|
|
171643
|
-
} else if (
|
|
171845
|
+
} else if (isExposePath(child))
|
|
171846
|
+
exposePaths.push(child);
|
|
171847
|
+
else if (isVerifyStmt(child))
|
|
171644
171848
|
verifyStmts.push(child);
|
|
171645
171849
|
else if (isSatisfyStmt(child))
|
|
171646
171850
|
satisfyStmts.push(child);
|
|
@@ -171656,6 +171860,7 @@ ${baseIndent}}`;
|
|
|
171656
171860
|
this.checkPrivateImports(imports, index2, accept);
|
|
171657
171861
|
this.checkPrivateWildcardReferences(node, imports, index2, accept);
|
|
171658
171862
|
this.checkImportCycles(imports, index2, accept);
|
|
171863
|
+
this.checkUnevaluatedFilters(imports, exposePaths, accept);
|
|
171659
171864
|
if (sysmlDiagnosticSettings.unusedImports !== "off") {
|
|
171660
171865
|
this.checkUnusedImports(node, imports, index2, sysmlDiagnosticSettings.unusedImports, accept);
|
|
171661
171866
|
}
|
|
@@ -171685,6 +171890,49 @@ ${baseIndent}}`;
|
|
|
171685
171890
|
this.checkTypeComposition(decl, index2, accept);
|
|
171686
171891
|
}
|
|
171687
171892
|
}
|
|
171893
|
+
// ══════════════════════════════════════════════════════════════════════
|
|
171894
|
+
// REQ-160 — occurrence portions: `timeslice` / `snapshot` well-formedness
|
|
171895
|
+
// ══════════════════════════════════════════════════════════════════════
|
|
171896
|
+
// The declaration kinds that are NOT occurrences, so a portion of their life is
|
|
171897
|
+
// meaningless. Kept as a deny-list rather than an allow-list because nearly every
|
|
171898
|
+
// SysML usage kind IS an OccurrenceUsage (part, item, action, state, port,
|
|
171899
|
+
// connection, case, …) while the data-valued ones are few and closed: an
|
|
171900
|
+
// AttributeUsage is typed by a DataType and an enumeration is a special attribute,
|
|
171901
|
+
// neither of which has a life to carve up.
|
|
171902
|
+
static NON_OCCURRENCE_OWNER_TYPES = /* @__PURE__ */ new Set(["AttributeDecl", "EnumDecl", "EnumValueDecl", "MetadataDecl", "MultiplicityDecl"]);
|
|
171903
|
+
// REQ-160 — OMG SysML v2 §8.2.2.9 (Occurrences) with the Kernel Semantic Library
|
|
171904
|
+
// `Occurrences::TimeSlice` / `Occurrences::Snapshot`:
|
|
171905
|
+
//
|
|
171906
|
+
// SSM015 — a portion is a portion OF something. Its owning type must be an
|
|
171907
|
+
// occurrence; declared at package level (or inside an attribute /
|
|
171908
|
+
// enumeration body) there is no life for it to be a portion of.
|
|
171909
|
+
// SSM016 — `Snapshot :> TimeSlice` with a zero duration: a snapshot is the
|
|
171910
|
+
// occurrence at ONE instant. Every portion of a zero-duration
|
|
171911
|
+
// occurrence is itself zero-duration, so a snapshot may own further
|
|
171912
|
+
// snapshots but never a `timeslice`.
|
|
171913
|
+
//
|
|
171914
|
+
// Both are structural — they read modifiers and owners only — so they hold
|
|
171915
|
+
// without resolving a single cross-reference.
|
|
171916
|
+
checkOccurrencePortions(node, accept) {
|
|
171917
|
+
for (const child of ast_utils_exports.streamAllContents(node)) {
|
|
171918
|
+
const kind = portionKindOf2(child);
|
|
171919
|
+
if (!kind)
|
|
171920
|
+
continue;
|
|
171921
|
+
const label = declLabel(child, kind);
|
|
171922
|
+
const owner = owningTypeOf(child);
|
|
171923
|
+
if (!owner) {
|
|
171924
|
+
accept(severity("SSM015", "error"), `A '${kind}' is a portion of an occurrence's life, so ${label} must be declared inside an occurrence \u2014 not directly in a package.`, { node: child, code: "SSM015" });
|
|
171925
|
+
continue;
|
|
171926
|
+
}
|
|
171927
|
+
if (_SysmlValidator.NON_OCCURRENCE_OWNER_TYPES.has(owner.$type)) {
|
|
171928
|
+
accept(severity("SSM015", "error"), `A '${kind}' is a portion of an occurrence's life, and '${owner.name ?? owner.$type}' is not an occurrence.`, { node: child, code: "SSM015" });
|
|
171929
|
+
continue;
|
|
171930
|
+
}
|
|
171931
|
+
if (kind === "timeslice" && portionKindOf2(owner) === "snapshot") {
|
|
171932
|
+
accept(severity("SSM016", "error"), `A 'snapshot' is a zero-duration timeslice, so ${label} cannot be a timeslice of it \u2014 a portion of an instant is itself a snapshot.`, { node: child, code: "SSM016" });
|
|
171933
|
+
}
|
|
171934
|
+
}
|
|
171935
|
+
}
|
|
171688
171936
|
// REQ-328 — KSM008: a `filter` membership condition must be Boolean. Only a
|
|
171689
171937
|
// *definitely* non-Boolean expression is flagged — a string or numeric/quantity
|
|
171690
171938
|
// literal, or an arithmetic/range binary expression. A bare feature path is left
|
|
@@ -172231,6 +172479,34 @@ ${baseIndent}}`;
|
|
|
172231
172479
|
}
|
|
172232
172480
|
return false;
|
|
172233
172481
|
}
|
|
172482
|
+
/**
|
|
172483
|
+
* REQ-387 — RES018: an `import` or `expose` filter the metadata-filter
|
|
172484
|
+
* evaluator cannot decide (issue #102).
|
|
172485
|
+
*
|
|
172486
|
+
* The evaluator keeps a member it cannot decide, so an unevaluated filter
|
|
172487
|
+
* silently contributes the members it was written to exclude — a scope or a
|
|
172488
|
+
* view that reads as authoritative and is not. Failing open stays (narrowing
|
|
172489
|
+
* on a guess would manufacture unresolved-name errors); what changes is that
|
|
172490
|
+
* the model now says so at the filter that is not applied.
|
|
172491
|
+
*
|
|
172492
|
+
* Default severity is `info` rather than a warning: the model is legal and the
|
|
172493
|
+
* limitation is this evaluator's, not the author's. Teams that want an
|
|
172494
|
+
* unevaluated filter to break a build raise it per code through
|
|
172495
|
+
* `sysml.validation.severities` (REQ-240).
|
|
172496
|
+
*/
|
|
172497
|
+
checkUnevaluatedFilters(imports, exposePaths, accept) {
|
|
172498
|
+
const report2 = (condition, subject) => {
|
|
172499
|
+
const undecidable = undecidableFilterCondition(condition);
|
|
172500
|
+
if (!undecidable)
|
|
172501
|
+
return;
|
|
172502
|
+
accept(severity("RES018", "info"), DIAGNOSTIC_MESSAGES.RES018_UNEVALUATED_FILTER(subject, undecidable.construct), { node: undecidable.node, code: "RES018" });
|
|
172503
|
+
};
|
|
172504
|
+
for (const imp of imports)
|
|
172505
|
+
for (const filter4 of imp.filters)
|
|
172506
|
+
report2(filter4.condition, "Import");
|
|
172507
|
+
for (const path10 of exposePaths)
|
|
172508
|
+
report2(path10.condition, "Expose");
|
|
172509
|
+
}
|
|
172234
172510
|
// REQ-324 — RES009 unused import (configurable, OFF by default)
|
|
172235
172511
|
checkUnusedImports(root4, imports, index2, level, accept) {
|
|
172236
172512
|
if (imports.length === 0)
|
|
@@ -176534,6 +176810,7 @@ function readProjectConfig(root4) {
|
|
|
176534
176810
|
// ../extension/src/webview/diagram/flow/diagram-rules.ts
|
|
176535
176811
|
var PORT_GLYPH_SIZE = 20;
|
|
176536
176812
|
var PORT_GLYPH_HALF = PORT_GLYPH_SIZE / 2;
|
|
176813
|
+
var FEATURE_COMPARTMENT_CLEARANCE = PORT_GLYPH_HALF + 12;
|
|
176537
176814
|
var ACTION_PIN_GLYPH_SIZE = PORT_GLYPH_SIZE;
|
|
176538
176815
|
function endpointGlyphSize(endpoint) {
|
|
176539
176816
|
return endpoint.pin ? ACTION_PIN_GLYPH_SIZE : PORT_GLYPH_SIZE;
|
|
@@ -176576,18 +176853,26 @@ var DOCK_TANGENT = {
|
|
|
176576
176853
|
left: { x: 0, y: 1 },
|
|
176577
176854
|
right: { x: 0, y: 1 }
|
|
176578
176855
|
};
|
|
176579
|
-
function portGlyphRect(g, w, h) {
|
|
176580
|
-
const base = sidePoint(g.side, g.offset, w, h);
|
|
176581
|
-
const t = DOCK_TANGENT[g.side];
|
|
176582
|
-
const n2 = DOCK_NORMAL[g.side];
|
|
176583
|
-
const shift = g.shift ?? { along: 0, across: 0 };
|
|
176584
|
-
const cx = base.x + t.x * shift.along + n2.x * shift.across;
|
|
176585
|
-
const cy = base.y + t.y * shift.along + n2.y * shift.across;
|
|
176856
|
+
function portGlyphRect(g, w, h, topReserve = 0) {
|
|
176586
176857
|
const natural = endpointGlyphSize(g.port);
|
|
176587
176858
|
const along = g.along ?? natural;
|
|
176588
176859
|
const toggleRun = g.toggleRun ?? 0;
|
|
176589
176860
|
const across = g.across ?? (along - toggleRun > natural ? NESTED_PORT_HOST_ACROSS : natural);
|
|
176590
176861
|
const vertical = g.side === "left" || g.side === "right";
|
|
176862
|
+
const base = sidePoint(g.side, g.offset, w, h, topReserve);
|
|
176863
|
+
const t = DOCK_TANGENT[g.side];
|
|
176864
|
+
const n2 = DOCK_NORMAL[g.side];
|
|
176865
|
+
const shift = g.shift ?? { along: 0, across: 0 };
|
|
176866
|
+
const rawCx = base.x + t.x * shift.along + n2.x * shift.across;
|
|
176867
|
+
const rawCy = base.y + t.y * shift.along + n2.y * shift.across;
|
|
176868
|
+
const run = sideLength(g.side, w, h, topReserve);
|
|
176869
|
+
const alongCentre = vertical ? rawCy : rawCx;
|
|
176870
|
+
const rootAlong = g.rootAlong ?? along;
|
|
176871
|
+
const rootCentre = vertical ? base.y : base.x;
|
|
176872
|
+
const boundedRootCentre = topReserve > 0 && vertical ? run >= rootAlong ? Math.max(topReserve + rootAlong / 2, Math.min(topReserve + run - rootAlong / 2, rootCentre)) : topReserve + run / 2 : rootCentre;
|
|
176873
|
+
const boundedAlong = alongCentre + boundedRootCentre - rootCentre;
|
|
176874
|
+
const cx = vertical ? rawCx : boundedAlong;
|
|
176875
|
+
const cy = vertical ? boundedAlong : rawCy;
|
|
176591
176876
|
const width = vertical ? across : along;
|
|
176592
176877
|
const height = vertical ? along : across;
|
|
176593
176878
|
return {
|
|
@@ -176661,18 +176946,40 @@ var DOCK_NORMAL = {
|
|
|
176661
176946
|
bottom: { x: 0, y: 1 },
|
|
176662
176947
|
left: { x: -1, y: 0 }
|
|
176663
176948
|
};
|
|
176664
|
-
function
|
|
176949
|
+
function portSideHeight(h, topReserve = 0) {
|
|
176950
|
+
const band = Number.isFinite(topReserve) ? Math.max(0, Math.min(Math.max(0, h), topReserve)) : 0;
|
|
176951
|
+
return Math.max(0, h - band);
|
|
176952
|
+
}
|
|
176953
|
+
function sidePoint(side, offset2, w, h, topReserve = 0) {
|
|
176954
|
+
const top = h - portSideHeight(h, topReserve);
|
|
176955
|
+
const sideH = portSideHeight(h, topReserve);
|
|
176665
176956
|
switch (side) {
|
|
176666
176957
|
case "top":
|
|
176667
176958
|
return { x: w * offset2, y: 0 };
|
|
176668
176959
|
case "bottom":
|
|
176669
176960
|
return { x: w * offset2, y: h };
|
|
176670
176961
|
case "left":
|
|
176671
|
-
return { x: 0, y:
|
|
176962
|
+
return { x: 0, y: top + sideH * offset2 };
|
|
176672
176963
|
case "right":
|
|
176673
|
-
return { x: w, y:
|
|
176964
|
+
return { x: w, y: top + sideH * offset2 };
|
|
176674
176965
|
}
|
|
176675
176966
|
}
|
|
176967
|
+
function nearestPortOwnerPlacement(x, y, w, h, topReserve = 0) {
|
|
176968
|
+
const sideH = portSideHeight(h, topReserve);
|
|
176969
|
+
const top = h - sideH;
|
|
176970
|
+
const clamp3 = (value, lo, hi) => Math.max(lo, Math.min(hi, value));
|
|
176971
|
+
const distanceSq = (px, py, qx, qy) => (px - qx) ** 2 + (py - qy) ** 2;
|
|
176972
|
+
const sideY = clamp3(y, top, h);
|
|
176973
|
+
const offsetY = sideH > 0 ? (sideY - top) / sideH : 0.5;
|
|
176974
|
+
const candidates = [
|
|
176975
|
+
{ side: "left", offset: offsetY, distance: distanceSq(x, y, 0, sideY) },
|
|
176976
|
+
{ side: "right", offset: offsetY, distance: distanceSq(x, y, w, sideY) },
|
|
176977
|
+
{ side: "top", offset: w > 0 ? clamp3(x, 0, w) / w : 0.5, distance: distanceSq(x, y, clamp3(x, 0, w), 0) },
|
|
176978
|
+
{ side: "bottom", offset: w > 0 ? clamp3(x, 0, w) / w : 0.5, distance: distanceSq(x, y, clamp3(x, 0, w), h) }
|
|
176979
|
+
];
|
|
176980
|
+
const best = candidates.reduce((nearest, candidate) => candidate.distance < nearest.distance ? candidate : nearest);
|
|
176981
|
+
return { side: best.side, offset: best.offset };
|
|
176982
|
+
}
|
|
176676
176983
|
var SIDE_ANCHOR_SEP = ":";
|
|
176677
176984
|
var CONNECT_POINT_SPACING_DEFAULT = 24;
|
|
176678
176985
|
var CONNECT_POINT_SPACING_MIN = 8;
|
|
@@ -176705,12 +177012,12 @@ function centerOutOffsetOrder(offsets) {
|
|
|
176705
177012
|
function sidePointOffsetsForLength(length2, spacing) {
|
|
176706
177013
|
return sidePointOffsets(connectPointCountForLength(length2, spacing));
|
|
176707
177014
|
}
|
|
176708
|
-
function sideLength(side, w, h) {
|
|
176709
|
-
return side === "top" || side === "bottom" ? w : h;
|
|
177015
|
+
function sideLength(side, w, h, topReserve = 0) {
|
|
177016
|
+
return side === "top" || side === "bottom" ? w : portSideHeight(h, topReserve);
|
|
176710
177017
|
}
|
|
176711
177018
|
var SENDACCEPT_NOTCH = 14;
|
|
176712
|
-
function sideEffectiveLength(shape, side, w, h) {
|
|
176713
|
-
const raw = sideLength(side, w, h);
|
|
177019
|
+
function sideEffectiveLength(shape, side, w, h, topReserve = 0) {
|
|
177020
|
+
const raw = sideLength(side, w, h, topReserve);
|
|
176714
177021
|
switch (shape) {
|
|
176715
177022
|
case "usecase":
|
|
176716
177023
|
return raw * 0.82;
|
|
@@ -176725,7 +177032,7 @@ function sideEffectiveLength(shape, side, w, h) {
|
|
|
176725
177032
|
return raw;
|
|
176726
177033
|
}
|
|
176727
177034
|
}
|
|
176728
|
-
function sideSurfacePoint(shape, side, offset2, w, h) {
|
|
177035
|
+
function sideSurfacePoint(shape, side, offset2, w, h, topReserve = 0) {
|
|
176729
177036
|
const cx = w / 2;
|
|
176730
177037
|
const cy = h / 2;
|
|
176731
177038
|
switch (shape) {
|
|
@@ -176753,22 +177060,22 @@ function sideSurfacePoint(shape, side, offset2, w, h) {
|
|
|
176753
177060
|
case "send": {
|
|
176754
177061
|
if (side === "top" || side === "bottom") return { x: (w - SENDACCEPT_NOTCH) * offset2, y: side === "top" ? 0 : h };
|
|
176755
177062
|
if (side === "right") return { x: w, y: cy };
|
|
176756
|
-
return sidePoint(side, offset2, w, h);
|
|
177063
|
+
return sidePoint(side, offset2, w, h, topReserve);
|
|
176757
177064
|
}
|
|
176758
177065
|
case "accept": {
|
|
176759
177066
|
if (side === "left") return { x: SENDACCEPT_NOTCH, y: cy };
|
|
176760
|
-
return sidePoint(side, offset2, w, h);
|
|
177067
|
+
return sidePoint(side, offset2, w, h, topReserve);
|
|
176761
177068
|
}
|
|
176762
177069
|
default:
|
|
176763
|
-
return sidePoint(side, offset2, w, h);
|
|
177070
|
+
return sidePoint(side, offset2, w, h, topReserve);
|
|
176764
177071
|
}
|
|
176765
177072
|
}
|
|
176766
177073
|
function isPackageEndpoint(shape, keyword) {
|
|
176767
177074
|
if (shape === "package") return true;
|
|
176768
177075
|
return (keyword ?? "").trim().toLowerCase() === "package";
|
|
176769
177076
|
}
|
|
176770
|
-
function sidePointOffsetsFor(side, w, h, spacing, connectable, shape) {
|
|
176771
|
-
return connectable ? sidePointOffsetsForLength(sideEffectiveLength(shape, side, w, h), spacing) : [0.5];
|
|
177077
|
+
function sidePointOffsetsFor(side, w, h, spacing, connectable, shape, topReserve = 0) {
|
|
177078
|
+
return connectable ? sidePointOffsetsForLength(sideEffectiveLength(shape, side, w, h, topReserve), spacing) : [0.5];
|
|
176772
177079
|
}
|
|
176773
177080
|
function sideAnchorHandleId(side, offset2) {
|
|
176774
177081
|
return Math.abs(offset2 - 0.5) < 1e-6 ? side : `${side}${SIDE_ANCHOR_SEP}${offset2.toFixed(3)}`;
|
|
@@ -176809,6 +177116,50 @@ function clampDockSide(encoded, portSide) {
|
|
|
176809
177116
|
}
|
|
176810
177117
|
var PORT_PLUS_GAP = 7;
|
|
176811
177118
|
var PORT_PLUS_HALF = 4;
|
|
177119
|
+
var NODE_USAGE_CORNER_RADIUS = 14;
|
|
177120
|
+
var NODE_ROUNDED_USAGE_RADIUS = 20;
|
|
177121
|
+
var NODE_ROUNDED_TITLED_RADIUS = 12;
|
|
177122
|
+
function nodeCornerRadius(shape, isDef, height, titled) {
|
|
177123
|
+
if (isDef) return 0;
|
|
177124
|
+
if (shape === "action" || shape === "state") {
|
|
177125
|
+
const r = Math.min(height / 2, NODE_ROUNDED_USAGE_RADIUS);
|
|
177126
|
+
return titled ? Math.min(r, NODE_ROUNDED_TITLED_RADIUS) : r;
|
|
177127
|
+
}
|
|
177128
|
+
return NODE_USAGE_CORNER_RADIUS;
|
|
177129
|
+
}
|
|
177130
|
+
var FRAME_USAGE_CORNER_RADIUS = 12;
|
|
177131
|
+
var CONTAINER_CONTROL_SIZE = 20;
|
|
177132
|
+
var CONTAINER_CONTROL_GAP = 1;
|
|
177133
|
+
var CONTAINER_CONTROLS_RIGHT = 2;
|
|
177134
|
+
function containerControlsInset(cornerRadius) {
|
|
177135
|
+
return Math.max(CONTAINER_CONTROLS_RIGHT, Math.ceil(cornerRadius * (1 - Math.SQRT1_2)));
|
|
177136
|
+
}
|
|
177137
|
+
var CONTAINER_CONTROLS_INSET_MAX = containerControlsInset(NODE_ROUNDED_USAGE_RADIUS);
|
|
177138
|
+
var CONTAINER_TITLE_RIGHT_RESERVE = 2 * CONTAINER_CONTROL_SIZE + CONTAINER_CONTROL_GAP + CONTAINER_CONTROLS_INSET_MAX + 11;
|
|
177139
|
+
var COLLAPSED_CONTAINER_MIN_WIDTH = CONTAINER_TITLE_RIGHT_RESERVE + 48;
|
|
177140
|
+
var CONTAINER_GLYPH_VIEWBOX = 20;
|
|
177141
|
+
var CONTAINER_GLYPH_EXTENT = 11;
|
|
177142
|
+
function containerTitleArea(ownerWidth, controlsVisible) {
|
|
177143
|
+
const width = Math.max(0, ownerWidth - (controlsVisible ? CONTAINER_TITLE_RIGHT_RESERVE : 0));
|
|
177144
|
+
return { centerX: width / 2, width };
|
|
177145
|
+
}
|
|
177146
|
+
var NODE_COMPARTMENT_TOP = 30;
|
|
177147
|
+
var FRAME_TITLE_HEIGHT = NODE_COMPARTMENT_TOP;
|
|
177148
|
+
function containerTitleHeight(isFrame) {
|
|
177149
|
+
return isFrame ? FRAME_TITLE_HEIGHT : NODE_COMPARTMENT_TOP;
|
|
177150
|
+
}
|
|
177151
|
+
var CONTAINER_TITLE_KIND_BASELINE = 14;
|
|
177152
|
+
var CONTAINER_TITLE_NAME_BASELINE = 28;
|
|
177153
|
+
function containerTopReserve(bandHeight, isFrame) {
|
|
177154
|
+
return bandHeight && bandHeight > 0 ? containerTitleHeight(isFrame) + bandHeight : 0;
|
|
177155
|
+
}
|
|
177156
|
+
var COMPARTMENT_TITLE_HEIGHT = 16;
|
|
177157
|
+
var COMPARTMENT_ROW_HEIGHT = 14;
|
|
177158
|
+
var COMPARTMENT_TITLE_BASELINE = 12;
|
|
177159
|
+
var COMPARTMENT_ROW_BASELINE = 26;
|
|
177160
|
+
function compartmentBlockHeight(items) {
|
|
177161
|
+
return COMPARTMENT_TITLE_HEIGHT + items * COMPARTMENT_ROW_HEIGHT;
|
|
177162
|
+
}
|
|
176812
177163
|
function portLabelPlacement(side, x, y, label, half = PORT_GLYPH_HALF, alongHalf = half) {
|
|
176813
177164
|
const vertical = side === "left" || side === "right";
|
|
176814
177165
|
const halfX = vertical ? half : alongHalf;
|
|
@@ -176846,18 +177197,20 @@ function edgeRouteKey(e, duplicateIndex = 0) {
|
|
|
176846
177197
|
const name = e.name ?? e.label;
|
|
176847
177198
|
return `${e.kind}:${e.from}->${e.to}${name ? `:${name}` : ""}${duplicateIndex > 0 ? `~${duplicateIndex}` : ""}`;
|
|
176848
177199
|
}
|
|
176849
|
-
var GV_TREE_EDGE_KIND_LIST = ["owningMembership", "composition", "reference", "definedBy"];
|
|
177200
|
+
var GV_TREE_EDGE_KIND_LIST = ["owningMembership", "composition", "portion", "reference", "definedBy"];
|
|
176850
177201
|
var GV_TREE_EDGE_KINDS = new Set(GV_TREE_EDGE_KIND_LIST);
|
|
176851
|
-
var GV_TREE_HIERARCHY_EDGE_KIND_LIST = ["owningMembership", "composition"];
|
|
177202
|
+
var GV_TREE_HIERARCHY_EDGE_KIND_LIST = ["owningMembership", "composition", "portion"];
|
|
176852
177203
|
var GV_TREE_HIERARCHY_EDGE_KINDS = new Set(GV_TREE_HIERARCHY_EDGE_KIND_LIST);
|
|
176853
177204
|
function gvModeEdges(model, mode) {
|
|
176854
177205
|
if (mode === "group") return [];
|
|
176855
|
-
|
|
177206
|
+
const packageIds = new Set(model.nodes.filter((node) => node.shape === "package").map((node) => node.id));
|
|
177207
|
+
const drawn = (edge) => edge.kind !== "owningMembership" && !packageIds.has(edge.from) && !packageIds.has(edge.to);
|
|
177208
|
+
return model.edges.every(drawn) ? model.edges : model.edges.filter(drawn);
|
|
176856
177209
|
}
|
|
176857
177210
|
function isGvUsageNode(n2) {
|
|
176858
177211
|
return n2.meta?.gvUsage === true;
|
|
176859
177212
|
}
|
|
176860
|
-
var GV_BOXED_USAGE_COMPARTMENTS = /* @__PURE__ */ new Set(["parts", "occurrences"]);
|
|
177213
|
+
var GV_BOXED_USAGE_COMPARTMENTS = /* @__PURE__ */ new Set(["parts", "occurrences", "timeslices", "snapshots", "individuals"]);
|
|
176861
177214
|
function stripBoxedUsageCompartments(nodes) {
|
|
176862
177215
|
let changed = false;
|
|
176863
177216
|
const out = nodes.map((n2) => {
|
|
@@ -176898,7 +177251,8 @@ var GV_CATEGORIES = [
|
|
|
176898
177251
|
function gvNodeCategory(node) {
|
|
176899
177252
|
if (node.shape === "package") return "package";
|
|
176900
177253
|
if (node.shape === "annotation" || node.shape === "dot") return "annotation";
|
|
176901
|
-
const k = node.keyword.toLowerCase().trim().replace(/^(individual|timeslice|snapshot|parallel|variation|variant|abstract|ref|derived)\s
|
|
177254
|
+
const k = node.keyword.toLowerCase().trim().replace(/^(individual|timeslice|snapshot|parallel|variation|variant|abstract|ref|derived)(\s+|$)/g, "").replace(/\s+def$/, "").trim();
|
|
177255
|
+
if (k === "" || k === "def") return "item";
|
|
176902
177256
|
const alias = {
|
|
176903
177257
|
part: "part",
|
|
176904
177258
|
port: "port",
|
|
@@ -176952,9 +177306,19 @@ function twKind(text) {
|
|
|
176952
177306
|
function compartmentHeight(node) {
|
|
176953
177307
|
if (!node.compartments?.length) return 0;
|
|
176954
177308
|
let h = 0;
|
|
176955
|
-
for (const c of node.compartments) h +=
|
|
177309
|
+
for (const c of node.compartments) h += compartmentBlockHeight(c.items.length);
|
|
176956
177310
|
return h;
|
|
176957
177311
|
}
|
|
177312
|
+
function featureCompartmentBandHeight(node) {
|
|
177313
|
+
if (node?.meta?.featureCompartmentsVisible !== true || !node.compartments?.length) return 0;
|
|
177314
|
+
return compartmentHeight(node) + FEATURE_COMPARTMENT_CLEARANCE;
|
|
177315
|
+
}
|
|
177316
|
+
function frameFeatureCompartmentHeight(frame2) {
|
|
177317
|
+
return featureCompartmentBandHeight(frame2);
|
|
177318
|
+
}
|
|
177319
|
+
function featureBandTopReserve(data) {
|
|
177320
|
+
return containerTopReserve(data.featureCompartmentHeight, data.frame !== void 0);
|
|
177321
|
+
}
|
|
176958
177322
|
function titleWidth(node) {
|
|
176959
177323
|
let t = `${node.name}${node.type ? ` : ${node.type}` : ""}`;
|
|
176960
177324
|
if (node.multiplicity) t += ` ${node.multiplicity}`;
|
|
@@ -177013,10 +177377,11 @@ function nodeSize(node, direction) {
|
|
|
177013
177377
|
const sideLabelW = (side) => ph.filter((p) => p.side === side).reduce((m, p) => Math.max(m, tw(p.port.name, 9) + 18), 0);
|
|
177014
177378
|
const portsW = ph.length ? sideLabelW("left") + sideLabelW("right") + 56 : 0;
|
|
177015
177379
|
const portRows = Math.max(ph.filter((p) => p.side === "left").length, ph.filter((p) => p.side === "right").length);
|
|
177380
|
+
const titleRightReserve = node.meta?.containerControls === true || node.meta?.internalsHidden === true ? CONTAINER_TITLE_RIGHT_RESERVE : 0;
|
|
177016
177381
|
const w = Math.max(
|
|
177017
177382
|
NODE_W,
|
|
177018
|
-
titleWidth(node) + 2 * PAD,
|
|
177019
|
-
twKind(`\xAB${node.keyword}\xBB`) + 2 * PAD,
|
|
177383
|
+
titleWidth(node) + 2 * PAD + titleRightReserve,
|
|
177384
|
+
twKind(`\xAB${node.keyword}\xBB`) + 2 * PAD + titleRightReserve,
|
|
177020
177385
|
compartmentWidth(node) + 2 * PAD,
|
|
177021
177386
|
portsW,
|
|
177022
177387
|
// issue #108 — an elongated port on the top/bottom edge widens the owner,
|
|
@@ -177024,13 +177389,15 @@ function nodeSize(node, direction) {
|
|
|
177024
177389
|
portedSideLength(ph, "top"),
|
|
177025
177390
|
portedSideLength(ph, "bottom")
|
|
177026
177391
|
);
|
|
177027
|
-
const
|
|
177392
|
+
const featureH = featureCompartmentBandHeight(node);
|
|
177393
|
+
const bodyH = Math.max(
|
|
177028
177394
|
BOX_H,
|
|
177029
|
-
36 + compartmentHeight(node),
|
|
177395
|
+
featureH > 0 ? 0 : 36 + compartmentHeight(node),
|
|
177030
177396
|
portRows ? 40 + portRows * 24 + 8 : 0,
|
|
177031
177397
|
portedSideLength(ph, "left"),
|
|
177032
177398
|
portedSideLength(ph, "right")
|
|
177033
177399
|
);
|
|
177400
|
+
const h = bodyH + featureH;
|
|
177034
177401
|
return { w, h };
|
|
177035
177402
|
}
|
|
177036
177403
|
function frameMinSize(f) {
|
|
@@ -177038,13 +177405,21 @@ function frameMinSize(f) {
|
|
|
177038
177405
|
const sideLabelW = (side) => ports.filter((p) => p.side === side).reduce((m, p) => Math.max(m, tw(p.port.name, 9) + 18), 0);
|
|
177039
177406
|
const headerW = twKind(`\xAB${f.keyword}\xBB`) + tw(f.label, 11) + 28;
|
|
177040
177407
|
const portsW = sideLabelW("left") + sideLabelW("right") + 56;
|
|
177041
|
-
const
|
|
177408
|
+
const featureH = frameFeatureCompartmentHeight(f);
|
|
177409
|
+
const w = Math.max(
|
|
177410
|
+
160,
|
|
177411
|
+
headerW,
|
|
177412
|
+
portsW,
|
|
177413
|
+
...featureH > 0 ? [compartmentWidth(f) + 2 * PAD] : [],
|
|
177414
|
+
portedSideLength(ports, "top"),
|
|
177415
|
+
portedSideLength(ports, "bottom")
|
|
177416
|
+
);
|
|
177042
177417
|
const portRows = Math.max(ports.filter((p) => p.side === "left").length, ports.filter((p) => p.side === "right").length);
|
|
177043
177418
|
const h = Math.max(
|
|
177044
|
-
58,
|
|
177045
|
-
36 + portRows * 24,
|
|
177046
|
-
portedSideLength(ports, "left"),
|
|
177047
|
-
portedSideLength(ports, "right")
|
|
177419
|
+
58 + featureH,
|
|
177420
|
+
36 + portRows * 24 + featureH,
|
|
177421
|
+
featureH + portedSideLength(ports, "left"),
|
|
177422
|
+
featureH + portedSideLength(ports, "right")
|
|
177048
177423
|
);
|
|
177049
177424
|
return { w, h };
|
|
177050
177425
|
}
|
|
@@ -177180,6 +177555,7 @@ function assignPortHandles(ports, overrides) {
|
|
|
177180
177555
|
side,
|
|
177181
177556
|
offset: +(PORT_BAND_START + centre * PORT_BAND_LENGTH).toFixed(4),
|
|
177182
177557
|
along: alongs[i],
|
|
177558
|
+
rootAlong: alongs[i] ?? endpointGlyphSize(port),
|
|
177183
177559
|
across: alongs[i] === void 0 ? void 0 : metricsOf(port).across,
|
|
177184
177560
|
toggleRun: toggleRunOf(port) || void 0
|
|
177185
177561
|
};
|
|
@@ -177211,6 +177587,7 @@ function assignPortHandles(ports, overrides) {
|
|
|
177211
177587
|
side: parent.side,
|
|
177212
177588
|
offset: parent.offset,
|
|
177213
177589
|
shift: { along: (parent.shift?.along ?? 0) + slot.along, across: slot.across },
|
|
177590
|
+
rootAlong: parent.rootAlong ?? parent.along ?? endpointGlyphSize(parent.port),
|
|
177214
177591
|
...hasToggle(kid) ? { along, across, toggleRun: toggleRunOf(kid) } : {}
|
|
177215
177592
|
};
|
|
177216
177593
|
nestedHandles.push(handle);
|
|
@@ -177220,10 +177597,10 @@ function assignPortHandles(ports, overrides) {
|
|
|
177220
177597
|
for (const parent of topHandles) placeChildren(parent);
|
|
177221
177598
|
return [...topHandles, ...nestedHandles];
|
|
177222
177599
|
}
|
|
177223
|
-
function sizeWithOverride(base, o) {
|
|
177600
|
+
function sizeWithOverride(base, o, minimum = { w: 48, h: 24 }) {
|
|
177224
177601
|
return {
|
|
177225
|
-
w: o?.w !== void 0 ? Math.max(
|
|
177226
|
-
h: o?.h !== void 0 ? Math.max(
|
|
177602
|
+
w: o?.w !== void 0 ? Math.max(minimum.w, o.w) : base.w,
|
|
177603
|
+
h: o?.h !== void 0 ? Math.max(minimum.h, o.h) : base.h
|
|
177227
177604
|
};
|
|
177228
177605
|
}
|
|
177229
177606
|
function normalizeIvModel(model) {
|
|
@@ -177258,6 +177635,7 @@ function promoteIvLeafPartsToFrames(model) {
|
|
|
177258
177635
|
const existing = frames[existingIndex];
|
|
177259
177636
|
frames[existingIndex] = {
|
|
177260
177637
|
...existing,
|
|
177638
|
+
layoutKey: n2.layoutKey ?? existing.layoutKey,
|
|
177261
177639
|
label: n2.name || existing.label,
|
|
177262
177640
|
isDef: n2.isDef ?? existing.isDef,
|
|
177263
177641
|
type: n2.type ?? existing.type,
|
|
@@ -177275,6 +177653,7 @@ function promoteIvLeafPartsToFrames(model) {
|
|
|
177275
177653
|
if (isAnchor || isLeafUsagePart) {
|
|
177276
177654
|
frames.push({
|
|
177277
177655
|
id: n2.id,
|
|
177656
|
+
layoutKey: n2.layoutKey,
|
|
177278
177657
|
label: n2.name,
|
|
177279
177658
|
keyword: n2.keyword,
|
|
177280
177659
|
parent: n2.frame,
|
|
@@ -177332,13 +177711,11 @@ function applyCaseDefs(model, show) {
|
|
|
177332
177711
|
edges
|
|
177333
177712
|
};
|
|
177334
177713
|
}
|
|
177335
|
-
function collapseIvModel(model,
|
|
177714
|
+
function collapseIvModel(model, hiddenInternals) {
|
|
177336
177715
|
const frames = model.frames ?? [];
|
|
177337
177716
|
if (!frames.length) return model;
|
|
177338
177717
|
const frameById = new Map(frames.map((f) => [f.id, f]));
|
|
177339
|
-
const requested = new Set(
|
|
177340
|
-
Object.entries(collapsed).filter(([, c]) => c).map(([id2]) => id2).filter((id2) => frameById.get(id2)?.keyword !== "package" && frameById.get(id2)?.meta?.anchorFrame !== true)
|
|
177341
|
-
);
|
|
177718
|
+
const requested = new Set(frames.filter((frame2) => framePresentationEnabled(hiddenInternals, frame2, true) && isCollapsibleFrame("iv", frame2)).map((frame2) => frame2.id));
|
|
177342
177719
|
if (requested.size === 0) return model;
|
|
177343
177720
|
const hasRequestedAncestor = (id2) => {
|
|
177344
177721
|
let p = frameById.get(id2)?.parent;
|
|
@@ -177371,6 +177748,7 @@ function collapseIvModel(model, collapsed) {
|
|
|
177371
177748
|
if (!f) return [];
|
|
177372
177749
|
return [{
|
|
177373
177750
|
id: f.id,
|
|
177751
|
+
layoutKey: f.layoutKey,
|
|
177374
177752
|
name: f.label,
|
|
177375
177753
|
keyword: f.keyword,
|
|
177376
177754
|
isDef: f.isDef ?? false,
|
|
@@ -177381,7 +177759,7 @@ function collapseIvModel(model, collapsed) {
|
|
|
177381
177759
|
compartments: f.compartments,
|
|
177382
177760
|
frame: f.parent,
|
|
177383
177761
|
source: f.source,
|
|
177384
|
-
meta: { ...f.meta,
|
|
177762
|
+
meta: { ...f.meta, internalsHidden: true }
|
|
177385
177763
|
}];
|
|
177386
177764
|
});
|
|
177387
177765
|
return {
|
|
@@ -177394,22 +177772,67 @@ function collapseIvModel(model, collapsed) {
|
|
|
177394
177772
|
function isCollapsibleActionFrame(frame2) {
|
|
177395
177773
|
return frame2.meta?.compositeAction === true && frame2.meta?.anchorFrame !== true;
|
|
177396
177774
|
}
|
|
177775
|
+
function isCollapsibleStateFrame(frame2) {
|
|
177776
|
+
return frame2.meta?.composite === true && frame2.meta?.anchorFrame !== true;
|
|
177777
|
+
}
|
|
177397
177778
|
function frameStateKey(frame2) {
|
|
177398
177779
|
return frame2.layoutKey ?? frame2.id;
|
|
177399
177780
|
}
|
|
177781
|
+
function framePresentationEnabled(current2, frame2, acceptLegacyDisplayId = false, whenAbsent = false) {
|
|
177782
|
+
const key = frameStateKey(frame2);
|
|
177783
|
+
if (Object.prototype.hasOwnProperty.call(current2, key)) return current2[key] === true;
|
|
177784
|
+
if (acceptLegacyDisplayId && key !== frame2.id && Object.prototype.hasOwnProperty.call(current2, frame2.id)) {
|
|
177785
|
+
return current2[frame2.id] === true;
|
|
177786
|
+
}
|
|
177787
|
+
return whenAbsent;
|
|
177788
|
+
}
|
|
177400
177789
|
function isCollapsibleFrame(kind, frame2) {
|
|
177401
177790
|
if (frame2.meta?.anchorFrame === true) return false;
|
|
177402
177791
|
if (kind === "iv") return frame2.keyword !== "package";
|
|
177403
177792
|
if (kind === "afv") return isCollapsibleActionFrame(frame2);
|
|
177793
|
+
if (kind === "stv") return isCollapsibleStateFrame(frame2);
|
|
177794
|
+
return false;
|
|
177795
|
+
}
|
|
177796
|
+
function isFeatureCompartmentNode(kind, node) {
|
|
177797
|
+
if (node.meta?.internalsHidden === true) return false;
|
|
177798
|
+
if (node.meta?.boundary === true || node.meta?.boundaryBox === true) return false;
|
|
177799
|
+
if (kind === "iv") return node.shape === "box" && /\b(?:part|item)\b/i.test(node.keyword);
|
|
177800
|
+
if (kind === "afv") return node.shape === "action";
|
|
177801
|
+
if (kind === "stv") return node.shape === "state";
|
|
177404
177802
|
return false;
|
|
177405
177803
|
}
|
|
177406
|
-
function
|
|
177804
|
+
function applyFeatureCompartmentVisibility(model, visibleFeatureCompartments, hiddenInternals = {}) {
|
|
177805
|
+
if (!CONTAINER_PRESENTATION_KINDS.has(model.kind)) return model;
|
|
177806
|
+
const legacy = model.kind === "iv";
|
|
177807
|
+
let changed = false;
|
|
177808
|
+
const project = (host, leaf) => {
|
|
177809
|
+
const visible = framePresentationEnabled(visibleFeatureCompartments, host, legacy, leaf);
|
|
177810
|
+
const compartments = visible ? host.compartments : void 0;
|
|
177811
|
+
const internalsHidden = leaf ? framePresentationEnabled(hiddenInternals, host, legacy) : host.meta?.internalsHidden === true;
|
|
177812
|
+
if (compartments === host.compartments && host.meta?.containerControls === true && host.meta?.featureCompartmentsVisible === visible && (!leaf || host.meta?.internalsHidden === internalsHidden)) return host;
|
|
177813
|
+
changed = true;
|
|
177814
|
+
return {
|
|
177815
|
+
...host,
|
|
177816
|
+
compartments,
|
|
177817
|
+
meta: {
|
|
177818
|
+
...host.meta,
|
|
177819
|
+
containerControls: true,
|
|
177820
|
+
featureCompartmentsVisible: visible,
|
|
177821
|
+
...leaf ? { internalsHidden } : {}
|
|
177822
|
+
}
|
|
177823
|
+
};
|
|
177824
|
+
};
|
|
177825
|
+
const frames = (model.frames ?? []).map((frame2) => isCollapsibleFrame(model.kind, frame2) ? project(frame2, false) : frame2);
|
|
177826
|
+
const nodes = model.nodes.map((node) => isFeatureCompartmentNode(model.kind, node) ? project(node, true) : node);
|
|
177827
|
+
return changed ? { ...model, frames, nodes } : model;
|
|
177828
|
+
}
|
|
177829
|
+
var CONTAINER_PRESENTATION_KINDS = /* @__PURE__ */ new Set(["iv", "afv", "stv"]);
|
|
177830
|
+
function collapseActionFrames(model, hiddenInternals, isHost = isCollapsibleActionFrame, collapsedShape = "action") {
|
|
177407
177831
|
const frames = model.frames ?? [];
|
|
177408
177832
|
if (!frames.length) return model;
|
|
177409
177833
|
const frameById = new Map(frames.map((f) => [f.id, f]));
|
|
177410
|
-
const on = new Set(Object.entries(collapsed).filter(([, value]) => value).map(([key]) => key));
|
|
177411
177834
|
const requested = new Set(
|
|
177412
|
-
frames.filter((f) =>
|
|
177835
|
+
frames.filter((f) => framePresentationEnabled(hiddenInternals, f) && isHost(f)).map((f) => f.id)
|
|
177413
177836
|
);
|
|
177414
177837
|
if (requested.size === 0) return model;
|
|
177415
177838
|
const rootOf = (id2) => {
|
|
@@ -177448,17 +177871,18 @@ function collapseActionFrames(model, collapsed) {
|
|
|
177448
177871
|
if (!f) return [];
|
|
177449
177872
|
return [{
|
|
177450
177873
|
id: f.id,
|
|
177874
|
+
layoutKey: f.layoutKey,
|
|
177451
177875
|
name: f.label,
|
|
177452
177876
|
keyword: f.keyword,
|
|
177453
177877
|
isDef: f.isDef ?? false,
|
|
177454
|
-
shape:
|
|
177878
|
+
shape: collapsedShape,
|
|
177455
177879
|
type: f.type,
|
|
177456
177880
|
multiplicity: f.multiplicity,
|
|
177457
177881
|
ports: f.ports,
|
|
177458
177882
|
compartments: f.compartments,
|
|
177459
177883
|
frame: f.parent,
|
|
177460
177884
|
source: f.source,
|
|
177461
|
-
meta: { ...f.meta,
|
|
177885
|
+
meta: { ...f.meta, internalsHidden: true }
|
|
177462
177886
|
}];
|
|
177463
177887
|
});
|
|
177464
177888
|
const seenEdge = /* @__PURE__ */ new Set();
|
|
@@ -177498,8 +177922,13 @@ function modelToFlow(model, opts) {
|
|
|
177498
177922
|
model = collapseNestedPorts(model, opts.nestedPorts ?? {});
|
|
177499
177923
|
if (model.kind === "iv") model = normalizeIvModel(model);
|
|
177500
177924
|
if (model.kind === "iv" && (model.meta?.overview === true || model.meta?.unified === true)) model = promoteIvLeafPartsToFrames(model);
|
|
177501
|
-
|
|
177502
|
-
|
|
177925
|
+
const legacyPresentation = model.kind === "iv" ? opts.ivCompartments : model.kind === "afv" ? opts.collapsedActions : void 0;
|
|
177926
|
+
const hiddenInternals = opts.hiddenInternals ?? legacyPresentation ?? {};
|
|
177927
|
+
const visibleFeatureCompartments = opts.visibleFeatureCompartments ?? legacyPresentation ?? {};
|
|
177928
|
+
model = applyFeatureCompartmentVisibility(model, visibleFeatureCompartments, hiddenInternals);
|
|
177929
|
+
if (model.kind === "iv") model = collapseIvModel(model, hiddenInternals);
|
|
177930
|
+
if (model.kind === "afv") model = collapseActionFrames(model, hiddenInternals);
|
|
177931
|
+
if (model.kind === "stv") model = collapseActionFrames(model, hiddenInternals, isCollapsibleStateFrame, "state");
|
|
177503
177932
|
if (model.kind === "cv" && opts.subjectBoundary) model = applyCaseBoundary(model);
|
|
177504
177933
|
const ov = opts.overrides ?? {};
|
|
177505
177934
|
const nodes = [];
|
|
@@ -177528,7 +177957,13 @@ function modelToFlow(model, opts) {
|
|
|
177528
177957
|
}
|
|
177529
177958
|
const orderedFrames = [...frames].sort((a2, b) => frameDepth(a2.id) - frameDepth(b.id));
|
|
177530
177959
|
for (const f of orderedFrames) {
|
|
177531
|
-
const
|
|
177960
|
+
const natural = frameMinSize(f);
|
|
177961
|
+
const featureH = frameFeatureCompartmentHeight(f);
|
|
177962
|
+
const size = sizeWithOverride(
|
|
177963
|
+
natural,
|
|
177964
|
+
ov[f.layoutKey ?? f.id],
|
|
177965
|
+
{ w: 48, h: featureH > 0 ? natural.h : 24 }
|
|
177966
|
+
);
|
|
177532
177967
|
nodes.push({
|
|
177533
177968
|
id: f.id,
|
|
177534
177969
|
type: "frame",
|
|
@@ -177540,6 +177975,8 @@ function modelToFlow(model, opts) {
|
|
|
177540
177975
|
ports: assignPortHandles(f.ports, opts.portOverrides),
|
|
177541
177976
|
w: size.w,
|
|
177542
177977
|
h: size.h,
|
|
177978
|
+
featureCompartmentHeight: featureH,
|
|
177979
|
+
featureCompartmentMinHeight: featureH > 0 ? natural.h : void 0,
|
|
177543
177980
|
showPortLabels: opts.showPortLabels,
|
|
177544
177981
|
showMult: opts.showMult,
|
|
177545
177982
|
connectPointSpacing,
|
|
@@ -177591,8 +178028,16 @@ function modelToFlow(model, opts) {
|
|
|
177591
178028
|
for (const n2 of renderModelNodes) {
|
|
177592
178029
|
const canvasNode = nodeForCanvas(n2);
|
|
177593
178030
|
const isGeo = model.kind === "gev" && n2.geo !== void 0;
|
|
178031
|
+
const featureH = featureCompartmentBandHeight(n2);
|
|
177594
178032
|
const base = isGeo ? { w: 24, h: 24 } : nodeSize(canvasNode, opts.direction);
|
|
177595
|
-
const size = sizeWithOverride(
|
|
178033
|
+
const size = sizeWithOverride(
|
|
178034
|
+
base,
|
|
178035
|
+
ov[n2.layoutKey ?? n2.id],
|
|
178036
|
+
{
|
|
178037
|
+
w: canvasNode.meta?.containerControls === true || canvasNode.meta?.internalsHidden === true ? COLLAPSED_CONTAINER_MIN_WIDTH : 48,
|
|
178038
|
+
h: featureH > 0 ? base.h : 24
|
|
178039
|
+
}
|
|
178040
|
+
);
|
|
177596
178041
|
const parentId = n2.frame ?? (model.kind === "gv" && n2.parent && gvPackageIds.has(n2.parent) ? n2.parent : void 0) ?? (boundary ? boundary.id : void 0);
|
|
177597
178042
|
nodes.push({
|
|
177598
178043
|
id: n2.id,
|
|
@@ -177605,6 +178050,8 @@ function modelToFlow(model, opts) {
|
|
|
177605
178050
|
ports: assignPortHandles(n2.ports, opts.portOverrides),
|
|
177606
178051
|
w: size.w,
|
|
177607
178052
|
h: size.h,
|
|
178053
|
+
featureCompartmentHeight: featureH,
|
|
178054
|
+
featureCompartmentMinHeight: featureH > 0 ? base.h : void 0,
|
|
177608
178055
|
showPortLabels: opts.showPortLabels,
|
|
177609
178056
|
showMult: opts.showMult,
|
|
177610
178057
|
connectPointSpacing
|
|
@@ -177623,10 +178070,14 @@ function modelToFlow(model, opts) {
|
|
|
177623
178070
|
// often nearly the whole visible canvas at typical zoom, so its empty
|
|
177624
178071
|
// interior must pan the canvas rather than move the part (a click
|
|
177625
178072
|
// there still selects it — dragHandle only gates the DRAG gesture,
|
|
177626
|
-
// never click).
|
|
177627
|
-
//
|
|
177628
|
-
//
|
|
177629
|
-
|
|
178073
|
+
// never click). Every other diagram kind keeps the whole-body drag.
|
|
178074
|
+
// User report 2026-08-11 — the grabbable area was the SVG title TEXT
|
|
178075
|
+
// alone, which a part with hidden internals could barely be moved by
|
|
178076
|
+
// and which carries no move cursor: `.rf-node-header` is the same
|
|
178077
|
+
// full-width title strip a container frame has, so a part behaves the
|
|
178078
|
+
// same whether it draws its internals or not. The text selectors stay
|
|
178079
|
+
// for the title of a node whose header strip is not rendered.
|
|
178080
|
+
...model.kind === "iv" && !isGeo ? { dragHandle: ".rf-node-header, .dnode-kind, .dnode-label" } : {}
|
|
177630
178081
|
});
|
|
177631
178082
|
}
|
|
177632
178083
|
if (model.kind === "sv") {
|
|
@@ -178104,6 +178555,9 @@ async function elkLayout(elk, graph) {
|
|
|
178104
178555
|
}
|
|
178105
178556
|
var FRAME_PAD_TOP = 36;
|
|
178106
178557
|
var FRAME_PAD = 22;
|
|
178558
|
+
function frameTopPad(node) {
|
|
178559
|
+
return FRAME_PAD_TOP + frameFeatureCompartmentHeight(node.data.frame);
|
|
178560
|
+
}
|
|
178107
178561
|
var GV_DOCK_FAMILY_ORDER = /* @__PURE__ */ new Map([
|
|
178108
178562
|
["owningMembership", 0],
|
|
178109
178563
|
["composition", 1],
|
|
@@ -178748,7 +179202,7 @@ function buildElkTree(nodes, direction, kind, tree) {
|
|
|
178748
179202
|
...children2.length ? {
|
|
178749
179203
|
children: children2.map(toElk),
|
|
178750
179204
|
layoutOptions: {
|
|
178751
|
-
"elk.padding": `[top=${
|
|
179205
|
+
"elk.padding": `[top=${frameTopPad(n2)},left=${FRAME_PAD},bottom=${FRAME_PAD},right=${FRAME_PAD}]`,
|
|
178752
179206
|
...minimum,
|
|
178753
179207
|
// REQ-371 — repeat the selected axis on EVERY compound part.
|
|
178754
179208
|
// ELK does not reliably inherit a root direction into nested
|
|
@@ -178854,12 +179308,12 @@ function arrangeIvHierarchy(nodes, direction) {
|
|
|
178854
179308
|
children2.push(node);
|
|
178855
179309
|
byParent.set(key, children2);
|
|
178856
179310
|
}
|
|
178857
|
-
const arrange = (children2,
|
|
179311
|
+
const arrange = (children2, insetFor) => {
|
|
178858
179312
|
if (!children2.length) return;
|
|
178859
179313
|
const minX = Math.min(...children2.map((child) => child.position.x));
|
|
178860
179314
|
const minY = Math.min(...children2.map((child) => child.position.y));
|
|
178861
|
-
const baseX =
|
|
178862
|
-
const baseY =
|
|
179315
|
+
const baseX = insetFor ? FRAME_PAD : 0;
|
|
179316
|
+
const baseY = insetFor ? frameTopPad(insetFor) : 0;
|
|
178863
179317
|
for (const child of children2) {
|
|
178864
179318
|
child.position = {
|
|
178865
179319
|
x: child.position.x - minX + baseX,
|
|
@@ -178938,7 +179392,7 @@ function arrangeIvHierarchy(nodes, direction) {
|
|
|
178938
179392
|
frame2.data = { ...frame2.data, w: minimum.w, h: minimum.h };
|
|
178939
179393
|
const children2 = byParent.get(frame2.id) ?? [];
|
|
178940
179394
|
if (!children2.length) continue;
|
|
178941
|
-
arrange(children2,
|
|
179395
|
+
arrange(children2, frame2);
|
|
178942
179396
|
const maxX = Math.max(...children2.map((child) => child.position.x + (child.width ?? child.data.w)));
|
|
178943
179397
|
const maxY = Math.max(...children2.map((child) => child.position.y + (child.height ?? child.data.h)));
|
|
178944
179398
|
const width = Math.max(minimum.w, maxX + FRAME_PAD);
|
|
@@ -178947,7 +179401,7 @@ function arrangeIvHierarchy(nodes, direction) {
|
|
|
178947
179401
|
frame2.height = height;
|
|
178948
179402
|
frame2.data = { ...frame2.data, w: width, h: height };
|
|
178949
179403
|
}
|
|
178950
|
-
arrange(byParent.get(void 0) ?? [],
|
|
179404
|
+
arrange(byParent.get(void 0) ?? [], void 0);
|
|
178951
179405
|
}
|
|
178952
179406
|
function applyElkPositions(node, byId) {
|
|
178953
179407
|
for (const child of node.children ?? []) {
|
|
@@ -179066,7 +179520,13 @@ function nextSideAnchor(counts, offsetsCache, node, side, spacing, demand) {
|
|
|
179066
179520
|
let offsets = offsetsCache.get(key);
|
|
179067
179521
|
if (!offsets) {
|
|
179068
179522
|
const derived = sidePointOffsetsForLength(
|
|
179069
|
-
sideEffectiveLength(
|
|
179523
|
+
sideEffectiveLength(
|
|
179524
|
+
node.data.node?.shape,
|
|
179525
|
+
side,
|
|
179526
|
+
node.data.w,
|
|
179527
|
+
node.data.h,
|
|
179528
|
+
featureBandTopReserve(node.data)
|
|
179529
|
+
),
|
|
179070
179530
|
spacing
|
|
179071
179531
|
);
|
|
179072
179532
|
const needed = demand?.get(key) ?? 0;
|
|
@@ -179078,7 +179538,13 @@ function nextSideAnchor(counts, offsetsCache, node, side, spacing, demand) {
|
|
|
179078
179538
|
}
|
|
179079
179539
|
const offset2 = offsets[i % offsets.length];
|
|
179080
179540
|
if (i < offsets.length && !sidePointOffsetsForLength(
|
|
179081
|
-
sideEffectiveLength(
|
|
179541
|
+
sideEffectiveLength(
|
|
179542
|
+
node.data.node?.shape,
|
|
179543
|
+
side,
|
|
179544
|
+
node.data.w,
|
|
179545
|
+
node.data.h,
|
|
179546
|
+
featureBandTopReserve(node.data)
|
|
179547
|
+
),
|
|
179082
179548
|
spacing
|
|
179083
179549
|
).some((o) => Math.abs(o - offset2) < 1e-6)) {
|
|
179084
179550
|
const explicit = node.data.explicitSideAnchors?.[side] ?? [];
|
|
@@ -189511,7 +189977,7 @@ function dockPoint(node, handleId, byId, fallback) {
|
|
|
189511
189977
|
const ph = node.data.ports?.find((p) => p.port.id === port.portId);
|
|
189512
189978
|
if (ph) {
|
|
189513
189979
|
const dockSide = clampDockSide(port.side, ph.side);
|
|
189514
|
-
const rect = portGlyphRect(ph, w, h);
|
|
189980
|
+
const rect = portGlyphRect(ph, w, h, featureBandTopReserve(node.data));
|
|
189515
189981
|
const n2 = DOCK_NORMAL[dockSide];
|
|
189516
189982
|
const at = portDockAt(rect, ph.side, dockSide);
|
|
189517
189983
|
return { point: { x: pos.x + at.x, y: pos.y + at.y }, normal: n2 };
|
|
@@ -189519,12 +189985,19 @@ function dockPoint(node, handleId, byId, fallback) {
|
|
|
189519
189985
|
}
|
|
189520
189986
|
const structural = node.data.structuralDocks?.find((dock) => dock.id === handleId);
|
|
189521
189987
|
if (structural) {
|
|
189522
|
-
const c = sidePoint(structural.side, structural.offset, w, h);
|
|
189988
|
+
const c = sidePoint(structural.side, structural.offset, w, h, featureBandTopReserve(node.data));
|
|
189523
189989
|
return { point: { x: pos.x + c.x, y: pos.y + c.y }, normal: DOCK_NORMAL[structural.side] };
|
|
189524
189990
|
}
|
|
189525
189991
|
const sideAnchor = parseSideAnchorHandleId(handleId);
|
|
189526
189992
|
if (sideAnchor) {
|
|
189527
|
-
const c = sideSurfacePoint(
|
|
189993
|
+
const c = sideSurfacePoint(
|
|
189994
|
+
node.data.node?.shape,
|
|
189995
|
+
sideAnchor.side,
|
|
189996
|
+
sideAnchor.offset,
|
|
189997
|
+
w,
|
|
189998
|
+
h,
|
|
189999
|
+
featureBandTopReserve(node.data)
|
|
190000
|
+
);
|
|
189528
190001
|
return { point: { x: pos.x + c.x, y: pos.y + c.y }, normal: DOCK_NORMAL[sideAnchor.side] };
|
|
189529
190002
|
}
|
|
189530
190003
|
return { point: fallback };
|
|
@@ -189607,7 +190080,9 @@ function paintedRouteForEdge(edge, nodes, byId, edges = [], lineStyle = "orthogo
|
|
|
189607
190080
|
return { points: manhattanThroughPoints([sd.point, ...route, td.point], sd.normal), corner: 0 };
|
|
189608
190081
|
}
|
|
189609
190082
|
const structural = isStructuralBusEdge(edge);
|
|
189610
|
-
const
|
|
190083
|
+
const sp = sd.point;
|
|
190084
|
+
const tp = td.point;
|
|
190085
|
+
const via = fanVia(sp, tp, parallelEdgeOffset(
|
|
189611
190086
|
edge.id,
|
|
189612
190087
|
edge.source,
|
|
189613
190088
|
edge.target,
|
|
@@ -189615,6 +190090,9 @@ function paintedRouteForEdge(edge, nodes, byId, edges = [], lineStyle = "orthogo
|
|
|
189615
190090
|
edge.targetHandle,
|
|
189616
190091
|
edges
|
|
189617
190092
|
));
|
|
190093
|
+
if (via.length) {
|
|
190094
|
+
return { points: manhattanThroughPoints([sp, ...via, tp], sd.normal), corner: 0 };
|
|
190095
|
+
}
|
|
189618
190096
|
if (edgeUsesObstacleRouting(edge.data?.kind, lineStyle, structural)) {
|
|
189619
190097
|
return {
|
|
189620
190098
|
points: routeOrthogonalAroundRects(sp, tp, obstacleRects(nodes, edge.source, edge.target, byId, scene), {
|
|
@@ -189642,7 +190120,7 @@ function geometrySignature(nodes) {
|
|
|
189642
190120
|
if (n2.dragging === true || n2.resizing === true) continue;
|
|
189643
190121
|
out += `${n2.id}:${n2.parentId ?? ""}:${n2.type ?? ""}:${n2.hidden ? 1 : 0}:`;
|
|
189644
190122
|
out += `${n2.position.x},${n2.position.y},${n2.width ?? n2.measured?.width ?? n2.data.w},${n2.height ?? n2.measured?.height ?? n2.data.h}`;
|
|
189645
|
-
out += `:${n2.data.node?.shape ?? ""}:${n2.data.isBoundary ? 1 : 0}`;
|
|
190123
|
+
out += `:${n2.data.node?.shape ?? ""}:${n2.data.isBoundary ? 1 : 0}:${n2.data.featureCompartmentHeight ?? 0}`;
|
|
189646
190124
|
for (const p of n2.data.ports ?? []) {
|
|
189647
190125
|
out += `|${p.port.id},${p.side},${p.offset},${p.along ?? ""},${p.shift?.along ?? ""},${p.shift?.across ?? ""}`;
|
|
189648
190126
|
}
|
|
@@ -189762,12 +190240,15 @@ function parallelOffsetMap(edges) {
|
|
|
189762
190240
|
const groups = /* @__PURE__ */ new Map();
|
|
189763
190241
|
for (const edge of edges) {
|
|
189764
190242
|
if (isPortDocked(edge.sourceHandle) || isPortDocked(edge.targetHandle)) continue;
|
|
189765
|
-
const
|
|
190243
|
+
const forward = edge.source <= edge.target;
|
|
190244
|
+
const [a2, b] = forward ? [edge.source, edge.target] : [edge.target, edge.source];
|
|
190245
|
+
const [ha, hb] = forward ? [edge.sourceHandle ?? "", edge.targetHandle ?? ""] : [edge.targetHandle ?? "", edge.sourceHandle ?? ""];
|
|
189766
190246
|
let byTarget = groups.get(a2);
|
|
189767
190247
|
if (!byTarget) groups.set(a2, byTarget = /* @__PURE__ */ new Map());
|
|
189768
|
-
const
|
|
190248
|
+
const key = `${b}\0${ha}\0${hb}`;
|
|
190249
|
+
const group = byTarget.get(key) ?? [];
|
|
189769
190250
|
group.push(edge);
|
|
189770
|
-
byTarget.set(
|
|
190251
|
+
byTarget.set(key, group);
|
|
189771
190252
|
}
|
|
189772
190253
|
cached = /* @__PURE__ */ new Map();
|
|
189773
190254
|
for (const byTarget of groups.values()) {
|
|
@@ -189788,14 +190269,14 @@ function parallelEdgeOffset(id2, _source, _target, sourceHandle, targetHandle, e
|
|
|
189788
190269
|
if (isPortDocked(sourceHandle) || isPortDocked(targetHandle)) return 0;
|
|
189789
190270
|
return parallelOffsetMap(edges).get(id2) ?? 0;
|
|
189790
190271
|
}
|
|
189791
|
-
function
|
|
190272
|
+
function fanVia(sp, tp, off) {
|
|
189792
190273
|
const dx = tp.x - sp.x;
|
|
189793
190274
|
const dy = tp.y - sp.y;
|
|
189794
190275
|
const len = Math.hypot(dx, dy);
|
|
189795
|
-
if (!len || !off) return [
|
|
190276
|
+
if (!len || !off) return [];
|
|
189796
190277
|
const nx = -dy / len;
|
|
189797
190278
|
const ny = dx / len;
|
|
189798
|
-
return [{ x: sp.x + nx * off, y: sp.y +
|
|
190279
|
+
return [{ x: (sp.x + tp.x) / 2 + nx * off, y: (sp.y + tp.y) / 2 + ny * off }];
|
|
189799
190280
|
}
|
|
189800
190281
|
var GV_BUS_EDGE_KINDS = /* @__PURE__ */ new Set([
|
|
189801
190282
|
"owningMembership",
|
|
@@ -189845,13 +190326,14 @@ function computeEdgePath(args) {
|
|
|
189845
190326
|
live ? { x: live.targetX, y: live.targetY } : nodeCentre(targetNode, byId)
|
|
189846
190327
|
);
|
|
189847
190328
|
const route = args.route ?? edge.data?.route;
|
|
189848
|
-
const
|
|
189849
|
-
const
|
|
189850
|
-
const
|
|
190329
|
+
const sp = sd.point;
|
|
190330
|
+
const tp = td.point;
|
|
190331
|
+
const via = route?.length ? route : fanVia(sp, tp, parallelEdgeOffset(edge.id, edge.source, edge.target, edge.sourceHandle, edge.targetHandle, edges));
|
|
190332
|
+
const anchors = [sp, ...via, tp];
|
|
189851
190333
|
const common = { sourceX: sp.x, sourceY: sp.y, targetX: tp.x, targetY: tp.y };
|
|
189852
190334
|
const structural = isStructuralBusEdge(edge);
|
|
189853
190335
|
const wantsObstacles = edgeUsesObstacleRouting(edge.data?.kind, lineStyle, structural);
|
|
189854
|
-
const
|
|
190336
|
+
const guided = via.length > 0 ? lineStyle === "curved" ? { path: smoothPathThroughPoints(anchors), label: pathMidpoint(anchors), points: void 0 } : lineStyle === "straight" ? { path: pointsToPath(anchors), label: pathMidpoint(anchors), points: void 0 } : (() => {
|
|
189855
190337
|
const pts = manhattanThroughPoints(anchors, sd.normal);
|
|
189856
190338
|
return { path: pointsToPath(pts), label: pathMidpoint(pts), points: pts };
|
|
189857
190339
|
})() : void 0;
|
|
@@ -189869,8 +190351,8 @@ function computeEdgePath(args) {
|
|
|
189869
190351
|
normal: sd.normal
|
|
189870
190352
|
};
|
|
189871
190353
|
}
|
|
189872
|
-
const autoRouted = wantsObstacles && !
|
|
189873
|
-
const routed =
|
|
190354
|
+
const autoRouted = wantsObstacles && !guided && !args.dragging ? routedOrthogonalPath({ point: sp, normal: sd.normal }, { point: tp, normal: td.normal }, nodes, edge.source, edge.target) : void 0;
|
|
190355
|
+
const routed = guided ?? autoRouted;
|
|
189874
190356
|
if (routed) {
|
|
189875
190357
|
return {
|
|
189876
190358
|
path: routed.path,
|
|
@@ -189930,6 +190412,13 @@ function markersFor(kind) {
|
|
|
189930
190412
|
case "redefinition":
|
|
189931
190413
|
case "referenceSubsetting":
|
|
189932
190414
|
return { end: "url(#tri-hollow)" };
|
|
190415
|
+
// REQ-160 — temporal decomposition (OMG 8.2.3.9): an occurrence's life →
|
|
190416
|
+
// one `timeslice`/`snapshot` PORTION of it. A portion specializes the life
|
|
190417
|
+
// it is part of, so it carries the specialization triangle — at the WHOLE
|
|
190418
|
+
// end, which is where the edge starts, so the marker is a start-oriented
|
|
190419
|
+
// twin of `tri-hollow` rather than the end-oriented one.
|
|
190420
|
+
case "portion":
|
|
190421
|
+
return { start: "url(#tri-hollow-start)" };
|
|
189933
190422
|
case "flow":
|
|
189934
190423
|
case "message":
|
|
189935
190424
|
return { end: "url(#arrow-cyan)" };
|
|
@@ -190250,6 +190739,10 @@ var MARKER_DEFS_SVG = [
|
|
|
190250
190739
|
`<marker markerUnits="userSpaceOnUse" id="arrow-open-neutral" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="8" markerHeight="8" orient="auto"><path d="M0 0L10 5L0 10" fill="none" stroke="${GREY}" stroke-width="1.4"/></marker>`,
|
|
190251
190740
|
`<marker markerUnits="userSpaceOnUse" id="tri-accent" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="8" markerHeight="8" orient="auto"><path d="M0 0L10 5L0 10z" fill="${ACCENT}"/></marker>`,
|
|
190252
190741
|
`<marker markerUnits="userSpaceOnUse" id="tri-hollow" viewBox="0 0 12 12" refX="11" refY="6" markerWidth="11" markerHeight="11" orient="auto"><path d="M0 0L12 6L0 12z" fill="${BG}" stroke="${GREY}" stroke-width="1.2"/></marker>`,
|
|
190742
|
+
// REQ-160 — the portion (temporal-decomposition) triangle sits at the START of
|
|
190743
|
+
// the edge, at the whole occurrence. Same shape as `tri-hollow`, mirrored so
|
|
190744
|
+
// `orient="auto"` points it back along the line instead of down it.
|
|
190745
|
+
`<marker markerUnits="userSpaceOnUse" id="tri-hollow-start" viewBox="0 0 12 12" refX="1" refY="6" markerWidth="11" markerHeight="11" orient="auto"><path d="M12 0L0 6L12 12z" fill="${BG}" stroke="${GREY}" stroke-width="1.2"/></marker>`,
|
|
190253
190746
|
`<marker markerUnits="userSpaceOnUse" id="defined-by" viewBox="0 0 18 12" refX="17" refY="6" markerWidth="12" markerHeight="8" orient="auto"><circle cx="3.2" cy="3.6" r="1.6" fill="${GREY}"/><circle cx="3.2" cy="8.4" r="1.6" fill="${GREY}"/><path d="M7 1L17 6L7 11z" fill="${GREY}"/></marker>`,
|
|
190254
190747
|
`<marker markerUnits="userSpaceOnUse" id="owning-membership" viewBox="0 0 14 14" refX="1" refY="7" markerWidth="12" markerHeight="12" orient="auto"><circle cx="7" cy="7" r="5.2" fill="${BG}" stroke="${GREY}" stroke-width="1.2"/><path d="M3.8 7H10.2M7 3.8V10.2" fill="none" stroke="${GREY}" stroke-width="1.2"/></marker>`,
|
|
190255
190748
|
`<marker markerUnits="userSpaceOnUse" id="diamond-filled" viewBox="0 0 14 14" refX="1" refY="7" markerWidth="12" markerHeight="12" orient="auto"><path d="M0 7L7 0L14 7L7 14z" fill="${GREY}"/></marker>`,
|
|
@@ -190263,6 +190756,7 @@ var KIN_MARKER_DEFS_SVG = [
|
|
|
190263
190756
|
`<marker markerUnits="userSpaceOnUse" id="arrow-open-neutral-kin" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="8" markerHeight="8" orient="auto"><path d="M0 0L10 5L0 10" fill="none" stroke="${KIN}" stroke-width="1.4"/></marker>`,
|
|
190264
190757
|
`<marker markerUnits="userSpaceOnUse" id="tri-accent-kin" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="8" markerHeight="8" orient="auto"><path d="M0 0L10 5L0 10z" fill="${KIN}"/></marker>`,
|
|
190265
190758
|
`<marker markerUnits="userSpaceOnUse" id="tri-hollow-kin" viewBox="0 0 12 12" refX="11" refY="6" markerWidth="11" markerHeight="11" orient="auto"><path d="M0 0L12 6L0 12z" fill="${BG}" stroke="${KIN}" stroke-width="1.5"/></marker>`,
|
|
190759
|
+
`<marker markerUnits="userSpaceOnUse" id="tri-hollow-start-kin" viewBox="0 0 12 12" refX="1" refY="6" markerWidth="11" markerHeight="11" orient="auto"><path d="M12 0L0 6L12 12z" fill="${BG}" stroke="${KIN}" stroke-width="1.5"/></marker>`,
|
|
190266
190760
|
`<marker markerUnits="userSpaceOnUse" id="defined-by-kin" viewBox="0 0 18 12" refX="17" refY="6" markerWidth="12" markerHeight="8" orient="auto"><circle cx="3.2" cy="3.6" r="1.6" fill="${KIN}"/><circle cx="3.2" cy="8.4" r="1.6" fill="${KIN}"/><path d="M7 1L17 6L7 11z" fill="${KIN}"/></marker>`,
|
|
190267
190761
|
`<marker markerUnits="userSpaceOnUse" id="owning-membership-kin" viewBox="0 0 14 14" refX="1" refY="7" markerWidth="12" markerHeight="12" orient="auto"><circle cx="7" cy="7" r="5.2" fill="${BG}" stroke="${KIN}" stroke-width="1.5"/><path d="M3.8 7H10.2M7 3.8V10.2" fill="none" stroke="${KIN}" stroke-width="1.5"/></marker>`,
|
|
190268
190762
|
`<marker markerUnits="userSpaceOnUse" id="diamond-filled-kin" viewBox="0 0 14 14" refX="1" refY="7" markerWidth="12" markerHeight="12" orient="auto"><path d="M0 7L7 0L14 7L7 14z" fill="${KIN}"/></marker>`,
|
|
@@ -190408,6 +190902,9 @@ body {
|
|
|
190408
190902
|
* reading. */
|
|
190409
190903
|
.dframe-rect { fill: var(--node-surface); fill-opacity: 0.92; stroke: var(--fg-3); stroke-width: 1.2; }
|
|
190410
190904
|
.dframe-rect.container { fill-opacity: 0.16; }
|
|
190905
|
+
/* REQ-366/386 \u2014 an expanded frame remains translucent around its graphical
|
|
190906
|
+
* internals, but its optional bottom feature list is an opaque readable card. */
|
|
190907
|
+
.dfeature-band-bg { fill: var(--node-surface); }
|
|
190411
190908
|
.dframe-rect.package.library { stroke-dasharray: 5 3; }
|
|
190412
190909
|
.dframe-rect.selected { stroke: var(--accent); stroke-width: 2; }
|
|
190413
190910
|
/* RULE (diagram-rules \u2014 Frame): parallel composite-state region \u2014 dashed border. */
|
|
@@ -190452,17 +190949,6 @@ body {
|
|
|
190452
190949
|
.dnode-shape.decision { stroke: var(--yellow); }
|
|
190453
190950
|
/* REQ-006 \u2014 selected-node resize grip */
|
|
190454
190951
|
.dresize-grip { fill: var(--accent); stroke: var(--bg-1); stroke-width: 1; cursor: nwse-resize; }
|
|
190455
|
-
/* REQ-366 \u2014 local IV part presentation control in the upper-right corner.
|
|
190456
|
-
Issue #18 \u2014 a bare +/\u2212 glyph, no surrounding box; the rect stays in the
|
|
190457
|
-
markup only as an invisible, comfortably-sized click target. */
|
|
190458
|
-
.div-part-toggle { cursor: pointer; }
|
|
190459
|
-
.div-part-toggle rect { fill: transparent; stroke: none; }
|
|
190460
|
-
.div-part-toggle text {
|
|
190461
|
-
fill: var(--fg-1); font-family: var(--font-ui); font-size: 16px; font-weight: 700;
|
|
190462
|
-
pointer-events: none;
|
|
190463
|
-
}
|
|
190464
|
-
.div-part-toggle:hover text { fill: var(--accent); }
|
|
190465
|
-
|
|
190466
190952
|
/* edges (REQ-186) */
|
|
190467
190953
|
.dlink { stroke: var(--fg-2); stroke-width: 1.2; fill: none; }
|
|
190468
190954
|
.dlink.flow, .dlink.connect, .dlink.message, .dlink.interface { stroke: var(--cyan); }
|
|
@@ -190483,6 +190969,9 @@ body {
|
|
|
190483
190969
|
}
|
|
190484
190970
|
.dlink.binding { stroke: var(--yellow); stroke-width: 2.6; } /* REQ-195 \u2014 "=" binding (double-weight line) */
|
|
190485
190971
|
.dlink.specialization, .dlink.owningMembership, .dlink.composition, .dlink.association { stroke: var(--fg-2); }
|
|
190972
|
+
/* REQ-160 \u2014 temporal decomposition of an occurrence into timeslices/snapshots
|
|
190973
|
+
(OMG 8.2.3.9): a solid structural line, like the specialization it is. */
|
|
190974
|
+
.dlink.portion { stroke: var(--fg-2); }
|
|
190486
190975
|
/* REQ-094/190 \u2014 custom bound-reference overlay. A dotted directed line is
|
|
190487
190976
|
deliberately distinct from solid feature membership and its owner diamond. */
|
|
190488
190977
|
.dlink.reference { stroke: var(--fg-2); stroke-dasharray: 1 3; stroke-linecap: round; }
|
|
@@ -190842,16 +191331,23 @@ body {
|
|
|
190842
191331
|
/* REQ-190 \u2014 the direction, General-View mode, and line-style segs are icon-only:
|
|
190843
191332
|
tighter padding (see issue 146). */
|
|
190844
191333
|
.seg.seg-dir button, .seg.seg-gvmode button, .seg.seg-line-style button, .seg.seg-gridpreset button,
|
|
190845
|
-
.seg.seg-
|
|
190846
|
-
/* REQ-196 \u2014
|
|
190847
|
-
|
|
190848
|
-
|
|
190849
|
-
.seg.seg-
|
|
190850
|
-
|
|
191334
|
+
.seg.seg-visibility button, .seg.seg-presentation button { padding: 2px 6px; }
|
|
191335
|
+
/* REQ-196/200/366/386 \u2014 every visibility/presentation segment shares one
|
|
191336
|
+
treatment: visible is lit; hidden is dimmed and slashed. Semantic icon hues
|
|
191337
|
+
remain visible instead of being replaced by a solid orange active button. */
|
|
191338
|
+
.seg.seg-visibility button.on, .seg.seg-presentation button.on {
|
|
191339
|
+
background: var(--bg-active); color: var(--fg-0);
|
|
191340
|
+
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--fg-2) 30%, transparent); }
|
|
191341
|
+
.seg.seg-visibility button:not(.on), .seg.seg-presentation button:not(.on) { opacity: 0.38; }
|
|
191342
|
+
.seg.seg-visibility button:not(.on)::after, .seg.seg-presentation button:not(.on)::after {
|
|
190851
191343
|
content: ''; position: absolute; left: 4px; right: 4px; top: 50%;
|
|
190852
|
-
border-top: 1.2px solid
|
|
191344
|
+
border-top: 1.2px solid var(--red, #e07a7a); transform: rotate(-20deg);
|
|
190853
191345
|
}
|
|
190854
|
-
.seg.seg-
|
|
191346
|
+
.seg.seg-visibility button, .seg.seg-presentation button { position: relative; }
|
|
191347
|
+
.visibility-icon.tone-structure, .presentation-icon.tone-structure { color: var(--cyan); }
|
|
191348
|
+
.visibility-icon.tone-behavior, .presentation-icon.tone-behavior { color: var(--accent); }
|
|
191349
|
+
.visibility-icon.tone-definition, .presentation-icon.tone-definition,
|
|
191350
|
+
.definition-visibility-icon { color: var(--violet); }
|
|
190855
191351
|
/* issue 156 \u2014 General View quick filters: one icon chip per element category
|
|
190856
191352
|
(parts always show). A chip stays lit in its element-type colour while its
|
|
190857
191353
|
category is VISIBLE; hiding one dims and slashes it so an engaged filter is
|
|
@@ -191089,6 +191585,12 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
191089
191585
|
.rf-frame .rf-node-svg { pointer-events: none; }
|
|
191090
191586
|
.rf-frame .dframe-rect { pointer-events: none; }
|
|
191091
191587
|
.rf-frame-header { position: absolute; pointer-events: auto; cursor: move; }
|
|
191588
|
+
/* issue #58 / user report 2026-08-11 \u2014 the matching title strip on an
|
|
191589
|
+
* Interconnection View PART node. It is what the node's dragHandle selects, so
|
|
191590
|
+
* a part reads and moves identically whether it draws its internals (a frame) or
|
|
191591
|
+
* has them hidden (a node) \u2014 and shows the same move cursor either way, instead
|
|
191592
|
+
* of React Flow's grab hand over a body that cannot actually be dragged. */
|
|
191593
|
+
.rf-node-header { position: absolute; pointer-events: auto; cursor: move; }
|
|
191092
191594
|
/* REQ-379 \u2014 the frame's BORDER band is hover-sensitive (the interior stays
|
|
191093
191595
|
* click-through): hovering it reveals and mounts the frame's side connect points,
|
|
191094
191596
|
* which are drawn on that same border. Stroke-only hit testing, so nothing but the
|
|
@@ -191096,7 +191598,7 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
191096
191598
|
.dframe-hover-band { stroke-width: 12; pointer-events: stroke; }
|
|
191097
191599
|
.rf-frame .dport-hit { pointer-events: auto; }
|
|
191098
191600
|
.rf-frame .react-flow__handle { pointer-events: auto; }
|
|
191099
|
-
.rf-frame .
|
|
191601
|
+
.rf-frame .dcontainer-controls { pointer-events: auto; }
|
|
191100
191602
|
.rf-frame .react-flow__resize-control { pointer-events: auto; }
|
|
191101
191603
|
.rf-node-svg { display: block; overflow: visible; }
|
|
191102
191604
|
.react-flow__node.selected { box-shadow: none; }
|
|
@@ -191293,12 +191795,29 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
191293
191795
|
color: var(--fg-0); background: var(--bg-1); border: 1px solid var(--line-soft); border-radius: 3px; padding: 0 4px; white-space: nowrap; }
|
|
191294
191796
|
.rf-edge-label.mult { background: transparent; border: 0; color: var(--fg-2); padding: 0; }
|
|
191295
191797
|
|
|
191296
|
-
/* REQ-366
|
|
191297
|
-
*
|
|
191298
|
-
|
|
191299
|
-
|
|
191798
|
+
/* REQ-366/386 \u2014 two adjacent, independent container presentation controls.
|
|
191799
|
+
* +/\u2212 owns graphical internals; the outlined list owns textual feature
|
|
191800
|
+
* compartments. Their compact hit targets stay interactive over frame chrome.
|
|
191801
|
+
* Both marks are STROKED SVG sized to the whole button (nodes.tsx
|
|
191802
|
+
* ContainerControlGlyph), so nothing here can shift them off centre \u2014 a typed
|
|
191803
|
+
* +/\u2212 character and a bordered box drawn in CSS both did (user report
|
|
191804
|
+
* 2026-08-11). */
|
|
191805
|
+
/* The inset is set inline per shape (nodes.tsx ContainerControls): a rounded
|
|
191806
|
+
* outline needs the pair pulled in from its corner arc, a sharp one does not.
|
|
191807
|
+
* These values are the sharp-corner default. */
|
|
191808
|
+
.dcontainer-controls { position: absolute; right: ${CONTAINER_CONTROLS_RIGHT}px; top: ${CONTAINER_CONTROLS_RIGHT}px; z-index: 8;
|
|
191809
|
+
display: inline-flex; align-items: center; gap: ${CONTAINER_CONTROL_GAP}px; pointer-events: auto; }
|
|
191810
|
+
/* The BUTTON is only a hit target: no plate, no fill, in any state (user
|
|
191811
|
+
* direction 2026-08-11 \u2014 "remove that translucent thing surrounding the box I
|
|
191812
|
+
* just want the hamburger menu"). Neither does STATE live here: the mark itself
|
|
191813
|
+
* carries it \u2014 an empty box or a filled one, a + or a \u2212, at one resting colour
|
|
191814
|
+
* ("at best don't even change color"). Only the pointer feedback is a colour. */
|
|
191815
|
+
.div-part-toggle, .dfeature-toggle { width: ${CONTAINER_CONTROL_SIZE}px; height: ${CONTAINER_CONTROL_SIZE}px;
|
|
191816
|
+
padding: 0; margin: 0; border: 0; background: none; cursor: pointer; color: var(--fg-1);
|
|
191300
191817
|
display: inline-flex; align-items: center; justify-content: center; }
|
|
191301
|
-
.div-part-toggle
|
|
191818
|
+
.div-part-toggle svg, .dfeature-toggle svg { display: block; }
|
|
191819
|
+
.div-part-toggle:hover, .div-part-toggle:active, .div-part-toggle:focus-visible,
|
|
191820
|
+
.dfeature-toggle:hover, .dfeature-toggle:active, .dfeature-toggle:focus-visible { color: var(--accent); outline: none; }
|
|
191302
191821
|
|
|
191303
191822
|
/* React Flow chrome theming (controls / minimap / attribution) */
|
|
191304
191823
|
.react-flow__controls { box-shadow: 0 2px 10px rgba(0,0,0,0.35); }
|
|
@@ -191395,7 +191914,7 @@ function buildDiagramSvg(options) {
|
|
|
191395
191914
|
const { w, h } = sizeOf(node);
|
|
191396
191915
|
extend2(p.x, p.y, w, h);
|
|
191397
191916
|
for (const ph of node.data.ports ?? []) {
|
|
191398
|
-
const rect = portGlyphRect(ph, w, h);
|
|
191917
|
+
const rect = portGlyphRect(ph, w, h, featureBandTopReserve(node.data));
|
|
191399
191918
|
extend2(p.x + rect.x, p.y + rect.y, rect.width, rect.height);
|
|
191400
191919
|
if (!node.data.showPortLabels || rect.elongated) continue;
|
|
191401
191920
|
const text = `${ph.port.conjugated ? "~" : ""}${ph.port.name}`;
|
|
@@ -191538,7 +192057,7 @@ function tableToCsv(table2, order) {
|
|
|
191538
192057
|
// ../extension/src/diagram-sidecar.ts
|
|
191539
192058
|
var import_diagram_protocol2 = __toESM(require_out());
|
|
191540
192059
|
var FILE_OVERVIEW_ANCHOR = "~file";
|
|
191541
|
-
var SIDECAR_VERSION =
|
|
192060
|
+
var SIDECAR_VERSION = 4;
|
|
191542
192061
|
function emptySideCar() {
|
|
191543
192062
|
return { version: SIDECAR_VERSION, anchors: {} };
|
|
191544
192063
|
}
|
|
@@ -191593,6 +192112,20 @@ function dropOrdinalKeys(map3) {
|
|
|
191593
192112
|
}
|
|
191594
192113
|
return Object.keys(kept).length > 0 ? kept : void 0;
|
|
191595
192114
|
}
|
|
192115
|
+
function enabledEntries(value) {
|
|
192116
|
+
if (!value || typeof value !== "object") return {};
|
|
192117
|
+
return Object.fromEntries(Object.entries(value).filter(([, enabled]) => enabled === true));
|
|
192118
|
+
}
|
|
192119
|
+
function normalizeContainerPresentation(state, kind) {
|
|
192120
|
+
const legacy = state;
|
|
192121
|
+
const coupled = kind === "iv" ? enabledEntries(legacy.ivCompartments) : kind === "afv" ? enabledEntries(legacy.collapsedActions) : {};
|
|
192122
|
+
if (Object.keys(coupled).length > 0) {
|
|
192123
|
+
state.hiddenInternals = { ...coupled, ...state.hiddenInternals ?? {} };
|
|
192124
|
+
state.visibleFeatureCompartments = { ...coupled, ...state.visibleFeatureCompartments ?? {} };
|
|
192125
|
+
}
|
|
192126
|
+
delete legacy.ivCompartments;
|
|
192127
|
+
delete legacy.collapsedActions;
|
|
192128
|
+
}
|
|
191596
192129
|
function normalizeSideCar(value) {
|
|
191597
192130
|
if (!value || typeof value !== "object") return emptySideCar();
|
|
191598
192131
|
const v = value;
|
|
@@ -191601,16 +192134,36 @@ function normalizeSideCar(value) {
|
|
|
191601
192134
|
if (version >= SIDECAR_VERSION) {
|
|
191602
192135
|
for (const byKind of Object.values(anchors)) {
|
|
191603
192136
|
if (!byKind || typeof byKind !== "object") continue;
|
|
191604
|
-
for (const state of Object.
|
|
192137
|
+
for (const [kind, state] of Object.entries(byKind)) {
|
|
191605
192138
|
if (!state || typeof state !== "object") continue;
|
|
191606
192139
|
const dir = sanitizeDirection(state.direction);
|
|
191607
192140
|
if (dir === void 0) delete state.direction;
|
|
191608
192141
|
else state.direction = dir;
|
|
191609
192142
|
normalizeGridFields(state);
|
|
192143
|
+
normalizeContainerPresentation(state, kind);
|
|
191610
192144
|
}
|
|
191611
192145
|
}
|
|
191612
192146
|
return { version, anchors };
|
|
191613
192147
|
}
|
|
192148
|
+
if (version === 3) {
|
|
192149
|
+
const migrated2 = {};
|
|
192150
|
+
for (const [anchor, byKind] of Object.entries(anchors)) {
|
|
192151
|
+
if (!byKind || typeof byKind !== "object") continue;
|
|
192152
|
+
const nextByKind = {};
|
|
192153
|
+
for (const [kind, raw] of Object.entries(byKind)) {
|
|
192154
|
+
if (!raw || typeof raw !== "object") continue;
|
|
192155
|
+
const state = { ...raw };
|
|
192156
|
+
normalizeGridFields(state);
|
|
192157
|
+
const dir = sanitizeDirection(state.direction);
|
|
192158
|
+
if (dir === void 0) delete state.direction;
|
|
192159
|
+
else state.direction = dir;
|
|
192160
|
+
normalizeContainerPresentation(state, kind);
|
|
192161
|
+
nextByKind[kind] = state;
|
|
192162
|
+
}
|
|
192163
|
+
migrated2[anchor] = nextByKind;
|
|
192164
|
+
}
|
|
192165
|
+
return { version: SIDECAR_VERSION, anchors: migrated2 };
|
|
192166
|
+
}
|
|
191614
192167
|
if (version === 2) {
|
|
191615
192168
|
const migrated2 = {};
|
|
191616
192169
|
for (const [anchor, byKind] of Object.entries(anchors)) {
|
|
@@ -191629,6 +192182,7 @@ function normalizeSideCar(value) {
|
|
|
191629
192182
|
const ports = dropOrdinalKeys(state.ports);
|
|
191630
192183
|
if (ports) state.ports = ports;
|
|
191631
192184
|
else delete state.ports;
|
|
192185
|
+
normalizeContainerPresentation(state, kind);
|
|
191632
192186
|
nextByKind[kind] = state;
|
|
191633
192187
|
}
|
|
191634
192188
|
migrated2[anchor] = nextByKind;
|
|
@@ -191643,14 +192197,17 @@ function normalizeSideCar(value) {
|
|
|
191643
192197
|
if (!raw || typeof raw !== "object") continue;
|
|
191644
192198
|
const state = raw;
|
|
191645
192199
|
normalizeGridFields(state);
|
|
192200
|
+
normalizeContainerPresentation(state, kind);
|
|
191646
192201
|
const next = {};
|
|
191647
192202
|
if (state.mode !== void 0) next.mode = state.mode;
|
|
191648
192203
|
if (state.zoom !== void 0) next.zoom = state.zoom;
|
|
191649
192204
|
const dir = sanitizeDirection(state.direction);
|
|
191650
192205
|
if (dir !== void 0) next.direction = dir;
|
|
191651
|
-
if (state.
|
|
192206
|
+
if (state.hiddenInternals !== void 0) next.hiddenInternals = state.hiddenInternals;
|
|
192207
|
+
if (state.visibleFeatureCompartments !== void 0) {
|
|
192208
|
+
next.visibleFeatureCompartments = state.visibleFeatureCompartments;
|
|
192209
|
+
}
|
|
191652
192210
|
if (state.nestedPorts !== void 0) next.nestedPorts = state.nestedPorts;
|
|
191653
|
-
if (state.collapsedActions !== void 0) next.collapsedActions = state.collapsedActions;
|
|
191654
192211
|
if (state.gvMode !== void 0) next.gvMode = state.gvMode;
|
|
191655
192212
|
if (state.gvFilters !== void 0) next.gvFilters = state.gvFilters;
|
|
191656
192213
|
if (state.lineStyle !== void 0) next.lineStyle = state.lineStyle;
|
|
@@ -191726,6 +192283,7 @@ function edgeKindLabel(kind) {
|
|
|
191726
192283
|
if (kind === "composition") return "feature membership";
|
|
191727
192284
|
if (kind === "owningMembership") return "owning membership";
|
|
191728
192285
|
if (kind === "definedBy") return "defined by";
|
|
192286
|
+
if (kind === "portion") return "temporal decomposition (portion)";
|
|
191729
192287
|
return kind;
|
|
191730
192288
|
}
|
|
191731
192289
|
|
|
@@ -192374,7 +192932,8 @@ function nodeSidePointOffsets(data, side, connectable) {
|
|
|
192374
192932
|
data.h,
|
|
192375
192933
|
data.connectPointSpacing ?? CONNECT_POINT_SPACING_DEFAULT,
|
|
192376
192934
|
connectable,
|
|
192377
|
-
data.node?.shape
|
|
192935
|
+
data.node?.shape,
|
|
192936
|
+
data.featureCompartmentHeight ?? 0
|
|
192378
192937
|
);
|
|
192379
192938
|
const explicit = data.explicitSideAnchors?.[side] ?? [];
|
|
192380
192939
|
return [.../* @__PURE__ */ new Set([...derived, ...explicit])].sort((a2, b) => a2 - b);
|
|
@@ -192405,7 +192964,7 @@ var SIDE_NORMAL = {
|
|
|
192405
192964
|
left: { x: -1, y: 0 }
|
|
192406
192965
|
};
|
|
192407
192966
|
var clampOffset = (v) => Math.max(0.06, Math.min(0.94, v));
|
|
192408
|
-
function usePortDrag(containerRef, w, h, onPortMove, onPortPreview, onSelect) {
|
|
192967
|
+
function usePortDrag(containerRef, w, h, topReserve, onPortMove, onPortPreview, onSelect) {
|
|
192409
192968
|
const [dragId, setDragId] = (0, import_react8.useState)(void 0);
|
|
192410
192969
|
const onPortPointerDown = (portId, e, draggable = true) => {
|
|
192411
192970
|
if (e.button !== 0) return;
|
|
@@ -192422,12 +192981,8 @@ function usePortDrag(containerRef, w, h, onPortMove, onPortPreview, onSelect) {
|
|
|
192422
192981
|
const placement = (cx, cy) => {
|
|
192423
192982
|
const lx = rect.width ? (cx - rect.left) / rect.width * w : 0;
|
|
192424
192983
|
const ly = rect.height ? (cy - rect.top) / rect.height * h : 0;
|
|
192425
|
-
const
|
|
192426
|
-
|
|
192427
|
-
if (m === dt) return { side: "top", offset: clampOffset(lx / w) };
|
|
192428
|
-
if (m === db) return { side: "bottom", offset: clampOffset(lx / w) };
|
|
192429
|
-
if (m === dl) return { side: "left", offset: clampOffset(ly / h) };
|
|
192430
|
-
return { side: "right", offset: clampOffset(ly / h) };
|
|
192984
|
+
const nearest = nearestPortOwnerPlacement(lx, ly, w, h, topReserve);
|
|
192985
|
+
return { side: nearest.side, offset: clampOffset(nearest.offset) };
|
|
192431
192986
|
};
|
|
192432
192987
|
const move = (ev) => {
|
|
192433
192988
|
if (!moved && Math.hypot(ev.clientX - sx, ev.clientY - sy) < 4) return;
|
|
@@ -192450,18 +193005,6 @@ function usePortDrag(containerRef, w, h, onPortMove, onPortPreview, onSelect) {
|
|
|
192450
193005
|
};
|
|
192451
193006
|
return { dragId, onPortPointerDown };
|
|
192452
193007
|
}
|
|
192453
|
-
function sideXY(side, offset2, w, h) {
|
|
192454
|
-
switch (side) {
|
|
192455
|
-
case "top":
|
|
192456
|
-
return { x: w * offset2, y: 0 };
|
|
192457
|
-
case "bottom":
|
|
192458
|
-
return { x: w * offset2, y: h };
|
|
192459
|
-
case "left":
|
|
192460
|
-
return { x: 0, y: h * offset2 };
|
|
192461
|
-
case "right":
|
|
192462
|
-
return { x: w, y: h * offset2 };
|
|
192463
|
-
}
|
|
192464
|
-
}
|
|
192465
193008
|
function DualHandle({ id: id2, side, x, y, kind, active, connectable = true, startable = false, size }) {
|
|
192466
193009
|
const style2 = size !== void 0 ? { left: x, top: y, width: size, height: size, transform: "translate(-50%,-50%)" } : { left: x, top: y, transform: "translate(-50%,-50%)" };
|
|
192467
193010
|
const cls = `rf-handle rf-handle-${kind}${active ? " active" : ""}`;
|
|
@@ -192512,16 +193055,22 @@ function fitKind(s, availPx) {
|
|
|
192512
193055
|
function FullTitle({ full, shown }) {
|
|
192513
193056
|
return shown === full ? null : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("title", { children: full });
|
|
192514
193057
|
}
|
|
192515
|
-
function compartmentTops(node, top =
|
|
193058
|
+
function compartmentTops(node, top = NODE_COMPARTMENT_TOP) {
|
|
192516
193059
|
const comps = node.compartments ?? [];
|
|
192517
193060
|
const tops = [];
|
|
192518
193061
|
let acc = top;
|
|
192519
193062
|
for (const c of comps) {
|
|
192520
193063
|
tops.push(acc);
|
|
192521
|
-
acc +=
|
|
193064
|
+
acc += compartmentBlockHeight(c.items.length);
|
|
192522
193065
|
}
|
|
192523
193066
|
return { tops, comps };
|
|
192524
193067
|
}
|
|
193068
|
+
function containerBandBottom(node, top) {
|
|
193069
|
+
return top + (node.compartments ?? []).reduce((h, c) => h + compartmentBlockHeight(c.items.length), 0);
|
|
193070
|
+
}
|
|
193071
|
+
function ContainerBandRule({ w, y }) {
|
|
193072
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { className: "dcompartment-rule closing", x1: 0, y1: y, x2: w, y2: y });
|
|
193073
|
+
}
|
|
192525
193074
|
function Compartments({ node, w, top }) {
|
|
192526
193075
|
const { tops, comps } = compartmentTops(node, top);
|
|
192527
193076
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: comps.map((c, ci) => {
|
|
@@ -192529,13 +193078,13 @@ function Compartments({ node, w, top }) {
|
|
|
192529
193078
|
const title = fitKind(c.title, w - 16);
|
|
192530
193079
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("g", { className: "dnode-compartment", children: [
|
|
192531
193080
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { className: "dcompartment-rule", x1: 0, y1: cy, x2: w, y2: cy }),
|
|
192532
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("text", { className: "dnode-kind", x: 8, y: cy +
|
|
193081
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("text", { className: "dnode-kind", x: 8, y: cy + COMPARTMENT_TITLE_BASELINE, children: [
|
|
192533
193082
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FullTitle, { full: c.title, shown: title }),
|
|
192534
193083
|
title
|
|
192535
193084
|
] }),
|
|
192536
193085
|
c.items.map((it, i) => {
|
|
192537
193086
|
const shown = fitText(it.text, w - 20, 10);
|
|
192538
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("text", { className: "dnode-label", x: 12, y: cy +
|
|
193087
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("text", { className: "dnode-label", x: 12, y: cy + COMPARTMENT_ROW_BASELINE + i * COMPARTMENT_ROW_HEIGHT, style: { fontSize: 10 }, children: [
|
|
192539
193088
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FullTitle, { full: it.text, shown }),
|
|
192540
193089
|
shown
|
|
192541
193090
|
] }, i);
|
|
@@ -192548,37 +193097,53 @@ function variabilityMark(keyword) {
|
|
|
192548
193097
|
if (/^variant\b/.test(keyword)) return " \u25C6";
|
|
192549
193098
|
return "";
|
|
192550
193099
|
}
|
|
193100
|
+
function nodeShowsControls(node) {
|
|
193101
|
+
return node.meta?.containerControls === true;
|
|
193102
|
+
}
|
|
193103
|
+
function titleNameLine(name, type, mult, alias, availPx) {
|
|
193104
|
+
const suffixChars = (mult ? mult.length + 1 : 0) + (alias ? alias.length + 9 : 0);
|
|
193105
|
+
const budget = Math.max(6, fitChars(availPx, 11) - suffixChars);
|
|
193106
|
+
let nameShown = name;
|
|
193107
|
+
let typeShown = type;
|
|
193108
|
+
if (type) {
|
|
193109
|
+
if (name.length + 3 + type.length > budget) {
|
|
193110
|
+
const nameMax = Math.max(4, Math.min(name.length, Math.ceil(budget * 0.6)));
|
|
193111
|
+
nameShown = clipText(name, nameMax);
|
|
193112
|
+
typeShown = clipText(type, Math.max(3, budget - nameShown.length - 3));
|
|
193113
|
+
}
|
|
193114
|
+
} else {
|
|
193115
|
+
nameShown = clipText(name, budget);
|
|
193116
|
+
}
|
|
193117
|
+
return {
|
|
193118
|
+
nameShown,
|
|
193119
|
+
typeShown,
|
|
193120
|
+
full: `${name}${type ? ` : ${type}` : ""}`,
|
|
193121
|
+
shown: `${nameShown}${typeShown ? ` : ${typeShown}` : ""}`
|
|
193122
|
+
};
|
|
193123
|
+
}
|
|
192551
193124
|
function BoxBody({ node, w, h, showMult }) {
|
|
192552
|
-
const rx = node.isDef
|
|
193125
|
+
const rx = nodeCornerRadius(node.shape, node.isDef, h, false);
|
|
192553
193126
|
const cls = node.keyword.startsWith("requirement") ? "req" : "";
|
|
192554
|
-
const
|
|
193127
|
+
const titleArea = containerTitleArea(w, nodeShowsControls(node));
|
|
193128
|
+
const cx = titleArea.centerX;
|
|
192555
193129
|
const kindFull = `\xAB${node.keyword}\xBB${variabilityMark(node.keyword)}`;
|
|
192556
|
-
const kindShown = fitKind(kindFull,
|
|
192557
|
-
const avail = Math.max(24, w - 12);
|
|
193130
|
+
const kindShown = fitKind(kindFull, Math.max(24, titleArea.width - 8));
|
|
192558
193131
|
const mult = showMult && node.multiplicity ? node.multiplicity : void 0;
|
|
192559
193132
|
const alias = node.meta?.alias ? String(node.meta.alias) : void 0;
|
|
192560
|
-
const
|
|
192561
|
-
|
|
192562
|
-
|
|
192563
|
-
|
|
192564
|
-
|
|
192565
|
-
|
|
192566
|
-
|
|
192567
|
-
nameShown = clipText(node.name, nameMax);
|
|
192568
|
-
typeShown = clipText(node.type, Math.max(3, budget - nameShown.length - 3));
|
|
192569
|
-
}
|
|
192570
|
-
} else {
|
|
192571
|
-
nameShown = clipText(node.name, budget);
|
|
192572
|
-
}
|
|
192573
|
-
const fullTitle = `${node.name}${node.type ? ` : ${node.type}` : ""}`;
|
|
192574
|
-
const shownTitle = `${nameShown}${typeShown ? ` : ${typeShown}` : ""}`;
|
|
193133
|
+
const { nameShown, typeShown, full: fullTitle, shown: shownTitle } = titleNameLine(
|
|
193134
|
+
node.name,
|
|
193135
|
+
node.type,
|
|
193136
|
+
mult,
|
|
193137
|
+
alias,
|
|
193138
|
+
Math.max(24, titleArea.width - 12)
|
|
193139
|
+
);
|
|
192575
193140
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("g", { children: [
|
|
192576
193141
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("rect", { className: `dnode-rect ${cls}`, x: 0, y: 0, width: w, height: h, rx }),
|
|
192577
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("text", { className: "dnode-kind", x: cx, y:
|
|
193142
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("text", { className: "dnode-kind", x: cx, y: CONTAINER_TITLE_KIND_BASELINE, textAnchor: "middle", children: [
|
|
192578
193143
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FullTitle, { full: kindFull, shown: kindShown }),
|
|
192579
193144
|
kindShown
|
|
192580
193145
|
] }),
|
|
192581
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("text", { className: `dnode-label ${node.abstract ? "abstract" : ""}`, x: cx, y:
|
|
193146
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("text", { className: `dnode-label ${node.abstract ? "abstract" : ""}`, x: cx, y: CONTAINER_TITLE_NAME_BASELINE, textAnchor: "middle", children: [
|
|
192582
193147
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FullTitle, { full: fullTitle, shown: shownTitle }),
|
|
192583
193148
|
nameShown,
|
|
192584
193149
|
typeShown ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
@@ -192594,41 +193159,57 @@ function BoxBody({ node, w, h, showMult }) {
|
|
|
192594
193159
|
alias
|
|
192595
193160
|
] }) : ""
|
|
192596
193161
|
] }),
|
|
192597
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Compartments, { node, w })
|
|
193162
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Compartments, { node, w }),
|
|
193163
|
+
nodeShowsControls(node) ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ContainerBandRule, { w, y: containerBandBottom(node, NODE_COMPARTMENT_TOP) }) : null
|
|
192598
193164
|
] });
|
|
192599
193165
|
}
|
|
192600
|
-
function RoundedBody({ node, w, h, cls }) {
|
|
192601
|
-
const r = node.isDef ? 0 : Math.min(h / 2, 20);
|
|
193166
|
+
function RoundedBody({ node, w, h, cls, showMult }) {
|
|
192602
193167
|
const comps = node.compartments ?? [];
|
|
193168
|
+
const r = nodeCornerRadius(node.shape, node.isDef, h, comps.length > 0);
|
|
192603
193169
|
const composite = node.meta?.composite === true ? " composite" : "";
|
|
192604
193170
|
const kindFull = `\xAB${node.keyword}\xBB${node.meta?.parallel ? " \u2225" : ""}${variabilityMark(node.keyword)}`;
|
|
192605
|
-
const
|
|
192606
|
-
const
|
|
193171
|
+
const titleArea = containerTitleArea(w, nodeShowsControls(node));
|
|
193172
|
+
const cx = titleArea.centerX;
|
|
193173
|
+
const kindShown = fitKind(kindFull, Math.max(24, titleArea.width - 8));
|
|
193174
|
+
const mult = showMult && node.multiplicity ? node.multiplicity : void 0;
|
|
193175
|
+
const { nameShown, typeShown, full: fullTitle, shown: shownTitle } = titleNameLine(
|
|
193176
|
+
node.name,
|
|
193177
|
+
node.type,
|
|
193178
|
+
mult,
|
|
193179
|
+
void 0,
|
|
193180
|
+
Math.max(24, titleArea.width - 12)
|
|
193181
|
+
);
|
|
193182
|
+
const nameLine = (y) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("text", { className: "dnode-label", x: cx, y, textAnchor: "middle", children: [
|
|
193183
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FullTitle, { full: fullTitle, shown: shownTitle }),
|
|
193184
|
+
nameShown,
|
|
193185
|
+
typeShown ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
193186
|
+
" : ",
|
|
193187
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("tspan", { className: "dnode-type", children: typeShown })
|
|
193188
|
+
] }) : "",
|
|
193189
|
+
mult ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("tspan", { className: "dnode-kind", children: [
|
|
193190
|
+
" ",
|
|
193191
|
+
mult
|
|
193192
|
+
] }) : ""
|
|
193193
|
+
] });
|
|
192607
193194
|
if (comps.length > 0) {
|
|
192608
|
-
const cx = w / 2;
|
|
192609
193195
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("g", { children: [
|
|
192610
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("rect", { className: `dnode-rect ${cls}${composite}`, x: 0, y: 0, width: w, height: h, rx:
|
|
192611
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("text", { className: "dnode-kind", x: cx, y:
|
|
193196
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("rect", { className: `dnode-rect ${cls}${composite}`, x: 0, y: 0, width: w, height: h, rx: r }),
|
|
193197
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("text", { className: "dnode-kind", x: cx, y: CONTAINER_TITLE_KIND_BASELINE, textAnchor: "middle", children: [
|
|
192612
193198
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FullTitle, { full: kindFull, shown: kindShown }),
|
|
192613
193199
|
kindShown
|
|
192614
193200
|
] }),
|
|
192615
|
-
|
|
192616
|
-
|
|
192617
|
-
|
|
192618
|
-
] }),
|
|
192619
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Compartments, { node, w })
|
|
193201
|
+
nameLine(CONTAINER_TITLE_NAME_BASELINE),
|
|
193202
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Compartments, { node, w }),
|
|
193203
|
+
nodeShowsControls(node) ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ContainerBandRule, { w, y: containerBandBottom(node, NODE_COMPARTMENT_TOP) }) : null
|
|
192620
193204
|
] });
|
|
192621
193205
|
}
|
|
192622
193206
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("g", { children: [
|
|
192623
193207
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("rect", { className: `dnode-rect ${cls}${composite}`, x: 0, y: 0, width: w, height: h, rx: r }),
|
|
192624
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("text", { className: "dnode-
|
|
192625
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FullTitle, { full: node.name, shown: nameShown }),
|
|
192626
|
-
nameShown
|
|
192627
|
-
] }),
|
|
192628
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("text", { className: "dnode-kind", x: w / 2, y: h / 2 + 12, textAnchor: "middle", children: [
|
|
193208
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("text", { className: "dnode-kind", x: cx, y: h / 2 - 4, textAnchor: "middle", children: [
|
|
192629
193209
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FullTitle, { full: kindFull, shown: kindShown }),
|
|
192630
193210
|
kindShown
|
|
192631
|
-
] })
|
|
193211
|
+
] }),
|
|
193212
|
+
nameLine(h / 2 + 11)
|
|
192632
193213
|
] });
|
|
192633
193214
|
}
|
|
192634
193215
|
function UseCaseBody({ node, w, h }) {
|
|
@@ -192809,8 +193390,8 @@ function LifelineBody({ node, w, lineBottom, activation, eventMarks }) {
|
|
|
192809
193390
|
] })
|
|
192810
193391
|
] });
|
|
192811
193392
|
}
|
|
192812
|
-
function PortGlyph({ ph, w, h, showLabels, selected: selected2, hovered, moving, connectTarget, connectStart, onSelect, onContext }) {
|
|
192813
|
-
const rect = portGlyphRect(ph, w, h);
|
|
193393
|
+
function PortGlyph({ ph, w, h, topReserve = 0, showLabels, selected: selected2, hovered, moving, connectTarget, connectStart, onSelect, onContext }) {
|
|
193394
|
+
const rect = portGlyphRect(ph, w, h, topReserve);
|
|
192814
193395
|
const x = rect.cx;
|
|
192815
193396
|
const y = rect.cy;
|
|
192816
193397
|
const half = rect.across / 2;
|
|
@@ -192930,12 +193511,12 @@ function PortGlyph({ ph, w, h, showLabels, selected: selected2, hovered, moving,
|
|
|
192930
193511
|
}
|
|
192931
193512
|
);
|
|
192932
193513
|
}
|
|
192933
|
-
function NestedPortToggles({ ports, w, h, onToggle }) {
|
|
193514
|
+
function NestedPortToggles({ ports, w, h, topReserve = 0, onToggle }) {
|
|
192934
193515
|
const hosts = ports.filter((ph) => ph.port.meta?.nestedHost === true);
|
|
192935
193516
|
if (!hosts.length) return null;
|
|
192936
193517
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: hosts.map((ph) => {
|
|
192937
193518
|
const expanded2 = ph.port.meta?.nestedExpanded === true;
|
|
192938
|
-
const at = nestedPortTogglePoint(portGlyphRect(ph, w, h), ph.side);
|
|
193519
|
+
const at = nestedPortTogglePoint(portGlyphRect(ph, w, h, topReserve), ph.side);
|
|
192939
193520
|
const what = ph.port.pin ? "parameters" : "ports";
|
|
192940
193521
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
192941
193522
|
"button",
|
|
@@ -192966,6 +193547,84 @@ function NestedPortToggles({ ports, w, h, onToggle }) {
|
|
|
192966
193547
|
);
|
|
192967
193548
|
}) });
|
|
192968
193549
|
}
|
|
193550
|
+
function ContainerControlGlyph({ kind, expanded: expanded2 }) {
|
|
193551
|
+
const c = CONTAINER_GLYPH_VIEWBOX / 2;
|
|
193552
|
+
const half = CONTAINER_GLYPH_EXTENT / 2;
|
|
193553
|
+
const box = CONTAINER_GLYPH_EXTENT;
|
|
193554
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
193555
|
+
"svg",
|
|
193556
|
+
{
|
|
193557
|
+
className: kind === "internals" ? "internals-glyph" : "feature-list-glyph",
|
|
193558
|
+
viewBox: `0 0 ${CONTAINER_GLYPH_VIEWBOX} ${CONTAINER_GLYPH_VIEWBOX}`,
|
|
193559
|
+
width: CONTAINER_GLYPH_VIEWBOX,
|
|
193560
|
+
height: CONTAINER_GLYPH_VIEWBOX,
|
|
193561
|
+
"aria-hidden": "true",
|
|
193562
|
+
children: kind === "internals" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("g", { stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", children: [
|
|
193563
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: c - half, y1: c, x2: c + half, y2: c }),
|
|
193564
|
+
expanded2 ? null : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: c, y1: c - half, x2: c, y2: c + half })
|
|
193565
|
+
] }) : (
|
|
193566
|
+
// A compartment box carrying its rows while the list is HIDDEN and
|
|
193567
|
+
// empty once it is shown (user direction 2026-08-11, correcting the
|
|
193568
|
+
// first reading: "in collapsed state show hamburger menu"). Like
|
|
193569
|
+
// the `+` beside it, the mark advertises what pressing it reveals,
|
|
193570
|
+
// so no colour has to carry the state. The rows are spaced evenly
|
|
193571
|
+
// about the centre line, so the glyph reads as centred either way.
|
|
193572
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("g", { stroke: "currentColor", fill: "none", children: [
|
|
193573
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("rect", { x: c - half, y: c - half, width: box, height: box, rx: 1.5, strokeWidth: "1.4" }),
|
|
193574
|
+
expanded2 ? null : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("g", { strokeWidth: "1.2", strokeLinecap: "round", children: [
|
|
193575
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: c - half + 2.5, y1: c - 1.6, x2: c + half - 2.5, y2: c - 1.6 }),
|
|
193576
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: c - half + 2.5, y1: c + 1.6, x2: c + half - 2.5, y2: c + 1.6 })
|
|
193577
|
+
] })
|
|
193578
|
+
] })
|
|
193579
|
+
)
|
|
193580
|
+
}
|
|
193581
|
+
);
|
|
193582
|
+
}
|
|
193583
|
+
function ContainerControls({
|
|
193584
|
+
id: id2,
|
|
193585
|
+
label,
|
|
193586
|
+
internalNoun,
|
|
193587
|
+
internalsVisible,
|
|
193588
|
+
featureCompartmentsVisible,
|
|
193589
|
+
cornerRadius,
|
|
193590
|
+
onToggleInternals,
|
|
193591
|
+
onToggleFeatureCompartments
|
|
193592
|
+
}) {
|
|
193593
|
+
if (!onToggleInternals && !onToggleFeatureCompartments) return null;
|
|
193594
|
+
const inset = containerControlsInset(cornerRadius);
|
|
193595
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dcontainer-controls nodrag", style: { right: inset, top: inset }, children: [
|
|
193596
|
+
onToggleFeatureCompartments ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
193597
|
+
"button",
|
|
193598
|
+
{
|
|
193599
|
+
className: "dfeature-toggle nodrag",
|
|
193600
|
+
title: `${featureCompartmentsVisible ? "Hide" : "Show"} feature compartments`,
|
|
193601
|
+
"aria-label": `${featureCompartmentsVisible ? "Hide" : "Show"} feature compartments of ${label}`,
|
|
193602
|
+
"aria-pressed": featureCompartmentsVisible,
|
|
193603
|
+
onPointerDown: (e) => e.stopPropagation(),
|
|
193604
|
+
onClick: (e) => {
|
|
193605
|
+
e.stopPropagation();
|
|
193606
|
+
onToggleFeatureCompartments(id2);
|
|
193607
|
+
},
|
|
193608
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ContainerControlGlyph, { kind: "featureList", expanded: featureCompartmentsVisible })
|
|
193609
|
+
}
|
|
193610
|
+
) : null,
|
|
193611
|
+
onToggleInternals ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
193612
|
+
"button",
|
|
193613
|
+
{
|
|
193614
|
+
className: "div-part-toggle nodrag",
|
|
193615
|
+
title: `${internalsVisible ? "Hide" : "Show"} ${internalNoun}`,
|
|
193616
|
+
"aria-label": `${internalsVisible ? "Hide" : "Show"} ${internalNoun} of ${label}`,
|
|
193617
|
+
"aria-pressed": internalsVisible,
|
|
193618
|
+
onPointerDown: (e) => e.stopPropagation(),
|
|
193619
|
+
onClick: (e) => {
|
|
193620
|
+
e.stopPropagation();
|
|
193621
|
+
onToggleInternals(id2);
|
|
193622
|
+
},
|
|
193623
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ContainerControlGlyph, { kind: "internals", expanded: internalsVisible })
|
|
193624
|
+
}
|
|
193625
|
+
) : null
|
|
193626
|
+
] });
|
|
193627
|
+
}
|
|
192969
193628
|
function InlineEditor({ initial, mode, elementKind, onCommit, onCancel, w }) {
|
|
192970
193629
|
const ref = (0, import_react8.useRef)(null);
|
|
192971
193630
|
(0, import_react8.useEffect)(() => {
|
|
@@ -193011,13 +193670,18 @@ var BAND_HEADER_PX = 26;
|
|
|
193011
193670
|
var BAND_MIN_W2 = 200;
|
|
193012
193671
|
var BAND_MIN_H2 = 80;
|
|
193013
193672
|
var SMALL_GLYPH_SHAPES = /* @__PURE__ */ new Set(["initial", "final", "terminate", "dot", "fork", "join", "decision", "merge"]);
|
|
193673
|
+
var INTERNAL_NOUN = {
|
|
193674
|
+
iv: "internal parts",
|
|
193675
|
+
afv: "nested actions",
|
|
193676
|
+
stv: "sub-states"
|
|
193677
|
+
};
|
|
193014
193678
|
function shapeBody(node, data) {
|
|
193015
193679
|
const { w, h, showMult } = data;
|
|
193016
193680
|
switch (node.shape) {
|
|
193017
193681
|
case "state":
|
|
193018
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RoundedBody, { node, w, h, cls: "state" });
|
|
193682
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RoundedBody, { node, w, h, cls: "state", showMult });
|
|
193019
193683
|
case "action":
|
|
193020
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RoundedBody, { node, w, h, cls: "action" });
|
|
193684
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RoundedBody, { node, w, h, cls: "action", showMult });
|
|
193021
193685
|
case "initial":
|
|
193022
193686
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(InitialBody, { w, h });
|
|
193023
193687
|
case "final":
|
|
@@ -193067,6 +193731,7 @@ function NodeBody({ node, data, selectedPortId, hoveredPortId, movingPortId, con
|
|
|
193067
193731
|
ph,
|
|
193068
193732
|
w,
|
|
193069
193733
|
h,
|
|
193734
|
+
topReserve: featureBandTopReserve(data),
|
|
193070
193735
|
showLabels: data.showPortLabels,
|
|
193071
193736
|
selected: selectedPortId === ph.port.id,
|
|
193072
193737
|
hovered: hoveredPortId === ph.port.id,
|
|
@@ -193096,15 +193761,26 @@ function SysmlNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
193096
193761
|
const dim = useInteraction(ctx.store, (s) => s.matchedIds ? !s.matchedIds.has(id2) : false);
|
|
193097
193762
|
const editing = useInteraction(ctx.store, (s) => s.editing?.nodeId === id2 && !s.editing?.at && !s.editing?.edgeId ? s.editing : void 0);
|
|
193098
193763
|
const editingHere = editing !== void 0;
|
|
193099
|
-
const
|
|
193100
|
-
const
|
|
193764
|
+
const hiddenContainer = node.meta?.internalsHidden === true;
|
|
193765
|
+
const showsControls = nodeShowsControls(node);
|
|
193766
|
+
const internalNoun = INTERNAL_NOUN[data.kind] ?? "internal parts";
|
|
193767
|
+
const featureCompartmentsVisible = node.meta?.featureCompartmentsVisible === true;
|
|
193768
|
+
const featureCompartmentHeight = featureBandTopReserve(data);
|
|
193101
193769
|
const containerRef = (0, import_react8.useRef)(null);
|
|
193102
193770
|
const portSource = (pid) => {
|
|
193103
193771
|
const p = node.ports?.find((pp) => pp.id === pid);
|
|
193104
193772
|
ctx.onPortSelected?.();
|
|
193105
193773
|
ctx.onReveal(p?.source, pid);
|
|
193106
193774
|
};
|
|
193107
|
-
const { dragId, onPortPointerDown } = usePortDrag(
|
|
193775
|
+
const { dragId, onPortPointerDown } = usePortDrag(
|
|
193776
|
+
containerRef,
|
|
193777
|
+
w,
|
|
193778
|
+
h,
|
|
193779
|
+
featureCompartmentHeight,
|
|
193780
|
+
ctx.onPortMove,
|
|
193781
|
+
ctx.onPortPreview,
|
|
193782
|
+
portSource
|
|
193783
|
+
);
|
|
193108
193784
|
const ports = data.ports;
|
|
193109
193785
|
const liveData = { ...data, w, h, ports };
|
|
193110
193786
|
const directRelation = directRelationForHandle(data.kind, {
|
|
@@ -193144,7 +193820,9 @@ function SysmlNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
193144
193820
|
children: [
|
|
193145
193821
|
resizable ? (() => {
|
|
193146
193822
|
const min2 = resizeMinFor(node.shape, h);
|
|
193147
|
-
|
|
193823
|
+
const minWidth = showsControls ? Math.max(min2.minWidth, COLLAPSED_CONTAINER_MIN_WIDTH) : min2.minWidth;
|
|
193824
|
+
const minHeight = Math.max(min2.minHeight, data.featureCompartmentMinHeight ?? 0);
|
|
193825
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(NodeResizer, { minWidth, minHeight, maxHeight: min2.maxHeight, isVisible: true, color: "var(--accent)" });
|
|
193148
193826
|
})() : null,
|
|
193149
193827
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
193150
193828
|
NodeBody,
|
|
@@ -193160,12 +193838,25 @@ function SysmlNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
193160
193838
|
onPortContext: ctx.onContextNode
|
|
193161
193839
|
}
|
|
193162
193840
|
),
|
|
193841
|
+
data.kind === "iv" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
193842
|
+
"div",
|
|
193843
|
+
{
|
|
193844
|
+
className: "rf-node-header",
|
|
193845
|
+
title: node.name,
|
|
193846
|
+
style: {
|
|
193847
|
+
left: 0,
|
|
193848
|
+
top: 0,
|
|
193849
|
+
height: NODE_COMPARTMENT_TOP,
|
|
193850
|
+
width: containerTitleArea(w, nodeShowsControls(node)).width
|
|
193851
|
+
}
|
|
193852
|
+
}
|
|
193853
|
+
) : null,
|
|
193163
193854
|
SIDES.flatMap((side, si) => {
|
|
193164
193855
|
const n2 = SIDE_NORMAL[side];
|
|
193165
193856
|
const out = SMALL_GLYPH_SHAPES.has(node.shape) ? 9 : 0;
|
|
193166
193857
|
const offsets = sideOffsets[si];
|
|
193167
193858
|
return offsets.map((offset2, i) => {
|
|
193168
|
-
const { x, y } = sideSurfacePoint(node.shape, side, offset2, w, h);
|
|
193859
|
+
const { x, y } = sideSurfacePoint(node.shape, side, offset2, w, h, featureCompartmentHeight);
|
|
193169
193860
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
193170
193861
|
DualHandle,
|
|
193171
193862
|
{
|
|
@@ -193182,7 +193873,7 @@ function SysmlNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
193182
193873
|
});
|
|
193183
193874
|
}),
|
|
193184
193875
|
ports.flatMap((ph) => {
|
|
193185
|
-
const rect = portGlyphRect(ph, w, h);
|
|
193876
|
+
const rect = portGlyphRect(ph, w, h, featureCompartmentHeight);
|
|
193186
193877
|
const c = { x: rect.cx, y: rect.cy };
|
|
193187
193878
|
const startable = directRelationForHandle(data.kind, {
|
|
193188
193879
|
id: ph.port.id,
|
|
@@ -193203,7 +193894,7 @@ function SysmlNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
193203
193894
|
];
|
|
193204
193895
|
}),
|
|
193205
193896
|
ctx.onPortMove ? ports.map((ph) => {
|
|
193206
|
-
const rect = portGlyphRect(ph, w, h);
|
|
193897
|
+
const rect = portGlyphRect(ph, w, h, featureCompartmentHeight);
|
|
193207
193898
|
const nestedChild = ph.port.parentPort !== void 0;
|
|
193208
193899
|
const strip = portInteractionStrip(rect, ph.side);
|
|
193209
193900
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
@@ -193237,20 +193928,27 @@ function SysmlNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
193237
193928
|
}
|
|
193238
193929
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: handles });
|
|
193239
193930
|
})() : null,
|
|
193240
|
-
ctx.onToggleNestedPort ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
193241
|
-
|
|
193242
|
-
"button",
|
|
193931
|
+
ctx.onToggleNestedPort ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
193932
|
+
NestedPortToggles,
|
|
193243
193933
|
{
|
|
193244
|
-
|
|
193245
|
-
|
|
193246
|
-
|
|
193247
|
-
|
|
193248
|
-
|
|
193249
|
-
|
|
193250
|
-
|
|
193251
|
-
|
|
193252
|
-
|
|
193253
|
-
|
|
193934
|
+
ports,
|
|
193935
|
+
w,
|
|
193936
|
+
h,
|
|
193937
|
+
topReserve: featureCompartmentHeight,
|
|
193938
|
+
onToggle: ctx.onToggleNestedPort
|
|
193939
|
+
}
|
|
193940
|
+
) : null,
|
|
193941
|
+
showsControls ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
193942
|
+
ContainerControls,
|
|
193943
|
+
{
|
|
193944
|
+
id: id2,
|
|
193945
|
+
label: node.name,
|
|
193946
|
+
internalNoun,
|
|
193947
|
+
internalsVisible: !hiddenContainer,
|
|
193948
|
+
featureCompartmentsVisible,
|
|
193949
|
+
cornerRadius: nodeCornerRadius(node.shape, node.isDef, h, (node.compartments?.length ?? 0) > 0),
|
|
193950
|
+
onToggleInternals: ctx.onToggleInternals,
|
|
193951
|
+
onToggleFeatureCompartments: ctx.onToggleFeatureCompartments
|
|
193254
193952
|
}
|
|
193255
193953
|
) : null,
|
|
193256
193954
|
editingHere && ctx.onEditCommit && ctx.onEditCancel ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
@@ -193286,6 +193984,23 @@ function packageFramePath(w, h) {
|
|
|
193286
193984
|
"Z"
|
|
193287
193985
|
].join(" ");
|
|
193288
193986
|
}
|
|
193987
|
+
function frameFeatureBandPath(w, h, bottom, radius) {
|
|
193988
|
+
const left = 1;
|
|
193989
|
+
const right = Math.max(left, w - 1);
|
|
193990
|
+
const top = 1;
|
|
193991
|
+
const end = Math.max(top, Math.min(bottom, h - 1));
|
|
193992
|
+
const r = Math.max(0, Math.min(radius, (right - left) / 2, end - top));
|
|
193993
|
+
if (r === 0) return `M ${left} ${top} H ${right} V ${end} H ${left} Z`;
|
|
193994
|
+
return [
|
|
193995
|
+
`M ${left} ${top + r}`,
|
|
193996
|
+
`Q ${left} ${top} ${left + r} ${top}`,
|
|
193997
|
+
`H ${right - r}`,
|
|
193998
|
+
`Q ${right} ${top} ${right} ${top + r}`,
|
|
193999
|
+
`V ${end}`,
|
|
194000
|
+
`H ${left}`,
|
|
194001
|
+
"Z"
|
|
194002
|
+
].join(" ");
|
|
194003
|
+
}
|
|
193289
194004
|
function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
193290
194005
|
const ctx = useDiagram();
|
|
193291
194006
|
const frame2 = data.frame;
|
|
@@ -193300,13 +194015,30 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
193300
194015
|
const isPackage2 = frame2.keyword === "package";
|
|
193301
194016
|
const isLibraryPackage = isPackage2 && frame2.meta?.library === true;
|
|
193302
194017
|
const resizable = selected2 && (!isPackage2 || data.kind === "gv");
|
|
193303
|
-
const collapsible = isCollapsibleFrame(data.kind, frame2)
|
|
194018
|
+
const collapsible = isCollapsibleFrame(data.kind, frame2);
|
|
194019
|
+
const controllable = collapsible && (ctx.onToggleInternals !== void 0 || ctx.onToggleFeatureCompartments !== void 0);
|
|
194020
|
+
const internalNoun = INTERNAL_NOUN[data.kind] ?? "internal parts";
|
|
194021
|
+
const featureCompartmentsVisible = frame2.meta?.featureCompartmentsVisible === true;
|
|
194022
|
+
const featureBandHeight = data.featureCompartmentHeight ?? frameFeatureCompartmentHeight(frame2);
|
|
194023
|
+
const featureCompartmentHeight = featureBandHeight > 0 ? FRAME_TITLE_HEIGHT + featureBandHeight : 0;
|
|
194024
|
+
const bandBottom = containerBandBottom(
|
|
194025
|
+
featureBandHeight > 0 ? frame2 : { compartments: void 0 },
|
|
194026
|
+
FRAME_TITLE_HEIGHT
|
|
194027
|
+
);
|
|
193304
194028
|
const containerRef = (0, import_react8.useRef)(null);
|
|
193305
194029
|
const portSource = (pid) => {
|
|
193306
194030
|
ctx.onPortSelected?.();
|
|
193307
194031
|
ctx.onReveal(frame2.ports?.find((p) => p.id === pid)?.source, pid);
|
|
193308
194032
|
};
|
|
193309
|
-
const { dragId, onPortPointerDown } = usePortDrag(
|
|
194033
|
+
const { dragId, onPortPointerDown } = usePortDrag(
|
|
194034
|
+
containerRef,
|
|
194035
|
+
w,
|
|
194036
|
+
h,
|
|
194037
|
+
featureCompartmentHeight,
|
|
194038
|
+
ctx.onPortMove,
|
|
194039
|
+
ctx.onPortPreview,
|
|
194040
|
+
portSource
|
|
194041
|
+
);
|
|
193310
194042
|
const ports = data.ports;
|
|
193311
194043
|
const showPorts = ports.length > 0;
|
|
193312
194044
|
const isOuterViewFrame = (data.kind === "afv" || data.kind === "stv") && frame2.meta?.anchorFrame === true;
|
|
@@ -193345,32 +194077,59 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
193345
194077
|
ctx.onContextNode(id2, e.clientX, e.clientY);
|
|
193346
194078
|
},
|
|
193347
194079
|
children: [
|
|
193348
|
-
resizable ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
194080
|
+
resizable ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
194081
|
+
NodeResizer,
|
|
194082
|
+
{
|
|
194083
|
+
minWidth: isPackage2 ? 180 : 80,
|
|
194084
|
+
minHeight: Math.max(isPackage2 ? 100 : 60, data.featureCompartmentMinHeight ?? 0),
|
|
194085
|
+
isVisible: true,
|
|
194086
|
+
color: "var(--accent)"
|
|
194087
|
+
}
|
|
194088
|
+
) : null,
|
|
193349
194089
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { className: "rf-node-svg", width: w, height: h, style: { overflow: "visible" }, children: [
|
|
193350
194090
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("rect", { className: "dframe-hover-band", x: 0, y: 0, width: w, height: h, rx: 12, fill: "none", stroke: "transparent" }),
|
|
193351
194091
|
isPackage2 && data.kind === "gv" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { className: `dframe-rect package${isLibraryPackage ? " library" : ""}${data.isContainer ? " container" : ""}`, d: packageFramePath(w, h) }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("rect", { className: `dframe-rect${data.isContainer ? " container" : ""}${frame2.meta?.boundaryBox === true ? " boundary" : ""}${frame2.meta?.parallel === true ? " parallel" : ""}${frame2.meta?.loop === true ? " loop" : ""}${frame2.meta?.performerLane === true ? " performer" : ""}`, x: 0, y: 0, width: w, height: h, rx: frame2.isDef === true ? 0 : 12 }),
|
|
194092
|
+
collapsible ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
194093
|
+
"path",
|
|
194094
|
+
{
|
|
194095
|
+
className: "dfeature-band-bg",
|
|
194096
|
+
d: frameFeatureBandPath(w, h, bandBottom, frame2.isDef === true ? 0 : 12)
|
|
194097
|
+
}
|
|
194098
|
+
) : null,
|
|
193352
194099
|
(() => {
|
|
193353
194100
|
const kindFull = `\xAB${frame2.keyword}\xBB${isLibraryPackage ? " (standard library)" : ""}${frame2.meta?.parallel === true ? " \u2225" : ""}${variabilityMark(frame2.keyword)}`;
|
|
193354
|
-
const
|
|
193355
|
-
const
|
|
193356
|
-
const
|
|
194101
|
+
const avail = Math.max(24, containerTitleArea(w, controllable).width - 14);
|
|
194102
|
+
const kindShown = fitKind(kindFull, avail);
|
|
194103
|
+
const mult = data.showMult && frame2.multiplicity ? frame2.multiplicity : void 0;
|
|
194104
|
+
const title = titleNameLine(frame2.label, frame2.type, mult, void 0, avail);
|
|
193357
194105
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
193358
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("text", { className: "dnode-kind", x: 10, y:
|
|
194106
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("text", { className: "dnode-kind", x: 10, y: CONTAINER_TITLE_KIND_BASELINE, children: [
|
|
193359
194107
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FullTitle, { full: kindFull, shown: kindShown }),
|
|
193360
194108
|
kindShown
|
|
193361
194109
|
] }),
|
|
193362
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("text", { className: "dnode-label", x:
|
|
193363
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FullTitle, { full:
|
|
193364
|
-
|
|
194110
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("text", { className: "dnode-label", x: 10, y: CONTAINER_TITLE_NAME_BASELINE, style: { fontSize: 11 }, children: [
|
|
194111
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FullTitle, { full: title.full, shown: title.shown }),
|
|
194112
|
+
title.nameShown,
|
|
194113
|
+
title.typeShown ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
194114
|
+
" : ",
|
|
194115
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("tspan", { className: "dnode-type", children: title.typeShown })
|
|
194116
|
+
] }) : "",
|
|
194117
|
+
mult ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("tspan", { className: "dnode-kind", children: [
|
|
194118
|
+
" ",
|
|
194119
|
+
mult
|
|
194120
|
+
] }) : ""
|
|
193365
194121
|
] })
|
|
193366
194122
|
] });
|
|
193367
194123
|
})(),
|
|
194124
|
+
featureBandHeight > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Compartments, { node: frame2, w, top: FRAME_TITLE_HEIGHT }) : null,
|
|
194125
|
+
collapsible ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ContainerBandRule, { w, y: bandBottom }) : null,
|
|
193368
194126
|
ports.map((ph) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
193369
194127
|
PortGlyph,
|
|
193370
194128
|
{
|
|
193371
194129
|
ph,
|
|
193372
194130
|
w,
|
|
193373
194131
|
h,
|
|
194132
|
+
topReserve: featureCompartmentHeight,
|
|
193374
194133
|
showLabels: true,
|
|
193375
194134
|
selected: selectedPortId === ph.port.id,
|
|
193376
194135
|
hovered: hoveredPortId === ph.port.id,
|
|
@@ -193383,11 +194142,18 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
193383
194142
|
ph.port.id
|
|
193384
194143
|
))
|
|
193385
194144
|
] }),
|
|
193386
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
194145
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
194146
|
+
"div",
|
|
194147
|
+
{
|
|
194148
|
+
className: "rf-frame-header",
|
|
194149
|
+
style: { left: 0, top: 0, width: "100%", height: FRAME_TITLE_HEIGHT },
|
|
194150
|
+
title: frame2.label
|
|
194151
|
+
}
|
|
194152
|
+
),
|
|
193387
194153
|
SIDES.flatMap((side, si) => {
|
|
193388
194154
|
const offsets = sideOffsets[si];
|
|
193389
194155
|
return offsets.map((offset2, i) => {
|
|
193390
|
-
const { x, y } =
|
|
194156
|
+
const { x, y } = sidePoint(side, offset2, w, h, featureCompartmentHeight);
|
|
193391
194157
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
193392
194158
|
DualHandle,
|
|
193393
194159
|
{
|
|
@@ -193404,7 +194170,7 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
193404
194170
|
});
|
|
193405
194171
|
}),
|
|
193406
194172
|
showPorts ? ports.flatMap((ph) => {
|
|
193407
|
-
const rect = portGlyphRect(ph, w, h);
|
|
194173
|
+
const rect = portGlyphRect(ph, w, h, featureCompartmentHeight);
|
|
193408
194174
|
const c = { x: rect.cx, y: rect.cy };
|
|
193409
194175
|
const startable = directRelationForHandle(data.kind, {
|
|
193410
194176
|
id: ph.port.id,
|
|
@@ -193425,7 +194191,7 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
193425
194191
|
];
|
|
193426
194192
|
}) : null,
|
|
193427
194193
|
ctx.onPortMove ? ports.map((ph) => {
|
|
193428
|
-
const rect = portGlyphRect(ph, w, h);
|
|
194194
|
+
const rect = portGlyphRect(ph, w, h, featureCompartmentHeight);
|
|
193429
194195
|
const nestedChild = ph.port.parentPort !== void 0;
|
|
193430
194196
|
const strip = portInteractionStrip(rect, ph.side);
|
|
193431
194197
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
@@ -193447,20 +194213,27 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
193447
194213
|
`pd-${ph.port.id}`
|
|
193448
194214
|
);
|
|
193449
194215
|
}) : null,
|
|
193450
|
-
ctx.onToggleNestedPort ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
194216
|
+
ctx.onToggleNestedPort ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
194217
|
+
NestedPortToggles,
|
|
194218
|
+
{
|
|
194219
|
+
ports,
|
|
194220
|
+
w,
|
|
194221
|
+
h,
|
|
194222
|
+
topReserve: featureCompartmentHeight,
|
|
194223
|
+
onToggle: ctx.onToggleNestedPort
|
|
194224
|
+
}
|
|
194225
|
+
) : null,
|
|
193451
194226
|
collapsible ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
193452
|
-
|
|
194227
|
+
ContainerControls,
|
|
193453
194228
|
{
|
|
193454
|
-
|
|
193455
|
-
|
|
193456
|
-
|
|
193457
|
-
|
|
193458
|
-
|
|
193459
|
-
|
|
193460
|
-
|
|
193461
|
-
|
|
193462
|
-
},
|
|
193463
|
-
children: "\u2212"
|
|
194229
|
+
id: id2,
|
|
194230
|
+
label: frame2.label,
|
|
194231
|
+
internalNoun,
|
|
194232
|
+
internalsVisible: true,
|
|
194233
|
+
featureCompartmentsVisible,
|
|
194234
|
+
cornerRadius: frame2.isDef === true ? 0 : FRAME_USAGE_CORNER_RADIUS,
|
|
194235
|
+
onToggleInternals: ctx.onToggleInternals,
|
|
194236
|
+
onToggleFeatureCompartments: ctx.onToggleFeatureCompartments
|
|
193464
194237
|
}
|
|
193465
194238
|
) : null,
|
|
193466
194239
|
editing && ctx.onEditCommit && ctx.onEditCancel ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
@@ -193648,9 +194421,9 @@ function resolveViewConfig(settings, view, overrides = {}) {
|
|
|
193648
194421
|
gvFilters: new Set(view?.gvFilters ?? []),
|
|
193649
194422
|
// Case View definitions are shown unless the user turned them off.
|
|
193650
194423
|
cvShowDefs: view?.cvShowDefs !== false,
|
|
193651
|
-
|
|
194424
|
+
hiddenInternals: view?.hiddenInternals ?? {},
|
|
194425
|
+
visibleFeatureCompartments: view?.visibleFeatureCompartments ?? {},
|
|
193652
194426
|
nestedPorts: view?.nestedPorts ?? {},
|
|
193653
|
-
collapsedActions: view?.collapsedActions ?? {},
|
|
193654
194427
|
showPortLabels: settings.showPortLabels,
|
|
193655
194428
|
showMultiplicities: settings.showMultiplicities,
|
|
193656
194429
|
showSubjectAsBoundaryBox: settings.showSubjectAsBoundaryBox,
|
|
@@ -193725,9 +194498,9 @@ async function renderDiagramSvg(document2, provider, options) {
|
|
|
193725
194498
|
showMult: config.showMultiplicities,
|
|
193726
194499
|
connectPointSpacing: config.connectPointSpacing,
|
|
193727
194500
|
subjectBoundary: config.showSubjectAsBoundaryBox,
|
|
193728
|
-
|
|
194501
|
+
hiddenInternals: config.hiddenInternals,
|
|
194502
|
+
visibleFeatureCompartments: config.visibleFeatureCompartments,
|
|
193729
194503
|
nestedPorts: config.nestedPorts,
|
|
193730
|
-
collapsedActions: config.collapsedActions,
|
|
193731
194504
|
overrides: config.overrides,
|
|
193732
194505
|
portOverrides: config.portOverrides,
|
|
193733
194506
|
edgeRoutes: config.edgeRoutes,
|
|
@@ -193797,7 +194570,7 @@ async function runExport(command) {
|
|
|
193797
194570
|
}
|
|
193798
194571
|
|
|
193799
194572
|
// src/main.ts
|
|
193800
|
-
var VERSION2 = true ? "0.
|
|
194573
|
+
var VERSION2 = true ? "0.15.1" : "dev";
|
|
193801
194574
|
function display(file) {
|
|
193802
194575
|
const rel2 = path9.relative(process.cwd(), file);
|
|
193803
194576
|
return rel2 && !rel2.startsWith("..") ? rel2.split(path9.sep).join("/") : file;
|