ngx-vflow 0.16.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/README.md +8 -1
  2. package/esm2022/lib/vflow/components/background/background.component.mjs +6 -7
  3. package/esm2022/lib/vflow/components/connection/connection.component.mjs +66 -53
  4. package/esm2022/lib/vflow/components/custom-node-base/custom-node-base.component.mjs +32 -25
  5. package/esm2022/lib/vflow/components/default-node/default-node.component.mjs +9 -11
  6. package/esm2022/lib/vflow/components/defs/defs.component.mjs +9 -12
  7. package/esm2022/lib/vflow/components/edge/edge.component.mjs +21 -24
  8. package/esm2022/lib/vflow/components/edge-label/edge-label.component.mjs +26 -31
  9. package/esm2022/lib/vflow/components/node/node.component.mjs +54 -50
  10. package/esm2022/lib/vflow/components/vflow/vflow.component.mjs +93 -91
  11. package/esm2022/lib/vflow/decorators/run-in-injection-context.decorator.mjs +1 -1
  12. package/esm2022/lib/vflow/directives/changes-controller.directive.mjs +41 -125
  13. package/esm2022/lib/vflow/directives/connection-controller.directive.mjs +16 -16
  14. package/esm2022/lib/vflow/directives/drag-handle.directive.mjs +7 -6
  15. package/esm2022/lib/vflow/directives/flow-size-controller.directive.mjs +7 -6
  16. package/esm2022/lib/vflow/directives/handle-size-controller.directive.mjs +15 -12
  17. package/esm2022/lib/vflow/directives/map-context.directive.mjs +8 -5
  18. package/esm2022/lib/vflow/directives/pointer.directive.mjs +18 -19
  19. package/esm2022/lib/vflow/directives/reference.directive.mjs +6 -5
  20. package/esm2022/lib/vflow/directives/root-pointer.directive.mjs +8 -5
  21. package/esm2022/lib/vflow/directives/root-svg-context.directive.mjs +8 -5
  22. package/esm2022/lib/vflow/directives/selectable.directive.mjs +10 -7
  23. package/esm2022/lib/vflow/directives/space-point-context.directive.mjs +8 -5
  24. package/esm2022/lib/vflow/directives/template.directive.mjs +43 -25
  25. package/esm2022/lib/vflow/interfaces/component-node-event.interface.mjs +1 -1
  26. package/esm2022/lib/vflow/interfaces/node.interface.mjs +1 -1
  27. package/esm2022/lib/vflow/interfaces/optimization.interface.mjs +1 -1
  28. package/esm2022/lib/vflow/math/edge-path/bezier-path.mjs +1 -1
  29. package/esm2022/lib/vflow/math/edge-path/smooth-step-path.mjs +1 -1
  30. package/esm2022/lib/vflow/models/connection.model.mjs +1 -1
  31. package/esm2022/lib/vflow/models/edge.model.mjs +1 -1
  32. package/esm2022/lib/vflow/models/handle.model.mjs +2 -2
  33. package/esm2022/lib/vflow/models/node.model.mjs +4 -10
  34. package/esm2022/lib/vflow/models/toolbar.model.mjs +1 -1
  35. package/esm2022/lib/vflow/public-components/custom-dynamic-node/custom-dynamic-node.component.mjs +16 -10
  36. package/esm2022/lib/vflow/public-components/custom-node/custom-node.component.mjs +15 -10
  37. package/esm2022/lib/vflow/public-components/handle/handle.component.mjs +52 -0
  38. package/esm2022/lib/vflow/public-components/minimap/minimap.component.mjs +35 -44
  39. package/esm2022/lib/vflow/public-components/node-toolbar/node-toolbar.component.mjs +24 -27
  40. package/esm2022/lib/vflow/public-components/resizable/resizable.component.mjs +60 -45
  41. package/esm2022/lib/vflow/services/component-event-bus.service.mjs +3 -3
  42. package/esm2022/lib/vflow/services/draggable.service.mjs +4 -4
  43. package/esm2022/lib/vflow/services/edge-changes.service.mjs +3 -3
  44. package/esm2022/lib/vflow/services/flow-entities.service.mjs +4 -4
  45. package/esm2022/lib/vflow/services/flow-settings.service.mjs +4 -10
  46. package/esm2022/lib/vflow/services/flow-status.service.mjs +4 -4
  47. package/esm2022/lib/vflow/services/handle.service.mjs +4 -4
  48. package/esm2022/lib/vflow/services/keyboard.service.mjs +5 -5
  49. package/esm2022/lib/vflow/services/node-accessor.service.mjs +3 -3
  50. package/esm2022/lib/vflow/services/node-changes.service.mjs +3 -3
  51. package/esm2022/lib/vflow/services/node-rendering.service.mjs +3 -3
  52. package/esm2022/lib/vflow/services/overlays.service.mjs +3 -3
  53. package/esm2022/lib/vflow/services/selection.service.mjs +4 -4
  54. package/esm2022/lib/vflow/services/viewport.service.mjs +3 -3
  55. package/esm2022/lib/vflow/utils/adjust-direction.mjs +1 -1
  56. package/esm2022/lib/vflow/utils/get-os.mjs +1 -1
  57. package/esm2022/lib/vflow/utils/nodes.mjs +1 -1
  58. package/esm2022/lib/vflow/vflow.mjs +24 -0
  59. package/esm2022/public-api.mjs +4 -5
  60. package/fesm2022/ngx-vflow.mjs +914 -1022
  61. package/fesm2022/ngx-vflow.mjs.map +1 -1
  62. package/lib/vflow/components/background/background.component.d.ts +3 -3
  63. package/lib/vflow/components/connection/connection.component.d.ts +3 -3
  64. package/lib/vflow/components/custom-node-base/custom-node-base.component.d.ts +4 -9
  65. package/lib/vflow/components/default-node/default-node.component.d.ts +2 -2
  66. package/lib/vflow/components/defs/defs.component.d.ts +2 -2
  67. package/lib/vflow/components/edge/edge.component.d.ts +7 -7
  68. package/lib/vflow/components/edge-label/edge-label.component.d.ts +9 -8
  69. package/lib/vflow/components/node/node.component.d.ts +5 -6
  70. package/lib/vflow/components/vflow/vflow.component.d.ts +19 -29
  71. package/lib/vflow/directives/changes-controller.directive.d.ts +29 -30
  72. package/lib/vflow/directives/connection-controller.directive.d.ts +1 -2
  73. package/lib/vflow/directives/drag-handle.directive.d.ts +1 -1
  74. package/lib/vflow/directives/flow-size-controller.directive.d.ts +1 -1
  75. package/lib/vflow/directives/handle-size-controller.directive.d.ts +2 -2
  76. package/lib/vflow/directives/map-context.directive.d.ts +1 -1
  77. package/lib/vflow/directives/pointer.directive.d.ts +9 -6
  78. package/lib/vflow/directives/reference.directive.d.ts +1 -1
  79. package/lib/vflow/directives/root-pointer.directive.d.ts +1 -1
  80. package/lib/vflow/directives/root-svg-context.directive.d.ts +1 -1
  81. package/lib/vflow/directives/selectable.directive.d.ts +1 -1
  82. package/lib/vflow/directives/space-point-context.directive.d.ts +1 -1
  83. package/lib/vflow/directives/template.directive.d.ts +6 -6
  84. package/lib/vflow/interfaces/component-node-event.interface.d.ts +3 -3
  85. package/lib/vflow/interfaces/node.interface.d.ts +14 -14
  86. package/lib/vflow/interfaces/optimization.interface.d.ts +0 -7
  87. package/lib/vflow/models/edge.model.d.ts +1 -17
  88. package/lib/vflow/models/handle.model.d.ts +4 -4
  89. package/lib/vflow/models/node.model.d.ts +2 -5
  90. package/lib/vflow/public-components/custom-dynamic-node/custom-dynamic-node.component.d.ts +3 -3
  91. package/lib/vflow/public-components/custom-node/custom-node.component.d.ts +3 -3
  92. package/lib/vflow/{components → public-components}/handle/handle.component.d.ts +5 -5
  93. package/lib/vflow/public-components/minimap/minimap.component.d.ts +8 -10
  94. package/lib/vflow/public-components/node-toolbar/node-toolbar.component.d.ts +6 -5
  95. package/lib/vflow/public-components/resizable/resizable.component.d.ts +5 -4
  96. package/lib/vflow/services/flow-settings.service.d.ts +0 -7
  97. package/lib/vflow/utils/reference-keeper.d.ts +1 -1
  98. package/lib/vflow/vflow.d.ts +9 -0
  99. package/package.json +3 -3
  100. package/public-api.d.ts +2 -3
  101. package/esm2022/lib/vflow/components/handle/handle.component.mjs +0 -49
  102. package/esm2022/lib/vflow/interfaces/handle-positions.interface.mjs +0 -2
  103. package/esm2022/lib/vflow/vflow.module.mjs +0 -121
  104. package/lib/vflow/interfaces/handle-positions.interface.d.ts +0 -5
  105. package/lib/vflow/vflow.module.d.ts +0 -30
@@ -1,13 +1,12 @@
1
- import * as i1 from '@angular/common';
2
- import { NgIf, NgFor, NgTemplateOutlet, NgComponentOutlet, KeyValuePipe } from '@angular/common';
3
1
  import * as i0 from '@angular/core';
4
- import { signal, computed, Injectable, inject, ElementRef, Directive, effect, untracked, TemplateRef, EventEmitter, Output, DestroyRef, Input, runInInjectionContext, Component, Injector, ChangeDetectionStrategy, HostListener, ViewChild, NgZone, ContentChild, NgModule } from '@angular/core';
2
+ import { signal, computed, Injectable, inject, ElementRef, Directive, effect, untracked, TemplateRef, output, DestroyRef, EventEmitter, OutputEmitterRef, input, viewChild, Component, ChangeDetectionStrategy, Injector, runInInjectionContext, HostListener, NgZone, contentChild, Input, forwardRef } from '@angular/core';
5
3
  import { select } from 'd3-selection';
6
4
  import { zoomIdentity, zoom } from 'd3-zoom';
7
- import { switchMap, merge, fromEvent, tap, Subject, observeOn, animationFrameScheduler, skip, map, pairwise, filter, distinctUntilChanged, asyncScheduler, zip, share, Observable, startWith, of } from 'rxjs';
8
- import { toObservable, takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
5
+ import { switchMap, merge, fromEvent, tap, Subject, Observable, observeOn, animationFrameScheduler, skip, map, pairwise, filter, distinctUntilChanged, asyncScheduler, zip, share, startWith, of } from 'rxjs';
6
+ import { toObservable, takeUntilDestroyed, toSignal, outputFromObservable } from '@angular/core/rxjs-interop';
9
7
  import { drag } from 'd3-drag';
10
8
  import { __decorate } from 'tslib';
9
+ import { NgTemplateOutlet, NgComponentOutlet, KeyValuePipe } from '@angular/common';
11
10
 
12
11
  function getNodesBounds(nodes) {
13
12
  if (nodes.length === 0) {
@@ -129,10 +128,10 @@ class FlowEntitiesService {
129
128
  getDetachedEdges() {
130
129
  return this.edges().filter(e => e.detached());
131
130
  }
132
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FlowEntitiesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
133
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FlowEntitiesService }); }
131
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowEntitiesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
132
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowEntitiesService }); }
134
133
  }
135
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FlowEntitiesService, decorators: [{
134
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowEntitiesService, decorators: [{
136
135
  type: Injectable
137
136
  }] });
138
137
 
@@ -154,12 +153,6 @@ function clamp(value, min = 0, max = 1) {
154
153
  class FlowSettingsService {
155
154
  constructor() {
156
155
  this.entitiesSelectable = signal(true);
157
- /**
158
- * Global setting with handle positions. Nodes derive this value
159
- *
160
- * @deprecated
161
- */
162
- this.handlePositions = signal({ source: 'right', target: 'left' });
163
156
  /**
164
157
  * @see {VflowComponent.view}
165
158
  */
@@ -176,10 +169,10 @@ class FlowSettingsService {
176
169
  this.maxZoom = signal(3);
177
170
  this.background = signal({ type: 'solid', color: '#fff' });
178
171
  }
179
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FlowSettingsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
180
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FlowSettingsService }); }
172
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowSettingsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
173
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowSettingsService }); }
181
174
  }
182
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FlowSettingsService, decorators: [{
175
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowSettingsService, decorators: [{
183
176
  type: Injectable
184
177
  }] });
185
178
 
@@ -225,10 +218,10 @@ class ViewportService {
225
218
  .map(nodeId => this.entitiesService.nodes().find(({ node }) => node.id === nodeId))
226
219
  .filter((node) => !!node);
227
220
  }
228
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ViewportService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
229
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ViewportService }); }
221
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ViewportService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
222
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ViewportService }); }
230
223
  }
231
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ViewportService, decorators: [{
224
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ViewportService, decorators: [{
232
225
  type: Injectable
233
226
  }] });
234
227
 
@@ -240,13 +233,14 @@ class RootSvgReferenceDirective {
240
233
  constructor() {
241
234
  this.element = inject(ElementRef).nativeElement;
242
235
  }
243
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RootSvgReferenceDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
244
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: RootSvgReferenceDirective, selector: "svg[rootSvgRef]", ngImport: i0 }); }
236
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RootSvgReferenceDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
237
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: RootSvgReferenceDirective, isStandalone: true, selector: "svg[rootSvgRef]", ngImport: i0 }); }
245
238
  }
246
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RootSvgReferenceDirective, decorators: [{
239
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RootSvgReferenceDirective, decorators: [{
247
240
  type: Directive,
248
241
  args: [{
249
- selector: 'svg[rootSvgRef]'
242
+ standalone: true,
243
+ selector: 'svg[rootSvgRef]',
250
244
  }]
251
245
  }] });
252
246
 
@@ -307,12 +301,12 @@ class KeyboardService {
307
301
  isActiveAction(action) {
308
302
  return this.actionsActive[action];
309
303
  }
310
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: KeyboardService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
311
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: KeyboardService }); }
304
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: KeyboardService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
305
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: KeyboardService }); }
312
306
  }
313
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: KeyboardService, decorators: [{
307
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: KeyboardService, decorators: [{
314
308
  type: Injectable
315
- }], ctorParameters: function () { return []; } });
309
+ }], ctorParameters: () => [] });
316
310
 
317
311
  class SelectionService {
318
312
  constructor() {
@@ -353,10 +347,10 @@ class SelectionService {
353
347
  entity.selected.set(true);
354
348
  }
355
349
  }
356
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SelectionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
357
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SelectionService }); }
350
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SelectionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
351
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SelectionService }); }
358
352
  }
359
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SelectionService, decorators: [{
353
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SelectionService, decorators: [{
360
354
  type: Injectable
361
355
  }] });
362
356
 
@@ -437,12 +431,15 @@ class MapContextDirective {
437
431
  .call(this.zoomBehavior)
438
432
  .on('dblclick.zoom', null);
439
433
  }
440
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MapContextDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
441
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: MapContextDirective, selector: "g[mapContext]", ngImport: i0 }); }
434
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MapContextDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
435
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: MapContextDirective, isStandalone: true, selector: "g[mapContext]", ngImport: i0 }); }
442
436
  }
443
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MapContextDirective, decorators: [{
437
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MapContextDirective, decorators: [{
444
438
  type: Directive,
445
- args: [{ selector: 'g[mapContext]' }]
439
+ args: [{
440
+ standalone: true,
441
+ selector: 'g[mapContext]',
442
+ }]
446
443
  }] });
447
444
  const mapTransformToViewportState = (transform) => ({ zoom: transform.k, x: transform.x, y: transform.y });
448
445
  const evTarget = (anyEvent) => {
@@ -530,10 +527,10 @@ class DraggableService {
530
527
  // we only can move current node if it's not selected
531
528
  : [model];
532
529
  }
533
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DraggableService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
534
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DraggableService }); }
530
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DraggableService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
531
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DraggableService }); }
535
532
  }
536
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DraggableService, decorators: [{
533
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DraggableService, decorators: [{
537
534
  type: Injectable
538
535
  }] });
539
536
  function moveNode(model, point) {
@@ -552,67 +549,85 @@ class EdgeTemplateDirective {
552
549
  constructor() {
553
550
  this.templateRef = inject(TemplateRef);
554
551
  }
555
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EdgeTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
556
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: EdgeTemplateDirective, selector: "ng-template[edge]", ngImport: i0 }); }
552
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
553
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: EdgeTemplateDirective, isStandalone: true, selector: "ng-template[edge]", ngImport: i0 }); }
557
554
  }
558
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EdgeTemplateDirective, decorators: [{
555
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeTemplateDirective, decorators: [{
559
556
  type: Directive,
560
- args: [{ selector: 'ng-template[edge]' }]
557
+ args: [{
558
+ standalone: true,
559
+ selector: 'ng-template[edge]',
560
+ }]
561
561
  }] });
562
562
  class ConnectionTemplateDirective {
563
563
  constructor() {
564
564
  this.templateRef = inject(TemplateRef);
565
565
  }
566
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ConnectionTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
567
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: ConnectionTemplateDirective, selector: "ng-template[connection]", ngImport: i0 }); }
566
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ConnectionTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
567
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: ConnectionTemplateDirective, isStandalone: true, selector: "ng-template[connection]", ngImport: i0 }); }
568
568
  }
569
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ConnectionTemplateDirective, decorators: [{
569
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ConnectionTemplateDirective, decorators: [{
570
570
  type: Directive,
571
- args: [{ selector: 'ng-template[connection]' }]
571
+ args: [{
572
+ standalone: true,
573
+ selector: 'ng-template[connection]'
574
+ }]
572
575
  }] });
573
576
  class EdgeLabelHtmlTemplateDirective {
574
577
  constructor() {
575
578
  this.templateRef = inject(TemplateRef);
576
579
  }
577
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EdgeLabelHtmlTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
578
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: EdgeLabelHtmlTemplateDirective, selector: "ng-template[edgeLabelHtml]", ngImport: i0 }); }
580
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeLabelHtmlTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
581
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: EdgeLabelHtmlTemplateDirective, isStandalone: true, selector: "ng-template[edgeLabelHtml]", ngImport: i0 }); }
579
582
  }
580
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EdgeLabelHtmlTemplateDirective, decorators: [{
583
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeLabelHtmlTemplateDirective, decorators: [{
581
584
  type: Directive,
582
- args: [{ selector: 'ng-template[edgeLabelHtml]' }]
585
+ args: [{
586
+ standalone: true,
587
+ selector: 'ng-template[edgeLabelHtml]'
588
+ }]
583
589
  }] });
584
590
  class NodeHtmlTemplateDirective {
585
591
  constructor() {
586
592
  this.templateRef = inject(TemplateRef);
587
593
  }
588
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeHtmlTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
589
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: NodeHtmlTemplateDirective, selector: "ng-template[nodeHtml]", ngImport: i0 }); }
594
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeHtmlTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
595
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: NodeHtmlTemplateDirective, isStandalone: true, selector: "ng-template[nodeHtml]", ngImport: i0 }); }
590
596
  }
591
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeHtmlTemplateDirective, decorators: [{
597
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeHtmlTemplateDirective, decorators: [{
592
598
  type: Directive,
593
- args: [{ selector: 'ng-template[nodeHtml]' }]
599
+ args: [{
600
+ standalone: true,
601
+ selector: 'ng-template[nodeHtml]'
602
+ }]
594
603
  }] });
595
604
  class GroupNodeTemplateDirective {
596
605
  constructor() {
597
606
  this.templateRef = inject(TemplateRef);
598
607
  }
599
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupNodeTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
600
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: GroupNodeTemplateDirective, selector: "ng-template[groupNode]", ngImport: i0 }); }
608
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: GroupNodeTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
609
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: GroupNodeTemplateDirective, isStandalone: true, selector: "ng-template[groupNode]", ngImport: i0 }); }
601
610
  }
602
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupNodeTemplateDirective, decorators: [{
611
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: GroupNodeTemplateDirective, decorators: [{
603
612
  type: Directive,
604
- args: [{ selector: 'ng-template[groupNode]' }]
613
+ args: [{
614
+ standalone: true,
615
+ selector: 'ng-template[groupNode]'
616
+ }]
605
617
  }] });
606
618
  class HandleTemplateDirective {
607
619
  constructor() {
608
620
  this.templateRef = inject(TemplateRef);
609
621
  }
610
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HandleTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
611
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: HandleTemplateDirective, selector: "ng-template[handle]", ngImport: i0 }); }
622
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
623
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: HandleTemplateDirective, isStandalone: true, selector: "ng-template[handle]", ngImport: i0 }); }
612
624
  }
613
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HandleTemplateDirective, decorators: [{
625
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleTemplateDirective, decorators: [{
614
626
  type: Directive,
615
- args: [{ selector: 'ng-template[handle]' }]
627
+ args: [{
628
+ standalone: true,
629
+ selector: 'ng-template[handle]'
630
+ }]
616
631
  }] });
617
632
 
618
633
  function addNodesToEdges(nodes, edges) {
@@ -642,10 +657,10 @@ class FlowStatusService {
642
657
  setConnectionEndStatus(source, target, sourceHandle, targetHandle) {
643
658
  this.status.set({ state: 'connection-end', payload: { source, target, sourceHandle, targetHandle } });
644
659
  }
645
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FlowStatusService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
646
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FlowStatusService }); }
660
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowStatusService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
661
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowStatusService }); }
647
662
  }
648
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FlowStatusService, decorators: [{
663
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowStatusService, decorators: [{
649
664
  type: Injectable
650
665
  }] });
651
666
  /**
@@ -703,7 +718,7 @@ class ConnectionControllerDirective {
703
718
  * Also it's important to note, that this event only fires when connection is valid by validator function in `ConnectionSettings`,
704
719
  * by default without passing the validator every connection concidered valid.
705
720
  */
706
- this.onConnect = new EventEmitter();
721
+ this.onConnect = output();
707
722
  this.statusService = inject(FlowStatusService);
708
723
  this.flowEntitiesService = inject(FlowEntitiesService);
709
724
  this.connectEffect = effect(() => {
@@ -718,7 +733,7 @@ class ConnectionControllerDirective {
718
733
  source: status.payload.source,
719
734
  sourceHandle: status.payload.sourceHandle,
720
735
  target: status.payload.target,
721
- targetHandle: status.payload.targetHandle
736
+ targetHandle: status.payload.targetHandle,
722
737
  });
723
738
  source = adjusted.source;
724
739
  target = adjusted.target;
@@ -731,8 +746,10 @@ class ConnectionControllerDirective {
731
746
  const targetHandleId = targetHandle.rawHandle.id;
732
747
  const connectionModel = this.flowEntitiesService.connection();
733
748
  const connection = {
734
- source: sourceId, target: targetId,
735
- sourceHandle: sourceHandleId, targetHandle: targetHandleId
749
+ source: sourceId,
750
+ target: targetId,
751
+ sourceHandle: sourceHandleId,
752
+ targetHandle: targetHandleId,
736
753
  };
737
754
  if (connectionModel.validator(connection)) {
738
755
  this.onConnect.emit(connection);
@@ -757,7 +774,7 @@ class ConnectionControllerDirective {
757
774
  source: status.payload.source,
758
775
  sourceHandle: status.payload.sourceHandle,
759
776
  target: handle.parentNode,
760
- targetHandle: handle
777
+ targetHandle: handle,
761
778
  });
762
779
  source = adjusted.source;
763
780
  target = adjusted.target;
@@ -768,7 +785,7 @@ class ConnectionControllerDirective {
768
785
  source: source.node.id,
769
786
  target: target.node.id,
770
787
  sourceHandle: sourceHandle.rawHandle.id,
771
- targetHandle: targetHandle.rawHandle.id
788
+ targetHandle: targetHandle.rawHandle.id,
772
789
  });
773
790
  // TODO: check how react flow handles highlight of handle
774
791
  // if direction changes
@@ -800,18 +817,16 @@ class ConnectionControllerDirective {
800
817
  () => this.statusService.setIdleStatus());
801
818
  }
802
819
  }
803
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ConnectionControllerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
804
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: ConnectionControllerDirective, isStandalone: true, selector: "[connectionController]", outputs: { onConnect: "onConnect" }, ngImport: i0 }); }
820
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ConnectionControllerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
821
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: ConnectionControllerDirective, isStandalone: true, selector: "[connectionController]", outputs: { onConnect: "onConnect" }, ngImport: i0 }); }
805
822
  }
806
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ConnectionControllerDirective, decorators: [{
823
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ConnectionControllerDirective, decorators: [{
807
824
  type: Directive,
808
825
  args: [{
809
826
  selector: '[connectionController]',
810
- standalone: true
827
+ standalone: true,
811
828
  }]
812
- }], propDecorators: { onConnect: [{
813
- type: Output
814
- }] } });
829
+ }] });
815
830
 
816
831
  class ComponentEventBusService {
817
832
  constructor() {
@@ -821,89 +836,120 @@ class ComponentEventBusService {
821
836
  pushEvent(event) {
822
837
  this._event$.next(event);
823
838
  }
824
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ComponentEventBusService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
825
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ComponentEventBusService }); }
839
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ComponentEventBusService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
840
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ComponentEventBusService }); }
841
+ }
842
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ComponentEventBusService, decorators: [{
843
+ type: Injectable
844
+ }] });
845
+
846
+ /**
847
+ * Service to fix cyclic dependency between node and resizable component
848
+ */
849
+ class NodeAccessorService {
850
+ constructor() {
851
+ this.model = signal(null);
852
+ }
853
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeAccessorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
854
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeAccessorService }); }
826
855
  }
827
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ComponentEventBusService, decorators: [{
856
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeAccessorService, decorators: [{
828
857
  type: Injectable
829
858
  }] });
830
859
 
831
860
  class CustomNodeBaseComponent {
832
861
  constructor() {
833
862
  this.eventBus = inject(ComponentEventBusService);
863
+ this.nodeService = inject(NodeAccessorService);
834
864
  this.destroyRef = inject(DestroyRef);
835
865
  /**
836
866
  * Signal with selected state of node
837
867
  */
838
- this.selected = signal(false);
868
+ this.selected = this.nodeService.model().selected;
839
869
  this.data = signal(undefined);
840
870
  }
841
- set _selected(value) {
842
- this.selected.set(value);
843
- }
844
871
  ngOnInit() {
845
- this.trackEvents()
846
- .pipe(takeUntilDestroyed(this.destroyRef))
847
- .subscribe();
872
+ this.trackEvents().pipe(takeUntilDestroyed(this.destroyRef)).subscribe();
848
873
  }
849
874
  trackEvents() {
850
875
  const props = Object.getOwnPropertyNames(this);
851
- const emitters = new Map();
876
+ const emittersOrRefs = new Map();
852
877
  for (const prop of props) {
853
878
  const field = this[prop];
854
879
  if (field instanceof EventEmitter) {
855
- emitters.set(field, prop);
880
+ emittersOrRefs.set(field, prop);
881
+ }
882
+ if (field instanceof OutputEmitterRef) {
883
+ emittersOrRefs.set(outputRefToObservable(field), prop);
856
884
  }
857
885
  }
858
- return merge(...Array.from(emitters.keys()).map(emitter => emitter.pipe(tap((event) => {
886
+ return merge(...Array.from(emittersOrRefs.keys()).map((emitter) => emitter.pipe(tap((event) => {
859
887
  this.eventBus.pushEvent({
860
- nodeId: this.node.id,
861
- eventName: emitters.get(emitter),
862
- eventPayload: event
888
+ nodeId: this.nodeService.model()?.node.id ?? '',
889
+ eventName: emittersOrRefs.get(emitter),
890
+ eventPayload: event,
863
891
  });
864
892
  }))));
865
893
  }
866
- ;
867
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CustomNodeBaseComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
868
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CustomNodeBaseComponent, inputs: { _selected: "_selected" }, ngImport: i0 }); }
894
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomNodeBaseComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
895
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: CustomNodeBaseComponent, ngImport: i0 }); }
869
896
  }
