@memberjunction/ng-flow-editor 6.1.0-edge.0 → 6.1.0-edge.2

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.
@@ -15,10 +15,11 @@ import * as i7 from "./flow-palette.component";
15
15
  import * as i8 from "./flow-toolbar.component";
16
16
  import * as i9 from "./flow-status-bar.component";
17
17
  const _c0 = ["fZoomRef"];
18
- const _c1 = (a0, a1) => ({ x: a0, y: a1 });
18
+ const _c1 = ["canvasArea"];
19
+ const _c2 = (a0, a1) => ({ x: a0, y: a1 });
19
20
  function FlowEditorComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
20
21
  const _r2 = i0.ɵɵgetCurrentView();
21
- i0.ɵɵelementStart(0, "div", 2)(1, "mj-flow-toolbar", 17);
22
+ i0.ɵɵelementStart(0, "div", 3)(1, "mj-flow-toolbar", 18);
22
23
  i0.ɵɵlistener("ZoomInClicked", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_ZoomInClicked_1_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ZoomIn()); })("ZoomOutClicked", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_ZoomOutClicked_1_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ZoomOut()); })("FitToScreenClicked", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_FitToScreenClicked_1_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ZoomToFit()); })("AutoLayoutClicked", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_AutoLayoutClicked_1_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.AutoArrange()); })("GridToggled", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_GridToggled_1_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onGridToggled($event)); })("MinimapToggled", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_MinimapToggled_1_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onMinimapToggled($event)); })("LegendToggled", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_LegendToggled_1_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onLegendToggled($event)); })("PanModeToggled", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_PanModeToggled_1_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onPanModeToggled($event)); });
23
24
  i0.ɵɵelementEnd()();
24
25
  } if (rf & 2) {
@@ -27,196 +28,199 @@ function FlowEditorComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
27
28
  i0.ɵɵproperty("ZoomLevel", ctx_r2.zoomLevel)("ShowGrid", ctx_r2.ShowGrid)("ShowMinimap", ctx_r2.ShowMinimap)("ShowLegend", ctx_r2.ShowLegend)("ReadOnly", ctx_r2.ReadOnly)("PanMode", ctx_r2.panMode);
28
29
  } }
29
30
  function FlowEditorComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
30
- i0.ɵɵelement(0, "mj-flow-palette", 4);
31
+ const _r4 = i0.ɵɵgetCurrentView();
32
+ i0.ɵɵelementStart(0, "mj-flow-palette", 19);
33
+ i0.ɵɵlistener("NodeTypeActivated", function FlowEditorComponent_Conditional_3_Template_mj_flow_palette_NodeTypeActivated_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onPaletteNodeTypeActivated($event)); });
34
+ i0.ɵɵelementEnd();
31
35
  } if (rf & 2) {
32
36
  const ctx_r2 = i0.ɵɵnextContext();
33
37
  i0.ɵɵproperty("NodeTypes", ctx_r2.NodeTypes);
34
38
  } }
35
- function FlowEditorComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
39
+ function FlowEditorComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
36
40
  i0.ɵɵelementStart(0, "f-background");
37
- i0.ɵɵelement(1, "f-circle-pattern", 18);
41
+ i0.ɵɵelement(1, "f-circle-pattern", 20);
38
42
  i0.ɵɵelementEnd();
39
43
  } if (rf & 2) {
40
44
  i0.ɵɵadvance();
41
45
  i0.ɵɵproperty("color", "#94a3b8")("radius", 24);
42
46
  } }
43
- function FlowEditorComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
44
- i0.ɵɵelement(0, "f-line-alignment", 7);
47
+ function FlowEditorComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
48
+ i0.ɵɵelement(0, "f-line-alignment", 8);
45
49
  } if (rf & 2) {
46
50
  i0.ɵɵproperty("fAlignThreshold", 10);
47
51
  } }
48
- function FlowEditorComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
49
- i0.ɵɵelementStart(0, "f-connection-for-create", 9);
52
+ function FlowEditorComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
53
+ i0.ɵɵelementStart(0, "f-connection-for-create", 10);
50
54
  i0.ɵɵnamespaceSVG();
51
- i0.ɵɵelementStart(1, "svg", 19);
52
- i0.ɵɵelement(2, "path", 20);
55
+ i0.ɵɵelementStart(1, "svg", 21);
56
+ i0.ɵɵelement(2, "path", 22);
53
57
  i0.ɵɵelementEnd()();
54
58
  } if (rf & 2) {
55
59
  i0.ɵɵproperty("fRadius", 8)("fOffset", 12);
56
60
  i0.ɵɵadvance();
57
61
  i0.ɵɵproperty("refX", 9)("refY", 5)("height", 10)("width", 10);
58
62
  } }
59
- function FlowEditorComponent_For_12_Conditional_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
60
- i0.ɵɵelement(0, "i", 26);
63
+ function FlowEditorComponent_For_13_Conditional_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
64
+ i0.ɵɵelement(0, "i", 28);
61
65
  } if (rf & 2) {
62
- const conn_r5 = i0.ɵɵnextContext(2).$implicit;
63
- i0.ɵɵstyleProp("color", conn_r5.LabelIconColor || "inherit");
64
- i0.ɵɵproperty("ngClass", conn_r5.LabelIcon);
66
+ const conn_r6 = i0.ɵɵnextContext(2).$implicit;
67
+ i0.ɵɵstyleProp("color", conn_r6.LabelIconColor || "inherit");
68
+ i0.ɵɵproperty("ngClass", conn_r6.LabelIcon);
65
69
  } }
66
- function FlowEditorComponent_For_12_Conditional_3_Template(rf, ctx) { if (rf & 1) {
67
- i0.ɵɵelementStart(0, "div", 24);
68
- i0.ɵɵconditionalCreate(1, FlowEditorComponent_For_12_Conditional_3_Conditional_1_Template, 1, 3, "i", 25);
70
+ function FlowEditorComponent_For_13_Conditional_3_Template(rf, ctx) { if (rf & 1) {
71
+ i0.ɵɵelementStart(0, "div", 26);
72
+ i0.ɵɵconditionalCreate(1, FlowEditorComponent_For_13_Conditional_3_Conditional_1_Template, 1, 3, "i", 27);
69
73
  i0.ɵɵtext(2);
70
74
  i0.ɵɵelementEnd();
71
75
  } if (rf & 2) {
72
- const conn_r5 = i0.ɵɵnextContext().$implicit;
76
+ const conn_r6 = i0.ɵɵnextContext().$implicit;
73
77
  const ctx_r2 = i0.ɵɵnextContext();
74
78
  i0.ɵɵstyleProp("background-color", ctx_r2.ConnectionLabelBackground)("border-color", ctx_r2.ConnectionLabelBorderColor)("color", ctx_r2.ConnectionLabelTextColor);
75
- i0.ɵɵproperty("position", 0.5)("title", conn_r5.LabelDetail || conn_r5.Label || "");
79
+ i0.ɵɵproperty("position", 0.5)("title", conn_r6.LabelDetail || conn_r6.Label || "");
76
80
  i0.ɵɵadvance();
77
- i0.ɵɵconditional(conn_r5.LabelIcon ? 1 : -1);
81
+ i0.ɵɵconditional(conn_r6.LabelIcon ? 1 : -1);
78
82
  i0.ɵɵadvance();
79
- i0.ɵɵtextInterpolate1(" ", conn_r5.Label, " ");
83
+ i0.ɵɵtextInterpolate1(" ", conn_r6.Label, " ");
80
84
  } }
81
- function FlowEditorComponent_For_12_Template(rf, ctx) { if (rf & 1) {
82
- const _r4 = i0.ɵɵgetCurrentView();
83
- i0.ɵɵelementStart(0, "f-connection", 21);
84
- i0.ɵɵlistener("click", function FlowEditorComponent_For_12_Template_f_connection_click_0_listener($event) { const conn_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onConnectionClicked($event, conn_r5)); })("contextmenu", function FlowEditorComponent_For_12_Template_f_connection_contextmenu_0_listener($event) { const conn_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onConnectionContextMenu($event, conn_r5)); });
85
+ function FlowEditorComponent_For_13_Template(rf, ctx) { if (rf & 1) {
86
+ const _r5 = i0.ɵɵgetCurrentView();
87
+ i0.ɵɵelementStart(0, "f-connection", 23);
88
+ i0.ɵɵlistener("click", function FlowEditorComponent_For_13_Template_f_connection_click_0_listener($event) { const conn_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onConnectionClicked($event, conn_r6)); })("contextmenu", function FlowEditorComponent_For_13_Template_f_connection_contextmenu_0_listener($event) { const conn_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onConnectionContextMenu($event, conn_r6)); });
85
89
  i0.ɵɵnamespaceSVG();
86
- i0.ɵɵelementStart(1, "svg", 19);
87
- i0.ɵɵelement(2, "path", 22);
90
+ i0.ɵɵelementStart(1, "svg", 21);
91
+ i0.ɵɵelement(2, "path", 24);
88
92
  i0.ɵɵelementEnd();
89
- i0.ɵɵconditionalCreate(3, FlowEditorComponent_For_12_Conditional_3_Template, 3, 10, "div", 23);
93
+ i0.ɵɵconditionalCreate(3, FlowEditorComponent_For_13_Conditional_3_Template, 3, 10, "div", 25);
90
94
  i0.ɵɵelementEnd();
91
95
  } if (rf & 2) {
92
- const conn_r5 = ctx.$implicit;
96
+ const conn_r6 = ctx.$implicit;
93
97
  const ctx_r2 = i0.ɵɵnextContext();
94
- i0.ɵɵstyleProp("--connection-color", conn_r5.Color || "#94a3b8");
95
- i0.ɵɵclassProp("mj-flow-connection-colored", !!conn_r5.Color)("mj-flow-connection-dashed", conn_r5.Style === "dashed")("mj-flow-connection-dotted", conn_r5.Style === "dotted");
96
- i0.ɵɵproperty("fConnectionId", conn_r5.ID)("fOutputId", conn_r5.SourcePortID)("fInputId", conn_r5.TargetPortID)("fRadius", 8)("fOffset", 12)("fSelectionDisabled", false)("fReassignDisabled", ctx_r2.ReadOnly);
98
+ i0.ɵɵstyleProp("--connection-color", conn_r6.Color || "#94a3b8");
99
+ i0.ɵɵclassProp("mj-flow-connection-colored", !!conn_r6.Color)("mj-flow-connection-dashed", conn_r6.Style === "dashed")("mj-flow-connection-dotted", conn_r6.Style === "dotted");
100
+ i0.ɵɵproperty("fConnectionId", conn_r6.ID)("fOutputId", conn_r6.SourcePortID)("fInputId", conn_r6.TargetPortID)("fRadius", 8)("fOffset", 12)("fSelectionDisabled", false)("fReassignDisabled", ctx_r2.ReadOnly);
97
101
  i0.ɵɵadvance();
98
102
  i0.ɵɵproperty("refX", 9)("refY", 5)("height", 10)("width", 10);
99
103
  i0.ɵɵadvance();
100
- i0.ɵɵattribute("fill", conn_r5.Color || "#94a3b8");
104
+ i0.ɵɵattribute("fill", conn_r6.Color || "#94a3b8");
101
105
  i0.ɵɵadvance();
102
- i0.ɵɵconditional(conn_r5.Label ? 3 : -1);
106
+ i0.ɵɵconditional(conn_r6.Label ? 3 : -1);
103
107
  } }
104
- function FlowEditorComponent_For_14_Template(rf, ctx) { if (rf & 1) {
105
- const _r6 = i0.ɵɵgetCurrentView();
106
- i0.ɵɵelementStart(0, "mj-flow-node", 27);
107
- i0.ɵɵlistener("contextmenu", function FlowEditorComponent_For_14_Template_mj_flow_node_contextmenu_0_listener($event) { const node_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onNodeContextMenu($event, node_r7)); });
108
+ function FlowEditorComponent_For_15_Template(rf, ctx) { if (rf & 1) {
109
+ const _r7 = i0.ɵɵgetCurrentView();
110
+ i0.ɵɵelementStart(0, "mj-flow-node", 29);
111
+ i0.ɵɵlistener("contextmenu", function FlowEditorComponent_For_15_Template_mj_flow_node_contextmenu_0_listener($event) { const node_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onNodeContextMenu($event, node_r8)); });
108
112
  i0.ɵɵelementEnd();
109
113
  } if (rf & 2) {
110
- const node_r7 = ctx.$implicit;
114
+ const node_r8 = ctx.$implicit;
111
115
  const ctx_r2 = i0.ɵɵnextContext();
112
- i0.ɵɵproperty("fNodeId", node_r7.ID)("fNodePosition", i0.ɵɵpureFunction2(8, _c1, node_r7.Position.X, node_r7.Position.Y))("fNodeDraggingDisabled", ctx_r2.ReadOnly || ctx_r2.panMode || node_r7.Locked === true)("fNodeSelectionDisabled", ctx_r2.panMode)("fConnectOnNode", !ctx_r2.ReadOnly && !ctx_r2.panMode)("Node", node_r7)("TypeConfig", ctx_r2.GetTypeConfig(node_r7.Type))("ReadOnly", ctx_r2.ReadOnly);
116
+ i0.ɵɵproperty("fNodeId", node_r8.ID)("fNodePosition", i0.ɵɵpureFunction2(8, _c2, node_r8.Position.X, node_r8.Position.Y))("fNodeDraggingDisabled", ctx_r2.ReadOnly || ctx_r2.panMode || node_r8.Locked === true)("fNodeSelectionDisabled", ctx_r2.panMode)("fConnectOnNode", !ctx_r2.ReadOnly && !ctx_r2.panMode)("Node", node_r8)("TypeConfig", ctx_r2.GetTypeConfig(node_r8.Type))("ReadOnly", ctx_r2.ReadOnly);
113
117
  } }
