@rangertechnologies/ngnxt 2.1.254 → 2.1.255-beta
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.
- package/fesm2022/rangertechnologies-ngnxt.mjs +135 -166
- package/fesm2022/rangertechnologies-ngnxt.mjs.map +1 -1
- package/lib/components/pick-location/pick-location.component.d.ts +0 -1
- package/package.json +4 -6
- package/rangertechnologies-ngnxt-2.1.255-beta.tgz +0 -0
- package/esm2022/environments/version.mjs +0 -15
- package/esm2022/lib/components/button/nxt-button.component.mjs +0 -154
- package/esm2022/lib/components/custom-calendar/custom-calendar.component.mjs +0 -360
- package/esm2022/lib/components/custom-dropdown/custom-dropdown.component.mjs +0 -263
- package/esm2022/lib/components/custom-model/custom-model.component.mjs +0 -53
- package/esm2022/lib/components/custom-radio/custom-radio.component.mjs +0 -158
- package/esm2022/lib/components/datatable/datatable.component.mjs +0 -1744
- package/esm2022/lib/components/file-upload/file-upload.component.mjs +0 -292
- package/esm2022/lib/components/icon-selector/icon-selector.component.mjs +0 -106
- package/esm2022/lib/components/image-cropper/component/cropper.state.mjs +0 -208
- package/esm2022/lib/components/image-cropper/component/image-cropper.component.mjs +0 -562
- package/esm2022/lib/components/image-cropper/interfaces/basic-event.interface.mjs +0 -2
- package/esm2022/lib/components/image-cropper/interfaces/cropper-options.interface.mjs +0 -2
- package/esm2022/lib/components/image-cropper/interfaces/cropper-position.interface.mjs +0 -2
- package/esm2022/lib/components/image-cropper/interfaces/dimensions.interface.mjs +0 -2
- package/esm2022/lib/components/image-cropper/interfaces/exif-transform.interface.mjs +0 -2
- package/esm2022/lib/components/image-cropper/interfaces/image-cropped-event.interface.mjs +0 -2
- package/esm2022/lib/components/image-cropper/interfaces/image-transform.interface.mjs +0 -2
- package/esm2022/lib/components/image-cropper/interfaces/index.mjs +0 -2
- package/esm2022/lib/components/image-cropper/interfaces/loaded-image.interface.mjs +0 -2
- package/esm2022/lib/components/image-cropper/interfaces/move-start.interface.mjs +0 -8
- package/esm2022/lib/components/image-cropper/services/crop.service.mjs +0 -139
- package/esm2022/lib/components/image-cropper/services/load-image.service.mjs +0 -194
- package/esm2022/lib/components/image-cropper/utils/cropper-position.utils.mjs +0 -239
- package/esm2022/lib/components/image-cropper/utils/exif.utils.mjs +0 -79
- package/esm2022/lib/components/image-cropper/utils/keyboard.utils.mjs +0 -40
- package/esm2022/lib/components/image-cropper/utils/percentage.utils.mjs +0 -4
- package/esm2022/lib/components/image-cropper/utils/resize.utils.mjs +0 -75
- package/esm2022/lib/components/list-view-filter/list-view-filter.component.mjs +0 -392
- package/esm2022/lib/components/nxt-input/nxt-input.component.mjs +0 -2972
- package/esm2022/lib/components/pagination/pagination.component.mjs +0 -105
- package/esm2022/lib/components/pick-location/pick-location.component.mjs +0 -220
- package/esm2022/lib/components/search-box/search-box.component.mjs +0 -470
- package/esm2022/lib/country.json +0 -43237
- package/esm2022/lib/interfaces/actionMeta.mjs +0 -2
- package/esm2022/lib/interfaces/dependencyMeta.mjs +0 -2
- package/esm2022/lib/model/bookletWrapper.mjs +0 -7
- package/esm2022/lib/model/changeWrapper.mjs +0 -10
- package/esm2022/lib/model/errorWrapper.mjs +0 -6
- package/esm2022/lib/nxt-app.component.mjs +0 -22
- package/esm2022/lib/nxt-app.module.mjs +0 -115
- package/esm2022/lib/nxt-app.service.mjs +0 -14
- package/esm2022/lib/pages/booklet/booklet.component.mjs +0 -616
- package/esm2022/lib/pages/builder/element/element.component.mjs +0 -483
- package/esm2022/lib/pages/builder/form/form.component.mjs +0 -48
- package/esm2022/lib/pages/builder/properties/common-fields.constants.mjs +0 -97
- package/esm2022/lib/pages/builder/properties/properties.component.mjs +0 -1121
- package/esm2022/lib/pages/builder/templates/templates.component.mjs +0 -35
- package/esm2022/lib/pages/pdfDesigner/pdf-designer/pdf-designer.component.mjs +0 -639
- package/esm2022/lib/pages/pdfDesigner/pdf-properties/pdf-properties.component.mjs +0 -1114
- package/esm2022/lib/pages/questionbook/questionbook.component.mjs +0 -784
- package/esm2022/lib/pages/questionnaire/questionnaire.component.mjs +0 -2206
- package/esm2022/lib/pipe/button-styles.pipe.mjs +0 -26
- package/esm2022/lib/pipe/custom-translate.pipe.mjs +0 -37
- package/esm2022/lib/pipe/get-value.pipe.mjs +0 -54
- package/esm2022/lib/pipe/question-by-row.pipe.mjs +0 -51
- package/esm2022/lib/pipe/search-filter/search-filter.pipe.mjs +0 -40
- package/esm2022/lib/pipe/svg/svg.pipe.mjs +0 -26
- package/esm2022/lib/sample.mjs +0 -3715
- package/esm2022/lib/services/change/change.service.mjs +0 -46
- package/esm2022/lib/services/country/country.service.mjs +0 -135
- package/esm2022/lib/services/data/data.service.mjs +0 -100
- package/esm2022/lib/services/form-builder/form-builder.service.mjs +0 -474
- package/esm2022/lib/services/pdf-designer/pdf-designer.service.mjs +0 -395
- package/esm2022/lib/services/salesforce/salesforce.service.mjs +0 -41
- package/esm2022/lib/services/shared/shared.service.mjs +0 -100
- package/esm2022/lib/services/storage/storage.service.mjs +0 -59
- package/esm2022/lib/services/template/template.service.mjs +0 -335
- package/esm2022/lib/services/translation/translation.service.mjs +0 -121
- package/esm2022/lib/wrapper.mjs +0 -175
- package/esm2022/public-api.mjs +0 -22
- package/esm2022/rangertechnologies-ngnxt.mjs +0 -5
- package/rangertechnologies-ngnxt-2.1.254.tgz +0 -0
|
@@ -1,1121 +0,0 @@
|
|
|
1
|
-
import { ChangeDetectionStrategy, Component, EventEmitter, HostListener, Input, Output, signal, computed, ViewChild } from '@angular/core';
|
|
2
|
-
import { CommonModule } from '@angular/common';
|
|
3
|
-
import { FormsModule } from '@angular/forms';
|
|
4
|
-
import { v4 as uuidv4 } from 'uuid';
|
|
5
|
-
//AP-25JUN25-Importing common constants for element, field, and appearance properties
|
|
6
|
-
import { COMMON_ELEMENT_PROPS, COMMON_OPTIONS_FIELD, COMMON_FIELD_PROPS, COMMON_APPEARANCE_PROPS } from '../properties/common-fields.constants';
|
|
7
|
-
import { NgClass, NgFor, NgIf } from '@angular/common';
|
|
8
|
-
import { Pipe } from '@angular/core';
|
|
9
|
-
import { NxtCustomTranslatePipe } from '../../../pipe/custom-translate.pipe';
|
|
10
|
-
import * as i0 from "@angular/core";
|
|
11
|
-
import * as i1 from "../../../services/form-builder/form-builder.service";
|
|
12
|
-
import * as i2 from "../../../services/template/template.service";
|
|
13
|
-
import * as i3 from "../../../services/translation/translation.service";
|
|
14
|
-
import * as i4 from "@angular/common";
|
|
15
|
-
import * as i5 from "@angular/forms";
|
|
16
|
-
// Custom pipe for path-based value access
|
|
17
|
-
export class GetValueByPathPipe {
|
|
18
|
-
transform(obj, path, defaultValue = '') {
|
|
19
|
-
if (!obj || !path)
|
|
20
|
-
return defaultValue;
|
|
21
|
-
return path.split('.').reduce((o, k) => o?.[k] ?? defaultValue, obj);
|
|
22
|
-
}
|
|
23
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GetValueByPathPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
24
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: GetValueByPathPipe, isStandalone: true, name: "getValueByPath" });
|
|
25
|
-
}
|
|
26
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GetValueByPathPipe, decorators: [{
|
|
27
|
-
type: Pipe,
|
|
28
|
-
args: [{
|
|
29
|
-
name: 'getValueByPath',
|
|
30
|
-
standalone: true,
|
|
31
|
-
pure: true
|
|
32
|
-
}]
|
|
33
|
-
}] });
|
|
34
|
-
export class PropertiesComponent {
|
|
35
|
-
formBuilderService;
|
|
36
|
-
templateService;
|
|
37
|
-
translationService;
|
|
38
|
-
cdr;
|
|
39
|
-
templateSelected = false;
|
|
40
|
-
set selectedElementType(value) {
|
|
41
|
-
this.selectedElementTypeSig.set(value);
|
|
42
|
-
}
|
|
43
|
-
formButtonHandler = new EventEmitter();
|
|
44
|
-
templateSaveHandler = new EventEmitter();
|
|
45
|
-
dropdown;
|
|
46
|
-
// Signals for reactive state
|
|
47
|
-
selectedElementTypeSig = signal('');
|
|
48
|
-
selectedElement = signal(null);
|
|
49
|
-
selectedElementIndex = signal(-1);
|
|
50
|
-
headerSelect = signal(false);
|
|
51
|
-
book = signal(null);
|
|
52
|
-
bookId = signal(null);
|
|
53
|
-
activeTab = signal('attributes');
|
|
54
|
-
selectColumn = signal(null);
|
|
55
|
-
transform = signal({
|
|
56
|
-
translateUnit: 'px',
|
|
57
|
-
scale: 1,
|
|
58
|
-
rotate: 0,
|
|
59
|
-
flipH: false,
|
|
60
|
-
flipV: false,
|
|
61
|
-
translateH: 0,
|
|
62
|
-
translateV: 0
|
|
63
|
-
});
|
|
64
|
-
canvasRotation = signal(0);
|
|
65
|
-
cropper = signal(undefined);
|
|
66
|
-
loading = signal(false);
|
|
67
|
-
isLinkDropdownOpen = signal(false);
|
|
68
|
-
errorMessage = signal('');
|
|
69
|
-
bookSubtext = signal({
|
|
70
|
-
endpoint: 'https://dev-api.valarhr.com/nxt',
|
|
71
|
-
variable: null,
|
|
72
|
-
field: ['label', 'name'],
|
|
73
|
-
defaultField: 'label'
|
|
74
|
-
});
|
|
75
|
-
isStyleExpanded = signal(false);
|
|
76
|
-
cropperMaxHeight = 0;
|
|
77
|
-
cropperMaxWidth = 0;
|
|
78
|
-
cropperMinHeight = 0;
|
|
79
|
-
cropperMinWidth = 0;
|
|
80
|
-
cropperStaticWidth = 0;
|
|
81
|
-
cropperStaticHeight = 0;
|
|
82
|
-
aspectRatio = 4 / 3;
|
|
83
|
-
roundCropper = false;
|
|
84
|
-
isExpanded = false;
|
|
85
|
-
alignImage = 'center';
|
|
86
|
-
elementType = ['Header', 'Line', 'Space', 'Table', 'TableColumn', 'Checkbox', 'Dropdown', 'Radio', "Text", "Calendar", "Date", "Time", "DateTime", "Email", "Book", "List", "TextArea", "RichTextArea", "Number", "Image", "Label", "Boolean", "File", "Icon", 'Button'];
|
|
87
|
-
// Add these properties to your component class
|
|
88
|
-
_cachedProperties = null;
|
|
89
|
-
_lastSelectedElement = null;
|
|
90
|
-
_lastSelectedColumn = null;
|
|
91
|
-
// Computed signals for memoization
|
|
92
|
-
fieldAsString = computed(() => this.bookSubtext().field.join(', '));
|
|
93
|
-
filteredColumns = computed(() => {
|
|
94
|
-
const fieldsMeta = this.selectedElement()?.fieldsMeta ?? [];
|
|
95
|
-
return Array.isArray(fieldsMeta)
|
|
96
|
-
? fieldsMeta.filter(column => column.uniqueIdentifier !== this.selectColumn())
|
|
97
|
-
: [];
|
|
98
|
-
});
|
|
99
|
-
// Memoized properties
|
|
100
|
-
elementProperties = computed(() => this.createElementProperties());
|
|
101
|
-
formBuilderLanguageCode = 'en';
|
|
102
|
-
copied = false;
|
|
103
|
-
constructor(formBuilderService, templateService, translationService, cdr) {
|
|
104
|
-
this.formBuilderService = formBuilderService;
|
|
105
|
-
this.templateService = templateService;
|
|
106
|
-
this.translationService = translationService;
|
|
107
|
-
this.cdr = cdr;
|
|
108
|
-
}
|
|
109
|
-
ngOnInit() {
|
|
110
|
-
this.formBuilderService.selectHeaderSubject$.subscribe(header => {
|
|
111
|
-
if (header) {
|
|
112
|
-
this.selectedElement.set({ type: header });
|
|
113
|
-
this.headerSelect.set(true);
|
|
114
|
-
const bookData = this.formBuilderService.getBook();
|
|
115
|
-
this.book.set(bookData);
|
|
116
|
-
this.bookId.set(bookData?.records[0]?.id);
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
this.formBuilderService.selectedElement$.subscribe(index => {
|
|
120
|
-
this.selectedElementIndex.set(index);
|
|
121
|
-
this.headerSelect.set(false);
|
|
122
|
-
if (index >= 0) {
|
|
123
|
-
const elements = this.formBuilderService.getElements();
|
|
124
|
-
if (!elements || !Array.isArray(elements) || index >= elements.length) {
|
|
125
|
-
this.selectedElement.set(null); // Reset selectedElement if invalid
|
|
126
|
-
this.selectColumn.set(null);
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
const element = { ...elements[index] }; // Safe to spread since we checked
|
|
130
|
-
let fieldsMeta = element?.fieldsMeta;
|
|
131
|
-
if (element?.type === 'Table') {
|
|
132
|
-
try {
|
|
133
|
-
fieldsMeta = Array.isArray(fieldsMeta)
|
|
134
|
-
? fieldsMeta
|
|
135
|
-
: JSON.parse(fieldsMeta || '[]');
|
|
136
|
-
}
|
|
137
|
-
catch (e) {
|
|
138
|
-
// console.error('Error parsing fieldsMeta:', e);
|
|
139
|
-
fieldsMeta = [];
|
|
140
|
-
}
|
|
141
|
-
this.selectColumn.set(this.formBuilderService.getSelectTableColumn() ?? null);
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
this.selectColumn.set(null);
|
|
145
|
-
}
|
|
146
|
-
this.selectedElement.set({ ...element, fieldsMeta });
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
this.selectedElement.set(null); // Reset if index is invalid
|
|
150
|
-
this.selectColumn.set(null);
|
|
151
|
-
}
|
|
152
|
-
const element = this.selectedElement();
|
|
153
|
-
if (element) {
|
|
154
|
-
let subText = element.subText;
|
|
155
|
-
if (typeof subText === 'string' && subText.trim() !== '') {
|
|
156
|
-
try {
|
|
157
|
-
subText = JSON.parse(subText);
|
|
158
|
-
}
|
|
159
|
-
catch (e) {
|
|
160
|
-
// console.error('Error parsing subText:', e);
|
|
161
|
-
subText = {};
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
else if (typeof subText !== 'object' || subText === null) {
|
|
165
|
-
subText = {};
|
|
166
|
-
}
|
|
167
|
-
const arrayFields = ['field', 'queryParameter', 'sourceQuestionId', 'queryField', 'queryValue'];
|
|
168
|
-
if (subText) {
|
|
169
|
-
arrayFields.forEach(key => {
|
|
170
|
-
if (Array.isArray(subText[key])) {
|
|
171
|
-
subText[key] = subText[key].join(', ');
|
|
172
|
-
}
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
if (element.type === 'Table') {
|
|
176
|
-
element.fieldsMeta.forEach(field => {
|
|
177
|
-
if (field?.question?.subText) {
|
|
178
|
-
arrayFields.forEach(key => {
|
|
179
|
-
if (Array.isArray(field.question.subText[key])) {
|
|
180
|
-
field.question.subText[key] = field.question.subText[key].join(', ');
|
|
181
|
-
}
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
this.selectedElement.update(el => ({ ...el, subText }));
|
|
187
|
-
}
|
|
188
|
-
});
|
|
189
|
-
// SKS28JUL25 formbuilder current element translation value update
|
|
190
|
-
this.translationService.formBuilderTranslationsLoaded$.subscribe(event => {
|
|
191
|
-
this.formBuilderLanguageCode = event;
|
|
192
|
-
const elements = this.formBuilderService.getElements();
|
|
193
|
-
if (Array.isArray(elements) && this.selectedElement()) {
|
|
194
|
-
const matchedElement = elements.find((ele) => ele.id === this.selectedElement().id);
|
|
195
|
-
if (matchedElement) {
|
|
196
|
-
this.selectedElement.set(matchedElement);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
if (this.selectedElement()?.type === "Header") {
|
|
200
|
-
const bookData = this.formBuilderService.getBook();
|
|
201
|
-
this.book.set(bookData);
|
|
202
|
-
this.selectedElement.set({ ...this.selectedElement() });
|
|
203
|
-
}
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
createElementProperties() {
|
|
207
|
-
return {
|
|
208
|
-
Header: {
|
|
209
|
-
elementProps: [
|
|
210
|
-
{ label: 'Label', placeholder: 'Enter Text', type: 'text', key: 'title', isTranslate: true, labelPath: 'LABEL' }
|
|
211
|
-
],
|
|
212
|
-
},
|
|
213
|
-
Line: {
|
|
214
|
-
elementProps: [
|
|
215
|
-
{ label: 'Line Width', type: 'fieldSize', key: 'size', labelPath: 'LINE_WIDTH' },
|
|
216
|
-
{ label: 'Padding Top', type: 'number', key: 'paddingTop', placeholder: 'Enter padding top', labelPath: 'PADDING_TOP' },
|
|
217
|
-
{ label: 'Padding Bottom', type: 'number', key: 'paddingBottom', placeholder: 'Enter padding bottom', labelPath: 'PADDING_BOTTOM' },
|
|
218
|
-
{
|
|
219
|
-
label: 'Line Style', type: 'select', key: 'lineStyle', labelPath: 'LINE_STYLE',
|
|
220
|
-
options: [
|
|
221
|
-
{ label: 'Solid', value: 'Solid', labelPath: 'SOLID' },
|
|
222
|
-
{ label: 'Dashed', value: 'Dashed', labelPath: 'DASHED' },
|
|
223
|
-
{ label: 'Dotted', value: 'Dotted', labelPath: 'DOTTED' }
|
|
224
|
-
]
|
|
225
|
-
}
|
|
226
|
-
],
|
|
227
|
-
fieldProps: []
|
|
228
|
-
},
|
|
229
|
-
Space: {
|
|
230
|
-
elementProps: [
|
|
231
|
-
{ label: 'Element', type: 'number', key: 'questionNumber', labelPath: 'ELEMENT' },
|
|
232
|
-
{ label: 'Field Size', type: 'fieldSize', key: 'size', labelPath: 'FIELD_SIZE' },
|
|
233
|
-
],
|
|
234
|
-
fieldProps: []
|
|
235
|
-
},
|
|
236
|
-
Table: {
|
|
237
|
-
elementProps: [
|
|
238
|
-
{ label: 'Is Label', placeholder: 'Enter Text', type: 'checkbox', key: 'style.showLabel', labelPath: 'IS_LABEL' },
|
|
239
|
-
{ label: 'primaryKey', placeholder: 'Enter Text', type: 'checkbox', key: 'primaryKey', labelPath: 'PRIMARY_KEY' },
|
|
240
|
-
{ label: 'tableName', placeholder: 'Enter here', type: 'text', key: 'questionText', isTranslate: true, labelPath: 'TABLE_NAME' },
|
|
241
|
-
{ label: 'inputTextAlignment', placeholder: 'Left', type: 'text', key: 'inputTextAlignment', labelPath: 'INPUT_TEXT_ALIGNMENT' },
|
|
242
|
-
{ label: 'tableScaleSize', placeholder: '06 - Full Scale', type: 'text', key: 'tableScaleSize', labelPath: 'TABLE_SCALE_SIZE' },
|
|
243
|
-
{ label: 'isNosIndicator', placeholder: '06 - Full Scale', type: 'checkbox', key: 'tableConfig.isNosIndicator', labelPath: 'IS_NOS_INDICATOR' },
|
|
244
|
-
{ label: 'isPagination', placeholder: '06 - Full Scale', type: 'checkbox', key: 'tableConfig.isPagination', labelPath: 'IS_PAGINATION' },
|
|
245
|
-
{ label: 'addInlineRecord', placeholder: '06 - Full Scale', type: 'checkbox', key: 'tableConfig.addInlineRecord', labelPath: 'ADD_INLINE_RECORD' },
|
|
246
|
-
{ label: 'actionButton', placeholder: '06 - Full Scale', type: 'checkbox', key: 'tableConfig.actionButton', labelPath: 'ACTION_BUTTON' },
|
|
247
|
-
{ label: 'searchBar', placeholder: '06 - Full Scale', type: 'checkbox', key: 'tableConfig.searchBar', labelPath: 'SEARCH_BAR' },
|
|
248
|
-
{ label: 'isDeleteRow', placeholder: '06 - Full Scale', type: 'checkbox', key: 'tableConfig.isDeleteRow', labelPath: 'IS_DELETE_ROW' },
|
|
249
|
-
{ label: 'isEditRow', placeholder: '06 - Full Scale', type: 'checkbox', key: 'tableConfig.isEditRow', labelPath: 'IS_EDIT_ROW' },
|
|
250
|
-
{ label: 'isButtons', placeholder: '06 - Full Scale', type: 'checkbox', key: 'tableConfig.isButtons', labelPath: 'IS_BUTTONS' },
|
|
251
|
-
{ label: 'rowChoice', placeholder: '', type: 'text', key: 'rowChoice', labelPath: 'ROW_CHOICE' },
|
|
252
|
-
{ label: 'questionNumber', type: 'number', key: 'questionNumber', labelPath: 'QUESTION_NUMBER' },
|
|
253
|
-
{ label: 'Field Size', type: 'fieldSize', key: 'size', labelPath: 'FIELD_SIZE' },
|
|
254
|
-
],
|
|
255
|
-
fieldProps: [
|
|
256
|
-
{ label: 'tableId', placeholder: 'Emp_Table_01', type: 'text', key: 'tableId', isTranslate: true, labelPath: 'TABLE_ID' },
|
|
257
|
-
{ label: 'helpText', placeholder: 'Enter message', type: 'text', key: 'helpText', isTranslate: true, labelPath: 'HELP_TEXT' },
|
|
258
|
-
{ label: 'defaultValue', placeholder: 'Default Value', type: 'text', key: 'defaultValue', labelPath: 'DEFAULT_VALUE' },
|
|
259
|
-
{ label: 'Reference', placeholder: 'Reference Field', type: 'text', key: 'referenceField', labelPath: 'REFERENCE_FIELD' },
|
|
260
|
-
{
|
|
261
|
-
label: 'Sub Text', placeholder: 'Enter Text', type: 'subQuestion', key: 'isSubText', labelPath: 'SUB_TEXT',
|
|
262
|
-
subQuestion: [
|
|
263
|
-
{ label: 'End Point', placeholder: 'endpoint', type: 'text', key: 'subText.endpoint', labelPath: 'END_POINT' },
|
|
264
|
-
{ label: 'Variable', placeholder: 'variable', type: 'text', key: 'subText.variable', labelPath: 'VARIABLE' },
|
|
265
|
-
{ label: 'Field', placeholder: 'field', type: 'text', key: 'subText.field', labelPath: 'FIELD' },
|
|
266
|
-
{ label: 'Query Parameter', placeholder: 'queryParameter', type: 'text', key: 'subText.queryParameter', labelPath: 'QUERY_PARAMETER' },
|
|
267
|
-
{ label: 'Default Field', placeholder: 'defaultField', type: 'text', key: 'subText.defaultField', labelPath: 'DEFAULT_FIELD' },
|
|
268
|
-
{ label: 'Label Field', placeholder: 'labelField', type: 'text', key: 'subText.labelField', labelPath: 'LABEL_FIELD' },
|
|
269
|
-
{ label: 'Value Field', placeholder: 'valueField', type: 'text', key: 'subText.valueField', labelPath: 'VALUE_FIELD' },
|
|
270
|
-
{ label: 'Source Question Id', placeholder: 'sourceQuestionId', type: 'text', key: 'subText.sourceQuestionId', labelPath: 'SOURCE_QUESTION_ID' },
|
|
271
|
-
{ label: 'Dependent Value', placeholder: 'dependentValue', type: 'text', key: 'subText.dependentValue', labelPath: 'DEPENDENT_VALUE' },
|
|
272
|
-
{ label: 'Dependent Field', placeholder: 'isDependentField', type: 'boolean', key: 'subText.isDependentField', labelPath: 'DEPENDENT_FIELD' },
|
|
273
|
-
{ label: 'Query Field', placeholder: 'queryField', type: 'text', key: 'subText.queryField', labelPath: 'QUERY_FIELD' },
|
|
274
|
-
{ label: 'Query Value', placeholder: 'queryValue', type: 'text', key: 'subText.queryValue', labelPath: 'QUERY_VALUE' },
|
|
275
|
-
{ label: 'Query Value Ref', placeholder: 'queryValueRef', type: 'text', key: 'subText.queryValueReference', labelPath: 'QUERY_VALUE_REF' },
|
|
276
|
-
{ label: 'Unique Key', placeholder: 'uniqueKey', type: 'text', key: 'subText.uniqueKey', labelPath: 'UNIQUE_KEY' },
|
|
277
|
-
]
|
|
278
|
-
},
|
|
279
|
-
],
|
|
280
|
-
appearance: [
|
|
281
|
-
{ label: 'Select Font', type: 'select', key: 'font', placeholder: 'Left', required: true, labelPath: 'SELECT_FONT', options: [
|
|
282
|
-
{ label: 'Helvetica Neue', value: 'Helvetica Neue', labelPath: 'HELVETICA_NEUE' },
|
|
283
|
-
{ label: 'Arial', value: 'Arial', labelPath: 'ARIAL' },
|
|
284
|
-
{ label: 'Times New Roman', value: 'Times New Roman', labelPath: 'TIMES_NEW_ROMAN' },
|
|
285
|
-
{ label: 'Roboto', value: 'Roboto', labelPath: 'ROBOTO' }
|
|
286
|
-
] },
|
|
287
|
-
{ label: 'Font Color', type: 'color', key: 'fontColor', defaultValue: '', required: true, labelPath: 'FONT_COLOR' },
|
|
288
|
-
{ label: 'Font Size', type: 'select', key: 'fontSize', defaultValue: '', required: true, labelPath: 'FONT_SIZE', options: [
|
|
289
|
-
{ label: 'Small', value: '12px', labelPath: 'SMALL' },
|
|
290
|
-
{ label: 'Medium', value: '14px', labelPath: 'MEDIUM' },
|
|
291
|
-
{ label: 'Large', value: '16px', labelPath: 'LARGE' }
|
|
292
|
-
] },
|
|
293
|
-
{ label: 'Font Width', type: 'select', key: 'fontWeight', defaultValue: '', required: true, labelPath: 'FONT_WIDTH', options: [
|
|
294
|
-
{ value: '400', label: '400-Normal', labelPath: '400_NORMAL' },
|
|
295
|
-
{ value: '500', label: '500-Medium', labelPath: '500_MEDIUM' },
|
|
296
|
-
{ value: '600', label: '600-Semi Bold', labelPath: '600_SEMI_BOLD' },
|
|
297
|
-
{ value: '700', label: '700-Bold', labelPath: '700_BOLD' }
|
|
298
|
-
] },
|
|
299
|
-
{ label: 'Duplicate Field', type: 'button-toggle', key: 'duplicateField', defaultValue: false, labelPath: 'DUPLICATE_FIELD' }
|
|
300
|
-
]
|
|
301
|
-
},
|
|
302
|
-
TableColumn: {
|
|
303
|
-
elementProps: [
|
|
304
|
-
{ label: 'Type', placeholder: 'Text', type: 'select', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'fldType', required: true, labelPath: 'TYPE', options: this.elementType.map(f => ({ label: f, value: f, labelPath: f.toUpperCase() })) },
|
|
305
|
-
{ label: 'headerLabels', placeholder: 'Enter here', type: 'text', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'label', isTranslate: true, labelPath: 'HEADER_LABELS' },
|
|
306
|
-
{ label: 'apiName', placeholder: 'Enter here', type: 'text', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'apiName', labelPath: 'API_NAME' },
|
|
307
|
-
{
|
|
308
|
-
label: 'Summary Column', placeholder: 'Summary Column', type: 'subQuestion', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'summaryColumn', labelPath: 'SUMMARY_COLUMN',
|
|
309
|
-
subQuestion: [
|
|
310
|
-
{ label: 'Type', placeholder: 'Enter here', type: 'text', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'fldType', labelPath: 'TYPE' },
|
|
311
|
-
{ label: 'Operation', placeholder: 'Enter here', type: 'text', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'operation', labelPath: 'OPERATION' },
|
|
312
|
-
{ label: 'Operands', placeholder: 'Enter here', type: 'array', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'operands', labelPath: 'OPERANDS' },
|
|
313
|
-
]
|
|
314
|
-
},
|
|
315
|
-
{
|
|
316
|
-
label: 'Summary Row', placeholder: 'Summary Row', type: 'subQuestion', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'summaryRow', labelPath: 'SUMMARY_ROW',
|
|
317
|
-
subQuestion: [
|
|
318
|
-
{ label: 'Type', placeholder: 'Enter here', type: 'text', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'fldType', labelPath: 'TYPE' },
|
|
319
|
-
{ label: 'operation', placeholder: 'operation', type: 'text', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'operation', labelPath: 'OPERATION' },
|
|
320
|
-
{ label: 'column', placeholder: 'Enter here', type: 'radio', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'column', labelPath: 'COLUMN' },
|
|
321
|
-
{ label: 'columns', placeholder: 'Enter here', type: 'array', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'columns', labelPath: 'COLUMNS' },
|
|
322
|
-
{ label: 'operands', placeholder: 'Enter here', type: 'array', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'operands', labelPath: 'OPERANDS' },
|
|
323
|
-
]
|
|
324
|
-
},
|
|
325
|
-
{ label: 'textAlignment', placeholder: 'Left', type: 'text', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'textAlignment', labelPath: 'TEXT_ALIGNMENT' },
|
|
326
|
-
{ label: 'columnScaleSize', placeholder: '06 - Full Scale', type: 'text', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'columnScaleSize', labelPath: 'COLUMN_SCALE_SIZE' },
|
|
327
|
-
],
|
|
328
|
-
fieldProps: [],
|
|
329
|
-
appearance: []
|
|
330
|
-
},
|
|
331
|
-
Checkbox: this.createElementConfig({ customFieldProps: COMMON_OPTIONS_FIELD.map(opt => ({ ...opt, type: 'checkbox' })) }),
|
|
332
|
-
Dropdown: this.createElementConfig({ customFieldProps: COMMON_OPTIONS_FIELD.map(opt => ({ ...opt, type: 'dropdown' })) }),
|
|
333
|
-
Radio: this.createElementConfig({ customFieldProps: COMMON_OPTIONS_FIELD.map(opt => ({ ...opt, type: 'checkbox' })) }),
|
|
334
|
-
Text: this.createElementConfig(),
|
|
335
|
-
Calendar: this.createElementConfig(),
|
|
336
|
-
Date: this.createElementConfig(),
|
|
337
|
-
Time: this.createElementConfig(),
|
|
338
|
-
DateTime: this.createElementConfig(),
|
|
339
|
-
Email: this.createElementConfig(),
|
|
340
|
-
Book: this.createElementConfig(),
|
|
341
|
-
List: this.createElementConfig(),
|
|
342
|
-
TextArea: this.createElementConfig(),
|
|
343
|
-
RichTextArea: this.createElementConfig(),
|
|
344
|
-
Number: this.createElementConfig(),
|
|
345
|
-
Image: this.createElementConfig(),
|
|
346
|
-
Label: this.createElementConfig(),
|
|
347
|
-
Boolean: this.createElementConfig(),
|
|
348
|
-
File: this.createElementConfig(),
|
|
349
|
-
Icon: this.createElementConfig(), //MSM10JUL25 icon selector element
|
|
350
|
-
Button: this.createElementConfig(),
|
|
351
|
-
};
|
|
352
|
-
}
|
|
353
|
-
createElementConfig(config) {
|
|
354
|
-
return {
|
|
355
|
-
elementProps: [...COMMON_ELEMENT_PROPS, ...(config?.customElementProps || [])],
|
|
356
|
-
fieldProps: [...COMMON_FIELD_PROPS, ...(config?.customFieldProps || [])],
|
|
357
|
-
appearance: [...COMMON_APPEARANCE_PROPS, ...(config?.customAppearanceProps || [])]
|
|
358
|
-
};
|
|
359
|
-
}
|
|
360
|
-
// AP 23MAY25 - Add a new button with default styling
|
|
361
|
-
addNewButton() {
|
|
362
|
-
const lastPercent = this.book()?.questionbook?.action?.slice(-1)[0]?.positionPercent ?? 0;
|
|
363
|
-
const buttons = {
|
|
364
|
-
name: '',
|
|
365
|
-
eventtoemit: '',
|
|
366
|
-
alt: '',
|
|
367
|
-
endpoint: '',
|
|
368
|
-
method: '',
|
|
369
|
-
id: this.formBuilderService.addElementWithId(),
|
|
370
|
-
positionPercent: lastPercent + 10,
|
|
371
|
-
width: 100,
|
|
372
|
-
borderRadius: 6,
|
|
373
|
-
alignment: 'flex-start'
|
|
374
|
-
};
|
|
375
|
-
this.formBuilderService.updateQuestionBookActionButtons(buttons, 'add');
|
|
376
|
-
this.book.update(book => ({ ...book }));
|
|
377
|
-
}
|
|
378
|
-
//AP 23MAY25 - Remove a button from the action list
|
|
379
|
-
removeButton(btn) {
|
|
380
|
-
this.formBuilderService.updateQuestionBookActionButtons(btn, 'remove');
|
|
381
|
-
this.book.update(book => ({ ...book }));
|
|
382
|
-
}
|
|
383
|
-
//AP 23MAY25 - Update a specific property of a button
|
|
384
|
-
onButtonPropertyChange(index, key, value, isTranslate = false) {
|
|
385
|
-
const buttons = this.book()?.questionbook?.action ?? [];
|
|
386
|
-
if (buttons[index]) {
|
|
387
|
-
buttons[index][key] = value;
|
|
388
|
-
this.book.update(book => ({ ...book, questionbook: { ...book.questionbook, action: buttons } }));
|
|
389
|
-
}
|
|
390
|
-
let button = buttons[index];
|
|
391
|
-
if (isTranslate) {
|
|
392
|
-
//SKS28JUL25 Refresh the book signal from service
|
|
393
|
-
const updatedBook = this.formBuilderService.getBook();
|
|
394
|
-
this.book.set(updatedBook);
|
|
395
|
-
//SKS28JUL25 Work with a mutable copy
|
|
396
|
-
const currentBook = this.book();
|
|
397
|
-
const translationMap = currentBook.translationMap || {};
|
|
398
|
-
const currentLang = this.translationService.getFormBuilderLanguage();
|
|
399
|
-
//SKS28JUL25 Ensure nested structure exists
|
|
400
|
-
if (!translationMap[currentLang])
|
|
401
|
-
translationMap[currentLang] = {};
|
|
402
|
-
if (!translationMap[currentLang][button.id])
|
|
403
|
-
translationMap[currentLang][button.id] = {};
|
|
404
|
-
//SKS28JUL25 Set the translated value
|
|
405
|
-
translationMap[currentLang][button.id][key] = value;
|
|
406
|
-
//SKS28JUL25 Update book and re-set the signal
|
|
407
|
-
currentBook.translationMap = translationMap;
|
|
408
|
-
if (currentLang === 'en') {
|
|
409
|
-
this.translationService.updateTranslations(translationMap);
|
|
410
|
-
}
|
|
411
|
-
this.book.set(currentBook); // Trigger reactive update
|
|
412
|
-
//SKS28JUL25 Update in service if needed
|
|
413
|
-
this.formBuilderService.updateBook(currentBook);
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
//AP-10MAR25 Updates the title using the form builder service
|
|
417
|
-
updateTitle(value) {
|
|
418
|
-
this.formBuilderService.updateTitle(value);
|
|
419
|
-
this.book.update(book => ({
|
|
420
|
-
...book,
|
|
421
|
-
records: [{ ...book.records[0], title: value }]
|
|
422
|
-
}));
|
|
423
|
-
}
|
|
424
|
-
validateInput(value, type) {
|
|
425
|
-
if (type === 'label' || type === 'placeholder') {
|
|
426
|
-
const regex = /^[a-zA-Z0-9\s]*$/;
|
|
427
|
-
if (!regex.test(value)) {
|
|
428
|
-
this.errorMessage.set('Only letters and numbers are allowed');
|
|
429
|
-
return false;
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
this.errorMessage.set('');
|
|
433
|
-
return true;
|
|
434
|
-
}
|
|
435
|
-
updateField(value) {
|
|
436
|
-
this.bookSubtext.update(subtext => ({
|
|
437
|
-
...subtext,
|
|
438
|
-
field: value.split(',').map(item => item.trim())
|
|
439
|
-
}));
|
|
440
|
-
}
|
|
441
|
-
onCheckboxChange(targetArrayPath, targetArrayKey, key, apiName, isChecked) {
|
|
442
|
-
const targetArray = this.getDataByPath(targetArrayPath);
|
|
443
|
-
const foundItem = targetArray.find(item => item[targetArrayKey] === this.selectColumn());
|
|
444
|
-
foundItem[key] = foundItem[key] ? foundItem[key] : [];
|
|
445
|
-
if (isChecked) {
|
|
446
|
-
if (!foundItem[key].includes(apiName)) {
|
|
447
|
-
foundItem[key].push(apiName);
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
else {
|
|
451
|
-
const index = foundItem[key].indexOf(apiName);
|
|
452
|
-
if (index > -1) {
|
|
453
|
-
foundItem[key].splice(index, 1);
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
this.updateElement(this.selectedElement());
|
|
457
|
-
}
|
|
458
|
-
updateProperty(key, value) {
|
|
459
|
-
if (this.selectedElementIndex() >= 0) {
|
|
460
|
-
if (key === 'questionText' || key === 'question') {
|
|
461
|
-
if (!this.validateInput(value, key)) {
|
|
462
|
-
return;
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
if (key === 'questionNumber') {
|
|
466
|
-
//AP-10MAR25 Convert the value to an integer
|
|
467
|
-
const newOrder = parseInt(value, 10);
|
|
468
|
-
if (isNaN(newOrder))
|
|
469
|
-
return;
|
|
470
|
-
//AP-10MAR25 Update the element's questionNumber in the form builder service
|
|
471
|
-
this.formBuilderService.updateElement(this.selectedElementIndex(), { questionNumber: newOrder });
|
|
472
|
-
//AP-10MAR25 Sort elements based on the updated questionNumber
|
|
473
|
-
this.formBuilderService.sortElementsByOrder();
|
|
474
|
-
}
|
|
475
|
-
if (key === 'font' || key === 'fontWeight') {
|
|
476
|
-
this.selectedElement.update(el => ({ ...el, [key]: value }));
|
|
477
|
-
}
|
|
478
|
-
const update = { [key]: value };
|
|
479
|
-
this.formBuilderService.updateElement(this.selectedElementIndex(), update);
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
onRadioChange(targetArrayPath, targetArrayKey, key, value) {
|
|
483
|
-
if (this.selectedElement()?.type === 'Table') {
|
|
484
|
-
let targetArray = this.getDataByPath(targetArrayPath);
|
|
485
|
-
if (typeof targetArray === 'string') {
|
|
486
|
-
try {
|
|
487
|
-
targetArray = JSON.parse(targetArray || '[]');
|
|
488
|
-
}
|
|
489
|
-
catch (e) {
|
|
490
|
-
// console.error('Error parsing targetArray:', e);
|
|
491
|
-
targetArray = [];
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
if (!Array.isArray(targetArray))
|
|
495
|
-
return;
|
|
496
|
-
let foundItem = targetArray.find(item => item[targetArrayKey] === this.selectColumn());
|
|
497
|
-
if (!foundItem) {
|
|
498
|
-
foundItem = { [targetArrayKey]: this.selectColumn() };
|
|
499
|
-
targetArray.push(foundItem);
|
|
500
|
-
}
|
|
501
|
-
const keys = key.split('.');
|
|
502
|
-
let obj = foundItem;
|
|
503
|
-
for (let i = 0; i < keys.length - 1; i++) {
|
|
504
|
-
const k = keys[i];
|
|
505
|
-
if (!obj[k])
|
|
506
|
-
obj[k] = {};
|
|
507
|
-
obj = obj[k];
|
|
508
|
-
}
|
|
509
|
-
obj[keys[keys.length - 1]] = value;
|
|
510
|
-
this.selectedElement.update(el => ({
|
|
511
|
-
...el,
|
|
512
|
-
fieldsMeta: targetArray
|
|
513
|
-
}));
|
|
514
|
-
this.updateElement(this.selectedElement());
|
|
515
|
-
}
|
|
516
|
-
else {
|
|
517
|
-
this.setValueByPath(key, value);
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
onRequiredChange(value) {
|
|
521
|
-
if (this.selectedElement()) {
|
|
522
|
-
let label = this.selectedElement().label ? this.selectedElement().label.replace(/\s*\*+$/, '') : 'Label';
|
|
523
|
-
if (value) {
|
|
524
|
-
label = `${label} *`;
|
|
525
|
-
}
|
|
526
|
-
this.updateProperty('label', label);
|
|
527
|
-
this.updateProperty('isOptional', value);
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
toggleSubQuestion(prop) {
|
|
531
|
-
this.isExpanded = !this.isExpanded;
|
|
532
|
-
}
|
|
533
|
-
toggleStyleSection() {
|
|
534
|
-
this.isStyleExpanded.set(!this.isStyleExpanded());
|
|
535
|
-
}
|
|
536
|
-
getProperties() {
|
|
537
|
-
const element = this.selectedElement();
|
|
538
|
-
const selectedColumn = this.selectColumn();
|
|
539
|
-
// Check if we can use cached result
|
|
540
|
-
if (this._cachedProperties &&
|
|
541
|
-
this._lastSelectedElement === element &&
|
|
542
|
-
this._lastSelectedColumn === selectedColumn) {
|
|
543
|
-
return this._cachedProperties;
|
|
544
|
-
}
|
|
545
|
-
if (!element) {
|
|
546
|
-
this._cachedProperties = null;
|
|
547
|
-
this._lastSelectedElement = null;
|
|
548
|
-
this._lastSelectedColumn = null;
|
|
549
|
-
return null;
|
|
550
|
-
}
|
|
551
|
-
let result = null;
|
|
552
|
-
if (element.type === 'Header') {
|
|
553
|
-
result = this.elementProperties()['Header'];
|
|
554
|
-
}
|
|
555
|
-
else if (element.type === 'Table' && selectedColumn !== null) {
|
|
556
|
-
let fieldsMeta = element.fieldsMeta;
|
|
557
|
-
try {
|
|
558
|
-
fieldsMeta = Array.isArray(fieldsMeta)
|
|
559
|
-
? fieldsMeta
|
|
560
|
-
: JSON.parse(fieldsMeta || '[]');
|
|
561
|
-
}
|
|
562
|
-
catch (e) {
|
|
563
|
-
// console.error('Error parsing fieldsMeta in getProperties:', e);
|
|
564
|
-
fieldsMeta = [];
|
|
565
|
-
}
|
|
566
|
-
const column = fieldsMeta.find((c) => c.uniqueIdentifier === selectedColumn);
|
|
567
|
-
if (column) {
|
|
568
|
-
const markIsTableColumn = (items = []) => items.map(item => {
|
|
569
|
-
const newItem = { ...item, isTableColumn: true };
|
|
570
|
-
if (Array.isArray(newItem.subQuestion)) {
|
|
571
|
-
newItem.subQuestion = newItem.subQuestion.map(sub => ({
|
|
572
|
-
...sub,
|
|
573
|
-
isTableColumn: true
|
|
574
|
-
}));
|
|
575
|
-
}
|
|
576
|
-
return newItem;
|
|
577
|
-
});
|
|
578
|
-
result = {
|
|
579
|
-
elementProps: [
|
|
580
|
-
...(this.elementProperties()['TableColumn'].elementProps || []),
|
|
581
|
-
...markIsTableColumn(this.elementProperties()[this.elementType.includes(column.fldType) ? column.fldType : 'Text']?.elementProps)
|
|
582
|
-
],
|
|
583
|
-
fieldProps: [
|
|
584
|
-
...(this.elementProperties()['TableColumn'].fieldProps || []),
|
|
585
|
-
...markIsTableColumn(this.elementProperties()[this.elementType.includes(column.fldType) ? column.fldType : 'Text']?.fieldProps)
|
|
586
|
-
],
|
|
587
|
-
appearance: [
|
|
588
|
-
...(this.elementProperties()['TableColumn'].appearance || []),
|
|
589
|
-
...markIsTableColumn(this.elementProperties()[this.elementType.includes(column.fldType) ? column.fldType : 'Text']?.appearance)
|
|
590
|
-
]
|
|
591
|
-
};
|
|
592
|
-
}
|
|
593
|
-
else {
|
|
594
|
-
result = this.elementProperties()['TableColumn'];
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
else {
|
|
598
|
-
result = this.elementProperties()[element.type];
|
|
599
|
-
}
|
|
600
|
-
// Cache the result
|
|
601
|
-
this._cachedProperties = result;
|
|
602
|
-
this._lastSelectedElement = element;
|
|
603
|
-
this._lastSelectedColumn = selectedColumn;
|
|
604
|
-
return result;
|
|
605
|
-
}
|
|
606
|
-
// Add method to clear cache when needed
|
|
607
|
-
clearPropertiesCache() {
|
|
608
|
-
this._cachedProperties = null;
|
|
609
|
-
this._lastSelectedElement = null;
|
|
610
|
-
this._lastSelectedColumn = null;
|
|
611
|
-
}
|
|
612
|
-
// AP-28MAR25 Add an option with a unique UUID
|
|
613
|
-
addOption(options) {
|
|
614
|
-
const unique_id = uuidv4();
|
|
615
|
-
options.push({ id: unique_id, value: '' });
|
|
616
|
-
}
|
|
617
|
-
// AP-28MAR25 Function to remove an option based on its unique UUID
|
|
618
|
-
removeOption(options, id) {
|
|
619
|
-
const index = options.findIndex(option => option.id === id);
|
|
620
|
-
if (index !== -1) {
|
|
621
|
-
options.splice(index, 1);
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
handleButtonClick() {
|
|
625
|
-
this.formButtonHandler.emit(this.formBuilderService.downloadElement());
|
|
626
|
-
}
|
|
627
|
-
handleTemplateSave() {
|
|
628
|
-
this.templateSaveHandler.emit(this.templateService.download());
|
|
629
|
-
}
|
|
630
|
-
setActiveTab(tab) {
|
|
631
|
-
this.activeTab.set(tab);
|
|
632
|
-
}
|
|
633
|
-
onSave() { }
|
|
634
|
-
onCancel() { }
|
|
635
|
-
onAlignSelect(value) {
|
|
636
|
-
this.selectedElement.update(el => ({ ...el, textAlign: value }));
|
|
637
|
-
}
|
|
638
|
-
onStyleSelect(value) {
|
|
639
|
-
this.selectedElement.update(el => ({
|
|
640
|
-
...el,
|
|
641
|
-
styles: [value]
|
|
642
|
-
}));
|
|
643
|
-
}
|
|
644
|
-
isStyleActive(value) {
|
|
645
|
-
return this.selectedElement()?.styles?.includes(value) || false;
|
|
646
|
-
}
|
|
647
|
-
getValueByPath(path, obj = this.selectedElement(), defaultValue = '') {
|
|
648
|
-
if (!obj || !path)
|
|
649
|
-
return defaultValue;
|
|
650
|
-
return path.split('.').reduce((o, k) => o?.[k] ?? defaultValue, obj);
|
|
651
|
-
}
|
|
652
|
-
isAnotherIdSelected() {
|
|
653
|
-
return this.formBuilderService.getElements()
|
|
654
|
-
.some((el, i) => i !== this.selectedElementIndex() && el.primaryKey);
|
|
655
|
-
}
|
|
656
|
-
// Also update your onToggleChange method to clear cache
|
|
657
|
-
onToggleChange(path, event) {
|
|
658
|
-
// Clear cache when element changes
|
|
659
|
-
this.clearPropertiesCache();
|
|
660
|
-
const checked = event.target ? event.target.checked : event;
|
|
661
|
-
this.setValueByPath(path, checked);
|
|
662
|
-
if (this.selectedElement()?.type === 'Table') {
|
|
663
|
-
let fieldsMeta = this.getDataByPath('fieldsMeta');
|
|
664
|
-
if (typeof fieldsMeta === 'string') {
|
|
665
|
-
try {
|
|
666
|
-
fieldsMeta = JSON.parse(fieldsMeta || '[]');
|
|
667
|
-
}
|
|
668
|
-
catch (e) {
|
|
669
|
-
// console.error('Error parsing fieldsMeta:', e);
|
|
670
|
-
fieldsMeta = [];
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
this.selectedElement.update(el => ({
|
|
674
|
-
...el,
|
|
675
|
-
fieldsMeta: fieldsMeta
|
|
676
|
-
}));
|
|
677
|
-
this.updateElement(this.selectedElement());
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
// Update your setValueByPath method to clear cache
|
|
681
|
-
setValueByPath(path, value, isTranslate = false) {
|
|
682
|
-
// Clear cache when element changes
|
|
683
|
-
this.clearPropertiesCache();
|
|
684
|
-
if (this.selectedElementIndex() >= 0) {
|
|
685
|
-
if (path === 'questionText' || path === 'question') {
|
|
686
|
-
if (!this.validateInput(value, path)) {
|
|
687
|
-
return;
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
if (path === 'questionNumber') {
|
|
691
|
-
const newOrder = parseInt(value, 10);
|
|
692
|
-
if (isNaN(newOrder))
|
|
693
|
-
return;
|
|
694
|
-
this.formBuilderService.updateElement(this.selectedElementIndex(), { questionNumber: newOrder });
|
|
695
|
-
this.formBuilderService.sortElementsByOrder();
|
|
696
|
-
}
|
|
697
|
-
if (path === 'font' || path === 'fontWeight') {
|
|
698
|
-
this.selectedElement.update(el => ({ ...el, [path]: value }));
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
const element = this.selectedElement();
|
|
702
|
-
if (element) {
|
|
703
|
-
let subText = element.subText;
|
|
704
|
-
if (typeof subText === 'string' && subText.trim() !== '') {
|
|
705
|
-
try {
|
|
706
|
-
subText = JSON.parse(subText);
|
|
707
|
-
}
|
|
708
|
-
catch (e) {
|
|
709
|
-
// console.error('Error parsing subText:', e);
|
|
710
|
-
subText = {};
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
else if (typeof subText !== 'object' || subText === null) {
|
|
714
|
-
subText = {};
|
|
715
|
-
}
|
|
716
|
-
const arrayFields = ['field', 'queryParameter', 'sourceQuestionId', 'queryField', 'queryValue'];
|
|
717
|
-
if (subText) {
|
|
718
|
-
arrayFields.forEach(key => {
|
|
719
|
-
if (Array.isArray(subText[key])) {
|
|
720
|
-
subText[key] = subText[key].join(', ');
|
|
721
|
-
}
|
|
722
|
-
});
|
|
723
|
-
}
|
|
724
|
-
if (element.type === 'Table') {
|
|
725
|
-
element.fieldsMeta.forEach(field => {
|
|
726
|
-
if (field?.question?.subText) {
|
|
727
|
-
arrayFields.forEach(key => {
|
|
728
|
-
if (Array.isArray(field.question.subText[key])) {
|
|
729
|
-
field.question.subText[key] = field.question.subText[key].join(', ');
|
|
730
|
-
}
|
|
731
|
-
});
|
|
732
|
-
}
|
|
733
|
-
});
|
|
734
|
-
}
|
|
735
|
-
if (isTranslate) {
|
|
736
|
-
//SKS28JUL25 Refresh the book signal from service
|
|
737
|
-
const updatedBook = this.formBuilderService.getBook();
|
|
738
|
-
this.book.set(updatedBook);
|
|
739
|
-
// Work with a mutable copy
|
|
740
|
-
const currentBook = this.book();
|
|
741
|
-
const translationMap = currentBook.translationMap || {};
|
|
742
|
-
const currentLang = this.translationService.getFormBuilderLanguage();
|
|
743
|
-
//SKS28JUL25 Ensure nested structure exists
|
|
744
|
-
if (!translationMap[currentLang])
|
|
745
|
-
translationMap[currentLang] = {};
|
|
746
|
-
if (!translationMap[currentLang][element.id])
|
|
747
|
-
translationMap[currentLang][element.id] = {};
|
|
748
|
-
// Set the translated value
|
|
749
|
-
translationMap[currentLang][element.id][path] = value;
|
|
750
|
-
// Update book and re-set the signal
|
|
751
|
-
currentBook.translationMap = translationMap;
|
|
752
|
-
if (currentLang === 'en') {
|
|
753
|
-
this.translationService.updateTranslations(translationMap);
|
|
754
|
-
}
|
|
755
|
-
this.book.set(currentBook); // Trigger reactive update
|
|
756
|
-
//SKS28JUL25 Update in service if needed
|
|
757
|
-
this.formBuilderService.updateBook(currentBook);
|
|
758
|
-
}
|
|
759
|
-
this.selectedElement.update(el => ({ ...el, subText }));
|
|
760
|
-
}
|
|
761
|
-
const keys = path.split('.');
|
|
762
|
-
this.selectedElement.update(el => {
|
|
763
|
-
let obj = { ...el };
|
|
764
|
-
let current = obj;
|
|
765
|
-
keys.forEach((key, index) => {
|
|
766
|
-
if (index === keys.length - 1) {
|
|
767
|
-
current[key] = value;
|
|
768
|
-
}
|
|
769
|
-
else {
|
|
770
|
-
if (!current[key]) {
|
|
771
|
-
current[key] = isNaN(Number(keys[index + 1])) ? {} : [];
|
|
772
|
-
}
|
|
773
|
-
current = current[key];
|
|
774
|
-
}
|
|
775
|
-
});
|
|
776
|
-
return obj;
|
|
777
|
-
});
|
|
778
|
-
this.formBuilderService.elementUpdate(this.selectedElementIndex(), this.selectedElement());
|
|
779
|
-
}
|
|
780
|
-
optionTranslationUpdate(option, event) {
|
|
781
|
-
//SKS28JUL25 Refresh the book signal from service
|
|
782
|
-
const updatedBook = this.formBuilderService.getBook();
|
|
783
|
-
this.book.set(updatedBook);
|
|
784
|
-
// Work with a mutable copy
|
|
785
|
-
const currentBook = this.book();
|
|
786
|
-
const translationMap = currentBook.translationMap || {};
|
|
787
|
-
const currentLang = this.translationService.getFormBuilderLanguage();
|
|
788
|
-
//SKS28JUL25 Ensure nested structure exists
|
|
789
|
-
if (!translationMap[currentLang])
|
|
790
|
-
translationMap[currentLang] = {};
|
|
791
|
-
if (!translationMap[currentLang][option.id])
|
|
792
|
-
translationMap[currentLang][option.id] = {};
|
|
793
|
-
// Set the translated value
|
|
794
|
-
translationMap[currentLang][option.id]['label'] = event;
|
|
795
|
-
// Update book and re-set the signal
|
|
796
|
-
currentBook.translationMap = translationMap;
|
|
797
|
-
if (currentLang === 'en') {
|
|
798
|
-
this.translationService.updateTranslations(translationMap);
|
|
799
|
-
}
|
|
800
|
-
this.book.set(currentBook); // Trigger reactive update
|
|
801
|
-
//SKS28JUL25 Update in service if needed
|
|
802
|
-
this.formBuilderService.updateBook(currentBook);
|
|
803
|
-
}
|
|
804
|
-
getStyleKeys() {
|
|
805
|
-
const style = this.selectedElement()?.style;
|
|
806
|
-
return style && typeof style === 'object' ? Object.keys(style) : [];
|
|
807
|
-
}
|
|
808
|
-
updateElement(element) {
|
|
809
|
-
this.formBuilderService.elementUpdate(this.selectedElementIndex(), element);
|
|
810
|
-
if (element?.type === 'Table' && this.selectColumn()) {
|
|
811
|
-
this.formBuilderService.setSelectedTableElement(this.selectedElementIndex(), { uniqueIdentifier: this.selectColumn() || null });
|
|
812
|
-
this.selectedElement.set({ ...element }); // Ensure reactive update
|
|
813
|
-
}
|
|
814
|
-
}
|
|
815
|
-
getValueByArrayPath(targetArrayPath, targetArrayKey, selectColumn, keyPath, isTableColumn = false) {
|
|
816
|
-
if (isTableColumn) {
|
|
817
|
-
targetArrayPath = 'fieldsMeta';
|
|
818
|
-
targetArrayKey = 'uniqueIdentifier';
|
|
819
|
-
keyPath = 'question.' + keyPath;
|
|
820
|
-
}
|
|
821
|
-
let targetArray = this.getDataByPath(targetArrayPath);
|
|
822
|
-
if (typeof targetArray === 'string') {
|
|
823
|
-
try {
|
|
824
|
-
targetArray = JSON.parse(targetArray || '[]');
|
|
825
|
-
}
|
|
826
|
-
catch (e) {
|
|
827
|
-
// console.error('Error parsing targetArray:', e);
|
|
828
|
-
return '';
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
if (!Array.isArray(targetArray))
|
|
832
|
-
return '';
|
|
833
|
-
const foundItem = targetArray.find(item => item[targetArrayKey] === selectColumn);
|
|
834
|
-
return foundItem ? keyPath.split('.').reduce((obj, key) => obj?.[key], foundItem) : '';
|
|
835
|
-
}
|
|
836
|
-
updateValueByArrayPath(targetArrayPath, targetArrayKey, selectColumn, keyPath, event, isTableColumn = false, isTranslate = false) {
|
|
837
|
-
// Clear cache when element changes
|
|
838
|
-
this.clearPropertiesCache();
|
|
839
|
-
if (isTableColumn) {
|
|
840
|
-
targetArrayPath = 'fieldsMeta';
|
|
841
|
-
targetArrayKey = 'uniqueIdentifier';
|
|
842
|
-
keyPath = 'question.' + keyPath;
|
|
843
|
-
}
|
|
844
|
-
let targetArray = this.getDataByPath(targetArrayPath);
|
|
845
|
-
if (typeof targetArray === 'string') {
|
|
846
|
-
try {
|
|
847
|
-
targetArray = JSON.parse(targetArray || '[]');
|
|
848
|
-
}
|
|
849
|
-
catch (e) {
|
|
850
|
-
// console.error('Error parsing targetArray:', e);
|
|
851
|
-
targetArray = [];
|
|
852
|
-
}
|
|
853
|
-
}
|
|
854
|
-
if (!Array.isArray(targetArray)) {
|
|
855
|
-
targetArray = [];
|
|
856
|
-
this.selectedElement.update(el => ({
|
|
857
|
-
...el,
|
|
858
|
-
[targetArrayPath]: targetArray
|
|
859
|
-
}));
|
|
860
|
-
}
|
|
861
|
-
let foundItem = targetArray.find(item => item[targetArrayKey] === selectColumn);
|
|
862
|
-
if (!foundItem) {
|
|
863
|
-
foundItem = { [targetArrayKey]: selectColumn };
|
|
864
|
-
targetArray.push(foundItem);
|
|
865
|
-
}
|
|
866
|
-
const keys = keyPath.split('.');
|
|
867
|
-
let obj = foundItem;
|
|
868
|
-
for (let i = 0; i < keys.length - 1; i++) {
|
|
869
|
-
const key = keys[i];
|
|
870
|
-
if (!obj[key])
|
|
871
|
-
obj[key] = {};
|
|
872
|
-
obj = obj[key];
|
|
873
|
-
}
|
|
874
|
-
const lastKey = keys[keys.length - 1];
|
|
875
|
-
const inputElement = event.target ? event.target : event;
|
|
876
|
-
obj[lastKey] = inputElement?.type === 'checkbox' ? inputElement.checked : inputElement.value ? inputElement.value : inputElement;
|
|
877
|
-
if (isTranslate) {
|
|
878
|
-
// Refresh the book
|
|
879
|
-
this.book.set(this.formBuilderService.getBook());
|
|
880
|
-
//SKS28JUL25 Work with a mutable copy of the signal value
|
|
881
|
-
const currentBook = this.book();
|
|
882
|
-
const translationMap = currentBook.translationMap || {};
|
|
883
|
-
const currentLang = this.translationService.getFormBuilderLanguage();
|
|
884
|
-
// Initialize nested structure safely
|
|
885
|
-
if (!translationMap[currentLang])
|
|
886
|
-
translationMap[currentLang] = {};
|
|
887
|
-
if (!translationMap[currentLang][obj.uniqueIdentifier])
|
|
888
|
-
translationMap[currentLang][obj.uniqueIdentifier] = {};
|
|
889
|
-
// Set the translated input
|
|
890
|
-
translationMap[currentLang][obj.uniqueIdentifier][lastKey] = inputElement;
|
|
891
|
-
//SKS28JUL25 Update the book object and re-set the signal
|
|
892
|
-
currentBook.translationMap = translationMap;
|
|
893
|
-
if (currentLang === 'en') {
|
|
894
|
-
this.translationService.updateTranslations(translationMap);
|
|
895
|
-
}
|
|
896
|
-
this.book.set(currentBook);
|
|
897
|
-
// Optionally inform the service
|
|
898
|
-
this.formBuilderService.updateBook(currentBook);
|
|
899
|
-
}
|
|
900
|
-
if (keyPath === 'summaryColumn') {
|
|
901
|
-
if (obj['summaryRow'] === true) {
|
|
902
|
-
obj['summaryRow'] = false;
|
|
903
|
-
}
|
|
904
|
-
if (inputElement.checked === true) {
|
|
905
|
-
obj['fldType'] = 'calculation';
|
|
906
|
-
}
|
|
907
|
-
else {
|
|
908
|
-
obj['fldType'] = 'Text';
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
if (keyPath === 'summaryRow') {
|
|
912
|
-
if (obj['summaryColumn'] === true) {
|
|
913
|
-
obj['summaryColumn'] = false;
|
|
914
|
-
}
|
|
915
|
-
if (inputElement.checked === true) {
|
|
916
|
-
obj['fldType'] = 'calculation';
|
|
917
|
-
}
|
|
918
|
-
else {
|
|
919
|
-
obj['fldType'] = 'Text';
|
|
920
|
-
}
|
|
921
|
-
}
|
|
922
|
-
this.selectedElement.update(el => ({
|
|
923
|
-
...el,
|
|
924
|
-
[targetArrayPath]: targetArray
|
|
925
|
-
}));
|
|
926
|
-
this.updateElement(this.selectedElement());
|
|
927
|
-
}
|
|
928
|
-
getDataByPath(path) {
|
|
929
|
-
return path.split('.').reduce((obj, key) => obj?.[key], this.selectedElement());
|
|
930
|
-
}
|
|
931
|
-
flipHorizontal() {
|
|
932
|
-
this.transform.update(t => ({ ...t, flipH: !t.flipH }));
|
|
933
|
-
}
|
|
934
|
-
flipVertical() {
|
|
935
|
-
this.transform.update(t => ({ ...t, flipV: !t.flipV }));
|
|
936
|
-
}
|
|
937
|
-
resetImage() {
|
|
938
|
-
this.canvasRotation.set(0);
|
|
939
|
-
this.cropper.set(undefined);
|
|
940
|
-
this.transform.set({
|
|
941
|
-
translateUnit: 'px',
|
|
942
|
-
scale: 1,
|
|
943
|
-
rotate: 0,
|
|
944
|
-
flipH: false,
|
|
945
|
-
flipV: false,
|
|
946
|
-
translateH: 0,
|
|
947
|
-
translateV: 0
|
|
948
|
-
});
|
|
949
|
-
}
|
|
950
|
-
zoomOut() {
|
|
951
|
-
this.transform.update(t => ({ ...t, scale: t.scale - 0.1 }));
|
|
952
|
-
}
|
|
953
|
-
zoomIn() {
|
|
954
|
-
this.transform.update(t => ({ ...t, scale: t.scale + 0.1 }));
|
|
955
|
-
}
|
|
956
|
-
rotateLeft() {
|
|
957
|
-
this.loading.set(true);
|
|
958
|
-
setTimeout(() => {
|
|
959
|
-
this.canvasRotation.update(c => c - 1);
|
|
960
|
-
this.flipAfterRotate();
|
|
961
|
-
});
|
|
962
|
-
}
|
|
963
|
-
rotateRight() {
|
|
964
|
-
this.loading.set(true);
|
|
965
|
-
setTimeout(() => {
|
|
966
|
-
this.canvasRotation.update(c => c + 1);
|
|
967
|
-
this.flipAfterRotate();
|
|
968
|
-
});
|
|
969
|
-
}
|
|
970
|
-
moveLeft() {
|
|
971
|
-
this.transform.update(t => ({ ...t, translateH: t.translateH - 1 }));
|
|
972
|
-
}
|
|
973
|
-
moveRight() {
|
|
974
|
-
this.transform.update(t => ({ ...t, translateH: t.translateH + 1 }));
|
|
975
|
-
}
|
|
976
|
-
moveDown() {
|
|
977
|
-
this.transform.update(t => ({ ...t, translateV: t.translateV + 1 }));
|
|
978
|
-
}
|
|
979
|
-
moveUp() {
|
|
980
|
-
this.transform.update(t => ({ ...t, translateV: t.translateV - 1 }));
|
|
981
|
-
}
|
|
982
|
-
flipAfterRotate() {
|
|
983
|
-
this.transform.update(t => ({
|
|
984
|
-
...t,
|
|
985
|
-
flipH: t.flipV,
|
|
986
|
-
flipV: t.flipH,
|
|
987
|
-
translateH: 0,
|
|
988
|
-
translateV: 0
|
|
989
|
-
}));
|
|
990
|
-
}
|
|
991
|
-
async imageCropped(event) {
|
|
992
|
-
try {
|
|
993
|
-
const base64 = await this.convertBlobToBase64(event.objectUrl);
|
|
994
|
-
this.selectedElement.update(el => ({ ...el, imageData: base64 }));
|
|
995
|
-
await this.formBuilderService.elementUpdate(this.selectedElementIndex(), this.selectedElement());
|
|
996
|
-
}
|
|
997
|
-
catch (error) {
|
|
998
|
-
// console.error("Error in imageCropped:", error);
|
|
999
|
-
}
|
|
1000
|
-
}
|
|
1001
|
-
cropperReady(sourceImageDimensions) {
|
|
1002
|
-
this.loading.set(false);
|
|
1003
|
-
}
|
|
1004
|
-
convertBlobToBase64(objectUrl) {
|
|
1005
|
-
return fetch(objectUrl)
|
|
1006
|
-
.then(response => response.blob())
|
|
1007
|
-
.then(blob => {
|
|
1008
|
-
return new Promise((resolve, reject) => {
|
|
1009
|
-
const reader = new FileReader();
|
|
1010
|
-
reader.readAsDataURL(blob);
|
|
1011
|
-
reader.onloadend = () => resolve(reader.result);
|
|
1012
|
-
reader.onerror = error => reject(error);
|
|
1013
|
-
});
|
|
1014
|
-
});
|
|
1015
|
-
}
|
|
1016
|
-
childEventCapture(event) {
|
|
1017
|
-
this.selectedElement.update(el => ({
|
|
1018
|
-
...el,
|
|
1019
|
-
qbReference: event.valueObj?.name,
|
|
1020
|
-
qbReferenceQuestions: event.valueObj?.jsonBody
|
|
1021
|
-
}));
|
|
1022
|
-
this.formBuilderService.elementUpdate(this.selectedElementIndex(), this.selectedElement());
|
|
1023
|
-
}
|
|
1024
|
-
linkToggleDropdown(event) {
|
|
1025
|
-
event.stopPropagation();
|
|
1026
|
-
this.isLinkDropdownOpen.update(open => !open);
|
|
1027
|
-
}
|
|
1028
|
-
onClickOutside(event) {
|
|
1029
|
-
if (this.dropdown && !this.dropdown.nativeElement.contains(event.target)) {
|
|
1030
|
-
this.isLinkDropdownOpen.set(false);
|
|
1031
|
-
}
|
|
1032
|
-
}
|
|
1033
|
-
onDragStart(event, id) {
|
|
1034
|
-
this.draggedId = id;
|
|
1035
|
-
event.dataTransfer.effectAllowed = "move";
|
|
1036
|
-
}
|
|
1037
|
-
// AP-28MAR25 Prevent default behavior to allow drop
|
|
1038
|
-
onDragOver(event) {
|
|
1039
|
-
event.preventDefault();
|
|
1040
|
-
}
|
|
1041
|
-
// AP-28MAR25 Swap the dragged item with the dropped position
|
|
1042
|
-
onDrop(event, key) {
|
|
1043
|
-
event.preventDefault();
|
|
1044
|
-
const targetId = event.target.closest(".option-items")?.getAttribute("data-id");
|
|
1045
|
-
if (this.draggedId && targetId && this.draggedId !== targetId) {
|
|
1046
|
-
this.selectedElement.update(el => {
|
|
1047
|
-
const options = [...el[key]];
|
|
1048
|
-
const draggedIndex = options.findIndex(option => option.id === this.draggedId);
|
|
1049
|
-
const targetIndex = options.findIndex(option => option.id === targetId);
|
|
1050
|
-
if (draggedIndex !== -1 && targetIndex !== -1) {
|
|
1051
|
-
[options[draggedIndex], options[targetIndex]] = [options[targetIndex], options[draggedIndex]];
|
|
1052
|
-
}
|
|
1053
|
-
return { ...el, [key]: options };
|
|
1054
|
-
});
|
|
1055
|
-
}
|
|
1056
|
-
this.draggedId = null;
|
|
1057
|
-
}
|
|
1058
|
-
duplicateField(element) {
|
|
1059
|
-
const elements = this.formBuilderService.getElements();
|
|
1060
|
-
const copy = JSON.parse(JSON.stringify(element));
|
|
1061
|
-
//AP-18APR25 Generate a new ID using the service's method
|
|
1062
|
-
copy.id = this.formBuilderService.addElementWithId();
|
|
1063
|
-
//copy.uuid = copy.id;
|
|
1064
|
-
// AP-18APR25 Set the questionNumber to the next available number
|
|
1065
|
-
copy.questionNumber = elements.length + 1;
|
|
1066
|
-
this.formBuilderService.addElement(copy);
|
|
1067
|
-
}
|
|
1068
|
-
draggedId = null;
|
|
1069
|
-
updateBookSubtext(key, value) {
|
|
1070
|
-
this.bookSubtext.update((s) => ({
|
|
1071
|
-
...s,
|
|
1072
|
-
[key]: value,
|
|
1073
|
-
}));
|
|
1074
|
-
}
|
|
1075
|
-
trackByProp(index, item) {
|
|
1076
|
-
return item?.key ?? index;
|
|
1077
|
-
}
|
|
1078
|
-
getOptimizedSubPropValue(subProp) {
|
|
1079
|
-
const element = this.selectedElement();
|
|
1080
|
-
if (this.selectedElement()?.type === 'Table' && (subProp.targetArray || subProp.isTableColumn)) {
|
|
1081
|
-
return this.getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, this.selectColumn(), subProp.key, subProp.isTableColumn);
|
|
1082
|
-
}
|
|
1083
|
-
return this.getValueByPath(subProp.key, element);
|
|
1084
|
-
}
|
|
1085
|
-
// SKS31JUL25 default language text copy to clipboard
|
|
1086
|
-
copyToClipboard(text) {
|
|
1087
|
-
if (text && navigator.clipboard) {
|
|
1088
|
-
navigator.clipboard.writeText(text).then(() => {
|
|
1089
|
-
this.copied = true;
|
|
1090
|
-
this.cdr.detectChanges(); // manually trigger update
|
|
1091
|
-
setTimeout(() => {
|
|
1092
|
-
this.copied = false;
|
|
1093
|
-
this.cdr.detectChanges(); // update again when hiding
|
|
1094
|
-
}, 1500);
|
|
1095
|
-
}).catch(err => {
|
|
1096
|
-
console.error('Failed to copy:', err);
|
|
1097
|
-
});
|
|
1098
|
-
}
|
|
1099
|
-
}
|
|
1100
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PropertiesComponent, deps: [{ token: i1.FormBuilderService }, { token: i2.TemplateService }, { token: i3.TranslationService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
1101
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: PropertiesComponent, isStandalone: true, selector: "app-properties", inputs: { templateSelected: "templateSelected", selectedElementType: "selectedElementType" }, outputs: { formButtonHandler: "formButtonHandler", templateSaveHandler: "templateSaveHandler" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, viewQueries: [{ propertyName: "dropdown", first: true, predicate: ["dropdown"], descendants: true }], ngImport: i0, template: "<!-- AP 22JAN25 - Field and Element Properties -->\n\n<div class=\"container\">\n <div class=\"tabs\">\n <div class=\"tab\" [ngClass]=\"{'active': activeTab() === 'attributes'}\" (click)=\"setActiveTab('attributes')\">{{ 'ATTRIBUTES' | nxtCustomTranslate : 'Attributes' }}</div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab() === 'property'}\" (click)=\"setActiveTab('property')\">{{ 'PROPERTY' | nxtCustomTranslate : 'Property' }}</div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab() === 'appearance'}\" (click)=\"setActiveTab('appearance')\">{{ 'APPEARANCE' | nxtCustomTranslate : 'Appearance' }}</div>\n </div>\n <div class=\"tab-content\" *ngIf=\"activeTab() === 'attributes'\">\n @defer (when getProperties()) {\n <div>\n @defer (when selectedElement()?.type === 'Image') {\n <image-cropper\n *ngIf=\"selectedElement().imageData\"\n [imageBase64]=\"selectedElement().orgImageData\"\n [disabled]=\"false\"\n [alignImage]=\"alignImage\"\n [roundCropper]=\"roundCropper\"\n [backgroundColor]=\"'white'\"\n imageAltText=\"Alternative image text\"\n [allowMoveImage]=\"false\"\n [hideResizeSquares]=\"false\"\n [canvasRotation]=\"canvasRotation()\"\n [aspectRatio]=\"aspectRatio\"\n [containWithinAspectRatio]=\"false\"\n [maintainAspectRatio]=\"false\"\n [cropperStaticWidth]=\"cropperStaticWidth\"\n [cropperStaticHeight]=\"cropperStaticHeight\"\n [cropperMinWidth]=\"cropperMinWidth\"\n [cropperMinHeight]=\"cropperMinHeight\"\n [cropperMaxWidth]=\"cropperMaxWidth\"\n [cropperMaxHeight]=\"cropperMaxHeight\"\n [resetCropOnAspectRatioChange]=\"true\"\n [(cropper)]=\"cropper\"\n [(transform)]=\"transform\"\n [onlyScaleDown]=\"true\"\n output=\"blob\"\n format=\"png\"\n (imageCropped)=\"imageCropped($event)\"\n (cropperReady)=\"cropperReady($event)\"\n ></image-cropper>\n <div *ngIf=\"selectedElement().imageData\" style=\"display: flex; gap: 2px;\">\n <div class=\"cursor-pointer logo-icon\" (click)=\"rotateLeft()\" title=\"{{ 'ROTATE_LEFT' | nxtCustomTranslate : 'Rotate Left' }}\">\u27F2</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"rotateRight()\" title=\"{{ 'ROTATE_RIGHT' | nxtCustomTranslate : 'Rotate Right' }}\">\u27F3</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"zoomOut()\" title=\"{{ 'ZOOM_OUT' | nxtCustomTranslate : 'Zoom Out' }}\">-</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"zoomIn()\" title=\"{{ 'ZOOM_IN' | nxtCustomTranslate : 'Zoom In' }}\">+</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveLeft()\" title=\"{{ 'MOVE_LEFT' | nxtCustomTranslate : 'Move Left' }}\">\u2190</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveRight()\" title=\"{{ 'MOVE_RIGHT' | nxtCustomTranslate : 'Move Right' }}\">\u2192</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveUp()\" title=\"{{ 'MOVE_UP' | nxtCustomTranslate : 'Move Up' }}\">\u2191</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveDown()\" title=\"{{ 'MOVE_DOWN' | nxtCustomTranslate : 'Move Down' }}\">\u2193</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipHorizontal()\" [ngClass]=\"{'enabled': transform().flipH}\" title=\"{{ 'FLIP_HORIZONTALLY' | nxtCustomTranslate : 'Flip Horizontally' }}\">\u2194</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipVertical()\" [ngClass]=\"{'enabled': transform().flipV}\" title=\"{{ 'FLIP_VERTICALLY' | nxtCustomTranslate : 'Flip Vertically' }}\">\u2195</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"resetImage()\" title=\"{{ 'RESET' | nxtCustomTranslate : 'Reset' }}\">\u00D7</div>\n </div>\n }\n <div *ngIf=\"selectedElement()?.type === 'Book'\">\n <label class=\"text-sm\">{{ 'SEARCH_BOOK' | nxtCustomTranslate : 'Search Book' }}</label>\n <div style=\"display: flex; gap: 2px; align-items: center; justify-content: center;\">\n <nxt-search-box\n [question]=\"selectedElement()\"\n [apiMeta]=\"bookSubtext()\"\n [placeHolderText]=\"'SEARCH' | nxtCustomTranslate : 'Search...'\"\n (searchValueChange)=\"childEventCapture($event.value)\"\n ></nxt-search-box>\n <div class=\"link-icon\">\n <svg (click)=\"linkToggleDropdown($event)\" fill=\"#000000\" version=\"1.1\" id=\"Capa_1\"\n xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"24px\" height=\"24px\"\n viewBox=\"0 0 450 450\" xml:space=\"preserve\">\n <g>\n <g>\n <g>\n <path d=\"M318.15,230.195l77.934-77.937c31.894-31.892,31.894-83.782-0.004-115.674l-12.66-12.66\n c-31.893-31.896-83.78-31.896-115.674-0.004l-77.937,77.934c-17.588,17.588-25.457,41.264-23.646,64.311\n c-23.045-1.813-46.722,6.056-64.308,23.647L23.92,267.748c-31.894,31.889-31.894,83.779,0,115.674l12.664,12.662\n c31.893,31.893,83.783,31.893,115.674,0l77.935-77.936c17.592-17.59,25.459-41.266,23.647-64.309\n C276.884,255.654,300.56,247.783,318.15,230.195z M202.653,290.605l-77.936,77.938c-16.705,16.703-43.889,16.703-60.59,0\n l-12.666-12.666c-16.705-16.701-16.703-43.885,0-60.594l77.936-77.932c14.14-14.141,35.779-16.306,52.226-6.516l-32.302,32.307\n c-7.606,7.604-7.606,19.938,0,27.541c7.605,7.607,19.937,7.607,27.541,0l32.306-32.303\n C218.959,254.828,216.795,276.469,202.653,290.605z M238.382,209.169l32.299-32.306c7.608-7.602,7.608-19.935,0-27.538\n c-7.604-7.61-19.936-7.61-27.541-0.004l-32.303,32.303c-9.791-16.446-7.627-38.087,6.514-52.226l77.935-77.935\n c16.707-16.707,43.89-16.707,60.594,0l12.664,12.664c16.705,16.705,16.705,43.886,0,60.591l-77.936,77.937\n C276.468,216.797,254.828,218.959,238.382,209.169z\" />\n <path d=\"M343.466,261.465c-45.287,0-82,36.713-82,82s36.713,82,82,82c45.286,0,82-36.713,82-82S388.753,261.465,343.466,261.465z\n M372.505,333.564l-56.046,56.104c-0.239,0.238-0.536,0.41-0.862,0.496l-22.315,5.85c-0.649,0.168-1.347-0.02-1.822-0.494\n c-0.477-0.479-0.666-1.172-0.496-1.824l5.826-22.318c0.084-0.326,0.256-0.627,0.494-0.863l56.047-56.104\n c0.742-0.742,1.945-0.744,2.688-0.002l4.548,4.541c0.739,0.74,0.741,1.943,0,2.688l-37.433,37.471l4.709,4.703l37.435-37.471\n c0.739-0.742,1.94-0.742,2.682-0.002l4.55,4.541C373.25,331.617,373.25,332.822,372.505,333.564z M395.472,310.574l-17,17.018\n c-0.739,0.744-1.942,0.744-2.685,0.002l-16.489-16.475c-0.744-0.74-0.744-1.943-0.002-2.688l17-17.02\n c0.741-0.74,1.944-0.74,2.688-0.002l16.487,16.477C396.216,308.629,396.216,309.832,395.472,310.574z\" />\n </g>\n </g>\n </g>\n </svg>\n <div class=\"link-dropdown-menu\" *ngIf=\"isLinkDropdownOpen()\" #dropdown>\n <label>{{ 'END_POINT' | nxtCustomTranslate : 'Endpoint' }}:</label>\n <input type=\"text\" [ngModel]=\"bookSubtext().endpoint\" (ngModelChange)=\"updateBookSubtext('endpoint', $event)\" />\n <label>{{ 'VARIABLE' | nxtCustomTranslate : 'Variable' }}:</label>\n <input type=\"text\" [ngModel]=\"bookSubtext().variable\" (ngModelChange)=\"updateBookSubtext('variable', $event)\" />\n <label>{{ 'FIELD' | nxtCustomTranslate : 'Field' }}:</label>\n <input type=\"text\" [ngModel]=\"fieldAsString()\" (ngModelChange)=\"updateField($event)\" />\n <label>{{ 'DEFAULT_FIELD' | nxtCustomTranslate : 'Default Field' }}:</label>\n <input type=\"text\" [ngModel]=\"bookSubtext().defaultField\" (ngModelChange)=\"updateBookSubtext('defaultField', $event)\" />\n </div>\n </div>\n </div>\n </div>\n <ng-container *ngFor=\"let prop of getProperties()?.elementProps; trackBy: trackByProp\">\n <div class=\"form-group\">\n <label *ngIf=\"prop.type !== 'checkbox' && prop.type !== 'subQuestion'\" class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <ng-container *ngIf=\"prop.isTranslate && formBuilderLanguageCode && formBuilderLanguageCode !== 'en'\">\n <ng-container *ngIf=\"((selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? selectColumn() : selectedElement().id) + '.' + prop.key | nxtCustomTranslate : '' : 'formBuilder') as translated\">\n <div *ngIf=\"translated?.trim()\" class=\"translation-fallback\">\n <div style=\"font-size: 10px;\">Default (English)</div>\n <div class=\"readonly-box\" style=\"display: flex; align-items: center; gap: 8px; position: relative;\">\n \n <span>{{ translated }}</span>\n \n <!-- Copy Icon -->\n <svg *ngIf=\"!copied\"\n (click)=\"copyToClipboard(translated)\" width=\"16px\" height=\"16px\" viewBox=\"0 0 24.00 24.00\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" transform=\"rotate(0)\"><g id=\"SVGRepo_bgCarrier\" stroke-width=\"0\"></g><g id=\"SVGRepo_tracerCarrier\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"#CCCCCC\" stroke-width=\"0.048\"></g><g id=\"SVGRepo_iconCarrier\"> <g id=\"style=stroke\"> <g id=\"copy\"> <path id=\"rec (Stroke)\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M6.25 5.25C6.25 2.50265 8.43733 0.25 11.1667 0.25H17.8333C20.5627 0.25 22.75 2.50265 22.75 5.25V13.75C22.75 16.4974 20.5627 18.75 17.8333 18.75C17.4191 18.75 17.0833 18.4142 17.0833 18C17.0833 17.5858 17.4191 17.25 17.8333 17.25C19.7064 17.25 21.25 15.6971 21.25 13.75V5.25C21.25 3.30293 19.7064 1.75 17.8333 1.75H11.1667C9.29363 1.75 7.75 3.30293 7.75 5.25C7.75 5.66421 7.41421 6 7 6C6.58579 6 6.25 5.66421 6.25 5.25Z\" fill=\"#000000\"></path> <path id=\"rec (Stroke)_2\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M1.25 10.25C1.25 7.50265 3.43733 5.25 6.16667 5.25H12.8333C15.5627 5.25 17.75 7.50265 17.75 10.25V18.75C17.75 21.4974 15.5627 23.75 12.8333 23.75H6.16667C3.43733 23.75 1.25 21.4974 1.25 18.75V10.25ZM6.16667 6.75C4.29363 6.75 2.75 8.30293 2.75 10.25V18.75C2.75 20.6971 4.29363 22.25 6.16667 22.25H12.8333C14.7064 22.25 16.25 20.6971 16.25 18.75V10.25C16.25 8.30293 14.7064 6.75 12.8333 6.75H6.16667Z\" fill=\"#000000\"></path> </g> </g> </g></svg>\n \n <!-- Copied Message -->\n <span *ngIf=\"copied\" class=\"copied-msg\">Copied!</span>\n </div>\n </div>\n </ng-container>\n </ng-container>\n <div *ngIf=\"prop.key === 'helpText' && selectedElement()?.helpText\">{{ selectedElement()?.helpText }}</div>\n <input *ngIf=\"prop.type === 'text'\"\n type=\"text\"\n [placeholder]=\"prop.placeholder\"\n [ngModel]=\"headerSelect() ? book().records[0].title : (selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"headerSelect() ? updateTitle($event) : (selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n [class.read-only]=\"selectedElement()?.readOnly\"\n [readonly]=\"selectedElement()?.readOnly\"\n />\n <input *ngIf=\"prop.type === 'number'\"\n type=\"number\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n />\n <select *ngIf=\"prop.type === 'select'\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n >\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\">{{ option.labelPath | nxtCustomTranslate : option.label }}</option>\n </select>\n <div *ngIf=\"prop.type === 'checkbox'\">\n <input\n type=\"checkbox\"\n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange(prop.key, $event)\"\n />\n <span class=\"toggle-label\" style=\"padding-left: 10px;\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</span>\n </div>\n <div *ngIf=\"prop.type === 'subQuestion'\">\n <div style=\"display: flex; flex-direction: row; gap: 10px; align-items: center;\">\n <div>{{ prop.labelPath | nxtCustomTranslate : prop.label }}</div>\n <input\n type=\"checkbox\"\n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange(prop.key, $event)\"\n />\n </div>\n <div\n *ngIf=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\"\n >\n <div *ngFor=\"let subProp of prop.subQuestion\" style=\"background-color: #e7f2ff; padding: 8px; border-radius: 4px;\">\n <div class=\"form-group\">\n <label>{{ subProp.labelPath | nxtCustomTranslate : subProp.label }}</label>\n <div *ngIf=\"subProp.type === 'array'\">\n <div *ngFor=\"let column of filteredColumns()\">\n <label>\n <input\n type=\"checkbox\"\n [checked]=\"subProp.operands ? subProp.operands.includes(column.apiName) : false\"\n (change)=\"onCheckboxChange(subProp.targetArray, subProp.targetArrayKey, subProp.key, column.apiName, $event.target.checked)\"\n >\n {{ column.apiName }}\n </label>\n </div>\n </div>\n <div *ngIf=\"subProp.type === 'radio'\">\n <div *ngFor=\"let column of filteredColumns()\">\n <label>\n <input\n type=\"radio\"\n [name]=\"subProp.key\"\n [value]=\"column.apiName\"\n [checked]=\"getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key) === column.apiName\"\n (change)=\"onRadioChange(subProp.targetArray, subProp.targetArrayKey, subProp.key, column.apiName)\"\n >\n {{ column.apiName }}\n </label>\n </div>\n </div>\n <input\n *ngIf=\"subProp.type === 'text'\"\n type=\"text\"\n [placeholder]=\"subProp.placeholder\"\n [ngModel]=\"selectedElement()?.type === 'Table' ? (subProp.targetArray ? getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key) : (selectedElement() | getValueByPath : subProp.key)) : (selectedElement() | getValueByPath : subProp.key)\"\n (ngModelChange)=\"selectedElement()?.type === 'Table' ? (subProp.targetArray ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, $event,false, prop.isTranslate) : setValueByPath(subProp.key, $event)) : setValueByPath(subProp.key, $event, prop.isTranslate)\"\n />\n <input\n *ngIf=\"subProp.type === 'boolean'\"\n type=\"checkbox\"\n [checked]=\"selectedElement() | getValueByPath : subProp.key\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\"\n />\n <select\n *ngIf=\"subProp.type === 'select'\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (subProp.targetArray || subProp.isTableColumn) ? (getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, subProp.isTableColumn)) : (selectedElement() | getValueByPath : subProp.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (subProp.targetArray || subProp.isTableColumn) ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, $event, subProp.isTableColumn, prop.isTranslate) : setValueByPath(subProp.key, $event, prop.isTranslate))\"\n >\n <option *ngFor=\"let option of subProp.options\" [value]=\"option.value\">{{ option.labelPath | nxtCustomTranslate : option.label }}</option>\n </select>\n <input\n *ngIf=\"subProp.type === 'checkbox'\"\n type=\"checkbox\"\n [checked]=\"selectedElement() | getValueByPath : subProp.key\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\"\n />\n </div>\n </div>\n </div>\n </div>\n <div *ngIf=\"prop.type === 'align'\">\n <button *ngFor=\"let option of prop.options\" (click)=\"onAlignSelect(option.value)\" [ngClass]=\"{'active': selectedElement()?.textAlign === option.value}\" [title]=\"option.value\">\n <img [src]=\"'../assets/icons/' + option.icon + '.svg'\" [alt]=\"option.value\" class=\"icon-size\" />\n </button>\n </div>\n <div *ngIf=\"prop.type === 'style'\">\n <button *ngFor=\"let option of prop.options\" (click)=\"onStyleSelect(option.value)\" [ngClass]=\"{'active': isStyleActive(option.value)}\" [title]=\"option.value\">\n <img [src]=\"'../assets/icons/' + option.icon + '.svg'\" [alt]=\"option.value\" class=\"icon-size\" />\n </button>\n </div>\n <div *ngIf=\"prop.type === 'color'\">\n <input\n type=\"color\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n />\n </div>\n <div *ngIf=\"prop.key === 'title'\" style=\"margin-top: 15px; border: 1px solid #ddd; padding: 20px; border-radius: 12px; background-color: #f9f9f9;\">\n <div class=\"form-header\">\n <label class=\"form-label\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <button (click)=\"addNewButton()\" class=\"add-button\">+ {{ 'ADD_BUTTON' | nxtCustomTranslate : 'Add Button' }}</button>\n </div>\n <div *ngFor=\"let btn of book()?.questionbook?.action || []; let i = index\" class=\"button-config-card\">\n <div class=\"form-group\">\n <label>{{ 'BUTTON_NAME' | nxtCustomTranslate : 'Button Name' }}</label>\n <input type=\"text\" [ngModel]=\"btn.name\" (ngModelChange)=\"onButtonPropertyChange(i, 'name', $event,true)\" placeholder=\"Enter button name\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'EVENT_NAME' | nxtCustomTranslate : 'Event Name' }}</label>\n <input type=\"text\" [ngModel]=\"btn.eventtoemit\" (ngModelChange)=\"onButtonPropertyChange(i, 'eventtoemit', $event)\" placeholder=\"Event to emit\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'ALT' | nxtCustomTranslate : 'Alt' }}</label>\n <input type=\"text\" [ngModel]=\"btn.alt\" (ngModelChange)=\"onButtonPropertyChange(i, 'alt', $event)\" placeholder=\"Button alt text\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'END_POINT' | nxtCustomTranslate : 'Endpoint' }}</label>\n <input type=\"text\" [ngModel]=\"btn.endpoint\" (ngModelChange)=\"onButtonPropertyChange(i, 'endpoint', $event)\" placeholder=\"API endpoint\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'METHOD' | nxtCustomTranslate : 'Method' }}</label>\n <select [ngModel]=\"btn.method\" (ngModelChange)=\"onButtonPropertyChange(i, 'method', $event)\">\n <option value=\"GET\">GET</option>\n <option value=\"POST\">POST</option>\n <option value=\"PUT\">PUT</option>\n <option value=\"DELETE\">DELETE</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>{{ 'BACKGROUND_COLOR' | nxtCustomTranslate : 'Background Color' }}</label>\n <input type=\"color\" [ngModel]=\"btn.bgColor\" (ngModelChange)=\"onButtonPropertyChange(i, 'bgColor', $event)\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'BORDER_RADIUS' | nxtCustomTranslate : 'Border Radius' }}</label>\n <input type=\"range\" min=\"0\" max=\"50\" [ngModel]=\"btn.borderRadius\" (ngModelChange)=\"onButtonPropertyChange(i, 'borderRadius', $event)\">\n <span>{{ btn.borderRadius }}px</span>\n </div>\n <div class=\"form-group\">\n <label>{{ 'BUTTON_WIDTH_PX' | nxtCustomTranslate : 'Button Width (px)' }}</label>\n <input type=\"number\" [ngModel]=\"btn.width\" (ngModelChange)=\"onButtonPropertyChange(i, 'width', $event)\" min=\"50\" placeholder=\"Enter width in px\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'TEXT_COLOR' | nxtCustomTranslate : 'Text Color' }}</label>\n <input type=\"color\" [ngModel]=\"btn.textColor\" (ngModelChange)=\"onButtonPropertyChange(i, 'textColor', $event)\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'POSITION_PERCENT' | nxtCustomTranslate : 'Position (%)' }}</label>\n <input type=\"range\" min=\"0\" max=\"100\" [ngModel]=\"btn.positionPercent\" (ngModelChange)=\"onButtonPropertyChange(i, 'positionPercent', $event)\">\n <span>{{ btn.positionPercent }}%</span>\n </div>\n <button (click)=\"removeButton(btn)\" class=\"remove-button\">\u00D7 {{ 'REMOVE' | nxtCustomTranslate : 'Remove' }}</button>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n }\n </div>\n\n <div class=\"tab-content\" *ngIf=\"activeTab() === 'property'\">\n @defer (when getProperties()) {\n <div>\n <label>Label Id</label>\n <div style=\"font-size: 13px; padding: 11px; border-radius: 5px; background-color: #f8f8f8; border: 1px solid #ddd;\">\n {{ headerSelect() ? bookId() : selectedElement()?.id }}\n </div>\n <ng-container *ngFor=\"let prop of getProperties()?.fieldProps; trackBy: trackByProp\">\n <div class=\"form-group\">\n <label *ngIf=\"prop.type !== 'subQuestion'\" class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <div *ngIf=\"prop.type === 'toggleGroup'\" class=\"toggle-group\">\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" \n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isOptional', true) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : 'isOptional')\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isOptional', $event, true, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange('isOptional', $event)\"\n />\n {{ 'REQUIRED' | nxtCustomTranslate : 'Required' }}\n </label>\n </div>\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" \n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isReadOnly', true) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : 'isReadOnly')\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isReadOnly', $event, true, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange('isReadOnly', $event)\"\n />\n {{ 'READ_ONLY' | nxtCustomTranslate : 'Read Only' }}\n </label>\n </div>\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" \n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isHidden', true) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : 'isHidden')\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isHidden', $event, true, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange('isHidden', $event)\"\n />\n {{ 'IS_HIDE' | nxtCustomTranslate : 'Is Hide' }}\n </label>\n </div>\n </div>\n <div *ngIf=\" prop.type === 'checkbox' || prop.type === 'radio' || prop.key === 'options'\" class=\"options-container\">\n <div class=\"option-list\" (dragover)=\"onDragOver($event)\" (drop)=\"onDrop($event, prop.key)\">\n <div *ngFor=\"let option of selectedElement()?.type === 'Table' && selectColumn() ? getValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(), prop.key, true) : selectedElement()[prop.key] ; let i = index\" class=\"option-items\" [attr.data-id]=\"option.id\" draggable=\"true\" (dragstart)=\"onDragStart($event, option.id)\">\n <input type=\"text\" style=\"padding: 4px; border-radius: 2px;\" [ngModel]=\"option.value\" (ngModelChange)=\"option.value = $event\" placeholder=\"Value\" class=\"options\" />\n <input type=\"text\" style=\"padding: 4px; border-radius: 2px;\" [ngModel]=\"option.label\" (ngModelChange)=\"option.label = $event; optionTranslationUpdate(option,$event)\" placeholder=\"Label\" class=\"options\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeOption(selectedElement()[prop.key], option.id)\">\n <span class=\"drag-handle\">\u2630</span>\n </div>\n </div>\n <button (click)=\"addOption(selectedElement()?.type === 'Table' && selectColumn() ? getValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(), prop.key, true) : selectedElement()[prop.key])\">\n <div class=\"add-varient\">\n <span class=\"text-lg\">+</span>\n <span>{{ 'ADD' | nxtCustomTranslate : 'Add' }}</span>\n </div>\n </button>\n </div>\n <input *ngIf=\"prop.type === 'text'\"\n type=\"text\"\n [placeholder]=\"prop.placeholder\"\n [ngModel]=\"headerSelect() ? book().records[0].title : (selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"headerSelect() ? updateTitle($event) : (selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n [class.read-only]=\"selectedElement()?.readOnly\"\n [readonly]=\"selectedElement()?.readOnly\"\n />\n <div *ngIf=\"prop.type === 'subQuestion'\">\n <div class=\"style-toggle-header\" (click)=\"toggleSubQuestion(prop)\">\n <div class=\"head-elements\">Sub Text</div>\n <img [src]=\"isExpanded ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\"\n alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n <div *ngIf=\"isExpanded\" style=\"border: 1px solid #ddd; border-radius: 4px;\">\n <div *ngFor=\"let subProp of prop.subQuestion; trackBy: trackByProp\" style=\"background-color: #e7f2ff; padding: 8px; border-radius: 4px;\">\n <div class=\"form-group\">\n <label>{{ subProp.labelPath | nxtCustomTranslate : subProp.label }}</label>\n <input *ngIf=\"subProp.type === 'text'\"\n type=\"text\"\n [placeholder]=\"subProp.placeholder\"\n [value]=\"getOptimizedSubPropValue(subProp)\"\n (input)=\"(selectedElement()?.type === 'Table' && (subProp.targetArray || subProp.isTableColumn)) ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, $event.target.value, subProp.isTableColumn, prop.isTranslate) : setValueByPath(subProp.key, $event.target.value, prop.isTranslate)\"\n [class.read-only]=\"selectedElement()?.readOnly\"\n [readonly]=\"selectedElement()?.readOnly\" />\n \n <!-- AP-02APR25 Render input field only if subProp.type is 'array' -->\n <input *ngIf=\"subProp.type === 'array'\" type=\"text\" [placeholder]=\"subProp.placeholder\"\n [value]=\"getValueByPath(subProp.key)\" (input)=\"setValueByPath(subProp.key, $event.target.value, prop.isTranslate)\" />\n\n <input *ngIf=\"subProp.type === 'boolean'\" type=\"checkbox\" [checked]=\"getValueByPath(subProp.key)\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\" />\n </div>\n </div>\n </div>\n </div>\n <div *ngIf=\"prop.type === 'checkbox'\">\n <span class=\"toggle-label\" style=\"padding-right: 10px;\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</span>\n <input\n type=\"checkbox\"\n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange(prop.key, $event)\"\n />\n </div>\n </div>\n </ng-container>\n <div class=\"style-toggle-header\" (click)=\"toggleStyleSection()\">\n <div class=\"head-elements\">{{ 'STYLE' | nxtCustomTranslate : 'Style' }}</div>\n <img [src]=\"isStyleExpanded() ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\" alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n <div *ngIf=\"isStyleExpanded()\" style=\"border: 1px solid #ddd; padding: 8px; border-radius: 4px;\">\n <div class=\"form-group\">\n <div *ngFor=\"let key of getStyleKeys()\">\n <label>{{ key }}</label>\n <input\n type=\"text\"\n [value]=\"selectedElement()?.type === 'Table' && selectColumn() ? getValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(),'style.' + key, true) : (selectedElement() | getValueByPath : 'style.' + key)\"\n (input)=\"(selectedElement()?.type === 'Table' && selectColumn() ) ? updateValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(), 'style.' + key, $event.target.value, true) : setValueByPath('style.' + key, $event.target.value)\"\n placeholder=\"Enter {{ key }}\"\n />\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n\n <div class=\"tab-content\" *ngIf=\"activeTab() === 'appearance'\">\n @defer (when getProperties()) {\n <div>\n <ng-container *ngFor=\"let prop of getProperties()?.appearance; trackBy: trackByProp\">\n <div class=\"form-group\">\n <label class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <select\n *ngIf=\"prop.type === 'select'\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n >\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\">{{ option.labelPath | nxtCustomTranslate : option.label }}</option>\n </select>\n <input\n *ngIf=\"prop.type === 'text'\"\n type=\"text\"\n [placeholder]=\"prop.placeholder\"\n [ngModel]=\"selectedElement() | getValueByPath : prop.key\"\n (ngModelChange)=\"setValueByPath(prop.key, $event, prop.isTranslate)\"\n />\n\n <div class=\"flex-container\">\n <div *ngIf=\"prop.type === 'color'\" class=\"color-selector\">\n <input\n type=\"color\"\n [ngModel]=\"selectedElement()?.fontColor\"\n (ngModelChange)=\"setValueByPath('fontColor', $event, prop.isTranslate)\"\n >\n </div>\n <div *ngIf=\"prop.type === 'color'\" class=\"hex-input-container\">\n <span>{{ 'HEX_CODE' | nxtCustomTranslate : 'HEX Code' }}</span>\n <input\n type=\"text\"\n [ngModel]=\"selectedElement() | getValueByPath : prop.key\"\n (ngModelChange)=\"setValueByPath(prop.key, $event, prop.isTranslate)\"\n />\n </div>\n </div>\n <div *ngIf=\"prop.type === 'button-toggle'\" class=\"button-toggle-wrapper\">\n <button\n type=\"button\"\n class=\"toggle-button\"\n (click)=\"duplicateField(selectedElement())\"\n >\n {{ 'ADD_DUPLICATE' | nxtCustomTranslate : 'Add Duplicate' }}\n </button>\n </div>\n </div>\n </ng-container>\n </div>\n }\n </div>\n\n <div class=\"button-container\" *ngIf=\"!templateSelected\">\n <button class=\"cancel-btn\" (click)=\"onCancel()\">{{ 'CANCEL' | nxtCustomTranslate : 'Cancel' }}</button>\n <button class=\"save-btn\" (click)=\"handleButtonClick()\">{{ 'SAVE' | nxtCustomTranslate : 'Save' }}</button>\n </div>\n\n <div class=\"button-container\" *ngIf=\"templateSelected\" style=\"margin-top: 20px;\">\n <button class=\"save-btn\" (click)=\"handleTemplateSave()\">{{ 'SAVE_TEMPLATE' | nxtCustomTranslate : 'Save Template' }}</button>\n </div>\n</div>", styles: ["*{margin:0;padding:0;box-sizing:border-box;font-family:Roboto,sans-serif}.properties{height:calc(100vh - 20px);overflow-y:auto}.container{width:100%;max-width:500px;margin:0 auto;background:#fff;box-shadow:0 2px 10px #0000001a;overflow:hidden;font-family:Arial,sans-serif}.design-header{display:flex;justify-content:center;align-items:center;padding:15px 20px;background:#fff;border-radius:8px;box-shadow:0 2px 10px #0000001a;margin-bottom:20px}.header-title{font-size:20px;font-weight:400;color:#222}.toggle-header,.style-toggle-header{display:flex;align-items:center;justify-content:space-between;cursor:pointer;padding:10px;background:#f8f8f8;border:1px solid #ddd;border-radius:6px;margin-bottom:6px}.tabs{display:flex;background:#f0f2f5;border-bottom:2px solid #0052cc}.tab{flex:1;padding:15px 10px;text-align:center;cursor:pointer}.tab.active{background:#0052cc;color:#fff;font-weight:700}.tab-content{padding:20px;max-height:80vh;overflow-y:auto;overflow-x:hidden}.form-group{margin-bottom:15px}label{display:block;font-size:14px;font-weight:500;color:#444;margin-bottom:8px}.required:before{content:\"*\";color:red;margin-right:3px}input[type=text],input[type=number],select,textarea{width:100%;padding:10px;font-size:14px;border:1px solid #ccc;border-radius:6px;outline:none;transition:all .3s;background:#f8f8f8}input:focus,select:focus,textarea:focus{border-color:#007bff;background:#fff;box-shadow:0 0 5px #007bff4d}textarea{min-height:55px;resize:vertical}button,.btn{padding:10px 15px;border:none;border-radius:6px;background:#007bff;color:#fff;font-size:15px;cursor:pointer;transition:all .3s}button:hover,.btn:hover{background:#0056b3;transform:translateY(-2px)}.add-button{padding:8px 14px;background:#0954c5;border-radius:8px}.remove-button{background:#e74c3c;padding:6px 12px;margin-top:10px}.remove-button:hover{background:#c0392b}.cancel-btn{background:#fff;color:#666;border:1px solid #ddd;margin-right:10px}.save-btn{background:#0052cc}.toggle-group{display:grid;grid-template-columns:1fr 1fr;gap:10px}.toggle-item{display:flex;align-items:center;gap:10px;padding:8px}.switch{position:relative;width:42px;height:22px}.switch input{opacity:0;width:0;height:0}.slider{position:absolute;cursor:pointer;inset:0;background:#ccc;transition:.4s;border-radius:24px}.slider:before{position:absolute;content:\"\";height:20px;width:20px;left:1px;bottom:1px;background:#fff;transition:.4s;border-radius:50%}input:checked+.slider{background:#2196f3}input:checked+.slider:before{transform:translate(18px)}.radio-item{display:flex;align-items:center;gap:20px}.radio-item input{accent-color:#007bff}.checkbox-row{display:flex;margin-bottom:10px}.checkbox-group{display:flex;align-items:center;margin-right:20px;min-width:120px}.checkbox-group input[type=checkbox]{margin-right:5px}.color-picker-row,.color-picker-container{display:flex;align-items:center}.color-picker-container{border:1px solid #ddd;border-radius:4px;margin-right:10px}.color-box,.color-selector input[type=color]{width:78px;height:40px;border:none;border-radius:4px;cursor:pointer}.hex-input-container{display:flex;gap:20px;align-items:center;font-size:12px;color:#b0b0b0}.hex-input-container span{font-size:14px;margin-top:10px}.hex-input,.hex-input-container input[type=text]{width:120px;padding:10px 12px;border:1px solid #d1d1d1;color:#28343e}.hex-label{color:#999;margin-right:5px}.select-container,.input-box-field{position:relative;width:100%}.dropdown-arrow,.input-box-field:after{position:absolute;right:10px;top:50%;transform:translateY(-50%);pointer-events:none;color:#666;font-size:12px}.input-box-field:after{content:\"\\25bc\";color:#1c1b1f;font-size:10px}.input-box-field select{background:#28343e;color:#fff;border:none;appearance:none;-webkit-appearance:none;-moz-appearance:none}.input-box-field select::-ms-expand{display:none}.all-properties details{background:#fff;border:1px solid #ddd;border-radius:8px;margin-bottom:12px;padding:12px;box-shadow:0 2px 8px #0000000d}.all-properties summary{font-size:15px;font-weight:400;cursor:pointer;padding:6px;transition:color .3s}.all-properties summary:hover{color:#007bff}.inner-content{padding:12px 0}.head-elements{font-size:14px;font-weight:500;color:#444}.options-container{display:flex;flex-direction:column;gap:12px}.field-size-controls,.flex-container{display:flex;align-items:center;gap:12px}.flex-container{margin-bottom:1rem}.size-input{width:110px;text-align:center}.input-container{display:flex;flex-direction:column;align-items:flex-start;gap:10px;width:100%}.subtext-textarea{width:100%;margin-left:auto}.arrow-icon{width:19px;height:23px;transition:transform .3s ease}.icon{display:inline-block;width:18px;height:18px;border-radius:50%;text-align:center;line-height:18px;color:#fff;font-size:12px;margin-left:5px}.edit-icon{background:#4caf50}.view-icon{background:#2196f3}.delete-icon{background:#f44336}.logo-icon{width:20px;height:20px;display:flex;justify-content:center;background:#d0d9ff;border-radius:4px}.link-icon{background:#e7f2ff;padding:5px;border-radius:5px;margin:5px;display:inline-block;cursor:pointer;position:relative;transition:all .3s}.link-icon:hover{background:#d0e5ff}.link-icon:active{background:#a8d0ff}.link-dropdown-menu{position:absolute;top:100%;right:0;background:#fff;border:1px solid #ccc;padding:10px;width:200px;box-shadow:0 4px 6px #0000001a}.link-dropdown-menu input{width:100%;margin-bottom:5px;padding:5px;border:1px solid #ccc;border-radius:3px}.option-items{display:flex;align-items:center;padding:5px;gap:5px;border:1px solid #ccc;margin-bottom:10px;cursor:grab;background:#fff}.option-items:active{opacity:.5}.drag-handle{cursor:grab}.button-toggle-wrapper{margin-top:8px}.toggle-button{padding:8px 16px;border:1px solid #cbd2d9;border-radius:6px;font-size:14px;cursor:pointer;transition:all .2s ease-in-out}.toggle-button.active:hover{background:#2c6dd5}.button-config-card{background:#fff;padding:15px;border-radius:12px;border:1px solid #ccc;margin-top:20px;box-shadow:0 2px 8px #0000000d}.design-footer{display:flex;justify-content:space-between;margin-top:20px}.button-container{display:flex;padding:15px;background:#f9f9f9;border-top:1px solid #eee}.button-container .cancel-btn,.button-container .save-btn{flex:1;padding:12px;font-weight:700}.divider{border-top:1px dashed #ddd;margin:20px 0}input{width:auto}@media screen and (max-width: 768px){.container{height:calc(100vh - 20px);min-height:calc(100vh - 20px)}.tabs{flex-direction:column}.tab{padding:1rem;font-size:.9rem}.form-group,.tab-content[aria-label=attributes] .form-group,.tab-content[aria-label=property] .form-group,.tab-content[aria-label=appearance] .form-group{flex-direction:column;grid-template-columns:1fr}.toggle-group{flex-direction:column;align-items:flex-start}}@media screen and (max-width: 480px){.container{padding:0 10px}.tabs{flex-direction:column}.tab{padding:1rem;border-bottom:1px solid #dee2e6}input[type=text],input[type=number],select,textarea{font-size:.9rem}}.translation-fallback label,.translation-input-group label{font-weight:500;font-size:13px;margin-bottom:4px;display:block;color:#666}.readonly-box{font-size:14px;padding:4px;border:1px solid #ddd;border-radius:5px;-webkit-user-select:text;user-select:text;cursor:text;color:#7a7a7a;margin-bottom:3px}.copied-msg{font-size:12px;color:green;opacity:0;animation:fadeInOut 1.5s ease}@keyframes fadeInOut{0%{opacity:0;transform:translateY(-2px)}20%{opacity:1;transform:translateY(0)}80%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-2px)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "pipe", type: NxtCustomTranslatePipe, name: "nxtCustomTranslate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [i4.NgClass, i4.NgForOf, i4.NgIf, i5.NgSelectOption, i5.ɵNgSelectMultipleOption, i5.DefaultValueAccessor, i5.NumberValueAccessor, i5.RangeValueAccessor, i5.SelectControlValueAccessor, i5.NgControlStatus, i5.MinValidator, i5.NgModel, import("../../../components/search-box/search-box.component").then(m => m.NxtSearchBox), GetValueByPathPipe, NxtCustomTranslatePipe], () => [i4.NgClass, i4.NgIf, import("../../../components/image-cropper/component/image-cropper.component").then(m => m.ImageCropperComponent), NxtCustomTranslatePipe], () => [i4.NgForOf, i4.NgIf, i5.DefaultValueAccessor, i5.NgControlStatus, i5.NgModel, GetValueByPathPipe, NxtCustomTranslatePipe], () => [i4.NgForOf, i4.NgIf, i5.NgSelectOption, i5.ɵNgSelectMultipleOption, i5.DefaultValueAccessor, i5.SelectControlValueAccessor, i5.NgControlStatus, i5.NgModel, GetValueByPathPipe, NxtCustomTranslatePipe]] });
|
|
1102
|
-
}
|
|
1103
|
-
i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "18.2.13", ngImport: i0, type: PropertiesComponent, resolveDeferredDeps: () => [import("../../../components/search-box/search-box.component").then(m => m.NxtSearchBox), import("../../../components/image-cropper/component/image-cropper.component").then(m => m.ImageCropperComponent)], resolveMetadata: (NxtSearchBox, ImageCropperComponent) => ({ decorators: [{
|
|
1104
|
-
type: Component,
|
|
1105
|
-
args: [{ selector: 'app-properties', standalone: true, imports: [CommonModule, FormsModule, ImageCropperComponent, NxtSearchBox, NgClass, NgFor, NgIf, GetValueByPathPipe, NxtCustomTranslatePipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- AP 22JAN25 - Field and Element Properties -->\n\n<div class=\"container\">\n <div class=\"tabs\">\n <div class=\"tab\" [ngClass]=\"{'active': activeTab() === 'attributes'}\" (click)=\"setActiveTab('attributes')\">{{ 'ATTRIBUTES' | nxtCustomTranslate : 'Attributes' }}</div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab() === 'property'}\" (click)=\"setActiveTab('property')\">{{ 'PROPERTY' | nxtCustomTranslate : 'Property' }}</div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab() === 'appearance'}\" (click)=\"setActiveTab('appearance')\">{{ 'APPEARANCE' | nxtCustomTranslate : 'Appearance' }}</div>\n </div>\n <div class=\"tab-content\" *ngIf=\"activeTab() === 'attributes'\">\n @defer (when getProperties()) {\n <div>\n @defer (when selectedElement()?.type === 'Image') {\n <image-cropper\n *ngIf=\"selectedElement().imageData\"\n [imageBase64]=\"selectedElement().orgImageData\"\n [disabled]=\"false\"\n [alignImage]=\"alignImage\"\n [roundCropper]=\"roundCropper\"\n [backgroundColor]=\"'white'\"\n imageAltText=\"Alternative image text\"\n [allowMoveImage]=\"false\"\n [hideResizeSquares]=\"false\"\n [canvasRotation]=\"canvasRotation()\"\n [aspectRatio]=\"aspectRatio\"\n [containWithinAspectRatio]=\"false\"\n [maintainAspectRatio]=\"false\"\n [cropperStaticWidth]=\"cropperStaticWidth\"\n [cropperStaticHeight]=\"cropperStaticHeight\"\n [cropperMinWidth]=\"cropperMinWidth\"\n [cropperMinHeight]=\"cropperMinHeight\"\n [cropperMaxWidth]=\"cropperMaxWidth\"\n [cropperMaxHeight]=\"cropperMaxHeight\"\n [resetCropOnAspectRatioChange]=\"true\"\n [(cropper)]=\"cropper\"\n [(transform)]=\"transform\"\n [onlyScaleDown]=\"true\"\n output=\"blob\"\n format=\"png\"\n (imageCropped)=\"imageCropped($event)\"\n (cropperReady)=\"cropperReady($event)\"\n ></image-cropper>\n <div *ngIf=\"selectedElement().imageData\" style=\"display: flex; gap: 2px;\">\n <div class=\"cursor-pointer logo-icon\" (click)=\"rotateLeft()\" title=\"{{ 'ROTATE_LEFT' | nxtCustomTranslate : 'Rotate Left' }}\">\u27F2</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"rotateRight()\" title=\"{{ 'ROTATE_RIGHT' | nxtCustomTranslate : 'Rotate Right' }}\">\u27F3</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"zoomOut()\" title=\"{{ 'ZOOM_OUT' | nxtCustomTranslate : 'Zoom Out' }}\">-</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"zoomIn()\" title=\"{{ 'ZOOM_IN' | nxtCustomTranslate : 'Zoom In' }}\">+</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveLeft()\" title=\"{{ 'MOVE_LEFT' | nxtCustomTranslate : 'Move Left' }}\">\u2190</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveRight()\" title=\"{{ 'MOVE_RIGHT' | nxtCustomTranslate : 'Move Right' }}\">\u2192</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveUp()\" title=\"{{ 'MOVE_UP' | nxtCustomTranslate : 'Move Up' }}\">\u2191</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveDown()\" title=\"{{ 'MOVE_DOWN' | nxtCustomTranslate : 'Move Down' }}\">\u2193</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipHorizontal()\" [ngClass]=\"{'enabled': transform().flipH}\" title=\"{{ 'FLIP_HORIZONTALLY' | nxtCustomTranslate : 'Flip Horizontally' }}\">\u2194</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipVertical()\" [ngClass]=\"{'enabled': transform().flipV}\" title=\"{{ 'FLIP_VERTICALLY' | nxtCustomTranslate : 'Flip Vertically' }}\">\u2195</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"resetImage()\" title=\"{{ 'RESET' | nxtCustomTranslate : 'Reset' }}\">\u00D7</div>\n </div>\n }\n <div *ngIf=\"selectedElement()?.type === 'Book'\">\n <label class=\"text-sm\">{{ 'SEARCH_BOOK' | nxtCustomTranslate : 'Search Book' }}</label>\n <div style=\"display: flex; gap: 2px; align-items: center; justify-content: center;\">\n <nxt-search-box\n [question]=\"selectedElement()\"\n [apiMeta]=\"bookSubtext()\"\n [placeHolderText]=\"'SEARCH' | nxtCustomTranslate : 'Search...'\"\n (searchValueChange)=\"childEventCapture($event.value)\"\n ></nxt-search-box>\n <div class=\"link-icon\">\n <svg (click)=\"linkToggleDropdown($event)\" fill=\"#000000\" version=\"1.1\" id=\"Capa_1\"\n xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"24px\" height=\"24px\"\n viewBox=\"0 0 450 450\" xml:space=\"preserve\">\n <g>\n <g>\n <g>\n <path d=\"M318.15,230.195l77.934-77.937c31.894-31.892,31.894-83.782-0.004-115.674l-12.66-12.66\n c-31.893-31.896-83.78-31.896-115.674-0.004l-77.937,77.934c-17.588,17.588-25.457,41.264-23.646,64.311\n c-23.045-1.813-46.722,6.056-64.308,23.647L23.92,267.748c-31.894,31.889-31.894,83.779,0,115.674l12.664,12.662\n c31.893,31.893,83.783,31.893,115.674,0l77.935-77.936c17.592-17.59,25.459-41.266,23.647-64.309\n C276.884,255.654,300.56,247.783,318.15,230.195z M202.653,290.605l-77.936,77.938c-16.705,16.703-43.889,16.703-60.59,0\n l-12.666-12.666c-16.705-16.701-16.703-43.885,0-60.594l77.936-77.932c14.14-14.141,35.779-16.306,52.226-6.516l-32.302,32.307\n c-7.606,7.604-7.606,19.938,0,27.541c7.605,7.607,19.937,7.607,27.541,0l32.306-32.303\n C218.959,254.828,216.795,276.469,202.653,290.605z M238.382,209.169l32.299-32.306c7.608-7.602,7.608-19.935,0-27.538\n c-7.604-7.61-19.936-7.61-27.541-0.004l-32.303,32.303c-9.791-16.446-7.627-38.087,6.514-52.226l77.935-77.935\n c16.707-16.707,43.89-16.707,60.594,0l12.664,12.664c16.705,16.705,16.705,43.886,0,60.591l-77.936,77.937\n C276.468,216.797,254.828,218.959,238.382,209.169z\" />\n <path d=\"M343.466,261.465c-45.287,0-82,36.713-82,82s36.713,82,82,82c45.286,0,82-36.713,82-82S388.753,261.465,343.466,261.465z\n M372.505,333.564l-56.046,56.104c-0.239,0.238-0.536,0.41-0.862,0.496l-22.315,5.85c-0.649,0.168-1.347-0.02-1.822-0.494\n c-0.477-0.479-0.666-1.172-0.496-1.824l5.826-22.318c0.084-0.326,0.256-0.627,0.494-0.863l56.047-56.104\n c0.742-0.742,1.945-0.744,2.688-0.002l4.548,4.541c0.739,0.74,0.741,1.943,0,2.688l-37.433,37.471l4.709,4.703l37.435-37.471\n c0.739-0.742,1.94-0.742,2.682-0.002l4.55,4.541C373.25,331.617,373.25,332.822,372.505,333.564z M395.472,310.574l-17,17.018\n c-0.739,0.744-1.942,0.744-2.685,0.002l-16.489-16.475c-0.744-0.74-0.744-1.943-0.002-2.688l17-17.02\n c0.741-0.74,1.944-0.74,2.688-0.002l16.487,16.477C396.216,308.629,396.216,309.832,395.472,310.574z\" />\n </g>\n </g>\n </g>\n </svg>\n <div class=\"link-dropdown-menu\" *ngIf=\"isLinkDropdownOpen()\" #dropdown>\n <label>{{ 'END_POINT' | nxtCustomTranslate : 'Endpoint' }}:</label>\n <input type=\"text\" [ngModel]=\"bookSubtext().endpoint\" (ngModelChange)=\"updateBookSubtext('endpoint', $event)\" />\n <label>{{ 'VARIABLE' | nxtCustomTranslate : 'Variable' }}:</label>\n <input type=\"text\" [ngModel]=\"bookSubtext().variable\" (ngModelChange)=\"updateBookSubtext('variable', $event)\" />\n <label>{{ 'FIELD' | nxtCustomTranslate : 'Field' }}:</label>\n <input type=\"text\" [ngModel]=\"fieldAsString()\" (ngModelChange)=\"updateField($event)\" />\n <label>{{ 'DEFAULT_FIELD' | nxtCustomTranslate : 'Default Field' }}:</label>\n <input type=\"text\" [ngModel]=\"bookSubtext().defaultField\" (ngModelChange)=\"updateBookSubtext('defaultField', $event)\" />\n </div>\n </div>\n </div>\n </div>\n <ng-container *ngFor=\"let prop of getProperties()?.elementProps; trackBy: trackByProp\">\n <div class=\"form-group\">\n <label *ngIf=\"prop.type !== 'checkbox' && prop.type !== 'subQuestion'\" class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <ng-container *ngIf=\"prop.isTranslate && formBuilderLanguageCode && formBuilderLanguageCode !== 'en'\">\n <ng-container *ngIf=\"((selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? selectColumn() : selectedElement().id) + '.' + prop.key | nxtCustomTranslate : '' : 'formBuilder') as translated\">\n <div *ngIf=\"translated?.trim()\" class=\"translation-fallback\">\n <div style=\"font-size: 10px;\">Default (English)</div>\n <div class=\"readonly-box\" style=\"display: flex; align-items: center; gap: 8px; position: relative;\">\n \n <span>{{ translated }}</span>\n \n <!-- Copy Icon -->\n <svg *ngIf=\"!copied\"\n (click)=\"copyToClipboard(translated)\" width=\"16px\" height=\"16px\" viewBox=\"0 0 24.00 24.00\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" transform=\"rotate(0)\"><g id=\"SVGRepo_bgCarrier\" stroke-width=\"0\"></g><g id=\"SVGRepo_tracerCarrier\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"#CCCCCC\" stroke-width=\"0.048\"></g><g id=\"SVGRepo_iconCarrier\"> <g id=\"style=stroke\"> <g id=\"copy\"> <path id=\"rec (Stroke)\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M6.25 5.25C6.25 2.50265 8.43733 0.25 11.1667 0.25H17.8333C20.5627 0.25 22.75 2.50265 22.75 5.25V13.75C22.75 16.4974 20.5627 18.75 17.8333 18.75C17.4191 18.75 17.0833 18.4142 17.0833 18C17.0833 17.5858 17.4191 17.25 17.8333 17.25C19.7064 17.25 21.25 15.6971 21.25 13.75V5.25C21.25 3.30293 19.7064 1.75 17.8333 1.75H11.1667C9.29363 1.75 7.75 3.30293 7.75 5.25C7.75 5.66421 7.41421 6 7 6C6.58579 6 6.25 5.66421 6.25 5.25Z\" fill=\"#000000\"></path> <path id=\"rec (Stroke)_2\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M1.25 10.25C1.25 7.50265 3.43733 5.25 6.16667 5.25H12.8333C15.5627 5.25 17.75 7.50265 17.75 10.25V18.75C17.75 21.4974 15.5627 23.75 12.8333 23.75H6.16667C3.43733 23.75 1.25 21.4974 1.25 18.75V10.25ZM6.16667 6.75C4.29363 6.75 2.75 8.30293 2.75 10.25V18.75C2.75 20.6971 4.29363 22.25 6.16667 22.25H12.8333C14.7064 22.25 16.25 20.6971 16.25 18.75V10.25C16.25 8.30293 14.7064 6.75 12.8333 6.75H6.16667Z\" fill=\"#000000\"></path> </g> </g> </g></svg>\n \n <!-- Copied Message -->\n <span *ngIf=\"copied\" class=\"copied-msg\">Copied!</span>\n </div>\n </div>\n </ng-container>\n </ng-container>\n <div *ngIf=\"prop.key === 'helpText' && selectedElement()?.helpText\">{{ selectedElement()?.helpText }}</div>\n <input *ngIf=\"prop.type === 'text'\"\n type=\"text\"\n [placeholder]=\"prop.placeholder\"\n [ngModel]=\"headerSelect() ? book().records[0].title : (selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"headerSelect() ? updateTitle($event) : (selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n [class.read-only]=\"selectedElement()?.readOnly\"\n [readonly]=\"selectedElement()?.readOnly\"\n />\n <input *ngIf=\"prop.type === 'number'\"\n type=\"number\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n />\n <select *ngIf=\"prop.type === 'select'\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n >\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\">{{ option.labelPath | nxtCustomTranslate : option.label }}</option>\n </select>\n <div *ngIf=\"prop.type === 'checkbox'\">\n <input\n type=\"checkbox\"\n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange(prop.key, $event)\"\n />\n <span class=\"toggle-label\" style=\"padding-left: 10px;\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</span>\n </div>\n <div *ngIf=\"prop.type === 'subQuestion'\">\n <div style=\"display: flex; flex-direction: row; gap: 10px; align-items: center;\">\n <div>{{ prop.labelPath | nxtCustomTranslate : prop.label }}</div>\n <input\n type=\"checkbox\"\n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange(prop.key, $event)\"\n />\n </div>\n <div\n *ngIf=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\"\n >\n <div *ngFor=\"let subProp of prop.subQuestion\" style=\"background-color: #e7f2ff; padding: 8px; border-radius: 4px;\">\n <div class=\"form-group\">\n <label>{{ subProp.labelPath | nxtCustomTranslate : subProp.label }}</label>\n <div *ngIf=\"subProp.type === 'array'\">\n <div *ngFor=\"let column of filteredColumns()\">\n <label>\n <input\n type=\"checkbox\"\n [checked]=\"subProp.operands ? subProp.operands.includes(column.apiName) : false\"\n (change)=\"onCheckboxChange(subProp.targetArray, subProp.targetArrayKey, subProp.key, column.apiName, $event.target.checked)\"\n >\n {{ column.apiName }}\n </label>\n </div>\n </div>\n <div *ngIf=\"subProp.type === 'radio'\">\n <div *ngFor=\"let column of filteredColumns()\">\n <label>\n <input\n type=\"radio\"\n [name]=\"subProp.key\"\n [value]=\"column.apiName\"\n [checked]=\"getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key) === column.apiName\"\n (change)=\"onRadioChange(subProp.targetArray, subProp.targetArrayKey, subProp.key, column.apiName)\"\n >\n {{ column.apiName }}\n </label>\n </div>\n </div>\n <input\n *ngIf=\"subProp.type === 'text'\"\n type=\"text\"\n [placeholder]=\"subProp.placeholder\"\n [ngModel]=\"selectedElement()?.type === 'Table' ? (subProp.targetArray ? getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key) : (selectedElement() | getValueByPath : subProp.key)) : (selectedElement() | getValueByPath : subProp.key)\"\n (ngModelChange)=\"selectedElement()?.type === 'Table' ? (subProp.targetArray ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, $event,false, prop.isTranslate) : setValueByPath(subProp.key, $event)) : setValueByPath(subProp.key, $event, prop.isTranslate)\"\n />\n <input\n *ngIf=\"subProp.type === 'boolean'\"\n type=\"checkbox\"\n [checked]=\"selectedElement() | getValueByPath : subProp.key\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\"\n />\n <select\n *ngIf=\"subProp.type === 'select'\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (subProp.targetArray || subProp.isTableColumn) ? (getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, subProp.isTableColumn)) : (selectedElement() | getValueByPath : subProp.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (subProp.targetArray || subProp.isTableColumn) ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, $event, subProp.isTableColumn, prop.isTranslate) : setValueByPath(subProp.key, $event, prop.isTranslate))\"\n >\n <option *ngFor=\"let option of subProp.options\" [value]=\"option.value\">{{ option.labelPath | nxtCustomTranslate : option.label }}</option>\n </select>\n <input\n *ngIf=\"subProp.type === 'checkbox'\"\n type=\"checkbox\"\n [checked]=\"selectedElement() | getValueByPath : subProp.key\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\"\n />\n </div>\n </div>\n </div>\n </div>\n <div *ngIf=\"prop.type === 'align'\">\n <button *ngFor=\"let option of prop.options\" (click)=\"onAlignSelect(option.value)\" [ngClass]=\"{'active': selectedElement()?.textAlign === option.value}\" [title]=\"option.value\">\n <img [src]=\"'../assets/icons/' + option.icon + '.svg'\" [alt]=\"option.value\" class=\"icon-size\" />\n </button>\n </div>\n <div *ngIf=\"prop.type === 'style'\">\n <button *ngFor=\"let option of prop.options\" (click)=\"onStyleSelect(option.value)\" [ngClass]=\"{'active': isStyleActive(option.value)}\" [title]=\"option.value\">\n <img [src]=\"'../assets/icons/' + option.icon + '.svg'\" [alt]=\"option.value\" class=\"icon-size\" />\n </button>\n </div>\n <div *ngIf=\"prop.type === 'color'\">\n <input\n type=\"color\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n />\n </div>\n <div *ngIf=\"prop.key === 'title'\" style=\"margin-top: 15px; border: 1px solid #ddd; padding: 20px; border-radius: 12px; background-color: #f9f9f9;\">\n <div class=\"form-header\">\n <label class=\"form-label\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <button (click)=\"addNewButton()\" class=\"add-button\">+ {{ 'ADD_BUTTON' | nxtCustomTranslate : 'Add Button' }}</button>\n </div>\n <div *ngFor=\"let btn of book()?.questionbook?.action || []; let i = index\" class=\"button-config-card\">\n <div class=\"form-group\">\n <label>{{ 'BUTTON_NAME' | nxtCustomTranslate : 'Button Name' }}</label>\n <input type=\"text\" [ngModel]=\"btn.name\" (ngModelChange)=\"onButtonPropertyChange(i, 'name', $event,true)\" placeholder=\"Enter button name\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'EVENT_NAME' | nxtCustomTranslate : 'Event Name' }}</label>\n <input type=\"text\" [ngModel]=\"btn.eventtoemit\" (ngModelChange)=\"onButtonPropertyChange(i, 'eventtoemit', $event)\" placeholder=\"Event to emit\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'ALT' | nxtCustomTranslate : 'Alt' }}</label>\n <input type=\"text\" [ngModel]=\"btn.alt\" (ngModelChange)=\"onButtonPropertyChange(i, 'alt', $event)\" placeholder=\"Button alt text\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'END_POINT' | nxtCustomTranslate : 'Endpoint' }}</label>\n <input type=\"text\" [ngModel]=\"btn.endpoint\" (ngModelChange)=\"onButtonPropertyChange(i, 'endpoint', $event)\" placeholder=\"API endpoint\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'METHOD' | nxtCustomTranslate : 'Method' }}</label>\n <select [ngModel]=\"btn.method\" (ngModelChange)=\"onButtonPropertyChange(i, 'method', $event)\">\n <option value=\"GET\">GET</option>\n <option value=\"POST\">POST</option>\n <option value=\"PUT\">PUT</option>\n <option value=\"DELETE\">DELETE</option>\n </select>\n </div>\n <div class=\"form-group\">\n <label>{{ 'BACKGROUND_COLOR' | nxtCustomTranslate : 'Background Color' }}</label>\n <input type=\"color\" [ngModel]=\"btn.bgColor\" (ngModelChange)=\"onButtonPropertyChange(i, 'bgColor', $event)\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'BORDER_RADIUS' | nxtCustomTranslate : 'Border Radius' }}</label>\n <input type=\"range\" min=\"0\" max=\"50\" [ngModel]=\"btn.borderRadius\" (ngModelChange)=\"onButtonPropertyChange(i, 'borderRadius', $event)\">\n <span>{{ btn.borderRadius }}px</span>\n </div>\n <div class=\"form-group\">\n <label>{{ 'BUTTON_WIDTH_PX' | nxtCustomTranslate : 'Button Width (px)' }}</label>\n <input type=\"number\" [ngModel]=\"btn.width\" (ngModelChange)=\"onButtonPropertyChange(i, 'width', $event)\" min=\"50\" placeholder=\"Enter width in px\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'TEXT_COLOR' | nxtCustomTranslate : 'Text Color' }}</label>\n <input type=\"color\" [ngModel]=\"btn.textColor\" (ngModelChange)=\"onButtonPropertyChange(i, 'textColor', $event)\">\n </div>\n <div class=\"form-group\">\n <label>{{ 'POSITION_PERCENT' | nxtCustomTranslate : 'Position (%)' }}</label>\n <input type=\"range\" min=\"0\" max=\"100\" [ngModel]=\"btn.positionPercent\" (ngModelChange)=\"onButtonPropertyChange(i, 'positionPercent', $event)\">\n <span>{{ btn.positionPercent }}%</span>\n </div>\n <button (click)=\"removeButton(btn)\" class=\"remove-button\">\u00D7 {{ 'REMOVE' | nxtCustomTranslate : 'Remove' }}</button>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n }\n </div>\n\n <div class=\"tab-content\" *ngIf=\"activeTab() === 'property'\">\n @defer (when getProperties()) {\n <div>\n <label>Label Id</label>\n <div style=\"font-size: 13px; padding: 11px; border-radius: 5px; background-color: #f8f8f8; border: 1px solid #ddd;\">\n {{ headerSelect() ? bookId() : selectedElement()?.id }}\n </div>\n <ng-container *ngFor=\"let prop of getProperties()?.fieldProps; trackBy: trackByProp\">\n <div class=\"form-group\">\n <label *ngIf=\"prop.type !== 'subQuestion'\" class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <div *ngIf=\"prop.type === 'toggleGroup'\" class=\"toggle-group\">\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" \n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isOptional', true) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : 'isOptional')\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isOptional', $event, true, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange('isOptional', $event)\"\n />\n {{ 'REQUIRED' | nxtCustomTranslate : 'Required' }}\n </label>\n </div>\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" \n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isReadOnly', true) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : 'isReadOnly')\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isReadOnly', $event, true, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange('isReadOnly', $event)\"\n />\n {{ 'READ_ONLY' | nxtCustomTranslate : 'Read Only' }}\n </label>\n </div>\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" \n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isHidden', true) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : 'isHidden')\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), 'isHidden', $event, true, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange('isHidden', $event)\"\n />\n {{ 'IS_HIDE' | nxtCustomTranslate : 'Is Hide' }}\n </label>\n </div>\n </div>\n <div *ngIf=\" prop.type === 'checkbox' || prop.type === 'radio' || prop.key === 'options'\" class=\"options-container\">\n <div class=\"option-list\" (dragover)=\"onDragOver($event)\" (drop)=\"onDrop($event, prop.key)\">\n <div *ngFor=\"let option of selectedElement()?.type === 'Table' && selectColumn() ? getValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(), prop.key, true) : selectedElement()[prop.key] ; let i = index\" class=\"option-items\" [attr.data-id]=\"option.id\" draggable=\"true\" (dragstart)=\"onDragStart($event, option.id)\">\n <input type=\"text\" style=\"padding: 4px; border-radius: 2px;\" [ngModel]=\"option.value\" (ngModelChange)=\"option.value = $event\" placeholder=\"Value\" class=\"options\" />\n <input type=\"text\" style=\"padding: 4px; border-radius: 2px;\" [ngModel]=\"option.label\" (ngModelChange)=\"option.label = $event; optionTranslationUpdate(option,$event)\" placeholder=\"Label\" class=\"options\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeOption(selectedElement()[prop.key], option.id)\">\n <span class=\"drag-handle\">\u2630</span>\n </div>\n </div>\n <button (click)=\"addOption(selectedElement()?.type === 'Table' && selectColumn() ? getValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(), prop.key, true) : selectedElement()[prop.key])\">\n <div class=\"add-varient\">\n <span class=\"text-lg\">+</span>\n <span>{{ 'ADD' | nxtCustomTranslate : 'Add' }}</span>\n </div>\n </button>\n </div>\n <input *ngIf=\"prop.type === 'text'\"\n type=\"text\"\n [placeholder]=\"prop.placeholder\"\n [ngModel]=\"headerSelect() ? book().records[0].title : (selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"headerSelect() ? updateTitle($event) : (selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n [class.read-only]=\"selectedElement()?.readOnly\"\n [readonly]=\"selectedElement()?.readOnly\"\n />\n <div *ngIf=\"prop.type === 'subQuestion'\">\n <div class=\"style-toggle-header\" (click)=\"toggleSubQuestion(prop)\">\n <div class=\"head-elements\">Sub Text</div>\n <img [src]=\"isExpanded ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\"\n alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n <div *ngIf=\"isExpanded\" style=\"border: 1px solid #ddd; border-radius: 4px;\">\n <div *ngFor=\"let subProp of prop.subQuestion; trackBy: trackByProp\" style=\"background-color: #e7f2ff; padding: 8px; border-radius: 4px;\">\n <div class=\"form-group\">\n <label>{{ subProp.labelPath | nxtCustomTranslate : subProp.label }}</label>\n <input *ngIf=\"subProp.type === 'text'\"\n type=\"text\"\n [placeholder]=\"subProp.placeholder\"\n [value]=\"getOptimizedSubPropValue(subProp)\"\n (input)=\"(selectedElement()?.type === 'Table' && (subProp.targetArray || subProp.isTableColumn)) ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn(), subProp.key, $event.target.value, subProp.isTableColumn, prop.isTranslate) : setValueByPath(subProp.key, $event.target.value, prop.isTranslate)\"\n [class.read-only]=\"selectedElement()?.readOnly\"\n [readonly]=\"selectedElement()?.readOnly\" />\n \n <!-- AP-02APR25 Render input field only if subProp.type is 'array' -->\n <input *ngIf=\"subProp.type === 'array'\" type=\"text\" [placeholder]=\"subProp.placeholder\"\n [value]=\"getValueByPath(subProp.key)\" (input)=\"setValueByPath(subProp.key, $event.target.value, prop.isTranslate)\" />\n\n <input *ngIf=\"subProp.type === 'boolean'\" type=\"checkbox\" [checked]=\"getValueByPath(subProp.key)\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\" />\n </div>\n </div>\n </div>\n </div>\n <div *ngIf=\"prop.type === 'checkbox'\">\n <span class=\"toggle-label\" style=\"padding-right: 10px;\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</span>\n <input\n type=\"checkbox\"\n [checked]=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn) : (selectedElement() | getValueByPath : prop.key)) : (selectedElement() | getValueByPath : prop.key)\"\n (change)=\"selectedElement()?.type === 'Table' ? (prop.targetArray || prop.isTableColumn ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : onToggleChange(prop.key, $event)) : onToggleChange(prop.key, $event)\"\n />\n </div>\n </div>\n </ng-container>\n <div class=\"style-toggle-header\" (click)=\"toggleStyleSection()\">\n <div class=\"head-elements\">{{ 'STYLE' | nxtCustomTranslate : 'Style' }}</div>\n <img [src]=\"isStyleExpanded() ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\" alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n <div *ngIf=\"isStyleExpanded()\" style=\"border: 1px solid #ddd; padding: 8px; border-radius: 4px;\">\n <div class=\"form-group\">\n <div *ngFor=\"let key of getStyleKeys()\">\n <label>{{ key }}</label>\n <input\n type=\"text\"\n [value]=\"selectedElement()?.type === 'Table' && selectColumn() ? getValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(),'style.' + key, true) : (selectedElement() | getValueByPath : 'style.' + key)\"\n (input)=\"(selectedElement()?.type === 'Table' && selectColumn() ) ? updateValueByArrayPath('fieldsMeta', 'uniqueIdentifier', selectColumn(), 'style.' + key, $event.target.value, true) : setValueByPath('style.' + key, $event.target.value)\"\n placeholder=\"Enter {{ key }}\"\n />\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n\n <div class=\"tab-content\" *ngIf=\"activeTab() === 'appearance'\">\n @defer (when getProperties()) {\n <div>\n <ng-container *ngFor=\"let prop of getProperties()?.appearance; trackBy: trackByProp\">\n <div class=\"form-group\">\n <label class=\"text-sm\">{{ prop.labelPath | nxtCustomTranslate : prop.label }}</label>\n <select\n *ngIf=\"prop.type === 'select'\"\n [ngModel]=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? (getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, prop.isTableColumn)) : (selectedElement() | getValueByPath : prop.key))\"\n (ngModelChange)=\"(selectedElement()?.type === 'Table' && (prop.targetArray || prop.isTableColumn) ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn(), prop.key, $event, prop.isTableColumn, prop.isTranslate) : setValueByPath(prop.key, $event, prop.isTranslate))\"\n >\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\">{{ option.labelPath | nxtCustomTranslate : option.label }}</option>\n </select>\n <input\n *ngIf=\"prop.type === 'text'\"\n type=\"text\"\n [placeholder]=\"prop.placeholder\"\n [ngModel]=\"selectedElement() | getValueByPath : prop.key\"\n (ngModelChange)=\"setValueByPath(prop.key, $event, prop.isTranslate)\"\n />\n\n <div class=\"flex-container\">\n <div *ngIf=\"prop.type === 'color'\" class=\"color-selector\">\n <input\n type=\"color\"\n [ngModel]=\"selectedElement()?.fontColor\"\n (ngModelChange)=\"setValueByPath('fontColor', $event, prop.isTranslate)\"\n >\n </div>\n <div *ngIf=\"prop.type === 'color'\" class=\"hex-input-container\">\n <span>{{ 'HEX_CODE' | nxtCustomTranslate : 'HEX Code' }}</span>\n <input\n type=\"text\"\n [ngModel]=\"selectedElement() | getValueByPath : prop.key\"\n (ngModelChange)=\"setValueByPath(prop.key, $event, prop.isTranslate)\"\n />\n </div>\n </div>\n <div *ngIf=\"prop.type === 'button-toggle'\" class=\"button-toggle-wrapper\">\n <button\n type=\"button\"\n class=\"toggle-button\"\n (click)=\"duplicateField(selectedElement())\"\n >\n {{ 'ADD_DUPLICATE' | nxtCustomTranslate : 'Add Duplicate' }}\n </button>\n </div>\n </div>\n </ng-container>\n </div>\n }\n </div>\n\n <div class=\"button-container\" *ngIf=\"!templateSelected\">\n <button class=\"cancel-btn\" (click)=\"onCancel()\">{{ 'CANCEL' | nxtCustomTranslate : 'Cancel' }}</button>\n <button class=\"save-btn\" (click)=\"handleButtonClick()\">{{ 'SAVE' | nxtCustomTranslate : 'Save' }}</button>\n </div>\n\n <div class=\"button-container\" *ngIf=\"templateSelected\" style=\"margin-top: 20px;\">\n <button class=\"save-btn\" (click)=\"handleTemplateSave()\">{{ 'SAVE_TEMPLATE' | nxtCustomTranslate : 'Save Template' }}</button>\n </div>\n</div>", styles: ["*{margin:0;padding:0;box-sizing:border-box;font-family:Roboto,sans-serif}.properties{height:calc(100vh - 20px);overflow-y:auto}.container{width:100%;max-width:500px;margin:0 auto;background:#fff;box-shadow:0 2px 10px #0000001a;overflow:hidden;font-family:Arial,sans-serif}.design-header{display:flex;justify-content:center;align-items:center;padding:15px 20px;background:#fff;border-radius:8px;box-shadow:0 2px 10px #0000001a;margin-bottom:20px}.header-title{font-size:20px;font-weight:400;color:#222}.toggle-header,.style-toggle-header{display:flex;align-items:center;justify-content:space-between;cursor:pointer;padding:10px;background:#f8f8f8;border:1px solid #ddd;border-radius:6px;margin-bottom:6px}.tabs{display:flex;background:#f0f2f5;border-bottom:2px solid #0052cc}.tab{flex:1;padding:15px 10px;text-align:center;cursor:pointer}.tab.active{background:#0052cc;color:#fff;font-weight:700}.tab-content{padding:20px;max-height:80vh;overflow-y:auto;overflow-x:hidden}.form-group{margin-bottom:15px}label{display:block;font-size:14px;font-weight:500;color:#444;margin-bottom:8px}.required:before{content:\"*\";color:red;margin-right:3px}input[type=text],input[type=number],select,textarea{width:100%;padding:10px;font-size:14px;border:1px solid #ccc;border-radius:6px;outline:none;transition:all .3s;background:#f8f8f8}input:focus,select:focus,textarea:focus{border-color:#007bff;background:#fff;box-shadow:0 0 5px #007bff4d}textarea{min-height:55px;resize:vertical}button,.btn{padding:10px 15px;border:none;border-radius:6px;background:#007bff;color:#fff;font-size:15px;cursor:pointer;transition:all .3s}button:hover,.btn:hover{background:#0056b3;transform:translateY(-2px)}.add-button{padding:8px 14px;background:#0954c5;border-radius:8px}.remove-button{background:#e74c3c;padding:6px 12px;margin-top:10px}.remove-button:hover{background:#c0392b}.cancel-btn{background:#fff;color:#666;border:1px solid #ddd;margin-right:10px}.save-btn{background:#0052cc}.toggle-group{display:grid;grid-template-columns:1fr 1fr;gap:10px}.toggle-item{display:flex;align-items:center;gap:10px;padding:8px}.switch{position:relative;width:42px;height:22px}.switch input{opacity:0;width:0;height:0}.slider{position:absolute;cursor:pointer;inset:0;background:#ccc;transition:.4s;border-radius:24px}.slider:before{position:absolute;content:\"\";height:20px;width:20px;left:1px;bottom:1px;background:#fff;transition:.4s;border-radius:50%}input:checked+.slider{background:#2196f3}input:checked+.slider:before{transform:translate(18px)}.radio-item{display:flex;align-items:center;gap:20px}.radio-item input{accent-color:#007bff}.checkbox-row{display:flex;margin-bottom:10px}.checkbox-group{display:flex;align-items:center;margin-right:20px;min-width:120px}.checkbox-group input[type=checkbox]{margin-right:5px}.color-picker-row,.color-picker-container{display:flex;align-items:center}.color-picker-container{border:1px solid #ddd;border-radius:4px;margin-right:10px}.color-box,.color-selector input[type=color]{width:78px;height:40px;border:none;border-radius:4px;cursor:pointer}.hex-input-container{display:flex;gap:20px;align-items:center;font-size:12px;color:#b0b0b0}.hex-input-container span{font-size:14px;margin-top:10px}.hex-input,.hex-input-container input[type=text]{width:120px;padding:10px 12px;border:1px solid #d1d1d1;color:#28343e}.hex-label{color:#999;margin-right:5px}.select-container,.input-box-field{position:relative;width:100%}.dropdown-arrow,.input-box-field:after{position:absolute;right:10px;top:50%;transform:translateY(-50%);pointer-events:none;color:#666;font-size:12px}.input-box-field:after{content:\"\\25bc\";color:#1c1b1f;font-size:10px}.input-box-field select{background:#28343e;color:#fff;border:none;appearance:none;-webkit-appearance:none;-moz-appearance:none}.input-box-field select::-ms-expand{display:none}.all-properties details{background:#fff;border:1px solid #ddd;border-radius:8px;margin-bottom:12px;padding:12px;box-shadow:0 2px 8px #0000000d}.all-properties summary{font-size:15px;font-weight:400;cursor:pointer;padding:6px;transition:color .3s}.all-properties summary:hover{color:#007bff}.inner-content{padding:12px 0}.head-elements{font-size:14px;font-weight:500;color:#444}.options-container{display:flex;flex-direction:column;gap:12px}.field-size-controls,.flex-container{display:flex;align-items:center;gap:12px}.flex-container{margin-bottom:1rem}.size-input{width:110px;text-align:center}.input-container{display:flex;flex-direction:column;align-items:flex-start;gap:10px;width:100%}.subtext-textarea{width:100%;margin-left:auto}.arrow-icon{width:19px;height:23px;transition:transform .3s ease}.icon{display:inline-block;width:18px;height:18px;border-radius:50%;text-align:center;line-height:18px;color:#fff;font-size:12px;margin-left:5px}.edit-icon{background:#4caf50}.view-icon{background:#2196f3}.delete-icon{background:#f44336}.logo-icon{width:20px;height:20px;display:flex;justify-content:center;background:#d0d9ff;border-radius:4px}.link-icon{background:#e7f2ff;padding:5px;border-radius:5px;margin:5px;display:inline-block;cursor:pointer;position:relative;transition:all .3s}.link-icon:hover{background:#d0e5ff}.link-icon:active{background:#a8d0ff}.link-dropdown-menu{position:absolute;top:100%;right:0;background:#fff;border:1px solid #ccc;padding:10px;width:200px;box-shadow:0 4px 6px #0000001a}.link-dropdown-menu input{width:100%;margin-bottom:5px;padding:5px;border:1px solid #ccc;border-radius:3px}.option-items{display:flex;align-items:center;padding:5px;gap:5px;border:1px solid #ccc;margin-bottom:10px;cursor:grab;background:#fff}.option-items:active{opacity:.5}.drag-handle{cursor:grab}.button-toggle-wrapper{margin-top:8px}.toggle-button{padding:8px 16px;border:1px solid #cbd2d9;border-radius:6px;font-size:14px;cursor:pointer;transition:all .2s ease-in-out}.toggle-button.active:hover{background:#2c6dd5}.button-config-card{background:#fff;padding:15px;border-radius:12px;border:1px solid #ccc;margin-top:20px;box-shadow:0 2px 8px #0000000d}.design-footer{display:flex;justify-content:space-between;margin-top:20px}.button-container{display:flex;padding:15px;background:#f9f9f9;border-top:1px solid #eee}.button-container .cancel-btn,.button-container .save-btn{flex:1;padding:12px;font-weight:700}.divider{border-top:1px dashed #ddd;margin:20px 0}input{width:auto}@media screen and (max-width: 768px){.container{height:calc(100vh - 20px);min-height:calc(100vh - 20px)}.tabs{flex-direction:column}.tab{padding:1rem;font-size:.9rem}.form-group,.tab-content[aria-label=attributes] .form-group,.tab-content[aria-label=property] .form-group,.tab-content[aria-label=appearance] .form-group{flex-direction:column;grid-template-columns:1fr}.toggle-group{flex-direction:column;align-items:flex-start}}@media screen and (max-width: 480px){.container{padding:0 10px}.tabs{flex-direction:column}.tab{padding:1rem;border-bottom:1px solid #dee2e6}input[type=text],input[type=number],select,textarea{font-size:.9rem}}.translation-fallback label,.translation-input-group label{font-weight:500;font-size:13px;margin-bottom:4px;display:block;color:#666}.readonly-box{font-size:14px;padding:4px;border:1px solid #ddd;border-radius:5px;-webkit-user-select:text;user-select:text;cursor:text;color:#7a7a7a;margin-bottom:3px}.copied-msg{font-size:12px;color:green;opacity:0;animation:fadeInOut 1.5s ease}@keyframes fadeInOut{0%{opacity:0;transform:translateY(-2px)}20%{opacity:1;transform:translateY(0)}80%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-2px)}}\n"] }]
|
|
1106
|
-
}], ctorParameters: () => [{ type: i1.FormBuilderService }, { type: i2.TemplateService }, { type: i3.TranslationService }, { type: i0.ChangeDetectorRef }], propDecorators: { templateSelected: [{
|
|
1107
|
-
type: Input
|
|
1108
|
-
}], selectedElementType: [{
|
|
1109
|
-
type: Input
|
|
1110
|
-
}], formButtonHandler: [{
|
|
1111
|
-
type: Output
|
|
1112
|
-
}], templateSaveHandler: [{
|
|
1113
|
-
type: Output
|
|
1114
|
-
}], dropdown: [{
|
|
1115
|
-
type: ViewChild,
|
|
1116
|
-
args: ['dropdown', { static: false }]
|
|
1117
|
-
}], onClickOutside: [{
|
|
1118
|
-
type: HostListener,
|
|
1119
|
-
args: ['document:click', ['$event']]
|
|
1120
|
-
}] } }) });
|
|
1121
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvcGVydGllcy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9ueHQtYXBwL3NyYy9saWIvcGFnZXMvYnVpbGRlci9wcm9wZXJ0aWVzL3Byb3BlcnRpZXMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbnh0LWFwcC9zcmMvbGliL3BhZ2VzL2J1aWxkZXIvcHJvcGVydGllcy9wcm9wZXJ0aWVzLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQWMsWUFBWSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQVUsU0FBUyxFQUFxQixNQUFNLGVBQWUsQ0FBQztBQUMxTCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRzdDLE9BQU8sRUFBRSxFQUFFLElBQUksTUFBTSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXBDLHFGQUFxRjtBQUNyRixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsb0JBQW9CLEVBQUUsa0JBQWtCLEVBQUUsdUJBQXVCLEVBQXVCLE1BQU0sdUNBQXVDLENBQUM7QUFFckssT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdkQsT0FBTyxFQUFFLElBQUksRUFBaUIsTUFBTSxlQUFlLENBQUM7QUFJcEQsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0scUNBQXFDLENBQUM7Ozs7Ozs7QUFFN0UsMENBQTBDO0FBTTFDLE1BQU0sT0FBTyxrQkFBa0I7SUFDN0IsU0FBUyxDQUFDLEdBQVEsRUFBRSxJQUFZLEVBQUUsZUFBb0IsRUFBRTtRQUN0RCxJQUFJLENB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QVEsRUFBRTt5QkFDMUQsRUFBQztvQkFDRixFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFO29CQUNuSCxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRTs0QkFDeEgsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRTs0QkFDckQsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRTs0QkFDdkQsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRTt5QkFDdEQsRUFBQztvQkFDRixFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRTs0QkFDNUgsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRTs0QkFDOUQsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRTs0QkFDOUQsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxlQUFlLEVBQUUsU0FBUyxFQUFFLGVBQWUsRUFBRTs0QkFDcEUsRUFBRSxLQUFLLEVBQUUs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QyxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUVELFVBQVU7UUFDUixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN2QixVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ2QsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDdkMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3pCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN2QixVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ2QsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDdkMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3pCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELFFBQVE7UUFDTixJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFDLFVBQVcsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDeEUsQ0FBQztJQUVELFNBQVM7UUFDUCxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFDLFVBQVcsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDeEUsQ0FBQztJQUVELFFBQVE7UUFDTixJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFD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b21wb25lbnQsIEVsZW1lbnRSZWYsIEV2ZW50RW1pdHRlciwgSG9zdExpc3RlbmVyLCBJbnB1dCwgT25Jbml0LCBPdXRwdXQsIHNpZ25hbCwgY29tcHV0ZWQsIGVmZmVjdCwgVmlld0NoaWxkLCBDaGFuZ2VEZXRlY3RvclJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgSW1hZ2VDcm9wcGVyQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vLi4vY29tcG9uZW50cy9pbWFnZS1jcm9wcGVyL2NvbXBvbmVudC9pbWFnZS1jcm9wcGVyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBOeHRTZWFyY2hCb3ggfSBmcm9tICcuLi8uLi8uLi9jb21wb25lbnRzL3NlYXJjaC1ib3gvc2VhcmNoLWJveC5jb21wb25lbnQnO1xuaW1wb3J0IHsgdjQgYXMgdXVpZHY0IH0gZnJvbSAndXVpZCc7XG5pbXBvcnQgeyBDcm9wcGVyUG9zaXRpb24sIERpbWVuc2lvbnMsIEltYWdlVHJhbnNmb3JtIH0gZnJvbSAnLi4vLi4vLi4vY29tcG9uZW50cy9pbWFnZS1jcm9wcGVyL2ludGVyZmFjZXMnO1xuLy9BUC0yNUpVTjI1LUltcG9ydGluZyBjb21tb24gY29uc3RhbnRzIGZvciBlbGVtZW50LCBmaWVsZCwgYW5kIGFwcGVhcmFuY2UgcHJvcGVydGllc1xuaW1wb3J0IHsgQ09NTU9OX0VMRU1FTlRfUFJPUFMsIENPTU1PTl9PUFRJT05TX0ZJRUxELCBDT01NT05fRklFTERfUFJPUFMsIENPTU1PTl9BUFBFQVJBTkNFX1BST1BTLCBDT01NT05fQ09MVU1OX0ZJRUxEIH0gZnJvbSAnLi4vcHJvcGVydGllcy9jb21tb24tZmllbGRzLmNvbnN0YW50cyc7XG5pbXBvcnQgeyB0b1NpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7IE5nQ2xhc3MsIE5nRm9yLCBOZ0lmIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IFBpcGUsIFBpcGVUcmFuc2Zvcm0gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1CdWlsZGVyU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2Zvcm0tYnVpbGRlci9mb3JtLWJ1aWxkZXIuc2VydmljZSc7XG5pbXBvcnQgeyBUZW1wbGF0ZVNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy90ZW1wbGF0ZS90ZW1wbGF0ZS5zZXJ2aWNlJztcbmltcG9ydCB7IFRyYW5zbGF0aW9uU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL3RyYW5zbGF0aW9uL3RyYW5zbGF0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHsgTnh0Q3VzdG9tVHJhbnNsYXRlUGlwZSB9IGZyb20gJy4uLy4uLy4uL3BpcGUvY3VzdG9tLXRyYW5zbGF0ZS5waXBlJztcblxuLy8gQ3VzdG9tIHBpcGUgZm9yIHBhdGgtYmFzZWQgdmFsdWUgYWNjZXNzXG5AUGlwZSh7XG4gIG5hbWU6ICdnZXRWYWx1ZUJ5UGF0aCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIHB1cmU6IHRydWVcbn0pXG5leHBvcnQgY2xhc3MgR2V0VmFsdWVCeVBhdGhQaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XG4gIHRyYW5zZm9ybShvYmo6IGFueSwgcGF0aDogc3RyaW5nLCBkZWZhdWx0VmFsdWU6IGFueSA9ICcnKTogYW55IHtcbiAgICBpZiAoIW9iaiB8fCAhcGF0aCkgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICByZXR1cm4gcGF0aC5zcGxpdCgnLicpLnJlZHVjZSgobywgaykgPT4gbz8uW2tdID8/IGRlZmF1bHRWYWx1ZSwgb2JqKTtcbiAgfVxufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtcHJvcGVydGllcycsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIEZvcm1zTW9kdWxlLCBJbWFnZUNyb3BwZXJDb21wb25lbnQsIE54dFNlYXJjaEJveCwgTmdDbGFzcywgTmdGb3IsIE5nSWYsIEdldFZhbHVlQnlQYXRoUGlwZSwgTnh0Q3VzdG9tVHJhbnNsYXRlUGlwZV0sXG4gIHRlbXBsYXRlVXJsOiAnLi9wcm9wZXJ0aWVzLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vcHJvcGVydGllcy5jb21wb25lbnQuY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIFByb3BlcnRpZXNDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBASW5wdXQoKSB0ZW1wbGF0ZVNlbGVjdGVkID0gZmFsc2U7XG4gIEBJbnB1dCgpIHNldCBzZWxlY3RlZEVsZW1lbnRUeXBlKHZhbHVlOiBzdHJpbmcpIHtcbiAgICB0aGlzLnNlbGVjdGVkRWxlbWVudFR5cGVTaWcuc2V0KHZhbHVlKTtcbiAgfVxuICBAT3V0cHV0KCkgZm9ybUJ1dHRvbkhhbmRsZXIgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgQE91dHB1dCgpIHRlbXBsYXRlU2F2ZUhhbmRsZXIgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICBAVmlld0NoaWxkKCdkcm9wZG93bicsIHsgc3RhdGljOiBmYWxzZSB9KSBkcm9wZG93biE6IEVsZW1lbnRSZWY7XG5cbiAgLy8gU2lnbmFscyBmb3IgcmVhY3RpdmUgc3RhdGVcbiAgc2VsZWN0ZWRFbGVtZW50VHlwZVNpZyA9IHNpZ25hbDxzdHJpbmc+KCcnKTtcbiAgc2VsZWN0ZWRFbGVtZW50ID0gc2lnbmFsPGFueT4obnVsbCk7XG4gIHNlbGVjdGVkRWxlbWVudEluZGV4ID0gc2lnbmFsPG51bWJlcj4oLTEpO1xuICBoZWFkZXJTZWxlY3QgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICBib29rID0gc2lnbmFsPGFueT4obnVsbCk7XG4gIGJvb2tJZCA9IHNpZ25hbDxhbnk+KG51bGwpO1xuICBhY3RpdmVUYWIgPSBzaWduYWw8c3RyaW5nPignYXR0cmlidXRlcycpO1xuICBzZWxlY3RDb2x1bW4gPSBzaWduYWw8YW55PihudWxsKTtcbiAgdHJhbnNmb3JtID0gc2lnbmFsPEltYWdlVHJhbnNmb3JtPih7XG4gICAgdHJhbnNsYXRlVW5pdDogJ3B4JyxcbiAgICBzY2FsZTogMSxcbiAgICByb3RhdGU6IDAsXG4gICAgZmxpcEg6IGZhbHNlLFxuICAgIGZsaXBWOiBmYWxzZSxcbiAgICB0cmFuc2xhdGVIOiAwLFxuICAgIHRyYW5zbGF0ZVY6IDBcbiAgfSk7XG4gIGNhbnZhc1JvdGF0aW9uID0gc2lnbmFsPG51bWJlcj4oMCk7XG4gIGNyb3BwZXIgPSBzaWduYWw8Q3JvcHBlclBvc2l0aW9uIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuICBsb2FkaW5nID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgaXNMaW5rRHJvcGRvd25PcGVuID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgZXJyb3JNZXNzYWdlID0gc2lnbmFsPHN0cmluZz4oJycpO1xuICBib29rU3VidGV4dCA9IHNpZ25hbCh7XG4gICAgZW5kcG9pbnQ6ICdodHRwczovL2Rldi1hcGkudmFsYXJoci5jb20vbnh0JyxcbiAgICB2YXJpYWJsZTogbnVsbCxcbiAgICBmaWVsZDogWydsYWJlbCcsICduYW1lJ10sXG4gICAgZGVmYXVsdEZpZWxkOiAnbGFiZWwnXG4gIH0pO1xuICBpc1N0eWxlRXhwYW5kZWQgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICBjcm9wcGVyTWF4SGVpZ2h0ID0gMDtcbiAgY3JvcHBlck1heFdpZHRoID0gMDtcbiAgY3JvcHBlck1pbkhlaWdodCA9IDA7XG4gIGNyb3BwZXJNaW5XaWR0aCA9IDA7XG4gIGNyb3BwZXJTdGF0aWNXaWR0aCA9IDA7XG4gIGNyb3BwZXJTdGF0aWNIZWlnaHQgPSAwO1xuICBhc3BlY3RSYXRpbyA9IDQgLyAzO1xuICByb3VuZENyb3BwZXIgPSBmYWxzZTtcbiAgaXNFeHBhbmRlZDogQm9vbGVhbiA9IGZhbHNlXG4gIGFsaWduSW1hZ2UgPSAnY2VudGVyJyBhcyBjb25zdDtcbiAgZWxlbWVudFR5cGUgPSBbJ0hlYWRlcicsJ0xpbmUnLCdTcGFjZScsJ1RhYmxlJywnVGFibGVDb2x1bW4nLCdDaGVja2JveCcsJ0Ryb3Bkb3duJywnUmFkaW8nLFwiVGV4dFwiLCBcIkNhbGVuZGFyXCIsIFwiRGF0ZVwiLCBcIlRpbWVcIiwgXCJEYXRlVGltZVwiLCBcIkVtYWlsXCIsIFwiQm9va1wiLCBcIkxpc3RcIiwgXCJUZXh0QXJlYVwiLCBcIlJpY2hUZXh0QXJlYVwiLCBcIk51bWJlclwiLCBcIkltYWdlXCIsIFwiTGFiZWxcIiwgXCJCb29sZWFuXCIsIFwiRmlsZVwiLCBcIkljb25cIiwgJ0J1dHRvbiddXG5cbiAgLy8gQWRkIHRoZXNlIHByb3BlcnRpZXMgdG8geW91ciBjb21wb25lbnQgY2xhc3NcbiAgcHJpdmF0ZSBfY2FjaGVkUHJvcGVydGllczogYW55ID0gbnVsbDtcbiAgcHJpdmF0ZSBfbGFzdFNlbGVjdGVkRWxlbWVudDogYW55ID0gbnVsbDtcbiAgcHJpdmF0ZSBfbGFzdFNlbGVjdGVkQ29sdW1uOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICAvLyBDb21wdXRlZCBzaWduYWxzIGZvciBtZW1vaXphdGlvblxuICBmaWVsZEFzU3RyaW5nID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5ib29rU3VidGV4dCgpLmZpZWxkLmpvaW4oJywgJykpO1xuICBmaWx0ZXJlZENvbHVtbnMgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3QgZmllbGRzTWV0YSA9IHRoaXMuc2VsZWN0ZWRFbGVtZW50KCk/LmZpZWxkc01ldGEgPz8gW107XG4gICAgcmV0dXJuIEFycmF5LmlzQXJyYXkoZmllbGRzTWV0YSlcbiAgICAgID8gZmllbGRzTWV0YS5maWx0ZXIoY29sdW1uID0+IGNvbHVtbi51bmlxdWVJZGVudGlmaWVyICE9PSB0aGlzLnNlbGVjdENvbHVtbigpKVxuICAgICAgOiBbXTtcbiAgfSk7XG5cbiAgLy8gTWVtb2l6ZWQgcHJvcGVydGllc1xuICBlbGVtZW50UHJvcGVydGllcyA9IGNvbXB1dGVkKCgpID0+IHRoaXMuY3JlYXRlRWxlbWVudFByb3BlcnRpZXMoKSk7XG4gIGZvcm1CdWlsZGVyTGFuZ3VhZ2VDb2RlOmFueSA9ICdlbidcbiAgY29waWVkID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBmb3JtQnVpbGRlclNlcnZpY2U6IEZvcm1CdWlsZGVyU2VydmljZSxcbiAgICBwcml2YXRlIHRlbXBsYXRlU2VydmljZTogVGVtcGxhdGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgdHJhbnNsYXRpb25TZXJ2aWNlOiBUcmFuc2xhdGlvblNlcnZpY2UsXG4gICAgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmXG4gICkge31cbiAgXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLnNlbGVjdEhlYWRlclN1YmplY3QkLnN1YnNjcmliZShoZWFkZXIgPT4ge1xuICAgICAgaWYgKGhlYWRlcikge1xuICAgICAgICB0aGlzLnNlbGVjdGVkRWxlbWVudC5zZXQoeyB0eXBlOiBoZWFkZXIgfSk7XG4gICAgICAgIHRoaXMuaGVhZGVyU2VsZWN0LnNldCh0cnVlKTtcbiAgICAgICAgY29uc3QgYm9va0RhdGEgPSB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5nZXRCb29rKCk7XG4gICAgICAgIHRoaXMuYm9vay5zZXQoYm9va0RhdGEpO1xuICAgICAgICB0aGlzLmJvb2tJZC5zZXQoYm9va0RhdGE/LnJlY29yZHNbMF0/LmlkKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgXG4gICAgdGhpcy5mb3JtQnVpbGRlclNlcnZpY2Uuc2VsZWN0ZWRFbGVtZW50JC5zdWJzY3JpYmUoaW5kZXggPT4ge1xuICAgICAgdGhpcy5zZWxlY3RlZEVsZW1lbnRJbmRleC5zZXQoaW5kZXgpO1xuICAgICAgdGhpcy5oZWFkZXJTZWxlY3Quc2V0KGZhbHNlKTtcbiAgICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UuZ2V0RWxlbWVudHMoKTtcbiAgICAgICAgaWYgKCFlbGVtZW50cyB8fCAhQXJyYXkuaXNBcnJheShlbGVtZW50cykgfHwgaW5kZXggPj0gZWxlbWVudHMubGVuZ3RoKSB7XG4gICAgICAgICAgdGhpcy5zZWxlY3RlZEVsZW1lbnQuc2V0KG51bGwpOyAvLyBSZXNldCBzZWxlY3RlZEVsZW1lbnQgaWYgaW52YWxpZFxuICAgICAgICAgIHRoaXMuc2VsZWN0Q29sdW1uLnNldChudWxsKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZWxlbWVudCA9IHsgLi4uZWxlbWVudHNbaW5kZXhdIH07IC8vIFNhZmUgdG8gc3ByZWFkIHNpbmNlIHdlIGNoZWNrZWRcbiAgICAgICAgbGV0IGZpZWxkc01ldGEgPSBlbGVtZW50Py5maWVsZHNNZXRhO1xuICAgICAgICBpZiAoZWxlbWVudD8udHlwZSA9PT0gJ1RhYmxlJykge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBmaWVsZHNNZXRhID0gQXJyYXkuaXNBcnJheShmaWVsZHNNZXRhKVxuICAgICAgICAgICAgICA/IGZpZWxkc01ldGFcbiAgICAgICAgICAgICAgOiBKU09OLnBhcnNlKGZpZWxkc01ldGEgfHwgJ1tdJyk7XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgLy8gY29uc29sZS5lcnJvcignRXJyb3IgcGFyc2luZyBmaWVsZHNNZXRhOicsIGUpO1xuICAgICAgICAgICAgZmllbGRzTWV0YSA9IFtdO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLnNlbGVjdENvbHVtbi5zZXQodGhpcy5mb3JtQnVpbGRlclNlcnZpY2UuZ2V0U2VsZWN0VGFibGVDb2x1bW4oKSA/PyBudWxsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnNlbGVjdENvbHVtbi5zZXQobnVsbCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZWxlY3RlZEVsZW1lbnQuc2V0KHsgLi4uZWxlbWVudCwgZmllbGRzTWV0YSB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50LnNldChudWxsKTsgLy8gUmVzZXQgaWYgaW5kZXggaXMgaW52YWxpZFxuICAgICAgICB0aGlzLnNlbGVjdENvbHVtbi5zZXQobnVsbCk7XG4gICAgICB9XG4gICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5zZWxlY3RlZEVsZW1lbnQoKTtcbiAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgIGxldCBzdWJUZXh0ID0gZWxlbWVudC5zdWJUZXh0O1xuICAgICAgICBpZiAodHlwZW9mIHN1YlRleHQgPT09ICdzdHJpbmcnICYmIHN1YlRleHQudHJpbSgpICE9PSAnJykge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBzdWJUZXh0ID0gSlNPTi5wYXJzZShzdWJUZXh0KTtcbiAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBjb25zb2xlLmVycm9yKCdFcnJvciBwYXJzaW5nIHN1YlRleHQ6JywgZSk7XG4gICAgICAgICAgICBzdWJUZXh0ID0ge307XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBzdWJUZXh0ICE9PSAnb2JqZWN0JyB8fCBzdWJUZXh0ID09PSBudWxsKSB7XG4gICAgICAgICAgc3ViVGV4dCA9IHt9O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFycmF5RmllbGRzID0gWydmaWVsZCcsICdxdWVyeVBhcmFtZXRlcicsICdzb3VyY2VRdWVzdGlvbklkJywgJ3F1ZXJ5RmllbGQnLCAncXVlcnlWYWx1ZSddO1xuICAgICAgICBpZiAoc3ViVGV4dCkge1xuICAgICAgICAgIGFycmF5RmllbGRzLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHN1YlRleHRba2V5XSkpIHtcbiAgICAgICAgICAgICAgc3ViVGV4dFtrZXldID0gc3ViVGV4dFtrZXldLmpvaW4oJywgJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gICAgICAgIFxuICAgICAgICBpZihlbGVtZW50LnR5cGUgPT09ICdUYWJsZScpe1xuICAgICAgICAgIGVsZW1lbnQuZmllbGRzTWV0YS5mb3JFYWNoKGZpZWxkID0+IHtcbiAgICAgICAgICAgIGlmKGZpZWxkPy5xdWVzdGlvbj8uc3ViVGV4dCl7XG4gICAgICAgICAgICAgIGFycmF5RmllbGRzLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShmaWVsZC5xdWVzdGlvbi5zdWJUZXh0W2tleV0pKSB7XG4gICAgICAgICAgICAgICAgICBmaWVsZC5xdWVzdGlvbi5zdWJUZXh0W2tleV0gPSBmaWVsZC5xdWVzdGlvbi5zdWJUZXh0W2tleV0uam9pbignLCAnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50LnVwZGF0ZShlbCA9PiAoeyAuLi5lbCwgc3ViVGV4dCB9KSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgLy8gU0tTMjhKVUwyNSBmb3JtYnVpbGRlciBjdXJyZW50IGVsZW1lbnQgdHJhbnNsYXRpb24gdmFsdWUgdXBkYXRlIFxuICAgIHRoaXMudHJhbnNsYXRpb25TZXJ2aWNlLmZvcm1CdWlsZGVyVHJhbnNsYXRpb25zTG9hZGVkJC5zdWJzY3JpYmUoZXZlbnQgPT4ge1xuICAgICAgdGhpcy5mb3JtQnVpbGRlckxhbmd1YWdlQ29kZSA9IGV2ZW50XG4gICAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLmdldEVsZW1lbnRzKCk7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShlbGVtZW50cykgJiYgdGhpcy5zZWxlY3RlZEVsZW1lbnQoKSkge1xuICAgICAgICBjb25zdCBtYXRjaGVkRWxlbWVudCA9IGVsZW1lbnRzLmZpbmQoKGVsZTogYW55KSA9PiBlbGUuaWQgPT09IHRoaXMuc2VsZWN0ZWRFbGVtZW50KCkuaWQpO1xuICAgICAgICBpZiAobWF0Y2hlZEVsZW1lbnQpIHtcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkRWxlbWVudC5zZXQobWF0Y2hlZEVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9ICAgICAgXG4gICAgICBpZih0aGlzLnNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSBcIkhlYWRlclwiKXtcbiAgICAgICAgY29uc3QgYm9va0RhdGEgPSB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5nZXRCb29rKCk7XG4gICAgICAgIHRoaXMuYm9vay5zZXQoYm9va0RhdGEpO1xuICAgICAgICB0aGlzLnNlbGVjdGVkRWxlbWVudC5zZXQoey4uLnRoaXMuc2VsZWN0ZWRFbGVtZW50KCl9KVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUVsZW1lbnRQcm9wZXJ0aWVzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBIZWFkZXI6IHtcbiAgICAgICAgZWxlbWVudFByb3BzOiBbXG4gICAgICAgICAgeyBsYWJlbDogJ0xhYmVsJywgcGxhY2Vob2xkZXI6ICdFbnRlciBUZXh0JywgdHlwZTogJ3RleHQnLCBrZXk6ICd0aXRsZScsIGlzVHJhbnNsYXRlOiB0cnVlLCBsYWJlbFBhdGg6ICdMQUJFTCcgfVxuICAgICAgICBdLFxuICAgICAgfSxcbiAgICAgIExpbmU6IHtcbiAgICAgICAgZWxlbWVudFByb3BzOiBbXG4gICAgICAgICAgeyBsYWJlbDogJ0xpbmUgV2lkdGgnLCB0eXBlOiAnZmllbGRTaXplJywga2V5OiAnc2l6ZScsIGxhYmVsUGF0aDogJ0xJTkVfV0lEVEgnIH0sXG4gICAgICAgICAgeyBsYWJlbDogJ1BhZGRpbmcgVG9wJywgdHlwZTogJ251bWJlcicsIGtleTogJ3BhZGRpbmdUb3AnLCBwbGFjZWhvbGRlcjogJ0VudGVyIHBhZGRpbmcgdG9wJywgbGFiZWxQYXRoOiAnUEFERElOR19UT1AnIH0sXG4gICAgICAgICAgeyBsYWJlbDogJ1BhZGRpbmcgQm90dG9tJywgdHlwZTogJ251bWJlcicsIGtleTogJ3BhZGRpbmdCb3R0b20nLCBwbGFjZWhvbGRlcjogJ0VudGVyIHBhZGRpbmcgYm90dG9tJywgbGFiZWxQYXRoOiAnUEFERElOR19CT1RUT00nIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbGFiZWw6ICdMaW5lIFN0eWxlJywgdHlwZTogJ3NlbGVjdCcsIGtleTogJ2xpbmVTdHlsZScsIGxhYmVsUGF0aDogJ0xJTkVfU1RZTEUnLFxuICAgICAgICAgICAgb3B0aW9uczogW1xuICAgICAgICAgICAgICB7IGxhYmVsOiAnU29saWQnLCB2YWx1ZTogJ1NvbGlkJywgbGFiZWxQYXRoOiAnU09MSUQnIH0sXG4gICAgICAgICAgICAgIHsgbGFiZWw6ICdEYXNoZWQnLCB2YWx1ZTogJ0Rhc2hlZCcsIGxhYmVsUGF0aDogJ0RBU0hFRCcgfSxcbiAgICAgICAgICAgICAgeyBsYWJlbDogJ0RvdHRlZCcsIHZhbHVlOiAnRG90dGVkJywgbGFiZWxQYXRoOiAnRE9UVEVEJyB9XG4gICAgICAgICAgICBdXG4gICAgICAgICAgfVxuICAgICAgICBdLFxuICAgICAgICBmaWVsZFByb3BzOiBbXVxuICAgICAgfSxcbiAgICAgIFNwYWNlOiB7XG4gICAgICAgIGVsZW1lbnRQcm9wczogW1xuICAgICAgICAgIHsgbGFiZWw6ICdFbGVtZW50JywgdHlwZTogJ251bWJlcicsIGtleTogJ3F1ZXN0aW9uTnVtYmVyJywgbGFiZWxQYXRoOiAnRUxFTUVOVCcgfSxcbiAgICAgICAgICB7IGxhYmVsOiAnRmllbGQgU2l6ZScsIHR5cGU6ICdmaWVsZFNpemUnLCBrZXk6ICdzaXplJywgbGFiZWxQYXRoOiAnRklFTERfU0laRScgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZmllbGRQcm9wczogW11cbiAgICAgIH0sXG4gICAgICBUYWJsZToge1xuICAgICAgICBlbGVtZW50UHJvcHM6IFtcbiAgICAgICAgICB7IGxhYmVsOiAnSXMgTGFiZWwnLCBwbGFjZWhvbGRlcjogJ0VudGVyIFRleHQnLCB0eXBlOiAnY2hlY2tib3gnLCBrZXk6ICdzdHlsZS5zaG93TGFiZWwnLCBsYWJlbFBhdGg6ICdJU19MQUJFTCcgfSxcbiAgICAgICAgICB7IGxhYmVsOiAncHJpbWFyeUtleScsIHBsYWNlaG9sZGVyOiAnRW50ZXIgVGV4dCcsIHR5cGU6ICdjaGVja2JveCcsIGtleTogJ3ByaW1hcnlLZXknLCBsYWJlbFBhdGg6ICdQUklNQVJZX0tFWScgfSxcbiAgICAgICAgICB7IGxhYmVsOiAndGFibGVOYW1lJywgcGxhY2Vob2xkZXI6ICdFbnRlciBoZXJlJywgdHlwZTogJ3RleHQnLCBrZXk6ICdxdWVzdGlvblRleHQnLCBpc1RyYW5zbGF0ZTogdHJ1ZSwgbGFiZWxQYXRoOiAnVEFCTEVfTkFNRScgfSxcbiAgICAgICAgICB7IGxhYmVsOiAnaW5wdXRUZXh0QWxpZ25tZW50JywgcGxhY2Vob2xkZXI6ICdMZWZ0JywgdHlwZTogJ3RleHQnLCBrZXk6ICdpbnB1dFRleHRBbGlnbm1lbnQnLCBsYWJlbFBhdGg6ICdJTlBVVF9URVhUX0FMSUdOTUVOVCcgfSxcbiAgICAgICAgICB7IGxhYmVsOiAndGFibGVTY2FsZVNpemUnLCBwbGFjZWhvbGRlcjogJzA2IC0gRnVsbCBTY2FsZScsIHR5cGU6ICd0ZXh0Jywga2V5OiAndGFibGVTY2FsZVNpemUnLCBsYWJlbFBhdGg6ICdUQUJMRV9TQ0FMRV9TSVpFJyB9LFxuICAgICAgICAgIHsgbGFiZWw6ICdpc05vc0luZGljYXRvcicsIHBsYWNlaG9sZGVyOiAnMDYgLSBGdWxsIFNjYWxlJywgdHlwZTogJ2NoZWNrYm94Jywga2V5OiAndGFibGVDb25maWcuaXNOb3NJbmRpY2F0b3InLCBsYWJlbFBhdGg6ICdJU19OT1NfSU5ESUNBVE9SJyB9LFxuICAgICAgICAgIHsgbGFiZWw6ICdpc1BhZ2luYXRpb24nLCBwbGFjZWhvbGRlcjogJzA2IC0gRnVsbCBTY2FsZScsIHR5cGU6ICdjaGVja2JveCcsIGtleTogJ3RhYmxlQ29uZmlnLmlzUGFnaW5hdGlvbicsIGxhYmVsUGF0aDogJ0lTX1BBR0lOQVRJT04nIH0sXG4gICAgICAgICAgeyBsYWJlbDogJ2FkZElubGluZVJlY29yZCcsIHBsYWNlaG9sZGVyOiAnMDYgLSBGdWxsIFNjYWxlJywgdHlwZTogJ2NoZWNrYm94Jywga2V5OiAndGFibGVDb25maWcuYWRkSW5saW5lUmVjb3JkJywgbGFiZWxQYXRoOiAnQUREX0lOTElORV9SRUNPUkQnIH0sXG4gICAgICAgICAgeyBsYWJlbDogJ2FjdGlvbkJ1dHRvbicsIHBsYWNlaG9sZGVyOiAnMDYgLSBGdWxsIFNjYWxlJywgdHlwZTogJ2NoZWNrYm94Jywga2V5OiAndGFibGVDb25maWcuYWN0aW9uQnV0dG9uJywgbGFiZWxQYXRoOiAnQUNUSU9OX0JVVFRPTicgfSxcbiAgICAgICAgICB7IGxhYmVsOiAnc2VhcmNoQmFyJywgcGxhY2Vob2xkZXI6ICcwNiAtIEZ1bGwgU2NhbGUnLCB0eXBlOiAnY2hlY2tib3gnLCBrZXk6ICd0YWJsZUNvbmZpZy5zZWFyY2hCYXInLCBsYWJlbFBhdGg6ICdTRUFSQ0hfQkFSJyB9LFxuICAgICAgICAgIHsgbGFiZWw6ICdpc0RlbGV0ZVJvdycsIHBsYWNlaG9sZGVyOiAnMDYgLSBGdWxsIFNjYWxlJywgdHlwZTogJ2NoZWNrYm94Jywga2V5OiAndGFibGVDb25maWcuaXNEZWxldGVSb3cnLCBsYWJlbFBhdGg6ICdJU19ERUxFVEVfUk9XJyB9LFxuICAgICAgICAgIHsgbGFiZWw6ICdpc0VkaXRSb3cnLCBwbGFjZWhvbGRlcjogJzA2IC0gRnVsbCBTY2FsZScsIHR5cGU6ICdjaGVja2JveCcsIGtleTogJ3RhYmxlQ29uZmlnLmlzRWRpdFJvdycsIGxhYmVsUGF0aDogJ0lTX0VESVRfUk9XJyB9LFxuICAgICAgICAgIHsgbGFiZWw6ICdpc0J1dHRvbnMnLCBwbGFjZWhvbGRlcjogJzA2IC0gRnVsbCBTY2FsZScsIHR5cGU6ICdjaGVja2JveCcsIGtleTogJ3RhYmxlQ29uZmlnLmlzQnV0dG9ucycsIGxhYmVsUGF0aDogJ0lTX0JVVFRPTlMnIH0sXG4gICAgICAgICAgeyBsYWJlbDogJ3Jvd0Nob2ljZScsIHBsYWNlaG9sZGVyOiAnJywgdHlwZTogJ3RleHQnLCBrZXk6ICdyb3dDaG9pY2UnLCBsYWJlbFBhdGg6ICdST1dfQ0hPSUNFJyB9LFxuICAgICAgICAgIHsgbGFiZWw6ICdxdWVzdGlvbk51bWJlcicsIHR5cGU6ICdudW1iZXInLCBrZXk6ICdxdWVzdGlvbk51bWJlcicsIGxhYmVsUGF0aDogJ1FVRVNUSU9OX05VTUJFUicgfSxcbiAgICAgICAgICB7IGxhYmVsOiAnRmllbGQgU2l6ZScsIHR5cGU6ICdmaWVsZFNpemUnLCBrZXk6ICdzaXplJywgbGFiZWxQYXRoOiAnRklFTERfU0laRScgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZmllbGRQcm9wczogW1xuICAgICAgICAgIHsgbGFiZWw6ICd0YWJsZUlkJywgcGxhY2Vob2xkZXI6ICdFbXBfVGFibGVfMDEnLCB0eXBlOiAndGV4dCcsIGtleTogJ3RhYmxlSWQnLCBpc1RyYW5zbGF0ZTogdHJ1ZSwgbGFiZWxQYXRoOiAnVEFCTEVfSUQnIH0sXG4gICAgICAgICAgeyBsYWJlbDogJ2hlbHBUZXh0JywgcGxhY2Vob2xkZXI6ICdFbnRlciBtZXNzYWdlJywgdHlwZTogJ3RleHQnLCBrZXk6ICdoZWxwVGV4dCcsIGlzVHJhbnNsYXRlOiB0cnVlLCBsYWJlbFBhdGg6ICdIRUxQX1RFWFQnIH0sXG4gICAgICAgICAgeyBsYWJlbDogJ2RlZmF1bHRWYWx1ZScsIHBsYWNlaG9sZGVyOiAnRGVmYXVsdCBWYWx1ZScsIHR5cGU6ICd0ZXh0Jywga2V5OiAnZGVmYXVsdFZhbHVlJywgbGFiZWxQYXRoOiAnREVGQVVMVF9WQUxVRScgfSxcbiAgICAgICAgICB7IGxhYmVsOiAnUmVmZXJlbmNlJywgcGxhY2Vob2xkZXI6ICdSZWZlcmVuY2UgRmllbGQnLCB0eXBlOiAndGV4dCcsIGtleTogJ3JlZmVyZW5jZUZpZWxkJywgbGFiZWxQYXRoOiAnUkVGRVJFTkNFX0ZJRUxEJyB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGxhYmVsOiAnU3ViIFRleHQnLCBwbGFjZWhvbGRlcjogJ0VudGVyIFRleHQnLCB0eXBlOiAnc3ViUXVlc3Rpb24nLCBrZXk6ICdpc1N1YlRleHQnLCBsYWJlbFBhdGg6ICdTVUJfVEVYVCcsXG4gICAgICAgICAgICBzdWJRdWVzdGlvbjogW1xuICAgICAgICAgICAgICB7IGxhYmVsOiAnRW5kIFBvaW50JywgcGxhY2Vob2xkZXI6ICdlbmRwb2ludCcsIHR5cGU6ICd0ZXh0Jywga2V5OiAnc3ViVGV4dC5lbmRwb2ludCcsIGxhYmVsUGF0aDogJ0VORF9QT0lOVCcgfSxcbiAgICAgICAgICAgICAgeyBsYWJlbDogJ1ZhcmlhYmxlJywgcGxhY2Vob2xkZXI6ICd2YXJpYWJsZScsIHR5cGU6ICd0ZXh0Jywga2V5OiAnc3ViVGV4dC52YXJpYWJsZScsIGxhYmVsUGF0aDogJ1ZBUklBQkxFJyB9LFxuICAgICAgICAgICAgICB7IGxhYmVsOiAnRmllbGQnLCBwbGFjZWhvbGRlcjogJ2ZpZWxkJywgdHlwZTogJ3RleHQnLCBrZXk6ICdzdWJUZXh0LmZpZWxkJywgbGFiZWxQYXRoOiAnRklFTEQnIH0sXG4gICAgICAgICAgICAgIHsgbGFiZWw6ICdRdWVyeSBQYXJhbWV0ZXInLCBwbGFjZWhvbGRlcjogJ3F1ZXJ5UGFyYW1ldGVyJywgdHlwZTogJ3RleHQnLCBrZXk6ICdzdWJUZXh0LnF1ZXJ5UGFyYW1ldGVyJywgbGFiZWxQYXRoOiAnUVVFUllfUEFSQU1FVEVSJyB9LFxuICAgICAgICAgICAgICB7IGxhYmVsOiAnRGVmYXVsdCBGaWVsZCcsIHBsYWNlaG9sZGVyOiAnZGVmYXVsdEZpZWxkJywgdHlwZTogJ3RleHQnLCBrZXk6ICdzdWJUZXh0LmRlZmF1bHRGaWVsZCcsIGxhYmVsUGF0aDogJ0RFRkFVTFRfRklFTEQnIH0sXG4gICAgICAgICAgICAgIHsgbGFiZWw6ICdMYWJlbCBGaWVsZCcsIHBsYWNlaG9sZGVyOiAnbGFiZWxGaWVsZCcsIHR5cGU6ICd0ZXh0Jywga2V5OiAnc3ViVGV4dC5sYWJlbEZpZWxkJywgbGFiZWxQYXRoOiAnTEFCRUxfRklFTEQnIH0sXG4gICAgICAgICAgICAgIHsgbGFiZWw6ICdWYWx1ZSBGaWVsZCcsIHBsYWNlaG9sZGVyOiAndmFsdWVGaWVsZCcsIHR5cGU6ICd0ZXh0Jywga2V5OiAnc3ViVGV4dC52YWx1ZUZpZWxkJywgbGFiZWxQYXRoOiAnVkFMVUVfRklFTEQnIH0sXG4gICAgICAgICAgICAgIHsgbGFiZWw6ICdTb3VyY2UgUXVlc3Rpb24gSWQnLCBwbGFjZWhvbGRlcjogJ3NvdXJjZVF1ZXN0aW9uSWQnLCB0eXBlOiAndGV4dCcsIGtleTogJ3N1YlRleHQuc291cmNlUXVlc3Rpb25JZCcsIGxhYmVsUGF0aDogJ1NPVVJDRV9RVUVTVElPTl9JRCcgfSxcbiAgICAgICAgICAgICAgeyBsYWJlbDogJ0RlcGVuZGVudCBWYWx1ZScsIHBsYWNlaG9sZGVyOiAnZGVwZW5kZW50VmFsdWUnLCB0eXBlOiAndGV4dCcsIGtleTogJ3N1YlRleHQuZGVwZW5kZW50VmFsdWUnLCBsYWJlbFBhdGg6ICdERVBFTkRFTlRfVkFMVUUnIH0sXG4gICAgICAgICAgICAgIHsgbGFiZWw6ICdEZXBlbmRlbnQgRmllbGQnLCBwbGFjZWhvbGRlcjogJ2lzRGVwZW5kZW50RmllbGQnLCB0eXBlOiAnYm9vbGVhbicsIGtleTogJ3N1YlRleHQuaXNEZXBlbmRlbnRGaWVsZCcsIGxhYmVsUGF0aDogJ0RFUEVOREVOVF9GSUVMRCcgfSxcbiAgICAgICAgICAgICAgeyBsYWJlbDogJ1F1ZXJ5IEZpZWxkJywgcGxhY2Vob2xkZXI6ICdxdWVyeUZpZWxkJywgdHlwZTogJ3RleHQnLCBrZXk6ICdzdWJUZXh0LnF1ZXJ5RmllbGQnLCBsYWJlbFBhdGg6ICdRVUVSWV9GSUVMRCcgfSxcbiAgICAgICAgICAgICAgeyBsYWJlbDogJ1F1ZXJ5IFZhbHVlJywgcGxhY2Vob2xkZXI6ICdxdWVyeVZhbHVlJywgdHlwZTogJ3RleHQnLCBrZXk6ICdzdWJUZXh0LnF1ZXJ5VmFsdWUnLCBsYWJlbFBhdGg6ICdRVUVSWV9WQUxVRScgfSxcbiAgICAgICAgICAgICAgeyBsYWJlbDogJ1F1ZXJ5IFZhbHVlIFJlZicsIHBsYWNlaG9sZGVyOiAncXVlcnlWYWx1ZVJlZicsIHR5cGU6ICd0ZXh0Jywga2V5OiAnc3ViVGV4dC5xdWVyeVZhbHVlUmVmZXJlbmNlJywgbGFiZWxQYXRoOiAnUVVFUllfVkFMVUVfUkVGJyB9LFxuICAgICAgICAgICAgICB7IGxhYmVsOiAnVW5pcXVlIEtleScsIHBsYWNlaG9sZGVyOiAndW5pcXVlS2V5JywgdHlwZTogJ3RleHQnLCBrZXk6ICdzdWJUZXh0LnVuaXF1ZUtleScsIGxhYmVsUGF0aDogJ1VOSVFVRV9LRVknIH0sXG4gICAgICAgICAgICBdXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgYXBwZWFyYW5jZTogW1xuICAgICAgICAgIHsgbGFiZWw6ICdTZWxlY3QgRm9udCcsIHR5cGU6ICdzZWxlY3QnLCBrZXk6ICdmb250JywgcGxhY2Vob2xkZXI6ICdMZWZ0JywgcmVxdWlyZWQ6IHRydWUsIGxhYmVsUGF0aDogJ1NFTEVDVF9GT05UJywgb3B0aW9uczogW1xuICAgICAgICAgICAgeyBsYWJlbDogJ0hlbHZldGljYSBOZXVlJywgdmFsdWU6ICdIZWx2ZXRpY2EgTmV1ZScsIGxhYmVsUGF0aDogJ0hFTFZFVElDQV9ORVVFJyB9LFxuICAgICAgICAgICAgeyBsYWJlbDogJ0FyaWFsJywgdmFsdWU6ICdBcmlhbCcsIGxhYmVsUGF0aDogJ0FSSUFMJyB9LFxuICAgICAgICAgICAgeyBsYWJlbDogJ1RpbWVzIE5ldyBSb21hbicsIHZhbHVlOiAnVGltZXMgTmV3IFJvbWFuJywgbGFiZWxQYXRoOiAnVElNRVNfTkVXX1JPTUFOJyB9LFxuICAgICAgICAgICAgeyBsYWJlbDogJ1JvYm90bycsIHZhbHVlOiAnUm9ib3RvJywgbGFiZWxQYXRoOiAnUk9CT1RPJyB9XG4gICAgICAgICAgXX0sXG4gICAgICAgICAgeyBsYWJlbDogJ0ZvbnQgQ29sb3InLCB0eXBlOiAnY29sb3InLCBrZXk6ICdmb250Q29sb3InLCBkZWZhdWx0VmFsdWU6ICcnLCByZXF1aXJlZDogdHJ1ZSwgbGFiZWxQYXRoOiAnRk9OVF9DT0xPUicgfSxcbiAgICAgICAgICB7IGxhYmVsOiAnRm9udCBTaXplJywgdHlwZTogJ3NlbGVjdCcsIGtleTogJ2ZvbnRTaXplJywgZGVmYXVsdFZhbHVlOiAnJywgcmVxdWlyZWQ6IHRydWUsIGxhYmVsUGF0aDogJ0ZPTlRfU0laRScsIG9wdGlvbnM6IFtcbiAgICAgICAgICAgIHsgbGFiZWw6ICdTbWFsbCcsIHZhbHVlOiAnMTJweCcsIGxhYmVsUGF0aDogJ1NNQUxMJyB9LFxuICAgICAgICAgICAgeyBsYWJlbDogJ01lZGl1bScsIHZhbHVlOiAnMTRweCcsIGxhYmVsUGF0aDogJ01FRElVTScgfSxcbiAgICAgICAgICAgIHsgbGFiZWw6ICdMYXJnZScsIHZhbHVlOiAnMTZweCcsIGxhYmVsUGF0aDogJ0xBUkdFJyB9XG4gICAgICAgICAgXX0sXG4gICAgICAgICAgeyBsYWJlbDogJ0ZvbnQgV2lkdGgnLCB0eXBlOiAnc2VsZWN0Jywga2V5OiAnZm9udFdlaWdodCcsIGRlZmF1bHRWYWx1ZTogJycsIHJlcXVpcmVkOiB0cnVlLCBsYWJlbFBhdGg6ICdGT05UX1dJRFRIJywgb3B0aW9uczogW1xuICAgICAgICAgICAgeyB2YWx1ZTogJzQwMCcsIGxhYmVsOiAnNDAwLU5vcm1hbCcsIGxhYmVsUGF0aDogJzQwMF9OT1JNQUwnIH0sXG4gICAgICAgICAgICB7IHZhbHVlOiAnNTAwJywgbGFiZWw6ICc1MDAtTWVkaXVtJywgbGFiZWxQYXRoOiAnNTAwX01FRElVTScgfSxcbiAgICAgICAgICAgIHsgdmFsdWU6ICc2MDAnLCBsYWJlbDogJzYwMC1TZW1pIEJvbGQnLCBsYWJlbFBhdGg6ICc2MDBfU0VNSV9CT0xEJyB9LFxuICAgICAgICAgICAgeyB2YWx1ZTogJzcwMCcsIGxhYmVsOiAnNzAwLUJvbGQnLCBsYWJlbFBhdGg6ICc3MDBfQk9MRCcgfVxuICAgICAgICAgIF19LFxuICAgICAgICAgIHsgbGFiZWw6ICdEdXBsaWNhdGUgRmllbGQnLCB0eXBlOiAnYnV0dG9uLXRvZ2dsZScsIGtleTogJ2R1cGxpY2F0ZUZpZWxkJywgZGVmYXVsdFZhbHVlOiBmYWxzZSwgbGFiZWxQYXRoOiAnRFVQTElDQVRFX0ZJRUxEJyB9XG4gICAgICAgIF1cbiAgICAgIH0sXG4gICAgICBUYWJsZUNvbHVtbjoge1xuICAgICAgICBlbGVtZW50UHJvcHM6IFtcbiAgICAgICAgICB7IGxhYmVsOiAnVHlwZScsIHBsYWNlaG9sZGVyOiAnVGV4dCcsIHR5cGU6ICdzZWxlY3QnLCB0YXJnZXRBcnJheTogJ2ZpZWxkc01ldGEnLCB0YXJnZXRBcnJheUtleTogJ3VuaXF1ZUlkZW50aWZpZXInLCBrZXk6ICdmbGRUeXBlJywgcmVxdWlyZWQ6IHRydWUsIGxhYmVsUGF0aDogJ1RZUEUnLCBvcHRpb25zOiB0aGlzLmVsZW1lbnRUeXBlLm1hcChmID0+ICh7IGxhYmVsOiBmLCB2YWx1ZTogZiwgbGFiZWxQYXRoOiBmLnRvVXBwZXJDYXNlKCkgfSkpfSxcbiAgICAgICAgICB7IGxhYmVsOiAnaGVhZGVyTGFiZWxzJywgcGxhY2Vob2xkZXI6ICdFbnRlciBoZXJlJywgdHlwZTogJ3RleHQnLCB0YXJnZXRBcnJheTogJ2ZpZWxkc01ldGEnLCB0YXJnZXRBcnJheUtleTogJ3VuaXF1ZUlkZW50aWZpZXInLCBrZXk6ICdsYWJlbCcsIGlzVHJhbnNsYXRlOiB0cnVlLCBsYWJlbFBhdGg6ICdIRUFERVJfTEFCRUxTJyB9LFxuICAgICAgICAgIHsgbGFiZWw6ICdhcGlOYW1lJywgcGxhY2Vob2xkZXI6ICdFbnRlciBoZXJlJywgdHlwZTogJ3RleHQnLCB0YXJnZXRBcnJheTogJ2ZpZWxkc01ldGEnLCB0YXJnZXRBcnJheUtleTogJ3VuaXF1ZUlkZW50aWZpZXInLCBrZXk6ICdhcGlOYW1lJywgbGFiZWxQYXRoOiAnQVBJX05BTUUnIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbGFiZWw6ICdTdW1tYXJ5IENvbHVtbicsIHBsYWNlaG9sZGVyOiAnU3VtbWFyeSBDb2x1bW4nLCB0eXBlOiAnc3ViUXVlc3Rpb24nLCB0YXJnZXRBcnJheTogJ2ZpZWxkc01ldGEnLCB0YXJnZXRBcnJheUtleTogJ3VuaXF1ZUlkZW50aWZpZXInLCBrZXk6ICdzdW1tYXJ5Q29sdW1uJywgbGFiZWxQYXRoOiAnU1VNTUFSWV9DT0xVTU4nLFxuICAgICAgICAgICAgc3ViUXVlc3Rpb246IFtcbiAgICAgICAgICAgICAgeyBsYWJlbDogJ1R5cGUnLCBwbGFjZWhvbGRlcjogJ0VudGVyIGhlcmUnLCB0eXBlOiAndGV4dCcsIHRhcmdldEFycmF5OiAnZmllbGRzTWV0YScsIHRhcmdldEFycmF5S2V5OiAndW5pcXVlSWRlbnRpZmllcicsIGtleTogJ2ZsZFR5cGUnLCBsYWJlbFBhdGg6ICdUWVBFJyB9LFxuICAgICAgICAgICAgICB7IGxhYmVsOiAnT3BlcmF0aW9uJywgcGxhY2Vob2xkZXI6ICdFbnRlciBoZXJlJywgdHlwZTogJ3RleHQnLCB0YXJnZXRBcnJheTogJ2ZpZWxkc01ldGEnLCB0YXJnZXRBcnJheUtleTogJ3VuaXF1ZUlkZW50aWZpZXInLCBrZXk6ICdvcGVyYXRpb24nLCBsYWJlbFBhdGg6ICdPUEVSQVRJT04nIH0sXG4gICAgICAgICAgICAgIHsgbGFiZWw6ICdPcGVyYW5kcycsIHBsYWNlaG9sZGVyOiAnRW50ZXIgaGVyZScsIHR5cGU6ICdhcnJheScsIHRhcmdldEFycmF5OiAnZmllbGRzTWV0YScsIHRhcmdldEFycmF5S2V5OiAndW5pcXVlSWRlbnRpZmllcicsIGtleTogJ29wZXJhbmRzJywgbGFiZWxQYXRoOiAnT1BFUkFORFMnIH0sXG4gICAgICAgICAgICBdXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBsYWJlbDogJ1N1bW1hcnkgUm93JywgcGxhY2Vob2xkZXI6ICdTdW1tYXJ5IFJvdycsIHR5cGU6ICdzdWJRdWVzdGlvbicsIHRhcmdldEFycmF5OiAnZmllbGRzTWV0YScsIHRhcmdldEFycmF5S2V5OiAndW5pcXVlSWRlbnRpZmllcicsIGtleTogJ3N1bW1hcnlSb3cnLCBsYWJlbFBhdGg6ICdTVU1NQVJZX1JPVycsXG4gICAgICAgICAgICBzdWJRdWVzdGlvbjogW1xuICAgICAgICAgICAgICB7IGxhYmVsOiAnVHlwZScsIHBsYWNlaG9sZGVyOiAnRW50ZXIgaGVyZScsIHR5cGU6ICd0ZXh0JywgdGFyZ2V0QXJyYXk6ICdmaWVsZHNNZXRhJywgdGFyZ2V0QXJyYXlLZXk6ICd1bmlxdWVJZGVudGlmaWVyJywga2V5OiAnZmxkVHlwZScsIGxhYmVsUGF0aDogJ1RZUEUnIH0sXG4gICAgICAgICAgICAgIHsgbGFiZWw6ICdvcGVyYXRpb24nLCBwbGFjZWhvbGRlcjogJ29wZXJhdGlvbicsIHR5cGU6ICd0ZXh0JywgdGFyZ2V0QXJyYXk6ICdmaWVsZHNNZXRhJywgdGFyZ2V0QXJyYXlLZXk6ICd1bmlxdWVJZGVudGlmaWVyJywga2V5OiAnb3BlcmF0aW9uJywgbGFiZWxQYXRoOiAnT1BFUkFUSU9OJyB9LFxuICAgICAgICAgICAgICB7IGxhYmVsOiAnY29sdW1uJywgcGxhY2Vob2xkZXI6ICdFbnRlciBoZXJlJywgdHlwZTogJ3JhZGlvJywgdGFyZ2V0QXJyYXk6ICdmaWVsZHNNZXRhJywgdGFyZ2V0QXJyYXlLZXk6ICd1bmlxdWVJZGVudGlmaWVyJywga2V5OiAnY29sdW1uJywgbGFiZWxQYXRoOiAnQ09MVU1OJyB9LFxuICAgICAgICAgICAgICB7IGxhYmVsOiAnY29sdW1ucycsIHBsYWNlaG9sZGVyOiAnRW50ZXIgaGVyZScsIHR5cGU6ICdhcnJheScsIHRhcmdldEFycmF5OiAnZmllbGRzTWV0YScsIHRhcmdldEFycmF5S2V5OiAndW5pcXVlSWRlbnRpZmllcicsIGtleTogJ2NvbHVtbnMnLCBsYWJlbFBhdGg6ICdDT0xVTU5TJyB9LFxuICAgICAgICAgICAgICB7IGxhYmVsOiAnb3BlcmFuZHMnLCBwbGFjZWhvbGRlcjogJ0VudGVyIGhlcmUnLCB0eXBlOiAnYXJyYXknLCB0YXJnZXRBcnJheTogJ2ZpZWxkc01ldGEnLCB0YXJnZXRBcnJheUtleTogJ3VuaXF1ZUlkZW50aWZpZXInLCBrZXk6ICdvcGVyYW5kcycsIGxhYmVsUGF0aDogJ09QRVJBTkRTJyB9LFxuICAgICAgICAgICAgXVxuICAgICAgICAgIH0sXG4gICAgICAgICAgeyBsYWJlbDogJ3RleHRBbGlnbm1lbnQnLCBwbGFjZWhvbGRlcjogJ0xlZnQnLCB0eXBlOiAndGV4dCcsIHRhcmdldEFycmF5OiAnZmllbGRzTWV0YScsIHRhcmdldEFycmF5S2V5OiAndW5pcXVlSWRlbnRpZmllcicsIGtleTogJ3RleHRBbGlnbm1lbnQnLCBsYWJlbFBhdGg6ICdURVhUX0FMSUdOTUVOVCcgfSxcbiAgICAgICAgICB7IGxhYmVsOiAnY29sdW1uU2NhbGVTaXplJywgcGxhY2Vob2xkZXI6ICcwNiAtIEZ1bGwgU2NhbGUnLCB0eXBlOiAndGV4dCcsIHRhcmdldEFycmF5OiAnZmllbGRzTWV0YScsIHRhcmdldEFycmF5S2V5OiAndW5pcXVlSWRlbnRpZmllcicsIGtleTogJ2NvbHVtblNjYWxlU2l6ZScsIGxhYmVsUGF0aDogJ0NPTFVNTl9TQ0FMRV9TSVpFJyB9LFxuICAgICAgICBdLFxuICAgICAgICBmaWVsZFByb3BzOiBbXSxcbiAgICAgICAgYXBwZWFyYW5jZTogW11cbiAgICAgIH0sXG4gICAgICBDaGVja2JveDogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKHsgY3VzdG9tRmllbGRQcm9wczogQ09NTU9OX09QVElPTlNfRklFTEQubWFwKG9wdCA9PiAoeyAuLi5vcHQsIHR5cGU6ICdjaGVja2JveCcgfSkpIH0pLFxuICAgICAgRHJvcGRvd246IHRoaXMuY3JlYXRlRWxlbWVudENvbmZpZyh7IGN1c3RvbUZpZWxkUHJvcHM6IENPTU1PTl9PUFRJT05TX0ZJRUxELm1hcChvcHQgPT4gKHsgLi4ub3B0LCB0eXBlOiAnZHJvcGRvd24nIH0pKSB9KSxcbiAgICAgIFJhZGlvOiB0aGlzLmNyZWF0ZUVsZW1lbnRDb25maWcoeyBjdXN0b21GaWVsZFByb3BzOiBDT01NT05fT1BUSU9OU19GSUVMRC5tYXAob3B0ID0+ICh7IC4uLm9wdCwgdHlwZTogJ2NoZWNrYm94JyB9KSkgfSksXG4gICAgICBUZXh0OiB0aGlzLmNyZWF0ZUVsZW1lbnRDb25maWcoKSxcbiAgICAgIENhbGVuZGFyOiB0aGlzLmNyZWF0ZUVsZW1lbnRDb25maWcoKSxcbiAgICAgIERhdGU6IHRoaXMuY3JlYXRlRWxlbWVudENvbmZpZygpLFxuICAgICAgVGltZTogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKCksXG4gICAgICBEYXRlVGltZTogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKCksXG4gICAgICBFbWFpbDogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKCksXG4gICAgICBCb29rOiB0aGlzLmNyZWF0ZUVsZW1lbnRDb25maWcoKSxcbiAgICAgIExpc3Q6IHRoaXMuY3JlYXRlRWxlbWVudENvbmZpZygpLFxuICAgICAgVGV4dEFyZWE6IHRoaXMuY3JlYXRlRWxlbWVudENvbmZpZygpLFxuICAgICAgUmljaFRleHRBcmVhOiB0aGlzLmNyZWF0ZUVsZW1lbnRDb25maWcoKSxcbiAgICAgIE51bWJlcjogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKCksXG4gICAgICBJbWFnZTogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKCksXG4gICAgICBMYWJlbDogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKCksXG4gICAgICBCb29sZWFuOiB0aGlzLmNyZWF0ZUVsZW1lbnRDb25maWcoKSxcbiAgICAgIEZpbGU6IHRoaXMuY3JlYXRlRWxlbWVudENvbmZpZygpLFxuICAgICAgSWNvbjogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKCksIC8vTVNNMTBKVUwyNSBpY29uIHNlbGVjdG9yIGVsZW1lbnRcbiAgICAgIEJ1dHRvbjogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKCksXG4gICAgfTtcbiAgfVxuXG4gIGNyZWF0ZUVsZW1lbnRDb25maWcoY29uZmlnPzogeyBjdXN0b21FbGVtZW50UHJvcHM/OiBhbnlbXSwgY3VzdG9tRmllbGRQcm9wcz86IGFueVtdLCBjdXN0b21BcHBlYXJhbmNlUHJvcHM/OiBhbnlbXSB9KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGVsZW1lbnRQcm9wczogWy4uLkNPTU1PTl9FTEVNRU5UX1BST1BTLCAuLi4oY29uZmlnPy5jdXN0b21FbGVtZW50UHJvcHMgfHwgW10pXSxcbiAgICAgIGZpZWxkUHJvcHM6IFsuLi5DT01NT05fRklFTERfUFJPUFMsIC4uLihjb25maWc/LmN1c3RvbUZpZWxkUHJvcHMgfHwgW10pXSxcbiAgICAgIGFwcGVhcmFuY2U6IFsuLi5DT01NT05fQVBQRUFSQU5DRV9QUk9QUywgLi4uKGNvbmZpZz8uY3VzdG9tQXBwZWFyYW5jZVByb3BzIHx8IFtdKV1cbiAgICB9O1xuICB9XG4gIC8vIEFQIDIzTUFZMjUgLSBBZGQgYSBuZXcgYnV0dG9uIHdpdGggZGVmYXVsdCBzdHlsaW5nXG4gIGFkZE5ld0J1dHRvbigpIHtcbiAgICBjb25zdCBsYXN0UGVyY2VudCA9IHRoaXMuYm9vaygpPy5xdWVzdGlvbmJvb2s/LmFjdGlvbj8uc2xpY2UoLTEpWzBdPy5wb3NpdGlvblBlcmNlbnQgPz8gMDtcbiAgICBjb25zdCBidXR0b25zID0ge1xuICAgICAgbmFtZTogJycsXG4gICAgICBldmVudHRvZW1pdDogJycsXG4gICAgICBhbHQ6ICcnLFxuICAgICAgZW5kcG9pbnQ6ICcnLFxuICAgICAgbWV0aG9kOiAnJyxcbiAgICAgIGlkOiB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5hZGRFbGVtZW50V2l0aElkKCksXG4gICAgICBwb3NpdGlvblBlcmNlbnQ6IGxhc3RQZXJjZW50ICsgMTAsXG4gICAgICB3aWR0aDogMTAwLFxuICAgICAgYm9yZGVyUmFkaXVzOiA2LFxuICAgICAgYWxpZ25tZW50OiAnZmxleC1zdGFydCdcbiAgICB9O1xuICAgIHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLnVwZGF0ZVF1ZXN0aW9uQm9va0FjdGlvbkJ1dHRvbnMoYnV0dG9ucywgJ2FkZCcpO1xuICAgIHRoaXMuYm9vay51cGRhdGUoYm9vayA9PiAoeyAuLi5ib29rIH0pKTtcbiAgfVxuICAvL0FQIDIzTUFZMjUgLSBSZW1vdmUgYSBidXR0b24gZnJvbSB0aGUgYWN0aW9uIGxpc3QgXG4gIHJlbW92ZUJ1dHRvbihidG46IGFueSkge1xuICAgIHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLnVwZGF0ZVF1ZXN0aW9uQm9va0FjdGlvbkJ1dHRvbnMoYnRuLCAncmVtb3ZlJyk7XG4gICAgdGhpcy5ib29rLnVwZGF0ZShib29rID0+ICh7IC4uLmJvb2sgfSkpO1xuICB9XG4gIC8vQVAgMjNNQVkyNSAtIFVwZGF0ZSBhIHNwZWNpZmljIHByb3BlcnR5IG9mIGEgYnV0dG9uXG4gIG9uQnV0dG9uUHJvcGVydHlDaGFuZ2UoaW5kZXg6IG51bWJlciwga2V5OiBzdHJpbmcsIHZhbHVlOiBhbnksaXNUcmFuc2xhdGU6IGJvb2xlYW4gPSBmYWxzZSkge1xuICAgIGNvbnN0IGJ1dHRvbnMgPSB0aGlzLmJvb2soKT8ucXVlc3Rpb25ib29rPy5hY3Rpb24gPz8gW107XG4gICAgaWYgKGJ1dHRvbnNbaW5kZXhdKSB7XG4gICAgICBidXR0b25zW2luZGV4XVtrZXldID0gdmFsdWU7XG4gICAgICB0aGlzLmJvb2sudXBkYXRlKGJvb2sgPT4gKHsgLi4uYm9vaywgcXVlc3Rpb25ib29rOiB7IC4uLmJvb2sucXVlc3Rpb25ib29rLCBhY3Rpb246IGJ1dHRvbnMgfSB9KSk7XG4gICAgfVxuICAgIGxldCBidXR0b24gPSBidXR0b25zW2luZGV4XVxuICAgIGlmKGlzVHJhbnNsYXRlKXtcbiAgICAgIC8vU0tTMjhKVUwyNSBSZWZyZXNoIHRoZSBib29rIHNpZ25hbCBmcm9tIHNlcnZpY2VcbiAgICAgIGNvbnN0IHVwZGF0ZWRCb29rID0gdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UuZ2V0Qm9vaygpO1xuICAgICAgdGhpcy5ib29rLnNldCh1cGRhdGVkQm9vayk7XG4gICAgICAvL1NLUzI4SlVMMjUgV29yayB3aXRoIGEgbXV0YWJsZSBjb3B5XG4gICAgICBjb25zdCBjdXJyZW50Qm9vayA9IHRoaXMuYm9vaygpO1xuICAgICAgY29uc3QgdHJhbnNsYXRpb25NYXAgPSBjdXJyZW50Qm9vay50cmFuc2xhdGlvbk1hcCB8fCB7fTtcbiAgICAgIGNvbnN0IGN1cnJlbnRMYW5nID0gdGhpcy50cmFuc2xhdGlvblNlcnZpY2UuZ2V0Rm9ybUJ1aWxkZXJMYW5ndWFnZSgpO1xuICAgICAgLy9TS1MyOEpVTDI1IEVuc3VyZSBuZXN0ZWQgc3RydWN0dXJlIGV4aXN0c1xuICAgICAgaWYgKCF0cmFuc2xhdGlvbk1hcFtjdXJyZW50TGFuZ10pIHRyYW5zbGF0aW9uTWFwW2N1cnJlbnRMYW5nXSA9IHt9O1xuICAgICAgaWYgKCF0cmFuc2xhdGlvbk1hcFtjdXJyZW50TGFuZ11bYnV0dG9uLmlkXSkgdHJhbnNsYXRpb25NYXBbY3VycmVudExhbmddW2J1dHRvbi5pZF0gPSB7fTtcbiAgICAgIC8vU0tTMjhKVUwyNSBTZXQgdGhlIHRyYW5zbGF0ZWQgdmFsdWVcbiAgICAgIHRyYW5zbGF0aW9uTWFwW2N1cnJlbnRMYW5nXVtidXR0b24uaWRdW2tleV0gPSB2YWx1ZTtcbiAgICAgIC8vU0tTMjhKVUwyNSBVcGRhdGUgYm9vayBhbmQgcmUtc2V0IHRoZSBzaWduYWxcbiAgICAgIGN1cnJlbnRCb29rLnRyYW5zbGF0aW9uTWFwID0gdHJhbnNsYXRpb25NYXA7XG4gICAgICBpZihjdXJyZW50TGFuZyA9PT0gJ2VuJyl7XG4gICAgICAgIHRoaXMudHJhbnNsYXRpb25TZXJ2aWNlLnVwZGF0ZVRyYW5zbGF0aW9ucyh0cmFuc2xhdGlvbk1hcClcbiAgICAgIH1cbiAgICAgIHRoaXMuYm9vay5zZXQoY3VycmVudEJvb2spOyAvLyBUcmlnZ2VyIHJlYWN0aXZlIHVwZGF0ZVxuICAgICAgLy9TS1MyOEpVTDI1IFVwZGF0ZSBpbiBzZXJ2aWNlIGlmIG5lZWRlZFxuICAgICAgdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UudXBkYXRlQm9vayhjdXJyZW50Qm9vayk7XG4gICAgfVxuICB9XG4gIC8vQVAtMTBNQVIyNSBVcGRhdGVzIHRoZSB0aXRsZSB1c2luZyB0aGUgZm9ybSBidWlsZGVyIHNlcnZpY2UgIFxuICB1cGRhdGVUaXRsZSh2YWx1ZTogc3RyaW5nKSB7XG4gICAgdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UudXBkYXRlVGl0bGUodmFsdWUpO1xuICAgIHRoaXMuYm9vay51cGRhdGUoYm9vayA9PiAoe1xuICAgICAgLi4uYm9vayxcbiAgICAgIHJlY29yZHM6IFt7IC4uLmJvb2sucmVjb3Jkc1swXSwgdGl0bGU6IHZhbHVlIH1dXG4gICAgfSkpO1xuICB9XG5cbiAgdmFsaWRhdGVJbnB1dCh2YWx1ZTogc3RyaW5nLCB0eXBlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBpZiAodHlwZSA9PT0gJ2xhYmVsJyB8fCB0eXBlID09PSAncGxhY2Vob2xkZXInKSB7XG4gICAgICBjb25zdCByZWdleCA9IC9eW2EtekEtWjAtOVxcc10qJC87XG4gICAgICBpZiAoIXJlZ2V4LnRlc3QodmFsdWUpKSB7XG4gICAgICAgIHRoaXMuZXJyb3JNZXNzYWdlLnNldCgnT25seSBsZXR0ZXJzIGFuZCBudW1iZXJzIGFyZSBhbGxvd2VkJyk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5lcnJvck1lc3NhZ2Uuc2V0KCcnKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHVwZGF0ZUZpZWxkKHZhbHVlOiBzdHJpbmcpIHtcbiAgICB0aGlzLmJvb2tTdWJ0ZXh0LnVwZGF0ZShzdWJ0ZXh0ID0+ICh7XG4gICAgICAuLi5zdWJ0ZXh0LFxuICAgICAgZmllbGQ6IHZhbHVlLnNwbGl0KCcsJykubWFwKGl0ZW0gPT4gaXRlbS50cmltKCkpXG4gICAgfSkpO1xuICB9XG5cbiAgb25DaGVja2JveENoYW5nZSh0YXJnZXRBcnJheVBhdGg6IGFueSwgdGFyZ2V0QXJyYXlLZXk6IGFueSwga2V5OiBhbnksIGFwaU5hbWU6IHN0cmluZywgaXNDaGVja2VkOiBib29sZWFuKSB7XG4gICAgY29uc3QgdGFyZ2V0QXJyYXkgPSB0aGlzLmdldERhdGFCeVBhdGgodGFyZ2V0QXJyYXlQYXRoKTtcbiAgICBjb25zdCBmb3VuZEl0ZW0gPSB0YXJnZXRBcnJheS5maW5kKGl0ZW0gPT4gaXRlbVt0YXJnZXRBcnJheUtleV0gPT09IHRoaXMuc2VsZWN0Q29sdW1uKCkpO1xuICAgIGZvdW5kSXRlbVtrZXldID0gZm91bmRJdGVtW2tleV0gPyBmb3VuZEl0ZW1ba2V5XSA6IFtdO1xuICAgIGlmIChpc0NoZWNrZWQpIHtcbiAgICAgIGlmICghZm91bmRJdGVtW2tleV0uaW5jbHVkZXMoYXBpTmFtZSkpIHtcbiAgICAgICAgZm91bmRJdGVtW2tleV0ucHVzaChhcGlOYW1lKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgaW5kZXggPSBmb3VuZEl0ZW1ba2V5XS5pbmRleE9mKGFwaU5hbWUpO1xuICAgICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgICAgZm91bmRJdGVtW2tleV0uc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy51cGRhdGVFbGVtZW50KHRoaXMuc2VsZWN0ZWRFbGVtZW50KCkpO1xuICB9XG5cbiAgdXBkYXRlUHJvcGVydHkoa2V5OiBzdHJpbmcsIHZhbHVlOiBhbnkpIHtcbiAgICBpZiAodGhpcy5zZWxlY3RlZEVsZW1lbnRJbmRleCgpID49IDApIHtcbiAgICAgIGlmIChrZXkgPT09ICdxdWVzdGlvblRleHQnIHx8IGtleSA9PT0gJ3F1ZXN0aW9uJykge1xuICAgICAgICBpZiAoIXRoaXMudmFsaWRhdGVJbnB1dCh2YWx1ZSwga2V5KSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGtleSA9PT0gJ3F1ZXN0aW9uTnVtYmVyJykge1xuICAgICAgICAvL0FQLTEwTUFSMjUgQ29udmVydCB0aGUgdmFsdWUgdG8gYW4gaW50ZWdlciAgXG4gICAgICAgIGNvbnN0IG5ld09yZGVyID0gcGFyc2VJbnQodmFsdWUsIDEwKTtcbiAgICAgICAgaWYgKGlzTmFOKG5ld09yZGVyKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vQVAtMTBNQVIyNSBVcGRhdGUgdGhlIGVsZW1lbnQncyBxdWVzdGlvbk51bWJlciBpbiB0aGUgZm9ybSBidWlsZGVyIHNlcnZpY2UgIFxuICAgICAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS51cGRhdGVFbGVtZW50KHRoaXMuc2VsZWN0ZWRFbGVtZW50SW5kZXgoKSwgeyBxdWVzdGlvbk51bWJlcjogbmV3T3JkZXIgfSk7XG5cbiAgICAgICAgLy9BUC0xME1BUjI1IFNvcnQgZWxlbWVudHMgYmFzZWQgb24gdGhlIHVwZGF0ZWQgcXVlc3Rpb25OdW1iZXIgIFxuICAgICAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5zb3J0RWxlbWVudHNCeU9yZGVyKCk7XG4gICAgICB9XG4gICAgICBpZiAoa2V5ID09PSAnZm9udCcgfHwga2V5ID09PSAnZm9udFdlaWdodCcpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZEVsZW1lbnQudXBkYXRlKGVsID0+ICh7IC4uLmVsLCBba2V5XTogdmFsdWUgfSkpO1xuICAgICAgfVxuICAgICAgY29uc3QgdXBkYXRlID0geyBba2V5XTogdmFsdWUgfTtcbiAgICAgIHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLnVwZGF0ZUVsZW1lbnQodGhpcy5zZWxlY3RlZEVsZW1lbnRJbmRleCgpLCB1cGRhdGUpO1xuICAgIH1cbiAgfVxuXG4gIG9uUmFkaW9DaGFuZ2UodGFyZ2V0QXJyYXlQYXRoOiBhbnksIHRhcmdldEFycmF5S2V5OiBhbnksIGtleTogYW55LCB2YWx1ZTogYW55KSB7XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScpIHtcbiAgICAgIGxldCB0YXJnZXRBcnJheSA9IHRoaXMuZ2V0RGF0YUJ5UGF0aCh0YXJnZXRBcnJheVBhdGgpO1xuICAgICAgaWYgKHR5cGVvZiB0YXJnZXRBcnJheSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB0YXJnZXRBcnJheSA9IEpTT04ucGFyc2UodGFyZ2V0QXJyYXkgfHwgJ1tdJyk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAvLyBjb25zb2xlLmVycm9yKCdFcnJvciBwYXJzaW5nIHRhcmdldEFycmF5OicsIGUpO1xuICAgICAgICAgIHRhcmdldEFycmF5ID0gW107XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICghQXJyYXkuaXNBcnJheSh0YXJnZXRBcnJheSkpIHJldHVybjtcbiAgICAgIGxldCBmb3VuZEl0ZW0gPSB0YXJnZXRBcnJheS5maW5kKGl0ZW0gPT4gaXRlbVt0YXJnZXRBcnJheUtleV0gPT09IHRoaXMuc2VsZWN0Q29sdW1uKCkpO1xuICAgICAgaWYgKCFmb3VuZEl0ZW0pIHtcbiAgICAgICAgZm91bmRJdGVtID0geyBbdGFyZ2V0QXJyYXlLZXldOiB0aGlzLnNlbGVjdENvbHVtbigpIH07XG4gICAgICAgIHRhcmdldEFycmF5LnB1c2goZm91bmRJdGVtKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGtleXMgPSBrZXkuc3BsaXQoJy4nKTtcbiAgICAgIGxldCBvYmogPSBmb3VuZEl0ZW07XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGtleXMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGsgPSBrZXlzW2ldO1xuICAgICAgICBpZiAoIW9ialtrXSkgb2JqW2tdID0ge307XG4gICAgICAgIG9iaiA9IG9ialtrXTtcbiAgICAgIH1cbiAgICAgIG9ialtrZXlzW2tleXMubGVuZ3RoIC0gMV1dID0gdmFsdWU7XG4gICAgICB0aGlzLnNlbGVjdGVkRWxlbWVudC51cGRhdGUoZWwgPT4gKHtcbiAgICAgICAgLi4uZWwsXG4gICAgICAgIGZpZWxkc01ldGE6IHRhcmdldEFycmF5XG4gICAgICB9KSk7XG4gICAgICB0aGlzLnVwZGF0ZUVsZW1lbnQodGhpcy5zZWxlY3RlZEVsZW1lbnQoKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2V0VmFsdWVCeVBhdGgoa2V5LCB2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgb25SZXF1aXJlZENoYW5nZSh2YWx1ZTogYm9vbGVhbikge1xuICAgIGlmICh0aGlzLnNlbGVjdGVkRWxlbWVudCgpKSB7XG4gICAgICBsZXQgbGFiZWwgPSB0aGlzLnNlbGVjdGVkRWxlbWVudCgpLmxhYmVsID8gdGhpcy5zZWxlY3RlZEVsZW1lbnQoKS5sYWJlbC5yZXBsYWNlKC9cXHMqXFwqKyQvLCAnJykgOiAnTGFiZWwnO1xuICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgIGxhYmVsID0gYCR7bGFiZWx9ICpgO1xuICAgICAgfVxuICAgICAgdGhpcy51cGRhdGVQcm9wZXJ0eSgnbGFiZWwnLCBsYWJlbCk7XG4gICAgICB0aGlzLnVwZGF0ZVByb3BlcnR5KCdpc09wdGlvbmFsJywgdmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHRvZ2dsZVN1YlF1ZXN0aW9uKHByb3A6IGFueSkge1xuICAgIHRoaXMuaXNFeHBhbmRlZCA9ICF0aGlzLmlzRXhwYW5kZWQ7XG4gIH1cblxuICB0b2dnbGVTdHlsZVNlY3Rpb24oKSB7XG4gICAgdGhpcy5pc1N0eWxlRXhwYW5kZWQuc2V0KCF0aGlzLmlzU3R5bGVFeHBhbmRlZCgpKTtcbiAgfVxuXG4gIGdldFByb3BlcnRpZXMoKSB7XG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMuc2VsZWN0ZWRFbGVtZW50KCk7XG4gICAgY29uc3Qgc2VsZWN0ZWRDb2x1bW4gPSB0aGlzLnNlbGVjdENvbHVtbigpO1xuICAgIFxuICAgIC8vIENoZWNrIGlmIHdlIGNhbiB1c2UgY2FjaGVkIHJlc3VsdFxuICAgIGlmICh0aGlzLl9jYWNoZWRQcm9wZXJ0aWVzICYmIFxuICAgICAgICB0aGlzLl9sYXN0U2VsZWN0ZWRFbGVtZW50ID09PSBlbGVtZW50ICYmIFxuICAgICAgICB0aGlzLl9sYXN0U2VsZWN0ZWRDb2x1bW4gPT09IHNlbGVjdGVkQ29sdW1uKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY2FjaGVkUHJvcGVydGllcztcbiAgICB9ICAgIFxuICAgIGlmICghZWxlbWVudCkge1xuICAgICAgdGhpcy5fY2FjaGVkUHJvcGVydGllcyA9IG51bGw7XG4gICAgICB0aGlzLl9sYXN0U2VsZWN0ZWRFbGVtZW50ID0gbnVsbDtcbiAgICAgIHRoaXMuX2xhc3RTZWxlY3RlZENvbHVtbiA9IG51bGw7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIFxuICAgIGxldCByZXN1bHQgPSBudWxsO1xuICAgIFxuICAgIGlmIChlbGVtZW50LnR5cGUgPT09ICdIZWFkZXInKSB7XG4gICAgICByZXN1bHQgPSB0aGlzLmVsZW1lbnRQcm9wZXJ0aWVzKClbJ0hlYWRlciddO1xuICAgIH0gZWxzZSBpZiAoZWxlbWVudC50eXBlID09PSAnVGFibGUnICYmIHNlbGVjdGVkQ29sdW1uICE9PSBudWxsKSB7XG4gICAgICBsZXQgZmllbGRzTWV0YSA9IGVsZW1lbnQuZmllbGRzTWV0YTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGZpZWxkc01ldGEgPSBBcnJheS5pc0FycmF5KGZpZWxkc01ldGEpXG4gICAgICAgICAgPyBmaWVsZHNNZXRhXG4gICAgICAgICAgOiBKU09OLnBhcnNlKGZpZWxkc01ldGEgfHwgJ1tdJyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHBhcnNpbmcgZmllbGRzTWV0YSBpbiBnZXRQcm9wZXJ0aWVzOicsIGUpO1xuICAgICAgICBmaWVsZHNNZXRhID0gW107XG4gICAgICB9XG4gICAgICBcbiAgICAgIGNvbnN0IGNvbHVtbiA9IGZpZWxkc01ldGEuZmluZCgoYzogYW55KSA9PiBjLnVuaXF1ZUlkZW50aWZpZXIgPT09IHNlbGVjdGVkQ29sdW1uKTtcbiAgICAgIGlmIChjb2x1bW4pIHtcbiAgICAgICAgY29uc3QgbWFya0lzVGFibGVDb2x1bW4gPSAoaXRlbXM6IGFueVtdID0gW10pID0+XG4gICAgICAgICAgaXRlbXMubWFwKGl0ZW0gPT4ge1xuICAgICAgICAgICAgY29uc3QgbmV3SXRlbSA9IHsgLi4uaXRlbSwgaXNUYWJsZUNvbHVtbjogdHJ1ZSB9O1xuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkobmV3SXRlbS5zdWJRdWVzdGlvbikpIHtcbiAgICAgICAgICAgICAgbmV3SXRlbS5zdWJRdWVzdGlvbiA9IG5ld0l0ZW0uc3ViUXVlc3Rpb24ubWFwKHN1YiA9PiAoe1xuICAgICAgICAgICAgICAgIC4uLnN1YixcbiAgICAgICAgICAgICAgICBpc1RhYmxlQ29sdW1uOiB0cnVlXG4gICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBuZXdJdGVtO1xuICAgICAgICAgIH0pO1xuICAgICAgICBcbiAgICAgICAgcmVzdWx0ID0ge1xuICAgICAgICAgIGVsZW1lbnRQcm9wczogW1xuICAgICAgICAgICAgLi4uKHRoaXMuZWxlbWVudFByb3BlcnRpZXMoKVsnVGFibGVDb2x1bW4nXS5lbGVtZW50UHJvcHMgfHwgW10pLFxuICAgICAgICAgICAgLi4ubWFya0lzVGFibGVDb2x1bW4odGhpcy5lbGVtZW50UHJvcGVydGllcygpW3RoaXMuZWxlbWVudFR5cGUuaW5jbHVkZXMoY29sdW1uLmZsZFR5cGUpID8gY29sdW1uLmZsZFR5cGUgOiAnVGV4dCddPy5lbGVtZW50UHJvcHMpXG4gICAgICAgICAgXSxcbiAgICAgICAgICBmaWVsZFByb3BzOiBbXG4gICAgICAgICAgICAuLi4odGhpcy5lbGVtZW50UHJvcGVydGllcygpWydUYWJsZUNvbHVtbiddLmZpZWxkUHJvcHMgfHwgW10pLFxuICAgICAgICAgICAgLi4ubWFya0lzVGFibGVDb2x1bW4odGhpcy5lbGVtZW50UHJvcGVydGllcygpW3RoaXMuZWxlbWVudFR5cGUuaW5jbHVkZXMoY29sdW1uLmZsZFR5cGUpID8gY29sdW1uLmZsZFR5cGUgOiAnVGV4dCddPy5maWVsZFByb3BzKVxuICAgICAgICAgIF0sXG4gICAgICAgICAgYXBwZWFyYW5jZTogW1xuICAgICAgICAgICAgLi4uKHRoaXMuZWxlbWVudFByb3BlcnRpZXMoKVsnVGFibGVDb2x1bW4nXS5hcHBlYXJhbmNlIHx8IFtdKSxcbiAgICAgICAgICAgIC4uLm1hcmtJc1RhYmxlQ29sdW1uKHRoaXMuZWxlbWVudFByb3BlcnRpZXMoKVt0aGlzLmVsZW1lbnRUeXBlLmluY2x1ZGVzKGNvbHVtbi5mbGRUeXBlKSA/IGNvbHVtbi5mbGRUeXBlIDogJ1RleHQnXT8uYXBwZWFyYW5jZSlcbiAgICAgICAgICBdXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHQgPSB0aGlzLmVsZW1lbnRQcm9wZXJ0aWVzKClbJ1RhYmxlQ29sdW1uJ107XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdCA9IHRoaXMuZWxlbWVudFByb3BlcnRpZXMoKVtlbGVtZW50LnR5cGVdO1xuICAgIH1cbiAgICBcbiAgICAvLyBDYWNoZSB0aGUgcmVzdWx0XG4gICAgdGhpcy5fY2FjaGVkUHJvcGVydGllcyA9IHJlc3VsdDtcbiAgICB0aGlzLl9sYXN0U2VsZWN0ZWRFbGVtZW50ID0gZWxlbWVudDtcbiAgICB0aGlzLl9sYXN0U2VsZWN0ZWRDb2x1bW4gPSBzZWxlY3RlZENvbHVtbjtcbiAgICBcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIC8vIEFkZCBtZXRob2QgdG8gY2xlYXIgY2FjaGUgd2hlbiBuZWVkZWRcbiAgcHJpdmF0ZSBjbGVhclByb3BlcnRpZXNDYWNoZSgpIHtcbiAgICB0aGlzLl9jYWNoZWRQcm9wZXJ0aWVzID0gbnVsbDtcbiAgICB0aGlzLl9sYXN0U2VsZWN0ZWRFbGVtZW50ID0gbnVsbDtcbiAgICB0aGlzLl9sYXN0U2VsZWN0ZWRDb2x1bW4gPSBudWxsO1xuICB9XG4gIC8vIEFQLTI4TUFSMjUgQWRkIGFuIG9wdGlvbiB3aXRoIGEgdW5pcXVlIFVVSURcbiAgYWRkT3B0aW9uKG9wdGlvbnM6IGFueVtdKSB7XG4gICAgY29uc3QgdW5pcXVlX2lkID0gdXVpZHY0KCk7XG4gICAgb3B0aW9ucy5wdXNoKHsgaWQ6IHVuaXF1ZV9pZCwgdmFsdWU6ICcnIH0pO1xuICB9XG5cbiAgLy8gQVAtMjhNQVIyNSBGdW5jdGlvbiB0byByZW1vdmUgYW4gb3B0aW9uIGJhc2VkIG9uIGl0cyB1bmlxdWUgVVVJRFxuICByZW1vdmVPcHRpb24ob3B0aW9uczogYW55W10sIGlkOiBzdHJpbmcpIHtcbiAgICBjb25zdCBpbmRleCA9IG9wdGlvbnMuZmluZEluZGV4KG9wdGlvbiA9PiBvcHRpb24uaWQgPT09IGlkKTtcbiAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICBvcHRpb25zLnNwbGljZShpbmRleCwgMSk7XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlQnV0dG9uQ2xpY2soKSB7XG4gICAgdGhpcy5mb3JtQnV0dG9uSGFuZGxlci5lbWl0KHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLmRvd25sb2FkRWxlbWVudCgpKTtcbiAgfVxuXG4gIGhhbmRsZVRlbXBsYXRlU2F2ZSgpIHtcbiAgICB0aGlzLnRlbXBsYXRlU2F2ZUhhbmRsZXIuZW1pdCh0aGlzLnRlbXBsYXRlU2VydmljZS5kb3dubG9hZCgpKTtcbiAgfVxuXG4gIHNldEFjdGl2ZVRhYih0YWI6IHN0cmluZykge1xuICAgIHRoaXMuYWN0aXZlVGFiLnNldCh0YWIpO1xuICB9XG5cbiAgb25TYXZlKCkge31cblxuICBvbkNhbmNlbCgpIHt9XG5cbiAgb25BbGlnblNlbGVjdCh2YWx1ZTogc3RyaW5nKSB7XG4gICAgdGhpcy5zZWxlY3RlZEVsZW1lbnQudXBkYXRlKGVsID0+ICh7IC4uLmVsLCB0ZXh0QWxpZ246IHZhbHVlIH0pKTtcbiAgfVxuXG4gIG9uU3R5bGVTZWxlY3QodmFsdWU6IHN0cmluZykge1xuICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50LnVwZGF0ZShlbCA9PiAoe1xuICAgICAgLi4uZWwsXG4gICAgICBzdHlsZXM6IFt2YWx1ZV1cbiAgICB9KSk7XG4gIH1cblxuICBpc1N0eWxlQWN0aXZlKHZhbHVlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3RlZEVsZW1lbnQoKT8uc3R5bGVzPy5pbmNsdWRlcyh2YWx1ZSkgfHwgZmFsc2U7XG4gIH1cblxuICBnZXRWYWx1ZUJ5UGF0aChwYXRoOiBzdHJpbmcsIG9iajogYW55ID0gdGhpcy5zZWxlY3RlZEVsZW1lbnQoKSwgZGVmYXVsdFZhbHVlOiBhbnkgPSAnJyk6IGFueSB7XG4gICAgaWYgKCFvYmogfHwgIXBhdGgpIHJldHVybiBkZWZhdWx0VmFsdWU7XG4gICAgcmV0dXJuIHBhdGguc3BsaXQoJy4nKS5yZWR1Y2UoKG8sIGspID0+IG8/LltrXSA/PyBkZWZhdWx0VmFsdWUsIG9iaik7XG4gIH1cbiAgaXNBbm90aGVySWRTZWxlY3RlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UuZ2V0RWxlbWVudHMoKVxuICAgICAgLnNvbWUoKGVsLCBpKSA9PiBpICE9PSB0aGlzLnNlbGVjdGVkRWxlbWVudEluZGV4KCkgJiYgZWwucHJpbWFyeUtleSk7XG4gIH1cblxuICAvLyBBbHNvIHVwZGF0ZSB5b3VyIG9uVG9nZ2xlQ2hhbmdlIG1ldGhvZCB0byBjbGVhciBjYWNoZVxub25Ub2dnbGVDaGFuZ2UocGF0aDogc3RyaW5nLCBldmVudDogYW55KSB7XG4gIC8vIENsZWFyIGNhY2hlIHdoZW4gZWxlbWVudCBjaGFuZ2VzXG4gIHRoaXMuY2xlYXJQcm9wZXJ0aWVzQ2FjaGUoKTtcbiAgY29uc3QgY2hlY2tlZCA9IGV2ZW50LnRhcmdldCA/IChldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudCkuY2hlY2tlZCA6IGV2ZW50O1xuICB0aGlzLnNldFZhbHVlQnlQYXRoKHBhdGgsIGNoZWNrZWQpO1xuICBcbiAgaWYgKHRoaXMuc2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScpIHtcbiAgICBsZXQgZmllbGRzTWV0YSA9IHRoaXMuZ2V0RGF0YUJ5UGF0aCgnZmllbGRzTWV0YScpO1xuICAgIGlmICh0eXBlb2YgZmllbGRzTWV0YSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGZpZWxkc01ldGEgPSBKU09OLnBhcnNlKGZpZWxkc01ldGEgfHwgJ1tdJyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHBhcnNpbmcgZmllbGRzTWV0YTonLCBlKTtcbiAgICAgICAgZmllbGRzTWV0YSA9IFtdO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnNlbGVjdGVkRWxlbWVudC51cGRhdGUoZWwgPT4gKHtcbiAgICAgIC4uLmVsLFxuICAgICAgZmllbGRzTWV0YTogZmllbGRzTWV0YVxuICAgIH0pKTtcbiAgICB0aGlzLnVwZGF0ZUVsZW1lbnQodGhpcy5zZWxlY3RlZEVsZW1lbnQoKSk7XG4gIH1cbn1cblxuICAvLyBVcGRhdGUgeW91ciBzZXRWYWx1ZUJ5UGF0aCBtZXRob2QgdG8gY2xlYXIgY2FjaGVcbnNldFZhbHVlQnlQYXRoKHBhdGg6IHN0cmluZywgdmFsdWU6IGFueSxpc1RyYW5zbGF0ZTpib29sZWFuID0gZmFsc2UpIHtcbiAgLy8gQ2xlYXIgY2FjaGUgd2hlbiBlbGVtZW50IGNoYW5nZXNcbiAgdGhpcy5jbGVhclByb3BlcnRpZXNDYWNoZSgpO1xuICBcbiAgaWYgKHRoaXMuc2VsZWN0ZWRFbGVtZW50SW5kZXgoKSA+PSAwKSB7XG4gICAgaWYgKHBhdGggPT09ICdxdWVzdGlvblRleHQnIHx8IHBhdGggPT09ICdxdWVzdGlvbicpIHtcbiAgICAgIGlmICghdGhpcy52YWxpZGF0ZUlucHV0KHZhbHVlLCBwYXRoKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChwYXRoID09PSAncXVlc3Rpb25OdW1iZXInKSB7XG4gICAgICBjb25zdCBuZXdPcmRlciA9IHBhcnNlSW50KHZhbHVlLCAxMCk7XG4gICAgICBpZiAoaXNOYU4obmV3T3JkZXIpKSByZXR1cm47XG4gICAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS51cGRhdGVFbGVtZW50KHRoaXMuc2VsZWN0ZWRFbGVtZW50SW5kZXgoKSwgeyBxdWVzdGlvbk51bWJlcjogbmV3T3JkZXIgfSk7XG4gICAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5zb3J0RWxlbWVudHNCeU9yZGVyKCk7XG4gICAgfVxuICAgIGlmIChwYXRoID09PSAnZm9udCcgfHwgcGF0aCA9PT0gJ2ZvbnRXZWlnaHQnKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkRWxlbWVudC51cGRhdGUoZWwgPT4gKHsgLi4uZWwsIFtwYXRoXTogdmFsdWUgfSkpO1xuICAgIH1cbiAgfVxuICBcbiAgY29uc3QgZWxlbWVudCA9IHRoaXMuc2VsZWN0ZWRFbGVtZW50KCk7XG4gIGlmIChlbGVtZW50KSB7XG4gICAgbGV0IHN1YlRleHQgPSBlbGVtZW50LnN1YlRleHQ7XG4gICAgaWYgKHR5cGVvZiBzdWJUZXh0ID09PSAnc3RyaW5nJyAmJiBzdWJUZXh0LnRyaW0oKSAhPT0gJycpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHN1YlRleHQgPSBKU09OLnBhcnNlKHN1YlRleHQpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyBjb25zb2xlLmVycm9yKCdFcnJvciBwYXJzaW5nIHN1YlRleHQ6JywgZSk7XG4gICAgICAgIHN1YlRleHQgPSB7fTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzdWJUZXh0ICE9PSAnb2JqZWN0JyB8fCBzdWJUZXh0ID09PSBudWxsKSB7XG4gICAgICBzdWJUZXh0ID0ge307XG4gICAgfVxuICAgIGNvbnN0IGFycmF5RmllbGRzID0gWydmaWVsZCcsICdxdWVyeVBhcmFtZXRlcicsICdzb3VyY2VRdWVzdGlvbklkJywgJ3F1ZXJ5RmllbGQnLCAncXVlcnlWYWx1ZSddO1xuICAgIGlmIChzdWJUZXh0KSB7XG4gICAgICBhcnJheUZpZWxkcy5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHN1YlRleHRba2V5XSkpIHtcbiAgICAgICAgICBzdWJUZXh0W2tleV0gPSBzdWJUZXh0W2tleV0uam9pbignLCAnKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSAgICAgICAgXG4gICAgaWYoZWxlbWVudC50eXBlID09PSAnVGFibGUnKXtcbiAgICAgIGVsZW1lbnQuZmllbGRzTWV0YS5mb3JFYWNoKGZpZWxkID0+IHtcbiAgICAgICAgaWYoZmllbGQ/LnF1ZXN0aW9uPy5zdWJUZXh0KXtcbiAgICAgICAgICBhcnJheUZpZWxkcy5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShmaWVsZC5xdWVzdGlvbi5zdWJUZXh0W2tleV0pKSB7XG4gICAgICAgICAgICAgIGZpZWxkLnF1ZXN0aW9uLnN1YlRleHRba2V5XSA9IGZpZWxkLnF1ZXN0aW9uLnN1YlRleHRba2V5XS5qb2luKCcsICcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gICAgaWYgKGlzVHJhbnNsYXRlKSB7XG4gICAgICAvL1NLUzI4SlVMMjUgUmVmcmVzaCB0aGUgYm9vayBzaWduYWwgZnJvbSBzZXJ2aWNlXG4gICAgICBjb25zdCB1cGRhdGVkQm9vayA9IHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLmdldEJvb2soKTtcbiAgICAgIHRoaXMuYm9vay5zZXQodXBkYXRlZEJvb2spO1xuICAgICAgLy8gV29yayB3aXRoIGEgbXV0YWJsZSBjb3B5XG4gICAgICBjb25zdCBjdXJyZW50Qm9vayA9IHRoaXMuYm9vaygpO1xuICAgICAgY29uc3QgdHJhbnNsYXRpb25NYXAgPSBjdXJyZW50Qm9vay50cmFuc2xhdGlvbk1hcCB8fCB7fTtcbiAgICAgIGNvbnN0IGN1cnJlbnRMYW5nID0gdGhpcy50cmFuc2xhdGlvblNlcnZpY2UuZ2V0Rm9ybUJ1aWxkZXJMYW5ndWFnZSgpO1xuICAgICAgLy9TS1MyOEpVTDI1IEVuc3VyZSBuZXN0ZWQgc3RydWN0dXJlIGV4aXN0c1xuICAgICAgaWYgKCF0cmFuc2xhdGlvbk1hcFtjdXJyZW50TGFuZ10pIHRyYW5zbGF0aW9uTWFwW2N1cnJlbnRMYW5nXSA9IHt9O1xuICAgICAgaWYgKCF0cmFuc2xhdGlvbk1hcFtjdXJyZW50TGFuZ11bZWxlbWVudC5pZF0pIHRyYW5zbGF0aW9uTWFwW2N1cnJlbnRMYW5nXVtlbGVtZW50LmlkXSA9IHt9O1xuICAgICAgLy8gU2V0IHRoZSB0cmFuc2xhdGVkIHZhbHVlXG4gICAgICB0cmFuc2xhdGlvbk1hcFtjdXJyZW50TGFuZ11bZWxlbWVudC5pZF1bcGF0aF0gPSB2YWx1ZTtcbiAgICAgIC8vIFVwZGF0ZSBib29rIGFuZCByZS1zZXQgdGhlIHNpZ25hbFxuICAgICAgY3VycmVudEJvb2sudHJhbnNsYXRpb25NYXAgPSB0cmFuc2xhdGlvbk1hcDtcbiAgICAgIGlmKGN1cnJlbnRMYW5nID09PSAnZW4nKXtcbiAgICAgICAgdGhpcy50cmFuc2xhdGlvblNlcnZpY2UudXBkYXRlVHJhbnNsYXRpb25zKHRyYW5zbGF0aW9uTWFwKVxuICAgICAgfVxuICAgICAgdGhpcy5ib29rLnNldChjdXJyZW50Qm9vayk7IC8vIFRyaWdnZXIgcmVhY3RpdmUgdXBkYXRlXG4gICAgICAvL1NLUzI4SlVMMjUgVXBkYXRlIGluIHNlcnZpY2UgaWYgbmVlZGVkXG4gICAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS51cGRhdGVCb29rKGN1cnJlbnRCb29rKTtcbiAgICB9ICAgIFxuICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50LnVwZGF0ZShlbCA9PiAoeyAuLi5lbCwgc3ViVGV4dCB9KSk7XG4gIH1cbiAgXG4gIGNvbnN0IGtleXMgPSBwYXRoLnNwbGl0KCcuJyk7XG4gIHRoaXMuc2VsZWN0ZWRFbGVtZW50LnVwZGF0ZShlbCA9PiB7XG4gICAgbGV0IG9iaiA9IHsgLi4uZWwgfTtcbiAgICBsZXQgY3VycmVudCA9IG9iajtcbiAgICBrZXlzLmZvckVhY2goKGtleSwgaW5kZXgpID0+IHtcbiAgICAgIGlmIChpbmRleCA9PT0ga2V5cy5sZW5ndGggLSAxKSB7XG4gICAgICAgIGN1cnJlbnRba2V5XSA9IHZhbHVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKCFjdXJyZW50W2tleV0pIHtcbiAgICAgICAgICBjdXJyZW50W2tleV0gPSBpc05hTihOdW1iZXIoa2V5c1tpbmRleCArIDFdKSkgPyB7fSA6IFtdO1xuICAgICAgICB9XG4gICAgICAgIGN1cnJlbnQgPSBjdXJyZW50W2tleV07XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIG9iajtcbiAgfSk7XG4gIFxuICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5lbGVtZW50VXBkYXRlKHRoaXMuc2VsZWN0ZWRFbGVtZW50SW5kZXgoKSwgdGhpcy5zZWxlY3RlZEVsZW1lbnQoKSk7XG59XG5vcHRpb25UcmFuc2xhdGlvblVwZGF0ZShvcHRpb246IGFueSwgZXZlbnQ6IGFueSl7XG4gIC8vU0tTMjhKVUwyNSBSZWZyZXNoIHRoZSBib29rIHNpZ25hbCBmcm9tIHNlcnZpY2VcbiAgY29uc3QgdXBkYXRlZEJvb2sgPSB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5nZXRCb29rKCk7XG4gIHRoaXMuYm9vay5zZXQodXBkYXRlZEJvb2spO1xuICAvLyBXb3JrIHdpdGggYSBtdXRhYmxlIGNvcHlcbiAgY29uc3QgY3VycmVudEJvb2sgPSB0aGlzLmJvb2soKTtcbiAgY29uc3QgdHJhbnNsYXRpb25NYXAgPSBjdXJyZW50Qm9vay50cmFuc2xhdGlvbk1hcCB8fCB7fTtcbiAgY29uc3QgY3VycmVudExhbmcgPSB0aGlzLnRyYW5zbGF0aW9uU2VydmljZS5nZXRGb3JtQnVpbGRlckxhbmd1YWdlKCk7XG4gIC8vU0tTMjhKVUwyNSBFbnN1cmUgbmVzdGVkIHN0cnVjdHVyZSBleGlzdHNcbiAgaWYgKCF0cmFuc2xhdGlvbk1hcFtjdXJyZW50TGFuZ10pIHRyYW5zbGF0aW9uTWFwW2N1cnJlbnRMYW5nXSA9IHt9O1xuICBpZiAoIXRyYW5zbGF0aW9uTWFwW2N1cnJlbnRMYW5nXVtvcHRpb24uaWRdKSB0cmFuc2xhdGlvbk1hcFtjdXJyZW50TGFuZ11bb3B0aW9uLmlkXSA9IHt9O1xuICAvLyBTZXQgdGhlIHRyYW5zbGF0ZWQgdmFsdWVcbiAgdHJhbnNsYXRpb25NYXBbY3VycmVudExhbmddW29wdGlvbi5pZF1bJ2xhYmVsJ10gPSBldmVudDtcbiAgLy8gVXBkYXRlIGJvb2sgYW5kIHJlLXNldCB0aGUgc2lnbmFsXG4gIGN1cnJlbnRCb29rLnRyYW5zbGF0aW9uTWFwID0gdHJhbnNsYXRpb25NYXA7XG4gIGlmKGN1cnJlbnRMYW5nID09PSAnZW4nKXtcbiAgICB0aGlzLnRyYW5zbGF0aW9uU2VydmljZS51cGRhdGVUcmFuc2xhdGlvbnModHJhbnNsYXRpb25NYXApXG4gIH1cbiAgdGhpcy5ib29rLnNldChjdXJyZW50Qm9vayk7IC8vIFRyaWdnZXIgcmVhY3RpdmUgdXBkYXRlXG4gIC8vU0tTMjhKVUwyNSBVcGRhdGUgaW4gc2VydmljZSBpZiBuZWVkZWRcbiAgdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UudXBkYXRlQm9vayhjdXJyZW50Qm9vayk7XG59XG4gIGdldFN0eWxlS2V5cygpOiBzdHJpbmdbXSB7XG4gICAgY29uc3Qgc3R5bGUgPSB0aGlzLnNlbGVjdGVkRWxlbWVudCgpPy5zdHlsZTtcbiAgICByZXR1cm4gc3R5bGUgJiYgdHlwZW9mIHN0eWxlID09PSAnb2JqZWN0JyA/IE9iamVjdC5rZXlzKHN0eWxlKSA6IFtdO1xuICB9XG5cbiAgdXBkYXRlRWxlbWVudChlbGVtZW50OiBhbnkpIHtcbiAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5lbGVtZW50VXBkYXRlKHRoaXMuc2VsZWN0ZWRFbGVtZW50SW5kZXgoKSwgZWxlbWVudCk7XG4gICAgaWYgKGVsZW1lbnQ/LnR5cGUgPT09ICdUYWJsZScgJiYgdGhpcy5zZWxlY3RDb2x1bW4oKSkge1xuICAgICAgdGhpcy5mb3JtQnVpbGRlclNlcnZpY2Uuc2V0U2VsZWN0ZWRUYWJsZUVsZW1lbnQodGhpcy5zZWxlY3RlZEVsZW1lbnRJbmRleCgpLCB7IHVuaXF1ZUlkZW50aWZpZXI6IHRoaXMuc2VsZWN0Q29sdW1uKCkgfHwgbnVsbCB9KTtcbiAgICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50LnNldCh7IC4uLmVsZW1lbnQgfSk7IC8vIEVuc3VyZSByZWFjdGl2ZSB1cGRhdGVcbiAgICB9XG4gIH1cblxuICBnZXRWYWx1ZUJ5QXJyYXlQYXRoKHRhcmdldEFycmF5UGF0aDogYW55LCB0YXJnZXRBcnJheUtleTogc3RyaW5nLCBzZWxlY3RDb2x1bW46IHN0cmluZywga2V5UGF0aDogc3RyaW5nLCBpc1RhYmxlQ29sdW1uOiBib29sZWFuID0gZmFsc2UpOiBhbnkge1xuICAgIGlmIChpc1RhYmxlQ29sdW1uKSB7XG4gICAgICB0YXJnZXRBcnJheVBhdGggPSAnZmllbGRzTWV0YSc7XG4gICAgICB0YXJnZXRBcnJheUtleSA9ICd1bmlxdWVJZGVudGlmaWVyJztcbiAgICAgIGtleVBhdGggPSAncXVlc3Rpb24uJyArIGtleVBhdGg7XG4gICAgfVxuICAgIGxldCB0YXJnZXRBcnJheSA9IHRoaXMuZ2V0RGF0YUJ5UGF0aCh0YXJnZXRBcnJheVBhdGgpO1xuICAgIGlmICh0eXBlb2YgdGFyZ2V0QXJyYXkgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0cnkge1xuICAgICAgICB0YXJnZXRBcnJheSA9IEpTT04ucGFyc2UodGFyZ2V0QXJyYXkgfHwgJ1tdJyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHBhcnNpbmcgdGFyZ2V0QXJyYXk6JywgZSk7XG4gICAgICAgIHJldHVybiAnJztcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHRhcmdldEFycmF5KSkgcmV0dXJuICcnO1xuICAgIGNvbnN0IGZvdW5kSXRlbSA9IHRhcmdldEFycmF5LmZpbmQoaXRlbSA9PiBpdGVtW3RhcmdldEFycmF5S2V5XSA9PT0gc2VsZWN0Q29sdW1uKTtcbiAgICByZXR1cm4gZm91bmRJdGVtID8ga2V5UGF0aC5zcGxpdCgnLicpLnJlZHVjZSgob2JqLCBrZXkpID0+IG9iaj8uW2tleV0sIGZvdW5kSXRlbSkgOiAnJztcbiAgfVxuICBcbiAgdXBkYXRlVmFsdWVCeUFycmF5UGF0aCh0YXJnZXRBcnJheVBhdGg6IGFueSwgdGFyZ2V0QXJyYXlLZXk6IHN0cmluZywgc2VsZWN0Q29sdW1uOiBzdHJpbmcsIGtleVBhdGg6IHN0cmluZywgZXZlbnQ6IGFueSwgaXNUYWJsZUNvbHVtbjogYm9vbGVhbiA9IGZhbHNlLGlzVHJhbnNsYXRlOmJvb2xlYW4gPSBmYWxzZSApIHtcbiAgICAvLyBDbGVhciBjYWNoZSB3aGVuIGVsZW1lbnQgY2hhbmdlc1xuICAgIHRoaXMuY2xlYXJQcm9wZXJ0aWVzQ2FjaGUoKTtcbiAgICAgICAgXG4gICAgaWYgKGlzVGFibGVDb2x1bW4pIHtcbiAgICAgIHRhcmdldEFycmF5UGF0aCA9ICdmaWVsZHNNZXRhJztcbiAgICAgIHRhcmdldEFycmF5S2V5ID0gJ3VuaXF1ZUlkZW50aWZpZXInO1xuICAgICAga2V5UGF0aCA9ICdxdWVzdGlvbi4nICsga2V5UGF0aDtcbiAgICB9XG4gICAgICAgIFxuICAgIGxldCB0YXJnZXRBcnJheSA9IHRoaXMuZ2V0RGF0YUJ5UGF0aCh0YXJnZXRBcnJheVBhdGgpO1xuICAgIGlmICh0eXBlb2YgdGFyZ2V0QXJyYXkgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0cnkge1xuICAgICAgICB0YXJnZXRBcnJheSA9IEpTT04ucGFyc2UodGFyZ2V0QXJyYXkgfHwgJ1tdJyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHBhcnNpbmcgdGFyZ2V0QXJyYXk6JywgZSk7XG4gICAgICAgIHRhcmdldEFycmF5ID0gW107XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIGlmICghQXJyYXkuaXNBcnJheSh0YXJnZXRBcnJheSkpIHtcbiAgICAgIHRhcmdldEFycmF5ID0gW107XG4gICAgICB0aGlzLnNlbGVjdGVkRWxlbWVudC51cGRhdGUoZWwgPT4gKHtcbiAgICAgICAgLi4uZWwsXG4gICAgICAgIFt0YXJnZXRBcnJheVBhdGhdOiB0YXJnZXRBcnJheVxuICAgICAgfSkpO1xuICAgIH1cbiAgICBcbiAgICBsZXQgZm91bmRJdGVtID0gdGFyZ2V0QXJyYXkuZmluZChpdGVtID0+IGl0ZW1bdGFyZ2V0QXJyYXlLZXldID09PSBzZWxlY3RDb2x1bW4pO1xuICAgIGlmICghZm91bmRJdGVtKSB7XG4gICAgICBmb3VuZEl0ZW0gPSB7IFt0YXJnZXRBcnJheUtleV06IHNlbGVjdENvbHVtbiB9O1xuICAgICAgdGFyZ2V0QXJyYXkucHVzaChmb3VuZEl0ZW0pO1xuICAgIH1cbiAgICBcbiAgICBjb25zdCBrZXlzID0ga2V5UGF0aC5zcGxpdCgnLicpO1xuICAgIGxldCBvYmogPSBmb3VuZEl0ZW07XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgY29uc3Qga2V5ID0ga2V5c1tpXTtcbiAgICAgIGlmICghb2JqW2tleV0pIG9ialtrZXldID0ge307XG4gICAgICBvYmogPSBvYmpba2V5XTtcbiAgICB9XG4gICAgXG4gICAgY29uc3QgbGFzdEtleSA9IGtleXNba2V5cy5sZW5ndGggLSAxXTtcbiAgICBjb25zdCBpbnB1dEVsZW1lbnQ6IGFueSA9IGV2ZW50LnRhcmdldCA/IGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50IDogZXZlbnQ7XG4gICAgb2JqW2xhc3RLZXldID0gaW5wdXRFbGVtZW50Py50eXBlID09PSAnY2hlY2tib3gnID8gaW5wdXRFbGVtZW50LmNoZWNrZWQgOiBpbnB1dEVsZW1lbnQudmFsdWUgPyBpbnB1dEVsZW1lbnQudmFsdWUgOiBpbnB1dEVsZW1lbnQ7XG4gICAgaWYgKGlzVHJhbnNsYXRlKSB7XG4gICAgICAvLyBSZWZyZXNoIHRoZSBib29rXG4gICAgICB0aGlzLmJvb2suc2V0KHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLmdldEJvb2soKSk7XG4gICAgICAvL1NLUzI4SlVMMjUgV29yayB3aXRoIGEgbXV0YWJsZSBjb3B5IG9mIHRoZSBzaWduYWwgdmFsdWVcbiAgICAgIGNvbnN0IGN1cnJlbnRCb29rID0gdGhpcy5ib29rKCk7XG4gICAgICBjb25zdCB0cmFuc2xhdGlvbk1hcCA9IGN1cnJlbnRCb29rLnRyYW5zbGF0aW9uTWFwIHx8IHt9O1xuICAgICAgY29uc3QgY3VycmVudExhbmcgPSB0aGlzLnRyYW5zbGF0aW9uU2VydmljZS5nZXRGb3JtQnVpbGRlckxhbmd1YWdlKCk7XG4gICAgICAvLyBJbml0aWFsaXplIG5lc3RlZCBzdHJ1Y3R1cmUgc2FmZWx5XG4gICAgICBpZiAoIXRyYW5zbGF0aW9uTWFwW2N1cnJlbnRMYW5nXSkgdHJhbnNsYXRpb25NYXBbY3VycmVudExhbmddID0ge307XG4gICAgICBpZiAoIXRyYW5zbGF0aW9uTWFwW2N1cnJlbnRMYW5nXVtvYmoudW5pcXVlSWRlbnRpZmllcl0pIHRyYW5zbGF0aW9uTWFwW2N1cnJlbnRMYW5nXVtvYmoudW5pcXVlSWRlbnRpZmllcl0gPSB7fTtcbiAgICAgIC8vIFNldCB0aGUgdHJhbnNsYXRlZCBpbnB1dFxuICAgICAgdHJhbnNsYXRpb25NYXBbY3VycmVudExhbmddW29iai51bmlxdWVJZGVudGlmaWVyXVtsYXN0S2V5XSA9IGlucHV0RWxlbWVudDtcbiAgICAgIC8vU0tTMjhKVUwyNSBVcGRhdGUgdGhlIGJvb2sgb2JqZWN0IGFuZCByZS1zZXQgdGhlIHNpZ25hbFxuICAgICAgY3VycmVudEJvb2sudHJhbnNsYXRpb25NYXAgPSB0cmFuc2xhdGlvbk1hcDtcbiAgICAgIGlmKGN1cnJlbnRMYW5nID09PSAnZW4nKXtcbiAgICAgICAgdGhpcy50cmFuc2xhdGlvblNlcnZpY2UudXBkYXRlVHJhbnNsYXRpb25zKHRyYW5zbGF0aW9uTWFwKVxuICAgICAgfVxuICAgICAgdGhpcy5ib29rLnNldChjdXJyZW50Qm9vayk7XG4gICAgICAvLyBPcHRpb25hbGx5IGluZm9ybSB0aGUgc2VydmljZVxuICAgICAgdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UudXBkYXRlQm9vayhjdXJyZW50Qm9vayk7XG4gICAgfSAgICBcbiAgICBpZiAoa2V5UGF0aCA9PT0gJ3N1bW1hcnlDb2x1bW4nKSB7XG4gICAgICBpZiAob2JqWydzdW1tYXJ5Um93J10gPT09IHRydWUpIHtcbiAgICAgICAgb2JqWydzdW1tYXJ5Um93J10gPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmIChpbnB1dEVsZW1lbnQuY2hlY2tlZCA9PT0gdHJ1ZSkge1xuICAgICAgICBvYmpbJ2ZsZFR5cGUnXSA9ICdjYWxjdWxhdGlvbic7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvYmpbJ2ZsZFR5cGUnXSA9ICdUZXh0JztcbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgaWYgKGtleVBhdGggPT09ICdzdW1tYXJ5Um93Jykge1xuICAgICAgaWYgKG9ialsnc3VtbWFyeUNvbHVtbiddID09PSB0cnVlKSB7XG4gICAgICAgIG9ialsnc3VtbWFyeUNvbHVtbiddID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoaW5wdXRFbGVtZW50LmNoZWNrZWQgPT09IHRydWUpIHtcbiAgICAgICAgb2JqWydmbGRUeXBlJ10gPSAnY2FsY3VsYXRpb24nO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb2JqWydmbGRUeXBlJ10gPSAnVGV4dCc7XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50LnVwZGF0ZShlbCA9PiAoe1xuICAgICAgLi4uZWwsXG4gICAgICBbdGFyZ2V0QXJyYXlQYXRoXTogdGFyZ2V0QXJyYXlcbiAgICB9KSk7XG4gICAgXG4gICAgdGhpcy51cGRhdGVFbGVtZW50KHRoaXMuc2VsZWN0ZWRFbGVtZW50KCkpO1xuICB9XG5cbiAgZ2V0RGF0YUJ5UGF0aChwYXRoOiBzdHJpbmcpOiBhbnkge1xuICAgIHJldHVybiBwYXRoLnNwbGl0KCcuJykucmVkdWNlKChvYmosIGtleSkgPT4gb2JqPy5ba2V5XSwgdGhpcy5zZWxlY3RlZEVsZW1lbnQoKSk7XG4gIH1cblxuICBmbGlwSG9yaXpvbnRhbCgpIHtcbiAgICB0aGlzLnRyYW5zZm9ybS51cGRhdGUodCA9PiAoeyAuLi50LCBmbGlwSDogIXQuZmxpcEggfSkpO1xuICB9XG5cbiAgZmxpcFZlcnRpY2FsKCkge1xuICAgIHRoaXMudHJhbnNmb3JtLnVwZGF0ZSh0ID0+ICh7IC4uLnQsIGZsaXBWOiAhdC5mbGlwViB9KSk7XG4gIH1cblxuICByZXNldEltYWdlKCkge1xuICAgIHRoaXMuY2FudmFzUm90YXRpb24uc2V0KDApO1xuICAgIHRoaXMuY3JvcHBlci5zZXQodW5kZWZpbmVkKTtcbiAgICB0aGlzLnRyYW5zZm9ybS5zZXQoe1xuICAgICAgdHJhbnNsYXRlVW5pdDogJ3B4JyxcbiAgICAgIHNjYWxlOiAxLFxuICAgICAgcm90YXRlOiAwLFxuICAgICAgZmxpcEg6IGZhbHNlLFxuICAgICAgZmxpcFY6IGZhbHNlLFxuICAgICAgdHJhbnNsYXRlSDogMCxcbiAgICAgIHRyYW5zbGF0ZVY6IDBcbiAgICB9KTtcbiAgfVxuXG4gIHpvb21PdXQoKSB7XG4gICAgdGhpcy50cmFuc2Zvcm0udXBkYXRlKHQgPT4gKHsgLi4udCwgc2NhbGU6IHQuc2NhbGUhIC0gMC4xIH0pKTtcbiAgfVxuXG4gIHpvb21JbigpIHtcbiAgICB0aGlzLnRyYW5zZm9ybS51cGRhdGUodCA9PiAoeyAuLi50LCBzY2FsZTogdC5zY2FsZSEgKyAwLjEgfSkpO1xuICB9XG5cbiAgcm90YXRlTGVmdCgpIHtcbiAgICB0aGlzLmxvYWRpbmcuc2V0KHRydWUpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5jYW52YXNSb3RhdGlvbi51cGRhdGUoYyA9PiBjIC0gMSk7XG4gICAgICB0aGlzLmZsaXBBZnRlclJvdGF0ZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgcm90YXRlUmlnaHQoKSB7XG4gICAgdGhpcy5sb2FkaW5nLnNldCh0cnVlKTtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuY2FudmFzUm90YXRpb24udXBkYXRlKGMgPT4gYyArIDEpO1xuICAgICAgdGhpcy5mbGlwQWZ0ZXJSb3RhdGUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIG1vdmVMZWZ0KCkge1xuICAgIHRoaXMudHJhbnNmb3JtLnVwZGF0ZSh0ID0+ICh7IC4uLnQsIHRyYW5zbGF0ZUg6IHQudHJhbnNsYXRlSCEgLSAxIH0pKTtcbiAgfVxuXG4gIG1vdmVSaWdodCgpIHtcbiAgICB0aGlzLnRyYW5zZm9ybS51cGRhdGUodCA9PiAoeyAuLi50LCB0cmFuc2xhdGVIOiB0LnRyYW5zbGF0ZUghICsgMSB9KSk7XG4gIH1cblxuICBtb3ZlRG93bigpIHtcbiAgICB0aGlzLnRyYW5zZm9ybS51cGRhdGUodCA9PiAoeyAuLi50LCB0cmFuc2xhdGVWOiB0LnRyYW5zbGF0ZVYhICsgMSB9KSk7XG4gIH1cblxuICBtb3ZlVXAoKSB7XG4gICAgdGhpcy50cmFuc2Zvcm0udXBkYXRlKHQgPT4gKHsgLi4udCwgdHJhbnNsYXRlVjogdC50cmFuc2xhdGVWISAtIDEgfSkpO1xuICB9XG5cbiAgcHJpdmF0ZSBmbGlwQWZ0ZXJSb3RhdGUoKSB7XG4gICAgdGhpcy50cmFuc2Zvcm0udXBkYXRlKHQgPT4gKHtcbiAgICAgIC4uLnQsXG4gICAgICBmbGlwSDogdC5mbGlwVixcbiAgICAgIGZsaXBWOiB0LmZsaXBILFxuICAgICAgdHJhbnNsYXRlSDogMCxcbiAgICAgIHRyYW5zbGF0ZVY6IDBcbiAgICB9KSk7XG4gIH1cblxuICBhc3luYyBpbWFnZUNyb3BwZWQoZXZlbnQ6IGFueSkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBiYXNlNjQgPSBhd2FpdCB0aGlzLmNvbnZlcnRCbG9iVG9CYXNlNjQoZXZlbnQub2JqZWN0VXJsKTtcbiAgICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50LnVwZGF0ZShlbCA9PiAoeyAuLi5lbCwgaW1hZ2VEYXRhOiBiYXNlNjQgfSkpO1xuICAgICAgYXdhaXQgdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UuZWxlbWVudFVwZGF0ZSh0aGlzLnNlbGVjdGVkRWxlbWVudEluZGV4KCksIHRoaXMuc2VsZWN0ZWRFbGVtZW50KCkpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBjb25zb2xlLmVycm9yKFwiRXJyb3IgaW4gaW1hZ2VDcm9wcGVkOlwiLCBlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgY3JvcHBlclJlYWR5KHNvdXJjZUltYWdlRGltZW5zaW9uczogRGltZW5zaW9ucykge1xuICAgIHRoaXMubG9hZGluZy5zZXQoZmFsc2UpO1xuICB9XG5cbiAgY29udmVydEJsb2JUb0Jhc2U2NChvYmplY3RVcmw6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgcmV0dXJuIGZldGNoKG9iamVjdFVybClcbiAgICAgIC50aGVuKHJlc3BvbnNlID0+IHJlc3BvbnNlLmJsb2IoKSlcbiAgICAgIC50aGVuKGJsb2IgPT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgICAgICAgcmVhZGVyLnJlYWRBc0RhdGFVUkwoYmxvYik7XG4gICAgICAgICAgcmVhZGVyLm9ubG9hZGVuZCA9ICgpID0+IHJlc29sdmUocmVhZGVyLnJlc3VsdCBhcyBzdHJpbmcpO1xuICAgICAgICAgIHJlYWRlci5vbmVycm9yID0gZXJyb3IgPT4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgfVxuXG4gIGNoaWxkRXZlbnRDYXB0dXJlKGV2ZW50OiBhbnkpIHtcbiAgICB0aGlzLnNlbGVjdGVkRWxlbWVudC51cGRhdGUoZWwgPT4gKHtcbiAgICAgIC4uLmVsLFxuICAgICAgcWJSZWZlcmVuY2U6IGV2ZW50LnZhbHVlT2JqPy5uYW1lLFxuICAgICAgcWJSZWZlcmVuY2VRdWVzdGlvbnM6IGV2ZW50LnZhbHVlT2JqPy5qc29uQm9keVxuICAgIH0pKTtcbiAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5lbGVtZW50VXBkYXRlKHRoaXMuc2VsZWN0ZWRFbGVtZW50SW5kZXgoKSwgdGhpcy5zZWxlY3RlZEVsZW1lbnQoKSk7XG4gIH1cblxuICBsaW5rVG9nZ2xlRHJvcGRvd24oZXZlbnQ6IEV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5pc0xpbmtEcm9wZG93bk9wZW4udXBkYXRlKG9wZW4gPT4gIW9wZW4pO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6Y2xpY2snLCBbJyRldmVudCddKVxuICBvbkNsaWNrT3V0c2lkZShldmVudDogRXZlbnQpIHtcbiAgICBpZiAodGhpcy5kcm9wZG93biAmJiAhdGhpcy5kcm9wZG93bi5uYXRpdmVFbGVtZW50LmNvbnRhaW5zKGV2ZW50LnRhcmdldCkpIHtcbiAgICAgIHRoaXMuaXNMaW5rRHJvcGRvd25PcGVuLnNldChmYWxzZSk7XG4gICAgfVxuICB9XG5cbiAgb25EcmFnU3RhcnQoZXZlbnQ6IERyYWdFdmVudCwgaWQ6IHN0cmluZykge1xuICAgIHRoaXMuZHJhZ2dlZElkID0gaWQ7XG4gICAgZXZlbnQuZGF0YVRyYW5zZmVyIS5lZmZlY3RBbGxvd2VkID0gXCJtb3ZlXCI7XG4gIH1cblxuICAvLyBBUC0yOE1BUjI1IFByZXZlbnQgZGVmYXVsdCBiZWhhdmlvciB0byBhbGxvdyBkcm9wXG4gIG9uRHJhZ092ZXIoZXZlbnQ6IERyYWdFdmVudCkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gIH1cblxuICAvLyBBUC0yOE1BUjI1IFN3YXAgdGhlIGRyYWdnZWQgaXRlbSB3aXRoIHRoZSBkcm9wcGVkIHBvc2l0aW9uXG4gIG9uRHJvcChldmVudDogRHJhZ0V2ZW50LCBrZXk6IHN0cmluZykge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgY29uc3QgdGFyZ2V0SWQgPSAoZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50KS5jbG9zZXN0KFwiLm9wdGlvbi1pdGVtc1wiKT8uZ2V0QXR0cmlidXRlKFwiZGF0YS1pZFwiKTtcbiAgICBpZiAodGhpcy5kcmFnZ2VkSWQgJiYgdGFyZ2V0SWQgJiYgdGhpcy5kcmFnZ2VkSWQgIT09IHRhcmdldElkKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkRWxlbWVudC51cGRhdGUoZWwgPT4ge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gWy4uLmVsW2tleV1dO1xuICAgICAgICBjb25zdCBkcmFnZ2VkSW5kZXggPSBvcHRpb25zLmZpbmRJbmRleChvcHRpb24gPT4gb3B0aW9uLmlkID09PSB0aGlzLmRyYWdnZWRJZCk7XG4gICAgICAgIGNvbnN0IHRhcmdldEluZGV4ID0gb3B0aW9ucy5maW5kSW5kZXgob3B0aW9uID0+IG9wdGlvbi5pZCA9PT0gdGFyZ2V0SWQpO1xuICAgICAgICBpZiAoZHJhZ2dlZEluZGV4ICE9PSAtMSAmJiB0YXJnZXRJbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICBbb3B0aW9uc1tkcmFnZ2VkSW5kZXhdLCBvcHRpb25zW3RhcmdldEluZGV4XV0gPSBbb3B0aW9uc1t0YXJnZXRJbmRleF0sIG9wdGlvbnNbZHJhZ2dlZEluZGV4XV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgLi4uZWwsIFtrZXldOiBvcHRpb25zIH07XG4gICAgICB9KTtcbiAgICB9XG4gICAgdGhpcy5kcmFnZ2VkSWQgPSBudWxsO1xuICB9XG5cbiAgZHVwbGljYXRlRmllbGQoZWxlbWVudDogYW55KSB7XG4gICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5nZXRFbGVtZW50cygpO1xuICAgIGNvbnN0IGNvcHkgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGVsZW1lbnQpKTtcbiAgICAvL0FQLTE4QVBSMjUgR2VuZXJhdGUgYSBuZXcgSUQgdXNpbmcgdGhlIHNlcnZpY2UncyBtZXRob2RcbiAgICBjb3B5LmlkID0gdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UuYWRkRWxlbWVudFdpdGhJZCgpO1xuICAgIC8vY29weS51dWlkID0gY29weS5pZDsgXG4gICAgLy8gQVAtMThBUFIyNSBTZXQgdGhlIHF1ZXN0aW9uTnVtYmVyIHRvIHRoZSBuZXh0IGF2YWlsYWJsZSBudW1iZXJcbiAgICBjb3B5LnF1ZXN0aW9uTnVtYmVyID0gZWxlbWVudHMubGVuZ3RoICsgMTtcbiAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5hZGRFbGVtZW50KGNvcHkpO1xuICB9XG5cbiAgcHJpdmF0ZSBkcmFnZ2VkSWQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICB1cGRhdGVCb29rU3VidGV4dChrZXk6ICdlbmRwb2ludCcgfCAndmFyaWFibGUnIHwgJ2RlZmF1bHRGaWVsZCcsIHZhbHVlOiBzdHJpbmcpIHtcbiAgICB0aGlzLmJvb2tTdWJ0ZXh0LnVwZGF0ZSgocykgPT4gKHtcbiAgICAgIC4uLnMsXG4gICAgICBba2V5XTogdmFsdWUsXG4gICAgfSkpO1xuICB9ICBcbiAgdHJhY2tCeVByb3AoaW5kZXg6IG51bWJlciwgaXRlbTogYW55KTogYW55IHtcbiAgICByZXR1cm4gaXRlbT8ua2V5ID8/IGluZGV4O1xuICB9XG4gIFxuICBnZXRPcHRpbWl6ZWRTdWJQcm9wVmFsdWUoc3ViUHJvcDogYW55KTogc3RyaW5nIHtcbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5zZWxlY3RlZEVsZW1lbnQoKTtcbiAgICBpZiAodGhpcy5zZWxlY3RlZEVsZW1lbnQoKT8udHlwZSA9PT0gJ1RhYmxlJyAmJiAoc3ViUHJvcC50YXJnZXRBcnJheSB8fCBzdWJQcm9wLmlzVGFibGVDb2x1bW4pKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRWYWx1ZUJ5QXJyYXlQYXRoKFxuICAgICAgICBzdWJQcm9wLnRhcmdldEFycmF5LCBcbiAgICAgICAgc3ViUHJvcC50YXJnZXRBcnJheUtleSwgXG4gICAgICAgIHRoaXMuc2VsZWN0Q29sdW1uKCksIFxuICAgICAgICBzdWJQcm9wLmtleSwgXG4gICAgICAgIHN1YlByb3AuaXNUYWJsZUNvbHVtblxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZ2V0VmFsdWVCeVBhdGgoc3ViUHJvcC5rZXksIGVsZW1lbnQpO1xuICB9XG4vLyBTS1MzMUpVTDI1IGRlZmF1bHQgbGFuZ3VhZ2UgdGV4dCBjb3B5IHRvIGNsaXBib2FyZFxuICBjb3B5VG9DbGlwYm9hcmQodGV4dDogc3RyaW5nIHwgbnVsbCk6IHZvaWQge1xuICAgIGlmICh0ZXh0ICYmIG5hdmlnYXRvci5jbGlwYm9hcmQpIHtcbiAgICAgIG5hdmlnYXRvci5jbGlwYm9hcmQud3JpdGVUZXh0KHRleHQpLnRoZW4oKCkgPT4ge1xuICAgICAgICB0aGlzLmNvcGllZCA9IHRydWU7XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTsgLy8gbWFudWFsbHkgdHJpZ2dlciB1cGRhdGVcbiAgXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIHRoaXMuY29waWVkID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpOyAvLyB1cGRhdGUgYWdhaW4gd2hlbiBoaWRpbmdcbiAgICAgICAgfSwgMTUwMCk7XG4gICAgICB9KS5jYXRjaChlcnIgPT4ge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gY29weTonLCBlcnIpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG59IiwiPCEtLSBBUCAyMkpBTjI1IC0gRmllbGQgYW5kIEVsZW1lbnQgUHJvcGVydGllcyAtLT5cblxuPGRpdiBjbGFzcz1cImNvbnRhaW5lclwiPlxuICA8ZGl2IGNsYXNzPVwidGFic1wiPlxuICAgIDxkaXYgY2xhc3M9XCJ0YWJcIiBbbmdDbGFzc109XCJ7J2FjdGl2ZSc6IGFjdGl2ZVRhYigpID09PSAnYXR0cmlidXRlcyd9XCIgKGNsaWNrKT1cInNldEFjdGl2ZVRhYignYXR0cmlidXRlcycpXCI+e3sgJ0FUVFJJQlVURVMnIHwgbnh0Q3VzdG9tVHJhbnNsYXRlIDogJ0F0dHJpYnV0ZXMnIH19PC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cInRhYlwiIFtuZ0NsYXNzXT1cInsnYWN0aXZlJzogYWN0aXZlVGFiKCkgPT09ICdwcm9wZXJ0eSd9XCIgKGNsaWNrKT1cInNldEFjdGl2ZVRhYigncHJvcGVydHknKVwiPnt7ICdQUk9QRVJUWScgfCBueHRDdXN0b21UcmFuc2xhdGUgOiAnUHJvcGVydHknIH19PC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cInRhYlwiIFtuZ0NsYXNzXT1cInsnYWN0aXZlJzogYWN0aXZlVGFiKCkgPT09ICdhcHBlYXJhbmNlJ31cIiAoY2xpY2spPVwic2V0QWN0aXZlVGFiKCdhcHBlYXJhbmNlJylcIj57eyAnQVBQRUFSQU5DRScgfCBueHRDdXN0b21UcmFuc2xhdGUgOiAnQXBwZWFyYW5jZScgfX08L2Rpdj5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJ0YWItY29udGVudFwiICpuZ0lmPVwiYWN0aXZlVGFiKCkgPT09ICdhdHRyaWJ1dGVzJ1wiPlxuICAgIEBkZWZlciAod2hlbiBnZXRQcm9wZXJ0aWVzKCkpIHtcbiAgICAgIDxkaXY+XG4gICAgICAgIEBkZWZlciAod2hlbiBzZWxlY3RlZEVsZW1lbnQoKT8udHlwZSA9PT0gJ0ltYWdlJykge1xuICAgICAgICAgIDxpbWFnZS1jcm9wcGVyXG4gICAgICAgICAgICAqbmdJZj1cInNlbGVjdGVkRWxlbWVudCgpLmltYWdlRGF0YVwiXG4gICAgICAgICAgICBbaW1hZ2VCYXNlNjRdPVwic2VsZWN0ZWRFbGVtZW50KCkub3JnSW1hZ2VEYXRhXCJcbiAgICAgICAgICAgIFtkaXNhYmxlZF09XCJmYWxzZVwiXG4gICAgICAgICAgICBbYWxpZ25JbWFnZV09XCJhbGlnbkltYWdlXCJcbiAgICAgICAgICAgIFtyb3VuZENyb3BwZXJdPVwicm91bmRDcm9wcGVyXCJcbiAgICAgICAgICAgIFtiYWNrZ3JvdW5kQ29sb3JdPVwiJ3doaXRlJ1wiXG4gICAgICAgICAgICBpbWFnZUFsdFRleHQ9XCJBbHRlcm5hdGl2ZSBpbWFnZSB0ZXh0XCJcbiAgICAgICAgICAgIFthbGxvd01vdmVJbWFnZV09XCJmYWxzZVwiXG4gICAgICAgICAgICBbaGlkZVJlc2l6ZVNxdWFyZXNdPVwiZmFsc2VcIlxuICAgICAgICAgICAgW2NhbnZhc1JvdGF0aW9uXT1cImNhbnZhc1JvdGF0aW9uKClcIlxuICAgICAgICAgICAgW2FzcGVjdFJhdGlvXT1cImFzcGVjdFJhdGlvXCJcbiAgICAgICAgICAgIFtjb250YWluV2l0aGluQXNwZWN0UmF0aW9dPVwiZmFsc2VcIlxuICAgICAgICAgICAgW21haW50YWluQXNwZWN0UmF0aW9dPVwiZmFsc2VcIlxuICAgICAgICAgICAgW2Nyb3BwZXJTdGF0aWNXaWR0aF09XCJjcm9wcGVyU3RhdGljV2lkdGhcIlxuICAgICAgICAgICAgW2Nyb3BwZXJTdGF0aWNIZWlnaHRdPVwiY3JvcHBlclN0YXRpY0hlaWdodFwiXG4gICAgICAgICAgICBbY3JvcHBlck1pbldpZHRoXT1cImNyb3BwZXJNaW5XaWR0aFwiXG4gICAgICAgICAgICBbY3JvcHBlck1pbkhlaWdodF09XCJjcm9wcGVyTWluSGVpZ2h0XCJcbiAgICAgICAgICAgIFtjcm9wcGVyTWF4V2lkdGhdPVwiY3JvcHBlck1heFdpZHRoXCJcbiAgICAgICAgICAgIFtjcm9wcGVyTWF4SGVpZ2h0XT1cImNyb3BwZXJNYXhIZWlnaHRcIlxuICAgICAgICAgICAgW3Jlc2V0Q3JvcE9uQXNwZWN0UmF0aW9DaGFuZ2VdPVwidHJ1ZVwiXG4gICAgICAgICAgICBbKGNyb3BwZXIpXT1cImNyb3BwZXJcIlxuICAgICAgICAgICAgWyh0cmFuc2Zvcm0pXT1cInRyYW5zZm9ybVwiXG4gICAgICAgICAgICBbb25seVNjYWxlRG93bl09XCJ0cnVlXCJcbiAgICAgICAgICAgIG91dHB1dD1cImJsb2JcIlxuICAgICAgICAgICAgZm9ybWF0PVwicG5nXCJcbiAgICAgICAgICAgIChpbWFnZUNyb3BwZWQpPVwiaW1hZ2VDcm9wcGVkKCRldmVudClcIlxuICAgICAgICAgICAgKGNyb3BwZXJSZWFkeSk9XCJjcm9wcGVyUmVhZHkoJGV2ZW50KVwiXG4gICAgICAgICAgPjwvaW1hZ2UtY3JvcHBlcj5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwic2VsZWN0ZWRFbGVtZW50KCkuaW1hZ2VEYXRhXCIgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBnYXA6IDJweDtcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjdXJzb3ItcG9pbnRlciBsb2dvLWljb25cIiAoY2xpY2spPVwicm90YXRlTGVmdCgpXCIgdGl0bGU9XCJ7eyAnUk9UQVRFX0xFRlQnIHwgbnh0Q3VzdG9tVHJhbnNsYXRlIDogJ1JvdGF0ZSBMZWZ0JyB9fVwiPuKfsjwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImN1cnNvci1wb2ludGVyIGxvZ28taWNvblwiIChjbGljayk9XCJyb3RhdGVSaWdodCgpXCIgdGl0bGU9XCJ7eyAnUk9UQVRFX1JJR0hUJyB8IG54dEN1c3RvbVRyYW5zbGF0ZSA6ICdSb3RhdGUgUmlnaHQnIH19XCI+4p+zPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3Vyc29yLXBvaW50ZXIgbG9nby1pY29uXCIgKGNsaWNrKT1cInpvb21PdXQoKVwiIHRpdGxlPVwie3sgJ1pPT01fT1VUJyB8IG54dEN1c3RvbVRyYW5zbGF0ZSA6ICdab29tIE91dCcgfX1cIj4tPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3Vyc29yLXBvaW50ZXIgbG9nby1pY29uXCIgKGNsaWNrKT1cInpvb21JbigpXCIgdGl0bGU9XCJ7eyAnWk9PTV9JTicgfCBueHRDdXN0b21UcmFuc2xhdGUgOiAnWm9vbSBJbicgfX1cIj4rPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3Vyc29yLXBvaW50ZXIgbG9nby1pY29uXCIgKGNsaWNrKT1cIm1vdmVMZWZ0KClcIiB0aXRsZT1cInt7ICdNT1ZFX0xFRlQnIHwgbnh0Q3VzdG9tVHJhbnNsYXRlIDogJ01vdmUgTGVmdCcgfX1cIj7ihpA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjdXJzb3ItcG9pbnRlciBsb2dvLWljb25cIiAoY2xpY2spPVwibW92ZVJpZ2h0KClcIiB0aXRsZT1cInt7ICdNT1ZFX1JJR0hUJyB8IG54dEN1c3RvbVRyYW5zbGF0ZSA6ICdNb3ZlIFJpZ2h0JyB9fVwiPuKGkjwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImN1cnNvci1wb2ludGVyIGxvZ28taWNvblwiIChjbGljayk9XCJtb3ZlVXAoKVwiIHRpdGxlPVwie3sgJ01PVkVfVVAnIHwgbnh0Q3VzdG9tVHJhbnNsYXRlIDogJ01vdmUgVXAnIH19XCI+4oaRPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3Vyc29yLXBvaW50ZXIgbG9nby1pY29uXCIgKGNsaWNrKT1cIm1vdmVEb3duKClcIiB0aXRsZT1cInt7ICdNT1ZFX0RPV04nIHwgbnh0Q3VzdG9tVHJhbnNsYXRlIDogJ01vdmUgRG93bicgfX1cIj7ihpM8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjdXJzb3ItcG9pbnRlciBsb2dvLWljb25cIiAoY2xpY2spPVwiZmxpcEhvcml6b250YWwoKVwiIFtuZ0NsYXNzXT1cInsnZW5hYmxlZCc6IHRyYW5zZm9ybSgpLmZsaXBIfVwiIHRpdGxlPVwie3sgJ0ZMSVBfSE9SSVpPTlRBTExZJyB8IG54dEN1c3RvbVRyYW5zbGF0ZSA6ICdGbGlwIEhvcml6b250YWxseScgfX1cIj7ihpQ8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjdXJzb3ItcG9pbnRlciBsb2dvLWljb25cIiAoY2xpY2spPVwiZmxpcFZlcnRpY2FsKClcIiBbbmdDbGFzc109XCJ7J2VuYWJsZWQnOiB0cmFuc2Zvcm0oKS5mbGlwVn1cIiB0aXRsZT1cInt7ICdGTElQX1ZFUlRJQ0FMTFknIHwgbnh0Q3VzdG9tVHJhbnNsYXRlIDogJ0ZsaXAgVmVydGljYWxseScgfX1cIj7ihpU8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjdXJzb3ItcG9pbnRlciBsb2dvLWljb25cIiAoY2xpY2spPVwicmVzZXRJbWFnZSgpXCIgdGl0bGU9XCJ7eyAnUkVTRVQnIHwgbnh0Q3VzdG9tVHJhbnNsYXRlIDogJ1Jlc2V0JyB9fVwiPsOXPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgICAgPGRpdiAqbmdJZj1cInNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnQm9vaydcIj5cbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJ0ZXh0LXNtXCI+e3sgJ1NFQVJDSF9CT09LJyB8IG54dEN1c3RvbVRyYW5zbGF0ZSA6ICdTZWFyY2ggQm9vaycgfX08L2xhYmVsPlxuICAgICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBnYXA6IDJweDsgYWxpZ24taXRlbXM6IGNlbnRlcjsganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XCI+XG4gICAgICAgICAgICA8bnh0LXNlYXJjaC1ib3hcbiAgICAgICAgICAgICAgW3F1ZXN0aW9uXT1cInNlbGVjdGVkRWxlbWVudCgpXCJcbiAgICAgICAgICAgICAgW2FwaU1ldGFdPVwiYm9va1N1YnRleHQoKVwiXG4gICAgICAgICAgICAgIFtwbGFjZUhvbGRlclRleHRdPVwiJ1NFQVJDSCcgfCBueHRDdXN0b21UcmFuc2xhdGUgOiAnU2VhcmNoLi4uJ1wiXG4gICAgICAgICAgICAgIChzZWFyY2hWYWx1ZUNoYW5nZSk9XCJjaGlsZEV2ZW50Q2FwdHVyZSgkZXZlbnQudmFsdWUpXCJcbiAgICAgICAgICAgID48L254dC1zZWFyY2gtYm94PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxpbmstaWNvblwiPlxuICAgICAgICAgICAgICA8c3ZnIChjbGljayk9XCJsaW5rVG9nZ2xlRHJvcGRvd24oJGV2ZW50KVwiIGZpbGw9XCIjMDAwMDAwXCIgdmVyc2lvbj1cIjEuMVwiIGlkPVwiQ2FwYV8xXCJcbiAgICAgICAgICAgICAgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHdpZHRoPVwiMjRweFwiIGhlaWdodD1cIjI0cHhcIlxuICAgICAgICAgICAgICB2aWV3Qm94PVwiMCAwIDQ1MCA0NTBcIiB4bWw6c3BhY2U9XCJwcmVzZXJ2ZVwiPlxuICAgICAgICAgICAgICA8Zz5cbiAgICAgICAgICAgICAgICA8Zz5cbiAgICAgICAgICAgICAgICAgIDxnPlxuICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTMxOC4xNSwyMzAuMTk1bDc3LjkzNC03Ny45MzdjMzEuODk0LTMxLjg5MiwzMS44OTQtODMuNzgyLTAuMDA0LTExNS42NzRsLTEyLjY2LTEyLjY2XG4gICAgICAgICAgYy0zMS44OTMtMzEuODk2LTgzLjc4LTMxLjg5Ni0xMTUuNjc0LTAuMDA0bC03Ny45MzcsNzcuOTM0Yy0xNy41ODgsMTcuNTg4LTI1LjQ1Nyw0MS4yNjQtMjMuNjQ2LDY0LjMxMVxuICAgICAgICAgIGMtMjMuMDQ1LTEuODEzLTQ2LjcyMiw2LjA1Ni02NC4zMDgsMjMuNjQ3TDIzLjkyLDI2Ny43NDhjLTMxLjg5NCwzMS44ODktMzEuODk0LDgzLjc3OSwwLDExNS42NzRsMTIuNjY0LDEyLjY2MlxuICAgICAgICAgIGMzMS44OTMsMzEuODkzLDgzLjc4MywzMS44OTMsMTE1LjY3NCwwbDc3LjkzNS03Ny45MzZjMTcuNTkyLTE3LjU5LDI1LjQ1OS00MS4yNjYsMjMuNjQ3LTY0LjMwOVxuICAgICAgICAgIEMyNzYuODg0LDI1NS42NTQsMzAwLjU2LDI0Ny43ODMsMzE4LjE1LDIzMC4xOTV6IE0yMDIuNjUzLDI5MC42MDVsLTc3LjkzNiw3Ny45MzhjLTE2LjcwNSwxNi43MDMtNDMuODg5LDE2LjcwMy02MC41OSwwXG4gICAgICAgICAgbC0xMi42NjYtMTIuNjY2Yy0xNi43MDUtMTYuNzAxLTE2LjcwMy00My44ODUsMC02MC41OTRsNzcuOTM2LTc3LjkzMmMxNC4xNC0xNC4xNDEsMzUuNzc5LTE2LjMwNiw1Mi4yMjYtNi41MTZsLTMyLjMwMiwzMi4zMDdcbiAgICAgICAgICBjLTcuNjA2LDcuNjA0LTcuNjA2LDE5LjkzOCwwLDI3LjU0MWM3LjYwNSw3LjYwNywxOS45MzcsNy42MDcsMjcuNTQxLDBsMzIuMzA2LTMyLjMwM1xuICAgICAgICAgIEMyMTguOTU5LDI1NC44MjgsMjE2Ljc5NSwyNzYuNDY5LDIwMi42NTMsMjkwLjYwNXogTTIzOC4zODIsMjA5LjE2OWwzMi4yOTktMzIuMzA2YzcuNjA4LTcuNjAyLDcuNjA4LTE5LjkzNSwwLTI3LjUzOFxuICAgICAgICAgIGMtNy42MDQtNy42MS0xOS45MzYtNy42MS0yNy41NDEtMC4wMDRsLTMyLjMwMywzMi4zMDNjLTkuNzkxLTE2LjQ0Ni03LjYyNy0zOC4wODcsNi41MTQtNTIuMjI2bDc3LjkzNS03Ny45MzVcbiAgICAgICAgICBjMTYuNzA3LTE2LjcwNyw0My44OS0xNi43MDcsNjAuNTk0LDBsMTIuNjY0LDEyLjY2NGMxNi43MDUsMTYuNzA1LDE2LjcwNSw0My44ODYsMCw2MC41OTFsLTc3LjkzNiw3Ny45MzdcbiAgICAgICAgICBDMjc2LjQ2OCwyMTYuNzk3LDI1NC44MjgsMjE4Ljk1OSwyMzguMzgyLDIwOS4xNjl6XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD1cIk0zNDMuNDY2LDI2MS40NjVjLTQ1LjI4NywwLTgyLDM2LjcxMy04Miw4MnMzNi43MTMsODIsODIsODJjNDUuMjg2LDAsODItMzYuNzEzLDgyLTgyUzM4OC43NTMsMjYxLjQ2NSwzNDMuNDY2LDI2MS40NjV6XG4gICAgICAgICAgIE0zNzIuNTA1LDMzMy41NjRsLTU2LjA0Niw1Ni4xMDRjLTAuMjM5LDAuMjM4LTAuNTM2LDAuNDEtMC44NjIsMC40OTZsLTIyLjMxNSw1Ljg1Yy0wLjY0OSwwLjE2OC0xLjM0Ny0wLjAyLTEuODIyLTAuNDk0XG4gICAgICAgICAgYy0wLjQ3Ny0wLjQ3OS0wLjY2Ni0xLjE3Mi0wLjQ5Ni0xLjgyNGw1LjgyNi0yMi4zMThjMC4wODQtMC4zMjYsMC4yNTYtMC42MjcsMC40OTQtMC44NjNsNTYuMDQ3LTU2LjEwNFxuICAgICAgICAgIGMwLjc0Mi0wLjc0MiwxLjk0NS0wLjc0NCwyLjY4OC0wLjAwMmw0LjU0OCw0LjU0MWMwLjczOSwwLjc0LDAuNzQxLDEuOTQzLDAsMi42ODhsLTM3LjQzMywzNy40NzFsNC43MDksNC43MDNsMzcuNDM1LTM3LjQ3MVxuICAgICAgICAgIGMwLjczOS0wLjc0MiwxLjk0LTAuNzQyLDIuNjgyLTAuMDAybDQuNTUsNC41NDFDMzczLjI1LDMzMS42MTcsMzczLjI1LDMzMi44MjIsMzcyLjUwNSwzMzMuNTY0eiBNMzk1LjQ3MiwzMTAuNTc0bC0xNywxNy4wMThcbiAgICAgICAgICBjLTAuNzM5LDAuNzQ0LTEuOTQyLDAuNzQ0LTIuNjg1LDAuMDAybC0xNi40ODktMTYuNDc1Yy0wLjc0NC0wLjc0LTAuNzQ0LTEuOTQzLTAuMDAyLTIuNjg4bDE3LTE3LjAyXG4gICAgICAgICAgYzAuNzQxLTAuNzQsMS45NDQtMC43NCwyLjY4OC0wLjAwMmwxNi40ODcsMTYuNDc3QzM5Ni4yMTYsMzA4LjYyOSwzOTYuMjE2LDMwOS44MzIsMzk1LjQ3MiwzMTAuNTc0elwiIC8+XG4gICAgICAgICAgICAgICAgICA8L2c+XG4gICAgICAgICAgICAgICAgPC9nPlxuICAgICAgICAgICAgICA8L2c+XG4gICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxpbmstZHJvcGRvd24tbWVudVwiICpuZ0lmPVwiaXNMaW5rRHJvcGRvd25PcGVuKClcIiAjZHJvcGRvd24+XG4gICAgICAgICAgICAgICAgPGxhYmVsPnt7ICdFTkRfUE9JTlQnIHwgbnh0Q3VzdG9tVHJhbnNsYXRlIDogJ0VuZHBvaW50JyB9fTo8L2xhYmVsPlxuICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIFtuZ01vZGVsXT1cImJvb2tTdWJ0ZXh0KCkuZW5kcG9pbnRcIiAobmdNb2RlbENoYW5nZSk9XCJ1cGRhdGVCb29rU3VidGV4dCgnZW5kcG9pbnQnLCAkZXZlbnQpXCIgLz5cbiAgICAgICAgICAgICAgICA8bGFiZWw+e3sgJ1ZBUklBQkxFJyB8IG54dEN1c3RvbVRyYW5zbGF0ZSA6ICdWYXJpYWJsZScgfX06PC9sYWJlbD5cbiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBbbmdNb2RlbF09XCJib29rU3VidGV4dCgpLnZhcmlhYmxlXCIgKG5nTW9kZWxDaGFuZ2UpPVwidXBkYXRlQm9va1N1YnRleHQoJ3ZhcmlhYmxlJywgJGV2ZW50KVwiIC8+XG4gICAgICAgICAgICAgICAgPGxhYmVsPnt7ICdGSUVMRCcgfCBueHRDdXN0b21UcmFuc2xhdGUgOiAnRmllbGQnIH19OjwvbGFiZWw+XG4gICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgW25nTW9kZWxdPVwiZmllbGRBc1N0cmluZygpXCIgKG5nTW9kZWxDaGFuZ2UpPVwidXBkYXRlRmllbGQoJGV2ZW50KVwiIC8+XG4gICAgICAgICAgICAgICAgPGxhYmVsPnt7ICdERUZBVUxUX0ZJRUxEJyB8IG54dEN1c3RvbVRyYW5zbGF0ZSA6ICdEZWZhdWx0IEZpZWxkJyB9fTo8L2xhYmVsPlxuICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIFtuZ01vZGVsXT1cImJvb2tTdWJ0ZXh0KCkuZGVmYXVsdEZpZWxkXCIgKG5nTW9kZWxDaGFuZ2UpPVwidXBkYXRlQm9va1N1YnRleHQoJ2RlZmF1bHRGaWVsZCcsICRldmVudClcIiAvPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgcHJvcCBvZiBnZXRQcm9wZXJ0aWVzKCk/LmVsZW1lbnRQcm9wczsgdHJhY2tCeTogdHJhY2tCeVByb3BcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgICAgICAgICAgPGxhYmVsICpuZ0lmPVwicHJvcC50eXBlICE9PSAnY2hlY2tib3gnICYmIHByb3AudHlwZSAhPT0gJ3N1YlF1ZXN0aW9uJ1wiIGNsYXNzPVwidGV4dC1zbVwiPnt7IHByb3AubGFiZWxQYXRoIHwgbnh0Q3VzdG9tVHJhbnNsYXRlIDogcHJvcC5sYWJlbCB9fTwvbGFiZWw+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwicHJvcC5pc1RyYW5zbGF0ZSAmJiBmb3JtQnVpbGRlckxhbmd1YWdlQ29kZSAmJiBmb3JtQnVpbGRlckxhbmd1YWdlQ29kZSAhPT0gJ2VuJ1wiPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiKChzZWxlY3RlZEVsZW1lbnQoKT8udHlwZSA9PT0gJ1RhYmxlJyAmJiAocHJvcC50YXJnZXRBcnJheSB8fCBwcm9wLmlzVGFibGVDb2x1bW4pID8gc2VsZWN0Q29sdW1uKCkgOiBzZWxlY3RlZEVsZW1lbnQoKS5pZCkgKyAnLicgKyBwcm9wLmtleSB8IG54dEN1c3RvbVRyYW5zbGF0ZSA6ICcnIDogJ2Zvcm1CdWlsZGVyJykgYXMgdHJhbnNsYXRlZFwiPlxuICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJ0cmFuc2xhdGVkPy50cmltKClcIiBjbGFzcz1cInRyYW5zbGF0aW9uLWZhbGxiYWNrXCI+XG4gICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDEwcHg7XCI+RGVmYXVsdCAoRW5nbGlzaCk8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZWFkb25seS1ib3hcIiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogOHB4OyBwb3NpdGlvbjogcmVsYXRpdmU7XCI+XG4gICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj57eyB0cmFuc2xhdGVkIH19PC9zcGFuPlxuICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gQ29weSBJY29uIC0tPlxuICAgICAgICAgICAgICAgICAgICA8c3ZnICpuZ0lmPVwiIWNvcGllZFwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJjb3B5VG9DbGlwYm9hcmQodHJhbnNsYXRlZClcIiB3aWR0aD1cIjE2cHhcIiBoZWlnaHQ9XCIxNnB4XCIgdmlld0JveD1cIjAgMCAyNC4wMCAyNC4wMFwiIGZpbGw9XCJub25lXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHRyYW5zZm9ybT1cInJvdGF0ZSgwKVwiPjxnIGlkPVwiU1ZHUmVwb19iZ0NhcnJpZXJcIiBzdHJva2Utd2lkdGg9XCIwXCI+PC9nPjxnIGlkPVwiU1ZHUmVwb190cmFjZXJDYXJyaWVyXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgc3Ryb2tlPVwiI0NDQ0NDQ1wiIHN0cm9rZS13aWR0aD1cIjAuMDQ4XCI+PC9nPjxnIGlkPVwiU1ZHUmVwb19pY29uQ2FycmllclwiPiA8ZyBpZD1cInN0eWxlPXN0cm9rZVwiPiA8ZyBpZD1cImNvcHlcIj4gPHBhdGggaWQ9XCJyZWMgKFN0cm9rZSlcIiBmaWxsLXJ1bGU9XCJldmVub2RkXCIgY2xpcC1ydWxlPVwiZXZlbm9kZFwiIGQ9XCJNNi4yNSA1LjI1QzYuMjUgMi41MDI2NSA4LjQzNzMzIDAuMjUgMTEuMTY2NyAwLjI1SDE3LjgzMzNDMjAuNTYyNyAwLjI1IDIyLjc1IDIuNTAyNjUgMjIuNzUgNS4yNVYxMy43NUMyMi43NSAxNi40OTc0IDIwLjU2MjcgMTguNzUgMTcuODMzMyAxOC43NUMxNy40MTkxIDE4Ljc1IDE3LjA4MzMgMTguNDE0MiAxNy4wODMzIDE4QzE3LjA4MzMgMTcuNTg1OCAxNy40MTkxIDE3LjI1IDE3LjgzMzMgMTcuMjVDMTkuNzA2NCAxNy4yNSAyMS4yNSAxNS42OTcxIDIxLjI1IDEzLjc1VjUuMjVDMjEuMjUgMy4zMDI5MyAxOS43MDY0IDEuNzUgMTcuODMzMyAxLjc1SDExLjE2NjdDOS4yOTM2MyAxLjc1IDcuNzUgMy4zMDI5MyA3Ljc1IDUuMjVDNy43NSA1LjY2NDIxIDcuNDE0MjEgNiA3IDZDNi41ODU3OSA2IDYuMjUgNS42NjQyMSA2LjI1IDUuMjVaXCIgZmlsbD1cIiMwMDAwMDBcIj48L3BhdGg+IDxwYXRoIGlkPVwicmVjIChTdHJva2UpXzJcIiBmaWxsLXJ1bGU9XCJldmVub2RkXCIgY2xpcC1ydWxlPVwiZXZlbm9kZFwiIGQ9XCJNMS4yNSAxMC4yNUMxLjI1IDcuNTAyNjUgMy40MzczMyA1LjI1IDYuMTY2NjcgNS4yNUgxMi44MzMzQzE1LjU2MjcgNS4yNSAxNy43NSA3LjUwMjY1IDE3Ljc1IDEwLjI1VjE4Ljc1QzE3Ljc1IDIxLjQ5NzQgMTUuNTYyNyAyMy43NSAxMi44MzMzIDIzLjc1SDYuMTY2NjdDMy40MzczMyAyMy43NSAxLjI1IDIxLjQ5NzQgMS4yNSAxOC43NVYxMC4yNVpNNi4xNjY2NyA2Ljc1QzQuMjkzNjMgNi43NSAyLjc1IDguMzAyOTMgMi43NSAxMC4yNVYxOC43NUMyLjc1IDIwLjY5NzEgNC4yOTM2MyAyMi4yNSA2LjE2NjY3IDIyLjI1SDEyLjgzMzNDMTQuNzA2NCAyMi4yNSAxNi4yNSAyMC42OTcxIDE2LjI1IDE4Ljc1VjEwLjI1QzE2LjI1IDguMzAyOTMgMTQuNzA2NCA2Ljc1IDEyLjgzMzMgNi43NUg2LjE2NjY3WlwiIGZpbGw9XCIjMDAwMDAwXCI+PC9wYXRoPiA8L2c+IDwvZz4gPC9nPjwvc3ZnPlxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICA8IS0tIENvcGllZCBNZXNzYWdlIC0tPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cImNvcGllZFwiIGNsYXNzPVwiY29waWVkLW1zZ1wiPkNvcGllZCE8L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJwcm9wLmtleSA9PT0gJ2hlbHBUZXh0JyAmJiBzZWxlY3RlZEVsZW1lbnQoKT8uaGVscFRleHRcIj57eyBzZWxlY3RlZEVsZW1lbnQoKT8uaGVscFRleHQgfX08L2Rpdj5cbiAgICAgICAgICAgIDxpbnB1dCAqbmdJZj1cInByb3AudHlwZSA9PT0gJ3RleHQnXCJcbiAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwicHJvcC5wbGFjZWhvbGRlclwiXG4gICAgICAgICAgICAgIFtuZ01vZGVsXT1cImhlYWRlclNlbGVjdCgpID8gYm9vaygpLnJlY29yZHNbMF0udGl0bGUgOiAoc2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgJiYgKHByb3AudGFyZ2V0QXJyYXkgfHwgcHJvcC5pc1RhYmxlQ29sdW1uKSA/IChnZXRWYWx1ZUJ5QXJyYXlQYXRoKHByb3AudGFyZ2V0QXJyYXksIHByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCBwcm9wLmtleSwgcHJvcC5pc1RhYmxlQ29sdW1uKSkgOiAoc2VsZWN0ZWRFbGVtZW50KCkgfCBnZXRWYWx1ZUJ5UGF0aCA6IHByb3Aua2V5KSlcIlxuICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJoZWFkZXJTZWxlY3QoKSA/IHVwZGF0ZVRpdGxlKCRldmVudCkgOiAoc2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgJiYgKHByb3AudGFyZ2V0QXJyYXkgfHwgcHJvcC5pc1RhYmxlQ29sdW1uKSA/IHVwZGF0ZVZhbHVlQnlBcnJheVBhdGgocHJvcC50YXJnZXRBcnJheSwgcHJvcC50YXJnZXRBcnJheUtleSwgc2VsZWN0Q29sdW1uKCksIHByb3Aua2V5LCAkZXZlbnQsIHByb3AuaXNUYWJsZUNvbHVtbiwgcHJvcC5pc1RyYW5zbGF0ZSkgOiBzZXRWYWx1ZUJ5UGF0aChwcm9wLmtleSwgJGV2ZW50LCBwcm9wLmlzVHJhbnNsYXRlKSlcIlxuICAgICAgICAgICAgICBbY2xhc3MucmVhZC1vbmx5XT1cInNlbGVjdGVkRWxlbWVudCgpPy5yZWFkT25seVwiXG4gICAgICAgICAgICAgIFtyZWFkb25seV09XCJzZWxlY3RlZEVsZW1lbnQoKT8ucmVhZE9ubHlcIlxuICAgICAgICAgICAgLz5cbiAgICAgICAgICAgIDxpbnB1dCAqbmdJZj1cInByb3AudHlwZSA9PT0gJ251bWJlcidcIlxuICAgICAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgICAgW25nTW9kZWxdPVwiKHNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnICYmIChwcm9wLnRhcmdldEFycmF5IHx8IHByb3AuaXNUYWJsZUNvbHVtbikgPyAoZ2V0VmFsdWVCeUFycmF5UGF0aChwcm9wLnRhcmdldEFycmF5LCBwcm9wLnRhcmdldEFycmF5S2V5LCBzZWxlY3RDb2x1bW4oKSwgcHJvcC5rZXksIHByb3AuaXNUYWJsZUNvbHVtbikpIDogKHNlbGVjdGVkRWxlbWVudCgpIHwgZ2V0VmFsdWVCeVBhdGggOiBwcm9wLmtleSkpXCJcbiAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiKHNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnICYmIChwcm9wLnRhcmdldEFycmF5IHx8IHByb3AuaXNUYWJsZUNvbHVtbikgPyB1cGRhdGVWYWx1ZUJ5QXJyYXlQYXRoKHByb3AudGFyZ2V0QXJyYXksIHByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCBwcm9wLmtleSwgJGV2ZW50LCBwcm9wLmlzVGFibGVDb2x1bW4sIHByb3AuaXNUcmFuc2xhdGUpIDogc2V0VmFsdWVCeVBhdGgocHJvcC5rZXksICRldmVudCwgcHJvcC5pc1RyYW5zbGF0ZSkpXCJcbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgICA8c2VsZWN0ICpuZ0lmPVwicHJvcC50eXBlID09PSAnc2VsZWN0J1wiXG4gICAgICAgICAgICAgIFtuZ01vZGVsXT1cIihzZWxlY3RlZEVsZW1lbnQoKT8udHlwZSA9PT0gJ1RhYmxlJyAmJiAocHJvcC50YXJnZXRBcnJheSB8fCBwcm9wLmlzVGFibGVDb2x1bW4pID8gKGdldFZhbHVlQnlBcnJheVBhdGgocHJvcC50YXJnZXRBcnJheSwgcHJvcC50YXJnZXRBcnJheUtleSwgc2VsZWN0Q29sdW1uKCksIHByb3Aua2V5LCBwcm9wLmlzVGFibGVDb2x1bW4pKSA6IChzZWxlY3RlZEVsZW1lbnQoKSB8IGdldFZhbHVlQnlQYXRoIDogcHJvcC5rZXkpKVwiXG4gICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIihzZWxlY3RlZEVsZW1lbnQoKT8udHlwZSA9PT0gJ1RhYmxlJyAmJiAocHJvcC50YXJnZXRBcnJheSB8fCBwcm9wLmlzVGFibGVDb2x1bW4pID8gdXBkYXRlVmFsdWVCeUFycmF5UGF0aChwcm9wLnRhcmdldEFycmF5LCBwcm9wLnRhcmdldEFycmF5S2V5LCBzZWxlY3RDb2x1bW4oKSwgcHJvcC5rZXksICRldmVudCwgcHJvcC5pc1RhYmxlQ29sdW1uLCBwcm9wLmlzVHJhbnNsYXRlKSA6IHNldFZhbHVlQnlQYXRoKHByb3Aua2V5LCAkZXZlbnQsIHByb3AuaXNUcmFuc2xhdGUpKVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IG9wdGlvbiBvZiBwcm9wLm9wdGlvbnNcIiBbdmFsdWVdPVwib3B0aW9uLnZhbHVlXCI+e3sgb3B0aW9uLmxhYmVsUGF0aCB8IG54dEN1c3RvbVRyYW5zbGF0ZSA6IG9wdGlvbi5sYWJlbCB9fTwvb3B0aW9uPlxuICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwicHJvcC50eXBlID09PSAnY2hlY2tib3gnXCI+XG4gICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgIHR5cGU9XCJjaGVja2JveFwiXG4gICAgICAgICAgICAgICAgW2NoZWNrZWRdPVwic2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgPyAocHJvcC50YXJnZXRBcnJheSB8fCBwcm9wLmlzVGFibGVDb2x1bW4gPyBnZXRWYWx1ZUJ5QXJyYXlQYXRoKHByb3AudGFyZ2V0QXJyYXksIHByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCBwcm9wLmtleSwgcHJvcC5pc1RhYmxlQ29sdW1uKSA6IChzZWxlY3RlZEVsZW1lbnQoKSB8IGdldFZhbHVlQnlQYXRoIDogcHJvcC5rZXkpKSA6IChzZWxlY3RlZEVsZW1lbnQoKSB8IGdldFZhbHVlQnlQYXRoIDogcHJvcC5rZXkpXCJcbiAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnID8gKHByb3AudGFyZ2V0QXJyYXkgfHwgcHJvcC5pc1RhYmxlQ29sdW1uID8gdXBkYXRlVmFsdWVCeUFycmF5UGF0aChwcm9wLnRhcmdldEFycmF5LCBwcm9wLnRhcmdldEFycmF5S2V5LCBzZWxlY3RDb2x1bW4oKSwgcHJvcC5rZXksICRldmVudCwgcHJvcC5pc1RhYmxlQ29sdW1uLCBwcm9wLmlzVHJhbnNsYXRlKSA6IG9uVG9nZ2xlQ2hhbmdlKHByb3Aua2V5LCAkZXZlbnQpKSA6IG9uVG9nZ2xlQ2hhbmdlKHByb3Aua2V5LCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0b2dnbGUtbGFiZWxcIiBzdHlsZT1cInBhZGRpbmctbGVmdDogMTBweDtcIj57eyBwcm9wLmxhYmVsUGF0aCB8IG54dEN1c3RvbVRyYW5zbGF0ZSA6IHByb3AubGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJwcm9wLnR5cGUgPT09ICdzdWJRdWVzdGlvbidcIj5cbiAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGZsZXgtZGlyZWN0aW9uOiByb3c7IGdhcDogMTBweDsgYWxpZ24taXRlbXM6IGNlbnRlcjtcIj5cbiAgICAgICAgICAgICAgICA8ZGl2Pnt7IHByb3AubGFiZWxQYXRoIHwgbnh0Q3VzdG9tVHJhbnNsYXRlIDogcHJvcC5sYWJlbCB9fTwvZGl2PlxuICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgdHlwZT1cImNoZWNrYm94XCJcbiAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cInNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnID8gKHByb3AudGFyZ2V0QXJyYXkgfHwgcHJvcC5pc1RhYmxlQ29sdW1uID8gZ2V0VmFsdWVCeUFycmF5UGF0aChwcm9wLnRhcmdldEFycmF5LCBwcm9wLnRhcmdldEFycmF5S2V5LCBzZWxlY3RDb2x1bW4oKSwgcHJvcC5rZXksIHByb3AuaXNUYWJsZUNvbHVtbikgOiAoc2VsZWN0ZWRFbGVtZW50KCkgfCBnZXRWYWx1ZUJ5UGF0aCA6IHByb3Aua2V5KSkgOiAoc2VsZWN0ZWRFbGVtZW50KCkgfCBnZXRWYWx1ZUJ5UGF0aCA6IHByb3Aua2V5KVwiXG4gICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnID8gKHByb3AudGFyZ2V0QXJyYXkgfHwgcHJvcC5pc1RhYmxlQ29sdW1uID8gdXBkYXRlVmFsdWVCeUFycmF5UGF0aChwcm9wLnRhcmdldEFycmF5LCBwcm9wLnRhcmdldEFycmF5S2V5LCBzZWxlY3RDb2x1bW4oKSwgcHJvcC5rZXksICRldmVudCwgcHJvcC5pc1RhYmxlQ29sdW1uLCBwcm9wLmlzVHJhbnNsYXRlKSA6IG9uVG9nZ2xlQ2hhbmdlKHByb3Aua2V5LCAkZXZlbnQpKSA6IG9uVG9nZ2xlQ2hhbmdlKHByb3Aua2V5LCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICpuZ0lmPVwic2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgPyAocHJvcC50YXJnZXRBcnJheSB8fCBwcm9wLmlzVGFibGVDb2x1bW4gPyBnZXRWYWx1ZUJ5QXJyYXlQYXRoKHByb3AudGFyZ2V0QXJyYXksIHByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCBwcm9wLmtleSwgcHJvcC5pc1RhYmxlQ29sdW1uKSA6IChzZWxlY3RlZEVsZW1lbnQoKSB8IGdldFZhbHVlQnlQYXRoIDogcHJvcC5rZXkpKSA6IChzZWxlY3RlZEVsZW1lbnQoKSB8IGdldFZhbHVlQnlQYXRoIDogcHJvcC5rZXkpXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IHN1YlByb3Agb2YgcHJvcC5zdWJRdWVzdGlvblwiIHN0eWxlPVwiYmFja2dyb3VuZC1jb2xvcjogI2U3ZjJmZjsgcGFkZGluZzogOHB4OyBib3JkZXItcmFkaXVzOiA0cHg7XCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWw+e3sgc3ViUHJvcC5sYWJlbFBhdGggfCBueHRDdXN0b21UcmFuc2xhdGUgOiBzdWJQcm9wLmxhYmVsIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cInN1YlByb3AudHlwZSA9PT0gJ2FycmF5J1wiPlxuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiBmaWx0ZXJlZENvbHVtbnMoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cInN1YlByb3Aub3BlcmFuZHMgPyBzdWJQcm9wLm9wZXJhbmRzLmluY2x1ZGVzKGNvbHVtbi5hcGlOYW1lKSA6IGZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIm9uQ2hlY2tib3hDaGFuZ2Uoc3ViUHJvcC50YXJnZXRBcnJheSwgc3ViUHJvcC50YXJnZXRBcnJheUtleSwgc3ViUHJvcC5rZXksIGNvbHVtbi5hcGlOYW1lLCAkZXZlbnQudGFyZ2V0LmNoZWNrZWQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBjb2x1bW4uYXBpTmFtZSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJzdWJQcm9wLnR5cGUgPT09ICdyYWRpbydcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgZmlsdGVyZWRDb2x1bW5zKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cInJhZGlvXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmFtZV09XCJzdWJQcm9wLmtleVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImNvbHVtbi5hcGlOYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2hlY2tlZF09XCJnZXRWYWx1ZUJ5QXJyYXlQYXRoKHN1YlByb3AudGFyZ2V0QXJyYXksIHN1YlByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCBzdWJQcm9wLmtleSkgPT09IGNvbHVtbi5hcGlOYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIm9uUmFkaW9DaGFuZ2Uoc3ViUHJvcC50YXJnZXRBcnJheSwgc3ViUHJvcC50YXJnZXRBcnJheUtleSwgc3ViUHJvcC5rZXksIGNvbHVtbi5hcGlOYW1lKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAge3sgY29sdW1uLmFwaU5hbWUgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInN1YlByb3AudHlwZSA9PT0gJ3RleHQnXCJcbiAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cInN1YlByb3AucGxhY2Vob2xkZXJcIlxuICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnID8gKHN1YlByb3AudGFyZ2V0QXJyYXkgPyBnZXRWYWx1ZUJ5QXJyYXlQYXRoKHN1YlByb3AudGFyZ2V0QXJyYXksIHN1YlByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCBzdWJQcm9wLmtleSkgOiAoc2VsZWN0ZWRFbGVtZW50KCkgfCBnZXRWYWx1ZUJ5UGF0aCA6IHN1YlByb3Aua2V5KSkgOiAoc2VsZWN0ZWRFbGVtZW50KCkgfCBnZXRWYWx1ZUJ5UGF0aCA6IHN1YlByb3Aua2V5KVwiXG4gICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwic2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgPyAoc3ViUHJvcC50YXJnZXRBcnJheSA/IHVwZGF0ZVZhbHVlQnlBcnJheVBhdGgoc3ViUHJvcC50YXJnZXRBcnJheSwgc3ViUHJvcC50YXJnZXRBcnJheUtleSwgc2VsZWN0Q29sdW1uKCksIHN1YlByb3Aua2V5LCAkZXZlbnQsZmFsc2UsIHByb3AuaXNUcmFuc2xhdGUpIDogc2V0VmFsdWVCeVBhdGgoc3ViUHJvcC5rZXksICRldmVudCkpIDogc2V0VmFsdWVCeVBhdGgoc3ViUHJvcC5rZXksICRldmVudCwgcHJvcC5pc1RyYW5zbGF0ZSlcIlxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInN1YlByb3AudHlwZSA9PT0gJ2Jvb2xlYW4nXCJcbiAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cInNlbGVjdGVkRWxlbWVudCgpIHwgZ2V0VmFsdWVCeVBhdGggOiBzdWJQcm9wLmtleVwiXG4gICAgICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJzZXRWYWx1ZUJ5UGF0aChzdWJQcm9wLmtleSwgJGV2ZW50LnRhcmdldC5jaGVja2VkKVwiXG4gICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgIDxzZWxlY3RcbiAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInN1YlByb3AudHlwZSA9PT0gJ3NlbGVjdCdcIlxuICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cIihzZWxlY3RlZEVsZW1lbnQoKT8udHlwZSA9PT0gJ1RhYmxlJyAmJiAoc3ViUHJvcC50YXJnZXRBcnJheSB8fCBzdWJQcm9wLmlzVGFibGVDb2x1bW4pID8gKGdldFZhbHVlQnlBcnJheVBhdGgoc3ViUHJvcC50YXJnZXRBcnJheSwgc3ViUHJvcC50YXJnZXRBcnJheUtleSwgc2VsZWN0Q29sdW1uKCksIHN1YlByb3Aua2V5LCBzdWJQcm9wLmlzVGFibGVDb2x1bW4pKSA6IChzZWxlY3RlZEVsZW1lbnQoKSB8IGdldFZhbHVlQnlQYXRoIDogc3ViUHJvcC5rZXkpKVwiXG4gICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiKHNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnICYmIChzdWJQcm9wLnRhcmdldEFycmF5IHx8IHN1YlByb3AuaXNUYWJsZUNvbHVtbikgPyB1cGRhdGVWYWx1ZUJ5QXJyYXlQYXRoKHN1YlByb3AudGFyZ2V0QXJyYXksIHN1YlByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCBzdWJQcm9wLmtleSwgJGV2ZW50LCBzdWJQcm9wLmlzVGFibGVDb2x1bW4sIHByb3AuaXNUcmFuc2xhdGUpIDogc2V0VmFsdWVCeVBhdGgoc3ViUHJvcC5rZXksICRldmVudCwgcHJvcC5pc1RyYW5zbGF0ZSkpXCJcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IG9wdGlvbiBvZiBzdWJQcm9wLm9wdGlvbnNcIiBbdmFsdWVdPVwib3B0aW9uLnZhbHVlXCI+e3sgb3B0aW9uLmxhYmVsUGF0aCB8IG54dEN1c3RvbVRyYW5zbGF0ZSA6IG9wdGlvbi5sYWJlbCB9fTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJzdWJQcm9wLnR5cGUgPT09ICdjaGVja2JveCdcIlxuICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJjaGVja2JveFwiXG4gICAgICAgICAgICAgICAgICAgICAgW2NoZWNrZWRdPVwic2VsZWN0ZWRFbGVtZW50KCkgfCBnZXRWYWx1ZUJ5UGF0aCA6IHN1YlByb3Aua2V5XCJcbiAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInNldFZhbHVlQnlQYXRoKHN1YlByb3Aua2V5LCAkZXZlbnQudGFyZ2V0LmNoZWNrZWQpXCJcbiAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cInByb3AudHlwZSA9PT0gJ2FsaWduJ1wiPlxuICAgICAgICAgICAgICA8YnV0dG9uICpuZ0Zvcj1cImxldCBvcHRpb24gb2YgcHJvcC5vcHRpb25zXCIgKGNsaWNrKT1cIm9uQWxpZ25TZWxlY3Qob3B0aW9uLnZhbHVlKVwiIFtuZ0NsYXNzXT1cInsnYWN0aXZlJzogc2VsZWN0ZWRFbGVtZW50KCk/LnRleHRBbGlnbiA9PT0gb3B0aW9uLnZhbHVlfVwiIFt0aXRsZV09XCJvcHRpb24udmFsdWVcIj5cbiAgICAgICAgICAgICAgICA8aW1nIFtzcmNdPVwiJy4uL2Fzc2V0cy9pY29ucy8nICsgb3B0aW9uLmljb24gKyAnLnN2ZydcIiBbYWx0XT1cIm9wdGlvbi52YWx1ZVwiIGNsYXNzPVwiaWNvbi1zaXplXCIgLz5cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJwcm9wLnR5cGUgPT09ICdzdHlsZSdcIj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIHByb3Aub3B0aW9uc1wiIChjbGljayk9XCJvblN0eWxlU2VsZWN0KG9wdGlvbi52YWx1ZSlcIiBbbmdDbGFzc109XCJ7J2FjdGl2ZSc6IGlzU3R5bGVBY3RpdmUob3B0aW9uLnZhbHVlKX1cIiBbdGl0bGVdPVwib3B0aW9uLnZhbHVlXCI+XG4gICAgICAgICAgICAgICAgPGltZyBbc3JjXT1cIicuLi9hc3NldHMvaWNvbnMvJyArIG9wdGlvbi5pY29uICsgJy5zdmcnXCIgW2FsdF09XCJvcHRpb24udmFsdWVcIiBjbGFzcz1cImljb24tc2l6ZVwiIC8+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwicHJvcC50eXBlID09PSAnY29sb3InXCI+XG4gICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgIHR5cGU9XCJjb2xvclwiXG4gICAgICAgICAgICAgICAgW25nTW9kZWxdPVwiKHNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnICYmIChwcm9wLnRhcmdldEFycmF5IHx8IHByb3AuaXNUYWJsZUNvbHVtbikgPyAoZ2V0VmFsdWVCeUFycmF5UGF0aChwcm9wLnRhcmdldEFycmF5LCBwcm9wLnRhcmdldEFycmF5S2V5LCBzZWxlY3RDb2x1bW4oKSwgcHJvcC5rZXksIHByb3AuaXNUYWJsZUNvbHVtbikpIDogKHNlbGVjdGVkRWxlbWVudCgpIHwgZ2V0VmFsdWVCeVBhdGggOiBwcm9wLmtleSkpXCJcbiAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCIoc2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgJiYgKHByb3AudGFyZ2V0QXJyYXkgfHwgcHJvcC5pc1RhYmxlQ29sdW1uKSA/IHVwZGF0ZVZhbHVlQnlBcnJheVBhdGgocHJvcC50YXJnZXRBcnJheSwgcHJvcC50YXJnZXRBcnJheUtleSwgc2VsZWN0Q29sdW1uKCksIHByb3Aua2V5LCAkZXZlbnQsIHByb3AuaXNUYWJsZUNvbHVtbiwgcHJvcC5pc1RyYW5zbGF0ZSkgOiBzZXRWYWx1ZUJ5UGF0aChwcm9wLmtleSwgJGV2ZW50LCBwcm9wLmlzVHJhbnNsYXRlKSlcIlxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwicHJvcC5rZXkgPT09ICd0aXRsZSdcIiBzdHlsZT1cIm1hcmdpbi10b3A6IDE1cHg7IGJvcmRlcjogMXB4IHNvbGlkICNkZGQ7IHBhZGRpbmc6IDIwcHg7IGJvcmRlci1yYWRpdXM6IDEycHg7IGJhY2tncm91bmQtY29sb3I6ICNmOWY5Zjk7XCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWhlYWRlclwiPlxuICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWxcIj57eyBwcm9wLmxhYmVsUGF0aCB8IG54dEN1c3RvbVRyYW5zbGF0ZSA6IHByb3AubGFiZWwgfX08L2xhYmVsPlxuICAgICAgICAgICAgICAgIDxidXR0b24gKGNsaWNrKT1cImFkZE5ld0J1dHRvbigpXCIgY2xhc3M9XCJhZGQtYnV0dG9uXCI+KyB7eyAnQUREX0JVVFRPTicgfCBueHRDdXN0b21UcmFuc2xhdGUgOiAnQWRkIEJ1dHRvbicgfX08L2J1dHRvbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGJ0biBvZiBib29rKCk/LnF1ZXN0aW9uYm9vaz8uYWN0aW9uIHx8IFtdOyBsZXQgaSA9IGluZGV4XCIgY2xhc3M9XCJidXR0b24tY29uZmlnLWNhcmRcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgPGxhYmVsPnt7ICdCVVRUT05fTkFNRScgfCBueHRDdXN0b21UcmFuc2xhdGUgOiAnQnV0dG9uIE5hbWUnIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIFtuZ01vZGVsXT1cImJ0bi5uYW1lXCIgKG5nTW9kZWxDaGFuZ2UpPVwib25CdXR0b25Qcm9wZXJ0eUNoYW5nZShpLCAnbmFtZScsICRldmVudCx0cnVlKVwiIHBsYWNlaG9sZGVyPVwiRW50ZXIgYnV0dG9uIG5hbWVcIj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgPGxhYmVsPnt7ICdFVkVOVF9OQU1FJyB8IG54dEN1c3RvbVRyYW5zbGF0ZSA6ICdFdmVudCBOYW1lJyB9fTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBbbmdNb2RlbF09XCJidG4uZXZlbnR0b2VtaXRcIiAobmdNb2RlbENoYW5nZSk9XCJvbkJ1dHRvblByb3BlcnR5Q2hhbmdlKGksICdldmVudHRvZW1pdCcsICRldmVudClcIiBwbGFjZWhvbGRlcj1cIkV2ZW50IHRvIGVtaXRcIj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgPGxhYmVsPnt7ICdBTFQnIHwgbnh0Q3VzdG9tVHJhbnNsYXRlIDogJ0FsdCcgfX08L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgW25nTW9kZWxdPVwiYnRuLmFsdFwiIChuZ01vZGVsQ2hhbmdlKT1cIm9uQnV0dG9uUHJvcGVydHlDaGFuZ2UoaSwgJ2FsdCcsICRldmVudClcIiBwbGFjZWhvbGRlcj1cIkJ1dHRvbiBhbHQgdGV4dFwiPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICA8bGFiZWw+e3sgJ0VORF9QT0lOVCcgfCBueHRDdXN0b21UcmFuc2xhdGUgOiAnRW5kcG9pbnQnIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIFtuZ01vZGVsXT1cImJ0bi5lbmRwb2ludFwiIChuZ01vZGVsQ2hhbmdlKT1cIm9uQnV0dG9uUHJvcGVydHlDaGFuZ2UoaSwgJ2VuZHBvaW50JywgJGV2ZW50KVwiIHBsYWNlaG9sZGVyPVwiQVBJIGVuZHBvaW50XCI+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICAgICAgICAgICAgICAgIDxsYWJlbD57eyAnTUVUSE9EJyB8IG54dEN1c3RvbVRyYW5zbGF0ZSA6ICdNZXRob2QnIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgIDxzZWxlY3QgW25nTW9kZWxdPVwiYnRuLm1ldGhvZFwiIChuZ01vZGVsQ2hhbmdlKT1cIm9uQnV0dG9uUHJvcGVydHlDaGFuZ2UoaSwgJ21ldGhvZCcsICRldmVudClcIj5cbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIkdFVFwiPkdFVDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiUE9TVFwiPlBPU1Q8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlBVVFwiPlBVVDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiREVMRVRFXCI+REVMRVRFPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgPGxhYmVsPnt7ICdCQUNLR1JPVU5EX0NPTE9SJyB8IG54dEN1c3RvbVRyYW5zbGF0ZSA6ICdCYWNrZ3JvdW5kIENvbG9yJyB9fTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNvbG9yXCIgW25nTW9kZWxdPVwiYnRuLmJnQ29sb3JcIiAobmdNb2RlbENoYW5nZSk9XCJvbkJ1dHRvblByb3BlcnR5Q2hhbmdlKGksICdiZ0NvbG9yJywgJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICA8bGFiZWw+e3sgJ0JPUkRFUl9SQURJVVMnIHwgbnh0Q3VzdG9tVHJhbnNsYXRlIDogJ0JvcmRlciBSYWRpdXMnIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwicmFuZ2VcIiBtaW49XCIwXCIgbWF4PVwiNTBcIiBbbmdNb2RlbF09XCJidG4uYm9yZGVyUmFkaXVzXCIgKG5nTW9kZWxDaGFuZ2UpPVwib25CdXR0b25Qcm9wZXJ0eUNoYW5nZShpLCAnYm9yZGVyUmFkaXVzJywgJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgYnRuLmJvcmRlclJhZGl1cyB9fXB4PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICA8bGFiZWw+e3sgJ0JVVFRPTl9XSURUSF9QWCcgfCBueHRDdXN0b21UcmFuc2xhdGUgOiAnQnV0dG9uIFdpZHRoIChweCknIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgW25nTW9kZWxdPVwiYnRuLndpZHRoXCIgKG5nTW9kZWxDaGFuZ2UpPVwib25CdXR0b25Qcm9wZXJ0eUNoYW5nZShpLCAnd2lkdGgnLCAkZXZlbnQpXCIgbWluPVwiNTBcIiBwbGFjZWhvbGRlcj1cIkVudGVyIHdpZHRoIGluIHB4XCI+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICAgICAgICAgICAgICAgIDxsYWJlbD57eyAnVEVYVF9DT0xPUicgfCBueHRDdXN0b21UcmFuc2xhdGUgOiAnVGV4dCBDb2xvcicgfX08L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjb2xvclwiIFtuZ01vZGVsXT1cImJ0bi50ZXh0Q29sb3JcIiAobmdNb2RlbENoYW5nZSk9XCJvbkJ1dHRvblByb3BlcnR5Q2hhbmdlKGksICd0ZXh0Q29sb3InLCAkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICAgICAgICAgICAgICAgIDxsYWJlbD57eyAnUE9TSVRJT05fUEVSQ0VOVCcgfCBueHRDdXN0b21UcmFuc2xhdGUgOiAnUG9zaXRpb24gKCUpJyB9fTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInJhbmdlXCIgbWluPVwiMFwiIG1heD1cIjEwMFwiIFtuZ01vZGVsXT1cImJ0bi5wb3NpdGlvblBlcmNlbnRcIiAobmdNb2RlbENoYW5nZSk9XCJvbkJ1dHRvblByb3BlcnR5Q2hhbmdlKGksICdwb3NpdGlvblBlcmNlbnQnLCAkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICA8c3Bhbj57eyBidG4ucG9zaXRpb25QZXJjZW50IH19JTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIChjbGljayk9XCJyZW1vdmVCdXR0b24oYnRuKVwiIGNsYXNzPVwicmVtb3ZlLWJ1dHRvblwiPsOXIHt7ICdSRU1PVkUnIHwgbnh0Q3VzdG9tVHJhbnNsYXRlIDogJ1JlbW92ZScgfX08L2J1dHRvbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L2Rpdj5cbiAgICB9XG4gIDwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJ0YWItY29udGVudFwiICpuZ0lmPVwiYWN0aXZlVGFiKCkgPT09ICdwcm9wZXJ0eSdcIj5cbiAgICBAZGVmZXIgKHdoZW4gZ2V0UHJvcGVydGllcygpKSB7XG4gICAgICA8ZGl2PlxuICAgICAgICA8bGFiZWw+TGFiZWwgSWQ8L2xhYmVsPlxuICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiAxM3B4OyBwYWRkaW5nOiAxMXB4OyBib3JkZXItcmFkaXVzOiA1cHg7IGJhY2tncm91bmQtY29sb3I6ICNmOGY4Zjg7IGJvcmRlcjogMXB4IHNvbGlkICNkZGQ7XCI+XG4gICAgICAgICAge3sgaGVhZGVyU2VsZWN0KCkgPyBib29rSWQoKSA6IHNlbGVjdGVkRWxlbWVudCgpPy5pZCB9fVxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgcHJvcCBvZiBnZXRQcm9wZXJ0aWVzKCk/LmZpZWxkUHJvcHM7IHRyYWNrQnk6IHRyYWNrQnlQcm9wXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICAgICAgICAgIDxsYWJlbCAgKm5nSWY9XCJwcm9wLnR5cGUgIT09ICdzdWJRdWVzdGlvbidcIiBjbGFzcz1cInRleHQtc21cIj57eyBwcm9wLmxhYmVsUGF0aCB8IG54dEN1c3RvbVRyYW5zbGF0ZSA6IHByb3AubGFiZWwgfX08L2xhYmVsPlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cInByb3AudHlwZSA9PT0gJ3RvZ2dsZUdyb3VwJ1wiIGNsYXNzPVwidG9nZ2xlLWdyb3VwXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0b2dnbGUtaXRlbVwiPlxuICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInRvZ2dsZS1sYWJlbFwiPlxuICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIFxuICAgICAgICAgICAgICAgICAgW2NoZWNrZWRdPVwic2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgPyAocHJvcC50YXJnZXRBcnJheSB8fCBwcm9wLmlzVGFibGVDb2x1bW4gPyBnZXRWYWx1ZUJ5QXJyYXlQYXRoKHByb3AudGFyZ2V0QXJyYXksIHByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCAnaXNPcHRpb25hbCcsIHRydWUpIDogKHNlbGVjdGVkRWxlbWVudCgpIHwgZ2V0VmFsdWVCeVBhdGggOiBwcm9wLmtleSkpIDogKHNlbGVjdGVkRWxlbWVudCgpIHwgZ2V0VmFsdWVCeVBhdGggOiAnaXNPcHRpb25hbCcpXCJcbiAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwic2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgPyAocHJvcC50YXJnZXRBcnJheSB8fCBwcm9wLmlzVGFibGVDb2x1bW4gPyB1cGRhdGVWYWx1ZUJ5QXJyYXlQYXRoKHByb3AudGFyZ2V0QXJyYXksIHByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCAnaXNPcHRpb25hbCcsICRldmVudCwgdHJ1ZSwgcHJvcC5pc1RyYW5zbGF0ZSkgOiBvblRvZ2dsZUNoYW5nZShwcm9wLmtleSwgJGV2ZW50KSkgOiBvblRvZ2dsZUNoYW5nZSgnaXNPcHRpb25hbCcsICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgIHt7ICdSRVFVSVJFRCcgfCBueHRDdXN0b21UcmFuc2xhdGUgOiAnUmVxdWlyZWQnIH19XG4gICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0b2dnbGUtaXRlbVwiPlxuICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInRvZ2dsZS1sYWJlbFwiPlxuICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIFxuICAgICAgICAgICAgICAgICAgW2NoZWNrZWRdPVwic2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgPyAocHJvcC50YXJnZXRBcnJheSB8fCBwcm9wLmlzVGFibGVDb2x1bW4gPyBnZXRWYWx1ZUJ5QXJyYXlQYXRoKHByb3AudGFyZ2V0QXJyYXksIHByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCAnaXNSZWFkT25seScsIHRydWUpIDogKHNlbGVjdGVkRWxlbWVudCgpIHwgZ2V0VmFsdWVCeVBhdGggOiBwcm9wLmtleSkpIDogKHNlbGVjdGVkRWxlbWVudCgpIHwgZ2V0VmFsdWVCeVBhdGggOiAnaXNSZWFkT25seScpXCJcbiAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwic2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgPyAocHJvcC50YXJnZXRBcnJheSB8fCBwcm9wLmlzVGFibGVDb2x1bW4gPyB1cGRhdGVWYWx1ZUJ5QXJyYXlQYXRoKHByb3AudGFyZ2V0QXJyYXksIHByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCAnaXNSZWFkT25seScsICRldmVudCwgdHJ1ZSwgcHJvcC5pc1RyYW5zbGF0ZSkgOiBvblRvZ2dsZUNoYW5nZShwcm9wLmtleSwgJGV2ZW50KSkgOiBvblRvZ2dsZUNoYW5nZSgnaXNSZWFkT25seScsICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgIHt7ICdSRUFEX09OTFknIHwgbnh0Q3VzdG9tVHJhbnNsYXRlIDogJ1JlYWQgT25seScgfX1cbiAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRvZ2dsZS1pdGVtXCI+XG4gICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwidG9nZ2xlLWxhYmVsXCI+XG4gICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgXG4gICAgICAgICAgICAgICAgICBbY2hlY2tlZF09XCJzZWxlY3RlZEVsZW1lbnQoKT8udHlwZSA9PT0gJ1RhYmxlJyA/IChwcm9wLnRhcmdldEFycmF5IHx8IHByb3AuaXNUYWJsZUNvbHVtbiA/IGdldFZhbHVlQnlBcnJheVBhdGgocHJvcC50YXJnZXRBcnJheSwgcHJvcC50YXJnZXRBcnJheUtleSwgc2VsZWN0Q29sdW1uKCksICdpc0hpZGRlbicsIHRydWUpIDogKHNlbGVjdGVkRWxlbWVudCgpIHwgZ2V0VmFsdWVCeVBhdGggOiBwcm9wLmtleSkpIDogKHNlbGVjdGVkRWxlbWVudCgpIHwgZ2V0VmFsdWVCeVBhdGggOiAnaXNIaWRkZW4nKVwiXG4gICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnID8gKHByb3AudGFyZ2V0QXJyYXkgfHwgcHJvcC5pc1RhYmxlQ29sdW1uID8gdXBkYXRlVmFsdWVCeUFycmF5UGF0aChwcm9wLnRhcmdldEFycmF5LCBwcm9wLnRhcmdldEFycmF5S2V5LCBzZWxlY3RDb2x1bW4oKSwgJ2lzSGlkZGVuJywgJGV2ZW50LCB0cnVlLCBwcm9wLmlzVHJhbnNsYXRlKSA6IG9uVG9nZ2xlQ2hhbmdlKHByb3Aua2V5LCAkZXZlbnQpKSA6IG9uVG9nZ2xlQ2hhbmdlKCdpc0hpZGRlbicsICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgIHt7ICdJU19ISURFJyB8IG54dEN1c3RvbVRyYW5zbGF0ZSA6ICdJcyBIaWRlJyB9fVxuICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiIHByb3AudHlwZSA9PT0gJ2NoZWNrYm94JyB8fCBwcm9wLnR5cGUgPT09ICdyYWRpbycgfHwgcHJvcC5rZXkgPT09ICdvcHRpb25zJ1wiIGNsYXNzPVwib3B0aW9ucy1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm9wdGlvbi1saXN0XCIgKGRyYWdvdmVyKT1cIm9uRHJhZ092ZXIoJGV2ZW50KVwiIChkcm9wKT1cIm9uRHJvcCgkZXZlbnQsIHByb3Aua2V5KVwiPlxuICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IG9wdGlvbiBvZiBzZWxlY3RlZEVsZW1lbnQoKT8udHlwZSA9PT0gJ1RhYmxlJyAmJiBzZWxlY3RDb2x1bW4oKSA/IGdldFZhbHVlQnlBcnJheVBhdGgoJ2ZpZWxkc01ldGEnLCAndW5pcXVlSWRlbnRpZmllcicsIHNlbGVjdENvbHVtbigpLCAgcHJvcC5rZXksIHRydWUpIDogc2VsZWN0ZWRFbGVtZW50KClbcHJvcC5rZXldIDsgbGV0IGkgPSBpbmRleFwiIGNsYXNzPVwib3B0aW9uLWl0ZW1zXCIgW2F0dHIuZGF0YS1pZF09XCJvcHRpb24uaWRcIiBkcmFnZ2FibGU9XCJ0cnVlXCIgKGRyYWdzdGFydCk9XCJvbkRyYWdTdGFydCgkZXZlbnQsIG9wdGlvbi5pZClcIj5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIHN0eWxlPVwicGFkZGluZzogNHB4OyBib3JkZXItcmFkaXVzOiAycHg7XCIgW25nTW9kZWxdPVwib3B0aW9uLnZhbHVlXCIgKG5nTW9kZWxDaGFuZ2UpPVwib3B0aW9uLnZhbHVlID0gJGV2ZW50XCIgcGxhY2Vob2xkZXI9XCJWYWx1ZVwiIGNsYXNzPVwib3B0aW9uc1wiIC8+XG4gICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBzdHlsZT1cInBhZGRpbmc6IDRweDsgYm9yZGVyLXJhZGl1czogMnB4O1wiIFtuZ01vZGVsXT1cIm9wdGlvbi5sYWJlbFwiIChuZ01vZGVsQ2hhbmdlKT1cIm9wdGlvbi5sYWJlbCA9ICRldmVudDsgb3B0aW9uVHJhbnNsYXRpb25VcGRhdGUob3B0aW9uLCRldmVudClcIiBwbGFjZWhvbGRlcj1cIkxhYmVsXCIgY2xhc3M9XCJvcHRpb25zXCIgLz5cbiAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiLi4vYXNzZXRzL2ljb25zL1RyYXNoLnN2Z1wiIChjbGljayk9XCJyZW1vdmVPcHRpb24oc2VsZWN0ZWRFbGVtZW50KClbcHJvcC5rZXldLCBvcHRpb24uaWQpXCI+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRyYWctaGFuZGxlXCI+4piwPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiAoY2xpY2spPVwiYWRkT3B0aW9uKHNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnICYmIHNlbGVjdENvbHVtbigpID8gZ2V0VmFsdWVCeUFycmF5UGF0aCgnZmllbGRzTWV0YScsICd1bmlxdWVJZGVudGlmaWVyJywgc2VsZWN0Q29sdW1uKCksIHByb3Aua2V5LCB0cnVlKSA6IHNlbGVjdGVkRWxlbWVudCgpW3Byb3Aua2V5XSlcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWRkLXZhcmllbnRcIj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1sZ1wiPis8L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8c3Bhbj57eyAnQUREJyB8IG54dEN1c3RvbVRyYW5zbGF0ZSA6ICdBZGQnIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGlucHV0ICpuZ0lmPVwicHJvcC50eXBlID09PSAndGV4dCdcIlxuICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJwcm9wLnBsYWNlaG9sZGVyXCJcbiAgICAgICAgICAgICAgW25nTW9kZWxdPVwiaGVhZGVyU2VsZWN0KCkgPyBib29rKCkucmVjb3Jkc1swXS50aXRsZSA6IChzZWxlY3RlZEVsZW1lbnQoKT8udHlwZSA9PT0gJ1RhYmxlJyAmJiAocHJvcC50YXJnZXRBcnJheSB8fCBwcm9wLmlzVGFibGVDb2x1bW4pID8gZ2V0VmFsdWVCeUFycmF5UGF0aChwcm9wLnRhcmdldEFycmF5LCBwcm9wLnRhcmdldEFycmF5S2V5LCBzZWxlY3RDb2x1bW4oKSwgcHJvcC5rZXksIHByb3AuaXNUYWJsZUNvbHVtbikgOiAoc2VsZWN0ZWRFbGVtZW50KCkgfCBnZXRWYWx1ZUJ5UGF0aCA6IHByb3Aua2V5KSlcIlxuICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJoZWFkZXJTZWxlY3QoKSA/IHVwZGF0ZVRpdGxlKCRldmVudCkgOiAoc2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgJiYgKHByb3AudGFyZ2V0QXJyYXkgfHwgcHJvcC5pc1RhYmxlQ29sdW1uKSA/IHVwZGF0ZVZhbHVlQnlBcnJheVBhdGgocHJvcC50YXJnZXRBcnJheSwgcHJvcC50YXJnZXRBcnJheUtleSwgc2VsZWN0Q29sdW1uKCksIHByb3Aua2V5LCAkZXZlbnQsIHByb3AuaXNUYWJsZUNvbHVtbiwgcHJvcC5pc1RyYW5zbGF0ZSkgOiBzZXRWYWx1ZUJ5UGF0aChwcm9wLmtleSwgJGV2ZW50LCBwcm9wLmlzVHJhbnNsYXRlKSlcIlxuICAgICAgICAgICAgICBbY2xhc3MucmVhZC1vbmx5XT1cInNlbGVjdGVkRWxlbWVudCgpPy5yZWFkT25seVwiXG4gICAgICAgICAgICAgIFtyZWFkb25seV09XCJzZWxlY3RlZEVsZW1lbnQoKT8ucmVhZE9ubHlcIlxuICAgICAgICAgICAgLz5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJwcm9wLnR5cGUgPT09ICdzdWJRdWVzdGlvbidcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN0eWxlLXRvZ2dsZS1oZWFkZXJcIiAoY2xpY2spPVwidG9nZ2xlU3ViUXVlc3Rpb24ocHJvcClcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGVhZC1lbGVtZW50c1wiPlN1YiBUZXh0PC9kaXY+XG4gICAgICAgICAgICAgICAgPGltZyBbc3JjXT1cImlzRXhwYW5kZWQgPyAnLi4vYXNzZXRzL2ljb25zL2Fycm93LWRvd24uc3ZnJyA6ICcuLi9hc3NldHMvaWNvbnMvYXJyb3ctcmlnaHQuc3ZnJ1wiXG4gICAgICAgICAgICAgICAgICBhbHQ9XCJUb2dnbGUgQXJyb3dcIiBjbGFzcz1cImFycm93LWljb25cIj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpc0V4cGFuZGVkXCIgc3R5bGU9XCJib3JkZXI6IDFweCBzb2xpZCAjZGRkOyBib3JkZXItcmFkaXVzOiA0cHg7XCI+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgc3ViUHJvcCBvZiBwcm9wLnN1YlF1ZXN0aW9uOyB0cmFja0J5OiB0cmFja0J5UHJvcFwiIHN0eWxlPVwiYmFja2dyb3VuZC1jb2xvcjogI2U3ZjJmZjsgcGFkZGluZzogOHB4OyBib3JkZXItcmFkaXVzOiA0cHg7XCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWw+e3sgc3ViUHJvcC5sYWJlbFBhdGggfCBueHRDdXN0b21UcmFuc2xhdGUgOiBzdWJQcm9wLmxhYmVsIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0ICpuZ0lmPVwic3ViUHJvcC50eXBlID09PSAndGV4dCdcIlxuICAgICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJzdWJQcm9wLnBsYWNlaG9sZGVyXCJcbiAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImdldE9wdGltaXplZFN1YlByb3BWYWx1ZShzdWJQcm9wKVwiXG4gICAgICAgICAgICAgICAgICAgIChpbnB1dCk9XCIoc2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgJiYgKHN1YlByb3AudGFyZ2V0QXJyYXkgfHwgc3ViUHJvcC5pc1RhYmxlQ29sdW1uKSkgPyB1cGRhdGVWYWx1ZUJ5QXJyYXlQYXRoKHN1YlByb3AudGFyZ2V0QXJyYXksIHN1YlByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCBzdWJQcm9wLmtleSwgJGV2ZW50LnRhcmdldC52YWx1ZSwgc3ViUHJvcC5pc1RhYmxlQ29sdW1uLCBwcm9wLmlzVHJhbnNsYXRlKSA6IHNldFZhbHVlQnlQYXRoKHN1YlByb3Aua2V5LCAkZXZlbnQudGFyZ2V0LnZhbHVlLCBwcm9wLmlzVHJhbnNsYXRlKVwiXG4gICAgICAgICAgICAgICAgICAgIFtjbGFzcy5yZWFkLW9ubHldPVwic2VsZWN0ZWRFbGVtZW50KCk/LnJlYWRPbmx5XCJcbiAgICAgICAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cInNlbGVjdGVkRWxlbWVudCgpPy5yZWFkT25seVwiIC8+XG4gICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgPCEtLSBBUC0wMkFQUjI1IFJlbmRlciBpbnB1dCBmaWVsZCBvbmx5IGlmIHN1YlByb3AudHlwZSBpcyAnYXJyYXknIC0tPlxuICAgICAgICAgICAgICAgICAgPGlucHV0ICpuZ0lmPVwic3ViUHJvcC50eXBlID09PSAnYXJyYXknXCIgdHlwZT1cInRleHRcIiBbcGxhY2Vob2xkZXJdPVwic3ViUHJvcC5wbGFjZWhvbGRlclwiXG4gICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJnZXRWYWx1ZUJ5UGF0aChzdWJQcm9wLmtleSlcIiAoaW5wdXQpPVwic2V0VmFsdWVCeVBhdGgoc3ViUHJvcC5rZXksICRldmVudC50YXJnZXQudmFsdWUsIHByb3AuaXNUcmFuc2xhdGUpXCIgLz5cblxuICAgICAgICAgICAgICAgICAgPGlucHV0ICpuZ0lmPVwic3ViUHJvcC50eXBlID09PSAnYm9vbGVhbidcIiB0eXBlPVwiY2hlY2tib3hcIiBbY2hlY2tlZF09XCJnZXRWYWx1ZUJ5UGF0aChzdWJQcm9wLmtleSlcIlxuICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInNldFZhbHVlQnlQYXRoKHN1YlByb3Aua2V5LCAkZXZlbnQudGFyZ2V0LmNoZWNrZWQpXCIgLz5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cInByb3AudHlwZSA9PT0gJ2NoZWNrYm94J1wiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRvZ2dsZS1sYWJlbFwiIHN0eWxlPVwicGFkZGluZy1yaWdodDogMTBweDtcIj57eyBwcm9wLmxhYmVsUGF0aCB8IG54dEN1c3RvbVRyYW5zbGF0ZSA6IHByb3AubGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgIHR5cGU9XCJjaGVja2JveFwiXG4gICAgICAgICAgICAgICAgW2NoZWNrZWRdPVwic2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgPyAocHJvcC50YXJnZXRBcnJheSB8fCBwcm9wLmlzVGFibGVDb2x1bW4gPyBnZXRWYWx1ZUJ5QXJyYXlQYXRoKHByb3AudGFyZ2V0QXJyYXksIHByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCBwcm9wLmtleSwgcHJvcC5pc1RhYmxlQ29sdW1uKSA6IChzZWxlY3RlZEVsZW1lbnQoKSB8IGdldFZhbHVlQnlQYXRoIDogcHJvcC5rZXkpKSA6IChzZWxlY3RlZEVsZW1lbnQoKSB8IGdldFZhbHVlQnlQYXRoIDogcHJvcC5rZXkpXCJcbiAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnID8gKHByb3AudGFyZ2V0QXJyYXkgfHwgcHJvcC5pc1RhYmxlQ29sdW1uID8gdXBkYXRlVmFsdWVCeUFycmF5UGF0aChwcm9wLnRhcmdldEFycmF5LCBwcm9wLnRhcmdldEFycmF5S2V5LCBzZWxlY3RDb2x1bW4oKSwgcHJvcC5rZXksICRldmVudCwgcHJvcC5pc1RhYmxlQ29sdW1uLCBwcm9wLmlzVHJhbnNsYXRlKSA6IG9uVG9nZ2xlQ2hhbmdlKHByb3Aua2V5LCAkZXZlbnQpKSA6IG9uVG9nZ2xlQ2hhbmdlKHByb3Aua2V5LCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInN0eWxlLXRvZ2dsZS1oZWFkZXJcIiAoY2xpY2spPVwidG9nZ2xlU3R5bGVTZWN0aW9uKClcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGVhZC1lbGVtZW50c1wiPnt7ICdTVFlMRScgfCBueHRDdXN0b21UcmFuc2xhdGUgOiAnU3R5bGUnIH19PC9kaXY+XG4gICAgICAgICAgPGltZyBbc3JjXT1cImlzU3R5bGVFeHBhbmRlZCgpID8gJy4uL2Fzc2V0cy9pY29ucy9hcnJvdy1kb3duLnN2ZycgOiAnLi4vYXNzZXRzL2ljb25zL2Fycm93LXJpZ2h0LnN2ZydcIiBhbHQ9XCJUb2dnbGUgQXJyb3dcIiBjbGFzcz1cImFycm93LWljb25cIj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgKm5nSWY9XCJpc1N0eWxlRXhwYW5kZWQoKVwiIHN0eWxlPVwiYm9yZGVyOiAxcHggc29saWQgI2RkZDsgcGFkZGluZzogOHB4OyBib3JkZXItcmFkaXVzOiA0cHg7XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGtleSBvZiBnZXRTdHlsZUtleXMoKVwiPlxuICAgICAgICAgICAgICA8bGFiZWw+e3sga2V5IH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJzZWxlY3RlZEVsZW1lbnQoKT8udHlwZSA9PT0gJ1RhYmxlJyAmJiBzZWxlY3RDb2x1bW4oKSA/IGdldFZhbHVlQnlBcnJheVBhdGgoJ2ZpZWxkc01ldGEnLCAndW5pcXVlSWRlbnRpZmllcicsIHNlbGVjdENvbHVtbigpLCdzdHlsZS4nICsga2V5LCB0cnVlKSA6IChzZWxlY3RlZEVsZW1lbnQoKSB8IGdldFZhbHVlQnlQYXRoIDogJ3N0eWxlLicgKyBrZXkpXCJcbiAgICAgICAgICAgICAgICAoaW5wdXQpPVwiKHNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnICYmIHNlbGVjdENvbHVtbigpICkgPyB1cGRhdGVWYWx1ZUJ5QXJyYXlQYXRoKCdmaWVsZHNNZXRhJywgJ3VuaXF1ZUlkZW50aWZpZXInLCBzZWxlY3RDb2x1bW4oKSwgJ3N0eWxlLicgKyBrZXksICRldmVudC50YXJnZXQudmFsdWUsIHRydWUpIDogc2V0VmFsdWVCeVBhdGgoJ3N0eWxlLicgKyBrZXksICRldmVudC50YXJnZXQudmFsdWUpXCJcbiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIkVudGVyIHt7IGtleSB9fVwiXG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICB9XG4gIDwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJ0YWItY29udGVudFwiICpuZ0lmPVwiYWN0aXZlVGFiKCkgPT09ICdhcHBlYXJhbmNlJ1wiPlxuICAgIEBkZWZlciAod2hlbiBnZXRQcm9wZXJ0aWVzKCkpIHtcbiAgICAgIDxkaXY+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHByb3Agb2YgZ2V0UHJvcGVydGllcygpPy5hcHBlYXJhbmNlOyB0cmFja0J5OiB0cmFja0J5UHJvcFwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJ0ZXh0LXNtXCI+e3sgcHJvcC5sYWJlbFBhdGggfCBueHRDdXN0b21UcmFuc2xhdGUgOiBwcm9wLmxhYmVsIH19PC9sYWJlbD5cbiAgICAgICAgICAgIDxzZWxlY3RcbiAgICAgICAgICAgICAgKm5nSWY9XCJwcm9wLnR5cGUgPT09ICdzZWxlY3QnXCJcbiAgICAgICAgICAgICAgW25nTW9kZWxdPVwiKHNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnICYmIChwcm9wLnRhcmdldEFycmF5IHx8IHByb3AuaXNUYWJsZUNvbHVtbikgPyAoZ2V0VmFsdWVCeUFycmF5UGF0aChwcm9wLnRhcmdldEFycmF5LCBwcm9wLnRhcmdldEFycmF5S2V5LCBzZWxlY3RDb2x1bW4oKSwgcHJvcC5rZXksIHByb3AuaXNUYWJsZUNvbHVtbikpIDogKHNlbGVjdGVkRWxlbWVudCgpIHwgZ2V0VmFsdWVCeVBhdGggOiBwcm9wLmtleSkpXCJcbiAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiKHNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnICYmIChwcm9wLnRhcmdldEFycmF5IHx8IHByb3AuaXNUYWJsZUNvbHVtbikgPyB1cGRhdGVWYWx1ZUJ5QXJyYXlQYXRoKHByb3AudGFyZ2V0QXJyYXksIHByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCBwcm9wLmtleSwgJGV2ZW50LCBwcm9wLmlzVGFibGVDb2x1bW4sIHByb3AuaXNUcmFuc2xhdGUpIDogc2V0VmFsdWVCeVBhdGgocHJvcC5rZXksICRldmVudCwgcHJvcC5pc1RyYW5zbGF0ZSkpXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIHByb3Aub3B0aW9uc1wiIFt2YWx1ZV09XCJvcHRpb24udmFsdWVcIj57eyBvcHRpb24ubGFiZWxQYXRoIHwgbnh0Q3VzdG9tVHJhbnNsYXRlIDogb3B0aW9uLmxhYmVsIH19PC9vcHRpb24+XG4gICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAqbmdJZj1cInByb3AudHlwZSA9PT0gJ3RleHQnXCJcbiAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwicHJvcC5wbGFjZWhvbGRlclwiXG4gICAgICAgICAgICAgIFtuZ01vZGVsXT1cInNlbGVjdGVkRWxlbWVudCgpIHwgZ2V0VmFsdWVCeVBhdGggOiBwcm9wLmtleVwiXG4gICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInNldFZhbHVlQnlQYXRoKHByb3Aua2V5LCAkZXZlbnQsIHByb3AuaXNUcmFuc2xhdGUpXCJcbiAgICAgICAgICAgIC8+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4LWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwicHJvcC50eXBlID09PSAnY29sb3InXCIgY2xhc3M9XCJjb2xvci1zZWxlY3RvclwiPlxuICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgdHlwZT1cImNvbG9yXCJcbiAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInNlbGVjdGVkRWxlbWVudCgpPy5mb250Q29sb3JcIlxuICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwic2V0VmFsdWVCeVBhdGgoJ2ZvbnRDb2xvcicsICRldmVudCwgcHJvcC5pc1RyYW5zbGF0ZSlcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJwcm9wLnR5cGUgPT09ICdjb2xvcidcIiBjbGFzcz1cImhleC1pbnB1dC1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICA8c3Bhbj57eyAnSEVYX0NPREUnIHwgbnh0Q3VzdG9tVHJhbnNsYXRlIDogJ0hFWCBDb2RlJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInNlbGVjdGVkRWxlbWVudCgpIHwgZ2V0VmFsdWVCeVBhdGggOiBwcm9wLmtleVwiXG4gICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJzZXRWYWx1ZUJ5UGF0aChwcm9wLmtleSwgJGV2ZW50LCBwcm9wLmlzVHJhbnNsYXRlKVwiXG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJwcm9wLnR5cGUgPT09ICdidXR0b24tdG9nZ2xlJ1wiIGNsYXNzPVwiYnV0dG9uLXRvZ2dsZS13cmFwcGVyXCI+XG4gICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInRvZ2dsZS1idXR0b25cIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJkdXBsaWNhdGVGaWVsZChzZWxlY3RlZEVsZW1lbnQoKSlcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgIHt7ICdBRERfRFVQTElDQVRFJyB8IG54dEN1c3RvbVRyYW5zbGF0ZSA6ICdBZGQgRHVwbGljYXRlJyB9fVxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvZGl2PlxuICAgIH1cbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cImJ1dHRvbi1jb250YWluZXJcIiAqbmdJZj1cIiF0ZW1wbGF0ZVNlbGVjdGVkXCI+XG4gICAgPGJ1dHRvbiBjbGFzcz1cImNhbmNlbC1idG5cIiAoY2xpY2spPVwib25DYW5jZWwoKVwiPnt7ICdDQU5DRUwnIHwgbnh0Q3VzdG9tVHJhbnNsYXRlIDogJ0NhbmNlbCcgfX08L2J1dHRvbj5cbiAgICA8YnV0dG9uIGNsYXNzPVwic2F2ZS1idG5cIiAoY2xpY2spPVwiaGFuZGxlQnV0dG9uQ2xpY2soKVwiPnt7ICdTQVZFJyB8IG54dEN1c3RvbVRyYW5zbGF0ZSA6ICdTYXZlJyB9fTwvYnV0dG9uPlxuICA8L2Rpdj5cblxuICA8ZGl2IGNsYXNzPVwiYnV0dG9uLWNvbnRhaW5lclwiICpuZ0lmPVwidGVtcGxhdGVTZWxlY3RlZFwiIHN0eWxlPVwibWFyZ2luLXRvcDogMjBweDtcIj5cbiAgICA8YnV0dG9uIGNsYXNzPVwic2F2ZS1idG5cIiAoY2xpY2spPVwiaGFuZGxlVGVtcGxhdGVTYXZlKClcIj57eyAnU0FWRV9URU1QTEFURScgfCBueHRDdXN0b21UcmFuc2xhdGUgOiAnU2F2ZSBUZW1wbGF0ZScgfX08L2J1dHRvbj5cbiAgPC9kaXY+XG48L2Rpdj4iXX0=
|