sysml-diagram 0.22.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/main.js +2043 -465
- package/out/main.js.map +4 -4
- package/package.json +1 -1
- package/resources/sysml.dimension-table.json +1 -1
package/out/main.js
CHANGED
|
@@ -161289,6 +161289,10 @@ function applyTransform(m, p) {
|
|
|
161289
161289
|
m.r[6] * p[0] + m.r[7] * p[1] + m.r[8] * p[2] + m.t[2]
|
|
161290
161290
|
];
|
|
161291
161291
|
}
|
|
161292
|
+
function isUnrotated(m) {
|
|
161293
|
+
const id2 = [1, 0, 0, 0, 1, 0, 0, 0, 1];
|
|
161294
|
+
return m.r.every((v, i) => Math.abs(v - id2[i]) < 1e-6);
|
|
161295
|
+
}
|
|
161292
161296
|
function yawOf(m) {
|
|
161293
161297
|
if (Math.abs(m.r[2]) > 1e-6 || Math.abs(m.r[5]) > 1e-6)
|
|
161294
161298
|
return void 0;
|
|
@@ -162227,6 +162231,91 @@ var FeaturePathResolver = class {
|
|
|
162227
162231
|
}
|
|
162228
162232
|
};
|
|
162229
162233
|
|
|
162234
|
+
// ../language-server/out/src/platform/platform.js
|
|
162235
|
+
var current;
|
|
162236
|
+
function setPlatform(platform) {
|
|
162237
|
+
current = platform;
|
|
162238
|
+
}
|
|
162239
|
+
function getPlatform() {
|
|
162240
|
+
if (!current)
|
|
162241
|
+
throw new Error("SysML: no platform installed - the entry point must call setPlatform() first.");
|
|
162242
|
+
return current;
|
|
162243
|
+
}
|
|
162244
|
+
function hasPlatform() {
|
|
162245
|
+
return current !== void 0;
|
|
162246
|
+
}
|
|
162247
|
+
|
|
162248
|
+
// ../language-server/out/src/services/library-index-manager.js
|
|
162249
|
+
var SysmlIndexManager = class extends DefaultIndexManager {
|
|
162250
|
+
constructor(services) {
|
|
162251
|
+
super(services);
|
|
162252
|
+
}
|
|
162253
|
+
// REQ-075, REQ-383 — `libraryRoot` is a URI and the concrete file URIs come
|
|
162254
|
+
// from the platform, because the two hosts index the same library under
|
|
162255
|
+
// different schemes (`file:` on the desktop, `sysml-lib:` in a worker).
|
|
162256
|
+
loadPrecomputedLibraryIndex(index2, libraryRoot) {
|
|
162257
|
+
const platform = getPlatform();
|
|
162258
|
+
let symbolCount = 0;
|
|
162259
|
+
for (const file of index2.files) {
|
|
162260
|
+
const documentUri = platform.libraryUri(libraryRoot, file.path);
|
|
162261
|
+
const descriptions = file.symbols.map((symbol) => this.deserializeSymbol(symbol, documentUri));
|
|
162262
|
+
const uri = documentUri.toString();
|
|
162263
|
+
this.symbolIndex.set(uri, descriptions);
|
|
162264
|
+
this.symbolByTypeIndex.clear(uri);
|
|
162265
|
+
symbolCount += descriptions.length;
|
|
162266
|
+
}
|
|
162267
|
+
return symbolCount;
|
|
162268
|
+
}
|
|
162269
|
+
deserializeSymbol(symbol, documentUri) {
|
|
162270
|
+
return {
|
|
162271
|
+
name: symbol.name,
|
|
162272
|
+
type: symbol.type,
|
|
162273
|
+
path: symbol.path,
|
|
162274
|
+
documentUri,
|
|
162275
|
+
nameSegment: symbol.nameSegment,
|
|
162276
|
+
selectionSegment: symbol.selectionSegment,
|
|
162277
|
+
// REQ-068 — preserve declared visibility for wildcard re-export.
|
|
162278
|
+
...symbol.isPrivate ? { isPrivate: true } : {},
|
|
162279
|
+
...symbol.visibility ? { visibility: symbol.visibility } : {},
|
|
162280
|
+
// issue #152 — a re-exported alias is not owned nesting.
|
|
162281
|
+
...symbol.derivedKind ? { derivedKind: symbol.derivedKind } : {},
|
|
162282
|
+
// REQ-242 — issue #103 — keeps type completion to definitions.
|
|
162283
|
+
...symbol.isUsage ? { isUsage: true } : {}
|
|
162284
|
+
};
|
|
162285
|
+
}
|
|
162286
|
+
};
|
|
162287
|
+
function isSysmlIndexManager(value) {
|
|
162288
|
+
return typeof value.loadPrecomputedLibraryIndex === "function";
|
|
162289
|
+
}
|
|
162290
|
+
var libraryRoots = /* @__PURE__ */ new Set();
|
|
162291
|
+
var ROOT_SEPARATOR = "\0";
|
|
162292
|
+
function normalizeLibraryPath(p) {
|
|
162293
|
+
return p.replace(/\\/gu, "/").replace(/\/+$/u, "").toLowerCase();
|
|
162294
|
+
}
|
|
162295
|
+
function registerLibraryRoot(root4) {
|
|
162296
|
+
const uri = typeof root4 === "string" ? root4.length > 0 ? URI2.file(root4) : void 0 : root4;
|
|
162297
|
+
if (!uri)
|
|
162298
|
+
return;
|
|
162299
|
+
libraryRoots.add(`${uri.scheme}${ROOT_SEPARATOR}${normalizeLibraryPath(uri.path)}`);
|
|
162300
|
+
}
|
|
162301
|
+
function isInsideDir(fsPath, dir) {
|
|
162302
|
+
return fsPath === dir || fsPath.startsWith(`${dir}/`);
|
|
162303
|
+
}
|
|
162304
|
+
function isStandardLibraryUri(uri) {
|
|
162305
|
+
const fsPath = normalizeLibraryPath(uri.path);
|
|
162306
|
+
for (const entry of libraryRoots) {
|
|
162307
|
+
const separator = entry.indexOf(ROOT_SEPARATOR);
|
|
162308
|
+
if (entry.slice(0, separator) !== uri.scheme)
|
|
162309
|
+
continue;
|
|
162310
|
+
if (isInsideDir(fsPath, entry.slice(separator + 1)))
|
|
162311
|
+
return true;
|
|
162312
|
+
}
|
|
162313
|
+
return fsPath.split("/").some((segment) => segment === "sysml.library");
|
|
162314
|
+
}
|
|
162315
|
+
function isLibraryDocument(doc) {
|
|
162316
|
+
return doc.isLibraryDocument === true || isStandardLibraryUri(doc.uri);
|
|
162317
|
+
}
|
|
162318
|
+
|
|
162230
162319
|
// ../language-server/out/src/services/namespace-kind.js
|
|
162231
162320
|
var KERML_CLASSIFIER_DECL_TYPES = /* @__PURE__ */ new Set([
|
|
162232
162321
|
"AssociationDecl",
|
|
@@ -162372,6 +162461,112 @@ function multiplicityText(m) {
|
|
|
162372
162461
|
return void 0;
|
|
162373
162462
|
return hi == null || hi === lo ? `[${lo}]` : `[${lo}..${hi}]`;
|
|
162374
162463
|
}
|
|
162464
|
+
function connectionEndMultiplicity(node) {
|
|
162465
|
+
if (!node)
|
|
162466
|
+
return void 0;
|
|
162467
|
+
const n2 = node;
|
|
162468
|
+
const multiplicity = n2.innerMultiplicity ?? n2.multiplicity ?? n2.endMultiplicity;
|
|
162469
|
+
if (!multiplicity)
|
|
162470
|
+
return void 0;
|
|
162471
|
+
const lo = boundText(multiplicity.lower);
|
|
162472
|
+
const hi = boundText(multiplicity.upper);
|
|
162473
|
+
if (lo == null && hi == null)
|
|
162474
|
+
return void 0;
|
|
162475
|
+
return hi == null || hi === lo ? `[${lo}]` : `[${lo}..${hi}]`;
|
|
162476
|
+
}
|
|
162477
|
+
function isEmptyPrefixFlow(node) {
|
|
162478
|
+
const fm = node;
|
|
162479
|
+
return node.$type === "FlowStmt" && fm.target !== void 0 && fm.source === void 0;
|
|
162480
|
+
}
|
|
162481
|
+
function flowStmtName(node) {
|
|
162482
|
+
return isEmptyPrefixFlow(node) ? void 0 : effectiveNameOf(node);
|
|
162483
|
+
}
|
|
162484
|
+
function flowKeyword(fm) {
|
|
162485
|
+
return `${fm.succession === true ? "succession " : ""}${fm.flowKind === "message" ? "message" : "flow"}`;
|
|
162486
|
+
}
|
|
162487
|
+
function flowTransferredFeature(ends) {
|
|
162488
|
+
const sourceFeature = ends.source ? lastSeg(ends.source) : void 0;
|
|
162489
|
+
const targetFeature = ends.target ? lastSeg(ends.target) : void 0;
|
|
162490
|
+
return sourceFeature === targetFeature ? sourceFeature : sourceFeature ?? targetFeature;
|
|
162491
|
+
}
|
|
162492
|
+
function flowDecorationMeta(carried) {
|
|
162493
|
+
const drawn = carried.filter((flow) => !flow.message);
|
|
162494
|
+
if (!drawn.length)
|
|
162495
|
+
return {};
|
|
162496
|
+
return {
|
|
162497
|
+
flowDecorations: drawn.map(({ keyword, label, name, reversed, row }) => ({
|
|
162498
|
+
keyword,
|
|
162499
|
+
...label ? { label } : {},
|
|
162500
|
+
...name ? { name } : {},
|
|
162501
|
+
reversed,
|
|
162502
|
+
...row.source ? { source: row.source } : {}
|
|
162503
|
+
}))
|
|
162504
|
+
};
|
|
162505
|
+
}
|
|
162506
|
+
var END_PROPERTY_ADORNMENTS = /* @__PURE__ */ new Set(["abstract", "derived", "readonly", "ordered", "nonunique"]);
|
|
162507
|
+
var uniqueStrings = (values2) => [...new Set([...values2].filter((value) => !!value))];
|
|
162508
|
+
function formatConnectionEndAdornment(notation) {
|
|
162509
|
+
const adornment = [
|
|
162510
|
+
notation.direction,
|
|
162511
|
+
...notation.properties ?? [],
|
|
162512
|
+
notation.subsets?.length ? `subsets ${notation.subsets.join(", ")}` : void 0,
|
|
162513
|
+
notation.redefines?.length ? `redefines ${notation.redefines.join(", ")}` : void 0
|
|
162514
|
+
].filter((value) => !!value).join(" ");
|
|
162515
|
+
return adornment || void 0;
|
|
162516
|
+
}
|
|
162517
|
+
function mergeConnectionEndNotation(local, inherited) {
|
|
162518
|
+
const notation = {
|
|
162519
|
+
role: local.role ?? inherited?.role,
|
|
162520
|
+
multiplicity: local.multiplicity ?? inherited?.multiplicity,
|
|
162521
|
+
direction: local.direction ?? inherited?.direction,
|
|
162522
|
+
properties: uniqueStrings([...local.properties ?? [], ...inherited?.properties ?? []]),
|
|
162523
|
+
subsets: uniqueStrings([...local.subsets ?? [], ...inherited?.subsets ?? []]),
|
|
162524
|
+
redefines: uniqueStrings([...local.redefines ?? [], ...inherited?.redefines ?? []]),
|
|
162525
|
+
type: local.type ?? inherited?.type
|
|
162526
|
+
};
|
|
162527
|
+
notation.adornment = formatConnectionEndAdornment(notation);
|
|
162528
|
+
return notation;
|
|
162529
|
+
}
|
|
162530
|
+
function connectionEndNotationClaims(notation) {
|
|
162531
|
+
return uniqueStrings([
|
|
162532
|
+
notation.role,
|
|
162533
|
+
...(notation.redefines ?? []).map(lastSeg)
|
|
162534
|
+
]);
|
|
162535
|
+
}
|
|
162536
|
+
function connectionEndSpecializesRole(notation, role) {
|
|
162537
|
+
const wanted = lastSeg(role);
|
|
162538
|
+
return [...notation.subsets ?? [], ...notation.redefines ?? []].some((target) => lastSeg(target) === wanted);
|
|
162539
|
+
}
|
|
162540
|
+
function declaredConnectionEndNotation(node) {
|
|
162541
|
+
const n2 = node;
|
|
162542
|
+
const modifiers2 = [
|
|
162543
|
+
...n2.modifiers ?? [],
|
|
162544
|
+
...n2.postModifiers ?? [],
|
|
162545
|
+
...n2.trailingQuals ?? [],
|
|
162546
|
+
...n2.innerTrailingQuals ?? []
|
|
162547
|
+
];
|
|
162548
|
+
const direction = modifiers2.find((value) => value === "in" || value === "out" || value === "inout");
|
|
162549
|
+
const properties = uniqueStrings(modifiers2.filter((value) => END_PROPERTY_ADORNMENTS.has(value)));
|
|
162550
|
+
const subsets = [];
|
|
162551
|
+
const redefines = [];
|
|
162552
|
+
for (const relationship of [...n2.relationships ?? [], ...n2.innerRelationships ?? []]) {
|
|
162553
|
+
const targets = relationship.targets ?? [];
|
|
162554
|
+
if (relationship.kind === ":>" || relationship.kind === "subsets") {
|
|
162555
|
+
subsets.push(...targets);
|
|
162556
|
+
} else if (relationship.kind === ":>>" || relationship.kind === "redefines") {
|
|
162557
|
+
redefines.push(...targets);
|
|
162558
|
+
}
|
|
162559
|
+
}
|
|
162560
|
+
return mergeConnectionEndNotation({
|
|
162561
|
+
role: n2.innerName ?? nameOf2(node) ?? redefines.map(lastSeg).find(Boolean),
|
|
162562
|
+
multiplicity: connectionEndMultiplicity(node),
|
|
162563
|
+
direction,
|
|
162564
|
+
properties,
|
|
162565
|
+
subsets: uniqueStrings(subsets),
|
|
162566
|
+
redefines: uniqueStrings(redefines),
|
|
162567
|
+
type: n2.innerTyping?.type?.$refText ?? n2.typing?.type?.$refText
|
|
162568
|
+
}, void 0);
|
|
162569
|
+
}
|
|
162375
162570
|
function multText(node) {
|
|
162376
162571
|
if (!node)
|
|
162377
162572
|
return void 0;
|
|
@@ -162782,17 +162977,40 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
162782
162977
|
else
|
|
162783
162978
|
drawn.set(k, [target]);
|
|
162784
162979
|
};
|
|
162785
|
-
|
|
162786
|
-
claim(n2.source, { id: n2.id, parent: n2.parent, frame: n2.frame });
|
|
162980
|
+
const claimNode = (n2, definitionLayer2 = false) => {
|
|
162981
|
+
claim(n2.source, { id: n2.id, parent: n2.parent, frame: n2.frame, definitionLayer: definitionLayer2 });
|
|
162787
162982
|
for (const port of n2.ports ?? []) {
|
|
162788
|
-
|
|
162983
|
+
if (port.meta?.connectionEndPin === true)
|
|
162984
|
+
continue;
|
|
162985
|
+
claim(port.source, {
|
|
162986
|
+
id: port.id,
|
|
162987
|
+
parent: n2.parent,
|
|
162988
|
+
frame: n2.frame,
|
|
162989
|
+
port: true,
|
|
162990
|
+
definitionLayer: definitionLayer2
|
|
162991
|
+
});
|
|
162789
162992
|
}
|
|
162790
|
-
}
|
|
162791
|
-
|
|
162792
|
-
claim(f.source, { id: f.id, frame: f.id });
|
|
162993
|
+
};
|
|
162994
|
+
const claimFrame = (f, definitionLayer2 = false) => {
|
|
162995
|
+
claim(f.source, { id: f.id, frame: f.id, definitionLayer: definitionLayer2 });
|
|
162793
162996
|
for (const port of f.ports ?? []) {
|
|
162794
|
-
|
|
162997
|
+
if (port.meta?.connectionEndPin === true)
|
|
162998
|
+
continue;
|
|
162999
|
+
claim(port.source, { id: port.id, frame: f.id, port: true, definitionLayer: definitionLayer2 });
|
|
162795
163000
|
}
|
|
163001
|
+
};
|
|
163002
|
+
for (const n2 of model.nodes) {
|
|
163003
|
+
claimNode(n2);
|
|
163004
|
+
}
|
|
163005
|
+
for (const f of model.frames ?? []) {
|
|
163006
|
+
claimFrame(f);
|
|
163007
|
+
}
|
|
163008
|
+
const definitionLayer = model.layers?.definitions;
|
|
163009
|
+
for (const n2 of definitionLayer?.nodes ?? []) {
|
|
163010
|
+
claimNode(n2, true);
|
|
163011
|
+
}
|
|
163012
|
+
for (const f of definitionLayer?.frames ?? []) {
|
|
163013
|
+
claimFrame(f, true);
|
|
162796
163014
|
}
|
|
162797
163015
|
if (model.ivBoundary) {
|
|
162798
163016
|
claim(model.ivBoundary.source, { id: model.ivBoundary.id, frame: model.ivBoundary.id });
|
|
@@ -162804,15 +163022,22 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
162804
163022
|
return model;
|
|
162805
163023
|
const nodes = [...model.nodes];
|
|
162806
163024
|
const edges = [...model.edges];
|
|
163025
|
+
const definitionNodes = [...definitionLayer?.nodes ?? []];
|
|
163026
|
+
const definitionEdges = [...definitionLayer?.edges ?? []];
|
|
162807
163027
|
let noteCount = 0;
|
|
162808
|
-
let edgeCount = edges.
|
|
163028
|
+
let edgeCount = [...edges, ...definitionEdges].reduce((next, edge) => {
|
|
163029
|
+
const match = /^e(\d+)$/u.exec(edge.id);
|
|
163030
|
+
return match ? Math.max(next, Number(match[1]) + 1) : next;
|
|
163031
|
+
}, 0);
|
|
162809
163032
|
const note = (annotation) => {
|
|
162810
163033
|
const targets = drawn.get(key(sourceOf2(annotation.owner, uri)) ?? "")?.filter((target) => annotation.keyword !== "doc" || docAsNote || target.port);
|
|
162811
163034
|
if (!targets?.length)
|
|
162812
163035
|
return;
|
|
162813
163036
|
for (const target of targets) {
|
|
162814
163037
|
const id2 = `__note_${noteCount++}__`;
|
|
162815
|
-
nodes
|
|
163038
|
+
const targetNodes = target.definitionLayer ? definitionNodes : nodes;
|
|
163039
|
+
const targetEdges = target.definitionLayer ? definitionEdges : edges;
|
|
163040
|
+
targetNodes.push({
|
|
162816
163041
|
id: id2,
|
|
162817
163042
|
name: annotation.label,
|
|
162818
163043
|
keyword: annotation.keyword,
|
|
@@ -162825,7 +163050,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
162825
163050
|
...target.frame ? { frame: target.frame } : {},
|
|
162826
163051
|
source: sourceOf2(annotation.annotation, uri)
|
|
162827
163052
|
});
|
|
162828
|
-
|
|
163053
|
+
targetEdges.push({
|
|
162829
163054
|
id: `e${edgeCount++}`,
|
|
162830
163055
|
from: id2,
|
|
162831
163056
|
to: target.id,
|
|
@@ -162843,7 +163068,23 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
162843
163068
|
note(annotation);
|
|
162844
163069
|
}
|
|
162845
163070
|
}
|
|
162846
|
-
|
|
163071
|
+
if (!noteCount)
|
|
163072
|
+
return model;
|
|
163073
|
+
return {
|
|
163074
|
+
...model,
|
|
163075
|
+
nodes,
|
|
163076
|
+
edges,
|
|
163077
|
+
...definitionLayer ? {
|
|
163078
|
+
layers: {
|
|
163079
|
+
...model.layers,
|
|
163080
|
+
definitions: {
|
|
163081
|
+
...definitionLayer,
|
|
163082
|
+
nodes: definitionNodes,
|
|
163083
|
+
edges: definitionEdges
|
|
163084
|
+
}
|
|
163085
|
+
}
|
|
163086
|
+
} : {}
|
|
163087
|
+
};
|
|
162847
163088
|
}
|
|
162848
163089
|
// REQ-224 — Detect the file/anchor-specific view kinds that will render
|
|
162849
163090
|
// substantive diagram content. The extension uses this to limit the
|
|
@@ -163670,8 +163911,27 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
163670
163911
|
hasGeometryObject(node, index2) {
|
|
163671
163912
|
return this.collectGeometry(node, index2).length > 0;
|
|
163672
163913
|
}
|
|
163914
|
+
// REQ-360 — Package overview
|
|
163915
|
+
/** Package overviews contain layouts, not inventories of unplaced shape types. */
|
|
163916
|
+
hasPlacedGeometryObject(node, index2) {
|
|
163917
|
+
return this.collectGeometry(node, index2).some((candidate) => candidate.geo !== void 0);
|
|
163918
|
+
}
|
|
163919
|
+
// REQ-360 — Package overview
|
|
163920
|
+
/** Collapse a wrapper whose only direct object owns the actual layout. */
|
|
163921
|
+
hasGeometryOverviewLayout(node, index2) {
|
|
163922
|
+
const placed = this.collectGeometry(node, index2).filter((candidate) => candidate.geo !== void 0);
|
|
163923
|
+
if (placed.length === 0)
|
|
163924
|
+
return false;
|
|
163925
|
+
const direct = placed.filter((candidate) => !candidate.name.includes("."));
|
|
163926
|
+
if (direct.length !== 1)
|
|
163927
|
+
return true;
|
|
163928
|
+
const prefix = `${direct[0].name}.`;
|
|
163929
|
+
return !placed.some((candidate) => candidate.name.startsWith(prefix));
|
|
163930
|
+
}
|
|
163673
163931
|
hasRenderablePorts(node, index2) {
|
|
163674
|
-
|
|
163932
|
+
if (membersOf(node).some((member) => isPortDecl(member) && member.isDef !== true))
|
|
163933
|
+
return true;
|
|
163934
|
+
return this.inheritedFeatureOwnersOf(node, index2).some((source) => membersOf(source).some((member) => isPortDecl(member) && member.isDef !== true && !this.isInheritedLibraryBackboneFeature(source, member, index2)));
|
|
163675
163935
|
}
|
|
163676
163936
|
// REQ-192, issue #233 — the named part usages a part shows when expanded: its
|
|
163677
163937
|
// own and the ones it inherits, through its typing definition or a `:>`
|
|
@@ -163679,11 +163939,51 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
163679
163939
|
// The predicate form of `childUsagesOf`, so an anchor that only INHERITS
|
|
163680
163940
|
// internals is recognised as having them.
|
|
163681
163941
|
hasNestedPartUsages(node, index2) {
|
|
163682
|
-
return
|
|
163942
|
+
return this.structuralChildUsagesOf(node, index2).some((usage) => nameOf2(usage) !== void 0);
|
|
163683
163943
|
}
|
|
163684
163944
|
nestedUsages(node, guard) {
|
|
163685
163945
|
return membersOf(node).filter((m) => guard(m) && m.isDef !== true);
|
|
163686
163946
|
}
|
|
163947
|
+
// REQ-192 - standard-library definitions contribute real inherited structure,
|
|
163948
|
+
// but their recursive backbone features are collecting roles, not additional
|
|
163949
|
+
// concrete children of every typed usage. For example, SpatialItem declares
|
|
163950
|
+
// `subSpatialParts : SpatialItem`, and Part declares `start : Part`. Expanding
|
|
163951
|
+
// either role as another occurrence recursively materializes the library model
|
|
163952
|
+
// instead of the user's composition. A local redefinition remains visible.
|
|
163953
|
+
isInheritedLibraryBackboneFeature(source, usage, index2) {
|
|
163954
|
+
if (!isLibraryDocument(ast_utils_exports.getDocument(usage)))
|
|
163955
|
+
return false;
|
|
163956
|
+
if (modifiersOf(usage).includes("abstract"))
|
|
163957
|
+
return true;
|
|
163958
|
+
const ownerType = source.isDef === true ? source : this.resolveType(source, index2);
|
|
163959
|
+
const usageType = this.resolveType(usage, index2);
|
|
163960
|
+
if (!ownerType || !usageType)
|
|
163961
|
+
return false;
|
|
163962
|
+
if (ownerType === usageType)
|
|
163963
|
+
return true;
|
|
163964
|
+
return this.inheritedFeatureOwnersOf(ownerType, index2).includes(usageType) || this.inheritedFeatureOwnersOf(usageType, index2).includes(ownerType);
|
|
163965
|
+
}
|
|
163966
|
+
/** The concrete structural children projected by IV, with the same nearest-name
|
|
163967
|
+
* fold used for other effective inventories. Authored subsets of an inherited
|
|
163968
|
+
* library collection stay visible; only the inherited recursive role is hidden. */
|
|
163969
|
+
structuralChildUsagesOf(part, index2) {
|
|
163970
|
+
const out = this.nestedUsages(part, isPartDecl);
|
|
163971
|
+
const have = new Set(out.map(effectiveNameOf).filter((name) => !!name));
|
|
163972
|
+
for (const source of this.inheritedFeatureOwnersOf(part, index2)) {
|
|
163973
|
+
for (const usage of this.nestedUsages(source, isPartDecl)) {
|
|
163974
|
+
if (this.isInheritedLibraryBackboneFeature(source, usage, index2))
|
|
163975
|
+
continue;
|
|
163976
|
+
const name = effectiveNameOf(usage);
|
|
163977
|
+
if (name !== void 0) {
|
|
163978
|
+
if (have.has(name))
|
|
163979
|
+
continue;
|
|
163980
|
+
have.add(name);
|
|
163981
|
+
}
|
|
163982
|
+
out.push(usage);
|
|
163983
|
+
}
|
|
163984
|
+
}
|
|
163985
|
+
return out;
|
|
163986
|
+
}
|
|
163687
163987
|
// issue #109 — usages of kinds with NO dedicated usage view (constraint /
|
|
163688
163988
|
// calc / occurrence / item / attribute). Nested in an element they surface as
|
|
163689
163989
|
// owner compartments (compartmentsFor); declared as direct package members
|
|
@@ -163718,8 +164018,13 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
163718
164018
|
const all = [...ast_utils_exports.streamAllContents(scope)];
|
|
163719
164019
|
const defNodes = all.filter((n2) => isDefinitionNode(n2) && nameOf2(n2));
|
|
163720
164020
|
const packageOverview = isPackage(ctx.anchor) || isDocument(ctx.anchor);
|
|
163721
|
-
const
|
|
163722
|
-
const
|
|
164021
|
+
const isDirectPackageInterfaceUsage = (n2) => isInterfaceDecl(n2) && n2.isDef !== true && this.isDirectPackageMember(n2);
|
|
164022
|
+
const isPackageInterfaceUsage = (n2) => {
|
|
164023
|
+
const usage = n2;
|
|
164024
|
+
const emptyPrefix = usage.target !== void 0 && usage.connect === void 0;
|
|
164025
|
+
return isDirectPackageInterfaceUsage(n2) && !emptyPrefix && !!nameOf2(n2);
|
|
164026
|
+
};
|
|
164027
|
+
const hasOwnedMemberNode = all.some((n2) => isPackage(n2) && !!nameOf2(n2) || isDefinitionNode(n2) && !!nameOf2(n2) || this.isViewlessUsage(n2) && this.isDirectPackageMember(n2) || isDirectPackageInterfaceUsage(n2) || isPartDecl(n2) && n2.isDef !== true && !!nameOf2(n2) && this.isDirectPackageMember(n2));
|
|
163723
164028
|
const packageNodes = [
|
|
163724
164029
|
...packageOverview && hasOwnedMemberNode && isPackage(scope) && nameOf2(scope) ? [scope] : [],
|
|
163725
164030
|
...all.filter((p) => isPackage(p) && nameOf2(p))
|
|
@@ -163880,6 +164185,77 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
163880
164185
|
}
|
|
163881
164186
|
}
|
|
163882
164187
|
}
|
|
164188
|
+
for (const definition of defNodes.filter(isConnectionDecl)) {
|
|
164189
|
+
const definitionId = ids.get(definition);
|
|
164190
|
+
if (!definitionId)
|
|
164191
|
+
continue;
|
|
164192
|
+
const effectiveEnds = this.connectionEndNotationsOf(definition, index2);
|
|
164193
|
+
const resolvedEnds = effectiveEnds.map((notation) => {
|
|
164194
|
+
const target = notation.type ? resolveDrawnByText(notation.type) : void 0;
|
|
164195
|
+
return target && ids.has(target) ? { id: ids.get(target), notation } : void 0;
|
|
164196
|
+
});
|
|
164197
|
+
if (resolvedEnds.length < 2 || resolvedEnds.some((end) => !end))
|
|
164198
|
+
continue;
|
|
164199
|
+
const completeEnds = resolvedEnds.filter((end) => !!end);
|
|
164200
|
+
const definitionNode = nodes.find((node) => node.id === definitionId);
|
|
164201
|
+
const hasElaboration = !!definitionNode?.compartments?.length || specializationFamily(definition).length > 0;
|
|
164202
|
+
if (definitionNode) {
|
|
164203
|
+
definitionNode.meta = {
|
|
164204
|
+
...definitionNode.meta,
|
|
164205
|
+
connectionDefinitionGraphical: true,
|
|
164206
|
+
...hasElaboration ? { connectionDefinitionElaboration: true } : {}
|
|
164207
|
+
};
|
|
164208
|
+
}
|
|
164209
|
+
const common = {
|
|
164210
|
+
kind: "connect",
|
|
164211
|
+
name: nameOf2(definition),
|
|
164212
|
+
isDef: true,
|
|
164213
|
+
label: `\xABconnection def\xBB ${nameOf2(definition) ?? ""}`.trim(),
|
|
164214
|
+
source: sourceOf2(definition, uri),
|
|
164215
|
+
meta: { connectionDefinitionGraphical: true },
|
|
164216
|
+
...hasElaboration ? { elaboration: definitionId } : {}
|
|
164217
|
+
};
|
|
164218
|
+
if (completeEnds.length === 2) {
|
|
164219
|
+
edges.push({
|
|
164220
|
+
id: `e${e++}`,
|
|
164221
|
+
from: completeEnds[0].id,
|
|
164222
|
+
to: completeEnds[1].id,
|
|
164223
|
+
...common,
|
|
164224
|
+
endRoleFrom: completeEnds[0].notation.role,
|
|
164225
|
+
endLabelFrom: completeEnds[0].notation.multiplicity,
|
|
164226
|
+
endAdornmentFrom: completeEnds[0].notation.adornment,
|
|
164227
|
+
endRoleTo: completeEnds[1].notation.role,
|
|
164228
|
+
endLabelTo: completeEnds[1].notation.multiplicity,
|
|
164229
|
+
endAdornmentTo: completeEnds[1].notation.adornment
|
|
164230
|
+
});
|
|
164231
|
+
} else {
|
|
164232
|
+
const hubId = `${definitionId}::__connection__`;
|
|
164233
|
+
nodes.push({
|
|
164234
|
+
id: hubId,
|
|
164235
|
+
name: nameOf2(definition) ?? "",
|
|
164236
|
+
keyword: "connection def",
|
|
164237
|
+
isDef: true,
|
|
164238
|
+
shape: "dot",
|
|
164239
|
+
...packageOf2(definition),
|
|
164240
|
+
source: sourceOf2(definition, uri),
|
|
164241
|
+
meta: {
|
|
164242
|
+
connectionDefinitionGraphical: true,
|
|
164243
|
+
connectionDefinitionHub: true,
|
|
164244
|
+
naryConnectionHub: true
|
|
164245
|
+
}
|
|
164246
|
+
});
|
|
164247
|
+
completeEnds.forEach((end, indexOfEnd) => edges.push({
|
|
164248
|
+
id: `e${e++}`,
|
|
164249
|
+
from: hubId,
|
|
164250
|
+
to: end.id,
|
|
164251
|
+
...common,
|
|
164252
|
+
...indexOfEnd === 0 ? {} : { label: void 0, elaboration: void 0 },
|
|
164253
|
+
endRoleTo: end.notation.role,
|
|
164254
|
+
endLabelTo: end.notation.multiplicity,
|
|
164255
|
+
endAdornmentTo: end.notation.adornment
|
|
164256
|
+
}));
|
|
164257
|
+
}
|
|
164258
|
+
}
|
|
163883
164259
|
for (const rs of all.filter((m) => m.$type === "StandaloneRelationshipDecl")) {
|
|
163884
164260
|
const rn = rs;
|
|
163885
164261
|
const from = resolveDrawnByText(String(rn.source ?? ""));
|
|
@@ -164296,6 +164672,270 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164296
164672
|
const o = v;
|
|
164297
164673
|
return this.featurePath(o.reference) ?? this.featurePath(o.path) ?? o.$cstNode?.text?.replace(/\[[^\]]*\]/g, "").trim();
|
|
164298
164674
|
}
|
|
164675
|
+
connectorEndRole(v) {
|
|
164676
|
+
if (!v || typeof v !== "object")
|
|
164677
|
+
return void 0;
|
|
164678
|
+
const end = v;
|
|
164679
|
+
if (!end.reference)
|
|
164680
|
+
return void 0;
|
|
164681
|
+
const role = this.featurePath(end.path);
|
|
164682
|
+
return role ? lastSeg(role) : void 0;
|
|
164683
|
+
}
|
|
164684
|
+
// REQ-192, issue #111: connection and interface definitions may specialize
|
|
164685
|
+
// definitions that own their ends. Fold those ends nearest-first, just like
|
|
164686
|
+
// the rest of the effective IV inventory. A local end shadows an inherited
|
|
164687
|
+
// end by role or explicit redefinition and inherits notation it omits.
|
|
164688
|
+
connectionEndNotationsOf(owner, index2) {
|
|
164689
|
+
if (!owner)
|
|
164690
|
+
return [];
|
|
164691
|
+
const inheritedOwners = owner.isDef === true ? [] : this.inheritedFeatureOwnersOf(owner, index2);
|
|
164692
|
+
const definition = owner.isDef === true ? owner : this.resolveType(owner, index2) ?? inheritedOwners.find((candidate) => candidate.isDef === true && candidate.$type === owner.$type);
|
|
164693
|
+
if (!definition)
|
|
164694
|
+
return [];
|
|
164695
|
+
const selected2 = [];
|
|
164696
|
+
for (const source of [definition, ...this.inheritedFeatureOwnersOf(definition, index2)]) {
|
|
164697
|
+
for (const end of membersOf(source).filter(isEndMember)) {
|
|
164698
|
+
const notation = declaredConnectionEndNotation(end);
|
|
164699
|
+
const claims = new Set(connectionEndNotationClaims(notation));
|
|
164700
|
+
const existing = selected2.find((candidate) => [...claims].some((claim) => candidate.claims.has(claim)));
|
|
164701
|
+
if (existing) {
|
|
164702
|
+
existing.notation = mergeConnectionEndNotation(existing.notation, notation);
|
|
164703
|
+
for (const claim of connectionEndNotationClaims(existing.notation))
|
|
164704
|
+
existing.claims.add(claim);
|
|
164705
|
+
continue;
|
|
164706
|
+
}
|
|
164707
|
+
const inheritedRole = notation.role;
|
|
164708
|
+
const specialized = inheritedRole ? selected2.filter((candidate) => connectionEndSpecializesRole(candidate.notation, inheritedRole)) : [];
|
|
164709
|
+
if (specialized.length > 0) {
|
|
164710
|
+
for (const candidate of specialized) {
|
|
164711
|
+
candidate.notation = mergeConnectionEndNotation(candidate.notation, notation);
|
|
164712
|
+
for (const claim of connectionEndNotationClaims(candidate.notation))
|
|
164713
|
+
candidate.claims.add(claim);
|
|
164714
|
+
}
|
|
164715
|
+
continue;
|
|
164716
|
+
}
|
|
164717
|
+
selected2.push({ notation, claims });
|
|
164718
|
+
}
|
|
164719
|
+
}
|
|
164720
|
+
return selected2.map(({ notation }) => notation);
|
|
164721
|
+
}
|
|
164722
|
+
matchingConnectionEndNotation(notations, role, ordinal) {
|
|
164723
|
+
const wanted = role ? lastSeg(role) : void 0;
|
|
164724
|
+
if (wanted) {
|
|
164725
|
+
return notations.find((notation) => connectionEndNotationClaims(notation).some((claim) => lastSeg(claim) === wanted));
|
|
164726
|
+
}
|
|
164727
|
+
return notations[ordinal];
|
|
164728
|
+
}
|
|
164729
|
+
declaredConnectionEndBinding(node) {
|
|
164730
|
+
const n2 = node;
|
|
164731
|
+
for (const relationship of [...n2.relationships ?? [], ...n2.innerRelationships ?? []]) {
|
|
164732
|
+
if (relationship.kind !== "::>" && relationship.kind !== "references")
|
|
164733
|
+
continue;
|
|
164734
|
+
for (const [occurrence, target] of (relationship.targets ?? []).entries()) {
|
|
164735
|
+
if (!target)
|
|
164736
|
+
continue;
|
|
164737
|
+
return {
|
|
164738
|
+
path: target,
|
|
164739
|
+
binding: {
|
|
164740
|
+
host: relationship,
|
|
164741
|
+
property: "targets",
|
|
164742
|
+
occurrence
|
|
164743
|
+
}
|
|
164744
|
+
};
|
|
164745
|
+
}
|
|
164746
|
+
}
|
|
164747
|
+
return {};
|
|
164748
|
+
}
|
|
164749
|
+
connectorEndBinding(end) {
|
|
164750
|
+
if (!end || typeof end !== "object" || !("$type" in end))
|
|
164751
|
+
return void 0;
|
|
164752
|
+
const connectorEnd = end;
|
|
164753
|
+
if (connectorEnd.$type !== "ConnectorEnd")
|
|
164754
|
+
return void 0;
|
|
164755
|
+
return {
|
|
164756
|
+
host: connectorEnd,
|
|
164757
|
+
property: connectorEnd.reference ? "reference" : "path",
|
|
164758
|
+
occurrence: 0
|
|
164759
|
+
};
|
|
164760
|
+
}
|
|
164761
|
+
canonicalConnectionBindingTarget(target, seen = /* @__PURE__ */ new Set()) {
|
|
164762
|
+
if (!isAliasDecl(target))
|
|
164763
|
+
return target;
|
|
164764
|
+
if (seen.has(target))
|
|
164765
|
+
return void 0;
|
|
164766
|
+
seen.add(target);
|
|
164767
|
+
const resolution = this.annotationPathResolver(target).resolvePropertyPath(target, "target");
|
|
164768
|
+
if (resolution.unresolvedIndex !== void 0 || resolution.indeterminateIndex !== void 0)
|
|
164769
|
+
return void 0;
|
|
164770
|
+
const terminal = resolution.segments.at(-1);
|
|
164771
|
+
const aliasTarget = terminal?.target ?? this.annotationDescriptionNode(target, terminal?.description);
|
|
164772
|
+
return aliasTarget ? this.canonicalConnectionBindingTarget(aliasTarget, seen) : void 0;
|
|
164773
|
+
}
|
|
164774
|
+
explicitFeatureAncestorsOf(node, index2) {
|
|
164775
|
+
const ancestors = [];
|
|
164776
|
+
const seen = /* @__PURE__ */ new Set([node]);
|
|
164777
|
+
const queue = [node];
|
|
164778
|
+
while (queue.length > 0) {
|
|
164779
|
+
const current2 = queue.shift();
|
|
164780
|
+
for (const path10 of featureInheritanceTargets(current2)) {
|
|
164781
|
+
const target = this.resolveFeatureInheritanceTarget(current2, path10, index2, /* @__PURE__ */ new Set());
|
|
164782
|
+
if (!target || seen.has(target))
|
|
164783
|
+
continue;
|
|
164784
|
+
seen.add(target);
|
|
164785
|
+
ancestors.push(target);
|
|
164786
|
+
queue.push(target);
|
|
164787
|
+
}
|
|
164788
|
+
}
|
|
164789
|
+
return ancestors;
|
|
164790
|
+
}
|
|
164791
|
+
/** REQ-192: whether the declared path resolves to the exact rendered
|
|
164792
|
+
* occurrence path. The ordinary IV endpoint resolver remains forgiving for
|
|
164793
|
+
* issue #62; inherited visibility also checks every semantic receiver so a
|
|
164794
|
+
* path such as `outside.p` cannot borrow another visible `inside.p` merely
|
|
164795
|
+
* because both ports share one definition. */
|
|
164796
|
+
connectionUsageEndBindingMatches(end, renderedPath, ownerPath, index2) {
|
|
164797
|
+
if (!end.binding || !renderedPath || !ownerPath)
|
|
164798
|
+
return false;
|
|
164799
|
+
const resolution = this.annotationPathResolver(end.binding.host).resolvePropertyPath(end.binding.host, end.binding.property, end.binding.occurrence);
|
|
164800
|
+
if (resolution.unresolvedIndex !== void 0 || resolution.indeterminateIndex !== void 0)
|
|
164801
|
+
return false;
|
|
164802
|
+
const semanticPath = [];
|
|
164803
|
+
const resolver = this.annotationPathResolver(end.binding.host);
|
|
164804
|
+
let canonicalOwner;
|
|
164805
|
+
for (const segment of resolution.segments) {
|
|
164806
|
+
const target = canonicalOwner ? resolver.visibleMembers(canonicalOwner).find((candidate) => effectiveNameOf(candidate) === segment.text) : segment.target ?? this.annotationDescriptionNode(end.binding.host, segment.description);
|
|
164807
|
+
if (!target)
|
|
164808
|
+
return false;
|
|
164809
|
+
const canonical = this.canonicalConnectionBindingTarget(target);
|
|
164810
|
+
if (!canonical)
|
|
164811
|
+
return false;
|
|
164812
|
+
if (canonicalOwner || isAliasDecl(target))
|
|
164813
|
+
canonicalOwner = canonical;
|
|
164814
|
+
if (isPackage(canonical) || isDocument(canonical) || canonical.$type === "NamespaceDecl")
|
|
164815
|
+
continue;
|
|
164816
|
+
semanticPath.push(canonical);
|
|
164817
|
+
}
|
|
164818
|
+
if (semanticPath.length === 0)
|
|
164819
|
+
return false;
|
|
164820
|
+
const sameDeclaration = (candidate, expected) => {
|
|
164821
|
+
if (candidate === expected)
|
|
164822
|
+
return true;
|
|
164823
|
+
const candidateCst = candidate.$cstNode;
|
|
164824
|
+
const expectedCst = expected.$cstNode;
|
|
164825
|
+
if (!candidateCst || !expectedCst || candidate.$type !== expected.$type || candidateCst.offset !== expectedCst.offset || candidateCst.end !== expectedCst.end) {
|
|
164826
|
+
return false;
|
|
164827
|
+
}
|
|
164828
|
+
try {
|
|
164829
|
+
return ast_utils_exports.getDocument(candidate).uri.toString() === ast_utils_exports.getDocument(expected).uri.toString();
|
|
164830
|
+
} catch {
|
|
164831
|
+
return false;
|
|
164832
|
+
}
|
|
164833
|
+
};
|
|
164834
|
+
const matches = (candidatePath, allowRootRebinding) => candidatePath.length === semanticPath.length && candidatePath.every((candidate, at) => {
|
|
164835
|
+
const expected = semanticPath[at];
|
|
164836
|
+
if (sameDeclaration(candidate, expected) || this.explicitFeatureAncestorsOf(candidate, index2).some((ancestor) => sameDeclaration(ancestor, expected))) {
|
|
164837
|
+
return true;
|
|
164838
|
+
}
|
|
164839
|
+
return allowRootRebinding && at === 0 && this.inheritedFeatureOwnersOf(candidate, index2).some((ancestor) => sameDeclaration(ancestor, expected));
|
|
164840
|
+
});
|
|
164841
|
+
const relativePath = renderedPath.slice(ownerPath.length);
|
|
164842
|
+
const ownerRootedPath = renderedPath.slice(Math.max(0, ownerPath.length - 1));
|
|
164843
|
+
const result = matches(relativePath, false) || matches(ownerRootedPath, true) || matches(renderedPath, true) || semanticPath.length === 1 && matches(renderedPath.slice(-1), false);
|
|
164844
|
+
return result;
|
|
164845
|
+
}
|
|
164846
|
+
/** REQ-192: the ends written directly on one explicit connection usage.
|
|
164847
|
+
* This keeps the concrete binding path beside its notation so inheritance
|
|
164848
|
+
* can fold both pieces of the effective end together. */
|
|
164849
|
+
declaredConnectionUsageEndsOf(owner, index2) {
|
|
164850
|
+
const clause = owner.connect;
|
|
164851
|
+
if (clause) {
|
|
164852
|
+
const rawEnds = clause.ends?.length ? clause.ends : [clause.source, clause.target].filter((end) => end !== void 0);
|
|
164853
|
+
return rawEnds.map((end, ordinal) => ({
|
|
164854
|
+
notation: this.connectorEndNotation(owner, end, index2, ordinal),
|
|
164855
|
+
path: this.connectorEndPath(end),
|
|
164856
|
+
binding: this.connectorEndBinding(end),
|
|
164857
|
+
ordinal
|
|
164858
|
+
}));
|
|
164859
|
+
}
|
|
164860
|
+
const effective = this.connectionEndNotationsOf(owner, index2);
|
|
164861
|
+
return membersOf(owner).filter(isEndMember).map((end, ordinal) => {
|
|
164862
|
+
const local = declaredConnectionEndNotation(end);
|
|
164863
|
+
const declaredBinding = this.declaredConnectionEndBinding(end);
|
|
164864
|
+
return {
|
|
164865
|
+
notation: mergeConnectionEndNotation(local, this.matchingConnectionEndNotation(effective, local.role, ordinal)),
|
|
164866
|
+
...declaredBinding,
|
|
164867
|
+
ordinal
|
|
164868
|
+
};
|
|
164869
|
+
});
|
|
164870
|
+
}
|
|
164871
|
+
/** REQ-192/195: an explicit connection or interface usage redefinition
|
|
164872
|
+
* inherits any end binding it does not replace. Sources are nearest first.
|
|
164873
|
+
* Role and redefinition claims identify corresponding ends, with source-local
|
|
164874
|
+
* ordinal as the fallback. */
|
|
164875
|
+
effectiveConnectionUsageEndsOf(owner, index2) {
|
|
164876
|
+
const declared = [];
|
|
164877
|
+
for (const source of [owner, ...this.inheritedFeatureOwnersOf(owner, index2)]) {
|
|
164878
|
+
if (source.$type !== owner.$type || !isConnectionDecl(source) && !isInterfaceDecl(source) || source.isDef === true)
|
|
164879
|
+
continue;
|
|
164880
|
+
for (const candidate of this.declaredConnectionUsageEndsOf(source, index2)) {
|
|
164881
|
+
const claims = connectionEndNotationClaims(candidate.notation).map(lastSeg);
|
|
164882
|
+
let existingIndex = claims.length > 0 ? declared.findIndex((current2) => connectionEndNotationClaims(current2.notation).map(lastSeg).some((claim) => claims.includes(claim))) : -1;
|
|
164883
|
+
if (existingIndex < 0) {
|
|
164884
|
+
const ordinalIndex = declared.findIndex((current2) => current2.ordinal === candidate.ordinal);
|
|
164885
|
+
const ordinalClaims = ordinalIndex >= 0 ? connectionEndNotationClaims(declared[ordinalIndex].notation).map(lastSeg) : [];
|
|
164886
|
+
if (claims.length === 0 || ordinalClaims.length === 0)
|
|
164887
|
+
existingIndex = ordinalIndex;
|
|
164888
|
+
}
|
|
164889
|
+
if (existingIndex < 0) {
|
|
164890
|
+
declared.push(candidate);
|
|
164891
|
+
continue;
|
|
164892
|
+
}
|
|
164893
|
+
const nearer = declared[existingIndex];
|
|
164894
|
+
const inheritsPath = nearer.path === void 0;
|
|
164895
|
+
declared[existingIndex] = {
|
|
164896
|
+
...nearer,
|
|
164897
|
+
notation: mergeConnectionEndNotation(nearer.notation, candidate.notation),
|
|
164898
|
+
path: nearer.path ?? candidate.path,
|
|
164899
|
+
binding: inheritsPath ? candidate.binding : nearer.binding
|
|
164900
|
+
};
|
|
164901
|
+
}
|
|
164902
|
+
}
|
|
164903
|
+
const effective = this.connectionEndNotationsOf(owner, index2);
|
|
164904
|
+
const selectedDeclared = /* @__PURE__ */ new Set();
|
|
164905
|
+
const ends = effective.map((notation, ordinal) => {
|
|
164906
|
+
const claims = connectionEndNotationClaims(notation).map(lastSeg);
|
|
164907
|
+
let declaredIndex = declared.findIndex((candidate, candidateIndex) => !selectedDeclared.has(candidateIndex) && connectionEndNotationClaims(candidate.notation).map(lastSeg).some((claim) => claims.includes(claim)));
|
|
164908
|
+
if (declaredIndex < 0 && declared[ordinal] && !selectedDeclared.has(ordinal)) {
|
|
164909
|
+
const declaredClaims = connectionEndNotationClaims(declared[ordinal].notation).map(lastSeg);
|
|
164910
|
+
if (claims.length === 0 || declaredClaims.length === 0)
|
|
164911
|
+
declaredIndex = ordinal;
|
|
164912
|
+
}
|
|
164913
|
+
const concrete = declaredIndex >= 0 ? declared[declaredIndex] : void 0;
|
|
164914
|
+
if (declaredIndex >= 0)
|
|
164915
|
+
selectedDeclared.add(declaredIndex);
|
|
164916
|
+
return {
|
|
164917
|
+
notation: mergeConnectionEndNotation(concrete?.notation ?? {}, notation),
|
|
164918
|
+
path: concrete?.path,
|
|
164919
|
+
binding: concrete?.binding,
|
|
164920
|
+
ordinal
|
|
164921
|
+
};
|
|
164922
|
+
});
|
|
164923
|
+
for (const [declaredIndex, candidate] of declared.entries()) {
|
|
164924
|
+
if (selectedDeclared.has(declaredIndex))
|
|
164925
|
+
continue;
|
|
164926
|
+
ends.push({ ...candidate, ordinal: ends.length });
|
|
164927
|
+
}
|
|
164928
|
+
return ends;
|
|
164929
|
+
}
|
|
164930
|
+
connectorEndNotation(owner, rawEnd, index2, ordinal = 0) {
|
|
164931
|
+
const explicit = rawEnd && typeof rawEnd === "object" && "$type" in rawEnd ? connectionEndMultiplicity(rawEnd) : void 0;
|
|
164932
|
+
const role = this.connectorEndRole(rawEnd);
|
|
164933
|
+
const inherited = this.matchingConnectionEndNotation(this.connectionEndNotationsOf(owner, index2), role, ordinal);
|
|
164934
|
+
return mergeConnectionEndNotation({
|
|
164935
|
+
role,
|
|
164936
|
+
multiplicity: explicit ?? inherited?.multiplicity
|
|
164937
|
+
}, inherited);
|
|
164938
|
+
}
|
|
164299
164939
|
// FlowStmt ends for both spec forms (OMG SysML 8.2.2.16): explicit
|
|
164300
164940
|
// `from a to b`, and the keyword-less shorthand `flow a.x to b.y;` whose
|
|
164301
164941
|
// source is parsed as name + dotted segments.
|
|
@@ -164308,6 +164948,27 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164308
164948
|
}
|
|
164309
164949
|
return { source: void 0, target: fm.target ? String(fm.target) : void 0 };
|
|
164310
164950
|
}
|
|
164951
|
+
// REQ-401 — the `flows-compartment` row of one flow or message usage (OMG
|
|
164952
|
+
// SysML 8.2.3.16). Rebuilt from the declaration instead of copied from the
|
|
164953
|
+
// source text, because a flow may carry a BODY (`flow a.x to b.y { doc ... }`)
|
|
164954
|
+
// whose whole text would otherwise be inlined into one compartment row.
|
|
164955
|
+
// `ends` overrides the declared endpoints with the concrete ones a relationship
|
|
164956
|
+
// usage rebinds them to (REQ-402).
|
|
164957
|
+
// REQ-401 — Flow notation: on-connection decoration, port docking, and the flow usage node
|
|
164958
|
+
flowRowText(flow, ends) {
|
|
164959
|
+
const fm = flow;
|
|
164960
|
+
const declared = ends ?? this.flowStmtEnds(fm);
|
|
164961
|
+
const type = typeText(flow);
|
|
164962
|
+
const payload = this.flowPayloadText(fm);
|
|
164963
|
+
return [
|
|
164964
|
+
flowKeyword(fm),
|
|
164965
|
+
flowStmtName(flow),
|
|
164966
|
+
type ? `: ${type}` : void 0,
|
|
164967
|
+
payload ? `of ${payload}` : void 0,
|
|
164968
|
+
declared.source ? `from ${declared.source}` : void 0,
|
|
164969
|
+
declared.target ? `to ${declared.target}` : void 0
|
|
164970
|
+
].filter(Boolean).join(" ");
|
|
164971
|
+
}
|
|
164311
164972
|
// Payload text of a flow/message (`of Fuel` / `of f : Fuel`) per OMG SysML
|
|
164312
164973
|
// 8.2.2.16 PayloadFeature.
|
|
164313
164974
|
flowPayloadText(fm) {
|
|
@@ -164317,6 +164978,87 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164317
164978
|
const typeRef = p.type?.$refText ?? p.typing?.type?.$refText;
|
|
164318
164979
|
return typeRef ? lastSeg(typeRef) : p.name;
|
|
164319
164980
|
}
|
|
164981
|
+
// REQ-402 — the flows a connection or interface usage CARRIES. A flow declared
|
|
164982
|
+
// in a `connection def` / `interface def` body (OMG SysML 8.2.3.16, and the
|
|
164983
|
+
// `Flow Interface Example` of the training corpus) is transported by every
|
|
164984
|
+
// usage of that definition; it is not a transfer of its own between two
|
|
164985
|
+
// unrelated features. Each end path is rebound through the usage's own end
|
|
164986
|
+
// bindings, so the definition-local `supplierPort.fuelSupply` reads as the
|
|
164987
|
+
// concrete `tankAssy.fuelTankPort.fuelSupply` this usage connects, and the
|
|
164988
|
+
// transfer direction is expressed relative to the usage's own end ordinals so
|
|
164989
|
+
// it survives whichever notation the relationship is drawn in.
|
|
164990
|
+
// REQ-402 — Flows carried by a connection or interface usage
|
|
164991
|
+
carriedFlowsOf(usage, ends, index2, uri) {
|
|
164992
|
+
const ordinalByRole = /* @__PURE__ */ new Map();
|
|
164993
|
+
const pathByRole = /* @__PURE__ */ new Map();
|
|
164994
|
+
for (const end of ends) {
|
|
164995
|
+
const role = end.notation.role;
|
|
164996
|
+
if (!role)
|
|
164997
|
+
continue;
|
|
164998
|
+
if (!ordinalByRole.has(role))
|
|
164999
|
+
ordinalByRole.set(role, end.ordinal);
|
|
165000
|
+
if (end.path && !pathByRole.has(role))
|
|
165001
|
+
pathByRole.set(role, end.path);
|
|
165002
|
+
}
|
|
165003
|
+
const rebind = (path10) => {
|
|
165004
|
+
if (!path10)
|
|
165005
|
+
return void 0;
|
|
165006
|
+
const segs = path10.split(".");
|
|
165007
|
+
const bound = pathByRole.get(segs[0]);
|
|
165008
|
+
return bound ? [bound, ...segs.slice(1)].join(".") : path10;
|
|
165009
|
+
};
|
|
165010
|
+
const carried = [];
|
|
165011
|
+
const seen = /* @__PURE__ */ new Set();
|
|
165012
|
+
for (const source of [usage, ...this.inheritedFeatureOwnersOf(usage, index2)]) {
|
|
165013
|
+
for (const member of membersOf(source)) {
|
|
165014
|
+
if (member.$type !== "FlowStmt" || member.isDef === true)
|
|
165015
|
+
continue;
|
|
165016
|
+
const fm = member;
|
|
165017
|
+
const flowEnds = this.flowStmtEnds(fm);
|
|
165018
|
+
const name = flowStmtName(member);
|
|
165019
|
+
const payload = this.flowPayloadText(fm);
|
|
165020
|
+
const key = name ?? `\0${flowEnds.source ?? ""}\0${flowEnds.target ?? ""}\0${payload ?? typeText(member) ?? ""}`;
|
|
165021
|
+
if (seen.has(key))
|
|
165022
|
+
continue;
|
|
165023
|
+
seen.add(key);
|
|
165024
|
+
const fromOrdinal = flowEnds.source ? ordinalByRole.get(flowEnds.source.split(".")[0]) : void 0;
|
|
165025
|
+
const from = rebind(flowEnds.source);
|
|
165026
|
+
const to = rebind(flowEnds.target);
|
|
165027
|
+
carried.push({
|
|
165028
|
+
flow: member,
|
|
165029
|
+
keyword: flowKeyword(fm),
|
|
165030
|
+
label: payload ?? typeText(member) ?? flowTransferredFeature(flowEnds),
|
|
165031
|
+
name,
|
|
165032
|
+
// The decoration rides the relationship, whose drawn direction
|
|
165033
|
+
// runs from its first end to its second.
|
|
165034
|
+
reversed: fromOrdinal !== void 0 && fromOrdinal > 0,
|
|
165035
|
+
inherited: source !== usage,
|
|
165036
|
+
message: fm.flowKind === "message",
|
|
165037
|
+
row: {
|
|
165038
|
+
text: this.flowRowText(member, { source: from, target: to }),
|
|
165039
|
+
source: sourceOf2(member, uri)
|
|
165040
|
+
}
|
|
165041
|
+
});
|
|
165042
|
+
}
|
|
165043
|
+
}
|
|
165044
|
+
return carried;
|
|
165045
|
+
}
|
|
165046
|
+
// REQ-402 — merge the transfers a relationship usage carries from its
|
|
165047
|
+
// definitions into the `flows` compartment its own body already contributes,
|
|
165048
|
+
// so one heading holds every transfer the usage transports.
|
|
165049
|
+
// REQ-402 — Flows carried by a connection or interface usage
|
|
165050
|
+
withCarriedFlowRows(compartments, carried) {
|
|
165051
|
+
const rows = carried.filter((flow) => flow.inherited).map((flow) => flow.row);
|
|
165052
|
+
if (!rows.length)
|
|
165053
|
+
return compartments;
|
|
165054
|
+
const out = [...compartments ?? []];
|
|
165055
|
+
const existing = out.findIndex((compartment) => compartment.title === "flows");
|
|
165056
|
+
if (existing >= 0)
|
|
165057
|
+
out[existing] = { ...out[existing], items: [...out[existing].items, ...rows] };
|
|
165058
|
+
else
|
|
165059
|
+
out.push({ title: "flows", items: rows });
|
|
165060
|
+
return out;
|
|
165061
|
+
}
|
|
164320
165062
|
// REQ-192/360/363 — the ONE recursive Interconnection View renderer. Given the
|
|
164321
165063
|
// top-level `roots` to draw, it renders each part instance and nests its
|
|
164322
165064
|
// internals recursively, drilling into a usage's type DEFINITION (+
|
|
@@ -164329,7 +165071,13 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164329
165071
|
const nodes = [];
|
|
164330
165072
|
const edges = [];
|
|
164331
165073
|
const frames = [];
|
|
165074
|
+
const primaryTarget = { nodes, edges, frames };
|
|
165075
|
+
const definitionTarget = { nodes: [], edges: [], frames: [] };
|
|
164332
165076
|
const eRef = { n: 0 };
|
|
165077
|
+
const drawnPartIds = /* @__PURE__ */ new Set();
|
|
165078
|
+
const endpointProvenance = /* @__PURE__ */ new Map();
|
|
165079
|
+
const typedPartUsages = [];
|
|
165080
|
+
const definitionRootIds = /* @__PURE__ */ new Map();
|
|
164333
165081
|
const enclosingPackage = (n2) => {
|
|
164334
165082
|
let c = n2.$container;
|
|
164335
165083
|
while (c && c !== scope) {
|
|
@@ -164352,29 +165100,14 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164352
165100
|
pkgFrame.set(pkg, id2);
|
|
164353
165101
|
return id2;
|
|
164354
165102
|
};
|
|
164355
|
-
const childUsagesOf = (part) =>
|
|
164356
|
-
const out = this.nestedUsages(part, isPartDecl);
|
|
164357
|
-
const have = new Set(out.map(effectiveNameOf).filter((x) => !!x));
|
|
164358
|
-
for (const source of this.inheritedFeatureOwnersOf(part, index2)) {
|
|
164359
|
-
for (const usage of this.nestedUsages(source, isPartDecl)) {
|
|
164360
|
-
const nm = effectiveNameOf(usage);
|
|
164361
|
-
if (nm !== void 0) {
|
|
164362
|
-
if (have.has(nm))
|
|
164363
|
-
continue;
|
|
164364
|
-
have.add(nm);
|
|
164365
|
-
}
|
|
164366
|
-
out.push(usage);
|
|
164367
|
-
}
|
|
164368
|
-
}
|
|
164369
|
-
return out;
|
|
164370
|
-
};
|
|
165103
|
+
const childUsagesOf = (part) => this.structuralChildUsagesOf(part, index2);
|
|
164371
165104
|
const effectiveMembersOf = (part) => {
|
|
164372
165105
|
const effective = [];
|
|
164373
165106
|
const claimedNames = /* @__PURE__ */ new Set();
|
|
164374
165107
|
for (const source of [part, ...this.inheritedFeatureOwnersOf(part, index2)]) {
|
|
164375
165108
|
for (const member of membersOf(source)) {
|
|
164376
165109
|
const relationship = member;
|
|
164377
|
-
const emptyPrefixFlow = member
|
|
165110
|
+
const emptyPrefixFlow = isEmptyPrefixFlow(member);
|
|
164378
165111
|
const emptyPrefixInterface = isInterfaceDecl(member) && relationship.target !== void 0 && relationship.connect === void 0;
|
|
164379
165112
|
const namedRelationship = isConnectorDecl(member) || isConnectionDecl(member) || isInterfaceDecl(member) && !emptyPrefixInterface || member.$type === "BindingDecl" || member.$type === "FlowStmt" && !emptyPrefixFlow;
|
|
164380
165113
|
if (namedRelationship) {
|
|
@@ -164394,6 +165127,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164394
165127
|
const actionPort = /* @__PURE__ */ new Map();
|
|
164395
165128
|
const localNode = /* @__PURE__ */ new Map();
|
|
164396
165129
|
const actionPinIds = /* @__PURE__ */ new Set();
|
|
165130
|
+
const structuralPortIds = /* @__PURE__ */ new Set();
|
|
164397
165131
|
const addActionPort = (key, id2) => {
|
|
164398
165132
|
if (!actionPort.has(key))
|
|
164399
165133
|
actionPort.set(key, id2);
|
|
@@ -164411,6 +165145,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164411
165145
|
localPort.set(`${id2}.${rel2}`, port.id);
|
|
164412
165146
|
if (bare)
|
|
164413
165147
|
localPort.set(rel2, port.id);
|
|
165148
|
+
structuralPortIds.add(port.id);
|
|
164414
165149
|
}
|
|
164415
165150
|
};
|
|
164416
165151
|
for (const { usage, id: id2 } of childInfos)
|
|
@@ -164457,25 +165192,40 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164457
165192
|
return actionPort.get(firstLast) ?? void 0;
|
|
164458
165193
|
if (localPort.has(firstLast))
|
|
164459
165194
|
return localPort.get(firstLast);
|
|
165195
|
+
const rootId = localNode.get(segs[0]);
|
|
165196
|
+
const nestedId = rootId ? `${rootId}::${segs.slice(1).join("::")}` : void 0;
|
|
165197
|
+
if (nestedId && drawnPartIds.has(nestedId))
|
|
165198
|
+
return nestedId;
|
|
164460
165199
|
}
|
|
164461
165200
|
const bare = bareName2.get(segs[segs.length - 1]);
|
|
164462
165201
|
if (bare)
|
|
164463
165202
|
return bare;
|
|
164464
165203
|
return segs.length === 1 ? localNode.get(segs[0]) : void 0;
|
|
164465
165204
|
};
|
|
164466
|
-
return { resolve: resolve8, actionPinIds };
|
|
165205
|
+
return { resolve: resolve8, actionPinIds, structuralPortIds };
|
|
164467
165206
|
};
|
|
164468
|
-
const renderInstance = (part, instanceId, parentFrame, seenTypes, depth, inheritedLocalUsage, inheritedLocalPath = []) => {
|
|
165207
|
+
const renderInstance = (part, instanceId, parentFrame, seenTypes, depth, inheritedLocalUsage, inheritedLocalPath = [], target = primaryTarget, definitionLayerRoot = false, occurrenceInherited = false, parentOccurrencePath = []) => {
|
|
165208
|
+
drawnPartIds.add(instanceId);
|
|
165209
|
+
const occurrencePath = [...parentOccurrencePath, part];
|
|
165210
|
+
endpointProvenance.set(instanceId, occurrencePath);
|
|
164469
165211
|
const typeDef = part.isDef === true ? void 0 : this.resolveType(part, index2) ?? this.inheritedFeatureOwnersOf(part, index2).find((owner) => owner.isDef === true);
|
|
165212
|
+
if (typeDef && isPartDecl(typeDef) && typeDef.isDef === true && part.isDef !== true) {
|
|
165213
|
+
typedPartUsages.push({ usage: part, id: instanceId, definition: typeDef });
|
|
165214
|
+
}
|
|
164470
165215
|
const typeQ = typeDef ? qnameOf(typeDef) : void 0;
|
|
164471
165216
|
const declarationId = nameOf2(part) ? qnameOf(part) || instanceId : instanceId;
|
|
164472
165217
|
const projected = nameOf2(part) === void 0 || declarationId !== instanceId;
|
|
164473
165218
|
const localUsage = part.isDef !== true && !projected ? part : inheritedLocalUsage;
|
|
164474
165219
|
const localPath = part.isDef !== true && !projected ? [] : inheritedLocalPath;
|
|
164475
|
-
const
|
|
165220
|
+
const projectedPorts = this.portsOf(part, index2, uri, instanceId, localUsage);
|
|
165221
|
+
const ports = projectedPorts.ports;
|
|
165222
|
+
for (const [id2, origin] of projectedPorts.origins) {
|
|
165223
|
+
endpointProvenance.set(id2, [...occurrencePath, ...origin]);
|
|
165224
|
+
}
|
|
164476
165225
|
const syncDeclaration = this.synchronizationDeclarationOf(part, index2);
|
|
164477
165226
|
const editMeta = {
|
|
164478
165227
|
...ivEditMeta(part, instanceId, typeDef, localUsage, localPath, uri),
|
|
165228
|
+
...definitionLayerRoot ? { ivPartDef: true } : {},
|
|
164479
165229
|
...syncDeclaration && syncDeclaration !== part ? {
|
|
164480
165230
|
syncDeclarationId: qnameOf(syncDeclaration),
|
|
164481
165231
|
syncDeclarationName: effectiveNameOf(syncDeclaration),
|
|
@@ -164483,7 +165233,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164483
165233
|
} : {}
|
|
164484
165234
|
};
|
|
164485
165235
|
const children2 = depth < 8 && !(typeQ !== void 0 && seenTypes.has(typeQ)) ? childUsagesOf(part) : [];
|
|
164486
|
-
const concretePerformPath = (statement,
|
|
165236
|
+
const concretePerformPath = (statement, target2) => {
|
|
164487
165237
|
if (!this.isAnonymousBehaviorReference(statement)) {
|
|
164488
165238
|
return qnameOf(statement) || nameOf2(statement) || "perform";
|
|
164489
165239
|
}
|
|
@@ -164491,7 +165241,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164491
165241
|
const featureStart = segments.findIndex((segment, at) => at > 0 && segment.separator === ".");
|
|
164492
165242
|
if (featureStart > 0) {
|
|
164493
165243
|
const writtenPath = segments.map((segment) => segment.text).join("::");
|
|
164494
|
-
const targetName = qnameOf(
|
|
165244
|
+
const targetName = qnameOf(target2);
|
|
164495
165245
|
if (targetName === writtenPath || targetName.endsWith(`::${writtenPath}`)) {
|
|
164496
165246
|
return targetName;
|
|
164497
165247
|
}
|
|
@@ -164510,7 +165260,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164510
165260
|
return [qnameOf(root4), ...segments.slice(featureStart).map((segment) => segment.text)].join("::");
|
|
164511
165261
|
}
|
|
164512
165262
|
}
|
|
164513
|
-
return qnameOf(
|
|
165263
|
+
return qnameOf(target2) || nameOf2(target2) || segments.map((segment) => segment.text).join("::");
|
|
164514
165264
|
};
|
|
164515
165265
|
const performedActions = depth < 8 && !(typeQ !== void 0 && seenTypes.has(typeQ)) ? effectiveMembersOf(part).filter((m) => m.$type === "PerformStmt" && !!nameOf2(m)).map((act) => {
|
|
164516
165266
|
const pinSource = this.performTargetOf(act, index2) ?? act;
|
|
@@ -164550,7 +165300,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164550
165300
|
});
|
|
164551
165301
|
const emitOwnedActions = (frameOf) => {
|
|
164552
165302
|
for (const { act, name, id: actId, pins, meta } of performedActionInfos) {
|
|
164553
|
-
nodes.push({
|
|
165303
|
+
target.nodes.push({
|
|
164554
165304
|
id: actId,
|
|
164555
165305
|
name,
|
|
164556
165306
|
keyword: keywordFor(act),
|
|
@@ -164566,7 +165316,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164566
165316
|
}
|
|
164567
165317
|
};
|
|
164568
165318
|
if (children2.length > 0 || performedActions.length > 0) {
|
|
164569
|
-
frames.push({
|
|
165319
|
+
target.frames.push({
|
|
164570
165320
|
id: instanceId,
|
|
164571
165321
|
label: effectiveNameOf(part) ?? lastSeg(instanceId),
|
|
164572
165322
|
keyword: keywordFor(part),
|
|
@@ -164584,13 +165334,13 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164584
165334
|
const nextSeen = typeQ ? /* @__PURE__ */ new Set([...seenTypes, typeQ]) : seenTypes;
|
|
164585
165335
|
const childInfos = children2.map((cu) => ({ usage: cu, id: `${instanceId}::${effectiveNameOf(cu) ?? lastSeg(qnameOf(cu) || "")}` }));
|
|
164586
165336
|
for (const { usage, id: id2 } of childInfos) {
|
|
164587
|
-
renderInstance(usage, id2, instanceId, nextSeen, depth + 1, localUsage, [...localPath, effectiveNameOf(usage) ?? lastSeg(id2)]);
|
|
165337
|
+
renderInstance(usage, id2, instanceId, nextSeen, depth + 1, localUsage, [...localPath, effectiveNameOf(usage) ?? lastSeg(id2)], target, false, occurrenceInherited || !isAstDescendantOrSelf(usage, part), occurrencePath);
|
|
164588
165338
|
}
|
|
164589
165339
|
emitOwnedActions(instanceId);
|
|
164590
165340
|
const resolver = childResolver(childInfos, { usage: part, id: instanceId }, performedActionInfos);
|
|
164591
|
-
this.emitInterconnectEdges(effectiveMembersOf(part), resolver.resolve, children2, index2, uri, nodes, edges, eRef, instanceId, resolver.actionPinIds, part);
|
|
165341
|
+
this.emitInterconnectEdges(effectiveMembersOf(part), resolver.resolve, children2, index2, uri, target.nodes, target.edges, eRef, instanceId, resolver.actionPinIds, resolver.structuralPortIds, part, occurrenceInherited, endpointProvenance);
|
|
164592
165342
|
} else {
|
|
164593
|
-
nodes.push({
|
|
165343
|
+
target.nodes.push({
|
|
164594
165344
|
id: instanceId,
|
|
164595
165345
|
name: effectiveNameOf(part) ?? lastSeg(instanceId),
|
|
164596
165346
|
keyword: keywordFor(part),
|
|
@@ -164605,7 +165355,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164605
165355
|
meta: editMeta
|
|
164606
165356
|
});
|
|
164607
165357
|
const resolver = childResolver([], { usage: part, id: instanceId });
|
|
164608
|
-
this.emitInterconnectEdges(effectiveMembersOf(part), resolver.resolve, [], index2, uri, nodes, edges, eRef, instanceId, resolver.actionPinIds, part);
|
|
165358
|
+
this.emitInterconnectEdges(effectiveMembersOf(part), resolver.resolve, [], index2, uri, target.nodes, target.edges, eRef, instanceId, resolver.actionPinIds, resolver.structuralPortIds, part, occurrenceInherited, endpointProvenance);
|
|
164609
165359
|
}
|
|
164610
165360
|
};
|
|
164611
165361
|
const packageOfRoot = (root4) => enclosingPackage(root4) ?? scope;
|
|
@@ -164635,18 +165385,53 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164635
165385
|
const rootInfos = [];
|
|
164636
165386
|
for (const root4 of roots) {
|
|
164637
165387
|
const id2 = rootOccurrenceIds.get(root4) ?? rootBaseId(root4);
|
|
164638
|
-
|
|
165388
|
+
const rootIsDefinition = root4.isDef === true;
|
|
165389
|
+
if (rootIsDefinition)
|
|
165390
|
+
definitionRootIds.set(root4, id2);
|
|
165391
|
+
renderInstance(root4, id2, opts.packageFrames ? ensurePkgFrame(enclosingPackage(root4)) : void 0, /* @__PURE__ */ new Set(), 0, root4.isDef === true ? void 0 : root4, [], primaryTarget, opts.packageFrames && rootIsDefinition);
|
|
164639
165392
|
rootInfos.push({ usage: root4, id: id2, pkg: packageOfRoot(root4) });
|
|
164640
165393
|
}
|
|
165394
|
+
for (let cursor = 0; cursor < typedPartUsages.length; cursor++) {
|
|
165395
|
+
const { definition } = typedPartUsages[cursor];
|
|
165396
|
+
if (definitionRootIds.has(definition))
|
|
165397
|
+
continue;
|
|
165398
|
+
const definitionId = qnameOf(definition) || nameOf2(definition);
|
|
165399
|
+
if (!definitionId)
|
|
165400
|
+
continue;
|
|
165401
|
+
definitionRootIds.set(definition, definitionId);
|
|
165402
|
+
renderInstance(definition, definitionId, void 0, /* @__PURE__ */ new Set(), 0, void 0, [], definitionTarget, true);
|
|
165403
|
+
}
|
|
165404
|
+
const linkedDefinitions = /* @__PURE__ */ new Set();
|
|
165405
|
+
for (const { id: id2, definition } of typedPartUsages) {
|
|
165406
|
+
const definitionId = definitionRootIds.get(definition);
|
|
165407
|
+
if (!definitionId || id2 === definitionId)
|
|
165408
|
+
continue;
|
|
165409
|
+
const key = `${id2}\0${definitionId}`;
|
|
165410
|
+
if (linkedDefinitions.has(key))
|
|
165411
|
+
continue;
|
|
165412
|
+
linkedDefinitions.add(key);
|
|
165413
|
+
definitionTarget.edges.push({
|
|
165414
|
+
id: `e${eRef.n++}`,
|
|
165415
|
+
from: id2,
|
|
165416
|
+
to: definitionId,
|
|
165417
|
+
kind: "definedBy",
|
|
165418
|
+
meta: { ivDefinedBy: true }
|
|
165419
|
+
});
|
|
165420
|
+
}
|
|
164641
165421
|
if (opts.packageFrames) {
|
|
164642
165422
|
for (const pkg of [scope, ...[...ast_utils_exports.streamAllContents(scope)].filter(isPackage)]) {
|
|
164643
165423
|
const localInfos = rootInfos.filter((r) => r.pkg === pkg && r.usage.isDef !== true);
|
|
164644
165424
|
const localRoots = localInfos.map((r) => r.usage);
|
|
164645
165425
|
const resolver = childResolver(localInfos);
|
|
164646
|
-
this.emitInterconnectEdges(membersOf(pkg), resolver.resolve, localRoots, index2, uri, nodes, edges, eRef, void 0, resolver.actionPinIds, pkg);
|
|
165426
|
+
this.emitInterconnectEdges(membersOf(pkg), resolver.resolve, localRoots, index2, uri, nodes, edges, eRef, void 0, resolver.actionPinIds, resolver.structuralPortIds, pkg, false, endpointProvenance);
|
|
164647
165427
|
}
|
|
164648
165428
|
}
|
|
164649
|
-
|
|
165429
|
+
const definitionLayer = definitionTarget.nodes.length > 0 || definitionTarget.edges.length > 0 || definitionTarget.frames.length > 0 ? {
|
|
165430
|
+
nodes: definitionTarget.nodes,
|
|
165431
|
+
edges: definitionTarget.edges,
|
|
165432
|
+
...definitionTarget.frames.length ? { frames: definitionTarget.frames } : {}
|
|
165433
|
+
} : void 0;
|
|
165434
|
+
return { nodes, edges, frames, definitionLayer };
|
|
164650
165435
|
}
|
|
164651
165436
|
// REQ-192 — Interconnection View for a single part/part-def anchor: the anchor
|
|
164652
165437
|
// is the (non-collapsible) container frame and its internals nest inside it,
|
|
@@ -164654,7 +165439,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164654
165439
|
buildInterconnectionView(ctx) {
|
|
164655
165440
|
const anchor = ctx.anchor;
|
|
164656
165441
|
const anchorId = qnameOf(anchor) || nameOf2(anchor) || "__anchor__";
|
|
164657
|
-
const { nodes, edges, frames } = this.renderIvRoots(ctx, [anchor], { packageFrames: false });
|
|
165442
|
+
const { nodes, edges, frames, definitionLayer } = this.renderIvRoots(ctx, [anchor], { packageFrames: false });
|
|
164658
165443
|
if (anchor.isDef === true && frames.length === 0 && nodes.every((n2) => !n2.ports?.length && !n2.compartments?.length)) {
|
|
164659
165444
|
return this.model("iv", anchor, [], []);
|
|
164660
165445
|
}
|
|
@@ -164668,6 +165453,8 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164668
165453
|
}
|
|
164669
165454
|
const model = this.model("iv", anchor, nodes, edges);
|
|
164670
165455
|
model.frames = frames;
|
|
165456
|
+
if (definitionLayer)
|
|
165457
|
+
model.layers = { definitions: definitionLayer };
|
|
164671
165458
|
model.meta = { ...model.meta, unified: true, groupMode: "nested" };
|
|
164672
165459
|
return model;
|
|
164673
165460
|
}
|
|
@@ -164676,14 +165463,16 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164676
165463
|
// single Interconnection View (called once over the anchor's whole subtree)
|
|
164677
165464
|
// and the package overview (called once per container part, tagging any
|
|
164678
165465
|
// synthetic n-ary dot with that container's frame id).
|
|
164679
|
-
emitInterconnectEdges(members, resolveEnd, parts, index2, uri, nodes, edges, eRef, frameId, actionPinIds = /* @__PURE__ */ new Set(), memberOwner) {
|
|
165466
|
+
emitInterconnectEdges(members, resolveEnd, parts, index2, uri, nodes, edges, eRef, frameId, actionPinIds = /* @__PURE__ */ new Set(), structuralPortIds = /* @__PURE__ */ new Set(), memberOwner, memberOwnerInherited = false, endpointProvenance = /* @__PURE__ */ new Map()) {
|
|
164680
165467
|
const memberList2 = [...members];
|
|
165468
|
+
const pendingFlows = [];
|
|
165469
|
+
const firstEdge = edges.length;
|
|
164681
165470
|
const relationshipFields = (source) => {
|
|
164682
165471
|
let directMember = source;
|
|
164683
165472
|
while (directMember.$container && directMember.$container !== memberOwner) {
|
|
164684
165473
|
directMember = directMember.$container;
|
|
164685
165474
|
}
|
|
164686
|
-
const inherited = !!memberOwner && directMember.$container !== memberOwner;
|
|
165475
|
+
const inherited = memberOwnerInherited || !!memberOwner && directMember.$container !== memberOwner;
|
|
164687
165476
|
const meta = {
|
|
164688
165477
|
...inherited ? { ivInheritedRelation: true } : {},
|
|
164689
165478
|
...frameId ? { ivRelationshipOwnerId: frameId } : {}
|
|
@@ -164694,12 +165483,38 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164694
165483
|
};
|
|
164695
165484
|
};
|
|
164696
165485
|
const supportsEndpoints = (kind, ids) => {
|
|
165486
|
+
if (kind === "interface") {
|
|
165487
|
+
return ids.length > 0 && ids.every((id2) => structuralPortIds.has(id2));
|
|
165488
|
+
}
|
|
164697
165489
|
const pinCount = ids.filter((id2) => actionPinIds.has(id2)).length;
|
|
164698
165490
|
if (pinCount === 0)
|
|
164699
165491
|
return true;
|
|
164700
165492
|
return ids.length === 2 && pinCount === 2 && (kind === "flow" || kind === "binding");
|
|
164701
165493
|
};
|
|
164702
|
-
const dot = (id2, name, src) => ({
|
|
165494
|
+
const dot = (id2, name, src) => ({
|
|
165495
|
+
id: id2,
|
|
165496
|
+
name,
|
|
165497
|
+
keyword: "connection",
|
|
165498
|
+
isDef: false,
|
|
165499
|
+
shape: "dot",
|
|
165500
|
+
frame: frameId,
|
|
165501
|
+
source: sourceOf2(src, uri),
|
|
165502
|
+
meta: { naryConnectionHub: true }
|
|
165503
|
+
});
|
|
165504
|
+
const connectionUsageNodeId = (connection) => {
|
|
165505
|
+
const source = sourceOf2(connection, uri);
|
|
165506
|
+
const ownerId = frameId ?? (qnameOf(memberOwner ?? connection) || "iv");
|
|
165507
|
+
const semanticName = frameId ? effectiveNameOf(connection) : qnameOf(connection);
|
|
165508
|
+
const suffix = semanticName ?? (source ? `${source.range.start.line}_${source.range.start.character}` : `${eRef.n}`);
|
|
165509
|
+
return `${ownerId}::__connection_${suffix}`;
|
|
165510
|
+
};
|
|
165511
|
+
const interfaceUsageNodeId = (interfaceUsage) => {
|
|
165512
|
+
const source = sourceOf2(interfaceUsage, uri);
|
|
165513
|
+
const ownerId = frameId ?? (qnameOf(memberOwner ?? interfaceUsage) || "iv");
|
|
165514
|
+
const semanticName = frameId ? effectiveNameOf(interfaceUsage) : qnameOf(interfaceUsage);
|
|
165515
|
+
const suffix = semanticName ?? (source ? `${source.range.start.line}_${source.range.start.character}` : `${eRef.n}`);
|
|
165516
|
+
return `${ownerId}::__interface_${suffix}`;
|
|
165517
|
+
};
|
|
164703
165518
|
const emitConnector = (rawEnds, src, label, name, type) => {
|
|
164704
165519
|
const resolvedEnds = rawEnds.map((end) => ({ id: resolveEnd(this.connectorEndPath(end) ?? ""), end })).filter((x) => !!x.id);
|
|
164705
165520
|
if (resolvedEnds.length < 2)
|
|
@@ -164707,6 +165522,8 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164707
165522
|
if (!supportsEndpoints("connect", resolvedEnds.map(({ id: id2 }) => id2)))
|
|
164708
165523
|
return;
|
|
164709
165524
|
if (resolvedEnds.length === 2) {
|
|
165525
|
+
const fromNotation = this.connectorEndNotation(src, resolvedEnds[0].end, index2, 0);
|
|
165526
|
+
const toNotation = this.connectorEndNotation(src, resolvedEnds[1].end, index2, 1);
|
|
164710
165527
|
edges.push({
|
|
164711
165528
|
id: `e${eRef.n++}`,
|
|
164712
165529
|
from: resolvedEnds[0].id,
|
|
@@ -164716,15 +165533,20 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164716
165533
|
type,
|
|
164717
165534
|
isDef: false,
|
|
164718
165535
|
label,
|
|
164719
|
-
|
|
164720
|
-
|
|
165536
|
+
endRoleFrom: fromNotation.role,
|
|
165537
|
+
endLabelFrom: fromNotation.multiplicity,
|
|
165538
|
+
endAdornmentFrom: fromNotation.adornment,
|
|
165539
|
+
endRoleTo: toNotation.role,
|
|
165540
|
+
endLabelTo: toNotation.multiplicity,
|
|
165541
|
+
endAdornmentTo: toNotation.adornment,
|
|
164721
165542
|
...relationshipFields(src)
|
|
164722
165543
|
});
|
|
164723
165544
|
return;
|
|
164724
165545
|
}
|
|
164725
165546
|
const dotId = `__nary_${eRef.n}__`;
|
|
164726
165547
|
nodes.push(dot(dotId, label ?? "", src));
|
|
164727
|
-
for (const { id: endId, end } of resolvedEnds) {
|
|
165548
|
+
for (const [ordinal, { id: endId, end }] of resolvedEnds.entries()) {
|
|
165549
|
+
const notation = this.connectorEndNotation(src, end, index2, ordinal);
|
|
164728
165550
|
edges.push({
|
|
164729
165551
|
id: `e${eRef.n++}`,
|
|
164730
165552
|
from: dotId,
|
|
@@ -164734,7 +165556,9 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164734
165556
|
type,
|
|
164735
165557
|
isDef: false,
|
|
164736
165558
|
label,
|
|
164737
|
-
|
|
165559
|
+
endRoleTo: notation.role,
|
|
165560
|
+
endLabelTo: notation.multiplicity,
|
|
165561
|
+
endAdornmentTo: notation.adornment,
|
|
164738
165562
|
...relationshipFields(src)
|
|
164739
165563
|
});
|
|
164740
165564
|
}
|
|
@@ -164769,21 +165593,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164769
165593
|
} else if (m.$type === "ConnectStmt") {
|
|
164770
165594
|
const cs = m;
|
|
164771
165595
|
if (cs.ends?.length) {
|
|
164772
|
-
|
|
164773
|
-
if (resolvedEnds.length >= 2 && supportsEndpoints("connect", resolvedEnds.map(({ id: id2 }) => id2))) {
|
|
164774
|
-
const dotId = `__nary_${eRef.n}__`;
|
|
164775
|
-
nodes.push(dot(dotId, "", m));
|
|
164776
|
-
for (const { id: endId, end } of resolvedEnds) {
|
|
164777
|
-
edges.push({
|
|
164778
|
-
id: `e${eRef.n++}`,
|
|
164779
|
-
from: dotId,
|
|
164780
|
-
to: endId,
|
|
164781
|
-
kind: "connect",
|
|
164782
|
-
endLabelTo: multText(end),
|
|
164783
|
-
...relationshipFields(m)
|
|
164784
|
-
});
|
|
164785
|
-
}
|
|
164786
|
-
}
|
|
165596
|
+
emitConnector(cs.ends, m);
|
|
164787
165597
|
} else {
|
|
164788
165598
|
const srcEnd = m.source;
|
|
164789
165599
|
const tgtEnd = m.target;
|
|
@@ -164791,6 +165601,8 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164791
165601
|
const from = resolveEnd(srcPath);
|
|
164792
165602
|
const to = resolveEnd(this.connectorEndPath(tgtEnd) ?? "");
|
|
164793
165603
|
if (from && to && supportsEndpoints("connect", [from, to])) {
|
|
165604
|
+
const fromNotation = this.connectorEndNotation(m, srcEnd, index2, 0);
|
|
165605
|
+
const toNotation = this.connectorEndNotation(m, tgtEnd, index2, 1);
|
|
164794
165606
|
edges.push({
|
|
164795
165607
|
id: `e${eRef.n++}`,
|
|
164796
165608
|
from,
|
|
@@ -164798,29 +165610,19 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164798
165610
|
kind: "connect",
|
|
164799
165611
|
label: this.flowItemLabel(srcPath, parts, index2),
|
|
164800
165612
|
// REQ-179 — connector end multiplicities (`connect [1] a to [0..*] b;`)
|
|
164801
|
-
|
|
164802
|
-
|
|
165613
|
+
endRoleFrom: fromNotation.role,
|
|
165614
|
+
endLabelFrom: fromNotation.multiplicity,
|
|
165615
|
+
endAdornmentFrom: fromNotation.adornment,
|
|
165616
|
+
endRoleTo: toNotation.role,
|
|
165617
|
+
endLabelTo: toNotation.multiplicity,
|
|
165618
|
+
endAdornmentTo: toNotation.adornment,
|
|
164803
165619
|
...relationshipFields(m)
|
|
164804
165620
|
});
|
|
164805
165621
|
}
|
|
164806
165622
|
}
|
|
164807
165623
|
} else if (m.$type === "FlowStmt") {
|
|
164808
|
-
|
|
164809
|
-
|
|
164810
|
-
continue;
|
|
164811
|
-
const { source, target } = this.flowStmtEnds(fm);
|
|
164812
|
-
const from = resolveEnd(source ?? "");
|
|
164813
|
-
const to = resolveEnd(target ?? "");
|
|
164814
|
-
if (from && to && supportsEndpoints("flow", [from, to])) {
|
|
164815
|
-
edges.push({
|
|
164816
|
-
id: `e${eRef.n++}`,
|
|
164817
|
-
from,
|
|
164818
|
-
to,
|
|
164819
|
-
kind: "flow",
|
|
164820
|
-
label: this.flowPayloadText(fm) ?? typeText(m) ?? nameOf2(m),
|
|
164821
|
-
...relationshipFields(m)
|
|
164822
|
-
});
|
|
164823
|
-
}
|
|
165624
|
+
if (m.isDef !== true)
|
|
165625
|
+
pendingFlows.push(m);
|
|
164824
165626
|
} else if (m.$type === "BindStmt" || m.$type === "BindingConnectorStmt" || m.$type === "BindingDecl") {
|
|
164825
165627
|
const bn = m;
|
|
164826
165628
|
const leftEnd = bn.left ?? bn.source;
|
|
@@ -164845,110 +165647,284 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164845
165647
|
});
|
|
164846
165648
|
}
|
|
164847
165649
|
} else if (isInterfaceDecl(m) && m.isDef !== true) {
|
|
164848
|
-
const
|
|
164849
|
-
if (
|
|
164850
|
-
const
|
|
164851
|
-
const
|
|
164852
|
-
const
|
|
164853
|
-
const
|
|
164854
|
-
|
|
164855
|
-
const docks = resolvedEnds.length === rawEnds.length && supportsEndpoints("interface", resolvedEnds.map(({ id: id2 }) => id2));
|
|
164856
|
-
if (docks && resolvedEnds.length === 2) {
|
|
165650
|
+
const interfaceUsage = m;
|
|
165651
|
+
if (interfaceUsage.target !== void 0 && interfaceUsage.connect === void 0) {
|
|
165652
|
+
const sourcePath = [nameOf2(m) ?? "", ...interfaceUsage.srcSegs ?? []].filter(Boolean).join(".");
|
|
165653
|
+
const targetPath = this.featurePath(interfaceUsage.target) ?? "";
|
|
165654
|
+
const from = resolveEnd(sourcePath);
|
|
165655
|
+
const to = resolveEnd(targetPath);
|
|
165656
|
+
if (from && to && supportsEndpoints("interface", [from, to])) {
|
|
164857
165657
|
edges.push({
|
|
164858
165658
|
id: `e${eRef.n++}`,
|
|
164859
|
-
from
|
|
164860
|
-
to
|
|
165659
|
+
from,
|
|
165660
|
+
to,
|
|
164861
165661
|
kind: "interface",
|
|
164862
|
-
name,
|
|
164863
|
-
type,
|
|
164864
165662
|
isDef: false,
|
|
164865
|
-
label,
|
|
164866
|
-
endLabelFrom: multText(resolvedEnds[0].end),
|
|
164867
|
-
endLabelTo: multText(resolvedEnds[1].end),
|
|
165663
|
+
label: "\xABinterface\xBB",
|
|
164868
165664
|
...relationshipFields(m)
|
|
164869
165665
|
});
|
|
164870
|
-
}
|
|
164871
|
-
|
|
164872
|
-
|
|
164873
|
-
|
|
164874
|
-
|
|
164875
|
-
|
|
164876
|
-
|
|
164877
|
-
|
|
164878
|
-
|
|
164879
|
-
|
|
164880
|
-
|
|
164881
|
-
|
|
164882
|
-
|
|
164883
|
-
|
|
164884
|
-
|
|
164885
|
-
|
|
165666
|
+
}
|
|
165667
|
+
continue;
|
|
165668
|
+
}
|
|
165669
|
+
const name = effectiveNameOf(m);
|
|
165670
|
+
const inheritedType = this.inheritedFeatureOwnersOf(m, index2).filter((candidate) => isInterfaceDecl(candidate) && candidate.isDef !== true).map(typeText).find((candidate) => !!candidate);
|
|
165671
|
+
const type = typeText(m) ?? inheritedType;
|
|
165672
|
+
const usageEnds = this.effectiveConnectionUsageEndsOf(m, index2);
|
|
165673
|
+
const usageId = interfaceUsageNodeId(m);
|
|
165674
|
+
const usageSource = sourceOf2(m, uri);
|
|
165675
|
+
const relationship = relationshipFields(m);
|
|
165676
|
+
const resolvedUsageEnds = usageEnds.flatMap((end, ordinal) => {
|
|
165677
|
+
const targetId = end.path ? resolveEnd(end.path) : void 0;
|
|
165678
|
+
return targetId && supportsEndpoints("interface", [targetId]) ? [{ end, ordinal, targetId }] : [];
|
|
165679
|
+
});
|
|
165680
|
+
const inherited = relationship.meta?.ivInheritedRelation === true;
|
|
165681
|
+
const visibleUsageEnds = inherited ? resolvedUsageEnds.filter(({ end, targetId }) => this.connectionUsageEndBindingMatches(end, endpointProvenance.get(targetId), frameId ? endpointProvenance.get(frameId) : void 0, index2)) : resolvedUsageEnds;
|
|
165682
|
+
if (inherited && visibleUsageEnds.length === 0)
|
|
165683
|
+
continue;
|
|
165684
|
+
const resolvedOrdinals = new Set(visibleUsageEnds.map(({ ordinal }) => ordinal));
|
|
165685
|
+
const ownerNode = frameId ? nodes.find((node) => node.id === frameId) : void 0;
|
|
165686
|
+
const usageFrame = ownerNode ? ownerNode.frame : frameId;
|
|
165687
|
+
const ports = usageEnds.map((end, ordinal) => {
|
|
165688
|
+
const role = end.notation.role;
|
|
165689
|
+
const direction = end.notation.direction === "in" || end.notation.direction === "out" || end.notation.direction === "inout" ? end.notation.direction : void 0;
|
|
165690
|
+
return {
|
|
165691
|
+
id: `${usageId}::__end_${ordinal}`,
|
|
165692
|
+
name: role ?? `end${ordinal + 1}`,
|
|
165693
|
+
type: end.notation.type,
|
|
165694
|
+
direction,
|
|
165695
|
+
isDef: false,
|
|
165696
|
+
pin: false,
|
|
165697
|
+
source: usageSource,
|
|
165698
|
+
meta: {
|
|
165699
|
+
// The shared renderer uses this presentation marker for
|
|
165700
|
+
// the outline-coloured dot and its single outward dock.
|
|
165701
|
+
connectionEndPin: true,
|
|
165702
|
+
interfaceEndPort: true,
|
|
165703
|
+
connectionUsageId: usageId,
|
|
165704
|
+
interfaceUsageId: usageId,
|
|
165705
|
+
connectionEndOrdinal: ordinal,
|
|
165706
|
+
...role ? { connectionEndRole: role } : {},
|
|
165707
|
+
...resolvedOrdinals.has(ordinal) ? { connectionEndBound: true } : {},
|
|
165708
|
+
...end.notation.multiplicity ? { connectionEndMultiplicity: end.notation.multiplicity } : {},
|
|
165709
|
+
...end.notation.adornment ? { connectionEndAdornment: end.notation.adornment } : {}
|
|
164886
165710
|
}
|
|
164887
|
-
}
|
|
164888
|
-
|
|
164889
|
-
|
|
164890
|
-
|
|
164891
|
-
|
|
164892
|
-
|
|
164893
|
-
|
|
164894
|
-
|
|
164895
|
-
|
|
164896
|
-
|
|
164897
|
-
|
|
164898
|
-
|
|
164899
|
-
|
|
164900
|
-
|
|
164901
|
-
|
|
164902
|
-
|
|
165711
|
+
};
|
|
165712
|
+
});
|
|
165713
|
+
const carriedFlows = this.carriedFlowsOf(m, usageEnds, index2, uri);
|
|
165714
|
+
nodes.push({
|
|
165715
|
+
id: usageId,
|
|
165716
|
+
name: name ?? ANONYMOUS_INTERFACE_NAME,
|
|
165717
|
+
keyword: "interface",
|
|
165718
|
+
isDef: false,
|
|
165719
|
+
shape: "box",
|
|
165720
|
+
type,
|
|
165721
|
+
multiplicity: multText(m),
|
|
165722
|
+
ports,
|
|
165723
|
+
...usageFrame ? { frame: usageFrame } : {},
|
|
165724
|
+
compartments: this.withCarriedFlowRows(this.compartmentsFor(m, uri, index2), carriedFlows),
|
|
165725
|
+
source: usageSource,
|
|
165726
|
+
meta: {
|
|
165727
|
+
...relationship.meta ?? {},
|
|
165728
|
+
interfaceUsage: true,
|
|
165729
|
+
...name ? { explicitRelationshipName: name } : {},
|
|
165730
|
+
...flowDecorationMeta(carriedFlows)
|
|
164903
165731
|
}
|
|
165732
|
+
});
|
|
165733
|
+
for (const { end, ordinal, targetId } of visibleUsageEnds) {
|
|
165734
|
+
const role = end.notation.role;
|
|
165735
|
+
edges.push({
|
|
165736
|
+
id: `e${eRef.n++}`,
|
|
165737
|
+
from: ports[ordinal].id,
|
|
165738
|
+
to: targetId,
|
|
165739
|
+
kind: "interface",
|
|
165740
|
+
name,
|
|
165741
|
+
type,
|
|
165742
|
+
isDef: false,
|
|
165743
|
+
endRoleFrom: role,
|
|
165744
|
+
endLabelFrom: end.notation.multiplicity,
|
|
165745
|
+
endAdornmentFrom: end.notation.adornment,
|
|
165746
|
+
source: relationship.source,
|
|
165747
|
+
meta: {
|
|
165748
|
+
...relationship.meta ?? {},
|
|
165749
|
+
interfaceUsageEnd: true,
|
|
165750
|
+
interfaceUsageId: usageId,
|
|
165751
|
+
connectionUsageId: usageId,
|
|
165752
|
+
connectionEndOrdinal: ordinal,
|
|
165753
|
+
...role ? { connectionEndRole: role } : {}
|
|
165754
|
+
}
|
|
165755
|
+
});
|
|
164904
165756
|
}
|
|
164905
165757
|
} else if (isConnectionDecl(m) && m.isDef !== true) {
|
|
164906
|
-
const
|
|
164907
|
-
|
|
165758
|
+
const name = effectiveNameOf(m);
|
|
165759
|
+
const inheritedType = this.inheritedFeatureOwnersOf(m, index2).filter((candidate) => isConnectionDecl(candidate) && candidate.isDef !== true).map(typeText).find((candidate) => !!candidate);
|
|
165760
|
+
const type = typeText(m) ?? inheritedType;
|
|
165761
|
+
const usageEnds = this.effectiveConnectionUsageEndsOf(m, index2);
|
|
165762
|
+
const usageId = connectionUsageNodeId(m);
|
|
165763
|
+
const usageSource = sourceOf2(m, uri);
|
|
165764
|
+
const relationship = relationshipFields(m);
|
|
165765
|
+
const resolvedUsageEnds = usageEnds.flatMap((end, ordinal) => {
|
|
165766
|
+
const targetId = end.path ? resolveEnd(end.path) : void 0;
|
|
165767
|
+
return targetId && supportsEndpoints("connect", [targetId]) ? [{ end, ordinal, targetId }] : [];
|
|
165768
|
+
});
|
|
165769
|
+
const inherited = relationship.meta?.ivInheritedRelation === true;
|
|
165770
|
+
const visibleUsageEnds = inherited ? resolvedUsageEnds.filter(({ end, targetId }) => this.connectionUsageEndBindingMatches(end, endpointProvenance.get(targetId), frameId ? endpointProvenance.get(frameId) : void 0, index2)) : resolvedUsageEnds;
|
|
165771
|
+
if (inherited && visibleUsageEnds.length === 0) {
|
|
164908
165772
|
continue;
|
|
164909
|
-
|
|
164910
|
-
const
|
|
164911
|
-
const
|
|
164912
|
-
|
|
164913
|
-
|
|
164914
|
-
|
|
164915
|
-
|
|
164916
|
-
|
|
164917
|
-
|
|
164918
|
-
|
|
164919
|
-
|
|
164920
|
-
|
|
164921
|
-
|
|
164922
|
-
|
|
164923
|
-
|
|
164924
|
-
|
|
164925
|
-
|
|
164926
|
-
|
|
164927
|
-
|
|
164928
|
-
|
|
164929
|
-
}
|
|
165773
|
+
}
|
|
165774
|
+
const resolvedOrdinals = new Set(visibleUsageEnds.map(({ ordinal }) => ordinal));
|
|
165775
|
+
const ownerNode = frameId ? nodes.find((node) => node.id === frameId) : void 0;
|
|
165776
|
+
const usageFrame = ownerNode ? ownerNode.frame : frameId;
|
|
165777
|
+
const ports = usageEnds.map((end, ordinal) => {
|
|
165778
|
+
const role = end.notation.role;
|
|
165779
|
+
const direction = end.notation.direction === "in" || end.notation.direction === "out" || end.notation.direction === "inout" ? end.notation.direction : void 0;
|
|
165780
|
+
return {
|
|
165781
|
+
id: `${usageId}::__end_${ordinal}`,
|
|
165782
|
+
name: role ?? `end${ordinal + 1}`,
|
|
165783
|
+
type: end.notation.type,
|
|
165784
|
+
direction,
|
|
165785
|
+
isDef: false,
|
|
165786
|
+
pin: true,
|
|
165787
|
+
source: usageSource,
|
|
165788
|
+
meta: {
|
|
165789
|
+
connectionEndPin: true,
|
|
165790
|
+
connectionUsageId: usageId,
|
|
165791
|
+
connectionEndOrdinal: ordinal,
|
|
165792
|
+
...role ? { connectionEndRole: role } : {},
|
|
165793
|
+
...resolvedOrdinals.has(ordinal) ? { connectionEndBound: true } : {},
|
|
165794
|
+
...end.notation.multiplicity ? { connectionEndMultiplicity: end.notation.multiplicity } : {},
|
|
165795
|
+
...end.notation.adornment ? { connectionEndAdornment: end.notation.adornment } : {}
|
|
164930
165796
|
}
|
|
165797
|
+
};
|
|
165798
|
+
});
|
|
165799
|
+
const carriedFlows = this.carriedFlowsOf(m, usageEnds, index2, uri);
|
|
165800
|
+
nodes.push({
|
|
165801
|
+
id: usageId,
|
|
165802
|
+
name: name ?? "connection",
|
|
165803
|
+
keyword: "connection",
|
|
165804
|
+
isDef: false,
|
|
165805
|
+
shape: "box",
|
|
165806
|
+
type,
|
|
165807
|
+
ports,
|
|
165808
|
+
...usageFrame ? { frame: usageFrame } : {},
|
|
165809
|
+
compartments: this.withCarriedFlowRows(this.compartmentsFor(m, uri, index2), carriedFlows),
|
|
165810
|
+
source: usageSource,
|
|
165811
|
+
meta: {
|
|
165812
|
+
...relationship.meta ?? {},
|
|
165813
|
+
connectionUsage: true,
|
|
165814
|
+
...name ? { explicitRelationshipName: name } : {},
|
|
165815
|
+
...flowDecorationMeta(carriedFlows)
|
|
164931
165816
|
}
|
|
164932
|
-
}
|
|
164933
|
-
|
|
164934
|
-
const
|
|
164935
|
-
|
|
164936
|
-
|
|
164937
|
-
|
|
164938
|
-
|
|
164939
|
-
|
|
164940
|
-
|
|
164941
|
-
|
|
164942
|
-
|
|
164943
|
-
|
|
165817
|
+
});
|
|
165818
|
+
for (const { end, ordinal, targetId } of visibleUsageEnds) {
|
|
165819
|
+
const role = end.notation.role;
|
|
165820
|
+
edges.push({
|
|
165821
|
+
id: `e${eRef.n++}`,
|
|
165822
|
+
from: ports[ordinal].id,
|
|
165823
|
+
to: targetId,
|
|
165824
|
+
kind: "connect",
|
|
165825
|
+
name,
|
|
165826
|
+
type,
|
|
165827
|
+
isDef: false,
|
|
165828
|
+
endRoleFrom: role,
|
|
165829
|
+
endLabelFrom: end.notation.multiplicity,
|
|
165830
|
+
endAdornmentFrom: end.notation.adornment,
|
|
165831
|
+
source: relationship.source,
|
|
165832
|
+
meta: {
|
|
165833
|
+
...relationship.meta ?? {},
|
|
165834
|
+
connectionUsageEnd: true,
|
|
165835
|
+
connectionUsageId: usageId,
|
|
165836
|
+
connectionEndOrdinal: ordinal,
|
|
165837
|
+
...role ? { connectionEndRole: role } : {}
|
|
165838
|
+
}
|
|
165839
|
+
});
|
|
165840
|
+
}
|
|
165841
|
+
}
|
|
165842
|
+
}
|
|
165843
|
+
const resolveFlowEnd = (pathText) => {
|
|
165844
|
+
const direct = resolveEnd(pathText);
|
|
165845
|
+
if (direct)
|
|
165846
|
+
return { id: direct, docked: false };
|
|
165847
|
+
const parts2 = pathText.split(/(::|\.)/u).filter((part) => part.length > 0);
|
|
165848
|
+
for (let length2 = parts2.length - 2; length2 >= 1; length2 -= 2) {
|
|
165849
|
+
const carrier = resolveEnd(parts2.slice(0, length2).join(""));
|
|
165850
|
+
if (carrier)
|
|
165851
|
+
return { id: carrier, docked: true };
|
|
165852
|
+
}
|
|
165853
|
+
return void 0;
|
|
165854
|
+
};
|
|
165855
|
+
const transportFor = (from, to) => edges.slice(firstEdge).find((edge) => (edge.kind === "connect" || edge.kind === "interface") && (edge.from === from && edge.to === to || edge.from === to && edge.to === from));
|
|
165856
|
+
const flowUsageNodeId = (flow) => {
|
|
165857
|
+
const src = sourceOf2(flow, uri);
|
|
165858
|
+
const ownerId = frameId ?? (qnameOf(memberOwner ?? flow) || "iv");
|
|
165859
|
+
const suffix = (frameId ? flowStmtName(flow) : qnameOf(flow)) ?? (src ? `${src.range.start.line}_${src.range.start.character}` : `${eRef.n}`);
|
|
165860
|
+
return `${ownerId}::__flow_${suffix}`;
|
|
165861
|
+
};
|
|
165862
|
+
for (const m of pendingFlows) {
|
|
165863
|
+
const fm = m;
|
|
165864
|
+
const message = fm.flowKind === "message";
|
|
165865
|
+
const keyword = flowKeyword(fm);
|
|
165866
|
+
const { source, target } = this.flowStmtEnds(fm);
|
|
165867
|
+
const flowName = flowStmtName(m);
|
|
165868
|
+
const sourceEnd = message ? void 0 : resolveFlowEnd(source ?? "");
|
|
165869
|
+
const targetEnd = message ? void 0 : resolveFlowEnd(target ?? "");
|
|
165870
|
+
const selfDock = sourceEnd !== void 0 && sourceEnd.id === targetEnd?.id && (sourceEnd.docked || targetEnd.docked);
|
|
165871
|
+
const from = selfDock ? void 0 : sourceEnd?.id;
|
|
165872
|
+
const to = selfDock ? void 0 : targetEnd?.id;
|
|
165873
|
+
const transferred = flowTransferredFeature({ source, target });
|
|
165874
|
+
const label = this.flowPayloadText(fm) ?? typeText(m) ?? transferred ?? flowName;
|
|
165875
|
+
if (from && to && supportsEndpoints("flow", [from, to])) {
|
|
165876
|
+
const transport = transportFor(from, to);
|
|
165877
|
+
if (transport) {
|
|
165878
|
+
const decorations = Array.isArray(transport.meta?.flowDecorations) ? transport.meta.flowDecorations : [];
|
|
165879
|
+
transport.meta = {
|
|
165880
|
+
...transport.meta ?? {},
|
|
165881
|
+
flowDecorations: [...decorations, {
|
|
165882
|
+
keyword,
|
|
164944
165883
|
label,
|
|
164945
|
-
|
|
164946
|
-
|
|
164947
|
-
|
|
164948
|
-
}
|
|
164949
|
-
}
|
|
165884
|
+
...flowName ? { name: flowName } : {},
|
|
165885
|
+
reversed: transport.from === to,
|
|
165886
|
+
source: sourceOf2(m, uri)
|
|
165887
|
+
}]
|
|
165888
|
+
};
|
|
165889
|
+
continue;
|
|
164950
165890
|
}
|
|
165891
|
+
edges.push({
|
|
165892
|
+
id: `e${eRef.n++}`,
|
|
165893
|
+
from,
|
|
165894
|
+
to,
|
|
165895
|
+
kind: "flow",
|
|
165896
|
+
label,
|
|
165897
|
+
...relationshipFields(m)
|
|
165898
|
+
});
|
|
165899
|
+
continue;
|
|
164951
165900
|
}
|
|
165901
|
+
if (message || !flowName)
|
|
165902
|
+
continue;
|
|
165903
|
+
const ownerNode = frameId ? nodes.find((node) => node.id === frameId) : void 0;
|
|
165904
|
+
const ends = [
|
|
165905
|
+
...source ? [{ text: `from ${source}` }] : [],
|
|
165906
|
+
...target ? [{ text: `to ${target}` }] : []
|
|
165907
|
+
];
|
|
165908
|
+
nodes.push({
|
|
165909
|
+
id: flowUsageNodeId(m),
|
|
165910
|
+
name: flowName,
|
|
165911
|
+
keyword,
|
|
165912
|
+
isDef: false,
|
|
165913
|
+
shape: "box",
|
|
165914
|
+
type: typeText(m),
|
|
165915
|
+
multiplicity: multText(m),
|
|
165916
|
+
...ownerNode ? { frame: ownerNode.frame } : frameId ? { frame: frameId } : {},
|
|
165917
|
+
compartments: [
|
|
165918
|
+
...label ? [{ title: "payload", items: [{ text: label }] }] : [],
|
|
165919
|
+
...ends.length ? [{ title: "ends", items: ends }] : []
|
|
165920
|
+
],
|
|
165921
|
+
source: sourceOf2(m, uri),
|
|
165922
|
+
meta: {
|
|
165923
|
+
...relationshipFields(m).meta ?? {},
|
|
165924
|
+
flowUsage: true,
|
|
165925
|
+
explicitRelationshipName: flowName
|
|
165926
|
+
}
|
|
165927
|
+
});
|
|
164952
165928
|
}
|
|
164953
165929
|
}
|
|
164954
165930
|
// ── iv overview (REQ-360) — recursive nested Interconnection View over a
|
|
@@ -164997,9 +165973,11 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164997
165973
|
if (roots.length === 0) {
|
|
164998
165974
|
roots = all.filter((d) => isDefPart(d) && !insideAPart(d) && !insideAnOccurrence(d) && hasInternalParts(d)).sort(byName);
|
|
164999
165975
|
}
|
|
165000
|
-
const { nodes, edges, frames } = this.renderIvRoots(ctx, roots, { packageFrames: true });
|
|
165976
|
+
const { nodes, edges, frames, definitionLayer } = this.renderIvRoots(ctx, roots, { packageFrames: true });
|
|
165001
165977
|
const model = this.model("iv", scope, nodes, edges);
|
|
165002
165978
|
model.frames = frames;
|
|
165979
|
+
if (definitionLayer)
|
|
165980
|
+
model.layers = { definitions: definitionLayer };
|
|
165003
165981
|
model.meta = { ...model.meta, overview: true, groupMode: "nested" };
|
|
165004
165982
|
model.root = { ...model.root, keyword: "package", name: nameOf2(scope) ?? model.root.name };
|
|
165005
165983
|
if (nodes.length === 0 && frames.length === 0) {
|
|
@@ -165011,7 +165989,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
165011
165989
|
// (non-package) single view of `kind`; each renders as one overview tile.
|
|
165012
165990
|
collectOverviewAnchors(scope, kind, index2) {
|
|
165013
165991
|
const all = [...ast_utils_exports.streamAllContents(scope)];
|
|
165014
|
-
const isNaturalAnchor = (n2) => !isPackage(n2) && !isDocument(n2) && (this.hasAnchorContent(n2, kind, index2) || kind === "afv" && this.isAfvScaffoldAnchor(n2)) && (kind !== "sv" || this.hasSequenceInteraction(n2));
|
|
165992
|
+
const isNaturalAnchor = (n2) => !isPackage(n2) && !isDocument(n2) && ((kind === "gev" ? this.hasGeometryOverviewLayout(n2, index2) : this.hasAnchorContent(n2, kind, index2)) || kind === "afv" && this.isAfvScaffoldAnchor(n2)) && (kind !== "sv" || this.hasSequenceInteraction(n2));
|
|
165015
165993
|
const naturalAnchors = all.filter(isNaturalAnchor);
|
|
165016
165994
|
const hasNaturalDescendant = (candidate) => naturalAnchors.some((natural) => {
|
|
165017
165995
|
for (let cur = natural.$container; cur && cur !== scope; cur = cur.$container) {
|
|
@@ -165072,7 +166050,8 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
165072
166050
|
const scopeQ = qnameOf(ctx.anchor);
|
|
165073
166051
|
const collected = this.collectOverviewAnchors(ctx.anchor, kind, ctx.index).sort((a2, b) => (qnameOf(a2) || nameOf2(a2) || "").localeCompare(qnameOf(b) || nameOf2(b) || ""));
|
|
165074
166052
|
const sequenceScaffold = kind === "sv" && this.nestedUsages(ctx.anchor, isPartDecl).some((n2) => nameOf2(n2) !== void 0);
|
|
165075
|
-
const
|
|
166053
|
+
const useScopeFallback = kind === "gev" ? this.hasPlacedGeometryObject(ctx.anchor, ctx.index) : sequenceScaffold;
|
|
166054
|
+
const anchors = collected.length > 0 ? collected : useScopeFallback ? [ctx.anchor] : [];
|
|
165076
166055
|
const nodes = [];
|
|
165077
166056
|
const edges = [];
|
|
165078
166057
|
const frames = [];
|
|
@@ -166307,9 +167286,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
166307
167286
|
const to = resolvePin(ends.target, occurrenceContext);
|
|
166308
167287
|
if (from && to) {
|
|
166309
167288
|
const kind = fm.succession === true ? "successionFlow" : "flow";
|
|
166310
|
-
const
|
|
166311
|
-
const targetFeature = ends.target ? lastSeg(ends.target) : void 0;
|
|
166312
|
-
const transferredFeature = sourceFeature === targetFeature ? sourceFeature : sourceFeature ?? targetFeature;
|
|
167289
|
+
const transferredFeature = flowTransferredFeature(ends);
|
|
166313
167290
|
edges.push({
|
|
166314
167291
|
id: `e${e++}`,
|
|
166315
167292
|
from,
|
|
@@ -168024,18 +169001,31 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
168024
169001
|
geo.sizeZ = Math.abs(sizeZ);
|
|
168025
169002
|
if (radius !== void 0)
|
|
168026
169003
|
geo.radius = Math.abs(radius);
|
|
168027
|
-
const
|
|
168028
|
-
|
|
169004
|
+
const localYaw = local.rot === void 0 ? void 0 : rotationTransform([0, 0, 1], local.rot);
|
|
169005
|
+
const orientedWorld = localYaw ? composeTransforms(state.world, localYaw) : state.world;
|
|
169006
|
+
const yaw = yawOf(orientedWorld);
|
|
169007
|
+
if (!state.fromFrame && local.rot !== void 0)
|
|
168029
169008
|
geo.rot = local.rot;
|
|
168030
169009
|
else if (yaw !== void 0 && yaw !== 0)
|
|
168031
169010
|
geo.rot = yaw;
|
|
168032
|
-
|
|
168033
|
-
|
|
168034
|
-
|
|
169011
|
+
if (state.fromFrame && !isUnrotated(orientedWorld)) {
|
|
169012
|
+
const r = orientedWorld.r.map(roundGeo);
|
|
169013
|
+
geo.orientation = [
|
|
169014
|
+
r[0],
|
|
169015
|
+
r[1],
|
|
169016
|
+
r[2],
|
|
169017
|
+
r[3],
|
|
169018
|
+
r[4],
|
|
169019
|
+
r[5],
|
|
169020
|
+
r[6],
|
|
169021
|
+
r[7],
|
|
169022
|
+
r[8]
|
|
169023
|
+
];
|
|
169024
|
+
}
|
|
168035
169025
|
if (state.fromFrame)
|
|
168036
169026
|
geo.frame = true;
|
|
168037
|
-
if (approx)
|
|
168038
|
-
geo.approx = approx;
|
|
169027
|
+
if (state.approx)
|
|
169028
|
+
geo.approx = state.approx;
|
|
168039
169029
|
return geo;
|
|
168040
169030
|
}
|
|
168041
169031
|
// issue #107 — a node's OWN placement relative to its parent frame: the
|
|
@@ -168128,7 +169118,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
168128
169118
|
return {
|
|
168129
169119
|
present: true,
|
|
168130
169120
|
transform: translationTransform(origin),
|
|
168131
|
-
approx: reoriented ? "its frame declares basisDirections
|
|
169121
|
+
approx: reoriented ? "its frame declares basisDirections that this workspace cannot evaluate numerically" : void 0,
|
|
168132
169122
|
unit,
|
|
168133
169123
|
sourcePath
|
|
168134
169124
|
};
|
|
@@ -168685,9 +169675,10 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
168685
169675
|
portsOf(node, index2, uri, ownerId, localUsage) {
|
|
168686
169676
|
const ports = [];
|
|
168687
169677
|
const map3 = /* @__PURE__ */ new Map();
|
|
169678
|
+
const origins = /* @__PURE__ */ new Map();
|
|
168688
169679
|
const visibleNames = /* @__PURE__ */ new Set();
|
|
168689
169680
|
const usageName = effectiveNameOf(node);
|
|
168690
|
-
const makePort = (portNode, inheritedFromType, parentPortId, parentPath) => {
|
|
169681
|
+
const makePort = (portNode, inheritedFromType, parentPortId, parentPath, parentOrigin = []) => {
|
|
168691
169682
|
const pn = effectiveNameOf(portNode);
|
|
168692
169683
|
if (!pn)
|
|
168693
169684
|
return void 0;
|
|
@@ -168772,7 +169763,9 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
168772
169763
|
if (usageName)
|
|
168773
169764
|
map3.set(`${usageName}.${rel2}`, portId);
|
|
168774
169765
|
map3.set(`${ownerId}.${rel2}`, portId);
|
|
168775
|
-
|
|
169766
|
+
const origin = [...parentOrigin, portNode];
|
|
169767
|
+
origins.set(portId, origin);
|
|
169768
|
+
return { port, portTypeDef, inheritedOwners, origin };
|
|
168776
169769
|
};
|
|
168777
169770
|
const addNested = (portNode, made, inheritedFromType, path10, depth, seenTypes) => {
|
|
168778
169771
|
if (depth > NESTED_PORT_MAX_DEPTH)
|
|
@@ -168783,18 +169776,20 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
168783
169776
|
const nestedSeen = /* @__PURE__ */ new Set();
|
|
168784
169777
|
const nestedSources = [
|
|
168785
169778
|
// declared in this port usage's body: as local as its parent is
|
|
168786
|
-
...membersOf(portNode).map((member) => ({ member, inherited: inheritedFromType })),
|
|
169779
|
+
...membersOf(portNode).map((member) => ({ member, inherited: inheritedFromType, source: portNode })),
|
|
168787
169780
|
// every effective owner contributes its body, nearest first
|
|
168788
|
-
...!repeatedType ? made.inheritedOwners.flatMap((owner) => membersOf(owner).map((member) => ({ member, inherited: true }))) : []
|
|
169781
|
+
...!repeatedType ? made.inheritedOwners.flatMap((owner) => membersOf(owner).map((member) => ({ member, inherited: true, source: owner }))) : []
|
|
168789
169782
|
];
|
|
168790
|
-
for (const { member, inherited } of nestedSources) {
|
|
169783
|
+
for (const { member, inherited, source } of nestedSources) {
|
|
168791
169784
|
if (!isPortDecl(member) || member.isDef === true)
|
|
168792
169785
|
continue;
|
|
169786
|
+
if (inherited && this.isInheritedLibraryBackboneFeature(source, member, index2))
|
|
169787
|
+
continue;
|
|
168793
169788
|
const nn = effectiveNameOf(member);
|
|
168794
169789
|
if (!nn || nestedSeen.has(nn))
|
|
168795
169790
|
continue;
|
|
168796
169791
|
nestedSeen.add(nn);
|
|
168797
|
-
const child = makePort(member, inherited, made.port.id, path10);
|
|
169792
|
+
const child = makePort(member, inherited, made.port.id, path10, made.origin);
|
|
168798
169793
|
if (!child)
|
|
168799
169794
|
continue;
|
|
168800
169795
|
ports.push(child.port);
|
|
@@ -168816,11 +169811,12 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
168816
169811
|
if (isPortDecl(m) && m.isDef !== true)
|
|
168817
169812
|
addPort(m, false);
|
|
168818
169813
|
for (const inherited of this.inheritedFeatureOwnersOf(node, index2)) {
|
|
168819
|
-
for (const m of membersOf(inherited))
|
|
168820
|
-
if (isPortDecl(m) && m.isDef !== true)
|
|
169814
|
+
for (const m of membersOf(inherited)) {
|
|
169815
|
+
if (isPortDecl(m) && m.isDef !== true && !this.isInheritedLibraryBackboneFeature(inherited, m, index2))
|
|
168821
169816
|
addPort(m, true);
|
|
169817
|
+
}
|
|
168822
169818
|
}
|
|
168823
|
-
return { ports, map: map3 };
|
|
169819
|
+
return { ports, map: map3, origins };
|
|
168824
169820
|
}
|
|
168825
169821
|
// REQ-100, issue #132 — the effective directions of a port type's directed
|
|
168826
169822
|
// features, following the specialization chain and flipping `in`↔`out` across
|
|
@@ -168986,7 +169982,9 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
168986
169982
|
add("ports", usages(isPortDecl).map((m) => item(m)));
|
|
168987
169983
|
add("parts", usages(isPartDecl).filter(notPortion).map((m) => item(m)));
|
|
168988
169984
|
}
|
|
169985
|
+
add("connections", members.filter((member) => isConnectionDecl(member) && member.isDef !== true && isOrdinaryMember(member)).map((member) => item(member, this.featureText(member) || "(anonymous connection)")));
|
|
168989
169986
|
add("interfaces", members.filter((m) => isInterfaceDecl(m) && m.isDef !== true && isOrdinaryMember(m)).map((m) => item(m, this.interfaceRowText(m))));
|
|
169987
|
+
add("flows", members.filter((m) => m.$type === "FlowStmt" && m.isDef !== true && isOrdinaryMember(m)).map((m) => item(m, this.flowRowText(m))));
|
|
168990
169988
|
add("features", members.filter((m) => m.$type === "FeatureShorthand" || m.$type === "FeatureRedefinitionShorthand").filter(isOrdinaryMember).filter((m) => !isOccurrenceModified(m)).map((m) => item(m, canonicalFeatureText(m))));
|
|
168991
169989
|
const undirected = (guard) => usages(guard);
|
|
168992
169990
|
add("items", undirected(isItemDecl).filter(notPortion).map((m) => item(m)));
|
|
@@ -169101,25 +170099,6 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
169101
170099
|
return ends;
|
|
169102
170100
|
return [head2, ends].filter(Boolean).join(" ");
|
|
169103
170101
|
}
|
|
169104
|
-
// REQ-195 — Interface and binding guidance (usage-node fallback body)
|
|
169105
|
-
// issue #110 — the body of the `«interface»` usage node the IV draws when the
|
|
169106
|
-
// connect ends do not dock on the canvas. The written end paths ARE the
|
|
169107
|
-
// information the missing edge would have carried, so they read as the node's
|
|
169108
|
-
// `ends` compartment (OMG SysML 8.2.3.14), after any end members it declares.
|
|
169109
|
-
interfaceFallbackCompartments(node, uri, index2) {
|
|
169110
|
-
const clause = node.connect;
|
|
169111
|
-
const paths = clause?.ends?.length ? clause.ends.map((end) => this.connectorEndPath(end) ?? "?") : clause ? [this.connectorEndPath(clause.source) ?? "?", this.connectorEndPath(clause.target) ?? "?"] : [];
|
|
169112
|
-
const compartments = [...this.compartmentsFor(node, uri, index2) ?? []];
|
|
169113
|
-
if (!paths.length)
|
|
169114
|
-
return compartments.length ? compartments : void 0;
|
|
169115
|
-
const items = paths.map((text) => ({ text }));
|
|
169116
|
-
const existing = compartments.find((compartment) => compartment.title === "ends");
|
|
169117
|
-
if (existing)
|
|
169118
|
-
existing.items = [...existing.items, ...items];
|
|
169119
|
-
else
|
|
169120
|
-
compartments.push({ title: "ends", items });
|
|
169121
|
-
return compartments;
|
|
169122
|
-
}
|
|
169123
170102
|
refText(v) {
|
|
169124
170103
|
if (typeof v === "string")
|
|
169125
170104
|
return v;
|
|
@@ -169642,91 +170621,6 @@ function outlineGroupForType(astType) {
|
|
|
169642
170621
|
return CATEGORY_TO_OUTLINE_GROUP[categoryForType(astType)] ?? "structure";
|
|
169643
170622
|
}
|
|
169644
170623
|
|
|
169645
|
-
// ../language-server/out/src/platform/platform.js
|
|
169646
|
-
var current;
|
|
169647
|
-
function setPlatform(platform) {
|
|
169648
|
-
current = platform;
|
|
169649
|
-
}
|
|
169650
|
-
function getPlatform() {
|
|
169651
|
-
if (!current)
|
|
169652
|
-
throw new Error("SysML: no platform installed - the entry point must call setPlatform() first.");
|
|
169653
|
-
return current;
|
|
169654
|
-
}
|
|
169655
|
-
function hasPlatform() {
|
|
169656
|
-
return current !== void 0;
|
|
169657
|
-
}
|
|
169658
|
-
|
|
169659
|
-
// ../language-server/out/src/services/library-index-manager.js
|
|
169660
|
-
var SysmlIndexManager = class extends DefaultIndexManager {
|
|
169661
|
-
constructor(services) {
|
|
169662
|
-
super(services);
|
|
169663
|
-
}
|
|
169664
|
-
// REQ-075, REQ-383 — `libraryRoot` is a URI and the concrete file URIs come
|
|
169665
|
-
// from the platform, because the two hosts index the same library under
|
|
169666
|
-
// different schemes (`file:` on the desktop, `sysml-lib:` in a worker).
|
|
169667
|
-
loadPrecomputedLibraryIndex(index2, libraryRoot) {
|
|
169668
|
-
const platform = getPlatform();
|
|
169669
|
-
let symbolCount = 0;
|
|
169670
|
-
for (const file of index2.files) {
|
|
169671
|
-
const documentUri = platform.libraryUri(libraryRoot, file.path);
|
|
169672
|
-
const descriptions = file.symbols.map((symbol) => this.deserializeSymbol(symbol, documentUri));
|
|
169673
|
-
const uri = documentUri.toString();
|
|
169674
|
-
this.symbolIndex.set(uri, descriptions);
|
|
169675
|
-
this.symbolByTypeIndex.clear(uri);
|
|
169676
|
-
symbolCount += descriptions.length;
|
|
169677
|
-
}
|
|
169678
|
-
return symbolCount;
|
|
169679
|
-
}
|
|
169680
|
-
deserializeSymbol(symbol, documentUri) {
|
|
169681
|
-
return {
|
|
169682
|
-
name: symbol.name,
|
|
169683
|
-
type: symbol.type,
|
|
169684
|
-
path: symbol.path,
|
|
169685
|
-
documentUri,
|
|
169686
|
-
nameSegment: symbol.nameSegment,
|
|
169687
|
-
selectionSegment: symbol.selectionSegment,
|
|
169688
|
-
// REQ-068 — preserve declared visibility for wildcard re-export.
|
|
169689
|
-
...symbol.isPrivate ? { isPrivate: true } : {},
|
|
169690
|
-
...symbol.visibility ? { visibility: symbol.visibility } : {},
|
|
169691
|
-
// issue #152 — a re-exported alias is not owned nesting.
|
|
169692
|
-
...symbol.derivedKind ? { derivedKind: symbol.derivedKind } : {},
|
|
169693
|
-
// REQ-242 — issue #103 — keeps type completion to definitions.
|
|
169694
|
-
...symbol.isUsage ? { isUsage: true } : {}
|
|
169695
|
-
};
|
|
169696
|
-
}
|
|
169697
|
-
};
|
|
169698
|
-
function isSysmlIndexManager(value) {
|
|
169699
|
-
return typeof value.loadPrecomputedLibraryIndex === "function";
|
|
169700
|
-
}
|
|
169701
|
-
var libraryRoots = /* @__PURE__ */ new Set();
|
|
169702
|
-
var ROOT_SEPARATOR = "\0";
|
|
169703
|
-
function normalizeLibraryPath(p) {
|
|
169704
|
-
return p.replace(/\\/gu, "/").replace(/\/+$/u, "").toLowerCase();
|
|
169705
|
-
}
|
|
169706
|
-
function registerLibraryRoot(root4) {
|
|
169707
|
-
const uri = typeof root4 === "string" ? root4.length > 0 ? URI2.file(root4) : void 0 : root4;
|
|
169708
|
-
if (!uri)
|
|
169709
|
-
return;
|
|
169710
|
-
libraryRoots.add(`${uri.scheme}${ROOT_SEPARATOR}${normalizeLibraryPath(uri.path)}`);
|
|
169711
|
-
}
|
|
169712
|
-
function isInsideDir(fsPath, dir) {
|
|
169713
|
-
return fsPath === dir || fsPath.startsWith(`${dir}/`);
|
|
169714
|
-
}
|
|
169715
|
-
function isStandardLibraryUri(uri) {
|
|
169716
|
-
const fsPath = normalizeLibraryPath(uri.path);
|
|
169717
|
-
for (const entry of libraryRoots) {
|
|
169718
|
-
const separator = entry.indexOf(ROOT_SEPARATOR);
|
|
169719
|
-
if (entry.slice(0, separator) !== uri.scheme)
|
|
169720
|
-
continue;
|
|
169721
|
-
if (isInsideDir(fsPath, entry.slice(separator + 1)))
|
|
169722
|
-
return true;
|
|
169723
|
-
}
|
|
169724
|
-
return fsPath.split("/").some((segment) => segment === "sysml.library");
|
|
169725
|
-
}
|
|
169726
|
-
function isLibraryDocument(doc) {
|
|
169727
|
-
return doc.isLibraryDocument === true || isStandardLibraryUri(doc.uri);
|
|
169728
|
-
}
|
|
169729
|
-
|
|
169730
170624
|
// ../language-server/out/src/services/document-symbol-provider.js
|
|
169731
170625
|
var SPECIALIZATION_KINDS2 = /* @__PURE__ */ new Set([":>", "specializes"]);
|
|
169732
170626
|
var REDEFINITION_KINDS = /* @__PURE__ */ new Set([":>>", "redefines"]);
|
|
@@ -176575,7 +177469,7 @@ ${baseIndent}}`;
|
|
|
176575
177469
|
return;
|
|
176576
177470
|
const expected = interfaceEndTypes(definition);
|
|
176577
177471
|
const connect = decl.connect;
|
|
176578
|
-
const written = [connect?.source, connect?.target];
|
|
177472
|
+
const written = connect?.ends?.length ? connect.ends : [connect?.source, connect?.target];
|
|
176579
177473
|
if (expected.length !== written.length)
|
|
176580
177474
|
return;
|
|
176581
177475
|
for (let position = 0; position < written.length; position += 1) {
|
|
@@ -182522,7 +183416,9 @@ var PORT_GLYPH_SIZE = 20;
|
|
|
182522
183416
|
var PORT_GLYPH_HALF = PORT_GLYPH_SIZE / 2;
|
|
182523
183417
|
var FEATURE_COMPARTMENT_CLEARANCE = PORT_GLYPH_HALF + 12;
|
|
182524
183418
|
var ACTION_PIN_GLYPH_SIZE = PORT_GLYPH_SIZE;
|
|
183419
|
+
var CONNECTION_END_GLYPH_SIZE = 12;
|
|
182525
183420
|
function endpointGlyphSize(endpoint) {
|
|
183421
|
+
if (endpoint.meta?.connectionEndPin === true) return CONNECTION_END_GLYPH_SIZE;
|
|
182526
183422
|
return endpoint.pin ? ACTION_PIN_GLYPH_SIZE : PORT_GLYPH_SIZE;
|
|
182527
183423
|
}
|
|
182528
183424
|
var NESTED_PORT_GAP = 8;
|
|
@@ -182643,9 +183539,9 @@ function portDockSides(side) {
|
|
|
182643
183539
|
}
|
|
182644
183540
|
var PORT_MOVE_STRIP_ALONG = 24;
|
|
182645
183541
|
var PORT_CONNECT_DOT_HIT = 10;
|
|
182646
|
-
function portInteractionStrip(rect, side) {
|
|
183542
|
+
function portInteractionStrip(rect, side, singleOutwardHandle = false) {
|
|
182647
183543
|
const vertical = side === "left" || side === "right";
|
|
182648
|
-
const across = Math.max(1, rect.across - PORT_CONNECT_DOT_HIT);
|
|
183544
|
+
const across = singleOutwardHandle ? rect.across : Math.max(1, rect.across - PORT_CONNECT_DOT_HIT);
|
|
182649
183545
|
const run = Math.max(PORT_MOVE_STRIP_ALONG, rect.along);
|
|
182650
183546
|
return {
|
|
182651
183547
|
cx: rect.cx,
|
|
@@ -182731,6 +183627,10 @@ function sideLength(side, w, h, topReserve = 0) {
|
|
|
182731
183627
|
}
|
|
182732
183628
|
var SENDACCEPT_NOTCH = 14;
|
|
182733
183629
|
var CIRCULAR_CONTROL_RADII = {
|
|
183630
|
+
// REQ-192 - the n-ary connection hub is the same kind of fixed circular
|
|
183631
|
+
// canvas control as an AFV start node. Its wrapper, handles, saved size,
|
|
183632
|
+
// and painted outline therefore share one exact radius.
|
|
183633
|
+
dot: CONNECTION_END_GLYPH_SIZE / 2,
|
|
182734
183634
|
initial: 6,
|
|
182735
183635
|
final: 8,
|
|
182736
183636
|
terminate: 8
|
|
@@ -182954,6 +183854,15 @@ function gvModeEdges(model, mode) {
|
|
|
182954
183854
|
function isGvUsageNode(n2) {
|
|
182955
183855
|
return n2.meta?.gvUsage === true;
|
|
182956
183856
|
}
|
|
183857
|
+
function isConnectionDefinitionHub(n2) {
|
|
183858
|
+
return n2.meta?.connectionDefinitionHub === true;
|
|
183859
|
+
}
|
|
183860
|
+
function isGraphicalConnectionDefinitionCard(n2) {
|
|
183861
|
+
return n2.meta?.connectionDefinitionGraphical === true && n2.meta?.connectionDefinitionHub !== true && n2.meta?.connectionDefinitionElaboration !== true;
|
|
183862
|
+
}
|
|
183863
|
+
function isGraphicalConnectionDefinitionEdge(edge) {
|
|
183864
|
+
return edge.meta?.connectionDefinitionGraphical === true;
|
|
183865
|
+
}
|
|
182957
183866
|
var GV_BOXED_USAGE_COMPARTMENTS = /* @__PURE__ */ new Set(["parts", "occurrences", "timeslices", "snapshots", "individuals"]);
|
|
182958
183867
|
function stripBoxedUsageCompartments(nodes) {
|
|
182959
183868
|
let changed = false;
|
|
@@ -182970,11 +183879,16 @@ function applyGvMode(model, mode) {
|
|
|
182970
183879
|
if (model.kind !== "gv") return model;
|
|
182971
183880
|
const edges = gvModeEdges(model, mode);
|
|
182972
183881
|
if (mode === "group") {
|
|
182973
|
-
const nodes2 = model.nodes.filter((n2) => !isGvUsageNode(n2));
|
|
183882
|
+
const nodes2 = model.nodes.filter((n2) => !isGvUsageNode(n2) && !isConnectionDefinitionHub(n2));
|
|
182974
183883
|
return { ...model, nodes: nodes2, edges };
|
|
182975
183884
|
}
|
|
182976
|
-
const
|
|
182977
|
-
|
|
183885
|
+
const cardIsVisible = (node) => !isGraphicalConnectionDefinitionCard(node);
|
|
183886
|
+
const graphicalNodes = model.nodes.every(cardIsVisible) ? model.nodes : model.nodes.filter(cardIsVisible);
|
|
183887
|
+
const nodes = stripBoxedUsageCompartments(graphicalNodes);
|
|
183888
|
+
const nodeIds = new Set(nodes.map((node) => node.id));
|
|
183889
|
+
const edgeIsVisible = (edge) => nodeIds.has(edge.from) && nodeIds.has(edge.to);
|
|
183890
|
+
const visibleEdges = edges.every(edgeIsVisible) ? edges : edges.filter(edgeIsVisible);
|
|
183891
|
+
return nodes === model.nodes && visibleEdges === model.edges ? model : { ...model, nodes, edges: visibleEdges };
|
|
182978
183892
|
}
|
|
182979
183893
|
var GV_CATEGORIES = [
|
|
182980
183894
|
{ key: "package", label: "Packages" },
|
|
@@ -182994,6 +183908,7 @@ var GV_CATEGORIES = [
|
|
|
182994
183908
|
];
|
|
182995
183909
|
function gvNodeCategory(node) {
|
|
182996
183910
|
if (node.shape === "package") return "package";
|
|
183911
|
+
if (isConnectionDefinitionHub(node)) return "interface";
|
|
182997
183912
|
if (node.shape === "annotation" || node.shape === "dot") return "annotation";
|
|
182998
183913
|
const k = node.keyword.toLowerCase().trim().replace(/^(individual|timeslice|snapshot|parallel|variation|variant|abstract|ref|derived)(\s+|$)/g, "").replace(/\s+def$/, "").trim();
|
|
182999
183914
|
if (k === "" || k === "def") return "item";
|
|
@@ -183035,13 +183950,13 @@ function withoutOrphanedAnnotations(original, nodes, edges) {
|
|
|
183035
183950
|
function applyGvFilters(model, hidden) {
|
|
183036
183951
|
if (model.kind !== "gv" || hidden.size === 0) return model;
|
|
183037
183952
|
const nodes = model.nodes.filter((n2) => n2.shape === "package" || !hidden.has(gvNodeCategory(n2)));
|
|
183038
|
-
if (nodes.length === model.nodes.length) return model;
|
|
183039
183953
|
const keptIds = /* @__PURE__ */ new Set();
|
|
183040
183954
|
for (const n2 of nodes) {
|
|
183041
183955
|
keptIds.add(n2.id);
|
|
183042
183956
|
for (const p of n2.ports ?? []) keptIds.add(p.id);
|
|
183043
183957
|
}
|
|
183044
|
-
const edges = model.edges.filter((e) => keptIds.has(e.from) && keptIds.has(e.to));
|
|
183958
|
+
const edges = model.edges.filter((e) => !(hidden.has("interface") && isGraphicalConnectionDefinitionEdge(e)) && keptIds.has(e.from) && keptIds.has(e.to));
|
|
183959
|
+
if (nodes.length === model.nodes.length && edges.length === model.edges.length) return model;
|
|
183045
183960
|
return { ...model, nodes: withoutOrphanedAnnotations(model, nodes, edges), edges };
|
|
183046
183961
|
}
|
|
183047
183962
|
var PAD = 10;
|
|
@@ -183127,6 +184042,13 @@ function compartmentWidth(node) {
|
|
|
183127
184042
|
return w;
|
|
183128
184043
|
}
|
|
183129
184044
|
function nodeForCanvas(node) {
|
|
184045
|
+
if (node.meta?.connectionUsage === true || node.meta?.interfaceUsage === true) {
|
|
184046
|
+
const compartments2 = node.compartments?.filter((compartment) => compartment.title === "doc" || compartment.title === "flows");
|
|
184047
|
+
return {
|
|
184048
|
+
...node,
|
|
184049
|
+
compartments: compartments2?.length ? compartments2 : void 0
|
|
184050
|
+
};
|
|
184051
|
+
}
|
|
183130
184052
|
if (!/\bconstraint(?:\s+def)?$/u.test(node.keyword.trim().toLowerCase())) return node;
|
|
183131
184053
|
const compartments = node.compartments?.filter((compartment) => compartment.title !== "expression");
|
|
183132
184054
|
return {
|
|
@@ -183164,13 +184086,12 @@ function nodeSize(node, direction) {
|
|
|
183164
184086
|
// connector attaching at the node edge meets the visible circle.
|
|
183165
184087
|
case "initial":
|
|
183166
184088
|
case "final":
|
|
184089
|
+
case "dot":
|
|
183167
184090
|
return circularControlSize(node.shape);
|
|
183168
184091
|
// OMG SysML v2.1 Part 1, Table 15: the terminate control node is an
|
|
183169
184092
|
// unlabeled circled X, regardless of its optional semantic target.
|
|
183170
184093
|
case "terminate":
|
|
183171
184094
|
return circularControlSize(node.shape);
|
|
183172
|
-
case "dot":
|
|
183173
|
-
return { w: 14, h: 14 };
|
|
183174
184095
|
case "decision":
|
|
183175
184096
|
case "merge":
|
|
183176
184097
|
return { w: Math.max(64, Math.ceil((twKind(node.name) + 8) / 0.7)), h: 48 };
|
|
@@ -183210,9 +184131,10 @@ function nodeSize(node, direction) {
|
|
|
183210
184131
|
);
|
|
183211
184132
|
const featureH = nodeFeatureCompartmentReserve(node);
|
|
183212
184133
|
const compactContainer = node.meta?.internalsHidden === true;
|
|
183213
|
-
const
|
|
184134
|
+
const connectionUsage = node.meta?.connectionUsage === true || node.meta?.interfaceUsage === true;
|
|
184135
|
+
const portRunHeight = connectionUsage ? portRows ? portRows * 18 + 6 : 0 : portRows ? compactContainer ? portRows * 24 + 8 : 40 + portRows * 24 + 8 : 0;
|
|
183214
184136
|
const bodyH = Math.max(
|
|
183215
|
-
BOX_H,
|
|
184137
|
+
connectionUsage ? 42 : BOX_H,
|
|
183216
184138
|
featureH === 0 ? NODE_COMPARTMENT_TOP + compartmentHeight(node) : 0,
|
|
183217
184139
|
portRunHeight,
|
|
183218
184140
|
portedSideLength(ph, "left"),
|
|
@@ -183437,6 +184359,18 @@ function assignPortHandles(ports, overrides, ownerShape) {
|
|
|
183437
184359
|
for (const parent of topHandles) placeChildren(parent);
|
|
183438
184360
|
return [...topHandles, ...nestedHandles];
|
|
183439
184361
|
}
|
|
184362
|
+
var CONNECTION_BLOCK_GEOMETRY_VERSION = 2;
|
|
184363
|
+
function connectionUsageHeightOverride(node, height, connectionBlockVersion) {
|
|
184364
|
+
if (height === void 0 || node?.meta?.connectionUsage !== true) return height;
|
|
184365
|
+
if ((connectionBlockVersion ?? 0) >= CONNECTION_BLOCK_GEOMETRY_VERSION) return height;
|
|
184366
|
+
const handles = assignPortHandles(node.ports, void 0, node.shape);
|
|
184367
|
+
const rows = Math.max(
|
|
184368
|
+
handles.filter((handle) => handle.side === "left").length,
|
|
184369
|
+
handles.filter((handle) => handle.side === "right").length
|
|
184370
|
+
);
|
|
184371
|
+
const oldAutomaticHeight = Math.max(BOX_H, rows ? rows * 24 + 48 : 0);
|
|
184372
|
+
return height === oldAutomaticHeight ? void 0 : height;
|
|
184373
|
+
}
|
|
183440
184374
|
function sizeWithOverride(base, o, minimum = { w: 48, h: 24 }) {
|
|
183441
184375
|
return {
|
|
183442
184376
|
w: o?.w !== void 0 ? Math.max(minimum.w, o.w) : base.w,
|
|
@@ -183553,11 +184487,38 @@ function applyCaseDefs(model, show) {
|
|
|
183553
184487
|
};
|
|
183554
184488
|
}
|
|
183555
184489
|
var BEHAVIOR_FILTER_DEFAULTS = {
|
|
183556
|
-
afv: {
|
|
183557
|
-
|
|
184490
|
+
afv: {
|
|
184491
|
+
parts: true,
|
|
184492
|
+
performers: true,
|
|
184493
|
+
ports: true,
|
|
184494
|
+
defs: true,
|
|
184495
|
+
definedBy: true,
|
|
184496
|
+
actions: true,
|
|
184497
|
+
connectionBoxes: true,
|
|
184498
|
+
interfaceBoxes: true
|
|
184499
|
+
},
|
|
184500
|
+
stv: {
|
|
184501
|
+
parts: false,
|
|
184502
|
+
performers: true,
|
|
184503
|
+
ports: true,
|
|
184504
|
+
defs: true,
|
|
184505
|
+
definedBy: true,
|
|
184506
|
+
actions: true,
|
|
184507
|
+
connectionBoxes: true,
|
|
184508
|
+
interfaceBoxes: true
|
|
184509
|
+
},
|
|
183558
184510
|
// The Interconnection View is a STRUCTURE view; explicitly performed actions
|
|
183559
184511
|
// are an optional behavior overlay and therefore the first layer to drop.
|
|
183560
|
-
iv: {
|
|
184512
|
+
iv: {
|
|
184513
|
+
parts: true,
|
|
184514
|
+
performers: true,
|
|
184515
|
+
ports: true,
|
|
184516
|
+
defs: true,
|
|
184517
|
+
definedBy: true,
|
|
184518
|
+
actions: true,
|
|
184519
|
+
connectionBoxes: true,
|
|
184520
|
+
interfaceBoxes: true
|
|
184521
|
+
}
|
|
183561
184522
|
};
|
|
183562
184523
|
function behaviorFilterDefaults(kind) {
|
|
183563
184524
|
return BEHAVIOR_FILTER_DEFAULTS[kind === "stv" ? "stv" : kind === "iv" ? "iv" : "afv"];
|
|
@@ -183570,9 +184531,164 @@ function restoreBehaviorFilters(kind, saved) {
|
|
|
183570
184531
|
return restored;
|
|
183571
184532
|
}
|
|
183572
184533
|
var FILTERED_KINDS = /* @__PURE__ */ new Set(["afv", "stv", "iv"]);
|
|
184534
|
+
function withVisibleDefinitionLayer(model) {
|
|
184535
|
+
const layer = model.layers?.definitions;
|
|
184536
|
+
if (!layer) return model;
|
|
184537
|
+
return {
|
|
184538
|
+
...model,
|
|
184539
|
+
nodes: [...model.nodes, ...layer.nodes],
|
|
184540
|
+
edges: [...model.edges, ...layer.edges],
|
|
184541
|
+
frames: [...model.frames ?? [], ...layer.frames ?? []],
|
|
184542
|
+
layers: void 0
|
|
184543
|
+
};
|
|
184544
|
+
}
|
|
184545
|
+
function explicitRelationshipBindings(usage, model) {
|
|
184546
|
+
return (usage.ports ?? []).flatMap((port, fallbackOrdinal) => {
|
|
184547
|
+
const edge = model.edges.find((candidate) => candidate.from === port.id || candidate.to === port.id);
|
|
184548
|
+
if (!edge) return [];
|
|
184549
|
+
const pinAtFrom = edge.from === port.id;
|
|
184550
|
+
const ordinal = typeof port.meta?.connectionEndOrdinal === "number" ? port.meta.connectionEndOrdinal : fallbackOrdinal;
|
|
184551
|
+
const role = typeof port.meta?.connectionEndRole === "string" ? port.meta.connectionEndRole : pinAtFrom ? edge.endRoleFrom : edge.endRoleTo;
|
|
184552
|
+
return [{
|
|
184553
|
+
edge,
|
|
184554
|
+
externalId: pinAtFrom ? edge.to : edge.from,
|
|
184555
|
+
ordinal,
|
|
184556
|
+
role,
|
|
184557
|
+
multiplicity: pinAtFrom ? edge.endLabelFrom : edge.endLabelTo,
|
|
184558
|
+
adornment: pinAtFrom ? edge.endAdornmentFrom : edge.endAdornmentTo
|
|
184559
|
+
}];
|
|
184560
|
+
}).sort((left, right) => left.ordinal - right.ordinal);
|
|
184561
|
+
}
|
|
184562
|
+
function hideExplicitRelationshipBoxes(model, relationship) {
|
|
184563
|
+
if (model.kind !== "iv") return model;
|
|
184564
|
+
const usages = model.nodes.filter((node) => relationship === "connection" ? node.meta?.connectionUsage === true : node.meta?.interfaceUsage === true);
|
|
184565
|
+
if (usages.length === 0) return model;
|
|
184566
|
+
const usageIds = new Set(usages.map((usage) => usage.id));
|
|
184567
|
+
const annotatedUsageIds = /* @__PURE__ */ new Set();
|
|
184568
|
+
for (const edge of model.edges) {
|
|
184569
|
+
if (edge.kind !== "annotation") continue;
|
|
184570
|
+
if (usageIds.has(edge.from)) annotatedUsageIds.add(edge.from);
|
|
184571
|
+
if (usageIds.has(edge.to)) annotatedUsageIds.add(edge.to);
|
|
184572
|
+
}
|
|
184573
|
+
const projections = usages.map((usage) => ({
|
|
184574
|
+
usage,
|
|
184575
|
+
bindings: explicitRelationshipBindings(usage, model),
|
|
184576
|
+
endCount: usage.ports?.length ?? 0
|
|
184577
|
+
}));
|
|
184578
|
+
const blocksCompaction = ({ usage, endCount }) => (nodeForCanvas(usage).compartments ?? []).some((compartment) => endCount !== 2 || compartment.title !== "flows");
|
|
184579
|
+
const retainedIds = new Set(projections.filter((projection2) => blocksCompaction(projection2) || annotatedUsageIds.has(projection2.usage.id) || projection2.endCount < 2 || projection2.bindings.length !== projection2.endCount).map(({ usage }) => usage.id));
|
|
184580
|
+
const hiddenIds = /* @__PURE__ */ new Set();
|
|
184581
|
+
for (const { usage } of projections) {
|
|
184582
|
+
if (retainedIds.has(usage.id)) continue;
|
|
184583
|
+
hiddenIds.add(usage.id);
|
|
184584
|
+
for (const port of usage.ports ?? []) hiddenIds.add(port.id);
|
|
184585
|
+
}
|
|
184586
|
+
const edges = model.edges.filter((edge) => !hiddenIds.has(edge.from) && !hiddenIds.has(edge.to));
|
|
184587
|
+
const compactNodes = [];
|
|
184588
|
+
const compactEdges = [];
|
|
184589
|
+
for (const { usage, bindings, endCount } of projections) {
|
|
184590
|
+
if (retainedIds.has(usage.id)) continue;
|
|
184591
|
+
const sharedEdgeMeta = { ...bindings[0]?.edge.meta ?? {} };
|
|
184592
|
+
delete sharedEdgeMeta.connectionUsageEnd;
|
|
184593
|
+
delete sharedEdgeMeta.interfaceUsageEnd;
|
|
184594
|
+
delete sharedEdgeMeta.connectionEndOrdinal;
|
|
184595
|
+
delete sharedEdgeMeta.connectionEndRole;
|
|
184596
|
+
const semanticName = typeof usage.meta?.explicitRelationshipName === "string" ? usage.meta.explicitRelationshipName : bindings[0]?.edge.name;
|
|
184597
|
+
const semanticType = bindings[0]?.edge.type ?? usage.type;
|
|
184598
|
+
const label = relationship === "interface" ? ["\xABinterface\xBB", semanticName ?? "", semanticType ? `: ${semanticType}` : ""].filter(Boolean).join(" ").trim() : semanticName;
|
|
184599
|
+
const baseMeta = {
|
|
184600
|
+
...usage.meta,
|
|
184601
|
+
...sharedEdgeMeta,
|
|
184602
|
+
connectionUsageId: usage.id,
|
|
184603
|
+
connectionUsageSource: usage.source,
|
|
184604
|
+
...relationship === "interface" ? { interfaceUsageId: usage.id } : {}
|
|
184605
|
+
};
|
|
184606
|
+
if (endCount <= 2) {
|
|
184607
|
+
if (bindings.length !== 2) continue;
|
|
184608
|
+
const [from, to] = bindings;
|
|
184609
|
+
compactEdges.push({
|
|
184610
|
+
id: from.edge.id,
|
|
184611
|
+
from: from.externalId,
|
|
184612
|
+
to: to.externalId,
|
|
184613
|
+
kind: relationship === "connection" ? "connect" : "interface",
|
|
184614
|
+
name: semanticName,
|
|
184615
|
+
type: semanticType,
|
|
184616
|
+
isDef: false,
|
|
184617
|
+
label,
|
|
184618
|
+
endRoleFrom: from.role,
|
|
184619
|
+
endLabelFrom: from.multiplicity,
|
|
184620
|
+
endAdornmentFrom: from.adornment,
|
|
184621
|
+
endRoleTo: to.role,
|
|
184622
|
+
endLabelTo: to.multiplicity,
|
|
184623
|
+
endAdornmentTo: to.adornment,
|
|
184624
|
+
source: usage.source ?? from.edge.source,
|
|
184625
|
+
meta: {
|
|
184626
|
+
...baseMeta,
|
|
184627
|
+
...relationship === "connection" ? { compactConnectionUsage: true } : { compactInterfaceUsage: true },
|
|
184628
|
+
connectionEndFromOrdinal: from.ordinal,
|
|
184629
|
+
connectionEndToOrdinal: to.ordinal,
|
|
184630
|
+
...from.role ? { connectionEndFromRole: from.role } : {},
|
|
184631
|
+
...to.role ? { connectionEndToRole: to.role } : {}
|
|
184632
|
+
}
|
|
184633
|
+
});
|
|
184634
|
+
continue;
|
|
184635
|
+
}
|
|
184636
|
+
const hubMeta = { ...baseMeta };
|
|
184637
|
+
delete hubMeta.flowDecorations;
|
|
184638
|
+
const hubId = `${usage.id}::__compact_hub`;
|
|
184639
|
+
compactNodes.push({
|
|
184640
|
+
id: hubId,
|
|
184641
|
+
name: "",
|
|
184642
|
+
keyword: relationship,
|
|
184643
|
+
isDef: false,
|
|
184644
|
+
shape: "dot",
|
|
184645
|
+
...usage.frame ? { frame: usage.frame } : {},
|
|
184646
|
+
source: usage.source,
|
|
184647
|
+
meta: {
|
|
184648
|
+
...hubMeta,
|
|
184649
|
+
naryConnectionHub: true,
|
|
184650
|
+
...relationship === "connection" ? { compactConnectionUsageHub: true } : { compactInterfaceUsageHub: true }
|
|
184651
|
+
}
|
|
184652
|
+
});
|
|
184653
|
+
for (const binding of bindings) {
|
|
184654
|
+
compactEdges.push({
|
|
184655
|
+
id: binding.edge.id,
|
|
184656
|
+
from: hubId,
|
|
184657
|
+
to: binding.externalId,
|
|
184658
|
+
kind: relationship === "connection" ? "connect" : "interface",
|
|
184659
|
+
name: semanticName,
|
|
184660
|
+
type: semanticType,
|
|
184661
|
+
isDef: false,
|
|
184662
|
+
label,
|
|
184663
|
+
endRoleTo: binding.role,
|
|
184664
|
+
endLabelTo: binding.multiplicity,
|
|
184665
|
+
endAdornmentTo: binding.adornment,
|
|
184666
|
+
source: usage.source ?? binding.edge.source,
|
|
184667
|
+
meta: {
|
|
184668
|
+
...hubMeta,
|
|
184669
|
+
...relationship === "connection" ? { compactConnectionUsageEnd: true } : { compactInterfaceUsageEnd: true },
|
|
184670
|
+
connectionEndOrdinal: binding.ordinal,
|
|
184671
|
+
...binding.role ? { connectionEndRole: binding.role } : {}
|
|
184672
|
+
}
|
|
184673
|
+
});
|
|
184674
|
+
}
|
|
184675
|
+
}
|
|
184676
|
+
return {
|
|
184677
|
+
...model,
|
|
184678
|
+
nodes: [...model.nodes.filter((node) => !hiddenIds.has(node.id)), ...compactNodes],
|
|
184679
|
+
edges: [...edges, ...compactEdges]
|
|
184680
|
+
};
|
|
184681
|
+
}
|
|
184682
|
+
function hideExplicitConnectionBoxes(model) {
|
|
184683
|
+
return hideExplicitRelationshipBoxes(model, "connection");
|
|
184684
|
+
}
|
|
184685
|
+
function hideExplicitInterfaceBoxes(model) {
|
|
184686
|
+
return hideExplicitRelationshipBoxes(model, "interface");
|
|
184687
|
+
}
|
|
183573
184688
|
function applyBehaviorFilters(model, filters) {
|
|
183574
184689
|
if (!FILTERED_KINDS.has(model.kind)) return model;
|
|
183575
|
-
const
|
|
184690
|
+
const visibleModel = filters.defs ? withVisibleDefinitionLayer(model) : model;
|
|
184691
|
+
const frames = visibleModel.frames ?? [];
|
|
183576
184692
|
const dropped = /* @__PURE__ */ new Set();
|
|
183577
184693
|
const reparented = /* @__PURE__ */ new Set();
|
|
183578
184694
|
for (const frame2 of frames) {
|
|
@@ -183581,12 +184697,15 @@ function applyBehaviorFilters(model, filters) {
|
|
|
183581
184697
|
if (!filters.parts && isOwnerPartFrame || !filters.performers && isPerformerLane) {
|
|
183582
184698
|
reparented.add(frame2.id);
|
|
183583
184699
|
}
|
|
183584
|
-
if (!filters.defs && frame2.meta?.behaviorDef === true) dropped.add(frame2.id);
|
|
184700
|
+
if (!filters.defs && (frame2.meta?.behaviorDef === true || frame2.meta?.ivPartDef === true)) dropped.add(frame2.id);
|
|
183585
184701
|
}
|
|
183586
|
-
const droppedNodes = new Set(
|
|
184702
|
+
const droppedNodes = new Set(visibleModel.nodes.filter((n2) => !filters.parts && n2.meta?.stvPart === true || !filters.defs && (n2.meta?.behaviorDef === true || n2.meta?.ivPartDef === true) || !filters.actions && n2.meta?.ivAction === true).map((n2) => n2.id));
|
|
183587
184703
|
const strippedPorts = !filters.ports && frames.some((f) => f.ports?.some((p) => p.meta?.afvPartPort === true));
|
|
183588
|
-
const strippedDefinedBy =
|
|
183589
|
-
if (dropped.size === 0 && reparented.size === 0 && droppedNodes.size === 0 && !strippedPorts && !strippedDefinedBy)
|
|
184704
|
+
const strippedDefinedBy = !filters.definedBy && visibleModel.edges.some((edge) => edge.kind === "definedBy");
|
|
184705
|
+
if (dropped.size === 0 && reparented.size === 0 && droppedNodes.size === 0 && !strippedPorts && !strippedDefinedBy) {
|
|
184706
|
+
const connectionsProjected2 = filters.connectionBoxes ? visibleModel : hideExplicitConnectionBoxes(visibleModel);
|
|
184707
|
+
return filters.interfaceBoxes ? connectionsProjected2 : hideExplicitInterfaceBoxes(connectionsProjected2);
|
|
184708
|
+
}
|
|
183590
184709
|
const byId = new Map(frames.map((f) => [f.id, f]));
|
|
183591
184710
|
const insideDropped = (id2) => {
|
|
183592
184711
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -183617,7 +184736,7 @@ function applyBehaviorFilters(model, filters) {
|
|
|
183617
184736
|
const ports = keepPorts(f.ports);
|
|
183618
184737
|
return parent === f.parent && ports === f.ports ? f : { ...f, parent, ports };
|
|
183619
184738
|
});
|
|
183620
|
-
const nodes =
|
|
184739
|
+
const nodes = visibleModel.nodes.filter((n2) => !droppedNodes.has(n2.id) && !insideDropped(n2.frame) && !dropped.has(n2.frame ?? "")).map((n2) => {
|
|
183621
184740
|
const frame2 = visibleParent(n2.frame);
|
|
183622
184741
|
return frame2 === n2.frame ? n2 : { ...n2, frame: frame2 };
|
|
183623
184742
|
});
|
|
@@ -183627,8 +184746,15 @@ function applyBehaviorFilters(model, filters) {
|
|
|
183627
184746
|
...nextFrames.map((f) => f.id),
|
|
183628
184747
|
...nextFrames.flatMap((f) => (f.ports ?? []).map((p) => p.id))
|
|
183629
184748
|
]);
|
|
183630
|
-
const edges =
|
|
183631
|
-
|
|
184749
|
+
const edges = visibleModel.edges.filter((e) => !(!filters.definedBy && e.kind === "definedBy") && !hiddenPortIds.has(e.from) && !hiddenPortIds.has(e.to) && liveIds.has(e.from) && liveIds.has(e.to));
|
|
184750
|
+
const filtered = {
|
|
184751
|
+
...visibleModel,
|
|
184752
|
+
frames: nextFrames,
|
|
184753
|
+
nodes: withoutOrphanedAnnotations(visibleModel, nodes, edges),
|
|
184754
|
+
edges
|
|
184755
|
+
};
|
|
184756
|
+
const connectionsProjected = filters.connectionBoxes ? filtered : hideExplicitConnectionBoxes(filtered);
|
|
184757
|
+
return filters.interfaceBoxes ? connectionsProjected : hideExplicitInterfaceBoxes(connectionsProjected);
|
|
183632
184758
|
}
|
|
183633
184759
|
function isProxyPort(port) {
|
|
183634
184760
|
return port.meta?.proxy === true;
|
|
@@ -183736,7 +184862,7 @@ function collapseIvModel(model, hiddenInternals) {
|
|
|
183736
184862
|
const hidden = /* @__PURE__ */ new Set([...hiddenFrameIds, ...hiddenNodeIds, ...ownerOfHiddenPort.keys()]);
|
|
183737
184863
|
const containerRootOf = (id2) => proxyHost.get(id2) ?? bodyDock.get(id2);
|
|
183738
184864
|
const seenEdge = /* @__PURE__ */ new Set();
|
|
183739
|
-
const edges = model.edges.filter((e) => {
|
|
184865
|
+
const edges = model.edges.filter((edge) => rootFor(typeof edge.meta?.ivRelationshipOwnerId === "string" ? edge.meta.ivRelationshipOwnerId : void 0) === void 0).filter((e) => {
|
|
183740
184866
|
const fromRoot = containerRootOf(e.from);
|
|
183741
184867
|
const toRoot = containerRootOf(e.to);
|
|
183742
184868
|
if (fromRoot !== void 0 && fromRoot === toRoot) return false;
|
|
@@ -184114,15 +185240,24 @@ function modelToFlow(model, opts) {
|
|
|
184114
185240
|
const visibleFeatureH = featureCompartmentBandHeight(canvasNode);
|
|
184115
185241
|
const featureH = nodeFeatureCompartmentReserve(canvasNode);
|
|
184116
185242
|
const base = isGeo ? { w: 24, h: 24 } : nodeSize(canvasNode, opts.direction);
|
|
185243
|
+
const requiresNaturalCompartmentHeight = visibleFeatureH > 0 || (canvasNode.meta?.connectionUsage === true || canvasNode.meta?.interfaceUsage === true) && !!canvasNode.compartments?.length;
|
|
184117
185244
|
const sizeOverride = ov[n2.layoutKey ?? n2.id];
|
|
184118
185245
|
const compactCollapsed = canvasNode.meta?.internalsHidden === true;
|
|
184119
|
-
const
|
|
185246
|
+
const compactOverride = compactCollapsed && sizeOverride ? { ...sizeOverride, w: sizeOverride.collapsedW, h: sizeOverride.collapsedH } : sizeOverride;
|
|
185247
|
+
const presentationOverride = compactOverride ? {
|
|
185248
|
+
...compactOverride,
|
|
185249
|
+
h: connectionUsageHeightOverride(
|
|
185250
|
+
canvasNode,
|
|
185251
|
+
compactOverride.h,
|
|
185252
|
+
compactOverride.connectionBlockVersion
|
|
185253
|
+
)
|
|
185254
|
+
} : compactOverride;
|
|
184120
185255
|
const projectedSize = isCircularControlShape(canvasNode.shape) ? base : isForkJoinShape(canvasNode.shape) ? forkJoinSizeWithOverride(presentationOverride, opts.direction) : sizeWithOverride(
|
|
184121
185256
|
base,
|
|
184122
185257
|
presentationOverride,
|
|
184123
185258
|
{
|
|
184124
185259
|
w: canvasNode.meta?.containerControls === true || canvasNode.meta?.internalsHidden === true ? COLLAPSED_CONTAINER_MIN_WIDTH : 48,
|
|
184125
|
-
h:
|
|
185260
|
+
h: requiresNaturalCompartmentHeight ? base.h : 24
|
|
184126
185261
|
}
|
|
184127
185262
|
);
|
|
184128
185263
|
const compactPortHandles = compactCollapsed ? assignPortHandles(canvasNode.ports, opts.portOverrides, canvasNode.shape) : [];
|
|
@@ -184152,7 +185287,7 @@ function modelToFlow(model, opts) {
|
|
|
184152
185287
|
w: size.w,
|
|
184153
185288
|
h: size.h,
|
|
184154
185289
|
featureCompartmentHeight: featureH,
|
|
184155
|
-
featureCompartmentMinHeight:
|
|
185290
|
+
featureCompartmentMinHeight: requiresNaturalCompartmentHeight ? base.h : void 0,
|
|
184156
185291
|
showPortLabels: opts.showPortLabels,
|
|
184157
185292
|
showMult: opts.showMult,
|
|
184158
185293
|
connectPointSpacing
|
|
@@ -184273,18 +185408,27 @@ function modelToFlow(model, opts) {
|
|
|
184273
185408
|
const routeKey = edgeRouteKey(e, dup, persistedEndpoints);
|
|
184274
185409
|
const savedAnchor = opts.edgeAnchors?.[routeKey];
|
|
184275
185410
|
const settledGeometry = opts.edgeGeometry?.[routeKey];
|
|
184276
|
-
const
|
|
184277
|
-
const
|
|
184278
|
-
const
|
|
184279
|
-
const
|
|
185411
|
+
const explicitSourceHandle = fromPort ? void 0 : canonicalSideHandle(savedAnchor?.sourceHandle);
|
|
185412
|
+
const explicitTargetHandle = toPort ? void 0 : canonicalSideHandle(savedAnchor?.targetHandle);
|
|
185413
|
+
const savedSourceHandle = explicitSourceHandle ?? (fromPort ? void 0 : canonicalSideHandle(settledGeometry?.sourceHandle));
|
|
185414
|
+
const savedTargetHandle = explicitTargetHandle ?? (toPort ? void 0 : canonicalSideHandle(settledGeometry?.targetHandle));
|
|
185415
|
+
const portSideForHandle = (ownerId, portId, persistedHandle) => {
|
|
185416
|
+
const portHandle = nodeById.get(ownerId)?.data.ports?.find((handle) => handle.port.id === portId);
|
|
185417
|
+
return portHandle?.port.meta?.connectionEndPin === true ? portHandle.side : parsePortAnchorHandleId(persistedHandle)?.side;
|
|
185418
|
+
};
|
|
185419
|
+
const savedSourcePortSide = fromPort ? portSideForHandle(source, e.from, settledGeometry?.sourceHandle) : void 0;
|
|
185420
|
+
const savedTargetPortSide = toPort ? portSideForHandle(target, e.to, settledGeometry?.targetHandle) : void 0;
|
|
185421
|
+
const sourceHandle = fromPort ? savedSourcePortSide ? portAnchorHandleId(e.from, savedSourcePortSide) : e.from : savedSourceHandle;
|
|
185422
|
+
const targetHandle = toPort ? savedTargetPortSide ? portAnchorHandleId(e.to, savedTargetPortSide) : e.to : savedTargetHandle;
|
|
185423
|
+
const settledHandlesMatch = !settledGeometry || (settledGeometry.sourceHandle === void 0 || settledGeometry.sourceHandle === sourceHandle) && (settledGeometry.targetHandle === void 0 || settledGeometry.targetHandle === targetHandle);
|
|
184280
185424
|
retainExplicitHandle(source, savedSourceHandle);
|
|
184281
185425
|
retainExplicitHandle(target, savedTargetHandle);
|
|
184282
185426
|
edges.push({
|
|
184283
185427
|
id: e.id,
|
|
184284
185428
|
source,
|
|
184285
185429
|
target,
|
|
184286
|
-
...
|
|
184287
|
-
...
|
|
185430
|
+
...sourceHandle ? { sourceHandle } : {},
|
|
185431
|
+
...targetHandle ? { targetHandle } : {},
|
|
184288
185432
|
type: "sysml",
|
|
184289
185433
|
data: {
|
|
184290
185434
|
kind: model.kind,
|
|
@@ -184293,7 +185437,9 @@ function modelToFlow(model, opts) {
|
|
|
184293
185437
|
showMult: opts.showMult,
|
|
184294
185438
|
routeKey,
|
|
184295
185439
|
route: opts.edgeRoutes?.[routeKey],
|
|
184296
|
-
|
|
185440
|
+
...explicitSourceHandle ? { explicitSourceAnchor: true } : {},
|
|
185441
|
+
...explicitTargetHandle ? { explicitTargetAnchor: true } : {},
|
|
185442
|
+
settledGeometry: settledHandlesMatch ? settledGeometry : void 0
|
|
184297
185443
|
},
|
|
184298
185444
|
selectable: true,
|
|
184299
185445
|
reconnectable: true,
|
|
@@ -184385,7 +185531,7 @@ function clampDirection(kind, d) {
|
|
|
184385
185531
|
|
|
184386
185532
|
// ../extension/src/webview/diagram/flow/geo-layout.ts
|
|
184387
185533
|
var GEO_MARGIN_LEFT = 48;
|
|
184388
|
-
var GEO_TOP_PAD =
|
|
185534
|
+
var GEO_TOP_PAD = 40;
|
|
184389
185535
|
var GEO_TARGET_W = 860;
|
|
184390
185536
|
var GEO_TARGET_H = 520;
|
|
184391
185537
|
var GEO_DEF_W = 400;
|
|
@@ -184400,33 +185546,110 @@ function geoProject(f, x, y, z2) {
|
|
|
184400
185546
|
const isoY = (x + y) * f.sinA - z2;
|
|
184401
185547
|
return [f.ox + (isoX - f.isoMinX) * f.scale, f.oy + (isoY - f.isoMinY) * f.scale];
|
|
184402
185548
|
}
|
|
184403
|
-
function
|
|
185549
|
+
function geoWorldPoint(placement, local) {
|
|
185550
|
+
const [lx, ly, lz] = local;
|
|
185551
|
+
const orientation = placement.orientation;
|
|
185552
|
+
if (orientation) {
|
|
185553
|
+
return [
|
|
185554
|
+
placement.x + orientation[0] * lx + orientation[1] * ly + orientation[2] * lz,
|
|
185555
|
+
placement.y + orientation[3] * lx + orientation[4] * ly + orientation[5] * lz,
|
|
185556
|
+
(placement.z ?? 0) + orientation[6] * lx + orientation[7] * ly + orientation[8] * lz
|
|
185557
|
+
];
|
|
185558
|
+
}
|
|
185559
|
+
if (placement.rot) {
|
|
185560
|
+
const angle = placement.rot * Math.PI / 180;
|
|
185561
|
+
const cos = Math.cos(angle);
|
|
185562
|
+
const sin = Math.sin(angle);
|
|
185563
|
+
return [
|
|
185564
|
+
placement.x + cos * lx - sin * ly,
|
|
185565
|
+
placement.y + sin * lx + cos * ly,
|
|
185566
|
+
(placement.z ?? 0) + lz
|
|
185567
|
+
];
|
|
185568
|
+
}
|
|
185569
|
+
return [placement.x + lx, placement.y + ly, (placement.z ?? 0) + lz];
|
|
185570
|
+
}
|
|
185571
|
+
function geoHalfExtentsOf(node, def) {
|
|
184404
185572
|
const g = node.geo;
|
|
184405
|
-
const z2 = g.z ?? 0;
|
|
184406
185573
|
switch (g.shape) {
|
|
184407
185574
|
case "sphere": {
|
|
184408
185575
|
const r = g.radius ?? def / 2;
|
|
184409
|
-
return { hx: r, hy: r,
|
|
185576
|
+
return { hx: r, hy: r, hz: r };
|
|
184410
185577
|
}
|
|
184411
185578
|
case "cylinder":
|
|
184412
185579
|
case "cone": {
|
|
184413
185580
|
const r = g.radius ?? def / 2;
|
|
184414
|
-
|
|
184415
|
-
return { hx: r, hy: r, zlo: z2 - h / 2, zhi: z2 + h / 2 };
|
|
185581
|
+
return { hx: r, hy: r, hz: (g.sizeZ ?? def) / 2 };
|
|
184416
185582
|
}
|
|
184417
185583
|
case "pyramid":
|
|
184418
185584
|
case "wedge":
|
|
184419
|
-
case "box":
|
|
184420
|
-
|
|
184421
|
-
|
|
184422
|
-
|
|
184423
|
-
|
|
184424
|
-
|
|
184425
|
-
default:
|
|
184426
|
-
|
|
184427
|
-
|
|
184428
|
-
|
|
185585
|
+
case "box":
|
|
185586
|
+
return {
|
|
185587
|
+
hx: (g.sizeX ?? def) / 2,
|
|
185588
|
+
hy: (g.sizeY ?? def) / 2,
|
|
185589
|
+
hz: (g.sizeZ ?? def) / 2
|
|
185590
|
+
};
|
|
185591
|
+
default:
|
|
185592
|
+
return { hx: (g.sizeX ?? GEO_DEF_W) / 2, hy: (g.sizeY ?? GEO_DEF_H) / 2, hz: 0 };
|
|
185593
|
+
}
|
|
185594
|
+
}
|
|
185595
|
+
function geoShapePoints(node, def) {
|
|
185596
|
+
const g = node.geo;
|
|
185597
|
+
const { hx, hy, hz } = geoHalfExtentsOf(node, def);
|
|
185598
|
+
const transform2 = (points) => points.map((point) => geoWorldPoint(g, point));
|
|
185599
|
+
const ring = (z2) => Array.from({ length: 32 }, (_2, index2) => {
|
|
185600
|
+
const angle = index2 * Math.PI / 16;
|
|
185601
|
+
return [hx * Math.cos(angle), hy * Math.sin(angle), z2];
|
|
185602
|
+
});
|
|
185603
|
+
switch (g.shape) {
|
|
185604
|
+
case "sphere": {
|
|
185605
|
+
const radius = g.radius ?? def / 2;
|
|
185606
|
+
const cosA = Math.cos(Math.PI / 6);
|
|
185607
|
+
const sinA = Math.sin(Math.PI / 6);
|
|
185608
|
+
const norm = Math.hypot(cosA, cosA);
|
|
185609
|
+
const silhouette = Array.from({ length: 32 }, (_2, index2) => {
|
|
185610
|
+
const angle = index2 * Math.PI / 16;
|
|
185611
|
+
const alongX = [cosA / norm, -cosA / norm, 0];
|
|
185612
|
+
const alongY = [sinA / norm, sinA / norm, -1 / norm];
|
|
185613
|
+
const x = radius * (alongX[0] * Math.cos(angle) + alongY[0] * Math.sin(angle));
|
|
185614
|
+
const y = radius * (alongX[1] * Math.cos(angle) + alongY[1] * Math.sin(angle));
|
|
185615
|
+
const z2 = radius * (alongX[2] * Math.cos(angle) + alongY[2] * Math.sin(angle));
|
|
185616
|
+
return [g.x + x, g.y + y, (g.z ?? 0) + z2];
|
|
185617
|
+
});
|
|
185618
|
+
return [
|
|
185619
|
+
...silhouette,
|
|
185620
|
+
[g.x - radius, g.y, g.z ?? 0],
|
|
185621
|
+
[g.x + radius, g.y, g.z ?? 0],
|
|
185622
|
+
[g.x, g.y - radius, g.z ?? 0],
|
|
185623
|
+
[g.x, g.y + radius, g.z ?? 0],
|
|
185624
|
+
[g.x, g.y, (g.z ?? 0) - radius],
|
|
185625
|
+
[g.x, g.y, (g.z ?? 0) + radius]
|
|
185626
|
+
];
|
|
184429
185627
|
}
|
|
185628
|
+
case "cylinder":
|
|
185629
|
+
return transform2([...ring(-hz), ...ring(hz)]);
|
|
185630
|
+
case "cone":
|
|
185631
|
+
return transform2([...ring(-hz), [0, 0, hz]]);
|
|
185632
|
+
case "pyramid":
|
|
185633
|
+
return transform2([
|
|
185634
|
+
[-hx, -hy, -hz],
|
|
185635
|
+
[hx, -hy, -hz],
|
|
185636
|
+
[hx, hy, -hz],
|
|
185637
|
+
[-hx, hy, -hz],
|
|
185638
|
+
[0, 0, hz]
|
|
185639
|
+
]);
|
|
185640
|
+
case "wedge":
|
|
185641
|
+
return transform2([
|
|
185642
|
+
[-hx, -hy, -hz],
|
|
185643
|
+
[hx, -hy, -hz],
|
|
185644
|
+
[hx, hy, -hz],
|
|
185645
|
+
[-hx, hy, -hz],
|
|
185646
|
+
[0, -hy, hz],
|
|
185647
|
+
[0, hy, hz]
|
|
185648
|
+
]);
|
|
185649
|
+
case "box":
|
|
185650
|
+
return transform2([-1, 1].flatMap((x) => [-1, 1].flatMap((y) => [-1, 1].map((z2) => [x * hx, y * hy, z2 * hz]))));
|
|
185651
|
+
default:
|
|
185652
|
+
return transform2([[-hx, -hy, 0], [hx, -hy, 0], [hx, hy, 0], [-hx, hy, 0]]);
|
|
184430
185653
|
}
|
|
184431
185654
|
}
|
|
184432
185655
|
function makeGeoFrameNode(kind, w, h, geo) {
|
|
@@ -184506,26 +185729,30 @@ function layoutPlan(kind, placed, strip, axes, edges) {
|
|
|
184506
185729
|
function layoutIso(kind, placed, strip, unit, edges) {
|
|
184507
185730
|
const cosA = Math.cos(Math.PI / 6);
|
|
184508
185731
|
const sinA = Math.sin(Math.PI / 6);
|
|
184509
|
-
let
|
|
185732
|
+
let centreMinX = 0, centreMaxX = 0, centreMinY = 0, centreMaxY = 0;
|
|
184510
185733
|
for (const n2 of placed) {
|
|
184511
185734
|
const g = n2.data.node.geo;
|
|
184512
|
-
|
|
184513
|
-
|
|
184514
|
-
|
|
184515
|
-
|
|
184516
|
-
pmaxZ = Math.max(pmaxZ, g.z ?? 0);
|
|
185735
|
+
centreMinX = Math.min(centreMinX, g.x);
|
|
185736
|
+
centreMaxX = Math.max(centreMaxX, g.x);
|
|
185737
|
+
centreMinY = Math.min(centreMinY, g.y);
|
|
185738
|
+
centreMaxY = Math.max(centreMaxY, g.y);
|
|
184517
185739
|
}
|
|
184518
|
-
const span = Math.max(
|
|
185740
|
+
const span = Math.max(centreMaxX - centreMinX, centreMaxY - centreMinY, 1);
|
|
184519
185741
|
const def = Math.max(span * 0.12, 1e-4);
|
|
185742
|
+
let pminX = 0, pmaxX = 0, pminY = 0, pmaxY = 0, pmaxZ = 0;
|
|
184520
185743
|
let isoMinX = Infinity, isoMaxX = -Infinity, isoMinY = Infinity, isoMaxY = -Infinity;
|
|
184521
185744
|
const iso = (x, y, z2) => [(x - y) * cosA, (x + y) * sinA - z2];
|
|
184522
|
-
const
|
|
185745
|
+
const pointsByNode = /* @__PURE__ */ new Map();
|
|
184523
185746
|
for (const n2 of placed) {
|
|
184524
|
-
const
|
|
184525
|
-
|
|
184526
|
-
const
|
|
184527
|
-
|
|
184528
|
-
|
|
185747
|
+
const points = geoShapePoints(n2.data.node, def);
|
|
185748
|
+
pointsByNode.set(n2, points);
|
|
185749
|
+
for (const [worldX, worldY, worldZ] of points) {
|
|
185750
|
+
pminX = Math.min(pminX, worldX);
|
|
185751
|
+
pmaxX = Math.max(pmaxX, worldX);
|
|
185752
|
+
pminY = Math.min(pminY, worldY);
|
|
185753
|
+
pmaxY = Math.max(pmaxY, worldY);
|
|
185754
|
+
pmaxZ = Math.max(pmaxZ, worldZ);
|
|
185755
|
+
const [ix, iy] = iso(worldX, worldY, worldZ);
|
|
184529
185756
|
isoMinX = Math.min(isoMinX, ix);
|
|
184530
185757
|
isoMaxX = Math.max(isoMaxX, ix);
|
|
184531
185758
|
isoMinY = Math.min(isoMinY, iy);
|
|
@@ -184537,11 +185764,9 @@ function layoutIso(kind, placed, strip, unit, edges) {
|
|
|
184537
185764
|
const oy = GEO_TOP_PAD + 6;
|
|
184538
185765
|
const frame3d = { ox, oy, scale, cosA, sinA, isoMinX, isoMinY, minX: pminX, maxX: pmaxX, minY: pminY, maxY: pmaxY, maxZ: pmaxZ, unit, def };
|
|
184539
185766
|
const outPlaced = placed.map((n2) => {
|
|
184540
|
-
const e = exts.get(n2);
|
|
184541
|
-
const g = n2.data.node.geo;
|
|
184542
185767
|
let sxMin = Infinity, syMin = Infinity, sxMax = -Infinity, syMax = -Infinity;
|
|
184543
|
-
for (const
|
|
184544
|
-
const [px, py] = geoProject(frame3d,
|
|
185768
|
+
for (const [worldX, worldY, worldZ] of pointsByNode.get(n2)) {
|
|
185769
|
+
const [px, py] = geoProject(frame3d, worldX, worldY, worldZ);
|
|
184545
185770
|
sxMin = Math.min(sxMin, px);
|
|
184546
185771
|
syMin = Math.min(syMin, py);
|
|
184547
185772
|
sxMax = Math.max(sxMax, px);
|
|
@@ -194080,7 +195305,7 @@ function buildEdgeBundles(candidates, obstacles = [], busPositions = {}) {
|
|
|
194080
195305
|
const buckets = /* @__PURE__ */ new Map();
|
|
194081
195306
|
const fanSizes = /* @__PURE__ */ new Map();
|
|
194082
195307
|
const add = (edge, role) => {
|
|
194083
|
-
if (edge.eligible === false) return;
|
|
195308
|
+
if (edge.eligible === false || edge.eligibleRole && edge.eligibleRole !== role) return;
|
|
194084
195309
|
const pairKey = `${edge.source}\0${edge.target}\0${edge.className}`;
|
|
194085
195310
|
if ((pairCounts.get(pairKey) ?? 0) > 1) return;
|
|
194086
195311
|
const commonNodeId = role === "source" ? edge.source : edge.target;
|
|
@@ -194784,6 +196009,16 @@ async function elkLayout(elk, graph) {
|
|
|
194784
196009
|
}
|
|
194785
196010
|
}
|
|
194786
196011
|
function overrideFor(node, overrides) {
|
|
196012
|
+
const stored = storedOverrideFor(node, overrides);
|
|
196013
|
+
if (!stored) return void 0;
|
|
196014
|
+
const compact2 = node.data.node?.meta?.internalsHidden === true || node.data.frame?.meta?.internalsHidden === true;
|
|
196015
|
+
const active = compact2 ? { ...stored, w: stored.collapsedW, h: stored.collapsedH } : stored;
|
|
196016
|
+
return {
|
|
196017
|
+
...active,
|
|
196018
|
+
h: connectionUsageHeightOverride(node.data.node, active.h, active.connectionBlockVersion)
|
|
196019
|
+
};
|
|
196020
|
+
}
|
|
196021
|
+
function storedOverrideFor(node, overrides) {
|
|
194787
196022
|
return overrides?.[node.data.layoutKey] ?? overrides?.[node.id];
|
|
194788
196023
|
}
|
|
194789
196024
|
var AFV_LAYOUT_EDGE_KINDS = /* @__PURE__ */ new Set([
|
|
@@ -196010,7 +197245,8 @@ function semanticPortHandle(node, handle) {
|
|
|
196010
197245
|
function validConcretePortAnchor(node, handle) {
|
|
196011
197246
|
const parsed = parsePortAnchorHandleId(handle);
|
|
196012
197247
|
const ph = parsed ? portOnNode(node, parsed.portId) : void 0;
|
|
196013
|
-
|
|
197248
|
+
if (!ph) return false;
|
|
197249
|
+
return ph.port.meta?.connectionEndPin === true ? handle === portAnchorHandleId(ph.port.id, ph.side) : portConnectHandleIds(ph.port.id, ph.side).includes(handle);
|
|
196014
197250
|
}
|
|
196015
197251
|
function isStrictDescendant(nodeId, ancestorId, byId) {
|
|
196016
197252
|
let cur = byId.get(nodeId)?.parentId;
|
|
@@ -196025,6 +197261,7 @@ function isStrictDescendant(nodeId, ancestorId, byId) {
|
|
|
196025
197261
|
function inferredPortAnchorSide(node, other, portId, byId) {
|
|
196026
197262
|
const ph = portOnNode(node, portId);
|
|
196027
197263
|
if (!ph) return "right";
|
|
197264
|
+
if (ph.port.meta?.connectionEndPin === true) return ph.side;
|
|
196028
197265
|
return other.id === node.id || isStrictDescendant(other.id, node.id, byId) ? OPPOSITE[ph.side] : ph.side;
|
|
196029
197266
|
}
|
|
196030
197267
|
function assignPortAnchorSides(nodes, edges) {
|
|
@@ -196115,6 +197352,38 @@ function nextSideAnchor(counts, offsetsCache, assignedOffsets, node, side, spaci
|
|
|
196115
197352
|
}
|
|
196116
197353
|
function assignEdgeSides(nodes, edges, topDown = false, connectPointSpacing = CONNECT_POINT_SPACING_DEFAULT, behaviorDirection) {
|
|
196117
197354
|
const byId = new Map(nodes.map((n2) => [n2.id, n2]));
|
|
197355
|
+
const naryHub = (node) => node?.data.node?.shape === "dot" && node.data.node.meta?.naryConnectionHub === true;
|
|
197356
|
+
const explicitHubAnchors = /* @__PURE__ */ new Map();
|
|
197357
|
+
const retainExplicitHubAnchor = (nodeId, side, offset2) => {
|
|
197358
|
+
const current2 = explicitHubAnchors.get(nodeId) ?? {};
|
|
197359
|
+
const offsets = current2[side] ?? [];
|
|
197360
|
+
if (!offsets.includes(offset2)) current2[side] = [...offsets, offset2].sort((a2, b) => a2 - b);
|
|
197361
|
+
explicitHubAnchors.set(nodeId, current2);
|
|
197362
|
+
};
|
|
197363
|
+
for (const edge of edges) {
|
|
197364
|
+
const sourceAnchor = parseSideAnchorHandleId(edge.sourceHandle);
|
|
197365
|
+
if (sourceAnchor && naryHub(byId.get(edge.source))) {
|
|
197366
|
+
if (edge.data?.explicitSourceAnchor === true) {
|
|
197367
|
+
retainExplicitHubAnchor(edge.source, sourceAnchor.side, sourceAnchor.offset);
|
|
197368
|
+
} else {
|
|
197369
|
+
edge.sourceHandle = sideAnchorHandleId(sourceAnchor.side, 0.5);
|
|
197370
|
+
}
|
|
197371
|
+
}
|
|
197372
|
+
const targetAnchor = parseSideAnchorHandleId(edge.targetHandle);
|
|
197373
|
+
if (targetAnchor && naryHub(byId.get(edge.target))) {
|
|
197374
|
+
if (edge.data?.explicitTargetAnchor === true) {
|
|
197375
|
+
retainExplicitHubAnchor(edge.target, targetAnchor.side, targetAnchor.offset);
|
|
197376
|
+
} else {
|
|
197377
|
+
edge.targetHandle = sideAnchorHandleId(targetAnchor.side, 0.5);
|
|
197378
|
+
}
|
|
197379
|
+
}
|
|
197380
|
+
}
|
|
197381
|
+
for (const node of nodes) {
|
|
197382
|
+
const explicit = explicitHubAnchors.get(node.id);
|
|
197383
|
+
if (naryHub(node) && (node.data.explicitSideAnchors || explicit)) {
|
|
197384
|
+
node.data = { ...node.data, explicitSideAnchors: explicit };
|
|
197385
|
+
}
|
|
197386
|
+
}
|
|
196118
197387
|
const sideCounts = /* @__PURE__ */ new Map();
|
|
196119
197388
|
const offsetsCache = /* @__PURE__ */ new Map();
|
|
196120
197389
|
const assignedOffsets = /* @__PURE__ */ new Map();
|
|
@@ -196134,7 +197403,7 @@ function assignEdgeSides(nodes, edges, topDown = false, connectPointSpacing = CO
|
|
|
196134
197403
|
const requests = /* @__PURE__ */ new Map();
|
|
196135
197404
|
const requestPreference = /* @__PURE__ */ new Map();
|
|
196136
197405
|
const requestKey = (edge, role) => `${edge.id}|${role}`;
|
|
196137
|
-
const anchor = (node, side, preferred) => nextSideAnchor(sideCounts, offsetsCache, assignedOffsets, node, side, connectPointSpacing, demand, preferred);
|
|
197406
|
+
const anchor = (node, side, preferred) => naryHub(node) ? sideAnchorHandleId(side, 0.5) : nextSideAnchor(sideCounts, offsetsCache, assignedOffsets, node, side, connectPointSpacing, demand, preferred);
|
|
196138
197407
|
const diamondPreference = (node, side, dx, dy) => {
|
|
196139
197408
|
const shape = node.data.node?.shape;
|
|
196140
197409
|
if (shape !== "decision" && shape !== "merge") return void 0;
|
|
@@ -197107,6 +198376,45 @@ function successionFlowLabelPoint(centre, mark) {
|
|
|
197107
198376
|
y: markCoordinate(centre.y - mark.normal.y * 16)
|
|
197108
198377
|
};
|
|
197109
198378
|
}
|
|
198379
|
+
function flowDecorationsOf(edge) {
|
|
198380
|
+
const raw = edge.meta?.flowDecorations;
|
|
198381
|
+
if (!Array.isArray(raw)) return [];
|
|
198382
|
+
return raw.flatMap((entry) => {
|
|
198383
|
+
if (!entry || typeof entry !== "object") return [];
|
|
198384
|
+
const decoration = entry;
|
|
198385
|
+
return [{
|
|
198386
|
+
keyword: typeof decoration.keyword === "string" ? decoration.keyword : "flow",
|
|
198387
|
+
label: typeof decoration.label === "string" ? decoration.label : void 0,
|
|
198388
|
+
name: typeof decoration.name === "string" ? decoration.name : void 0,
|
|
198389
|
+
reversed: decoration.reversed === true
|
|
198390
|
+
}];
|
|
198391
|
+
});
|
|
198392
|
+
}
|
|
198393
|
+
var FLOW_DECORATION_STEP = 26;
|
|
198394
|
+
function flowDecorationGeometry(centre, points, source, target, index2, count, reversed) {
|
|
198395
|
+
const raw = midpointTangent(points?.length ? points : [source, target]) ?? { x: target.x - source.x, y: target.y - source.y };
|
|
198396
|
+
const length2 = Math.hypot(raw.x, raw.y);
|
|
198397
|
+
if (length2 <= 0) return void 0;
|
|
198398
|
+
const tangent = { x: raw.x / length2, y: raw.y / length2 };
|
|
198399
|
+
const normal = { x: -tangent.y, y: tangent.x };
|
|
198400
|
+
const shift = (index2 - (count - 1) / 2) * FLOW_DECORATION_STEP;
|
|
198401
|
+
const at = { x: centre.x + tangent.x * shift, y: centre.y + tangent.y * shift };
|
|
198402
|
+
const sign = reversed ? -1 : 1;
|
|
198403
|
+
const tip = { x: at.x + tangent.x * 5 * sign, y: at.y + tangent.y * 5 * sign };
|
|
198404
|
+
const back = { x: at.x - tangent.x * 4 * sign, y: at.y - tangent.y * 4 * sign };
|
|
198405
|
+
const corner = (side) => ({
|
|
198406
|
+
x: back.x + normal.x * 4 * side,
|
|
198407
|
+
y: back.y + normal.y * 4 * side
|
|
198408
|
+
});
|
|
198409
|
+
const wing = [corner(1), corner(-1)];
|
|
198410
|
+
return {
|
|
198411
|
+
chevron: [tip, wing[0], wing[1]].map((point) => `${markCoordinate(point.x)},${markCoordinate(point.y)}`).join(" "),
|
|
198412
|
+
label: {
|
|
198413
|
+
x: markCoordinate(at.x + normal.x * 13),
|
|
198414
|
+
y: markCoordinate(at.y + normal.y * 13)
|
|
198415
|
+
}
|
|
198416
|
+
};
|
|
198417
|
+
}
|
|
197110
198418
|
function routePointNearSource(points, source, target, distance2) {
|
|
197111
198419
|
const route = [source, ...points ?? [], target].filter((point, index2, all) => index2 === 0 || point.x !== all[index2 - 1].x || point.y !== all[index2 - 1].y);
|
|
197112
198420
|
let remaining = distance2;
|
|
@@ -197128,6 +198436,50 @@ function routePointNearSource(points, source, target, distance2) {
|
|
|
197128
198436
|
}
|
|
197129
198437
|
return void 0;
|
|
197130
198438
|
}
|
|
198439
|
+
function connectionEndLabelLines(edge, side, showMultiplicity) {
|
|
198440
|
+
const semanticRole = side === "from" ? edge.endRoleFrom : edge.endRoleTo;
|
|
198441
|
+
const multiplicity = side === "from" ? edge.endLabelFrom : edge.endLabelTo;
|
|
198442
|
+
let adornment = side === "from" ? edge.endAdornmentFrom : edge.endAdornmentTo;
|
|
198443
|
+
const namedPinEnd = side === "from" && (edge.meta?.connectionUsageEnd === true || edge.meta?.interfaceUsageEnd === true);
|
|
198444
|
+
if (namedPinEnd && semanticRole && adornment) {
|
|
198445
|
+
const impliedRedefinition = `redefines ${semanticRole}`;
|
|
198446
|
+
if (adornment === impliedRedefinition) {
|
|
198447
|
+
adornment = void 0;
|
|
198448
|
+
} else if (adornment.endsWith(` ${impliedRedefinition}`)) {
|
|
198449
|
+
adornment = adornment.slice(0, -(impliedRedefinition.length + 1)).trim() || void 0;
|
|
198450
|
+
}
|
|
198451
|
+
}
|
|
198452
|
+
const role = namedPinEnd ? void 0 : semanticRole;
|
|
198453
|
+
return [role, showMultiplicity ? multiplicity : void 0, adornment].filter((line2) => !!line2);
|
|
198454
|
+
}
|
|
198455
|
+
function connectionEndLabelPoint(points, source, target, side) {
|
|
198456
|
+
const reversed = side === "to" ? [...points ?? []].reverse() : points;
|
|
198457
|
+
const start2 = side === "to" ? target : source;
|
|
198458
|
+
const finish = side === "to" ? source : target;
|
|
198459
|
+
const near = routePointNearSource(reversed, start2, finish, 24);
|
|
198460
|
+
if (!near) return start2;
|
|
198461
|
+
return {
|
|
198462
|
+
x: markCoordinate(near.point.x - near.tangent.y * 12),
|
|
198463
|
+
y: markCoordinate(near.point.y + near.tangent.x * 12)
|
|
198464
|
+
};
|
|
198465
|
+
}
|
|
198466
|
+
function connectionElaborationGeometry(start2, target) {
|
|
198467
|
+
const cx = target.x + target.width / 2;
|
|
198468
|
+
const cy = target.y + target.height / 2;
|
|
198469
|
+
const dx = start2.x - cx;
|
|
198470
|
+
const dy = start2.y - cy;
|
|
198471
|
+
const scale = Math.max(
|
|
198472
|
+
Math.abs(dx) / Math.max(target.width / 2, 1),
|
|
198473
|
+
Math.abs(dy) / Math.max(target.height / 2, 1),
|
|
198474
|
+
1
|
|
198475
|
+
);
|
|
198476
|
+
const end = { x: cx + dx / scale, y: cy + dy / scale };
|
|
198477
|
+
return {
|
|
198478
|
+
start: start2,
|
|
198479
|
+
target: end,
|
|
198480
|
+
path: `M ${markCoordinate(start2.x)} ${markCoordinate(start2.y)} L ${markCoordinate(end.x)} ${markCoordinate(end.y)}`
|
|
198481
|
+
};
|
|
198482
|
+
}
|
|
197131
198483
|
function edgeLabelPoint(edge, centre, mark, points, source, target) {
|
|
197132
198484
|
const branchLabel = edge.kind === "succession" && (edge.label === "else" || /^\[.*\]$/u.test(edge.label ?? ""));
|
|
197133
198485
|
if (!branchLabel) return successionFlowLabelPoint(centre, mark);
|
|
@@ -197270,13 +198622,25 @@ function treeFacingDock(node, other, byId) {
|
|
|
197270
198622
|
const normal = otherCentre.y >= centre.y ? DOCK_NORMAL.bottom : DOCK_NORMAL.top;
|
|
197271
198623
|
return { point: { x: centre.x, y: centre.y + normal.y * h / 2 }, normal };
|
|
197272
198624
|
}
|
|
198625
|
+
function naryFacingDock(node, other, byId) {
|
|
198626
|
+
const from = nodeCentre(node, byId);
|
|
198627
|
+
const to = nodeCentre(other, byId);
|
|
198628
|
+
const dx = to.x - from.x;
|
|
198629
|
+
const dy = to.y - from.y;
|
|
198630
|
+
const side = Math.abs(dx) >= Math.abs(dy) ? dx >= 0 ? "right" : "left" : dy >= 0 ? "bottom" : "top";
|
|
198631
|
+
return dockPoint(node, sideAnchorHandleId(side, 0.5), byId, from);
|
|
198632
|
+
}
|
|
198633
|
+
function isNaryConnectionHub(node) {
|
|
198634
|
+
return node?.data.node?.shape === "dot" && node.data.node.meta?.naryConnectionHub === true;
|
|
198635
|
+
}
|
|
197273
198636
|
function bundleCandidateFor(edge, byId) {
|
|
197274
198637
|
const semantic = edge.data?.edge;
|
|
197275
198638
|
const sourceNode = byId.get(edge.source);
|
|
197276
198639
|
const targetNode = byId.get(edge.target);
|
|
197277
198640
|
if (!semantic || !sourceNode || !targetNode) return void 0;
|
|
197278
|
-
const
|
|
197279
|
-
const
|
|
198641
|
+
const naryRole = semantic.kind === "connect" ? isNaryConnectionHub(sourceNode) ? "source" : isNaryConnectionHub(targetNode) ? "target" : void 0 : void 0;
|
|
198642
|
+
const sourceFallback = naryRole ? naryFacingDock(sourceNode, targetNode, byId) : treeFacingDock(sourceNode, targetNode, byId);
|
|
198643
|
+
const targetFallback = naryRole ? naryFacingDock(targetNode, sourceNode, byId) : treeFacingDock(targetNode, sourceNode, byId);
|
|
197280
198644
|
const explicitSource = dockPoint(sourceNode, edge.sourceHandle, byId, sourceFallback.point);
|
|
197281
198645
|
const explicitTarget = dockPoint(targetNode, edge.targetHandle, byId, targetFallback.point);
|
|
197282
198646
|
const source = explicitSource.normal ? explicitSource : sourceFallback;
|
|
@@ -197299,7 +198663,8 @@ function bundleCandidateFor(edge, byId) {
|
|
|
197299
198663
|
// remaining separate semantic edges. Once one connector owns manual
|
|
197300
198664
|
// waypoints it deliberately leaves that automatic fan and keeps its
|
|
197301
198665
|
// individually movable route.
|
|
197302
|
-
eligible: edge.data?.kind === "gv" && GV_BUS_EDGE_KINDS.has(semantic.kind) &&
|
|
198666
|
+
eligible: edge.source !== edge.target && !edge.data?.route?.length && (naryRole !== void 0 || edge.data?.kind === "gv" && GV_BUS_EDGE_KINDS.has(semantic.kind) && !isPortDocked(edge.sourceHandle) && !isPortDocked(edge.targetHandle)),
|
|
198667
|
+
...naryRole ? { eligibleRole: naryRole } : {}
|
|
197303
198668
|
};
|
|
197304
198669
|
}
|
|
197305
198670
|
function movingNodeIds(nodes, byId) {
|
|
@@ -197472,7 +198837,7 @@ function edgeBundles(nodes, edges, runtime = defaultBundleRuntime) {
|
|
|
197472
198837
|
function projectedBundleMember(edge) {
|
|
197473
198838
|
return edge.data?.bundleMember;
|
|
197474
198839
|
}
|
|
197475
|
-
function
|
|
198840
|
+
function projectAutomaticBusRenderEdges(nodes, semanticEdges, runtime) {
|
|
197476
198841
|
const bundles = edgeBundles(nodes, semanticEdges, runtime);
|
|
197477
198842
|
if (!bundles.size) return semanticEdges;
|
|
197478
198843
|
return semanticEdges.map((edge) => {
|
|
@@ -198079,6 +199444,13 @@ body {
|
|
|
198079
199444
|
.dlink { stroke: var(--diagram-line-structural); stroke-width: 1.2; fill: none; }
|
|
198080
199445
|
.dlink.successionFlow { stroke-width: 2; }
|
|
198081
199446
|
.dsuccession-flow-mark { pointer-events: none; stroke-linecap: butt; }
|
|
199447
|
+
/* REQ-401 \u2014 OMG 8.2.3.16 flow-on-connection: the payload chevron rides the
|
|
199448
|
+
connector that transports it, in the item-flow hue, and never takes pointer
|
|
199449
|
+
events away from the connector it decorates. */
|
|
199450
|
+
.dflow-decoration {
|
|
199451
|
+
pointer-events: none; stroke: none;
|
|
199452
|
+
fill: var(--diagram-line-connection, #6cd1d9);
|
|
199453
|
+
}
|
|
198082
199454
|
/* REQ-196: AFV control transitions (IR succession) use a dotted route so
|
|
198083
199455
|
they remain visually distinct from continuous item and succession flows. */
|
|
198084
199456
|
.dlink.succession { stroke-dasharray: 1 3; stroke-linecap: round; }
|
|
@@ -198086,6 +199458,7 @@ body {
|
|
|
198086
199458
|
/* REQ-186/188/189/199/206/210 \u2014 the dashed labelled families */
|
|
198087
199459
|
.dlink.allocate, .dlink.frame, .dlink.derive, .dlink.causation, .dlink.import, .dlink.expose { stroke-dasharray: 4 3; }
|
|
198088
199460
|
.dlink.annotation { stroke-dasharray: 2 3; }
|
|
199461
|
+
.dlink.elaboration { stroke-dasharray: 2 3; pointer-events: none; }
|
|
198089
199462
|
.dlink.reply { stroke-dasharray: 4 3; } /* REQ-202 \u2014 sequence reply arrows */
|
|
198090
199463
|
/* issue #84 \u2014 REQ-202: a message is dragged up/down to change WHEN it happens.
|
|
198091
199464
|
The grip is the invisible hit band over the arrow (a row-resize cursor is the
|
|
@@ -198124,6 +199497,15 @@ body {
|
|
|
198124
199497
|
* on rather than the flow colour (user direction 2026-08-09). Its rounded corners and its
|
|
198125
199498
|
* direction arrow come from the shared port path in nodes.tsx. */
|
|
198126
199499
|
.dnode-port.pin { fill: var(--element-fill); stroke: var(--element-outline); stroke-width: 1.2; }
|
|
199500
|
+
/* REQ-192 - explicit connection ends are outline-coloured endpoint dots, not
|
|
199501
|
+
* action-pin boxes. The dot itself is the persistent snap affordance. */
|
|
199502
|
+
.dconnection-end-dot { fill: var(--element-outline); stroke: var(--element-outline); stroke-width: 1.2; }
|
|
199503
|
+
.dconnection-end-dot.selected { fill: var(--accent); stroke: var(--accent); }
|
|
199504
|
+
.rf-node.selected .dnode-control.dot { fill: var(--accent); stroke: var(--accent); }
|
|
199505
|
+
.dconnection-end-dot.hovered, .dconnection-end-dot.connect-target {
|
|
199506
|
+
fill: var(--cyan); stroke: var(--cyan); filter: drop-shadow(0 0 3px var(--cyan));
|
|
199507
|
+
}
|
|
199508
|
+
.dconnection-end-dot.moving { fill: var(--accent); stroke: var(--accent); filter: drop-shadow(0 0 4px var(--accent)); }
|
|
198127
199509
|
/* REQ-194 \u2014 the port direction ARROW: a shaft across the glyph with a solid head
|
|
198128
199510
|
* at each directed end (--> out, <-- in, <-> inout), per OMG 8.2.3.12.
|
|
198129
199511
|
* NOTE: no backticks in this file's CSS \u2014 STYLE is a template literal. */
|
|
@@ -198288,15 +199670,19 @@ body {
|
|
|
198288
199670
|
/* REQ-205 \u2014 Geometry View 3D (isometric) shapes + ground frame */
|
|
198289
199671
|
.dgeo3d-grid { stroke-width: 1; opacity: 0.35; }
|
|
198290
199672
|
.dgeo3d-face { stroke: var(--element-outline); stroke-width: 1; stroke-linejoin: round; }
|
|
198291
|
-
.dgeo3d-face.top { fill: var(--element-fill); fill-opacity: 0.
|
|
198292
|
-
.dgeo3d-face.side { fill: var(--element-fill); fill-opacity: 0.
|
|
198293
|
-
.dgeo3d-face.side2 { fill: var(--element-fill); fill-opacity: 0.
|
|
199673
|
+
.dgeo3d-face.top { fill: var(--element-fill); fill-opacity: 0.42; }
|
|
199674
|
+
.dgeo3d-face.side { fill: var(--element-fill); fill-opacity: 0.28; }
|
|
199675
|
+
.dgeo3d-face.side2 { fill: var(--element-fill); fill-opacity: 0.18; }
|
|
198294
199676
|
.dgeo3d-edge { stroke: var(--element-outline); stroke-width: 1; opacity: 0.7; }
|
|
198295
199677
|
.dgeo3d-node { cursor: pointer; }
|
|
198296
199678
|
.dgeo3d-node:hover .dgeo3d-face { fill-opacity: 0.42; }
|
|
198297
199679
|
.dgeo3d-node.selected .dgeo3d-face { stroke: var(--accent); }
|
|
198298
199680
|
.dgeo3d-node.selected .dgeo3d-face.top { fill: var(--accent); fill-opacity: 0.34; }
|
|
198299
|
-
.dgeo3d-name {
|
|
199681
|
+
.dgeo3d-name {
|
|
199682
|
+
fill: var(--fg-0); stroke: var(--diagram-canvas); stroke-width: 3px;
|
|
199683
|
+
paint-order: stroke fill; stroke-linejoin: round;
|
|
199684
|
+
font-family: var(--font-mono); font-size: 10px;
|
|
199685
|
+
}
|
|
198300
199686
|
/* REQ-205 \u2014 an object whose coordinate-frame transformation could not be fully
|
|
198301
199687
|
decided is DRAWN and MARKED, never silently misplaced: its outline goes dashed
|
|
198302
199688
|
and it carries a warning glyph whose tooltip names the reason. (The issue
|
|
@@ -198873,14 +200259,17 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
198873
200259
|
* Each 5px dot has a compact hit box and can start or end a connector. The chosen
|
|
198874
200260
|
* handle is the chosen dock point, while the central body stays selectable. */
|
|
198875
200261
|
.react-flow__handle.rf-handle-port { width: ${PORT_CONNECT_DOT_HIT}px; height: ${PORT_CONNECT_DOT_HIT}px; --rf-dot-size: 5px; z-index: 6; }
|
|
200262
|
+
.react-flow__handle.rf-handle-connection-end { width: 12px; height: 12px; z-index: 6; }
|
|
200263
|
+
.react-flow__handle.rf-handle-connection-end::after { display: none; }
|
|
198876
200264
|
.react-flow__handle.rf-handle-side { width: ${BODY_SNAP_POINT_HIT_SIZE}px; height: ${BODY_SNAP_POINT_HIT_SIZE}px; --rf-dot-size: 5px; z-index: 2; }
|
|
198877
200265
|
/* REQ-370: body snap points are hollow circles. Port and pin endpoints are
|
|
198878
200266
|
* solid squares, so adjacent targets cannot be mistaken for each other. */
|
|
198879
200267
|
.react-flow__handle.rf-handle-side::after { background: var(--bg-1); border: 1.5px solid var(--cyan); }
|
|
198880
200268
|
.react-flow__handle.rf-handle-port::after { border-radius: 1px; }
|
|
198881
|
-
/* The start
|
|
198882
|
-
* even though four 12px handle targets meet over these
|
|
198883
|
-
* perimeter dots remain above the rest of the node and
|
|
200269
|
+
/* The start, done, and n-ary hub centre stays available for normal node
|
|
200270
|
+
* selection and dragging even though four 12px handle targets meet over these
|
|
200271
|
+
* exact-size glyphs. The perimeter dots remain above the rest of the node and
|
|
200272
|
+
* keep their full hit area. */
|
|
198884
200273
|
.rf-circular-control-hit {
|
|
198885
200274
|
position: absolute; left: 50%; top: 50%; width: 50%; height: 50%;
|
|
198886
200275
|
transform: translate(-50%, -50%); border-radius: 50%;
|
|
@@ -198894,6 +200283,7 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
198894
200283
|
.react-flow.sysml-connecting .react-flow__handle.rf-handle-side.connectionindicator,
|
|
198895
200284
|
.react-flow.sysml-connecting .react-flow__handle.rf-handle-lifeline.connectionindicator { opacity: 0.42; }
|
|
198896
200285
|
.react-flow.sysml-connecting .react-flow__handle.rf-handle-port.connectionindicator { opacity: 0.42; }
|
|
200286
|
+
.react-flow.sysml-connecting .react-flow__handle.rf-handle-connection-end.connectionindicator { opacity: 0.42; }
|
|
198897
200287
|
.react-flow.sysml-connecting .react-flow__handle.rf-handle-port.active { opacity: 1; }
|
|
198898
200288
|
/* The nearest semantically valid body target is stronger than the candidate
|
|
198899
200289
|
* points. Port and pin targets use the highlighted endpoint glyph instead. */
|
|
@@ -199044,6 +200434,9 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
199044
200434
|
.rf-edge-label { position: absolute; pointer-events: none; font-family: var(--font-mono); font-size: 9px;
|
|
199045
200435
|
color: var(--fg-0); background: transparent; border: 0; padding: 0; white-space: nowrap; }
|
|
199046
200436
|
.rf-edge-label.mult { background: transparent; border: 0; color: var(--fg-2); padding: 0; }
|
|
200437
|
+
.rf-edge-label.connection-end { color: var(--fg-1); display: flex; flex-direction: column;
|
|
200438
|
+
line-height: 1.15; text-align: center; white-space: nowrap; }
|
|
200439
|
+
.rf-edge-label.connection-end span:nth-child(n+2) { color: var(--fg-2); }
|
|
199047
200440
|
|
|
199048
200441
|
/* REQ-366/386 \u2014 two adjacent, independent container presentation controls.
|
|
199049
200442
|
* +/\u2212 owns graphical internals; the outlined list owns textual feature
|
|
@@ -199126,6 +200519,11 @@ function labelExtent(text) {
|
|
|
199126
200519
|
function labelSvg(text, x, y, cls) {
|
|
199127
200520
|
return `<text class="${cls}" x="${Math.round(x)}" y="${Math.round(y)}" text-anchor="middle" dominant-baseline="central">${escapeXml(text)}</text>`;
|
|
199128
200521
|
}
|
|
200522
|
+
function multilineLabelSvg(lines, x, y, cls) {
|
|
200523
|
+
const firstY = y - (lines.length - 1) * 5.5;
|
|
200524
|
+
const spans = lines.map((line2, index2) => `<tspan x="${Math.round(x)}" dy="${index2 === 0 ? 0 : 11}">${escapeXml(line2)}</tspan>`).join("");
|
|
200525
|
+
return `<text class="${cls}" x="${Math.round(x)}" y="${Math.round(firstY)}" text-anchor="middle" dominant-baseline="central">${spans}</text>`;
|
|
200526
|
+
}
|
|
199129
200527
|
function buildDiagramSvg(options) {
|
|
199130
200528
|
const { nodes, edges, lineStyle, nodeMarkup } = options;
|
|
199131
200529
|
if (!nodes.length) return null;
|
|
@@ -199204,6 +200602,22 @@ function buildDiagramSvg(options) {
|
|
|
199204
200602
|
const markerStart = style2.markerStart ? ` marker-start="${style2.markerStart}"` : "";
|
|
199205
200603
|
const markerEnd = style2.markerEnd ? ` marker-end="${style2.markerEnd}"` : "";
|
|
199206
200604
|
edgeParts.push(`<path class="${style2.className}" d="${geometry.path}"${markerStart}${markerEnd}/>`);
|
|
200605
|
+
if (semantic?.elaboration) {
|
|
200606
|
+
const targetNode = byId.get(semantic.elaboration);
|
|
200607
|
+
if (targetNode) {
|
|
200608
|
+
const position = absolutePos(targetNode.id, byId);
|
|
200609
|
+
const size = sizeOf(targetNode);
|
|
200610
|
+
const elaboration = connectionElaborationGeometry(geometry.label, {
|
|
200611
|
+
x: position.x,
|
|
200612
|
+
y: position.y,
|
|
200613
|
+
width: size.w,
|
|
200614
|
+
height: size.h
|
|
200615
|
+
});
|
|
200616
|
+
edgeParts.push(`<path class="dlink elaboration" d="${elaboration.path}"/>`);
|
|
200617
|
+
extendPoint(elaboration.start.x, elaboration.start.y, 2);
|
|
200618
|
+
extendPoint(elaboration.target.x, elaboration.target.y, 2);
|
|
200619
|
+
}
|
|
200620
|
+
}
|
|
199207
200621
|
const sequencingMark = successionFlowMarkGeometry(
|
|
199208
200622
|
style2,
|
|
199209
200623
|
geometry.label,
|
|
@@ -199216,6 +200630,24 @@ function buildDiagramSvg(options) {
|
|
|
199216
200630
|
extendPoint(sequencingMark.x1, sequencingMark.y1, 2);
|
|
199217
200631
|
extendPoint(sequencingMark.x2, sequencingMark.y2, 2);
|
|
199218
200632
|
}
|
|
200633
|
+
const decorations = semantic ? flowDecorationsOf(semantic) : [];
|
|
200634
|
+
decorations.forEach((decoration, index2) => {
|
|
200635
|
+
const placement = flowDecorationGeometry(
|
|
200636
|
+
geometry.label,
|
|
200637
|
+
geometry.points ?? geometry.anchors,
|
|
200638
|
+
geometry.source,
|
|
200639
|
+
geometry.target,
|
|
200640
|
+
index2,
|
|
200641
|
+
decorations.length,
|
|
200642
|
+
decoration.reversed === true
|
|
200643
|
+
);
|
|
200644
|
+
if (!placement) return;
|
|
200645
|
+
edgeParts.push(`<polygon class="dflow-decoration ${decoration.keyword.replace(/\s+/gu, "-")}" points="${placement.chevron}"/>`);
|
|
200646
|
+
const text = [decoration.name, decoration.label].filter(Boolean).join(" : ");
|
|
200647
|
+
if (!text) return;
|
|
200648
|
+
labelParts.push(labelSvg(text, placement.label.x, placement.label.y, "elabel flow"));
|
|
200649
|
+
extendLabel(text, placement.label.x, placement.label.y);
|
|
200650
|
+
});
|
|
199219
200651
|
extendPoint(geometry.source.x, geometry.source.y, MARKER_ALLOWANCE);
|
|
199220
200652
|
extendPoint(geometry.target.x, geometry.target.y, MARKER_ALLOWANCE);
|
|
199221
200653
|
for (const point of geometry.points ?? geometry.anchors) extendPoint(point.x, point.y, MARKER_ALLOWANCE);
|
|
@@ -199231,14 +200663,22 @@ function buildDiagramSvg(options) {
|
|
|
199231
200663
|
labelParts.push(labelSvg(semantic.label, labelPoint.x, labelPoint.y, `elabel ${semantic.kind}`));
|
|
199232
200664
|
extendLabel(semantic.label, labelPoint.x, labelPoint.y);
|
|
199233
200665
|
}
|
|
199234
|
-
if (
|
|
199235
|
-
|
|
199236
|
-
|
|
199237
|
-
|
|
199238
|
-
|
|
199239
|
-
|
|
199240
|
-
|
|
199241
|
-
|
|
200666
|
+
if (semantic) {
|
|
200667
|
+
for (const side of ["from", "to"]) {
|
|
200668
|
+
const lines = connectionEndLabelLines(semantic, side, edge.data?.showMult === true);
|
|
200669
|
+
if (!lines.length) continue;
|
|
200670
|
+
const point = connectionEndLabelPoint(
|
|
200671
|
+
geometry.points ?? geometry.anchors,
|
|
200672
|
+
geometry.source,
|
|
200673
|
+
geometry.target,
|
|
200674
|
+
side
|
|
200675
|
+
);
|
|
200676
|
+
const role = side === "from" ? semantic.endRoleFrom : semantic.endRoleTo;
|
|
200677
|
+
const adornment = side === "from" ? semantic.endAdornmentFrom : semantic.endAdornmentTo;
|
|
200678
|
+
labelParts.push(!role && !adornment && lines.length === 1 ? labelSvg(lines[0], point.x, point.y, "elabel mult") : multilineLabelSvg(lines, point.x, point.y, "elabel connection-end"));
|
|
200679
|
+
const widest = lines.reduce((longest, line2) => line2.length > longest.length ? line2 : longest, "");
|
|
200680
|
+
extendLabel(widest, point.x, point.y);
|
|
200681
|
+
extendPoint(point.x, point.y, lines.length * 6);
|
|
199242
200682
|
}
|
|
199243
200683
|
}
|
|
199244
200684
|
}
|
|
@@ -199707,6 +201147,7 @@ var TOOLBOX = {
|
|
|
199707
201147
|
elements: [
|
|
199708
201148
|
el("part", "part", "\u25A2"),
|
|
199709
201149
|
el("port", "port", "\u25AB"),
|
|
201150
|
+
el("connection", "connection", "\u25AD"),
|
|
199710
201151
|
el("attribute", "attribute", "\u2013"),
|
|
199711
201152
|
el("item", "item", "\u25C7"),
|
|
199712
201153
|
el("constraint", "constraint", "{}"),
|
|
@@ -199871,7 +201312,7 @@ var COMMON_USAGE_KINDS = [
|
|
|
199871
201312
|
var CASE_CHILDREN = ["subject", "actor", "part", "attribute", "action", "item", "requirement"];
|
|
199872
201313
|
var CHILD_KINDS = {
|
|
199873
201314
|
package: ["package", ...DEFINITION_KINDS, ...COMMON_USAGE_KINDS],
|
|
199874
|
-
part: ["part", "attribute", "port", "item", "constraint", "action", "state", "calc", "occurrence"],
|
|
201315
|
+
part: ["part", "attribute", "port", "item", "connection", "constraint", "action", "state", "calc", "occurrence"],
|
|
199875
201316
|
item: ["attribute", "port", "part", "item"],
|
|
199876
201317
|
// REQ-006/REQ-192 — a port owns the features that describe what crosses
|
|
199877
201318
|
// its boundary. Keep the direction in the creation choice so an IV user
|
|
@@ -199976,6 +201417,7 @@ function isWritableRelationEndpoint(endpoint) {
|
|
|
199976
201417
|
}
|
|
199977
201418
|
function directRelationForHandle(viewKind, endpoint) {
|
|
199978
201419
|
if (!endpoint || !isWritableRelationEndpoint(endpoint)) return void 0;
|
|
201420
|
+
if (viewKind === "iv" && (endpoint.connectionEnd || normalizedElementKeyword(endpoint.keyword).base === "connection end")) return "connectionEnd";
|
|
199979
201421
|
return relationToolsForNode(endpoint.keyword, viewKind, endpoint.shape).find((tool) => tool.kind !== "terminate" && tool.kind !== "finish")?.kind;
|
|
199980
201422
|
}
|
|
199981
201423
|
var START_PSEUDOSTATE_BASES = /* @__PURE__ */ new Set(["start", "initial"]);
|
|
@@ -200066,6 +201508,65 @@ function relationToolsForNode(keyword, viewKind, shape) {
|
|
|
200066
201508
|
var import_react7 = __toESM(require_react());
|
|
200067
201509
|
var import_jsx_runtime3 = __toESM(require_jsx_runtime());
|
|
200068
201510
|
var ptStr = (pts) => pts.map((p) => `${p[0].toFixed(1)},${p[1].toFixed(1)}`).join(" ");
|
|
201511
|
+
var GEO_VIEW_DIRECTION = [1, 1, 1];
|
|
201512
|
+
function dot3(a2, b) {
|
|
201513
|
+
return a2[0] * b[0] + a2[1] * b[1] + a2[2] * b[2];
|
|
201514
|
+
}
|
|
201515
|
+
function cross3(a2, b) {
|
|
201516
|
+
return [
|
|
201517
|
+
a2[1] * b[2] - a2[2] * b[1],
|
|
201518
|
+
a2[2] * b[0] - a2[0] * b[2],
|
|
201519
|
+
a2[0] * b[1] - a2[1] * b[0]
|
|
201520
|
+
];
|
|
201521
|
+
}
|
|
201522
|
+
function subtract3(a2, b) {
|
|
201523
|
+
return [a2[0] - b[0], a2[1] - b[1], a2[2] - b[2]];
|
|
201524
|
+
}
|
|
201525
|
+
function convexHull(points) {
|
|
201526
|
+
const sorted = [...points].sort((a2, b) => a2[0] - b[0] || a2[1] - b[1]);
|
|
201527
|
+
if (sorted.length <= 2) return sorted;
|
|
201528
|
+
const turn = (a2, b, c) => (b[0] - a2[0]) * (c[1] - a2[1]) - (b[1] - a2[1]) * (c[0] - a2[0]);
|
|
201529
|
+
const half = (input) => {
|
|
201530
|
+
const result = [];
|
|
201531
|
+
for (const point of input) {
|
|
201532
|
+
while (result.length >= 2 && turn(result.at(-2), result.at(-1), point) <= 0) result.pop();
|
|
201533
|
+
result.push(point);
|
|
201534
|
+
}
|
|
201535
|
+
return result;
|
|
201536
|
+
};
|
|
201537
|
+
const lower2 = half(sorted);
|
|
201538
|
+
const upper = half([...sorted].reverse());
|
|
201539
|
+
return [...lower2.slice(0, -1), ...upper.slice(0, -1)];
|
|
201540
|
+
}
|
|
201541
|
+
function polyhedronBody(node, f, localVertices, faces) {
|
|
201542
|
+
const g = node.geo;
|
|
201543
|
+
const center = geoWorldPoint(g, [0, 0, 0]);
|
|
201544
|
+
const world = localVertices.map((point) => geoWorldPoint(g, point));
|
|
201545
|
+
const visible = faces.flatMap((face, index2) => {
|
|
201546
|
+
let points = face.map((vertex) => world[vertex]);
|
|
201547
|
+
let normal = cross3(subtract3(points[1], points[0]), subtract3(points[2], points[0]));
|
|
201548
|
+
const faceCenter = [
|
|
201549
|
+
points.reduce((sum, point) => sum + point[0], 0) / points.length,
|
|
201550
|
+
points.reduce((sum, point) => sum + point[1], 0) / points.length,
|
|
201551
|
+
points.reduce((sum, point) => sum + point[2], 0) / points.length
|
|
201552
|
+
];
|
|
201553
|
+
if (dot3(normal, subtract3(faceCenter, center)) < 0) {
|
|
201554
|
+
points = [...points].reverse();
|
|
201555
|
+
normal = [-normal[0], -normal[1], -normal[2]];
|
|
201556
|
+
}
|
|
201557
|
+
const normalLength = Math.hypot(normal[0], normal[1], normal[2]);
|
|
201558
|
+
if (normalLength === 0 || dot3(normal, GEO_VIEW_DIRECTION) / (normalLength * Math.sqrt(3)) <= 1e-9) return [];
|
|
201559
|
+
const absolute = normal.map(Math.abs);
|
|
201560
|
+
const faceClass = absolute[2] >= absolute[0] && absolute[2] >= absolute[1] && normal[2] > 0 ? "top" : absolute[0] >= absolute[1] ? "side2" : "side";
|
|
201561
|
+
return [{
|
|
201562
|
+
key: index2,
|
|
201563
|
+
faceClass,
|
|
201564
|
+
depth: points.reduce((sum, point) => sum + dot3(point, GEO_VIEW_DIRECTION), 0) / points.length,
|
|
201565
|
+
points: points.map((point) => geoProject(f, point[0], point[1], point[2]))
|
|
201566
|
+
}];
|
|
201567
|
+
}).sort((a2, b) => a2.depth - b.depth);
|
|
201568
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("g", { children: visible.map((face) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polygon", { className: `dgeo3d-face ${face.faceClass}`, points: ptStr(face.points) }, face.key)) });
|
|
201569
|
+
}
|
|
200069
201570
|
var GEO_HANDLE_POSITION = {
|
|
200070
201571
|
top: Position3.Top,
|
|
200071
201572
|
right: Position3.Right,
|
|
@@ -200188,15 +201689,16 @@ function IsoAxes({ f, marker }) {
|
|
|
200188
201689
|
}
|
|
200189
201690
|
function geoShapeBody(node, f) {
|
|
200190
201691
|
const g = node.geo;
|
|
200191
|
-
const
|
|
201692
|
+
const { hx, hy, hz } = geoHalfExtentsOf(node, f.def);
|
|
200192
201693
|
const P = (x, y, z2) => geoProject(f, x, y, z2);
|
|
200193
|
-
const
|
|
200194
|
-
|
|
200195
|
-
|
|
201694
|
+
const PL = (point) => {
|
|
201695
|
+
const world = geoWorldPoint(g, point);
|
|
201696
|
+
return P(world[0], world[1], world[2]);
|
|
201697
|
+
};
|
|
200196
201698
|
switch (g.shape) {
|
|
200197
201699
|
case "sphere": {
|
|
200198
|
-
const c =
|
|
200199
|
-
const pts =
|
|
201700
|
+
const c = PL([0, 0, 0]);
|
|
201701
|
+
const pts = geoShapePoints(node, f.def).map((point) => P(point[0], point[1], point[2]));
|
|
200200
201702
|
const r = Math.max(...pts.map((p) => Math.hypot(p[0] - c[0], p[1] - c[1])));
|
|
200201
201703
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("g", { children: [
|
|
200202
201704
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { className: "dgeo3d-face top", cx: c[0], cy: c[1], r }),
|
|
@@ -200205,64 +201707,79 @@ function geoShapeBody(node, f) {
|
|
|
200205
201707
|
}
|
|
200206
201708
|
case "cylinder":
|
|
200207
201709
|
case "cone": {
|
|
200208
|
-
const
|
|
200209
|
-
const
|
|
200210
|
-
|
|
200211
|
-
|
|
200212
|
-
|
|
200213
|
-
|
|
200214
|
-
|
|
200215
|
-
const base = exr(zlo);
|
|
201710
|
+
const ring = (z2) => Array.from({ length: 32 }, (_2, index2) => {
|
|
201711
|
+
const angle = index2 * Math.PI / 16;
|
|
201712
|
+
return [hx * Math.cos(angle), hy * Math.sin(angle), z2];
|
|
201713
|
+
});
|
|
201714
|
+
const baseLocal = ring(-hz);
|
|
201715
|
+
const baseWorld = baseLocal.map((point) => geoWorldPoint(g, point));
|
|
201716
|
+
const base = baseWorld.map((point) => P(point[0], point[1], point[2]));
|
|
200216
201717
|
if (g.shape === "cone") {
|
|
200217
|
-
const
|
|
201718
|
+
const apexWorld = geoWorldPoint(g, [0, 0, hz]);
|
|
201719
|
+
const apex = P(apexWorld[0], apexWorld[1], apexWorld[2]);
|
|
201720
|
+
const baseCenter = geoWorldPoint(g, [0, 0, -hz]);
|
|
201721
|
+
const baseVisible = dot3(baseCenter, GEO_VIEW_DIRECTION) > dot3(apexWorld, GEO_VIEW_DIRECTION);
|
|
200218
201722
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("g", { children: [
|
|
200219
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("
|
|
200220
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polygon", { className: "dgeo3d-face
|
|
200221
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ellipse", { className: "dgeo3d-edge", cx: base.c[0], cy: base.c[1], rx: base.rx, ry: base.ry, fill: "none" })
|
|
201723
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polygon", { className: "dgeo3d-face side", points: ptStr(convexHull([...base, apex])) }),
|
|
201724
|
+
baseVisible ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polygon", { className: "dgeo3d-face top", points: ptStr(base) }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polyline", { className: "dgeo3d-edge", points: ptStr([...base, base[0]]), fill: "none", strokeDasharray: "3 3" })
|
|
200222
201725
|
] });
|
|
200223
201726
|
}
|
|
200224
|
-
const
|
|
201727
|
+
const topLocal = ring(hz);
|
|
201728
|
+
const topWorld = topLocal.map((point) => geoWorldPoint(g, point));
|
|
201729
|
+
const top = topWorld.map((point) => P(point[0], point[1], point[2]));
|
|
201730
|
+
const baseDepth = dot3(geoWorldPoint(g, [0, 0, -hz]), GEO_VIEW_DIRECTION);
|
|
201731
|
+
const topDepth = dot3(geoWorldPoint(g, [0, 0, hz]), GEO_VIEW_DIRECTION);
|
|
201732
|
+
const near = topDepth >= baseDepth ? top : base;
|
|
201733
|
+
const far = topDepth >= baseDepth ? base : top;
|
|
200225
201734
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("g", { children: [
|
|
200226
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("
|
|
200227
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("
|
|
200228
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("
|
|
201735
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polygon", { className: "dgeo3d-face side", points: ptStr(convexHull([...base, ...top])) }),
|
|
201736
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polyline", { className: "dgeo3d-edge", points: ptStr([...far, far[0]]), fill: "none", strokeDasharray: "3 3" }),
|
|
201737
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polygon", { className: "dgeo3d-face top", points: ptStr(near) })
|
|
200229
201738
|
] });
|
|
200230
201739
|
}
|
|
200231
201740
|
case "pyramid": {
|
|
200232
|
-
const
|
|
200233
|
-
|
|
200234
|
-
|
|
200235
|
-
|
|
200236
|
-
|
|
200237
|
-
|
|
200238
|
-
|
|
200239
|
-
|
|
200240
|
-
] });
|
|
201741
|
+
const vertices = [
|
|
201742
|
+
[-hx, -hy, -hz],
|
|
201743
|
+
[hx, -hy, -hz],
|
|
201744
|
+
[hx, hy, -hz],
|
|
201745
|
+
[-hx, hy, -hz],
|
|
201746
|
+
[0, 0, hz]
|
|
201747
|
+
];
|
|
201748
|
+
return polyhedronBody(node, f, vertices, [[0, 3, 2, 1], [0, 1, 4], [1, 2, 4], [2, 3, 4], [3, 0, 4]]);
|
|
200241
201749
|
}
|
|
200242
201750
|
case "wedge": {
|
|
200243
|
-
const
|
|
200244
|
-
|
|
200245
|
-
|
|
200246
|
-
|
|
200247
|
-
|
|
200248
|
-
|
|
200249
|
-
|
|
200250
|
-
|
|
200251
|
-
|
|
200252
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polygon", { className: "dgeo3d-face side", points: ptStr([bul, bur, rb]) })
|
|
200253
|
-
] });
|
|
201751
|
+
const vertices = [
|
|
201752
|
+
[-hx, -hy, -hz],
|
|
201753
|
+
[hx, -hy, -hz],
|
|
201754
|
+
[hx, hy, -hz],
|
|
201755
|
+
[-hx, hy, -hz],
|
|
201756
|
+
[0, -hy, hz],
|
|
201757
|
+
[0, hy, hz]
|
|
201758
|
+
];
|
|
201759
|
+
return polyhedronBody(node, f, vertices, [[0, 3, 2, 1], [0, 1, 4], [1, 2, 5, 4], [2, 3, 5], [3, 0, 4, 5]]);
|
|
200254
201760
|
}
|
|
200255
201761
|
case "box": {
|
|
200256
|
-
const
|
|
200257
|
-
|
|
200258
|
-
|
|
200259
|
-
|
|
200260
|
-
|
|
200261
|
-
|
|
200262
|
-
|
|
201762
|
+
const vertices = [
|
|
201763
|
+
[-hx, -hy, -hz],
|
|
201764
|
+
[hx, -hy, -hz],
|
|
201765
|
+
[hx, hy, -hz],
|
|
201766
|
+
[-hx, hy, -hz],
|
|
201767
|
+
[-hx, -hy, hz],
|
|
201768
|
+
[hx, -hy, hz],
|
|
201769
|
+
[hx, hy, hz],
|
|
201770
|
+
[-hx, hy, hz]
|
|
201771
|
+
];
|
|
201772
|
+
return polyhedronBody(node, f, vertices, [
|
|
201773
|
+
[0, 3, 2, 1],
|
|
201774
|
+
[4, 5, 6, 7],
|
|
201775
|
+
[0, 1, 5, 4],
|
|
201776
|
+
[1, 2, 6, 5],
|
|
201777
|
+
[2, 3, 7, 6],
|
|
201778
|
+
[3, 0, 4, 7]
|
|
201779
|
+
]);
|
|
200263
201780
|
}
|
|
200264
201781
|
default: {
|
|
200265
|
-
const q = [
|
|
201782
|
+
const q = [PL([-hx, -hy, 0]), PL([hx, -hy, 0]), PL([hx, hy, 0]), PL([-hx, hy, 0])];
|
|
200266
201783
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polygon", { className: "dgeo3d-face top", points: ptStr(q) });
|
|
200267
201784
|
}
|
|
200268
201785
|
}
|
|
@@ -200285,6 +201802,7 @@ function GeoShapeNode({ id: id2, data, selected: selected2 }) {
|
|
|
200285
201802
|
const dim = useInteraction(ctx.store, (s) => s.matchedIds ? !s.matchedIds.has(id2) : false);
|
|
200286
201803
|
const origin = data.origin;
|
|
200287
201804
|
const iso = data.geo3d && node.geo && origin;
|
|
201805
|
+
const displayName = node.name.split(/::|\./u).filter(Boolean).at(-1) ?? node.name;
|
|
200288
201806
|
const approx = node.geo?.approx;
|
|
200289
201807
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
200290
201808
|
"div",
|
|
@@ -200300,7 +201818,10 @@ function GeoShapeNode({ id: id2, data, selected: selected2 }) {
|
|
|
200300
201818
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { className: "rf-node-svg", width: w, height: h, style: { overflow: "visible" }, children: [
|
|
200301
201819
|
iso ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
200302
201820
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("g", { className: `dgeo3d-node${selected2 ? " selected" : ""}`, transform: `translate(${-origin.x},${-origin.y})`, children: geoShapeBody(node, data.geo3d) }),
|
|
200303
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.
|
|
201821
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("text", { className: "dgeo3d-name", x: w / 2, y: -3, textAnchor: "middle", children: [
|
|
201822
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("title", { children: node.name }),
|
|
201823
|
+
displayName
|
|
201824
|
+
] })
|
|
200304
201825
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
200305
201826
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("rect", { className: `dnode-rect${selected2 ? " selected" : ""}`, x: 0, y: 0, width: w, height: h, rx: node.isDef ? 0 : 12 }),
|
|
200306
201827
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("text", { className: "dnode-label", x: w / 2, y: h / 2 + 3, textAnchor: "middle", children: node.name })
|
|
@@ -200521,7 +202042,7 @@ function usePortDrag(containerRef, w, h, topReserve, onPortMove, onPortPreview,
|
|
|
200521
202042
|
};
|
|
200522
202043
|
return { dragId, onPortPointerDown };
|
|
200523
202044
|
}
|
|
200524
|
-
function DualHandle({ id: id2, side, x, y, kind, active, connectable = true, startable = false, size, occluded = false }) {
|
|
202045
|
+
function DualHandle({ id: id2, side, x, y, kind, active, connectable = true, startable = false, size, occluded = false, onContextMenu }) {
|
|
200525
202046
|
const dimensions = typeof size === "number" ? { width: size, height: size } : size;
|
|
200526
202047
|
const style2 = dimensions ? { left: x, top: y, ...dimensions, transform: "translate(-50%,-50%)" } : { left: x, top: y, transform: "translate(-50%,-50%)" };
|
|
200527
202048
|
const enabled = connectable && !occluded;
|
|
@@ -200537,7 +202058,8 @@ function DualHandle({ id: id2, side, x, y, kind, active, connectable = true, sta
|
|
|
200537
202058
|
className: cls,
|
|
200538
202059
|
isConnectable: enabled,
|
|
200539
202060
|
isConnectableStart: false,
|
|
200540
|
-
isConnectableEnd: enabled
|
|
202061
|
+
isConnectableEnd: enabled,
|
|
202062
|
+
onContextMenu
|
|
200541
202063
|
}
|
|
200542
202064
|
),
|
|
200543
202065
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
@@ -200550,7 +202072,8 @@ function DualHandle({ id: id2, side, x, y, kind, active, connectable = true, sta
|
|
|
200550
202072
|
className: cls,
|
|
200551
202073
|
isConnectable: enabled,
|
|
200552
202074
|
isConnectableStart: enabled && startable,
|
|
200553
|
-
isConnectableEnd: enabled
|
|
202075
|
+
isConnectableEnd: enabled,
|
|
202076
|
+
onContextMenu
|
|
200554
202077
|
}
|
|
200555
202078
|
)
|
|
200556
202079
|
] });
|
|
@@ -200892,7 +202415,15 @@ function AnnotationBody({ node, w, h }) {
|
|
|
200892
202415
|
}
|
|
200893
202416
|
function DotBody({ node, w, h }) {
|
|
200894
202417
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("g", { children: [
|
|
200895
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
202418
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
202419
|
+
"circle",
|
|
202420
|
+
{
|
|
202421
|
+
className: "dnode-control dot dconnection-end-dot",
|
|
202422
|
+
cx: w / 2,
|
|
202423
|
+
cy: h / 2,
|
|
202424
|
+
r: circularControlRadius("dot")
|
|
202425
|
+
}
|
|
202426
|
+
),
|
|
200896
202427
|
node.name ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("text", { className: "dnode-kind", x: w / 2 + 9, y: h / 2 + 4, children: node.name }) : ""
|
|
200897
202428
|
] });
|
|
200898
202429
|
}
|
|
@@ -200961,6 +202492,8 @@ function PortGlyph({ ph, w, h, topReserve = 0, showLabels, selected: selected2,
|
|
|
200961
202492
|
};
|
|
200962
202493
|
})() : void 0;
|
|
200963
202494
|
const proxy = rect.proxy;
|
|
202495
|
+
const connectionEnd = ph.port.meta?.connectionEndPin === true;
|
|
202496
|
+
const glyphClass = `${selected2 ? " selected" : ""}${hovered ? " hovered" : ""}${moving ? " moving" : ""}${connectTargetSide ? " connect-target" : ""}`;
|
|
200964
202497
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
200965
202498
|
"g",
|
|
200966
202499
|
{
|
|
@@ -200990,10 +202523,10 @@ function PortGlyph({ ph, w, h, topReserve = 0, showLabels, selected: selected2,
|
|
|
200990
202523
|
}
|
|
200991
202524
|
);
|
|
200992
202525
|
})() : null,
|
|
200993
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
202526
|
+
connectionEnd ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("circle", { className: `dconnection-end-dot${glyphClass}`, cx: x, cy: y, r: half }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200994
202527
|
"rect",
|
|
200995
202528
|
{
|
|
200996
|
-
className: `dnode-port${ph.port.pin ? " pin" : ""}${ph.port.ref ? " ref" : ""}${rect.elongated ? " host" : ""}${proxy ? " proxy" : ""}${
|
|
202529
|
+
className: `dnode-port${ph.port.pin ? " pin" : ""}${ph.port.ref ? " ref" : ""}${rect.elongated ? " host" : ""}${proxy ? " proxy" : ""}${glyphClass}`,
|
|
200997
202530
|
x: rect.x,
|
|
200998
202531
|
y: rect.y,
|
|
200999
202532
|
width: rect.width,
|
|
@@ -201001,12 +202534,12 @@ function PortGlyph({ ph, w, h, topReserve = 0, showLabels, selected: selected2,
|
|
|
201001
202534
|
rx: ph.port.isDef ? 0 : PORT_CORNER_RADIUS
|
|
201002
202535
|
}
|
|
201003
202536
|
),
|
|
201004
|
-
d ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
202537
|
+
d && !connectionEnd ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
201005
202538
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { className: "dport-dir", d: arrowShaft() }),
|
|
201006
202539
|
d === "out" || d === "inout" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { className: "dport-dir head", d: arrowHead(1) }) : "",
|
|
201007
202540
|
d === "in" || d === "inout" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { className: "dport-dir head", d: arrowHead(-1) }) : ""
|
|
201008
202541
|
] }) : "",
|
|
201009
|
-
selected2 && connectStart && !connectTargetSide && !proxy ? (() => {
|
|
202542
|
+
selected2 && connectStart && !connectTargetSide && !proxy && !connectionEnd ? (() => {
|
|
201010
202543
|
const px = x + v.x * (half + PORT_PLUS_GAP);
|
|
201011
202544
|
const py = y + v.y * (half + PORT_PLUS_GAP);
|
|
201012
202545
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("g", { className: "dport-plus", children: [
|
|
@@ -201014,7 +202547,7 @@ function PortGlyph({ ph, w, h, topReserve = 0, showLabels, selected: selected2,
|
|
|
201014
202547
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: px, y1: py - PORT_PLUS_HALF, x2: px, y2: py + PORT_PLUS_HALF })
|
|
201015
202548
|
] });
|
|
201016
202549
|
})() : "",
|
|
201017
|
-
connectTargetSide ? (() => {
|
|
202550
|
+
connectTargetSide && !connectionEnd ? (() => {
|
|
201018
202551
|
const at2 = portDockAt(rect, ph.side, connectTargetSide);
|
|
201019
202552
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("circle", { className: "dport-anchor", cx: at2.x, cy: at2.y, r: 1.7 });
|
|
201020
202553
|
})() : "",
|
|
@@ -201270,7 +202803,7 @@ function NodeBody({ node, data, selectedPortId, hoveredPortId, movingPortId, con
|
|
|
201270
202803
|
hovered: hoveredPortId === ph.port.id,
|
|
201271
202804
|
moving: movingPortId === ph.port.id,
|
|
201272
202805
|
connectTargetSide: connectTargetPortId === ph.port.id ? connectTargetPortSide : void 0,
|
|
201273
|
-
connectStart: showPortConnectStart && (data.kind === "iv" ? ph.port.pin !== true : data.kind === "afv"),
|
|
202806
|
+
connectStart: showPortConnectStart && (data.kind === "iv" ? ph.port.pin !== true || ph.port.meta?.connectionEndPin === true : data.kind === "afv"),
|
|
201274
202807
|
onSelect: onPortSelect,
|
|
201275
202808
|
onContext: onPortContext
|
|
201276
202809
|
},
|
|
@@ -201322,15 +202855,16 @@ function SysmlNode({ id: id2, data, draggable, selected: selected2, width, heigh
|
|
|
201322
202855
|
shape: node.shape,
|
|
201323
202856
|
source: node.source
|
|
201324
202857
|
});
|
|
201325
|
-
const
|
|
202858
|
+
const connectionUsage = node.meta?.connectionUsage === true || node.meta?.interfaceUsage === true;
|
|
202859
|
+
const nodeSideStartable = !connectionUsage && directRelation !== void 0 && data.kind !== "sv" && node.shape !== "lifeline" && !isPackageEndpoint(node.shape, node.keyword);
|
|
201326
202860
|
const selectedPortId = useInteraction(ctx.store, (s) => typeof s.selectedId === "string" && myPortIds.includes(s.selectedId) ? s.selectedId : void 0);
|
|
201327
202861
|
const dropClass = useDropState(ctx.store, id2);
|
|
201328
202862
|
const [hoveredPortId, setHoveredPortId] = (0, import_react9.useState)(void 0);
|
|
201329
202863
|
const [sidePointsHovered, setSidePointsHovered] = (0, import_react9.useState)(false);
|
|
201330
202864
|
const isPackageNode = isPackageEndpoint(node.shape, node.keyword);
|
|
201331
|
-
const sideConnectable = data.kind !== "sv" && !isPackageNode;
|
|
202865
|
+
const sideConnectable = data.kind !== "sv" && !isPackageNode && !connectionUsage;
|
|
201332
202866
|
const perimeterControl = keepsPerimeterSidePointsMounted(node.shape);
|
|
201333
|
-
const sideOffsets = SIDES.map((side) => mountedNodeSidePointOffsets(
|
|
202867
|
+
const sideOffsets = connectionUsage ? SIDES.map(() => []) : SIDES.map((side) => mountedNodeSidePointOffsets(
|
|
201334
202868
|
data,
|
|
201335
202869
|
side,
|
|
201336
202870
|
sideConnectable,
|
|
@@ -201453,17 +202987,39 @@ function SysmlNode({ id: id2, data, draggable, selected: selected2, width, heigh
|
|
|
201453
202987
|
);
|
|
201454
202988
|
});
|
|
201455
202989
|
}),
|
|
201456
|
-
node.shape === "initial" || node.shape === "final" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "rf-circular-control-hit", "aria-hidden": "true" }) : null,
|
|
202990
|
+
node.shape === "initial" || node.shape === "final" || node.shape === "dot" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "rf-circular-control-hit", "aria-hidden": "true" }) : null,
|
|
201457
202991
|
ports.flatMap((ph) => {
|
|
201458
202992
|
const rect = portGlyphRect(ph, w, h, featureCompartmentHeight);
|
|
201459
202993
|
const proxied = isProxyPort(ph.port);
|
|
201460
202994
|
const startable = !proxied && directRelationForHandle(data.kind, {
|
|
201461
202995
|
id: ph.port.id,
|
|
201462
202996
|
name: ph.port.name,
|
|
201463
|
-
keyword: ph.port.pin ? "pin" : "port",
|
|
202997
|
+
keyword: ph.port.meta?.interfaceEndPort === true ? "interface end" : ph.port.meta?.connectionEndPin === true ? "connection end" : ph.port.pin ? "pin" : "port",
|
|
201464
202998
|
shape: ph.port.pin ? "pin" : "port",
|
|
201465
202999
|
source: ph.port.source
|
|
201466
203000
|
}) !== void 0;
|
|
203001
|
+
if (ph.port.meta?.connectionEndPin === true) {
|
|
203002
|
+
const point = portDockAt(rect, ph.side, ph.side);
|
|
203003
|
+
return [/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
203004
|
+
DualHandle,
|
|
203005
|
+
{
|
|
203006
|
+
id: portAnchorHandleId(ph.port.id, ph.side),
|
|
203007
|
+
side: ph.side,
|
|
203008
|
+
x: point.x,
|
|
203009
|
+
y: point.y,
|
|
203010
|
+
kind: "connection-end",
|
|
203011
|
+
connectable: !proxied,
|
|
203012
|
+
active: !proxied && (ph.port.id === hoveredPortId || ph.port.id === selectedPortId || ph.port.id === connectTargetPortId),
|
|
203013
|
+
startable,
|
|
203014
|
+
onContextMenu: (e) => {
|
|
203015
|
+
e.preventDefault();
|
|
203016
|
+
e.stopPropagation();
|
|
203017
|
+
ctx.onContextNode(ph.port.id, e.clientX, e.clientY);
|
|
203018
|
+
}
|
|
203019
|
+
},
|
|
203020
|
+
`${ph.port.id}-end`
|
|
203021
|
+
)];
|
|
203022
|
+
}
|
|
201467
203023
|
const [outerId, innerId] = portConnectHandleIds(ph.port.id, ph.side);
|
|
201468
203024
|
const outer = portDockAt(rect, ph.side, ph.side);
|
|
201469
203025
|
const innerSide = OPPOSITE_DOCK_SIDE[ph.side];
|
|
@@ -201504,7 +203060,7 @@ function SysmlNode({ id: id2, data, draggable, selected: selected2, width, heigh
|
|
|
201504
203060
|
const rect = portGlyphRect(ph, w, h, featureCompartmentHeight);
|
|
201505
203061
|
const nestedChild = ph.port.parentPort !== void 0;
|
|
201506
203062
|
const proxyPort = isProxyPort(ph.port);
|
|
201507
|
-
const strip = portInteractionStrip(rect, ph.side);
|
|
203063
|
+
const strip = portInteractionStrip(rect, ph.side, ph.port.meta?.connectionEndPin === true);
|
|
201508
203064
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
201509
203065
|
"div",
|
|
201510
203066
|
{
|
|
@@ -201875,7 +203431,7 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
201875
203431
|
hovered: hoveredPortId === ph.port.id,
|
|
201876
203432
|
moving: dragId === ph.port.id,
|
|
201877
203433
|
connectTargetSide: connectTargetPortId === ph.port.id ? connectTargetPortSide : void 0,
|
|
201878
|
-
connectStart: data.kind === "iv" ? ph.port.pin !== true : data.kind === "afv",
|
|
203434
|
+
connectStart: data.kind === "iv" ? ph.port.pin !== true || ph.port.meta?.connectionEndPin === true : data.kind === "afv",
|
|
201879
203435
|
onSelect: ctx.onPortMove ? void 0 : portSource,
|
|
201880
203436
|
onContext: ctx.onContextNode
|
|
201881
203437
|
},
|
|
@@ -201948,10 +203504,32 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
201948
203504
|
const startable = !proxied && directRelationForHandle(data.kind, {
|
|
201949
203505
|
id: ph.port.id,
|
|
201950
203506
|
name: ph.port.name,
|
|
201951
|
-
keyword: ph.port.pin ? "pin" : "port",
|
|
203507
|
+
keyword: ph.port.meta?.interfaceEndPort === true ? "interface end" : ph.port.meta?.connectionEndPin === true ? "connection end" : ph.port.pin ? "pin" : "port",
|
|
201952
203508
|
shape: ph.port.pin ? "pin" : "port",
|
|
201953
203509
|
source: ph.port.source
|
|
201954
203510
|
}) !== void 0;
|
|
203511
|
+
if (ph.port.meta?.connectionEndPin === true) {
|
|
203512
|
+
const point = portDockAt(rect, ph.side, ph.side);
|
|
203513
|
+
return [/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
203514
|
+
DualHandle,
|
|
203515
|
+
{
|
|
203516
|
+
id: portAnchorHandleId(ph.port.id, ph.side),
|
|
203517
|
+
side: ph.side,
|
|
203518
|
+
x: point.x,
|
|
203519
|
+
y: point.y,
|
|
203520
|
+
kind: "connection-end",
|
|
203521
|
+
connectable: !proxied,
|
|
203522
|
+
active: !proxied && (ph.port.id === hoveredPortId || ph.port.id === selectedPortId || ph.port.id === connectTargetPortId),
|
|
203523
|
+
startable,
|
|
203524
|
+
onContextMenu: (e) => {
|
|
203525
|
+
e.preventDefault();
|
|
203526
|
+
e.stopPropagation();
|
|
203527
|
+
ctx.onContextNode(ph.port.id, e.clientX, e.clientY);
|
|
203528
|
+
}
|
|
203529
|
+
},
|
|
203530
|
+
`${ph.port.id}-end`
|
|
203531
|
+
)];
|
|
203532
|
+
}
|
|
201955
203533
|
const [outerId, innerId] = portConnectHandleIds(ph.port.id, ph.side);
|
|
201956
203534
|
const outer = portDockAt(rect, ph.side, ph.side);
|
|
201957
203535
|
const innerSide = OPPOSITE_DOCK_SIDE[ph.side];
|
|
@@ -201992,7 +203570,7 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
201992
203570
|
const rect = portGlyphRect(ph, w, h, featureCompartmentHeight);
|
|
201993
203571
|
const nestedChild = ph.port.parentPort !== void 0;
|
|
201994
203572
|
const proxyPort = isProxyPort(ph.port);
|
|
201995
|
-
const strip = portInteractionStrip(rect, ph.side);
|
|
203573
|
+
const strip = portInteractionStrip(rect, ph.side, ph.port.meta?.connectionEndPin === true);
|
|
201996
203574
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
201997
203575
|
"div",
|
|
201998
203576
|
{
|
|
@@ -202323,7 +203901,7 @@ async function renderDiagramSvg(document2, provider, options) {
|
|
|
202323
203901
|
overrides: config.overrides,
|
|
202324
203902
|
connectPointSpacing: config.connectPointSpacing
|
|
202325
203903
|
});
|
|
202326
|
-
const renderEdges =
|
|
203904
|
+
const renderEdges = config.lineStyle === "orthogonal" ? projectAutomaticBusRenderEdges(laid.nodes, laid.edges, createEdgeBundleRuntime()) : laid.edges;
|
|
202327
203905
|
const indexOf2 = new Map(laid.nodes.map((node, i) => [node.id, i]));
|
|
202328
203906
|
return buildDiagramSvg({
|
|
202329
203907
|
nodes: laid.nodes,
|
|
@@ -202379,7 +203957,7 @@ async function runExport(command) {
|
|
|
202379
203957
|
}
|
|
202380
203958
|
|
|
202381
203959
|
// src/main.ts
|
|
202382
|
-
var VERSION2 = true ? "0.
|
|
203960
|
+
var VERSION2 = true ? "0.24.0" : "dev";
|
|
202383
203961
|
function display(file) {
|
|
202384
203962
|
const rel2 = path9.relative(process.cwd(), file);
|
|
202385
203963
|
return rel2 && !rel2.startsWith("..") ? rel2.split(path9.sep).join("/") : file;
|