114
- function FlowEditorComponent_Conditional_15_Template(rf, ctx) { if (rf & 1) {
118
+ function FlowEditorComponent_Conditional_16_Template(rf, ctx) { if (rf & 1) {
115
119
  i0.ɵɵelement(0, "f-selection-area");
116
120
  } }
117
- function FlowEditorComponent_Conditional_16_Template(rf, ctx) { if (rf & 1) {
118
- i0.ɵɵelementStart(0, "div", 12);
119
- i0.ɵɵelement(1, "f-minimap", 28);
121
+ function FlowEditorComponent_Conditional_17_Template(rf, ctx) { if (rf & 1) {
122
+ i0.ɵɵelementStart(0, "div", 13);
123
+ i0.ɵɵelement(1, "f-minimap", 30);
120
124
  i0.ɵɵelementEnd();
121
125
  } if (rf & 2) {
122
126
  i0.ɵɵadvance();
123
127
  i0.ɵɵproperty("fMinSize", 1500);
124
128
  } }
125
- function FlowEditorComponent_Conditional_17_Template(rf, ctx) { if (rf & 1) {
126
- i0.ɵɵelementStart(0, "div", 13)(1, "div", 29);
129
+ function FlowEditorComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
130
+ i0.ɵɵelementStart(0, "div", 14)(1, "div", 31);
127
131
  i0.ɵɵtext(2, "Legend");
128
132
  i0.ɵɵelementEnd();
129
- i0.ɵɵelementStart(3, "div", 30)(4, "div", 31);
133
+ i0.ɵɵelementStart(3, "div", 32)(4, "div", 33);
130
134
  i0.ɵɵtext(5, "Connections");
131
135
  i0.ɵɵelementEnd();
132
- i0.ɵɵelementStart(6, "div", 32);
136
+ i0.ɵɵelementStart(6, "div", 34);
133
137
  i0.ɵɵnamespaceSVG();
134
- i0.ɵɵelementStart(7, "svg", 33);
135
- i0.ɵɵelement(8, "line", 34);
138
+ i0.ɵɵelementStart(7, "svg", 35);
139
+ i0.ɵɵelement(8, "line", 36);
136
140
  i0.ɵɵelementEnd();
137
141
  i0.ɵɵnamespaceHTML();
138
142
  i0.ɵɵelementStart(9, "span");
139
143
  i0.ɵɵtext(10, "Only exit path");
140
144
  i0.ɵɵelementEnd()();
141
- i0.ɵɵelementStart(11, "div", 32);
145
+ i0.ɵɵelementStart(11, "div", 34);
142
146
  i0.ɵɵnamespaceSVG();
143
- i0.ɵɵelementStart(12, "svg", 33);
144
- i0.ɵɵelement(13, "line", 35);
147
+ i0.ɵɵelementStart(12, "svg", 35);
148
+ i0.ɵɵelement(13, "line", 37);
145
149
  i0.ɵɵelementEnd();
146
150
  i0.ɵɵnamespaceHTML();
147
- i0.ɵɵelement(14, "i", 36);
151
+ i0.ɵɵelement(14, "i", 38);
148
152
  i0.ɵɵelementStart(15, "span");
149
153
  i0.ɵɵtext(16, "Default (fallback)");
150
154
  i0.ɵɵelementEnd()();
151
- i0.ɵɵelementStart(17, "div", 32);
155
+ i0.ɵɵelementStart(17, "div", 34);
152
156
  i0.ɵɵnamespaceSVG();
153
- i0.ɵɵelementStart(18, "svg", 33);
154
- i0.ɵɵelement(19, "line", 37);
157
+ i0.ɵɵelementStart(18, "svg", 35);
158
+ i0.ɵɵelement(19, "line", 39);
155
159
  i0.ɵɵelementEnd();
156
160
  i0.ɵɵnamespaceHTML();
157
161
  i0.ɵɵelementStart(20, "span");
158
162
  i0.ɵɵtext(21, "Conditional");
159
163
  i0.ɵɵelementEnd()();
160
- i0.ɵɵelementStart(22, "div", 32);
164
+ i0.ɵɵelementStart(22, "div", 34);
161
165
  i0.ɵɵnamespaceSVG();
162
- i0.ɵɵelementStart(23, "svg", 33);
163
- i0.ɵɵelement(24, "line", 38);
166
+ i0.ɵɵelementStart(23, "svg", 35);
167
+ i0.ɵɵelement(24, "line", 40);
164
168
  i0.ɵɵelementEnd();
165
169
  i0.ɵɵnamespaceHTML();
166
- i0.ɵɵelement(25, "i", 39);
170
+ i0.ɵɵelement(25, "i", 41);
167
171
  i0.ɵɵelementStart(26, "span");
168
172
  i0.ɵɵtext(27, "Duplicate defaults");
169
173
  i0.ɵɵelementEnd()()();
170
- i0.ɵɵelementStart(28, "div", 30)(29, "div", 31);
174
+ i0.ɵɵelementStart(28, "div", 32)(29, "div", 33);
171
175
  i0.ɵɵtext(30, "Step Types");
172
176
  i0.ɵɵelementEnd();
173
- i0.ɵɵelementStart(31, "div", 32);
174
- i0.ɵɵelement(32, "span", 40);
177
+ i0.ɵɵelementStart(31, "div", 34);
178
+ i0.ɵɵelement(32, "span", 42);
175
179
  i0.ɵɵelementStart(33, "span");
176
180
  i0.ɵɵtext(34, "Action");
177
181
  i0.ɵɵelementEnd()();
178
- i0.ɵɵelementStart(35, "div", 32);
179
- i0.ɵɵelement(36, "span", 41);
182
+ i0.ɵɵelementStart(35, "div", 34);
183
+ i0.ɵɵelement(36, "span", 43);
180
184
  i0.ɵɵelementStart(37, "span");
181
185
  i0.ɵɵtext(38, "Prompt");
182
186
  i0.ɵɵelementEnd()();
183
- i0.ɵɵelementStart(39, "div", 32);
184
- i0.ɵɵelement(40, "span", 42);
187
+ i0.ɵɵelementStart(39, "div", 34);
188
+ i0.ɵɵelement(40, "span", 44);
185
189
  i0.ɵɵelementStart(41, "span");
186
190
  i0.ɵɵtext(42, "Sub-Agent");
187
191
  i0.ɵɵelementEnd()();
188
- i0.ɵɵelementStart(43, "div", 32);
189
- i0.ɵɵelement(44, "span", 43);
192
+ i0.ɵɵelementStart(43, "div", 34);
193
+ i0.ɵɵelement(44, "span", 45);
190
194
  i0.ɵɵelementStart(45, "span");
191
195
  i0.ɵɵtext(46, "For Each");
192
196
  i0.ɵɵelementEnd()();
193
- i0.ɵɵelementStart(47, "div", 32);
194
- i0.ɵɵelement(48, "span", 44);
197
+ i0.ɵɵelementStart(47, "div", 34);
198
+ i0.ɵɵelement(48, "span", 46);
195
199
  i0.ɵɵelementStart(49, "span");
196
200
  i0.ɵɵtext(50, "While");
197
201
  i0.ɵɵelementEnd()()();
198
- i0.ɵɵelementStart(51, "div", 30)(52, "div", 31);
202
+ i0.ɵɵelementStart(51, "div", 32)(52, "div", 33);
199
203
  i0.ɵɵtext(53, "Borders");
200
204
  i0.ɵɵelementEnd();
201
- i0.ɵɵelementStart(54, "div", 32);
202
- i0.ɵɵelement(55, "span", 45);
205
+ i0.ɵɵelementStart(54, "div", 34);
206
+ i0.ɵɵelement(55, "span", 47);
203
207
  i0.ɵɵelementStart(56, "span");
204
208
  i0.ɵɵtext(57, "Start node");
205
209
  i0.ɵɵelementEnd()();
206
- i0.ɵɵelementStart(58, "div", 32);
207
- i0.ɵɵelement(59, "span", 46)(60, "i", 47);
210
+ i0.ɵɵelementStart(58, "div", 34);
211
+ i0.ɵɵelement(59, "span", 48)(60, "i", 49);
208
212
  i0.ɵɵelementStart(61, "span");
209
213
  i0.ɵɵtext(62, "Missing config");
210
214
  i0.ɵɵelementEnd()()()();
211
215
  } }
212
- function FlowEditorComponent_Conditional_18_Conditional_2_Template(rf, ctx) { if (rf & 1) {
213
- i0.ɵɵelementStart(0, "p", 49);
216
+ function FlowEditorComponent_Conditional_19_Conditional_2_Template(rf, ctx) { if (rf & 1) {
217
+ i0.ɵɵelementStart(0, "p", 51);
214
218
  i0.ɵɵtext(1, " Or use auto-layout after adding steps to arrange them automatically ");
215
219
  i0.ɵɵelementEnd();
216
220
  } }
217
- function FlowEditorComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
218
- i0.ɵɵelementStart(0, "div", 14)(1, "mj-empty-state", 48);
219
- i0.ɵɵconditionalCreate(2, FlowEditorComponent_Conditional_18_Conditional_2_Template, 2, 0, "p", 49);
221
+ function FlowEditorComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
222
+ i0.ɵɵelementStart(0, "div", 15)(1, "mj-empty-state", 50);
223
+ i0.ɵɵconditionalCreate(2, FlowEditorComponent_Conditional_19_Conditional_2_Template, 2, 0, "p", 51);
220
224
  i0.ɵɵelementEnd()();
221
225
  } if (rf & 2) {
222
226
  const ctx_r2 = i0.ɵɵnextContext();
@@ -225,20 +229,20 @@ function FlowEditorComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
225
229
  i0.ɵɵadvance();
226
230
  i0.ɵɵconditional(!ctx_r2.ReadOnly ? 2 : -1);
227
231
  } }
228
- function FlowEditorComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
229
- const _r8 = i0.ɵɵgetCurrentView();
230
- i0.ɵɵelementStart(0, "div", 50);
231
- i0.ɵɵlistener("click", function FlowEditorComponent_Conditional_19_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r8); return i0.ɵɵresetView($event.stopPropagation()); });
232
- i0.ɵɵelementStart(1, "button", 51);
233
- i0.ɵɵlistener("click", function FlowEditorComponent_Conditional_19_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onContextMenuAction("edit")); });
234
- i0.ɵɵelement(2, "i", 52);
232
+ function FlowEditorComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
233
+ const _r9 = i0.ɵɵgetCurrentView();
234
+ i0.ɵɵelementStart(0, "div", 52);
235
+ i0.ɵɵlistener("click", function FlowEditorComponent_Conditional_20_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r9); return i0.ɵɵresetView($event.stopPropagation()); });
236
+ i0.ɵɵelementStart(1, "button", 53);
237
+ i0.ɵɵlistener("click", function FlowEditorComponent_Conditional_20_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onContextMenuAction("edit")); });
238
+ i0.ɵɵelement(2, "i", 54);
235
239
  i0.ɵɵelementStart(3, "span");
236
240
  i0.ɵɵtext(4);
237
241
  i0.ɵɵelementEnd()();
238
- i0.ɵɵelement(5, "div", 53);
239
- i0.ɵɵelementStart(6, "button", 54);
240
- i0.ɵɵlistener("click", function FlowEditorComponent_Conditional_19_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onContextMenuAction("remove")); });
241
- i0.ɵɵelement(7, "i", 55);
242
+ i0.ɵɵelement(5, "div", 55);
243
+ i0.ɵɵelementStart(6, "button", 56);
244
+ i0.ɵɵlistener("click", function FlowEditorComponent_Conditional_20_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onContextMenuAction("remove")); });
245
+ i0.ɵɵelement(7, "i", 57);
242
246
  i0.ɵɵelementStart(8, "span");
243
247
  i0.ɵɵtext(9);
244
248
  i0.ɵɵelementEnd()()();
@@ -250,8 +254,8 @@ function FlowEditorComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
250
254
  i0.ɵɵadvance(5);
251
255
  i0.ɵɵtextInterpolate1("Remove ", ctx_r2.contextMenuTargetType === "node" ? "Node" : "Connection");
252
256
  } }
