@foblex/flow 1.0.1 → 1.0.3

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 (35) hide show
  1. package/esm2022/lib/components/f-connection/f-connection-base.mjs +6 -1
  2. package/esm2022/lib/components/f-connection/f-path/f-connection-path.component.mjs +4 -1
  3. package/esm2022/lib/components/f-flow/f-flow-base.mjs +9 -14
  4. package/esm2022/lib/components/f-flow/f-flow.component.mjs +6 -6
  5. package/esm2022/lib/components/f-node/f-node-base.mjs +7 -2
  6. package/esm2022/lib/components/f-node/f-node.component.mjs +1 -2
  7. package/esm2022/lib/components/f-node/index.mjs +2 -1
  8. package/esm2022/lib/components/f-node/is-node.mjs +4 -0
  9. package/esm2022/lib/directives/f-containers/f-items-container/canvas-change.event.mjs +7 -0
  10. package/esm2022/lib/directives/f-containers/f-items-container/f-items-container-base.mjs +5 -4
  11. package/esm2022/lib/directives/f-containers/f-items-container/f-items-container.directive.mjs +20 -3
  12. package/esm2022/lib/directives/f-containers/f-items-container/index.mjs +2 -1
  13. package/esm2022/lib/directives/f-containers/f-items-container/public-api.mjs +2 -1
  14. package/esm2022/lib/directives/f-draggable/connections/reassign-connection/reassign-on-pointer-up/reassign-connection.on-pointer-up.mjs +4 -1
  15. package/esm2022/lib/directives/f-draggable/selection/selection-on-pointer-down/selection.on-pointer-down.mjs +7 -6
  16. package/esm2022/lib/directives/f-zoom/f-zoom-base.mjs +5 -3
  17. package/esm2022/lib/f-flow.module.mjs +2 -2
  18. package/esm2022/lib/i-selectable.mjs +1 -1
  19. package/fesm2022/foblex-flow.mjs +497 -460
  20. package/fesm2022/foblex-flow.mjs.map +1 -1
  21. package/lib/components/f-connection/f-connection-base.d.ts +5 -1
  22. package/lib/components/f-connection/f-path/f-connection-path.component.d.ts +1 -0
  23. package/lib/components/f-flow/f-flow-base.d.ts +4 -4
  24. package/lib/components/f-flow/f-flow.component.d.ts +4 -4
  25. package/lib/components/f-node/f-node-base.d.ts +2 -0
  26. package/lib/components/f-node/f-node.component.d.ts +0 -1
  27. package/lib/components/f-node/index.d.ts +1 -0
  28. package/lib/components/f-node/is-node.d.ts +1 -0
  29. package/lib/directives/f-containers/f-items-container/canvas-change.event.d.ts +6 -0
  30. package/lib/directives/f-containers/f-items-container/f-items-container-base.d.ts +2 -1
  31. package/lib/directives/f-containers/f-items-container/f-items-container.directive.d.ts +6 -2
  32. package/lib/directives/f-containers/f-items-container/index.d.ts +1 -0
  33. package/lib/directives/f-containers/f-items-container/public-api.d.ts +1 -0
  34. package/lib/i-selectable.d.ts +1 -0
  35. package/package.json +3 -2
@@ -1,7 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, Directive, Component, ChangeDetectionStrategy, Input, ViewChild, EventEmitter, Output, NgModule, Inject, Optional, SkipSelf, ContentChildren, ContentChild, Injectable } from '@angular/core';
2
+ import { InjectionToken, Directive, Component, ChangeDetectionStrategy, Input, ViewChild, Inject, NgModule, Optional, SkipSelf, EventEmitter, ContentChildren, ContentChild, Output, Injectable } from '@angular/core';
3
3
  import { VectorExtensions, Point, PointExtensions, TransformModelExtensions, RectExtensions, SizeExtensions, BooleanExtensions, FResizeObserver, RectFElement, DomElementExtensions, MouseEventExtensions, IDragAndDropBase, LineFElement, EventExtensions } from '@foblex/core';
4
- import { Subject, merge, startWith, takeUntil, defer, switchMap, take, Subscription, debounceTime } from 'rxjs';
4
+ import { Subject, Subscription, startWith, debounceTime, defer, switchMap, merge, take, takeUntil } from 'rxjs';
5
5
  import * as i2 from '@angular/common';
6
6
  import { CommonModule } from '@angular/common';
7
7
 
@@ -12,6 +12,7 @@ class FConnectionBase {
12
12
  constructor() {
13
13
  this.path = '';
14
14
  this.vector = VectorExtensions.initialize();
15
+ this.stateChanges = new Subject();
15
16
  }
16
17
  initialize() {
17
18
  }
@@ -24,6 +25,9 @@ class FConnectionBase {
24
25
  select() {
25
26
  this.hostElement.classList.add(F_SELECTED_CLASS);
26
27
  }
28
+ isSelected() {
29
+ return this.hostElement.classList.contains(F_SELECTED_CLASS);
30
+ }
27
31
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FConnectionBase, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
28
32
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.4", type: FConnectionBase, ngImport: i0 }); }
29
33
  }
@@ -85,6 +89,9 @@ class FConnectionPathComponent {
85
89
  this.hostElement.setAttribute('marker-end', `url(#connection-marker-end)`);
86
90
  }
87
91
  }
92
+ isSelected() {
93
+ return this.hostElement.getAttribute('marker-start') === `url(#connection-marker-start-selected)`;
94
+ }
88
95
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FConnectionPathComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
89
96
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.4", type: FConnectionPathComponent, selector: "path[f-connection-path]", inputs: { fromTo: "fromTo" }, host: { properties: { "attr.id": "attrConnectionId", "attr.stroke": "linkToGradient" }, classAttribute: "f-component f-connection-path" }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
90
97
  }
@@ -393,205 +400,97 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImpor
393
400
  }]
394
401
  }], ctorParameters: function () { return [{ type: i0.ElementRef }]; } });
395
402
 
396
- function mixinChangeZoom(base) {
397
- return class extends base {
398
- setZoom(scaleValue, toPosition) {
399
- if (scaleValue !== this.transform.scale) {
400
- const summaryPosition = PointExtensions.sum(this.transform.scaledPosition, this.transform.position);
401
- const newX = toPosition.x - (toPosition.x - summaryPosition.x) * scaleValue / this.transform.scale;
402
- const newY = toPosition.y - (toPosition.y - summaryPosition.y) * scaleValue / this.transform.scale;
403
- this.transform.scale = scaleValue;
404
- this.transform.scaledPosition = PointExtensions.sub(PointExtensions.initialize(newX, newY), this.transform.position);
405
- }
406
- }
407
- setScalePosition(value) {
408
- this.transform.scaledPosition = value;
409
- }
410
- resetZoom() {
411
- this.transform.scale = 1;
412
- this.transform.scaledPosition = PointExtensions.initialize();
413
- }
414
- constructor(...args) {
415
- super(...args);
416
- }
417
- };
418
- }
419
-
420
- function mixinFitToParent(base) {
421
- return class extends base {
422
- fitToParent(rect, parentRect, points) {
423
- this.transform.scaledPosition = PointExtensions.initialize();
424
- this.transform.position = this.getZeroPositionWithoutScale(points);
425
- const itemsContainerWidth = rect.width / this.transform.scale;
426
- const itemsContainerHeight = rect.height / this.transform.scale;
427
- if ((itemsContainerWidth > parentRect.width || itemsContainerHeight > parentRect.height) ||
428
- itemsContainerWidth < parentRect.width && itemsContainerHeight < parentRect.height) {
429
- this.transform.scale = Math.min(parentRect.width / itemsContainerWidth, parentRect.height / itemsContainerHeight);
430
- }
431
- const newX = (parentRect.width - itemsContainerWidth * this.transform.scale) / 2 - this.transform.position.x * this.transform.scale;
432
- const newY = (parentRect.height - itemsContainerHeight * this.transform.scale) / 2 - this.transform.position.y * this.transform.scale;
433
- this.transform.position = PointExtensions.initialize(newX, newY);
434
- }
435
- getZeroPositionWithoutScale(points) {
436
- const xPoint = points.length ? Math.min(...points.map((point) => point.x)) : 0;
437
- const yPoint = points.length ? Math.min(...points.map((point) => point.y)) : 0;
438
- return PointExtensions.initialize(xPoint, yPoint);
439
- }
440
- constructor(...args) {
441
- super(...args);
442
- }
443
- };
444
- }
445
-
446
- function mixinOneToOneCentering(base) {
447
- return class extends base {
448
- oneToOneCentering(rect, parentRect, points) {
449
- this.transform.scaledPosition = PointExtensions.initialize();
450
- this.transform.position = this.getZeroPositionWithoutScale(points);
451
- const itemsContainerWidth = rect.width / this.transform.scale;
452
- const itemsContainerHeight = rect.height / this.transform.scale;
453
- this.transform.scale = 1;
454
- const newX = (parentRect.width - itemsContainerWidth * this.transform.scale) / 2 - this.transform.position.x * this.transform.scale;
455
- const newY = (parentRect.height - itemsContainerHeight * this.transform.scale) / 2 - this.transform.position.y * this.transform.scale;
456
- this.transform.position = PointExtensions.initialize(newX, newY);
457
- }
458
- getZeroPositionWithoutScale(points) {
459
- const xPoint = points.length ? Math.min(...points.map((point) => point.x)) : 0;
460
- const yPoint = points.length ? Math.min(...points.map((point) => point.y)) : 0;
461
- return PointExtensions.initialize(xPoint, yPoint);
462
- }
463
- constructor(...args) {
464
- super(...args);
465
- }
466
- };
467
- }
468
-
469
- function mixinChangePosition(base) {
470
- return class extends base {
471
- getPosition() {
472
- return this.transform.position;
473
- }
474
- setPosition(position) {
475
- this.transform.position = PointExtensions.copy(position);
476
- }
477
- constructor(...args) {
478
- super(...args);
479
- }
480
- };
481
- }
482
-
483
- const F_ITEMS_CONTAINER = new InjectionToken('F_ITEMS_CONTAINER');
484
- const MIXIN_BASE = mixinChangePosition(mixinFitToParent(mixinOneToOneCentering(mixinChangeZoom(class {
485
- constructor(transform) {
486
- this.transform = transform;
487
- }
488
- }))));
489
- class FItemsContainerBase extends MIXIN_BASE {
403
+ const F_BACKGROUND = new InjectionToken('F_BACKGROUND');
404
+ class FBackgroundBase {
490
405
  get hostElement() {
491
406
  return this.elementReference.nativeElement;
492
407
  }
493
- constructor(elementReference) {
494
- super(TransformModelExtensions.default());
408
+ constructor(elementReference, fCanvas) {
495
409
  this.elementReference = elementReference;
496
- this.parseData();
497
- }
498
- parseData() {
499
- const transform = TransformModelExtensions.fromString(this.hostElement.getAttribute("transform"));
500
- this.transform = transform ? transform : this.transform;
501
- }
502
- redraw() {
503
- this.hostElement.setAttribute("transform", TransformModelExtensions.toString(this.transform));
504
- }
505
- redrawWithAnimation() {
506
- this.hostElement.setAttribute("style", 'transition: transform 0.15s ease-in-out');
507
- this.redraw();
508
- setTimeout(() => {
509
- this.hostElement.removeAttribute("style");
510
- }, 150);
410
+ this.fCanvas = fCanvas;
411
+ this.transform = TransformModelExtensions.default();
412
+ console.log('FBackgroundBase');
511
413
  }
512
- completeDrag() {
513
- // const position = PointExtensions.sum(this.transform.position, this.transform.scaledPosition);
514
- this.canvasChange.emit();
414
+ isBackgroundElement(element) {
415
+ return this.hostElement === element || this.hostElement.contains(element) || this.fCanvas.hostElement.contains(element);
515
416
  }
516
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FItemsContainerBase, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
517
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.4", type: FItemsContainerBase, usesInheritance: true, ngImport: i0 }); }
417
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FBackgroundBase, deps: [{ token: i0.ElementRef }, { token: FCanvasBase }], target: i0.ɵɵFactoryTarget.Directive }); }
418
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.4", type: FBackgroundBase, ngImport: i0 }); }
518
419
  }
