@memberjunction/ng-task-graph-editor 0.0.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.
Files changed (35) hide show
  1. package/LICENSE +7 -0
  2. package/dist/lib/task-graph-canvas-adapter.d.ts +195 -0
  3. package/dist/lib/task-graph-canvas-adapter.d.ts.map +1 -0
  4. package/dist/lib/task-graph-canvas-adapter.js +380 -0
  5. package/dist/lib/task-graph-canvas-adapter.js.map +1 -0
  6. package/dist/lib/task-graph-editor-events.d.ts +137 -0
  7. package/dist/lib/task-graph-editor-events.d.ts.map +1 -0
  8. package/dist/lib/task-graph-editor-events.js +180 -0
  9. package/dist/lib/task-graph-editor-events.js.map +1 -0
  10. package/dist/lib/task-graph-editor.component.d.ts +230 -0
  11. package/dist/lib/task-graph-editor.component.d.ts.map +1 -0
  12. package/dist/lib/task-graph-editor.component.js +597 -0
  13. package/dist/lib/task-graph-editor.component.js.map +1 -0
  14. package/dist/lib/task-graph-editor.module.d.ts +14 -0
  15. package/dist/lib/task-graph-editor.module.d.ts.map +1 -0
  16. package/dist/lib/task-graph-editor.module.js +24 -0
  17. package/dist/lib/task-graph-editor.module.js.map +1 -0
  18. package/dist/lib/task-graph-properties-panel.component.d.ts +97 -0
  19. package/dist/lib/task-graph-properties-panel.component.d.ts.map +1 -0
  20. package/dist/lib/task-graph-properties-panel.component.js +357 -0
  21. package/dist/lib/task-graph-properties-panel.component.js.map +1 -0
  22. package/dist/lib/task-graph-run-view.component.d.ts +113 -0
  23. package/dist/lib/task-graph-run-view.component.d.ts.map +1 -0
  24. package/dist/lib/task-graph-run-view.component.js +289 -0
  25. package/dist/lib/task-graph-run-view.component.js.map +1 -0
  26. package/dist/lib/task-graph-runtime-source.d.ts +55 -0
  27. package/dist/lib/task-graph-runtime-source.d.ts.map +1 -0
  28. package/dist/lib/task-graph-runtime-source.js +66 -0
  29. package/dist/lib/task-graph-runtime-source.js.map +1 -0
  30. package/dist/public-api.d.ts +8 -0
  31. package/dist/public-api.d.ts.map +1 -0
  32. package/dist/public-api.js +16 -0
  33. package/dist/public-api.js.map +1 -0
  34. package/package.json +53 -7
  35. package/README.md +0 -45