253
- function FlowEditorComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
254
- i0.ɵɵelement(0, "mj-flow-status-bar", 16);
257
+ function FlowEditorComponent_Conditional_21_Template(rf, ctx) { if (rf & 1) {
258
+ i0.ɵɵelement(0, "mj-flow-status-bar", 17);
255
259
  } if (rf & 2) {
256
260
  const ctx_r2 = i0.ɵɵnextContext();
257
261
  i0.ɵɵproperty("NodeCount", ctx_r2.Nodes.length)("ConnectionCount", ctx_r2.Connections.length)("SelectedCount", ctx_r2.selectedCount)("ZoomLevel", ctx_r2.zoomLevel);
@@ -289,16 +293,18 @@ export class FlowEditorComponent {
289
293
  GridSize = 20;
290
294
  AutoLayoutDirection = 'vertical';
291
295
  /** Background color for connection labels */
292
- ConnectionLabelBackground = '#fffef5';
296
+ // Design tokens, not literals — the canvas renders on both themes, and a near-white pill on a
297
+ // dark canvas made the least important element the most visually dominant thing on screen.
298
+ ConnectionLabelBackground = 'var(--mj-bg-surface)';
293
299
  /** Border color for connection labels */
294
- ConnectionLabelBorderColor = '#cbd5e1';
300
+ ConnectionLabelBorderColor = 'var(--mj-border-default)';
295
301
  /** Text color for connection labels */
296
- ConnectionLabelTextColor = '#334155';
302
+ ConnectionLabelTextColor = 'var(--mj-text-secondary)';
297
303
  /** Title for the canvas empty-state overlay — depends on read-only mode. */
298
304
  get EmptyStateTitle() {
299
305
  return this.ReadOnly
300
306
  ? 'No steps defined for this flow'
301
- : 'Drag steps from the palette to start building your flow';
307
+ : 'Click a step in the palette — or drag one onto the canvas — to start building your flow';
302
308
  }
303
309
  // ── Outputs ─────────────────────────────────────────────────
304
310
  NodeSelected = new EventEmitter();
@@ -322,6 +328,7 @@ export class FlowEditorComponent {
322
328
  fFlow;
323
329
  fCanvas;
324
330
  fZoom;
331
+ canvasArea;
325
332
  // ── Internal State ──────────────────────────────────────────
326
333
  zoomLevel = 100;
327
334
  canvasPosition = { x: 0, y: 0 };
@@ -343,6 +350,11 @@ export class FlowEditorComponent {
343
350
  destroy$ = new Subject();
344
351
  initialized = false;
345
352
  lastConnectionClickTime = 0;
353
+ /** How many click-placed nodes are cascaded before the offset wraps back to the viewport centre. */
354
+ static CLICK_CASCADE_STEPS = 6;
355
+ /** Pixels (canvas units) each cascaded click-placed node is offset by. */
356
+ static CLICK_CASCADE_OFFSET = 40;
357
+ clickPlacementIndex = 0;
346
358
  constructor(cdr, stateService, layoutService) {
347
359
  this.cdr = cdr;
348
360
  this.stateService = stateService;
@@ -607,11 +619,7 @@ export class FlowEditorComponent {
607
619
  }
608
620
  /** External item dropped from palette */
609
621
  onCreateNode(event) {
610
- if (this.ReadOnly)
611
- return;
612
- this.pushUndoState();
613
- const nodeType = event.data;
614
- const config = this.NodeTypes.find(nt => nt.Type === nodeType);
622
+ const config = this.NodeTypes.find(nt => nt.Type === event.data);
615
623
  if (!config)
616
624
  return;
617
625
  // event.rect is already normalized to canvas coordinates by Foblex's
@@ -619,13 +627,45 @@ export class FlowEditorComponent {
619
627
  // Do NOT pass it through getPositionInFlow() again — that double-normalizes
620
628
  // and places the node far from the actual drop point.
621
629
  // Use the center of the preview rect (≈ cursor position at drop time).
622
- const dropPosition = {
630
+ this.addNodeFromPalette(config, {
623
631
  X: event.rect.x + event.rect.width / 2,
624
632
  Y: event.rect.y + event.rect.height / 2
625
- };
633
+ });
634
+ }
635
+ /**
636
+ * A palette entry was clicked (or activated from the keyboard) rather than dragged.
637
+ *
638
+ * Deliberately routed into the SAME `addNodeFromPalette` the drop path uses. A separate
639
+ * click-only creation path would be a second way for a node to come into existence, and the two
640
+ * would drift — which is exactly the failure this fixes, one level up.
641
+ */
642
+ onPaletteNodeTypeActivated(config) {
643
+ this.addNodeFromPalette(config, this.nextClickDropPosition());
644
+ }
645
+ /** The one place a palette-originated node is created and announced. */
646
+ addNodeFromPalette(config, dropPosition) {
647
+ if (this.ReadOnly)
648
+ return;
649
+ this.pushUndoState();
626
650
  const newNode = this.createDefaultNode(config, dropPosition);
627
651
  this.NodeAdded.emit({ Node: newNode, DropPosition: dropPosition });
628
652
  }
653
+ /**
654
+ * Where a clicked step lands: the middle of what the author is currently looking at, cascaded so
655
+ * consecutive clicks don't bury each other under one box.
656
+ *
657
+ * A click carries no coordinates, so *some* position has to be invented. The viewport centre is
658
+ * the only choice that is guaranteed on screen at any zoom or pan — placing at the canvas origin
659
+ * would drop steps off-screen the moment the author has scrolled anywhere.
660
+ */
661
+ nextClickDropPosition() {
662
+ const rect = this.canvasArea?.nativeElement.getBoundingClientRect();
663
+ const scale = this.canvasScale || 1;
664
+ const centerX = ((rect?.width ?? 800) / 2 - this.canvasPosition.x) / scale;
665
+ const centerY = ((rect?.height ?? 600) / 2 - this.canvasPosition.y) / scale;
666
+ const step = (this.clickPlacementIndex++ % FlowEditorComponent.CLICK_CASCADE_STEPS) * FlowEditorComponent.CLICK_CASCADE_OFFSET;
667
+ return { X: Math.round(centerX + step), Y: Math.round(centerY + step) };
668
+ }
629
669
  /** Selection changed in Foblex */
630
670
  onSelectionChange(event) {
631
671
  const timeSinceClick = Date.now() - this.lastConnectionClickTime;
@@ -725,23 +765,32 @@ export class FlowEditorComponent {
725
765
  this.showContextMenu(event, 'connection', null, conn);
726
766
  }
727
767
  onContextMenuAction(action) {
768
+ // Capture the target BEFORE closing: hideContextMenu() nulls contextMenuNode and
769
+ // contextMenuConnection, so reading them afterwards found nothing and every branch below fell
770
+ // through — the menu closed and neither Remove nor Edit did anything, for nodes or connections.
771
+ const targetType = this.contextMenuTargetType;
772
+ const node = this.contextMenuNode;
773
+ const connection = this.contextMenuConnection;
728
774
  this.hideContextMenu();
729
775
  if (action === 'edit') {
730
- if (this.contextMenuTargetType === 'node' && this.contextMenuNode) {
731
- this.NodeEditRequested.emit(this.contextMenuNode);
776
+ if (targetType === 'node' && node) {
777
+ this.NodeEditRequested.emit(node);
732
778
  }
733
- else if (this.contextMenuTargetType === 'connection' && this.contextMenuConnection) {
734
- this.ConnectionEditRequested.emit(this.contextMenuConnection);
779
+ else if (targetType === 'connection' && connection) {
780
+ this.ConnectionEditRequested.emit(connection);
735
781
  }
736
782
  }
737
783
  else if (action === 'remove') {
738
- this.pushUndoState();
739
- if (this.contextMenuTargetType === 'node' && this.contextMenuNode) {
740
- this.removeNodeById(this.contextMenuNode.ID);
784
+ if (targetType === 'node' && node) {
785
+ this.pushUndoState();
786
+ this.removeNodeById(node.ID);
741
787
  }
742
- else if (this.contextMenuTargetType === 'connection' && this.contextMenuConnection) {
743
- this.removeConnectionById(this.contextMenuConnection.ID);
788
+ else if (targetType === 'connection' && connection) {
789
+ this.pushUndoState();
790
+ this.removeConnectionById(connection.ID);
744
791
  }
792
+ // pushUndoState moved inside the branches: pushing before knowing there IS a target left an
793
+ // undo entry for an action that never happened, so the next Ctrl+Z did nothing visible.
745
794
  }
746
795
  }
747
796
  onDocumentClick() {
@@ -927,38 +976,39 @@ export class FlowEditorComponent {
927
976
  }
928
977
  static ɵfac = function FlowEditorComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || FlowEditorComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i1.FlowStateService), i0.ɵɵdirectiveInject(i2.FlowLayoutService)); };
929
978
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: FlowEditorComponent, selectors: [["mj-flow-editor"]], viewQuery: function FlowEditorComponent_Query(rf, ctx) { if (rf & 1) {
930
- i0.ɵɵviewQuery(FFlowComponent, 5)(FCanvasComponent, 5)(_c0, 5);
979
+ i0.ɵɵviewQuery(FFlowComponent, 5)(FCanvasComponent, 5)(_c0, 5)(_c1, 5);
931
980
  } if (rf & 2) {
932
981
  let _t;
933
982
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.fFlow = _t.first);
934
983
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.fCanvas = _t.first);
935
984
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.fZoom = _t.first);
985
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.canvasArea = _t.first);
936
986
  } }, hostBindings: function FlowEditorComponent_HostBindings(rf, ctx) { if (rf & 1) {
937
987
  i0.ɵɵlistener("click", function FlowEditorComponent_click_HostBindingHandler() { return ctx.onDocumentClick(); }, i0.ɵɵresolveDocument)("keydown", function FlowEditorComponent_keydown_HostBindingHandler($event) { return ctx.onKeyDown($event); });
938
- } }, inputs: { Nodes: "Nodes", Connections: "Connections", NodeTypes: "NodeTypes", ReadOnly: "ReadOnly", ShowMinimap: "ShowMinimap", ShowPalette: "ShowPalette", ShowGrid: "ShowGrid", ShowStatusBar: "ShowStatusBar", ShowToolbar: "ShowToolbar", ShowLegend: "ShowLegend", GridSize: "GridSize", AutoLayoutDirection: "AutoLayoutDirection", ConnectionLabelBackground: "ConnectionLabelBackground", ConnectionLabelBorderColor: "ConnectionLabelBorderColor", ConnectionLabelTextColor: "ConnectionLabelTextColor" }, outputs: { NodeSelected: "NodeSelected", NodeAdded: "NodeAdded", NodeRemoved: "NodeRemoved", NodeMoved: "NodeMoved", ConnectionCreated: "ConnectionCreated", ConnectionRemoved: "ConnectionRemoved", ConnectionReassigned: "ConnectionReassigned", ConnectionSelected: "ConnectionSelected", SelectionChanged: "SelectionChanged", CanvasClicked: "CanvasClicked", NodesChanged: "NodesChanged", ConnectionsChanged: "ConnectionsChanged", NodeEditRequested: "NodeEditRequested", ConnectionEditRequested: "ConnectionEditRequested", GridToggled: "GridToggled", MinimapToggled: "MinimapToggled", LegendToggled: "LegendToggled" }, standalone: false, features: [i0.ɵɵProvidersFeature([FlowStateService, FlowLayoutService])], decls: 21, vars: 25, consts: [["fZoomRef", "fComponent"], ["tabindex", "0", 1, "mj-flow-editor"], [1, "mj-flow-editor-toolbar-area"], [1, "mj-flow-editor-canvas-area"], [3, "NodeTypes"], [1, "mj-flow-editor-canvas"], ["fDraggable", "", 3, "fLoaded", "fCreateConnection", "fReassignConnection", "fCreateNode", "fSelectionChange", "fMoveNodes", "fDraggableDisabled", "fCanvasMoveTrigger", "vCellSize", "hCellSize", "fCellSizeWhileDragging"], [3, "fAlignThreshold"], ["fZoom", "", 3, "fCanvasChange", "fZoomMinimum", "fZoomMaximum", "fZoomStep", "position", "scale"], ["fType", "bezier", 3, "fRadius", "fOffset"], ["fType", "bezier", "fBehavior", "fixed", 3, "fConnectionId", "fOutputId", "fInputId", "fRadius", "fOffset", "fSelectionDisabled", "fReassignDisabled", "--connection-color", "mj-flow-connection-colored", "mj-flow-connection-dashed", "mj-flow-connection-dotted"], ["fNode", "", "fDragHandle", "", 3, "fNodeId", "fNodePosition", "fNodeDraggingDisabled", "fNodeSelectionDisabled", "fConnectOnNode", "Node", "TypeConfig", "ReadOnly"], ["fDragBlocker", "", 1, "mj-flow-editor-minimap"], [1, "mj-flow-editor-legend"], [1, "mj-flow-editor-empty"], [1, "mj-flow-context-menu", 3, "left", "top"], [3, "NodeCount", "ConnectionCount", "SelectedCount", "ZoomLevel"], [3, "ZoomInClicked", "ZoomOutClicked", "FitToScreenClicked", "AutoLayoutClicked", "GridToggled", "MinimapToggled", "LegendToggled", "PanModeToggled", "ZoomLevel", "ShowGrid", "ShowMinimap", "ShowLegend", "ReadOnly", "PanMode"], [3, "color", "radius"], ["viewBox", "0 0 10 10", "fMarker", "", "type", "end", "orient", "auto", 3, "refX", "refY", "height", "width"], ["d", "M0 0L10 5L0 10Z", "fill", "#94a3b8"], ["fType", "bezier", "fBehavior", "fixed", 3, "click", "contextmenu", "fConnectionId", "fOutputId", "fInputId", "fRadius", "fOffset", "fSelectionDisabled", "fReassignDisabled"], ["d", "M0 0L10 5L0 10Z"], ["fConnectionContent", "", 1, "mj-flow-connection-label", 3, "position", "backgroundColor", "borderColor", "color", "title"], ["fConnectionContent", "", 1, "mj-flow-connection-label", 3, "position", "title"], [1, "fa-solid", "mj-flow-connection-label-icon", 3, "ngClass", "color"], [1, "fa-solid", "mj-flow-connection-label-icon", 3, "ngClass"], ["fNode", "", "fDragHandle", "", 3, "contextmenu", "fNodeId", "fNodePosition", "fNodeDraggingDisabled", "fNodeSelectionDisabled", "fConnectOnNode", "Node", "TypeConfig", "ReadOnly"], [3, "fMinSize"], [1, "mj-flow-editor-legend-title"], [1, "mj-flow-editor-legend-section"], [1, "mj-flow-editor-legend-heading"], [1, "mj-flow-editor-legend-item"], ["width", "28", "height", "10", 1, "mj-flow-editor-legend-line-svg"], ["x1", "0", "y1", "5", "x2", "28", "y2", "5", "stroke", "#64748b", "stroke-width", "2"], ["x1", "0", "y1", "5", "x2", "28", "y2", "5", "stroke", "#16a34a", "stroke-width", "2"], [1, "fa-solid", "fa-circle-check", 2, "color", "#16a34a", "font-size", "10px"], ["x1", "0", "y1", "5", "x2", "28", "y2", "5", "stroke", "#f59e0b", "stroke-width", "2", "stroke-dasharray", "5 3"], ["x1", "0", "y1", "5", "x2", "28", "y2", "5", "stroke", "#ef4444", "stroke-width", "2"], [1, "fa-solid", "fa-triangle-exclamation", 2, "color", "#ef4444", "font-size", "10px"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#3B82F6"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#8B5CF6"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#10B981"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#F59E0B"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#F97316"], [1, "mj-flow-editor-legend-box", 2, "border-color", "#16a34a", "background", "#f0fdf4"], [1, "mj-flow-editor-legend-box", 2, "border-color", "#ef4444", "background", "#fef2f2"], [1, "fa-solid", "fa-triangle-exclamation", 2, "color", "#ea580c", "font-size", "10px"], ["Icon", "fa-solid fa-diagram-project", 3, "Title"], [1, "mj-flow-editor-empty-subtitle"], [1, "mj-flow-context-menu", 3, "click"], [1, "mj-flow-context-menu-item", 3, "click"], [1, "fa-solid", "fa-pen-to-square"], [1, "mj-flow-context-menu-divider"], [1, "mj-flow-context-menu-item", "mj-flow-context-menu-item--danger", 3, "click"], [1, "fa-solid", "fa-trash-can"]], template: function FlowEditorComponent_Template(rf, ctx) { if (rf & 1) {
988
+ } }, inputs: { Nodes: "Nodes", Connections: "Connections", NodeTypes: "NodeTypes", ReadOnly: "ReadOnly", ShowMinimap: "ShowMinimap", ShowPalette: "ShowPalette", ShowGrid: "ShowGrid", ShowStatusBar: "ShowStatusBar", ShowToolbar: "ShowToolbar", ShowLegend: "ShowLegend", GridSize: "GridSize", AutoLayoutDirection: "AutoLayoutDirection", ConnectionLabelBackground: "ConnectionLabelBackground", ConnectionLabelBorderColor: "ConnectionLabelBorderColor", ConnectionLabelTextColor: "ConnectionLabelTextColor" }, outputs: { NodeSelected: "NodeSelected", NodeAdded: "NodeAdded", NodeRemoved: "NodeRemoved", NodeMoved: "NodeMoved", ConnectionCreated: "ConnectionCreated", ConnectionRemoved: "ConnectionRemoved", ConnectionReassigned: "ConnectionReassigned", ConnectionSelected: "ConnectionSelected", SelectionChanged: "SelectionChanged", CanvasClicked: "CanvasClicked", NodesChanged: "NodesChanged", ConnectionsChanged: "ConnectionsChanged", NodeEditRequested: "NodeEditRequested", ConnectionEditRequested: "ConnectionEditRequested", GridToggled: "GridToggled", MinimapToggled: "MinimapToggled", LegendToggled: "LegendToggled" }, standalone: false, features: [i0.ɵɵProvidersFeature([FlowStateService, FlowLayoutService])], decls: 22, vars: 25, consts: [["canvasArea", ""], ["fZoomRef", "fComponent"], ["tabindex", "0", 1, "mj-flow-editor"], [1, "mj-flow-editor-toolbar-area"], [1, "mj-flow-editor-canvas-area"], [3, "NodeTypes"], [1, "mj-flow-editor-canvas"], ["fDraggable", "", 3, "fLoaded", "fCreateConnection", "fReassignConnection", "fCreateNode", "fSelectionChange", "fMoveNodes", "fDraggableDisabled", "fCanvasMoveTrigger", "vCellSize", "hCellSize", "fCellSizeWhileDragging"], [3, "fAlignThreshold"], ["fZoom", "", 3, "fCanvasChange", "fZoomMinimum", "fZoomMaximum", "fZoomStep", "position", "scale"], ["fType", "bezier", 3, "fRadius", "fOffset"], ["fType", "bezier", "fBehavior", "fixed", 3, "fConnectionId", "fOutputId", "fInputId", "fRadius", "fOffset", "fSelectionDisabled", "fReassignDisabled", "--connection-color", "mj-flow-connection-colored", "mj-flow-connection-dashed", "mj-flow-connection-dotted"], ["fNode", "", "fDragHandle", "", 3, "fNodeId", "fNodePosition", "fNodeDraggingDisabled", "fNodeSelectionDisabled", "fConnectOnNode", "Node", "TypeConfig", "ReadOnly"], ["fDragBlocker", "", 1, "mj-flow-editor-minimap"], [1, "mj-flow-editor-legend"], [1, "mj-flow-editor-empty"], [1, "mj-flow-context-menu", 3, "left", "top"], [3, "NodeCount", "ConnectionCount", "SelectedCount", "ZoomLevel"], [3, "ZoomInClicked", "ZoomOutClicked", "FitToScreenClicked", "AutoLayoutClicked", "GridToggled", "MinimapToggled", "LegendToggled", "PanModeToggled", "ZoomLevel", "ShowGrid", "ShowMinimap", "ShowLegend", "ReadOnly", "PanMode"], [3, "NodeTypeActivated", "NodeTypes"], [3, "color", "radius"], ["viewBox", "0 0 10 10", "fMarker", "", "type", "end", "orient", "auto", 3, "refX", "refY", "height", "width"], ["d", "M0 0L10 5L0 10Z", "fill", "#94a3b8"], ["fType", "bezier", "fBehavior", "fixed", 3, "click", "contextmenu", "fConnectionId", "fOutputId", "fInputId", "fRadius", "fOffset", "fSelectionDisabled", "fReassignDisabled"], ["d", "M0 0L10 5L0 10Z"], ["fConnectionContent", "", 1, "mj-flow-connection-label", 3, "position", "backgroundColor", "borderColor", "color", "title"], ["fConnectionContent", "", 1, "mj-flow-connection-label", 3, "position", "title"], [1, "fa-solid", "mj-flow-connection-label-icon", 3, "ngClass", "color"], [1, "fa-solid", "mj-flow-connection-label-icon", 3, "ngClass"], ["fNode", "", "fDragHandle", "", 3, "contextmenu", "fNodeId", "fNodePosition", "fNodeDraggingDisabled", "fNodeSelectionDisabled", "fConnectOnNode", "Node", "TypeConfig", "ReadOnly"], [3, "fMinSize"], [1, "mj-flow-editor-legend-title"], [1, "mj-flow-editor-legend-section"], [1, "mj-flow-editor-legend-heading"], [1, "mj-flow-editor-legend-item"], ["width", "28", "height", "10", 1, "mj-flow-editor-legend-line-svg"], ["x1", "0", "y1", "5", "x2", "28", "y2", "5", "stroke", "#64748b", "stroke-width", "2"], ["x1", "0", "y1", "5", "x2", "28", "y2", "5", "stroke", "#16a34a", "stroke-width", "2"], [1, "fa-solid", "fa-circle-check", 2, "color", "#16a34a", "font-size", "10px"], ["x1", "0", "y1", "5", "x2", "28", "y2", "5", "stroke", "#f59e0b", "stroke-width", "2", "stroke-dasharray", "5 3"], ["x1", "0", "y1", "5", "x2", "28", "y2", "5", "stroke", "#ef4444", "stroke-width", "2"], [1, "fa-solid", "fa-triangle-exclamation", 2, "color", "#ef4444", "font-size", "10px"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#3B82F6"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#8B5CF6"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#10B981"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#F59E0B"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#F97316"], [1, "mj-flow-editor-legend-box", 2, "border-color", "#16a34a", "background", "#f0fdf4"], [1, "mj-flow-editor-legend-box", 2, "border-color", "#ef4444", "background", "#fef2f2"], [1, "fa-solid", "fa-triangle-exclamation", 2, "color", "#ea580c", "font-size", "10px"], ["Icon", "fa-solid fa-diagram-project", 3, "Title"], [1, "mj-flow-editor-empty-subtitle"], [1, "mj-flow-context-menu", 3, "click"], [1, "mj-flow-context-menu-item", 3, "click"], [1, "fa-solid", "fa-pen-to-square"], [1, "mj-flow-context-menu-divider"], [1, "mj-flow-context-menu-item", "mj-flow-context-menu-item--danger", 3, "click"], [1, "fa-solid", "fa-trash-can"]], template: function FlowEditorComponent_Template(rf, ctx) { if (rf & 1) {
939
989
  const _r1 = i0.ɵɵgetCurrentView();
940
- i0.ɵɵelementStart(0, "div", 1);
941
- i0.ɵɵconditionalCreate(1, FlowEditorComponent_Conditional_1_Template, 2, 6, "div", 2);
942
- i0.ɵɵelementStart(2, "div", 3);
943
- i0.ɵɵconditionalCreate(3, FlowEditorComponent_Conditional_3_Template, 1, 1, "mj-flow-palette", 4);
944
- i0.ɵɵelementStart(4, "div", 5)(5, "f-flow", 6);
945
- i0.ɵɵlistener("fLoaded", function FlowEditorComponent_Template_f_flow_fLoaded_5_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onFlowLoaded()); })("fCreateConnection", function FlowEditorComponent_Template_f_flow_fCreateConnection_5_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onCreateConnection($event)); })("fReassignConnection", function FlowEditorComponent_Template_f_flow_fReassignConnection_5_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onReassignConnection($event)); })("fCreateNode", function FlowEditorComponent_Template_f_flow_fCreateNode_5_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onCreateNode($event)); })("fSelectionChange", function FlowEditorComponent_Template_f_flow_fSelectionChange_5_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onSelectionChange($event)); })("fMoveNodes", function FlowEditorComponent_Template_f_flow_fMoveNodes_5_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onNodesMoved($event)); });
946
- i0.ɵɵconditionalCreate(6, FlowEditorComponent_Conditional_6_Template, 2, 2, "f-background");
947
- i0.ɵɵconditionalCreate(7, FlowEditorComponent_Conditional_7_Template, 1, 1, "f-line-alignment", 7);
948
- i0.ɵɵelementStart(8, "f-canvas", 8, 0);
949
- i0.ɵɵlistener("fCanvasChange", function FlowEditorComponent_Template_f_canvas_fCanvasChange_8_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onCanvasChange($event)); });
950
- i0.ɵɵconditionalCreate(10, FlowEditorComponent_Conditional_10_Template, 3, 6, "f-connection-for-create", 9);
951
- i0.ɵɵrepeaterCreate(11, FlowEditorComponent_For_12_Template, 4, 21, "f-connection", 10, ctx.trackConnectionById, true);
952
- i0.ɵɵrepeaterCreate(13, FlowEditorComponent_For_14_Template, 1, 11, "mj-flow-node", 11, ctx.trackNodeById, true);
990
+ i0.ɵɵelementStart(0, "div", 2);
991
+ i0.ɵɵconditionalCreate(1, FlowEditorComponent_Conditional_1_Template, 2, 6, "div", 3);
992
+ i0.ɵɵelementStart(2, "div", 4);
993
+ i0.ɵɵconditionalCreate(3, FlowEditorComponent_Conditional_3_Template, 1, 1, "mj-flow-palette", 5);
994
+ i0.ɵɵelementStart(4, "div", 6, 0)(6, "f-flow", 7);
995
+ i0.ɵɵlistener("fLoaded", function FlowEditorComponent_Template_f_flow_fLoaded_6_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onFlowLoaded()); })("fCreateConnection", function FlowEditorComponent_Template_f_flow_fCreateConnection_6_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onCreateConnection($event)); })("fReassignConnection", function FlowEditorComponent_Template_f_flow_fReassignConnection_6_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onReassignConnection($event)); })("fCreateNode", function FlowEditorComponent_Template_f_flow_fCreateNode_6_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onCreateNode($event)); })("fSelectionChange", function FlowEditorComponent_Template_f_flow_fSelectionChange_6_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onSelectionChange($event)); })("fMoveNodes", function FlowEditorComponent_Template_f_flow_fMoveNodes_6_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onNodesMoved($event)); });
996
+ i0.ɵɵconditionalCreate(7, FlowEditorComponent_Conditional_7_Template, 2, 2, "f-background");
997
+ i0.ɵɵconditionalCreate(8, FlowEditorComponent_Conditional_8_Template, 1, 1, "f-line-alignment", 8);
998
+ i0.ɵɵelementStart(9, "f-canvas", 9, 1);
999
+ i0.ɵɵlistener("fCanvasChange", function FlowEditorComponent_Template_f_canvas_fCanvasChange_9_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onCanvasChange($event)); });
1000
+ i0.ɵɵconditionalCreate(11, FlowEditorComponent_Conditional_11_Template, 3, 6, "f-connection-for-create", 10);
1001
+ i0.ɵɵrepeaterCreate(12, FlowEditorComponent_For_13_Template, 4, 21, "f-connection", 11, ctx.trackConnectionById, true);
1002
+ i0.ɵɵrepeaterCreate(14, FlowEditorComponent_For_15_Template, 1, 11, "mj-flow-node", 12, ctx.trackNodeById, true);
953
1003
  i0.ɵɵelementEnd();
