@rangertechnologies/ngnxt 2.1.242 → 2.1.243

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/esm2022/environments/version.mjs +2 -2
  2. package/esm2022/lib/components/custom-calendar/custom-calendar.component.mjs +1 -11
  3. package/esm2022/lib/components/custom-dropdown/custom-dropdown.component.mjs +6 -9
  4. package/esm2022/lib/components/datatable/datatable.component.mjs +347 -218
  5. package/esm2022/lib/components/file-upload/file-upload.component.mjs +6 -6
  6. package/esm2022/lib/components/list-view-filter/list-view-filter.component.mjs +1 -3
  7. package/esm2022/lib/components/nxt-input/nxt-input.component.mjs +18 -7
  8. package/esm2022/lib/components/pick-location/pick-location.component.mjs +6 -13
  9. package/esm2022/lib/components/search-box/search-box.component.mjs +14 -10
  10. package/esm2022/lib/i18n.component.mjs +1 -3
  11. package/esm2022/lib/pages/booklet/booklet.component.mjs +4 -6
  12. package/esm2022/lib/pages/builder/element/element.component.mjs +41 -31
  13. package/esm2022/lib/pages/builder/form/form.component.mjs +1 -1
  14. package/esm2022/lib/pages/builder/properties/common-fields.constants.mjs +5 -5
  15. package/esm2022/lib/pages/builder/properties/properties.component.mjs +610 -687
  16. package/esm2022/lib/pages/pdfDesigner/pdf-designer/pdf-designer.component.mjs +12 -8
  17. package/esm2022/lib/pages/pdfDesigner/pdf-properties/pdf-properties.component.mjs +4 -12
  18. package/esm2022/lib/pages/questionbook/questionbook.component.mjs +2 -5
  19. package/esm2022/lib/pages/questionnaire/questionnaire.component.mjs +2 -170
  20. package/esm2022/lib/pipe/get-value.pipe.mjs +2 -2
  21. package/esm2022/lib/services/change.service.mjs +1 -5
  22. package/esm2022/lib/services/data.service.mjs +1 -4
  23. package/esm2022/lib/services/form-builder.service.mjs +35 -25
  24. package/esm2022/lib/services/pdf-designer.service.mjs +3 -6
  25. package/esm2022/lib/services/salesforce.service.mjs +1 -6
  26. package/esm2022/lib/services/storage.service.mjs +1 -2
  27. package/esm2022/lib/services/translation.service.mjs +1 -2
  28. package/fesm2022/rangertechnologies-ngnxt.mjs +8666 -8793
  29. package/fesm2022/rangertechnologies-ngnxt.mjs.map +1 -1
  30. package/lib/components/custom-dropdown/custom-dropdown.component.d.ts +2 -1
  31. package/lib/components/datatable/datatable.component.d.ts +34 -28
  32. package/lib/components/file-upload/file-upload.component.d.ts +2 -1
  33. package/lib/components/nxt-input/nxt-input.component.d.ts +5 -1
  34. package/lib/components/pick-location/pick-location.component.d.ts +2 -1
  35. package/lib/components/search-box/search-box.component.d.ts +2 -1
  36. package/lib/pages/builder/element/element.component.d.ts +2 -15
  37. package/lib/pages/builder/properties/common-fields.constants.d.ts +4 -16
  38. package/lib/pages/builder/properties/properties.component.d.ts +95 -129
  39. package/lib/pipe/get-value.pipe.d.ts +1 -1
  40. package/lib/services/form-builder.service.d.ts +0 -1
  41. package/package.json +1 -1
  42. package/rangertechnologies-ngnxt-2.1.243.tgz +0 -0
  43. package/rangertechnologies-ngnxt-2.1.242.tgz +0 -0
@@ -1,46 +1,54 @@
1
- import { Component, EventEmitter, HostListener, Input, Output, ViewChild } from '@angular/core';
2
- import { v4 as uuidv4 } from 'uuid'; //AP-28MAR25 import uuid
1
+ import { ChangeDetectionStrategy, Component, EventEmitter, HostListener, Input, Output, signal, computed, ViewChild } from '@angular/core';
3
2
  import { CommonModule } from '@angular/common';
4
3
  import { FormsModule } from '@angular/forms';
5
- import { ImageCropperComponent } from "../../../components/image-cropper/component/image-cropper.component";
6
- import { NxtSearchBox } from "../../../components/search-box/search-box.component";
4
+ import { v4 as uuidv4 } from 'uuid';
7
5
  //AP-25JUN25-Importing common constants for element, field, and appearance properties
8
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
9
  import * as i0 from "@angular/core";
10
- import * as i1 from "@angular/common/http";
11
- import * as i2 from "../../../services/form-builder.service";
12
- import * as i3 from "../../../services/template.service";
13
- import * as i4 from "@angular/common";
14
- import * as i5 from "@angular/forms";
10
+ import * as i1 from "../../../services/form-builder.service";
11
+ import * as i2 from "../../../services/template.service";
12
+ import * as i3 from "@angular/common";
13
+ import * as i4 from "@angular/forms";
14
+ // Custom pipe for path-based value access
15
+ export class GetValueByPathPipe {
16
+ transform(obj, path, defaultValue = '') {
17
+ if (!obj || !path)
18
+ return defaultValue;
19
+ return path.split('.').reduce((o, k) => o?.[k] ?? defaultValue, obj);
20
+ }
21
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GetValueByPathPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
22
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: GetValueByPathPipe, isStandalone: true, name: "getValueByPath" });
23
+ }
24
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GetValueByPathPipe, decorators: [{
25
+ type: Pipe,
26
+ args: [{
27
+ name: 'getValueByPath',
28
+ standalone: true,
29
+ pure: true
30
+ }]
31
+ }] });
15
32
  export class PropertiesComponent {
16
- http;
17
33
  formBuilderService;
18
34
  templateService;
19
- element;
20
- from;
21
- columns;
22
- createElementConfig(config) {
23
- return {
24
- elementProps: [...COMMON_ELEMENT_PROPS, ...(config?.customElementProps || [])],
25
- fieldProps: [...COMMON_FIELD_PROPS, ...(config?.customFieldProps || [])],
26
- appearance: [...COMMON_APPEARANCE_PROPS, ...(config?.customAppearanceProps || [])]
27
- };
35
+ templateSelected = false;
36
+ set selectedElementType(value) {
37
+ this.selectedElementTypeSig.set(value);
28
38
  }
29
39
  formButtonHandler = new EventEmitter();
30
40
  templateSaveHandler = new EventEmitter();
31
- selectedOption = '';
32
- selectedElementIndex = -1;
33
- selectedElementType = '';
34
- selectedAlign = 'align-left'; // Add this property
35
- selectedStyles = []; // Using array since multiple styles can be selected
36
- errorMessage = '';
37
- selectedElement = null; // Receive the selected element
38
- headerSelect = false;
39
- bookId;
40
- book;
41
- activeTab = 'attributes';
42
- selectColumn;
43
- transform = {
41
+ dropdown;
42
+ // Signals for reactive state
43
+ selectedElementTypeSig = signal('');
44
+ selectedElement = signal(null);
45
+ selectedElementIndex = signal(-1);
46
+ headerSelect = signal(false);
47
+ book = signal(null);
48
+ bookId = signal(null);
49
+ activeTab = signal('attributes');
50
+ selectColumn = signal(null);
51
+ transform = signal({
44
52
  translateUnit: 'px',
45
53
  scale: 1,
46
54
  rotate: 0,
@@ -48,10 +56,19 @@ export class PropertiesComponent {
48
56
  flipV: false,
49
57
  translateH: 0,
50
58
  translateV: 0
51
- };
52
- canvasRotation = 0;
53
- cropper;
54
- loading = false;
59
+ });
60
+ canvasRotation = signal(0);
61
+ cropper = signal(undefined);
62
+ loading = signal(false);
63
+ isLinkDropdownOpen = signal(false);
64
+ errorMessage = signal('');
65
+ bookSubtext = signal({
66
+ endpoint: 'https://dev-api.valarhr.com/nxt',
67
+ variable: null,
68
+ field: ['label', 'name'],
69
+ defaultField: 'label'
70
+ });
71
+ isStyleExpanded = signal(false);
55
72
  cropperMaxHeight = 0;
56
73
  cropperMaxWidth = 0;
57
74
  cropperMinHeight = 0;
@@ -60,372 +77,226 @@ export class PropertiesComponent {
60
77
  cropperStaticHeight = 0;
61
78
  aspectRatio = 4 / 3;
62
79
  roundCropper = false;
63
- imageChangedEvent = null;
80
+ isExpanded = false;
64
81
  alignImage = 'center';
65
- // "endpoint": "https://dev-api.valarhr.com/nxt",
66
- // SKS28MAR25 default book search endpoint
67
- bookSubtext = {
68
- "endpoint": "https://dev-api.valarhr.com/nxt",
69
- "variable": null,
70
- "field": ['label', 'name'],
71
- "defaultField": "label"
72
- };
73
- isLinkDropdownOpen = false;
74
- templateSelected = false;
75
- dropdown;
76
- draggedId = null;
77
- formElements = [];
78
- unique_id = 'book-1234'; // should be consistent
79
- selectedTemplate;
80
- elementProperties = {
81
- // AP-10MAR25 - Defines the Header element with a text input field
82
- // AP-25MAR25 Add subtext all variables
83
- 'Header': {
84
- elementProps: [
85
- { label: 'Label', placeholder: 'Enter Text', type: 'text', key: 'title' }
86
- ]
87
- },
88
- // AP-19MAR25 Add Line Property
89
- 'Line': {
90
- elementProps: [
91
- { label: 'Line Width', type: 'fieldSize', key: 'size' },
92
- { label: 'Padding Top', type: 'number', key: 'paddingTop', placeholder: 'Enter padding top' },
93
- { label: 'Padding Bottom', type: 'number', key: 'paddingBottom', placeholder: 'Enter padding bottom' },
94
- {
95
- label: 'Line Style', type: 'select', key: 'lineStyle',
96
- options: ['Solid', 'Dashed', 'Dotted']
97
- }
98
- ],
99
- fieldProps: []
100
- },
101
- 'Space': {
102
- elementProps: [
103
- { label: 'Element', type: 'number', key: 'questionNumber' },
104
- { label: 'Field Size', type: 'fieldSize', key: 'size' },
105
- ],
106
- fieldProps: []
107
- },
108
- "Table": {
109
- "elementProps": [
110
- { label: 'Is Label', placeholder: 'Enter Text ', type: 'checkbox', key: 'style.showLabel' },
111
- { key: 'primaryKey' },
112
- { "label": "tableName", "placeholder": "Employee Details", "type": "text", "key": "questionText" },
113
- { "label": "inputTextAlignment", "placeholder": "Left", "type": "text", "key": "inputTextAlignment" },
114
- { "label": "tableScaleSize", "placeholder": "06 - Full Scale", "type": "text", "key": "tableScaleSize" },
115
- { "label": "isNosIndicator", "placeholder": "06 - Full Scale", "type": "checkbox", "key": "tableConfig.isNosIndicator" },
116
- { "label": "isPagination", "placeholder": "06 - Full Scale", "type": "checkbox", "key": "tableConfig.isPagination" },
117
- { "label": "addInlineRecord", "placeholder": "06 - Full Scale", "type": "checkbox", "key": "tableConfig.addInlineRecord" },
118
- { "label": "actionButton", "placeholder": "06 - Full Scale", "type": "checkbox", "key": "tableConfig.actionButton" },
119
- { "label": "searchBar", "placeholder": "06 - Full Scale", "type": "checkbox", "key": "tableConfig.searchBar" },
120
- { "label": "isDeleteRow", "placeholder": "06 - Full Scale", "type": "checkbox", "key": "tableConfig.isDeleteRow" },
121
- { "label": "isEditRow", "placeholder": "06 - Full Scale", "type": "checkbox", "key": "tableConfig.isEditRow" },
122
- { "label": "isButtons", "placeholder": "06 - Full Scale", "type": "checkbox", "key": "tableConfig.isButtons" },
123
- { "label": "rowChoice", "placeholder": "", "type": "text", "key": "rowChoice" },
124
- { label: 'questionNumber', type: 'number', key: 'questionNumber' },
125
- { label: 'Field Size', type: 'fieldSize', key: 'size' },
126
- ],
127
- "fieldProps": [
128
- { "label": "tableId", "placeholder": "Emp_Table_01", "type": "text", "key": "tableId" },
129
- { "label": "helpText", "placeholder": "Enter message", "type": "text", "key": "helpText" },
130
- { "label": "defaultValue", "placeholder": "Default Value", "type": "text", "key": "defaultValue" },
131
- { label: 'Reference', placeholder: 'Reference Field', type: 'text', key: 'referenceField' },
132
- {
133
- "label": "", "placeholder": "Enter Text", "type": "subQuestion", "key": "isSubText",
134
- "subQuestion": [
135
- { "label": "End Point", "placeholder": "endpoint", "type": "text", "key": "subText.endpoint" },
136
- { "label": "Variable", "placeholder": "variable", "type": "text", "key": "subText.variable" },
137
- { "label": "Field", "placeholder": "field", "type": "text", "key": "subText.field" },
138
- { "label": "Default Field", "placeholder": "defaultField", "type": "text", "key": "subText.defaultField" },
139
- { "label": "Label Field", "placeholder": "labelField", "type": "text", "key": "subText.labelField" },
140
- { "label": "Value Field", "placeholder": "valueField", "type": "text", "key": "subText.valueField" },
141
- { "label": "Source Question Id", "placeholder": "sourceQuestionId", "type": "text", "key": "subText.sourceQuestionId" },
142
- { "label": "Dependent Value", "placeholder": "dependentValue", "type": "text", "key": "subText.dependentValue" },
143
- { "label": "Dependent Field", "placeholder": "isDependentField", "type": "boolean", "key": "subText.isDependentField" },
144
- { "label": "Query Field", "placeholder": "queryField", "type": "text", "key": "subText.queryField" },
145
- { "label": "Query Value", "placeholder": "queryValue", "type": "text", "key": "subText.queryValue" },
146
- { "label": "Query Value Ref", "placeholder": "queryValueRef", "type": "text", "key": "subText.queryValueReference" },
147
- { "label": "Unique Key", "placeholder": "uniqueKey", "type": "text", "key": "subText.uniqueKey" },
148
- ]
149
- },
150
- ],
151
- "appearance": [
152
- {
153
- label: 'Select Font', type: 'select', key: 'font', placeholder: 'Left', required: true,
154
- options: ['Helvetica Neue', 'Arial', 'Times New Roman', 'Roboto']
155
- },
156
- { label: 'Font Color', type: 'color', key: 'fontColor', defaultValue: '', required: true },
157
- {
158
- label: 'Font Size', type: 'select', key: 'fontSize', defaultValue: '', required: true,
159
- options: [
160
- { label: 'Small', value: '12px' },
161
- { label: 'Medium', value: '14px' },
162
- { label: 'Large', value: '16px' }
163
- ]
164
- },
165
- {
166
- label: 'Font Width', type: 'select', key: 'fontWeight', defaultValue: '', required: true,
167
- options: [
168
- { value: '400', label: '400-Normal' },
169
- { value: '500', label: '500-Medium' },
170
- { value: '600', label: '600-Semi Bold' },
171
- { value: '700', label: '700-Bold' }
172
- ]
173
- },
174
- { label: 'Duplicate Field', type: 'button-toggle', key: 'duplicateField', defaultValue: false }
175
- ]
176
- },
177
- "TableColumn": {
178
- "elementProps": [
179
- { "label": "headerLabels", "placeholder": "Employee Details", "type": "text", "targetArray": "fieldsMeta", "targetArrayKey": "uniqueIdentifier", "key": "label" },
180
- { "label": "apiName", "placeholder": "Employee Details", "type": "text", "targetArray": "fieldsMeta", "targetArrayKey": "uniqueIdentifier", "key": "apiName" },
181
- {
182
- "label": "Summary Column", "placeholder": "Summary Column", "type": "subQuestion", "targetArray": "fieldsMeta", "targetArrayKey": "uniqueIdentifier", "key": "summaryColumn",
183
- "subQuestion": [
184
- { "label": "Type", "placeholder": "Employee Details", "type": "text", "targetArray": "fieldsMeta", "targetArrayKey": "uniqueIdentifier", "key": "fldType" },
185
- { "label": "Operation", "placeholder": "Employee Details", "type": "text", "targetArray": "fieldsMeta", "targetArrayKey": "uniqueIdentifier", "key": "operation" },
186
- { "label": "Operands", "placeholder": "Employee Details", "type": "array", "targetArray": "fieldsMeta", "targetArrayKey": "uniqueIdentifier", "key": "operands" },
187
- ]
188
- },
189
- {
190
- "label": "Summary Row", "placeholder": "Summary Row", "type": "subQuestion", "targetArray": "fieldsMeta", "targetArrayKey": "uniqueIdentifier", "key": "summaryRow", "subQuestion": [
191
- { "label": "Type", "placeholder": "Employee Details", "type": "text", "targetArray": "fieldsMeta", "targetArrayKey": "uniqueIdentifier", "key": "fldType" },
192
- { "label": "operation", "placeholder": "operation", "type": "text", "targetArray": "fieldsMeta", "targetArrayKey": "uniqueIdentifier", "key": "operation" },
193
- { "label": "column", "placeholder": "Employee Details", "type": "radio", "targetArray": "fieldsMeta", "targetArrayKey": "uniqueIdentifier", "key": "column" },
194
- { "label": "operands", "placeholder": "Employee Details", "type": "array", "targetArray": "fieldsMeta", "targetArrayKey": "uniqueIdentifier", "key": "operands" },
195
- ]
196
- },
197
- { "label": "inputTextAlignment", "placeholder": "Left", "type": "text", "key": "inputTextAlignment" },
198
- { "label": "tableScaleSize", "placeholder": "06 - Full Scale", "type": "text", "key": "tableScaleSize" },
199
- { "label": "rowChoice", "placeholder": "", "type": "text", "key": "rowChoice" },
200
- ],
201
- "fieldProps": [
202
- { "label": "tableId", "placeholder": "Emp_Table_01", "type": "text", "key": "tableId" },
203
- { "label": "inputTextAlignment", "placeholder": "Left", "type": "text", "key": "inputTextAlignment" },
204
- { "label": "helpText", "placeholder": "Enter help message here", "type": "text", "key": "helpText" },
205
- { "label": "defaultValue", "placeholder": "Default Value", "type": "text", "key": "defaultValue" },
206
- { "label": "referenceAnchor", "placeholder": "http://source/rangernxt_bio_data/74/d.doc", "type": "text", "key": "referenceAnchor" },
207
- ],
208
- "appearance": [
209
- {
210
- label: 'Select Font', type: 'select', key: 'font', placeholder: 'Left', required: true,
211
- options: ['Helvetica Neue', 'Arial', 'Times New Roman', 'Roboto']
212
- },
213
- { label: 'Font Color', type: 'color', key: 'fontColor', defaultValue: '', required: true },
214
- {
215
- label: 'Font Size', type: 'select', key: 'fontSize', defaultValue: '', required: true,
216
- options: [
217
- { label: 'Small', value: '12px' },
218
- { label: 'Medium', value: '14px' },
219
- { label: 'Large', value: '16px' }
220
- ]
221
- },
222
- {
223
- label: 'Font Width', type: 'select', key: 'fontWeight', defaultValue: '', required: true,
224
- options: [
225
- { value: '400', label: '400-Normal' },
226
- { value: '500', label: '500-Medium' },
227
- { value: '600', label: '600-Semi Bold' },
228
- { value: '700', label: '700-Bold' }
229
- ]
230
- },
231
- { label: 'Duplicate Field', type: 'button-toggle', key: 'duplicateField', defaultValue: false }
232
- ]
233
- },
234
- ListColumn: this.createElementConfig({
235
- customFieldProps: [
236
- ...COMMON_OPTIONS_FIELD.map(opt => ({
237
- type: 'list'
238
- })),
239
- ],
240
- customElementProps: [
241
- { label: "headerLabels", placeholder: "Employee Details", type: "text", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "label" },
242
- { label: "apiName", placeholder: "Employee Details", type: "text", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "apiName" },
243
- {
244
- label: "Summary Column", placeholder: "Summary Column", type: "subQuestion", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "summaryColumn",
245
- subQuestion: [
246
- { label: "Type", placeholder: "Employee Details", type: "text", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "fldType" },
247
- { label: "Operation", placeholder: "Employee Details", type: "text", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "operation" },
248
- { label: "Operands", placeholder: "Employee Details", type: "array", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "operands" },
249
- ]
250
- },
251
- {
252
- label: "Summary Row", placeholder: "Summary Row", type: "subQuestion", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "summaryRow",
253
- subQuestion: [
254
- { label: "Type", placeholder: "Employee Details", type: "text", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "fldType" },
255
- { label: "operation", placeholder: "operation", type: "text", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "operation" },
256
- { label: "column", placeholder: "Employee Details", type: "radio", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "column" },
257
- { label: "operands", placeholder: "Employee Details", type: "array", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "operands" },
258
- ]
259
- },
260
- ]
261
- }),
262
- DropdownColumn: this.createElementConfig({
263
- customFieldProps: [
264
- ...COMMON_OPTIONS_FIELD.map(opt => ({
265
- ...opt,
266
- type: 'dropdown'
267
- })),
268
- ],
269
- customElementProps: [
270
- { label: "headerLabels", placeholder: "Employee Details", type: "text", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "label" },
271
- { label: "apiName", placeholder: "Employee Details", type: "text", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "apiName" },
272
- {
273
- label: "Summary Column", placeholder: "Summary Column", type: "subQuestion", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "summaryColumn",
274
- subQuestion: [
275
- { label: "Type", placeholder: "Employee Details", type: "text", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "fldType" },
276
- { label: "Operation", placeholder: "Employee Details", type: "text", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "operation" },
277
- { label: "Operands", placeholder: "Employee Details", type: "array", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "operands" },
278
- ]
279
- },
280
- {
281
- label: "Summary Row", placeholder: "Summary Row", type: "subQuestion", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "summaryRow",
282
- subQuestion: [
283
- { label: "Type", placeholder: "Employee Details", type: "text", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "fldType" },
284
- { label: "operation", placeholder: "operation", type: "text", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "operation" },
285
- { label: "column", placeholder: "Employee Details", type: "radio", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "column" },
286
- { label: "operands", placeholder: "Employee Details", type: "array", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "operands" },
287
- ]
288
- },
289
- ]
290
- }),
291
- DateColumn: this.createElementConfig({
292
- customFieldProps: [
293
- ...COMMON_OPTIONS_FIELD.map(opt => ({
294
- type: 'date'
295
- })),
296
- ],
297
- customElementProps: [
298
- { label: "headerLabels", placeholder: "Employee Details", type: "text", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "label" },
299
- { label: "apiName", placeholder: "Employee Details", type: "text", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "apiName" },
300
- {
301
- label: "Summary Column", placeholder: "Summary Column", type: "subQuestion", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "summaryColumn",
302
- subQuestion: [
303
- { label: "Type", placeholder: "Employee Details", type: "text", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "fldType" },
304
- { label: "Operation", placeholder: "Employee Details", type: "text", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "operation" },
305
- { label: "Operands", placeholder: "Employee Details", type: "array", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "operands" },
306
- ]
307
- },
308
- {
309
- label: "Summary Row", placeholder: "Summary Row", type: "subQuestion", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "summaryRow",
310
- subQuestion: [
311
- { label: "Type", placeholder: "Employee Details", type: "text", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "fldType" },
312
- { label: "operation", placeholder: "operation", type: "text", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "operation" },
313
- { label: "column", placeholder: "Employee Details", type: "radio", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "column" },
314
- { label: "operands", placeholder: "Employee Details", type: "array", targetArray: "fieldsMeta", targetArrayKey: "uniqueIdentifier", key: "operands" },
315
- ]
316
- },
317
- ]
318
- }),
319
- Checkbox: this.createElementConfig({
320
- customFieldProps: COMMON_OPTIONS_FIELD.map(opt => ({
321
- ...opt,
322
- type: 'checkbox'
323
- }))
324
- }),
325
- Dropdown: this.createElementConfig({
326
- customFieldProps: COMMON_OPTIONS_FIELD.map(opt => ({
327
- ...opt,
328
- type: 'dropdown'
329
- }))
330
- }),
331
- Radio: this.createElementConfig({
332
- customFieldProps: COMMON_OPTIONS_FIELD.map(opt => ({
333
- ...opt,
334
- type: 'checkbox'
335
- }))
336
- }),
337
- Text: this.createElementConfig(),
338
- Calendar: this.createElementConfig(),
339
- Date: this.createElementConfig(),
340
- Time: this.createElementConfig(),
341
- DateTime: this.createElementConfig(),
342
- Email: this.createElementConfig(),
343
- Book: this.createElementConfig(),
344
- List: this.createElementConfig(),
345
- TextArea: this.createElementConfig(),
346
- RichTextArea: this.createElementConfig(),
347
- Number: this.createElementConfig(),
348
- Image: this.createElementConfig(),
349
- Label: this.createElementConfig(),
350
- Boolean: this.createElementConfig(),
351
- File: this.createElementConfig(),
352
- Icon: this.createElementConfig(), //MSM10JUL25 icon selector element
353
- };
354
- constructor(http, formBuilderService, templateService) {
355
- this.http = http;
82
+ 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'];
83
+ // Add these properties to your component class
84
+ _cachedProperties = null;
85
+ _lastSelectedElement = null;
86
+ _lastSelectedColumn = null;
87
+ // Computed signals for memoization
88
+ fieldAsString = computed(() => this.bookSubtext().field.join(', '));
89
+ filteredColumns = computed(() => {
90
+ const fieldsMeta = this.selectedElement()?.fieldsMeta ?? [];
91
+ return Array.isArray(fieldsMeta)
92
+ ? fieldsMeta.filter(column => column.uniqueIdentifier !== this.selectColumn())
93
+ : [];
94
+ });
95
+ // Memoized properties
96
+ elementProperties = computed(() => this.createElementProperties());
97
+ constructor(formBuilderService, templateService) {
356
98
  this.formBuilderService = formBuilderService;
357
99
  this.templateService = templateService;
358
100
  }
359
- handleTemplateSelection(event) {
360
- this.formElements = event.elements;
361
- this.selectedTemplate = event.selectedTemplate;
362
- this.templateService.formElements = this.formElements;
363
- this.templateService.book = this.book;
364
- this.templateService.unique_id = this.unique_id;
365
- }
366
- duplicateField(element) {
367
- const elements = this.formBuilderService.getElements();
368
- const copy = JSON.parse(JSON.stringify(element));
369
- //AP-18APR25 Generate a new ID using the service's method
370
- copy.id = this.formBuilderService.addElementWithId();
371
- //copy.uuid = copy.id;
372
- // AP-18APR25 Set the questionNumber to the next available number
373
- copy.questionNumber = elements.length + 1;
374
- this.formBuilderService.addElement(copy);
375
- }
376
- saveData() {
377
- this.templateService.formElements = this.formElements;
378
- this.templateService.book = this.book;
379
- this.templateService.unique_id = this.unique_id;
380
- const updatedBook = this.templateService.download();
381
- }
382
101
  ngOnInit() {
383
- //AP-10MAR25 Subscribes to header selection changes and updates the selected element
384
102
  this.formBuilderService.selectHeaderSubject$.subscribe(header => {
385
103
  if (header) {
386
- if (!this.selectedElement) {
387
- this.selectedElement = {};
388
- }
389
- this.selectedElement['type'] = header;
390
- this.headerSelect = true;
391
- this.book = this.formBuilderService.getBook();
392
- this.bookId = this.book.records[0].id;
104
+ this.selectedElement.set({ type: header });
105
+ this.headerSelect.set(true);
106
+ const bookData = this.formBuilderService.getBook();
107
+ this.book.set(bookData);
108
+ this.bookId.set(bookData?.records[0]?.id);
393
109
  }
394
110
  });
395
111
  this.formBuilderService.selectedElement$.subscribe(index => {
396
- this.selectedElementIndex = index;
397
- this.headerSelect = false;
112
+ this.selectedElementIndex.set(index);
113
+ this.headerSelect.set(false);
398
114
  if (index >= 0) {
399
115
  const elements = this.formBuilderService.getElements();
400
- this.selectedElement = elements[index];
401
- if (this.selectedElement?.type === 'Table') {
402
- this.selectedElement['fieldsMeta'] = typeof this.selectedElement.fieldsMeta === 'object' ? this.selectedElement.fieldsMeta : JSON.parse(this.selectedElement['fieldsMeta'] || []);
403
- this.selectColumn = this.formBuilderService.getSelectTableColumn() === undefined ? null : this.formBuilderService.getSelectTableColumn();
116
+ if (!elements || !Array.isArray(elements) || index >= elements.length) {
117
+ this.selectedElement.set(null); // Reset selectedElement if invalid
118
+ this.selectColumn.set(null);
119
+ return;
120
+ }
121
+ const element = { ...elements[index] }; // Safe to spread since we checked
122
+ let fieldsMeta = element?.fieldsMeta;
123
+ if (element?.type === 'Table') {
124
+ try {
125
+ fieldsMeta = Array.isArray(fieldsMeta)
126
+ ? fieldsMeta
127
+ : JSON.parse(fieldsMeta || '[]');
128
+ }
129
+ catch (e) {
130
+ // console.error('Error parsing fieldsMeta:', e);
131
+ fieldsMeta = [];
132
+ }
133
+ this.selectColumn.set(this.formBuilderService.getSelectTableColumn() ?? null);
404
134
  }
405
135
  else {
406
- this.selectColumn = null;
136
+ this.selectColumn.set(null);
407
137
  }
138
+ this.selectedElement.set({ ...element, fieldsMeta });
408
139
  }
409
- this.getProperties();
410
- });
411
- this.formBuilderService.selectHeaderSubject$.subscribe(action => {
412
- if (action) {
413
- this.book = this.formBuilderService.getBook();
140
+ else {
141
+ this.selectedElement.set(null); // Reset if index is invalid
142
+ this.selectColumn.set(null);
414
143
  }
415
144
  });
416
- if (this.from === 'formBuilder') {
417
- const fieldsMeta = typeof this.element.fieldsMeta === 'string'
418
- ? JSON.parse(this.element.fieldsMeta)
419
- : this.element.fieldsMeta;
420
- this.columns = fieldsMeta.map(column => ({
421
- ...column,
422
- type: column.fldType || 'Text' // Default to 'Text' if fldType not available
423
- }));
145
+ const element = this.selectedElement();
146
+ if (element) {
147
+ let subText = element.subText;
148
+ if (typeof subText === 'string' && subText.trim() !== '') {
149
+ try {
150
+ subText = JSON.parse(subText);
151
+ }
152
+ catch (e) {
153
+ // console.error('Error parsing subText:', e);
154
+ subText = {};
155
+ }
156
+ }
157
+ else if (typeof subText !== 'object' || subText === null) {
158
+ subText = {};
159
+ }
160
+ if (subText && Array.isArray(subText.field)) {
161
+ subText = { ...subText, field: subText.field.join(', ') };
162
+ }
163
+ this.selectedElement.update(el => ({ ...el, subText }));
424
164
  }
425
165
  }
166
+ createElementProperties() {
167
+ return {
168
+ Header: {
169
+ elementProps: [{ label: 'Label', placeholder: 'Enter Text', type: 'text', key: 'title' }],
170
+ },
171
+ // AP-19MAR25 Add Line Property
172
+ Line: {
173
+ elementProps: [
174
+ { label: 'Line Width', type: 'fieldSize', key: 'size' },
175
+ { label: 'Padding Top', type: 'number', key: 'paddingTop', placeholder: 'Enter padding top' },
176
+ { label: 'Padding Bottom', type: 'number', key: 'paddingBottom', placeholder: 'Enter padding bottom' },
177
+ { label: 'Line Style', type: 'select', key: 'lineStyle', options: [{ label: 'Solid', value: 'Solid' }, { label: 'Dashed', value: 'Dashed' }, { label: 'Dotted', value: 'Dotted' }] }
178
+ ],
179
+ fieldProps: []
180
+ },
181
+ Space: {
182
+ elementProps: [
183
+ { label: 'Element', type: 'number', key: 'questionNumber' },
184
+ { label: 'Field Size', type: 'fieldSize', key: 'size' },
185
+ ],
186
+ fieldProps: []
187
+ },
188
+ Table: {
189
+ elementProps: [
190
+ { label: 'Is Label', placeholder: 'Enter Text', type: 'checkbox', key: 'style.showLabel' },
191
+ { label: 'primaryKey', placeholder: 'Enter Text', type: 'checkbox', key: 'primaryKey' },
192
+ { label: 'tableName', placeholder: 'Employee Details', type: 'text', key: 'questionText' },
193
+ { label: 'inputTextAlignment', placeholder: 'Left', type: 'text', key: 'inputTextAlignment' },
194
+ { label: 'tableScaleSize', placeholder: '06 - Full Scale', type: 'text', key: 'tableScaleSize' },
195
+ { label: 'isNosIndicator', placeholder: '06 - Full Scale', type: 'checkbox', key: 'tableConfig.isNosIndicator' },
196
+ { label: 'isPagination', placeholder: '06 - Full Scale', type: 'checkbox', key: 'tableConfig.isPagination' },
197
+ { label: 'addInlineRecord', placeholder: '06 - Full Scale', type: 'checkbox', key: 'tableConfig.addInlineRecord' },
198
+ { label: 'actionButton', placeholder: '06 - Full Scale', type: 'checkbox', key: 'tableConfig.actionButton' },
199
+ { label: 'searchBar', placeholder: '06 - Full Scale', type: 'checkbox', key: 'tableConfig.searchBar' },
200
+ { label: 'isDeleteRow', placeholder: '06 - Full Scale', type: 'checkbox', key: 'tableConfig.isDeleteRow' },
201
+ { label: 'isEditRow', placeholder: '06 - Full Scale', type: 'checkbox', key: 'tableConfig.isEditRow' },
202
+ { label: 'isButtons', placeholder: '06 - Full Scale', type: 'checkbox', key: 'tableConfig.isButtons' },
203
+ { label: 'rowChoice', placeholder: '', type: 'text', key: 'rowChoice' },
204
+ { label: 'questionNumber', type: 'number', key: 'questionNumber' },
205
+ { label: 'Field Size', type: 'fieldSize', key: 'size' },
206
+ ],
207
+ fieldProps: [
208
+ { label: 'tableId', placeholder: 'Emp_Table_01', type: 'text', key: 'tableId' },
209
+ { label: 'helpText', placeholder: 'Enter message', type: 'text', key: 'helpText' },
210
+ { label: 'defaultValue', placeholder: 'Default Value', type: 'text', key: 'defaultValue' },
211
+ { label: 'Reference', placeholder: 'Reference Field', type: 'text', key: 'referenceField' },
212
+ {
213
+ label: 'Sub Text', placeholder: 'Enter Text', type: 'subQuestion', key: 'isSubText',
214
+ subQuestion: [
215
+ { label: 'End Point', placeholder: 'endpoint', type: 'text', key: 'subText.endpoint' },
216
+ { label: 'Variable', placeholder: 'variable', type: 'text', key: 'subText.variable' },
217
+ { label: 'Field', placeholder: 'field', type: 'text', key: 'subText.field' },
218
+ { label: 'Default Field', placeholder: 'defaultField', type: 'text', key: 'subText.defaultField' },
219
+ { label: 'Label Field', placeholder: 'labelField', type: 'text', key: 'subText.labelField' },
220
+ { label: 'Value Field', placeholder: 'valueField', type: 'text', key: 'subText.valueField' },
221
+ { label: 'Source Question Id', placeholder: 'sourceQuestionId', type: 'text', key: 'subText.sourceQuestionId' },
222
+ { label: 'Dependent Value', placeholder: 'dependentValue', type: 'text', key: 'subText.dependentValue' },
223
+ { label: 'Dependent Field', placeholder: 'isDependentField', type: 'boolean', key: 'subText.isDependentField' },
224
+ { label: 'Query Field', placeholder: 'queryField', type: 'text', key: 'subText.queryField' },
225
+ { label: 'Query Value', placeholder: 'queryValue', type: 'text', key: 'subText.queryValue' },
226
+ { label: 'Query Value Ref', placeholder: 'queryValueRef', type: 'text', key: 'subText.queryValueReference' },
227
+ { label: 'Unique Key', placeholder: 'uniqueKey', type: 'text', key: 'subText.uniqueKey' },
228
+ ]
229
+ },
230
+ ],
231
+ appearance: [
232
+ { label: 'Select Font', type: 'select', key: 'font', placeholder: 'Left', required: true, options: [{ label: 'Helvetica Neue', value: 'Helvetica Neue' }, { label: 'Arial', value: 'Arial' }, { label: 'Times New Roman', value: 'Times New Roman' }, { label: 'Roboto', value: 'Roboto' }] },
233
+ { label: 'Font Color', type: 'color', key: 'fontColor', defaultValue: '', required: true },
234
+ { label: 'Font Size', type: 'select', key: 'fontSize', defaultValue: '', required: true, options: [{ label: 'Small', value: '12px' }, { label: 'Medium', value: '14px' }, { label: 'Large', value: '16px' }] },
235
+ { label: 'Font Width', type: 'select', key: 'fontWeight', defaultValue: '', required: true, options: [{ value: '400', label: '400-Normal' }, { value: '500', label: '500-Medium' }, { value: '600', label: '600-Semi Bold' }, { value: '700', label: '700-Bold' }] },
236
+ { label: 'Duplicate Field', type: 'button-toggle', key: 'duplicateField', defaultValue: false }
237
+ ]
238
+ },
239
+ TableColumn: {
240
+ elementProps: [
241
+ { label: 'Type', placeholder: 'Text', type: 'select', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'fldType', required: true, options: this.elementType.map(f => ({ label: f, value: f })) },
242
+ { label: 'headerLabels', placeholder: 'Employee Details', type: 'text', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'label' },
243
+ { label: 'apiName', placeholder: 'Employee Details', type: 'text', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'apiName' },
244
+ {
245
+ label: 'Summary Column', placeholder: 'Summary Column', type: 'subQuestion', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'summaryColumn',
246
+ subQuestion: [
247
+ { label: 'Type', placeholder: 'Employee Details', type: 'text', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'fldType' },
248
+ { label: 'Operation', placeholder: 'Employee Details', type: 'text', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'operation' },
249
+ { label: 'Operands', placeholder: 'Employee Details', type: 'array', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'operands' },
250
+ ]
251
+ },
252
+ {
253
+ label: 'Summary Row', placeholder: 'Summary Row', type: 'subQuestion', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'summaryRow',
254
+ subQuestion: [
255
+ { label: 'Type', placeholder: 'Employee Details', type: 'text', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'fldType' },
256
+ { label: 'operation', placeholder: 'operation', type: 'text', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'operation' },
257
+ { label: 'column', placeholder: 'Employee Details', type: 'radio', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'column' },
258
+ { label: 'columns', placeholder: 'Employee Details', type: 'array', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'columns' },
259
+ { label: 'operands', placeholder: 'Employee Details', type: 'array', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'operands' },
260
+ ]
261
+ },
262
+ { label: 'textAlignment', placeholder: 'Left', type: 'text', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'textAlignment' },
263
+ { label: 'columnScaleSize', placeholder: '06 - Full Scale', type: 'text', targetArray: 'fieldsMeta', targetArrayKey: 'uniqueIdentifier', key: 'columnScaleSize' },
264
+ ],
265
+ fieldProps: [],
266
+ appearance: []
267
+ },
268
+ Checkbox: this.createElementConfig({ customFieldProps: COMMON_OPTIONS_FIELD.map(opt => ({ ...opt, type: 'checkbox' })) }),
269
+ Dropdown: this.createElementConfig({ customFieldProps: COMMON_OPTIONS_FIELD.map(opt => ({ ...opt, type: 'dropdown' })) }),
270
+ Radio: this.createElementConfig({ customFieldProps: COMMON_OPTIONS_FIELD.map(opt => ({ ...opt, type: 'checkbox' })) }),
271
+ Text: this.createElementConfig(),
272
+ Calendar: this.createElementConfig(),
273
+ Date: this.createElementConfig(),
274
+ Time: this.createElementConfig(),
275
+ DateTime: this.createElementConfig(),
276
+ Email: this.createElementConfig(),
277
+ Book: this.createElementConfig(),
278
+ List: this.createElementConfig(),
279
+ TextArea: this.createElementConfig(),
280
+ RichTextArea: this.createElementConfig(),
281
+ Number: this.createElementConfig(),
282
+ Image: this.createElementConfig(),
283
+ Label: this.createElementConfig(),
284
+ Boolean: this.createElementConfig(),
285
+ File: this.createElementConfig(),
286
+ Icon: this.createElementConfig(), //MSM10JUL25 icon selector element
287
+ Button: this.createElementConfig(),
288
+ };
289
+ }
290
+ createElementConfig(config) {
291
+ return {
292
+ elementProps: [...COMMON_ELEMENT_PROPS, ...(config?.customElementProps || [])],
293
+ fieldProps: [...COMMON_FIELD_PROPS, ...(config?.customFieldProps || [])],
294
+ appearance: [...COMMON_APPEARANCE_PROPS, ...(config?.customAppearanceProps || [])]
295
+ };
296
+ }
426
297
  // AP 23MAY25 - Add a new button with default styling
427
298
  addNewButton() {
428
- const lastPercent = this.book?.questionbook?.action?.slice(-1)[0]?.positionPercent || 0;
299
+ const lastPercent = this.book()?.questionbook?.action?.slice(-1)[0]?.positionPercent ?? 0;
429
300
  const buttons = {
430
301
  name: '',
431
302
  eventtoemit: '',
@@ -439,70 +310,65 @@ export class PropertiesComponent {
439
310
  alignment: 'flex-start'
440
311
  };
441
312
  this.formBuilderService.updateQuestionBookActionButtons(buttons, 'add');
313
+ this.book.update(book => ({ ...book }));
442
314
  }
443
- //AP 23MAY25 - Remove a button from the action list
315
+ //AP 23MAY25 - Remove a button from the action list
444
316
  removeButton(btn) {
445
317
  this.formBuilderService.updateQuestionBookActionButtons(btn, 'remove');
318
+ this.book.update(book => ({ ...book }));
446
319
  }
447
320
  //AP 23MAY25 - Update a specific property of a button
448
321
  onButtonPropertyChange(index, key, value) {
449
- const buttons = this.getValueByPath('action') || [];
322
+ const buttons = this.book()?.questionbook?.action ?? [];
450
323
  if (buttons[index]) {
451
324
  buttons[index][key] = value;
452
- this.setValueByPath('action', buttons);
325
+ this.book.update(book => ({ ...book, questionbook: { ...book.questionbook, action: buttons } }));
453
326
  }
454
327
  }
455
328
  //AP-10MAR25 Updates the title using the form builder service
456
- updateTitle(event) {
457
- this.formBuilderService.updateTitle(event);
329
+ updateTitle(value) {
330
+ this.formBuilderService.updateTitle(value);
331
+ this.book.update(book => ({
332
+ ...book,
333
+ records: [{ ...book.records[0], title: value }]
334
+ }));
458
335
  }
459
336
  validateInput(value, type) {
460
337
  if (type === 'label' || type === 'placeholder') {
461
338
  const regex = /^[a-zA-Z0-9\s]*$/;
462
339
  if (!regex.test(value)) {
463
- this.errorMessage = 'Only letters and numbers are allowed';
340
+ this.errorMessage.set('Only letters and numbers are allowed');
464
341
  return false;
465
342
  }
466
343
  }
467
- this.errorMessage = '';
344
+ this.errorMessage.set('');
468
345
  return true;
469
346
  }
470
- get fieldAsString() {
471
- return this.bookSubtext.field.join(', '); //SKS28MAR25 Convert array to comma-separated string
472
- }
473
347
  updateField(value) {
474
- this.bookSubtext.field = value.split(',').map(item => item.trim()); //SKS28MAR25 Convert string back to array
348
+ this.bookSubtext.update(subtext => ({
349
+ ...subtext,
350
+ field: value.split(',').map(item => item.trim())
351
+ }));
475
352
  }
476
- // SKS20MAR25 Getter to filter columns, excluding the one with currentUniqueIdentifier
477
- get filteredColumns() {
478
- const targetArray = this.getDataByPath('fieldsMeta');
479
- return targetArray.filter(column => column.uniqueIdentifier !== this.selectColumn);
480
- }
481
- // SKS20MAR25 Method to handle checkbox changes
482
353
  onCheckboxChange(targetArrayPath, targetArrayKey, key, apiName, isChecked) {
483
354
  const targetArray = this.getDataByPath(targetArrayPath);
484
- const foundItem = targetArray.find(item => item[targetArrayKey] === this.selectColumn);
355
+ const foundItem = targetArray.find(item => item[targetArrayKey] === this.selectColumn());
485
356
  foundItem[key] = foundItem[key] ? foundItem[key] : [];
486
357
  if (isChecked) {
487
- // Add apiName to selectedApiNames if not already present
488
358
  if (!foundItem[key].includes(apiName)) {
489
359
  foundItem[key].push(apiName);
490
360
  }
491
361
  }
492
362
  else {
493
- // Remove apiName from selectedApiNames if present
494
363
  const index = foundItem[key].indexOf(apiName);
495
364
  if (index > -1) {
496
365
  foundItem[key].splice(index, 1);
497
366
  }
498
367
  }
499
- // this.updateElement(this.selectedElement)
368
+ this.updateElement(this.selectedElement());
500
369
  }
501
370
  updateProperty(key, value) {
502
- if (this.selectedElementIndex >= 0) {
503
- if (this.selectedElement.type === 'Table') {
504
- this.setValueByPath(key, value);
505
- }
371
+ if (this.selectedElementIndex() >= 0) {
506
372
  if (key === 'questionText' || key === 'question') {
507
373
  if (!this.validateInput(value, key)) {
508
374
  return;
@@ -514,63 +380,58 @@ export class PropertiesComponent {
514
380
  if (isNaN(newOrder))
515
381
  return;
516
382
  //AP-10MAR25 Update the element's questionNumber in the form builder service
517
- this.formBuilderService.updateElement(this.selectedElementIndex, { questionNumber: newOrder });
383
+ this.formBuilderService.updateElement(this.selectedElementIndex(), { questionNumber: newOrder });
518
384
  //AP-10MAR25 Sort elements based on the updated questionNumber
519
385
  this.formBuilderService.sortElementsByOrder();
520
386
  }
521
- if (key === 'fontWeight') {
522
- this.selectedElement[key] = value;
387
+ if (key === 'font' || key === 'fontWeight') {
388
+ this.selectedElement.update(el => ({ ...el, [key]: value }));
523
389
  }
524
390
  const update = { [key]: value };
525
- this.formBuilderService.updateElement(this.selectedElementIndex, update);
526
- // Special handling for font and font weight
527
- if (key === 'font') {
528
- this.selectedElement.font = value; // Directly update the selected element's font property
529
- }
391
+ this.formBuilderService.updateElement(this.selectedElementIndex(), update);
530
392
  }
531
393
  }
532
- // SKS21MAR25 radio button click handler
533
394
  onRadioChange(targetArrayPath, targetArrayKey, key, value) {
534
- if (this.selectedElement.type === 'Table') {
535
- // this.updateValueByArrayPath(targetArray, targetArrayKey, this.selectColumn, key, value);
536
- if (this.selectedElement?.type === 'Table') {
537
- this.selectedElement['fieldsMeta'] = typeof this.selectedElement?.fieldsMeta === 'object' ? this.selectedElement?.fieldsMeta : JSON.parse(this.selectedElement['fieldsMeta'] || []);
395
+ if (this.selectedElement()?.type === 'Table') {
396
+ let targetArray = this.getDataByPath(targetArrayPath);
397
+ if (typeof targetArray === 'string') {
398
+ try {
399
+ targetArray = JSON.parse(targetArray || '[]');
400
+ }
401
+ catch (e) {
402
+ // console.error('Error parsing targetArray:', e);
403
+ targetArray = [];
404
+ }
538
405
  }
539
- const targetArray = this.getDataByPath(targetArrayPath);
540
- // console.log("targetArray", targetArray, "targetArrayKey", targetArrayKey, "selectColumn", this.selectColumn, "keyPath", key, "event", value)
541
406
  if (!Array.isArray(targetArray))
542
407
  return;
543
- // Find the object that matches selectColumn
544
- let foundItem = targetArray.find(item => item[targetArrayKey] === this.selectColumn);
545
- // If the item does not exist, create and add it
408
+ let foundItem = targetArray.find(item => item[targetArrayKey] === this.selectColumn());
546
409
  if (!foundItem) {
547
- foundItem = { [targetArrayKey]: this.selectColumn }; // Ensure the key exists
410
+ foundItem = { [targetArrayKey]: this.selectColumn() };
548
411
  targetArray.push(foundItem);
549
412
  }
550
- // Traverse and set the value
551
413
  const keys = key.split('.');
552
414
  let obj = foundItem;
553
415
  for (let i = 0; i < keys.length - 1; i++) {
554
- const key = keys[i];
555
- if (!obj[key])
556
- obj[key] = {}; // Initialize missing objects
557
- obj = obj[key];
416
+ const k = keys[i];
417
+ if (!obj[k])
418
+ obj[k] = {};
419
+ obj = obj[k];
558
420
  }
559
- // Assign the value based on input type
560
- const lastKey = keys[keys.length - 1];
561
- obj[lastKey] = value;
562
- if (this.selectedElement?.type === 'Table') {
563
- this.selectedElement['fieldsMeta'] = typeof this.selectedElement?.fieldsMeta === 'object' ? JSON.stringify(this.selectedElement?.fieldsMeta) : this.selectedElement['fieldsMeta'] || [];
564
- }
565
- this.updateElement(this.selectedElement);
421
+ obj[keys[keys.length - 1]] = value;
422
+ this.selectedElement.update(el => ({
423
+ ...el,
424
+ fieldsMeta: targetArray
425
+ }));
426
+ this.updateElement(this.selectedElement());
566
427
  }
567
428
  else {
568
- this.setValueByPath(key, value); // Fallback for non-Table elements, if applicable
429
+ this.setValueByPath(key, value);
569
430
  }
570
431
  }
571
432
  onRequiredChange(value) {
572
- if (this.selectedElement) {
573
- let label = this.selectedElement.label ? this.selectedElement.label.replace(/\s*\*+$/, '') : 'Label';
433
+ if (this.selectedElement()) {
434
+ let label = this.selectedElement().label ? this.selectedElement().label.replace(/\s*\*+$/, '') : 'Label';
574
435
  if (value) {
575
436
  label = `${label} *`;
576
437
  }
@@ -578,48 +439,87 @@ export class PropertiesComponent {
578
439
  this.updateProperty('isOptional', value);
579
440
  }
580
441
  }
581
- // Toggle for Sub Questions (Each prop has its own state)
582
442
  toggleSubQuestion(prop) {
583
- prop.isExpanded = !prop.isExpanded;
443
+ this.isExpanded = !this.isExpanded;
584
444
  }
585
- // Separate Toggle for Style Section
586
- isStyleExpanded = false;
587
445
  toggleStyleSection() {
588
- this.isStyleExpanded = !this.isStyleExpanded;
446
+ this.isStyleExpanded.set(!this.isStyleExpanded());
589
447
  }
590
448
  getProperties() {
591
- if (!this.selectedElement)
449
+ const element = this.selectedElement();
450
+ const selectedColumn = this.selectColumn();
451
+ // Check if we can use cached result
452
+ if (this._cachedProperties &&
453
+ this._lastSelectedElement === element &&
454
+ this._lastSelectedColumn === selectedColumn) {
455
+ return this._cachedProperties;
456
+ }
457
+ if (!element) {
458
+ this._cachedProperties = null;
459
+ this._lastSelectedElement = null;
460
+ this._lastSelectedColumn = null;
592
461
  return null;
593
- // AP-10MAR25 Retrieve the latest book data
594
- this.book = this.formBuilderService.getBook();
595
- // AP-10MAR25 If the selected element is a 'Header', return its properties
596
- if (this.selectedElement?.type === 'Header') {
597
- return this.elementProperties['Header'];
598
- }
599
- if (this.selectedElement?.type === 'Table') {
600
- if (this.selectColumn !== null) {
601
- // Get the column metadata
602
- const fieldsMeta = Array.isArray(this.selectedElement.fieldsMeta)
603
- ? this.selectedElement.fieldsMeta
604
- : JSON.parse(this.selectedElement.fieldsMeta || '[]');
605
- const column = fieldsMeta.find((c) => c.uniqueIdentifier === this.selectColumn);
606
- if (column) {
607
- // Return specific properties based on column type
608
- switch (column.fldType) {
609
- case 'List':
610
- return this.elementProperties['ListColumn'];
611
- case 'Dropdown':
612
- return this.elementProperties['DropdownColumn'];
613
- case 'Date':
614
- return this.elementProperties['DateColumn'];
615
- default:
616
- return this.elementProperties['TableColumn'];
462
+ }
463
+ let result = null;
464
+ if (element.type === 'Header') {
465
+ result = this.elementProperties()['Header'];
466
+ }
467
+ else if (element.type === 'Table' && selectedColumn !== null) {
468
+ let fieldsMeta = element.fieldsMeta;
469
+ try {
470
+ fieldsMeta = Array.isArray(fieldsMeta)
471
+ ? fieldsMeta
472
+ : JSON.parse(fieldsMeta || '[]');
473
+ }
474
+ catch (e) {
475
+ // console.error('Error parsing fieldsMeta in getProperties:', e);
476
+ fieldsMeta = [];
477
+ }
478
+ const column = fieldsMeta.find((c) => c.uniqueIdentifier === selectedColumn);
479
+ if (column) {
480
+ const markIsTableColumn = (items = []) => items.map(item => {
481
+ const newItem = { ...item, isTableColumn: true };
482
+ if (Array.isArray(newItem.subQuestion)) {
483
+ newItem.subQuestion = newItem.subQuestion.map(sub => ({
484
+ ...sub,
485
+ isTableColumn: true
486
+ }));
617
487
  }
618
- }
619
- return this.elementProperties[this.selectedElement?.type] || this.elementProperties['DefaultColumn'];
488
+ return newItem;
489
+ });
490
+ result = {
491
+ elementProps: [
492
+ ...(this.elementProperties()['TableColumn'].elementProps || []),
493
+ ...markIsTableColumn(this.elementProperties()[this.elementType.includes(column.fldType) ? column.fldType : 'Text']?.elementProps)
494
+ ],
495
+ fieldProps: [
496
+ ...(this.elementProperties()['TableColumn'].fieldProps || []),
497
+ ...markIsTableColumn(this.elementProperties()[this.elementType.includes(column.fldType) ? column.fldType : 'Text']?.fieldProps)
498
+ ],
499
+ appearance: [
500
+ ...(this.elementProperties()['TableColumn'].appearance || []),
501
+ ...markIsTableColumn(this.elementProperties()[this.elementType.includes(column.fldType) ? column.fldType : 'Text']?.appearance)
502
+ ]
503
+ };
504
+ }
505
+ else {
506
+ result = this.elementProperties()['TableColumn'];
620
507
  }
621
508
  }
622
- return this.elementProperties[this.selectedElement?.type];
509
+ else {
510
+ result = this.elementProperties()[element.type];
511
+ }
512
+ // Cache the result
513
+ this._cachedProperties = result;
514
+ this._lastSelectedElement = element;
515
+ this._lastSelectedColumn = selectedColumn;
516
+ return result;
517
+ }
518
+ // Add method to clear cache when needed
519
+ clearPropertiesCache() {
520
+ this._cachedProperties = null;
521
+ this._lastSelectedElement = null;
522
+ this._lastSelectedColumn = null;
623
523
  }
624
524
  // AP-28MAR25 Add an option with a unique UUID
625
525
  addOption(options) {
@@ -639,173 +539,189 @@ export class PropertiesComponent {
639
539
  handleTemplateSave() {
640
540
  this.templateSaveHandler.emit(this.templateService.download());
641
541
  }
642
- // SKS13MAR25 active tab select
643
542
  setActiveTab(tab) {
644
- this.activeTab = tab;
645
- }
646
- // SKS13MAR25 table property save
647
- onSave() {
648
- // console.log('Saving data:');
649
- }
650
- // SKS13MAR25 table property reset
651
- onCancel() {
652
- // console.log('Operation cancelled');
653
- }
654
- updateProperties(elementType) {
655
- // Reset alignment and styles if switching elements
656
- this.selectedAlign = 'align-left';
657
- this.selectedStyles = [];
658
- // Fetch the properties of the selected element type
659
- const properties = this.getProperties();
660
- if (properties) {
661
- // Make sure the properties are dynamically updated
662
- }
543
+ this.activeTab.set(tab);
663
544
  }
545
+ onSave() { }
546
+ onCancel() { }
664
547
  onAlignSelect(value) {
665
- if (this.selectedElement) {
666
- this.selectedElement.textAlign = value;
667
- }
548
+ this.selectedElement.update(el => ({ ...el, textAlign: value }));
668
549
  }
669
550
  onStyleSelect(value) {
670
- if (!this.selectedElement)
671
- return;
672
- // Initialize styles array if it doesn't exist
673
- this.selectedElement.styles = this.selectedElement.styles || [];
674
- // Ensure only one style is selected at a time
675
- this.selectedElement.styles = [value];
551
+ this.selectedElement.update(el => ({
552
+ ...el,
553
+ styles: [value]
554
+ }));
676
555
  }
677
556
  isStyleActive(value) {
678
- return this.selectedElement?.styles?.includes(value) || false;
557
+ return this.selectedElement()?.styles?.includes(value) || false;
679
558
  }
680
- getValueByPath(path) {
681
- if (this.selectedElement?.type === 'Table') {
682
- this.selectedElement['fieldsMeta'] = typeof this.selectedElement?.fieldsMeta === 'object' ? this.selectedElement?.fieldsMeta : JSON.parse(this.selectedElement['fieldsMeta'] || []);
683
- }
684
- this.selectedElement['subText'] =
685
- typeof this.selectedElement?.subText === 'object'
686
- ? this.selectedElement.subText
687
- : (typeof this.selectedElement?.subText === 'string' && this.selectedElement.subText.trim() !== ''
688
- ? JSON.parse(this.selectedElement.subText)
689
- : {});
690
- if (this.selectedElement['subText'] && Array.isArray(this.selectedElement['subText'].field)) {
691
- // Convert array to a comma-separated string
692
- this.selectedElement['subText'].field = this.selectedElement['subText'].field.join(', ');
693
- }
694
- return path.split('.').reduce((obj, key) => obj?.[key] ?? '', this.selectedElement);
559
+ getValueByPath(path, obj = this.selectedElement(), defaultValue = '') {
560
+ if (!obj || !path)
561
+ return defaultValue;
562
+ return path.split('.').reduce((o, k) => o?.[k] ?? defaultValue, obj);
695
563
  }
696
564
  isAnotherIdSelected() {
697
565
  return this.formBuilderService.getElements()
698
- .some((el, i) => i !== this.selectedElementIndex && el.primaryKey);
566
+ .some((el, i) => i !== this.selectedElementIndex() && el.primaryKey);
699
567
  }
568
+ // Also update your onToggleChange method to clear cache
700
569
  onToggleChange(path, event) {
701
- const checked = event.target.checked;
570
+ // Clear cache when element changes
571
+ this.clearPropertiesCache();
572
+ const checked = event.target ? event.target.checked : event;
702
573
  this.setValueByPath(path, checked);
703
- if (this.selectedElement?.type === 'Table') {
704
- this.selectedElement['fieldsMeta'] = typeof this.selectedElement?.fieldsMeta === 'object' ? JSON.stringify(this.selectedElement?.fieldsMeta) : this.selectedElement['fieldsMeta'] || [];
574
+ if (this.selectedElement()?.type === 'Table') {
575
+ let fieldsMeta = this.getDataByPath('fieldsMeta');
576
+ if (typeof fieldsMeta === 'string') {
577
+ try {
578
+ fieldsMeta = JSON.parse(fieldsMeta || '[]');
579
+ }
580
+ catch (e) {
581
+ // console.error('Error parsing fieldsMeta:', e);
582
+ fieldsMeta = [];
583
+ }
584
+ }
585
+ this.selectedElement.update(el => ({
586
+ ...el,
587
+ fieldsMeta: fieldsMeta
588
+ }));
589
+ this.updateElement(this.selectedElement());
705
590
  }
706
- this.updateElement(this.selectedElement);
707
591
  }
592
+ // Update your setValueByPath method to clear cache
708
593
  setValueByPath(path, value) {
709
- if (this.selectedElementIndex >= 0) {
710
- if (path === 'questionText' || value === 'question') {
711
- if (!this.validateInput(value, value)) {
594
+ // Clear cache when element changes
595
+ this.clearPropertiesCache();
596
+ if (this.selectedElementIndex() >= 0) {
597
+ if (path === 'questionText' || path === 'question') {
598
+ if (!this.validateInput(value, path)) {
599
+ return;
712
600
  }
713
601
  }
714
602
  if (path === 'questionNumber') {
715
- //AP-10MAR25 Convert the value to an integer
716
603
  const newOrder = parseInt(value, 10);
717
604
  if (isNaN(newOrder))
718
605
  return;
719
- //AP-10MAR25 Update the element's questionNumber in the form builder service
720
- this.formBuilderService.updateElement(this.selectedElementIndex, { questionNumber: newOrder });
721
- //AP-10MAR25 Sort elements based on the updated questionNumber
606
+ this.formBuilderService.updateElement(this.selectedElementIndex(), { questionNumber: newOrder });
722
607
  this.formBuilderService.sortElementsByOrder();
723
608
  }
724
- if (path === 'fontWeight') {
725
- // console.log('Font weight selected:', value);
726
- this.selectedElement[path] = value;
727
- }
728
- // Special handling for font and font weight
729
- if (path === 'font') {
730
- this.selectedElement.font = value; // Directly update the selected element's font property
609
+ if (path === 'font' || path === 'fontWeight') {
610
+ this.selectedElement.update(el => ({ ...el, [path]: value }));
731
611
  }
732
612
  }
733
- const keys = path.split('.');
734
- let obj = this.selectedElement;
735
- if (this.selectedElement?.type === 'Table') {
736
- this.selectedElement['fieldsMeta'] = typeof this.selectedElement?.fieldsMeta === 'object' ? this.selectedElement?.fieldsMeta : JSON.parse(this.selectedElement['fieldsMeta'] || []);
737
- }
738
- this.selectedElement['subText'] = typeof this.selectedElement?.subText === 'object' ? this.selectedElement?.subText : JSON.parse(this.selectedElement['subText']);
739
- keys.forEach((key, index) => {
740
- if (!obj[key]) {
741
- // Check if the next key is a number (array index)
742
- const nextKey = keys[index + 1];
743
- obj[key] = isNaN(Number(nextKey)) ? {} : [];
613
+ const element = this.selectedElement();
614
+ if (element) {
615
+ let subText = element.subText;
616
+ if (typeof subText === 'string' && subText.trim() !== '') {
617
+ try {
618
+ subText = JSON.parse(subText);
619
+ }
620
+ catch (e) {
621
+ // console.error('Error parsing subText:', e);
622
+ subText = {};
623
+ }
744
624
  }
745
- if (index === keys.length - 1) {
746
- obj[key] = value; // Assign value to last key
625
+ else if (typeof subText !== 'object' || subText === null) {
626
+ subText = {};
747
627
  }
748
- else {
749
- obj = obj[key]; // Move deeper
628
+ if (subText && Array.isArray(subText.field)) {
629
+ subText = { ...subText, field: subText.field.join(', ') };
750
630
  }
631
+ this.selectedElement.update(el => ({ ...el, subText }));
632
+ }
633
+ const keys = path.split('.');
634
+ this.selectedElement.update(el => {
635
+ let obj = { ...el };
636
+ let current = obj;
637
+ keys.forEach((key, index) => {
638
+ if (index === keys.length - 1) {
639
+ current[key] = value;
640
+ }
641
+ else {
642
+ if (!current[key]) {
643
+ current[key] = isNaN(Number(keys[index + 1])) ? {} : [];
644
+ }
645
+ current = current[key];
646
+ }
647
+ });
648
+ return obj;
751
649
  });
752
- this.formBuilderService.elementUpdate(this.selectedElementIndex, this.selectedElement);
650
+ this.formBuilderService.elementUpdate(this.selectedElementIndex(), this.selectedElement());
753
651
  }
754
652
  getStyleKeys() {
755
- if (!this.selectedElement || !this.selectedElement.style || typeof this.selectedElement.style !== 'object') {
756
- return [];
757
- }
758
- return Object.keys(this.selectedElement.style);
653
+ const style = this.selectedElement()?.style;
654
+ return style && typeof style === 'object' ? Object.keys(style) : [];
759
655
  }
760
- // SKS19MAR25 update element in servies
761
656
  updateElement(element) {
762
- this.formBuilderService.elementUpdate(this.selectedElementIndex, element);
763
- if (this.selectedElement?.type === 'Table' && this.selectColumn) {
764
- this.selectedElement['fieldsMeta'] = typeof this.selectedElement?.fieldsMeta === 'object' ? this.selectedElement?.fieldsMeta : JSON.parse(this.selectedElement.fieldsMeta || []);
765
- const foundItem = this.selectedElement['fieldsMeta'].find(item => item['uniqueIdentifier'] === this.selectColumn);
766
- this.formBuilderService.setSelectedTableElement(this.selectedElementIndex, { column: foundItem?.apiName || null });
767
- }
768
- }
769
- // SKS19MAR25 get value from array
770
- getValueByArrayPath(targetArrayPath, targetArrayKey, selectColumn, keyPath) {
771
- if (this.selectedElement?.type === 'Table') {
772
- this.selectedElement['fieldsMeta'] = typeof this.selectedElement?.fieldsMeta === 'object' ? this.selectedElement?.fieldsMeta : JSON.parse(this.selectedElement['fieldsMeta'] || []);
657
+ this.formBuilderService.elementUpdate(this.selectedElementIndex(), element);
658
+ if (element?.type === 'Table' && this.selectColumn()) {
659
+ this.formBuilderService.setSelectedTableElement(this.selectedElementIndex(), { uniqueIdentifier: this.selectColumn() || null });
660
+ this.selectedElement.set({ ...element }); // Ensure reactive update
661
+ }
662
+ }
663
+ getValueByArrayPath(targetArrayPath, targetArrayKey, selectColumn, keyPath, isTableColumn = false) {
664
+ if (isTableColumn) {
665
+ targetArrayPath = 'fieldsMeta';
666
+ targetArrayKey = 'uniqueIdentifier';
667
+ keyPath = 'question.' + keyPath;
668
+ }
669
+ let targetArray = this.getDataByPath(targetArrayPath);
670
+ if (typeof targetArray === 'string') {
671
+ try {
672
+ targetArray = JSON.parse(targetArray || '[]');
673
+ }
674
+ catch (e) {
675
+ // console.error('Error parsing targetArray:', e);
676
+ return '';
677
+ }
773
678
  }
774
- const targetArray = this.getDataByPath(targetArrayPath);
775
679
  if (!Array.isArray(targetArray))
776
680
  return '';
777
681
  const foundItem = targetArray.find(item => item[targetArrayKey] === selectColumn);
778
682
  return foundItem ? keyPath.split('.').reduce((obj, key) => obj?.[key], foundItem) : '';
779
683
  }
780
- //SKS19MAR25 Function to update a value in an array dynamically
781
- updateValueByArrayPath(targetArrayPath, targetArrayKey, selectColumn, keyPath, event) {
782
- if (this.selectedElement?.type === 'Table') {
783
- this.selectedElement['fieldsMeta'] = typeof this.selectedElement?.fieldsMeta === 'object' ? this.selectedElement?.fieldsMeta : JSON.parse(this.selectedElement['fieldsMeta'] || []);
684
+ updateValueByArrayPath(targetArrayPath, targetArrayKey, selectColumn, keyPath, event, isTableColumn = false) {
685
+ // Clear cache when element changes
686
+ this.clearPropertiesCache();
687
+ if (isTableColumn) {
688
+ targetArrayPath = 'fieldsMeta';
689
+ targetArrayKey = 'uniqueIdentifier';
690
+ keyPath = 'question.' + keyPath;
691
+ }
692
+ let targetArray = this.getDataByPath(targetArrayPath);
693
+ if (typeof targetArray === 'string') {
694
+ try {
695
+ targetArray = JSON.parse(targetArray || '[]');
696
+ }
697
+ catch (e) {
698
+ // console.error('Error parsing targetArray:', e);
699
+ targetArray = [];
700
+ }
701
+ }
702
+ if (!Array.isArray(targetArray)) {
703
+ targetArray = [];
704
+ this.selectedElement.update(el => ({
705
+ ...el,
706
+ [targetArrayPath]: targetArray
707
+ }));
784
708
  }
785
- const targetArray = this.getDataByPath(targetArrayPath);
786
- // console.log("targetArray", targetArray, "targetArrayKey", targetArrayKey, "selectColumn", selectColumn, "keyPath", keyPath, "event", event)
787
- if (!Array.isArray(targetArray))
788
- return;
789
- // Find the object that matches selectColumn
790
709
  let foundItem = targetArray.find(item => item[targetArrayKey] === selectColumn);
791
- // If the item does not exist, create and add it
792
710
  if (!foundItem) {
793
- foundItem = { [targetArrayKey]: selectColumn }; // Ensure the key exists
711
+ foundItem = { [targetArrayKey]: selectColumn };
794
712
  targetArray.push(foundItem);
795
713
  }
796
- // Traverse and set the value
797
714
  const keys = keyPath.split('.');
798
715
  let obj = foundItem;
799
716
  for (let i = 0; i < keys.length - 1; i++) {
800
717
  const key = keys[i];
801
718
  if (!obj[key])
802
- obj[key] = {}; // Initialize missing objects
719
+ obj[key] = {};
803
720
  obj = obj[key];
804
721
  }
805
- // Assign the value based on input type
806
722
  const lastKey = keys[keys.length - 1];
807
- const inputElement = event.target;
808
- obj[lastKey] = inputElement?.type === 'checkbox' ? inputElement.checked : inputElement.value;
723
+ const inputElement = event.target ? event.target : event;
724
+ obj[lastKey] = inputElement?.type === 'checkbox' ? inputElement.checked : inputElement.value ? inputElement.value : inputElement;
809
725
  if (keyPath === 'summaryColumn') {
810
726
  if (obj['summaryRow'] === true) {
811
727
  obj['summaryRow'] = false;
@@ -828,34 +744,25 @@ export class PropertiesComponent {
828
744
  obj['fldType'] = 'Text';
829
745
  }
830
746
  }
831
- if (this.selectedElement?.type === 'Table') {
832
- this.selectedElement['fieldsMeta'] = typeof this.selectedElement?.fieldsMeta === 'object' ? JSON.stringify(this.selectedElement?.fieldsMeta) : this.selectedElement['fieldsMeta'] || [];
833
- }
834
- this.updateElement(this.selectedElement);
747
+ this.selectedElement.update(el => ({
748
+ ...el,
749
+ [targetArrayPath]: targetArray
750
+ }));
751
+ this.updateElement(this.selectedElement());
835
752
  }
836
753
  getDataByPath(path) {
837
- if (this.selectedElement?.type === 'Table') {
838
- this.selectedElement['fieldsMeta'] = typeof this.selectedElement?.fieldsMeta === 'object' ? this.selectedElement?.fieldsMeta : JSON.parse(this.selectedElement['fieldsMeta'] || []);
839
- }
840
- return path.split('.').reduce((obj, key) => obj?.[key], this.selectedElement);
754
+ return path.split('.').reduce((obj, key) => obj?.[key], this.selectedElement());
841
755
  }
842
- // SKS25MAR25 image edit functions
843
756
  flipHorizontal() {
844
- this.transform = {
845
- ...this.transform,
846
- flipH: !this.transform.flipH
847
- };
757
+ this.transform.update(t => ({ ...t, flipH: !t.flipH }));
848
758
  }
849
759
  flipVertical() {
850
- this.transform = {
851
- ...this.transform,
852
- flipV: !this.transform.flipV
853
- };
760
+ this.transform.update(t => ({ ...t, flipV: !t.flipV }));
854
761
  }
855
762
  resetImage() {
856
- this.canvasRotation = 0;
857
- this.cropper = undefined;
858
- this.transform = {
763
+ this.canvasRotation.set(0);
764
+ this.cropper.set(undefined);
765
+ this.transform.set({
859
766
  translateUnit: 'px',
860
767
  scale: 1,
861
768
  rotate: 0,
@@ -863,85 +770,62 @@ export class PropertiesComponent {
863
770
  flipV: false,
864
771
  translateH: 0,
865
772
  translateV: 0
866
- };
773
+ });
867
774
  }
868
775
  zoomOut() {
869
- this.transform = {
870
- ...this.transform,
871
- scale: this.transform.scale - .1
872
- };
776
+ this.transform.update(t => ({ ...t, scale: t.scale - 0.1 }));
873
777
  }
874
778
  zoomIn() {
875
- this.transform = {
876
- ...this.transform,
877
- scale: this.transform.scale + .1
878
- };
779
+ this.transform.update(t => ({ ...t, scale: t.scale + 0.1 }));
879
780
  }
880
781
  rotateLeft() {
881
- this.loading = true;
782
+ this.loading.set(true);
882
783
  setTimeout(() => {
883
- this.canvasRotation--;
784
+ this.canvasRotation.update(c => c - 1);
884
785
  this.flipAfterRotate();
885
786
  });
886
787
  }
887
788
  rotateRight() {
888
- this.loading = true;
789
+ this.loading.set(true);
889
790
  setTimeout(() => {
890
- this.canvasRotation++;
791
+ this.canvasRotation.update(c => c + 1);
891
792
  this.flipAfterRotate();
892
793
  });
893
794
  }
894
795
  moveLeft() {
895
- this.transform = {
896
- ...this.transform,
897
- translateH: this.transform.translateH - 1
898
- };
796
+ this.transform.update(t => ({ ...t, translateH: t.translateH - 1 }));
899
797
  }
900
798
  moveRight() {
901
- this.transform = {
902
- ...this.transform,
903
- translateH: this.transform.translateH + 1
904
- };
799
+ this.transform.update(t => ({ ...t, translateH: t.translateH + 1 }));
905
800
  }
906
801
  moveDown() {
907
- this.transform = {
908
- ...this.transform,
909
- translateV: this.transform.translateV + 1
910
- };
802
+ this.transform.update(t => ({ ...t, translateV: t.translateV + 1 }));
911
803
  }
912
804
  moveUp() {
913
- this.transform = {
914
- ...this.transform,
915
- translateV: this.transform.translateV - 1
916
- };
805
+ this.transform.update(t => ({ ...t, translateV: t.translateV - 1 }));
917
806
  }
918
807
  flipAfterRotate() {
919
- const flippedH = this.transform.flipH;
920
- const flippedV = this.transform.flipV;
921
- this.transform = {
922
- ...this.transform,
923
- flipH: flippedV,
924
- flipV: flippedH,
808
+ this.transform.update(t => ({
809
+ ...t,
810
+ flipH: t.flipV,
811
+ flipV: t.flipH,
925
812
  translateH: 0,
926
813
  translateV: 0
927
- };
814
+ }));
928
815
  }
929
816
  async imageCropped(event) {
930
817
  try {
931
818
  const base64 = await this.convertBlobToBase64(event.objectUrl);
932
- this.selectedElement.imageData = base64;
933
- await this.formBuilderService.elementUpdate(this.selectedElementIndex, this.selectedElement);
934
- // console.log('CROPPED', event);
819
+ this.selectedElement.update(el => ({ ...el, imageData: base64 }));
820
+ await this.formBuilderService.elementUpdate(this.selectedElementIndex(), this.selectedElement());
935
821
  }
936
822
  catch (error) {
937
- console.error("Error in imageCropped:", error);
823
+ // console.error("Error in imageCropped:", error);
938
824
  }
939
825
  }
940
826
  cropperReady(sourceImageDimensions) {
941
- // console.log('Cropper ready', sourceImageDimensions);
942
- this.loading = false;
827
+ this.loading.set(false);
943
828
  }
944
- // SKS25MAR25 blob to base 64 converter
945
829
  convertBlobToBase64(objectUrl) {
946
830
  return fetch(objectUrl)
947
831
  .then(response => response.blob())
@@ -954,24 +838,23 @@ export class PropertiesComponent {
954
838
  });
955
839
  });
956
840
  }
957
- // SKS28MAR25 qb book update in book element
958
841
  childEventCapture(event) {
959
- this.selectedElement.qbReference = event.valueObj?.name;
960
- this.selectedElement.qbReferenceQuestions = event.valueObj?.jsonBody;
961
- this.formBuilderService.elementUpdate(this.selectedElementIndex, this.selectedElement);
842
+ this.selectedElement.update(el => ({
843
+ ...el,
844
+ qbReference: event.valueObj?.name,
845
+ qbReferenceQuestions: event.valueObj?.jsonBody
846
+ }));
847
+ this.formBuilderService.elementUpdate(this.selectedElementIndex(), this.selectedElement());
962
848
  }
963
- // SKS28MAR25 book search dropdown emit
964
849
  linkToggleDropdown(event) {
965
850
  event.stopPropagation();
966
- this.isLinkDropdownOpen = !this.isLinkDropdownOpen;
851
+ this.isLinkDropdownOpen.update(open => !open);
967
852
  }
968
- // SKS28MAR25 book search dropdown close
969
853
  onClickOutside(event) {
970
854
  if (this.dropdown && !this.dropdown.nativeElement.contains(event.target)) {
971
- this.isLinkDropdownOpen = false;
855
+ this.isLinkDropdownOpen.set(false);
972
856
  }
973
857
  }
974
- // AP-28MAR25 When drag starts, store the index
975
858
  onDragStart(event, id) {
976
859
  this.draggedId = id;
977
860
  event.dataTransfer.effectAllowed = "move";
@@ -985,37 +868,77 @@ export class PropertiesComponent {
985
868
  event.preventDefault();
986
869
  const targetId = event.target.closest(".option-items")?.getAttribute("data-id");
987
870
  if (this.draggedId && targetId && this.draggedId !== targetId) {
988
- const options = this.selectedElement[key];
989
- [options[this.draggedId], options[targetId]] = [options[targetId], options[this.draggedId]];
990
- // Find the indexes of the dragged and target options
991
- const draggedIndex = options.findIndex(option => option.id === this.draggedId);
992
- const targetIndex = options.findIndex(option => option.id === targetId);
993
- // Swap the items
994
- if (draggedIndex !== -1 && targetIndex !== -1) {
995
- [options[draggedIndex], options[targetIndex]] = [options[targetIndex], options[draggedIndex]];
996
- }
871
+ this.selectedElement.update(el => {
872
+ const options = [...el[key]];
873
+ const draggedIndex = options.findIndex(option => option.id === this.draggedId);
874
+ const targetIndex = options.findIndex(option => option.id === targetId);
875
+ if (draggedIndex !== -1 && targetIndex !== -1) {
876
+ [options[draggedIndex], options[targetIndex]] = [options[targetIndex], options[draggedIndex]];
877
+ }
878
+ return { ...el, [key]: options };
879
+ });
997
880
  }
998
881
  this.draggedId = null;
999
882
  }
1000
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PropertiesComponent, deps: [{ token: i1.HttpClient }, { token: i2.FormBuilderService }, { token: i3.TemplateService }], target: i0.ɵɵFactoryTarget.Component });
1001
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: PropertiesComponent, isStandalone: true, selector: "app-properties", inputs: { selectedElementType: "selectedElementType", templateSelected: "templateSelected" }, 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<div class=\"container\">\n <div class=\"tabs\">\n <div class=\"tab\" [ngClass]=\"{'active': activeTab === 'attributes'}\" (click)=\"setActiveTab('attributes')\">\n Attributes\n </div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab === 'property'}\" (click)=\"setActiveTab('property')\">\n Property\n </div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab === 'appearance'}\" (click)=\"setActiveTab('appearance')\">\n Appearance\n </div>\n </div>\n\n <div class=\"tab-content\" *ngIf=\"activeTab === 'attributes'\">\n <!-- Element Properrties -->\n <!-- AP-06MAR25 Select element type show -->\n <div *ngIf=\"getProperties()\">\n <!-- SKS25MAR25 this is for image edit -->\n <div *ngIf=\"selectedElement?.type === 'Image'\">\n <image-cropper *ngIf=\"selectedElement.imageData \" [imageBase64]=\"selectedElement.orgImageData\"\n [disabled]=\"false\" [alignImage]=\"alignImage\" [roundCropper]=\"roundCropper\" [backgroundColor]=\"'white'\"\n imageAltText=\"Alternative image text\" [allowMoveImage]=\"false\" [hideResizeSquares]=\"false\"\n [canvasRotation]=\"canvasRotation\" [aspectRatio]=\"aspectRatio\" [containWithinAspectRatio]=\"false\"\n [maintainAspectRatio]=\"false\" [cropperStaticWidth]=\"cropperStaticWidth\"\n [cropperStaticHeight]=\"cropperStaticHeight\" [cropperMinWidth]=\"cropperMinWidth\"\n [cropperMinHeight]=\"cropperMinHeight\" [cropperMaxWidth]=\"cropperMaxWidth\"\n [cropperMaxHeight]=\"cropperMaxHeight\" [resetCropOnAspectRatioChange]='true' [(cropper)]=\"cropper\"\n [(transform)]=\"transform\" [onlyScaleDown]=\"true\" output=\"blob\" format=\"png\"\n (imageCropped)=\"imageCropped($event)\" (cropperReady)=\"cropperReady($event)\"></image-cropper>\n <div *ngIf=\"selectedElement.imageData \" style=\"display: flex; gap: 2px;\">\n <div class=\"cursor-pointer logo-icon\" (click)=\"rotateLeft()\" title=\"Rotate Left\">\u27F2</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"rotateRight()\" title=\"Rotate Right\">\u27F3</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"zoomOut()\" title=\"Zoom Out\">-</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"zoomIn()\" title=\"Zoom In\">+</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveLeft()\" title=\"Move Left\">\u2190</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveRight()\" title=\"Move Right\">\u2192</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveUp()\" title=\"Move Up\">\u2191</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveDown()\" title=\"Move Down\">\u2193</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipHorizontal()\" [class.enabled]=\"transform.flipH\"\n title=\"Flip Horizontally\">\u2194</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipVertical()\" [class.enabled]=\"transform.flipV\"\n title=\"Flip Vertically\">\u2195</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"resetImage()\" title=\"Reset\">\u00D7</div>\n </div>\n </div>\n <!-- SKS28MAR25 search book specific for book element -->\n <div *ngIf=\"selectedElement?.type === 'Book'\">\n <label class=\"text-sm\">Search Book</label>\n <div style=\"display: flex; gap: 2px; align-items: center; justify-content: center;\">\n <nxt-search-box [question]=\"selectedElement\" [apiMeta]=\"bookSubtext\" [placeHolderText]=\"'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>Endpoint:</label>\n <input type=\"text\" [(ngModel)]=\"bookSubtext.endpoint\" />\n\n <label>Variable:</label>\n <input type=\"text\" [(ngModel)]=\"bookSubtext.variable\" />\n\n <label>Field:</label>\n <input type=\"text\" [ngModel]=\"fieldAsString\" (ngModelChange)=\"updateField($event)\" />\n\n <label>Default Field:</label>\n <input type=\"text\" [(ngModel)]=\"bookSubtext.defaultField\" />\n </div>\n </div>\n </div>\n </div>\n <ng-container *ngFor=\"let prop of getProperties().elementProps\">\n <div class=\"form-group\">\n <label *ngIf=\"prop.type !== 'checkbox' && prop.type !== 'subQuestion'\" class=\"text-sm\">{{ prop.label\n }}</label>\n\n <!-- Text Input -->\n <input *ngIf=\"prop.type === 'text'\" type=\"text\" [placeholder]=\"prop.placeholder\"\n [value]=\"headerSelect ? book.records[0].title : (selectedElement?.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key))\"\n (input)=\"headerSelect ? updateTitle($event.target.value) : (selectedElement?.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value))\"\n [class.read-only]=\"selectedElement.readOnly\" [readonly]=\"selectedElement.readOnly\" />\n\n <!-- help text -->\n <div *ngIf=\"prop.key === 'helpText' && selectedElement.helpText\">{{\n selectedElement.helpText }}</div>\n\n <!-- questionNumber -->\n <input *ngIf=\"prop.key === 'questionNumber'\" type=\"number\" [value]=\"selectedElement.questionNumber\"\n (input)=\"setValueByPath('questionNumber', $event.target.value)\" />\n\n <!-- file -->\n <!-- Add this inside the elementProps loop where other inputs are rendered -->\n <select *ngIf=\"prop.type === 'select' && prop.key === 'supportType'\" [value]=\"selectedElement[prop.key]\"\n (change)=\"setValueByPath(prop.key, $event.target.value)\">\n <option value=\"\">Select file category</option>\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\"> {{ option.label }} </option>\n </select>\n\n <div *ngIf=\"prop.type === 'checkbox'\">\n\n <input type=\"checkbox\"\n [checked]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ): getValueByPath(prop.key) \"\n (change)=\" selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : onToggleChange(prop.key, $event) ) : onToggleChange(prop.key, $event)\" />\n <span class=\"toggle-label\" style=\"padding-left: 10px;\">{{ prop.label }}</span>\n\n </div>\n\n <!--AP-11JUN25 - Show this section only if the property key is 'primaryKey' -->\n <div *ngIf=\"prop.key === 'primaryKey'\">\n <input type=\"checkbox\" [checked]=\"getValueByPath('primaryKey')\" [disabled]=\"!getValueByPath('primaryKey') && isAnotherIdSelected()\" (change)=\"onToggleChange('primaryKey', $event)\"/>\n <span class=\"toggle-label\" style=\"padding-left: 10px;\">primaryKey</span>\n </div>\n\n <!-- SKS20MAR25 Subquestion Type -->\n <div *ngIf=\"prop.type === 'subQuestion'\">\n <div style=\"display: flex; flex-direction: row; gap: 10px; align-items: center;\">\n <div>{{ prop.label }}</div>\n <input type=\"checkbox\"\n [checked]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ): getValueByPath(prop.key) \"\n (change)=\" selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : onToggleChange(prop.key, $event) ) : onToggleChange(prop.key, $event)\" />\n </div>\n <!-- SKS20MAR25 Render subquestions when checkbox is checked -->\n <div\n *ngIf=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ): getValueByPath(prop.key)\">\n <div *ngFor=\"let subProp of prop.subQuestion\"\n style=\"background-color: #e7f2ff; padding: 8px; border-radius: 4px;\">\n <div class=\"form-group\">\n <label>{{ subProp.label }}</label>\n <div *ngIf=\"subProp.type === 'array'\">\n <!-- Iterate over filtered columns to display checkboxes -->\n <div *ngFor=\"let column of filteredColumns\">\n <label>\n <input 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 {{ column.apiName }}\n </label>\n </div>\n </div>\n <!-- SKS21MAR25 New radio type -->\n <div *ngIf=\"subProp.type === 'radio'\">\n <div *ngFor=\"let column of filteredColumns\">\n <label>\n <input type=\"radio\" [name]=\"subProp.key\" [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 {{ column.apiName }}\n </label>\n </div>\n </div>\n <!-- SKS20MAR25 Add more subproperty types as needed -->\n <!-- Inside the subProp ngFor loop -->\n <input *ngIf=\"subProp.type === 'text'\" type=\"text\" [placeholder]=\"subProp.placeholder\"\n [value]=\"selectedElement.type === 'Table' ? (subProp.targetArray ? getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key ) : getValueByPath(subProp.key) ) : getValueByPath(subProp.key)\"\n (input)=\"selectedElement.type === 'Table' ? (subProp.targetArray ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key, $event) : setValueByPath(subProp.key, $event.target.value) ) : setValueByPath(subProp.key, $event.target.value)\" />\n\n <input *ngIf=\"subProp.type === 'boolean'\" type=\"checkbox\" [checked]=\"getValueByPath(subProp.key)\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\" />\n <select *ngIf=\"subProp.type === 'select'\" [value]=\"getValueByPath(subProp.key)\"\n (change)=\"setValueByPath(subProp.key, $event.target.value)\">\n <option *ngFor=\"let option of subProp.options\" [value]=\"option\">{{ option }}</option>\n </select>\n <input *ngIf=\"subProp.type === 'checkbox'\" type=\"checkbox\" [checked]=\"getValueByPath(subProp.key)\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\" />\n </div>\n </div>\n </div>\n </div>\n\n <!-- SKS20MAR25 Text Align Buttons -->\n <div *ngIf=\"prop.type === 'align'\">\n <button *ngFor=\"let option of prop.options\" (click)=\"onAlignSelect(option.value)\"\n [class.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\n <div *ngIf=\"prop.type === 'style'\">\n <button *ngFor=\"let option of prop.options\" (click)=\"onStyleSelect(option.value)\"\n [class.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\n <!-- Field Size Controls -->\n <!-- AP 25FEB25 - Change key size -->\n <div *ngIf=\"prop.key === 'size'\">\n <input type=\"number\" [value]=\"selectedElement?.size\" (input)=\"setValueByPath('size', $event.target.value)\"\n class=\"size-input\" />\n </div>\n\n <!-- AP-19MAR25 Line Properties -->\n <!-- Padding Top -->\n <div *ngIf=\"prop.key === 'paddingTop'\">\n <input type=\"number\" [placeholder]=\"prop.placeholder\" [value]=\"selectedElement?.paddingTop\"\n (input)=\"setValueByPath('paddingTop', $event.target.value)\" />\n </div>\n\n <!-- Padding Bottom -->\n <div *ngIf=\"prop.key === 'paddingBottom'\">\n <input type=\"number\" [placeholder]=\"prop.placeholder\" [value]=\"selectedElement?.paddingBottom\"\n (input)=\"setValueByPath('paddingBottom', $event.target.value)\" />\n </div>\n\n <!-- Line Style -->\n <div *ngIf=\"prop.key === 'lineStyle'\">\n <select [value]=\"selectedElement?.lineStyle\" (change)=\"setValueByPath('lineStyle', $event.target.value)\">\n <option *ngFor=\"let option of prop.options\" [value]=\"option\">{{ option }}</option>\n </select>\n </div>\n\n <!-- Color -->\n <div *ngIf=\"prop.key === 'color'\">\n <input type=\"color\" [value]=\"selectedElement?.color\"\n (input)=\"setValueByPath('color', $event.target.value)\" />\n </div>\n\n </div>\n \n <!-- AP 23MAY25 - Action Button -->\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.label }}</label>\n <button (click)=\"addNewButton()\" class=\"add-button\">+ Add Button</button>\n </div>\n \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</label>\n <input type=\"text\" [(ngModel)]=\"btn.name\" (ngModelChange)=\"onButtonPropertyChange(i, 'name', $event)\" placeholder=\"Enter button name\">\n </div>\n \n <div class=\"form-group\">\n <label>Event Name</label>\n <input type=\"text\" [(ngModel)]=\"btn.eventtoemit\" (ngModelChange)=\"onButtonPropertyChange(i, 'eventtoemit', $event)\" placeholder=\"Event to emit\">\n </div>\n \n <div class=\"form-group\">\n <label>Alt</label>\n <input type=\"text\" [(ngModel)]=\"btn.alt\" (ngModelChange)=\"onButtonPropertyChange(i, 'alt', $event)\" placeholder=\"Button alt text\">\n </div>\n \n <div class=\"form-group\">\n <label>Endpoint</label>\n <input type=\"text\" [(ngModel)]=\"btn.endpoint\" (ngModelChange)=\"onButtonPropertyChange(i, 'endpoint', $event)\" placeholder=\"API endpoint\">\n </div>\n \n <div class=\"form-group\">\n <label>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 \n <!-- AP 23MAY25 - Action Style Fields -->\n <div class=\"form-group\">\n <label>Background Color</label>\n <input type=\"color\" [(ngModel)]=\"btn.bgColor\" (ngModelChange)=\"onButtonPropertyChange(i, 'bgColor', $event)\">\n </div>\n \n <div class=\"form-group\">\n <label>Border Radius</label>\n <input type=\"range\" min=\"0\" max=\"50\" [(ngModel)]=\"btn.borderRadius\" \n (ngModelChange)=\"onButtonPropertyChange(i, 'borderRadius', $event)\">\n <span>{{ btn.borderRadius }}px</span>\n </div> \n \n <div class=\"form-group\">\n <label>Button Width (px)</label>\n <input type=\"number\" [(ngModel)]=\"btn.width\"\n (ngModelChange)=\"onButtonPropertyChange(i, 'width', $event)\" min=\"50\" placeholder=\"Enter width in px\">\n </div>\n \n <div class=\"form-group\">\n <label>Text Color</label>\n <input type=\"color\" [(ngModel)]=\"btn.textColor\"\n (ngModelChange)=\"onButtonPropertyChange(i, 'textColor', $event)\">\n </div>\n \n <div class=\"form-group\">\n <label>Position (%)</label>\n <input type=\"range\" min=\"0\" max=\"100\" [(ngModel)]=\"btn.positionPercent\"\n (ngModelChange)=\"onButtonPropertyChange(i, 'positionPercent', $event)\">\n <span>{{ btn.positionPercent }}%</span>\n </div>\n <button (click)=\"removeButton(btn)\" class=\"remove-button\">\u00D7 Remove</button>\n </div>\n </div>\n \n </ng-container>\n </div>\n </div>\n <div class=\"tab-content\" *ngIf=\"activeTab === 'property'\">\n <!-- Field Elements Properties -->\n <!-- AP-06MAR25 Show elements ID -->\n <div *ngIf=\"getProperties()\">\n <label>Label Id</label>\n <div\n style=\"font-size: 13px; padding: 11px; border-radius: 5px; background-color: #f8f8f8; border: 1px solid #ddd;\">\n {{ headerSelect ? bookId : selectedElement.id }}</div>\n <ng-container *ngFor=\"let prop of getProperties().fieldProps\">\n <div class=\"form-group\">\n <label class=\"text-sm\">{{ prop.label }}</label>\n\n <!-- SKS21MAR25 Toggle Group -->\n <div *ngIf=\"prop.type === 'toggleGroup'\" class=\"toggle-group\">\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" [checked]=\"selectedElement?.isOptional\"\n (change)=\"onRequiredChange($event.target.checked)\" />\n Required\n </label>\n </div>\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" [checked]=\"selectedElement?.isReadOnly\"\n (change)=\"onToggleChange('isReadOnly', $event)\" />\n Read Only\n </label>\n </div>\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" />\n Disabled\n </label>\n </div>\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" [checked]=\"selectedElement?.isHidden\"\n (change)=\"onToggleChange('isHidden', $event)\" />\n Is Hide\n </label>\n </div>\n </div>\n\n <!-- AP 28FEB25 - handled options with UUID -->\n <div\n *ngIf=\"prop.type === 'dropdown' || prop.type === 'checkbox' || prop.type === 'radio' && prop.key === 'options'\"\n class=\"options-container\">\n\n <div class=\"option-list\" (dragover)=\"onDragOver($event)\" (drop)=\"onDrop($event, prop.key)\">\n <div *ngFor=\"let option of selectedElement[prop.key]\" class=\"option-items\" [attr.data-id]=\"option.id\"\n draggable=\"true\" (dragstart)=\"onDragStart($event, option.id)\">\n\n <input type=\"text\" [(ngModel)]=\"option.value\" placeholder=\"Option\" 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\n <button (click)=\"addOption(selectedElement[prop.key])\">\n <div class=\"add-varient\">\n <span class=\"text-lg\">+</span>\n <span>Add</span>\n </div>\n </button>\n </div>\n\n <input *ngIf=\"prop.type === 'text'\" type=\"text\" [placeholder]=\"prop.placeholder\"\n [value]=\"headerSelect ? book.records[0].title : (selectedElement?.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key))\"\n (input)=\"headerSelect ? updateTitle($event.target.value) : (selectedElement?.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value))\"\n [class.read-only]=\"selectedElement.readOnly\" [readonly]=\"selectedElement.readOnly\" />\n\n <!-- Sub Questions Toggle -->\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]=\"prop.isExpanded ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\"\n alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n\n <!-- Render subquestions when arrow is down -->\n <div *ngIf=\"prop.isExpanded\" style=\"border: 1px solid #ddd; padding: 8px; border-radius: 4px;\">\n <div *ngFor=\"let subProp of prop.subQuestion\" class=\"sub-question-container\">\n <div class=\"form-group\">\n <label>{{ subProp.label }}</label>\n\n <input *ngIf=\"subProp.type === 'text'\" type=\"text\" [placeholder]=\"subProp.placeholder\"\n [value]=\"getValueByPath(subProp.key)\" (input)=\"setValueByPath(subProp.key, $event.target.value)\" />\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)\" />\n <!-- <input type=\"text\" [ngModel]=\"fieldAsString\" (ngModelChange)=\"updateField($event)\" /> -->\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\n <div *ngIf=\"prop.type === 'checkbox'\">\n <span class=\"toggle-label\" style=\"padding-right: 10px;\">{{ prop.label }}</span>\n <input type=\"checkbox\"\n [checked]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ): getValueByPath(prop.key) \"\n (change)=\" selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : onToggleChange(prop.key, $event) ) : onToggleChange(prop.key, $event)\" />\n\n </div>\n\n </div>\n </ng-container>\n\n <!-- SKS21MAR25 Move Style Outside the Loop -->\n <!-- Style Toggle -->\n <div class=\"style-toggle-header\" (click)=\"toggleStyleSection()\">\n <div class=\"head-elements\">Style</div>\n <img [src]=\"isStyleExpanded ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\"\n alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n\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 type=\"text\" [(ngModel)]=\"selectedElement.style[key]\"\n (input)=\"setValueByPath('style.' + key, $event.target.value)\" placeholder=\"Enter {{ key }}\" />\n </div>\n </div>\n </div>\n\n </div>\n </div>\n <div class=\"tab-content\" *ngIf=\"activeTab === 'appearance'\">\n <div *ngIf=\"getProperties()\">\n <ng-container *ngFor=\"let prop of getProperties().appearance\">\n <div class=\"form-group\">\n <label class=\"text-sm\">{{ prop.label }}</label>\n <!-- Font Selection -->\n <div *ngIf=\"prop.key === 'font'\">\n <select *ngIf=\"prop.type === 'select'\" class=\"select-container\" [(ngModel)]=\"selectedElement.font\"\n (change)=\"setValueByPath('font', $event.target.value)\">\n <option *ngFor=\"let option of prop.options\" [value]=\"option\">\n {{ option }}\n </option>\n </select>\n </div>\n <!-- Input Box -->\n <input *ngIf=\"prop.type === 'text'\" type=\"text\" [placeholder]=\"prop.placeholder\"\n [value]=\"selectedElement[prop.key]\" (input)=\"setValueByPath(prop.key, $event.target.value)\" />\n\n <!-- Font Size Selection -->\n <div *ngIf=\"prop.key === 'fontSize'\">\n <select *ngIf=\"prop.type === 'select'\" [(ngModel)]=\"selectedElement[prop.key]\"\n (change)=\"setValueByPath(prop.key, $event.target.value)\">\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\">\n {{ option.label }}\n </option>\n </select>\n </div>\n <!-- Font Weight Selection -->\n <div *ngIf=\"prop.key === 'fontWeight'\">\n <select *ngIf=\"prop.type === 'select'\" [(ngModel)]=\"selectedElement[prop.key]\"\n (change)=\"setValueByPath(prop.key, $event.target.value)\">\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\">\n {{ option.label }}\n </option>\n </select>\n </div>\n\n <div class=\"flex-container\">\n <!-- Dropdown Box -->\n <div *ngIf=\"prop.type === 'dropdown'\" class=\"input-box-field\">\n <select [(ngModel)]=\"selectedElement[prop.key]\" (change)=\"setValueByPath(prop.key, $event.target.value)\">\n <option *ngFor=\"let option of prop.options\" [value]=\"option\">\n {{ option }}\n </option>\n </select>\n </div>\n\n <!-- Color Picker -->\n <div *ngIf=\"prop.type === 'color'\" class=\"color-selector\">\n <input type=\"color\" [(ngModel)]=\"selectedElement.fontColor\"\n (change)=\"setValueByPath('fontColor', $event.target.value)\">\n </div>\n\n <!-- HEX Input Box -->\n <div *ngIf=\"prop.type === 'color'\" class=\"hex-input-container\">\n <span>HEX Code</span>\n <input type=\"text\" [(ngModel)]=\"selectedElement[prop.key]\"\n (change)=\"setValueByPath(prop.key, $event.target.value)\" />\n </div>\n </div>\n \n <!-- AP-17APR25 Button for Duplicate Field -->\n<div *ngIf=\"prop.type === 'button-toggle'\" class=\"button-toggle-wrapper\">\n <button type=\"button\"\n class=\"toggle-button\"\n (click)=\"duplicateField(selectedElement)\">\n Add Duplicate\n </button>\n</div>\n\n\n </div>\n </ng-container>\n </div>\n </div>\n\n<!-- AP-08APR25 Default Save Button -->\n<div class=\"button-container\" *ngIf=\"!templateSelected\">\n <button class=\"cancel-btn\" (click)=\"onCancel()\">Cancel</button>\n <button class=\"save-btn\" (click)=\"handleButtonClick()\">Save</button>\n</div>\n\n<!-- AP-08APR25 Template Save Button -->\n<div class=\"button-container\" *ngIf=\"templateSelected\" style=\"margin-top: 20px;\">\n <button class=\"save-btn\" (click)=\"handleTemplateSave()\">Save Template</button>\n</div>\n\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;border:1px solid #ccc;margin-bottom:10px;cursor:grab;background:#fff}.option-items:active{opacity:.5}.drag-handle{margin-left:10px;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}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i5.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i5.RangeValueAccessor, selector: "input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]" }, { kind: "directive", type: i5.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ImageCropperComponent, selector: "image-cropper", inputs: ["imageChangedEvent", "imageURL", "imageBase64", "imageFile", "imageAltText", "options", "cropperFrameAriaLabel", "output", "format", "autoCrop", "cropper", "transform", "maintainAspectRatio", "aspectRatio", "resetCropOnAspectRatioChange", "resizeToWidth", "resizeToHeight", "cropperMinWidth", "cropperMinHeight", "cropperMaxHeight", "cropperMaxWidth", "cropperStaticWidth", "cropperStaticHeight", "canvasRotation", "initialStepSize", "roundCropper", "onlyScaleDown", "imageQuality", "backgroundColor", "containWithinAspectRatio", "hideResizeSquares", "allowMoveImage", "checkImageType", "alignImage", "disabled", "hidden"], outputs: ["imageCropped", "startCropImage", "imageLoaded", "cropperReady", "loadImageFailed", "transformChange", "cropperChange"] }, { kind: "component", type: NxtSearchBox, selector: "nxt-search-box", inputs: ["placeHolderText", "question", "apiMeta", "id", "readOnly", "mode"], outputs: ["searchValueChange"] }] });
883
+ duplicateField(element) {
884
+ const elements = this.formBuilderService.getElements();
885
+ const copy = JSON.parse(JSON.stringify(element));
886
+ //AP-18APR25 Generate a new ID using the service's method
887
+ copy.id = this.formBuilderService.addElementWithId();
888
+ //copy.uuid = copy.id;
889
+ // AP-18APR25 Set the questionNumber to the next available number
890
+ copy.questionNumber = elements.length + 1;
891
+ this.formBuilderService.addElement(copy);
892
+ }
893
+ draggedId = null;
894
+ updateBookSubtext(key, value) {
895
+ this.bookSubtext.update((s) => ({
896
+ ...s,
897
+ [key]: value,
898
+ }));
899
+ }
900
+ trackByProp(index, item) {
901
+ return item?.key ?? index;
902
+ }
903
+ // Add these getter methods
904
+ get currentElement() {
905
+ return this.selectedElement();
906
+ }
907
+ get currentElementType() {
908
+ return this.currentElement?.type;
909
+ }
910
+ get isTableElement() {
911
+ return this.currentElementType === 'Table';
912
+ }
913
+ get selectedColumnId() {
914
+ return this.selectColumn();
915
+ }
916
+ getOptimizedSubPropValue(subProp) {
917
+ const element = this.currentElement;
918
+ if (this.isTableElement && (subProp.targetArray || subProp.isTableColumn)) {
919
+ return this.getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, this.selectedColumnId, subProp.key, subProp.isTableColumn);
920
+ }
921
+ return this.getValueByPath(subProp.key, element);
922
+ }
923
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PropertiesComponent, deps: [{ token: i1.FormBuilderService }, { token: i2.TemplateService }], target: i0.ɵɵFactoryTarget.Component });
924
+ 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</div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab() === 'property'}\" (click)=\"setActiveTab('property')\">Property</div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab() === 'appearance'}\" (click)=\"setActiveTab('appearance')\">Appearance</div>\n </div>\n\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\">\u27F2</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"rotateRight()\" title=\"Rotate Right\">\u27F3</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"zoomOut()\" title=\"Zoom Out\">-</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"zoomIn()\" title=\"Zoom In\">+</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveLeft()\" title=\"Move Left\">\u2190</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveRight()\" title=\"Move Right\">\u2192</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveUp()\" title=\"Move Up\">\u2191</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveDown()\" title=\"Move Down\">\u2193</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipHorizontal()\" [ngClass]=\"{'enabled': transform().flipH}\" title=\"Flip Horizontally\">\u2194</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipVertical()\" [ngClass]=\"{'enabled': transform().flipV}\" title=\"Flip Vertically\">\u2195</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"resetImage()\" title=\"Reset\">\u00D7</div>\n </div>\n }\n <div *ngIf=\"selectedElement()?.type === 'Book'\">\n <label class=\"text-sm\">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...'\"\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>Endpoint:</label>\n <input type=\"text\" [ngModel]=\"bookSubtext().endpoint\" (ngModelChange)=\"updateBookSubtext('endpoint', $event)\" />\n <label>Variable:</label>\n <input type=\"text\" [ngModel]=\"bookSubtext().variable\" (ngModelChange)=\"updateBookSubtext('variable', $event)\" />\n <label>Field:</label>\n <input type=\"text\" [ngModel]=\"fieldAsString()\" (ngModelChange)=\"updateField($event)\" />\n <label>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.label }}</label>\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) : setValueByPath(prop.key, $event))\"\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) : setValueByPath(prop.key, $event))\"\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) : setValueByPath(prop.key, $event))\"\n >\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\">{{ 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) : onToggleChange(prop.key, $event)) : onToggleChange(prop.key, $event)\"\n />\n <span class=\"toggle-label\" style=\"padding-left: 10px;\">{{ 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.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) : 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.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) : setValueByPath(subProp.key, $event)) : setValueByPath(subProp.key, $event)\"\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) : setValueByPath(subProp.key, $event))\"\n >\n <option *ngFor=\"let option of subProp.options\" [value]=\"option.value\">{{ 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) : setValueByPath(prop.key, $event))\"\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.label }}</label>\n <button (click)=\"addNewButton()\" class=\"add-button\">+ 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</label>\n <input type=\"text\" [ngModel]=\"btn.name\" (ngModelChange)=\"onButtonPropertyChange(i, 'name', $event)\" placeholder=\"Enter button name\">\n </div>\n <div class=\"form-group\">\n <label>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</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>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</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</label>\n <input type=\"color\" [ngModel]=\"btn.bgColor\" (ngModelChange)=\"onButtonPropertyChange(i, 'bgColor', $event)\">\n </div>\n <div class=\"form-group\">\n <label>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)</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</label>\n <input type=\"color\" [ngModel]=\"btn.textColor\" (ngModelChange)=\"onButtonPropertyChange(i, 'textColor', $event)\">\n </div>\n <div class=\"form-group\">\n <label>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</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.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) : onToggleChange(prop.key, $event)) : onToggleChange('isOptional', $event)\"\n />\n 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) : onToggleChange(prop.key, $event)) : onToggleChange('isReadOnly', $event)\"\n />\n 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) : onToggleChange(prop.key, $event)) : onToggleChange('isHidden', $event)\"\n />\n 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\" [ngModel]=\"option.value\" (ngModelChange)=\"option.value = $event\" placeholder=\"Option\" 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</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) : setValueByPath(prop.key, $event))\"\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.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) : setValueByPath(subProp.key, $event.target.value)\"\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)\" />\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.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) : 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</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.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) : setValueByPath(prop.key, $event))\"\n >\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\">{{ 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)\"\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)\"\n >\n </div>\n <div *ngIf=\"prop.type === 'color'\" class=\"hex-input-container\">\n <span>HEX Code</span>\n <input\n type=\"text\"\n [ngModel]=\"selectedElement() | getValueByPath : prop.key\"\n (ngModelChange)=\"setValueByPath(prop.key, $event)\"\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\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</button>\n <button class=\"save-btn\" (click)=\"handleButtonClick()\">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</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;border:1px solid #ccc;margin-bottom:10px;cursor:grab;background:#fff}.option-items:active{opacity:.5}.drag-handle{margin-left:10px;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}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [i3.NgClass, i3.NgForOf, i3.NgIf, i4.NgSelectOption, i4.ɵNgSelectMultipleOption, i4.DefaultValueAccessor, i4.NumberValueAccessor, i4.RangeValueAccessor, i4.SelectControlValueAccessor, i4.NgControlStatus, i4.MinValidator, i4.NgModel, import("../../../components/search-box/search-box.component").then(m => m.NxtSearchBox), GetValueByPathPipe], () => [i3.NgClass, i3.NgIf, import("../../../components/image-cropper/component/image-cropper.component").then(m => m.ImageCropperComponent)], () => [i3.NgForOf, i3.NgIf, i4.DefaultValueAccessor, i4.NgControlStatus, i4.NgModel, GetValueByPathPipe], () => [i3.NgForOf, i3.NgIf, i4.NgSelectOption, i4.ɵNgSelectMultipleOption, i4.DefaultValueAccessor, i4.SelectControlValueAccessor, i4.NgControlStatus, i4.NgModel, GetValueByPathPipe]] });
1002
925
  }
1003
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PropertiesComponent, decorators: [{
1004
- type: Component,
1005
- args: [{ selector: 'app-properties', standalone: true, imports: [CommonModule, FormsModule, ImageCropperComponent, NxtSearchBox], template: "<!-- AP 22JAN25 - Field and Element Properties -->\n<div class=\"container\">\n <div class=\"tabs\">\n <div class=\"tab\" [ngClass]=\"{'active': activeTab === 'attributes'}\" (click)=\"setActiveTab('attributes')\">\n Attributes\n </div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab === 'property'}\" (click)=\"setActiveTab('property')\">\n Property\n </div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab === 'appearance'}\" (click)=\"setActiveTab('appearance')\">\n Appearance\n </div>\n </div>\n\n <div class=\"tab-content\" *ngIf=\"activeTab === 'attributes'\">\n <!-- Element Properrties -->\n <!-- AP-06MAR25 Select element type show -->\n <div *ngIf=\"getProperties()\">\n <!-- SKS25MAR25 this is for image edit -->\n <div *ngIf=\"selectedElement?.type === 'Image'\">\n <image-cropper *ngIf=\"selectedElement.imageData \" [imageBase64]=\"selectedElement.orgImageData\"\n [disabled]=\"false\" [alignImage]=\"alignImage\" [roundCropper]=\"roundCropper\" [backgroundColor]=\"'white'\"\n imageAltText=\"Alternative image text\" [allowMoveImage]=\"false\" [hideResizeSquares]=\"false\"\n [canvasRotation]=\"canvasRotation\" [aspectRatio]=\"aspectRatio\" [containWithinAspectRatio]=\"false\"\n [maintainAspectRatio]=\"false\" [cropperStaticWidth]=\"cropperStaticWidth\"\n [cropperStaticHeight]=\"cropperStaticHeight\" [cropperMinWidth]=\"cropperMinWidth\"\n [cropperMinHeight]=\"cropperMinHeight\" [cropperMaxWidth]=\"cropperMaxWidth\"\n [cropperMaxHeight]=\"cropperMaxHeight\" [resetCropOnAspectRatioChange]='true' [(cropper)]=\"cropper\"\n [(transform)]=\"transform\" [onlyScaleDown]=\"true\" output=\"blob\" format=\"png\"\n (imageCropped)=\"imageCropped($event)\" (cropperReady)=\"cropperReady($event)\"></image-cropper>\n <div *ngIf=\"selectedElement.imageData \" style=\"display: flex; gap: 2px;\">\n <div class=\"cursor-pointer logo-icon\" (click)=\"rotateLeft()\" title=\"Rotate Left\">\u27F2</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"rotateRight()\" title=\"Rotate Right\">\u27F3</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"zoomOut()\" title=\"Zoom Out\">-</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"zoomIn()\" title=\"Zoom In\">+</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveLeft()\" title=\"Move Left\">\u2190</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveRight()\" title=\"Move Right\">\u2192</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveUp()\" title=\"Move Up\">\u2191</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveDown()\" title=\"Move Down\">\u2193</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipHorizontal()\" [class.enabled]=\"transform.flipH\"\n title=\"Flip Horizontally\">\u2194</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipVertical()\" [class.enabled]=\"transform.flipV\"\n title=\"Flip Vertically\">\u2195</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"resetImage()\" title=\"Reset\">\u00D7</div>\n </div>\n </div>\n <!-- SKS28MAR25 search book specific for book element -->\n <div *ngIf=\"selectedElement?.type === 'Book'\">\n <label class=\"text-sm\">Search Book</label>\n <div style=\"display: flex; gap: 2px; align-items: center; justify-content: center;\">\n <nxt-search-box [question]=\"selectedElement\" [apiMeta]=\"bookSubtext\" [placeHolderText]=\"'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>Endpoint:</label>\n <input type=\"text\" [(ngModel)]=\"bookSubtext.endpoint\" />\n\n <label>Variable:</label>\n <input type=\"text\" [(ngModel)]=\"bookSubtext.variable\" />\n\n <label>Field:</label>\n <input type=\"text\" [ngModel]=\"fieldAsString\" (ngModelChange)=\"updateField($event)\" />\n\n <label>Default Field:</label>\n <input type=\"text\" [(ngModel)]=\"bookSubtext.defaultField\" />\n </div>\n </div>\n </div>\n </div>\n <ng-container *ngFor=\"let prop of getProperties().elementProps\">\n <div class=\"form-group\">\n <label *ngIf=\"prop.type !== 'checkbox' && prop.type !== 'subQuestion'\" class=\"text-sm\">{{ prop.label\n }}</label>\n\n <!-- Text Input -->\n <input *ngIf=\"prop.type === 'text'\" type=\"text\" [placeholder]=\"prop.placeholder\"\n [value]=\"headerSelect ? book.records[0].title : (selectedElement?.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key))\"\n (input)=\"headerSelect ? updateTitle($event.target.value) : (selectedElement?.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value))\"\n [class.read-only]=\"selectedElement.readOnly\" [readonly]=\"selectedElement.readOnly\" />\n\n <!-- help text -->\n <div *ngIf=\"prop.key === 'helpText' && selectedElement.helpText\">{{\n selectedElement.helpText }}</div>\n\n <!-- questionNumber -->\n <input *ngIf=\"prop.key === 'questionNumber'\" type=\"number\" [value]=\"selectedElement.questionNumber\"\n (input)=\"setValueByPath('questionNumber', $event.target.value)\" />\n\n <!-- file -->\n <!-- Add this inside the elementProps loop where other inputs are rendered -->\n <select *ngIf=\"prop.type === 'select' && prop.key === 'supportType'\" [value]=\"selectedElement[prop.key]\"\n (change)=\"setValueByPath(prop.key, $event.target.value)\">\n <option value=\"\">Select file category</option>\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\"> {{ option.label }} </option>\n </select>\n\n <div *ngIf=\"prop.type === 'checkbox'\">\n\n <input type=\"checkbox\"\n [checked]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ): getValueByPath(prop.key) \"\n (change)=\" selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : onToggleChange(prop.key, $event) ) : onToggleChange(prop.key, $event)\" />\n <span class=\"toggle-label\" style=\"padding-left: 10px;\">{{ prop.label }}</span>\n\n </div>\n\n <!--AP-11JUN25 - Show this section only if the property key is 'primaryKey' -->\n <div *ngIf=\"prop.key === 'primaryKey'\">\n <input type=\"checkbox\" [checked]=\"getValueByPath('primaryKey')\" [disabled]=\"!getValueByPath('primaryKey') && isAnotherIdSelected()\" (change)=\"onToggleChange('primaryKey', $event)\"/>\n <span class=\"toggle-label\" style=\"padding-left: 10px;\">primaryKey</span>\n </div>\n\n <!-- SKS20MAR25 Subquestion Type -->\n <div *ngIf=\"prop.type === 'subQuestion'\">\n <div style=\"display: flex; flex-direction: row; gap: 10px; align-items: center;\">\n <div>{{ prop.label }}</div>\n <input type=\"checkbox\"\n [checked]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ): getValueByPath(prop.key) \"\n (change)=\" selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : onToggleChange(prop.key, $event) ) : onToggleChange(prop.key, $event)\" />\n </div>\n <!-- SKS20MAR25 Render subquestions when checkbox is checked -->\n <div\n *ngIf=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ): getValueByPath(prop.key)\">\n <div *ngFor=\"let subProp of prop.subQuestion\"\n style=\"background-color: #e7f2ff; padding: 8px; border-radius: 4px;\">\n <div class=\"form-group\">\n <label>{{ subProp.label }}</label>\n <div *ngIf=\"subProp.type === 'array'\">\n <!-- Iterate over filtered columns to display checkboxes -->\n <div *ngFor=\"let column of filteredColumns\">\n <label>\n <input 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 {{ column.apiName }}\n </label>\n </div>\n </div>\n <!-- SKS21MAR25 New radio type -->\n <div *ngIf=\"subProp.type === 'radio'\">\n <div *ngFor=\"let column of filteredColumns\">\n <label>\n <input type=\"radio\" [name]=\"subProp.key\" [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 {{ column.apiName }}\n </label>\n </div>\n </div>\n <!-- SKS20MAR25 Add more subproperty types as needed -->\n <!-- Inside the subProp ngFor loop -->\n <input *ngIf=\"subProp.type === 'text'\" type=\"text\" [placeholder]=\"subProp.placeholder\"\n [value]=\"selectedElement.type === 'Table' ? (subProp.targetArray ? getValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key ) : getValueByPath(subProp.key) ) : getValueByPath(subProp.key)\"\n (input)=\"selectedElement.type === 'Table' ? (subProp.targetArray ? updateValueByArrayPath(subProp.targetArray, subProp.targetArrayKey, selectColumn, subProp.key, $event) : setValueByPath(subProp.key, $event.target.value) ) : setValueByPath(subProp.key, $event.target.value)\" />\n\n <input *ngIf=\"subProp.type === 'boolean'\" type=\"checkbox\" [checked]=\"getValueByPath(subProp.key)\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\" />\n <select *ngIf=\"subProp.type === 'select'\" [value]=\"getValueByPath(subProp.key)\"\n (change)=\"setValueByPath(subProp.key, $event.target.value)\">\n <option *ngFor=\"let option of subProp.options\" [value]=\"option\">{{ option }}</option>\n </select>\n <input *ngIf=\"subProp.type === 'checkbox'\" type=\"checkbox\" [checked]=\"getValueByPath(subProp.key)\"\n (change)=\"setValueByPath(subProp.key, $event.target.checked)\" />\n </div>\n </div>\n </div>\n </div>\n\n <!-- SKS20MAR25 Text Align Buttons -->\n <div *ngIf=\"prop.type === 'align'\">\n <button *ngFor=\"let option of prop.options\" (click)=\"onAlignSelect(option.value)\"\n [class.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\n <div *ngIf=\"prop.type === 'style'\">\n <button *ngFor=\"let option of prop.options\" (click)=\"onStyleSelect(option.value)\"\n [class.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\n <!-- Field Size Controls -->\n <!-- AP 25FEB25 - Change key size -->\n <div *ngIf=\"prop.key === 'size'\">\n <input type=\"number\" [value]=\"selectedElement?.size\" (input)=\"setValueByPath('size', $event.target.value)\"\n class=\"size-input\" />\n </div>\n\n <!-- AP-19MAR25 Line Properties -->\n <!-- Padding Top -->\n <div *ngIf=\"prop.key === 'paddingTop'\">\n <input type=\"number\" [placeholder]=\"prop.placeholder\" [value]=\"selectedElement?.paddingTop\"\n (input)=\"setValueByPath('paddingTop', $event.target.value)\" />\n </div>\n\n <!-- Padding Bottom -->\n <div *ngIf=\"prop.key === 'paddingBottom'\">\n <input type=\"number\" [placeholder]=\"prop.placeholder\" [value]=\"selectedElement?.paddingBottom\"\n (input)=\"setValueByPath('paddingBottom', $event.target.value)\" />\n </div>\n\n <!-- Line Style -->\n <div *ngIf=\"prop.key === 'lineStyle'\">\n <select [value]=\"selectedElement?.lineStyle\" (change)=\"setValueByPath('lineStyle', $event.target.value)\">\n <option *ngFor=\"let option of prop.options\" [value]=\"option\">{{ option }}</option>\n </select>\n </div>\n\n <!-- Color -->\n <div *ngIf=\"prop.key === 'color'\">\n <input type=\"color\" [value]=\"selectedElement?.color\"\n (input)=\"setValueByPath('color', $event.target.value)\" />\n </div>\n\n </div>\n \n <!-- AP 23MAY25 - Action Button -->\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.label }}</label>\n <button (click)=\"addNewButton()\" class=\"add-button\">+ Add Button</button>\n </div>\n \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</label>\n <input type=\"text\" [(ngModel)]=\"btn.name\" (ngModelChange)=\"onButtonPropertyChange(i, 'name', $event)\" placeholder=\"Enter button name\">\n </div>\n \n <div class=\"form-group\">\n <label>Event Name</label>\n <input type=\"text\" [(ngModel)]=\"btn.eventtoemit\" (ngModelChange)=\"onButtonPropertyChange(i, 'eventtoemit', $event)\" placeholder=\"Event to emit\">\n </div>\n \n <div class=\"form-group\">\n <label>Alt</label>\n <input type=\"text\" [(ngModel)]=\"btn.alt\" (ngModelChange)=\"onButtonPropertyChange(i, 'alt', $event)\" placeholder=\"Button alt text\">\n </div>\n \n <div class=\"form-group\">\n <label>Endpoint</label>\n <input type=\"text\" [(ngModel)]=\"btn.endpoint\" (ngModelChange)=\"onButtonPropertyChange(i, 'endpoint', $event)\" placeholder=\"API endpoint\">\n </div>\n \n <div class=\"form-group\">\n <label>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 \n <!-- AP 23MAY25 - Action Style Fields -->\n <div class=\"form-group\">\n <label>Background Color</label>\n <input type=\"color\" [(ngModel)]=\"btn.bgColor\" (ngModelChange)=\"onButtonPropertyChange(i, 'bgColor', $event)\">\n </div>\n \n <div class=\"form-group\">\n <label>Border Radius</label>\n <input type=\"range\" min=\"0\" max=\"50\" [(ngModel)]=\"btn.borderRadius\" \n (ngModelChange)=\"onButtonPropertyChange(i, 'borderRadius', $event)\">\n <span>{{ btn.borderRadius }}px</span>\n </div> \n \n <div class=\"form-group\">\n <label>Button Width (px)</label>\n <input type=\"number\" [(ngModel)]=\"btn.width\"\n (ngModelChange)=\"onButtonPropertyChange(i, 'width', $event)\" min=\"50\" placeholder=\"Enter width in px\">\n </div>\n \n <div class=\"form-group\">\n <label>Text Color</label>\n <input type=\"color\" [(ngModel)]=\"btn.textColor\"\n (ngModelChange)=\"onButtonPropertyChange(i, 'textColor', $event)\">\n </div>\n \n <div class=\"form-group\">\n <label>Position (%)</label>\n <input type=\"range\" min=\"0\" max=\"100\" [(ngModel)]=\"btn.positionPercent\"\n (ngModelChange)=\"onButtonPropertyChange(i, 'positionPercent', $event)\">\n <span>{{ btn.positionPercent }}%</span>\n </div>\n <button (click)=\"removeButton(btn)\" class=\"remove-button\">\u00D7 Remove</button>\n </div>\n </div>\n \n </ng-container>\n </div>\n </div>\n <div class=\"tab-content\" *ngIf=\"activeTab === 'property'\">\n <!-- Field Elements Properties -->\n <!-- AP-06MAR25 Show elements ID -->\n <div *ngIf=\"getProperties()\">\n <label>Label Id</label>\n <div\n style=\"font-size: 13px; padding: 11px; border-radius: 5px; background-color: #f8f8f8; border: 1px solid #ddd;\">\n {{ headerSelect ? bookId : selectedElement.id }}</div>\n <ng-container *ngFor=\"let prop of getProperties().fieldProps\">\n <div class=\"form-group\">\n <label class=\"text-sm\">{{ prop.label }}</label>\n\n <!-- SKS21MAR25 Toggle Group -->\n <div *ngIf=\"prop.type === 'toggleGroup'\" class=\"toggle-group\">\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" [checked]=\"selectedElement?.isOptional\"\n (change)=\"onRequiredChange($event.target.checked)\" />\n Required\n </label>\n </div>\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" [checked]=\"selectedElement?.isReadOnly\"\n (change)=\"onToggleChange('isReadOnly', $event)\" />\n Read Only\n </label>\n </div>\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" />\n Disabled\n </label>\n </div>\n <div class=\"toggle-item\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" [checked]=\"selectedElement?.isHidden\"\n (change)=\"onToggleChange('isHidden', $event)\" />\n Is Hide\n </label>\n </div>\n </div>\n\n <!-- AP 28FEB25 - handled options with UUID -->\n <div\n *ngIf=\"prop.type === 'dropdown' || prop.type === 'checkbox' || prop.type === 'radio' && prop.key === 'options'\"\n class=\"options-container\">\n\n <div class=\"option-list\" (dragover)=\"onDragOver($event)\" (drop)=\"onDrop($event, prop.key)\">\n <div *ngFor=\"let option of selectedElement[prop.key]\" class=\"option-items\" [attr.data-id]=\"option.id\"\n draggable=\"true\" (dragstart)=\"onDragStart($event, option.id)\">\n\n <input type=\"text\" [(ngModel)]=\"option.value\" placeholder=\"Option\" 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\n <button (click)=\"addOption(selectedElement[prop.key])\">\n <div class=\"add-varient\">\n <span class=\"text-lg\">+</span>\n <span>Add</span>\n </div>\n </button>\n </div>\n\n <input *ngIf=\"prop.type === 'text'\" type=\"text\" [placeholder]=\"prop.placeholder\"\n [value]=\"headerSelect ? book.records[0].title : (selectedElement?.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ) : getValueByPath(prop.key))\"\n (input)=\"headerSelect ? updateTitle($event.target.value) : (selectedElement?.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : setValueByPath(prop.key, $event.target.value) ) : setValueByPath(prop.key, $event.target.value))\"\n [class.read-only]=\"selectedElement.readOnly\" [readonly]=\"selectedElement.readOnly\" />\n\n <!-- Sub Questions Toggle -->\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]=\"prop.isExpanded ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\"\n alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n\n <!-- Render subquestions when arrow is down -->\n <div *ngIf=\"prop.isExpanded\" style=\"border: 1px solid #ddd; padding: 8px; border-radius: 4px;\">\n <div *ngFor=\"let subProp of prop.subQuestion\" class=\"sub-question-container\">\n <div class=\"form-group\">\n <label>{{ subProp.label }}</label>\n\n <input *ngIf=\"subProp.type === 'text'\" type=\"text\" [placeholder]=\"subProp.placeholder\"\n [value]=\"getValueByPath(subProp.key)\" (input)=\"setValueByPath(subProp.key, $event.target.value)\" />\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)\" />\n <!-- <input type=\"text\" [ngModel]=\"fieldAsString\" (ngModelChange)=\"updateField($event)\" /> -->\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\n <div *ngIf=\"prop.type === 'checkbox'\">\n <span class=\"toggle-label\" style=\"padding-right: 10px;\">{{ prop.label }}</span>\n <input type=\"checkbox\"\n [checked]=\"selectedElement.type === 'Table' ? (prop.targetArray ? getValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key ) : getValueByPath(prop.key) ): getValueByPath(prop.key) \"\n (change)=\" selectedElement.type === 'Table' ? (prop.targetArray ? updateValueByArrayPath(prop.targetArray, prop.targetArrayKey, selectColumn, prop.key, $event) : onToggleChange(prop.key, $event) ) : onToggleChange(prop.key, $event)\" />\n\n </div>\n\n </div>\n </ng-container>\n\n <!-- SKS21MAR25 Move Style Outside the Loop -->\n <!-- Style Toggle -->\n <div class=\"style-toggle-header\" (click)=\"toggleStyleSection()\">\n <div class=\"head-elements\">Style</div>\n <img [src]=\"isStyleExpanded ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\"\n alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n\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 type=\"text\" [(ngModel)]=\"selectedElement.style[key]\"\n (input)=\"setValueByPath('style.' + key, $event.target.value)\" placeholder=\"Enter {{ key }}\" />\n </div>\n </div>\n </div>\n\n </div>\n </div>\n <div class=\"tab-content\" *ngIf=\"activeTab === 'appearance'\">\n <div *ngIf=\"getProperties()\">\n <ng-container *ngFor=\"let prop of getProperties().appearance\">\n <div class=\"form-group\">\n <label class=\"text-sm\">{{ prop.label }}</label>\n <!-- Font Selection -->\n <div *ngIf=\"prop.key === 'font'\">\n <select *ngIf=\"prop.type === 'select'\" class=\"select-container\" [(ngModel)]=\"selectedElement.font\"\n (change)=\"setValueByPath('font', $event.target.value)\">\n <option *ngFor=\"let option of prop.options\" [value]=\"option\">\n {{ option }}\n </option>\n </select>\n </div>\n <!-- Input Box -->\n <input *ngIf=\"prop.type === 'text'\" type=\"text\" [placeholder]=\"prop.placeholder\"\n [value]=\"selectedElement[prop.key]\" (input)=\"setValueByPath(prop.key, $event.target.value)\" />\n\n <!-- Font Size Selection -->\n <div *ngIf=\"prop.key === 'fontSize'\">\n <select *ngIf=\"prop.type === 'select'\" [(ngModel)]=\"selectedElement[prop.key]\"\n (change)=\"setValueByPath(prop.key, $event.target.value)\">\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\">\n {{ option.label }}\n </option>\n </select>\n </div>\n <!-- Font Weight Selection -->\n <div *ngIf=\"prop.key === 'fontWeight'\">\n <select *ngIf=\"prop.type === 'select'\" [(ngModel)]=\"selectedElement[prop.key]\"\n (change)=\"setValueByPath(prop.key, $event.target.value)\">\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\">\n {{ option.label }}\n </option>\n </select>\n </div>\n\n <div class=\"flex-container\">\n <!-- Dropdown Box -->\n <div *ngIf=\"prop.type === 'dropdown'\" class=\"input-box-field\">\n <select [(ngModel)]=\"selectedElement[prop.key]\" (change)=\"setValueByPath(prop.key, $event.target.value)\">\n <option *ngFor=\"let option of prop.options\" [value]=\"option\">\n {{ option }}\n </option>\n </select>\n </div>\n\n <!-- Color Picker -->\n <div *ngIf=\"prop.type === 'color'\" class=\"color-selector\">\n <input type=\"color\" [(ngModel)]=\"selectedElement.fontColor\"\n (change)=\"setValueByPath('fontColor', $event.target.value)\">\n </div>\n\n <!-- HEX Input Box -->\n <div *ngIf=\"prop.type === 'color'\" class=\"hex-input-container\">\n <span>HEX Code</span>\n <input type=\"text\" [(ngModel)]=\"selectedElement[prop.key]\"\n (change)=\"setValueByPath(prop.key, $event.target.value)\" />\n </div>\n </div>\n \n <!-- AP-17APR25 Button for Duplicate Field -->\n<div *ngIf=\"prop.type === 'button-toggle'\" class=\"button-toggle-wrapper\">\n <button type=\"button\"\n class=\"toggle-button\"\n (click)=\"duplicateField(selectedElement)\">\n Add Duplicate\n </button>\n</div>\n\n\n </div>\n </ng-container>\n </div>\n </div>\n\n<!-- AP-08APR25 Default Save Button -->\n<div class=\"button-container\" *ngIf=\"!templateSelected\">\n <button class=\"cancel-btn\" (click)=\"onCancel()\">Cancel</button>\n <button class=\"save-btn\" (click)=\"handleButtonClick()\">Save</button>\n</div>\n\n<!-- AP-08APR25 Template Save Button -->\n<div class=\"button-container\" *ngIf=\"templateSelected\" style=\"margin-top: 20px;\">\n <button class=\"save-btn\" (click)=\"handleTemplateSave()\">Save Template</button>\n</div>\n\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;border:1px solid #ccc;margin-bottom:10px;cursor:grab;background:#fff}.option-items:active{opacity:.5}.drag-handle{margin-left:10px;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}}\n"] }]
1006
- }], ctorParameters: () => [{ type: i1.HttpClient }, { type: i2.FormBuilderService }, { type: i3.TemplateService }], propDecorators: { formButtonHandler: [{
1007
- type: Output
1008
- }], templateSaveHandler: [{
1009
- type: Output
1010
- }], selectedElementType: [{
1011
- type: Input
1012
- }], templateSelected: [{
1013
- type: Input
1014
- }], dropdown: [{
1015
- type: ViewChild,
1016
- args: ['dropdown', { static: false }]
1017
- }], onClickOutside: [{
1018
- type: HostListener,
1019
- args: ['document:click', ['$event']]
1020
- }] } });
1021
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvcGVydGllcy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9ueHQtYXBwL3NyYy9saWIvcGFnZXMvYnVpbGRlci9wcm9wZXJ0aWVzL3Byb3BlcnRpZXMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbnh0LWFwcC9zcmMvbGliL3BhZ2VzL2J1aWxkZXIvcHJvcGVydGllcy9wcm9wZXJ0aWVzLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxTQUFTLEVBQWMsWUFBWSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFpQixTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHbkksT0FBTyxFQUFFLEVBQUUsSUFBSSxNQUFNLEVBQUUsTUFBTSxNQUFNLENBQUMsQ0FBQSx3QkFBd0I7QUFHNUQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxxRUFBcUUsQ0FBQztBQUM1RyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0scURBQXFELENBQUM7QUFDbkYscUZBQXFGO0FBQ3JGLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxvQkFBb0IsRUFBRSxrQkFBa0IsRUFBRSx1QkFBdUIsRUFBc0IsTUFBTSx1Q0FBdUMsQ0FBQzs7Ozs7OztBQVFwSyxNQUFNLE9BQU8sbUJBQW1CO0lBZ1lWO0lBQTBCO0lBQStDO0lBL1g3RixPQUFPLENBQU07SUFDYixJQUFJLENBQVM7SUFDYixPQUFPLENBQU07SUFFYixtQkFBbUIsQ0FBQyxNQUErRjtRQUNqSCxPQUFPO1lBQ0wsWUFBWSxFQUFFLENBQUMsR0FBRyxvQkFBb0IsRUFBRSxHQUFHLENBQUMsTUFBTSxFQUFF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QUUsQ0FBQztnQkFDOUMsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLEVBQUUsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLEVBQUUsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7WUFDaEcsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztJQUN4QixDQUFDO3dHQXBrQ1UsbUJBQW1COzRGQUFuQixtQkFBbUIsb2JDckJoQyw4ditCQTRoQk0sNDJORDNnQk0sWUFBWSw2VkFBRSxXQUFXLHFnREFBRSxxQkFBcUIsc3pCQUFFLFlBQVk7OzRGQUk3RCxtQkFBbUI7a0JBUC9CLFNBQVM7K0JBQ0UsZ0JBQWdCLGNBQ2QsSUFBSSxXQUNQLENBQUMsWUFBWSxFQUFFLFdBQVcsRUFBRSxxQkFBcUIsRUFBRSxZQUFZLENBQUM7OElBaUIvRCxpQkFBaUI7c0JBQTFCLE1BQU07Z0JBQ0csbUJBQW1CO3NCQUE1QixNQUFNO2dCQUdFLG1CQUFtQjtzQkFBM0IsS0FBSztnQkF5Q0csZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUVvQyxRQUFRO3NCQUFqRCxTQUFTO3VCQUFDLFVBQVUsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7Z0JBbytCeEMsY0FBYztzQkFEYixZQUFZO3VCQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQVAgMjJKQU4yNVxuaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBIb3N0TGlzdGVuZXIsIElucHV0LCBPbkluaXQsIE91dHB1dCwgU2ltcGxlQ2hhbmdlcywgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBGb3JtQnVpbGRlclNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9mb3JtLWJ1aWxkZXIuc2VydmljZSc7XG5pbXBvcnQgeyBDcm9wcGVyUG9zaXRpb24sIERpbWVuc2lvbnMsIEltYWdlVHJhbnNmb3JtIH0gZnJvbSAnLi4vLi4vLi4vY29tcG9uZW50cy9pbWFnZS1jcm9wcGVyL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgdjQgYXMgdXVpZHY0IH0gZnJvbSAndXVpZCc7Ly9BUC0yOE1BUjI1IGltcG9ydCB1dWlkXG4vLyBBUC0xMUFQUjI1IGltcG9ydCB0ZW1wbGF0ZSBzZXJ2aWNlXG5pbXBvcnQgeyBUZW1wbGF0ZVNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy90ZW1wbGF0ZS5zZXJ2aWNlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IEltYWdlQ3JvcHBlckNvbXBvbmVudCB9IGZyb20gXCIuLi8uLi8uLi9jb21wb25lbnRzL2ltYWdlLWNyb3BwZXIvY29tcG9uZW50L2ltYWdlLWNyb3BwZXIuY29tcG9uZW50XCI7XG5pbXBvcnQgeyBOeHRTZWFyY2hCb3ggfSBmcm9tIFwiLi4vLi4vLi4vY29tcG9uZW50cy9zZWFyY2gtYm94L3NlYXJjaC1ib3guY29tcG9uZW50XCI7XG4vL0FQLTI1SlVOMjUtSW1wb3J0aW5nIGNvbW1vbiBjb25zdGFudHMgZm9yIGVsZW1lbnQsIGZpZWxkLCBhbmQgYXBwZWFyYW5jZSBwcm9wZXJ0aWVzXG5pbXBvcnQgeyBDT01NT05fRUxFTUVOVF9QUk9QUywgQ09NTU9OX09QVElPTlNfRklFTEQsIENPTU1PTl9GSUVMRF9QUk9QUywgQ09NTU9OX0FQUEVBUkFOQ0VfUFJPUFMsIENPTU1PTl9DT0xVTU5fRklFTER9IGZyb20gJy4uL3Byb3BlcnRpZXMvY29tbW9uLWZpZWxkcy5jb25zdGFudHMnO1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLXByb3BlcnRpZXMnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBGb3Jtc01vZHVsZSwgSW1hZ2VDcm9wcGVyQ29tcG9uZW50LCBOeHRTZWFyY2hCb3hdLFxuICB0ZW1wbGF0ZVVybDogJy4vcHJvcGVydGllcy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3Byb3BlcnRpZXMuY29tcG9uZW50LmNzcyddXG59KVxuZXhwb3J0IGNsYXNzIFByb3BlcnRpZXNDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBlbGVtZW50OiBhbnk7XG4gIGZyb206IHN0cmluZztcbiAgY29sdW1uczogYW55O1xuXG4gIGNyZWF0ZUVsZW1lbnRDb25maWcoY29uZmlnPzogeyBjdXN0b21FbGVtZW50UHJvcHM/OiBhbnlbXSwgY3VzdG9tRmllbGRQcm9wcz86IGFueVtdLCBjdXN0b21BcHBlYXJhbmNlUHJvcHM/OiBhbnlbXX0pIHtcbiAgICByZXR1cm4ge1xuICAgICAgZWxlbWVudFByb3BzOiBbLi4uQ09NTU9OX0VMRU1FTlRfUFJPUFMsIC4uLihjb25maWc/LmN1c3RvbUVsZW1lbnRQcm9wcyB8fCBbXSldLFxuICAgICAgZmllbGRQcm9wczogWy4uLkNPTU1PTl9GSUVMRF9QUk9QUywgLi4uKGNvbmZpZz8uY3VzdG9tRmllbGRQcm9wcyB8fCBbXSldLFxuICAgICAgYXBwZWFyYW5jZTogWy4uLkNPTU1PTl9BUFBFQVJBTkNFX1BST1BTLCAuLi4oY29uZmlnPy5jdXN0b21BcHBlYXJhbmNlUHJvcHMgfHwgW10pXVxuICAgIH07XG4gIH1cblxuICBAT3V0cHV0KCkgZm9ybUJ1dHRvbkhhbmRsZXIgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgQE91dHB1dCgpIHRlbXBsYXRlU2F2ZUhhbmRsZXIgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgc2VsZWN0ZWRPcHRpb246IHN0cmluZyA9ICcnO1xuICBzZWxlY3RlZEVsZW1lbnRJbmRleDogbnVtYmVyID0gLTE7XG4gIEBJbnB1dCgpIHNlbGVjdGVkRWxlbWVudFR5cGU6IHN0cmluZyA9ICcnO1xuICBzZWxlY3RlZEFsaWduOiBzdHJpbmcgPSAnYWxpZ24tbGVmdCc7ICAvLyBBZGQgdGhpcyBwcm9wZXJ0eVxuICBzZWxlY3RlZFN0eWxlczogc3RyaW5nW10gPSBbXTsgIC8vIFVzaW5nIGFycmF5IHNpbmNlIG11bHRpcGxlIHN0eWxlcyBjYW4gYmUgc2VsZWN0ZWRcbiAgZXJyb3JNZXNzYWdlOiBzdHJpbmcgPSAnJztcbiAgc2VsZWN0ZWRFbGVtZW50OiBhbnkgPSBudWxsOyAgLy8gUmVjZWl2ZSB0aGUgc2VsZWN0ZWQgZWxlbWVudFxuICBoZWFkZXJTZWxlY3Q6IGJvb2xlYW4gPSBmYWxzZTtcbiAgYm9va0lkOiBhbnk7XG4gIGJvb2s6IGFueTtcbiAgYWN0aXZlVGFiOiBzdHJpbmcgPSAnYXR0cmlidXRlcyc7XG4gIHNlbGVjdENvbHVtbjogYW55XG4gIHRyYW5zZm9ybTogSW1hZ2VUcmFuc2Zvcm0gPSB7XG4gICAgdHJhbnNsYXRlVW5pdDogJ3B4JyxcbiAgICBzY2FsZTogMSxcbiAgICByb3RhdGU6IDAsXG4gICAgZmxpcEg6IGZhbHNlLFxuICAgIGZsaXBWOiBmYWxzZSxcbiAgICB0cmFuc2xhdGVIOiAwLFxuICAgIHRyYW5zbGF0ZVY6IDBcbiAgfTtcbiAgY2FudmFzUm90YXRpb24gPSAwO1xuICBjcm9wcGVyPzogQ3JvcHBlclBvc2l0aW9uO1xuICBsb2FkaW5nID0gZmFsc2U7XG4gIGNyb3BwZXJNYXhIZWlnaHQgPSAwO1xuICBjcm9wcGVyTWF4V2lkdGggPSAwO1xuICBjcm9wcGVyTWluSGVpZ2h0ID0gMDtcbiAgY3JvcHBlck1pbldpZHRoID0gMDtcbiAgY3JvcHBlclN0YXRpY1dpZHRoID0gMDtcbiAgY3JvcHBlclN0YXRpY0hlaWdodCA9IDA7XG4gIGFzcGVjdFJhdGlvID0gNCAvIDM7XG4gIHJvdW5kQ3JvcHBlciA9IGZhbHNlO1xuICBpbWFnZUNoYW5nZWRFdmVudDogRXZlbnQgfCBudWxsID0gbnVsbDtcbiAgYWxpZ25JbWFnZSA9ICdjZW50ZXInIGFzIGNvbnN0O1xuICAvLyAgXCJlbmRwb2ludFwiOiBcImh0dHBzOi8vZGV2LWFwaS52YWxhcmhyLmNvbS9ueHRcIixcbiAgLy8gU0tTMjhNQVIyNSBkZWZhdWx0IGJvb2sgc2VhcmNoIGVuZHBvaW50XG4gIGJvb2tTdWJ0ZXh0ID0ge1xuICAgIFwiZW5kcG9pbnRcIjogXCJodHRwczovL2Rldi1hcGkudmFsYXJoci5jb20vbnh0XCIsXG4gICAgXCJ2YXJpYWJsZVwiOiBudWxsLFxuICAgIFwiZmllbGRcIjogWydsYWJlbCcsICduYW1lJ10sXG4gICAgXCJkZWZhdWx0RmllbGRcIjogXCJsYWJlbFwiXG4gIH1cbiAgaXNMaW5rRHJvcGRvd25PcGVuID0gZmFsc2U7XG4gIEBJbnB1dCgpIHRlbXBsYXRlU2VsZWN0ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBAVmlld0NoaWxkKCdkcm9wZG93bicsIHsgc3RhdGljOiBmYWxzZSB9KSBkcm9wZG93biE6IEVsZW1lbnRSZWY7XG5cblxuICBkcmFnZ2VkSWQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBmb3JtRWxlbWVudHM6IGFueVtdID0gW107XG4gXG4gIHVuaXF1ZV9pZDogc3RyaW5nID0gJ2Jvb2stMTIzNCc7IC8vIHNob3VsZCBiZSBjb25zaXN0ZW50XG4gIHNlbGVjdGVkVGVtcGxhdGU6IGFueTtcblxuICBlbGVtZW50UHJvcGVydGllcyA9IHtcbiAgICAvLyBBUC0xME1BUjI1IC0gRGVmaW5lcyB0aGUgSGVhZGVyIGVsZW1lbnQgd2l0aCBhIHRleHQgaW5wdXQgZmllbGQgICBcbiAgICAvLyBBUC0yNU1BUjI1IEFkZCBzdWJ0ZXh0IGFsbCB2YXJpYWJsZXNcbiAgICAnSGVhZGVyJzoge1xuICAgICAgZWxlbWVudFByb3BzOiBbXG4gICAgICAgIHsgbGFiZWw6ICdMYWJlbCcsIHBsYWNlaG9sZGVyOiAnRW50ZXIgVGV4dCcsIHR5cGU6ICd0ZXh0Jywga2V5OiAndGl0bGUnIH1dXG4gICAgfSxcbiAgICAvLyBBUC0xOU1BUjI1IEFkZCBMaW5lIFByb3BlcnR5XG4gICAgJ0xpbmUnOiB7XG4gICAgICBlbGVtZW50UHJvcHM6IFtcbiAgICAgICAgeyBsYWJlbDogJ0xpbmUgV2lkdGgnLCB0eXBlOiAnZmllbGRTaXplJywga2V5OiAnc2l6ZScgfSxcbiAgICAgICAgeyBsYWJlbDogJ1BhZGRpbmcgVG9wJywgdHlwZTogJ251bWJlcicsIGtleTogJ3BhZGRpbmdUb3AnLCBwbGFjZWhvbGRlcjogJ0VudGVyIHBhZGRpbmcgdG9wJyB9LFxuICAgICAgICB7IGxhYmVsOiAnUGFkZGluZyBCb3R0b20nLCB0eXBlOiAnbnVtYmVyJywga2V5OiAncGFkZGluZ0JvdHRvbScsIHBsYWNlaG9sZGVyOiAnRW50ZXIgcGFkZGluZyBib3R0b20nIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBsYWJlbDogJ0xpbmUgU3R5bGUnLCB0eXBlOiAnc2VsZWN0Jywga2V5OiAnbGluZVN0eWxlJyxcbiAgICAgICAgICBvcHRpb25zOiBbJ1NvbGlkJywgJ0Rhc2hlZCcsICdEb3R0ZWQnXVxuICAgICAgICB9XG4gICAgICBdLFxuICAgICAgZmllbGRQcm9wczogW11cbiAgICB9LFxuXG4gICAgJ1NwYWNlJzoge1xuICAgICAgZWxlbWVudFByb3BzOiBbXG4gICAgICAgIHsgbGFiZWw6ICdFbGVtZW50JywgdHlwZTogJ251bWJlcicsIGtleTogJ3F1ZXN0aW9uTnVtYmVyJyB9LFxuICAgICAgICB7IGxhYmVsOiAnRmllbGQgU2l6ZScsIHR5cGU6ICdmaWVsZFNpemUnLCBrZXk6ICdzaXplJyB9LFxuICAgICAgXSxcbiAgICAgIGZpZWxkUHJvcHM6IFtdXG4gICAgfSxcblxuICAgIFwiVGFibGVcIjoge1xuICAgICAgXCJlbGVtZW50UHJvcHNcIjogW1xuICAgICAgICB7bGFiZWw6ICdJcyBMYWJlbCcsIHBsYWNlaG9sZGVyOiAnRW50ZXIgVGV4dCAnLCB0eXBlOiAnY2hlY2tib3gnLCBrZXk6ICdzdHlsZS5zaG93TGFiZWwnIH0sXG4gICAgICAgIHsga2V5OiAncHJpbWFyeUtleScgfSxcbiAgICAgICAgeyBcImxhYmVsXCI6IFwidGFibGVOYW1lXCIsIFwicGxhY2Vob2xkZXJcIjogXCJFbXBsb3llZSBEZXRhaWxzXCIsIFwidHlwZVwiOiBcInRleHRcIiwgXCJrZXlcIjogXCJxdWVzdGlvblRleHRcIiB9LFxuICAgICAgICB7IFwibGFiZWxcIjogXCJpbnB1dFRleHRBbGlnbm1lbnRcIiwgXCJwbGFjZWhvbGRlclwiOiBcIkxlZnRcIiwgXCJ0eXBlXCI6IFwidGV4dFwiLCBcImtleVwiOiBcImlucHV0VGV4dEFsaWdubWVudFwiIH0sXG4gICAgICAgIHsgXCJsYWJlbFwiOiBcInRhYmxlU2NhbGVTaXplXCIsIFwicGxhY2Vob2xkZXJcIjogXCIwNiAtIEZ1bGwgU2NhbGVcIiwgXCJ0eXBlXCI6IFwidGV4dFwiLCBcImtleVwiOiBcInRhYmxlU2NhbGVTaXplXCIgfSxcbiAgICAgICAgeyBcImxhYmVsXCI6IFwiaXNOb3NJbmRpY2F0b3JcIiwgXCJwbGFjZWhvbGRlclwiOiBcIjA2IC0gRnVsbCBTY2FsZVwiLCBcInR5cGVcIjogXCJjaGVja2JveFwiLCBcImtleVwiOiBcInRhYmxlQ29uZmlnLmlzTm9zSW5kaWNhdG9yXCIgfSxcbiAgICAgICAgeyBcImxhYmVsXCI6IFwiaXNQYWdpbmF0aW9uXCIsIFwicGxhY2Vob2xkZXJcIjogXCIwNiAtIEZ1bGwgU2NhbGVcIiwgXCJ0eXBlXCI6IFwiY2hlY2tib3hcIiwgXCJrZXlcIjogXCJ0YWJsZUNvbmZpZy5pc1BhZ2luYXRpb25cIiB9LFxuICAgICAgICB7IFwibGFiZWxcIjogXCJhZGRJbmxpbmVSZWNvcmRcIiwgXCJwbGFjZWhvbGRlclwiOiBcIjA2IC0gRnVsbCBTY2FsZVwiLCBcInR5cGVcIjogXCJjaGVja2JveFwiLCBcImtleVwiOiBcInRhYmxlQ29uZmlnLmFkZElubGluZVJlY29yZFwiIH0sXG4gICAgICAgIHsgXCJsYWJlbFwiOiBcImFjdGlvbkJ1dHRvblwiLCBcInBsYWNlaG9sZGVyXCI6IFwiMDYgLSBGdWxsIFNjYWxlXCIsIFwidHlwZVwiOiBcImNoZWNrYm94XCIsIFwia2V5XCI6IFwidGFibGVDb25maWcuYWN0aW9uQnV0dG9uXCIgfSxcbiAgICAgICAgeyBcImxhYmVsXCI6IFwic2VhcmNoQmFyXCIsIFwicGxhY2Vob2xkZXJcIjogXCIwNiAtIEZ1bGwgU2NhbGVcIiwgXCJ0eXBlXCI6IFwiY2hlY2tib3hcIiwgXCJrZXlcIjogXCJ0YWJsZUNvbmZpZy5zZWFyY2hCYXJcIiB9LFxuICAgICAgICB7IFwibGFiZWxcIjogXCJpc0RlbGV0ZVJvd1wiLCBcInBsYWNlaG9sZGVyXCI6IFwiMDYgLSBGdWxsIFNjYWxlXCIsIFwidHlwZVwiOiBcImNoZWNrYm94XCIsIFwia2V5XCI6IFwidGFibGVDb25maWcuaXNEZWxldGVSb3dcIiB9LFxuICAgICAgICB7IFwibGFiZWxcIjogXCJpc0VkaXRSb3dcIiwgXCJwbGFjZWhvbGRlclwiOiBcIjA2IC0gRnVsbCBTY2FsZVwiLCBcInR5cGVcIjogXCJjaGVja2JveFwiLCBcImtleVwiOiBcInRhYmxlQ29uZmlnLmlzRWRpdFJvd1wiIH0sXG4gICAgICAgIHsgXCJsYWJlbFwiOiBcImlzQnV0dG9uc1wiLCBcInBsYWNlaG9sZGVyXCI6IFwiMDYgLSBGdWxsIFNjYWxlXCIsIFwidHlwZVwiOiBcImNoZWNrYm94XCIsIFwia2V5XCI6IFwidGFibGVDb25maWcuaXNCdXR0b25zXCIgfSxcblxuXG4gICAgICAgIHsgXCJsYWJlbFwiOiBcInJvd0Nob2ljZVwiLCBcInBsYWNlaG9sZGVyXCI6IFwiXCIsIFwidHlwZVwiOiBcInRleHRcIiwgXCJrZXlcIjogXCJyb3dDaG9pY2VcIiB9LFxuICAgICAgICB7IGxhYmVsOiAncXVlc3Rpb25OdW1iZXInLCB0eXBlOiAnbnVtYmVyJywga2V5OiAncXVlc3Rpb25OdW1iZXInIH0sXG4gICAgICAgIHsgbGFiZWw6ICdGaWVsZCBTaXplJywgdHlwZTogJ2ZpZWxkU2l6ZScsIGtleTogJ3NpemUnIH0sXG4gICAgICBdLFxuICAgICAgXCJmaWVsZFByb3BzXCI6IFtcbiAgICAgICAgeyBcImxhYmVsXCI6IFwidGFibGVJZFwiLCBcInBsYWNlaG9sZGVyXCI6IFwiRW1wX1RhYmxlXzAxXCIsIFwidHlwZVwiOiBcInRleHRcIiwgXCJrZXlcIjogXCJ0YWJsZUlkXCIgfSxcbiAgICAgICAgeyBcImxhYmVsXCI6IFwiaGVscFRleHRcIiwgXCJwbGFjZWhvbGRlclwiOiBcIkVudGVyIG1lc3NhZ2VcIiwgXCJ0eXBlXCI6IFwidGV4dFwiLCBcImtleVwiOiBcImhlbHBUZXh0XCIgfSxcbiAgICAgICAgeyBcImxhYmVsXCI6IFwiZGVmYXVsdFZhbHVlXCIsIFwicGxhY2Vob2xkZXJcIjogXCJEZWZhdWx0IFZhbHVlXCIsIFwidHlwZVwiOiBcInRleHRcIiwgXCJrZXlcIjogXCJkZWZhdWx0VmFsdWVcIiB9LFxuICAgICAgICB7IGxhYmVsOiAnUmVmZXJlbmNlJywgcGxhY2Vob2xkZXI6ICdSZWZlcmVuY2UgRmllbGQnLCB0eXBlOiAndGV4dCcsIGtleTogJ3JlZmVyZW5jZUZpZWxkJyB9LFxuICAgICAgICB7XG4gICAgICAgICAgXCJsYWJlbFwiOiBcIlwiLCBcInBsYWNlaG9sZGVyXCI6IFwiRW50ZXIgVGV4dFwiLCBcInR5cGVcIjogXCJzdWJRdWVzdGlvblwiLCBcImtleVwiOiBcImlzU3ViVGV4dFwiLFxuICAgICAgICAgIFwic3ViUXVlc3Rpb25cIjogW1xuICAgICAgICAgICAgeyBcImxhYmVsXCI6IFwiRW5kIFBvaW50XCIsIFwicGxhY2Vob2xkZXJcIjogXCJlbmRwb2ludFwiLCBcInR5cGVcIjogXCJ0ZXh0XCIsIFwia2V5XCI6IFwic3ViVGV4dC5lbmRwb2ludFwiIH0sXG4gICAgICAgICAgICB7IFwibGFiZWxcIjogXCJWYXJpYWJsZVwiLCBcInBsYWNlaG9sZGVyXCI6IFwidmFyaWFibGVcIiwgXCJ0eXBlXCI6IFwidGV4dFwiLCBcImtleVwiOiBcInN1YlRleHQudmFyaWFibGVcIiB9LFxuICAgICAgICAgICAgeyBcImxhYmVsXCI6IFwiRmllbGRcIiwgXCJwbGFjZWhvbGRlclwiOiBcImZpZWxkXCIsIFwidHlwZVwiOiBcInRleHRcIiwgXCJrZXlcIjogXCJzdWJUZXh0LmZpZWxkXCIgfSxcblxuICAgICAgICAgICAgeyBcImxhYmVsXCI6IFwiRGVmYXVsdCBGaWVsZFwiLCBcInBsYWNlaG9sZGVyXCI6IFwiZGVmYXVsdEZpZWxkXCIsIFwidHlwZVwiOiBcInRleHRcIiwgXCJrZXlcIjogXCJzdWJUZXh0LmRlZmF1bHRGaWVsZFwiIH0sXG4gICAgICAgICAgICB7IFwibGFiZWxcIjogXCJMYWJlbCBGaWVsZFwiLCBcInBsYWNlaG9sZGVyXCI6IFwibGFiZWxGaWVsZFwiLCBcInR5cGVcIjogXCJ0ZXh0XCIsIFwia2V5XCI6IFwic3ViVGV4dC5sYWJlbEZpZWxkXCIgfSxcbiAgICAgICAgICAgIHsgXCJsYWJlbFwiOiBcIlZhbHVlIEZpZWxkXCIsIFwicGxhY2Vob2xkZXJcIjogXCJ2YWx1ZUZpZWxkXCIsIFwidHlwZVwiOiBcInRleHRcIiwgXCJrZXlcIjogXCJzdWJUZXh0LnZhbHVlRmllbGRcIiB9LFxuICAgICAgICAgICAgeyBcImxhYmVsXCI6IFwiU291cmNlIFF1ZXN0aW9uIElkXCIsIFwicGxhY2Vob2xkZXJcIjogXCJzb3VyY2VRdWVzdGlvbklkXCIsIFwidHlwZVwiOiBcInRleHRcIiwgXCJrZXlcIjogXCJzdWJUZXh0LnNvdXJjZVF1ZXN0aW9uSWRcIiB9LFxuICAgICAgICAgICAgeyBcImxhYmVsXCI6IFwiRGVwZW5kZW50IFZhbHVlXCIsIFwicGxhY2Vob2xkZXJcIjogXCJkZXBlbmRlbnRWYWx1ZVwiLCBcInR5cGVcIjogXCJ0ZXh0XCIsIFwia2V5XCI6IFwic3ViVGV4dC5kZXBlbmRlbnRWYWx1ZVwiIH0sXG4gICAgICAgICAgICB7IFwibGFiZWxcIjogXCJEZXBlbmRlbnQgRmllbGRcIiwgXCJwbGFjZWhvbGRlclwiOiBcImlzRGVwZW5kZW50RmllbGRcIiwgXCJ0eXBlXCI6IFwiYm9vbGVhblwiLCBcImtleVwiOiBcInN1YlRleHQuaXNEZXBlbmRlbnRGaWVsZFwiIH0sXG5cbiAgICAgICAgICAgIHsgXCJsYWJlbFwiOiBcIlF1ZXJ5IEZpZWxkXCIsIFwicGxhY2Vob2xkZXJcIjogXCJxdWVyeUZpZWxkXCIsIFwidHlwZVwiOiBcInRleHRcIiwgXCJrZXlcIjogXCJzdWJUZXh0LnF1ZXJ5RmllbGRcIiB9LFxuICAgICAgICAgICAgeyBcImxhYmVsXCI6IFwiUXVlcnkgVmFsdWVcIiwgXCJwbGFjZWhvbGRlclwiOiBcInF1ZXJ5VmFsdWVcIiwgXCJ0eXBlXCI6IFwidGV4dFwiLCBcImtleVwiOiBcInN1YlRleHQucXVlcnlWYWx1ZVwiIH0sXG4gICAgICAgICAgICB7IFwibGFiZWxcIjogXCJRdWVyeSBWYWx1ZSBSZWZcIiwgXCJwbGFjZWhvbGRlclwiOiBcInF1ZXJ5VmFsdWVSZWZcIiwgXCJ0eXBlXCI6IFwidGV4dFwiLCBcImtleVwiOiBcInN1YlRleHQucXVlcnlWYWx1ZVJlZmVyZW5jZVwiIH0sXG4gICAgICAgICAgICB7IFwibGFiZWxcIjogXCJVbmlxdWUgS2V5XCIsIFwicGxhY2Vob2xkZXJcIjogXCJ1bmlxdWVLZXlcIiwgXCJ0eXBlXCI6IFwidGV4dFwiLCBcImtleVwiOiBcInN1YlRleHQudW5pcXVlS2V5XCIgfSxcbiAgICAgICAgICBdXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgXCJhcHBlYXJhbmNlXCI6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBsYWJlbDogJ1NlbGVjdCBGb250JywgdHlwZTogJ3NlbGVjdCcsIGtleTogJ2ZvbnQnLCBwbGFjZWhvbGRlcjogJ0xlZnQnLCByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIG9wdGlvbnM6IFsnSGVsdmV0aWNhIE5ldWUnLCAnQXJpYWwnLCAnVGltZXMgTmV3IFJvbWFuJywgJ1JvYm90byddXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7IGxhYmVsOiAnRm9udCBDb2xvcicsIHR5cGU6ICdjb2xvcicsIGtleTogJ2ZvbnRDb2xvcicsIGRlZmF1bHRWYWx1ZTogJycsIHJlcXVpcmVkOiB0cnVlIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbGFiZWw6ICdGb250IFNpemUnLCB0eXBlOiAnc2VsZWN0Jywga2V5OiAnZm9udFNpemUnLCBkZWZhdWx0VmFsdWU6ICcnLCByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIG9wdGlvbnM6IFtcbiAgICAgICAgICAgICAgeyBsYWJlbDogJ1NtYWxsJywgdmFsdWU6ICcxMnB4JyB9LFxuICAgICAgICAgICAgICB7IGxhYmVsOiAnTWVkaXVtJywgdmFsdWU6ICcxNHB4JyB9LFxuICAgICAgICAgICAgICB7IGxhYmVsOiAnTGFyZ2UnLCB2YWx1ZTogJzE2cHgnIH1cbiAgICAgICAgICAgIF1cbiAgICAgICAgICB9LFxuICBcbiAgICAgICAgICB7XG4gICAgICAgICAgICBsYWJlbDogJ0ZvbnQgV2lkdGgnLCB0eXBlOiAnc2VsZWN0Jywga2V5OiAnZm9udFdlaWdodCcsIGRlZmF1bHRWYWx1ZTogJycsIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgICAgb3B0aW9uczogW1xuICAgICAgICAgICAgICB7IHZhbHVlOiAnNDAwJywgbGFiZWw6ICc0MDAtTm9ybWFsJyB9LFxuICAgICAgICAgICAgICB7IHZhbHVlOiAnNTAwJywgbGFiZWw6ICc1MDAtTWVkaXVtJyB9LFxuICAgICAgICAgICAgICB7IHZhbHVlOiAnNjAwJywgbGFiZWw6ICc2MDAtU2VtaSBCb2xkJyB9LFxuICAgICAgICAgICAgICB7IHZhbHVlOiAnNzAwJywgbGFiZWw6ICc3MDAtQm9sZCcgfVxuICAgICAgICAgICAgXVxuICAgICAgICAgIH0sXG4gICAgICAgICAgeyBsYWJlbDogJ0R1cGxpY2F0ZSBGaWVsZCcsIHR5cGU6ICdidXR0b24tdG9nZ2xlJywga2V5OiAnZHVwbGljYXRlRmllbGQnLCBkZWZhdWx0VmFsdWU6IGZhbHNlIH1cbiAgICAgICAgXVxuICAgIH0sXG4gICAgXCJUYWJsZUNvbHVtblwiOiB7XG4gICAgICBcImVsZW1lbnRQcm9wc1wiOiBbXG5cbiAgICAgICAgeyBcImxhYmVsXCI6IFwiaGVhZGVyTGFiZWxzXCIsIFwicGxhY2Vob2xkZXJcIjogXCJFbXBsb3llZSBEZXRhaWxzXCIsIFwidHlwZVwiOiBcInRleHRcIiwgXCJ0YXJnZXRBcnJheVwiOiBcImZpZWxkc01ldGFcIiwgXCJ0YXJnZXRBcnJheUtleVwiOiBcInVuaXF1ZUlkZW50aWZpZXJcIiwgXCJrZXlcIjogXCJsYWJlbFwiIH0sXG4gICAgICAgIHsgXCJsYWJlbFwiOiBcImFwaU5hbWVcIiwgXCJwbGFjZWhvbGRlclwiOiBcIkVtcGxveWVlIERldGFpbHNcIiwgXCJ0eXBlXCI6IFwidGV4dFwiLCBcInRhcmdldEFycmF5XCI6IFwiZmllbGRzTWV0YVwiLCBcInRhcmdldEFycmF5S2V5XCI6IFwidW5pcXVlSWRlbnRpZmllclwiLCBcImtleVwiOiBcImFwaU5hbWVcIiB9LFxuXG4gICAgICAgIHtcbiAgICAgICAgICBcImxhYmVsXCI6IFwiU3VtbWFyeSBDb2x1bW5cIiwgXCJwbGFjZWhvbGRlclwiOiBcIlN1bW1hcnkgQ29sdW1uXCIsIFwidHlwZVwiOiBcInN1YlF1ZXN0aW9uXCIsIFwidGFyZ2V0QXJyYXlcIjogXCJmaWVsZHNNZXRhXCIsIFwidGFyZ2V0QXJyYXlLZXlcIjogXCJ1bmlxdWVJZGVudGlmaWVyXCIsIFwia2V5XCI6IFwic3VtbWFyeUNvbHVtblwiLFxuICAgICAgICAgIFwic3ViUXVlc3Rpb25cIjogW1xuICAgICAgICAgICAgeyBcImxhYmVsXCI6IFwiVHlwZVwiLCBcInBsYWNlaG9sZGVyXCI6IFwiRW1wbG95ZWUgRGV0YWlsc1wiLCBcInR5cGVcIjogXCJ0ZXh0XCIsIFwidGFyZ2V0QXJyYXlcIjogXCJmaWVsZHNNZXRhXCIsIFwidGFyZ2V0QXJyYXlLZXlcIjogXCJ1bmlxdWVJZGVudGlmaWVyXCIsIFwia2V5XCI6IFwiZmxkVHlwZVwiIH0sXG4gICAgICAgICAgICB7IFwibGFiZWxcIjogXCJPcGVyYXRpb25cIiwgXCJwbGFjZWhvbGRlclwiOiBcIkVtcGxveWVlIERldGFpbHNcIiwgXCJ0eXBlXCI6IFwidGV4dFwiLCBcInRhcmdldEFycmF5XCI6IFwiZmllbGRzTWV0YVwiLCBcInRhcmdldEFycmF5S2V5XCI6IFwidW5pcXVlSWRlbnRpZmllclwiLCBcImtleVwiOiBcIm9wZXJhdGlvblwiIH0sXG4gICAgICAgICAgICB7IFwibGFiZWxcIjogXCJPcGVyYW5kc1wiLCBcInBsYWNlaG9sZGVyXCI6IFwiRW1wbG95ZWUgRGV0YWlsc1wiLCBcInR5cGVcIjogXCJhcnJheVwiLCBcInRhcmdldEFycmF5XCI6IFwiZmllbGRzTWV0YVwiLCBcInRhcmdldEFycmF5S2V5XCI6IFwidW5pcXVlSWRlbnRpZmllclwiLCBcImtleVwiOiBcIm9wZXJhbmRzXCIgfSxcbiAgICAgICAgICBdXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBcImxhYmVsXCI6IFwiU3VtbWFyeSBSb3dcIiwgXCJwbGFjZWhvbGRlclwiOiBcIlN1bW1hcnkgUm93XCIsIFwidHlwZVwiOiBcInN1YlF1ZXN0aW9uXCIsIFwidGFyZ2V0QXJyYXlcIjogXCJmaWVsZHNNZXRhXCIsIFwidGFyZ2V0QXJyYXlLZXlcIjogXCJ1bmlxdWVJZGVudGlmaWVyXCIsIFwia2V5XCI6IFwic3VtbWFyeVJvd1wiLCBcInN1YlF1ZXN0aW9uXCI6IFtcbiAgICAgICAgICAgIHsgXCJsYWJlbFwiOiBcIlR5cGVcIiwgXCJwbGFjZWhvbGRlclwiOiBcIkVtcGxveWVlIERldGFpbHNcIiwgXCJ0eXBlXCI6IFwidGV4dFwiLCBcInRhcmdldEFycmF5XCI6IFwiZmllbGRzTWV0YVwiLCBcInRhcmdldEFycmF5S2V5XCI6IFwidW5pcXVlSWRlbnRpZmllclwiLCBcImtleVwiOiBcImZsZFR5cGVcIiB9LFxuICAgICAgICAgICAgeyBcImxhYmVsXCI6IFwib3BlcmF0aW9uXCIsIFwicGxhY2Vob2xkZXJcIjogXCJvcGVyYXRpb25cIiwgXCJ0eXBlXCI6IFwidGV4dFwiLCBcInRhcmdldEFycmF5XCI6IFwiZmllbGRzTWV0YVwiLCBcInRhcmdldEFycmF5S2V5XCI6IFwidW5pcXVlSWRlbnRpZmllclwiLCBcImtleVwiOiBcIm9wZXJhdGlvblwiIH0sXG4gICAgICAgICAgICB7IFwibGFiZWxcIjogXCJjb2x1bW5cIiwgXCJwbGFjZWhvbGRlclwiOiBcIkVtcGxveWVlIERldGFpbHNcIiwgXCJ0eXBlXCI6IFwicmFkaW9cIiwgXCJ0YXJnZXRBcnJheVwiOiBcImZpZWxkc01ldGFcIiwgXCJ0YXJnZXRBcnJheUtleVwiOiBcInVuaXF1ZUlkZW50aWZpZXJcIiwgXCJrZXlcIjogXCJjb2x1bW5cIiB9LFxuICAgICAgICAgICAgeyBcImxhYmVsXCI6IFwib3BlcmFuZHNcIiwgXCJwbGFjZWhvbGRlclwiOiBcIkVtcGxveWVlIERldGFpbHNcIiwgXCJ0eXBlXCI6IFwiYXJyYXlcIiwgXCJ0YXJnZXRBcnJheVwiOiBcImZpZWxkc01ldGFcIiwgXCJ0YXJnZXRBcnJheUtleVwiOiBcInVuaXF1ZUlkZW50aWZpZXJcIiwgXCJrZXlcIjogXCJvcGVyYW5kc1wiIH0sXG4gICAgICAgICAgXVxuICAgICAgICB9LFxuXG4gICAgICAgIHsgXCJsYWJlbFwiOiBcImlucHV0VGV4dEFsaWdubWVudFwiLCBcInBsYWNlaG9sZGVyXCI6IFwiTGVmdFwiLCBcInR5cGVcIjogXCJ0ZXh0XCIsIFwia2V5XCI6IFwiaW5wdXRUZXh0QWxpZ25tZW50XCIgfSxcbiAgICAgICAgeyBcImxhYmVsXCI6IFwidGFibGVTY2FsZVNpemVcIiwgXCJwbGFjZWhvbGRlclwiOiBcIjA2IC0gRnVsbCBTY2FsZVwiLCBcInR5cGVcIjogXCJ0ZXh0XCIsIFwia2V5XCI6IFwidGFibGVTY2FsZVNpemVcIiB9LFxuICAgICAgICB7IFwibGFiZWxcIjogXCJyb3dDaG9pY2VcIiwgXCJwbGFjZWhvbGRlclwiOiBcIlwiLCBcInR5cGVcIjogXCJ0ZXh0XCIsIFwia2V5XCI6IFwicm93Q2hvaWNlXCIgfSxcbiAgICAgIF0sXG4gICAgICBcImZpZWxkUHJvcHNcIjogW1xuICAgICAgICB7IFwibGFiZWxcIjogXCJ0YWJsZUlkXCIsIFwicGxhY2Vob2xkZXJcIjogXCJFbXBfVGFibGVfMDFcIiwgXCJ0eXBlXCI6IFwidGV4dFwiLCBcImtleVwiOiBcInRhYmxlSWRcIiB9LFxuICAgICAgICB7IFwibGFiZWxcIjogXCJpbnB1dFRleHRBbGlnbm1lbnRcIiwgXCJwbGFjZWhvbGRlclwiOiBcIkxlZnRcIiwgXCJ0eXBlXCI6IFwidGV4dFwiLCBcImtleVwiOiBcImlucHV0VGV4dEFsaWdubWVudFwiIH0sXG4gICAgICAgIHsgXCJsYWJlbFwiOiBcImhlbHBUZXh0XCIsIFwicGxhY2Vob2xkZXJcIjogXCJFbnRlciBoZWxwIG1lc3NhZ2UgaGVyZVwiLCBcInR5cGVcIjogXCJ0ZXh0XCIsIFwia2V5XCI6IFwiaGVscFRleHRcIiB9LFxuICAgICAgICB7IFwibGFiZWxcIjogXCJkZWZhdWx0VmFsdWVcIiwgXCJwbGFjZWhvbGRlclwiOiBcIkRlZmF1bHQgVmFsdWVcIiwgXCJ0eXBlXCI6IFwidGV4dFwiLCBcImtleVwiOiBcImRlZmF1bHRWYWx1ZVwiIH0sXG4gICAgICAgIHsgXCJsYWJlbFwiOiBcInJlZmVyZW5jZUFuY2hvclwiLCBcInBsYWNlaG9sZGVyXCI6IFwiaHR0cDovL3NvdXJjZS9yYW5nZXJueHRfYmlvX2RhdGEvNzQvZC5kb2NcIiwgXCJ0eXBlXCI6IFwidGV4dFwiLCBcImtleVwiOiBcInJlZmVyZW5jZUFuY2hvclwiIH0sXG4gICAgICBdLFxuICAgICAgXCJhcHBlYXJhbmNlXCI6IFtcbiAgICAgICAge1xuICAgICAgICAgIGxhYmVsOiAnU2VsZWN0IEZvbnQnLCB0eXBlOiAnc2VsZWN0Jywga2V5OiAnZm9udCcsIHBsYWNlaG9sZGVyOiAnTGVmdCcsIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgIG9wdGlvbnM6IFsnSGVsdmV0aWNhIE5ldWUnLCAnQXJpYWwnLCAnVGltZXMgTmV3IFJvbWFuJywgJ1JvYm90byddXG4gICAgICAgIH0sXG4gICAgICAgIHsgbGFiZWw6ICdGb250IENvbG9yJywgdHlwZTogJ2NvbG9yJywga2V5OiAnZm9udENvbG9yJywgZGVmYXVsdFZhbHVlOiAnJywgcmVxdWlyZWQ6IHRydWUgfSxcbiAgICAgICAge1xuICAgICAgICAgIGxhYmVsOiAnRm9udCBTaXplJywgdHlwZTogJ3NlbGVjdCcsIGtleTogJ2ZvbnRTaXplJywgZGVmYXVsdFZhbHVlOiAnJywgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgb3B0aW9uczogW1xuICAgICAgICAgICAgeyBsYWJlbDogJ1NtYWxsJywgdmFsdWU6ICcxMnB4JyB9LFxuICAgICAgICAgICAgeyBsYWJlbDogJ01lZGl1bScsIHZhbHVlOiAnMTRweCcgfSxcbiAgICAgICAgICAgIHsgbGFiZWw6ICdMYXJnZScsIHZhbHVlOiAnMTZweCcgfVxuICAgICAgICAgIF1cbiAgICAgICAgfSxcblxuICAgICAgICB7XG4gICAgICAgICAgbGFiZWw6ICdGb250IFdpZHRoJywgdHlwZTogJ3NlbGVjdCcsIGtleTogJ2ZvbnRXZWlnaHQnLCBkZWZhdWx0VmFsdWU6ICcnLCByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICBvcHRpb25zOiBbXG4gICAgICAgICAgICB7IHZhbHVlOiAnNDAwJywgbGFiZWw6ICc0MDAtTm9ybWFsJyB9LFxuICAgICAgICAgICAgeyB2YWx1ZTogJzUwMCcsIGxhYmVsOiAnNTAwLU1lZGl1bScgfSxcbiAgICAgICAgICAgIHsgdmFsdWU6ICc2MDAnLCBsYWJlbDogJzYwMC1TZW1pIEJvbGQnIH0sXG4gICAgICAgICAgICB7IHZhbHVlOiAnNzAwJywgbGFiZWw6ICc3MDAtQm9sZCcgfVxuICAgICAgICAgIF1cbiAgICAgICAgfSxcbiAgICAgICAgeyBsYWJlbDogJ0R1cGxpY2F0ZSBGaWVsZCcsIHR5cGU6ICdidXR0b24tdG9nZ2xlJywga2V5OiAnZHVwbGljYXRlRmllbGQnLCBkZWZhdWx0VmFsdWU6IGZhbHNlIH1cbiAgICAgIF1cbiAgICB9LFxuXG4gICAgTGlzdENvbHVtbjogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKHtcbiAgICAgIGN1c3RvbUZpZWxkUHJvcHM6IFtcbiAgICAgICAgLi4uQ09NTU9OX09QVElPTlNfRklFTEQubWFwKG9wdCA9PiAoe1xuICAgICAgICAgIHR5cGU6ICdsaXN0J1xuICAgICAgICB9KSksXG4gICAgICBdLFxuICAgICAgY3VzdG9tRWxlbWVudFByb3BzOltcbiAgICAgICAgeyBsYWJlbDogXCJoZWFkZXJMYWJlbHNcIiwgcGxhY2Vob2xkZXI6IFwiRW1wbG95ZWUgRGV0YWlsc1wiLCB0eXBlOiBcInRleHRcIiwgdGFyZ2V0QXJyYXk6IFwiZmllbGRzTWV0YVwiLCB0YXJnZXRBcnJheUtleTogXCJ1bmlxdWVJZGVudGlmaWVyXCIsIGtleTogXCJsYWJlbFwiIH0sXG4gICAgICAgIHsgbGFiZWw6IFwiYXBpTmFtZVwiLCBwbGFjZWhvbGRlcjogXCJFbXBsb3llZSBEZXRhaWxzXCIsIHR5cGU6IFwidGV4dFwiLCB0YXJnZXRBcnJheTogXCJmaWVsZHNNZXRhXCIsIHRhcmdldEFycmF5S2V5OiBcInVuaXF1ZUlkZW50aWZpZXJcIiwga2V5OiBcImFwaU5hbWVcIiB9LFxuICAgIFxuICAgICAgICB7XG4gICAgICAgICAgbGFiZWw6IFwiU3VtbWFyeSBDb2x1bW5cIiwgcGxhY2Vob2xkZXI6IFwiU3VtbWFyeSBDb2x1bW5cIiwgdHlwZTogXCJzdWJRdWVzdGlvblwiLCB0YXJnZXRBcnJheTogXCJmaWVsZHNNZXRhXCIsIHRhcmdldEFycmF5S2V5OiBcInVuaXF1ZUlkZW50aWZpZXJcIiwga2V5OiBcInN1bW1hcnlDb2x1bW5cIixcbiAgICAgICAgICBzdWJRdWVzdGlvbjogW1xuICAgICAgICAgICAgeyBsYWJlbDogXCJUeXBlXCIsIHBsYWNlaG9sZGVyOiBcIkVtcGxveWVlIERldGFpbHNcIiwgdHlwZTogXCJ0ZXh0XCIsIHRhcmdldEFycmF5OiBcImZpZWxkc01ldGFcIiwgdGFyZ2V0QXJyYXlLZXk6IFwidW5pcXVlSWRlbnRpZmllclwiLCBrZXk6IFwiZmxkVHlwZVwiIH0sXG4gICAgICAgICAgICB7IGxhYmVsOiBcIk9wZXJhdGlvblwiLCBwbGFjZWhvbGRlcjogXCJFbXBsb3llZSBEZXRhaWxzXCIsIHR5cGU6IFwidGV4dFwiLCB0YXJnZXRBcnJheTogXCJmaWVsZHNNZXRhXCIsIHRhcmdldEFycmF5S2V5OiBcInVuaXF1ZUlkZW50aWZpZXJcIiwga2V5OiBcIm9wZXJhdGlvblwiIH0sXG4gICAgICAgICAgICB7IGxhYmVsOiBcIk9wZXJhbmRzXCIsIHBsYWNlaG9sZGVyOiBcIkVtcGxveWVlIERldGFpbHNcIiwgdHlwZTogXCJhcnJheVwiLCB0YXJnZXRBcnJheTogXCJmaWVsZHNNZXRhXCIsIHRhcmdldEFycmF5S2V5OiBcInVuaXF1ZUlkZW50aWZpZXJcIiwga2V5OiBcIm9wZXJhbmRzXCIgfSxcbiAgICAgICAgICBdXG4gICAgICAgIH0sXG4gICAgXG4gICAgICAgIHtcbiAgICAgICAgICBsYWJlbDogXCJTdW1tYXJ5IFJvd1wiLCBwbGFjZWhvbGRlcjogXCJTdW1tYXJ5IFJvd1wiLCB0eXBlOiBcInN1YlF1ZXN0aW9uXCIsIHRhcmdldEFycmF5OiBcImZpZWxkc01ldGFcIiwgdGFyZ2V0QXJyYXlLZXk6IFwidW5pcXVlSWRlbnRpZmllclwiLCBrZXk6IFwic3VtbWFyeVJvd1wiLFxuICAgICAgICAgIHN1YlF1ZXN0aW9uOiBbXG4gICAgICAgICAgICB7IGxhYmVsOiBcIlR5cGVcIiwgcGxhY2Vob2xkZXI6IFwiRW1wbG95ZWUgRGV0YWlsc1wiLCB0eXBlOiBcInRleHRcIiwgdGFyZ2V0QXJyYXk6IFwiZmllbGRzTWV0YVwiLCB0YXJnZXRBcnJheUtleTogXCJ1bmlxdWVJZGVudGlmaWVyXCIsIGtleTogXCJmbGRUeXBlXCIgfSxcbiAgICAgICAgICAgIHsgbGFiZWw6IFwib3BlcmF0aW9uXCIsIHBsYWNlaG9sZGVyOiBcIm9wZXJhdGlvblwiLCB0eXBlOiBcInRleHRcIiwgdGFyZ2V0QXJyYXk6IFwiZmllbGRzTWV0YVwiLCB0YXJnZXRBcnJheUtleTogXCJ1bmlxdWVJZGVudGlmaWVyXCIsIGtleTogXCJvcGVyYXRpb25cIiB9LFxuICAgICAgICAgICAgeyBsYWJlbDogXCJjb2x1bW5cIiwgcGxhY2Vob2xkZXI6IFwiRW1wbG95ZWUgRGV0YWlsc1wiLCB0eXBlOiBcInJhZGlvXCIsIHRhcmdldEFycmF5OiBcImZpZWxkc01ldGFcIiwgdGFyZ2V0QXJyYXlLZXk6IFwidW5pcXVlSWRlbnRpZmllclwiLCBrZXk6IFwiY29sdW1uXCIgfSxcbiAgICAgICAgICAgIHsgbGFiZWw6IFwib3BlcmFuZHNcIiwgcGxhY2Vob2xkZXI6IFwiRW1wbG95ZWUgRGV0YWlsc1wiLCB0eXBlOiBcImFycmF5XCIsIHRhcmdldEFycmF5OiBcImZpZWxkc01ldGFcIiwgdGFyZ2V0QXJyYXlLZXk6IFwidW5pcXVlSWRlbnRpZmllclwiLCBrZXk6IFwib3BlcmFuZHNcIiB9LFxuICAgICAgICAgIF1cbiAgICAgICAgfSxcbiAgICAgIF1cbiAgICB9KSwgICAgXG5cbiAgICBEcm9wZG93bkNvbHVtbjogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKHtcbiAgICAgIGN1c3RvbUZpZWxkUHJvcHM6IFtcblxuICAgICAgICAuLi5DT01NT05fT1BUSU9OU19GSUVMRC5tYXAob3B0ID0+ICh7XG4gICAgICAgICAgLi4ub3B0LFxuICAgICAgICAgIHR5cGU6ICdkcm9wZG93bidcbiAgICAgICAgfSkpLFxuICAgICAgXSxcbiAgICAgICAgY3VzdG9tRWxlbWVudFByb3BzOltcbiAgICAgICAgeyBsYWJlbDogXCJoZWFkZXJMYWJlbHNcIiwgcGxhY2Vob2xkZXI6IFwiRW1wbG95ZWUgRGV0YWlsc1wiLCB0eXBlOiBcInRleHRcIiwgdGFyZ2V0QXJyYXk6IFwiZmllbGRzTWV0YVwiLCB0YXJnZXRBcnJheUtleTogXCJ1bmlxdWVJZGVudGlmaWVyXCIsIGtleTogXCJsYWJlbFwiIH0sXG4gICAgICAgIHsgbGFiZWw6IFwiYXBpTmFtZVwiLCBwbGFjZWhvbGRlcjogXCJFbXBsb3llZSBEZXRhaWxzXCIsIHR5cGU6IFwidGV4dFwiLCB0YXJnZXRBcnJheTogXCJmaWVsZHNNZXRhXCIsIHRhcmdldEFycmF5S2V5OiBcInVuaXF1ZUlkZW50aWZpZXJcIiwga2V5OiBcImFwaU5hbWVcIiB9LFxuICAgIFxuICAgICAgICB7XG4gICAgICAgICAgbGFiZWw6IFwiU3VtbWFyeSBDb2x1bW5cIiwgcGxhY2Vob2xkZXI6IFwiU3VtbWFyeSBDb2x1bW5cIiwgdHlwZTogXCJzdWJRdWVzdGlvblwiLCB0YXJnZXRBcnJheTogXCJmaWVsZHNNZXRhXCIsIHRhcmdldEFycmF5S2V5OiBcInVuaXF1ZUlkZW50aWZpZXJcIiwga2V5OiBcInN1bW1hcnlDb2x1bW5cIixcbiAgICAgICAgICBzdWJRdWVzdGlvbjogW1xuICAgICAgICAgICAgeyBsYWJlbDogXCJUeXBlXCIsIHBsYWNlaG9sZGVyOiBcIkVtcGxveWVlIERldGFpbHNcIiwgdHlwZTogXCJ0ZXh0XCIsIHRhcmdldEFycmF5OiBcImZpZWxkc01ldGFcIiwgdGFyZ2V0QXJyYXlLZXk6IFwidW5pcXVlSWRlbnRpZmllclwiLCBrZXk6IFwiZmxkVHlwZVwiIH0sXG4gICAgICAgICAgICB7IGxhYmVsOiBcIk9wZXJhdGlvblwiLCBwbGFjZWhvbGRlcjogXCJFbXBsb3llZSBEZXRhaWxzXCIsIHR5cGU6IFwidGV4dFwiLCB0YXJnZXRBcnJheTogXCJmaWVsZHNNZXRhXCIsIHRhcmdldEFycmF5S2V5OiBcInVuaXF1ZUlkZW50aWZpZXJcIiwga2V5OiBcIm9wZXJhdGlvblwiIH0sXG4gICAgICAgICAgICB7IGxhYmVsOiBcIk9wZXJhbmRzXCIsIHBsYWNlaG9sZGVyOiBcIkVtcGxveWVlIERldGFpbHNcIiwgdHlwZTogXCJhcnJheVwiLCB0YXJnZXRBcnJheTogXCJmaWVsZHNNZXRhXCIsIHRhcmdldEFycmF5S2V5OiBcInVuaXF1ZUlkZW50aWZpZXJcIiwga2V5OiBcIm9wZXJhbmRzXCIgfSxcbiAgICAgICAgICBdXG4gICAgICAgIH0sXG4gICAgXG4gICAgICAgIHtcbiAgICAgICAgICBsYWJlbDogXCJTdW1tYXJ5IFJvd1wiLCBwbGFjZWhvbGRlcjogXCJTdW1tYXJ5IFJvd1wiLCB0eXBlOiBcInN1YlF1ZXN0aW9uXCIsIHRhcmdldEFycmF5OiBcImZpZWxkc01ldGFcIiwgdGFyZ2V0QXJyYXlLZXk6IFwidW5pcXVlSWRlbnRpZmllclwiLCBrZXk6IFwic3VtbWFyeVJvd1wiLFxuICAgICAgICAgIHN1YlF1ZXN0aW9uOiBbXG4gICAgICAgICAgICB7IGxhYmVsOiBcIlR5cGVcIiwgcGxhY2Vob2xkZXI6IFwiRW1wbG95ZWUgRGV0YWlsc1wiLCB0eXBlOiBcInRleHRcIiwgdGFyZ2V0QXJyYXk6IFwiZmllbGRzTWV0YVwiLCB0YXJnZXRBcnJheUtleTogXCJ1bmlxdWVJZGVudGlmaWVyXCIsIGtleTogXCJmbGRUeXBlXCIgfSxcbiAgICAgICAgICAgIHsgbGFiZWw6IFwib3BlcmF0aW9uXCIsIHBsYWNlaG9sZGVyOiBcIm9wZXJhdGlvblwiLCB0eXBlOiBcInRleHRcIiwgdGFyZ2V0QXJyYXk6IFwiZmllbGRzTWV0YVwiLCB0YXJnZXRBcnJheUtleTogXCJ1bmlxdWVJZGVudGlmaWVyXCIsIGtleTogXCJvcGVyYXRpb25cIiB9LFxuICAgICAgICAgICAgeyBsYWJlbDogXCJjb2x1bW5cIiwgcGxhY2Vob2xkZXI6IFwiRW1wbG95ZWUgRGV0YWlsc1wiLCB0eXBlOiBcInJhZGlvXCIsIHRhcmdldEFycmF5OiBcImZpZWxkc01ldGFcIiwgdGFyZ2V0QXJyYXlLZXk6IFwidW5pcXVlSWRlbnRpZmllclwiLCBrZXk6IFwiY29sdW1uXCIgfSxcbiAgICAgICAgICAgIHsgbGFiZWw6IFwib3BlcmFuZHNcIiwgcGxhY2Vob2xkZXI6IFwiRW1wbG95ZWUgRGV0YWlsc1wiLCB0eXBlOiBcImFycmF5XCIsIHRhcmdldEFycmF5OiBcImZpZWxkc01ldGFcIiwgdGFyZ2V0QXJyYXlLZXk6IFwidW5pcXVlSWRlbnRpZmllclwiLCBrZXk6IFwib3BlcmFuZHNcIiB9LFxuICAgICAgICAgIF1cbiAgICAgICAgfSxcbiAgICAgIF1cbiAgICB9KSwgICAgXG5cbiAgICBEYXRlQ29sdW1uOiB0aGlzLmNyZWF0ZUVsZW1lbnRDb25maWcoe1xuICAgICAgY3VzdG9tRmllbGRQcm9wczogW1xuICAgICAgICAuLi5DT01NT05fT1BUSU9OU19GSUVMRC5tYXAob3B0ID0+ICh7XG4gICAgICAgICAgdHlwZTogJ2RhdGUnXG4gICAgICAgIH0pKSxcbiAgICAgIF0sXG4gICAgICBjdXN0b21FbGVtZW50UHJvcHM6W1xuICAgICAgICB7IGxhYmVsOiBcImhlYWRlckxhYmVsc1wiLCBwbGFjZWhvbGRlcjogXCJFbXBsb3llZSBEZXRhaWxzXCIsIHR5cGU6IFwidGV4dFwiLCB0YXJnZXRBcnJheTogXCJmaWVsZHNNZXRhXCIsIHRhcmdldEFycmF5S2V5OiBcInVuaXF1ZUlkZW50aWZpZXJcIiwga2V5OiBcImxhYmVsXCIgfSxcbiAgICAgICAgeyBsYWJlbDogXCJhcGlOYW1lXCIsIHBsYWNlaG9sZGVyOiBcIkVtcGxveWVlIERldGFpbHNcIiwgdHlwZTogXCJ0ZXh0XCIsIHRhcmdldEFycmF5OiBcImZpZWxkc01ldGFcIiwgdGFyZ2V0QXJyYXlLZXk6IFwidW5pcXVlSWRlbnRpZmllclwiLCBrZXk6IFwiYXBpTmFtZVwiIH0sXG4gICAgXG4gICAgICAgIHtcbiAgICAgICAgICBsYWJlbDogXCJTdW1tYXJ5IENvbHVtblwiLCBwbGFjZWhvbGRlcjogXCJTdW1tYXJ5IENvbHVtblwiLCB0eXBlOiBcInN1YlF1ZXN0aW9uXCIsIHRhcmdldEFycmF5OiBcImZpZWxkc01ldGFcIiwgdGFyZ2V0QXJyYXlLZXk6IFwidW5pcXVlSWRlbnRpZmllclwiLCBrZXk6IFwic3VtbWFyeUNvbHVtblwiLFxuICAgICAgICAgIHN1YlF1ZXN0aW9uOiBbXG4gICAgICAgICAgICB7IGxhYmVsOiBcIlR5cGVcIiwgcGxhY2Vob2xkZXI6IFwiRW1wbG95ZWUgRGV0YWlsc1wiLCB0eXBlOiBcInRleHRcIiwgdGFyZ2V0QXJyYXk6IFwiZmllbGRzTWV0YVwiLCB0YXJnZXRBcnJheUtleTogXCJ1bmlxdWVJZGVudGlmaWVyXCIsIGtleTogXCJmbGRUeXBlXCIgfSxcbiAgICAgICAgICAgIHsgbGFiZWw6IFwiT3BlcmF0aW9uXCIsIHBsYWNlaG9sZGVyOiBcIkVtcGxveWVlIERldGFpbHNcIiwgdHlwZTogXCJ0ZXh0XCIsIHRhcmdldEFycmF5OiBcImZpZWxkc01ldGFcIiwgdGFyZ2V0QXJyYXlLZXk6IFwidW5pcXVlSWRlbnRpZmllclwiLCBrZXk6IFwib3BlcmF0aW9uXCIgfSxcbiAgICAgICAgICAgIHsgbGFiZWw6IFwiT3BlcmFuZHNcIiwgcGxhY2Vob2xkZXI6IFwiRW1wbG95ZWUgRGV0YWlsc1wiLCB0eXBlOiBcImFycmF5XCIsIHRhcmdldEFycmF5OiBcImZpZWxkc01ldGFcIiwgdGFyZ2V0QXJyYXlLZXk6IFwidW5pcXVlSWRlbnRpZmllclwiLCBrZXk6IFwib3BlcmFuZHNcIiB9LFxuICAgICAgICAgIF1cbiAgICAgICAgfSxcbiAgICBcbiAgICAgICAge1xuICAgICAgICAgIGxhYmVsOiBcIlN1bW1hcnkgUm93XCIsIHBsYWNlaG9sZGVyOiBcIlN1bW1hcnkgUm93XCIsIHR5cGU6IFwic3ViUXVlc3Rpb25cIiwgdGFyZ2V0QXJyYXk6IFwiZmllbGRzTWV0YVwiLCB0YXJnZXRBcnJheUtleTogXCJ1bmlxdWVJZGVudGlmaWVyXCIsIGtleTogXCJzdW1tYXJ5Um93XCIsXG4gICAgICAgICAgc3ViUXVlc3Rpb246IFtcbiAgICAgICAgICAgIHsgbGFiZWw6IFwiVHlwZVwiLCBwbGFjZWhvbGRlcjogXCJFbXBsb3llZSBEZXRhaWxzXCIsIHR5cGU6IFwidGV4dFwiLCB0YXJnZXRBcnJheTogXCJmaWVsZHNNZXRhXCIsIHRhcmdldEFycmF5S2V5OiBcInVuaXF1ZUlkZW50aWZpZXJcIiwga2V5OiBcImZsZFR5cGVcIiB9LFxuICAgICAgICAgICAgeyBsYWJlbDogXCJvcGVyYXRpb25cIiwgcGxhY2Vob2xkZXI6IFwib3BlcmF0aW9uXCIsIHR5cGU6IFwidGV4dFwiLCB0YXJnZXRBcnJheTogXCJmaWVsZHNNZXRhXCIsIHRhcmdldEFycmF5S2V5OiBcInVuaXF1ZUlkZW50aWZpZXJcIiwga2V5OiBcIm9wZXJhdGlvblwiIH0sXG4gICAgICAgICAgICB7IGxhYmVsOiBcImNvbHVtblwiLCBwbGFjZWhvbGRlcjogXCJFbXBsb3llZSBEZXRhaWxzXCIsIHR5cGU6IFwicmFkaW9cIiwgdGFyZ2V0QXJyYXk6IFwiZmllbGRzTWV0YVwiLCB0YXJnZXRBcnJheUtleTogXCJ1bmlxdWVJZGVudGlmaWVyXCIsIGtleTogXCJjb2x1bW5cIiB9LFxuICAgICAgICAgICAgeyBsYWJlbDogXCJvcGVyYW5kc1wiLCBwbGFjZWhvbGRlcjogXCJFbXBsb3llZSBEZXRhaWxzXCIsIHR5cGU6IFwiYXJyYXlcIiwgdGFyZ2V0QXJyYXk6IFwiZmllbGRzTWV0YVwiLCB0YXJnZXRBcnJheUtleTogXCJ1bmlxdWVJZGVudGlmaWVyXCIsIGtleTogXCJvcGVyYW5kc1wiIH0sXG4gICAgICAgICAgXVxuICAgICAgICB9LFxuICAgICAgXVxuICAgIH0pLCAgICBcblxuICAgIENoZWNrYm94OiB0aGlzLmNyZWF0ZUVsZW1lbnRDb25maWcoe1xuICAgICAgY3VzdG9tRmllbGRQcm9wczogQ09NTU9OX09QVElPTlNfRklFTEQubWFwKG9wdCA9PiAoe1xuICAgICAgICAuLi5vcHQsXG4gICAgICAgIHR5cGU6ICdjaGVja2JveCdcbiAgICAgIH0pKVxuICAgIH0pLFxuICBcbiAgICBEcm9wZG93bjogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKHtcbiAgICAgIGN1c3RvbUZpZWxkUHJvcHM6IENPTU1PTl9PUFRJT05TX0ZJRUxELm1hcChvcHQgPT4gKHtcbiAgICAgICAgLi4ub3B0LFxuICAgICAgICB0eXBlOiAnZHJvcGRvd24nXG4gICAgICB9KSlcbiAgICB9KSxcbiAgXG4gICAgUmFkaW86IHRoaXMuY3JlYXRlRWxlbWVudENvbmZpZyh7XG4gICAgICBjdXN0b21GaWVsZFByb3BzOiBDT01NT05fT1BUSU9OU19GSUVMRC5tYXAob3B0ID0+ICh7XG4gICAgICAgIC4uLm9wdCxcbiAgICAgICAgdHlwZTogJ2NoZWNrYm94J1xuICAgICAgfSkpXG4gICAgfSksXG5cbiAgICBUZXh0OiB0aGlzLmNyZWF0ZUVsZW1lbnRDb25maWcoKSxcblxuICAgIENhbGVuZGFyOiB0aGlzLmNyZWF0ZUVsZW1lbnRDb25maWcoKSxcblxuICAgIERhdGU6IHRoaXMuY3JlYXRlRWxlbWVudENvbmZpZygpLFxuXG4gICAgVGltZTogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKCksXG5cbiAgICBEYXRlVGltZTogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKCksXG5cbiAgICBFbWFpbDogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKCksXG5cbiAgICBCb29rOiB0aGlzLmNyZWF0ZUVsZW1lbnRDb25maWcoKSxcbiAgICBcbiAgICBMaXN0OiB0aGlzLmNyZWF0ZUVsZW1lbnRDb25maWcoKSxcblxuICAgIFRleHRBcmVhOiB0aGlzLmNyZWF0ZUVsZW1lbnRDb25maWcoKSxcblxuICAgIFJpY2hUZXh0QXJlYTogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKCksXG4gICAgXG4gICAgTnVtYmVyOiB0aGlzLmNyZWF0ZUVsZW1lbnRDb25maWcoKSxcblxuICAgIEltYWdlOiB0aGlzLmNyZWF0ZUVsZW1lbnRDb25maWcoKSxcblxuICAgIExhYmVsOiB0aGlzLmNyZWF0ZUVsZW1lbnRDb25maWcoKSxcblxuICAgIEJvb2xlYW46IHRoaXMuY3JlYXRlRWxlbWVudENvbmZpZygpLFxuXG4gICAgRmlsZTogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKCksXG5cbiAgICBJY29uOiB0aGlzLmNyZWF0ZUVsZW1lbnRDb25maWcoKSwgLy9NU00xMEpVTDI1IGljb24gc2VsZWN0b3IgZWxlbWVudFxuICB9O1xuICBcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGh0dHA6IEh0dHBDbGllbnQsIHByaXZhdGUgZm9ybUJ1aWxkZXJTZXJ2aWNlOiBGb3JtQnVpbGRlclNlcnZpY2UscHJpdmF0ZSB0ZW1wbGF0ZVNlcnZpY2U6IFRlbXBsYXRlU2VydmljZSkgeyB9XG5cbiAgaGFuZGxlVGVtcGxhdGVTZWxlY3Rpb24oZXZlbnQ6IGFueSkge1xuICAgIHRoaXMuZm9ybUVsZW1lbnRzID0gZXZlbnQuZWxlbWVudHM7IFxuICAgIHRoaXMuc2VsZWN0ZWRUZW1wbGF0ZSA9IGV2ZW50LnNlbGVjdGVkVGVtcGxhdGU7XG4gICAgdGhpcy50ZW1wbGF0ZVNlcnZpY2UuZm9ybUVsZW1lbnRzID0gdGhpcy5mb3JtRWxlbWVudHM7XG4gICAgdGhpcy50ZW1wbGF0ZVNlcnZpY2UuYm9vayA9IHRoaXMuYm9vaztcbiAgICB0aGlzLnRlbXBsYXRlU2VydmljZS51bmlxdWVfaWQgPSB0aGlzLnVuaXF1ZV9pZDtcbiAgfVxuICBkdXBsaWNhdGVGaWVsZChlbGVtZW50OiBhbnkpIHtcbiAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLmdldEVsZW1lbnRzKCk7XG4gICAgY29uc3QgY29weSA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoZWxlbWVudCkpO1xuICAgIC8vQVAtMThBUFIyNSBHZW5lcmF0ZSBhIG5ldyBJRCB1c2luZyB0aGUgc2VydmljZSdzIG1ldGhvZFxuICAgIGNvcHkuaWQgPSB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5hZGRFbGVtZW50V2l0aElkKCk7XG4gICAgLy9jb3B5LnV1aWQgPSBjb3B5LmlkOyBcbiAgICAvLyBBUC0xOEFQUjI1IFNldCB0aGUgcXVlc3Rpb25OdW1iZXIgdG8gdGhlIG5leHQgYXZhaWxhYmxlIG51bWJlclxuICAgIGNvcHkucXVlc3Rpb25OdW1iZXIgPSBlbGVtZW50cy5sZW5ndGggKyAxO1xuICAgIHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLmFkZEVsZW1lbnQoY29weSk7XG4gIH1cbiAgXG4gIHNhdmVEYXRhKCkge1xuICAgIHRoaXMudGVtcGxhdGVTZXJ2aWNlLmZvcm1FbGVtZW50cyA9IHRoaXMuZm9ybUVsZW1lbnRzO1xuICAgIHRoaXMudGVtcGxhdGVTZXJ2aWNlLmJvb2sgPSB0aGlzLmJvb2s7XG4gICAgdGhpcy50ZW1wbGF0ZVNlcnZpY2UudW5pcXVlX2lkID0gdGhpcy51bmlxdWVfaWQ7XG4gICAgY29uc3QgdXBkYXRlZEJvb2sgPSB0aGlzLnRlbXBsYXRlU2VydmljZS5kb3dubG9hZCgpO1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgLy9BUC0xME1BUjI1IFN1YnNjcmliZXMgdG8gaGVhZGVyIHNlbGVjdGlvbiBjaGFuZ2VzIGFuZCB1cGRhdGVzIHRoZSBzZWxlY3RlZCBlbGVtZW50ICBcbiAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5zZWxlY3RIZWFkZXJTdWJqZWN0JC5zdWJzY3JpYmUoaGVhZGVyID0+IHtcbiAgICAgIGlmIChoZWFkZXIpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNlbGVjdGVkRWxlbWVudCkge1xuICAgICAgICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50ID0ge307XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZWxlY3RlZEVsZW1lbnRbJ3R5cGUnXSA9IGhlYWRlcjtcbiAgICAgICAgdGhpcy5oZWFkZXJTZWxlY3QgPSB0cnVlO1xuICAgICAgICB0aGlzLmJvb2sgPSB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5nZXRCb29rKCk7XG4gICAgICAgIHRoaXMuYm9va0lkID0gdGhpcy5ib29rLnJlY29yZHNbMF0uaWQ7XG4gICAgICB9XG5cbiAgICB9KTtcbiAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5zZWxlY3RlZEVsZW1lbnQkLnN1YnNjcmliZShpbmRleCA9PiB7XG4gICAgICB0aGlzLnNlbGVjdGVkRWxlbWVudEluZGV4ID0gaW5kZXg7XG4gICAgICB0aGlzLmhlYWRlclNlbGVjdCA9IGZhbHNlO1xuICAgICAgaWYgKGluZGV4ID49IDApIHtcbiAgICAgICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5nZXRFbGVtZW50cygpO1xuICAgICAgICB0aGlzLnNlbGVjdGVkRWxlbWVudCA9IGVsZW1lbnRzW2luZGV4XTtcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRFbGVtZW50Py50eXBlID09PSAnVGFibGUnKSB7XG4gICAgICAgICAgdGhpcy5zZWxlY3RlZEVsZW1lbnRbJ2ZpZWxkc01ldGEnXSA9IHR5cGVvZiB0aGlzLnNlbGVjdGVkRWxlbWVudC5maWVsZHNNZXRhID09PSAnb2JqZWN0JyA/IHRoaXMuc2VsZWN0ZWRFbGVtZW50LmZpZWxkc01ldGEgOiBKU09OLnBhcnNlKHRoaXMuc2VsZWN0ZWRFbGVtZW50WydmaWVsZHNNZXRhJ10gfHwgW10pO1xuICAgICAgICAgIHRoaXMuc2VsZWN0Q29sdW1uID0gdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UuZ2V0U2VsZWN0VGFibGVDb2x1bW4oKSA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLmdldFNlbGVjdFRhYmxlQ29sdW1uKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5zZWxlY3RDb2x1bW4gPSBudWxsXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuZ2V0UHJvcGVydGllcygpXG4gICAgfSk7XG4gICAgdGhpcy5mb3JtQnVpbGRlclNlcnZpY2Uuc2VsZWN0SGVhZGVyU3ViamVjdCQuc3Vic2NyaWJlKGFjdGlvbiA9PiB7XG4gICAgICBpZiAoYWN0aW9uKSB7XG4gICAgICAgIHRoaXMuYm9vayA9IHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLmdldEJvb2soKTtcbiAgICAgIH1cblxuICAgIH0pO1xuICAgICBpZiAodGhpcy5mcm9tID09PSAnZm9ybUJ1aWxkZXInKSB7XG4gICAgY29uc3QgZmllbGRzTWV0YSA9IHR5cGVvZiB0aGlzLmVsZW1lbnQuZmllbGRzTWV0YSA9PT0gJ3N0cmluZydcbiAgICAgID8gSlNPTi5wYXJzZSh0aGlzLmVsZW1lbnQuZmllbGRzTWV0YSlcbiAgICAgIDogdGhpcy5lbGVtZW50LmZpZWxkc01ldGE7XG5cbiAgICB0aGlzLmNvbHVtbnMgPSBmaWVsZHNNZXRhLm1hcChjb2x1bW4gPT4gKHtcbiAgICAgIC4uLmNvbHVtbixcbiAgICAgIHR5cGU6IGNvbHVtbi5mbGRUeXBlIHx8ICdUZXh0JyAvLyBEZWZhdWx0IHRvICdUZXh0JyBpZiBmbGRUeXBlIG5vdCBhdmFpbGFibGVcbiAgICB9KSk7XG4gIH1cbiAgfVxuXG4gIC8vIEFQIDIzTUFZMjUgLSBBZGQgYSBuZXcgYnV0dG9uIHdpdGggZGVmYXVsdCBzdHlsaW5nXG4gIGFkZE5ld0J1dHRvbigpOiB2b2lkIHtcbiAgICBjb25zdCBsYXN0UGVyY2VudCA9IHRoaXMuYm9vaz8ucXVlc3Rpb25ib29rPy5hY3Rpb24/LnNsaWNlKC0xKVswXT8ucG9zaXRpb25QZXJjZW50IHx8IDA7XG4gICAgY29uc3QgYnV0dG9ucyA9IHtcbiAgICAgIG5hbWU6ICcnLFxuICAgICAgZXZlbnR0b2VtaXQ6ICcnLFxuICAgICAgYWx0OiAnJyxcbiAgICAgIGVuZHBvaW50OiAnJyxcbiAgICAgIG1ldGhvZDogJycsXG4gICAgICBpZDogdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UuYWRkRWxlbWVudFdpdGhJZCgpLFxuICAgICAgcG9zaXRpb25QZXJjZW50OiBsYXN0UGVyY2VudCArIDEwLCAgXG4gICAgICB3aWR0aDogMTAwLFxuICAgICAgYm9yZGVyUmFkaXVzOiA2LFxuICAgICAgYWxpZ25tZW50OiAnZmxleC1zdGFydCdcbiAgICB9O1xuICAgIHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLnVwZGF0ZVF1ZXN0aW9uQm9va0FjdGlvbkJ1dHRvbnMoYnV0dG9ucywgJ2FkZCcpO1xuICB9XG4gIFxuIC8vQVAgMjNNQVkyNSAtIFJlbW92ZSBhIGJ1dHRvbiBmcm9tIHRoZSBhY3Rpb24gbGlzdFxuICByZW1vdmVCdXR0b24oYnRuOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS51cGRhdGVRdWVzdGlvbkJvb2tBY3Rpb25CdXR0b25zKGJ0biwncmVtb3ZlJyk7XG4gIH1cbiAgLy9BUCAyM01BWTI1IC0gVXBkYXRlIGEgc3BlY2lmaWMgcHJvcGVydHkgb2YgYSBidXR0b25cbiAgb25CdXR0b25Qcm9wZXJ0eUNoYW5nZShpbmRleDogbnVtYmVyLCBrZXk6IHN0cmluZywgdmFsdWU6IGFueSk6IHZvaWQge1xuICAgIGNvbnN0IGJ1dHRvbnMgPSB0aGlzLmdldFZhbHVlQnlQYXRoKCdhY3Rpb24nKSB8fCBbXTtcbiAgICBpZiAoYnV0dG9uc1tpbmRleF0pIHtcbiAgICAgIGJ1dHRvbnNbaW5kZXhdW2tleV0gPSB2YWx1ZTtcbiAgICAgIHRoaXMuc2V0VmFsdWVCeVBhdGgoJ2FjdGlvbicsIGJ1dHRvbnMpOyBcbiAgICB9XG4gIH1cbiAgLy9BUC0xME1BUjI1IFVwZGF0ZXMgdGhlIHRpdGxlIHVzaW5nIHRoZSBmb3JtIGJ1aWxkZXIgc2VydmljZSAgXG4gIHVwZGF0ZVRpdGxlKGV2ZW50OiBhbnkpIHtcbiAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS51cGRhdGVUaXRsZShldmVudCk7XG4gIH1cbiAgdmFsaWRhdGVJbnB1dCh2YWx1ZTogc3RyaW5nLCB0eXBlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBpZiAodHlwZSA9PT0gJ2xhYmVsJyB8fCB0eXBlID09PSAncGxhY2Vob2xkZXInKSB7XG4gICAgICBjb25zdCByZWdleCA9IC9eW2EtekEtWjAtOVxcc10qJC87XG4gICAgICBpZiAoIXJlZ2V4LnRlc3QodmFsdWUpKSB7XG4gICAgICAgIHRoaXMuZXJyb3JNZXNzYWdlID0gJ09ubHkgbGV0dGVycyBhbmQgbnVtYmVycyBhcmUgYWxsb3dlZCc7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5lcnJvck1lc3NhZ2UgPSAnJztcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGdldCBmaWVsZEFzU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuYm9va1N1YnRleHQuZmllbGQuam9pbignLCAnKTsgLy9TS1MyOE1BUjI1IENvbnZlcnQgYXJyYXkgdG8gY29tbWEtc2VwYXJhdGVkIHN0cmluZ1xuICB9XG5cbiAgdXBkYXRlRmllbGQodmFsdWU6IHN0cmluZykge1xuICAgIHRoaXMuYm9va1N1YnRleHQuZmllbGQgPSB2YWx1ZS5zcGxpdCgnLCcpLm1hcChpdGVtID0+IGl0ZW0udHJpbSgpKTsgLy9TS1MyOE1BUjI1IENvbnZlcnQgc3RyaW5nIGJhY2sgdG8gYXJyYXlcbiAgfVxuICAvLyBTS1MyME1BUjI1IEdldHRlciB0byBmaWx0ZXIgY29sdW1ucywgZXhjbHVkaW5nIHRoZSBvbmUgd2l0aCBjdXJyZW50VW5pcXVlSWRlbnRpZmllclxuICBnZXQgZmlsdGVyZWRDb2x1bW5zKCk6IGFueVtdIHtcbiAgICBjb25zdCB0YXJnZXRBcnJheSA9IHRoaXMuZ2V0RGF0YUJ5UGF0aCgnZmllbGRzTWV0YScpO1xuICAgIHJldHVybiB0YXJnZXRBcnJheS5maWx0ZXIoY29sdW1uID0+IGNvbHVtbi51bmlxdWVJZGVudGlmaWVyICE9PSB0aGlzLnNlbGVjdENvbHVtbik7XG4gIH1cblxuICAvLyBTS1MyME1BUjI1IE1ldGhvZCB0byBoYW5kbGUgY2hlY2tib3ggY2hhbmdlc1xuICBvbkNoZWNrYm94Q2hhbmdlKHRhcmdldEFycmF5UGF0aDogYW55LCB0YXJnZXRBcnJheUtleTogYW55LCBrZXk6IGFueSwgYXBpTmFtZTogc3RyaW5nLCBpc0NoZWNrZWQ6IGJvb2xlYW4pIHtcbiAgICBjb25zdCB0YXJnZXRBcnJheSA9IHRoaXMuZ2V0RGF0YUJ5UGF0aCh0YXJnZXRBcnJheVBhdGgpO1xuICAgIGNvbnN0IGZvdW5kSXRlbSA9IHRhcmdldEFycmF5LmZpbmQoaXRlbSA9PiBpdGVtW3RhcmdldEFycmF5S2V5XSA9PT0gdGhpcy5zZWxlY3RDb2x1bW4pO1xuICAgIGZvdW5kSXRlbVtrZXldID0gZm91bmRJdGVtW2tleV0gPyBmb3VuZEl0ZW1ba2V5XSA6IFtdO1xuICAgIGlmIChpc0NoZWNrZWQpIHtcbiAgICAgIC8vIEFkZCBhcGlOYW1lIHRvIHNlbGVjdGVkQXBpTmFtZXMgaWYgbm90IGFscmVhZHkgcHJlc2VudFxuICAgICAgaWYgKCFmb3VuZEl0ZW1ba2V5XS5pbmNsdWRlcyhhcGlOYW1lKSkge1xuICAgICAgICBmb3VuZEl0ZW1ba2V5XS5wdXNoKGFwaU5hbWUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBSZW1vdmUgYXBpTmFtZSBmcm9tIHNlbGVjdGVkQXBpTmFtZXMgaWYgcHJlc2VudFxuICAgICAgY29uc3QgaW5kZXggPSBmb3VuZEl0ZW1ba2V5XS5pbmRleE9mKGFwaU5hbWUpO1xuICAgICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgICAgZm91bmRJdGVtW2tleV0uc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gdGhpcy51cGRhdGVFbGVtZW50KHRoaXMuc2VsZWN0ZWRFbGVtZW50KVxuICB9XG4gIHVwZGF0ZVByb3BlcnR5KGtleTogc3RyaW5nLCB2YWx1ZTogYW55KSB7XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRFbGVtZW50SW5kZXggPj0gMCkge1xuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRFbGVtZW50LnR5cGUgPT09ICdUYWJsZScpIHtcbiAgICAgICAgdGhpcy5zZXRWYWx1ZUJ5UGF0aChrZXksIHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIGlmIChrZXkgPT09ICdxdWVzdGlvblRleHQnIHx8IGtleSA9PT0gJ3F1ZXN0aW9uJykge1xuICAgICAgICBpZiAoIXRoaXMudmFsaWRhdGVJbnB1dCh2YWx1ZSwga2V5KSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGtleSA9PT0gJ3F1ZXN0aW9uTnVtYmVyJykge1xuICAgICAgICAvL0FQLTEwTUFSMjUgQ29udmVydCB0aGUgdmFsdWUgdG8gYW4gaW50ZWdlciAgXG4gICAgICAgIGNvbnN0IG5ld09yZGVyID0gcGFyc2VJbnQodmFsdWUsIDEwKTtcbiAgICAgICAgaWYgKGlzTmFOKG5ld09yZGVyKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vQVAtMTBNQVIyNSBVcGRhdGUgdGhlIGVsZW1lbnQncyBxdWVzdGlvbk51bWJlciBpbiB0aGUgZm9ybSBidWlsZGVyIHNlcnZpY2UgIFxuICAgICAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS51cGRhdGVFbGVtZW50KHRoaXMuc2VsZWN0ZWRFbGVtZW50SW5kZXgsIHsgcXVlc3Rpb25OdW1iZXI6IG5ld09yZGVyIH0pO1xuXG4gICAgICAgIC8vQVAtMTBNQVIyNSBTb3J0IGVsZW1lbnRzIGJhc2VkIG9uIHRoZSB1cGRhdGVkIHF1ZXN0aW9uTnVtYmVyICBcbiAgICAgICAgdGhpcy5mb3JtQnVpbGRlclNlcnZpY2Uuc29ydEVsZW1lbnRzQnlPcmRlcigpO1xuICAgICAgfVxuXG5cbiAgICAgIGlmIChrZXkgPT09ICdmb250V2VpZ2h0Jykge1xuICAgICAgICB0aGlzLnNlbGVjdGVkRWxlbWVudFtrZXldID0gdmFsdWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHVwZGF0ZSA9IHsgW2tleV06IHZhbHVlIH07XG4gICAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS51cGRhdGVFbGVtZW50KHRoaXMuc2VsZWN0ZWRFbGVtZW50SW5kZXgsIHVwZGF0ZSk7XG5cbiAgICAgIC8vIFNwZWNpYWwgaGFuZGxpbmcgZm9yIGZvbnQgYW5kIGZvbnQgd2VpZ2h0XG4gICAgICBpZiAoa2V5ID09PSAnZm9udCcpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZEVsZW1lbnQuZm9udCA9IHZhbHVlOyAvLyBEaXJlY3RseSB1cGRhdGUgdGhlIHNlbGVjdGVkIGVsZW1lbnQncyBmb250IHByb3BlcnR5XG4gICAgICB9XG4gICAgfVxuICB9XG4gIC8vIFNLUzIxTUFSMjUgcmFkaW8gYnV0dG9uIGNsaWNrIGhhbmRsZXJcbiAgb25SYWRpb0NoYW5nZSh0YXJnZXRBcnJheVBhdGg6IGFueSwgdGFyZ2V0QXJyYXlLZXk6IGFueSwga2V5OiBhbnksIHZhbHVlOiBhbnkpIHtcbiAgICBpZiAodGhpcy5zZWxlY3RlZEVsZW1lbnQudHlwZSA9PT0gJ1RhYmxlJykge1xuICAgICAgLy8gdGhpcy51cGRhdGVWYWx1ZUJ5QXJyYXlQYXRoKHRhcmdldEFycmF5LCB0YXJnZXRBcnJheUtleSwgdGhpcy5zZWxlY3RDb2x1bW4sIGtleSwgdmFsdWUpO1xuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRFbGVtZW50Py50eXBlID09PSAnVGFibGUnKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50WydmaWVsZHNNZXRhJ10gPSB0eXBlb2YgdGhpcy5zZWxlY3RlZEVsZW1lbnQ/LmZpZWxkc01ldGEgPT09ICdvYmplY3QnID8gdGhpcy5zZWxlY3RlZEVsZW1lbnQ/LmZpZWxkc01ldGEgOiBKU09OLnBhcnNlKHRoaXMuc2VsZWN0ZWRFbGVtZW50WydmaWVsZHNNZXRhJ10gfHwgW10pO1xuICAgICAgfVxuICAgICAgY29uc3QgdGFyZ2V0QXJyYXkgPSB0aGlzLmdldERhdGFCeVBhdGgodGFyZ2V0QXJyYXlQYXRoKTtcbiAgICAgIC8vIGNvbnNvbGUubG9nKFwidGFyZ2V0QXJyYXlcIiwgdGFyZ2V0QXJyYXksIFwidGFyZ2V0QXJyYXlLZXlcIiwgdGFyZ2V0QXJyYXlLZXksIFwic2VsZWN0Q29sdW1uXCIsIHRoaXMuc2VsZWN0Q29sdW1uLCBcImtleVBhdGhcIiwga2V5LCBcImV2ZW50XCIsIHZhbHVlKVxuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHRhcmdldEFycmF5KSkgcmV0dXJuO1xuXG4gICAgICAvLyBGaW5kIHRoZSBvYmplY3QgdGhhdCBtYXRjaGVzIHNlbGVjdENvbHVtblxuICAgICAgbGV0IGZvdW5kSXRlbSA9IHRhcmdldEFycmF5LmZpbmQoaXRlbSA9PiBpdGVtW3RhcmdldEFycmF5S2V5XSA9PT0gdGhpcy5zZWxlY3RDb2x1bW4pO1xuXG4gICAgICAvLyBJZiB0aGUgaXRlbSBkb2VzIG5vdCBleGlzdCwgY3JlYXRlIGFuZCBhZGQgaXRcbiAgICAgIGlmICghZm91bmRJdGVtKSB7XG4gICAgICAgIGZvdW5kSXRlbSA9IHsgW3RhcmdldEFycmF5S2V5XTogdGhpcy5zZWxlY3RDb2x1bW4gfTsgLy8gRW5zdXJlIHRoZSBrZXkgZXhpc3RzXG4gICAgICAgIHRhcmdldEFycmF5LnB1c2goZm91bmRJdGVtKTtcbiAgICAgIH1cblxuICAgICAgLy8gVHJhdmVyc2UgYW5kIHNldCB0aGUgdmFsdWVcbiAgICAgIGNvbnN0IGtleXMgPSBrZXkuc3BsaXQoJy4nKTtcbiAgICAgIGxldCBvYmogPSBmb3VuZEl0ZW07XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgY29uc3Qga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgaWYgKCFvYmpba2V5XSkgb2JqW2tleV0gPSB7fTsgLy8gSW5pdGlhbGl6ZSBtaXNzaW5nIG9iamVjdHNcbiAgICAgICAgb2JqID0gb2JqW2tleV07XG4gICAgICB9XG5cbiAgICAgIC8vIEFzc2lnbiB0aGUgdmFsdWUgYmFzZWQgb24gaW5wdXQgdHlwZVxuICAgICAgY29uc3QgbGFzdEtleSA9IGtleXNba2V5cy5sZW5ndGggLSAxXTtcblxuICAgICAgb2JqW2xhc3RLZXldID0gdmFsdWU7XG4gICAgICBpZiAodGhpcy5zZWxlY3RlZEVsZW1lbnQ/LnR5cGUgPT09ICdUYWJsZScpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZEVsZW1lbnRbJ2ZpZWxkc01ldGEnXSA9IHR5cGVvZiB0aGlzLnNlbGVjdGVkRWxlbWVudD8uZmllbGRzTWV0YSA9PT0gJ29iamVjdCcgPyBKU09OLnN0cmluZ2lmeSh0aGlzLnNlbGVjdGVkRWxlbWVudD8uZmllbGRzTWV0YSkgOiB0aGlzLnNlbGVjdGVkRWxlbWVudFsnZmllbGRzTWV0YSddIHx8IFtdO1xuICAgICAgfVxuICAgICAgdGhpcy51cGRhdGVFbGVtZW50KHRoaXMuc2VsZWN0ZWRFbGVtZW50KVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNldFZhbHVlQnlQYXRoKGtleSwgdmFsdWUpOyAvLyBGYWxsYmFjayBmb3Igbm9uLVRhYmxlIGVsZW1lbnRzLCBpZiBhcHBsaWNhYmxlXG4gICAgfVxuICB9XG4gIG9uUmVxdWlyZWRDaGFuZ2UodmFsdWU6IGJvb2xlYW4pIHtcbiAgICBpZiAodGhpcy5zZWxlY3RlZEVsZW1lbnQpIHtcbiAgICAgIGxldCBsYWJlbCA9IHRoaXMuc2VsZWN0ZWRFbGVtZW50LmxhYmVsID8gdGhpcy5zZWxlY3RlZEVsZW1lbnQubGFiZWwucmVwbGFjZSgvXFxzKlxcKiskLywgJycpIDogJ0xhYmVsJztcblxuICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgIGxhYmVsID0gYCR7bGFiZWx9ICpgO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnVwZGF0ZVByb3BlcnR5KCdsYWJlbCcsIGxhYmVsKTtcbiAgICAgIHRoaXMudXBkYXRlUHJvcGVydHkoJ2lzT3B0aW9uYWwnLCB2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgLy8gVG9nZ2xlIGZvciBTdWIgUXVlc3Rpb25zIChFYWNoIHByb3AgaGFzIGl0cyBvd24gc3RhdGUpXG4gIHRvZ2dsZVN1YlF1ZXN0aW9uKHByb3A6IGFueSkge1xuICAgIHByb3AuaXNFeHBhbmRlZCA9ICFwcm9wLmlzRXhwYW5kZWQ7XG4gIH1cblxuICAvLyBTZXBhcmF0ZSBUb2dnbGUgZm9yIFN0eWxlIFNlY3Rpb25cbiAgaXNTdHlsZUV4cGFuZGVkID0gZmFsc2U7XG5cbiAgdG9nZ2xlU3R5bGVTZWN0aW9uKCkge1xuICAgIHRoaXMuaXNTdHlsZUV4cGFuZGVkID0gIXRoaXMuaXNTdHlsZUV4cGFuZGVkO1xuICB9XG5cbiAgZ2V0UHJvcGVydGllcygpIHtcbiAgICBpZiAoIXRoaXMuc2VsZWN0ZWRFbGVtZW50KSByZXR1cm4gbnVsbDtcblxuICAgIC8vIEFQLTEwTUFSMjUgUmV0cmlldmUgdGhlIGxhdGVzdCBib29rIGRhdGFcbiAgICB0aGlzLmJvb2sgPSB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5nZXRCb29rKCk7XG5cbiAgICAvLyBBUC0xME1BUjI1IElmIHRoZSBzZWxlY3RlZCBlbGVtZW50IGlzIGEgJ0hlYWRlcicsIHJldHVybiBpdHMgcHJvcGVydGllc1xuICAgIGlmICh0aGlzLnNlbGVjdGVkRWxlbWVudD8udHlwZSA9PT0gJ0hlYWRlcicpIHtcbiAgICAgIHJldHVybiB0aGlzLmVsZW1lbnRQcm9wZXJ0aWVzWydIZWFkZXInXTtcbiAgICB9XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRFbGVtZW50Py50eXBlID09PSAnVGFibGUnKSB7XG4gICAgICBpZiAodGhpcy5zZWxlY3RDb2x1bW4gIT09IG51bGwpIHtcbiAgICAgICAgLy8gR2V0IHRoZSBjb2x1bW4gbWV0YWRhdGFcbiAgICAgICAgY29uc3QgZmllbGRzTWV0YSA9IEFycmF5LmlzQXJyYXkodGhpcy5zZWxlY3RlZEVsZW1lbnQuZmllbGRzTWV0YSkgXG4gICAgICAgICAgPyB0aGlzLnNlbGVjdGVkRWxlbWVudC5maWVsZHNNZXRhIFxuICAgICAgICAgIDogSlNPTi5wYXJzZSh0aGlzLnNlbGVjdGVkRWxlbWVudC5maWVsZHNNZXRhIHx8ICdbXScpO1xuICAgICAgICBcbiAgICAgICAgY29uc3QgY29sdW1uID0gZmllbGRzTWV0YS5maW5kKChjOiBhbnkpID0+IGMudW5pcXVlSWRlbnRpZmllciA9PT0gdGhpcy5zZWxlY3RDb2x1bW4pO1xuICAgICAgICBcbiAgICAgICAgaWYgKGNvbHVtbikge1xuICAgICAgICAgIC8vIFJldHVybiBzcGVjaWZpYyBwcm9wZXJ0aWVzIGJhc2VkIG9uIGNvbHVtbiB0eXBlXG4gICAgICAgICAgc3dpdGNoIChjb2x1bW4uZmxkVHlwZSkge1xuICAgICAgICAgICAgY2FzZSAnTGlzdCc6XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnRQcm9wZXJ0aWVzWydMaXN0Q29sdW1uJ107XG4gICAgICAgICAgICBjYXNlICdEcm9wZG93bic6XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnRQcm9wZXJ0aWVzWydEcm9wZG93bkNvbHVtbiddO1xuICAgICAgICAgICAgY2FzZSAnRGF0ZSc6XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnRQcm9wZXJ0aWVzWydEYXRlQ29sdW1uJ107XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50UHJvcGVydGllc1snVGFibGVDb2x1bW4nXTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudFByb3BlcnRpZXNbdGhpcy5zZWxlY3RlZEVsZW1lbnQ/LnR5cGVdIHx8IHRoaXMuZWxlbWVudFByb3BlcnRpZXNbJ0RlZmF1bHRDb2x1bW4nXTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZWxlbWVudFByb3BlcnRpZXNbdGhpcy5zZWxlY3RlZEVsZW1lbnQ/LnR5cGVdO1xuICB9XG4gIC8vIEFQLTI4TUFSMjUgQWRkIGFuIG9wdGlvbiB3aXRoIGEgdW5pcXVlIFVVSURcbiAgYWRkT3B0aW9uKG9wdGlvbnM6IGFueVtdKSB7XG4gICAgY29uc3QgdW5pcXVlX2lkID0gdXVpZHY0KCk7XG4gICAgb3B0aW9ucy5wdXNoKHsgaWQ6IHVuaXF1ZV9pZCx2YWx1ZTogJycgfSk7XG4gIH1cblxuICAvLyBBUC0yOE1BUjI1IEZ1bmN0aW9uIHRvIHJlbW92ZSBhbiBvcHRpb24gYmFzZWQgb24gaXRzIHVuaXF1ZSBVVUlEXG4gIHJlbW92ZU9wdGlvbihvcHRpb25zOiBhbnlbXSwgaWQ6IHN0cmluZykge1xuICAgIGNvbnN0IGluZGV4ID0gb3B0aW9ucy5maW5kSW5kZXgob3B0aW9uID0+IG9wdGlvbi5pZCA9PT0gaWQpO1xuICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgIG9wdGlvbnMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICB9XG4gIH1cblxuICBoYW5kbGVCdXR0b25DbGljaygpIHtcbiAgICB0aGlzLmZvcm1CdXR0b25IYW5kbGVyLmVtaXQodGhpcy5mb3JtQnVpbGRlclNlcnZpY2UuZG93bmxvYWRFbGVtZW50KCkpO1xuICB9XG4gIGhhbmRsZVRlbXBsYXRlU2F2ZSgpIHtcbiAgICB0aGlzLnRlbXBsYXRlU2F2ZUhhbmRsZXIuZW1pdCh0aGlzLnRlbXBsYXRlU2VydmljZS5kb3dubG9hZCgpKTtcbiAgfVxuICAvLyBTS1MxM01BUjI1IGFjdGl2ZSB0YWIgc2VsZWN0XG4gIHNldEFjdGl2ZVRhYih0YWI6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuYWN0aXZlVGFiID0gdGFiO1xuICB9XG4gIC8vIFNLUzEzTUFSMjUgdGFibGUgcHJvcGVydHkgc2F2ZVxuICBvblNhdmUoKTogdm9pZCB7XG4gICAgLy8gY29uc29sZS5sb2coJ1NhdmluZyBkYXRhOicpO1xuICB9XG4gIC8vIFNLUzEzTUFSMjUgdGFibGUgcHJvcGVydHkgcmVzZXRcbiAgb25DYW5jZWwoKTogdm9pZCB7XG4gICAgLy8gY29uc29sZS5sb2coJ09wZXJhdGlvbiBjYW5jZWxsZWQnKTtcbiAgfVxuXG4gIHVwZGF0ZVByb3BlcnRpZXMoZWxlbWVudFR5cGU6IHN0cmluZyk6IHZvaWQge1xuICAgIC8vIFJlc2V0IGFsaWdubWVudCBhbmQgc3R5bGVzIGlmIHN3aXRjaGluZyBlbGVtZW50c1xuICAgIHRoaXMuc2VsZWN0ZWRBbGlnbiA9ICdhbGlnbi1sZWZ0JztcbiAgICB0aGlzLnNlbGVjdGVkU3R5bGVzID0gW107XG5cbiAgICAvLyBGZXRjaCB0aGUgcHJvcGVydGllcyBvZiB0aGUgc2VsZWN0ZWQgZWxlbWVudCB0eXBlXG5cbiAgICBjb25zdCBwcm9wZXJ0aWVzID0gdGhpcy5nZXRQcm9wZXJ0aWVzKCk7XG4gICAgaWYgKHByb3BlcnRpZXMpIHtcbiAgICAgIC8vIE1ha2Ugc3VyZSB0aGUgcHJvcGVydGllcyBhcmUgZHluYW1pY2FsbHkgdXBkYXRlZFxuICAgIH1cbiAgfVxuXG4gIG9uQWxpZ25TZWxlY3QodmFsdWU6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICh0aGlzLnNlbGVjdGVkRWxlbWVudCkge1xuICAgICAgdGhpcy5zZWxlY3RlZEVsZW1lbnQudGV4dEFsaWduID0gdmFsdWU7XG4gICAgfVxuICB9XG5cbiAgb25TdHlsZVNlbGVjdCh2YWx1ZTogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnNlbGVjdGVkRWxlbWVudCkgcmV0dXJuO1xuXG4gICAgLy8gSW5pdGlhbGl6ZSBzdHlsZXMgYXJyYXkgaWYgaXQgZG9lc24ndCBleGlzdFxuICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50LnN0eWxlcyA9IHRoaXMuc2VsZWN0ZWRFbGVtZW50LnN0eWxlcyB8fCBbXTtcblxuICAgIC8vIEVuc3VyZSBvbmx5IG9uZSBzdHlsZSBpcyBzZWxlY3RlZCBhdCBhIHRpbWVcbiAgICB0aGlzLnNlbGVjdGVkRWxlbWVudC5zdHlsZXMgPSBbdmFsdWVdO1xuXG4gIH1cblxuICBpc1N0eWxlQWN0aXZlKHZhbHVlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3RlZEVsZW1lbnQ/LnN0eWxlcz8uaW5jbHVkZXModmFsdWUpIHx8IGZhbHNlO1xuICB9XG4gIGdldFZhbHVlQnlQYXRoKHBhdGg6IHN0cmluZyk6IGFueSB7XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRFbGVtZW50Py50eXBlID09PSAnVGFibGUnKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkRWxlbWVudFsnZmllbGRzTWV0YSddID0gdHlwZW9mIHRoaXMuc2VsZWN0ZWRFbGVtZW50Py5maWVsZHNNZXRhID09PSAnb2JqZWN0JyA/IHRoaXMuc2VsZWN0ZWRFbGVtZW50Py5maWVsZHNNZXRhIDogSlNPTi5wYXJzZSh0aGlzLnNlbGVjdGVkRWxlbWVudFsnZmllbGRzTWV0YSddIHx8IFtdKTtcbiAgICB9XG5cbiAgICB0aGlzLnNlbGVjdGVkRWxlbWVudFsnc3ViVGV4dCddID0gXG4gICAgICAgIHR5cGVvZiB0aGlzLnNlbGVjdGVkRWxlbWVudD8uc3ViVGV4dCA9PT0gJ29iamVjdCdcbiAgICAgICAgICAgID8gdGhpcy5zZWxlY3RlZEVsZW1lbnQuc3ViVGV4dFxuICAgICAgICAgICAgOiAodHlwZW9mIHRoaXMuc2VsZWN0ZWRFbGVtZW50Py5zdWJUZXh0ID09PSAnc3RyaW5nJyAmJiB0aGlzLnNlbGVjdGVkRWxlbWVudC5zdWJUZXh0LnRyaW0oKSAhPT0gJycgXG4gICAgICAgICAgICAgICAgPyBKU09OLnBhcnNlKHRoaXMuc2VsZWN0ZWRFbGVtZW50LnN1YlRleHQpIFxuICAgICAgICAgICAgICAgIDoge30pO1xuXG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRFbGVtZW50WydzdWJUZXh0J10gJiYgQXJyYXkuaXNBcnJheSh0aGlzLnNlbGVjdGVkRWxlbWVudFsnc3ViVGV4dCddLmZpZWxkKSkge1xuICAgICAgICAvLyBDb252ZXJ0IGFycmF5IHRvIGEgY29tbWEtc2VwYXJhdGVkIHN0cmluZ1xuICAgICAgICB0aGlzLnNlbGVjdGVkRWxlbWVudFsnc3ViVGV4dCddLmZpZWxkID0gdGhpcy5zZWxlY3RlZEVsZW1lbnRbJ3N1YlRleHQnXS5maWVsZC5qb2luKCcsICcpO1xuICAgIH0gIFxuICAgIHJldHVybiBwYXRoLnNwbGl0KCcuJykucmVkdWNlKChvYmosIGtleSkgPT4gb2JqPy5ba2V5XSA/PyAnJywgdGhpcy5zZWxlY3RlZEVsZW1lbnQpO1xuICB9XG5pc0Fub3RoZXJJZFNlbGVjdGVkKCk6IGJvb2xlYW4ge1xuICByZXR1cm4gdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UuZ2V0RWxlbWVudHMoKVxuICAgIC5zb21lKChlbCwgaSkgPT4gaSAhPT0gdGhpcy5zZWxlY3RlZEVsZW1lbnRJbmRleCAmJiBlbC5wcmltYXJ5S2V5KTtcbn1cbiAgb25Ub2dnbGVDaGFuZ2UocGF0aDogc3RyaW5nLCBldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBjaGVja2VkID0gKGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50KS5jaGVja2VkO1xuICAgIHRoaXMuc2V0VmFsdWVCeVBhdGgocGF0aCwgY2hlY2tlZCk7XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRFbGVtZW50Py50eXBlID09PSAnVGFibGUnKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkRWxlbWVudFsnZmllbGRzTWV0YSddID0gdHlwZW9mIHRoaXMuc2VsZWN0ZWRFbGVtZW50Py5maWVsZHNNZXRhID09PSAnb2JqZWN0JyA/IEpTT04uc3RyaW5naWZ5KHRoaXMuc2VsZWN0ZWRFbGVtZW50Py5maWVsZHNNZXRhKSA6IHRoaXMuc2VsZWN0ZWRFbGVtZW50WydmaWVsZHNNZXRhJ10gfHwgW107XG4gICAgfVxuICAgIHRoaXMudXBkYXRlRWxlbWVudCh0aGlzLnNlbGVjdGVkRWxlbWVudClcbiAgfVxuXG4gIHNldFZhbHVlQnlQYXRoKHBhdGg6IHN0cmluZywgdmFsdWU6IGFueSk6IHZvaWQge1xuXG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRFbGVtZW50SW5kZXggPj0gMCkge1xuICAgICAgaWYgKHBhdGggPT09ICdxdWVzdGlvblRleHQnIHx8IHZhbHVlID09PSAncXVlc3Rpb24nKSB7XG4gICAgICAgIGlmICghdGhpcy52YWxpZGF0ZUlucHV0KHZhbHVlLCB2YWx1ZSkpIHtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHBhdGggPT09ICdxdWVzdGlvbk51bWJlcicpIHtcbiAgICAgICAgLy9BUC0xME1BUjI1IENvbnZlcnQgdGhlIHZhbHVlIHRvIGFuIGludGVnZXIgIFxuICAgICAgICBjb25zdCBuZXdPcmRlciA9IHBhcnNlSW50KHZhbHVlLCAxMCk7XG4gICAgICAgIGlmIChpc05hTihuZXdPcmRlcikpIHJldHVybjtcblxuICAgICAgICAvL0FQLTEwTUFSMjUgVXBkYXRlIHRoZSBlbGVtZW50J3MgcXVlc3Rpb25OdW1iZXIgaW4gdGhlIGZvcm0gYnVpbGRlciBzZXJ2aWNlICBcbiAgICAgICAgdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UudXBkYXRlRWxlbWVudCh0aGlzLnNlbGVjdGVkRWxlbWVudEluZGV4LCB7IHF1ZXN0aW9uTnVtYmVyOiBuZXdPcmRlciB9KTtcblxuICAgICAgICAvL0FQLTEwTUFSMjUgU29ydCBlbGVtZW50cyBiYXNlZCBvbiB0aGUgdXBkYXRlZCBxdWVzdGlvbk51bWJlciAgXG4gICAgICAgIHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLnNvcnRFbGVtZW50c0J5T3JkZXIoKTtcbiAgICAgIH1cbiAgICAgIGlmIChwYXRoID09PSAnZm9udFdlaWdodCcpIHtcbiAgICAgICAgLy8gY29uc29sZS5sb2coJ0ZvbnQgd2VpZ2h0IHNlbGVjdGVkOicsIHZhbHVlKTtcbiAgICAgICAgdGhpcy5zZWxlY3RlZEVsZW1lbnRbcGF0aF0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIC8vIFNwZWNpYWwgaGFuZGxpbmcgZm9yIGZvbnQgYW5kIGZvbnQgd2VpZ2h0XG4gICAgICBpZiAocGF0aCA9PT0gJ2ZvbnQnKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50LmZvbnQgPSB2YWx1ZTsgLy8gRGlyZWN0bHkgdXBkYXRlIHRoZSBzZWxlY3RlZCBlbGVtZW50J3MgZm9udCBwcm9wZXJ0eVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGtleXMgPSBwYXRoLnNwbGl0KCcuJyk7XG4gICAgbGV0IG9iaiA9IHRoaXMuc2VsZWN0ZWRFbGVtZW50O1xuICAgIGlmICh0aGlzLnNlbGVjdGVkRWxlbWVudD8udHlwZSA9PT0gJ1RhYmxlJykge1xuICAgICAgdGhpcy5zZWxlY3RlZEVsZW1lbnRbJ2ZpZWxkc01ldGEnXSA9IHR5cGVvZiB0aGlzLnNlbGVjdGVkRWxlbWVudD8uZmllbGRzTWV0YSA9PT0gJ29iamVjdCcgPyB0aGlzLnNlbGVjdGVkRWxlbWVudD8uZmllbGRzTWV0YSA6IEpTT04ucGFyc2UodGhpcy5zZWxlY3RlZEVsZW1lbnRbJ2ZpZWxkc01ldGEnXSB8fCBbXSk7XG4gICAgfVxuICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50WydzdWJUZXh0J10gPSB0eXBlb2YgdGhpcy5zZWxlY3RlZEVsZW1lbnQ/LnN1YlRleHQgPT09ICdvYmplY3QnID8gdGhpcy5zZWxlY3RlZEVsZW1lbnQ/LnN1YlRleHQgOiBKU09OLnBhcnNlKHRoaXMuc2VsZWN0ZWRFbGVtZW50WydzdWJUZXh0J10pO1xuXG4gICAga2V5cy5mb3JFYWNoKChrZXksIGluZGV4KSA9PiB7XG4gICAgICBpZiAoIW9ialtrZXldKSB7XG4gICAgICAgIC8vIENoZWNrIGlmIHRoZSBuZXh0IGtleSBpcyBhIG51bWJlciAoYXJyYXkgaW5kZXgpXG4gICAgICAgIGNvbnN0IG5leHRLZXkgPSBrZXlzW2luZGV4ICsgMV07XG4gICAgICAgIG9ialtrZXldID0gaXNOYU4oTnVtYmVyKG5leHRLZXkpKSA/IHt9IDogW107XG4gICAgICB9XG4gICAgICBpZiAoaW5kZXggPT09IGtleXMubGVuZ3RoIC0gMSkge1xuICAgICAgICBvYmpba2V5XSA9IHZhbHVlOyAvLyBBc3NpZ24gdmFsdWUgdG8gbGFzdCBrZXlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9iaiA9IG9ialtrZXldOyAvLyBNb3ZlIGRlZXBlclxuICAgICAgfVxuICAgIH0pO1xuICAgIHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLmVsZW1lbnRVcGRhdGUodGhpcy5zZWxlY3RlZEVsZW1lbnRJbmRleCwgdGhpcy5zZWxlY3RlZEVsZW1lbnQpO1xuICB9XG4gIGdldFN0eWxlS2V5cygpOiBzdHJpbmdbXSB7XG4gICAgaWYgKCF0aGlzLnNlbGVjdGVkRWxlbWVudCB8fCAhdGhpcy5zZWxlY3RlZEVsZW1lbnQuc3R5bGUgfHwgdHlwZW9mIHRoaXMuc2VsZWN0ZWRFbGVtZW50LnN0eWxlICE9PSAnb2JqZWN0Jykge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5zZWxlY3RlZEVsZW1lbnQuc3R5bGUpO1xuICB9ICBcblxuICAvLyBTS1MxOU1BUjI1IHVwZGF0ZSBlbGVtZW50IGluIHNlcnZpZXNcbiAgdXBkYXRlRWxlbWVudChlbGVtZW50OiBhbnkpIHtcbiAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5lbGVtZW50VXBkYXRlKHRoaXMuc2VsZWN0ZWRFbGVtZW50SW5kZXgsIGVsZW1lbnQpXG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRFbGVtZW50Py50eXBlID09PSAnVGFibGUnICYmIHRoaXMuc2VsZWN0Q29sdW1uKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkRWxlbWVudFsnZmllbGRzTWV0YSddID0gdHlwZW9mIHRoaXMuc2VsZWN0ZWRFbGVtZW50Py5maWVsZHNNZXRhID09PSAnb2JqZWN0JyA/IHRoaXMuc2VsZWN0ZWRFbGVtZW50Py5maWVsZHNNZXRhIDogSlNPTi5wYXJzZSh0aGlzLnNlbGVjdGVkRWxlbWVudC5maWVsZHNNZXRhIHx8IFtdKTtcbiAgICAgIGNvbnN0IGZvdW5kSXRlbSA9IHRoaXMuc2VsZWN0ZWRFbGVtZW50WydmaWVsZHNNZXRhJ10uZmluZChpdGVtID0+IGl0ZW1bJ3VuaXF1ZUlkZW50aWZpZXInXSA9PT0gdGhpcy5zZWxlY3RDb2x1bW4pO1xuICAgICAgdGhpcy5mb3JtQnVpbGRlclNlcnZpY2Uuc2V0U2VsZWN0ZWRUYWJsZUVsZW1lbnQodGhpcy5zZWxlY3RlZEVsZW1lbnRJbmRleCwgeyBjb2x1bW46IGZvdW5kSXRlbT8uYXBpTmFtZSB8fCBudWxsIH0pO1xuICAgIH1cbiAgfVxuICAvLyBTS1MxOU1BUjI1IGdldCB2YWx1ZSBmcm9tIGFycmF5XG4gIGdldFZhbHVlQnlBcnJheVBhdGgodGFyZ2V0QXJyYXlQYXRoOiBhbnksIHRhcmdldEFycmF5S2V5OiBzdHJpbmcsIHNlbGVjdENvbHVtbjogc3RyaW5nLCBrZXlQYXRoOiBzdHJpbmcpOiBhbnkge1xuICAgIGlmICh0aGlzLnNlbGVjdGVkRWxlbWVudD8udHlwZSA9PT0gJ1RhYmxlJykge1xuICAgICAgdGhpcy5zZWxlY3RlZEVsZW1lbnRbJ2ZpZWxkc01ldGEnXSA9IHR5cGVvZiB0aGlzLnNlbGVjdGVkRWxlbWVudD8uZmllbGRzTWV0YSA9PT0gJ29iamVjdCcgPyB0aGlzLnNlbGVjdGVkRWxlbWVudD8uZmllbGRzTWV0YSA6IEpTT04ucGFyc2UodGhpcy5zZWxlY3RlZEVsZW1lbnRbJ2ZpZWxkc01ldGEnXSB8fCBbXSk7XG4gICAgfVxuICAgIGNvbnN0IHRhcmdldEFycmF5ID0gdGhpcy5nZXREYXRhQnlQYXRoKHRhcmdldEFycmF5UGF0aCk7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHRhcmdldEFycmF5KSkgcmV0dXJuICcnO1xuXG4gICAgY29uc3QgZm91bmRJdGVtID0gdGFyZ2V0QXJyYXkuZmluZChpdGVtID0+IGl0ZW1bdGFyZ2V0QXJyYXlLZXldID09PSBzZWxlY3RDb2x1bW4pO1xuXG4gICAgcmV0dXJuIGZvdW5kSXRlbSA/IGtleVBhdGguc3BsaXQoJy4nKS5yZWR1Y2UoKG9iaiwga2V5KSA9PiBvYmo/LltrZXldLCBmb3VuZEl0ZW0pIDogJyc7XG4gIH1cblxuICAvL1NLUzE5TUFSMjUgRnVuY3Rpb24gdG8gdXBkYXRlIGEgdmFsdWUgaW4gYW4gYXJyYXkgZHluYW1pY2FsbHlcbiAgdXBkYXRlVmFsdWVCeUFycmF5UGF0aCh0YXJnZXRBcnJheVBhdGg6IGFueSwgdGFyZ2V0QXJyYXlLZXk6IHN0cmluZywgc2VsZWN0Q29sdW1uOiBzdHJpbmcsIGtleVBhdGg6IHN0cmluZywgZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRFbGVtZW50Py50eXBlID09PSAnVGFibGUnKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkRWxlbWVudFsnZmllbGRzTWV0YSddID0gdHlwZW9mIHRoaXMuc2VsZWN0ZWRFbGVtZW50Py5maWVsZHNNZXRhID09PSAnb2JqZWN0JyA/IHRoaXMuc2VsZWN0ZWRFbGVtZW50Py5maWVsZHNNZXRhIDogSlNPTi5wYXJzZSh0aGlzLnNlbGVjdGVkRWxlbWVudFsnZmllbGRzTWV0YSddIHx8IFtdKTtcbiAgICB9XG4gICAgY29uc3QgdGFyZ2V0QXJyYXkgPSB0aGlzLmdldERhdGFCeVBhdGgodGFyZ2V0QXJyYXlQYXRoKTtcbiAgICAvLyBjb25zb2xlLmxvZyhcInRhcmdldEFycmF5XCIsIHRhcmdldEFycmF5LCBcInRhcmdldEFycmF5S2V5XCIsIHRhcmdldEFycmF5S2V5LCBcInNlbGVjdENvbHVtblwiLCBzZWxlY3RDb2x1bW4sIFwia2V5UGF0aFwiLCBrZXlQYXRoLCBcImV2ZW50XCIsIGV2ZW50KVxuICAgIGlmICghQXJyYXkuaXNBcnJheSh0YXJnZXRBcnJheSkpIHJldHVybjtcblxuICAgIC8vIEZpbmQgdGhlIG9iamVjdCB0aGF0IG1hdGNoZXMgc2VsZWN0Q29sdW1uXG4gICAgbGV0IGZvdW5kSXRlbSA9IHRhcmdldEFycmF5LmZpbmQoaXRlbSA9PiBpdGVtW3RhcmdldEFycmF5S2V5XSA9PT0gc2VsZWN0Q29sdW1uKTtcblxuICAgIC8vIElmIHRoZSBpdGVtIGRvZXMgbm90IGV4aXN0LCBjcmVhdGUgYW5kIGFkZCBpdFxuICAgIGlmICghZm91bmRJdGVtKSB7XG4gICAgICBmb3VuZEl0ZW0gPSB7IFt0YXJnZXRBcnJheUtleV06IHNlbGVjdENvbHVtbiB9OyAvLyBFbnN1cmUgdGhlIGtleSBleGlzdHNcbiAgICAgIHRhcmdldEFycmF5LnB1c2goZm91bmRJdGVtKTtcbiAgICB9XG5cbiAgICAvLyBUcmF2ZXJzZSBhbmQgc2V0IHRoZSB2YWx1ZVxuICAgIGNvbnN0IGtleXMgPSBrZXlQYXRoLnNwbGl0KCcuJyk7XG4gICAgbGV0IG9iaiA9IGZvdW5kSXRlbTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgIGNvbnN0IGtleSA9IGtleXNbaV07XG4gICAgICBpZiAoIW9ialtrZXldKSBvYmpba2V5XSA9IHt9OyAvLyBJbml0aWFsaXplIG1pc3Npbmcgb2JqZWN0c1xuICAgICAgb2JqID0gb2JqW2tleV07XG4gICAgfVxuXG4gICAgLy8gQXNzaWduIHRoZSB2YWx1ZSBiYXNlZCBvbiBpbnB1dCB0eXBlXG4gICAgY29uc3QgbGFzdEtleSA9IGtleXNba2V5cy5sZW5ndGggLSAxXTtcbiAgICBjb25zdCBpbnB1dEVsZW1lbnQgPSBldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudDtcblxuICAgIG9ialtsYXN0S2V5XSA9IGlucHV0RWxlbWVudD8udHlwZSA9PT0gJ2NoZWNrYm94JyA/IGlucHV0RWxlbWVudC5jaGVja2VkIDogaW5wdXRFbGVtZW50LnZhbHVlO1xuICAgIGlmIChrZXlQYXRoID09PSAnc3VtbWFyeUNvbHVtbicpIHtcbiAgICAgIGlmIChvYmpbJ3N1bW1hcnlSb3cnXSA9PT0gdHJ1ZSkge1xuICAgICAgICBvYmpbJ3N1bW1hcnlSb3cnXSA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKGlucHV0RWxlbWVudC5jaGVja2VkID09PSB0cnVlKSB7XG4gICAgICAgIG9ialsnZmxkVHlwZSddID0gJ2NhbGN1bGF0aW9uJ1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb2JqWydmbGRUeXBlJ10gPSAnVGV4dCdcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGtleVBhdGggPT09ICdzdW1tYXJ5Um93Jykge1xuICAgICAgaWYgKG9ialsnc3VtbWFyeUNvbHVtbiddID09PSB0cnVlKSB7XG4gICAgICAgIG9ialsnc3VtbWFyeUNvbHVtbiddID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoaW5wdXRFbGVtZW50LmNoZWNrZWQgPT09IHRydWUpIHtcbiAgICAgICAgb2JqWydmbGRUeXBlJ10gPSAnY2FsY3VsYXRpb24nXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvYmpbJ2ZsZFR5cGUnXSA9ICdUZXh0J1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodGhpcy5zZWxlY3RlZEVsZW1lbnQ/LnR5cGUgPT09ICdUYWJsZScpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50WydmaWVsZHNNZXRhJ10gPSB0eXBlb2YgdGhpcy5zZWxlY3RlZEVsZW1lbnQ/LmZpZWxkc01ldGEgPT09ICdvYmplY3QnID8gSlNPTi5zdHJpbmdpZnkodGhpcy5zZWxlY3RlZEVsZW1lbnQ/LmZpZWxkc01ldGEpIDogdGhpcy5zZWxlY3RlZEVsZW1lbnRbJ2ZpZWxkc01ldGEnXSB8fCBbXTtcbiAgICB9XG4gICAgdGhpcy51cGRhdGVFbGVtZW50KHRoaXMuc2VsZWN0ZWRFbGVtZW50KVxuICB9XG4gIGdldERhdGFCeVBhdGgocGF0aDogc3RyaW5nKTogYW55IHtcbiAgICBpZiAodGhpcy5zZWxlY3RlZEVsZW1lbnQ/LnR5cGUgPT09ICdUYWJsZScpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50WydmaWVsZHNNZXRhJ10gPSB0eXBlb2YgdGhpcy5zZWxlY3RlZEVsZW1lbnQ/LmZpZWxkc01ldGEgPT09ICdvYmplY3QnID8gdGhpcy5zZWxlY3RlZEVsZW1lbnQ/LmZpZWxkc01ldGEgOiBKU09OLnBhcnNlKHRoaXMuc2VsZWN0ZWRFbGVtZW50WydmaWVsZHNNZXRhJ10gfHwgW10pO1xuICAgIH1cbiAgICByZXR1cm4gcGF0aC5zcGxpdCgnLicpLnJlZHVjZSgob2JqLCBrZXkpID0+IG9iaj8uW2tleV0sIHRoaXMuc2VsZWN0ZWRFbGVtZW50KTtcbiAgfVxuXG4gIC8vIFNLUzI1TUFSMjUgaW1hZ2UgZWRpdCBmdW5jdGlvbnNcbiAgZmxpcEhvcml6b250YWwoKSB7XG4gICAgdGhpcy50cmFuc2Zvcm0gPSB7XG4gICAgICAuLi50aGlzLnRyYW5zZm9ybSxcbiAgICAgIGZsaXBIOiAhdGhpcy50cmFuc2Zvcm0uZmxpcEhcbiAgICB9O1xuICB9XG5cbiAgZmxpcFZlcnRpY2FsKCkge1xuICAgIHRoaXMudHJhbnNmb3JtID0ge1xuICAgICAgLi4udGhpcy50cmFuc2Zvcm0sXG4gICAgICBmbGlwVjogIXRoaXMudHJhbnNmb3JtLmZsaXBWXG4gICAgfTtcbiAgfVxuXG4gIHJlc2V0SW1hZ2UoKSB7XG4gICAgdGhpcy5jYW52YXNSb3RhdGlvbiA9IDA7XG4gICAgdGhpcy5jcm9wcGVyID0gdW5kZWZpbmVkO1xuICAgIHRoaXMudHJhbnNmb3JtID0ge1xuICAgICAgdHJhbnNsYXRlVW5pdDogJ3B4JyxcbiAgICAgIHNjYWxlOiAxLFxuICAgICAgcm90YXRlOiAwLFxuICAgICAgZmxpcEg6IGZhbHNlLFxuICAgICAgZmxpcFY6IGZhbHNlLFxuICAgICAgdHJhbnNsYXRlSDogMCxcbiAgICAgIHRyYW5zbGF0ZVY6IDBcbiAgICB9O1xuICB9XG5cbiAgem9vbU91dCgpIHtcbiAgICB0aGlzLnRyYW5zZm9ybSA9IHtcbiAgICAgIC4uLnRoaXMudHJhbnNmb3JtLFxuICAgICAgc2NhbGU6IHRoaXMudHJhbnNmb3JtLnNjYWxlISAtIC4xXG4gICAgfTtcbiAgfVxuXG4gIHpvb21JbigpIHtcbiAgICB0aGlzLnRyYW5zZm9ybSA9IHtcbiAgICAgIC4uLnRoaXMudHJhbnNmb3JtLFxuICAgICAgc2NhbGU6IHRoaXMudHJhbnNmb3JtLnNjYWxlISArIC4xXG4gICAgfTtcbiAgfVxuICByb3RhdGVMZWZ0KCkge1xuICAgIHRoaXMubG9hZGluZyA9IHRydWU7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7IC8vIFVzZSB0aW1lb3V0IGJlY2F1c2Ugcm90YXRpbmcgaW1hZ2UgaXMgYSBoZWF2eSBvcGVyYXRpb24gYW5kIHdpbGwgYmxvY2sgdGhlIHVpIHRocmVhZFxuICAgICAgdGhpcy5jYW52YXNSb3RhdGlvbi0tO1xuICAgICAgdGhpcy5mbGlwQWZ0ZXJSb3RhdGUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHJvdGF0ZVJpZ2h0KCkge1xuICAgIHRoaXMubG9hZGluZyA9IHRydWU7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmNhbnZhc1JvdGF0aW9uKys7XG4gICAgICB0aGlzLmZsaXBBZnRlclJvdGF0ZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgbW92ZUxlZnQoKSB7XG4gICAgdGhpcy50cmFuc2Zvcm0gPSB7XG4gICAgICAuLi50aGlzLnRyYW5zZm9ybSxcbiAgICAgIHRyYW5zbGF0ZUg6IHRoaXMudHJhbnNmb3JtLnRyYW5zbGF0ZUghIC0gMVxuICAgIH07XG4gIH1cblxuICBtb3ZlUmlnaHQoKSB7XG4gICAgdGhpcy50cmFuc2Zvcm0gPSB7XG4gICAgICAuLi50aGlzLnRyYW5zZm9ybSxcbiAgICAgIHRyYW5zbGF0ZUg6IHRoaXMudHJhbnNmb3JtLnRyYW5zbGF0ZUghICsgMVxuICAgIH07XG4gIH1cblxuICBtb3ZlRG93bigpIHtcbiAgICB0aGlzLnRyYW5zZm9ybSA9IHtcbiAgICAgIC4uLnRoaXMudHJhbnNmb3JtLFxuICAgICAgdHJhbnNsYXRlVjogdGhpcy50cmFuc2Zvcm0udHJhbnNsYXRlViEgKyAxXG4gICAgfTtcbiAgfVxuXG4gIG1vdmVVcCgpIHtcbiAgICB0aGlzLnRyYW5zZm9ybSA9IHtcbiAgICAgIC4uLnRoaXMudHJhbnNmb3JtLFxuICAgICAgdHJhbnNsYXRlVjogdGhpcy50cmFuc2Zvcm0udHJhbnNsYXRlViEgLSAxXG4gICAgfTtcbiAgfVxuICBwcml2YXRlIGZsaXBBZnRlclJvdGF0ZSgpIHtcbiAgICBjb25zdCBmbGlwcGVkSCA9IHRoaXMudHJhbnNmb3JtLmZsaXBIO1xuICAgIGNvbnN0IGZsaXBwZWRWID0gdGhpcy50cmFuc2Zvcm0uZmxpcFY7XG4gICAgdGhpcy50cmFuc2Zvcm0gPSB7XG4gICAgICAuLi50aGlzLnRyYW5zZm9ybSxcbiAgICAgIGZsaXBIOiBmbGlwcGVkVixcbiAgICAgIGZsaXBWOiBmbGlwcGVkSCxcbiAgICAgIHRyYW5zbGF0ZUg6IDAsXG4gICAgICB0cmFuc2xhdGVWOiAwXG4gICAgfTtcbiAgfVxuICBhc3luYyBpbWFnZUNyb3BwZWQoZXZlbnQ6IGFueSkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBiYXNlNjQgPSBhd2FpdCB0aGlzLmNvbnZlcnRCbG9iVG9CYXNlNjQoZXZlbnQub2JqZWN0VXJsKTtcbiAgICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50LmltYWdlRGF0YSA9IGJhc2U2NDtcbiAgICAgIGF3YWl0IHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLmVsZW1lbnRVcGRhdGUodGhpcy5zZWxlY3RlZEVsZW1lbnRJbmRleCwgdGhpcy5zZWxlY3RlZEVsZW1lbnQpO1xuICAgICAgLy8gY29uc29sZS5sb2coJ0NST1BQRUQnLCBldmVudCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciBpbiBpbWFnZUNyb3BwZWQ6XCIsIGVycm9yKTtcbiAgICB9XG4gIH1cblxuXG4gIGNyb3BwZXJSZWFkeShzb3VyY2VJbWFnZURpbWVuc2lvbnM6IERpbWVuc2lvbnMpIHtcbiAgICAvLyBjb25zb2xlLmxvZygnQ3JvcHBlciByZWFkeScsIHNvdXJjZUltYWdlRGltZW5zaW9ucyk7XG4gICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gIH1cbiAgLy8gU0tTMjVNQVIyNSBibG9iIHRvIGJhc2UgNjQgY29udmVydGVyXG4gIGNvbnZlcnRCbG9iVG9CYXNlNjQob2JqZWN0VXJsOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHJldHVybiBmZXRjaChvYmplY3RVcmwpXG4gICAgICAudGhlbihyZXNwb25zZSA9PiByZXNwb25zZS5ibG9iKCkpXG4gICAgICAudGhlbihibG9iID0+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICBjb25zdCByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xuICAgICAgICAgIHJlYWRlci5yZWFkQXNEYXRhVVJMKGJsb2IpO1xuICAgICAgICAgIHJlYWRlci5vbmxvYWRlbmQgPSAoKSA9PiByZXNvbHZlKHJlYWRlci5yZXN1bHQgYXMgc3RyaW5nKTtcbiAgICAgICAgICByZWFkZXIub25lcnJvciA9IGVycm9yID0+IHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gIH1cbiAgLy8gU0tTMjhNQVIyNSBxYiBib29rIHVwZGF0ZSBpbiBib29rIGVsZW1lbnRcbiAgY2hpbGRFdmVudENhcHR1cmUoZXZlbnQ6IGFueSkge1xuICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50LnFiUmVmZXJlbmNlID0gZXZlbnQudmFsdWVPYmo/Lm5hbWVcbiAgICB0aGlzLnNlbGVjdGVkRWxlbWVudC5xYlJlZmVyZW5jZVF1ZXN0aW9ucyA9IGV2ZW50LnZhbHVlT2JqPy5qc29uQm9keVxuICAgIHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLmVsZW1lbnRVcGRhdGUodGhpcy5zZWxlY3RlZEVsZW1lbnRJbmRleCwgdGhpcy5zZWxlY3RlZEVsZW1lbnQpO1xuICB9XG5cbiAgLy8gU0tTMjhNQVIyNSBib29rIHNlYXJjaCBkcm9wZG93biBlbWl0XG4gIGxpbmtUb2dnbGVEcm9wZG93bihldmVudDogRXZlbnQpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLmlzTGlua0Ryb3Bkb3duT3BlbiA9ICF0aGlzLmlzTGlua0Ryb3Bkb3duT3BlbjtcbiAgfVxuXG4gIC8vIFNLUzI4TUFSMjUgYm9vayBzZWFyY2ggZHJvcGRvd24gY2xvc2VcbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6Y2xpY2snLCBbJyRldmVudCddKVxuICBvbkNsaWNrT3V0c2lkZShldmVudDogRXZlbnQpIHtcbiAgICBpZiAodGhpcy5kcm9wZG93biAmJiAhdGhpcy5kcm9wZG93bi5uYXRpdmVFbGVtZW50LmNvbnRhaW5zKGV2ZW50LnRhcmdldCkpIHtcbiAgICAgIHRoaXMuaXNMaW5rRHJvcGRvd25PcGVuID0gZmFsc2U7XG4gICAgfVxuICB9XG4gIC8vIEFQLTI4TUFSMjUgV2hlbiBkcmFnIHN0YXJ0cywgc3RvcmUgdGhlIGluZGV4XG4gIG9uRHJhZ1N0YXJ0KGV2ZW50OiBEcmFnRXZlbnQsIGlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLmRyYWdnZWRJZCA9IGlkO1xuICAgIGV2ZW50LmRhdGFUcmFuc2ZlciEuZWZmZWN0QWxsb3dlZCA9IFwibW92ZVwiO1xuICB9XG5cbiAgLy8gQVAtMjhNQVIyNSBQcmV2ZW50IGRlZmF1bHQgYmVoYXZpb3IgdG8gYWxsb3cgZHJvcFxuICBvbkRyYWdPdmVyKGV2ZW50OiBEcmFnRXZlbnQpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9XG5cbiAgLy8gQVAtMjhNQVIyNSBTd2FwIHRoZSBkcmFnZ2VkIGl0ZW0gd2l0aCB0aGUgZHJvcHBlZCBwb3NpdGlvblxuICBvbkRyb3AoZXZlbnQ6IERyYWdFdmVudCwga2V5OiBzdHJpbmcpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGNvbnN0IHRhcmdldElkID0gKGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudCkuY2xvc2VzdChcIi5vcHRpb24taXRlbXNcIik/LmdldEF0dHJpYnV0ZShcImRhdGEtaWRcIik7XG5cbiAgICBpZiAodGhpcy5kcmFnZ2VkSWQgJiYgdGFyZ2V0SWQgJiYgdGhpcy5kcmFnZ2VkSWQgIT09IHRhcmdldElkKSB7XG4gICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5zZWxlY3RlZEVsZW1lbnRba2V5XTtcblxuICAgICAgW29wdGlvbnNbdGhpcy5kcmFnZ2VkSWRdLCBvcHRpb25zW3RhcmdldElkXV0gPSBbb3B0aW9uc1t0YXJnZXRJZF0sIG9wdGlvbnNbdGhpcy5kcmFnZ2VkSWRdXTtcbiAgICAgIC8vIEZpbmQgdGhlIGluZGV4ZXMgb2YgdGhlIGRyYWdnZWQgYW5kIHRhcmdldCBvcHRpb25zXG4gICAgICBjb25zdCBkcmFnZ2VkSW5kZXggPSBvcHRpb25zLmZpbmRJbmRleChvcHRpb24gPT4gb3B0aW9uLmlkID09PSB0aGlzLmRyYWdnZWRJZCk7XG4gICAgICBjb25zdCB0YXJnZXRJbmRleCA9IG9wdGlvbnMuZmluZEluZGV4KG9wdGlvbiA9PiBvcHRpb24uaWQgPT09IHRhcmdldElkKTtcblxuICAgICAgLy8gU3dhcCB0aGUgaXRlbXNcbiAgICAgIGlmIChkcmFnZ2VkSW5kZXggIT09IC0xICYmIHRhcmdldEluZGV4ICE9PSAtMSkge1xuICAgICAgICBbb3B0aW9uc1tkcmFnZ2VkSW5kZXhdLCBvcHRpb25zW3RhcmdldEluZGV4XV0gPSBbb3B0aW9uc1t0YXJnZXRJbmRleF0sIG9wdGlvbnNbZHJhZ2dlZEluZGV4XV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5kcmFnZ2VkSWQgPSBudWxsO1xuICB9XG59XG4iLCI8IS0tIEFQIDIySkFOMjUgLSBGaWVsZCBhbmQgRWxlbWVudCBQcm9wZXJ0aWVzIC0tPlxuPGRpdiBjbGFzcz1cImNvbnRhaW5lclwiPlxuICA8ZGl2IGNsYXNzPVwidGFic1wiPlxuICAgIDxkaXYgY2xhc3M9XCJ0YWJcIiBbbmdDbGFzc109XCJ7J2FjdGl2ZSc6IGFjdGl2ZVRhYiA9PT0gJ2F0dHJpYnV0ZXMnfVwiIChjbGljayk9XCJzZXRBY3RpdmVUYWIoJ2F0dHJpYnV0ZXMnKVwiPlxuICAgICAgQXR0cmlidXRlc1xuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJ0YWJcIiBbbmdDbGFzc109XCJ7J2FjdGl2ZSc6IGFjdGl2ZVRhYiA9PT0gJ3Byb3BlcnR5J31cIiAoY2xpY2spPVwic2V0QWN0aXZlVGFiKCdwcm9wZXJ0eScpXCI+XG4gICAgICBQcm9wZXJ0eVxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJ0YWJcIiBbbmdDbGFzc109XCJ7J2FjdGl2ZSc6IGFjdGl2ZVRhYiA9PT0gJ2FwcGVhcmFuY2UnfVwiIChjbGljayk9XCJzZXRBY3RpdmVUYWIoJ2FwcGVhcmFuY2UnKVwiPlxuICAgICAgQXBwZWFyYW5jZVxuICAgIDwvZGl2PlxuICA8L2Rpdj5cblxuICA8ZGl2IGNsYXNzPVwidGFiLWNvbnRlbnRcIiAqbmdJZj1cImFjdGl2ZVRhYiA9PT0gJ2F0dHJpYnV0ZXMnXCI+XG4gICAgPCEtLSBFbGVtZW50IFByb3BlcnJ0aWVzIC0tPlxuICAgIDwhLS0gQVAtMDZNQVIyNSBTZWxlY3QgZWxlbWVudCB0eXBlIHNob3cgLS0+XG4gICAgPGRpdiAqbmdJZj1cImdldFByb3BlcnRpZXMoKVwiPlxuICAgICAgPCEtLSBTS1MyNU1BUjI1IHRoaXMgaXMgZm9yIGltYWdlIGVkaXQgLS0+XG4gICAgICA8ZGl2ICpuZ0lmPVwic2VsZWN0ZWRFbGVtZW50Py50eXBlID09PSAnSW1hZ2UnXCI+XG4gICAgICAgIDxpbWFnZS1jcm9wcGVyICpuZ0lmPVwic2VsZWN0ZWRFbGVtZW50LmltYWdlRGF0YSBcIiBbaW1hZ2VCYXNlNjRdPVwic2VsZWN0ZWRFbGVtZW50Lm9yZ0ltYWdlRGF0YVwiXG4gICAgICAgICAgW2Rpc2FibGVkXT1cImZhbHNlXCIgW2FsaWduSW1hZ2VdPVwiYWxpZ25JbWFnZVwiIFtyb3VuZENyb3BwZXJdPVwicm91bmRDcm9wcGVyXCIgW2JhY2tncm91bmRDb2xvcl09XCInd2hpdGUnXCJcbiAgICAgICAgICBpbWFnZUFsdFRleHQ9XCJBbHRlcm5hdGl2ZSBpbWFnZSB0ZXh0XCIgW2FsbG93TW92ZUltYWdlXT1cImZhbHNlXCIgW2hpZGVSZXNpemVTcXVhcmVzXT1cImZhbHNlXCJcbiAgICAgICAgICBbY2FudmFzUm90YXRpb25dPVwiY2FudmFzUm90YXRpb25cIiBbYXNwZWN0UmF0aW9dPVwiYXNwZWN0UmF0aW9cIiBbY29udGFpbldpdGhpbkFzcGVjdFJhdGlvXT1cImZhbHNlXCJcbiAgICAgICAgICBbbWFpbnRhaW5Bc3BlY3RSYXRpb109XCJmYWxzZVwiIFtjcm9wcGVyU3RhdGljV2lkdGhdPVwiY3JvcHBlclN0YXRpY1dpZHRoXCJcbiAgICAgICAgICBbY3JvcHBlclN0YXRpY0hlaWdodF09XCJjcm9wcGVyU3RhdGljSGVpZ2h0XCIgW2Nyb3BwZXJNaW5XaWR0aF09XCJjcm9wcGVyTWluV2lkdGhcIlxuICAgICAgICAgIFtjcm9wcGVyTWluSGVpZ2h0XT1cImNyb3BwZXJNaW5IZWlnaHRcIiBbY3JvcHBlck1heFdpZHRoXT1cImNyb3BwZXJNYXhXaWR0aFwiXG4gICAgICAgICAgW2Nyb3BwZXJNYXhIZWlnaHRdPVwiY3JvcHBlck1heEhlaWdodFwiIFtyZXNldENyb3BPbkFzcGVjdFJhdGlvQ2hhbmdlXT0ndHJ1ZScgWyhjcm9wcGVyKV09XCJjcm9wcGVyXCJcbiAgICAgICAgICBbKHRyYW5zZm9ybSldPVwidHJhbnNmb3JtXCIgW29ubHlTY2FsZURvd25dPVwidHJ1ZVwiIG91dHB1dD1cImJsb2JcIiBmb3JtYXQ9XCJwbmdcIlxuICAgICAgICAgIChpbWFnZUNyb3BwZWQpPVwiaW1hZ2VDcm9wcGVkKCRldmVudClcIiAoY3JvcHBlclJlYWR5KT1cImNyb3BwZXJSZWFkeSgkZXZlbnQpXCI+PC9pbWFnZS1jcm9wcGVyPlxuICAgICAgICA8ZGl2ICpuZ0lmPVwic2VsZWN0ZWRFbGVtZW50LmltYWdlRGF0YSBcIiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGdhcDogMnB4O1wiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjdXJzb3ItcG9pbnRlciBsb2dvLWljb25cIiAoY2xpY2spPVwicm90YXRlTGVmdCgpXCIgdGl0bGU9XCJSb3RhdGUgTGVmdFwiPuKfsjwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjdXJzb3ItcG9pbnRlciBsb2dvLWljb25cIiAoY2xpY2spPVwicm90YXRlUmlnaHQoKVwiIHRpdGxlPVwiUm90YXRlIFJpZ2h0XCI+4p+zPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImN1cnNvci1wb2ludGVyIGxvZ28taWNvblwiIChjbGljayk9XCJ6b29tT3V0KClcIiB0aXRsZT1cIlpvb20gT3V0XCI+LTwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjdXJzb3ItcG9pbnRlciBsb2dvLWljb25cIiAoY2xpY2spPVwiem9vbUluKClcIiB0aXRsZT1cIlpvb20gSW5cIj4rPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImN1cnNvci1wb2ludGVyIGxvZ28taWNvblwiIChjbGljayk9XCJtb3ZlTGVmdCgpXCIgdGl0bGU9XCJNb3ZlIExlZnRcIj7ihpA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3Vyc29yLXBvaW50ZXIgbG9nby1pY29uXCIgKGNsaWNrKT1cIm1vdmVSaWdodCgpXCIgdGl0bGU9XCJNb3ZlIFJpZ2h0XCI+4oaSPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImN1cnNvci1wb2ludGVyIGxvZ28taWNvblwiIChjbGljayk9XCJtb3ZlVXAoKVwiIHRpdGxlPVwiTW92ZSBVcFwiPuKGkTwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjdXJzb3ItcG9pbnRlciBsb2dvLWljb25cIiAoY2xpY2spPVwibW92ZURvd24oKVwiIHRpdGxlPVwiTW92ZSBEb3duXCI+4oaTPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImN1cnNvci1wb2ludGVyIGxvZ28taWNvblwiIChjbGljayk9XCJmbGlwSG9yaXpvbnRhbCgpXCIgW2NsYXNzLmVuYWJsZWRdPVwidHJhbnNmb3JtLmZsaXBIXCJcbiAgICAgICAgICAgIHRpdGxlPVwiRmxpcCBIb3Jpem9udGFsbHlcIj7ihpQ8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3Vyc29yLXBvaW50ZXIgbG9nby1pY29uXCIgKGNsaWNrKT1cImZsaXBWZXJ0aWNhbCgpXCIgW2NsYXNzLmVuYWJsZWRdPVwidHJhbnNmb3JtLmZsaXBWXCJcbiAgICAgICAgICAgIHRpdGxlPVwiRmxpcCBWZXJ0aWNhbGx5XCI+4oaVPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImN1cnNvci1wb2ludGVyIGxvZ28taWNvblwiIChjbGljayk9XCJyZXNldEltYWdlKClcIiB0aXRsZT1cIlJlc2V0XCI+w5c8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICAgIDwhLS0gU0tTMjhNQVIyNSBzZWFyY2ggYm9vayBzcGVjaWZpYyBmb3IgYm9vayBlbGVtZW50IC0tPlxuICAgICAgPGRpdiAqbmdJZj1cInNlbGVjdGVkRWxlbWVudD8udHlwZSA9PT0gJ0Jvb2snXCI+XG4gICAgICAgIDxsYWJlbCBjbGFzcz1cInRleHQtc21cIj5TZWFyY2ggQm9vazwvbGFiZWw+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBnYXA6IDJweDsgYWxpZ24taXRlbXM6IGNlbnRlcjsganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XCI+XG4gICAgICAgICAgPG54dC1zZWFyY2gtYm94IFtxdWVzdGlvbl09XCJzZWxlY3RlZEVsZW1lbnRcIiBbYXBpTWV0YV09XCJib29rU3VidGV4dFwiIFtwbGFjZUhvbGRlclRleHRdPVwiJ1NlYXJjaC4uLidcIlxuICAgICAgICAgICAgKHNlYXJjaFZhbHVlQ2hhbmdlKT1cImNoaWxkRXZlbnRDYXB0dXJlKCRldmVudC52YWx1ZSlcIj5cbiAgICAgICAgICA8L254dC1zZWFyY2gtYm94PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJsaW5rLWljb25cIj5cbiAgICAgICAgICAgIDxzdmcgKGNsaWNrKT1cImxpbmtUb2dnbGVEcm9wZG93bigkZXZlbnQpXCIgZmlsbD1cIiMwMDAwMDBcIiB2ZXJzaW9uPVwiMS4xXCIgaWQ9XCJDYXBhXzFcIlxuICAgICAgICAgICAgICB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgd2lkdGg9XCIyNHB4XCIgaGVpZ2h0PVwiMjRweFwiXG4gICAgICAgICAgICAgIHZpZXdCb3g9XCIwIDAgNDUwIDQ1MFwiIHhtbDpzcGFjZT1cInByZXNlcnZlXCI+XG4gICAgICAgICAgICAgIDxnPlxuICAgICAgICAgICAgICAgIDxnPlxuICAgICAgICAgICAgICAgICAgPGc+XG4gICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMzE4LjE1LDIzMC4xOTVsNzcuOTM0LTc3LjkzN2MzMS44OTQtMzEuODkyLDMxLjg5NC04My43ODItMC4wMDQtMTE1LjY3NGwtMTIuNjYtMTIuNjZcbiAgICAgICAgICBjLTMxLjg5My0zMS44OTYtODMuNzgtMzEuODk2LTExNS42NzQtMC4wMDRsLTc3LjkzNyw3Ny45MzRjLTE3LjU4OCwxNy41ODgtMjUuNDU3LDQxLjI2NC0yMy42NDYsNjQuMzExXG4gICAgICAgICAgYy0yMy4wNDUtMS44MTMtNDYuNzIyLDYuMDU2LTY0LjMwOCwyMy42NDdMMjMuOTIsMjY3Ljc0OGMtMzEuODk0LDMxLjg4OS0zMS44OTQsODMuNzc5LDAsMTE1LjY3NGwxMi42NjQsMTIuNjYyXG4gICAgICAgICAgYzMxLjg5MywzMS44OTMsODMuNzgzLDMxLjg5MywxMTUuNjc0LDBsNzcuOTM1LTc3LjkzNmMxNy41OTItMTcuNTksMjUuNDU5LTQxLjI2NiwyMy42NDctNjQuMzA5XG4gICAgICAgICAgQzI3Ni44ODQsMjU1LjY1NCwzMDAuNTYsMjQ3Ljc4MywzMTguMTUsMjMwLjE5NXogTTIwMi42NTMsMjkwLjYwNWwtNzcuOTM2LDc3LjkzOGMtMTYuNzA1LDE2LjcwMy00My44ODksMTYuNzAzLTYwLjU5LDBcbiAgICAgICAgICBsLTEyLjY2Ni0xMi42NjZjLTE2LjcwNS0xNi43MDEtMTYuNzAzLTQzLjg4NSwwLTYwLjU5NGw3Ny45MzYtNzcuOTMyYzE0LjE0LTE0LjE0MSwzNS43NzktMTYuMzA2LDUyLjIyNi02LjUxNmwtMzIuMzAyLDMyLjMwN1xuICAgICAgICAgIGMtNy42MDYsNy42MDQtNy42MDYsMTkuOTM4LDAsMjcuNTQxYzcuNjA1LDcuNjA3LDE5LjkzNyw3LjYwNywyNy41NDEsMGwzMi4zMDYtMzIuMzAzXG4gICAgICAgICAgQzIxOC45NTksMjU0LjgyOCwyMTYuNzk1LDI3Ni40NjksMjAyLjY1MywyOTAuNjA1eiBNMjM4LjM4MiwyMDkuMTY5bDMyLjI5OS0zMi4zMDZjNy42MDgtNy42MDIsNy42MDgtMTkuOTM1LDAtMjcuNTM4XG4gICAgICAgICAgYy03LjYwNC03LjYxLTE5LjkzNi03LjYxLTI3LjU0MS0wLjAwNGwtMzIuMzAzLDMyLjMwM2MtOS43OTEtMTYuNDQ2LTcuNjI3LTM4LjA4Nyw2LjUxNC01Mi4yMjZsNzcuOTM1LTc3LjkzNVxuICAgICAgICAgIGMxNi43MDctMTYuNzA3LDQzLjg5LTE2LjcwNyw2MC41OTQsMGwxMi42NjQsMTIuNjY0YzE2LjcwNSwxNi43MDUsMTYuNzA1LDQzLjg4NiwwLDYwLjU5MWwtNzcuOTM2LDc3LjkzN1xuICAgICAgICAgIEMyNzYuNDY4LDIxNi43OTcsMjU0LjgyOCwyMTguOTU5LDIzOC4zODIsMjA5LjE2OXpcIiAvPlxuICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTM0My40NjYsMjYxLjQ2NWMtNDUuMjg3LDAtODIsMzYuNzEzLTgyLDgyczM2LjcxMyw4Miw4Miw4MmM0NS4yODYsMCw4Mi0zNi43MTMsODItODJTMzg4Ljc1MywyNjEuNDY1LDM0My40NjYsMjYxLjQ2NXpcbiAgICAgICAgICAgTTM3Mi41MDUsMzMzLjU2NGwtNTYuMDQ2LDU2LjEwNGMtMC4yMzksMC4yMzgtMC41MzYsMC40MS0wLjg2MiwwLjQ5NmwtMjIuMzE1LDUuODVjLTAuNjQ5LDAuMTY4LTEuMzQ3LTAuMDItMS44MjItMC40OTRcbiAgICAgICAgICBjLTAuNDc3LTAuNDc5LTAuNjY2LTEuMTcyLTAuNDk2LTEuODI0bDUuODI2LTIyLjMxOGMwLjA4NC0wLjMyNiwwLjI1Ni0wLjYyNywwLjQ5NC0wLjg2M2w1Ni4wNDctNTYuMTA0XG4gICAgICAgICAgYzAuNzQyLTAuNzQyLDEuOTQ1LTAuNzQ0LDIuNjg4LTAuMDAybDQuNTQ4LDQuNTQxYzAuNzM5LDAuNzQsMC43NDEsMS45NDMsMCwyLjY4OGwtMzcuNDMzLDM3LjQ3MWw0LjcwOSw0LjcwM2wzNy40MzUtMzcuNDcxXG4gICAgICAgICAgYzAuNzM5LTAuNzQyLDEuOTQtMC43NDIsMi42ODItMC4wMDJsNC41NSw0LjU0MUMzNzMuMjUsMzMxLjYxNywzNzMuMjUsMzMyLjgyMiwzNzIuNTA1LDMzMy41NjR6IE0zOTUuNDcyLDMxMC41NzRsLTE3LDE3LjAxOFxuICAgICAgICAgIGMtMC43MzksMC43NDQtMS45NDIsMC43NDQtMi42ODUsMC4wMDJsLTE2LjQ4OS0xNi40NzVjLTAuNzQ0LTAuNzQtMC43NDQtMS45NDMtMC4wMDItMi42ODhsMTctMTcuMDJcbiAgICAgICAgICBjMC43NDEtMC43NCwxLjk0NC0wLjc0LDIuNjg4LTAuMDAybDE2LjQ4NywxNi40NzdDMzk2LjIxNiwzMDguNjI5LDM5Ni4yMTYsMzA5LjgzMiwzOTUuNDcyLDMxMC41NzR6XCIgLz5cbiAgICAgICAgICAgICAgICAgIDwvZz5cbiAgICAgICAgICAgICAgICA8L2c+XG4gICAgICAgICAgICAgIDwvZz5cbiAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxpbmstZHJvcGRvd24tbWVudVwiICpuZ0lmPVwiaXNMaW5rRHJvcGRvd25PcGVuXCIgI2Ryb3Bkb3duPlxuICAgICAgICAgICAgICA8bGFiZWw+RW5kcG9pbnQ6PC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgWyhuZ01vZGVsKV09XCJib29rU3VidGV4dC5lbmRwb2ludFwiIC8+XG5cbiAgICAgICAgICAgICAgPGxhYmVsPlZhcmlhYmxlOjwvbGFiZWw+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIFsobmdNb2RlbCldPVwiYm9va1N1YnRleHQudmFyaWFibGVcIiAvPlxuXG4gICAgICAgICAgICAgIDxsYWJlbD5GaWVsZDo8L2xhYmVsPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBbbmdNb2RlbF09XCJmaWVsZEFzU3RyaW5nXCIgKG5nTW9kZWxDaGFuZ2UpPVwidXBkYXRlRmllbGQoJGV2ZW50KVwiIC8+XG5cbiAgICAgICAgICAgICAgPGxhYmVsPkRlZmF1bHQgRmllbGQ6PC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgWyhuZ01vZGVsKV09XCJib29rU3VidGV4dC5kZWZhdWx0RmllbGRcIiAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBwcm9wIG9mIGdldFByb3BlcnRpZXMoKS5lbGVtZW50UHJvcHNcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICAgICAgICA8bGFiZWwgKm5nSWY9XCJwcm9wLnR5cGUgIT09ICdjaGVja2JveCcgJiYgcHJvcC50eXBlICE9PSAnc3ViUXVlc3Rpb24nXCIgY2xhc3M9XCJ0ZXh0LXNtXCI+e3sgcHJvcC5sYWJlbFxuICAgICAgICAgICAgfX08L2xhYmVsPlxuXG4gICAgICAgICAgPCEtLSBUZXh0IElucHV0IC0tPlxuICAgICAgICAgIDxpbnB1dCAqbmdJZj1cInByb3AudHlwZSA9PT0gJ3RleHQnXCIgdHlwZT1cInRleHRcIiBbcGxhY2Vob2xkZXJdPVwicHJvcC5wbGFjZWhvbGRlclwiXG4gICAgICAgICAgICBbdmFsdWVdPVwiaGVhZGVyU2VsZWN0ID8gYm9vay5yZWNvcmRzWzBdLnRpdGxlIDogKHNlbGVjdGVkRWxlbWVudD8udHlwZSA9PT0gJ1RhYmxlJyA/IChwcm9wLnRhcmdldEFycmF5ID8gZ2V0VmFsdWVCeUFycmF5UGF0aChwcm9wLnRhcmdldEFycmF5LCBwcm9wLnRhcmdldEFycmF5S2V5LCBzZWxlY3RDb2x1bW4sIHByb3Aua2V5ICkgOiBnZXRWYWx1ZUJ5UGF0aChwcm9wLmtleSkgKSA6ICBnZXRWYWx1ZUJ5UGF0aChwcm9wLmtleSkpXCJcbiAgICAgICAgICAgIChpbnB1dCk9XCJoZWFkZXJTZWxlY3QgPyB1cGRhdGVUaXRsZSgkZXZlbnQudGFyZ2V0LnZhbHVlKSA6IChzZWxlY3RlZEVsZW1lbnQ/LnR5cGUgPT09ICdUYWJsZScgPyAocHJvcC50YXJnZXRBcnJheSA/IHVwZGF0ZVZhbHVlQnlBcnJheVBhdGgocHJvcC50YXJnZXRBcnJheSwgcHJvcC50YXJnZXRBcnJheUtleSwgc2VsZWN0Q29sdW1uLCBwcm9wLmtleSwgJGV2ZW50KSA6IHNldFZhbHVlQnlQYXRoKHByb3Aua2V5LCAkZXZlbnQudGFyZ2V0LnZhbHVlKSApIDogc2V0VmFsdWVCeVBhdGgocHJvcC5rZXksICRldmVudC50YXJnZXQudmFsdWUpKVwiXG4gICAgICAgICAgICBbY2xhc3MucmVhZC1vbmx5XT1cInNlbGVjdGVkRWxlbWVudC5yZWFkT25seVwiIFtyZWFkb25seV09XCJzZWxlY3RlZEVsZW1lbnQucmVhZE9ubHlcIiAvPlxuXG4gICAgICAgICAgPCEtLSBoZWxwIHRleHQgLS0+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cInByb3Aua2V5ID09PSAnaGVscFRleHQnICYmIHNlbGVjdGVkRWxlbWVudC5oZWxwVGV4dFwiPnt7XG4gICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnQuaGVscFRleHQgfX08L2Rpdj5cblxuICAgICAgICAgIDwhLS0gcXVlc3Rpb25OdW1iZXIgLS0+XG4gICAgICAgICAgPGlucHV0ICpuZ0lmPVwicHJvcC5rZXkgPT09ICdxdWVzdGlvbk51bWJlcidcIiB0eXBlPVwibnVtYmVyXCIgW3ZhbHVlXT1cInNlbGVjdGVkRWxlbWVudC5xdWVzdGlvbk51bWJlclwiXG4gICAgICAgICAgICAoaW5wdXQpPVwic2V0VmFsdWVCeVBhdGgoJ3F1ZXN0aW9uTnVtYmVyJywgJGV2ZW50LnRhcmdldC52YWx1ZSlcIiAvPlxuXG4gICAgICAgICAgPCEtLSBmaWxlIC0tPlxuICAgICAgICAgIDwhLS0gQWRkIHRoaXMgaW5zaWRlIHRoZSBlbGVtZW50UHJvcHMgbG9vcCB3aGVyZSBvdGhlciBpbnB1dHMgYXJlIHJlbmRlcmVkIC0tPlxuICAgICAgICAgIDxzZWxlY3QgKm5nSWY9XCJwcm9wLnR5cGUgPT09ICdzZWxlY3QnICYmIHByb3Aua2V5ID09PSAnc3VwcG9ydFR5cGUnXCIgW3ZhbHVlXT1cInNlbGVjdGVkRWxlbWVudFtwcm9wLmtleV1cIlxuICAgICAgICAgICAgKGNoYW5nZSk9XCJzZXRWYWx1ZUJ5UGF0aChwcm9wLmtleSwgJGV2ZW50LnRhcmdldC52YWx1ZSlcIj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj5TZWxlY3QgZmlsZSBjYXRlZ29yeTwvb3B0aW9uPlxuICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIHByb3Aub3B0aW9uc1wiIFt2YWx1ZV09XCJvcHRpb24udmFsdWVcIj4ge3sgb3B0aW9uLmxhYmVsIH19IDwvb3B0aW9uPlxuICAgICAgICAgIDwvc2VsZWN0PlxuXG4gICAgICAgICAgPGRpdiAqbmdJZj1cInByb3AudHlwZSA9PT0gJ2NoZWNrYm94J1wiPlxuXG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCJcbiAgICAgICAgICAgICAgW2NoZWNrZWRdPVwic2VsZWN0ZWRFbGVtZW50LnR5cGUgPT09ICdUYWJsZScgPyAocHJvcC50YXJnZXRBcnJheSA/IGdldFZhbHVlQnlBcnJheVBhdGgocHJvcC50YXJnZXRBcnJheSwgcHJvcC50YXJnZXRBcnJheUtleSwgc2VsZWN0Q29sdW1uLCBwcm9wLmtleSApIDogZ2V0VmFsdWVCeVBhdGgocHJvcC5rZXkpICk6ICBnZXRWYWx1ZUJ5UGF0aChwcm9wLmtleSkgXCJcbiAgICAgICAgICAgICAgKGNoYW5nZSk9XCIgc2VsZWN0ZWRFbGVtZW50LnR5cGUgPT09ICdUYWJsZScgPyAocHJvcC50YXJnZXRBcnJheSA/IHVwZGF0ZVZhbHVlQnlBcnJheVBhdGgocHJvcC50YXJnZXRBcnJheSwgcHJvcC50YXJnZXRBcnJheUtleSwgc2VsZWN0Q29sdW1uLCBwcm9wLmtleSwgJGV2ZW50KSA6IG9uVG9nZ2xlQ2hhbmdlKHByb3Aua2V5LCAkZXZlbnQpICkgOiBvblRvZ2dsZUNoYW5nZShwcm9wLmtleSwgJGV2ZW50KVwiIC8+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidG9nZ2xlLWxhYmVsXCIgc3R5bGU9XCJwYWRkaW5nLWxlZnQ6IDEwcHg7XCI+e3sgcHJvcC5sYWJlbCB9fTwvc3Bhbj5cblxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLUFQLTExSlVOMjUgLSBTaG93IHRoaXMgc2VjdGlvbiBvbmx5IGlmIHRoZSBwcm9wZXJ0eSBrZXkgaXMgJ3ByaW1hcnlLZXknIC0tPlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJwcm9wLmtleSA9PT0gJ3ByaW1hcnlLZXknXCI+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgW2NoZWNrZWRdPVwiZ2V0VmFsdWVCeVBhdGgoJ3ByaW1hcnlLZXknKVwiIFtkaXNhYmxlZF09XCIhZ2V0VmFsdWVCeVBhdGgoJ3ByaW1hcnlLZXknKSAmJiBpc0Fub3RoZXJJZFNlbGVjdGVkKClcIiAoY2hhbmdlKT1cIm9uVG9nZ2xlQ2hhbmdlKCdwcmltYXJ5S2V5JywgJGV2ZW50KVwiLz5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidG9nZ2xlLWxhYmVsXCIgc3R5bGU9XCJwYWRkaW5nLWxlZnQ6IDEwcHg7XCI+cHJpbWFyeUtleTwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDwhLS0gU0tTMjBNQVIyNSBTdWJxdWVzdGlvbiBUeXBlIC0tPlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJwcm9wLnR5cGUgPT09ICdzdWJRdWVzdGlvbidcIj5cbiAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBmbGV4LWRpcmVjdGlvbjogcm93OyBnYXA6IDEwcHg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7XCI+XG4gICAgICAgICAgICAgIDxkaXY+e3sgcHJvcC5sYWJlbCB9fTwvZGl2PlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCJcbiAgICAgICAgICAgICAgICBbY2hlY2tlZF09XCJzZWxlY3RlZEVsZW1lbnQudHlwZSA9PT0gJ1RhYmxlJyA/IChwcm9wLnRhcmdldEFycmF5ID8gZ2V0VmFsdWVCeUFycmF5UGF0aChwcm9wLnRhcmdldEFycmF5LCBwcm9wLnRhcmdldEFycmF5S2V5LCBzZWxlY3RDb2x1bW4sIHByb3Aua2V5ICkgOiBnZXRWYWx1ZUJ5UGF0aChwcm9wLmtleSkgKTogIGdldFZhbHVlQnlQYXRoKHByb3Aua2V5KSBcIlxuICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwiIHNlbGVjdGVkRWxlbWVudC50eXBlID09PSAnVGFibGUnID8gKHByb3AudGFyZ2V0QXJyYXkgPyB1cGRhdGVWYWx1ZUJ5QXJyYXlQYXRoKHByb3AudGFyZ2V0QXJyYXksIHByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbiwgcHJvcC5rZXksICRldmVudCkgOiBvblRvZ2dsZUNoYW5nZShwcm9wLmtleSwgJGV2ZW50KSApIDogb25Ub2dnbGVDaGFuZ2UocHJvcC5rZXksICRldmVudClcIiAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8IS0tIFNLUzIwTUFSMjUgUmVuZGVyIHN1YnF1ZXN0aW9ucyB3aGVuIGNoZWNrYm94IGlzIGNoZWNrZWQgLS0+XG4gICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICpuZ0lmPVwic2VsZWN0ZWRFbGVtZW50LnR5cGUgPT09ICdUYWJsZScgPyAocHJvcC50YXJnZXRBcnJheSA/IGdldFZhbHVlQnlBcnJheVBhdGgocHJvcC50YXJnZXRBcnJheSwgcHJvcC50YXJnZXRBcnJheUtleSwgc2VsZWN0Q29sdW1uLCBwcm9wLmtleSApIDogZ2V0VmFsdWVCeVBhdGgocHJvcC5rZXkpICk6ICBnZXRWYWx1ZUJ5UGF0aChwcm9wLmtleSlcIj5cbiAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgc3ViUHJvcCBvZiBwcm9wLnN1YlF1ZXN0aW9uXCJcbiAgICAgICAgICAgICAgICBzdHlsZT1cImJhY2tncm91bmQtY29sb3I6ICNlN2YyZmY7IHBhZGRpbmc6IDhweDsgYm9yZGVyLXJhZGl1czogNHB4O1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICA8bGFiZWw+e3sgc3ViUHJvcC5sYWJlbCB9fTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwic3ViUHJvcC50eXBlID09PSAnYXJyYXknXCI+XG4gICAgICAgICAgICAgICAgICAgIDwhLS0gSXRlcmF0ZSBvdmVyIGZpbHRlcmVkIGNvbHVtbnMgdG8gZGlzcGxheSBjaGVja2JveGVzIC0tPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgZmlsdGVyZWRDb2x1bW5zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPGxhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cInN1YlByb3Aub3BlcmFuZHMgPyBzdWJQcm9wLm9wZXJhbmRzLmluY2x1ZGVzKGNvbHVtbi5hcGlOYW1lKSA6IGZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJvbkNoZWNrYm94Q2hhbmdlKHN1YlByb3AudGFyZ2V0QXJyYXksc3ViUHJvcC50YXJnZXRBcnJheUtleSxzdWJQcm9wLmtleSwgY29sdW1uLmFwaU5hbWUsICRldmVudC50YXJnZXQuY2hlY2tlZClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7IGNvbHVtbi5hcGlOYW1lIH19XG4gICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDwhLS0gU0tTMjFNQVIyNSBOZXcgcmFkaW8gdHlwZSAtLT5cbiAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJzdWJQcm9wLnR5cGUgPT09ICdyYWRpbydcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGZpbHRlcmVkQ29sdW1uc1wiPlxuICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwicmFkaW9cIiBbbmFtZV09XCJzdWJQcm9wLmtleVwiIFt2YWx1ZV09XCJjb2x1bW4uYXBpTmFtZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cImdldFZhbHVlQnlBcnJheVBhdGgoc3ViUHJvcC50YXJnZXRBcnJheSwgc3ViUHJvcC50YXJnZXRBcnJheUtleSwgc2VsZWN0Q29sdW1uLCBzdWJQcm9wLmtleSkgPT09IGNvbHVtbi5hcGlOYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJvblJhZGlvQ2hhbmdlKHN1YlByb3AudGFyZ2V0QXJyYXksIHN1YlByb3AudGFyZ2V0QXJyYXlLZXksIHN1YlByb3Aua2V5LCBjb2x1bW4uYXBpTmFtZSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7IGNvbHVtbi5hcGlOYW1lIH19XG4gICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDwhLS0gU0tTMjBNQVIyNSBBZGQgbW9yZSBzdWJwcm9wZXJ0eSB0eXBlcyBhcyBuZWVkZWQgLS0+XG4gICAgICAgICAgICAgICAgICA8IS0tIEluc2lkZSB0aGUgc3ViUHJvcCBuZ0ZvciBsb29wIC0tPlxuICAgICAgICAgICAgICAgICAgPGlucHV0ICpuZ0lmPVwic3ViUHJvcC50eXBlID09PSAndGV4dCdcIiB0eXBlPVwidGV4dFwiIFtwbGFjZWhvbGRlcl09XCJzdWJQcm9wLnBsYWNlaG9sZGVyXCJcbiAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cInNlbGVjdGVkRWxlbWVudC50eXBlID09PSAnVGFibGUnID8gKHN1YlByb3AudGFyZ2V0QXJyYXkgPyBnZXRWYWx1ZUJ5QXJyYXlQYXRoKHN1YlByb3AudGFyZ2V0QXJyYXksIHN1YlByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbiwgc3ViUHJvcC5rZXkgKSA6IGdldFZhbHVlQnlQYXRoKHN1YlByb3Aua2V5KSApIDogZ2V0VmFsdWVCeVBhdGgoc3ViUHJvcC5rZXkpXCJcbiAgICAgICAgICAgICAgICAgICAgKGlucHV0KT1cInNlbGVjdGVkRWxlbWVudC50eXBlID09PSAnVGFibGUnID8gKHN1YlByb3AudGFyZ2V0QXJyYXkgPyB1cGRhdGVWYWx1ZUJ5QXJyYXlQYXRoKHN1YlByb3AudGFyZ2V0QXJyYXksIHN1YlByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbiwgc3ViUHJvcC5rZXksICRldmVudCkgOiBzZXRWYWx1ZUJ5UGF0aChzdWJQcm9wLmtleSwgJGV2ZW50LnRhcmdldC52YWx1ZSkgKSA6IHNldFZhbHVlQnlQYXRoKHN1YlByb3Aua2V5LCAkZXZlbnQudGFyZ2V0LnZhbHVlKVwiIC8+XG5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dCAqbmdJZj1cInN1YlByb3AudHlwZSA9PT0gJ2Jvb2xlYW4nXCIgdHlwZT1cImNoZWNrYm94XCIgW2NoZWNrZWRdPVwiZ2V0VmFsdWVCeVBhdGgoc3ViUHJvcC5rZXkpXCJcbiAgICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJzZXRWYWx1ZUJ5UGF0aChzdWJQcm9wLmtleSwgJGV2ZW50LnRhcmdldC5jaGVja2VkKVwiIC8+XG4gICAgICAgICAgICAgICAgICA8c2VsZWN0ICpuZ0lmPVwic3ViUHJvcC50eXBlID09PSAnc2VsZWN0J1wiIFt2YWx1ZV09XCJnZXRWYWx1ZUJ5UGF0aChzdWJQcm9wLmtleSlcIlxuICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInNldFZhbHVlQnlQYXRoKHN1YlByb3Aua2V5LCAkZXZlbnQudGFyZ2V0LnZhbHVlKVwiPlxuICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBvcHRpb24gb2Ygc3ViUHJvcC5vcHRpb25zXCIgW3ZhbHVlXT1cIm9wdGlvblwiPnt7IG9wdGlvbiB9fTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICA8aW5wdXQgKm5nSWY9XCJzdWJQcm9wLnR5cGUgPT09ICdjaGVja2JveCdcIiB0eXBlPVwiY2hlY2tib3hcIiBbY2hlY2tlZF09XCJnZXRWYWx1ZUJ5UGF0aChzdWJQcm9wLmtleSlcIlxuICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInNldFZhbHVlQnlQYXRoKHN1YlByb3Aua2V5LCAkZXZlbnQudGFyZ2V0LmNoZWNrZWQpXCIgLz5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDwhLS0gU0tTMjBNQVIyNSBUZXh0IEFsaWduIEJ1dHRvbnMgLS0+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cInByb3AudHlwZSA9PT0gJ2FsaWduJ1wiPlxuICAgICAgICAgICAgPGJ1dHRvbiAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIHByb3Aub3B0aW9uc1wiIChjbGljayk9XCJvbkFsaWduU2VsZWN0KG9wdGlvbi52YWx1ZSlcIlxuICAgICAgICAgICAgICBbY2xhc3MuYWN0aXZlXT1cInNlbGVjdGVkRWxlbWVudD8udGV4dEFsaWduID09PSBvcHRpb24udmFsdWVcIiBbdGl0bGVdPVwib3B0aW9uLnZhbHVlXCI+XG4gICAgICAgICAgICAgIDxpbWcgW3NyY109XCInLi4vYXNzZXRzL2ljb25zLycgKyBvcHRpb24uaWNvbiArICcuc3ZnJ1wiIFthbHRdPVwib3B0aW9uLnZhbHVlXCIgY2xhc3M9XCJpY29uLXNpemVcIiAvPlxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwicHJvcC50eXBlID09PSAnc3R5bGUnXCI+XG4gICAgICAgICAgICA8YnV0dG9uICpuZ0Zvcj1cImxldCBvcHRpb24gb2YgcHJvcC5vcHRpb25zXCIgKGNsaWNrKT1cIm9uU3R5bGVTZWxlY3Qob3B0aW9uLnZhbHVlKVwiXG4gICAgICAgICAgICAgIFtjbGFzcy5hY3RpdmVdPVwiaXNTdHlsZUFjdGl2ZShvcHRpb24udmFsdWUpXCIgW3RpdGxlXT1cIm9wdGlvbi52YWx1ZVwiPlxuICAgICAgICAgICAgICA8aW1nIFtzcmNdPVwiJy4uL2Fzc2V0cy9pY29ucy8nICsgb3B0aW9uLmljb24gKyAnLnN2ZydcIiBbYWx0XT1cIm9wdGlvbi52YWx1ZVwiIGNsYXNzPVwiaWNvbi1zaXplXCIgLz5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBGaWVsZCBTaXplIENvbnRyb2xzIC0tPlxuICAgICAgICAgIDwhLS0gQVAgMjVGRUIyNSAtIENoYW5nZSBrZXkgc2l6ZSAtLT5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwicHJvcC5rZXkgPT09ICdzaXplJ1wiPlxuICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBbdmFsdWVdPVwic2VsZWN0ZWRFbGVtZW50Py5zaXplXCIgKGlucHV0KT1cInNldFZhbHVlQnlQYXRoKCdzaXplJywgJGV2ZW50LnRhcmdldC52YWx1ZSlcIlxuICAgICAgICAgICAgICBjbGFzcz1cInNpemUtaW5wdXRcIiAvPlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBBUC0xOU1BUjI1IExpbmUgUHJvcGVydGllcyAtLT5cbiAgICAgICAgICA8IS0tIFBhZGRpbmcgVG9wIC0tPlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJwcm9wLmtleSA9PT0gJ3BhZGRpbmdUb3AnXCI+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiIFtwbGFjZWhvbGRlcl09XCJwcm9wLnBsYWNlaG9sZGVyXCIgW3ZhbHVlXT1cInNlbGVjdGVkRWxlbWVudD8ucGFkZGluZ1RvcFwiXG4gICAgICAgICAgICAgIChpbnB1dCk9XCJzZXRWYWx1ZUJ5UGF0aCgncGFkZGluZ1RvcCcsICRldmVudC50YXJnZXQudmFsdWUpXCIgLz5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDwhLS0gUGFkZGluZyBCb3R0b20gLS0+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cInByb3Aua2V5ID09PSAncGFkZGluZ0JvdHRvbSdcIj5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgW3BsYWNlaG9sZGVyXT1cInByb3AucGxhY2Vob2xkZXJcIiBbdmFsdWVdPVwic2VsZWN0ZWRFbGVtZW50Py5wYWRkaW5nQm90dG9tXCJcbiAgICAgICAgICAgICAgKGlucHV0KT1cInNldFZhbHVlQnlQYXRoKCdwYWRkaW5nQm90dG9tJywgJGV2ZW50LnRhcmdldC52YWx1ZSlcIiAvPlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBMaW5lIFN0eWxlIC0tPlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJwcm9wLmtleSA9PT0gJ2xpbmVTdHlsZSdcIj5cbiAgICAgICAgICAgIDxzZWxlY3QgW3ZhbHVlXT1cInNlbGVjdGVkRWxlbWVudD8ubGluZVN0eWxlXCIgKGNoYW5nZSk9XCJzZXRWYWx1ZUJ5UGF0aCgnbGluZVN0eWxlJywgJGV2ZW50LnRhcmdldC52YWx1ZSlcIj5cbiAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIHByb3Aub3B0aW9uc1wiIFt2YWx1ZV09XCJvcHRpb25cIj57eyBvcHRpb24gfX08L29wdGlvbj5cbiAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBDb2xvciAtLT5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwicHJvcC5rZXkgPT09ICdjb2xvcidcIj5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY29sb3JcIiBbdmFsdWVdPVwic2VsZWN0ZWRFbGVtZW50Py5jb2xvclwiXG4gICAgICAgICAgICAgIChpbnB1dCk9XCJzZXRWYWx1ZUJ5UGF0aCgnY29sb3InLCAkZXZlbnQudGFyZ2V0LnZhbHVlKVwiIC8+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIFxuICAgICAgICAgPCEtLSBBUCAyM01BWTI1IC0gQWN0aW9uIEJ1dHRvbiAtLT5cbiAgICAgICAgPGRpdiAqbmdJZj1cInByb3Aua2V5ID09PSAndGl0bGUnXCIgc3R5bGU9XCJtYXJnaW4tdG9wOiAxNXB4OyBib3JkZXI6IDFweCBzb2xpZCAjZGRkOyBwYWRkaW5nOiAyMHB4OyBib3JkZXItcmFkaXVzOiAxMnB4OyBiYWNrZ3JvdW5kLWNvbG9yOiAjZjlmOWY5O1wiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWhlYWRlclwiPlxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbFwiPnt7IHByb3AubGFiZWwgfX08L2xhYmVsPlxuICAgICAgICAgICAgPGJ1dHRvbiAoY2xpY2spPVwiYWRkTmV3QnV0dG9uKClcIiBjbGFzcz1cImFkZC1idXR0b25cIj4rIEFkZCBCdXR0b248L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgXG4gICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgYnRuIG9mIGJvb2s/LnF1ZXN0aW9uYm9vaz8uYWN0aW9uIHx8IFtdOyBsZXQgaSA9IGluZGV4XCIgY2xhc3M9XCJidXR0b24tY29uZmlnLWNhcmRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICAgIDxsYWJlbD5CdXR0b24gTmFtZTwvbGFiZWw+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIFsobmdNb2RlbCldPVwiYnRuLm5hbWVcIiAobmdNb2RlbENoYW5nZSk9XCJvbkJ1dHRvblByb3BlcnR5Q2hhbmdlKGksICduYW1lJywgJGV2ZW50KVwiIHBsYWNlaG9sZGVyPVwiRW50ZXIgYnV0dG9uIG5hbWVcIj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICBcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICAgIDxsYWJlbD5FdmVudCBOYW1lPC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgWyhuZ01vZGVsKV09XCJidG4uZXZlbnR0b2VtaXRcIiAobmdNb2RlbENoYW5nZSk9XCJvbkJ1dHRvblByb3BlcnR5Q2hhbmdlKGksICdldmVudHRvZW1pdCcsICRldmVudClcIiBwbGFjZWhvbGRlcj1cIkV2ZW50IHRvIGVtaXRcIj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICBcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICAgIDxsYWJlbD5BbHQ8L2xhYmVsPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBbKG5nTW9kZWwpXT1cImJ0bi5hbHRcIiAobmdNb2RlbENoYW5nZSk9XCJvbkJ1dHRvblByb3BlcnR5Q2hhbmdlKGksICdhbHQnLCAkZXZlbnQpXCIgcGxhY2Vob2xkZXI9XCJCdXR0b24gYWx0IHRleHRcIj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICBcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICAgIDxsYWJlbD5FbmRwb2ludDwvbGFiZWw+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIFsobmdNb2RlbCldPVwiYnRuLmVuZHBvaW50XCIgKG5nTW9kZWxDaGFuZ2UpPVwib25CdXR0b25Qcm9wZXJ0eUNoYW5nZShpLCAnZW5kcG9pbnQnLCAkZXZlbnQpXCIgcGxhY2Vob2xkZXI9XCJBUEkgZW5kcG9pbnRcIj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICBcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICAgIDxsYWJlbD5NZXRob2Q8L2xhYmVsPlxuICAgICAgICAgICAgICA8c2VsZWN0IFsobmdNb2RlbCldPVwiYnRuLm1ldGhvZFwiIChuZ01vZGVsQ2hhbmdlKT1cIm9uQnV0dG9uUHJvcGVydHlDaGFuZ2UoaSwgJ21ldGhvZCcsICRldmVudClcIj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCInR0VUJ1wiPkdFVDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cIidQT1NUJ1wiPlBPU1Q8L29wdGlvbj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCInUFVUJ1wiPlBVVDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cIidERUxFVEUnXCI+REVMRVRFPC9vcHRpb24+XG4gICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIFxuICAgICAgICAgICAgPCEtLSBBUCAyM01BWTI1IC0gQWN0aW9uIFN0eWxlIEZpZWxkcyAtLT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICAgIDxsYWJlbD5CYWNrZ3JvdW5kIENvbG9yPC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjb2xvclwiIFsobmdNb2RlbCldPVwiYnRuLmJnQ29sb3JcIiAobmdNb2RlbENoYW5nZSk9XCJvbkJ1dHRvblByb3BlcnR5Q2hhbmdlKGksICdiZ0NvbG9yJywgJGV2ZW50KVwiPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICAgICAgICAgICAgPGxhYmVsPkJvcmRlciBSYWRpdXM8L2xhYmVsPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInJhbmdlXCIgbWluPVwiMFwiIG1heD1cIjUwXCIgWyhuZ01vZGVsKV09XCJidG4uYm9yZGVyUmFkaXVzXCIgXG4gICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJvbkJ1dHRvblByb3BlcnR5Q2hhbmdlKGksICdib3JkZXJSYWRpdXMnLCAkZXZlbnQpXCI+XG4gICAgICAgICAgICAgIDxzcGFuPnt7IGJ0bi5ib3JkZXJSYWRpdXMgfX1weDwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PiAgICAgICAgICAgIFxuICAgICAgICAgICAgXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgICAgICAgICAgICA8bGFiZWw+QnV0dG9uIFdpZHRoIChweCk8L2xhYmVsPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiIFsobmdNb2RlbCldPVwiYnRuLndpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIm9uQnV0dG9uUHJvcGVydHlDaGFuZ2UoaSwgJ3dpZHRoJywgJGV2ZW50KVwiIG1pbj1cIjUwXCIgcGxhY2Vob2xkZXI9XCJFbnRlciB3aWR0aCBpbiBweFwiPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICAgIDxsYWJlbD5UZXh0IENvbG9yPC9sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjb2xvclwiIFsobmdNb2RlbCldPVwiYnRuLnRleHRDb2xvclwiXG4gICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJvbkJ1dHRvblByb3BlcnR5Q2hhbmdlKGksICd0ZXh0Q29sb3InLCAkZXZlbnQpXCI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICAgICAgICAgICAgPGxhYmVsPlBvc2l0aW9uICglKTwvbGFiZWw+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwicmFuZ2VcIiBtaW49XCIwXCIgbWF4PVwiMTAwXCIgWyhuZ01vZGVsKV09XCJidG4ucG9zaXRpb25QZXJjZW50XCJcbiAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIm9uQnV0dG9uUHJvcGVydHlDaGFuZ2UoaSwgJ3Bvc2l0aW9uUGVyY2VudCcsICRldmVudClcIj5cbiAgICAgICAgICAgICAgPHNwYW4+e3sgYnRuLnBvc2l0aW9uUGVyY2VudCB9fSU8L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxidXR0b24gKGNsaWNrKT1cInJlbW92ZUJ1dHRvbihidG4pXCIgY2xhc3M9XCJyZW1vdmUtYnV0dG9uXCI+w5cgUmVtb3ZlPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICBcbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbiAgPGRpdiBjbGFzcz1cInRhYi1jb250ZW50XCIgKm5nSWY9XCJhY3RpdmVUYWIgPT09ICdwcm9wZXJ0eSdcIj5cbiAgICA8IS0tIEZpZWxkIEVsZW1lbnRzIFByb3BlcnRpZXMgLS0+XG4gICAgPCEtLSBBUC0wNk1BUjI1IFNob3cgZWxlbWVudHMgSUQgIC0tPlxuICAgIDxkaXYgKm5nSWY9XCJnZXRQcm9wZXJ0aWVzKClcIj5cbiAgICAgIDxsYWJlbD5MYWJlbCBJZDwvbGFiZWw+XG4gICAgICA8ZGl2XG4gICAgICAgIHN0eWxlPVwiZm9udC1zaXplOiAxM3B4OyBwYWRkaW5nOiAxMXB4OyBib3JkZXItcmFkaXVzOiA1cHg7IGJhY2tncm91bmQtY29sb3I6ICNmOGY4Zjg7IGJvcmRlcjogMXB4IHNvbGlkICNkZGQ7XCI+XG4gICAgICAgIHt7IGhlYWRlclNlbGVjdCA/IGJvb2tJZCA6IHNlbGVjdGVkRWxlbWVudC5pZCB9fTwvZGl2PlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgcHJvcCBvZiBnZXRQcm9wZXJ0aWVzKCkuZmllbGRQcm9wc1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInRleHQtc21cIj57eyBwcm9wLmxhYmVsIH19PC9sYWJlbD5cblxuICAgICAgICAgIDwhLS0gU0tTMjFNQVIyNSBUb2dnbGUgR3JvdXAgLS0+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cInByb3AudHlwZSA9PT0gJ3RvZ2dsZUdyb3VwJ1wiIGNsYXNzPVwidG9nZ2xlLWdyb3VwXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidG9nZ2xlLWl0ZW1cIj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwidG9nZ2xlLWxhYmVsXCI+XG4gICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIFtjaGVja2VkXT1cInNlbGVjdGVkRWxlbWVudD8uaXNPcHRpb25hbFwiXG4gICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIm9uUmVxdWlyZWRDaGFuZ2UoJGV2ZW50LnRhcmdldC5jaGVja2VkKVwiIC8+XG4gICAgICAgICAgICAgICAgUmVxdWlyZWRcbiAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRvZ2dsZS1pdGVtXCI+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInRvZ2dsZS1sYWJlbFwiPlxuICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBbY2hlY2tlZF09XCJzZWxlY3RlZEVsZW1lbnQ/LmlzUmVhZE9ubHlcIlxuICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJvblRvZ2dsZUNoYW5nZSgnaXNSZWFkT25seScsICRldmVudClcIiAvPlxuICAgICAgICAgICAgICAgIFJlYWQgT25seVxuICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidG9nZ2xlLWl0ZW1cIj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwidG9nZ2xlLWxhYmVsXCI+XG4gICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIC8+XG4gICAgICAgICAgICAgICAgRGlzYWJsZWRcbiAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRvZ2dsZS1pdGVtXCI+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInRvZ2dsZS1sYWJlbFwiPlxuICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBbY2hlY2tlZF09XCJzZWxlY3RlZEVsZW1lbnQ/LmlzSGlkZGVuXCJcbiAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwib25Ub2dnbGVDaGFuZ2UoJ2lzSGlkZGVuJywgJGV2ZW50KVwiIC8+XG4gICAgICAgICAgICAgICAgSXMgSGlkZVxuICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8IS0tIEFQIDI4RkVCMjUgLSBoYW5kbGVkIG9wdGlvbnMgd2l0aCBVVUlEIC0tPlxuICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICpuZ0lmPVwicHJvcC50eXBlID09PSAnZHJvcGRvd24nIHx8IHByb3AudHlwZSA9PT0gJ2NoZWNrYm94JyB8fCBwcm9wLnR5cGUgPT09ICdyYWRpbycgJiYgcHJvcC5rZXkgPT09ICdvcHRpb25zJ1wiXG4gICAgICAgICAgICBjbGFzcz1cIm9wdGlvbnMtY29udGFpbmVyXCI+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvcHRpb24tbGlzdFwiIChkcmFnb3Zlcik9XCJvbkRyYWdPdmVyKCRldmVudClcIiAoZHJvcCk9XCJvbkRyb3AoJGV2ZW50LCBwcm9wLmtleSlcIj5cbiAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIHNlbGVjdGVkRWxlbWVudFtwcm9wLmtleV1cIiBjbGFzcz1cIm9wdGlvbi1pdGVtc1wiIFthdHRyLmRhdGEtaWRdPVwib3B0aW9uLmlkXCJcbiAgICAgICAgICAgICAgICBkcmFnZ2FibGU9XCJ0cnVlXCIgKGRyYWdzdGFydCk9XCJvbkRyYWdTdGFydCgkZXZlbnQsIG9wdGlvbi5pZClcIj5cblxuICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIFsobmdNb2RlbCldPVwib3B0aW9uLnZhbHVlXCIgcGxhY2Vob2xkZXI9XCJPcHRpb25cIiBjbGFzcz1cIm9wdGlvbnNcIiAvPlxuICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiLi4vYXNzZXRzL2ljb25zL1RyYXNoLnN2Z1wiIChjbGljayk9XCJyZW1vdmVPcHRpb24oc2VsZWN0ZWRFbGVtZW50W3Byb3Aua2V5XSwgb3B0aW9uLmlkKVwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZHJhZy1oYW5kbGVcIj7imLA8L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxidXR0b24gKGNsaWNrKT1cImFkZE9wdGlvbihzZWxlY3RlZEVsZW1lbnRbcHJvcC5rZXldKVwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWRkLXZhcmllbnRcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtbGdcIj4rPC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuPkFkZDwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDxpbnB1dCAqbmdJZj1cInByb3AudHlwZSA9PT0gJ3RleHQnXCIgdHlwZT1cInRleHRcIiBbcGxhY2Vob2xkZXJdPVwicHJvcC5wbGFjZWhvbGRlclwiXG4gICAgICAgICAgICBbdmFsdWVdPVwiaGVhZGVyU2VsZWN0ID8gYm9vay5yZWNvcmRzWzBdLnRpdGxlIDogKHNlbGVjdGVkRWxlbWVudD8udHlwZSA9PT0gJ1RhYmxlJyA/IChwcm9wLnRhcmdldEFycmF5ID8gZ2V0VmFsdWVCeUFycmF5UGF0aChwcm9wLnRhcmdldEFycmF5LCBwcm9wLnRhcmdldEFycmF5S2V5LCBzZWxlY3RDb2x1bW4sIHByb3Aua2V5ICkgOiBnZXRWYWx1ZUJ5UGF0aChwcm9wLmtleSkgKSA6ICBnZXRWYWx1ZUJ5UGF0aChwcm9wLmtleSkpXCJcbiAgICAgICAgICAgIChpbnB1dCk9XCJoZWFkZXJTZWxlY3QgPyB1cGRhdGVUaXRsZSgkZXZlbnQudGFyZ2V0LnZhbHVlKSA6IChzZWxlY3RlZEVsZW1lbnQ/LnR5cGUgPT09ICdUYWJsZScgPyAocHJvcC50YXJnZXRBcnJheSA/IHVwZGF0ZVZhbHVlQnlBcnJheVBhdGgocHJvcC50YXJnZXRBcnJheSwgcHJvcC50YXJnZXRBcnJheUtleSwgc2VsZWN0Q29sdW1uLCBwcm9wLmtleSwgJGV2ZW50KSA6IHNldFZhbHVlQnlQYXRoKHByb3Aua2V5LCAkZXZlbnQudGFyZ2V0LnZhbHVlKSApIDogc2V0VmFsdWVCeVBhdGgocHJvcC5rZXksICRldmVudC50YXJnZXQudmFsdWUpKVwiXG4gICAgICAgICAgICBbY2xhc3MucmVhZC1vbmx5XT1cInNlbGVjdGVkRWxlbWVudC5yZWFkT25seVwiIFtyZWFkb25seV09XCJzZWxlY3RlZEVsZW1lbnQucmVhZE9ubHlcIiAvPlxuXG4gICAgICAgICAgPCEtLSBTdWIgUXVlc3Rpb25zIFRvZ2dsZSAtLT5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwicHJvcC50eXBlID09PSAnc3ViUXVlc3Rpb24nXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3R5bGUtdG9nZ2xlLWhlYWRlclwiIChjbGljayk9XCJ0b2dnbGVTdWJRdWVzdGlvbihwcm9wKVwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGVhZC1lbGVtZW50c1wiPlN1YiBUZXh0PC9kaXY+XG4gICAgICAgICAgICAgIDxpbWcgW3NyY109XCJwcm9wLmlzRXhwYW5kZWQgPyAnLi4vYXNzZXRzL2ljb25zL2Fycm93LWRvd24uc3ZnJyA6ICcuLi9hc3NldHMvaWNvbnMvYXJyb3ctcmlnaHQuc3ZnJ1wiXG4gICAgICAgICAgICAgICAgYWx0PVwiVG9nZ2xlIEFycm93XCIgY2xhc3M9XCJhcnJvdy1pY29uXCI+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPCEtLSBSZW5kZXIgc3VicXVlc3Rpb25zIHdoZW4gYXJyb3cgaXMgZG93biAtLT5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJwcm9wLmlzRXhwYW5kZWRcIiBzdHlsZT1cImJvcmRlcjogMXB4IHNvbGlkICNkZGQ7IHBhZGRpbmc6IDhweDsgYm9yZGVyLXJhZGl1czogNHB4O1wiPlxuICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBzdWJQcm9wIG9mIHByb3Auc3ViUXVlc3Rpb25cIiBjbGFzcz1cInN1Yi1xdWVzdGlvbi1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgPGxhYmVsPnt7IHN1YlByb3AubGFiZWwgfX08L2xhYmVsPlxuXG4gICAgICAgICAgICAgICAgICA8aW5wdXQgKm5nSWY9XCJzdWJQcm9wLnR5cGUgPT09ICd0ZXh0J1wiIHR5cGU9XCJ0ZXh0XCIgW3BsYWNlaG9sZGVyXT1cInN1YlByb3AucGxhY2Vob2xkZXJcIlxuICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwiZ2V0VmFsdWVCeVBhdGgoc3ViUHJvcC5rZXkpXCIgKGlucHV0KT1cInNldFZhbHVlQnlQYXRoKHN1YlByb3Aua2V5LCAkZXZlbnQudGFyZ2V0LnZhbHVlKVwiIC8+XG4gICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgPCEtLSBBUC0wMkFQUjI1IFJlbmRlciBpbnB1dCBmaWVsZCBvbmx5IGlmIHN1YlByb3AudHlwZSBpcyAnYXJyYXknIC0tPlxuICAgICAgICAgICAgICAgICAgPGlucHV0ICpuZ0lmPVwic3ViUHJvcC50eXBlID09PSAnYXJyYXknXCIgdHlwZT1cInRleHRcIiBbcGxhY2Vob2xkZXJdPVwic3ViUHJvcC5wbGFjZWhvbGRlclwiXG4gICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJnZXRWYWx1ZUJ5UGF0aChzdWJQcm9wLmtleSlcIiAoaW5wdXQpPVwic2V0VmFsdWVCeVBhdGgoc3ViUHJvcC5rZXksICRldmVudC50YXJnZXQudmFsdWUpXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSA8aW5wdXQgdHlwZT1cInRleHRcIiBbbmdNb2RlbF09XCJmaWVsZEFzU3RyaW5nXCIgKG5nTW9kZWxDaGFuZ2UpPVwidXBkYXRlRmllbGQoJGV2ZW50KVwiIC8+IC0tPlxuXG4gICAgICAgICAgICAgICAgICA8aW5wdXQgKm5nSWY9XCJzdWJQcm9wLnR5cGUgPT09ICdib29sZWFuJ1wiIHR5cGU9XCJjaGVja2JveFwiIFtjaGVja2VkXT1cImdldFZhbHVlQnlQYXRoKHN1YlByb3Aua2V5KVwiXG4gICAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwic2V0VmFsdWVCeVBhdGgoc3ViUHJvcC5rZXksICRldmVudC50YXJnZXQuY2hlY2tlZClcIiAvPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPGRpdiAqbmdJZj1cInByb3AudHlwZSA9PT0gJ2NoZWNrYm94J1wiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0b2dnbGUtbGFiZWxcIiBzdHlsZT1cInBhZGRpbmctcmlnaHQ6IDEwcHg7XCI+e3sgcHJvcC5sYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgICAgICBbY2hlY2tlZF09XCJzZWxlY3RlZEVsZW1lbnQudHlwZSA9PT0gJ1RhYmxlJyA/IChwcm9wLnRhcmdldEFycmF5ID8gZ2V0VmFsdWVCeUFycmF5UGF0aChwcm9wLnRhcmdldEFycmF5LCBwcm9wLnRhcmdldEFycmF5S2V5LCBzZWxlY3RDb2x1bW4sIHByb3Aua2V5ICkgOiBnZXRWYWx1ZUJ5UGF0aChwcm9wLmtleSkgKTogIGdldFZhbHVlQnlQYXRoKHByb3Aua2V5KSBcIlxuICAgICAgICAgICAgICAoY2hhbmdlKT1cIiBzZWxlY3RlZEVsZW1lbnQudHlwZSA9PT0gJ1RhYmxlJyA/IChwcm9wLnRhcmdldEFycmF5ID8gdXBkYXRlVmFsdWVCeUFycmF5UGF0aChwcm9wLnRhcmdldEFycmF5LCBwcm9wLnRhcmdldEFycmF5S2V5LCBzZWxlY3RDb2x1bW4sIHByb3Aua2V5LCAkZXZlbnQpIDogb25Ub2dnbGVDaGFuZ2UocHJvcC5rZXksICRldmVudCkgKSA6IG9uVG9nZ2xlQ2hhbmdlKHByb3Aua2V5LCAkZXZlbnQpXCIgLz5cblxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gU0tTMjFNQVIyNSBNb3ZlIFN0eWxlIE91dHNpZGUgdGhlIExvb3AgLS0+XG4gICAgICA8IS0tIFN0eWxlIFRvZ2dsZSAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJzdHlsZS10b2dnbGUtaGVhZGVyXCIgKGNsaWNrKT1cInRvZ2dsZVN0eWxlU2VjdGlvbigpXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJoZWFkLWVsZW1lbnRzXCI+U3R5bGU8L2Rpdj5cbiAgICAgICAgPGltZyBbc3JjXT1cImlzU3R5bGVFeHBhbmRlZCA/ICcuLi9hc3NldHMvaWNvbnMvYXJyb3ctZG93bi5zdmcnIDogJy4uL2Fzc2V0cy9pY29ucy9hcnJvdy1yaWdodC5zdmcnXCJcbiAgICAgICAgICBhbHQ9XCJUb2dnbGUgQXJyb3dcIiBjbGFzcz1cImFycm93LWljb25cIj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2ICpuZ0lmPVwiaXNTdHlsZUV4cGFuZGVkXCIgc3R5bGU9XCJib3JkZXI6IDFweCBzb2xpZCAjZGRkOyBwYWRkaW5nOiA4cHg7IGJvcmRlci1yYWRpdXM6IDRweDtcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBrZXkgb2YgZ2V0U3R5bGVLZXlzKClcIj5cbiAgICAgICAgICAgIDxsYWJlbD57eyBrZXkgfX08L2xhYmVsPlxuICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgWyhuZ01vZGVsKV09XCJzZWxlY3RlZEVsZW1lbnQuc3R5bGVba2V5XVwiXG4gICAgICAgICAgICAgIChpbnB1dCk9XCJzZXRWYWx1ZUJ5UGF0aCgnc3R5bGUuJyArIGtleSwgJGV2ZW50LnRhcmdldC52YWx1ZSlcIiBwbGFjZWhvbGRlcj1cIkVudGVyIHt7IGtleSB9fVwiIC8+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJ0YWItY29udGVudFwiICpuZ0lmPVwiYWN0aXZlVGFiID09PSAnYXBwZWFyYW5jZSdcIj5cbiAgICA8ZGl2ICpuZ0lmPVwiZ2V0UHJvcGVydGllcygpXCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBwcm9wIG9mIGdldFByb3BlcnRpZXMoKS5hcHBlYXJhbmNlXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgPGxhYmVsIGNsYXNzPVwidGV4dC1zbVwiPnt7IHByb3AubGFiZWwgfX08L2xhYmVsPlxuICAgICAgICAgIDwhLS0gRm9udCBTZWxlY3Rpb24gLS0+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cInByb3Aua2V5ID09PSAnZm9udCdcIj5cbiAgICAgICAgICAgIDxzZWxlY3QgKm5nSWY9XCJwcm9wLnR5cGUgPT09ICdzZWxlY3QnXCIgY2xhc3M9XCJzZWxlY3QtY29udGFpbmVyXCIgWyhuZ01vZGVsKV09XCJzZWxlY3RlZEVsZW1lbnQuZm9udFwiXG4gICAgICAgICAgICAgIChjaGFuZ2UpPVwic2V0VmFsdWVCeVBhdGgoJ2ZvbnQnLCAkZXZlbnQudGFyZ2V0LnZhbHVlKVwiPlxuICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBvcHRpb24gb2YgcHJvcC5vcHRpb25zXCIgW3ZhbHVlXT1cIm9wdGlvblwiPlxuICAgICAgICAgICAgICAgIHt7IG9wdGlvbiB9fVxuICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwhLS0gSW5wdXQgQm94IC0tPlxuICAgICAgICAgIDxpbnB1dCAqbmdJZj1cInByb3AudHlwZSA9PT0gJ3RleHQnXCIgdHlwZT1cInRleHRcIiBbcGxhY2Vob2xkZXJdPVwicHJvcC5wbGFjZWhvbGRlclwiXG4gICAgICAgICAgICBbdmFsdWVdPVwic2VsZWN0ZWRFbGVtZW50W3Byb3Aua2V5XVwiIChpbnB1dCk9XCJzZXRWYWx1ZUJ5UGF0aChwcm9wLmtleSwgJGV2ZW50LnRhcmdldC52YWx1ZSlcIiAvPlxuXG4gICAgICAgICAgPCEtLSBGb250IFNpemUgU2VsZWN0aW9uIC0tPlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJwcm9wLmtleSA9PT0gJ2ZvbnRTaXplJ1wiPlxuICAgICAgICAgICAgPHNlbGVjdCAqbmdJZj1cInByb3AudHlwZSA9PT0gJ3NlbGVjdCdcIiBbKG5nTW9kZWwpXT1cInNlbGVjdGVkRWxlbWVudFtwcm9wLmtleV1cIlxuICAgICAgICAgICAgICAoY2hhbmdlKT1cInNldFZhbHVlQnlQYXRoKHByb3Aua2V5LCAkZXZlbnQudGFyZ2V0LnZhbHVlKVwiPlxuICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBvcHRpb24gb2YgcHJvcC5vcHRpb25zXCIgW3ZhbHVlXT1cIm9wdGlvbi52YWx1ZVwiPlxuICAgICAgICAgICAgICAgIHt7IG9wdGlvbi5sYWJlbCB9fVxuICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwhLS0gRm9udCBXZWlnaHQgU2VsZWN0aW9uIC0tPlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJwcm9wLmtleSA9PT0gJ2ZvbnRXZWlnaHQnXCI+XG4gICAgICAgICAgICA8c2VsZWN0ICpuZ0lmPVwicHJvcC50eXBlID09PSAnc2VsZWN0J1wiIFsobmdNb2RlbCldPVwic2VsZWN0ZWRFbGVtZW50W3Byb3Aua2V5XVwiXG4gICAgICAgICAgICAgIChjaGFuZ2UpPVwic2V0VmFsdWVCeVBhdGgocHJvcC5rZXksICRldmVudC50YXJnZXQudmFsdWUpXCI+XG4gICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IG9wdGlvbiBvZiBwcm9wLm9wdGlvbnNcIiBbdmFsdWVdPVwib3B0aW9uLnZhbHVlXCI+XG4gICAgICAgICAgICAgICAge3sgb3B0aW9uLmxhYmVsIH19XG4gICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleC1jb250YWluZXJcIj5cbiAgICAgICAgICAgIDwhLS0gRHJvcGRvd24gQm94IC0tPlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cInByb3AudHlwZSA9PT0gJ2Ryb3Bkb3duJ1wiIGNsYXNzPVwiaW5wdXQtYm94LWZpZWxkXCI+XG4gICAgICAgICAgICAgIDxzZWxlY3QgWyhuZ01vZGVsKV09XCJzZWxlY3RlZEVsZW1lbnRbcHJvcC5rZXldXCIgKGNoYW5nZSk9XCJzZXRWYWx1ZUJ5UGF0aChwcm9wLmtleSwgJGV2ZW50LnRhcmdldC52YWx1ZSlcIj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBvcHRpb24gb2YgcHJvcC5vcHRpb25zXCIgW3ZhbHVlXT1cIm9wdGlvblwiPlxuICAgICAgICAgICAgICAgICAge3sgb3B0aW9uIH19XG4gICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDwhLS0gQ29sb3IgUGlja2VyIC0tPlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cInByb3AudHlwZSA9PT0gJ2NvbG9yJ1wiIGNsYXNzPVwiY29sb3Itc2VsZWN0b3JcIj5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjb2xvclwiIFsobmdNb2RlbCldPVwic2VsZWN0ZWRFbGVtZW50LmZvbnRDb2xvclwiXG4gICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJzZXRWYWx1ZUJ5UGF0aCgnZm9udENvbG9yJywgJGV2ZW50LnRhcmdldC52YWx1ZSlcIj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8IS0tIEhFWCBJbnB1dCBCb3ggLS0+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwicHJvcC50eXBlID09PSAnY29sb3InXCIgY2xhc3M9XCJoZXgtaW5wdXQtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgIDxzcGFuPkhFWCBDb2RlPC9zcGFuPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBbKG5nTW9kZWwpXT1cInNlbGVjdGVkRWxlbWVudFtwcm9wLmtleV1cIlxuICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwic2V0VmFsdWVCeVBhdGgocHJvcC5rZXksICRldmVudC50YXJnZXQudmFsdWUpXCIgLz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIFxuICAgICAgICAgIDwhLS0gQVAtMTdBUFIyNSBCdXR0b24gZm9yIER1cGxpY2F0ZSBGaWVsZCAgLS0+XG48ZGl2ICpuZ0lmPVwicHJvcC50eXBlID09PSAnYnV0dG9uLXRvZ2dsZSdcIiBjbGFzcz1cImJ1dHRvbi10b2dnbGUtd3JhcHBlclwiPlxuICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIlxuICAgIGNsYXNzPVwidG9nZ2xlLWJ1dHRvblwiXG4gICAgKGNsaWNrKT1cImR1cGxpY2F0ZUZpZWxkKHNlbGVjdGVkRWxlbWVudClcIj5cbiAgICBBZGQgRHVwbGljYXRlXG4gIDwvYnV0dG9uPlxuPC9kaXY+XG5cblxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cblxuPCEtLSBBUC0wOEFQUjI1IERlZmF1bHQgU2F2ZSBCdXR0b24gLS0+XG48ZGl2IGNsYXNzPVwiYnV0dG9uLWNvbnRhaW5lclwiICpuZ0lmPVwiIXRlbXBsYXRlU2VsZWN0ZWRcIj5cbiAgPGJ1dHRvbiBjbGFzcz1cImNhbmNlbC1idG5cIiAoY2xpY2spPVwib25DYW5jZWwoKVwiPkNhbmNlbDwvYnV0dG9uPlxuICA8YnV0dG9uIGNsYXNzPVwic2F2ZS1idG5cIiAoY2xpY2spPVwiaGFuZGxlQnV0dG9uQ2xpY2soKVwiPlNhdmU8L2J1dHRvbj5cbjwvZGl2PlxuXG48IS0tIEFQLTA4QVBSMjUgVGVtcGxhdGUgU2F2ZSBCdXR0b24gLS0+XG48ZGl2IGNsYXNzPVwiYnV0dG9uLWNvbnRhaW5lclwiICpuZ0lmPVwidGVtcGxhdGVTZWxlY3RlZFwiIHN0eWxlPVwibWFyZ2luLXRvcDogMjBweDtcIj5cbiAgPGJ1dHRvbiBjbGFzcz1cInNhdmUtYnRuXCIgKGNsaWNrKT1cImhhbmRsZVRlbXBsYXRlU2F2ZSgpXCI+U2F2ZSBUZW1wbGF0ZTwvYnV0dG9uPlxuPC9kaXY+XG5cbjwvZGl2PiJdfQ==
926
+ 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: [{
927
+ type: Component,
928
+ args: [{ selector: 'app-properties', standalone: true, imports: [CommonModule, FormsModule, ImageCropperComponent, NxtSearchBox, NgClass, NgFor, NgIf, GetValueByPathPipe], 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</div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab() === 'property'}\" (click)=\"setActiveTab('property')\">Property</div>\n <div class=\"tab\" [ngClass]=\"{'active': activeTab() === 'appearance'}\" (click)=\"setActiveTab('appearance')\">Appearance</div>\n </div>\n\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\">\u27F2</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"rotateRight()\" title=\"Rotate Right\">\u27F3</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"zoomOut()\" title=\"Zoom Out\">-</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"zoomIn()\" title=\"Zoom In\">+</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveLeft()\" title=\"Move Left\">\u2190</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveRight()\" title=\"Move Right\">\u2192</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveUp()\" title=\"Move Up\">\u2191</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"moveDown()\" title=\"Move Down\">\u2193</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipHorizontal()\" [ngClass]=\"{'enabled': transform().flipH}\" title=\"Flip Horizontally\">\u2194</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"flipVertical()\" [ngClass]=\"{'enabled': transform().flipV}\" title=\"Flip Vertically\">\u2195</div>\n <div class=\"cursor-pointer logo-icon\" (click)=\"resetImage()\" title=\"Reset\">\u00D7</div>\n </div>\n }\n <div *ngIf=\"selectedElement()?.type === 'Book'\">\n <label class=\"text-sm\">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...'\"\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>Endpoint:</label>\n <input type=\"text\" [ngModel]=\"bookSubtext().endpoint\" (ngModelChange)=\"updateBookSubtext('endpoint', $event)\" />\n <label>Variable:</label>\n <input type=\"text\" [ngModel]=\"bookSubtext().variable\" (ngModelChange)=\"updateBookSubtext('variable', $event)\" />\n <label>Field:</label>\n <input type=\"text\" [ngModel]=\"fieldAsString()\" (ngModelChange)=\"updateField($event)\" />\n <label>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.label }}</label>\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) : setValueByPath(prop.key, $event))\"\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) : setValueByPath(prop.key, $event))\"\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) : setValueByPath(prop.key, $event))\"\n >\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\">{{ 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) : onToggleChange(prop.key, $event)) : onToggleChange(prop.key, $event)\"\n />\n <span class=\"toggle-label\" style=\"padding-left: 10px;\">{{ 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.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) : 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.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) : setValueByPath(subProp.key, $event)) : setValueByPath(subProp.key, $event)\"\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) : setValueByPath(subProp.key, $event))\"\n >\n <option *ngFor=\"let option of subProp.options\" [value]=\"option.value\">{{ 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) : setValueByPath(prop.key, $event))\"\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.label }}</label>\n <button (click)=\"addNewButton()\" class=\"add-button\">+ 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</label>\n <input type=\"text\" [ngModel]=\"btn.name\" (ngModelChange)=\"onButtonPropertyChange(i, 'name', $event)\" placeholder=\"Enter button name\">\n </div>\n <div class=\"form-group\">\n <label>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</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>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</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</label>\n <input type=\"color\" [ngModel]=\"btn.bgColor\" (ngModelChange)=\"onButtonPropertyChange(i, 'bgColor', $event)\">\n </div>\n <div class=\"form-group\">\n <label>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)</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</label>\n <input type=\"color\" [ngModel]=\"btn.textColor\" (ngModelChange)=\"onButtonPropertyChange(i, 'textColor', $event)\">\n </div>\n <div class=\"form-group\">\n <label>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</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.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) : onToggleChange(prop.key, $event)) : onToggleChange('isOptional', $event)\"\n />\n 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) : onToggleChange(prop.key, $event)) : onToggleChange('isReadOnly', $event)\"\n />\n 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) : onToggleChange(prop.key, $event)) : onToggleChange('isHidden', $event)\"\n />\n 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\" [ngModel]=\"option.value\" (ngModelChange)=\"option.value = $event\" placeholder=\"Option\" 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</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) : setValueByPath(prop.key, $event))\"\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.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) : setValueByPath(subProp.key, $event.target.value)\"\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)\" />\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.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) : 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</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.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) : setValueByPath(prop.key, $event))\"\n >\n <option *ngFor=\"let option of prop.options\" [value]=\"option.value\">{{ 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)\"\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)\"\n >\n </div>\n <div *ngIf=\"prop.type === 'color'\" class=\"hex-input-container\">\n <span>HEX Code</span>\n <input\n type=\"text\"\n [ngModel]=\"selectedElement() | getValueByPath : prop.key\"\n (ngModelChange)=\"setValueByPath(prop.key, $event)\"\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\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</button>\n <button class=\"save-btn\" (click)=\"handleButtonClick()\">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</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;border:1px solid #ccc;margin-bottom:10px;cursor:grab;background:#fff}.option-items:active{opacity:.5}.drag-handle{margin-left:10px;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}}\n"] }]
929
+ }], ctorParameters: () => [{ type: i1.FormBuilderService }, { type: i2.TemplateService }], propDecorators: { templateSelected: [{
930
+ type: Input
931
+ }], selectedElementType: [{
932
+ type: Input
933
+ }], formButtonHandler: [{
934
+ type: Output
935
+ }], templateSaveHandler: [{
936
+ type: Output
937
+ }], dropdown: [{
938
+ type: ViewChild,
939
+ args: ['dropdown', { static: false }]
940
+ }], onClickOutside: [{
941
+ type: HostListener,
942
+ args: ['document:click', ['$event']]
943
+ }] } }) });
944
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvcGVydGllcy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9ueHQtYXBwL3NyYy9saWIvcGFnZXMvYnVpbGRlci9wcm9wZXJ0aWVzL3Byb3BlcnRpZXMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbnh0LWFwcC9zcmMvbGliL3BhZ2VzL2J1aWxkZXIvcHJvcGVydGllcy9wcm9wZXJ0aWVzLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQWMsWUFBWSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQVUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZLLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFLN0MsT0FBTyxFQUFFLEVBQUUsSUFBSSxNQUFNLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFcEMscUZBQXFGO0FBQ3JGLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxvQkFBb0IsRUFBRSxrQkFBa0IsRUFBRSx1QkFBdUIsRUFBdUIsTUFBTSx1Q0FBdUMsQ0FBQztBQUVySyxPQUFPLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsSUFBSSxFQUFpQixNQUFNLGVBQWUsQ0FBQzs7Ozs7O0FBRXBELDBDQUEwQztBQU0xQyxNQUFNLE9BQU8sa0JBQWtCO0lBQzdCLFNBQVMsQ0FBQyxHQUFRLEVBQUUsSUFBWSxFQUFFLGVBQW9CLEVBQUU7UUFDdEQsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUk7WUFBRSxPQUFPLFlBQVksQ0FBQztRQUN2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QUM7U0FDZCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsT0FBTztRQUNMLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsS0FBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNoRSxDQUFDO0lBRUQsTUFBTTtRQUNKLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsS0FBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNoRSxDQUFDO0lBRUQsVUFBVTtRQUNSLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3ZCLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUN2QyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDekIsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3ZCLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUN2QyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDekIsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsUUFBUTtRQUNOLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLFVBQVUsRUFBRSxDQUFD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YyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsSUFBSSxPQUFPLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQztZQUMxRSxPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FDN0IsT0FBTyxDQUFDLFdBQVcsRUFDbkIsT0FBTyxDQUFDLGNBQWMsRUFDdEIsSUFBSSxDQUFDLGdCQUFnQixFQUNyQixPQUFPLENBQUMsR0FBRyxFQUNYLE9BQU8sQ0FBQyxhQUFhLENBQ3RCLENBQUM7UUFDSixDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDbkQsQ0FBQzt3R0EzN0JVLG1CQUFtQjs0RkFBbkIsbUJBQW1CLG9iQ3BDaEMsNmhqQ0FzZE0sNDJORHZiTSxZQUFZLGdPQUFFLFdBQVcsMFpBVnhCLGtCQUFrQix1T0FBbEIsa0JBQWtCLHNLQUFsQixrQkFBa0I7O2lHQWVsQixtQkFBbUI7c0JBUi9CLFNBQVM7bUNBQ0UsZ0JBQWdCLGNBQ2QsSUFBSSxXQUNQLENBQUMsWUFBWSxFQUFFLFdBQVcsRUFBRSxxQkFBcUIsRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsa0JBQWtCLENBQUMsbUJBR2xHLHVCQUF1QixDQUFDLE1BQU07eUhBR3RDLGdCQUFnQjswQkFBeEIsS0FBSztvQkFDTyxtQkFBbUI7MEJBQS9CLEtBQUs7b0JBR0ksaUJBQWlCOzBCQUExQixNQUFNO29CQUNHLG1CQUFtQjswQkFBNUIsTUFBTTtvQkFFbUMsUUFBUTswQkFBakQsU0FBUzsyQkFBQyxVQUFVLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFO29CQWcyQnhDLGNBQWM7MEJBRGIsWUFBWTsyQkFBQyxnQkFBZ0IsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEV2ZW50RW1pdHRlciwgSG9zdExpc3RlbmVyLCBJbnB1dCwgT25Jbml0LCBPdXRwdXQsIHNpZ25hbCwgY29tcHV0ZWQsIGVmZmVjdCwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBJbWFnZUNyb3BwZXJDb21wb25lbnQgfSBmcm9tICcuLi8uLi8uLi9jb21wb25lbnRzL2ltYWdlLWNyb3BwZXIvY29tcG9uZW50L2ltYWdlLWNyb3BwZXIuY29tcG9uZW50JztcbmltcG9ydCB7IE54dFNlYXJjaEJveCB9IGZyb20gJy4uLy4uLy4uL2NvbXBvbmVudHMvc2VhcmNoLWJveC9zZWFyY2gtYm94LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBGb3JtQnVpbGRlclNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9mb3JtLWJ1aWxkZXIuc2VydmljZSc7XG5pbXBvcnQgeyBUZW1wbGF0ZVNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy90ZW1wbGF0ZS5zZXJ2aWNlJztcbmltcG9ydCB7IHY0IGFzIHV1aWR2NCB9IGZyb20gJ3V1aWQnO1xuaW1wb3J0IHsgQ3JvcHBlclBvc2l0aW9uLCBEaW1lbnNpb25zLCBJbWFnZVRyYW5zZm9ybSB9IGZyb20gJy4uLy4uLy4uL2NvbXBvbmVudHMvaW1hZ2UtY3JvcHBlci9pbnRlcmZhY2VzJztcbi8vQVAtMjVKVU4yNS1JbXBvcnRpbmcgY29tbW9uIGNvbnN0YW50cyBmb3IgZWxlbWVudCwgZmllbGQsIGFuZCBhcHBlYXJhbmNlIHByb3BlcnRpZXNcbmltcG9ydCB7IENPTU1PTl9FTEVNRU5UX1BST1BTLCBDT01NT05fT1BUSU9OU19GSUVMRCwgQ09NTU9OX0ZJRUxEX1BST1BTLCBDT01NT05fQVBQRUFSQU5DRV9QUk9QUywgQ09NTU9OX0NPTFVNTl9GSUVMRCB9IGZyb20gJy4uL3Byb3BlcnRpZXMvY29tbW9uLWZpZWxkcy5jb25zdGFudHMnO1xuaW1wb3J0IHsgdG9TaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5pbXBvcnQgeyBOZ0NsYXNzLCBOZ0ZvciwgTmdJZiB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBQaXBlLCBQaXBlVHJhbnNmb3JtIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbi8vIEN1c3RvbSBwaXBlIGZvciBwYXRoLWJhc2VkIHZhbHVlIGFjY2Vzc1xuQFBpcGUoe1xuICBuYW1lOiAnZ2V0VmFsdWVCeVBhdGgnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBwdXJlOiB0cnVlXG59KVxuZXhwb3J0IGNsYXNzIEdldFZhbHVlQnlQYXRoUGlwZSBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xuICB0cmFuc2Zvcm0ob2JqOiBhbnksIHBhdGg6IHN0cmluZywgZGVmYXVsdFZhbHVlOiBhbnkgPSAnJyk6IGFueSB7XG4gICAgaWYgKCFvYmogfHwgIXBhdGgpIHJldHVybiBkZWZhdWx0VmFsdWU7XG4gICAgcmV0dXJuIHBhdGguc3BsaXQoJy4nKS5yZWR1Y2UoKG8sIGspID0+IG8/LltrXSA/PyBkZWZhdWx0VmFsdWUsIG9iaik7XG4gIH1cbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLXByb3BlcnRpZXMnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBGb3Jtc01vZHVsZSwgSW1hZ2VDcm9wcGVyQ29tcG9uZW50LCBOeHRTZWFyY2hCb3gsIE5nQ2xhc3MsIE5nRm9yLCBOZ0lmLCBHZXRWYWx1ZUJ5UGF0aFBpcGVdLFxuICB0ZW1wbGF0ZVVybDogJy4vcHJvcGVydGllcy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3Byb3BlcnRpZXMuY29tcG9uZW50LmNzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBQcm9wZXJ0aWVzQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgQElucHV0KCkgdGVtcGxhdGVTZWxlY3RlZCA9IGZhbHNlO1xuICBASW5wdXQoKSBzZXQgc2VsZWN0ZWRFbGVtZW50VHlwZSh2YWx1ZTogc3RyaW5nKSB7XG4gICAgdGhpcy5zZWxlY3RlZEVsZW1lbnRUeXBlU2lnLnNldCh2YWx1ZSk7XG4gIH1cbiAgQE91dHB1dCgpIGZvcm1CdXR0b25IYW5kbGVyID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIEBPdXRwdXQoKSB0ZW1wbGF0ZVNhdmVIYW5kbGVyID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG5cbiAgQFZpZXdDaGlsZCgnZHJvcGRvd24nLCB7IHN0YXRpYzogZmFsc2UgfSkgZHJvcGRvd24hOiBFbGVtZW50UmVmO1xuXG4gIC8vIFNpZ25hbHMgZm9yIHJlYWN0aXZlIHN0YXRlXG4gIHNlbGVjdGVkRWxlbWVudFR5cGVTaWcgPSBzaWduYWw8c3RyaW5nPignJyk7XG4gIHNlbGVjdGVkRWxlbWVudCA9IHNpZ25hbDxhbnk+KG51bGwpO1xuICBzZWxlY3RlZEVsZW1lbnRJbmRleCA9IHNpZ25hbDxudW1iZXI+KC0xKTtcbiAgaGVhZGVyU2VsZWN0ID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgYm9vayA9IHNpZ25hbDxhbnk+KG51bGwpO1xuICBib29rSWQgPSBzaWduYWw8YW55PihudWxsKTtcbiAgYWN0aXZlVGFiID0gc2lnbmFsPHN0cmluZz4oJ2F0dHJpYnV0ZXMnKTtcbiAgc2VsZWN0Q29sdW1uID0gc2lnbmFsPGFueT4obnVsbCk7XG4gIHRyYW5zZm9ybSA9IHNpZ25hbDxJbWFnZVRyYW5zZm9ybT4oe1xuICAgIHRyYW5zbGF0ZVVuaXQ6ICdweCcsXG4gICAgc2NhbGU6IDEsXG4gICAgcm90YXRlOiAwLFxuICAgIGZsaXBIOiBmYWxzZSxcbiAgICBmbGlwVjogZmFsc2UsXG4gICAgdHJhbnNsYXRlSDogMCxcbiAgICB0cmFuc2xhdGVWOiAwXG4gIH0pO1xuICBjYW52YXNSb3RhdGlvbiA9IHNpZ25hbDxudW1iZXI+KDApO1xuICBjcm9wcGVyID0gc2lnbmFsPENyb3BwZXJQb3NpdGlvbiB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgbG9hZGluZyA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XG4gIGlzTGlua0Ryb3Bkb3duT3BlbiA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XG4gIGVycm9yTWVzc2FnZSA9IHNpZ25hbDxzdHJpbmc+KCcnKTtcbiAgYm9va1N1YnRleHQgPSBzaWduYWwoe1xuICAgIGVuZHBvaW50OiAnaHR0cHM6Ly9kZXYtYXBpLnZhbGFyaHIuY29tL254dCcsXG4gICAgdmFyaWFibGU6IG51bGwsXG4gICAgZmllbGQ6IFsnbGFiZWwnLCAnbmFtZSddLFxuICAgIGRlZmF1bHRGaWVsZDogJ2xhYmVsJ1xuICB9KTtcbiAgaXNTdHlsZUV4cGFuZGVkID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgY3JvcHBlck1heEhlaWdodCA9IDA7XG4gIGNyb3BwZXJNYXhXaWR0aCA9IDA7XG4gIGNyb3BwZXJNaW5IZWlnaHQgPSAwO1xuICBjcm9wcGVyTWluV2lkdGggPSAwO1xuICBjcm9wcGVyU3RhdGljV2lkdGggPSAwO1xuICBjcm9wcGVyU3RhdGljSGVpZ2h0ID0gMDtcbiAgYXNwZWN0UmF0aW8gPSA0IC8gMztcbiAgcm91bmRDcm9wcGVyID0gZmFsc2U7XG4gIGlzRXhwYW5kZWQ6IEJvb2xlYW4gPSBmYWxzZVxuICBhbGlnbkltYWdlID0gJ2NlbnRlcicgYXMgY29uc3Q7XG4gIGVsZW1lbnRUeXBlID0gWydIZWFkZXInLCdMaW5lJywnU3BhY2UnLCdUYWJsZScsJ1RhYmxlQ29sdW1uJywnQ2hlY2tib3gnLCdEcm9wZG93bicsJ1JhZGlvJyxcIlRleHRcIiwgXCJDYWxlbmRhclwiLCBcIkRhdGVcIiwgXCJUaW1lXCIsIFwiRGF0ZVRpbWVcIiwgXCJFbWFpbFwiLCBcIkJvb2tcIiwgXCJMaXN0XCIsIFwiVGV4dEFyZWFcIiwgXCJSaWNoVGV4dEFyZWFcIiwgXCJOdW1iZXJcIiwgXCJJbWFnZVwiLCBcIkxhYmVsXCIsIFwiQm9vbGVhblwiLCBcIkZpbGVcIiwgXCJJY29uXCIsICdCdXR0b24nXVxuXG4gIC8vIEFkZCB0aGVzZSBwcm9wZXJ0aWVzIHRvIHlvdXIgY29tcG9uZW50IGNsYXNzXG4gIHByaXZhdGUgX2NhY2hlZFByb3BlcnRpZXM6IGFueSA9IG51bGw7XG4gIHByaXZhdGUgX2xhc3RTZWxlY3RlZEVsZW1lbnQ6IGFueSA9IG51bGw7XG4gIHByaXZhdGUgX2xhc3RTZWxlY3RlZENvbHVtbjogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgLy8gQ29tcHV0ZWQgc2lnbmFscyBmb3IgbWVtb2l6YXRpb25cbiAgZmllbGRBc1N0cmluZyA9IGNvbXB1dGVkKCgpID0+IHRoaXMuYm9va1N1YnRleHQoKS5maWVsZC5qb2luKCcsICcpKTtcbiAgZmlsdGVyZWRDb2x1bW5zID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGZpZWxkc01ldGEgPSB0aGlzLnNlbGVjdGVkRWxlbWVudCgpPy5maWVsZHNNZXRhID8/IFtdO1xuICAgIHJldHVybiBBcnJheS5pc0FycmF5KGZpZWxkc01ldGEpXG4gICAgICA/IGZpZWxkc01ldGEuZmlsdGVyKGNvbHVtbiA9PiBjb2x1bW4udW5pcXVlSWRlbnRpZmllciAhPT0gdGhpcy5zZWxlY3RDb2x1bW4oKSlcbiAgICAgIDogW107XG4gIH0pO1xuXG4gIC8vIE1lbW9pemVkIHByb3BlcnRpZXNcbiAgZWxlbWVudFByb3BlcnRpZXMgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmNyZWF0ZUVsZW1lbnRQcm9wZXJ0aWVzKCkpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgZm9ybUJ1aWxkZXJTZXJ2aWNlOiBGb3JtQnVpbGRlclNlcnZpY2UsXG4gICAgcHJpdmF0ZSB0ZW1wbGF0ZVNlcnZpY2U6IFRlbXBsYXRlU2VydmljZVxuICApIHt9XG4gIFxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5zZWxlY3RIZWFkZXJTdWJqZWN0JC5zdWJzY3JpYmUoaGVhZGVyID0+IHtcbiAgICAgIGlmIChoZWFkZXIpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZEVsZW1lbnQuc2V0KHsgdHlwZTogaGVhZGVyIH0pO1xuICAgICAgICB0aGlzLmhlYWRlclNlbGVjdC5zZXQodHJ1ZSk7XG4gICAgICAgIGNvbnN0IGJvb2tEYXRhID0gdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UuZ2V0Qm9vaygpO1xuICAgICAgICB0aGlzLmJvb2suc2V0KGJvb2tEYXRhKTtcbiAgICAgICAgdGhpcy5ib29rSWQuc2V0KGJvb2tEYXRhPy5yZWNvcmRzWzBdPy5pZCk7XG4gICAgICB9XG4gICAgfSk7XG4gIFxuICAgIHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLnNlbGVjdGVkRWxlbWVudCQuc3Vic2NyaWJlKGluZGV4ID0+IHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50SW5kZXguc2V0KGluZGV4KTtcbiAgICAgIHRoaXMuaGVhZGVyU2VsZWN0LnNldChmYWxzZSk7XG4gICAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLmdldEVsZW1lbnRzKCk7XG4gICAgICAgIGlmICghZWxlbWVudHMgfHwgIUFycmF5LmlzQXJyYXkoZWxlbWVudHMpIHx8IGluZGV4ID49IGVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50LnNldChudWxsKTsgLy8gUmVzZXQgc2VsZWN0ZWRFbGVtZW50IGlmIGludmFsaWRcbiAgICAgICAgICB0aGlzLnNlbGVjdENvbHVtbi5zZXQobnVsbCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSB7IC4uLmVsZW1lbnRzW2luZGV4XSB9OyAvLyBTYWZlIHRvIHNwcmVhZCBzaW5jZSB3ZSBjaGVja2VkXG4gICAgICAgIGxldCBmaWVsZHNNZXRhID0gZWxlbWVudD8uZmllbGRzTWV0YTtcbiAgICAgICAgaWYgKGVsZW1lbnQ/LnR5cGUgPT09ICdUYWJsZScpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgZmllbGRzTWV0YSA9IEFycmF5LmlzQXJyYXkoZmllbGRzTWV0YSlcbiAgICAgICAgICAgICAgPyBmaWVsZHNNZXRhXG4gICAgICAgICAgICAgIDogSlNPTi5wYXJzZShmaWVsZHNNZXRhIHx8ICdbXScpO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHBhcnNpbmcgZmllbGRzTWV0YTonLCBlKTtcbiAgICAgICAgICAgIGZpZWxkc01ldGEgPSBbXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5zZWxlY3RDb2x1bW4uc2V0KHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLmdldFNlbGVjdFRhYmxlQ29sdW1uKCkgPz8gbnVsbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5zZWxlY3RDb2x1bW4uc2V0KG51bGwpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50LnNldCh7IC4uLmVsZW1lbnQsIGZpZWxkc01ldGEgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnNlbGVjdGVkRWxlbWVudC5zZXQobnVsbCk7IC8vIFJlc2V0IGlmIGluZGV4IGlzIGludmFsaWRcbiAgICAgICAgdGhpcy5zZWxlY3RDb2x1bW4uc2V0KG51bGwpO1xuICAgICAgfVxuICAgIH0pO1xuICBcbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5zZWxlY3RlZEVsZW1lbnQoKTtcbiAgICBpZiAoZWxlbWVudCkge1xuICAgICAgbGV0IHN1YlRleHQgPSBlbGVtZW50LnN1YlRleHQ7XG4gICAgICBpZiAodHlwZW9mIHN1YlRleHQgPT09ICdzdHJpbmcnICYmIHN1YlRleHQudHJpbSgpICE9PSAnJykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHN1YlRleHQgPSBKU09OLnBhcnNlKHN1YlRleHQpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgLy8gY29uc29sZS5lcnJvcignRXJyb3IgcGFyc2luZyBzdWJUZXh0OicsIGUpO1xuICAgICAgICAgIHN1YlRleHQgPSB7fTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2Ygc3ViVGV4dCAhPT0gJ29iamVjdCcgfHwgc3ViVGV4dCA9PT0gbnVsbCkge1xuICAgICAgICBzdWJUZXh0ID0ge307XG4gICAgICB9XG4gICAgICBpZiAoc3ViVGV4dCAmJiBBcnJheS5pc0FycmF5KHN1YlRleHQuZmllbGQpKSB7XG4gICAgICAgIHN1YlRleHQgPSB7IC4uLnN1YlRleHQsIGZpZWxkOiBzdWJUZXh0LmZpZWxkLmpvaW4oJywgJykgfTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50LnVwZGF0ZShlbCA9PiAoeyAuLi5lbCwgc3ViVGV4dCB9KSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVFbGVtZW50UHJvcGVydGllcygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgSGVhZGVyOiB7XG4gICAgICAgIGVsZW1lbnRQcm9wczogW3sgbGFiZWw6ICdMYWJlbCcsIHBsYWNlaG9sZGVyOiAnRW50ZXIgVGV4dCcsIHR5cGU6ICd0ZXh0Jywga2V5OiAndGl0bGUnIH1dLFxuICAgICAgfSxcbiAgICAgIC8vIEFQLTE5TUFSMjUgQWRkIExpbmUgUHJvcGVydHlcbiAgICAgIExpbmU6IHtcbiAgICAgICAgZWxlbWVudFByb3BzOiBbXG4gICAgICAgICAgeyBsYWJlbDogJ0xpbmUgV2lkdGgnLCB0eXBlOiAnZmllbGRTaXplJywga2V5OiAnc2l6ZScgfSxcbiAgICAgICAgICB7IGxhYmVsOiAnUGFkZGluZyBUb3AnLCB0eXBlOiAnbnVtYmVyJywga2V5OiAncGFkZGluZ1RvcCcsIHBsYWNlaG9sZGVyOiAnRW50ZXIgcGFkZGluZyB0b3AnIH0sXG4gICAgICAgICAgeyBsYWJlbDogJ1BhZGRpbmcgQm90dG9tJywgdHlwZTogJ251bWJlcicsIGtleTogJ3BhZGRpbmdCb3R0b20nLCBwbGFjZWhvbGRlcjogJ0VudGVyIHBhZGRpbmcgYm90dG9tJyB9LFxuICAgICAgICAgIHsgbGFiZWw6ICdMaW5lIFN0eWxlJywgdHlwZTogJ3NlbGVjdCcsIGtleTogJ2xpbmVTdHlsZScsIG9wdGlvbnM6IFt7bGFiZWw6J1NvbGlkJyx2YWx1ZTonU29saWQnfSx7bGFiZWw6J0Rhc2hlZCcsdmFsdWU6J0Rhc2hlZCd9LHtsYWJlbDonRG90dGVkJyx2YWx1ZTonRG90dGVkJ31dICAgICAgICB9XG4gICAgICAgIF0sXG4gICAgICAgIGZpZWxkUHJvcHM6IFtdXG4gICAgICB9LFxuICAgICAgU3BhY2U6IHtcbiAgICAgICAgZWxlbWVudFByb3BzOiBbXG4gICAgICAgICAgeyBsYWJlbDogJ0VsZW1lbnQnLCB0eXBlOiAnbnVtYmVyJywga2V5OiAncXVlc3Rpb25OdW1iZXInIH0sXG4gICAgICAgICAgeyBsYWJlbDogJ0ZpZWxkIFNpemUnLCB0eXBlOiAnZmllbGRTaXplJywga2V5OiAnc2l6ZScgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZmllbGRQcm9wczogW11cbiAgICAgIH0sXG4gICAgICBUYWJsZToge1xuICAgICAgICBlbGVtZW50UHJvcHM6IFtcbiAgICAgICAgICB7IGxhYmVsOiAnSXMgTGFiZWwnLCBwbGFjZWhvbGRlcjogJ0VudGVyIFRleHQnLCB0eXBlOiAnY2hlY2tib3gnLCBrZXk6ICdzdHlsZS5zaG93TGFiZWwnIH0sXG4gICAgICAgICAgeyBsYWJlbDogJ3ByaW1hcnlLZXknLCBwbGFjZWhvbGRlcjogJ0VudGVyIFRleHQnLCB0eXBlOiAnY2hlY2tib3gnLCBrZXk6ICdwcmltYXJ5S2V5JyB9LFxuICAgICAgICAgIHsgbGFiZWw6ICd0YWJsZU5hbWUnLCBwbGFjZWhvbGRlcjogJ0VtcGxveWVlIERldGFpbHMnLCB0eXBlOiAndGV4dCcsIGtleTogJ3F1ZXN0aW9uVGV4dCcgfSxcbiAgICAgICAgICB7IGxhYmVsOiAnaW5wdXRUZXh0QWxpZ25tZW50JywgcGxhY2Vob2xkZXI6ICdMZWZ0JywgdHlwZTogJ3RleHQnLCBrZXk6ICdpbnB1dFRleHRBbGlnbm1lbnQnIH0sXG4gICAgICAgICAgeyBsYWJlbDogJ3RhYmxlU2NhbGVTaXplJywgcGxhY2Vob2xkZXI6ICcwNiAtIEZ1bGwgU2NhbGUnLCB0eXBlOiAndGV4dCcsIGtleTogJ3RhYmxlU2NhbGVTaXplJyB9LFxuICAgICAgICAgIHsgbGFiZWw6ICdpc05vc0luZGljYXRvcicsIHBsYWNlaG9sZGVyOiAnMDYgLSBGdWxsIFNjYWxlJywgdHlwZTogJ2NoZWNrYm94Jywga2V5OiAndGFibGVDb25maWcuaXNOb3NJbmRpY2F0b3InIH0sXG4gICAgICAgICAgeyBsYWJlbDogJ2lzUGFnaW5hdGlvbicsIHBsYWNlaG9sZGVyOiAnMDYgLSBGdWxsIFNjYWxlJywgdHlwZTogJ2NoZWNrYm94Jywga2V5OiAndGFibGVDb25maWcuaXNQYWdpbmF0aW9uJyB9LFxuICAgICAgICAgIHsgbGFiZWw6ICdhZGRJbmxpbmVSZWNvcmQnLCBwbGFjZWhvbGRlcjogJzA2IC0gRnVsbCBTY2FsZScsIHR5cGU6ICdjaGVja2JveCcsIGtleTogJ3RhYmxlQ29uZmlnLmFkZElubGluZVJlY29yZCcgfSxcbiAgICAgICAgICB7IGxhYmVsOiAnYWN0aW9uQnV0dG9uJywgcGxhY2Vob2xkZXI6ICcwNiAtIEZ1bGwgU2NhbGUnLCB0eXBlOiAnY2hlY2tib3gnLCBrZXk6ICd0YWJsZUNvbmZpZy5hY3Rpb25CdXR0b24nIH0sXG4gICAgICAgICAgeyBsYWJlbDogJ3NlYXJjaEJhcicsIHBsYWNlaG9sZGVyOiAnMDYgLSBGdWxsIFNjYWxlJywgdHlwZTogJ2NoZWNrYm94Jywga2V5OiAndGFibGVDb25maWcuc2VhcmNoQmFyJyB9LFxuICAgICAgICAgIHsgbGFiZWw6ICdpc0RlbGV0ZVJvdycsIHBsYWNlaG9sZGVyOiAnMDYgLSBGdWxsIFNjYWxlJywgdHlwZTogJ2NoZWNrYm94Jywga2V5OiAndGFibGVDb25maWcuaXNEZWxldGVSb3cnIH0sXG4gICAgICAgICAgeyBsYWJlbDogJ2lzRWRpdFJvdycsIHBsYWNlaG9sZGVyOiAnMDYgLSBGdWxsIFNjYWxlJywgdHlwZTogJ2NoZWNrYm94Jywga2V5OiAndGFibGVDb25maWcuaXNFZGl0Um93JyB9LFxuICAgICAgICAgIHsgbGFiZWw6ICdpc0J1dHRvbnMnLCBwbGFjZWhvbGRlcjogJzA2IC0gRnVsbCBTY2FsZScsIHR5cGU6ICdjaGVja2JveCcsIGtleTogJ3RhYmxlQ29uZmlnLmlzQnV0dG9ucycgfSxcbiAgICAgICAgICB7IGxhYmVsOiAncm93Q2hvaWNlJywgcGxhY2Vob2xkZXI6ICcnLCB0eXBlOiAndGV4dCcsIGtleTogJ3Jvd0Nob2ljZScgfSxcbiAgICAgICAgICB7IGxhYmVsOiAncXVlc3Rpb25OdW1iZXInLCB0eXBlOiAnbnVtYmVyJywga2V5OiAncXVlc3Rpb25OdW1iZXInIH0sXG4gICAgICAgICAgeyBsYWJlbDogJ0ZpZWxkIFNpemUnLCB0eXBlOiAnZmllbGRTaXplJywga2V5OiAnc2l6ZScgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZmllbGRQcm9wczogW1xuICAgICAgICAgIHsgbGFiZWw6ICd0YWJsZUlkJywgcGxhY2Vob2xkZXI6ICdFbXBfVGFibGVfMDEnLCB0eXBlOiAndGV4dCcsIGtleTogJ3RhYmxlSWQnIH0sXG4gICAgICAgICAgeyBsYWJlbDogJ2hlbHBUZXh0JywgcGxhY2Vob2xkZXI6ICdFbnRlciBtZXNzYWdlJywgdHlwZTogJ3RleHQnLCBrZXk6ICdoZWxwVGV4dCcgfSxcbiAgICAgICAgICB7IGxhYmVsOiAnZGVmYXVsdFZhbHVlJywgcGxhY2Vob2xkZXI6ICdEZWZhdWx0IFZhbHVlJywgdHlwZTogJ3RleHQnLCBrZXk6ICdkZWZhdWx0VmFsdWUnIH0sXG4gICAgICAgICAgeyBsYWJlbDogJ1JlZmVyZW5jZScsIHBsYWNlaG9sZGVyOiAnUmVmZXJlbmNlIEZpZWxkJywgdHlwZTogJ3RleHQnLCBrZXk6ICdyZWZlcmVuY2VGaWVsZCcgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBsYWJlbDogJ1N1YiBUZXh0JywgcGxhY2Vob2xkZXI6ICdFbnRlciBUZXh0JywgdHlwZTogJ3N1YlF1ZXN0aW9uJywga2V5OiAnaXNTdWJUZXh0JyxcbiAgICAgICAgICAgIHN1YlF1ZXN0aW9uOiBbXG4gICAgICAgICAgICAgIHsgbGFiZWw6ICdFbmQgUG9pbnQnLCBwbGFjZWhvbGRlcjogJ2VuZHBvaW50JywgdHlwZTogJ3RleHQnLCBrZXk6ICdzdWJUZXh0LmVuZHBvaW50JyB9LFxuICAgICAgICAgICAgICB7IGxhYmVsOiAnVmFyaWFibGUnLCBwbGFjZWhvbGRlcjogJ3ZhcmlhYmxlJywgdHlwZTogJ3RleHQnLCBrZXk6ICdzdWJUZXh0LnZhcmlhYmxlJyB9LFxuICAgICAgICAgICAgICB7IGxhYmVsOiAnRmllbGQnLCBwbGFjZWhvbGRlcjogJ2ZpZWxkJywgdHlwZTogJ3RleHQnLCBrZXk6ICdzdWJUZXh0LmZpZWxkJyB9LFxuICAgICAgICAgICAgICB7IGxhYmVsOiAnRGVmYXVsdCBGaWVsZCcsIHBsYWNlaG9sZGVyOiAnZGVmYXVsdEZpZWxkJywgdHlwZTogJ3RleHQnLCBrZXk6ICdzdWJUZXh0LmRlZmF1bHRGaWVsZCcgfSxcbiAgICAgICAgICAgICAgeyBsYWJlbDogJ0xhYmVsIEZpZWxkJywgcGxhY2Vob2xkZXI6ICdsYWJlbEZpZWxkJywgdHlwZTogJ3RleHQnLCBrZXk6ICdzdWJUZXh0LmxhYmVsRmllbGQnIH0sXG4gICAgICAgICAgICAgIHsgbGFiZWw6ICdWYWx1ZSBGaWVsZCcsIHBsYWNlaG9sZGVyOiAndmFsdWVGaWVsZCcsIHR5cGU6ICd0ZXh0Jywga2V5OiAnc3ViVGV4dC52YWx1ZUZpZWxkJyB9LFxuICAgICAgICAgICAgICB7IGxhYmVsOiAnU291cmNlIFF1ZXN0aW9uIElkJywgcGxhY2Vob2xkZXI6ICdzb3VyY2VRdWVzdGlvbklkJywgdHlwZTogJ3RleHQnLCBrZXk6ICdzdWJUZXh0LnNvdXJjZVF1ZXN0aW9uSWQnIH0sXG4gICAgICAgICAgICAgIHsgbGFiZWw6ICdEZXBlbmRlbnQgVmFsdWUnLCBwbGFjZWhvbGRlcjogJ2RlcGVuZGVudFZhbHVlJywgdHlwZTogJ3RleHQnLCBrZXk6ICdzdWJUZXh0LmRlcGVuZGVudFZhbHVlJyB9LFxuICAgICAgICAgICAgICB7IGxhYmVsOiAnRGVwZW5kZW50IEZpZWxkJywgcGxhY2Vob2xkZXI6ICdpc0RlcGVuZGVudEZpZWxkJywgdHlwZTogJ2Jvb2xlYW4nLCBrZXk6ICdzdWJUZXh0LmlzRGVwZW5kZW50RmllbGQnIH0sXG4gICAgICAgICAgICAgIHsgbGFiZWw6ICdRdWVyeSBGaWVsZCcsIHBsYWNlaG9sZGVyOiAncXVlcnlGaWVsZCcsIHR5cGU6ICd0ZXh0Jywga2V5OiAnc3ViVGV4dC5xdWVyeUZpZWxkJyB9LFxuICAgICAgICAgICAgICB7IGxhYmVsOiAnUXVlcnkgVmFsdWUnLCBwbGFjZWhvbGRlcjogJ3F1ZXJ5VmFsdWUnLCB0eXBlOiAndGV4dCcsIGtleTogJ3N1YlRleHQucXVlcnlWYWx1ZScgfSxcbiAgICAgICAgICAgICAgeyBsYWJlbDogJ1F1ZXJ5IFZhbHVlIFJlZicsIHBsYWNlaG9sZGVyOiAncXVlcnlWYWx1ZVJlZicsIHR5cGU6ICd0ZXh0Jywga2V5OiAnc3ViVGV4dC5xdWVyeVZhbHVlUmVmZXJlbmNlJyB9LFxuICAgICAgICAgICAgICB7IGxhYmVsOiAnVW5pcXVlIEtleScsIHBsYWNlaG9sZGVyOiAndW5pcXVlS2V5JywgdHlwZTogJ3RleHQnLCBrZXk6ICdzdWJUZXh0LnVuaXF1ZUtleScgfSxcbiAgICAgICAgICAgIF1cbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBhcHBlYXJhbmNlOiBbXG4gICAgICAgICAgeyBsYWJlbDogJ1NlbGVjdCBGb250JywgdHlwZTogJ3NlbGVjdCcsIGtleTogJ2ZvbnQnLCBwbGFjZWhvbGRlcjogJ0xlZnQnLCByZXF1aXJlZDogdHJ1ZSwgb3B0aW9uczogW3tsYWJlbDonSGVsdmV0aWNhIE5ldWUnLHZhbHVlOidIZWx2ZXRpY2EgTmV1ZSd9LHtsYWJlbDonQXJpYWwnLHZhbHVlOidBcmlhbCd9LHtsYWJlbDonVGltZXMgTmV3IFJvbWFuJyx2YWx1ZTonVGltZXMgTmV3IFJvbWFuJ30se2xhYmVsOidSb2JvdG8nLHZhbHVlOidSb2JvdG8nfV0gfSxcbiAgICAgICAgICB7IGxhYmVsOiAnRm9udCBDb2xvcicsIHR5cGU6ICdjb2xvcicsIGtleTogJ2ZvbnRDb2xvcicsIGRlZmF1bHRWYWx1ZTogJycsIHJlcXVpcmVkOiB0cnVlIH0sXG4gICAgICAgICAgeyBsYWJlbDogJ0ZvbnQgU2l6ZScsIHR5cGU6ICdzZWxlY3QnLCBrZXk6ICdmb250U2l6ZScsIGRlZmF1bHRWYWx1ZTogJycsIHJlcXVpcmVkOiB0cnVlLCBvcHRpb25zOiBbeyBsYWJlbDogJ1NtYWxsJywgdmFsdWU6ICcxMnB4JyB9LCB7IGxhYmVsOiAnTWVkaXVtJywgdmFsdWU6ICcxNHB4JyB9LCB7IGxhYmVsOiAnTGFyZ2UnLCB2YWx1ZTogJzE2cHgnIH1dIH0sXG4gICAgICAgICAgeyBsYWJlbDogJ0ZvbnQgV2lkdGgnLCB0eXBlOiAnc2VsZWN0Jywga2V5OiAnZm9udFdlaWdodCcsIGRlZmF1bHRWYWx1ZTogJycsIHJlcXVpcmVkOiB0cnVlLCBvcHRpb25zOiBbeyB2YWx1ZTogJzQwMCcsIGxhYmVsOiAnNDAwLU5vcm1hbCcgfSwgeyB2YWx1ZTogJzUwMCcsIGxhYmVsOiAnNTAwLU1lZGl1bScgfSwgeyB2YWx1ZTogJzYwMCcsIGxhYmVsOiAnNjAwLVNlbWkgQm9sZCcgfSwgeyB2YWx1ZTogJzcwMCcsIGxhYmVsOiAnNzAwLUJvbGQnIH1dIH0sXG4gICAgICAgICAgeyBsYWJlbDogJ0R1cGxpY2F0ZSBGaWVsZCcsIHR5cGU6ICdidXR0b24tdG9nZ2xlJywga2V5OiAnZHVwbGljYXRlRmllbGQnLCBkZWZhdWx0VmFsdWU6IGZhbHNlIH1cbiAgICAgICAgXVxuICAgICAgfSxcbiAgICAgIFRhYmxlQ29sdW1uOiB7XG4gICAgICAgIGVsZW1lbnRQcm9wczogW1xuICAgICAgICAgIHsgbGFiZWw6ICdUeXBlJywgcGxhY2Vob2xkZXI6ICdUZXh0JywgdHlwZTogJ3NlbGVjdCcsIHRhcmdldEFycmF5OiAnZmllbGRzTWV0YScsIHRhcmdldEFycmF5S2V5OiAndW5pcXVlSWRlbnRpZmllcicsIGtleTogJ2ZsZFR5cGUnLCByZXF1aXJlZDogdHJ1ZSAsIG9wdGlvbnM6IHRoaXMuZWxlbWVudFR5cGUubWFwKGYgPT4gKHsgbGFiZWw6IGYsIHZhbHVlOiBmIH0pKX0sXG4gICAgICAgICAgeyBsYWJlbDogJ2hlYWRlckxhYmVscycsIHBsYWNlaG9sZGVyOiAnRW1wbG95ZWUgRGV0YWlscycsIHR5cGU6ICd0ZXh0JywgdGFyZ2V0QXJyYXk6ICdmaWVsZHNNZXRhJywgdGFyZ2V0QXJyYXlLZXk6ICd1bmlxdWVJZGVudGlmaWVyJywga2V5OiAnbGFiZWwnIH0sXG4gICAgICAgICAgeyBsYWJlbDogJ2FwaU5hbWUnLCBwbGFjZWhvbGRlcjogJ0VtcGxveWVlIERldGFpbHMnLCB0eXBlOiAndGV4dCcsIHRhcmdldEFycmF5OiAnZmllbGRzTWV0YScsIHRhcmdldEFycmF5S2V5OiAndW5pcXVlSWRlbnRpZmllcicsIGtleTogJ2FwaU5hbWUnIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbGFiZWw6ICdTdW1tYXJ5IENvbHVtbicsIHBsYWNlaG9sZGVyOiAnU3VtbWFyeSBDb2x1bW4nLCB0eXBlOiAnc3ViUXVlc3Rpb24nLCB0YXJnZXRBcnJheTogJ2ZpZWxkc01ldGEnLCB0YXJnZXRBcnJheUtleTogJ3VuaXF1ZUlkZW50aWZpZXInLCBrZXk6ICdzdW1tYXJ5Q29sdW1uJyxcbiAgICAgICAgICAgIHN1YlF1ZXN0aW9uOiBbXG4gICAgICAgICAgICAgIHsgbGFiZWw6ICdUeXBlJywgcGxhY2Vob2xkZXI6ICdFbXBsb3llZSBEZXRhaWxzJywgdHlwZTogJ3RleHQnLCB0YXJnZXRBcnJheTogJ2ZpZWxkc01ldGEnLCB0YXJnZXRBcnJheUtleTogJ3VuaXF1ZUlkZW50aWZpZXInLCBrZXk6ICdmbGRUeXBlJyB9LFxuICAgICAgICAgICAgICB7IGxhYmVsOiAnT3BlcmF0aW9uJywgcGxhY2Vob2xkZXI6ICdFbXBsb3llZSBEZXRhaWxzJywgdHlwZTogJ3RleHQnLCB0YXJnZXRBcnJheTogJ2ZpZWxkc01ldGEnLCB0YXJnZXRBcnJheUtleTogJ3VuaXF1ZUlkZW50aWZpZXInLCBrZXk6ICdvcGVyYXRpb24nIH0sXG4gICAgICAgICAgICAgIHsgbGFiZWw6ICdPcGVyYW5kcycsIHBsYWNlaG9sZGVyOiAnRW1wbG95ZWUgRGV0YWlscycsIHR5cGU6ICdhcnJheScsIHRhcmdldEFycmF5OiAnZmllbGRzTWV0YScsIHRhcmdldEFycmF5S2V5OiAndW5pcXVlSWRlbnRpZmllcicsIGtleTogJ29wZXJhbmRzJyB9LFxuICAgICAgICAgICAgXVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbGFiZWw6ICdTdW1tYXJ5IFJvdycsIHBsYWNlaG9sZGVyOiAnU3VtbWFyeSBSb3cnLCB0eXBlOiAnc3ViUXVlc3Rpb24nLCB0YXJnZXRBcnJheTogJ2ZpZWxkc01ldGEnLCB0YXJnZXRBcnJheUtleTogJ3VuaXF1ZUlkZW50aWZpZXInLCBrZXk6ICdzdW1tYXJ5Um93JyxcbiAgICAgICAgICAgIHN1YlF1ZXN0aW9uOiBbXG4gICAgICAgICAgICAgIHsgbGFiZWw6ICdUeXBlJywgcGxhY2Vob2xkZXI6ICdFbXBsb3llZSBEZXRhaWxzJywgdHlwZTogJ3RleHQnLCB0YXJnZXRBcnJheTogJ2ZpZWxkc01ldGEnLCB0YXJnZXRBcnJheUtleTogJ3VuaXF1ZUlkZW50aWZpZXInLCBrZXk6ICdmbGRUeXBlJyB9LFxuICAgICAgICAgICAgICB7IGxhYmVsOiAnb3BlcmF0aW9uJywgcGxhY2Vob2xkZXI6ICdvcGVyYXRpb24nLCB0eXBlOiAndGV4dCcsIHRhcmdldEFycmF5OiAnZmllbGRzTWV0YScsIHRhcmdldEFycmF5S2V5OiAndW5pcXVlSWRlbnRpZmllcicsIGtleTogJ29wZXJhdGlvbicgfSxcbiAgICAgICAgICAgICAgeyBsYWJlbDogJ2NvbHVtbicsIHBsYWNlaG9sZGVyOiAnRW1wbG95ZWUgRGV0YWlscycsIHR5cGU6ICdyYWRpbycsIHRhcmdldEFycmF5OiAnZmllbGRzTWV0YScsIHRhcmdldEFycmF5S2V5OiAndW5pcXVlSWRlbnRpZmllcicsIGtleTogJ2NvbHVtbicgfSxcbiAgICAgICAgICAgICAgeyBsYWJlbDogJ2NvbHVtbnMnLCBwbGFjZWhvbGRlcjogJ0VtcGxveWVlIERldGFpbHMnLCB0eXBlOiAnYXJyYXknLCB0YXJnZXRBcnJheTogJ2ZpZWxkc01ldGEnLCB0YXJnZXRBcnJheUtleTogJ3VuaXF1ZUlkZW50aWZpZXInLCBrZXk6ICdjb2x1bW5zJyB9LFxuICAgICAgICAgICAgICB7IGxhYmVsOiAnb3BlcmFuZHMnLCBwbGFjZWhvbGRlcjogJ0VtcGxveWVlIERldGFpbHMnLCB0eXBlOiAnYXJyYXknLCB0YXJnZXRBcnJheTogJ2ZpZWxkc01ldGEnLCB0YXJnZXRBcnJheUtleTogJ3VuaXF1ZUlkZW50aWZpZXInLCBrZXk6ICdvcGVyYW5kcycgfSxcbiAgICAgICAgICAgIF1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHsgbGFiZWw6ICd0ZXh0QWxpZ25tZW50JywgcGxhY2Vob2xkZXI6ICdMZWZ0JywgdHlwZTogJ3RleHQnLCB0YXJnZXRBcnJheTogJ2ZpZWxkc01ldGEnLCB0YXJnZXRBcnJheUtleTogJ3VuaXF1ZUlkZW50aWZpZXInLCBrZXk6ICd0ZXh0QWxpZ25tZW50JyB9LFxuICAgICAgICAgIHsgbGFiZWw6ICdjb2x1bW5TY2FsZVNpemUnLCBwbGFjZWhvbGRlcjogJzA2IC0gRnVsbCBTY2FsZScsIHR5cGU6ICd0ZXh0JywgdGFyZ2V0QXJyYXk6ICdmaWVsZHNNZXRhJywgdGFyZ2V0QXJyYXlLZXk6ICd1bmlxdWVJZGVudGlmaWVyJywga2V5OiAnY29sdW1uU2NhbGVTaXplJyB9LFxuICAgICAgICBdLFxuICAgICAgICBmaWVsZFByb3BzOiBbXSxcbiAgICAgICAgYXBwZWFyYW5jZTogW11cbiAgICAgIH0sXG4gICAgICBDaGVja2JveDogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKHsgY3VzdG9tRmllbGRQcm9wczogQ09NTU9OX09QVElPTlNfRklFTEQubWFwKG9wdCA9PiAoeyAuLi5vcHQsIHR5cGU6ICdjaGVja2JveCcgfSkpIH0pLFxuICAgICAgRHJvcGRvd246IHRoaXMuY3JlYXRlRWxlbWVudENvbmZpZyh7IGN1c3RvbUZpZWxkUHJvcHM6IENPTU1PTl9PUFRJT05TX0ZJRUxELm1hcChvcHQgPT4gKHsgLi4ub3B0LCB0eXBlOiAnZHJvcGRvd24nIH0pKSB9KSxcbiAgICAgIFJhZGlvOiB0aGlzLmNyZWF0ZUVsZW1lbnRDb25maWcoeyBjdXN0b21GaWVsZFByb3BzOiBDT01NT05fT1BUSU9OU19GSUVMRC5tYXAob3B0ID0+ICh7IC4uLm9wdCwgdHlwZTogJ2NoZWNrYm94JyB9KSkgfSksXG4gICAgICBUZXh0OiB0aGlzLmNyZWF0ZUVsZW1lbnRDb25maWcoKSxcbiAgICAgIENhbGVuZGFyOiB0aGlzLmNyZWF0ZUVsZW1lbnRDb25maWcoKSxcbiAgICAgIERhdGU6IHRoaXMuY3JlYXRlRWxlbWVudENvbmZpZygpLFxuICAgICAgVGltZTogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKCksXG4gICAgICBEYXRlVGltZTogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKCksXG4gICAgICBFbWFpbDogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKCksXG4gICAgICBCb29rOiB0aGlzLmNyZWF0ZUVsZW1lbnRDb25maWcoKSxcbiAgICAgIExpc3Q6IHRoaXMuY3JlYXRlRWxlbWVudENvbmZpZygpLFxuICAgICAgVGV4dEFyZWE6IHRoaXMuY3JlYXRlRWxlbWVudENvbmZpZygpLFxuICAgICAgUmljaFRleHRBcmVhOiB0aGlzLmNyZWF0ZUVsZW1lbnRDb25maWcoKSxcbiAgICAgIE51bWJlcjogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKCksXG4gICAgICBJbWFnZTogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKCksXG4gICAgICBMYWJlbDogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKCksXG4gICAgICBCb29sZWFuOiB0aGlzLmNyZWF0ZUVsZW1lbnRDb25maWcoKSxcbiAgICAgIEZpbGU6IHRoaXMuY3JlYXRlRWxlbWVudENvbmZpZygpLFxuICAgICAgSWNvbjogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKCksIC8vTVNNMTBKVUwyNSBpY29uIHNlbGVjdG9yIGVsZW1lbnRcbiAgICAgIEJ1dHRvbjogdGhpcy5jcmVhdGVFbGVtZW50Q29uZmlnKCksXG4gICAgfTtcbiAgfVxuXG4gIGNyZWF0ZUVsZW1lbnRDb25maWcoY29uZmlnPzogeyBjdXN0b21FbGVtZW50UHJvcHM/OiBhbnlbXSwgY3VzdG9tRmllbGRQcm9wcz86IGFueVtdLCBjdXN0b21BcHBlYXJhbmNlUHJvcHM/OiBhbnlbXSB9KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGVsZW1lbnRQcm9wczogWy4uLkNPTU1PTl9FTEVNRU5UX1BST1BTLCAuLi4oY29uZmlnPy5jdXN0b21FbGVtZW50UHJvcHMgfHwgW10pXSxcbiAgICAgIGZpZWxkUHJvcHM6IFsuLi5DT01NT05fRklFTERfUFJPUFMsIC4uLihjb25maWc/LmN1c3RvbUZpZWxkUHJvcHMgfHwgW10pXSxcbiAgICAgIGFwcGVhcmFuY2U6IFsuLi5DT01NT05fQVBQRUFSQU5DRV9QUk9QUywgLi4uKGNvbmZpZz8uY3VzdG9tQXBwZWFyYW5jZVByb3BzIHx8IFtdKV1cbiAgICB9O1xuICB9XG4gIC8vIEFQIDIzTUFZMjUgLSBBZGQgYSBuZXcgYnV0dG9uIHdpdGggZGVmYXVsdCBzdHlsaW5nXG4gIGFkZE5ld0J1dHRvbigpIHtcbiAgICBjb25zdCBsYXN0UGVyY2VudCA9IHRoaXMuYm9vaygpPy5xdWVzdGlvbmJvb2s/LmFjdGlvbj8uc2xpY2UoLTEpWzBdPy5wb3NpdGlvblBlcmNlbnQgPz8gMDtcbiAgICBjb25zdCBidXR0b25zID0ge1xuICAgICAgbmFtZTogJycsXG4gICAgICBldmVudHRvZW1pdDogJycsXG4gICAgICBhbHQ6ICcnLFxuICAgICAgZW5kcG9pbnQ6ICcnLFxuICAgICAgbWV0aG9kOiAnJyxcbiAgICAgIGlkOiB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5hZGRFbGVtZW50V2l0aElkKCksXG4gICAgICBwb3NpdGlvblBlcmNlbnQ6IGxhc3RQZXJjZW50ICsgMTAsXG4gICAgICB3aWR0aDogMTAwLFxuICAgICAgYm9yZGVyUmFkaXVzOiA2LFxuICAgICAgYWxpZ25tZW50OiAnZmxleC1zdGFydCdcbiAgICB9O1xuICAgIHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLnVwZGF0ZVF1ZXN0aW9uQm9va0FjdGlvbkJ1dHRvbnMoYnV0dG9ucywgJ2FkZCcpO1xuICAgIHRoaXMuYm9vay51cGRhdGUoYm9vayA9PiAoeyAuLi5ib29rIH0pKTtcbiAgfVxuICAvL0FQIDIzTUFZMjUgLSBSZW1vdmUgYSBidXR0b24gZnJvbSB0aGUgYWN0aW9uIGxpc3QgXG4gIHJlbW92ZUJ1dHRvbihidG46IGFueSkge1xuICAgIHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLnVwZGF0ZVF1ZXN0aW9uQm9va0FjdGlvbkJ1dHRvbnMoYnRuLCAncmVtb3ZlJyk7XG4gICAgdGhpcy5ib29rLnVwZGF0ZShib29rID0+ICh7IC4uLmJvb2sgfSkpO1xuICB9XG4gIC8vQVAgMjNNQVkyNSAtIFVwZGF0ZSBhIHNwZWNpZmljIHByb3BlcnR5IG9mIGEgYnV0dG9uXG4gIG9uQnV0dG9uUHJvcGVydHlDaGFuZ2UoaW5kZXg6IG51bWJlciwga2V5OiBzdHJpbmcsIHZhbHVlOiBhbnkpIHtcbiAgICBjb25zdCBidXR0b25zID0gdGhpcy5ib29rKCk/LnF1ZXN0aW9uYm9vaz8uYWN0aW9uID8/IFtdO1xuICAgIGlmIChidXR0b25zW2luZGV4XSkge1xuICAgICAgYnV0dG9uc1tpbmRleF1ba2V5XSA9IHZhbHVlO1xuICAgICAgdGhpcy5ib29rLnVwZGF0ZShib29rID0+ICh7IC4uLmJvb2ssIHF1ZXN0aW9uYm9vazogeyAuLi5ib29rLnF1ZXN0aW9uYm9vaywgYWN0aW9uOiBidXR0b25zIH0gfSkpO1xuICAgIH1cbiAgfVxuICAvL0FQLTEwTUFSMjUgVXBkYXRlcyB0aGUgdGl0bGUgdXNpbmcgdGhlIGZvcm0gYnVpbGRlciBzZXJ2aWNlICBcbiAgdXBkYXRlVGl0bGUodmFsdWU6IHN0cmluZykge1xuICAgIHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLnVwZGF0ZVRpdGxlKHZhbHVlKTtcbiAgICB0aGlzLmJvb2sudXBkYXRlKGJvb2sgPT4gKHtcbiAgICAgIC4uLmJvb2ssXG4gICAgICByZWNvcmRzOiBbeyAuLi5ib29rLnJlY29yZHNbMF0sIHRpdGxlOiB2YWx1ZSB9XVxuICAgIH0pKTtcbiAgfVxuXG4gIHZhbGlkYXRlSW5wdXQodmFsdWU6IHN0cmluZywgdHlwZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKHR5cGUgPT09ICdsYWJlbCcgfHwgdHlwZSA9PT0gJ3BsYWNlaG9sZGVyJykge1xuICAgICAgY29uc3QgcmVnZXggPSAvXlthLXpBLVowLTlcXHNdKiQvO1xuICAgICAgaWYgKCFyZWdleC50ZXN0KHZhbHVlKSkge1xuICAgICAgICB0aGlzLmVycm9yTWVzc2FnZS5zZXQoJ09ubHkgbGV0dGVycyBhbmQgbnVtYmVycyBhcmUgYWxsb3dlZCcpO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuZXJyb3JNZXNzYWdlLnNldCgnJyk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICB1cGRhdGVGaWVsZCh2YWx1ZTogc3RyaW5nKSB7XG4gICAgdGhpcy5ib29rU3VidGV4dC51cGRhdGUoc3VidGV4dCA9PiAoe1xuICAgICAgLi4uc3VidGV4dCxcbiAgICAgIGZpZWxkOiB2YWx1ZS5zcGxpdCgnLCcpLm1hcChpdGVtID0+IGl0ZW0udHJpbSgpKVxuICAgIH0pKTtcbiAgfVxuXG4gIG9uQ2hlY2tib3hDaGFuZ2UodGFyZ2V0QXJyYXlQYXRoOiBhbnksIHRhcmdldEFycmF5S2V5OiBhbnksIGtleTogYW55LCBhcGlOYW1lOiBzdHJpbmcsIGlzQ2hlY2tlZDogYm9vbGVhbikge1xuICAgIGNvbnN0IHRhcmdldEFycmF5ID0gdGhpcy5nZXREYXRhQnlQYXRoKHRhcmdldEFycmF5UGF0aCk7XG4gICAgY29uc3QgZm91bmRJdGVtID0gdGFyZ2V0QXJyYXkuZmluZChpdGVtID0+IGl0ZW1bdGFyZ2V0QXJyYXlLZXldID09PSB0aGlzLnNlbGVjdENvbHVtbigpKTtcbiAgICBmb3VuZEl0ZW1ba2V5XSA9IGZvdW5kSXRlbVtrZXldID8gZm91bmRJdGVtW2tleV0gOiBbXTtcbiAgICBpZiAoaXNDaGVja2VkKSB7XG4gICAgICBpZiAoIWZvdW5kSXRlbVtrZXldLmluY2x1ZGVzKGFwaU5hbWUpKSB7XG4gICAgICAgIGZvdW5kSXRlbVtrZXldLnB1c2goYXBpTmFtZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGluZGV4ID0gZm91bmRJdGVtW2tleV0uaW5kZXhPZihhcGlOYW1lKTtcbiAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgIGZvdW5kSXRlbVtrZXldLnNwbGljZShpbmRleCwgMSk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMudXBkYXRlRWxlbWVudCh0aGlzLnNlbGVjdGVkRWxlbWVudCgpKTtcbiAgfVxuXG4gIHVwZGF0ZVByb3BlcnR5KGtleTogc3RyaW5nLCB2YWx1ZTogYW55KSB7XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRFbGVtZW50SW5kZXgoKSA+PSAwKSB7XG4gICAgICBpZiAoa2V5ID09PSAncXVlc3Rpb25UZXh0JyB8fCBrZXkgPT09ICdxdWVzdGlvbicpIHtcbiAgICAgICAgaWYgKCF0aGlzLnZhbGlkYXRlSW5wdXQodmFsdWUsIGtleSkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChrZXkgPT09ICdxdWVzdGlvbk51bWJlcicpIHtcbiAgICAgICAgLy9BUC0xME1BUjI1IENvbnZlcnQgdGhlIHZhbHVlIHRvIGFuIGludGVnZXIgIFxuICAgICAgICBjb25zdCBuZXdPcmRlciA9IHBhcnNlSW50KHZhbHVlLCAxMCk7XG4gICAgICAgIGlmIChpc05hTihuZXdPcmRlcikpIHJldHVybjtcblxuICAgICAgICAvL0FQLTEwTUFSMjUgVXBkYXRlIHRoZSBlbGVtZW50J3MgcXVlc3Rpb25OdW1iZXIgaW4gdGhlIGZvcm0gYnVpbGRlciBzZXJ2aWNlICBcbiAgICAgICAgdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UudXBkYXRlRWxlbWVudCh0aGlzLnNlbGVjdGVkRWxlbWVudEluZGV4KCksIHsgcXVlc3Rpb25OdW1iZXI6IG5ld09yZGVyIH0pO1xuXG4gICAgICAgIC8vQVAtMTBNQVIyNSBTb3J0IGVsZW1lbnRzIGJhc2VkIG9uIHRoZSB1cGRhdGVkIHF1ZXN0aW9uTnVtYmVyICBcbiAgICAgICAgdGhpcy5mb3JtQnVpbGRlclNlcnZpY2Uuc29ydEVsZW1lbnRzQnlPcmRlcigpO1xuICAgICAgfVxuICAgICAgaWYgKGtleSA9PT0gJ2ZvbnQnIHx8IGtleSA9PT0gJ2ZvbnRXZWlnaHQnKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50LnVwZGF0ZShlbCA9PiAoeyAuLi5lbCwgW2tleV06IHZhbHVlIH0pKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHVwZGF0ZSA9IHsgW2tleV06IHZhbHVlIH07XG4gICAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS51cGRhdGVFbGVtZW50KHRoaXMuc2VsZWN0ZWRFbGVtZW50SW5kZXgoKSwgdXBkYXRlKTtcbiAgICB9XG4gIH1cblxuICBvblJhZGlvQ2hhbmdlKHRhcmdldEFycmF5UGF0aDogYW55LCB0YXJnZXRBcnJheUtleTogYW55LCBrZXk6IGFueSwgdmFsdWU6IGFueSkge1xuICAgIGlmICh0aGlzLnNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnKSB7XG4gICAgICBsZXQgdGFyZ2V0QXJyYXkgPSB0aGlzLmdldERhdGFCeVBhdGgodGFyZ2V0QXJyYXlQYXRoKTtcbiAgICAgIGlmICh0eXBlb2YgdGFyZ2V0QXJyYXkgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdGFyZ2V0QXJyYXkgPSBKU09OLnBhcnNlKHRhcmdldEFycmF5IHx8ICdbXScpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgLy8gY29uc29sZS5lcnJvcignRXJyb3IgcGFyc2luZyB0YXJnZXRBcnJheTonLCBlKTtcbiAgICAgICAgICB0YXJnZXRBcnJheSA9IFtdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkodGFyZ2V0QXJyYXkpKSByZXR1cm47XG4gICAgICBsZXQgZm91bmRJdGVtID0gdGFyZ2V0QXJyYXkuZmluZChpdGVtID0+IGl0ZW1bdGFyZ2V0QXJyYXlLZXldID09PSB0aGlzLnNlbGVjdENvbHVtbigpKTtcbiAgICAgIGlmICghZm91bmRJdGVtKSB7XG4gICAgICAgIGZvdW5kSXRlbSA9IHsgW3RhcmdldEFycmF5S2V5XTogdGhpcy5zZWxlY3RDb2x1bW4oKSB9O1xuICAgICAgICB0YXJnZXRBcnJheS5wdXNoKGZvdW5kSXRlbSk7XG4gICAgICB9XG4gICAgICBjb25zdCBrZXlzID0ga2V5LnNwbGl0KCcuJyk7XG4gICAgICBsZXQgb2JqID0gZm91bmRJdGVtO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICBjb25zdCBrID0ga2V5c1tpXTtcbiAgICAgICAgaWYgKCFvYmpba10pIG9ialtrXSA9IHt9O1xuICAgICAgICBvYmogPSBvYmpba107XG4gICAgICB9XG4gICAgICBvYmpba2V5c1trZXlzLmxlbmd0aCAtIDFdXSA9IHZhbHVlO1xuICAgICAgdGhpcy5zZWxlY3RlZEVsZW1lbnQudXBkYXRlKGVsID0+ICh7XG4gICAgICAgIC4uLmVsLFxuICAgICAgICBmaWVsZHNNZXRhOiB0YXJnZXRBcnJheVxuICAgICAgfSkpO1xuICAgICAgdGhpcy51cGRhdGVFbGVtZW50KHRoaXMuc2VsZWN0ZWRFbGVtZW50KCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNldFZhbHVlQnlQYXRoKGtleSwgdmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIG9uUmVxdWlyZWRDaGFuZ2UodmFsdWU6IGJvb2xlYW4pIHtcbiAgICBpZiAodGhpcy5zZWxlY3RlZEVsZW1lbnQoKSkge1xuICAgICAgbGV0IGxhYmVsID0gdGhpcy5zZWxlY3RlZEVsZW1lbnQoKS5sYWJlbCA/IHRoaXMuc2VsZWN0ZWRFbGVtZW50KCkubGFiZWwucmVwbGFjZSgvXFxzKlxcKiskLywgJycpIDogJ0xhYmVsJztcbiAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICBsYWJlbCA9IGAke2xhYmVsfSAqYDtcbiAgICAgIH1cbiAgICAgIHRoaXMudXBkYXRlUHJvcGVydHkoJ2xhYmVsJywgbGFiZWwpO1xuICAgICAgdGhpcy51cGRhdGVQcm9wZXJ0eSgnaXNPcHRpb25hbCcsIHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICB0b2dnbGVTdWJRdWVzdGlvbihwcm9wOiBhbnkpIHtcbiAgICB0aGlzLmlzRXhwYW5kZWQgPSAhdGhpcy5pc0V4cGFuZGVkO1xuICB9XG5cbiAgdG9nZ2xlU3R5bGVTZWN0aW9uKCkge1xuICAgIHRoaXMuaXNTdHlsZUV4cGFuZGVkLnNldCghdGhpcy5pc1N0eWxlRXhwYW5kZWQoKSk7XG4gIH1cblxuICBnZXRQcm9wZXJ0aWVzKCkge1xuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLnNlbGVjdGVkRWxlbWVudCgpO1xuICAgIGNvbnN0IHNlbGVjdGVkQ29sdW1uID0gdGhpcy5zZWxlY3RDb2x1bW4oKTtcbiAgICBcbiAgICAvLyBDaGVjayBpZiB3ZSBjYW4gdXNlIGNhY2hlZCByZXN1bHRcbiAgICBpZiAodGhpcy5fY2FjaGVkUHJvcGVydGllcyAmJiBcbiAgICAgICAgdGhpcy5fbGFzdFNlbGVjdGVkRWxlbWVudCA9PT0gZWxlbWVudCAmJiBcbiAgICAgICAgdGhpcy5fbGFzdFNlbGVjdGVkQ29sdW1uID09PSBzZWxlY3RlZENvbHVtbikge1xuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZFByb3BlcnRpZXM7XG4gICAgfSAgICBcbiAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgIHRoaXMuX2NhY2hlZFByb3BlcnRpZXMgPSBudWxsO1xuICAgICAgdGhpcy5fbGFzdFNlbGVjdGVkRWxlbWVudCA9IG51bGw7XG4gICAgICB0aGlzLl9sYXN0U2VsZWN0ZWRDb2x1bW4gPSBudWxsO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICBcbiAgICBsZXQgcmVzdWx0ID0gbnVsbDtcbiAgICBcbiAgICBpZiAoZWxlbWVudC50eXBlID09PSAnSGVhZGVyJykge1xuICAgICAgcmVzdWx0ID0gdGhpcy5lbGVtZW50UHJvcGVydGllcygpWydIZWFkZXInXTtcbiAgICB9IGVsc2UgaWYgKGVsZW1lbnQudHlwZSA9PT0gJ1RhYmxlJyAmJiBzZWxlY3RlZENvbHVtbiAhPT0gbnVsbCkge1xuICAgICAgbGV0IGZpZWxkc01ldGEgPSBlbGVtZW50LmZpZWxkc01ldGE7XG4gICAgICB0cnkge1xuICAgICAgICBmaWVsZHNNZXRhID0gQXJyYXkuaXNBcnJheShmaWVsZHNNZXRhKVxuICAgICAgICAgID8gZmllbGRzTWV0YVxuICAgICAgICAgIDogSlNPTi5wYXJzZShmaWVsZHNNZXRhIHx8ICdbXScpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyBjb25zb2xlLmVycm9yKCdFcnJvciBwYXJzaW5nIGZpZWxkc01ldGEgaW4gZ2V0UHJvcGVydGllczonLCBlKTtcbiAgICAgICAgZmllbGRzTWV0YSA9IFtdO1xuICAgICAgfVxuICAgICAgXG4gICAgICBjb25zdCBjb2x1bW4gPSBmaWVsZHNNZXRhLmZpbmQoKGM6IGFueSkgPT4gYy51bmlxdWVJZGVudGlmaWVyID09PSBzZWxlY3RlZENvbHVtbik7XG4gICAgICBpZiAoY29sdW1uKSB7XG4gICAgICAgIGNvbnN0IG1hcmtJc1RhYmxlQ29sdW1uID0gKGl0ZW1zOiBhbnlbXSA9IFtdKSA9PlxuICAgICAgICAgIGl0ZW1zLm1hcChpdGVtID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG5ld0l0ZW0gPSB7IC4uLml0ZW0sIGlzVGFibGVDb2x1bW46IHRydWUgfTtcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KG5ld0l0ZW0uc3ViUXVlc3Rpb24pKSB7XG4gICAgICAgICAgICAgIG5ld0l0ZW0uc3ViUXVlc3Rpb24gPSBuZXdJdGVtLnN1YlF1ZXN0aW9uLm1hcChzdWIgPT4gKHtcbiAgICAgICAgICAgICAgICAuLi5zdWIsXG4gICAgICAgICAgICAgICAgaXNUYWJsZUNvbHVtbjogdHJ1ZVxuICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbmV3SXRlbTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgXG4gICAgICAgIHJlc3VsdCA9IHtcbiAgICAgICAgICBlbGVtZW50UHJvcHM6IFtcbiAgICAgICAgICAgIC4uLih0aGlzLmVsZW1lbnRQcm9wZXJ0aWVzKClbJ1RhYmxlQ29sdW1uJ10uZWxlbWVudFByb3BzIHx8IFtdKSxcbiAgICAgICAgICAgIC4uLm1hcmtJc1RhYmxlQ29sdW1uKHRoaXMuZWxlbWVudFByb3BlcnRpZXMoKVt0aGlzLmVsZW1lbnRUeXBlLmluY2x1ZGVzKGNvbHVtbi5mbGRUeXBlKSA/IGNvbHVtbi5mbGRUeXBlIDogJ1RleHQnXT8uZWxlbWVudFByb3BzKVxuICAgICAgICAgIF0sXG4gICAgICAgICAgZmllbGRQcm9wczogW1xuICAgICAgICAgICAgLi4uKHRoaXMuZWxlbWVudFByb3BlcnRpZXMoKVsnVGFibGVDb2x1bW4nXS5maWVsZFByb3BzIHx8IFtdKSxcbiAgICAgICAgICAgIC4uLm1hcmtJc1RhYmxlQ29sdW1uKHRoaXMuZWxlbWVudFByb3BlcnRpZXMoKVt0aGlzLmVsZW1lbnRUeXBlLmluY2x1ZGVzKGNvbHVtbi5mbGRUeXBlKSA/IGNvbHVtbi5mbGRUeXBlIDogJ1RleHQnXT8uZmllbGRQcm9wcylcbiAgICAgICAgICBdLFxuICAgICAgICAgIGFwcGVhcmFuY2U6IFtcbiAgICAgICAgICAgIC4uLih0aGlzLmVsZW1lbnRQcm9wZXJ0aWVzKClbJ1RhYmxlQ29sdW1uJ10uYXBwZWFyYW5jZSB8fCBbXSksXG4gICAgICAgICAgICAuLi5tYXJrSXNUYWJsZUNvbHVtbih0aGlzLmVsZW1lbnRQcm9wZXJ0aWVzKClbdGhpcy5lbGVtZW50VHlwZS5pbmNsdWRlcyhjb2x1bW4uZmxkVHlwZSkgPyBjb2x1bW4uZmxkVHlwZSA6ICdUZXh0J10/LmFwcGVhcmFuY2UpXG4gICAgICAgICAgXVxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0ID0gdGhpcy5lbGVtZW50UHJvcGVydGllcygpWydUYWJsZUNvbHVtbiddO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQgPSB0aGlzLmVsZW1lbnRQcm9wZXJ0aWVzKClbZWxlbWVudC50eXBlXTtcbiAgICB9XG4gICAgXG4gICAgLy8gQ2FjaGUgdGhlIHJlc3VsdFxuICAgIHRoaXMuX2NhY2hlZFByb3BlcnRpZXMgPSByZXN1bHQ7XG4gICAgdGhpcy5fbGFzdFNlbGVjdGVkRWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgdGhpcy5fbGFzdFNlbGVjdGVkQ29sdW1uID0gc2VsZWN0ZWRDb2x1bW47XG4gICAgXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICAvLyBBZGQgbWV0aG9kIHRvIGNsZWFyIGNhY2hlIHdoZW4gbmVlZGVkXG4gIHByaXZhdGUgY2xlYXJQcm9wZXJ0aWVzQ2FjaGUoKSB7XG4gICAgdGhpcy5fY2FjaGVkUHJvcGVydGllcyA9IG51bGw7XG4gICAgdGhpcy5fbGFzdFNlbGVjdGVkRWxlbWVudCA9IG51bGw7XG4gICAgdGhpcy5fbGFzdFNlbGVjdGVkQ29sdW1uID0gbnVsbDtcbiAgfVxuICAvLyBBUC0yOE1BUjI1IEFkZCBhbiBvcHRpb24gd2l0aCBhIHVuaXF1ZSBVVUlEXG4gIGFkZE9wdGlvbihvcHRpb25zOiBhbnlbXSkge1xuICAgIGNvbnN0IHVuaXF1ZV9pZCA9IHV1aWR2NCgpO1xuICAgIG9wdGlvbnMucHVzaCh7IGlkOiB1bmlxdWVfaWQsIHZhbHVlOiAnJyB9KTtcbiAgfVxuXG4gIC8vIEFQLTI4TUFSMjUgRnVuY3Rpb24gdG8gcmVtb3ZlIGFuIG9wdGlvbiBiYXNlZCBvbiBpdHMgdW5pcXVlIFVVSURcbiAgcmVtb3ZlT3B0aW9uKG9wdGlvbnM6IGFueVtdLCBpZDogc3RyaW5nKSB7XG4gICAgY29uc3QgaW5kZXggPSBvcHRpb25zLmZpbmRJbmRleChvcHRpb24gPT4gb3B0aW9uLmlkID09PSBpZCk7XG4gICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgb3B0aW9ucy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIH1cbiAgfVxuXG4gIGhhbmRsZUJ1dHRvbkNsaWNrKCkge1xuICAgIHRoaXMuZm9ybUJ1dHRvbkhhbmRsZXIuZW1pdCh0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5kb3dubG9hZEVsZW1lbnQoKSk7XG4gIH1cblxuICBoYW5kbGVUZW1wbGF0ZVNhdmUoKSB7XG4gICAgdGhpcy50ZW1wbGF0ZVNhdmVIYW5kbGVyLmVtaXQodGhpcy50ZW1wbGF0ZVNlcnZpY2UuZG93bmxvYWQoKSk7XG4gIH1cblxuICBzZXRBY3RpdmVUYWIodGFiOiBzdHJpbmcpIHtcbiAgICB0aGlzLmFjdGl2ZVRhYi5zZXQodGFiKTtcbiAgfVxuXG4gIG9uU2F2ZSgpIHt9XG5cbiAgb25DYW5jZWwoKSB7fVxuXG4gIG9uQWxpZ25TZWxlY3QodmFsdWU6IHN0cmluZykge1xuICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50LnVwZGF0ZShlbCA9PiAoeyAuLi5lbCwgdGV4dEFsaWduOiB2YWx1ZSB9KSk7XG4gIH1cblxuICBvblN0eWxlU2VsZWN0KHZhbHVlOiBzdHJpbmcpIHtcbiAgICB0aGlzLnNlbGVjdGVkRWxlbWVudC51cGRhdGUoZWwgPT4gKHtcbiAgICAgIC4uLmVsLFxuICAgICAgc3R5bGVzOiBbdmFsdWVdXG4gICAgfSkpO1xuICB9XG5cbiAgaXNTdHlsZUFjdGl2ZSh2YWx1ZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWRFbGVtZW50KCk/LnN0eWxlcz8uaW5jbHVkZXModmFsdWUpIHx8IGZhbHNlO1xuICB9XG5cbiAgZ2V0VmFsdWVCeVBhdGgocGF0aDogc3RyaW5nLCBvYmo6IGFueSA9IHRoaXMuc2VsZWN0ZWRFbGVtZW50KCksIGRlZmF1bHRWYWx1ZTogYW55ID0gJycpOiBhbnkge1xuICAgIGlmICghb2JqIHx8ICFwYXRoKSByZXR1cm4gZGVmYXVsdFZhbHVlO1xuICAgIHJldHVybiBwYXRoLnNwbGl0KCcuJykucmVkdWNlKChvLCBrKSA9PiBvPy5ba10gPz8gZGVmYXVsdFZhbHVlLCBvYmopO1xuICB9XG4gIGlzQW5vdGhlcklkU2VsZWN0ZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLmdldEVsZW1lbnRzKClcbiAgICAgIC5zb21lKChlbCwgaSkgPT4gaSAhPT0gdGhpcy5zZWxlY3RlZEVsZW1lbnRJbmRleCgpICYmIGVsLnByaW1hcnlLZXkpO1xuICB9XG5cbiAgLy8gQWxzbyB1cGRhdGUgeW91ciBvblRvZ2dsZUNoYW5nZSBtZXRob2QgdG8gY2xlYXIgY2FjaGVcbm9uVG9nZ2xlQ2hhbmdlKHBhdGg6IHN0cmluZywgZXZlbnQ6IGFueSkge1xuICAvLyBDbGVhciBjYWNoZSB3aGVuIGVsZW1lbnQgY2hhbmdlc1xuICB0aGlzLmNsZWFyUHJvcGVydGllc0NhY2hlKCk7XG4gIGNvbnN0IGNoZWNrZWQgPSBldmVudC50YXJnZXQgPyAoZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQpLmNoZWNrZWQgOiBldmVudDtcbiAgdGhpcy5zZXRWYWx1ZUJ5UGF0aChwYXRoLCBjaGVja2VkKTtcbiAgXG4gIGlmICh0aGlzLnNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnKSB7XG4gICAgbGV0IGZpZWxkc01ldGEgPSB0aGlzLmdldERhdGFCeVBhdGgoJ2ZpZWxkc01ldGEnKTtcbiAgICBpZiAodHlwZW9mIGZpZWxkc01ldGEgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0cnkge1xuICAgICAgICBmaWVsZHNNZXRhID0gSlNPTi5wYXJzZShmaWVsZHNNZXRhIHx8ICdbXScpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyBjb25zb2xlLmVycm9yKCdFcnJvciBwYXJzaW5nIGZpZWxkc01ldGE6JywgZSk7XG4gICAgICAgIGZpZWxkc01ldGEgPSBbXTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5zZWxlY3RlZEVsZW1lbnQudXBkYXRlKGVsID0+ICh7XG4gICAgICAuLi5lbCxcbiAgICAgIGZpZWxkc01ldGE6IGZpZWxkc01ldGFcbiAgICB9KSk7XG4gICAgdGhpcy51cGRhdGVFbGVtZW50KHRoaXMuc2VsZWN0ZWRFbGVtZW50KCkpO1xuICB9XG59XG5cbiAgLy8gVXBkYXRlIHlvdXIgc2V0VmFsdWVCeVBhdGggbWV0aG9kIHRvIGNsZWFyIGNhY2hlXG5zZXRWYWx1ZUJ5UGF0aChwYXRoOiBzdHJpbmcsIHZhbHVlOiBhbnkpIHtcbiAgLy8gQ2xlYXIgY2FjaGUgd2hlbiBlbGVtZW50IGNoYW5nZXNcbiAgdGhpcy5jbGVhclByb3BlcnRpZXNDYWNoZSgpO1xuICBcbiAgaWYgKHRoaXMuc2VsZWN0ZWRFbGVtZW50SW5kZXgoKSA+PSAwKSB7XG4gICAgaWYgKHBhdGggPT09ICdxdWVzdGlvblRleHQnIHx8IHBhdGggPT09ICdxdWVzdGlvbicpIHtcbiAgICAgIGlmICghdGhpcy52YWxpZGF0ZUlucHV0KHZhbHVlLCBwYXRoKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChwYXRoID09PSAncXVlc3Rpb25OdW1iZXInKSB7XG4gICAgICBjb25zdCBuZXdPcmRlciA9IHBhcnNlSW50KHZhbHVlLCAxMCk7XG4gICAgICBpZiAoaXNOYU4obmV3T3JkZXIpKSByZXR1cm47XG4gICAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS51cGRhdGVFbGVtZW50KHRoaXMuc2VsZWN0ZWRFbGVtZW50SW5kZXgoKSwgeyBxdWVzdGlvbk51bWJlcjogbmV3T3JkZXIgfSk7XG4gICAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5zb3J0RWxlbWVudHNCeU9yZGVyKCk7XG4gICAgfVxuICAgIGlmIChwYXRoID09PSAnZm9udCcgfHwgcGF0aCA9PT0gJ2ZvbnRXZWlnaHQnKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkRWxlbWVudC51cGRhdGUoZWwgPT4gKHsgLi4uZWwsIFtwYXRoXTogdmFsdWUgfSkpO1xuICAgIH1cbiAgfVxuICBcbiAgY29uc3QgZWxlbWVudCA9IHRoaXMuc2VsZWN0ZWRFbGVtZW50KCk7XG4gIGlmIChlbGVtZW50KSB7XG4gICAgbGV0IHN1YlRleHQgPSBlbGVtZW50LnN1YlRleHQ7XG4gICAgaWYgKHR5cGVvZiBzdWJUZXh0ID09PSAnc3RyaW5nJyAmJiBzdWJUZXh0LnRyaW0oKSAhPT0gJycpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHN1YlRleHQgPSBKU09OLnBhcnNlKHN1YlRleHQpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyBjb25zb2xlLmVycm9yKCdFcnJvciBwYXJzaW5nIHN1YlRleHQ6JywgZSk7XG4gICAgICAgIHN1YlRleHQgPSB7fTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzdWJUZXh0ICE9PSAnb2JqZWN0JyB8fCBzdWJUZXh0ID09PSBudWxsKSB7XG4gICAgICBzdWJUZXh0ID0ge307XG4gICAgfVxuICAgIGlmIChzdWJUZXh0ICYmIEFycmF5LmlzQXJyYXkoc3ViVGV4dC5maWVsZCkpIHtcbiAgICAgIHN1YlRleHQgPSB7IC4uLnN1YlRleHQsIGZpZWxkOiBzdWJUZXh0LmZpZWxkLmpvaW4oJywgJykgfTtcbiAgICB9XG4gICAgdGhpcy5zZWxlY3RlZEVsZW1lbnQudXBkYXRlKGVsID0+ICh7IC4uLmVsLCBzdWJUZXh0IH0pKTtcbiAgfVxuICBcbiAgY29uc3Qga2V5cyA9IHBhdGguc3BsaXQoJy4nKTtcbiAgdGhpcy5zZWxlY3RlZEVsZW1lbnQudXBkYXRlKGVsID0+IHtcbiAgICBsZXQgb2JqID0geyAuLi5lbCB9O1xuICAgIGxldCBjdXJyZW50ID0gb2JqO1xuICAgIGtleXMuZm9yRWFjaCgoa2V5LCBpbmRleCkgPT4ge1xuICAgICAgaWYgKGluZGV4ID09PSBrZXlzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgY3VycmVudFtrZXldID0gdmFsdWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoIWN1cnJlbnRba2V5XSkge1xuICAgICAgICAgIGN1cnJlbnRba2V5XSA9IGlzTmFOKE51bWJlcihrZXlzW2luZGV4ICsgMV0pKSA/IHt9IDogW107XG4gICAgICAgIH1cbiAgICAgICAgY3VycmVudCA9IGN1cnJlbnRba2V5XTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gb2JqO1xuICB9KTtcbiAgXG4gIHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLmVsZW1lbnRVcGRhdGUodGhpcy5zZWxlY3RlZEVsZW1lbnRJbmRleCgpLCB0aGlzLnNlbGVjdGVkRWxlbWVudCgpKTtcbn1cblxuICBnZXRTdHlsZUtleXMoKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IHN0eWxlID0gdGhpcy5zZWxlY3RlZEVsZW1lbnQoKT8uc3R5bGU7XG4gICAgcmV0dXJuIHN0eWxlICYmIHR5cGVvZiBzdHlsZSA9PT0gJ29iamVjdCcgPyBPYmplY3Qua2V5cyhzdHlsZSkgOiBbXTtcbiAgfVxuXG4gIHVwZGF0ZUVsZW1lbnQoZWxlbWVudDogYW55KSB7XG4gICAgdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UuZWxlbWVudFVwZGF0ZSh0aGlzLnNlbGVjdGVkRWxlbWVudEluZGV4KCksIGVsZW1lbnQpO1xuICAgIGlmIChlbGVtZW50Py50eXBlID09PSAnVGFibGUnICYmIHRoaXMuc2VsZWN0Q29sdW1uKCkpIHtcbiAgICAgIHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLnNldFNlbGVjdGVkVGFibGVFbGVtZW50KHRoaXMuc2VsZWN0ZWRFbGVtZW50SW5kZXgoKSwgeyB1bmlxdWVJZGVudGlmaWVyOiB0aGlzLnNlbGVjdENvbHVtbigpIHx8IG51bGwgfSk7XG4gICAgICB0aGlzLnNlbGVjdGVkRWxlbWVudC5zZXQoeyAuLi5lbGVtZW50IH0pOyAvLyBFbnN1cmUgcmVhY3RpdmUgdXBkYXRlXG4gICAgfVxuICB9XG5cbiAgZ2V0VmFsdWVCeUFycmF5UGF0aCh0YXJnZXRBcnJheVBhdGg6IGFueSwgdGFyZ2V0QXJyYXlLZXk6IHN0cmluZywgc2VsZWN0Q29sdW1uOiBzdHJpbmcsIGtleVBhdGg6IHN0cmluZywgaXNUYWJsZUNvbHVtbjogYm9vbGVhbiA9IGZhbHNlKTogYW55IHtcbiAgICBpZiAoaXNUYWJsZUNvbHVtbikge1xuICAgICAgdGFyZ2V0QXJyYXlQYXRoID0gJ2ZpZWxkc01ldGEnO1xuICAgICAgdGFyZ2V0QXJyYXlLZXkgPSAndW5pcXVlSWRlbnRpZmllcic7XG4gICAgICBrZXlQYXRoID0gJ3F1ZXN0aW9uLicgKyBrZXlQYXRoO1xuICAgIH1cbiAgICBsZXQgdGFyZ2V0QXJyYXkgPSB0aGlzLmdldERhdGFCeVBhdGgodGFyZ2V0QXJyYXlQYXRoKTtcbiAgICBpZiAodHlwZW9mIHRhcmdldEFycmF5ID09PSAnc3RyaW5nJykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgdGFyZ2V0QXJyYXkgPSBKU09OLnBhcnNlKHRhcmdldEFycmF5IHx8ICdbXScpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyBjb25zb2xlLmVycm9yKCdFcnJvciBwYXJzaW5nIHRhcmdldEFycmF5OicsIGUpO1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICghQXJyYXkuaXNBcnJheSh0YXJnZXRBcnJheSkpIHJldHVybiAnJztcbiAgICBjb25zdCBmb3VuZEl0ZW0gPSB0YXJnZXRBcnJheS5maW5kKGl0ZW0gPT4gaXRlbVt0YXJnZXRBcnJheUtleV0gPT09IHNlbGVjdENvbHVtbik7XG4gICAgcmV0dXJuIGZvdW5kSXRlbSA/IGtleVBhdGguc3BsaXQoJy4nKS5yZWR1Y2UoKG9iaiwga2V5KSA9PiBvYmo/LltrZXldLCBmb3VuZEl0ZW0pIDogJyc7XG4gIH1cbiAgXG4gIHVwZGF0ZVZhbHVlQnlBcnJheVBhdGgodGFyZ2V0QXJyYXlQYXRoOiBhbnksIHRhcmdldEFycmF5S2V5OiBzdHJpbmcsIHNlbGVjdENvbHVtbjogc3RyaW5nLCBrZXlQYXRoOiBzdHJpbmcsIGV2ZW50OiBhbnksIGlzVGFibGVDb2x1bW46IGJvb2xlYW4gPSBmYWxzZSkge1xuICAgIC8vIENsZWFyIGNhY2hlIHdoZW4gZWxlbWVudCBjaGFuZ2VzXG4gICAgdGhpcy5jbGVhclByb3BlcnRpZXNDYWNoZSgpO1xuICAgICAgICBcbiAgICBpZiAoaXNUYWJsZUNvbHVtbikge1xuICAgICAgdGFyZ2V0QXJyYXlQYXRoID0gJ2ZpZWxkc01ldGEnO1xuICAgICAgdGFyZ2V0QXJyYXlLZXkgPSAndW5pcXVlSWRlbnRpZmllcic7XG4gICAgICBrZXlQYXRoID0gJ3F1ZXN0aW9uLicgKyBrZXlQYXRoO1xuICAgIH1cbiAgICAgICAgXG4gICAgbGV0IHRhcmdldEFycmF5ID0gdGhpcy5nZXREYXRhQnlQYXRoKHRhcmdldEFycmF5UGF0aCk7XG4gICAgaWYgKHR5cGVvZiB0YXJnZXRBcnJheSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRhcmdldEFycmF5ID0gSlNPTi5wYXJzZSh0YXJnZXRBcnJheSB8fCAnW10nKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gY29uc29sZS5lcnJvcignRXJyb3IgcGFyc2luZyB0YXJnZXRBcnJheTonLCBlKTtcbiAgICAgICAgdGFyZ2V0QXJyYXkgPSBbXTtcbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHRhcmdldEFycmF5KSkge1xuICAgICAgdGFyZ2V0QXJyYXkgPSBbXTtcbiAgICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50LnVwZGF0ZShlbCA9PiAoe1xuICAgICAgICAuLi5lbCxcbiAgICAgICAgW3RhcmdldEFycmF5UGF0aF06IHRhcmdldEFycmF5XG4gICAgICB9KSk7XG4gICAgfVxuICAgIFxuICAgIGxldCBmb3VuZEl0ZW0gPSB0YXJnZXRBcnJheS5maW5kKGl0ZW0gPT4gaXRlbVt0YXJnZXRBcnJheUtleV0gPT09IHNlbGVjdENvbHVtbik7XG4gICAgaWYgKCFmb3VuZEl0ZW0pIHtcbiAgICAgIGZvdW5kSXRlbSA9IHsgW3RhcmdldEFycmF5S2V5XTogc2VsZWN0Q29sdW1uIH07XG4gICAgICB0YXJnZXRBcnJheS5wdXNoKGZvdW5kSXRlbSk7XG4gICAgfVxuICAgIFxuICAgIGNvbnN0IGtleXMgPSBrZXlQYXRoLnNwbGl0KCcuJyk7XG4gICAgbGV0IG9iaiA9IGZvdW5kSXRlbTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGtleXMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICBjb25zdCBrZXkgPSBrZXlzW2ldO1xuICAgICAgaWYgKCFvYmpba2V5XSkgb2JqW2tleV0gPSB7fTtcbiAgICAgIG9iaiA9IG9ialtrZXldO1xuICAgIH1cbiAgICBcbiAgICBjb25zdCBsYXN0S2V5ID0ga2V5c1trZXlzLmxlbmd0aCAtIDFdO1xuICAgIGNvbnN0IGlucHV0RWxlbWVudDogYW55ID0gZXZlbnQudGFyZ2V0ID8gZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQgOiBldmVudDtcbiAgICBvYmpbbGFzdEtleV0gPSBpbnB1dEVsZW1lbnQ/LnR5cGUgPT09ICdjaGVja2JveCcgPyBpbnB1dEVsZW1lbnQuY2hlY2tlZCA6IGlucHV0RWxlbWVudC52YWx1ZSA/IGlucHV0RWxlbWVudC52YWx1ZSA6IGlucHV0RWxlbWVudDtcbiAgICBcbiAgICBpZiAoa2V5UGF0aCA9PT0gJ3N1bW1hcnlDb2x1bW4nKSB7XG4gICAgICBpZiAob2JqWydzdW1tYXJ5Um93J10gPT09IHRydWUpIHtcbiAgICAgICAgb2JqWydzdW1tYXJ5Um93J10gPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmIChpbnB1dEVsZW1lbnQuY2hlY2tlZCA9PT0gdHJ1ZSkge1xuICAgICAgICBvYmpbJ2ZsZFR5cGUnXSA9ICdjYWxjdWxhdGlvbic7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvYmpbJ2ZsZFR5cGUnXSA9ICdUZXh0JztcbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgaWYgKGtleVBhdGggPT09ICdzdW1tYXJ5Um93Jykge1xuICAgICAgaWYgKG9ialsnc3VtbWFyeUNvbHVtbiddID09PSB0cnVlKSB7XG4gICAgICAgIG9ialsnc3VtbWFyeUNvbHVtbiddID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoaW5wdXRFbGVtZW50LmNoZWNrZWQgPT09IHRydWUpIHtcbiAgICAgICAgb2JqWydmbGRUeXBlJ10gPSAnY2FsY3VsYXRpb24nO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb2JqWydmbGRUeXBlJ10gPSAnVGV4dCc7XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50LnVwZGF0ZShlbCA9PiAoe1xuICAgICAgLi4uZWwsXG4gICAgICBbdGFyZ2V0QXJyYXlQYXRoXTogdGFyZ2V0QXJyYXlcbiAgICB9KSk7XG4gICAgXG4gICAgdGhpcy51cGRhdGVFbGVtZW50KHRoaXMuc2VsZWN0ZWRFbGVtZW50KCkpO1xuICB9XG5cbiAgZ2V0RGF0YUJ5UGF0aChwYXRoOiBzdHJpbmcpOiBhbnkge1xuICAgIHJldHVybiBwYXRoLnNwbGl0KCcuJykucmVkdWNlKChvYmosIGtleSkgPT4gb2JqPy5ba2V5XSwgdGhpcy5zZWxlY3RlZEVsZW1lbnQoKSk7XG4gIH1cblxuICBmbGlwSG9yaXpvbnRhbCgpIHtcbiAgICB0aGlzLnRyYW5zZm9ybS51cGRhdGUodCA9PiAoeyAuLi50LCBmbGlwSDogIXQuZmxpcEggfSkpO1xuICB9XG5cbiAgZmxpcFZlcnRpY2FsKCkge1xuICAgIHRoaXMudHJhbnNmb3JtLnVwZGF0ZSh0ID0+ICh7IC4uLnQsIGZsaXBWOiAhdC5mbGlwViB9KSk7XG4gIH1cblxuICByZXNldEltYWdlKCkge1xuICAgIHRoaXMuY2FudmFzUm90YXRpb24uc2V0KDApO1xuICAgIHRoaXMuY3JvcHBlci5zZXQodW5kZWZpbmVkKTtcbiAgICB0aGlzLnRyYW5zZm9ybS5zZXQoe1xuICAgICAgdHJhbnNsYXRlVW5pdDogJ3B4JyxcbiAgICAgIHNjYWxlOiAxLFxuICAgICAgcm90YXRlOiAwLFxuICAgICAgZmxpcEg6IGZhbHNlLFxuICAgICAgZmxpcFY6IGZhbHNlLFxuICAgICAgdHJhbnNsYXRlSDogMCxcbiAgICAgIHRyYW5zbGF0ZVY6IDBcbiAgICB9KTtcbiAgfVxuXG4gIHpvb21PdXQoKSB7XG4gICAgdGhpcy50cmFuc2Zvcm0udXBkYXRlKHQgPT4gKHsgLi4udCwgc2NhbGU6IHQuc2NhbGUhIC0gMC4xIH0pKTtcbiAgfVxuXG4gIHpvb21JbigpIHtcbiAgICB0aGlzLnRyYW5zZm9ybS51cGRhdGUodCA9PiAoeyAuLi50LCBzY2FsZTogdC5zY2FsZSEgKyAwLjEgfSkpO1xuICB9XG5cbiAgcm90YXRlTGVmdCgpIHtcbiAgICB0aGlzLmxvYWRpbmcuc2V0KHRydWUpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5jYW52YXNSb3RhdGlvbi51cGRhdGUoYyA9PiBjIC0gMSk7XG4gICAgICB0aGlzLmZsaXBBZnRlclJvdGF0ZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgcm90YXRlUmlnaHQoKSB7XG4gICAgdGhpcy5sb2FkaW5nLnNldCh0cnVlKTtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuY2FudmFzUm90YXRpb24udXBkYXRlKGMgPT4gYyArIDEpO1xuICAgICAgdGhpcy5mbGlwQWZ0ZXJSb3RhdGUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIG1vdmVMZWZ0KCkge1xuICAgIHRoaXMudHJhbnNmb3JtLnVwZGF0ZSh0ID0+ICh7IC4uLnQsIHRyYW5zbGF0ZUg6IHQudHJhbnNsYXRlSCEgLSAxIH0pKTtcbiAgfVxuXG4gIG1vdmVSaWdodCgpIHtcbiAgICB0aGlzLnRyYW5zZm9ybS51cGRhdGUodCA9PiAoeyAuLi50LCB0cmFuc2xhdGVIOiB0LnRyYW5zbGF0ZUghICsgMSB9KSk7XG4gIH1cblxuICBtb3ZlRG93bigpIHtcbiAgICB0aGlzLnRyYW5zZm9ybS51cGRhdGUodCA9PiAoeyAuLi50LCB0cmFuc2xhdGVWOiB0LnRyYW5zbGF0ZVYhICsgMSB9KSk7XG4gIH1cblxuICBtb3ZlVXAoKSB7XG4gICAgdGhpcy50cmFuc2Zvcm0udXBkYXRlKHQgPT4gKHsgLi4udCwgdHJhbnNsYXRlVjogdC50cmFuc2xhdGVWISAtIDEgfSkpO1xuICB9XG5cbiAgcHJpdmF0ZSBmbGlwQWZ0ZXJSb3RhdGUoKSB7XG4gICAgdGhpcy50cmFuc2Zvcm0udXBkYXRlKHQgPT4gKHtcbiAgICAgIC4uLnQsXG4gICAgICBmbGlwSDogdC5mbGlwVixcbiAgICAgIGZsaXBWOiB0LmZsaXBILFxuICAgICAgdHJhbnNsYXRlSDogMCxcbiAgICAgIHRyYW5zbGF0ZVY6IDBcbiAgICB9KSk7XG4gIH1cblxuICBhc3luYyBpbWFnZUNyb3BwZWQoZXZlbnQ6IGFueSkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBiYXNlNjQgPSBhd2FpdCB0aGlzLmNvbnZlcnRCbG9iVG9CYXNlNjQoZXZlbnQub2JqZWN0VXJsKTtcbiAgICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50LnVwZGF0ZShlbCA9PiAoeyAuLi5lbCwgaW1hZ2VEYXRhOiBiYXNlNjQgfSkpO1xuICAgICAgYXdhaXQgdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UuZWxlbWVudFVwZGF0ZSh0aGlzLnNlbGVjdGVkRWxlbWVudEluZGV4KCksIHRoaXMuc2VsZWN0ZWRFbGVtZW50KCkpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBjb25zb2xlLmVycm9yKFwiRXJyb3IgaW4gaW1hZ2VDcm9wcGVkOlwiLCBlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgY3JvcHBlclJlYWR5KHNvdXJjZUltYWdlRGltZW5zaW9uczogRGltZW5zaW9ucykge1xuICAgIHRoaXMubG9hZGluZy5zZXQoZmFsc2UpO1xuICB9XG5cbiAgY29udmVydEJsb2JUb0Jhc2U2NChvYmplY3RVcmw6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgcmV0dXJuIGZldGNoKG9iamVjdFVybClcbiAgICAgIC50aGVuKHJlc3BvbnNlID0+IHJlc3BvbnNlLmJsb2IoKSlcbiAgICAgIC50aGVuKGJsb2IgPT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgICAgICAgcmVhZGVyLnJlYWRBc0RhdGFVUkwoYmxvYik7XG4gICAgICAgICAgcmVhZGVyLm9ubG9hZGVuZCA9ICgpID0+IHJlc29sdmUocmVhZGVyLnJlc3VsdCBhcyBzdHJpbmcpO1xuICAgICAgICAgIHJlYWRlci5vbmVycm9yID0gZXJyb3IgPT4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgfVxuXG4gIGNoaWxkRXZlbnRDYXB0dXJlKGV2ZW50OiBhbnkpIHtcbiAgICB0aGlzLnNlbGVjdGVkRWxlbWVudC51cGRhdGUoZWwgPT4gKHtcbiAgICAgIC4uLmVsLFxuICAgICAgcWJSZWZlcmVuY2U6IGV2ZW50LnZhbHVlT2JqPy5uYW1lLFxuICAgICAgcWJSZWZlcmVuY2VRdWVzdGlvbnM6IGV2ZW50LnZhbHVlT2JqPy5qc29uQm9keVxuICAgIH0pKTtcbiAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5lbGVtZW50VXBkYXRlKHRoaXMuc2VsZWN0ZWRFbGVtZW50SW5kZXgoKSwgdGhpcy5zZWxlY3RlZEVsZW1lbnQoKSk7XG4gIH1cblxuICBsaW5rVG9nZ2xlRHJvcGRvd24oZXZlbnQ6IEV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5pc0xpbmtEcm9wZG93bk9wZW4udXBkYXRlKG9wZW4gPT4gIW9wZW4pO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6Y2xpY2snLCBbJyRldmVudCddKVxuICBvbkNsaWNrT3V0c2lkZShldmVudDogRXZlbnQpIHtcbiAgICBpZiAodGhpcy5kcm9wZG93biAmJiAhdGhpcy5kcm9wZG93bi5uYXRpdmVFbGVtZW50LmNvbnRhaW5zKGV2ZW50LnRhcmdldCkpIHtcbiAgICAgIHRoaXMuaXNMaW5rRHJvcGRvd25PcGVuLnNldChmYWxzZSk7XG4gICAgfVxuICB9XG5cbiAgb25EcmFnU3RhcnQoZXZlbnQ6IERyYWdFdmVudCwgaWQ6IHN0cmluZykge1xuICAgIHRoaXMuZHJhZ2dlZElkID0gaWQ7XG4gICAgZXZlbnQuZGF0YVRyYW5zZmVyIS5lZmZlY3RBbGxvd2VkID0gXCJtb3ZlXCI7XG4gIH1cblxuICAvLyBBUC0yOE1BUjI1IFByZXZlbnQgZGVmYXVsdCBiZWhhdmlvciB0byBhbGxvdyBkcm9wXG4gIG9uRHJhZ092ZXIoZXZlbnQ6IERyYWdFdmVudCkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gIH1cblxuICAvLyBBUC0yOE1BUjI1IFN3YXAgdGhlIGRyYWdnZWQgaXRlbSB3aXRoIHRoZSBkcm9wcGVkIHBvc2l0aW9uXG4gIG9uRHJvcChldmVudDogRHJhZ0V2ZW50LCBrZXk6IHN0cmluZykge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgY29uc3QgdGFyZ2V0SWQgPSAoZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50KS5jbG9zZXN0KFwiLm9wdGlvbi1pdGVtc1wiKT8uZ2V0QXR0cmlidXRlKFwiZGF0YS1pZFwiKTtcbiAgICBpZiAodGhpcy5kcmFnZ2VkSWQgJiYgdGFyZ2V0SWQgJiYgdGhpcy5kcmFnZ2VkSWQgIT09IHRhcmdldElkKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkRWxlbWVudC51cGRhdGUoZWwgPT4ge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gWy4uLmVsW2tleV1dO1xuICAgICAgICBjb25zdCBkcmFnZ2VkSW5kZXggPSBvcHRpb25zLmZpbmRJbmRleChvcHRpb24gPT4gb3B0aW9uLmlkID09PSB0aGlzLmRyYWdnZWRJZCk7XG4gICAgICAgIGNvbnN0IHRhcmdldEluZGV4ID0gb3B0aW9ucy5maW5kSW5kZXgob3B0aW9uID0+IG9wdGlvbi5pZCA9PT0gdGFyZ2V0SWQpO1xuICAgICAgICBpZiAoZHJhZ2dlZEluZGV4ICE9PSAtMSAmJiB0YXJnZXRJbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICBbb3B0aW9uc1tkcmFnZ2VkSW5kZXhdLCBvcHRpb25zW3RhcmdldEluZGV4XV0gPSBbb3B0aW9uc1t0YXJnZXRJbmRleF0sIG9wdGlvbnNbZHJhZ2dlZEluZGV4XV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgLi4uZWwsIFtrZXldOiBvcHRpb25zIH07XG4gICAgICB9KTtcbiAgICB9XG4gICAgdGhpcy5kcmFnZ2VkSWQgPSBudWxsO1xuICB9XG5cbiAgZHVwbGljYXRlRmllbGQoZWxlbWVudDogYW55KSB7XG4gICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5nZXRFbGVtZW50cygpO1xuICAgIGNvbnN0IGNvcHkgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGVsZW1lbnQpKTtcbiAgICAvL0FQLTE4QVBSMjUgR2VuZXJhdGUgYSBuZXcgSUQgdXNpbmcgdGhlIHNlcnZpY2UncyBtZXRob2RcbiAgICBjb3B5LmlkID0gdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UuYWRkRWxlbWVudFdpdGhJZCgpO1xuICAgIC8vY29weS51dWlkID0gY29weS5pZDsgXG4gICAgLy8gQVAtMThBUFIyNSBTZXQgdGhlIHF1ZXN0aW9uTnVtYmVyIHRvIHRoZSBuZXh0IGF2YWlsYWJsZSBudW1iZXJcbiAgICBjb3B5LnF1ZXN0aW9uTnVtYmVyID0gZWxlbWVudHMubGVuZ3RoICsgMTtcbiAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5hZGRFbGVtZW50KGNvcHkpO1xuICB9XG5cbiAgcHJpdmF0ZSBkcmFnZ2VkSWQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICB1cGRhdGVCb29rU3VidGV4dChrZXk6ICdlbmRwb2ludCcgfCAndmFyaWFibGUnIHwgJ2RlZmF1bHRGaWVsZCcsIHZhbHVlOiBzdHJpbmcpIHtcbiAgICB0aGlzLmJvb2tTdWJ0ZXh0LnVwZGF0ZSgocykgPT4gKHtcbiAgICAgIC4uLnMsXG4gICAgICBba2V5XTogdmFsdWUsXG4gICAgfSkpO1xuICB9ICBcbiAgdHJhY2tCeVByb3AoaW5kZXg6IG51bWJlciwgaXRlbTogYW55KTogYW55IHtcbiAgICByZXR1cm4gaXRlbT8ua2V5ID8/IGluZGV4O1xuICB9XG4gIC8vIEFkZCB0aGVzZSBnZXR0ZXIgbWV0aG9kc1xuICBnZXQgY3VycmVudEVsZW1lbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWRFbGVtZW50KCk7XG4gIH1cblxuICBnZXQgY3VycmVudEVsZW1lbnRUeXBlKCkge1xuICAgIHJldHVybiB0aGlzLmN1cnJlbnRFbGVtZW50Py50eXBlO1xuICB9XG5cbiAgZ2V0IGlzVGFibGVFbGVtZW50KCkge1xuICAgIHJldHVybiB0aGlzLmN1cnJlbnRFbGVtZW50VHlwZSA9PT0gJ1RhYmxlJztcbiAgfVxuXG4gIGdldCBzZWxlY3RlZENvbHVtbklkKCkge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdENvbHVtbigpO1xuICB9XG4gIGdldE9wdGltaXplZFN1YlByb3BWYWx1ZShzdWJQcm9wOiBhbnkpOiBzdHJpbmcge1xuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmN1cnJlbnRFbGVtZW50O1xuICAgIGlmICh0aGlzLmlzVGFibGVFbGVtZW50ICYmIChzdWJQcm9wLnRhcmdldEFycmF5IHx8IHN1YlByb3AuaXNUYWJsZUNvbHVtbikpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldFZhbHVlQnlBcnJheVBhdGgoXG4gICAgICAgIHN1YlByb3AudGFyZ2V0QXJyYXksIFxuICAgICAgICBzdWJQcm9wLnRhcmdldEFycmF5S2V5LCBcbiAgICAgICAgdGhpcy5zZWxlY3RlZENvbHVtbklkLCBcbiAgICAgICAgc3ViUHJvcC5rZXksIFxuICAgICAgICBzdWJQcm9wLmlzVGFibGVDb2x1bW5cbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmdldFZhbHVlQnlQYXRoKHN1YlByb3Aua2V5LCBlbGVtZW50KTtcbiAgfVxufSIsIjwhLS0gQVAgMjJKQU4yNSAtIEZpZWxkIGFuZCBFbGVtZW50IFByb3BlcnRpZXMgLS0+XG5cbjxkaXYgY2xhc3M9XCJjb250YWluZXJcIj5cbiAgPGRpdiBjbGFzcz1cInRhYnNcIj5cbiAgICA8ZGl2IGNsYXNzPVwidGFiXCIgW25nQ2xhc3NdPVwieydhY3RpdmUnOiBhY3RpdmVUYWIoKSA9PT0gJ2F0dHJpYnV0ZXMnfVwiIChjbGljayk9XCJzZXRBY3RpdmVUYWIoJ2F0dHJpYnV0ZXMnKVwiPkF0dHJpYnV0ZXM8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwidGFiXCIgW25nQ2xhc3NdPVwieydhY3RpdmUnOiBhY3RpdmVUYWIoKSA9PT0gJ3Byb3BlcnR5J31cIiAoY2xpY2spPVwic2V0QWN0aXZlVGFiKCdwcm9wZXJ0eScpXCI+UHJvcGVydHk8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwidGFiXCIgW25nQ2xhc3NdPVwieydhY3RpdmUnOiBhY3RpdmVUYWIoKSA9PT0gJ2FwcGVhcmFuY2UnfVwiIChjbGljayk9XCJzZXRBY3RpdmVUYWIoJ2FwcGVhcmFuY2UnKVwiPkFwcGVhcmFuY2U8L2Rpdj5cbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cInRhYi1jb250ZW50XCIgKm5nSWY9XCJhY3RpdmVUYWIoKSA9PT0gJ2F0dHJpYnV0ZXMnXCI+XG4gICAgQGRlZmVyICh3aGVuIGdldFByb3BlcnRpZXMoKSkge1xuICAgICAgPGRpdj5cbiAgICAgICAgQGRlZmVyICh3aGVuIHNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnSW1hZ2UnKSB7XG4gICAgICAgICAgPGltYWdlLWNyb3BwZXJcbiAgICAgICAgICAgICpuZ0lmPVwic2VsZWN0ZWRFbGVtZW50KCkuaW1hZ2VEYXRhXCJcbiAgICAgICAgICAgIFtpbWFnZUJhc2U2NF09XCJzZWxlY3RlZEVsZW1lbnQoKS5vcmdJbWFnZURhdGFcIlxuICAgICAgICAgICAgW2Rpc2FibGVkXT1cImZhbHNlXCJcbiAgICAgICAgICAgIFthbGlnbkltYWdlXT1cImFsaWduSW1hZ2VcIlxuICAgICAgICAgICAgW3JvdW5kQ3JvcHBlcl09XCJyb3VuZENyb3BwZXJcIlxuICAgICAgICAgICAgW2JhY2tncm91bmRDb2xvcl09XCInd2hpdGUnXCJcbiAgICAgICAgICAgIGltYWdlQWx0VGV4dD1cIkFsdGVybmF0aXZlIGltYWdlIHRleHRcIlxuICAgICAgICAgICAgW2FsbG93TW92ZUltYWdlXT1cImZhbHNlXCJcbiAgICAgICAgICAgIFtoaWRlUmVzaXplU3F1YXJlc109XCJmYWxzZVwiXG4gICAgICAgICAgICBbY2FudmFzUm90YXRpb25dPVwiY2FudmFzUm90YXRpb24oKVwiXG4gICAgICAgICAgICBbYXNwZWN0UmF0aW9dPVwiYXNwZWN0UmF0aW9cIlxuICAgICAgICAgICAgW2NvbnRhaW5XaXRoaW5Bc3BlY3RSYXRpb109XCJmYWxzZVwiXG4gICAgICAgICAgICBbbWFpbnRhaW5Bc3BlY3RSYXRpb109XCJmYWxzZVwiXG4gICAgICAgICAgICBbY3JvcHBlclN0YXRpY1dpZHRoXT1cImNyb3BwZXJTdGF0aWNXaWR0aFwiXG4gICAgICAgICAgICBbY3JvcHBlclN0YXRpY0hlaWdodF09XCJjcm9wcGVyU3RhdGljSGVpZ2h0XCJcbiAgICAgICAgICAgIFtjcm9wcGVyTWluV2lkdGhdPVwiY3JvcHBlck1pbldpZHRoXCJcbiAgICAgICAgICAgIFtjcm9wcGVyTWluSGVpZ2h0XT1cImNyb3BwZXJNaW5IZWlnaHRcIlxuICAgICAgICAgICAgW2Nyb3BwZXJNYXhXaWR0aF09XCJjcm9wcGVyTWF4V2lkdGhcIlxuICAgICAgICAgICAgW2Nyb3BwZXJNYXhIZWlnaHRdPVwiY3JvcHBlck1heEhlaWdodFwiXG4gICAgICAgICAgICBbcmVzZXRDcm9wT25Bc3BlY3RSYXRpb0NoYW5nZV09XCJ0cnVlXCJcbiAgICAgICAgICAgIFsoY3JvcHBlcildPVwiY3JvcHBlclwiXG4gICAgICAgICAgICBbKHRyYW5zZm9ybSldPVwidHJhbnNmb3JtXCJcbiAgICAgICAgICAgIFtvbmx5U2NhbGVEb3duXT1cInRydWVcIlxuICAgICAgICAgICAgb3V0cHV0PVwiYmxvYlwiXG4gICAgICAgICAgICBmb3JtYXQ9XCJwbmdcIlxuICAgICAgICAgICAgKGltYWdlQ3JvcHBlZCk9XCJpbWFnZUNyb3BwZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICAoY3JvcHBlclJlYWR5KT1cImNyb3BwZXJSZWFkeSgkZXZlbnQpXCJcbiAgICAgICAgICA+PC9pbWFnZS1jcm9wcGVyPlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJzZWxlY3RlZEVsZW1lbnQoKS5pbWFnZURhdGFcIiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGdhcDogMnB4O1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImN1cnNvci1wb2ludGVyIGxvZ28taWNvblwiIChjbGljayk9XCJyb3RhdGVMZWZ0KClcIiB0aXRsZT1cIlJvdGF0ZSBMZWZ0XCI+4p+yPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3Vyc29yLXBvaW50ZXIgbG9nby1pY29uXCIgKGNsaWNrKT1cInJvdGF0ZVJpZ2h0KClcIiB0aXRsZT1cIlJvdGF0ZSBSaWdodFwiPuKfszwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImN1cnNvci1wb2ludGVyIGxvZ28taWNvblwiIChjbGljayk9XCJ6b29tT3V0KClcIiB0aXRsZT1cIlpvb20gT3V0XCI+LTwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImN1cnNvci1wb2ludGVyIGxvZ28taWNvblwiIChjbGljayk9XCJ6b29tSW4oKVwiIHRpdGxlPVwiWm9vbSBJblwiPis8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjdXJzb3ItcG9pbnRlciBsb2dvLWljb25cIiAoY2xpY2spPVwibW92ZUxlZnQoKVwiIHRpdGxlPVwiTW92ZSBMZWZ0XCI+4oaQPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3Vyc29yLXBvaW50ZXIgbG9nby1pY29uXCIgKGNsaWNrKT1cIm1vdmVSaWdodCgpXCIgdGl0bGU9XCJNb3ZlIFJpZ2h0XCI+4oaSPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3Vyc29yLXBvaW50ZXIgbG9nby1pY29uXCIgKGNsaWNrKT1cIm1vdmVVcCgpXCIgdGl0bGU9XCJNb3ZlIFVwXCI+4oaRPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3Vyc29yLXBvaW50ZXIgbG9nby1pY29uXCIgKGNsaWNrKT1cIm1vdmVEb3duKClcIiB0aXRsZT1cIk1vdmUgRG93blwiPuKGkzwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImN1cnNvci1wb2ludGVyIGxvZ28taWNvblwiIChjbGljayk9XCJmbGlwSG9yaXpvbnRhbCgpXCIgW25nQ2xhc3NdPVwieydlbmFibGVkJzogdHJhbnNmb3JtKCkuZmxpcEh9XCIgdGl0bGU9XCJGbGlwIEhvcml6b250YWxseVwiPuKGlDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImN1cnNvci1wb2ludGVyIGxvZ28taWNvblwiIChjbGljayk9XCJmbGlwVmVydGljYWwoKVwiIFtuZ0NsYXNzXT1cInsnZW5hYmxlZCc6IHRyYW5zZm9ybSgpLmZsaXBWfVwiIHRpdGxlPVwiRmxpcCBWZXJ0aWNhbGx5XCI+4oaVPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3Vyc29yLXBvaW50ZXIgbG9nby1pY29uXCIgKGNsaWNrKT1cInJlc2V0SW1hZ2UoKVwiIHRpdGxlPVwiUmVzZXRcIj7DlzwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICAgIDxkaXYgKm5nSWY9XCJzZWxlY3RlZEVsZW1lbnQoKT8udHlwZSA9PT0gJ0Jvb2snXCI+XG4gICAgICAgICAgPGxhYmVsIGNsYXNzPVwidGV4dC1zbVwiPlNlYXJjaCBCb29rPC9sYWJlbD5cbiAgICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgZ2FwOiAycHg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGp1c3RpZnktY29udGVudDogY2VudGVyO1wiPlxuICAgICAgICAgICAgPG54dC1zZWFyY2gtYm94XG4gICAgICAgICAgICAgIFtxdWVzdGlvbl09XCJzZWxlY3RlZEVsZW1lbnQoKVwiXG4gICAgICAgICAgICAgIFthcGlNZXRhXT1cImJvb2tTdWJ0ZXh0KClcIlxuICAgICAgICAgICAgICBbcGxhY2VIb2xkZXJUZXh0XT1cIidTZWFyY2guLi4nXCJcbiAgICAgICAgICAgICAgKHNlYXJjaFZhbHVlQ2hhbmdlKT1cImNoaWxkRXZlbnRDYXB0dXJlKCRldmVudC52YWx1ZSlcIlxuICAgICAgICAgICAgPjwvbnh0LXNlYXJjaC1ib3g+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibGluay1pY29uXCI+XG4gICAgICAgICAgICAgIDxzdmcgKGNsaWNrKT1cImxpbmtUb2dnbGVEcm9wZG93bigkZXZlbnQpXCIgZmlsbD1cIiMwMDAwMDBcIiB2ZXJzaW9uPVwiMS4xXCIgaWQ9XCJDYXBhXzFcIlxuICAgICAgICAgICAgICB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgd2lkdGg9XCIyNHB4XCIgaGVpZ2h0PVwiMjRweFwiXG4gICAgICAgICAgICAgIHZpZXdCb3g9XCIwIDAgNDUwIDQ1MFwiIHhtbDpzcGFjZT1cInByZXNlcnZlXCI+XG4gICAgICAgICAgICAgIDxnPlxuICAgICAgICAgICAgICAgIDxnPlxuICAgICAgICAgICAgICAgICAgPGc+XG4gICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMzE4LjE1LDIzMC4xOTVsNzcuOTM0LTc3LjkzN2MzMS44OTQtMzEuODkyLDMxLjg5NC04My43ODItMC4wMDQtMTE1LjY3NGwtMTIuNjYtMTIuNjZcbiAgICAgICAgICBjLTMxLjg5My0zMS44OTYtODMuNzgtMzEuODk2LTExNS42NzQtMC4wMDRsLTc3LjkzNyw3Ny45MzRjLTE3LjU4OCwxNy41ODgtMjUuNDU3LDQxLjI2NC0yMy42NDYsNjQuMzExXG4gICAgICAgICAgYy0yMy4wNDUtMS44MTMtNDYuNzIyLDYuMDU2LTY0LjMwOCwyMy42NDdMMjMuOTIsMjY3Ljc0OGMtMzEuODk0LDMxLjg4OS0zMS44OTQsODMuNzc5LDAsMTE1LjY3NGwxMi42NjQsMTIuNjYyXG4gICAgICAgICAgYzMxLjg5MywzMS44OTMsODMuNzgzLDMxLjg5MywxMTUuNjc0LDBsNzcuOTM1LTc3LjkzNmMxNy41OTItMTcuNTksMjUuNDU5LTQxLjI2NiwyMy42NDctNjQuMzA5XG4gICAgICAgICAgQzI3Ni44ODQsMjU1LjY1NCwzMDAuNTYsMjQ3Ljc4MywzMTguMTUsMjMwLjE5NXogTTIwMi42NTMsMjkwLjYwNWwtNzcuOTM2LDc3LjkzOGMtMTYuNzA1LDE2LjcwMy00My44ODksMTYuNzAzLTYwLjU5LDBcbiAgICAgICAgICBsLTEyLjY2Ni0xMi42NjZjLTE2LjcwNS0xNi43MDEtMTYuNzAzLTQzLjg4NSwwLTYwLjU5NGw3Ny45MzYtNzcuOTMyYzE0LjE0LTE0LjE0MSwzNS43NzktMTYuMzA2LDUyLjIyNi02LjUxNmwtMzIuMzAyLDMyLjMwN1xuICAgICAgICAgIGMtNy42MDYsNy42MDQtNy42MDYsMTkuOTM4LDAsMjcuNTQxYzcuNjA1LDcuNjA3LDE5LjkzNyw3LjYwNywyNy41NDEsMGwzMi4zMDYtMzIuMzAzXG4gICAgICAgICAgQzIxOC45NTksMjU0LjgyOCwyMTYuNzk1LDI3Ni40NjksMjAyLjY1MywyOTAuNjA1eiBNMjM4LjM4MiwyMDkuMTY5bDMyLjI5OS0zMi4zMDZjNy42MDgtNy42MDIsNy42MDgtMTkuOTM1LDAtMjcuNTM4XG4gICAgICAgICAgYy03LjYwNC03LjYxLTE5LjkzNi03LjYxLTI3LjU0MS0wLjAwNGwtMzIuMzAzLDMyLjMwM2MtOS43OTEtMTYuNDQ2LTcuNjI3LTM4LjA4Nyw2LjUxNC01Mi4yMjZsNzcuOTM1LTc3LjkzNVxuICAgICAgICAgIGMxNi43MDctMTYuNzA3LDQzLjg5LTE2LjcwNyw2MC41OTQsMGwxMi42NjQsMTIuNjY0YzE2LjcwNSwxNi43MDUsMTYuNzA1LDQzLjg4NiwwLDYwLjU5MWwtNzcuOTM2LDc3LjkzN1xuICAgICAgICAgIEMyNzYuNDY4LDIxNi43OTcsMjU0LjgyOCwyMTguOTU5LDIzOC4zODIsMjA5LjE2OXpcIiAvPlxuICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTM0My40NjYsMjYxLjQ2NWMtNDUuMjg3LDAtODIsMzYuNzEzLTgyLDgyczM2LjcxMyw4Miw4Miw4MmM0NS4yODYsMCw4Mi0zNi43MTMsODItODJTMzg4Ljc1MywyNjEuNDY1LDM0My40NjYsMjYxLjQ2NXpcbiAgICAgICAgICAgTTM3Mi41MDUsMzMzLjU2NGwtNTYuMDQ2LDU2LjEwNGMtMC4yMzksMC4yMzgtMC41MzYsMC40MS0wLjg2MiwwLjQ5NmwtMjIuMzE1LDUuODVjLTAuNjQ5LDAuMTY4LTEuMzQ3LTAuMDItMS44MjItMC40OTRcbiAgICAgICAgICBjLTAuNDc3LTAuNDc5LTAuNjY2LTEuMTcyLTAuNDk2LTEuODI0bDUuODI2LTIyLjMxOGMwLjA4NC0wLjMyNiwwLjI1Ni0wLjYyNywwLjQ5NC0wLjg2M2w1Ni4wNDctNTYuMTA0XG4gICAgICAgICAgYzAuNzQyLTAuNzQyLDEuOTQ1LTAuNzQ0LDIuNjg4LTAuMDAybDQuNTQ4LDQuNTQxYzAuNzM5LDAuNzQsMC43NDEsMS45NDMsMCwyLjY4OGwtMzcuNDMzLDM3LjQ3MWw0LjcwOSw0LjcwM2wzNy40MzUtMzcuNDcxXG4gICAgICAgICAgYzAuNzM5LTAuNzQyLDEuOTQtMC43NDIsMi42ODItMC4wMDJsNC41NSw0LjU0MUMzNzMuMjUsMzMxLjYxNywzNzMuMjUsMzMyLjgyMiwzNzIuNTA1LDMzMy41NjR6IE0zOTUuNDcyLDMxMC41NzRsLTE3LDE3LjAxOFxuICAgICAgICAgIGMtMC43MzksMC43NDQtMS45NDIsMC43NDQtMi42ODUsMC4wMDJsLTE2LjQ4OS0xNi40NzVjLTAuNzQ0LTAuNzQtMC43NDQtMS45NDMtMC4wMDItMi42ODhsMTctMTcuMDJcbiAgICAgICAgICBjMC43NDEtMC43NCwxLjk0NC0wLjc0LDIuNjg4LTAuMDAybDE2LjQ4NywxNi40NzdDMzk2LjIxNiwzMDguNjI5LDM5Ni4yMTYsMzA5LjgzMiwzOTUuNDcyLDMxMC41NzR6XCIgLz5cbiAgICAgICAgICAgICAgICAgIDwvZz5cbiAgICAgICAgICAgICAgICA8L2c+XG4gICAgICAgICAgICAgIDwvZz5cbiAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibGluay1kcm9wZG93bi1tZW51XCIgKm5nSWY9XCJpc0xpbmtEcm9wZG93bk9wZW4oKVwiICNkcm9wZG93bj5cbiAgICAgICAgICAgICAgICA8bGFiZWw+RW5kcG9pbnQ6PC9sYWJlbD5cbiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBbbmdNb2RlbF09XCJib29rU3VidGV4dCgpLmVuZHBvaW50XCIgKG5nTW9kZWxDaGFuZ2UpPVwidXBkYXRlQm9va1N1YnRleHQoJ2VuZHBvaW50JywgJGV2ZW50KVwiIC8+XG4gICAgICAgICAgICAgICAgPGxhYmVsPlZhcmlhYmxlOjwvbGFiZWw+XG4gICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgW25nTW9kZWxdPVwiYm9va1N1YnRleHQoKS52YXJpYWJsZVwiIChuZ01vZGVsQ2hhbmdlKT1cInVwZGF0ZUJvb2tTdWJ0ZXh0KCd2YXJpYWJsZScsICRldmVudClcIiAvPlxuICAgICAgICAgICAgICAgIDxsYWJlbD5GaWVsZDo8L2xhYmVsPlxuICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIFtuZ01vZGVsXT1cImZpZWxkQXNTdHJpbmcoKVwiIChuZ01vZGVsQ2hhbmdlKT1cInVwZGF0ZUZpZWxkKCRldmVudClcIiAvPlxuICAgICAgICAgICAgICAgIDxsYWJlbD5EZWZhdWx0IEZpZWxkOjwvbGFiZWw+XG4gICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgW25nTW9kZWxdPVwiYm9va1N1YnRleHQoKS5kZWZhdWx0RmllbGRcIiAobmdNb2RlbENoYW5nZSk9XCJ1cGRhdGVCb29rU3VidGV4dCgnZGVmYXVsdEZpZWxkJywgJGV2ZW50KVwiIC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBwcm9wIG9mIGdldFByb3BlcnRpZXMoKT8uZWxlbWVudFByb3BzOyB0cmFja0J5OiB0cmFja0J5UHJvcFwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICA8bGFiZWwgKm5nSWY9XCJwcm9wLnR5cGUgIT09ICdjaGVja2JveCcgJiYgcHJvcC50eXBlICE9PSAnc3ViUXVlc3Rpb24nXCIgY2xhc3M9XCJ0ZXh0LXNtXCI+e3sgcHJvcC5sYWJlbCB9fTwvbGFiZWw+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwicHJvcC5rZXkgPT09ICdoZWxwVGV4dCcgJiYgc2VsZWN0ZWRFbGVtZW50KCk/LmhlbHBUZXh0XCI+e3sgc2VsZWN0ZWRFbGVtZW50KCk/LmhlbHBUZXh0IH19PC9kaXY+XG4gICAgICAgICAgICA8aW5wdXQgKm5nSWY9XCJwcm9wLnR5cGUgPT09ICd0ZXh0J1wiXG4gICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cInByb3AucGxhY2Vob2xkZXJcIlxuICAgICAgICAgICAgICBbbmdNb2RlbF09XCJoZWFkZXJTZWxlY3QoKSA/IGJvb2soKS5yZWNvcmRzWzBdLnRpdGxlIDogKHNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnICYmIChwcm9wLnRhcmdldEFycmF5IHx8IHByb3AuaXNUYWJsZUNvbHVtbikgPyAoZ2V0VmFsdWVCeUFycmF5UGF0aChwcm9wLnRhcmdldEFycmF5LCBwcm9wLnRhcmdldEFycmF5S2V5LCBzZWxlY3RDb2x1bW4oKSwgcHJvcC5rZXksIHByb3AuaXNUYWJsZUNvbHVtbikpIDogKHNlbGVjdGVkRWxlbWVudCgpIHwgZ2V0VmFsdWVCeVBhdGggOiBwcm9wLmtleSkpXCJcbiAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiaGVhZGVyU2VsZWN0KCkgPyB1cGRhdGVUaXRsZSgkZXZlbnQpIDogKHNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnICYmIChwcm9wLnRhcmdldEFycmF5IHx8IHByb3AuaXNUYWJsZUNvbHVtbikgPyB1cGRhdGVWYWx1ZUJ5QXJyYXlQYXRoKHByb3AudGFyZ2V0QXJyYXksIHByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCBwcm9wLmtleSwgJGV2ZW50LCBwcm9wLmlzVGFibGVDb2x1bW4pIDogc2V0VmFsdWVCeVBhdGgocHJvcC5rZXksICRldmVudCkpXCJcbiAgICAgICAgICAgICAgW2NsYXNzLnJlYWQtb25seV09XCJzZWxlY3RlZEVsZW1lbnQoKT8ucmVhZE9ubHlcIlxuICAgICAgICAgICAgICBbcmVhZG9ubHldPVwic2VsZWN0ZWRFbGVtZW50KCk/LnJlYWRPbmx5XCJcbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgICA8aW5wdXQgKm5nSWY9XCJwcm9wLnR5cGUgPT09ICdudW1iZXInXCJcbiAgICAgICAgICAgICAgdHlwZT1cIm51bWJlclwiXG4gICAgICAgICAgICAgIFtuZ01vZGVsXT1cIihzZWxlY3RlZEVsZW1lbnQoKT8udHlwZSA9PT0gJ1RhYmxlJyAmJiAocHJvcC50YXJnZXRBcnJheSB8fCBwcm9wLmlzVGFibGVDb2x1bW4pID8gKGdldFZhbHVlQnlBcnJheVBhdGgocHJvcC50YXJnZXRBcnJheSwgcHJvcC50YXJnZXRBcnJheUtleSwgc2VsZWN0Q29sdW1uKCksIHByb3Aua2V5LCBwcm9wLmlzVGFibGVDb2x1bW4pKSA6IChzZWxlY3RlZEVsZW1lbnQoKSB8IGdldFZhbHVlQnlQYXRoIDogcHJvcC5rZXkpKVwiXG4gICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIihzZWxlY3RlZEVsZW1lbnQoKT8udHlwZSA9PT0gJ1RhYmxlJyAmJiAocHJvcC50YXJnZXRBcnJheSB8fCBwcm9wLmlzVGFibGVDb2x1bW4pID8gdXBkYXRlVmFsdWVCeUFycmF5UGF0aChwcm9wLnRhcmdldEFycmF5LCBwcm9wLnRhcmdldEFycmF5S2V5LCBzZWxlY3RDb2x1bW4oKSwgcHJvcC5rZXksICRldmVudCwgcHJvcC5pc1RhYmxlQ29sdW1uKSA6IHNldFZhbHVlQnlQYXRoKHByb3Aua2V5LCAkZXZlbnQpKVwiXG4gICAgICAgICAgICAvPlxuICAgICAgICAgICAgPHNlbGVjdCAqbmdJZj1cInByb3AudHlwZSA9PT0gJ3NlbGVjdCdcIlxuICAgICAgICAgICAgICBbbmdNb2RlbF09XCIoc2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgJiYgKHByb3AudGFyZ2V0QXJyYXkgfHwgcHJvcC5pc1RhYmxlQ29sdW1uKSA/IChnZXRWYWx1ZUJ5QXJyYXlQYXRoKHByb3AudGFyZ2V0QXJyYXksIHByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCBwcm9wLmtleSwgcHJvcC5pc1RhYmxlQ29sdW1uKSkgOiAoc2VsZWN0ZWRFbGVtZW50KCkgfCBnZXRWYWx1ZUJ5UGF0aCA6IHByb3Aua2V5KSlcIlxuICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCIoc2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgJiYgKHByb3AudGFyZ2V0QXJyYXkgfHwgcHJvcC5pc1RhYmxlQ29sdW1uKSA/IHVwZGF0ZVZhbHVlQnlBcnJheVBhdGgocHJvcC50YXJnZXRBcnJheSwgcHJvcC50YXJnZXRBcnJheUtleSwgc2VsZWN0Q29sdW1uKCksIHByb3Aua2V5LCAkZXZlbnQsIHByb3AuaXNUYWJsZUNvbHVtbikgOiBzZXRWYWx1ZUJ5UGF0aChwcm9wLmtleSwgJGV2ZW50KSlcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBvcHRpb24gb2YgcHJvcC5vcHRpb25zXCIgW3ZhbHVlXT1cIm9wdGlvbi52YWx1ZVwiPnt7IG9wdGlvbi5sYWJlbCB9fTwvb3B0aW9uPlxuICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwicHJvcC50eXBlID09PSAnY2hlY2tib3gnXCI+XG4gICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgIHR5cGU9XCJjaGVja2JveFwiXG4gICAgICAgICAgICAgICAgW2NoZWNrZWRdPVwic2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgPyAocHJvcC50YXJnZXRBcnJheSB8fCBwcm9wLmlzVGFibGVDb2x1bW4gPyBnZXRWYWx1ZUJ5QXJyYXlQYXRoKHByb3AudGFyZ2V0QXJyYXksIHByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCBwcm9wLmtleSwgcHJvcC5pc1RhYmxlQ29sdW1uKSA6IChzZWxlY3RlZEVsZW1lbnQoKSB8IGdldFZhbHVlQnlQYXRoIDogcHJvcC5rZXkpKSA6IChzZWxlY3RlZEVsZW1lbnQoKSB8IGdldFZhbHVlQnlQYXRoIDogcHJvcC5rZXkpXCJcbiAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnID8gKHByb3AudGFyZ2V0QXJyYXkgfHwgcHJvcC5pc1RhYmxlQ29sdW1uID8gdXBkYXRlVmFsdWVCeUFycmF5UGF0aChwcm9wLnRhcmdldEFycmF5LCBwcm9wLnRhcmdldEFycmF5S2V5LCBzZWxlY3RDb2x1bW4oKSwgcHJvcC5rZXksICRldmVudCwgcHJvcC5pc1RhYmxlQ29sdW1uKSA6IG9uVG9nZ2xlQ2hhbmdlKHByb3Aua2V5LCAkZXZlbnQpKSA6IG9uVG9nZ2xlQ2hhbmdlKHByb3Aua2V5LCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0b2dnbGUtbGFiZWxcIiBzdHlsZT1cInBhZGRpbmctbGVmdDogMTBweDtcIj57eyBwcm9wLmxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwicHJvcC50eXBlID09PSAnc3ViUXVlc3Rpb24nXCI+XG4gICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBmbGV4LWRpcmVjdGlvbjogcm93OyBnYXA6IDEwcHg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7XCI+XG4gICAgICAgICAgICAgICAgPGRpdj57eyBwcm9wLmxhYmVsIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgICAgICAgICAgW2NoZWNrZWRdPVwic2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgPyAocHJvcC50YXJnZXRBcnJheSB8fCBwcm9wLmlzVGFibGVDb2x1bW4gPyBnZXRWYWx1ZUJ5QXJyYXlQYXRoKHByb3AudGFyZ2V0QXJyYXksIHByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCBwcm9wLmtleSwgcHJvcC5pc1RhYmxlQ29sdW1uKSA6IChzZWxlY3RlZEVsZW1lbnQoKSB8IGdldFZhbHVlQnlQYXRoIDogcHJvcC5rZXkpKSA6IChzZWxlY3RlZEVsZW1lbnQoKSB8IGdldFZhbHVlQnlQYXRoIDogcHJvcC5rZXkpXCJcbiAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwic2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgPyAocHJvcC50YXJnZXRBcnJheSB8fCBwcm9wLmlzVGFibGVDb2x1bW4gPyB1cGRhdGVWYWx1ZUJ5QXJyYXlQYXRoKHByb3AudGFyZ2V0QXJyYXksIHByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCBwcm9wLmtleSwgJGV2ZW50LCBwcm9wLmlzVGFibGVDb2x1bW4pIDogb25Ub2dnbGVDaGFuZ2UocHJvcC5rZXksICRldmVudCkpIDogb25Ub2dnbGVDaGFuZ2UocHJvcC5rZXksICRldmVudClcIlxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgKm5nSWY9XCJzZWxlY3RlZEVsZW1lbnQoKT8udHlwZSA9PT0gJ1RhYmxlJyA/IChwcm9wLnRhcmdldEFycmF5IHx8IHByb3AuaXNUYWJsZUNvbHVtbiA/IGdldFZhbHVlQnlBcnJheVBhdGgocHJvcC50YXJnZXRBcnJheSwgcHJvcC50YXJnZXRBcnJheUtleSwgc2VsZWN0Q29sdW1uKCksIHByb3Aua2V5LCBwcm9wLmlzVGFibGVDb2x1bW4pIDogKHNlbGVjdGVkRWxlbWVudCgpIHwgZ2V0VmFsdWVCeVBhdGggOiBwcm9wLmtleSkpIDogKHNlbGVjdGVkRWxlbWVudCgpIHwgZ2V0VmFsdWVCeVBhdGggOiBwcm9wLmtleSlcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgc3ViUHJvcCBvZiBwcm9wLnN1YlF1ZXN0aW9uXCIgc3R5bGU9XCJiYWNrZ3JvdW5kLWNvbG9yOiAjZTdmMmZmOyBwYWRkaW5nOiA4cHg7IGJvcmRlci1yYWRpdXM6IDRweDtcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbD57eyBzdWJQcm9wLmxhYmVsIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cInN1YlByb3AudHlwZSA9PT0gJ2FycmF5J1wiPlxuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiBmaWx0ZXJlZENvbHVtbnMoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cInN1YlByb3Aub3BlcmFuZHMgPyBzdWJQcm9wLm9wZXJhbmRzLmluY2x1ZGVzKGNvbHVtbi5hcGlOYW1lKSA6IGZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIm9uQ2hlY2tib3hDaGFuZ2Uoc3ViUHJvcC50YXJnZXRBcnJheSwgc3ViUHJvcC50YXJnZXRBcnJheUtleSwgc3ViUHJvcC5rZXksIGNvbHVtbi5hcGlOYW1lLCAkZXZlbnQudGFyZ2V0LmNoZWNrZWQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBjb2x1bW4uYXBpTmFtZSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJzdWJQcm9wLnR5cGUgPT09ICdyYWRpbydcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgZmlsdGVyZWRDb2x1bW5zKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cInJhZGlvXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmFtZV09XCJzdWJQcm9wLmtleVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImNvbHVtbi5hcGlOYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2hlY2tlZF09XCJnZXRWYWx1ZUJ5QXJyYXlQYXRoKHN1YlByb3AudGFyZ2V0QXJyYXksIHN1YlByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCBzdWJQcm9wLmtleSkgPT09IGNvbHVtbi5hcGlOYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIm9uUmFkaW9DaGFuZ2Uoc3ViUHJvcC50YXJnZXRBcnJheSwgc3ViUHJvcC50YXJnZXRBcnJheUtleSwgc3ViUHJvcC5rZXksIGNvbHVtbi5hcGlOYW1lKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAge3sgY29sdW1uLmFwaU5hbWUgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInN1YlByb3AudHlwZSA9PT0gJ3RleHQnXCJcbiAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cInN1YlByb3AucGxhY2Vob2xkZXJcIlxuICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnID8gKHN1YlByb3AudGFyZ2V0QXJyYXkgPyBnZXRWYWx1ZUJ5QXJyYXlQYXRoKHN1YlByb3AudGFyZ2V0QXJyYXksIHN1YlByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCBzdWJQcm9wLmtleSkgOiAoc2VsZWN0ZWRFbGVtZW50KCkgfCBnZXRWYWx1ZUJ5UGF0aCA6IHN1YlByb3Aua2V5KSkgOiAoc2VsZWN0ZWRFbGVtZW50KCkgfCBnZXRWYWx1ZUJ5UGF0aCA6IHN1YlByb3Aua2V5KVwiXG4gICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwic2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgPyAoc3ViUHJvcC50YXJnZXRBcnJheSA/IHVwZGF0ZVZhbHVlQnlBcnJheVBhdGgoc3ViUHJvcC50YXJnZXRBcnJheSwgc3ViUHJvcC50YXJnZXRBcnJheUtleSwgc2VsZWN0Q29sdW1uKCksIHN1YlByb3Aua2V5LCAkZXZlbnQpIDogc2V0VmFsdWVCeVBhdGgoc3ViUHJvcC5rZXksICRldmVudCkpIDogc2V0VmFsdWVCeVBhdGgoc3ViUHJvcC5rZXksICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInN1YlByb3AudHlwZSA9PT0gJ2Jvb2xlYW4nXCJcbiAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cInNlbGVjdGVkRWxlbWVudCgpIHwgZ2V0VmFsdWVCeVBhdGggOiBzdWJQcm9wLmtleVwiXG4gICAgICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJzZXRWYWx1ZUJ5UGF0aChzdWJQcm9wLmtleSwgJGV2ZW50LnRhcmdldC5jaGVja2VkKVwiXG4gICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgIDxzZWxlY3RcbiAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInN1YlByb3AudHlwZSA9PT0gJ3NlbGVjdCdcIlxuICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cIihzZWxlY3RlZEVsZW1lbnQoKT8udHlwZSA9PT0gJ1RhYmxlJyAmJiAoc3ViUHJvcC50YXJnZXRBcnJheSB8fCBzdWJQcm9wLmlzVGFibGVDb2x1bW4pID8gKGdldFZhbHVlQnlBcnJheVBhdGgoc3ViUHJvcC50YXJnZXRBcnJheSwgc3ViUHJvcC50YXJnZXRBcnJheUtleSwgc2VsZWN0Q29sdW1uKCksIHN1YlByb3Aua2V5LCBzdWJQcm9wLmlzVGFibGVDb2x1bW4pKSA6IChzZWxlY3RlZEVsZW1lbnQoKSB8IGdldFZhbHVlQnlQYXRoIDogc3ViUHJvcC5rZXkpKVwiXG4gICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiKHNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnICYmIChzdWJQcm9wLnRhcmdldEFycmF5IHx8IHN1YlByb3AuaXNUYWJsZUNvbHVtbikgPyB1cGRhdGVWYWx1ZUJ5QXJyYXlQYXRoKHN1YlByb3AudGFyZ2V0QXJyYXksIHN1YlByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCBzdWJQcm9wLmtleSwgJGV2ZW50LCBzdWJQcm9wLmlzVGFibGVDb2x1bW4pIDogc2V0VmFsdWVCeVBhdGgoc3ViUHJvcC5rZXksICRldmVudCkpXCJcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IG9wdGlvbiBvZiBzdWJQcm9wLm9wdGlvbnNcIiBbdmFsdWVdPVwib3B0aW9uLnZhbHVlXCI+e3sgb3B0aW9uLmxhYmVsIH19PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInN1YlByb3AudHlwZSA9PT0gJ2NoZWNrYm94J1wiXG4gICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImNoZWNrYm94XCJcbiAgICAgICAgICAgICAgICAgICAgICBbY2hlY2tlZF09XCJzZWxlY3RlZEVsZW1lbnQoKSB8IGdldFZhbHVlQnlQYXRoIDogc3ViUHJvcC5rZXlcIlxuICAgICAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwic2V0VmFsdWVCeVBhdGgoc3ViUHJvcC5rZXksICRldmVudC50YXJnZXQuY2hlY2tlZClcIlxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwicHJvcC50eXBlID09PSAnYWxpZ24nXCI+XG4gICAgICAgICAgICAgIDxidXR0b24gKm5nRm9yPVwibGV0IG9wdGlvbiBvZiBwcm9wLm9wdGlvbnNcIiAoY2xpY2spPVwib25BbGlnblNlbGVjdChvcHRpb24udmFsdWUpXCIgW25nQ2xhc3NdPVwieydhY3RpdmUnOiBzZWxlY3RlZEVsZW1lbnQoKT8udGV4dEFsaWduID09PSBvcHRpb24udmFsdWV9XCIgW3RpdGxlXT1cIm9wdGlvbi52YWx1ZVwiPlxuICAgICAgICAgICAgICAgIDxpbWcgW3NyY109XCInLi4vYXNzZXRzL2ljb25zLycgKyBvcHRpb24uaWNvbiArICcuc3ZnJ1wiIFthbHRdPVwib3B0aW9uLnZhbHVlXCIgY2xhc3M9XCJpY29uLXNpemVcIiAvPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cInByb3AudHlwZSA9PT0gJ3N0eWxlJ1wiPlxuICAgICAgICAgICAgICA8YnV0dG9uICpuZ0Zvcj1cImxldCBvcHRpb24gb2YgcHJvcC5vcHRpb25zXCIgKGNsaWNrKT1cIm9uU3R5bGVTZWxlY3Qob3B0aW9uLnZhbHVlKVwiIFtuZ0NsYXNzXT1cInsnYWN0aXZlJzogaXNTdHlsZUFjdGl2ZShvcHRpb24udmFsdWUpfVwiIFt0aXRsZV09XCJvcHRpb24udmFsdWVcIj5cbiAgICAgICAgICAgICAgICA8aW1nIFtzcmNdPVwiJy4uL2Fzc2V0cy9pY29ucy8nICsgb3B0aW9uLmljb24gKyAnLnN2ZydcIiBbYWx0XT1cIm9wdGlvbi52YWx1ZVwiIGNsYXNzPVwiaWNvbi1zaXplXCIgLz5cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJwcm9wLnR5cGUgPT09ICdjb2xvcidcIj5cbiAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgdHlwZT1cImNvbG9yXCJcbiAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCIoc2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgJiYgKHByb3AudGFyZ2V0QXJyYXkgfHwgcHJvcC5pc1RhYmxlQ29sdW1uKSA/IChnZXRWYWx1ZUJ5QXJyYXlQYXRoKHByb3AudGFyZ2V0QXJyYXksIHByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCBwcm9wLmtleSwgcHJvcC5pc1RhYmxlQ29sdW1uKSkgOiAoc2VsZWN0ZWRFbGVtZW50KCkgfCBnZXRWYWx1ZUJ5UGF0aCA6IHByb3Aua2V5KSlcIlxuICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIihzZWxlY3RlZEVsZW1lbnQoKT8udHlwZSA9PT0gJ1RhYmxlJyAmJiAocHJvcC50YXJnZXRBcnJheSB8fCBwcm9wLmlzVGFibGVDb2x1bW4pID8gdXBkYXRlVmFsdWVCeUFycmF5UGF0aChwcm9wLnRhcmdldEFycmF5LCBwcm9wLnRhcmdldEFycmF5S2V5LCBzZWxlY3RDb2x1bW4oKSwgcHJvcC5rZXksICRldmVudCwgcHJvcC5pc1RhYmxlQ29sdW1uKSA6IHNldFZhbHVlQnlQYXRoKHByb3Aua2V5LCAkZXZlbnQpKVwiXG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJwcm9wLmtleSA9PT0gJ3RpdGxlJ1wiIHN0eWxlPVwibWFyZ2luLXRvcDogMTVweDsgYm9yZGVyOiAxcHggc29saWQgI2RkZDsgcGFkZGluZzogMjBweDsgYm9yZGVyLXJhZGl1czogMTJweDsgYmFja2dyb3VuZC1jb2xvcjogI2Y5ZjlmOTtcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0taGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbFwiPnt7IHByb3AubGFiZWwgfX08L2xhYmVsPlxuICAgICAgICAgICAgICAgIDxidXR0b24gKGNsaWNrKT1cImFkZE5ld0J1dHRvbigpXCIgY2xhc3M9XCJhZGQtYnV0dG9uXCI+KyBBZGQgQnV0dG9uPC9idXR0b24+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBidG4gb2YgYm9vaygpPy5xdWVzdGlvbmJvb2s/LmFjdGlvbiB8fCBbXTsgbGV0IGkgPSBpbmRleFwiIGNsYXNzPVwiYnV0dG9uLWNvbmZpZy1jYXJkXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICAgICAgICAgICAgICAgIDxsYWJlbD5CdXR0b24gTmFtZTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBbbmdNb2RlbF09XCJidG4ubmFtZVwiIChuZ01vZGVsQ2hhbmdlKT1cIm9uQnV0dG9uUHJvcGVydHlDaGFuZ2UoaSwgJ25hbWUnLCAkZXZlbnQpXCIgcGxhY2Vob2xkZXI9XCJFbnRlciBidXR0b24gbmFtZVwiPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICA8bGFiZWw+RXZlbnQgTmFtZTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBbbmdNb2RlbF09XCJidG4uZXZlbnR0b2VtaXRcIiAobmdNb2RlbENoYW5nZSk9XCJvbkJ1dHRvblByb3BlcnR5Q2hhbmdlKGksICdldmVudHRvZW1pdCcsICRldmVudClcIiBwbGFjZWhvbGRlcj1cIkV2ZW50IHRvIGVtaXRcIj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgPGxhYmVsPkFsdDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBbbmdNb2RlbF09XCJidG4uYWx0XCIgKG5nTW9kZWxDaGFuZ2UpPVwib25CdXR0b25Qcm9wZXJ0eUNoYW5nZShpLCAnYWx0JywgJGV2ZW50KVwiIHBsYWNlaG9sZGVyPVwiQnV0dG9uIGFsdCB0ZXh0XCI+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICAgICAgICAgICAgICAgIDxsYWJlbD5FbmRwb2ludDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBbbmdNb2RlbF09XCJidG4uZW5kcG9pbnRcIiAobmdNb2RlbENoYW5nZSk9XCJvbkJ1dHRvblByb3BlcnR5Q2hhbmdlKGksICdlbmRwb2ludCcsICRldmVudClcIiBwbGFjZWhvbGRlcj1cIkFQSSBlbmRwb2ludFwiPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICA8bGFiZWw+TWV0aG9kPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgIDxzZWxlY3QgW25nTW9kZWxdPVwiYnRuLm1ldGhvZFwiIChuZ01vZGVsQ2hhbmdlKT1cIm9uQnV0dG9uUHJvcGVydHlDaGFuZ2UoaSwgJ21ldGhvZCcsICRldmVudClcIj5cbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIkdFVFwiPkdFVDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiUE9TVFwiPlBPU1Q8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlBVVFwiPlBVVDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiREVMRVRFXCI+REVMRVRFPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgPGxhYmVsPkJhY2tncm91bmQgQ29sb3I8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjb2xvclwiIFtuZ01vZGVsXT1cImJ0bi5iZ0NvbG9yXCIgKG5nTW9kZWxDaGFuZ2UpPVwib25CdXR0b25Qcm9wZXJ0eUNoYW5nZShpLCAnYmdDb2xvcicsICRldmVudClcIj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgPGxhYmVsPkJvcmRlciBSYWRpdXM8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJyYW5nZVwiIG1pbj1cIjBcIiBtYXg9XCI1MFwiIFtuZ01vZGVsXT1cImJ0bi5ib3JkZXJSYWRpdXNcIiAobmdNb2RlbENoYW5nZSk9XCJvbkJ1dHRvblByb3BlcnR5Q2hhbmdlKGksICdib3JkZXJSYWRpdXMnLCAkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICA8c3Bhbj57eyBidG4uYm9yZGVyUmFkaXVzIH19cHg8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICAgICAgICAgICAgICAgIDxsYWJlbD5CdXR0b24gV2lkdGggKHB4KTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiIFtuZ01vZGVsXT1cImJ0bi53aWR0aFwiIChuZ01vZGVsQ2hhbmdlKT1cIm9uQnV0dG9uUHJvcGVydHlDaGFuZ2UoaSwgJ3dpZHRoJywgJGV2ZW50KVwiIG1pbj1cIjUwXCIgcGxhY2Vob2xkZXI9XCJFbnRlciB3aWR0aCBpbiBweFwiPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICA8bGFiZWw+VGV4dCBDb2xvcjwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNvbG9yXCIgW25nTW9kZWxdPVwiYnRuLnRleHRDb2xvclwiIChuZ01vZGVsQ2hhbmdlKT1cIm9uQnV0dG9uUHJvcGVydHlDaGFuZ2UoaSwgJ3RleHRDb2xvcicsICRldmVudClcIj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgPGxhYmVsPlBvc2l0aW9uICglKTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInJhbmdlXCIgbWluPVwiMFwiIG1heD1cIjEwMFwiIFtuZ01vZGVsXT1cImJ0bi5wb3NpdGlvblBlcmNlbnRcIiAobmdNb2RlbENoYW5nZSk9XCJvbkJ1dHRvblByb3BlcnR5Q2hhbmdlKGksICdwb3NpdGlvblBlcmNlbnQnLCAkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICA8c3Bhbj57eyBidG4ucG9zaXRpb25QZXJjZW50IH19JTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIChjbGljayk9XCJyZW1vdmVCdXR0b24oYnRuKVwiIGNsYXNzPVwicmVtb3ZlLWJ1dHRvblwiPsOXIFJlbW92ZTwvYnV0dG9uPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvZGl2PlxuICAgIH1cbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cInRhYi1jb250ZW50XCIgKm5nSWY9XCJhY3RpdmVUYWIoKSA9PT0gJ3Byb3BlcnR5J1wiPlxuICAgIEBkZWZlciAod2hlbiBnZXRQcm9wZXJ0aWVzKCkpIHtcbiAgICAgIDxkaXY+XG4gICAgICAgIDxsYWJlbD5MYWJlbCBJZDwvbGFiZWw+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJmb250LXNpemU6IDEzcHg7IHBhZGRpbmc6IDExcHg7IGJvcmRlci1yYWRpdXM6IDVweDsgYmFja2dyb3VuZC1jb2xvcjogI2Y4ZjhmODsgYm9yZGVyOiAxcHggc29saWQgI2RkZDtcIj5cbiAgICAgICAgICB7eyBoZWFkZXJTZWxlY3QoKSA/IGJvb2tJZCgpIDogc2VsZWN0ZWRFbGVtZW50KCk/LmlkIH19XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBwcm9wIG9mIGdldFByb3BlcnRpZXMoKT8uZmllbGRQcm9wczsgdHJhY2tCeTogdHJhY2tCeVByb3BcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgICAgICAgICAgPGxhYmVsICAqbmdJZj1cInByb3AudHlwZSAhPT0gJ3N1YlF1ZXN0aW9uJ1wiIGNsYXNzPVwidGV4dC1zbVwiPnt7IHByb3AubGFiZWwgfX08L2xhYmVsPlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cInByb3AudHlwZSA9PT0gJ3RvZ2dsZUdyb3VwJ1wiIGNsYXNzPVwidG9nZ2xlLWdyb3VwXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0b2dnbGUtaXRlbVwiPlxuICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInRvZ2dsZS1sYWJlbFwiPlxuICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIFxuICAgICAgICAgICAgICAgICAgW2NoZWNrZWRdPVwic2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgPyAocHJvcC50YXJnZXRBcnJheSB8fCBwcm9wLmlzVGFibGVDb2x1bW4gPyBnZXRWYWx1ZUJ5QXJyYXlQYXRoKHByb3AudGFyZ2V0QXJyYXksIHByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCAnaXNPcHRpb25hbCcsIHRydWUpIDogKHNlbGVjdGVkRWxlbWVudCgpIHwgZ2V0VmFsdWVCeVBhdGggOiBwcm9wLmtleSkpIDogKHNlbGVjdGVkRWxlbWVudCgpIHwgZ2V0VmFsdWVCeVBhdGggOiAnaXNPcHRpb25hbCcpXCJcbiAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwic2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgPyAocHJvcC50YXJnZXRBcnJheSB8fCBwcm9wLmlzVGFibGVDb2x1bW4gPyB1cGRhdGVWYWx1ZUJ5QXJyYXlQYXRoKHByb3AudGFyZ2V0QXJyYXksIHByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCAnaXNPcHRpb25hbCcsICRldmVudCwgdHJ1ZSkgOiBvblRvZ2dsZUNoYW5nZShwcm9wLmtleSwgJGV2ZW50KSkgOiBvblRvZ2dsZUNoYW5nZSgnaXNPcHRpb25hbCcsICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgIFJlcXVpcmVkXG4gICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0b2dnbGUtaXRlbVwiPlxuICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInRvZ2dsZS1sYWJlbFwiPlxuICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIFxuICAgICAgICAgICAgICAgICAgW2NoZWNrZWRdPVwic2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgPyAocHJvcC50YXJnZXRBcnJheSB8fCBwcm9wLmlzVGFibGVDb2x1bW4gPyBnZXRWYWx1ZUJ5QXJyYXlQYXRoKHByb3AudGFyZ2V0QXJyYXksIHByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCAnaXNSZWFkT25seScsIHRydWUpIDogKHNlbGVjdGVkRWxlbWVudCgpIHwgZ2V0VmFsdWVCeVBhdGggOiBwcm9wLmtleSkpIDogKHNlbGVjdGVkRWxlbWVudCgpIHwgZ2V0VmFsdWVCeVBhdGggOiAnaXNSZWFkT25seScpXCJcbiAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwic2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgPyAocHJvcC50YXJnZXRBcnJheSB8fCBwcm9wLmlzVGFibGVDb2x1bW4gPyB1cGRhdGVWYWx1ZUJ5QXJyYXlQYXRoKHByb3AudGFyZ2V0QXJyYXksIHByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCAnaXNSZWFkT25seScsICRldmVudCwgdHJ1ZSkgOiBvblRvZ2dsZUNoYW5nZShwcm9wLmtleSwgJGV2ZW50KSkgOiBvblRvZ2dsZUNoYW5nZSgnaXNSZWFkT25seScsICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgIFJlYWQgT25seVxuICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidG9nZ2xlLWl0ZW1cIj5cbiAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJ0b2dnbGUtbGFiZWxcIj5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBcbiAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cInNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnID8gKHByb3AudGFyZ2V0QXJyYXkgfHwgcHJvcC5pc1RhYmxlQ29sdW1uID8gZ2V0VmFsdWVCeUFycmF5UGF0aChwcm9wLnRhcmdldEFycmF5LCBwcm9wLnRhcmdldEFycmF5S2V5LCBzZWxlY3RDb2x1bW4oKSwgJ2lzSGlkZGVuJywgdHJ1ZSkgOiAoc2VsZWN0ZWRFbGVtZW50KCkgfCBnZXRWYWx1ZUJ5UGF0aCA6IHByb3Aua2V5KSkgOiAoc2VsZWN0ZWRFbGVtZW50KCkgfCBnZXRWYWx1ZUJ5UGF0aCA6ICdpc0hpZGRlbicpXCJcbiAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwic2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgPyAocHJvcC50YXJnZXRBcnJheSB8fCBwcm9wLmlzVGFibGVDb2x1bW4gPyB1cGRhdGVWYWx1ZUJ5QXJyYXlQYXRoKHByb3AudGFyZ2V0QXJyYXksIHByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCAnaXNIaWRkZW4nLCAkZXZlbnQsIHRydWUpIDogb25Ub2dnbGVDaGFuZ2UocHJvcC5rZXksICRldmVudCkpIDogb25Ub2dnbGVDaGFuZ2UoJ2lzSGlkZGVuJywgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgSXMgSGlkZVxuICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiIHByb3AudHlwZSA9PT0gJ2NoZWNrYm94JyB8fCBwcm9wLnR5cGUgPT09ICdyYWRpbycgfHwgcHJvcC5rZXkgPT09ICdvcHRpb25zJ1wiIGNsYXNzPVwib3B0aW9ucy1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm9wdGlvbi1saXN0XCIgKGRyYWdvdmVyKT1cIm9uRHJhZ092ZXIoJGV2ZW50KVwiIChkcm9wKT1cIm9uRHJvcCgkZXZlbnQsIHByb3Aua2V5KVwiPlxuICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IG9wdGlvbiBvZiBzZWxlY3RlZEVsZW1lbnQoKT8udHlwZSA9PT0gJ1RhYmxlJyAmJiBzZWxlY3RDb2x1bW4oKSA/IGdldFZhbHVlQnlBcnJheVBhdGgoJ2ZpZWxkc01ldGEnLCAndW5pcXVlSWRlbnRpZmllcicsIHNlbGVjdENvbHVtbigpLCAgcHJvcC5rZXksIHRydWUpIDogc2VsZWN0ZWRFbGVtZW50KClbcHJvcC5rZXldIDsgbGV0IGkgPSBpbmRleFwiIGNsYXNzPVwib3B0aW9uLWl0ZW1zXCIgW2F0dHIuZGF0YS1pZF09XCJvcHRpb24uaWRcIiBkcmFnZ2FibGU9XCJ0cnVlXCIgKGRyYWdzdGFydCk9XCJvbkRyYWdTdGFydCgkZXZlbnQsIG9wdGlvbi5pZClcIj5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIFtuZ01vZGVsXT1cIm9wdGlvbi52YWx1ZVwiIChuZ01vZGVsQ2hhbmdlKT1cIm9wdGlvbi52YWx1ZSA9ICRldmVudFwiIHBsYWNlaG9sZGVyPVwiT3B0aW9uXCIgY2xhc3M9XCJvcHRpb25zXCIgLz5cbiAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiLi4vYXNzZXRzL2ljb25zL1RyYXNoLnN2Z1wiIChjbGljayk9XCJyZW1vdmVPcHRpb24oc2VsZWN0ZWRFbGVtZW50KClbcHJvcC5rZXldLCBvcHRpb24uaWQpXCI+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRyYWctaGFuZGxlXCI+4piwPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiAoY2xpY2spPVwiYWRkT3B0aW9uKHNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnICYmIHNlbGVjdENvbHVtbigpID8gZ2V0VmFsdWVCeUFycmF5UGF0aCgnZmllbGRzTWV0YScsICd1bmlxdWVJZGVudGlmaWVyJywgc2VsZWN0Q29sdW1uKCksIHByb3Aua2V5LCB0cnVlKSA6IHNlbGVjdGVkRWxlbWVudCgpW3Byb3Aua2V5XSlcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWRkLXZhcmllbnRcIj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1sZ1wiPis8L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8c3Bhbj5BZGQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8aW5wdXQgKm5nSWY9XCJwcm9wLnR5cGUgPT09ICd0ZXh0J1wiXG4gICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cInByb3AucGxhY2Vob2xkZXJcIlxuICAgICAgICAgICAgICBbbmdNb2RlbF09XCJoZWFkZXJTZWxlY3QoKSA/IGJvb2soKS5yZWNvcmRzWzBdLnRpdGxlIDogKHNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnICYmIChwcm9wLnRhcmdldEFycmF5IHx8IHByb3AuaXNUYWJsZUNvbHVtbikgPyBnZXRWYWx1ZUJ5QXJyYXlQYXRoKHByb3AudGFyZ2V0QXJyYXksIHByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCBwcm9wLmtleSwgcHJvcC5pc1RhYmxlQ29sdW1uKSA6IChzZWxlY3RlZEVsZW1lbnQoKSB8IGdldFZhbHVlQnlQYXRoIDogcHJvcC5rZXkpKVwiXG4gICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImhlYWRlclNlbGVjdCgpID8gdXBkYXRlVGl0bGUoJGV2ZW50KSA6IChzZWxlY3RlZEVsZW1lbnQoKT8udHlwZSA9PT0gJ1RhYmxlJyAmJiAocHJvcC50YXJnZXRBcnJheSB8fCBwcm9wLmlzVGFibGVDb2x1bW4pID8gdXBkYXRlVmFsdWVCeUFycmF5UGF0aChwcm9wLnRhcmdldEFycmF5LCBwcm9wLnRhcmdldEFycmF5S2V5LCBzZWxlY3RDb2x1bW4oKSwgcHJvcC5rZXksICRldmVudCwgcHJvcC5pc1RhYmxlQ29sdW1uKSA6IHNldFZhbHVlQnlQYXRoKHByb3Aua2V5LCAkZXZlbnQpKVwiXG4gICAgICAgICAgICAgIFtjbGFzcy5yZWFkLW9ubHldPVwic2VsZWN0ZWRFbGVtZW50KCk/LnJlYWRPbmx5XCJcbiAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cInNlbGVjdGVkRWxlbWVudCgpPy5yZWFkT25seVwiXG4gICAgICAgICAgICAvPlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cInByb3AudHlwZSA9PT0gJ3N1YlF1ZXN0aW9uJ1wiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3R5bGUtdG9nZ2xlLWhlYWRlclwiIChjbGljayk9XCJ0b2dnbGVTdWJRdWVzdGlvbihwcm9wKVwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoZWFkLWVsZW1lbnRzXCI+U3ViIFRleHQ8L2Rpdj5cbiAgICAgICAgICAgICAgICA8aW1nIFtzcmNdPVwiaXNFeHBhbmRlZCA/ICcuLi9hc3NldHMvaWNvbnMvYXJyb3ctZG93bi5zdmcnIDogJy4uL2Fzc2V0cy9pY29ucy9hcnJvdy1yaWdodC5zdmcnXCJcbiAgICAgICAgICAgICAgICAgIGFsdD1cIlRvZ2dsZSBBcnJvd1wiIGNsYXNzPVwiYXJyb3ctaWNvblwiPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImlzRXhwYW5kZWRcIiBzdHlsZT1cImJvcmRlcjogMXB4IHNvbGlkICNkZGQ7IGJvcmRlci1yYWRpdXM6IDRweDtcIj5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBzdWJQcm9wIG9mIHByb3Auc3ViUXVlc3Rpb247IHRyYWNrQnk6IHRyYWNrQnlQcm9wXCIgc3R5bGU9XCJiYWNrZ3JvdW5kLWNvbG9yOiAjZTdmMmZmOyBwYWRkaW5nOiA4cHg7IGJvcmRlci1yYWRpdXM6IDRweDtcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbD57eyBzdWJQcm9wLmxhYmVsIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0ICpuZ0lmPVwic3ViUHJvcC50eXBlID09PSAndGV4dCdcIlxuICAgICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJzdWJQcm9wLnBsYWNlaG9sZGVyXCJcbiAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImdldE9wdGltaXplZFN1YlByb3BWYWx1ZShzdWJQcm9wKVwiXG4gICAgICAgICAgICAgICAgICAgIChpbnB1dCk9XCIoc2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgJiYgKHN1YlByb3AudGFyZ2V0QXJyYXkgfHwgc3ViUHJvcC5pc1RhYmxlQ29sdW1uKSkgPyB1cGRhdGVWYWx1ZUJ5QXJyYXlQYXRoKHN1YlByb3AudGFyZ2V0QXJyYXksIHN1YlByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCBzdWJQcm9wLmtleSwgJGV2ZW50LnRhcmdldC52YWx1ZSwgc3ViUHJvcC5pc1RhYmxlQ29sdW1uKSA6IHNldFZhbHVlQnlQYXRoKHN1YlByb3Aua2V5LCAkZXZlbnQudGFyZ2V0LnZhbHVlKVwiXG4gICAgICAgICAgICAgICAgICAgIFtjbGFzcy5yZWFkLW9ubHldPVwic2VsZWN0ZWRFbGVtZW50KCk/LnJlYWRPbmx5XCJcbiAgICAgICAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cInNlbGVjdGVkRWxlbWVudCgpPy5yZWFkT25seVwiIC8+XG4gICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgPCEtLSBBUC0wMkFQUjI1IFJlbmRlciBpbnB1dCBmaWVsZCBvbmx5IGlmIHN1YlByb3AudHlwZSBpcyAnYXJyYXknIC0tPlxuICAgICAgICAgICAgICAgICAgPGlucHV0ICpuZ0lmPVwic3ViUHJvcC50eXBlID09PSAnYXJyYXknXCIgdHlwZT1cInRleHRcIiBbcGxhY2Vob2xkZXJdPVwic3ViUHJvcC5wbGFjZWhvbGRlclwiXG4gICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJnZXRWYWx1ZUJ5UGF0aChzdWJQcm9wLmtleSlcIiAoaW5wdXQpPVwic2V0VmFsdWVCeVBhdGgoc3ViUHJvcC5rZXksICRldmVudC50YXJnZXQudmFsdWUpXCIgLz5cblxuICAgICAgICAgICAgICAgICAgPGlucHV0ICpuZ0lmPVwic3ViUHJvcC50eXBlID09PSAnYm9vbGVhbidcIiB0eXBlPVwiY2hlY2tib3hcIiBbY2hlY2tlZF09XCJnZXRWYWx1ZUJ5UGF0aChzdWJQcm9wLmtleSlcIlxuICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInNldFZhbHVlQnlQYXRoKHN1YlByb3Aua2V5LCAkZXZlbnQudGFyZ2V0LmNoZWNrZWQpXCIgLz5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cInByb3AudHlwZSA9PT0gJ2NoZWNrYm94J1wiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRvZ2dsZS1sYWJlbFwiIHN0eWxlPVwicGFkZGluZy1yaWdodDogMTBweDtcIj57eyBwcm9wLmxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cInNlbGVjdGVkRWxlbWVudCgpPy50eXBlID09PSAnVGFibGUnID8gKHByb3AudGFyZ2V0QXJyYXkgfHwgcHJvcC5pc1RhYmxlQ29sdW1uID8gZ2V0VmFsdWVCeUFycmF5UGF0aChwcm9wLnRhcmdldEFycmF5LCBwcm9wLnRhcmdldEFycmF5S2V5LCBzZWxlY3RDb2x1bW4oKSwgcHJvcC5rZXksIHByb3AuaXNUYWJsZUNvbHVtbikgOiAoc2VsZWN0ZWRFbGVtZW50KCkgfCBnZXRWYWx1ZUJ5UGF0aCA6IHByb3Aua2V5KSkgOiAoc2VsZWN0ZWRFbGVtZW50KCkgfCBnZXRWYWx1ZUJ5UGF0aCA6IHByb3Aua2V5KVwiXG4gICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJzZWxlY3RlZEVsZW1lbnQoKT8udHlwZSA9PT0gJ1RhYmxlJyA/IChwcm9wLnRhcmdldEFycmF5IHx8IHByb3AuaXNUYWJsZUNvbHVtbiA/IHVwZGF0ZVZhbHVlQnlBcnJheVBhdGgocHJvcC50YXJnZXRBcnJheSwgcHJvcC50YXJnZXRBcnJheUtleSwgc2VsZWN0Q29sdW1uKCksIHByb3Aua2V5LCAkZXZlbnQsIHByb3AuaXNUYWJsZUNvbHVtbikgOiBvblRvZ2dsZUNoYW5nZShwcm9wLmtleSwgJGV2ZW50KSkgOiBvblRvZ2dsZUNoYW5nZShwcm9wLmtleSwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJzdHlsZS10b2dnbGUtaGVhZGVyXCIgKGNsaWNrKT1cInRvZ2dsZVN0eWxlU2VjdGlvbigpXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImhlYWQtZWxlbWVudHNcIj5TdHlsZTwvZGl2PlxuICAgICAgICAgIDxpbWcgW3NyY109XCJpc1N0eWxlRXhwYW5kZWQoKSA/ICcuLi9hc3NldHMvaWNvbnMvYXJyb3ctZG93bi5zdmcnIDogJy4uL2Fzc2V0cy9pY29ucy9hcnJvdy1yaWdodC5zdmcnXCIgYWx0PVwiVG9nZ2xlIEFycm93XCIgY2xhc3M9XCJhcnJvdy1pY29uXCI+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNTdHlsZUV4cGFuZGVkKClcIiBzdHlsZT1cImJvcmRlcjogMXB4IHNvbGlkICNkZGQ7IHBhZGRpbmc6IDhweDsgYm9yZGVyLXJhZGl1czogNHB4O1wiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBrZXkgb2YgZ2V0U3R5bGVLZXlzKClcIj5cbiAgICAgICAgICAgICAgPGxhYmVsPnt7IGtleSB9fTwvbGFiZWw+XG4gICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgICAgICBbdmFsdWVdPVwic2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgJiYgc2VsZWN0Q29sdW1uKCkgPyBnZXRWYWx1ZUJ5QXJyYXlQYXRoKCdmaWVsZHNNZXRhJywgJ3VuaXF1ZUlkZW50aWZpZXInLCBzZWxlY3RDb2x1bW4oKSwnc3R5bGUuJyArIGtleSwgdHJ1ZSkgOiAoc2VsZWN0ZWRFbGVtZW50KCkgfCBnZXRWYWx1ZUJ5UGF0aCA6ICdzdHlsZS4nICsga2V5KVwiXG4gICAgICAgICAgICAgICAgKGlucHV0KT1cIihzZWxlY3RlZEVsZW1lbnQoKT8udHlwZSA9PT0gJ1RhYmxlJyAmJiBzZWxlY3RDb2x1bW4oKSApID8gdXBkYXRlVmFsdWVCeUFycmF5UGF0aCgnZmllbGRzTWV0YScsICd1bmlxdWVJZGVudGlmaWVyJywgc2VsZWN0Q29sdW1uKCksICdzdHlsZS4nICsga2V5LCAkZXZlbnQudGFyZ2V0LnZhbHVlLCB0cnVlKSA6IHNldFZhbHVlQnlQYXRoKCdzdHlsZS4nICsga2V5LCAkZXZlbnQudGFyZ2V0LnZhbHVlKVwiXG4gICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJFbnRlciB7eyBrZXkgfX1cIlxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgfVxuICA8L2Rpdj5cblxuICA8ZGl2IGNsYXNzPVwidGFiLWNvbnRlbnRcIiAqbmdJZj1cImFjdGl2ZVRhYigpID09PSAnYXBwZWFyYW5jZSdcIj5cbiAgICBAZGVmZXIgKHdoZW4gZ2V0UHJvcGVydGllcygpKSB7XG4gICAgICA8ZGl2PlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBwcm9wIG9mIGdldFByb3BlcnRpZXMoKT8uYXBwZWFyYW5jZTsgdHJhY2tCeTogdHJhY2tCeVByb3BcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwidGV4dC1zbVwiPnt7IHByb3AubGFiZWwgfX08L2xhYmVsPlxuICAgICAgICAgICAgPHNlbGVjdFxuICAgICAgICAgICAgICAqbmdJZj1cInByb3AudHlwZSA9PT0gJ3NlbGVjdCdcIlxuICAgICAgICAgICAgICBbbmdNb2RlbF09XCIoc2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgJiYgKHByb3AudGFyZ2V0QXJyYXkgfHwgcHJvcC5pc1RhYmxlQ29sdW1uKSA/IChnZXRWYWx1ZUJ5QXJyYXlQYXRoKHByb3AudGFyZ2V0QXJyYXksIHByb3AudGFyZ2V0QXJyYXlLZXksIHNlbGVjdENvbHVtbigpLCBwcm9wLmtleSwgcHJvcC5pc1RhYmxlQ29sdW1uKSkgOiAoc2VsZWN0ZWRFbGVtZW50KCkgfCBnZXRWYWx1ZUJ5UGF0aCA6IHByb3Aua2V5KSlcIlxuICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCIoc2VsZWN0ZWRFbGVtZW50KCk/LnR5cGUgPT09ICdUYWJsZScgJiYgKHByb3AudGFyZ2V0QXJyYXkgfHwgcHJvcC5pc1RhYmxlQ29sdW1uKSA/IHVwZGF0ZVZhbHVlQnlBcnJheVBhdGgocHJvcC50YXJnZXRBcnJheSwgcHJvcC50YXJnZXRBcnJheUtleSwgc2VsZWN0Q29sdW1uKCksIHByb3Aua2V5LCAkZXZlbnQsIHByb3AuaXNUYWJsZUNvbHVtbikgOiBzZXRWYWx1ZUJ5UGF0aChwcm9wLmtleSwgJGV2ZW50KSlcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBvcHRpb24gb2YgcHJvcC5vcHRpb25zXCIgW3ZhbHVlXT1cIm9wdGlvbi52YWx1ZVwiPnt7IG9wdGlvbi5sYWJlbCB9fTwvb3B0aW9uPlxuICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgKm5nSWY9XCJwcm9wLnR5cGUgPT09ICd0ZXh0J1wiXG4gICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cInByb3AucGxhY2Vob2xkZXJcIlxuICAgICAgICAgICAgICBbbmdNb2RlbF09XCJzZWxlY3RlZEVsZW1lbnQoKSB8IGdldFZhbHVlQnlQYXRoIDogcHJvcC5rZXlcIlxuICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJzZXRWYWx1ZUJ5UGF0aChwcm9wLmtleSwgJGV2ZW50KVwiXG4gICAgICAgICAgICAvPlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleC1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cInByb3AudHlwZSA9PT0gJ2NvbG9yJ1wiIGNsYXNzPVwiY29sb3Itc2VsZWN0b3JcIj5cbiAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgIHR5cGU9XCJjb2xvclwiXG4gICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJzZWxlY3RlZEVsZW1lbnQoKT8uZm9udENvbG9yXCJcbiAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInNldFZhbHVlQnlQYXRoKCdmb250Q29sb3InLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwicHJvcC50eXBlID09PSAnY29sb3InXCIgY2xhc3M9XCJoZXgtaW5wdXQtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4+SEVYIENvZGU8L3NwYW4+XG4gICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJzZWxlY3RlZEVsZW1lbnQoKSB8IGdldFZhbHVlQnlQYXRoIDogcHJvcC5rZXlcIlxuICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwic2V0VmFsdWVCeVBhdGgocHJvcC5rZXksICRldmVudClcIlxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwicHJvcC50eXBlID09PSAnYnV0dG9uLXRvZ2dsZSdcIiBjbGFzcz1cImJ1dHRvbi10b2dnbGUtd3JhcHBlclwiPlxuICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJ0b2dnbGUtYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwiZHVwbGljYXRlRmllbGQoc2VsZWN0ZWRFbGVtZW50KCkpXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIEFkZCBEdXBsaWNhdGVcbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L2Rpdj5cbiAgICB9XG4gIDwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJidXR0b24tY29udGFpbmVyXCIgKm5nSWY9XCIhdGVtcGxhdGVTZWxlY3RlZFwiPlxuICAgIDxidXR0b24gY2xhc3M9XCJjYW5jZWwtYnRuXCIgKGNsaWNrKT1cIm9uQ2FuY2VsKClcIj5DYW5jZWw8L2J1dHRvbj5cbiAgICA8YnV0dG9uIGNsYXNzPVwic2F2ZS1idG5cIiAoY2xpY2spPVwiaGFuZGxlQnV0dG9uQ2xpY2soKVwiPlNhdmU8L2J1dHRvbj5cbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cImJ1dHRvbi1jb250YWluZXJcIiAqbmdJZj1cInRlbXBsYXRlU2VsZWN0ZWRcIiBzdHlsZT1cIm1hcmdpbi10b3A6IDIwcHg7XCI+XG4gICAgPGJ1dHRvbiBjbGFzcz1cInNhdmUtYnRuXCIgKGNsaWNrKT1cImhhbmRsZVRlbXBsYXRlU2F2ZSgpXCI+U2F2ZSBUZW1wbGF0ZTwvYnV0dG9uPlxuICA8L2Rpdj5cbjwvZGl2PiJdfQ==