ngx-dynamic-entity-builder 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +54 -0
  2. package/esm2022/lib/builder-store.service.mjs +923 -0
  3. package/esm2022/lib/clone.mjs +14 -0
  4. package/esm2022/lib/components/connection-source-config.component.mjs +121 -0
  5. package/esm2022/lib/components/entity-builder-canvas.component.mjs +83 -0
  6. package/esm2022/lib/components/entity-builder-tree-node.component.mjs +173 -0
  7. package/esm2022/lib/components/entity-reference-config.component.mjs +405 -0
  8. package/esm2022/lib/components/field-inspector.component.mjs +139 -0
  9. package/esm2022/lib/components/field-palette.component.mjs +57 -0
  10. package/esm2022/lib/components/field-rules-list.component.mjs +224 -0
  11. package/esm2022/lib/components/referenced-field-config.component.mjs +228 -0
  12. package/esm2022/lib/components/rule-form.component.mjs +201 -0
  13. package/esm2022/lib/components/tab-manager.component.mjs +341 -0
  14. package/esm2022/lib/entity-builder.component.mjs +153 -0
  15. package/esm2022/lib/field-catalog.mjs +6 -0
  16. package/esm2022/ngx-dynamic-entity-builder.mjs +5 -0
  17. package/esm2022/public-api.mjs +17 -0
  18. package/fesm2022/ngx-dynamic-entity-builder.mjs +2910 -0
  19. package/fesm2022/ngx-dynamic-entity-builder.mjs.map +1 -0
  20. package/index.d.ts +5 -0
  21. package/lib/builder-store.service.d.ts +165 -0
  22. package/lib/clone.d.ts +9 -0
  23. package/lib/components/connection-source-config.component.d.ts +16 -0
  24. package/lib/components/entity-builder-canvas.component.d.ts +9 -0
  25. package/lib/components/entity-builder-tree-node.component.d.ts +17 -0
  26. package/lib/components/entity-reference-config.component.d.ts +29 -0
  27. package/lib/components/field-inspector.component.d.ts +33 -0
  28. package/lib/components/field-palette.component.d.ts +13 -0
  29. package/lib/components/field-rules-list.component.d.ts +19 -0
  30. package/lib/components/referenced-field-config.component.d.ts +18 -0
  31. package/lib/components/rule-form.component.d.ts +16 -0
  32. package/lib/components/tab-manager.component.d.ts +19 -0
  33. package/lib/entity-builder.component.d.ts +42 -0
  34. package/lib/field-catalog.d.ts +5 -0
  35. package/package.json +42 -0
  36. package/public-api.d.ts +13 -0
