ngx-vflow 0.13.0 → 0.14.1

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 (29) hide show
  1. package/esm2022/lib/vflow/components/background/background.component.mjs +7 -16
  2. package/esm2022/lib/vflow/components/default-node/default-node.component.mjs +18 -0
  3. package/esm2022/lib/vflow/components/defs/defs.component.mjs +1 -1
  4. package/esm2022/lib/vflow/components/node/node.component.mjs +8 -7
  5. package/esm2022/lib/vflow/components/vflow/vflow.component.mjs +11 -7
  6. package/esm2022/lib/vflow/math/edge-path/bezier-path.mjs +14 -17
  7. package/esm2022/lib/vflow/math/edge-path/straigh-path.mjs +2 -6
  8. package/esm2022/lib/vflow/models/handle.model.mjs +3 -2
  9. package/esm2022/lib/vflow/models/minimap.model.mjs +7 -0
  10. package/esm2022/lib/vflow/public-components/minimap/minimap.component.mjs +119 -0
  11. package/esm2022/lib/vflow/services/flow-entities.service.mjs +6 -5
  12. package/esm2022/lib/vflow/services/flow-settings.service.mjs +2 -1
  13. package/esm2022/lib/vflow/utils/transform-background.mjs +6 -0
  14. package/esm2022/lib/vflow/vflow.module.mjs +15 -7
  15. package/esm2022/public-api.mjs +2 -1
  16. package/fesm2022/ngx-vflow.mjs +189 -56
  17. package/fesm2022/ngx-vflow.mjs.map +1 -1
  18. package/lib/vflow/components/background/background.component.d.ts +3 -6
  19. package/lib/vflow/components/default-node/default-node.component.d.ts +6 -0
  20. package/lib/vflow/components/vflow/vflow.component.d.ts +2 -1
  21. package/lib/vflow/models/handle.model.d.ts +1 -0
  22. package/lib/vflow/models/minimap.model.d.ts +4 -0
  23. package/lib/vflow/public-components/minimap/minimap.component.d.ts +49 -0
  24. package/lib/vflow/services/flow-entities.service.d.ts +7 -5
  25. package/lib/vflow/services/flow-settings.service.d.ts +2 -0
  26. package/lib/vflow/utils/transform-background.d.ts +2 -0
  27. package/lib/vflow/vflow.module.d.ts +21 -19
  28. package/package.json +1 -3
  29. package/public-api.d.ts +1 -0
@@ -1,13 +1,12 @@
1
1
  import * as i1 from '@angular/common';
2
- import { CommonModule } from '@angular/common';
2
+ import { NgIf, NgFor, NgTemplateOutlet, NgComponentOutlet, KeyValuePipe } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
- import { signal, computed, Injectable, inject, ElementRef, Directive, effect, untracked, TemplateRef, EventEmitter, Output, DestroyRef, Input, runInInjectionContext, Injector, Component, ChangeDetectionStrategy, HostListener, ViewChild, NgZone, ContentChild, NgModule } 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';
5
5
  import { select } from 'd3-selection';
6
6
  import { zoomIdentity, zoom } from 'd3-zoom';
7
7
  import { switchMap, merge, fromEvent, tap, Subject, observeOn, animationFrameScheduler, skip, map, pairwise, filter, distinctUntilChanged, asyncScheduler, zip, share, Observable, startWith } from 'rxjs';
8
8
  import { toObservable, takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
9
9
  import { drag } from 'd3-drag';
10
- import { path } from 'd3-path';
11
10
  import { __decorate } from 'tslib';
12
11
 
13
12
  function getNodesBounds(nodes) {
@@ -94,6 +93,10 @@ class FlowEntitiesService {
94
93
  // empty arrays considered equal, other arrays may not be equal
95
94
  equal: (a, b) => !a.length && !b.length ? true : a === b
96
95
  });
96
+ this.validEdges = computed(() => {
97
+ const nodes = this.nodes();
98
+ return this.edges().filter(e => nodes.includes(e.source()) && nodes.includes(e.target()));
99
+ });
97
100
  this.connection = signal(new ConnectionModel({}));
98
101
  this.markers = computed(() => {
99
102
  const markersMap = new Map();
@@ -114,14 +117,11 @@ class FlowEntitiesService {
114
117
  }
115
118
  return markersMap;
116
119
  });
117
- this.validEdges = computed(() => {
118
- const nodes = this.nodes();
119
- return this.edges().filter(e => nodes.includes(e.source()) && nodes.includes(e.target()));
120
- });
121
120
  this.entities = computed(() => [
122
121
  ...this.nodes(),
123
122
  ...this.edges()
124
123
  ]);
124
+ this.minimap = signal(null);
125
125
  }
