@istar-ts/core 0.14.2 → 0.15.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -0
- package/dist/index.cjs +372 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +244 -133
- package/dist/index.d.ts +244 -133
- package/dist/index.js +367 -47
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -763,14 +763,204 @@ function defaultHubPosition(model, source, target, size) {
|
|
|
763
763
|
y: (a.y + b.y) / 2 - size.height / 2
|
|
764
764
|
};
|
|
765
765
|
}
|
|
766
|
+
/** Space kept between inner elements and an actor's boundary (piStar's `updateBoundary` adds 10px). */
|
|
767
|
+
const ACTOR_PADDING = 10;
|
|
768
|
+
/** A kind's default size, absent any per-host override (see `actorBounds`' `defaultSizeOf`). */
|
|
769
|
+
function metamodelSizeOf(metamodel, kind) {
|
|
770
|
+
return metamodel.elements.get(kind)?.size ?? {
|
|
771
|
+
width: 0,
|
|
772
|
+
height: 0
|
|
773
|
+
};
|
|
774
|
+
}
|
|
775
|
+
/**
|
|
776
|
+
* An actor's boundary: the kind's default-size rectangle at the actor's position, grown to
|
|
777
|
+
* include every inner element (each padded by `ACTOR_PADDING`), like piStar's `updateBoundary`
|
|
778
|
+
* (which floors on the kind's default size, not the actor's last expanded `display` size; an
|
|
779
|
+
* inner element's own `display` size does override, same as its rendered size elsewhere).
|
|
780
|
+
* Shared by `@istar-ts/react`'s node layout and `@istar-ts/glsp`'s GModel, so an actor draws the
|
|
781
|
+
* same box in both: children are looked up by category (`metamodelOf`), not `istar.*` names.
|
|
782
|
+
*
|
|
783
|
+
* `defaultSizeOf` resolves a kind's default size; it defaults to the metamodel's, but a host
|
|
784
|
+
* whose registry overrides a kind's size independently of the metamodel (`@istar-ts/react`'s
|
|
785
|
+
* `IstarRegistry`) must pass one that reads its own sizes, or its boundary would stop matching
|
|
786
|
+
* what it actually draws.
|
|
787
|
+
*/
|
|
788
|
+
function actorBounds(model, actorId, metamodel = metamodelOf(model), defaultSizeOf = (kind) => metamodelSizeOf(metamodel, kind)) {
|
|
789
|
+
const actor = model.elements.get(actorId);
|
|
790
|
+
if (!actor) throw new Error(`no element "${actorId}" in the model`);
|
|
791
|
+
const meta = metamodel;
|
|
792
|
+
const ownSize = defaultSizeOf(actor.kind);
|
|
793
|
+
let minX = actor.x;
|
|
794
|
+
let minY = actor.y;
|
|
795
|
+
let maxX = actor.x + ownSize.width;
|
|
796
|
+
let maxY = actor.y + ownSize.height;
|
|
797
|
+
for (const child of model.elements.values()) {
|
|
798
|
+
if (child.parent !== actorId) continue;
|
|
799
|
+
if (meta.elements.get(child.kind)?.category === "actor") continue;
|
|
800
|
+
const base = defaultSizeOf(child.kind);
|
|
801
|
+
const width = child.display?.width ?? base.width;
|
|
802
|
+
const height = child.display?.height ?? base.height;
|
|
803
|
+
minX = Math.min(minX, child.x - 10);
|
|
804
|
+
minY = Math.min(minY, child.y - 10);
|
|
805
|
+
maxX = Math.max(maxX, child.x + width + 10);
|
|
806
|
+
maxY = Math.max(maxY, child.y + height + 10);
|
|
807
|
+
}
|
|
808
|
+
return {
|
|
809
|
+
x: minX,
|
|
810
|
+
y: minY,
|
|
811
|
+
width: maxX - minX,
|
|
812
|
+
height: maxY - minY
|
|
813
|
+
};
|
|
814
|
+
}
|
|
815
|
+
/** Space kept between a suggested box and any existing element (`suggestPosition`). */
|
|
816
|
+
const SUGGEST_MARGIN = 20;
|
|
817
|
+
/** Step between candidate positions on the grid `suggestPosition` scans. */
|
|
818
|
+
const SUGGEST_STEP = 40;
|
|
819
|
+
/** How many rings out `suggestPosition` scans before falling back to `guaranteedFreePoint`. */
|
|
820
|
+
const SUGGEST_MAX_RING = 25;
|
|
821
|
+
function boxesOverlap(a, b) {
|
|
822
|
+
return a.x < b.x + b.width && a.x + a.width > b.x && a.y < b.y + b.height && a.y + a.height > b.y;
|
|
823
|
+
}
|
|
824
|
+
function padded(box, margin) {
|
|
825
|
+
return {
|
|
826
|
+
x: box.x - margin,
|
|
827
|
+
y: box.y - margin,
|
|
828
|
+
width: box.width + margin * 2,
|
|
829
|
+
height: box.height + margin * 2
|
|
830
|
+
};
|
|
831
|
+
}
|
|
832
|
+
function firstFreeCandidate(candidates, size, obstacles, fallback) {
|
|
833
|
+
for (const point of candidates) {
|
|
834
|
+
const box = {
|
|
835
|
+
x: point.x,
|
|
836
|
+
y: point.y,
|
|
837
|
+
width: size.width,
|
|
838
|
+
height: size.height
|
|
839
|
+
};
|
|
840
|
+
if (!obstacles.some((obstacle) => boxesOverlap(padded(box, 20), obstacle))) return point;
|
|
841
|
+
}
|
|
842
|
+
return fallback;
|
|
843
|
+
}
|
|
844
|
+
/**
|
|
845
|
+
* A point guaranteed to overlap no obstacle, however dense the model: past the right edge of
|
|
846
|
+
* every obstacle's box, so no obstacle can reach it regardless of its y (`suggestPosition`'s
|
|
847
|
+
* last-resort fallback, once every ring candidate is taken).
|
|
848
|
+
*/
|
|
849
|
+
function guaranteedFreePoint(obstacles, referenceY) {
|
|
850
|
+
if (obstacles.length === 0) return {
|
|
851
|
+
x: 0,
|
|
852
|
+
y: referenceY
|
|
853
|
+
};
|
|
854
|
+
return {
|
|
855
|
+
x: Math.max(...obstacles.map((box) => box.x + box.width)) + 20,
|
|
856
|
+
y: referenceY
|
|
857
|
+
};
|
|
858
|
+
}
|
|
859
|
+
/** Candidate positions in expanding square rings around `center`, in a fixed scan order. */
|
|
860
|
+
function ringCandidates(center, maxRing) {
|
|
861
|
+
const points = [center];
|
|
862
|
+
for (let ring = 1; ring <= maxRing; ring++) {
|
|
863
|
+
const offset = ring * SUGGEST_STEP;
|
|
864
|
+
for (let dx = -offset; dx <= offset; dx += SUGGEST_STEP) {
|
|
865
|
+
points.push({
|
|
866
|
+
x: center.x + dx,
|
|
867
|
+
y: center.y - offset
|
|
868
|
+
});
|
|
869
|
+
points.push({
|
|
870
|
+
x: center.x + dx,
|
|
871
|
+
y: center.y + offset
|
|
872
|
+
});
|
|
873
|
+
}
|
|
874
|
+
for (let dy = -offset + SUGGEST_STEP; dy <= offset - SUGGEST_STEP; dy += SUGGEST_STEP) {
|
|
875
|
+
points.push({
|
|
876
|
+
x: center.x - offset,
|
|
877
|
+
y: center.y + dy
|
|
878
|
+
});
|
|
879
|
+
points.push({
|
|
880
|
+
x: center.x + offset,
|
|
881
|
+
y: center.y + dy
|
|
882
|
+
});
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
return points;
|
|
886
|
+
}
|
|
887
|
+
function modelBoxes(model, defaultSizeOf) {
|
|
888
|
+
const boxes = [];
|
|
889
|
+
for (const element of model.elements.values()) {
|
|
890
|
+
const base = defaultSizeOf(element.kind);
|
|
891
|
+
const width = element.display?.width ?? base.width;
|
|
892
|
+
const height = element.display?.height ?? base.height;
|
|
893
|
+
boxes.push({
|
|
894
|
+
x: element.x,
|
|
895
|
+
y: element.y,
|
|
896
|
+
width,
|
|
897
|
+
height
|
|
898
|
+
});
|
|
899
|
+
}
|
|
900
|
+
return boxes;
|
|
901
|
+
}
|
|
902
|
+
/**
|
|
903
|
+
* A free spot for a new element of `kind`, overlapping no existing element (sizes from the
|
|
904
|
+
* metamodel, or `defaultSizeOf` for a host with its own size overrides, as in `actorBounds`).
|
|
905
|
+
*
|
|
906
|
+
* Scans a deterministic, fixed-order set of candidates — rings around `near` when given, else
|
|
907
|
+
* the container's interior, else rings around the origin — and returns the first whose padded
|
|
908
|
+
* box (`SUGGEST_MARGIN`) overlaps nothing; same input always yields the same output. However
|
|
909
|
+
* dense the model, the result never overlaps: once every ring candidate is taken, it falls back
|
|
910
|
+
* to a point past the right edge of every obstacle (`guaranteedFreePoint`).
|
|
911
|
+
*
|
|
912
|
+
* Inside `containerId`, the candidate stays within the actor's current boundary (`actorBounds`)
|
|
913
|
+
* when there is room, or goes just past its last child when the boundary is full — the boundary
|
|
914
|
+
* grows from there, same as any other inner element (`actorBounds`).
|
|
915
|
+
*/
|
|
916
|
+
function suggestPosition(model, options) {
|
|
917
|
+
const metamodel = options.metamodel ?? metamodelOf(model);
|
|
918
|
+
const defaultSizeOf = options.defaultSizeOf ?? ((kind) => metamodelSizeOf(metamodel, kind));
|
|
919
|
+
const size = defaultSizeOf(options.kind);
|
|
920
|
+
const obstacles = modelBoxes(model, defaultSizeOf);
|
|
921
|
+
const near = typeof options.near === "string" ? model.elements.get(options.near) : options.near;
|
|
922
|
+
const nearPoint = near ? "kind" in near ? {
|
|
923
|
+
x: near.x,
|
|
924
|
+
y: near.y
|
|
925
|
+
} : near : void 0;
|
|
926
|
+
if (options.containerId) {
|
|
927
|
+
const bounds = actorBounds(model, options.containerId, metamodel, defaultSizeOf);
|
|
928
|
+
const candidates = ringCandidates(nearPoint ?? {
|
|
929
|
+
x: bounds.x + 10,
|
|
930
|
+
y: bounds.y + 10
|
|
931
|
+
}, SUGGEST_MAX_RING).filter((point) => point.x >= bounds.x + 10 && point.y >= bounds.y + 10 && point.x + size.width <= bounds.x + bounds.width - 10 && point.y + size.height <= bounds.y + bounds.height - 10);
|
|
932
|
+
if (candidates.length > 0) {
|
|
933
|
+
const sentinel = {
|
|
934
|
+
x: NaN,
|
|
935
|
+
y: NaN
|
|
936
|
+
};
|
|
937
|
+
const found = firstFreeCandidate(candidates, size, obstacles, sentinel);
|
|
938
|
+
if (found !== sentinel) return found;
|
|
939
|
+
}
|
|
940
|
+
const pastLastChild = {
|
|
941
|
+
x: bounds.x + bounds.width + 10,
|
|
942
|
+
y: bounds.y + 10
|
|
943
|
+
};
|
|
944
|
+
return firstFreeCandidate(ringCandidates(pastLastChild, SUGGEST_MAX_RING), size, obstacles, guaranteedFreePoint(obstacles, pastLastChild.y));
|
|
945
|
+
}
|
|
946
|
+
const start = nearPoint ?? (obstacles.length > 0 ? {
|
|
947
|
+
x: Math.max(...obstacles.map((box) => box.x + box.width)) + 20,
|
|
948
|
+
y: 0
|
|
949
|
+
} : {
|
|
950
|
+
x: 0,
|
|
951
|
+
y: 0
|
|
952
|
+
});
|
|
953
|
+
return firstFreeCandidate(ringCandidates(start, SUGGEST_MAX_RING), size, obstacles, guaranteedFreePoint(obstacles, start.y));
|
|
954
|
+
}
|
|
766
955
|
//#endregion
|
|
767
956
|
//#region src/constraints.ts
|
|
768
957
|
const OK = { ok: true };
|
|
769
|
-
function fail$1(code, reason) {
|
|
958
|
+
function fail$1(code, reason, end) {
|
|
770
959
|
return {
|
|
771
960
|
ok: false,
|
|
772
961
|
code,
|
|
773
|
-
reason
|
|
962
|
+
reason,
|
|
963
|
+
end
|
|
774
964
|
};
|
|
775
965
|
}
|
|
776
966
|
/**
|
|
@@ -800,8 +990,8 @@ function canLink(model, source, target, kind, options = {}) {
|
|
|
800
990
|
const metamodel = options.metamodel ?? metamodelOf(model);
|
|
801
991
|
const s = resolve(any, source);
|
|
802
992
|
const t = resolve(any, target) ?? any.links.get(refId(target));
|
|
803
|
-
if (!s) return fail$1("unknown-element", `unknown source element "${refId(source)}"
|
|
804
|
-
if (!t) return fail$1("unknown-element", `unknown target element "${refId(target)}"
|
|
993
|
+
if (!s) return fail$1("unknown-element", `unknown source element "${refId(source)}"`, "source");
|
|
994
|
+
if (!t) return fail$1("unknown-element", `unknown target element "${refId(target)}"`, "target");
|
|
805
995
|
let definition = metamodel.links.get(kind);
|
|
806
996
|
if (!definition) return fail$1("unknown-link-kind", `unknown link kind "${String(kind)}"`);
|
|
807
997
|
if (definition.parts && !isLinkRef(t) && metamodel.elements.get(t.kind)?.of === definition.kind) definition = metamodel.links.get(definition.parts.leg) ?? definition;
|
|
@@ -852,7 +1042,7 @@ function hubCheck(graph, definition, source, target) {
|
|
|
852
1042
|
}
|
|
853
1043
|
/** The built-in (iStar 2.0) rules only know element targets. */
|
|
854
1044
|
function elementTargetOnly(definition) {
|
|
855
|
-
return fail$1("invalid-target", `the target of ${/^[aeiou]/i.test(definition.label) ? "an" : "a"} ${definition.label} link must be an element, not a link
|
|
1045
|
+
return fail$1("invalid-target", `the target of ${/^[aeiou]/i.test(definition.label) ? "an" : "a"} ${definition.label} link must be an element, not a link`, "target");
|
|
856
1046
|
}
|
|
857
1047
|
function refId(ref) {
|
|
858
1048
|
return typeof ref === "string" ? ref : ref.id;
|
|
@@ -928,16 +1118,16 @@ const is = (graph, element, ...shortNames) => {
|
|
|
928
1118
|
};
|
|
929
1119
|
const isDependum = (element) => element.isDependum === true;
|
|
930
1120
|
const isALink = (graph, source, target) => {
|
|
931
|
-
if (!is(graph, source, "Actor", "Role")) return fail$1("invalid-source", "the source of Is-A links must be a Role or a general Actor (iStar 2.0 Guide, Page 6).");
|
|
1121
|
+
if (!is(graph, source, "Actor", "Role")) return fail$1("invalid-source", "the source of Is-A links must be a Role or a general Actor (iStar 2.0 Guide, Page 6).", "source");
|
|
932
1122
|
if (source.kind !== target.kind) return fail$1("actor-types-differ", "the source and target of Is-A links must be of the same type - Actor and Actor, or Role and Role (iStar 2.0 Guide, Page 6).");
|
|
933
|
-
if (!is(graph, target, "Actor", "Role")) return fail$1("invalid-target", "the target of Is-A links must be a Role or a general Actor (iStar 2.0 Guide, Page 6).");
|
|
1123
|
+
if (!is(graph, target, "Actor", "Role")) return fail$1("invalid-target", "the target of Is-A links must be a Role or a general Actor (iStar 2.0 Guide, Page 6).", "target");
|
|
934
1124
|
if (source.id === target.id) return fail$1("self-link", "you cannot make Is-A links from an actor onto itself.");
|
|
935
1125
|
if (graph.isThereLinkBetween(source, target)) return fail$1("duplicate-link", "there can only be one Actor link between the same two actors (iStar 2.0 Guide, Page 14).");
|
|
936
1126
|
return OK;
|
|
937
1127
|
};
|
|
938
1128
|
const participatesInLink = (graph, source, target) => {
|
|
939
|
-
if (!graph.isActor(source)) return fail$1("invalid-source", "the source of a Participates-In link must be some kind of actor (iStar 2.0 Guide, Page 6)");
|
|
940
|
-
if (!graph.isActor(target)) return fail$1("invalid-target", "the target of a Participates-In link must be some kind of actor (iStar 2.0 Guide, Page 6)");
|
|
1129
|
+
if (!graph.isActor(source)) return fail$1("invalid-source", "the source of a Participates-In link must be some kind of actor (iStar 2.0 Guide, Page 6)", "source");
|
|
1130
|
+
if (!graph.isActor(target)) return fail$1("invalid-target", "the target of a Participates-In link must be some kind of actor (iStar 2.0 Guide, Page 6)", "target");
|
|
941
1131
|
if (source.id === target.id) return fail$1("self-link", "you cannot make a Participates-In link from an actor onto itself.");
|
|
942
1132
|
if (graph.isThereLinkBetween(source, target)) return fail$1("duplicate-link", "there can only be one Actor link between the same two actors (iStar 2.0 Guide, Page 14).");
|
|
943
1133
|
return OK;
|
|
@@ -948,30 +1138,30 @@ function owningActorId(graph, element) {
|
|
|
948
1138
|
}
|
|
949
1139
|
const dependencyLink = (graph, source, target) => {
|
|
950
1140
|
if (source.id === target.id) return fail$1("self-link", "a Dependency link cannot link an element onto itself");
|
|
951
|
-
if (isDependum(source)) return fail$1("dependum-endpoint", "a Dependency link cannot start from a dependum");
|
|
952
|
-
if (isDependum(target)) return fail$1("dependum-endpoint", "a Dependency link cannot end in a dependum");
|
|
1141
|
+
if (isDependum(source)) return fail$1("dependum-endpoint", "a Dependency link cannot start from a dependum", "source");
|
|
1142
|
+
if (isDependum(target)) return fail$1("dependum-endpoint", "a Dependency link cannot end in a dependum", "target");
|
|
953
1143
|
if (owningActorId(graph, source) === owningActorId(graph, target)) return fail$1("same-actor", "a Dependency link must involve two different actors (iStar 2.0 Guide, Page 14)");
|
|
954
|
-
if (graph.isTargetOfType(source, "istar.OrRefinementLink") || graph.isTargetOfType(source, "istar.AndRefinementLink")) return fail$1("refined-depender", "a refined element cannot be the Depender Element in a Dependency link (iStar 2.0 Guide, Page 14). Instead, you can try to add the Dependency originating from a child.");
|
|
955
|
-
if (graph.isTargetOfType(source, "istar.ContributionLink")) return fail$1("contributed-depender", "a contributed element cannot be the Depender Element in a Dependency link (iStar 2.0 Guide, Page 14). Instead, you can try to add the Dependency originating from a child.");
|
|
1144
|
+
if (graph.isTargetOfType(source, "istar.OrRefinementLink") || graph.isTargetOfType(source, "istar.AndRefinementLink")) return fail$1("refined-depender", "a refined element cannot be the Depender Element in a Dependency link (iStar 2.0 Guide, Page 14). Instead, you can try to add the Dependency originating from a child.", "source");
|
|
1145
|
+
if (graph.isTargetOfType(source, "istar.ContributionLink")) return fail$1("contributed-depender", "a contributed element cannot be the Depender Element in a Dependency link (iStar 2.0 Guide, Page 14). Instead, you can try to add the Dependency originating from a child.", "source");
|
|
956
1146
|
return OK;
|
|
957
1147
|
};
|
|
958
1148
|
function refinementLink(label) {
|
|
959
1149
|
const other = label === "AND" ? "istar.OrRefinementLink" : "istar.AndRefinementLink";
|
|
960
1150
|
return (graph, source, target) => {
|
|
961
|
-
if (!is(graph, source, "Task", "Goal")) return fail$1("invalid-source", `the source of an ${label}-refinement link must be a Goal or a Task (iStar 2.0 Guide, Table 1)
|
|
962
|
-
if (!is(graph, target, "Task", "Goal")) return fail$1("invalid-target", `the target of an ${label}-refinement link must be a Goal or a Task (iStar 2.0 Guide, Table 1)
|
|
1151
|
+
if (!is(graph, source, "Task", "Goal")) return fail$1("invalid-source", `the source of an ${label}-refinement link must be a Goal or a Task (iStar 2.0 Guide, Table 1)`, "source");
|
|
1152
|
+
if (!is(graph, target, "Task", "Goal")) return fail$1("invalid-target", `the target of an ${label}-refinement link must be a Goal or a Task (iStar 2.0 Guide, Table 1)`, "target");
|
|
963
1153
|
if (source.id === target.id) return fail$1("self-link", `you cannot make an ${label}-refinement link from an element onto itself`);
|
|
964
1154
|
if (isDependum(source) || isDependum(target)) return fail$1("dependum-endpoint", `you cannot make an ${label}-refinement link with a dependum (iStar 2.0 Guide, Page 14)`);
|
|
965
1155
|
if (source.parent !== target.parent) return fail$1("different-actors", `the source and target of an ${label}-refinement link must pertain to the same actor (iStar 2.0 Guide, Page 14)`);
|
|
966
1156
|
if (graph.isThereLinkBetween(source, target)) return fail$1("duplicate-link", "there can only be one refinement link between the same two elements");
|
|
967
|
-
if (graph.isSourceOfType(target, "istar.DependencyLink")) return fail$1("depender-target", "you cannot refine a Depender Element; that is, an element that is the source of a Dependency (iStar 2.0 Guide, Page 14). Instead, you can try to move the dependency to the sub-element.");
|
|
968
|
-
if (graph.isTargetOfType(target, other)) return fail$1("mixed-refinement", label === "AND" ? "you cannot mix AND-refinements with OR-refinements targeting the same element (iStar 2.0 Guide, Page 10)." : "you cannot mix OR-refinements with AND-refinements targeting the same element (iStar 2.0 Guide, Page 10).");
|
|
1157
|
+
if (graph.isSourceOfType(target, "istar.DependencyLink")) return fail$1("depender-target", "you cannot refine a Depender Element; that is, an element that is the source of a Dependency (iStar 2.0 Guide, Page 14). Instead, you can try to move the dependency to the sub-element.", "target");
|
|
1158
|
+
if (graph.isTargetOfType(target, other)) return fail$1("mixed-refinement", label === "AND" ? "you cannot mix AND-refinements with OR-refinements targeting the same element (iStar 2.0 Guide, Page 10)." : "you cannot mix OR-refinements with AND-refinements targeting the same element (iStar 2.0 Guide, Page 10).", "target");
|
|
969
1159
|
return OK;
|
|
970
1160
|
};
|
|
971
1161
|
}
|
|
972
1162
|
const neededByLink = (graph, source, target) => {
|
|
973
|
-
if (!is(graph, source, "Resource")) return fail$1("invalid-source", "the source of a Needed-By link must be a Resource (iStar 2.0 Guide, Table 1)");
|
|
974
|
-
if (!is(graph, target, "Task")) return fail$1("invalid-target", "the target of a Needed-By link must be a Task (iStar 2.0 Guide, Table 1)");
|
|
1163
|
+
if (!is(graph, source, "Resource")) return fail$1("invalid-source", "the source of a Needed-By link must be a Resource (iStar 2.0 Guide, Table 1)", "source");
|
|
1164
|
+
if (!is(graph, target, "Task")) return fail$1("invalid-target", "the target of a Needed-By link must be a Task (iStar 2.0 Guide, Table 1)", "target");
|
|
975
1165
|
if (source.id === target.id) return fail$1("self-link", "you cannot make a Needed-By link from an element onto itself");
|
|
976
1166
|
if (isDependum(source) || isDependum(target)) return fail$1("dependum-endpoint", "you cannot make a Needed-By link with a dependum (iStar 2.0 Guide, Page 14)");
|
|
977
1167
|
if (source.parent !== target.parent) return fail$1("different-actors", "the source and target of a Needed-By link must pertain to the same actor (iStar 2.0 Guide, Page 14)");
|
|
@@ -979,19 +1169,19 @@ const neededByLink = (graph, source, target) => {
|
|
|
979
1169
|
return OK;
|
|
980
1170
|
};
|
|
981
1171
|
const contributionLink = (graph, source, target) => {
|
|
982
|
-
if (!is(graph, source, "Goal", "Quality", "Task", "Resource")) return fail$1("invalid-source", "the source of a Contribution link must be a Goal, a Quality, a Task or a Resource (iStar 2.0 Guide, Table 1)");
|
|
983
|
-
if (!is(graph, target, "Quality")) return fail$1("invalid-target", "the target of a Contribution link must be a Quality (iStar 2.0 Guide, Table 1)");
|
|
1172
|
+
if (!is(graph, source, "Goal", "Quality", "Task", "Resource")) return fail$1("invalid-source", "the source of a Contribution link must be a Goal, a Quality, a Task or a Resource (iStar 2.0 Guide, Table 1)", "source");
|
|
1173
|
+
if (!is(graph, target, "Quality")) return fail$1("invalid-target", "the target of a Contribution link must be a Quality (iStar 2.0 Guide, Table 1)", "target");
|
|
984
1174
|
if (source.id === target.id) return fail$1("self-link", "you cannot make a Contribution link from an element onto itself (iStar 2.0 Guide, Page 15)");
|
|
985
1175
|
if (isDependum(source) || isDependum(target)) return fail$1("dependum-endpoint", "you cannot make a Contribution link with a dependum (iStar 2.0 Guide, Page 14)");
|
|
986
1176
|
if (source.parent !== target.parent) return fail$1("different-actors", "the source and target of a Contribution link must pertain to the same actor (iStar 2.0 Guide, Page 14)");
|
|
987
1177
|
if (graph.isThereLinkBetween(source, target, "istar.ContributionLink")) return fail$1("duplicate-link", "there can only be one Contribution link between the same two elements");
|
|
988
1178
|
if (graph.isThereLinkBetween(source, target, "istar.QualificationLink")) return fail$1("contribution-and-qualification", "you cannot have Contribution and Qualification links between the same two elements (iStar 2.0 Guide, Page 15)");
|
|
989
|
-
if (graph.isSourceOfType(target, "istar.DependencyLink")) return fail$1("depender-target", "you cannot contribute to a Depender Element; that is, an element that is the source of a Dependency (iStar 2.0 Guide, Page 14). Instead, you can try to move the dependency to the sub-quality.");
|
|
1179
|
+
if (graph.isSourceOfType(target, "istar.DependencyLink")) return fail$1("depender-target", "you cannot contribute to a Depender Element; that is, an element that is the source of a Dependency (iStar 2.0 Guide, Page 14). Instead, you can try to move the dependency to the sub-quality.", "target");
|
|
990
1180
|
return OK;
|
|
991
1181
|
};
|
|
992
1182
|
const qualificationLink = (graph, source, target) => {
|
|
993
|
-
if (!is(graph, source, "Quality")) return fail$1("invalid-source", "the source of a Qualification link must be a Quality (iStar 2.0 Guide, Table 1)");
|
|
994
|
-
if (!is(graph, target, "Goal", "Task", "Resource")) return fail$1("invalid-target", "the target of a Qualification link must be a Goal, a Task or a Resource (iStar 2.0 Guide, Table 1)");
|
|
1183
|
+
if (!is(graph, source, "Quality")) return fail$1("invalid-source", "the source of a Qualification link must be a Quality (iStar 2.0 Guide, Table 1)", "source");
|
|
1184
|
+
if (!is(graph, target, "Goal", "Task", "Resource")) return fail$1("invalid-target", "the target of a Qualification link must be a Goal, a Task or a Resource (iStar 2.0 Guide, Table 1)", "target");
|
|
995
1185
|
if (source.id === target.id) return fail$1("self-link", "you cannot make a Qualification link from an element onto itself");
|
|
996
1186
|
if (isDependum(source) || isDependum(target)) return fail$1("dependum-endpoint", "you cannot make a Qualification link with a dependum (iStar 2.0 Guide, Page 14)");
|
|
997
1187
|
if (source.parent !== target.parent) return fail$1("different-actors", "the source and target of a Qualification link must pertain to the same actor (iStar 2.0 Guide, Page 14)");
|
|
@@ -1031,12 +1221,12 @@ function matchesSelector(graph, element, selector) {
|
|
|
1031
1221
|
function declarativeCheck(graph, definition, rules, rulesKind, source, target) {
|
|
1032
1222
|
const name = definition.label;
|
|
1033
1223
|
const article = /^[aeiou]/i.test(name) ? "an" : "a";
|
|
1034
|
-
if (!rules.sources.some((selector) => matchesSelector(graph, source, selector))) return fail$1("invalid-source", `the source of ${article} ${name} link must be ${describe(graph, rules.sources)}
|
|
1224
|
+
if (!rules.sources.some((selector) => matchesSelector(graph, source, selector))) return fail$1("invalid-source", `the source of ${article} ${name} link must be ${describe(graph, rules.sources)}`, "source");
|
|
1035
1225
|
if (!rules.targets.some((selector) => matchesSelector(graph, target, selector))) {
|
|
1036
1226
|
const targetKind = isLinkRef(target) ? void 0 : graph.metamodel.elements.get(target.kind);
|
|
1037
1227
|
const hubOf = targetKind?.role === "hub" && targetKind.of !== void 0 ? graph.metamodel.links.get(targetKind.of) : void 0;
|
|
1038
|
-
if (hubOf) return fail$1("hub-target", `you cannot make ${article} ${name} link towards the hub of ${/^[aeiou]/i.test(hubOf.label) ? "an" : "a"} ${hubOf.label} link
|
|
1039
|
-
return fail$1("invalid-target", `the target of ${article} ${name} link must be ${describe(graph, rules.targets)}
|
|
1228
|
+
if (hubOf) return fail$1("hub-target", `you cannot make ${article} ${name} link towards the hub of ${/^[aeiou]/i.test(hubOf.label) ? "an" : "a"} ${hubOf.label} link`, "target");
|
|
1229
|
+
return fail$1("invalid-target", `the target of ${article} ${name} link must be ${describe(graph, rules.targets)}`, "target");
|
|
1040
1230
|
}
|
|
1041
1231
|
if (!rules.allowSelf && source.id === target.id) return fail$1("self-link", `you cannot make ${article} ${name} link from an element onto itself`);
|
|
1042
1232
|
if (definition.category === "node" && !isLinkRef(target)) {
|
|
@@ -1791,6 +1981,20 @@ function withFileMetamodel(model, block) {
|
|
|
1791
1981
|
//#region src/operations.ts
|
|
1792
1982
|
var ModelOperationError = class extends Error {
|
|
1793
1983
|
name = "ModelOperationError";
|
|
1984
|
+
/** The element or link the error is about, when the operation named one. */
|
|
1985
|
+
elementId;
|
|
1986
|
+
constructor(message, elementId) {
|
|
1987
|
+
super(message);
|
|
1988
|
+
this.elementId = elementId;
|
|
1989
|
+
}
|
|
1990
|
+
/** As a `GoalDiagnostic`, anchored on `elementId` (empty string if the error names none). */
|
|
1991
|
+
toDiagnostic() {
|
|
1992
|
+
return {
|
|
1993
|
+
elementId: this.elementId ?? "",
|
|
1994
|
+
severity: "error",
|
|
1995
|
+
message: this.message
|
|
1996
|
+
};
|
|
1997
|
+
}
|
|
1794
1998
|
};
|
|
1795
1999
|
const defaultIdGenerator = () => {
|
|
1796
2000
|
const c = globalThis.crypto;
|
|
@@ -1820,12 +2024,12 @@ function derive(from, changes) {
|
|
|
1820
2024
|
}
|
|
1821
2025
|
function requireElement(model, id) {
|
|
1822
2026
|
const element = model.elements.get(id);
|
|
1823
|
-
if (!element) throw new ModelOperationError(`unknown element "${id}"
|
|
2027
|
+
if (!element) throw new ModelOperationError(`unknown element "${id}"`, id);
|
|
1824
2028
|
return element;
|
|
1825
2029
|
}
|
|
1826
2030
|
function requireLink(model, id) {
|
|
1827
2031
|
const link = model.links.get(id);
|
|
1828
|
-
if (!link) throw new ModelOperationError(`unknown link "${id}"
|
|
2032
|
+
if (!link) throw new ModelOperationError(`unknown link "${id}"`, id);
|
|
1829
2033
|
return link;
|
|
1830
2034
|
}
|
|
1831
2035
|
function withoutUndefined(value) {
|
|
@@ -1839,10 +2043,10 @@ function addElement(model, input, ctx = {}) {
|
|
|
1839
2043
|
const definition = metamodel.elements.get(input.kind);
|
|
1840
2044
|
if (!definition) throw new ModelOperationError(`unknown element kind "${input.kind}" in ${metamodel.name}`);
|
|
1841
2045
|
const id = input.id ?? (ctx.createId ?? defaultIdGenerator)();
|
|
1842
|
-
if (m.elements.has(id) || m.links.has(id)) throw new ModelOperationError(`id "${id}" is already in use
|
|
2046
|
+
if (m.elements.has(id) || m.links.has(id)) throw new ModelOperationError(`id "${id}" is already in use`, id);
|
|
1843
2047
|
if (input.parent !== void 0) {
|
|
1844
2048
|
if (definition.category === "actor") throw new ModelOperationError("actors cannot be nested");
|
|
1845
|
-
if (!isActorIn$1(m, requireElement(m, input.parent).kind)) throw new ModelOperationError(`parent "${input.parent}" is not an actor
|
|
2049
|
+
if (!isActorIn$1(m, requireElement(m, input.parent).kind)) throw new ModelOperationError(`parent "${input.parent}" is not an actor`, input.parent);
|
|
1846
2050
|
}
|
|
1847
2051
|
const element = withoutUndefined({
|
|
1848
2052
|
id,
|
|
@@ -1911,10 +2115,10 @@ function moveElement(model, id, x, y) {
|
|
|
1911
2115
|
function nestElement(model, id, parent) {
|
|
1912
2116
|
const m = any(model);
|
|
1913
2117
|
const current = requireElement(m, id);
|
|
1914
|
-
if (isActorIn$1(m, current.kind)) throw new ModelOperationError("actors cannot be nested");
|
|
1915
|
-
if (current.isDependum) throw new ModelOperationError("a dependum cannot be nested");
|
|
2118
|
+
if (isActorIn$1(m, current.kind)) throw new ModelOperationError("actors cannot be nested", id);
|
|
2119
|
+
if (current.isDependum) throw new ModelOperationError("a dependum cannot be nested", id);
|
|
1916
2120
|
if ((current.parent ?? null) === parent) return model;
|
|
1917
|
-
if (parent !== null && !isActorIn$1(m, requireElement(m, parent).kind)) throw new ModelOperationError(`parent "${parent}" is not an actor
|
|
2121
|
+
if (parent !== null && !isActorIn$1(m, requireElement(m, parent).kind)) throw new ModelOperationError(`parent "${parent}" is not an actor`, parent);
|
|
1918
2122
|
const elements = new Map(m.elements);
|
|
1919
2123
|
elements.delete(id);
|
|
1920
2124
|
const { parent: _old, ...rest } = current;
|
|
@@ -1992,12 +2196,27 @@ function removeCascade(model, elementIds, linkIds) {
|
|
|
1992
2196
|
});
|
|
1993
2197
|
}
|
|
1994
2198
|
/**
|
|
2199
|
+
* Maps a failing `connect` result to a `GoalDiagnostic`, anchored on the end named by the
|
|
2200
|
+
* `LinkCheck`'s `end` field (`target` when a check doesn't single out one end, such as
|
|
2201
|
+
* `self-link` or `actor-types-differ`). `undefined` for a successful result.
|
|
2202
|
+
*/
|
|
2203
|
+
function connectResultToDiagnostic(result, endpoints) {
|
|
2204
|
+
if (result.ok) return void 0;
|
|
2205
|
+
return {
|
|
2206
|
+
elementId: (result.end ?? "target") === "source" ? endpoints.source : endpoints.target,
|
|
2207
|
+
severity: "error",
|
|
2208
|
+
message: result.reason,
|
|
2209
|
+
code: result.code
|
|
2210
|
+
};
|
|
2211
|
+
}
|
|
2212
|
+
/**
|
|
1995
2213
|
* Adds a link between two elements if the iStar constraints allow it.
|
|
1996
2214
|
*
|
|
1997
2215
|
* With an n-ary kind (`arity: 'n'`), a `target` that is one of the kind's hubs gets a new leg
|
|
1998
|
-
* from `source` (see `addLeg`).
|
|
1999
|
-
* target
|
|
2000
|
-
*
|
|
2216
|
+
* from `source` (see `addLeg`), taking `input.id` or `input.legId` (default a fresh id) as the
|
|
2217
|
+
* leg's id. Any other target gets a new hub, centred between source and target, with a leg from
|
|
2218
|
+
* `source` and an end to `target`. `input.id` and `customProperties` then go to the hub, `label`
|
|
2219
|
+
* and `name` to the end, and `legId`/`endId` (default fresh ids) to the leg and end.
|
|
2001
2220
|
*/
|
|
2002
2221
|
function connect(model, input, options = {}) {
|
|
2003
2222
|
const m = any(model);
|
|
@@ -2026,7 +2245,7 @@ function connect(model, input, options = {}) {
|
|
|
2026
2245
|
if (!m.links.has(target)) requireElement(m, target);
|
|
2027
2246
|
}
|
|
2028
2247
|
const id = input.id ?? (options.createId ?? defaultIdGenerator)();
|
|
2029
|
-
if (m.elements.has(id) || m.links.has(id)) throw new ModelOperationError(`id "${id}" is already in use
|
|
2248
|
+
if (m.elements.has(id) || m.links.has(id)) throw new ModelOperationError(`id "${id}" is already in use`, id);
|
|
2030
2249
|
const link = withoutUndefined({
|
|
2031
2250
|
id,
|
|
2032
2251
|
kind,
|
|
@@ -2047,7 +2266,13 @@ function connectHub(m, definition, input, options) {
|
|
|
2047
2266
|
const metamodel = metaOf(m);
|
|
2048
2267
|
const parts = definition.parts;
|
|
2049
2268
|
const { source, target } = input;
|
|
2050
|
-
if (m.elements.get(target)?.kind === parts.hub)
|
|
2269
|
+
if (m.elements.get(target)?.kind === parts.hub) {
|
|
2270
|
+
const legId = input.id ?? input.legId;
|
|
2271
|
+
return addLeg(typed(m), target, source, {
|
|
2272
|
+
...options,
|
|
2273
|
+
...legId === void 0 ? {} : { id: legId }
|
|
2274
|
+
});
|
|
2275
|
+
}
|
|
2051
2276
|
if (!options.force) {
|
|
2052
2277
|
const check = canLink(m, source, target, definition.kind);
|
|
2053
2278
|
if (!check.ok) return check;
|
|
@@ -2056,8 +2281,8 @@ function connectHub(m, definition, input, options) {
|
|
|
2056
2281
|
const to = requireElement(m, target);
|
|
2057
2282
|
const createId = options.createId ?? defaultIdGenerator;
|
|
2058
2283
|
const hubId = input.id ?? createId();
|
|
2059
|
-
const legId = createId();
|
|
2060
|
-
const endId = createId();
|
|
2284
|
+
const legId = input.legId ?? createId();
|
|
2285
|
+
const endId = input.endId ?? createId();
|
|
2061
2286
|
for (const [i, id] of [
|
|
2062
2287
|
hubId,
|
|
2063
2288
|
legId,
|
|
@@ -2066,7 +2291,7 @@ function connectHub(m, definition, input, options) {
|
|
|
2066
2291
|
hubId,
|
|
2067
2292
|
legId,
|
|
2068
2293
|
endId
|
|
2069
|
-
].indexOf(id) !== i) throw new ModelOperationError(`id "${id}" is already in use
|
|
2294
|
+
].indexOf(id) !== i) throw new ModelOperationError(`id "${id}" is already in use`, id);
|
|
2070
2295
|
const position = defaultHubPosition(m, from, to, metamodel.elements.get(parts.hub)?.size ?? {
|
|
2071
2296
|
width: 20,
|
|
2072
2297
|
height: 20
|
|
@@ -2117,14 +2342,14 @@ function addLeg(model, hubId, source, options = {}) {
|
|
|
2117
2342
|
const metamodel = metaOf(m);
|
|
2118
2343
|
const hub = requireElement(m, hubId);
|
|
2119
2344
|
const base = metamodel.links.get(metamodel.elements.get(hub.kind)?.of ?? "");
|
|
2120
|
-
if (metamodel.elements.get(hub.kind)?.role !== "hub" || !base?.parts) throw new ModelOperationError(`"${hubId}" is not the hub of an n-ary link
|
|
2345
|
+
if (metamodel.elements.get(hub.kind)?.role !== "hub" || !base?.parts) throw new ModelOperationError(`"${hubId}" is not the hub of an n-ary link`, hubId);
|
|
2121
2346
|
const kind = base.parts.leg;
|
|
2122
2347
|
if (!options.force) {
|
|
2123
2348
|
const check = canLink(m, source, hubId, kind);
|
|
2124
2349
|
if (!check.ok) return check;
|
|
2125
2350
|
} else requireElement(m, source);
|
|
2126
2351
|
const id = options.id ?? (options.createId ?? defaultIdGenerator)();
|
|
2127
|
-
if (m.elements.has(id) || m.links.has(id)) throw new ModelOperationError(`id "${id}" is already in use
|
|
2352
|
+
if (m.elements.has(id) || m.links.has(id)) throw new ModelOperationError(`id "${id}" is already in use`, id);
|
|
2128
2353
|
const leg = {
|
|
2129
2354
|
id,
|
|
2130
2355
|
kind,
|
|
@@ -2147,7 +2372,7 @@ function addLeg(model, hubId, source, options = {}) {
|
|
|
2147
2372
|
function removeLeg(model, legId) {
|
|
2148
2373
|
const m = any(model);
|
|
2149
2374
|
const leg = requireLink(m, legId);
|
|
2150
|
-
if (metaOf(m).links.get(leg.kind)?.role !== "leg") throw new ModelOperationError(`"${legId}" is not a leg of an n-ary link
|
|
2375
|
+
if (metaOf(m).links.get(leg.kind)?.role !== "leg") throw new ModelOperationError(`"${legId}" is not a leg of an n-ary link`, legId);
|
|
2151
2376
|
return disconnect(model, legId);
|
|
2152
2377
|
}
|
|
2153
2378
|
/** Adds depender → dependum → dependee. */
|
|
@@ -2191,7 +2416,7 @@ function addDependency(model, input, options = {}) {
|
|
|
2191
2416
|
source: dependum.id,
|
|
2192
2417
|
target: dependee.id
|
|
2193
2418
|
};
|
|
2194
|
-
for (const id of [id1, id2]) if (added.model.elements.has(id) || added.model.links.has(id) || id1 === id2) throw new ModelOperationError(`id "${id}" is already in use
|
|
2419
|
+
for (const id of [id1, id2]) if (added.model.elements.has(id) || added.model.links.has(id) || id1 === id2) throw new ModelOperationError(`id "${id}" is already in use`, id);
|
|
2195
2420
|
return {
|
|
2196
2421
|
ok: true,
|
|
2197
2422
|
model: typed(derive(m, {
|
|
@@ -2973,11 +3198,108 @@ function fromNodeIdDiagnostics(diagnostics) {
|
|
|
2973
3198
|
return result;
|
|
2974
3199
|
}
|
|
2975
3200
|
//#endregion
|
|
3201
|
+
//#region src/palette.ts
|
|
3202
|
+
/**
|
|
3203
|
+
* The data part of each kind's palette entry: label, grouping, ordering, and the presets a
|
|
3204
|
+
* toolbar entry creates with (a link's `value`, a dependency's `dependum`, an element's
|
|
3205
|
+
* `properties`). React-free so a host can answer "what can I add here" (GLSP's
|
|
3206
|
+
* `RequestContextActions`) without the react package. Icons, titles and components are
|
|
3207
|
+
* presentation and stay in `packages/react/src/registry`, which derives its default entries
|
|
3208
|
+
* from `DEFAULT_PALETTE`.
|
|
3209
|
+
*/
|
|
3210
|
+
function defaultElementEntry(kind, index) {
|
|
3211
|
+
const actor = isActorKind(kind);
|
|
3212
|
+
return {
|
|
3213
|
+
label: shortKindName(kind),
|
|
3214
|
+
order: actor ? index : 30 + index,
|
|
3215
|
+
section: actor ? "actors" : "elements",
|
|
3216
|
+
...actor ? { group: "actors" } : {}
|
|
3217
|
+
};
|
|
3218
|
+
}
|
|
3219
|
+
const CONTRIBUTION_ENTRY_LABELS = {
|
|
3220
|
+
make: "Make (++)",
|
|
3221
|
+
help: "Help (+)",
|
|
3222
|
+
hurt: "Hurt (-)",
|
|
3223
|
+
break: "Break (--)"
|
|
3224
|
+
};
|
|
3225
|
+
const LINK_ENTRIES = {
|
|
3226
|
+
"istar.IsALink": [{
|
|
3227
|
+
label: "Is A",
|
|
3228
|
+
order: 10,
|
|
3229
|
+
group: "actor-links",
|
|
3230
|
+
section: "actors"
|
|
3231
|
+
}],
|
|
3232
|
+
"istar.ParticipatesInLink": [{
|
|
3233
|
+
label: "Participates-In",
|
|
3234
|
+
order: 11,
|
|
3235
|
+
group: "actor-links",
|
|
3236
|
+
section: "actors"
|
|
3237
|
+
}],
|
|
3238
|
+
"istar.DependencyLink": NODE_KINDS.map((dependum, i) => ({
|
|
3239
|
+
label: `${shortKindName(dependum)} dependency`,
|
|
3240
|
+
dependum,
|
|
3241
|
+
order: 20 + i,
|
|
3242
|
+
group: "dependencies",
|
|
3243
|
+
section: "actors"
|
|
3244
|
+
})),
|
|
3245
|
+
"istar.AndRefinementLink": [{
|
|
3246
|
+
label: "And",
|
|
3247
|
+
order: 40,
|
|
3248
|
+
section: "elements"
|
|
3249
|
+
}],
|
|
3250
|
+
"istar.OrRefinementLink": [{
|
|
3251
|
+
label: "Or",
|
|
3252
|
+
order: 41,
|
|
3253
|
+
section: "elements"
|
|
3254
|
+
}],
|
|
3255
|
+
"istar.NeededByLink": [{
|
|
3256
|
+
label: "Needed-By",
|
|
3257
|
+
order: 42,
|
|
3258
|
+
section: "elements"
|
|
3259
|
+
}],
|
|
3260
|
+
"istar.QualificationLink": [{
|
|
3261
|
+
label: "Qualification",
|
|
3262
|
+
order: 43,
|
|
3263
|
+
section: "elements"
|
|
3264
|
+
}],
|
|
3265
|
+
"istar.ContributionLink": CONTRIBUTION_LABELS.map((value, i) => ({
|
|
3266
|
+
label: CONTRIBUTION_ENTRY_LABELS[value],
|
|
3267
|
+
value,
|
|
3268
|
+
order: 50 + i,
|
|
3269
|
+
group: "contributions",
|
|
3270
|
+
section: "elements"
|
|
3271
|
+
}))
|
|
3272
|
+
};
|
|
3273
|
+
/** piStar's dropdown buttons. */
|
|
3274
|
+
const DEFAULT_PALETTE_GROUPS = {
|
|
3275
|
+
actors: { label: "Actor" },
|
|
3276
|
+
"actor-links": { label: "Actor links" },
|
|
3277
|
+
dependencies: { label: "Dependency" },
|
|
3278
|
+
contributions: { label: "Contribution" }
|
|
3279
|
+
};
|
|
3280
|
+
function buildDefaultPalette() {
|
|
3281
|
+
const elements = {};
|
|
3282
|
+
ELEMENT_KINDS.forEach((kind, i) => {
|
|
3283
|
+
elements[kind] = defaultElementEntry(kind, i);
|
|
3284
|
+
});
|
|
3285
|
+
const links = {};
|
|
3286
|
+
for (const kind of LINK_KINDS) links[kind] = LINK_ENTRIES[kind];
|
|
3287
|
+
return {
|
|
3288
|
+
elements,
|
|
3289
|
+
links,
|
|
3290
|
+
groups: DEFAULT_PALETTE_GROUPS
|
|
3291
|
+
};
|
|
3292
|
+
}
|
|
3293
|
+
/** The palette data of iStar 2.0, as piStar's toolbar presents it. */
|
|
3294
|
+
const DEFAULT_PALETTE = buildDefaultPalette();
|
|
3295
|
+
//#endregion
|
|
2976
3296
|
exports.ACTOR_KINDS = ACTOR_KINDS;
|
|
2977
3297
|
exports.ACTOR_LINK_KINDS = ACTOR_LINK_KINDS;
|
|
3298
|
+
exports.ACTOR_PADDING = ACTOR_PADDING;
|
|
2978
3299
|
exports.CONTRIBUTION_LABELS = CONTRIBUTION_LABELS;
|
|
2979
3300
|
exports.DEFAULT_DIAGRAM = DEFAULT_DIAGRAM;
|
|
2980
3301
|
exports.DEFAULT_ELEMENT_SIZE = DEFAULT_ELEMENT_SIZE;
|
|
3302
|
+
exports.DEFAULT_PALETTE = DEFAULT_PALETTE;
|
|
2981
3303
|
exports.DEPENDENCY_LINK_KINDS = DEPENDENCY_LINK_KINDS;
|
|
2982
3304
|
exports.DIAGNOSTIC_SEVERITIES = DIAGNOSTIC_SEVERITIES;
|
|
2983
3305
|
exports.DIAGRAM_LAYOUT_KEY = DIAGRAM_LAYOUT_KEY;
|
|
@@ -3002,6 +3324,8 @@ exports.NODE_LINK_KINDS = NODE_LINK_KINDS;
|
|
|
3002
3324
|
exports.PISTAR_TOOL = PISTAR_TOOL;
|
|
3003
3325
|
exports.PistarParseError = PistarParseError;
|
|
3004
3326
|
exports.PistarWriteError = PistarWriteError;
|
|
3327
|
+
exports.SUGGEST_MARGIN = SUGGEST_MARGIN;
|
|
3328
|
+
exports.actorBounds = actorBounds;
|
|
3005
3329
|
exports.addDependency = addDependency;
|
|
3006
3330
|
exports.addElement = addElement;
|
|
3007
3331
|
exports.addLeg = addLeg;
|
|
@@ -3010,6 +3334,7 @@ exports.canLink = canLink;
|
|
|
3010
3334
|
exports.childrenOf = childrenOf;
|
|
3011
3335
|
exports.compareSeverity = compareSeverity;
|
|
3012
3336
|
exports.connect = connect;
|
|
3337
|
+
exports.connectResultToDiagnostic = connectResultToDiagnostic;
|
|
3013
3338
|
exports.createDiagnosticsStore = createDiagnosticsStore;
|
|
3014
3339
|
exports.createEmptyModel = createEmptyModel;
|
|
3015
3340
|
exports.createModelStore = createModelStore;
|
|
@@ -3078,6 +3403,7 @@ exports.removeLeg = removeLeg;
|
|
|
3078
3403
|
exports.setHostMetamodel = setHostMetamodel;
|
|
3079
3404
|
exports.shortKindName = shortKindName;
|
|
3080
3405
|
exports.string = string;
|
|
3406
|
+
exports.suggestPosition = suggestPosition;
|
|
3081
3407
|
exports.targetsLinks = targetsLinks;
|
|
3082
3408
|
exports.toPistar = toPistar;
|
|
3083
3409
|
exports.toPistarObject = toPistarObject;
|