870
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CustomNodeBaseComponent, decorators: [{
897
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomNodeBaseComponent, decorators: [{
871
898
  type: Directive
872
- }], propDecorators: { _selected: [{
873
- type: Input
874
- }] } });
899
+ }] });
900
+ function outputRefToObservable(ref) {
901
+ return new Observable((subscriber) => {
902
+ const subscription = ref.subscribe((value) => {
903
+ subscriber.next(value);
904
+ });
905
+ return () => {
906
+ subscription.unsubscribe();
907
+ };
908
+ });
909
+ }
875
910
 
876
911
  class CustomNodeComponent extends CustomNodeBaseComponent {
912
+ constructor() {
913
+ super(...arguments);
914
+ /**
915
+ * Reference to node bound to this component
916
+ */
917
+ this.node = input.required();
918
+ }
877
919
  ngOnInit() {
878
- if (this.node.data) {
879
- this.data.set(this.node.data);
920
+ if (this.node().data) {
921
+ this.data.set(this.node().data);
880
922
  }
881
923
  super.ngOnInit();
882
924
  }
883
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CustomNodeComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
884
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CustomNodeComponent, inputs: { node: "node" }, usesInheritance: true, ngImport: i0 }); }
925
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomNodeComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
926
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "17.3.12", type: CustomNodeComponent, inputs: { node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0 }); }
885
927
  }
886
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CustomNodeComponent, decorators: [{
928
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomNodeComponent, decorators: [{
887
929
  type: Directive
888
- }], propDecorators: { node: [{
889
- type: Input
890
- }] } });
930
+ }] });
891
931
 
892
932
  class CustomDynamicNodeComponent extends CustomNodeBaseComponent {
933
+ constructor() {
934
+ super(...arguments);
935
+ /**
936
+ * Reference to node bound to this component
937
+ */
938
+ this.node = input.required();
939
+ }
893
940
  ngOnInit() {
894
- if (this.node.data) {
895
- this.data = this.node.data;
941
+ const data = this.node().data;
942
+ if (data) {
943
+ this.data = data;
896
944
  }
897
945
  super.ngOnInit();
898
946
  }
899
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CustomDynamicNodeComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
900
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CustomDynamicNodeComponent, inputs: { node: "node" }, usesInheritance: true, ngImport: i0 }); }
947
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomDynamicNodeComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
948
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "17.3.12", type: CustomDynamicNodeComponent, inputs: { node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0 }); }
901
949
  }
902
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CustomDynamicNodeComponent, decorators: [{
950
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomDynamicNodeComponent, decorators: [{
903
951
  type: Directive
904
- }], propDecorators: { node: [{
905
- type: Input
906
- }] } });
952
+ }] });
907
953
 
908
954
  function isStaticNode(node) {
909
955
  return typeof node.point !== 'function';
@@ -977,9 +1023,6 @@ class NodeModel {
977
1023
  return { x, y };
978
1024
  });
979
1025
  this.pointTransform = computed(() => `translate(${this.globalPoint().x}, ${this.globalPoint().y})`);
980
- // Now source and handle positions derived from parent flow
981
- this.sourcePosition = computed(() => this.flowSettingsService.handlePositions().source);
982
- this.targetPosition = computed(() => this.flowSettingsService.handlePositions().target);
983
1026
  this.handles = signal([]);
984
1027
  this.handles$ = toObservable(this.handles);
985
1028
  this.draggable = signal(true);
@@ -992,12 +1035,9 @@ class NodeModel {
992
1035
  // Default node specific thing
993
1036
  this.text = this.createTextSignal();
994
1037
  // Component node specific thing
995
- this.componentTypeInputs = computed(() => {
996
- return {
997
- node: this.node,
998
- _selected: this.selected()
999
- };
1000
- });
1038
+ this.componentTypeInputs = {
1039
+ node: this.node,
1040
+ };
1001
1041
  this.parent = computed(() => this.entitiesService.nodes().find(n => n.node.id === this.parentId()) ?? null);
1002
1042
  this.children = computed(() => this.entitiesService.nodes().filter(n => n.parentId() === this.node.id));
1003
1043
  this.color = signal(NodeModel.defaultColor);
@@ -1533,10 +1573,10 @@ class NodesChangeService {
1533
1573
  // you can't get valid list of detached edges
1534
1574
  observeOn(asyncScheduler, DELAY_FOR_SCHEDULER));
1535
1575
  }
1536
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodesChangeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1537
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodesChangeService }); }
1576
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodesChangeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1577
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodesChangeService }); }
1538
1578
  }
1539
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodesChangeService, decorators: [{
1579
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodesChangeService, decorators: [{
1540
1580
  type: Injectable
1541
1581
  }] });
1542
1582
 
@@ -1577,10 +1617,10 @@ class EdgeChangesService {
1577
1617
  // right after [nodes] input change
1578
1618
  observeOn(asyncScheduler));
1579
1619
  }
1580
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EdgeChangesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1581
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EdgeChangesService }); }
1620
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeChangesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1621
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeChangesService }); }
1582
1622
  }
1583
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EdgeChangesService, decorators: [{
1623
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeChangesService, decorators: [{
1584
1624
  type: Injectable
1585
1625
  }] });
1586
1626
 
@@ -1591,146 +1631,61 @@ class ChangesControllerDirective {
1591
1631
  /**
1592
1632
  * Watch nodes change
1593
1633
  */
1594
- this.onNodesChange = this.nodesChangeService.changes$;
1595
- this.onNodesChangePosition = this.nodeChangesOfType('position');
1596
- this.onNodesChangePositionSignle = this.singleChange(this.nodeChangesOfType('position'));
1597
- this.onNodesChangePositionMany = this.manyChanges(this.nodeChangesOfType('position'));
1598
- this.onNodesChangeSize = this.nodeChangesOfType('size');
1599
- this.onNodesChangeSizeSingle = this.singleChange(this.nodeChangesOfType('size'));
1600
- this.onNodesChangeSizeMany = this.manyChanges(this.nodeChangesOfType('size'));
1601
- this.onNodesChangeAdd = this.nodeChangesOfType('add');
1602
- this.onNodesChangeAddSingle = this.singleChange(this.nodeChangesOfType('add'));
1603
- this.onNodesChangeAddMany = this.manyChanges(this.nodeChangesOfType('add'));
1604
- this.onNodesChangeRemove = this.nodeChangesOfType('remove');
1605
- this.onNodesChangeRemoveSingle = this.singleChange(this.nodeChangesOfType('remove'));
1606
- this.onNodesChangeRemoveMany = this.manyChanges(this.nodeChangesOfType('remove'));
1607
- this.onNodesChangeSelect = this.nodeChangesOfType('select');
1608
- this.onNodesChangeSelectSingle = this.singleChange(this.nodeChangesOfType('select'));
1609
- this.onNodesChangeSelectMany = this.manyChanges(this.nodeChangesOfType('select'));
1634
+ this.onNodesChange = outputFromObservable(this.nodesChangeService.changes$);
1635
+ this.onNodesChangePosition = outputFromObservable(this.nodeChangesOfType('position'), { alias: 'onNodesChange.position' });
1636
+ this.onNodesChangePositionSignle = outputFromObservable(this.singleChange(this.nodeChangesOfType('position')), { alias: 'onNodesChange.position.single' });
1637
+ this.onNodesChangePositionMany = outputFromObservable(this.manyChanges(this.nodeChangesOfType('position')), { alias: 'onNodesChange.position.many' });
1638
+ this.onNodesChangeSize = outputFromObservable(this.nodeChangesOfType('size'), { alias: 'onNodesChange.size' });
1639
+ this.onNodesChangeSizeSingle = outputFromObservable(this.singleChange(this.nodeChangesOfType('size')), { alias: 'onNodesChange.size.single' });
1640
+ this.onNodesChangeSizeMany = outputFromObservable(this.manyChanges(this.nodeChangesOfType('size')), { alias: 'onNodesChange.size.many' });
1641
+ this.onNodesChangeAdd = outputFromObservable(this.nodeChangesOfType('add'), { alias: 'onNodesChange.add' });
1642
+ this.onNodesChangeAddSingle = outputFromObservable(this.singleChange(this.nodeChangesOfType('add')), { alias: 'onNodesChange.add.single' });
1643
+ this.onNodesChangeAddMany = outputFromObservable(this.manyChanges(this.nodeChangesOfType('add')), { alias: 'onNodesChange.add.many' });
1644
+ this.onNodesChangeRemove = outputFromObservable(this.nodeChangesOfType('remove'), { alias: 'onNodesChange.remove' });
1645
+ this.onNodesChangeRemoveSingle = outputFromObservable(this.singleChange(this.nodeChangesOfType('remove')), { alias: 'onNodesChange.remove.single' });
1646
+ this.onNodesChangeRemoveMany = outputFromObservable(this.manyChanges(this.nodeChangesOfType('remove')), { alias: 'onNodesChange.remove.many' });
1647
+ this.onNodesChangeSelect = outputFromObservable(this.nodeChangesOfType('select'), { alias: 'onNodesChange.select' });
1648
+ this.onNodesChangeSelectSingle = outputFromObservable(this.singleChange(this.nodeChangesOfType('select')), { alias: 'onNodesChange.select.single' });
1649
+ this.onNodesChangeSelectMany = outputFromObservable(this.manyChanges(this.nodeChangesOfType('select')), { alias: 'onNodesChange.select.many' });
1610
1650
  /**
1611
1651
  * Watch edges change
1612
1652
  */
1613
- this.onEdgesChange = this.edgesChangeService.changes$;
1614
- this.onNodesChangeDetached = this.edgeChangesOfType('detached');
1615
- this.onNodesChangeDetachedSingle = this.singleChange(this.edgeChangesOfType('detached'));
1616
- this.onNodesChangeDetachedMany = this.manyChanges(this.edgeChangesOfType('detached'));
1617
- this.onEdgesChangeAdd = this.edgeChangesOfType('add');
1618
- this.onEdgeChangeAddSingle = this.singleChange(this.edgeChangesOfType('add'));
1619
- this.onEdgeChangeAddMany = this.manyChanges(this.edgeChangesOfType('add'));
1620
- this.onEdgeChangeRemove = this.edgeChangesOfType('remove');
1621
- this.onEdgeChangeRemoveSingle = this.singleChange(this.edgeChangesOfType('remove'));
1622
- this.onEdgeChangeRemoveMany = this.manyChanges(this.edgeChangesOfType('remove'));
1623
- this.onEdgeChangeSelect = this.edgeChangesOfType('select');
1624
- this.onEdgeChangeSelectSingle = this.singleChange(this.edgeChangesOfType('select'));
1625
- this.onEdgeChangeSelectMany = this.manyChanges(this.edgeChangesOfType('select'));
1653
+ this.onEdgesChange = outputFromObservable(this.edgesChangeService.changes$);
1654
+ this.onNodesChangeDetached = outputFromObservable(this.edgeChangesOfType('detached'), { alias: 'onEdgesChange.detached' });
1655
+ this.onNodesChangeDetachedSingle = outputFromObservable(this.singleChange(this.edgeChangesOfType('detached')), { alias: 'onEdgesChange.detached.single' });
1656
+ this.onNodesChangeDetachedMany = outputFromObservable(this.manyChanges(this.edgeChangesOfType('detached')), { alias: 'onEdgesChange.detached.many' });
1657
+ this.onEdgesChangeAdd = outputFromObservable(this.edgeChangesOfType('add'), { alias: 'onEdgesChange.add' });
1658
+ this.onEdgeChangeAddSingle = outputFromObservable(this.singleChange(this.edgeChangesOfType('add')), { alias: 'onEdgesChange.add.single' });
1659
+ this.onEdgeChangeAddMany = outputFromObservable(this.manyChanges(this.edgeChangesOfType('add')), { alias: 'onEdgesChange.add.many' });
1660
+ this.onEdgeChangeRemove = outputFromObservable(this.edgeChangesOfType('remove'), { alias: 'onEdgesChange.remove' });
1661
+ this.onEdgeChangeRemoveSingle = outputFromObservable(this.singleChange(this.edgeChangesOfType('remove')), { alias: 'onEdgesChange.remove.single' });
1662
+ this.onEdgeChangeRemoveMany = outputFromObservable(this.manyChanges(this.edgeChangesOfType('remove')), { alias: 'onEdgesChange.remove.many' });
1663
+ this.onEdgeChangeSelect = outputFromObservable(this.edgeChangesOfType('select'), { alias: 'onEdgesChange.select' });
1664
+ this.onEdgeChangeSelectSingle = outputFromObservable(this.singleChange(this.edgeChangesOfType('select')), { alias: 'onEdgesChange.select.single' });
1665
+ this.onEdgeChangeSelectMany = outputFromObservable(this.manyChanges(this.edgeChangesOfType('select')), { alias: 'onEdgesChange.select.many' });
1626
1666
  }
1627
1667
  nodeChangesOfType(type) {
1628
- return this.nodesChangeService.changes$.pipe(map(changes => changes.filter((c) => c.type === type)), filter(changes => !!changes.length));
1668
+ return this.nodesChangeService.changes$.pipe(map((changes) => changes.filter((c) => c.type === type)), filter((changes) => !!changes.length));
1629
1669
  }
1630
1670
  edgeChangesOfType(type) {
1631
- return this.edgesChangeService.changes$.pipe(map(changes => changes.filter((c) => c.type === type)), filter(changes => !!changes.length));
1671
+ return this.edgesChangeService.changes$.pipe(map((changes) => changes.filter((c) => c.type === type)), filter((changes) => !!changes.length));
1632
1672
  }
1633
1673
  singleChange(changes$) {
1634
- return changes$.pipe(filter(changes => changes.length === 1), map(([first]) => first));
1674
+ return changes$.pipe(filter((changes) => changes.length === 1), map(([first]) => first));
1635
1675
  }
1636
1676
  manyChanges(changes$) {
1637
- return changes$.pipe(filter(changes => changes.length > 1));
1677
+ return changes$.pipe(filter((changes) => changes.length > 1));
1638
1678
  }
1639
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ChangesControllerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1640
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: ChangesControllerDirective, isStandalone: true, selector: "[changesController]", outputs: { onNodesChange: "onNodesChange", onNodesChangePosition: "onNodesChange.position", onNodesChangePositionSignle: "onNodesChange.position.single", onNodesChangePositionMany: "onNodesChange.position.many", onNodesChangeSize: "onNodesChange.size", onNodesChangeSizeSingle: "onNodesChange.size.single", onNodesChangeSizeMany: "onNodesChange.size.many", onNodesChangeAdd: "onNodesChange.add", onNodesChangeAddSingle: "onNodesChange.add.single", onNodesChangeAddMany: "onNodesChange.add.many", onNodesChangeRemove: "onNodesChange.remove", onNodesChangeRemoveSingle: "onNodesChange.remove.single", onNodesChangeRemoveMany: "onNodesChange.remove.many", onNodesChangeSelect: "onNodesChange.select", onNodesChangeSelectSingle: "onNodesChange.select.single", onNodesChangeSelectMany: "onNodesChange.select.many", onEdgesChange: "onEdgesChange", onNodesChangeDetached: "onEdgesChange.detached", onNodesChangeDetachedSingle: "onEdgesChange.detached.single", onNodesChangeDetachedMany: "onEdgesChange.detached.many", onEdgesChangeAdd: "onEdgesChange.add", onEdgeChangeAddSingle: "onEdgesChange.add.single", onEdgeChangeAddMany: "onEdgesChange.add.many", onEdgeChangeRemove: "onEdgesChange.remove", onEdgeChangeRemoveSingle: "onEdgesChange.remove.single", onEdgeChangeRemoveMany: "onEdgesChange.remove.many", onEdgeChangeSelect: "onEdgesChange.select", onEdgeChangeSelectSingle: "onEdgesChange.select.single", onEdgeChangeSelectMany: "onEdgesChange.select.many" }, ngImport: i0 }); }
1679
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ChangesControllerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1680
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: ChangesControllerDirective, isStandalone: true, selector: "[changesController]", outputs: { onNodesChange: "onNodesChange", onNodesChangePosition: "onNodesChange.position", onNodesChangePositionSignle: "onNodesChange.position.single", onNodesChangePositionMany: "onNodesChange.position.many", onNodesChangeSize: "onNodesChange.size", onNodesChangeSizeSingle: "onNodesChange.size.single", onNodesChangeSizeMany: "onNodesChange.size.many", onNodesChangeAdd: "onNodesChange.add", onNodesChangeAddSingle: "onNodesChange.add.single", onNodesChangeAddMany: "onNodesChange.add.many", onNodesChangeRemove: "onNodesChange.remove", onNodesChangeRemoveSingle: "onNodesChange.remove.single", onNodesChangeRemoveMany: "onNodesChange.remove.many", onNodesChangeSelect: "onNodesChange.select", onNodesChangeSelectSingle: "onNodesChange.select.single", onNodesChangeSelectMany: "onNodesChange.select.many", onEdgesChange: "onEdgesChange", onNodesChangeDetached: "onEdgesChange.detached", onNodesChangeDetachedSingle: "onEdgesChange.detached.single", onNodesChangeDetachedMany: "onEdgesChange.detached.many", onEdgesChangeAdd: "onEdgesChange.add", onEdgeChangeAddSingle: "onEdgesChange.add.single", onEdgeChangeAddMany: "onEdgesChange.add.many", onEdgeChangeRemove: "onEdgesChange.remove", onEdgeChangeRemoveSingle: "onEdgesChange.remove.single", onEdgeChangeRemoveMany: "onEdgesChange.remove.many", onEdgeChangeSelect: "onEdgesChange.select", onEdgeChangeSelectSingle: "onEdgesChange.select.single", onEdgeChangeSelectMany: "onEdgesChange.select.many" }, ngImport: i0 }); }
1641
1681
  }
1642
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ChangesControllerDirective, decorators: [{
1682
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ChangesControllerDirective, decorators: [{
1643
1683
  type: Directive,
1644
1684
  args: [{
1645
1685
  selector: '[changesController]',
1646
- standalone: true
1686
+ standalone: true,
1647
1687
  }]
1648
- }], propDecorators: { onNodesChange: [{
1649
- type: Output
1650
- }], onNodesChangePosition: [{
1651
- type: Output,
1652
- args: ['onNodesChange.position']
1653
- }], onNodesChangePositionSignle: [{
1654
- type: Output,
1655
- args: ['onNodesChange.position.single']
1656
- }], onNodesChangePositionMany: [{
1657
- type: Output,
1658
- args: ['onNodesChange.position.many']
1659
- }], onNodesChangeSize: [{
1660
- type: Output,
1661
- args: ['onNodesChange.size']
1662
- }], onNodesChangeSizeSingle: [{
1663
- type: Output,
1664
- args: ['onNodesChange.size.single']
1665
- }], onNodesChangeSizeMany: [{
1666
- type: Output,
1667
- args: ['onNodesChange.size.many']
1668
- }], onNodesChangeAdd: [{
1669
- type: Output,
1670
- args: ['onNodesChange.add']
1671
- }], onNodesChangeAddSingle: [{
1672
- type: Output,
1673
- args: ['onNodesChange.add.single']
1674
- }], onNodesChangeAddMany: [{
1675
- type: Output,
1676
- args: ['onNodesChange.add.many']
1677
- }], onNodesChangeRemove: [{
1678
- type: Output,
1679
- args: ['onNodesChange.remove']
1680
- }], onNodesChangeRemoveSingle: [{
1681
- type: Output,
1682
- args: ['onNodesChange.remove.single']
1683
- }], onNodesChangeRemoveMany: [{
1684
- type: Output,
1685
- args: ['onNodesChange.remove.many']
1686
- }], onNodesChangeSelect: [{
1687
- type: Output,
1688
- args: ['onNodesChange.select']
1689
- }], onNodesChangeSelectSingle: [{
1690
- type: Output,
1691
- args: ['onNodesChange.select.single']
1692
- }], onNodesChangeSelectMany: [{
1693
- type: Output,
1694
- args: ['onNodesChange.select.many']
1695
- }], onEdgesChange: [{
1696
- type: Output
1697
- }], onNodesChangeDetached: [{
1698
- type: Output,
1699
- args: ['onEdgesChange.detached']
1700
- }], onNodesChangeDetachedSingle: [{
1701
- type: Output,
1702
- args: ['onEdgesChange.detached.single']
1703
- }], onNodesChangeDetachedMany: [{
1704
- type: Output,
1705
- args: ['onEdgesChange.detached.many']
1706
- }], onEdgesChangeAdd: [{
1707
- type: Output,
1708
- args: ['onEdgesChange.add']
1709
- }], onEdgeChangeAddSingle: [{
1710
- type: Output,
1711
- args: ['onEdgesChange.add.single']
1712
- }], onEdgeChangeAddMany: [{
1713
- type: Output,
1714
- args: ['onEdgesChange.add.many']
1715
- }], onEdgeChangeRemove: [{
1716
- type: Output,
1717
- args: ['onEdgesChange.remove']
1718
- }], onEdgeChangeRemoveSingle: [{
1719
- type: Output,
1720
- args: ['onEdgesChange.remove.single']
1721
- }], onEdgeChangeRemoveMany: [{
1722
- type: Output,
1723
- args: ['onEdgesChange.remove.many']
1724
- }], onEdgeChangeSelect: [{
1725
- type: Output,
1726
- args: ['onEdgesChange.select']
1727
- }], onEdgeChangeSelectSingle: [{
1728
- type: Output,
1729
- args: ['onEdgesChange.select.single']
1730
- }], onEdgeChangeSelectMany: [{
1731
- type: Output,
1732
- args: ['onEdgesChange.select.many']
1733
- }] } });
1688
+ }] });
1734
1689
 
1735
1690
  function isGroupNode(node) {
1736
1691
  return node.node.type === 'default-group' || node.node.type === 'template-group';
@@ -1763,10 +1718,10 @@ class NodeRenderingService {
1763
1718
  .filter(n => n.parent() === node)
1764
1719
  .forEach(n => this.pullNode(n));
1765
1720
  }
1766
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeRenderingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1767
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeRenderingService }); }
1721
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeRenderingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1722
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeRenderingService }); }
1768
1723
  }
1769
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeRenderingService, decorators: [{
1724
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeRenderingService, decorators: [{
1770
1725
  type: Injectable
1771
1726
  }] });
1772
1727
 
@@ -1818,12 +1773,15 @@ class RootPointerDirective {
1818
1773
  setInitialTouch(event) {
1819
1774
  this.initialTouch$.next(event);
1820
1775
  }
1821
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RootPointerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1822
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: RootPointerDirective, selector: "svg[rootPointer]", ngImport: i0 }); }
1776
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RootPointerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1777
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: RootPointerDirective, isStandalone: true, selector: "svg[rootPointer]", ngImport: i0 }); }
1823
1778
  }
1824
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RootPointerDirective, decorators: [{
1779
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RootPointerDirective, decorators: [{
1825
1780
  type: Directive,
1826
- args: [{ selector: 'svg[rootPointer]' }]
1781
+ args: [{
1782
+ standalone: true,
1783
+ selector: 'svg[rootPointer]',
1784
+ }]
1827
1785
  }] });
1828
1786
 
1829
1787
  class SpacePointContextDirective {
@@ -1852,12 +1810,15 @@ class SpacePointContextDirective {
1852
1810
  point.y = documentPoint.y;
1853
1811
  return point.matrixTransform(this.host.getScreenCTM().inverse());
1854
1812
  }
1855
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SpacePointContextDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1856
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: SpacePointContextDirective, selector: "g[spacePointContext]", ngImport: i0 }); }
1813
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SpacePointContextDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1814
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: SpacePointContextDirective, isStandalone: true, selector: "g[spacePointContext]", ngImport: i0 }); }
1857
1815
  }
1858
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SpacePointContextDirective, decorators: [{
1816
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SpacePointContextDirective, decorators: [{
1859
1817
  type: Directive,
1860
- args: [{ selector: 'g[spacePointContext]' }]
1818
+ args: [{
1819
+ standalone: true,
1820
+ selector: 'g[spacePointContext]',
1821
+ }]
1861
1822
  }] });
1862
1823
 
1863
1824
  function transformBackground(background) {
@@ -1894,8 +1855,8 @@ class OverlaysService {
1894
1855
  removeToolbar(toolbar) {
1895
1856
  this.toolbars.update((toolbars) => toolbars.filter(t => t !== toolbar));
1896
1857
  }
1897
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: OverlaysService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1898
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: OverlaysService }); }
1858
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: OverlaysService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1859
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: OverlaysService }); }
1899
1860
  }