126
126
  getNode(id) {
127
127
  return this.nodes().find(({ node }) => node.id === id);
@@ -174,6 +174,7 @@ class FlowSettingsService {
174
174
  this.computedFlowHeight = signal(0);
175
175
  this.minZoom = signal(0.5);
176
176
  this.maxZoom = signal(3);
177
+ this.background = signal({ type: 'solid', color: '#fff' });
177
178
  }
178
179
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FlowSettingsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
179
180
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FlowSettingsService }); }
@@ -1125,11 +1126,8 @@ function getPointOnLineByRatio(start, end, ratio) {
1125
1126
  function straightPath(source, target, usingPoints = [false, false, false]) {
1126
1127
  const [start, center, end] = usingPoints;
1127
1128
  const nullPoint = { x: 0, y: 0 };
1128
- const path$1 = path();
1129
- path$1.moveTo(source.x, source.y);
1130
- path$1.lineTo(target.x, target.y);
1131
1129
  return {
1132
- path: path$1.toString(),
1130
+ path: `M ${source.x},${source.y}L ${target.x},${target.y}`,
1133
1131
  points: {
1134
1132
  start: start ? getPointOnLineByRatio(source, target, .15) : nullPoint,
1135
1133
  center: center ? getPointOnLineByRatio(source, target, .50) : nullPoint,
@@ -1139,13 +1137,11 @@ function straightPath(source, target, usingPoints = [false, false, false]) {
1139
1137
  }
1140
1138
 
1141
1139
  function bezierPath(source, target, sourcePosition, targetPosition, usingPoints = [false, false, false]) {
1142
- const path$1 = path();
1143
- path$1.moveTo(source.x, source.y);
1144
1140
  const distanceVector = { x: source.x - target.x, y: source.y - target.y };
1145
- const firstControl = calcControlPoint(source, sourcePosition, distanceVector);
1146
- const secondControl = calcControlPoint(target, targetPosition, distanceVector);
1147
- path$1.bezierCurveTo(firstControl.x, firstControl.y, secondControl.x, secondControl.y, target.x, target.y);
1148
- return getPathData(path$1, source, target, firstControl, secondControl, usingPoints);
1141
+ const sourceControl = calcControlPoint(source, sourcePosition, distanceVector);
1142
+ const targetControl = calcControlPoint(target, targetPosition, distanceVector);
1143
+ const path = `M${source.x},${source.y} C${sourceControl.x},${sourceControl.y} ${targetControl.x},${targetControl.y} ${target.x},${target.y}`;
1144
+ return getPathData(path, source, target, sourceControl, targetControl, usingPoints);
1149
1145
  }
1150
1146
  /**
1151
1147
  * Calculate control point based on provided point
@@ -1185,20 +1181,20 @@ function calcControlPoint(point, pointPosition, distanceVector) {
1185
1181
  y: point.y - factorPoint.y * controlOffset,
1186
1182
  };
1187
1183
  }
1188
- function getPathData(path, source, target, firstControl, secondControl, usingPoints) {
1184
+ function getPathData(path, source, target, sourceControl, targetControl, usingPoints) {
1189
1185
  const [start, center, end] = usingPoints;
1190
1186
  const nullPoint = { x: 0, y: 0 };
1191
1187
  return {
1192
- path: path.toString(),
1188
+ path,
1193
1189
  points: {
1194
1190
  start: start
1195
- ? getPointOnBezier(source, target, firstControl, secondControl, 0.1)
1191
+ ? getPointOnBezier(source, target, sourceControl, targetControl, 0.1)
1196
1192
  : nullPoint,
1197
1193
  center: center
1198
- ? getPointOnBezier(source, target, firstControl, secondControl, 0.5)
1194
+ ? getPointOnBezier(source, target, sourceControl, targetControl, 0.5)
1199
1195
  : nullPoint,
1200
1196
  end: end
1201
- ? getPointOnBezier(source, target, firstControl, secondControl, 0.9)
1197
+ ? getPointOnBezier(source, target, sourceControl, targetControl, 0.9)
1202
1198
  : nullPoint,
1203
1199
  },
1204
1200
  };
@@ -1206,10 +1202,10 @@ function getPathData(path, source, target, firstControl, secondControl, usingPoi
1206
1202
  /**
1207
1203
  * Get point on bezier curve by ratio
1208
1204
  */
1209
- function getPointOnBezier(sourcePoint, targetPoint, controlPoint1, controlPoint2, ratio) {
1210
- const fromSourceToFirstControl = getPointOnLineByRatio(sourcePoint, controlPoint1, ratio);
1211
- const fromFirstControlToSecond = getPointOnLineByRatio(controlPoint1, controlPoint2, ratio);
1212
- const fromSecondControlToTarget = getPointOnLineByRatio(controlPoint2, targetPoint, ratio);
1205
+ function getPointOnBezier(sourcePoint, targetPoint, sourceControl, targetControl, ratio) {
1206
+ const fromSourceToFirstControl = getPointOnLineByRatio(sourcePoint, sourceControl, ratio);
1207
+ const fromFirstControlToSecond = getPointOnLineByRatio(sourceControl, targetControl, ratio);
1208
+ const fromSecondControlToTarget = getPointOnLineByRatio(targetControl, targetPoint, ratio);
1213
1209
  return getPointOnLineByRatio(getPointOnLineByRatio(fromSourceToFirstControl, fromFirstControlToSecond, ratio), getPointOnLineByRatio(fromFirstControlToSecond, fromSecondControlToTarget, ratio), ratio);
1214
1210
  }
1215
1211
 
@@ -1676,6 +1672,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
1676
1672
  args: [{ selector: 'g[spacePointContext]' }]
1677
1673
  }] });
1678
1674
 
1675
+ function transformBackground(background) {
1676
+ return typeof background === 'string'
1677
+ ? { type: 'solid', color: background }
1678
+ : background;
1679
+ }
1680
+
1679
1681
  function Microtask(target, key, descriptor) {
1680
1682
  const originalMethod = descriptor.value;
1681
1683
  descriptor.value = function (...args) {
@@ -1754,6 +1756,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
1754
1756
  type: Injectable
1755
1757
  }] });
