@miragon/team-topologies-renderer 0.3.1 → 0.4.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/dist/index.js CHANGED
@@ -1,852 +1,841 @@
1
- import B from "diagram-js/lib/Diagram";
2
- import { TEAM_TYPE_SPECS as T, newId as L, INTERACTION_MODE_SPECS as S, FLOW_SPEC as w, dashArray as x, DOCUMENT_VERSION as K, ALL_TEAM_SPECS as U, ALL_INTERACTION_SPECS as V } from "@miragon/team-topologies-schema-model";
3
- import G from "diagram-js/lib/draw/BaseRenderer";
4
- import { attr as g, create as y, append as _ } from "tiny-svg";
5
- import H from "diagram-js/lib/features/selection";
6
- import Y from "diagram-js/lib/navigation/zoomscroll";
7
- import X from "diagram-js/lib/navigation/movecanvas";
8
- import W from "diagram-js/lib/features/modeling";
9
- import Z from "diagram-js/lib/features/move";
10
- import q from "diagram-js/lib/features/outline";
11
- import J from "diagram-js/lib/features/resize";
12
- import Q from "diagram-js/lib/features/rules";
13
- import tt from "diagram-js/lib/features/rules/RuleProvider";
14
- import et from "diagram-js/lib/command/CommandInterceptor";
15
- import it from "diagram-js/lib/features/palette";
16
- import nt from "diagram-js/lib/features/create";
17
- import ot from "diagram-js/lib/features/context-pad";
18
- function R(r) {
19
- return typeof r == "object" && r !== null ? r.ttKind : void 0;
20
- }
21
- function $(r) {
22
- return typeof R(r) == "string";
23
- }
24
- function I(r) {
25
- return R(r) === "team";
26
- }
27
- function C(r) {
28
- return R(r) === "interaction";
29
- }
30
- function O(r) {
31
- return R(r) === "flow";
32
- }
33
- const k = 40;
34
- function rt(r, t) {
35
- const e = r.getContainer().querySelector("svg");
36
- if (!e) throw new Error("No SVG found in the canvas container.");
37
- let o = 1 / 0, n = 1 / 0, s = -1 / 0, a = -1 / 0;
38
- for (const b of t.getAll()) {
39
- if (!$(b)) continue;
40
- const d = b;
41
- o = Math.min(o, d.x), n = Math.min(n, d.y), s = Math.max(s, d.x + d.width), a = Math.max(a, d.y + d.height);
42
- }
43
- Number.isFinite(o) || (o = 0, n = 0, s = 100, a = 100);
44
- const c = o - k, h = n - k, l = s - o + k * 2, m = a - n + k * 2, u = e.cloneNode(!0);
45
- u.setAttribute("xmlns", "http://www.w3.org/2000/svg"), u.setAttribute("viewBox", `${c} ${h} ${l} ${m}`), u.setAttribute("width", String(Math.round(l))), u.setAttribute("height", String(Math.round(m)));
46
- const f = u.querySelector(".viewport");
47
- return f && f.removeAttribute("transform"), { svg: `<?xml version="1.0" encoding="utf-8"?>
48
- ` + new XMLSerializer().serializeToString(u) };
49
- }
50
- const M = "tt-root";
51
- function z(r) {
52
- return typeof r == "number" ? `${r}px` : r;
53
- }
54
- class st {
55
- _diagram;
56
- _container;
57
- _options;
58
- constructor(t = {}) {
59
- this._options = t, this._container = this._createContainer(t);
60
- }
61
- _createContainer(t) {
62
- const i = t.container ?? document.createElement("div");
63
- return i.classList.add("tt-djs-container"), i.style.width = z(t.width ?? "100%"), i.style.height = z(t.height ?? (t.container ? "100%" : "600px")), i;
64
- }
65
- _ensureDiagram() {
66
- if (!this._diagram) {
67
- const t = [...this._getModules(), ...this._options.additionalModules ?? []];
68
- this._diagram = new B({ canvas: { container: this._container }, modules: t });
69
- }
70
- return this._diagram;
71
- }
72
- /** Resolve a diagram-js service from the didi injector. */
73
- get(t) {
74
- return this._ensureDiagram().get(t);
75
- }
76
- on(t, i, e = 1e3) {
77
- this.get("eventBus").on(t, e, i);
78
- }
79
- off(t, i) {
80
- this.get("eventBus").off(t, i);
81
- }
82
- /** Load a document into the canvas (replaces existing content). */
83
- importDocument(t) {
84
- const i = this._ensureDiagram(), e = i.get("eventBus"), o = i.get("ttImporter");
85
- o.clear();
86
- const n = o.import(t);
87
- return this._fit(), e.fire("import.done", { warnings: n }), { warnings: n };
88
- }
89
- /** Current canvas state as a canonical document. */
90
- exportDocument() {
91
- return this.get("ttExporter").export();
92
- }
93
- /** Update diagram-level metadata (title / flow-of-change) on the root. */
94
- setMeta(t) {
95
- const i = this.get("canvas");
96
- let e;
97
- try {
98
- e = i.getRootElement();
99
- } catch {
100
- return;
101
- }
102
- if (!e || e.id !== M) return;
103
- const o = e.businessObject ?? { title: "Untitled team topology" };
104
- e.businessObject = { ...o, ...t };
105
- }
106
- /** Read diagram-level metadata (title / flow-of-change) from the root. */
107
- getMeta() {
108
- try {
109
- return this.get("canvas").getRootElement().businessObject;
110
- } catch {
111
- return;
112
- }
113
- }
114
- /** Standalone, self-contained SVG snapshot. */
115
- saveSVG() {
116
- return rt(this.get("canvas"), this.get("elementRegistry"));
117
- }
118
- /** Fit the content into the viewport, leaving room at the top for the palette. */
119
- _fit(t = 84, i = 56) {
120
- const e = this.get("canvas"), o = this.get("elementRegistry");
121
- let n = 1 / 0, s = 1 / 0, a = -1 / 0, c = -1 / 0;
122
- for (const b of o.getAll()) {
123
- const d = b;
124
- typeof d.x != "number" || typeof d.y != "number" || typeof d.width != "number" || typeof d.height != "number" || (n = Math.min(n, d.x), s = Math.min(s, d.y), a = Math.max(a, d.x + d.width), c = Math.max(c, d.y + d.height));
125
- }
126
- if (!Number.isFinite(n)) return;
127
- const h = this._container.getBoundingClientRect(), l = h.width, m = h.height, u = Math.max(a - n, 1), f = Math.max(c - s, 1);
128
- if (!l || !m) {
129
- e.zoom("fit-viewport");
130
- return;
131
- }
132
- const p = Math.min((l - 2 * i) / u, (m - t - i) / f, 1.25);
133
- e.viewbox({
134
- x: n + u / 2 - l / 2 / p,
135
- y: s - t / p,
136
- width: l / p,
137
- height: m / p
138
- });
139
- }
140
- /** Attach the container into `target`. */
141
- attachTo(t) {
142
- t.appendChild(this._container), this.get("canvas").resized();
143
- }
144
- /** Detach the container from the DOM, preserving state. */
145
- detach() {
146
- this._container.remove();
147
- }
148
- clear() {
149
- this._ensureDiagram().clear();
150
- }
151
- destroy() {
152
- this._diagram && (this._diagram.destroy(), this._diagram = void 0), this._container.remove();
153
- }
154
- get container() {
155
- return this._container;
156
- }
157
- }
158
- class at {
159
- constructor(t) {
160
- this.elementFactory = t;
161
- }
162
- static $inject = ["elementFactory"];
163
- // --- from canonical document elements (import) -------------------------
164
- createTeam(t) {
165
- return this.elementFactory.createShape({
166
- id: t.id,
167
- x: t.position.x,
168
- y: t.position.y,
169
- width: t.size.width,
170
- height: t.size.height,
171
- ttKind: "team",
172
- teamType: t.type,
173
- ttLabel: t.label,
174
- ...t.description ? { description: t.description } : {},
175
- ...t.fill ? { fill: t.fill } : {},
176
- ...t.stroke ? { stroke: t.stroke } : {}
177
- });
178
- }
179
- createInteraction(t) {
180
- return this.elementFactory.createShape({
181
- id: t.id,
182
- x: t.position.x,
183
- y: t.position.y,
184
- width: t.size.width,
185
- height: t.size.height,
186
- ttKind: "interaction",
187
- mode: t.mode,
188
- ...t.label ? { ttLabel: t.label } : {},
189
- ...t.fill ? { fill: t.fill } : {},
190
- ...t.stroke ? { stroke: t.stroke } : {}
191
- });
192
- }
193
- createFlow(t) {
194
- return this.elementFactory.createShape({
195
- id: t.id,
196
- x: t.position.x,
197
- y: t.position.y,
198
- width: t.size.width,
199
- height: t.size.height,
200
- ttKind: "flow",
201
- ...t.label ? { ttLabel: t.label } : {}
202
- });
203
- }
204
- // --- fresh, not-yet-placed shapes (palette / context-pad create) -------
205
- //
206
- // These set an explicit model-style id (`team_…`/`int_…`/`flow_…`, matching
207
- // the model package's factory). We must NOT fall back to diagram-js' own
208
- // auto-id: its counter starts at `shape_12` and is not advanced past ids that
209
- // come in via import, so a re-imported `shape_N` (an element created in a
210
- // previous session, then autosaved) collides with the next palette create —
211
- // the first placement after a reload then throws "element already exists".
212
- createNewTeam(t, i) {
213
- const e = T[t];
214
- return this.elementFactory.createShape({
215
- id: L("team"),
216
- width: e.defaultSize.width,
217
- height: e.defaultSize.height,
218
- ttKind: "team",
219
- teamType: t,
220
- ttLabel: i ?? e.label
221
- });
222
- }
223
- createNewInteraction(t) {
224
- const i = S[t];
225
- return this.elementFactory.createShape({
226
- id: L("int"),
227
- width: i.defaultSize.width,
228
- height: i.defaultSize.height,
229
- ttKind: "interaction",
230
- mode: t
231
- });
232
- }
233
- createNewFlow() {
234
- return this.elementFactory.createShape({
235
- id: L("flow"),
236
- width: w.defaultSize.width,
237
- height: w.defaultSize.height,
238
- ttKind: "flow",
239
- ttLabel: w.label
240
- });
241
- }
242
- }
243
- const ct = {
244
- ttElementFactory: ["type", at]
245
- }, lt = 1500, dt = "#1f2430", ht = "#525a6b", E = {
246
- /**
247
- * Set directly as the `font-family` attribute on every SVG <text> (canvas
248
- * labels and therefore the SVG export too) — not inherited from a CSS
249
- * container. Falls back to system sans when the host doesn't provide Inter.
250
- */
251
- family: "'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif",
252
- label: 13.5,
253
- small: 11
1
+ import e from "diagram-js/lib/Diagram";
2
+ import { ALL_INTERACTION_SPECS as t, ALL_TEAM_SPECS as n, DOCUMENT_VERSION as r, FLOW_SPEC as i, INTERACTION_MODE_SPECS as a, TEAM_TYPE_SPECS as o, dashArray as s, newId as c } from "@miragon/team-topologies-schema-model";
3
+ import l from "diagram-js/lib/draw/BaseRenderer";
4
+ import { append as u, attr as d, create as f } from "tiny-svg";
5
+ import p from "diagram-js/lib/features/selection";
6
+ import m from "diagram-js/lib/navigation/zoomscroll";
7
+ import h from "diagram-js/lib/navigation/movecanvas";
8
+ import g from "diagram-js/lib/features/modeling";
9
+ import ee from "diagram-js/lib/features/move";
10
+ import te from "diagram-js/lib/features/outline";
11
+ import ne from "diagram-js/lib/features/resize";
12
+ import re from "diagram-js/lib/features/rules";
13
+ import ie from "diagram-js/lib/features/rules/RuleProvider";
14
+ import ae from "diagram-js/lib/command/CommandInterceptor";
15
+ import oe from "diagram-js/lib/features/palette";
16
+ import se from "diagram-js/lib/features/create";
17
+ import ce from "diagram-js/lib/features/context-pad";
18
+ //#region src/model/di-types.ts
19
+ function _(e) {
20
+ return typeof e == "object" && e ? e.ttKind : void 0;
21
+ }
22
+ function v(e) {
23
+ return typeof _(e) == "string";
24
+ }
25
+ function y(e) {
26
+ return _(e) === "team";
27
+ }
28
+ function b(e) {
29
+ return _(e) === "interaction";
30
+ }
31
+ function x(e) {
32
+ return _(e) === "flow";
33
+ }
34
+ //#endregion
35
+ //#region src/io/saveSvg.ts
36
+ var S = 40;
37
+ function C(e, t) {
38
+ let n = e.getContainer().querySelector("svg");
39
+ if (!n) throw Error("No SVG found in the canvas container.");
40
+ let r = Infinity, i = Infinity, a = -Infinity, o = -Infinity;
41
+ for (let e of t.getAll()) {
42
+ if (!v(e)) continue;
43
+ let t = e;
44
+ r = Math.min(r, t.x), i = Math.min(i, t.y), a = Math.max(a, t.x + t.width), o = Math.max(o, t.y + t.height);
45
+ }
46
+ Number.isFinite(r) || (r = 0, i = 0, a = 100, o = 100);
47
+ let s = r - S, c = i - S, l = a - r + S * 2, u = o - i + S * 2, d = n.cloneNode(!0);
48
+ d.setAttribute("xmlns", "http://www.w3.org/2000/svg"), d.setAttribute("viewBox", `${s} ${c} ${l} ${u}`), d.setAttribute("width", String(Math.round(l))), d.setAttribute("height", String(Math.round(u)));
49
+ let f = d.querySelector(".viewport");
50
+ return f && f.removeAttribute("transform"), { svg: "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + new XMLSerializer().serializeToString(d) };
51
+ }
52
+ //#endregion
53
+ //#region src/io/types.ts
54
+ var w = "tt-root";
55
+ //#endregion
56
+ //#region src/TtBaseViewer.ts
57
+ function T(e) {
58
+ return typeof e == "number" ? `${e}px` : e;
59
+ }
60
+ var E = class {
61
+ _diagram;
62
+ _container;
63
+ _options;
64
+ constructor(e = {}) {
65
+ this._options = e, this._container = this._createContainer(e);
66
+ }
67
+ _createContainer(e) {
68
+ let t = e.container ?? document.createElement("div");
69
+ return t.classList.add("tt-djs-container"), t.style.width = T(e.width ?? "100%"), t.style.height = T(e.height ?? (e.container ? "100%" : "600px")), t;
70
+ }
71
+ _ensureDiagram() {
72
+ if (!this._diagram) {
73
+ let t = [...this._getModules(), ...this._options.additionalModules ?? []];
74
+ this._diagram = new e({
75
+ canvas: { container: this._container },
76
+ modules: t
77
+ });
78
+ }
79
+ return this._diagram;
80
+ }
81
+ get(e) {
82
+ return this._ensureDiagram().get(e);
83
+ }
84
+ on(e, t, n = 1e3) {
85
+ this.get("eventBus").on(e, n, t);
86
+ }
87
+ off(e, t) {
88
+ this.get("eventBus").off(e, t);
89
+ }
90
+ importDocument(e) {
91
+ let t = this._ensureDiagram(), n = t.get("eventBus"), r = t.get("ttImporter");
92
+ r.clear();
93
+ let i = r.import(e);
94
+ return this._fit(), n.fire("import.done", { warnings: i }), { warnings: i };
95
+ }
96
+ exportDocument() {
97
+ return this.get("ttExporter").export();
98
+ }
99
+ setMeta(e) {
100
+ let t = this.get("canvas"), n;
101
+ try {
102
+ n = t.getRootElement();
103
+ } catch {
104
+ return;
105
+ }
106
+ if (!n || n.id !== "tt-root") return;
107
+ let r = n.businessObject ?? { title: "Untitled team topology" };
108
+ n.businessObject = {
109
+ ...r,
110
+ ...e
111
+ };
112
+ }
113
+ getMeta() {
114
+ try {
115
+ return this.get("canvas").getRootElement().businessObject;
116
+ } catch {
117
+ return;
118
+ }
119
+ }
120
+ saveSVG() {
121
+ return C(this.get("canvas"), this.get("elementRegistry"));
122
+ }
123
+ _fit(e = 84, t = 56) {
124
+ let n = this.get("canvas"), r = this.get("elementRegistry"), i = Infinity, a = Infinity, o = -Infinity, s = -Infinity;
125
+ for (let e of r.getAll()) {
126
+ let t = e;
127
+ typeof t.x != "number" || typeof t.y != "number" || typeof t.width != "number" || typeof t.height != "number" || (i = Math.min(i, t.x), a = Math.min(a, t.y), o = Math.max(o, t.x + t.width), s = Math.max(s, t.y + t.height));
128
+ }
129
+ if (!Number.isFinite(i)) return;
130
+ let c = this._container.getBoundingClientRect(), l = c.width, u = c.height, d = Math.max(o - i, 1), f = Math.max(s - a, 1);
131
+ if (!l || !u) {
132
+ n.zoom("fit-viewport");
133
+ return;
134
+ }
135
+ let p = Math.min((l - 2 * t) / d, (u - e - t) / f, 1.25);
136
+ n.viewbox({
137
+ x: i + d / 2 - l / 2 / p,
138
+ y: a - e / p,
139
+ width: l / p,
140
+ height: u / p
141
+ });
142
+ }
143
+ attachTo(e) {
144
+ e.appendChild(this._container), this.get("canvas").resized();
145
+ }
146
+ detach() {
147
+ this._container.remove();
148
+ }
149
+ clear() {
150
+ this._ensureDiagram().clear();
151
+ }
152
+ destroy() {
153
+ this._diagram &&= (this._diagram.destroy(), void 0), this._container.remove();
154
+ }
155
+ get container() {
156
+ return this._container;
157
+ }
158
+ }, D = class {
159
+ elementFactory;
160
+ static $inject = ["elementFactory"];
161
+ constructor(e) {
162
+ this.elementFactory = e;
163
+ }
164
+ createTeam(e) {
165
+ return this.elementFactory.createShape({
166
+ id: e.id,
167
+ x: e.position.x,
168
+ y: e.position.y,
169
+ width: e.size.width,
170
+ height: e.size.height,
171
+ ttKind: "team",
172
+ teamType: e.type,
173
+ ttLabel: e.label,
174
+ ...e.description ? { description: e.description } : {},
175
+ ...e.fill ? { fill: e.fill } : {},
176
+ ...e.stroke ? { stroke: e.stroke } : {}
177
+ });
178
+ }
179
+ createInteraction(e) {
180
+ return this.elementFactory.createShape({
181
+ id: e.id,
182
+ x: e.position.x,
183
+ y: e.position.y,
184
+ width: e.size.width,
185
+ height: e.size.height,
186
+ ttKind: "interaction",
187
+ mode: e.mode,
188
+ ...e.label ? { ttLabel: e.label } : {},
189
+ ...e.fill ? { fill: e.fill } : {},
190
+ ...e.stroke ? { stroke: e.stroke } : {}
191
+ });
192
+ }
193
+ createFlow(e) {
194
+ return this.elementFactory.createShape({
195
+ id: e.id,
196
+ x: e.position.x,
197
+ y: e.position.y,
198
+ width: e.size.width,
199
+ height: e.size.height,
200
+ ttKind: "flow",
201
+ ...e.label ? { ttLabel: e.label } : {}
202
+ });
203
+ }
204
+ createNewTeam(e, t) {
205
+ let n = o[e];
206
+ return this.elementFactory.createShape({
207
+ id: c("team"),
208
+ width: n.defaultSize.width,
209
+ height: n.defaultSize.height,
210
+ ttKind: "team",
211
+ teamType: e,
212
+ ttLabel: t ?? n.label
213
+ });
214
+ }
215
+ createNewInteraction(e) {
216
+ let t = a[e];
217
+ return this.elementFactory.createShape({
218
+ id: c("int"),
219
+ width: t.defaultSize.width,
220
+ height: t.defaultSize.height,
221
+ ttKind: "interaction",
222
+ mode: e
223
+ });
224
+ }
225
+ createNewFlow() {
226
+ return this.elementFactory.createShape({
227
+ id: c("flow"),
228
+ width: i.defaultSize.width,
229
+ height: i.defaultSize.height,
230
+ ttKind: "flow",
231
+ ttLabel: i.label
232
+ });
233
+ }
234
+ }, O = { ttElementFactory: ["type", D] }, le = 1500, ue = "#1f2430", de = "#525a6b", k = {
235
+ family: "'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif",
236
+ label: 13.5,
237
+ small: 11
238
+ }, A = class extends l {
239
+ static $inject = ["eventBus"];
240
+ constructor(e) {
241
+ super(e, le);
242
+ }
243
+ canRender(e) {
244
+ return v(e);
245
+ }
246
+ drawShape(e, t) {
247
+ if (y(t)) return this.drawTeam(e, t);
248
+ if (b(t)) return this.drawInteraction(e, t);
249
+ if (x(t)) return this.drawFlow(e, t);
250
+ let n = d(f("rect"), {
251
+ width: t.width,
252
+ height: t.height,
253
+ fill: "#eee"
254
+ });
255
+ return u(e, n), n;
256
+ }
257
+ getShapePath(e) {
258
+ let { x: t, y: n, width: r, height: i } = e;
259
+ return `M${t},${n}l${r},0l0,${i}l${-r},0z`;
260
+ }
261
+ drawTeam(e, t) {
262
+ let n = o[t.teamType] ?? o["stream-aligned"], r = Math.max(t.width, 1), i = Math.max(t.height, 1), a = n.strokeWidth, c = s(n.strokeStyle, a), l = this.teamOutline(n.shape, r, i, a, {
263
+ fill: t.fill ?? n.fill,
264
+ stroke: t.stroke ?? n.stroke,
265
+ "stroke-width": a,
266
+ ...c ? { "stroke-dasharray": c } : {},
267
+ "stroke-linejoin": "round"
268
+ });
269
+ return u(e, l), this.appendLabel(e, t.ttLabel ?? "", r, i, { "font-weight": "640" }), l;
270
+ }
271
+ teamOutline(e, t, n, r, i) {
272
+ let a = r / 2, o = t - r, s = n - r;
273
+ if (e === "octagon") {
274
+ let e = Math.min(o, s) * .29;
275
+ return d(f("polygon"), {
276
+ points: fe(a, o, s, e),
277
+ ...i
278
+ });
279
+ }
280
+ let c = e === "rect" ? 4 : Math.min(20, s / 2, o / 2);
281
+ return d(f("rect"), {
282
+ x: a,
283
+ y: a,
284
+ width: o,
285
+ height: s,
286
+ rx: c,
287
+ ry: c,
288
+ ...i
289
+ });
290
+ }
291
+ drawInteraction(e, t) {
292
+ let n = a[t.mode] ?? a.collaboration, r = Math.max(t.width, 1), i = Math.max(t.height, 1), o = {
293
+ fill: t.fill ?? n.fill,
294
+ "fill-opacity": n.opacity,
295
+ stroke: t.stroke ?? n.stroke,
296
+ "stroke-width": 2,
297
+ "stroke-dasharray": s(n.strokeStyle, 2) || "6 4",
298
+ "stroke-linejoin": "round"
299
+ }, c;
300
+ if (n.shape === "circle") c = d(f("ellipse"), {
301
+ cx: r / 2,
302
+ cy: i / 2,
303
+ rx: (r - 2) / 2,
304
+ ry: (i - 2) / 2,
305
+ ...o
306
+ });
307
+ else if (n.shape === "triangle") {
308
+ let e = `${r / 2},1 ${r - 1},${i - 1} 1,${i - 1}`;
309
+ c = d(f("polygon"), {
310
+ points: e,
311
+ ...o
312
+ });
313
+ } else {
314
+ let e = Math.min(r * .26, i * .85), t = `${1 + e},1 ${r - 1},1 ${r - 1 - e},${i - 1} 1,${i - 1}`;
315
+ c = d(f("polygon"), {
316
+ points: t,
317
+ ...o
318
+ });
319
+ }
320
+ return u(e, c), t.ttLabel && this.appendLabel(e, t.ttLabel, r, i, {
321
+ "font-size": k.small,
322
+ "font-weight": "600"
323
+ }), c;
324
+ }
325
+ drawFlow(e, t) {
326
+ let n = Math.max(t.width, 1), r = Math.max(t.height, 1), a = i.strokeWidth, o = a / 2, c = Math.min(n * .16, r * 1.1), l = r * .5, p = (r - l) / 2, m = p + l, h = [
327
+ [o, p],
328
+ [n - c, p],
329
+ [n - c, o],
330
+ [n - o, r / 2],
331
+ [n - c, r - o],
332
+ [n - c, m],
333
+ [o, m]
334
+ ].map((e) => e.join(",")).join(" "), g = d(f("polygon"), {
335
+ points: h,
336
+ fill: "none",
337
+ stroke: i.stroke,
338
+ "stroke-width": a,
339
+ "stroke-dasharray": s(i.strokeStyle, a) || "6 4",
340
+ "stroke-linejoin": "round"
341
+ });
342
+ return u(e, g), t.ttLabel && this.appendLabel(e, t.ttLabel, n - c, r, {
343
+ "font-size": k.small,
344
+ "font-weight": "650",
345
+ "letter-spacing": "0.06em",
346
+ fill: de
347
+ }), g;
348
+ }
349
+ appendLabel(e, t, n, r, i) {
350
+ let a = typeof i["font-size"] == "number" ? i["font-size"] : k.label, o = pe(t, n - 20, a), s = a * 1.2, c = r / 2 - (o.length - 1) * s / 2;
351
+ o.forEach((t, r) => {
352
+ let o = d(f("text"), {
353
+ x: n / 2,
354
+ y: c + r * s,
355
+ "font-family": k.family,
356
+ "font-size": a,
357
+ fill: ue,
358
+ "text-anchor": "middle",
359
+ "dominant-baseline": "central",
360
+ ...i
361
+ });
362
+ o.textContent = t, u(e, o);
363
+ });
364
+ }
254
365
  };
255
- class ut extends G {
256
- static $inject = ["eventBus"];
257
- constructor(t) {
258
- super(t, lt);
259
- }
260
- canRender(t) {
261
- return $(t);
262
- }
263
- drawShape(t, i) {
264
- if (I(i)) return this.drawTeam(t, i);
265
- if (C(i)) return this.drawInteraction(t, i);
266
- if (O(i)) return this.drawFlow(t, i);
267
- const e = g(y("rect"), {
268
- width: i.width,
269
- height: i.height,
270
- fill: "#eee"
271
- });
272
- return _(t, e), e;
273
- }
274
- getShapePath(t) {
275
- const { x: i, y: e, width: o, height: n } = t;
276
- return `M${i},${e}l${o},0l0,${n}l${-o},0z`;
277
- }
278
- // --- teams ---------------------------------------------------------------
279
- drawTeam(t, i) {
280
- const e = T[i.teamType] ?? T["stream-aligned"], o = Math.max(i.width, 1), n = Math.max(i.height, 1), s = e.strokeWidth, a = x(e.strokeStyle, s), c = this.teamOutline(e.shape, o, n, s, {
281
- fill: i.fill ?? e.fill,
282
- stroke: i.stroke ?? e.stroke,
283
- "stroke-width": s,
284
- ...a ? { "stroke-dasharray": a } : {},
285
- "stroke-linejoin": "round"
286
- });
287
- return _(t, c), this.appendLabel(t, i.ttLabel ?? "", o, n, { "font-weight": "640" }), c;
288
- }
289
- teamOutline(t, i, e, o, n) {
290
- const s = o / 2, a = i - o, c = e - o;
291
- if (t === "octagon") {
292
- const l = Math.min(a, c) * 0.29;
293
- return g(y("polygon"), { points: mt(s, a, c, l), ...n });
294
- }
295
- const h = t === "rect" ? 4 : Math.min(20, c / 2, a / 2);
296
- return g(y("rect"), { x: s, y: s, width: a, height: c, rx: h, ry: h, ...n });
297
- }
298
- // --- interactions --------------------------------------------------------
299
- drawInteraction(t, i) {
300
- const e = S[i.mode] ?? S.collaboration, o = Math.max(i.width, 1), n = Math.max(i.height, 1), s = 2, a = s / 2, c = {
301
- fill: i.fill ?? e.fill,
302
- "fill-opacity": e.opacity,
303
- stroke: i.stroke ?? e.stroke,
304
- "stroke-width": s,
305
- "stroke-dasharray": x(e.strokeStyle, s) || "6 4",
306
- "stroke-linejoin": "round"
307
- };
308
- let h;
309
- if (e.shape === "circle")
310
- h = g(y("ellipse"), {
311
- cx: o / 2,
312
- cy: n / 2,
313
- rx: (o - s) / 2,
314
- ry: (n - s) / 2,
315
- ...c
316
- });
317
- else if (e.shape === "triangle") {
318
- const l = `${o / 2},${a} ${o - a},${n - a} ${a},${n - a}`;
319
- h = g(y("polygon"), { points: l, ...c });
320
- } else {
321
- const l = Math.min(o * 0.26, n * 0.85), m = `${a + l},${a} ${o - a},${a} ${o - a - l},${n - a} ${a},${n - a}`;
322
- h = g(y("polygon"), { points: m, ...c });
323
- }
324
- return _(t, h), i.ttLabel && this.appendLabel(t, i.ttLabel, o, n, {
325
- "font-size": E.small,
326
- "font-weight": "600"
327
- }), h;
328
- }
329
- // --- flow of change ------------------------------------------------------
330
- drawFlow(t, i) {
331
- const e = Math.max(i.width, 1), o = Math.max(i.height, 1), n = w.strokeWidth, s = n / 2, a = Math.min(e * 0.16, o * 1.1), c = o * 0.5, h = (o - c) / 2, l = h + c, m = [
332
- [s, h],
333
- [e - a, h],
334
- [e - a, s],
335
- [e - s, o / 2],
336
- [e - a, o - s],
337
- [e - a, l],
338
- [s, l]
339
- ].map((f) => f.join(",")).join(" "), u = g(y("polygon"), {
340
- points: m,
341
- fill: "none",
342
- stroke: w.stroke,
343
- "stroke-width": n,
344
- "stroke-dasharray": x(w.strokeStyle, n) || "6 4",
345
- "stroke-linejoin": "round"
346
- });
347
- return _(t, u), i.ttLabel && this.appendLabel(t, i.ttLabel, e - a, o, {
348
- "font-size": E.small,
349
- "font-weight": "650",
350
- "letter-spacing": "0.06em",
351
- fill: ht
352
- }), u;
353
- }
354
- // --- shared label rendering (wrapped, centred, no halo) ------------------
355
- appendLabel(t, i, e, o, n) {
356
- const s = typeof n["font-size"] == "number" ? n["font-size"] : E.label, a = ft(i, e - 20, s), c = s * 1.2, h = o / 2 - (a.length - 1) * c / 2;
357
- a.forEach((l, m) => {
358
- const u = g(y("text"), {
359
- x: e / 2,
360
- y: h + m * c,
361
- "font-family": E.family,
362
- "font-size": s,
363
- fill: dt,
364
- "text-anchor": "middle",
365
- "dominant-baseline": "central",
366
- ...n
367
- });
368
- u.textContent = l, _(t, u);
369
- });
370
- }
371
- }
372
- function mt(r, t, i, e) {
373
- return [
374
- [r + e, r],
375
- [r + t - e, r],
376
- [r + t, r + e],
377
- [r + t, r + i - e],
378
- [r + t - e, r + i],
379
- [r + e, r + i],
380
- [r, r + i - e],
381
- [r, r + e]
382
- ].map((o) => o.join(",")).join(" ");
383
- }
384
- function ft(r, t, i) {
385
- const e = Math.max(4, Math.floor(t / (i * 0.58))), o = r.split(/\s+/).filter(Boolean);
386
- if (o.length === 0) return [];
387
- const n = [];
388
- let s = "";
389
- for (const a of o) {
390
- const c = s ? `${s} ${a}` : a;
391
- c.length > e && s ? (n.push(s), s = a) : s = c;
392
- }
393
- return s && n.push(s), n;
394
- }
395
- const pt = {
396
- __init__: ["ttRenderer"],
397
- ttRenderer: ["type", ut]
366
+ function fe(e, t, n, r) {
367
+ return [
368
+ [e + r, e],
369
+ [e + t - r, e],
370
+ [e + t, e + r],
371
+ [e + t, e + n - r],
372
+ [e + t - r, e + n],
373
+ [e + r, e + n],
374
+ [e, e + n - r],
375
+ [e, e + r]
376
+ ].map((e) => e.join(",")).join(" ");
377
+ }
378
+ function pe(e, t, n) {
379
+ let r = Math.max(4, Math.floor(t / (n * .58))), i = e.split(/\s+/).filter(Boolean);
380
+ if (i.length === 0) return [];
381
+ let a = [], o = "";
382
+ for (let e of i) {
383
+ let t = o ? `${o} ${e}` : e;
384
+ t.length > r && o ? (a.push(o), o = e) : o = t;
385
+ }
386
+ return o && a.push(o), a;
387
+ }
388
+ //#endregion
389
+ //#region src/draw/index.ts
390
+ var j = {
391
+ __init__: ["ttRenderer"],
392
+ ttRenderer: ["type", A]
393
+ }, M = class {
394
+ canvas;
395
+ elementFactory;
396
+ factory;
397
+ eventBus;
398
+ elementRegistry;
399
+ static $inject = [
400
+ "canvas",
401
+ "elementFactory",
402
+ "ttElementFactory",
403
+ "eventBus",
404
+ "elementRegistry"
405
+ ];
406
+ constructor(e, t, n, r, i) {
407
+ this.canvas = e, this.elementFactory = t, this.factory = n, this.eventBus = r, this.elementRegistry = i;
408
+ }
409
+ import(e) {
410
+ let t = [];
411
+ this.eventBus.fire("import.render.start", { document: e });
412
+ let n;
413
+ try {
414
+ n = this.canvas.getRootElement();
415
+ } catch {
416
+ n = void 0;
417
+ }
418
+ let r;
419
+ n && n.id === "tt-root" ? r = n : (r = this.elementFactory.createRoot({ id: w }), this.canvas.setRootElement(r)), r.businessObject = { title: e.title };
420
+ for (let t of e.flows) this.canvas.addShape(this.factory.createFlow(t), r);
421
+ for (let t of e.nodes) this.canvas.addShape(this.factory.createTeam(t), r);
422
+ for (let t of e.interactions) this.canvas.addShape(this.factory.createInteraction(t), r);
423
+ return this.eventBus.fire("import.render.done", { warnings: t }), t;
424
+ }
425
+ clear() {
426
+ for (let e of [...this.elementRegistry.getAll()]) if (e.id !== "tt-root") try {
427
+ this.canvas.removeShape(e.id);
428
+ } catch {}
429
+ }
430
+ }, N = class {
431
+ elementRegistry;
432
+ canvas;
433
+ static $inject = ["elementRegistry", "canvas"];
434
+ constructor(e, t) {
435
+ this.elementRegistry = e, this.canvas = t;
436
+ }
437
+ export() {
438
+ let e;
439
+ try {
440
+ e = this.canvas.getRootElement().businessObject;
441
+ } catch {
442
+ e = void 0;
443
+ }
444
+ let t = [], n = [], i = [];
445
+ for (let e of this.elementRegistry.getAll()) {
446
+ if (e.id === "tt-root") continue;
447
+ let r = e, a = {
448
+ x: r.x,
449
+ y: r.y
450
+ }, o = {
451
+ width: r.width,
452
+ height: r.height
453
+ };
454
+ y(e) ? t.push({
455
+ id: e.id,
456
+ type: e.teamType,
457
+ label: e.ttLabel ?? "",
458
+ position: a,
459
+ size: o,
460
+ ...e.description ? { description: e.description } : {},
461
+ ...e.fill ? { fill: e.fill } : {},
462
+ ...e.stroke ? { stroke: e.stroke } : {}
463
+ }) : b(e) ? n.push({
464
+ id: e.id,
465
+ mode: e.mode,
466
+ position: a,
467
+ size: o,
468
+ ...e.ttLabel ? { label: e.ttLabel } : {},
469
+ ...e.fill ? { fill: e.fill } : {},
470
+ ...e.stroke ? { stroke: e.stroke } : {}
471
+ }) : x(e) && i.push({
472
+ id: e.id,
473
+ position: a,
474
+ size: o,
475
+ ...e.ttLabel ? { label: e.ttLabel } : {}
476
+ });
477
+ }
478
+ return {
479
+ version: r,
480
+ title: e?.title ?? "Untitled team topology",
481
+ nodes: t,
482
+ interactions: n,
483
+ flows: i
484
+ };
485
+ }
486
+ }, P = {
487
+ ttImporter: ["type", M],
488
+ ttExporter: ["type", N]
489
+ }, F = class extends E {
490
+ _getModules() {
491
+ return [
492
+ O,
493
+ j,
494
+ P
495
+ ];
496
+ }
497
+ }, I = class extends F {
498
+ _getModules() {
499
+ return [
500
+ ...super._getModules(),
501
+ p,
502
+ m,
503
+ h
504
+ ];
505
+ }
398
506
  };
399
- class gt {
400
- constructor(t, i, e, o, n) {
401
- this.canvas = t, this.elementFactory = i, this.factory = e, this.eventBus = o, this.elementRegistry = n;
402
- }
403
- static $inject = ["canvas", "elementFactory", "ttElementFactory", "eventBus", "elementRegistry"];
404
- import(t) {
405
- const i = [];
406
- this.eventBus.fire("import.render.start", { document: t });
407
- let e;
408
- try {
409
- e = this.canvas.getRootElement();
410
- } catch {
411
- e = void 0;
412
- }
413
- let o;
414
- e && e.id === M ? o = e : (o = this.elementFactory.createRoot({ id: M }), this.canvas.setRootElement(o)), o.businessObject = { title: t.title };
415
- for (const n of t.flows)
416
- this.canvas.addShape(this.factory.createFlow(n), o);
417
- for (const n of t.nodes)
418
- this.canvas.addShape(this.factory.createTeam(n), o);
419
- for (const n of t.interactions)
420
- this.canvas.addShape(this.factory.createInteraction(n), o);
421
- return this.eventBus.fire("import.render.done", { warnings: i }), i;
422
- }
423
- /** Removes every element (for re-import). */
424
- clear() {
425
- for (const t of [...this.elementRegistry.getAll()])
426
- if (t.id !== M)
427
- try {
428
- this.canvas.removeShape(t.id);
429
- } catch {
430
- }
431
- }
432
- }
433
- class yt {
434
- constructor(t, i) {
435
- this.elementRegistry = t, this.canvas = i;
436
- }
437
- static $inject = ["elementRegistry", "canvas"];
438
- export() {
439
- let t;
440
- try {
441
- t = this.canvas.getRootElement().businessObject;
442
- } catch {
443
- t = void 0;
444
- }
445
- const i = [], e = [], o = [];
446
- for (const n of this.elementRegistry.getAll()) {
447
- if (n.id === M) continue;
448
- const s = n, a = { x: s.x, y: s.y }, c = { width: s.width, height: s.height };
449
- I(n) ? i.push({
450
- id: n.id,
451
- type: n.teamType,
452
- label: n.ttLabel ?? "",
453
- position: a,
454
- size: c,
455
- ...n.description ? { description: n.description } : {},
456
- ...n.fill ? { fill: n.fill } : {},
457
- ...n.stroke ? { stroke: n.stroke } : {}
458
- }) : C(n) ? e.push({
459
- id: n.id,
460
- mode: n.mode,
461
- position: a,
462
- size: c,
463
- ...n.ttLabel ? { label: n.ttLabel } : {},
464
- ...n.fill ? { fill: n.fill } : {},
465
- ...n.stroke ? { stroke: n.stroke } : {}
466
- }) : O(n) && o.push({
467
- id: n.id,
468
- position: a,
469
- size: c,
470
- ...n.ttLabel ? { label: n.ttLabel } : {}
471
- });
472
- }
473
- return {
474
- version: K,
475
- title: t?.title ?? "Untitled team topology",
476
- nodes: i,
477
- interactions: e,
478
- flows: o
479
- };
480
- }
481
- }
482
- const vt = {
483
- ttImporter: ["type", gt],
484
- ttExporter: ["type", yt]
507
+ //#endregion
508
+ //#region src/modeling/cmd/UpdatePropertiesHandler.ts
509
+ function L(e, t, n) {
510
+ n === void 0 ? delete e[t] : e[t] = n;
511
+ }
512
+ var me = class {
513
+ execute(e) {
514
+ let { element: t, properties: n } = e, r = t, i = {};
515
+ for (let e of Object.keys(n)) i[e] = r[e], L(r, e, n[e]);
516
+ return e.oldProperties = i, [t];
517
+ }
518
+ revert(e) {
519
+ let { element: t, oldProperties: n } = e, r = t;
520
+ if (n) for (let e of Object.keys(n)) L(r, e, n[e]);
521
+ return [t];
522
+ }
523
+ }, R = "element.updateProperties", he = class {
524
+ commandStack;
525
+ static $inject = ["commandStack"];
526
+ constructor(e) {
527
+ this.commandStack = e, e.registerHandler(R, me);
528
+ }
529
+ updateProperties(e, t) {
530
+ this.commandStack.execute(R, {
531
+ element: e,
532
+ properties: t
533
+ });
534
+ }
535
+ updateLabel(e, t) {
536
+ this.updateProperties(e, { ttLabel: t || void 0 });
537
+ }
538
+ setTeamType(e, t) {
539
+ this.updateProperties(e, { teamType: t });
540
+ }
541
+ setInteractionMode(e, t) {
542
+ this.updateProperties(e, { mode: t });
543
+ }
544
+ setColors(e, t, n) {
545
+ this.updateProperties(e, {
546
+ fill: t,
547
+ stroke: n
548
+ });
549
+ }
550
+ setDescription(e, t) {
551
+ this.updateProperties(e, { description: t });
552
+ }
553
+ }, z = {
554
+ __init__: ["ttModeling"],
555
+ ttModeling: ["type", he]
556
+ }, B = class extends ie {
557
+ static $inject = ["eventBus"];
558
+ constructor(e) {
559
+ super(e);
560
+ }
561
+ init() {
562
+ this.addRule(["shape.move", "elements.move"], (e) => e.target && e.target.parent ? null : !0), this.addRule("shape.create", () => !0), this.addRule("shape.resize", () => !0);
563
+ }
564
+ }, V = {
565
+ __depends__: [re],
566
+ __init__: ["ttRules"],
567
+ ttRules: ["type", B]
568
+ }, H = class extends ae {
569
+ static $inject = ["eventBus", "canvas"];
570
+ constructor(e, t) {
571
+ super(e), this.preExecute(["shape.create", "elements.create"], (e) => {
572
+ e.parent = t.getRootElement();
573
+ }, !0);
574
+ }
575
+ }, U = {
576
+ __init__: ["ttFlatModelBehavior"],
577
+ ttFlatModelBehavior: ["type", H]
485
578
  };
486
- class wt extends st {
487
- _getModules() {
488
- return [ct, pt, vt];
489
- }
490
- }
491
- class bt extends wt {
492
- _getModules() {
493
- return [...super._getModules(), H, Y, X];
494
- }
495
- }
496
- function F(r, t, i) {
497
- i === void 0 ? delete r[t] : r[t] = i;
498
- }
499
- class _t {
500
- execute(t) {
501
- const { element: i, properties: e } = t, o = i, n = {};
502
- for (const s of Object.keys(e))
503
- n[s] = o[s], F(o, s, e[s]);
504
- return t.oldProperties = n, [i];
505
- }
506
- revert(t) {
507
- const { element: i, oldProperties: e } = t, o = i;
508
- if (e)
509
- for (const n of Object.keys(e)) F(o, n, e[n]);
510
- return [i];
511
- }
512
- }
513
- const N = "element.updateProperties";
514
- class xt {
515
- constructor(t) {
516
- this.commandStack = t, t.registerHandler(N, _t);
517
- }
518
- static $inject = ["commandStack"];
519
- updateProperties(t, i) {
520
- this.commandStack.execute(N, { element: t, properties: i });
521
- }
522
- /** Rename / relabel any element. */
523
- updateLabel(t, i) {
524
- this.updateProperties(t, { ttLabel: i || void 0 });
525
- }
526
- setTeamType(t, i) {
527
- this.updateProperties(t, { teamType: i });
528
- }
529
- setInteractionMode(t, i) {
530
- this.updateProperties(t, { mode: i });
531
- }
532
- /** Set or clear per-element colour overrides (`undefined` reverts to default). */
533
- setColors(t, i, e) {
534
- this.updateProperties(t, { fill: i, stroke: e });
535
- }
536
- setDescription(t, i) {
537
- this.updateProperties(t, { description: i });
538
- }
539
- }
540
- const Mt = {
541
- __init__: ["ttModeling"],
542
- ttModeling: ["type", xt]
579
+ //#endregion
580
+ //#region src/draw/palette-icons.ts
581
+ function W(e) {
582
+ return `<svg class="tt-palette-svg" width="24" height="24" viewBox="0 0 26 26" aria-hidden="true">${e}</svg>`;
583
+ }
584
+ function G(e) {
585
+ let t = o[e], n = s(t.strokeStyle, 1.5), r = `fill="${t.fill}" stroke="${t.stroke}" stroke-width="1.5"` + (n ? ` stroke-dasharray="${n}"` : "");
586
+ switch (t.shape) {
587
+ case "octagon": return W(`<polygon points="8,3 18,3 23,8 23,18 18,23 8,23 3,18 3,8" ${r}/>`);
588
+ case "rounded-rect-vertical": return W(`<rect x="8" y="3" width="10" height="20" rx="4" ${r}/>`);
589
+ case "rect": return W(`<rect x="3" y="7" width="20" height="12" rx="1.5" ${r}/>`);
590
+ default: return W(`<rect x="3" y="8" width="20" height="10" rx="5" ${r}/>`);
591
+ }
592
+ }
593
+ function K() {
594
+ return W("<g fill=\"none\" stroke=\"#6b6459\" stroke-width=\"1.5\" stroke-linejoin=\"round\" stroke-dasharray=\"3 2\"><polygon points=\"3,9 16,9 16,5 23,13 16,21 16,17 3,17\"/></g>");
595
+ }
596
+ function q(e) {
597
+ let t = a[e], n = s(t.strokeStyle, 1.5), r = `fill="${t.fill}" fill-opacity="${t.opacity}" stroke="${t.stroke}" stroke-width="1.5"` + (n ? ` stroke-dasharray="${n}"` : "");
598
+ switch (t.shape) {
599
+ case "circle": return W(`<circle cx="13" cy="13" r="9" ${r}/>`);
600
+ case "triangle": return W(`<polygon points="5,6 22,13 5,20" ${r}/>`);
601
+ default: return W(`<polygon points="9,6 23,6 17,20 3,20" ${r}/>`);
602
+ }
603
+ }
604
+ //#endregion
605
+ //#region src/palette/TtPaletteProvider.ts
606
+ var ge = "tt-1-teams", _e = "tt-2-modes", ve = "tt-3-flow";
607
+ function J(e, t) {
608
+ return `<div class="entry tt-palette-entry" draggable="true" title="${t}">${e}</div>`;
609
+ }
610
+ var Y = class {
611
+ create;
612
+ factory;
613
+ static $inject = [
614
+ "palette",
615
+ "create",
616
+ "ttElementFactory"
617
+ ];
618
+ constructor(e, t, n) {
619
+ this.create = t, this.factory = n, e.registerProvider(this);
620
+ }
621
+ getPaletteEntries() {
622
+ let e = {};
623
+ for (let t of n) {
624
+ let n = (e) => this.create.start(e, this.factory.createNewTeam(t.type, t.label));
625
+ e[`team.${t.type}`] = {
626
+ group: ge,
627
+ title: `${t.label} team — ${t.description}`,
628
+ html: J(G(t.type), `${t.label} team — ${t.description}`),
629
+ action: {
630
+ dragstart: n,
631
+ click: n
632
+ }
633
+ };
634
+ }
635
+ for (let n of t) {
636
+ let t = (e) => this.create.start(e, this.factory.createNewInteraction(n.mode));
637
+ e[`mode.${n.mode}`] = {
638
+ group: _e,
639
+ title: `${n.label} — ${n.description} (place over the teams it relates to)`,
640
+ html: J(q(n.mode), `${n.label} — ${n.description}`),
641
+ action: {
642
+ dragstart: t,
643
+ click: t
644
+ }
645
+ };
646
+ }
647
+ let r = (e) => this.create.start(e, this.factory.createNewFlow());
648
+ return e.flow = {
649
+ group: ve,
650
+ title: `${i.label} — the implied left-to-right flow`,
651
+ html: J(K(), i.label),
652
+ action: {
653
+ dragstart: r,
654
+ click: r
655
+ }
656
+ }, e;
657
+ }
658
+ }, X = {
659
+ __depends__: [oe, se],
660
+ __init__: ["ttPaletteProvider"],
661
+ ttPaletteProvider: ["type", Y]
662
+ }, ye = "M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34a.9959.9959 0 0 0-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z", be = "M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z";
663
+ function xe(e, t = 18) {
664
+ return `<svg width="${t}" height="${t}" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="${e}"/></svg>`;
665
+ }
666
+ //#endregion
667
+ //#region src/context-pad/TtContextPadProvider.ts
668
+ function Z(e, t) {
669
+ return `<div class="entry tt-cp-entry" title="${t}">${xe(e)}</div>`;
670
+ }
671
+ var Q = class {
672
+ modeling;
673
+ labelEditing;
674
+ static $inject = [
675
+ "contextPad",
676
+ "modeling",
677
+ "ttLabelEditing"
678
+ ];
679
+ constructor(e, t, n) {
680
+ this.modeling = t, this.labelEditing = n, e.registerProvider(this);
681
+ }
682
+ getContextPadEntries(e) {
683
+ return v(e) ? {
684
+ "edit-label": {
685
+ group: "edit",
686
+ title: "Rename",
687
+ html: Z(ye, "Rename"),
688
+ action: { click: () => this.labelEditing.activate(e) }
689
+ },
690
+ delete: {
691
+ group: "edit",
692
+ title: "Delete",
693
+ html: Z(be, "Delete"),
694
+ action: { click: () => this.modeling.removeElements([e]) }
695
+ }
696
+ } : {};
697
+ }
698
+ }, Se = {
699
+ __depends__: [ce],
700
+ __init__: ["ttContextPadProvider"],
701
+ ttContextPadProvider: ["type", Q]
702
+ }, Ce = class {
703
+ canvas;
704
+ modeling;
705
+ static $inject = [
706
+ "eventBus",
707
+ "canvas",
708
+ "ttModeling"
709
+ ];
710
+ active = null;
711
+ constructor(e, t, n) {
712
+ this.canvas = t, this.modeling = n, e.on("element.dblclick", (e) => {
713
+ v(e.element) && this.activate(e.element);
714
+ }), e.on([
715
+ "element.mousedown",
716
+ "drag.init",
717
+ "canvas.viewbox.changing"
718
+ ], () => this.active?.commit());
719
+ }
720
+ activate(e) {
721
+ this.active?.commit();
722
+ let t = this.canvas.getContainer(), n = this.canvas.zoom(), r = this.canvas.viewbox(), i = e.x + e.width / 2, a = e.y + e.height / 2, o = (i - r.x) * n - 170 / 2, s = (a - r.y) * n - 14, c = document.createElement("input");
723
+ c.type = "text", c.className = "tt-label-input", c.value = e.ttLabel ?? "", c.style.position = "absolute", c.style.left = `${o}px`, c.style.top = `${s}px`, c.style.width = "170px", t.appendChild(c), c.focus(), c.select();
724
+ let l = !1, u = () => {
725
+ l || (l = !0, c.removeEventListener("keydown", f), c.removeEventListener("blur", p), c.remove(), this.active = null);
726
+ }, d = () => {
727
+ if (l) return;
728
+ let t = c.value.trim(), n = t !== (e.ttLabel ?? "");
729
+ u(), n && this.modeling.updateLabel(e, t);
730
+ }, f = (e) => {
731
+ e.key === "Enter" ? (e.preventDefault(), d()) : e.key === "Escape" && (e.preventDefault(), u());
732
+ }, p = () => d();
733
+ c.addEventListener("keydown", f), c.addEventListener("blur", p), this.active = {
734
+ commit: d,
735
+ cleanup: u
736
+ };
737
+ }
738
+ cancel() {
739
+ this.active?.cleanup();
740
+ }
741
+ }, we = {
742
+ __init__: ["ttLabelEditing"],
743
+ ttLabelEditing: ["type", Ce]
543
744
  };
544
- class $t extends tt {
545
- static $inject = ["eventBus"];
546
- constructor(t) {
547
- super(t);
548
- }
549
- init() {
550
- this.addRule(
551
- ["shape.move", "elements.move"],
552
- (t) => t.target && t.target.parent ? null : !0
553
- ), this.addRule("shape.create", () => !0), this.addRule("shape.resize", () => !0);
554
- }
555
- }
556
- const kt = {
557
- __depends__: [Q],
558
- __init__: ["ttRules"],
559
- ttRules: ["type", $t]
745
+ //#endregion
746
+ //#region src/keyboard/TtKeyboard.ts
747
+ function Te(e) {
748
+ let t = e;
749
+ return t ? t.tagName === "INPUT" || t.tagName === "TEXTAREA" || t.tagName === "SELECT" || t.isContentEditable : !1;
750
+ }
751
+ var Ee = class {
752
+ static $inject = [
753
+ "canvas",
754
+ "commandStack",
755
+ "selection",
756
+ "modeling"
757
+ ];
758
+ constructor(e, t, n, r) {
759
+ (e.getContainer().ownerDocument ?? document).addEventListener("keydown", (e) => {
760
+ if (Te(e.target)) return;
761
+ let i = e.ctrlKey || e.metaKey, a = e.key.toLowerCase();
762
+ if (i && a === "z" && !e.shiftKey) e.preventDefault(), t.canUndo() && t.undo();
763
+ else if (i && a === "z" && e.shiftKey || i && a === "y") e.preventDefault(), t.canRedo() && t.redo();
764
+ else if (a === "delete" || a === "backspace") {
765
+ let t = n.get();
766
+ t.length && (e.preventDefault(), r.removeElements([...t]));
767
+ }
768
+ });
769
+ }
770
+ }, De = {
771
+ __init__: ["ttKeyboard"],
772
+ ttKeyboard: ["type", Ee]
560
773
  };
561
- class Et extends et {
562
- static $inject = ["eventBus", "canvas"];
563
- constructor(t, i) {
564
- super(t), this.preExecute(
565
- ["shape.create", "elements.create"],
566
- (e) => {
567
- e.parent = i.getRootElement();
568
- },
569
- !0
570
- );
571
- }
572
- }
573
- const Tt = {
574
- __init__: ["ttFlatModelBehavior"],
575
- ttFlatModelBehavior: ["type", Et]
576
- };
577
- function v(r) {
578
- return `<svg class="tt-palette-svg" width="24" height="24" viewBox="0 0 26 26" aria-hidden="true">${r}</svg>`;
579
- }
580
- function St(r) {
581
- const t = T[r], i = x(t.strokeStyle, 1.5), e = `fill="${t.fill}" stroke="${t.stroke}" stroke-width="1.5"` + (i ? ` stroke-dasharray="${i}"` : "");
582
- switch (t.shape) {
583
- case "octagon":
584
- return v(`<polygon points="8,3 18,3 23,8 23,18 18,23 8,23 3,18 3,8" ${e}/>`);
585
- case "rounded-rect-vertical":
586
- return v(`<rect x="8" y="3" width="10" height="20" rx="4" ${e}/>`);
587
- case "rect":
588
- return v(`<rect x="3" y="7" width="20" height="12" rx="1.5" ${e}/>`);
589
- default:
590
- return v(`<rect x="3" y="8" width="20" height="10" rx="5" ${e}/>`);
591
- }
592
- }
593
- function Rt() {
594
- return v(
595
- '<g fill="none" stroke="#6b6459" stroke-width="1.5" stroke-linejoin="round" stroke-dasharray="3 2"><polygon points="3,9 16,9 16,5 23,13 16,21 16,17 3,17"/></g>'
596
- );
597
- }
598
- function Lt(r) {
599
- const t = S[r], i = x(t.strokeStyle, 1.5), e = `fill="${t.fill}" fill-opacity="${t.opacity}" stroke="${t.stroke}" stroke-width="1.5"` + (i ? ` stroke-dasharray="${i}"` : "");
600
- switch (t.shape) {
601
- case "circle":
602
- return v(`<circle cx="13" cy="13" r="9" ${e}/>`);
603
- case "triangle":
604
- return v(`<polygon points="5,6 22,13 5,20" ${e}/>`);
605
- default:
606
- return v(`<polygon points="9,6 23,6 17,20 3,20" ${e}/>`);
607
- }
608
- }
609
- const Pt = "tt-1-teams", It = "tt-2-modes", Ct = "tt-3-flow";
610
- function P(r, t) {
611
- return `<div class="entry tt-palette-entry" draggable="true" title="${t}">${r}</div>`;
612
- }
613
- class Ot {
614
- constructor(t, i, e) {
615
- this.create = i, this.factory = e, t.registerProvider(this);
616
- }
617
- static $inject = ["palette", "create", "ttElementFactory"];
618
- getPaletteEntries() {
619
- const t = {};
620
- for (const e of U) {
621
- const o = (n) => this.create.start(
622
- n,
623
- this.factory.createNewTeam(e.type, e.label)
624
- );
625
- t[`team.${e.type}`] = {
626
- group: Pt,
627
- title: `${e.label} team — ${e.description}`,
628
- html: P(St(e.type), `${e.label} team — ${e.description}`),
629
- action: { dragstart: o, click: o }
630
- };
631
- }
632
- for (const e of V) {
633
- const o = (n) => this.create.start(
634
- n,
635
- this.factory.createNewInteraction(e.mode)
636
- );
637
- t[`mode.${e.mode}`] = {
638
- group: It,
639
- title: `${e.label} — ${e.description} (place over the teams it relates to)`,
640
- html: P(Lt(e.mode), `${e.label} — ${e.description}`),
641
- action: { dragstart: o, click: o }
642
- };
643
- }
644
- const i = (e) => this.create.start(e, this.factory.createNewFlow());
645
- return t.flow = {
646
- group: Ct,
647
- title: `${w.label} — the implied left-to-right flow`,
648
- html: P(Rt(), w.label),
649
- action: { dragstart: i, click: i }
650
- }, t;
651
- }
652
- }
653
- const zt = {
654
- __depends__: [it, nt],
655
- __init__: ["ttPaletteProvider"],
656
- ttPaletteProvider: ["type", Ot]
657
- }, Ft = "M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34a.9959.9959 0 0 0-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z", Nt = "M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z";
658
- function jt(r, t = 18) {
659
- return `<svg width="${t}" height="${t}" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="${r}"/></svg>`;
660
- }
661
- function j(r, t) {
662
- return `<div class="entry tt-cp-entry" title="${t}">${jt(r)}</div>`;
663
- }
664
- class Dt {
665
- constructor(t, i, e) {
666
- this.modeling = i, this.labelEditing = e, t.registerProvider(this);
667
- }
668
- static $inject = ["contextPad", "modeling", "ttLabelEditing"];
669
- getContextPadEntries(t) {
670
- return $(t) ? {
671
- "edit-label": {
672
- group: "edit",
673
- title: "Rename",
674
- html: j(Ft, "Rename"),
675
- action: { click: () => this.labelEditing.activate(t) }
676
- },
677
- delete: {
678
- group: "edit",
679
- title: "Delete",
680
- html: j(Nt, "Delete"),
681
- action: { click: () => this.modeling.removeElements([t]) }
682
- }
683
- } : {};
684
- }
685
- }
686
- const At = {
687
- __depends__: [ot],
688
- __init__: ["ttContextPadProvider"],
689
- ttContextPadProvider: ["type", Dt]
690
- };
691
- class Bt {
692
- constructor(t, i, e) {
693
- this.canvas = i, this.modeling = e, t.on("element.dblclick", (o) => {
694
- $(o.element) && this.activate(o.element);
695
- }), t.on(
696
- ["element.mousedown", "drag.init", "canvas.viewbox.changing"],
697
- () => this.active?.commit()
698
- );
699
- }
700
- static $inject = ["eventBus", "canvas", "ttModeling"];
701
- active = null;
702
- activate(t) {
703
- this.active?.commit();
704
- const i = this.canvas.getContainer(), e = this.canvas.zoom(), o = this.canvas.viewbox(), n = t.x + t.width / 2, s = t.y + t.height / 2, a = 170, c = (n - o.x) * e - a / 2, h = (s - o.y) * e - 14, l = document.createElement("input");
705
- l.type = "text", l.className = "tt-label-input", l.value = t.ttLabel ?? "", l.style.position = "absolute", l.style.left = `${c}px`, l.style.top = `${h}px`, l.style.width = `${a}px`, i.appendChild(l), l.focus(), l.select();
706
- let m = !1;
707
- const u = () => {
708
- m || (m = !0, l.removeEventListener("keydown", p), l.removeEventListener("blur", b), l.remove(), this.active = null);
709
- }, f = () => {
710
- if (m) return;
711
- const d = l.value.trim(), A = d !== (t.ttLabel ?? "");
712
- u(), A && this.modeling.updateLabel(t, d);
713
- }, p = (d) => {
714
- d.key === "Enter" ? (d.preventDefault(), f()) : d.key === "Escape" && (d.preventDefault(), u());
715
- }, b = () => f();
716
- l.addEventListener("keydown", p), l.addEventListener("blur", b), this.active = { commit: f, cleanup: u };
717
- }
718
- cancel() {
719
- this.active?.cleanup();
720
- }
721
- }
722
- const Kt = {
723
- __init__: ["ttLabelEditing"],
724
- ttLabelEditing: ["type", Bt]
725
- };
726
- function Ut(r) {
727
- const t = r;
728
- return t ? t.tagName === "INPUT" || t.tagName === "TEXTAREA" || t.tagName === "SELECT" || t.isContentEditable : !1;
729
- }
730
- class Vt {
731
- static $inject = ["canvas", "commandStack", "selection", "modeling"];
732
- constructor(t, i, e, o) {
733
- (t.getContainer().ownerDocument ?? document).addEventListener("keydown", (s) => {
734
- if (Ut(s.target)) return;
735
- const a = s.ctrlKey || s.metaKey, c = s.key.toLowerCase();
736
- if (a && c === "z" && !s.shiftKey)
737
- s.preventDefault(), i.canUndo() && i.undo();
738
- else if (a && c === "z" && s.shiftKey || a && c === "y")
739
- s.preventDefault(), i.canRedo() && i.redo();
740
- else if (c === "delete" || c === "backspace") {
741
- const h = e.get();
742
- h.length && (s.preventDefault(), o.removeElements([...h]));
743
- }
744
- });
745
- }
746
- }
747
- const Gt = {
748
- __init__: ["ttKeyboard"],
749
- ttKeyboard: ["type", Vt]
750
- };
751
- function D(r) {
752
- return O(r) ? 0 : I(r) ? r.teamType === "enabling" ? 3 : r.teamType === "complicated-subsystem" ? 2 : 1 : C(r) ? 4 : 1;
753
- }
754
- class Ht {
755
- constructor(t, i, e) {
756
- this.canvas = i, this.elementRegistry = e, t.on("import.render.start", () => {
757
- this.importing = !0;
758
- }), t.on("import.render.done", () => {
759
- this.importing = !1, this.reorder();
760
- }), t.on("commandStack.changed", () => {
761
- this.importing || this.reorder();
762
- });
763
- }
764
- static $inject = ["eventBus", "canvas", "elementRegistry"];
765
- importing = !1;
766
- /** Re-append each element's graphics group in ascending tier order (back → front). */
767
- reorder() {
768
- const t = this.elementRegistry.getAll().filter($).sort(
769
- (i, e) => D(i) - D(e)
770
- );
771
- for (const i of t) {
772
- const o = this.canvas.getGraphics(i)?.parentNode, n = o?.parentNode;
773
- o && n && n.appendChild(o);
774
- }
775
- }
776
- }
777
- const Yt = {
778
- __init__: ["ttZOrder"],
779
- ttZOrder: ["type", Ht]
780
- };
781
- class he extends bt {
782
- _getModules() {
783
- return [
784
- ...super._getModules(),
785
- // diagram-js stock
786
- W,
787
- Z,
788
- q,
789
- J,
790
- // Team Topologies editor
791
- Mt,
792
- kt,
793
- Tt,
794
- zt,
795
- At,
796
- Kt,
797
- Gt,
798
- Yt
799
- ];
800
- }
801
- undo() {
802
- this.get("commandStack").undo();
803
- }
804
- redo() {
805
- this.get("commandStack").redo();
806
- }
807
- canUndo() {
808
- return this.get("commandStack").canUndo();
809
- }
810
- canRedo() {
811
- return this.get("commandStack").canRedo();
812
- }
813
- }
814
- export {
815
- he as Modeler,
816
- bt as NavigatedViewer,
817
- M as ROOT_ID,
818
- ut as TeamTopologiesRenderer,
819
- st as TtBaseViewer,
820
- Dt as TtContextPadProvider,
821
- at as TtElementFactory,
822
- yt as TtExporter,
823
- Et as TtFlatModelBehavior,
824
- gt as TtImporter,
825
- Vt as TtKeyboard,
826
- Bt as TtLabelEditing,
827
- xt as TtModeling,
828
- Ot as TtPaletteProvider,
829
- $t as TtRules,
830
- Ht as TtZOrder,
831
- wt as Viewer,
832
- Rt as flowIconSvg,
833
- Lt as interactionIconSvg,
834
- vt as ioModule,
835
- $ as isTtElement,
836
- O as isTtFlow,
837
- C as isTtInteraction,
838
- I as isTtTeam,
839
- rt as saveSVG,
840
- St as teamIconSvg,
841
- Tt as ttBehaviorsModule,
842
- At as ttContextPadModule,
843
- pt as ttDrawModule,
844
- Gt as ttKeyboardModule,
845
- Kt as ttLabelEditingModule,
846
- ct as ttModelModule,
847
- Mt as ttModelingModule,
848
- zt as ttPaletteModule,
849
- kt as ttRulesModule,
850
- Yt as ttZOrderModule
774
+ //#endregion
775
+ //#region src/zorder/TtZOrder.ts
776
+ function Oe(e) {
777
+ return x(e) ? 0 : y(e) ? e.teamType === "enabling" ? 3 : e.teamType === "complicated-subsystem" ? 2 : 1 : b(e) ? 4 : 1;
778
+ }
779
+ var ke = class {
780
+ canvas;
781
+ elementRegistry;
782
+ static $inject = [
783
+ "eventBus",
784
+ "canvas",
785
+ "elementRegistry"
786
+ ];
787
+ importing = !1;
788
+ constructor(e, t, n) {
789
+ this.canvas = t, this.elementRegistry = n, e.on("import.render.start", () => {
790
+ this.importing = !0;
791
+ }), e.on("import.render.done", () => {
792
+ this.importing = !1, this.reorder();
793
+ }), e.on("commandStack.changed", () => {
794
+ this.importing || this.reorder();
795
+ });
796
+ }
797
+ reorder() {
798
+ let e = this.elementRegistry.getAll().filter(v).sort((e, t) => Oe(e) - Oe(t));
799
+ for (let t of e) {
800
+ let e = this.canvas.getGraphics(t)?.parentNode, n = e?.parentNode;
801
+ e && n && n.appendChild(e);
802
+ }
803
+ }
804
+ }, $ = {
805
+ __init__: ["ttZOrder"],
806
+ ttZOrder: ["type", ke]
807
+ }, Ae = class extends I {
808
+ _getModules() {
809
+ return [
810
+ ...super._getModules(),
811
+ g,
812
+ ee,
813
+ te,
814
+ ne,
815
+ z,
816
+ V,
817
+ U,
818
+ X,
819
+ Se,
820
+ we,
821
+ De,
822
+ $
823
+ ];
824
+ }
825
+ undo() {
826
+ this.get("commandStack").undo();
827
+ }
828
+ redo() {
829
+ this.get("commandStack").redo();
830
+ }
831
+ canUndo() {
832
+ return this.get("commandStack").canUndo();
833
+ }
834
+ canRedo() {
835
+ return this.get("commandStack").canRedo();
836
+ }
851
837
  };
852
- //# sourceMappingURL=index.js.map
838
+ //#endregion
839
+ export { Ae as Modeler, I as NavigatedViewer, w as ROOT_ID, A as TeamTopologiesRenderer, E as TtBaseViewer, Q as TtContextPadProvider, D as TtElementFactory, N as TtExporter, H as TtFlatModelBehavior, M as TtImporter, Ee as TtKeyboard, Ce as TtLabelEditing, he as TtModeling, Y as TtPaletteProvider, B as TtRules, ke as TtZOrder, F as Viewer, K as flowIconSvg, q as interactionIconSvg, P as ioModule, v as isTtElement, x as isTtFlow, b as isTtInteraction, y as isTtTeam, C as saveSVG, G as teamIconSvg, U as ttBehaviorsModule, Se as ttContextPadModule, j as ttDrawModule, De as ttKeyboardModule, we as ttLabelEditingModule, O as ttModelModule, z as ttModelingModule, X as ttPaletteModule, V as ttRulesModule, $ as ttZOrderModule };
840
+
841
+ //# sourceMappingURL=index.js.map