519
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FItemsContainerBase, decorators: [{
420
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FBackgroundBase, decorators: [{
520
421
  type: Directive
521
- }], ctorParameters: function () { return [{ type: i0.ElementRef }]; } });
422
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: FCanvasBase }]; } });
522
423
 
523
- class FItemsContainerDirective extends FItemsContainerBase {
524
- constructor(elementReference) {
525
- super(elementReference);
526
- this.canvasChange = new EventEmitter();
424
+ class FBackgroundDirective extends FBackgroundBase {
425
+ constructor(elementReference, fCanvas) {
426
+ super(elementReference, fCanvas);
527
427
  }
528
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FItemsContainerDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
529
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.4", type: FItemsContainerDirective, selector: "g[fItemsContainer]", outputs: { canvasChange: "canvasChange" }, host: { classAttribute: "f-items-container" }, providers: [{ provide: F_ITEMS_CONTAINER, useExisting: FItemsContainerDirective }], exportAs: ["fComponent"], usesInheritance: true, ngImport: i0 }); }
428
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FBackgroundDirective, deps: [{ token: i0.ElementRef }, { token: F_CANVAS }], target: i0.ɵɵFactoryTarget.Directive }); }
429
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.4", type: FBackgroundDirective, isStandalone: true, selector: "g[fBackground]", providers: [{ provide: F_BACKGROUND, useExisting: FBackgroundDirective }], usesInheritance: true, ngImport: i0 }); }
530
430
  }
531
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FItemsContainerDirective, decorators: [{
431
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FBackgroundDirective, decorators: [{
532
432
  type: Directive,
533
433
  args: [{
534
- selector: "g[fItemsContainer]",
535
- exportAs: 'fComponent',
536
- host: {
537
- 'class': 'f-items-container'
538
- },
539
- providers: [{ provide: F_ITEMS_CONTAINER, useExisting: FItemsContainerDirective }],
434
+ selector: "g[fBackground]",
435
+ standalone: true,
436
+ providers: [{ provide: F_BACKGROUND, useExisting: FBackgroundDirective }],
540
437
  }]
541
- }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { canvasChange: [{
542
- type: Output
543
- }] } });
438
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: FCanvasBase, decorators: [{
439
+ type: Inject,
440
+ args: [F_CANVAS]
441
+ }] }]; } });
544
442
 
545
- const F_FLOW_COMPONENT = new InjectionToken('F_FLOW_COMPONENT');
546
- class FFlowBase {
547
- get hostElement() {
548
- return this.elementReference.nativeElement;
549
- }
550
- constructor(elementReference, changeDetectorRef, ngZone) {
551
- this.elementReference = elementReference;
552
- this.changeDetectorRef = changeDetectorRef;
553
- this.ngZone = ngZone;
554
- this.onDestroy = new Subject();
555
- }
556
- ngAfterContentInit() {
557
- this.subscribeOnComponentsChanges();
558
- }
559
- subscribeOnComponentsChanges() {
560
- console.log(this.fNodesContainer);
561
- const changes = [
562
- this.fNodesContainer.fNodes.changes,
563
- this.fConnectionsContainer.fConnections.changes,
564
- this.outlets.changes,
565
- this.outputs.changes,
566
- this.inputs.changes
567
- ];
568
- merge(...changes).pipe(startWith(null), takeUntil(this.onDestroy)).subscribe(() => {
569
- const changedOrDestroyed = merge(...changes, this.onDestroy);
570
- // const nodesChanges = new QueryListStateChanges(this.ngZone).handle(this.nodes);
571
- //
572
- // merge(nodesChanges).pipe(startWith(null), takeUntil(changedOrDestroyed)).subscribe(() => {
573
- //
574
- //
575
- // });
576
- this.fConnectionsContainer.fConnections.forEach((connection) => {
577
- connection.fromTo = {
578
- output: this.outputs.find((x) => x.id === connection.outputId),
579
- input: this.inputs.find((x) => x.id === connection.inputId)
580
- };
581
- connection.initialize();
582
- });
583
- });
584
- }
585
- ngOnDestroy() {
586
- this.onDestroy.next();
587
- this.onDestroy.complete();
443
+ class TempConnectionInputOutputModel {
444
+ constructor(output) {
445
+ this.output = output;
446
+ this.input = null;
588
447
  }
589
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FFlowBase, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); }
590
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.4", type: FFlowBase, ngImport: i0 }); }
591
448
  }
592
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FFlowBase, decorators: [{
593
- type: Directive
594
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }]; } });
449
+
450
+ class FConnectionModule {
451
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FConnectionModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
452
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.4", ngImport: i0, type: FConnectionModule, declarations: [FTempConnectionComponent,
453
+ FConnectionComponent,
454
+ FConnectionDragHandleComponent,
455
+ FConnectionGradientComponent,
456
+ FConnectionPathComponent,
457
+ FConnectionTextComponent,
458
+ FConnectionTextPathDirective,
459
+ FConnectionSelectionComponent], imports: [CommonModule], exports: [FTempConnectionComponent,
460
+ FConnectionComponent] }); }
461
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FConnectionModule, imports: [CommonModule] }); }
462
+ }
463
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FConnectionModule, decorators: [{
464
+ type: NgModule,
465
+ args: [{
466
+ declarations: [
467
+ FTempConnectionComponent,
468
+ FConnectionComponent,
469
+ FConnectionDragHandleComponent,
470
+ FConnectionGradientComponent,
471
+ FConnectionPathComponent,
472
+ FConnectionTextComponent,
473
+ FConnectionTextPathDirective,
474
+ FConnectionSelectionComponent
475
+ ],
476
+ imports: [
477
+ CommonModule
478
+ ],
479
+ exports: [
480
+ FTempConnectionComponent,
481
+ FConnectionComponent
482
+ ]
483
+ }]
484
+ }] });
485
+
486
+ function getConnectionIntersect(fromRect, toRect) {
487
+ const fromResult = RectExtensions.intersectionWithVector(fromRect, fromRect.gravityCenter, toRect.gravityCenter);
488
+ const toResult = RectExtensions.intersectionWithVector(toRect, fromRect.gravityCenter, toRect.gravityCenter);
489
+ return {
490
+ point1: fromResult ? fromResult[1] : fromRect.gravityCenter,
491
+ point2: toResult ? toResult[0] : toRect.gravityCenter,
492
+ };
493
+ }
595
494
 
596
495
  function getElementRectInCanvas(element, transform, svgHost) {
597
496
  const rect = RectExtensions.fromElement(element);
@@ -834,98 +733,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImpor
834
733
  args: ['fNodeOutputDisabled']
835
734
  }] } });
836
735
 
837
- const F_NODES_CONTAINER = new InjectionToken('F_NODES_CONTAINER');
838
- class FNodesContainerBase {
839
- constructor(ngZone) {
840
- this.ngZone = ngZone;
841
- this.stateChanges = defer(() => {
842
- const items = this.fNodes;
843
- if (items) {
844
- return items.changes.pipe(startWith(items), switchMap(() => merge(...items.map(x => merge(x.fForeignObject.stateChanges, x.stateChanges)))));
845
- }
846
- return this.ngZone.onStable.pipe(take(1), switchMap(() => this.stateChanges));
847
- });
848
- }
849
- findNode(element) {
850
- return this.fNodes.find((x) => {
851
- return x.isContains(element);
852
- });
853
- }
854
- setNodeToTopLayer(node) {
855
- const elements = Array.from(this.hostElement.children);
856
- const elementsCount = elements.length;
857
- const targetIndex = elements.findIndex((x) => x === node.hostElement);
858
- if (targetIndex !== elementsCount - 1) {
859
- const afterElements = elements.splice(targetIndex + 1);
860
- afterElements.forEach((x) => {
861
- this.hostElement.removeChild(x);
862
- this.hostElement.insertBefore(x, node.hostElement);
863
- });
864
- }
865
- }
866
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FNodesContainerBase, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); }
867
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.4", type: FNodesContainerBase, ngImport: i0 }); }
868
- }
869
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FNodesContainerBase, decorators: [{
870
- type: Directive
871
- }], ctorParameters: function () { return [{ type: i0.NgZone }]; } });
872
-
873
- class TempConnectionInputOutputModel {
874
- constructor(output) {
875
- this.output = output;
876
- this.input = null;
877
- }
878
- }
879
-
880
- class FConnectionModule {
881
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FConnectionModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
882
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.4", ngImport: i0, type: FConnectionModule, declarations: [FTempConnectionComponent,
883
- FConnectionComponent,
884
- FConnectionDragHandleComponent,
885
- FConnectionGradientComponent,
886
- FConnectionPathComponent,
887
- FConnectionTextComponent,
888
- FConnectionTextPathDirective,
889
- FConnectionSelectionComponent], imports: [CommonModule], exports: [FTempConnectionComponent,
890
- FConnectionComponent] }); }
891
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FConnectionModule, imports: [CommonModule] }); }
892
- }
893
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FConnectionModule, decorators: [{
894
- type: NgModule,
895
- args: [{
896
- declarations: [
897
- FTempConnectionComponent,
898
- FConnectionComponent,
899
- FConnectionDragHandleComponent,
900
- FConnectionGradientComponent,
901
- FConnectionPathComponent,
902
- FConnectionTextComponent,
903
- FConnectionTextPathDirective,
904
- FConnectionSelectionComponent
905
- ],
906
- imports: [
907
- CommonModule
908
- ],
909
- exports: [
910
- FTempConnectionComponent,
911
- FConnectionComponent
912
- ]
913
- }]
914
- }] });
915
-
916
- function getConnectionIntersect(fromRect, toRect) {
917
- const fromResult = RectExtensions.intersectionWithVector(fromRect, fromRect.gravityCenter, toRect.gravityCenter);
918
- const toResult = RectExtensions.intersectionWithVector(toRect, fromRect.gravityCenter, toRect.gravityCenter);
919
- return {
920
- point1: fromResult ? fromResult[1] : fromRect.gravityCenter,
921
- point2: toResult ? toResult[0] : toRect.gravityCenter,
922
- };
923
- }
924
-
925
736
  const F_NODE_COMPONENT = new InjectionToken('F_NODE_COMPONENT');
