ngx-vflow 1.8.2 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/esm2022/lib/vflow/components/connection/connection.component.mjs +33 -13
  2. package/esm2022/lib/vflow/components/edge/edge.component.mjs +3 -3
  3. package/esm2022/lib/vflow/components/vflow/vflow.component.mjs +12 -8
  4. package/esm2022/lib/vflow/interfaces/curve-factory.interface.mjs +2 -0
  5. package/esm2022/lib/vflow/interfaces/edge.interface.mjs +1 -1
  6. package/esm2022/lib/vflow/math/edge-path/bezier-path.mjs +12 -14
  7. package/esm2022/lib/vflow/math/edge-path/smooth-step-path.mjs +5 -5
  8. package/esm2022/lib/vflow/math/edge-path/straigh-path.mjs +7 -9
  9. package/esm2022/lib/vflow/models/edge.model.mjs +24 -8
  10. package/esm2022/lib/vflow/services/edge-rendering.service.mjs +3 -1
  11. package/esm2022/lib/vflow/services/flow-entities.service.mjs +3 -1
  12. package/esm2022/lib/vflow/services/node-rendering.service.mjs +5 -1
  13. package/esm2022/lib/vflow/utils/entities-per-frame.mjs +2 -0
  14. package/esm2022/public-api.mjs +15 -13
  15. package/esm2022/testing/component-mocks/custom-template-edge-mock.component.mjs +16 -0
  16. package/esm2022/testing/component-mocks/handle-mock.component.mjs +24 -0
  17. package/esm2022/{lib/vflow/testing-utils → testing}/component-mocks/minimap-mock.component.mjs +1 -1
  18. package/esm2022/testing/component-mocks/node-toolbar-mock.component.mjs +23 -0
  19. package/esm2022/testing/component-mocks/resizable-mock.component.mjs +25 -0
  20. package/esm2022/testing/component-mocks/vflow-mock.component.mjs +296 -0
  21. package/esm2022/testing/directive-mocks/connection-controller-mock.directive.mjs +27 -0
  22. package/esm2022/testing/directive-mocks/drag-handle-mock.directive.mjs +11 -0
  23. package/esm2022/{lib/vflow/testing-utils → testing}/directive-mocks/selectable-mock.directive.mjs +1 -1
  24. package/esm2022/{lib/vflow/testing-utils → testing}/directive-mocks/template-mock.directive.mjs +1 -1
  25. package/esm2022/testing/ngx-vflow-testing.mjs +5 -0
  26. package/esm2022/testing/provide-custom-node-mocks.mjs +59 -0
  27. package/esm2022/testing/public-api.mjs +13 -0
  28. package/esm2022/testing/types.mjs +2 -0
  29. package/esm2022/testing/vflow-mocks.mjs +28 -0
  30. package/fesm2022/ngx-vflow-testing.mjs +626 -0
  31. package/fesm2022/ngx-vflow-testing.mjs.map +1 -0
  32. package/fesm2022/ngx-vflow.mjs +94 -648
  33. package/fesm2022/ngx-vflow.mjs.map +1 -1
  34. package/lib/vflow/components/connection/connection.component.d.ts +4 -2
  35. package/lib/vflow/components/vflow/vflow.component.d.ts +4 -0
  36. package/lib/vflow/interfaces/curve-factory.interface.d.ts +44 -0
  37. package/lib/vflow/interfaces/edge.interface.d.ts +2 -1
  38. package/lib/vflow/math/edge-path/bezier-path.d.ts +2 -5
  39. package/lib/vflow/math/edge-path/smooth-step-path.d.ts +2 -3
  40. package/lib/vflow/math/edge-path/straigh-path.d.ts +2 -4
  41. package/lib/vflow/models/edge.model.d.ts +6 -4
  42. package/lib/vflow/services/edge-rendering.service.d.ts +1 -0
  43. package/lib/vflow/services/flow-entities.service.d.ts +3 -0
  44. package/lib/vflow/services/node-rendering.service.d.ts +3 -0
  45. package/lib/vflow/utils/entities-per-frame.d.ts +1 -0
  46. package/package.json +9 -3
  47. package/public-api.d.ts +13 -11
  48. package/testing/component-mocks/custom-template-edge-mock.component.d.ts +7 -0
  49. package/{lib/vflow/testing-utils → testing}/component-mocks/handle-mock.component.d.ts +2 -3
  50. package/{lib/vflow/testing-utils → testing}/component-mocks/minimap-mock.component.d.ts +1 -1
  51. package/{lib/vflow/testing-utils → testing}/component-mocks/node-toolbar-mock.component.d.ts +1 -2
  52. package/{lib/vflow/testing-utils → testing}/component-mocks/resizable-mock.component.d.ts +1 -1
  53. package/{lib/vflow/testing-utils → testing}/component-mocks/vflow-mock.component.d.ts +2 -14
  54. package/{lib/vflow/testing-utils → testing}/directive-mocks/connection-controller-mock.directive.d.ts +2 -3
  55. package/{lib/vflow/testing-utils → testing}/directive-mocks/drag-handle-mock.directive.d.ts +1 -1
  56. package/{lib/vflow/testing-utils → testing}/directive-mocks/selectable-mock.directive.d.ts +1 -1
  57. package/{lib/vflow/testing-utils → testing}/directive-mocks/template-mock.directive.d.ts +1 -1
  58. package/testing/index.d.ts +5 -0
  59. package/testing/public-api.d.ts +11 -0
  60. package/{lib/vflow/testing-utils → testing}/vflow-mocks.d.ts +2 -1
  61. package/esm2022/lib/vflow/interfaces/path-data.interface.mjs +0 -2
  62. package/esm2022/lib/vflow/testing-utils/component-mocks/handle-mock.component.mjs +0 -24
  63. package/esm2022/lib/vflow/testing-utils/component-mocks/node-toolbar-mock.component.mjs +0 -23
  64. package/esm2022/lib/vflow/testing-utils/component-mocks/resizable-mock.component.mjs +0 -25
  65. package/esm2022/lib/vflow/testing-utils/component-mocks/vflow-mock.component.mjs +0 -296
  66. package/esm2022/lib/vflow/testing-utils/directive-mocks/connection-controller-mock.directive.mjs +0 -27
  67. package/esm2022/lib/vflow/testing-utils/directive-mocks/drag-handle-mock.directive.mjs +0 -11
  68. package/esm2022/lib/vflow/testing-utils/provide-custom-node-mocks.mjs +0 -68
  69. package/esm2022/lib/vflow/testing-utils/types.mjs +0 -2
  70. package/esm2022/lib/vflow/testing-utils/vflow-mocks.mjs +0 -26
  71. package/esm2022/lib/vflow/types/using-points.type.mjs +0 -2
  72. package/lib/vflow/interfaces/path-data.interface.d.ts +0 -8
  73. package/lib/vflow/types/using-points.type.d.ts +0 -5
  74. /package/{lib/vflow/testing-utils → testing}/provide-custom-node-mocks.d.ts +0 -0
  75. /package/{lib/vflow/testing-utils → testing}/types.d.ts +0 -0
@@ -117,10 +117,12 @@ class FlowEntitiesService {
117
117
  // empty arrays considered equal, other arrays may not be equal
118
118
  equal: (a, b) => (!a.length && !b.length ? true : a === b),
119
119
  });
120
+ this.rawNodes = computed(() => this.nodes().map((n) => n.rawNode));
120
121
  this.edges = signal([], {
121
122
  // empty arrays considered equal, other arrays may not be equal
122
123
  equal: (a, b) => (!a.length && !b.length ? true : a === b),
123
124
  });