954
- i0.ɵɵconditionalCreate(15, FlowEditorComponent_Conditional_15_Template, 1, 0, "f-selection-area");
955
- i0.ɵɵconditionalCreate(16, FlowEditorComponent_Conditional_16_Template, 2, 1, "div", 12);
1004
+ i0.ɵɵconditionalCreate(16, FlowEditorComponent_Conditional_16_Template, 1, 0, "f-selection-area");
1005
+ i0.ɵɵconditionalCreate(17, FlowEditorComponent_Conditional_17_Template, 2, 1, "div", 13);
956
1006
  i0.ɵɵelementEnd();
957
- i0.ɵɵconditionalCreate(17, FlowEditorComponent_Conditional_17_Template, 63, 0, "div", 13);
958
- i0.ɵɵconditionalCreate(18, FlowEditorComponent_Conditional_18_Template, 3, 2, "div", 14);
1007
+ i0.ɵɵconditionalCreate(18, FlowEditorComponent_Conditional_18_Template, 63, 0, "div", 14);
1008
+ i0.ɵɵconditionalCreate(19, FlowEditorComponent_Conditional_19_Template, 3, 2, "div", 15);
959
1009
  i0.ɵɵelementEnd()();
960
- i0.ɵɵconditionalCreate(19, FlowEditorComponent_Conditional_19_Template, 10, 6, "div", 15);
961
- i0.ɵɵconditionalCreate(20, FlowEditorComponent_Conditional_20_Template, 1, 4, "mj-flow-status-bar", 16);
1010
+ i0.ɵɵconditionalCreate(20, FlowEditorComponent_Conditional_20_Template, 10, 6, "div", 16);
1011
+ i0.ɵɵconditionalCreate(21, FlowEditorComponent_Conditional_21_Template, 1, 4, "mj-flow-status-bar", 17);
962
1012
  i0.ɵɵelementEnd();