@@ -0,0 +1,228 @@
1
+ import { Component, computed, inject } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { FormsModule } from '@angular/forms';
4
+ import { MatButtonModule } from '@angular/material/button';
5
+ import { MatDividerModule } from '@angular/material/divider';
6
+ import { MatFormFieldModule } from '@angular/material/form-field';
7
+ import { MatIconModule } from '@angular/material/icon';
8
+ import { MatInputModule } from '@angular/material/input';
9
+ import { MatSlideToggleModule } from '@angular/material/slide-toggle';
10
+ import { ConfigSourceService } from 'ngx-dynamic-entity';
11
+ import { BuilderStore } from '../builder-store.service';
12
+ import * as i0 from "@angular/core";
13
+ import * as i1 from "@angular/forms";
14
+ import * as i2 from "@angular/material/button";
15
+ import * as i3 from "@angular/material/form-field";
16
+ import * as i4 from "@angular/material/icon";
17
+ import * as i5 from "@angular/material/input";
18
+ import * as i6 from "@angular/material/slide-toggle";
19
+ export class ReferencedFieldConfigComponent {
20
+ store = inject(BuilderStore);
21
+ configSource = inject(ConfigSourceService, { optional: true });
22
+ field = computed(() => this.store.selectedField());
23
+ toggleReferenced(field, enabled) {
24
+ if (enabled) {
25
+ this.store.updateField(field.id, { isReferenced: true });
26
+ }
27
+ else {
28
+ this.store.unlinkReferencedField(field.id);
29
+ }
30
+ }
31
+ updateEntityKey(field, key) {
32
+ const trimmed = key.trim();
33
+ this.store.updateField(field.id, { referencedEntityKey: trimmed || undefined });
34
+ this.checkDriftForField(field.id);
35
+ }
36
+ updateFieldId(field, fieldId) {
37
+ const trimmed = fieldId.trim();
38
+ this.store.updateField(field.id, { referencedFieldId: trimmed || undefined });
39
+ this.checkDriftForField(field.id);
40
+ }
41
+ async syncWithSource(field) {
42
+ if (!field.referencedEntityKey || !field.referencedFieldId || !this.configSource)
43
+ return;
44
+ const sourceConfig = await this.configSource.getConfig(field.referencedEntityKey);
45
+ if (!sourceConfig)
46
+ return;
47
+ const sourceField = this.findField(sourceConfig.tabs ?? [], field.referencedFieldId);
48
+ if (sourceField) {
49
+ this.store.syncReferencedField(field.id, sourceField);
50
+ }
51
+ }
52
+ async checkDriftForField(fieldId) {
53
+ const f = this.store.selectedField();
54
+ if (!f || !f.isReferenced || !f.referencedEntityKey || !f.referencedFieldId || !this.configSource)
55
+ return;
56
+ const sourceConfig = await this.configSource.getConfig(f.referencedEntityKey);
57
+ if (sourceConfig) {
58
+ this.store.checkDrift({ [f.referencedEntityKey]: sourceConfig });
59
+ }
60
+ }
61
+ findField(tabs, id) {
62
+ for (const t of tabs) {
63
+ for (const f of t.fields ?? []) {
64
+ if (f.id === id)
65
+ return f;
66
+ if (f.children?.length) {
67
+ const res = this.findFieldInList(f.children, id);
68
+ if (res)
69
+ return res;
70
+ }
71
+ }
72
+ }
73
+ return undefined;
74
+ }
75
+ findFieldInList(fields, id) {
76
+ for (const f of fields) {
77
+ if (f.id === id)
78
+ return f;
79
+ if (f.children?.length) {
80
+ const res = this.findFieldInList(f.children, id);
81
+ if (res)
82
+ return res;
83
+ }
84
+ }
85
+ return undefined;
86
+ }
87
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ReferencedFieldConfigComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
88
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: ReferencedFieldConfigComponent, isStandalone: true, selector: "ngx-referenced-field-config", ngImport: i0, template: `
89
+ @if (field(); as f) {
90
+ <div class="deb-referenced-field" style="margin-top: 16px;">
91
+ <div class="deb-row" style="justify-content: space-between; align-items: center; margin-bottom: 8px;">
92
+ <span class="deb-section-title" style="margin:0;">Referenced Field</span>
93
+ <mat-slide-toggle
94
+ data-testid="toggle-referenced"
95
+ [ngModel]="f.isReferenced ?? false"
96
+ (ngModelChange)="toggleReferenced(f, $event)"
97
+ >
98
+ Link
99
+ </mat-slide-toggle>
100
+ </div>
101
+
102
+ @if (f.isReferenced) {
103
+ <mat-form-field appearance="outline" subscriptSizing="dynamic" class="deb-full" style="margin-bottom: 8px;">
104
+ <mat-label>Source Entity Key</mat-label>
105
+ <input
106
+ matInput
107
+ data-testid="referenced-entity-key"
108
+ [ngModel]="f.referencedEntityKey ?? ''"
109
+ (ngModelChange)="updateEntityKey(f, $event)"
110
+ placeholder="e.g. individuals"
111
+ />
112
+ </mat-form-field>
113
+
114
+ <mat-form-field appearance="outline" subscriptSizing="dynamic" class="deb-full" style="margin-bottom: 8px;">
115
+ <mat-label>Source Field ID</mat-label>
116
+ <input
117
+ matInput
118
+ data-testid="referenced-field-id"
119
+ [ngModel]="f.referencedFieldId ?? ''"
120
+ (ngModelChange)="updateFieldId(f, $event)"
121
+ placeholder="e.g. firstName"
122
+ />
123
+ </mat-form-field>
124
+
125
+ @if (f.hasDrift) {
126
+ <div class="deb-drift-banner" data-testid="drift-banner" style="background: #fff3e0; border: 1px solid #ffe0b2; padding: 8px 12px; border-radius: 4px; margin-top: 8px;">
127
+ <div class="deb-row" style="gap: 8px; align-items: center; color: #e65100; font-weight: 500;">
128
+ <mat-icon style="font-size: 18px; width:18px; height:18px;">warning</mat-icon>
129
+ <span>Source field definition has drifted!</span>
130
+ </div>
131
+ <p style="margin: 4px 0 8px 0; font-size: 12px; color: #666;">
132
+ The upstream field configuration in "{{ f.referencedEntityKey }}" has evolved.
133
+ </p>
134
+ <button
135
+ mat-flat-button
136
+ color="warn"
137
+ type="button"
138
+ data-testid="sync-source-btn"
139
+ (click)="syncWithSource(f)"
140
+ >
141
+ Sync with Source
142
+ </button>
143
+ </div>
144
+ }
145
+ }
146
+ </div>
147
+ }
148
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }] });
149
+ }
150
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ReferencedFieldConfigComponent, decorators: [{
151
+ type: Component,
152
+ args: [{
153
+ selector: 'ngx-referenced-field-config',
154
+ standalone: true,
155
+ imports: [
156
+ CommonModule,
157
+ FormsModule,
158
+ MatButtonModule,
159
+ MatDividerModule,
160
+ MatFormFieldModule,
161
+ MatIconModule,
162
+ MatInputModule,
163
+ MatSlideToggleModule,
164
+ ],
165
+ template: `
166
+ @if (field(); as f) {
167
+ <div class="deb-referenced-field" style="margin-top: 16px;">
168
+ <div class="deb-row" style="justify-content: space-between; align-items: center; margin-bottom: 8px;">
169
+ <span class="deb-section-title" style="margin:0;">Referenced Field</span>
170
+ <mat-slide-toggle
171
+ data-testid="toggle-referenced"
172
+ [ngModel]="f.isReferenced ?? false"
173
+ (ngModelChange)="toggleReferenced(f, $event)"
174
+ >
175
+ Link
176
+ </mat-slide-toggle>
177
+ </div>
178
+
179
+ @if (f.isReferenced) {
180
+ <mat-form-field appearance="outline" subscriptSizing="dynamic" class="deb-full" style="margin-bottom: 8px;">
181
+ <mat-label>Source Entity Key</mat-label>
182
+ <input
183
+ matInput
184
+ data-testid="referenced-entity-key"
185
+ [ngModel]="f.referencedEntityKey ?? ''"
186
+ (ngModelChange)="updateEntityKey(f, $event)"
187
+ placeholder="e.g. individuals"
188
+ />
189
+ </mat-form-field>
190
+
191
+ <mat-form-field appearance="outline" subscriptSizing="dynamic" class="deb-full" style="margin-bottom: 8px;">
192
+ <mat-label>Source Field ID</mat-label>
193
+ <input
194
+ matInput
195
+ data-testid="referenced-field-id"
196
+ [ngModel]="f.referencedFieldId ?? ''"
197
+ (ngModelChange)="updateFieldId(f, $event)"
198
+ placeholder="e.g. firstName"
199
+ />
200
+ </mat-form-field>
201
+
202
+ @if (f.hasDrift) {
203
+ <div class="deb-drift-banner" data-testid="drift-banner" style="background: #fff3e0; border: 1px solid #ffe0b2; padding: 8px 12px; border-radius: 4px; margin-top: 8px;">
204
+ <div class="deb-row" style="gap: 8px; align-items: center; color: #e65100; font-weight: 500;">
205
+ <mat-icon style="font-size: 18px; width:18px; height:18px;">warning</mat-icon>
206
+ <span>Source field definition has drifted!</span>
207
+ </div>
208
+ <p style="margin: 4px 0 8px 0; font-size: 12px; color: #666;">
209
+ The upstream field configuration in "{{ f.referencedEntityKey }}" has evolved.
210
+ </p>
211
+ <button
212
+ mat-flat-button
213
+ color="warn"
214
+ type="button"
215
+ data-testid="sync-source-btn"
216
+ (click)="syncWithSource(f)"
217
+ >
218
+ Sync with Source
219
+ </button>
220
+ </div>
221
+ }
222
+ }
223
+ </div>
224
+ }
225
+ `,
226
+ }]
227
+ }] });
228
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVmZXJlbmNlZC1maWVsZC1jb25maWcuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9jb21wb25lbnRzL3JlZmVyZW5jZWQtZmllbGQtY29uZmlnLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQVUsTUFBTSxlQUFlLENBQUM7QUFDcEUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDN0QsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUN0RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUV6RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7Ozs7Ozs7O0FBNkV4RCxNQUFNLE9BQU8sOEJBQThCO0lBQ3RCLEtBQUssR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDN0IsWUFBWSxHQUFHLE1BQU0sQ0FBQyxtQkFBbUIsRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBK0IsQ0FBQztJQUM3RixLQUFLLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLENBQUMs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QUFFO3dCQUNQLFlBQVk7d0JBQ1osV0FBVzt3QkFDWCxlQUFlO3dCQUNmLGdCQUFnQjt3QkFDaEIsa0JBQWtCO3dCQUNsQixhQUFhO3dCQUNiLGNBQWM7d0JBQ2Qsb0JBQW9CO3FCQUNyQjtvQkFDRCxRQUFRLEVBQUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTREVDtpQkFDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgY29tcHV0ZWQsIGluamVjdCwgc2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBNYXRCdXR0b25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9idXR0b24nO1xuaW1wb3J0IHsgTWF0RGl2aWRlck1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RpdmlkZXInO1xuaW1wb3J0IHsgTWF0Rm9ybUZpZWxkTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZm9ybS1maWVsZCc7XG5pbXBvcnQgeyBNYXRJY29uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaWNvbic7XG5pbXBvcnQgeyBNYXRJbnB1dE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2lucHV0JztcbmltcG9ydCB7IE1hdFNsaWRlVG9nZ2xlTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvc2xpZGUtdG9nZ2xlJztcbmltcG9ydCB7IENvbmZpZ1NvdXJjZVNlcnZpY2UgfSBmcm9tICduZ3gtZHluYW1pYy1lbnRpdHknO1xuaW1wb3J0IHR5cGUgeyBOZXN0ZWRGaWVsZENvbmZpZyB9IGZyb20gJ0BkeW5hbWljLWVudGl0eS9jb3JlJztcbmltcG9ydCB7IEJ1aWxkZXJTdG9yZSB9IGZyb20gJy4uL2J1aWxkZXItc3RvcmUuc2VydmljZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25neC1yZWZlcmVuY2VkLWZpZWxkLWNvbmZpZycsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGUsXG4gICAgRm9ybXNNb2R1bGUsXG4gICAgTWF0QnV0dG9uTW9kdWxlLFxuICAgIE1hdERpdmlkZXJNb2R1bGUsXG4gICAgTWF0Rm9ybUZpZWxkTW9kdWxlLFxuICAgIE1hdEljb25Nb2R1bGUsXG4gICAgTWF0SW5wdXRNb2R1bGUsXG4gICAgTWF0U2xpZGVUb2dnbGVNb2R1bGUsXG4gIF0sXG4gIHRlbXBsYXRlOiBgXG4gICAgQGlmIChmaWVsZCgpOyBhcyBmKSB7XG4gICAgICA8ZGl2IGNsYXNzPVwiZGViLXJlZmVyZW5jZWQtZmllbGRcIiBzdHlsZT1cIm1hcmdpbi10b3A6IDE2cHg7XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkZWItcm93XCIgc3R5bGU9XCJqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47IGFsaWduLWl0ZW1zOiBjZW50ZXI7IG1hcmdpbi1ib3R0b206IDhweDtcIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImRlYi1zZWN0aW9uLXRpdGxlXCIgc3R5bGU9XCJtYXJnaW46MDtcIj5SZWZlcmVuY2VkIEZpZWxkPC9zcGFuPlxuICAgICAgICAgIDxtYXQtc2xpZGUtdG9nZ2xlXG4gICAgICAgICAgICBkYXRhLXRlc3RpZD1cInRvZ2dsZS1yZWZlcmVuY2VkXCJcbiAgICAgICAgICAgIFtuZ01vZGVsXT1cImYuaXNSZWZlcmVuY2VkID8/IGZhbHNlXCJcbiAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInRvZ2dsZVJlZmVyZW5jZWQoZiwgJGV2ZW50KVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgTGlua1xuICAgICAgICAgIDwvbWF0LXNsaWRlLXRvZ2dsZT5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgQGlmIChmLmlzUmVmZXJlbmNlZCkge1xuICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBhcHBlYXJhbmNlPVwib3V0bGluZVwiIHN1YnNjcmlwdFNpemluZz1cImR5bmFtaWNcIiBjbGFzcz1cImRlYi1mdWxsXCIgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiA4cHg7XCI+XG4gICAgICAgICAgICA8bWF0LWxhYmVsPlNvdXJjZSBFbnRpdHkgS2V5PC9tYXQtbGFiZWw+XG4gICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgZGF0YS10ZXN0aWQ9XCJyZWZlcmVuY2VkLWVudGl0eS1rZXlcIlxuICAgICAgICAgICAgICBbbmdNb2RlbF09XCJmLnJlZmVyZW5jZWRFbnRpdHlLZXkgPz8gJydcIlxuICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJ1cGRhdGVFbnRpdHlLZXkoZiwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiZS5nLiBpbmRpdmlkdWFsc1wiXG4gICAgICAgICAgICAvPlxuICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiBzdWJzY3JpcHRTaXppbmc9XCJkeW5hbWljXCIgY2xhc3M9XCJkZWItZnVsbFwiIHN0eWxlPVwibWFyZ2luLWJvdHRvbTogOHB4O1wiPlxuICAgICAgICAgICAgPG1hdC1sYWJlbD5Tb3VyY2UgRmllbGQgSUQ8L21hdC1sYWJlbD5cbiAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICBtYXRJbnB1dFxuICAgICAgICAgICAgICBkYXRhLXRlc3RpZD1cInJlZmVyZW5jZWQtZmllbGQtaWRcIlxuICAgICAgICAgICAgICBbbmdNb2RlbF09XCJmLnJlZmVyZW5jZWRGaWVsZElkID8/ICcnXCJcbiAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwidXBkYXRlRmllbGRJZChmLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJlLmcuIGZpcnN0TmFtZVwiXG4gICAgICAgICAgICAvPlxuICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgICAgICBAaWYgKGYuaGFzRHJpZnQpIHtcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZWItZHJpZnQtYmFubmVyXCIgZGF0YS10ZXN0aWQ9XCJkcmlmdC1iYW5uZXJcIiBzdHlsZT1cImJhY2tncm91bmQ6ICNmZmYzZTA7IGJvcmRlcjogMXB4IHNvbGlkICNmZmUwYjI7IHBhZGRpbmc6IDhweCAxMnB4OyBib3JkZXItcmFkaXVzOiA0cHg7IG1hcmdpbi10b3A6IDhweDtcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRlYi1yb3dcIiBzdHlsZT1cImdhcDogOHB4OyBhbGlnbi1pdGVtczogY2VudGVyOyBjb2xvcjogI2U2NTEwMDsgZm9udC13ZWlnaHQ6IDUwMDtcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWljb24gc3R5bGU9XCJmb250LXNpemU6IDE4cHg7IHdpZHRoOjE4cHg7IGhlaWdodDoxOHB4O1wiPndhcm5pbmc8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgIDxzcGFuPlNvdXJjZSBmaWVsZCBkZWZpbml0aW9uIGhhcyBkcmlmdGVkITwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxwIHN0eWxlPVwibWFyZ2luOiA0cHggMCA4cHggMDsgZm9udC1zaXplOiAxMnB4OyBjb2xvcjogIzY2NjtcIj5cbiAgICAgICAgICAgICAgICBUaGUgdXBzdHJlYW0gZmllbGQgY29uZmlndXJhdGlvbiBpbiBcInt7IGYucmVmZXJlbmNlZEVudGl0eUtleSB9fVwiIGhhcyBldm9sdmVkLlxuICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICBtYXQtZmxhdC1idXR0b25cbiAgICAgICAgICAgICAgICBjb2xvcj1cIndhcm5cIlxuICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgIGRhdGEtdGVzdGlkPVwic3luYy1zb3VyY2UtYnRuXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwic3luY1dpdGhTb3VyY2UoZilcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgU3luYyB3aXRoIFNvdXJjZVxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgPC9kaXY+XG4gICAgfVxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBSZWZlcmVuY2VkRmllbGRDb25maWdDb21wb25lbnQge1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgc3RvcmUgPSBpbmplY3QoQnVpbGRlclN0b3JlKTtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGNvbmZpZ1NvdXJjZSA9IGluamVjdChDb25maWdTb3VyY2VTZXJ2aWNlLCB7IG9wdGlvbmFsOiB0cnVlIH0pIGFzIENvbmZpZ1NvdXJjZVNlcnZpY2UgfCBudWxsO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZmllbGQgPSBjb21wdXRlZCgoKSA9PiB0aGlzLnN0b3JlLnNlbGVjdGVkRmllbGQoKSk7XG5cbiAgcHJvdGVjdGVkIHRvZ2dsZVJlZmVyZW5jZWQoZmllbGQ6IE5lc3RlZEZpZWxkQ29uZmlnLCBlbmFibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKGVuYWJsZWQpIHtcbiAgICAgIHRoaXMuc3RvcmUudXBkYXRlRmllbGQoZmllbGQuaWQsIHsgaXNSZWZlcmVuY2VkOiB0cnVlIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnN0b3JlLnVubGlua1JlZmVyZW5jZWRGaWVsZChmaWVsZC5pZCk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIHVwZGF0ZUVudGl0eUtleShmaWVsZDogTmVzdGVkRmllbGRDb25maWcsIGtleTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgdHJpbW1lZCA9IGtleS50cmltKCk7XG4gICAgdGhpcy5zdG9yZS51cGRhdGVGaWVsZChmaWVsZC5pZCwgeyByZWZlcmVuY2VkRW50aXR5S2V5OiB0cmltbWVkIHx8IHVuZGVmaW5lZCB9KTtcbiAgICB0aGlzLmNoZWNrRHJpZnRGb3JGaWVsZChmaWVsZC5pZCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgdXBkYXRlRmllbGRJZChmaWVsZDogTmVzdGVkRmllbGRDb25maWcsIGZpZWxkSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHRyaW1tZWQgPSBmaWVsZElkLnRyaW0oKTtcbiAgICB0aGlzLnN0b3JlLnVwZGF0ZUZpZWxkKGZpZWxkLmlkLCB7IHJlZmVyZW5jZWRGaWVsZElkOiB0cmltbWVkIHx8IHVuZGVmaW5lZCB9KTtcbiAgICB0aGlzLmNoZWNrRHJpZnRGb3JGaWVsZChmaWVsZC5pZCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgc3luY1dpdGhTb3VyY2UoZmllbGQ6IE5lc3RlZEZpZWxkQ29uZmlnKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCFmaWVsZC5yZWZlcmVuY2VkRW50aXR5S2V5IHx8ICFmaWVsZC5yZWZlcmVuY2VkRmllbGRJZCB8fCAhdGhpcy5jb25maWdTb3VyY2UpIHJldHVybjtcbiAgICBjb25zdCBzb3VyY2VDb25maWcgPSBhd2FpdCB0aGlzLmNvbmZpZ1NvdXJjZS5nZXRDb25maWcoZmllbGQucmVmZXJlbmNlZEVudGl0eUtleSk7XG4gICAgaWYgKCFzb3VyY2VDb25maWcpIHJldHVybjtcblxuICAgIGNvbnN0IHNvdXJjZUZpZWxkID0gdGhpcy5maW5kRmllbGQoc291cmNlQ29uZmlnLnRhYnMgPz8gW10sIGZpZWxkLnJlZmVyZW5jZWRGaWVsZElkKTtcbiAgICBpZiAoc291cmNlRmllbGQpIHtcbiAgICAgIHRoaXMuc3RvcmUuc3luY1JlZmVyZW5jZWRGaWVsZChmaWVsZC5pZCwgc291cmNlRmllbGQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgY2hlY2tEcmlmdEZvckZpZWxkKGZpZWxkSWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGYgPSB0aGlzLnN0b3JlLnNlbGVjdGVkRmllbGQoKTtcbiAgICBpZiAoIWYgfHwgIWYuaXNSZWZlcmVuY2VkIHx8ICFmLnJlZmVyZW5jZWRFbnRpdHlLZXkgfHwgIWYucmVmZXJlbmNlZEZpZWxkSWQgfHwgIXRoaXMuY29uZmlnU291cmNlKSByZXR1cm47XG4gICAgY29uc3Qgc291cmNlQ29uZmlnID0gYXdhaXQgdGhpcy5jb25maWdTb3VyY2UuZ2V0Q29uZmlnKGYucmVmZXJlbmNlZEVudGl0eUtleSk7XG4gICAgaWYgKHNvdXJjZUNvbmZpZykge1xuICAgICAgdGhpcy5zdG9yZS5jaGVja0RyaWZ0KHsgW2YucmVmZXJlbmNlZEVudGl0eUtleV06IHNvdXJjZUNvbmZpZyB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGZpbmRGaWVsZCh0YWJzOiBhbnlbXSwgaWQ6IHN0cmluZyk6IE5lc3RlZEZpZWxkQ29uZmlnIHwgdW5kZWZpbmVkIHtcbiAgICBmb3IgKGNvbnN0IHQgb2YgdGFicykge1xuICAgICAgZm9yIChjb25zdCBmIG9mIHQuZmllbGRzID8/IFtdKSB7XG4gICAgICAgIGlmIChmLmlkID09PSBpZCkgcmV0dXJuIGY7XG4gICAgICAgIGlmIChmLmNoaWxkcmVuPy5sZW5ndGgpIHtcbiAgICAgICAgICBjb25zdCByZXMgPSB0aGlzLmZpbmRGaWVsZEluTGlzdChmLmNoaWxkcmVuLCBpZCk7XG4gICAgICAgICAgaWYgKHJlcykgcmV0dXJuIHJlcztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHJpdmF0ZSBmaW5kRmllbGRJbkxpc3QoZmllbGRzOiBOZXN0ZWRGaWVsZENvbmZpZ1tdLCBpZDogc3RyaW5nKTogTmVzdGVkRmllbGRDb25maWcgfCB1bmRlZmluZWQge1xuICAgIGZvciAoY29uc3QgZiBvZiBmaWVsZHMpIHtcbiAgICAgIGlmIChmLmlkID09PSBpZCkgcmV0dXJuIGY7XG4gICAgICBpZiAoZi5jaGlsZHJlbj8ubGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IHJlcyA9IHRoaXMuZmluZEZpZWxkSW5MaXN0KGYuY2hpbGRyZW4sIGlkKTtcbiAgICAgICAgaWYgKHJlcykgcmV0dXJuIHJlcztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuIl19
@@ -0,0 +1,201 @@
1
+ import { Component, EventEmitter, Input, Output } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { FormsModule } from '@angular/forms';
4
+ import { MatButtonModule } from '@angular/material/button';
5
+ import { MatFormFieldModule } from '@angular/material/form-field';
6
+ import { MatIconModule } from '@angular/material/icon';
7
+ import { MatInputModule } from '@angular/material/input';
8
+ import { MatSelectModule } from '@angular/material/select';
9
+ import * as i0 from "@angular/core";
10
+ import * as i1 from "@angular/forms";
11
+ import * as i2 from "@angular/material/button";
12
+ import * as i3 from "@angular/material/form-field";
13
+ import * as i4 from "@angular/material/icon";
14
+ import * as i5 from "@angular/material/input";
15
+ import * as i6 from "@angular/material/select";
16
+ import * as i7 from "@angular/material/core";
17
+ /**
18
+ * RuleFormComponent — dialog/panel form for creating or editing a FormRule.
19
+ */
20
+ export class RuleFormComponent {
21
+ rule = {
22
+ formConfigId: 'form-1',
23
+ fieldId: '',
24
+ conditions: [{ operator: 'EQUAL', compareType: 'value', value: '' }],
25
+ action: { type: 'visibility', value: false },
26
+ targets: [],
27
+ enabled: true,
28
+ priority: 1,
29
+ };
30
+ save = new EventEmitter();
31
+ cancel = new EventEmitter();
32
+ operators = [
33
+ 'EQUAL',
34
+ 'NOT_EQUAL',
35
+ 'CONTAINS',
36
+ 'NOT_CONTAINS',
37
+ 'STARTS_WITH',
38
+ 'ENDS_WITH',
39
+ 'IS_EMPTY',
40
+ 'IS_NOT_EMPTY',
41
+ 'LESS_THAN',
42
+ 'MORE_THAN',
43
+ 'LESS_THAN_EQUAL',
44
+ 'MORE_THAN_EQUAL',
45
+ 'DATE_BEFORE',
46
+ 'DATE_AFTER',
47
+ 'IN',
48
+ 'NOT_IN',
49
+ 'HAS_ITEMS',
50
+ 'VALUE_CHANGED',
51
+ ];
52
+ addCondition() {
53
+ this.rule.conditions.push({ operator: 'EQUAL', compareType: 'value', value: '' });
54
+ }
55
+ removeCondition(index) {
56
+ this.rule.conditions.splice(index, 1);
57
+ }
58
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RuleFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
59
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: RuleFormComponent, isStandalone: true, selector: "ngx-rule-form", inputs: { rule: "rule" }, outputs: { save: "save", cancel: "cancel" }, ngImport: i0, template: `
60
+ <div class="deb-rule-form">
61
+ <h3 class="deb-rule-form__title">{{ rule.id ? 'Edit Rule' : 'New Form Rule' }}</h3>
62
+
63
+ <!-- Trigger Field -->
64
+ <mat-form-field appearance="outline" subscriptSizing="dynamic" class="deb-full">
65
+ <mat-label>Trigger Field ID</mat-label>
66
+ <input matInput [(ngModel)]="rule.fieldId" placeholder="e.g. status" />
67
+ </mat-form-field>
68
+
69
+ <!-- Conditions -->
70
+ <div class="deb-rule-section">
71
+ <h4>Conditions</h4>
72
+ @for (cond of rule.conditions; track $index) {
73
+ <div class="deb-rule-row">
74
+ <mat-form-field appearance="outline" subscriptSizing="dynamic">
75
+ <mat-label>Operator</mat-label>
76
+ <mat-select [(ngModel)]="cond.operator">
77
+ @for (op of operators; track op) {
78
+ <mat-option [value]="op">{{ op }}</mat-option>
79
+ }
80
+ </mat-select>
81
+ </mat-form-field>
82
+ <mat-form-field appearance="outline" subscriptSizing="dynamic">
83
+ <mat-label>Value</mat-label>
84
+ <input matInput [(ngModel)]="cond.value" placeholder="Condition value" />
85
+ </mat-form-field>
86
+ <button mat-icon-button color="warn" type="button" (click)="removeCondition($index)">
87
+ <mat-icon>delete</mat-icon>
88
+ </button>
89
+ </div>
90
+ }
91
+ <button mat-stroked-button type="button" (click)="addCondition()">
92
+ <mat-icon>add</mat-icon> Add Condition
93
+ </button>
94
+ </div>
95
+
96
+ <!-- Action -->
97
+ <div class="deb-rule-section">
98
+ <h4>Action</h4>
99
+ <div class="deb-rule-row">
100
+ <mat-form-field appearance="outline" subscriptSizing="dynamic">
101
+ <mat-label>Action Type</mat-label>
102
+ <mat-select [(ngModel)]="rule.action.type">
103
+ <mat-option value="visibility">Visibility (Show/Hide)</mat-option>
104
+ <mat-option value="validation">Validation Message</mat-option>
105
+ <mat-option value="info">Info Banner</mat-option>
106
+ </mat-select>
107
+ </mat-form-field>
108
+ <mat-form-field appearance="outline" subscriptSizing="dynamic">
109
+ <mat-label>Value / Message</mat-label>
110
+ <input matInput [(ngModel)]="rule.action.value" placeholder="false to hide, or message text" />
111
+ </mat-form-field>
112
+ </div>
113
+ </div>
114
+
115
+ <div class="deb-rule-form__actions">
116
+ <button mat-button type="button" (click)="cancel.emit()">Cancel</button>
117
+ <button mat-raised-button color="primary" type="button" (click)="save.emit(rule)">Save Rule</button>
118
+ </div>
119
+ </div>
120
+ `, isInline: true, styles: [".deb-rule-form{display:flex;flex-direction:column;gap:12px;background:#fafafa;border:1px solid #e0e0e0;border-radius:8px;padding:16px}.deb-rule-form__title{margin:0 0 8px;font-size:16px;font-weight:600}.deb-full{width:100%}.deb-rule-section{display:flex;flex-direction:column;gap:8px}.deb-rule-section h4{margin:0;font-size:13px;font-weight:600;color:#555}.deb-rule-row{display:flex;gap:8px;align-items:center}.deb-rule-row>*{flex:1}.deb-rule-form__actions{display:flex;justify-content:flex-end;gap:8px;margin-top:8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i7.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }] });
121
+ }
122
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RuleFormComponent, decorators: [{
123
+ type: Component,
124
+ args: [{ selector: 'ngx-rule-form', standalone: true, imports: [
125
+ CommonModule,
126
+ FormsModule,
127
+ MatButtonModule,
128
+ MatFormFieldModule,
129
+ MatIconModule,
130
+ MatInputModule,
131
+ MatSelectModule,
132
+ ], template: `
133
+ <div class="deb-rule-form">
134
+ <h3 class="deb-rule-form__title">{{ rule.id ? 'Edit Rule' : 'New Form Rule' }}</h3>
135
+
136
+ <!-- Trigger Field -->
137
+ <mat-form-field appearance="outline" subscriptSizing="dynamic" class="deb-full">
138
+ <mat-label>Trigger Field ID</mat-label>
139
+ <input matInput [(ngModel)]="rule.fieldId" placeholder="e.g. status" />
140
+ </mat-form-field>
141
+
142
+ <!-- Conditions -->
143
+ <div class="deb-rule-section">
144
+ <h4>Conditions</h4>
145
+ @for (cond of rule.conditions; track $index) {
146
+ <div class="deb-rule-row">
147
+ <mat-form-field appearance="outline" subscriptSizing="dynamic">
148
+ <mat-label>Operator</mat-label>
149
+ <mat-select [(ngModel)]="cond.operator">
150
+ @for (op of operators; track op) {
151
+ <mat-option [value]="op">{{ op }}</mat-option>
152
+ }
153
+ </mat-select>
154
+ </mat-form-field>
155
+ <mat-form-field appearance="outline" subscriptSizing="dynamic">
156
+ <mat-label>Value</mat-label>
157
+ <input matInput [(ngModel)]="cond.value" placeholder="Condition value" />
158
+ </mat-form-field>
159
+ <button mat-icon-button color="warn" type="button" (click)="removeCondition($index)">
160
+ <mat-icon>delete</mat-icon>
161
+ </button>
162
+ </div>
163
+ }
164
+ <button mat-stroked-button type="button" (click)="addCondition()">
165
+ <mat-icon>add</mat-icon> Add Condition
166
+ </button>
167
+ </div>
168
+
169
+ <!-- Action -->
170
+ <div class="deb-rule-section">
171
+ <h4>Action</h4>
172
+ <div class="deb-rule-row">
173
+ <mat-form-field appearance="outline" subscriptSizing="dynamic">
174
+ <mat-label>Action Type</mat-label>
175
+ <mat-select [(ngModel)]="rule.action.type">
176
+ <mat-option value="visibility">Visibility (Show/Hide)</mat-option>
177
+ <mat-option value="validation">Validation Message</mat-option>
178
+ <mat-option value="info">Info Banner</mat-option>
179
+ </mat-select>
180
+ </mat-form-field>
181
+ <mat-form-field appearance="outline" subscriptSizing="dynamic">
182
+ <mat-label>Value / Message</mat-label>
183
+ <input matInput [(ngModel)]="rule.action.value" placeholder="false to hide, or message text" />
184
+ </mat-form-field>
185
+ </div>
186
+ </div>
187
+
188
+ <div class="deb-rule-form__actions">
189
+ <button mat-button type="button" (click)="cancel.emit()">Cancel</button>
190
+ <button mat-raised-button color="primary" type="button" (click)="save.emit(rule)">Save Rule</button>
191
+ </div>
192
+ </div>
193
+ `, styles: [".deb-rule-form{display:flex;flex-direction:column;gap:12px;background:#fafafa;border:1px solid #e0e0e0;border-radius:8px;padding:16px}.deb-rule-form__title{margin:0 0 8px;font-size:16px;font-weight:600}.deb-full{width:100%}.deb-rule-section{display:flex;flex-direction:column;gap:8px}.deb-rule-section h4{margin:0;font-size:13px;font-weight:600;color:#555}.deb-rule-row{display:flex;gap:8px;align-items:center}.deb-rule-row>*{flex:1}.deb-rule-form__actions{display:flex;justify-content:flex-end;gap:8px;margin-top:8px}\n"] }]
194
+ }], propDecorators: { rule: [{
195
+ type: Input
196
+ }], save: [{
197
+ type: Output
198
+ }], cancel: [{
199
+ type: Output
200
+ }] } });
201
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVsZS1mb3JtLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy9ydWxlLWZvcm0uY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdkUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7Ozs7Ozs7OztBQUkzRDs7R0FFRztBQTBISCxNQUFNLE9BQU8saUJBQWlCO0lBQ25CLElBQUksR0FBYTtRQUN4QixZQUFZLEVBQUUsUUFBUTtRQUN0QixPQUFPLEVBQUUsRUFBRTtRQUNYLFVBQVUsRUFBRSxDQUFDLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsQ0FBQztRQUNwRSxNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUU7UUFDNUMsT0FBTyxFQUFFLEVBQUU7UUFDWCxPQUFPLEVBQUUsSUFBSTtRQUNiLFFBQVEsRUFBRSxDQUFDO0tBQ1osQ0FBQztJQUVRLElBQUksR0FBRyxJQUFJLFlBQVksRUFBWSxDQUFDO0lBQ3BDLE1BQU0sR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO0lBRW5DLFNBQVMsR0FBbUI7UUFDbkMsT0FBTztRQUNQLFdBQVc7UUFDWCxVQUFVO1FBQ1YsY0FBYztRQUNkLGFBQWE7UUFDYixXQUFXO1FBQ1gsVUFBVTtRQUNWLGNBQWM7UUFDZCxXQUFXO1FBQ1gsV0FBVztRQUNYLGlCQUFpQjtRQUNqQixpQkFBaUI7UUFDakIsYUFBYTtRQUNiLFlBQVk7UUFDWixJQUFJO1FBQ0osUUFBUTtRQUNSLFdBQVc7UUFDWCxlQUFlO0tBQ2hCLENBQUM7SUFFRixZQUFZO1FBQ1YsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ3BGLENBQUM7SUFFRCxlQUFlLENBQUMsS0FBYTtRQUMzQixJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3hDLENBQUM7d0dBekNVLGlCQUFpQjs0RkFBakIsaUJBQWlCLGdKQTdHbEI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E2RFQsaWxCQXJFQyxZQUFZLDhCQUNaLFdBQVcsOG1CQUNYLGVBQWUsd1VBQ2Ysa0JBQWtCLDBTQUNsQixhQUFhLG1MQUNiLGNBQWMsMFdBQ2QsZUFBZTs7NEZBK0dOLGlCQUFpQjtrQkF6SDdCLFNBQVM7K0JBQ0UsZUFBZSxjQUNiLElBQUksV0FDUDt3QkFDUCxZQUFZO3dCQUNaLFdBQVc7d0JBQ1gsZUFBZTt3QkFDZixrQkFBa0I7d0JBQ2xCLGFBQWE7d0JBQ2IsY0FBYzt3QkFDZCxlQUFlO3FCQUNoQixZQUNTOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBNkRUOzhCQWlEUSxJQUFJO3NCQUFaLEtBQUs7Z0JBVUksSUFBSTtzQkFBYixNQUFNO2dCQUNHLE1BQU07c0JBQWYsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBNYXRCdXR0b25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9idXR0b24nO1xuaW1wb3J0IHsgTWF0Rm9ybUZpZWxkTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZm9ybS1maWVsZCc7XG5pbXBvcnQgeyBNYXRJY29uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaWNvbic7XG5pbXBvcnQgeyBNYXRJbnB1dE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2lucHV0JztcbmltcG9ydCB7IE1hdFNlbGVjdE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3NlbGVjdCc7XG5cbmltcG9ydCB0eXBlIHsgRm9ybVJ1bGUsIFJ1bGVBY3Rpb25UeXBlLCBSdWxlT3BlcmF0b3IgfSBmcm9tICdAZHluYW1pYy1lbnRpdHkvY29yZSc7XG5cbi8qKlxuICogUnVsZUZvcm1Db21wb25lbnQg4oCUIGRpYWxvZy9wYW5lbCBmb3JtIGZvciBjcmVhdGluZyBvciBlZGl0aW5nIGEgRm9ybVJ1bGUuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25neC1ydWxlLWZvcm0nLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlLFxuICAgIEZvcm1zTW9kdWxlLFxuICAgIE1hdEJ1dHRvbk1vZHVsZSxcbiAgICBNYXRGb3JtRmllbGRNb2R1bGUsXG4gICAgTWF0SWNvbk1vZHVsZSxcbiAgICBNYXRJbnB1dE1vZHVsZSxcbiAgICBNYXRTZWxlY3RNb2R1bGUsXG4gIF0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBjbGFzcz1cImRlYi1ydWxlLWZvcm1cIj5cbiAgICAgIDxoMyBjbGFzcz1cImRlYi1ydWxlLWZvcm1fX3RpdGxlXCI+e3sgcnVsZS5pZCA/ICdFZGl0IFJ1bGUnIDogJ05ldyBGb3JtIFJ1bGUnIH19PC9oMz5cblxuICAgICAgPCEtLSBUcmlnZ2VyIEZpZWxkIC0tPlxuICAgICAgPG1hdC1mb3JtLWZpZWxkIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCIgc3Vic2NyaXB0U2l6aW5nPVwiZHluYW1pY1wiIGNsYXNzPVwiZGViLWZ1bGxcIj5cbiAgICAgICAgPG1hdC1sYWJlbD5UcmlnZ2VyIEZpZWxkIElEPC9tYXQtbGFiZWw+XG4gICAgICAgIDxpbnB1dCBtYXRJbnB1dCBbKG5nTW9kZWwpXT1cInJ1bGUuZmllbGRJZFwiIHBsYWNlaG9sZGVyPVwiZS5nLiBzdGF0dXNcIiAvPlxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cblxuICAgICAgPCEtLSBDb25kaXRpb25zIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cImRlYi1ydWxlLXNlY3Rpb25cIj5cbiAgICAgICAgPGg0PkNvbmRpdGlvbnM8L2g0PlxuICAgICAgICBAZm9yIChjb25kIG9mIHJ1bGUuY29uZGl0aW9uczsgdHJhY2sgJGluZGV4KSB7XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImRlYi1ydWxlLXJvd1wiPlxuICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCIgc3Vic2NyaXB0U2l6aW5nPVwiZHluYW1pY1wiPlxuICAgICAgICAgICAgICA8bWF0LWxhYmVsPk9wZXJhdG9yPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgIDxtYXQtc2VsZWN0IFsobmdNb2RlbCldPVwiY29uZC5vcGVyYXRvclwiPlxuICAgICAgICAgICAgICAgIEBmb3IgKG9wIG9mIG9wZXJhdG9yczsgdHJhY2sgb3ApIHtcbiAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCJvcFwiPnt7IG9wIH19PC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBhcHBlYXJhbmNlPVwib3V0bGluZVwiIHN1YnNjcmlwdFNpemluZz1cImR5bmFtaWNcIj5cbiAgICAgICAgICAgICAgPG1hdC1sYWJlbD5WYWx1ZTwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgWyhuZ01vZGVsKV09XCJjb25kLnZhbHVlXCIgcGxhY2Vob2xkZXI9XCJDb25kaXRpb24gdmFsdWVcIiAvPlxuICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uIGNvbG9yPVwid2FyblwiIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwicmVtb3ZlQ29uZGl0aW9uKCRpbmRleClcIj5cbiAgICAgICAgICAgICAgPG1hdC1pY29uPmRlbGV0ZTwvbWF0LWljb24+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuICAgICAgICA8YnV0dG9uIG1hdC1zdHJva2VkLWJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImFkZENvbmRpdGlvbigpXCI+XG4gICAgICAgICAgPG1hdC1pY29uPmFkZDwvbWF0LWljb24+IEFkZCBDb25kaXRpb25cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBBY3Rpb24gLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwiZGViLXJ1bGUtc2VjdGlvblwiPlxuICAgICAgICA8aDQ+QWN0aW9uPC9oND5cbiAgICAgICAgPGRpdiBjbGFzcz1cImRlYi1ydWxlLXJvd1wiPlxuICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBhcHBlYXJhbmNlPVwib3V0bGluZVwiIHN1YnNjcmlwdFNpemluZz1cImR5bmFtaWNcIj5cbiAgICAgICAgICAgIDxtYXQtbGFiZWw+QWN0aW9uIFR5cGU8L21hdC1sYWJlbD5cbiAgICAgICAgICAgIDxtYXQtc2VsZWN0IFsobmdNb2RlbCldPVwicnVsZS5hY3Rpb24udHlwZVwiPlxuICAgICAgICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cInZpc2liaWxpdHlcIj5WaXNpYmlsaXR5IChTaG93L0hpZGUpPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cInZhbGlkYXRpb25cIj5WYWxpZGF0aW9uIE1lc3NhZ2U8L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgIDxtYXQtb3B0aW9uIHZhbHVlPVwiaW5mb1wiPkluZm8gQmFubmVyPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCIgc3Vic2NyaXB0U2l6aW5nPVwiZHluYW1pY1wiPlxuICAgICAgICAgICAgPG1hdC1sYWJlbD5WYWx1ZSAvIE1lc3NhZ2U8L21hdC1sYWJlbD5cbiAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBbKG5nTW9kZWwpXT1cInJ1bGUuYWN0aW9uLnZhbHVlXCIgcGxhY2Vob2xkZXI9XCJmYWxzZSB0byBoaWRlLCBvciBtZXNzYWdlIHRleHRcIiAvPlxuICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJkZWItcnVsZS1mb3JtX19hY3Rpb25zXCI+XG4gICAgICAgIDxidXR0b24gbWF0LWJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImNhbmNlbC5lbWl0KClcIj5DYW5jZWw8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBtYXQtcmFpc2VkLWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cInNhdmUuZW1pdChydWxlKVwiPlNhdmUgUnVsZTwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIGAsXG4gIHN0eWxlczogW1xuICAgIGBcbiAgICAgIC5kZWItcnVsZS1mb3JtIHtcbiAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgICAgZ2FwOiAxMnB4O1xuICAgICAgICBiYWNrZ3JvdW5kOiAjZmFmYWZhO1xuICAgICAgICBib3JkZXI6IDFweCBzb2xpZCAjZTBlMGUwO1xuICAgICAgICBib3JkZXItcmFkaXVzOiA4cHg7XG4gICAgICAgIHBhZGRpbmc6IDE2cHg7XG4gICAgICB9XG4gICAgICAuZGViLXJ1bGUtZm9ybV9fdGl0bGUge1xuICAgICAgICBtYXJnaW46IDAgMCA4cHggMDtcbiAgICAgICAgZm9udC1zaXplOiAxNnB4O1xuICAgICAgICBmb250LXdlaWdodDogNjAwO1xuICAgICAgfVxuICAgICAgLmRlYi1mdWxsIHtcbiAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICB9XG4gICAgICAuZGViLXJ1bGUtc2VjdGlvbiB7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICAgIGdhcDogOHB4O1xuICAgICAgfVxuICAgICAgLmRlYi1ydWxlLXNlY3Rpb24gaDQge1xuICAgICAgICBtYXJnaW46IDA7XG4gICAgICAgIGZvbnQtc2l6ZTogMTNweDtcbiAgICAgICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgICAgICAgY29sb3I6ICM1NTU7XG4gICAgICB9XG4gICAgICAuZGViLXJ1bGUtcm93IHtcbiAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgZ2FwOiA4cHg7XG4gICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICB9XG4gICAgICAuZGViLXJ1bGUtcm93ID4gKiB7XG4gICAgICAgIGZsZXg6IDE7XG4gICAgICB9XG4gICAgICAuZGViLXJ1bGUtZm9ybV9fYWN0aW9ucyB7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgIGp1c3RpZnktY29udGVudDogZmxleC1lbmQ7XG4gICAgICAgIGdhcDogOHB4O1xuICAgICAgICBtYXJnaW4tdG9wOiA4cHg7XG4gICAgICB9XG4gICAgYCxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgUnVsZUZvcm1Db21wb25lbnQge1xuICBASW5wdXQoKSBydWxlOiBGb3JtUnVsZSA9IHtcbiAgICBmb3JtQ29uZmlnSWQ6ICdmb3JtLTEnLFxuICAgIGZpZWxkSWQ6ICcnLFxuICAgIGNvbmRpdGlvbnM6IFt7IG9wZXJhdG9yOiAnRVFVQUwnLCBjb21wYXJlVHlwZTogJ3ZhbHVlJywgdmFsdWU6ICcnIH1dLFxuICAgIGFjdGlvbjogeyB0eXBlOiAndmlzaWJpbGl0eScsIHZhbHVlOiBmYWxzZSB9LFxuICAgIHRhcmdldHM6IFtdLFxuICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgcHJpb3JpdHk6IDEsXG4gIH07XG5cbiAgQE91dHB1dCgpIHNhdmUgPSBuZXcgRXZlbnRFbWl0dGVyPEZvcm1SdWxlPigpO1xuICBAT3V0cHV0KCkgY2FuY2VsID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIHJlYWRvbmx5IG9wZXJhdG9yczogUnVsZU9wZXJhdG9yW10gPSBbXG4gICAgJ0VRVUFMJyxcbiAgICAnTk9UX0VRVUFMJyxcbiAgICAnQ09OVEFJTlMnLFxuICAgICdOT1RfQ09OVEFJTlMnLFxuICAgICdTVEFSVFNfV0lUSCcsXG4gICAgJ0VORFNfV0lUSCcsXG4gICAgJ0lTX0VNUFRZJyxcbiAgICAnSVNfTk9UX0VNUFRZJyxcbiAgICAnTEVTU19USEFOJyxcbiAgICAnTU9SRV9USEFOJyxcbiAgICAnTEVTU19USEFOX0VRVUFMJyxcbiAgICAnTU9SRV9USEFOX0VRVUFMJyxcbiAgICAnREFURV9CRUZPUkUnLFxuICAgICdEQVRFX0FGVEVSJyxcbiAgICAnSU4nLFxuICAgICdOT1RfSU4nLFxuICAgICdIQVNfSVRFTVMnLFxuICAgICdWQUxVRV9DSEFOR0VEJyxcbiAgXTtcblxuICBhZGRDb25kaXRpb24oKTogdm9pZCB7XG4gICAgdGhpcy5ydWxlLmNvbmRpdGlvbnMucHVzaCh7IG9wZXJhdG9yOiAnRVFVQUwnLCBjb21wYXJlVHlwZTogJ3ZhbHVlJywgdmFsdWU6ICcnIH0pO1xuICB9XG5cbiAgcmVtb3ZlQ29uZGl0aW9uKGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLnJ1bGUuY29uZGl0aW9ucy5zcGxpY2UoaW5kZXgsIDEpO1xuICB9XG59XG4iXX0=