@cqa-lib/cqa-ui 1.1.225 → 1.1.227

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 (23) hide show
  1. package/esm2020/lib/simulator/simulator.component.mjs +28 -45
  2. package/esm2020/lib/step-builder/step-builder-action/step-builder-action.component.mjs +267 -44
  3. package/esm2020/lib/step-builder/step-builder-condition/step-builder-condition.component.mjs +183 -41
  4. package/esm2020/lib/step-builder/step-builder-loop/step-builder-loop.component.mjs +44 -3
  5. package/esm2020/lib/step-builder/template-variables-form/template-variables-form.component.mjs +218 -57
  6. package/esm2020/lib/test-case-details/element-popup/element-form/element-form.component.mjs +277 -0
  7. package/esm2020/lib/test-case-details/element-popup/element-popup.component.mjs +32 -192
  8. package/esm2020/lib/ui-kit.module.mjs +6 -1
  9. package/esm2020/public-api.mjs +2 -1
  10. package/fesm2015/cqa-lib-cqa-ui.mjs +1118 -444
  11. package/fesm2015/cqa-lib-cqa-ui.mjs.map +1 -1
  12. package/fesm2020/cqa-lib-cqa-ui.mjs +1103 -440
  13. package/fesm2020/cqa-lib-cqa-ui.mjs.map +1 -1
  14. package/lib/step-builder/step-builder-action/step-builder-action.component.d.ts +50 -4
  15. package/lib/step-builder/step-builder-condition/step-builder-condition.component.d.ts +39 -2
  16. package/lib/step-builder/step-builder-loop/step-builder-loop.component.d.ts +17 -1
  17. package/lib/step-builder/template-variables-form/template-variables-form.component.d.ts +56 -5
  18. package/lib/test-case-details/element-popup/element-form/element-form.component.d.ts +77 -0
  19. package/lib/test-case-details/element-popup/element-popup.component.d.ts +13 -32
  20. package/lib/ui-kit.module.d.ts +42 -41
  21. package/package.json +1 -1
  22. package/public-api.d.ts +1 -0
  23. package/styles.css +1 -1