963
1013
  } if (rf & 2) {
964
1014
  i0.ɵɵclassProp("mj-flow-editor--readonly", ctx.ReadOnly);
@@ -968,37 +1018,37 @@ export class FlowEditorComponent {
968
1018
  i0.ɵɵconditional(ctx.ShowPalette && !ctx.ReadOnly ? 3 : -1);
969
1019
  i0.ɵɵadvance();
970
1020
  i0.ɵɵclassProp("mj-flow-editor-canvas--pan-mode", ctx.panMode);
971
- i0.ɵɵadvance();
1021
+ i0.ɵɵadvance(2);
972
1022
  i0.ɵɵproperty("fDraggableDisabled", false)("fCanvasMoveTrigger", ctx.canvasMoveTriggerFn)("vCellSize", ctx.GridSize)("hCellSize", ctx.GridSize)("fCellSizeWhileDragging", ctx.ShowGrid);
973
1023
  i0.ɵɵadvance();
974
- i0.ɵɵconditional(ctx.ShowGrid ? 6 : -1);
1024
+ i0.ɵɵconditional(ctx.ShowGrid ? 7 : -1);
975
1025
  i0.ɵɵadvance();
976
- i0.ɵɵconditional(!ctx.ReadOnly ? 7 : -1);
1026
+ i0.ɵɵconditional(!ctx.ReadOnly ? 8 : -1);
977
1027
  i0.ɵɵadvance();
978
1028
  i0.ɵɵproperty("fZoomMinimum", 0.15)("fZoomMaximum", 3)("fZoomStep", 0.1)("position", ctx.canvasPosition)("scale", ctx.canvasScale);
979
1029
  i0.ɵɵadvance(2);
980
- i0.ɵɵconditional(!ctx.ReadOnly ? 10 : -1);
1030
+ i0.ɵɵconditional(!ctx.ReadOnly ? 11 : -1);
981
1031
  i0.ɵɵadvance();
982
1032
  i0.ɵɵrepeater(ctx.Connections);
983
1033
  i0.ɵɵadvance(2);
984
1034
  i0.ɵɵrepeater(ctx.Nodes);
985
1035
  i0.ɵɵadvance(2);
986
- i0.ɵɵconditional(!ctx.ReadOnly ? 15 : -1);
1036
+ i0.ɵɵconditional(!ctx.ReadOnly ? 16 : -1);
987
1037
  i0.ɵɵadvance();
988
- i0.ɵɵconditional(ctx.ShowMinimap ? 16 : -1);
1038
+ i0.ɵɵconditional(ctx.ShowMinimap ? 17 : -1);
989
1039
  i0.ɵɵadvance();
990
- i0.ɵɵconditional(ctx.ShowLegend && ctx.Nodes.length > 0 ? 17 : -1);
1040
+ i0.ɵɵconditional(ctx.ShowLegend && ctx.Nodes.length > 0 ? 18 : -1);
991
1041
  i0.ɵɵadvance();
992
- i0.ɵɵconditional(ctx.Nodes.length === 0 ? 18 : -1);
1042
+ i0.ɵɵconditional(ctx.Nodes.length === 0 ? 19 : -1);
993
1043
  i0.ɵɵadvance();
994
- i0.ɵɵconditional(ctx.contextMenuVisible ? 19 : -1);
1044
+ i0.ɵɵconditional(ctx.contextMenuVisible ? 20 : -1);
995
1045
  i0.ɵɵadvance();
996
- i0.ɵɵconditional(ctx.ShowStatusBar ? 20 : -1);
1046
+ i0.ɵɵconditional(ctx.ShowStatusBar ? 21 : -1);
997
1047
  } }, dependencies: [i3.NgClass, i4.FFlowComponent, i4.FCanvasComponent, i4.FBackgroundComponent, i4.FCirclePatternComponent, i4.FZoomDirective, i4.FConnectionContent, i4.FConnectionMarker, i4.FConnectionComponent, i4.FConnectionForCreateComponent, i4.FLineAlignmentComponent, i4.FMinimapComponent, i4.FNodeDirective, i4.FDragHandleDirective, i4.FSelectionAreaComponent, i4.FDragBlockerDirective, i4.FDraggableDirective, i5.MJEmptyStateComponent, i6.FlowNodeComponent, i7.FlowPaletteComponent, i8.FlowToolbarComponent, i9.FlowStatusBarComponent], styles: ["/* ============================================================\n Flow Editor \u2014 Main container styles\n ============================================================ */\n\n.mj-flow-editor {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-height: 400px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n outline: none;\n position: relative;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n}\n\n.mj-flow-editor--readonly .mj-flow-node-port {\n cursor: default;\n pointer-events: none;\n}\n\n/* \u2500\u2500 Toolbar Area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-toolbar-area {\n position: absolute;\n top: 10px;\n left: 50%;\n transform: translateX(-50%);\n z-index: 20;\n}\n\n/* \u2500\u2500 Canvas Area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-canvas-area {\n display: flex;\n flex: 1;\n overflow: hidden;\n position: relative;\n}\n\n.mj-flow-editor-canvas {\n flex: 1;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface);\n}\n\n.mj-flow-editor-canvas f-flow {\n width: 100%;\n height: 100%;\n}\n\n/* Pan mode \u2014 grab cursor, nodes pass through pointer events to canvas */\n.mj-flow-editor-canvas--pan-mode {\n cursor: grab;\n}\n\n.mj-flow-editor-canvas--pan-mode:active {\n cursor: grabbing;\n}\n\n.mj-flow-editor-canvas--pan-mode mj-flow-node {\n pointer-events: none;\n cursor: grab;\n}\n\n.mj-flow-editor-canvas--pan-mode f-connection {\n pointer-events: none;\n}\n\n.mj-flow-editor-canvas--pan-mode .mj-flow-connection-label {\n pointer-events: none;\n}\n\n/* \u2500\u2500 Minimap \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-minimap {\n position: absolute;\n bottom: 12px;\n right: 12px;\n width: 160px;\n height: 120px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n z-index: 15;\n}\n\n.mj-flow-editor-minimap f-minimap {\n width: 100%;\n height: 100%;\n}\n\n/* Foblex minimap SVG node rectangles (no default styles provided by Foblex) */\n.mj-flow-editor-minimap .f-minimap-node {\n fill: var(--mj-border-strong);\n stroke: var(--mj-text-disabled);\n stroke-width: 1;\n rx: 3;\n ry: 3;\n}\n\n.mj-flow-editor-minimap .f-minimap-node.f-selected {\n fill: color-mix(in srgb, var(--mj-brand-primary) 50%, var(--mj-bg-surface));\n stroke: var(--mj-brand-primary);\n stroke-width: 1.5;\n}\n\n.mj-flow-editor-minimap .f-minimap-group {\n fill: var(--mj-border-default);\n stroke: var(--mj-text-disabled);\n stroke-width: 0.5;\n rx: 2;\n ry: 2;\n}\n\n/* Viewport indicator rectangle */\n.mj-flow-editor-minimap .f-minimap-view {\n fill: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n stroke: var(--mj-brand-primary);\n stroke-width: 1.5;\n}\n\n/* \u2500\u2500 Empty State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-empty {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n z-index: 5;\n}\n\n.mj-flow-editor-empty-subtitle {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-disabled);\n margin: 0;\n}\n\n/* \u2500\u2500 Connection Labels \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-connection-label {\n display: inline-flex;\n align-items: flex-start;\n gap: 5px;\n background: var(--mj-bg-surface);\n border: 1.5px solid var(--mj-border-strong);\n border-radius: 5px;\n padding: 4px 10px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n box-shadow: var(--mj-shadow-sm);\n pointer-events: none;\n line-height: 1.4;\n text-align: center;\n}\n\n.mj-flow-connection-label-icon {\n font-size: 10px;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n/* \u2500\u2500 Foblex Overrides \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* Canvas \u2014 transparent so the grid pattern shows through */\nf-canvas {\n background: transparent;\n}\n\n/* Selection area */\nf-selection-area {\n --f-selection-area-background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n --f-selection-area-border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n/* Line alignment guides */\nf-line-alignment {\n --f-line-alignment-color: var(--mj-brand-primary);\n}\n\n/* Connection paths \u2014 default stroke color prevents invisible connections */\n.f-connection path {\n stroke: var(--mj-text-disabled);\n stroke-width: 2;\n fill: none;\n transition: stroke 0.15s ease, stroke-width 0.15s ease;\n}\n\n.f-connection:hover path {\n stroke-width: 3;\n}\n\n.f-connection.f-selected path {\n stroke: var(--mj-brand-primary);\n stroke-width: 3;\n}\n\n/* Colored connections use the --connection-color custom property,\n defaulting to neutral when no color is specified by the consumer */\n.mj-flow-connection-colored path {\n stroke: var(--connection-color, var(--mj-text-disabled));\n}\n\n.mj-flow-connection-colored.f-selected path {\n stroke: var(--connection-color, var(--mj-brand-primary));\n stroke-width: 3;\n filter: brightness(0.85);\n}\n\n/* Dashed connection style */\n.mj-flow-connection-dashed path {\n stroke-dasharray: 8 4;\n}\n\n/* Dotted connection style */\n.mj-flow-connection-dotted path {\n stroke-dasharray: 3 3;\n}\n\n/* Connection for create (dragging) */\n.f-connection-for-create path {\n stroke: var(--mj-text-disabled);\n stroke-dasharray: 6 3;\n stroke-width: 2;\n}\n\n/* \u2500\u2500 Legend \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-legend {\n position: absolute;\n bottom: 12px;\n left: 12px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n backdrop-filter: blur(6px);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 10px 14px;\n box-shadow: var(--mj-shadow-sm);\n z-index: 15;\n font-size: 11px;\n color: var(--mj-text-secondary);\n max-width: 200px;\n}\n\n.mj-flow-editor-legend-title {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 8px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.mj-flow-editor-legend-section {\n margin-bottom: 8px;\n}\n\n.mj-flow-editor-legend-section:last-child {\n margin-bottom: 0;\n}\n\n.mj-flow-editor-legend-heading {\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n margin-bottom: 4px;\n}\n\n.mj-flow-editor-legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 2px 0;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.mj-flow-editor-legend-svg,\n.mj-flow-editor-legend-line-svg {\n flex-shrink: 0;\n}\n\n.mj-flow-editor-legend-swatch {\n display: inline-block;\n width: 10px;\n height: 10px;\n border-radius: var(--mj-radius-sm);\n flex-shrink: 0;\n}\n\n.mj-flow-editor-legend-box {\n display: inline-block;\n width: 14px;\n height: 10px;\n border: 2px solid;\n border-radius: var(--mj-radius-sm);\n flex-shrink: 0;\n}\n\n/* \u2500\u2500 Context Menu \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-context-menu {\n position: fixed;\n min-width: 180px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-lg);\n padding: 4px;\n z-index: 9999;\n animation: mj-ctx-fade-in 0.1s ease-out;\n}\n\n@keyframes mj-ctx-fade-in {\n from { opacity: 0; transform: scale(0.95); }\n to { opacity: 1; transform: scale(1); }\n}\n\n.mj-flow-context-menu-item {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 8px 12px;\n border: none;\n background: none;\n font-size: var(--mj-text-sm);\n font-weight: 450;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 5px;\n text-align: left;\n transition: background-color 0.1s ease;\n}\n\n.mj-flow-context-menu-item:hover {\n background-color: var(--mj-bg-surface-sunken);\n}\n\n.mj-flow-context-menu-item i {\n width: 16px;\n text-align: center;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mj-flow-context-menu-item--danger {\n color: var(--mj-status-error);\n}\n\n.mj-flow-context-menu-item--danger:hover {\n background-color: var(--mj-status-error-subtle);\n}\n\n.mj-flow-context-menu-item--danger i {\n color: var(--mj-status-error);\n}\n\n.mj-flow-context-menu-divider {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 8px;\n}\n\n/* \u2500\u2500 Focus Indicators (Accessibility) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-toolbar-btn:focus-visible,\n.mj-agent-editor-btn:focus-visible,\n.mj-agent-editor-view-btn:focus-visible,\n.mj-agent-props-close:focus-visible,\n.mj-agent-props-delete-btn:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.mj-flow-palette-item:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 1px;\n border-radius: var(--mj-radius-md);\n}\n"], encapsulation: 2 });