1756
1758
 
1759
+ class DefaultNodeComponent {
1760
+ constructor() {
1761
+ this.selected = false;
1762
+ }
1763
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DefaultNodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1764
+ 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"] }); }
1765
+ }
1766
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DefaultNodeComponent, decorators: [{
1767
+ type: Component,
1768
+ args: [{ selector: 'default-node', host: {
1769
+ '[class.selected]': 'selected'
1770
+ }, 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"] }]
1771
+ }], propDecorators: { selected: [{
1772
+ type: Input
1773
+ }] } });
1774
+
1757
1775
  class HandleModel {
1758
1776
  constructor(rawHandle, parentNode) {
1759
1777
  this.rawHandle = rawHandle;
@@ -1821,7 +1839,8 @@ class HandleModel {
1821
1839
  this.templateContext = {
1822
1840
  $implicit: {
1823
1841
  point: this.offset,
1824
- state: this.state
1842
+ state: this.state,
1843
+ node: this.parentNode.node
1825
1844
  }
1826
1845
  };
1827
1846
  }
@@ -2268,7 +2287,7 @@ class NodeComponent {
2268
2287
  }
2269
2288
  }
2270
2289
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2271
- 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" }, 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 <div\n #htmlWrapper\n class=\"default-node\"\n [class.default-node_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 </div>\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", styles: [".magnet{opacity:0}.wrapper{display:table-cell}.default-node{border:1.5px solid #1b262c;border-radius:5px;display:flex;align-items:center;justify-content:center;color:#000;background-color:#fff}.default-node_selected{border-width:2px}.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.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { 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: 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 }); }
2290
+ 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" }, 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", 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 }); }
2272
2291
  }
