@sarasanalytics-com/design-system 0.0.155 → 0.0.157

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.
@@ -10,27 +10,17 @@ import { MatFormFieldModule } from '@angular/material/form-field';
10
10
  import { MatSelectModule } from '@angular/material/select';
11
11
  import { MatOptionModule } from '@angular/material/core';
12
12
  import { MatIconModule } from '@angular/material/icon';
13
+ import { trigger, style, transition, animate } from '@angular/animations';
13
14
  import * as i0 from "@angular/core";
14
15
  import * as i1 from "@ngx-formly/core";
15
16
  export class QueryBuilderFormlyComponent extends FieldArrayType {
16
- constructor() {
17
- super(...arguments);
18
- // reset(): void {
19
- // this.formControl.reset();
20
- // }
21
- /**
22
- * Duplicates the row at the given index.
23
- * A deep–clone of that row’s model is inserted right after the original row.
24
- */
25
- this.copied = false;
26
- }
27
17
  ngOnInit() {
28
18
  }
29
19
  getRowCondition(index) {
30
20
  if (index === 0)
31
21
  return 'and';
32
22
  const ruleGroup = this.formControl.at(index);
33
- return ruleGroup.get('condition')?.value || 'and';
23
+ return ruleGroup.get('logicalOperator')?.value || 'and';
34
24
  }
35
25
  /**
36
26
  * Sets the condition for a specific row
@@ -39,9 +29,9 @@ export class QueryBuilderFormlyComponent extends FieldArrayType {
39
29
  */
40
30
  setRowCondition(index, condition) {
41
31
  if (index === 0)
42
- return; // First row doesn't have a condition
32
+ return; // First row doesn't have a logical operator
43
33
  const ruleGroup = this.formControl.at(index);
44
- ruleGroup.get('condition')?.setValue(condition);
34
+ ruleGroup.get('logicalOperator')?.setValue(condition);
45
35
  }
46
36
  copyRule() {
47
37
  }
@@ -66,117 +56,121 @@ export class QueryBuilderFormlyComponent extends FieldArrayType {
66
56
  }
67
57
  return undefined;
68
58
  }