998
1048
  }
999
1049
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FlowEditorComponent, [{
1000
1050
  type: Component,
1001
- args: [{ standalone: false, selector: 'mj-flow-editor', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.Default, providers: [FlowStateService, FlowLayoutService], template: "<div class=\"mj-flow-editor\" [class.mj-flow-editor--readonly]=\"ReadOnly\" tabindex=\"0\">\n\n <!-- Canvas Toolbar -->\n @if (ShowToolbar) {\n <div class=\"mj-flow-editor-toolbar-area\">\n <mj-flow-toolbar\n [ZoomLevel]=\"zoomLevel\"\n [ShowGrid]=\"ShowGrid\"\n [ShowMinimap]=\"ShowMinimap\"\n [ShowLegend]=\"ShowLegend\"\n [ReadOnly]=\"ReadOnly\"\n [PanMode]=\"panMode\"\n (ZoomInClicked)=\"ZoomIn()\"\n (ZoomOutClicked)=\"ZoomOut()\"\n (FitToScreenClicked)=\"ZoomToFit()\"\n (AutoLayoutClicked)=\"AutoArrange()\"\n (GridToggled)=\"onGridToggled($event)\"\n (MinimapToggled)=\"onMinimapToggled($event)\"\n (LegendToggled)=\"onLegendToggled($event)\"\n (PanModeToggled)=\"onPanModeToggled($event)\">\n </mj-flow-toolbar>\n </div>\n }\n\n <!-- Main Canvas Area -->\n <div class=\"mj-flow-editor-canvas-area\">\n\n <!-- Palette Sidebar -->\n @if (ShowPalette && !ReadOnly) {\n <mj-flow-palette\n [NodeTypes]=\"NodeTypes\">\n </mj-flow-palette>\n }\n\n <!-- Foblex Canvas -->\n <div class=\"mj-flow-editor-canvas\"\n [class.mj-flow-editor-canvas--pan-mode]=\"panMode\">\n <f-flow fDraggable\n [fDraggableDisabled]=\"false\"\n [fCanvasMoveTrigger]=\"canvasMoveTriggerFn\"\n [vCellSize]=\"GridSize\"\n [hCellSize]=\"GridSize\"\n [fCellSizeWhileDragging]=\"ShowGrid\"\n (fLoaded)=\"onFlowLoaded()\"\n (fCreateConnection)=\"onCreateConnection($event)\"\n (fReassignConnection)=\"onReassignConnection($event)\"\n (fCreateNode)=\"onCreateNode($event)\"\n (fSelectionChange)=\"onSelectionChange($event)\"\n (fMoveNodes)=\"onNodesMoved($event)\">\n\n <!-- Background grid \u2014 MUST be direct child of f-flow (Foblex content projection requires it) -->\n @if (ShowGrid) {\n <f-background>\n <f-circle-pattern [color]=\"'#94a3b8'\" [radius]=\"24\"></f-circle-pattern>\n </f-background>\n }\n\n <!-- Alignment snap lines \u2014 direct child of f-flow -->\n @if (!ReadOnly) {\n <f-line-alignment [fAlignThreshold]=\"10\"></f-line-alignment>\n }\n\n <f-canvas fZoom #fZoomRef=\"fComponent\"\n [fZoomMinimum]=\"0.15\"\n [fZoomMaximum]=\"3\"\n [fZoomStep]=\"0.1\"\n [position]=\"canvasPosition\"\n [scale]=\"canvasScale\"\n (fCanvasChange)=\"onCanvasChange($event)\">\n\n <!-- Interactive connection drawing -->\n @if (!ReadOnly) {\n <f-connection-for-create\n fType=\"bezier\"\n [fRadius]=\"8\"\n [fOffset]=\"12\">\n <svg viewBox=\"0 0 10 10\" fMarker type=\"end\"\n orient=\"auto\" [refX]=\"9\" [refY]=\"5\" [height]=\"10\" [width]=\"10\">\n <path d=\"M0 0L10 5L0 10Z\" fill=\"#94a3b8\"/>\n </svg>\n </f-connection-for-create>\n }\n\n <!-- Connections -->\n @for (conn of Connections; track trackConnectionById($index, conn)) {\n <f-connection\n [fConnectionId]=\"conn.ID\"\n [fOutputId]=\"conn.SourcePortID\"\n [fInputId]=\"conn.TargetPortID\"\n fType=\"bezier\"\n fBehavior=\"fixed\"\n [fRadius]=\"8\"\n [fOffset]=\"12\"\n [fSelectionDisabled]=\"false\"\n [fReassignDisabled]=\"ReadOnly\"\n [style.--connection-color]=\"conn.Color || '#94a3b8'\"\n [class.mj-flow-connection-colored]=\"!!conn.Color\"\n [class.mj-flow-connection-dashed]=\"conn.Style === 'dashed'\"\n [class.mj-flow-connection-dotted]=\"conn.Style === 'dotted'\"\n (click)=\"onConnectionClicked($event, conn)\"\n (contextmenu)=\"onConnectionContextMenu($event, conn)\">\n <!-- Arrow marker -->\n <svg viewBox=\"0 0 10 10\" fMarker type=\"end\"\n orient=\"auto\" [refX]=\"9\" [refY]=\"5\" [height]=\"10\" [width]=\"10\">\n <path d=\"M0 0L10 5L0 10Z\" [attr.fill]=\"conn.Color || '#94a3b8'\"/>\n </svg>\n <!-- Connection label -->\n @if (conn.Label) {\n <div fConnectionContent [position]=\"0.5\"\n class=\"mj-flow-connection-label\"\n [style.backgroundColor]=\"ConnectionLabelBackground\"\n [style.borderColor]=\"ConnectionLabelBorderColor\"\n [style.color]=\"ConnectionLabelTextColor\"\n [title]=\"conn.LabelDetail || conn.Label || ''\">\n @if (conn.LabelIcon) {\n <i\n class=\"fa-solid mj-flow-connection-label-icon\"\n [ngClass]=\"conn.LabelIcon\"\n [style.color]=\"conn.LabelIconColor || 'inherit'\"></i>\n }\n {{ conn.Label }}\n </div>\n }\n </f-connection>\n }\n\n <!-- Nodes -->\n @for (node of Nodes; track trackNodeById($index, node)) {\n <mj-flow-node\n fNode\n fDragHandle\n [fNodeId]=\"node.ID\"\n [fNodePosition]=\"{ x: node.Position.X, y: node.Position.Y }\"\n [fNodeDraggingDisabled]=\"ReadOnly || panMode || node.Locked === true\"\n [fNodeSelectionDisabled]=\"panMode\"\n [fConnectOnNode]=\"!ReadOnly && !panMode\"\n [Node]=\"node\"\n [TypeConfig]=\"GetTypeConfig(node.Type)\"\n [ReadOnly]=\"ReadOnly\"\n (contextmenu)=\"onNodeContextMenu($event, node)\">\n </mj-flow-node>\n }\n\n </f-canvas>\n\n <!-- Rubber-band selection \u2014 direct child of f-flow -->\n @if (!ReadOnly) {\n <f-selection-area></f-selection-area>\n }\n\n <!-- Minimap -->\n @if (ShowMinimap) {\n <div class=\"mj-flow-editor-minimap\" fDragBlocker>\n <f-minimap [fMinSize]=\"1500\"></f-minimap>\n </div>\n }\n </f-flow>\n\n <!-- Legend -->\n @if (ShowLegend && Nodes.length > 0) {\n <div class=\"mj-flow-editor-legend\">\n <div class=\"mj-flow-editor-legend-title\">Legend</div>\n <div class=\"mj-flow-editor-legend-section\">\n <div class=\"mj-flow-editor-legend-heading\">Connections</div>\n <div class=\"mj-flow-editor-legend-item\">\n <svg class=\"mj-flow-editor-legend-line-svg\" width=\"28\" height=\"10\"><line x1=\"0\" y1=\"5\" x2=\"28\" y2=\"5\" stroke=\"#64748b\" stroke-width=\"2\"/></svg>\n <span>Only exit path</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <svg class=\"mj-flow-editor-legend-line-svg\" width=\"28\" height=\"10\"><line x1=\"0\" y1=\"5\" x2=\"28\" y2=\"5\" stroke=\"#16a34a\" stroke-width=\"2\"/></svg>\n <i class=\"fa-solid fa-circle-check\" style=\"color:#16a34a;font-size:10px;\"></i>\n <span>Default (fallback)</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <svg class=\"mj-flow-editor-legend-line-svg\" width=\"28\" height=\"10\"><line x1=\"0\" y1=\"5\" x2=\"28\" y2=\"5\" stroke=\"#f59e0b\" stroke-width=\"2\" stroke-dasharray=\"5 3\"/></svg>\n <span>Conditional</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <svg class=\"mj-flow-editor-legend-line-svg\" width=\"28\" height=\"10\"><line x1=\"0\" y1=\"5\" x2=\"28\" y2=\"5\" stroke=\"#ef4444\" stroke-width=\"2\"/></svg>\n <i class=\"fa-solid fa-triangle-exclamation\" style=\"color:#ef4444;font-size:10px;\"></i>\n <span>Duplicate defaults</span>\n </div>\n </div>\n <div class=\"mj-flow-editor-legend-section\">\n <div class=\"mj-flow-editor-legend-heading\">Step Types</div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#3B82F6\"></span>\n <span>Action</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#8B5CF6\"></span>\n <span>Prompt</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#10B981\"></span>\n <span>Sub-Agent</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#F59E0B\"></span>\n <span>For Each</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#F97316\"></span>\n <span>While</span>\n </div>\n </div>\n <div class=\"mj-flow-editor-legend-section\">\n <div class=\"mj-flow-editor-legend-heading\">Borders</div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-box\" style=\"border-color:#16a34a;background:#f0fdf4;\"></span>\n <span>Start node</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-box\" style=\"border-color:#ef4444;background:#fef2f2;\"></span>\n <i class=\"fa-solid fa-triangle-exclamation\" style=\"color:#ea580c;font-size:10px;\"></i>\n <span>Missing config</span>\n </div>\n </div>\n </div>\n }\n\n <!-- Empty state overlay -->\n @if (Nodes.length === 0) {\n <div class=\"mj-flow-editor-empty\">\n <mj-empty-state\n Icon=\"fa-solid fa-diagram-project\"\n [Title]=\"EmptyStateTitle\">\n @if (!ReadOnly) {\n <p class=\"mj-flow-editor-empty-subtitle\">\n Or use auto-layout after adding steps to arrange them automatically\n </p>\n }\n </mj-empty-state>\n </div>\n }\n </div>\n </div>\n\n <!-- Context Menu -->\n @if (contextMenuVisible) {\n <div\n class=\"mj-flow-context-menu\"\n [style.left.px]=\"contextMenuX\"\n [style.top.px]=\"contextMenuY\"\n (click)=\"$event.stopPropagation()\">\n <button class=\"mj-flow-context-menu-item\" (click)=\"onContextMenuAction('edit')\">\n <i class=\"fa-solid fa-pen-to-square\"></i>\n <span>Edit {{ contextMenuTargetType === 'node' ? 'Node' : 'Connection' }}</span>\n </button>\n <div class=\"mj-flow-context-menu-divider\"></div>\n <button class=\"mj-flow-context-menu-item mj-flow-context-menu-item--danger\" (click)=\"onContextMenuAction('remove')\">\n <i class=\"fa-solid fa-trash-can\"></i>\n <span>Remove {{ contextMenuTargetType === 'node' ? 'Node' : 'Connection' }}</span>\n </button>\n </div>\n }\n\n <!-- Status Bar -->\n @if (ShowStatusBar) {\n <mj-flow-status-bar\n [NodeCount]=\"Nodes.length\"\n [ConnectionCount]=\"Connections.length\"\n [SelectedCount]=\"selectedCount\"\n [ZoomLevel]=\"zoomLevel\">\n </mj-flow-status-bar>\n }\n</div>\n", styles: ["/* ============================================================\n Flow Editor \u2014 Main container styles\n ============================================================ */\n\n.mj-flow-editor {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-height: 400px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n outline: none;\n position: relative;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n}\n\n.mj-flow-editor--readonly .mj-flow-node-port {\n cursor: default;\n pointer-events: none;\n}\n\n/* \u2500\u2500 Toolbar Area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-toolbar-area {\n position: absolute;\n top: 10px;\n left: 50%;\n transform: translateX(-50%);\n z-index: 20;\n}\n\n/* \u2500\u2500 Canvas Area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-canvas-area {\n display: flex;\n flex: 1;\n overflow: hidden;\n position: relative;\n}\n\n.mj-flow-editor-canvas {\n flex: 1;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface);\n}\n\n.mj-flow-editor-canvas f-flow {\n width: 100%;\n height: 100%;\n}\n\n/* Pan mode \u2014 grab cursor, nodes pass through pointer events to canvas */\n.mj-flow-editor-canvas--pan-mode {\n cursor: grab;\n}\n\n.mj-flow-editor-canvas--pan-mode:active {\n cursor: grabbing;\n}\n\n.mj-flow-editor-canvas--pan-mode mj-flow-node {\n pointer-events: none;\n cursor: grab;\n}\n\n.mj-flow-editor-canvas--pan-mode f-connection {\n pointer-events: none;\n}\n\n.mj-flow-editor-canvas--pan-mode .mj-flow-connection-label {\n pointer-events: none;\n}\n\n/* \u2500\u2500 Minimap \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-minimap {\n position: absolute;\n bottom: 12px;\n right: 12px;\n width: 160px;\n height: 120px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n z-index: 15;\n}\n\n.mj-flow-editor-minimap f-minimap {\n width: 100%;\n height: 100%;\n}\n\n/* Foblex minimap SVG node rectangles (no default styles provided by Foblex) */\n.mj-flow-editor-minimap .f-minimap-node {\n fill: var(--mj-border-strong);\n stroke: var(--mj-text-disabled);\n stroke-width: 1;\n rx: 3;\n ry: 3;\n}\n\n.mj-flow-editor-minimap .f-minimap-node.f-selected {\n fill: color-mix(in srgb, var(--mj-brand-primary) 50%, var(--mj-bg-surface));\n stroke: var(--mj-brand-primary);\n stroke-width: 1.5;\n}\n\n.mj-flow-editor-minimap .f-minimap-group {\n fill: var(--mj-border-default);\n stroke: var(--mj-text-disabled);\n stroke-width: 0.5;\n rx: 2;\n ry: 2;\n}\n\n/* Viewport indicator rectangle */\n.mj-flow-editor-minimap .f-minimap-view {\n fill: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n stroke: var(--mj-brand-primary);\n stroke-width: 1.5;\n}\n\n/* \u2500\u2500 Empty State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-empty {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n z-index: 5;\n}\n\n.mj-flow-editor-empty-subtitle {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-disabled);\n margin: 0;\n}\n\n/* \u2500\u2500 Connection Labels \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-connection-label {\n display: inline-flex;\n align-items: flex-start;\n gap: 5px;\n background: var(--mj-bg-surface);\n border: 1.5px solid var(--mj-border-strong);\n border-radius: 5px;\n padding: 4px 10px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n box-shadow: var(--mj-shadow-sm);\n pointer-events: none;\n line-height: 1.4;\n text-align: center;\n}\n\n.mj-flow-connection-label-icon {\n font-size: 10px;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n/* \u2500\u2500 Foblex Overrides \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* Canvas \u2014 transparent so the grid pattern shows through */\nf-canvas {\n background: transparent;\n}\n\n/* Selection area */\nf-selection-area {\n --f-selection-area-background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n --f-selection-area-border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n/* Line alignment guides */\nf-line-alignment {\n --f-line-alignment-color: var(--mj-brand-primary);\n}\n\n/* Connection paths \u2014 default stroke color prevents invisible connections */\n.f-connection path {\n stroke: var(--mj-text-disabled);\n stroke-width: 2;\n fill: none;\n transition: stroke 0.15s ease, stroke-width 0.15s ease;\n}\n\n.f-connection:hover path {\n stroke-width: 3;\n}\n\n.f-connection.f-selected path {\n stroke: var(--mj-brand-primary);\n stroke-width: 3;\n}\n\n/* Colored connections use the --connection-color custom property,\n defaulting to neutral when no color is specified by the consumer */\n.mj-flow-connection-colored path {\n stroke: var(--connection-color, var(--mj-text-disabled));\n}\n\n.mj-flow-connection-colored.f-selected path {\n stroke: var(--connection-color, var(--mj-brand-primary));\n stroke-width: 3;\n filter: brightness(0.85);\n}\n\n/* Dashed connection style */\n.mj-flow-connection-dashed path {\n stroke-dasharray: 8 4;\n}\n\n/* Dotted connection style */\n.mj-flow-connection-dotted path {\n stroke-dasharray: 3 3;\n}\n\n/* Connection for create (dragging) */\n.f-connection-for-create path {\n stroke: var(--mj-text-disabled);\n stroke-dasharray: 6 3;\n stroke-width: 2;\n}\n\n/* \u2500\u2500 Legend \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-legend {\n position: absolute;\n bottom: 12px;\n left: 12px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n backdrop-filter: blur(6px);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 10px 14px;\n box-shadow: var(--mj-shadow-sm);\n z-index: 15;\n font-size: 11px;\n color: var(--mj-text-secondary);\n max-width: 200px;\n}\n\n.mj-flow-editor-legend-title {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 8px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.mj-flow-editor-legend-section {\n margin-bottom: 8px;\n}\n\n.mj-flow-editor-legend-section:last-child {\n margin-bottom: 0;\n}\n\n.mj-flow-editor-legend-heading {\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n margin-bottom: 4px;\n}\n\n.mj-flow-editor-legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 2px 0;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.mj-flow-editor-legend-svg,\n.mj-flow-editor-legend-line-svg {\n flex-shrink: 0;\n}\n\n.mj-flow-editor-legend-swatch {\n display: inline-block;\n width: 10px;\n height: 10px;\n border-radius: var(--mj-radius-sm);\n flex-shrink: 0;\n}\n\n.mj-flow-editor-legend-box {\n display: inline-block;\n width: 14px;\n height: 10px;\n border: 2px solid;\n border-radius: var(--mj-radius-sm);\n flex-shrink: 0;\n}\n\n/* \u2500\u2500 Context Menu \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-context-menu {\n position: fixed;\n min-width: 180px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-lg);\n padding: 4px;\n z-index: 9999;\n animation: mj-ctx-fade-in 0.1s ease-out;\n}\n\n@keyframes mj-ctx-fade-in {\n from { opacity: 0; transform: scale(0.95); }\n to { opacity: 1; transform: scale(1); }\n}\n\n.mj-flow-context-menu-item {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 8px 12px;\n border: none;\n background: none;\n font-size: var(--mj-text-sm);\n font-weight: 450;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 5px;\n text-align: left;\n transition: background-color 0.1s ease;\n}\n\n.mj-flow-context-menu-item:hover {\n background-color: var(--mj-bg-surface-sunken);\n}\n\n.mj-flow-context-menu-item i {\n width: 16px;\n text-align: center;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mj-flow-context-menu-item--danger {\n color: var(--mj-status-error);\n}\n\n.mj-flow-context-menu-item--danger:hover {\n background-color: var(--mj-status-error-subtle);\n}\n\n.mj-flow-context-menu-item--danger i {\n color: var(--mj-status-error);\n}\n\n.mj-flow-context-menu-divider {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 8px;\n}\n\n/* \u2500\u2500 Focus Indicators (Accessibility) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-toolbar-btn:focus-visible,\n.mj-agent-editor-btn:focus-visible,\n.mj-agent-editor-view-btn:focus-visible,\n.mj-agent-props-close:focus-visible,\n.mj-agent-props-delete-btn:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.mj-flow-palette-item:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 1px;\n border-radius: var(--mj-radius-md);\n}\n"] }]
1051
+ args: [{ standalone: false, selector: 'mj-flow-editor', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.Default, providers: [FlowStateService, FlowLayoutService], template: "<div class=\"mj-flow-editor\" [class.mj-flow-editor--readonly]=\"ReadOnly\" tabindex=\"0\">\n\n <!-- Canvas Toolbar -->\n @if (ShowToolbar) {\n <div class=\"mj-flow-editor-toolbar-area\">\n <mj-flow-toolbar\n [ZoomLevel]=\"zoomLevel\"\n [ShowGrid]=\"ShowGrid\"\n [ShowMinimap]=\"ShowMinimap\"\n [ShowLegend]=\"ShowLegend\"\n [ReadOnly]=\"ReadOnly\"\n [PanMode]=\"panMode\"\n (ZoomInClicked)=\"ZoomIn()\"\n (ZoomOutClicked)=\"ZoomOut()\"\n (FitToScreenClicked)=\"ZoomToFit()\"\n (AutoLayoutClicked)=\"AutoArrange()\"\n (GridToggled)=\"onGridToggled($event)\"\n (MinimapToggled)=\"onMinimapToggled($event)\"\n (LegendToggled)=\"onLegendToggled($event)\"\n (PanModeToggled)=\"onPanModeToggled($event)\">\n </mj-flow-toolbar>\n </div>\n }\n\n <!-- Main Canvas Area -->\n <div class=\"mj-flow-editor-canvas-area\">\n\n <!-- Palette Sidebar -->\n @if (ShowPalette && !ReadOnly) {\n <mj-flow-palette\n [NodeTypes]=\"NodeTypes\"\n (NodeTypeActivated)=\"onPaletteNodeTypeActivated($event)\">\n </mj-flow-palette>\n }\n\n <!-- Foblex Canvas -->\n <div class=\"mj-flow-editor-canvas\" #canvasArea\n [class.mj-flow-editor-canvas--pan-mode]=\"panMode\">\n <f-flow fDraggable\n [fDraggableDisabled]=\"false\"\n [fCanvasMoveTrigger]=\"canvasMoveTriggerFn\"\n [vCellSize]=\"GridSize\"\n [hCellSize]=\"GridSize\"\n [fCellSizeWhileDragging]=\"ShowGrid\"\n (fLoaded)=\"onFlowLoaded()\"\n (fCreateConnection)=\"onCreateConnection($event)\"\n (fReassignConnection)=\"onReassignConnection($event)\"\n (fCreateNode)=\"onCreateNode($event)\"\n (fSelectionChange)=\"onSelectionChange($event)\"\n (fMoveNodes)=\"onNodesMoved($event)\">\n\n <!-- Background grid \u2014 MUST be direct child of f-flow (Foblex content projection requires it) -->\n @if (ShowGrid) {\n <f-background>\n <f-circle-pattern [color]=\"'#94a3b8'\" [radius]=\"24\"></f-circle-pattern>\n </f-background>\n }\n\n <!-- Alignment snap lines \u2014 direct child of f-flow -->\n @if (!ReadOnly) {\n <f-line-alignment [fAlignThreshold]=\"10\"></f-line-alignment>\n }\n\n <f-canvas fZoom #fZoomRef=\"fComponent\"\n [fZoomMinimum]=\"0.15\"\n [fZoomMaximum]=\"3\"\n [fZoomStep]=\"0.1\"\n [position]=\"canvasPosition\"\n [scale]=\"canvasScale\"\n (fCanvasChange)=\"onCanvasChange($event)\">\n\n <!-- Interactive connection drawing -->\n @if (!ReadOnly) {\n <f-connection-for-create\n fType=\"bezier\"\n [fRadius]=\"8\"\n [fOffset]=\"12\">\n <svg viewBox=\"0 0 10 10\" fMarker type=\"end\"\n orient=\"auto\" [refX]=\"9\" [refY]=\"5\" [height]=\"10\" [width]=\"10\">\n <path d=\"M0 0L10 5L0 10Z\" fill=\"#94a3b8\"/>\n </svg>\n </f-connection-for-create>\n }\n\n <!-- Connections -->\n @for (conn of Connections; track trackConnectionById($index, conn)) {\n <f-connection\n [fConnectionId]=\"conn.ID\"\n [fOutputId]=\"conn.SourcePortID\"\n [fInputId]=\"conn.TargetPortID\"\n fType=\"bezier\"\n fBehavior=\"fixed\"\n [fRadius]=\"8\"\n [fOffset]=\"12\"\n [fSelectionDisabled]=\"false\"\n [fReassignDisabled]=\"ReadOnly\"\n [style.--connection-color]=\"conn.Color || '#94a3b8'\"\n [class.mj-flow-connection-colored]=\"!!conn.Color\"\n [class.mj-flow-connection-dashed]=\"conn.Style === 'dashed'\"\n [class.mj-flow-connection-dotted]=\"conn.Style === 'dotted'\"\n (click)=\"onConnectionClicked($event, conn)\"\n (contextmenu)=\"onConnectionContextMenu($event, conn)\">\n <!-- Arrow marker -->\n <svg viewBox=\"0 0 10 10\" fMarker type=\"end\"\n orient=\"auto\" [refX]=\"9\" [refY]=\"5\" [height]=\"10\" [width]=\"10\">\n <path d=\"M0 0L10 5L0 10Z\" [attr.fill]=\"conn.Color || '#94a3b8'\"/>\n </svg>\n <!-- Connection label -->\n @if (conn.Label) {\n <div fConnectionContent [position]=\"0.5\"\n class=\"mj-flow-connection-label\"\n [style.backgroundColor]=\"ConnectionLabelBackground\"\n [style.borderColor]=\"ConnectionLabelBorderColor\"\n [style.color]=\"ConnectionLabelTextColor\"\n [title]=\"conn.LabelDetail || conn.Label || ''\">\n @if (conn.LabelIcon) {\n <i\n class=\"fa-solid mj-flow-connection-label-icon\"\n [ngClass]=\"conn.LabelIcon\"\n [style.color]=\"conn.LabelIconColor || 'inherit'\"></i>\n }\n {{ conn.Label }}\n </div>\n }\n </f-connection>\n }\n\n <!-- Nodes -->\n @for (node of Nodes; track trackNodeById($index, node)) {\n <mj-flow-node\n fNode\n fDragHandle\n [fNodeId]=\"node.ID\"\n [fNodePosition]=\"{ x: node.Position.X, y: node.Position.Y }\"\n [fNodeDraggingDisabled]=\"ReadOnly || panMode || node.Locked === true\"\n [fNodeSelectionDisabled]=\"panMode\"\n [fConnectOnNode]=\"!ReadOnly && !panMode\"\n [Node]=\"node\"\n [TypeConfig]=\"GetTypeConfig(node.Type)\"\n [ReadOnly]=\"ReadOnly\"\n (contextmenu)=\"onNodeContextMenu($event, node)\">\n </mj-flow-node>\n }\n\n </f-canvas>\n\n <!-- Rubber-band selection \u2014 direct child of f-flow -->\n @if (!ReadOnly) {\n <f-selection-area></f-selection-area>\n }\n\n <!-- Minimap -->\n @if (ShowMinimap) {\n <div class=\"mj-flow-editor-minimap\" fDragBlocker>\n <f-minimap [fMinSize]=\"1500\"></f-minimap>\n </div>\n }\n </f-flow>\n\n <!-- Legend -->\n @if (ShowLegend && Nodes.length > 0) {\n <div class=\"mj-flow-editor-legend\">\n <div class=\"mj-flow-editor-legend-title\">Legend</div>\n <div class=\"mj-flow-editor-legend-section\">\n <div class=\"mj-flow-editor-legend-heading\">Connections</div>\n <div class=\"mj-flow-editor-legend-item\">\n <svg class=\"mj-flow-editor-legend-line-svg\" width=\"28\" height=\"10\"><line x1=\"0\" y1=\"5\" x2=\"28\" y2=\"5\" stroke=\"#64748b\" stroke-width=\"2\"/></svg>\n <span>Only exit path</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <svg class=\"mj-flow-editor-legend-line-svg\" width=\"28\" height=\"10\"><line x1=\"0\" y1=\"5\" x2=\"28\" y2=\"5\" stroke=\"#16a34a\" stroke-width=\"2\"/></svg>\n <i class=\"fa-solid fa-circle-check\" style=\"color:#16a34a;font-size:10px;\"></i>\n <span>Default (fallback)</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <svg class=\"mj-flow-editor-legend-line-svg\" width=\"28\" height=\"10\"><line x1=\"0\" y1=\"5\" x2=\"28\" y2=\"5\" stroke=\"#f59e0b\" stroke-width=\"2\" stroke-dasharray=\"5 3\"/></svg>\n <span>Conditional</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <svg class=\"mj-flow-editor-legend-line-svg\" width=\"28\" height=\"10\"><line x1=\"0\" y1=\"5\" x2=\"28\" y2=\"5\" stroke=\"#ef4444\" stroke-width=\"2\"/></svg>\n <i class=\"fa-solid fa-triangle-exclamation\" style=\"color:#ef4444;font-size:10px;\"></i>\n <span>Duplicate defaults</span>\n </div>\n </div>\n <div class=\"mj-flow-editor-legend-section\">\n <div class=\"mj-flow-editor-legend-heading\">Step Types</div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#3B82F6\"></span>\n <span>Action</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#8B5CF6\"></span>\n <span>Prompt</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#10B981\"></span>\n <span>Sub-Agent</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#F59E0B\"></span>\n <span>For Each</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#F97316\"></span>\n <span>While</span>\n </div>\n </div>\n <div class=\"mj-flow-editor-legend-section\">\n <div class=\"mj-flow-editor-legend-heading\">Borders</div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-box\" style=\"border-color:#16a34a;background:#f0fdf4;\"></span>\n <span>Start node</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-box\" style=\"border-color:#ef4444;background:#fef2f2;\"></span>\n <i class=\"fa-solid fa-triangle-exclamation\" style=\"color:#ea580c;font-size:10px;\"></i>\n <span>Missing config</span>\n </div>\n </div>\n </div>\n }\n\n <!-- Empty state overlay -->\n @if (Nodes.length === 0) {\n <div class=\"mj-flow-editor-empty\">\n <mj-empty-state\n Icon=\"fa-solid fa-diagram-project\"\n [Title]=\"EmptyStateTitle\">\n @if (!ReadOnly) {\n <p class=\"mj-flow-editor-empty-subtitle\">\n Or use auto-layout after adding steps to arrange them automatically\n </p>\n }\n </mj-empty-state>\n </div>\n }\n </div>\n </div>\n\n <!-- Context Menu -->\n @if (contextMenuVisible) {\n <div\n class=\"mj-flow-context-menu\"\n [style.left.px]=\"contextMenuX\"\n [style.top.px]=\"contextMenuY\"\n (click)=\"$event.stopPropagation()\">\n <button class=\"mj-flow-context-menu-item\" (click)=\"onContextMenuAction('edit')\">\n <i class=\"fa-solid fa-pen-to-square\"></i>\n <span>Edit {{ contextMenuTargetType === 'node' ? 'Node' : 'Connection' }}</span>\n </button>\n <div class=\"mj-flow-context-menu-divider\"></div>\n <button class=\"mj-flow-context-menu-item mj-flow-context-menu-item--danger\" (click)=\"onContextMenuAction('remove')\">\n <i class=\"fa-solid fa-trash-can\"></i>\n <span>Remove {{ contextMenuTargetType === 'node' ? 'Node' : 'Connection' }}</span>\n </button>\n </div>\n }\n\n <!-- Status Bar -->\n @if (ShowStatusBar) {\n <mj-flow-status-bar\n [NodeCount]=\"Nodes.length\"\n [ConnectionCount]=\"Connections.length\"\n [SelectedCount]=\"selectedCount\"\n [ZoomLevel]=\"zoomLevel\">\n </mj-flow-status-bar>\n }\n</div>\n", styles: ["/* ============================================================\n Flow Editor \u2014 Main container styles\n ============================================================ */\n\n.mj-flow-editor {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-height: 400px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n outline: none;\n position: relative;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n}\n\n.mj-flow-editor--readonly .mj-flow-node-port {\n cursor: default;\n pointer-events: none;\n}\n\n/* \u2500\u2500 Toolbar Area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-toolbar-area {\n position: absolute;\n top: 10px;\n left: 50%;\n transform: translateX(-50%);\n z-index: 20;\n}\n\n/* \u2500\u2500 Canvas Area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-canvas-area {\n display: flex;\n flex: 1;\n overflow: hidden;\n position: relative;\n}\n\n.mj-flow-editor-canvas {\n flex: 1;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface);\n}\n\n.mj-flow-editor-canvas f-flow {\n width: 100%;\n height: 100%;\n}\n\n/* Pan mode \u2014 grab cursor, nodes pass through pointer events to canvas */\n.mj-flow-editor-canvas--pan-mode {\n cursor: grab;\n}\n\n.mj-flow-editor-canvas--pan-mode:active {\n cursor: grabbing;\n}\n\n.mj-flow-editor-canvas--pan-mode mj-flow-node {\n pointer-events: none;\n cursor: grab;\n}\n\n.mj-flow-editor-canvas--pan-mode f-connection {\n pointer-events: none;\n}\n\n.mj-flow-editor-canvas--pan-mode .mj-flow-connection-label {\n pointer-events: none;\n}\n\n/* \u2500\u2500 Minimap \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-minimap {\n position: absolute;\n bottom: 12px;\n right: 12px;\n width: 160px;\n height: 120px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n z-index: 15;\n}\n\n.mj-flow-editor-minimap f-minimap {\n width: 100%;\n height: 100%;\n}\n\n/* Foblex minimap SVG node rectangles (no default styles provided by Foblex) */\n.mj-flow-editor-minimap .f-minimap-node {\n fill: var(--mj-border-strong);\n stroke: var(--mj-text-disabled);\n stroke-width: 1;\n rx: 3;\n ry: 3;\n}\n\n.mj-flow-editor-minimap .f-minimap-node.f-selected {\n fill: color-mix(in srgb, var(--mj-brand-primary) 50%, var(--mj-bg-surface));\n stroke: var(--mj-brand-primary);\n stroke-width: 1.5;\n}\n\n.mj-flow-editor-minimap .f-minimap-group {\n fill: var(--mj-border-default);\n stroke: var(--mj-text-disabled);\n stroke-width: 0.5;\n rx: 2;\n ry: 2;\n}\n\n/* Viewport indicator rectangle */\n.mj-flow-editor-minimap .f-minimap-view {\n fill: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n stroke: var(--mj-brand-primary);\n stroke-width: 1.5;\n}\n\n/* \u2500\u2500 Empty State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-empty {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n z-index: 5;\n}\n\n.mj-flow-editor-empty-subtitle {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-disabled);\n margin: 0;\n}\n\n/* \u2500\u2500 Connection Labels \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-connection-label {\n display: inline-flex;\n align-items: flex-start;\n gap: 5px;\n background: var(--mj-bg-surface);\n border: 1.5px solid var(--mj-border-strong);\n border-radius: 5px;\n padding: 4px 10px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n box-shadow: var(--mj-shadow-sm);\n pointer-events: none;\n line-height: 1.4;\n text-align: center;\n}\n\n.mj-flow-connection-label-icon {\n font-size: 10px;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n/* \u2500\u2500 Foblex Overrides \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* Canvas \u2014 transparent so the grid pattern shows through */\nf-canvas {\n background: transparent;\n}\n\n/* Selection area */\nf-selection-area {\n --f-selection-area-background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n --f-selection-area-border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n/* Line alignment guides */\nf-line-alignment {\n --f-line-alignment-color: var(--mj-brand-primary);\n}\n\n/* Connection paths \u2014 default stroke color prevents invisible connections */\n.f-connection path {\n stroke: var(--mj-text-disabled);\n stroke-width: 2;\n fill: none;\n transition: stroke 0.15s ease, stroke-width 0.15s ease;\n}\n\n.f-connection:hover path {\n stroke-width: 3;\n}\n\n.f-connection.f-selected path {\n stroke: var(--mj-brand-primary);\n stroke-width: 3;\n}\n\n/* Colored connections use the --connection-color custom property,\n defaulting to neutral when no color is specified by the consumer */\n.mj-flow-connection-colored path {\n stroke: var(--connection-color, var(--mj-text-disabled));\n}\n\n.mj-flow-connection-colored.f-selected path {\n stroke: var(--connection-color, var(--mj-brand-primary));\n stroke-width: 3;\n filter: brightness(0.85);\n}\n\n/* Dashed connection style */\n.mj-flow-connection-dashed path {\n stroke-dasharray: 8 4;\n}\n\n/* Dotted connection style */\n.mj-flow-connection-dotted path {\n stroke-dasharray: 3 3;\n}\n\n/* Connection for create (dragging) */\n.f-connection-for-create path {\n stroke: var(--mj-text-disabled);\n stroke-dasharray: 6 3;\n stroke-width: 2;\n}\n\n/* \u2500\u2500 Legend \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-legend {\n position: absolute;\n bottom: 12px;\n left: 12px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n backdrop-filter: blur(6px);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 10px 14px;\n box-shadow: var(--mj-shadow-sm);\n z-index: 15;\n font-size: 11px;\n color: var(--mj-text-secondary);\n max-width: 200px;\n}\n\n.mj-flow-editor-legend-title {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 8px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.mj-flow-editor-legend-section {\n margin-bottom: 8px;\n}\n\n.mj-flow-editor-legend-section:last-child {\n margin-bottom: 0;\n}\n\n.mj-flow-editor-legend-heading {\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n margin-bottom: 4px;\n}\n\n.mj-flow-editor-legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 2px 0;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.mj-flow-editor-legend-svg,\n.mj-flow-editor-legend-line-svg {\n flex-shrink: 0;\n}\n\n.mj-flow-editor-legend-swatch {\n display: inline-block;\n width: 10px;\n height: 10px;\n border-radius: var(--mj-radius-sm);\n flex-shrink: 0;\n}\n\n.mj-flow-editor-legend-box {\n display: inline-block;\n width: 14px;\n height: 10px;\n border: 2px solid;\n border-radius: var(--mj-radius-sm);\n flex-shrink: 0;\n}\n\n/* \u2500\u2500 Context Menu \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-context-menu {\n position: fixed;\n min-width: 180px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-lg);\n padding: 4px;\n z-index: 9999;\n animation: mj-ctx-fade-in 0.1s ease-out;\n}\n\n@keyframes mj-ctx-fade-in {\n from { opacity: 0; transform: scale(0.95); }\n to { opacity: 1; transform: scale(1); }\n}\n\n.mj-flow-context-menu-item {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 8px 12px;\n border: none;\n background: none;\n font-size: var(--mj-text-sm);\n font-weight: 450;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 5px;\n text-align: left;\n transition: background-color 0.1s ease;\n}\n\n.mj-flow-context-menu-item:hover {\n background-color: var(--mj-bg-surface-sunken);\n}\n\n.mj-flow-context-menu-item i {\n width: 16px;\n text-align: center;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mj-flow-context-menu-item--danger {\n color: var(--mj-status-error);\n}\n\n.mj-flow-context-menu-item--danger:hover {\n background-color: var(--mj-status-error-subtle);\n}\n\n.mj-flow-context-menu-item--danger i {\n color: var(--mj-status-error);\n}\n\n.mj-flow-context-menu-divider {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 8px;\n}\n\n/* \u2500\u2500 Focus Indicators (Accessibility) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-toolbar-btn:focus-visible,\n.mj-agent-editor-btn:focus-visible,\n.mj-agent-editor-view-btn:focus-visible,\n.mj-agent-props-close:focus-visible,\n.mj-agent-props-delete-btn:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.mj-flow-palette-item:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 1px;\n border-radius: var(--mj-radius-md);\n}\n"] }]
1002
1052
  }], () => [{ type: i0.ChangeDetectorRef }, { type: i1.FlowStateService }, { type: i2.FlowLayoutService }], { Nodes: [{
1003
1053
  type: Input
1004
1054
  }], Connections: [{
@@ -1072,6 +1122,9 @@ export class FlowEditorComponent {
1072
1122
  }], fZoom: [{
1073
1123
  type: ViewChild,
1074
1124
  args: ['fZoomRef']
1125
+ }], canvasArea: [{
1126
+ type: ViewChild,
1127
+ args: ['canvasArea']
1075
1128
  }], onDocumentClick: [{
1076
1129
  type: HostListener,
1077
1130
  args: ['document:click']