2273
2292
  __decorate([
2274
2293
  InjectionContext
@@ -2278,7 +2297,7 @@ __decorate([
2278
2297
  ], NodeComponent.prototype, "ngAfterViewInit", null);
2279
2298
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeComponent, decorators: [{
2280
2299
  type: Component,
2281
- args: [{ selector: 'g[node]', changeDetection: ChangeDetectionStrategy.OnPush, providers: [HandleService, NodeAccessorService], 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 <div\n #htmlWrapper\n class=\"default-node\"\n [class.default-node_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 </div>\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", styles: [".magnet{opacity:0}.wrapper{display:table-cell}.default-node{border:1.5px solid #1b262c;border-radius:5px;display:flex;align-items:center;justify-content:center;color:#000;background-color:#fff}.default-node_selected{border-width:2px}.default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}.default-handle{stroke:#fff;fill:#1b262c}\n"] }]
2300
+ args: [{ selector: 'g[node]', changeDetection: ChangeDetectionStrategy.OnPush, providers: [HandleService, NodeAccessorService], 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", 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"] }]
2282
2301
  }], propDecorators: { nodeModel: [{
2283
2302
  type: Input
2284
2303
  }], nodeTemplate: [{
@@ -2514,7 +2533,7 @@ class DefsComponent {
2514
2533
  this.defaultColor = 'rgb(177, 177, 183)';
2515
2534
  }
2516
2535
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DefsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2517
- 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.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2536
+ 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 }); }
2518
2537
  }
2519
2538
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DefsComponent, decorators: [{
2520
2539
  type: Component,
@@ -2534,13 +2553,11 @@ const defaultGap = 20;
2534
2553
  const defaultDotSize = 2;
2535
2554
  const defaultDotColor = 'rgb(177, 177, 183)';
2536
2555
  class BackgroundComponent {
2537
- set background(value) {
2538
- this.backgroundSignal.set(value);
2539
- }
2540
2556
  constructor() {
2541
2557
  this.viewportService = inject(ViewportService);
2542
2558
  this.rootSvg = inject(RootSvgReferenceDirective).element;
2543
- this.backgroundSignal = signal({ type: 'solid', color: defaultBg });
2559
+ this.settingsService = inject(FlowSettingsService);
2560
+ this.backgroundSignal = this.settingsService.background;
2544
2561
  this.scaledGap = computed(() => {
2545
2562
  const background = this.backgroundSignal();
2546
2563
  if (background.type === 'dots') {
@@ -2574,20 +2591,12 @@ class BackgroundComponent {
2574
2591
  });
2575
2592
  }
2576
2593
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BackgroundComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2577
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "16.2.12", type: BackgroundComponent, selector: "g[background]", inputs: { background: ["background", "background", transform] }, 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", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2594
+ 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", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2578
2595
  }
2579
2596
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BackgroundComponent, decorators: [{
2580
2597
  type: Component,
2581
2598
  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" }]
2582
- }], ctorParameters: function () { return []; }, propDecorators: { background: [{
2583
- type: Input,
2584
- args: [{ required: true, transform }]
2585
- }] } });
2586
- function transform(background) {
2587
- return typeof background === 'string'
2588
- ? { type: 'solid', color: background }
2589
- : background;
2590
- }
2599
+ }], ctorParameters: function () { return []; } });
2591
2600
 
2592
2601
  // TODO: too general purpose nane
