sysml-diagram 0.22.0 → 0.23.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 +1749 -446
- 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,83 @@ 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
|
+
var END_PROPERTY_ADORNMENTS = /* @__PURE__ */ new Set(["abstract", "derived", "readonly", "ordered", "nonunique"]);
|
|
162478
|
+
var uniqueStrings = (values2) => [...new Set([...values2].filter((value) => !!value))];
|
|
162479
|
+
function formatConnectionEndAdornment(notation) {
|
|
162480
|
+
const adornment = [
|
|
162481
|
+
notation.direction,
|
|
162482
|
+
...notation.properties ?? [],
|
|
162483
|
+
notation.subsets?.length ? `subsets ${notation.subsets.join(", ")}` : void 0,
|
|
162484
|
+
notation.redefines?.length ? `redefines ${notation.redefines.join(", ")}` : void 0
|
|
162485
|
+
].filter((value) => !!value).join(" ");
|
|
162486
|
+
return adornment || void 0;
|
|
162487
|
+
}
|
|
162488
|
+
function mergeConnectionEndNotation(local, inherited) {
|
|
162489
|
+
const notation = {
|
|
162490
|
+
role: local.role ?? inherited?.role,
|
|
162491
|
+
multiplicity: local.multiplicity ?? inherited?.multiplicity,
|
|
162492
|
+
direction: local.direction ?? inherited?.direction,
|
|
162493
|
+
properties: uniqueStrings([...local.properties ?? [], ...inherited?.properties ?? []]),
|
|
162494
|
+
subsets: uniqueStrings([...local.subsets ?? [], ...inherited?.subsets ?? []]),
|
|
162495
|
+
redefines: uniqueStrings([...local.redefines ?? [], ...inherited?.redefines ?? []]),
|
|
162496
|
+
type: local.type ?? inherited?.type
|
|
162497
|
+
};
|
|
162498
|
+
notation.adornment = formatConnectionEndAdornment(notation);
|
|
162499
|
+
return notation;
|
|
162500
|
+
}
|
|
162501
|
+
function connectionEndNotationClaims(notation) {
|
|
162502
|
+
return uniqueStrings([
|
|
162503
|
+
notation.role,
|
|
162504
|
+
...(notation.redefines ?? []).map(lastSeg)
|
|
162505
|
+
]);
|
|
162506
|
+
}
|
|
162507
|
+
function connectionEndSpecializesRole(notation, role) {
|
|
162508
|
+
const wanted = lastSeg(role);
|
|
162509
|
+
return [...notation.subsets ?? [], ...notation.redefines ?? []].some((target) => lastSeg(target) === wanted);
|
|
162510
|
+
}
|
|
162511
|
+
function declaredConnectionEndNotation(node) {
|
|
162512
|
+
const n2 = node;
|
|
162513
|
+
const modifiers2 = [
|
|
162514
|
+
...n2.modifiers ?? [],
|
|
162515
|
+
...n2.postModifiers ?? [],
|
|
162516
|
+
...n2.trailingQuals ?? [],
|
|
162517
|
+
...n2.innerTrailingQuals ?? []
|
|
162518
|
+
];
|
|
162519
|
+
const direction = modifiers2.find((value) => value === "in" || value === "out" || value === "inout");
|
|
162520
|
+
const properties = uniqueStrings(modifiers2.filter((value) => END_PROPERTY_ADORNMENTS.has(value)));
|
|
162521
|
+
const subsets = [];
|
|
162522
|
+
const redefines = [];
|
|
162523
|
+
for (const relationship of [...n2.relationships ?? [], ...n2.innerRelationships ?? []]) {
|
|
162524
|
+
const targets = relationship.targets ?? [];
|
|
162525
|
+
if (relationship.kind === ":>" || relationship.kind === "subsets") {
|
|
162526
|
+
subsets.push(...targets);
|
|
162527
|
+
} else if (relationship.kind === ":>>" || relationship.kind === "redefines") {
|
|
162528
|
+
redefines.push(...targets);
|
|
162529
|
+
}
|
|
162530
|
+
}
|
|
162531
|
+
return mergeConnectionEndNotation({
|
|
162532
|
+
role: n2.innerName ?? nameOf2(node) ?? redefines.map(lastSeg).find(Boolean),
|
|
162533
|
+
multiplicity: connectionEndMultiplicity(node),
|
|
162534
|
+
direction,
|
|
162535
|
+
properties,
|
|
162536
|
+
subsets: uniqueStrings(subsets),
|
|
162537
|
+
redefines: uniqueStrings(redefines),
|
|
162538
|
+
type: n2.innerTyping?.type?.$refText ?? n2.typing?.type?.$refText
|
|
162539
|
+
}, void 0);
|
|
162540
|
+
}
|
|
162375
162541
|
function multText(node) {
|
|
162376
162542
|
if (!node)
|
|
162377
162543
|
return void 0;
|
|
@@ -162782,17 +162948,40 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
162782
162948
|
else
|
|
162783
162949
|
drawn.set(k, [target]);
|
|
162784
162950
|
};
|
|
162785
|
-
|
|
162786
|
-
claim(n2.source, { id: n2.id, parent: n2.parent, frame: n2.frame });
|
|
162951
|
+
const claimNode = (n2, definitionLayer2 = false) => {
|
|
162952
|
+
claim(n2.source, { id: n2.id, parent: n2.parent, frame: n2.frame, definitionLayer: definitionLayer2 });
|
|
162787
162953
|
for (const port of n2.ports ?? []) {
|
|
162788
|
-
|
|
162954
|
+
if (port.meta?.connectionEndPin === true)
|
|
162955
|
+
continue;
|
|
162956
|
+
claim(port.source, {
|
|
162957
|
+
id: port.id,
|
|
162958
|
+
parent: n2.parent,
|
|
162959
|
+
frame: n2.frame,
|
|
162960
|
+
port: true,
|
|
162961
|
+
definitionLayer: definitionLayer2
|
|
162962
|
+
});
|
|
162789
162963
|
}
|
|
162790
|
-
}
|
|
162791
|
-
|
|
162792
|
-
claim(f.source, { id: f.id, frame: f.id });
|
|
162964
|
+
};
|
|
162965
|
+
const claimFrame = (f, definitionLayer2 = false) => {
|
|
162966
|
+
claim(f.source, { id: f.id, frame: f.id, definitionLayer: definitionLayer2 });
|
|
162793
162967
|
for (const port of f.ports ?? []) {
|
|
162794
|
-
|
|
162968
|
+
if (port.meta?.connectionEndPin === true)
|
|
162969
|
+
continue;
|
|
162970
|
+
claim(port.source, { id: port.id, frame: f.id, port: true, definitionLayer: definitionLayer2 });
|
|
162795
162971
|
}
|
|
162972
|
+
};
|
|
162973
|
+
for (const n2 of model.nodes) {
|
|
162974
|
+
claimNode(n2);
|
|
162975
|
+
}
|
|
162976
|
+
for (const f of model.frames ?? []) {
|
|
162977
|
+
claimFrame(f);
|
|
162978
|
+
}
|
|
162979
|
+
const definitionLayer = model.layers?.definitions;
|
|
162980
|
+
for (const n2 of definitionLayer?.nodes ?? []) {
|
|
162981
|
+
claimNode(n2, true);
|
|
162982
|
+
}
|
|
162983
|
+
for (const f of definitionLayer?.frames ?? []) {
|
|
162984
|
+
claimFrame(f, true);
|
|
162796
162985
|
}
|
|
162797
162986
|
if (model.ivBoundary) {
|
|
162798
162987
|
claim(model.ivBoundary.source, { id: model.ivBoundary.id, frame: model.ivBoundary.id });
|
|
@@ -162804,15 +162993,22 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
162804
162993
|
return model;
|
|
162805
162994
|
const nodes = [...model.nodes];
|
|
162806
162995
|
const edges = [...model.edges];
|
|
162996
|
+
const definitionNodes = [...definitionLayer?.nodes ?? []];
|
|
162997
|
+
const definitionEdges = [...definitionLayer?.edges ?? []];
|
|
162807
162998
|
let noteCount = 0;
|
|
162808
|
-
let edgeCount = edges.
|
|
162999
|
+
let edgeCount = [...edges, ...definitionEdges].reduce((next, edge) => {
|
|
163000
|
+
const match = /^e(\d+)$/u.exec(edge.id);
|
|
163001
|
+
return match ? Math.max(next, Number(match[1]) + 1) : next;
|
|
163002
|
+
}, 0);
|
|
162809
163003
|
const note = (annotation) => {
|
|
162810
163004
|
const targets = drawn.get(key(sourceOf2(annotation.owner, uri)) ?? "")?.filter((target) => annotation.keyword !== "doc" || docAsNote || target.port);
|
|
162811
163005
|
if (!targets?.length)
|
|
162812
163006
|
return;
|
|
162813
163007
|
for (const target of targets) {
|
|
162814
163008
|
const id2 = `__note_${noteCount++}__`;
|
|
162815
|
-
nodes
|
|
163009
|
+
const targetNodes = target.definitionLayer ? definitionNodes : nodes;
|
|
163010
|
+
const targetEdges = target.definitionLayer ? definitionEdges : edges;
|
|
163011
|
+
targetNodes.push({
|
|
162816
163012
|
id: id2,
|
|
162817
163013
|
name: annotation.label,
|
|
162818
163014
|
keyword: annotation.keyword,
|
|
@@ -162825,7 +163021,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
162825
163021
|
...target.frame ? { frame: target.frame } : {},
|
|
162826
163022
|
source: sourceOf2(annotation.annotation, uri)
|
|
162827
163023
|
});
|
|
162828
|
-
|
|
163024
|
+
targetEdges.push({
|
|
162829
163025
|
id: `e${edgeCount++}`,
|
|
162830
163026
|
from: id2,
|
|
162831
163027
|
to: target.id,
|
|
@@ -162843,7 +163039,23 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
162843
163039
|
note(annotation);
|
|
162844
163040
|
}
|
|
162845
163041
|
}
|
|
162846
|
-
|
|
163042
|
+
if (!noteCount)
|
|
163043
|
+
return model;
|
|
163044
|
+
return {
|
|
163045
|
+
...model,
|
|
163046
|
+
nodes,
|
|
163047
|
+
edges,
|
|
163048
|
+
...definitionLayer ? {
|
|
163049
|
+
layers: {
|
|
163050
|
+
...model.layers,
|
|
163051
|
+
definitions: {
|
|
163052
|
+
...definitionLayer,
|
|
163053
|
+
nodes: definitionNodes,
|
|
163054
|
+
edges: definitionEdges
|
|
163055
|
+
}
|
|
163056
|
+
}
|
|
163057
|
+
} : {}
|
|
163058
|
+
};
|
|
162847
163059
|
}
|
|
162848
163060
|
// REQ-224 — Detect the file/anchor-specific view kinds that will render
|
|
162849
163061
|
// substantive diagram content. The extension uses this to limit the
|
|
@@ -163670,8 +163882,27 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
163670
163882
|
hasGeometryObject(node, index2) {
|
|
163671
163883
|
return this.collectGeometry(node, index2).length > 0;
|
|
163672
163884
|
}
|
|
163885
|
+
// REQ-360 — Package overview
|
|
163886
|
+
/** Package overviews contain layouts, not inventories of unplaced shape types. */
|
|
163887
|
+
hasPlacedGeometryObject(node, index2) {
|
|
163888
|
+
return this.collectGeometry(node, index2).some((candidate) => candidate.geo !== void 0);
|
|
163889
|
+
}
|
|
163890
|
+
// REQ-360 — Package overview
|
|
163891
|
+
/** Collapse a wrapper whose only direct object owns the actual layout. */
|
|
163892
|
+
hasGeometryOverviewLayout(node, index2) {
|
|
163893
|
+
const placed = this.collectGeometry(node, index2).filter((candidate) => candidate.geo !== void 0);
|
|
163894
|
+
if (placed.length === 0)
|
|
163895
|
+
return false;
|
|
163896
|
+
const direct = placed.filter((candidate) => !candidate.name.includes("."));
|
|
163897
|
+
if (direct.length !== 1)
|
|
163898
|
+
return true;
|
|
163899
|
+
const prefix = `${direct[0].name}.`;
|
|
163900
|
+
return !placed.some((candidate) => candidate.name.startsWith(prefix));
|
|
163901
|
+
}
|
|
163673
163902
|
hasRenderablePorts(node, index2) {
|
|
163674
|
-
|
|
163903
|
+
if (membersOf(node).some((member) => isPortDecl(member) && member.isDef !== true))
|
|
163904
|
+
return true;
|
|
163905
|
+
return this.inheritedFeatureOwnersOf(node, index2).some((source) => membersOf(source).some((member) => isPortDecl(member) && member.isDef !== true && !this.isInheritedLibraryBackboneFeature(source, member, index2)));
|
|
163675
163906
|
}
|
|
163676
163907
|
// REQ-192, issue #233 — the named part usages a part shows when expanded: its
|
|
163677
163908
|
// own and the ones it inherits, through its typing definition or a `:>`
|
|
@@ -163679,11 +163910,51 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
163679
163910
|
// The predicate form of `childUsagesOf`, so an anchor that only INHERITS
|
|
163680
163911
|
// internals is recognised as having them.
|
|
163681
163912
|
hasNestedPartUsages(node, index2) {
|
|
163682
|
-
return
|
|
163913
|
+
return this.structuralChildUsagesOf(node, index2).some((usage) => nameOf2(usage) !== void 0);
|
|
163683
163914
|
}
|
|
163684
163915
|
nestedUsages(node, guard) {
|
|
163685
163916
|
return membersOf(node).filter((m) => guard(m) && m.isDef !== true);
|
|
163686
163917
|
}
|
|
163918
|
+
// REQ-192 - standard-library definitions contribute real inherited structure,
|
|
163919
|
+
// but their recursive backbone features are collecting roles, not additional
|
|
163920
|
+
// concrete children of every typed usage. For example, SpatialItem declares
|
|
163921
|
+
// `subSpatialParts : SpatialItem`, and Part declares `start : Part`. Expanding
|
|
163922
|
+
// either role as another occurrence recursively materializes the library model
|
|
163923
|
+
// instead of the user's composition. A local redefinition remains visible.
|
|
163924
|
+
isInheritedLibraryBackboneFeature(source, usage, index2) {
|
|
163925
|
+
if (!isLibraryDocument(ast_utils_exports.getDocument(usage)))
|
|
163926
|
+
return false;
|
|
163927
|
+
if (modifiersOf(usage).includes("abstract"))
|
|
163928
|
+
return true;
|
|
163929
|
+
const ownerType = source.isDef === true ? source : this.resolveType(source, index2);
|
|
163930
|
+
const usageType = this.resolveType(usage, index2);
|
|
163931
|
+
if (!ownerType || !usageType)
|
|
163932
|
+
return false;
|
|
163933
|
+
if (ownerType === usageType)
|
|
163934
|
+
return true;
|
|
163935
|
+
return this.inheritedFeatureOwnersOf(ownerType, index2).includes(usageType) || this.inheritedFeatureOwnersOf(usageType, index2).includes(ownerType);
|
|
163936
|
+
}
|
|
163937
|
+
/** The concrete structural children projected by IV, with the same nearest-name
|
|
163938
|
+
* fold used for other effective inventories. Authored subsets of an inherited
|
|
163939
|
+
* library collection stay visible; only the inherited recursive role is hidden. */
|
|
163940
|
+
structuralChildUsagesOf(part, index2) {
|
|
163941
|
+
const out = this.nestedUsages(part, isPartDecl);
|
|
163942
|
+
const have = new Set(out.map(effectiveNameOf).filter((name) => !!name));
|
|
163943
|
+
for (const source of this.inheritedFeatureOwnersOf(part, index2)) {
|
|
163944
|
+
for (const usage of this.nestedUsages(source, isPartDecl)) {
|
|
163945
|
+
if (this.isInheritedLibraryBackboneFeature(source, usage, index2))
|
|
163946
|
+
continue;
|
|
163947
|
+
const name = effectiveNameOf(usage);
|
|
163948
|
+
if (name !== void 0) {
|
|
163949
|
+
if (have.has(name))
|
|
163950
|
+
continue;
|
|
163951
|
+
have.add(name);
|
|
163952
|
+
}
|
|
163953
|
+
out.push(usage);
|
|
163954
|
+
}
|
|
163955
|
+
}
|
|
163956
|
+
return out;
|
|
163957
|
+
}
|
|
163687
163958
|
// issue #109 — usages of kinds with NO dedicated usage view (constraint /
|
|
163688
163959
|
// calc / occurrence / item / attribute). Nested in an element they surface as
|
|
163689
163960
|
// owner compartments (compartmentsFor); declared as direct package members
|
|
@@ -163718,8 +163989,13 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
163718
163989
|
const all = [...ast_utils_exports.streamAllContents(scope)];
|
|
163719
163990
|
const defNodes = all.filter((n2) => isDefinitionNode(n2) && nameOf2(n2));
|
|
163720
163991
|
const packageOverview = isPackage(ctx.anchor) || isDocument(ctx.anchor);
|
|
163721
|
-
const
|
|
163722
|
-
const
|
|
163992
|
+
const isDirectPackageInterfaceUsage = (n2) => isInterfaceDecl(n2) && n2.isDef !== true && this.isDirectPackageMember(n2);
|
|
163993
|
+
const isPackageInterfaceUsage = (n2) => {
|
|
163994
|
+
const usage = n2;
|
|
163995
|
+
const emptyPrefix = usage.target !== void 0 && usage.connect === void 0;
|
|
163996
|
+
return isDirectPackageInterfaceUsage(n2) && !emptyPrefix && !!nameOf2(n2);
|
|
163997
|
+
};
|
|
163998
|
+
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
163999
|
const packageNodes = [
|
|
163724
164000
|
...packageOverview && hasOwnedMemberNode && isPackage(scope) && nameOf2(scope) ? [scope] : [],
|
|
163725
164001
|
...all.filter((p) => isPackage(p) && nameOf2(p))
|
|
@@ -163880,6 +164156,77 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
163880
164156
|
}
|
|
163881
164157
|
}
|
|
163882
164158
|
}
|
|
164159
|
+
for (const definition of defNodes.filter(isConnectionDecl)) {
|
|
164160
|
+
const definitionId = ids.get(definition);
|
|
164161
|
+
if (!definitionId)
|
|
164162
|
+
continue;
|
|
164163
|
+
const effectiveEnds = this.connectionEndNotationsOf(definition, index2);
|
|
164164
|
+
const resolvedEnds = effectiveEnds.map((notation) => {
|
|
164165
|
+
const target = notation.type ? resolveDrawnByText(notation.type) : void 0;
|
|
164166
|
+
return target && ids.has(target) ? { id: ids.get(target), notation } : void 0;
|
|
164167
|
+
});
|
|
164168
|
+
if (resolvedEnds.length < 2 || resolvedEnds.some((end) => !end))
|
|
164169
|
+
continue;
|
|
164170
|
+
const completeEnds = resolvedEnds.filter((end) => !!end);
|
|
164171
|
+
const definitionNode = nodes.find((node) => node.id === definitionId);
|
|
164172
|
+
const hasElaboration = !!definitionNode?.compartments?.length || specializationFamily(definition).length > 0;
|
|
164173
|
+
if (definitionNode) {
|
|
164174
|
+
definitionNode.meta = {
|
|
164175
|
+
...definitionNode.meta,
|
|
164176
|
+
connectionDefinitionGraphical: true,
|
|
164177
|
+
...hasElaboration ? { connectionDefinitionElaboration: true } : {}
|
|
164178
|
+
};
|
|
164179
|
+
}
|
|
164180
|
+
const common = {
|
|
164181
|
+
kind: "connect",
|
|
164182
|
+
name: nameOf2(definition),
|
|
164183
|
+
isDef: true,
|
|
164184
|
+
label: `\xABconnection def\xBB ${nameOf2(definition) ?? ""}`.trim(),
|
|
164185
|
+
source: sourceOf2(definition, uri),
|
|
164186
|
+
meta: { connectionDefinitionGraphical: true },
|
|
164187
|
+
...hasElaboration ? { elaboration: definitionId } : {}
|
|
164188
|
+
};
|
|
164189
|
+
if (completeEnds.length === 2) {
|
|
164190
|
+
edges.push({
|
|
164191
|
+
id: `e${e++}`,
|
|
164192
|
+
from: completeEnds[0].id,
|
|
164193
|
+
to: completeEnds[1].id,
|
|
164194
|
+
...common,
|
|
164195
|
+
endRoleFrom: completeEnds[0].notation.role,
|
|
164196
|
+
endLabelFrom: completeEnds[0].notation.multiplicity,
|
|
164197
|
+
endAdornmentFrom: completeEnds[0].notation.adornment,
|
|
164198
|
+
endRoleTo: completeEnds[1].notation.role,
|
|
164199
|
+
endLabelTo: completeEnds[1].notation.multiplicity,
|
|
164200
|
+
endAdornmentTo: completeEnds[1].notation.adornment
|
|
164201
|
+
});
|
|
164202
|
+
} else {
|
|
164203
|
+
const hubId = `${definitionId}::__connection__`;
|
|
164204
|
+
nodes.push({
|
|
164205
|
+
id: hubId,
|
|
164206
|
+
name: nameOf2(definition) ?? "",
|
|
164207
|
+
keyword: "connection def",
|
|
164208
|
+
isDef: true,
|
|
164209
|
+
shape: "dot",
|
|
164210
|
+
...packageOf2(definition),
|
|
164211
|
+
source: sourceOf2(definition, uri),
|
|
164212
|
+
meta: {
|
|
164213
|
+
connectionDefinitionGraphical: true,
|
|
164214
|
+
connectionDefinitionHub: true,
|
|
164215
|
+
naryConnectionHub: true
|
|
164216
|
+
}
|
|
164217
|
+
});
|
|
164218
|
+
completeEnds.forEach((end, indexOfEnd) => edges.push({
|
|
164219
|
+
id: `e${e++}`,
|
|
164220
|
+
from: hubId,
|
|
164221
|
+
to: end.id,
|
|
164222
|
+
...common,
|
|
164223
|
+
...indexOfEnd === 0 ? {} : { label: void 0, elaboration: void 0 },
|
|
164224
|
+
endRoleTo: end.notation.role,
|
|
164225
|
+
endLabelTo: end.notation.multiplicity,
|
|
164226
|
+
endAdornmentTo: end.notation.adornment
|
|
164227
|
+
}));
|
|
164228
|
+
}
|
|
164229
|
+
}
|
|
163883
164230
|
for (const rs of all.filter((m) => m.$type === "StandaloneRelationshipDecl")) {
|
|
163884
164231
|
const rn = rs;
|
|
163885
164232
|
const from = resolveDrawnByText(String(rn.source ?? ""));
|
|
@@ -164296,6 +164643,270 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164296
164643
|
const o = v;
|
|
164297
164644
|
return this.featurePath(o.reference) ?? this.featurePath(o.path) ?? o.$cstNode?.text?.replace(/\[[^\]]*\]/g, "").trim();
|
|
164298
164645
|
}
|
|
164646
|
+
connectorEndRole(v) {
|
|
164647
|
+
if (!v || typeof v !== "object")
|
|
164648
|
+
return void 0;
|
|
164649
|
+
const end = v;
|
|
164650
|
+
if (!end.reference)
|
|
164651
|
+
return void 0;
|
|
164652
|
+
const role = this.featurePath(end.path);
|
|
164653
|
+
return role ? lastSeg(role) : void 0;
|
|
164654
|
+
}
|
|
164655
|
+
// REQ-192, issue #111: connection and interface definitions may specialize
|
|
164656
|
+
// definitions that own their ends. Fold those ends nearest-first, just like
|
|
164657
|
+
// the rest of the effective IV inventory. A local end shadows an inherited
|
|
164658
|
+
// end by role or explicit redefinition and inherits notation it omits.
|
|
164659
|
+
connectionEndNotationsOf(owner, index2) {
|
|
164660
|
+
if (!owner)
|
|
164661
|
+
return [];
|
|
164662
|
+
const inheritedOwners = owner.isDef === true ? [] : this.inheritedFeatureOwnersOf(owner, index2);
|
|
164663
|
+
const definition = owner.isDef === true ? owner : this.resolveType(owner, index2) ?? inheritedOwners.find((candidate) => candidate.isDef === true && candidate.$type === owner.$type);
|
|
164664
|
+
if (!definition)
|
|
164665
|
+
return [];
|
|
164666
|
+
const selected2 = [];
|
|
164667
|
+
for (const source of [definition, ...this.inheritedFeatureOwnersOf(definition, index2)]) {
|
|
164668
|
+
for (const end of membersOf(source).filter(isEndMember)) {
|
|
164669
|
+
const notation = declaredConnectionEndNotation(end);
|
|
164670
|
+
const claims = new Set(connectionEndNotationClaims(notation));
|
|
164671
|
+
const existing = selected2.find((candidate) => [...claims].some((claim) => candidate.claims.has(claim)));
|
|
164672
|
+
if (existing) {
|
|
164673
|
+
existing.notation = mergeConnectionEndNotation(existing.notation, notation);
|
|
164674
|
+
for (const claim of connectionEndNotationClaims(existing.notation))
|
|
164675
|
+
existing.claims.add(claim);
|
|
164676
|
+
continue;
|
|
164677
|
+
}
|
|
164678
|
+
const inheritedRole = notation.role;
|
|
164679
|
+
const specialized = inheritedRole ? selected2.filter((candidate) => connectionEndSpecializesRole(candidate.notation, inheritedRole)) : [];
|
|
164680
|
+
if (specialized.length > 0) {
|
|
164681
|
+
for (const candidate of specialized) {
|
|
164682
|
+
candidate.notation = mergeConnectionEndNotation(candidate.notation, notation);
|
|
164683
|
+
for (const claim of connectionEndNotationClaims(candidate.notation))
|
|
164684
|
+
candidate.claims.add(claim);
|
|
164685
|
+
}
|
|
164686
|
+
continue;
|
|
164687
|
+
}
|
|
164688
|
+
selected2.push({ notation, claims });
|
|
164689
|
+
}
|
|
164690
|
+
}
|
|
164691
|
+
return selected2.map(({ notation }) => notation);
|
|
164692
|
+
}
|
|
164693
|
+
matchingConnectionEndNotation(notations, role, ordinal) {
|
|
164694
|
+
const wanted = role ? lastSeg(role) : void 0;
|
|
164695
|
+
if (wanted) {
|
|
164696
|
+
return notations.find((notation) => connectionEndNotationClaims(notation).some((claim) => lastSeg(claim) === wanted));
|
|
164697
|
+
}
|
|
164698
|
+
return notations[ordinal];
|
|
164699
|
+
}
|
|
164700
|
+
declaredConnectionEndBinding(node) {
|
|
164701
|
+
const n2 = node;
|
|
164702
|
+
for (const relationship of [...n2.relationships ?? [], ...n2.innerRelationships ?? []]) {
|
|
164703
|
+
if (relationship.kind !== "::>" && relationship.kind !== "references")
|
|
164704
|
+
continue;
|
|
164705
|
+
for (const [occurrence, target] of (relationship.targets ?? []).entries()) {
|
|
164706
|
+
if (!target)
|
|
164707
|
+
continue;
|
|
164708
|
+
return {
|
|
164709
|
+
path: target,
|
|
164710
|
+
binding: {
|
|
164711
|
+
host: relationship,
|
|
164712
|
+
property: "targets",
|
|
164713
|
+
occurrence
|
|
164714
|
+
}
|
|
164715
|
+
};
|
|
164716
|
+
}
|
|
164717
|
+
}
|
|
164718
|
+
return {};
|
|
164719
|
+
}
|
|
164720
|
+
connectorEndBinding(end) {
|
|
164721
|
+
if (!end || typeof end !== "object" || !("$type" in end))
|
|
164722
|
+
return void 0;
|
|
164723
|
+
const connectorEnd = end;
|
|
164724
|
+
if (connectorEnd.$type !== "ConnectorEnd")
|
|
164725
|
+
return void 0;
|
|
164726
|
+
return {
|
|
164727
|
+
host: connectorEnd,
|
|
164728
|
+
property: connectorEnd.reference ? "reference" : "path",
|
|
164729
|
+
occurrence: 0
|
|
164730
|
+
};
|
|
164731
|
+
}
|
|
164732
|
+
canonicalConnectionBindingTarget(target, seen = /* @__PURE__ */ new Set()) {
|
|
164733
|
+
if (!isAliasDecl(target))
|
|
164734
|
+
return target;
|
|
164735
|
+
if (seen.has(target))
|
|
164736
|
+
return void 0;
|
|
164737
|
+
seen.add(target);
|
|
164738
|
+
const resolution = this.annotationPathResolver(target).resolvePropertyPath(target, "target");
|
|
164739
|
+
if (resolution.unresolvedIndex !== void 0 || resolution.indeterminateIndex !== void 0)
|
|
164740
|
+
return void 0;
|
|
164741
|
+
const terminal = resolution.segments.at(-1);
|
|
164742
|
+
const aliasTarget = terminal?.target ?? this.annotationDescriptionNode(target, terminal?.description);
|
|
164743
|
+
return aliasTarget ? this.canonicalConnectionBindingTarget(aliasTarget, seen) : void 0;
|
|
164744
|
+
}
|
|
164745
|
+
explicitFeatureAncestorsOf(node, index2) {
|
|
164746
|
+
const ancestors = [];
|
|
164747
|
+
const seen = /* @__PURE__ */ new Set([node]);
|
|
164748
|
+
const queue = [node];
|
|
164749
|
+
while (queue.length > 0) {
|
|
164750
|
+
const current2 = queue.shift();
|
|
164751
|
+
for (const path10 of featureInheritanceTargets(current2)) {
|
|
164752
|
+
const target = this.resolveFeatureInheritanceTarget(current2, path10, index2, /* @__PURE__ */ new Set());
|
|
164753
|
+
if (!target || seen.has(target))
|
|
164754
|
+
continue;
|
|
164755
|
+
seen.add(target);
|
|
164756
|
+
ancestors.push(target);
|
|
164757
|
+
queue.push(target);
|
|
164758
|
+
}
|
|
164759
|
+
}
|
|
164760
|
+
return ancestors;
|
|
164761
|
+
}
|
|
164762
|
+
/** REQ-192: whether the declared path resolves to the exact rendered
|
|
164763
|
+
* occurrence path. The ordinary IV endpoint resolver remains forgiving for
|
|
164764
|
+
* issue #62; inherited visibility also checks every semantic receiver so a
|
|
164765
|
+
* path such as `outside.p` cannot borrow another visible `inside.p` merely
|
|
164766
|
+
* because both ports share one definition. */
|
|
164767
|
+
connectionUsageEndBindingMatches(end, renderedPath, ownerPath, index2) {
|
|
164768
|
+
if (!end.binding || !renderedPath || !ownerPath)
|
|
164769
|
+
return false;
|
|
164770
|
+
const resolution = this.annotationPathResolver(end.binding.host).resolvePropertyPath(end.binding.host, end.binding.property, end.binding.occurrence);
|
|
164771
|
+
if (resolution.unresolvedIndex !== void 0 || resolution.indeterminateIndex !== void 0)
|
|
164772
|
+
return false;
|
|
164773
|
+
const semanticPath = [];
|
|
164774
|
+
const resolver = this.annotationPathResolver(end.binding.host);
|
|
164775
|
+
let canonicalOwner;
|
|
164776
|
+
for (const segment of resolution.segments) {
|
|
164777
|
+
const target = canonicalOwner ? resolver.visibleMembers(canonicalOwner).find((candidate) => effectiveNameOf(candidate) === segment.text) : segment.target ?? this.annotationDescriptionNode(end.binding.host, segment.description);
|
|
164778
|
+
if (!target)
|
|
164779
|
+
return false;
|
|
164780
|
+
const canonical = this.canonicalConnectionBindingTarget(target);
|
|
164781
|
+
if (!canonical)
|
|
164782
|
+
return false;
|
|
164783
|
+
if (canonicalOwner || isAliasDecl(target))
|
|
164784
|
+
canonicalOwner = canonical;
|
|
164785
|
+
if (isPackage(canonical) || isDocument(canonical) || canonical.$type === "NamespaceDecl")
|
|
164786
|
+
continue;
|
|
164787
|
+
semanticPath.push(canonical);
|
|
164788
|
+
}
|
|
164789
|
+
if (semanticPath.length === 0)
|
|
164790
|
+
return false;
|
|
164791
|
+
const sameDeclaration = (candidate, expected) => {
|
|
164792
|
+
if (candidate === expected)
|
|
164793
|
+
return true;
|
|
164794
|
+
const candidateCst = candidate.$cstNode;
|
|
164795
|
+
const expectedCst = expected.$cstNode;
|
|
164796
|
+
if (!candidateCst || !expectedCst || candidate.$type !== expected.$type || candidateCst.offset !== expectedCst.offset || candidateCst.end !== expectedCst.end) {
|
|
164797
|
+
return false;
|
|
164798
|
+
}
|
|
164799
|
+
try {
|
|
164800
|
+
return ast_utils_exports.getDocument(candidate).uri.toString() === ast_utils_exports.getDocument(expected).uri.toString();
|
|
164801
|
+
} catch {
|
|
164802
|
+
return false;
|
|
164803
|
+
}
|
|
164804
|
+
};
|
|
164805
|
+
const matches = (candidatePath, allowRootRebinding) => candidatePath.length === semanticPath.length && candidatePath.every((candidate, at) => {
|
|
164806
|
+
const expected = semanticPath[at];
|
|
164807
|
+
if (sameDeclaration(candidate, expected) || this.explicitFeatureAncestorsOf(candidate, index2).some((ancestor) => sameDeclaration(ancestor, expected))) {
|
|
164808
|
+
return true;
|
|
164809
|
+
}
|
|
164810
|
+
return allowRootRebinding && at === 0 && this.inheritedFeatureOwnersOf(candidate, index2).some((ancestor) => sameDeclaration(ancestor, expected));
|
|
164811
|
+
});
|
|
164812
|
+
const relativePath = renderedPath.slice(ownerPath.length);
|
|
164813
|
+
const ownerRootedPath = renderedPath.slice(Math.max(0, ownerPath.length - 1));
|
|
164814
|
+
const result = matches(relativePath, false) || matches(ownerRootedPath, true) || matches(renderedPath, true) || semanticPath.length === 1 && matches(renderedPath.slice(-1), false);
|
|
164815
|
+
return result;
|
|
164816
|
+
}
|
|
164817
|
+
/** REQ-192: the ends written directly on one explicit connection usage.
|
|
164818
|
+
* This keeps the concrete binding path beside its notation so inheritance
|
|
164819
|
+
* can fold both pieces of the effective end together. */
|
|
164820
|
+
declaredConnectionUsageEndsOf(owner, index2) {
|
|
164821
|
+
const clause = owner.connect;
|
|
164822
|
+
if (clause) {
|
|
164823
|
+
const rawEnds = clause.ends?.length ? clause.ends : [clause.source, clause.target].filter((end) => end !== void 0);
|
|
164824
|
+
return rawEnds.map((end, ordinal) => ({
|
|
164825
|
+
notation: this.connectorEndNotation(owner, end, index2, ordinal),
|
|
164826
|
+
path: this.connectorEndPath(end),
|
|
164827
|
+
binding: this.connectorEndBinding(end),
|
|
164828
|
+
ordinal
|
|
164829
|
+
}));
|
|
164830
|
+
}
|
|
164831
|
+
const effective = this.connectionEndNotationsOf(owner, index2);
|
|
164832
|
+
return membersOf(owner).filter(isEndMember).map((end, ordinal) => {
|
|
164833
|
+
const local = declaredConnectionEndNotation(end);
|
|
164834
|
+
const declaredBinding = this.declaredConnectionEndBinding(end);
|
|
164835
|
+
return {
|
|
164836
|
+
notation: mergeConnectionEndNotation(local, this.matchingConnectionEndNotation(effective, local.role, ordinal)),
|
|
164837
|
+
...declaredBinding,
|
|
164838
|
+
ordinal
|
|
164839
|
+
};
|
|
164840
|
+
});
|
|
164841
|
+
}
|
|
164842
|
+
/** REQ-192/195: an explicit connection or interface usage redefinition
|
|
164843
|
+
* inherits any end binding it does not replace. Sources are nearest first.
|
|
164844
|
+
* Role and redefinition claims identify corresponding ends, with source-local
|
|
164845
|
+
* ordinal as the fallback. */
|
|
164846
|
+
effectiveConnectionUsageEndsOf(owner, index2) {
|
|
164847
|
+
const declared = [];
|
|
164848
|
+
for (const source of [owner, ...this.inheritedFeatureOwnersOf(owner, index2)]) {
|
|
164849
|
+
if (source.$type !== owner.$type || !isConnectionDecl(source) && !isInterfaceDecl(source) || source.isDef === true)
|
|
164850
|
+
continue;
|
|
164851
|
+
for (const candidate of this.declaredConnectionUsageEndsOf(source, index2)) {
|
|
164852
|
+
const claims = connectionEndNotationClaims(candidate.notation).map(lastSeg);
|
|
164853
|
+
let existingIndex = claims.length > 0 ? declared.findIndex((current2) => connectionEndNotationClaims(current2.notation).map(lastSeg).some((claim) => claims.includes(claim))) : -1;
|
|
164854
|
+
if (existingIndex < 0) {
|
|
164855
|
+
const ordinalIndex = declared.findIndex((current2) => current2.ordinal === candidate.ordinal);
|
|
164856
|
+
const ordinalClaims = ordinalIndex >= 0 ? connectionEndNotationClaims(declared[ordinalIndex].notation).map(lastSeg) : [];
|
|
164857
|
+
if (claims.length === 0 || ordinalClaims.length === 0)
|
|
164858
|
+
existingIndex = ordinalIndex;
|
|
164859
|
+
}
|
|
164860
|
+
if (existingIndex < 0) {
|
|
164861
|
+
declared.push(candidate);
|
|
164862
|
+
continue;
|
|
164863
|
+
}
|
|
164864
|
+
const nearer = declared[existingIndex];
|
|
164865
|
+
const inheritsPath = nearer.path === void 0;
|
|
164866
|
+
declared[existingIndex] = {
|
|
164867
|
+
...nearer,
|
|
164868
|
+
notation: mergeConnectionEndNotation(nearer.notation, candidate.notation),
|
|
164869
|
+
path: nearer.path ?? candidate.path,
|
|
164870
|
+
binding: inheritsPath ? candidate.binding : nearer.binding
|
|
164871
|
+
};
|
|
164872
|
+
}
|
|
164873
|
+
}
|
|
164874
|
+
const effective = this.connectionEndNotationsOf(owner, index2);
|
|
164875
|
+
const selectedDeclared = /* @__PURE__ */ new Set();
|
|
164876
|
+
const ends = effective.map((notation, ordinal) => {
|
|
164877
|
+
const claims = connectionEndNotationClaims(notation).map(lastSeg);
|
|
164878
|
+
let declaredIndex = declared.findIndex((candidate, candidateIndex) => !selectedDeclared.has(candidateIndex) && connectionEndNotationClaims(candidate.notation).map(lastSeg).some((claim) => claims.includes(claim)));
|
|
164879
|
+
if (declaredIndex < 0 && declared[ordinal] && !selectedDeclared.has(ordinal)) {
|
|
164880
|
+
const declaredClaims = connectionEndNotationClaims(declared[ordinal].notation).map(lastSeg);
|
|
164881
|
+
if (claims.length === 0 || declaredClaims.length === 0)
|
|
164882
|
+
declaredIndex = ordinal;
|
|
164883
|
+
}
|
|
164884
|
+
const concrete = declaredIndex >= 0 ? declared[declaredIndex] : void 0;
|
|
164885
|
+
if (declaredIndex >= 0)
|
|
164886
|
+
selectedDeclared.add(declaredIndex);
|
|
164887
|
+
return {
|
|
164888
|
+
notation: mergeConnectionEndNotation(concrete?.notation ?? {}, notation),
|
|
164889
|
+
path: concrete?.path,
|
|
164890
|
+
binding: concrete?.binding,
|
|
164891
|
+
ordinal
|
|
164892
|
+
};
|
|
164893
|
+
});
|
|
164894
|
+
for (const [declaredIndex, candidate] of declared.entries()) {
|
|
164895
|
+
if (selectedDeclared.has(declaredIndex))
|
|
164896
|
+
continue;
|
|
164897
|
+
ends.push({ ...candidate, ordinal: ends.length });
|
|
164898
|
+
}
|
|
164899
|
+
return ends;
|
|
164900
|
+
}
|
|
164901
|
+
connectorEndNotation(owner, rawEnd, index2, ordinal = 0) {
|
|
164902
|
+
const explicit = rawEnd && typeof rawEnd === "object" && "$type" in rawEnd ? connectionEndMultiplicity(rawEnd) : void 0;
|
|
164903
|
+
const role = this.connectorEndRole(rawEnd);
|
|
164904
|
+
const inherited = this.matchingConnectionEndNotation(this.connectionEndNotationsOf(owner, index2), role, ordinal);
|
|
164905
|
+
return mergeConnectionEndNotation({
|
|
164906
|
+
role,
|
|
164907
|
+
multiplicity: explicit ?? inherited?.multiplicity
|
|
164908
|
+
}, inherited);
|
|
164909
|
+
}
|
|
164299
164910
|
// FlowStmt ends for both spec forms (OMG SysML 8.2.2.16): explicit
|
|
164300
164911
|
// `from a to b`, and the keyword-less shorthand `flow a.x to b.y;` whose
|
|
164301
164912
|
// source is parsed as name + dotted segments.
|
|
@@ -164329,7 +164940,13 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164329
164940
|
const nodes = [];
|
|
164330
164941
|
const edges = [];
|
|
164331
164942
|
const frames = [];
|
|
164943
|
+
const primaryTarget = { nodes, edges, frames };
|
|
164944
|
+
const definitionTarget = { nodes: [], edges: [], frames: [] };
|
|
164332
164945
|
const eRef = { n: 0 };
|
|
164946
|
+
const drawnPartIds = /* @__PURE__ */ new Set();
|
|
164947
|
+
const endpointProvenance = /* @__PURE__ */ new Map();
|
|
164948
|
+
const typedPartUsages = [];
|
|
164949
|
+
const definitionRootIds = /* @__PURE__ */ new Map();
|
|
164333
164950
|
const enclosingPackage = (n2) => {
|
|
164334
164951
|
let c = n2.$container;
|
|
164335
164952
|
while (c && c !== scope) {
|
|
@@ -164352,22 +164969,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164352
164969
|
pkgFrame.set(pkg, id2);
|
|
164353
164970
|
return id2;
|
|
164354
164971
|
};
|
|
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
|
-
};
|
|
164972
|
+
const childUsagesOf = (part) => this.structuralChildUsagesOf(part, index2);
|
|
164371
164973
|
const effectiveMembersOf = (part) => {
|
|
164372
164974
|
const effective = [];
|
|
164373
164975
|
const claimedNames = /* @__PURE__ */ new Set();
|
|
@@ -164394,6 +164996,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164394
164996
|
const actionPort = /* @__PURE__ */ new Map();
|
|
164395
164997
|
const localNode = /* @__PURE__ */ new Map();
|
|
164396
164998
|
const actionPinIds = /* @__PURE__ */ new Set();
|
|
164999
|
+
const structuralPortIds = /* @__PURE__ */ new Set();
|
|
164397
165000
|
const addActionPort = (key, id2) => {
|
|
164398
165001
|
if (!actionPort.has(key))
|
|
164399
165002
|
actionPort.set(key, id2);
|
|
@@ -164411,6 +165014,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164411
165014
|
localPort.set(`${id2}.${rel2}`, port.id);
|
|
164412
165015
|
if (bare)
|
|
164413
165016
|
localPort.set(rel2, port.id);
|
|
165017
|
+
structuralPortIds.add(port.id);
|
|
164414
165018
|
}
|
|
164415
165019
|
};
|
|
164416
165020
|
for (const { usage, id: id2 } of childInfos)
|
|
@@ -164457,25 +165061,40 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164457
165061
|
return actionPort.get(firstLast) ?? void 0;
|
|
164458
165062
|
if (localPort.has(firstLast))
|
|
164459
165063
|
return localPort.get(firstLast);
|
|
165064
|
+
const rootId = localNode.get(segs[0]);
|
|
165065
|
+
const nestedId = rootId ? `${rootId}::${segs.slice(1).join("::")}` : void 0;
|
|
165066
|
+
if (nestedId && drawnPartIds.has(nestedId))
|
|
165067
|
+
return nestedId;
|
|
164460
165068
|
}
|
|
164461
165069
|
const bare = bareName2.get(segs[segs.length - 1]);
|
|
164462
165070
|
if (bare)
|
|
164463
165071
|
return bare;
|
|
164464
165072
|
return segs.length === 1 ? localNode.get(segs[0]) : void 0;
|
|
164465
165073
|
};
|
|
164466
|
-
return { resolve: resolve8, actionPinIds };
|
|
165074
|
+
return { resolve: resolve8, actionPinIds, structuralPortIds };
|
|
164467
165075
|
};
|
|
164468
|
-
const renderInstance = (part, instanceId, parentFrame, seenTypes, depth, inheritedLocalUsage, inheritedLocalPath = []) => {
|
|
165076
|
+
const renderInstance = (part, instanceId, parentFrame, seenTypes, depth, inheritedLocalUsage, inheritedLocalPath = [], target = primaryTarget, definitionLayerRoot = false, occurrenceInherited = false, parentOccurrencePath = []) => {
|
|
165077
|
+
drawnPartIds.add(instanceId);
|
|
165078
|
+
const occurrencePath = [...parentOccurrencePath, part];
|
|
165079
|
+
endpointProvenance.set(instanceId, occurrencePath);
|
|
164469
165080
|
const typeDef = part.isDef === true ? void 0 : this.resolveType(part, index2) ?? this.inheritedFeatureOwnersOf(part, index2).find((owner) => owner.isDef === true);
|
|
165081
|
+
if (typeDef && isPartDecl(typeDef) && typeDef.isDef === true && part.isDef !== true) {
|
|
165082
|
+
typedPartUsages.push({ usage: part, id: instanceId, definition: typeDef });
|
|
165083
|
+
}
|
|
164470
165084
|
const typeQ = typeDef ? qnameOf(typeDef) : void 0;
|
|
164471
165085
|
const declarationId = nameOf2(part) ? qnameOf(part) || instanceId : instanceId;
|
|
164472
165086
|
const projected = nameOf2(part) === void 0 || declarationId !== instanceId;
|
|
164473
165087
|
const localUsage = part.isDef !== true && !projected ? part : inheritedLocalUsage;
|
|
164474
165088
|
const localPath = part.isDef !== true && !projected ? [] : inheritedLocalPath;
|
|
164475
|
-
const
|
|
165089
|
+
const projectedPorts = this.portsOf(part, index2, uri, instanceId, localUsage);
|
|
165090
|
+
const ports = projectedPorts.ports;
|
|
165091
|
+
for (const [id2, origin] of projectedPorts.origins) {
|
|
165092
|
+
endpointProvenance.set(id2, [...occurrencePath, ...origin]);
|
|
165093
|
+
}
|
|
164476
165094
|
const syncDeclaration = this.synchronizationDeclarationOf(part, index2);
|
|
164477
165095
|
const editMeta = {
|
|
164478
165096
|
...ivEditMeta(part, instanceId, typeDef, localUsage, localPath, uri),
|
|
165097
|
+
...definitionLayerRoot ? { ivPartDef: true } : {},
|
|
164479
165098
|
...syncDeclaration && syncDeclaration !== part ? {
|
|
164480
165099
|
syncDeclarationId: qnameOf(syncDeclaration),
|
|
164481
165100
|
syncDeclarationName: effectiveNameOf(syncDeclaration),
|
|
@@ -164483,7 +165102,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164483
165102
|
} : {}
|
|
164484
165103
|
};
|
|
164485
165104
|
const children2 = depth < 8 && !(typeQ !== void 0 && seenTypes.has(typeQ)) ? childUsagesOf(part) : [];
|
|
164486
|
-
const concretePerformPath = (statement,
|
|
165105
|
+
const concretePerformPath = (statement, target2) => {
|
|
164487
165106
|
if (!this.isAnonymousBehaviorReference(statement)) {
|
|
164488
165107
|
return qnameOf(statement) || nameOf2(statement) || "perform";
|
|
164489
165108
|
}
|
|
@@ -164491,7 +165110,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164491
165110
|
const featureStart = segments.findIndex((segment, at) => at > 0 && segment.separator === ".");
|
|
164492
165111
|
if (featureStart > 0) {
|
|
164493
165112
|
const writtenPath = segments.map((segment) => segment.text).join("::");
|
|
164494
|
-
const targetName = qnameOf(
|
|
165113
|
+
const targetName = qnameOf(target2);
|
|
164495
165114
|
if (targetName === writtenPath || targetName.endsWith(`::${writtenPath}`)) {
|
|
164496
165115
|
return targetName;
|
|
164497
165116
|
}
|
|
@@ -164510,7 +165129,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164510
165129
|
return [qnameOf(root4), ...segments.slice(featureStart).map((segment) => segment.text)].join("::");
|
|
164511
165130
|
}
|
|
164512
165131
|
}
|
|
164513
|
-
return qnameOf(
|
|
165132
|
+
return qnameOf(target2) || nameOf2(target2) || segments.map((segment) => segment.text).join("::");
|
|
164514
165133
|
};
|
|
164515
165134
|
const performedActions = depth < 8 && !(typeQ !== void 0 && seenTypes.has(typeQ)) ? effectiveMembersOf(part).filter((m) => m.$type === "PerformStmt" && !!nameOf2(m)).map((act) => {
|
|
164516
165135
|
const pinSource = this.performTargetOf(act, index2) ?? act;
|
|
@@ -164550,7 +165169,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164550
165169
|
});
|
|
164551
165170
|
const emitOwnedActions = (frameOf) => {
|
|
164552
165171
|
for (const { act, name, id: actId, pins, meta } of performedActionInfos) {
|
|
164553
|
-
nodes.push({
|
|
165172
|
+
target.nodes.push({
|
|
164554
165173
|
id: actId,
|
|
164555
165174
|
name,
|
|
164556
165175
|
keyword: keywordFor(act),
|
|
@@ -164566,7 +165185,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164566
165185
|
}
|
|
164567
165186
|
};
|
|
164568
165187
|
if (children2.length > 0 || performedActions.length > 0) {
|
|
164569
|
-
frames.push({
|
|
165188
|
+
target.frames.push({
|
|
164570
165189
|
id: instanceId,
|
|
164571
165190
|
label: effectiveNameOf(part) ?? lastSeg(instanceId),
|
|
164572
165191
|
keyword: keywordFor(part),
|
|
@@ -164584,13 +165203,13 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164584
165203
|
const nextSeen = typeQ ? /* @__PURE__ */ new Set([...seenTypes, typeQ]) : seenTypes;
|
|
164585
165204
|
const childInfos = children2.map((cu) => ({ usage: cu, id: `${instanceId}::${effectiveNameOf(cu) ?? lastSeg(qnameOf(cu) || "")}` }));
|
|
164586
165205
|
for (const { usage, id: id2 } of childInfos) {
|
|
164587
|
-
renderInstance(usage, id2, instanceId, nextSeen, depth + 1, localUsage, [...localPath, effectiveNameOf(usage) ?? lastSeg(id2)]);
|
|
165206
|
+
renderInstance(usage, id2, instanceId, nextSeen, depth + 1, localUsage, [...localPath, effectiveNameOf(usage) ?? lastSeg(id2)], target, false, occurrenceInherited || !isAstDescendantOrSelf(usage, part), occurrencePath);
|
|
164588
165207
|
}
|
|
164589
165208
|
emitOwnedActions(instanceId);
|
|
164590
165209
|
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);
|
|
165210
|
+
this.emitInterconnectEdges(effectiveMembersOf(part), resolver.resolve, children2, index2, uri, target.nodes, target.edges, eRef, instanceId, resolver.actionPinIds, resolver.structuralPortIds, part, occurrenceInherited, endpointProvenance);
|
|
164592
165211
|
} else {
|
|
164593
|
-
nodes.push({
|
|
165212
|
+
target.nodes.push({
|
|
164594
165213
|
id: instanceId,
|
|
164595
165214
|
name: effectiveNameOf(part) ?? lastSeg(instanceId),
|
|
164596
165215
|
keyword: keywordFor(part),
|
|
@@ -164605,7 +165224,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164605
165224
|
meta: editMeta
|
|
164606
165225
|
});
|
|
164607
165226
|
const resolver = childResolver([], { usage: part, id: instanceId });
|
|
164608
|
-
this.emitInterconnectEdges(effectiveMembersOf(part), resolver.resolve, [], index2, uri, nodes, edges, eRef, instanceId, resolver.actionPinIds, part);
|
|
165227
|
+
this.emitInterconnectEdges(effectiveMembersOf(part), resolver.resolve, [], index2, uri, target.nodes, target.edges, eRef, instanceId, resolver.actionPinIds, resolver.structuralPortIds, part, occurrenceInherited, endpointProvenance);
|
|
164609
165228
|
}
|
|
164610
165229
|
};
|
|
164611
165230
|
const packageOfRoot = (root4) => enclosingPackage(root4) ?? scope;
|
|
@@ -164635,18 +165254,53 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164635
165254
|
const rootInfos = [];
|
|
164636
165255
|
for (const root4 of roots) {
|
|
164637
165256
|
const id2 = rootOccurrenceIds.get(root4) ?? rootBaseId(root4);
|
|
164638
|
-
|
|
165257
|
+
const rootIsDefinition = root4.isDef === true;
|
|
165258
|
+
if (rootIsDefinition)
|
|
165259
|
+
definitionRootIds.set(root4, id2);
|
|
165260
|
+
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
165261
|
rootInfos.push({ usage: root4, id: id2, pkg: packageOfRoot(root4) });
|
|
164640
165262
|
}
|
|
165263
|
+
for (let cursor = 0; cursor < typedPartUsages.length; cursor++) {
|
|
165264
|
+
const { definition } = typedPartUsages[cursor];
|
|
165265
|
+
if (definitionRootIds.has(definition))
|
|
165266
|
+
continue;
|
|
165267
|
+
const definitionId = qnameOf(definition) || nameOf2(definition);
|
|
165268
|
+
if (!definitionId)
|
|
165269
|
+
continue;
|
|
165270
|
+
definitionRootIds.set(definition, definitionId);
|
|
165271
|
+
renderInstance(definition, definitionId, void 0, /* @__PURE__ */ new Set(), 0, void 0, [], definitionTarget, true);
|
|
165272
|
+
}
|
|
165273
|
+
const linkedDefinitions = /* @__PURE__ */ new Set();
|
|
165274
|
+
for (const { id: id2, definition } of typedPartUsages) {
|
|
165275
|
+
const definitionId = definitionRootIds.get(definition);
|
|
165276
|
+
if (!definitionId || id2 === definitionId)
|
|
165277
|
+
continue;
|
|
165278
|
+
const key = `${id2}\0${definitionId}`;
|
|
165279
|
+
if (linkedDefinitions.has(key))
|
|
165280
|
+
continue;
|
|
165281
|
+
linkedDefinitions.add(key);
|
|
165282
|
+
definitionTarget.edges.push({
|
|
165283
|
+
id: `e${eRef.n++}`,
|
|
165284
|
+
from: id2,
|
|
165285
|
+
to: definitionId,
|
|
165286
|
+
kind: "definedBy",
|
|
165287
|
+
meta: { ivDefinedBy: true }
|
|
165288
|
+
});
|
|
165289
|
+
}
|
|
164641
165290
|
if (opts.packageFrames) {
|
|
164642
165291
|
for (const pkg of [scope, ...[...ast_utils_exports.streamAllContents(scope)].filter(isPackage)]) {
|
|
164643
165292
|
const localInfos = rootInfos.filter((r) => r.pkg === pkg && r.usage.isDef !== true);
|
|
164644
165293
|
const localRoots = localInfos.map((r) => r.usage);
|
|
164645
165294
|
const resolver = childResolver(localInfos);
|
|
164646
|
-
this.emitInterconnectEdges(membersOf(pkg), resolver.resolve, localRoots, index2, uri, nodes, edges, eRef, void 0, resolver.actionPinIds, pkg);
|
|
165295
|
+
this.emitInterconnectEdges(membersOf(pkg), resolver.resolve, localRoots, index2, uri, nodes, edges, eRef, void 0, resolver.actionPinIds, resolver.structuralPortIds, pkg, false, endpointProvenance);
|
|
164647
165296
|
}
|
|
164648
165297
|
}
|
|
164649
|
-
|
|
165298
|
+
const definitionLayer = definitionTarget.nodes.length > 0 || definitionTarget.edges.length > 0 || definitionTarget.frames.length > 0 ? {
|
|
165299
|
+
nodes: definitionTarget.nodes,
|
|
165300
|
+
edges: definitionTarget.edges,
|
|
165301
|
+
...definitionTarget.frames.length ? { frames: definitionTarget.frames } : {}
|
|
165302
|
+
} : void 0;
|
|
165303
|
+
return { nodes, edges, frames, definitionLayer };
|
|
164650
165304
|
}
|
|
164651
165305
|
// REQ-192 — Interconnection View for a single part/part-def anchor: the anchor
|
|
164652
165306
|
// is the (non-collapsible) container frame and its internals nest inside it,
|
|
@@ -164654,7 +165308,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164654
165308
|
buildInterconnectionView(ctx) {
|
|
164655
165309
|
const anchor = ctx.anchor;
|
|
164656
165310
|
const anchorId = qnameOf(anchor) || nameOf2(anchor) || "__anchor__";
|
|
164657
|
-
const { nodes, edges, frames } = this.renderIvRoots(ctx, [anchor], { packageFrames: false });
|
|
165311
|
+
const { nodes, edges, frames, definitionLayer } = this.renderIvRoots(ctx, [anchor], { packageFrames: false });
|
|
164658
165312
|
if (anchor.isDef === true && frames.length === 0 && nodes.every((n2) => !n2.ports?.length && !n2.compartments?.length)) {
|
|
164659
165313
|
return this.model("iv", anchor, [], []);
|
|
164660
165314
|
}
|
|
@@ -164668,6 +165322,8 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164668
165322
|
}
|
|
164669
165323
|
const model = this.model("iv", anchor, nodes, edges);
|
|
164670
165324
|
model.frames = frames;
|
|
165325
|
+
if (definitionLayer)
|
|
165326
|
+
model.layers = { definitions: definitionLayer };
|
|
164671
165327
|
model.meta = { ...model.meta, unified: true, groupMode: "nested" };
|
|
164672
165328
|
return model;
|
|
164673
165329
|
}
|
|
@@ -164676,14 +165332,14 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164676
165332
|
// single Interconnection View (called once over the anchor's whole subtree)
|
|
164677
165333
|
// and the package overview (called once per container part, tagging any
|
|
164678
165334
|
// 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) {
|
|
165335
|
+
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
165336
|
const memberList2 = [...members];
|
|
164681
165337
|
const relationshipFields = (source) => {
|
|
164682
165338
|
let directMember = source;
|
|
164683
165339
|
while (directMember.$container && directMember.$container !== memberOwner) {
|
|
164684
165340
|
directMember = directMember.$container;
|
|
164685
165341
|
}
|
|
164686
|
-
const inherited = !!memberOwner && directMember.$container !== memberOwner;
|
|
165342
|
+
const inherited = memberOwnerInherited || !!memberOwner && directMember.$container !== memberOwner;
|
|
164687
165343
|
const meta = {
|
|
164688
165344
|
...inherited ? { ivInheritedRelation: true } : {},
|
|
164689
165345
|
...frameId ? { ivRelationshipOwnerId: frameId } : {}
|
|
@@ -164694,12 +165350,38 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164694
165350
|
};
|
|
164695
165351
|
};
|
|
164696
165352
|
const supportsEndpoints = (kind, ids) => {
|
|
165353
|
+
if (kind === "interface") {
|
|
165354
|
+
return ids.length > 0 && ids.every((id2) => structuralPortIds.has(id2));
|
|
165355
|
+
}
|
|
164697
165356
|
const pinCount = ids.filter((id2) => actionPinIds.has(id2)).length;
|
|
164698
165357
|
if (pinCount === 0)
|
|
164699
165358
|
return true;
|
|
164700
165359
|
return ids.length === 2 && pinCount === 2 && (kind === "flow" || kind === "binding");
|
|
164701
165360
|
};
|
|
164702
|
-
const dot = (id2, name, src) => ({
|
|
165361
|
+
const dot = (id2, name, src) => ({
|
|
165362
|
+
id: id2,
|
|
165363
|
+
name,
|
|
165364
|
+
keyword: "connection",
|
|
165365
|
+
isDef: false,
|
|
165366
|
+
shape: "dot",
|
|
165367
|
+
frame: frameId,
|
|
165368
|
+
source: sourceOf2(src, uri),
|
|
165369
|
+
meta: { naryConnectionHub: true }
|
|
165370
|
+
});
|
|
165371
|
+
const connectionUsageNodeId = (connection) => {
|
|
165372
|
+
const source = sourceOf2(connection, uri);
|
|
165373
|
+
const ownerId = frameId ?? (qnameOf(memberOwner ?? connection) || "iv");
|
|
165374
|
+
const semanticName = frameId ? effectiveNameOf(connection) : qnameOf(connection);
|
|
165375
|
+
const suffix = semanticName ?? (source ? `${source.range.start.line}_${source.range.start.character}` : `${eRef.n}`);
|
|
165376
|
+
return `${ownerId}::__connection_${suffix}`;
|
|
165377
|
+
};
|
|
165378
|
+
const interfaceUsageNodeId = (interfaceUsage) => {
|
|
165379
|
+
const source = sourceOf2(interfaceUsage, uri);
|
|
165380
|
+
const ownerId = frameId ?? (qnameOf(memberOwner ?? interfaceUsage) || "iv");
|
|
165381
|
+
const semanticName = frameId ? effectiveNameOf(interfaceUsage) : qnameOf(interfaceUsage);
|
|
165382
|
+
const suffix = semanticName ?? (source ? `${source.range.start.line}_${source.range.start.character}` : `${eRef.n}`);
|
|
165383
|
+
return `${ownerId}::__interface_${suffix}`;
|
|
165384
|
+
};
|
|
164703
165385
|
const emitConnector = (rawEnds, src, label, name, type) => {
|
|
164704
165386
|
const resolvedEnds = rawEnds.map((end) => ({ id: resolveEnd(this.connectorEndPath(end) ?? ""), end })).filter((x) => !!x.id);
|
|
164705
165387
|
if (resolvedEnds.length < 2)
|
|
@@ -164707,6 +165389,8 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164707
165389
|
if (!supportsEndpoints("connect", resolvedEnds.map(({ id: id2 }) => id2)))
|
|
164708
165390
|
return;
|
|
164709
165391
|
if (resolvedEnds.length === 2) {
|
|
165392
|
+
const fromNotation = this.connectorEndNotation(src, resolvedEnds[0].end, index2, 0);
|
|
165393
|
+
const toNotation = this.connectorEndNotation(src, resolvedEnds[1].end, index2, 1);
|
|
164710
165394
|
edges.push({
|
|
164711
165395
|
id: `e${eRef.n++}`,
|
|
164712
165396
|
from: resolvedEnds[0].id,
|
|
@@ -164716,15 +165400,20 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164716
165400
|
type,
|
|
164717
165401
|
isDef: false,
|
|
164718
165402
|
label,
|
|
164719
|
-
|
|
164720
|
-
|
|
165403
|
+
endRoleFrom: fromNotation.role,
|
|
165404
|
+
endLabelFrom: fromNotation.multiplicity,
|
|
165405
|
+
endAdornmentFrom: fromNotation.adornment,
|
|
165406
|
+
endRoleTo: toNotation.role,
|
|
165407
|
+
endLabelTo: toNotation.multiplicity,
|
|
165408
|
+
endAdornmentTo: toNotation.adornment,
|
|
164721
165409
|
...relationshipFields(src)
|
|
164722
165410
|
});
|
|
164723
165411
|
return;
|
|
164724
165412
|
}
|
|
164725
165413
|
const dotId = `__nary_${eRef.n}__`;
|
|
164726
165414
|
nodes.push(dot(dotId, label ?? "", src));
|
|
164727
|
-
for (const { id: endId, end } of resolvedEnds) {
|
|
165415
|
+
for (const [ordinal, { id: endId, end }] of resolvedEnds.entries()) {
|
|
165416
|
+
const notation = this.connectorEndNotation(src, end, index2, ordinal);
|
|
164728
165417
|
edges.push({
|
|
164729
165418
|
id: `e${eRef.n++}`,
|
|
164730
165419
|
from: dotId,
|
|
@@ -164734,7 +165423,9 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164734
165423
|
type,
|
|
164735
165424
|
isDef: false,
|
|
164736
165425
|
label,
|
|
164737
|
-
|
|
165426
|
+
endRoleTo: notation.role,
|
|
165427
|
+
endLabelTo: notation.multiplicity,
|
|
165428
|
+
endAdornmentTo: notation.adornment,
|
|
164738
165429
|
...relationshipFields(src)
|
|
164739
165430
|
});
|
|
164740
165431
|
}
|
|
@@ -164769,21 +165460,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164769
165460
|
} else if (m.$type === "ConnectStmt") {
|
|
164770
165461
|
const cs = m;
|
|
164771
165462
|
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
|
-
}
|
|
165463
|
+
emitConnector(cs.ends, m);
|
|
164787
165464
|
} else {
|
|
164788
165465
|
const srcEnd = m.source;
|
|
164789
165466
|
const tgtEnd = m.target;
|
|
@@ -164791,6 +165468,8 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164791
165468
|
const from = resolveEnd(srcPath);
|
|
164792
165469
|
const to = resolveEnd(this.connectorEndPath(tgtEnd) ?? "");
|
|
164793
165470
|
if (from && to && supportsEndpoints("connect", [from, to])) {
|
|
165471
|
+
const fromNotation = this.connectorEndNotation(m, srcEnd, index2, 0);
|
|
165472
|
+
const toNotation = this.connectorEndNotation(m, tgtEnd, index2, 1);
|
|
164794
165473
|
edges.push({
|
|
164795
165474
|
id: `e${eRef.n++}`,
|
|
164796
165475
|
from,
|
|
@@ -164798,8 +165477,12 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164798
165477
|
kind: "connect",
|
|
164799
165478
|
label: this.flowItemLabel(srcPath, parts, index2),
|
|
164800
165479
|
// REQ-179 — connector end multiplicities (`connect [1] a to [0..*] b;`)
|
|
164801
|
-
|
|
164802
|
-
|
|
165480
|
+
endRoleFrom: fromNotation.role,
|
|
165481
|
+
endLabelFrom: fromNotation.multiplicity,
|
|
165482
|
+
endAdornmentFrom: fromNotation.adornment,
|
|
165483
|
+
endRoleTo: toNotation.role,
|
|
165484
|
+
endLabelTo: toNotation.multiplicity,
|
|
165485
|
+
endAdornmentTo: toNotation.adornment,
|
|
164803
165486
|
...relationshipFields(m)
|
|
164804
165487
|
});
|
|
164805
165488
|
}
|
|
@@ -164845,108 +165528,192 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164845
165528
|
});
|
|
164846
165529
|
}
|
|
164847
165530
|
} 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) {
|
|
165531
|
+
const interfaceUsage = m;
|
|
165532
|
+
if (interfaceUsage.target !== void 0 && interfaceUsage.connect === void 0) {
|
|
165533
|
+
const sourcePath = [nameOf2(m) ?? "", ...interfaceUsage.srcSegs ?? []].filter(Boolean).join(".");
|
|
165534
|
+
const targetPath = this.featurePath(interfaceUsage.target) ?? "";
|
|
165535
|
+
const from = resolveEnd(sourcePath);
|
|
165536
|
+
const to = resolveEnd(targetPath);
|
|
165537
|
+
if (from && to && supportsEndpoints("interface", [from, to])) {
|
|
164857
165538
|
edges.push({
|
|
164858
165539
|
id: `e${eRef.n++}`,
|
|
164859
|
-
from
|
|
164860
|
-
to
|
|
165540
|
+
from,
|
|
165541
|
+
to,
|
|
164861
165542
|
kind: "interface",
|
|
164862
|
-
name,
|
|
164863
|
-
type,
|
|
164864
165543
|
isDef: false,
|
|
164865
|
-
label,
|
|
164866
|
-
endLabelFrom: multText(resolvedEnds[0].end),
|
|
164867
|
-
endLabelTo: multText(resolvedEnds[1].end),
|
|
165544
|
+
label: "\xABinterface\xBB",
|
|
164868
165545
|
...relationshipFields(m)
|
|
164869
165546
|
});
|
|
164870
|
-
}
|
|
164871
|
-
|
|
164872
|
-
|
|
164873
|
-
|
|
164874
|
-
|
|
164875
|
-
|
|
164876
|
-
|
|
164877
|
-
|
|
164878
|
-
|
|
164879
|
-
|
|
164880
|
-
|
|
164881
|
-
|
|
164882
|
-
|
|
164883
|
-
|
|
164884
|
-
|
|
164885
|
-
|
|
165547
|
+
}
|
|
165548
|
+
continue;
|
|
165549
|
+
}
|
|
165550
|
+
const name = effectiveNameOf(m);
|
|
165551
|
+
const inheritedType = this.inheritedFeatureOwnersOf(m, index2).filter((candidate) => isInterfaceDecl(candidate) && candidate.isDef !== true).map(typeText).find((candidate) => !!candidate);
|
|
165552
|
+
const type = typeText(m) ?? inheritedType;
|
|
165553
|
+
const usageEnds = this.effectiveConnectionUsageEndsOf(m, index2);
|
|
165554
|
+
const usageId = interfaceUsageNodeId(m);
|
|
165555
|
+
const usageSource = sourceOf2(m, uri);
|
|
165556
|
+
const relationship = relationshipFields(m);
|
|
165557
|
+
const resolvedUsageEnds = usageEnds.flatMap((end, ordinal) => {
|
|
165558
|
+
const targetId = end.path ? resolveEnd(end.path) : void 0;
|
|
165559
|
+
return targetId && supportsEndpoints("interface", [targetId]) ? [{ end, ordinal, targetId }] : [];
|
|
165560
|
+
});
|
|
165561
|
+
const inherited = relationship.meta?.ivInheritedRelation === true;
|
|
165562
|
+
const visibleUsageEnds = inherited ? resolvedUsageEnds.filter(({ end, targetId }) => this.connectionUsageEndBindingMatches(end, endpointProvenance.get(targetId), frameId ? endpointProvenance.get(frameId) : void 0, index2)) : resolvedUsageEnds;
|
|
165563
|
+
if (inherited && visibleUsageEnds.length === 0)
|
|
165564
|
+
continue;
|
|
165565
|
+
const resolvedOrdinals = new Set(visibleUsageEnds.map(({ ordinal }) => ordinal));
|
|
165566
|
+
const ownerNode = frameId ? nodes.find((node) => node.id === frameId) : void 0;
|
|
165567
|
+
const usageFrame = ownerNode ? ownerNode.frame : frameId;
|
|
165568
|
+
const ports = usageEnds.map((end, ordinal) => {
|
|
165569
|
+
const role = end.notation.role;
|
|
165570
|
+
const direction = end.notation.direction === "in" || end.notation.direction === "out" || end.notation.direction === "inout" ? end.notation.direction : void 0;
|
|
165571
|
+
return {
|
|
165572
|
+
id: `${usageId}::__end_${ordinal}`,
|
|
165573
|
+
name: role ?? `end${ordinal + 1}`,
|
|
165574
|
+
type: end.notation.type,
|
|
165575
|
+
direction,
|
|
165576
|
+
isDef: false,
|
|
165577
|
+
pin: false,
|
|
165578
|
+
source: usageSource,
|
|
165579
|
+
meta: {
|
|
165580
|
+
// The shared renderer uses this presentation marker for
|
|
165581
|
+
// the outline-coloured dot and its single outward dock.
|
|
165582
|
+
connectionEndPin: true,
|
|
165583
|
+
interfaceEndPort: true,
|
|
165584
|
+
connectionUsageId: usageId,
|
|
165585
|
+
interfaceUsageId: usageId,
|
|
165586
|
+
connectionEndOrdinal: ordinal,
|
|
165587
|
+
...role ? { connectionEndRole: role } : {},
|
|
165588
|
+
...resolvedOrdinals.has(ordinal) ? { connectionEndBound: true } : {},
|
|
165589
|
+
...end.notation.multiplicity ? { connectionEndMultiplicity: end.notation.multiplicity } : {},
|
|
165590
|
+
...end.notation.adornment ? { connectionEndAdornment: end.notation.adornment } : {}
|
|
164886
165591
|
}
|
|
164887
|
-
}
|
|
164888
|
-
|
|
164889
|
-
|
|
164890
|
-
|
|
164891
|
-
|
|
164892
|
-
|
|
164893
|
-
|
|
164894
|
-
|
|
164895
|
-
|
|
164896
|
-
|
|
164897
|
-
|
|
164898
|
-
|
|
164899
|
-
|
|
164900
|
-
|
|
164901
|
-
|
|
164902
|
-
}
|
|
165592
|
+
};
|
|
165593
|
+
});
|
|
165594
|
+
nodes.push({
|
|
165595
|
+
id: usageId,
|
|
165596
|
+
name: name ?? ANONYMOUS_INTERFACE_NAME,
|
|
165597
|
+
keyword: "interface",
|
|
165598
|
+
isDef: false,
|
|
165599
|
+
shape: "box",
|
|
165600
|
+
type,
|
|
165601
|
+
multiplicity: multText(m),
|
|
165602
|
+
ports,
|
|
165603
|
+
...usageFrame ? { frame: usageFrame } : {},
|
|
165604
|
+
compartments: this.compartmentsFor(m, uri, index2),
|
|
165605
|
+
source: usageSource,
|
|
165606
|
+
meta: {
|
|
165607
|
+
...relationship.meta ?? {},
|
|
165608
|
+
interfaceUsage: true,
|
|
165609
|
+
...name ? { explicitRelationshipName: name } : {}
|
|
164903
165610
|
}
|
|
165611
|
+
});
|
|
165612
|
+
for (const { end, ordinal, targetId } of visibleUsageEnds) {
|
|
165613
|
+
const role = end.notation.role;
|
|
165614
|
+
edges.push({
|
|
165615
|
+
id: `e${eRef.n++}`,
|
|
165616
|
+
from: ports[ordinal].id,
|
|
165617
|
+
to: targetId,
|
|
165618
|
+
kind: "interface",
|
|
165619
|
+
name,
|
|
165620
|
+
type,
|
|
165621
|
+
isDef: false,
|
|
165622
|
+
endRoleFrom: role,
|
|
165623
|
+
endLabelFrom: end.notation.multiplicity,
|
|
165624
|
+
endAdornmentFrom: end.notation.adornment,
|
|
165625
|
+
source: relationship.source,
|
|
165626
|
+
meta: {
|
|
165627
|
+
...relationship.meta ?? {},
|
|
165628
|
+
interfaceUsageEnd: true,
|
|
165629
|
+
interfaceUsageId: usageId,
|
|
165630
|
+
connectionUsageId: usageId,
|
|
165631
|
+
connectionEndOrdinal: ordinal,
|
|
165632
|
+
...role ? { connectionEndRole: role } : {}
|
|
165633
|
+
}
|
|
165634
|
+
});
|
|
164904
165635
|
}
|
|
164905
165636
|
} else if (isConnectionDecl(m) && m.isDef !== true) {
|
|
164906
|
-
const
|
|
164907
|
-
|
|
165637
|
+
const name = effectiveNameOf(m);
|
|
165638
|
+
const inheritedType = this.inheritedFeatureOwnersOf(m, index2).filter((candidate) => isConnectionDecl(candidate) && candidate.isDef !== true).map(typeText).find((candidate) => !!candidate);
|
|
165639
|
+
const type = typeText(m) ?? inheritedType;
|
|
165640
|
+
const usageEnds = this.effectiveConnectionUsageEndsOf(m, index2);
|
|
165641
|
+
const usageId = connectionUsageNodeId(m);
|
|
165642
|
+
const usageSource = sourceOf2(m, uri);
|
|
165643
|
+
const relationship = relationshipFields(m);
|
|
165644
|
+
const resolvedUsageEnds = usageEnds.flatMap((end, ordinal) => {
|
|
165645
|
+
const targetId = end.path ? resolveEnd(end.path) : void 0;
|
|
165646
|
+
return targetId && supportsEndpoints("connect", [targetId]) ? [{ end, ordinal, targetId }] : [];
|
|
165647
|
+
});
|
|
165648
|
+
const inherited = relationship.meta?.ivInheritedRelation === true;
|
|
165649
|
+
const visibleUsageEnds = inherited ? resolvedUsageEnds.filter(({ end, targetId }) => this.connectionUsageEndBindingMatches(end, endpointProvenance.get(targetId), frameId ? endpointProvenance.get(frameId) : void 0, index2)) : resolvedUsageEnds;
|
|
165650
|
+
if (inherited && visibleUsageEnds.length === 0) {
|
|
164908
165651
|
continue;
|
|
164909
|
-
|
|
164910
|
-
const
|
|
164911
|
-
const
|
|
164912
|
-
|
|
164913
|
-
|
|
164914
|
-
|
|
164915
|
-
|
|
164916
|
-
|
|
164917
|
-
|
|
164918
|
-
|
|
164919
|
-
|
|
164920
|
-
|
|
164921
|
-
|
|
164922
|
-
|
|
164923
|
-
|
|
164924
|
-
|
|
164925
|
-
|
|
164926
|
-
|
|
164927
|
-
|
|
164928
|
-
|
|
164929
|
-
}
|
|
165652
|
+
}
|
|
165653
|
+
const resolvedOrdinals = new Set(visibleUsageEnds.map(({ ordinal }) => ordinal));
|
|
165654
|
+
const ownerNode = frameId ? nodes.find((node) => node.id === frameId) : void 0;
|
|
165655
|
+
const usageFrame = ownerNode ? ownerNode.frame : frameId;
|
|
165656
|
+
const ports = usageEnds.map((end, ordinal) => {
|
|
165657
|
+
const role = end.notation.role;
|
|
165658
|
+
const direction = end.notation.direction === "in" || end.notation.direction === "out" || end.notation.direction === "inout" ? end.notation.direction : void 0;
|
|
165659
|
+
return {
|
|
165660
|
+
id: `${usageId}::__end_${ordinal}`,
|
|
165661
|
+
name: role ?? `end${ordinal + 1}`,
|
|
165662
|
+
type: end.notation.type,
|
|
165663
|
+
direction,
|
|
165664
|
+
isDef: false,
|
|
165665
|
+
pin: true,
|
|
165666
|
+
source: usageSource,
|
|
165667
|
+
meta: {
|
|
165668
|
+
connectionEndPin: true,
|
|
165669
|
+
connectionUsageId: usageId,
|
|
165670
|
+
connectionEndOrdinal: ordinal,
|
|
165671
|
+
...role ? { connectionEndRole: role } : {},
|
|
165672
|
+
...resolvedOrdinals.has(ordinal) ? { connectionEndBound: true } : {},
|
|
165673
|
+
...end.notation.multiplicity ? { connectionEndMultiplicity: end.notation.multiplicity } : {},
|
|
165674
|
+
...end.notation.adornment ? { connectionEndAdornment: end.notation.adornment } : {}
|
|
164930
165675
|
}
|
|
165676
|
+
};
|
|
165677
|
+
});
|
|
165678
|
+
nodes.push({
|
|
165679
|
+
id: usageId,
|
|
165680
|
+
name: name ?? "connection",
|
|
165681
|
+
keyword: "connection",
|
|
165682
|
+
isDef: false,
|
|
165683
|
+
shape: "box",
|
|
165684
|
+
type,
|
|
165685
|
+
ports,
|
|
165686
|
+
...usageFrame ? { frame: usageFrame } : {},
|
|
165687
|
+
compartments: this.compartmentsFor(m, uri, index2),
|
|
165688
|
+
source: usageSource,
|
|
165689
|
+
meta: {
|
|
165690
|
+
...relationship.meta ?? {},
|
|
165691
|
+
connectionUsage: true,
|
|
165692
|
+
...name ? { explicitRelationshipName: name } : {}
|
|
164931
165693
|
}
|
|
164932
|
-
}
|
|
164933
|
-
|
|
164934
|
-
const
|
|
164935
|
-
|
|
164936
|
-
|
|
164937
|
-
|
|
164938
|
-
|
|
164939
|
-
|
|
164940
|
-
|
|
164941
|
-
|
|
164942
|
-
|
|
164943
|
-
|
|
164944
|
-
|
|
164945
|
-
|
|
164946
|
-
|
|
164947
|
-
|
|
164948
|
-
|
|
164949
|
-
|
|
165694
|
+
});
|
|
165695
|
+
for (const { end, ordinal, targetId } of visibleUsageEnds) {
|
|
165696
|
+
const role = end.notation.role;
|
|
165697
|
+
edges.push({
|
|
165698
|
+
id: `e${eRef.n++}`,
|
|
165699
|
+
from: ports[ordinal].id,
|
|
165700
|
+
to: targetId,
|
|
165701
|
+
kind: "connect",
|
|
165702
|
+
name,
|
|
165703
|
+
type,
|
|
165704
|
+
isDef: false,
|
|
165705
|
+
endRoleFrom: role,
|
|
165706
|
+
endLabelFrom: end.notation.multiplicity,
|
|
165707
|
+
endAdornmentFrom: end.notation.adornment,
|
|
165708
|
+
source: relationship.source,
|
|
165709
|
+
meta: {
|
|
165710
|
+
...relationship.meta ?? {},
|
|
165711
|
+
connectionUsageEnd: true,
|
|
165712
|
+
connectionUsageId: usageId,
|
|
165713
|
+
connectionEndOrdinal: ordinal,
|
|
165714
|
+
...role ? { connectionEndRole: role } : {}
|
|
165715
|
+
}
|
|
165716
|
+
});
|
|
164950
165717
|
}
|
|
164951
165718
|
}
|
|
164952
165719
|
}
|
|
@@ -164997,9 +165764,11 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
164997
165764
|
if (roots.length === 0) {
|
|
164998
165765
|
roots = all.filter((d) => isDefPart(d) && !insideAPart(d) && !insideAnOccurrence(d) && hasInternalParts(d)).sort(byName);
|
|
164999
165766
|
}
|
|
165000
|
-
const { nodes, edges, frames } = this.renderIvRoots(ctx, roots, { packageFrames: true });
|
|
165767
|
+
const { nodes, edges, frames, definitionLayer } = this.renderIvRoots(ctx, roots, { packageFrames: true });
|
|
165001
165768
|
const model = this.model("iv", scope, nodes, edges);
|
|
165002
165769
|
model.frames = frames;
|
|
165770
|
+
if (definitionLayer)
|
|
165771
|
+
model.layers = { definitions: definitionLayer };
|
|
165003
165772
|
model.meta = { ...model.meta, overview: true, groupMode: "nested" };
|
|
165004
165773
|
model.root = { ...model.root, keyword: "package", name: nameOf2(scope) ?? model.root.name };
|
|
165005
165774
|
if (nodes.length === 0 && frames.length === 0) {
|
|
@@ -165011,7 +165780,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
165011
165780
|
// (non-package) single view of `kind`; each renders as one overview tile.
|
|
165012
165781
|
collectOverviewAnchors(scope, kind, index2) {
|
|
165013
165782
|
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));
|
|
165783
|
+
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
165784
|
const naturalAnchors = all.filter(isNaturalAnchor);
|
|
165016
165785
|
const hasNaturalDescendant = (candidate) => naturalAnchors.some((natural) => {
|
|
165017
165786
|
for (let cur = natural.$container; cur && cur !== scope; cur = cur.$container) {
|
|
@@ -165072,7 +165841,8 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
165072
165841
|
const scopeQ = qnameOf(ctx.anchor);
|
|
165073
165842
|
const collected = this.collectOverviewAnchors(ctx.anchor, kind, ctx.index).sort((a2, b) => (qnameOf(a2) || nameOf2(a2) || "").localeCompare(qnameOf(b) || nameOf2(b) || ""));
|
|
165074
165843
|
const sequenceScaffold = kind === "sv" && this.nestedUsages(ctx.anchor, isPartDecl).some((n2) => nameOf2(n2) !== void 0);
|
|
165075
|
-
const
|
|
165844
|
+
const useScopeFallback = kind === "gev" ? this.hasPlacedGeometryObject(ctx.anchor, ctx.index) : sequenceScaffold;
|
|
165845
|
+
const anchors = collected.length > 0 ? collected : useScopeFallback ? [ctx.anchor] : [];
|
|
165076
165846
|
const nodes = [];
|
|
165077
165847
|
const edges = [];
|
|
165078
165848
|
const frames = [];
|
|
@@ -168024,18 +168794,31 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
168024
168794
|
geo.sizeZ = Math.abs(sizeZ);
|
|
168025
168795
|
if (radius !== void 0)
|
|
168026
168796
|
geo.radius = Math.abs(radius);
|
|
168027
|
-
const
|
|
168028
|
-
|
|
168797
|
+
const localYaw = local.rot === void 0 ? void 0 : rotationTransform([0, 0, 1], local.rot);
|
|
168798
|
+
const orientedWorld = localYaw ? composeTransforms(state.world, localYaw) : state.world;
|
|
168799
|
+
const yaw = yawOf(orientedWorld);
|
|
168800
|
+
if (!state.fromFrame && local.rot !== void 0)
|
|
168029
168801
|
geo.rot = local.rot;
|
|
168030
168802
|
else if (yaw !== void 0 && yaw !== 0)
|
|
168031
168803
|
geo.rot = yaw;
|
|
168032
|
-
|
|
168033
|
-
|
|
168034
|
-
|
|
168804
|
+
if (state.fromFrame && !isUnrotated(orientedWorld)) {
|
|
168805
|
+
const r = orientedWorld.r.map(roundGeo);
|
|
168806
|
+
geo.orientation = [
|
|
168807
|
+
r[0],
|
|
168808
|
+
r[1],
|
|
168809
|
+
r[2],
|
|
168810
|
+
r[3],
|
|
168811
|
+
r[4],
|
|
168812
|
+
r[5],
|
|
168813
|
+
r[6],
|
|
168814
|
+
r[7],
|
|
168815
|
+
r[8]
|
|
168816
|
+
];
|
|
168817
|
+
}
|
|
168035
168818
|
if (state.fromFrame)
|
|
168036
168819
|
geo.frame = true;
|
|
168037
|
-
if (approx)
|
|
168038
|
-
geo.approx = approx;
|
|
168820
|
+
if (state.approx)
|
|
168821
|
+
geo.approx = state.approx;
|
|
168039
168822
|
return geo;
|
|
168040
168823
|
}
|
|
168041
168824
|
// issue #107 — a node's OWN placement relative to its parent frame: the
|
|
@@ -168128,7 +168911,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
168128
168911
|
return {
|
|
168129
168912
|
present: true,
|
|
168130
168913
|
transform: translationTransform(origin),
|
|
168131
|
-
approx: reoriented ? "its frame declares basisDirections
|
|
168914
|
+
approx: reoriented ? "its frame declares basisDirections that this workspace cannot evaluate numerically" : void 0,
|
|
168132
168915
|
unit,
|
|
168133
168916
|
sourcePath
|
|
168134
168917
|
};
|
|
@@ -168685,9 +169468,10 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
168685
169468
|
portsOf(node, index2, uri, ownerId, localUsage) {
|
|
168686
169469
|
const ports = [];
|
|
168687
169470
|
const map3 = /* @__PURE__ */ new Map();
|
|
169471
|
+
const origins = /* @__PURE__ */ new Map();
|
|
168688
169472
|
const visibleNames = /* @__PURE__ */ new Set();
|
|
168689
169473
|
const usageName = effectiveNameOf(node);
|
|
168690
|
-
const makePort = (portNode, inheritedFromType, parentPortId, parentPath) => {
|
|
169474
|
+
const makePort = (portNode, inheritedFromType, parentPortId, parentPath, parentOrigin = []) => {
|
|
168691
169475
|
const pn = effectiveNameOf(portNode);
|
|
168692
169476
|
if (!pn)
|
|
168693
169477
|
return void 0;
|
|
@@ -168772,7 +169556,9 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
168772
169556
|
if (usageName)
|
|
168773
169557
|
map3.set(`${usageName}.${rel2}`, portId);
|
|
168774
169558
|
map3.set(`${ownerId}.${rel2}`, portId);
|
|
168775
|
-
|
|
169559
|
+
const origin = [...parentOrigin, portNode];
|
|
169560
|
+
origins.set(portId, origin);
|
|
169561
|
+
return { port, portTypeDef, inheritedOwners, origin };
|
|
168776
169562
|
};
|
|
168777
169563
|
const addNested = (portNode, made, inheritedFromType, path10, depth, seenTypes) => {
|
|
168778
169564
|
if (depth > NESTED_PORT_MAX_DEPTH)
|
|
@@ -168783,18 +169569,20 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
168783
169569
|
const nestedSeen = /* @__PURE__ */ new Set();
|
|
168784
169570
|
const nestedSources = [
|
|
168785
169571
|
// declared in this port usage's body: as local as its parent is
|
|
168786
|
-
...membersOf(portNode).map((member) => ({ member, inherited: inheritedFromType })),
|
|
169572
|
+
...membersOf(portNode).map((member) => ({ member, inherited: inheritedFromType, source: portNode })),
|
|
168787
169573
|
// every effective owner contributes its body, nearest first
|
|
168788
|
-
...!repeatedType ? made.inheritedOwners.flatMap((owner) => membersOf(owner).map((member) => ({ member, inherited: true }))) : []
|
|
169574
|
+
...!repeatedType ? made.inheritedOwners.flatMap((owner) => membersOf(owner).map((member) => ({ member, inherited: true, source: owner }))) : []
|
|
168789
169575
|
];
|
|
168790
|
-
for (const { member, inherited } of nestedSources) {
|
|
169576
|
+
for (const { member, inherited, source } of nestedSources) {
|
|
168791
169577
|
if (!isPortDecl(member) || member.isDef === true)
|
|
168792
169578
|
continue;
|
|
169579
|
+
if (inherited && this.isInheritedLibraryBackboneFeature(source, member, index2))
|
|
169580
|
+
continue;
|
|
168793
169581
|
const nn = effectiveNameOf(member);
|
|
168794
169582
|
if (!nn || nestedSeen.has(nn))
|
|
168795
169583
|
continue;
|
|
168796
169584
|
nestedSeen.add(nn);
|
|
168797
|
-
const child = makePort(member, inherited, made.port.id, path10);
|
|
169585
|
+
const child = makePort(member, inherited, made.port.id, path10, made.origin);
|
|
168798
169586
|
if (!child)
|
|
168799
169587
|
continue;
|
|
168800
169588
|
ports.push(child.port);
|
|
@@ -168816,11 +169604,12 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
168816
169604
|
if (isPortDecl(m) && m.isDef !== true)
|
|
168817
169605
|
addPort(m, false);
|
|
168818
169606
|
for (const inherited of this.inheritedFeatureOwnersOf(node, index2)) {
|
|
168819
|
-
for (const m of membersOf(inherited))
|
|
168820
|
-
if (isPortDecl(m) && m.isDef !== true)
|
|
169607
|
+
for (const m of membersOf(inherited)) {
|
|
169608
|
+
if (isPortDecl(m) && m.isDef !== true && !this.isInheritedLibraryBackboneFeature(inherited, m, index2))
|
|
168821
169609
|
addPort(m, true);
|
|
169610
|
+
}
|
|
168822
169611
|
}
|
|
168823
|
-
return { ports, map: map3 };
|
|
169612
|
+
return { ports, map: map3, origins };
|
|
168824
169613
|
}
|
|
168825
169614
|
// REQ-100, issue #132 — the effective directions of a port type's directed
|
|
168826
169615
|
// features, following the specialization chain and flipping `in`↔`out` across
|
|
@@ -168986,6 +169775,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
168986
169775
|
add("ports", usages(isPortDecl).map((m) => item(m)));
|
|
168987
169776
|
add("parts", usages(isPartDecl).filter(notPortion).map((m) => item(m)));
|
|
168988
169777
|
}
|
|
169778
|
+
add("connections", members.filter((member) => isConnectionDecl(member) && member.isDef !== true && isOrdinaryMember(member)).map((member) => item(member, this.featureText(member) || "(anonymous connection)")));
|
|
168989
169779
|
add("interfaces", members.filter((m) => isInterfaceDecl(m) && m.isDef !== true && isOrdinaryMember(m)).map((m) => item(m, this.interfaceRowText(m))));
|
|
168990
169780
|
add("features", members.filter((m) => m.$type === "FeatureShorthand" || m.$type === "FeatureRedefinitionShorthand").filter(isOrdinaryMember).filter((m) => !isOccurrenceModified(m)).map((m) => item(m, canonicalFeatureText(m))));
|
|
168991
169781
|
const undirected = (guard) => usages(guard);
|
|
@@ -169101,25 +169891,6 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
169101
169891
|
return ends;
|
|
169102
169892
|
return [head2, ends].filter(Boolean).join(" ");
|
|
169103
169893
|
}
|
|
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
169894
|
refText(v) {
|
|
169124
169895
|
if (typeof v === "string")
|
|
169125
169896
|
return v;
|
|
@@ -169642,91 +170413,6 @@ function outlineGroupForType(astType) {
|
|
|
169642
170413
|
return CATEGORY_TO_OUTLINE_GROUP[categoryForType(astType)] ?? "structure";
|
|
169643
170414
|
}
|
|
169644
170415
|
|
|
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
170416
|
// ../language-server/out/src/services/document-symbol-provider.js
|
|
169731
170417
|
var SPECIALIZATION_KINDS2 = /* @__PURE__ */ new Set([":>", "specializes"]);
|
|
169732
170418
|
var REDEFINITION_KINDS = /* @__PURE__ */ new Set([":>>", "redefines"]);
|
|
@@ -176575,7 +177261,7 @@ ${baseIndent}}`;
|
|
|
176575
177261
|
return;
|
|
176576
177262
|
const expected = interfaceEndTypes(definition);
|
|
176577
177263
|
const connect = decl.connect;
|
|
176578
|
-
const written = [connect?.source, connect?.target];
|
|
177264
|
+
const written = connect?.ends?.length ? connect.ends : [connect?.source, connect?.target];
|
|
176579
177265
|
if (expected.length !== written.length)
|
|
176580
177266
|
return;
|
|
176581
177267
|
for (let position = 0; position < written.length; position += 1) {
|
|
@@ -182522,7 +183208,9 @@ var PORT_GLYPH_SIZE = 20;
|
|
|
182522
183208
|
var PORT_GLYPH_HALF = PORT_GLYPH_SIZE / 2;
|
|
182523
183209
|
var FEATURE_COMPARTMENT_CLEARANCE = PORT_GLYPH_HALF + 12;
|
|
182524
183210
|
var ACTION_PIN_GLYPH_SIZE = PORT_GLYPH_SIZE;
|
|
183211
|
+
var CONNECTION_END_GLYPH_SIZE = 12;
|
|
182525
183212
|
function endpointGlyphSize(endpoint) {
|
|
183213
|
+
if (endpoint.meta?.connectionEndPin === true) return CONNECTION_END_GLYPH_SIZE;
|
|
182526
183214
|
return endpoint.pin ? ACTION_PIN_GLYPH_SIZE : PORT_GLYPH_SIZE;
|
|
182527
183215
|
}
|
|
182528
183216
|
var NESTED_PORT_GAP = 8;
|
|
@@ -182643,9 +183331,9 @@ function portDockSides(side) {
|
|
|
182643
183331
|
}
|
|
182644
183332
|
var PORT_MOVE_STRIP_ALONG = 24;
|
|
182645
183333
|
var PORT_CONNECT_DOT_HIT = 10;
|
|
182646
|
-
function portInteractionStrip(rect, side) {
|
|
183334
|
+
function portInteractionStrip(rect, side, singleOutwardHandle = false) {
|
|
182647
183335
|
const vertical = side === "left" || side === "right";
|
|
182648
|
-
const across = Math.max(1, rect.across - PORT_CONNECT_DOT_HIT);
|
|
183336
|
+
const across = singleOutwardHandle ? rect.across : Math.max(1, rect.across - PORT_CONNECT_DOT_HIT);
|
|
182649
183337
|
const run = Math.max(PORT_MOVE_STRIP_ALONG, rect.along);
|
|
182650
183338
|
return {
|
|
182651
183339
|
cx: rect.cx,
|
|
@@ -182731,6 +183419,10 @@ function sideLength(side, w, h, topReserve = 0) {
|
|
|
182731
183419
|
}
|
|
182732
183420
|
var SENDACCEPT_NOTCH = 14;
|
|
182733
183421
|
var CIRCULAR_CONTROL_RADII = {
|
|
183422
|
+
// REQ-192 - the n-ary connection hub is the same kind of fixed circular
|
|
183423
|
+
// canvas control as an AFV start node. Its wrapper, handles, saved size,
|
|
183424
|
+
// and painted outline therefore share one exact radius.
|
|
183425
|
+
dot: CONNECTION_END_GLYPH_SIZE / 2,
|
|
182734
183426
|
initial: 6,
|
|
182735
183427
|
final: 8,
|
|
182736
183428
|
terminate: 8
|
|
@@ -182954,6 +183646,15 @@ function gvModeEdges(model, mode) {
|
|
|
182954
183646
|
function isGvUsageNode(n2) {
|
|
182955
183647
|
return n2.meta?.gvUsage === true;
|
|
182956
183648
|
}
|
|
183649
|
+
function isConnectionDefinitionHub(n2) {
|
|
183650
|
+
return n2.meta?.connectionDefinitionHub === true;
|
|
183651
|
+
}
|
|
183652
|
+
function isGraphicalConnectionDefinitionCard(n2) {
|
|
183653
|
+
return n2.meta?.connectionDefinitionGraphical === true && n2.meta?.connectionDefinitionHub !== true && n2.meta?.connectionDefinitionElaboration !== true;
|
|
183654
|
+
}
|
|
183655
|
+
function isGraphicalConnectionDefinitionEdge(edge) {
|
|
183656
|
+
return edge.meta?.connectionDefinitionGraphical === true;
|
|
183657
|
+
}
|
|
182957
183658
|
var GV_BOXED_USAGE_COMPARTMENTS = /* @__PURE__ */ new Set(["parts", "occurrences", "timeslices", "snapshots", "individuals"]);
|
|
182958
183659
|
function stripBoxedUsageCompartments(nodes) {
|
|
182959
183660
|
let changed = false;
|
|
@@ -182970,11 +183671,16 @@ function applyGvMode(model, mode) {
|
|
|
182970
183671
|
if (model.kind !== "gv") return model;
|
|
182971
183672
|
const edges = gvModeEdges(model, mode);
|
|
182972
183673
|
if (mode === "group") {
|
|
182973
|
-
const nodes2 = model.nodes.filter((n2) => !isGvUsageNode(n2));
|
|
183674
|
+
const nodes2 = model.nodes.filter((n2) => !isGvUsageNode(n2) && !isConnectionDefinitionHub(n2));
|
|
182974
183675
|
return { ...model, nodes: nodes2, edges };
|
|
182975
183676
|
}
|
|
182976
|
-
const
|
|
182977
|
-
|
|
183677
|
+
const cardIsVisible = (node) => !isGraphicalConnectionDefinitionCard(node);
|
|
183678
|
+
const graphicalNodes = model.nodes.every(cardIsVisible) ? model.nodes : model.nodes.filter(cardIsVisible);
|
|
183679
|
+
const nodes = stripBoxedUsageCompartments(graphicalNodes);
|
|
183680
|
+
const nodeIds = new Set(nodes.map((node) => node.id));
|
|
183681
|
+
const edgeIsVisible = (edge) => nodeIds.has(edge.from) && nodeIds.has(edge.to);
|
|
183682
|
+
const visibleEdges = edges.every(edgeIsVisible) ? edges : edges.filter(edgeIsVisible);
|
|
183683
|
+
return nodes === model.nodes && visibleEdges === model.edges ? model : { ...model, nodes, edges: visibleEdges };
|
|
182978
183684
|
}
|
|
182979
183685
|
var GV_CATEGORIES = [
|
|
182980
183686
|
{ key: "package", label: "Packages" },
|
|
@@ -182994,6 +183700,7 @@ var GV_CATEGORIES = [
|
|
|
182994
183700
|
];
|
|
182995
183701
|
function gvNodeCategory(node) {
|
|
182996
183702
|
if (node.shape === "package") return "package";
|
|
183703
|
+
if (isConnectionDefinitionHub(node)) return "interface";
|
|
182997
183704
|
if (node.shape === "annotation" || node.shape === "dot") return "annotation";
|
|
182998
183705
|
const k = node.keyword.toLowerCase().trim().replace(/^(individual|timeslice|snapshot|parallel|variation|variant|abstract|ref|derived)(\s+|$)/g, "").replace(/\s+def$/, "").trim();
|
|
182999
183706
|
if (k === "" || k === "def") return "item";
|
|
@@ -183035,13 +183742,13 @@ function withoutOrphanedAnnotations(original, nodes, edges) {
|
|
|
183035
183742
|
function applyGvFilters(model, hidden) {
|
|
183036
183743
|
if (model.kind !== "gv" || hidden.size === 0) return model;
|
|
183037
183744
|
const nodes = model.nodes.filter((n2) => n2.shape === "package" || !hidden.has(gvNodeCategory(n2)));
|
|
183038
|
-
if (nodes.length === model.nodes.length) return model;
|
|
183039
183745
|
const keptIds = /* @__PURE__ */ new Set();
|
|
183040
183746
|
for (const n2 of nodes) {
|
|
183041
183747
|
keptIds.add(n2.id);
|
|
183042
183748
|
for (const p of n2.ports ?? []) keptIds.add(p.id);
|
|
183043
183749
|
}
|
|
183044
|
-
const edges = model.edges.filter((e) => keptIds.has(e.from) && keptIds.has(e.to));
|
|
183750
|
+
const edges = model.edges.filter((e) => !(hidden.has("interface") && isGraphicalConnectionDefinitionEdge(e)) && keptIds.has(e.from) && keptIds.has(e.to));
|
|
183751
|
+
if (nodes.length === model.nodes.length && edges.length === model.edges.length) return model;
|
|
183045
183752
|
return { ...model, nodes: withoutOrphanedAnnotations(model, nodes, edges), edges };
|
|
183046
183753
|
}
|
|
183047
183754
|
var PAD = 10;
|
|
@@ -183127,6 +183834,13 @@ function compartmentWidth(node) {
|
|
|
183127
183834
|
return w;
|
|
183128
183835
|
}
|
|
183129
183836
|
function nodeForCanvas(node) {
|
|
183837
|
+
if (node.meta?.connectionUsage === true || node.meta?.interfaceUsage === true) {
|
|
183838
|
+
const compartments2 = node.compartments?.filter((compartment) => compartment.title === "doc");
|
|
183839
|
+
return {
|
|
183840
|
+
...node,
|
|
183841
|
+
compartments: compartments2?.length ? compartments2 : void 0
|
|
183842
|
+
};
|
|
183843
|
+
}
|
|
183130
183844
|
if (!/\bconstraint(?:\s+def)?$/u.test(node.keyword.trim().toLowerCase())) return node;
|
|
183131
183845
|
const compartments = node.compartments?.filter((compartment) => compartment.title !== "expression");
|
|
183132
183846
|
return {
|
|
@@ -183164,13 +183878,12 @@ function nodeSize(node, direction) {
|
|
|
183164
183878
|
// connector attaching at the node edge meets the visible circle.
|
|
183165
183879
|
case "initial":
|
|
183166
183880
|
case "final":
|
|
183881
|
+
case "dot":
|
|
183167
183882
|
return circularControlSize(node.shape);
|
|
183168
183883
|
// OMG SysML v2.1 Part 1, Table 15: the terminate control node is an
|
|
183169
183884
|
// unlabeled circled X, regardless of its optional semantic target.
|
|
183170
183885
|
case "terminate":
|
|
183171
183886
|
return circularControlSize(node.shape);
|
|
183172
|
-
case "dot":
|
|
183173
|
-
return { w: 14, h: 14 };
|
|
183174
183887
|
case "decision":
|
|
183175
183888
|
case "merge":
|
|
183176
183889
|
return { w: Math.max(64, Math.ceil((twKind(node.name) + 8) / 0.7)), h: 48 };
|
|
@@ -183210,9 +183923,10 @@ function nodeSize(node, direction) {
|
|
|
183210
183923
|
);
|
|
183211
183924
|
const featureH = nodeFeatureCompartmentReserve(node);
|
|
183212
183925
|
const compactContainer = node.meta?.internalsHidden === true;
|
|
183213
|
-
const
|
|
183926
|
+
const connectionUsage = node.meta?.connectionUsage === true || node.meta?.interfaceUsage === true;
|
|
183927
|
+
const portRunHeight = connectionUsage ? portRows ? portRows * 18 + 6 : 0 : portRows ? compactContainer ? portRows * 24 + 8 : 40 + portRows * 24 + 8 : 0;
|
|
183214
183928
|
const bodyH = Math.max(
|
|
183215
|
-
BOX_H,
|
|
183929
|
+
connectionUsage ? 42 : BOX_H,
|
|
183216
183930
|
featureH === 0 ? NODE_COMPARTMENT_TOP + compartmentHeight(node) : 0,
|
|
183217
183931
|
portRunHeight,
|
|
183218
183932
|
portedSideLength(ph, "left"),
|
|
@@ -183437,6 +184151,18 @@ function assignPortHandles(ports, overrides, ownerShape) {
|
|
|
183437
184151
|
for (const parent of topHandles) placeChildren(parent);
|
|
183438
184152
|
return [...topHandles, ...nestedHandles];
|
|
183439
184153
|
}
|
|
184154
|
+
var CONNECTION_BLOCK_GEOMETRY_VERSION = 2;
|
|
184155
|
+
function connectionUsageHeightOverride(node, height, connectionBlockVersion) {
|
|
184156
|
+
if (height === void 0 || node?.meta?.connectionUsage !== true) return height;
|
|
184157
|
+
if ((connectionBlockVersion ?? 0) >= CONNECTION_BLOCK_GEOMETRY_VERSION) return height;
|
|
184158
|
+
const handles = assignPortHandles(node.ports, void 0, node.shape);
|
|
184159
|
+
const rows = Math.max(
|
|
184160
|
+
handles.filter((handle) => handle.side === "left").length,
|
|
184161
|
+
handles.filter((handle) => handle.side === "right").length
|
|
184162
|
+
);
|
|
184163
|
+
const oldAutomaticHeight = Math.max(BOX_H, rows ? rows * 24 + 48 : 0);
|
|
184164
|
+
return height === oldAutomaticHeight ? void 0 : height;
|
|
184165
|
+
}
|
|
183440
184166
|
function sizeWithOverride(base, o, minimum = { w: 48, h: 24 }) {
|
|
183441
184167
|
return {
|
|
183442
184168
|
w: o?.w !== void 0 ? Math.max(minimum.w, o.w) : base.w,
|
|
@@ -183553,11 +184279,38 @@ function applyCaseDefs(model, show) {
|
|
|
183553
184279
|
};
|
|
183554
184280
|
}
|
|
183555
184281
|
var BEHAVIOR_FILTER_DEFAULTS = {
|
|
183556
|
-
afv: {
|
|
183557
|
-
|
|
184282
|
+
afv: {
|
|
184283
|
+
parts: true,
|
|
184284
|
+
performers: true,
|
|
184285
|
+
ports: true,
|
|
184286
|
+
defs: true,
|
|
184287
|
+
definedBy: true,
|
|
184288
|
+
actions: true,
|
|
184289
|
+
connectionBoxes: true,
|
|
184290
|
+
interfaceBoxes: true
|
|
184291
|
+
},
|
|
184292
|
+
stv: {
|
|
184293
|
+
parts: false,
|
|
184294
|
+
performers: true,
|
|
184295
|
+
ports: true,
|
|
184296
|
+
defs: true,
|
|
184297
|
+
definedBy: true,
|
|
184298
|
+
actions: true,
|
|
184299
|
+
connectionBoxes: true,
|
|
184300
|
+
interfaceBoxes: true
|
|
184301
|
+
},
|
|
183558
184302
|
// The Interconnection View is a STRUCTURE view; explicitly performed actions
|
|
183559
184303
|
// are an optional behavior overlay and therefore the first layer to drop.
|
|
183560
|
-
iv: {
|
|
184304
|
+
iv: {
|
|
184305
|
+
parts: true,
|
|
184306
|
+
performers: true,
|
|
184307
|
+
ports: true,
|
|
184308
|
+
defs: true,
|
|
184309
|
+
definedBy: true,
|
|
184310
|
+
actions: true,
|
|
184311
|
+
connectionBoxes: true,
|
|
184312
|
+
interfaceBoxes: true
|
|
184313
|
+
}
|
|
183561
184314
|
};
|
|
183562
184315
|
function behaviorFilterDefaults(kind) {
|
|
183563
184316
|
return BEHAVIOR_FILTER_DEFAULTS[kind === "stv" ? "stv" : kind === "iv" ? "iv" : "afv"];
|
|
@@ -183570,9 +184323,161 @@ function restoreBehaviorFilters(kind, saved) {
|
|
|
183570
184323
|
return restored;
|
|
183571
184324
|
}
|
|
183572
184325
|
var FILTERED_KINDS = /* @__PURE__ */ new Set(["afv", "stv", "iv"]);
|
|
184326
|
+
function withVisibleDefinitionLayer(model) {
|
|
184327
|
+
const layer = model.layers?.definitions;
|
|
184328
|
+
if (!layer) return model;
|
|
184329
|
+
return {
|
|
184330
|
+
...model,
|
|
184331
|
+
nodes: [...model.nodes, ...layer.nodes],
|
|
184332
|
+
edges: [...model.edges, ...layer.edges],
|
|
184333
|
+
frames: [...model.frames ?? [], ...layer.frames ?? []],
|
|
184334
|
+
layers: void 0
|
|
184335
|
+
};
|
|
184336
|
+
}
|
|
184337
|
+
function explicitRelationshipBindings(usage, model) {
|
|
184338
|
+
return (usage.ports ?? []).flatMap((port, fallbackOrdinal) => {
|
|
184339
|
+
const edge = model.edges.find((candidate) => candidate.from === port.id || candidate.to === port.id);
|
|
184340
|
+
if (!edge) return [];
|
|
184341
|
+
const pinAtFrom = edge.from === port.id;
|
|
184342
|
+
const ordinal = typeof port.meta?.connectionEndOrdinal === "number" ? port.meta.connectionEndOrdinal : fallbackOrdinal;
|
|
184343
|
+
const role = typeof port.meta?.connectionEndRole === "string" ? port.meta.connectionEndRole : pinAtFrom ? edge.endRoleFrom : edge.endRoleTo;
|
|
184344
|
+
return [{
|
|
184345
|
+
edge,
|
|
184346
|
+
externalId: pinAtFrom ? edge.to : edge.from,
|
|
184347
|
+
ordinal,
|
|
184348
|
+
role,
|
|
184349
|
+
multiplicity: pinAtFrom ? edge.endLabelFrom : edge.endLabelTo,
|
|
184350
|
+
adornment: pinAtFrom ? edge.endAdornmentFrom : edge.endAdornmentTo
|
|
184351
|
+
}];
|
|
184352
|
+
}).sort((left, right) => left.ordinal - right.ordinal);
|
|
184353
|
+
}
|
|
184354
|
+
function hideExplicitRelationshipBoxes(model, relationship) {
|
|
184355
|
+
if (model.kind !== "iv") return model;
|
|
184356
|
+
const usages = model.nodes.filter((node) => relationship === "connection" ? node.meta?.connectionUsage === true : node.meta?.interfaceUsage === true);
|
|
184357
|
+
if (usages.length === 0) return model;
|
|
184358
|
+
const usageIds = new Set(usages.map((usage) => usage.id));
|
|
184359
|
+
const annotatedUsageIds = /* @__PURE__ */ new Set();
|
|
184360
|
+
for (const edge of model.edges) {
|
|
184361
|
+
if (edge.kind !== "annotation") continue;
|
|
184362
|
+
if (usageIds.has(edge.from)) annotatedUsageIds.add(edge.from);
|
|
184363
|
+
if (usageIds.has(edge.to)) annotatedUsageIds.add(edge.to);
|
|
184364
|
+
}
|
|
184365
|
+
const projections = usages.map((usage) => ({
|
|
184366
|
+
usage,
|
|
184367
|
+
bindings: explicitRelationshipBindings(usage, model),
|
|
184368
|
+
endCount: usage.ports?.length ?? 0
|
|
184369
|
+
}));
|
|
184370
|
+
const retainedIds = new Set(projections.filter(({ usage, bindings, endCount }) => (nodeForCanvas(usage).compartments?.length ?? 0) > 0 || annotatedUsageIds.has(usage.id) || endCount < 2 || bindings.length !== endCount).map(({ usage }) => usage.id));
|
|
184371
|
+
const hiddenIds = /* @__PURE__ */ new Set();
|
|
184372
|
+
for (const { usage } of projections) {
|
|
184373
|
+
if (retainedIds.has(usage.id)) continue;
|
|
184374
|
+
hiddenIds.add(usage.id);
|
|
184375
|
+
for (const port of usage.ports ?? []) hiddenIds.add(port.id);
|
|
184376
|
+
}
|
|
184377
|
+
const edges = model.edges.filter((edge) => !hiddenIds.has(edge.from) && !hiddenIds.has(edge.to));
|
|
184378
|
+
const compactNodes = [];
|
|
184379
|
+
const compactEdges = [];
|
|
184380
|
+
for (const { usage, bindings, endCount } of projections) {
|
|
184381
|
+
if (retainedIds.has(usage.id)) continue;
|
|
184382
|
+
const sharedEdgeMeta = { ...bindings[0]?.edge.meta ?? {} };
|
|
184383
|
+
delete sharedEdgeMeta.connectionUsageEnd;
|
|
184384
|
+
delete sharedEdgeMeta.interfaceUsageEnd;
|
|
184385
|
+
delete sharedEdgeMeta.connectionEndOrdinal;
|
|
184386
|
+
delete sharedEdgeMeta.connectionEndRole;
|
|
184387
|
+
const semanticName = typeof usage.meta?.explicitRelationshipName === "string" ? usage.meta.explicitRelationshipName : bindings[0]?.edge.name;
|
|
184388
|
+
const semanticType = bindings[0]?.edge.type ?? usage.type;
|
|
184389
|
+
const label = relationship === "interface" ? ["\xABinterface\xBB", semanticName ?? "", semanticType ? `: ${semanticType}` : ""].filter(Boolean).join(" ").trim() : semanticName;
|
|
184390
|
+
const baseMeta = {
|
|
184391
|
+
...usage.meta,
|
|
184392
|
+
...sharedEdgeMeta,
|
|
184393
|
+
connectionUsageId: usage.id,
|
|
184394
|
+
connectionUsageSource: usage.source,
|
|
184395
|
+
...relationship === "interface" ? { interfaceUsageId: usage.id } : {}
|
|
184396
|
+
};
|
|
184397
|
+
if (endCount <= 2) {
|
|
184398
|
+
if (bindings.length !== 2) continue;
|
|
184399
|
+
const [from, to] = bindings;
|
|
184400
|
+
compactEdges.push({
|
|
184401
|
+
id: from.edge.id,
|
|
184402
|
+
from: from.externalId,
|
|
184403
|
+
to: to.externalId,
|
|
184404
|
+
kind: relationship === "connection" ? "connect" : "interface",
|
|
184405
|
+
name: semanticName,
|
|
184406
|
+
type: semanticType,
|
|
184407
|
+
isDef: false,
|
|
184408
|
+
label,
|
|
184409
|
+
endRoleFrom: from.role,
|
|
184410
|
+
endLabelFrom: from.multiplicity,
|
|
184411
|
+
endAdornmentFrom: from.adornment,
|
|
184412
|
+
endRoleTo: to.role,
|
|
184413
|
+
endLabelTo: to.multiplicity,
|
|
184414
|
+
endAdornmentTo: to.adornment,
|
|
184415
|
+
source: usage.source ?? from.edge.source,
|
|
184416
|
+
meta: {
|
|
184417
|
+
...baseMeta,
|
|
184418
|
+
...relationship === "connection" ? { compactConnectionUsage: true } : { compactInterfaceUsage: true },
|
|
184419
|
+
connectionEndFromOrdinal: from.ordinal,
|
|
184420
|
+
connectionEndToOrdinal: to.ordinal,
|
|
184421
|
+
...from.role ? { connectionEndFromRole: from.role } : {},
|
|
184422
|
+
...to.role ? { connectionEndToRole: to.role } : {}
|
|
184423
|
+
}
|
|
184424
|
+
});
|
|
184425
|
+
continue;
|
|
184426
|
+
}
|
|
184427
|
+
const hubId = `${usage.id}::__compact_hub`;
|
|
184428
|
+
compactNodes.push({
|
|
184429
|
+
id: hubId,
|
|
184430
|
+
name: "",
|
|
184431
|
+
keyword: relationship,
|
|
184432
|
+
isDef: false,
|
|
184433
|
+
shape: "dot",
|
|
184434
|
+
...usage.frame ? { frame: usage.frame } : {},
|
|
184435
|
+
source: usage.source,
|
|
184436
|
+
meta: {
|
|
184437
|
+
...baseMeta,
|
|
184438
|
+
naryConnectionHub: true,
|
|
184439
|
+
...relationship === "connection" ? { compactConnectionUsageHub: true } : { compactInterfaceUsageHub: true }
|
|
184440
|
+
}
|
|
184441
|
+
});
|
|
184442
|
+
for (const binding of bindings) {
|
|
184443
|
+
compactEdges.push({
|
|
184444
|
+
id: binding.edge.id,
|
|
184445
|
+
from: hubId,
|
|
184446
|
+
to: binding.externalId,
|
|
184447
|
+
kind: relationship === "connection" ? "connect" : "interface",
|
|
184448
|
+
name: semanticName,
|
|
184449
|
+
type: semanticType,
|
|
184450
|
+
isDef: false,
|
|
184451
|
+
label,
|
|
184452
|
+
endRoleTo: binding.role,
|
|
184453
|
+
endLabelTo: binding.multiplicity,
|
|
184454
|
+
endAdornmentTo: binding.adornment,
|
|
184455
|
+
source: usage.source ?? binding.edge.source,
|
|
184456
|
+
meta: {
|
|
184457
|
+
...baseMeta,
|
|
184458
|
+
...relationship === "connection" ? { compactConnectionUsageEnd: true } : { compactInterfaceUsageEnd: true },
|
|
184459
|
+
connectionEndOrdinal: binding.ordinal,
|
|
184460
|
+
...binding.role ? { connectionEndRole: binding.role } : {}
|
|
184461
|
+
}
|
|
184462
|
+
});
|
|
184463
|
+
}
|
|
184464
|
+
}
|
|
184465
|
+
return {
|
|
184466
|
+
...model,
|
|
184467
|
+
nodes: [...model.nodes.filter((node) => !hiddenIds.has(node.id)), ...compactNodes],
|
|
184468
|
+
edges: [...edges, ...compactEdges]
|
|
184469
|
+
};
|
|
184470
|
+
}
|
|
184471
|
+
function hideExplicitConnectionBoxes(model) {
|
|
184472
|
+
return hideExplicitRelationshipBoxes(model, "connection");
|
|
184473
|
+
}
|
|
184474
|
+
function hideExplicitInterfaceBoxes(model) {
|
|
184475
|
+
return hideExplicitRelationshipBoxes(model, "interface");
|
|
184476
|
+
}
|
|
183573
184477
|
function applyBehaviorFilters(model, filters) {
|
|
183574
184478
|
if (!FILTERED_KINDS.has(model.kind)) return model;
|
|
183575
|
-
const
|
|
184479
|
+
const visibleModel = filters.defs ? withVisibleDefinitionLayer(model) : model;
|
|
184480
|
+
const frames = visibleModel.frames ?? [];
|
|
183576
184481
|
const dropped = /* @__PURE__ */ new Set();
|
|
183577
184482
|
const reparented = /* @__PURE__ */ new Set();
|
|
183578
184483
|
for (const frame2 of frames) {
|
|
@@ -183581,12 +184486,15 @@ function applyBehaviorFilters(model, filters) {
|
|
|
183581
184486
|
if (!filters.parts && isOwnerPartFrame || !filters.performers && isPerformerLane) {
|
|
183582
184487
|
reparented.add(frame2.id);
|
|
183583
184488
|
}
|
|
183584
|
-
if (!filters.defs && frame2.meta?.behaviorDef === true) dropped.add(frame2.id);
|
|
184489
|
+
if (!filters.defs && (frame2.meta?.behaviorDef === true || frame2.meta?.ivPartDef === true)) dropped.add(frame2.id);
|
|
183585
184490
|
}
|
|
183586
|
-
const droppedNodes = new Set(
|
|
184491
|
+
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
184492
|
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)
|
|
184493
|
+
const strippedDefinedBy = !filters.definedBy && visibleModel.edges.some((edge) => edge.kind === "definedBy");
|
|
184494
|
+
if (dropped.size === 0 && reparented.size === 0 && droppedNodes.size === 0 && !strippedPorts && !strippedDefinedBy) {
|
|
184495
|
+
const connectionsProjected2 = filters.connectionBoxes ? visibleModel : hideExplicitConnectionBoxes(visibleModel);
|
|
184496
|
+
return filters.interfaceBoxes ? connectionsProjected2 : hideExplicitInterfaceBoxes(connectionsProjected2);
|
|
184497
|
+
}
|
|
183590
184498
|
const byId = new Map(frames.map((f) => [f.id, f]));
|
|
183591
184499
|
const insideDropped = (id2) => {
|
|
183592
184500
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -183617,7 +184525,7 @@ function applyBehaviorFilters(model, filters) {
|
|
|
183617
184525
|
const ports = keepPorts(f.ports);
|
|
183618
184526
|
return parent === f.parent && ports === f.ports ? f : { ...f, parent, ports };
|
|
183619
184527
|
});
|
|
183620
|
-
const nodes =
|
|
184528
|
+
const nodes = visibleModel.nodes.filter((n2) => !droppedNodes.has(n2.id) && !insideDropped(n2.frame) && !dropped.has(n2.frame ?? "")).map((n2) => {
|
|
183621
184529
|
const frame2 = visibleParent(n2.frame);
|
|
183622
184530
|
return frame2 === n2.frame ? n2 : { ...n2, frame: frame2 };
|
|
183623
184531
|
});
|
|
@@ -183627,8 +184535,15 @@ function applyBehaviorFilters(model, filters) {
|
|
|
183627
184535
|
...nextFrames.map((f) => f.id),
|
|
183628
184536
|
...nextFrames.flatMap((f) => (f.ports ?? []).map((p) => p.id))
|
|
183629
184537
|
]);
|
|
183630
|
-
const edges =
|
|
183631
|
-
|
|
184538
|
+
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));
|
|
184539
|
+
const filtered = {
|
|
184540
|
+
...visibleModel,
|
|
184541
|
+
frames: nextFrames,
|
|
184542
|
+
nodes: withoutOrphanedAnnotations(visibleModel, nodes, edges),
|
|
184543
|
+
edges
|
|
184544
|
+
};
|
|
184545
|
+
const connectionsProjected = filters.connectionBoxes ? filtered : hideExplicitConnectionBoxes(filtered);
|
|
184546
|
+
return filters.interfaceBoxes ? connectionsProjected : hideExplicitInterfaceBoxes(connectionsProjected);
|
|
183632
184547
|
}
|
|
183633
184548
|
function isProxyPort(port) {
|
|
183634
184549
|
return port.meta?.proxy === true;
|
|
@@ -183736,7 +184651,7 @@ function collapseIvModel(model, hiddenInternals) {
|
|
|
183736
184651
|
const hidden = /* @__PURE__ */ new Set([...hiddenFrameIds, ...hiddenNodeIds, ...ownerOfHiddenPort.keys()]);
|
|
183737
184652
|
const containerRootOf = (id2) => proxyHost.get(id2) ?? bodyDock.get(id2);
|
|
183738
184653
|
const seenEdge = /* @__PURE__ */ new Set();
|
|
183739
|
-
const edges = model.edges.filter((e) => {
|
|
184654
|
+
const edges = model.edges.filter((edge) => rootFor(typeof edge.meta?.ivRelationshipOwnerId === "string" ? edge.meta.ivRelationshipOwnerId : void 0) === void 0).filter((e) => {
|
|
183740
184655
|
const fromRoot = containerRootOf(e.from);
|
|
183741
184656
|
const toRoot = containerRootOf(e.to);
|
|
183742
184657
|
if (fromRoot !== void 0 && fromRoot === toRoot) return false;
|
|
@@ -184114,15 +185029,24 @@ function modelToFlow(model, opts) {
|
|
|
184114
185029
|
const visibleFeatureH = featureCompartmentBandHeight(canvasNode);
|
|
184115
185030
|
const featureH = nodeFeatureCompartmentReserve(canvasNode);
|
|
184116
185031
|
const base = isGeo ? { w: 24, h: 24 } : nodeSize(canvasNode, opts.direction);
|
|
185032
|
+
const requiresNaturalCompartmentHeight = visibleFeatureH > 0 || (canvasNode.meta?.connectionUsage === true || canvasNode.meta?.interfaceUsage === true) && !!canvasNode.compartments?.length;
|
|
184117
185033
|
const sizeOverride = ov[n2.layoutKey ?? n2.id];
|
|
184118
185034
|
const compactCollapsed = canvasNode.meta?.internalsHidden === true;
|
|
184119
|
-
const
|
|
185035
|
+
const compactOverride = compactCollapsed && sizeOverride ? { ...sizeOverride, w: sizeOverride.collapsedW, h: sizeOverride.collapsedH } : sizeOverride;
|
|
185036
|
+
const presentationOverride = compactOverride ? {
|
|
185037
|
+
...compactOverride,
|
|
185038
|
+
h: connectionUsageHeightOverride(
|
|
185039
|
+
canvasNode,
|
|
185040
|
+
compactOverride.h,
|
|
185041
|
+
compactOverride.connectionBlockVersion
|
|
185042
|
+
)
|
|
185043
|
+
} : compactOverride;
|
|
184120
185044
|
const projectedSize = isCircularControlShape(canvasNode.shape) ? base : isForkJoinShape(canvasNode.shape) ? forkJoinSizeWithOverride(presentationOverride, opts.direction) : sizeWithOverride(
|
|
184121
185045
|
base,
|
|
184122
185046
|
presentationOverride,
|
|
184123
185047
|
{
|
|
184124
185048
|
w: canvasNode.meta?.containerControls === true || canvasNode.meta?.internalsHidden === true ? COLLAPSED_CONTAINER_MIN_WIDTH : 48,
|
|
184125
|
-
h:
|
|
185049
|
+
h: requiresNaturalCompartmentHeight ? base.h : 24
|
|
184126
185050
|
}
|
|
184127
185051
|
);
|
|
184128
185052
|
const compactPortHandles = compactCollapsed ? assignPortHandles(canvasNode.ports, opts.portOverrides, canvasNode.shape) : [];
|
|
@@ -184152,7 +185076,7 @@ function modelToFlow(model, opts) {
|
|
|
184152
185076
|
w: size.w,
|
|
184153
185077
|
h: size.h,
|
|
184154
185078
|
featureCompartmentHeight: featureH,
|
|
184155
|
-
featureCompartmentMinHeight:
|
|
185079
|
+
featureCompartmentMinHeight: requiresNaturalCompartmentHeight ? base.h : void 0,
|
|
184156
185080
|
showPortLabels: opts.showPortLabels,
|
|
184157
185081
|
showMult: opts.showMult,
|
|
184158
185082
|
connectPointSpacing
|
|
@@ -184273,18 +185197,27 @@ function modelToFlow(model, opts) {
|
|
|
184273
185197
|
const routeKey = edgeRouteKey(e, dup, persistedEndpoints);
|
|
184274
185198
|
const savedAnchor = opts.edgeAnchors?.[routeKey];
|
|
184275
185199
|
const settledGeometry = opts.edgeGeometry?.[routeKey];
|
|
184276
|
-
const
|
|
184277
|
-
const
|
|
184278
|
-
const
|
|
184279
|
-
const
|
|
185200
|
+
const explicitSourceHandle = fromPort ? void 0 : canonicalSideHandle(savedAnchor?.sourceHandle);
|
|
185201
|
+
const explicitTargetHandle = toPort ? void 0 : canonicalSideHandle(savedAnchor?.targetHandle);
|
|
185202
|
+
const savedSourceHandle = explicitSourceHandle ?? (fromPort ? void 0 : canonicalSideHandle(settledGeometry?.sourceHandle));
|
|
185203
|
+
const savedTargetHandle = explicitTargetHandle ?? (toPort ? void 0 : canonicalSideHandle(settledGeometry?.targetHandle));
|
|
185204
|
+
const portSideForHandle = (ownerId, portId, persistedHandle) => {
|
|
185205
|
+
const portHandle = nodeById.get(ownerId)?.data.ports?.find((handle) => handle.port.id === portId);
|
|
185206
|
+
return portHandle?.port.meta?.connectionEndPin === true ? portHandle.side : parsePortAnchorHandleId(persistedHandle)?.side;
|
|
185207
|
+
};
|
|
185208
|
+
const savedSourcePortSide = fromPort ? portSideForHandle(source, e.from, settledGeometry?.sourceHandle) : void 0;
|
|
185209
|
+
const savedTargetPortSide = toPort ? portSideForHandle(target, e.to, settledGeometry?.targetHandle) : void 0;
|
|
185210
|
+
const sourceHandle = fromPort ? savedSourcePortSide ? portAnchorHandleId(e.from, savedSourcePortSide) : e.from : savedSourceHandle;
|
|
185211
|
+
const targetHandle = toPort ? savedTargetPortSide ? portAnchorHandleId(e.to, savedTargetPortSide) : e.to : savedTargetHandle;
|
|
185212
|
+
const settledHandlesMatch = !settledGeometry || (settledGeometry.sourceHandle === void 0 || settledGeometry.sourceHandle === sourceHandle) && (settledGeometry.targetHandle === void 0 || settledGeometry.targetHandle === targetHandle);
|
|
184280
185213
|
retainExplicitHandle(source, savedSourceHandle);
|
|
184281
185214
|
retainExplicitHandle(target, savedTargetHandle);
|
|
184282
185215
|
edges.push({
|
|
184283
185216
|
id: e.id,
|
|
184284
185217
|
source,
|
|
184285
185218
|
target,
|
|
184286
|
-
...
|
|
184287
|
-
...
|
|
185219
|
+
...sourceHandle ? { sourceHandle } : {},
|
|
185220
|
+
...targetHandle ? { targetHandle } : {},
|
|
184288
185221
|
type: "sysml",
|
|
184289
185222
|
data: {
|
|
184290
185223
|
kind: model.kind,
|
|
@@ -184293,7 +185226,9 @@ function modelToFlow(model, opts) {
|
|
|
184293
185226
|
showMult: opts.showMult,
|
|
184294
185227
|
routeKey,
|
|
184295
185228
|
route: opts.edgeRoutes?.[routeKey],
|
|
184296
|
-
|
|
185229
|
+
...explicitSourceHandle ? { explicitSourceAnchor: true } : {},
|
|
185230
|
+
...explicitTargetHandle ? { explicitTargetAnchor: true } : {},
|
|
185231
|
+
settledGeometry: settledHandlesMatch ? settledGeometry : void 0
|
|
184297
185232
|
},
|
|
184298
185233
|
selectable: true,
|
|
184299
185234
|
reconnectable: true,
|
|
@@ -184385,7 +185320,7 @@ function clampDirection(kind, d) {
|
|
|
184385
185320
|
|
|
184386
185321
|
// ../extension/src/webview/diagram/flow/geo-layout.ts
|
|
184387
185322
|
var GEO_MARGIN_LEFT = 48;
|
|
184388
|
-
var GEO_TOP_PAD =
|
|
185323
|
+
var GEO_TOP_PAD = 40;
|
|
184389
185324
|
var GEO_TARGET_W = 860;
|
|
184390
185325
|
var GEO_TARGET_H = 520;
|
|
184391
185326
|
var GEO_DEF_W = 400;
|
|
@@ -184400,33 +185335,110 @@ function geoProject(f, x, y, z2) {
|
|
|
184400
185335
|
const isoY = (x + y) * f.sinA - z2;
|
|
184401
185336
|
return [f.ox + (isoX - f.isoMinX) * f.scale, f.oy + (isoY - f.isoMinY) * f.scale];
|
|
184402
185337
|
}
|
|
184403
|
-
function
|
|
185338
|
+
function geoWorldPoint(placement, local) {
|
|
185339
|
+
const [lx, ly, lz] = local;
|
|
185340
|
+
const orientation = placement.orientation;
|
|
185341
|
+
if (orientation) {
|
|
185342
|
+
return [
|
|
185343
|
+
placement.x + orientation[0] * lx + orientation[1] * ly + orientation[2] * lz,
|
|
185344
|
+
placement.y + orientation[3] * lx + orientation[4] * ly + orientation[5] * lz,
|
|
185345
|
+
(placement.z ?? 0) + orientation[6] * lx + orientation[7] * ly + orientation[8] * lz
|
|
185346
|
+
];
|
|
185347
|
+
}
|
|
185348
|
+
if (placement.rot) {
|
|
185349
|
+
const angle = placement.rot * Math.PI / 180;
|
|
185350
|
+
const cos = Math.cos(angle);
|
|
185351
|
+
const sin = Math.sin(angle);
|
|
185352
|
+
return [
|
|
185353
|
+
placement.x + cos * lx - sin * ly,
|
|
185354
|
+
placement.y + sin * lx + cos * ly,
|
|
185355
|
+
(placement.z ?? 0) + lz
|
|
185356
|
+
];
|
|
185357
|
+
}
|
|
185358
|
+
return [placement.x + lx, placement.y + ly, (placement.z ?? 0) + lz];
|
|
185359
|
+
}
|
|
185360
|
+
function geoHalfExtentsOf(node, def) {
|
|
184404
185361
|
const g = node.geo;
|
|
184405
|
-
const z2 = g.z ?? 0;
|
|
184406
185362
|
switch (g.shape) {
|
|
184407
185363
|
case "sphere": {
|
|
184408
185364
|
const r = g.radius ?? def / 2;
|
|
184409
|
-
return { hx: r, hy: r,
|
|
185365
|
+
return { hx: r, hy: r, hz: r };
|
|
184410
185366
|
}
|
|
184411
185367
|
case "cylinder":
|
|
184412
185368
|
case "cone": {
|
|
184413
185369
|
const r = g.radius ?? def / 2;
|
|
184414
|
-
|
|
184415
|
-
return { hx: r, hy: r, zlo: z2 - h / 2, zhi: z2 + h / 2 };
|
|
185370
|
+
return { hx: r, hy: r, hz: (g.sizeZ ?? def) / 2 };
|
|
184416
185371
|
}
|
|
184417
185372
|
case "pyramid":
|
|
184418
185373
|
case "wedge":
|
|
184419
|
-
case "box":
|
|
184420
|
-
|
|
184421
|
-
|
|
184422
|
-
|
|
184423
|
-
|
|
184424
|
-
|
|
184425
|
-
default:
|
|
184426
|
-
|
|
184427
|
-
|
|
184428
|
-
|
|
185374
|
+
case "box":
|
|
185375
|
+
return {
|
|
185376
|
+
hx: (g.sizeX ?? def) / 2,
|
|
185377
|
+
hy: (g.sizeY ?? def) / 2,
|
|
185378
|
+
hz: (g.sizeZ ?? def) / 2
|
|
185379
|
+
};
|
|
185380
|
+
default:
|
|
185381
|
+
return { hx: (g.sizeX ?? GEO_DEF_W) / 2, hy: (g.sizeY ?? GEO_DEF_H) / 2, hz: 0 };
|
|
185382
|
+
}
|
|
185383
|
+
}
|
|
185384
|
+
function geoShapePoints(node, def) {
|
|
185385
|
+
const g = node.geo;
|
|
185386
|
+
const { hx, hy, hz } = geoHalfExtentsOf(node, def);
|
|
185387
|
+
const transform2 = (points) => points.map((point) => geoWorldPoint(g, point));
|
|
185388
|
+
const ring = (z2) => Array.from({ length: 32 }, (_2, index2) => {
|
|
185389
|
+
const angle = index2 * Math.PI / 16;
|
|
185390
|
+
return [hx * Math.cos(angle), hy * Math.sin(angle), z2];
|
|
185391
|
+
});
|
|
185392
|
+
switch (g.shape) {
|
|
185393
|
+
case "sphere": {
|
|
185394
|
+
const radius = g.radius ?? def / 2;
|
|
185395
|
+
const cosA = Math.cos(Math.PI / 6);
|
|
185396
|
+
const sinA = Math.sin(Math.PI / 6);
|
|
185397
|
+
const norm = Math.hypot(cosA, cosA);
|
|
185398
|
+
const silhouette = Array.from({ length: 32 }, (_2, index2) => {
|
|
185399
|
+
const angle = index2 * Math.PI / 16;
|
|
185400
|
+
const alongX = [cosA / norm, -cosA / norm, 0];
|
|
185401
|
+
const alongY = [sinA / norm, sinA / norm, -1 / norm];
|
|
185402
|
+
const x = radius * (alongX[0] * Math.cos(angle) + alongY[0] * Math.sin(angle));
|
|
185403
|
+
const y = radius * (alongX[1] * Math.cos(angle) + alongY[1] * Math.sin(angle));
|
|
185404
|
+
const z2 = radius * (alongX[2] * Math.cos(angle) + alongY[2] * Math.sin(angle));
|
|
185405
|
+
return [g.x + x, g.y + y, (g.z ?? 0) + z2];
|
|
185406
|
+
});
|
|
185407
|
+
return [
|
|
185408
|
+
...silhouette,
|
|
185409
|
+
[g.x - radius, g.y, g.z ?? 0],
|
|
185410
|
+
[g.x + radius, g.y, g.z ?? 0],
|
|
185411
|
+
[g.x, g.y - radius, g.z ?? 0],
|
|
185412
|
+
[g.x, g.y + radius, g.z ?? 0],
|
|
185413
|
+
[g.x, g.y, (g.z ?? 0) - radius],
|
|
185414
|
+
[g.x, g.y, (g.z ?? 0) + radius]
|
|
185415
|
+
];
|
|
184429
185416
|
}
|
|
185417
|
+
case "cylinder":
|
|
185418
|
+
return transform2([...ring(-hz), ...ring(hz)]);
|
|
185419
|
+
case "cone":
|
|
185420
|
+
return transform2([...ring(-hz), [0, 0, hz]]);
|
|
185421
|
+
case "pyramid":
|
|
185422
|
+
return transform2([
|
|
185423
|
+
[-hx, -hy, -hz],
|
|
185424
|
+
[hx, -hy, -hz],
|
|
185425
|
+
[hx, hy, -hz],
|
|
185426
|
+
[-hx, hy, -hz],
|
|
185427
|
+
[0, 0, hz]
|
|
185428
|
+
]);
|
|
185429
|
+
case "wedge":
|
|
185430
|
+
return transform2([
|
|
185431
|
+
[-hx, -hy, -hz],
|
|
185432
|
+
[hx, -hy, -hz],
|
|
185433
|
+
[hx, hy, -hz],
|
|
185434
|
+
[-hx, hy, -hz],
|
|
185435
|
+
[0, -hy, hz],
|
|
185436
|
+
[0, hy, hz]
|
|
185437
|
+
]);
|
|
185438
|
+
case "box":
|
|
185439
|
+
return transform2([-1, 1].flatMap((x) => [-1, 1].flatMap((y) => [-1, 1].map((z2) => [x * hx, y * hy, z2 * hz]))));
|
|
185440
|
+
default:
|
|
185441
|
+
return transform2([[-hx, -hy, 0], [hx, -hy, 0], [hx, hy, 0], [-hx, hy, 0]]);
|
|
184430
185442
|
}
|
|
184431
185443
|
}
|
|
184432
185444
|
function makeGeoFrameNode(kind, w, h, geo) {
|
|
@@ -184506,26 +185518,30 @@ function layoutPlan(kind, placed, strip, axes, edges) {
|
|
|
184506
185518
|
function layoutIso(kind, placed, strip, unit, edges) {
|
|
184507
185519
|
const cosA = Math.cos(Math.PI / 6);
|
|
184508
185520
|
const sinA = Math.sin(Math.PI / 6);
|
|
184509
|
-
let
|
|
185521
|
+
let centreMinX = 0, centreMaxX = 0, centreMinY = 0, centreMaxY = 0;
|
|
184510
185522
|
for (const n2 of placed) {
|
|
184511
185523
|
const g = n2.data.node.geo;
|
|
184512
|
-
|
|
184513
|
-
|
|
184514
|
-
|
|
184515
|
-
|
|
184516
|
-
pmaxZ = Math.max(pmaxZ, g.z ?? 0);
|
|
185524
|
+
centreMinX = Math.min(centreMinX, g.x);
|
|
185525
|
+
centreMaxX = Math.max(centreMaxX, g.x);
|
|
185526
|
+
centreMinY = Math.min(centreMinY, g.y);
|
|
185527
|
+
centreMaxY = Math.max(centreMaxY, g.y);
|
|
184517
185528
|
}
|
|
184518
|
-
const span = Math.max(
|
|
185529
|
+
const span = Math.max(centreMaxX - centreMinX, centreMaxY - centreMinY, 1);
|
|
184519
185530
|
const def = Math.max(span * 0.12, 1e-4);
|
|
185531
|
+
let pminX = 0, pmaxX = 0, pminY = 0, pmaxY = 0, pmaxZ = 0;
|
|
184520
185532
|
let isoMinX = Infinity, isoMaxX = -Infinity, isoMinY = Infinity, isoMaxY = -Infinity;
|
|
184521
185533
|
const iso = (x, y, z2) => [(x - y) * cosA, (x + y) * sinA - z2];
|
|
184522
|
-
const
|
|
185534
|
+
const pointsByNode = /* @__PURE__ */ new Map();
|
|
184523
185535
|
for (const n2 of placed) {
|
|
184524
|
-
const
|
|
184525
|
-
|
|
184526
|
-
const
|
|
184527
|
-
|
|
184528
|
-
|
|
185536
|
+
const points = geoShapePoints(n2.data.node, def);
|
|
185537
|
+
pointsByNode.set(n2, points);
|
|
185538
|
+
for (const [worldX, worldY, worldZ] of points) {
|
|
185539
|
+
pminX = Math.min(pminX, worldX);
|
|
185540
|
+
pmaxX = Math.max(pmaxX, worldX);
|
|
185541
|
+
pminY = Math.min(pminY, worldY);
|
|
185542
|
+
pmaxY = Math.max(pmaxY, worldY);
|
|
185543
|
+
pmaxZ = Math.max(pmaxZ, worldZ);
|
|
185544
|
+
const [ix, iy] = iso(worldX, worldY, worldZ);
|
|
184529
185545
|
isoMinX = Math.min(isoMinX, ix);
|
|
184530
185546
|
isoMaxX = Math.max(isoMaxX, ix);
|
|
184531
185547
|
isoMinY = Math.min(isoMinY, iy);
|
|
@@ -184537,11 +185553,9 @@ function layoutIso(kind, placed, strip, unit, edges) {
|
|
|
184537
185553
|
const oy = GEO_TOP_PAD + 6;
|
|
184538
185554
|
const frame3d = { ox, oy, scale, cosA, sinA, isoMinX, isoMinY, minX: pminX, maxX: pmaxX, minY: pminY, maxY: pmaxY, maxZ: pmaxZ, unit, def };
|
|
184539
185555
|
const outPlaced = placed.map((n2) => {
|
|
184540
|
-
const e = exts.get(n2);
|
|
184541
|
-
const g = n2.data.node.geo;
|
|
184542
185556
|
let sxMin = Infinity, syMin = Infinity, sxMax = -Infinity, syMax = -Infinity;
|
|
184543
|
-
for (const
|
|
184544
|
-
const [px, py] = geoProject(frame3d,
|
|
185557
|
+
for (const [worldX, worldY, worldZ] of pointsByNode.get(n2)) {
|
|
185558
|
+
const [px, py] = geoProject(frame3d, worldX, worldY, worldZ);
|
|
184545
185559
|
sxMin = Math.min(sxMin, px);
|
|
184546
185560
|
syMin = Math.min(syMin, py);
|
|
184547
185561
|
sxMax = Math.max(sxMax, px);
|
|
@@ -194080,7 +195094,7 @@ function buildEdgeBundles(candidates, obstacles = [], busPositions = {}) {
|
|
|
194080
195094
|
const buckets = /* @__PURE__ */ new Map();
|
|
194081
195095
|
const fanSizes = /* @__PURE__ */ new Map();
|
|
194082
195096
|
const add = (edge, role) => {
|
|
194083
|
-
if (edge.eligible === false) return;
|
|
195097
|
+
if (edge.eligible === false || edge.eligibleRole && edge.eligibleRole !== role) return;
|
|
194084
195098
|
const pairKey = `${edge.source}\0${edge.target}\0${edge.className}`;
|
|
194085
195099
|
if ((pairCounts.get(pairKey) ?? 0) > 1) return;
|
|
194086
195100
|
const commonNodeId = role === "source" ? edge.source : edge.target;
|
|
@@ -194784,6 +195798,16 @@ async function elkLayout(elk, graph) {
|
|
|
194784
195798
|
}
|
|
194785
195799
|
}
|
|
194786
195800
|
function overrideFor(node, overrides) {
|
|
195801
|
+
const stored = storedOverrideFor(node, overrides);
|
|
195802
|
+
if (!stored) return void 0;
|
|
195803
|
+
const compact2 = node.data.node?.meta?.internalsHidden === true || node.data.frame?.meta?.internalsHidden === true;
|
|
195804
|
+
const active = compact2 ? { ...stored, w: stored.collapsedW, h: stored.collapsedH } : stored;
|
|
195805
|
+
return {
|
|
195806
|
+
...active,
|
|
195807
|
+
h: connectionUsageHeightOverride(node.data.node, active.h, active.connectionBlockVersion)
|
|
195808
|
+
};
|
|
195809
|
+
}
|
|
195810
|
+
function storedOverrideFor(node, overrides) {
|
|
194787
195811
|
return overrides?.[node.data.layoutKey] ?? overrides?.[node.id];
|
|
194788
195812
|
}
|
|
194789
195813
|
var AFV_LAYOUT_EDGE_KINDS = /* @__PURE__ */ new Set([
|
|
@@ -196010,7 +197034,8 @@ function semanticPortHandle(node, handle) {
|
|
|
196010
197034
|
function validConcretePortAnchor(node, handle) {
|
|
196011
197035
|
const parsed = parsePortAnchorHandleId(handle);
|
|
196012
197036
|
const ph = parsed ? portOnNode(node, parsed.portId) : void 0;
|
|
196013
|
-
|
|
197037
|
+
if (!ph) return false;
|
|
197038
|
+
return ph.port.meta?.connectionEndPin === true ? handle === portAnchorHandleId(ph.port.id, ph.side) : portConnectHandleIds(ph.port.id, ph.side).includes(handle);
|
|
196014
197039
|
}
|
|
196015
197040
|
function isStrictDescendant(nodeId, ancestorId, byId) {
|
|
196016
197041
|
let cur = byId.get(nodeId)?.parentId;
|
|
@@ -196025,6 +197050,7 @@ function isStrictDescendant(nodeId, ancestorId, byId) {
|
|
|
196025
197050
|
function inferredPortAnchorSide(node, other, portId, byId) {
|
|
196026
197051
|
const ph = portOnNode(node, portId);
|
|
196027
197052
|
if (!ph) return "right";
|
|
197053
|
+
if (ph.port.meta?.connectionEndPin === true) return ph.side;
|
|
196028
197054
|
return other.id === node.id || isStrictDescendant(other.id, node.id, byId) ? OPPOSITE[ph.side] : ph.side;
|
|
196029
197055
|
}
|
|
196030
197056
|
function assignPortAnchorSides(nodes, edges) {
|
|
@@ -196115,6 +197141,38 @@ function nextSideAnchor(counts, offsetsCache, assignedOffsets, node, side, spaci
|
|
|
196115
197141
|
}
|
|
196116
197142
|
function assignEdgeSides(nodes, edges, topDown = false, connectPointSpacing = CONNECT_POINT_SPACING_DEFAULT, behaviorDirection) {
|
|
196117
197143
|
const byId = new Map(nodes.map((n2) => [n2.id, n2]));
|
|
197144
|
+
const naryHub = (node) => node?.data.node?.shape === "dot" && node.data.node.meta?.naryConnectionHub === true;
|
|
197145
|
+
const explicitHubAnchors = /* @__PURE__ */ new Map();
|
|
197146
|
+
const retainExplicitHubAnchor = (nodeId, side, offset2) => {
|
|
197147
|
+
const current2 = explicitHubAnchors.get(nodeId) ?? {};
|
|
197148
|
+
const offsets = current2[side] ?? [];
|
|
197149
|
+
if (!offsets.includes(offset2)) current2[side] = [...offsets, offset2].sort((a2, b) => a2 - b);
|
|
197150
|
+
explicitHubAnchors.set(nodeId, current2);
|
|
197151
|
+
};
|
|
197152
|
+
for (const edge of edges) {
|
|
197153
|
+
const sourceAnchor = parseSideAnchorHandleId(edge.sourceHandle);
|
|
197154
|
+
if (sourceAnchor && naryHub(byId.get(edge.source))) {
|
|
197155
|
+
if (edge.data?.explicitSourceAnchor === true) {
|
|
197156
|
+
retainExplicitHubAnchor(edge.source, sourceAnchor.side, sourceAnchor.offset);
|
|
197157
|
+
} else {
|
|
197158
|
+
edge.sourceHandle = sideAnchorHandleId(sourceAnchor.side, 0.5);
|
|
197159
|
+
}
|
|
197160
|
+
}
|
|
197161
|
+
const targetAnchor = parseSideAnchorHandleId(edge.targetHandle);
|
|
197162
|
+
if (targetAnchor && naryHub(byId.get(edge.target))) {
|
|
197163
|
+
if (edge.data?.explicitTargetAnchor === true) {
|
|
197164
|
+
retainExplicitHubAnchor(edge.target, targetAnchor.side, targetAnchor.offset);
|
|
197165
|
+
} else {
|
|
197166
|
+
edge.targetHandle = sideAnchorHandleId(targetAnchor.side, 0.5);
|
|
197167
|
+
}
|
|
197168
|
+
}
|
|
197169
|
+
}
|
|
197170
|
+
for (const node of nodes) {
|
|
197171
|
+
const explicit = explicitHubAnchors.get(node.id);
|
|
197172
|
+
if (naryHub(node) && (node.data.explicitSideAnchors || explicit)) {
|
|
197173
|
+
node.data = { ...node.data, explicitSideAnchors: explicit };
|
|
197174
|
+
}
|
|
197175
|
+
}
|
|
196118
197176
|
const sideCounts = /* @__PURE__ */ new Map();
|
|
196119
197177
|
const offsetsCache = /* @__PURE__ */ new Map();
|
|
196120
197178
|
const assignedOffsets = /* @__PURE__ */ new Map();
|
|
@@ -196134,7 +197192,7 @@ function assignEdgeSides(nodes, edges, topDown = false, connectPointSpacing = CO
|
|
|
196134
197192
|
const requests = /* @__PURE__ */ new Map();
|
|
196135
197193
|
const requestPreference = /* @__PURE__ */ new Map();
|
|
196136
197194
|
const requestKey = (edge, role) => `${edge.id}|${role}`;
|
|
196137
|
-
const anchor = (node, side, preferred) => nextSideAnchor(sideCounts, offsetsCache, assignedOffsets, node, side, connectPointSpacing, demand, preferred);
|
|
197195
|
+
const anchor = (node, side, preferred) => naryHub(node) ? sideAnchorHandleId(side, 0.5) : nextSideAnchor(sideCounts, offsetsCache, assignedOffsets, node, side, connectPointSpacing, demand, preferred);
|
|
196138
197196
|
const diamondPreference = (node, side, dx, dy) => {
|
|
196139
197197
|
const shape = node.data.node?.shape;
|
|
196140
197198
|
if (shape !== "decision" && shape !== "merge") return void 0;
|
|
@@ -197128,6 +198186,50 @@ function routePointNearSource(points, source, target, distance2) {
|
|
|
197128
198186
|
}
|
|
197129
198187
|
return void 0;
|
|
197130
198188
|
}
|
|
198189
|
+
function connectionEndLabelLines(edge, side, showMultiplicity) {
|
|
198190
|
+
const semanticRole = side === "from" ? edge.endRoleFrom : edge.endRoleTo;
|
|
198191
|
+
const multiplicity = side === "from" ? edge.endLabelFrom : edge.endLabelTo;
|
|
198192
|
+
let adornment = side === "from" ? edge.endAdornmentFrom : edge.endAdornmentTo;
|
|
198193
|
+
const namedPinEnd = side === "from" && (edge.meta?.connectionUsageEnd === true || edge.meta?.interfaceUsageEnd === true);
|
|
198194
|
+
if (namedPinEnd && semanticRole && adornment) {
|
|
198195
|
+
const impliedRedefinition = `redefines ${semanticRole}`;
|
|
198196
|
+
if (adornment === impliedRedefinition) {
|
|
198197
|
+
adornment = void 0;
|
|
198198
|
+
} else if (adornment.endsWith(` ${impliedRedefinition}`)) {
|
|
198199
|
+
adornment = adornment.slice(0, -(impliedRedefinition.length + 1)).trim() || void 0;
|
|
198200
|
+
}
|
|
198201
|
+
}
|
|
198202
|
+
const role = namedPinEnd ? void 0 : semanticRole;
|
|
198203
|
+
return [role, showMultiplicity ? multiplicity : void 0, adornment].filter((line2) => !!line2);
|
|
198204
|
+
}
|
|
198205
|
+
function connectionEndLabelPoint(points, source, target, side) {
|
|
198206
|
+
const reversed = side === "to" ? [...points ?? []].reverse() : points;
|
|
198207
|
+
const start2 = side === "to" ? target : source;
|
|
198208
|
+
const finish = side === "to" ? source : target;
|
|
198209
|
+
const near = routePointNearSource(reversed, start2, finish, 24);
|
|
198210
|
+
if (!near) return start2;
|
|
198211
|
+
return {
|
|
198212
|
+
x: markCoordinate(near.point.x - near.tangent.y * 12),
|
|
198213
|
+
y: markCoordinate(near.point.y + near.tangent.x * 12)
|
|
198214
|
+
};
|
|
198215
|
+
}
|
|
198216
|
+
function connectionElaborationGeometry(start2, target) {
|
|
198217
|
+
const cx = target.x + target.width / 2;
|
|
198218
|
+
const cy = target.y + target.height / 2;
|
|
198219
|
+
const dx = start2.x - cx;
|
|
198220
|
+
const dy = start2.y - cy;
|
|
198221
|
+
const scale = Math.max(
|
|
198222
|
+
Math.abs(dx) / Math.max(target.width / 2, 1),
|
|
198223
|
+
Math.abs(dy) / Math.max(target.height / 2, 1),
|
|
198224
|
+
1
|
|
198225
|
+
);
|
|
198226
|
+
const end = { x: cx + dx / scale, y: cy + dy / scale };
|
|
198227
|
+
return {
|
|
198228
|
+
start: start2,
|
|
198229
|
+
target: end,
|
|
198230
|
+
path: `M ${markCoordinate(start2.x)} ${markCoordinate(start2.y)} L ${markCoordinate(end.x)} ${markCoordinate(end.y)}`
|
|
198231
|
+
};
|
|
198232
|
+
}
|
|
197131
198233
|
function edgeLabelPoint(edge, centre, mark, points, source, target) {
|
|
197132
198234
|
const branchLabel = edge.kind === "succession" && (edge.label === "else" || /^\[.*\]$/u.test(edge.label ?? ""));
|
|
197133
198235
|
if (!branchLabel) return successionFlowLabelPoint(centre, mark);
|
|
@@ -197270,13 +198372,25 @@ function treeFacingDock(node, other, byId) {
|
|
|
197270
198372
|
const normal = otherCentre.y >= centre.y ? DOCK_NORMAL.bottom : DOCK_NORMAL.top;
|
|
197271
198373
|
return { point: { x: centre.x, y: centre.y + normal.y * h / 2 }, normal };
|
|
197272
198374
|
}
|
|
198375
|
+
function naryFacingDock(node, other, byId) {
|
|
198376
|
+
const from = nodeCentre(node, byId);
|
|
198377
|
+
const to = nodeCentre(other, byId);
|
|
198378
|
+
const dx = to.x - from.x;
|
|
198379
|
+
const dy = to.y - from.y;
|
|
198380
|
+
const side = Math.abs(dx) >= Math.abs(dy) ? dx >= 0 ? "right" : "left" : dy >= 0 ? "bottom" : "top";
|
|
198381
|
+
return dockPoint(node, sideAnchorHandleId(side, 0.5), byId, from);
|
|
198382
|
+
}
|
|
198383
|
+
function isNaryConnectionHub(node) {
|
|
198384
|
+
return node?.data.node?.shape === "dot" && node.data.node.meta?.naryConnectionHub === true;
|
|
198385
|
+
}
|
|
197273
198386
|
function bundleCandidateFor(edge, byId) {
|
|
197274
198387
|
const semantic = edge.data?.edge;
|
|
197275
198388
|
const sourceNode = byId.get(edge.source);
|
|
197276
198389
|
const targetNode = byId.get(edge.target);
|
|
197277
198390
|
if (!semantic || !sourceNode || !targetNode) return void 0;
|
|
197278
|
-
const
|
|
197279
|
-
const
|
|
198391
|
+
const naryRole = semantic.kind === "connect" ? isNaryConnectionHub(sourceNode) ? "source" : isNaryConnectionHub(targetNode) ? "target" : void 0 : void 0;
|
|
198392
|
+
const sourceFallback = naryRole ? naryFacingDock(sourceNode, targetNode, byId) : treeFacingDock(sourceNode, targetNode, byId);
|
|
198393
|
+
const targetFallback = naryRole ? naryFacingDock(targetNode, sourceNode, byId) : treeFacingDock(targetNode, sourceNode, byId);
|
|
197280
198394
|
const explicitSource = dockPoint(sourceNode, edge.sourceHandle, byId, sourceFallback.point);
|
|
197281
198395
|
const explicitTarget = dockPoint(targetNode, edge.targetHandle, byId, targetFallback.point);
|
|
197282
198396
|
const source = explicitSource.normal ? explicitSource : sourceFallback;
|
|
@@ -197299,7 +198413,8 @@ function bundleCandidateFor(edge, byId) {
|
|
|
197299
198413
|
// remaining separate semantic edges. Once one connector owns manual
|
|
197300
198414
|
// waypoints it deliberately leaves that automatic fan and keeps its
|
|
197301
198415
|
// individually movable route.
|
|
197302
|
-
eligible: edge.data?.kind === "gv" && GV_BUS_EDGE_KINDS.has(semantic.kind) &&
|
|
198416
|
+
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)),
|
|
198417
|
+
...naryRole ? { eligibleRole: naryRole } : {}
|
|
197303
198418
|
};
|
|
197304
198419
|
}
|
|
197305
198420
|
function movingNodeIds(nodes, byId) {
|
|
@@ -197472,7 +198587,7 @@ function edgeBundles(nodes, edges, runtime = defaultBundleRuntime) {
|
|
|
197472
198587
|
function projectedBundleMember(edge) {
|
|
197473
198588
|
return edge.data?.bundleMember;
|
|
197474
198589
|
}
|
|
197475
|
-
function
|
|
198590
|
+
function projectAutomaticBusRenderEdges(nodes, semanticEdges, runtime) {
|
|
197476
198591
|
const bundles = edgeBundles(nodes, semanticEdges, runtime);
|
|
197477
198592
|
if (!bundles.size) return semanticEdges;
|
|
197478
198593
|
return semanticEdges.map((edge) => {
|
|
@@ -198086,6 +199201,7 @@ body {
|
|
|
198086
199201
|
/* REQ-186/188/189/199/206/210 \u2014 the dashed labelled families */
|
|
198087
199202
|
.dlink.allocate, .dlink.frame, .dlink.derive, .dlink.causation, .dlink.import, .dlink.expose { stroke-dasharray: 4 3; }
|
|
198088
199203
|
.dlink.annotation { stroke-dasharray: 2 3; }
|
|
199204
|
+
.dlink.elaboration { stroke-dasharray: 2 3; pointer-events: none; }
|
|
198089
199205
|
.dlink.reply { stroke-dasharray: 4 3; } /* REQ-202 \u2014 sequence reply arrows */
|
|
198090
199206
|
/* issue #84 \u2014 REQ-202: a message is dragged up/down to change WHEN it happens.
|
|
198091
199207
|
The grip is the invisible hit band over the arrow (a row-resize cursor is the
|
|
@@ -198124,6 +199240,15 @@ body {
|
|
|
198124
199240
|
* on rather than the flow colour (user direction 2026-08-09). Its rounded corners and its
|
|
198125
199241
|
* direction arrow come from the shared port path in nodes.tsx. */
|
|
198126
199242
|
.dnode-port.pin { fill: var(--element-fill); stroke: var(--element-outline); stroke-width: 1.2; }
|
|
199243
|
+
/* REQ-192 - explicit connection ends are outline-coloured endpoint dots, not
|
|
199244
|
+
* action-pin boxes. The dot itself is the persistent snap affordance. */
|
|
199245
|
+
.dconnection-end-dot { fill: var(--element-outline); stroke: var(--element-outline); stroke-width: 1.2; }
|
|
199246
|
+
.dconnection-end-dot.selected { fill: var(--accent); stroke: var(--accent); }
|
|
199247
|
+
.rf-node.selected .dnode-control.dot { fill: var(--accent); stroke: var(--accent); }
|
|
199248
|
+
.dconnection-end-dot.hovered, .dconnection-end-dot.connect-target {
|
|
199249
|
+
fill: var(--cyan); stroke: var(--cyan); filter: drop-shadow(0 0 3px var(--cyan));
|
|
199250
|
+
}
|
|
199251
|
+
.dconnection-end-dot.moving { fill: var(--accent); stroke: var(--accent); filter: drop-shadow(0 0 4px var(--accent)); }
|
|
198127
199252
|
/* REQ-194 \u2014 the port direction ARROW: a shaft across the glyph with a solid head
|
|
198128
199253
|
* at each directed end (--> out, <-- in, <-> inout), per OMG 8.2.3.12.
|
|
198129
199254
|
* NOTE: no backticks in this file's CSS \u2014 STYLE is a template literal. */
|
|
@@ -198288,15 +199413,19 @@ body {
|
|
|
198288
199413
|
/* REQ-205 \u2014 Geometry View 3D (isometric) shapes + ground frame */
|
|
198289
199414
|
.dgeo3d-grid { stroke-width: 1; opacity: 0.35; }
|
|
198290
199415
|
.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.
|
|
199416
|
+
.dgeo3d-face.top { fill: var(--element-fill); fill-opacity: 0.42; }
|
|
199417
|
+
.dgeo3d-face.side { fill: var(--element-fill); fill-opacity: 0.28; }
|
|
199418
|
+
.dgeo3d-face.side2 { fill: var(--element-fill); fill-opacity: 0.18; }
|
|
198294
199419
|
.dgeo3d-edge { stroke: var(--element-outline); stroke-width: 1; opacity: 0.7; }
|
|
198295
199420
|
.dgeo3d-node { cursor: pointer; }
|
|
198296
199421
|
.dgeo3d-node:hover .dgeo3d-face { fill-opacity: 0.42; }
|
|
198297
199422
|
.dgeo3d-node.selected .dgeo3d-face { stroke: var(--accent); }
|
|
198298
199423
|
.dgeo3d-node.selected .dgeo3d-face.top { fill: var(--accent); fill-opacity: 0.34; }
|
|
198299
|
-
.dgeo3d-name {
|
|
199424
|
+
.dgeo3d-name {
|
|
199425
|
+
fill: var(--fg-0); stroke: var(--diagram-canvas); stroke-width: 3px;
|
|
199426
|
+
paint-order: stroke fill; stroke-linejoin: round;
|
|
199427
|
+
font-family: var(--font-mono); font-size: 10px;
|
|
199428
|
+
}
|
|
198300
199429
|
/* REQ-205 \u2014 an object whose coordinate-frame transformation could not be fully
|
|
198301
199430
|
decided is DRAWN and MARKED, never silently misplaced: its outline goes dashed
|
|
198302
199431
|
and it carries a warning glyph whose tooltip names the reason. (The issue
|
|
@@ -198873,14 +200002,17 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
198873
200002
|
* Each 5px dot has a compact hit box and can start or end a connector. The chosen
|
|
198874
200003
|
* handle is the chosen dock point, while the central body stays selectable. */
|
|
198875
200004
|
.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; }
|
|
200005
|
+
.react-flow__handle.rf-handle-connection-end { width: 12px; height: 12px; z-index: 6; }
|
|
200006
|
+
.react-flow__handle.rf-handle-connection-end::after { display: none; }
|
|
198876
200007
|
.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
200008
|
/* REQ-370: body snap points are hollow circles. Port and pin endpoints are
|
|
198878
200009
|
* solid squares, so adjacent targets cannot be mistaken for each other. */
|
|
198879
200010
|
.react-flow__handle.rf-handle-side::after { background: var(--bg-1); border: 1.5px solid var(--cyan); }
|
|
198880
200011
|
.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
|
|
200012
|
+
/* The start, done, and n-ary hub centre stays available for normal node
|
|
200013
|
+
* selection and dragging even though four 12px handle targets meet over these
|
|
200014
|
+
* exact-size glyphs. The perimeter dots remain above the rest of the node and
|
|
200015
|
+
* keep their full hit area. */
|
|
198884
200016
|
.rf-circular-control-hit {
|
|
198885
200017
|
position: absolute; left: 50%; top: 50%; width: 50%; height: 50%;
|
|
198886
200018
|
transform: translate(-50%, -50%); border-radius: 50%;
|
|
@@ -198894,6 +200026,7 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
198894
200026
|
.react-flow.sysml-connecting .react-flow__handle.rf-handle-side.connectionindicator,
|
|
198895
200027
|
.react-flow.sysml-connecting .react-flow__handle.rf-handle-lifeline.connectionindicator { opacity: 0.42; }
|
|
198896
200028
|
.react-flow.sysml-connecting .react-flow__handle.rf-handle-port.connectionindicator { opacity: 0.42; }
|
|
200029
|
+
.react-flow.sysml-connecting .react-flow__handle.rf-handle-connection-end.connectionindicator { opacity: 0.42; }
|
|
198897
200030
|
.react-flow.sysml-connecting .react-flow__handle.rf-handle-port.active { opacity: 1; }
|
|
198898
200031
|
/* The nearest semantically valid body target is stronger than the candidate
|
|
198899
200032
|
* points. Port and pin targets use the highlighted endpoint glyph instead. */
|
|
@@ -199044,6 +200177,9 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
199044
200177
|
.rf-edge-label { position: absolute; pointer-events: none; font-family: var(--font-mono); font-size: 9px;
|
|
199045
200178
|
color: var(--fg-0); background: transparent; border: 0; padding: 0; white-space: nowrap; }
|
|
199046
200179
|
.rf-edge-label.mult { background: transparent; border: 0; color: var(--fg-2); padding: 0; }
|
|
200180
|
+
.rf-edge-label.connection-end { color: var(--fg-1); display: flex; flex-direction: column;
|
|
200181
|
+
line-height: 1.15; text-align: center; white-space: nowrap; }
|
|
200182
|
+
.rf-edge-label.connection-end span:nth-child(n+2) { color: var(--fg-2); }
|
|
199047
200183
|
|
|
199048
200184
|
/* REQ-366/386 \u2014 two adjacent, independent container presentation controls.
|
|
199049
200185
|
* +/\u2212 owns graphical internals; the outlined list owns textual feature
|
|
@@ -199126,6 +200262,11 @@ function labelExtent(text) {
|
|
|
199126
200262
|
function labelSvg(text, x, y, cls) {
|
|
199127
200263
|
return `<text class="${cls}" x="${Math.round(x)}" y="${Math.round(y)}" text-anchor="middle" dominant-baseline="central">${escapeXml(text)}</text>`;
|
|
199128
200264
|
}
|
|
200265
|
+
function multilineLabelSvg(lines, x, y, cls) {
|
|
200266
|
+
const firstY = y - (lines.length - 1) * 5.5;
|
|
200267
|
+
const spans = lines.map((line2, index2) => `<tspan x="${Math.round(x)}" dy="${index2 === 0 ? 0 : 11}">${escapeXml(line2)}</tspan>`).join("");
|
|
200268
|
+
return `<text class="${cls}" x="${Math.round(x)}" y="${Math.round(firstY)}" text-anchor="middle" dominant-baseline="central">${spans}</text>`;
|
|
200269
|
+
}
|
|
199129
200270
|
function buildDiagramSvg(options) {
|
|
199130
200271
|
const { nodes, edges, lineStyle, nodeMarkup } = options;
|
|
199131
200272
|
if (!nodes.length) return null;
|
|
@@ -199204,6 +200345,22 @@ function buildDiagramSvg(options) {
|
|
|
199204
200345
|
const markerStart = style2.markerStart ? ` marker-start="${style2.markerStart}"` : "";
|
|
199205
200346
|
const markerEnd = style2.markerEnd ? ` marker-end="${style2.markerEnd}"` : "";
|
|
199206
200347
|
edgeParts.push(`<path class="${style2.className}" d="${geometry.path}"${markerStart}${markerEnd}/>`);
|
|
200348
|
+
if (semantic?.elaboration) {
|
|
200349
|
+
const targetNode = byId.get(semantic.elaboration);
|
|
200350
|
+
if (targetNode) {
|
|
200351
|
+
const position = absolutePos(targetNode.id, byId);
|
|
200352
|
+
const size = sizeOf(targetNode);
|
|
200353
|
+
const elaboration = connectionElaborationGeometry(geometry.label, {
|
|
200354
|
+
x: position.x,
|
|
200355
|
+
y: position.y,
|
|
200356
|
+
width: size.w,
|
|
200357
|
+
height: size.h
|
|
200358
|
+
});
|
|
200359
|
+
edgeParts.push(`<path class="dlink elaboration" d="${elaboration.path}"/>`);
|
|
200360
|
+
extendPoint(elaboration.start.x, elaboration.start.y, 2);
|
|
200361
|
+
extendPoint(elaboration.target.x, elaboration.target.y, 2);
|
|
200362
|
+
}
|
|
200363
|
+
}
|
|
199207
200364
|
const sequencingMark = successionFlowMarkGeometry(
|
|
199208
200365
|
style2,
|
|
199209
200366
|
geometry.label,
|
|
@@ -199231,14 +200388,22 @@ function buildDiagramSvg(options) {
|
|
|
199231
200388
|
labelParts.push(labelSvg(semantic.label, labelPoint.x, labelPoint.y, `elabel ${semantic.kind}`));
|
|
199232
200389
|
extendLabel(semantic.label, labelPoint.x, labelPoint.y);
|
|
199233
200390
|
}
|
|
199234
|
-
if (
|
|
199235
|
-
|
|
199236
|
-
|
|
199237
|
-
|
|
199238
|
-
|
|
199239
|
-
|
|
199240
|
-
|
|
199241
|
-
|
|
200391
|
+
if (semantic) {
|
|
200392
|
+
for (const side of ["from", "to"]) {
|
|
200393
|
+
const lines = connectionEndLabelLines(semantic, side, edge.data?.showMult === true);
|
|
200394
|
+
if (!lines.length) continue;
|
|
200395
|
+
const point = connectionEndLabelPoint(
|
|
200396
|
+
geometry.points ?? geometry.anchors,
|
|
200397
|
+
geometry.source,
|
|
200398
|
+
geometry.target,
|
|
200399
|
+
side
|
|
200400
|
+
);
|
|
200401
|
+
const role = side === "from" ? semantic.endRoleFrom : semantic.endRoleTo;
|
|
200402
|
+
const adornment = side === "from" ? semantic.endAdornmentFrom : semantic.endAdornmentTo;
|
|
200403
|
+
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"));
|
|
200404
|
+
const widest = lines.reduce((longest, line2) => line2.length > longest.length ? line2 : longest, "");
|
|
200405
|
+
extendLabel(widest, point.x, point.y);
|
|
200406
|
+
extendPoint(point.x, point.y, lines.length * 6);
|
|
199242
200407
|
}
|
|
199243
200408
|
}
|
|
199244
200409
|
}
|
|
@@ -199707,6 +200872,7 @@ var TOOLBOX = {
|
|
|
199707
200872
|
elements: [
|
|
199708
200873
|
el("part", "part", "\u25A2"),
|
|
199709
200874
|
el("port", "port", "\u25AB"),
|
|
200875
|
+
el("connection", "connection", "\u25AD"),
|
|
199710
200876
|
el("attribute", "attribute", "\u2013"),
|
|
199711
200877
|
el("item", "item", "\u25C7"),
|
|
199712
200878
|
el("constraint", "constraint", "{}"),
|
|
@@ -199871,7 +201037,7 @@ var COMMON_USAGE_KINDS = [
|
|
|
199871
201037
|
var CASE_CHILDREN = ["subject", "actor", "part", "attribute", "action", "item", "requirement"];
|
|
199872
201038
|
var CHILD_KINDS = {
|
|
199873
201039
|
package: ["package", ...DEFINITION_KINDS, ...COMMON_USAGE_KINDS],
|
|
199874
|
-
part: ["part", "attribute", "port", "item", "constraint", "action", "state", "calc", "occurrence"],
|
|
201040
|
+
part: ["part", "attribute", "port", "item", "connection", "constraint", "action", "state", "calc", "occurrence"],
|
|
199875
201041
|
item: ["attribute", "port", "part", "item"],
|
|
199876
201042
|
// REQ-006/REQ-192 — a port owns the features that describe what crosses
|
|
199877
201043
|
// its boundary. Keep the direction in the creation choice so an IV user
|
|
@@ -199976,6 +201142,7 @@ function isWritableRelationEndpoint(endpoint) {
|
|
|
199976
201142
|
}
|
|
199977
201143
|
function directRelationForHandle(viewKind, endpoint) {
|
|
199978
201144
|
if (!endpoint || !isWritableRelationEndpoint(endpoint)) return void 0;
|
|
201145
|
+
if (viewKind === "iv" && (endpoint.connectionEnd || normalizedElementKeyword(endpoint.keyword).base === "connection end")) return "connectionEnd";
|
|
199979
201146
|
return relationToolsForNode(endpoint.keyword, viewKind, endpoint.shape).find((tool) => tool.kind !== "terminate" && tool.kind !== "finish")?.kind;
|
|
199980
201147
|
}
|
|
199981
201148
|
var START_PSEUDOSTATE_BASES = /* @__PURE__ */ new Set(["start", "initial"]);
|
|
@@ -200066,6 +201233,65 @@ function relationToolsForNode(keyword, viewKind, shape) {
|
|
|
200066
201233
|
var import_react7 = __toESM(require_react());
|
|
200067
201234
|
var import_jsx_runtime3 = __toESM(require_jsx_runtime());
|
|
200068
201235
|
var ptStr = (pts) => pts.map((p) => `${p[0].toFixed(1)},${p[1].toFixed(1)}`).join(" ");
|
|
201236
|
+
var GEO_VIEW_DIRECTION = [1, 1, 1];
|
|
201237
|
+
function dot3(a2, b) {
|
|
201238
|
+
return a2[0] * b[0] + a2[1] * b[1] + a2[2] * b[2];
|
|
201239
|
+
}
|
|
201240
|
+
function cross3(a2, b) {
|
|
201241
|
+
return [
|
|
201242
|
+
a2[1] * b[2] - a2[2] * b[1],
|
|
201243
|
+
a2[2] * b[0] - a2[0] * b[2],
|
|
201244
|
+
a2[0] * b[1] - a2[1] * b[0]
|
|
201245
|
+
];
|
|
201246
|
+
}
|
|
201247
|
+
function subtract3(a2, b) {
|
|
201248
|
+
return [a2[0] - b[0], a2[1] - b[1], a2[2] - b[2]];
|
|
201249
|
+
}
|
|
201250
|
+
function convexHull(points) {
|
|
201251
|
+
const sorted = [...points].sort((a2, b) => a2[0] - b[0] || a2[1] - b[1]);
|
|
201252
|
+
if (sorted.length <= 2) return sorted;
|
|
201253
|
+
const turn = (a2, b, c) => (b[0] - a2[0]) * (c[1] - a2[1]) - (b[1] - a2[1]) * (c[0] - a2[0]);
|
|
201254
|
+
const half = (input) => {
|
|
201255
|
+
const result = [];
|
|
201256
|
+
for (const point of input) {
|
|
201257
|
+
while (result.length >= 2 && turn(result.at(-2), result.at(-1), point) <= 0) result.pop();
|
|
201258
|
+
result.push(point);
|
|
201259
|
+
}
|
|
201260
|
+
return result;
|
|
201261
|
+
};
|
|
201262
|
+
const lower2 = half(sorted);
|
|
201263
|
+
const upper = half([...sorted].reverse());
|
|
201264
|
+
return [...lower2.slice(0, -1), ...upper.slice(0, -1)];
|
|
201265
|
+
}
|
|
201266
|
+
function polyhedronBody(node, f, localVertices, faces) {
|
|
201267
|
+
const g = node.geo;
|
|
201268
|
+
const center = geoWorldPoint(g, [0, 0, 0]);
|
|
201269
|
+
const world = localVertices.map((point) => geoWorldPoint(g, point));
|
|
201270
|
+
const visible = faces.flatMap((face, index2) => {
|
|
201271
|
+
let points = face.map((vertex) => world[vertex]);
|
|
201272
|
+
let normal = cross3(subtract3(points[1], points[0]), subtract3(points[2], points[0]));
|
|
201273
|
+
const faceCenter = [
|
|
201274
|
+
points.reduce((sum, point) => sum + point[0], 0) / points.length,
|
|
201275
|
+
points.reduce((sum, point) => sum + point[1], 0) / points.length,
|
|
201276
|
+
points.reduce((sum, point) => sum + point[2], 0) / points.length
|
|
201277
|
+
];
|
|
201278
|
+
if (dot3(normal, subtract3(faceCenter, center)) < 0) {
|
|
201279
|
+
points = [...points].reverse();
|
|
201280
|
+
normal = [-normal[0], -normal[1], -normal[2]];
|
|
201281
|
+
}
|
|
201282
|
+
const normalLength = Math.hypot(normal[0], normal[1], normal[2]);
|
|
201283
|
+
if (normalLength === 0 || dot3(normal, GEO_VIEW_DIRECTION) / (normalLength * Math.sqrt(3)) <= 1e-9) return [];
|
|
201284
|
+
const absolute = normal.map(Math.abs);
|
|
201285
|
+
const faceClass = absolute[2] >= absolute[0] && absolute[2] >= absolute[1] && normal[2] > 0 ? "top" : absolute[0] >= absolute[1] ? "side2" : "side";
|
|
201286
|
+
return [{
|
|
201287
|
+
key: index2,
|
|
201288
|
+
faceClass,
|
|
201289
|
+
depth: points.reduce((sum, point) => sum + dot3(point, GEO_VIEW_DIRECTION), 0) / points.length,
|
|
201290
|
+
points: points.map((point) => geoProject(f, point[0], point[1], point[2]))
|
|
201291
|
+
}];
|
|
201292
|
+
}).sort((a2, b) => a2.depth - b.depth);
|
|
201293
|
+
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)) });
|
|
201294
|
+
}
|
|
200069
201295
|
var GEO_HANDLE_POSITION = {
|
|
200070
201296
|
top: Position3.Top,
|
|
200071
201297
|
right: Position3.Right,
|
|
@@ -200188,15 +201414,16 @@ function IsoAxes({ f, marker }) {
|
|
|
200188
201414
|
}
|
|
200189
201415
|
function geoShapeBody(node, f) {
|
|
200190
201416
|
const g = node.geo;
|
|
200191
|
-
const
|
|
201417
|
+
const { hx, hy, hz } = geoHalfExtentsOf(node, f.def);
|
|
200192
201418
|
const P = (x, y, z2) => geoProject(f, x, y, z2);
|
|
200193
|
-
const
|
|
200194
|
-
|
|
200195
|
-
|
|
201419
|
+
const PL = (point) => {
|
|
201420
|
+
const world = geoWorldPoint(g, point);
|
|
201421
|
+
return P(world[0], world[1], world[2]);
|
|
201422
|
+
};
|
|
200196
201423
|
switch (g.shape) {
|
|
200197
201424
|
case "sphere": {
|
|
200198
|
-
const c =
|
|
200199
|
-
const pts =
|
|
201425
|
+
const c = PL([0, 0, 0]);
|
|
201426
|
+
const pts = geoShapePoints(node, f.def).map((point) => P(point[0], point[1], point[2]));
|
|
200200
201427
|
const r = Math.max(...pts.map((p) => Math.hypot(p[0] - c[0], p[1] - c[1])));
|
|
200201
201428
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("g", { children: [
|
|
200202
201429
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { className: "dgeo3d-face top", cx: c[0], cy: c[1], r }),
|
|
@@ -200205,64 +201432,79 @@ function geoShapeBody(node, f) {
|
|
|
200205
201432
|
}
|
|
200206
201433
|
case "cylinder":
|
|
200207
201434
|
case "cone": {
|
|
200208
|
-
const
|
|
200209
|
-
const
|
|
200210
|
-
|
|
200211
|
-
|
|
200212
|
-
|
|
200213
|
-
|
|
200214
|
-
|
|
200215
|
-
const base = exr(zlo);
|
|
201435
|
+
const ring = (z2) => Array.from({ length: 32 }, (_2, index2) => {
|
|
201436
|
+
const angle = index2 * Math.PI / 16;
|
|
201437
|
+
return [hx * Math.cos(angle), hy * Math.sin(angle), z2];
|
|
201438
|
+
});
|
|
201439
|
+
const baseLocal = ring(-hz);
|
|
201440
|
+
const baseWorld = baseLocal.map((point) => geoWorldPoint(g, point));
|
|
201441
|
+
const base = baseWorld.map((point) => P(point[0], point[1], point[2]));
|
|
200216
201442
|
if (g.shape === "cone") {
|
|
200217
|
-
const
|
|
201443
|
+
const apexWorld = geoWorldPoint(g, [0, 0, hz]);
|
|
201444
|
+
const apex = P(apexWorld[0], apexWorld[1], apexWorld[2]);
|
|
201445
|
+
const baseCenter = geoWorldPoint(g, [0, 0, -hz]);
|
|
201446
|
+
const baseVisible = dot3(baseCenter, GEO_VIEW_DIRECTION) > dot3(apexWorld, GEO_VIEW_DIRECTION);
|
|
200218
201447
|
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" })
|
|
201448
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polygon", { className: "dgeo3d-face side", points: ptStr(convexHull([...base, apex])) }),
|
|
201449
|
+
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
201450
|
] });
|
|
200223
201451
|
}
|
|
200224
|
-
const
|
|
201452
|
+
const topLocal = ring(hz);
|
|
201453
|
+
const topWorld = topLocal.map((point) => geoWorldPoint(g, point));
|
|
201454
|
+
const top = topWorld.map((point) => P(point[0], point[1], point[2]));
|
|
201455
|
+
const baseDepth = dot3(geoWorldPoint(g, [0, 0, -hz]), GEO_VIEW_DIRECTION);
|
|
201456
|
+
const topDepth = dot3(geoWorldPoint(g, [0, 0, hz]), GEO_VIEW_DIRECTION);
|
|
201457
|
+
const near = topDepth >= baseDepth ? top : base;
|
|
201458
|
+
const far = topDepth >= baseDepth ? base : top;
|
|
200225
201459
|
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)("
|
|
201460
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polygon", { className: "dgeo3d-face side", points: ptStr(convexHull([...base, ...top])) }),
|
|
201461
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polyline", { className: "dgeo3d-edge", points: ptStr([...far, far[0]]), fill: "none", strokeDasharray: "3 3" }),
|
|
201462
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polygon", { className: "dgeo3d-face top", points: ptStr(near) })
|
|
200229
201463
|
] });
|
|
200230
201464
|
}
|
|
200231
201465
|
case "pyramid": {
|
|
200232
|
-
const
|
|
200233
|
-
|
|
200234
|
-
|
|
200235
|
-
|
|
200236
|
-
|
|
200237
|
-
|
|
200238
|
-
|
|
200239
|
-
|
|
200240
|
-
] });
|
|
201466
|
+
const vertices = [
|
|
201467
|
+
[-hx, -hy, -hz],
|
|
201468
|
+
[hx, -hy, -hz],
|
|
201469
|
+
[hx, hy, -hz],
|
|
201470
|
+
[-hx, hy, -hz],
|
|
201471
|
+
[0, 0, hz]
|
|
201472
|
+
];
|
|
201473
|
+
return polyhedronBody(node, f, vertices, [[0, 3, 2, 1], [0, 1, 4], [1, 2, 4], [2, 3, 4], [3, 0, 4]]);
|
|
200241
201474
|
}
|
|
200242
201475
|
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
|
-
] });
|
|
201476
|
+
const vertices = [
|
|
201477
|
+
[-hx, -hy, -hz],
|
|
201478
|
+
[hx, -hy, -hz],
|
|
201479
|
+
[hx, hy, -hz],
|
|
201480
|
+
[-hx, hy, -hz],
|
|
201481
|
+
[0, -hy, hz],
|
|
201482
|
+
[0, hy, hz]
|
|
201483
|
+
];
|
|
201484
|
+
return polyhedronBody(node, f, vertices, [[0, 3, 2, 1], [0, 1, 4], [1, 2, 5, 4], [2, 3, 5], [3, 0, 4, 5]]);
|
|
200254
201485
|
}
|
|
200255
201486
|
case "box": {
|
|
200256
|
-
const
|
|
200257
|
-
|
|
200258
|
-
|
|
200259
|
-
|
|
200260
|
-
|
|
200261
|
-
|
|
200262
|
-
|
|
201487
|
+
const vertices = [
|
|
201488
|
+
[-hx, -hy, -hz],
|
|
201489
|
+
[hx, -hy, -hz],
|
|
201490
|
+
[hx, hy, -hz],
|
|
201491
|
+
[-hx, hy, -hz],
|
|
201492
|
+
[-hx, -hy, hz],
|
|
201493
|
+
[hx, -hy, hz],
|
|
201494
|
+
[hx, hy, hz],
|
|
201495
|
+
[-hx, hy, hz]
|
|
201496
|
+
];
|
|
201497
|
+
return polyhedronBody(node, f, vertices, [
|
|
201498
|
+
[0, 3, 2, 1],
|
|
201499
|
+
[4, 5, 6, 7],
|
|
201500
|
+
[0, 1, 5, 4],
|
|
201501
|
+
[1, 2, 6, 5],
|
|
201502
|
+
[2, 3, 7, 6],
|
|
201503
|
+
[3, 0, 4, 7]
|
|
201504
|
+
]);
|
|
200263
201505
|
}
|
|
200264
201506
|
default: {
|
|
200265
|
-
const q = [
|
|
201507
|
+
const q = [PL([-hx, -hy, 0]), PL([hx, -hy, 0]), PL([hx, hy, 0]), PL([-hx, hy, 0])];
|
|
200266
201508
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polygon", { className: "dgeo3d-face top", points: ptStr(q) });
|
|
200267
201509
|
}
|
|
200268
201510
|
}
|
|
@@ -200285,6 +201527,7 @@ function GeoShapeNode({ id: id2, data, selected: selected2 }) {
|
|
|
200285
201527
|
const dim = useInteraction(ctx.store, (s) => s.matchedIds ? !s.matchedIds.has(id2) : false);
|
|
200286
201528
|
const origin = data.origin;
|
|
200287
201529
|
const iso = data.geo3d && node.geo && origin;
|
|
201530
|
+
const displayName = node.name.split(/::|\./u).filter(Boolean).at(-1) ?? node.name;
|
|
200288
201531
|
const approx = node.geo?.approx;
|
|
200289
201532
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
200290
201533
|
"div",
|
|
@@ -200300,7 +201543,10 @@ function GeoShapeNode({ id: id2, data, selected: selected2 }) {
|
|
|
200300
201543
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { className: "rf-node-svg", width: w, height: h, style: { overflow: "visible" }, children: [
|
|
200301
201544
|
iso ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
200302
201545
|
/* @__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.
|
|
201546
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("text", { className: "dgeo3d-name", x: w / 2, y: -3, textAnchor: "middle", children: [
|
|
201547
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("title", { children: node.name }),
|
|
201548
|
+
displayName
|
|
201549
|
+
] })
|
|
200304
201550
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
200305
201551
|
/* @__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
201552
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("text", { className: "dnode-label", x: w / 2, y: h / 2 + 3, textAnchor: "middle", children: node.name })
|
|
@@ -200521,7 +201767,7 @@ function usePortDrag(containerRef, w, h, topReserve, onPortMove, onPortPreview,
|
|
|
200521
201767
|
};
|
|
200522
201768
|
return { dragId, onPortPointerDown };
|
|
200523
201769
|
}
|
|
200524
|
-
function DualHandle({ id: id2, side, x, y, kind, active, connectable = true, startable = false, size, occluded = false }) {
|
|
201770
|
+
function DualHandle({ id: id2, side, x, y, kind, active, connectable = true, startable = false, size, occluded = false, onContextMenu }) {
|
|
200525
201771
|
const dimensions = typeof size === "number" ? { width: size, height: size } : size;
|
|
200526
201772
|
const style2 = dimensions ? { left: x, top: y, ...dimensions, transform: "translate(-50%,-50%)" } : { left: x, top: y, transform: "translate(-50%,-50%)" };
|
|
200527
201773
|
const enabled = connectable && !occluded;
|
|
@@ -200537,7 +201783,8 @@ function DualHandle({ id: id2, side, x, y, kind, active, connectable = true, sta
|
|
|
200537
201783
|
className: cls,
|
|
200538
201784
|
isConnectable: enabled,
|
|
200539
201785
|
isConnectableStart: false,
|
|
200540
|
-
isConnectableEnd: enabled
|
|
201786
|
+
isConnectableEnd: enabled,
|
|
201787
|
+
onContextMenu
|
|
200541
201788
|
}
|
|
200542
201789
|
),
|
|
200543
201790
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
@@ -200550,7 +201797,8 @@ function DualHandle({ id: id2, side, x, y, kind, active, connectable = true, sta
|
|
|
200550
201797
|
className: cls,
|
|
200551
201798
|
isConnectable: enabled,
|
|
200552
201799
|
isConnectableStart: enabled && startable,
|
|
200553
|
-
isConnectableEnd: enabled
|
|
201800
|
+
isConnectableEnd: enabled,
|
|
201801
|
+
onContextMenu
|
|
200554
201802
|
}
|
|
200555
201803
|
)
|
|
200556
201804
|
] });
|
|
@@ -200892,7 +202140,15 @@ function AnnotationBody({ node, w, h }) {
|
|
|
200892
202140
|
}
|
|
200893
202141
|
function DotBody({ node, w, h }) {
|
|
200894
202142
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("g", { children: [
|
|
200895
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
202143
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
202144
|
+
"circle",
|
|
202145
|
+
{
|
|
202146
|
+
className: "dnode-control dot dconnection-end-dot",
|
|
202147
|
+
cx: w / 2,
|
|
202148
|
+
cy: h / 2,
|
|
202149
|
+
r: circularControlRadius("dot")
|
|
202150
|
+
}
|
|
202151
|
+
),
|
|
200896
202152
|
node.name ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("text", { className: "dnode-kind", x: w / 2 + 9, y: h / 2 + 4, children: node.name }) : ""
|
|
200897
202153
|
] });
|
|
200898
202154
|
}
|
|
@@ -200961,6 +202217,8 @@ function PortGlyph({ ph, w, h, topReserve = 0, showLabels, selected: selected2,
|
|
|
200961
202217
|
};
|
|
200962
202218
|
})() : void 0;
|
|
200963
202219
|
const proxy = rect.proxy;
|
|
202220
|
+
const connectionEnd = ph.port.meta?.connectionEndPin === true;
|
|
202221
|
+
const glyphClass = `${selected2 ? " selected" : ""}${hovered ? " hovered" : ""}${moving ? " moving" : ""}${connectTargetSide ? " connect-target" : ""}`;
|
|
200964
202222
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
200965
202223
|
"g",
|
|
200966
202224
|
{
|
|
@@ -200990,10 +202248,10 @@ function PortGlyph({ ph, w, h, topReserve = 0, showLabels, selected: selected2,
|
|
|
200990
202248
|
}
|
|
200991
202249
|
);
|
|
200992
202250
|
})() : null,
|
|
200993
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
202251
|
+
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
202252
|
"rect",
|
|
200995
202253
|
{
|
|
200996
|
-
className: `dnode-port${ph.port.pin ? " pin" : ""}${ph.port.ref ? " ref" : ""}${rect.elongated ? " host" : ""}${proxy ? " proxy" : ""}${
|
|
202254
|
+
className: `dnode-port${ph.port.pin ? " pin" : ""}${ph.port.ref ? " ref" : ""}${rect.elongated ? " host" : ""}${proxy ? " proxy" : ""}${glyphClass}`,
|
|
200997
202255
|
x: rect.x,
|
|
200998
202256
|
y: rect.y,
|
|
200999
202257
|
width: rect.width,
|
|
@@ -201001,12 +202259,12 @@ function PortGlyph({ ph, w, h, topReserve = 0, showLabels, selected: selected2,
|
|
|
201001
202259
|
rx: ph.port.isDef ? 0 : PORT_CORNER_RADIUS
|
|
201002
202260
|
}
|
|
201003
202261
|
),
|
|
201004
|
-
d ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
202262
|
+
d && !connectionEnd ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
201005
202263
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { className: "dport-dir", d: arrowShaft() }),
|
|
201006
202264
|
d === "out" || d === "inout" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { className: "dport-dir head", d: arrowHead(1) }) : "",
|
|
201007
202265
|
d === "in" || d === "inout" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { className: "dport-dir head", d: arrowHead(-1) }) : ""
|
|
201008
202266
|
] }) : "",
|
|
201009
|
-
selected2 && connectStart && !connectTargetSide && !proxy ? (() => {
|
|
202267
|
+
selected2 && connectStart && !connectTargetSide && !proxy && !connectionEnd ? (() => {
|
|
201010
202268
|
const px = x + v.x * (half + PORT_PLUS_GAP);
|
|
201011
202269
|
const py = y + v.y * (half + PORT_PLUS_GAP);
|
|
201012
202270
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("g", { className: "dport-plus", children: [
|
|
@@ -201014,7 +202272,7 @@ function PortGlyph({ ph, w, h, topReserve = 0, showLabels, selected: selected2,
|
|
|
201014
202272
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: px, y1: py - PORT_PLUS_HALF, x2: px, y2: py + PORT_PLUS_HALF })
|
|
201015
202273
|
] });
|
|
201016
202274
|
})() : "",
|
|
201017
|
-
connectTargetSide ? (() => {
|
|
202275
|
+
connectTargetSide && !connectionEnd ? (() => {
|
|
201018
202276
|
const at2 = portDockAt(rect, ph.side, connectTargetSide);
|
|
201019
202277
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("circle", { className: "dport-anchor", cx: at2.x, cy: at2.y, r: 1.7 });
|
|
201020
202278
|
})() : "",
|
|
@@ -201270,7 +202528,7 @@ function NodeBody({ node, data, selectedPortId, hoveredPortId, movingPortId, con
|
|
|
201270
202528
|
hovered: hoveredPortId === ph.port.id,
|
|
201271
202529
|
moving: movingPortId === ph.port.id,
|
|
201272
202530
|
connectTargetSide: connectTargetPortId === ph.port.id ? connectTargetPortSide : void 0,
|
|
201273
|
-
connectStart: showPortConnectStart && (data.kind === "iv" ? ph.port.pin !== true : data.kind === "afv"),
|
|
202531
|
+
connectStart: showPortConnectStart && (data.kind === "iv" ? ph.port.pin !== true || ph.port.meta?.connectionEndPin === true : data.kind === "afv"),
|
|
201274
202532
|
onSelect: onPortSelect,
|
|
201275
202533
|
onContext: onPortContext
|
|
201276
202534
|
},
|
|
@@ -201322,15 +202580,16 @@ function SysmlNode({ id: id2, data, draggable, selected: selected2, width, heigh
|
|
|
201322
202580
|
shape: node.shape,
|
|
201323
202581
|
source: node.source
|
|
201324
202582
|
});
|
|
201325
|
-
const
|
|
202583
|
+
const connectionUsage = node.meta?.connectionUsage === true || node.meta?.interfaceUsage === true;
|
|
202584
|
+
const nodeSideStartable = !connectionUsage && directRelation !== void 0 && data.kind !== "sv" && node.shape !== "lifeline" && !isPackageEndpoint(node.shape, node.keyword);
|
|
201326
202585
|
const selectedPortId = useInteraction(ctx.store, (s) => typeof s.selectedId === "string" && myPortIds.includes(s.selectedId) ? s.selectedId : void 0);
|
|
201327
202586
|
const dropClass = useDropState(ctx.store, id2);
|
|
201328
202587
|
const [hoveredPortId, setHoveredPortId] = (0, import_react9.useState)(void 0);
|
|
201329
202588
|
const [sidePointsHovered, setSidePointsHovered] = (0, import_react9.useState)(false);
|
|
201330
202589
|
const isPackageNode = isPackageEndpoint(node.shape, node.keyword);
|
|
201331
|
-
const sideConnectable = data.kind !== "sv" && !isPackageNode;
|
|
202590
|
+
const sideConnectable = data.kind !== "sv" && !isPackageNode && !connectionUsage;
|
|
201332
202591
|
const perimeterControl = keepsPerimeterSidePointsMounted(node.shape);
|
|
201333
|
-
const sideOffsets = SIDES.map((side) => mountedNodeSidePointOffsets(
|
|
202592
|
+
const sideOffsets = connectionUsage ? SIDES.map(() => []) : SIDES.map((side) => mountedNodeSidePointOffsets(
|
|
201334
202593
|
data,
|
|
201335
202594
|
side,
|
|
201336
202595
|
sideConnectable,
|
|
@@ -201453,17 +202712,39 @@ function SysmlNode({ id: id2, data, draggable, selected: selected2, width, heigh
|
|
|
201453
202712
|
);
|
|
201454
202713
|
});
|
|
201455
202714
|
}),
|
|
201456
|
-
node.shape === "initial" || node.shape === "final" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "rf-circular-control-hit", "aria-hidden": "true" }) : null,
|
|
202715
|
+
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
202716
|
ports.flatMap((ph) => {
|
|
201458
202717
|
const rect = portGlyphRect(ph, w, h, featureCompartmentHeight);
|
|
201459
202718
|
const proxied = isProxyPort(ph.port);
|
|
201460
202719
|
const startable = !proxied && directRelationForHandle(data.kind, {
|
|
201461
202720
|
id: ph.port.id,
|
|
201462
202721
|
name: ph.port.name,
|
|
201463
|
-
keyword: ph.port.pin ? "pin" : "port",
|
|
202722
|
+
keyword: ph.port.meta?.interfaceEndPort === true ? "interface end" : ph.port.meta?.connectionEndPin === true ? "connection end" : ph.port.pin ? "pin" : "port",
|
|
201464
202723
|
shape: ph.port.pin ? "pin" : "port",
|
|
201465
202724
|
source: ph.port.source
|
|
201466
202725
|
}) !== void 0;
|
|
202726
|
+
if (ph.port.meta?.connectionEndPin === true) {
|
|
202727
|
+
const point = portDockAt(rect, ph.side, ph.side);
|
|
202728
|
+
return [/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
202729
|
+
DualHandle,
|
|
202730
|
+
{
|
|
202731
|
+
id: portAnchorHandleId(ph.port.id, ph.side),
|
|
202732
|
+
side: ph.side,
|
|
202733
|
+
x: point.x,
|
|
202734
|
+
y: point.y,
|
|
202735
|
+
kind: "connection-end",
|
|
202736
|
+
connectable: !proxied,
|
|
202737
|
+
active: !proxied && (ph.port.id === hoveredPortId || ph.port.id === selectedPortId || ph.port.id === connectTargetPortId),
|
|
202738
|
+
startable,
|
|
202739
|
+
onContextMenu: (e) => {
|
|
202740
|
+
e.preventDefault();
|
|
202741
|
+
e.stopPropagation();
|
|
202742
|
+
ctx.onContextNode(ph.port.id, e.clientX, e.clientY);
|
|
202743
|
+
}
|
|
202744
|
+
},
|
|
202745
|
+
`${ph.port.id}-end`
|
|
202746
|
+
)];
|
|
202747
|
+
}
|
|
201467
202748
|
const [outerId, innerId] = portConnectHandleIds(ph.port.id, ph.side);
|
|
201468
202749
|
const outer = portDockAt(rect, ph.side, ph.side);
|
|
201469
202750
|
const innerSide = OPPOSITE_DOCK_SIDE[ph.side];
|
|
@@ -201504,7 +202785,7 @@ function SysmlNode({ id: id2, data, draggable, selected: selected2, width, heigh
|
|
|
201504
202785
|
const rect = portGlyphRect(ph, w, h, featureCompartmentHeight);
|
|
201505
202786
|
const nestedChild = ph.port.parentPort !== void 0;
|
|
201506
202787
|
const proxyPort = isProxyPort(ph.port);
|
|
201507
|
-
const strip = portInteractionStrip(rect, ph.side);
|
|
202788
|
+
const strip = portInteractionStrip(rect, ph.side, ph.port.meta?.connectionEndPin === true);
|
|
201508
202789
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
201509
202790
|
"div",
|
|
201510
202791
|
{
|
|
@@ -201875,7 +203156,7 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
201875
203156
|
hovered: hoveredPortId === ph.port.id,
|
|
201876
203157
|
moving: dragId === ph.port.id,
|
|
201877
203158
|
connectTargetSide: connectTargetPortId === ph.port.id ? connectTargetPortSide : void 0,
|
|
201878
|
-
connectStart: data.kind === "iv" ? ph.port.pin !== true : data.kind === "afv",
|
|
203159
|
+
connectStart: data.kind === "iv" ? ph.port.pin !== true || ph.port.meta?.connectionEndPin === true : data.kind === "afv",
|
|
201879
203160
|
onSelect: ctx.onPortMove ? void 0 : portSource,
|
|
201880
203161
|
onContext: ctx.onContextNode
|
|
201881
203162
|
},
|
|
@@ -201948,10 +203229,32 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
201948
203229
|
const startable = !proxied && directRelationForHandle(data.kind, {
|
|
201949
203230
|
id: ph.port.id,
|
|
201950
203231
|
name: ph.port.name,
|
|
201951
|
-
keyword: ph.port.pin ? "pin" : "port",
|
|
203232
|
+
keyword: ph.port.meta?.interfaceEndPort === true ? "interface end" : ph.port.meta?.connectionEndPin === true ? "connection end" : ph.port.pin ? "pin" : "port",
|
|
201952
203233
|
shape: ph.port.pin ? "pin" : "port",
|
|
201953
203234
|
source: ph.port.source
|
|
201954
203235
|
}) !== void 0;
|
|
203236
|
+
if (ph.port.meta?.connectionEndPin === true) {
|
|
203237
|
+
const point = portDockAt(rect, ph.side, ph.side);
|
|
203238
|
+
return [/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
203239
|
+
DualHandle,
|
|
203240
|
+
{
|
|
203241
|
+
id: portAnchorHandleId(ph.port.id, ph.side),
|
|
203242
|
+
side: ph.side,
|
|
203243
|
+
x: point.x,
|
|
203244
|
+
y: point.y,
|
|
203245
|
+
kind: "connection-end",
|
|
203246
|
+
connectable: !proxied,
|
|
203247
|
+
active: !proxied && (ph.port.id === hoveredPortId || ph.port.id === selectedPortId || ph.port.id === connectTargetPortId),
|
|
203248
|
+
startable,
|
|
203249
|
+
onContextMenu: (e) => {
|
|
203250
|
+
e.preventDefault();
|
|
203251
|
+
e.stopPropagation();
|
|
203252
|
+
ctx.onContextNode(ph.port.id, e.clientX, e.clientY);
|
|
203253
|
+
}
|
|
203254
|
+
},
|
|
203255
|
+
`${ph.port.id}-end`
|
|
203256
|
+
)];
|
|
203257
|
+
}
|
|
201955
203258
|
const [outerId, innerId] = portConnectHandleIds(ph.port.id, ph.side);
|
|
201956
203259
|
const outer = portDockAt(rect, ph.side, ph.side);
|
|
201957
203260
|
const innerSide = OPPOSITE_DOCK_SIDE[ph.side];
|
|
@@ -201992,7 +203295,7 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
201992
203295
|
const rect = portGlyphRect(ph, w, h, featureCompartmentHeight);
|
|
201993
203296
|
const nestedChild = ph.port.parentPort !== void 0;
|
|
201994
203297
|
const proxyPort = isProxyPort(ph.port);
|
|
201995
|
-
const strip = portInteractionStrip(rect, ph.side);
|
|
203298
|
+
const strip = portInteractionStrip(rect, ph.side, ph.port.meta?.connectionEndPin === true);
|
|
201996
203299
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
201997
203300
|
"div",
|
|
201998
203301
|
{
|
|
@@ -202323,7 +203626,7 @@ async function renderDiagramSvg(document2, provider, options) {
|
|
|
202323
203626
|
overrides: config.overrides,
|
|
202324
203627
|
connectPointSpacing: config.connectPointSpacing
|
|
202325
203628
|
});
|
|
202326
|
-
const renderEdges =
|
|
203629
|
+
const renderEdges = config.lineStyle === "orthogonal" ? projectAutomaticBusRenderEdges(laid.nodes, laid.edges, createEdgeBundleRuntime()) : laid.edges;
|
|
202327
203630
|
const indexOf2 = new Map(laid.nodes.map((node, i) => [node.id, i]));
|
|
202328
203631
|
return buildDiagramSvg({
|
|
202329
203632
|
nodes: laid.nodes,
|
|
@@ -202379,7 +203682,7 @@ async function runExport(command) {
|
|
|
202379
203682
|
}
|
|
202380
203683
|
|
|
202381
203684
|
// src/main.ts
|
|
202382
|
-
var VERSION2 = true ? "0.
|
|
203685
|
+
var VERSION2 = true ? "0.23.0" : "dev";
|
|
202383
203686
|
function display(file) {
|
|
202384
203687
|
const rel2 = path9.relative(process.cwd(), file);
|
|
202385
203688
|
return rel2 && !rel2.startsWith("..") ? rel2.split(path9.sep).join("/") : file;
|