125
+ this.rawEdges = computed(() => this.edges().map((e) => e.edge));
124
126
  this.validEdges = computed(() => {
125
127
  const nodes = this.nodes();
126
128
  return this.edges().filter((e) => nodes.includes(e.source()) && nodes.includes(e.target()));
@@ -1097,25 +1099,23 @@ function getPointOnLineByRatio(start, end, ratio) {
1097
1099
  };
1098
1100
  }
1099
1101
 
1100
- function straightPath(source, target, usingPoints = [false, false, false]) {
1101
- const [start, center, end] = usingPoints;
1102
- const nullPoint = { x: 0, y: 0 };
1102
+ function straightPath({ sourcePoint, targetPoint }) {
1103
1103
  return {
1104
- path: `M ${source.x},${source.y}L ${target.x},${target.y}`,
1105
- points: {
1106
- start: start ? getPointOnLineByRatio(source, target, 0.15) : nullPoint,
1107
- center: center ? getPointOnLineByRatio(source, target, 0.5) : nullPoint,
1108
- end: end ? getPointOnLineByRatio(source, target, 0.85) : nullPoint,
1104
+ path: `M ${sourcePoint.x},${sourcePoint.y}L ${targetPoint.x},${targetPoint.y}`,
1105
+ labelPoints: {
1106
+ start: getPointOnLineByRatio(sourcePoint, targetPoint, 0.15),
1107
+ center: getPointOnLineByRatio(sourcePoint, targetPoint, 0.5),
1108
+ end: getPointOnLineByRatio(sourcePoint, targetPoint, 0.85),
1109
1109
  },
1110
1110
  };
1111
1111
  }
1112
1112
 
1113
- function bezierPath(source, target, sourcePosition, targetPosition, usingPoints = [false, false, false]) {
1114
- const distanceVector = { x: source.x - target.x, y: source.y - target.y };
1115
- const sourceControl = calcControlPoint(source, sourcePosition, distanceVector);
1116
- const targetControl = calcControlPoint(target, targetPosition, distanceVector);
1117
- const path = `M${source.x},${source.y} C${sourceControl.x},${sourceControl.y} ${targetControl.x},${targetControl.y} ${target.x},${target.y}`;
1118
- return getPathData(path, source, target, sourceControl, targetControl, usingPoints);
1113
+ function bezierPath({ sourcePoint, targetPoint, sourcePosition, targetPosition, }) {
1114
+ const distanceVector = { x: sourcePoint.x - targetPoint.x, y: sourcePoint.y - targetPoint.y };
1115
+ const sourceControl = calcControlPoint(sourcePoint, sourcePosition, distanceVector);
1116
+ const targetControl = calcControlPoint(targetPoint, targetPosition, distanceVector);
1117
+ const path = `M${sourcePoint.x},${sourcePoint.y} C${sourceControl.x},${sourceControl.y} ${targetControl.x},${targetControl.y} ${targetPoint.x},${targetPoint.y}`;
1118
+ return getPathData(path, sourcePoint, targetPoint, sourceControl, targetControl);
1119
1119
  }
1120
1120
  /**
1121
1121
  * Calculate control point based on provided point
@@ -1155,15 +1155,13 @@ function calcControlPoint(point, pointPosition, distanceVector) {
1155
1155
  y: point.y - factorPoint.y * controlOffset,
1156
1156
  };
1157
1157
  }
1158
- function getPathData(path, source, target, sourceControl, targetControl, usingPoints) {
1159
- const [start, center, end] = usingPoints;
1160
- const nullPoint = { x: 0, y: 0 };
1158
+ function getPathData(path, source, target, sourceControl, targetControl) {
1161
1159
  return {
1162
1160
  path,
1163
- points: {
1164
- start: start ? getPointOnBezier(source, target, sourceControl, targetControl, 0.1) : nullPoint,
1165
- center: center ? getPointOnBezier(source, target, sourceControl, targetControl, 0.5) : nullPoint,
1166
- end: end ? getPointOnBezier(source, target, sourceControl, targetControl, 0.9) : nullPoint,
1161
+ labelPoints: {
1162
+ start: getPointOnBezier(source, target, sourceControl, targetControl, 0.1),
1163
+ center: getPointOnBezier(source, target, sourceControl, targetControl, 0.5),
1164
+ end: getPointOnBezier(source, target, sourceControl, targetControl, 0.9),
1167
1165
  },
1168
1166
  };
1169
1167
  }
@@ -1317,11 +1315,11 @@ function getBend(a, b, c, size) {
1317
1315
  const yDir = a.y < c.y ? -1 : 1;
1318
1316
  return `L ${x},${y + bendSize * yDir}Q ${x},${y} ${x + bendSize * xDir},${y}`;
1319
1317
  }
1320
- function smoothStepPath(source, target, sourcePosition, targetPosition, borderRadius = 5) {
1318
+ function smoothStepPath({ sourcePoint, targetPoint, sourcePosition, targetPosition }, borderRadius = 5) {
1321
1319
  const [points, labelX, labelY] = getPoints({
1322
- source,
1320
+ source: sourcePoint,
1323
1321
  sourcePosition,
1324
- target,
1322
+ target: targetPoint,
1325
1323
  targetPosition,
1326
1324
  offset: 20,
1327
1325
  });
@@ -1338,7 +1336,7 @@ function smoothStepPath(source, target, sourcePosition, targetPosition, borderRa
1338
1336
  }, '');
1339
1337
  return {
1340
1338
  path,
1341
- points: {
1339
+ labelPoints: {
1342
1340
  // TODO start and end points temporary unavailable for this path
1343
1341
  start: { x: labelX, y: labelY },
1344
1342
  center: { x: labelX, y: labelY },
@@ -1350,6 +1348,7 @@ function smoothStepPath(source, target, sourcePosition, targetPosition, borderRa
1350
1348
  class EdgeModel {
1351
1349
  constructor(edge) {
1352
1350
  this.edge = edge;
1351
+ this.flowEntitiesService = inject(FlowEntitiesService);
1353
1352
  this.source = signal(undefined);
1354
1353
  this.target = signal(undefined);
1355
1354
  this.selected = signal(false);
@@ -1385,22 +1384,25 @@ class EdgeModel {
1385
1384
  if (!source || !target) {
1386
1385
  return {
1387
1386
  path: '',
1388
- points: {
1387
+ labelPoints: {
1389
1388
  start: { x: 0, y: 0 },
1390
1389
  center: { x: 0, y: 0 },
1391
1390
  end: { x: 0, y: 0 },
1392
1391
  },
1393
1392
  };
1394
1393
  }
1394
+ const params = this.getPathFactoryParams(source, target);
1395
1395
  switch (this.curve) {
1396
1396
  case 'straight':
1397
- return straightPath(source.pointAbsolute(), target.pointAbsolute(), this.usingPoints);
1397
+ return straightPath(params);
1398
1398
  case 'bezier':
1399
- return bezierPath(source.pointAbsolute(), target.pointAbsolute(), source.rawHandle.position, target.rawHandle.position, this.usingPoints);
1399
+ return bezierPath(params);
1400
1400
  case 'smooth-step':
1401
- return smoothStepPath(source.pointAbsolute(), target.pointAbsolute(), source.rawHandle.position, target.rawHandle.position);
1401
+ return smoothStepPath(params);
1402
1402
  case 'step':
1403
- return smoothStepPath(source.pointAbsolute(), target.pointAbsolute(), source.rawHandle.position, target.rawHandle.position, 0);
1403
+ return smoothStepPath(params, 0);
1404
+ default:
1405
+ return this.curve(params);
1404
1406
  }
1405
1407
  });
1406
1408
  this.sourceHandle = computed(() => {
@@ -1457,7 +1459,18 @@ class EdgeModel {
1457
1459
  this.edgeLabels.center = new EdgeLabelModel(edge.edgeLabels.center);
1458
1460
  if (edge.edgeLabels?.end)
1459
1461
  this.edgeLabels.end = new EdgeLabelModel(edge.edgeLabels.end);
1460
- this.usingPoints = [!!this.edgeLabels.start, !!this.edgeLabels.center, !!this.edgeLabels.end];
1462
+ }
1463
+ getPathFactoryParams(source, target) {
1464
+ return {
1465
+ mode: 'edge',
1466
+ edge: this.edge,
1467
+ sourcePoint: source.pointAbsolute(),
1468
+ targetPoint: target.pointAbsolute(),
1469
+ sourcePosition: source.rawHandle.position,
1470
+ targetPosition: target.rawHandle.position,
1471
+ allEdges: this.flowEntitiesService.rawEdges(),
1472
+ allNodes: this.flowEntitiesService.rawNodes(),
1473
+ };
1461
1474
  }
1462
1475
  }
1463
1476
 
@@ -1724,6 +1737,8 @@ function isGroupNode(node) {
1724
1737
  return node.rawNode.type === 'default-group' || node.rawNode.type === 'template-group';
1725
1738
  }
1726
1739
 
1740
+ const entitiesPerFrame = (total, perFrame) => Math.max(1, Math.ceil(total / perFrame));
1741
+
1727
1742
  class NodeRenderingService {
1728
1743
  constructor() {
1729
1744
  this.flowEntitiesService = inject(FlowEntitiesService);
@@ -1736,6 +1751,9 @@ class NodeRenderingService {
1736
1751
  this.nonGroups = computed(() => {
1737
1752
  return this.nodes().filter((n) => !isGroupNode(n));
1738
1753
  });
1754
+ this.nodesPerFrame = computed(() => entitiesPerFrame(this.nodes().length, 10));
1755
+ this.groupsPerFrame = computed(() => entitiesPerFrame(this.groups().length, 10));
1756
+ this.nonGroupsPerFrame = computed(() => entitiesPerFrame(this.nonGroups().length, 10));
1739
1757
  this.maxOrder = computed(() => {
1740
1758
  return Math.max(...this.flowEntitiesService.nodes().map((n) => n.renderOrder()));
1741
1759
  });
@@ -2134,6 +2152,7 @@ class EdgeRenderingService {
2134
2152
  this.edges = computed(() => {
2135
2153
  return this.flowEntitiesService.validEdges().sort((aNode, bNode) => aNode.renderOrder() - bNode.renderOrder());
2136
2154
  });
2155
+ this.edgesPerFrame = computed(() => entitiesPerFrame(this.edges().length, 10));
2137
2156
  this.maxOrder = computed(() => {
2138
2157
  return Math.max(...this.flowEntitiesService.validEdges().map((n) => n.renderOrder()));
2139
2158
  });
@@ -2269,14 +2288,14 @@ class EdgeComponent {
2269
2288
  this.connectionController?.startReconnection(handle, this.model());
2270
2289
  }
2271
2290
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2272
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: EdgeComponent, isStandalone: true, selector: "g[edge]", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, edgeTemplate: { classPropertyName: "edgeTemplate", publicName: "edgeTemplate", isSignal: true, isRequired: false, transformFunction: null }, edgeLabelHtmlTemplate: { classPropertyName: "edgeLabelHtmlTemplate", publicName: "edgeLabelHtmlTemplate", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.visibility": "isReconnecting() ? \"hidden\" : \"visible\"" }, classAttribute: "selectable" }, ngImport: i0, template: "@if (model().type === 'default') {\n <svg:path\n class=\"edge\"\n [attr.d]=\"model().path().path\"\n [attr.marker-start]=\"model().markerStartUrl()\"\n [attr.marker-end]=\"model().markerEndUrl()\"\n [class.edge_selected]=\"model().selected()\" />\n\n <svg:path class=\"interactive-edge\" [attr.d]=\"model().path().path\" (pointerStart)=\"select(); pull()\" />\n}\n\n@if (model().type === 'template' && edgeTemplate()) {\n @if (edgeTemplate(); as edgeTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"edgeTemplate\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n }\n}\n\n@if (model().edgeLabels.start; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.start\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().edgeLabels.center; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.center\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().edgeLabels.end; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.end\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().sourceHandle() && model().targetHandle()) {\n @if (model().reconnectable === true || model().reconnectable === 'source') {\n <svg:circle\n class=\"reconnect-handle\"\n r=\"10\"\n [attr.cx]=\"model().sourceHandle()!.pointAbsolute().x\"\n [attr.cy]=\"model().sourceHandle()!.pointAbsolute().y\"\n (pointerStart)=\"startReconnection($event, model().targetHandle()!)\" />\n }\n\n @if (model().reconnectable === true || model().reconnectable === 'target') {\n <svg:circle\n class=\"reconnect-handle\"\n r=\"10\"\n [attr.cx]=\"model().targetHandle()!.pointAbsolute().x\"\n [attr.cy]=\"model().targetHandle()!.pointAbsolute().y\"\n (pointerStart)=\"startReconnection($event, model().sourceHandle()!)\" />\n }\n}\n", styles: [".edge{fill:none;stroke-width:2;stroke:#b1b1b7}.edge_selected{stroke-width:2.5;stroke:#0f4c75}.interactive-edge{fill:none;stroke-width:20;stroke:transparent}.reconnect-handle{fill:transparent;cursor:move}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: EdgeLabelComponent, selector: "g[edgeLabel]", inputs: ["model", "edgeModel", "point", "htmlTemplate"] }, { kind: "directive", type: PointerDirective, selector: "[pointerStart], [pointerEnd], [pointerOver], [pointerOut]", outputs: ["pointerOver", "pointerOut", "pointerStart", "pointerEnd"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2291
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: EdgeComponent, isStandalone: true, selector: "g[edge]", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, edgeTemplate: { classPropertyName: "edgeTemplate", publicName: "edgeTemplate", isSignal: true, isRequired: false, transformFunction: null }, edgeLabelHtmlTemplate: { classPropertyName: "edgeLabelHtmlTemplate", publicName: "edgeLabelHtmlTemplate", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.visibility": "isReconnecting() ? \"hidden\" : \"visible\"" }, classAttribute: "selectable" }, ngImport: i0, template: "@if (model().type === 'default') {\n <svg:path\n class=\"edge\"\n [attr.d]=\"model().path().path\"\n [attr.marker-start]=\"model().markerStartUrl()\"\n [attr.marker-end]=\"model().markerEndUrl()\"\n [class.edge_selected]=\"model().selected()\" />\n\n <svg:path class=\"interactive-edge\" [attr.d]=\"model().path().path\" (pointerStart)=\"select(); pull()\" />\n}\n\n@if (model().type === 'template' && edgeTemplate()) {\n @if (edgeTemplate(); as edgeTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"edgeTemplate\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n }\n}\n\n@if (model().edgeLabels.start; as label) {\n @if (model().path().labelPoints?.start; as point) {\n <svg:g edgeLabel [model]=\"label\" [point]=\"point\" [edgeModel]=\"model()\" [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n }\n}\n\n@if (model().edgeLabels.center; as label) {\n @if (model().path().labelPoints?.center; as point) {\n <svg:g edgeLabel [model]=\"label\" [point]=\"point\" [edgeModel]=\"model()\" [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n }\n}\n\n@if (model().edgeLabels.end; as label) {\n @if (model().path().labelPoints?.end; as point) {\n <svg:g edgeLabel [model]=\"label\" [point]=\"point\" [edgeModel]=\"model()\" [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n }\n}\n\n@if (model().sourceHandle() && model().targetHandle()) {\n @if (model().reconnectable === true || model().reconnectable === 'source') {\n <svg:circle\n class=\"reconnect-handle\"\n r=\"10\"\n [attr.cx]=\"model().sourceHandle()!.pointAbsolute().x\"\n [attr.cy]=\"model().sourceHandle()!.pointAbsolute().y\"\n (pointerStart)=\"startReconnection($event, model().targetHandle()!)\" />\n }\n\n @if (model().reconnectable === true || model().reconnectable === 'target') {\n <svg:circle\n class=\"reconnect-handle\"\n r=\"10\"\n [attr.cx]=\"model().targetHandle()!.pointAbsolute().x\"\n [attr.cy]=\"model().targetHandle()!.pointAbsolute().y\"\n (pointerStart)=\"startReconnection($event, model().sourceHandle()!)\" />\n }\n}\n", styles: [".edge{fill:none;stroke-width:2;stroke:#b1b1b7}.edge_selected{stroke-width:2.5;stroke:#0f4c75}.interactive-edge{fill:none;stroke-width:20;stroke:transparent}.reconnect-handle{fill:transparent;cursor:move}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: EdgeLabelComponent, selector: "g[edgeLabel]", inputs: ["model", "edgeModel", "point", "htmlTemplate"] }, { kind: "directive", type: PointerDirective, selector: "[pointerStart], [pointerEnd], [pointerOver], [pointerOut]", outputs: ["pointerOver", "pointerOut", "pointerStart", "pointerEnd"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2273
2292
  }
2274
2293
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeComponent, decorators: [{
2275
2294
  type: Component,
2276
2295
  args: [{ standalone: true, selector: 'g[edge]', changeDetection: ChangeDetectionStrategy.OnPush, host: {
2277
2296
  class: 'selectable',
2278
2297
  '[style.visibility]': 'isReconnecting() ? "hidden" : "visible"',
2279
- }, imports: [NgTemplateOutlet, EdgeLabelComponent, PointerDirective], template: "@if (model().type === 'default') {\n <svg:path\n class=\"edge\"\n [attr.d]=\"model().path().path\"\n [attr.marker-start]=\"model().markerStartUrl()\"\n [attr.marker-end]=\"model().markerEndUrl()\"\n [class.edge_selected]=\"model().selected()\" />\n\n <svg:path class=\"interactive-edge\" [attr.d]=\"model().path().path\" (pointerStart)=\"select(); pull()\" />\n}\n\n@if (model().type === 'template' && edgeTemplate()) {\n @if (edgeTemplate(); as edgeTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"edgeTemplate\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n }\n}\n\n@if (model().edgeLabels.start; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.start\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().edgeLabels.center; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.center\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().edgeLabels.end; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.end\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().sourceHandle() && model().targetHandle()) {\n @if (model().reconnectable === true || model().reconnectable === 'source') {\n <svg:circle\n class=\"reconnect-handle\"\n r=\"10\"\n [attr.cx]=\"model().sourceHandle()!.pointAbsolute().x\"\n [attr.cy]=\"model().sourceHandle()!.pointAbsolute().y\"\n (pointerStart)=\"startReconnection($event, model().targetHandle()!)\" />\n }\n\n @if (model().reconnectable === true || model().reconnectable === 'target') {\n <svg:circle\n class=\"reconnect-handle\"\n r=\"10\"\n [attr.cx]=\"model().targetHandle()!.pointAbsolute().x\"\n [attr.cy]=\"model().targetHandle()!.pointAbsolute().y\"\n (pointerStart)=\"startReconnection($event, model().sourceHandle()!)\" />\n }\n}\n", styles: [".edge{fill:none;stroke-width:2;stroke:#b1b1b7}.edge_selected{stroke-width:2.5;stroke:#0f4c75}.interactive-edge{fill:none;stroke-width:20;stroke:transparent}.reconnect-handle{fill:transparent;cursor:move}\n"] }]
2298
+ }, imports: [NgTemplateOutlet, EdgeLabelComponent, PointerDirective], template: "@if (model().type === 'default') {\n <svg:path\n class=\"edge\"\n [attr.d]=\"model().path().path\"\n [attr.marker-start]=\"model().markerStartUrl()\"\n [attr.marker-end]=\"model().markerEndUrl()\"\n [class.edge_selected]=\"model().selected()\" />\n\n <svg:path class=\"interactive-edge\" [attr.d]=\"model().path().path\" (pointerStart)=\"select(); pull()\" />\n}\n\n@if (model().type === 'template' && edgeTemplate()) {\n @if (edgeTemplate(); as edgeTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"edgeTemplate\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n }\n}\n\n@if (model().edgeLabels.start; as label) {\n @if (model().path().labelPoints?.start; as point) {\n <svg:g edgeLabel [model]=\"label\" [point]=\"point\" [edgeModel]=\"model()\" [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n }\n}\n\n@if (model().edgeLabels.center; as label) {\n @if (model().path().labelPoints?.center; as point) {\n <svg:g edgeLabel [model]=\"label\" [point]=\"point\" [edgeModel]=\"model()\" [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n }\n}\n\n@if (model().edgeLabels.end; as label) {\n @if (model().path().labelPoints?.end; as point) {\n <svg:g edgeLabel [model]=\"label\" [point]=\"point\" [edgeModel]=\"model()\" [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n }\n}\n\n@if (model().sourceHandle() && model().targetHandle()) {\n @if (model().reconnectable === true || model().reconnectable === 'source') {\n <svg:circle\n class=\"reconnect-handle\"\n r=\"10\"\n [attr.cx]=\"model().sourceHandle()!.pointAbsolute().x\"\n [attr.cy]=\"model().sourceHandle()!.pointAbsolute().y\"\n (pointerStart)=\"startReconnection($event, model().targetHandle()!)\" />\n }\n\n @if (model().reconnectable === true || model().reconnectable === 'target') {\n <svg:circle\n class=\"reconnect-handle\"\n r=\"10\"\n [attr.cx]=\"model().targetHandle()!.pointAbsolute().x\"\n [attr.cy]=\"model().targetHandle()!.pointAbsolute().y\"\n (pointerStart)=\"startReconnection($event, model().sourceHandle()!)\" />\n }\n}\n", styles: [".edge{fill:none;stroke-width:2;stroke:#b1b1b7}.edge_selected{stroke-width:2.5;stroke:#0f4c75}.interactive-edge{fill:none;stroke-width:20;stroke:transparent}.reconnect-handle{fill:transparent;cursor:move}\n"] }]
2280
2299
  }] });
2281
2300
 
2282
2301
  class HandleService {
@@ -2885,27 +2904,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
2885
2904
 
2886
2905
  class ConnectionComponent {
2887
2906
  constructor() {
2888
- this.model = input.required();
2889
- this.template = input();
2890
2907
  this.flowStatusService = inject(FlowStatusService);
2891
2908
  this.spacePointContext = inject(SpacePointContextDirective);
2909
+ this.flowEntitiesService = inject(FlowEntitiesService);
2910
+ this.model = input.required();
2911
+ this.template = input();
2892
2912
  this.path = computed(() => {
2893
2913
  const status = this.flowStatusService.status();
2914
+ const curve = this.model().curve;
2894
2915
  if (status.state === 'connection-start' || status.state === 'reconnection-start') {
2895
2916
  const sourceHandle = status.payload.sourceHandle;
2896
2917
  const sourcePoint = sourceHandle.pointAbsolute();
2897
2918
  const sourcePosition = sourceHandle.rawHandle.position;
2898
2919
  const targetPoint = this.spacePointContext.svgCurrentSpacePoint();
2899
2920
  const targetPosition = getOppositePostion(sourceHandle.rawHandle.position);
2900
- switch (this.model().curve) {
2921
+ const params = this.getPathFactoryParams(sourcePoint, targetPoint, sourcePosition, targetPosition);
2922
+ switch (curve) {
2901
2923
  case 'straight':
2902
- return straightPath(sourcePoint, targetPoint).path;
2924
+ return straightPath(params).path;
2903
2925
  case 'bezier':
2904
- return bezierPath(sourcePoint, targetPoint, sourcePosition, targetPosition).path;
2926
+ return bezierPath(params).path;
2905
2927
  case 'smooth-step':
2906
- return smoothStepPath(sourcePoint, targetPoint, sourcePosition, targetPosition).path;
2928
+ return smoothStepPath(params).path;
2907
2929
  case 'step':
2908
- return smoothStepPath(sourcePoint, targetPoint, sourcePosition, targetPosition, 0).path;
2930
+ return smoothStepPath(params, 0).path;
2931
+ default:
2932
+ return curve(params).path;
2909
2933
  }
2910
2934
  }
2911
2935
  if (status.state === 'connection-validation' || status.state === 'reconnection-validation') {
@@ -2920,15 +2944,18 @@ class ConnectionComponent {
2920
2944
  const targetPosition = status.payload.valid
2921
2945
  ? targetHandle.rawHandle.position
2922
2946
  : getOppositePostion(sourceHandle.rawHandle.position);
2923
- switch (this.model().curve) {
2947
+ const params = this.getPathFactoryParams(sourcePoint, targetPoint, sourcePosition, targetPosition);
2948
+ switch (curve) {
2924
2949
  case 'straight':
2925
- return straightPath(sourcePoint, targetPoint).path;
2950
+ return straightPath(params).path;
2926
2951
  case 'bezier':
2927
- return bezierPath(sourcePoint, targetPoint, sourcePosition, targetPosition).path;
2952
+ return bezierPath(params).path;
2928
2953
  case 'smooth-step':
2929
- return smoothStepPath(sourcePoint, targetPoint, sourcePosition, targetPosition).path;
2954
+ return smoothStepPath(params).path;
2930
2955
  case 'step':
2931
- return smoothStepPath(sourcePoint, targetPoint, sourcePosition, targetPosition, 0).path;
2956
+ return smoothStepPath(params, 0).path;
2957
+ default:
2958
+ return curve(params).path;
2932
2959
  }
2933
2960
  }
2934
2961
  return null;
@@ -2951,6 +2978,17 @@ class ConnectionComponent {
2951
2978
  },
2952
2979
  };
2953
2980
  }
2981
+ getPathFactoryParams(sourcePoint, targetPoint, sourcePosition, targetPosition) {
2982
+ return {
2983
+ mode: 'connection',
2984
+ sourcePoint,
2985
+ targetPoint,
2986
+ sourcePosition,
2987
+ targetPosition,
2988
+ allEdges: this.flowEntitiesService.rawEdges(),
2989
+ allNodes: this.flowEntitiesService.rawNodes(),
2990
+ };
2991
+ }
2954
2992
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ConnectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2955
2993
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: ConnectionComponent, isStandalone: true, selector: "g[connection]", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, template: { classPropertyName: "template", publicName: "template", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
2956
2994
  @if (model().type === 'default') {
@@ -3521,10 +3559,14 @@ class VflowComponent {
3521
3559
  this.optimization = input({
3522
3560
  detachedGroupsLayer: false,
3523
3561
  });
3524
- this.nodeModels = computed(() => this.nodeRenderingService.nodes());
3525
- this.groups = computed(() => this.nodeRenderingService.groups());
3526
- this.nonGroups = computed(() => this.nodeRenderingService.nonGroups());
3527
- this.edgeModels = computed(() => this.edgeRenderingService.edges());
3562
+ this.nodeModels = this.nodeRenderingService.nodes;
3563
+ this.nodesPerFrame = this.nodeRenderingService.nodesPerFrame;
3564
+ this.groups = this.nodeRenderingService.groups;
3565
+ this.groupsPerFrame = this.nodeRenderingService.groupsPerFrame;
3566
+ this.nonGroups = this.nodeRenderingService.nonGroups;
3567
+ this.nonGroupsPerFrame = this.nodeRenderingService.nonGroupsPerFrame;
3568
+ this.edgeModels = this.edgeRenderingService.edges;
3569
+ this.edgesPerFrame = this.edgeRenderingService.edgesPerFrame;
3528
3570
  // #endregion
3529
3571
  // #region OUTPUTS
3530
3572
  /**
@@ -3785,7 +3827,7 @@ class VflowComponent {
3785
3827
  ComponentEventBusService,
3786
3828
  KeyboardService,
3787
3829
  OverlaysService,
3788
- ], queries: [{ propertyName: "nodeTemplateDirective", first: true, predicate: NodeHtmlTemplateDirective, descendants: true, isSignal: true }, { propertyName: "nodeSvgTemplateDirective", first: true, predicate: NodeSvgTemplateDirective, descendants: true, isSignal: true }, { propertyName: "groupNodeTemplateDirective", first: true, predicate: GroupNodeTemplateDirective, descendants: true, isSignal: true }, { propertyName: "edgeTemplateDirective", first: true, predicate: EdgeTemplateDirective, descendants: true, isSignal: true }, { propertyName: "edgeLabelHtmlDirective", first: true, predicate: EdgeLabelHtmlTemplateDirective, descendants: true, isSignal: true }, { propertyName: "connectionTemplateDirective", first: true, predicate: ConnectionTemplateDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "mapContext", first: true, predicate: MapContextDirective, descendants: true, isSignal: true }, { propertyName: "spacePointContext", first: true, predicate: SpacePointContextDirective, descendants: true, isSignal: true }], hostDirectives: [{ directive: 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 #flow rootSvgRef rootSvgContext rootPointer flowSizeController class=\"root-svg\">\n <defs flowDefs [markers]=\"markers()\" />\n\n <g background />\n\n <svg:g mapContext spacePointContext>\n <!-- Connection -->\n <svg:g connection [model]=\"connection\" [template]=\"connectionTemplateDirective()?.templateRef\" />\n\n @if (optimization().detachedGroupsLayer) {\n <!-- Groups -->\n <svg:g\n *lazyFor=\"let model of groups(); trackBy: trackNodes\"\n node\n [model]=\"model\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n\n <!-- Edges -->\n <svg:g\n *lazyFor=\"let model of edgeModels(); trackBy: trackEdges\"\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\" />\n\n <!-- Nodes -->\n <svg:g\n *lazyFor=\"let model of nonGroups(); trackBy: trackNodes\"\n node\n [model]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [nodeSvgTemplate]=\"nodeSvgTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n\n @if (!optimization().detachedGroupsLayer) {\n <!-- Edges -->\n <svg:g\n *lazyFor=\"let model of edgeModels(); trackBy: trackEdges\"\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\" />\n\n <!-- Nodes -->\n <svg:g\n *lazyFor=\"let model of nodeModels(); trackBy: trackNodes\"\n node\n [model]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [nodeSvgTemplate]=\"nodeSvgTemplateDirective()?.templateRef\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n </svg:g>\n\n <!-- Minimap -->\n @if (minimap(); as minimap) {\n <ng-container [ngTemplateOutlet]=\"minimap.template()\" />\n }\n</svg:svg>\n", styles: [":host{display:block;width:100%;height:100%;-webkit-user-select:none;user-select:none}:host ::ng-deep *{box-sizing:border-box}\n"], dependencies: [{ kind: "directive", type: RootSvgReferenceDirective, selector: "svg[rootSvgRef]" }, { kind: "directive", type: RootSvgContextDirective, selector: "svg[rootSvgContext]" }, { kind: "directive", type: RootPointerDirective, selector: "svg[rootPointer]" }, { kind: "directive", type: FlowSizeControllerDirective, selector: "svg[flowSizeController]" }, { kind: "component", type: DefsComponent, selector: "defs[flowDefs]", inputs: ["markers"] }, { kind: "component", type: BackgroundComponent, selector: "g[background]" }, { kind: "directive", type: MapContextDirective, selector: "g[mapContext]" }, { kind: "directive", type: SpacePointContextDirective, selector: "g[spacePointContext]" }, { kind: "component", type: ConnectionComponent, selector: "g[connection]", inputs: ["model", "template"] }, { kind: "component", type: NodeComponent, selector: "g[node]", inputs: ["model", "nodeTemplate", "nodeSvgTemplate", "groupNodeTemplate"] }, { kind: "component", type: EdgeComponent, selector: "g[edge]", inputs: ["model", "edgeTemplate", "edgeLabelHtmlTemplate"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: LazyForDirective, selector: "[lazyFor][lazyForOf]", inputs: ["lazyForOf", "lazyForTrackBy", "lazyForItemsPerFrame", "lazyForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3830
+ ], queries: [{ propertyName: "nodeTemplateDirective", first: true, predicate: NodeHtmlTemplateDirective, descendants: true, isSignal: true }, { propertyName: "nodeSvgTemplateDirective", first: true, predicate: NodeSvgTemplateDirective, descendants: true, isSignal: true }, { propertyName: "groupNodeTemplateDirective", first: true, predicate: GroupNodeTemplateDirective, descendants: true, isSignal: true }, { propertyName: "edgeTemplateDirective", first: true, predicate: EdgeTemplateDirective, descendants: true, isSignal: true }, { propertyName: "edgeLabelHtmlDirective", first: true, predicate: EdgeLabelHtmlTemplateDirective, descendants: true, isSignal: true }, { propertyName: "connectionTemplateDirective", first: true, predicate: ConnectionTemplateDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "mapContext", first: true, predicate: MapContextDirective, descendants: true, isSignal: true }, { propertyName: "spacePointContext", first: true, predicate: SpacePointContextDirective, descendants: true, isSignal: true }], hostDirectives: [{ directive: 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 #flow rootSvgRef rootSvgContext rootPointer flowSizeController class=\"root-svg\">\n <defs flowDefs [markers]=\"markers()\" />\n\n <g background />\n\n <svg:g mapContext spacePointContext>\n <!-- Connection -->\n <svg:g connection [model]=\"connection\" [template]=\"connectionTemplateDirective()?.templateRef\" />\n\n @if (optimization().detachedGroupsLayer) {\n <!-- Groups -->\n <svg:g\n *lazyFor=\"let model of groups(); trackBy: trackNodes; itemsPerFrame: groupsPerFrame()\"\n node\n [model]=\"model\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n\n <!-- Edges -->\n <svg:g\n *lazyFor=\"let model of edgeModels(); trackBy: trackEdges; itemsPerFrame: edgesPerFrame()\"\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\" />\n\n <!-- Nodes -->\n <svg:g\n *lazyFor=\"let model of nonGroups(); trackBy: trackNodes; itemsPerFrame: nonGroupsPerFrame()\"\n node\n [model]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [nodeSvgTemplate]=\"nodeSvgTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n\n @if (!optimization().detachedGroupsLayer) {\n <!-- Edges -->\n <svg:g\n *lazyFor=\"let model of edgeModels(); trackBy: trackEdges; itemsPerFrame: edgesPerFrame()\"\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\" />\n\n <!-- Nodes -->\n <svg:g\n *lazyFor=\"let model of nodeModels(); trackBy: trackNodes; itemsPerFrame: nodesPerFrame()\"\n node\n [model]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [nodeSvgTemplate]=\"nodeSvgTemplateDirective()?.templateRef\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n </svg:g>\n\n <!-- Minimap -->\n @if (minimap(); as minimap) {\n <ng-container [ngTemplateOutlet]=\"minimap.template()\" />\n }\n</svg:svg>\n", styles: [":host{display:block;width:100%;height:100%;-webkit-user-select:none;user-select:none}:host ::ng-deep *{box-sizing:border-box}\n"], dependencies: [{ kind: "directive", type: RootSvgReferenceDirective, selector: "svg[rootSvgRef]" }, { kind: "directive", type: RootSvgContextDirective, selector: "svg[rootSvgContext]" }, { kind: "directive", type: RootPointerDirective, selector: "svg[rootPointer]" }, { kind: "directive", type: FlowSizeControllerDirective, selector: "svg[flowSizeController]" }, { kind: "component", type: DefsComponent, selector: "defs[flowDefs]", inputs: ["markers"] }, { kind: "component", type: BackgroundComponent, selector: "g[background]" }, { kind: "directive", type: MapContextDirective, selector: "g[mapContext]" }, { kind: "directive", type: SpacePointContextDirective, selector: "g[spacePointContext]" }, { kind: "component", type: ConnectionComponent, selector: "g[connection]", inputs: ["model", "template"] }, { kind: "component", type: NodeComponent, selector: "g[node]", inputs: ["model", "nodeTemplate", "nodeSvgTemplate", "groupNodeTemplate"] }, { kind: "component", type: EdgeComponent, selector: "g[edge]", inputs: ["model", "edgeTemplate", "edgeLabelHtmlTemplate"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: LazyForDirective, selector: "[lazyFor][lazyForOf]", inputs: ["lazyForOf", "lazyForTrackBy", "lazyForItemsPerFrame", "lazyForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3789
3831
  }
3790
3832
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: VflowComponent, decorators: [{
3791
3833
  type: Component,
@@ -3817,7 +3859,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
3817
3859
  EdgeComponent,
3818
3860
  NgTemplateOutlet,
3819
3861
  LazyForDirective,
3820
- ], template: "<svg:svg #flow rootSvgRef rootSvgContext rootPointer flowSizeController class=\"root-svg\">\n <defs flowDefs [markers]=\"markers()\" />\n\n <g background />\n\n <svg:g mapContext spacePointContext>\n <!-- Connection -->\n <svg:g connection [model]=\"connection\" [template]=\"connectionTemplateDirective()?.templateRef\" />\n\n @if (optimization().detachedGroupsLayer) {\n <!-- Groups -->\n <svg:g\n *lazyFor=\"let model of groups(); trackBy: trackNodes\"\n node\n [model]=\"model\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n\n <!-- Edges -->\n <svg:g\n *lazyFor=\"let model of edgeModels(); trackBy: trackEdges\"\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\" />\n\n <!-- Nodes -->\n <svg:g\n *lazyFor=\"let model of nonGroups(); trackBy: trackNodes\"\n node\n [model]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [nodeSvgTemplate]=\"nodeSvgTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n\n @if (!optimization().detachedGroupsLayer) {\n <!-- Edges -->\n <svg:g\n *lazyFor=\"let model of edgeModels(); trackBy: trackEdges\"\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\" />\n\n <!-- Nodes -->\n <svg:g\n *lazyFor=\"let model of nodeModels(); trackBy: trackNodes\"\n node\n [model]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [nodeSvgTemplate]=\"nodeSvgTemplateDirective()?.templateRef\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n </svg:g>\n\n <!-- Minimap -->\n @if (minimap(); as minimap) {\n <ng-container [ngTemplateOutlet]=\"minimap.template()\" />\n }\n</svg:svg>\n", styles: [":host{display:block;width:100%;height:100%;-webkit-user-select:none;user-select:none}:host ::ng-deep *{box-sizing:border-box}\n"] }]
3862
+ ], template: "<svg:svg #flow rootSvgRef rootSvgContext rootPointer flowSizeController class=\"root-svg\">\n <defs flowDefs [markers]=\"markers()\" />\n\n <g background />\n\n <svg:g mapContext spacePointContext>\n <!-- Connection -->\n <svg:g connection [model]=\"connection\" [template]=\"connectionTemplateDirective()?.templateRef\" />\n\n @if (optimization().detachedGroupsLayer) {\n <!-- Groups -->\n <svg:g\n *lazyFor=\"let model of groups(); trackBy: trackNodes; itemsPerFrame: groupsPerFrame()\"\n node\n [model]=\"model\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n\n <!-- Edges -->\n <svg:g\n *lazyFor=\"let model of edgeModels(); trackBy: trackEdges; itemsPerFrame: edgesPerFrame()\"\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\" />\n\n <!-- Nodes -->\n <svg:g\n *lazyFor=\"let model of nonGroups(); trackBy: trackNodes; itemsPerFrame: nonGroupsPerFrame()\"\n node\n [model]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [nodeSvgTemplate]=\"nodeSvgTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n\n @if (!optimization().detachedGroupsLayer) {\n <!-- Edges -->\n <svg:g\n *lazyFor=\"let model of edgeModels(); trackBy: trackEdges; itemsPerFrame: edgesPerFrame()\"\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\" />\n\n <!-- Nodes -->\n <svg:g\n *lazyFor=\"let model of nodeModels(); trackBy: trackNodes; itemsPerFrame: nodesPerFrame()\"\n node\n [model]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [nodeSvgTemplate]=\"nodeSvgTemplateDirective()?.templateRef\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n </svg:g>\n\n <!-- Minimap -->\n @if (minimap(); as minimap) {\n <ng-container [ngTemplateOutlet]=\"minimap.template()\" />\n }\n</svg:svg>\n", styles: [":host{display:block;width:100%;height:100%;-webkit-user-select:none;user-select:none}:host ::ng-deep *{box-sizing:border-box}\n"] }]
3821
3863
  }], propDecorators: { view: [{
3822
3864
  type: Input
3823
3865
  }], minZoom: [{
@@ -4160,607 +4202,11 @@ const Vflow = [
4160
4202
  HandleTemplateDirective,
4161
4203
  ];
4162
4204
 
4163
- const mockModel = () => new NodeModel({ id: 'mock', type: 'default', point: { x: 0, y: 0 } });
4164
- function provideCustomNodeMocks() {
4165
- return [
4166
- {
4167
- provide: ComponentEventBusService,
4168
- useValue: {
4169
- pushEvent: () => { },
4170
- },
4171
- },
4172
- {
4173
- provide: NodeAccessorService,
4174
- useFactory: () => ({
4175
- model: signal(mockModel()),
4176
- }),
4177
- },
4178
- FlowEntitiesService,
4179
- // TODO: mocks below should be removed after the major release
4180
- {
4181
- provide: HandleService,
4182
- useFactory: () => ({
4183
- node: signal(mockModel()),
4184
- createHandle: () => { },
4185
- destroyHandle: () => { },
4186
- }),
4187
- },
4188
- {
4189
- provide: RootPointerDirective,
4190
- useValue: {
4191
- pointerMovement$: of({
4192
- x: 0,
4193
- y: 0,
4194
- movementX: 0,
4195
- movementY: 0,
4196
- target: null,
4197
- originalEvent: null,
4198
- }),
4199
- documentPointerEnd$: of(null),
4200
- },
4201
- },
4202
- {
4203
- provide: SpacePointContextDirective,
4204
- useValue: {
4205
- documentPointToFlowPoint: (point) => point,
4206
- },
4207
- },
4208
- {
4209
- provide: SelectionService,
4210
- useValue: {
4211
- select: () => { },
4212
- },
4213
- },
4214
- FlowSettingsService,
4215
- ViewportService,
4216
- ];
4217
- }
4218
-
4219
- class EdgeTemplateMockDirective {
4220
- constructor() {
4221
- this.templateRef = inject(TemplateRef);
4222
- }
4223
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeTemplateMockDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
4224
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: EdgeTemplateMockDirective, isStandalone: true, selector: "ng-template[edge]", ngImport: i0 }); }
4225
- }
4226
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeTemplateMockDirective, decorators: [{
4227
- type: Directive,
4228
- args: [{
4229
- standalone: true,
4230
- selector: 'ng-template[edge]',
4231
- }]
4232
- }] });
4233
- class ConnectionTemplateMockDirective {
4234
- constructor() {
4235
- this.templateRef = inject(TemplateRef);
4236
- }
4237
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ConnectionTemplateMockDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
4238
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: ConnectionTemplateMockDirective, isStandalone: true, selector: "ng-template[connection]", ngImport: i0 }); }
4239
- }
4240
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ConnectionTemplateMockDirective, decorators: [{
4241
- type: Directive,
4242
- args: [{
4243
- standalone: true,
4244
- selector: 'ng-template[connection]',
4245
- }]
4246
- }] });
4247
- class EdgeLabelHtmlTemplateMockDirective {
4248
- constructor() {
4249
- this.templateRef = inject(TemplateRef);
4250
- }
4251
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeLabelHtmlTemplateMockDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
4252
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: EdgeLabelHtmlTemplateMockDirective, isStandalone: true, selector: "ng-template[edgeLabelHtml]", ngImport: i0 }); }
4253
- }
4254
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeLabelHtmlTemplateMockDirective, decorators: [{
4255
- type: Directive,
4256
- args: [{
4257
- standalone: true,
4258
- selector: 'ng-template[edgeLabelHtml]',
4259
- }]
4260
- }] });
4261
- class NodeHtmlTemplateMockDirective {
4262
- constructor() {
4263
- this.templateRef = inject(TemplateRef);
4264
- }
4265
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeHtmlTemplateMockDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
4266
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: NodeHtmlTemplateMockDirective, isStandalone: true, selector: "ng-template[nodeHtml]", ngImport: i0 }); }
4267
- }
4268
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeHtmlTemplateMockDirective, decorators: [{
4269
- type: Directive,
4270
- args: [{
4271
- standalone: true,
4272
- selector: 'ng-template[nodeHtml]',
4273
- }]
4274
- }] });
4275
- class NodeSvgTemplateMockDirective {
4276
- constructor() {
4277
- this.templateRef = inject(TemplateRef);
4278
- }
4279
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeSvgTemplateMockDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
4280
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: NodeSvgTemplateMockDirective, isStandalone: true, selector: "ng-template[nodeSvg]", ngImport: i0 }); }
4281
- }
4282
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeSvgTemplateMockDirective, decorators: [{
4283
- type: Directive,
4284
- args: [{
4285
- standalone: true,
4286
- selector: 'ng-template[nodeSvg]',
4287
- }]
4288
- }] });
4289
- class GroupNodeTemplateMockDirective {
4290
- constructor() {
4291
- this.templateRef = inject(TemplateRef);
4292
- }
4293
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: GroupNodeTemplateMockDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
4294
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: GroupNodeTemplateMockDirective, isStandalone: true, selector: "ng-template[groupNode]", ngImport: i0 }); }
4295
- }
4296
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: GroupNodeTemplateMockDirective, decorators: [{
4297
- type: Directive,
4298
- args: [{
4299
- standalone: true,
4300
- selector: 'ng-template[groupNode]',
4301
- }]
4302
- }] });
4303
- class HandleTemplateMockDirective {
4304
- constructor() {
4305
- this.templateRef = inject(TemplateRef);
4306
- }
4307
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleTemplateMockDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
4308
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: HandleTemplateMockDirective, isStandalone: true, selector: "ng-template[handle]", ngImport: i0 }); }
4309
- }
4310
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleTemplateMockDirective, decorators: [{
4311
- type: Directive,
4312
- args: [{
4313
- standalone: true,
4314
- selector: 'ng-template[handle]',
4315
- }]
4316
- }] });
4317
-
4318
- class VflowMockComponent {
4319
- constructor() {
4320
- this.view = [400, 400];
4321
- this.minZoom = 0.5;
4322
- this.maxZoom = 3;
4323
- this.background = '#fff';
4324
- this.optimization = input({
4325
- detachedGroupsLayer: false,
4326
- });
4327
- this.entitiesSelectable = true;
4328
- this.keyboardShortcuts = {
4329
- multiSelection: null,
4330
- };
4331
- this.connection = new ConnectionModel({});
4332
- // eslint-disable-next-line @angular-eslint/no-output-on-prefix
4333
- this.onComponentNodeEvent = output();
4334
- this.nodeTemplateDirective = contentChild(NodeHtmlTemplateMockDirective);
4335
- this.groupNodeTemplateDirective = contentChild(GroupNodeTemplateMockDirective);
4336
- this.edgeTemplateDirective = contentChild(EdgeTemplateMockDirective);
4337
- this.edgeLabelHtmlDirective = contentChild(EdgeLabelHtmlTemplateMockDirective);
4338
- this.connectionTemplateDirective = contentChild(ConnectionTemplateMockDirective);
4339
- this.viewport = signal({
4340
- x: 0,
4341
- y: 0,
4342
- zoom: 1,
4343
- });
4344
- this.nodesChange = signal([]);
4345
- this.edgesChange = signal([]);
4346
- this.viewportChange$ = toObservable(this.viewport);
4347
- this.nodesChange$ = toObservable(this.nodesChange);
4348
- this.edgesChange$ = toObservable(this.edgesChange);
4349
- }
4350
- // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method
4351
- ngOnInit() { }
4352
- viewportTo(viewport) {
4353
- this.viewport.set(viewport);
4354
- }
4355
- zoomTo(zoom) {
4356
- this.viewport.update((prev) => ({ ...prev, zoom }));
4357
- }
4358
- panTo(point) {
4359
- this.viewport.update((prev) => ({ ...prev, x: point.x, y: point.y }));
4360
- }
4361
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
4362
- fitView(options) { }
4363
- documentPointToFlowPoint(point, options) {
4364
- if (options?.spaces) {
4365
- return [
4366
- {
4367
- nodeId: null,
4368
- x: point.x,
4369
- y: point.y,
4370
- },
4371
- ];
4372
- }
4373
- return point;
4374
- }
4375
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
4376
- getIntesectingNodes(nodeId, options) {
4377
- return [];
4378
- }
4379
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
4380
- toNodeSpace(nodeId, spaceNodeId) {
4381
- return { x: 0, y: 0 };
4382
- }
4383
- getNode(id) {
4384
- return this.nodes.find((node) => node.id === id);
4385
- }
4386
- getDetachedEdges() {
4387
- return [];
4388
- }
4389
- createSignal(value) {
4390
- return signal(value);
4391
- }
4392
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: VflowMockComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4393
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: VflowMockComponent, isStandalone: true, selector: "vflow", inputs: { nodes: { classPropertyName: "nodes", publicName: "nodes", isSignal: false, isRequired: true, transformFunction: null }, edges: { classPropertyName: "edges", publicName: "edges", isSignal: false, isRequired: false, transformFunction: null }, view: { classPropertyName: "view", publicName: "view", isSignal: false, isRequired: false, transformFunction: null }, minZoom: { classPropertyName: "minZoom", publicName: "minZoom", isSignal: false, isRequired: false, transformFunction: null }, maxZoom: { classPropertyName: "maxZoom", publicName: "maxZoom", isSignal: false, isRequired: false, transformFunction: null }, background: { classPropertyName: "background", publicName: "background", isSignal: false, isRequired: false, transformFunction: null }, optimization: { classPropertyName: "optimization", publicName: "optimization", isSignal: true, isRequired: false, transformFunction: null }, entitiesSelectable: { classPropertyName: "entitiesSelectable", publicName: "entitiesSelectable", isSignal: false, isRequired: false, transformFunction: null }, keyboardShortcuts: { classPropertyName: "keyboardShortcuts", publicName: "keyboardShortcuts", isSignal: false, isRequired: false, transformFunction: null }, connection: { classPropertyName: "connection", publicName: "connection", isSignal: false, isRequired: false, transformFunction: (settings) => new ConnectionModel(settings) }, snapGrid: { classPropertyName: "snapGrid", publicName: "snapGrid", isSignal: false, isRequired: false, transformFunction: null }, elevateNodesOnSelect: { classPropertyName: "elevateNodesOnSelect", publicName: "elevateNodesOnSelect", isSignal: false, isRequired: false, transformFunction: null }, elevateEdgesOnSelect: { classPropertyName: "elevateEdgesOnSelect", publicName: "elevateEdgesOnSelect", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { onComponentNodeEvent: "onComponentNodeEvent" }, queries: [{ propertyName: "nodeTemplateDirective", first: true, predicate: NodeHtmlTemplateMockDirective, descendants: true, isSignal: true }, { propertyName: "groupNodeTemplateDirective", first: true, predicate: GroupNodeTemplateMockDirective, descendants: true, isSignal: true }, { propertyName: "edgeTemplateDirective", first: true, predicate: EdgeTemplateMockDirective, descendants: true, isSignal: true }, { propertyName: "edgeLabelHtmlDirective", first: true, predicate: EdgeLabelHtmlTemplateMockDirective, descendants: true, isSignal: true }, { propertyName: "connectionTemplateDirective", first: true, predicate: ConnectionTemplateMockDirective, descendants: true, isSignal: true }], ngImport: i0, template: `
4394
- <ng-content />
4395
-
4396
- @for (node of nodes; track $index) {
4397
- @if (node.type === 'html-template') {
4398
- <ng-component
4399
- [ngTemplateOutlet]="nodeTemplateDirective()?.templateRef ?? null"
4400
- [ngTemplateOutletContext]="{
4401
- $implicit: {
4402
- node: node,
4403
- selected: createSignal(false),
4404
- },
4405
- }" />
4406
- }
4407
-
4408
- @if (node.type === 'template-group') {
4409
- <ng-component
4410
- [ngTemplateOutlet]="groupNodeTemplateDirective()?.templateRef ?? null"
4411
- [ngTemplateOutletContext]="{
4412
- $implicit: {
4413
- node: node,
4414
- selected: createSignal(false),
4415
- width: createSignal(node.width),
4416
- height: createSignal(node.height),
4417
- },
4418
- }" />
4419
- }
4420
- }
4421
-
4422
- @for (edge of edges; track $index) {
4423
- @if (edge.type === 'template') {
4424
- <ng-component
4425
- [ngTemplateOutlet]="edgeTemplateDirective()?.templateRef ?? null"
4426
- [ngTemplateOutletContext]="{
4427
- $implicit: {
4428
- edge: edge,
4429
- selected: createSignal(false),
4430
- path: createSignal(''),
4431
- markerStart: createSignal(''),
4432
- markerEnd: createSignal(''),
4433
- },
4434
- }" />
4435
-
4436
- @if (edge.edgeLabels?.start) {
4437
- <ng-component
4438
- [ngTemplateOutlet]="edgeLabelHtmlDirective()?.templateRef ?? null"
4439
- [ngTemplateOutletContext]="{
4440
- $implicit: {
4441
- edge: edge,
4442
- },
4443
- }" />
4444
- }
4445
-
4446
- @if (edge.edgeLabels?.center) {
4447
- <ng-component
4448
- [ngTemplateOutlet]="edgeLabelHtmlDirective()?.templateRef ?? null"
4449
- [ngTemplateOutletContext]="{
4450
- $implicit: {
4451
- edge: edge,
4452
- label: edge.edgeLabels?.center,
4453
- },
4454
- }" />
4455
- }
4456
-
4457
- @if (edge.edgeLabels?.end) {
4458
- <ng-component
4459
- [ngTemplateOutlet]="edgeLabelHtmlDirective()?.templateRef ?? null"
4460
- [ngTemplateOutletContext]="{
4461
- $implicit: {
4462
- edge: edge,
4463
- label: edge.edgeLabels?.end,
4464
- },
4465
- }" />
4466
- }
4467
- }
4468
- }
4469
-
4470
- @if (connection.type === 'template') {
4471
- <ng-component
4472
- [ngTemplateOutlet]="connectionTemplateDirective()?.templateRef ?? null"
4473
- [ngTemplateOutletContext]="{
4474
- $implicit: {
4475
- path: createSignal(''),
4476
- marker: createSignal(''),
4477
- },
4478
- }" />
4479
- }
4480
- `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4481
- }
4482
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: VflowMockComponent, decorators: [{
4483
- type: Component,
4484
- args: [{
4485
- selector: 'vflow',
4486
- template: `
4487
- <ng-content />
4488
-
4489
- @for (node of nodes; track $index) {
4490
- @if (node.type === 'html-template') {
4491
- <ng-component
4492
- [ngTemplateOutlet]="nodeTemplateDirective()?.templateRef ?? null"
4493
- [ngTemplateOutletContext]="{
4494
- $implicit: {
4495
- node: node,
4496
- selected: createSignal(false),
4497
- },
4498
- }" />
4499
- }
4500
-
4501
- @if (node.type === 'template-group') {
4502
- <ng-component
4503
- [ngTemplateOutlet]="groupNodeTemplateDirective()?.templateRef ?? null"
4504
- [ngTemplateOutletContext]="{
4505
- $implicit: {
4506
- node: node,
4507
- selected: createSignal(false),
4508
- width: createSignal(node.width),
4509
- height: createSignal(node.height),
4510
- },
4511
- }" />
4512
- }
4513
- }
4514
-
4515
- @for (edge of edges; track $index) {
4516
- @if (edge.type === 'template') {
4517
- <ng-component
4518
- [ngTemplateOutlet]="edgeTemplateDirective()?.templateRef ?? null"
4519
- [ngTemplateOutletContext]="{
4520
- $implicit: {
4521
- edge: edge,
4522
- selected: createSignal(false),
4523
- path: createSignal(''),
4524
- markerStart: createSignal(''),
4525
- markerEnd: createSignal(''),
4526
- },
4527
- }" />
4528
-
4529
- @if (edge.edgeLabels?.start) {
4530
- <ng-component
4531
- [ngTemplateOutlet]="edgeLabelHtmlDirective()?.templateRef ?? null"
4532
- [ngTemplateOutletContext]="{
4533
- $implicit: {
4534
- edge: edge,
4535
- },
4536
- }" />
4537
- }
4538
-
4539
- @if (edge.edgeLabels?.center) {
4540
- <ng-component
4541
- [ngTemplateOutlet]="edgeLabelHtmlDirective()?.templateRef ?? null"
4542
- [ngTemplateOutletContext]="{
4543
- $implicit: {
4544
- edge: edge,
4545
- label: edge.edgeLabels?.center,
4546
- },
4547
- }" />
4548
- }
4549
-
4550
- @if (edge.edgeLabels?.end) {
4551
- <ng-component
4552
- [ngTemplateOutlet]="edgeLabelHtmlDirective()?.templateRef ?? null"
4553
- [ngTemplateOutletContext]="{
4554
- $implicit: {
4555
- edge: edge,
4556
- label: edge.edgeLabels?.end,
4557
- },
4558
- }" />
4559
- }
4560
- }
4561
- }
4562
-
4563
- @if (connection.type === 'template') {
4564
- <ng-component
4565
- [ngTemplateOutlet]="connectionTemplateDirective()?.templateRef ?? null"
4566
- [ngTemplateOutletContext]="{
4567
- $implicit: {
4568
- path: createSignal(''),
4569
- marker: createSignal(''),
4570
- },
4571
- }" />
4572
- }
4573
- `,
4574
- changeDetection: ChangeDetectionStrategy.OnPush,
4575
- standalone: true,
4576
- imports: [NgTemplateOutlet],
4577
- }]
4578
- }], propDecorators: { nodes: [{
4579
- type: Input,
4580
- args: [{ required: true }]
4581
- }], edges: [{
4582
- type: Input
4583
- }], view: [{
4584
- type: Input
4585
- }], minZoom: [{
4586
- type: Input
4587
- }], maxZoom: [{
4588
- type: Input
4589
- }], background: [{
4590
- type: Input
4591
- }], entitiesSelectable: [{
4592
- type: Input
4593
- }], keyboardShortcuts: [{
4594
- type: Input
4595
- }], connection: [{
4596
- type: Input,
4597
- args: [{
4598
- transform: (settings) => new ConnectionModel(settings),
4599
- }]
4600
- }], snapGrid: [{
4601
- type: Input
4602
- }], elevateNodesOnSelect: [{
4603
- type: Input
4604
- }], elevateEdgesOnSelect: [{
4605
- type: Input
4606
- }] } });
4607
-
4608
- class HandleMockComponent {
4609
- constructor() {
4610
- this.position = input.required();
4611
- this.type = input.required();
4612
- this.id = input();
4613
- this.template = input();
4614
- }
4615
- // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method
4616
- ngOnInit() { }
4617
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleMockComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4618
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "17.3.12", type: HandleMockComponent, isStandalone: true, selector: "handle", inputs: { position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: true, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: true, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, template: { classPropertyName: "template", publicName: "template", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4619
- }
4620
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleMockComponent, decorators: [{
4621
- type: Component,
4622
- args: [{
4623
- selector: 'handle',
4624
- template: '',
4625
- changeDetection: ChangeDetectionStrategy.OnPush,
4626
- standalone: true,
4627
- }]
4628
- }] });
4629
-
4630
- class ResizableMockComponent {
4631
- constructor() {
4632
- this.resizable = input();
4633
- this.resizerColor = input('#2e414c');
4634
- this.gap = input(1.5);
4635
- }
4636
- // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method
4637
- ngOnInit() { }
4638
- // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method
4639
- ngAfterViewInit() { }
4640
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ResizableMockComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4641
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "17.3.12", type: ResizableMockComponent, isStandalone: true, selector: "[resizable]", inputs: { resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, resizerColor: { classPropertyName: "resizerColor", publicName: "resizerColor", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: '<ng-content />', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4642
- }
4643
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ResizableMockComponent, decorators: [{
4644
- type: Component,
4645
- args: [{
4646
- selector: '[resizable]',
4647
- template: '<ng-content />',
4648
- standalone: true,
4649
- changeDetection: ChangeDetectionStrategy.OnPush,
4650
- }]
4651
- }] });
4652
-
4653
- class MiniMapMockComponent {
4654
- constructor() {
4655
- this.maskColor = input(`rgba(215, 215, 215, 0.6)`);
4656
- this.strokeColor = input(`rgb(200, 200, 200)`);
4657
- this.position = input('bottom-right');
4658
- this.scaleOnHover = input(false);
4659
- }
4660
- // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method
4661
- ngOnInit() { }
4662
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MiniMapMockComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4663
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "17.3.12", type: MiniMapMockComponent, isStandalone: true, selector: "mini-map", inputs: { maskColor: { classPropertyName: "maskColor", publicName: "maskColor", isSignal: true, isRequired: false, transformFunction: null }, strokeColor: { classPropertyName: "strokeColor", publicName: "strokeColor", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, scaleOnHover: { classPropertyName: "scaleOnHover", publicName: "scaleOnHover", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4664
- }
4665
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MiniMapMockComponent, decorators: [{
4666
- type: Component,
4667
- args: [{
4668
- selector: 'mini-map',
4669
- template: '',
4670
- standalone: true,
4671
- changeDetection: ChangeDetectionStrategy.OnPush,
4672
- }]
4673
- }] });
4674
-
4675
- class NodeToolbarMockComponent {
4676
- constructor() {
4677
- this.position = input('top');
4678
- }
4679
- // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method
4680
- ngOnInit() { }
4681
- // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method
4682
- ngOnDestroy() { }
4683
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeToolbarMockComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4684
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "17.3.12", type: NodeToolbarMockComponent, isStandalone: true, selector: "node-toolbar", inputs: { position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: '<ng-content />', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4685
- }
4686
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeToolbarMockComponent, decorators: [{
4687
- type: Component,
4688
- args: [{
4689
- selector: 'node-toolbar',
4690
- template: '<ng-content />',
4691
- standalone: true,
4692
- changeDetection: ChangeDetectionStrategy.OnPush,
4693
- }]
4694
- }] });
4695
-
4696
- class ConnectionControllerMockDirective {
4697
- constructor() {
4698
- // eslint-disable-next-line @angular-eslint/no-output-on-prefix
4699
- this.onConnect = output();
4700
- // eslint-disable-next-line @angular-eslint/no-output-on-prefix
4701
- this.onReconnect = output();
4702
- }
4703
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
4704
- startConnection(handle) { }
4705
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
4706
- startReconnection(handle) { }
4707
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
4708
- validateConnection(handle) { }
4709
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
4710
- resetValidateConnection(targetHandle) { }
4711
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
4712
- endConnection() { }
4713
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ConnectionControllerMockDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
4714
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: ConnectionControllerMockDirective, isStandalone: true, selector: "[onConnect]", outputs: { onConnect: "onConnect", onReconnect: "onReconnect" }, ngImport: i0 }); }
4715
- }
4716
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ConnectionControllerMockDirective, decorators: [{
4717
- type: Directive,
4718
- args: [{ selector: '[onConnect]', standalone: true }]
4719
- }] });
4720
-
4721
- class DragHandleMockDirective {
4722
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DragHandleMockDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
4723
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: DragHandleMockDirective, isStandalone: true, selector: "[dragHandle]", ngImport: i0 }); }
4724
- }
4725
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DragHandleMockDirective, decorators: [{
4726
- type: Directive,
4727
- args: [{ selector: '[dragHandle]', standalone: true }]
4728
- }] });
4729
-
4730
- class SelectableMockDirective {
4731
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SelectableMockDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
4732
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: SelectableMockDirective, isStandalone: true, selector: "[selectable]", ngImport: i0 }); }
4733
- }
4734
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SelectableMockDirective, decorators: [{
4735
- type: Directive,
4736
- args: [{
4737
- selector: '[selectable]',
4738
- standalone: true,
4739
- }]
4740
- }] });
4741
-
4742
- const VflowMocks = [
4743
- VflowMockComponent,
4744
- HandleMockComponent,
4745
- ResizableMockComponent,
4746
- SelectableMockDirective,
4747
- MiniMapMockComponent,
4748
- NodeToolbarMockComponent,
4749
- DragHandleMockDirective,
4750
- ConnectionControllerMockDirective,
4751
- NodeHtmlTemplateMockDirective,
4752
- GroupNodeTemplateMockDirective,
4753
- EdgeLabelHtmlTemplateMockDirective,
4754
- EdgeTemplateMockDirective,
4755
- ConnectionTemplateMockDirective,
4756
- HandleTemplateMockDirective,
4757
- ];
4758
-
4759
4205
  // Standalone Util
4760
4206
 
4761
4207
  /**
4762
4208
  * Generated bundle index. Do not edit.
4763
4209
  */
4764
4210
 
4765
- export { ChangesControllerDirective, ConnectionControllerDirective, ConnectionControllerMockDirective, ConnectionTemplateDirective, ConnectionTemplateMockDirective, CustomDynamicNodeComponent, CustomNodeComponent, CustomTemplateEdgeComponent, DragHandleDirective, DragHandleMockDirective, EdgeLabelHtmlTemplateDirective, EdgeLabelHtmlTemplateMockDirective, EdgeTemplateDirective, EdgeTemplateMockDirective, GroupNodeTemplateDirective, GroupNodeTemplateMockDirective, HandleComponent, HandleMockComponent, HandleTemplateDirective, HandleTemplateMockDirective, MiniMapComponent, MiniMapMockComponent, NodeHtmlTemplateDirective, NodeHtmlTemplateMockDirective, NodeSvgTemplateDirective, NodeSvgTemplateMockDirective, NodeToolbarComponent, NodeToolbarMockComponent, NodeToolbarWrapperDirective, ResizableComponent, ResizableMockComponent, SelectableDirective, SelectableMockDirective, Vflow, VflowComponent, VflowMockComponent, VflowMocks, isComponentDynamicNode, isComponentStaticNode, isDefaultDynamicGroupNode, isDefaultDynamicNode, isDefaultStaticGroupNode, isDefaultStaticNode, isDynamicNode, isStaticNode, isSvgTemplateDynamicNode, isSvgTemplateStaticNode, isTemplateDynamicGroupNode, isTemplateDynamicNode, isTemplateStaticGroupNode, isTemplateStaticNode, provideCustomNodeMocks };
4211
+ export { ChangesControllerDirective, ConnectionControllerDirective, ConnectionTemplateDirective, CustomDynamicNodeComponent, CustomNodeComponent, CustomTemplateEdgeComponent, DragHandleDirective, EdgeLabelHtmlTemplateDirective, EdgeTemplateDirective, GroupNodeTemplateDirective, HandleComponent, HandleTemplateDirective, MiniMapComponent, NodeHtmlTemplateDirective, NodeSvgTemplateDirective, NodeToolbarComponent, NodeToolbarWrapperDirective, ResizableComponent, SelectableDirective, Vflow, VflowComponent, isComponentDynamicNode, isComponentStaticNode, isDefaultDynamicGroupNode, isDefaultDynamicNode, isDefaultStaticGroupNode, isDefaultStaticNode, isDynamicNode, isStaticNode, isSvgTemplateDynamicNode, isSvgTemplateStaticNode, isTemplateDynamicGroupNode, isTemplateDynamicNode, isTemplateStaticGroupNode, isTemplateStaticNode, ComponentEventBusService as ɵComponentEventBusService, ConnectionModel as ɵConnectionModel, FlowEntitiesService as ɵFlowEntitiesService, FlowSettingsService as ɵFlowSettingsService, HandleModel as ɵHandleModel, HandleService as ɵHandleService, NodeAccessorService as ɵNodeAccessorService, NodeModel as ɵNodeModel, RootPointerDirective as ɵRootPointerDirective, SelectionService as ɵSelectionService, SpacePointContextDirective as ɵSpacePointContextDirective, ViewportService as ɵViewportService };
4766
4212
  //# sourceMappingURL=ngx-vflow.mjs.map