926
737
  class FNodeBase {
927
738
  constructor() {
928
739
  this.stateChanges = new Subject();
740
+ this._position = PointExtensions.initialize();
929
741
  }
930
742
  isContains(element) {
931
743
  return this.hostElement.contains(element);
@@ -939,8 +751,11 @@ class FNodeBase {
939
751
  select() {
940
752
  this.hostElement.classList.add(F_SELECTED_CLASS);
941
753
  }
754
+ isSelected() {
755
+ return this.hostElement.classList.contains(F_SELECTED_CLASS);
756
+ }
942
757
  updatePosition(position) {
943
- this.position = position;
758
+ this._position = position;
944
759
  }
945
760
  completeDrag() {
946
761
  this.positionChange.emit(this.position);
@@ -1112,7 +927,6 @@ class FNodeComponent extends FNodeBase {
1112
927
  super();
1113
928
  this.elementReference = elementReference;
1114
929
  this.id = `f-node-${uniqueId$3++}`;
1115
- this._position = PointExtensions.initialize();
1116
930
  this.positionChange = new EventEmitter();
1117
931
  }
1118
932
  ngOnInit() {
@@ -1153,6 +967,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImpor
1153
967
  args: ['fNodePositionChange']
1154
968
  }] } });
1155
969
 
970
+ function isNode(element) {
971
+ return !!element.closest('[fNode]');
972
+ }
973
+
1156
974
  const F_SELECTION = new InjectionToken('F_SELECTION');
1157
975
  class FSelectionDirective {
1158
976
  get hostElement() {
@@ -1190,27 +1008,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImpor
1190
1008
  }]
1191
1009
  }], ctorParameters: function () { return [{ type: i0.ElementRef }]; } });
1192
1010
 
1193
- class FNodesContainerComponent extends FNodesContainerBase {
1194
- get hostElement() {
1195
- return this.elementReference.nativeElement;
1196
- }
1197
- constructor(elementReference, ngZone) {
1198
- super(ngZone);
1199
- this.elementReference = elementReference;
1200
- }
1201
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FNodesContainerComponent, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
1202
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.4", type: FNodesContainerComponent, selector: "g[fNodesContainer]", host: { classAttribute: "f-nodes-container" }, providers: [{ provide: F_NODES_CONTAINER, useExisting: FNodesContainerComponent }], queries: [{ propertyName: "fNodes", predicate: F_NODE_COMPONENT, descendants: true }], exportAs: ["fComponent"], usesInheritance: true, ngImport: i0, template: "<ng-container xmlns:svg=\"http://www.w3.org/2000/svg\">\n <ng-content select=\"[fNode]\"></ng-content>\n</ng-container>\n" }); }
1203
- }
1204
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FNodesContainerComponent, decorators: [{
1205
- type: Component,
1206
- args: [{ selector: "g[fNodesContainer]", exportAs: 'fComponent', host: {
1207
- 'class': 'f-nodes-container'
1208
- }, providers: [{ provide: F_NODES_CONTAINER, useExisting: FNodesContainerComponent }], template: "<ng-container xmlns:svg=\"http://www.w3.org/2000/svg\">\n <ng-content select=\"[fNode]\"></ng-content>\n</ng-container>\n" }]
1209
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }]; }, propDecorators: { fNodes: [{
1210
- type: ContentChildren,
1211
- args: [F_NODE_COMPONENT, { descendants: true }]
1212
- }] } });
1213
-
1214
1011
  const F_CONNECTIONS_CONTAINER = new InjectionToken('F_CONNECTIONS_CONTAINER');
1215
1012
  class FConnectionsContainerBase {
1216
1013
  findConnectionWithElement(element) {
@@ -1241,198 +1038,257 @@ function findOutgoingConnections(allConnections, outputs) {
1241
1038
  });
1242
1039
  }
1243
1040
 
1244
- const F_BACKGROUND = new InjectionToken('F_BACKGROUND');
1245
- class FBackgroundBase {
1041
+ class FConnectionsContainerComponent extends FConnectionsContainerBase {
1246
1042
  get hostElement() {
1247
1043
  return this.elementReference.nativeElement;
1248
1044
  }
1249
- constructor(elementReference, fCanvas) {
1045
+ constructor(elementReference) {
1046
+ super();
1250
1047
  this.elementReference = elementReference;
1251
- this.fCanvas = fCanvas;
1252
- this.transform = TransformModelExtensions.default();
1253
- console.log('FBackgroundBase');
1254
1048
  }
1255
- isBackgroundElement(element) {
1256
- return this.hostElement === element || this.hostElement.contains(element) || this.fCanvas.hostElement.contains(element);
1257
- }
1258
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FBackgroundBase, deps: [{ token: i0.ElementRef }, { token: FCanvasBase }], target: i0.ɵɵFactoryTarget.Directive }); }
1259
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.4", type: FBackgroundBase, ngImport: i0 }); }
1049
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FConnectionsContainerComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
1050
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.4", type: FConnectionsContainerComponent, selector: "g[fConnectionsContainer]", host: { classAttribute: "f-connections-container" }, providers: [{ provide: F_CONNECTIONS_CONTAINER, useExisting: FConnectionsContainerComponent }], queries: [{ propertyName: "fConnections", predicate: F_CONNECTION_COMPONENT, descendants: true }], viewQueries: [{ propertyName: "fTempConnection", first: true, predicate: F_TEMP_CONNECTION_COMPONENT, descendants: true, static: true }], exportAs: ["fComponent"], usesInheritance: true, ngImport: i0, template: "<ng-container xmlns:svg=\"http://www.w3.org/2000/svg\">\n <ng-content select=\"[fConnection]\"></ng-content>\n <svg:g fTempConnection></svg:g>\n</ng-container>\n", dependencies: [{ kind: "component", type: FTempConnectionComponent, selector: "g[fTempConnection]" }] }); }
1260
1051
  }
1261
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FBackgroundBase, decorators: [{
1262
- type: Directive
1263
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: FCanvasBase }]; } });
1052
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FConnectionsContainerComponent, decorators: [{
1053
+ type: Component,
1054
+ args: [{ selector: "g[fConnectionsContainer]", exportAs: 'fComponent', host: {
1055
+ 'class': 'f-connections-container'
1056
+ }, providers: [{ provide: F_CONNECTIONS_CONTAINER, useExisting: FConnectionsContainerComponent }], template: "<ng-container xmlns:svg=\"http://www.w3.org/2000/svg\">\n <ng-content select=\"[fConnection]\"></ng-content>\n <svg:g fTempConnection></svg:g>\n</ng-container>\n" }]
1057
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { fConnections: [{
1058
+ type: ContentChildren,
1059
+ args: [F_CONNECTION_COMPONENT, { descendants: true }]
1060
+ }], fTempConnection: [{
1061
+ type: ViewChild,
1062
+ args: [F_TEMP_CONNECTION_COMPONENT, { static: true }]
1063
+ }] } });
1264
1064
 
1265
- class FBackgroundDirective extends FBackgroundBase {
1266
- constructor(elementReference, fCanvas) {
1267
- super(elementReference, fCanvas);
1268
- }
1269
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FBackgroundDirective, deps: [{ token: i0.ElementRef }, { token: F_CANVAS }], target: i0.ɵɵFactoryTarget.Directive }); }
1270
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.4", type: FBackgroundDirective, isStandalone: true, selector: "g[fBackground]", providers: [{ provide: F_BACKGROUND, useExisting: FBackgroundDirective }], usesInheritance: true, ngImport: i0 }); }
1065
+ function mixinChangeZoom(base) {
1066
+ return class extends base {
1067
+ setZoom(scaleValue, toPosition) {
1068
+ if (scaleValue !== this.transform.scale) {
1069
+ const summaryPosition = PointExtensions.sum(this.transform.scaledPosition, this.transform.position);
1070
+ const newX = toPosition.x - (toPosition.x - summaryPosition.x) * scaleValue / this.transform.scale;
1071
+ const newY = toPosition.y - (toPosition.y - summaryPosition.y) * scaleValue / this.transform.scale;
1072
+ this.transform.scale = scaleValue;
1073
+ this.transform.scaledPosition = PointExtensions.sub(PointExtensions.initialize(newX, newY), this.transform.position);
1074
+ }
1075
+ }
1076
+ setScalePosition(value) {
1077
+ this.transform.scaledPosition = value;
1078
+ }
1079
+ resetZoom() {
1080
+ this.transform.scale = 1;
1081
+ this.transform.scaledPosition = PointExtensions.initialize();
1082
+ }
1083
+ constructor(...args) {
1084
+ super(...args);
1085
+ }
1086
+ };
1271
1087
  }
1272
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FBackgroundDirective, decorators: [{
1273
- type: Directive,
1274
- args: [{
1275
- selector: "g[fBackground]",
1276
- standalone: true,
1277
- providers: [{ provide: F_BACKGROUND, useExisting: FBackgroundDirective }],
1278
- }]
1279
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: FCanvasBase, decorators: [{
1280
- type: Inject,
1281
- args: [F_CANVAS]
1282
- }] }]; } });
1283
1088
 