2593
2602
  class RootSvgContextDirective {
@@ -2696,10 +2705,6 @@ class VflowComponent {
2696
2705
  this.componentEventBusService = inject(ComponentEventBusService);
2697
2706
  this.keyboardService = inject(KeyboardService);
2698
2707
  this.injector = inject(Injector);
2699
- /**
2700
- * Background for flow
2701
- */
2702
- this.background = '#fff';
2703
2708
  this.optimization = {
2704
2709
  computeLayersOnInit: true
2705
2710
  };
@@ -2744,6 +2749,7 @@ class VflowComponent {
2744
2749
  this.edgesChange$ = this.edgesChangeService.changes$;
2745
2750
  // #endregion
2746
2751
  this.markers = this.flowEntitiesService.markers;
2752
+ this.minimap = this.flowEntitiesService.minimap;
2747
2753
  }
2748
2754
  // #endregion
2749
2755
  // #region SETTINGS
@@ -2780,6 +2786,12 @@ class VflowComponent {
2780
2786
  set handlePositions(handlePositions) {
2781
2787
  this.flowSettingsService.handlePositions.set(handlePositions);
2782
2788
  }
2789
+ /**
2790
+ * Background for flow
2791
+ */
2792
+ set background(value) {
2793
+ this.flowSettingsService.background.set(transformBackground(value));
2794
+ }
2783
2795
  /**
2784
2796
  * Global rule if you can or can't select entities
2785
2797
  */
@@ -2899,7 +2911,7 @@ class VflowComponent {
2899
2911
  FlowSettingsService,
2900
2912
  ComponentEventBusService,
2901
2913
  KeyboardService
2902
- ], 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]=\"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 <!-- 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 </svg:g>\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: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { 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]", inputs: ["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 }); }
2914
+ ], 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 <!-- 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 </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", 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 }); }
2903
2915
  }
2904
2916
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: VflowComponent, decorators: [{
2905
2917
  type: Component,
@@ -2918,7 +2930,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
2918
2930
  ], hostDirectives: [
2919
2931
  connectionControllerHostDirective,
2920
2932
  changesControllerHostDirective
2921
- ], 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]=\"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 <!-- 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 </svg:g>\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"] }]
2933
+ ], 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 <!-- 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 </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", styles: [":host{display:block;width:100%;height:100%;-webkit-user-select:none;user-select:none}:host ::ng-deep *{box-sizing:border-box}\n"] }]
2922
2934
  }], propDecorators: { view: [{
2923
2935
  type: Input
2924
2936
  }], minZoom: [{
@@ -3004,9 +3016,125 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
3004
3016
  args: ['touchstart']
3005
3017
  }] } });
3006
3018
 
