@miragon/team-topologies-renderer 0.7.1 → 0.9.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.
Files changed (55) hide show
  1. package/README.md +37 -20
  2. package/dist/Modeler.d.ts +3 -2
  3. package/dist/Modeler.d.ts.map +1 -1
  4. package/dist/behaviors/TtAssociationBehavior.d.ts +9 -0
  5. package/dist/behaviors/TtAssociationBehavior.d.ts.map +1 -0
  6. package/dist/behaviors/index.d.ts +5 -1
  7. package/dist/behaviors/index.d.ts.map +1 -1
  8. package/dist/context-pad/TtContextPadProvider.d.ts +10 -1
  9. package/dist/context-pad/TtContextPadProvider.d.ts.map +1 -1
  10. package/dist/context-pad/index.d.ts +1 -1
  11. package/dist/context-pad/index.d.ts.map +1 -1
  12. package/dist/copy-paste/TtCopyPaste.d.ts +2 -1
  13. package/dist/copy-paste/TtCopyPaste.d.ts.map +1 -1
  14. package/dist/draw/TeamTopologiesRenderer.d.ts +4 -1
  15. package/dist/draw/TeamTopologiesRenderer.d.ts.map +1 -1
  16. package/dist/draw/icons.d.ts +3 -0
  17. package/dist/draw/icons.d.ts.map +1 -1
  18. package/dist/draw/index.d.ts +5 -1
  19. package/dist/draw/index.d.ts.map +1 -1
  20. package/dist/draw/label-layout.d.ts +28 -0
  21. package/dist/draw/label-layout.d.ts.map +1 -0
  22. package/dist/draw/palette-icons.d.ts +3 -0
  23. package/dist/draw/palette-icons.d.ts.map +1 -1
  24. package/dist/draw/styles.d.ts +1 -0
  25. package/dist/draw/styles.d.ts.map +1 -1
  26. package/dist/index.d.ts +5 -5
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +669 -308
  29. package/dist/index.js.map +1 -1
  30. package/dist/io/TtExporter.d.ts.map +1 -1
  31. package/dist/io/TtImporter.d.ts +3 -1
  32. package/dist/io/TtImporter.d.ts.map +1 -1
  33. package/dist/keyboard/TtKeyboard.d.ts +4 -1
  34. package/dist/keyboard/TtKeyboard.d.ts.map +1 -1
  35. package/dist/label-editing/TtLabelEditing.d.ts.map +1 -1
  36. package/dist/label-editing/index.d.ts +1 -1
  37. package/dist/label-editing/index.d.ts.map +1 -1
  38. package/dist/model/TtElementFactory.d.ts +12 -2
  39. package/dist/model/TtElementFactory.d.ts.map +1 -1
  40. package/dist/model/di-types.d.ts +13 -3
  41. package/dist/model/di-types.d.ts.map +1 -1
  42. package/dist/modeling/TtLayouter.d.ts +7 -0
  43. package/dist/modeling/TtLayouter.d.ts.map +1 -0
  44. package/dist/modeling/TtModeling.d.ts +12 -2
  45. package/dist/modeling/TtModeling.d.ts.map +1 -1
  46. package/dist/modeling/index.d.ts +6 -1
  47. package/dist/modeling/index.d.ts.map +1 -1
  48. package/dist/palette/TtPaletteProvider.d.ts +3 -1
  49. package/dist/palette/TtPaletteProvider.d.ts.map +1 -1
  50. package/dist/palette/index.d.ts +1 -1
  51. package/dist/palette/index.d.ts.map +1 -1
  52. package/dist/rules/TtRules.d.ts.map +1 -1
  53. package/dist/team-topologies.css +1 -1
  54. package/dist/zorder/TtZOrder.d.ts.map +1 -1
  55. package/package.json +6 -6
package/dist/index.js CHANGED
@@ -1,65 +1,84 @@
1
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
- import le from "diagram-js/lib/features/copy-paste";
19
- import ue from "diagram-js/lib/features/copy-paste/CopyPaste.js";
2
+ import { getMid as t } from "diagram-js/lib/layout/LayoutUtil";
3
+ import { ALL_INTERACTION_SPECS as n, ALL_TEAM_SPECS as r, ANNOTATION_SPEC as i, DOCUMENT_VERSION as a, FLOW_SPEC as o, INTERACTION_MODE_SPECS as s, TEAM_TYPE_SPECS as c, dashArray as l, newId as u } from "@miragon/team-topologies-schema-model";
4
+ import d from "diagram-js/lib/layout/CroppingConnectionDocking";
5
+ import f from "diagram-js/lib/draw/BaseRenderer";
6
+ import { append as p, attr as m, create as h } from "tiny-svg";
7
+ import g from "diagram-js/lib/features/selection";
8
+ import ee from "diagram-js/lib/navigation/zoomscroll";
9
+ import te from "diagram-js/lib/navigation/movecanvas";
10
+ import _ from "diagram-js/lib/features/lasso-tool";
11
+ import v from "diagram-js/lib/features/modeling";
12
+ import ne from "diagram-js/lib/features/move";
13
+ import re from "diagram-js/lib/features/outline";
14
+ import ie from "diagram-js/lib/features/resize";
15
+ import ae from "diagram-js/lib/layout/BaseLayouter";
16
+ import oe from "diagram-js/lib/features/rules";
17
+ import se from "diagram-js/lib/features/rules/RuleProvider";
18
+ import ce from "diagram-js/lib/command/CommandInterceptor";
19
+ import le from "diagram-js/lib/features/palette";
20
+ import ue from "diagram-js/lib/features/create";
21
+ import de from "diagram-js/lib/features/connect";
22
+ import fe from "diagram-js/lib/features/connection-preview";
23
+ import pe from "diagram-js/lib/features/context-pad";
24
+ import me from "diagram-js/lib/features/copy-paste";
25
+ import he from "diagram-js/lib/features/copy-paste/CopyPaste.js";
20
26
  //#region src/model/di-types.ts
21
- function _(e) {
22
- return typeof e == "object" && e ? e.ttKind : void 0;
23
- }
24
- function v(e) {
25
- return typeof _(e) == "string";
26
- }
27
+ var ge = /* @__PURE__ */ new Set([
28
+ "team",
29
+ "interaction",
30
+ "flow",
31
+ "annotation"
32
+ ]);
27
33
  function y(e) {
28
- return _(e) === "team";
34
+ return typeof e == "object" && e ? e.ttKind : void 0;
29
35
  }
30
36
  function b(e) {
31
- return _(e) === "interaction";
37
+ let t = y(e);
38
+ return t !== void 0 && ge.has(t);
32
39
  }
33
40
  function x(e) {
34
- return _(e) === "flow";
41
+ return y(e) === "team";
42
+ }
43
+ function S(e) {
44
+ return y(e) === "interaction";
45
+ }
46
+ function C(e) {
47
+ return y(e) === "flow";
48
+ }
49
+ function w(e) {
50
+ return y(e) === "annotation";
51
+ }
52
+ function T(e) {
53
+ return y(e) === "association";
35
54
  }
36
55
  //#endregion
37
56
  //#region src/io/saveSvg.ts
38
- var S = 40;
39
- function C(e, t) {
57
+ var E = 40;
58
+ function D(e, t) {
40
59
  let n = e.getContainer().querySelector("svg");
41
60
  if (!n) throw Error("No SVG found in the canvas container.");
42
61
  let r = Infinity, i = Infinity, a = -Infinity, o = -Infinity;
43
62
  for (let e of t.getAll()) {
44
- if (!v(e)) continue;
63
+ if (!b(e)) continue;
45
64
  let t = e;
46
65
  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);
47
66
  }
48
67
  Number.isFinite(r) || (r = 0, i = 0, a = 100, o = 100);
49
- let s = r - S, c = i - S, l = a - r + 80, u = o - i + 80, d = n.cloneNode(!0);
68
+ let s = r - E, c = i - E, l = a - r + 80, u = o - i + 80, d = n.cloneNode(!0);
50
69
  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)));
51
70
  let f = d.querySelector(".viewport");
52
71
  return f && f.removeAttribute("transform"), { svg: "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + new XMLSerializer().serializeToString(d) };
53
72
  }
54
73
  //#endregion
55
74
  //#region src/io/types.ts
56
- var w = "tt-root";
75
+ var O = "tt-root";
57
76
  //#endregion
58
77
  //#region src/TtBaseViewer.ts