1284
- let uniqueId$2 = 0;
1285
- const CONNECTION_MARKER_START = "connection-marker-start";
1286
- const CONNECTION_MARKER_END = "connection-marker-end";
1287
- const CONNECTION_MARKER_START_SELECTED = "connection-marker-start-selected";
1288
- const CONNECTION_MARKER_END_SELECTED = "connection-marker-end-selected";
1289
- class FFlowComponent extends FFlowBase {
1290
- get transform() {
1291
- return this.fItemsContainer.transform;
1292
- }
1293
- constructor(elementReference, changeDetectorRef, ngZone) {
1294
- super(elementReference, changeDetectorRef, ngZone);
1295
- this.CONNECTION_MARKER_START = CONNECTION_MARKER_START;
1296
- this.CONNECTION_MARKER_END = CONNECTION_MARKER_END;
1297
- this.CONNECTION_MARKER_START_SELECTED = CONNECTION_MARKER_START_SELECTED;
1298
- this.CONNECTION_MARKER_END_SELECTED = CONNECTION_MARKER_END_SELECTED;
1299
- this.id = `f-flow-${uniqueId$2++}`;
1089
+ function mixinFitToParent(base) {
1090
+ return class extends base {
1091
+ fitToParent(rect, parentRect, points) {
1092
+ this.transform.scaledPosition = PointExtensions.initialize();
1093
+ this.transform.position = this.getZeroPositionWithoutScale(points);
1094
+ const itemsContainerWidth = rect.width / this.transform.scale;
1095
+ const itemsContainerHeight = rect.height / this.transform.scale;
1096
+ if ((itemsContainerWidth > parentRect.width || itemsContainerHeight > parentRect.height) ||
1097
+ itemsContainerWidth < parentRect.width && itemsContainerHeight < parentRect.height) {
1098
+ this.transform.scale = Math.min(parentRect.width / itemsContainerWidth, parentRect.height / itemsContainerHeight);
1099
+ }
1100
+ const newX = (parentRect.width - itemsContainerWidth * this.transform.scale) / 2 - this.transform.position.x * this.transform.scale;
1101
+ const newY = (parentRect.height - itemsContainerHeight * this.transform.scale) / 2 - this.transform.position.y * this.transform.scale;
1102
+ this.transform.position = PointExtensions.initialize(newX, newY);
1103
+ }
1104
+ getZeroPositionWithoutScale(points) {
1105
+ const xPoint = points.length ? Math.min(...points.map((point) => point.x)) : 0;
1106
+ const yPoint = points.length ? Math.min(...points.map((point) => point.y)) : 0;
1107
+ return PointExtensions.initialize(xPoint, yPoint);
1108
+ }
1109
+ constructor(...args) {
1110
+ super(...args);
1111
+ }
1112
+ };
1113
+ }
1114
+
1115
+ function mixinOneToOneCentering(base) {
1116
+ return class extends base {
1117
+ oneToOneCentering(rect, parentRect, points) {
1118
+ this.transform.scaledPosition = PointExtensions.initialize();
1119
+ this.transform.position = this.getZeroPositionWithoutScale(points);
1120
+ const itemsContainerWidth = rect.width / this.transform.scale;
1121
+ const itemsContainerHeight = rect.height / this.transform.scale;
1122
+ this.transform.scale = 1;
1123
+ const newX = (parentRect.width - itemsContainerWidth * this.transform.scale) / 2 - this.transform.position.x * this.transform.scale;
1124
+ const newY = (parentRect.height - itemsContainerHeight * this.transform.scale) / 2 - this.transform.position.y * this.transform.scale;
1125
+ this.transform.position = PointExtensions.initialize(newX, newY);
1126
+ }
1127
+ getZeroPositionWithoutScale(points) {
1128
+ const xPoint = points.length ? Math.min(...points.map((point) => point.x)) : 0;
1129
+ const yPoint = points.length ? Math.min(...points.map((point) => point.y)) : 0;
1130
+ return PointExtensions.initialize(xPoint, yPoint);
1131
+ }
1132
+ constructor(...args) {
1133
+ super(...args);
1134
+ }
1135
+ };
1136
+ }
1137
+
1138
+ function mixinChangePosition(base) {
1139
+ return class extends base {
1140
+ getPosition() {
1141
+ return this.transform.position;
1142
+ }
1143
+ setPosition(position) {
1144
+ this.transform.position = PointExtensions.copy(position);
1145
+ }
1146
+ constructor(...args) {
1147
+ super(...args);
1148
+ }
1149
+ };
1150
+ }
1151
+
1152
+ class CanvasChangeEvent {
1153
+ constructor(position, scale) {
1154
+ this.position = position;
1155
+ this.scale = scale;
1300
1156
  }
1301
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FFlowComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
1302
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.4", type: FFlowComponent, selector: "svg[fFlow]", inputs: { id: "id" }, host: { properties: { "attr.id": "id" }, classAttribute: "f-component f-flow" }, providers: [{ provide: F_FLOW_COMPONENT, useExisting: FFlowComponent }], queries: [{ propertyName: "fNodesContainer", first: true, predicate: F_NODES_CONTAINER, descendants: true, static: true }, { propertyName: "fConnectionsContainer", first: true, predicate: F_CONNECTIONS_CONTAINER, descendants: true }, { propertyName: "fItemsContainer", first: true, predicate: F_ITEMS_CONTAINER, descendants: true, static: true }, { propertyName: "outlets", predicate: F_NODE_OUTLET_DIRECTIVE, descendants: true }, { propertyName: "outputs", predicate: F_NODE_OUTPUT_DIRECTIVE, descendants: true }, { propertyName: "inputs", predicate: F_NODE_INPUT_DIRECTIVE, descendants: true }], viewQueries: [{ propertyName: "fBackground", first: true, predicate: F_BACKGROUND, descendants: true, static: true }], usesInheritance: true, hostDirectives: [{ directive: FCanvasDirective }], ngImport: i0, template: "<ng-container xmlns:svg=\"http://www.w3.org/2000/svg\">\n <svg:g fBackground>\n <rect width=\"100%\" height=\"100%\" fill=\"url(#background)\"></rect>\n </svg:g>\n <ng-content></ng-content>\n <svg:defs>\n <svg:marker [id]=\"CONNECTION_MARKER_START\" class=\"connection-marker-start\" markerHeight=\"10\" markerWidth=\"10\" refY=\"5\" refX=\"5\">\n <svg:circle cx=\"5\" cy=\"5\" r=\"2\"></svg:circle>\n </svg:marker>\n <svg:marker [id]=\"CONNECTION_MARKER_END\" class=\"connection-marker-end\" markerHeight=\"10\" markerWidth=\"10\" orient=\"auto\" refX=\"5\" refY=\"3\">\n <svg:path d=\"M0,0 L6,3 0,6Z\"></svg:path>\n </svg:marker>\n <svg:marker [id]=\"CONNECTION_MARKER_START_SELECTED\" class=\"connection-marker-start f-selected\" markerHeight=\"10\" markerWidth=\"10\" refY=\"5\" refX=\"5\">\n <svg:circle cx=\"5\" cy=\"5\" r=\"2\"></svg:circle>\n </svg:marker>\n <svg:marker [id]=\"CONNECTION_MARKER_END_SELECTED\" class=\"connection-marker-end f-selected\" markerHeight=\"10\" markerWidth=\"10\" orient=\"auto\" refX=\"5\" refY=\"3\">\n <svg:path d=\"M0,0 L6,3 0,6Z\"></svg:path>\n </svg:marker>\n <ng-container *ngIf=\"fConnectionsContainer\">\n <ng-container *ngFor=\"let connection of fConnectionsContainer.fConnections.toArray()\">\n <svg:marker [id]=\"'connection-marker-start-' + connection.fromTo?.output?.color\" markerHeight=\"10\" markerWidth=\"10\" refY=\"5\" refX=\"5\">\n <svg:circle cx=\"5\" cy=\"5\" r=\"2\" [attr.stroke]=\"'none'\" [attr.fill]=\"connection.fromTo?.output?.color\"></svg:circle>\n </svg:marker>\n <svg:marker [id]=\"'connection-marker-end-' + connection.fromTo?.input?.color\" markerHeight=\"10\" markerWidth=\"10\" orient=\"auto\" refX=\"5\" refY=\"3\">\n <svg:path d=\"M0,0 L6,3 0,6Z\" [attr.stroke]=\"'none'\" [attr.fill]=\"connection.fromTo?.input?.color\"></svg:path>\n </svg:marker>\n </ng-container>\n\n </ng-container>\n <svg:pattern id=\"background\" height=\"10\" width=\"10\" class=\"fb-background-pattern\"\n patternUnits=\"userSpaceOnUse\">\n <svg:circle cx=\"5\" cy=\"5\" r=\"0.5\"/>\n </svg:pattern>\n </svg:defs>\n</ng-container>\n", dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: FBackgroundDirective, selector: "g[fBackground]" }] }); }
1303
1157
  }