@@ -0,0 +1,277 @@
1
+ import { ChangeDetectionStrategy, Component, EventEmitter, Input, Optional, Output, } from '@angular/core';
2
+ import { FormBuilder, Validators } from '@angular/forms';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "@angular/forms";
5
+ import * as i2 from "../../../custom-input/custom-input.component";
6
+ import * as i3 from "../../../dynamic-select/dynamic-select-field.component";
7
+ import * as i4 from "@angular/material/icon";
8
+ import * as i5 from "../../../button/button.component";
9
+ import * as i6 from "@angular/common";
10
+ export class ElementFormComponent {
11
+ constructor(fb, cdr) {
12
+ this.cdr = cdr;
13
+ /** Current element data (for edit mode) */
14
+ this.element = { title: '', selector: '', labels: [] };
15
+ /** Screen name options for autocomplete (from API) */
16
+ this.screenNameOptions = [];
17
+ /** Whether more screen names are available for infinite scroll */
18
+ this.hasMoreScreenNames = false;
19
+ /** True while parent is loading screen names (search or load more) */
20
+ this.isLoadingScreenNames = false;
21
+ /** True while parent is fetching latest element data for edit (shows loading state) */
22
+ this.isElementLoading = false;
23
+ /** Whether we're in edit mode */
24
+ this.isEditMode = false;
25
+ /** Whether we're in create mode */
26
+ this.isCreateMode = false;
27
+ /** Whether edit in depth is available */
28
+ this.isEditInDepthAvailable = true;
29
+ /** Emitted when user creates a new element (parent should call API) */
30
+ this.createElement = new EventEmitter();
31
+ /** Emitted when user updates an element (parent should call API) */
32
+ this.updateElement = new EventEmitter();
33
+ /** Emitted when user requests to create a new screen name */
34
+ this.createScreenNameRequest = new EventEmitter();
35
+ /** Emitted when user searches screen names (server search) */
36
+ this.searchScreenName = new EventEmitter();
37
+ /** Emitted when user scrolls to load more screen names (passes current search query) */
38
+ this.loadMoreScreenNames = new EventEmitter();
39
+ /** Emitted when user clicks "Select from Element list" or "Cancel" */
40
+ this.cancel = new EventEmitter();
41
+ /** Emitted when user clicks "Edit in depth" */
42
+ this.editInDepth = new EventEmitter();
43
+ /** Labels (tags) as string array for multi-tag input */
44
+ this.formLabels = [];
45
+ /** Current tag input value */
46
+ this.tagInputValue = '';
47
+ /** Whether we're saving (disable buttons) */
48
+ this.saving = false;
49
+ this.fb = fb || new FormBuilder();
50
+ this.initializeForm();
51
+ }
52
+ ngOnChanges(changes) {
53
+ if (changes['screenNameOptions'] || changes['hasMoreScreenNames'] || changes['isLoadingScreenNames']) {
54
+ this.updateScreenNameSelectConfig();
55
+ }
56
+ if ((changes['element'] || changes['elementId']) && this.elementId) {
57
+ this.populateFormForEdit();
58
+ }
59
+ else if (changes['element'] && !this.elementId && this.isCreateMode) {
60
+ this.populateFormForCreateWithElement();
61
+ }
62
+ }
63
+ ngOnInit() {
64
+ if (this.elementId) {
65
+ this.populateFormForEdit();
66
+ }
67
+ else if (this.isCreateMode && this.element) {
68
+ this.populateFormForCreateWithElement();
69
+ }
70
+ }
71
+ initializeForm() {
72
+ this.form = this.fb.group({
73
+ name: ['', [Validators.required]],
74
+ screenNameId: [null, [Validators.required]],
75
+ value: ['', [Validators.required]],
76
+ });
77
+ this.updateScreenNameSelectConfig();
78
+ }
79
+ updateScreenNameSelectConfig() {
80
+ const opts = (this.screenNameOptions || []).map((o) => ({
81
+ id: o.id,
82
+ value: o.id,
83
+ name: o.name,
84
+ label: o.name,
85
+ }));
86
+ const currentId = this.form?.get('screenNameId')?.value;
87
+ if (currentId && this.element?.screenNameId === currentId && this.element?.screenName) {
88
+ const exists = opts.some((o) => o.id === currentId);
89
+ if (!exists) {
90
+ opts.unshift({
91
+ id: currentId,
92
+ value: currentId,
93
+ name: String(this.element.screenName),
94
+ label: String(this.element.screenName),
95
+ });
96
+ }
97
+ }
98
+ this.screenNameSelectConfig = {
99
+ key: 'screenNameId',
100
+ label: 'Screen Name',
101
+ placeholder: 'Select or create screen',
102
+ searchable: true,
103
+ serverSearch: true,
104
+ allowCustomValue: true,
105
+ options: opts,
106
+ hasMore: this.hasMoreScreenNames,
107
+ isLoading: this.isLoadingScreenNames,
108
+ onSearch: (q) => this.searchScreenName.emit(q || ''),
109
+ onLoadMore: (q) => this.loadMoreScreenNames.emit(q || ''),
110
+ };
111
+ this.cdr?.markForCheck();
112
+ }
113
+ populateFormForEdit() {
114
+ if (this.element && this.elementId != null) {
115
+ this.isEditMode = true;
116
+ this.isCreateMode = false;
117
+ this.form.patchValue({
118
+ name: this.element.title ?? '',
119
+ screenNameId: this.element.screenNameId ?? null,
120
+ value: this.element.selector ?? '',
121
+ });
122
+ this.formLabels = [...(this.element.labels || [])];
123
+ this.updateScreenNameSelectConfig();
124
+ }
125
+ else {
126
+ this.isEditMode = false;
127
+ this.isCreateMode = false;
128
+ this.formLabels = [];
129
+ }
130
+ this.cdr?.markForCheck();
131
+ }
132
+ populateFormForCreateWithElement() {
133
+ if (this.element) {
134
+ this.isCreateMode = true;
135
+ this.isEditMode = false;
136
+ this.form.patchValue({
137
+ name: this.element.title ?? '',
138
+ screenNameId: this.element.screenNameId ?? null,
139
+ value: this.element.selector ?? '',
140
+ });
141
+ this.formLabels = [...(this.element.labels || [])];
142
+ this.updateScreenNameSelectConfig();
143
+ }
144
+ else {
145
+ this.isCreateMode = true;
146
+ this.isEditMode = false;
147
+ this.formLabels = [];
148
+ }
149
+ this.cdr?.markForCheck();
150
+ }
151
+ /** Called by parent when a new screen name was created (so we can set the selected value) */
152
+ setCreatedScreenName(opt) {
153
+ this.form.get('screenNameId')?.setValue(opt.id);
154
+ this.updateScreenNameSelectConfig();
155
+ this.cdr?.markForCheck();
156
+ }
157
+ onApply() {
158
+ if (this.form.invalid) {
159
+ Object.keys(this.form.controls).forEach((key) => this.form.get(key)?.markAsTouched());
160
+ return;
161
+ }
162
+ const formValue = this.form.value;
163
+ const screenNameId = formValue.screenNameId;
164
+ const selectedOpt = this.screenNameOptions.find((o) => o.id === screenNameId);
165
+ const screenNameName = selectedOpt?.name ? String(selectedOpt.name).trim() : '';
166
+ if (!screenNameId || !screenNameName) {
167
+ this.form.get('screenNameId')?.setErrors({ required: true });
168
+ this.form.get('screenNameId')?.markAsTouched();
169
+ return;
170
+ }
171
+ this.saving = true;
172
+ this.cdr?.markForCheck();
173
+ const payload = {
174
+ name: formValue.name.trim(),
175
+ screenNameId,
176
+ screenNameName,
177
+ locatorValue: formValue.value.trim(),
178
+ labels: [...this.formLabels],
179
+ };
180
+ if (this.isEditMode && this.elementId) {
181
+ this.updateElement.emit({
182
+ ...payload,
183
+ elementId: this.elementId,
184
+ });
185
+ }
186
+ else {
187
+ this.createElement.emit(payload);
188
+ }
189
+ }
190
+ onCreateOrUpdateSuccess() {
191
+ this.saving = false;
192
+ this.cdr?.markForCheck();
193
+ }
194
+ onCreateOrUpdateError() {
195
+ this.saving = false;
196
+ this.cdr?.markForCheck();
197
+ }
198
+ onCancel() {
199
+ this.cancel.emit();
200
+ }
201
+ onEditInDepth(event) {
202
+ event.preventDefault();
203
+ this.editInDepth.emit();
204
+ }
205
+ getFormControl(controlName) {
206
+ return this.form.get(controlName);
207
+ }
208
+ getFormControlValue(controlName) {
209
+ return this.form.get(controlName)?.value || '';
210
+ }
211
+ onFormControlChange(controlName, value) {
212
+ this.form.patchValue({ [controlName]: value });
213
+ this.cdr?.markForCheck();
214
+ }
215
+ /** Add a tag (label) */
216
+ addTag(tag) {
217
+ const t = (tag || this.tagInputValue || '').trim();
218
+ if (t && !this.formLabels.includes(t)) {
219
+ this.formLabels = [...this.formLabels, t];
220
+ this.tagInputValue = '';
221
+ this.cdr?.markForCheck();
222
+ }
223
+ }
224
+ removeTag(tag) {
225
+ this.formLabels = this.formLabels.filter((l) => l !== tag);
226
+ this.cdr?.markForCheck();
227
+ }
228
+ onTagInputKeydown(event) {
229
+ if (event.key === 'Enter' || event.key === ',') {
230
+ event.preventDefault();
231
+ this.addTag();
232
+ }
233
+ }
234
+ }
235
+ ElementFormComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ElementFormComponent, deps: [{ token: i1.FormBuilder, optional: true }, { token: i0.ChangeDetectorRef, optional: true }], target: i0.ɵɵFactoryTarget.Component });
236
+ ElementFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: ElementFormComponent, selector: "cqa-element-form", inputs: { elementId: "elementId", element: "element", screenNameOptions: "screenNameOptions", hasMoreScreenNames: "hasMoreScreenNames", isLoadingScreenNames: "isLoadingScreenNames", isElementLoading: "isElementLoading", isEditMode: "isEditMode", isCreateMode: "isCreateMode", isEditInDepthAvailable: "isEditInDepthAvailable" }, outputs: { createElement: "createElement", updateElement: "updateElement", createScreenNameRequest: "createScreenNameRequest", searchScreenName: "searchScreenName", loadMoreScreenNames: "loadMoreScreenNames", cancel: "cancel", editInDepth: "editInDepth" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-flex cqa-flex-col cqa-gap-4 cqa-px-1 cqa-pt-3\">\n <div *ngIf=\"isElementLoading && isEditMode\" class=\"cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-gap-3 cqa-py-8\">\n <svg class=\"cqa-animate-spin cqa-h-6 cqa-w-6 cqa-text-[#3F43EE]\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"cqa-opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\n <path class=\"cqa-opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n <span class=\"cqa-text-[#6B7280] cqa-text-sm\">Loading element data...</span>\n </div>\n <div *ngIf=\"!isElementLoading\" class=\"cqa-flex cqa-gap-1.5\">\n <cqa-custom-input \n class=\"cqa-w-1/2\" \n label=\"Name\" \n placeholder=\"default-element\"\n [value]=\"getFormControlValue('name')\"\n [errors]=\"getFormControl('name')?.touched && getFormControl('name')?.invalid ? ['Name is required'] : []\"\n [required]=\"true\"\n (valueChange)=\"onFormControlChange('name', $event)\">\n </cqa-custom-input>\n <div class=\"cqa-w-1/2\">\n <cqa-dynamic-select [form]=\"form\" [config]=\"screenNameSelectConfig\"\n (addCustomValue)=\"createScreenNameRequest.emit($event.value)\"\n class=\"cqa-w-full\">\n </cqa-dynamic-select>\n <div *ngIf=\"getFormControl('screenNameId')?.touched && getFormControl('screenNameId')?.invalid\" class=\"cqa-flex cqa-flex-col cqa-gap-1 cqa-mt-1.5\">\n <div class=\"cqa-flex cqa-items-start cqa-gap-1.5\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n class=\"cqa-flex-shrink-0 cqa-mt-0.5\">\n <path d=\"M7 1.75C4.1 1.75 1.75 4.1 1.75 7C1.75 9.9 4.1 12.25 7 12.25C9.9 12.25 12.25 9.9 12.25 7C12.25 4.1 9.9 1.75 7 1.75ZM7 9.625C6.65625 9.625 6.375 9.34375 6.375 9V7C6.375 6.65625 6.65625 6.375 7 6.375C7.34375 6.375 7.625 6.65625 7.625 7V9C7.625 9.34375 7.34375 9.625 7 9.625ZM7.625 5.25H6.375V4H7.625V5.25Z\" fill=\"#EF4444\"/>\n </svg>\n <span class=\"cqa-text-xs cqa-text-[#EF4444] cqa-font-medium cqa-leading-[18px]\">\n Screen Name is required\n </span>\n </div>\n </div>\n </div>\n </div>\n <ng-container *ngIf=\"!isElementLoading\">\n <cqa-custom-input \n class=\"cqa-w-full\" \n label=\"Enter Value\" \n placeholder=\"#default_id or xpath\"\n [value]=\"getFormControlValue('value')\"\n [errors]=\"getFormControl('value')?.touched && getFormControl('value')?.invalid ? ['Value is required'] : []\"\n [required]=\"true\"\n (valueChange)=\"onFormControlChange('value', $event)\">\n </cqa-custom-input>\n <div class=\"cqa-w-full\">\n <label class=\"cqa-block cqa-text-[14px] cqa-font-medium cqa-text-[#374151] cqa-mb-1\">Labels (tags)</label>\n <div class=\"cqa-flex cqa-flex-wrap cqa-gap-2 cqa-p-2 cqa-border cqa-border-solid cqa-border-gray-200 cqa-rounded-md cqa-min-h-[42px]\">\n <span *ngFor=\"let tag of formLabels\"\n class=\"cqa-inline-flex cqa-items-center cqa-gap-1 cqa-px-2 cqa-py-1 cqa-bg-[#eff6ff] cqa-border cqa-border-[#c8e0ff] cqa-rounded-full cqa-text-[12px] cqa-text-[#3F43EE]\">\n {{ tag }}\n <button type=\"button\" (click)=\"removeTag(tag)\" class=\"cqa-p-0.5 hover:cqa-bg-[#c8e0ff] cqa-rounded cqa-cursor-pointer cqa-h-[16px] cqa-w-[16px]\">\n <mat-icon class=\"!cqa-w-3 !cqa-h-3 !cqa-text-[14px]\">close</mat-icon>\n </button>\n </span>\n <input type=\"text\"\n class=\"cqa-flex-1 cqa-min-w-[120px] cqa-px-2 cqa-py-1 cqa-text-sm cqa-border-0 cqa-outline-none cqa-bg-transparent\"\n placeholder=\"Type and press Enter to add\"\n [(ngModel)]=\"tagInputValue\"\n (keydown)=\"onTagInputKeydown($event)\"\n (blur)=\"addTag()\"\n [ngModelOptions]=\"{standalone: true}\">\n </div>\n </div>\n\n <div class=\"cqa-flex cqa-flex-col cqa-gap-3\">\n <div class=\"cqa-flex cqa-items-stretch cqa-gap-2 cqa-w-full\">\n <div class=\"cqa-flex-1 cqa-min-w-0\">\n <cqa-button variant=\"outlined\" btnSize=\"lg\" [text]=\"(elementId ? 'Cancel' : 'Select from Element list')\" [fullWidth]=\"true\" (clicked)=\"onCancel()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#414146]'\" [disabled]=\"saving\"></cqa-button>\n </div>\n <div class=\"cqa-flex-1 cqa-min-w-0\">\n <cqa-button variant=\"filled\" btnSize=\"lg\" [text]=\"saving ? 'Saving...' : (isEditMode ? 'Update' : 'Create')\" [fullWidth]=\"true\" (clicked)=\"onApply()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#3F43EE]'\" [disabled]=\"saving\"></cqa-button>\n </div>\n </div>\n </div>\n <a href=\"#\" *ngIf=\"isEditInDepthAvailable\" (click)=\"onEditInDepth($event)\"\n class=\"cqa-text-[#3F43EE] cqa-text-[12px] cqa-leading-[18px] cqa-font-medium cqa-flex cqa-items-center cqa-gap-1.5 cqa-no-underline hover:cqa-no-underline cqa-self-center\">\n <mat-icon class=\"!cqa-w-4 !cqa-h-4 !cqa-text-[16px]\">open_in_new</mat-icon>\n Edit in depth (open detailed right panel)\n </a>\n </ng-container>\n</div>\n\n\n", components: [{ type: i2.CustomInputComponent, selector: "cqa-custom-input", inputs: ["label", "type", "placeholder", "value", "disabled", "errors", "required", "ariaLabel", "size", "fullWidth", "maxLength", "showCharCount", "inputInlineStyle", "labelInlineStyle"], outputs: ["valueChange", "blurred", "focused", "enterPressed"] }, { type: i3.DynamicSelectFieldComponent, selector: "cqa-dynamic-select", inputs: ["form", "config"], outputs: ["selectionChange", "selectClick", "searchChange", "loadMore", "addCustomValue"] }, { type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i5.ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }], directives: [{ type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { 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]" }, { type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
237
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ElementFormComponent, decorators: [{
238
+ type: Component,
239
+ args: [{ selector: 'cqa-element-form', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"cqa-flex cqa-flex-col cqa-gap-4 cqa-px-1 cqa-pt-3\">\n <div *ngIf=\"isElementLoading && isEditMode\" class=\"cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-gap-3 cqa-py-8\">\n <svg class=\"cqa-animate-spin cqa-h-6 cqa-w-6 cqa-text-[#3F43EE]\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"cqa-opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\n <path class=\"cqa-opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n <span class=\"cqa-text-[#6B7280] cqa-text-sm\">Loading element data...</span>\n </div>\n <div *ngIf=\"!isElementLoading\" class=\"cqa-flex cqa-gap-1.5\">\n <cqa-custom-input \n class=\"cqa-w-1/2\" \n label=\"Name\" \n placeholder=\"default-element\"\n [value]=\"getFormControlValue('name')\"\n [errors]=\"getFormControl('name')?.touched && getFormControl('name')?.invalid ? ['Name is required'] : []\"\n [required]=\"true\"\n (valueChange)=\"onFormControlChange('name', $event)\">\n </cqa-custom-input>\n <div class=\"cqa-w-1/2\">\n <cqa-dynamic-select [form]=\"form\" [config]=\"screenNameSelectConfig\"\n (addCustomValue)=\"createScreenNameRequest.emit($event.value)\"\n class=\"cqa-w-full\">\n </cqa-dynamic-select>\n <div *ngIf=\"getFormControl('screenNameId')?.touched && getFormControl('screenNameId')?.invalid\" class=\"cqa-flex cqa-flex-col cqa-gap-1 cqa-mt-1.5\">\n <div class=\"cqa-flex cqa-items-start cqa-gap-1.5\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n class=\"cqa-flex-shrink-0 cqa-mt-0.5\">\n <path d=\"M7 1.75C4.1 1.75 1.75 4.1 1.75 7C1.75 9.9 4.1 12.25 7 12.25C9.9 12.25 12.25 9.9 12.25 7C12.25 4.1 9.9 1.75 7 1.75ZM7 9.625C6.65625 9.625 6.375 9.34375 6.375 9V7C6.375 6.65625 6.65625 6.375 7 6.375C7.34375 6.375 7.625 6.65625 7.625 7V9C7.625 9.34375 7.34375 9.625 7 9.625ZM7.625 5.25H6.375V4H7.625V5.25Z\" fill=\"#EF4444\"/>\n </svg>\n <span class=\"cqa-text-xs cqa-text-[#EF4444] cqa-font-medium cqa-leading-[18px]\">\n Screen Name is required\n </span>\n </div>\n </div>\n </div>\n </div>\n <ng-container *ngIf=\"!isElementLoading\">\n <cqa-custom-input \n class=\"cqa-w-full\" \n label=\"Enter Value\" \n placeholder=\"#default_id or xpath\"\n [value]=\"getFormControlValue('value')\"\n [errors]=\"getFormControl('value')?.touched && getFormControl('value')?.invalid ? ['Value is required'] : []\"\n [required]=\"true\"\n (valueChange)=\"onFormControlChange('value', $event)\">\n </cqa-custom-input>\n <div class=\"cqa-w-full\">\n <label class=\"cqa-block cqa-text-[14px] cqa-font-medium cqa-text-[#374151] cqa-mb-1\">Labels (tags)</label>\n <div class=\"cqa-flex cqa-flex-wrap cqa-gap-2 cqa-p-2 cqa-border cqa-border-solid cqa-border-gray-200 cqa-rounded-md cqa-min-h-[42px]\">\n <span *ngFor=\"let tag of formLabels\"\n class=\"cqa-inline-flex cqa-items-center cqa-gap-1 cqa-px-2 cqa-py-1 cqa-bg-[#eff6ff] cqa-border cqa-border-[#c8e0ff] cqa-rounded-full cqa-text-[12px] cqa-text-[#3F43EE]\">\n {{ tag }}\n <button type=\"button\" (click)=\"removeTag(tag)\" class=\"cqa-p-0.5 hover:cqa-bg-[#c8e0ff] cqa-rounded cqa-cursor-pointer cqa-h-[16px] cqa-w-[16px]\">\n <mat-icon class=\"!cqa-w-3 !cqa-h-3 !cqa-text-[14px]\">close</mat-icon>\n </button>\n </span>\n <input type=\"text\"\n class=\"cqa-flex-1 cqa-min-w-[120px] cqa-px-2 cqa-py-1 cqa-text-sm cqa-border-0 cqa-outline-none cqa-bg-transparent\"\n placeholder=\"Type and press Enter to add\"\n [(ngModel)]=\"tagInputValue\"\n (keydown)=\"onTagInputKeydown($event)\"\n (blur)=\"addTag()\"\n [ngModelOptions]=\"{standalone: true}\">\n </div>\n </div>\n\n <div class=\"cqa-flex cqa-flex-col cqa-gap-3\">\n <div class=\"cqa-flex cqa-items-stretch cqa-gap-2 cqa-w-full\">\n <div class=\"cqa-flex-1 cqa-min-w-0\">\n <cqa-button variant=\"outlined\" btnSize=\"lg\" [text]=\"(elementId ? 'Cancel' : 'Select from Element list')\" [fullWidth]=\"true\" (clicked)=\"onCancel()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#414146]'\" [disabled]=\"saving\"></cqa-button>\n </div>\n <div class=\"cqa-flex-1 cqa-min-w-0\">\n <cqa-button variant=\"filled\" btnSize=\"lg\" [text]=\"saving ? 'Saving...' : (isEditMode ? 'Update' : 'Create')\" [fullWidth]=\"true\" (clicked)=\"onApply()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#3F43EE]'\" [disabled]=\"saving\"></cqa-button>\n </div>\n </div>\n </div>\n <a href=\"#\" *ngIf=\"isEditInDepthAvailable\" (click)=\"onEditInDepth($event)\"\n class=\"cqa-text-[#3F43EE] cqa-text-[12px] cqa-leading-[18px] cqa-font-medium cqa-flex cqa-items-center cqa-gap-1.5 cqa-no-underline hover:cqa-no-underline cqa-self-center\">\n <mat-icon class=\"!cqa-w-4 !cqa-h-4 !cqa-text-[16px]\">open_in_new</mat-icon>\n Edit in depth (open detailed right panel)\n </a>\n </ng-container>\n</div>\n\n\n" }]
240
+ }], ctorParameters: function () { return [{ type: i1.FormBuilder, decorators: [{
241
+ type: Optional
242
+ }] }, { type: i0.ChangeDetectorRef, decorators: [{
243
+ type: Optional
244
+ }] }]; }, propDecorators: { elementId: [{
245
+ type: Input
246
+ }], element: [{
247
+ type: Input
248
+ }], screenNameOptions: [{
249
+ type: Input
250
+ }], hasMoreScreenNames: [{
251
+ type: Input
252
+ }], isLoadingScreenNames: [{
253
+ type: Input
254
+ }], isElementLoading: [{
255
+ type: Input
256
+ }], isEditMode: [{
257
+ type: Input
258
+ }], isCreateMode: [{
259
+ type: Input
260
+ }], isEditInDepthAvailable: [{
261
+ type: Input
262
+ }], createElement: [{
263
+ type: Output
264
+ }], updateElement: [{
265
+ type: Output
266
+ }], createScreenNameRequest: [{
267
+ type: Output
268
+ }], searchScreenName: [{
269
+ type: Output
270
+ }], loadMoreScreenNames: [{
271
+ type: Output
272
+ }], cancel: [{
273
+ type: Output
274
+ }], editInDepth: [{
275
+ type: Output
276
+ }] } });
277
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxlbWVudC1mb3JtLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvdGVzdC1jYXNlLWRldGFpbHMvZWxlbWVudC1wb3B1cC9lbGVtZW50LWZvcm0vZWxlbWVudC1mb3JtLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvdGVzdC1jYXNlLWRldGFpbHMvZWxlbWVudC1wb3B1cC9lbGVtZW50LWZvcm0vZWxlbWVudC1mb3JtLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUNULFlBQVksRUFDWixLQUFLLEVBR0wsUUFBUSxFQUNSLE1BQU0sR0FFUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsV0FBVyxFQUEwQixVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7Ozs7QUFXakYsTUFBTSxPQUFPLG9CQUFvQjtJQWdEL0IsWUFDYyxFQUFnQixFQUNDLEdBQXVCO1FBQXZCLFFBQUcsR0FBSCxHQUFHLENBQW9CO1FBL0N0RCwyQ0FBMkM7UUFDbEMsWUFBTyxHQUE2QixFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLENBQUM7UUFDckYsc0RBQXNEO1FBQzdDLHNCQUFpQixHQUF1QixFQUFFLENBQUM7UUFDcEQsa0VBQWtFO1FBQ3pELHVCQUFrQixHQUFZLEtBQUssQ0FBQztRQUM3QyxzRUFBc0U7UUFDN0QseUJBQW9CLEdBQVksS0FBSyxDQUFDO1FBQy9DLHVGQUF1RjtRQUM5RSxxQkFBZ0IsR0FBWSxLQUFLLENBQUM7UUFDM0MsaUNBQWlDO1FBQ3hCLGVBQVUsR0FBWSxLQUFLLENBQUM7UUFDckMsbUNBQW1DO1FBQzFCLGlCQUFZLEdBQVksS0FBSyxDQUFDO1FBRXZDLHlDQUF5QztRQUNo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Z0JBRUcsZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUVHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBRUcsWUFBWTtzQkFBcEIsS0FBSztnQkFHRyxzQkFBc0I7c0JBQTlCLEtBQUs7Z0JBR0ksYUFBYTtzQkFBdEIsTUFBTTtnQkFFRyxhQUFhO3NCQUF0QixNQUFNO2dCQUVHLHVCQUF1QjtzQkFBaEMsTUFBTTtnQkFFRyxnQkFBZ0I7c0JBQXpCLE1BQU07Z0JBRUcsbUJBQW1CO3NCQUE1QixNQUFNO2dCQUVHLE1BQU07c0JBQWYsTUFBTTtnQkFFRyxXQUFXO3NCQUFwQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25Jbml0LFxuICBPcHRpb25hbCxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2VzLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1CdWlsZGVyLCBGb3JtR3JvdXAsIEZvcm1Db250cm9sLCBWYWxpZGF0b3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgRHluYW1pY1NlbGVjdEZpZWxkQ29uZmlnLCBTZWxlY3RPcHRpb24gfSBmcm9tICcuLi8uLi8uLi9keW5hbWljLXNlbGVjdC9keW5hbWljLXNlbGVjdC1maWVsZC5jb21wb25lbnQnO1xuaW1wb3J0IHsgRWxlbWVudENyZWF0ZVBheWxvYWQsIEVsZW1lbnRVcGRhdGVQYXlsb2FkLCBTY3JlZW5OYW1lT3B0aW9uIH0gZnJvbSAnLi4vZWxlbWVudC1wb3B1cC1mb3JtLWRhdGEnO1xuaW1wb3J0IHsgRWxlbWVudFBvcHVwRGF0YUVsZW1lbnRzIH0gZnJvbSAnLi4vZWxlbWVudC1wb3B1cC1kYXRhJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnY3FhLWVsZW1lbnQtZm9ybScsXG4gIHRlbXBsYXRlVXJsOiAnLi9lbGVtZW50LWZvcm0uY29tcG9uZW50Lmh0bWwnLFxuICBob3N0OiB7IGNsYXNzOiAnY3FhLXVpLXJvb3QnIH0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBFbGVtZW50Rm9ybUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzIHtcbiAgLyoqIEVsZW1lbnQgSUQgd2hlbiBlZGl0aW5nIGV4aXN0aW5nIGVsZW1lbnQgKi9cbiAgQElucHV0KCkgZWxlbWVudElkPzogbnVtYmVyO1xuICAvKiogQ3VycmVudCBlbGVtZW50IGRhdGEgKGZvciBlZGl0IG1vZGUpICovXG4gIEBJbnB1dCgpIGVsZW1lbnQ6IEVsZW1lbnRQb3B1cERhdGFFbGVtZW50cyA9IHsgdGl0bGU6ICcnLCBzZWxlY3RvcjogJycsIGxhYmVsczogW10gfTtcbiAgLyoqIFNjcmVlbiBuYW1lIG9wdGlvbnMgZm9yIGF1dG9jb21wbGV0ZSAoZnJvbSBBUEkpICovXG4gIEBJbnB1dCgpIHNjcmVlbk5hbWVPcHRpb25zOiBTY3JlZW5OYW1lT3B0aW9uW10gPSBbXTtcbiAgLyoqIFdoZXRoZXIgbW9yZSBzY3JlZW4gbmFtZXMgYXJlIGF2YWlsYWJsZSBmb3IgaW5maW5pdGUgc2Nyb2xsICovXG4gIEBJbnB1dCgpIGhhc01vcmVTY3JlZW5OYW1lczogYm9vbGVhbiA9IGZhbHNlO1xuICAvKiogVHJ1ZSB3aGlsZSBwYXJlbnQgaXMgbG9hZGluZyBzY3JlZW4gbmFtZXMgKHNlYXJjaCBvciBsb2FkIG1vcmUpICovXG4gIEBJbnB1dCgpIGlzTG9hZGluZ1NjcmVlbk5hbWVzOiBib29sZWFuID0gZmFsc2U7XG4gIC8qKiBUcnVlIHdoaWxlIHBhcmVudCBpcyBmZXRjaGluZyBsYXRlc3QgZWxlbWVudCBkYXRhIGZvciBlZGl0IChzaG93cyBsb2FkaW5nIHN0YXRlKSAqL1xuICBASW5wdXQoKSBpc0VsZW1lbnRMb2FkaW5nOiBib29sZWFuID0gZmFsc2U7XG4gIC8qKiBXaGV0aGVyIHdlJ3JlIGluIGVkaXQgbW9kZSAqL1xuICBASW5wdXQoKSBpc0VkaXRNb2RlOiBib29sZWFuID0gZmFsc2U7XG4gIC8qKiBXaGV0aGVyIHdlJ3JlIGluIGNyZWF0ZSBtb2RlICovXG4gIEBJbnB1dCgpIGlzQ3JlYXRlTW9kZTogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8qKiBXaGV0aGVyIGVkaXQgaW4gZGVwdGggaXMgYXZhaWxhYmxlICovXG4gIEBJbnB1dCgpIGlzRWRpdEluRGVwdGhBdmFpbGFibGU6IGJvb2xlYW4gPSB0cnVlO1xuXG4gIC8qKiBFbWl0dGVkIHdoZW4gdXNlciBjcmVhdGVzIGEgbmV3IGVsZW1lbnQgKHBhcmVudCBzaG91bGQgY2FsbCBBUEkpICovXG4gIEBPdXRwdXQoKSBjcmVhdGVFbGVtZW50ID0gbmV3IEV2ZW50RW1pdHRlcjxFbGVtZW50Q3JlYXRlUGF5bG9hZD4oKTtcbiAgLyoqIEVtaXR0ZWQgd2hlbiB1c2VyIHVwZGF0ZXMgYW4gZWxlbWVudCAocGFyZW50IHNob3VsZCBjYWxsIEFQSSkgKi9cbiAgQE91dHB1dCgpIHVwZGF0ZUVsZW1lbnQgPSBuZXcgRXZlbnRFbWl0dGVyPEVsZW1lbnRVcGRhdGVQYXlsb2FkPigpO1xuICAvKiogRW1pdHRlZCB3aGVuIHVzZXIgcmVxdWVzdHMgdG8gY3JlYXRlIGEgbmV3IHNjcmVlbiBuYW1lICovXG4gIEBPdXRwdXQoKSBjcmVhdGVTY3JlZW5OYW1lUmVxdWVzdCA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICAvKiogRW1pdHRlZCB3aGVuIHVzZXIgc2VhcmNoZXMgc2NyZWVuIG5hbWVzIChzZXJ2ZXIgc2VhcmNoKSAqL1xuICBAT3V0cHV0KCkgc2VhcmNoU2NyZWVuTmFtZSA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICAvKiogRW1pdHRlZCB3aGVuIHVzZXIgc2Nyb2xscyB0byBsb2FkIG1vcmUgc2NyZWVuIG5hbWVzIChwYXNzZXMgY3VycmVudCBzZWFyY2ggcXVlcnkpICovXG4gIEBPdXRwdXQoKSBsb2FkTW9yZVNjcmVlbk5hbWVzID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIC8qKiBFbWl0dGVkIHdoZW4gdXNlciBjbGlja3MgXCJTZWxlY3QgZnJvbSBFbGVtZW50IGxpc3RcIiBvciBcIkNhbmNlbFwiICovXG4gIEBPdXRwdXQoKSBjYW5jZWwgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBFbWl0dGVkIHdoZW4gdXNlciBjbGlja3MgXCJFZGl0IGluIGRlcHRoXCIgKi9cbiAgQE91dHB1dCgpIGVkaXRJbkRlcHRoID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIGZvcm0hOiBGb3JtR3JvdXA7XG4gIC8qKiBMYWJlbHMgKHRhZ3MpIGFzIHN0cmluZyBhcnJheSBmb3IgbXVsdGktdGFnIGlucHV0ICovXG4gIGZvcm1MYWJlbHM6IHN0cmluZ1tdID0gW107XG4gIC8qKiBDdXJyZW50IHRhZyBpbnB1dCB2YWx1ZSAqL1xuICB0YWdJbnB1dFZhbHVlID0gJyc7XG4gIC8qKiBDb25maWcgZm9yIHNjcmVlbiBuYW1lIGR5bmFtaWMtc2VsZWN0IChzZXJ2ZXIgc2VhcmNoLCBhbGxvd0N1c3RvbVZhbHVlLCBpbmZpbml0ZSBzY3JvbGwpICovXG4gIHNjcmVlbk5hbWVTZWxlY3RDb25maWchOiBEeW5hbWljU2VsZWN0RmllbGRDb25maWc7XG4gIC8qKiBXaGV0aGVyIHdlJ3JlIHNhdmluZyAoZGlzYWJsZSBidXR0b25zKSAqL1xuICBzYXZpbmcgPSBmYWxzZTtcblxuICBwcml2YXRlIGZiOiBGb3JtQnVpbGRlcjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBAT3B0aW9uYWwoKSBmYj86IEZvcm1CdWlsZGVyLFxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgcmVhZG9ubHkgY2RyPzogQ2hhbmdlRGV0ZWN0b3JSZWZcbiAgKSB7XG4gICAgdGhpcy5mYiA9IGZiIHx8IG5ldyBGb3JtQnVpbGRlcigpO1xuICAgIHRoaXMuaW5pdGlhbGl6ZUZvcm0oKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlc1snc2NyZWVuTmFtZU9wdGlvbnMnXSB8fCBjaGFuZ2VzWydoYXNNb3JlU2NyZWVuTmFtZXMnXSB8fCBjaGFuZ2VzWydpc0xvYWRpbmdTY3JlZW5OYW1lcyddKSB7XG4gICAgICB0aGlzLnVwZGF0ZVNjcmVlbk5hbWVTZWxlY3RDb25maWcoKTtcbiAgICB9XG4gICAgaWYgKChjaGFuZ2VzWydlbGVtZW50J10gfHwgY2hhbmdlc1snZWxlbWVudElkJ10pICYmIHRoaXMuZWxlbWVudElkKSB7XG4gICAgICB0aGlzLnBvcHVsYXRlRm9ybUZvckVkaXQoKTtcbiAgICB9IGVsc2UgaWYgKGNoYW5nZXNbJ2VsZW1lbnQnXSAmJiAhdGhpcy5lbGVtZW50SWQgJiYgdGhpcy5pc0NyZWF0ZU1vZGUpIHtcbiAgICAgIHRoaXMucG9wdWxhdGVGb3JtRm9yQ3JlYXRlV2l0aEVsZW1lbnQoKTtcbiAgICB9XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5lbGVtZW50SWQpIHtcbiAgICAgIHRoaXMucG9wdWxhdGVGb3JtRm9yRWRpdCgpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5pc0NyZWF0ZU1vZGUgJiYgdGhpcy5lbGVtZW50KSB7XG4gICAgICB0aGlzLnBvcHVsYXRlRm9ybUZvckNyZWF0ZVdpdGhFbGVtZW50KCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplRm9ybSgpOiB2b2lkIHtcbiAgICB0aGlzLmZvcm0gPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgIG5hbWU6IFsnJywgW1ZhbGlkYXRvcnMucmVxdWlyZWRdXSxcbiAgICAgIHNjcmVlbk5hbWVJZDogW251bGwgYXMgbnVtYmVyIHwgbnVsbCwgW1ZhbGlkYXRvcnMucmVxdWlyZWRdXSxcbiAgICAgIHZhbHVlOiBbJycsIFtWYWxpZGF0b3JzLnJlcXVpcmVkXV0sXG4gICAgfSk7XG4gICAgdGhpcy51cGRhdGVTY3JlZW5OYW1lU2VsZWN0Q29uZmlnKCk7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVNjcmVlbk5hbWVTZWxlY3RDb25maWcoKTogdm9pZCB7XG4gICAgY29uc3Qgb3B0czogU2VsZWN0T3B0aW9uW10gPSAodGhpcy5zY3JlZW5OYW1lT3B0aW9ucyB8fCBbXSkubWFwKChvKSA9PiAoe1xuICAgICAgaWQ6IG8uaWQsXG4gICAgICB2YWx1ZTogby5pZCxcbiAgICAgIG5hbWU6IG8ubmFtZSxcbiAgICAgIGxhYmVsOiBvLm5hbWUsXG4gICAgfSkpO1xuICAgIGNvbnN0IGN1cnJlbnRJZCA9IHRoaXMuZm9ybT8uZ2V0KCdzY3JlZW5OYW1lSWQnKT8udmFsdWU7XG4gICAgaWYgKGN1cnJlbnRJZCAmJiB0aGlzLmVsZW1lbnQ/LnNjcmVlbk5hbWVJZCA9PT0gY3VycmVudElkICYmIHRoaXMuZWxlbWVudD8uc2NyZWVuTmFtZSkge1xuICAgICAgY29uc3QgZXhpc3RzID0gb3B0cy5zb21lKChvKSA9PiBvLmlkID09PSBjdXJyZW50SWQpO1xuICAgICAgaWYgKCFleGlzdHMpIHtcbiAgICAgICAgb3B0cy51bnNoaWZ0KHtcbiAgICAgICAgICBpZDogY3VycmVudElkLFxuICAgICAgICAgIHZhbHVlOiBjdXJyZW50SWQsXG4gICAgICAgICAgbmFtZTogU3RyaW5nKHRoaXMuZWxlbWVudC5zY3JlZW5OYW1lKSxcbiAgICAgICAgICBsYWJlbDogU3RyaW5nKHRoaXMuZWxlbWVudC5zY3JlZW5OYW1lKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuc2NyZWVuTmFtZVNlbGVjdENvbmZpZyA9IHtcbiAgICAgIGtleTogJ3NjcmVlbk5hbWVJZCcsXG4gICAgICBsYWJlbDogJ1NjcmVlbiBOYW1lJyxcbiAgICAgIHBsYWNlaG9sZGVyOiAnU2VsZWN0IG9yIGNyZWF0ZSBzY3JlZW4nLFxuICAgICAgc2VhcmNoYWJsZTogdHJ1ZSxcbiAgICAgIHNlcnZlclNlYXJjaDogdHJ1ZSxcbiAgICAgIGFsbG93Q3VzdG9tVmFsdWU6IHRydWUsXG4gICAgICBvcHRpb25zOiBvcHRzLFxuICAgICAgaGFzTW9yZTogdGhpcy5oYXNNb3JlU2NyZWVuTmFtZXMsXG4gICAgICBpc0xvYWRpbmc6IHRoaXMuaXNMb2FkaW5nU2NyZWVuTmFtZXMsXG4gICAgICBvblNlYXJjaDogKHEpID0+IHRoaXMuc2VhcmNoU2NyZWVuTmFtZS5lbWl0KHEgfHwgJycpLFxuICAgICAgb25Mb2FkTW9yZTogKHEpID0+IHRoaXMubG9hZE1vcmVTY3JlZW5OYW1lcy5lbWl0KHEgfHwgJycpLFxuICAgIH07XG4gICAgdGhpcy5jZHI/Lm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgcHJpdmF0ZSBwb3B1bGF0ZUZvcm1Gb3JFZGl0KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmVsZW1lbnQgJiYgdGhpcy5lbGVtZW50SWQgIT0gbnVsbCkge1xuICAgICAgdGhpcy5pc0VkaXRNb2RlID0gdHJ1ZTtcbiAgICAgIHRoaXMuaXNDcmVhdGVNb2RlID0gZmFsc2U7XG4gICAgICB0aGlzLmZvcm0ucGF0Y2hWYWx1ZSh7XG4gICAgICAgIG5hbWU6IHRoaXMuZWxlbWVudC50aXRsZSA/PyAnJyxcbiAgICAgICAgc2NyZWVuTmFtZUlkOiB0aGlzLmVsZW1lbnQuc2NyZWVuTmFtZUlkID8/IG51bGwsXG4gICAgICAgIHZhbHVlOiB0aGlzLmVsZW1lbnQuc2VsZWN0b3IgPz8gJycsXG4gICAgICB9KTtcbiAgICAgIHRoaXMuZm9ybUxhYmVscyA9IFsuLi4odGhpcy5lbGVtZW50LmxhYmVscyB8fCBbXSldO1xuICAgICAgdGhpcy51cGRhdGVTY3JlZW5OYW1lU2VsZWN0Q29uZmlnKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaXNFZGl0TW9kZSA9IGZhbHNlO1xuICAgICAgdGhpcy5pc0NyZWF0ZU1vZGUgPSBmYWxzZTtcbiAgICAgIHRoaXMuZm9ybUxhYmVscyA9IFtdO1xuICAgIH1cbiAgICB0aGlzLmNkcj8ubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBwcml2YXRlIHBvcHVsYXRlRm9ybUZvckNyZWF0ZVdpdGhFbGVtZW50KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmVsZW1lbnQpIHtcbiAgICAgIHRoaXMuaXNDcmVhdGVNb2RlID0gdHJ1ZTtcbiAgICAgIHRoaXMuaXNFZGl0TW9kZSA9IGZhbHNlO1xuICAgICAgdGhpcy5mb3JtLnBhdGNoVmFsdWUoe1xuICAgICAgICBuYW1lOiB0aGlzLmVsZW1lbnQudGl0bGUgPz8gJycsXG4gICAgICAgIHNjcmVlbk5hbWVJZDogdGhpcy5lbGVtZW50LnNjcmVlbk5hbWVJZCA/PyBudWxsLFxuICAgICAgICB2YWx1ZTogdGhpcy5lbGVtZW50LnNlbGVjdG9yID8/ICcnLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmZvcm1MYWJlbHMgPSBbLi4uKHRoaXMuZWxlbWVudC5sYWJlbHMgfHwgW10pXTtcbiAgICAgIHRoaXMudXBkYXRlU2NyZWVuTmFtZVNlbGVjdENvbmZpZygpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmlzQ3JlYXRlTW9kZSA9IHRydWU7XG4gICAgICB0aGlzLmlzRWRpdE1vZGUgPSBmYWxzZTtcbiAgICAgIHRoaXMuZm9ybUxhYmVscyA9IFtdO1xuICAgIH1cbiAgICB0aGlzLmNkcj8ubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICAvKiogQ2FsbGVkIGJ5IHBhcmVudCB3aGVuIGEgbmV3IHNjcmVlbiBuYW1lIHdhcyBjcmVhdGVkIChzbyB3ZSBjYW4gc2V0IHRoZSBzZWxlY3RlZCB2YWx1ZSkgKi9cbiAgc2V0Q3JlYXRlZFNjcmVlbk5hbWUob3B0OiB7IGlkOiBudW1iZXI7IG5hbWU6IHN0cmluZyB9KTogdm9pZCB7XG4gICAgdGhpcy5mb3JtLmdldCgnc2NyZWVuTmFtZUlkJyk/LnNldFZhbHVlKG9wdC5pZCk7XG4gICAgdGhpcy51cGRhdGVTY3JlZW5OYW1lU2VsZWN0Q29uZmlnKCk7XG4gICAgdGhpcy5jZHI/Lm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgb25BcHBseSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5mb3JtLmludmFsaWQpIHtcbiAgICAgIE9iamVjdC5rZXlzKHRoaXMuZm9ybS5jb250cm9scykuZm9yRWFjaCgoa2V5KSA9PlxuICAgICAgICB0aGlzLmZvcm0uZ2V0KGtleSk/Lm1hcmtBc1RvdWNoZWQoKVxuICAgICAgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBmb3JtVmFsdWUgPSB0aGlzLmZvcm0udmFsdWU7XG4gICAgY29uc3Qgc2NyZWVuTmFtZUlkID0gZm9ybVZhbHVlLnNjcmVlbk5hbWVJZDtcbiAgICBjb25zdCBzZWxlY3RlZE9wdCA9IHRoaXMuc2NyZWVuTmFtZU9wdGlvbnMuZmluZCgobykgPT4gby5pZCA9PT0gc2NyZWVuTmFtZUlkKTtcbiAgICBjb25zdCBzY3JlZW5OYW1lTmFtZSA9IHNlbGVjdGVkT3B0Py5uYW1lID8gU3RyaW5nKHNlbGVjdGVkT3B0Lm5hbWUpLnRyaW0oKSA6ICcnO1xuICAgIGlmICghc2NyZWVuTmFtZUlkIHx8ICFzY3JlZW5OYW1lTmFtZSkge1xuICAgICAgdGhpcy5mb3JtLmdldCgnc2NyZWVuTmFtZUlkJyk/LnNldEVycm9ycyh7IHJlcXVpcmVkOiB0cnVlIH0pO1xuICAgICAgdGhpcy5mb3JtLmdldCgnc2NyZWVuTmFtZUlkJyk/Lm1hcmtBc1RvdWNoZWQoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnNhdmluZyA9IHRydWU7XG4gICAgdGhpcy5jZHI/Lm1hcmtGb3JDaGVjaygpO1xuXG4gICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgIG5hbWU6IGZvcm1WYWx1ZS5uYW1lLnRyaW0oKSxcbiAgICAgIHNjcmVlbk5hbWVJZCxcbiAgICAgIHNjcmVlbk5hbWVOYW1lLFxuICAgICAgbG9jYXRvclZhbHVlOiBmb3JtVmFsdWUudmFsdWUudHJpbSgpLFxuICAgICAgbGFiZWxzOiBbLi4udGhpcy5mb3JtTGFiZWxzXSxcbiAgICB9O1xuXG4gICAgaWYgKHRoaXMuaXNFZGl0TW9kZSAmJiB0aGlzLmVsZW1lbnRJZCkge1xuICAgICAgdGhpcy51cGRhdGVFbGVtZW50LmVtaXQoe1xuICAgICAgICAuLi5wYXlsb2FkLFxuICAgICAgICBlbGVtZW50SWQ6IHRoaXMuZWxlbWVudElkLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY3JlYXRlRWxlbWVudC5lbWl0KHBheWxvYWQpO1xuICAgIH1cbiAgfVxuXG4gIG9uQ3JlYXRlT3JVcGRhdGVTdWNjZXNzKCk6IHZvaWQge1xuICAgIHRoaXMuc2F2aW5nID0gZmFsc2U7XG4gICAgdGhpcy5jZHI/Lm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgb25DcmVhdGVPclVwZGF0ZUVycm9yKCk6IHZvaWQge1xuICAgIHRoaXMuc2F2aW5nID0gZmFsc2U7XG4gICAgdGhpcy5jZHI/Lm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgb25DYW5jZWwoKTogdm9pZCB7XG4gICAgdGhpcy5jYW5jZWwuZW1pdCgpO1xuICB9XG5cbiAgb25FZGl0SW5EZXB0aChldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMuZWRpdEluRGVwdGguZW1pdCgpO1xuICB9XG5cbiAgZ2V0Rm9ybUNvbnRyb2woY29udHJvbE5hbWU6IHN0cmluZyk6IEZvcm1Db250cm9sIHtcbiAgICByZXR1cm4gdGhpcy5mb3JtLmdldChjb250cm9sTmFtZSkgYXMgRm9ybUNvbnRyb2w7XG4gIH1cblxuICBnZXRGb3JtQ29udHJvbFZhbHVlKGNvbnRyb2xOYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmZvcm0uZ2V0KGNvbnRyb2xOYW1lKT8udmFsdWUgfHwgJyc7XG4gIH1cblxuICBvbkZvcm1Db250cm9sQ2hhbmdlKGNvbnRyb2xOYW1lOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmZvcm0ucGF0Y2hWYWx1ZSh7IFtjb250cm9sTmFtZV06IHZhbHVlIH0pO1xuICAgIHRoaXMuY2RyPy5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIC8qKiBBZGQgYSB0YWcgKGxhYmVsKSAqL1xuICBhZGRUYWcodGFnPzogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgdCA9ICh0YWcgfHwgdGhpcy50YWdJbnB1dFZhbHVlIHx8ICcnKS50cmltKCk7XG4gICAgaWYgKHQgJiYgIXRoaXMuZm9ybUxhYmVscy5pbmNsdWRlcyh0KSkge1xuICAgICAgdGhpcy5mb3JtTGFiZWxzID0gWy4uLnRoaXMuZm9ybUxhYmVscywgdF07XG4gICAgICB0aGlzLnRhZ0lucHV0VmFsdWUgPSAnJztcbiAgICAgIHRoaXMuY2RyPy5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG4gIH1cblxuICByZW1vdmVUYWcodGFnOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmZvcm1MYWJlbHMgPSB0aGlzLmZvcm1MYWJlbHMuZmlsdGVyKChsKSA9PiBsICE9PSB0YWcpO1xuICAgIHRoaXMuY2RyPy5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIG9uVGFnSW5wdXRLZXlkb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50LmtleSA9PT0gJ0VudGVyJyB8fCBldmVudC5rZXkgPT09ICcsJykge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHRoaXMuYWRkVGFnKCk7XG4gICAgfVxuICB9XG59XG5cblxuIiwiPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtZ2FwLTQgY3FhLXB4LTEgY3FhLXB0LTNcIj5cbiAgPGRpdiAqbmdJZj1cImlzRWxlbWVudExvYWRpbmcgJiYgaXNFZGl0TW9kZVwiIGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1pdGVtcy1jZW50ZXIgY3FhLWp1c3RpZnktY2VudGVyIGNxYS1nYXAtMyBjcWEtcHktOFwiPlxuICAgIDxzdmcgY2xhc3M9XCJjcWEtYW5pbWF0ZS1zcGluIGNxYS1oLTYgY3FhLXctNiBjcWEtdGV4dC1bIzNGNDNFRV1cIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgZmlsbD1cIm5vbmVcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCI+XG4gICAgICA8Y2lyY2xlIGNsYXNzPVwiY3FhLW9wYWNpdHktMjVcIiBjeD1cIjEyXCIgY3k9XCIxMlwiIHI9XCIxMFwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjRcIj48L2NpcmNsZT5cbiAgICAgIDxwYXRoIGNsYXNzPVwiY3FhLW9wYWNpdHktNzVcIiBmaWxsPVwiY3VycmVudENvbG9yXCIgZD1cIk00IDEyYTggOCAwIDAxOC04VjBDNS4zNzMgMCAwIDUuMzczIDAgMTJoNHptMiA1LjI5MUE3Ljk2MiA3Ljk2MiAwIDAxNCAxMkgwYzAgMy4wNDIgMS4xMzUgNS44MjQgMyA3LjkzOGwzLTIuNjQ3elwiPjwvcGF0aD5cbiAgICA8L3N2Zz5cbiAgICA8c3BhbiBjbGFzcz1cImNxYS10ZXh0LVsjNkI3MjgwXSBjcWEtdGV4dC1zbVwiPkxvYWRpbmcgZWxlbWVudCBkYXRhLi4uPC9zcGFuPlxuICA8L2Rpdj5cbiAgPGRpdiAqbmdJZj1cIiFpc0VsZW1lbnRMb2FkaW5nXCIgY2xhc3M9XCJjcWEtZmxleCBjcWEtZ2FwLTEuNVwiPlxuICAgIDxjcWEtY3VzdG9tLWlucHV0IFxuICAgICAgY2xhc3M9XCJjcWEtdy0xLzJcIiBcbiAgICAgIGxhYmVsPVwiTmFtZVwiIFxuICAgICAgcGxhY2Vob2xkZXI9XCJkZWZhdWx0LWVsZW1lbnRcIlxuICAgICAgW3ZhbHVlXT1cImdldEZvcm1Db250cm9sVmFsdWUoJ25hbWUnKVwiXG4gICAgICBbZXJyb3JzXT1cImdldEZvcm1Db250cm9sKCduYW1lJyk/LnRvdWNoZWQgJiYgZ2V0Rm9ybUNvbnRyb2woJ25hbWUnKT8uaW52YWxpZCA/IFsnTmFtZSBpcyByZXF1aXJlZCddIDogW11cIlxuICAgICAgW3JlcXVpcmVkXT1cInRydWVcIlxuICAgICAgKHZhbHVlQ2hhbmdlKT1cIm9uRm9ybUNvbnRyb2xDaGFuZ2UoJ25hbWUnLCAkZXZlbnQpXCI+XG4gICAgPC9jcWEtY3VzdG9tLWlucHV0PlxuICAgIDxkaXYgY2xhc3M9XCJjcWEtdy0xLzJcIj5cbiAgICAgIDxjcWEtZHluYW1pYy1zZWxlY3QgW2Zvcm1dPVwiZm9ybVwiIFtjb25maWddPVwic2NyZWVuTmFtZVNlbGVjdENvbmZpZ1wiXG4gICAgICAgIChhZGRDdXN0b21WYWx1ZSk9XCJjcmVhdGVTY3JlZW5OYW1lUmVxdWVzdC5lbWl0KCRldmVudC52YWx1ZSlcIlxuICAgICAgICBjbGFzcz1cImNxYS13LWZ1bGxcIj5cbiAgICAgIDwvY3FhLWR5bmFtaWMtc2VsZWN0PlxuICAgICAgPGRpdiAqbmdJZj1cImdldEZvcm1Db250cm9sKCdzY3JlZW5OYW1lSWQnKT8udG91Y2hlZCAmJiBnZXRGb3JtQ29udHJvbCgnc2NyZWVuTmFtZUlkJyk/LmludmFsaWRcIiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtZ2FwLTEgY3FhLW10LTEuNVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLXN0YXJ0IGNxYS1nYXAtMS41XCI+XG4gICAgICAgICAgPHN2Z1xuICAgICAgICAgICAgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiXG4gICAgICAgICAgICB3aWR0aD1cIjE0XCJcbiAgICAgICAgICAgIGhlaWdodD1cIjE0XCJcbiAgICAgICAgICAgIHZpZXdCb3g9XCIwIDAgMTQgMTRcIlxuICAgICAgICAgICAgZmlsbD1cIm5vbmVcIlxuICAgICAgICAgICAgY2xhc3M9XCJjcWEtZmxleC1zaHJpbmstMCBjcWEtbXQtMC41XCI+XG4gICAgICAgICAgICA8cGF0aCBkPVwiTTcgMS43NUM0LjEgMS43NSAxLjc1IDQuMSAxLjc1IDdDMS43NSA5LjkgNC4xIDEyLjI1IDcgMTIuMjVDOS45IDEyLjI1IDEyLjI1IDkuOSAxMi4yNSA3QzEyLjI1IDQuMSA5LjkgMS43NSA3IDEuNzVaTTcgOS42MjVDNi42NTYyNSA5LjYyNSA2LjM3NSA5LjM0Mzc1IDYuMzc1IDlWN0M2LjM3NSA2LjY1NjI1IDYuNjU2MjUgNi4zNzUgNyA2LjM3NUM3LjM0Mzc1IDYuMzc1IDcuNjI1IDYuNjU2MjUgNy42MjUgN1Y5QzcuNjI1IDkuMzQzNzUgNy4zNDM3NSA5LjYyNSA3IDkuNjI1Wk03LjYyNSA1LjI1SDYuMzc1VjRINy42MjVWNS4yNVpcIiBmaWxsPVwiI0VGNDQ0NFwiLz5cbiAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImNxYS10ZXh0LXhzIGNxYS10ZXh0LVsjRUY0NDQ0XSBjcWEtZm9udC1tZWRpdW0gY3FhLWxlYWRpbmctWzE4cHhdXCI+XG4gICAgICAgICAgICBTY3JlZW4gTmFtZSBpcyByZXF1aXJlZFxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNFbGVtZW50TG9hZGluZ1wiPlxuICAgIDxjcWEtY3VzdG9tLWlucHV0IFxuICAgICAgY2xhc3M9XCJjcWEtdy1mdWxsXCIgIFxuICAgICAgbGFiZWw9XCJFbnRlciBWYWx1ZVwiIFxuICAgICAgcGxhY2Vob2xkZXI9XCIjZGVmYXVsdF9pZCBvciB4cGF0aFwiXG4gICAgICBbdmFsdWVdPVwiZ2V0Rm9ybUNvbnRyb2xWYWx1ZSgndmFsdWUnKVwiXG4gICAgICBbZXJyb3JzXT1cImdldEZvcm1Db250cm9sKCd2YWx1ZScpPy50b3VjaGVkICYmIGdldEZvcm1Db250cm9sKCd2YWx1ZScpPy5pbnZhbGlkID8gWydWYWx1ZSBpcyByZXF1aXJlZCddIDogW11cIlxuICAgICAgW3JlcXVpcmVkXT1cInRydWVcIlxuICAgICAgKHZhbHVlQ2hhbmdlKT1cIm9uRm9ybUNvbnRyb2xDaGFuZ2UoJ3ZhbHVlJywgJGV2ZW50KVwiPlxuICAgIDwvY3FhLWN1c3RvbS1pbnB1dD5cbiAgICA8ZGl2IGNsYXNzPVwiY3FhLXctZnVsbFwiPlxuICAgICAgPGxhYmVsIGNsYXNzPVwiY3FhLWJsb2NrIGNxYS10ZXh0LVsxNHB4XSBjcWEtZm9udC1tZWRpdW0gY3FhLXRleHQtWyMzNzQxNTFdIGNxYS1tYi0xXCI+TGFiZWxzICh0YWdzKTwvbGFiZWw+XG4gICAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtd3JhcCBjcWEtZ2FwLTIgY3FhLXAtMiBjcWEtYm9yZGVyIGNxYS1ib3JkZXItc29saWQgY3FhLWJvcmRlci1ncmF5LTIwMCBjcWEtcm91bmRlZC1tZCBjcWEtbWluLWgtWzQycHhdXCI+XG4gICAgICAgIDxzcGFuICpuZ0Zvcj1cImxldCB0YWcgb2YgZm9ybUxhYmVsc1wiXG4gICAgICAgICAgY2xhc3M9XCJjcWEtaW5saW5lLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTEgY3FhLXB4LTIgY3FhLXB5LTEgY3FhLWJnLVsjZWZmNmZmXSBjcWEtYm9yZGVyIGNxYS1ib3JkZXItWyNjOGUwZmZdIGNxYS1yb3VuZGVkLWZ1bGwgY3FhLXRleHQtWzEycHhdIGNxYS10ZXh0LVsjM0Y0M0VFXVwiPlxuICAgICAgICAgIHt7IHRhZyB9fVxuICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJyZW1vdmVUYWcodGFnKVwiIGNsYXNzPVwiY3FhLXAtMC41IGhvdmVyOmNxYS1iZy1bI2M4ZTBmZl0gY3FhLXJvdW5kZWQgY3FhLWN1cnNvci1wb2ludGVyIGNxYS1oLVsxNnB4XSBjcWEtdy1bMTZweF1cIj5cbiAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIiFjcWEtdy0zICFjcWEtaC0zICFjcWEtdGV4dC1bMTRweF1cIj5jbG9zZTwvbWF0LWljb24+XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICBjbGFzcz1cImNxYS1mbGV4LTEgY3FhLW1pbi13LVsxMjBweF0gY3FhLXB4LTIgY3FhLXB5LTEgY3FhLXRleHQtc20gY3FhLWJvcmRlci0wIGNxYS1vdXRsaW5lLW5vbmUgY3FhLWJnLXRyYW5zcGFyZW50XCJcbiAgICAgICAgICBwbGFjZWhvbGRlcj1cIlR5cGUgYW5kIHByZXNzIEVudGVyIHRvIGFkZFwiXG4gICAgICAgICAgWyhuZ01vZGVsKV09XCJ0YWdJbnB1dFZhbHVlXCJcbiAgICAgICAgICAoa2V5ZG93bik9XCJvblRhZ0lucHV0S2V5ZG93bigkZXZlbnQpXCJcbiAgICAgICAgICAoYmx1cik9XCJhZGRUYWcoKVwiXG4gICAgICAgICAgW25nTW9kZWxPcHRpb25zXT1cIntzdGFuZGFsb25lOiB0cnVlfVwiPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1nYXAtM1wiPlxuICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1zdHJldGNoIGNxYS1nYXAtMiBjcWEtdy1mdWxsXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleC0xIGNxYS1taW4tdy0wXCI+XG4gICAgICAgICAgPGNxYS1idXR0b24gdmFyaWFudD1cIm91dGxpbmVkXCIgYnRuU2l6ZT1cImxnXCIgW3RleHRdPVwiKGVsZW1lbnRJZCA/ICdDYW5jZWwnIDogJ1NlbGVjdCBmcm9tIEVsZW1lbnQgbGlzdCcpXCIgW2Z1bGxXaWR0aF09XCJ0cnVlXCIgKGNsaWNrZWQpPVwib25DYW5jZWwoKVwiXG4gICAgICAgICAgICBbY3VzdG9tQ2xhc3NdPVwiJ2NxYS10ZXh0LVsxNHB4XSBjcWEtcHktWzlweF0gY3FhLWJvcmRlci1bIzQxNDE0Nl0nXCIgW2Rpc2FibGVkXT1cInNhdmluZ1wiPjwvY3FhLWJ1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleC0xIGNxYS1taW4tdy0wXCI+XG4gICAgICAgICAgPGNxYS1idXR0b24gdmFyaWFudD1cImZpbGxlZFwiIGJ0blNpemU9XCJsZ1wiIFt0ZXh0XT1cInNhdmluZyA/ICdTYXZpbmcuLi4nIDogKGlzRWRpdE1vZGUgPyAnVXBkYXRlJyA6ICdDcmVhdGUnKVwiIFtmdWxsV2lkdGhdPVwidHJ1ZVwiIChjbGlja2VkKT1cIm9uQXBwbHkoKVwiXG4gICAgICAgICAgICBbY3VzdG9tQ2xhc3NdPVwiJ2NxYS10ZXh0LVsxNHB4XSBjcWEtcHktWzlweF0gY3FhLWJvcmRlci1bIzNGNDNFRV0nXCIgW2Rpc2FibGVkXT1cInNhdmluZ1wiPjwvY3FhLWJ1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8YSBocmVmPVwiI1wiICpuZ0lmPVwiaXNFZGl0SW5EZXB0aEF2YWlsYWJsZVwiIChjbGljayk9XCJvbkVkaXRJbkRlcHRoKCRldmVudClcIlxuICAgICAgY2xhc3M9XCJjcWEtdGV4dC1bIzNGNDNFRV0gY3FhLXRleHQtWzEycHhdIGNxYS1sZWFkaW5nLVsxOHB4XSBjcWEtZm9udC1tZWRpdW0gY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTEuNSBjcWEtbm8tdW5kZXJsaW5lIGhvdmVyOmNxYS1uby11bmRlcmxpbmUgY3FhLXNlbGYtY2VudGVyXCI+XG4gICAgICA8bWF0LWljb24gY2xhc3M9XCIhY3FhLXctNCAhY3FhLWgtNCAhY3FhLXRleHQtWzE2cHhdXCI+b3Blbl9pbl9uZXc8L21hdC1pY29uPlxuICAgICAgRWRpdCBpbiBkZXB0aCAob3BlbiBkZXRhaWxlZCByaWdodCBwYW5lbClcbiAgICA8L2E+XG4gIDwvbmctY29udGFpbmVyPlxuPC9kaXY+XG5cblxuIl19