@rangertechnologies/ngnxt 2.1.243-beta → 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 (100) hide show
  1. package/esm2022/environments/version.mjs +15 -0
  2. package/esm2022/lib/ar.i18n.mjs +29 -0
  3. package/esm2022/lib/components/button/nxt-button.component.mjs +165 -0
  4. package/esm2022/lib/components/custom-calendar/custom-calendar.component.mjs +361 -0
  5. package/esm2022/lib/components/custom-dropdown/custom-dropdown.component.mjs +271 -0
  6. package/esm2022/lib/components/custom-model/custom-model.component.mjs +51 -0
  7. package/esm2022/lib/components/custom-radio/custom-radio.component.mjs +156 -0
  8. package/esm2022/lib/components/datatable/datatable.component.mjs +1754 -0
  9. package/esm2022/lib/components/file-upload/file-upload.component.mjs +283 -0
  10. package/esm2022/lib/components/icon-selector/icon-selector.component.mjs +104 -0
  11. package/esm2022/lib/components/image-cropper/component/cropper.state.mjs +208 -0
  12. package/esm2022/lib/components/image-cropper/component/image-cropper.component.mjs +562 -0
  13. package/esm2022/lib/components/image-cropper/interfaces/basic-event.interface.mjs +2 -0
  14. package/esm2022/lib/components/image-cropper/interfaces/cropper-options.interface.mjs +2 -0
  15. package/esm2022/lib/components/image-cropper/interfaces/cropper-position.interface.mjs +2 -0
  16. package/esm2022/lib/components/image-cropper/interfaces/dimensions.interface.mjs +2 -0
  17. package/esm2022/lib/components/image-cropper/interfaces/exif-transform.interface.mjs +2 -0
  18. package/esm2022/lib/components/image-cropper/interfaces/image-cropped-event.interface.mjs +2 -0
  19. package/esm2022/lib/components/image-cropper/interfaces/image-transform.interface.mjs +2 -0
  20. package/esm2022/lib/components/image-cropper/interfaces/index.mjs +2 -0
  21. package/esm2022/lib/components/image-cropper/interfaces/loaded-image.interface.mjs +2 -0
  22. package/esm2022/lib/components/image-cropper/interfaces/move-start.interface.mjs +8 -0
  23. package/esm2022/lib/components/image-cropper/services/crop.service.mjs +139 -0
  24. package/esm2022/lib/components/image-cropper/services/load-image.service.mjs +194 -0
  25. package/esm2022/lib/components/image-cropper/utils/cropper-position.utils.mjs +239 -0
  26. package/esm2022/lib/components/image-cropper/utils/exif.utils.mjs +79 -0
  27. package/esm2022/lib/components/image-cropper/utils/keyboard.utils.mjs +40 -0
  28. package/esm2022/lib/components/image-cropper/utils/percentage.utils.mjs +4 -0
  29. package/esm2022/lib/components/image-cropper/utils/resize.utils.mjs +75 -0
  30. package/esm2022/lib/components/list-view-filter/list-view-filter.component.mjs +401 -0
  31. package/esm2022/lib/components/nxt-input/nxt-input.component.mjs +2936 -0
  32. package/esm2022/lib/components/pagination/pagination.component.mjs +101 -0
  33. package/esm2022/lib/components/pick-location/pick-location.component.mjs +227 -0
  34. package/esm2022/lib/components/search-box/search-box.component.mjs +417 -0
  35. package/esm2022/lib/country.json +43237 -0
  36. package/esm2022/lib/en.i18n.mjs +29 -0
  37. package/esm2022/lib/i18n-config.service.mjs +4 -0
  38. package/esm2022/lib/i18n.component.mjs +45 -0
  39. package/esm2022/lib/i18n.module.mjs +38 -0
  40. package/esm2022/lib/i18n.pipe.mjs +26 -0
  41. package/esm2022/lib/i18n.service.mjs +56 -0
  42. package/esm2022/lib/interfaces/actionMeta.mjs +2 -0
  43. package/esm2022/lib/interfaces/apimeta.mjs +2 -0
  44. package/esm2022/lib/interfaces/dependencyMeta.mjs +2 -0
  45. package/esm2022/lib/model/bookletWrapper.mjs +9 -0
  46. package/esm2022/lib/model/changeWrapper.mjs +11 -0
  47. package/esm2022/lib/model/errorWrapper.mjs +6 -0
  48. package/esm2022/lib/nxt-app.component.mjs +22 -0
  49. package/esm2022/lib/nxt-app.module.mjs +139 -0
  50. package/esm2022/lib/nxt-app.service.mjs +14 -0
  51. package/esm2022/lib/pages/booklet/booklet.component.mjs +673 -0
  52. package/esm2022/lib/pages/builder/element/element.component.mjs +476 -0
  53. package/esm2022/lib/pages/builder/form/form.component.mjs +45 -0
  54. package/esm2022/lib/pages/builder/properties/common-fields.constants.mjs +89 -0
  55. package/esm2022/lib/pages/builder/properties/properties.component.mjs +944 -0
  56. package/esm2022/lib/pages/builder/templates/templates.component.mjs +34 -0
  57. package/esm2022/lib/pages/pdfDesigner/pdf-designer/pdf-designer.component.mjs +680 -0
  58. package/esm2022/lib/pages/pdfDesigner/pdf-properties/pdf-properties.component.mjs +1118 -0
  59. package/esm2022/lib/pages/questionbook/questionbook.component.mjs +838 -0
  60. package/esm2022/lib/pages/questionnaire/questionnaire.component.mjs +2237 -0
  61. package/esm2022/lib/pipe/custom-translate.pipe.mjs +27 -0
  62. package/esm2022/lib/pipe/date/date.pipe.mjs +28 -0
  63. package/esm2022/lib/pipe/editColumnCheck/edit-column-check.pipe.mjs +28 -0
  64. package/esm2022/lib/pipe/editColumnDropdown/edit-column-dropdown.pipe.mjs +20 -0
  65. package/esm2022/lib/pipe/editColumnType/edit-column-type.pipe.mjs +20 -0
  66. package/esm2022/lib/pipe/get-value.pipe.mjs +48 -0
  67. package/esm2022/lib/pipe/search-filter/search-filter.pipe.mjs +39 -0
  68. package/esm2022/lib/pipe/time/time.pipe.mjs +26 -0
  69. package/esm2022/lib/sample.mjs +3715 -0
  70. package/esm2022/lib/services/change.service.mjs +46 -0
  71. package/esm2022/lib/services/country.service.mjs +135 -0
  72. package/esm2022/lib/services/data.service.mjs +100 -0
  73. package/esm2022/lib/services/form-builder.service.mjs +385 -0
  74. package/esm2022/lib/services/pdf-designer.service.mjs +398 -0
  75. package/esm2022/lib/services/salesforce.service.mjs +41 -0
  76. package/esm2022/lib/services/shared.service.mjs +100 -0
  77. package/esm2022/lib/services/storage.service.mjs +43 -0
  78. package/esm2022/lib/services/template.service.mjs +351 -0
  79. package/esm2022/lib/services/translation.service.mjs +61 -0
  80. package/esm2022/lib/tam.i18n.mjs +29 -0
  81. package/esm2022/lib/wrapper.mjs +175 -0
  82. package/esm2022/public-api.mjs +25 -0
  83. package/esm2022/rangertechnologies-ngnxt.mjs +5 -0
  84. package/fesm2022/rangertechnologies-ngnxt.mjs +8783 -8878
  85. package/fesm2022/rangertechnologies-ngnxt.mjs.map +1 -1
  86. package/lib/components/custom-dropdown/custom-dropdown.component.d.ts +2 -1
  87. package/lib/components/datatable/datatable.component.d.ts +34 -28
  88. package/lib/components/file-upload/file-upload.component.d.ts +2 -1
  89. package/lib/components/image-cropper/component/image-cropper.component.d.ts +1 -1
  90. package/lib/components/nxt-input/nxt-input.component.d.ts +5 -1
  91. package/lib/components/pick-location/pick-location.component.d.ts +3 -1
  92. package/lib/components/search-box/search-box.component.d.ts +2 -1
  93. package/lib/pages/builder/element/element.component.d.ts +2 -15
  94. package/lib/pages/builder/properties/common-fields.constants.d.ts +4 -16
  95. package/lib/pages/builder/properties/properties.component.d.ts +95 -129
  96. package/lib/pipe/get-value.pipe.d.ts +1 -1
  97. package/lib/services/form-builder.service.d.ts +0 -1
  98. package/package.json +6 -4
  99. package/rangertechnologies-ngnxt-2.1.243.tgz +0 -0
  100. package/rangertechnologies-ngnxt-2.1.243-beta.tgz +0 -0