@@ -0,0 +1,357 @@
1
+ /**
2
+ * @fileoverview Edits the selected task's properties, plus the graph-level traversal settings.
3
+ *
4
+ * Split out of the canvas component for the reason panels usually are — the canvas is about
5
+ * *structure* (what connects to what) and this is about *content* (what a step actually does). But
6
+ * also for a sharper reason: a host embedding the read-only viewer in a chat card or a run history
7
+ * pane wants the graph without a form beside it, and a panel welded into the canvas cannot be
8
+ * declined.
9
+ *
10
+ * Emits intent rather than mutating: the canvas component owns the spec, so every edit here leaves
11
+ * as a request the parent applies through the same `Before*`/`After*` path a drag or a delete takes.
12
+ * Two write paths into one spec would be two places for the veto contract to be wrong.
13
+ *
14
+ * @module @memberjunction/ng-task-graph-editor
15
+ */
16
+ import { Component, EventEmitter, Input, Output } from '@angular/core';
17
+ import { ConfigOf, TaskNode } from '@memberjunction/ai-core-plus';
18
+ import { GetDependencies, GetTaskNodeType, IsAuthorableNodeType } from './task-graph-canvas-adapter';
19
+ import * as i0 from "@angular/core";
20
+ import * as i1 from "@angular/forms";
21
+ import * as i2 from "@memberjunction/ng-ui-components";
22
+ const _forTrack0 = ($index, $item) => $item.FromTempId;
23
+ function TaskGraphPropertiesPanelComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
24
+ i0.ɵɵelement(0, "mj-empty-state", 1);
25
+ } }
26
+ function TaskGraphPropertiesPanelComponent_Conditional_2_Case_18_Conditional_0_For_2_Template(rf, ctx) { if (rf & 1) {
27
+ i0.ɵɵelementStart(0, "option", 16);
28
+ i0.ɵɵtext(1);
29
+ i0.ɵɵelementEnd();
30
+ } if (rf & 2) {
31
+ const name_r4 = ctx.$implicit;
32
+ i0.ɵɵproperty("value", name_r4);
33
+ i0.ɵɵadvance();
34
+ i0.ɵɵtextInterpolate(name_r4);
35
+ } }
36
+ function TaskGraphPropertiesPanelComponent_Conditional_2_Case_18_Conditional_0_Template(rf, ctx) { if (rf & 1) {
37
+ const _r3 = i0.ɵɵgetCurrentView();
38
+ i0.ɵɵelementStart(0, "select", 15);
39
+ i0.ɵɵtwoWayListener("ngModelChange", function TaskGraphPropertiesPanelComponent_Conditional_2_Case_18_Conditional_0_Template_select_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.AgentName, $event) || (ctx_r1.AgentName = $event); return i0.ɵɵresetView($event); });
40
+ i0.ɵɵlistener("change", function TaskGraphPropertiesPanelComponent_Conditional_2_Case_18_Conditional_0_Template_select_change_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.Commit()); });
41
+ i0.ɵɵrepeaterCreate(1, TaskGraphPropertiesPanelComponent_Conditional_2_Case_18_Conditional_0_For_2_Template, 2, 2, "option", 16, i0.ɵɵrepeaterTrackByIdentity);
42
+ i0.ɵɵelementEnd();
43
+ } if (rf & 2) {
44
+ const ctx_r1 = i0.ɵɵnextContext(3);
45
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r1.AgentName);
46
+ i0.ɵɵproperty("disabled", ctx_r1.ReadOnly);
47
+ i0.ɵɵadvance();
48
+ i0.ɵɵrepeater(ctx_r1.AvailableAgentNames);
49
+ } }
50
+ function TaskGraphPropertiesPanelComponent_Conditional_2_Case_18_Conditional_1_Template(rf, ctx) { if (rf & 1) {
51
+ i0.ɵɵelement(0, "mj-alert", 14);
52
+ } }
53
+ function TaskGraphPropertiesPanelComponent_Conditional_2_Case_18_Template(rf, ctx) { if (rf & 1) {
54
+ i0.ɵɵconditionalCreate(0, TaskGraphPropertiesPanelComponent_Conditional_2_Case_18_Conditional_0_Template, 3, 2, "select", 13)(1, TaskGraphPropertiesPanelComponent_Conditional_2_Case_18_Conditional_1_Template, 1, 0, "mj-alert", 14);
55
+ } if (rf & 2) {
56
+ const ctx_r1 = i0.ɵɵnextContext(2);
57
+ i0.ɵɵconditional(ctx_r1.AvailableAgentNames.length > 0 ? 0 : 1);
58
+ } }
59
+ function TaskGraphPropertiesPanelComponent_Conditional_2_Case_19_Conditional_0_For_2_Template(rf, ctx) { if (rf & 1) {
60
+ i0.ɵɵelementStart(0, "option", 16);
61
+ i0.ɵɵtext(1);
62
+ i0.ɵɵelementEnd();
63
+ } if (rf & 2) {
64
+ const name_r6 = ctx.$implicit;
65
+ i0.ɵɵproperty("value", name_r6);
66
+ i0.ɵɵadvance();
67
+ i0.ɵɵtextInterpolate(name_r6);
68
+ } }
69
+ function TaskGraphPropertiesPanelComponent_Conditional_2_Case_19_Conditional_0_Template(rf, ctx) { if (rf & 1) {
70
+ const _r5 = i0.ɵɵgetCurrentView();
71
+ i0.ɵɵelementStart(0, "select", 19);
72
+ i0.ɵɵtwoWayListener("ngModelChange", function TaskGraphPropertiesPanelComponent_Conditional_2_Case_19_Conditional_0_Template_select_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.ActionName, $event) || (ctx_r1.ActionName = $event); return i0.ɵɵresetView($event); });
73
+ i0.ɵɵlistener("change", function TaskGraphPropertiesPanelComponent_Conditional_2_Case_19_Conditional_0_Template_select_change_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.Commit()); });
74
+ i0.ɵɵrepeaterCreate(1, TaskGraphPropertiesPanelComponent_Conditional_2_Case_19_Conditional_0_For_2_Template, 2, 2, "option", 16, i0.ɵɵrepeaterTrackByIdentity);
75
+ i0.ɵɵelementEnd();
76
+ } if (rf & 2) {
77
+ const ctx_r1 = i0.ɵɵnextContext(3);
78
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r1.ActionName);
79
+ i0.ɵɵproperty("disabled", ctx_r1.ReadOnly);
80
+ i0.ɵɵadvance();
81
+ i0.ɵɵrepeater(ctx_r1.AvailableActionNames);
82
+ } }
83
+ function TaskGraphPropertiesPanelComponent_Conditional_2_Case_19_Conditional_1_Template(rf, ctx) { if (rf & 1) {
84
+ i0.ɵɵelement(0, "mj-alert", 18);
85
+ } }
86
+ function TaskGraphPropertiesPanelComponent_Conditional_2_Case_19_Template(rf, ctx) { if (rf & 1) {
87
+ i0.ɵɵconditionalCreate(0, TaskGraphPropertiesPanelComponent_Conditional_2_Case_19_Conditional_0_Template, 3, 2, "select", 17)(1, TaskGraphPropertiesPanelComponent_Conditional_2_Case_19_Conditional_1_Template, 1, 0, "mj-alert", 18);
88
+ } if (rf & 2) {
89
+ const ctx_r1 = i0.ɵɵnextContext(2);
90
+ i0.ɵɵconditional(ctx_r1.AvailableActionNames.length > 0 ? 0 : 1);
91
+ } }
92
+ function TaskGraphPropertiesPanelComponent_Conditional_2_Case_20_Template(rf, ctx) { if (rf & 1) {
93
+ i0.ɵɵelement(0, "mj-alert", 12);
94
+ } }
95
+ function TaskGraphPropertiesPanelComponent_Conditional_2_Conditional_21_For_3_Template(rf, ctx) { if (rf & 1) {
96
+ const _r7 = i0.ɵɵgetCurrentView();
97
+ i0.ɵɵelementStart(0, "div", 20)(1, "span", 21);
98
+ i0.ɵɵelement(2, "i", 22);
99
+ i0.ɵɵtext(3);
100
+ i0.ɵɵelementEnd();
101
+ i0.ɵɵelementStart(4, "input", 23);
102
+ i0.ɵɵlistener("blur", function TaskGraphPropertiesPanelComponent_Conditional_2_Conditional_21_For_3_Template_input_blur_4_listener($event) { const edge_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.CommitCondition(edge_r8.FromTempId, $event.target.value)); });
103
+ i0.ɵɵelementEnd()();
104
+ } if (rf & 2) {
105
+ const edge_r8 = ctx.$implicit;
106
+ const ctx_r1 = i0.ɵɵnextContext(3);
107
+ i0.ɵɵadvance(3);
108
+ i0.ɵɵtextInterpolate1(" ", edge_r8.FromName);
109
+ i0.ɵɵadvance();
110
+ i0.ɵɵproperty("ngModel", edge_r8.Condition)("disabled", ctx_r1.ReadOnly);
111
+ } }
112
+ function TaskGraphPropertiesPanelComponent_Conditional_2_Conditional_21_Template(rf, ctx) { if (rf & 1) {
113
+ i0.ɵɵelementStart(0, "label", 6);
114
+ i0.ɵɵtext(1, "Runs after");
115
+ i0.ɵɵelementEnd();
116
+ i0.ɵɵrepeaterCreate(2, TaskGraphPropertiesPanelComponent_Conditional_2_Conditional_21_For_3_Template, 5, 3, "div", 20, _forTrack0);
117
+ } if (rf & 2) {
118
+ const ctx_r1 = i0.ɵɵnextContext(2);
119
+ i0.ɵɵadvance(2);
120
+ i0.ɵɵrepeater(ctx_r1.IncomingEdges);
121
+ } }
122
+ function TaskGraphPropertiesPanelComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
123
+ const _r1 = i0.ɵɵgetCurrentView();
124
+ i0.ɵɵelementStart(0, "label", 2);
125
+ i0.ɵɵtext(1, "Name");
126
+ i0.ɵɵelementEnd();
127
+ i0.ɵɵelementStart(2, "input", 3);
128
+ i0.ɵɵtwoWayListener("ngModelChange", function TaskGraphPropertiesPanelComponent_Conditional_2_Template_input_ngModelChange_2_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.Draft.name, $event) || (ctx_r1.Draft.name = $event); return i0.ɵɵresetView($event); });
129
+ i0.ɵɵlistener("blur", function TaskGraphPropertiesPanelComponent_Conditional_2_Template_input_blur_2_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Commit()); });
130
+ i0.ɵɵelementEnd();
131
+ i0.ɵɵelementStart(3, "label", 4);
132
+ i0.ɵɵtext(4, "What this step does");
133
+ i0.ɵɵelementEnd();
134
+ i0.ɵɵelementStart(5, "textarea", 5);
135
+ i0.ɵɵtwoWayListener("ngModelChange", function TaskGraphPropertiesPanelComponent_Conditional_2_Template_textarea_ngModelChange_5_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.Draft.description, $event) || (ctx_r1.Draft.description = $event); return i0.ɵɵresetView($event); });
136
+ i0.ɵɵlistener("blur", function TaskGraphPropertiesPanelComponent_Conditional_2_Template_textarea_blur_5_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Commit()); });
137
+ i0.ɵɵelementEnd();
138
+ i0.ɵɵelementStart(6, "label", 6);
139
+ i0.ɵɵtext(7, "Who does it");
140
+ i0.ɵɵelementEnd();
141
+ i0.ɵɵelementStart(8, "div", 7)(9, "button", 8);
142
+ i0.ɵɵlistener("click", function TaskGraphPropertiesPanelComponent_Conditional_2_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.SetAssignment("AgentTask")); });
143
+ i0.ɵɵelement(10, "i", 9);
144
+ i0.ɵɵtext(11, " An agent ");
145
+ i0.ɵɵelementEnd();
146
+ i0.ɵɵelementStart(12, "button", 8);
147
+ i0.ɵɵlistener("click", function TaskGraphPropertiesPanelComponent_Conditional_2_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.SetAssignment("ActionTask")); });
148
+ i0.ɵɵelement(13, "i", 10);
149
+ i0.ɵɵtext(14, " An action ");
150
+ i0.ɵɵelementEnd();
151
+ i0.ɵɵelementStart(15, "button", 8);
152
+ i0.ɵɵlistener("click", function TaskGraphPropertiesPanelComponent_Conditional_2_Template_button_click_15_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.SetAssignment("HumanTask")); });
153
+ i0.ɵɵelement(16, "i", 11);
154
+ i0.ɵɵtext(17, " A person ");
155
+ i0.ɵɵelementEnd()();
156
+ i0.ɵɵconditionalCreate(18, TaskGraphPropertiesPanelComponent_Conditional_2_Case_18_Template, 2, 1)(19, TaskGraphPropertiesPanelComponent_Conditional_2_Case_19_Template, 2, 1)(20, TaskGraphPropertiesPanelComponent_Conditional_2_Case_20_Template, 1, 0, "mj-alert", 12);
157
+ i0.ɵɵconditionalCreate(21, TaskGraphPropertiesPanelComponent_Conditional_2_Conditional_21_Template, 4, 0);
158
+ } if (rf & 2) {
159
+ let tmp_11_0;
160
+ const ctx_r1 = i0.ɵɵnextContext();
161
+ i0.ɵɵadvance(2);
162
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r1.Draft.name);
163
+ i0.ɵɵproperty("disabled", ctx_r1.ReadOnly);
164
+ i0.ɵɵadvance(3);
165
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r1.Draft.description);
166
+ i0.ɵɵproperty("disabled", ctx_r1.ReadOnly);
167
+ i0.ɵɵadvance(4);
168
+ i0.ɵɵproperty("variant", ctx_r1.Assignment === "AgentTask" ? "primary" : "outline")("disabled", ctx_r1.ReadOnly);
169
+ i0.ɵɵadvance(3);
170
+ i0.ɵɵproperty("variant", ctx_r1.Assignment === "ActionTask" ? "primary" : "outline")("disabled", ctx_r1.ReadOnly);
171
+ i0.ɵɵadvance(3);
172
+ i0.ɵɵproperty("variant", ctx_r1.Assignment === "HumanTask" ? "primary" : "outline")("disabled", ctx_r1.ReadOnly);
173
+ i0.ɵɵadvance(3);
174
+ i0.ɵɵconditional((tmp_11_0 = ctx_r1.Assignment) === "AgentTask" ? 18 : tmp_11_0 === "ActionTask" ? 19 : 20);
175
+ i0.ɵɵadvance(3);
176
+ i0.ɵɵconditional(ctx_r1.IncomingEdges.length > 0 ? 21 : -1);
177
+ } }
178
+ /** A requested change to one task. The parent applies it; this panel never writes. */
179
+ export class TaskPropertyChangeRequestedEventArgs {
180
+ TempId;
181
+ Next;
182
+ constructor(TempId, Next) {
183
+ this.TempId = TempId;
184
+ this.Next = Next;
185
+ }
186
+ }
187
+ /** A requested change to a dependency edge's condition. */
188
+ export class DependencyConditionChangeRequestedEventArgs {
189
+ FromTempId;
190
+ ToTempId;
191
+ Condition;
192
+ constructor(FromTempId, ToTempId,
193
+ /** Empty string clears the condition, making the edge unconditional again. */
194
+ Condition) {
195
+ this.FromTempId = FromTempId;
196
+ this.ToTempId = ToTempId;
197
+ this.Condition = Condition;
198
+ }
199
+ }
200
+ export class TaskGraphPropertiesPanelComponent {
201
+ /** The task being edited. Null shows the empty state rather than a form bound to nothing. */
202
+ set Task(value) {
203
+ this.currentTask = value;
204
+ // A working copy, so a half-typed name never reaches the spec — and so Cancel is possible
205
+ // at all. Editing the live node would make every keystroke an unvetoable mutation.
206
+ this.Draft = value ? { ...value } : null;
207
+ }
208
+ get Task() {
209
+ return this.currentTask;
210
+ }
211
+ /** The whole graph, for resolving the selected task's incoming edges. */
212
+ Spec = null;
213
+ /** Agent names offered in the assignment dropdown. Supplied by the host, which owns data access. */
214
+ AvailableAgentNames = [];
215
+ /** Action names offered in the assignment dropdown. Same ownership rule as `AvailableAgentNames`. */
216
+ AvailableActionNames = [];
217
+ ReadOnly = false;
218
+ TaskPropertyChangeRequested = new EventEmitter();
219
+ DependencyConditionChangeRequested = new EventEmitter();
220
+ Draft = null;
221
+ currentTask = null;
222
+ /**
223
+ * Which of the three assignment shapes this step currently uses.
224
+ *
225
+ * Derived from the draft rather than stored separately: the node's own `kind` is the single
226
+ * source of truth, and a parallel field could disagree with it.
227
+ */
228
+ get Assignment() {
229
+ if (!this.Draft)
230
+ return 'AgentTask';
231
+ const type = GetTaskNodeType(this.Draft);
232
+ // This panel edits the three authorable shapes. A display-only kind (a Prompt, a loop, an
233
+ // external step — kinds a run can contain but nobody draws here) has no editor, so it falls
234
+ // back rather than being mis-presented as an agent step with an agent picker.
235
+ return IsAuthorableNodeType(type) ? type : 'AgentTask';
236
+ }
237
+ /**
238
+ * The chosen agent, read and written through the node's configuration.
239
+ *
240
+ * A template cannot narrow a discriminated union, so the two-way binding goes through here
241
+ * rather than at `Draft.configuration.agentName` — which would also be wrong the moment the
242
+ * draft is a different kind.
243
+ */
244
+ get AgentName() {
245
+ return ConfigOf(this.Draft, 'Agent')?.agentName ?? '';
246
+ }
247
+ set AgentName(value) {
248
+ if (this.Draft?.kind === 'Agent') {
249
+ this.Draft = { ...this.Draft, configuration: { ...ConfigOf(this.Draft, 'Agent'), agentName: value } };
250
+ }
251
+ }
252
+ /** The chosen action. Same reasoning as {@link AgentName}. */
253
+ get ActionName() {
254
+ return ConfigOf(this.Draft, 'Action')?.actionName ?? '';
255
+ }
256
+ set ActionName(value) {
257
+ if (this.Draft?.kind === 'Action') {
258
+ this.Draft = { ...this.Draft, configuration: { ...ConfigOf(this.Draft, 'Action'), actionName: value } };
259
+ }
260
+ }
261
+ /** True when this step waits on a person. */
262
+ get IsHumanTask() {
263
+ return this.Assignment === 'HumanTask';
264
+ }
265
+ /** The edges into this task, so their conditions are editable where the step is. */
266
+ get IncomingEdges() {
267
+ if (!this.Draft || !this.Spec)
268
+ return [];
269
+ const nameOf = (id) => this.Spec.tasks.find((t) => t.tempId === id)?.name ?? id;
270
+ return GetDependencies(this.Draft).map((d) => ({
271
+ FromTempId: d.tempId,
272
+ FromName: nameOf(d.tempId),
273
+ Condition: d.condition ?? '',
274
+ }));
275
+ }
276
+ /**
277
+ * Switches the step between an agent, an action and a person.
278
+ *
279
+ * Replacing `kind` and `configuration` together is the whole operation now. Under the old flat
280
+ * shape this had to clear two sibling fields on every branch, and forgetting one produced an
281
+ * `AssignmentConflict` from a gesture that looked like a simple choice — a bug the union made
282
+ * unrepresentable rather than merely guarded.
283
+ *
284
+ * The previous name is carried over where it still applies, so toggling Agent → Person → Agent
285
+ * does not silently forget what the author had chosen.
286
+ */
287
+ SetAssignment(kind, name) {
288
+ if (!this.Draft || this.ReadOnly)
289
+ return;
290
+ const base = {
291
+ tempId: this.Draft.tempId,
292
+ name: this.Draft.name,
293
+ description: this.Draft.description,
294
+ dependsOn: this.Draft.dependsOn,
295
+ policy: this.Draft.policy,
296
+ layout: this.Draft.layout,
297
+ inputPayload: this.Draft.inputPayload,
298
+ };
299
+ switch (kind) {
300
+ case 'HumanTask':
301
+ this.Draft = TaskNode.Human(base, ConfigOf(this.Draft, 'Human') ?? {});
302
+ break;
303
+ case 'ActionTask':
304
+ this.Draft = TaskNode.Action(base, {
305
+ actionName: name ?? ConfigOf(this.Draft, 'Action')?.actionName ?? this.AvailableActionNames[0] ?? '',
306
+ });
307
+ break;
308
+ default:
309
+ this.Draft = TaskNode.Agent(base, {
310
+ agentName: name ?? ConfigOf(this.Draft, 'Agent')?.agentName ?? this.AvailableAgentNames[0] ?? '',
311
+ });
312
+ break;
313
+ }
314
+ this.Commit();
315
+ }
316
+ /** Asks the parent to apply the draft. */
317
+ Commit() {
318
+ if (!this.Draft || !this.currentTask || this.ReadOnly)
319
+ return;
320
+ this.TaskPropertyChangeRequested.emit(new TaskPropertyChangeRequestedEventArgs(this.currentTask.tempId, { ...this.Draft }));
321
+ }
322
+ /** Asks the parent to change (or, with an empty string, clear) an edge's condition. */
323
+ CommitCondition(fromTempId, condition) {
324
+ if (!this.Draft || this.ReadOnly)
325
+ return;
326
+ this.DependencyConditionChangeRequested.emit(new DependencyConditionChangeRequestedEventArgs(fromTempId, this.Draft.tempId, condition));
327
+ }
328
+ static ɵfac = function TaskGraphPropertiesPanelComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || TaskGraphPropertiesPanelComponent)(); };
329
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TaskGraphPropertiesPanelComponent, selectors: [["mj-task-graph-properties"]], inputs: { Task: "Task", Spec: "Spec", AvailableAgentNames: "AvailableAgentNames", AvailableActionNames: "AvailableActionNames", ReadOnly: "ReadOnly" }, outputs: { TaskPropertyChangeRequested: "TaskPropertyChangeRequested", DependencyConditionChangeRequested: "DependencyConditionChangeRequested" }, standalone: false, decls: 3, vars: 1, consts: [[1, "mj-tgp"], ["Icon", "fa-hand-pointer", "Title", "No step selected", "Message", "Pick a step on the canvas to edit what it does."], ["for", "tgp-name", 1, "mj-tgp__label"], ["id", "tgp-name", "type", "text", 1, "mj-input", 3, "ngModelChange", "blur", "ngModel", "disabled"], ["for", "tgp-desc", 1, "mj-tgp__label"], ["id", "tgp-desc", "rows", "3", 1, "mj-textarea", 3, "ngModelChange", "blur", "ngModel", "disabled"], [1, "mj-tgp__label"], [1, "mj-tgp__assignment"], ["mjButton", "", "size", "sm", 3, "click", "variant", "disabled"], [1, "fa-solid", "fa-robot"], [1, "fa-solid", "fa-bolt"], [1, "fa-solid", "fa-user-check"], ["Variant", "info", "Size", "sm", "Message", "This step waits for you. Assigning it to someone else isn't available yet."], ["aria-label", "Agent", 1, "mj-input", 3, "ngModel", "disabled"], ["Variant", "warning", "Size", "sm", "Message", "No agents are available to assign. This step will not run until one is chosen."], ["aria-label", "Agent", 1, "mj-input", 3, "ngModelChange", "change", "ngModel", "disabled"], [3, "value"], ["aria-label", "Action", 1, "mj-input", 3, "ngModel", "disabled"], ["Variant", "warning", "Size", "sm", "Message", "No actions are available to assign. This step will not run until one is chosen."], ["aria-label", "Action", 1, "mj-input", 3, "ngModelChange", "change", "ngModel", "disabled"], [1, "mj-tgp__edge"], [1, "mj-tgp__edge-name"], [1, "fa-solid", "fa-arrow-right-long"], ["type", "text", "placeholder", "Always \u2014 or a condition, e.g. output.severity > 3", 1, "mj-input", "mj-tgp__edge-condition", 3, "blur", "ngModel", "disabled"]], template: function TaskGraphPropertiesPanelComponent_Template(rf, ctx) { if (rf & 1) {
330
+ i0.ɵɵelementStart(0, "div", 0);
331
+ i0.ɵɵconditionalCreate(1, TaskGraphPropertiesPanelComponent_Conditional_1_Template, 1, 0, "mj-empty-state", 1)(2, TaskGraphPropertiesPanelComponent_Conditional_2_Template, 22, 12);
332
+ i0.ɵɵelementEnd();
333
+ } if (rf & 2) {
334
+ i0.ɵɵadvance();
335
+ i0.ɵɵconditional(!ctx.Draft ? 1 : 2);
336
+ } }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.DefaultValueAccessor, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.NgModel, i2.MJEmptyStateComponent, i2.MJAlertComponent, i2.MJButtonDirective], styles: ["\n\n.mj-tgp[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-sm, 0.5rem);\n padding: var(--mj-space-md, 1rem);\n overflow-y: auto;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n}\n\n.mj-tgp__label[_ngcontent-%COMP%] {\n font-size: var(--mj-font-size-sm, 0.8125rem);\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-top: var(--mj-space-xs, 0.25rem);\n}\n\n.mj-tgp__assignment[_ngcontent-%COMP%] {\n display: flex;\n gap: var(--mj-space-xs, 0.25rem);\n}\n\n.mj-tgp__edge[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2xs, 0.125rem);\n padding: var(--mj-space-xs, 0.25rem) 0;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.mj-tgp__edge-name[_ngcontent-%COMP%] {\n font-size: var(--mj-font-size-sm, 0.8125rem);\n color: var(--mj-text-secondary);\n}\n\n.mj-tgp__edge-condition[_ngcontent-%COMP%] {\n width: 100%;\n}"] });
337
+ }
338
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TaskGraphPropertiesPanelComponent, [{
339
+ type: Component,
340
+ args: [{ standalone: false, selector: 'mj-task-graph-properties', template: "<div class=\"mj-tgp\">\n @if (!Draft) {\n <mj-empty-state\n Icon=\"fa-hand-pointer\"\n Title=\"No step selected\"\n Message=\"Pick a step on the canvas to edit what it does.\">\n </mj-empty-state>\n } @else {\n <label class=\"mj-tgp__label\" for=\"tgp-name\">Name</label>\n <input id=\"tgp-name\" class=\"mj-input\" type=\"text\"\n [(ngModel)]=\"Draft.name\" [disabled]=\"ReadOnly\" (blur)=\"Commit()\" />\n\n <label class=\"mj-tgp__label\" for=\"tgp-desc\">What this step does</label>\n <textarea id=\"tgp-desc\" class=\"mj-textarea\" rows=\"3\"\n [(ngModel)]=\"Draft.description\" [disabled]=\"ReadOnly\" (blur)=\"Commit()\"></textarea>\n\n <label class=\"mj-tgp__label\">Who does it</label>\n <!-- Three, because TaskGraphSpecNode has exactly three mutually-exclusive assignment shapes:\n agentName, actionName, assignToUser. -->\n <div class=\"mj-tgp__assignment\">\n <button mjButton [variant]=\"Assignment === 'AgentTask' ? 'primary' : 'outline'\" size=\"sm\"\n [disabled]=\"ReadOnly\" (click)=\"SetAssignment('AgentTask')\">\n <i class=\"fa-solid fa-robot\"></i> An agent\n </button>\n <button mjButton [variant]=\"Assignment === 'ActionTask' ? 'primary' : 'outline'\" size=\"sm\"\n [disabled]=\"ReadOnly\" (click)=\"SetAssignment('ActionTask')\">\n <i class=\"fa-solid fa-bolt\"></i> An action\n </button>\n <button mjButton [variant]=\"Assignment === 'HumanTask' ? 'primary' : 'outline'\" size=\"sm\"\n [disabled]=\"ReadOnly\" (click)=\"SetAssignment('HumanTask')\">\n <i class=\"fa-solid fa-user-check\"></i> A person\n </button>\n </div>\n\n @switch (Assignment) {\n @case ('AgentTask') {\n @if (AvailableAgentNames.length > 0) {\n <select class=\"mj-input\" aria-label=\"Agent\" [(ngModel)]=\"AgentName\" [disabled]=\"ReadOnly\" (change)=\"Commit()\">\n @for (name of AvailableAgentNames; track name) {\n <option [value]=\"name\">{{ name }}</option>\n }\n </select>\n } @else {\n <!-- Says the list is empty rather than rendering an empty dropdown, which reads as a bug. -->\n <mj-alert Variant=\"warning\" Size=\"sm\"\n Message=\"No agents are available to assign. This step will not run until one is chosen.\">\n </mj-alert>\n }\n }\n @case ('ActionTask') {\n @if (AvailableActionNames.length > 0) {\n <select class=\"mj-input\" aria-label=\"Action\" [(ngModel)]=\"ActionName\" [disabled]=\"ReadOnly\" (change)=\"Commit()\">\n @for (name of AvailableActionNames; track name) {\n <option [value]=\"name\">{{ name }}</option>\n }\n </select>\n } @else {\n <mj-alert Variant=\"warning\" Size=\"sm\"\n Message=\"No actions are available to assign. This step will not run until one is chosen.\">\n </mj-alert>\n }\n }\n @default {\n <!-- Cross-user assignment is rejected at submission until the authorization model lands\n (#3524), so the panel states the rule rather than offering a picker that would fail. -->\n <mj-alert Variant=\"info\" Size=\"sm\"\n Message=\"This step waits for you. Assigning it to someone else isn't available yet.\">\n </mj-alert>\n }\n }\n\n @if (IncomingEdges.length > 0) {\n <label class=\"mj-tgp__label\">Runs after</label>\n @for (edge of IncomingEdges; track edge.FromTempId) {\n <div class=\"mj-tgp__edge\">\n <span class=\"mj-tgp__edge-name\"><i class=\"fa-solid fa-arrow-right-long\"></i> {{ edge.FromName }}</span>\n <!-- Leaving this empty makes the edge unconditional, which is how a fallback is written. -->\n <input class=\"mj-input mj-tgp__edge-condition\" type=\"text\"\n placeholder=\"Always \u2014 or a condition, e.g. output.severity > 3\"\n [ngModel]=\"edge.Condition\" [disabled]=\"ReadOnly\"\n (blur)=\"CommitCondition(edge.FromTempId, $any($event.target).value)\" />\n </div>\n }\n }\n }\n</div>\n", styles: ["/* Design tokens only \u2014 no hardcoded colors. */\n.mj-tgp {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-sm, 0.5rem);\n padding: var(--mj-space-md, 1rem);\n overflow-y: auto;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n}\n\n.mj-tgp__label {\n font-size: var(--mj-font-size-sm, 0.8125rem);\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-top: var(--mj-space-xs, 0.25rem);\n}\n\n.mj-tgp__assignment {\n display: flex;\n gap: var(--mj-space-xs, 0.25rem);\n}\n\n.mj-tgp__edge {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2xs, 0.125rem);\n padding: var(--mj-space-xs, 0.25rem) 0;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.mj-tgp__edge-name {\n font-size: var(--mj-font-size-sm, 0.8125rem);\n color: var(--mj-text-secondary);\n}\n\n.mj-tgp__edge-condition {\n width: 100%;\n}\n"] }]
341
+ }], null, { Task: [{
342
+ type: Input
343
+ }], Spec: [{
344
+ type: Input
345
+ }], AvailableAgentNames: [{
346
+ type: Input
347
+ }], AvailableActionNames: [{
348
+ type: Input
349
+ }], ReadOnly: [{
350
+ type: Input
351
+ }], TaskPropertyChangeRequested: [{
352
+ type: Output
353
+ }], DependencyConditionChangeRequested: [{
354
+ type: Output
355
+ }] }); })();
356
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TaskGraphPropertiesPanelComponent, { className: "TaskGraphPropertiesPanelComponent", filePath: "src/lib/task-graph-properties-panel.component.ts", lineNumber: 44 }); })();
357
+ //# sourceMappingURL=task-graph-properties-panel.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-graph-properties-panel.component.js","sourceRoot":"","sources":["../../src/lib/task-graph-properties-panel.component.ts","../../src/lib/task-graph-properties-panel.component.html"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAiE,MAAM,8BAA8B,CAAC;AACjI,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,oBAAoB,EAA0B,MAAM,6BAA6B,CAAC;;;;;;ICfzH,oCAIiB;;;IAiCP,kCAAuB;IAAA,YAAU;IAAA,iBAAS;;;IAAlC,+BAAc;IAAC,cAAU;IAAV,6BAAU;;;;IAFrC,kCAA8G;IAAlE,mVAAuB;IAAuB,8NAAU,eAAQ,KAAC;IAC3G,8JAEC;IACH,iBAAS;;;IAJmC,gDAAuB;IAAC,0CAAqB;IACvF,cAEC;IAFD,yCAEC;;;IAIH,+BAEW;;;IAJX,AANF,6HAAsC,yGAM7B;;;IANT,+DAWC;;;IAMK,kCAAuB;IAAA,YAAU;IAAA,iBAAS;;;IAAlC,+BAAc;IAAC,cAAU;IAAV,6BAAU;;;;IAFrC,kCAAgH;IAAnE,qVAAwB;IAAuB,8NAAU,eAAQ,KAAC;IAC7G,8JAEC;IACH,iBAAS;;;IAJoC,iDAAwB;IAAC,0CAAqB;IACzF,cAEC;IAFD,0CAEC;;;IAGH,+BAEW;;;IAHX,AANF,6HAAuC,yGAM9B;;;IANT,gEAUC;;;IAKD,+BAEW;;;;IAQT,AADF,+BAA0B,eACQ;IAAA,wBAA4C;IAAC,YAAmB;IAAA,iBAAO;IAEvG,iCAG8E;IAAvE,wPAAQ,+DAA2D,KAAC;IAC7E,AAJE,iBAG8E,EAC1E;;;;IANyE,eAAmB;IAAnB,4CAAmB;IAIzF,cAA0B;IAAC,AAA3B,2CAA0B,6BAAsB;;;IAP3D,gCAA6B;IAAA,0BAAU;IAAA,iBAAQ;IAC/C,kIASC;;;IATD,eASC;IATD,mCASC;;;;IA1EH,gCAA4C;IAAA,oBAAI;IAAA,iBAAQ;IACxD,gCAC0E;IAAnE,6TAAwB;IAAuB,kMAAQ,eAAQ,KAAC;IADvE,iBAC0E;IAE1E,gCAA4C;IAAA,mCAAmB;IAAA,iBAAQ;IACvE,mCACkF;IAAxE,8UAA+B;IAAuB,qMAAQ,eAAQ,KAAC;IAAC,iBAAW;IAE7F,gCAA6B;IAAA,2BAAW;IAAA,iBAAQ;IAI9C,AADF,8BAAgC,gBAEqC;IAArC,qMAAS,qBAAc,WAAW,CAAC,KAAC;IAChE,wBAAiC;IAAC,2BACpC;IAAA,iBAAS;IACT,kCACoE;IAAtC,sMAAS,qBAAc,YAAY,CAAC,KAAC;IACjE,yBAAgC;IAAC,4BACnC;IAAA,iBAAS;IACT,kCACmE;IAArC,sMAAS,qBAAc,WAAW,CAAC,KAAC;IAChE,yBAAsC;IAAC,2BACzC;IACF,AADE,iBAAS,EACL;IA8BJ,AAbA,AAdA,kGAAqB,4EAcC,4FAaZ;IASZ,yGAAgC;;;;IA7DzB,eAAwB;IAAxB,iDAAwB;IAAC,0CAAqB;IAI3C,eAA+B;IAA/B,wDAA+B;IAAC,0CAAqB;IAM5C,eAA8D;IACvE,AADS,mFAA8D,6BAClD;IAGZ,eAA+D;IACxE,AADS,oFAA+D,6BACnD;IAGZ,eAA8D;IACvE,AADS,mFAA8D,6BAClD;IAK/B,eAmCC;IAnCD,oDAAA,WAAW,qBAAX,YAAY,WAmCX;IAED,eAYC;IAZD,2DAYC;;ADhEL,sFAAsF;AACtF,MAAM,OAAO,oCAAoC;IAEzB;IACA;IAFpB,YACoB,MAAc,EACd,IAAuB;QADvB,WAAM,GAAN,MAAM,CAAQ;QACd,SAAI,GAAJ,IAAI,CAAmB;IACxC,CAAC;CACP;AAED,2DAA2D;AAC3D,MAAM,OAAO,2CAA2C;IAEhC;IACA;IAEA;IAJpB,YACoB,UAAkB,EAClB,QAAgB;IAChC,8EAA8E;IAC9D,SAAiB;QAHjB,eAAU,GAAV,UAAU,CAAQ;QAClB,aAAQ,GAAR,QAAQ,CAAQ;QAEhB,cAAS,GAAT,SAAS,CAAQ;IAClC,CAAC;CACP;AAQD,MAAM,OAAO,iCAAiC;IAC1C,6FAA6F;IAC7F,IACW,IAAI,CAAC,KAA+B;QAC3C,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,0FAA0F;QAC1F,mFAAmF;QACnF,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7C,CAAC;IACD,IAAW,IAAI;QACX,OAAO,IAAI,CAAC,WAAW,CAAC;IAC5B,CAAC;IAED,yEAAyE;IACzD,IAAI,GAAyB,IAAI,CAAC;IAElD,oGAAoG;IACpF,mBAAmB,GAAsB,EAAE,CAAC;IAE5D,qGAAqG;IACrF,oBAAoB,GAAsB,EAAE,CAAC;IAE7C,QAAQ,GAAY,KAAK,CAAC;IAEzB,2BAA2B,GAAG,IAAI,YAAY,EAAwC,CAAC;IACvF,kCAAkC,GAAG,IAAI,YAAY,EAA+C,CAAC;IAE/G,KAAK,GAA6B,IAAI,CAAC;IAEtC,WAAW,GAA6B,IAAI,CAAC;IAErD;;;;;OAKG;IACH,IAAW,UAAU;QACjB,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO,WAAW,CAAC;QACpC,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzC,0FAA0F;QAC1F,4FAA4F;QAC5F,8EAA8E;QAC9E,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC;IAC3D,CAAC;IAED;;;;;;OAMG;IACH,IAAW,SAAS;QAChB,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAM,EAAE,OAAO,CAAC,EAAE,SAAS,IAAI,EAAE,CAAC;IAC3D,CAAC;IACD,IAAW,SAAS,CAAC,KAAa;QAC9B,IAAI,IAAI,CAAC,KAAK,EAAE,IAAI,KAAK,OAAO,EAAE,CAAC;YAC/B,IAAI,CAAC,KAAK,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAE,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC;QAC3G,CAAC;IACL,CAAC;IAED,8DAA8D;IAC9D,IAAW,UAAU;QACjB,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAM,EAAE,QAAQ,CAAC,EAAE,UAAU,IAAI,EAAE,CAAC;IAC7D,CAAC;IACD,IAAW,UAAU,CAAC,KAAa;QAC/B,IAAI,IAAI,CAAC,KAAK,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;YAChC,IAAI,CAAC,KAAK,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAE,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,CAAC;QAC7G,CAAC;IACL,CAAC;IAED,6CAA6C;IAC7C,IAAW,WAAW;QAClB,OAAO,IAAI,CAAC,UAAU,KAAK,WAAW,CAAC;IAC3C,CAAC;IAED,oFAAoF;IACpF,IAAW,aAAa;QACpB,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,CAAC,IAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;QACzF,OAAO,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC3C,UAAU,EAAE,CAAC,CAAC,MAAM;YACpB,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;YAC1B,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,EAAE;SAC/B,CAAC,CAAC,CAAC;IACR,CAAC;IAED;;;;;;;;;;OAUG;IACI,aAAa,CAAC,IAAuB,EAAE,IAAa;QACvD,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QACzC,MAAM,IAAI,GAAiB;YACvB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;YACzB,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;YACrB,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW;YACnC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS;YAC/B,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;YACzB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;YACzB,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY;SACxC,CAAC;QACF,QAAQ,IAAI,EAAE,CAAC;YACX,KAAK,WAAW;gBACZ,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;gBACvE,MAAM;YACV,KAAK,YAAY;gBACb,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE;oBAC/B,UAAU,EAAE,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,UAAU,IAAI,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,EAAE;iBACvG,CAAC,CAAC;gBACH,MAAM;YACV;gBACI,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE;oBAC9B,SAAS,EAAE,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,SAAS,IAAI,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,EAAE;iBACnG,CAAC,CAAC;gBACH,MAAM;QACd,CAAC;QACD,IAAI,CAAC,MAAM,EAAE,CAAC;IAClB,CAAC;IAED,0CAA0C;IACnC,MAAM;QACT,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC9D,IAAI,CAAC,2BAA2B,CAAC,IAAI,CACjC,IAAI,oCAAoC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CACvF,CAAC;IACN,CAAC;IAED,uFAAuF;IAChF,eAAe,CAAC,UAAkB,EAAE,SAAiB;QACxD,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QACzC,IAAI,CAAC,kCAAkC,CAAC,IAAI,CACxC,IAAI,2CAA2C,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAC5F,CAAC;IACN,CAAC;2HA9IQ,iCAAiC;6DAAjC,iCAAiC;YC3C9C,8BAAoB;YAOhB,AANF,8GAAc,qEAML;YA8EX,iBAAM;;YApFJ,cAmFC;YAnFD,oCAmFC;;;iFDzCU,iCAAiC;cAN7C,SAAS;6BACM,KAAK,YACP,0BAA0B;;kBAMnC,KAAK;;kBAYL,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAEL,KAAK;;kBAEL,MAAM;;kBACN,MAAM;;kFAzBE,iCAAiC","sourcesContent":["/**\n * @fileoverview Edits the selected task's properties, plus the graph-level traversal settings.\n *\n * Split out of the canvas component for the reason panels usually are — the canvas is about\n * *structure* (what connects to what) and this is about *content* (what a step actually does). But\n * also for a sharper reason: a host embedding the read-only viewer in a chat card or a run history\n * pane wants the graph without a form beside it, and a panel welded into the canvas cannot be\n * declined.\n *\n * Emits intent rather than mutating: the canvas component owns the spec, so every edit here leaves\n * as a request the parent applies through the same `Before*`/`After*` path a drag or a delete takes.\n * Two write paths into one spec would be two places for the veto contract to be wrong.\n *\n * @module @memberjunction/ng-task-graph-editor\n */\nimport { Component, EventEmitter, Input, Output } from '@angular/core';\nimport { ConfigOf, TaskNode, type TaskGraphSpec, type TaskGraphSpecNode, type TaskNodeBase } from '@memberjunction/ai-core-plus';\nimport { GetDependencies, GetTaskNodeType, IsAuthorableNodeType, type TaskGraphNodeType } from './task-graph-canvas-adapter';\n\n/** A requested change to one task. The parent applies it; this panel never writes. */\nexport class TaskPropertyChangeRequestedEventArgs {\n constructor(\n public readonly TempId: string,\n public readonly Next: TaskGraphSpecNode,\n ) {}\n}\n\n/** A requested change to a dependency edge's condition. */\nexport class DependencyConditionChangeRequestedEventArgs {\n constructor(\n public readonly FromTempId: string,\n public readonly ToTempId: string,\n /** Empty string clears the condition, making the edge unconditional again. */\n public readonly Condition: string,\n ) {}\n}\n\n@Component({\n standalone: false,\n selector: 'mj-task-graph-properties',\n templateUrl: './task-graph-properties-panel.component.html',\n styleUrls: ['./task-graph-properties-panel.component.css'],\n})\nexport class TaskGraphPropertiesPanelComponent {\n /** The task being edited. Null shows the empty state rather than a form bound to nothing. */\n @Input()\n public set Task(value: TaskGraphSpecNode | null) {\n this.currentTask = value;\n // A working copy, so a half-typed name never reaches the spec — and so Cancel is possible\n // at all. Editing the live node would make every keystroke an unvetoable mutation.\n this.Draft = value ? { ...value } : null;\n }\n public get Task(): TaskGraphSpecNode | null {\n return this.currentTask;\n }\n\n /** The whole graph, for resolving the selected task's incoming edges. */\n @Input() public Spec: TaskGraphSpec | null = null;\n\n /** Agent names offered in the assignment dropdown. Supplied by the host, which owns data access. */\n @Input() public AvailableAgentNames: readonly string[] = [];\n\n /** Action names offered in the assignment dropdown. Same ownership rule as `AvailableAgentNames`. */\n @Input() public AvailableActionNames: readonly string[] = [];\n\n @Input() public ReadOnly: boolean = false;\n\n @Output() public TaskPropertyChangeRequested = new EventEmitter<TaskPropertyChangeRequestedEventArgs>();\n @Output() public DependencyConditionChangeRequested = new EventEmitter<DependencyConditionChangeRequestedEventArgs>();\n\n public Draft: TaskGraphSpecNode | null = null;\n\n private currentTask: TaskGraphSpecNode | null = null;\n\n /**\n * Which of the three assignment shapes this step currently uses.\n *\n * Derived from the draft rather than stored separately: the node's own `kind` is the single\n * source of truth, and a parallel field could disagree with it.\n */\n public get Assignment(): TaskGraphNodeType {\n if (!this.Draft) return 'AgentTask';\n const type = GetTaskNodeType(this.Draft);\n // This panel edits the three authorable shapes. A display-only kind (a Prompt, a loop, an\n // external step — kinds a run can contain but nobody draws here) has no editor, so it falls\n // back rather than being mis-presented as an agent step with an agent picker.\n return IsAuthorableNodeType(type) ? type : 'AgentTask';\n }\n\n /**\n * The chosen agent, read and written through the node's configuration.\n *\n * A template cannot narrow a discriminated union, so the two-way binding goes through here\n * rather than at `Draft.configuration.agentName` — which would also be wrong the moment the\n * draft is a different kind.\n */\n public get AgentName(): string {\n return ConfigOf(this.Draft!, 'Agent')?.agentName ?? '';\n }\n public set AgentName(value: string) {\n if (this.Draft?.kind === 'Agent') {\n this.Draft = { ...this.Draft, configuration: { ...ConfigOf(this.Draft, 'Agent')!, agentName: value } };\n }\n }\n\n /** The chosen action. Same reasoning as {@link AgentName}. */\n public get ActionName(): string {\n return ConfigOf(this.Draft!, 'Action')?.actionName ?? '';\n }\n public set ActionName(value: string) {\n if (this.Draft?.kind === 'Action') {\n this.Draft = { ...this.Draft, configuration: { ...ConfigOf(this.Draft, 'Action')!, actionName: value } };\n }\n }\n\n /** True when this step waits on a person. */\n public get IsHumanTask(): boolean {\n return this.Assignment === 'HumanTask';\n }\n\n /** The edges into this task, so their conditions are editable where the step is. */\n public get IncomingEdges(): Array<{ FromTempId: string; FromName: string; Condition: string }> {\n if (!this.Draft || !this.Spec) return [];\n const nameOf = (id: string) => this.Spec!.tasks.find((t) => t.tempId === id)?.name ?? id;\n return GetDependencies(this.Draft).map((d) => ({\n FromTempId: d.tempId,\n FromName: nameOf(d.tempId),\n Condition: d.condition ?? '',\n }));\n }\n\n /**\n * Switches the step between an agent, an action and a person.\n *\n * Replacing `kind` and `configuration` together is the whole operation now. Under the old flat\n * shape this had to clear two sibling fields on every branch, and forgetting one produced an\n * `AssignmentConflict` from a gesture that looked like a simple choice — a bug the union made\n * unrepresentable rather than merely guarded.\n *\n * The previous name is carried over where it still applies, so toggling Agent → Person → Agent\n * does not silently forget what the author had chosen.\n */\n public SetAssignment(kind: TaskGraphNodeType, name?: string): void {\n if (!this.Draft || this.ReadOnly) return;\n const base: TaskNodeBase = {\n tempId: this.Draft.tempId,\n name: this.Draft.name,\n description: this.Draft.description,\n dependsOn: this.Draft.dependsOn,\n policy: this.Draft.policy,\n layout: this.Draft.layout,\n inputPayload: this.Draft.inputPayload,\n };\n switch (kind) {\n case 'HumanTask':\n this.Draft = TaskNode.Human(base, ConfigOf(this.Draft, 'Human') ?? {});\n break;\n case 'ActionTask':\n this.Draft = TaskNode.Action(base, {\n actionName: name ?? ConfigOf(this.Draft, 'Action')?.actionName ?? this.AvailableActionNames[0] ?? '',\n });\n break;\n default:\n this.Draft = TaskNode.Agent(base, {\n agentName: name ?? ConfigOf(this.Draft, 'Agent')?.agentName ?? this.AvailableAgentNames[0] ?? '',\n });\n break;\n }\n this.Commit();\n }\n\n /** Asks the parent to apply the draft. */\n public Commit(): void {\n if (!this.Draft || !this.currentTask || this.ReadOnly) return;\n this.TaskPropertyChangeRequested.emit(\n new TaskPropertyChangeRequestedEventArgs(this.currentTask.tempId, { ...this.Draft }),\n );\n }\n\n /** Asks the parent to change (or, with an empty string, clear) an edge's condition. */\n public CommitCondition(fromTempId: string, condition: string): void {\n if (!this.Draft || this.ReadOnly) return;\n this.DependencyConditionChangeRequested.emit(\n new DependencyConditionChangeRequestedEventArgs(fromTempId, this.Draft.tempId, condition),\n );\n }\n}\n","<div class=\"mj-tgp\">\n @if (!Draft) {\n <mj-empty-state\n Icon=\"fa-hand-pointer\"\n Title=\"No step selected\"\n Message=\"Pick a step on the canvas to edit what it does.\">\n </mj-empty-state>\n } @else {\n <label class=\"mj-tgp__label\" for=\"tgp-name\">Name</label>\n <input id=\"tgp-name\" class=\"mj-input\" type=\"text\"\n [(ngModel)]=\"Draft.name\" [disabled]=\"ReadOnly\" (blur)=\"Commit()\" />\n\n <label class=\"mj-tgp__label\" for=\"tgp-desc\">What this step does</label>\n <textarea id=\"tgp-desc\" class=\"mj-textarea\" rows=\"3\"\n [(ngModel)]=\"Draft.description\" [disabled]=\"ReadOnly\" (blur)=\"Commit()\"></textarea>\n\n <label class=\"mj-tgp__label\">Who does it</label>\n <!-- Three, because TaskGraphSpecNode has exactly three mutually-exclusive assignment shapes:\n agentName, actionName, assignToUser. -->\n <div class=\"mj-tgp__assignment\">\n <button mjButton [variant]=\"Assignment === 'AgentTask' ? 'primary' : 'outline'\" size=\"sm\"\n [disabled]=\"ReadOnly\" (click)=\"SetAssignment('AgentTask')\">\n <i class=\"fa-solid fa-robot\"></i> An agent\n </button>\n <button mjButton [variant]=\"Assignment === 'ActionTask' ? 'primary' : 'outline'\" size=\"sm\"\n [disabled]=\"ReadOnly\" (click)=\"SetAssignment('ActionTask')\">\n <i class=\"fa-solid fa-bolt\"></i> An action\n </button>\n <button mjButton [variant]=\"Assignment === 'HumanTask' ? 'primary' : 'outline'\" size=\"sm\"\n [disabled]=\"ReadOnly\" (click)=\"SetAssignment('HumanTask')\">\n <i class=\"fa-solid fa-user-check\"></i> A person\n </button>\n </div>\n\n @switch (Assignment) {\n @case ('AgentTask') {\n @if (AvailableAgentNames.length > 0) {\n <select class=\"mj-input\" aria-label=\"Agent\" [(ngModel)]=\"AgentName\" [disabled]=\"ReadOnly\" (change)=\"Commit()\">\n @for (name of AvailableAgentNames; track name) {\n <option [value]=\"name\">{{ name }}</option>\n }\n </select>\n } @else {\n <!-- Says the list is empty rather than rendering an empty dropdown, which reads as a bug. -->\n <mj-alert Variant=\"warning\" Size=\"sm\"\n Message=\"No agents are available to assign. This step will not run until one is chosen.\">\n </mj-alert>\n }\n }\n @case ('ActionTask') {\n @if (AvailableActionNames.length > 0) {\n <select class=\"mj-input\" aria-label=\"Action\" [(ngModel)]=\"ActionName\" [disabled]=\"ReadOnly\" (change)=\"Commit()\">\n @for (name of AvailableActionNames; track name) {\n <option [value]=\"name\">{{ name }}</option>\n }\n </select>\n } @else {\n <mj-alert Variant=\"warning\" Size=\"sm\"\n Message=\"No actions are available to assign. This step will not run until one is chosen.\">\n </mj-alert>\n }\n }\n @default {\n <!-- Cross-user assignment is rejected at submission until the authorization model lands\n (#3524), so the panel states the rule rather than offering a picker that would fail. -->\n <mj-alert Variant=\"info\" Size=\"sm\"\n Message=\"This step waits for you. Assigning it to someone else isn't available yet.\">\n </mj-alert>\n }\n }\n\n @if (IncomingEdges.length > 0) {\n <label class=\"mj-tgp__label\">Runs after</label>\n @for (edge of IncomingEdges; track edge.FromTempId) {\n <div class=\"mj-tgp__edge\">\n <span class=\"mj-tgp__edge-name\"><i class=\"fa-solid fa-arrow-right-long\"></i> {{ edge.FromName }}</span>\n <!-- Leaving this empty makes the edge unconditional, which is how a fallback is written. -->\n <input class=\"mj-input mj-tgp__edge-condition\" type=\"text\"\n placeholder=\"Always — or a condition, e.g. output.severity > 3\"\n [ngModel]=\"edge.Condition\" [disabled]=\"ReadOnly\"\n (blur)=\"CommitCondition(edge.FromTempId, $any($event.target).value)\" />\n </div>\n }\n }\n }\n</div>\n"]}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * @fileoverview Watching a graph that is running, on the canvas its author drew on.
3
+ *
4
+ * **Why this is a component and not three.** A run needs rendering in at least three places — inside
5
+ * an Agent Run, inside the test harness, and on a standalone workflow-runs screen — and every one of
6
+ * them wants the identical thing: the graph, with live status, laid out legibly, with a node you can
7
+ * click. Three implementations would be three chances to render the same run differently, and the
8
+ * one that matters most (is that branch grey because it was *not taken*, or because it *broke*?) is
9
+ * exactly the distinction a second implementation gets wrong.
10
+ *
11
+ * **What it owns and what it doesn't.** It owns data acquisition — reading `MJ: Tasks` and
12
+ * `MJ: Task Dependencies` through the host's provider — and geometry. It does not navigate: a
13
+ * widgets-layer component cannot know whether it sits inside Explorer, so selecting a node emits an
14
+ * event and the host decides what "open the agent run" means. That boundary is the whole reason
15
+ * this can live beside the editor rather than in Explorer.
16
+ *
17
+ * @module @memberjunction/ng-task-graph-editor
18
+ */
19
+ import { ChangeDetectorRef, EventEmitter, OnDestroy } from '@angular/core';
20
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
21
+ import { MJTaskEntity } from '@memberjunction/core-entities';
22
+ import { type GraphNodePosition, type TaskGraphSpec } from '@memberjunction/ai-core-plus';
23
+ import type { TaskGraphRuntimeStatus } from './task-graph-canvas-adapter';
24
+ import type { TaskGraphSelectionChangedEventArgs } from './task-graph-editor-events';
25
+ import * as i0 from "@angular/core";
26
+ /** What the host learns when someone clicks a step. */
27
+ export type TaskGraphRunNodeSelectedEvent = {
28
+ /** The `MJ: Tasks` row id. */
29
+ TaskID: string;
30
+ Task: MJTaskEntity | null;
31
+ };
32
+ export declare class TaskGraphRunViewComponent extends BaseAngularComponent implements OnDestroy {
33
+ private cdr;
34
+ /**
35
+ * The graph to watch — the parent `MJ: Tasks` row that represents it.
36
+ *
37
+ * Setter-based rather than `ngOnChanges`, matching the editor beside it: the reaction is
38
+ * explicit and costs nothing on unrelated change-detection passes.
39
+ */
40
+ set ParentTaskID(value: string | null);
41
+ get ParentTaskID(): string | null;
42
+ /** Name shown on the compiled graph. Purely cosmetic; the rows carry the truth. */
43
+ WorkflowName: string;
44
+ /**
45
+ * Keep re-reading while the graph is still moving.
46
+ *
47
+ * Off by default: most hosts show a finished run, and a component that polls by default would
48
+ * have every historical run quietly issuing queries forever.
49
+ */
50
+ LiveUpdates: boolean;
51
+ /** How often to re-read while live. Seconds, not milliseconds — this is a human-scale view. */
52
+ PollIntervalSeconds: number;
53
+ /** Height of the canvas. Hosts embed this in very different amounts of space. */
54
+ Height: string;
55
+ NodeSelected: EventEmitter<TaskGraphRunNodeSelectedEvent>;
56
+ /** Emitted once, when every step has reached a terminal status. */
57
+ Settled: EventEmitter<void>;
58
+ Spec: TaskGraphSpec | null;
59
+ RuntimeStatus: TaskGraphRuntimeStatus | null;
60
+ Positions: Map<string, GraphNodePosition>;
61
+ IsLoading: boolean;
62
+ ErrorMessage: string | null;
63
+ /** Rows by id, so a selection event can hand the host the whole task rather than an id. */
64
+ private taskByID;
65
+ private parentTaskID;
66
+ private pollTimer;
67
+ private destroyed;
68
+ constructor(cdr: ChangeDetectorRef);
69
+ ngOnDestroy(): void;
70
+ /** Steps in a terminal state, for the host's summary line. */
71
+ get CompletedCount(): number;
72
+ get TotalCount(): number;
73
+ get SkippedCount(): number;
74
+ /**
75
+ * A node was selected on the canvas.
76
+ *
77
+ * The projected `tempId` IS the task id, so the row lookup is exact — and handing the host the
78
+ * whole task rather than an id spares every host from re-reading a row this component already
79
+ * holds.
80
+ */
81
+ OnSelectionChanged(args: TaskGraphSelectionChangedEventArgs): void;
82
+ /**
83
+ * Reads the graph and projects it onto the canvas.
84
+ *
85
+ * `BypassCache` throughout: a run view exists to show what is true *now*, and the whole point of
86
+ * the poll is to see a status that changed a second ago. A cached read would render a stale graph
87
+ * that looks authoritative.
88
+ */
89
+ private load;
90
+ /** Rows → spec + runtime + geometry. */
91
+ private project;
92
+ /**
93
+ * The author's arrangement where there is one, a computed layout everywhere else.
94
+ *
95
+ * Mixing the two per-node rather than choosing one for the whole graph: a workflow whose author
96
+ * positioned some steps and left others where they fell should keep the positions they chose.
97
+ * A wholly unpositioned graph — the normal case for anything an agent emitted — is laid out
98
+ * entirely by the algorithm.
99
+ */
100
+ private resolvePositions;
101
+ private isSettled;
102
+ private schedulePoll;
103
+ private stopPolling;
104
+ private fail;
105
+ /** Canvas extent, so a host can size its container to the graph rather than guessing. */
106
+ get GraphBounds(): {
107
+ Width: number;
108
+ Height: number;
109
+ };
110
+ static ɵfac: i0.ɵɵFactoryDeclaration<TaskGraphRunViewComponent, never>;
111
+ static ɵcmp: i0.ɵɵComponentDeclaration<TaskGraphRunViewComponent, "mj-task-graph-run-view", never, { "ParentTaskID": { "alias": "ParentTaskID"; "required": false; }; "WorkflowName": { "alias": "WorkflowName"; "required": false; }; "LiveUpdates": { "alias": "LiveUpdates"; "required": false; }; "PollIntervalSeconds": { "alias": "PollIntervalSeconds"; "required": false; }; "Height": { "alias": "Height"; "required": false; }; }, { "NodeSelected": "NodeSelected"; "Settled": "Settled"; }, never, never, false, never>;
112
+ }
113
+ //# sourceMappingURL=task-graph-run-view.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-graph-run-view.component.d.ts","sourceRoot":"","sources":["../../src/lib/task-graph-run-view.component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAEH,iBAAiB,EAEjB,YAAY,EAEZ,SAAS,EAEZ,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAErE,OAAO,EAAE,YAAY,EAA0B,MAAM,+BAA+B,CAAC;AACrF,OAAO,EAKH,KAAK,iBAAiB,EACtB,KAAK,aAAa,EACrB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,KAAK,EAAE,kCAAkC,EAAE,MAAM,4BAA4B,CAAC;;AAErF,uDAAuD;AACvD,MAAM,MAAM,6BAA6B,GAAG;IACxC,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;CAC7B,CAAC;AAKF,qBAOa,yBAA0B,SAAQ,oBAAqB,YAAW,SAAS;IAkDxE,OAAO,CAAC,GAAG;IAjDvB;;;;;OAKG;IACH,IACW,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAI3C;IACD,IAAW,YAAY,IAAI,MAAM,GAAG,IAAI,CAEvC;IAED,mFAAmF;IACnE,YAAY,EAAE,MAAM,CAAc;IAElD;;;;;OAKG;IACa,WAAW,EAAE,OAAO,CAAS;IAE7C,+FAA+F;IAC/E,mBAAmB,EAAE,MAAM,CAAK;IAEhD,iFAAiF;IACjE,MAAM,EAAE,MAAM,CAAW;IAExB,YAAY,8CAAqD;IAClF,mEAAmE;IAClD,OAAO,qBAA4B;IAE7C,IAAI,EAAE,aAAa,GAAG,IAAI,CAAQ;IAClC,aAAa,EAAE,sBAAsB,GAAG,IAAI,CAAQ;IACpD,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAa;IACtD,SAAS,UAAS;IAClB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE1C,2FAA2F;IAC3F,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,SAAS,CAA8C;IAC/D,OAAO,CAAC,SAAS,CAAS;gBAEN,GAAG,EAAE,iBAAiB;IAInC,WAAW,IAAI,IAAI;IAK1B,8DAA8D;IAC9D,IAAW,cAAc,IAAI,MAAM,CAElC;IAED,IAAW,UAAU,IAAI,MAAM,CAE9B;IAED,IAAW,YAAY,IAAI,MAAM,CAEhC;IAED;;;;;;OAMG;IACI,kBAAkB,CAAC,IAAI,EAAE,kCAAkC,GAAG,IAAI;IAMzE;;;;;;OAMG;YACW,IAAI;IA0DlB,wCAAwC;IACxC,OAAO,CAAC,OAAO;IAef;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,IAAI;IAMZ,yFAAyF;IACzF,IAAW,WAAW,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAG1D;yCAvNQ,yBAAyB;2CAAzB,yBAAyB;CAwNrC"}