1900
1861
  __decorate([
1901
1862
  Microtask
@@ -1903,10 +1864,105 @@ __decorate([
1903
1864
  __decorate([
1904
1865
  Microtask
1905
1866
  ], OverlaysService.prototype, "removeToolbar", null);
1906
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: OverlaysService, decorators: [{
1867
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: OverlaysService, decorators: [{
1907
1868
  type: Injectable
1908
1869
  }], propDecorators: { addToolbar: [], removeToolbar: [] } });
1909
1870
 
1871
+ class EdgeLabelComponent {
1872
+ constructor() {
1873
+ // TODO: too many inputs
1874
+ this.model = input.required();
1875
+ this.edgeModel = input.required();
1876
+ this.point = input({ x: 0, y: 0 });
1877
+ this.htmlTemplate = input();
1878
+ this.edgeLabelWrapperRef = viewChild.required('edgeLabelWrapper');
1879
+ /**
1880
+ * Centered point of label
1881
+ *
1882
+ * TODO: maybe put it into EdgeLabelModel
1883
+ */
1884
+ this.edgeLabelPoint = computed(() => {
1885
+ const point = this.point();
1886
+ const { width, height } = this.model().size();
1887
+ return {
1888
+ x: point.x - width / 2,
1889
+ y: point.y - height / 2,
1890
+ };
1891
+ });
1892
+ }
1893
+ ngAfterViewInit() {
1894
+ // this is a fix for visual artifact in chrome that for some reason adresses only for edge label.
1895
+ // the bug reproduces if edgeLabelWrapperRef size fully matched the size of parent foreignObject
1896
+ const MAGIC_VALUE_TO_FIX_GLITCH_IN_CHROME = 2;
1897
+ const width = this.edgeLabelWrapperRef().nativeElement.clientWidth +
1898
+ MAGIC_VALUE_TO_FIX_GLITCH_IN_CHROME;
1899
+ const height = this.edgeLabelWrapperRef().nativeElement.clientHeight +
1900
+ MAGIC_VALUE_TO_FIX_GLITCH_IN_CHROME;
1901
+ this.model().size.set({ width, height });
1902
+ }
1903
+ getLabelContext() {
1904
+ return {
1905
+ $implicit: {
1906
+ edge: this.edgeModel().edge,
1907
+ label: this.model().edgeLabel,
1908
+ },
1909
+ };
1910
+ }
1911
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeLabelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1912
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: EdgeLabelComponent, isStandalone: true, selector: "g[edgeLabel]", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, edgeModel: { classPropertyName: "edgeModel", publicName: "edgeModel", isSignal: true, isRequired: true, transformFunction: null }, point: { classPropertyName: "point", publicName: "point", isSignal: true, isRequired: false, transformFunction: null }, htmlTemplate: { classPropertyName: "htmlTemplate", publicName: "htmlTemplate", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "edgeLabelWrapperRef", first: true, predicate: ["edgeLabelWrapper"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (model().edgeLabel.type === \"html-template\" && htmlTemplate()) {\n @if (htmlTemplate(); as htmlTemplate) {\n <svg:foreignObject\n [attr.x]=\"edgeLabelPoint().x\"\n [attr.y]=\"edgeLabelPoint().y\"\n [attr.width]=\"model().size().width\"\n [attr.height]=\"model().size().height\"\n >\n <div #edgeLabelWrapper class=\"edge-label-wrapper\">\n <ng-container\n *ngTemplateOutlet=\"htmlTemplate; context: getLabelContext()\"\n />\n </div>\n </svg:foreignObject>\n }\n}\n", styles: [".edge-label-wrapper{width:max-content;margin-top:1px;margin-left:1px}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1913
+ }
1914
+ __decorate([
1915
+ Microtask
1916
+ ], EdgeLabelComponent.prototype, "ngAfterViewInit", null);
1917
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeLabelComponent, decorators: [{
1918
+ type: Component,
1919
+ args: [{ standalone: true, selector: 'g[edgeLabel]', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet], template: "@if (model().edgeLabel.type === \"html-template\" && htmlTemplate()) {\n @if (htmlTemplate(); as htmlTemplate) {\n <svg:foreignObject\n [attr.x]=\"edgeLabelPoint().x\"\n [attr.y]=\"edgeLabelPoint().y\"\n [attr.width]=\"model().size().width\"\n [attr.height]=\"model().size().height\"\n >\n <div #edgeLabelWrapper class=\"edge-label-wrapper\">\n <ng-container\n *ngTemplateOutlet=\"htmlTemplate; context: getLabelContext()\"\n />\n </div>\n </svg:foreignObject>\n }\n}\n", styles: [".edge-label-wrapper{width:max-content;margin-top:1px;margin-left:1px}\n"] }]
1920
+ }], propDecorators: { ngAfterViewInit: [] } });
1921
+
1922
+ class EdgeComponent {
1923
+ constructor() {
1924
+ this.injector = inject(Injector);
1925
+ this.selectionService = inject(SelectionService);
1926
+ this.flowSettingsService = inject(FlowSettingsService);
1927
+ this.model = input.required();
1928
+ this.edgeTemplate = input();
1929
+ this.edgeLabelHtmlTemplate = input();
1930
+ this.markerStartUrl = computed(() => {
1931
+ const marker = this.model().edge.markers?.start;
1932
+ return marker ? `url(#${hashCode(JSON.stringify(marker))})` : '';
1933
+ });
1934
+ this.markerEndUrl = computed(() => {
1935
+ const marker = this.model().edge.markers?.end;
1936
+ return marker ? `url(#${hashCode(JSON.stringify(marker))})` : '';
1937
+ });
1938
+ }
1939
+ ngOnInit() {
1940
+ this.edgeContext = {
1941
+ $implicit: {
1942
+ // TODO: check if edge could change
1943
+ edge: this.model().edge,
1944
+ path: computed(() => this.model().path().path),
1945
+ markerStart: this.markerStartUrl,
1946
+ markerEnd: this.markerEndUrl,
1947
+ selected: this.model().selected.asReadonly(),
1948
+ },
1949
+ };
1950
+ }
1951
+ onEdgeMouseDown() {
1952
+ if (this.flowSettingsService.entitiesSelectable()) {
1953
+ this.selectionService.select(this.model());
1954
+ }
1955
+ }
1956
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1957
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: EdgeComponent, isStandalone: true, selector: "g[edge]", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, edgeTemplate: { classPropertyName: "edgeTemplate", publicName: "edgeTemplate", isSignal: true, isRequired: false, transformFunction: null }, edgeLabelHtmlTemplate: { classPropertyName: "edgeLabelHtmlTemplate", publicName: "edgeLabelHtmlTemplate", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "selectable" }, ngImport: i0, template: "@if (model().type === \"default\") {\n <svg:path\n (mousedown)=\"onEdgeMouseDown()\"\n [attr.d]=\"model().path().path\"\n [attr.marker-start]=\"markerStartUrl()\"\n [attr.marker-end]=\"markerEndUrl()\"\n class=\"edge\"\n [class.edge_selected]=\"model().selected()\"\n />\n}\n\n@if (model().type === \"template\" && edgeTemplate()) {\n @if (edgeTemplate(); as edgeTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"edgeTemplate\"\n [ngTemplateOutletContext]=\"edgeContext\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n }\n}\n\n@if (model().edgeLabels.start; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.start\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\"\n />\n}\n\n@if (model().edgeLabels.center; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.center\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\"\n />\n}\n\n@if (model().edgeLabels.end; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.end\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\"\n />\n}\n", styles: [".edge{fill:none;stroke-width:2;stroke:#b1b1b7}.edge_selected{stroke-width:2.5;stroke:#0f4c75}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: EdgeLabelComponent, selector: "g[edgeLabel]", inputs: ["model", "edgeModel", "point", "htmlTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1958
+ }
1959
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeComponent, decorators: [{
1960
+ type: Component,
1961
+ args: [{ standalone: true, selector: 'g[edge]', changeDetection: ChangeDetectionStrategy.OnPush, host: {
1962
+ class: 'selectable',
1963
+ }, imports: [NgTemplateOutlet, EdgeLabelComponent], template: "@if (model().type === \"default\") {\n <svg:path\n (mousedown)=\"onEdgeMouseDown()\"\n [attr.d]=\"model().path().path\"\n [attr.marker-start]=\"markerStartUrl()\"\n [attr.marker-end]=\"markerEndUrl()\"\n class=\"edge\"\n [class.edge_selected]=\"model().selected()\"\n />\n}\n\n@if (model().type === \"template\" && edgeTemplate()) {\n @if (edgeTemplate(); as edgeTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"edgeTemplate\"\n [ngTemplateOutletContext]=\"edgeContext\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n }\n}\n\n@if (model().edgeLabels.start; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.start\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\"\n />\n}\n\n@if (model().edgeLabels.center; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.center\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\"\n />\n}\n\n@if (model().edgeLabels.end; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.end\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\"\n />\n}\n", styles: [".edge{fill:none;stroke-width:2;stroke:#b1b1b7}.edge_selected{stroke-width:2.5;stroke:#0f4c75}\n"] }]
1964
+ }] });
1965
+
1910
1966
  class HandleService {
1911
1967
  constructor() {
1912
1968
  this.node = signal(null);
@@ -1923,13 +1979,13 @@ class HandleService {
1923
1979
  node.handles.update(handles => handles.filter(handle => handle !== handleToDestoy));
1924
1980
  }
1925
1981
  }
1926
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HandleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1927
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HandleService }); }
1982
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1983
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleService }); }
1928
1984
  }
1929
1985
  __decorate([
1930
1986
  Microtask // TODO fixes rendering of handle for group node
1931
1987
  ], HandleService.prototype, "createHandle", null);
1932
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HandleService, decorators: [{
1988
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleService, decorators: [{
1933
1989
  type: Injectable
1934
1990
  }], propDecorators: { createHandle: [] } });
1935
1991
 
@@ -1960,191 +2016,86 @@ const implementsWithInjector = (instance) => {
1960
2016
  return 'injector' in instance && 'get' in instance.injector;
1961
2017
  };
1962
2018
 
1963
- /**
1964
- * Service to fix cyclic dependency between node and resizable component
1965
- */
1966
- class NodeAccessorService {
2019
+ class HandleSizeControllerDirective {
1967
2020
  constructor() {
1968
- this.model = signal(null);
2021
+ this.handleModel = input.required({
2022
+ alias: 'handleSizeController',
2023
+ });
2024
+ this.handleWrapper = inject(ElementRef);
2025
+ }
2026
+ ngAfterViewInit() {
2027
+ const element = this.handleWrapper.nativeElement;
2028
+ const rect = element.getBBox();
2029
+ const stroke = getChildStrokeWidth(element);
2030
+ this.handleModel().size.set({
2031
+ width: rect.width + stroke,
2032
+ height: rect.height + stroke,
2033
+ });
1969
2034
  }
1970
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeAccessorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1971
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeAccessorService }); }
2035
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleSizeControllerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2036
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "17.3.12", type: HandleSizeControllerDirective, isStandalone: true, selector: "[handleSizeController]", inputs: { handleModel: { classPropertyName: "handleModel", publicName: "handleSizeController", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 }); }
1972
2037
  }
1973
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeAccessorService, decorators: [{
1974
- type: Injectable
2038
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleSizeControllerDirective, decorators: [{
2039
+ type: Directive,
2040
+ args: [{
2041
+ standalone: true,
2042
+ selector: '[handleSizeController]',
2043
+ }]
1975
2044
  }] });
2045
+ function getChildStrokeWidth(element) {
2046
+ const child = element.firstElementChild;
2047
+ if (child) {
2048
+ const stroke = getComputedStyle(child).strokeWidth;
2049
+ const strokeAsNumber = Number(stroke.replace('px', ''));
2050
+ if (isNaN(strokeAsNumber)) {
2051
+ return 0;
2052
+ }
2053
+ return strokeAsNumber;
2054
+ }
2055
+ return 0;
2056
+ }
1976
2057
 
1977
2058
  class DefaultNodeComponent {
1978
2059
  constructor() {
1979
- this.selected = false;
2060
+ this.selected = input(false);
1980
2061
  }
1981
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DefaultNodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1982
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DefaultNodeComponent, selector: "default-node", inputs: { selected: "selected" }, host: { properties: { "class.selected": "selected" } }, ngImport: i0, template: "<ng-content />\n", styles: [":host{border:1.5px solid #1b262c;border-radius:5px;display:flex;align-items:center;justify-content:center;color:#000;background-color:#fff}:host(.selected){border-width:2px}\n"] }); }
2062
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DefaultNodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2063
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "17.3.12", type: DefaultNodeComponent, isStandalone: true, selector: "default-node", inputs: { selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.selected": "selected()" } }, ngImport: i0, template: "<ng-content />\n", styles: [":host{border:1.5px solid #1b262c;border-radius:5px;display:flex;align-items:center;justify-content:center;color:#000;background-color:#fff}:host(.selected){border-width:2px}\n"] }); }
1983
2064
  }
1984
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DefaultNodeComponent, decorators: [{
2065
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DefaultNodeComponent, decorators: [{
1985
2066
  type: Component,
1986
- args: [{ selector: 'default-node', host: {
1987
- '[class.selected]': 'selected'
2067
+ args: [{ standalone: true, selector: 'default-node', host: {
2068
+ '[class.selected]': 'selected()',
1988
2069
  }, template: "<ng-content />\n", styles: [":host{border:1.5px solid #1b262c;border-radius:5px;display:flex;align-items:center;justify-content:center;color:#000;background-color:#fff}:host(.selected){border-width:2px}\n"] }]
1989
- }], propDecorators: { selected: [{
1990
- type: Input
1991
- }] } });
2070
+ }] });
1992
2071
 
1993
- class HandleModel {
1994
- constructor(rawHandle, parentNode) {
1995
- this.rawHandle = rawHandle;
1996
- this.parentNode = parentNode;
1997
- this.strokeWidth = 2;
2072
+ class PointerDirective {
2073
+ constructor() {
2074
+ this.hostElement = inject(ElementRef).nativeElement;
2075
+ this.pointerMovementDirective = inject(RootPointerDirective);
2076
+ this.pointerOver = output();
2077
+ this.pointerOut = output();
1998
2078
  /**
1999
- * Pre-computed size for default handle, changed dynamically
2000
- * for custom handles
2079
+ * @todo the Angular may somehow ignore the event.
2080
+ * reproduced here: https://www.ngx-vflow.org/workshops/layout/vizdom-layout
2001
2081
  */
2002
- this.size = signal({
2003
- width: 10 + (2 * this.strokeWidth),
2004
- height: 10 + (2 * this.strokeWidth)
2005
- });
2006
- this.offset = computed(() => {
2007
- switch (this.rawHandle.position) {
2008
- case 'left': return {
2009
- x: 0,
2010
- y: this.parentPosition().y + (this.parentSize().height / 2)
2011
- };
2012
- case 'right': return {
2013
- x: this.parentNode.size().width,
2014
- y: this.parentPosition().y + (this.parentSize().height / 2)
2015
- };
2016
- case 'top': return {
2017
- x: this.parentPosition().x + (this.parentSize().width / 2),
2018
- y: 0
2019
- };
2020
- case 'bottom': return {
2021
- x: this.parentPosition().x + this.parentSize().width / 2,
2022
- y: this.parentNode.size().height
2023
- };
2024
- }
2025
- });
2026
- this.sizeOffset = computed(() => {
2027
- switch (this.rawHandle.position) {
2028
- case 'left': return { x: -(this.size().width / 2), y: 0 };
2029
- case 'right': return { x: this.size().width / 2, y: 0 };
2030
- case 'top': return { x: 0, y: -(this.size().height / 2) };
2031
- case 'bottom': return { x: 0, y: this.size().height / 2 };
2032
- }
2033
- });
2034
- this.pointAbsolute = computed(() => {
2035
- return {
2036
- x: this.parentNode.globalPoint().x + this.offset().x + this.sizeOffset().x,
2037
- y: this.parentNode.globalPoint().y + this.offset().y + this.sizeOffset().y,
2038
- };
2039
- });
2040
- this.state = signal('idle');
2041
- this.updateParentSizeAndPosition$ = new Subject();
2042
- this.parentSize = toSignal(this.updateParentSizeAndPosition$.pipe(map(() => this.getParentSize())), {
2043
- initialValue: { width: 0, height: 0 }
2044
- });
2045
- this.parentPosition = toSignal(this.updateParentSizeAndPosition$.pipe(map(() => ({
2046
- x: this.parentReference instanceof HTMLElement
2047
- ? this.parentReference.offsetLeft
2048
- : 0,
2049
- y: this.parentReference instanceof HTMLElement
2050
- ? this.parentReference.offsetTop
2051
- : 0 // for now just 0 for group nodes
2052
- }))), {
2053
- initialValue: { x: 0, y: 0 }
2054
- });
2055
- this.parentReference = this.rawHandle.parentReference;
2056
- this.template = this.rawHandle.template;
2057
- this.templateContext = {
2058
- $implicit: {
2059
- point: this.offset,
2060
- state: this.state,
2061
- node: this.parentNode.node
2062
- }
2063
- };
2064
- }
2065
- updateParent() {
2066
- this.updateParentSizeAndPosition$.next();
2082
+ this.pointerStart = output();
2083
+ this.pointerEnd = output();
2084
+ this.wasPointerOver = false;
2085
+ // TODO check if i could avoid global touch end
2086
+ this.touchEnd = this.pointerMovementDirective.touchEnd$
2087
+ .pipe(filter(({ target }) => target === this.hostElement), tap(({ originalEvent }) => this.pointerEnd.emit(originalEvent)), takeUntilDestroyed())
2088
+ .subscribe();
2089
+ this.touchOverOut = this.pointerMovementDirective.touchMovement$
2090
+ .pipe(tap(({ target, originalEvent }) => {
2091
+ this.handleTouchOverAndOut(target, originalEvent);
2092
+ }), takeUntilDestroyed())
2093
+ .subscribe();
2067
2094
  }
2068
- getParentSize() {
2069
- if (this.parentReference instanceof HTMLElement) {
2070
- return {
2071
- width: this.parentReference.offsetWidth,
2072
- height: this.parentReference.offsetHeight
2073
- };
2074
- }
2075
- else if (this.parentReference instanceof SVGGraphicsElement) {
2076
- return this.parentReference.getBBox();
2077
- }
2078
- return { width: 0, height: 0 };
2079
- }
2080
- }
2081
-
2082
- class HandleComponent {
2083
- constructor() {
2084
- this.injector = inject(Injector);
2085
- this.handleService = inject(HandleService);
2086
- this.element = inject(ElementRef).nativeElement;
2087
- this.destroyRef = inject(DestroyRef);
2088
- }
2089
- ngOnInit() {
2090
- const node = this.handleService.node();
2091
- if (node) {
2092
- this.model = new HandleModel({
2093
- position: this.position,
2094
- type: this.type,
2095
- id: this.id,
2096
- parentReference: this.element.parentElement,
2097
- template: this.template
2098
- }, node);
2099
- this.handleService.createHandle(this.model);
2100
- requestAnimationFrame(() => this.model.updateParent());
2101
- this.destroyRef.onDestroy(() => this.handleService.destroyHandle(this.model));
2102
- }
2103
- }
2104
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HandleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2105
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: HandleComponent, selector: "handle", inputs: { position: "position", type: "type", id: "id", template: "template" }, ngImport: i0, template: "", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2106
- }
2107
- __decorate([
2108
- InjectionContext
2109
- ], HandleComponent.prototype, "ngOnInit", null);
2110
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HandleComponent, decorators: [{
2111
- type: Component,
2112
- args: [{ selector: 'handle', changeDetection: ChangeDetectionStrategy.OnPush, template: "" }]
2113
- }], propDecorators: { position: [{
2114
- type: Input,
2115
- args: [{ required: true }]
2116
- }], type: [{
2117
- type: Input,
2118
- args: [{ required: true }]
2119
- }], id: [{
2120
- type: Input
2121
- }], template: [{
2122
- type: Input
2123
- }], ngOnInit: [] } });
2124
-
2125
- class PointerDirective {
2126
- constructor() {
2127
- this.hostElement = inject(ElementRef).nativeElement;
2128
- this.pointerMovementDirective = inject(RootPointerDirective);
2129
- this.pointerOver = new EventEmitter();
2130
- this.pointerOut = new EventEmitter();
2131
- this.pointerStart = new EventEmitter();
2132
- this.pointerEnd = new EventEmitter();
2133
- this.wasPointerOver = false;
2134
- // TODO check if i could avoid global touch end
2135
- this.touchEnd = this.pointerMovementDirective.touchEnd$
2136
- .pipe(filter(({ target }) => target === this.hostElement), tap(({ originalEvent }) => this.pointerEnd.emit(originalEvent)), takeUntilDestroyed())
2137
- .subscribe();
2138
- this.touchOverOut = this.pointerMovementDirective.touchMovement$
2139
- .pipe(tap(({ target, originalEvent }) => {
2140
- this.handleTouchOverAndOut(target, originalEvent);
2141
- }), takeUntilDestroyed())
2142
- .subscribe();
2143
- }
2144
- onPointerStart(event) {
2145
- this.pointerStart.emit(event);
2146
- if (event instanceof TouchEvent) {
2147
- this.pointerMovementDirective.setInitialTouch(event);
2095
+ onPointerStart(event) {
2096
+ this.pointerStart.emit(event);
2097
+ if (event instanceof TouchEvent) {
2098
+ this.pointerMovementDirective.setInitialTouch(event);
2148
2099
  }
2149
2100
  }
2150
2101
  onPointerEnd(event) {
@@ -2170,21 +2121,16 @@ class PointerDirective {
2170
2121
  this.wasPointerOver = false;
2171
2122
  }
2172
2123
  }
2173
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: PointerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2174
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: PointerDirective, selector: "[pointerStart], [pointerEnd], [pointerOver], [pointerOut]", outputs: { pointerOver: "pointerOver", pointerOut: "pointerOut", pointerStart: "pointerStart", pointerEnd: "pointerEnd" }, host: { listeners: { "mousedown": "onPointerStart($event)", "touchstart": "onPointerStart($event)", "mouseup": "onPointerEnd($event)", "mouseover": "onMouseOver($event)", "mouseout": "onMouseOut($event)" } }, ngImport: i0 }); }
2124
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PointerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2125
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: PointerDirective, isStandalone: true, selector: "[pointerStart], [pointerEnd], [pointerOver], [pointerOut]", outputs: { pointerOver: "pointerOver", pointerOut: "pointerOut", pointerStart: "pointerStart", pointerEnd: "pointerEnd" }, host: { listeners: { "mousedown": "onPointerStart($event)", "touchstart": "onPointerStart($event)", "mouseup": "onPointerEnd($event)", "mouseover": "onMouseOver($event)", "mouseout": "onMouseOut($event)" } }, ngImport: i0 }); }
2175
2126
  }