@@ -0,0 +1,476 @@
1
+ // AP 22JAN25 - form preview and All form elements
2
+ import { Component, EventEmitter, Input, Output, } from "@angular/core";
3
+ import { VERSION } from "../../../../environments/version";
4
+ import { CommonModule } from "@angular/common";
5
+ import { FormsModule } from "@angular/forms";
6
+ import { BookletComponent } from "../../booklet/booklet.component";
7
+ import { NxtDatatable } from "../../../components/datatable/datatable.component";
8
+ import * as i0 from "@angular/core";
9
+ import * as i1 from "../../../services/form-builder.service";
10
+ import * as i2 from "@angular/common";
11
+ import * as i3 from "@angular/forms";
12
+ export class ElementComponent {
13
+ formBuilderService;
14
+ bookletJSON;
15
+ bookletId;
16
+ templateMode = new EventEmitter();
17
+ field;
18
+ formElements = [];
19
+ elements = [];
20
+ bookId;
21
+ sections = {
22
+ basic: true, // Basic Elements open by default
23
+ advanced: true, // Advanced Elements closed by default
24
+ };
25
+ basicElements = [];
26
+ advancedElements = [];
27
+ //elementDisabledArray: any;
28
+ version = VERSION.version; //SKS10MAR25 get version from environment/version.ts
29
+ book;
30
+ selectedElement = null;
31
+ isSelectTablePopup = false;
32
+ currentType;
33
+ addTable = true;
34
+ dots = Array(6);
35
+ draggedIndex = null;
36
+ templateSelected = false;
37
+ isHeaderSelect = false;
38
+ selectedColumn;
39
+ constructor(formBuilderService) {
40
+ this.formBuilderService = formBuilderService;
41
+ }
42
+ // AP-06MAR25 Basic elements updated (RichTextArea, Date added)
43
+ ngOnInit() {
44
+ this.basicElements = [
45
+ { type: "Text", img: "Text", label: "Text" },
46
+ { type: "Number", img: "Number", label: "Number" },
47
+ { type: "Label", img: "Label", label: "Label" },
48
+ { type: "Email", img: "Email", label: "Email" },
49
+ { type: "Date", img: "Date", label: "Date" },
50
+ { type: "Time", img: "Time", label: "Time" },
51
+ { type: "DateTime", img: "DateTime", label: "DateTime" },
52
+ { type: "Calendar", img: "Calendar", label: "Calendar" },
53
+ { type: "File", img: "File", label: "Files" },
54
+ { type: "Image", img: "Image", label: "Image" },
55
+ { type: "Checkbox", img: "CheckBox", label: "Checkbox" },
56
+ { type: "Radio", img: "Radio", label: "Radio" },
57
+ { type: "Dropdown", img: "Drop", label: "Dropdown" },
58
+ { type: "TextArea", img: "TextArea", label: "Text Area" },
59
+ { type: "RichTextArea", img: "RichText", label: "Rich Text" },
60
+ ];
61
+ this.advancedElements = [
62
+ { type: "Icon", img: "Icon", label: "Icon" }, //MSM10JUL25 icon selector component
63
+ { type: "Line", img: "line", label: "Line" },
64
+ { type: "Space", img: "space", label: "Space" },
65
+ { type: "Boolean", img: "Boolean", label: "Boolean" },
66
+ { type: "Book", img: "Search", label: "Book" },
67
+ { type: "List", img: "Search", label: "List" },
68
+ { type: "Table", img: "Table", label: "Table" },
69
+ { type: "Button", img: "Button", label: "Button" },
70
+ ];
71
+ // this.elementDisabledArray = {
72
+ // Table: [
73
+ // 'Book', 'Calendar',"Boolean", 'List', 'Table', 'Checkbox', 'Radio',
74
+ // 'Dropdown', 'TextArea', 'RichTextArea', 'Number', 'Label', 'Image',
75
+ // 'Email', 'Date', 'Time', 'DateTime', 'Line', 'Space'
76
+ // ]
77
+ // };
78
+ this.formBuilderService.formElements$.subscribe((elements) => {
79
+ setTimeout(() => {
80
+ this.formElements = elements.map((field) => ({ ...field }));
81
+ }, 0);
82
+ });
83
+ if (this.bookletJSON && this.bookletJSON !== "") {
84
+ this.initializeForm();
85
+ }
86
+ else {
87
+ this.formBuilderService.newBook();
88
+ }
89
+ // AP-12MAR25 - Added to handle bookletId
90
+ if (this.bookletId) {
91
+ localStorage.setItem("unique_id", this.bookletId);
92
+ }
93
+ this.book = this.formBuilderService.getBook();
94
+ this.formBuilderService.selectedElement$.subscribe((index) => {
95
+ const elements = this.formBuilderService.getElements();
96
+ if (index >= 0) {
97
+ this.selectedElement = elements[index];
98
+ }
99
+ // SKS19MAR25 for fieldMeta checking
100
+ if (this.selectedElement?.type === "Table") {
101
+ this.selectedElement["fieldsMeta"] =
102
+ typeof this.selectedElement.fieldsMeta === "string"
103
+ ? this.selectedElement.fieldsMeta
104
+ : JSON.stringify(this.selectedElement["fieldsMeta"] || []);
105
+ }
106
+ // this.formElements = [...elements]
107
+ });
108
+ this.formBuilderService.addElementWithId();
109
+ }
110
+ // Add these methods
111
+ toggleSection(section) {
112
+ this.sections[section] = !this.sections[section];
113
+ }
114
+ isSectionOpen(section) {
115
+ return this.sections[section];
116
+ }
117
+ // AP - 26FEB25 - Added ngOnChanges to handle changes in bookletJSON
118
+ ngOnChanges(changes) {
119
+ if (changes["bookletJSON"] && changes["bookletJSON"].currentValue) {
120
+ if (this.bookletJSON && this.bookletJSON !== "") {
121
+ // AP-28MAY25 - Check and transform `action` if it's in Existing format
122
+ if (this.bookletJSON.questionbook &&
123
+ this.bookletJSON.questionbook.action &&
124
+ typeof this.bookletJSON.questionbook.action === "string") {
125
+ try {
126
+ const parsedActions = JSON.parse(this.bookletJSON.questionbook.action);
127
+ // AP-28MAY25 Assign specific positionPercent based on action name
128
+ const newActions = parsedActions.map((item, index) => {
129
+ const positionPercent = item.name === "Cancel"
130
+ ? 3
131
+ : item.name === "Save"
132
+ ? 14
133
+ : 10 + index * 10;
134
+ return {
135
+ ...item,
136
+ positionPercent: positionPercent,
137
+ width: 100,
138
+ textColor: "#ffffff",
139
+ borderRadius: 6,
140
+ id: index + 1,
141
+ };
142
+ });
143
+ // AP-28MAY25 Replace the old action string with the newly formatted array
144
+ this.bookletJSON.questionbook.action = newActions;
145
+ }
146
+ catch (e) {
147
+ console.error("Error parsing action JSON string:", e);
148
+ }
149
+ }
150
+ this.initializeForm();
151
+ }
152
+ else {
153
+ this.formBuilderService.newBook();
154
+ }
155
+ }
156
+ }
157
+ // AP-08APR25 Template is selected, update form elements and emit template mode
158
+ onTemplateSelected(event) {
159
+ this.formBuilderService.clearElements();
160
+ event.elements.forEach((el) => this.formBuilderService.addElement(el));
161
+ // Emit template mode to parent
162
+ this.templateMode.emit(true);
163
+ }
164
+ initializeForm() {
165
+ if (!this.bookletJSON || !this.bookletJSON.bookQuestionsMap) {
166
+ console.warn("Invalid bookletJSON structure");
167
+ return;
168
+ }
169
+ this.formElements = [];
170
+ this.formBuilderService.clearElements();
171
+ this.formBuilderService.intializeBook(this.bookletJSON);
172
+ const bookQuestionsMap = this.bookletJSON.bookQuestionsMap;
173
+ const bookQuestionsMapKeys = Object.keys(bookQuestionsMap);
174
+ if (bookQuestionsMapKeys.length === 0)
175
+ return;
176
+ for (const key of bookQuestionsMapKeys) {
177
+ const subQuestions = bookQuestionsMap[key]?.subQuestions;
178
+ if (Array.isArray(subQuestions)) {
179
+ subQuestions.forEach((subQuestion) => {
180
+ // AP-04APR24 If subQuestion.style exists as a string and is empty, replace it with a default style object
181
+ if (typeof subQuestion.style === "string" &&
182
+ subQuestion.style.trim() === "") {
183
+ subQuestion.style = {
184
+ labelClass: null,
185
+ labelStyle: null,
186
+ labelValueStyle: null,
187
+ inputClass: null,
188
+ inputStyle: null,
189
+ showLabel: true,
190
+ bookStyle: null,
191
+ direction: "ltr",
192
+ questionStyle: null,
193
+ };
194
+ }
195
+ });
196
+ }
197
+ }
198
+ this.formElements = this.formBuilderService.getElements();
199
+ }
200
+ // Add this method to handle element selection
201
+ selectElement(index) {
202
+ this.isHeaderSelect = false;
203
+ this.selectedColumn = null;
204
+ this.selectedFieldIndex = index; // element is selected
205
+ this.formBuilderService.setSelectedElement(index);
206
+ this.book = this.formBuilderService.getBook();
207
+ }
208
+ selectedFieldIndex = null; // element is cleared
209
+ selectHeading(event) {
210
+ this.isHeaderSelect = true;
211
+ this.selectedFieldIndex = null;
212
+ this.selectedColumn = null;
213
+ this.formBuilderService.selectHeading(event); //AP-10MAR25 Updates the selected heading in the service
214
+ this.book = this.formBuilderService.getBook(); //AP-10MAR25 Retrieves the updated book/form data
215
+ }
216
+ // AP-17APR25 generateUiId
217
+ generateUiId() {
218
+ return this.formBuilderService.addElementWithId();
219
+ }
220
+ addElement(type) {
221
+ const unique_id = this.generateUiId();
222
+ this.currentType = type;
223
+ if (this.selectedElement?.type === "Table" && this.addTable) {
224
+ this.isSelectTablePopup = true;
225
+ }
226
+ else {
227
+ const newElement = {
228
+ action: null,
229
+ id: unique_id,
230
+ type,
231
+ name: null,
232
+ questionText: null,
233
+ question: null,
234
+ helpText: null,
235
+ errorMessage: null,
236
+ isReadOnly: false,
237
+ isHidden: false,
238
+ required: false,
239
+ referenceField: null,
240
+ additionalRichContent: null,
241
+ groupName: null,
242
+ isDateBackward: false,
243
+ title: null,
244
+ subTitle: null,
245
+ size: 12,
246
+ isDateForward: false,
247
+ isOptional: false,
248
+ isTitle: false,
249
+ nextQuestion: null,
250
+ allowedFileExtensions: null,
251
+ questionNumber: this.formBuilderService.getElements().length + 1,
252
+ order: this.formElements.length + 1,
253
+ questionBookId: this.bookletId,
254
+ fieldsMeta: [],
255
+ trackingId: null,
256
+ recordId: null,
257
+ qbReference: null,
258
+ qbReferenceQuestions: null,
259
+ primaryKey: false,
260
+ style: {
261
+ labelClass: null,
262
+ labelStyle: null,
263
+ labelValueStyle: null,
264
+ inputClass: null,
265
+ inputStyle: null,
266
+ showLabel: true,
267
+ bookStyle: null,
268
+ direction: "ltr",
269
+ questionStyle: null,
270
+ },
271
+ subText: {
272
+ endpoint: null,
273
+ variable: null,
274
+ field: null,
275
+ defaultField: null,
276
+ sourceQuestionId: null,
277
+ valueField: null,
278
+ labelField: null,
279
+ isDependentField: false,
280
+ dependentValue: null,
281
+ queryField: null,
282
+ queryValue: null,
283
+ queryValueReference: null,
284
+ uniqueKey: null,
285
+ },
286
+ imageData: null,
287
+ boolean: false,
288
+ options: type === "Dropdown" || type === "TableColumn" || type === "Radio" || type === "Checkbox"
289
+ ? []
290
+ : null,
291
+ imageSize: type === "Image" ? { width: 150, height: 150 } : null,
292
+ tableConfig: type === "Table"
293
+ ? {
294
+ isNosIndicator: true,
295
+ addInlineRecord: true,
296
+ isPagination: true,
297
+ actionButton: true,
298
+ isDeleteRow: true,
299
+ isEditRow: true,
300
+ searchBar: true,
301
+ isButtons: true,
302
+ itemsPerPage: 10,
303
+ }
304
+ : null,
305
+ };
306
+ this.formBuilderService.addElement(newElement);
307
+ this.formElements = this.formBuilderService.getElements();
308
+ // SKS19MAR25 fieldsmeta check
309
+ this.formElements = this.updateTableFieldsMeta(this.formElements);
310
+ this.addTable = true;
311
+ }
312
+ }
313
+ // Remove an element by index
314
+ removeElement(field, index) {
315
+ this.formBuilderService.removeElementComponent(field.id);
316
+ this.formElements = this.formBuilderService.getElements();
317
+ // SKS19MAR25 fieldsmeta check
318
+ this.formElements = this.updateTableFieldsMeta(this.formElements);
319
+ }
320
+ onDragStart(event, index) {
321
+ this.draggedIndex = index;
322
+ event.dataTransfer?.setData("text/plain", index.toString());
323
+ }
324
+ // Allow dropping by preventing default
325
+ onDragOver(event, index) {
326
+ event.preventDefault();
327
+ }
328
+ // Handle drop event
329
+ onDrop(event, dropIndex) {
330
+ event.preventDefault();
331
+ if (this.draggedIndex === null || this.draggedIndex === dropIndex)
332
+ return;
333
+ const draggedItem = this.formElements[this.draggedIndex];
334
+ // Remove dragged item from old position and insert it in new position
335
+ this.formElements.splice(this.draggedIndex, 1);
336
+ this.formElements.splice(dropIndex, 0, draggedItem);
337
+ //AP-28MAR25 Update questionNumber dynamically based on new order
338
+ this.formElements.forEach((element, index) => {
339
+ element.questionNumber = index + 1;
340
+ });
341
+ // Reset dragged index
342
+ this.draggedIndex = null;
343
+ // Notify service about the update
344
+ this.formBuilderService.updateElementsOrder(this.formElements);
345
+ }
346
+ toggleBoolean(field) {
347
+ field.boolean = !field.boolean;
348
+ }
349
+ getBaseStyles(field, includeBorderStyle = false) {
350
+ const styles = {
351
+ "font-family": field?.font || "Helvetica Neue",
352
+ "font-weight": field?.fontWeight || "400",
353
+ "font-size": field?.fontSize || "14px",
354
+ "width": field?.size ? `${(field.size / 12) * 100}%` : "100%",
355
+ "text-align": field?.textAlign || "left",
356
+ "border-radius": "5px",
357
+ "border-width": field?.lineWidth ? `${field.lineWidth}px` : "1px",
358
+ "color": field?.fontColor || "#000000",
359
+ "margin-top": field?.paddingTop ? `${field.paddingTop}px` : "0px",
360
+ "margin-bottom": field?.paddingBottom ? `${field.paddingBottom}px` : "10px",
361
+ "border-color": field?.color || "#EFF8FF",
362
+ };
363
+ if (includeBorderStyle) {
364
+ styles["border-style"] = field?.lineStyle?.toLowerCase() || "solid";
365
+ }
366
+ return styles;
367
+ }
368
+ getFontStyles(field) {
369
+ return this.getBaseStyles(field, false);
370
+ }
371
+ getLineStyles(field) {
372
+ return this.getBaseStyles(field, true);
373
+ }
374
+ // SKS13MAR25 table popup conformation based element add
375
+ onClose() {
376
+ this.isSelectTablePopup = false;
377
+ this.addTable = false;
378
+ this.addElement(this.currentType);
379
+ }
380
+ // SKS13MAR25 column element add inside a table
381
+ addOnTable() {
382
+ this.addTable = true;
383
+ this.isSelectTablePopup = false;
384
+ const elements = [...this.formBuilderService.getElements()];
385
+ // Find the element and update its columns
386
+ const index = elements.findIndex((el) => el.id === this.selectedElement.id);
387
+ const rowNum = this.formElements[index].fieldsMeta
388
+ ? this.formElements[index].fieldsMeta?.length
389
+ : 0;
390
+ const unique_id = this.generateUiId();
391
+ const tableElement = {
392
+ label: `HEADER LABEL ${rowNum}`,
393
+ fieldName: `FIELD NAME ${rowNum}`,
394
+ type: this.currentType,
395
+ id: unique_id,
396
+ };
397
+ this.formBuilderService.addTableElement(tableElement, this.selectedFieldIndex);
398
+ this.formElements = this.formBuilderService.getElements();
399
+ // SKS19MAR25 fieldsmeta checking
400
+ this.formElements = this.updateTableFieldsMeta(this.formElements);
401
+ }
402
+ updateTableFieldsMeta(elements) {
403
+ return elements.map((ele) => {
404
+ if (ele.type === "Table") {
405
+ ele.fieldsMeta =
406
+ typeof ele.fieldsMeta === "string"
407
+ ? ele.fieldsMeta
408
+ : JSON.stringify(ele.fieldsMeta || []);
409
+ }
410
+ return ele;
411
+ });
412
+ }
413
+ columnSelected(event) {
414
+ // SKS19MAR25 table column update
415
+ this.formElements.forEach((ele, index) => {
416
+ if (ele.type === 'Table' && Array.isArray(ele.fieldsMeta)) {
417
+ const matchedField = ele.fieldsMeta.find((field) => field.uniqueIdentifier === event?.uniqueIdentifier);
418
+ if (matchedField) {
419
+ this.formBuilderService.setSelectedElement(index);
420
+ this.selectedFieldIndex = index;
421
+ }
422
+ }
423
+ });
424
+ this.formBuilderService.setSelectedTableElement(this.selectedFieldIndex, event);
425
+ this.selectedColumn = event?.uniqueIdentifier;
426
+ }
427
+ removeColumn(event) {
428
+ this.formBuilderService.removeSelectedTableElement(this.selectedFieldIndex, event);
429
+ this.selectedColumn = null;
430
+ }
431
+ // SKS25MAR25 image add
432
+ async fileChangeEvent(index, event) {
433
+ const file = event.target.files[0];
434
+ if (file) {
435
+ try {
436
+ const imageData = await this.readFileAsDataURL(file);
437
+ this.formElements[index].imageData = imageData;
438
+ this.formElements[index].orgImageData = imageData;
439
+ // Initialize logo size if not already set
440
+ if (!this.formElements[index].imageSize) {
441
+ this.formElements[index].imageSize = { width: 150, height: 150 };
442
+ }
443
+ await this.formBuilderService.elementUpdate(index, this.formElements[index]);
444
+ }
445
+ catch (error) {
446
+ console.error("Error reading file:", error);
447
+ }
448
+ }
449
+ }
450
+ readFileAsDataURL(file) {
451
+ return new Promise((resolve, reject) => {
452
+ const reader = new FileReader();
453
+ reader.onload = () => resolve(reader.result);
454
+ reader.onerror = (error) => reject(error);
455
+ reader.readAsDataURL(file);
456
+ });
457
+ }
458
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ElementComponent, deps: [{ token: i1.FormBuilderService }], target: i0.ɵɵFactoryTarget.Component });
459
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ElementComponent, isStandalone: true, selector: "app-element", inputs: { bookletJSON: "bookletJSON", bookletId: "bookletId" }, outputs: { templateMode: "templateMode" }, usesOnChanges: true, ngImport: i0, template: "<!-- AP 22JAN25 - form preview and All form elements -->\n<!-- AP 25FEB25 - All elements update -->\n<div class=\"center-frame\">\n <!-- Form Builder Section All Elements -->\n <div class=\"form-builder\">\n <!-- Basic Elements Toggle -->\n <div class=\"toggle-header\" (click)=\"toggleSection('basic')\">\n <div class=\"head-elements\">Basic Elements</div>\n <img [src]=\"sections.basic ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\"\n alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n\n <div *ngIf=\"sections.basic\">\n <ng-container *ngFor=\"let element of basicElements\">\n <div class=\"element\" (click)=\"addElement(element.type)\">\n <img src=\"../assets/icons/{{ element.img }}.svg\" class=\"element-icon\">\n <div class=\"hover-label\">{{ element.label }}</div>\n <div class=\"drag-dots\">\n <div class=\"dot\" *ngFor=\"let dot of dots\"></div>\n </div>\n </div>\n </ng-container>\n </div>\n\n <!-- Advanced Elements Toggle -->\n <div class=\"toggle-header\" (click)=\"toggleSection('advanced')\">\n <div class=\"head-elements\">Advanced Elements</div>\n <img [src]=\"sections.advanced ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\"\n alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n\n <div *ngIf=\"sections.advanced\">\n <ng-container *ngFor=\"let element of advancedElements\">\n <div class=\"element\" (click)=\"addElement(element.type)\">\n <img src=\"../assets/icons/{{ element.img }}.svg\">\n <div class=\"hover-label\">{{ element.label }}</div>\n <div class=\"drag-dots\">\n <div class=\"dot\" *ngFor=\"let dot of dots\"></div>\n </div>\n </div>\n </ng-container>\n </div>\n <!-- AP-08APR25 Add Templates Component -->\n <!-- <app-templates (templateSelected)=\"onTemplateSelected($event)\"></app-templates> -->\n\n <!-- SKS10MAR25 footer version show -->\n <div class=\"sticky-footer-version\">\n {{version}}\n </div>\n </div>\n <!-- AP-27MAR25 Remove CDK drag and drop replace draggable function -->\n <div class=\"form-preview\">\n <!-- AP-10MAR25 Heading -->\n <div class=\"field-container\"\n style=\"width: 100%;background-color: #EFF8FF; border: 1px solid #E6F3FF;display: flex;justify-content: center;margin-bottom:10px\"\n [class.highlight]=\"isHeaderSelect\"\n (click)=\"selectHeading('Header')\">\n <div class=\"label-container\" style=\"padding: 10px;\">\n <div *ngIf=\"book?.records\">\n <div *ngIf=\"book.records[0].title == ''\" style=\"color:#3f4a525c\">Heading</div>\n <div *ngIf=\"book.records[0].title !== ''\">{{book.records[0].title}}</div>\n </div>\n </div> \n </div>\n\n <ng-container *ngFor=\"let field of formElements; let i = index\" getProperties().elementProps>\n\n <!-- TextBox -->\n <div *ngIf=\"field.type === 'Text'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Label' }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"text\" class=\"custom-input\" [placeholder]=\"field.question || 'Enter text'\"\n [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : '' \" />\n </div>\n </div>\n </div>\n\n <!-- MSM-09JUL25 Icon-selectir Element -->\n <div *ngIf=\"field.type === 'Icon'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isRequired\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Choose Icon'\n }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div class=\"choose-icon-placeholder\">\n </div>\n </div>\n </div>\n </div>\n\n <!-- AP-19MAR25 Line Element -->\n <div *ngIf=\"field.type === 'Line'\" class=\"line-field\" (click)=\"selectElement(i)\"\n [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"line-element\">\n <div></div>\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n <hr class=\"custom-line\" style=\"display: inline-flex\" [ngStyle]=\"getLineStyles(field)\" />\n </div>\n\n <!--SKS25MAR25 Image Upload Element -->\n <div *ngIf=\"field.type === 'Image'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\" [ngStyle]=\"getFontStyles(field)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Upload Image' }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div>\n <div class=\"logo-container\">\n <!-- Logo preview area -->\n <div class=\"logo-preview\" *ngIf=\"field.imageData\">\n <img [src]=\"field.imageData\" />\n </div>\n\n <!-- Upload button -->\n <div *ngIf=\"!field.imageData\" class=\"logo-upload-placeholder\">\n <label for=\"logo-upload-{{i}}\" class=\"logo-upload-label\">\n <img src=\"../assets/icons/Image.svg\" alt=\"Upload\" />\n <span>Upload Image</span>\n </label>\n <input type=\"file\" id=\"logo-upload-{{i}}\" accept=\"image/*\" (change)=\"fileChangeEvent(i, $event)\"\n style=\"display: none;\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Space Element -->\n <div *ngIf=\"field.type === 'Space'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" style=\"height:93px\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <label [class.required]=\"field.isOptional\"></label>\n <div class=\"top-right\" style=\"margin: -11px -11px 0 0;\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Boolean Element -->\n <div *ngIf=\"field.type === 'Boolean'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{ field.questionText\n ? field.questionText : 'Boolean'}}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"checkbox\" [checked]=\"field.boolean\" (change)=\"toggleBoolean(field)\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n\n <!-- Calendar -->\n <div *ngIf=\"field.type === 'Calendar'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Select Date'\n }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n\n </div>\n <input type=\"date\" class=\"custom-input\" [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n </div>\n\n <!-- AP -12MAR25 Date -->\n <div *ngIf=\"field.type === 'Date'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Select Date'\n }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n\n </div>\n <input type=\"date\" class=\"custom-input\" [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n </div>\n\n <!-- AP-21MAR25 Add Time element -->\n <!-- Time Field -->\n <div *ngIf=\"field.type === 'Time'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <label [class.required]=\"field.isOptional\">{{ field.questionText ? field.questionText : 'Time' }}</label>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"time\" class=\"custom-input\" [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n </div>\n\n <!-- AP-28MAR25 DateTime -->\n <div *ngIf=\"field.type === 'DateTime'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Select Date & Time'\n }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"datetime-local\" class=\"custom-input\" [readonly]=\"field.isReadOnly\"\n [class.hidden]=\"field.isHidden\" />\n </div>\n </div>\n </div>\n\n <!-- Email -->\n <div *ngIf=\"field.type === 'Email'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\"> {{ field.questionText ? field.questionText : 'Label' }}\n </label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"email\" class=\"custom-input\" [placeholder]=\"field.question || 'Enter email'\"\n [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n </div>\n\n <!-- Numbers -->\n <div *ngIf=\"field.type === 'Number'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Label' }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"number\" class=\"custom-input\" [placeholder]=\"field.question || 'Enter number'\"\n [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n </div>\n\n <!-- TextArea -->\n <div *ngIf=\"field.type === 'TextArea'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Enter your text'}}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <textarea class=\"custom-textarea\" [placeholder]=\"field.question || 'Enter detailed text here...'\"\n [style.height.px]=\"field.size || 100\" [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\"></textarea>\n </div>\n </div>\n </div>\n\n <!-- RichText -->\n <div *ngIf=\"field.type === 'RichTextArea'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Enter your text'}}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <textarea class=\"custom-textarea\" [placeholder]=\"field.question || 'Enter detailed text here...'\"\n [style.height.px]=\"field.size || 100\" [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\"></textarea>\n </div>\n </div>\n </div>\n\n <!-- Label -->\n <div *ngIf=\"field.type === 'Label'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Label' }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Book -->\n <div *ngIf=\"field.type === 'Book'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Label' }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <lib-booklet [bookletJSON]=\"field.qbReferenceQuestions\"></lib-booklet>\n </div>\n </div>\n </div>\n\n <!-- File -->\n <div *ngIf=\"field.type === 'File'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Upload File'\n }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"file\" class=\"custom-input\" [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\" />\n </div>\n </div>\n </div>\n\n <!-- CheckBox -->\n <div *ngIf=\"field.type === 'Checkbox'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">\n {{ field.questionText ? field.questionText : 'Label' }}\n </label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n\n <div class=\"checkbox-options-container\">\n <div *ngFor=\"let option of field.options\" class=\"checkbox-option\">\n <input type=\"checkbox\" [id]=\"option.value + i\" [name]=\"field.id\"\n [value]=\"option.value || field.defaultValue\" class=\"checkbox-input\" [disabled]=\"field.isReadOnly\"\n [class.hidden]=\"field.isHidden\">\n <label [for]=\"option.value + i\" class=\"checkbox-label\">{{ option.value }}</label>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Radio -->\n <div *ngIf=\"field.type === 'Radio'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Label' }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div class=\"radio-options-container\">\n <div *ngFor=\"let option of field.options; let j = index\" class=\"radio-option\">\n <input type=\"radio\" [id]=\"'radio-' + field.id + '-' + j\" [name]=\"'radio-group-' + field.id\"\n [value]=\"option.value || field.defaultValue\" [(ngModel)]=\"field.selectedValue\" class=\"radio-input\"\n [disabled]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\">\n <label [for]=\"'radio-' + field.id + '-' + j\" class=\"radio-label\"> {{ option.value }}</label>\n </div>\n </div>\n </div>\n </div>\n </div>\n <!-- Dropdown -->\n <div *ngIf=\"field.type === 'Dropdown'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Label' }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <select id=\"options\" class=\"dropdown\" [disabled]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\">\n <option *ngFor=\"let option of field.options\" [value]=\"option.value || field.defaultValue\"> {{ option.value\n }} </option>\n </select>\n </div>\n </div>\n </div>\n\n <!-- Table -->\n <!-- AP-06MAR25 -->\n <div *ngIf=\"field.type === 'Table'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" style=\"overflow: hidden;\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Label' }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div class=\"nxt-table-container\">\n <nxt-datatable isButtons [question]=\"field\" from=\"formBuilder\" [mode]=\"'edit'\" [apiMeta]=\"field.subText\"\n [tableConfig]=\"field.tableConfig\" tableId=\"\" direction=\"ltr\" tableWidth=\"auto\" isEditable=true [selectedColumn]=\"selectedColumn\"\n (columnSelected)=columnSelected($event) (removeColumn)=removeColumn($event)>\n </nxt-datatable>\n </div>\n </div>\n </div>\n </div>\n\n <!-- List -->\n <!-- AP-06MAR25 - List data show-->\n <div *ngIf=\"field.type === 'List'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Label' }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"text\" class=\"custom-input\" placeholder=\"Search...\" [readonly]=\"field.isReadOnly\"\n [class.hidden]=\"field.isHidden\" [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n </div>\n\n </ng-container>\n </div>\n</div>\n<!-- SKS13MAR25 popup conformation box -->\n<div class=\"dialog-overlay\" *ngIf=\"isSelectTablePopup\">\n <div class=\"dialog-box\">\n <button class=\"close-btn-fb\" (click)=\"onClose()\">\u2715</button>\n <p>These element want to add a table</p>\n <div class=\"button-container-fb\">\n <button class=\"yes-btn-fb\" (click)=\"addOnTable()\">Yes</button>\n <button class=\"no-btn-fb\" (click)=\"onClose()\">No</button>\n </div>\n </div>\n</div>", styles: [".center-frame{display:flex;border-right-width:0}.head-elements{font-size:17px;font-weight:600}.form-builder{width:33.33%;height:calc(100vh - 20px);overflow-y:auto;background-color:#fff;padding:10px;border-right:10px solid #86A8CD;box-shadow:2px 2px 10px #0000001a}.form-builder .element{display:flex;align-items:center;gap:15px;margin-top:10px;padding:10px;border-radius:5px;background:#f8fafc;cursor:pointer;border-left:10px solid #E2F1FF;position:relative;color:#000}.form-builder .element:hover{background:#0250d9;color:#fff;border-left:10px solid #234465}.form-builder .element:hover img{filter:invert(1)}.form-builder .element:hover .hover-label{color:#fff}.form-builder .element:hover .dot{background-color:#ffffffb3}.form-builder .element .drag-dots:active{cursor:grabbing}.form-builder .element img{width:20px;height:20px;transition:filter .3s ease}.form-builder .hover-label{font-size:15px;font-weight:400;color:#000;transition:color .3s ease}.form-builder .section-title{font-weight:700;font-size:16px;margin-top:10px;padding:5px;border-bottom:1px solid #ddd;color:#000;display:flex;justify-content:space-between;align-items:center}.form-builder .section-title:after{content:\"\\25bc\";font-size:12px;color:#555}.form-builder .section{margin-bottom:10px}.toggle-header{display:flex;align-items:center;justify-content:space-between;cursor:pointer;padding:10px}.arrow-icon{width:19px;height:23px;transition:transform .3s ease}.toggle-header:hover .arrow-icon{transform:scale(1.1)}.drag-dots{display:grid;grid-template-columns:repeat(2,1fr);grid-template-rows:repeat(3,1fr);gap:3px;position:absolute;right:15px;top:50%;transform:translateY(-50%)}.dot{width:5px;height:5px;border-radius:50%;background-color:#cbd5e1;transition:background-color .3s ease}.drag-dot{height:13px}.field-wrapper,.line-field{background-color:#eff8ff;border:1px solid #E6F3FF;border-radius:5px;padding:10px}.line-field{width:100%;margin:10px 0;padding:3px}.field-container{padding:0 5px;transition:background .2s}.field-container:hover .top-right,.field-container.highlight .top-right{opacity:1;visibility:visible}.field-content{display:flex;flex-direction:column;gap:5px}.label-container{display:flex;justify-content:space-between;align-items:center}.label-container:hover .delete-icon{opacity:1;visibility:visible}.label-container label{font-size:15px;font-weight:400}.top-right{display:flex;gap:10px;padding:6px;border:1px solid #d7edff;margin:-10px -10px 0 0;background-color:#d7edff;opacity:0;visibility:hidden;cursor:grab;transition:opacity .1s,visibility .1s}.custom-input,.custom-textarea,.dropdown{width:100%;padding:8px;border:1px solid #ccc;background-color:#fff;border-radius:5px;outline:none}.custom-input{border-color:#dddbda}.custom-input:focus{border-color:#00008b;box-shadow:0 0 5px #0000ff80}.custom-textarea{min-height:100px;resize:vertical}.dropdown{font-size:14px;color:#333;cursor:pointer}.dropdown:focus{border-color:#007bff;box-shadow:0 0 5px #007bff80}.checkbox-options-container,.radio-options-container{display:flex;flex-direction:column;gap:5px;padding:8px;min-height:38px;border:1px solid #DDDBDA;background-color:#fff;border-radius:6px;outline:none;width:100%}.checkbox-option,.radio-option{display:flex;align-items:center;gap:8px;padding:8px;background-color:#fff;border-radius:4px;transition:background-color .2s ease}.checkbox-option:hover{background-color:#f1f3f5}.checkbox-input,.radio-input{width:18px;height:18px;accent-color:#4dabf7;cursor:pointer}.checkbox-label,.radio-label{font-size:14px;color:#495057;cursor:pointer;-webkit-user-select:none;user-select:none}.radio-input:checked{border-color:#007bff;background-color:#007bff}.radio-input:checked:after{content:\"\";width:8px;height:8px;background:#fff;border-radius:50%;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.form-preview{width:100%;height:fit-content;max-height:calc(100vh - 20px);overflow-y:auto;display:flex;flex-wrap:wrap;align-items:flex-start;padding:10px}.required:after{content:\" *\";color:red;margin-left:5px}.highlight{border:2px solid #5592FD!important;background-color:#eff8ff}.delete-icon{width:19px;height:19px;margin-top:-5px}.element.disabled{opacity:.5;cursor:not-allowed}.table-container label{font-size:14px;font-weight:700;margin-bottom:5px;display:block}.nxt-table-container{display:flex;justify-content:center;align-items:center;width:100%}nxt-datatable{width:100%!important;table-layout:fixed;max-width:100%}.dialog-overlay{position:fixed;inset:0;background:#00000080;display:flex;justify-content:center;align-items:center;z-index:1000}.dialog-box{background:#fff;padding:20px;border-radius:5px;text-align:center;width:300px;position:relative}.close-btn-fb{position:absolute;top:4px;right:4px;background:#ff4242;color:#fff;border:none;border-radius:50%;width:20px;height:20px;font-size:10px;cursor:pointer}.button-container-fb{display:flex;justify-content:flex-end;gap:10px}.yes-btn-fb{background:green;color:#fff;border:none;padding:0 12px;border-radius:5px;cursor:pointer}.no-btn-fb{background:gray;color:#fff;border:none;padding:8px 15px;border-radius:5px;cursor:pointer}.line-element{width:100%;display:flex;justify-content:space-between;align-items:center}.custom-line{width:100%;border:1px solid #000}.logo-container{display:flex;flex-direction:column;padding:10px;border:1px dashed #ccc;border-radius:5px;background-color:#f9f9f9}.logo-preview{position:relative;border:1px solid #e0e0e0;background-color:#fff;overflow:hidden}.logo-upload-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;width:150px;height:150px;border:2px dashed #ccc;cursor:pointer}.logo-upload-label{display:flex;flex-direction:column;align-items:center;cursor:pointer;color:#666}.logo-upload-label img{width:32px;height:32px;margin-bottom:8px}.sticky-footer-version{position:fixed;bottom:0;padding:10px;text-align:center}.choose-icon-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;width:48px;height:150px;border:2px dashed #ccc;cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.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: i3.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: BookletComponent, selector: "lib-booklet", inputs: ["bookletId", "serv", "tkn", "bookletJSON", "allIcons", "themeColor", "cdnIconURL", "dropdownDependentData", "labelValue", "token", "languageCode", "fieldRestrictions", "from", "apiUrl", "isEdit", "dataBind"], outputs: ["handleBookletActionEvent", "handlePage", "hadleDropDownDependent", "handleCalendarDate", "handleCalendarEvent"] }, { kind: "component", type: NxtDatatable, selector: "nxt-datatable", inputs: ["data", "tableFilterData", "columns", "withCheckBox", "searchBar", "tableSaveButton", "stickyColumn", "tableWidth", "actionColumHeader", "actionButton", "title", "isButtons", "buttonArray", "tableId", "isEditRow", "isDeleteRow", "addInlineRecord", "searchConfigs", "direction", "pagination", "actionButtonArray", "multipleFilter", "isPagination", "isNosIndicator", "isEditable", "from", "question", "rowTextSize", "rowTextColor", "apiMeta", "summaryRows", "summaryColumns", "isLoading", "tableConfig", "tableParams", "listViews", "mode", "languageCode", "selectedColumn", "allIcons"], outputs: ["tableRowClick", "onEditData", "saveButtonData", "onDeleteData", "buttonEmit", "hyperLinkEmit", "sideNavEmit", "actionButtonEmit", "columnSelected", "removeColumn", "valueChange", "selectedValues", "fileEmit", "NxtTableParamsEmit", "NxtTableFilterEmit", "hadleDropDownDependent", "NxtTableEmit"] }] });
460
+ }
461
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ElementComponent, decorators: [{
462
+ type: Component,
463
+ args: [{ selector: "app-element", standalone: true, imports: [
464
+ CommonModule,
465
+ FormsModule,
466
+ BookletComponent,
467
+ NxtDatatable
468
+ ], template: "<!-- AP 22JAN25 - form preview and All form elements -->\n<!-- AP 25FEB25 - All elements update -->\n<div class=\"center-frame\">\n <!-- Form Builder Section All Elements -->\n <div class=\"form-builder\">\n <!-- Basic Elements Toggle -->\n <div class=\"toggle-header\" (click)=\"toggleSection('basic')\">\n <div class=\"head-elements\">Basic Elements</div>\n <img [src]=\"sections.basic ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\"\n alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n\n <div *ngIf=\"sections.basic\">\n <ng-container *ngFor=\"let element of basicElements\">\n <div class=\"element\" (click)=\"addElement(element.type)\">\n <img src=\"../assets/icons/{{ element.img }}.svg\" class=\"element-icon\">\n <div class=\"hover-label\">{{ element.label }}</div>\n <div class=\"drag-dots\">\n <div class=\"dot\" *ngFor=\"let dot of dots\"></div>\n </div>\n </div>\n </ng-container>\n </div>\n\n <!-- Advanced Elements Toggle -->\n <div class=\"toggle-header\" (click)=\"toggleSection('advanced')\">\n <div class=\"head-elements\">Advanced Elements</div>\n <img [src]=\"sections.advanced ? '../assets/icons/arrow-down.svg' : '../assets/icons/arrow-right.svg'\"\n alt=\"Toggle Arrow\" class=\"arrow-icon\">\n </div>\n\n <div *ngIf=\"sections.advanced\">\n <ng-container *ngFor=\"let element of advancedElements\">\n <div class=\"element\" (click)=\"addElement(element.type)\">\n <img src=\"../assets/icons/{{ element.img }}.svg\">\n <div class=\"hover-label\">{{ element.label }}</div>\n <div class=\"drag-dots\">\n <div class=\"dot\" *ngFor=\"let dot of dots\"></div>\n </div>\n </div>\n </ng-container>\n </div>\n <!-- AP-08APR25 Add Templates Component -->\n <!-- <app-templates (templateSelected)=\"onTemplateSelected($event)\"></app-templates> -->\n\n <!-- SKS10MAR25 footer version show -->\n <div class=\"sticky-footer-version\">\n {{version}}\n </div>\n </div>\n <!-- AP-27MAR25 Remove CDK drag and drop replace draggable function -->\n <div class=\"form-preview\">\n <!-- AP-10MAR25 Heading -->\n <div class=\"field-container\"\n style=\"width: 100%;background-color: #EFF8FF; border: 1px solid #E6F3FF;display: flex;justify-content: center;margin-bottom:10px\"\n [class.highlight]=\"isHeaderSelect\"\n (click)=\"selectHeading('Header')\">\n <div class=\"label-container\" style=\"padding: 10px;\">\n <div *ngIf=\"book?.records\">\n <div *ngIf=\"book.records[0].title == ''\" style=\"color:#3f4a525c\">Heading</div>\n <div *ngIf=\"book.records[0].title !== ''\">{{book.records[0].title}}</div>\n </div>\n </div> \n </div>\n\n <ng-container *ngFor=\"let field of formElements; let i = index\" getProperties().elementProps>\n\n <!-- TextBox -->\n <div *ngIf=\"field.type === 'Text'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Label' }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"text\" class=\"custom-input\" [placeholder]=\"field.question || 'Enter text'\"\n [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : '' \" />\n </div>\n </div>\n </div>\n\n <!-- MSM-09JUL25 Icon-selectir Element -->\n <div *ngIf=\"field.type === 'Icon'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isRequired\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Choose Icon'\n }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div class=\"choose-icon-placeholder\">\n </div>\n </div>\n </div>\n </div>\n\n <!-- AP-19MAR25 Line Element -->\n <div *ngIf=\"field.type === 'Line'\" class=\"line-field\" (click)=\"selectElement(i)\"\n [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"line-element\">\n <div></div>\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n <hr class=\"custom-line\" style=\"display: inline-flex\" [ngStyle]=\"getLineStyles(field)\" />\n </div>\n\n <!--SKS25MAR25 Image Upload Element -->\n <div *ngIf=\"field.type === 'Image'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\" (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\" [ngStyle]=\"getFontStyles(field)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Upload Image' }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div>\n <div class=\"logo-container\">\n <!-- Logo preview area -->\n <div class=\"logo-preview\" *ngIf=\"field.imageData\">\n <img [src]=\"field.imageData\" />\n </div>\n\n <!-- Upload button -->\n <div *ngIf=\"!field.imageData\" class=\"logo-upload-placeholder\">\n <label for=\"logo-upload-{{i}}\" class=\"logo-upload-label\">\n <img src=\"../assets/icons/Image.svg\" alt=\"Upload\" />\n <span>Upload Image</span>\n </label>\n <input type=\"file\" id=\"logo-upload-{{i}}\" accept=\"image/*\" (change)=\"fileChangeEvent(i, $event)\"\n style=\"display: none;\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Space Element -->\n <div *ngIf=\"field.type === 'Space'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" style=\"height:93px\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <label [class.required]=\"field.isOptional\"></label>\n <div class=\"top-right\" style=\"margin: -11px -11px 0 0;\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Boolean Element -->\n <div *ngIf=\"field.type === 'Boolean'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{ field.questionText\n ? field.questionText : 'Boolean'}}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"checkbox\" [checked]=\"field.boolean\" (change)=\"toggleBoolean(field)\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n\n <!-- Calendar -->\n <div *ngIf=\"field.type === 'Calendar'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Select Date'\n }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n\n </div>\n <input type=\"date\" class=\"custom-input\" [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n </div>\n\n <!-- AP -12MAR25 Date -->\n <div *ngIf=\"field.type === 'Date'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Select Date'\n }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n\n </div>\n <input type=\"date\" class=\"custom-input\" [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n </div>\n\n <!-- AP-21MAR25 Add Time element -->\n <!-- Time Field -->\n <div *ngIf=\"field.type === 'Time'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <label [class.required]=\"field.isOptional\">{{ field.questionText ? field.questionText : 'Time' }}</label>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"time\" class=\"custom-input\" [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n </div>\n\n <!-- AP-28MAR25 DateTime -->\n <div *ngIf=\"field.type === 'DateTime'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Select Date & Time'\n }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"datetime-local\" class=\"custom-input\" [readonly]=\"field.isReadOnly\"\n [class.hidden]=\"field.isHidden\" />\n </div>\n </div>\n </div>\n\n <!-- Email -->\n <div *ngIf=\"field.type === 'Email'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\"> {{ field.questionText ? field.questionText : 'Label' }}\n </label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"email\" class=\"custom-input\" [placeholder]=\"field.question || 'Enter email'\"\n [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n </div>\n\n <!-- Numbers -->\n <div *ngIf=\"field.type === 'Number'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Label' }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"number\" class=\"custom-input\" [placeholder]=\"field.question || 'Enter number'\"\n [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n </div>\n\n <!-- TextArea -->\n <div *ngIf=\"field.type === 'TextArea'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Enter your text'}}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <textarea class=\"custom-textarea\" [placeholder]=\"field.question || 'Enter detailed text here...'\"\n [style.height.px]=\"field.size || 100\" [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\"></textarea>\n </div>\n </div>\n </div>\n\n <!-- RichText -->\n <div *ngIf=\"field.type === 'RichTextArea'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Enter your text'}}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <textarea class=\"custom-textarea\" [placeholder]=\"field.question || 'Enter detailed text here...'\"\n [style.height.px]=\"field.size || 100\" [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\"\n [value]=\"field.defaultValue ? field.defaultValue : ''\"></textarea>\n </div>\n </div>\n </div>\n\n <!-- Label -->\n <div *ngIf=\"field.type === 'Label'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Label' }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Book -->\n <div *ngIf=\"field.type === 'Book'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Label' }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <lib-booklet [bookletJSON]=\"field.qbReferenceQuestions\"></lib-booklet>\n </div>\n </div>\n </div>\n\n <!-- File -->\n <div *ngIf=\"field.type === 'File'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Upload File'\n }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"file\" class=\"custom-input\" [readonly]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\" />\n </div>\n </div>\n </div>\n\n <!-- CheckBox -->\n <div *ngIf=\"field.type === 'Checkbox'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">\n {{ field.questionText ? field.questionText : 'Label' }}\n </label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n\n <div class=\"checkbox-options-container\">\n <div *ngFor=\"let option of field.options\" class=\"checkbox-option\">\n <input type=\"checkbox\" [id]=\"option.value + i\" [name]=\"field.id\"\n [value]=\"option.value || field.defaultValue\" class=\"checkbox-input\" [disabled]=\"field.isReadOnly\"\n [class.hidden]=\"field.isHidden\">\n <label [for]=\"option.value + i\" class=\"checkbox-label\">{{ option.value }}</label>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Radio -->\n <div *ngIf=\"field.type === 'Radio'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Label' }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div class=\"radio-options-container\">\n <div *ngFor=\"let option of field.options; let j = index\" class=\"radio-option\">\n <input type=\"radio\" [id]=\"'radio-' + field.id + '-' + j\" [name]=\"'radio-group-' + field.id\"\n [value]=\"option.value || field.defaultValue\" [(ngModel)]=\"field.selectedValue\" class=\"radio-input\"\n [disabled]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\">\n <label [for]=\"'radio-' + field.id + '-' + j\" class=\"radio-label\"> {{ option.value }}</label>\n </div>\n </div>\n </div>\n </div>\n </div>\n <!-- Dropdown -->\n <div *ngIf=\"field.type === 'Dropdown'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Label' }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <select id=\"options\" class=\"dropdown\" [disabled]=\"field.isReadOnly\" [class.hidden]=\"field.isHidden\">\n <option *ngFor=\"let option of field.options\" [value]=\"option.value || field.defaultValue\"> {{ option.value\n }} </option>\n </select>\n </div>\n </div>\n </div>\n\n <!-- Table -->\n <!-- AP-06MAR25 -->\n <div *ngIf=\"field.type === 'Table'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\" style=\"overflow: hidden;\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Label' }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <div class=\"nxt-table-container\">\n <nxt-datatable isButtons [question]=\"field\" from=\"formBuilder\" [mode]=\"'edit'\" [apiMeta]=\"field.subText\"\n [tableConfig]=\"field.tableConfig\" tableId=\"\" direction=\"ltr\" tableWidth=\"auto\" isEditable=true [selectedColumn]=\"selectedColumn\"\n (columnSelected)=columnSelected($event) (removeColumn)=removeColumn($event)>\n </nxt-datatable>\n </div>\n </div>\n </div>\n </div>\n\n <!-- List -->\n <!-- AP-06MAR25 - List data show-->\n <div *ngIf=\"field.type === 'List'\" class=\"field-container\" (click)=\"selectElement(i)\"\n [ngStyle]=\"getFontStyles(field)\" [class.highlight]=\"selectedFieldIndex === i\" draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\" (dragover)=\"onDragOver($event, i)\" (drop)=\"onDrop($event, i)\">\n <div class=\"field-wrapper\">\n <div class=\"field-content\">\n <div class=\"label-container\">\n <div>\n <label [class.required]=\"field.isOptional\" *ngIf=\"field.style?.showLabel !== false\">{{\n field.questionText ? field.questionText : 'Label' }}</label>\n </div>\n <div class=\"top-right\">\n <img src=\"../assets/icons/drag-dots.svg\" alt=\"Drag\" class=\"drag-dot\" />\n <img src=\"../assets/icons/Trash.svg\" (click)=\"removeElement(field, i)\" class=\"delete-icon\" />\n </div>\n </div>\n <input type=\"text\" class=\"custom-input\" placeholder=\"Search...\" [readonly]=\"field.isReadOnly\"\n [class.hidden]=\"field.isHidden\" [value]=\"field.defaultValue ? field.defaultValue : ''\" />\n </div>\n </div>\n </div>\n\n </ng-container>\n </div>\n</div>\n<!-- SKS13MAR25 popup conformation box -->\n<div class=\"dialog-overlay\" *ngIf=\"isSelectTablePopup\">\n <div class=\"dialog-box\">\n <button class=\"close-btn-fb\" (click)=\"onClose()\">\u2715</button>\n <p>These element want to add a table</p>\n <div class=\"button-container-fb\">\n <button class=\"yes-btn-fb\" (click)=\"addOnTable()\">Yes</button>\n <button class=\"no-btn-fb\" (click)=\"onClose()\">No</button>\n </div>\n </div>\n</div>", styles: [".center-frame{display:flex;border-right-width:0}.head-elements{font-size:17px;font-weight:600}.form-builder{width:33.33%;height:calc(100vh - 20px);overflow-y:auto;background-color:#fff;padding:10px;border-right:10px solid #86A8CD;box-shadow:2px 2px 10px #0000001a}.form-builder .element{display:flex;align-items:center;gap:15px;margin-top:10px;padding:10px;border-radius:5px;background:#f8fafc;cursor:pointer;border-left:10px solid #E2F1FF;position:relative;color:#000}.form-builder .element:hover{background:#0250d9;color:#fff;border-left:10px solid #234465}.form-builder .element:hover img{filter:invert(1)}.form-builder .element:hover .hover-label{color:#fff}.form-builder .element:hover .dot{background-color:#ffffffb3}.form-builder .element .drag-dots:active{cursor:grabbing}.form-builder .element img{width:20px;height:20px;transition:filter .3s ease}.form-builder .hover-label{font-size:15px;font-weight:400;color:#000;transition:color .3s ease}.form-builder .section-title{font-weight:700;font-size:16px;margin-top:10px;padding:5px;border-bottom:1px solid #ddd;color:#000;display:flex;justify-content:space-between;align-items:center}.form-builder .section-title:after{content:\"\\25bc\";font-size:12px;color:#555}.form-builder .section{margin-bottom:10px}.toggle-header{display:flex;align-items:center;justify-content:space-between;cursor:pointer;padding:10px}.arrow-icon{width:19px;height:23px;transition:transform .3s ease}.toggle-header:hover .arrow-icon{transform:scale(1.1)}.drag-dots{display:grid;grid-template-columns:repeat(2,1fr);grid-template-rows:repeat(3,1fr);gap:3px;position:absolute;right:15px;top:50%;transform:translateY(-50%)}.dot{width:5px;height:5px;border-radius:50%;background-color:#cbd5e1;transition:background-color .3s ease}.drag-dot{height:13px}.field-wrapper,.line-field{background-color:#eff8ff;border:1px solid #E6F3FF;border-radius:5px;padding:10px}.line-field{width:100%;margin:10px 0;padding:3px}.field-container{padding:0 5px;transition:background .2s}.field-container:hover .top-right,.field-container.highlight .top-right{opacity:1;visibility:visible}.field-content{display:flex;flex-direction:column;gap:5px}.label-container{display:flex;justify-content:space-between;align-items:center}.label-container:hover .delete-icon{opacity:1;visibility:visible}.label-container label{font-size:15px;font-weight:400}.top-right{display:flex;gap:10px;padding:6px;border:1px solid #d7edff;margin:-10px -10px 0 0;background-color:#d7edff;opacity:0;visibility:hidden;cursor:grab;transition:opacity .1s,visibility .1s}.custom-input,.custom-textarea,.dropdown{width:100%;padding:8px;border:1px solid #ccc;background-color:#fff;border-radius:5px;outline:none}.custom-input{border-color:#dddbda}.custom-input:focus{border-color:#00008b;box-shadow:0 0 5px #0000ff80}.custom-textarea{min-height:100px;resize:vertical}.dropdown{font-size:14px;color:#333;cursor:pointer}.dropdown:focus{border-color:#007bff;box-shadow:0 0 5px #007bff80}.checkbox-options-container,.radio-options-container{display:flex;flex-direction:column;gap:5px;padding:8px;min-height:38px;border:1px solid #DDDBDA;background-color:#fff;border-radius:6px;outline:none;width:100%}.checkbox-option,.radio-option{display:flex;align-items:center;gap:8px;padding:8px;background-color:#fff;border-radius:4px;transition:background-color .2s ease}.checkbox-option:hover{background-color:#f1f3f5}.checkbox-input,.radio-input{width:18px;height:18px;accent-color:#4dabf7;cursor:pointer}.checkbox-label,.radio-label{font-size:14px;color:#495057;cursor:pointer;-webkit-user-select:none;user-select:none}.radio-input:checked{border-color:#007bff;background-color:#007bff}.radio-input:checked:after{content:\"\";width:8px;height:8px;background:#fff;border-radius:50%;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.form-preview{width:100%;height:fit-content;max-height:calc(100vh - 20px);overflow-y:auto;display:flex;flex-wrap:wrap;align-items:flex-start;padding:10px}.required:after{content:\" *\";color:red;margin-left:5px}.highlight{border:2px solid #5592FD!important;background-color:#eff8ff}.delete-icon{width:19px;height:19px;margin-top:-5px}.element.disabled{opacity:.5;cursor:not-allowed}.table-container label{font-size:14px;font-weight:700;margin-bottom:5px;display:block}.nxt-table-container{display:flex;justify-content:center;align-items:center;width:100%}nxt-datatable{width:100%!important;table-layout:fixed;max-width:100%}.dialog-overlay{position:fixed;inset:0;background:#00000080;display:flex;justify-content:center;align-items:center;z-index:1000}.dialog-box{background:#fff;padding:20px;border-radius:5px;text-align:center;width:300px;position:relative}.close-btn-fb{position:absolute;top:4px;right:4px;background:#ff4242;color:#fff;border:none;border-radius:50%;width:20px;height:20px;font-size:10px;cursor:pointer}.button-container-fb{display:flex;justify-content:flex-end;gap:10px}.yes-btn-fb{background:green;color:#fff;border:none;padding:0 12px;border-radius:5px;cursor:pointer}.no-btn-fb{background:gray;color:#fff;border:none;padding:8px 15px;border-radius:5px;cursor:pointer}.line-element{width:100%;display:flex;justify-content:space-between;align-items:center}.custom-line{width:100%;border:1px solid #000}.logo-container{display:flex;flex-direction:column;padding:10px;border:1px dashed #ccc;border-radius:5px;background-color:#f9f9f9}.logo-preview{position:relative;border:1px solid #e0e0e0;background-color:#fff;overflow:hidden}.logo-upload-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;width:150px;height:150px;border:2px dashed #ccc;cursor:pointer}.logo-upload-label{display:flex;flex-direction:column;align-items:center;cursor:pointer;color:#666}.logo-upload-label img{width:32px;height:32px;margin-bottom:8px}.sticky-footer-version{position:fixed;bottom:0;padding:10px;text-align:center}.choose-icon-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;width:48px;height:150px;border:2px dashed #ccc;cursor:pointer}\n"] }]
469
+ }], ctorParameters: () => [{ type: i1.FormBuilderService }], propDecorators: { bookletJSON: [{
470
+ type: Input
471
+ }], bookletId: [{
472
+ type: Input
473
+ }], templateMode: [{
474
+ type: Output
475
+ }] } });
476
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxlbWVudC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9ueHQtYXBwL3NyYy9saWIvcGFnZXMvYnVpbGRlci9lbGVtZW50L2VsZW1lbnQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbnh0LWFwcC9zcmMvbGliL3BhZ2VzL2J1aWxkZXIvZWxlbWVudC9lbGVtZW50LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGtEQUFrRDtBQUNsRCxPQUFPLEVBQ0wsU0FBUyxFQUNULFlBQVksRUFDWixLQUFLLEVBQ0wsTUFBTSxHQUVQLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUMzRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxtREFBbUQsQ0FBQzs7Ozs7QUFjakYsTUFBTSxPQUFPLGdCQUFnQjtJQTBCUDtJQXpCWCxXQUFXLENBQU07SUFDakIsU0FBUyxDQUFNO0lBQ2QsWUFBWSxHQUFHLElBQUksWUFBWSxFQUFXLENBQUM7SUFDckQsS0FBSyxDQUFNO0lBQ1gsWUFBWSxHQUFVLEVBQUUsQ0FBQztJQUN6QixRQUFRLEdBQVUsRUFBRSxDQUFDO0lBQ3JCLE1BQU0sQ0FBUztJQUNmLFFBQVEsR0FBRztRQUNULEtBQUssRUFBRSxJQUFJLEVBQUUsaUNBQWlDO1FBQzlDLFFBQVEsRUFBRSxJQUFJLEVBQUUsc0NBQXNDO0tBQ3ZELENBQUM7SUFDRixhQUFhLEdBQVUsRUFBRSxDQUFDO0lBQzFCLGdCQUFnQixHQUFVLEVBQUUsQ0FBQztJQUM3Qiw0QkFBNEI7SUFDNUIsT0FBTyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxvREFBb0Q7SUFDL0UsSUFBSSxDQUFNO0lBQ1YsZUFBZSxHQUFRLElBQUksQ0FBQztJQUM1QixrQkFBa0IsR0FBWSxLQUFLLENBQUM7SUFDcEMsV0FBVyxDQUFTO0lBQ3BCLFFBQVEsR0FBWSxJQUFJLENBQUM7SUFDekIsSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNoQixZQUFZLEdBQWtCLElBQUksQ0FBQztJQUNuQyxnQkFBZ0IsR0FBRyxLQUFLLENBQUM7SUFDekIsY0FBYyxHQUFZLEtBQUssQ0FBQztJQUNoQyxjQUFjLENBQU07SUFDcEIsWUFBb0Isa0JBQXNDO1FBQXRDLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBb0I7SUFBRyxDQUFDO0lBQ2hFLCtEQUErRDtJQUM3RCxRQUFRO1FBQ04sSUFBSSxDQUFDLGFBQWEsR0FBRztZQUNuQixFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFO1lBQzVDLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUU7WUFDbEQsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRTtZQUMvQyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFO1lBQy9DLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUU7WUFDNUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRTtZQUM1QyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsR0FBRyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFO1lBQ3hELEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUU7WUFDeEQsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRTtZQUM3QyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFO1lBQy9DLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUU7WUFDeEQsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRTtZQUMvQyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFO1lBQ3BELEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUU7WUFDekQsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRTtTQUM5RCxDQUFDO1FBRUYsSUFBSSxDQUFDLGdCQUFnQixHQUFHO1lBQ3RCLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsRUFBRSxvQ0FBb0M7WUFDbEYsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRTtZQUM1QyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFO1lBQy9DLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUU7WUFDckQsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRTtZQUM5QyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFO1lBQzlDLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUU7WUFDL0MsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRTtTQUNuRCxDQUFDO1FBQ0YsZ0NBQWdDO1FBQ2hDLGFBQWE7UUFDYiwwRUFBMEU7UUFDMUUsMEVBQTBFO1FBQzFFLDJEQUEyRDtRQUMzRCxNQUFNO1FBQ04sS0FBSztRQUVMLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7WUFDM0QsVUFBVSxDQUFDLEdBQUcsRUFBRTtnQkFDZCxJQUFJLENBQUMsWUFBWSxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxHQUFHLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM5RCxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDUixDQUFDLENBQUMsQ0FBQztRQUNILElBQUksSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsV0FBVyxLQUFLLEVBQUUsRUFBRSxDQUFDO1lBQ2hELElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN4QixDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNwQyxDQUFDO1FBQ0QseUNBQXlDO1FBQ3pDLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ25CLFlBQVksQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNwRCxDQUFDO1FBQ0QsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDOUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQzNELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUN2RCxJQUFJLEtBQUssSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDZixJQUFJLENBQUMsZUFBZSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN6QyxDQUFDO1lBQ0Qsb0NBQW9DO1lBQ3BDLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRSxJQUFJLEtBQUssT0FBTyxFQUFFLENBQUM7Z0JBQzNDLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxDQUFDO29CQUNoQyxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxLQUFLLFFBQVE7d0JBQ2pELENBQUMsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVU7d0JBQ2pDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7WUFDakUsQ0FBQztZQUNELG9DQUFvQztRQUN0QyxDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO0lBQzdDLENBQUM7SUFFRCxvQkFBb0I7SUFDcEIsYUFBYSxDQUFDLE9BQTZCO1FBQ3pDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFRCxhQUFhLENBQUMsT0FBZTtRQUMzQixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUVELG9FQUFvRTtJQUNwRSxXQUFXLENBQUMsT0FBc0I7UUFDaEMsSUFBSSxPQUFPLENBQUMsYUFBYSxDQUFDLElBQUksT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ2xFLElBQUksSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsV0FBVyxLQUFLLEVBQUUsRUFBRSxDQUFDO2dCQUNoRCx1RUFBdUU7Z0JBQ3ZFLElBQ0UsSUFBSSxDQUFDLFdBQVcsQ0FBQyxZQUFZO29CQUM3QixJQUFJLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxNQUFNO29CQUNwQyxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDLE1BQU0sS0FBSyxRQUFRLEVBQ3hELENBQUM7b0JBQ0QsSUFBSSxDQUFDO3dCQUNILE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQzlCLElBQUksQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FDckMsQ0FBQzt3QkFFRixrRUFBa0U7d0JBQ2xFLE1BQU0sVUFBVSxHQUFHLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFTLEVBQUUsS0FBYSxFQUFFLEVBQUU7NEJBQ2hFLE1BQU0sZUFBZSxHQUNuQixJQUFJLENBQUMsSUFBSSxLQUFLLFFBQVE7Z0NBQ3BCLENBQUMsQ0FBQyxDQUFDO2dDQUNILENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxLQUFLLE1BQU07b0NBQ3RCLENBQUMsQ0FBQyxFQUFFO29DQUNKLENBQUMsQ0FBQyxFQUFFLEdBQUcsS0FBSyxHQUFHLEVBQUUsQ0FBQzs0QkFFdEIsT0FBTztnQ0FDTCxHQUFHLElBQUk7Z0NBQ1AsZUFBZSxFQUFFLGVBQWU7Z0NBQ2hDLEtBQUssRUFBRSxHQUFHO2dDQUNWLFNBQVMsRUFBRSxTQUFTO2dDQUNwQixZQUFZLEVBQUUsQ0FBQztnQ0FDZixFQUFFLEVBQUUsS0FBSyxHQUFHLENBQUM7NkJBQ2QsQ0FBQzt3QkFDSixDQUFDLENBQUMsQ0FBQzt3QkFDSCwwRUFBMEU7d0JBQzFFLElBQUksQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDLE1BQU0sR0FBRyxVQUFVLENBQUM7b0JBQ3BELENBQUM7b0JBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQzt3QkFDWCxPQUFPLENBQUMsS0FBSyxDQUFDLG1DQUFtQyxFQUFFLENBQUMsQ0FBQyxDQUFDO29CQUN4RCxDQUFDO2dCQUNILENBQUM7Z0JBRUQsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3hCLENBQUM7aUJBQU0sQ0FBQztnQkFDTixJQUFJLENBQUMsa0JBQWtCLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDcEMsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBQ0QsK0VBQStFO0lBQy9FLGtCQUFrQixDQUFDLEtBQWlEO1FBQ2xFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUN4QyxLQUFLLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRXZFLCtCQUErQjtRQUMvQixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMvQixDQUFDO0lBRU8sY0FBYztRQUNwQixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUM1RCxPQUFPLENBQUMsSUFBSSxDQUFDLCtCQUErQixDQUFDLENBQUM7WUFDOUMsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsa0JBQWtCLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDeEMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFeEQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDO1FBQzNELE1BQU0sb0JBQW9CLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBRTNELElBQUksb0JBQW9CLENBQUMsTUFBTSxLQUFLLENBQUM7WUFBRSxPQUFPO1FBRTlDLEtBQUssTUFBTSxHQUFHLElBQUksb0JBQW9CLEVBQUUsQ0FBQztZQUN2QyxNQUFNLFlBQVksR0FBRyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsRUFBRSxZQUFZLENBQUM7WUFFekQsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7Z0JBQ2hDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBRTtvQkFDbkMsMEdBQTBHO29CQUMxRyxJQUNFLE9BQU8sV0FBVyxDQUFDLEtBQUssS0FBSyxRQUFRO3dCQUNyQyxXQUFXLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFDL0IsQ0FBQzt3QkFDRCxXQUFXLENBQUMsS0FBSyxHQUFHOzRCQUNsQixVQUFVLEVBQUUsSUFBSTs0QkFDaEIsVUFBVSxFQUFFLElBQUk7NEJBQ2hCLGVBQWUsRUFBRSxJQUFJOzRCQUNyQixVQUFVLEVBQUUsSUFBSTs0QkFDaEIsVUFBVSxFQUFFLElBQUk7NEJBQ2hCLFNBQVMsRUFBRSxJQUFJOzRCQUNmLFNBQVMsRUFBRSxJQUFJOzRCQUNmLFNBQVMsRUFBRSxLQUFLOzRCQUNoQixhQUFhLEVBQUUsSUFBSTt5QkFDcEIsQ0FBQztvQkFDSixDQUFDO2dCQUNILENBQUMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztRQUNILENBQUM7UUFDRCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUM1RCxDQUFDO0lBRUQsOENBQThDO0lBQzlDLGFBQWEsQ0FBQyxLQUFhO1FBQ3pCLElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFBO1FBQzNCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFBO1FBQzFCLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxLQUFLLENBQUMsQ0FBQyxzQkFBc0I7UUFDdkQsSUFBSSxDQUFDLGtCQUFrQixDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2xELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ2hELENBQUM7SUFDRCxrQkFBa0IsR0FBa0IsSUFBSSxDQUFDLENBQUMscUJBQXFCO0lBRS9ELGFBQWEsQ0FBQyxLQUFVO1FBQ3RCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFBO1FBQzFCLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUM7UUFDL0IsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUE7UUFDMUIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLHdEQUF3RDtRQUN0RyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLGlEQUFpRDtJQUNsRyxDQUFDO0lBQ0QsMEJBQTBCO0lBQzFCLFlBQVk7UUFDVixPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO0lBQ3BELENBQUM7SUFFRCxVQUFVLENBQUMsSUFBWTtRQUNyQixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDdEMsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7UUFDeEIsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFLElBQUksS0FBSyxPQUFPLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQzVELElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUM7UUFDakMsQ0FBQzthQUFNLENBQUM7WUFDTixNQUFNLFVBQVUsR0FBRztnQkFDakIsTUFBTSxFQUFFLElBQUk7Z0JBQ1osRUFBRSxFQUFFLFNBQVM7Z0JBQ2IsSUFBSTtnQkFDSixJQUFJLEVBQUUsSUFBSTtnQkFDVixZQUFZLEVBQUUsSUFBSTtnQkFDbEIsUUFBUSxFQUFFLElBQUk7Z0JBQ2QsUUFBUSxFQUFFLElBQUk7Z0JBQ2QsWUFBWSxFQUFFLElBQUk7Z0JBQ2xCLFVBQVUsRUFBRSxLQUFLO2dCQUNqQixRQUFRLEVBQUUsS0FBSztnQkFDZixRQUFRLEVBQUUsS0FBSztnQkFDZixjQUFjLEVBQUUsSUFBSTtnQkFDcEIscUJBQXFCLEVBQUUsSUFBSTtnQkFDM0IsU0FBUyxFQUFFLElBQUk7Z0JBQ2YsY0FBYyxFQUFFLEtBQUs7Z0JBQ3JCLEtBQUssRUFBRSxJQUFJO2dCQUNYLFFBQVEsRUFBRSxJQUFJO2dCQUNkLElBQUksRUFBRSxFQUFFO2dCQUNSLGFBQWEsRUFBRSxLQUFLO2dCQUNwQixVQUFVLEVBQUUsS0FBSztnQkFDakIsT0FBTyxFQUFFLEtBQUs7Z0JBQ2QsWUFBWSxFQUFFLElBQUk7Z0JBQ2xCLHFCQUFxQixFQUFFLElBQUk7Z0JBQzNCLGNBQWMsRUFBRSxJQUFJLENBQUMsa0JBQWtCLENBQUMsV0FBVyxFQUFFLENBQUMsTUFBTSxHQUFHLENBQUM7Z0JBQ2hFLEtBQUssRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sR0FBRyxDQUFDO2dCQUNuQyxjQUFjLEVBQUUsSUFBSSxDQUFDLFNBQVM7Z0JBQzlCLFVBQVUsRUFBRSxFQUFFO2dCQUNkLFVBQVUsRUFBRSxJQUFJO2dCQUNoQixRQUFRLEVBQUUsSUFBSTtnQkFDZCxXQUFXLEVBQUUsSUFBSTtnQkFDakIsb0JBQW9CLEVBQUUsSUFBSTtnQkFDMUIsVUFBVSxFQUFFLEtBQUs7Z0JBQ2pCLEtBQUssRUFBRTtvQkFDTCxVQUFVLEVBQUUsSUFBSTtvQkFDaEIsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLGVBQWUsRUFBRSxJQUFJO29CQUNyQixVQUFVLEVBQUUsSUFBSTtvQkFDaEIsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLFNBQVMsRUFBRSxJQUFJO29CQUNmLFNBQVMsRUFBRSxJQUFJO29CQUNmLFNBQVMsRUFBRSxLQUFLO29CQUNoQixhQUFhLEVBQUUsSUFBSTtpQkFDcEI7Z0JBQ0QsT0FBTyxFQUFFO29CQUNQLFFBQVEsRUFBRSxJQUFJO29CQUNkLFFBQVEsRUFBRSxJQUFJO29CQUNkLEtBQUssRUFBRSxJQUFJO29CQUNYLFlBQVksRUFBRSxJQUFJO29CQUNsQixnQkFBZ0IsRUFBRSxJQUFJO29CQUN0QixVQUFVLEVBQUUsSUFBSTtvQkFDaEIsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLGdCQUFnQixFQUFFLEtBQUs7b0JBQ3ZCLGNBQWMsRUFBRSxJQUFJO29CQUNwQixVQUFVLEVBQUUsSUFBSTtvQkFDaEIsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLG1CQUFtQixFQUFFLElBQUk7b0JBQ3pCLFNBQVMsRUFBRSxJQUFJO2lCQUNoQjtnQkFDRCxTQUFTLEVBQUUsSUFBSTtnQkFDZixPQUFPLEVBQUUsS0FBSztnQkFDZCxPQUFPLEVBQ0wsSUFBSSxLQUFLLFVBQVUsSUFBSSxJQUFJLEtBQUssYUFBYSxJQUFJLElBQUksS0FBSyxPQUFPLElBQUksSUFBSSxLQUFLLFVBQVU7b0JBQ3RGLENBQUMsQ0FBQyxFQUFFO29CQUNKLENBQUMsQ0FBQyxJQUFJO2dCQUNWLFNBQVMsRUFBRSxJQUFJLEtBQUssT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJO2dCQUNoRSxXQUFXLEVBQ1QsSUFBSSxLQUFLLE9BQU87b0JBQ2QsQ0FBQyxDQUFDO3dCQUNFLGNBQWMsRUFBRSxJQUFJO3dCQUNwQixlQUFlLEVBQUUsSUFBSTt3QkFDckIsWUFBWSxFQUFFLElBQUk7d0JBQ2xCLFlBQVksRUFBRSxJQUFJO3dCQUNsQixXQUFXLEVBQUUsSUFBSTt3QkFDakIsU0FBUyxFQUFFLElBQUk7d0JBQ2YsU0FBUyxFQUFFLElBQUk7d0JBQ2YsU0FBUyxFQUFFLElBQUk7d0JBQ2YsWUFBWSxFQUFFLEVBQUU7cUJBQ2pCO29CQUNILENBQUMsQ0FBQyxJQUFJO2FBQ1gsQ0FBQztZQUNGLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDL0MsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDMUQsOEJBQThCO1lBQzlCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUNsRSxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztRQUN2QixDQUFDO0lBQ0gsQ0FBQztJQUVELDZCQUE2QjtJQUM3QixhQUFhLENBQUMsS0FBVSxFQUFFLEtBQWE7UUFDckMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLHNCQUFzQixDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN6RCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUMxRCw4QkFBOEI7UUFDOUIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ3BFLENBQUM7SUFFRCxXQUFXLENBQUMsS0FBZ0IsRUFBRSxLQUFhO1FBQ3pDLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO1FBQzFCLEtBQUssQ0FBQyxZQUFZLEVBQUUsT0FBTyxDQUFDLFlBQVksRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztJQUM5RCxDQUFDO0lBRUQsdUNBQXVDO0lBQ3ZDLFVBQVUsQ0FBQyxLQUFnQixFQUFFLEtBQWE7UUFDeEMsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO0lBQ3pCLENBQUM7SUFFRCxvQkFBb0I7SUFDcEIsTUFBTSxDQUFDLEtBQWdCLEVBQUUsU0FBaUI7UUFDeEMsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBRXZCLElBQUksSUFBSSxDQUFDLFlBQVksS0FBSyxJQUFJLElBQUksSUFBSSxDQUFDLFlBQVksS0FBSyxTQUFTO1lBQUUsT0FBTztRQUUxRSxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUV6RCxzRUFBc0U7UUFDdEUsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMvQyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBRXBELGlFQUFpRTtRQUNqRSxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsRUFBRTtZQUMzQyxPQUFPLENBQUMsY0FBYyxHQUFHLEtBQUssR0FBRyxDQUFDLENBQUM7UUFDckMsQ0FBQyxDQUFDLENBQUM7UUFFSCxzQkFBc0I7UUFDdEIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7UUFFekIsa0NBQWtDO1FBQ2xDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDakUsQ0FBQztJQUVELGFBQWEsQ0FBQyxLQUFVO1FBQ3RCLEtBQUssQ0FBQyxPQUFPLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDO0lBQ2pDLENBQUM7SUFDRCxhQUFhLENBQUMsS0FBVSxFQUFFLHFCQUE4QixLQUFLO1FBQzNELE1BQU0sTUFBTSxHQUFRO1lBQ2xCLGFBQWEsRUFBRSxLQUFLLEVBQUUsSUFBSSxJQUFJLGdCQUFnQjtZQUM5QyxhQUFhLEVBQUUsS0FBSyxFQUFFLFVBQVUsSUFBSSxLQUFLO1lBQ3pDLFdBQVcsRUFBRSxLQUFLLEVBQUUsUUFBUSxJQUFJLE1BQU07WUFDdEMsT0FBTyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLEVBQUUsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxNQUFNO1lBQzdELFlBQVksRUFBRSxLQUFLLEVBQUUsU0FBUyxJQUFJLE1BQU07WUFDeEMsZUFBZSxFQUFFLEtBQUs7WUFDdEIsY0FBYyxFQUFFLEtBQUssRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLFNBQVMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLO1lBQ2pFLE9BQU8sRUFBRSxLQUFLLEVBQUUsU0FBUyxJQUFJLFNBQVM7WUFDdEMsWUFBWSxFQUFFLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLFVBQVUsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLO1lBQ2pFLGVBQWUsRUFBRSxLQUFLLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxhQUFhLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTTtZQUMzRSxjQUFjLEVBQUUsS0FBSyxFQUFFLEtBQUssSUFBSSxTQUFTO1NBQzFDLENBQUM7UUFDRixJQUFJLGtCQUFrQixFQUFFLENBQUM7WUFDdkIsTUFBTSxDQUFDLGNBQWMsQ0FBQyxHQUFHLEtBQUssRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLElBQUksT0FBTyxDQUFDO1FBQ3RFLENBQUM7UUFDRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRUQsYUFBYSxDQUFDLEtBQVU7UUFDdEIsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQsYUFBYSxDQUFDLEtBQVU7UUFDdEIsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQsd0RBQXdEO0lBQ3hELE9BQU87UUFDTCxJQUFJLENBQUMsa0JBQWtCLEdBQUcsS0FBSyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ3RCLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFDRCwrQ0FBK0M7SUFDL0MsVUFBVTtRQUNSLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxLQUFLLENBQUM7UUFDaEMsTUFBTSxRQUFRLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO1FBRTVELDBDQUEwQztRQUMxQyxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLElBQUksQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDNUUsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxVQUFVO1lBQ2hELENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDLFVBQVUsRUFBRSxNQUFNO1lBQzdDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDTixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDdEMsTUFBTSxZQUFZLEdBQUc7WUFDbkIsS0FBSyxFQUFFLGdCQUFnQixNQUFNLEVBQUU7WUFDL0IsU0FBUyxFQUFFLGNBQWMsTUFBTSxFQUFFO1lBQ2pDLElBQUksRUFBRSxJQUFJLENBQUMsV0FBVztZQUN0QixFQUFFLEVBQUUsU0FBUztTQUNkLENBQUM7UUFDRixJQUFJLENBQUMsa0JBQWtCLENBQUMsZUFBZSxDQUNyQyxZQUFZLEVBQ1osSUFBSSxDQUFDLGtCQUFrQixDQUN4QixDQUFDO1FBQ0YsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDMUQsaUNBQWlDO1FBQ2pDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUNwRSxDQUFDO0lBQ0QscUJBQXFCLENBQUMsUUFBZTtRQUNuQyxPQUFPLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUMxQixJQUFJLEdBQUcsQ0FBQyxJQUFJLEtBQUssT0FBTyxFQUFFLENBQUM7Z0JBQ3pCLEdBQUcsQ0FBQyxVQUFVO29CQUNaLE9BQU8sR0FBRyxDQUFDLFVBQVUsS0FBSyxRQUFRO3dCQUNoQyxDQUFDLENBQUMsR0FBRyxDQUFDLFVBQVU7d0JBQ2hCLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxVQUFVLElBQUksRUFBRSxDQUFDLENBQUM7WUFDN0MsQ0FBQztZQUNELE9BQU8sR0FBRyxDQUFDO1FBQ2IsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBQ0QsY0FBYyxDQUFDLEtBQVU7UUFDdkIsaUNBQWlDO1FBQ2pDLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBUSxFQUFFLEtBQWEsRUFBRSxFQUFFO1lBQ3BELElBQUksR0FBRyxDQUFDLElBQUksS0FBSyxPQUFPLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztnQkFDMUQsTUFBTSxZQUFZLEdBQUcsR0FBRyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQ3RDLENBQUMsS0FBVSxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEtBQUssS0FBSyxFQUFFLGdCQUFnQixDQUNuRSxDQUFDO2dCQUNGLElBQUksWUFBWSxFQUFFLENBQUM7b0JBQ2pCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDbEQsSUFBSSxDQUFDLGtCQUFrQixHQUFHLEtBQUssQ0FBQTtnQkFDakMsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxrQkFBa0IsQ0FBQyx1QkFBdUIsQ0FDN0MsSUFBSSxDQUFDLGtCQUFrQixFQUN2QixLQUFLLENBQ04sQ0FBQztRQUNGLElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxFQUFFLGdCQUFnQixDQUFBO0lBQy9DLENBQUM7SUFDRCxZQUFZLENBQUMsS0FBVTtRQUNyQixJQUFJLENBQUMsa0JBQWtCLENBQUMsMEJBQTBCLENBQ2hELElBQUksQ0FBQyxrQkFBa0IsRUFDdkIsS0FBSyxDQUNOLENBQUM7UUFDRixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQTtJQUM1QixDQUFDO0lBRUQsdUJBQXVCO0lBQ3ZCLEtBQUssQ0FBQyxlQUFlLENBQUMsS0FBVSxFQUFFLEtBQVU7UUFDMUMsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbkMsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUNULElBQUksQ0FBQztnQkFDSCxNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDckQsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO2dCQUMvQyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDLFlBQVksR0FBRyxTQUFTLENBQUM7Z0JBQ2xELDBDQUEwQztnQkFDMUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsU0FBUyxFQUFFLENBQUM7b0JBQ3hDLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsU0FBUyxHQUFHLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUM7Z0JBQ25FLENBQUM7Z0JBRUQsTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQUMsYUFBYSxDQUN6QyxLQUFLLEVBQ0wsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FDekIsQ0FBQztZQUNKLENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLE9BQU8sQ0FBQyxLQUFLLENBQUMscUJBQXFCLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDOUMsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRU8saUJBQWlCLENBQUMsSUFBVTtRQUNsQyxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3JDLE1BQU0sTUFBTSxHQUFHLElBQUksVUFBVSxFQUFFLENBQUM7WUFDaEMsTUFBTSxDQUFDLE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQWdCLENBQUMsQ0FBQztZQUN2RCxNQUFNLENBQUMsT0FBTyxHQUFHLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDMUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM3QixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7d0dBN2VVLGdCQUFnQjs0RkFBaEIsZ0JBQWdCLHVNQzNCN0IscXQrQkFzbEJNLHc4TERua0JGLFlBQVksb1ZBQ1osV0FBVywrZ0NBQ1gsZ0JBQWdCLDhZQUNoQixZQUFZOzs0RkFLSCxnQkFBZ0I7a0JBWjVCLFNBQVM7K0JBQ0UsYUFBYSxjQUNYLElBQUksV0FDUDt3QkFDUCxZQUFZO3dCQUNaLFdBQVc7d0JBQ1gsZ0JBQWdCO3dCQUNoQixZQUFZO3FCQUNmO3VGQUtVLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDSSxZQUFZO3NCQUFyQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQVAgMjJKQU4yNSAtIGZvcm0gcHJldmlldyBhbmQgQWxsIGZvcm0gZWxlbWVudHNcbmltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2VzLFxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgRm9ybUJ1aWxkZXJTZXJ2aWNlIH0gZnJvbSBcIi4uLy4uLy4uL3NlcnZpY2VzL2Zvcm0tYnVpbGRlci5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBWRVJTSU9OIH0gZnJvbSBcIi4uLy4uLy4uLy4uL2Vudmlyb25tZW50cy92ZXJzaW9uXCI7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uXCI7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gXCJAYW5ndWxhci9mb3Jtc1wiO1xuaW1wb3J0IHsgQm9va2xldENvbXBvbmVudCB9IGZyb20gXCIuLi8uLi9ib29rbGV0L2Jvb2tsZXQuY29tcG9uZW50XCI7XG5pbXBvcnQgeyBOeHREYXRhdGFibGUgfSBmcm9tIFwiLi4vLi4vLi4vY29tcG9uZW50cy9kYXRhdGFibGUvZGF0YXRhYmxlLmNvbXBvbmVudFwiO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6IFwiYXBwLWVsZW1lbnRcIixcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBGb3Jtc01vZHVsZSxcbiAgICBCb29rbGV0Q29tcG9uZW50LFxuICAgIE54dERhdGF0YWJsZVxuXSxcbiAgdGVtcGxhdGVVcmw6IFwiLi9lbGVtZW50LmNvbXBvbmVudC5odG1sXCIsXG4gIHN0eWxlVXJsczogW1wiLi9lbGVtZW50LmNvbXBvbmVudC5jc3NcIl0sXG59KVxuZXhwb3J0IGNsYXNzIEVsZW1lbnRDb21wb25lbnQge1xuICBASW5wdXQoKSBib29rbGV0SlNPTjogYW55O1xuICBASW5wdXQoKSBib29rbGV0SWQ6IGFueTtcbiAgQE91dHB1dCgpIHRlbXBsYXRlTW9kZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcbiAgZmllbGQ6IGFueTtcbiAgZm9ybUVsZW1lbnRzOiBhbnlbXSA9IFtdO1xuICBlbGVtZW50czogYW55W10gPSBbXTtcbiAgYm9va0lkOiBzdHJpbmc7XG4gIHNlY3Rpb25zID0ge1xuICAgIGJhc2ljOiB0cnVlLCAvLyBCYXNpYyBFbGVtZW50cyBvcGVuIGJ5IGRlZmF1bHRcbiAgICBhZHZhbmNlZDogdHJ1ZSwgLy8gQWR2YW5jZWQgRWxlbWVudHMgY2xvc2VkIGJ5IGRlZmF1bHRcbiAgfTtcbiAgYmFzaWNFbGVtZW50czogYW55W10gPSBbXTtcbiAgYWR2YW5jZWRFbGVtZW50czogYW55W10gPSBbXTtcbiAgLy9lbGVtZW50RGlzYWJsZWRBcnJheTogYW55O1xuICB2ZXJzaW9uID0gVkVSU0lPTi52ZXJzaW9uOyAvL1NLUzEwTUFSMjUgZ2V0IHZlcnNpb24gZnJvbSBlbnZpcm9ubWVudC92ZXJzaW9uLnRzXG4gIGJvb2s6IGFueTtcbiAgc2VsZWN0ZWRFbGVtZW50OiBhbnkgPSBudWxsO1xuICBpc1NlbGVjdFRhYmxlUG9wdXA6IGJvb2xlYW4gPSBmYWxzZTtcbiAgY3VycmVudFR5cGU6IHN0cmluZztcbiAgYWRkVGFibGU6IGJvb2xlYW4gPSB0cnVlO1xuICBkb3RzID0gQXJyYXkoNik7XG4gIGRyYWdnZWRJbmRleDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gIHRlbXBsYXRlU2VsZWN0ZWQgPSBmYWxzZTtcbiAgaXNIZWFkZXJTZWxlY3Q6IGJvb2xlYW4gPSBmYWxzZTtcbiAgc2VsZWN0ZWRDb2x1bW46IGFueTtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBmb3JtQnVpbGRlclNlcnZpY2U6IEZvcm1CdWlsZGVyU2VydmljZSkge31cbi8vIEFQLTA2TUFSMjUgQmFzaWMgZWxlbWVudHMgdXBkYXRlZCAoUmljaFRleHRBcmVhLCBEYXRlIGFkZGVkKVxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmJhc2ljRWxlbWVudHMgPSBbXG4gICAgICB7IHR5cGU6IFwiVGV4dFwiLCBpbWc6IFwiVGV4dFwiLCBsYWJlbDogXCJUZXh0XCIgfSxcbiAgICAgIHsgdHlwZTogXCJOdW1iZXJcIiwgaW1nOiBcIk51bWJlclwiLCBsYWJlbDogXCJOdW1iZXJcIiB9LFxuICAgICAgeyB0eXBlOiBcIkxhYmVsXCIsIGltZzogXCJMYWJlbFwiLCBsYWJlbDogXCJMYWJlbFwiIH0sXG4gICAgICB7IHR5cGU6IFwiRW1haWxcIiwgaW1nOiBcIkVtYWlsXCIsIGxhYmVsOiBcIkVtYWlsXCIgfSxcbiAgICAgIHsgdHlwZTogXCJEYXRlXCIsIGltZzogXCJEYXRlXCIsIGxhYmVsOiBcIkRhdGVcIiB9LFxuICAgICAgeyB0eXBlOiBcIlRpbWVcIiwgaW1nOiBcIlRpbWVcIiwgbGFiZWw6IFwiVGltZVwiIH0sXG4gICAgICB7IHR5cGU6IFwiRGF0ZVRpbWVcIiwgaW1nOiBcIkRhdGVUaW1lXCIsIGxhYmVsOiBcIkRhdGVUaW1lXCIgfSxcbiAgICAgIHsgdHlwZTogXCJDYWxlbmRhclwiLCBpbWc6IFwiQ2FsZW5kYXJcIiwgbGFiZWw6IFwiQ2FsZW5kYXJcIiB9LFxuICAgICAgeyB0eXBlOiBcIkZpbGVcIiwgaW1nOiBcIkZpbGVcIiwgbGFiZWw6IFwiRmlsZXNcIiB9LFxuICAgICAgeyB0eXBlOiBcIkltYWdlXCIsIGltZzogXCJJbWFnZVwiLCBsYWJlbDogXCJJbWFnZVwiIH0sXG4gICAgICB7IHR5cGU6IFwiQ2hlY2tib3hcIiwgaW1nOiBcIkNoZWNrQm94XCIsIGxhYmVsOiBcIkNoZWNrYm94XCIgfSxcbiAgICAgIHsgdHlwZTogXCJSYWRpb1wiLCBpbWc6IFwiUmFkaW9cIiwgbGFiZWw6IFwiUmFkaW9cIiB9LFxuICAgICAgeyB0eXBlOiBcIkRyb3Bkb3duXCIsIGltZzogXCJEcm9wXCIsIGxhYmVsOiBcIkRyb3Bkb3duXCIgfSxcbiAgICAgIHsgdHlwZTogXCJUZXh0QXJlYVwiLCBpbWc6IFwiVGV4dEFyZWFcIiwgbGFiZWw6IFwiVGV4dCBBcmVhXCIgfSxcbiAgICAgIHsgdHlwZTogXCJSaWNoVGV4dEFyZWFcIiwgaW1nOiBcIlJpY2hUZXh0XCIsIGxhYmVsOiBcIlJpY2ggVGV4dFwiIH0sXG4gICAgXTtcblxuICAgIHRoaXMuYWR2YW5jZWRFbGVtZW50cyA9IFtcbiAgICAgIHsgdHlwZTogXCJJY29uXCIsIGltZzogXCJJY29uXCIsIGxhYmVsOiBcIkljb25cIiB9LCAvL01TTTEwSlVMMjUgaWNvbiBzZWxlY3RvciBjb21wb25lbnRcbiAgICAgIHsgdHlwZTogXCJMaW5lXCIsIGltZzogXCJsaW5lXCIsIGxhYmVsOiBcIkxpbmVcIiB9LFxuICAgICAgeyB0eXBlOiBcIlNwYWNlXCIsIGltZzogXCJzcGFjZVwiLCBsYWJlbDogXCJTcGFjZVwiIH0sXG4gICAgICB7IHR5cGU6IFwiQm9vbGVhblwiLCBpbWc6IFwiQm9vbGVhblwiLCBsYWJlbDogXCJCb29sZWFuXCIgfSxcbiAgICAgIHsgdHlwZTogXCJCb29rXCIsIGltZzogXCJTZWFyY2hcIiwgbGFiZWw6IFwiQm9va1wiIH0sXG4gICAgICB7IHR5cGU6IFwiTGlzdFwiLCBpbWc6IFwiU2VhcmNoXCIsIGxhYmVsOiBcIkxpc3RcIiB9LFxuICAgICAgeyB0eXBlOiBcIlRhYmxlXCIsIGltZzogXCJUYWJsZVwiLCBsYWJlbDogXCJUYWJsZVwiIH0sXG4gICAgICB7IHR5cGU6IFwiQnV0dG9uXCIsIGltZzogXCJCdXR0b25cIiwgbGFiZWw6IFwiQnV0dG9uXCIgfSxcbiAgICBdO1xuICAgIC8vIHRoaXMuZWxlbWVudERpc2FibGVkQXJyYXkgPSB7XG4gICAgLy8gICBUYWJsZTogW1xuICAgIC8vICAgICAnQm9vaycsICdDYWxlbmRhcicsXCJCb29sZWFuXCIsICdMaXN0JywgJ1RhYmxlJywgJ0NoZWNrYm94JywgJ1JhZGlvJyxcbiAgICAvLyAgICAgJ0Ryb3Bkb3duJywgJ1RleHRBcmVhJywgJ1JpY2hUZXh0QXJlYScsICdOdW1iZXInLCAnTGFiZWwnLCAnSW1hZ2UnLFxuICAgIC8vICAgICAnRW1haWwnLCAnRGF0ZScsICdUaW1lJywgJ0RhdGVUaW1lJywgJ0xpbmUnLCAnU3BhY2UnXG4gICAgLy8gICBdXG4gICAgLy8gfTtcblxuICAgIHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLmZvcm1FbGVtZW50cyQuc3Vic2NyaWJlKChlbGVtZW50cykgPT4ge1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuZm9ybUVsZW1lbnRzID0gZWxlbWVudHMubWFwKChmaWVsZCkgPT4gKHsgLi4uZmllbGQgfSkpO1xuICAgICAgfSwgMCk7XG4gICAgfSk7XG4gICAgaWYgKHRoaXMuYm9va2xldEpTT04gJiYgdGhpcy5ib29rbGV0SlNPTiAhPT0gXCJcIikge1xuICAgICAgdGhpcy5pbml0aWFsaXplRm9ybSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5uZXdCb29rKCk7XG4gICAgfVxuICAgIC8vIEFQLTEyTUFSMjUgLSBBZGRlZCB0byBoYW5kbGUgYm9va2xldElkXG4gICAgaWYgKHRoaXMuYm9va2xldElkKSB7XG4gICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShcInVuaXF1ZV9pZFwiLCB0aGlzLmJvb2tsZXRJZCk7XG4gICAgfVxuICAgIHRoaXMuYm9vayA9IHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLmdldEJvb2soKTtcbiAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5zZWxlY3RlZEVsZW1lbnQkLnN1YnNjcmliZSgoaW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UuZ2V0RWxlbWVudHMoKTtcbiAgICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRFbGVtZW50ID0gZWxlbWVudHNbaW5kZXhdO1xuICAgICAgfVxuICAgICAgLy8gU0tTMTlNQVIyNSBmb3IgZmllbGRNZXRhIGNoZWNraW5nXG4gICAgICBpZiAodGhpcy5zZWxlY3RlZEVsZW1lbnQ/LnR5cGUgPT09IFwiVGFibGVcIikge1xuICAgICAgICB0aGlzLnNlbGVjdGVkRWxlbWVudFtcImZpZWxkc01ldGFcIl0gPVxuICAgICAgICAgIHR5cGVvZiB0aGlzLnNlbGVjdGVkRWxlbWVudC5maWVsZHNNZXRhID09PSBcInN0cmluZ1wiXG4gICAgICAgICAgICA/IHRoaXMuc2VsZWN0ZWRFbGVtZW50LmZpZWxkc01ldGFcbiAgICAgICAgICAgIDogSlNPTi5zdHJpbmdpZnkodGhpcy5zZWxlY3RlZEVsZW1lbnRbXCJmaWVsZHNNZXRhXCJdIHx8IFtdKTtcbiAgICAgIH1cbiAgICAgIC8vIHRoaXMuZm9ybUVsZW1lbnRzID0gWy4uLmVsZW1lbnRzXVxuICAgIH0pO1xuICAgIHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLmFkZEVsZW1lbnRXaXRoSWQoKTtcbiAgfVxuXG4gIC8vIEFkZCB0aGVzZSBtZXRob2RzXG4gIHRvZ2dsZVNlY3Rpb24oc2VjdGlvbjogXCJiYXNpY1wiIHwgXCJhZHZhbmNlZFwiKSB7XG4gICAgdGhpcy5zZWN0aW9uc1tzZWN0aW9uXSA9ICF0aGlzLnNlY3Rpb25zW3NlY3Rpb25dO1xuICB9XG5cbiAgaXNTZWN0aW9uT3BlbihzZWN0aW9uOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zZWN0aW9uc1tzZWN0aW9uXTtcbiAgfVxuXG4gIC8vIEFQIC0gMjZGRUIyNSAtIEFkZGVkIG5nT25DaGFuZ2VzIHRvIGhhbmRsZSBjaGFuZ2VzIGluIGJvb2tsZXRKU09OXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICBpZiAoY2hhbmdlc1tcImJvb2tsZXRKU09OXCJdICYmIGNoYW5nZXNbXCJib29rbGV0SlNPTlwiXS5jdXJyZW50VmFsdWUpIHtcbiAgICAgIGlmICh0aGlzLmJvb2tsZXRKU09OICYmIHRoaXMuYm9va2xldEpTT04gIT09IFwiXCIpIHtcbiAgICAgICAgLy8gQVAtMjhNQVkyNSAtIENoZWNrIGFuZCB0cmFuc2Zvcm0gYGFjdGlvbmAgaWYgaXQncyBpbiBFeGlzdGluZyBmb3JtYXRcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHRoaXMuYm9va2xldEpTT04ucXVlc3Rpb25ib29rICYmXG4gICAgICAgICAgdGhpcy5ib29rbGV0SlNPTi5xdWVzdGlvbmJvb2suYWN0aW9uICYmXG4gICAgICAgICAgdHlwZW9mIHRoaXMuYm9va2xldEpTT04ucXVlc3Rpb25ib29rLmFjdGlvbiA9PT0gXCJzdHJpbmdcIlxuICAgICAgICApIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcGFyc2VkQWN0aW9ucyA9IEpTT04ucGFyc2UoXG4gICAgICAgICAgICAgIHRoaXMuYm9va2xldEpTT04ucXVlc3Rpb25ib29rLmFjdGlvblxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgLy8gQVAtMjhNQVkyNSBBc3NpZ24gc3BlY2lmaWMgcG9zaXRpb25QZXJjZW50IGJhc2VkIG9uIGFjdGlvbiBuYW1lXG4gICAgICAgICAgICBjb25zdCBuZXdBY3Rpb25zID0gcGFyc2VkQWN0aW9ucy5tYXAoKGl0ZW06IGFueSwgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgICBjb25zdCBwb3NpdGlvblBlcmNlbnQgPVxuICAgICAgICAgICAgICAgIGl0ZW0ubmFtZSA9PT0gXCJDYW5jZWxcIlxuICAgICAgICAgICAgICAgICAgPyAzXG4gICAgICAgICAgICAgICAgICA6IGl0ZW0ubmFtZSA9PT0gXCJTYXZlXCJcbiAgICAgICAgICAgICAgICAgID8gMTRcbiAgICAgICAgICAgICAgICAgIDogMTAgKyBpbmRleCAqIDEwO1xuXG4gICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgLi4uaXRlbSxcbiAgICAgICAgICAgICAgICBwb3NpdGlvblBlcmNlbnQ6IHBvc2l0aW9uUGVyY2VudCxcbiAgICAgICAgICAgICAgICB3aWR0aDogMTAwLFxuICAgICAgICAgICAgICAgIHRleHRDb2xvcjogXCIjZmZmZmZmXCIsXG4gICAgICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiA2LFxuICAgICAgICAgICAgICAgIGlkOiBpbmRleCArIDEsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIEFQLTI4TUFZMjUgUmVwbGFjZSB0aGUgb2xkIGFjdGlvbiBzdHJpbmcgd2l0aCB0aGUgbmV3bHkgZm9ybWF0dGVkIGFycmF5XG4gICAgICAgICAgICB0aGlzLmJvb2tsZXRKU09OLnF1ZXN0aW9uYm9vay5hY3Rpb24gPSBuZXdBY3Rpb25zO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciBwYXJzaW5nIGFjdGlvbiBKU09OIHN0cmluZzpcIiwgZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5pbml0aWFsaXplRm9ybSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UubmV3Qm9vaygpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICAvLyBBUC0wOEFQUjI1IFRlbXBsYXRlIGlzIHNlbGVjdGVkLCB1cGRhdGUgZm9ybSBlbGVtZW50cyBhbmQgZW1pdCB0ZW1wbGF0ZSBtb2RlXG4gIG9uVGVtcGxhdGVTZWxlY3RlZChldmVudDogeyBzZWxlY3RlZFRlbXBsYXRlOiBhbnk7IGVsZW1lbnRzOiBhbnlbXSB9KSB7XG4gICAgdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UuY2xlYXJFbGVtZW50cygpO1xuICAgIGV2ZW50LmVsZW1lbnRzLmZvckVhY2goKGVsKSA9PiB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5hZGRFbGVtZW50KGVsKSk7XG5cbiAgICAvLyBFbWl0IHRlbXBsYXRlIG1vZGUgdG8gcGFyZW50XG4gICAgdGhpcy50ZW1wbGF0ZU1vZGUuZW1pdCh0cnVlKTtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZUZvcm0oKSB7XG4gICAgaWYgKCF0aGlzLmJvb2tsZXRKU09OIHx8ICF0aGlzLmJvb2tsZXRKU09OLmJvb2tRdWVzdGlvbnNNYXApIHtcbiAgICAgIGNvbnNvbGUud2FybihcIkludmFsaWQgYm9va2xldEpTT04gc3RydWN0dXJlXCIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmZvcm1FbGVtZW50cyA9IFtdO1xuICAgIHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLmNsZWFyRWxlbWVudHMoKTtcbiAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5pbnRpYWxpemVCb29rKHRoaXMuYm9va2xldEpTT04pO1xuXG4gICAgY29uc3QgYm9va1F1ZXN0aW9uc01hcCA9IHRoaXMuYm9va2xldEpTT04uYm9va1F1ZXN0aW9uc01hcDtcbiAgICBjb25zdCBib29rUXVlc3Rpb25zTWFwS2V5cyA9IE9iamVjdC5rZXlzKGJvb2tRdWVzdGlvbnNNYXApO1xuXG4gICAgaWYgKGJvb2tRdWVzdGlvbnNNYXBLZXlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuXG4gICAgZm9yIChjb25zdCBrZXkgb2YgYm9va1F1ZXN0aW9uc01hcEtleXMpIHtcbiAgICAgIGNvbnN0IHN1YlF1ZXN0aW9ucyA9IGJvb2tRdWVzdGlvbnNNYXBba2V5XT8uc3ViUXVlc3Rpb25zO1xuXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShzdWJRdWVzdGlvbnMpKSB7XG4gICAgICAgIHN1YlF1ZXN0aW9ucy5mb3JFYWNoKChzdWJRdWVzdGlvbikgPT4ge1xuICAgICAgICAgIC8vIEFQLTA0QVBSMjQgSWYgc3ViUXVlc3Rpb24uc3R5bGUgZXhpc3RzIGFzIGEgc3RyaW5nIGFuZCBpcyBlbXB0eSwgcmVwbGFjZSBpdCB3aXRoIGEgZGVmYXVsdCBzdHlsZSBvYmplY3RcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICB0eXBlb2Ygc3ViUXVlc3Rpb24uc3R5bGUgPT09IFwic3RyaW5nXCIgJiZcbiAgICAgICAgICAgIHN1YlF1ZXN0aW9uLnN0eWxlLnRyaW0oKSA9PT0gXCJcIlxuICAgICAgICAgICkge1xuICAgICAgICAgICAgc3ViUXVlc3Rpb24uc3R5bGUgPSB7XG4gICAgICAgICAgICAgIGxhYmVsQ2xhc3M6IG51bGwsXG4gICAgICAgICAgICAgIGxhYmVsU3R5bGU6IG51bGwsXG4gICAgICAgICAgICAgIGxhYmVsVmFsdWVTdHlsZTogbnVsbCxcbiAgICAgICAgICAgICAgaW5wdXRDbGFzczogbnVsbCxcbiAgICAgICAgICAgICAgaW5wdXRTdHlsZTogbnVsbCxcbiAgICAgICAgICAgICAgc2hvd0xhYmVsOiB0cnVlLFxuICAgICAgICAgICAgICBib29rU3R5bGU6IG51bGwsXG4gICAgICAgICAgICAgIGRpcmVjdGlvbjogXCJsdHJcIixcbiAgICAgICAgICAgICAgcXVlc3Rpb25TdHlsZTogbnVsbCxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5mb3JtRWxlbWVudHMgPSB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5nZXRFbGVtZW50cygpO1xuICB9XG5cbiAgLy8gQWRkIHRoaXMgbWV0aG9kIHRvIGhhbmRsZSBlbGVtZW50IHNlbGVjdGlvblxuICBzZWxlY3RFbGVtZW50KGluZGV4OiBudW1iZXIpIHtcbiAgICB0aGlzLmlzSGVhZGVyU2VsZWN0ID0gZmFsc2VcbiAgICB0aGlzLnNlbGVjdGVkQ29sdW1uID0gbnVsbFxuICAgIHRoaXMuc2VsZWN0ZWRGaWVsZEluZGV4ID0gaW5kZXg7IC8vIGVsZW1lbnQgaXMgc2VsZWN0ZWRcbiAgICB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5zZXRTZWxlY3RlZEVsZW1lbnQoaW5kZXgpO1xuICAgIHRoaXMuYm9vayA9IHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLmdldEJvb2soKTtcbiAgfVxuICBzZWxlY3RlZEZpZWxkSW5kZXg6IG51bWJlciB8IG51bGwgPSBudWxsOyAvLyBlbGVtZW50IGlzIGNsZWFyZWRcblxuICBzZWxlY3RIZWFkaW5nKGV2ZW50OiBhbnkpIHtcbiAgICB0aGlzLmlzSGVhZGVyU2VsZWN0ID0gdHJ1ZVxuICAgIHRoaXMuc2VsZWN0ZWRGaWVsZEluZGV4ID0gbnVsbDtcbiAgICB0aGlzLnNlbGVjdGVkQ29sdW1uID0gbnVsbFxuICAgIHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLnNlbGVjdEhlYWRpbmcoZXZlbnQpOyAvL0FQLTEwTUFSMjUgVXBkYXRlcyB0aGUgc2VsZWN0ZWQgaGVhZGluZyBpbiB0aGUgc2VydmljZVxuICAgIHRoaXMuYm9vayA9IHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLmdldEJvb2soKTsgLy9BUC0xME1BUjI1IFJldHJpZXZlcyB0aGUgdXBkYXRlZCBib29rL2Zvcm0gZGF0YVxuICB9XG4gIC8vIEFQLTE3QVBSMjUgZ2VuZXJhdGVVaUlkXG4gIGdlbmVyYXRlVWlJZCgpIHtcbiAgICByZXR1cm4gdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UuYWRkRWxlbWVudFdpdGhJZCgpO1xuICB9XG5cbiAgYWRkRWxlbWVudCh0eXBlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCB1bmlxdWVfaWQgPSB0aGlzLmdlbmVyYXRlVWlJZCgpO1xuICAgIHRoaXMuY3VycmVudFR5cGUgPSB0eXBlO1xuICAgIGlmICh0aGlzLnNlbGVjdGVkRWxlbWVudD8udHlwZSA9PT0gXCJUYWJsZVwiICYmIHRoaXMuYWRkVGFibGUpIHtcbiAgICAgIHRoaXMuaXNTZWxlY3RUYWJsZVBvcHVwID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgbmV3RWxlbWVudCA9IHtcbiAgICAgICAgYWN0aW9uOiBudWxsLFxuICAgICAgICBpZDogdW5pcXVlX2lkLFxuICAgICAgICB0eXBlLFxuICAgICAgICBuYW1lOiBudWxsLFxuICAgICAgICBxdWVzdGlvblRleHQ6IG51bGwsXG4gICAgICAgIHF1ZXN0aW9uOiBudWxsLFxuICAgICAgICBoZWxwVGV4dDogbnVsbCxcbiAgICAgICAgZXJyb3JNZXNzYWdlOiBudWxsLFxuICAgICAgICBpc1JlYWRPbmx5OiBmYWxzZSxcbiAgICAgICAgaXNIaWRkZW46IGZhbHNlLFxuICAgICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICAgIHJlZmVyZW5jZUZpZWxkOiBudWxsLFxuICAgICAgICBhZGRpdGlvbmFsUmljaENvbnRlbnQ6IG51bGwsXG4gICAgICAgIGdyb3VwTmFtZTogbnVsbCxcbiAgICAgICAgaXNEYXRlQmFja3dhcmQ6IGZhbHNlLFxuICAgICAgICB0aXRsZTogbnVsbCxcbiAgICAgICAgc3ViVGl0bGU6IG51bGwsXG4gICAgICAgIHNpemU6IDEyLFxuICAgICAgICBpc0RhdGVGb3J3YXJkOiBmYWxzZSxcbiAgICAgICAgaXNPcHRpb25hbDogZmFsc2UsXG4gICAgICAgIGlzVGl0bGU6IGZhbHNlLFxuICAgICAgICBuZXh0UXVlc3Rpb246IG51bGwsXG4gICAgICAgIGFsbG93ZWRGaWxlRXh0ZW5zaW9uczogbnVsbCxcbiAgICAgICAgcXVlc3Rpb25OdW1iZXI6IHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLmdldEVsZW1lbnRzKCkubGVuZ3RoICsgMSxcbiAgICAgICAgb3JkZXI6IHRoaXMuZm9ybUVsZW1lbnRzLmxlbmd0aCArIDEsXG4gICAgICAgIHF1ZXN0aW9uQm9va0lkOiB0aGlzLmJvb2tsZXRJZCxcbiAgICAgICAgZmllbGRzTWV0YTogW10sXG4gICAgICAgIHRyYWNraW5nSWQ6IG51bGwsXG4gICAgICAgIHJlY29yZElkOiBudWxsLFxuICAgICAgICBxYlJlZmVyZW5jZTogbnVsbCxcbiAgICAgICAgcWJSZWZlcmVuY2VRdWVzdGlvbnM6IG51bGwsXG4gICAgICAgIHByaW1hcnlLZXk6IGZhbHNlLFxuICAgICAgICBzdHlsZToge1xuICAgICAgICAgIGxhYmVsQ2xhc3M6IG51bGwsXG4gICAgICAgICAgbGFiZWxTdHlsZTogbnVsbCxcbiAgICAgICAgICBsYWJlbFZhbHVlU3R5bGU6IG51bGwsXG4gICAgICAgICAgaW5wdXRDbGFzczogbnVsbCxcbiAgICAgICAgICBpbnB1dFN0eWxlOiBudWxsLFxuICAgICAgICAgIHNob3dMYWJlbDogdHJ1ZSxcbiAgICAgICAgICBib29rU3R5bGU6IG51bGwsXG4gICAgICAgICAgZGlyZWN0aW9uOiBcImx0clwiLFxuICAgICAgICAgIHF1ZXN0aW9uU3R5bGU6IG51bGwsXG4gICAgICAgIH0sXG4gICAgICAgIHN1YlRleHQ6IHtcbiAgICAgICAgICBlbmRwb2ludDogbnVsbCxcbiAgICAgICAgICB2YXJpYWJsZTogbnVsbCxcbiAgICAgICAgICBmaWVsZDogbnVsbCxcbiAgICAgICAgICBkZWZhdWx0RmllbGQ6IG51bGwsXG4gICAgICAgICAgc291cmNlUXVlc3Rpb25JZDogbnVsbCxcbiAgICAgICAgICB2YWx1ZUZpZWxkOiBudWxsLFxuICAgICAgICAgIGxhYmVsRmllbGQ6IG51bGwsXG4gICAgICAgICAgaXNEZXBlbmRlbnRGaWVsZDogZmFsc2UsXG4gICAgICAgICAgZGVwZW5kZW50VmFsdWU6IG51bGwsXG4gICAgICAgICAgcXVlcnlGaWVsZDogbnVsbCxcbiAgICAgICAgICBxdWVyeVZhbHVlOiBudWxsLFxuICAgICAgICAgIHF1ZXJ5VmFsdWVSZWZlcmVuY2U6IG51bGwsXG4gICAgICAgICAgdW5pcXVlS2V5OiBudWxsLFxuICAgICAgICB9LFxuICAgICAgICBpbWFnZURhdGE6IG51bGwsXG4gICAgICAgIGJvb2xlYW46IGZhbHNlLFxuICAgICAgICBvcHRpb25zOlxuICAgICAgICAgIHR5cGUgPT09IFwiRHJvcGRvd25cIiB8fCB0eXBlID09PSBcIlRhYmxlQ29sdW1uXCIgfHwgdHlwZSA9PT0gXCJSYWRpb1wiIHx8IHR5cGUgPT09IFwiQ2hlY2tib3hcIlxuICAgICAgICAgICAgPyBbXVxuICAgICAgICAgICAgOiBudWxsLFxuICAgICAgICBpbWFnZVNpemU6IHR5cGUgPT09IFwiSW1hZ2VcIiA/IHsgd2lkdGg6IDE1MCwgaGVpZ2h0OiAxNTAgfSA6IG51bGwsXG4gICAgICAgIHRhYmxlQ29uZmlnOlxuICAgICAgICAgIHR5cGUgPT09IFwiVGFibGVcIlxuICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgaXNOb3NJbmRpY2F0b3I6IHRydWUsXG4gICAgICAgICAgICAgICAgYWRkSW5saW5lUmVjb3JkOiB0cnVlLFxuICAgICAgICAgICAgICAgIGlzUGFnaW5hdGlvbjogdHJ1ZSxcbiAgICAgICAgICAgICAgICBhY3Rpb25CdXR0b246IHRydWUsXG4gICAgICAgICAgICAgICAgaXNEZWxldGVSb3c6IHRydWUsXG4gICAgICAgICAgICAgICAgaXNFZGl0Um93OiB0cnVlLFxuICAgICAgICAgICAgICAgIHNlYXJjaEJhcjogdHJ1ZSxcbiAgICAgICAgICAgICAgICBpc0J1dHRvbnM6IHRydWUsXG4gICAgICAgICAgICAgICAgaXRlbXNQZXJQYWdlOiAxMCxcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgOiBudWxsLFxuICAgICAgfTtcbiAgICAgIHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLmFkZEVsZW1lbnQobmV3RWxlbWVudCk7XG4gICAgICB0aGlzLmZvcm1FbGVtZW50cyA9IHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLmdldEVsZW1lbnRzKCk7XG4gICAgICAvLyBTS1MxOU1BUjI1IGZpZWxkc21ldGEgY2hlY2tcbiAgICAgIHRoaXMuZm9ybUVsZW1lbnRzID0gdGhpcy51cGRhdGVUYWJsZUZpZWxkc01ldGEodGhpcy5mb3JtRWxlbWVudHMpO1xuICAgICAgdGhpcy5hZGRUYWJsZSA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgLy8gUmVtb3ZlIGFuIGVsZW1lbnQgYnkgaW5kZXhcbiAgcmVtb3ZlRWxlbWVudChmaWVsZDogYW55LCBpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UucmVtb3ZlRWxlbWVudENvbXBvbmVudChmaWVsZC5pZCk7XG4gICAgdGhpcy5mb3JtRWxlbWVudHMgPSB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5nZXRFbGVtZW50cygpO1xuICAgIC8vIFNLUzE5TUFSMjUgZmllbGRzbWV0YSBjaGVja1xuICAgIHRoaXMuZm9ybUVsZW1lbnRzID0gdGhpcy51cGRhdGVUYWJsZUZpZWxkc01ldGEodGhpcy5mb3JtRWxlbWVudHMpO1xuICB9XG5cbiAgb25EcmFnU3RhcnQoZXZlbnQ6IERyYWdFdmVudCwgaW5kZXg6IG51bWJlcikge1xuICAgIHRoaXMuZHJhZ2dlZEluZGV4ID0gaW5kZXg7XG4gICAgZXZlbnQuZGF0YVRyYW5zZmVyPy5zZXREYXRhKFwidGV4dC9wbGFpblwiLCBpbmRleC50b1N0cmluZygpKTtcbiAgfVxuXG4gIC8vIEFsbG93IGRyb3BwaW5nIGJ5IHByZXZlbnRpbmcgZGVmYXVsdFxuICBvbkRyYWdPdmVyKGV2ZW50OiBEcmFnRXZlbnQsIGluZGV4OiBudW1iZXIpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9XG5cbiAgLy8gSGFuZGxlIGRyb3AgZXZlbnRcbiAgb25Ecm9wKGV2ZW50OiBEcmFnRXZlbnQsIGRyb3BJbmRleDogbnVtYmVyKSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIGlmICh0aGlzLmRyYWdnZWRJbmRleCA9PT0gbnVsbCB8fCB0aGlzLmRyYWdnZWRJbmRleCA9PT0gZHJvcEluZGV4KSByZXR1cm47XG5cbiAgICBjb25zdCBkcmFnZ2VkSXRlbSA9IHRoaXMuZm9ybUVsZW1lbnRzW3RoaXMuZHJhZ2dlZEluZGV4XTtcblxuICAgIC8vIFJlbW92ZSBkcmFnZ2VkIGl0ZW0gZnJvbSBvbGQgcG9zaXRpb24gYW5kIGluc2VydCBpdCBpbiBuZXcgcG9zaXRpb25cbiAgICB0aGlzLmZvcm1FbGVtZW50cy5zcGxpY2UodGhpcy5kcmFnZ2VkSW5kZXgsIDEpO1xuICAgIHRoaXMuZm9ybUVsZW1lbnRzLnNwbGljZShkcm9wSW5kZXgsIDAsIGRyYWdnZWRJdGVtKTtcblxuICAgIC8vQVAtMjhNQVIyNSBVcGRhdGUgcXVlc3Rpb25OdW1iZXIgZHluYW1pY2FsbHkgYmFzZWQgb24gbmV3IG9yZGVyXG4gICAgdGhpcy5mb3JtRWxlbWVudHMuZm9yRWFjaCgoZWxlbWVudCwgaW5kZXgpID0+IHtcbiAgICAgIGVsZW1lbnQucXVlc3Rpb25OdW1iZXIgPSBpbmRleCArIDE7XG4gICAgfSk7XG5cbiAgICAvLyBSZXNldCBkcmFnZ2VkIGluZGV4XG4gICAgdGhpcy5kcmFnZ2VkSW5kZXggPSBudWxsO1xuXG4gICAgLy8gTm90aWZ5IHNlcnZpY2UgYWJvdXQgdGhlIHVwZGF0ZVxuICAgIHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLnVwZGF0ZUVsZW1lbnRzT3JkZXIodGhpcy5mb3JtRWxlbWVudHMpO1xuICB9XG5cbiAgdG9nZ2xlQm9vbGVhbihmaWVsZDogYW55KTogdm9pZCB7XG4gICAgZmllbGQuYm9vbGVhbiA9ICFmaWVsZC5ib29sZWFuO1xuICB9XG4gIGdldEJhc2VTdHlsZXMoZmllbGQ6IGFueSwgaW5jbHVkZUJvcmRlclN0eWxlOiBib29sZWFuID0gZmFsc2UpOiBhbnkge1xuICAgIGNvbnN0IHN0eWxlczogYW55ID0ge1xuICAgICAgXCJmb250LWZhbWlseVwiOiBmaWVsZD8uZm9udCB8fCBcIkhlbHZldGljYSBOZXVlXCIsXG4gICAgICBcImZvbnQtd2VpZ2h0XCI6IGZpZWxkPy5mb250V2VpZ2h0IHx8IFwiNDAwXCIsXG4gICAgICBcImZvbnQtc2l6ZVwiOiBmaWVsZD8uZm9udFNpemUgfHwgXCIxNHB4XCIsXG4gICAgICBcIndpZHRoXCI6IGZpZWxkPy5zaXplID8gYCR7KGZpZWxkLnNpemUgLyAxMikgKiAxMDB9JWAgOiBcIjEwMCVcIixcbiAgICAgIFwidGV4dC1hbGlnblwiOiBmaWVsZD8udGV4dEFsaWduIHx8IFwibGVmdFwiLFxuICAgICAgXCJib3JkZXItcmFkaXVzXCI6IFwiNXB4XCIsXG4gICAgICBcImJvcmRlci13aWR0aFwiOiBmaWVsZD8ubGluZVdpZHRoID8gYCR7ZmllbGQubGluZVdpZHRofXB4YCA6IFwiMXB4XCIsXG4gICAgICBcImNvbG9yXCI6IGZpZWxkPy5mb250Q29sb3IgfHwgXCIjMDAwMDAwXCIsXG4gICAgICBcIm1hcmdpbi10b3BcIjogZmllbGQ/LnBhZGRpbmdUb3AgPyBgJHtmaWVsZC5wYWRkaW5nVG9wfXB4YCA6IFwiMHB4XCIsXG4gICAgICBcIm1hcmdpbi1ib3R0b21cIjogZmllbGQ/LnBhZGRpbmdCb3R0b20gPyBgJHtmaWVsZC5wYWRkaW5nQm90dG9tfXB4YCA6IFwiMTBweFwiLFxuICAgICAgXCJib3JkZXItY29sb3JcIjogZmllbGQ/LmNvbG9yIHx8IFwiI0VGRjhGRlwiLFxuICAgIH07XG4gICAgaWYgKGluY2x1ZGVCb3JkZXJTdHlsZSkge1xuICAgICAgc3R5bGVzW1wiYm9yZGVyLXN0eWxlXCJdID0gZmllbGQ/LmxpbmVTdHlsZT8udG9Mb3dlckNhc2UoKSB8fCBcInNvbGlkXCI7XG4gICAgfVxuICAgIHJldHVybiBzdHlsZXM7XG4gIH1cblxuICBnZXRGb250U3R5bGVzKGZpZWxkOiBhbnkpOiBhbnkge1xuICAgIHJldHVybiB0aGlzLmdldEJhc2VTdHlsZXMoZmllbGQsIGZhbHNlKTtcbiAgfVxuXG4gIGdldExpbmVTdHlsZXMoZmllbGQ6IGFueSk6IGFueSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0QmFzZVN0eWxlcyhmaWVsZCwgdHJ1ZSk7XG4gIH1cblxuICAvLyBTS1MxM01BUjI1IHRhYmxlIHBvcHVwIGNvbmZvcm1hdGlvbiBiYXNlZCBlbGVtZW50IGFkZFxuICBvbkNsb3NlKCkge1xuICAgIHRoaXMuaXNTZWxlY3RUYWJsZVBvcHVwID0gZmFsc2U7XG4gICAgdGhpcy5hZGRUYWJsZSA9IGZhbHNlO1xuICAgIHRoaXMuYWRkRWxlbWVudCh0aGlzLmN1cnJlbnRUeXBlKTtcbiAgfVxuICAvLyBTS1MxM01BUjI1IGNvbHVtbiBlbGVtZW50IGFkZCBpbnNpZGUgYSB0YWJsZVxuICBhZGRPblRhYmxlKCkge1xuICAgIHRoaXMuYWRkVGFibGUgPSB0cnVlO1xuICAgIHRoaXMuaXNTZWxlY3RUYWJsZVBvcHVwID0gZmFsc2U7XG4gICAgY29uc3QgZWxlbWVudHMgPSBbLi4udGhpcy5mb3JtQnVpbGRlclNlcnZpY2UuZ2V0RWxlbWVudHMoKV07XG5cbiAgICAvLyBGaW5kIHRoZSBlbGVtZW50IGFuZCB1cGRhdGUgaXRzIGNvbHVtbnNcbiAgICBjb25zdCBpbmRleCA9IGVsZW1lbnRzLmZpbmRJbmRleCgoZWwpID0+IGVsLmlkID09PSB0aGlzLnNlbGVjdGVkRWxlbWVudC5pZCk7XG4gICAgY29uc3Qgcm93TnVtID0gdGhpcy5mb3JtRWxlbWVudHNbaW5kZXhdLmZpZWxkc01ldGFcbiAgICAgID8gdGhpcy5mb3JtRWxlbWVudHNbaW5kZXhdLmZpZWxkc01ldGE/Lmxlbmd0aFxuICAgICAgOiAwO1xuICAgIGNvbnN0IHVuaXF1ZV9pZCA9IHRoaXMuZ2VuZXJhdGVVaUlkKCk7XG4gICAgY29uc3QgdGFibGVFbGVtZW50ID0ge1xuICAgICAgbGFiZWw6IGBIRUFERVIgTEFCRUwgJHtyb3dOdW19YCxcbiAgICAgIGZpZWxkTmFtZTogYEZJRUxEIE5BTUUgJHtyb3dOdW19YCxcbiAgICAgIHR5cGU6IHRoaXMuY3VycmVudFR5cGUsXG4gICAgICBpZDogdW5pcXVlX2lkLFxuICAgIH07XG4gICAgdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UuYWRkVGFibGVFbGVtZW50KFxuICAgICAgdGFibGVFbGVtZW50LFxuICAgICAgdGhpcy5zZWxlY3RlZEZpZWxkSW5kZXhcbiAgICApO1xuICAgIHRoaXMuZm9ybUVsZW1lbnRzID0gdGhpcy5mb3JtQnVpbGRlclNlcnZpY2UuZ2V0RWxlbWVudHMoKTtcbiAgICAvLyBTS1MxOU1BUjI1IGZpZWxkc21ldGEgY2hlY2tpbmdcbiAgICB0aGlzLmZvcm1FbGVtZW50cyA9IHRoaXMudXBkYXRlVGFibGVGaWVsZHNNZXRhKHRoaXMuZm9ybUVsZW1lbnRzKTtcbiAgfVxuICB1cGRhdGVUYWJsZUZpZWxkc01ldGEoZWxlbWVudHM6IGFueVtdKTogYW55W10ge1xuICAgIHJldHVybiBlbGVtZW50cy5tYXAoKGVsZSkgPT4ge1xuICAgICAgaWYgKGVsZS50eXBlID09PSBcIlRhYmxlXCIpIHtcbiAgICAgICAgZWxlLmZpZWxkc01ldGEgPVxuICAgICAgICAgIHR5cGVvZiBlbGUuZmllbGRzTWV0YSA9PT0gXCJzdHJpbmdcIlxuICAgICAgICAgICAgPyBlbGUuZmllbGRzTWV0YVxuICAgICAgICAgICAgOiBKU09OLnN0cmluZ2lmeShlbGUuZmllbGRzTWV0YSB8fCBbXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZWxlO1xuICAgIH0pO1xuICB9ICBcbiAgY29sdW1uU2VsZWN0ZWQoZXZlbnQ6IGFueSkge1xuICAgIC8vIFNLUzE5TUFSMjUgdGFibGUgY29sdW1uIHVwZGF0ZVxuICAgIHRoaXMuZm9ybUVsZW1lbnRzLmZvckVhY2goKGVsZTogYW55LCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICBpZiAoZWxlLnR5cGUgPT09ICdUYWJsZScgJiYgQXJyYXkuaXNBcnJheShlbGUuZmllbGRzTWV0YSkpIHtcbiAgICAgICAgY29uc3QgbWF0Y2hlZEZpZWxkID0gZWxlLmZpZWxkc01ldGEuZmluZChcbiAgICAgICAgICAoZmllbGQ6IGFueSkgPT4gZmllbGQudW5pcXVlSWRlbnRpZmllciA9PT0gZXZlbnQ/LnVuaXF1ZUlkZW50aWZpZXJcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKG1hdGNoZWRGaWVsZCkge1xuICAgICAgICAgIHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLnNldFNlbGVjdGVkRWxlbWVudChpbmRleCk7XG4gICAgICAgICAgdGhpcy5zZWxlY3RlZEZpZWxkSW5kZXggPSBpbmRleFxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5mb3JtQnVpbGRlclNlcnZpY2Uuc2V0U2VsZWN0ZWRUYWJsZUVsZW1lbnQoXG4gICAgICB0aGlzLnNlbGVjdGVkRmllbGRJbmRleCxcbiAgICAgIGV2ZW50XG4gICAgKTtcbiAgICB0aGlzLnNlbGVjdGVkQ29sdW1uID0gZXZlbnQ/LnVuaXF1ZUlkZW50aWZpZXJcbiAgfVxuICByZW1vdmVDb2x1bW4oZXZlbnQ6IGFueSkge1xuICAgIHRoaXMuZm9ybUJ1aWxkZXJTZXJ2aWNlLnJlbW92ZVNlbGVjdGVkVGFibGVFbGVtZW50KFxuICAgICAgdGhpcy5zZWxlY3RlZEZpZWxkSW5kZXgsXG4gICAgICBldmVudFxuICAgICk7XG4gICAgdGhpcy5zZWxlY3RlZENvbHVtbiA9IG51bGxcbiAgfVxuXG4gIC8vIFNLUzI1TUFSMjUgaW1hZ2UgYWRkXG4gIGFzeW5jIGZpbGVDaGFuZ2VFdmVudChpbmRleDogYW55LCBldmVudDogYW55KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZmlsZSA9IGV2ZW50LnRhcmdldC5maWxlc1swXTtcbiAgICBpZiAoZmlsZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgaW1hZ2VEYXRhID0gYXdhaXQgdGhpcy5yZWFkRmlsZUFzRGF0YVVSTChmaWxlKTtcbiAgICAgICAgdGhpcy5mb3JtRWxlbWVudHNbaW5kZXhdLmltYWdlRGF0YSA9IGltYWdlRGF0YTtcbiAgICAgICAgdGhpcy5mb3JtRWxlbWVudHNbaW5kZXhdLm9yZ0ltYWdlRGF0YSA9IGltYWdlRGF0YTtcbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBsb2dvIHNpemUgaWYgbm90IGFscmVhZHkgc2V0XG4gICAgICAgIGlmICghdGhpcy5mb3JtRWxlbWVudHNbaW5kZXhdLmltYWdlU2l6ZSkge1xuICAgICAgICAgIHRoaXMuZm9ybUVsZW1lbnRzW2luZGV4XS5pbWFnZVNpemUgPSB7IHdpZHRoOiAxNTAsIGhlaWdodDogMTUwIH07XG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCB0aGlzLmZvcm1CdWlsZGVyU2VydmljZS5lbGVtZW50VXBkYXRlKFxuICAgICAgICAgIGluZGV4LFxuICAgICAgICAgIHRoaXMuZm9ybUVsZW1lbnRzW2luZGV4XVxuICAgICAgICApO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHJlYWRpbmcgZmlsZTpcIiwgZXJyb3IpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVhZEZpbGVBc0RhdGFVUkwoZmlsZTogRmlsZSk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgICByZWFkZXIub25sb2FkID0gKCkgPT4gcmVzb2x2ZShyZWFkZXIucmVzdWx0IGFzIHN0cmluZyk7XG4gICAgICByZWFkZXIub25lcnJvciA9IChlcnJvcikgPT4gcmVqZWN0KGVycm9yKTtcbiAgICAgIHJlYWRlci5yZWFkQXNEYXRhVVJMKGZpbGUpO1xuICAgIH0pO1xuICB9XG4gIC8vIFNLUzJBUFIyNSBkaXNhYmxlZCBlbGVtZW50XG4gIC8vIGlzRWxlbWVudERpc2FibGVkKGVsZW1lbnRUeXBlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgLy8gICBpZih0aGlzLnNlbGVjdGVkRWxlbWVudCl7XG4gIC8vICAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuZWxlbWVudERpc2FibGVkQXJyYXlbdGhpcy5zZWxlY3RlZEVsZW1lbnQudHlwZV1cbiAgLy8gICAgIGlmKGVsZW1lbnRzKXtcbiAgLy8gICAgICAgcmV0dXJuIGVsZW1lbnRzLmluY2x1ZGVzKGVsZW1lbnRUeXBlKTtcbiAgLy8gICAgIH1cbiAgLy8gICB9XG4gIC8vICAgcmV0dXJuIGZhbHNlO1xuICAvLyB9XG59XG4iLCI8IS0tIEFQIDIySkFOMjUgLSBmb3JtIHByZXZpZXcgYW5kIEFsbCBmb3JtIGVsZW1lbnRzIC0tPlxuPCEtLSBBUCAyNUZFQjI1IC0gQWxsIGVsZW1lbnRzIHVwZGF0ZSAtLT5cbjxkaXYgY2xhc3M9XCJjZW50ZXItZnJhbWVcIj5cbiAgPCEtLSBGb3JtIEJ1aWxkZXIgU2VjdGlvbiBBbGwgRWxlbWVudHMgLS0+XG4gIDxkaXYgY2xhc3M9XCJmb3JtLWJ1aWxkZXJcIj5cbiAgICA8IS0tIEJhc2ljIEVsZW1lbnRzIFRvZ2dsZSAtLT5cbiAgICA8ZGl2IGNsYXNzPVwidG9nZ2xlLWhlYWRlclwiIChjbGljayk9XCJ0b2dnbGVTZWN0aW9uKCdiYXNpYycpXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiaGVhZC1lbGVtZW50c1wiPkJhc2ljIEVsZW1lbnRzPC9kaXY+XG4gICAgICA8aW1nIFtzcmNdPVwic2VjdGlvbnMuYmFzaWMgPyAnLi4vYXNzZXRzL2ljb25zL2Fycm93LWRvd24uc3ZnJyA6ICcuLi9hc3NldHMvaWNvbnMvYXJyb3ctcmlnaHQuc3ZnJ1wiXG4gICAgICAgIGFsdD1cIlRvZ2dsZSBBcnJvd1wiIGNsYXNzPVwiYXJyb3ctaWNvblwiPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiAqbmdJZj1cInNlY3Rpb25zLmJhc2ljXCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBlbGVtZW50IG9mIGJhc2ljRWxlbWVudHNcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImVsZW1lbnRcIiAoY2xpY2spPVwiYWRkRWxlbWVudChlbGVtZW50LnR5cGUpXCI+XG4gICAgICAgICAgPGltZyBzcmM9XCIuLi9hc3NldHMvaWNvbnMve3sgZWxlbWVudC5pbWcgfX0uc3ZnXCIgY2xhc3M9XCJlbGVtZW50LWljb25cIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiaG92ZXItbGFiZWxcIj57eyBlbGVtZW50LmxhYmVsIH19PC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImRyYWctZG90c1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRvdFwiICpuZ0Zvcj1cImxldCBkb3Qgb2YgZG90c1wiPjwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBBZHZhbmNlZCBFbGVtZW50cyBUb2dnbGUgLS0+XG4gICAgPGRpdiBjbGFzcz1cInRvZ2dsZS1oZWFkZXJcIiAoY2xpY2spPVwidG9nZ2xlU2VjdGlvbignYWR2YW5jZWQnKVwiPlxuICAgICAgPGRpdiBjbGFzcz1cImhlYWQtZWxlbWVudHNcIj5BZHZhbmNlZCBFbGVtZW50czwvZGl2PlxuICAgICAgPGltZyBbc3JjXT1cInNlY3Rpb25zLmFkdmFuY2VkID8gJy4uL2Fzc2V0cy9pY29ucy9hcnJvdy1kb3duLnN2ZycgOiAnLi4vYXNzZXRzL2ljb25zL2Fycm93LXJpZ2h0LnN2ZydcIlxuICAgICAgICBhbHQ9XCJUb2dnbGUgQXJyb3dcIiBjbGFzcz1cImFycm93LWljb25cIj5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgKm5nSWY9XCJzZWN0aW9ucy5hZHZhbmNlZFwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgZWxlbWVudCBvZiBhZHZhbmNlZEVsZW1lbnRzXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJlbGVtZW50XCIgKGNsaWNrKT1cImFkZEVsZW1lbnQoZWxlbWVudC50eXBlKVwiPlxuICAgICAgICAgIDxpbWcgc3JjPVwiLi4vYXNzZXRzL2ljb25zL3t7IGVsZW1lbnQuaW1nIH19LnN2Z1wiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJob3Zlci1sYWJlbFwiPnt7IGVsZW1lbnQubGFiZWwgfX08L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZHJhZy1kb3RzXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZG90XCIgKm5nRm9yPVwibGV0IGRvdCBvZiBkb3RzXCI+PC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG4gICA8IS0tIEFQLTA4QVBSMjUgQWRkIFRlbXBsYXRlcyBDb21wb25lbnQgLS0+XG4gICAgPCEtLSA8YXBwLXRlbXBsYXRlcyAodGVtcGxhdGVTZWxlY3RlZCk9XCJvblRlbXBsYXRlU2VsZWN0ZWQoJGV2ZW50KVwiPjwvYXBwLXRlbXBsYXRlcz4gLS0+XG5cbiAgICA8IS0tIFNLUzEwTUFSMjUgZm9vdGVyIHZlcnNpb24gc2hvdyAtLT5cbiAgICA8ZGl2IGNsYXNzPVwic3RpY2t5LWZvb3Rlci12ZXJzaW9uXCI+XG4gICAgICB7e3ZlcnNpb259fVxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbiAgPCEtLSBBUC0yN01BUjI1IFJlbW92ZSBDREsgZHJhZyBhbmQgZHJvcCByZXBsYWNlIGRyYWdnYWJsZSBmdW5jdGlvbiAgLS0+XG4gIDxkaXYgY2xhc3M9XCJmb3JtLXByZXZpZXdcIj5cbiAgICA8IS0tIEFQLTEwTUFSMjUgSGVhZGluZyAtLT5cbiAgICA8ZGl2IGNsYXNzPVwiZmllbGQtY29udGFpbmVyXCJcbiAgICAgIHN0eWxlPVwid2lkdGg6IDEwMCU7YmFja2dyb3VuZC1jb2xvcjogI0VGRjhGRjsgYm9yZGVyOiAxcHggc29saWQgI0U2RjNGRjtkaXNwbGF5OiBmbGV4O2p1c3RpZnktY29udGVudDogY2VudGVyO21hcmdpbi1ib3R0b206MTBweFwiXG4gICAgICBbY2xhc3MuaGlnaGxpZ2h0XT1cImlzSGVhZGVyU2VsZWN0XCJcbiAgICAgIChjbGljayk9XCJzZWxlY3RIZWFkaW5nKCdIZWFkZXInKVwiPlxuICAgICAgPGRpdiBjbGFzcz1cImxhYmVsLWNvbnRhaW5lclwiIHN0eWxlPVwicGFkZGluZzogMTBweDtcIj5cbiAgICAgICAgPGRpdiAqbmdJZj1cImJvb2s/LnJlY29yZHNcIj5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwiYm9vay5yZWNvcmRzWzBdLnRpdGxlID09ICcnXCIgc3R5bGU9XCJjb2xvcjojM2Y0YTUyNWNcIj5IZWFkaW5nPC9kaXY+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cImJvb2sucmVjb3Jkc1swXS50aXRsZSAhPT0gJydcIj57e2Jvb2sucmVjb3Jkc1swXS50aXRsZX19PC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+ICAgIFxuICAgIDwvZGl2PlxuXG4gICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgZmllbGQgb2YgZm9ybUVsZW1lbnRzOyBsZXQgaSA9IGluZGV4XCIgZ2V0UHJvcGVydGllcygpLmVsZW1lbnRQcm9wcz5cblxuICAgICAgPCEtLSBUZXh0Qm94IC0tPlxuICAgICAgPGRpdiAqbmdJZj1cImZpZWxkLnR5cGUgPT09ICdUZXh0J1wiIGNsYXNzPVwiZmllbGQtY29udGFpbmVyXCIgKGNsaWNrKT1cInNlbGVjdEVsZW1lbnQoaSlcIlxuICAgICAgICBbbmdTdHlsZV09XCJnZXRGb250U3R5bGVzKGZpZWxkKVwiIFtjbGFzcy5oaWdobGlnaHRdPVwic2VsZWN0ZWRGaWVsZEluZGV4ID09PSBpXCIgZHJhZ2dhYmxlPVwidHJ1ZVwiXG4gICAgICAgIChkcmFnc3RhcnQpPVwib25EcmFnU3RhcnQoJGV2ZW50LCBpKVwiIChkcmFnb3Zlcik9XCJvbkRyYWdPdmVyKCRldmVudCwgaSlcIiAoZHJvcCk9XCJvbkRyb3AoJGV2ZW50LCBpKVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtd3JhcHBlclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1jb250ZW50XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibGFiZWwtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgPGxhYmVsIFtjbGFzcy5yZXF1aXJlZF09XCJmaWVsZC5pc09wdGlvbmFsXCIgKm5nSWY9XCJmaWVsZC5zdHlsZT8uc2hvd0xhYmVsICE9PSBmYWxzZVwiPnt7XG4gICAgICAgICAgICAgICAgICBmaWVsZC5xdWVzdGlvblRleHQgPyBmaWVsZC5xdWVzdGlvblRleHQgOiAnTGFiZWwnIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0b3AtcmlnaHRcIj5cbiAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi4uL2Fzc2V0cy9pY29ucy9kcmFnLWRvdHMuc3ZnXCIgYWx0PVwiRHJhZ1wiIGNsYXNzPVwiZHJhZy1kb3RcIiAvPlxuXG4gICAgICAgICAgICAgICAgPGltZyBzcmM9XCIuLi9hc3NldHMvaWNvbnMvVHJhc2guc3ZnXCIgKGNsaWNrKT1cInJlbW92ZUVsZW1lbnQoZmllbGQsIGkpXCIgY2xhc3M9XCJkZWxldGUtaWNvblwiIC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImN1c3RvbS1pbnB1dFwiIFtwbGFjZWhvbGRlcl09XCJmaWVsZC5xdWVzdGlvbiB8fCAnRW50ZXIgdGV4dCdcIlxuICAgICAgICAgICAgICBbcmVhZG9ubHldPVwiZmllbGQuaXNSZWFkT25seVwiIFtjbGFzcy5oaWRkZW5dPVwiZmllbGQuaXNIaWRkZW5cIlxuICAgICAgICAgICAgICBbdmFsdWVdPVwiZmllbGQuZGVmYXVsdFZhbHVlID8gZmllbGQuZGVmYXVsdFZhbHVlIDogJycgXCIgLz5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgIDwhLS0gTVNNLTA5SlVMMjUgSWNvbi1zZWxlY3RpciBFbGVtZW50IC0tPlxuICAgICAgICAgPGRpdiAqbmdJZj1cImZpZWxkLnR5cGUgPT09ICdJY29uJ1wiIGNsYXNzPVwiZmllbGQtY29udGFpbmVyXCIgKGNsaWNrKT1cInNlbGVjdEVsZW1lbnQoaSlcIlxuICAgICAgICBbbmdTdHlsZV09XCJnZXRGb250U3R5bGVzKGZpZWxkKVwiIFtjbGFzcy5oaWdobGlnaHRdPVwic2VsZWN0ZWRGaWVsZEluZGV4ID09PSBpXCIgZHJhZ2dhYmxlPVwidHJ1ZVwiXG4gICAgICAgIChkcmFnc3RhcnQpPVwib25EcmFnU3RhcnQoJGV2ZW50LCBpKVwiIChkcmFnb3Zlcik9XCJvbkRyYWdPdmVyKCRldmVudCwgaSlcIiAoZHJvcCk9XCJvbkRyb3AoJGV2ZW50LCBpKVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtd3JhcHBlclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1jb250ZW50XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibGFiZWwtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgPGxhYmVsIFtjbGFzcy5yZXF1aXJlZF09XCJmaWVsZC5pc1JlcXVpcmVkXCIgKm5nSWY9XCJmaWVsZC5zdHlsZT8uc2hvd0xhYmVsICE9PSBmYWxzZVwiPnt7XG4gICAgICAgICAgICAgICAgICBmaWVsZC5xdWVzdGlvblRleHQgPyBmaWVsZC5xdWVzdGlvblRleHQgOiAnQ2hvb3NlIEljb24nXG4gICAgICAgICAgICAgICAgICB9fTwvbGFiZWw+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidG9wLXJpZ2h0XCI+XG4gICAgICAgICAgICAgICAgPGltZyBzcmM9XCIuLi9hc3NldHMvaWNvbnMvZHJhZy1kb3RzLnN2Z1wiIGFsdD1cIkRyYWdcIiBjbGFzcz1cImRyYWctZG90XCIgLz5cbiAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi4uL2Fzc2V0cy9pY29ucy9UcmFzaC5zdmdcIiAoY2xpY2spPVwicmVtb3ZlRWxlbWVudChmaWVsZCwgaSlcIiBjbGFzcz1cImRlbGV0ZS1pY29uXCIgLz5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2hvb3NlLWljb24tcGxhY2Vob2xkZXJcIj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBBUC0xOU1BUjI1IExpbmUgRWxlbWVudCAtLT5cbiAgICAgIDxkaXYgKm5nSWY9XCJmaWVsZC50eXBlID09PSAnTGluZSdcIiBjbGFzcz1cImxpbmUtZmllbGRcIiAoY2xpY2spPVwic2VsZWN0RWxlbWVudChpKVwiXG4gICAgICAgIFtjbGFzcy5oaWdobGlnaHRdPVwic2VsZWN0ZWRGaWVsZEluZGV4ID09PSBpXCIgZHJhZ2dhYmxlPVwidHJ1ZVwiIChkcmFnc3RhcnQpPVwib25EcmFnU3RhcnQoJGV2ZW50LCBpKVwiXG4gICAgICAgIChkcmFnb3Zlcik9XCJvbkRyYWdPdmVyKCRldmVudCwgaSlcIiAoZHJvcCk9XCJvbkRyb3AoJGV2ZW50LCBpKVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwibGluZS1lbGVtZW50XCI+XG4gICAgICAgICAgPGRpdj48L2Rpdj5cbiAgICAgICAgICA8aW1nIHNyYz1cIi4uL2Fzc2V0cy9pY29ucy9UcmFzaC5zdmdcIiAoY2xpY2spPVwicmVtb3ZlRWxlbWVudChmaWVsZCwgaSlcIiBjbGFzcz1cImRlbGV0ZS1pY29uXCIgLz5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxociBjbGFzcz1cImN1c3RvbS1saW5lXCIgc3R5bGU9XCJkaXNwbGF5OiBpbmxpbmUtZmxleFwiIFtuZ1N0eWxlXT1cImdldExpbmVTdHlsZXMoZmllbGQpXCIgLz5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tU0tTMjVNQVIyNSBJbWFnZSBVcGxvYWQgRWxlbWVudCAtLT5cbiAgICAgIDxkaXYgKm5nSWY9XCJmaWVsZC50eXBlID09PSAnSW1hZ2UnXCIgY2xhc3M9XCJmaWVsZC1jb250YWluZXJcIiAoY2xpY2spPVwic2VsZWN0RWxlbWVudChpKVwiXG4gICAgICAgIFtjbGFzcy5oaWdobGlnaHRdPVwic2VsZWN0ZWRGaWVsZEluZGV4ID09PSBpXCIgZHJhZ2dhYmxlPVwidHJ1ZVwiIChkcmFnc3RhcnQpPVwib25EcmFnU3RhcnQoJGV2ZW50LCBpKVwiXG4gICAgICAgIChkcmFnb3Zlcik9XCJvbkRyYWdPdmVyKCRldmVudCwgaSlcIiAoZHJvcCk9XCJvbkRyb3AoJGV2ZW50LCBpKVwiIFtuZ1N0eWxlXT1cImdldEZvbnRTdHlsZXMoZmllbGQpXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC13cmFwcGVyXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWNvbnRlbnRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsYWJlbC1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICA8bGFiZWwgW2NsYXNzLnJlcXVpcmVkXT1cImZpZWxkLmlzT3B0aW9uYWxcIiAqbmdJZj1cImZpZWxkLnN0eWxlPy5zaG93TGFiZWwgIT09IGZhbHNlXCI+e3tcbiAgICAgICAgICAgICAgICAgIGZpZWxkLnF1ZXN0aW9uVGV4dCA/IGZpZWxkLnF1ZXN0aW9uVGV4dCA6ICdVcGxvYWQgSW1hZ2UnIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0b3AtcmlnaHRcIj5cbiAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi4uL2Fzc2V0cy9pY29ucy9kcmFnLWRvdHMuc3ZnXCIgYWx0PVwiRHJhZ1wiIGNsYXNzPVwiZHJhZy1kb3RcIiAvPlxuICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiLi4vYXNzZXRzL2ljb25zL1RyYXNoLnN2Z1wiIChjbGljayk9XCJyZW1vdmVFbGVtZW50KGZpZWxkLCBpKVwiIGNsYXNzPVwiZGVsZXRlLWljb25cIiAvPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxvZ28tY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgPCEtLSBMb2dvIHByZXZpZXcgYXJlYSAtLT5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibG9nby1wcmV2aWV3XCIgKm5nSWY9XCJmaWVsZC5pbWFnZURhdGFcIj5cbiAgICAgICAgICAgICAgICAgIDxpbWcgW3NyY109XCJmaWVsZC5pbWFnZURhdGFcIiAvPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPCEtLSBVcGxvYWQgYnV0dG9uIC0tPlxuICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCIhZmllbGQuaW1hZ2VEYXRhXCIgY2xhc3M9XCJsb2dvLXVwbG9hZC1wbGFjZWhvbGRlclwiPlxuICAgICAgICAgICAgICAgICAgPGxhYmVsIGZvcj1cImxvZ28tdXBsb2FkLXt7aX19XCIgY2xhc3M9XCJsb2dvLXVwbG9hZC1sYWJlbFwiPlxuICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi4uL2Fzc2V0cy9pY29ucy9JbWFnZS5zdmdcIiBhbHQ9XCJVcGxvYWRcIiAvPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj5VcGxvYWQgSW1hZ2U8L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJmaWxlXCIgaWQ9XCJsb2dvLXVwbG9hZC17e2l9fVwiIGFjY2VwdD1cImltYWdlLypcIiAoY2hhbmdlKT1cImZpbGVDaGFuZ2VFdmVudChpLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJkaXNwbGF5OiBub25lO1wiIC8+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gU3BhY2UgRWxlbWVudCAtLT5cbiAgICAgIDxkaXYgKm5nSWY9XCJmaWVsZC50eXBlID09PSAnU3BhY2UnXCIgY2xhc3M9XCJmaWVsZC1jb250YWluZXJcIiAoY2xpY2spPVwic2VsZWN0RWxlbWVudChpKVwiXG4gICAgICAgIFtuZ1N0eWxlXT1cImdldEZvbnRTdHlsZXMoZmllbGQpXCIgW2NsYXNzLmhpZ2hsaWdodF09XCJzZWxlY3RlZEZpZWxkSW5kZXggPT09IGlcIiBkcmFnZ2FibGU9XCJ0cnVlXCJcbiAgICAgICAgKGRyYWdzdGFydCk9XCJvbkRyYWdTdGFydCgkZXZlbnQsIGkpXCIgKGRyYWdvdmVyKT1cIm9uRHJhZ092ZXIoJGV2ZW50LCBpKVwiIChkcm9wKT1cIm9uRHJvcCgkZXZlbnQsIGkpXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC13cmFwcGVyXCIgc3R5bGU9XCJoZWlnaHQ6OTNweFwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1jb250ZW50XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibGFiZWwtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgIDxsYWJlbCBbY2xhc3MucmVxdWlyZWRdPVwiZmllbGQuaXNPcHRpb25hbFwiPjwvbGFiZWw+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0b3AtcmlnaHRcIiBzdHlsZT1cIm1hcmdpbjogLTExcHggLTExcHggMCAwO1wiPlxuICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiLi4vYXNzZXRzL2ljb25zL2RyYWctZG90cy5zdmdcIiBhbHQ9XCJEcmFnXCIgY2xhc3M9XCJkcmFnLWRvdFwiIC8+XG4gICAgICAgICAgICAgICAgPGltZyBzcmM9XCIuLi9hc3NldHMvaWNvbnMvVHJhc2guc3ZnXCIgKGNsaWNrKT1cInJlbW92ZUVsZW1lbnQoZmllbGQsIGkpXCIgY2xhc3M9XCJkZWxldGUtaWNvblwiIC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gQm9vbGVhbiBFbGVtZW50IC0tPlxuICAgICAgPGRpdiAqbmdJZj1cImZpZWxkLnR5cGUgPT09ICdCb29sZWFuJ1wiIGNsYXNzPVwiZmllbGQtY29udGFpbmVyXCIgKGNsaWNrKT1cInNlbGVjdEVsZW1lbnQoaSlcIlxuICAgICAgICBbbmdTdHlsZV09XCJnZXRGb250U3R5bGVzKGZpZWxkKVwiIFtjbGFzcy5oaWdobGlnaHRdPVwic2VsZWN0ZWRGaWVsZEluZGV4ID09PSBpXCIgZHJhZ2dhYmxlPVwidHJ1ZVwiXG4gICAgICAgIChkcmFnc3RhcnQpPVwib25EcmFnU3RhcnQoJGV2ZW50LCBpKVwiIChkcmFnb3Zlcik9XCJvbkRyYWdPdmVyKCRldmVudCwgaSlcIiAoZHJvcCk9XCJvbkRyb3AoJGV2ZW50LCBpKVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtd3JhcHBlclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJsYWJlbC1jb250YWluZXJcIj5cbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxsYWJlbCBbY2xhc3MucmVxdWlyZWRdPVwiZmllbGQuaXNPcHRpb25hbFwiICpuZ0lmPVwiZmllbGQuc3R5bGU/LnNob3dMYWJlbCAhPT0gZmFsc2VcIj57eyBmaWVsZC5xdWVzdGlvblRleHRcbiAgICAgICAgICAgICAgICA/IGZpZWxkLnF1ZXN0aW9uVGV4dCA6ICdCb29sZWFuJ319PC9sYWJlbD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRvcC1yaWdodFwiPlxuICAgICAgICAgICAgICA8aW1nIHNyYz1cIi4uL2Fzc2V0cy9pY29ucy9kcmFnLWRvdHMuc3ZnXCIgYWx0PVwiRHJhZ1wiIGNsYXNzPVwiZHJhZy1kb3RcIiAvPlxuXG4gICAgICAgICAgICAgIDxpbWcgc3JjPVwiLi4vYXNzZXRzL2ljb25zL1RyYXNoLnN2Z1wiIChjbGljayk9XCJyZW1vdmVFbGVtZW50KGZpZWxkLCBpKVwiIGNsYXNzPVwiZGVsZXRlLWljb25cIiAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIFtjaGVja2VkXT1cImZpZWxkLmJvb2xlYW5cIiAoY2hhbmdlKT1cInRvZ2dsZUJvb2xlYW4oZmllbGQpXCJcbiAgICAgICAgICAgIFt2YWx1ZV09XCJmaWVsZC5kZWZhdWx0VmFsdWUgPyBmaWVsZC5kZWZhdWx0VmFsdWUgOiAnJ1wiIC8+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gQ2FsZW5kYXIgLS0+XG4gICAgICA8ZGl2ICpuZ0lmPVwiZmllbGQudHlwZSA9PT0gJ0NhbGVuZGFyJ1wiIGNsYXNzPVwiZmllbGQtY29udGFpbmVyXCIgKGNsaWNrKT1cInNlbGVjdEVsZW1lbnQoaSlcIlxuICAgICAgICBbbmdTdHlsZV09XCJnZXRGb250U3R5bGVzKGZpZWxkKVwiIFtjbGFzcy5oaWdobGlnaHRdPVwic2VsZWN0ZWRGaWVsZEluZGV4ID09PSBpXCIgZHJhZ2dhYmxlPVwidHJ1ZVwiXG4gICAgICAgIChkcmFnc3RhcnQpPVwib25EcmFnU3RhcnQoJGV2ZW50LCBpKVwiIChkcmFnb3Zlcik9XCJvbkRyYWdPdmVyKCRldmVudCwgaSlcIiAoZHJvcCk9XCJvbkRyb3AoJGV2ZW50LCBpKVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtd3JhcHBlclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1jb250ZW50XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibGFiZWwtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgPGxhYmVsIFtjbGFzcy5yZXF1aXJlZF09XCJmaWVsZC5pc09wdGlvbmFsXCIgKm5nSWY9XCJmaWVsZC5zdHlsZT8uc2hvd0xhYmVsICE9PSBmYWxzZVwiPnt7XG4gICAgICAgICAgICAgICAgICBmaWVsZC5xdWVzdGlvblRleHQgPyBmaWVsZC5xdWVzdGlvblRleHQgOiAnU2VsZWN0IERhdGUnXG4gICAgICAgICAgICAgICAgICB9fTwvbGFiZWw+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidG9wLXJpZ2h0XCI+XG4gICAgICAgICAgICAgICAgPGltZyBzcmM9XCIuLi9hc3NldHMvaWNvbnMvZHJhZy1kb3RzLnN2Z1wiIGFsdD1cIkRyYWdcIiBjbGFzcz1cImRyYWctZG90XCIgLz5cbiAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi4uL2Fzc2V0cy9pY29ucy9UcmFzaC5zdmdcIiAoY2xpY2spPVwicmVtb3ZlRWxlbWVudChmaWVsZCwgaSlcIiBjbGFzcz1cImRlbGV0ZS1pY29uXCIgLz5cbiAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJkYXRlXCIgY2xhc3M9XCJjdXN0b20taW5wdXRcIiBbcmVhZG9ubHldPVwiZmllbGQuaXNSZWFkT25seVwiIFtjbGFzcy5oaWRkZW5dPVwiZmllbGQuaXNIaWRkZW5cIlxuICAgICAgICAgICAgICBbdmFsdWVdPVwiZmllbGQuZGVmYXVsdFZhbHVlID8gZmllbGQuZGVmYXVsdFZhbHVlIDogJydcIiAvPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIEFQIC0xMk1BUjI1IERhdGUgLS0+XG4gICAgICA8ZGl2ICpuZ0lmPVwiZmllbGQudHlwZSA9PT0gJ0RhdGUnXCIgY2xhc3M9XCJmaWVsZC1jb250YWluZXJcIiAoY2xpY2spPVwic2VsZWN0RWxlbWVudChpKVwiXG4gICAgICAgIFtuZ1N0eWxlXT1cImdldEZvbnRTdHlsZXMoZmllbGQpXCIgW2NsYXNzLmhpZ2hsaWdodF09XCJzZWxlY3RlZEZpZWxkSW5kZXggPT09IGlcIiBkcmFnZ2FibGU9XCJ0cnVlXCJcbiAgICAgICAgKGRyYWdzdGFydCk9XCJvbkRyYWdTdGFydCgkZXZlbnQsIGkpXCIgKGRyYWdvdmVyKT1cIm9uRHJhZ092ZXIoJGV2ZW50LCBpKVwiIChkcm9wKT1cIm9uRHJvcCgkZXZlbnQsIGkpXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC13cmFwcGVyXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWNvbnRlbnRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsYWJlbC1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICA8bGFiZWwgW2NsYXNzLnJlcXVpcmVkXT1cImZpZWxkLmlzT3B0aW9uYWxcIiAqbmdJZj1cImZpZWxkLnN0eWxlPy5zaG93TGFiZWwgIT09IGZhbHNlXCI+e3tcbiAgICAgICAgICAgICAgICAgIGZpZWxkLnF1ZXN0aW9uVGV4dCA/IGZpZWxkLnF1ZXN0aW9uVGV4dCA6ICdTZWxlY3QgRGF0ZSdcbiAgICAgICAgICAgICAgICAgIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0b3AtcmlnaHRcIj5cbiAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi4uL2Fzc2V0cy9pY29ucy9kcmFnLWRvdHMuc3ZnXCIgYWx0PVwiRHJhZ1wiIGNsYXNzPVwiZHJhZy1kb3RcIiAvPlxuICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiLi4vYXNzZXRzL2ljb25zL1RyYXNoLnN2Z1wiIChjbGljayk9XCJyZW1vdmVFbGVtZW50KGZpZWxkLCBpKVwiIGNsYXNzPVwiZGVsZXRlLWljb25cIiAvPlxuICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cImRhdGVcIiBjbGFzcz1cImN1c3RvbS1pbnB1dFwiIFtyZWFkb25seV09XCJmaWVsZC5pc1JlYWRPbmx5XCIgW2NsYXNzLmhpZGRlbl09XCJmaWVsZC5pc0hpZGRlblwiXG4gICAgICAgICAgICAgIFt2YWx1ZV09XCJmaWVsZC5kZWZhdWx0VmFsdWUgPyBmaWVsZC5kZWZhdWx0VmFsdWUgOiAnJ1wiIC8+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gQVAtMjFNQVIyNSBBZGQgVGltZSBlbGVtZW50IC0tPlxuICAgICAgPCEtLSBUaW1lIEZpZWxkIC0tPlxuICAgICAgPGRpdiAqbmdJZj1cImZpZWxkLnR5cGUgPT09ICdUaW1lJ1wiIGNsYXNzPVwiZmllbGQtY29udGFpbmVyXCIgKGNsaWNrKT1cInNlbGVjdEVsZW1lbnQoaSlcIlxuICAgICAgICBbbmdTdHlsZV09XCJnZXRGb250U3R5bGVzKGZpZWxkKVwiIFtjbGFzcy5oaWdobGlnaHRdPVwic2VsZWN0ZWRGaWVsZEluZGV4ID09PSBpXCIgZHJhZ2dhYmxlPVwidHJ1ZVwiXG4gICAgICAgIChkcmFnc3RhcnQpPVwib25EcmFnU3RhcnQoJGV2ZW50LCBpKVwiIChkcmFnb3Zlcik9XCJvbkRyYWdPdmVyKCRldmVudCwgaSlcIiAoZHJvcCk9XCJvbkRyb3AoJGV2ZW50LCBpKVwiPlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC13cmFwcGVyXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWNvbnRlbnRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsYWJlbC1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgPGxhYmVsIFtjbGFzcy5yZXF1aXJlZF09XCJmaWVsZC5pc09wdGlvbmFsXCI+e3sgZmllbGQucXVlc3Rpb25UZXh0ID8gZmllbGQucXVlc3Rpb25UZXh0IDogJ1RpbWUnIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRvcC1yaWdodFwiPlxuICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiLi4vYXNzZXRzL2ljb25zL2RyYWctZG90cy5zdmdcIiBhbHQ9XCJEcmFnXCIgY2xhc3M9XCJkcmFnLWRvdFwiIC8+XG4gICAgICAgICAgICAgICAgPGltZyBzcmM9XCIuLi9hc3NldHMvaWNvbnMvVHJhc2guc3ZnXCIgKGNsaWNrKT1cInJlbW92ZUVsZW1lbnQoZmllbGQsIGkpXCIgY2xhc3M9XCJkZWxldGUtaWNvblwiIC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRpbWVcIiBjbGFzcz1cImN1c3RvbS1pbnB1dFwiIFtyZWFkb25seV09XCJmaWVsZC5pc1JlYWRPbmx5XCIgW2NsYXNzLmhpZGRlbl09XCJmaWVsZC5pc0hpZGRlblwiXG4gICAgICAgICAgICAgIFt2YWx1ZV09XCJmaWVsZC5kZWZhdWx0VmFsdWUgPyBmaWVsZC5kZWZhdWx0VmFsdWUgOiAnJ1wiIC8+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gQVAtMjhNQVIyNSBEYXRlVGltZSAtLT5cbiAgICAgIDxkaXYgKm5nSWY9XCJmaWVsZC50eXBlID09PSAnRGF0ZVRpbWUnXCIgY2xhc3M9XCJmaWVsZC1jb250YWluZXJcIiAoY2xpY2spPVwic2VsZWN0RWxlbWVudChpKVwiXG4gICAgICAgIFtuZ1N0eWxlXT1cImdldEZvbnRTdHlsZXMoZmllbGQpXCIgW2NsYXNzLmhpZ2hsaWdodF09XCJzZWxlY3RlZEZpZWxkSW5kZXggPT09IGlcIiBkcmFnZ2FibGU9XCJ0cnVlXCJcbiAgICAgICAgKGRyYWdzdGFydCk9XCJvbkRyYWdTdGFydCgkZXZlbnQsIGkpXCIgKGRyYWdvdmVyKT1cIm9uRHJhZ092ZXIoJGV2ZW50LCBpKVwiIChkcm9wKT1cIm9uRHJvcCgkZXZlbnQsIGkpXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC13cmFwcGVyXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWNvbnRlbnRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsYWJlbC1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICA8bGFiZWwgW2NsYXNzLnJlcXVpcmVkXT1cImZpZWxkLmlzT3B0aW9uYWxcIiAqbmdJZj1cImZpZWxkLnN0eWxlPy5zaG93TGFiZWwgIT09IGZhbHNlXCI+e3tcbiAgICAgICAgICAgICAgICAgIGZpZWxkLnF1ZXN0aW9uVGV4dCA/IGZpZWxkLnF1ZXN0aW9uVGV4dCA6ICdTZWxlY3QgRGF0ZSAmIFRpbWUnXG4gICAgICAgICAgICAgICAgICB9fTwvbGFiZWw+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidG9wLXJpZ2h0XCI+XG4gICAgICAgICAgICAgICAgPGltZyBzcmM9XCIuLi9hc3NldHMvaWNvbnMvZHJhZy1kb3RzLnN2Z1wiIGFsdD1cIkRyYWdcIiBjbGFzcz1cImRyYWctZG90XCIgLz5cbiAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi4uL2Fzc2V0cy9pY29ucy9UcmFzaC5zdmdcIiAoY2xpY2spPVwicmVtb3ZlRWxlbWVudChmaWVsZCwgaSlcIiBjbGFzcz1cImRlbGV0ZS1pY29uXCIgLz5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiZGF0ZXRpbWUtbG9jYWxcIiBjbGFzcz1cImN1c3RvbS1pbnB1dFwiIFtyZWFkb25seV09XCJmaWVsZC5pc1JlYWRPbmx5XCJcbiAgICAgICAgICAgICAgW2NsYXNzLmhpZGRlbl09XCJmaWVsZC5pc0hpZGRlblwiIC8+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gRW1haWwgLS0+XG4gICAgICA8ZGl2ICpuZ0lmPVwiZmllbGQudHlwZSA9PT0gJ0VtYWlsJ1wiIGNsYXNzPVwiZmllbGQtY29udGFpbmVyXCIgKGNsaWNrKT1cInNlbGVjdEVsZW1lbnQoaSlcIlxuICAgICAgICBbbmdTdHlsZV09XCJnZXRGb250U3R5bGVzKGZpZWxkKVwiIFtjbGFzcy5oaWdobGlnaHRdPVwic2VsZWN0ZWRGaWVsZEluZGV4ID09PSBpXCIgZHJhZ2dhYmxlPVwidHJ1ZVwiXG4gICAgICAgIChkcmFnc3RhcnQpPVwib25EcmFnU3RhcnQoJGV2ZW50LCBpKVwiIChkcmFnb3Zlcik9XCJvbkRyYWdPdmVyKCRldmVudCwgaSlcIiAoZHJvcCk9XCJvbkRyb3AoJGV2ZW50LCBpKVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtd3JhcHBlclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1jb250ZW50XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibGFiZWwtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgPGxhYmVsIFtjbGFzcy5yZXF1aXJlZF09XCJmaWVsZC5pc09wdGlvbmFsXCI+IHt7IGZpZWxkLnF1ZXN0aW9uVGV4dCA/IGZpZWxkLnF1ZXN0aW9uVGV4dCA6ICdMYWJlbCcgfX1cbiAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRvcC1yaWdodFwiPlxuICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiLi4vYXNzZXRzL2ljb25zL2RyYWctZG90cy5zdmdcIiBhbHQ9XCJEcmFnXCIgY2xhc3M9XCJkcmFnLWRvdFwiIC8+XG4gICAgICAgICAgICAgICAgPGltZyBzcmM9XCIuLi9hc3NldHMvaWNvbnMvVHJhc2guc3ZnXCIgKGNsaWNrKT1cInJlbW92ZUVsZW1lbnQoZmllbGQsIGkpXCIgY2xhc3M9XCJkZWxldGUtaWNvblwiIC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cImVtYWlsXCIgY2xhc3M9XCJjdXN0b20taW5wdXRcIiBbcGxhY2Vob2xkZXJdPVwiZmllbGQucXVlc3Rpb24gfHwgJ0VudGVyIGVtYWlsJ1wiXG4gICAgICAgICAgICAgIFtyZWFkb25seV09XCJmaWVsZC5pc1JlYWRPbmx5XCIgW2NsYXNzLmhpZGRlbl09XCJmaWVsZC5pc0hpZGRlblwiXG4gICAgICAgICAgICAgIFt2YWx1ZV09XCJmaWVsZC5kZWZhdWx0VmFsdWUgPyBmaWVsZC5kZWZhdWx0VmFsdWUgOiAnJ1wiIC8+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gTnVtYmVycyAtLT5cbiAgICAgIDxkaXYgKm5nSWY9XCJmaWVsZC50eXBlID09PSAnTnVtYmVyJ1wiIGNsYXNzPVwiZmllbGQtY29udGFpbmVyXCIgKGNsaWNrKT1cInNlbGVjdEVsZW1lbnQoaSlcIlxuICAgICAgICBbbmdTdHlsZV09XCJnZXRGb250U3R5bGVzKGZpZWxkKVwiIFtjbGFzcy5oaWdobGlnaHRdPVwic2VsZWN0ZWRGaWVsZEluZGV4ID09PSBpXCIgZHJhZ2dhYmxlPVwidHJ1ZVwiXG4gICAgICAgIChkcmFnc3RhcnQpPVwib25EcmFnU3RhcnQoJGV2ZW50LCBpKVwiIChkcmFnb3Zlcik9XCJvbkRyYWdPdmVyKCRldmVudCwgaSlcIiAoZHJvcCk9XCJvbkRyb3AoJGV2ZW50LCBpKVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtd3JhcHBlclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1jb250ZW50XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibGFiZWwtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgPGxhYmVsIFtjbGFzcy5yZXF1aXJlZF09XCJmaWVsZC5pc09wdGlvbmFsXCIgKm5nSWY9XCJmaWVsZC5zdHlsZT8uc2hvd0xhYmVsICE9PSBmYWxzZVwiPnt7XG4gICAgICAgICAgICAgICAgICBmaWVsZC5xdWVzdGlvblRleHQgPyBmaWVsZC5xdWVzdGlvblRleHQgOiAnTGFiZWwnIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0b3AtcmlnaHRcIj5cbiAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi4uL2Fzc2V0cy9pY29ucy9kcmFnLWRvdHMuc3ZnXCIgYWx0PVwiRHJhZ1wiIGNsYXNzPVwiZHJhZy1kb3RcIiAvPlxuXG4gICAgICAgICAgICAgICAgPGltZyBzcmM9XCIuLi9hc3NldHMvaWNvbnMvVHJhc2guc3ZnXCIgKGNsaWNrKT1cInJlbW92ZUVsZW1lbnQoZmllbGQsIGkpXCIgY2xhc3M9XCJkZWxldGUtaWNvblwiIC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiIGNsYXNzPVwiY3VzdG9tLWlucHV0XCIgW3BsYWNlaG9sZGVyXT1cImZpZWxkLnF1ZXN0aW9uIHx8ICdFbnRlciBudW1iZXInXCJcbiAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cImZpZWxkLmlzUmVhZE9ubHlcIiBbY2xhc3MuaGlkZGVuXT1cImZpZWxkLmlzSGlkZGVuXCJcbiAgICAgICAgICAgICAgW3ZhbHVlXT1cImZpZWxkLmRlZmF1bHRWYWx1ZSA/IGZpZWxkLmRlZmF1bHRWYWx1ZSA6ICcnXCIgLz5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBUZXh0QXJlYSAtLT5cbiAgICAgIDxkaXYgKm5nSWY9XCJmaWVsZC50eXBlID09PSAnVGV4dEFyZWEnXCIgY2xhc3M9XCJmaWVsZC1jb250YWluZXJcIiAoY2xpY2spPVwic2VsZWN0RWxlbWVudChpKVwiXG4gICAgICAgIFtuZ1N0eWxlXT1cImdldEZvbnRTdHlsZXMoZmllbGQpXCIgW2NsYXNzLmhpZ2hsaWdodF09XCJzZWxlY3RlZEZpZWxkSW5kZXggPT09IGlcIiBkcmFnZ2FibGU9XCJ0cnVlXCJcbiAgICAgICAgKGRyYWdzdGFydCk9XCJvbkRyYWdTdGFydCgkZXZlbnQsIGkpXCIgKGRyYWdvdmVyKT1cIm9uRHJhZ092ZXIoJGV2ZW50LCBpKVwiIChkcm9wKT1cIm9uRHJvcCgkZXZlbnQsIGkpXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC13cmFwcGVyXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWNvbnRlbnRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsYWJlbC1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICA8bGFiZWwgW2NsYXNzLnJlcXVpcmVkXT1cImZpZWxkLmlzT3B0aW9uYWxcIiAqbmdJZj1cImZpZWxkLnN0eWxlPy5zaG93TGFiZWwgIT09IGZhbHNlXCI+e3tcbiAgICAgICAgICAgICAgICAgIGZpZWxkLnF1ZXN0aW9uVGV4dCA/IGZpZWxkLnF1ZXN0aW9uVGV4dCA6ICdFbnRlciB5b3VyIHRleHQnfX08L2xhYmVsPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRvcC1yaWdodFwiPlxuICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiLi4vYXNzZXRzL2ljb25zL2RyYWctZG90cy5zdmdcIiBhbHQ9XCJEcmFnXCIgY2xhc3M9XCJkcmFnLWRvdFwiIC8+XG5cbiAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi4uL2Fzc2V0cy9pY29ucy9UcmFzaC5zdmdcIiAoY2xpY2spPVwicmVtb3ZlRWxlbWVudChmaWVsZCwgaSlcIiBjbGFzcz1cImRlbGV0ZS1pY29uXCIgLz5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDx0ZXh0YXJlYSBjbGFzcz1cImN1c3RvbS10ZXh0YXJlYVwiIFtwbGFjZWhvbGRlcl09XCJmaWVsZC5xdWVzdGlvbiB8fCAnRW50ZXIgZGV0YWlsZWQgdGV4dCBoZXJlLi4uJ1wiXG4gICAgICAgICAgICAgIFtzdHlsZS5oZWlnaHQucHhdPVwiZmllbGQuc2l6ZSB8fCAxMDBcIiBbcmVhZG9ubHldPVwiZmllbGQuaXNSZWFkT25seVwiIFtjbGFzcy5oaWRkZW5dPVwiZmllbGQuaXNIaWRkZW5cIlxuICAgICAgICAgICAgICBbdmFsdWVdPVwiZmllbGQuZGVmYXVsdFZhbHVlID8gZmllbGQuZGVmYXVsdFZhbHVlIDogJydcIj48L3RleHRhcmVhPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIFJpY2hUZXh0IC0tPlxuICAgICAgPGRpdiAqbmdJZj1cImZpZWxkLnR5cGUgPT09ICdSaWNoVGV4dEFyZWEnXCIgY2xhc3M9XCJmaWVsZC1jb250YWluZXJcIiAoY2xpY2spPVwic2VsZWN0RWxlbWVudChpKVwiXG4gICAgICAgIFtuZ1N0eWxlXT1cImdldEZvbnRTdHlsZXMoZmllbGQpXCIgW2NsYXNzLmhpZ2hsaWdodF09XCJzZWxlY3RlZEZpZWxkSW5kZXggPT09IGlcIiBkcmFnZ2FibGU9XCJ0cnVlXCJcbiAgICAgICAgKGRyYWdzdGFydCk9XCJvbkRyYWdTdGFydCgkZXZlbnQsIGkpXCIgKGRyYWdvdmVyKT1cIm9uRHJhZ092ZXIoJGV2ZW50LCBpKVwiIChkcm9wKT1cIm9uRHJvcCgkZXZlbnQsIGkpXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC13cmFwcGVyXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWNvbnRlbnRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsYWJlbC1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICA8bGFiZWwgW2NsYXNzLnJlcXVpcmVkXT1cImZpZWxkLmlzT3B0aW9uYWxcIiAqbmdJZj1cImZpZWxkLnN0eWxlPy5zaG93TGFiZWwgIT09IGZhbHNlXCI+e3tcbiAgICAgICAgICAgICAgICAgIGZpZWxkLnF1ZXN0aW9uVGV4dCA/IGZpZWxkLnF1ZXN0aW9uVGV4dCA6ICdFbnRlciB5b3VyIHRleHQnfX08L2xhYmVsPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRvcC1yaWdodFwiPlxuICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiLi4vYXNzZXRzL2ljb25zL2RyYWctZG90cy5zdmdcIiBhbHQ9XCJEcmFnXCIgY2xhc3M9XCJkcmFnLWRvdFwiIC8+XG5cbiAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi4uL2Fzc2V0cy9pY29ucy9UcmFzaC5zdmdcIiAoY2xpY2spPVwicmVtb3ZlRWxlbWVudChmaWVsZCwgaSlcIiBjbGFzcz1cImRlbGV0ZS1pY29uXCIgLz5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDx0ZXh0YXJlYSBjbGFzcz1cImN1c3RvbS10ZXh0YXJlYVwiIFtwbGFjZWhvbGRlcl09XCJmaWVsZC5xdWVzdGlvbiB8fCAnRW50ZXIgZGV0YWlsZWQgdGV4dCBoZXJlLi4uJ1wiXG4gICAgICAgICAgICAgIFtzdHlsZS5oZWlnaHQucHhdPVwiZmllbGQuc2l6ZSB8fCAxMDBcIiBbcmVhZG9ubHldPVwiZmllbGQuaXNSZWFkT25seVwiIFtjbGFzcy5oaWRkZW5dPVwiZmllbGQuaXNIaWRkZW5cIlxuICAgICAgICAgICAgICBbdmFsdWVdPVwiZmllbGQuZGVmYXVsdFZhbHVlID8gZmllbGQuZGVmYXVsdFZhbHVlIDogJydcIj48L3RleHRhcmVhPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIExhYmVsIC0tPlxuICAgICAgPGRpdiAqbmdJZj1cImZpZWxkLnR5cGUgPT09ICdMYWJlbCdcIiBjbGFzcz1cImZpZWxkLWNvbnRhaW5lclwiIChjbGljayk9XCJzZWxlY3RFbGVtZW50KGkpXCJcbiAgICAgICAgW25nU3R5bGVdPVwiZ2V0Rm9udFN0eWxlcyhmaWVsZClcIiBbY2xhc3MuaGlnaGxpZ2h0XT1cInNlbGVjdGVkRmllbGRJbmRleCA9PT0gaVwiIGRyYWdnYWJsZT1cInRydWVcIlxuICAgICAgICAoZHJhZ3N0YXJ0KT1cIm9uRHJhZ1N0YXJ0KCRldmVudCwgaSlcIiAoZHJhZ292ZXIpPVwib25EcmFnT3ZlcigkZXZlbnQsIGkpXCIgKGRyb3ApPVwib25Ecm9wKCRldmVudCwgaSlcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLXdyYXBwZXJcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtY29udGVudFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxhYmVsLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgIDxsYWJlbCBbY2xhc3MucmVxdWlyZWRdPVwiZmllbGQuaXNPcHRpb25hbFwiICpuZ0lmPVwiZmllbGQuc3R5bGU/LnNob3dMYWJlbCAhPT0gZmFsc2VcIj57e1xuICAgICAgICAgICAgICAgICAgZmllbGQucXVlc3Rpb25UZXh0ID8gZmllbGQucXVlc3Rpb25UZXh0IDogJ0xhYmVsJyB9fTwvbGFiZWw+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidG9wLXJpZ2h0XCI+XG4gICAgICAgICAgICAgICAgPGltZyBzcmM9XCIuLi9hc3NldHMvaWNvbnMvZHJhZy1kb3RzLnN2Z1wiIGFsdD1cIkRyYWdcIiBjbGFzcz1cImRyYWctZG90XCIgLz5cblxuICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiLi4vYXNzZXRzL2ljb25zL1RyYXNoLnN2Z1wiIChjbGljayk9XCJyZW1vdmVFbGVtZW50KGZpZWxkLCBpKVwiIGNsYXNzPVwiZGVsZXRlLWljb25cIiAvPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIEJvb2sgLS0+XG4gICAgICA8ZGl2ICpuZ0lmPVwiZmllbGQudHlwZSA9PT0gJ0Jvb2snXCIgY2xhc3M9XCJmaWVsZC1jb250YWluZXJcIiAoY2xpY2spPVwic2VsZWN0RWxlbWVudChpKVwiXG4gICAgICAgIFtuZ1N0eWxlXT1cImdldEZvbnRTdHlsZXMoZmllbGQpXCIgW2NsYXNzLmhpZ2hsaWdodF09XCJzZWxlY3RlZEZpZWxkSW5kZXggPT09IGlcIiBkcmFnZ2FibGU9XCJ0cnVlXCJcbiAgICAgICAgKGRyYWdzdGFydCk9XCJvbkRyYWdTdGFydCgkZXZlbnQsIGkpXCIgKGRyYWdvdmVyKT1cIm9uRHJhZ092ZXIoJGV2ZW50LCBpKVwiIChkcm9wKT1cIm9uRHJvcCgkZXZlbnQsIGkpXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC13cmFwcGVyXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWNvbnRlbnRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsYWJlbC1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICA8bGFiZWwgW2NsYXNzLnJlcXVpcmVkXT1cImZpZWxkLmlzT3B0aW9uYWxcIiAqbmdJZj1cImZpZWxkLnN0eWxlPy5zaG93TGFiZWwgIT09IGZhbHNlXCI+e3tcbiAgICAgICAgICAgICAgICAgIGZpZWxkLnF1ZXN0aW9uVGV4dCA/IGZpZWxkLnF1ZXN0aW9uVGV4dCA6ICdMYWJlbCcgfX08L2xhYmVsPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRvcC1yaWdodFwiPlxuICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiLi4vYXNzZXRzL2ljb25zL2RyYWctZG90cy5zdmdcIiBhbHQ9XCJEcmFnXCIgY2xhc3M9XCJkcmFnLWRvdFwiIC8+XG4gICAgICAgICAgICAgICAgPGltZyBzcmM9XCIuLi9hc3NldHMvaWNvbnMvVHJhc2guc3ZnXCIgKGNsaWNrKT1cInJlbW92ZUVsZW1lbnQoZmllbGQsIGkpXCIgY2xhc3M9XCJkZWxldGUtaWNvblwiIC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8bGliLWJvb2tsZXQgW2Jvb2tsZXRKU09OXT1cImZpZWxkLnFiUmVmZXJlbmNlUXVlc3Rpb25zXCI+PC9saWItYm9va2xldD5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBGaWxlIC0tPlxuICAgICAgPGRpdiAqbmdJZj1cImZpZWxkLnR5cGUgPT09ICdGaWxlJ1wiIGNsYXNzPVwiZmllbGQtY29udGFpbmVyXCIgKGNsaWNrKT1cInNlbGVjdEVsZW1lbnQoaSlcIlxuICAgICAgICBbbmdTdHlsZV09XCJnZXRGb250U3R5bGVzKGZpZWxkKVwiIFtjbGFzcy5oaWdobGlnaHRdPVwic2VsZWN0ZWRGaWVsZEluZGV4ID09PSBpXCIgZHJhZ2dhYmxlPVwidHJ1ZVwiXG4gICAgICAgIChkcmFnc3RhcnQpPVwib25EcmFnU3RhcnQoJGV2ZW50LCBpKVwiIChkcmFnb3Zlcik9XCJvbkRyYWdPdmVyKCRldmVudCwgaSlcIiAoZHJvcCk9XCJvbkRyb3AoJGV2ZW50LCBpKVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtd3JhcHBlclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1jb250ZW50XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibGFiZWwtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgPGxhYmVsIFtjbGFzcy5yZXF1aXJlZF09XCJmaWVsZC5pc09wdGlvbmFsXCIgKm5nSWY9XCJmaWVsZC5zdHlsZT8uc2hvd0xhYmVsICE9PSBmYWxzZVwiPnt7XG4gICAgICAgICAgICAgICAgICBmaWVsZC5xdWVzdGlvblRleHQgPyBmaWVsZC5xdWVzdGlvblRleHQgOiAnVXBsb2FkIEZpbGUnXG4gICAgICAgICAgICAgICAgICB9fTwvbGFiZWw+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidG9wLXJpZ2h0XCI+XG4gICAgICAgICAgICAgICAgPGltZyBzcmM9XCIuLi9hc3NldHMvaWNvbnMvZHJhZy1kb3RzLnN2Z1wiIGFsdD1cIkRyYWdcIiBjbGFzcz1cImRyYWctZG90XCIgLz5cbiAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi4uL2Fzc2V0cy9pY29ucy9UcmFzaC5zdmdcIiAoY2xpY2spPVwicmVtb3ZlRWxlbWVudChmaWVsZCwgaSlcIiBjbGFzcz1cImRlbGV0ZS1pY29uXCIgLz5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiZmlsZVwiIGNsYXNzPVwiY3VzdG9tLWlucHV0XCIgW3JlYWRvbmx5XT1cImZpZWxkLmlzUmVhZE9ubHlcIiBbY2xhc3MuaGlkZGVuXT1cImZpZWxkLmlzSGlkZGVuXCIgLz5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBDaGVja0JveCAtLT5cbiAgICAgIDxkaXYgKm5nSWY9XCJmaWVsZC50eXBlID09PSAnQ2hlY2tib3gnXCIgY2xhc3M9XCJmaWVsZC1jb250YWluZXJcIiAoY2xpY2spPVwic2VsZWN0RWxlbWVudChpKVwiXG4gICAgICAgIFtuZ1N0eWxlXT1cImdldEZvbnRTdHlsZXMoZmllbGQpXCIgW2NsYXNzLmhpZ2hsaWdodF09XCJzZWxlY3RlZEZpZWxkSW5kZXggPT09IGlcIiBkcmFnZ2FibGU9XCJ0cnVlXCJcbiAgICAgICAgKGRyYWdzdGFydCk9XCJvbkRyYWdTdGFydCgkZXZlbnQsIGkpXCIgKGRyYWdvdmVyKT1cIm9uRHJhZ092ZXIoJGV2ZW50LCBpKVwiIChkcm9wKT1cIm9uRHJvcCgkZXZlbnQsIGkpXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC13cmFwcGVyXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWNvbnRlbnRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsYWJlbC1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICA8bGFiZWwgW2NsYXNzLnJlcXVpcmVkXT1cImZpZWxkLmlzT3B0aW9uYWxcIiAqbmdJZj1cImZpZWxkLnN0eWxlPy5zaG93TGFiZWwgIT09IGZhbHNlXCI+XG4gICAgICAgICAgICAgICAgICB7eyBmaWVsZC5xdWVzdGlvblRleHQgPyBmaWVsZC5xdWVzdGlvblRleHQgOiAnTGFiZWwnIH19XG4gICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0b3AtcmlnaHRcIj5cbiAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi4uL2Fzc2V0cy9pY29ucy9kcmFnLWRvdHMuc3ZnXCIgYWx0PVwiRHJhZ1wiIGNsYXNzPVwiZHJhZy1kb3RcIiAvPlxuICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiLi4vYXNzZXRzL2ljb25zL1RyYXNoLnN2Z1wiIChjbGljayk9XCJyZW1vdmVFbGVtZW50KGZpZWxkLCBpKVwiIGNsYXNzPVwiZGVsZXRlLWljb25cIiAvPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2hlY2tib3gtb3B0aW9ucy1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIGZpZWxkLm9wdGlvbnNcIiBjbGFzcz1cImNoZWNrYm94LW9wdGlvblwiPlxuICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBbaWRdPVwib3B0aW9uLnZhbHVlICsgaVwiIFtuYW1lXT1cImZpZWxkLmlkXCJcbiAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJvcHRpb24udmFsdWUgfHwgZmllbGQuZGVmYXVsdFZhbHVlXCIgY2xhc3M9XCJjaGVja2JveC1pbnB1dFwiIFtkaXNhYmxlZF09XCJmaWVsZC5pc1JlYWRPbmx5XCJcbiAgICAgICAgICAgICAgICAgIFtjbGFzcy5oaWRkZW5dPVwiZmllbGQuaXNIaWRkZW5cIj5cbiAgICAgICAgICAgICAgICA8bGFiZWwgW2Zvcl09XCJvcHRpb24udmFsdWUgKyBpXCIgY2xhc3M9XCJjaGVja2JveC1sYWJlbFwiPnt7IG9wdGlvbi52YWx1ZSB9fTwvbGFiZWw+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gUmFkaW8gLS0+XG4gICAgICA8ZGl2ICpuZ0lmPVwiZmllbGQudHlwZSA9PT0gJ1JhZGlvJ1wiIGNsYXNzPVwiZmllbGQtY29udGFpbmVyXCIgKGNsaWNrKT1cInNlbGVjdEVsZW1lbnQoaSlcIlxuICAgICAgICBbbmdTdHlsZV09XCJnZXRGb250U3R5bGVzKGZpZWxkKVwiIFtjbGFzcy5oaWdobGlnaHRdPVwic2VsZWN0ZWRGaWVsZEluZGV4ID09PSBpXCIgZHJhZ2dhYmxlPVwidHJ1ZVwiXG4gICAgICAgIChkcmFnc3RhcnQpPVwib25EcmFnU3RhcnQoJGV2ZW50LCBpKVwiIChkcmFnb3Zlcik9XCJvbkRyYWdPdmVyKCRldmVudCwgaSlcIiAoZHJvcCk9XCJvbkRyb3AoJGV2ZW50LCBpKVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtd3JhcHBlclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1jb250ZW50XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibGFiZWwtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgPGxhYmVsIFtjbGFzcy5yZXF1aXJlZF09XCJmaWVsZC5pc09wdGlvbmFsXCIgKm5nSWY9XCJmaWVsZC5zdHlsZT8uc2hvd0xhYmVsICE9PSBmYWxzZVwiPnt7XG4gICAgICAgICAgICAgICAgICBmaWVsZC5xdWVzdGlvblRleHQgPyBmaWVsZC5xdWVzdGlvblRleHQgOiAnTGFiZWwnIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0b3AtcmlnaHRcIj5cbiAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi4uL2Fzc2V0cy9pY29ucy9kcmFnLWRvdHMuc3ZnXCIgYWx0PVwiRHJhZ1wiIGNsYXNzPVwiZHJhZy1kb3RcIiAvPlxuXG4gICAgICAgICAgICAgICAgPGltZyBzcmM9XCIuLi9hc3NldHMvaWNvbnMvVHJhc2guc3ZnXCIgKGNsaWNrKT1cInJlbW92ZUVsZW1lbnQoZmllbGQsIGkpXCIgY2xhc3M9XCJkZWxldGUtaWNvblwiIC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmFkaW8tb3B0aW9ucy1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIGZpZWxkLm9wdGlvbnM7IGxldCBqID0gaW5kZXhcIiBjbGFzcz1cInJhZGlvLW9wdGlvblwiPlxuICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwicmFkaW9cIiBbaWRdPVwiJ3JhZGlvLScgKyBmaWVsZC5pZCArICctJyArIGpcIiBbbmFtZV09XCIncmFkaW8tZ3JvdXAtJyArIGZpZWxkLmlkXCJcbiAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJvcHRpb24udmFsdWUgfHwgZmllbGQuZGVmYXVsdFZhbHVlXCIgWyhuZ01vZGVsKV09XCJmaWVsZC5zZWxlY3RlZFZhbHVlXCIgY2xhc3M9XCJyYWRpby1pbnB1dFwiXG4gICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiZmllbGQuaXNSZWFkT25seVwiIFtjbGFzcy5oaWRkZW5dPVwiZmllbGQuaXNIaWRkZW5cIj5cbiAgICAgICAgICAgICAgICA8bGFiZWwgW2Zvcl09XCIncmFkaW8tJyArIGZpZWxkLmlkICsgJy0nICsgalwiIGNsYXNzPVwicmFkaW8tbGFiZWxcIj4ge3sgb3B0aW9uLnZhbHVlIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICAgIDwhLS0gRHJvcGRvd24gLS0+XG4gICAgICA8ZGl2ICpuZ0lmPVwiZmllbGQudHlwZSA9PT0gJ0Ryb3Bkb3duJ1wiIGNsYXNzPVwiZmllbGQtY29udGFpbmVyXCIgKGNsaWNrKT1cInNlbGVjdEVsZW1lbnQoaSlcIlxuICAgICAgICBbbmdTdHlsZV09XCJnZXRGb250U3R5bGVzKGZpZWxkKVwiIFtjbGFzcy5oaWdobGlnaHRdPVwic2VsZWN0ZWRGaWVsZEluZGV4ID09PSBpXCIgZHJhZ2dhYmxlPVwidHJ1ZVwiXG4gICAgICAgIChkcmFnc3RhcnQpPVwib25EcmFnU3RhcnQoJGV2ZW50LCBpKVwiIChkcmFnb3Zlcik9XCJvbkRyYWdPdmVyKCRldmVudCwgaSlcIiAoZHJvcCk9XCJvbkRyb3AoJGV2ZW50LCBpKVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtd3JhcHBlclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1jb250ZW50XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibGFiZWwtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgPGxhYmVsIFtjbGFzcy5yZXF1aXJlZF09XCJmaWVsZC5pc09wdGlvbmFsXCIgKm5nSWY9XCJmaWVsZC5zdHlsZT8uc2hvd0xhYmVsICE9PSBmYWxzZVwiPnt7XG4gICAgICAgICAgICAgICAgICBmaWVsZC5xdWVzdGlvblRleHQgPyBmaWVsZC5xdWVzdGlvblRleHQgOiAnTGFiZWwnIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0b3AtcmlnaHRcIj5cbiAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi4uL2Fzc2V0cy9pY29ucy9kcmFnLWRvdHMuc3ZnXCIgYWx0PVwiRHJhZ1wiIGNsYXNzPVwiZHJhZy1kb3RcIiAvPlxuXG4gICAgICAgICAgICAgICAgPGltZyBzcmM9XCIuLi9hc3NldHMvaWNvbnMvVHJhc2guc3ZnXCIgKGNsaWNrKT1cInJlbW92ZUVsZW1lbnQoZmllbGQsIGkpXCIgY2xhc3M9XCJkZWxldGUtaWNvblwiIC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8c2VsZWN0IGlkPVwib3B0aW9uc1wiIGNsYXNzPVwiZHJvcGRvd25cIiBbZGlzYWJsZWRdPVwiZmllbGQuaXNSZWFkT25seVwiIFtjbGFzcy5oaWRkZW5dPVwiZmllbGQuaXNIaWRkZW5cIj5cbiAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIGZpZWxkLm9wdGlvbnNcIiBbdmFsdWVdPVwib3B0aW9uLnZhbHVlIHx8IGZpZWxkLmRlZmF1bHRWYWx1ZVwiPiB7eyBvcHRpb24udmFsdWVcbiAgICAgICAgICAgICAgICB9fSA8L29wdGlvbj5cbiAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tICBUYWJsZSAgLS0+XG4gICAgICA8IS0tIEFQLTA2TUFSMjUgLS0+XG4gICAgICA8ZGl2ICpuZ0lmPVwiZmllbGQudHlwZSA9PT0gJ1RhYmxlJ1wiIGNsYXNzPVwiZmllbGQtY29udGFpbmVyXCIgKGNsaWNrKT1cInNlbGVjdEVsZW1lbnQoaSlcIlxuICAgICAgICBbbmdTdHlsZV09XCJnZXRGb250U3R5bGVzKGZpZWxkKVwiIFtjbGFzcy5oaWdobGlnaHRdPVwic2VsZWN0ZWRGaWVsZEluZGV4ID09PSBpXCIgZHJhZ2dhYmxlPVwidHJ1ZVwiXG4gICAgICAgIChkcmFnc3RhcnQpPVwib25EcmFnU3RhcnQoJGV2ZW50LCBpKVwiIChkcmFnb3Zlcik9XCJvbkRyYWdPdmVyKCRldmVudCwgaSlcIiAoZHJvcCk9XCJvbkRyb3AoJGV2ZW50LCBpKVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtd3JhcHBlclwiIHN0eWxlPVwib3ZlcmZsb3c6IGhpZGRlbjtcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtY29udGVudFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxhYmVsLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgIDxsYWJlbCBbY2xhc3MucmVxdWlyZWRdPVwiZmllbGQuaXNPcHRpb25hbFwiICpuZ0lmPVwiZmllbGQuc3R5bGU/LnNob3dMYWJlbCAhPT0gZmFsc2VcIj57e1xuICAgICAgICAgICAgICAgICAgZmllbGQucXVlc3Rpb25UZXh0ID8gZmllbGQucXVlc3Rpb25UZXh0IDogJ0xhYmVsJyB9fTwvbGFiZWw+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidG9wLXJpZ2h0XCI+XG4gICAgICAgICAgICAgICAgPGltZyBzcmM9XCIuLi9hc3NldHMvaWNvbnMvZHJhZy1kb3RzLnN2Z1wiIGFsdD1cIkRyYWdcIiBjbGFzcz1cImRyYWctZG90XCIgLz5cbiAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi4uL2Fzc2V0cy9pY29ucy9UcmFzaC5zdmdcIiAoY2xpY2spPVwicmVtb3ZlRWxlbWVudChmaWVsZCwgaSlcIiBjbGFzcz1cImRlbGV0ZS1pY29uXCIgLz5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJueHQtdGFibGUtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgIDxueHQtZGF0YXRhYmxlICBpc0J1dHRvbnMgW3F1ZXN0aW9uXT1cImZpZWxkXCIgZnJvbT1cImZvcm1CdWlsZGVyXCIgW21vZGVdPVwiJ2VkaXQnXCIgW2FwaU1ldGFdPVwiZmllbGQuc3ViVGV4dFwiXG4gICAgICAgICAgICAgICAgW3RhYmxlQ29uZmlnXT1cImZpZWxkLnRhYmxlQ29uZmlnXCIgdGFibGVJZD1cIlwiIGRpcmVjdGlvbj1cImx0clwiIHRhYmxlV2lkdGg9XCJhdXRvXCIgaXNFZGl0YWJsZT10cnVlIFtzZWxlY3RlZENvbHVtbl09XCJzZWxlY3RlZENvbHVtblwiXG4gICAgICAgICAgICAgICAgKGNvbHVtblNlbGVjdGVkKT1jb2x1bW5TZWxlY3RlZCgkZXZlbnQpIChyZW1vdmVDb2x1bW4pPXJlbW92ZUNvbHVtbigkZXZlbnQpPlxuICAgICAgICAgICAgICA8L254dC1kYXRhdGFibGU+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBMaXN0IC0tPlxuICAgICAgPCEtLSBBUC0wNk1BUjI1IC0gTGlzdCBkYXRhIHNob3ctLT5cbiAgICAgIDxkaXYgKm5nSWY9XCJmaWVsZC50eXBlID09PSAnTGlzdCdcIiBjbGFzcz1cImZpZWxkLWNvbnRhaW5lclwiIChjbGljayk9XCJzZWxlY3RFbGVtZW50KGkpXCJcbiAgICAgICAgW25nU3R5bGVdPVwiZ2V0Rm9udFN0eWxlcyhmaWVsZClcIiBbY2xhc3MuaGlnaGxpZ2h0XT1cInNlbGVjdGVkRmllbGRJbmRleCA9PT0gaVwiIGRyYWdnYWJsZT1cInRydWVcIlxuICAgICAgICAoZHJhZ3N0YXJ0KT1cIm9uRHJhZ1N0YXJ0KCRldmVudCwgaSlcIiAoZHJhZ292ZXIpPVwib25EcmFnT3ZlcigkZXZlbnQsIGkpXCIgKGRyb3ApPVwib25Ecm9wKCRldmVudCwgaSlcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLXdyYXBwZXJcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtY29udGVudFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxhYmVsLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgIDxsYWJlbCBbY2xhc3MucmVxdWlyZWRdPVwiZmllbGQuaXNPcHRpb25hbFwiICpuZ0lmPVwiZmllbGQuc3R5bGU/LnNob3dMYWJlbCAhPT0gZmFsc2VcIj57e1xuICAgICAgICAgICAgICAgICAgZmllbGQucXVlc3Rpb25UZXh0ID8gZmllbGQucXVlc3Rpb25UZXh0IDogJ0xhYmVsJyB9fTwvbGFiZWw+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidG9wLXJpZ2h0XCI+XG4gICAgICAgICAgICAgICAgPGltZyBzcmM9XCIuLi9hc3NldHMvaWNvbnMvZHJhZy1kb3RzLnN2Z1wiIGFsdD1cIkRyYWdcIiBjbGFzcz1cImRyYWctZG90XCIgLz5cbiAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi4uL2Fzc2V0cy9pY29ucy9UcmFzaC5zdmdcIiAoY2xpY2spPVwicmVtb3ZlRWxlbWVudChmaWVsZCwgaSlcIiBjbGFzcz1cImRlbGV0ZS1pY29uXCIgLz5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiY3VzdG9tLWlucHV0XCIgcGxhY2Vob2xkZXI9XCJTZWFyY2guLi5cIiBbcmVhZG9ubHldPVwiZmllbGQuaXNSZWFkT25seVwiXG4gICAgICAgICAgICAgIFtjbGFzcy5oaWRkZW5dPVwiZmllbGQuaXNIaWRkZW5cIiBbdmFsdWVdPVwiZmllbGQuZGVmYXVsdFZhbHVlID8gZmllbGQuZGVmYXVsdFZhbHVlIDogJydcIiAvPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvZGl2PlxuPC9kaXY+XG48IS0tIFNLUzEzTUFSMjUgcG9wdXAgY29uZm9ybWF0aW9uIGJveCAtLT5cbjxkaXYgY2xhc3M9XCJkaWFsb2ctb3ZlcmxheVwiICpuZ0lmPVwiaXNTZWxlY3RUYWJsZVBvcHVwXCI+XG4gIDxkaXYgY2xhc3M9XCJkaWFsb2ctYm94XCI+XG4gICAgPGJ1dHRvbiBjbGFzcz1cImNsb3NlLWJ0bi1mYlwiIChjbGljayk9XCJvbkNsb3NlKClcIj7inJU8L2J1dHRvbj5cbiAgICA8cD5UaGVzZSBlbGVtZW50IHdhbnQgdG8gYWRkIGEgdGFibGU8L3A+XG4gICAgPGRpdiBjbGFzcz1cImJ1dHRvbi1jb250YWluZXItZmJcIj5cbiAgICAgIDxidXR0b24gY2xhc3M9XCJ5ZXMtYnRuLWZiXCIgKGNsaWNrKT1cImFkZE9uVGFibGUoKVwiPlllczwvYnV0dG9uPlxuICAgICAgPGJ1dHRvbiBjbGFzcz1cIm5vLWJ0bi1mYlwiIChjbGljayk9XCJvbkNsb3NlKClcIj5ObzwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PiJdfQ==