59
- function T(e) {
78
+ function _e(e) {
60
79
  return typeof e == "number" ? `${e}px` : e;
61
80
  }
62
- var E = class {
81
+ var ve = class {
63
82
  _diagram;
64
83
  _container;
65
84
  _options;
@@ -68,7 +87,7 @@ var E = class {
68
87
  }
69
88
  _createContainer(e) {
70
89
  let t = e.container ?? document.createElement("div");
71
- 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;
90
+ return t.classList.add("tt-djs-container"), t.style.width = _e(e.width ?? "100%"), t.style.height = _e(e.height ?? (e.container ? "100%" : "600px")), t;
72
91
  }
73
92
  _ensureDiagram() {
74
93
  if (!this._diagram) {
@@ -120,7 +139,7 @@ var E = class {
120
139
  }
121
140
  }
122
141
  saveSVG() {
123
- return C(this.get("canvas"), this.get("elementRegistry"));
142
+ return D(this.get("canvas"), this.get("elementRegistry"));
124
143
  }
125
144
  _fit(e = 84, t = 56) {
126
145
  let n = this.get("canvas"), r = this.get("elementRegistry"), i = Infinity, a = Infinity, o = -Infinity, s = -Infinity;
@@ -157,7 +176,7 @@ var E = class {
157
176
  get container() {
158
177
  return this._container;
159
178
  }
160
- }, D = class {
179
+ }, ye = class {
161
180
  elementFactory;
162
181
  static $inject = ["elementFactory"];
163
182
  constructor(e) {
@@ -203,10 +222,30 @@ var E = class {
203
222
  ...e.label ? { ttLabel: e.label } : {}
204
223
  });
205
224
  }
225
+ createAnnotation(e) {
226
+ return this.elementFactory.createShape({
227
+ id: e.id,
228
+ x: e.position.x,
229
+ y: e.position.y,
230
+ width: e.size.width,
231
+ height: e.size.height,
232
+ ttKind: "annotation",
233
+ ...e.text ? { ttLabel: e.text } : {}
234
+ });
235
+ }
236
+ createAssociation(e, n) {
237
+ return this.elementFactory.createConnection({
238
+ id: `assoc_${e.id}`,
239
+ ttKind: "association",
240
+ source: e,
241
+ target: n,
242
+ waypoints: [t(e), t(n)]
243
+ });
244
+ }
206
245
  createNewTeam(e, t) {
207
- let n = o[e];
246
+ let n = c[e];
208
247
  return this.elementFactory.createShape({
209
- id: c("team"),
248
+ id: u("team"),
210
249
  width: n.defaultSize.width,
211
250
  height: n.defaultSize.height,
212
251
  ttKind: "team",
@@ -215,9 +254,9 @@ var E = class {
215
254
  });
216
255
  }
217
256
  createNewInteraction(e) {
218
- let t = a[e];
257
+ let t = s[e];
219
258
  return this.elementFactory.createShape({
220
- id: c("int"),
259
+ id: u("int"),
221
260
  width: t.defaultSize.width,
222
261
  height: t.defaultSize.height,
223
262
  ttKind: "interaction",
@@ -226,14 +265,29 @@ var E = class {
226
265
  }
227
266
  createNewFlow() {
228
267
  return this.elementFactory.createShape({
229
- id: c("flow"),
268
+ id: u("flow"),
269
+ width: o.defaultSize.width,
270
+ height: o.defaultSize.height,
271
+ ttKind: "flow",
272
+ ttLabel: o.label
273
+ });
274
+ }
275
+ createNewAnnotation(e) {
276
+ return this.elementFactory.createShape({
277
+ id: u("ann"),
230
278
  width: i.defaultSize.width,
231
279
  height: i.defaultSize.height,
232
- ttKind: "flow",
233
- ttLabel: i.label
280
+ ttKind: "annotation",
281
+ ...e ? { ttLabel: e } : {}
282
+ });
283
+ }
284
+ createNewAssociation() {
285
+ return this.elementFactory.createConnection({
286
+ id: u("assoc"),
287
+ ttKind: "association"
234
288
  });
235
289
  }
236
- }, O = { ttElementFactory: ["type", D] }, k = {
290
+ }, be = { ttElementFactory: ["type", ye] }, k = {
237
291
  blau: "#335DE5",
238
292
  blauLink: "#2B50D4",
239
293
  blauHell: "#6B8AFF",
@@ -250,60 +304,139 @@ var E = class {
250
304
  k.blau, k.gruen, k.grau, k.schwarz, k.weiss, k.blauLink, k.blauHell, k.success, k.warning, k.danger, k.info, k.gradientBrand;
251
305
  //#endregion
252
306
  //#region src/draw/styles.ts
253
- var de = 1500;
307
+ var xe = 1500;
254
308
  k.blau;
255
- var fe = k.schwarz, pe = "#5B5B5B", A = {
309
+ var Se = k.schwarz, A = "#5B5B5B", j = {
256
310
  family: "'Geist Variable', 'Geist', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif",
257
311
  label: 13.5,
258
- small: 11
312
+ small: 11,
313
+ annotation: 12
259
314
  };
260
315
  k.weiss;
261
316
  //#endregion
317
+ //#region src/draw/label-layout.ts
318
+ var M = 10, N = {
319
+ left: 10,
320
+ right: 6,
321
+ top: 6,
322
+ bottom: 6
323
+ }, P = 1.2;
324
+ function F(e, t) {
325
+ return Math.min(e * .16, t * 1.1);
326
+ }
327
+ function I(e) {
328
+ let t = Math.max(e.width, 1), n = Math.max(e.height, 1);
329
+ return w(e) ? {
330
+ box: {
331
+ x: N.left,
332
+ y: N.top,
333
+ width: Math.max(t - N.left - N.right, 1),
334
+ height: Math.max(n - N.top - N.bottom, 1)
335
+ },
336
+ align: "left-top",
337
+ fontSize: j.annotation,
338
+ fontWeight: "450",
339
+ fill: Se
340
+ } : C(e) ? {
341
+ box: {
342
+ x: M,
343
+ y: 0,
344
+ width: t - F(t, n) - 20,
345
+ height: n
346
+ },
347
+ align: "center",
348
+ fontSize: j.small,
349
+ fontWeight: "650",
350
+ letterSpacing: "0.06em",
351
+ fill: A
352
+ } : {
353
+ box: {
354
+ x: M,
355
+ y: 0,
356
+ width: t - 20,
357
+ height: n
358
+ },
359
+ align: "center",
360
+ fontSize: S(e) ? j.small : j.label,
361
+ fontWeight: S(e) ? "600" : "640",
362
+ fill: Se
363
+ };
364
+ }
365
+ function Ce(e, t, n) {
366
+ let r = Math.max(4, Math.floor(t / (n * .58))), i = e.split(/\r?\n/), a = [];
367
+ for (let e of i) {
368
+ let t = e.split(/\s+/).filter(Boolean), n = "";
369
+ for (let e of t) {
370
+ let t = n ? `${n} ${e}` : e;
371
+ t.length > r && n ? (a.push(n), n = e) : n = t;
372
+ }
373
+ a.push(n);
374
+ }
375
+ for (; a.length > 0 && a[a.length - 1] === "";) a.pop();
376
+ for (; a.length > 0 && a[0] === "";) a.shift();
377
+ return a;
378
+ }
379
+ //#endregion
262
380
  //#region src/draw/TeamTopologiesRenderer.ts
263
- var j = class extends l {
381
+ var L = class extends f {
264
382
  static $inject = ["eventBus"];
265
383
  constructor(e) {
266
- super(e, de);
384
+ super(e, xe);
267
385
  }
268
386
  canRender(e) {
269
- return v(e);
387
+ return b(e) || T(e);
270
388
  }
271
389
  drawShape(e, t) {
272
- if (y(t)) return this.drawTeam(e, t);
273
- if (b(t)) return this.drawInteraction(e, t);
274
- if (x(t)) return this.drawFlow(e, t);
275
- let n = d(f("rect"), {
390
+ if (x(t)) return this.drawTeam(e, t);
391
+ if (S(t)) return this.drawInteraction(e, t);
392
+ if (C(t)) return this.drawFlow(e, t);
393
+ if (w(t)) return this.drawAnnotation(e, t);
394
+ let n = m(h("rect"), {
276
395
  width: t.width,
277
396
  height: t.height,
278
397
  fill: "#eee"
279
398
  });
280
- return u(e, n), n;
399
+ return p(e, n), n;
400
+ }
401
+ drawConnection(e, t) {
402
+ let n = m(h("path"), {
403
+ d: R(t.waypoints),
404
+ fill: "none",
405
+ stroke: A,
406
+ "stroke-width": 1.5,
407
+ "stroke-dasharray": "4 4",
408
+ "stroke-linecap": "round"
409
+ });
410
+ return p(e, n), n;
281
411
  }
282
412
  getShapePath(e) {
283
413
  let { x: t, y: n, width: r, height: i } = e;
284
414
  return `M${t},${n}l${r},0l0,${i}l${-r},0z`;
285
415
  }
416
+ getConnectionPath(e) {
417
+ return R(e.waypoints);
418
+ }
286
419
  drawTeam(e, t) {
287
- 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, {
420
+ let n = c[t.teamType] ?? c["stream-aligned"], r = Math.max(t.width, 1), i = Math.max(t.height, 1), a = n.strokeWidth, o = l(n.strokeStyle, a), s = this.teamOutline(n.shape, r, i, a, {
288
421
  fill: t.fill ?? n.fill,
289
422
  stroke: t.stroke ?? n.stroke,
290
423
  "stroke-width": a,
291
- ...c ? { "stroke-dasharray": c } : {},
424
+ ...o ? { "stroke-dasharray": o } : {},
292
425
  "stroke-linejoin": "round"
293
426
  });
294
- return u(e, l), this.appendLabel(e, t.ttLabel ?? "", r, i, { "font-weight": "640" }), l;
427
+ return p(e, s), this.appendLabel(e, t.ttLabel ?? "", I(t)), s;
295
428
  }
296
429
  teamOutline(e, t, n, r, i) {
297
430
  let a = r / 2, o = t - r, s = n - r;
298
431
  if (e === "octagon") {
299
432
  let e = Math.min(o, s) * .29;
300
- return d(f("polygon"), {
301
- points: me(a, o, s, e),
433
+ return m(h("polygon"), {
434
+ points: we(a, o, s, e),
302
435
  ...i
303
436
  });
304
437
  }
305
438
  let c = e === "rect" ? 4 : Math.min(20, s / 2, o / 2);
306
- return d(f("rect"), {
439
+ return m(h("rect"), {
307
440
  x: a,
308
441
  y: a,
309
442
  width: o,
@@ -314,81 +447,85 @@ var j = class extends l {
314
447
  });
315
448
  }
316
449
  drawInteraction(e, t) {
317
- let n = a[t.mode] ?? a.collaboration, r = Math.max(t.width, 1), i = Math.max(t.height, 1), o = {
450
+ let n = s[t.mode] ?? s.collaboration, r = Math.max(t.width, 1), i = Math.max(t.height, 1), a = {
318
451
  fill: t.fill ?? n.fill,
319
452
  "fill-opacity": n.opacity,
320
453
  stroke: t.stroke ?? n.stroke,
321
454
  "stroke-width": 2,
322
- "stroke-dasharray": s(n.strokeStyle, 2) || "6 4",
455
+ "stroke-dasharray": l(n.strokeStyle, 2) || "6 4",
323
456
  "stroke-linejoin": "round"
324
- }, c;
325
- if (n.shape === "circle") c = d(f("ellipse"), {
457
+ }, o;
458
+ if (n.shape === "circle") o = m(h("ellipse"), {
326
459
  cx: r / 2,
327
460
  cy: i / 2,
328
461
  rx: (r - 2) / 2,
329
462
  ry: (i - 2) / 2,
330
- ...o
463
+ ...a
331
464
  });
332
465
  else if (n.shape === "triangle") {
333
466
  let e = `${r / 2},1 ${r - 1},${i - 1} 1,${i - 1}`;
334
- c = d(f("polygon"), {
467
+ o = m(h("polygon"), {
335
468
  points: e,
336
- ...o
469
+ ...a
337
470
  });
338
471
  } else {
339
472
  let e = Math.min(r * .26, i * .85), t = `${1 + e},1 ${r - 1},1 ${r - 1 - e},${i - 1} 1,${i - 1}`;
340
- c = d(f("polygon"), {
473
+ o = m(h("polygon"), {
341
474
  points: t,
342
- ...o
475
+ ...a
343
476
  });
344
477
  }
345
- return u(e, c), t.ttLabel && this.appendLabel(e, t.ttLabel, r, i, {
346
- "font-size": A.small,
347
- "font-weight": "600"
348
- }), c;
478
+ return p(e, o), this.appendLabel(e, t.ttLabel ?? "", I(t)), o;
349
479
  }
350
480
  drawFlow(e, t) {
351
- 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 = [
352
- [o, p],
353
- [n - c, p],
354
- [n - c, o],
355
- [n - o, r / 2],
356
- [n - c, r - o],
357
- [n - c, m],
358
- [o, m]
359
- ].map((e) => e.join(",")).join(" "), g = d(f("polygon"), {
360
- points: h,
481
+ let n = Math.max(t.width, 1), r = Math.max(t.height, 1), i = o.strokeWidth, a = i / 2, s = F(n, r), c = r * .5, u = (r - c) / 2, d = u + c, f = [
482
+ [a, u],
483
+ [n - s, u],
484
+ [n - s, a],
485
+ [n - a, r / 2],
486
+ [n - s, r - a],
487
+ [n - s, d],
488
+ [a, d]
489
+ ].map((e) => e.join(",")).join(" "), g = m(h("polygon"), {
490
+ points: f,
361
491
  fill: "none",
362
- stroke: i.stroke,
363
- "stroke-width": a,
364
- "stroke-dasharray": s(i.strokeStyle, a) || "6 4",
492
+ stroke: o.stroke,
493
+ "stroke-width": i,
494
+ "stroke-dasharray": l(o.strokeStyle, i) || "6 4",
495
+ "stroke-linejoin": "round"
496
+ });
497
+ return p(e, g), this.appendLabel(e, t.ttLabel ?? "", I(t)), g;
498
+ }
499
+ drawAnnotation(e, t) {
500
+ let n = Math.max(t.width, 1), r = Math.max(t.height, 1), i = 1.5, a = i / 2, o = Math.min(14, n / 2), s = m(h("path"), {
501
+ d: `M${o},${a} L${a},${a} L${a},${r - a} L${o},${r - a}`,
502
+ fill: "none",
503
+ stroke: A,
504
+ "stroke-width": i,
365
505
  "stroke-linejoin": "round"
366
506
  });
367
- return u(e, g), t.ttLabel && this.appendLabel(e, t.ttLabel, n - c, r, {
368
- "font-size": A.small,
369
- "font-weight": "650",
370
- "letter-spacing": "0.06em",
371
- fill: pe
372
- }), g;
373
- }
374
- appendLabel(e, t, n, r, i) {
375
- let a = typeof i["font-size"] == "number" ? i["font-size"] : A.label, o = he(t, n - 20, a), s = a * 1.2, c = r / 2 - (o.length - 1) * s / 2;
376
- o.forEach((t, r) => {
377
- let o = d(f("text"), {
378
- x: n / 2,
379
- y: c + r * s,
380
- "font-family": A.family,
381
- "font-size": a,
382
- fill: fe,
383
- "text-anchor": "middle",
507
+ return p(e, s), this.appendLabel(e, t.ttLabel ?? "", I(t)), s;
508
+ }
509
+ appendLabel(e, t, n) {
510
+ let { box: r, fontSize: i } = n, a = Ce(t, r.width, i), o = i * P, s = n.align === "center", c = s ? r.x + r.width / 2 : r.x, l = s ? r.y + r.height / 2 - (a.length - 1) * o / 2 : r.y + o / 2;
511
+ a.forEach((t, r) => {
512
+ if (!t) return;
513
+ let a = m(h("text"), {
514
+ x: c,
515
+ y: l + r * o,
516
+ "font-family": j.family,
517
+ "font-size": i,
518
+ fill: n.fill,
519
+ "text-anchor": s ? "middle" : "start",
384
520
  "dominant-baseline": "central",
385
- ...i
521
+ "font-weight": n.fontWeight,
522
+ ...n.letterSpacing ? { "letter-spacing": n.letterSpacing } : {}
386
523
  });
387
- o.textContent = t, u(e, o);
524
+ a.textContent = t, p(e, a);
388
525
  });
389
526
  }
390
527
  };
391
- function me(e, t, n, r) {
528
+ function we(e, t, n, r) {
392
529
  return [
393
530
  [e + r, e],
394
531
  [e + t - r, e],
@@ -400,36 +537,32 @@ function me(e, t, n, r) {
400
537
  [e, e + r]
401
538
  ].map((e) => e.join(",")).join(" ");
402
539
  }
403
- function he(e, t, n) {
404
- let r = Math.max(4, Math.floor(t / (n * .58))), i = e.split(/\s+/).filter(Boolean);
405
- if (i.length === 0) return [];
406
- let a = [], o = "";
407
- for (let e of i) {
408
- let t = o ? `${o} ${e}` : e;
409
- t.length > r && o ? (a.push(o), o = e) : o = t;
410
- }
411
- return o && a.push(o), a;
540
+ function R(e) {
541
+ return e.map((e, t) => `${t === 0 ? "M" : "L"}${e.x},${e.y}`).join(" ");
412
542
  }
413
543
  //#endregion
414
544
  //#region src/draw/index.ts
415
- var M = {
545
+ var z = {
416
546
  __init__: ["ttRenderer"],
417
- ttRenderer: ["type", j]
418
- }, N = class {
547
+ ttRenderer: ["type", L],
548
+ connectionDocking: ["type", d]
549
+ }, B = class {
419
550
  canvas;
420
551
  elementFactory;
421
552
  factory;
422
553
  eventBus;
423
554
  elementRegistry;
555
+ connectionDocking;
424
556
  static $inject = [
425
557
  "canvas",
426
558
  "elementFactory",
427
559
  "ttElementFactory",
428
560
  "eventBus",
429
- "elementRegistry"
561
+ "elementRegistry",
562
+ "connectionDocking"
430
563
  ];
431
- constructor(e, t, n, r, i) {
432
- this.canvas = e, this.elementFactory = t, this.factory = n, this.eventBus = r, this.elementRegistry = i;
564
+ constructor(e, t, n, r, i, a) {
565
+ this.canvas = e, this.elementFactory = t, this.factory = n, this.eventBus = r, this.elementRegistry = i, this.connectionDocking = a;
433
566
  }
434
567
  import(e) {
435
568
  let t = [];
@@ -441,18 +574,34 @@ var M = {
441
574
  n = void 0;
442
575
  }
443
576
  let r;
444
- n && n.id === "tt-root" ? r = n : (r = this.elementFactory.createRoot({ id: w }), this.canvas.setRootElement(r)), r.businessObject = { title: e.title };
577
+ n && n.id === "tt-root" ? r = n : (r = this.elementFactory.createRoot({ id: O }), this.canvas.setRootElement(r)), r.businessObject = { title: e.title };
445
578
  for (let t of e.flows) this.canvas.addShape(this.factory.createFlow(t), r);
446
579
  for (let t of e.nodes) this.canvas.addShape(this.factory.createTeam(t), r);
447
580
  for (let t of e.interactions) this.canvas.addShape(this.factory.createInteraction(t), r);
581
+ for (let t of e.annotations) this.canvas.addShape(this.factory.createAnnotation(t), r);
582
+ for (let n of e.annotations) {
583
+ if (!n.attachedTo) continue;
584
+ let e = this.elementRegistry.get(n.id), i = this.elementRegistry.get(n.attachedTo);
585
+ if (!b(i) || w(i)) {
586
+ t.push({
587
+ message: `Annotation "${n.id}" is attached to unknown element "${n.attachedTo}"; its connector was dropped.`,
588
+ elementId: n.id
589
+ });
590
+ continue;
591
+ }
592
+ let a = this.factory.createAssociation(e, i);
593
+ a.waypoints = this.connectionDocking.getCroppedWaypoints(a), this.canvas.addConnection(a, r);
594
+ }
448
595
  return this.eventBus.fire("import.render.done", { warnings: t }), t;
449
596
  }
450
597
  clear() {
451
- for (let e of [...this.elementRegistry.getAll()]) if (e.id !== "tt-root") try {
598
+ let e = this.elementRegistry.getAll().filter((e) => e.id !== O), t = e.filter((e) => "waypoints" in e), n = e.filter((e) => !("waypoints" in e));
599
+ for (let e of t) this.canvas.removeConnection(e.id);
600
+ for (let e of n) try {
452
601
  this.canvas.removeShape(e.id);
453
602
  } catch {}
454
603
  }
455
- }, P = class {
604
+ }, V = class {
456
605
  elementRegistry;
457
606
  canvas;
458
607
  static $inject = ["elementRegistry", "canvas"];
@@ -466,93 +615,121 @@ var M = {
466
615
  } catch {
467
616
  e = void 0;
468
617
  }
469
- let t = [], n = [], i = [];
618
+ let t = [], n = [], r = [], i = [];
470
619
  for (let e of this.elementRegistry.getAll()) {
471
620
  if (e.id === "tt-root") continue;
472
- let r = e, a = {
473
- x: r.x,
474
- y: r.y
475
- }, o = {
476
- width: r.width,
477
- height: r.height
621
+ let a = e, o = {
622
+ x: a.x,
623
+ y: a.y
624
+ }, s = {
625
+ width: a.width,
626
+ height: a.height
478
627
  };
479
- y(e) ? t.push({
628
+ if (x(e)) t.push({
480
629
  id: e.id,
481
630
  type: e.teamType,
482
631
  label: e.ttLabel ?? "",
483
- position: a,
484
- size: o,
632
+ position: o,
633
+ size: s,
485
634
  ...e.description ? { description: e.description } : {},
486
635
  ...e.fill ? { fill: e.fill } : {},
487
636
  ...e.stroke ? { stroke: e.stroke } : {}
488
- }) : b(e) ? n.push({
637
+ });
638
+ else if (S(e)) n.push({
489
639
  id: e.id,
490
640
  mode: e.mode,
491
- position: a,
492
- size: o,
641
+ position: o,
642
+ size: s,
493
643
  ...e.ttLabel ? { label: e.ttLabel } : {},
494
644
  ...e.fill ? { fill: e.fill } : {},
495
645
  ...e.stroke ? { stroke: e.stroke } : {}
496
- }) : x(e) && i.push({
646
+ });
647
+ else if (C(e)) r.push({
497
648
  id: e.id,
498
- position: a,
499
- size: o,
649
+ position: o,
650
+ size: s,
500
651
  ...e.ttLabel ? { label: e.ttLabel } : {}
501
652
  });
653
+ else if (w(e)) {
654
+ let t = Te(e);
655
+ i.push({
656
+ id: e.id,
657
+ text: e.ttLabel ?? "",
658
+ position: o,
659
+ size: s,
660
+ ...t ? { attachedTo: t } : {}
661
+ });
662
+ }
502
663
  }
503
664
  return {
504
- version: r,
665
+ version: a,
505
666
  title: e?.title ?? "Untitled team topology",
506
667
  nodes: t,
507
668
  interactions: n,
508
- flows: i
669
+ flows: r,
670
+ annotations: i
509
671
  };
510
672
  }
511
- }, F = {
512
- ttImporter: ["type", N],
513
- ttExporter: ["type", P]
514
- }, I = class extends E {
673
+ };
674
+ function Te(e) {
675
+ let t = [...e.outgoing, ...e.incoming].find(T);
676
+ if (t) return (t.source === e ? t.target : t.source)?.id;
677
+ }
678
+ //#endregion
679
+ //#region src/io/index.ts
680
+ var H = {
681
+ ttImporter: ["type", B],
682
+ ttExporter: ["type", V]
683
+ }, U = class extends ve {
515
684
  _getModules() {
516
685
  return [
517
- O,
518
- M,
519
- F
686
+ be,
687
+ z,
688
+ H
520
689
  ];
521
690
  }
522
- }, L = class extends I {
691
+ }, W = class extends U {
523
692
  _getModules() {
524
693
  return [
525
694
  ...super._getModules(),
526
- p,
527
- m,
528
- h
695
+ g,
696
+ ee,
697
+ te
529
698
  ];
530
699
  }
531
700
  };
532
701
  //#endregion
533
702
  //#region src/modeling/cmd/UpdatePropertiesHandler.ts
534
- function R(e, t, n) {
703
+ function G(e, t, n) {
535
704
  n === void 0 ? delete e[t] : e[t] = n;
536
705
  }
537
- var ge = class {
706
+ var Ee = class {
538
707
  execute(e) {
539
708
  let { element: t, properties: n } = e, r = t, i = {};
540
- for (let e of Object.keys(n)) i[e] = r[e], R(r, e, n[e]);
709
+ for (let e of Object.keys(n)) i[e] = r[e], G(r, e, n[e]);
541
710
  return e.oldProperties = i, [t];
542
711
  }
543
712
  revert(e) {
544
713
  let { element: t, oldProperties: n } = e, r = t;
545
- if (n) for (let e of Object.keys(n)) R(r, e, n[e]);
714
+ if (n) for (let e of Object.keys(n)) G(r, e, n[e]);
546
715
  return [t];
547
716
  }
548
- }, z = "element.updateProperties", B = class {
717
+ }, K = "element.updateProperties", q = 40, J = class {
549
718
  commandStack;
550
- static $inject = ["commandStack"];
551
- constructor(e) {
552
- this.commandStack = e, e.registerHandler(z, ge);
719
+ modeling;
720
+ factory;
721
+ canvas;
722
+ static $inject = [
723
+ "commandStack",
724
+ "modeling",
725
+ "ttElementFactory",
726
+ "canvas"
727
+ ];
728
+ constructor(e, t, n, r) {
729
+ this.commandStack = e, this.modeling = t, this.factory = n, this.canvas = r, e.registerHandler(K, Ee);
553
730
  }
554
731
  updateProperties(e, t) {
555
- this.commandStack.execute(z, {
732
+ this.commandStack.execute(K, {
556
733
  element: e,
557
734
  properties: t
558
735
  });
@@ -575,156 +752,278 @@ var ge = class {
575
752
  setDescription(e, t) {
576
753
  this.updateProperties(e, { description: t });
577
754
  }
578
- }, V = {
755
+ appendAnnotation(e) {
756
+ let t = this.factory.createNewAnnotation(), n = {
757
+ x: e.x + e.width + q + t.width / 2,
758
+ y: e.y - q / 4
759
+ };
760
+ return this.modeling.appendShape(e, t, n, this.canvas.getRootElement(), {
761
+ connection: this.factory.createNewAssociation(),
762
+ connectionTarget: e
763
+ });
764
+ }
765
+ detachAnnotation(e) {
766
+ let t = [...e.incoming, ...e.outgoing].filter(T);
767
+ t.length > 0 && this.modeling.removeElements(t);
768
+ }
769
+ }, Y = class extends ae {
770
+ layoutConnection(e, n = {}) {
771
+ let r = n.source ?? e.source, i = n.target ?? e.target;
772
+ return !r || !i ? super.layoutConnection(e, n) : [t(r), t(i)];
773
+ }
774
+ }, De = {
775
+ __depends__: [v],
579
776
  __init__: ["ttModeling"],
580
- ttModeling: ["type", B]
581
- }, H = class extends ie {
777
+ ttModeling: ["type", J],
778
+ layouter: ["type", Y]
779
+ };
780
+ //#endregion
781
+ //#region src/rules/TtRules.ts
782
+ function Oe(e) {
783
+ return b(e) && !w(e);
784
+ }
785
+ var ke = class extends se {
582
786
  static $inject = ["eventBus"];
583
787
  constructor(e) {
584
788
  super(e);
585
789
  }
586
790
  init() {
587
- this.addRule(["shape.move", "elements.move"], (e) => e.target && e.target.parent ? null : !0), this.addRule("shape.create", () => !0), this.addRule("shape.resize", () => !0), this.addRule("element.copy", () => !0);
791
+ this.addRule(["shape.move", "elements.move"], (e) => e.target && e.target.parent ? null : !0), this.addRule("shape.create", () => !0), this.addRule("shape.resize", () => !0), this.addRule("element.copy", () => !0), this.addRule("connection.create", ({ source: e, target: t }) => w(e) && Oe(t) || w(t) && Oe(e) ? { ttKind: "association" } : !1);
588
792
  }
589
- }, U = {
590
- __depends__: [re],
793
+ }, Ae = {
794
+ __depends__: [oe],
591
795
  __init__: ["ttRules"],
592
- ttRules: ["type", H]
593
- }, W = class extends ae {
796
+ ttRules: ["type", ke]
797
+ }, je = class extends ce {
594
798
  static $inject = ["eventBus", "canvas"];
595
799
  constructor(e, t) {
596
800
  super(e), this.preExecute(["shape.create", "elements.create"], (e) => {
597
801
  e.parent = t.getRootElement();
598
802
  }, !0);
599
803
  }
600
- }, _e = {
601
- __init__: ["ttFlatModelBehavior"],
602
- ttFlatModelBehavior: ["type", W]
804
+ }, Me = class extends ce {
805
+ static $inject = [
806
+ "eventBus",
807
+ "connectionDocking",
808
+ "modeling"
809
+ ];
810
+ constructor(e, t, n) {
811
+ super(e), this.executed(["connection.layout", "connection.create"], (e) => {
812
+ !e.cropped && T(e.connection) && (e.connection.waypoints = t.getCroppedWaypoints(e.connection), e.cropped = !0);
813
+ }, !0), this.reverted("connection.layout", (e) => {
814
+ delete e.cropped;
815
+ }, !0), this.postExecuted("connection.create", (e) => {
816
+ let t = e.connection;
817
+ if (!T(t)) return;
818
+ let r = w(t.source) ? t.source : t.target;
819
+ if (!w(r)) return;
820
+ let i = [...r.incoming, ...r.outgoing].filter((e) => e !== t && T(e));
821
+ i.length > 0 && n.removeElements(i);
822
+ }, !0);
823
+ }
824
+ }, Ne = {
825
+ __init__: ["ttFlatModelBehavior", "ttAssociationBehavior"],
826
+ ttFlatModelBehavior: ["type", je],
827
+ ttAssociationBehavior: ["type", Me]
603
828
  };
604
829
  //#endregion
605
830
  //#region src/draw/palette-icons.ts
606
- function G(e) {
831
+ function X(e) {
607
832
  return `<svg class="tt-palette-svg" width="24" height="24" viewBox="0 0 26 26" aria-hidden="true">${e}</svg>`;
608
833
  }
609
- function K(e) {
610
- 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}"` : "");
834
+ function Pe(e) {
835
+ let t = c[e], n = l(t.strokeStyle, 1.5), r = `fill="${t.fill}" stroke="${t.stroke}" stroke-width="1.5"` + (n ? ` stroke-dasharray="${n}"` : "");
611
836
  switch (t.shape) {
612
- case "octagon": return G(`<polygon points="8,3 18,3 23,8 23,18 18,23 8,23 3,18 3,8" ${r}/>`);
613
- case "rounded-rect-vertical": return G(`<rect x="8" y="3" width="10" height="20" rx="4" ${r}/>`);
614
- case "rect": return G(`<rect x="3" y="7" width="20" height="12" rx="1.5" ${r}/>`);
615
- default: return G(`<rect x="3" y="8" width="20" height="10" rx="5" ${r}/>`);
837
+ case "octagon": return X(`<polygon points="8,3 18,3 23,8 23,18 18,23 8,23 3,18 3,8" ${r}/>`);
838
+ case "rounded-rect-vertical": return X(`<rect x="8" y="3" width="10" height="20" rx="4" ${r}/>`);
839
+ case "rect": return X(`<rect x="3" y="7" width="20" height="12" rx="1.5" ${r}/>`);
840
+ default: return X(`<rect x="3" y="8" width="20" height="10" rx="5" ${r}/>`);
616
841
  }
617
842
  }
618
- function q() {
619
- return G("<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>");
843
+ function Fe() {
844
+ return X("<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>");
845
+ }
846
+ function Ie() {
847
+ return X(`<g fill="none" stroke="${A}" stroke-width="1.5" stroke-linecap="round"><path d="M10 4H5v18h5"/><path d="M13 9h9M13 13h9M13 17h6"/></g>`);
620
848
  }
621
- function J(e) {
622
- 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}"` : "");
849
+ function Le() {
850
+ return X("<rect x=\"3\" y=\"3\" width=\"16\" height=\"13\" rx=\"1.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-dasharray=\"3 2\"/><path d=\"M14 12l9 3.6-3.8 1.4-1.4 3.8z\" fill=\"currentColor\"/>");
851
+ }
852
+ function Re(e) {
853
+ let t = s[e], n = l(t.strokeStyle, 1.5), r = `fill="${t.fill}" fill-opacity="${t.opacity}" stroke="${t.stroke}" stroke-width="1.5"` + (n ? ` stroke-dasharray="${n}"` : "");
623
854
  switch (t.shape) {
624
- case "circle": return G(`<circle cx="13" cy="13" r="9" ${r}/>`);
625
- case "triangle": return G(`<polygon points="5,6 22,13 5,20" ${r}/>`);
626
- default: return G(`<polygon points="9,6 23,6 17,20 3,20" ${r}/>`);
855
+ case "circle": return X(`<circle cx="13" cy="13" r="9" ${r}/>`);
856
+ case "triangle": return X(`<polygon points="5,6 22,13 5,20" ${r}/>`);
857
+ default: return X(`<polygon points="9,6 23,6 17,20 3,20" ${r}/>`);
627
858
  }
628
859
  }
629
860
  //#endregion
630
861
  //#region src/palette/TtPaletteProvider.ts
631
- var ve = "tt-1-teams", ye = "tt-2-modes", be = "tt-3-flow";
632
- function Y(e, t) {
633
- return `<div class="entry tt-palette-entry" draggable="true" title="${t}">${e}</div>`;
862
+ var ze = "tools", Be = "tt-1-teams", Ve = "tt-2-modes", He = "tt-3-guides";
863
+ function Z(e, t, n = !0) {
864
+ return `<div class="entry tt-palette-entry" draggable="${n}" title="${t}">${e}</div>`;
634
865
  }
635
- var X = class {
866
+ var Ue = class {
636
867
  create;
637
868
  factory;
869
+ lassoTool;
638
870
  static $inject = [
639
871
  "palette",
640
872
  "create",
641
- "ttElementFactory"
873
+ "ttElementFactory",
874
+ "lassoTool"
642
875
  ];
643
- constructor(e, t, n) {
644
- this.create = t, this.factory = n, e.registerProvider(this);
876
+ constructor(e, t, n, r) {
877
+ this.create = t, this.factory = n, this.lassoTool = r, e.registerProvider(this);
645
878
  }
646
879
  getPaletteEntries() {
647
- let e = {};
648
- for (let t of n) {
880
+ let e = {}, t = "Select several elements (or Shift + drag on the canvas)";
881
+ e["lasso-tool"] = {
882
+ group: ze,
883
+ title: t,
884
+ html: Z(Le(), t, !1),
885
+ action: { click: (e) => this.lassoTool.activateSelection(e) }
886
+ };
887
+ for (let t of r) {
649
888
  let n = (e) => this.create.start(e, this.factory.createNewTeam(t.type, t.label));
650
889
  e[`team.${t.type}`] = {
651
- group: ve,
890
+ group: Be,
652
891
  title: `${t.label} team — ${t.description}`,
653
- html: Y(K(t.type), `${t.label} team — ${t.description}`),
892
+ html: Z(Pe(t.type), `${t.label} team — ${t.description}`),
654
893
  action: {
655
894
  dragstart: n,
656
895
  click: n
657
896
  }
658
897
  };
659
898
  }
660
- for (let n of t) {
661
- let t = (e) => this.create.start(e, this.factory.createNewInteraction(n.mode));
662
- e[`mode.${n.mode}`] = {
663
- group: ye,
664
- title: `${n.label} — ${n.description} (place over the teams it relates to)`,
665
- html: Y(J(n.mode), `${n.label} — ${n.description}`),
899
+ for (let t of n) {
900
+ let n = (e) => this.create.start(e, this.factory.createNewInteraction(t.mode));
901
+ e[`mode.${t.mode}`] = {
902
+ group: Ve,
903
+ title: `${t.label} — ${t.description} (place over the teams it relates to)`,
904
+ html: Z(Re(t.mode), `${t.label} — ${t.description}`),
666
905
  action: {
667
- dragstart: t,
668
- click: t
906
+ dragstart: n,
907
+ click: n
669
908
  }
670
909
  };
671
910
  }
672
- let r = (e) => this.create.start(e, this.factory.createNewFlow());
673
- return e.flow = {
674
- group: be,
675
- title: `${i.label} — the implied left-to-right flow`,
676
- html: Y(q(), i.label),
911
+ let a = (e) => this.create.start(e, this.factory.createNewFlow());
912
+ e.flow = {
913
+ group: He,
914
+ title: `${o.label} — the implied left-to-right flow`,
915
+ html: Z(Fe(), o.label),
677
916
  action: {
678
- dragstart: r,
679
- click: r
917
+ dragstart: a,
918
+ click: a
919
+ }
920
+ };
921
+ let s = (e) => this.create.start(e, this.factory.createNewAnnotation()), c = `${i.label} — a free-text note beside the diagram`;
922
+ return e.annotation = {
923
+ group: He,
924
+ title: c,
925
+ html: Z(Ie(), c),
926
+ action: {
927
+ dragstart: s,
928
+ click: s
680
929
  }
681
930
  }, e;
682
931
  }
683
- }, Z = {
684
- __depends__: [oe, se],
932
+ }, We = {
933
+ __depends__: [
934
+ le,
935
+ ue,
936
+ _
937
+ ],
685
938
  __init__: ["ttPaletteProvider"],
686
- ttPaletteProvider: ["type", X]
687
- }, xe = "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", Se = "M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z";
688
- function Ce(e, t = 18) {
939
+ ttPaletteProvider: ["type", Ue]
940
+ }, Ge = "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", Ke = "M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z", qe = "M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z", Je = "M4 3h5v2H6v14h3v2H4V3zm7 4h9v2h-9V7zm0 4h9v2h-9v-2zm0 4h6v2h-6v-2z";
941
+ function Ye(e, t = 18) {
689
942
  return `<svg width="${t}" height="${t}" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="${e}"/></svg>`;
690
943
  }
691
944
  //#endregion
692
945
  //#region src/context-pad/TtContextPadProvider.ts
693
946
  function Q(e, t) {
694
- return `<div class="entry tt-cp-entry" title="${t}">${Ce(e)}</div>`;
947
+ return `<div class="entry tt-cp-entry" title="${t}">${Ye(e)}</div>`;
695
948
  }
696
- var we = class {
949
+ var Xe = class {
697
950
  modeling;
951
+ ttModeling;
698
952
  labelEditing;
953
+ connect;
954
+ selection;
699
955
  static $inject = [
700
956
  "contextPad",
701
957
  "modeling",
702
- "ttLabelEditing"
958
+ "ttModeling",
959
+ "ttLabelEditing",
960
+ "connect",
961
+ "selection"
703
962
  ];
704
- constructor(e, t, n) {
705
- this.modeling = t, this.labelEditing = n, e.registerProvider(this);
963
+ constructor(e, t, n, r, i, a) {
964
+ this.modeling = t, this.ttModeling = n, this.labelEditing = r, this.connect = i, this.selection = a, e.registerProvider(this);
706
965
  }
707
966
  getContextPadEntries(e) {
708
- return v(e) ? {
709
- "edit-label": {
967
+ if (T(e)) return { delete: this.deleteEntry([e], "Remove connector") };
968
+ if (!b(e)) return {};
969
+ if (w(e)) {
970
+ let t = (t) => this.connect.start(t, e);
971
+ return {
972
+ "edit-label": this.editEntry(e, "Edit text"),
973
+ connect: {
974
+ group: "edit",
975
+ title: "Attach to an element",
976
+ html: Q(qe, "Attach to an element"),
977
+ action: {
978
+ click: t,
979
+ dragstart: t
980
+ }
981
+ },
982
+ delete: this.deleteEntry([e], "Delete")
983
+ };
984
+ }
985
+ return {
986
+ "edit-label": this.editEntry(e, "Rename"),
987
+ "append-annotation": {
710
988
  group: "edit",
711
- title: "Rename",
712
- html: Q(xe, "Rename"),
713
- action: { click: () => this.labelEditing.activate(e) }
989
+ title: "Add annotation",
990
+ html: Q(Je, "Add annotation"),
991
+ action: { click: () => {
992
+ let t = this.ttModeling.appendAnnotation(e);
993
+ this.selection.select(t), this.labelEditing.activate(t);
994
+ } }
714
995
  },
715
- delete: {
716
- group: "edit",
717
- title: "Delete",
718
- html: Q(Se, "Delete"),
719
- action: { click: () => this.modeling.removeElements([e]) }
720
- }
721
- } : {};
996
+ delete: this.deleteEntry([e], "Delete")
997
+ };
998
+ }
999
+ getMultiElementContextPadEntries(e) {
1000
+ return { delete: this.deleteEntry(e, `Delete ${e.length} elements`) };
1001
+ }
1002
+ editEntry(e, t) {
1003
+ return {
1004
+ group: "edit",
1005
+ title: t,
1006
+ html: Q(Ge, t),
1007
+ action: { click: () => this.labelEditing.activate(e) }
1008
+ };
1009
+ }
1010
+ deleteEntry(e, t) {
1011
+ return {
1012
+ group: "edit",
1013
+ title: t,
1014
+ html: Q(Ke, t),
1015
+ action: { click: () => this.modeling.removeElements([...e]) }
1016
+ };
722
1017
  }
723
- }, Te = {
724
- __depends__: [ce],
1018
+ }, Ze = {
1019
+ __depends__: [
1020
+ pe,
1021
+ de,
1022
+ fe
1023
+ ],
725
1024
  __init__: ["ttContextPadProvider"],
726
- ttContextPadProvider: ["type", we]
727
- }, Ee = class {
1025
+ ttContextPadProvider: ["type", Xe]
1026
+ }, $ = "tt-label-editing", Qe = 96, $e = class {
728
1027
  canvas;
729
1028
  modeling;
730
1029
  static $inject = [
@@ -735,82 +1034,133 @@ var we = class {
735
1034
  active = null;
736
1035
  constructor(e, t, n) {
737
1036
  this.canvas = t, this.modeling = n, e.on("element.dblclick", (e) => {
738
- v(e.element) && this.activate(e.element);
1037
+ b(e.element) && this.activate(e.element);
739
1038
  }), e.on([
740
1039
  "element.mousedown",
741
1040
  "drag.init",
742
1041
  "canvas.viewbox.changing"
743
- ], () => this.active?.commit());
1042
+ ], () => this.active?.commit()), e.on("import.render.start", () => this.cancel());
744
1043
  }
745
1044
  activate(e) {
746
1045
  this.active?.commit();
747
- 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 - 85, s = (a - r.y) * n - 14, c = document.createElement("input");
748
- 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();
749
- let l = !1, u = () => {
750
- l || (l = !0, c.removeEventListener("keydown", f), c.removeEventListener("blur", p), c.remove(), this.active = null);
751
- }, d = () => {
752
- if (l) return;
753
- let t = c.value.trim(), n = t !== (e.ttLabel ?? "");
754
- u(), n && this.modeling.updateLabel(e, t);
755
- }, f = (e) => {
756
- e.key === "Enter" ? (e.preventDefault(), d()) : e.key === "Escape" && (e.preventDefault(), u());
757
- }, p = () => d();
758
- c.addEventListener("keydown", f), c.addEventListener("blur", p), this.active = {
759
- commit: d,
760
- cleanup: u
1046
+ let t = I(e), n = t.align === "center", r = this.canvas.zoom(), i = this.canvas.viewbox(), a = n ? Math.max(t.box.width, Qe) : t.box.width, o = e.x + t.box.x + (t.box.width - a) / 2, s = (e.y + t.box.y - i.y) * r, c = t.box.height * r, l = document.createElement("textarea");
1047
+ l.className = "tt-label-editor", l.value = e.ttLabel ?? "", l.rows = 1, l.setAttribute("aria-label", w(e) ? "Annotation text" : "Label"), Object.assign(l.style, {
1048
+ left: `${(o - i.x) * r}px`,
1049
+ width: `${a * r}px`,
1050
+ fontFamily: j.family,
1051
+ fontSize: `${t.fontSize * r}px`,
1052
+ fontWeight: t.fontWeight,
1053
+ letterSpacing: t.letterSpacing ?? "normal",
1054
+ lineHeight: String(P),
1055
+ color: t.fill,
1056
+ textAlign: n ? "center" : "left"
1057
+ });
1058
+ let u = () => {
1059
+ l.style.height = "0px";
1060
+ let e = l.scrollHeight;
1061
+ l.style.height = `${n ? e : Math.max(e, c)}px`, l.style.top = `${n ? s + (c - e) / 2 : s}px`;
1062
+ };
1063
+ this.canvas.getContainer().appendChild(l), this.canvas.addMarker(e, $), u(), l.focus(), l.select();
1064
+ let d = !1, f = () => {
1065
+ d || (d = !0, l.removeEventListener("keydown", m), l.removeEventListener("input", u), l.removeEventListener("blur", h), l.remove(), this.canvas.removeMarker(e, $), this.active = null);
1066
+ }, p = () => {
1067
+ if (d) return;
1068
+ let t = l.value.trim(), n = t !== (e.ttLabel ?? "");
1069
+ f(), n && this.modeling.updateLabel(e, t);
1070
+ }, m = (e) => {
1071
+ e.key === "Enter" && !e.shiftKey && !e.isComposing ? (e.preventDefault(), p()) : e.key === "Escape" && (e.preventDefault(), f());
1072
+ }, h = () => p();
1073
+ l.addEventListener("keydown", m), l.addEventListener("input", u), l.addEventListener("blur", h), this.active = {
1074
+ commit: p,
1075
+ cleanup: f
761
1076
  };
762
1077
  }
763
1078
  cancel() {
764
1079
  this.active?.cleanup();
765
1080
  }
766
- }, De = {
1081
+ }, et = {
767
1082
  __init__: ["ttLabelEditing"],
768
- ttLabelEditing: ["type", Ee]
1083
+ ttLabelEditing: ["type", $e]
1084
+ }, tt = 1, nt = 10, rt = {
1085
+ ArrowLeft: {
1086
+ x: -1,
1087
+ y: 0
1088
+ },
1089
+ ArrowRight: {
1090
+ x: 1,
1091
+ y: 0
1092
+ },
1093
+ ArrowUp: {
1094
+ x: 0,
1095
+ y: -1
1096
+ },
1097
+ ArrowDown: {
1098
+ x: 0,
1099
+ y: 1
1100
+ }
769
1101
  };
770
- //#endregion
771
- //#region src/keyboard/TtKeyboard.ts
772
- function Oe(e) {
1102
+ function it(e) {
773
1103
  let t = e;
774
1104
  return t ? t.tagName === "INPUT" || t.tagName === "TEXTAREA" || t.tagName === "SELECT" || t.isContentEditable : !1;
775
1105
  }
776
- var ke = class {
1106
+ function at(e) {
1107
+ return !("waypoints" in e);
1108
+ }
1109
+ var ot = class {
777
1110
  static $inject = [
1111
+ "eventBus",
778
1112
  "canvas",
1113
+ "elementRegistry",
779
1114
  "commandStack",
780
1115
  "selection",
781
1116
  "modeling",
782
- "copyPaste"
1117
+ "copyPaste",
1118
+ "rules"
783
1119
  ];
784
- constructor(e, t, n, r, i) {
785
- (e.getContainer().ownerDocument ?? document).addEventListener("keydown", (e) => {
786
- if (Oe(e.target)) return;
787
- let a = e.ctrlKey || e.metaKey, o = e.key.toLowerCase();
788
- if (a && o === "z" && !e.shiftKey) e.preventDefault(), t.canUndo() && t.undo();
789
- else if (a && o === "z" && e.shiftKey || a && o === "y") e.preventDefault(), t.canRedo() && t.redo();
790
- else if (o === "delete" || o === "backspace") {
791
- let t = n.get();
792
- t.length && (e.preventDefault(), r.removeElements([...t]));
793
- } else if (a && o === "c") {
794
- let t = n.get();
795
- t.length && (e.preventDefault(), i.copy(t));
796
- } else a && o === "v" && (e.preventDefault(), i.paste());
797
- });
1120
+ constructor(e, t, n, r, i, a, o, s) {
1121
+ let c = t.getContainer().ownerDocument ?? document, l = (e) => {
1122
+ if (it(e.target)) return;
1123
+ let t = e.ctrlKey || e.metaKey, c = e.key.toLowerCase();
1124
+ if (t && c === "z" && !e.shiftKey) e.preventDefault(), r.canUndo() && r.undo();
1125
+ else if (t && c === "z" && e.shiftKey || t && c === "y") e.preventDefault(), r.canRedo() && r.redo();
1126
+ else if (c === "delete" || c === "backspace") {
1127
+ let t = i.get();
1128
+ t.length && (e.preventDefault(), a.removeElements([...t]));
1129
+ } else if (t && c === "c") {
1130
+ let t = i.get();
1131
+ t.length && (e.preventDefault(), o.copy(t));
1132
+ } else if (t && c === "v") e.preventDefault(), o.paste();
1133
+ else if (t && c === "a") e.preventDefault(), i.select(n.filter((e) => !!e.parent));
1134
+ else if (!t && !e.altKey && Object.hasOwn(rt, e.key)) {
1135
+ let t = i.get().filter(at);
1136
+ if (!t.length || !s.allowed("elements.move", { shapes: t })) return;
1137
+ e.preventDefault();
1138
+ let n = rt[e.key], r = e.shiftKey ? nt : tt;
1139
+ a.moveElements(t, {
1140
+ x: n.x * r,
1141
+ y: n.y * r
1142
+ });
1143
+ }
1144
+ };
1145
+ c.addEventListener("keydown", l), e.on("diagram.destroy", () => c.removeEventListener("keydown", l));
798
1146
  }
799
- }, Ae = {
1147
+ }, st = {
800
1148
  __init__: ["ttKeyboard"],
801
- ttKeyboard: ["type", ke]
1149
+ ttKeyboard: ["type", ot]
802
1150
  };
803
1151
  //#endregion
804
1152
  //#region src/copy-paste/TtCopyPaste.ts
805
- function je(e) {
1153
+ function ct(e) {
806
1154
  switch (e) {
807
1155
  case "team": return "team";
808
1156
  case "interaction": return "int";
809
1157
  case "flow": return "flow";
1158
+ case "annotation": return "ann";
1159
+ case "association": return "assoc";
810
1160
  default: return;
811
1161
  }
812
1162
  }
813
- var Me = class extends ue {
1163
+ var lt = class extends he {
814
1164
  elementFactory;
815
1165
  static $inject = [
816
1166
  "canvas",
@@ -825,14 +1175,21 @@ var Me = class extends ue {
825
1175
  constructor(e, t, n, r, i, a, o, s) {
826
1176
  super(e, t, n, r, i, a, o, s), this.elementFactory = r;
827
1177
  }
1178
+ createConnection(e) {
1179
+ let t = ct(e.ttKind);
1180
+ return t ? this.elementFactory.createConnection({
1181
+ ...e,
1182
+ id: u(t)
1183
+ }) : super.createConnection(e);
1184
+ }
828
1185
  createShape(e) {
829
- let t = je(e.ttKind);
1186
+ let t = ct(e.ttKind);
830
1187
  return t ? this.elementFactory.createShape({
831
1188
  ...e,
832
- id: c(t)
1189
+ id: u(t)
833
1190
  }) : super.createShape(e);
834
1191
  }
835
- }, Ne = [
1192
+ }, ut = [
836
1193
  "ttKind",
837
1194
  "teamType",
838
1195
  "mode",
@@ -840,28 +1197,31 @@ var Me = class extends ue {
840
1197
  "description",
841
1198
  "fill",
842
1199
  "stroke"
843
- ], Pe = {
844
- __depends__: [le],
1200
+ ], dt = {
1201
+ __depends__: [me],
845
1202
  __init__: ["ttCopyPasteProps"],
846
- copyPaste: ["type", Me],
1203
+ copyPaste: ["type", lt],
847
1204
  ttCopyPasteProps: ["type", class {
848
1205
  static $inject = ["eventBus"];
849
1206
  constructor(e) {
850
1207
  e.on("copyPaste.copyElement", (e) => {
851
1208
  let { descriptor: t, element: n } = e;
852
- if (!v(n)) return;
1209
+ if (!b(n) && !T(n)) return;
853
1210
  let r = n;
854
- for (let e of Ne) r[e] !== void 0 && (t[e] = r[e]);
1211
+ for (let e of ut) r[e] !== void 0 && (t[e] = r[e]);
855
1212
  });
856
1213
  }
857
1214
  }]
858
1215
  };
859
1216
  //#endregion
860
1217
  //#region src/zorder/TtZOrder.ts
861
- function Fe(e) {
862
- return x(e) ? 0 : y(e) ? e.teamType === "enabling" ? 3 : e.teamType === "complicated-subsystem" ? 2 : 1 : b(e) ? 4 : 1;
1218
+ function ft(e) {
1219
+ return C(e) ? 0 : x(e) ? e.teamType === "enabling" ? 3 : e.teamType === "complicated-subsystem" ? 2 : 1 : S(e) ? 4 : w(e) ? 5 : T(e) ? 6 : 1;
1220
+ }
1221
+ function pt(e) {
1222
+ return b(e) || T(e);
863
1223
  }
864
- var Ie = class {
1224
+ var mt = class {
865
1225
  canvas;
866
1226
  elementRegistry;
867
1227
  static $inject = [
@@ -880,32 +1240,33 @@ var Ie = class {
880
1240
  });
881
1241
  }
882
1242
  reorder() {
883
- let e = this.elementRegistry.getAll().filter(v).sort((e, t) => Fe(e) - Fe(t));
1243
+ let e = this.elementRegistry.getAll().filter(pt).sort((e, t) => ft(e) - ft(t));
884
1244
  for (let t of e) {
885
1245
  let e = this.canvas.getGraphics(t)?.parentNode, n = e?.parentNode;
886
1246
  e && n && n.appendChild(e);
887
1247
  }
888
1248
  }
889
- }, $ = {
1249
+ }, ht = {
890
1250
  __init__: ["ttZOrder"],
891
- ttZOrder: ["type", Ie]
892
- }, Le = class extends L {
1251
+ ttZOrder: ["type", mt]
1252
+ }, gt = class extends W {
893
1253
  _getModules() {
894
1254
  return [
895
1255
  ...super._getModules(),
896
- g,
897
- ee,
898
- te,
1256
+ v,
1257
+ _,
899
1258
  ne,
900
- V,
901
- U,
902
- _e,
903
- Z,
904
- Te,
1259
+ re,
1260
+ ie,
905
1261
  De,
906
1262
  Ae,
907
- Pe,
908
- $
1263
+ Ne,
1264
+ We,
1265
+ Ze,
1266
+ et,
1267
+ st,
1268
+ dt,
1269
+ ht
909
1270
  ];
910
1271
  }
911
1272
  undo() {
@@ -922,6 +1283,6 @@ var Ie = class {
922
1283
  }
923
1284
  };
924
1285
  //#endregion
925
- export { Le as Modeler, L as NavigatedViewer, w as ROOT_ID, j as TeamTopologiesRenderer, E as TtBaseViewer, we as TtContextPadProvider, D as TtElementFactory, P as TtExporter, W as TtFlatModelBehavior, N as TtImporter, ke as TtKeyboard, Ee as TtLabelEditing, B as TtModeling, X as TtPaletteProvider, H as TtRules, Ie as TtZOrder, I as Viewer, q as flowIconSvg, J as interactionIconSvg, F as ioModule, v as isTtElement, x as isTtFlow, b as isTtInteraction, y as isTtTeam, C as saveSVG, K as teamIconSvg, _e as ttBehaviorsModule, Te as ttContextPadModule, M as ttDrawModule, Ae as ttKeyboardModule, De as ttLabelEditingModule, O as ttModelModule, V as ttModelingModule, Z as ttPaletteModule, U as ttRulesModule, $ as ttZOrderModule };
1286
+ export { gt as Modeler, W as NavigatedViewer, O as ROOT_ID, L as TeamTopologiesRenderer, Me as TtAssociationBehavior, ve as TtBaseViewer, Xe as TtContextPadProvider, ye as TtElementFactory, V as TtExporter, je as TtFlatModelBehavior, B as TtImporter, ot as TtKeyboard, $e as TtLabelEditing, Y as TtLayouter, J as TtModeling, Ue as TtPaletteProvider, ke as TtRules, mt as TtZOrder, U as Viewer, Ie as annotationIconSvg, Fe as flowIconSvg, Re as interactionIconSvg, H as ioModule, w as isTtAnnotation, T as isTtAssociation, b as isTtElement, C as isTtFlow, S as isTtInteraction, x as isTtTeam, D as saveSVG, Pe as teamIconSvg, Ne as ttBehaviorsModule, Ze as ttContextPadModule, z as ttDrawModule, st as ttKeyboardModule, et as ttLabelEditingModule, be as ttModelModule, De as ttModelingModule, We as ttPaletteModule, Ae as ttRulesModule, ht as ttZOrderModule };
926
1287
 
927
1288
  //# sourceMappingURL=index.js.map