3019
+ class MinimapModel {
3020
+ constructor() {
3021
+ this.template = signal(null);
3022
+ }
3023
+ }
3024
+
3025
+ class MiniMapComponent {
3026
+ constructor() {
3027
+ this.entitiesService = inject(FlowEntitiesService);
3028
+ this.flowSettingsService = inject(FlowSettingsService);
3029
+ this.viewportService = inject(ViewportService);
3030
+ this.injector = inject(Injector);
3031
+ /**
3032
+ * The color outside the viewport (invisible area)
3033
+ */
3034
+ this.maskColor = `rgba(215, 215, 215, 0.6)`;
3035
+ /**
3036
+ * The minimap stroke color
3037
+ */
3038
+ this.strokeColor = `rgb(200, 200, 200)`;
3039
+ this.minimapOffset = 10;
3040
+ this.minimapScale = computed(() => {
3041
+ if (this.scaleOnHoverSignal()) {
3042
+ return this.hovered() ? 0.4 : 0.2;
3043
+ }
3044
+ return 0.2;
3045
+ });
3046
+ this.viewportColor = computed(() => this.flowSettingsService.background().color ?? '#fff');
3047
+ this.hovered = signal(false);
3048
+ this.minimapPoint = computed(() => {
3049
+ switch (this.minimapPosition()) {
3050
+ case 'top-left':
3051
+ return { x: this.minimapOffset, y: this.minimapOffset };
3052
+ case 'top-right':
3053
+ return {
3054
+ x: this.flowSettingsService.computedFlowWidth() - this.minimapWidth() - this.minimapOffset,
3055
+ y: this.minimapOffset
3056
+ };
3057
+ case 'bottom-left':
3058
+ return {
3059
+ x: this.minimapOffset,
3060
+ y: this.flowSettingsService.computedFlowHeight() - this.minimapHeight() - this.minimapOffset
3061
+ };
3062
+ case 'bottom-right':
3063
+ return {
3064
+ x: this.flowSettingsService.computedFlowWidth() - this.minimapWidth() - this.minimapOffset,
3065
+ y: this.flowSettingsService.computedFlowHeight() - this.minimapHeight() - this.minimapOffset
3066
+ };
3067
+ }
3068
+ });
3069
+ this.minimapWidth = computed(() => this.flowSettingsService.computedFlowWidth() * this.minimapScale());
3070
+ this.minimapHeight = computed(() => this.flowSettingsService.computedFlowHeight() * this.minimapScale());
3071
+ this.viewportTransform = computed(() => {
3072
+ const viewport = this.viewportService.readableViewport();
3073
+ let scale = 1 / viewport.zoom;
3074
+ let x = -(viewport.x * this.minimapScale()) * scale;
3075
+ x /= this.minimapScale();
3076
+ let y = -(viewport.y * this.minimapScale()) * scale;
3077
+ y /= this.minimapScale();
3078
+ scale /= this.minimapScale();
3079
+ return `translate(${x}, ${y}) scale(${scale})`;
3080
+ });
3081
+ this.boundsViewport = computed(() => {
3082
+ const nodes = this.entitiesService.nodes();
3083
+ return getViewportForBounds(getNodesBounds(nodes), this.flowSettingsService.computedFlowWidth(), this.flowSettingsService.computedFlowHeight(), -Infinity, 1.5, 0);
3084
+ });
3085
+ this.minimapTransform = computed(() => {
3086
+ const vport = this.boundsViewport();
3087
+ const x = vport.x * this.minimapScale();
3088
+ const y = vport.y * this.minimapScale();
3089
+ const scale = vport.zoom * this.minimapScale();
3090
+ return `translate(${x} ${y}) scale(${scale})`;
3091
+ });
3092
+ this.minimapPosition = signal('bottom-right');
3093
+ this.scaleOnHoverSignal = signal(false);
3094
+ }
3095
+ /**
3096
+ * The corner of the flow where to render a mini-map
3097
+ */
3098
+ set position(value) {
3099
+ this.minimapPosition.set(value);
3100
+ }
3101
+ /**
3102
+ * Make a minimap bigger on hover
3103
+ */
3104
+ set scaleOnHover(value) {
3105
+ this.scaleOnHoverSignal.set(value);
3106
+ }
3107
+ ngOnInit() {
3108
+ const model = new MinimapModel();
3109
+ model.template.set(this.minimap);
3110
+ this.entitiesService.minimap.set(model);
3111
+ }
3112
+ trackNodes(idx, { node }) {
3113
+ return node;
3114
+ }
3115
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MiniMapComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3116
+ 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"] }] }); }
3117
+ }
3118
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MiniMapComponent, decorators: [{
3119
+ type: Component,
3120
+ 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"] }]
3121
+ }], propDecorators: { position: [{
3122
+ type: Input
3123
+ }], maskColor: [{
3124
+ type: Input
3125
+ }], strokeColor: [{
3126
+ type: Input
3127
+ }], scaleOnHover: [{
3128
+ type: Input
3129
+ }], minimap: [{
3130
+ type: ViewChild,
3131
+ args: ['minimap', { static: true }]
3132
+ }] } });
3133
+
3007
3134
  const components = [
3008
3135
  VflowComponent,
3009
3136
  NodeComponent,
3137
+ DefaultNodeComponent,
3010
3138
  EdgeComponent,
3011
3139
  EdgeLabelComponent,
3012
3140
  ConnectionComponent,
@@ -3014,6 +3142,7 @@ const components = [
3014
3142
  DefsComponent,
3015
3143
  BackgroundComponent,
3016
3144
  ResizableComponent,
3145
+ MiniMapComponent
3017
3146
  ];
3018
3147
  const directives = [
3019
3148
  SpacePointContextDirective,
@@ -3038,13 +3167,15 @@ class VflowModule {
3038
3167
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: VflowModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
3039
3168
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: VflowModule, declarations: [VflowComponent,
3040
3169
  NodeComponent,
3170
+ DefaultNodeComponent,
3041
3171
  EdgeComponent,
3042
3172
  EdgeLabelComponent,
3043
3173
  ConnectionComponent,
3044
3174
  HandleComponent,
3045
3175
  DefsComponent,
3046
3176
  BackgroundComponent,
3047
- ResizableComponent, SpacePointContextDirective,
3177
+ ResizableComponent,
3178
+ MiniMapComponent, SpacePointContextDirective,
3048
3179
  MapContextDirective,
3049
3180
  RootSvgReferenceDirective,
3050
3181
  RootSvgContextDirective,
@@ -3057,26 +3188,28 @@ class VflowModule {
3057
3188
  EdgeLabelHtmlTemplateDirective,
3058
3189
  EdgeTemplateDirective,
3059
3190
  ConnectionTemplateDirective,
3060
- HandleTemplateDirective], imports: [CommonModule], exports: [VflowComponent,
3191
+ HandleTemplateDirective], imports: [NgIf, NgFor, NgTemplateOutlet, NgComponentOutlet, KeyValuePipe], exports: [VflowComponent,
3061
3192
  HandleComponent,
3062
3193
  ResizableComponent,
3063
- SelectableDirective, NodeHtmlTemplateDirective,
3194
+ SelectableDirective,
3195
+ MiniMapComponent, NodeHtmlTemplateDirective,
3064
3196
  GroupNodeTemplateDirective,
3065
3197
  EdgeLabelHtmlTemplateDirective,
3066
3198
  EdgeTemplateDirective,
3067
3199
  ConnectionTemplateDirective,
3068
3200
  HandleTemplateDirective] }); }
3069
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: VflowModule, imports: [CommonModule] }); }
3201
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: VflowModule }); }
3070
3202
  }