59
+ // reset(): void {
60
+ // this.formControl.reset();
61
+ // }
62
+ /**
63
+ * Duplicates the row at the given index.
64
+ * A deep–clone of that row’s model is inserted right after the original row.
65
+ */
69
66
  copy(index) {
70
67
  const rowModel = this.formControl.at(index)?.value;
71
68
  if (!rowModel)
72
69
  return;
73
- // Deep-clone model
74
- const cloned = JSON.parse(JSON.stringify(rowModel));
75
- // Insert row after the current one
76
- this.add(index + 1, cloned);
77
- // 👇 Force Formly to refresh the dynamic field
78
- const newRow = this.formControl.at(index + 1);
79
- const attr = newRow?.get('attribute')?.value;
80
- if (attr) {
81
- const attrCtrl = newRow?.get('attribute');
82
- attrCtrl.setValue(attrCtrl.value);
83
- // Re-trigger field type rebuild for filterValue
84
- const filterValueField = this.field.fieldGroup[index + 1].fieldGroup
85
- .find(f => f.key === 'filterValue');
86
- if (filterValueField) {
87
- const typeMap = {
88
- SELECT: 'sa-ng-select',
89
- STRING: 'sa-input',
90
- NUMBER: 'sa-input',
91
- DATE: 'sa-date-picker',
92
- CURRENCY: 'sa-currency-input',
93
- BOOLEAN: 'sa-ng-select',
94
- };
95
- const newType = typeMap[attr.filterType] || 'sa-input';
96
- filterValueField.type = newType;
97
- filterValueField.props = {
98
- ...this.createFieldProps(attr.filterType),
99
- hasDynamicType: true,
100
- disabled: false, // initial
101
- attribute: attr,
102
- };
103
- // 🔄 Notify Formly of type change
104
- filterValueField.options?.fieldChanges?.next({
105
- type: 'type',
106
- field: filterValueField,
107
- value: newType,
108
- });
109
- }
70
+ const clonedModel = JSON.parse(JSON.stringify(rowModel));
71
+ // Carry the value over to the new row so the onInit hook can restore it.
72
+ if (clonedModel.filterValue !== undefined) {
73
+ clonedModel._copiedValue = clonedModel.filterValue;
110
74
  }
111
- }
112
- createFieldProps(type) {
113
- switch (type) {
114
- case 'SELECT':
115
- return {
116
- placeholder: 'Select',
117
- multiple: false,
118
- bindLabel: 'label',
119
- bindValue: 'value',
120
- appearance: 'outline',
121
- isClearable: true,
122
- isSearchable: false,
123
- closeOnselect: true,
124
- required: true,
125
- disabled: false,
126
- };
127
- case 'STRING':
128
- return {
129
- placeholder: 'Enter value',
130
- appearance: 'outline',
131
- type: 'text'
132
- };
133
- case 'NUMBER':
134
- return {
135
- placeholder: 'Enter value',
136
- appearance: 'outline',
137
- type: 'number'
138
- };
139
- case 'DATE':
140
- return {
141
- placeholder: 'Select date',
142
- appearance: 'outline',
143
- type: 'date'
144
- };
145
- case 'CURRENCY':
146
- return {
147
- placeholder: 'Enter value',
148
- appearance: 'outline',
149
- };
150
- case 'BOOLEAN':
151
- return {
152
- placeholder: 'Enter value',
153
- appearance: 'outline',
154
- type: 'boolean',
155
- options: [
156
- { value: true, label: 'True' },
157
- { value: false, label: 'False' },
158
- ],
159
- bindLabel: 'label',
160
- bindValue: 'value',
161
- disabled: false,
162
- };
163
- default:
164
- return {
165
- placeholder: 'Enter value',
166
- appearance: 'outline',
167
- };
75
+ // If copying the first row (index 0), the new row (index 1) should have a logical operator
76
+ // Set default logical operator to 'and' for the new row
77
+ if (index === 0) {
78
+ clonedModel.logicalOperator = 'and';
168
79
  }
80
+ this.add(index + 1, clonedModel);
81
+ // Force rebuild of the filterValue field by triggering attribute change
82
+ setTimeout(() => {
83
+ const newRowForm = this.formControl.at(index + 1);
84
+ const attrCtrl = newRowForm?.get('attribute');
85
+ const filterValueCtrl = newRowForm?.get('filterValue');
86
+ if (attrCtrl && filterValueCtrl && clonedModel.attribute) {
87
+ // Store the copied value in the form model before triggering rebuild
88
+ const copiedValue = clonedModel._copiedValue;
89
+ // Temporarily clear the attribute to force a change event
90
+ attrCtrl.setValue(null, { emitEvent: false });
91
+ // Then restore it to trigger the field type rebuild
92
+ setTimeout(() => {
93
+ attrCtrl.setValue(clonedModel.attribute, { emitEvent: true });
94
+ // Ensure the copied value is still available after the rebuild
95
+ setTimeout(() => {
96
+ if (copiedValue !== undefined && !newRowForm.value._copiedValue) {
97
+ // Re-add the copied value if it was lost during rebuild
98
+ newRowForm.patchValue({ _copiedValue: copiedValue });
99
+ filterValueCtrl.setValue(copiedValue);
100
+ }
101
+ }, 50);
102
+ }, 10);
103
+ }
104
+ });
169
105
  }
170
106
  reset() {
171
107
  this.field.fieldGroup.splice(0, this.field.fieldGroup.length); // clear
172
108
  this.add(); // start fresh with one row
173
109
  }
174
110
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: QueryBuilderFormlyComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
175
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.2.4", type: QueryBuilderFormlyComponent, isStandalone: true, selector: "sa-query-builder-formly", providers: [], usesInheritance: true, ngImport: i0, template: "<div class=\"sa-query-builder-container\">\n <div class=\"query-builder-body\">\n @for(subField of field.fieldGroup; track $index) {\n <div class=\"row align-items-baseline\">\n @if ($index === 0) {\n <span class=\"where-text flex-1\">Where</span>\n }\n @for (subField of subField.fieldGroup; track $index) {\n @if(!!subField.props['hasDynamicType']){\n @switch (getFilterType(subField)) {\n @case ('STRING') {\n <formly-field [field]=\"subField\"></formly-field>\n }\n @case ('NUMBER') {\n <formly-field [field]=\"subField\"></formly-field>\n }\n @case ('BOOLEAN') {\n <formly-field [field]=\"subField\"></formly-field>\n }\n @case ('CURRENCY') {\n <formly-field [field]=\"subField\"></formly-field>\n }\n @case ('DATE') {\n\n }\n @case ('SELECT') {\n <formly-field [field]=\"createField(subField)\"></formly-field>\n }\n @default {\n <formly-field [field]=\"createField(subField)\"></formly-field>\n }\n }\n }@else{\n <formly-field\n class=\"col\"\n [field]=\"subField\"\n >\n </formly-field>\n }\n }\n @if(props?.['showCopyButton']){\n <sa-icon icon=\"copyOutlined\" class=\"copy-icon pointer\" (click)=\"copy($index)\"></sa-icon>\n }\n <sa-icon icon=\"deleteIcon\" class=\"delete-icon pointer\" (click)=\"remove($index)\"></sa-icon>\n </div>\n }\n \n <!-- Buttons -->\n <div class=\"rule-button-container\">\n <sa-button icon=\"add\" iconPosition=\"left\" text=\"Add filter\"\n (onClickEvent)=\"add()\"\n [state]=\"field?.fieldGroup?.length === (props?.['maxRows'] || 5) ? 'disabled' : 'default'\"\n type=\"outline\" size=\"medium\">\n </sa-button>\n <span class=\"filters-count\">({{field?.fieldGroup?.length}}/{{props?.['maxRows'] || 5}} filters)</span>\n @if(props?.['showResetButton']){\n <sa-button iconPosition=\"left\" text=\"Reset\"\n (onClickEvent)=\"reset()\"\n type=\"primary\" size=\"medium\">\n </sa-button>\n }\n </div> \n </div>\n</div>", styles: [".sa-query-builder-container{display:flex}.sa-query-builder-container .query-builder-body{display:flex;flex-direction:column;gap:var(--small-12px);width:-webkit-fill-available}.query-builder-body .row{display:flex;height:2.25rem;justify-content:center;align-items:center;flex:1 0 0;gap:var(--small-8px);width:-webkit-fill-available}.query-builder-form-wrapper{width:-webkit-fill-available}::ng-deep .query-builder-form-wrapper .sa-input-field.idle{border-radius:var(--small-4px);border:1px solid var(--grey-100, #EAECF0);background:var(--white, #FFF);height:2.438rem}::ng-deep .query-builder-form-wrapper .sa-input-container{height:3.438rem}::ng-deep .query-builder-form-wrapper .sa-input-container .disabled .sa-input-field input{color:var(--text-low-emphasis, #9B98A3);font-family:var(--font-family, Roboto);font-size:13px;font-style:normal;font-weight:400;line-height:var(--medium-20px);letter-spacing:.25px}.where-text{color:var(--text-medium-emphasis, #6D6979);font-family:var(--font-family-roboto);font-size:var(--small-14px);font-style:normal;font-weight:var(--font-weight-500);line-height:var(--medium-20px);letter-spacing:.1px;width:80px}.flex-1{flex:1 1 0;min-width:80px}.flex-2{flex:2 1 0;min-width:120px}.flex-4{flex:4 1 0;min-width:200px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: FormlyModule }, { kind: "component", type: i1.FormlyField, selector: "formly-field", inputs: ["field"] }, { kind: "component", type: ButtonComponent, selector: "sa-button", inputs: ["id", "type", "state", "size", "text", "ImagePath", "icon", "iconPosition", "href", "hrefTarget", "width", "isSubmit", "buttonIconSize", "showSpinner"], outputs: ["onClickEvent", "onMouseInEvent", "onMouseOutEvent"] }, { kind: "component", type: IconComponent, selector: "sa-icon", inputs: ["img", "icon", "size", "color", "iconPath", "iconUrl", "customClass", "href", "hrefTarget", "iconPosition"], outputs: ["onClickEvent"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "ngmodule", type: MatOptionModule }, { kind: "ngmodule", type: MatIconModule }] }); }
111
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.2.4", type: QueryBuilderFormlyComponent, isStandalone: true, selector: "sa-query-builder-formly", providers: [], usesInheritance: true, ngImport: i0, template: "<div class=\"sa-query-builder-container\">\n <div class=\"query-builder-body\">\n @for(subField of field.fieldGroup; track subField.id || $index) {\n <div class=\"row align-items-baseline query-row\" [@rowAnimation]>\n @if ($index === 0) {\n <span class=\"where-text flex-1\">Where</span>\n }\n @for (innerField of subField.fieldGroup; track innerField.key || $index) {\n @if(!!innerField.props['hasDynamicType']){\n @switch (getFilterType(innerField)) {\n @case ('STRING') {\n <formly-field [field]=\"innerField\"></formly-field>\n }\n @case ('NUMBER') {\n <formly-field [field]=\"innerField\"></formly-field>\n }\n @case ('BOOLEAN') {\n <formly-field [field]=\"innerField\"></formly-field>\n }\n @case ('CURRENCY') {\n <formly-field [field]=\"innerField\"></formly-field>\n }\n @case ('DATE') {\n\n }\n @case ('SELECT') {\n <formly-field [field]=\"createField(innerField)\"></formly-field>\n }\n @default {\n <formly-field [field]=\"createField(innerField)\"></formly-field>\n }\n }\n }@else{\n <formly-field\n class=\"col\"\n [field]=\"innerField\"\n >\n </formly-field>\n }\n }\n @if(props?.['showCopyButton']){\n <sa-icon icon=\"copyOutlined\" class=\"copy-icon pointer\" (click)=\"copy($index)\"></sa-icon>\n }\n <sa-icon icon=\"deleteIcon\" class=\"delete-icon pointer\" (click)=\"remove($index)\"></sa-icon>\n </div>\n }\n \n <!-- Buttons -->\n <div class=\"rule-button-container\">\n <sa-button icon=\"add\" iconPosition=\"left\" text=\"Add filter\"\n (onClickEvent)=\"add()\"\n [state]=\"field?.fieldGroup?.length === (props?.['maxRows'] || 5) ? 'disabled' : 'default'\"\n type=\"outline\" size=\"medium\">\n </sa-button>\n <span class=\"filters-count\">({{field?.fieldGroup?.length}}/{{props?.['maxRows'] || 5}} filters)</span>\n @if(props?.['showResetButton']){\n <sa-button iconPosition=\"left\" text=\"Reset\"\n (onClickEvent)=\"reset()\"\n type=\"primary\" size=\"medium\">\n </sa-button>\n }\n </div> \n </div>\n</div>", styles: [".sa-query-builder-container{display:flex}.sa-query-builder-container .query-builder-body{display:flex;flex-direction:column;gap:var(--small-12px);width:-webkit-fill-available}.query-builder-body .row{display:flex;height:2.25rem;justify-content:center;align-items:center;flex:1 0 0;gap:var(--small-8px);width:-webkit-fill-available}.query-row{transition:all .2s ease-in-out;border-radius:var(--small-4px);padding:var(--small-4px);margin:2px 0}.query-row:hover{transform:translate(2px)}.query-row ::ng-deep .query-builder-form-wrapper{transition:all .15s ease-in-out}.query-builder-form-wrapper{width:-webkit-fill-available}::ng-deep .query-builder-form-wrapper .sa-input-field.idle{border-radius:var(--small-4px);border:1px solid var(--grey-100, #EAECF0);background:var(--white, #FFF);height:2.438rem}::ng-deep .query-builder-form-wrapper .sa-input-container{height:3.438rem}::ng-deep .query-builder-form-wrapper .sa-input-container .disabled .sa-input-field input{color:var(--text-low-emphasis, #9B98A3);font-family:var(--font-family, Roboto);font-size:13px;font-style:normal;font-weight:400;line-height:var(--medium-20px);letter-spacing:.25px}.where-text{color:var(--text-medium-emphasis, #6D6979);font-family:var(--font-family-roboto);font-size:var(--small-14px);font-style:normal;font-weight:var(--font-weight-500);line-height:var(--medium-20px);letter-spacing:.1px;width:80px}.flex-1{flex:1 1 0;min-width:80px}.flex-2{flex:2 1 0;min-width:120px}.flex-4{flex:4 1 0;min-width:200px}.copy-icon,.delete-icon{transition:all .2s ease-in-out;padding:4px;border-radius:4px;opacity:.7}.copy-icon:hover,.delete-icon:hover{opacity:1;transform:scale(1.1);background-color:#0000000d}.copy-icon:active,.delete-icon:active{transform:scale(.95)}.copy-icon:hover{color:var(--primary-500, #7C3AED)}.delete-icon:hover{color:var(--error-500, #EF4444)}.rule-button-container{transition:all .2s ease-in-out}.rule-button-container sa-button{transition:all .2s ease-in-out}.rule-button-container sa-button:hover{transform:translateY(-1px)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: FormlyModule }, { kind: "component", type: i1.FormlyField, selector: "formly-field", inputs: ["field"] }, { kind: "component", type: ButtonComponent, selector: "sa-button", inputs: ["id", "type", "state", "size", "text", "ImagePath", "icon", "iconPosition", "href", "hrefTarget", "width", "isSubmit", "buttonIconSize", "showSpinner"], outputs: ["onClickEvent", "onMouseInEvent", "onMouseOutEvent"] }, { kind: "component", type: IconComponent, selector: "sa-icon", inputs: ["img", "icon", "size", "color", "iconPath", "iconUrl", "customClass", "href", "hrefTarget", "iconPosition"], outputs: ["onClickEvent"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "ngmodule", type: MatOptionModule }, { kind: "ngmodule", type: MatIconModule }], animations: [
112
+ trigger('rowAnimation', [
113
+ transition(':enter', [
114
+ style({
115
+ opacity: 0,
116
+ transform: 'translateY(-10px) scale(0.95)',
117
+ height: '0px',
118
+ overflow: 'hidden'
119
+ }),
120
+ animate('300ms cubic-bezier(0.4, 0.0, 0.2, 1)', style({
121
+ opacity: 1,
122
+ transform: 'translateY(0) scale(1)',
123
+ height: '*'
124
+ }))
125
+ ]),
126
+ transition(':leave', [
127
+ style({
128
+ opacity: 1,
129
+ transform: 'translateY(0) scale(1)',
130
+ height: '*'
131
+ }),
132
+ animate('250ms cubic-bezier(0.4, 0.0, 0.2, 1)', style({
133
+ opacity: 0,
134
+ transform: 'translateY(-10px) scale(0.95)',
135
+ height: '0px',
136
+ overflow: 'hidden'
137
+ }))
138
+ ])
139
+ ])
140
+ ] }); }
176
141
  }