2176
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: PointerDirective, decorators: [{
2127
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PointerDirective, decorators: [{
2177
2128
  type: Directive,
2178
- args: [{ selector: '[pointerStart], [pointerEnd], [pointerOver], [pointerOut]' }]
2179
- }], propDecorators: { pointerOver: [{
2180
- type: Output
2181
- }], pointerOut: [{
2182
- type: Output
2183
- }], pointerStart: [{
2184
- type: Output
2185
- }], pointerEnd: [{
2186
- type: Output
2187
- }], onPointerStart: [{
2129
+ args: [{
2130
+ standalone: true,
2131
+ selector: '[pointerStart], [pointerEnd], [pointerOver], [pointerOut]',
2132
+ }]
2133
+ }], propDecorators: { onPointerStart: [{
2188
2134
  type: HostListener,
2189
2135
  args: ['mousedown', ['$event']]
2190
2136
  }, {
@@ -2202,14 +2148,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
2202
2148
  }] } });
2203
2149
 
2204
2150
  class ResizableComponent {
2151
+ get model() {
2152
+ return this.nodeAccessor.model();
2153
+ }
2205
2154
  constructor() {
2206
2155
  this.nodeAccessor = inject(NodeAccessorService);
2207
2156
  this.rootPointer = inject(RootPointerDirective);
2208
2157
  this.viewportService = inject(ViewportService);
2209
2158
  this.spacePointContext = inject(SpacePointContextDirective);
2210
2159
  this.hostRef = inject(ElementRef);
2211
- this.resizerColor = '#2e414c';
2212
- this.gap = 1.5;
2160
+ this.resizable = input();
2161
+ this.resizerColor = input('#2e414c');
2162
+ this.gap = input(1.5);
2163
+ this.resizer = viewChild.required('resizer');
2213
2164
  this.lineGap = 3;
2214
2165
  this.handleSize = 6;
2215
2166
  this.resizeSide = null;
@@ -2223,24 +2174,24 @@ class ResizableComponent {
2223
2174
  this.endResizeOnGlobalMouseUp = this.rootPointer.documentPointerEnd$
2224
2175
  .pipe(tap(() => this.endResize()), takeUntilDestroyed())
2225
2176
  .subscribe();
2226
- }
2227
- set resizable(value) {
2228
- if (typeof value === 'boolean') {
2229
- this.model.resizable.set(value);
2230
- }
2231
- else {
2232
- this.model.resizable.set(true);
2233
- }
2234
- }
2235
- get model() {
2236
- return this.nodeAccessor.model();
2177
+ effect(() => {
2178
+ const resizable = this.resizable();
2179
+ if (typeof resizable === 'boolean') {
2180
+ this.model.resizable.set(resizable);
2181
+ }
2182
+ else {
2183
+ this.model.resizable.set(true);
2184
+ }
2185
+ }, { allowSignalWrites: true });
2237
2186
  }
2238
2187
  ngOnInit() {
2239
- this.model.resizerTemplate.set(this.resizer);
2188
+ this.model.resizerTemplate.set(this.resizer());
2240
2189
  }
2241
2190
  ngAfterViewInit() {
2242
- this.minWidth = +getComputedStyle(this.hostRef.nativeElement).minWidth.replace('px', '') || 0;
2243
- this.minHeight = +getComputedStyle(this.hostRef.nativeElement).minHeight.replace('px', '') || 0;
2191
+ this.minWidth =
2192
+ +getComputedStyle(this.hostRef.nativeElement).minWidth.replace('px', '') || 0;
2193
+ this.minHeight =
2194
+ +getComputedStyle(this.hostRef.nativeElement).minHeight.replace('px', '') || 0;
2244
2195
  }
2245
2196
  startResize(side, event) {
2246
2197
  event.stopPropagation();
@@ -2261,13 +2212,15 @@ class ResizableComponent {
2261
2212
  this.resizeSide = null;
2262
2213
  this.model.resizing.set(false);
2263
2214
  }
2264
- isResizeConstrained({ x, y, movementX, movementY }) {
2215
+ isResizeConstrained({ x, y, movementX, movementY, }) {
2265
2216
  const flowPoint = this.spacePointContext.documentPointToFlowPoint({ x, y });
2266
2217
  if (this.resizeSide?.includes('right')) {
2267
- if (movementX > 0 && flowPoint.x < (this.model.point().x + this.model.size().width)) {
2218
+ if (movementX > 0 &&
2219
+ flowPoint.x < this.model.point().x + this.model.size().width) {
2268
2220
  return true;
2269
2221
  }
2270
- if (movementX < 0 && flowPoint.x > this.model.point().x + this.model.size().width) {
2222
+ if (movementX < 0 &&
2223
+ flowPoint.x > this.model.point().x + this.model.size().width) {
2271
2224
  return true;
2272
2225
  }
2273
2226
  }
@@ -2280,10 +2233,12 @@ class ResizableComponent {
2280
2233
  }
2281
2234
  }
2282
2235
  if (this.resizeSide?.includes('bottom')) {
2283
- if (movementY > 0 && flowPoint.y < (this.model.point().y + this.model.size().height)) {
2236
+ if (movementY > 0 &&
2237
+ flowPoint.y < this.model.point().y + this.model.size().height) {
2284
2238
  return true;
2285
2239
  }
2286
- if (movementY < 0 && flowPoint.y > this.model.point().y + this.model.size().height) {
2240
+ if (movementY < 0 &&
2241
+ flowPoint.y > this.model.point().y + this.model.size().height) {
2287
2242
  return true;
2288
2243
  }
2289
2244
  }
@@ -2297,29 +2252,20 @@ class ResizableComponent {
2297
2252
  }
2298
2253
  return false;
2299
2254
  }
2300
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ResizableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2301
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ResizableComponent, selector: "[resizable]", inputs: { resizable: "resizable", resizerColor: "resizerColor", gap: "gap" }, viewQueries: [{ propertyName: "resizer", first: true, predicate: ["resizer"], descendants: true, static: true }], ngImport: i0, template: "<ng-template #resizer>\n <svg:g>\n <!-- top line -->\n <svg:line\n class=\"top\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"-gap\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"-gap\"\n [attr.stroke]=\"resizerColor\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('top', $event)\"\n />\n <!-- Left line -->\n <svg:line\n class=\"left\"\n [attr.x1]=\"-gap\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"-gap\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('left', $event)\"\n />\n <!-- Bottom line -->\n <svg:line\n class=\"bottom\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"model.size().height + gap\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"model.size().height + gap\"\n [attr.stroke]=\"resizerColor\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('bottom', $event)\"\n />\n <!-- Right line -->\n <svg:line\n class=\"right\"\n [attr.x1]=\"model.size().width + gap\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"model.size().width + gap\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('right', $event)\"\n />\n\n <!-- Top Left -->\n <svg:rect\n class=\"top-left\"\n [attr.x]=\"-(handleSize / 2) - gap\"\n [attr.y]=\"-(handleSize / 2) - gap\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor\"\n (pointerStart)=\"startResize('top-left', $event)\"\n />\n\n <!-- Top right -->\n <svg:rect\n class=\"top-right\"\n [attr.x]=\"model.size().width - (handleSize / 2) + gap\"\n [attr.y]=\"-(handleSize / 2) - gap\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor\"\n (pointerStart)=\"startResize('top-right', $event)\"\n />\n\n <!-- Bottom left -->\n <svg:rect\n class=\"bottom-left\"\n [attr.x]=\"-(handleSize / 2) - gap\"\n [attr.y]=\"model.size().height - (handleSize / 2) + gap\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor\"\n (pointerStart)=\"startResize('bottom-left', $event)\"\n />\n\n <!-- Bottom right -->\n <svg:rect\n class=\"bottom-right\"\n [attr.x]=\"model.size().width - (handleSize / 2) + gap\"\n [attr.y]=\"model.size().height - (handleSize / 2) + gap\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor\"\n (pointerStart)=\"startResize('bottom-right', $event)\"\n />\n </svg:g>\n</ng-template>\n\n<ng-content />\n", styles: [".top{cursor:n-resize}.left{cursor:w-resize}.right{cursor:e-resize}.bottom{cursor:s-resize}.top-left{cursor:nw-resize}.top-right{cursor:ne-resize}.bottom-left{cursor:sw-resize}.bottom-right{cursor:se-resize}\n"], dependencies: [{ kind: "directive", type: PointerDirective, selector: "[pointerStart], [pointerEnd], [pointerOver], [pointerOut]", outputs: ["pointerOver", "pointerOut", "pointerStart", "pointerEnd"] }] }); }
2255
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ResizableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2256
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "17.3.12", type: ResizableComponent, isStandalone: true, selector: "[resizable]", inputs: { resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, resizerColor: { classPropertyName: "resizerColor", publicName: "resizerColor", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "resizer", first: true, predicate: ["resizer"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template #resizer>\n <svg:g>\n <!-- top line -->\n <svg:line\n class=\"top\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"-gap()\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"-gap()\"\n [attr.stroke]=\"resizerColor()\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('top', $event)\"\n />\n <!-- Left line -->\n <svg:line\n class=\"left\"\n [attr.x1]=\"-gap()\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"-gap()\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor()\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('left', $event)\"\n />\n <!-- Bottom line -->\n <svg:line\n class=\"bottom\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"model.size().height + gap()\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"model.size().height + gap()\"\n [attr.stroke]=\"resizerColor()\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('bottom', $event)\"\n />\n <!-- Right line -->\n <svg:line\n class=\"right\"\n [attr.x1]=\"model.size().width + gap()\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"model.size().width + gap()\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor()\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('right', $event)\"\n />\n\n <!-- Top Left -->\n <svg:rect\n class=\"top-left\"\n [attr.x]=\"-(handleSize / 2) - gap()\"\n [attr.y]=\"-(handleSize / 2) - gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('top-left', $event)\"\n />\n\n <!-- Top right -->\n <svg:rect\n class=\"top-right\"\n [attr.x]=\"model.size().width - handleSize / 2 + gap()\"\n [attr.y]=\"-(handleSize / 2) - gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('top-right', $event)\"\n />\n\n <!-- Bottom left -->\n <svg:rect\n class=\"bottom-left\"\n [attr.x]=\"-(handleSize / 2) - gap()\"\n [attr.y]=\"model.size().height - handleSize / 2 + gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('bottom-left', $event)\"\n />\n\n <!-- Bottom right -->\n <svg:rect\n class=\"bottom-right\"\n [attr.x]=\"model.size().width - handleSize / 2 + gap()\"\n [attr.y]=\"model.size().height - handleSize / 2 + gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('bottom-right', $event)\"\n />\n </svg:g>\n</ng-template>\n\n<ng-content />\n", styles: [".top{cursor:n-resize}.left{cursor:w-resize}.right{cursor:e-resize}.bottom{cursor:s-resize}.top-left{cursor:nw-resize}.top-right{cursor:ne-resize}.bottom-left{cursor:sw-resize}.bottom-right{cursor:se-resize}\n"], dependencies: [{ kind: "directive", type: PointerDirective, selector: "[pointerStart], [pointerEnd], [pointerOver], [pointerOut]", outputs: ["pointerOver", "pointerOut", "pointerStart", "pointerEnd"] }] }); }
2302
2257
  }
2303
2258
  __decorate([
2304
2259
  Microtask
2305
2260
  ], ResizableComponent.prototype, "ngAfterViewInit", null);
2306
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ResizableComponent, decorators: [{
2261
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ResizableComponent, decorators: [{
2307
2262
  type: Component,
2308
- args: [{ selector: '[resizable]', template: "<ng-template #resizer>\n <svg:g>\n <!-- top line -->\n <svg:line\n class=\"top\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"-gap\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"-gap\"\n [attr.stroke]=\"resizerColor\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('top', $event)\"\n />\n <!-- Left line -->\n <svg:line\n class=\"left\"\n [attr.x1]=\"-gap\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"-gap\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('left', $event)\"\n />\n <!-- Bottom line -->\n <svg:line\n class=\"bottom\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"model.size().height + gap\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"model.size().height + gap\"\n [attr.stroke]=\"resizerColor\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('bottom', $event)\"\n />\n <!-- Right line -->\n <svg:line\n class=\"right\"\n [attr.x1]=\"model.size().width + gap\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"model.size().width + gap\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('right', $event)\"\n />\n\n <!-- Top Left -->\n <svg:rect\n class=\"top-left\"\n [attr.x]=\"-(handleSize / 2) - gap\"\n [attr.y]=\"-(handleSize / 2) - gap\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor\"\n (pointerStart)=\"startResize('top-left', $event)\"\n />\n\n <!-- Top right -->\n <svg:rect\n class=\"top-right\"\n [attr.x]=\"model.size().width - (handleSize / 2) + gap\"\n [attr.y]=\"-(handleSize / 2) - gap\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor\"\n (pointerStart)=\"startResize('top-right', $event)\"\n />\n\n <!-- Bottom left -->\n <svg:rect\n class=\"bottom-left\"\n [attr.x]=\"-(handleSize / 2) - gap\"\n [attr.y]=\"model.size().height - (handleSize / 2) + gap\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor\"\n (pointerStart)=\"startResize('bottom-left', $event)\"\n />\n\n <!-- Bottom right -->\n <svg:rect\n class=\"bottom-right\"\n [attr.x]=\"model.size().width - (handleSize / 2) + gap\"\n [attr.y]=\"model.size().height - (handleSize / 2) + gap\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor\"\n (pointerStart)=\"startResize('bottom-right', $event)\"\n />\n </svg:g>\n</ng-template>\n\n<ng-content />\n", styles: [".top{cursor:n-resize}.left{cursor:w-resize}.right{cursor:e-resize}.bottom{cursor:s-resize}.top-left{cursor:nw-resize}.top-right{cursor:ne-resize}.bottom-left{cursor:sw-resize}.bottom-right{cursor:se-resize}\n"] }]
2309
- }], propDecorators: { resizable: [{
2310
- type: Input
2311
- }], resizerColor: [{
2312
- type: Input
2313
- }], gap: [{
2314
- type: Input
2315
- }], resizer: [{
2316
- type: ViewChild,
2317
- args: ['resizer', { static: true }]
2318
- }], ngAfterViewInit: [] } });
2263
+ args: [{ standalone: true, selector: '[resizable]', imports: [PointerDirective], template: "<ng-template #resizer>\n <svg:g>\n <!-- top line -->\n <svg:line\n class=\"top\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"-gap()\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"-gap()\"\n [attr.stroke]=\"resizerColor()\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('top', $event)\"\n />\n <!-- Left line -->\n <svg:line\n class=\"left\"\n [attr.x1]=\"-gap()\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"-gap()\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor()\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('left', $event)\"\n />\n <!-- Bottom line -->\n <svg:line\n class=\"bottom\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"model.size().height + gap()\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"model.size().height + gap()\"\n [attr.stroke]=\"resizerColor()\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('bottom', $event)\"\n />\n <!-- Right line -->\n <svg:line\n class=\"right\"\n [attr.x1]=\"model.size().width + gap()\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"model.size().width + gap()\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor()\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('right', $event)\"\n />\n\n <!-- Top Left -->\n <svg:rect\n class=\"top-left\"\n [attr.x]=\"-(handleSize / 2) - gap()\"\n [attr.y]=\"-(handleSize / 2) - gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('top-left', $event)\"\n />\n\n <!-- Top right -->\n <svg:rect\n class=\"top-right\"\n [attr.x]=\"model.size().width - handleSize / 2 + gap()\"\n [attr.y]=\"-(handleSize / 2) - gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('top-right', $event)\"\n />\n\n <!-- Bottom left -->\n <svg:rect\n class=\"bottom-left\"\n [attr.x]=\"-(handleSize / 2) - gap()\"\n [attr.y]=\"model.size().height - handleSize / 2 + gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('bottom-left', $event)\"\n />\n\n <!-- Bottom right -->\n <svg:rect\n class=\"bottom-right\"\n [attr.x]=\"model.size().width - handleSize / 2 + gap()\"\n [attr.y]=\"model.size().height - handleSize / 2 + gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('bottom-right', $event)\"\n />\n </svg:g>\n</ng-template>\n\n<ng-content />\n", styles: [".top{cursor:n-resize}.left{cursor:w-resize}.right{cursor:e-resize}.bottom{cursor:s-resize}.top-left{cursor:nw-resize}.top-right{cursor:ne-resize}.bottom-left{cursor:sw-resize}.bottom-right{cursor:se-resize}\n"] }]
2264
+ }], ctorParameters: () => [], propDecorators: { ngAfterViewInit: [] } });
2319
2265
  function calcOffset(movementX, movementY, zoom) {
2320
2266
  return {
2321
2267
  offsetX: round(movementX / zoom),
2322
- offsetY: round(movementY / zoom)
2268
+ offsetY: round(movementY / zoom),
2323
2269
  };
2324
2270
  }
2325
2271
  function applyResize(side, model, offset) {
@@ -2337,11 +2283,26 @@ function applyResize(side, model, offset) {
2337
2283
  case 'bottom':
2338
2284
  return { x, y, width, height: height + offsetY };
2339
2285
  case 'top-left':
2340
- return { x: x + offsetX, y: y + offsetY, width: width - offsetX, height: height - offsetY };
2286
+ return {
2287
+ x: x + offsetX,
2288
+ y: y + offsetY,
2289
+ width: width - offsetX,
2290
+ height: height - offsetY,
2291
+ };
2341
2292
  case 'top-right':
2342
- return { x, y: y + offsetY, width: width + offsetX, height: height - offsetY };
2293
+ return {
2294
+ x,
2295
+ y: y + offsetY,
2296
+ width: width + offsetX,
2297
+ height: height - offsetY,
2298
+ };
2343
2299
  case 'bottom-left':
2344
- return { x: x + offsetX, y, width: width - offsetX, height: height + offsetY };
2300
+ return {
2301
+ x: x + offsetX,
2302
+ y,
2303
+ width: width - offsetX,
2304
+ height: height + offsetY,
2305
+ };
2345
2306
  case 'bottom-right':
2346
2307
  return { x, y, width: width + offsetX, height: height + offsetY };
2347
2308
  }
@@ -2375,7 +2336,7 @@ function constrainRect(rect, model, side, minWidth, minHeight) {
2375
2336
  // 4. Apply child node constraints (if children exist)
2376
2337
  if (bounds) {
2377
2338
  if (side.includes('left')) {
2378
- x = Math.min(x, (model.point().x + model.size().width) - (bounds.x + bounds.width));
2339
+ x = Math.min(x, model.point().x + model.size().width - (bounds.x + bounds.width));
2379
2340
  width = Math.max(width, bounds.x + bounds.width);
2380
2341
  }
2381
2342
  if (side.includes('right')) {
@@ -2385,7 +2346,7 @@ function constrainRect(rect, model, side, minWidth, minHeight) {
2385
2346
  height = Math.max(height, bounds.y + bounds.height);
2386
2347
  }
2387
2348
  if (side.includes('top')) {
2388
- y = Math.min(y, (model.point().y + model.size().height) - (bounds.y + bounds.height));
2349
+ y = Math.min(y, model.point().y + model.size().height - (bounds.y + bounds.height));
2389
2350
  height = Math.max(height, bounds.y + bounds.height);
2390
2351
  }
2391
2352
  }
@@ -2393,45 +2354,144 @@ function constrainRect(rect, model, side, minWidth, minHeight) {
2393
2354
  x,
2394
2355
  y,
2395
2356
  width,
2396
- height
2357
+ height,
2397
2358
  };
2398
2359
  }
2399
2360
 
2400
- class HandleSizeControllerDirective {
2401
- constructor() {
2402
- this.handleWrapper = inject(ElementRef);
2403
- }
2404
- ngAfterViewInit() {
2405
- const element = this.handleWrapper.nativeElement;
2406
- const rect = element.getBBox();
2407
- const stroke = getChildStrokeWidth(element);
2408
- this.handleModel.size.set({
2409
- width: rect.width + stroke,
2410
- height: rect.height + stroke
2361
+ class HandleModel {
2362
+ constructor(rawHandle, parentNode) {
2363
+ this.rawHandle = rawHandle;
2364
+ this.parentNode = parentNode;
2365
+ this.strokeWidth = 2;
2366
+ /**
2367
+ * Pre-computed size for default handle, changed dynamically
2368
+ * for custom handles
2369
+ */
2370
+ this.size = signal({
2371
+ width: 10 + (2 * this.strokeWidth),
2372
+ height: 10 + (2 * this.strokeWidth)
2373
+ });
2374
+ this.offset = computed(() => {
2375
+ switch (this.rawHandle.position) {
2376
+ case 'left': return {
2377
+ x: 0,
2378
+ y: this.parentPosition().y + (this.parentSize().height / 2)
2379
+ };
2380
+ case 'right': return {
2381
+ x: this.parentNode.size().width,
2382
+ y: this.parentPosition().y + (this.parentSize().height / 2)
2383
+ };
2384
+ case 'top': return {
2385
+ x: this.parentPosition().x + (this.parentSize().width / 2),
2386
+ y: 0
2387
+ };
2388
+ case 'bottom': return {
2389
+ x: this.parentPosition().x + this.parentSize().width / 2,
2390
+ y: this.parentNode.size().height
2391
+ };
2392
+ }
2393
+ });
2394
+ this.sizeOffset = computed(() => {
2395
+ switch (this.rawHandle.position) {
2396
+ case 'left': return { x: -(this.size().width / 2), y: 0 };
2397
+ case 'right': return { x: this.size().width / 2, y: 0 };
2398
+ case 'top': return { x: 0, y: -(this.size().height / 2) };
2399
+ case 'bottom': return { x: 0, y: this.size().height / 2 };
2400
+ }
2401
+ });
2402
+ this.pointAbsolute = computed(() => {
2403
+ return {
2404
+ x: this.parentNode.globalPoint().x + this.offset().x + this.sizeOffset().x,
2405
+ y: this.parentNode.globalPoint().y + this.offset().y + this.sizeOffset().y,
2406
+ };
2407
+ });
2408
+ this.state = signal('idle');
2409
+ this.updateParentSizeAndPosition$ = new Subject();
2410
+ this.parentSize = toSignal(this.updateParentSizeAndPosition$.pipe(map(() => this.getParentSize())), {
2411
+ initialValue: { width: 0, height: 0 }
2412
+ });
2413
+ this.parentPosition = toSignal(this.updateParentSizeAndPosition$.pipe(map(() => ({
2414
+ x: this.parentReference instanceof HTMLElement
2415
+ ? this.parentReference.offsetLeft
2416
+ : 0, // for now just 0 for group nodes
2417
+ y: this.parentReference instanceof HTMLElement
2418
+ ? this.parentReference.offsetTop
2419
+ : 0 // for now just 0 for group nodes
2420
+ }))), {
2421
+ initialValue: { x: 0, y: 0 }
2411
2422
  });
2423
+ this.parentReference = this.rawHandle.parentReference;
2424
+ this.template = this.rawHandle.template;
2425
+ this.templateContext = {
2426
+ $implicit: {
2427
+ point: this.offset,
2428
+ state: this.state,
2429
+ node: this.parentNode.node
2430
+ }
2431
+ };
2432
+ }
2433
+ updateParent() {
2434
+ this.updateParentSizeAndPosition$.next();
2435
+ }
2436
+ getParentSize() {
2437
+ if (this.parentReference instanceof HTMLElement) {
2438
+ return {
2439
+ width: this.parentReference.offsetWidth,
2440
+ height: this.parentReference.offsetHeight
2441
+ };
2442
+ }
2443
+ else if (this.parentReference instanceof SVGGraphicsElement) {
2444
+ return this.parentReference.getBBox();
2445
+ }
2446
+ return { width: 0, height: 0 };
2412
2447
  }
2413
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HandleSizeControllerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2414
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: HandleSizeControllerDirective, selector: "[handleSizeController]", inputs: { handleModel: ["handleSizeController", "handleModel"] }, ngImport: i0 }); }
2415
2448
  }
2416
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HandleSizeControllerDirective, decorators: [{
2417
- type: Directive,
2418
- args: [{ selector: '[handleSizeController]' }]
2419
- }], propDecorators: { handleModel: [{
2420
- type: Input,
2421
- args: [{ required: true, alias: 'handleSizeController' }]
2422
- }] } });
2423
- function getChildStrokeWidth(element) {
2424
- const child = element.firstElementChild;
2425
- if (child) {
2426
- const stroke = getComputedStyle(child).strokeWidth;
2427
- const strokeAsNumber = Number(stroke.replace('px', ''));
2428
- if (isNaN(strokeAsNumber)) {
2429
- return 0;
2449
+
2450
+ class HandleComponent {
2451
+ constructor() {
2452
+ this.injector = inject(Injector);
2453
+ this.handleService = inject(HandleService);
2454
+ this.element = inject(ElementRef).nativeElement;
2455
+ this.destroyRef = inject(DestroyRef);
2456
+ /**
2457
+ * At what side of node this component should be placed
2458
+ */
2459
+ this.position = input.required();
2460
+ /**
2461
+ * Source or target
2462
+ */
2463
+ this.type = input.required();
2464
+ /**
2465
+ * Should be used if node has more than one source/target
2466
+ */
2467
+ this.id = input();
2468
+ this.template = input();
2469
+ }
2470
+ ngOnInit() {
2471
+ const node = this.handleService.node();
2472
+ if (node) {
2473
+ this.model = new HandleModel({
2474
+ position: this.position(),
2475
+ type: this.type(),
2476
+ id: this.id(),
2477
+ parentReference: this.element.parentElement,
2478
+ template: this.template(),
2479
+ }, node);
2480
+ this.handleService.createHandle(this.model);
2481
+ requestAnimationFrame(() => this.model.updateParent());
2482
+ this.destroyRef.onDestroy(() => this.handleService.destroyHandle(this.model));
2430
2483
  }
2431
- return strokeAsNumber;
2432
2484
  }
2433
- return 0;
2485
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2486
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "17.3.12", type: HandleComponent, isStandalone: true, selector: "handle", inputs: { position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: true, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: true, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, template: { classPropertyName: "template", publicName: "template", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2434
2487
  }
2488
+ __decorate([
2489
+ InjectionContext
2490
+ ], HandleComponent.prototype, "ngOnInit", null);
2491
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleComponent, decorators: [{
2492
+ type: Component,
2493
+ args: [{ standalone: true, selector: 'handle', changeDetection: ChangeDetectionStrategy.OnPush, template: "" }]
2494
+ }], propDecorators: { ngOnInit: [] } });
2435
2495
 
2436
2496
  class NodeComponent {
2437
2497
  constructor() {
@@ -2447,40 +2507,47 @@ class NodeComponent {
2447
2507
  this.nodeAccessor = inject(NodeAccessorService);
2448
2508
  this.overlaysService = inject(OverlaysService);
2449
2509
  this.zone = inject(NgZone);
2510
+ this.nodeModel = input.required();
2511
+ this.nodeTemplate = input();
2512
+ this.groupNodeTemplate = input();
2513
+ this.htmlWrapperRef = viewChild.required('htmlWrapper');
2450
2514
  this.showMagnet = computed(() => this.flowStatusService.status().state === 'connection-start' ||
2451
2515
  this.flowStatusService.status().state === 'connection-validation');
2452
- this.styleWidth = computed(() => `${this.nodeModel.size().width}px`);
2453
- this.styleHeight = computed(() => `${this.nodeModel.size().height}px`);
2454
- this.toolbar = computed(() => this.overlaysService.nodeToolbars().get(this.nodeModel));
2516
+ this.styleWidth = computed(() => `${this.nodeModel().size().width}px`);
2517
+ this.styleHeight = computed(() => `${this.nodeModel().size().height}px`);
2518
+ this.toolbar = computed(() => this.overlaysService.nodeToolbars().get(this.nodeModel()));
2455
2519
  }
2456
2520
  ngOnInit() {
2457
- this.nodeAccessor.model.set(this.nodeModel);
2458
- this.handleService.node.set(this.nodeModel);
2521
+ this.nodeAccessor.model.set(this.nodeModel());
2522
+ this.handleService.node.set(this.nodeModel());
2459
2523
  effect(() => {
2460
- if (this.nodeModel.draggable()) {
2461
- this.draggableService.enable(this.hostRef.nativeElement, this.nodeModel);
2524
+ if (this.nodeModel().draggable()) {
2525
+ this.draggableService.enable(this.hostRef.nativeElement, this.nodeModel());
2462
2526
  }
2463
2527
  else {
2464
2528
  this.draggableService.disable(this.hostRef.nativeElement);
2465
2529
  }
2466
2530
  });
2467
- this.nodeModel.handles$
2468
- .pipe(switchMap((handles) => resizable(handles.map(h => h.parentReference), this.zone)
2469
- .pipe(map(() => handles))), tap((handles) => {
2531
+ this.nodeModel()
2532
+ .handles$.pipe(switchMap((handles) => resizable(handles.map((h) => h.parentReference), this.zone).pipe(map(() => handles))), tap((handles) => {
2470
2533
  // TODO (performance) inspect how to avoid calls of this when flow initially rendered
2471
- handles.forEach(h => h.updateParent());
2534
+ handles.forEach((h) => h.updateParent());
2472
2535
  }), takeUntilDestroyed())
2473
2536
  .subscribe();
2474
2537
  }
2475
2538
  ngAfterViewInit() {
2476
- this.nodeModel.linkDefaultNodeSizeWithModelSize();
2477
- if (this.nodeModel.node.type === 'html-template' || this.nodeModel.isComponentType) {
2478
- resizable([this.htmlWrapperRef.nativeElement], this.zone)
2479
- .pipe(startWith(null), tap(() => this.nodeModel.handles().forEach(h => h.updateParent())), filter(() => !this.nodeModel.resizing()), tap(() => {
2480
- const width = this.htmlWrapperRef.nativeElement.clientWidth;
2481
- const height = this.htmlWrapperRef.nativeElement.clientHeight;
2482
- this.nodeModel.size.set({ width, height });
2483
- }), takeUntilDestroyed()).subscribe();
2539
+ this.nodeModel().linkDefaultNodeSizeWithModelSize();
2540
+ if (this.nodeModel().node.type === 'html-template' ||
2541
+ this.nodeModel().isComponentType) {
2542
+ resizable([this.htmlWrapperRef().nativeElement], this.zone)
2543
+ .pipe(startWith(null), tap(() => this.nodeModel()
2544
+ .handles()
2545
+ .forEach((h) => h.updateParent())), filter(() => !this.nodeModel().resizing()), tap(() => {
2546
+ const width = this.htmlWrapperRef().nativeElement.clientWidth;
2547
+ const height = this.htmlWrapperRef().nativeElement.clientHeight;
2548
+ this.nodeModel().size.set({ width, height });
2549
+ }), takeUntilDestroyed())
2550
+ .subscribe();
2484
2551
  }
2485
2552
  }
2486
2553
  ngOnDestroy() {
@@ -2501,15 +2568,15 @@ class NodeComponent {
2501
2568
  this.connectionController.endConnection(handle);
2502
2569
  }
2503
2570
  pullNode() {
2504
- this.nodeRenderingService.pullNode(this.nodeModel);
2571
+ this.nodeRenderingService.pullNode(this.nodeModel());
2505
2572
  }
2506
2573
  selectNode() {
2507
2574
  if (this.flowSettingsService.entitiesSelectable()) {
2508
- this.selectionService.select(this.nodeModel);
2575
+ this.selectionService.select(this.nodeModel());
2509
2576
  }
2510
2577
  }
2511
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2512
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NodeComponent, selector: "g[node]", inputs: { nodeModel: "nodeModel", nodeTemplate: "nodeTemplate", groupNodeTemplate: "groupNodeTemplate" }, host: { classAttribute: "vflow-node" }, providers: [HandleService, NodeAccessorService], viewQueries: [{ propertyName: "nodeContentRef", first: true, predicate: ["nodeContent"], descendants: true }, { propertyName: "htmlWrapperRef", first: true, predicate: ["htmlWrapper"], descendants: true }], ngImport: i0, template: "<!-- Default node -->\n<svg:foreignObject\n *ngIf=\"nodeModel.node.type === 'default'\"\n class=\"selectable\"\n #nodeContent\n [attr.width]=\"nodeModel.size().width\"\n [attr.height]=\"nodeModel.size().height\"\n (pointerStart)=\"pullNode(); selectNode()\"\n>\n <default-node\n #htmlWrapper\n [selected]=\"nodeModel.selected()\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n [style.max-width]=\"styleWidth()\"\n [style.max-height]=\"styleHeight()\"\n >\n <div [outerHTML]=\"nodeModel.text()\"></div>\n\n <handle type=\"source\" [position]=\"nodeModel.sourcePosition()\" />\n <handle type=\"target\" [position]=\"nodeModel.targetPosition()\" />\n </default-node>\n</svg:foreignObject>\n\n<!-- Template node -->\n<svg:foreignObject\n *ngIf=\"nodeModel.node.type === 'html-template' && nodeTemplate\"\n class=\"selectable\"\n [attr.width]=\"nodeModel.size().width\"\n [attr.height]=\"nodeModel.size().height\"\n (pointerStart)=\"pullNode()\"\n>\n <div\n #htmlWrapper\n class=\"wrapper\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n >\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: { node: nodeModel.node, selected: nodeModel.selected } }\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n </div>\n</svg:foreignObject>\n\n<!-- Component node -->\n<svg:foreignObject\n *ngIf=\"nodeModel.isComponentType\"\n class=\"selectable\"\n [attr.width]=\"nodeModel.size().width\"\n [attr.height]=\"nodeModel.size().height\"\n (pointerStart)=\"pullNode()\"\n>\n <div\n #htmlWrapper\n class=\"wrapper\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n >\n <ng-container\n [ngComponentOutlet]=\"$any(nodeModel.node.type)\"\n [ngComponentOutletInputs]=\"nodeModel.componentTypeInputs()\"\n [ngComponentOutletInjector]=\"injector\"\n />\n </div>\n</svg:foreignObject>\n\n<!-- Default group node -->\n<svg:rect\n *ngIf=\"nodeModel.node.type === 'default-group'\"\n [resizable]=\"nodeModel.resizable()\"\n [gap]=\"3\"\n [resizerColor]=\"nodeModel.color()\"\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [class.default-group-node_selected]=\"nodeModel.selected()\"\n [attr.width]=\"nodeModel.size().width\"\n [attr.height]=\"nodeModel.size().height\"\n [style.stroke]=\"nodeModel.color()\"\n [style.fill]=\"nodeModel.color()\"\n (pointerStart)=\"pullNode(); selectNode()\"\n/>\n\n<!-- Template group node -->\n<svg:g\n *ngIf=\"nodeModel.node.type === 'template-group' && groupNodeTemplate\"\n class=\"selectable\"\n (pointerStart)=\"pullNode()\"\n>\n <ng-container\n [ngTemplateOutlet]=\"groupNodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: { node: nodeModel.node, selected: nodeModel.selected, width: nodeModel.width, height: nodeModel.height } }\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n</svg:g>\n\n<!-- Resizer -->\n<ng-container *ngIf=\"nodeModel.resizerTemplate() as template\">\n <ng-container *ngIf=\"nodeModel.resizable()\">\n <ng-template [ngTemplateOutlet]=\"template\" />\n </ng-container>\n</ng-container>\n\n<!-- Handles -->\n<ng-container *ngFor=\"let handle of nodeModel.handles()\">\n <svg:circle\n *ngIf=\"!handle.template\"\n class=\"default-handle\"\n [attr.cx]=\"handle.offset().x\"\n [attr.cy]=\"handle.offset().y\"\n [attr.stroke-width]=\"handle.strokeWidth\"\n r=\"5\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection(handle)\"\n />\n\n <svg:g\n *ngIf=\"handle.template\"\n [handleSizeController]=\"handle\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection(handle)\"\n >\n <ng-container *ngTemplateOutlet=\"handle.template; context: handle.templateContext\" />\n </svg:g>\n\n <svg:circle\n *ngIf=\"showMagnet()\"\n class=\"magnet\"\n [attr.r]=\"nodeModel.magnetRadius\"\n [attr.cx]=\"handle.offset().x\"\n [attr.cy]=\"handle.offset().y\"\n (pointerEnd)=\"endConnection(handle); resetValidateConnection(handle)\"\n (pointerOver)=\"validateConnection(handle)\"\n (pointerOut)=\"resetValidateConnection(handle)\"\n />\n</ng-container>\n\n<!-- Toolbar -->\n<svg:foreignObject\n *ngIf=\"toolbar() as toolbar\"\n [attr.width]=\"toolbar.size().width\"\n [attr.height]=\"toolbar.size().height\"\n [attr.transform]=\"toolbar.transform()\"\n>\n <ng-container [ngTemplateOutlet]=\"toolbar.template()\" />\n</svg:foreignObject>\n", styles: [".magnet{opacity:0}.wrapper{display:table-cell}.default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}.default-handle{stroke:#fff;fill:#1b262c}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "component", type: DefaultNodeComponent, selector: "default-node", inputs: ["selected"] }, { kind: "component", type: HandleComponent, selector: "handle", inputs: ["position", "type", "id", "template"] }, { kind: "component", type: ResizableComponent, selector: "[resizable]", inputs: ["resizable", "resizerColor", "gap"] }, { kind: "directive", type: HandleSizeControllerDirective, selector: "[handleSizeController]", inputs: ["handleSizeController"] }, { kind: "directive", type: PointerDirective, selector: "[pointerStart], [pointerEnd], [pointerOver], [pointerOut]", outputs: ["pointerOver", "pointerOut", "pointerStart", "pointerEnd"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2578
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2579
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: NodeComponent, isStandalone: true, selector: "g[node]", inputs: { nodeModel: { classPropertyName: "nodeModel", publicName: "nodeModel", isSignal: true, isRequired: true, transformFunction: null }, nodeTemplate: { classPropertyName: "nodeTemplate", publicName: "nodeTemplate", isSignal: true, isRequired: false, transformFunction: null }, groupNodeTemplate: { classPropertyName: "groupNodeTemplate", publicName: "groupNodeTemplate", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "vflow-node" }, providers: [HandleService, NodeAccessorService], viewQueries: [{ propertyName: "htmlWrapperRef", first: true, predicate: ["htmlWrapper"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Default node -->\n@if (nodeModel().node.type === \"default\") {\n @defer {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n (pointerStart)=\"pullNode(); selectNode()\"\n >\n <default-node\n #htmlWrapper\n [selected]=\"nodeModel().selected()\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n [style.max-width]=\"styleWidth()\"\n [style.max-height]=\"styleHeight()\"\n >\n <div [outerHTML]=\"nodeModel().text()\"></div>\n\n <handle type=\"source\" position=\"right\"/>\n <handle type=\"target\" position=\"left\" />\n </default-node>\n </svg:foreignObject>\n }\n}\n\n<!-- Template node -->\n@if (nodeModel().node.type === \"html-template\" && nodeTemplate()) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n (pointerStart)=\"pullNode()\"\n >\n <div\n #htmlWrapper\n class=\"wrapper\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n >\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"{\n $implicit: { node: nodeModel().node, selected: nodeModel().selected },\n }\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n </div>\n </svg:foreignObject>\n}\n\n<!-- Component node -->\n@if (nodeModel().isComponentType) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n (pointerStart)=\"pullNode()\"\n >\n <div\n #htmlWrapper\n class=\"wrapper\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n >\n <ng-container\n [ngComponentOutlet]=\"$any(nodeModel().node.type)\"\n [ngComponentOutletInputs]=\"nodeModel().componentTypeInputs\"\n [ngComponentOutletInjector]=\"injector\"\n />\n </div>\n </svg:foreignObject>\n}\n\n<!-- Default group node -->\n@if (nodeModel().node.type === \"default-group\") {\n @defer {\n <svg:rect\n [resizable]=\"nodeModel().resizable()\"\n [gap]=\"3\"\n [resizerColor]=\"nodeModel().color()\"\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [class.default-group-node_selected]=\"nodeModel().selected()\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n [style.stroke]=\"nodeModel().color()\"\n [style.fill]=\"nodeModel().color()\"\n (pointerStart)=\"pullNode(); selectNode()\"\n />\n }\n}\n\n<!-- Template group node -->\n@if (nodeModel().node.type === \"template-group\" && groupNodeTemplate()) {\n <svg:g class=\"selectable\" (pointerStart)=\"pullNode()\">\n <ng-container\n [ngTemplateOutlet]=\"groupNodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"{\n $implicit: {\n node: nodeModel().node,\n selected: nodeModel().selected,\n width: nodeModel().width,\n height: nodeModel().height,\n },\n }\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n </svg:g>\n}\n\n<!-- Resizer -->\n@if (nodeModel().resizerTemplate(); as template) {\n @if (nodeModel().resizable()) {\n <ng-template [ngTemplateOutlet]=\"template\" />\n }\n}\n\n<!-- Handles -->\n@for (handle of nodeModel().handles(); track handle) {\n @if (!handle.template) {\n <svg:circle\n class=\"default-handle\"\n [attr.cx]=\"handle.offset().x\"\n [attr.cy]=\"handle.offset().y\"\n [attr.stroke-width]=\"handle.strokeWidth\"\n r=\"5\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection(handle)\"\n />\n }\n\n @if (handle.template) {\n <svg:g\n [handleSizeController]=\"handle\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection(handle)\"\n >\n <ng-container\n *ngTemplateOutlet=\"handle.template; context: handle.templateContext\"\n />\n </svg:g>\n }\n\n @if (showMagnet()) {\n <svg:circle\n class=\"magnet\"\n [attr.r]=\"nodeModel().magnetRadius\"\n [attr.cx]=\"handle.offset().x\"\n [attr.cy]=\"handle.offset().y\"\n (pointerEnd)=\"endConnection(handle); resetValidateConnection(handle)\"\n (pointerOver)=\"validateConnection(handle)\"\n (pointerOut)=\"resetValidateConnection(handle)\"\n />\n }\n}\n\n<!-- Toolbar -->\n@if (toolbar(); as toolbar) {\n <svg:foreignObject\n [attr.width]=\"toolbar.size().width\"\n [attr.height]=\"toolbar.size().height\"\n [attr.transform]=\"toolbar.transform()\"\n >\n <ng-container [ngTemplateOutlet]=\"toolbar.template()\" />\n </svg:foreignObject>\n}\n", styles: [".magnet{opacity:0}.wrapper{display:table-cell}.default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}.default-handle{stroke:#fff;fill:#1b262c}\n"], dependencies: [{ kind: "directive", type: PointerDirective, selector: "[pointerStart], [pointerEnd], [pointerOver], [pointerOut]", outputs: ["pointerOver", "pointerOut", "pointerStart", "pointerEnd"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "directive", type: HandleSizeControllerDirective, selector: "[handleSizeController]", inputs: ["handleSizeController"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2513
2580
  }
2514
2581
  __decorate([
2515
2582
  InjectionContext
@@ -2517,130 +2584,25 @@ __decorate([
2517
2584
  __decorate([
2518
2585
  InjectionContext
2519
2586
  ], NodeComponent.prototype, "ngAfterViewInit", null);
2520
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeComponent, decorators: [{
2587
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeComponent, decorators: [{
2521
2588
  type: Component,
2522
- args: [{ selector: 'g[node]', changeDetection: ChangeDetectionStrategy.OnPush, providers: [HandleService, NodeAccessorService], host: {
2523
- 'class': 'vflow-node',
2524
- }, template: "<!-- Default node -->\n<svg:foreignObject\n *ngIf=\"nodeModel.node.type === 'default'\"\n class=\"selectable\"\n #nodeContent\n [attr.width]=\"nodeModel.size().width\"\n [attr.height]=\"nodeModel.size().height\"\n (pointerStart)=\"pullNode(); selectNode()\"\n>\n <default-node\n #htmlWrapper\n [selected]=\"nodeModel.selected()\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n [style.max-width]=\"styleWidth()\"\n [style.max-height]=\"styleHeight()\"\n >\n <div [outerHTML]=\"nodeModel.text()\"></div>\n\n <handle type=\"source\" [position]=\"nodeModel.sourcePosition()\" />\n <handle type=\"target\" [position]=\"nodeModel.targetPosition()\" />\n </default-node>\n</svg:foreignObject>\n\n<!-- Template node -->\n<svg:foreignObject\n *ngIf=\"nodeModel.node.type === 'html-template' && nodeTemplate\"\n class=\"selectable\"\n [attr.width]=\"nodeModel.size().width\"\n [attr.height]=\"nodeModel.size().height\"\n (pointerStart)=\"pullNode()\"\n>\n <div\n #htmlWrapper\n class=\"wrapper\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n >\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: { node: nodeModel.node, selected: nodeModel.selected } }\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n </div>\n</svg:foreignObject>\n\n<!-- Component node -->\n<svg:foreignObject\n *ngIf=\"nodeModel.isComponentType\"\n class=\"selectable\"\n [attr.width]=\"nodeModel.size().width\"\n [attr.height]=\"nodeModel.size().height\"\n (pointerStart)=\"pullNode()\"\n>\n <div\n #htmlWrapper\n class=\"wrapper\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n >\n <ng-container\n [ngComponentOutlet]=\"$any(nodeModel.node.type)\"\n [ngComponentOutletInputs]=\"nodeModel.componentTypeInputs()\"\n [ngComponentOutletInjector]=\"injector\"\n />\n </div>\n</svg:foreignObject>\n\n<!-- Default group node -->\n<svg:rect\n *ngIf=\"nodeModel.node.type === 'default-group'\"\n [resizable]=\"nodeModel.resizable()\"\n [gap]=\"3\"\n [resizerColor]=\"nodeModel.color()\"\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [class.default-group-node_selected]=\"nodeModel.selected()\"\n [attr.width]=\"nodeModel.size().width\"\n [attr.height]=\"nodeModel.size().height\"\n [style.stroke]=\"nodeModel.color()\"\n [style.fill]=\"nodeModel.color()\"\n (pointerStart)=\"pullNode(); selectNode()\"\n/>\n\n<!-- Template group node -->\n<svg:g\n *ngIf=\"nodeModel.node.type === 'template-group' && groupNodeTemplate\"\n class=\"selectable\"\n (pointerStart)=\"pullNode()\"\n>\n <ng-container\n [ngTemplateOutlet]=\"groupNodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: { node: nodeModel.node, selected: nodeModel.selected, width: nodeModel.width, height: nodeModel.height } }\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n</svg:g>\n\n<!-- Resizer -->\n<ng-container *ngIf=\"nodeModel.resizerTemplate() as template\">\n <ng-container *ngIf=\"nodeModel.resizable()\">\n <ng-template [ngTemplateOutlet]=\"template\" />\n </ng-container>\n</ng-container>\n\n<!-- Handles -->\n<ng-container *ngFor=\"let handle of nodeModel.handles()\">\n <svg:circle\n *ngIf=\"!handle.template\"\n class=\"default-handle\"\n [attr.cx]=\"handle.offset().x\"\n [attr.cy]=\"handle.offset().y\"\n [attr.stroke-width]=\"handle.strokeWidth\"\n r=\"5\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection(handle)\"\n />\n\n <svg:g\n *ngIf=\"handle.template\"\n [handleSizeController]=\"handle\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection(handle)\"\n >\n <ng-container *ngTemplateOutlet=\"handle.template; context: handle.templateContext\" />\n </svg:g>\n\n <svg:circle\n *ngIf=\"showMagnet()\"\n class=\"magnet\"\n [attr.r]=\"nodeModel.magnetRadius\"\n [attr.cx]=\"handle.offset().x\"\n [attr.cy]=\"handle.offset().y\"\n (pointerEnd)=\"endConnection(handle); resetValidateConnection(handle)\"\n (pointerOver)=\"validateConnection(handle)\"\n (pointerOut)=\"resetValidateConnection(handle)\"\n />\n</ng-container>\n\n<!-- Toolbar -->\n<svg:foreignObject\n *ngIf=\"toolbar() as toolbar\"\n [attr.width]=\"toolbar.size().width\"\n [attr.height]=\"toolbar.size().height\"\n [attr.transform]=\"toolbar.transform()\"\n>\n <ng-container [ngTemplateOutlet]=\"toolbar.template()\" />\n</svg:foreignObject>\n", styles: [".magnet{opacity:0}.wrapper{display:table-cell}.default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}.default-handle{stroke:#fff;fill:#1b262c}\n"] }]
2525
- }], propDecorators: { nodeModel: [{
2526
- type: Input
2527
- }], nodeTemplate: [{
2528
- type: Input
2529
- }], groupNodeTemplate: [{
2530
- type: Input
2531
- }], nodeContentRef: [{
2532
- type: ViewChild,
2533
- args: ['nodeContent']
2534
- }], htmlWrapperRef: [{
2535
- type: ViewChild,
2536
- args: ['htmlWrapper']
2537
- }], ngOnInit: [], ngAfterViewInit: [] } });
2538
-
2539
- class EdgeLabelComponent {
2540
- constructor() {
2541
- /**
2542
- * Centered point of label
2543
- *
2544
- * TODO: maybe put it into EdgeLabelModel
2545
- */
2546
- this.edgeLabelPoint = computed(() => {
2547
- const point = this.pointSignal();
2548
- const { width, height } = this.model.size();
2549
- return {
2550
- x: point.x - (width / 2),
2551
- y: point.y - (height / 2)
2552
- };
2553
- });
2554
- this.pointSignal = signal({ x: 0, y: 0 });
2555
- }
2556
- set point(point) { this.pointSignal.set(point); }
2557
- ngAfterViewInit() {
2558
- // this is a fix for visual artifact in chrome that for some reason adresses only for edge label.
2559
- // the bug reproduces if edgeLabelWrapperRef size fully matched the size of parent foreignObject
2560
- const MAGIC_VALUE_TO_FIX_GLITCH_IN_CHROME = 2;
2561
- const width = this.edgeLabelWrapperRef.nativeElement.clientWidth + MAGIC_VALUE_TO_FIX_GLITCH_IN_CHROME;
2562
- const height = this.edgeLabelWrapperRef.nativeElement.clientHeight + MAGIC_VALUE_TO_FIX_GLITCH_IN_CHROME;
2563
- this.model.size.set({ width, height });
2564
- }
2565
- getLabelContext() {
2566
- return {
2567
- $implicit: {
2568
- edge: this.edgeModel.edge,
2569
- label: this.model.edgeLabel
2570
- }
2571
- };
2572
- }
2573
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EdgeLabelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2574
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: EdgeLabelComponent, selector: "g[edgeLabel]", inputs: { model: "model", edgeModel: "edgeModel", point: "point", htmlTemplate: "htmlTemplate" }, viewQueries: [{ propertyName: "edgeLabelWrapperRef", first: true, predicate: ["edgeLabelWrapper"], descendants: true }], ngImport: i0, template: "<svg:foreignObject\n [attr.x]=\"edgeLabelPoint().x\"\n [attr.y]=\"edgeLabelPoint().y\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\"\n *ngIf=\"model.edgeLabel.type === 'html-template' && htmlTemplate\"\n>\n <div #edgeLabelWrapper class=\"edge-label-wrapper\">\n <ng-container\n *ngTemplateOutlet=\"htmlTemplate; context: getLabelContext()\"\n />\n </div>\n</svg:foreignObject>\n", styles: [".edge-label-wrapper{width:max-content;margin-top:1px;margin-left:1px}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2575
- }
2576
- __decorate([
2577
- Microtask
2578
- ], EdgeLabelComponent.prototype, "ngAfterViewInit", null);
2579
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EdgeLabelComponent, decorators: [{
2580
- type: Component,
2581
- args: [{ selector: 'g[edgeLabel]', changeDetection: ChangeDetectionStrategy.OnPush, template: "<svg:foreignObject\n [attr.x]=\"edgeLabelPoint().x\"\n [attr.y]=\"edgeLabelPoint().y\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\"\n *ngIf=\"model.edgeLabel.type === 'html-template' && htmlTemplate\"\n>\n <div #edgeLabelWrapper class=\"edge-label-wrapper\">\n <ng-container\n *ngTemplateOutlet=\"htmlTemplate; context: getLabelContext()\"\n />\n </div>\n</svg:foreignObject>\n", styles: [".edge-label-wrapper{width:max-content;margin-top:1px;margin-left:1px}\n"] }]
2582
- }], propDecorators: { model: [{
2583
- type: Input
2584
- }], edgeModel: [{
2585
- type: Input
2586
- }], point: [{
2587
- type: Input
2588
- }], htmlTemplate: [{
2589
- type: Input
2590
- }], edgeLabelWrapperRef: [{
2591
- type: ViewChild,
2592
- args: ['edgeLabelWrapper']
2593
- }], ngAfterViewInit: [] } });
2594
-
2595
- class EdgeComponent {
2596
- constructor() {
2597
- this.injector = inject(Injector);
2598
- this.selectionService = inject(SelectionService);
2599
- this.flowSettingsService = inject(FlowSettingsService);
2600
- this.markerStartUrl = computed(() => {
2601
- const marker = this.model.edge.markers?.start;
2602
- return marker ? `url(#${hashCode(JSON.stringify(marker))})` : '';
2603
- });
2604
- this.markerEndUrl = computed(() => {
2605
- const marker = this.model.edge.markers?.end;
2606
- return marker ? `url(#${hashCode(JSON.stringify(marker))})` : '';
2607
- });
2608
- }
2609
- ngOnInit() {
2610
- this.edgeContext = {
2611
- $implicit: {
2612
- // TODO: check if edge could change
2613
- edge: this.model.edge,
2614
- path: computed(() => this.model.path().path),
2615
- markerStart: this.markerStartUrl,
2616
- markerEnd: this.markerEndUrl,
2617
- selected: this.model.selected.asReadonly()
2618
- }
2619
- };
2620
- }
2621
- onEdgeMouseDown() {
2622
- if (this.flowSettingsService.entitiesSelectable()) {
2623
- this.selectionService.select(this.model);
2624
- }
2625
- }
2626
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EdgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2627
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: EdgeComponent, selector: "g[edge]", inputs: { model: "model", edgeTemplate: "edgeTemplate", edgeLabelHtmlTemplate: "edgeLabelHtmlTemplate" }, host: { classAttribute: "selectable" }, ngImport: i0, template: "<svg:path\n *ngIf=\"model.type === 'default'\"\n (mousedown)=\"onEdgeMouseDown()\"\n [attr.d]=\"model.path().path\"\n [attr.marker-start]=\"markerStartUrl()\"\n [attr.marker-end]=\"markerEndUrl()\"\n class=\"edge\"\n [class.edge_selected]=\"model.selected()\"\n/>\n\n<ng-container *ngIf=\"model.type === 'template' && edgeTemplate\">\n <ng-container\n [ngTemplateOutlet]=\"edgeTemplate\"\n [ngTemplateOutletContext]=\"edgeContext\"\n [ngTemplateOutletInjector]=\"injector\"\n ></ng-container>\n</ng-container>\n\n<ng-container *ngIf=\"model.edgeLabels?.start as label\">\n <svg:g edgeLabel\n [model]=\"label\"\n [point]=\"model.path().points.start\"\n [edgeModel]=\"model\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate\"\n />\n</ng-container>\n\n<ng-container *ngIf=\"model.edgeLabels?.center as label\">\n <svg:g edgeLabel\n [model]=\"label\"\n [point]=\"model.path().points.center\"\n [edgeModel]=\"model\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate\"\n />\n</ng-container>\n\n<ng-container *ngIf=\"model.edgeLabels?.end as label\">\n <svg:g edgeLabel\n [model]=\"label\"\n [point]=\"model.path().points.end\"\n [edgeModel]=\"model\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate\"\n />\n</ng-container>\n", styles: [".edge{fill:none;stroke-width:2;stroke:#b1b1b7}.edge_selected{stroke-width:2.5;stroke:#0f4c75}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: EdgeLabelComponent, selector: "g[edgeLabel]", inputs: ["model", "edgeModel", "point", "htmlTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2628
- }
2629
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EdgeComponent, decorators: [{
2630
- type: Component,
2631
- args: [{ selector: 'g[edge]', changeDetection: ChangeDetectionStrategy.OnPush, host: {
2632
- 'class': 'selectable'
2633
- }, template: "<svg:path\n *ngIf=\"model.type === 'default'\"\n (mousedown)=\"onEdgeMouseDown()\"\n [attr.d]=\"model.path().path\"\n [attr.marker-start]=\"markerStartUrl()\"\n [attr.marker-end]=\"markerEndUrl()\"\n class=\"edge\"\n [class.edge_selected]=\"model.selected()\"\n/>\n\n<ng-container *ngIf=\"model.type === 'template' && edgeTemplate\">\n <ng-container\n [ngTemplateOutlet]=\"edgeTemplate\"\n [ngTemplateOutletContext]=\"edgeContext\"\n [ngTemplateOutletInjector]=\"injector\"\n ></ng-container>\n</ng-container>\n\n<ng-container *ngIf=\"model.edgeLabels?.start as label\">\n <svg:g edgeLabel\n [model]=\"label\"\n [point]=\"model.path().points.start\"\n [edgeModel]=\"model\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate\"\n />\n</ng-container>\n\n<ng-container *ngIf=\"model.edgeLabels?.center as label\">\n <svg:g edgeLabel\n [model]=\"label\"\n [point]=\"model.path().points.center\"\n [edgeModel]=\"model\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate\"\n />\n</ng-container>\n\n<ng-container *ngIf=\"model.edgeLabels?.end as label\">\n <svg:g edgeLabel\n [model]=\"label\"\n [point]=\"model.path().points.end\"\n [edgeModel]=\"model\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate\"\n />\n</ng-container>\n", styles: [".edge{fill:none;stroke-width:2;stroke:#b1b1b7}.edge_selected{stroke-width:2.5;stroke:#0f4c75}\n"] }]
2634
- }], propDecorators: { model: [{
2635
- type: Input
2636
- }], edgeTemplate: [{
2637
- type: Input
2638
- }], edgeLabelHtmlTemplate: [{
2639
- type: Input
2640
- }] } });
2589
+ args: [{ standalone: true, selector: 'g[node]', changeDetection: ChangeDetectionStrategy.OnPush, providers: [HandleService, NodeAccessorService], host: {
2590
+ class: 'vflow-node',
2591
+ }, imports: [
2592
+ PointerDirective,
2593
+ DefaultNodeComponent,
2594
+ HandleComponent,
2595
+ NgTemplateOutlet,
2596
+ NgComponentOutlet,
2597
+ ResizableComponent,
2598
+ HandleSizeControllerDirective,
2599
+ ], template: "<!-- Default node -->\n@if (nodeModel().node.type === \"default\") {\n @defer {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n (pointerStart)=\"pullNode(); selectNode()\"\n >\n <default-node\n #htmlWrapper\n [selected]=\"nodeModel().selected()\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n [style.max-width]=\"styleWidth()\"\n [style.max-height]=\"styleHeight()\"\n >\n <div [outerHTML]=\"nodeModel().text()\"></div>\n\n <handle type=\"source\" position=\"right\"/>\n <handle type=\"target\" position=\"left\" />\n </default-node>\n </svg:foreignObject>\n }\n}\n\n<!-- Template node -->\n@if (nodeModel().node.type === \"html-template\" && nodeTemplate()) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n (pointerStart)=\"pullNode()\"\n >\n <div\n #htmlWrapper\n class=\"wrapper\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n >\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"{\n $implicit: { node: nodeModel().node, selected: nodeModel().selected },\n }\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n </div>\n </svg:foreignObject>\n}\n\n<!-- Component node -->\n@if (nodeModel().isComponentType) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n (pointerStart)=\"pullNode()\"\n >\n <div\n #htmlWrapper\n class=\"wrapper\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n >\n <ng-container\n [ngComponentOutlet]=\"$any(nodeModel().node.type)\"\n [ngComponentOutletInputs]=\"nodeModel().componentTypeInputs\"\n [ngComponentOutletInjector]=\"injector\"\n />\n </div>\n </svg:foreignObject>\n}\n\n<!-- Default group node -->\n@if (nodeModel().node.type === \"default-group\") {\n @defer {\n <svg:rect\n [resizable]=\"nodeModel().resizable()\"\n [gap]=\"3\"\n [resizerColor]=\"nodeModel().color()\"\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [class.default-group-node_selected]=\"nodeModel().selected()\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n [style.stroke]=\"nodeModel().color()\"\n [style.fill]=\"nodeModel().color()\"\n (pointerStart)=\"pullNode(); selectNode()\"\n />\n }\n}\n\n<!-- Template group node -->\n@if (nodeModel().node.type === \"template-group\" && groupNodeTemplate()) {\n <svg:g class=\"selectable\" (pointerStart)=\"pullNode()\">\n <ng-container\n [ngTemplateOutlet]=\"groupNodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"{\n $implicit: {\n node: nodeModel().node,\n selected: nodeModel().selected,\n width: nodeModel().width,\n height: nodeModel().height,\n },\n }\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n </svg:g>\n}\n\n<!-- Resizer -->\n@if (nodeModel().resizerTemplate(); as template) {\n @if (nodeModel().resizable()) {\n <ng-template [ngTemplateOutlet]=\"template\" />\n }\n}\n\n<!-- Handles -->\n@for (handle of nodeModel().handles(); track handle) {\n @if (!handle.template) {\n <svg:circle\n class=\"default-handle\"\n [attr.cx]=\"handle.offset().x\"\n [attr.cy]=\"handle.offset().y\"\n [attr.stroke-width]=\"handle.strokeWidth\"\n r=\"5\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection(handle)\"\n />\n }\n\n @if (handle.template) {\n <svg:g\n [handleSizeController]=\"handle\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection(handle)\"\n >\n <ng-container\n *ngTemplateOutlet=\"handle.template; context: handle.templateContext\"\n />\n </svg:g>\n }\n\n @if (showMagnet()) {\n <svg:circle\n class=\"magnet\"\n [attr.r]=\"nodeModel().magnetRadius\"\n [attr.cx]=\"handle.offset().x\"\n [attr.cy]=\"handle.offset().y\"\n (pointerEnd)=\"endConnection(handle); resetValidateConnection(handle)\"\n (pointerOver)=\"validateConnection(handle)\"\n (pointerOut)=\"resetValidateConnection(handle)\"\n />\n }\n}\n\n<!-- Toolbar -->\n@if (toolbar(); as toolbar) {\n <svg:foreignObject\n [attr.width]=\"toolbar.size().width\"\n [attr.height]=\"toolbar.size().height\"\n [attr.transform]=\"toolbar.transform()\"\n >\n <ng-container [ngTemplateOutlet]=\"toolbar.template()\" />\n </svg:foreignObject>\n}\n", styles: [".magnet{opacity:0}.wrapper{display:table-cell}.default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}.default-handle{stroke:#fff;fill:#1b262c}\n"] }]
2600
+ }], propDecorators: { ngOnInit: [], ngAfterViewInit: [] } });
2641
2601
 
2642
2602
  class ConnectionComponent {
2643
2603
  constructor() {
2604
+ this.model = input.required();
2605
+ this.template = input();
2644
2606
  this.flowStatusService = inject(FlowStatusService);
2645
2607
  this.spacePointContext = inject(SpacePointContextDirective);
2646
2608
  this.path = computed(() => {
@@ -2651,11 +2613,15 @@ class ConnectionComponent {
2651
2613
  const sourcePosition = sourceHandle.rawHandle.position;
2652
2614
  const targetPoint = this.spacePointContext.svgCurrentSpacePoint();
2653
2615
  const targetPosition = getOppositePostion(sourceHandle.rawHandle.position);
2654
- switch (this.model.curve) {
2655
- case 'straight': return straightPath(sourcePoint, targetPoint).path;
2656
- case 'bezier': return bezierPath(sourcePoint, targetPoint, sourcePosition, targetPosition).path;
2657
- case 'smooth-step': return smoothStepPath(sourcePoint, targetPoint, sourcePosition, targetPosition).path;
2658
- case 'step': return smoothStepPath(sourcePoint, targetPoint, sourcePosition, targetPosition, 0).path;
2616
+ switch (this.model().curve) {
2617
+ case 'straight':
2618
+ return straightPath(sourcePoint, targetPoint).path;
2619
+ case 'bezier':
2620
+ return bezierPath(sourcePoint, targetPoint, sourcePosition, targetPosition).path;
2621
+ case 'smooth-step':
2622
+ return smoothStepPath(sourcePoint, targetPoint, sourcePosition, targetPosition).path;
2623
+ case 'step':
2624
+ return smoothStepPath(sourcePoint, targetPoint, sourcePosition, targetPosition, 0).path;
2659
2625
  }
2660
2626
  }
2661
2627
  if (status.state === 'connection-validation') {
@@ -2670,17 +2636,21 @@ class ConnectionComponent {
2670
2636
  const targetPosition = status.payload.valid
2671
2637
  ? targetHandle.rawHandle.position
2672
2638
  : getOppositePostion(sourceHandle.rawHandle.position);
2673
- switch (this.model.curve) {
2674
- case 'straight': return straightPath(sourcePoint, targetPoint).path;
2675
- case 'bezier': return bezierPath(sourcePoint, targetPoint, sourcePosition, targetPosition).path;
2676
- case 'smooth-step': return smoothStepPath(sourcePoint, targetPoint, sourcePosition, targetPosition).path;
2677
- case 'step': return smoothStepPath(sourcePoint, targetPoint, sourcePosition, targetPosition, 0).path;
2639
+ switch (this.model().curve) {
2640
+ case 'straight':
2641
+ return straightPath(sourcePoint, targetPoint).path;
2642
+ case 'bezier':
2643
+ return bezierPath(sourcePoint, targetPoint, sourcePosition, targetPosition).path;
2644
+ case 'smooth-step':
2645
+ return smoothStepPath(sourcePoint, targetPoint, sourcePosition, targetPosition).path;
2646
+ case 'step':
2647
+ return smoothStepPath(sourcePoint, targetPoint, sourcePosition, targetPosition, 0).path;
2678
2648
  }
2679
2649
  }
2680
2650
  return null;
2681
2651
  });
2682
2652
  this.markerUrl = computed(() => {
2683
- const marker = this.model.settings.marker;
2653
+ const marker = this.model().settings.marker;
2684
2654
  if (marker) {
2685
2655
  return `url(#${hashCode(JSON.stringify(marker))})`;
2686
2656
  }
@@ -2692,56 +2662,59 @@ class ConnectionComponent {
2692
2662
  return {
2693
2663
  $implicit: {
2694
2664
  path: this.path,
2695
- marker: this.markerUrl
2696
- }
2665
+ marker: this.markerUrl,
2666
+ },
2697
2667
  };
2698
2668
  }
2699
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ConnectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2700
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ConnectionComponent, selector: "g[connection]", inputs: { model: "model", template: "template" }, ngImport: i0, template: `
2701
- <ng-container *ngIf="model.type === 'default'">
2702
- <svg:path
2703
- *ngIf="path() as path"
2704
- [attr.d]="path"
2705
- [attr.marker-end]="markerUrl()"
2706
- [attr.stroke]="defaultColor"
2707
- fill="none"
2708
- stroke-width="2"
2709
- />
2710
- </ng-container>
2711
-
2712
- <ng-container *ngIf="model.type === 'template' && template">
2713
- <ng-container *ngTemplateOutlet="template; context: getContext()" />
2714
- </ng-container>
2715
- `, isInline: true, dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2716
- }
2717
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ConnectionComponent, decorators: [{
2669
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ConnectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2670
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: ConnectionComponent, isStandalone: true, selector: "g[connection]", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, template: { classPropertyName: "template", publicName: "template", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
2671
+ @if (model().type === 'default') {
2672
+ @if (path(); as path) {
2673
+ <svg:path
2674
+ [attr.d]="path"
2675
+ [attr.marker-end]="markerUrl()"
2676
+ [attr.stroke]="defaultColor"
2677
+ fill="none"
2678
+ stroke-width="2"
2679
+ />
2680
+ }
2681
+ }
2682
+
2683
+ @if (model().type === 'template') {
2684
+ @if (template(); as template) {
2685
+ <ng-container *ngTemplateOutlet="template; context: getContext()" />
2686
+ }
2687
+ }
2688
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2689
+ }
2690
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ConnectionComponent, decorators: [{
2718
2691
  type: Component,
2719
2692
  args: [{
2693
+ standalone: true,
2720
2694
  selector: 'g[connection]',
2721
2695
  template: `
2722
- <ng-container *ngIf="model.type === 'default'">
2723
- <svg:path
2724
- *ngIf="path() as path"
2725
- [attr.d]="path"
2726
- [attr.marker-end]="markerUrl()"
2727
- [attr.stroke]="defaultColor"
2728
- fill="none"
2729
- stroke-width="2"
2730
- />
2731
- </ng-container>
2732
-
2733
- <ng-container *ngIf="model.type === 'template' && template">
2734
- <ng-container *ngTemplateOutlet="template; context: getContext()" />
2735
- </ng-container>
2696
+ @if (model().type === 'default') {
2697
+ @if (path(); as path) {
2698
+ <svg:path
2699
+ [attr.d]="path"
2700
+ [attr.marker-end]="markerUrl()"
2701
+ [attr.stroke]="defaultColor"
2702
+ fill="none"
2703
+ stroke-width="2"
2704
+ />
2705
+ }
2706
+ }
2707
+
2708
+ @if (model().type === 'template') {
2709
+ @if (template(); as template) {
2710
+ <ng-container *ngTemplateOutlet="template; context: getContext()" />
2711
+ }
2712
+ }
2736
2713
  `,
2737
- changeDetection: ChangeDetectionStrategy.OnPush
2714
+ changeDetection: ChangeDetectionStrategy.OnPush,
2715
+ imports: [NgTemplateOutlet],
2738
2716
  }]
2739
- }], propDecorators: { model: [{
2740
- type: Input,
2741
- args: [{ required: true }]
2742
- }], template: [{
2743
- type: Input
2744
- }] } });
2717
+ }] });
2745
2718
  function getOppositePostion(position) {
2746
2719
  switch (position) {
2747
2720
  case 'top':
@@ -2755,22 +2728,6 @@ function getOppositePostion(position) {
2755
2728
  }
2756
2729
  }
2757
2730
 
2758
- class DefsComponent {
2759
- constructor() {
2760
- this.markers = new Map();
2761
- this.defaultColor = 'rgb(177, 177, 183)';
2762
- }
2763
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DefsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2764
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DefsComponent, selector: "defs[flowDefs]", inputs: { markers: "markers" }, ngImport: i0, template: "<svg:marker\n *ngFor=\"let marker of markers | keyvalue\"\n [attr.id]=\"marker.key\"\n [attr.markerWidth]=\"marker.value.width ?? 16.5\"\n [attr.markerHeight]=\"marker.value.height ?? 16.5\"\n [attr.orient]=\"marker.value.orient ?? 'auto-start-reverse'\"\n viewBox=\"-10 -10 20 20\"\n [attr.markerUnits]=\"marker.value.markerUnits ?? 'userSpaceOnUse'\"\n refX=\"0\"\n refY=\"0\"\n>\n <polyline\n *ngIf=\"marker.value.type === 'arrow-closed' || !marker.value.type\"\n class=\"marker__arrow_closed\"\n [style.stroke]=\"marker.value.color ?? defaultColor\"\n [style.stroke-width]=\"marker.value.strokeWidth ?? 2\"\n [style.fill]=\"marker.value.color ?? defaultColor\"\n points=\"-5,-4 1,0 -5,4 -5,-4\"\n />\n\n <polyline\n *ngIf=\"marker.value.type === 'arrow'\"\n class=\"marker__arrow_default\"\n [style.stroke]=\"marker.value.color ?? defaultColor\"\n [style.stroke-width]=\"marker.value.strokeWidth ?? 2\"\n points=\"-5,-4 0,0 -5,4\"\n />\n</svg:marker>\n", styles: [".marker__arrow_default{stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;fill:none}.marker__arrow_closed{stroke-linecap:round;stroke-linejoin:round}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "pipe", type: i1.KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2765
- }
2766
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DefsComponent, decorators: [{
2767
- type: Component,
2768
- args: [{ selector: 'defs[flowDefs]', changeDetection: ChangeDetectionStrategy.OnPush, template: "<svg:marker\n *ngFor=\"let marker of markers | keyvalue\"\n [attr.id]=\"marker.key\"\n [attr.markerWidth]=\"marker.value.width ?? 16.5\"\n [attr.markerHeight]=\"marker.value.height ?? 16.5\"\n [attr.orient]=\"marker.value.orient ?? 'auto-start-reverse'\"\n viewBox=\"-10 -10 20 20\"\n [attr.markerUnits]=\"marker.value.markerUnits ?? 'userSpaceOnUse'\"\n refX=\"0\"\n refY=\"0\"\n>\n <polyline\n *ngIf=\"marker.value.type === 'arrow-closed' || !marker.value.type\"\n class=\"marker__arrow_closed\"\n [style.stroke]=\"marker.value.color ?? defaultColor\"\n [style.stroke-width]=\"marker.value.strokeWidth ?? 2\"\n [style.fill]=\"marker.value.color ?? defaultColor\"\n points=\"-5,-4 1,0 -5,4 -5,-4\"\n />\n\n <polyline\n *ngIf=\"marker.value.type === 'arrow'\"\n class=\"marker__arrow_default\"\n [style.stroke]=\"marker.value.color ?? defaultColor\"\n [style.stroke-width]=\"marker.value.strokeWidth ?? 2\"\n points=\"-5,-4 0,0 -5,4\"\n />\n</svg:marker>\n", styles: [".marker__arrow_default{stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;fill:none}.marker__arrow_closed{stroke-linecap:round;stroke-linejoin:round}\n"] }]
2769
- }], propDecorators: { markers: [{
2770
- type: Input,
2771
- args: [{ required: true }]
2772
- }] } });
2773
-
2774
2731
  function id() {
2775
2732
  const randomLetter = String.fromCharCode(65 + Math.floor(Math.random() * 26));
2776
2733
  return randomLetter + Date.now();
@@ -2877,13 +2834,13 @@ class BackgroundComponent {
2877
2834
  }
2878
2835
  });
2879
2836
  }
2880
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BackgroundComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2881
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: BackgroundComponent, selector: "g[background]", ngImport: i0, template: "<ng-container *ngIf=\"backgroundSignal().type === 'dots'\">\n <svg:pattern\n [attr.id]=\"patternId\"\n [attr.x]=\"x()\"\n [attr.y]=\"y()\"\n [attr.width]=\"scaledGap()\"\n [attr.height]=\"scaledGap()\"\n patternUnits=\"userSpaceOnUse\"\n >\n <svg:circle\n [attr.cx]=\"patternSize()\"\n [attr.cy]=\"patternSize()\"\n [attr.r]=\"patternSize()\"\n [attr.fill]=\"patternColor()\"\n />\n </svg:pattern>\n\n <svg:rect\n x=\"0\"\n y=\"0\"\n width=\"100%\"\n height=\"100%\"\n [attr.fill]=\"patternUrl\"\n />\n</ng-container>\n\n<ng-container *ngIf=\"backgroundSignal().type === 'image'\">\n <ng-container *ngIf=\"repeated()\">\n <svg:pattern\n [attr.id]=\"patternId\"\n [attr.x]=\"imageX()\"\n [attr.y]=\"imageY()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n patternUnits=\"userSpaceOnUse\"\n >\n <svg:image\n [attr.href]=\"bgImageSrc()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n />\n </svg:pattern>\n\n <svg:rect\n x=\"0\"\n y=\"0\"\n width=\"100%\"\n height=\"100%\"\n [attr.fill]=\"patternUrl\"\n />\n </ng-container>\n\n <ng-container *ngIf=\"!repeated()\">\n <svg:image\n [attr.x]=\"imageX()\"\n [attr.y]=\"imageY()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n [attr.href]=\"bgImageSrc()\"\n />\n </ng-container>\n</ng-container>\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2837
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: BackgroundComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2838
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: BackgroundComponent, isStandalone: true, selector: "g[background]", ngImport: i0, template: "@if (backgroundSignal().type === 'dots') {\n <svg:pattern\n [attr.id]=\"patternId\"\n [attr.x]=\"x()\"\n [attr.y]=\"y()\"\n [attr.width]=\"scaledGap()\"\n [attr.height]=\"scaledGap()\"\n patternUnits=\"userSpaceOnUse\"\n >\n <svg:circle\n [attr.cx]=\"patternSize()\"\n [attr.cy]=\"patternSize()\"\n [attr.r]=\"patternSize()\"\n [attr.fill]=\"patternColor()\"\n />\n </svg:pattern>\n\n <svg:rect\n x=\"0\"\n y=\"0\"\n width=\"100%\"\n height=\"100%\"\n [attr.fill]=\"patternUrl\"\n />\n}\n\n@if (backgroundSignal().type === 'image') {\n @if (repeated()) {\n <svg:pattern\n [attr.id]=\"patternId\"\n [attr.x]=\"imageX()\"\n [attr.y]=\"imageY()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n patternUnits=\"userSpaceOnUse\"\n >\n <svg:image\n [attr.href]=\"bgImageSrc()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n />\n </svg:pattern>\n\n <svg:rect\n x=\"0\"\n y=\"0\"\n width=\"100%\"\n height=\"100%\"\n [attr.fill]=\"patternUrl\"\n />\n }\n\n @if (!repeated()) {\n <svg:image\n [attr.x]=\"imageX()\"\n [attr.y]=\"imageY()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n [attr.href]=\"bgImageSrc()\"\n />\n }\n}\n", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2882
2839
  }
2883
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BackgroundComponent, decorators: [{
2840
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: BackgroundComponent, decorators: [{
2884
2841
  type: Component,
2885
- args: [{ selector: 'g[background]', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"backgroundSignal().type === 'dots'\">\n <svg:pattern\n [attr.id]=\"patternId\"\n [attr.x]=\"x()\"\n [attr.y]=\"y()\"\n [attr.width]=\"scaledGap()\"\n [attr.height]=\"scaledGap()\"\n patternUnits=\"userSpaceOnUse\"\n >\n <svg:circle\n [attr.cx]=\"patternSize()\"\n [attr.cy]=\"patternSize()\"\n [attr.r]=\"patternSize()\"\n [attr.fill]=\"patternColor()\"\n />\n </svg:pattern>\n\n <svg:rect\n x=\"0\"\n y=\"0\"\n width=\"100%\"\n height=\"100%\"\n [attr.fill]=\"patternUrl\"\n />\n</ng-container>\n\n<ng-container *ngIf=\"backgroundSignal().type === 'image'\">\n <ng-container *ngIf=\"repeated()\">\n <svg:pattern\n [attr.id]=\"patternId\"\n [attr.x]=\"imageX()\"\n [attr.y]=\"imageY()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n patternUnits=\"userSpaceOnUse\"\n >\n <svg:image\n [attr.href]=\"bgImageSrc()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n />\n </svg:pattern>\n\n <svg:rect\n x=\"0\"\n y=\"0\"\n width=\"100%\"\n height=\"100%\"\n [attr.fill]=\"patternUrl\"\n />\n </ng-container>\n\n <ng-container *ngIf=\"!repeated()\">\n <svg:image\n [attr.x]=\"imageX()\"\n [attr.y]=\"imageY()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n [attr.href]=\"bgImageSrc()\"\n />\n </ng-container>\n</ng-container>\n" }]
2886
- }], ctorParameters: function () { return []; } });
2842
+ args: [{ standalone: true, selector: 'g[background]', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (backgroundSignal().type === 'dots') {\n <svg:pattern\n [attr.id]=\"patternId\"\n [attr.x]=\"x()\"\n [attr.y]=\"y()\"\n [attr.width]=\"scaledGap()\"\n [attr.height]=\"scaledGap()\"\n patternUnits=\"userSpaceOnUse\"\n >\n <svg:circle\n [attr.cx]=\"patternSize()\"\n [attr.cy]=\"patternSize()\"\n [attr.r]=\"patternSize()\"\n [attr.fill]=\"patternColor()\"\n />\n </svg:pattern>\n\n <svg:rect\n x=\"0\"\n y=\"0\"\n width=\"100%\"\n height=\"100%\"\n [attr.fill]=\"patternUrl\"\n />\n}\n\n@if (backgroundSignal().type === 'image') {\n @if (repeated()) {\n <svg:pattern\n [attr.id]=\"patternId\"\n [attr.x]=\"imageX()\"\n [attr.y]=\"imageY()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n patternUnits=\"userSpaceOnUse\"\n >\n <svg:image\n [attr.href]=\"bgImageSrc()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n />\n </svg:pattern>\n\n <svg:rect\n x=\"0\"\n y=\"0\"\n width=\"100%\"\n height=\"100%\"\n [attr.fill]=\"patternUrl\"\n />\n }\n\n @if (!repeated()) {\n <svg:image\n [attr.x]=\"imageX()\"\n [attr.y]=\"imageY()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n [attr.href]=\"bgImageSrc()\"\n />\n }\n}\n" }]
2843
+ }], ctorParameters: () => [] });
2887
2844
  function createImage(url) {
2888
2845
  const image = new Image();
2889
2846
  image.src = url;
@@ -2892,31 +2849,18 @@ function createImage(url) {
2892
2849
  });
2893
2850
  }
2894
2851
 
2895
- // TODO: too general purpose nane
2896
- class RootSvgContextDirective {
2852
+ class DefsComponent {
2897
2853
  constructor() {
2898
- this.flowStatusService = inject(FlowStatusService);
2899
- }
2900
- // TODO: check for multiple instances on page
2901
- resetConnection() {
2902
- const status = this.flowStatusService.status();
2903
- if (status.state === 'connection-start') {
2904
- this.flowStatusService.setIdleStatus();
2905
- }
2854
+ this.markers = input.required();
2855
+ this.defaultColor = 'rgb(177, 177, 183)';
2906
2856
  }
2907
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RootSvgContextDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2908
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: RootSvgContextDirective, selector: "svg[rootSvgContext]", host: { listeners: { "document:mouseup": "resetConnection()", "document:touchend": "resetConnection()" } }, ngImport: i0 }); }
2857
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DefsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2858
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: DefsComponent, isStandalone: true, selector: "defs[flowDefs]", inputs: { markers: { classPropertyName: "markers", publicName: "markers", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@for (marker of markers() | keyvalue; track marker) {\n <svg:marker\n [attr.id]=\"marker.key\"\n [attr.markerWidth]=\"marker.value.width ?? 16.5\"\n [attr.markerHeight]=\"marker.value.height ?? 16.5\"\n [attr.orient]=\"marker.value.orient ?? 'auto-start-reverse'\"\n viewBox=\"-10 -10 20 20\"\n [attr.markerUnits]=\"marker.value.markerUnits ?? 'userSpaceOnUse'\"\n refX=\"0\"\n refY=\"0\"\n >\n @if (marker.value.type === \"arrow-closed\" || !marker.value.type) {\n <polyline\n class=\"marker__arrow_closed\"\n [style.stroke]=\"marker.value.color ?? defaultColor\"\n [style.stroke-width]=\"marker.value.strokeWidth ?? 2\"\n [style.fill]=\"marker.value.color ?? defaultColor\"\n points=\"-5,-4 1,0 -5,4 -5,-4\"\n />\n }\n\n @if (marker.value.type === \"arrow\") {\n <polyline\n class=\"marker__arrow_default\"\n [style.stroke]=\"marker.value.color ?? defaultColor\"\n [style.stroke-width]=\"marker.value.strokeWidth ?? 2\"\n points=\"-5,-4 0,0 -5,4\"\n />\n }\n </svg:marker>\n}\n", styles: [".marker__arrow_default{stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;fill:none}.marker__arrow_closed{stroke-linecap:round;stroke-linejoin:round}\n"], dependencies: [{ kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2909
2859
  }
2910
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RootSvgContextDirective, decorators: [{
2911
- type: Directive,
2912
- args: [{ selector: 'svg[rootSvgContext]' }]
2913
- }], propDecorators: { resetConnection: [{
2914
- type: HostListener,
2915
- args: ['document:mouseup']
2916
- }, {
2917
- type: HostListener,
2918
- args: ['document:touchend']
2919
- }] } });
2860
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DefsComponent, decorators: [{
2861
+ type: Component,
2862
+ args: [{ standalone: true, selector: 'defs[flowDefs]', changeDetection: ChangeDetectionStrategy.OnPush, imports: [KeyValuePipe], template: "@for (marker of markers() | keyvalue; track marker) {\n <svg:marker\n [attr.id]=\"marker.key\"\n [attr.markerWidth]=\"marker.value.width ?? 16.5\"\n [attr.markerHeight]=\"marker.value.height ?? 16.5\"\n [attr.orient]=\"marker.value.orient ?? 'auto-start-reverse'\"\n viewBox=\"-10 -10 20 20\"\n [attr.markerUnits]=\"marker.value.markerUnits ?? 'userSpaceOnUse'\"\n refX=\"0\"\n refY=\"0\"\n >\n @if (marker.value.type === \"arrow-closed\" || !marker.value.type) {\n <polyline\n class=\"marker__arrow_closed\"\n [style.stroke]=\"marker.value.color ?? defaultColor\"\n [style.stroke-width]=\"marker.value.strokeWidth ?? 2\"\n [style.fill]=\"marker.value.color ?? defaultColor\"\n points=\"-5,-4 1,0 -5,4 -5,-4\"\n />\n }\n\n @if (marker.value.type === \"arrow\") {\n <polyline\n class=\"marker__arrow_default\"\n [style.stroke]=\"marker.value.color ?? defaultColor\"\n [style.stroke-width]=\"marker.value.strokeWidth ?? 2\"\n points=\"-5,-4 0,0 -5,4\"\n />\n }\n </svg:marker>\n}\n", styles: [".marker__arrow_default{stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;fill:none}.marker__arrow_closed{stroke-linecap:round;stroke-linejoin:round}\n"] }]
2863
+ }] });
2920
2864
 
2921
2865
  class FlowSizeControllerDirective {
2922
2866
  constructor() {
@@ -2935,23 +2879,53 @@ class FlowSizeControllerDirective {
2935
2879
  this.flowSettingsService.computedFlowHeight.set(entry.contentRect.height);
2936
2880
  }), takeUntilDestroyed()).subscribe();
2937
2881
  }
2938
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FlowSizeControllerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2939
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: FlowSizeControllerDirective, selector: "svg[flowSizeController]", host: { properties: { "attr.width": "flowWidth()", "attr.height": "flowHeight()" } }, ngImport: i0 }); }
2882
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowSizeControllerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2883
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: FlowSizeControllerDirective, isStandalone: true, selector: "svg[flowSizeController]", host: { properties: { "attr.width": "flowWidth()", "attr.height": "flowHeight()" } }, ngImport: i0 }); }
2940
2884
  }
2941
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FlowSizeControllerDirective, decorators: [{
2885
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowSizeControllerDirective, decorators: [{
2942
2886
  type: Directive,
2943
2887
  args: [{
2888
+ standalone: true,
2944
2889
  selector: 'svg[flowSizeController]',
2945
2890
  host: {
2946
2891
  '[attr.width]': 'flowWidth()',
2947
2892
  '[attr.height]': 'flowHeight()'
2948
- }
2893
+ },
2949
2894
  }]
2950
- }], ctorParameters: function () { return []; } });
2895
+ }], ctorParameters: () => [] });
2896
+
2897
+ // TODO: too general purpose nane
2898
+ class RootSvgContextDirective {
2899
+ constructor() {
2900
+ this.flowStatusService = inject(FlowStatusService);
2901
+ }
2902
+ // TODO: check for multiple instances on page
2903
+ resetConnection() {
2904
+ const status = this.flowStatusService.status();
2905
+ if (status.state === 'connection-start') {
2906
+ this.flowStatusService.setIdleStatus();
2907
+ }
2908
+ }
2909
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RootSvgContextDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2910
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: RootSvgContextDirective, isStandalone: true, selector: "svg[rootSvgContext]", host: { listeners: { "document:mouseup": "resetConnection()", "document:touchend": "resetConnection()" } }, ngImport: i0 }); }
2911
+ }
2912
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RootSvgContextDirective, decorators: [{
2913
+ type: Directive,
2914
+ args: [{
2915
+ standalone: true,
2916
+ selector: 'svg[rootSvgContext]',
2917
+ }]
2918
+ }], propDecorators: { resetConnection: [{
2919
+ type: HostListener,
2920
+ args: ['document:mouseup']
2921
+ }, {
2922
+ type: HostListener,
2923
+ args: ['document:touchend']
2924
+ }] } });
2951
2925
 