3071
3203
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: VflowModule, decorators: [{
3072
3204
  type: NgModule,
3073
3205
  args: [{
3074
- imports: [CommonModule],
3206
+ imports: [NgIf, NgFor, NgTemplateOutlet, NgComponentOutlet, KeyValuePipe],
3075
3207
  exports: [
3076
3208
  VflowComponent,
3077
3209
  HandleComponent,
3078
3210
  ResizableComponent,
3079
3211
  SelectableDirective,
3212
+ MiniMapComponent,
3080
3213
  ...templateDirectives
3081
3214
  ],
3082
3215
  declarations: [...components, ...directives, ...templateDirectives],
@@ -3089,5 +3222,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
3089
3222
  * Generated bundle index. Do not edit.
3090
3223
  */
3091
3224
 
3092
- export { ChangesControllerDirective, ConnectionControllerDirective, ConnectionTemplateDirective, CustomDynamicNodeComponent, CustomNodeComponent, EdgeLabelHtmlTemplateDirective, EdgeTemplateDirective, GroupNodeTemplateDirective, HandleComponent, HandleTemplateDirective, NodeHtmlTemplateDirective, ResizableComponent, SelectableDirective, VflowComponent, VflowModule, isComponentDynamicNode, isComponentStaticNode, isDefaultDynamicGroupNode, isDefaultDynamicNode, isDefaultStaticGroupNode, isDefaultStaticNode, isDynamicNode, isStaticNode, isTemplateDynamicGroupNode, isTemplateDynamicNode, isTemplateStaticGroupNode, isTemplateStaticNode };
3225
+ export { ChangesControllerDirective, ConnectionControllerDirective, ConnectionTemplateDirective, CustomDynamicNodeComponent, CustomNodeComponent, EdgeLabelHtmlTemplateDirective, EdgeTemplateDirective, GroupNodeTemplateDirective, HandleComponent, HandleTemplateDirective, MiniMapComponent, NodeHtmlTemplateDirective, ResizableComponent, SelectableDirective, VflowComponent, VflowModule, isComponentDynamicNode, isComponentStaticNode, isDefaultDynamicGroupNode, isDefaultDynamicNode, isDefaultStaticGroupNode, isDefaultStaticNode, isDynamicNode, isStaticNode, isTemplateDynamicGroupNode, isTemplateDynamicNode, isTemplateStaticGroupNode, isTemplateStaticNode };
3093
3226
  //# sourceMappingURL=ngx-vflow.mjs.map