177
142
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: QueryBuilderFormlyComponent, decorators: [{
178
143
  type: Component,
179
- args: [{ selector: 'sa-query-builder-formly', standalone: true, providers: [], imports: [
144
+ args: [{ selector: 'sa-query-builder-formly', standalone: true, providers: [], animations: [
145
+ trigger('rowAnimation', [
146
+ transition(':enter', [
147
+ style({
148
+ opacity: 0,
149
+ transform: 'translateY(-10px) scale(0.95)',
150
+ height: '0px',
151
+ overflow: 'hidden'
152
+ }),
153
+ animate('300ms cubic-bezier(0.4, 0.0, 0.2, 1)', style({
154
+ opacity: 1,
155
+ transform: 'translateY(0) scale(1)',
156
+ height: '*'
157
+ }))
158
+ ]),
159
+ transition(':leave', [
160
+ style({
161
+ opacity: 1,
162
+ transform: 'translateY(0) scale(1)',
163
+ height: '*'
164
+ }),
165
+ animate('250ms cubic-bezier(0.4, 0.0, 0.2, 1)', style({
166
+ opacity: 0,
167
+ transform: 'translateY(-10px) scale(0.95)',
168
+ height: '0px',
169
+ overflow: 'hidden'
170
+ }))
171
+ ])
172
+ ])
173
+ ], imports: [
180
174
  CommonModule,
181
175
  ReactiveFormsModule,
182
176
  FormlyModule,
@@ -186,6 +180,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImpor
186
180
  MatSelectModule,
187
181
  MatOptionModule,
188
182
  MatIconModule
189
- ], template: "<div class=\"sa-query-builder-container\">\n <div class=\"query-builder-body\">\n @for(subField of field.fieldGroup; track $index) {\n <div class=\"row align-items-baseline\">\n @if ($index === 0) {\n <span class=\"where-text flex-1\">Where</span>\n }\n @for (subField of subField.fieldGroup; track $index) {\n @if(!!subField.props['hasDynamicType']){\n @switch (getFilterType(subField)) {\n @case ('STRING') {\n <formly-field [field]=\"subField\"></formly-field>\n }\n @case ('NUMBER') {\n <formly-field [field]=\"subField\"></formly-field>\n }\n @case ('BOOLEAN') {\n <formly-field [field]=\"subField\"></formly-field>\n }\n @case ('CURRENCY') {\n <formly-field [field]=\"subField\"></formly-field>\n }\n @case ('DATE') {\n\n }\n @case ('SELECT') {\n <formly-field [field]=\"createField(subField)\"></formly-field>\n }\n @default {\n <formly-field [field]=\"createField(subField)\"></formly-field>\n }\n }\n }@else{\n <formly-field\n class=\"col\"\n [field]=\"subField\"\n >\n </formly-field>\n }\n }\n @if(props?.['showCopyButton']){\n <sa-icon icon=\"copyOutlined\" class=\"copy-icon pointer\" (click)=\"copy($index)\"></sa-icon>\n }\n <sa-icon icon=\"deleteIcon\" class=\"delete-icon pointer\" (click)=\"remove($index)\"></sa-icon>\n </div>\n }\n \n <!-- Buttons -->\n <div class=\"rule-button-container\">\n <sa-button icon=\"add\" iconPosition=\"left\" text=\"Add filter\"\n (onClickEvent)=\"add()\"\n [state]=\"field?.fieldGroup?.length === (props?.['maxRows'] || 5) ? 'disabled' : 'default'\"\n type=\"outline\" size=\"medium\">\n </sa-button>\n <span class=\"filters-count\">({{field?.fieldGroup?.length}}/{{props?.['maxRows'] || 5}} filters)</span>\n @if(props?.['showResetButton']){\n <sa-button iconPosition=\"left\" text=\"Reset\"\n (onClickEvent)=\"reset()\"\n type=\"primary\" size=\"medium\">\n </sa-button>\n }\n </div> \n </div>\n</div>", styles: [".sa-query-builder-container{display:flex}.sa-query-builder-container .query-builder-body{display:flex;flex-direction:column;gap:var(--small-12px);width:-webkit-fill-available}.query-builder-body .row{display:flex;height:2.25rem;justify-content:center;align-items:center;flex:1 0 0;gap:var(--small-8px);width:-webkit-fill-available}.query-builder-form-wrapper{width:-webkit-fill-available}::ng-deep .query-builder-form-wrapper .sa-input-field.idle{border-radius:var(--small-4px);border:1px solid var(--grey-100, #EAECF0);background:var(--white, #FFF);height:2.438rem}::ng-deep .query-builder-form-wrapper .sa-input-container{height:3.438rem}::ng-deep .query-builder-form-wrapper .sa-input-container .disabled .sa-input-field input{color:var(--text-low-emphasis, #9B98A3);font-family:var(--font-family, Roboto);font-size:13px;font-style:normal;font-weight:400;line-height:var(--medium-20px);letter-spacing:.25px}.where-text{color:var(--text-medium-emphasis, #6D6979);font-family:var(--font-family-roboto);font-size:var(--small-14px);font-style:normal;font-weight:var(--font-weight-500);line-height:var(--medium-20px);letter-spacing:.1px;width:80px}.flex-1{flex:1 1 0;min-width:80px}.flex-2{flex:2 1 0;min-width:120px}.flex-4{flex:4 1 0;min-width:200px}\n"] }]
183
+ ], template: "<div class=\"sa-query-builder-container\">\n <div class=\"query-builder-body\">\n @for(subField of field.fieldGroup; track subField.id || $index) {\n <div class=\"row align-items-baseline query-row\" [@rowAnimation]>\n @if ($index === 0) {\n <span class=\"where-text flex-1\">Where</span>\n }\n @for (innerField of subField.fieldGroup; track innerField.key || $index) {\n @if(!!innerField.props['hasDynamicType']){\n @switch (getFilterType(innerField)) {\n @case ('STRING') {\n <formly-field [field]=\"innerField\"></formly-field>\n }\n @case ('NUMBER') {\n <formly-field [field]=\"innerField\"></formly-field>\n }\n @case ('BOOLEAN') {\n <formly-field [field]=\"innerField\"></formly-field>\n }\n @case ('CURRENCY') {\n <formly-field [field]=\"innerField\"></formly-field>\n }\n @case ('DATE') {\n\n }\n @case ('SELECT') {\n <formly-field [field]=\"createField(innerField)\"></formly-field>\n }\n @default {\n <formly-field [field]=\"createField(innerField)\"></formly-field>\n }\n }\n }@else{\n <formly-field\n class=\"col\"\n [field]=\"innerField\"\n >\n </formly-field>\n }\n }\n @if(props?.['showCopyButton']){\n <sa-icon icon=\"copyOutlined\" class=\"copy-icon pointer\" (click)=\"copy($index)\"></sa-icon>\n }\n <sa-icon icon=\"deleteIcon\" class=\"delete-icon pointer\" (click)=\"remove($index)\"></sa-icon>\n </div>\n }\n \n <!-- Buttons -->\n <div class=\"rule-button-container\">\n <sa-button icon=\"add\" iconPosition=\"left\" text=\"Add filter\"\n (onClickEvent)=\"add()\"\n [state]=\"field?.fieldGroup?.length === (props?.['maxRows'] || 5) ? 'disabled' : 'default'\"\n type=\"outline\" size=\"medium\">\n </sa-button>\n <span class=\"filters-count\">({{field?.fieldGroup?.length}}/{{props?.['maxRows'] || 5}} filters)</span>\n @if(props?.['showResetButton']){\n <sa-button iconPosition=\"left\" text=\"Reset\"\n (onClickEvent)=\"reset()\"\n type=\"primary\" size=\"medium\">\n </sa-button>\n }\n </div> \n </div>\n</div>", styles: [".sa-query-builder-container{display:flex}.sa-query-builder-container .query-builder-body{display:flex;flex-direction:column;gap:var(--small-12px);width:-webkit-fill-available}.query-builder-body .row{display:flex;height:2.25rem;justify-content:center;align-items:center;flex:1 0 0;gap:var(--small-8px);width:-webkit-fill-available}.query-row{transition:all .2s ease-in-out;border-radius:var(--small-4px);padding:var(--small-4px);margin:2px 0}.query-row:hover{transform:translate(2px)}.query-row ::ng-deep .query-builder-form-wrapper{transition:all .15s ease-in-out}.query-builder-form-wrapper{width:-webkit-fill-available}::ng-deep .query-builder-form-wrapper .sa-input-field.idle{border-radius:var(--small-4px);border:1px solid var(--grey-100, #EAECF0);background:var(--white, #FFF);height:2.438rem}::ng-deep .query-builder-form-wrapper .sa-input-container{height:3.438rem}::ng-deep .query-builder-form-wrapper .sa-input-container .disabled .sa-input-field input{color:var(--text-low-emphasis, #9B98A3);font-family:var(--font-family, Roboto);font-size:13px;font-style:normal;font-weight:400;line-height:var(--medium-20px);letter-spacing:.25px}.where-text{color:var(--text-medium-emphasis, #6D6979);font-family:var(--font-family-roboto);font-size:var(--small-14px);font-style:normal;font-weight:var(--font-weight-500);line-height:var(--medium-20px);letter-spacing:.1px;width:80px}.flex-1{flex:1 1 0;min-width:80px}.flex-2{flex:2 1 0;min-width:120px}.flex-4{flex:4 1 0;min-width:200px}.copy-icon,.delete-icon{transition:all .2s ease-in-out;padding:4px;border-radius:4px;opacity:.7}.copy-icon:hover,.delete-icon:hover{opacity:1;transform:scale(1.1);background-color:#0000000d}.copy-icon:active,.delete-icon:active{transform:scale(.95)}.copy-icon:hover{color:var(--primary-500, #7C3AED)}.delete-icon:hover{color:var(--error-500, #EF4444)}.rule-button-container{transition:all .2s ease-in-out}.rule-button-container sa-button{transition:all .2s ease-in-out}.rule-button-container sa-button:hover{transform:translateY(-1px)}\n"] }]
190
184
  }] });