1304
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FFlowComponent, decorators: [{
1305
- type: Component,
1306
- args: [{ selector: 'svg[fFlow]', hostDirectives: [
1307
- {
1308
- directive: FCanvasDirective
1309
- }
1310
- ], host: {
1311
- '[attr.id]': 'id',
1312
- class: "f-component f-flow"
1313
- }, providers: [{ provide: F_FLOW_COMPONENT, useExisting: FFlowComponent }], template: "<ng-container xmlns:svg=\"http://www.w3.org/2000/svg\">\n <svg:g fBackground>\n <rect width=\"100%\" height=\"100%\" fill=\"url(#background)\"></rect>\n </svg:g>\n <ng-content></ng-content>\n <svg:defs>\n <svg:marker [id]=\"CONNECTION_MARKER_START\" class=\"connection-marker-start\" markerHeight=\"10\" markerWidth=\"10\" refY=\"5\" refX=\"5\">\n <svg:circle cx=\"5\" cy=\"5\" r=\"2\"></svg:circle>\n </svg:marker>\n <svg:marker [id]=\"CONNECTION_MARKER_END\" class=\"connection-marker-end\" markerHeight=\"10\" markerWidth=\"10\" orient=\"auto\" refX=\"5\" refY=\"3\">\n <svg:path d=\"M0,0 L6,3 0,6Z\"></svg:path>\n </svg:marker>\n <svg:marker [id]=\"CONNECTION_MARKER_START_SELECTED\" class=\"connection-marker-start f-selected\" markerHeight=\"10\" markerWidth=\"10\" refY=\"5\" refX=\"5\">\n <svg:circle cx=\"5\" cy=\"5\" r=\"2\"></svg:circle>\n </svg:marker>\n <svg:marker [id]=\"CONNECTION_MARKER_END_SELECTED\" class=\"connection-marker-end f-selected\" markerHeight=\"10\" markerWidth=\"10\" orient=\"auto\" refX=\"5\" refY=\"3\">\n <svg:path d=\"M0,0 L6,3 0,6Z\"></svg:path>\n </svg:marker>\n <ng-container *ngIf=\"fConnectionsContainer\">\n <ng-container *ngFor=\"let connection of fConnectionsContainer.fConnections.toArray()\">\n <svg:marker [id]=\"'connection-marker-start-' + connection.fromTo?.output?.color\" markerHeight=\"10\" markerWidth=\"10\" refY=\"5\" refX=\"5\">\n <svg:circle cx=\"5\" cy=\"5\" r=\"2\" [attr.stroke]=\"'none'\" [attr.fill]=\"connection.fromTo?.output?.color\"></svg:circle>\n </svg:marker>\n <svg:marker [id]=\"'connection-marker-end-' + connection.fromTo?.input?.color\" markerHeight=\"10\" markerWidth=\"10\" orient=\"auto\" refX=\"5\" refY=\"3\">\n <svg:path d=\"M0,0 L6,3 0,6Z\" [attr.stroke]=\"'none'\" [attr.fill]=\"connection.fromTo?.input?.color\"></svg:path>\n </svg:marker>\n </ng-container>\n\n </ng-container>\n <svg:pattern id=\"background\" height=\"10\" width=\"10\" class=\"fb-background-pattern\"\n patternUnits=\"userSpaceOnUse\">\n <svg:circle cx=\"5\" cy=\"5\" r=\"0.5\"/>\n </svg:pattern>\n </svg:defs>\n</ng-container>\n" }]
1314
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }]; }, propDecorators: { id: [{
1315
- type: Input
1316
- }], fNodesContainer: [{
1317
- type: ContentChild,
1318
- args: [F_NODES_CONTAINER, { static: true }]
1319
- }], fConnectionsContainer: [{
1320
- type: ContentChild,
1321
- args: [F_CONNECTIONS_CONTAINER, { descendants: true }]
1322
- }], fItemsContainer: [{
1323
- type: ContentChild,
1324
- args: [F_ITEMS_CONTAINER, { static: true }]
1325
- }], fBackground: [{
1326
- type: ViewChild,
1327
- args: [F_BACKGROUND, { static: true }]
1328
- }], outlets: [{
1329
- type: ContentChildren,
1330
- args: [F_NODE_OUTLET_DIRECTIVE, { descendants: true }]
1331
- }], outputs: [{
1332
- type: ContentChildren,
1333
- args: [F_NODE_OUTPUT_DIRECTIVE, { descendants: true }]
1334
- }], inputs: [{
1335
- type: ContentChildren,
1336
- args: [F_NODE_INPUT_DIRECTIVE, { descendants: true }]
1337
- }] } });
1338
1158
 
1339
- let uniqueId$1 = 0;
1340
- class FConnectionComponent extends FConnectionBase {
1159
+ const F_ITEMS_CONTAINER = new InjectionToken('F_ITEMS_CONTAINER');
1160
+ const MIXIN_BASE = mixinChangePosition(mixinFitToParent(mixinOneToOneCentering(mixinChangeZoom(class {
1161
+ constructor(transform) {
1162
+ this.transform = transform;
1163
+ }
1164
+ }))));
1165
+ class FItemsContainerBase extends MIXIN_BASE {
1341
1166
  get hostElement() {
1342
1167
  return this.elementReference.nativeElement;
1343
1168
  }
1344
- constructor(elementReference, flow) {
1345
- super();
1169
+ constructor(elementReference) {
1170
+ super(TransformModelExtensions.default());
1346
1171
  this.elementReference = elementReference;
1347
- this.flow = flow;
1348
- this.id = `f-connection-${uniqueId$1++}`;
1349
- }
1350
- initialize() {
1351
- const vector = getConnectionIntersect(this.fromTo.output.getElementRectInCanvas(this.flow.transform, this.flow.hostElement), this.fromTo.input.getElementRectInCanvas(this.flow.transform, this.flow.hostElement));
1352
- this.setVector(vector);
1353
- this.redraw();
1354
- }
1355
- initializeDrag() {
1172
+ this.parseData();
1356
1173
  }
1357
- setVector(vector) {
1358
- this.vector = vector;
1359
- this.path = `M${vector.point1.x},${vector.point1.y}L${vector.point2.x + 0.0001},${vector.point2.y + 0.0001}`;
1174
+ parseData() {
1175
+ const transform = TransformModelExtensions.fromString(this.hostElement.getAttribute("transform"));
1176
+ this.transform = transform ? transform : this.transform;
1360
1177
  }
1361
1178
  redraw() {
1362
- this.fPath.setPath(this.path);
1363
- this.fSelection.setPath(this.path);
1364
- this.fGradient.redraw(this.vector);
1365
- this.fDragHandle.redraw(this.vector.point2);
1366
- this.fText.redraw(this.vector);
1367
- }
1368
- select() {
1369
- this.fPath.select();
1370
- super.select();
1179
+ this.hostElement.setAttribute("transform", TransformModelExtensions.toString(this.transform));
1371
1180
  }
1372
- deselect() {
1373
- this.fPath.deselect();
1374
- super.deselect();
1181
+ redrawWithAnimation() {
1182
+ this.hostElement.setAttribute("style", 'transition: transform 0.15s ease-in-out');
1183
+ this.redraw();
1184
+ setTimeout(() => {
1185
+ this.hostElement.removeAttribute("style");
1186
+ }, 150);
1375
1187
  }
1376
1188
  completeDrag() {
1189
+ const position = PointExtensions.sum(this.transform.position, this.transform.scaledPosition);
1190
+ this.canvasChange.emit(new CanvasChangeEvent(position, this.transform.scale));
1191
+ }
1192
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FItemsContainerBase, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
1193
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.4", type: FItemsContainerBase, usesInheritance: true, ngImport: i0 }); }
1194
+ }
1195
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FItemsContainerBase, decorators: [{
1196
+ type: Directive
1197
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }]; } });
1198
+
1199
+ class FItemsContainerDirective extends FItemsContainerBase {
1200
+ set position(value) {
1201
+ const position = PointExtensions.sum(this.transform.position, this.transform.scaledPosition);
1202
+ if (!PointExtensions.isEqual(position, value)) {
1203
+ this.transform.position = value;
1204
+ this.transform.scaledPosition = PointExtensions.initialize();
1205
+ this.redraw();
1206
+ }
1207
+ }
1208
+ set scale(value) {
1209
+ this.transform.scale = value;
1377
1210
  this.redraw();
1378
1211
  }
1379
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FConnectionComponent, deps: [{ token: i0.ElementRef }, { token: F_FLOW_COMPONENT }], target: i0.ɵɵFactoryTarget.Component }); }
1380
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.4", type: FConnectionComponent, selector: "g[fConnection]", inputs: { id: "id", outputId: "outputId", inputId: "inputId" }, host: { properties: { "attr.id": "id" }, classAttribute: "f-component f-connection" }, providers: [{ provide: F_CONNECTION_COMPONENT, useExisting: FConnectionComponent }], viewQueries: [{ propertyName: "fPath", first: true, predicate: FConnectionPathComponent, descendants: true, static: true }, { propertyName: "fGradient", first: true, predicate: FConnectionGradientComponent, descendants: true, static: true }, { propertyName: "fDragHandle", first: true, predicate: FConnectionDragHandleComponent, descendants: true, static: true }, { propertyName: "fSelection", first: true, predicate: FConnectionSelectionComponent, descendants: true, static: true }, { propertyName: "fText", first: true, predicate: FConnectionTextComponent, descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<ng-container xmlns:svg=\"http://www.w3.org/2000/svg\">\n <svg:linearGradient fConnectionGradient [fromTo]=\"fromTo\"></svg:linearGradient>\n <svg:path fConnectionSelection [attr.d]=\"path\" [fromTo]=\"fromTo\"></svg:path>\n <svg:g>\n <svg:path f-connection-path [attr.d]=\"path\" [fromTo]=\"fromTo\"></svg:path>\n <svg:circle f-connection-drag-handle r=\"8\"></svg:circle>\n </svg:g>\n <svg:text f-connection-text [fromTo]=\"fromTo\"></svg:text>\n</ng-container>\n", dependencies: [{ kind: "component", type: FConnectionDragHandleComponent, selector: "circle[f-connection-drag-handle]" }, { kind: "component", type: FConnectionGradientComponent, selector: "linearGradient[fConnectionGradient]", inputs: ["fromTo"] }, { kind: "component", type: FConnectionPathComponent, selector: "path[f-connection-path]", inputs: ["fromTo"] }, { kind: "component", type: FConnectionTextComponent, selector: "text[f-connection-text]", inputs: ["fromTo"] }, { kind: "component", type: FConnectionSelectionComponent, selector: "path[fConnectionSelection]", inputs: ["fromTo"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1212
+ constructor(elementReference) {
1213
+ super(elementReference);
1214
+ this.canvasChange = new EventEmitter();
1215
+ }
1216
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FItemsContainerDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
1217
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.4", type: FItemsContainerDirective, selector: "g[fItemsContainer]", inputs: { position: "position", scale: "scale" }, outputs: { canvasChange: "canvasChange" }, host: { classAttribute: "f-items-container" }, providers: [{ provide: F_ITEMS_CONTAINER, useExisting: FItemsContainerDirective }], exportAs: ["fComponent"], usesInheritance: true, ngImport: i0 }); }
1381
1218
  }
1382
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FConnectionComponent, decorators: [{
1383
- type: Component,
1384
- args: [{ selector: "g[fConnection]", changeDetection: ChangeDetectionStrategy.OnPush, host: {
1385
- '[attr.id]': 'id',
1386
- class: "f-component f-connection"
1387
- }, providers: [{ provide: F_CONNECTION_COMPONENT, useExisting: FConnectionComponent }], template: "<ng-container xmlns:svg=\"http://www.w3.org/2000/svg\">\n <svg:linearGradient fConnectionGradient [fromTo]=\"fromTo\"></svg:linearGradient>\n <svg:path fConnectionSelection [attr.d]=\"path\" [fromTo]=\"fromTo\"></svg:path>\n <svg:g>\n <svg:path f-connection-path [attr.d]=\"path\" [fromTo]=\"fromTo\"></svg:path>\n <svg:circle f-connection-drag-handle r=\"8\"></svg:circle>\n </svg:g>\n <svg:text f-connection-text [fromTo]=\"fromTo\"></svg:text>\n</ng-container>\n" }]
1388
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: FFlowBase, decorators: [{
1389
- type: Inject,
1390
- args: [F_FLOW_COMPONENT]
1391
- }] }]; }, propDecorators: { id: [{
1392
- type: Input
1393
- }], outputId: [{
1219
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FItemsContainerDirective, decorators: [{
1220
+ type: Directive,
1221
+ args: [{
1222
+ selector: "g[fItemsContainer]",
1223
+ exportAs: 'fComponent',
1224
+ host: {
1225
+ 'class': 'f-items-container'
1226
+ },
1227
+ providers: [{ provide: F_ITEMS_CONTAINER, useExisting: FItemsContainerDirective }],
1228
+ }]
1229
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { canvasChange: [{
1230
+ type: Output
1231
+ }], position: [{
1394
1232
  type: Input
1395
- }], inputId: [{
1233
+ }], scale: [{
1396
1234
  type: Input
1397
- }], fPath: [{
1398
- type: ViewChild,
1399
- args: [FConnectionPathComponent, { static: true }]
1400
- }], fGradient: [{
1401
- type: ViewChild,
1402
- args: [FConnectionGradientComponent, { static: true }]
1403
- }], fDragHandle: [{
1404
- type: ViewChild,
1405
- args: [FConnectionDragHandleComponent, { static: true }]
1406
- }], fSelection: [{
1407
- type: ViewChild,
1408
- args: [FConnectionSelectionComponent, { static: true }]
1409
- }], fText: [{
1410
- type: ViewChild,
1411
- args: [FConnectionTextComponent, { static: true }]
1412
1235
  }] } });
1413
1236
 
1414
- class FConnectionsContainerComponent extends FConnectionsContainerBase {
1237
+ const F_NODES_CONTAINER = new InjectionToken('F_NODES_CONTAINER');
1238
+ class FNodesContainerBase {
1239
+ constructor(ngZone) {
1240
+ this.ngZone = ngZone;
1241
+ this.stateChanges = defer(() => {
1242
+ const items = this.fNodes;
1243
+ if (items) {
1244
+ return items.changes.pipe(startWith(items), switchMap(() => merge(...items.map(x => merge(x.fForeignObject.stateChanges, x.stateChanges)))));
1245
+ }
1246
+ return this.ngZone.onStable.pipe(take(1), switchMap(() => this.stateChanges));
1247
+ });
1248
+ }
1249
+ findNode(element) {
1250
+ return this.fNodes.find((x) => {
1251
+ return x.isContains(element);
1252
+ });
1253
+ }
1254
+ setNodeToTopLayer(node) {
1255
+ const elements = Array.from(this.hostElement.children);
1256
+ const elementsCount = elements.length;
1257
+ const targetIndex = elements.findIndex((x) => x === node.hostElement);
1258
+ if (targetIndex !== elementsCount - 1) {
1259
+ const afterElements = elements.splice(targetIndex + 1);
1260
+ afterElements.forEach((x) => {
1261
+ this.hostElement.removeChild(x);
1262
+ this.hostElement.insertBefore(x, node.hostElement);
1263
+ });
1264
+ }
1265
+ }
1266
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FNodesContainerBase, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); }
1267
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.4", type: FNodesContainerBase, ngImport: i0 }); }
1268
+ }
1269
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FNodesContainerBase, decorators: [{
1270
+ type: Directive
1271
+ }], ctorParameters: function () { return [{ type: i0.NgZone }]; } });
1272
+
1273
+ class FNodesContainerComponent extends FNodesContainerBase {
1415
1274
  get hostElement() {
1416
1275
  return this.elementReference.nativeElement;
1417
1276
  }
1418
- constructor(elementReference) {
1419
- super();
1277
+ constructor(elementReference, ngZone) {
1278
+ super(ngZone);
1420
1279
  this.elementReference = elementReference;
1421
1280
  }
1422
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FConnectionsContainerComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
1423
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.4", type: FConnectionsContainerComponent, selector: "g[fConnectionsContainer]", host: { classAttribute: "f-connections-container" }, providers: [{ provide: F_CONNECTIONS_CONTAINER, useExisting: FConnectionsContainerComponent }], queries: [{ propertyName: "fConnections", predicate: F_CONNECTION_COMPONENT, descendants: true }], viewQueries: [{ propertyName: "fTempConnection", first: true, predicate: F_TEMP_CONNECTION_COMPONENT, descendants: true, static: true }], exportAs: ["fComponent"], usesInheritance: true, ngImport: i0, template: "<ng-container xmlns:svg=\"http://www.w3.org/2000/svg\">\n <ng-content select=\"[fConnection]\"></ng-content>\n <svg:g fTempConnection></svg:g>\n</ng-container>\n", dependencies: [{ kind: "component", type: FTempConnectionComponent, selector: "g[fTempConnection]" }] }); }
1281
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FNodesContainerComponent, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
1282
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.4", type: FNodesContainerComponent, selector: "g[fNodesContainer]", host: { classAttribute: "f-nodes-container" }, providers: [{ provide: F_NODES_CONTAINER, useExisting: FNodesContainerComponent }], queries: [{ propertyName: "fNodes", predicate: F_NODE_COMPONENT, descendants: true }], exportAs: ["fComponent"], usesInheritance: true, ngImport: i0, template: "<ng-container xmlns:svg=\"http://www.w3.org/2000/svg\">\n <ng-content select=\"[fNode]\"></ng-content>\n</ng-container>\n" }); }
1424
1283
  }
