@html-graph/html-graph 0.0.43 → 0.0.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -29,26 +29,26 @@ This library fits for tasks where easy nodes customization and interactiveness a
29
29
  ## Getting started:
30
30
 
31
31
  ```
32
- npm i @html-graph/core
32
+ npm i @html-graph/html-graph
33
33
  ```
34
34
 
35
35
  ```typescript
36
- import { ApiPortPayload, CanvasBuilder } from "@html-graph/html-graph";
36
+ import { MarkPortRequest, CanvasBuilder } from "@html-graph/html-graph";
37
37
 
38
38
  const canvas = new CanvasBuilder()
39
- .options({
39
+ .setOptions({
40
40
  background: { type: "dots" },
41
41
  connections: { hasTargetArrow: true },
42
42
  })
43
- .draggableNodes()
44
- .transformableCanvas()
43
+ .setDraggableNodes()
44
+ .setTransformableCanvas()
45
45
  .build();
46
46
 
47
47
  function createNode(
48
48
  name: string,
49
49
  frontPortId: string,
50
50
  backPortId: string,
51
- ): [HTMLElement, Record<string, ApiPortPayload>] {
51
+ ): [HTMLElement, Record<string, MarkPortRequest>] {
52
52
  const node = document.createElement("div");
53
53
  node.classList.add("node");
54
54
 
package/dist/main.d.ts CHANGED
@@ -1,10 +1,19 @@
1
- export declare interface ApiConnection {
1
+ export declare interface AddConnectionRequest {
2
2
  id?: string;
3
3
  from: string;
4
4
  to: string;
5
5
  options?: ConnectionOptions;
6
6
  }
7
7
 
8
+ export declare interface AddNodeRequest {
9
+ id?: string;
10
+ element: HTMLElement;
11
+ x: number;
12
+ y: number;
13
+ ports?: Record<string, MarkPortRequest>;
14
+ centerFn?: CenterFn;
15
+ }
16
+
8
17
  export declare interface ApiContentMoveTransform {
9
18
  x?: number;
10
19
  y?: number;
@@ -16,15 +25,6 @@ export declare interface ApiContentScaleTransform {
16
25
  y?: number;
17
26
  }
18
27
 
19
- export declare interface ApiNode {
20
- id?: string;
21
- element: HTMLElement;
22
- x: number;
23
- y: number;
24
- ports?: Record<string, ApiPortsPayload>;
25
- centerFn?: CenterFn;
26
- }
27
-
28
28
  export declare interface ApiPort {
29
29
  readonly id?: string;
30
30
  readonly element: HTMLElement;
@@ -33,22 +33,12 @@ export declare interface ApiPort {
33
33
  readonly direction?: number | null;
34
34
  }
35
35
 
36
- export declare type ApiPortsPayload = HTMLElement | {
37
- readonly element: HTMLElement;
38
- readonly centerFn?: CenterFn;
39
- readonly direction?: number | null;
40
- };
41
-
42
- declare interface ApiTransform {
36
+ export declare interface ApiTransform {
43
37
  scale?: number;
44
38
  x?: number;
45
39
  y?: number;
46
40
  }
47
41
 
48
- declare interface ApiUpdateConnection {
49
- readonly controller?: ConnectionController;
50
- }
51
-
52
42
  export declare type BackgroundDrawingFn = (ctx: CanvasRenderingContext2D, transformer: PublicViewportTransformer) => void;
53
43
 
54
44
  declare type BackgroundOptions = {
@@ -107,7 +97,7 @@ export declare interface Canvas {
107
97
  /**
108
98
  * adds node to graph
109
99
  */
110
- addNode(node: ApiNode): Canvas;
100
+ addNode(node: AddNodeRequest): Canvas;
111
101
  /**
112
102
  * removes node from graph
113
103
  * all the ports of node get unmarked
@@ -130,7 +120,7 @@ export declare interface Canvas {
130
120
  /**
131
121
  * adds connection to graph
132
122
  */
133
- addConnection(connection: ApiConnection): Canvas;
123
+ addConnection(connection: AddConnectionRequest): Canvas;
134
124
  /**
135
125
  * removes connection from graph
136
126
  */
@@ -158,7 +148,7 @@ export declare interface Canvas {
158
148
  /**
159
149
  * updates connection
160
150
  */
161
- updateConnectionOptions(connectionId: string, options: ApiUpdateConnection): Canvas;
151
+ updateConnectionController(connectionId: string, controller: ConnectionController): Canvas;
162
152
  /**
163
153
  * drags node in viewport
164
154
  */
@@ -194,9 +184,9 @@ export declare class CanvasBuilder {
194
184
  private transformOptions;
195
185
  private isDraggable;
196
186
  private isTransformable;
197
- options(options: CoreOptions): CanvasBuilder;
198
- draggableNodes(): CanvasBuilder;
199
- transformableCanvas(options?: TransformOptions): CanvasBuilder;
187
+ setOptions(options: CoreOptions): CanvasBuilder;
188
+ setDraggableNodes(): CanvasBuilder;
189
+ setTransformableCanvas(options?: TransformOptions): CanvasBuilder;
200
190
  build(): Canvas;
201
191
  }
202
192
 
@@ -210,20 +200,20 @@ export declare class CanvasCore implements Canvas {
210
200
  private readonly options;
211
201
  private readonly di;
212
202
  constructor(apiOptions?: CoreOptions | undefined);
213
- addNode(node: ApiNode): CanvasCore;
203
+ addNode(node: AddNodeRequest): CanvasCore;
214
204
  moveNodeOnTop(nodeId: string): CanvasCore;
215
205
  removeNode(nodeId: string): CanvasCore;
216
206
  markPort(port: ApiPort): CanvasCore;
217
207
  updatePortConnections(portId: string): CanvasCore;
218
208
  unmarkPort(portId: string): CanvasCore;
219
- addConnection(connection: ApiConnection): CanvasCore;
209
+ addConnection(connection: AddConnectionRequest): CanvasCore;
220
210
  removeConnection(connectionId: string): CanvasCore;
221
211
  patchViewportTransform(apiTransform: ApiTransform): CanvasCore;
222
212
  moveContent(apiTransform: ApiContentMoveTransform): CanvasCore;
223
213
  scaleContent(apiTransform: ApiContentScaleTransform): CanvasCore;
224
214
  moveToNodes(nodeIds: readonly string[]): CanvasCore;
225
215
  updateNodeCoords(nodeId: string, x: number, y: number): CanvasCore;
226
- updateConnectionOptions(connectionId: string, options: ApiUpdateConnection): CanvasCore;
216
+ updateConnectionController(connectionId: string, controller: ConnectionController): CanvasCore;
227
217
  dragNode(nodeId: string, dx: number, dy: number): CanvasCore;
228
218
  clear(): CanvasCore;
229
219
  attach(element: HTMLElement): CanvasCore;
@@ -233,12 +223,12 @@ export declare class CanvasCore implements Canvas {
233
223
 
234
224
  declare type CenterFn = (width: number, height: number) => [number, number];
235
225
 
236
- declare interface ConnectionController {
226
+ export declare interface ConnectionController {
237
227
  readonly svg: SVGSVGElement;
238
228
  update(x: number, y: number, width: number, height: number, from: PortPayload, to: PortPayload): void;
239
229
  }
240
230
 
241
- declare type ConnectionControllerFactory = () => ConnectionController;
231
+ declare type ConnectionControllerFactory = (type: ConnectionType) => ConnectionController;
242
232
 
243
233
  declare type ConnectionOptions = BezierConnectionOptions | StraightConnectionOptions | CustomConnectionOptions;
244
234
 
@@ -248,6 +238,11 @@ declare interface ConnectionPayload {
248
238
  controller: ConnectionController;
249
239
  }
250
240
 
241
+ export declare enum ConnectionType {
242
+ Regular = "regular",
243
+ Cycle = "cycle"
244
+ }
245
+
251
246
  export declare class ConnectionUtils {
252
247
  static getPortCenter(port: PortPayload): Point;
253
248
  static rotate(point: Point, vector: Point, center: Point): Point;
@@ -296,6 +291,26 @@ export declare interface CoreOptions {
296
291
  };
297
292
  }
298
293
 
294
+ export declare const createBezierConnectionControllerFactory: (options: {
295
+ color: string;
296
+ width: number;
297
+ arrowLength: number;
298
+ arrowWidth: number;
299
+ curvature: number;
300
+ hasSourceArrow: boolean;
301
+ hasTargetArrow: boolean;
302
+ }) => ConnectionControllerFactory;
303
+
304
+ export declare const createStraightConnectionControllerFactory: (options: {
305
+ color: string;
306
+ width: number;
307
+ arrowLength: number;
308
+ arrowWidth: number;
309
+ minPortOffset: number;
310
+ hasSourceArrow: boolean;
311
+ hasTargetArrow: boolean;
312
+ }) => ConnectionControllerFactory;
313
+
299
314
  declare interface CustomConnectionOptions {
300
315
  readonly type: "custom";
301
316
  readonly controllerFactory: ConnectionControllerFactory;
@@ -316,19 +331,19 @@ export declare class DraggableNodesCanvas implements Canvas {
316
331
  private readonly onCanvasTouchEnd;
317
332
  private previousTouchCoords;
318
333
  constructor(canvas: Canvas);
319
- addNode(node: ApiNode): DraggableNodesCanvas;
334
+ addNode(node: AddNodeRequest): DraggableNodesCanvas;
320
335
  removeNode(nodeId: string): DraggableNodesCanvas;
321
336
  markPort(port: ApiPort): DraggableNodesCanvas;
322
337
  updatePortConnections(portId: string): DraggableNodesCanvas;
323
338
  unmarkPort(portId: string): DraggableNodesCanvas;
324
- addConnection(connection: ApiConnection): DraggableNodesCanvas;
339
+ addConnection(connection: AddConnectionRequest): DraggableNodesCanvas;
325
340
  removeConnection(connectionId: string): DraggableNodesCanvas;
326
341
  patchViewportTransform(apiTransform: ApiTransform): DraggableNodesCanvas;
327
342
  moveContent(apiTransform: ApiContentMoveTransform): DraggableNodesCanvas;
328
343
  scaleContent(apiTransform: ApiContentScaleTransform): DraggableNodesCanvas;
329
344
  moveToNodes(nodeIds: readonly string[]): DraggableNodesCanvas;
330
345
  updateNodeCoords(nodeId: string, x: number, y: number): DraggableNodesCanvas;
331
- updateConnectionOptions(connectionId: string, options: ApiUpdateConnection): DraggableNodesCanvas;
346
+ updateConnectionController(connectionId: string, controller: ConnectionController): DraggableNodesCanvas;
332
347
  dragNode(nodeId: string, dx: number, dy: number): DraggableNodesCanvas;
333
348
  moveNodeOnTop(nodeId: string): DraggableNodesCanvas;
334
349
  clear(): DraggableNodesCanvas;
@@ -378,6 +393,12 @@ declare class GraphStore {
378
393
 
379
394
  declare type LayersMode = "connections-on-top" | "nodes-on-top" | "connections-follow-node";
380
395
 
396
+ export declare type MarkPortRequest = HTMLElement | {
397
+ readonly element: HTMLElement;
398
+ readonly centerFn?: CenterFn;
399
+ readonly direction?: number | null;
400
+ };
401
+
381
402
  declare interface NodePayload {
382
403
  element: HTMLElement;
383
404
  x: number;
@@ -497,19 +518,19 @@ export declare class TransformableCanvas implements Canvas {
497
518
  private readonly onTouchMove;
498
519
  private readonly onTouchEnd;
499
520
  constructor(canvas: Canvas, options?: TransformOptions | undefined);
500
- addNode(node: ApiNode): TransformableCanvas;
521
+ addNode(node: AddNodeRequest): TransformableCanvas;
501
522
  removeNode(nodeId: string): TransformableCanvas;
502
523
  markPort(port: ApiPort): TransformableCanvas;
503
524
  updatePortConnections(portId: string): TransformableCanvas;
504
525
  unmarkPort(portId: string): TransformableCanvas;
505
- addConnection(connection: ApiConnection): TransformableCanvas;
526
+ addConnection(connection: AddConnectionRequest): TransformableCanvas;
506
527
  removeConnection(connectionId: string): TransformableCanvas;
507
528
  patchViewportTransform(apiTransform: ApiTransform): TransformableCanvas;
508
529
  moveContent(apiTransform: ApiContentMoveTransform): TransformableCanvas;
509
530
  scaleContent(apiTransform: ApiContentScaleTransform): TransformableCanvas;
510
531
  moveToNodes(nodeIds: readonly string[]): TransformableCanvas;
511
532
  updateNodeCoords(nodeId: string, x: number, y: number): TransformableCanvas;
512
- updateConnectionOptions(connectionId: string, options: ApiUpdateConnection): TransformableCanvas;
533
+ updateConnectionController(connectionId: string, controller: ConnectionController): TransformableCanvas;
513
534
  dragNode(nodeId: string, dx: number, dy: number): TransformableCanvas;
514
535
  moveNodeOnTop(nodeId: string): TransformableCanvas;
515
536
  clear(): TransformableCanvas;
package/dist/main.js CHANGED
@@ -1,28 +1,7 @@
1
- var V = Object.defineProperty;
2
- var k = (n, t, e) => t in n ? V(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
3
- var r = (n, t, e) => k(n, typeof t != "symbol" ? t + "" : t, e);
4
- class nt {
5
- constructor() {
6
- r(this, "coreOptions");
7
- r(this, "transformOptions");
8
- r(this, "isDraggable", !1);
9
- r(this, "isTransformable", !1);
10
- }
11
- options(t) {
12
- return this.coreOptions = t, this;
13
- }
14
- draggableNodes() {
15
- return this.isDraggable = !0, this;
16
- }
17
- transformableCanvas(t) {
18
- return this.isTransformable = !0, this.transformOptions = t, this;
19
- }
20
- build() {
21
- let t = new I(this.coreOptions);
22
- return this.isDraggable && (t = new tt(t)), this.isTransformable && (t = new et(t, this.transformOptions)), t;
23
- }
24
- }
25
- class j {
1
+ var k = Object.defineProperty;
2
+ var j = (n, t, e) => t in n ? k(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
3
+ var r = (n, t, e) => j(n, typeof t != "symbol" ? t + "" : t, e);
4
+ class F {
26
5
  constructor(t) {
27
6
  r(this, "canvasWrapper", null);
28
7
  r(this, "host");
@@ -204,11 +183,11 @@ class j {
204
183
  ), [f, y] = s.centerFn(
205
184
  c.width * g,
206
185
  c.height * g
207
- ), b = u + h, S = p + l, N = f + m, C = y + d, w = Math.min(b, N), T = Math.min(S, C), E = Math.abs(N - b), O = Math.abs(C - S), x = this.connectionIdToElementMap.get(t), M = b <= N, L = S <= C;
208
- x.style.transform = `matrix(${M ? 1 : -1}, 0, 0, ${L ? 1 : -1}, ${w}, ${T})`, e.controller.update(w, T, E, O, o, s);
186
+ ), b = u + h, S = p + l, N = f + m, v = y + d, w = Math.min(b, N), T = Math.min(S, v), E = Math.abs(N - b), O = Math.abs(v - S), M = this.connectionIdToElementMap.get(t), L = b <= N, V = S <= v;
187
+ M.style.transform = `matrix(${L ? 1 : -1}, 0, 0, ${V ? 1 : -1}, ${w}, ${T})`, e.controller.update(w, T, E, O, o, s);
209
188
  }
210
189
  }
211
- class F {
190
+ class W {
212
191
  constructor() {
213
192
  r(this, "state", {
214
193
  scale: 1,
@@ -278,7 +257,7 @@ class F {
278
257
  };
279
258
  }
280
259
  }
281
- class W {
260
+ class D {
282
261
  constructor(t) {
283
262
  this.transformer = t;
284
263
  }
@@ -311,7 +290,7 @@ class W {
311
290
  return this.transformer.getAbsScale();
312
291
  }
313
292
  }
314
- class v {
293
+ class C {
315
294
  static getPortCenter(t) {
316
295
  const { top: e, left: o, width: s, height: i } = t.element.getBoundingClientRect(), c = t.centerFn(s, i);
317
296
  return [o + c[0], e + c[1]];
@@ -341,7 +320,7 @@ class v {
341
320
  return `M ${a[0][0]} ${a[0][1]} L ${a[1][0]} ${a[1][1]}`;
342
321
  }
343
322
  }
344
- class D {
323
+ class R {
345
324
  constructor(t, e, o, s, i, c, a) {
346
325
  r(this, "svg");
347
326
  r(this, "group");
@@ -358,21 +337,21 @@ class D {
358
337
  }
359
338
  update(t, e, o, s, i, c) {
360
339
  this.svg.style.width = `${o}px`, this.svg.style.height = `${s}px`;
361
- const a = v.getPortCenter(i), h = v.getPortCenter(c), l = a[0] <= h[0] ? 1 : -1, m = a[1] <= h[1] ? 1 : -1;
340
+ const a = C.getPortCenter(i), h = C.getPortCenter(c), l = a[0] <= h[0] ? 1 : -1, m = a[1] <= h[1] ? 1 : -1;
362
341
  this.svg.style.transform = `translate(${t}px, ${e}px)`, this.group.style.transform = `scale(${l}, ${m})`;
363
- const d = v.getDirectionVector(
342
+ const d = C.getDirectionVector(
364
343
  i.direction,
365
344
  l,
366
345
  m
367
- ), g = v.getDirectionVector(
346
+ ), g = C.getDirectionVector(
368
347
  c.direction,
369
348
  l,
370
349
  m
371
- ), u = v.rotate(
350
+ ), u = C.rotate(
372
351
  [this.arrowLength, 0],
373
352
  d,
374
353
  [0, 0]
375
- ), p = v.rotate(
354
+ ), p = C.rotate(
376
355
  [o - this.arrowLength, s],
377
356
  g,
378
357
  [o, s]
@@ -382,9 +361,9 @@ class D {
382
361
  ], y = [
383
362
  p[0] - g[0] * this.curvature,
384
363
  p[1] - g[1] * this.curvature
385
- ], b = `M ${u[0]} ${u[1]}`, S = `C ${f[0]} ${f[1]}, ${y[0]} ${y[1]}, ${p[0]} ${p[1]}`, N = `M 0 0 L ${u[0]} ${u[1]} `, C = ` M ${p[0]} ${p[1]} L ${o} ${s}`, w = `${this.sourceArrow ? "" : N}${b} ${S}${this.targetArrow ? "" : C}`;
364
+ ], b = `M ${u[0]} ${u[1]}`, S = `C ${f[0]} ${f[1]}, ${y[0]} ${y[1]}, ${p[0]} ${p[1]}`, N = `M 0 0 L ${u[0]} ${u[1]} `, v = ` M ${p[0]} ${p[1]} L ${o} ${s}`, w = `${this.sourceArrow ? "" : N}${b} ${S}${this.targetArrow ? "" : v}`;
386
365
  if (this.line.setAttribute("d", w), this.sourceArrow) {
387
- const T = v.getArrowPath(
366
+ const T = C.getArrowPath(
388
367
  d,
389
368
  0,
390
369
  0,
@@ -394,7 +373,7 @@ class D {
394
373
  this.sourceArrow.setAttribute("d", T);
395
374
  }
396
375
  if (this.targetArrow) {
397
- const T = v.getArrowPath(
376
+ const T = C.getArrowPath(
398
377
  g,
399
378
  o,
400
379
  s,
@@ -405,7 +384,7 @@ class D {
405
384
  }
406
385
  }
407
386
  }
408
- const R = (n) => () => new D(
387
+ const z = (n) => () => new R(
409
388
  n.color ?? "#5c5c5c",
410
389
  n.width ?? 1,
411
390
  n.curvature ?? 90,
@@ -414,7 +393,7 @@ const R = (n) => () => new D(
414
393
  n.hasSourceArrow ?? !1,
415
394
  n.hasTargetArrow ?? !1
416
395
  );
417
- class z {
396
+ class G {
418
397
  constructor(t, e, o, s, i, c, a) {
419
398
  r(this, "svg");
420
399
  r(this, "group");
@@ -431,39 +410,39 @@ class z {
431
410
  }
432
411
  update(t, e, o, s, i, c) {
433
412
  this.svg.style.width = `${o}px`, this.svg.style.height = `${s}px`;
434
- const a = v.getPortCenter(i), h = v.getPortCenter(c), l = a[0] <= h[0] ? 1 : -1, m = a[1] <= h[1] ? 1 : -1;
413
+ const a = C.getPortCenter(i), h = C.getPortCenter(c), l = a[0] <= h[0] ? 1 : -1, m = a[1] <= h[1] ? 1 : -1;
435
414
  this.svg.style.transform = `translate(${t}px, ${e}px)`, this.group.style.transform = `scale(${l}, ${m})`;
436
- const d = v.getDirectionVector(
415
+ const d = C.getDirectionVector(
437
416
  i.direction,
438
417
  l,
439
418
  m
440
- ), g = v.getDirectionVector(
419
+ ), g = C.getDirectionVector(
441
420
  c.direction,
442
421
  l,
443
422
  m
444
- ), u = v.rotate(
423
+ ), u = C.rotate(
445
424
  [this.arrowLength + this.minPortOffset, 0],
446
425
  d,
447
426
  [0, 0]
448
- ), p = v.rotate(
427
+ ), p = C.rotate(
449
428
  [o - this.arrowLength - this.minPortOffset, s],
450
429
  g,
451
430
  [o, s]
452
- ), [f, y] = [o / 2, s / 2], b = l * (p[0] - u[0]) > 0 ? `M ${u[0]} ${u[1]} L ${f} ${u[1]} L ${f} ${p[1]} L ${p[0]} ${p[1]}` : `M ${u[0]} ${u[1]} L ${u[0]} ${y} L ${p[0]} ${y} L ${p[0]} ${p[1]}`, S = `M 0 0 L ${u[0]} ${u[1]} `, N = ` M ${p[0]} ${p[1]} L ${o} ${s}`, C = v.getArrowOffsetPath(
431
+ ), [f, y] = [o / 2, s / 2], b = l * (p[0] - u[0]) > 0 ? `M ${u[0]} ${u[1]} L ${f} ${u[1]} L ${f} ${p[1]} L ${p[0]} ${p[1]}` : `M ${u[0]} ${u[1]} L ${u[0]} ${y} L ${p[0]} ${y} L ${p[0]} ${p[1]}`, S = `M 0 0 L ${u[0]} ${u[1]} `, N = ` M ${p[0]} ${p[1]} L ${o} ${s}`, v = C.getArrowOffsetPath(
453
432
  d,
454
433
  0,
455
434
  0,
456
435
  this.arrowLength,
457
436
  this.minPortOffset
458
- ), w = v.getArrowOffsetPath(
437
+ ), w = C.getArrowOffsetPath(
459
438
  g,
460
439
  o,
461
440
  s,
462
441
  -this.arrowLength,
463
442
  -this.minPortOffset
464
- ), T = `${this.sourceArrow ? C : S}${b}${this.targetArrow ? w : N}`;
443
+ ), T = `${this.sourceArrow ? v : S}${b}${this.targetArrow ? w : N}`;
465
444
  if (this.line.setAttribute("d", T), this.sourceArrow) {
466
- const E = v.getArrowPath(
445
+ const E = C.getArrowPath(
467
446
  d,
468
447
  0,
469
448
  0,
@@ -473,7 +452,7 @@ class z {
473
452
  this.sourceArrow.setAttribute("d", E);
474
453
  }
475
454
  if (this.targetArrow) {
476
- const E = v.getArrowPath(
455
+ const E = C.getArrowPath(
477
456
  g,
478
457
  o,
479
458
  s,
@@ -484,7 +463,7 @@ class z {
484
463
  }
485
464
  }
486
465
  }
487
- const G = (n) => () => new z(
466
+ const B = (n) => () => new G(
488
467
  n.color,
489
468
  n.width,
490
469
  n.arrowLength,
@@ -492,33 +471,9 @@ const G = (n) => () => new z(
492
471
  n.minPortOffset,
493
472
  n.hasSourceArrow,
494
473
  n.hasTargetArrow
495
- ), $ = (n) => {
496
- switch (n == null ? void 0 : n.type) {
497
- case "custom":
498
- return n.controllerFactory;
499
- case "straight":
500
- return G({
501
- color: n.color ?? "#5c5c5c",
502
- width: n.width ?? 1,
503
- arrowLength: n.arrowLength ?? 15,
504
- arrowWidth: n.arrowWidth ?? 4,
505
- minPortOffset: n.minPortOffset ?? 15,
506
- hasSourceArrow: n.hasSourceArrow ?? !1,
507
- hasTargetArrow: n.hasTargetArrow ?? !1
508
- });
509
- default:
510
- return R({
511
- color: n.color ?? "#5c5c5c",
512
- width: n.width ?? 1,
513
- curvature: n.curvature ?? 90,
514
- arrowLength: n.arrowLength ?? 15,
515
- arrowWidth: n.arrowWidth ?? 4,
516
- hasSourceArrow: n.hasSourceArrow ?? !1,
517
- hasTargetArrow: n.hasTargetArrow ?? !1
518
- });
519
- }
520
- };
521
- class B {
474
+ );
475
+ var $ = /* @__PURE__ */ ((n) => (n.Regular = "regular", n.Cycle = "cycle", n))($ || {});
476
+ class Y {
522
477
  constructor(t) {
523
478
  this.di = t;
524
479
  }
@@ -600,12 +555,11 @@ class B {
600
555
  throw new Error("failed to add connection from nonexisting port");
601
556
  if (!this.di.graphStore.hasPort(o))
602
557
  throw new Error("failed to add connection to nonexisting port");
603
- const i = s !== void 0 ? $(s) : this.di.options.connections.controllerFactory;
604
558
  this.di.graphStore.addConnection(
605
559
  t,
606
560
  e,
607
561
  o,
608
- i()
562
+ s($.Regular)
609
563
  ), this.di.htmlController.attachConnection(t);
610
564
  }
611
565
  removeConnection(t) {
@@ -645,14 +599,9 @@ class B {
645
599
  this.di.graphStore.updateNodeCoords(t, e, o), this.di.htmlController.updateNodePosition(t);
646
600
  }
647
601
  updateConnectionOptions(t, e) {
648
- if (e.controller !== void 0) {
649
- if (!this.di.graphStore.hasConnection(t))
650
- throw new Error("failed to update nonexisting connection");
651
- this.di.htmlController.detachConnection(t), this.di.graphStore.updateConnectionController(
652
- t,
653
- e.controller
654
- ), this.di.htmlController.attachConnection(t);
655
- }
602
+ if (!this.di.graphStore.hasConnection(t))
603
+ throw new Error("failed to update nonexisting connection");
604
+ this.di.htmlController.detachConnection(t), this.di.graphStore.updateConnectionController(t, e), this.di.htmlController.attachConnection(t);
656
605
  }
657
606
  clear() {
658
607
  this.di.htmlController.clear(), this.di.graphStore.clear(), this.di.nodeIdGenerator.reset(), this.di.portIdGenerator.reset(), this.di.connectionIdGenerator.reset();
@@ -661,7 +610,7 @@ class B {
661
610
  this.di.htmlController.destroy();
662
611
  }
663
612
  }
664
- class Y {
613
+ class X {
665
614
  constructor() {
666
615
  r(this, "nodes", /* @__PURE__ */ Object.create(null));
667
616
  r(this, "ports", /* @__PURE__ */ Object.create(null));
@@ -797,19 +746,7 @@ class Y {
797
746
  this.nodes = /* @__PURE__ */ Object.create(null), this.ports = /* @__PURE__ */ Object.create(null), this.nodePorts = /* @__PURE__ */ Object.create(null), this.portNodeId = /* @__PURE__ */ Object.create(null), this.connections = /* @__PURE__ */ Object.create(null), this.incommingConnections = /* @__PURE__ */ Object.create(null), this.outcommingConnections = /* @__PURE__ */ Object.create(null), this.cycleConnections = /* @__PURE__ */ Object.create(null);
798
747
  }
799
748
  }
800
- class A {
801
- constructor() {
802
- r(this, "counter", 0);
803
- }
804
- next() {
805
- const t = `${this.counter}`;
806
- return this.counter++, t;
807
- }
808
- reset() {
809
- this.counter = 0;
810
- }
811
- }
812
- class X {
749
+ class Z {
813
750
  constructor(t) {
814
751
  this.graphStore = t;
815
752
  }
@@ -868,7 +805,19 @@ class X {
868
805
  return this.graphStore.getNodeAdjacentConnections(t);
869
806
  }
870
807
  }
871
- class Z {
808
+ class A {
809
+ constructor() {
810
+ r(this, "counter", 0);
811
+ }
812
+ next() {
813
+ const t = `${this.counter}`;
814
+ return this.counter++, t;
815
+ }
816
+ reset() {
817
+ this.counter = 0;
818
+ }
819
+ }
820
+ class H {
872
821
  constructor(t) {
873
822
  r(this, "htmlController");
874
823
  r(this, "viewportTransformer");
@@ -879,15 +828,16 @@ class Z {
879
828
  r(this, "nodeIdGenerator");
880
829
  r(this, "portIdGenerator");
881
830
  r(this, "connectionIdGenerator");
882
- this.options = t, this.htmlController = new j(this), this.viewportTransformer = new F(), this.publicViewportTransformer = new W(
831
+ this.options = t, this.htmlController = new F(this), this.viewportTransformer = new W(), this.publicViewportTransformer = new D(
883
832
  this.viewportTransformer
884
- ), this.controller = new B(this), this.graphStore = new Y(), this.publicGraphStore = new X(this.graphStore), this.nodeIdGenerator = new A(), this.portIdGenerator = new A(), this.connectionIdGenerator = new A();
833
+ ), this.controller = new Y(this), this.graphStore = new X(), this.publicGraphStore = new Z(this.graphStore), this.nodeIdGenerator = new A(), this.portIdGenerator = new A(), this.connectionIdGenerator = new A();
885
834
  }
886
835
  }
887
836
  const P = (n, t) => [
888
837
  n / 2,
889
838
  t / 2
890
- ], H = (n, t, e, o, s, i) => {
839
+ ], U = () => () => {
840
+ }, q = (n, t, e, o, s, i) => {
891
841
  n.fillStyle = i, n.fillRect(0, 0, n.canvas.width, n.canvas.height);
892
842
  const c = t.getViewCoords(0, 0), a = t.getViewScale(), h = o * a;
893
843
  let l = 0, m = 0, d = h / 2;
@@ -896,13 +846,11 @@ const P = (n, t) => [
896
846
  while (l * m > 1e4);
897
847
  const g = c[0] - Math.floor(c[0] / d) * d, u = c[1] - Math.floor(c[1] / d) * d, p = s * a, f = 2 * Math.PI, y = g - d, b = u - d, S = n.canvas.width + g, N = n.canvas.height + u;
898
848
  n.fillStyle = e;
899
- for (let C = y; C <= S; C += d)
849
+ for (let v = y; v <= S; v += d)
900
850
  for (let w = b; w <= N; w += d)
901
- n.beginPath(), n.arc(C, w, p, 0, f), n.closePath(), n.fill();
902
- }, U = (n, t) => {
903
- n.fillStyle = t, n.fillRect(0, 0, n.canvas.width, n.canvas.height);
904
- }, q = (n, t, e, o) => (s, i) => {
905
- H(
851
+ n.beginPath(), n.arc(v, w, p, 0, f), n.closePath(), n.fill();
852
+ }, J = (n, t, e, o) => (s, i) => {
853
+ q(
906
854
  s,
907
855
  i,
908
856
  n,
@@ -910,30 +858,58 @@ const P = (n, t) => [
910
858
  e,
911
859
  o
912
860
  );
913
- }, J = () => () => {
914
- }, K = (n) => (t) => {
915
- U(t, n);
916
- }, Q = (n) => {
861
+ }, K = (n, t) => {
862
+ n.fillStyle = t, n.fillRect(0, 0, n.canvas.width, n.canvas.height);
863
+ }, Q = (n) => (t) => {
864
+ K(t, n);
865
+ }, _ = (n) => {
917
866
  switch (n == null ? void 0 : n.type) {
918
867
  case "custom":
919
868
  return n.drawingFn;
920
869
  case "dots":
921
- return q(
870
+ return J(
922
871
  n.dotColor ?? "#d8d8d8",
923
872
  n.dotGap ?? 25,
924
873
  n.dotRadius ?? 1.5,
925
874
  n.color ?? "#ffffff"
926
875
  );
927
876
  case "color":
928
- return K(n.color ?? "#ffffff");
877
+ return Q(n.color ?? "#ffffff");
929
878
  default:
930
- return J();
879
+ return U();
931
880
  }
932
- }, _ = (n) => {
881
+ }, x = (n) => {
882
+ switch (n == null ? void 0 : n.type) {
883
+ case "custom":
884
+ return n.controllerFactory;
885
+ case "straight":
886
+ return B({
887
+ color: n.color ?? "#5c5c5c",
888
+ width: n.width ?? 1,
889
+ arrowLength: n.arrowLength ?? 15,
890
+ arrowWidth: n.arrowWidth ?? 4,
891
+ minPortOffset: n.minPortOffset ?? 15,
892
+ hasSourceArrow: n.hasSourceArrow ?? !1,
893
+ hasTargetArrow: n.hasTargetArrow ?? !1
894
+ });
895
+ default:
896
+ return z({
897
+ color: n.color ?? "#5c5c5c",
898
+ width: n.width ?? 1,
899
+ curvature: n.curvature ?? 90,
900
+ arrowLength: n.arrowLength ?? 15,
901
+ arrowWidth: n.arrowWidth ?? 4,
902
+ hasSourceArrow: n.hasSourceArrow ?? !1,
903
+ hasTargetArrow: n.hasTargetArrow ?? !1
904
+ });
905
+ }
906
+ }, I = (n) => {
933
907
  var t, e, o;
934
908
  return {
935
909
  background: {
936
- drawingFn: Q(n.background)
910
+ drawingFn: _(
911
+ n.background ?? { type: "none" }
912
+ )
937
913
  },
938
914
  nodes: {
939
915
  centerFn: ((t = n.nodes) == null ? void 0 : t.centerFn) ?? P
@@ -942,7 +918,7 @@ const P = (n, t) => [
942
918
  centerFn: ((e = n.ports) == null ? void 0 : e.centerFn) ?? P
943
919
  },
944
920
  connections: {
945
- controllerFactory: $(
921
+ controllerFactory: x(
946
922
  n.connections ?? {}
947
923
  )
948
924
  },
@@ -951,13 +927,13 @@ const P = (n, t) => [
951
927
  }
952
928
  };
953
929
  };
954
- class I {
930
+ class tt {
955
931
  constructor(t) {
956
932
  r(this, "transformation");
957
933
  r(this, "model");
958
934
  r(this, "options");
959
935
  r(this, "di");
960
- this.apiOptions = t, this.options = _(this.apiOptions ?? {}), this.di = new Z(this.options), this.transformation = this.di.publicViewportTransformer, this.model = this.di.publicGraphStore;
936
+ this.apiOptions = t, this.options = I(this.apiOptions ?? {}), this.di = new H(this.options), this.transformation = this.di.publicViewportTransformer, this.model = this.di.publicGraphStore;
961
937
  }
962
938
  addNode(t) {
963
939
  return this.di.controller.addNode(
@@ -991,11 +967,12 @@ class I {
991
967
  return this.di.controller.unmarkPort(t), this;
992
968
  }
993
969
  addConnection(t) {
970
+ const e = t.options !== void 0 ? x(t.options) : this.di.options.connections.controllerFactory;
994
971
  return this.di.controller.addConnection(
995
972
  t.id,
996
973
  t.from,
997
974
  t.to,
998
- t.options
975
+ e
999
976
  ), this;
1000
977
  }
1001
978
  removeConnection(t) {
@@ -1024,7 +1001,7 @@ class I {
1024
1001
  updateNodeCoords(t, e, o) {
1025
1002
  return this.di.controller.updateNodeCoords(t, e, o), this;
1026
1003
  }
1027
- updateConnectionOptions(t, e) {
1004
+ updateConnectionController(t, e) {
1028
1005
  return this.di.controller.updateConnectionOptions(t, e), this;
1029
1006
  }
1030
1007
  dragNode(t, e, o) {
@@ -1043,7 +1020,7 @@ class I {
1043
1020
  this.di.controller.destroy();
1044
1021
  }
1045
1022
  }
1046
- class tt {
1023
+ class et {
1047
1024
  constructor(t) {
1048
1025
  r(this, "transformation");
1049
1026
  r(this, "model");
@@ -1138,8 +1115,8 @@ class tt {
1138
1115
  updateNodeCoords(t, e, o) {
1139
1116
  return this.canvas.updateNodeCoords(t, e, o), this;
1140
1117
  }
1141
- updateConnectionOptions(t, e) {
1142
- return this.canvas.updateConnectionOptions(t, e), this;
1118
+ updateConnectionController(t, e) {
1119
+ return this.canvas.updateConnectionController(t, e), this;
1143
1120
  }
1144
1121
  dragNode(t, e, o) {
1145
1122
  return this.canvas.dragNode(t, e, o), this;
@@ -1167,7 +1144,7 @@ class tt {
1167
1144
  this.element !== null && (t !== null ? this.element.style.cursor = t : this.element.style.removeProperty("cursor"));
1168
1145
  }
1169
1146
  }
1170
- class et {
1147
+ class ot {
1171
1148
  constructor(t, e) {
1172
1149
  r(this, "transformation");
1173
1150
  r(this, "model");
@@ -1255,8 +1232,8 @@ class et {
1255
1232
  updateNodeCoords(t, e, o) {
1256
1233
  return this.canvas.updateNodeCoords(t, e, o), this;
1257
1234
  }
1258
- updateConnectionOptions(t, e) {
1259
- return this.canvas.updateConnectionOptions(t, e), this;
1235
+ updateConnectionController(t, e) {
1236
+ return this.canvas.updateConnectionController(t, e), this;
1260
1237
  }
1261
1238
  dragNode(t, e, o) {
1262
1239
  return this.canvas.dragNode(t, e, o), this;
@@ -1297,12 +1274,35 @@ class et {
1297
1274
  this.element !== null && (t !== null ? this.element.style.cursor = t : this.element.style.removeProperty("cursor"));
1298
1275
  }
1299
1276
  }
1277
+ class st {
1278
+ constructor() {
1279
+ r(this, "coreOptions");
1280
+ r(this, "transformOptions");
1281
+ r(this, "isDraggable", !1);
1282
+ r(this, "isTransformable", !1);
1283
+ }
1284
+ setOptions(t) {
1285
+ return this.coreOptions = t, this;
1286
+ }
1287
+ setDraggableNodes() {
1288
+ return this.isDraggable = !0, this;
1289
+ }
1290
+ setTransformableCanvas(t) {
1291
+ return this.isTransformable = !0, this.transformOptions = t, this;
1292
+ }
1293
+ build() {
1294
+ let t = new tt(this.coreOptions);
1295
+ return this.isDraggable && (t = new et(t)), this.isTransformable && (t = new ot(t, this.transformOptions)), t;
1296
+ }
1297
+ }
1300
1298
  export {
1301
- D as BezierConnectionController,
1302
- nt as CanvasBuilder,
1303
- I as CanvasCore,
1304
- v as ConnectionUtils,
1305
- tt as DraggableNodesCanvas,
1306
- z as StraightConnectionController,
1307
- et as TransformableCanvas
1299
+ R as BezierConnectionController,
1300
+ st as CanvasBuilder,
1301
+ tt as CanvasCore,
1302
+ C as ConnectionUtils,
1303
+ et as DraggableNodesCanvas,
1304
+ G as StraightConnectionController,
1305
+ ot as TransformableCanvas,
1306
+ z as createBezierConnectionControllerFactory,
1307
+ B as createStraightConnectionControllerFactory
1308
1308
  };
package/dist/main.umd.cjs CHANGED
@@ -1 +1 @@
1
- (function(v,w){typeof exports=="object"&&typeof module<"u"?w(exports):typeof define=="function"&&define.amd?define(["exports"],w):(v=typeof globalThis<"u"?globalThis:v||self,w(v.HTMLGraph={}))})(this,function(v){"use strict";var ot=Object.defineProperty;var nt=(v,w,P)=>w in v?ot(v,w,{enumerable:!0,configurable:!0,writable:!0,value:P}):v[w]=P;var r=(v,w,P)=>nt(v,typeof w!="symbol"?w+"":w,P);class w{constructor(){r(this,"coreOptions");r(this,"transformOptions");r(this,"isDraggable",!1);r(this,"isTransformable",!1)}options(t){return this.coreOptions=t,this}draggableNodes(){return this.isDraggable=!0,this}transformableCanvas(t){return this.isTransformable=!0,this.transformOptions=t,this}build(){let t=new j(this.coreOptions);return this.isDraggable&&(t=new k(t)),this.isTransformable&&(t=new F(t,this.transformOptions)),t}}class P{constructor(t){r(this,"canvasWrapper",null);r(this,"host");r(this,"nodesContainer");r(this,"connectionsContainer");r(this,"canvas");r(this,"canvasCtx");r(this,"hostResizeObserver");r(this,"nodesResizeObserver");r(this,"nodeElementToIdMap",new Map);r(this,"nodeWrapperElementToIdMap",new Map);r(this,"nodeIdToWrapperElementMap",new Map);r(this,"connectionIdToElementMap",new Map);r(this,"currentZIndex",0);r(this,"layers",{"connections-on-top":{create:()=>{this.host.appendChild(this.nodesContainer),this.host.appendChild(this.connectionsContainer)},update:(t,e,o)=>{this.nodesContainer.style.transform=`matrix(${t}, 0, 0, ${t}, ${e}, ${o})`,this.connectionsContainer.style.transform=`matrix(${t}, 0, 0, ${t}, ${e}, ${o})`},moveOnTop:t=>{this.currentZIndex+=1;const e=this.nodeIdToWrapperElementMap.get(t);e.style.zIndex=`${this.currentZIndex}`}},"connections-follow-node":{create:()=>{this.host.appendChild(this.nodesContainer),this.connectionsContainer=this.nodesContainer},update:(t,e,o)=>{this.nodesContainer.style.transform=`matrix(${t}, 0, 0, ${t}, ${e}, ${o})`},moveOnTop:t=>{const e=this.nodeIdToWrapperElementMap.get(t);this.currentZIndex+=2,e.style.zIndex=`${this.currentZIndex}`,this.di.graphStore.getNodeAdjacentConnections(t).forEach(n=>{this.connectionIdToElementMap.get(n).style.zIndex=`${this.currentZIndex-1}`})}},"nodes-on-top":{create:()=>{this.host.appendChild(this.connectionsContainer),this.host.appendChild(this.nodesContainer)},update:(t,e,o)=>{this.nodesContainer.style.transform=`matrix(${t}, 0, 0, ${t}, ${e}, ${o})`,this.connectionsContainer.style.transform=`matrix(${t}, 0, 0, ${t}, ${e}, ${o})`},moveOnTop:t=>{this.currentZIndex+=1;const e=this.nodeIdToWrapperElementMap.get(t);e.style.zIndex=`${this.currentZIndex}`}}});this.di=t,this.host=this.createHost(),this.canvas=this.createCanvas(),this.nodesContainer=this.createNodesContainer(),this.connectionsContainer=this.createConnectionsContainer();const e=this.canvas.getContext("2d");if(e===null)throw new Error("unable to get canvas context");this.canvasCtx=e,this.host.appendChild(this.canvas);const o=this.di.options.layers.mode;this.layers[o].create(),this.hostResizeObserver=this.createHostResizeObserver(),this.hostResizeObserver.observe(this.host),this.nodesResizeObserver=this.createNodesResizeObserver()}clear(){Array.from(this.connectionIdToElementMap.keys()).forEach(t=>{this.detachConnection(t)}),Array.from(this.nodeElementToIdMap.values()).forEach(t=>{this.detachNode(t)})}attach(t){this.canvasWrapper=t,this.canvasWrapper.appendChild(this.host)}detach(){this.canvasWrapper!==null&&this.canvasWrapper.removeChild(this.host)}destroy(){this.hostResizeObserver.disconnect(),this.nodesResizeObserver.disconnect(),this.host.removeChild(this.canvas),this.host.removeChild(this.connectionsContainer),this.host.removeChild(this.nodesContainer),this.canvasWrapper!==null&&this.canvasWrapper.removeChild(this.host)}applyTransform(){this.canvasCtx.clearRect(0,0,this.canvasCtx.canvas.width,this.canvasCtx.canvas.height),this.canvasCtx.save(),this.di.options.background.drawingFn(this.canvasCtx,this.di.publicViewportTransformer),this.canvasCtx.restore();const[t,e]=this.di.viewportTransformer.getViewCoords(0,0),o=this.di.viewportTransformer.getViewScale();this.layers[this.di.options.layers.mode].update(o,t,e)}attachNode(t){const e=this.di.graphStore.getNode(t),o=document.createElement("div");o.appendChild(e.element),o.style.position="absolute",o.style.top="0",o.style.left="0",o.style.zIndex=`${this.currentZIndex}`,this.currentZIndex+=1,o.style.visibility="hidden",this.nodesContainer.appendChild(o),this.nodeElementToIdMap.set(e.element,t),this.nodeWrapperElementToIdMap.set(o,t),this.nodeIdToWrapperElementMap.set(t,o),this.updateNodeCoords(t,e.x,e.y),this.nodesResizeObserver.observe(o),o.style.visibility="visible"}detachNode(t){const e=this.di.graphStore.getNode(t);this.nodesResizeObserver.unobserve(e.element),this.nodesContainer.removeChild(e.element);const o=this.nodeIdToWrapperElementMap.get(t);o.removeChild(e.element),this.nodeElementToIdMap.delete(e.element),this.nodeWrapperElementToIdMap.delete(o),this.nodeIdToWrapperElementMap.delete(t)}attachConnection(t){const o=this.di.graphStore.getConnection(t).controller.svg;o.style.transformOrigin="50% 50%",o.style.position="absolute",o.style.top="0",o.style.left="0",o.style.zIndex=`${this.currentZIndex}`,this.currentZIndex+=1,this.connectionIdToElementMap.set(t,o),this.updateConnectionCoords(t),this.connectionsContainer.appendChild(o)}detachConnection(t){const e=this.connectionIdToElementMap.get(t);this.connectionIdToElementMap.delete(t),this.connectionsContainer.removeChild(e)}moveNodeOnTop(t){this.layers[this.di.options.layers.mode].moveOnTop(t)}updateNodePosition(t){const e=this.di.graphStore.getNode(t),o=this.di.graphStore.getNodeAdjacentConnections(t);this.updateNodeCoords(t,e.x,e.y),o.forEach(n=>{this.updateConnectionCoords(n)})}updatePortConnections(t){this.di.graphStore.getPortAdjacentConnections(t).forEach(o=>{this.updateConnectionCoords(o)})}getViewportDimensions(){const t=this.host.getBoundingClientRect();return[t.width,t.height]}createHost(){const t=document.createElement("div");return t.style.width="100%",t.style.height="100%",t.style.position="relative",t.style.overflow="hidden",t}createCanvas(){const t=document.createElement("canvas");return t.style.position="absolute",t.style.inset="0",t}createNodesContainer(){const t=document.createElement("div");return t.style.position="absolute",t.style.top="0",t.style.left="0",t.style.width="0",t.style.height="0",t}createConnectionsContainer(){const t=document.createElement("div");return t.style.position="absolute",t.style.pointerEvents="none",t.style.top="0",t.style.left="0",t.style.width="0",t.style.height="0",t}createHostResizeObserver(){return new ResizeObserver(()=>{this.updateCanvasDimensions(),this.applyTransform()})}createNodesResizeObserver(){return new ResizeObserver(t=>{t.forEach(e=>{const o=e.target,n=this.nodeWrapperElementToIdMap.get(o),i=this.di.graphStore.getNode(n);this.updateNodeCoords(n,i.x,i.y),this.di.graphStore.getNodeAdjacentConnections(n).forEach(a=>{this.updateConnectionCoords(a)})})})}updateCanvasDimensions(){const{width:t,height:e}=this.host.getBoundingClientRect();this.canvas.width=t,this.canvas.height=e}updateNodeCoords(t,e,o){const n=this.nodeIdToWrapperElementMap.get(t),{width:i,height:c}=n.getBoundingClientRect(),a=this.di.viewportTransformer.getAbsScale(),h=this.di.graphStore.getNode(t),[l,m]=h.centerFn(i,c);n.style.transform=`matrix(1, 0, 0, 1, ${e-a*l}, ${o-a*m})`}updateConnectionCoords(t){const e=this.di.graphStore.getConnection(t),o=this.di.graphStore.getPort(e.from),n=this.di.graphStore.getPort(e.to),i=o.element.getBoundingClientRect(),c=n.element.getBoundingClientRect(),a=this.host.getBoundingClientRect(),[h,l]=this.di.viewportTransformer.getAbsCoords(i.left-a.left,i.top-a.top),[m,d]=this.di.viewportTransformer.getAbsCoords(c.left-a.left,c.top-a.top),g=this.di.viewportTransformer.getAbsScale(),[u,p]=o.centerFn(i.width*g,i.height*g),[b,S]=n.centerFn(c.width*g,c.height*g),T=u+h,N=p+l,E=b+m,f=S+d,y=Math.min(T,E),A=Math.min(N,f),$=Math.abs(E-T),_=Math.abs(f-N),I=this.connectionIdToElementMap.get(t),tt=T<=E,et=N<=f;I.style.transform=`matrix(${tt?1:-1}, 0, 0, ${et?1:-1}, ${y}, ${A})`,e.controller.update(y,A,$,_,o,n)}}class W{constructor(){r(this,"state",{scale:1,x:0,y:0})}applyShift(t,e){this.state={scale:this.state.scale,x:this.state.scale*t+this.state.x,y:this.state.scale*e+this.state.y}}applyScale(t,e,o){this.state={scale:this.state.scale*t,x:this.state.scale*(1-t)*e+this.state.x,y:this.state.scale*(1-t)*o+this.state.y}}getViewCoords(t,e){return[(t-this.state.x)/this.state.scale,(e-this.state.y)/this.state.scale]}getViewScale(){return 1/this.state.scale}getAbsCoords(t,e){return[t*this.state.scale+this.state.x,e*this.state.scale+this.state.y]}getAbsScale(){return this.state.scale}patchState(t,e,o){this.state={scale:t??this.state.scale,x:e??this.state.x,y:o??this.state.y}}}class D{constructor(t){this.transformer=t}getViewCoords(t,e){return this.transformer.getViewCoords(t,e)}getViewScale(){return this.transformer.getViewScale()}getAbsCoords(t,e){return this.transformer.getAbsCoords(t,e)}getAbsScale(){return this.transformer.getAbsScale()}}class C{static getPortCenter(t){const{top:e,left:o,width:n,height:i}=t.element.getBoundingClientRect(),c=t.centerFn(n,i);return[o+c[0],e+c[1]]}static rotate(t,e,o){return[e[0]*t[0]-e[1]*t[1]+((1-e[0])*o[0]+e[1]*o[1]),e[1]*t[0]+e[0]*t[1]+((1-e[0])*o[1]-e[1]*o[0])]}static getDirectionVector(t,e,o){return[e*Math.cos(t??0),o*Math.sin(t??0)]}static getArrowPath(t,e,o,n,i){const a=[[0,0],[n,i],[n,-i]].map(d=>this.rotate(d,t,[0,0])).map(d=>[d[0]+e,d[1]+o]),h=`M ${a[0][0]} ${a[0][1]}`,l=`L ${a[1][0]} ${a[1][1]}`,m=`L ${a[2][0]} ${a[2][1]}`;return`${h} ${l} ${m}`}static getArrowOffsetPath(t,e,o,n,i){const a=[[n,0],[n+i,0]].map(h=>this.rotate(h,t,[0,0])).map(h=>[h[0]+e,h[1]+o]);return`M ${a[0][0]} ${a[0][1]} L ${a[1][0]} ${a[1][1]}`}}class x{constructor(t,e,o,n,i,c,a){r(this,"svg");r(this,"group");r(this,"line");r(this,"sourceArrow",null);r(this,"targetArrow",null);this.color=t,this.width=e,this.curvature=o,this.arrowLength=n,this.arrowWidth=i,this.hasSourceArrow=c,this.hasTargetArrow=a,this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.pointerEvents="none",this.group=document.createElementNS("http://www.w3.org/2000/svg","g"),this.svg.appendChild(this.group),this.line=document.createElementNS("http://www.w3.org/2000/svg","path"),this.line.setAttribute("stroke",this.color),this.line.setAttribute("stroke-width",`${this.width}`),this.line.setAttribute("fill","none"),this.group.appendChild(this.line),this.group.style.transformOrigin="50% 50%",this.hasSourceArrow&&(this.sourceArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.sourceArrow.setAttribute("fill",this.color),this.group.appendChild(this.sourceArrow)),this.hasTargetArrow&&(this.targetArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.targetArrow.setAttribute("fill",this.color),this.group.appendChild(this.targetArrow)),this.svg.style.overflow="visible"}update(t,e,o,n,i,c){this.svg.style.width=`${o}px`,this.svg.style.height=`${n}px`;const a=C.getPortCenter(i),h=C.getPortCenter(c),l=a[0]<=h[0]?1:-1,m=a[1]<=h[1]?1:-1;this.svg.style.transform=`translate(${t}px, ${e}px)`,this.group.style.transform=`scale(${l}, ${m})`;const d=C.getDirectionVector(i.direction,l,m),g=C.getDirectionVector(c.direction,l,m),u=C.rotate([this.arrowLength,0],d,[0,0]),p=C.rotate([o-this.arrowLength,n],g,[o,n]),b=[u[0]+d[0]*this.curvature,u[1]+d[1]*this.curvature],S=[p[0]-g[0]*this.curvature,p[1]-g[1]*this.curvature],T=`M ${u[0]} ${u[1]}`,N=`C ${b[0]} ${b[1]}, ${S[0]} ${S[1]}, ${p[0]} ${p[1]}`,E=`M 0 0 L ${u[0]} ${u[1]} `,f=` M ${p[0]} ${p[1]} L ${o} ${n}`,y=`${this.sourceArrow?"":E}${T} ${N}${this.targetArrow?"":f}`;if(this.line.setAttribute("d",y),this.sourceArrow){const A=C.getArrowPath(d,0,0,this.arrowLength,this.arrowWidth);this.sourceArrow.setAttribute("d",A)}if(this.targetArrow){const A=C.getArrowPath(g,o,n,-this.arrowLength,this.arrowWidth);this.targetArrow.setAttribute("d",A)}}}const z=s=>()=>new x(s.color??"#5c5c5c",s.width??1,s.curvature??90,s.arrowLength??15,s.arrowWidth??4,s.hasSourceArrow??!1,s.hasTargetArrow??!1);class M{constructor(t,e,o,n,i,c,a){r(this,"svg");r(this,"group");r(this,"line");r(this,"sourceArrow",null);r(this,"targetArrow",null);this.color=t,this.width=e,this.arrowLength=o,this.arrowWidth=n,this.minPortOffset=i,this.hasSourceArrow=c,this.hasTargetArrow=a,this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.pointerEvents="none",this.group=document.createElementNS("http://www.w3.org/2000/svg","g"),this.svg.appendChild(this.group),this.line=document.createElementNS("http://www.w3.org/2000/svg","path"),this.line.setAttribute("stroke",this.color),this.line.setAttribute("stroke-width",`${this.width}`),this.line.setAttribute("fill","none"),this.group.appendChild(this.line),this.group.style.transformOrigin="50% 50%",this.hasSourceArrow&&(this.sourceArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.sourceArrow.setAttribute("fill",this.color),this.group.appendChild(this.sourceArrow)),this.hasTargetArrow&&(this.targetArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.targetArrow.setAttribute("fill",this.color),this.group.appendChild(this.targetArrow)),this.svg.style.overflow="visible"}update(t,e,o,n,i,c){this.svg.style.width=`${o}px`,this.svg.style.height=`${n}px`;const a=C.getPortCenter(i),h=C.getPortCenter(c),l=a[0]<=h[0]?1:-1,m=a[1]<=h[1]?1:-1;this.svg.style.transform=`translate(${t}px, ${e}px)`,this.group.style.transform=`scale(${l}, ${m})`;const d=C.getDirectionVector(i.direction,l,m),g=C.getDirectionVector(c.direction,l,m),u=C.rotate([this.arrowLength+this.minPortOffset,0],d,[0,0]),p=C.rotate([o-this.arrowLength-this.minPortOffset,n],g,[o,n]),[b,S]=[o/2,n/2],T=l*(p[0]-u[0])>0?`M ${u[0]} ${u[1]} L ${b} ${u[1]} L ${b} ${p[1]} L ${p[0]} ${p[1]}`:`M ${u[0]} ${u[1]} L ${u[0]} ${S} L ${p[0]} ${S} L ${p[0]} ${p[1]}`,N=`M 0 0 L ${u[0]} ${u[1]} `,E=` M ${p[0]} ${p[1]} L ${o} ${n}`,f=C.getArrowOffsetPath(d,0,0,this.arrowLength,this.minPortOffset),y=C.getArrowOffsetPath(g,o,n,-this.arrowLength,-this.minPortOffset),A=`${this.sourceArrow?f:N}${T}${this.targetArrow?y:E}`;if(this.line.setAttribute("d",A),this.sourceArrow){const $=C.getArrowPath(d,0,0,this.arrowLength,this.arrowWidth);this.sourceArrow.setAttribute("d",$)}if(this.targetArrow){const $=C.getArrowPath(g,o,n,-this.arrowLength,this.arrowWidth);this.targetArrow.setAttribute("d",$)}}}const R=s=>()=>new M(s.color,s.width,s.arrowLength,s.arrowWidth,s.minPortOffset,s.hasSourceArrow,s.hasTargetArrow),L=s=>{switch(s==null?void 0:s.type){case"custom":return s.controllerFactory;case"straight":return R({color:s.color??"#5c5c5c",width:s.width??1,arrowLength:s.arrowLength??15,arrowWidth:s.arrowWidth??4,minPortOffset:s.minPortOffset??15,hasSourceArrow:s.hasSourceArrow??!1,hasTargetArrow:s.hasTargetArrow??!1});default:return z({color:s.color??"#5c5c5c",width:s.width??1,curvature:s.curvature??90,arrowLength:s.arrowLength??15,arrowWidth:s.arrowWidth??4,hasSourceArrow:s.hasSourceArrow??!1,hasTargetArrow:s.hasTargetArrow??!1})}};class G{constructor(t){this.di=t}moveNodeOnTop(t){if(!this.di.graphStore.hasNode(t))throw new Error("failed to move on top nonexisting node");this.di.htmlController.moveNodeOnTop(t)}dragNode(t,e,o){if(!this.di.graphStore.hasNode(t))throw new Error("failed to drag nonexisting node");const n=this.di.graphStore.getNode(t),[i,c]=this.di.viewportTransformer.getViewCoords(n.x,n.y),a=i+e,h=c+o,[l,m]=this.di.viewportTransformer.getAbsCoords(a,h);this.di.graphStore.updateNodeCoords(t,l,m),this.di.htmlController.updateNodePosition(t)}addNode(t,e,o,n,i,c){if(t===void 0)do t=this.di.nodeIdGenerator.next();while(this.di.graphStore.hasNode(t));if(this.di.graphStore.hasNode(t))throw new Error("failed to add node with existing id");this.di.graphStore.addNode(t,e,o,n,c??this.di.options.nodes.centerFn),this.di.htmlController.attachNode(t),i!==void 0&&Object.entries(i).forEach(([a,h])=>{h instanceof HTMLElement?this.di.controller.markPort(a,h,t,this.di.options.ports.centerFn,null):this.di.controller.markPort(a,h.element,t,h.centerFn??this.di.options.ports.centerFn,h.direction??null)})}markPort(t,e,o,n,i){if(t===void 0)do t=this.di.portIdGenerator.next();while(this.di.graphStore.hasPort(t));if(!this.di.graphStore.hasNode(o))throw new Error("failed to set port on nonexisting node");if(this.di.graphStore.hasPort(t))throw new Error("failed to add port with existing id");this.di.graphStore.addPort(t,e,o,n??this.di.options.ports.centerFn,i??null)}updatePortConnections(t){if(!this.di.graphStore.hasPort(t))throw new Error("failed to unset nonexisting port");this.di.htmlController.updatePortConnections(t)}unmarkPort(t){if(!this.di.graphStore.hasPort(t))throw new Error("failed to unset nonexisting port");this.di.graphStore.getPortAdjacentConnections(t).forEach(e=>{this.removeConnection(e)}),this.di.graphStore.removePort(t)}addConnection(t,e,o,n){if(t===void 0)do t=this.di.connectionIdGenerator.next();while(this.di.graphStore.hasConnection(t));if(!this.di.graphStore.hasPort(e))throw new Error("failed to add connection from nonexisting port");if(!this.di.graphStore.hasPort(o))throw new Error("failed to add connection to nonexisting port");const i=n!==void 0?L(n):this.di.options.connections.controllerFactory;this.di.graphStore.addConnection(t,e,o,i()),this.di.htmlController.attachConnection(t)}removeConnection(t){if(!this.di.graphStore.hasConnection(t))throw new Error("failed to remove nonexisting connection");this.di.htmlController.detachConnection(t),this.di.graphStore.removeConnection(t)}removeNode(t){if(!this.di.graphStore.hasNode(t))throw new Error("failed to remove nonexisting node");this.di.htmlController.detachNode(t),this.di.graphStore.removeNode(t)}patchViewportTransform(t,e,o){this.di.viewportTransformer.patchState(t,e,o),this.di.htmlController.applyTransform()}moveContent(t,e){this.di.viewportTransformer.applyShift(-t,-e),this.di.htmlController.applyTransform()}scaleContent(t,e,o){this.di.viewportTransformer.applyScale(1/t,e,o),this.di.htmlController.applyTransform()}moveToNodes(t){if(t.length===0)return;const e=t.map(g=>this.di.graphStore.getNode(g)).filter(g=>g!==void 0);if(e.length<t.length)throw new Error("failed to move to nonexisting node");const[o,n]=e.reduce((g,u)=>[g[0]+u.x,g[1]+u.y],[0,0]),i=o/e.length,c=n/e.length,[a,h]=this.di.htmlController.getViewportDimensions(),l=this.di.viewportTransformer.getAbsScale(),m=i-l*a/2,d=c-l*h/2;this.patchViewportTransform(null,m,d)}updateNodeCoords(t,e,o){if(!this.di.graphStore.hasNode(t))throw new Error("failed to update coordinates of nonexisting node");this.di.graphStore.updateNodeCoords(t,e,o),this.di.htmlController.updateNodePosition(t)}updateConnectionOptions(t,e){if(e.controller!==void 0){if(!this.di.graphStore.hasConnection(t))throw new Error("failed to update nonexisting connection");this.di.htmlController.detachConnection(t),this.di.graphStore.updateConnectionController(t,e.controller),this.di.htmlController.attachConnection(t)}}clear(){this.di.htmlController.clear(),this.di.graphStore.clear(),this.di.nodeIdGenerator.reset(),this.di.portIdGenerator.reset(),this.di.connectionIdGenerator.reset()}destroy(){this.di.htmlController.destroy()}}class B{constructor(){r(this,"nodes",Object.create(null));r(this,"ports",Object.create(null));r(this,"nodePorts",Object.create(null));r(this,"portNodeId",Object.create(null));r(this,"connections",Object.create(null));r(this,"incommingConnections",Object.create(null));r(this,"outcommingConnections",Object.create(null));r(this,"cycleConnections",Object.create(null))}getAllNodes(){return Object.keys(this.nodes)}getAllPorts(){return Object.keys(this.ports)}getAllConnections(){return Object.keys(this.connections)}addNode(t,e,o,n,i){this.nodes[t]={element:e,x:o,y:n,centerFn:i},this.nodePorts[t]=Object.create(null)}hasNode(t){return this.nodes[t]!==void 0}getNode(t){return this.nodes[t]}updateNodeCoords(t,e,o){this.nodes[t].x=e,this.nodes[t].y=o}updateConnectionController(t,e){this.connections[t].controller=e}removeNode(t){this.getNodeAdjacentConnections(t).forEach(n=>{this.removeConnection(n)}),delete this.nodes[t];const o=this.nodePorts[t];Object.keys(o).forEach(n=>{delete this.portNodeId[n]}),delete this.nodePorts[t]}addPort(t,e,o,n,i){this.ports[t]={element:e,centerFn:n,direction:i},this.cycleConnections[t]={},this.incommingConnections[t]={},this.outcommingConnections[t]={},this.portNodeId[t]=o;const c=this.nodePorts[o];c!==void 0&&(c[t]=e)}getPort(t){return this.ports[t]}getPortNode(t){return this.portNodeId[t]}hasPort(t){return this.portNodeId[t]!==void 0}removePort(t){Object.keys(this.cycleConnections[t]).forEach(n=>{this.removeConnection(n)}),delete this.cycleConnections[t],Object.keys(this.incommingConnections[t]).forEach(n=>{this.removeConnection(n)}),delete this.incommingConnections[t],Object.keys(this.outcommingConnections[t]).forEach(n=>{this.removeConnection(n)}),delete this.outcommingConnections[t];const e=this.portNodeId[t];delete this.portNodeId[t];const o=this.nodePorts[e];delete o[t],delete this.ports[t]}addConnection(t,e,o,n){this.connections[t]={from:e,to:o,controller:n},e!==o?(this.outcommingConnections[e][t]=!0,this.incommingConnections[o][t]=!0):this.cycleConnections[e][t]=!0}getConnection(t){return this.connections[t]}hasConnection(t){return this.connections[t]!==void 0}removeConnection(t){const e=this.connections[t],o=e.from,n=e.to;delete this.cycleConnections[o][t],delete this.cycleConnections[n][t],delete this.incommingConnections[o][t],delete this.incommingConnections[n][t],delete this.outcommingConnections[o][t],delete this.outcommingConnections[n][t],delete this.connections[t]}getPortIncomingConnections(t){return Object.keys(this.incommingConnections[t]??{})}getPortOutcomingConnections(t){return Object.keys(this.outcommingConnections[t]??{})}getPortCycleConnections(t){return Object.keys(this.cycleConnections[t]??{})}getPortAdjacentConnections(t){return[...this.getPortIncomingConnections(t),...this.getPortOutcomingConnections(t),...this.getPortCycleConnections(t)]}getNodeIncomingConnections(t){const e=Object.keys(this.nodePorts[t]);let o=[];return e.forEach(n=>{o=[...o,...this.getPortIncomingConnections(n)]}),o}getNodeOutcomingConnections(t){const e=Object.keys(this.nodePorts[t]);let o=[];return e.forEach(n=>{o=[...o,...this.getPortOutcomingConnections(n)]}),o}getNodeCycleConnections(t){const e=Object.keys(this.nodePorts[t]);let o=[];return e.forEach(n=>{o=[...o,...this.getPortCycleConnections(n)]}),o}getNodeAdjacentConnections(t){return[...this.getNodeIncomingConnections(t),...this.getNodeOutcomingConnections(t),...this.getNodeCycleConnections(t)]}clear(){this.nodes=Object.create(null),this.ports=Object.create(null),this.nodePorts=Object.create(null),this.portNodeId=Object.create(null),this.connections=Object.create(null),this.incommingConnections=Object.create(null),this.outcommingConnections=Object.create(null),this.cycleConnections=Object.create(null)}}class O{constructor(){r(this,"counter",0)}next(){const t=`${this.counter}`;return this.counter++,t}reset(){this.counter=0}}class Y{constructor(t){this.graphStore=t}getNode(t){const e=this.graphStore.getNode(t);return e===void 0?null:{x:e.x,y:e.y}}getPort(t){const e=this.graphStore.getPortNode(t);return e===void 0?null:{nodeId:e}}getConnection(t){const e=this.graphStore.getConnection(t);return e===void 0?null:{from:e.from,to:e.to}}getAllNodes(){return this.graphStore.getAllNodes()}getAllPorts(){return this.graphStore.getAllPorts()}getAllConnections(){return this.graphStore.getAllConnections()}hasNode(t){return this.graphStore.hasNode(t)}hasPort(t){return this.graphStore.hasPort(t)}hasConnection(t){return this.graphStore.hasConnection(t)}getPortIncomingConnections(t){return this.graphStore.getPortIncomingConnections(t)}getPortOutcomingConnections(t){return this.graphStore.getPortOutcomingConnections(t)}getPortCycleConnections(t){return this.graphStore.getPortCycleConnections(t)}getPortAdjacentConnections(t){return this.graphStore.getPortAdjacentConnections(t)}getNodeIncomingConnections(t){return this.graphStore.getNodeIncomingConnections(t)}getNodeOutcomingConnections(t){return this.graphStore.getNodeOutcomingConnections(t)}getNodeCycleConnections(t){return this.graphStore.getNodeCycleConnections(t)}getNodeAdjacentConnections(t){return this.graphStore.getNodeAdjacentConnections(t)}}class X{constructor(t){r(this,"htmlController");r(this,"viewportTransformer");r(this,"publicViewportTransformer");r(this,"controller");r(this,"graphStore");r(this,"publicGraphStore");r(this,"nodeIdGenerator");r(this,"portIdGenerator");r(this,"connectionIdGenerator");this.options=t,this.htmlController=new P(this),this.viewportTransformer=new W,this.publicViewportTransformer=new D(this.viewportTransformer),this.controller=new G(this),this.graphStore=new B,this.publicGraphStore=new Y(this.graphStore),this.nodeIdGenerator=new O,this.portIdGenerator=new O,this.connectionIdGenerator=new O}}const V=(s,t)=>[s/2,t/2],Z=(s,t,e,o,n,i)=>{s.fillStyle=i,s.fillRect(0,0,s.canvas.width,s.canvas.height);const c=t.getViewCoords(0,0),a=t.getViewScale(),h=o*a;let l=0,m=0,d=h/2;do d*=2,l=s.canvas.width/d,m=s.canvas.height/d;while(l*m>1e4);const g=c[0]-Math.floor(c[0]/d)*d,u=c[1]-Math.floor(c[1]/d)*d,p=n*a,b=2*Math.PI,S=g-d,T=u-d,N=s.canvas.width+g,E=s.canvas.height+u;s.fillStyle=e;for(let f=S;f<=N;f+=d)for(let y=T;y<=E;y+=d)s.beginPath(),s.arc(f,y,p,0,b),s.closePath(),s.fill()},H=(s,t)=>{s.fillStyle=t,s.fillRect(0,0,s.canvas.width,s.canvas.height)},U=(s,t,e,o)=>(n,i)=>{Z(n,i,s,t,e,o)},q=()=>()=>{},J=s=>t=>{H(t,s)},K=s=>{switch(s==null?void 0:s.type){case"custom":return s.drawingFn;case"dots":return U(s.dotColor??"#d8d8d8",s.dotGap??25,s.dotRadius??1.5,s.color??"#ffffff");case"color":return J(s.color??"#ffffff");default:return q()}},Q=s=>{var t,e,o;return{background:{drawingFn:K(s.background)},nodes:{centerFn:((t=s.nodes)==null?void 0:t.centerFn)??V},ports:{centerFn:((e=s.ports)==null?void 0:e.centerFn)??V},connections:{controllerFactory:L(s.connections??{})},layers:{mode:((o=s.layers)==null?void 0:o.mode)??"connections-follow-node"}}};class j{constructor(t){r(this,"transformation");r(this,"model");r(this,"options");r(this,"di");this.apiOptions=t,this.options=Q(this.apiOptions??{}),this.di=new X(this.options),this.transformation=this.di.publicViewportTransformer,this.model=this.di.publicGraphStore}addNode(t){return this.di.controller.addNode(t.id,t.element,t.x,t.y,t.ports,t.centerFn),this}moveNodeOnTop(t){return this.di.controller.moveNodeOnTop(t),this}removeNode(t){return this.di.controller.removeNode(t),this}markPort(t){return this.di.controller.markPort(t.id,t.element,t.nodeId,t.centerFn,t.direction),this}updatePortConnections(t){return this.di.controller.updatePortConnections(t),this}unmarkPort(t){return this.di.controller.unmarkPort(t),this}addConnection(t){return this.di.controller.addConnection(t.id,t.from,t.to,t.options),this}removeConnection(t){return this.di.controller.removeConnection(t),this}patchViewportTransform(t){return this.di.controller.patchViewportTransform(t.scale??null,t.x??null,t.y??null),this}moveContent(t){return this.di.controller.moveContent(t.x??0,t.y??0),this}scaleContent(t){return this.di.controller.scaleContent(t.scale,t.x??0,t.y??0),this}moveToNodes(t){return this.di.controller.moveToNodes(t),this}updateNodeCoords(t,e,o){return this.di.controller.updateNodeCoords(t,e,o),this}updateConnectionOptions(t,e){return this.di.controller.updateConnectionOptions(t,e),this}dragNode(t,e,o){return this.di.controller.dragNode(t,e,o),this}clear(){return this.di.controller.clear(),this}attach(t){return this.di.htmlController.attach(t),this}detach(){return this.di.htmlController.detach(),this}destroy(){this.di.controller.destroy()}}class k{constructor(t){r(this,"transformation");r(this,"model");r(this,"nodes",new Map);r(this,"grabbedNodeId",null);r(this,"nodeIdGenerator",new O);r(this,"element",null);r(this,"onCanvasMouseUp",()=>{this.setCursor(null),this.grabbedNodeId=null});r(this,"onCanvasMouseMove",t=>{this.grabbedNodeId!==null&&(t.stopPropagation(),this.canvas.dragNode(this.grabbedNodeId,t.movementX,t.movementY))});r(this,"onCanvasTouchStart",t=>{this.previousTouchCoords=[t.touches[0].clientX,t.touches[0].clientY]});r(this,"onCanvasTouchMove",t=>{if(this.grabbedNodeId===null||t.touches.length!==1||this.previousTouchCoords===null)return;t.stopImmediatePropagation();const[e,o]=[t.touches[0].clientX-this.previousTouchCoords[0],t.touches[0].clientY-this.previousTouchCoords[1]];this.canvas.dragNode(this.grabbedNodeId,e,o),this.previousTouchCoords=[t.touches[0].clientX,t.touches[0].clientY]});r(this,"onCanvasTouchEnd",()=>{this.previousTouchCoords=null,this.grabbedNodeId=null});r(this,"previousTouchCoords",null);this.canvas=t,this.transformation=this.canvas.transformation,this.model=this.canvas.model}addNode(t){let e=t.id;if(e===void 0)do e=this.nodeIdGenerator.next();while(this.nodes.has(e));this.canvas.addNode(t);const o=i=>{i.stopImmediatePropagation(),this.grabbedNodeId=e,this.setCursor("grab"),this.canvas.moveNodeOnTop(e)},n=i=>{i.touches.length===1&&(this.grabbedNodeId=e,this.canvas.moveNodeOnTop(e))};return this.nodes.set(e,{el:t.element,onMouseDown:o,onTouchStart:n}),t.element.addEventListener("mousedown",o),t.element.addEventListener("touchstart",n),this}removeNode(t){const e=this.nodes.get(t);return e!==void 0&&(e.el.removeEventListener("mousedown",e.onMouseDown),e.el.removeEventListener("touchstart",e.onTouchStart)),this.canvas.removeNode(t),this.nodes.delete(t),this}markPort(t){return this.canvas.markPort(t),this}updatePortConnections(t){return this.canvas.updatePortConnections(t),this}unmarkPort(t){return this.canvas.unmarkPort(t),this}addConnection(t){return this.canvas.addConnection(t),this}removeConnection(t){return this.canvas.removeConnection(t),this}patchViewportTransform(t){return this.canvas.patchViewportTransform(t),this}moveContent(t){return this.canvas.moveContent(t),this}scaleContent(t){return this.canvas.scaleContent(t),this}moveToNodes(t){return this.canvas.moveToNodes(t),this}updateNodeCoords(t,e,o){return this.canvas.updateNodeCoords(t,e,o),this}updateConnectionOptions(t,e){return this.canvas.updateConnectionOptions(t,e),this}dragNode(t,e,o){return this.canvas.dragNode(t,e,o),this}moveNodeOnTop(t){return this.canvas.moveNodeOnTop(t),this}clear(){return this.canvas.clear(),this.nodes.forEach(t=>{t.el.removeEventListener("mousedown",t.onMouseDown),t.el.removeEventListener("touchstart",t.onTouchStart)}),this.nodes.clear(),this}attach(t){return this.canvas.attach(t),this.element=t,t.addEventListener("mouseup",this.onCanvasMouseUp),t.addEventListener("mousemove",this.onCanvasMouseMove),t.addEventListener("touchstart",this.onCanvasTouchStart),t.addEventListener("touchmove",this.onCanvasTouchMove),t.addEventListener("touchend",this.onCanvasTouchEnd),t.addEventListener("touchcancel",this.onCanvasTouchEnd),this}detach(){return this.canvas.detach(),this.element!==null&&(this.element.removeEventListener("mouseup",this.onCanvasMouseUp),this.element.removeEventListener("mousemove",this.onCanvasMouseMove),this.element.removeEventListener("touchstart",this.onCanvasTouchStart),this.element.removeEventListener("touchmove",this.onCanvasTouchMove),this.element.removeEventListener("touchend",this.onCanvasTouchEnd),this.element.removeEventListener("touchcancel",this.onCanvasTouchEnd),this.element=null),this}destroy(){this.detach(),this.nodes.forEach(t=>{t.el.removeEventListener("mousedown",t.onMouseDown),t.el.removeEventListener("touchstart",t.onTouchStart)}),this.canvas.destroy()}setCursor(t){this.element!==null&&(t!==null?this.element.style.cursor=t:this.element.style.removeProperty("cursor"))}}class F{constructor(t,e){r(this,"transformation");r(this,"model");r(this,"element",null);r(this,"isMoving",!1);r(this,"prevTouches",null);r(this,"isScalable");r(this,"isShiftable");r(this,"minContentScale");r(this,"maxContentScale");r(this,"wheelSensitivity");r(this,"onMouseDown",()=>{this.setCursor("grab"),this.isMoving=!0});r(this,"onMouseMove",t=>{!this.isMoving||!this.isShiftable||this.canvas.moveContent({x:t.movementX,y:t.movementY})});r(this,"onMouseUp",()=>{this.setCursor(null),this.isMoving=!1});r(this,"onWheelScroll",t=>{if(this.element===null||this.isScalable===!1)return;t.preventDefault();const{left:e,top:o}=this.element.getBoundingClientRect(),n=t.clientX-e,i=t.clientY-o,c=t.deltaY<0?this.wheelSensitivity:1/this.wheelSensitivity,a=this.canvas.transformation.getViewScale()*c;this.checkNextScaleValid(a)&&this.canvas.scaleContent({scale:c,x:n,y:i})});r(this,"onTouchStart",t=>{this.prevTouches=this.getAverageTouch(t)});r(this,"onTouchMove",t=>{if(this.prevTouches===null||this.element===null||!this.isShiftable)return;const e=this.getAverageTouch(t);if((e.touchesCnt===1||e.touchesCnt===2)&&this.canvas.moveContent({x:e.x-this.prevTouches.x,y:e.y-this.prevTouches.y}),e.touchesCnt===2&&this.isScalable){const{left:o,top:n}=this.element.getBoundingClientRect(),i=this.prevTouches.x-o,c=this.prevTouches.y-n,a=e.scale/this.prevTouches.scale,h=this.canvas.transformation.getViewScale()*a;this.checkNextScaleValid(h)&&this.canvas.scaleContent({scale:a,x:i,y:c})}this.prevTouches=e,t.preventDefault()});r(this,"onTouchEnd",()=>{this.prevTouches=null});var n,i,c,a,h,l,m,d,g,u;this.canvas=t,this.options=e,this.transformation=this.canvas.transformation,this.model=this.canvas.model,this.isScalable=((i=(n=this.options)==null?void 0:n.scale)==null?void 0:i.enabled)!==!1,this.minContentScale=((a=(c=this.options)==null?void 0:c.scale)==null?void 0:a.minContent)??null,this.maxContentScale=((l=(h=this.options)==null?void 0:h.scale)==null?void 0:l.maxContent)??null,this.isShiftable=((d=(m=this.options)==null?void 0:m.shift)==null?void 0:d.enabled)!==!1;const o=(u=(g=this.options)==null?void 0:g.scale)==null?void 0:u.wheelSensitivity;this.wheelSensitivity=o!==void 0?o:1.2}addNode(t){return this.canvas.addNode(t),this}removeNode(t){return this.canvas.removeNode(t),this}markPort(t){return this.canvas.markPort(t),this}updatePortConnections(t){return this.canvas.updatePortConnections(t),this}unmarkPort(t){return this.canvas.unmarkPort(t),this}addConnection(t){return this.canvas.addConnection(t),this}removeConnection(t){return this.canvas.removeConnection(t),this}patchViewportTransform(t){return this.canvas.patchViewportTransform(t),this}moveContent(t){return this.canvas.moveContent(t),this}scaleContent(t){return this.canvas.scaleContent(t),this}moveToNodes(t){return this.canvas.moveToNodes(t),this}updateNodeCoords(t,e,o){return this.canvas.updateNodeCoords(t,e,o),this}updateConnectionOptions(t,e){return this.canvas.updateConnectionOptions(t,e),this}dragNode(t,e,o){return this.canvas.dragNode(t,e,o),this}moveNodeOnTop(t){return this.canvas.moveNodeOnTop(t),this}clear(){return this.canvas.clear(),this}attach(t){return this.canvas.attach(t),this.element=t,t.addEventListener("mousedown",this.onMouseDown),t.addEventListener("mousemove",this.onMouseMove),t.addEventListener("mouseup",this.onMouseUp),t.addEventListener("wheel",this.onWheelScroll),t.addEventListener("touchstart",this.onTouchStart),t.addEventListener("touchmove",this.onTouchMove),t.addEventListener("touchend",this.onTouchEnd),t.addEventListener("touchcancel",this.onTouchEnd),this}detach(){return this.canvas.detach(),this.element!==null&&(this.element.removeEventListener("mousedown",this.onMouseDown),this.element.removeEventListener("mousemove",this.onMouseMove),this.element.removeEventListener("mouseup",this.onMouseUp),this.element.removeEventListener("wheel",this.onWheelScroll),this.element.removeEventListener("touchstart",this.onTouchStart),this.element.removeEventListener("touchmove",this.onTouchMove),this.element.removeEventListener("touchend",this.onTouchEnd),this.element.removeEventListener("touchcancel",this.onTouchEnd)),this.element=null,this}destroy(){this.detach(),this.canvas.destroy()}getAverageTouch(t){const e=[],o=t.touches.length;for(let h=0;h<o;h++)e.push([t.touches[h].clientX,t.touches[h].clientY]);const n=e.reduce((h,l)=>[h[0]+l[0],h[1]+l[1]],[0,0]),i=[n[0]/o,n[1]/o],a=e.map(h=>[h[0]-i[0],h[1]-i[1]]).reduce((h,l)=>h+Math.sqrt(l[0]*l[0]+l[1]*l[1]),0);return{x:i[0],y:i[1],scale:a/o,touchesCnt:o}}checkNextScaleValid(t){const e=this.canvas.transformation.getViewScale();return!(this.maxContentScale!==null&&t>this.maxContentScale&&t>e||this.minContentScale!==null&&t<this.minContentScale&&t<e)}setCursor(t){this.element!==null&&(t!==null?this.element.style.cursor=t:this.element.style.removeProperty("cursor"))}}v.BezierConnectionController=x,v.CanvasBuilder=w,v.CanvasCore=j,v.ConnectionUtils=C,v.DraggableNodesCanvas=k,v.StraightConnectionController=M,v.TransformableCanvas=F,Object.defineProperty(v,Symbol.toStringTag,{value:"Module"})});
1
+ (function(p,w){typeof exports=="object"&&typeof module<"u"?w(exports):typeof define=="function"&&define.amd?define(["exports"],w):(p=typeof globalThis<"u"?globalThis:p||self,w(p.HTMLGraph={}))})(this,function(p){"use strict";var nt=Object.defineProperty;var st=(p,w,P)=>w in p?nt(p,w,{enumerable:!0,configurable:!0,writable:!0,value:P}):p[w]=P;var r=(p,w,P)=>st(p,typeof w!="symbol"?w+"":w,P);class w{constructor(t){r(this,"canvasWrapper",null);r(this,"host");r(this,"nodesContainer");r(this,"connectionsContainer");r(this,"canvas");r(this,"canvasCtx");r(this,"hostResizeObserver");r(this,"nodesResizeObserver");r(this,"nodeElementToIdMap",new Map);r(this,"nodeWrapperElementToIdMap",new Map);r(this,"nodeIdToWrapperElementMap",new Map);r(this,"connectionIdToElementMap",new Map);r(this,"currentZIndex",0);r(this,"layers",{"connections-on-top":{create:()=>{this.host.appendChild(this.nodesContainer),this.host.appendChild(this.connectionsContainer)},update:(t,e,o)=>{this.nodesContainer.style.transform=`matrix(${t}, 0, 0, ${t}, ${e}, ${o})`,this.connectionsContainer.style.transform=`matrix(${t}, 0, 0, ${t}, ${e}, ${o})`},moveOnTop:t=>{this.currentZIndex+=1;const e=this.nodeIdToWrapperElementMap.get(t);e.style.zIndex=`${this.currentZIndex}`}},"connections-follow-node":{create:()=>{this.host.appendChild(this.nodesContainer),this.connectionsContainer=this.nodesContainer},update:(t,e,o)=>{this.nodesContainer.style.transform=`matrix(${t}, 0, 0, ${t}, ${e}, ${o})`},moveOnTop:t=>{const e=this.nodeIdToWrapperElementMap.get(t);this.currentZIndex+=2,e.style.zIndex=`${this.currentZIndex}`,this.di.graphStore.getNodeAdjacentConnections(t).forEach(s=>{this.connectionIdToElementMap.get(s).style.zIndex=`${this.currentZIndex-1}`})}},"nodes-on-top":{create:()=>{this.host.appendChild(this.connectionsContainer),this.host.appendChild(this.nodesContainer)},update:(t,e,o)=>{this.nodesContainer.style.transform=`matrix(${t}, 0, 0, ${t}, ${e}, ${o})`,this.connectionsContainer.style.transform=`matrix(${t}, 0, 0, ${t}, ${e}, ${o})`},moveOnTop:t=>{this.currentZIndex+=1;const e=this.nodeIdToWrapperElementMap.get(t);e.style.zIndex=`${this.currentZIndex}`}}});this.di=t,this.host=this.createHost(),this.canvas=this.createCanvas(),this.nodesContainer=this.createNodesContainer(),this.connectionsContainer=this.createConnectionsContainer();const e=this.canvas.getContext("2d");if(e===null)throw new Error("unable to get canvas context");this.canvasCtx=e,this.host.appendChild(this.canvas);const o=this.di.options.layers.mode;this.layers[o].create(),this.hostResizeObserver=this.createHostResizeObserver(),this.hostResizeObserver.observe(this.host),this.nodesResizeObserver=this.createNodesResizeObserver()}clear(){Array.from(this.connectionIdToElementMap.keys()).forEach(t=>{this.detachConnection(t)}),Array.from(this.nodeElementToIdMap.values()).forEach(t=>{this.detachNode(t)})}attach(t){this.canvasWrapper=t,this.canvasWrapper.appendChild(this.host)}detach(){this.canvasWrapper!==null&&this.canvasWrapper.removeChild(this.host)}destroy(){this.hostResizeObserver.disconnect(),this.nodesResizeObserver.disconnect(),this.host.removeChild(this.canvas),this.host.removeChild(this.connectionsContainer),this.host.removeChild(this.nodesContainer),this.canvasWrapper!==null&&this.canvasWrapper.removeChild(this.host)}applyTransform(){this.canvasCtx.clearRect(0,0,this.canvasCtx.canvas.width,this.canvasCtx.canvas.height),this.canvasCtx.save(),this.di.options.background.drawingFn(this.canvasCtx,this.di.publicViewportTransformer),this.canvasCtx.restore();const[t,e]=this.di.viewportTransformer.getViewCoords(0,0),o=this.di.viewportTransformer.getViewScale();this.layers[this.di.options.layers.mode].update(o,t,e)}attachNode(t){const e=this.di.graphStore.getNode(t),o=document.createElement("div");o.appendChild(e.element),o.style.position="absolute",o.style.top="0",o.style.left="0",o.style.zIndex=`${this.currentZIndex}`,this.currentZIndex+=1,o.style.visibility="hidden",this.nodesContainer.appendChild(o),this.nodeElementToIdMap.set(e.element,t),this.nodeWrapperElementToIdMap.set(o,t),this.nodeIdToWrapperElementMap.set(t,o),this.updateNodeCoords(t,e.x,e.y),this.nodesResizeObserver.observe(o),o.style.visibility="visible"}detachNode(t){const e=this.di.graphStore.getNode(t);this.nodesResizeObserver.unobserve(e.element),this.nodesContainer.removeChild(e.element);const o=this.nodeIdToWrapperElementMap.get(t);o.removeChild(e.element),this.nodeElementToIdMap.delete(e.element),this.nodeWrapperElementToIdMap.delete(o),this.nodeIdToWrapperElementMap.delete(t)}attachConnection(t){const o=this.di.graphStore.getConnection(t).controller.svg;o.style.transformOrigin="50% 50%",o.style.position="absolute",o.style.top="0",o.style.left="0",o.style.zIndex=`${this.currentZIndex}`,this.currentZIndex+=1,this.connectionIdToElementMap.set(t,o),this.updateConnectionCoords(t),this.connectionsContainer.appendChild(o)}detachConnection(t){const e=this.connectionIdToElementMap.get(t);this.connectionIdToElementMap.delete(t),this.connectionsContainer.removeChild(e)}moveNodeOnTop(t){this.layers[this.di.options.layers.mode].moveOnTop(t)}updateNodePosition(t){const e=this.di.graphStore.getNode(t),o=this.di.graphStore.getNodeAdjacentConnections(t);this.updateNodeCoords(t,e.x,e.y),o.forEach(s=>{this.updateConnectionCoords(s)})}updatePortConnections(t){this.di.graphStore.getPortAdjacentConnections(t).forEach(o=>{this.updateConnectionCoords(o)})}getViewportDimensions(){const t=this.host.getBoundingClientRect();return[t.width,t.height]}createHost(){const t=document.createElement("div");return t.style.width="100%",t.style.height="100%",t.style.position="relative",t.style.overflow="hidden",t}createCanvas(){const t=document.createElement("canvas");return t.style.position="absolute",t.style.inset="0",t}createNodesContainer(){const t=document.createElement("div");return t.style.position="absolute",t.style.top="0",t.style.left="0",t.style.width="0",t.style.height="0",t}createConnectionsContainer(){const t=document.createElement("div");return t.style.position="absolute",t.style.pointerEvents="none",t.style.top="0",t.style.left="0",t.style.width="0",t.style.height="0",t}createHostResizeObserver(){return new ResizeObserver(()=>{this.updateCanvasDimensions(),this.applyTransform()})}createNodesResizeObserver(){return new ResizeObserver(t=>{t.forEach(e=>{const o=e.target,s=this.nodeWrapperElementToIdMap.get(o),i=this.di.graphStore.getNode(s);this.updateNodeCoords(s,i.x,i.y),this.di.graphStore.getNodeAdjacentConnections(s).forEach(a=>{this.updateConnectionCoords(a)})})})}updateCanvasDimensions(){const{width:t,height:e}=this.host.getBoundingClientRect();this.canvas.width=t,this.canvas.height=e}updateNodeCoords(t,e,o){const s=this.nodeIdToWrapperElementMap.get(t),{width:i,height:c}=s.getBoundingClientRect(),a=this.di.viewportTransformer.getAbsScale(),h=this.di.graphStore.getNode(t),[l,m]=h.centerFn(i,c);s.style.transform=`matrix(1, 0, 0, 1, ${e-a*l}, ${o-a*m})`}updateConnectionCoords(t){const e=this.di.graphStore.getConnection(t),o=this.di.graphStore.getPort(e.from),s=this.di.graphStore.getPort(e.to),i=o.element.getBoundingClientRect(),c=s.element.getBoundingClientRect(),a=this.host.getBoundingClientRect(),[h,l]=this.di.viewportTransformer.getAbsCoords(i.left-a.left,i.top-a.top),[m,d]=this.di.viewportTransformer.getAbsCoords(c.left-a.left,c.top-a.top),g=this.di.viewportTransformer.getAbsScale(),[u,C]=o.centerFn(i.width*g,i.height*g),[b,S]=s.centerFn(c.width*g,c.height*g),T=u+h,N=C+l,E=b+m,f=S+d,y=Math.min(T,E),A=Math.min(N,f),$=Math.abs(E-T),I=Math.abs(f-N),tt=this.connectionIdToElementMap.get(t),et=T<=E,ot=N<=f;tt.style.transform=`matrix(${et?1:-1}, 0, 0, ${ot?1:-1}, ${y}, ${A})`,e.controller.update(y,A,$,I,o,s)}}class P{constructor(){r(this,"state",{scale:1,x:0,y:0})}applyShift(t,e){this.state={scale:this.state.scale,x:this.state.scale*t+this.state.x,y:this.state.scale*e+this.state.y}}applyScale(t,e,o){this.state={scale:this.state.scale*t,x:this.state.scale*(1-t)*e+this.state.x,y:this.state.scale*(1-t)*o+this.state.y}}getViewCoords(t,e){return[(t-this.state.x)/this.state.scale,(e-this.state.y)/this.state.scale]}getViewScale(){return 1/this.state.scale}getAbsCoords(t,e){return[t*this.state.scale+this.state.x,e*this.state.scale+this.state.y]}getAbsScale(){return this.state.scale}patchState(t,e,o){this.state={scale:t??this.state.scale,x:e??this.state.x,y:o??this.state.y}}}class z{constructor(t){this.transformer=t}getViewCoords(t,e){return this.transformer.getViewCoords(t,e)}getViewScale(){return this.transformer.getViewScale()}getAbsCoords(t,e){return this.transformer.getAbsCoords(t,e)}getAbsScale(){return this.transformer.getAbsScale()}}class v{static getPortCenter(t){const{top:e,left:o,width:s,height:i}=t.element.getBoundingClientRect(),c=t.centerFn(s,i);return[o+c[0],e+c[1]]}static rotate(t,e,o){return[e[0]*t[0]-e[1]*t[1]+((1-e[0])*o[0]+e[1]*o[1]),e[1]*t[0]+e[0]*t[1]+((1-e[0])*o[1]-e[1]*o[0])]}static getDirectionVector(t,e,o){return[e*Math.cos(t??0),o*Math.sin(t??0)]}static getArrowPath(t,e,o,s,i){const a=[[0,0],[s,i],[s,-i]].map(d=>this.rotate(d,t,[0,0])).map(d=>[d[0]+e,d[1]+o]),h=`M ${a[0][0]} ${a[0][1]}`,l=`L ${a[1][0]} ${a[1][1]}`,m=`L ${a[2][0]} ${a[2][1]}`;return`${h} ${l} ${m}`}static getArrowOffsetPath(t,e,o,s,i){const a=[[s,0],[s+i,0]].map(h=>this.rotate(h,t,[0,0])).map(h=>[h[0]+e,h[1]+o]);return`M ${a[0][0]} ${a[0][1]} L ${a[1][0]} ${a[1][1]}`}}class x{constructor(t,e,o,s,i,c,a){r(this,"svg");r(this,"group");r(this,"line");r(this,"sourceArrow",null);r(this,"targetArrow",null);this.color=t,this.width=e,this.curvature=o,this.arrowLength=s,this.arrowWidth=i,this.hasSourceArrow=c,this.hasTargetArrow=a,this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.pointerEvents="none",this.group=document.createElementNS("http://www.w3.org/2000/svg","g"),this.svg.appendChild(this.group),this.line=document.createElementNS("http://www.w3.org/2000/svg","path"),this.line.setAttribute("stroke",this.color),this.line.setAttribute("stroke-width",`${this.width}`),this.line.setAttribute("fill","none"),this.group.appendChild(this.line),this.group.style.transformOrigin="50% 50%",this.hasSourceArrow&&(this.sourceArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.sourceArrow.setAttribute("fill",this.color),this.group.appendChild(this.sourceArrow)),this.hasTargetArrow&&(this.targetArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.targetArrow.setAttribute("fill",this.color),this.group.appendChild(this.targetArrow)),this.svg.style.overflow="visible"}update(t,e,o,s,i,c){this.svg.style.width=`${o}px`,this.svg.style.height=`${s}px`;const a=v.getPortCenter(i),h=v.getPortCenter(c),l=a[0]<=h[0]?1:-1,m=a[1]<=h[1]?1:-1;this.svg.style.transform=`translate(${t}px, ${e}px)`,this.group.style.transform=`scale(${l}, ${m})`;const d=v.getDirectionVector(i.direction,l,m),g=v.getDirectionVector(c.direction,l,m),u=v.rotate([this.arrowLength,0],d,[0,0]),C=v.rotate([o-this.arrowLength,s],g,[o,s]),b=[u[0]+d[0]*this.curvature,u[1]+d[1]*this.curvature],S=[C[0]-g[0]*this.curvature,C[1]-g[1]*this.curvature],T=`M ${u[0]} ${u[1]}`,N=`C ${b[0]} ${b[1]}, ${S[0]} ${S[1]}, ${C[0]} ${C[1]}`,E=`M 0 0 L ${u[0]} ${u[1]} `,f=` M ${C[0]} ${C[1]} L ${o} ${s}`,y=`${this.sourceArrow?"":E}${T} ${N}${this.targetArrow?"":f}`;if(this.line.setAttribute("d",y),this.sourceArrow){const A=v.getArrowPath(d,0,0,this.arrowLength,this.arrowWidth);this.sourceArrow.setAttribute("d",A)}if(this.targetArrow){const A=v.getArrowPath(g,o,s,-this.arrowLength,this.arrowWidth);this.targetArrow.setAttribute("d",A)}}}const M=n=>()=>new x(n.color??"#5c5c5c",n.width??1,n.curvature??90,n.arrowLength??15,n.arrowWidth??4,n.hasSourceArrow??!1,n.hasTargetArrow??!1);class L{constructor(t,e,o,s,i,c,a){r(this,"svg");r(this,"group");r(this,"line");r(this,"sourceArrow",null);r(this,"targetArrow",null);this.color=t,this.width=e,this.arrowLength=o,this.arrowWidth=s,this.minPortOffset=i,this.hasSourceArrow=c,this.hasTargetArrow=a,this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.pointerEvents="none",this.group=document.createElementNS("http://www.w3.org/2000/svg","g"),this.svg.appendChild(this.group),this.line=document.createElementNS("http://www.w3.org/2000/svg","path"),this.line.setAttribute("stroke",this.color),this.line.setAttribute("stroke-width",`${this.width}`),this.line.setAttribute("fill","none"),this.group.appendChild(this.line),this.group.style.transformOrigin="50% 50%",this.hasSourceArrow&&(this.sourceArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.sourceArrow.setAttribute("fill",this.color),this.group.appendChild(this.sourceArrow)),this.hasTargetArrow&&(this.targetArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.targetArrow.setAttribute("fill",this.color),this.group.appendChild(this.targetArrow)),this.svg.style.overflow="visible"}update(t,e,o,s,i,c){this.svg.style.width=`${o}px`,this.svg.style.height=`${s}px`;const a=v.getPortCenter(i),h=v.getPortCenter(c),l=a[0]<=h[0]?1:-1,m=a[1]<=h[1]?1:-1;this.svg.style.transform=`translate(${t}px, ${e}px)`,this.group.style.transform=`scale(${l}, ${m})`;const d=v.getDirectionVector(i.direction,l,m),g=v.getDirectionVector(c.direction,l,m),u=v.rotate([this.arrowLength+this.minPortOffset,0],d,[0,0]),C=v.rotate([o-this.arrowLength-this.minPortOffset,s],g,[o,s]),[b,S]=[o/2,s/2],T=l*(C[0]-u[0])>0?`M ${u[0]} ${u[1]} L ${b} ${u[1]} L ${b} ${C[1]} L ${C[0]} ${C[1]}`:`M ${u[0]} ${u[1]} L ${u[0]} ${S} L ${C[0]} ${S} L ${C[0]} ${C[1]}`,N=`M 0 0 L ${u[0]} ${u[1]} `,E=` M ${C[0]} ${C[1]} L ${o} ${s}`,f=v.getArrowOffsetPath(d,0,0,this.arrowLength,this.minPortOffset),y=v.getArrowOffsetPath(g,o,s,-this.arrowLength,-this.minPortOffset),A=`${this.sourceArrow?f:N}${T}${this.targetArrow?y:E}`;if(this.line.setAttribute("d",A),this.sourceArrow){const $=v.getArrowPath(d,0,0,this.arrowLength,this.arrowWidth);this.sourceArrow.setAttribute("d",$)}if(this.targetArrow){const $=v.getArrowPath(g,o,s,-this.arrowLength,this.arrowWidth);this.targetArrow.setAttribute("d",$)}}}const V=n=>()=>new L(n.color,n.width,n.arrowLength,n.arrowWidth,n.minPortOffset,n.hasSourceArrow,n.hasTargetArrow);var j=(n=>(n.Regular="regular",n.Cycle="cycle",n))(j||{});class G{constructor(t){this.di=t}moveNodeOnTop(t){if(!this.di.graphStore.hasNode(t))throw new Error("failed to move on top nonexisting node");this.di.htmlController.moveNodeOnTop(t)}dragNode(t,e,o){if(!this.di.graphStore.hasNode(t))throw new Error("failed to drag nonexisting node");const s=this.di.graphStore.getNode(t),[i,c]=this.di.viewportTransformer.getViewCoords(s.x,s.y),a=i+e,h=c+o,[l,m]=this.di.viewportTransformer.getAbsCoords(a,h);this.di.graphStore.updateNodeCoords(t,l,m),this.di.htmlController.updateNodePosition(t)}addNode(t,e,o,s,i,c){if(t===void 0)do t=this.di.nodeIdGenerator.next();while(this.di.graphStore.hasNode(t));if(this.di.graphStore.hasNode(t))throw new Error("failed to add node with existing id");this.di.graphStore.addNode(t,e,o,s,c??this.di.options.nodes.centerFn),this.di.htmlController.attachNode(t),i!==void 0&&Object.entries(i).forEach(([a,h])=>{h instanceof HTMLElement?this.di.controller.markPort(a,h,t,this.di.options.ports.centerFn,null):this.di.controller.markPort(a,h.element,t,h.centerFn??this.di.options.ports.centerFn,h.direction??null)})}markPort(t,e,o,s,i){if(t===void 0)do t=this.di.portIdGenerator.next();while(this.di.graphStore.hasPort(t));if(!this.di.graphStore.hasNode(o))throw new Error("failed to set port on nonexisting node");if(this.di.graphStore.hasPort(t))throw new Error("failed to add port with existing id");this.di.graphStore.addPort(t,e,o,s??this.di.options.ports.centerFn,i??null)}updatePortConnections(t){if(!this.di.graphStore.hasPort(t))throw new Error("failed to unset nonexisting port");this.di.htmlController.updatePortConnections(t)}unmarkPort(t){if(!this.di.graphStore.hasPort(t))throw new Error("failed to unset nonexisting port");this.di.graphStore.getPortAdjacentConnections(t).forEach(e=>{this.removeConnection(e)}),this.di.graphStore.removePort(t)}addConnection(t,e,o,s){if(t===void 0)do t=this.di.connectionIdGenerator.next();while(this.di.graphStore.hasConnection(t));if(!this.di.graphStore.hasPort(e))throw new Error("failed to add connection from nonexisting port");if(!this.di.graphStore.hasPort(o))throw new Error("failed to add connection to nonexisting port");this.di.graphStore.addConnection(t,e,o,s(j.Regular)),this.di.htmlController.attachConnection(t)}removeConnection(t){if(!this.di.graphStore.hasConnection(t))throw new Error("failed to remove nonexisting connection");this.di.htmlController.detachConnection(t),this.di.graphStore.removeConnection(t)}removeNode(t){if(!this.di.graphStore.hasNode(t))throw new Error("failed to remove nonexisting node");this.di.htmlController.detachNode(t),this.di.graphStore.removeNode(t)}patchViewportTransform(t,e,o){this.di.viewportTransformer.patchState(t,e,o),this.di.htmlController.applyTransform()}moveContent(t,e){this.di.viewportTransformer.applyShift(-t,-e),this.di.htmlController.applyTransform()}scaleContent(t,e,o){this.di.viewportTransformer.applyScale(1/t,e,o),this.di.htmlController.applyTransform()}moveToNodes(t){if(t.length===0)return;const e=t.map(g=>this.di.graphStore.getNode(g)).filter(g=>g!==void 0);if(e.length<t.length)throw new Error("failed to move to nonexisting node");const[o,s]=e.reduce((g,u)=>[g[0]+u.x,g[1]+u.y],[0,0]),i=o/e.length,c=s/e.length,[a,h]=this.di.htmlController.getViewportDimensions(),l=this.di.viewportTransformer.getAbsScale(),m=i-l*a/2,d=c-l*h/2;this.patchViewportTransform(null,m,d)}updateNodeCoords(t,e,o){if(!this.di.graphStore.hasNode(t))throw new Error("failed to update coordinates of nonexisting node");this.di.graphStore.updateNodeCoords(t,e,o),this.di.htmlController.updateNodePosition(t)}updateConnectionOptions(t,e){if(!this.di.graphStore.hasConnection(t))throw new Error("failed to update nonexisting connection");this.di.htmlController.detachConnection(t),this.di.graphStore.updateConnectionController(t,e),this.di.htmlController.attachConnection(t)}clear(){this.di.htmlController.clear(),this.di.graphStore.clear(),this.di.nodeIdGenerator.reset(),this.di.portIdGenerator.reset(),this.di.connectionIdGenerator.reset()}destroy(){this.di.htmlController.destroy()}}class B{constructor(){r(this,"nodes",Object.create(null));r(this,"ports",Object.create(null));r(this,"nodePorts",Object.create(null));r(this,"portNodeId",Object.create(null));r(this,"connections",Object.create(null));r(this,"incommingConnections",Object.create(null));r(this,"outcommingConnections",Object.create(null));r(this,"cycleConnections",Object.create(null))}getAllNodes(){return Object.keys(this.nodes)}getAllPorts(){return Object.keys(this.ports)}getAllConnections(){return Object.keys(this.connections)}addNode(t,e,o,s,i){this.nodes[t]={element:e,x:o,y:s,centerFn:i},this.nodePorts[t]=Object.create(null)}hasNode(t){return this.nodes[t]!==void 0}getNode(t){return this.nodes[t]}updateNodeCoords(t,e,o){this.nodes[t].x=e,this.nodes[t].y=o}updateConnectionController(t,e){this.connections[t].controller=e}removeNode(t){this.getNodeAdjacentConnections(t).forEach(s=>{this.removeConnection(s)}),delete this.nodes[t];const o=this.nodePorts[t];Object.keys(o).forEach(s=>{delete this.portNodeId[s]}),delete this.nodePorts[t]}addPort(t,e,o,s,i){this.ports[t]={element:e,centerFn:s,direction:i},this.cycleConnections[t]={},this.incommingConnections[t]={},this.outcommingConnections[t]={},this.portNodeId[t]=o;const c=this.nodePorts[o];c!==void 0&&(c[t]=e)}getPort(t){return this.ports[t]}getPortNode(t){return this.portNodeId[t]}hasPort(t){return this.portNodeId[t]!==void 0}removePort(t){Object.keys(this.cycleConnections[t]).forEach(s=>{this.removeConnection(s)}),delete this.cycleConnections[t],Object.keys(this.incommingConnections[t]).forEach(s=>{this.removeConnection(s)}),delete this.incommingConnections[t],Object.keys(this.outcommingConnections[t]).forEach(s=>{this.removeConnection(s)}),delete this.outcommingConnections[t];const e=this.portNodeId[t];delete this.portNodeId[t];const o=this.nodePorts[e];delete o[t],delete this.ports[t]}addConnection(t,e,o,s){this.connections[t]={from:e,to:o,controller:s},e!==o?(this.outcommingConnections[e][t]=!0,this.incommingConnections[o][t]=!0):this.cycleConnections[e][t]=!0}getConnection(t){return this.connections[t]}hasConnection(t){return this.connections[t]!==void 0}removeConnection(t){const e=this.connections[t],o=e.from,s=e.to;delete this.cycleConnections[o][t],delete this.cycleConnections[s][t],delete this.incommingConnections[o][t],delete this.incommingConnections[s][t],delete this.outcommingConnections[o][t],delete this.outcommingConnections[s][t],delete this.connections[t]}getPortIncomingConnections(t){return Object.keys(this.incommingConnections[t]??{})}getPortOutcomingConnections(t){return Object.keys(this.outcommingConnections[t]??{})}getPortCycleConnections(t){return Object.keys(this.cycleConnections[t]??{})}getPortAdjacentConnections(t){return[...this.getPortIncomingConnections(t),...this.getPortOutcomingConnections(t),...this.getPortCycleConnections(t)]}getNodeIncomingConnections(t){const e=Object.keys(this.nodePorts[t]);let o=[];return e.forEach(s=>{o=[...o,...this.getPortIncomingConnections(s)]}),o}getNodeOutcomingConnections(t){const e=Object.keys(this.nodePorts[t]);let o=[];return e.forEach(s=>{o=[...o,...this.getPortOutcomingConnections(s)]}),o}getNodeCycleConnections(t){const e=Object.keys(this.nodePorts[t]);let o=[];return e.forEach(s=>{o=[...o,...this.getPortCycleConnections(s)]}),o}getNodeAdjacentConnections(t){return[...this.getNodeIncomingConnections(t),...this.getNodeOutcomingConnections(t),...this.getNodeCycleConnections(t)]}clear(){this.nodes=Object.create(null),this.ports=Object.create(null),this.nodePorts=Object.create(null),this.portNodeId=Object.create(null),this.connections=Object.create(null),this.incommingConnections=Object.create(null),this.outcommingConnections=Object.create(null),this.cycleConnections=Object.create(null)}}class Y{constructor(t){this.graphStore=t}getNode(t){const e=this.graphStore.getNode(t);return e===void 0?null:{x:e.x,y:e.y}}getPort(t){const e=this.graphStore.getPortNode(t);return e===void 0?null:{nodeId:e}}getConnection(t){const e=this.graphStore.getConnection(t);return e===void 0?null:{from:e.from,to:e.to}}getAllNodes(){return this.graphStore.getAllNodes()}getAllPorts(){return this.graphStore.getAllPorts()}getAllConnections(){return this.graphStore.getAllConnections()}hasNode(t){return this.graphStore.hasNode(t)}hasPort(t){return this.graphStore.hasPort(t)}hasConnection(t){return this.graphStore.hasConnection(t)}getPortIncomingConnections(t){return this.graphStore.getPortIncomingConnections(t)}getPortOutcomingConnections(t){return this.graphStore.getPortOutcomingConnections(t)}getPortCycleConnections(t){return this.graphStore.getPortCycleConnections(t)}getPortAdjacentConnections(t){return this.graphStore.getPortAdjacentConnections(t)}getNodeIncomingConnections(t){return this.graphStore.getNodeIncomingConnections(t)}getNodeOutcomingConnections(t){return this.graphStore.getNodeOutcomingConnections(t)}getNodeCycleConnections(t){return this.graphStore.getNodeCycleConnections(t)}getNodeAdjacentConnections(t){return this.graphStore.getNodeAdjacentConnections(t)}}class O{constructor(){r(this,"counter",0)}next(){const t=`${this.counter}`;return this.counter++,t}reset(){this.counter=0}}class X{constructor(t){r(this,"htmlController");r(this,"viewportTransformer");r(this,"publicViewportTransformer");r(this,"controller");r(this,"graphStore");r(this,"publicGraphStore");r(this,"nodeIdGenerator");r(this,"portIdGenerator");r(this,"connectionIdGenerator");this.options=t,this.htmlController=new w(this),this.viewportTransformer=new P,this.publicViewportTransformer=new z(this.viewportTransformer),this.controller=new G(this),this.graphStore=new B,this.publicGraphStore=new Y(this.graphStore),this.nodeIdGenerator=new O,this.portIdGenerator=new O,this.connectionIdGenerator=new O}}const k=(n,t)=>[n/2,t/2],Z=()=>()=>{},H=(n,t,e,o,s,i)=>{n.fillStyle=i,n.fillRect(0,0,n.canvas.width,n.canvas.height);const c=t.getViewCoords(0,0),a=t.getViewScale(),h=o*a;let l=0,m=0,d=h/2;do d*=2,l=n.canvas.width/d,m=n.canvas.height/d;while(l*m>1e4);const g=c[0]-Math.floor(c[0]/d)*d,u=c[1]-Math.floor(c[1]/d)*d,C=s*a,b=2*Math.PI,S=g-d,T=u-d,N=n.canvas.width+g,E=n.canvas.height+u;n.fillStyle=e;for(let f=S;f<=N;f+=d)for(let y=T;y<=E;y+=d)n.beginPath(),n.arc(f,y,C,0,b),n.closePath(),n.fill()},U=(n,t,e,o)=>(s,i)=>{H(s,i,n,t,e,o)},q=(n,t)=>{n.fillStyle=t,n.fillRect(0,0,n.canvas.width,n.canvas.height)},J=n=>t=>{q(t,n)},K=n=>{switch(n==null?void 0:n.type){case"custom":return n.drawingFn;case"dots":return U(n.dotColor??"#d8d8d8",n.dotGap??25,n.dotRadius??1.5,n.color??"#ffffff");case"color":return J(n.color??"#ffffff");default:return Z()}},F=n=>{switch(n==null?void 0:n.type){case"custom":return n.controllerFactory;case"straight":return V({color:n.color??"#5c5c5c",width:n.width??1,arrowLength:n.arrowLength??15,arrowWidth:n.arrowWidth??4,minPortOffset:n.minPortOffset??15,hasSourceArrow:n.hasSourceArrow??!1,hasTargetArrow:n.hasTargetArrow??!1});default:return M({color:n.color??"#5c5c5c",width:n.width??1,curvature:n.curvature??90,arrowLength:n.arrowLength??15,arrowWidth:n.arrowWidth??4,hasSourceArrow:n.hasSourceArrow??!1,hasTargetArrow:n.hasTargetArrow??!1})}},Q=n=>{var t,e,o;return{background:{drawingFn:K(n.background??{type:"none"})},nodes:{centerFn:((t=n.nodes)==null?void 0:t.centerFn)??k},ports:{centerFn:((e=n.ports)==null?void 0:e.centerFn)??k},connections:{controllerFactory:F(n.connections??{})},layers:{mode:((o=n.layers)==null?void 0:o.mode)??"connections-follow-node"}}};class W{constructor(t){r(this,"transformation");r(this,"model");r(this,"options");r(this,"di");this.apiOptions=t,this.options=Q(this.apiOptions??{}),this.di=new X(this.options),this.transformation=this.di.publicViewportTransformer,this.model=this.di.publicGraphStore}addNode(t){return this.di.controller.addNode(t.id,t.element,t.x,t.y,t.ports,t.centerFn),this}moveNodeOnTop(t){return this.di.controller.moveNodeOnTop(t),this}removeNode(t){return this.di.controller.removeNode(t),this}markPort(t){return this.di.controller.markPort(t.id,t.element,t.nodeId,t.centerFn,t.direction),this}updatePortConnections(t){return this.di.controller.updatePortConnections(t),this}unmarkPort(t){return this.di.controller.unmarkPort(t),this}addConnection(t){const e=t.options!==void 0?F(t.options):this.di.options.connections.controllerFactory;return this.di.controller.addConnection(t.id,t.from,t.to,e),this}removeConnection(t){return this.di.controller.removeConnection(t),this}patchViewportTransform(t){return this.di.controller.patchViewportTransform(t.scale??null,t.x??null,t.y??null),this}moveContent(t){return this.di.controller.moveContent(t.x??0,t.y??0),this}scaleContent(t){return this.di.controller.scaleContent(t.scale,t.x??0,t.y??0),this}moveToNodes(t){return this.di.controller.moveToNodes(t),this}updateNodeCoords(t,e,o){return this.di.controller.updateNodeCoords(t,e,o),this}updateConnectionController(t,e){return this.di.controller.updateConnectionOptions(t,e),this}dragNode(t,e,o){return this.di.controller.dragNode(t,e,o),this}clear(){return this.di.controller.clear(),this}attach(t){return this.di.htmlController.attach(t),this}detach(){return this.di.htmlController.detach(),this}destroy(){this.di.controller.destroy()}}class D{constructor(t){r(this,"transformation");r(this,"model");r(this,"nodes",new Map);r(this,"grabbedNodeId",null);r(this,"nodeIdGenerator",new O);r(this,"element",null);r(this,"onCanvasMouseUp",()=>{this.setCursor(null),this.grabbedNodeId=null});r(this,"onCanvasMouseMove",t=>{this.grabbedNodeId!==null&&(t.stopPropagation(),this.canvas.dragNode(this.grabbedNodeId,t.movementX,t.movementY))});r(this,"onCanvasTouchStart",t=>{this.previousTouchCoords=[t.touches[0].clientX,t.touches[0].clientY]});r(this,"onCanvasTouchMove",t=>{if(this.grabbedNodeId===null||t.touches.length!==1||this.previousTouchCoords===null)return;t.stopImmediatePropagation();const[e,o]=[t.touches[0].clientX-this.previousTouchCoords[0],t.touches[0].clientY-this.previousTouchCoords[1]];this.canvas.dragNode(this.grabbedNodeId,e,o),this.previousTouchCoords=[t.touches[0].clientX,t.touches[0].clientY]});r(this,"onCanvasTouchEnd",()=>{this.previousTouchCoords=null,this.grabbedNodeId=null});r(this,"previousTouchCoords",null);this.canvas=t,this.transformation=this.canvas.transformation,this.model=this.canvas.model}addNode(t){let e=t.id;if(e===void 0)do e=this.nodeIdGenerator.next();while(this.nodes.has(e));this.canvas.addNode(t);const o=i=>{i.stopImmediatePropagation(),this.grabbedNodeId=e,this.setCursor("grab"),this.canvas.moveNodeOnTop(e)},s=i=>{i.touches.length===1&&(this.grabbedNodeId=e,this.canvas.moveNodeOnTop(e))};return this.nodes.set(e,{el:t.element,onMouseDown:o,onTouchStart:s}),t.element.addEventListener("mousedown",o),t.element.addEventListener("touchstart",s),this}removeNode(t){const e=this.nodes.get(t);return e!==void 0&&(e.el.removeEventListener("mousedown",e.onMouseDown),e.el.removeEventListener("touchstart",e.onTouchStart)),this.canvas.removeNode(t),this.nodes.delete(t),this}markPort(t){return this.canvas.markPort(t),this}updatePortConnections(t){return this.canvas.updatePortConnections(t),this}unmarkPort(t){return this.canvas.unmarkPort(t),this}addConnection(t){return this.canvas.addConnection(t),this}removeConnection(t){return this.canvas.removeConnection(t),this}patchViewportTransform(t){return this.canvas.patchViewportTransform(t),this}moveContent(t){return this.canvas.moveContent(t),this}scaleContent(t){return this.canvas.scaleContent(t),this}moveToNodes(t){return this.canvas.moveToNodes(t),this}updateNodeCoords(t,e,o){return this.canvas.updateNodeCoords(t,e,o),this}updateConnectionController(t,e){return this.canvas.updateConnectionController(t,e),this}dragNode(t,e,o){return this.canvas.dragNode(t,e,o),this}moveNodeOnTop(t){return this.canvas.moveNodeOnTop(t),this}clear(){return this.canvas.clear(),this.nodes.forEach(t=>{t.el.removeEventListener("mousedown",t.onMouseDown),t.el.removeEventListener("touchstart",t.onTouchStart)}),this.nodes.clear(),this}attach(t){return this.canvas.attach(t),this.element=t,t.addEventListener("mouseup",this.onCanvasMouseUp),t.addEventListener("mousemove",this.onCanvasMouseMove),t.addEventListener("touchstart",this.onCanvasTouchStart),t.addEventListener("touchmove",this.onCanvasTouchMove),t.addEventListener("touchend",this.onCanvasTouchEnd),t.addEventListener("touchcancel",this.onCanvasTouchEnd),this}detach(){return this.canvas.detach(),this.element!==null&&(this.element.removeEventListener("mouseup",this.onCanvasMouseUp),this.element.removeEventListener("mousemove",this.onCanvasMouseMove),this.element.removeEventListener("touchstart",this.onCanvasTouchStart),this.element.removeEventListener("touchmove",this.onCanvasTouchMove),this.element.removeEventListener("touchend",this.onCanvasTouchEnd),this.element.removeEventListener("touchcancel",this.onCanvasTouchEnd),this.element=null),this}destroy(){this.detach(),this.nodes.forEach(t=>{t.el.removeEventListener("mousedown",t.onMouseDown),t.el.removeEventListener("touchstart",t.onTouchStart)}),this.canvas.destroy()}setCursor(t){this.element!==null&&(t!==null?this.element.style.cursor=t:this.element.style.removeProperty("cursor"))}}class R{constructor(t,e){r(this,"transformation");r(this,"model");r(this,"element",null);r(this,"isMoving",!1);r(this,"prevTouches",null);r(this,"isScalable");r(this,"isShiftable");r(this,"minContentScale");r(this,"maxContentScale");r(this,"wheelSensitivity");r(this,"onMouseDown",()=>{this.setCursor("grab"),this.isMoving=!0});r(this,"onMouseMove",t=>{!this.isMoving||!this.isShiftable||this.canvas.moveContent({x:t.movementX,y:t.movementY})});r(this,"onMouseUp",()=>{this.setCursor(null),this.isMoving=!1});r(this,"onWheelScroll",t=>{if(this.element===null||this.isScalable===!1)return;t.preventDefault();const{left:e,top:o}=this.element.getBoundingClientRect(),s=t.clientX-e,i=t.clientY-o,c=t.deltaY<0?this.wheelSensitivity:1/this.wheelSensitivity,a=this.canvas.transformation.getViewScale()*c;this.checkNextScaleValid(a)&&this.canvas.scaleContent({scale:c,x:s,y:i})});r(this,"onTouchStart",t=>{this.prevTouches=this.getAverageTouch(t)});r(this,"onTouchMove",t=>{if(this.prevTouches===null||this.element===null||!this.isShiftable)return;const e=this.getAverageTouch(t);if((e.touchesCnt===1||e.touchesCnt===2)&&this.canvas.moveContent({x:e.x-this.prevTouches.x,y:e.y-this.prevTouches.y}),e.touchesCnt===2&&this.isScalable){const{left:o,top:s}=this.element.getBoundingClientRect(),i=this.prevTouches.x-o,c=this.prevTouches.y-s,a=e.scale/this.prevTouches.scale,h=this.canvas.transformation.getViewScale()*a;this.checkNextScaleValid(h)&&this.canvas.scaleContent({scale:a,x:i,y:c})}this.prevTouches=e,t.preventDefault()});r(this,"onTouchEnd",()=>{this.prevTouches=null});var s,i,c,a,h,l,m,d,g,u;this.canvas=t,this.options=e,this.transformation=this.canvas.transformation,this.model=this.canvas.model,this.isScalable=((i=(s=this.options)==null?void 0:s.scale)==null?void 0:i.enabled)!==!1,this.minContentScale=((a=(c=this.options)==null?void 0:c.scale)==null?void 0:a.minContent)??null,this.maxContentScale=((l=(h=this.options)==null?void 0:h.scale)==null?void 0:l.maxContent)??null,this.isShiftable=((d=(m=this.options)==null?void 0:m.shift)==null?void 0:d.enabled)!==!1;const o=(u=(g=this.options)==null?void 0:g.scale)==null?void 0:u.wheelSensitivity;this.wheelSensitivity=o!==void 0?o:1.2}addNode(t){return this.canvas.addNode(t),this}removeNode(t){return this.canvas.removeNode(t),this}markPort(t){return this.canvas.markPort(t),this}updatePortConnections(t){return this.canvas.updatePortConnections(t),this}unmarkPort(t){return this.canvas.unmarkPort(t),this}addConnection(t){return this.canvas.addConnection(t),this}removeConnection(t){return this.canvas.removeConnection(t),this}patchViewportTransform(t){return this.canvas.patchViewportTransform(t),this}moveContent(t){return this.canvas.moveContent(t),this}scaleContent(t){return this.canvas.scaleContent(t),this}moveToNodes(t){return this.canvas.moveToNodes(t),this}updateNodeCoords(t,e,o){return this.canvas.updateNodeCoords(t,e,o),this}updateConnectionController(t,e){return this.canvas.updateConnectionController(t,e),this}dragNode(t,e,o){return this.canvas.dragNode(t,e,o),this}moveNodeOnTop(t){return this.canvas.moveNodeOnTop(t),this}clear(){return this.canvas.clear(),this}attach(t){return this.canvas.attach(t),this.element=t,t.addEventListener("mousedown",this.onMouseDown),t.addEventListener("mousemove",this.onMouseMove),t.addEventListener("mouseup",this.onMouseUp),t.addEventListener("wheel",this.onWheelScroll),t.addEventListener("touchstart",this.onTouchStart),t.addEventListener("touchmove",this.onTouchMove),t.addEventListener("touchend",this.onTouchEnd),t.addEventListener("touchcancel",this.onTouchEnd),this}detach(){return this.canvas.detach(),this.element!==null&&(this.element.removeEventListener("mousedown",this.onMouseDown),this.element.removeEventListener("mousemove",this.onMouseMove),this.element.removeEventListener("mouseup",this.onMouseUp),this.element.removeEventListener("wheel",this.onWheelScroll),this.element.removeEventListener("touchstart",this.onTouchStart),this.element.removeEventListener("touchmove",this.onTouchMove),this.element.removeEventListener("touchend",this.onTouchEnd),this.element.removeEventListener("touchcancel",this.onTouchEnd)),this.element=null,this}destroy(){this.detach(),this.canvas.destroy()}getAverageTouch(t){const e=[],o=t.touches.length;for(let h=0;h<o;h++)e.push([t.touches[h].clientX,t.touches[h].clientY]);const s=e.reduce((h,l)=>[h[0]+l[0],h[1]+l[1]],[0,0]),i=[s[0]/o,s[1]/o],a=e.map(h=>[h[0]-i[0],h[1]-i[1]]).reduce((h,l)=>h+Math.sqrt(l[0]*l[0]+l[1]*l[1]),0);return{x:i[0],y:i[1],scale:a/o,touchesCnt:o}}checkNextScaleValid(t){const e=this.canvas.transformation.getViewScale();return!(this.maxContentScale!==null&&t>this.maxContentScale&&t>e||this.minContentScale!==null&&t<this.minContentScale&&t<e)}setCursor(t){this.element!==null&&(t!==null?this.element.style.cursor=t:this.element.style.removeProperty("cursor"))}}class _{constructor(){r(this,"coreOptions");r(this,"transformOptions");r(this,"isDraggable",!1);r(this,"isTransformable",!1)}setOptions(t){return this.coreOptions=t,this}setDraggableNodes(){return this.isDraggable=!0,this}setTransformableCanvas(t){return this.isTransformable=!0,this.transformOptions=t,this}build(){let t=new W(this.coreOptions);return this.isDraggable&&(t=new D(t)),this.isTransformable&&(t=new R(t,this.transformOptions)),t}}p.BezierConnectionController=x,p.CanvasBuilder=_,p.CanvasCore=W,p.ConnectionUtils=v,p.DraggableNodesCanvas=D,p.StraightConnectionController=L,p.TransformableCanvas=R,p.createBezierConnectionControllerFactory=M,p.createStraightConnectionControllerFactory=V,Object.defineProperty(p,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@html-graph/html-graph",
3
3
  "author": "Dmitry Marov",
4
4
  "private": false,
5
- "version": "0.0.43",
5
+ "version": "0.0.45",
6
6
  "type": "module",
7
7
  "main": "dist/main.js",
8
8
  "types": "dist/main.d.ts",