2952
2926
  const connectionControllerHostDirective = {
2953
2927
  directive: ConnectionControllerDirective,
2954
- outputs: ['onConnect']
2928
+ outputs: ['onConnect'],
2955
2929
  };
2956
2930
  const changesControllerHostDirective = {
2957
2931
  directive: ChangesControllerDirective,
@@ -2985,7 +2959,7 @@ const changesControllerHostDirective = {
2985
2959
  'onEdgesChange.select',
2986
2960
  'onEdgesChange.select.single',
2987
2961
  'onEdgesChange.select.many',
2988
- ]
2962
+ ],
2989
2963
  };
2990
2964
  class VflowComponent {
2991
2965
  constructor() {
@@ -2999,10 +2973,9 @@ class VflowComponent {
2999
2973
  this.componentEventBusService = inject(ComponentEventBusService);
3000
2974
  this.keyboardService = inject(KeyboardService);
3001
2975
  this.injector = inject(Injector);
3002
- this.optimization = {
3003
- computeLayersOnInit: true,
3004
- detachedGroupsLayer: false
3005
- };
2976
+ this.optimization = input({
2977
+ detachedGroupsLayer: false,
2978
+ });
3006
2979
  this.nodeModels = computed(() => this.nodeRenderingService.nodes());
3007
2980
  this.groups = computed(() => this.nodeRenderingService.groups());
3008
2981
  this.nonGroups = computed(() => this.nodeRenderingService.nonGroups());
@@ -3014,7 +2987,18 @@ class VflowComponent {
3014
2987
  *
3015
2988
  * @experimental
3016
2989
  */
3017
- this.onComponentNodeEvent = this.componentEventBusService.event$; // TODO: research how to remove as any
2990
+ this.onComponentNodeEvent = outputFromObservable(this.componentEventBusService.event$); // TODO: research how to remove any
2991
+ // #endregion
2992
+ // #region TEMPLATES
2993
+ this.nodeTemplateDirective = contentChild(NodeHtmlTemplateDirective);
2994
+ this.groupNodeTemplateDirective = contentChild(GroupNodeTemplateDirective);
2995
+ this.edgeTemplateDirective = contentChild(EdgeTemplateDirective);
2996
+ this.edgeLabelHtmlDirective = contentChild(EdgeLabelHtmlTemplateDirective);
2997
+ this.connectionTemplateDirective = contentChild(ConnectionTemplateDirective);
2998
+ // #endregion
2999
+ // #region DIRECTIVES
3000
+ this.mapContext = viewChild(MapContextDirective);
3001
+ this.spacePointContext = viewChild.required(SpacePointContextDirective);
3018
3002
  // #endregion
3019
3003
  // #region SIGNAL_API
3020
3004
  /**
@@ -3024,18 +3008,21 @@ class VflowComponent {
3024
3008
  /**
3025
3009
  * Signal for reading nodes change
3026
3010
  */
3027
- this.nodesChange = toSignal(this.nodesChangeService.changes$, { initialValue: [] });
3011
+ this.nodesChange = toSignal(this.nodesChangeService.changes$, {
3012
+ initialValue: [],
3013
+ });
3028
3014
  /**
3029
3015
  * Signal to reading edges change
3030
3016
  */
3031
- this.edgesChange = toSignal(this.edgesChangeService.changes$, { initialValue: [] });
3017
+ this.edgesChange = toSignal(this.edgesChangeService.changes$, {
3018
+ initialValue: [],
3019
+ });
3032
3020
  // #endregion
3033
3021
  // #region RX_API
3034
3022
  /**
3035
3023
  * Observable with viewport change
3036
3024
  */
3037
- this.viewportChange$ = toObservable(this.viewportService.readableViewport)
3038
- .pipe(skip(1)); // skip default value that set by signal
3025
+ this.viewportChange$ = toObservable(this.viewportService.readableViewport).pipe(skip(1)); // skip default value that set by signal
3039
3026
  /**
3040
3027
  * Observable with nodes change
3041
3028
  */
@@ -3072,17 +3059,6 @@ class VflowComponent {
3072
3059
  set maxZoom(value) {
3073
3060
  this.flowSettingsService.maxZoom.set(value);
3074
3061
  }
3075
- /**
3076
- * Object that controls flow direction.
3077
- *
3078
- * For example, if you want to archieve right to left direction
3079
- * then you need to pass these positions { source: 'left', target: 'right' }
3080
- *
3081
- * @deprecated
3082
- */
3083
- set handlePositions(handlePositions) {
3084
- this.flowSettingsService.handlePositions.set(handlePositions);
3085
- }
3086
3062
  /**
3087
3063
  * Background for flow
3088
3064
  */
@@ -3103,8 +3079,12 @@ class VflowComponent {
3103
3079
  *
3104
3080
  * You need to pass `ConnectionSettings` in this input.
3105
3081
  */
3106
- set connection(connection) { this.flowEntitiesService.connection.set(connection); }
3107
- get connection() { return this.flowEntitiesService.connection(); }
3082
+ set connection(connection) {
3083
+ this.flowEntitiesService.connection.set(connection);
3084
+ }
3085
+ get connection() {
3086
+ return this.flowEntitiesService.connection();
3087
+ }
3108
3088
  // #endregion
3109
3089
  // #region MAIN_INPUTS
3110
3090
  /**
@@ -3135,7 +3115,11 @@ class VflowComponent {
3135
3115
  * @param viewport viewport state
3136
3116
  */
3137
3117
  viewportTo(viewport) {
3138
- this.viewportService.writableViewport.set({ changeType: 'absolute', state: viewport, duration: 0 });
3118
+ this.viewportService.writableViewport.set({
3119
+ changeType: 'absolute',
3120
+ state: viewport,
3121
+ duration: 0,
3122
+ });
3139
3123
  }
3140
3124
  /**
3141
3125
  * Change zoom
@@ -3143,7 +3127,11 @@ class VflowComponent {
3143
3127
  * @param zoom zoom value
3144
3128
  */
3145
3129
  zoomTo(zoom) {
3146
- this.viewportService.writableViewport.set({ changeType: 'absolute', state: { zoom }, duration: 0 });
3130
+ this.viewportService.writableViewport.set({
3131
+ changeType: 'absolute',
3132
+ state: { zoom },
3133
+ duration: 0,
3134
+ });
3147
3135
  }
3148
3136
  /**
3149
3137
  * Move to specified coordinate
@@ -3151,7 +3139,11 @@ class VflowComponent {
3151
3139
  * @param point point where to move
3152
3140
  */
3153
3141
  panTo(point) {
3154
- this.viewportService.writableViewport.set({ changeType: 'absolute', state: point, duration: 0 });
3142
+ this.viewportService.writableViewport.set({
3143
+ changeType: 'absolute',
3144
+ state: point,
3145
+ duration: 0,
3146
+ });
3155
3147
  }
3156
3148
  fitView(options) {
3157
3149
  this.viewportService.fitView(options);
@@ -3168,13 +3160,13 @@ class VflowComponent {
3168
3160
  * Sync method to get detached edges
3169
3161
  */
3170
3162
  getDetachedEdges() {
3171
- return this.flowEntitiesService.getDetachedEdges().map(e => e.edge);
3163
+ return this.flowEntitiesService.getDetachedEdges().map((e) => e.edge);
3172
3164
  }
3173
3165
  /**
3174
3166
  * Convert point received from document to point on the flow
3175
3167
  */
3176
3168
  documentPointToFlowPoint(point) {
3177
- return this.spacePointContext.documentPointToFlowPoint(point);
3169
+ return this.spacePointContext().documentPointToFlowPoint(point);
3178
3170
  }
3179
3171
  // #endregion
3180
3172
  trackNodes(idx, { node }) {
@@ -3184,19 +3176,17 @@ class VflowComponent {
3184
3176
  return edge;
3185
3177
  }
3186
3178
  setInitialNodesOrder() {
3187
- if (this.optimization.computeLayersOnInit) {
3188
- this.nodeModels().forEach(model => {
3189
- switch (model.node.type) {
3190
- case 'default-group':
3191
- case 'template-group': {
3192
- this.nodeRenderingService.pullNode(model);
3193
- }
3179
+ this.nodeModels().forEach((model) => {
3180
+ switch (model.node.type) {
3181
+ case 'default-group':
3182
+ case 'template-group': {
3183
+ this.nodeRenderingService.pullNode(model);
3194
3184
  }
3195
- });
3196
- }
3185
+ }
3186
+ });
3197
3187
  }
3198
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: VflowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3199
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "16.2.12", type: VflowComponent, selector: "vflow", inputs: { view: "view", minZoom: "minZoom", maxZoom: "maxZoom", handlePositions: "handlePositions", background: "background", optimization: "optimization", entitiesSelectable: "entitiesSelectable", keyboardShortcuts: "keyboardShortcuts", connection: ["connection", "connection", (settings) => new ConnectionModel(settings)], nodes: "nodes", edges: "edges" }, outputs: { onComponentNodeEvent: "onComponentNodeEvent" }, providers: [
3188
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: VflowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3189
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: VflowComponent, isStandalone: true, selector: "vflow", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: false, isRequired: false, transformFunction: null }, minZoom: { classPropertyName: "minZoom", publicName: "minZoom", isSignal: false, isRequired: false, transformFunction: null }, maxZoom: { classPropertyName: "maxZoom", publicName: "maxZoom", isSignal: false, isRequired: false, transformFunction: null }, background: { classPropertyName: "background", publicName: "background", isSignal: false, isRequired: false, transformFunction: null }, optimization: { classPropertyName: "optimization", publicName: "optimization", isSignal: true, isRequired: false, transformFunction: null }, entitiesSelectable: { classPropertyName: "entitiesSelectable", publicName: "entitiesSelectable", isSignal: false, isRequired: false, transformFunction: null }, keyboardShortcuts: { classPropertyName: "keyboardShortcuts", publicName: "keyboardShortcuts", isSignal: false, isRequired: false, transformFunction: null }, connection: { classPropertyName: "connection", publicName: "connection", isSignal: false, isRequired: false, transformFunction: (settings) => new ConnectionModel(settings) }, nodes: { classPropertyName: "nodes", publicName: "nodes", isSignal: false, isRequired: true, transformFunction: null }, edges: { classPropertyName: "edges", publicName: "edges", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { onComponentNodeEvent: "onComponentNodeEvent" }, providers: [
3200
3190
  DraggableService,
3201
3191
  ViewportService,
3202
3192
  FlowStatusService,
@@ -3208,12 +3198,12 @@ class VflowComponent {
3208
3198
  FlowSettingsService,
3209
3199
  ComponentEventBusService,
3210
3200
  KeyboardService,
3211
- OverlaysService
3212
- ], queries: [{ propertyName: "nodeTemplateDirective", first: true, predicate: NodeHtmlTemplateDirective, descendants: true }, { propertyName: "groupNodeTemplateDirective", first: true, predicate: GroupNodeTemplateDirective, descendants: true }, { propertyName: "edgeTemplateDirective", first: true, predicate: EdgeTemplateDirective, descendants: true }, { propertyName: "edgeLabelHtmlDirective", first: true, predicate: EdgeLabelHtmlTemplateDirective, descendants: true }, { propertyName: "connectionTemplateDirective", first: true, predicate: ConnectionTemplateDirective, descendants: true }], viewQueries: [{ propertyName: "mapContext", first: true, predicate: MapContextDirective, descendants: true }, { propertyName: "spacePointContext", first: true, predicate: SpacePointContextDirective, descendants: true }], hostDirectives: [{ directive: ConnectionControllerDirective, outputs: ["onConnect", "onConnect"] }, { directive: ChangesControllerDirective, outputs: ["onNodesChange", "onNodesChange", "onNodesChange.position", "onNodesChange.position", "onNodesChange.position.single", "onNodesChange.position.single", "onNodesChange.position.many", "onNodesChange.position.many", "onNodesChange.size", "onNodesChange.size", "onNodesChange.size.single", "onNodesChange.size.single", "onNodesChange.size.many", "onNodesChange.size.many", "onNodesChange.add", "onNodesChange.add", "onNodesChange.add.single", "onNodesChange.add.single", "onNodesChange.add.many", "onNodesChange.add.many", "onNodesChange.remove", "onNodesChange.remove", "onNodesChange.remove.single", "onNodesChange.remove.single", "onNodesChange.remove.many", "onNodesChange.remove.many", "onNodesChange.select", "onNodesChange.select", "onNodesChange.select.single", "onNodesChange.select.single", "onNodesChange.select.many", "onNodesChange.select.many", "onEdgesChange", "onEdgesChange", "onEdgesChange.detached", "onEdgesChange.detached", "onEdgesChange.detached.single", "onEdgesChange.detached.single", "onEdgesChange.detached.many", "onEdgesChange.detached.many", "onEdgesChange.add", "onEdgesChange.add", "onEdgesChange.add.single", "onEdgesChange.add.single", "onEdgesChange.add.many", "onEdgesChange.add.many", "onEdgesChange.remove", "onEdgesChange.remove", "onEdgesChange.remove.single", "onEdgesChange.remove.single", "onEdgesChange.remove.many", "onEdgesChange.remove.many", "onEdgesChange.select", "onEdgesChange.select", "onEdgesChange.select.single", "onEdgesChange.select.single", "onEdgesChange.select.many", "onEdgesChange.select.many"] }], ngImport: i0, template: "<svg:svg\n rootSvgRef\n rootSvgContext\n rootPointer\n flowSizeController\n class=\"root-svg\"\n #flow\n>\n <defs [markers]=\"markers()\" flowDefs />\n\n <g background />\n\n <svg:g\n mapContext\n spacePointContext\n >\n <!-- Connection -->\n <svg:g\n connection\n [model]=\"connection\"\n [template]=\"connectionTemplateDirective?.templateRef\"\n />\n\n <ng-container *ngIf=\"optimization.detachedGroupsLayer\">\n <!-- Groups -->\n <svg:g\n *ngFor=\"let model of groups(); trackBy: trackNodes\"\n node\n [nodeModel]=\"model\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\n\n <!-- Edges -->\n <svg:g\n *ngFor=\"let model of edgeModels(); trackBy: trackEdges\"\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective?.templateRef\"\n />\n\n <!-- Nodes -->\n <svg:g\n *ngFor=\"let model of nonGroups(); trackBy: trackNodes\"\n node\n [nodeModel]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\n </ng-container>\n\n <ng-container *ngIf=\"!optimization.detachedGroupsLayer\">\n <!-- Edges -->\n <svg:g\n *ngFor=\"let model of edgeModels(); trackBy: trackEdges\"\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective?.templateRef\"\n />\n\n <!-- Nodes -->\n <svg:g\n *ngFor=\"let model of nodeModels(); trackBy: trackNodes\"\n node\n [nodeModel]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective?.templateRef\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\n </ng-container>\n\n </svg:g>\n\n <!-- Minimap -->\n <ng-container *ngIf=\"minimap() as minimap\">\n <ng-container [ngTemplateOutlet]=\"minimap.template()\" />\n </ng-container>\n</svg:svg>\n\n", styles: [":host{display:block;width:100%;height:100%;-webkit-user-select:none;user-select:none}:host ::ng-deep *{box-sizing:border-box}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: NodeComponent, selector: "g[node]", inputs: ["nodeModel", "nodeTemplate", "groupNodeTemplate"] }, { kind: "component", type: EdgeComponent, selector: "g[edge]", inputs: ["model", "edgeTemplate", "edgeLabelHtmlTemplate"] }, { kind: "component", type: ConnectionComponent, selector: "g[connection]", inputs: ["model", "template"] }, { kind: "component", type: DefsComponent, selector: "defs[flowDefs]", inputs: ["markers"] }, { kind: "component", type: BackgroundComponent, selector: "g[background]" }, { kind: "directive", type: SpacePointContextDirective, selector: "g[spacePointContext]" }, { kind: "directive", type: MapContextDirective, selector: "g[mapContext]" }, { kind: "directive", type: RootSvgReferenceDirective, selector: "svg[rootSvgRef]" }, { kind: "directive", type: RootSvgContextDirective, selector: "svg[rootSvgContext]" }, { kind: "directive", type: RootPointerDirective, selector: "svg[rootPointer]" }, { kind: "directive", type: FlowSizeControllerDirective, selector: "svg[flowSizeController]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3201
+ OverlaysService,
3202
+ ], queries: [{ propertyName: "nodeTemplateDirective", first: true, predicate: NodeHtmlTemplateDirective, descendants: true, isSignal: true }, { propertyName: "groupNodeTemplateDirective", first: true, predicate: GroupNodeTemplateDirective, descendants: true, isSignal: true }, { propertyName: "edgeTemplateDirective", first: true, predicate: EdgeTemplateDirective, descendants: true, isSignal: true }, { propertyName: "edgeLabelHtmlDirective", first: true, predicate: EdgeLabelHtmlTemplateDirective, descendants: true, isSignal: true }, { propertyName: "connectionTemplateDirective", first: true, predicate: ConnectionTemplateDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "mapContext", first: true, predicate: MapContextDirective, descendants: true, isSignal: true }, { propertyName: "spacePointContext", first: true, predicate: SpacePointContextDirective, descendants: true, isSignal: true }], hostDirectives: [{ directive: ConnectionControllerDirective, outputs: ["onConnect", "onConnect"] }, { directive: ChangesControllerDirective, outputs: ["onNodesChange", "onNodesChange", "onNodesChange.position", "onNodesChange.position", "onNodesChange.position.single", "onNodesChange.position.single", "onNodesChange.position.many", "onNodesChange.position.many", "onNodesChange.size", "onNodesChange.size", "onNodesChange.size.single", "onNodesChange.size.single", "onNodesChange.size.many", "onNodesChange.size.many", "onNodesChange.add", "onNodesChange.add", "onNodesChange.add.single", "onNodesChange.add.single", "onNodesChange.add.many", "onNodesChange.add.many", "onNodesChange.remove", "onNodesChange.remove", "onNodesChange.remove.single", "onNodesChange.remove.single", "onNodesChange.remove.many", "onNodesChange.remove.many", "onNodesChange.select", "onNodesChange.select", "onNodesChange.select.single", "onNodesChange.select.single", "onNodesChange.select.many", "onNodesChange.select.many", "onEdgesChange", "onEdgesChange", "onEdgesChange.detached", "onEdgesChange.detached", "onEdgesChange.detached.single", "onEdgesChange.detached.single", "onEdgesChange.detached.many", "onEdgesChange.detached.many", "onEdgesChange.add", "onEdgesChange.add", "onEdgesChange.add.single", "onEdgesChange.add.single", "onEdgesChange.add.many", "onEdgesChange.add.many", "onEdgesChange.remove", "onEdgesChange.remove", "onEdgesChange.remove.single", "onEdgesChange.remove.single", "onEdgesChange.remove.many", "onEdgesChange.remove.many", "onEdgesChange.select", "onEdgesChange.select", "onEdgesChange.select.single", "onEdgesChange.select.single", "onEdgesChange.select.many", "onEdgesChange.select.many"] }], ngImport: i0, template: "<svg:svg\n rootSvgRef\n rootSvgContext\n rootPointer\n flowSizeController\n class=\"root-svg\"\n #flow\n>\n <defs [markers]=\"markers()\" flowDefs />\n\n <g background />\n\n <svg:g mapContext spacePointContext>\n <!-- Connection -->\n <svg:g\n connection\n [model]=\"connection\"\n [template]=\"connectionTemplateDirective()?.templateRef\"\n />\n\n @if (optimization().detachedGroupsLayer) {\n <!-- Groups -->\n @for (model of groups(); track trackNodes($index, model)) {\n <svg:g\n node\n [nodeModel]=\"model\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\n }\n <!-- Edges -->\n @for (model of edgeModels(); track trackEdges($index, model)) {\n <svg:g\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\"\n />\n }\n <!-- Nodes -->\n @for (model of nonGroups(); track trackNodes($index, model)) {\n <svg:g\n node\n [nodeModel]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\n }\n }\n\n @if (!optimization().detachedGroupsLayer) {\n <!-- Edges -->\n @for (model of edgeModels(); track trackEdges($index, model)) {\n <svg:g\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\"\n />\n }\n <!-- Nodes -->\n @for (model of nodeModels(); track trackNodes($index, model)) {\n <svg:g\n node\n [nodeModel]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\n }\n }\n </svg:g>\n\n <!-- Minimap -->\n @if (minimap(); as minimap) {\n <ng-container [ngTemplateOutlet]=\"minimap.template()\" />\n }\n</svg:svg>\n", styles: [":host{display:block;width:100%;height:100%;-webkit-user-select:none;user-select:none}:host ::ng-deep *{box-sizing:border-box}\n"], dependencies: [{ kind: "directive", type: RootSvgReferenceDirective, selector: "svg[rootSvgRef]" }, { kind: "directive", type: RootSvgContextDirective, selector: "svg[rootSvgContext]" }, { kind: "directive", type: RootPointerDirective, selector: "svg[rootPointer]" }, { kind: "directive", type: FlowSizeControllerDirective, selector: "svg[flowSizeController]" }, { kind: "component", type: DefsComponent, selector: "defs[flowDefs]", inputs: ["markers"] }, { kind: "component", type: BackgroundComponent, selector: "g[background]" }, { kind: "directive", type: MapContextDirective, selector: "g[mapContext]" }, { kind: "directive", type: SpacePointContextDirective, selector: "g[spacePointContext]" }, { kind: "component", type: ConnectionComponent, selector: "g[connection]", inputs: ["model", "template"] }, { kind: "component", type: NodeComponent, selector: "g[node]", inputs: ["nodeModel", "nodeTemplate", "groupNodeTemplate"] }, { kind: "component", type: EdgeComponent, selector: "g[edge]", inputs: ["model", "edgeTemplate", "edgeLabelHtmlTemplate"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3213
3203
  }
3214
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: VflowComponent, decorators: [{
3204
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: VflowComponent, decorators: [{
3215
3205
  type: Component,
3216
- args: [{ selector: 'vflow', changeDetection: ChangeDetectionStrategy.OnPush, providers: [
3206
+ args: [{ standalone: true, selector: 'vflow', changeDetection: ChangeDetectionStrategy.OnPush, providers: [
3217
3207
  DraggableService,
3218
3208
  ViewportService,
3219
3209
  FlowStatusService,
@@ -3225,60 +3215,73 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
3225
3215
  FlowSettingsService,
3226
3216
  ComponentEventBusService,
3227
3217
  KeyboardService,
3228
- OverlaysService
3218
+ OverlaysService,
3229
3219
  ], hostDirectives: [
3230
3220
  connectionControllerHostDirective,
3231
- changesControllerHostDirective
3232
- ], template: "<svg:svg\n rootSvgRef\n rootSvgContext\n rootPointer\n flowSizeController\n class=\"root-svg\"\n #flow\n>\n <defs [markers]=\"markers()\" flowDefs />\n\n <g background />\n\n <svg:g\n mapContext\n spacePointContext\n >\n <!-- Connection -->\n <svg:g\n connection\n [model]=\"connection\"\n [template]=\"connectionTemplateDirective?.templateRef\"\n />\n\n <ng-container *ngIf=\"optimization.detachedGroupsLayer\">\n <!-- Groups -->\n <svg:g\n *ngFor=\"let model of groups(); trackBy: trackNodes\"\n node\n [nodeModel]=\"model\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\n\n <!-- Edges -->\n <svg:g\n *ngFor=\"let model of edgeModels(); trackBy: trackEdges\"\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective?.templateRef\"\n />\n\n <!-- Nodes -->\n <svg:g\n *ngFor=\"let model of nonGroups(); trackBy: trackNodes\"\n node\n [nodeModel]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\n </ng-container>\n\n <ng-container *ngIf=\"!optimization.detachedGroupsLayer\">\n <!-- Edges -->\n <svg:g\n *ngFor=\"let model of edgeModels(); trackBy: trackEdges\"\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective?.templateRef\"\n />\n\n <!-- Nodes -->\n <svg:g\n *ngFor=\"let model of nodeModels(); trackBy: trackNodes\"\n node\n [nodeModel]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective?.templateRef\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\n </ng-container>\n\n </svg:g>\n\n <!-- Minimap -->\n <ng-container *ngIf=\"minimap() as minimap\">\n <ng-container [ngTemplateOutlet]=\"minimap.template()\" />\n </ng-container>\n</svg:svg>\n\n", styles: [":host{display:block;width:100%;height:100%;-webkit-user-select:none;user-select:none}:host ::ng-deep *{box-sizing:border-box}\n"] }]
3221
+ changesControllerHostDirective,
3222
+ ], imports: [
3223
+ RootSvgReferenceDirective,
3224
+ RootSvgContextDirective,
3225
+ RootPointerDirective,
3226
+ FlowSizeControllerDirective,
3227
+ DefsComponent,
3228
+ BackgroundComponent,
3229
+ MapContextDirective,
3230
+ SpacePointContextDirective,
3231
+ ConnectionComponent,
3232
+ NodeComponent,
3233
+ EdgeComponent,
3234
+ NgTemplateOutlet,
3235
+ ], template: "<svg:svg\n rootSvgRef\n rootSvgContext\n rootPointer\n flowSizeController\n class=\"root-svg\"\n #flow\n>\n <defs [markers]=\"markers()\" flowDefs />\n\n <g background />\n\n <svg:g mapContext spacePointContext>\n <!-- Connection -->\n <svg:g\n connection\n [model]=\"connection\"\n [template]=\"connectionTemplateDirective()?.templateRef\"\n />\n\n @if (optimization().detachedGroupsLayer) {\n <!-- Groups -->\n @for (model of groups(); track trackNodes($index, model)) {\n <svg:g\n node\n [nodeModel]=\"model\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\n }\n <!-- Edges -->\n @for (model of edgeModels(); track trackEdges($index, model)) {\n <svg:g\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\"\n />\n }\n <!-- Nodes -->\n @for (model of nonGroups(); track trackNodes($index, model)) {\n <svg:g\n node\n [nodeModel]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\n }\n }\n\n @if (!optimization().detachedGroupsLayer) {\n <!-- Edges -->\n @for (model of edgeModels(); track trackEdges($index, model)) {\n <svg:g\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\"\n />\n }\n <!-- Nodes -->\n @for (model of nodeModels(); track trackNodes($index, model)) {\n <svg:g\n node\n [nodeModel]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\n }\n }\n </svg:g>\n\n <!-- Minimap -->\n @if (minimap(); as minimap) {\n <ng-container [ngTemplateOutlet]=\"minimap.template()\" />\n }\n</svg:svg>\n", styles: [":host{display:block;width:100%;height:100%;-webkit-user-select:none;user-select:none}:host ::ng-deep *{box-sizing:border-box}\n"] }]
3233
3236
  }], propDecorators: { view: [{
3234
3237
  type: Input
3235
3238
  }], minZoom: [{
3236
3239
  type: Input
3237
3240
  }], maxZoom: [{
3238
3241
  type: Input
3239
- }], handlePositions: [{
3240
- type: Input
3241
3242
  }], background: [{
3242
3243
  type: Input
3243
- }], optimization: [{
3244
- type: Input
3245
3244
  }], entitiesSelectable: [{
3246
3245
  type: Input
3247
3246
  }], keyboardShortcuts: [{
3248
3247
  type: Input
3249
3248
  }], connection: [{
3250
3249
  type: Input,
3251
- args: [{ transform: (settings) => new ConnectionModel(settings) }]
3250
+ args: [{
3251
+ transform: (settings) => new ConnectionModel(settings),
3252
+ }]
3252
3253
  }], nodes: [{
3253
3254
  type: Input,
3254
3255
  args: [{ required: true }]
3255
3256
  }], edges: [{
3256
3257
  type: Input
3257
- }], onComponentNodeEvent: [{
3258
- type: Output
3259
- }], nodeTemplateDirective: [{
3260
- type: ContentChild,
3261
- args: [NodeHtmlTemplateDirective]
3262
- }], groupNodeTemplateDirective: [{
3263
- type: ContentChild,
3264
- args: [GroupNodeTemplateDirective]
3265
- }], edgeTemplateDirective: [{
3266
- type: ContentChild,
3267
- args: [EdgeTemplateDirective]
3268
- }], edgeLabelHtmlDirective: [{
3269
- type: ContentChild,
3270
- args: [EdgeLabelHtmlTemplateDirective]
3271
- }], connectionTemplateDirective: [{
3272
- type: ContentChild,
3273
- args: [ConnectionTemplateDirective]
3274
- }], mapContext: [{
3275
- type: ViewChild,
3276
- args: [MapContextDirective]
3277
- }], spacePointContext: [{
3278
- type: ViewChild,
3279
- args: [SpacePointContextDirective]
3280
3258
  }] } });
3281
3259
 
3260
+ class DragHandleDirective {
3261
+ get model() {
3262
+ return this.nodeAccessor.model();
3263
+ }
3264
+ constructor() {
3265
+ this.nodeAccessor = inject(NodeAccessorService);
3266
+ this.model.dragHandlesCount.update((count) => count + 1);
3267
+ inject(DestroyRef).onDestroy(() => {
3268
+ this.model.dragHandlesCount.update(count => count - 1);
3269
+ });
3270
+ }
3271
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DragHandleDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3272
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: DragHandleDirective, isStandalone: true, selector: "[dragHandle]", host: { classAttribute: "vflow-drag-handle" }, ngImport: i0 }); }
3273
+ }
3274
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DragHandleDirective, decorators: [{
3275
+ type: Directive,
3276
+ args: [{
3277
+ standalone: true,
3278
+ selector: '[dragHandle]',
3279
+ host: {
3280
+ 'class': 'vflow-drag-handle'
3281
+ },
3282
+ }]
3283
+ }], ctorParameters: () => [] });
3284
+
3282
3285
  class SelectableDirective {
3283
3286
  constructor() {
3284
3287
  this.flowSettingsService = inject(FlowSettingsService);
@@ -3294,19 +3297,22 @@ class SelectableDirective {
3294
3297
  }
3295
3298
  entity() {
3296
3299
  if (this.parentNode) {
3297
- return this.parentNode.nodeModel;
3300
+ return this.parentNode.nodeModel();
3298
3301
  }
3299
3302
  else if (this.parentEdge) {
3300
- return this.parentEdge.model;
3303
+ return this.parentEdge.model();
3301
3304
  }
3302
3305
  return null;
3303
3306
  }
3304
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SelectableDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3305
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: SelectableDirective, selector: "[selectable]", host: { listeners: { "mousedown": "onMousedown()", "touchstart": "onMousedown()" } }, ngImport: i0 }); }
3307
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SelectableDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3308
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: SelectableDirective, isStandalone: true, selector: "[selectable]", host: { listeners: { "mousedown": "onMousedown()", "touchstart": "onMousedown()" } }, ngImport: i0 }); }
3306
3309
  }
3307
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SelectableDirective, decorators: [{
3310
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SelectableDirective, decorators: [{
3308
3311
  type: Directive,
3309
- args: [{ selector: '[selectable]' }]
3312
+ args: [{
3313
+ standalone: true,
3314
+ selector: '[selectable]',
3315
+ }]
3310
3316
  }], propDecorators: { onMousedown: [{
3311
3317
  type: HostListener,
3312
3318
  args: ['mousedown']
@@ -3330,14 +3336,23 @@ class MiniMapComponent {
3330
3336
  /**
3331
3337
  * The color outside the viewport (invisible area)
3332
3338
  */
3333
- this.maskColor = `rgba(215, 215, 215, 0.6)`;
3339
+ this.maskColor = input(`rgba(215, 215, 215, 0.6)`);
3334
3340
  /**
3335
3341
  * The minimap stroke color
3336
3342
  */
3337
- this.strokeColor = `rgb(200, 200, 200)`;
3343
+ this.strokeColor = input(`rgb(200, 200, 200)`);
3344
+ /**
3345
+ * The corner of the flow where to render a mini-map
3346
+ */
3347
+ this.position = input('bottom-right');
3348
+ /**
3349
+ * Make a minimap bigger on hover
3350
+ */
3351
+ this.scaleOnHover = input(false);
3352
+ this.minimap = viewChild.required('minimap');
3338
3353
  this.minimapOffset = 10;
3339
3354
  this.minimapScale = computed(() => {
3340
- if (this.scaleOnHoverSignal()) {
3355
+ if (this.scaleOnHover()) {
3341
3356
  return this.hovered() ? 0.4 : 0.2;
3342
3357
  }
3343
3358
  return 0.2;
@@ -3351,23 +3366,31 @@ class MiniMapComponent {
3351
3366
  });
3352
3367
  this.hovered = signal(false);
3353
3368
  this.minimapPoint = computed(() => {
3354
- switch (this.minimapPosition()) {
3369
+ switch (this.position()) {
3355
3370
  case 'top-left':
3356
3371
  return { x: this.minimapOffset, y: this.minimapOffset };
3357
3372
  case 'top-right':
3358
3373
  return {
3359
- x: this.flowSettingsService.computedFlowWidth() - this.minimapWidth() - this.minimapOffset,
3360
- y: this.minimapOffset
3374
+ x: this.flowSettingsService.computedFlowWidth() -
3375
+ this.minimapWidth() -
3376
+ this.minimapOffset,
3377
+ y: this.minimapOffset,
3361
3378
  };
3362
3379
  case 'bottom-left':
3363
3380
  return {
3364
3381
  x: this.minimapOffset,
3365
- y: this.flowSettingsService.computedFlowHeight() - this.minimapHeight() - this.minimapOffset
3382
+ y: this.flowSettingsService.computedFlowHeight() -
3383
+ this.minimapHeight() -
3384
+ this.minimapOffset,
3366
3385
  };
3367
3386
  case 'bottom-right':
3368
3387
  return {
3369
- x: this.flowSettingsService.computedFlowWidth() - this.minimapWidth() - this.minimapOffset,
3370
- y: this.flowSettingsService.computedFlowHeight() - this.minimapHeight() - this.minimapOffset
3388
+ x: this.flowSettingsService.computedFlowWidth() -
3389
+ this.minimapWidth() -
3390
+ this.minimapOffset,
3391
+ y: this.flowSettingsService.computedFlowHeight() -
3392
+ this.minimapHeight() -
3393
+ this.minimapOffset,
3371
3394
  };
3372
3395
  }
3373
3396
  });
@@ -3394,47 +3417,22 @@ class MiniMapComponent {
3394
3417
  const scale = vport.zoom * this.minimapScale();
3395
3418
  return `translate(${x} ${y}) scale(${scale})`;
3396
3419
  });
3397
- this.minimapPosition = signal('bottom-right');
3398
- this.scaleOnHoverSignal = signal(false);
3399
- }
3400
- /**
3401
- * The corner of the flow where to render a mini-map
3402
- */
3403
- set position(value) {
3404
- this.minimapPosition.set(value);
3405
- }
3406
- /**
3407
- * Make a minimap bigger on hover
3408
- */
3409
- set scaleOnHover(value) {
3410
- this.scaleOnHoverSignal.set(value);
3411
3420
  }
3412
3421
  ngOnInit() {
3413
3422
  const model = new MinimapModel();
3414
- model.template.set(this.minimap);
3423
+ model.template.set(this.minimap());
3415
3424
  this.entitiesService.minimap.set(model);
3416
3425
  }
3417
3426
  trackNodes(idx, { node }) {
3418
3427
  return node;
3419
3428
  }
3420
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MiniMapComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3421
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: MiniMapComponent, selector: "mini-map", inputs: { position: "position", maskColor: "maskColor", strokeColor: "strokeColor", scaleOnHover: "scaleOnHover" }, viewQueries: [{ propertyName: "minimap", first: true, predicate: ["minimap"], descendants: true, static: true }], ngImport: i0, template: "<ng-template #minimap>\n <svg:rect\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n [attr.stroke]=\"strokeColor\"\n fill=\"none\"\n />\n\n <svg:svg\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n (mouseover)=\"hovered.set(true)\"\n (mouseleave)=\"hovered.set(false)\"\n >\n <svg:rect\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n [attr.fill]=\"maskColor\"\n />\n\n <svg:g [attr.transform]=\"minimapTransform()\">\n <svg:rect\n [attr.fill]=\"viewportColor()\"\n [attr.transform]=\"viewportTransform()\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n />\n\n <ng-container\n *ngFor=\"let model of entitiesService.nodes(); trackBy: trackNodes\"\n >\n <svg:foreignObject\n *ngIf=\"model.node.type === 'default' || model.node.type === 'html-template' || model.isComponentType\"\n [attr.transform]=\"model.pointTransform()\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\"\n >\n <default-node\n [selected]=\"model.selected()\"\n [style.width.px]=\"model.size().width\"\n [style.height.px]=\"model.size().height\"\n [style.max-width.px]=\"model.size().width\"\n [style.max-height.px]=\"model.size().height\"\n >\n <div [outerHTML]=\"model.text()\"></div>\n </default-node>\n </svg:foreignObject>\n\n <svg:rect\n *ngIf=\"model.node.type === 'default-group' || model.node.type === 'template-group'\"\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [attr.transform]=\"model.pointTransform()\"\n [class.default-group-node_selected]=\"model.selected()\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\"\n [style.stroke]=\"model.color()\"\n [style.fill]=\"model.color()\"\n />\n\n </ng-container>\n </svg:g>\n </svg:svg>\n</ng-template>\n", styles: [".default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: DefaultNodeComponent, selector: "default-node", inputs: ["selected"] }] }); }
3429
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MiniMapComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3430
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: MiniMapComponent, isStandalone: true, selector: "mini-map", inputs: { maskColor: { classPropertyName: "maskColor", publicName: "maskColor", isSignal: true, isRequired: false, transformFunction: null }, strokeColor: { classPropertyName: "strokeColor", publicName: "strokeColor", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, scaleOnHover: { classPropertyName: "scaleOnHover", publicName: "scaleOnHover", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "minimap", first: true, predicate: ["minimap"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template #minimap>\n <svg:rect\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n [attr.stroke]=\"strokeColor()\"\n fill=\"none\"\n />\n\n <svg:svg\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n (mouseover)=\"hovered.set(true)\"\n (mouseleave)=\"hovered.set(false)\"\n >\n <svg:rect\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n [attr.fill]=\"maskColor()\"\n />\n\n <svg:g [attr.transform]=\"minimapTransform()\">\n <svg:rect\n [attr.fill]=\"viewportColor()\"\n [attr.transform]=\"viewportTransform()\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n />\n\n @for (model of entitiesService.nodes(); track trackNodes($index, model)) {\n <ng-container>\n @if (\n model.node.type === \"default\" ||\n model.node.type === \"html-template\" ||\n model.isComponentType\n ) {\n <svg:foreignObject\n [attr.transform]=\"model.pointTransform()\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\"\n >\n <default-node\n [selected]=\"model.selected()\"\n [style.width.px]=\"model.size().width\"\n [style.height.px]=\"model.size().height\"\n [style.max-width.px]=\"model.size().width\"\n [style.max-height.px]=\"model.size().height\"\n >\n <div [outerHTML]=\"model.text()\"></div>\n </default-node>\n </svg:foreignObject>\n }\n @if (\n model.node.type === \"default-group\" ||\n model.node.type === \"template-group\"\n ) {\n <svg:rect\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [attr.transform]=\"model.pointTransform()\"\n [class.default-group-node_selected]=\"model.selected()\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\"\n [style.stroke]=\"model.color()\"\n [style.fill]=\"model.color()\"\n />\n }\n </ng-container>\n }\n </svg:g>\n </svg:svg>\n</ng-template>\n", styles: [".default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}\n"], dependencies: [{ kind: "component", type: DefaultNodeComponent, selector: "default-node", inputs: ["selected"] }] }); }
3422
3431
  }
3423
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MiniMapComponent, decorators: [{
3432
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MiniMapComponent, decorators: [{
3424
3433
  type: Component,
3425
- args: [{ selector: 'mini-map', template: "<ng-template #minimap>\n <svg:rect\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n [attr.stroke]=\"strokeColor\"\n fill=\"none\"\n />\n\n <svg:svg\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n (mouseover)=\"hovered.set(true)\"\n (mouseleave)=\"hovered.set(false)\"\n >\n <svg:rect\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n [attr.fill]=\"maskColor\"\n />\n\n <svg:g [attr.transform]=\"minimapTransform()\">\n <svg:rect\n [attr.fill]=\"viewportColor()\"\n [attr.transform]=\"viewportTransform()\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n />\n\n <ng-container\n *ngFor=\"let model of entitiesService.nodes(); trackBy: trackNodes\"\n >\n <svg:foreignObject\n *ngIf=\"model.node.type === 'default' || model.node.type === 'html-template' || model.isComponentType\"\n [attr.transform]=\"model.pointTransform()\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\"\n >\n <default-node\n [selected]=\"model.selected()\"\n [style.width.px]=\"model.size().width\"\n [style.height.px]=\"model.size().height\"\n [style.max-width.px]=\"model.size().width\"\n [style.max-height.px]=\"model.size().height\"\n >\n <div [outerHTML]=\"model.text()\"></div>\n </default-node>\n </svg:foreignObject>\n\n <svg:rect\n *ngIf=\"model.node.type === 'default-group' || model.node.type === 'template-group'\"\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [attr.transform]=\"model.pointTransform()\"\n [class.default-group-node_selected]=\"model.selected()\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\"\n [style.stroke]=\"model.color()\"\n [style.fill]=\"model.color()\"\n />\n\n </ng-container>\n </svg:g>\n </svg:svg>\n</ng-template>\n", styles: [".default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}\n"] }]
3426
- }], propDecorators: { position: [{
3427
- type: Input
3428
- }], maskColor: [{
3429
- type: Input
3430
- }], strokeColor: [{
3431
- type: Input
3432
- }], scaleOnHover: [{
3433
- type: Input
3434
- }], minimap: [{
3435
- type: ViewChild,
3436
- args: ['minimap', { static: true }]
3437
- }] } });
3434
+ args: [{ standalone: true, selector: 'mini-map', imports: [DefaultNodeComponent], template: "<ng-template #minimap>\n <svg:rect\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n [attr.stroke]=\"strokeColor()\"\n fill=\"none\"\n />\n\n <svg:svg\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n (mouseover)=\"hovered.set(true)\"\n (mouseleave)=\"hovered.set(false)\"\n >\n <svg:rect\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n [attr.fill]=\"maskColor()\"\n />\n\n <svg:g [attr.transform]=\"minimapTransform()\">\n <svg:rect\n [attr.fill]=\"viewportColor()\"\n [attr.transform]=\"viewportTransform()\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n />\n\n @for (model of entitiesService.nodes(); track trackNodes($index, model)) {\n <ng-container>\n @if (\n model.node.type === \"default\" ||\n model.node.type === \"html-template\" ||\n model.isComponentType\n ) {\n <svg:foreignObject\n [attr.transform]=\"model.pointTransform()\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\"\n >\n <default-node\n [selected]=\"model.selected()\"\n [style.width.px]=\"model.size().width\"\n [style.height.px]=\"model.size().height\"\n [style.max-width.px]=\"model.size().width\"\n [style.max-height.px]=\"model.size().height\"\n >\n <div [outerHTML]=\"model.text()\"></div>\n </default-node>\n </svg:foreignObject>\n }\n @if (\n model.node.type === \"default-group\" ||\n model.node.type === \"template-group\"\n ) {\n <svg:rect\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [attr.transform]=\"model.pointTransform()\"\n [class.default-group-node_selected]=\"model.selected()\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\"\n [style.stroke]=\"model.color()\"\n [style.fill]=\"model.color()\"\n />\n }\n </ng-container>\n }\n </svg:g>\n </svg:svg>\n</ng-template>\n", styles: [".default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}\n"] }]
3435
+ }] });
3438
3436
 
3439
3437
  class ToolbarModel {
3440
3438
  constructor(node) {
@@ -3475,114 +3473,67 @@ class NodeToolbarComponent {
3475
3473
  constructor() {
3476
3474
  this.overlaysService = inject(OverlaysService);
3477
3475
  this.nodeService = inject(NodeAccessorService);
3476
+ this.position = input('top');
3477
+ this.toolbarContentTemplate = viewChild.required('toolbar');
3478
3478
  this.model = new ToolbarModel(this.nodeService.model());
3479
- }
3480
- set position(value) {
3481
- this.model.position.set(value);
3479
+ effect(() => this.model.position.set(this.position()), { allowSignalWrites: true });
3482
3480
  }
3483
3481
  ngOnInit() {
3484
- this.model.template.set(this.toolbarContentTemplate);
3482
+ this.model.template.set(this.toolbarContentTemplate());
3485
3483
  this.overlaysService.addToolbar(this.model);
3486
3484
  }
3487
3485
  ngOnDestroy() {
3488
3486
  this.overlaysService.removeToolbar(this.model);
3489
3487
  }
3490
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3491
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NodeToolbarComponent, selector: "node-toolbar", inputs: { position: "position" }, viewQueries: [{ propertyName: "toolbarContentTemplate", first: true, predicate: ["toolbar"], descendants: true, static: true }], ngImport: i0, template: `
3488
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3489
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "17.3.12", type: NodeToolbarComponent, isStandalone: true, selector: "node-toolbar", inputs: { position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "toolbarContentTemplate", first: true, predicate: ["toolbar"], descendants: true, isSignal: true }], ngImport: i0, template: `
3492
3490
  <ng-template #toolbar>
3493
3491
  <div class="wrapper" nodeToolbarWrapper [model]="model">
3494
3492
  <ng-content />
3495
3493
  </div>
3496
3494
  </ng-template>
3497
- `, isInline: true, styles: [".wrapper{width:max-content}\n"], dependencies: [{ kind: "directive", type: i0.forwardRef(function () { return NodeToolbarWrapperDirective; }), selector: "[nodeToolbarWrapper]", inputs: ["model"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3495
+ `, isInline: true, styles: [".wrapper{width:max-content}\n"], dependencies: [{ kind: "directive", type: i0.forwardRef(() => NodeToolbarWrapperDirective), selector: "[nodeToolbarWrapper]", inputs: ["model"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3498
3496
  }
3499
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeToolbarComponent, decorators: [{
3497
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeToolbarComponent, decorators: [{
3500
3498
  type: Component,
3501
- args: [{ selector: 'node-toolbar', template: `
3499
+ args: [{ standalone: true, selector: 'node-toolbar', template: `
3502
3500
  <ng-template #toolbar>
3503
3501
  <div class="wrapper" nodeToolbarWrapper [model]="model">
3504
3502
  <ng-content />
3505
3503
  </div>
3506
3504
  </ng-template>
3507
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".wrapper{width:max-content}\n"] }]
3508
- }], propDecorators: { position: [{
3509
- type: Input
3510
- }], toolbarContentTemplate: [{
3511
- type: ViewChild,
3512
- args: ['toolbar', { static: true }]
3513
- }] } });
3505
+ `, changeDetection: ChangeDetectionStrategy.OnPush, imports: [forwardRef(() => NodeToolbarWrapperDirective)], styles: [".wrapper{width:max-content}\n"] }]
3506
+ }], ctorParameters: () => [] });
3514
3507
  class NodeToolbarWrapperDirective {
3515
3508
  constructor() {
3516
3509
  this.element = inject(ElementRef);
3510
+ this.model = input.required();
3517
3511
  }
3518
3512
  ngOnInit() {
3519
- this.model.size.set({
3513
+ this.model().size.set({
3520
3514
  width: this.element.nativeElement.clientWidth,
3521
- height: this.element.nativeElement.clientHeight
3515
+ height: this.element.nativeElement.clientHeight,
3522
3516
  });
3523
3517
  }
3524
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeToolbarWrapperDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3525
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: NodeToolbarWrapperDirective, selector: "[nodeToolbarWrapper]", inputs: { model: "model" }, ngImport: i0 }); }
3518
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeToolbarWrapperDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3519
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "17.3.12", type: NodeToolbarWrapperDirective, isStandalone: true, selector: "[nodeToolbarWrapper]", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 }); }
3526
3520
  }
3527
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeToolbarWrapperDirective, decorators: [{
3528
- type: Directive,
3529
- args: [{ selector: '[nodeToolbarWrapper]' }]
3530
- }], propDecorators: { model: [{
3531
- type: Input
3532
- }] } });
3533
-
3534
- class DragHandleDirective {
3535
- get model() {
3536
- return this.nodeAccessor.model();
3537
- }
3538
- constructor() {
3539
- this.nodeAccessor = inject(NodeAccessorService);
3540
- this.model.dragHandlesCount.update((count) => count + 1);
3541
- inject(DestroyRef).onDestroy(() => {
3542
- this.model.dragHandlesCount.update(count => count - 1);
3543
- });
3544
- }
3545
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DragHandleDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3546
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: DragHandleDirective, selector: "[dragHandle]", host: { classAttribute: "vflow-drag-handle" }, ngImport: i0 }); }
3547
- }
3548
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DragHandleDirective, decorators: [{
3521
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeToolbarWrapperDirective, decorators: [{
3549
3522
  type: Directive,
3550
3523
  args: [{
3551
- selector: '[dragHandle]',
3552
- host: {
3553
- 'class': 'vflow-drag-handle'
3554
- }
3524
+ selector: '[nodeToolbarWrapper]',
3525
+ standalone: true
3555
3526
  }]
3556
- }], ctorParameters: function () { return []; } });
3527
+ }] });
3557
3528
 
3558
- const components = [
3529
+ const Vflow = [
3559
3530
  VflowComponent,
3560
- NodeComponent,
3561
- DefaultNodeComponent,
3562
- EdgeComponent,
3563
- EdgeLabelComponent,
3564
- ConnectionComponent,
3565
3531
  HandleComponent,
3566
- DefsComponent,
3567
- BackgroundComponent,
3568
3532
  ResizableComponent,
3569
- MiniMapComponent,
3570
- NodeToolbarComponent
3571
- ];
3572
- const directives = [
3573
- SpacePointContextDirective,
3574
- MapContextDirective,
3575
- RootSvgReferenceDirective,
3576
- RootSvgContextDirective,
3577
- HandleSizeControllerDirective,
3578
3533
  SelectableDirective,
3534
+ MiniMapComponent,
3535
+ NodeToolbarComponent,
3579
3536
  DragHandleDirective,
3580
- PointerDirective,
3581
- RootPointerDirective,
3582
- FlowSizeControllerDirective,
3583
- NodeToolbarWrapperDirective
3584
- ];
3585
- const templateDirectives = [
3586
3537
  NodeHtmlTemplateDirective,
3587
3538
  GroupNodeTemplateDirective,
3588
3539
  EdgeLabelHtmlTemplateDirective,
@@ -3590,65 +3541,6 @@ const templateDirectives = [
3590
3541
  ConnectionTemplateDirective,
3591
3542
  HandleTemplateDirective
3592
3543
  ];
3593
- class VflowModule {
3594
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: VflowModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
3595
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: VflowModule, declarations: [VflowComponent,
3596
- NodeComponent,
3597
- DefaultNodeComponent,
3598
- EdgeComponent,
3599
- EdgeLabelComponent,
3600
- ConnectionComponent,
3601
- HandleComponent,
3602
- DefsComponent,
3603
- BackgroundComponent,
3604
- ResizableComponent,
3605
- MiniMapComponent,
3606
- NodeToolbarComponent, SpacePointContextDirective,
3607
- MapContextDirective,
3608
- RootSvgReferenceDirective,
3609
- RootSvgContextDirective,
3610
- HandleSizeControllerDirective,
3611
- SelectableDirective,
3612
- DragHandleDirective,
3613
- PointerDirective,
3614
- RootPointerDirective,
3615
- FlowSizeControllerDirective,
3616
- NodeToolbarWrapperDirective, NodeHtmlTemplateDirective,
3617
- GroupNodeTemplateDirective,
3618
- EdgeLabelHtmlTemplateDirective,
3619
- EdgeTemplateDirective,
3620
- ConnectionTemplateDirective,
3621
- HandleTemplateDirective], imports: [NgIf, NgFor, NgTemplateOutlet, NgComponentOutlet, KeyValuePipe], exports: [VflowComponent,
3622
- HandleComponent,
3623
- ResizableComponent,
3624
- SelectableDirective,
3625
- MiniMapComponent,
3626
- NodeToolbarComponent,
3627
- DragHandleDirective, NodeHtmlTemplateDirective,
3628
- GroupNodeTemplateDirective,
3629
- EdgeLabelHtmlTemplateDirective,
3630
- EdgeTemplateDirective,
3631
- ConnectionTemplateDirective,
3632
- HandleTemplateDirective] }); }
3633
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: VflowModule }); }
3634
- }
3635
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: VflowModule, decorators: [{
3636
- type: NgModule,
3637
- args: [{
3638
- imports: [NgIf, NgFor, NgTemplateOutlet, NgComponentOutlet, KeyValuePipe],
3639
- exports: [
3640
- VflowComponent,
3641
- HandleComponent,
3642
- ResizableComponent,
3643
- SelectableDirective,
3644
- MiniMapComponent,
3645
- NodeToolbarComponent,
3646
- DragHandleDirective,
3647
- ...templateDirectives
3648
- ],
3649
- declarations: [...components, ...directives, ...templateDirectives],
3650
- }]
3651
- }] });
3652
3544
 
3653
3545
  const mockModel = () => new NodeModel({ id: 'mock', type: 'default', point: { x: 0, y: 0 } });
3654
3546
  function provideCustomNodeMocks() {
@@ -3705,11 +3597,11 @@ function provideCustomNodeMocks() {
3705
3597
  ];
3706
3598
  }
3707
3599
 
3708
- // Modules
3600
+ // Standalone Util
3709
3601
 
3710
3602
  /**
3711
3603
  * Generated bundle index. Do not edit.
3712
3604
  */
3713
3605
 
3714
- export { ChangesControllerDirective, ConnectionControllerDirective, ConnectionTemplateDirective, CustomDynamicNodeComponent, CustomNodeComponent, DragHandleDirective, EdgeLabelHtmlTemplateDirective, EdgeTemplateDirective, GroupNodeTemplateDirective, HandleComponent, HandleTemplateDirective, MiniMapComponent, NodeHtmlTemplateDirective, NodeToolbarComponent, NodeToolbarWrapperDirective, ResizableComponent, SelectableDirective, VflowComponent, VflowModule, isComponentDynamicNode, isComponentStaticNode, isDefaultDynamicGroupNode, isDefaultDynamicNode, isDefaultStaticGroupNode, isDefaultStaticNode, isDynamicNode, isStaticNode, isTemplateDynamicGroupNode, isTemplateDynamicNode, isTemplateStaticGroupNode, isTemplateStaticNode, provideCustomNodeMocks };
3606
+ export { ChangesControllerDirective, ConnectionControllerDirective, ConnectionTemplateDirective, CustomDynamicNodeComponent, CustomNodeComponent, DragHandleDirective, EdgeLabelHtmlTemplateDirective, EdgeTemplateDirective, GroupNodeTemplateDirective, HandleComponent, HandleTemplateDirective, MiniMapComponent, NodeHtmlTemplateDirective, NodeToolbarComponent, NodeToolbarWrapperDirective, ResizableComponent, SelectableDirective, Vflow, VflowComponent, isComponentDynamicNode, isComponentStaticNode, isDefaultDynamicGroupNode, isDefaultDynamicNode, isDefaultStaticGroupNode, isDefaultStaticNode, isDynamicNode, isStaticNode, isTemplateDynamicGroupNode, isTemplateDynamicNode, isTemplateStaticGroupNode, isTemplateStaticNode, provideCustomNodeMocks };
3715
3607
  //# sourceMappingURL=ngx-vflow.mjs.map