1425
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FConnectionsContainerComponent, decorators: [{
1284
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FNodesContainerComponent, decorators: [{
1426
1285
  type: Component,
1427
- args: [{ selector: "g[fConnectionsContainer]", exportAs: 'fComponent', host: {
1428
- 'class': 'f-connections-container'
1429
- }, providers: [{ provide: F_CONNECTIONS_CONTAINER, useExisting: FConnectionsContainerComponent }], template: "<ng-container xmlns:svg=\"http://www.w3.org/2000/svg\">\n <ng-content select=\"[fConnection]\"></ng-content>\n <svg:g fTempConnection></svg:g>\n</ng-container>\n" }]
1430
- }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { fConnections: [{
1286
+ args: [{ selector: "g[fNodesContainer]", exportAs: 'fComponent', host: {
1287
+ 'class': 'f-nodes-container'
1288
+ }, providers: [{ provide: F_NODES_CONTAINER, useExisting: FNodesContainerComponent }], template: "<ng-container xmlns:svg=\"http://www.w3.org/2000/svg\">\n <ng-content select=\"[fNode]\"></ng-content>\n</ng-container>\n" }]
1289
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }]; }, propDecorators: { fNodes: [{
1431
1290
  type: ContentChildren,
1432
- args: [F_CONNECTION_COMPONENT, { descendants: true }]
1433
- }], fTempConnection: [{
1434
- type: ViewChild,
1435
- args: [F_TEMP_CONNECTION_COMPONENT, { static: true }]
1291
+ args: [F_NODE_COMPONENT, { descendants: true }]
1436
1292
  }] } });
1437
1293
 
1438
1294
  var EDraggableType;
@@ -1823,10 +1679,13 @@ class ReassignConnectionOnPointerUp {
1823
1679
  this.onReassignConnection = onReassignConnection;
1824
1680
  }
1825
1681
  handle(payload) {
1682
+ console.log('ReassignConnectionOnPointerUp', payload);
1826
1683
  const isReassignConnection = payload.dragHandler.draggableItems.some((x) => x.type === EDraggableType.REASSIGN_CONNECTION);
1827
1684
  if (isReassignConnection) {
1685
+ console.log('ReassignConnectionOnPointerUp - isReassignConnection');
1828
1686
  const handler = payload.dragHandler.draggableItems[0];
1829
1687
  const inputsUnderPointer = new FindInputsUnderPointerHandler(this.fFlow).handle(new FindInputsUnderPointerRequest(payload.event, handler));
1688
+ console.log(inputsUnderPointer);
1830
1689
  if (inputsUnderPointer.length > 0) {
1831
1690
  if (handler.connection.fromTo?.input?.id !== inputsUnderPointer[0]?.id) {
1832
1691
  this.onReassignConnection.emit(new ReassignConnectionEvent(handler.connection.id, handler.connection.fromTo?.output.id, handler.connection.fromTo?.input?.id, inputsUnderPointer[0]?.id));
@@ -1899,7 +1758,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImpor
1899
1758
  type: Injectable
1900
1759
  }] });
1901
1760
 
1902
- let uniqueId = 0;
1761
+ let uniqueId$2 = 0;
1903
1762
  class FExternalItemDirective extends FExternalItemBase {
1904
1763
  get hostElement() {
1905
1764
  return this.elementReference.nativeElement;
@@ -1908,7 +1767,7 @@ class FExternalItemDirective extends FExternalItemBase {
1908
1767
  super();
1909
1768
  this.elementReference = elementReference;
1910
1769
  this.fExternalItemService = fExternalItemService;
1911
- this.id = `f-external-item-${uniqueId++}`;
1770
+ this.id = `f-external-item-${uniqueId$2++}`;
1912
1771
  }
1913
1772
  ngOnInit() {
1914
1773
  this.fExternalItemService.registerItem(this);
@@ -2298,7 +2157,9 @@ class SelectionOnPointerDown {
2298
2157
  let node = this.fFlow.fNodesContainer.findNode(payload.event.targetElement);
2299
2158
  const connection = this.fFlow.fConnectionsContainer.findConnectionWithElement(payload.event.targetElement);
2300
2159
  payload.selectedItems.forEach((x) => {
2301
- x.deselect();
2160
+ if (x !== node || (!isNodeOutlet(payload.event.targetElement) && !isNodeOutput(payload.event.targetElement))) {
2161
+ x.deselect();
2162
+ }
2302
2163
  });
2303
2164
  const isMultiselect = MouseEventExtensions.isCommandButton(payload.event.originalEvent) ||
2304
2165
  MouseEventExtensions.isShiftPressed(payload.event.originalEvent);
@@ -2306,9 +2167,6 @@ class SelectionOnPointerDown {
2306
2167
  payload.selectedItems = [];
2307
2168
  }
2308
2169
  if (node) {
2309
- if (isNodeOutlet(payload.event.targetElement) || isNodeOutput(payload.event.targetElement)) {
2310
- node = undefined;
2311
- }
2312
2170
  if (node) {
2313
2171
  if (!payload.selectedItems.includes(node)) {
2314
2172
  payload.selectedItems.push(node);
@@ -2327,7 +2185,9 @@ class SelectionOnPointerDown {
2327
2185
  }
2328
2186
  }
2329
2187
  payload.selectedItems.forEach((x) => {
2330
- x.select();
2188
+ if (!x.isSelected()) {
2189
+ x.select();
2190
+ }
2331
2191
  });
2332
2192
  let draggableItems = [];
2333
2193
  if (MouseEventExtensions.isShiftPressed(payload.event.originalEvent)) {
@@ -2899,7 +2759,8 @@ class FZoomBase {
2899
2759
  this.fItemsContainer.completeDrag();
2900
2760
  }
2901
2761
  onZoomToCenter(deltaY) {
2902
- const preventDefault = () => { };
2762
+ const preventDefault = () => {
2763
+ };
2903
2764
  const rect = RectExtensions.fromElement(this.fCanvas.hostElement);
2904
2765
  this.onWheel({
2905
2766
  deltaY, preventDefault, clientX: rect.gravityCenter.x, clientY: rect.gravityCenter.y
@@ -2907,7 +2768,7 @@ class FZoomBase {
2907
2768
  }
2908
2769
  onDoubleClick(event) {
2909
2770
  event.preventDefault();
2910
- if (this.fDnd.isDragStarted) {
2771
+ if (this.fDnd.isDragStarted || isNode(event.target)) {
2911
2772
  return;
2912
2773
  }
2913
2774
  let result = this.getScale();
@@ -2977,6 +2838,182 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImpor
2977
2838
  args: ['fZoom']
2978
2839
  }] } });
2979
2840
 
2841
+ const F_FLOW_COMPONENT = new InjectionToken('F_FLOW_COMPONENT');
2842
+ class FFlowBase {
2843
+ get hostElement() {
2844
+ return this.elementReference.nativeElement;
2845
+ }
2846
+ constructor(elementReference, changeDetectorRef, ngZone) {
2847
+ this.elementReference = elementReference;
2848
+ this.changeDetectorRef = changeDetectorRef;
2849
+ this.ngZone = ngZone;
2850
+ this.onDestroy = new Subject();
2851
+ }
2852
+ ngAfterContentInit() {
2853
+ this.subscribeOnComponentsChanges();
2854
+ }
2855
+ subscribeOnComponentsChanges() {
2856
+ const changes = [
2857
+ this.fNodesContainer.fNodes.changes,
2858
+ this.fConnectionsContainer.fConnections.changes,
2859
+ this.outlets.changes,
2860
+ this.outputs.changes,
2861
+ this.inputs.changes
2862
+ ];
2863
+ merge(...changes).pipe(startWith(null), takeUntil(this.onDestroy)).subscribe(() => {
2864
+ const changedOrDestroyed = merge(...changes, this.onDestroy);
2865
+ merge(this.fNodesContainer.stateChanges).pipe(startWith(null), takeUntil(changedOrDestroyed)).subscribe(() => {
2866
+ this.fConnectionsContainer.fConnections.forEach((connection) => {
2867
+ connection.fromTo = {
2868
+ output: this.outputs.find((x) => x.id === connection.outputId),
2869
+ input: this.inputs.find((x) => x.id === connection.inputId)
2870
+ };
2871
+ connection.initialize();
2872
+ });
2873
+ });
2874
+ });
2875
+ }
2876
+ ngOnDestroy() {
2877
+ this.onDestroy.next();
2878
+ this.onDestroy.complete();
2879
+ }
2880
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FFlowBase, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); }
2881
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.4", type: FFlowBase, ngImport: i0 }); }
2882
+ }
2883
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FFlowBase, decorators: [{
2884
+ type: Directive
2885
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }]; } });
2886
+
2887
+ let uniqueId$1 = 0;
2888
+ const CONNECTION_MARKER_START = "connection-marker-start";
2889
+ const CONNECTION_MARKER_END = "connection-marker-end";
2890
+ const CONNECTION_MARKER_START_SELECTED = "connection-marker-start-selected";
2891
+ const CONNECTION_MARKER_END_SELECTED = "connection-marker-end-selected";
2892
+ class FFlowComponent extends FFlowBase {
2893
+ get transform() {
2894
+ return this.fItemsContainer.transform;
2895
+ }
2896
+ constructor(elementReference, changeDetectorRef, ngZone) {
2897
+ super(elementReference, changeDetectorRef, ngZone);
2898
+ this.CONNECTION_MARKER_START = CONNECTION_MARKER_START;
2899
+ this.CONNECTION_MARKER_END = CONNECTION_MARKER_END;
2900
+ this.CONNECTION_MARKER_START_SELECTED = CONNECTION_MARKER_START_SELECTED;
2901
+ this.CONNECTION_MARKER_END_SELECTED = CONNECTION_MARKER_END_SELECTED;
2902
+ this.id = `f-flow-${uniqueId$1++}`;
2903
+ }
2904
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FFlowComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
2905
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.4", type: FFlowComponent, selector: "svg[fFlow]", inputs: { id: "id" }, host: { properties: { "attr.id": "id" }, classAttribute: "f-component f-flow" }, providers: [{ provide: F_FLOW_COMPONENT, useExisting: FFlowComponent }], queries: [{ propertyName: "fNodesContainer", first: true, predicate: F_NODES_CONTAINER, descendants: true, static: true }, { propertyName: "fConnectionsContainer", first: true, predicate: F_CONNECTIONS_CONTAINER, descendants: true }, { propertyName: "fItemsContainer", first: true, predicate: F_ITEMS_CONTAINER, descendants: true, static: true }, { propertyName: "outlets", predicate: F_NODE_OUTLET_DIRECTIVE, descendants: true }, { propertyName: "outputs", predicate: F_NODE_OUTPUT_DIRECTIVE, descendants: true }, { propertyName: "inputs", predicate: F_NODE_INPUT_DIRECTIVE, descendants: true }], viewQueries: [{ propertyName: "fBackground", first: true, predicate: F_BACKGROUND, descendants: true, static: true }], usesInheritance: true, hostDirectives: [{ directive: FCanvasDirective }], ngImport: i0, template: "<ng-container xmlns:svg=\"http://www.w3.org/2000/svg\">\n <svg:g fBackground>\n <rect width=\"100%\" height=\"100%\" fill=\"url(#background)\"></rect>\n </svg:g>\n <ng-content></ng-content>\n <svg:defs>\n <svg:marker [id]=\"CONNECTION_MARKER_START\" class=\"connection-marker-start\" markerHeight=\"10\" markerWidth=\"10\" refY=\"5\" refX=\"5\">\n <svg:circle cx=\"5\" cy=\"5\" r=\"2\"></svg:circle>\n </svg:marker>\n <svg:marker [id]=\"CONNECTION_MARKER_END\" class=\"connection-marker-end\" markerHeight=\"10\" markerWidth=\"10\" orient=\"auto\" refX=\"5\" refY=\"3\">\n <svg:path d=\"M0,0 L6,3 0,6Z\"></svg:path>\n </svg:marker>\n <svg:marker [id]=\"CONNECTION_MARKER_START_SELECTED\" class=\"connection-marker-start f-selected\" markerHeight=\"10\" markerWidth=\"10\" refY=\"5\" refX=\"5\">\n <svg:circle cx=\"5\" cy=\"5\" r=\"2\"></svg:circle>\n </svg:marker>\n <svg:marker [id]=\"CONNECTION_MARKER_END_SELECTED\" class=\"connection-marker-end f-selected\" markerHeight=\"10\" markerWidth=\"10\" orient=\"auto\" refX=\"5\" refY=\"3\">\n <svg:path d=\"M0,0 L6,3 0,6Z\"></svg:path>\n </svg:marker>\n <ng-container *ngIf=\"fConnectionsContainer\">\n <ng-container *ngFor=\"let connection of fConnectionsContainer.fConnections.toArray()\">\n <svg:marker [id]=\"'connection-marker-start-' + connection.fromTo?.output?.color\" markerHeight=\"10\" markerWidth=\"10\" refY=\"5\" refX=\"5\">\n <svg:circle cx=\"5\" cy=\"5\" r=\"2\" [attr.stroke]=\"'none'\" [attr.fill]=\"connection.fromTo?.output?.color\"></svg:circle>\n </svg:marker>\n <svg:marker [id]=\"'connection-marker-end-' + connection.fromTo?.input?.color\" markerHeight=\"10\" markerWidth=\"10\" orient=\"auto\" refX=\"5\" refY=\"3\">\n <svg:path d=\"M0,0 L6,3 0,6Z\" [attr.stroke]=\"'none'\" [attr.fill]=\"connection.fromTo?.input?.color\"></svg:path>\n </svg:marker>\n </ng-container>\n\n </ng-container>\n <svg:pattern id=\"background\" height=\"10\" width=\"10\" class=\"fb-background-pattern\"\n patternUnits=\"userSpaceOnUse\">\n <svg:circle cx=\"5\" cy=\"5\" r=\"0.5\"/>\n </svg:pattern>\n </svg:defs>\n</ng-container>\n", dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: FBackgroundDirective, selector: "g[fBackground]" }] }); }
2906
+ }
2907
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FFlowComponent, decorators: [{
2908
+ type: Component,
2909
+ args: [{ selector: 'svg[fFlow]', hostDirectives: [
2910
+ {
2911
+ directive: FCanvasDirective
2912
+ }
2913
+ ], host: {
2914
+ '[attr.id]': 'id',
2915
+ class: "f-component f-flow"
2916
+ }, providers: [{ provide: F_FLOW_COMPONENT, useExisting: FFlowComponent }], template: "<ng-container xmlns:svg=\"http://www.w3.org/2000/svg\">\n <svg:g fBackground>\n <rect width=\"100%\" height=\"100%\" fill=\"url(#background)\"></rect>\n </svg:g>\n <ng-content></ng-content>\n <svg:defs>\n <svg:marker [id]=\"CONNECTION_MARKER_START\" class=\"connection-marker-start\" markerHeight=\"10\" markerWidth=\"10\" refY=\"5\" refX=\"5\">\n <svg:circle cx=\"5\" cy=\"5\" r=\"2\"></svg:circle>\n </svg:marker>\n <svg:marker [id]=\"CONNECTION_MARKER_END\" class=\"connection-marker-end\" markerHeight=\"10\" markerWidth=\"10\" orient=\"auto\" refX=\"5\" refY=\"3\">\n <svg:path d=\"M0,0 L6,3 0,6Z\"></svg:path>\n </svg:marker>\n <svg:marker [id]=\"CONNECTION_MARKER_START_SELECTED\" class=\"connection-marker-start f-selected\" markerHeight=\"10\" markerWidth=\"10\" refY=\"5\" refX=\"5\">\n <svg:circle cx=\"5\" cy=\"5\" r=\"2\"></svg:circle>\n </svg:marker>\n <svg:marker [id]=\"CONNECTION_MARKER_END_SELECTED\" class=\"connection-marker-end f-selected\" markerHeight=\"10\" markerWidth=\"10\" orient=\"auto\" refX=\"5\" refY=\"3\">\n <svg:path d=\"M0,0 L6,3 0,6Z\"></svg:path>\n </svg:marker>\n <ng-container *ngIf=\"fConnectionsContainer\">\n <ng-container *ngFor=\"let connection of fConnectionsContainer.fConnections.toArray()\">\n <svg:marker [id]=\"'connection-marker-start-' + connection.fromTo?.output?.color\" markerHeight=\"10\" markerWidth=\"10\" refY=\"5\" refX=\"5\">\n <svg:circle cx=\"5\" cy=\"5\" r=\"2\" [attr.stroke]=\"'none'\" [attr.fill]=\"connection.fromTo?.output?.color\"></svg:circle>\n </svg:marker>\n <svg:marker [id]=\"'connection-marker-end-' + connection.fromTo?.input?.color\" markerHeight=\"10\" markerWidth=\"10\" orient=\"auto\" refX=\"5\" refY=\"3\">\n <svg:path d=\"M0,0 L6,3 0,6Z\" [attr.stroke]=\"'none'\" [attr.fill]=\"connection.fromTo?.input?.color\"></svg:path>\n </svg:marker>\n </ng-container>\n\n </ng-container>\n <svg:pattern id=\"background\" height=\"10\" width=\"10\" class=\"fb-background-pattern\"\n patternUnits=\"userSpaceOnUse\">\n <svg:circle cx=\"5\" cy=\"5\" r=\"0.5\"/>\n </svg:pattern>\n </svg:defs>\n</ng-container>\n" }]
2917
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }]; }, propDecorators: { id: [{
2918
+ type: Input
2919
+ }], fNodesContainer: [{
2920
+ type: ContentChild,
2921
+ args: [F_NODES_CONTAINER, { static: true }]
2922
+ }], fConnectionsContainer: [{
2923
+ type: ContentChild,
2924
+ args: [F_CONNECTIONS_CONTAINER, { descendants: true }]
2925
+ }], fItemsContainer: [{
2926
+ type: ContentChild,
2927
+ args: [F_ITEMS_CONTAINER, { static: true }]
2928
+ }], fBackground: [{
2929
+ type: ViewChild,
2930
+ args: [F_BACKGROUND, { static: true }]
2931
+ }], outlets: [{
2932
+ type: ContentChildren,
2933
+ args: [F_NODE_OUTLET_DIRECTIVE, { descendants: true }]
2934
+ }], outputs: [{
2935
+ type: ContentChildren,
2936
+ args: [F_NODE_OUTPUT_DIRECTIVE, { descendants: true }]
2937
+ }], inputs: [{
2938
+ type: ContentChildren,
2939
+ args: [F_NODE_INPUT_DIRECTIVE, { descendants: true }]
2940
+ }] } });
2941
+
2942
+ let uniqueId = 0;
2943
+ class FConnectionComponent extends FConnectionBase {
2944
+ get hostElement() {
2945
+ return this.elementReference.nativeElement;
2946
+ }
2947
+ constructor(elementReference, flow) {
2948
+ super();
2949
+ this.elementReference = elementReference;
2950
+ this.flow = flow;
2951
+ this.id = `f-connection-${uniqueId++}`;
2952
+ }
2953
+ initialize() {
2954
+ const vector = getConnectionIntersect(this.fromTo.output.getElementRectInCanvas(this.flow.transform, this.flow.hostElement), this.fromTo.input.getElementRectInCanvas(this.flow.transform, this.flow.hostElement));
2955
+ this.setVector(vector);
2956
+ this.redraw();
2957
+ }
2958
+ initializeDrag() {
2959
+ }
2960
+ setVector(vector) {
2961
+ this.vector = vector;
2962
+ this.path = `M${vector.point1.x},${vector.point1.y}L${vector.point2.x + 0.0001},${vector.point2.y + 0.0001}`;
2963
+ }
2964
+ redraw() {
2965
+ this.fPath.setPath(this.path);
2966
+ this.fSelection.setPath(this.path);
2967
+ this.fGradient.redraw(this.vector);
2968
+ this.fDragHandle.redraw(this.vector.point2);
2969
+ this.fText.redraw(this.vector);
2970
+ }
2971
+ select() {
2972
+ this.fPath.select();
2973
+ super.select();
2974
+ }
2975
+ deselect() {
2976
+ this.fPath.deselect();
2977
+ super.deselect();
2978
+ }
2979
+ completeDrag() {
2980
+ this.redraw();
2981
+ }
2982
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FConnectionComponent, deps: [{ token: i0.ElementRef }, { token: F_FLOW_COMPONENT }], target: i0.ɵɵFactoryTarget.Component }); }
2983
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.4", type: FConnectionComponent, selector: "g[fConnection]", inputs: { id: "id", outputId: "outputId", inputId: "inputId" }, host: { properties: { "attr.id": "id" }, classAttribute: "f-component f-connection" }, providers: [{ provide: F_CONNECTION_COMPONENT, useExisting: FConnectionComponent }], viewQueries: [{ propertyName: "fPath", first: true, predicate: FConnectionPathComponent, descendants: true, static: true }, { propertyName: "fGradient", first: true, predicate: FConnectionGradientComponent, descendants: true, static: true }, { propertyName: "fDragHandle", first: true, predicate: FConnectionDragHandleComponent, descendants: true, static: true }, { propertyName: "fSelection", first: true, predicate: FConnectionSelectionComponent, descendants: true, static: true }, { propertyName: "fText", first: true, predicate: FConnectionTextComponent, descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<ng-container xmlns:svg=\"http://www.w3.org/2000/svg\">\n <svg:linearGradient fConnectionGradient [fromTo]=\"fromTo\"></svg:linearGradient>\n <svg:path fConnectionSelection [attr.d]=\"path\" [fromTo]=\"fromTo\"></svg:path>\n <svg:g>\n <svg:path f-connection-path [attr.d]=\"path\" [fromTo]=\"fromTo\"></svg:path>\n <svg:circle f-connection-drag-handle r=\"8\"></svg:circle>\n </svg:g>\n <svg:text f-connection-text [fromTo]=\"fromTo\"></svg:text>\n</ng-container>\n", dependencies: [{ kind: "component", type: FConnectionDragHandleComponent, selector: "circle[f-connection-drag-handle]" }, { kind: "component", type: FConnectionGradientComponent, selector: "linearGradient[fConnectionGradient]", inputs: ["fromTo"] }, { kind: "component", type: FConnectionPathComponent, selector: "path[f-connection-path]", inputs: ["fromTo"] }, { kind: "component", type: FConnectionTextComponent, selector: "text[f-connection-text]", inputs: ["fromTo"] }, { kind: "component", type: FConnectionSelectionComponent, selector: "path[fConnectionSelection]", inputs: ["fromTo"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2984
+ }
2985
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FConnectionComponent, decorators: [{
2986
+ type: Component,
2987
+ args: [{ selector: "g[fConnection]", changeDetection: ChangeDetectionStrategy.OnPush, host: {
2988
+ '[attr.id]': 'id',
2989
+ class: "f-component f-connection"
2990
+ }, providers: [{ provide: F_CONNECTION_COMPONENT, useExisting: FConnectionComponent }], template: "<ng-container xmlns:svg=\"http://www.w3.org/2000/svg\">\n <svg:linearGradient fConnectionGradient [fromTo]=\"fromTo\"></svg:linearGradient>\n <svg:path fConnectionSelection [attr.d]=\"path\" [fromTo]=\"fromTo\"></svg:path>\n <svg:g>\n <svg:path f-connection-path [attr.d]=\"path\" [fromTo]=\"fromTo\"></svg:path>\n <svg:circle f-connection-drag-handle r=\"8\"></svg:circle>\n </svg:g>\n <svg:text f-connection-text [fromTo]=\"fromTo\"></svg:text>\n</ng-container>\n" }]
2991
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: FFlowBase, decorators: [{
2992
+ type: Inject,
2993
+ args: [F_FLOW_COMPONENT]
2994
+ }] }]; }, propDecorators: { id: [{
2995
+ type: Input
2996
+ }], outputId: [{
2997
+ type: Input
2998
+ }], inputId: [{
2999
+ type: Input
3000
+ }], fPath: [{
3001
+ type: ViewChild,
3002
+ args: [FConnectionPathComponent, { static: true }]
3003
+ }], fGradient: [{
3004
+ type: ViewChild,
3005
+ args: [FConnectionGradientComponent, { static: true }]
3006
+ }], fDragHandle: [{
3007
+ type: ViewChild,
3008
+ args: [FConnectionDragHandleComponent, { static: true }]
3009
+ }], fSelection: [{
3010
+ type: ViewChild,
3011
+ args: [FConnectionSelectionComponent, { static: true }]
3012
+ }], fText: [{
3013
+ type: ViewChild,
3014
+ args: [FConnectionTextComponent, { static: true }]
3015
+ }] } });
3016
+
2980
3017
  class FFlowModule {
2981
3018
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.4", ngImport: i0, type: FFlowModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2982
3019
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.4", ngImport: i0, type: FFlowModule, declarations: [FFlowComponent,
@@ -3051,5 +3088,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.4", ngImpor
3051
3088
  * Generated bundle index. Do not edit.
3052
3089
  */
3053
3090
 
3054
- export { CONNECTION_MARKER_END, CONNECTION_MARKER_END_SELECTED, CONNECTION_MARKER_START, CONNECTION_MARKER_START_SELECTED, FCanvasDirective, FConnectIfIntersectDirective, FConnectionComponent, FConnectionModule, FConnectionsContainerComponent, FDragHandleDirective, FDraggableDirective, FExternalItemDirective, FFlowComponent, FFlowModule, FForeignObjectComponent, FItemsContainerDirective, FLineAlignmentDirective, FNodeComponent, FNodeInputDirective, FNodeOutletDirective, FNodeOutputDirective, FNodesContainerComponent, FSelectionDirective, FTempConnectionComponent, FZoomDirective, F_CONNECT_IF_INTERSECT, F_DRAG_HANDLE, F_LINE_ALIGNMENT, F_SELECTION, F_TEMP_CONNECTION_COMPONENT };
3091
+ export { CONNECTION_MARKER_END, CONNECTION_MARKER_END_SELECTED, CONNECTION_MARKER_START, CONNECTION_MARKER_START_SELECTED, CanvasChangeEvent, FCanvasDirective, FConnectIfIntersectDirective, FConnectionComponent, FConnectionModule, FConnectionsContainerComponent, FDragHandleDirective, FDraggableDirective, FExternalItemDirective, FFlowComponent, FFlowModule, FForeignObjectComponent, FItemsContainerDirective, FLineAlignmentDirective, FNodeComponent, FNodeInputDirective, FNodeOutletDirective, FNodeOutputDirective, FNodesContainerComponent, FSelectionDirective, FTempConnectionComponent, FZoomDirective, F_CONNECT_IF_INTERSECT, F_DRAG_HANDLE, F_LINE_ALIGNMENT, F_SELECTION, F_TEMP_CONNECTION_COMPONENT };
3055
3092
  //# sourceMappingURL=foblex-flow.mjs.map