191
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcnktYnVpbGRlci1mb3JtbHkuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29tcG9uZW50LWxpYnJhcnkvc3JjL2xpYi9xdWVyeS1idWlsZGVyLWZvcm1seS9xdWVyeS1idWlsZGVyLWZvcm1seS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnQtbGlicmFyeS9zcmMvbGliL3F1ZXJ5LWJ1aWxkZXItZm9ybWx5L3F1ZXJ5LWJ1aWxkZXItZm9ybWx5LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsTUFBTSxlQUFlLENBQUM7QUFDbEQsT0FBTyxFQUFFLGNBQWMsRUFBcUIsTUFBTSxrQkFBa0IsQ0FBQztBQUNyRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2hELE9BQU8sRUFBYSxtQkFBbUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQ25DLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdkQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbEUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzNELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN6RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7OztBQXFCdkQsTUFBTSxPQUFPLDJCQUE0QixTQUFRLGNBQWM7SUFsQi9EOztRQXVFRSxr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SjtnQkFDRSxPQUFPO29CQUNMLFdBQVcsRUFBRSxhQUFhO29CQUMxQixVQUFVLEVBQUUsU0FBUztpQkFDdEIsQ0FBQztRQUNOLENBQUM7SUFDSCxDQUFDO0lBRUQsS0FBSztRQUNILElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxRQUFRO1FBQ3ZFLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLDJCQUEyQjtJQUN6QyxDQUFDOzhHQS9LVSwyQkFBMkI7a0dBQTNCLDJCQUEyQixzRUFiM0IsRUFBRSxpRENuQmYseTRFQStETSw2eENEMUNGLFlBQVksOEJBQ1osbUJBQW1CLDhCQUNuQixZQUFZLHlIQUNaLGVBQWUsd1JBQ2YsYUFBYSxvTUFDYixrQkFBa0IsOEJBQ2xCLGVBQWUsOEJBQ2YsZUFBZSw4QkFDZixhQUFhOzsyRkFHSiwyQkFBMkI7a0JBbEJ2QyxTQUFTOytCQUNFLHlCQUF5QixjQUd2QixJQUFJLGFBQ0wsRUFBRSxXQUNKO3dCQUNQLFlBQVk7d0JBQ1osbUJBQW1CO3dCQUNuQixZQUFZO3dCQUNaLGVBQWU7d0JBQ2YsYUFBYTt3QkFDYixrQkFBa0I7d0JBQ2xCLGVBQWU7d0JBQ2YsZUFBZTt3QkFDZixhQUFhO3FCQUNkIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZpZWxkQXJyYXlUeXBlLCBGb3JtbHlGaWVsZENvbmZpZyB9IGZyb20gJ0BuZ3gtZm9ybWx5L2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJzsgXG5pbXBvcnQgeyBGb3JtbHlNb2R1bGUgfSBmcm9tICdAbmd4LWZvcm1seS9jb3JlJztcbmltcG9ydCB7IEZvcm1Hcm91cCwgUmVhY3RpdmVGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IGdldCwga2V5cyB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBCdXR0b25Db21wb25lbnQgfSBmcm9tICcuLi9idXR0b24vYnV0dG9uLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBJY29uQ29tcG9uZW50IH0gZnJvbSAnLi4vaWNvbi9pY29uLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBNYXRGb3JtRmllbGRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9mb3JtLWZpZWxkJztcbmltcG9ydCB7IE1hdFNlbGVjdE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3NlbGVjdCc7XG5pbXBvcnQgeyBNYXRPcHRpb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9jb3JlJztcbmltcG9ydCB7IE1hdEljb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pY29uJztcblxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdzYS1xdWVyeS1idWlsZGVyLWZvcm1seScsXG4gIHRlbXBsYXRlVXJsOiAnLi9xdWVyeS1idWlsZGVyLWZvcm1seS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3F1ZXJ5LWJ1aWxkZXItZm9ybWx5LmNvbXBvbmVudC5zY3NzJ10sXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIHByb3ZpZGVyczogW10sXG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGUsXG4gICAgUmVhY3RpdmVGb3Jtc01vZHVsZSxcbiAgICBGb3JtbHlNb2R1bGUsXG4gICAgQnV0dG9uQ29tcG9uZW50LFxuICAgIEljb25Db21wb25lbnQsXG4gICAgTWF0Rm9ybUZpZWxkTW9kdWxlLFxuICAgIE1hdFNlbGVjdE1vZHVsZSxcbiAgICBNYXRPcHRpb25Nb2R1bGUsXG4gICAgTWF0SWNvbk1vZHVsZSAgICBcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBRdWVyeUJ1aWxkZXJGb3JtbHlDb21wb25lbnQgZXh0ZW5kcyBGaWVsZEFycmF5VHlwZSBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIFxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBcbiAgICBcbiAgfVxuICBcbiAgZ2V0Um93Q29uZGl0aW9uKGluZGV4OiBudW1iZXIpOiAnYW5kJyB8ICdvcicge1xuICAgICAgaWYgKGluZGV4ID09PSAwKSByZXR1cm4gJ2FuZCc7IFxuICAgICAgXG4gICAgICBjb25zdCBydWxlR3JvdXAgPSB0aGlzLmZvcm1Db250cm9sLmF0KGluZGV4KSBhcyBGb3JtR3JvdXA7XG4gICAgICByZXR1cm4gcnVsZUdyb3VwLmdldCgnY29uZGl0aW9uJyk/LnZhbHVlIHx8ICdhbmQnO1xuICAgIH1cblxuICAgIC8qKlxuICAgKiBTZXRzIHRoZSBjb25kaXRpb24gZm9yIGEgc3BlY2lmaWMgcm93XG4gICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHJvd1xuICAgKiBAcGFyYW0gY29uZGl0aW9uIFRoZSBjb25kaXRpb24gdG8gc2V0IChhbmQvb3IpXG4gICAqL1xuICBzZXRSb3dDb25kaXRpb24oaW5kZXg6IG51bWJlciwgY29uZGl0aW9uOiAnYW5kJyB8ICdvcicpOiB2b2lkIHtcbiAgICBpZiAoaW5kZXggPT09IDApIHJldHVybjsgLy8gRmlyc3Qgcm93IGRvZXNuJ3QgaGF2ZSBhIGNvbmRpdGlvblxuICAgIFxuICAgIGNvbnN0IHJ1bGVHcm91cCA9IHRoaXMuZm9ybUNvbnRyb2wuYXQoaW5kZXgpIGFzIEZvcm1Hcm91cDtcbiAgICBydWxlR3JvdXAuZ2V0KCdjb25kaXRpb24nKT8uc2V0VmFsdWUoY29uZGl0aW9uKTtcbiAgfVxuXG4gIGNvcHlSdWxlKCk6IHZvaWQge1xuICAgIFxuICB9XG5cbiAgY3JlYXRlRmllbGQoZmllbGQ6IEZvcm1seUZpZWxkQ29uZmlnKTogRm9ybWx5RmllbGRDb25maWcge1xuICAgIGlmKGZpZWxkLnR5cGUgPT09ICdkeW5hbWljLXR5cGUnIHx8IGZpZWxkLnR5cGUgPT09ICcnKSB7XG4gICAgICBmaWVsZC50eXBlID0gJ3NhLWlucHV0JztcbiAgICAgIGZpZWxkLnByb3BzLnR5cGUgPSAndGV4dCc7XG4gICAgICBmaWVsZC5wcm9wcy5wbGFjZWhvbGRlciA9ICdFbnRlci9TZWxlY3QnO1xuICAgIH1cbiAgICByZXR1cm4gZmllbGQ7XG4gIH1cblxuICBnZXRGaWx0ZXJUeXBlKHN1YkZpZWxkOiBGb3JtbHlGaWVsZENvbmZpZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgcGFyZW50VmFsdWUgPSBnZXQoc3ViRmllbGQsICdmb3JtQ29udHJvbC5wYXJlbnQudmFsdWUnKTtcbiAgICBpZiAoIXBhcmVudFZhbHVlKSByZXR1cm4gdW5kZWZpbmVkO1xuICBcbiAgICAvLyBMb29rIHRocm91Z2ggYWxsIGtleXMgb2YgdGhlIHBhcmVudCB2YWx1ZVxuICAgIGZvciAoY29uc3Qga2V5IG9mIGtleXMocGFyZW50VmFsdWUpKSB7XG4gICAgICBjb25zdCB2YWwgPSBwYXJlbnRWYWx1ZVtrZXldO1xuICAgICAgaWYgKHZhbCAmJiB0eXBlb2YgdmFsID09PSAnb2JqZWN0JyAmJiAnZmlsdGVyVHlwZScgaW4gdmFsKSB7XG4gICAgICAgIHJldHVybiB2YWwuZmlsdGVyVHlwZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8vIHJlc2V0KCk6IHZvaWQge1xuICAvLyAgIHRoaXMuZm9ybUNvbnRyb2wucmVzZXQoKTtcbiAgLy8gfVxuXG4gIC8qKlxuICAgKiBEdXBsaWNhdGVzIHRoZSByb3cgYXQgdGhlIGdpdmVuIGluZGV4LlxuICAgKiBBIGRlZXDigJNjbG9uZSBvZiB0aGF0IHJvd+KAmXMgbW9kZWwgaXMgaW5zZXJ0ZWQgcmlnaHQgYWZ0ZXIgdGhlIG9yaWdpbmFsIHJvdy5cbiAgICovXG4gIGNvcGllZDogYm9vbGVhbiA9IGZhbHNlO1xuICBjb3B5KGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCByb3dNb2RlbCA9IHRoaXMuZm9ybUNvbnRyb2wuYXQoaW5kZXgpPy52YWx1ZTtcbiAgICBpZiAoIXJvd01vZGVsKSByZXR1cm47XG4gIFxuICAgIC8vIERlZXAtY2xvbmUgbW9kZWxcbiAgICBjb25zdCBjbG9uZWQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHJvd01vZGVsKSk7XG4gIFxuICAgIC8vIEluc2VydCByb3cgYWZ0ZXIgdGhlIGN1cnJlbnQgb25lXG4gICAgdGhpcy5hZGQoaW5kZXggKyAxLCBjbG9uZWQpO1xuICBcbiAgICAvLyDwn5GHIEZvcmNlIEZvcm1seSB0byByZWZyZXNoIHRoZSBkeW5hbWljIGZpZWxkXG4gICAgY29uc3QgbmV3Um93ID0gdGhpcy5mb3JtQ29udHJvbC5hdChpbmRleCArIDEpO1xuICAgIGNvbnN0IGF0dHIgPSBuZXdSb3c/LmdldCgnYXR0cmlidXRlJyk/LnZhbHVlO1xuICBcbiAgICBpZiAoYXR0cikge1xuICAgICAgY29uc3QgYXR0ckN0cmwgPSBuZXdSb3c/LmdldCgnYXR0cmlidXRlJyk7XG4gICAgICBhdHRyQ3RybC5zZXRWYWx1ZShhdHRyQ3RybC52YWx1ZSk7XG4gICAgICAvLyBSZS10cmlnZ2VyIGZpZWxkIHR5cGUgcmVidWlsZCBmb3IgZmlsdGVyVmFsdWVcbiAgICAgIGNvbnN0IGZpbHRlclZhbHVlRmllbGQgPSB0aGlzLmZpZWxkLmZpZWxkR3JvdXBbaW5kZXggKyAxXS5maWVsZEdyb3VwXG4gICAgICAgIC5maW5kKGYgPT4gZi5rZXkgPT09ICdmaWx0ZXJWYWx1ZScpO1xuICBcbiAgICAgICAgaWYgKGZpbHRlclZhbHVlRmllbGQpIHtcbiAgICAgICAgICBjb25zdCB0eXBlTWFwID0ge1xuICAgICAgICAgICAgU0VMRUNUOiAnc2Etbmctc2VsZWN0JyxcbiAgICAgICAgICAgIFNUUklORzogJ3NhLWlucHV0JyxcbiAgICAgICAgICAgIE5VTUJFUjogJ3NhLWlucHV0JyxcbiAgICAgICAgICAgIERBVEU6ICdzYS1kYXRlLXBpY2tlcicsXG4gICAgICAgICAgICBDVVJSRU5DWTogJ3NhLWN1cnJlbmN5LWlucHV0JyxcbiAgICAgICAgICAgIEJPT0xFQU46ICdzYS1uZy1zZWxlY3QnLFxuICAgICAgICAgIH07XG4gICAgICAgIFxuICAgICAgICAgIGNvbnN0IG5ld1R5cGUgPSB0eXBlTWFwW2F0dHIuZmlsdGVyVHlwZV0gfHwgJ3NhLWlucHV0JztcbiAgICAgICAgICBmaWx0ZXJWYWx1ZUZpZWxkLnR5cGUgPSBuZXdUeXBlO1xuICAgICAgICAgIGZpbHRlclZhbHVlRmllbGQucHJvcHMgPSB7XG4gICAgICAgICAgICAuLi50aGlzLmNyZWF0ZUZpZWxkUHJvcHMoYXR0ci5maWx0ZXJUeXBlKSxcbiAgICAgICAgICAgIGhhc0R5bmFtaWNUeXBlOiB0cnVlLFxuICAgICAgICAgICAgZGlzYWJsZWQ6IGZhbHNlLCAgLy8gaW5pdGlhbFxuICAgICAgICAgICAgYXR0cmlidXRlOiBhdHRyLFxuICAgICAgICAgIH07XG4gICAgICAgIFxuICAgICAgICAgIC8vIPCflIQgTm90aWZ5IEZvcm1seSBvZiB0eXBlIGNoYW5nZVxuICAgICAgICAgIGZpbHRlclZhbHVlRmllbGQub3B0aW9ucz8uZmllbGRDaGFuZ2VzPy5uZXh0KHtcbiAgICAgICAgICAgIHR5cGU6ICd0eXBlJyxcbiAgICAgICAgICAgIGZpZWxkOiBmaWx0ZXJWYWx1ZUZpZWxkLFxuICAgICAgICAgICAgdmFsdWU6IG5ld1R5cGUsXG4gICAgICAgICAgfSk7XG4gICAgICAgIFxuICAgICAgICB9XG4gICAgICAgIFxuICAgIH1cbiAgfVxuICBjcmVhdGVGaWVsZFByb3BzKHR5cGU6IHN0cmluZykge1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSAnU0VMRUNUJzpcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBwbGFjZWhvbGRlcjogJ1NlbGVjdCcsXG4gICAgICAgICAgbXVsdGlwbGU6IGZhbHNlLFxuICAgICAgICAgIGJpbmRMYWJlbDogJ2xhYmVsJyxcbiAgICAgICAgICBiaW5kVmFsdWU6ICd2YWx1ZScsXG4gICAgICAgICAgYXBwZWFyYW5jZTogJ291dGxpbmUnLFxuICAgICAgICAgIGlzQ2xlYXJhYmxlOiB0cnVlLFxuICAgICAgICAgIGlzU2VhcmNoYWJsZTogZmFsc2UsXG4gICAgICAgICAgY2xvc2VPbnNlbGVjdDogdHJ1ZSxcbiAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICBkaXNhYmxlZDogZmFsc2UsXG4gICAgICAgIH07XG4gICAgICBjYXNlICdTVFJJTkcnOlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHBsYWNlaG9sZGVyOiAnRW50ZXIgdmFsdWUnLFxuICAgICAgICAgIGFwcGVhcmFuY2U6ICdvdXRsaW5lJyxcbiAgICAgICAgICB0eXBlOiAndGV4dCdcbiAgICAgICAgfTtcbiAgICAgIGNhc2UgJ05VTUJFUic6XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcGxhY2Vob2xkZXI6ICdFbnRlciB2YWx1ZScsXG4gICAgICAgICAgYXBwZWFyYW5jZTogJ291dGxpbmUnLFxuICAgICAgICAgIHR5cGU6ICdudW1iZXInXG4gICAgICAgIH07XG4gICAgICBjYXNlICdEQVRFJzpcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBwbGFjZWhvbGRlcjogJ1NlbGVjdCBkYXRlJyxcbiAgICAgICAgICBhcHBlYXJhbmNlOiAnb3V0bGluZScsXG4gICAgICAgICAgdHlwZTogJ2RhdGUnXG4gICAgICAgIH07XG4gICAgICBjYXNlICdDVVJSRU5DWSc6XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcGxhY2Vob2xkZXI6ICdFbnRlciB2YWx1ZScsXG4gICAgICAgICAgYXBwZWFyYW5jZTogJ291dGxpbmUnLFxuICAgICAgICB9O1xuICAgICAgY2FzZSAnQk9PTEVBTic6XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcGxhY2Vob2xkZXI6ICdFbnRlciB2YWx1ZScsXG4gICAgICAgICAgYXBwZWFyYW5jZTogJ291dGxpbmUnLFxuICAgICAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgICAgICBvcHRpb25zOiBbXG4gICAgICAgICAgICB7IHZhbHVlOiB0cnVlLCBsYWJlbDogJ1RydWUnIH0sXG4gICAgICAgICAgICB7IHZhbHVlOiBmYWxzZSwgbGFiZWw6ICdGYWxzZScgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGJpbmRMYWJlbDogJ2xhYmVsJyxcbiAgICAgICAgICBiaW5kVmFsdWU6ICd2YWx1ZScsXG4gICAgICAgICAgZGlzYWJsZWQ6IGZhbHNlLFxuICAgICAgICB9O1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBwbGFjZWhvbGRlcjogJ0VudGVyIHZhbHVlJyxcbiAgICAgICAgICBhcHBlYXJhbmNlOiAnb3V0bGluZScsXG4gICAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcmVzZXQoKSB7XG4gICAgdGhpcy5maWVsZC5maWVsZEdyb3VwLnNwbGljZSgwLCB0aGlzLmZpZWxkLmZpZWxkR3JvdXAubGVuZ3RoKTsgLy8gY2xlYXJcbiAgICB0aGlzLmFkZCgpOyAvLyBzdGFydCBmcmVzaCB3aXRoIG9uZSByb3dcbiAgfVxuXG59XG4iLCI8ZGl2IGNsYXNzPVwic2EtcXVlcnktYnVpbGRlci1jb250YWluZXJcIj5cbiAgPGRpdiBjbGFzcz1cInF1ZXJ5LWJ1aWxkZXItYm9keVwiPlxuICAgIEBmb3Ioc3ViRmllbGQgb2YgZmllbGQuZmllbGRHcm91cDsgdHJhY2sgJGluZGV4KSB7XG4gICAgICA8ZGl2IGNsYXNzPVwicm93IGFsaWduLWl0ZW1zLWJhc2VsaW5lXCI+XG4gICAgICAgIEBpZiAoJGluZGV4ID09PSAwKSB7XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJ3aGVyZS10ZXh0IGZsZXgtMVwiPldoZXJlPC9zcGFuPlxuICAgICAgICB9XG4gICAgICAgIEBmb3IgKHN1YkZpZWxkIG9mIHN1YkZpZWxkLmZpZWxkR3JvdXA7IHRyYWNrICRpbmRleCkge1xuICAgICAgICAgIEBpZighIXN1YkZpZWxkLnByb3BzWydoYXNEeW5hbWljVHlwZSddKXtcbiAgICAgICAgICAgIEBzd2l0Y2ggKGdldEZpbHRlclR5cGUoc3ViRmllbGQpKSB7XG4gICAgICAgICAgICAgIEBjYXNlICgnU1RSSU5HJykge1xuICAgICAgICAgICAgICAgIDxmb3JtbHktZmllbGQgW2ZpZWxkXT1cInN1YkZpZWxkXCI+PC9mb3JtbHktZmllbGQ+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIEBjYXNlICgnTlVNQkVSJykge1xuICAgICAgICAgICAgICAgIDxmb3JtbHktZmllbGQgW2ZpZWxkXT1cInN1YkZpZWxkXCI+PC9mb3JtbHktZmllbGQ+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIEBjYXNlICgnQk9PTEVBTicpIHtcbiAgICAgICAgICAgICAgICAgIDxmb3JtbHktZmllbGQgW2ZpZWxkXT1cInN1YkZpZWxkXCI+PC9mb3JtbHktZmllbGQ+XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBAY2FzZSAoJ0NVUlJFTkNZJykge1xuICAgICAgICAgICAgICAgICAgICA8Zm9ybWx5LWZpZWxkIFtmaWVsZF09XCJzdWJGaWVsZFwiPjwvZm9ybWx5LWZpZWxkPlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgQGNhc2UgKCdEQVRFJykge1xuXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBAY2FzZSAoJ1NFTEVDVCcpIHtcbiAgICAgICAgICAgICAgICAgIDxmb3JtbHktZmllbGQgW2ZpZWxkXT1cImNyZWF0ZUZpZWxkKHN1YkZpZWxkKVwiPjwvZm9ybWx5LWZpZWxkPlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgQGRlZmF1bHQge1xuICAgICAgICAgICAgICAgICAgPGZvcm1seS1maWVsZCBbZmllbGRdPVwiY3JlYXRlRmllbGQoc3ViRmllbGQpXCI+PC9mb3JtbHktZmllbGQ+XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfUBlbHNle1xuICAgICAgICAgICAgPGZvcm1seS1maWVsZFxuICAgICAgICAgICAgY2xhc3M9XCJjb2xcIlxuICAgICAgICAgICAgW2ZpZWxkXT1cInN1YkZpZWxkXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgPC9mb3JtbHktZmllbGQ+XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIEBpZihwcm9wcz8uWydzaG93Q29weUJ1dHRvbiddKXtcbiAgICAgICAgPHNhLWljb24gaWNvbj1cImNvcHlPdXRsaW5lZFwiIGNsYXNzPVwiY29weS1pY29uIHBvaW50ZXJcIiAoY2xpY2spPVwiY29weSgkaW5kZXgpXCI+PC9zYS1pY29uPlxuICAgICAgICB9XG4gICAgICAgIDxzYS1pY29uIGljb249XCJkZWxldGVJY29uXCIgY2xhc3M9XCJkZWxldGUtaWNvbiBwb2ludGVyXCIgKGNsaWNrKT1cInJlbW92ZSgkaW5kZXgpXCI+PC9zYS1pY29uPlxuICAgICAgPC9kaXY+XG4gICAgfVxuICBcbiAgICA8IS0tIEJ1dHRvbnMgLS0+XG4gICAgPGRpdiBjbGFzcz1cInJ1bGUtYnV0dG9uLWNvbnRhaW5lclwiPlxuICAgICAgPHNhLWJ1dHRvbiBpY29uPVwiYWRkXCIgaWNvblBvc2l0aW9uPVwibGVmdFwiIHRleHQ9XCJBZGQgZmlsdGVyXCJcbiAgICAgIChvbkNsaWNrRXZlbnQpPVwiYWRkKClcIlxuICAgICAgW3N0YXRlXT1cImZpZWxkPy5maWVsZEdyb3VwPy5sZW5ndGggPT09IChwcm9wcz8uWydtYXhSb3dzJ10gfHwgNSkgPyAnZGlzYWJsZWQnIDogJ2RlZmF1bHQnXCJcbiAgICAgIHR5cGU9XCJvdXRsaW5lXCIgc2l6ZT1cIm1lZGl1bVwiPlxuICAgICAgPC9zYS1idXR0b24+XG4gICAgICA8c3BhbiBjbGFzcz1cImZpbHRlcnMtY291bnRcIj4oe3tmaWVsZD8uZmllbGRHcm91cD8ubGVuZ3RofX0ve3twcm9wcz8uWydtYXhSb3dzJ10gfHwgNX19IGZpbHRlcnMpPC9zcGFuPlxuICAgICAgQGlmKHByb3BzPy5bJ3Nob3dSZXNldEJ1dHRvbiddKXtcbiAgICAgIDxzYS1idXR0b24gaWNvblBvc2l0aW9uPVwibGVmdFwiIHRleHQ9XCJSZXNldFwiXG4gICAgICAob25DbGlja0V2ZW50KT1cInJlc2V0KClcIlxuICAgICAgdHlwZT1cInByaW1hcnlcIiBzaXplPVwibWVkaXVtXCI+XG4gICAgICA8L3NhLWJ1dHRvbj5cbiAgICAgIH1cbiAgICA8L2Rpdj4gICAgXG4gICAgPC9kaXY+XG48L2Rpdj4iXX0=
185
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcnktYnVpbGRlci1mb3JtbHkuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29tcG9uZW50LWxpYnJhcnkvc3JjL2xpYi9xdWVyeS1idWlsZGVyLWZvcm1seS9xdWVyeS1idWlsZGVyLWZvcm1seS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnQtbGlicmFyeS9zcmMvbGliL3F1ZXJ5LWJ1aWxkZXItZm9ybWx5L3F1ZXJ5LWJ1aWxkZXItZm9ybWx5LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsTUFBTSxlQUFlLENBQUM7QUFDbEQsT0FBTyxFQUFFLGNBQWMsRUFBcUIsTUFBTSxrQkFBa0IsQ0FBQztBQUNyRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2hELE9BQU8sRUFBYSxtQkFBbUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQ25DLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdkQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbEUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzNELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN6RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdkQsT0FBTyxFQUFFLE9BQU8sRUFBUyxLQUFLLEVBQUUsVUFBVSxFQUFFLE9BQU8s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QkFBeUIsY0FHdkIsSUFBSSxhQUNMLEVBQUUsY0FDRDt3QkFDVixPQUFPLENBQUMsY0FBYyxFQUFFOzRCQUN0QixVQUFVLENBQUMsUUFBUSxFQUFFO2dDQUNuQixLQUFLLENBQUM7b0NBQ0osT0FBTyxFQUFFLENBQUM7b0NBQ1YsU0FBUyxFQUFFLCtCQUErQjtvQ0FDMUMsTUFBTSxFQUFFLEtBQUs7b0NBQ2IsUUFBUSxFQUFFLFFBQVE7aUNBQ25CLENBQUM7Z0NBQ0YsT0FBTyxDQUFDLHNDQUFzQyxFQUFFLEtBQUssQ0FBQztvQ0FDcEQsT0FBTyxFQUFFLENBQUM7b0NBQ1YsU0FBUyxFQUFFLHdCQUF3QjtvQ0FDbkMsTUFBTSxFQUFFLEdBQUc7aUNBQ1osQ0FBQyxDQUFDOzZCQUNKLENBQUM7NEJBQ0YsVUFBVSxDQUFDLFFBQVEsRUFBRTtnQ0FDbkIsS0FBSyxDQUFDO29DQUNKLE9BQU8sRUFBRSxDQUFDO29DQUNWLFNBQVMsRUFBRSx3QkFBd0I7b0NBQ25DLE1BQU0sRUFBRSxHQUFHO2lDQUNaLENBQUM7Z0NBQ0YsT0FBTyxDQUFDLHNDQUFzQyxFQUFFLEtBQUssQ0FBQztvQ0FDcEQsT0FBTyxFQUFFLENBQUM7b0NBQ1YsU0FBUyxFQUFFLCtCQUErQjtvQ0FDMUMsTUFBTSxFQUFFLEtBQUs7b0NBQ2IsUUFBUSxFQUFFLFFBQVE7aUNBQ25CLENBQUMsQ0FBQzs2QkFDSixDQUFDO3lCQUNILENBQUM7cUJBQ0gsV0FDUTt3QkFDUCxZQUFZO3dCQUNaLG1CQUFtQjt3QkFDbkIsWUFBWTt3QkFDWixlQUFlO3dCQUNmLGFBQWE7d0JBQ2Isa0JBQWtCO3dCQUNsQixlQUFlO3dCQUNmLGVBQWU7d0JBQ2YsYUFBYTtxQkFDZCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT25Jbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBGaWVsZEFycmF5VHlwZSwgRm9ybWx5RmllbGRDb25maWcgfSBmcm9tICdAbmd4LWZvcm1seS9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7IFxuaW1wb3J0IHsgRm9ybWx5TW9kdWxlIH0gZnJvbSAnQG5neC1mb3JtbHkvY29yZSc7XG5pbXBvcnQgeyBGb3JtR3JvdXAsIFJlYWN0aXZlRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBnZXQsIGtleXMgfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgQnV0dG9uQ29tcG9uZW50IH0gZnJvbSAnLi4vYnV0dG9uL2J1dHRvbi5jb21wb25lbnQnO1xuaW1wb3J0IHsgSWNvbkNvbXBvbmVudCB9IGZyb20gJy4uL2ljb24vaWNvbi5jb21wb25lbnQnO1xuaW1wb3J0IHsgTWF0Rm9ybUZpZWxkTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZm9ybS1maWVsZCc7XG5pbXBvcnQgeyBNYXRTZWxlY3RNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zZWxlY3QnO1xuaW1wb3J0IHsgTWF0T3B0aW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvY29yZSc7XG5pbXBvcnQgeyBNYXRJY29uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaWNvbic7XG5pbXBvcnQgeyB0cmlnZ2VyLCBzdGF0ZSwgc3R5bGUsIHRyYW5zaXRpb24sIGFuaW1hdGUsIHF1ZXJ5LCBzdGFnZ2VyIH0gZnJvbSAnQGFuZ3VsYXIvYW5pbWF0aW9ucyc7XG5cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnc2EtcXVlcnktYnVpbGRlci1mb3JtbHknLFxuICB0ZW1wbGF0ZVVybDogJy4vcXVlcnktYnVpbGRlci1mb3JtbHkuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9xdWVyeS1idWlsZGVyLWZvcm1seS5jb21wb25lbnQuc2NzcyddLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBwcm92aWRlcnM6IFtdLFxuICBhbmltYXRpb25zOiBbXG4gICAgdHJpZ2dlcigncm93QW5pbWF0aW9uJywgW1xuICAgICAgdHJhbnNpdGlvbignOmVudGVyJywgW1xuICAgICAgICBzdHlsZSh7IFxuICAgICAgICAgIG9wYWNpdHk6IDAsIFxuICAgICAgICAgIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVkoLTEwcHgpIHNjYWxlKDAuOTUpJyxcbiAgICAgICAgICBoZWlnaHQ6ICcwcHgnLFxuICAgICAgICAgIG92ZXJmbG93OiAnaGlkZGVuJ1xuICAgICAgICB9KSxcbiAgICAgICAgYW5pbWF0ZSgnMzAwbXMgY3ViaWMtYmV6aWVyKDAuNCwgMC4wLCAwLjIsIDEpJywgc3R5bGUoeyBcbiAgICAgICAgICBvcGFjaXR5OiAxLCBcbiAgICAgICAgICB0cmFuc2Zvcm06ICd0cmFuc2xhdGVZKDApIHNjYWxlKDEpJyxcbiAgICAgICAgICBoZWlnaHQ6ICcqJ1xuICAgICAgICB9KSlcbiAgICAgIF0pLFxuICAgICAgdHJhbnNpdGlvbignOmxlYXZlJywgW1xuICAgICAgICBzdHlsZSh7IFxuICAgICAgICAgIG9wYWNpdHk6IDEsIFxuICAgICAgICAgIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVkoMCkgc2NhbGUoMSknLFxuICAgICAgICAgIGhlaWdodDogJyonXG4gICAgICAgIH0pLFxuICAgICAgICBhbmltYXRlKCcyNTBtcyBjdWJpYy1iZXppZXIoMC40LCAwLjAsIDAuMiwgMSknLCBzdHlsZSh7IFxuICAgICAgICAgIG9wYWNpdHk6IDAsIFxuICAgICAgICAgIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVkoLTEwcHgpIHNjYWxlKDAuOTUpJyxcbiAgICAgICAgICBoZWlnaHQ6ICcwcHgnLFxuICAgICAgICAgIG92ZXJmbG93OiAnaGlkZGVuJ1xuICAgICAgICB9KSlcbiAgICAgIF0pXG4gICAgXSlcbiAgXSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBSZWFjdGl2ZUZvcm1zTW9kdWxlLFxuICAgIEZvcm1seU1vZHVsZSxcbiAgICBCdXR0b25Db21wb25lbnQsXG4gICAgSWNvbkNvbXBvbmVudCxcbiAgICBNYXRGb3JtRmllbGRNb2R1bGUsXG4gICAgTWF0U2VsZWN0TW9kdWxlLFxuICAgIE1hdE9wdGlvbk1vZHVsZSxcbiAgICBNYXRJY29uTW9kdWxlICAgIFxuICBdXG59KVxuZXhwb3J0IGNsYXNzIFF1ZXJ5QnVpbGRlckZvcm1seUNvbXBvbmVudCBleHRlbmRzIEZpZWxkQXJyYXlUeXBlIGltcGxlbWVudHMgT25Jbml0IHtcbiAgXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIFxuICAgIFxuICB9XG4gIFxuICBnZXRSb3dDb25kaXRpb24oaW5kZXg6IG51bWJlcik6ICdhbmQnIHwgJ29yJyB7XG4gICAgICBpZiAoaW5kZXggPT09IDApIHJldHVybiAnYW5kJzsgXG4gICAgICBcbiAgICAgIGNvbnN0IHJ1bGVHcm91cCA9IHRoaXMuZm9ybUNvbnRyb2wuYXQoaW5kZXgpIGFzIEZvcm1Hcm91cDtcbiAgICAgIHJldHVybiBydWxlR3JvdXAuZ2V0KCdsb2dpY2FsT3BlcmF0b3InKT8udmFsdWUgfHwgJ2FuZCc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAqIFNldHMgdGhlIGNvbmRpdGlvbiBmb3IgYSBzcGVjaWZpYyByb3dcbiAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgcm93XG4gICAqIEBwYXJhbSBjb25kaXRpb24gVGhlIGNvbmRpdGlvbiB0byBzZXQgKGFuZC9vcilcbiAgICovXG4gIHNldFJvd0NvbmRpdGlvbihpbmRleDogbnVtYmVyLCBjb25kaXRpb246ICdhbmQnIHwgJ29yJyk6IHZvaWQge1xuICAgIGlmIChpbmRleCA9PT0gMCkgcmV0dXJuOyAvLyBGaXJzdCByb3cgZG9lc24ndCBoYXZlIGEgbG9naWNhbCBvcGVyYXRvclxuICAgIFxuICAgIGNvbnN0IHJ1bGVHcm91cCA9IHRoaXMuZm9ybUNvbnRyb2wuYXQoaW5kZXgpIGFzIEZvcm1Hcm91cDtcbiAgICBydWxlR3JvdXAuZ2V0KCdsb2dpY2FsT3BlcmF0b3InKT8uc2V0VmFsdWUoY29uZGl0aW9uKTtcbiAgfVxuXG4gIGNvcHlSdWxlKCk6IHZvaWQge1xuICAgIFxuICB9XG5cbiAgY3JlYXRlRmllbGQoZmllbGQ6IEZvcm1seUZpZWxkQ29uZmlnKTogRm9ybWx5RmllbGRDb25maWcge1xuICAgIGlmKGZpZWxkLnR5cGUgPT09ICdkeW5hbWljLXR5cGUnIHx8IGZpZWxkLnR5cGUgPT09ICcnKSB7XG4gICAgICBmaWVsZC50eXBlID0gJ3NhLWlucHV0JztcbiAgICAgIGZpZWxkLnByb3BzLnR5cGUgPSAndGV4dCc7XG4gICAgICBmaWVsZC5wcm9wcy5wbGFjZWhvbGRlciA9ICdFbnRlci9TZWxlY3QnO1xuICAgIH1cbiAgICByZXR1cm4gZmllbGQ7XG4gIH1cblxuICBnZXRGaWx0ZXJUeXBlKHN1YkZpZWxkOiBGb3JtbHlGaWVsZENvbmZpZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgcGFyZW50VmFsdWUgPSBnZXQoc3ViRmllbGQsICdmb3JtQ29udHJvbC5wYXJlbnQudmFsdWUnKTtcbiAgICBpZiAoIXBhcmVudFZhbHVlKSByZXR1cm4gdW5kZWZpbmVkO1xuICBcbiAgICAvLyBMb29rIHRocm91Z2ggYWxsIGtleXMgb2YgdGhlIHBhcmVudCB2YWx1ZVxuICAgIGZvciAoY29uc3Qga2V5IG9mIGtleXMocGFyZW50VmFsdWUpKSB7XG4gICAgICBjb25zdCB2YWwgPSBwYXJlbnRWYWx1ZVtrZXldO1xuICAgICAgaWYgKHZhbCAmJiB0eXBlb2YgdmFsID09PSAnb2JqZWN0JyAmJiAnZmlsdGVyVHlwZScgaW4gdmFsKSB7XG4gICAgICAgIHJldHVybiB2YWwuZmlsdGVyVHlwZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8vIHJlc2V0KCk6IHZvaWQge1xuICAvLyAgIHRoaXMuZm9ybUNvbnRyb2wucmVzZXQoKTtcbiAgLy8gfVxuXG4gIC8qKlxuICAgKiBEdXBsaWNhdGVzIHRoZSByb3cgYXQgdGhlIGdpdmVuIGluZGV4LlxuICAgKiBBIGRlZXDigJNjbG9uZSBvZiB0aGF0IHJvd+KAmXMgbW9kZWwgaXMgaW5zZXJ0ZWQgcmlnaHQgYWZ0ZXIgdGhlIG9yaWdpbmFsIHJvdy5cbiAgICovXG4gIGNvcHkoaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHJvd01vZGVsID0gdGhpcy5mb3JtQ29udHJvbC5hdChpbmRleCk/LnZhbHVlO1xuICAgIGlmICghcm93TW9kZWwpIHJldHVybjtcblxuICAgIGNvbnN0IGNsb25lZE1vZGVsID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShyb3dNb2RlbCkpO1xuXG4gICAgLy8gQ2FycnkgdGhlIHZhbHVlIG92ZXIgdG8gdGhlIG5ldyByb3cgc28gdGhlIG9uSW5pdCBob29rIGNhbiByZXN0b3JlIGl0LlxuICAgIGlmIChjbG9uZWRNb2RlbC5maWx0ZXJWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjbG9uZWRNb2RlbC5fY29waWVkVmFsdWUgPSBjbG9uZWRNb2RlbC5maWx0ZXJWYWx1ZTtcbiAgICB9XG5cbiAgICAvLyBJZiBjb3B5aW5nIHRoZSBmaXJzdCByb3cgKGluZGV4IDApLCB0aGUgbmV3IHJvdyAoaW5kZXggMSkgc2hvdWxkIGhhdmUgYSBsb2dpY2FsIG9wZXJhdG9yXG4gICAgLy8gU2V0IGRlZmF1bHQgbG9naWNhbCBvcGVyYXRvciB0byAnYW5kJyBmb3IgdGhlIG5ldyByb3dcbiAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgIGNsb25lZE1vZGVsLmxvZ2ljYWxPcGVyYXRvciA9ICdhbmQnO1xuICAgIH1cblxuICAgIHRoaXMuYWRkKGluZGV4ICsgMSwgY2xvbmVkTW9kZWwpO1xuXG4gICAgLy8gRm9yY2UgcmVidWlsZCBvZiB0aGUgZmlsdGVyVmFsdWUgZmllbGQgYnkgdHJpZ2dlcmluZyBhdHRyaWJ1dGUgY2hhbmdlXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBjb25zdCBuZXdSb3dGb3JtID0gdGhpcy5mb3JtQ29udHJvbC5hdChpbmRleCArIDEpIGFzIEZvcm1Hcm91cDtcbiAgICAgIGNvbnN0IGF0dHJDdHJsID0gbmV3Um93Rm9ybT8uZ2V0KCdhdHRyaWJ1dGUnKTtcbiAgICAgIGNvbnN0IGZpbHRlclZhbHVlQ3RybCA9IG5ld1Jvd0Zvcm0/LmdldCgnZmlsdGVyVmFsdWUnKTtcbiAgICAgIFxuICAgICAgaWYgKGF0dHJDdHJsICYmIGZpbHRlclZhbHVlQ3RybCAmJiBjbG9uZWRNb2RlbC5hdHRyaWJ1dGUpIHtcbiAgICAgICAgLy8gU3RvcmUgdGhlIGNvcGllZCB2YWx1ZSBpbiB0aGUgZm9ybSBtb2RlbCBiZWZvcmUgdHJpZ2dlcmluZyByZWJ1aWxkXG4gICAgICAgIGNvbnN0IGNvcGllZFZhbHVlID0gY2xvbmVkTW9kZWwuX2NvcGllZFZhbHVlO1xuICAgICAgICBcbiAgICAgICAgLy8gVGVtcG9yYXJpbHkgY2xlYXIgdGhlIGF0dHJpYnV0ZSB0byBmb3JjZSBhIGNoYW5nZSBldmVudFxuICAgICAgICBhdHRyQ3RybC5zZXRWYWx1ZShudWxsLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICAgIFxuICAgICAgICAvLyBUaGVuIHJlc3RvcmUgaXQgdG8gdHJpZ2dlciB0aGUgZmllbGQgdHlwZSByZWJ1aWxkXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIGF0dHJDdHJsLnNldFZhbHVlKGNsb25lZE1vZGVsLmF0dHJpYnV0ZSwgeyBlbWl0RXZlbnQ6IHRydWUgfSk7XG4gICAgICAgICAgXG4gICAgICAgICAgLy8gRW5zdXJlIHRoZSBjb3BpZWQgdmFsdWUgaXMgc3RpbGwgYXZhaWxhYmxlIGFmdGVyIHRoZSByZWJ1aWxkXG4gICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBpZiAoY29waWVkVmFsdWUgIT09IHVuZGVmaW5lZCAmJiAhbmV3Um93Rm9ybS52YWx1ZS5fY29waWVkVmFsdWUpIHtcbiAgICAgICAgICAgICAgLy8gUmUtYWRkIHRoZSBjb3BpZWQgdmFsdWUgaWYgaXQgd2FzIGxvc3QgZHVyaW5nIHJlYnVpbGRcbiAgICAgICAgICAgICAgbmV3Um93Rm9ybS5wYXRjaFZhbHVlKHsgX2NvcGllZFZhbHVlOiBjb3BpZWRWYWx1ZSB9KTtcbiAgICAgICAgICAgICAgZmlsdGVyVmFsdWVDdHJsLnNldFZhbHVlKGNvcGllZFZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LCA1MCk7XG4gICAgICAgIH0sIDEwKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICBcbiAgcmVzZXQoKSB7XG4gICAgdGhpcy5maWVsZC5maWVsZEdyb3VwLnNwbGljZSgwLCB0aGlzLmZpZWxkLmZpZWxkR3JvdXAubGVuZ3RoKTsgLy8gY2xlYXJcbiAgICB0aGlzLmFkZCgpOyAvLyBzdGFydCBmcmVzaCB3aXRoIG9uZSByb3dcbiAgfVxuXG59XG4iLCI8ZGl2IGNsYXNzPVwic2EtcXVlcnktYnVpbGRlci1jb250YWluZXJcIj5cbiAgPGRpdiBjbGFzcz1cInF1ZXJ5LWJ1aWxkZXItYm9keVwiPlxuICAgIEBmb3Ioc3ViRmllbGQgb2YgZmllbGQuZmllbGRHcm91cDsgdHJhY2sgc3ViRmllbGQuaWQgfHwgJGluZGV4KSB7XG4gICAgICA8ZGl2IGNsYXNzPVwicm93IGFsaWduLWl0ZW1zLWJhc2VsaW5lIHF1ZXJ5LXJvd1wiIFtAcm93QW5pbWF0aW9uXT5cbiAgICAgICAgQGlmICgkaW5kZXggPT09IDApIHtcbiAgICAgICAgICA8c3BhbiBjbGFzcz1cIndoZXJlLXRleHQgZmxleC0xXCI+V2hlcmU8L3NwYW4+XG4gICAgICAgIH1cbiAgICAgICAgQGZvciAoaW5uZXJGaWVsZCBvZiBzdWJGaWVsZC5maWVsZEdyb3VwOyB0cmFjayBpbm5lckZpZWxkLmtleSB8fCAkaW5kZXgpIHtcbiAgICAgICAgICBAaWYoISFpbm5lckZpZWxkLnByb3BzWydoYXNEeW5hbWljVHlwZSddKXtcbiAgICAgICAgICAgIEBzd2l0Y2ggKGdldEZpbHRlclR5cGUoaW5uZXJGaWVsZCkpIHtcbiAgICAgICAgICAgICAgQGNhc2UgKCdTVFJJTkcnKSB7XG4gICAgICAgICAgICAgICAgPGZvcm1seS1maWVsZCBbZmllbGRdPVwiaW5uZXJGaWVsZFwiPjwvZm9ybWx5LWZpZWxkPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBAY2FzZSAoJ05VTUJFUicpIHtcbiAgICAgICAgICAgICAgICA8Zm9ybWx5LWZpZWxkIFtmaWVsZF09XCJpbm5lckZpZWxkXCI+PC9mb3JtbHktZmllbGQ+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIEBjYXNlICgnQk9PTEVBTicpIHtcbiAgICAgICAgICAgICAgICAgIDxmb3JtbHktZmllbGQgW2ZpZWxkXT1cImlubmVyRmllbGRcIj48L2Zvcm1seS1maWVsZD5cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIEBjYXNlICgnQ1VSUkVOQ1knKSB7XG4gICAgICAgICAgICAgICAgICAgIDxmb3JtbHktZmllbGQgW2ZpZWxkXT1cImlubmVyRmllbGRcIj48L2Zvcm1seS1maWVsZD5cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIEBjYXNlICgnREFURScpIHtcblxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgQGNhc2UgKCdTRUxFQ1QnKSB7XG4gICAgICAgICAgICAgICAgICA8Zm9ybWx5LWZpZWxkIFtmaWVsZF09XCJjcmVhdGVGaWVsZChpbm5lckZpZWxkKVwiPjwvZm9ybWx5LWZpZWxkPlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgQGRlZmF1bHQge1xuICAgICAgICAgICAgICAgICAgPGZvcm1seS1maWVsZCBbZmllbGRdPVwiY3JlYXRlRmllbGQoaW5uZXJGaWVsZClcIj48L2Zvcm1seS1maWVsZD5cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9QGVsc2V7XG4gICAgICAgICAgICA8Zm9ybWx5LWZpZWxkXG4gICAgICAgICAgICBjbGFzcz1cImNvbFwiXG4gICAgICAgICAgICBbZmllbGRdPVwiaW5uZXJGaWVsZFwiXG4gICAgICAgICAgPlxuICAgICAgICAgIDwvZm9ybWx5LWZpZWxkPlxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBAaWYocHJvcHM/Llsnc2hvd0NvcHlCdXR0b24nXSl7XG4gICAgICAgIDxzYS1pY29uIGljb249XCJjb3B5T3V0bGluZWRcIiBjbGFzcz1cImNvcHktaWNvbiBwb2ludGVyXCIgKGNsaWNrKT1cImNvcHkoJGluZGV4KVwiPjwvc2EtaWNvbj5cbiAgICAgICAgfVxuICAgICAgICA8c2EtaWNvbiBpY29uPVwiZGVsZXRlSWNvblwiIGNsYXNzPVwiZGVsZXRlLWljb24gcG9pbnRlclwiIChjbGljayk9XCJyZW1vdmUoJGluZGV4KVwiPjwvc2EtaWNvbj5cbiAgICAgIDwvZGl2PlxuICAgIH1cbiAgXG4gICAgPCEtLSBCdXR0b25zIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJydWxlLWJ1dHRvbi1jb250YWluZXJcIj5cbiAgICAgIDxzYS1idXR0b24gaWNvbj1cImFkZFwiIGljb25Qb3NpdGlvbj1cImxlZnRcIiB0ZXh0PVwiQWRkIGZpbHRlclwiXG4gICAgICAob25DbGlja0V2ZW50KT1cImFkZCgpXCJcbiAgICAgIFtzdGF0ZV09XCJmaWVsZD8uZmllbGRHcm91cD8ubGVuZ3RoID09PSAocHJvcHM/LlsnbWF4Um93cyddIHx8IDUpID8gJ2Rpc2FibGVkJyA6ICdkZWZhdWx0J1wiXG4gICAgICB0eXBlPVwib3V0bGluZVwiIHNpemU9XCJtZWRpdW1cIj5cbiAgICAgIDwvc2EtYnV0dG9uPlxuICAgICAgPHNwYW4gY2xhc3M9XCJmaWx0ZXJzLWNvdW50XCI+KHt7ZmllbGQ/LmZpZWxkR3JvdXA/Lmxlbmd0aH19L3t7cHJvcHM/LlsnbWF4Um93cyddIHx8IDV9fSBmaWx0ZXJzKTwvc3Bhbj5cbiAgICAgIEBpZihwcm9wcz8uWydzaG93UmVzZXRCdXR0b24nXSl7XG4gICAgICA8c2EtYnV0dG9uIGljb25Qb3NpdGlvbj1cImxlZnRcIiB0ZXh0PVwiUmVzZXRcIlxuICAgICAgKG9uQ2xpY2tFdmVudCk9XCJyZXNldCgpXCJcbiAgICAgIHR5cGU9XCJwcmltYXJ5XCIgc2l6ZT1cIm1lZGl1bVwiPlxuICAgICAgPC9zYS1idXR0b24+XG4gICAgICB9XG4gICAgPC9kaXY+ICAgIFxuICAgIDwvZGl2PlxuPC9kaXY+Il19