@rangertechnologies/ngnxt 2.1.242 → 2.1.243-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/fesm2022/rangertechnologies-ngnxt.mjs +153 -185
  2. package/fesm2022/rangertechnologies-ngnxt.mjs.map +1 -1
  3. package/lib/components/image-cropper/component/image-cropper.component.d.ts +1 -1
  4. package/lib/components/pick-location/pick-location.component.d.ts +0 -1
  5. package/package.json +4 -6
  6. package/rangertechnologies-ngnxt-2.1.243-beta.tgz +0 -0
  7. package/esm2022/environments/version.mjs +0 -15
  8. package/esm2022/lib/ar.i18n.mjs +0 -29
  9. package/esm2022/lib/components/button/nxt-button.component.mjs +0 -165
  10. package/esm2022/lib/components/custom-calendar/custom-calendar.component.mjs +0 -371
  11. package/esm2022/lib/components/custom-dropdown/custom-dropdown.component.mjs +0 -274
  12. package/esm2022/lib/components/custom-model/custom-model.component.mjs +0 -51
  13. package/esm2022/lib/components/custom-radio/custom-radio.component.mjs +0 -156
  14. package/esm2022/lib/components/datatable/datatable.component.mjs +0 -1625
  15. package/esm2022/lib/components/file-upload/file-upload.component.mjs +0 -283
  16. package/esm2022/lib/components/icon-selector/icon-selector.component.mjs +0 -104
  17. package/esm2022/lib/components/image-cropper/component/cropper.state.mjs +0 -208
  18. package/esm2022/lib/components/image-cropper/component/image-cropper.component.mjs +0 -562
  19. package/esm2022/lib/components/image-cropper/interfaces/basic-event.interface.mjs +0 -2
  20. package/esm2022/lib/components/image-cropper/interfaces/cropper-options.interface.mjs +0 -2
  21. package/esm2022/lib/components/image-cropper/interfaces/cropper-position.interface.mjs +0 -2
  22. package/esm2022/lib/components/image-cropper/interfaces/dimensions.interface.mjs +0 -2
  23. package/esm2022/lib/components/image-cropper/interfaces/exif-transform.interface.mjs +0 -2
  24. package/esm2022/lib/components/image-cropper/interfaces/image-cropped-event.interface.mjs +0 -2
  25. package/esm2022/lib/components/image-cropper/interfaces/image-transform.interface.mjs +0 -2
  26. package/esm2022/lib/components/image-cropper/interfaces/index.mjs +0 -2
  27. package/esm2022/lib/components/image-cropper/interfaces/loaded-image.interface.mjs +0 -2
  28. package/esm2022/lib/components/image-cropper/interfaces/move-start.interface.mjs +0 -8
  29. package/esm2022/lib/components/image-cropper/services/crop.service.mjs +0 -139
  30. package/esm2022/lib/components/image-cropper/services/load-image.service.mjs +0 -194
  31. package/esm2022/lib/components/image-cropper/utils/cropper-position.utils.mjs +0 -239
  32. package/esm2022/lib/components/image-cropper/utils/exif.utils.mjs +0 -79
  33. package/esm2022/lib/components/image-cropper/utils/keyboard.utils.mjs +0 -40
  34. package/esm2022/lib/components/image-cropper/utils/percentage.utils.mjs +0 -4
  35. package/esm2022/lib/components/image-cropper/utils/resize.utils.mjs +0 -75
  36. package/esm2022/lib/components/list-view-filter/list-view-filter.component.mjs +0 -403
  37. package/esm2022/lib/components/nxt-input/nxt-input.component.mjs +0 -2925
  38. package/esm2022/lib/components/pagination/pagination.component.mjs +0 -101
  39. package/esm2022/lib/components/pick-location/pick-location.component.mjs +0 -234
  40. package/esm2022/lib/components/search-box/search-box.component.mjs +0 -413
  41. package/esm2022/lib/country.json +0 -43237
  42. package/esm2022/lib/en.i18n.mjs +0 -29
  43. package/esm2022/lib/i18n-config.service.mjs +0 -4
  44. package/esm2022/lib/i18n.component.mjs +0 -47
  45. package/esm2022/lib/i18n.module.mjs +0 -38
  46. package/esm2022/lib/i18n.pipe.mjs +0 -26
  47. package/esm2022/lib/i18n.service.mjs +0 -56
  48. package/esm2022/lib/interfaces/actionMeta.mjs +0 -2
  49. package/esm2022/lib/interfaces/apimeta.mjs +0 -2
  50. package/esm2022/lib/interfaces/dependencyMeta.mjs +0 -2
  51. package/esm2022/lib/model/bookletWrapper.mjs +0 -9
  52. package/esm2022/lib/model/changeWrapper.mjs +0 -11
  53. package/esm2022/lib/model/errorWrapper.mjs +0 -6
  54. package/esm2022/lib/nxt-app.component.mjs +0 -22
  55. package/esm2022/lib/nxt-app.module.mjs +0 -139
  56. package/esm2022/lib/nxt-app.service.mjs +0 -14
  57. package/esm2022/lib/pages/booklet/booklet.component.mjs +0 -675
  58. package/esm2022/lib/pages/builder/element/element.component.mjs +0 -466
  59. package/esm2022/lib/pages/builder/form/form.component.mjs +0 -45
  60. package/esm2022/lib/pages/builder/properties/common-fields.constants.mjs +0 -89
  61. package/esm2022/lib/pages/builder/properties/properties.component.mjs +0 -1021
  62. package/esm2022/lib/pages/builder/templates/templates.component.mjs +0 -34
  63. package/esm2022/lib/pages/pdfDesigner/pdf-designer/pdf-designer.component.mjs +0 -676
  64. package/esm2022/lib/pages/pdfDesigner/pdf-properties/pdf-properties.component.mjs +0 -1126
  65. package/esm2022/lib/pages/questionbook/questionbook.component.mjs +0 -841
  66. package/esm2022/lib/pages/questionnaire/questionnaire.component.mjs +0 -2405
  67. package/esm2022/lib/pipe/custom-translate.pipe.mjs +0 -27
  68. package/esm2022/lib/pipe/date/date.pipe.mjs +0 -28
  69. package/esm2022/lib/pipe/editColumnCheck/edit-column-check.pipe.mjs +0 -28
  70. package/esm2022/lib/pipe/editColumnDropdown/edit-column-dropdown.pipe.mjs +0 -20
  71. package/esm2022/lib/pipe/editColumnType/edit-column-type.pipe.mjs +0 -20
  72. package/esm2022/lib/pipe/get-value.pipe.mjs +0 -48
  73. package/esm2022/lib/pipe/search-filter/search-filter.pipe.mjs +0 -39
  74. package/esm2022/lib/pipe/time/time.pipe.mjs +0 -26
  75. package/esm2022/lib/sample.mjs +0 -3715
  76. package/esm2022/lib/services/change.service.mjs +0 -50
  77. package/esm2022/lib/services/country.service.mjs +0 -135
  78. package/esm2022/lib/services/data.service.mjs +0 -103
  79. package/esm2022/lib/services/form-builder.service.mjs +0 -375
  80. package/esm2022/lib/services/pdf-designer.service.mjs +0 -401
  81. package/esm2022/lib/services/salesforce.service.mjs +0 -46
  82. package/esm2022/lib/services/shared.service.mjs +0 -100
  83. package/esm2022/lib/services/storage.service.mjs +0 -44
  84. package/esm2022/lib/services/template.service.mjs +0 -351
  85. package/esm2022/lib/services/translation.service.mjs +0 -62
  86. package/esm2022/lib/tam.i18n.mjs +0 -29
  87. package/esm2022/lib/wrapper.mjs +0 -175
  88. package/esm2022/public-api.mjs +0 -25
  89. package/esm2022/rangertechnologies-ngnxt.mjs +0 -5
  90. package/rangertechnologies-ngnxt-2.1.242.tgz +0 -0
@@ -1,403 +0,0 @@
1
- import { Component, Input, Output, EventEmitter, HostListener } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
- import { FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
4
- import { CustomTranslatePipe } from '../../pipe/custom-translate.pipe';
5
- import { MatTooltipModule } from '@angular/material/tooltip';
6
- import * as i0 from "@angular/core";
7
- import * as i1 from "@angular/forms";
8
- import * as i2 from "../../pipe/custom-translate.pipe";
9
- import * as i3 from "@angular/common";
10
- import * as i4 from "@angular/material/tooltip";
11
- export class ListViewFilterComponent {
12
- fb;
13
- customTranslate;
14
- listViews = [];
15
- tableFilterArray = [];
16
- selectedView = '';
17
- displayedColumns = [];
18
- availableOperators = [
19
- { label: 'Equals (=)', labelPath: 'APP.EQUALS', value: '=' },
20
- { label: 'Not Equal (!=)', labelPath: 'APP.NOT_EQUAL', value: '!=' },
21
- { label: 'Greater Than (>)', labelPath: 'APP.GREATER_THAN', value: '>' },
22
- { label: 'Less Than (<)', labelPath: 'APP.LESS_THAN', value: '<' },
23
- { label: 'Greater Than or Equal (>=)', labelPath: 'APP.GREATER_THAN_OR_EQUAL', value: '>=' },
24
- { label: 'Less Than or Equal (<=)', labelPath: 'APP.LESS_THAN_OR_EQUAL', value: '<=' }
25
- ]; // 'contains', 'not contains', 'starts with', 'ends with'
26
- listViewEmit = new EventEmitter();
27
- isDropdownOpen = false;
28
- isModalOpen = false;
29
- isDeleteModalOpen = false;
30
- isAdding = false;
31
- viewToDelete = null;
32
- editingView;
33
- isColumnDropdownOpen = [];
34
- isOperatorDropdownOpen = [];
35
- isValueDropdownOpen = [];
36
- isColumnNameDropdownOpen = [];
37
- selectedViewPath;
38
- tableFilterArrayTrans;
39
- displayedColumnsTrans;
40
- availableOperatorsTrans;
41
- constructor(fb, customTranslate) {
42
- this.fb = fb;
43
- this.customTranslate = customTranslate;
44
- this.editingView = this.fb.group({
45
- filterName: ['', Validators.required],
46
- order: [0, [Validators.required, Validators.min(0)]],
47
- isDefault: [false],
48
- conditions: this.fb.array([]),
49
- columns: this.fb.array([])
50
- });
51
- }
52
- ngOnInit() {
53
- if (!this.selectedView && this.listViews?.length > 0) {
54
- this.selectedView = this.listViews[0].filterName;
55
- this.selectedViewPath = this.listViews[0].labelPath;
56
- }
57
- else {
58
- this.selectedViewPath = this.selectedView === 'All Data' ? this.listViews[0].labelPath : this.selectedView;
59
- }
60
- this.tableFilterArrayTrans = this.tableFilterArray;
61
- this.tableFilterArrayTrans.forEach((ele) => {
62
- ele.label = this.customTranslate.transform(ele.labelPath || ele.label, ele.label);
63
- });
64
- this.displayedColumnsTrans = this.displayedColumns;
65
- this.displayedColumnsTrans.forEach((ele) => {
66
- ele.label = this.customTranslate.transform(ele.labelPath || ele.label, ele.label);
67
- });
68
- this.availableOperatorsTrans = this.availableOperators;
69
- this.availableOperatorsTrans.forEach((ele) => {
70
- ele.label = this.customTranslate.transform(ele.labelPath || ele.label, ele.label);
71
- });
72
- }
73
- ngOnChanges(changes) {
74
- if (!this.selectedView && this.listViews?.length > 0) {
75
- this.selectedView = this.listViews[0].filterName;
76
- this.selectedViewPath = this.listViews[0].labelPath;
77
- }
78
- else {
79
- this.selectedViewPath = this.selectedView === 'All Data' ? this.listViews[0].labelPath : this.selectedView;
80
- }
81
- }
82
- get conditions() {
83
- return this.editingView.get('conditions');
84
- }
85
- // SKS3MAY25 Returns the FormArray of columns from the editing form
86
- get columns() {
87
- return this.editingView.get('columns');
88
- }
89
- // SKS3MAY25 Adds a new filter condition to the form
90
- addFilter() {
91
- this.conditions.push(this.fb.group({
92
- field: ['', Validators.required],
93
- operator: ['', Validators.required],
94
- value: ['', Validators.required]
95
- }));
96
- this.isColumnDropdownOpen.push(false);
97
- this.isOperatorDropdownOpen.push(false);
98
- this.isValueDropdownOpen.push(false);
99
- }
100
- // SKS3MAY25 Removes a filter condition by index
101
- removeFilter(index) {
102
- this.conditions.removeAt(index);
103
- this.isColumnDropdownOpen.splice(index, 1);
104
- this.isOperatorDropdownOpen.splice(index, 1);
105
- this.isValueDropdownOpen.splice(index, 1);
106
- }
107
- addColumn() {
108
- this.columns.push(this.fb.group({
109
- name: ['', Validators.required],
110
- sortable: [false],
111
- filterable: [false]
112
- }));
113
- this.isColumnNameDropdownOpen.push(false);
114
- }
115
- removeColumn(index) {
116
- this.columns.removeAt(index);
117
- this.isColumnNameDropdownOpen.splice(index, 1);
118
- }
119
- toggleDropdown() {
120
- this.listViewEmit.emit({ "action": 'filterGet' });
121
- this.isDropdownOpen = !this.isDropdownOpen;
122
- }
123
- // SKS3MAY25 Handles selecting a list view from the dropdown
124
- selectListView(view) {
125
- this.selectedView = view.filterName;
126
- this.selectedViewPath = view.labelPath || view.filterName;
127
- this.listViewEmit.emit({ 'action': 'select', 'data': view });
128
- this.isDropdownOpen = false;
129
- }
130
- // SKS3MAY25 Opens modal to edit an existing list view
131
- startEdit(view, event) {
132
- if (event)
133
- event.stopPropagation();
134
- this.isAdding = false;
135
- this.isModalOpen = true;
136
- this.editingView.reset();
137
- while (this.conditions.length)
138
- this.conditions.removeAt(0);
139
- while (this.columns.length)
140
- this.columns.removeAt(0);
141
- this.editingView.patchValue({
142
- filterName: view.filterName,
143
- order: view.order,
144
- isDefault: view.isDefault
145
- });
146
- view?.conditions?.forEach(filter => {
147
- this.conditions.push(this.fb.group({
148
- field: [filter.field, Validators.required],
149
- operator: [filter.operator, Validators.required],
150
- value: [filter.value, Validators.required]
151
- }));
152
- });
153
- view?.columns?.forEach(col => {
154
- this.displayedColumnsTrans.forEach(field => {
155
- if (col.name == field.fieldName) {
156
- this.columns.push(this.fb.group({
157
- name: [field.label, Validators.required],
158
- sortable: [col.sortable || false],
159
- filterable: [col.filterable || false]
160
- }));
161
- }
162
- });
163
- });
164
- }
165
- // SKS3MAY25 Opens modal to create a new list view
166
- startAdd() {
167
- this.isAdding = true;
168
- this.isModalOpen = true;
169
- this.editingView.reset();
170
- while (this.conditions.length)
171
- this.conditions.removeAt(0);
172
- while (this.columns.length)
173
- this.columns.removeAt(0);
174
- this.editingView.patchValue({
175
- order: this.listViews?.length,
176
- isDefault: false
177
- });
178
- this.isDropdownOpen = false;
179
- // SKS26MAY25 Second loop: from displayedColumnsTrans, skip duplicates
180
- this.displayedColumnsTrans.forEach(field => {
181
- this.columns.push(this.fb.group({
182
- name: [field.label, Validators.required],
183
- sortable: [field.hyperLink || false],
184
- filterable: [field.filter || false]
185
- }));
186
- });
187
- }
188
- // SKS3MAY25 Saves the currently edited or added list view
189
- save() {
190
- if (this.editingView.valid) {
191
- const formValue = this.editingView.value;
192
- formValue?.columns?.forEach((col) => {
193
- this.displayedColumnsTrans.forEach((dCol) => {
194
- if (dCol.label === col.name) {
195
- col.name = dCol.fieldName;
196
- }
197
- });
198
- });
199
- formValue?.conditions?.forEach((col) => {
200
- this.displayedColumnsTrans.forEach((dCol) => {
201
- if (dCol.label === col.field) {
202
- col.field = dCol.fieldName;
203
- }
204
- });
205
- });
206
- const listView = {
207
- filterName: formValue.filterName,
208
- labelPath: formValue.labelPath || formValue.filterName,
209
- order: formValue.order,
210
- isDefault: formValue.isDefault,
211
- conditions: formValue.conditions,
212
- columns: formValue.columns
213
- };
214
- // if (listView.isDefault) {
215
- // this.listViews.forEach(view => {
216
- // if (view.id !== listView.id) view.isDefault = false;
217
- // });
218
- // }
219
- // const existingIndex = this.listViews.findIndex(view => view.id === listView.id);
220
- // if (existingIndex >= 0) {
221
- // this.listViews[existingIndex] = { ...listView };
222
- // } else {
223
- // this.listViews.push(listView);
224
- // }
225
- this.listViews.sort((a, b) => a.order - b.order);
226
- this.selectedView = listView.filterName;
227
- this.selectedViewPath = listView.labelPath || listView.filterName;
228
- this.listViewEmit.emit({ 'action': 'save', "data": listView });
229
- this.closeModal();
230
- }
231
- }
232
- closeModal() {
233
- this.isModalOpen = false;
234
- }
235
- // SKS3MAY25 Shows action buttons for a list view on hover
236
- showActions(view) {
237
- view.showActions = true;
238
- }
239
- // SKS3MAY25 Hides action buttons for all list views
240
- hideActions() {
241
- this.listViews.forEach(view => view.showActions = false);
242
- }
243
- // SKS3MAY25 Opens confirmation modal to delete a list view
244
- confirmDelete(view, event) {
245
- if (event)
246
- event.stopPropagation();
247
- this.viewToDelete = view;
248
- this.isDeleteModalOpen = true;
249
- this.isDropdownOpen = false;
250
- }
251
- // SKS3MAY25 Closes the delete confirmation modal
252
- closeDeleteModal() {
253
- this.isDeleteModalOpen = false;
254
- this.viewToDelete = null;
255
- }
256
- // SKS3MAY25 Deletes the selected list view after confirmation
257
- deleteConfirmed() {
258
- if (this.viewToDelete) {
259
- const index = this.listViews.findIndex(view => view.filterName === this.viewToDelete?.filterName);
260
- if (index >= 0) {
261
- // this.listViews.splice(index, 1);
262
- if (this.selectedView === this.viewToDelete.filterName) {
263
- this.selectedView = this.listViews?.length > 0 ? this.listViews[0].filterName : '';
264
- this.selectedViewPath = this.listViews?.length > 0 ? this.listViews[0].labelPath : '';
265
- this.listViewEmit.emit({ 'action': 'select', 'data': this.selectedView });
266
- }
267
- this.listViewEmit.emit({ 'action': 'delete', "data": this.viewToDelete });
268
- }
269
- this.closeDeleteModal();
270
- }
271
- }
272
- // SKS3MAY25 Returns filtered list of columns based on input search term
273
- getFilteredColumns(term) {
274
- if (!term)
275
- return this.tableFilterArrayTrans;
276
- term = term.toLowerCase();
277
- return this.tableFilterArrayTrans.filter(col => col.label.toLowerCase().includes(term));
278
- }
279
- getColumnColumns(term) {
280
- console.log(term);
281
- if (!term)
282
- return this.displayedColumnsTrans;
283
- term = term.toLowerCase();
284
- return this.displayedColumnsTrans.filter(col => col.label.toLowerCase().includes(term));
285
- }
286
- // SKS3MAY25 Returns possible values for a selected field/column
287
- getPossibleValues(field, term) {
288
- const match = this.tableFilterArrayTrans.find(col => col.label === field);
289
- if (!match || !Array.isArray(match.value))
290
- return [];
291
- if (!term)
292
- return match.value;
293
- const lowerTerm = term.toLowerCase();
294
- return match.value.filter(val => typeof val === 'string' && val.toLowerCase().includes(lowerTerm));
295
- }
296
- // SKS3MAY25 Returns filtered list of operators based on input search term
297
- getFilteredOperators(term) {
298
- if (!term)
299
- return this.availableOperatorsTrans;
300
- term = term.toLowerCase();
301
- return this.availableOperatorsTrans.filter(operator => operator.label.toLowerCase().includes(term));
302
- }
303
- operatorInput = [];
304
- onOperatorInput(value, index) {
305
- this.operatorInput[index] = value;
306
- }
307
- getOperatorLabel(value) {
308
- const found = this.availableOperatorsTrans.find(op => op.value === value);
309
- return found ? found.label : value;
310
- }
311
- // SKS3MAY25 Opens a dropdown on focus for the given input type and index
312
- onFocus(type, index) {
313
- if (type === 'field') {
314
- this.isColumnDropdownOpen[index] = true;
315
- }
316
- else if (type === 'operator') {
317
- this.isOperatorDropdownOpen[index] = true;
318
- }
319
- else if (type === 'value') {
320
- this.isValueDropdownOpen[index] = true;
321
- }
322
- else if (type === 'columnName') {
323
- this.isColumnNameDropdownOpen[index] = true;
324
- }
325
- }
326
- // SKS3MAY25 Delays closing dropdown to allow selection on blur
327
- onBlur(type, index) {
328
- setTimeout(() => {
329
- if (type === 'field') {
330
- this.isColumnDropdownOpen[index] = false;
331
- }
332
- else if (type === 'operator') {
333
- this.isOperatorDropdownOpen[index] = false;
334
- }
335
- else if (type === 'value') {
336
- this.isValueDropdownOpen[index] = false;
337
- }
338
- else if (type === 'columnName') {
339
- this.isColumnNameDropdownOpen[index] = false;
340
- }
341
- }, 200);
342
- }
343
- // SKS3MAY25 Sets selected value in the form control and closes the dropdown
344
- selectOption(type, index, value) {
345
- if (type === 'field') {
346
- this.conditions.at(index).get('field')?.setValue(value);
347
- this.isColumnDropdownOpen[index] = false;
348
- }
349
- else if (type === 'operator') {
350
- this.conditions.at(index).get('operator')?.setValue(value);
351
- this.isOperatorDropdownOpen[index] = false;
352
- }
353
- else if (type === 'value') {
354
- this.conditions.at(index).get('value')?.setValue(value);
355
- this.isValueDropdownOpen[index] = false;
356
- }
357
- else if (type === 'columnName') {
358
- this.columns.at(index).get('name')?.setValue(value);
359
- this.isColumnNameDropdownOpen[index] = false;
360
- }
361
- }
362
- getLabelByFieldName(fieldName) {
363
- console.log(fieldName);
364
- const match = this.displayedColumnsTrans.find(col => col.fieldName === fieldName);
365
- return match?.label ? match.label : fieldName;
366
- }
367
- onManualInput(inputValue, index) {
368
- const match = this.displayedColumnsTrans.find(col => col.label.toLowerCase() === inputValue.toLowerCase());
369
- if (match) {
370
- this.columns.at(index).get('name').setValue(match.label);
371
- }
372
- }
373
- // SKS3MAY25 Listens to document click and closes the dropdown if clicked outside
374
- onDocumentClick(event) {
375
- event.stopPropagation();
376
- const target = event.target;
377
- if (!target.closest('.list-view-filter')) {
378
- this.isDropdownOpen = false;
379
- }
380
- }
381
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ListViewFilterComponent, deps: [{ token: i1.FormBuilder }, { token: i2.CustomTranslatePipe }], target: i0.ɵɵFactoryTarget.Component });
382
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ListViewFilterComponent, isStandalone: true, selector: "app-list-view-filter", inputs: { listViews: "listViews", tableFilterArray: "tableFilterArray", selectedView: "selectedView", displayedColumns: "displayedColumns", availableOperators: "availableOperators" }, outputs: { listViewEmit: "listViewEmit" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, providers: [CustomTranslatePipe], usesOnChanges: true, ngImport: i0, template: "<div class=\"list-view-filter\">\n <div class=\"custom-dropdown\">\n <div class=\"filter-label\">{{'APP.DATA_RELATED_TO' | customTranslate : 'Data Related to'}}</div>\n <div class=\"select-wrapper\">\n <svg class=\"filter-icon\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"24\" height=\"24\" rx=\"5\" fill=\"#F1F1F1\" />\n <path d=\"M5.51288 4.5H12.1879C12.7429 4.5 13.2004 4.9575 13.2004 5.5125V6.62249C13.2004 7.02749 12.9454 7.53 12.6979 7.785L10.5229 9.705C10.2229 9.96 10.0204 10.4625 10.0204 10.8675V13.0425C10.0204 13.3425 9.8179 13.7475 9.5629 13.905L8.85789 14.3625C8.19789 14.7675 7.29037 14.31 7.29037 13.5V10.8225C7.29037 10.47 7.08789 10.0125 6.88539 9.75751L4.96539 7.7325C4.71039 7.4775 4.5079 7.02749 4.5079 6.71999V5.5575C4.5004 4.9575 4.95788 4.5 5.51288 4.5Z\" stroke=\"#292D32\" stroke-width=\"1.5\" stroke-miterlimit=\"10\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M4.5 11.9999V14.2499C4.5 17.9999 6 19.4999 9.75 19.4999H14.25C18 19.4999 19.5 17.9999 19.5 14.2499V9.74994C19.5 7.40994 18.915 5.93993 17.5575 5.17493C17.175 4.95743 16.41 4.79243 15.7125 4.67993\" stroke=\"#292D32\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M12.75 12.75H16.5\" stroke=\"#292D32\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M11.25 15.75H16.5\" stroke=\"#292D32\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n <div class=\"custom-dropdown\">\n <div class=\"selected-option\" (click)=\"toggleDropdown()\">\n <div>\n {{ selectedView ? (selectedViewPath || selectedView | customTranslate : selectedView) : ('APP.SELECT_A_VIEW' | customTranslate : 'Select a view') }}\n </div>\n <svg class=\"chevron-icon\" width=\"24\" height=\"24\" viewBox=\"0 0 40 40\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M19.9999 25.6667C23.6818 25.6667 26.6666 22.6819 26.6666 19C26.6666 15.3181 23.6818 12.3334 19.9999 12.3334C16.318 12.3334 13.3333 15.3181 13.3333 19C13.3333 22.6819 16.318 25.6667 19.9999 25.6667Z\" fill=\"#292D32\" stroke=\"#292D32\" stroke-width=\"1.5\" stroke-miterlimit=\"10\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M17.6467 18.16L20.0001 20.5067L22.3534 18.16\" stroke=\"white\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n </div>\n </div>\n <!-- SKS3MAY25 list view Drop down-->\n <div *ngIf=\"isDropdownOpen\" class=\"dropdown-options-container\">\n <ul class=\"dropdown-options\">\n <li *ngFor=\"let view of listViews\" [class.selected]=\"selectedView === view.filterName\" (mouseenter)=\"showActions(view)\" (mouseleave)=\"hideActions()\" (click)=\"selectListView(view)\" class=\"list-view-item\">\n <span class=\"view-name\">{{ view.labelPath || view.filterName | customTranslate : view.filterName }}</span>\n <div *ngIf=\"view.showActions\">\n <div class=\"actions\">\n <div class=\"edit-icon\" (click)=\"startEdit(view, $event)\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M9.32923 3.98726L12.0126 6.67059M9.32923 3.98726L2.50008 10.8164V13.4997H5.18342L12.0126 6.67059M9.32923 3.98726L12.0126 1.30392L14.6959 3.98726L12.0126 6.67059\" stroke=\"#000000\" stroke-width=\"1\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n <div class=\"delete-icon\" (click)=\"confirmDelete(view, $event)\" *ngIf=\"listViews.length > 1\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M14 3.98726C11.78 3.76726 9.54667 3.65393 7.32 3.65393C6 3.65393 4.68 3.7206 3.36 3.85393L2 3.98726\" stroke=\"#000000\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M5.6665 3.31362L5.81317 2.44028C5.91984 1.80695 5.99984 1.33362 7.1265 1.33362H8.87317C9.99984 1.33362 10.0865 1.83362 10.1865 2.44695L10.3332 3.31362\" stroke=\"#000000\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M12.5667 6.09375L12.1334 12.8071C12.06 13.8537 12 14.6671 10.14 14.6671H5.86002C4.00002 14.6671 3.94002 13.8537 3.86668 12.8071L3.43335 6.09375\" stroke=\"#000000\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6.88647 11.0004H9.10647\" stroke=\"#000000\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6.3335 8.33325H9.66683\" stroke=\"#000000\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n </div>\n </div>\n </li>\n </ul>\n <div class=\"add-filter\" (click)=\"startAdd()\">\n <div class=\"add-icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M8 3.33325V12.6666\" stroke=\"#007bff\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M3.33301 8H12.6663\" stroke=\"#007bff\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n <span>{{'APP.NEW_LIST_VIEW' | customTranslate : 'New List View'}}</span>\n </div>\n </div>\n </div>\n <!-- SKS3MAY25 Add New List View-->\n <div *ngIf=\"isModalOpen\" class=\"modal\">\n <div class=\"modal-content\">\n <div class=\"modal-header-div\">\n {{ (isAdding ? 'APP.ADD_NEW_LIST_VIEW' : 'APP.EDIT_LIST_VIEW') | customTranslate : (isAdding ? 'Add New List View' : 'Edit List View') }} \n <span class=\"close\" (click)=\"closeModal()\">&times;</span>\n </div>\n <form [formGroup]=\"editingView\">\n <div class=\"form-row\">\n <div class=\"form-group\">\n <label>{{'APP.NAME' | customTranslate :'Name'}}:</label>\n <input formControlName=\"filterName\" [placeholder]=\"'APP.ENTER_LIST_VIEW_NAME' | customTranslate : 'Enter list view name'\" required>\n <div *ngIf=\"editingView.get('filterName')?.invalid && (editingView.get('filterName')?.dirty || editingView.get('filterName')?.touched)\" class=\"error-message\">\n {{ 'APP.NAME_IS_REQ' | customTranslate : 'Name is required'}}.\n </div>\n </div>\n <div class=\"form-group\">\n <label>{{'APP.ORDER' | customTranslate : 'Order'}}:</label>\n <input type=\"number\" formControlName=\"order\" [placeholder]=\" 'APP.ENTER_DISPLAY_ORDER' | customTranslate : 'Enter display order'\" required>\n <div *ngIf=\"editingView.get('order')?.invalid && (editingView.get('order')?.dirty || editingView.get('order')?.touched)\" class=\"error-message\">\n {{'APP.ORDER_IS_REQ_AND_BE_A_NUM' | customTranslate : 'Order is required and must be a number'}}.\n </div>\n </div>\n <div class=\"form-group\">\n <label>{{'APP.DEFAULT_VIEW' | customTranslate : 'Default View'}}:</label>\n <div class=\"toggle-wrapper small\">\n <input type=\"checkbox\" formControlName=\"isDefault\" id=\"isDefault\">\n <label for=\"isDefault\" class=\"toggle-button\"></label>\n </div>\n </div>\n </div>\n\n <div class=\"section-header\">\n <h3>{{'APP.FILTERS' | customTranslate : 'Filters'}}</h3>\n <span class=\"section-description\">{{'APP.DEFINE_CONDITIONS_FOR_FILTERED_LIST_VIEW' | customTranslate : 'Define conditions for filtered list view'}}</span>\n </div>\n <div formArrayName=\"conditions\" class=\"table-container\">\n <div class=\"table-header\">\n <div class=\"column-cell\">{{'APP.COLUMN' | customTranslate : 'Column'}}</div>\n <div class=\"operator-cell\">{{'APP.OPERATOR' | customTranslate : 'Operator'}}</div>\n <div class=\"value-cell\">{{'APP.VALUE' | customTranslate : 'Value'}}</div>\n <div class=\"action-cell\">{{'APP.ACTION' | customTranslate : 'Action'}}</div>\n </div>\n \n <div *ngFor=\"let filter of conditions.controls; let i = index\" [formGroupName]=\"i\" class=\"filter-row\">\n <div class=\"column-cell\">\n <div class=\"listview-custom-select\">\n <input formControlName=\"field\" [value]=\"getLabelByFieldName(conditions.at(i).get('field').value)\" (focus)=\"onFocus('field', i)\" (blur)=\"onBlur('field', i)\" [placeholder]=\"'APP.ENTER_OR_SELECT_COLUMN' | customTranslate : 'Enter or select column'\">\n <div class=\"dropdown-list\" *ngIf=\"isColumnDropdownOpen[i]\">\n <div *ngFor=\"let field of getFilteredColumns(conditions.at(i).get('field').value)\" class=\"dropdown-item\" (click)=\"selectOption('field', i, field.label)\">\n {{ field.label }}\n </div>\n </div>\n </div>\n <div *ngIf=\"filter.get('field')?.invalid && (filter.get('field')?.dirty || filter.get('field')?.touched)\" class=\"error-message\">\n {{'APP.COLUMN_IS_REQ' | customTranslate : 'Column is required'}}.\n </div>\n </div>\n \n <div class=\"operator-cell\">\n <div class=\"listview-custom-select\">\n <input\n [value]=\"getOperatorLabel(conditions.at(i).get('operator').value)\"\n (input)=\"onOperatorInput($event.target.value, i)\"\n (focus)=\"onFocus('operator', i)\"\n (blur)=\"onBlur('operator', i)\"\n [placeholder]=\"'APP.ENTER_OR_SELECT_OPERATOR' | customTranslate : 'Enter or select operator'\"\n />\n \n <div class=\"dropdown-list\" *ngIf=\"isOperatorDropdownOpen[i]\">\n <div\n *ngFor=\"let operator of getFilteredOperators(operatorInput[i])\"\n class=\"dropdown-item\"\n (click)=\"selectOption('operator', i, operator.value)\"\n >\n {{ operator.label }}\n </div>\n </div>\n </div> \n <div *ngIf=\"filter.get('operator')?.invalid && (filter.get('operator')?.dirty || filter.get('operator')?.touched)\" class=\"error-message\">\n {{'APP.OPERATOR_IS_REQ' | customTranslate : 'Operator is required'}}.\n </div>\n </div>\n \n <div class=\"value-cell\">\n <div class=\"listview-custom-select\">\n <input formControlName=\"value\" (focus)=\"onFocus('value', i)\" (blur)=\"onBlur('value', i)\" [placeholder]=\"'APP.ENTER_OR_SELECT_VALUE' | customTranslate : 'Enter or select value'\">\n <div class=\"dropdown-list\" *ngIf=\"isValueDropdownOpen[i] && getPossibleValues(conditions.at(i).get('field').value, conditions.at(i).get('value').value)?.length > 0\">\n <div *ngFor=\"let val of getPossibleValues(conditions.at(i).get('field').value, conditions.at(i).get('value').value)\" class=\"dropdown-item\" (click)=\"selectOption('value', i, val)\">\n {{ val }}\n </div>\n </div>\n </div>\n <div *ngIf=\"filter.get('value')?.invalid && (filter.get('value')?.dirty || filter.get('value')?.touched)\" class=\"error-message\">\n {{'APP.VALUE_IS_REQUIRED' | customTranslate : 'Value is required'}}.\n </div>\n </div>\n \n <div class=\"action-cell\">\n <div class=\"dicon-container\" [matTooltip]=\"'APP.REMOVE' | customTranslate : 'Remove'\">\n <div class=\"delete-icon\" (click)=\"removeFilter(i)\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M14 3.98726C11.78 3.76726 9.54667 3.65393 7.32 3.65393C6 3.65393 4.68 3.7206 3.36 3.85393L2 3.98726\" stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M5.6665 3.31362L5.81317 2.44028C5.91984 1.80695 5.99984 1.33362 7.1265 1.33362H8.87317C9.99984 1.33362 10.0865 1.83362 10.1865 2.44695L10.3332 3.31362\" stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M12.5667 6.09375L12.1334 12.8071C12.06 13.8537 12 14.6671 10.14 14.6671H5.86002C4.00002 14.6671 3.94002 13.8537 3.86668 12.8071L3.43335 6.09375\" stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6.88647 11.0004H9.10647\" stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6.3335 8.33325H9.66683\" stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n </div>\n </div>\n </div>\n \n <div class=\"add-row\">\n <div class=\"flex addIconBor cursor-pointer\" (click)=\"addFilter()\" [matTooltip]=\"'APP.ADD_FILTER' | customTranslate : 'Add Filter'\">\n <div class=\"addIcon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M8 3.33325V12.6666\" stroke=\"#007bff\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M3.33301 8H12.6663\" stroke=\"#007bff\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n </div>\n <span>{{'APP.ADD_FILTER' | customTranslate : 'Add Filter'}}</span>\n </div>\n </div>\n\n <div class=\"section-header\">\n <h3>{{'APP.COLUMNS' | customTranslate : 'Columns'}}</h3>\n <span class=\"section-description\">{{'APP.SELECT_FIELD_TO_DISPLAY_IN_TABLE' | customTranslate : 'Select field to display in table'}}</span>\n </div>\n <div formArrayName=\"columns\" class=\"table-container\">\n <div class=\"table-header\">\n <div class=\"name-cell\">{{'APP.COLUMN_NAME' | customTranslate : 'Column Name'}}</div>\n <div class=\"bool-cell\">{{'APP.SORTABLE' | customTranslate : 'Sortable'}}</div>\n <div class=\"bool-cell\">{{'APP.FILTERABLE' | customTranslate :'Filterable'}}</div>\n <div class=\"action-cell\">{{'APP.ACTION' | customTranslate : 'Action'}}</div>\n </div>\n \n <div *ngFor=\"let field of columns.controls; let i = index\" [formGroupName]=\"i\" class=\"column-row\">\n <div class=\"name-cell\">\n <div class=\"listview-custom-select\">\n <input \n formControlName=\"name\" \n (focus)=\"onFocus('columnName', i)\" \n (blur)=\"onBlur('columnName', i)\" \n (input)=\"onManualInput($event.target.value, i)\"\n [placeholder]=\"'APP.ENTER_OR_SELECT_COLUMN_NAME' | customTranslate : 'Enter or select column name'\">\n <div class=\"dropdown-list\" *ngIf=\"isColumnNameDropdownOpen[i]\">\n <div *ngFor=\"let colName of getColumnColumns(columns.at(i).get('name').value)\" class=\"dropdown-item\" (click)=\"selectOption('columnName', i, colName.label); isColumnNameDropdownOpen[i] = false\">\n {{ colName.label }}\n </div>\n </div>\n </div>\n <div *ngIf=\"field.get('name')?.invalid && (field.get('name')?.dirty || field.get('name')?.touched)\" class=\"error-message\">\n {{'APP.COLUMN_NAME_IS_REQ' | customTranslate : 'Column name is required'}}.\n </div>\n </div>\n \n <div class=\"bool-cell\">\n <div class=\"toggle-wrapper small\">\n <input type=\"checkbox\" [id]=\"'sortable-' + i\" formControlName=\"sortable\">\n <label [for]=\"'sortable-' + i\" class=\"toggle-button\"></label>\n </div>\n </div>\n \n <div class=\"bool-cell\">\n <div class=\"toggle-wrapper small\">\n <input type=\"checkbox\" [id]=\"'filterable-' + i\" formControlName=\"filterable\">\n <label [for]=\"'filterable-' + i\" class=\"toggle-button\"></label>\n </div>\n </div>\n \n <div class=\"action-cell\">\n <div class=\"dicon-container\" [matTooltip]=\"'APP.REMOVE' | customTranslate : 'Remove'\">\n <div class=\"delete-icon\" (click)=\"removeColumn(i)\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M14 3.98726C11.78 3.76726 9.54667 3.65393 7.32 3.65393C6 3.65393 4.68 3.7206 3.36 3.85393L2 3.98726\" stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M5.6665 3.31362L5.81317 2.44028C5.91984 1.80695 5.99984 1.33362 7.1265 1.33362H8.87317C9.99984 1.33362 10.0865 1.83362 10.1865 2.44695L10.3332 3.31362\" stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M12.5667 6.09375L12.1334 12.8071C12.06 13.8537 12 14.6671 10.14 14.6671H5.86002C4.00002 14.6671 3.94002 13.8537 3.86668 12.8071L3.43335 6.09375\" stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6.88647 11.0004H9.10647\" stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6.3335 8.33325H9.66683\" stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n </div>\n </div>\n </div>\n \n <div class=\"add-row\">\n <div class=\"flex addIconBor cursor-pointer\" (click)=\"addColumn()\" [matTooltip]=\"'APP.ADD_COLUMN' | customTranslate : 'Add Column'\">\n <div class=\"addIcon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M8 3.33325V12.6666\" stroke=\"#007bff\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M3.33301 8H12.6663\" stroke=\"#007bff\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n </div>\n <span>{{'APP.ADD_COLUMN' | customTranslate : 'Add Column'}}</span>\n </div>\n </div>\n <div *ngIf=\"conditions.length === 0 && columns.length === 0\" class=\"error-message\">\n {{'APP.AT_LEAST_ONE_FILTER_OR_ONE_COLUMN_IS_REQ' | customTranslate : ' At least one filter or one column is required'}}.\n </div> \n <div class=\"form-actions\">\n <button type=\"button\" class=\"save-button\" (click)=\"save()\" [disabled]=\"!editingView.valid || (conditions.length === 0 && columns.length === 0)\">{{'APP.SAVE' | customTranslate : 'Save'}}</button>\n <button type=\"button\" (click)=\"closeModal()\">{{'APP.CANCEL' | customTranslate : 'Cancel'}}</button>\n </div>\n </form>\n </div>\n </div>\n <!-- SKS3MAY25 Delete List View-->\n <div *ngIf=\"isDeleteModalOpen\" class=\"modal\">\n <div class=\"modal-content\">\n <h2>{{'APP.DELETE_LIST_VIEW' | customTranslate : 'Delete List View'}}</h2>\n <p>{{'APP.ARE_YOU_SURE_YOU_WANT_TO_DELETE' | customTranslate : 'Are you sure you want to delete'}} \"{{ viewToDelete?.filterName }}\"?</p>\n <div class=\"form-delete\">\n <button type=\"button\" (click)=\"deleteConfirmed()\">{{'APP.DELETE' | customTranslate : 'Delete'}}</button>\n <button type=\"button\" (click)=\"closeDeleteModal()\">{{'APP.CANCEL' | customTranslate : 'Cancel'}}</button>\n </div>\n </div>\n </div>\n</div>", styles: [".list-view-filter{padding-left:10px;padding-right:10px}.filter-label{font-size:11px;color:#747577;margin-right:8px}.select-wrapper{display:flex;align-items:center;cursor:pointer}.custom-dropdown{position:relative;cursor:pointer;display:inline-block}.selected-option{padding:2px 5px;font-size:16px;font-weight:700;display:flex;gap:8px}.chevron-icon{cursor:pointer;background-color:#f5f5f5;border-radius:5px}.dropdown-options-container{position:absolute;top:100%;display:flex;flex-direction:column;border:1px solid #ccc;background:#fff;box-shadow:0 2px 8px #0000001a;z-index:1000;min-width:250px}.dropdown-options{background:#fff;list-style:none;padding:0;margin:0;white-space:nowrap;width:100%;max-height:300px;overflow-y:auto}.dropdown-options li{padding:8px;cursor:pointer}.dropdown-options li:hover{background-color:#f1f1f1}.dropdown-options li.selected{background-color:#f1f1f1;font-weight:600}.list-view-item{display:flex;justify-content:space-between;padding:8px;cursor:pointer;border-bottom:1px solid #f0f0f0}.list-view-item:hover{background-color:#f8f9fa}.actions{display:flex;gap:10px}.edit-icon,.delete-icon{cursor:pointer;color:#666;transition:color .2s}.edit-icon:hover{color:#007bff}.delete-icon:hover{color:#dc3545}.add-filter{background-color:#fff;padding:10px;border-top:1px solid #dddddd;cursor:pointer;display:flex;align-items:center;gap:8px;width:100%}.add-filter:hover{background-color:#f8f9fa}.add-icon{padding:1px;border-radius:5px;background-color:#ddd;transition:background-color .3s}.modal{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:1001}.modal-content{background-color:#fff;border-radius:8px;padding:24px;width:700px;max-width:95%;max-height:90vh;overflow-y:auto;box-shadow:0 4px 20px #00000026}.modal-content h2{margin-top:0;margin-bottom:20px;font-size:20px;color:#333}.form-group{margin-bottom:16px}.form-group label{display:block;margin-bottom:8px;font-size:14px;font-weight:500}.form-group input{width:100%;padding:8px 12px;border:1px solid #ddd;border-radius:4px;font-size:14px}.toggle-wrapper{position:relative;display:inline-block}.toggle-wrapper input[type=checkbox]{opacity:0;width:0;height:0}.toggle-button{position:relative;display:inline-block;width:50px;height:24px;background-color:#ccc;border-radius:24px;transition:.3s;cursor:pointer}.toggle-button:before{position:absolute;content:\"\";height:20px;width:20px;left:2px;bottom:2px;background-color:#fff;border-radius:50%;transition:.3s}input[type=checkbox]:checked+.toggle-button{background-color:#007bff}input[type=checkbox]:checked+.toggle-button:before{transform:translate(20px)}.toggle-wrapper.small .toggle-button{width:40px;height:20px}.toggle-wrapper.small .toggle-button:before{height:16px;width:16px}input[type=checkbox]:checked+.toggle-button.small:before{transform:translate(20px)}.section-header{padding-bottom:8px}.section-header h3{margin:0 0 4px;font-size:16px;color:#333}.section-description{font-size:12px;color:#777}.table-container{border:1px solid #e0e0e0;border-radius:4px}.table-header{display:grid;background-color:#f8f9fa;font-weight:600;font-size:12px;padding:8px 12px;border-bottom:1px solid #e0e0e0}.filter-row,.column-row{display:grid;padding:8px 12px;border-bottom:1px solid #f0f0f0;align-items:center}.filter-row,.column-row,.table-header{grid-template-columns:1fr 1fr 1fr auto;gap:10px}.table-header.column-header{grid-template-columns:1fr 1fr 1fr auto}.column-cell,.operator-cell,.value-cell,.name-cell,.bool-cell,.action-cell{padding:5px}.action-cell{display:flex;justify-content:center}.listview-custom-select{position:relative;width:100%}.listview-custom-select input{border:none;font-size:12px}.dropdown-list{position:absolute;top:100%;left:0;width:100%;max-height:200px;overflow-y:auto;background:#fff;border:1px solid #ddd;border-top:none;border-radius:0 0 4px 4px;z-index:10;box-shadow:0 4px 8px #0000001a}.dropdown-item{padding:8px 12px;cursor:pointer}.dropdown-item:hover{background-color:#f5f5f5}.add-row{display:flex;align-items:center;gap:8px;padding:10px;cursor:pointer}.add-row:hover{background-color:#f8f9fa}.addIconBor{padding:4px;border-radius:5px;border:1px solid #6c757d;transition:background-color .3s,border-color .3s}.addIconBor:hover .addIcon{background-color:#bbd3ff}.addIcon{padding:1px;border-radius:5px;background-color:#ddd;transition:background-color .3s}.dicon-container{padding:2px;border:1px solid #ffb5b5;border-radius:5px;margin-left:3px;margin-right:3px;display:flex;width:38px}.delete-icon{padding:2px 4px;border-radius:5px;background-color:#feeeed;align-content:center;width:32px;display:flex;justify-content:center;align-items:center}.dicon-container:hover .delete-icon svg path{stroke:#fff!important;fill:transparent!important}.dicon-container:hover .delete-icon{background-color:#ff7575!important;cursor:pointer}.dicon-container:hover{border:1px solid #ff2121!important}.form-actions{display:flex;justify-content:flex-end;gap:12px;margin-top:20px}.form-delete{display:flex;justify-content:flex-end;gap:12px}.form-actions button,.form-delete button{padding:8px 16px;border-radius:4px;font-size:14px;cursor:pointer;transition:background-color .2s}.form-actions button:first-child{background-color:#007bff;color:#fff;border:1px solid #007bff}.form-actions button:nth-child(2){background-color:#f8f9fa;border:1px solid #ddd;color:#333}.form-delete button:first-child{background-color:#dc3545;color:#fff;border:1px solid #dc3545}.form-delete button:nth-child(2){background-color:#f8f9fa;border:1px solid #ddd;color:#333}.form-actions button:hover,.form-delete button:hover{opacity:.9}.cursor-pointer{cursor:pointer}.flex{display:flex}.form-row{display:flex;gap:16px;align-items:flex-start}.form-group{min-width:0;margin-bottom:0!important}.error-message{color:#dc3545;font-size:12px;margin-top:4px}.listview-custom-select input[readonly]{cursor:pointer;background-color:#fff}.error-message{color:#ff2c10;font-size:.875rem;margin-bottom:.5rem}.save-button:disabled{background-color:#ccc!important;color:#666!important;cursor:not-allowed!important}.modal-header-div{display:flex;justify-content:space-between;font-size:18px;padding-bottom:10px}.close{color:#aaa;float:right;font-size:28px;font-weight:700}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "pipe", type: CustomTranslatePipe, name: "customTranslate" }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
383
- }
384
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ListViewFilterComponent, decorators: [{
385
- type: Component,
386
- args: [{ selector: 'app-list-view-filter', standalone: true, imports: [CommonModule, FormsModule, ReactiveFormsModule, CustomTranslatePipe, MatTooltipModule], providers: [CustomTranslatePipe], template: "<div class=\"list-view-filter\">\n <div class=\"custom-dropdown\">\n <div class=\"filter-label\">{{'APP.DATA_RELATED_TO' | customTranslate : 'Data Related to'}}</div>\n <div class=\"select-wrapper\">\n <svg class=\"filter-icon\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"24\" height=\"24\" rx=\"5\" fill=\"#F1F1F1\" />\n <path d=\"M5.51288 4.5H12.1879C12.7429 4.5 13.2004 4.9575 13.2004 5.5125V6.62249C13.2004 7.02749 12.9454 7.53 12.6979 7.785L10.5229 9.705C10.2229 9.96 10.0204 10.4625 10.0204 10.8675V13.0425C10.0204 13.3425 9.8179 13.7475 9.5629 13.905L8.85789 14.3625C8.19789 14.7675 7.29037 14.31 7.29037 13.5V10.8225C7.29037 10.47 7.08789 10.0125 6.88539 9.75751L4.96539 7.7325C4.71039 7.4775 4.5079 7.02749 4.5079 6.71999V5.5575C4.5004 4.9575 4.95788 4.5 5.51288 4.5Z\" stroke=\"#292D32\" stroke-width=\"1.5\" stroke-miterlimit=\"10\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M4.5 11.9999V14.2499C4.5 17.9999 6 19.4999 9.75 19.4999H14.25C18 19.4999 19.5 17.9999 19.5 14.2499V9.74994C19.5 7.40994 18.915 5.93993 17.5575 5.17493C17.175 4.95743 16.41 4.79243 15.7125 4.67993\" stroke=\"#292D32\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M12.75 12.75H16.5\" stroke=\"#292D32\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M11.25 15.75H16.5\" stroke=\"#292D32\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n <div class=\"custom-dropdown\">\n <div class=\"selected-option\" (click)=\"toggleDropdown()\">\n <div>\n {{ selectedView ? (selectedViewPath || selectedView | customTranslate : selectedView) : ('APP.SELECT_A_VIEW' | customTranslate : 'Select a view') }}\n </div>\n <svg class=\"chevron-icon\" width=\"24\" height=\"24\" viewBox=\"0 0 40 40\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M19.9999 25.6667C23.6818 25.6667 26.6666 22.6819 26.6666 19C26.6666 15.3181 23.6818 12.3334 19.9999 12.3334C16.318 12.3334 13.3333 15.3181 13.3333 19C13.3333 22.6819 16.318 25.6667 19.9999 25.6667Z\" fill=\"#292D32\" stroke=\"#292D32\" stroke-width=\"1.5\" stroke-miterlimit=\"10\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M17.6467 18.16L20.0001 20.5067L22.3534 18.16\" stroke=\"white\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n </div>\n </div>\n <!-- SKS3MAY25 list view Drop down-->\n <div *ngIf=\"isDropdownOpen\" class=\"dropdown-options-container\">\n <ul class=\"dropdown-options\">\n <li *ngFor=\"let view of listViews\" [class.selected]=\"selectedView === view.filterName\" (mouseenter)=\"showActions(view)\" (mouseleave)=\"hideActions()\" (click)=\"selectListView(view)\" class=\"list-view-item\">\n <span class=\"view-name\">{{ view.labelPath || view.filterName | customTranslate : view.filterName }}</span>\n <div *ngIf=\"view.showActions\">\n <div class=\"actions\">\n <div class=\"edit-icon\" (click)=\"startEdit(view, $event)\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M9.32923 3.98726L12.0126 6.67059M9.32923 3.98726L2.50008 10.8164V13.4997H5.18342L12.0126 6.67059M9.32923 3.98726L12.0126 1.30392L14.6959 3.98726L12.0126 6.67059\" stroke=\"#000000\" stroke-width=\"1\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n <div class=\"delete-icon\" (click)=\"confirmDelete(view, $event)\" *ngIf=\"listViews.length > 1\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M14 3.98726C11.78 3.76726 9.54667 3.65393 7.32 3.65393C6 3.65393 4.68 3.7206 3.36 3.85393L2 3.98726\" stroke=\"#000000\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M5.6665 3.31362L5.81317 2.44028C5.91984 1.80695 5.99984 1.33362 7.1265 1.33362H8.87317C9.99984 1.33362 10.0865 1.83362 10.1865 2.44695L10.3332 3.31362\" stroke=\"#000000\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M12.5667 6.09375L12.1334 12.8071C12.06 13.8537 12 14.6671 10.14 14.6671H5.86002C4.00002 14.6671 3.94002 13.8537 3.86668 12.8071L3.43335 6.09375\" stroke=\"#000000\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6.88647 11.0004H9.10647\" stroke=\"#000000\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6.3335 8.33325H9.66683\" stroke=\"#000000\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n </div>\n </div>\n </li>\n </ul>\n <div class=\"add-filter\" (click)=\"startAdd()\">\n <div class=\"add-icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M8 3.33325V12.6666\" stroke=\"#007bff\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M3.33301 8H12.6663\" stroke=\"#007bff\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n <span>{{'APP.NEW_LIST_VIEW' | customTranslate : 'New List View'}}</span>\n </div>\n </div>\n </div>\n <!-- SKS3MAY25 Add New List View-->\n <div *ngIf=\"isModalOpen\" class=\"modal\">\n <div class=\"modal-content\">\n <div class=\"modal-header-div\">\n {{ (isAdding ? 'APP.ADD_NEW_LIST_VIEW' : 'APP.EDIT_LIST_VIEW') | customTranslate : (isAdding ? 'Add New List View' : 'Edit List View') }} \n <span class=\"close\" (click)=\"closeModal()\">&times;</span>\n </div>\n <form [formGroup]=\"editingView\">\n <div class=\"form-row\">\n <div class=\"form-group\">\n <label>{{'APP.NAME' | customTranslate :'Name'}}:</label>\n <input formControlName=\"filterName\" [placeholder]=\"'APP.ENTER_LIST_VIEW_NAME' | customTranslate : 'Enter list view name'\" required>\n <div *ngIf=\"editingView.get('filterName')?.invalid && (editingView.get('filterName')?.dirty || editingView.get('filterName')?.touched)\" class=\"error-message\">\n {{ 'APP.NAME_IS_REQ' | customTranslate : 'Name is required'}}.\n </div>\n </div>\n <div class=\"form-group\">\n <label>{{'APP.ORDER' | customTranslate : 'Order'}}:</label>\n <input type=\"number\" formControlName=\"order\" [placeholder]=\" 'APP.ENTER_DISPLAY_ORDER' | customTranslate : 'Enter display order'\" required>\n <div *ngIf=\"editingView.get('order')?.invalid && (editingView.get('order')?.dirty || editingView.get('order')?.touched)\" class=\"error-message\">\n {{'APP.ORDER_IS_REQ_AND_BE_A_NUM' | customTranslate : 'Order is required and must be a number'}}.\n </div>\n </div>\n <div class=\"form-group\">\n <label>{{'APP.DEFAULT_VIEW' | customTranslate : 'Default View'}}:</label>\n <div class=\"toggle-wrapper small\">\n <input type=\"checkbox\" formControlName=\"isDefault\" id=\"isDefault\">\n <label for=\"isDefault\" class=\"toggle-button\"></label>\n </div>\n </div>\n </div>\n\n <div class=\"section-header\">\n <h3>{{'APP.FILTERS' | customTranslate : 'Filters'}}</h3>\n <span class=\"section-description\">{{'APP.DEFINE_CONDITIONS_FOR_FILTERED_LIST_VIEW' | customTranslate : 'Define conditions for filtered list view'}}</span>\n </div>\n <div formArrayName=\"conditions\" class=\"table-container\">\n <div class=\"table-header\">\n <div class=\"column-cell\">{{'APP.COLUMN' | customTranslate : 'Column'}}</div>\n <div class=\"operator-cell\">{{'APP.OPERATOR' | customTranslate : 'Operator'}}</div>\n <div class=\"value-cell\">{{'APP.VALUE' | customTranslate : 'Value'}}</div>\n <div class=\"action-cell\">{{'APP.ACTION' | customTranslate : 'Action'}}</div>\n </div>\n \n <div *ngFor=\"let filter of conditions.controls; let i = index\" [formGroupName]=\"i\" class=\"filter-row\">\n <div class=\"column-cell\">\n <div class=\"listview-custom-select\">\n <input formControlName=\"field\" [value]=\"getLabelByFieldName(conditions.at(i).get('field').value)\" (focus)=\"onFocus('field', i)\" (blur)=\"onBlur('field', i)\" [placeholder]=\"'APP.ENTER_OR_SELECT_COLUMN' | customTranslate : 'Enter or select column'\">\n <div class=\"dropdown-list\" *ngIf=\"isColumnDropdownOpen[i]\">\n <div *ngFor=\"let field of getFilteredColumns(conditions.at(i).get('field').value)\" class=\"dropdown-item\" (click)=\"selectOption('field', i, field.label)\">\n {{ field.label }}\n </div>\n </div>\n </div>\n <div *ngIf=\"filter.get('field')?.invalid && (filter.get('field')?.dirty || filter.get('field')?.touched)\" class=\"error-message\">\n {{'APP.COLUMN_IS_REQ' | customTranslate : 'Column is required'}}.\n </div>\n </div>\n \n <div class=\"operator-cell\">\n <div class=\"listview-custom-select\">\n <input\n [value]=\"getOperatorLabel(conditions.at(i).get('operator').value)\"\n (input)=\"onOperatorInput($event.target.value, i)\"\n (focus)=\"onFocus('operator', i)\"\n (blur)=\"onBlur('operator', i)\"\n [placeholder]=\"'APP.ENTER_OR_SELECT_OPERATOR' | customTranslate : 'Enter or select operator'\"\n />\n \n <div class=\"dropdown-list\" *ngIf=\"isOperatorDropdownOpen[i]\">\n <div\n *ngFor=\"let operator of getFilteredOperators(operatorInput[i])\"\n class=\"dropdown-item\"\n (click)=\"selectOption('operator', i, operator.value)\"\n >\n {{ operator.label }}\n </div>\n </div>\n </div> \n <div *ngIf=\"filter.get('operator')?.invalid && (filter.get('operator')?.dirty || filter.get('operator')?.touched)\" class=\"error-message\">\n {{'APP.OPERATOR_IS_REQ' | customTranslate : 'Operator is required'}}.\n </div>\n </div>\n \n <div class=\"value-cell\">\n <div class=\"listview-custom-select\">\n <input formControlName=\"value\" (focus)=\"onFocus('value', i)\" (blur)=\"onBlur('value', i)\" [placeholder]=\"'APP.ENTER_OR_SELECT_VALUE' | customTranslate : 'Enter or select value'\">\n <div class=\"dropdown-list\" *ngIf=\"isValueDropdownOpen[i] && getPossibleValues(conditions.at(i).get('field').value, conditions.at(i).get('value').value)?.length > 0\">\n <div *ngFor=\"let val of getPossibleValues(conditions.at(i).get('field').value, conditions.at(i).get('value').value)\" class=\"dropdown-item\" (click)=\"selectOption('value', i, val)\">\n {{ val }}\n </div>\n </div>\n </div>\n <div *ngIf=\"filter.get('value')?.invalid && (filter.get('value')?.dirty || filter.get('value')?.touched)\" class=\"error-message\">\n {{'APP.VALUE_IS_REQUIRED' | customTranslate : 'Value is required'}}.\n </div>\n </div>\n \n <div class=\"action-cell\">\n <div class=\"dicon-container\" [matTooltip]=\"'APP.REMOVE' | customTranslate : 'Remove'\">\n <div class=\"delete-icon\" (click)=\"removeFilter(i)\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M14 3.98726C11.78 3.76726 9.54667 3.65393 7.32 3.65393C6 3.65393 4.68 3.7206 3.36 3.85393L2 3.98726\" stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M5.6665 3.31362L5.81317 2.44028C5.91984 1.80695 5.99984 1.33362 7.1265 1.33362H8.87317C9.99984 1.33362 10.0865 1.83362 10.1865 2.44695L10.3332 3.31362\" stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M12.5667 6.09375L12.1334 12.8071C12.06 13.8537 12 14.6671 10.14 14.6671H5.86002C4.00002 14.6671 3.94002 13.8537 3.86668 12.8071L3.43335 6.09375\" stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6.88647 11.0004H9.10647\" stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6.3335 8.33325H9.66683\" stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n </div>\n </div>\n </div>\n \n <div class=\"add-row\">\n <div class=\"flex addIconBor cursor-pointer\" (click)=\"addFilter()\" [matTooltip]=\"'APP.ADD_FILTER' | customTranslate : 'Add Filter'\">\n <div class=\"addIcon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M8 3.33325V12.6666\" stroke=\"#007bff\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M3.33301 8H12.6663\" stroke=\"#007bff\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n </div>\n <span>{{'APP.ADD_FILTER' | customTranslate : 'Add Filter'}}</span>\n </div>\n </div>\n\n <div class=\"section-header\">\n <h3>{{'APP.COLUMNS' | customTranslate : 'Columns'}}</h3>\n <span class=\"section-description\">{{'APP.SELECT_FIELD_TO_DISPLAY_IN_TABLE' | customTranslate : 'Select field to display in table'}}</span>\n </div>\n <div formArrayName=\"columns\" class=\"table-container\">\n <div class=\"table-header\">\n <div class=\"name-cell\">{{'APP.COLUMN_NAME' | customTranslate : 'Column Name'}}</div>\n <div class=\"bool-cell\">{{'APP.SORTABLE' | customTranslate : 'Sortable'}}</div>\n <div class=\"bool-cell\">{{'APP.FILTERABLE' | customTranslate :'Filterable'}}</div>\n <div class=\"action-cell\">{{'APP.ACTION' | customTranslate : 'Action'}}</div>\n </div>\n \n <div *ngFor=\"let field of columns.controls; let i = index\" [formGroupName]=\"i\" class=\"column-row\">\n <div class=\"name-cell\">\n <div class=\"listview-custom-select\">\n <input \n formControlName=\"name\" \n (focus)=\"onFocus('columnName', i)\" \n (blur)=\"onBlur('columnName', i)\" \n (input)=\"onManualInput($event.target.value, i)\"\n [placeholder]=\"'APP.ENTER_OR_SELECT_COLUMN_NAME' | customTranslate : 'Enter or select column name'\">\n <div class=\"dropdown-list\" *ngIf=\"isColumnNameDropdownOpen[i]\">\n <div *ngFor=\"let colName of getColumnColumns(columns.at(i).get('name').value)\" class=\"dropdown-item\" (click)=\"selectOption('columnName', i, colName.label); isColumnNameDropdownOpen[i] = false\">\n {{ colName.label }}\n </div>\n </div>\n </div>\n <div *ngIf=\"field.get('name')?.invalid && (field.get('name')?.dirty || field.get('name')?.touched)\" class=\"error-message\">\n {{'APP.COLUMN_NAME_IS_REQ' | customTranslate : 'Column name is required'}}.\n </div>\n </div>\n \n <div class=\"bool-cell\">\n <div class=\"toggle-wrapper small\">\n <input type=\"checkbox\" [id]=\"'sortable-' + i\" formControlName=\"sortable\">\n <label [for]=\"'sortable-' + i\" class=\"toggle-button\"></label>\n </div>\n </div>\n \n <div class=\"bool-cell\">\n <div class=\"toggle-wrapper small\">\n <input type=\"checkbox\" [id]=\"'filterable-' + i\" formControlName=\"filterable\">\n <label [for]=\"'filterable-' + i\" class=\"toggle-button\"></label>\n </div>\n </div>\n \n <div class=\"action-cell\">\n <div class=\"dicon-container\" [matTooltip]=\"'APP.REMOVE' | customTranslate : 'Remove'\">\n <div class=\"delete-icon\" (click)=\"removeColumn(i)\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M14 3.98726C11.78 3.76726 9.54667 3.65393 7.32 3.65393C6 3.65393 4.68 3.7206 3.36 3.85393L2 3.98726\" stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M5.6665 3.31362L5.81317 2.44028C5.91984 1.80695 5.99984 1.33362 7.1265 1.33362H8.87317C9.99984 1.33362 10.0865 1.83362 10.1865 2.44695L10.3332 3.31362\" stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M12.5667 6.09375L12.1334 12.8071C12.06 13.8537 12 14.6671 10.14 14.6671H5.86002C4.00002 14.6671 3.94002 13.8537 3.86668 12.8071L3.43335 6.09375\" stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6.88647 11.0004H9.10647\" stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6.3335 8.33325H9.66683\" stroke=\"#FF2C10\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n </div>\n </div>\n </div>\n \n <div class=\"add-row\">\n <div class=\"flex addIconBor cursor-pointer\" (click)=\"addColumn()\" [matTooltip]=\"'APP.ADD_COLUMN' | customTranslate : 'Add Column'\">\n <div class=\"addIcon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M8 3.33325V12.6666\" stroke=\"#007bff\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M3.33301 8H12.6663\" stroke=\"#007bff\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n </div>\n <span>{{'APP.ADD_COLUMN' | customTranslate : 'Add Column'}}</span>\n </div>\n </div>\n <div *ngIf=\"conditions.length === 0 && columns.length === 0\" class=\"error-message\">\n {{'APP.AT_LEAST_ONE_FILTER_OR_ONE_COLUMN_IS_REQ' | customTranslate : ' At least one filter or one column is required'}}.\n </div> \n <div class=\"form-actions\">\n <button type=\"button\" class=\"save-button\" (click)=\"save()\" [disabled]=\"!editingView.valid || (conditions.length === 0 && columns.length === 0)\">{{'APP.SAVE' | customTranslate : 'Save'}}</button>\n <button type=\"button\" (click)=\"closeModal()\">{{'APP.CANCEL' | customTranslate : 'Cancel'}}</button>\n </div>\n </form>\n </div>\n </div>\n <!-- SKS3MAY25 Delete List View-->\n <div *ngIf=\"isDeleteModalOpen\" class=\"modal\">\n <div class=\"modal-content\">\n <h2>{{'APP.DELETE_LIST_VIEW' | customTranslate : 'Delete List View'}}</h2>\n <p>{{'APP.ARE_YOU_SURE_YOU_WANT_TO_DELETE' | customTranslate : 'Are you sure you want to delete'}} \"{{ viewToDelete?.filterName }}\"?</p>\n <div class=\"form-delete\">\n <button type=\"button\" (click)=\"deleteConfirmed()\">{{'APP.DELETE' | customTranslate : 'Delete'}}</button>\n <button type=\"button\" (click)=\"closeDeleteModal()\">{{'APP.CANCEL' | customTranslate : 'Cancel'}}</button>\n </div>\n </div>\n </div>\n</div>", styles: [".list-view-filter{padding-left:10px;padding-right:10px}.filter-label{font-size:11px;color:#747577;margin-right:8px}.select-wrapper{display:flex;align-items:center;cursor:pointer}.custom-dropdown{position:relative;cursor:pointer;display:inline-block}.selected-option{padding:2px 5px;font-size:16px;font-weight:700;display:flex;gap:8px}.chevron-icon{cursor:pointer;background-color:#f5f5f5;border-radius:5px}.dropdown-options-container{position:absolute;top:100%;display:flex;flex-direction:column;border:1px solid #ccc;background:#fff;box-shadow:0 2px 8px #0000001a;z-index:1000;min-width:250px}.dropdown-options{background:#fff;list-style:none;padding:0;margin:0;white-space:nowrap;width:100%;max-height:300px;overflow-y:auto}.dropdown-options li{padding:8px;cursor:pointer}.dropdown-options li:hover{background-color:#f1f1f1}.dropdown-options li.selected{background-color:#f1f1f1;font-weight:600}.list-view-item{display:flex;justify-content:space-between;padding:8px;cursor:pointer;border-bottom:1px solid #f0f0f0}.list-view-item:hover{background-color:#f8f9fa}.actions{display:flex;gap:10px}.edit-icon,.delete-icon{cursor:pointer;color:#666;transition:color .2s}.edit-icon:hover{color:#007bff}.delete-icon:hover{color:#dc3545}.add-filter{background-color:#fff;padding:10px;border-top:1px solid #dddddd;cursor:pointer;display:flex;align-items:center;gap:8px;width:100%}.add-filter:hover{background-color:#f8f9fa}.add-icon{padding:1px;border-radius:5px;background-color:#ddd;transition:background-color .3s}.modal{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:1001}.modal-content{background-color:#fff;border-radius:8px;padding:24px;width:700px;max-width:95%;max-height:90vh;overflow-y:auto;box-shadow:0 4px 20px #00000026}.modal-content h2{margin-top:0;margin-bottom:20px;font-size:20px;color:#333}.form-group{margin-bottom:16px}.form-group label{display:block;margin-bottom:8px;font-size:14px;font-weight:500}.form-group input{width:100%;padding:8px 12px;border:1px solid #ddd;border-radius:4px;font-size:14px}.toggle-wrapper{position:relative;display:inline-block}.toggle-wrapper input[type=checkbox]{opacity:0;width:0;height:0}.toggle-button{position:relative;display:inline-block;width:50px;height:24px;background-color:#ccc;border-radius:24px;transition:.3s;cursor:pointer}.toggle-button:before{position:absolute;content:\"\";height:20px;width:20px;left:2px;bottom:2px;background-color:#fff;border-radius:50%;transition:.3s}input[type=checkbox]:checked+.toggle-button{background-color:#007bff}input[type=checkbox]:checked+.toggle-button:before{transform:translate(20px)}.toggle-wrapper.small .toggle-button{width:40px;height:20px}.toggle-wrapper.small .toggle-button:before{height:16px;width:16px}input[type=checkbox]:checked+.toggle-button.small:before{transform:translate(20px)}.section-header{padding-bottom:8px}.section-header h3{margin:0 0 4px;font-size:16px;color:#333}.section-description{font-size:12px;color:#777}.table-container{border:1px solid #e0e0e0;border-radius:4px}.table-header{display:grid;background-color:#f8f9fa;font-weight:600;font-size:12px;padding:8px 12px;border-bottom:1px solid #e0e0e0}.filter-row,.column-row{display:grid;padding:8px 12px;border-bottom:1px solid #f0f0f0;align-items:center}.filter-row,.column-row,.table-header{grid-template-columns:1fr 1fr 1fr auto;gap:10px}.table-header.column-header{grid-template-columns:1fr 1fr 1fr auto}.column-cell,.operator-cell,.value-cell,.name-cell,.bool-cell,.action-cell{padding:5px}.action-cell{display:flex;justify-content:center}.listview-custom-select{position:relative;width:100%}.listview-custom-select input{border:none;font-size:12px}.dropdown-list{position:absolute;top:100%;left:0;width:100%;max-height:200px;overflow-y:auto;background:#fff;border:1px solid #ddd;border-top:none;border-radius:0 0 4px 4px;z-index:10;box-shadow:0 4px 8px #0000001a}.dropdown-item{padding:8px 12px;cursor:pointer}.dropdown-item:hover{background-color:#f5f5f5}.add-row{display:flex;align-items:center;gap:8px;padding:10px;cursor:pointer}.add-row:hover{background-color:#f8f9fa}.addIconBor{padding:4px;border-radius:5px;border:1px solid #6c757d;transition:background-color .3s,border-color .3s}.addIconBor:hover .addIcon{background-color:#bbd3ff}.addIcon{padding:1px;border-radius:5px;background-color:#ddd;transition:background-color .3s}.dicon-container{padding:2px;border:1px solid #ffb5b5;border-radius:5px;margin-left:3px;margin-right:3px;display:flex;width:38px}.delete-icon{padding:2px 4px;border-radius:5px;background-color:#feeeed;align-content:center;width:32px;display:flex;justify-content:center;align-items:center}.dicon-container:hover .delete-icon svg path{stroke:#fff!important;fill:transparent!important}.dicon-container:hover .delete-icon{background-color:#ff7575!important;cursor:pointer}.dicon-container:hover{border:1px solid #ff2121!important}.form-actions{display:flex;justify-content:flex-end;gap:12px;margin-top:20px}.form-delete{display:flex;justify-content:flex-end;gap:12px}.form-actions button,.form-delete button{padding:8px 16px;border-radius:4px;font-size:14px;cursor:pointer;transition:background-color .2s}.form-actions button:first-child{background-color:#007bff;color:#fff;border:1px solid #007bff}.form-actions button:nth-child(2){background-color:#f8f9fa;border:1px solid #ddd;color:#333}.form-delete button:first-child{background-color:#dc3545;color:#fff;border:1px solid #dc3545}.form-delete button:nth-child(2){background-color:#f8f9fa;border:1px solid #ddd;color:#333}.form-actions button:hover,.form-delete button:hover{opacity:.9}.cursor-pointer{cursor:pointer}.flex{display:flex}.form-row{display:flex;gap:16px;align-items:flex-start}.form-group{min-width:0;margin-bottom:0!important}.error-message{color:#dc3545;font-size:12px;margin-top:4px}.listview-custom-select input[readonly]{cursor:pointer;background-color:#fff}.error-message{color:#ff2c10;font-size:.875rem;margin-bottom:.5rem}.save-button:disabled{background-color:#ccc!important;color:#666!important;cursor:not-allowed!important}.modal-header-div{display:flex;justify-content:space-between;font-size:18px;padding-bottom:10px}.close{color:#aaa;float:right;font-size:28px;font-weight:700}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer}\n"] }]
387
- }], ctorParameters: () => [{ type: i1.FormBuilder }, { type: i2.CustomTranslatePipe }], propDecorators: { listViews: [{
388
- type: Input
389
- }], tableFilterArray: [{
390
- type: Input
391
- }], selectedView: [{
392
- type: Input
393
- }], displayedColumns: [{
394
- type: Input
395
- }], availableOperators: [{
396
- type: Input
397
- }], listViewEmit: [{
398
- type: Output
399
- }], onDocumentClick: [{
400
- type: HostListener,
401
- args: ['document:click', ['$event']]
402
- }] } });
403
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdC12aWV3LWZpbHRlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9ueHQtYXBwL3NyYy9saWIvY29tcG9uZW50cy9saXN0LXZpZXctZmlsdGVyL2xpc3Qtdmlldy1maWx0ZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbnh0LWFwcC9zcmMvbGliL2NvbXBvbmVudHMvbGlzdC12aWV3LWZpbHRlci9saXN0LXZpZXctZmlsdGVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFpQixNQUFNLGVBQWUsQ0FBQztBQUM1RyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxtQkFBbUIsRUFBcUMsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDakgsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDdkUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7Ozs7OztBQWdDN0QsTUFBTSxPQUFPLHVCQUF1QjtJQWlDZDtJQUF3QjtJQWhDbkMsU0FBUyxHQUFlLEVBQUUsQ0FBQztJQUMzQixnQkFBZ0IsR0FBUSxFQUFFLENBQUM7SUFDM0IsWUFBWSxHQUFXLEVBQUUsQ0FBQztJQUMxQixnQkFBZ0IsR0FBUSxFQUFFLENBQUM7SUFDM0Isa0JBQWtCLEdBQXlEO1FBQ2xGLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBQyxTQUFTLEVBQUMsWUFBWSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUU7UUFDMUQsRUFBRSxLQUFLLEVBQUUsZ0JBQWdCLEVBQUMsU0FBUyxFQUFDLGVBQWUsRUFBRSxLQUFLLEVBQUUsSUFBSSxF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QUFLLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDM0QsQ0FBQztJQUNILENBQUM7SUFDRCxpRkFBaUY7SUFFakYsZUFBZSxDQUFDLEtBQVU7UUFDeEIsS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3hCLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFxQixDQUFDO1FBQzNDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLG1CQUFtQixDQUFDLEVBQUUsQ0FBQztZQUN6QyxJQUFJLENBQUMsY0FBYyxHQUFHLEtBQUssQ0FBQztRQUM5QixDQUFDO0lBQ0gsQ0FBQzt3R0E1WVUsdUJBQXVCOzRGQUF2Qix1QkFBdUIsNFdBSnZCLENBQUMsbUJBQW1CLENBQUMsK0NDaENsQyxpdnZCQXVSTSx1dk1EeFBNLFlBQVksK1BBQUUsV0FBVywyc0NBQUUsbUJBQW1CLHloQkFBRSxtQkFBbUIsdURBQUMsZ0JBQWdCOzs0RkFLbkYsdUJBQXVCO2tCQVJuQyxTQUFTOytCQUNFLHNCQUFzQixjQUNwQixJQUFJLFdBQ1AsQ0FBQyxZQUFZLEVBQUUsV0FBVyxFQUFFLG1CQUFtQixFQUFFLG1CQUFtQixFQUFDLGdCQUFnQixDQUFDLGFBQ3BGLENBQUMsbUJBQW1CLENBQUM7a0hBS3ZCLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ0csZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUNHLGtCQUFrQjtzQkFBMUIsS0FBSztnQkFTSSxZQUFZO3NCQUFyQixNQUFNO2dCQXdYUCxlQUFlO3NCQURkLFlBQVk7dUJBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBIb3N0TGlzdGVuZXIsIFNpbXBsZUNoYW5nZXMgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSwgUmVhY3RpdmVGb3Jtc01vZHVsZSwgRm9ybUJ1aWxkZXIsIEZvcm1Hcm91cCwgRm9ybUFycmF5LCBWYWxpZGF0b3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQ3VzdG9tVHJhbnNsYXRlUGlwZSB9IGZyb20gJy4uLy4uL3BpcGUvY3VzdG9tLXRyYW5zbGF0ZS5waXBlJztcbmltcG9ydCB7IE1hdFRvb2x0aXBNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC90b29sdGlwJztcblxuaW50ZXJmYWNlIExpc3RWaWV3IHtcbiAgZmlsdGVyTmFtZTogc3RyaW5nO1xuICBsYWJlbFBhdGg6IGFueTtcbiAgb3JkZXI6IG51bWJlcjtcbiAgaXNEZWZhdWx0OiBib29sZWFuO1xuICBjb25kaXRpb25zOiBMaXN0Vmlld0ZpbHRlcltdO1xuICBjb2x1bW5zOiBMaXN0Vmlld0NvbHVtbltdO1xuICBzaG93QWN0aW9ucz86IGJvb2xlYW47XG59XG5cbmludGVyZmFjZSBMaXN0Vmlld0ZpbHRlciB7XG4gIGZpZWxkOiBzdHJpbmc7XG4gIG9wZXJhdG9yOiBzdHJpbmc7XG4gIHZhbHVlOiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBMaXN0Vmlld0NvbHVtbiB7XG4gIG5hbWU6IHN0cmluZztcbiAgc29ydGFibGU6IGJvb2xlYW47XG4gIGZpbHRlcmFibGU6IGJvb2xlYW47XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC1saXN0LXZpZXctZmlsdGVyJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgRm9ybXNNb2R1bGUsIFJlYWN0aXZlRm9ybXNNb2R1bGUsIEN1c3RvbVRyYW5zbGF0ZVBpcGUsTWF0VG9vbHRpcE1vZHVsZV0sXG4gIHByb3ZpZGVyczogW0N1c3RvbVRyYW5zbGF0ZVBpcGVdLFxuICB0ZW1wbGF0ZVVybDogJy4vbGlzdC12aWV3LWZpbHRlci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2xpc3Qtdmlldy1maWx0ZXIuY29tcG9uZW50LmNzcyddXG59KVxuZXhwb3J0IGNsYXNzIExpc3RWaWV3RmlsdGVyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgQElucHV0KCkgbGlzdFZpZXdzOiBMaXN0Vmlld1tdID0gW107XG4gIEBJbnB1dCgpIHRhYmxlRmlsdGVyQXJyYXk6IGFueSA9IFtdO1xuICBASW5wdXQoKSBzZWxlY3RlZFZpZXc6IHN0cmluZyA9ICcnO1xuICBASW5wdXQoKSBkaXNwbGF5ZWRDb2x1bW5zOiBhbnkgPSBbXTtcbiAgQElucHV0KCkgYXZhaWxhYmxlT3BlcmF0b3JzOiB7IGxhYmVsOiBzdHJpbmcsbGFiZWxQYXRoOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcgfVtdID0gW1xuICAgIHsgbGFiZWw6ICdFcXVhbHMgKD0pJyxsYWJlbFBhdGg6J0FQUC5FUVVBTFMnLCB2YWx1ZTogJz0nIH0sXG4gICAgeyBsYWJlbDogJ05vdCBFcXVhbCAoIT0pJyxsYWJlbFBhdGg6J0FQUC5OT1RfRVFVQUwnLCB2YWx1ZTogJyE9JyB9LFxuICAgIHsgbGFiZWw6ICdHcmVhdGVyIFRoYW4gKD4pJyxsYWJlbFBhdGg6J0FQUC5HUkVBVEVSX1RIQU4nLCB2YWx1ZTogJz4nIH0sXG4gICAgeyBsYWJlbDogJ0xlc3MgVGhhbiAoPCknLGxhYmVsUGF0aDonQVBQLkxFU1NfVEhBTicsIHZhbHVlOiAnPCcgfSxcbiAgICB7IGxhYmVsOiAnR3JlYXRlciBUaGFuIG9yIEVxdWFsICg+PSknLGxhYmVsUGF0aDonQVBQLkdSRUFURVJfVEhBTl9PUl9FUVVBTCcsIHZhbHVlOiAnPj0nIH0sXG4gICAgeyBsYWJlbDogJ0xlc3MgVGhhbiBvciBFcXVhbCAoPD0pJyxsYWJlbFBhdGg6J0FQUC5MRVNTX1RIQU5fT1JfRVFVQUwnLCB2YWx1ZTogJzw9JyB9XG4gIF07ICAvLyAnY29udGFpbnMnLCAnbm90IGNvbnRhaW5zJywgJ3N0YXJ0cyB3aXRoJywgJ2VuZHMgd2l0aCdcblxuICBAT3V0cHV0KCkgbGlzdFZpZXdFbWl0ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG5cbiAgaXNEcm9wZG93bk9wZW46IGJvb2xlYW4gPSBmYWxzZTtcbiAgaXNNb2RhbE9wZW46IGJvb2xlYW4gPSBmYWxzZTtcbiAgaXNEZWxldGVNb2RhbE9wZW46IGJvb2xlYW4gPSBmYWxzZTtcbiAgaXNBZGRpbmc6IGJvb2xlYW4gPSBmYWxzZTtcbiAgdmlld1RvRGVsZXRlOiBMaXN0VmlldyB8IG51bGwgPSBudWxsO1xuXG4gIGVkaXRpbmdWaWV3OiBGb3JtR3JvdXA7XG5cbiAgaXNDb2x1bW5Ecm9wZG93bk9wZW46IGJvb2xlYW5bXSA9IFtdO1xuICBpc09wZXJhdG9yRHJvcGRvd25PcGVuOiBib29sZWFuW10gPSBbXTtcbiAgaXNWYWx1ZURyb3Bkb3duT3BlbjogYm9vbGVhbltdID0gW107XG4gIGlzQ29sdW1uTmFtZURyb3Bkb3duT3BlbjogYm9vbGVhbltdID0gW107XG4gIHNlbGVjdGVkVmlld1BhdGg6IHN0cmluZztcbiAgdGFibGVGaWx0ZXJBcnJheVRyYW5zOiBhbnk7XG4gIGRpc3BsYXllZENvbHVtbnNUcmFuczogYW55O1xuICBhdmFpbGFibGVPcGVyYXRvcnNUcmFuczogeyBsYWJlbDogc3RyaW5nOyB2YWx1ZTogc3RyaW5nOyB9W107XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBmYjogRm9ybUJ1aWxkZXIscHJpdmF0ZSBjdXN0b21UcmFuc2xhdGU6IEN1c3RvbVRyYW5zbGF0ZVBpcGUpIHtcbiAgICB0aGlzLmVkaXRpbmdWaWV3ID0gdGhpcy5mYi5ncm91cCh7XG4gICAgICBmaWx0ZXJOYW1lOiBbJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgb3JkZXI6IFswLCBbVmFsaWRhdG9ycy5yZXF1aXJlZCwgVmFsaWRhdG9ycy5taW4oMCldXSxcbiAgICAgIGlzRGVmYXVsdDogW2ZhbHNlXSxcbiAgICAgIGNvbmRpdGlvbnM6IHRoaXMuZmIuYXJyYXkoW10pLFxuICAgICAgY29sdW1uczogdGhpcy5mYi5hcnJheShbXSlcbiAgICB9KTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICBpZiAoIXRoaXMuc2VsZWN0ZWRWaWV3ICYmIHRoaXMubGlzdFZpZXdzPy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkVmlldyA9IHRoaXMubGlzdFZpZXdzWzBdLmZpbHRlck5hbWU7XG4gICAgICB0aGlzLnNlbGVjdGVkVmlld1BhdGggPSB0aGlzLmxpc3RWaWV3c1swXS5sYWJlbFBhdGhcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZWxlY3RlZFZpZXdQYXRoID0gdGhpcy5zZWxlY3RlZFZpZXcgPT09ICdBbGwgRGF0YScgPyB0aGlzLmxpc3RWaWV3c1swXS5sYWJlbFBhdGggOiB0aGlzLnNlbGVjdGVkVmlld1xuICAgIH1cbiAgICB0aGlzLnRhYmxlRmlsdGVyQXJyYXlUcmFucyA9dGhpcy50YWJsZUZpbHRlckFycmF5XG4gICAgdGhpcy50YWJsZUZpbHRlckFycmF5VHJhbnMuZm9yRWFjaCgoZWxlOmFueSkgPT4ge1xuICAgICAgZWxlLmxhYmVsID0gdGhpcy5jdXN0b21UcmFuc2xhdGUudHJhbnNmb3JtKGVsZS5sYWJlbFBhdGggfHwgZWxlLmxhYmVsLGVsZS5sYWJlbCApXG4gICAgfSk7XG4gICAgdGhpcy5kaXNwbGF5ZWRDb2x1bW5zVHJhbnMgPXRoaXMuZGlzcGxheWVkQ29sdW1uc1xuICAgIHRoaXMuZGlzcGxheWVkQ29sdW1uc1RyYW5zLmZvckVhY2goKGVsZTphbnkpID0+IHtcbiAgICAgIGVsZS5sYWJlbCA9IHRoaXMuY3VzdG9tVHJhbnNsYXRlLnRyYW5zZm9ybShlbGUubGFiZWxQYXRoIHx8IGVsZS5sYWJlbCxlbGUubGFiZWwgKVxuICAgIH0pO1xuICAgIHRoaXMuYXZhaWxhYmxlT3BlcmF0b3JzVHJhbnMgPSB0aGlzLmF2YWlsYWJsZU9wZXJhdG9yc1xuICAgIHRoaXMuYXZhaWxhYmxlT3BlcmF0b3JzVHJhbnMuZm9yRWFjaCgoZWxlOmFueSkgPT4ge1xuICAgICAgZWxlLmxhYmVsID0gdGhpcy5jdXN0b21UcmFuc2xhdGUudHJhbnNmb3JtKGVsZS5sYWJlbFBhdGggfHwgZWxlLmxhYmVsLGVsZS5sYWJlbCApXG4gICAgfSk7XG4gIH1cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgIGlmICghdGhpcy5zZWxlY3RlZFZpZXcgJiYgdGhpcy5saXN0Vmlld3M/Lmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRWaWV3ID0gdGhpcy5saXN0Vmlld3NbMF0uZmlsdGVyTmFtZTtcbiAgICAgIHRoaXMuc2VsZWN0ZWRWaWV3UGF0aCA9IHRoaXMubGlzdFZpZXdzWzBdLmxhYmVsUGF0aFxuICAgIH1lbHNlIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRWaWV3UGF0aCA9IHRoaXMuc2VsZWN0ZWRWaWV3ID09PSAnQWxsIERhdGEnID8gdGhpcy5saXN0Vmlld3NbMF0ubGFiZWxQYXRoIDogdGhpcy5zZWxlY3RlZFZpZXdcbiAgICB9XG4gIH1cblxuICBnZXQgY29uZGl0aW9ucygpOiBGb3JtQXJyYXkge1xuICAgIHJldHVybiB0aGlzLmVkaXRpbmdWaWV3LmdldCgnY29uZGl0aW9ucycpIGFzIEZvcm1BcnJheTtcbiAgfVxuXG4gIC8vIFNLUzNNQVkyNSBSZXR1cm5zIHRoZSBGb3JtQXJyYXkgb2YgY29sdW1ucyBmcm9tIHRoZSBlZGl0aW5nIGZvcm1cbiAgZ2V0IGNvbHVtbnMoKTogRm9ybUFycmF5IHtcbiAgICByZXR1cm4gdGhpcy5lZGl0aW5nVmlldy5nZXQoJ2NvbHVtbnMnKSBhcyBGb3JtQXJyYXk7XG4gIH1cblxuICAvLyBTS1MzTUFZMjUgQWRkcyBhIG5ldyBmaWx0ZXIgY29uZGl0aW9uIHRvIHRoZSBmb3JtXG4gIGFkZEZpbHRlcigpOiB2b2lkIHtcbiAgICB0aGlzLmNvbmRpdGlvbnMucHVzaCh0aGlzLmZiLmdyb3VwKHtcbiAgICAgIGZpZWxkOiBbJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgb3BlcmF0b3I6IFsnJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICB2YWx1ZTogWycnLCBWYWxpZGF0b3JzLnJlcXVpcmVkXVxuICAgIH0pKTtcbiAgICB0aGlzLmlzQ29sdW1uRHJvcGRvd25PcGVuLnB1c2goZmFsc2UpO1xuICAgIHRoaXMuaXNPcGVyYXRvckRyb3Bkb3duT3Blbi5wdXNoKGZhbHNlKTtcbiAgICB0aGlzLmlzVmFsdWVEcm9wZG93bk9wZW4ucHVzaChmYWxzZSk7XG4gIH1cblxuICAvLyBTS1MzTUFZMjUgUmVtb3ZlcyBhIGZpbHRlciBjb25kaXRpb24gYnkgaW5kZXhcbiAgcmVtb3ZlRmlsdGVyKGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmNvbmRpdGlvbnMucmVtb3ZlQXQoaW5kZXgpO1xuICAgIHRoaXMuaXNDb2x1bW5Ecm9wZG93bk9wZW4uc3BsaWNlKGluZGV4LCAxKTtcbiAgICB0aGlzLmlzT3BlcmF0b3JEcm9wZG93bk9wZW4uc3BsaWNlKGluZGV4LCAxKTtcbiAgICB0aGlzLmlzVmFsdWVEcm9wZG93bk9wZW4uc3BsaWNlKGluZGV4LCAxKTtcbiAgfVxuXG4gIGFkZENvbHVtbigpOiB2b2lkIHtcbiAgICB0aGlzLmNvbHVtbnMucHVzaCh0aGlzLmZiLmdyb3VwKHtcbiAgICAgIG5hbWU6IFsnJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICBzb3J0YWJsZTogW2ZhbHNlXSxcbiAgICAgIGZpbHRlcmFibGU6IFtmYWxzZV1cbiAgICB9KSk7XG4gICAgdGhpcy5pc0NvbHVtbk5hbWVEcm9wZG93bk9wZW4ucHVzaChmYWxzZSk7XG4gIH1cblxuICByZW1vdmVDb2x1bW4oaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuY29sdW1ucy5yZW1vdmVBdChpbmRleCk7XG4gICAgdGhpcy5pc0NvbHVtbk5hbWVEcm9wZG93bk9wZW4uc3BsaWNlKGluZGV4LCAxKTtcbiAgfVxuXG4gIHRvZ2dsZURyb3Bkb3duKCk6IHZvaWQge1xuICAgIHRoaXMubGlzdFZpZXdFbWl0LmVtaXQoe1wiYWN0aW9uXCI6ICdmaWx0ZXJHZXQnfSk7XG4gICAgdGhpcy5pc0Ryb3Bkb3duT3BlbiA9ICF0aGlzLmlzRHJvcGRvd25PcGVuO1xuICB9XG5cbiAgLy8gU0tTM01BWTI1IEhhbmRsZXMgc2VsZWN0aW5nIGEgbGlzdCB2aWV3IGZyb20gdGhlIGRyb3Bkb3duXG4gIHNlbGVjdExpc3RWaWV3KHZpZXc6IGFueSk6IHZvaWQge1xuICAgIHRoaXMuc2VsZWN0ZWRWaWV3ID0gdmlldy5maWx0ZXJOYW1lO1xuICAgIHRoaXMuc2VsZWN0ZWRWaWV3UGF0aCA9IHZpZXcubGFiZWxQYXRoIHx8IHZpZXcuZmlsdGVyTmFtZTtcbiAgICB0aGlzLmxpc3RWaWV3RW1pdC5lbWl0KHsnYWN0aW9uJzonc2VsZWN0JywgJ2RhdGEnOnZpZXd9KTtcbiAgICB0aGlzLmlzRHJvcGRvd25PcGVuID0gZmFsc2U7XG4gIH1cblxuICAvLyBTS1MzTUFZMjUgT3BlbnMgbW9kYWwgdG8gZWRpdCBhbiBleGlzdGluZyBsaXN0IHZpZXdcbiAgc3RhcnRFZGl0KHZpZXc6IExpc3RWaWV3LCBldmVudD86IEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50KSBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgIHRoaXMuaXNBZGRpbmcgPSBmYWxzZTtcbiAgICB0aGlzLmlzTW9kYWxPcGVuID0gdHJ1ZTtcblxuICAgIHRoaXMuZWRpdGluZ1ZpZXcucmVzZXQoKTtcbiAgICB3aGlsZSAodGhpcy5jb25kaXRpb25zLmxlbmd0aCkgdGhpcy5jb25kaXRpb25zLnJlbW92ZUF0KDApO1xuICAgIHdoaWxlICh0aGlzLmNvbHVtbnMubGVuZ3RoKSB0aGlzLmNvbHVtbnMucmVtb3ZlQXQoMCk7XG5cbiAgICB0aGlzLmVkaXRpbmdWaWV3LnBhdGNoVmFsdWUoe1xuICAgICAgZmlsdGVyTmFtZTogdmlldy5maWx0ZXJOYW1lLFxuICAgICAgb3JkZXI6IHZpZXcub3JkZXIsXG4gICAgICBpc0RlZmF1bHQ6IHZpZXcuaXNEZWZhdWx0XG4gICAgfSk7XG5cbiAgICB2aWV3Py5jb25kaXRpb25zPy5mb3JFYWNoKGZpbHRlciA9PiB7XG4gICAgICB0aGlzLmNvbmRpdGlvbnMucHVzaCh0aGlzLmZiLmdyb3VwKHtcbiAgICAgICAgZmllbGQ6IFtmaWx0ZXIuZmllbGQsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgICBvcGVyYXRvcjogW2ZpbHRlci5vcGVyYXRvciwgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICAgIHZhbHVlOiBbZmlsdGVyLnZhbHVlLCBWYWxpZGF0b3JzLnJlcXVpcmVkXVxuICAgICAgfSkpO1xuICAgIH0pO1xuXG4gICAgXG4gICAgdmlldz8uY29sdW1ucz8uZm9yRWFjaChjb2wgPT4ge1xuICAgICAgdGhpcy5kaXNwbGF5ZWRDb2x1bW5zVHJhbnMuZm9yRWFjaChmaWVsZCA9PiB7XG4gICAgICAgIGlmKGNvbC5uYW1lID09IGZpZWxkLmZpZWxkTmFtZSkge1xuICAgICAgICAgIHRoaXMuY29sdW1ucy5wdXNoKHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgICAgICAgbmFtZTogW2ZpZWxkLmxhYmVsLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcbiAgICAgICAgICAgIHNvcnRhYmxlOiBbY29sLnNvcnRhYmxlIHx8IGZhbHNlXSxcbiAgICAgICAgICAgIGZpbHRlcmFibGU6IFtjb2wuZmlsdGVyYWJsZSB8fCBmYWxzZV1cbiAgICAgICAgICB9KSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gIH1cblxuICAvLyBTS1MzTUFZMjUgT3BlbnMgbW9kYWwgdG8gY3JlYXRlIGEgbmV3IGxpc3Qgdmlld1xuICBzdGFydEFkZCgpOiB2b2lkIHtcbiAgICB0aGlzLmlzQWRkaW5nID0gdHJ1ZTtcbiAgICB0aGlzLmlzTW9kYWxPcGVuID0gdHJ1ZTtcblxuICAgIHRoaXMuZWRpdGluZ1ZpZXcucmVzZXQoKTtcbiAgICB3aGlsZSAodGhpcy5jb25kaXRpb25zLmxlbmd0aCkgdGhpcy5jb25kaXRpb25zLnJlbW92ZUF0KDApO1xuICAgIHdoaWxlICh0aGlzLmNvbHVtbnMubGVuZ3RoKSB0aGlzLmNvbHVtbnMucmVtb3ZlQXQoMCk7XG5cbiAgICB0aGlzLmVkaXRpbmdWaWV3LnBhdGNoVmFsdWUoe1xuICAgICAgb3JkZXI6IHRoaXMubGlzdFZpZXdzPy5sZW5ndGgsXG4gICAgICBpc0RlZmF1bHQ6IGZhbHNlXG4gICAgfSk7XG4gICAgdGhpcy5pc0Ryb3Bkb3duT3BlbiA9IGZhbHNlO1xuXG4gICAgLy8gU0tTMjZNQVkyNSBTZWNvbmQgbG9vcDogZnJvbSBkaXNwbGF5ZWRDb2x1bW5zVHJhbnMsIHNraXAgZHVwbGljYXRlc1xuICAgIHRoaXMuZGlzcGxheWVkQ29sdW1uc1RyYW5zLmZvckVhY2goZmllbGQgPT4ge1xuICAgICAgdGhpcy5jb2x1bW5zLnB1c2godGhpcy5mYi5ncm91cCh7XG4gICAgICAgIG5hbWU6IFtmaWVsZC5sYWJlbCwgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICAgIHNvcnRhYmxlOiBbZmllbGQuaHlwZXJMaW5rIHx8IGZhbHNlXSxcbiAgICAgICAgZmlsdGVyYWJsZTogW2ZpZWxkLmZpbHRlciB8fCBmYWxzZV1cbiAgICAgIH0pKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFNLUzNNQVkyNSBTYXZlcyB0aGUgY3VycmVudGx5IGVkaXRlZCBvciBhZGRlZCBsaXN0IHZpZXdcbiAgc2F2ZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5lZGl0aW5nVmlldy52YWxpZCkge1xuICAgICAgY29uc3QgZm9ybVZhbHVlID0gdGhpcy5lZGl0aW5nVmlldy52YWx1ZTtcbiAgICAgIGZvcm1WYWx1ZT8uY29sdW1ucz8uZm9yRWFjaCgoY29sKT0+e1xuICAgICAgICB0aGlzLmRpc3BsYXllZENvbHVtbnNUcmFucy5mb3JFYWNoKChkQ29sKSA9PiB7XG4gICAgICAgICAgaWYgKGRDb2wubGFiZWwgPT09IGNvbC5uYW1lKSB7XG4gICAgICAgICAgICBjb2wubmFtZSA9IGRDb2wuZmllbGROYW1lXG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgfSlcbiAgICAgIGZvcm1WYWx1ZT8uY29uZGl0aW9ucz8uZm9yRWFjaCgoY29sKT0+e1xuICAgICAgICB0aGlzLmRpc3BsYXllZENvbHVtbnNUcmFucy5mb3JFYWNoKChkQ29sKSA9PiB7XG4gICAgICAgICAgaWYgKGRDb2wubGFiZWwgPT09IGNvbC5maWVsZCkge1xuICAgICAgICAgICAgY29sLmZpZWxkID0gZENvbC5maWVsZE5hbWVcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICB9KVxuICAgICAgY29uc3QgbGlzdFZpZXc6IExpc3RWaWV3ID0ge1xuICAgICAgICBmaWx0ZXJOYW1lOiBmb3JtVmFsdWUuZmlsdGVyTmFtZSxcbiAgICAgICAgbGFiZWxQYXRoOiBmb3JtVmFsdWUubGFiZWxQYXRoIHx8IGZvcm1WYWx1ZS5maWx0ZXJOYW1lLFxuICAgICAgICBvcmRlcjogZm9ybVZhbHVlLm9yZGVyLFxuICAgICAgICBpc0RlZmF1bHQ6IGZvcm1WYWx1ZS5pc0RlZmF1bHQsXG4gICAgICAgIGNvbmRpdGlvbnM6IGZvcm1WYWx1ZS5jb25kaXRpb25zLFxuICAgICAgICBjb2x1bW5zOiBmb3JtVmFsdWUuY29sdW1uc1xuICAgICAgfTtcblxuICAgICAgLy8gaWYgKGxpc3RWaWV3LmlzRGVmYXVsdCkge1xuICAgICAgLy8gICB0aGlzLmxpc3RWaWV3cy5mb3JFYWNoKHZpZXcgPT4ge1xuICAgICAgLy8gICAgIGlmICh2aWV3LmlkICE9PSBsaXN0Vmlldy5pZCkgdmlldy5pc0RlZmF1bHQgPSBmYWxzZTtcbiAgICAgIC8vICAgfSk7XG4gICAgICAvLyB9XG5cbiAgICAgIC8vIGNvbnN0IGV4aXN0aW5nSW5kZXggPSB0aGlzLmxpc3RWaWV3cy5maW5kSW5kZXgodmlldyA9PiB2aWV3LmlkID09PSBsaXN0Vmlldy5pZCk7XG4gICAgICAvLyBpZiAoZXhpc3RpbmdJbmRleCA+PSAwKSB7XG4gICAgICAvLyAgIHRoaXMubGlzdFZpZXdzW2V4aXN0aW5nSW5kZXhdID0geyAuLi5saXN0VmlldyB9O1xuICAgICAgLy8gfSBlbHNlIHtcbiAgICAgIC8vICAgdGhpcy5saXN0Vmlld3MucHVzaChsaXN0Vmlldyk7XG4gICAgICAvLyB9XG5cbiAgICAgIHRoaXMubGlzdFZpZXdzLnNvcnQoKGEsIGIpID0+IGEub3JkZXIgLSBiLm9yZGVyKTtcbiAgICAgIHRoaXMuc2VsZWN0ZWRWaWV3ID0gbGlzdFZpZXcuZmlsdGVyTmFtZTtcbiAgICAgIHRoaXMuc2VsZWN0ZWRWaWV3UGF0aCA9IGxpc3RWaWV3LmxhYmVsUGF0aCB8fCBsaXN0Vmlldy5maWx0ZXJOYW1lO1xuICAgICAgdGhpcy5saXN0Vmlld0VtaXQuZW1pdCh7J2FjdGlvbic6J3NhdmUnLCBcImRhdGFcIjogbGlzdFZpZXd9KTtcbiAgICAgIHRoaXMuY2xvc2VNb2RhbCgpO1xuICAgIH1cbiAgfVxuXG4gIGNsb3NlTW9kYWwoKTogdm9pZCB7XG4gICAgdGhpcy5pc01vZGFsT3BlbiA9IGZhbHNlO1xuICB9XG5cbiAgLy8gU0tTM01BWTI1IFNob3dzIGFjdGlvbiBidXR0b25zIGZvciBhIGxpc3QgdmlldyBvbiBob3ZlclxuICBzaG93QWN0aW9ucyh2aWV3OiBMaXN0Vmlldyk6IHZvaWQge1xuICAgIHZpZXcuc2hvd0FjdGlvbnMgPSB0cnVlO1xuICB9XG5cbiAgLy8gU0tTM01BWTI1IEhpZGVzIGFjdGlvbiBidXR0b25zIGZvciBhbGwgbGlzdCB2aWV3c1xuICBoaWRlQWN0aW9ucygpOiB2b2lkIHtcbiAgICB0aGlzLmxpc3RWaWV3cy5mb3JFYWNoKHZpZXcgPT4gdmlldy5zaG93QWN0aW9ucyA9IGZhbHNlKTtcbiAgfVxuXG4gIC8vIFNLUzNNQVkyNSBPcGVucyBjb25maXJtYXRpb24gbW9kYWwgdG8gZGVsZXRlIGEgbGlzdCB2aWV3XG4gIGNvbmZpcm1EZWxldGUodmlldzogTGlzdFZpZXcsIGV2ZW50PzogRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoZXZlbnQpIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMudmlld1RvRGVsZXRlID0gdmlldztcbiAgICB0aGlzLmlzRGVsZXRlTW9kYWxPcGVuID0gdHJ1ZTtcbiAgICB0aGlzLmlzRHJvcGRvd25PcGVuID0gZmFsc2U7XG4gIH1cblxuICAvLyBTS1MzTUFZMjUgQ2xvc2VzIHRoZSBkZWxldGUgY29uZmlybWF0aW9uIG1vZGFsXG4gIGNsb3NlRGVsZXRlTW9kYWwoKTogdm9pZCB7XG4gICAgdGhpcy5pc0RlbGV0ZU1vZGFsT3BlbiA9IGZhbHNlO1xuICAgIHRoaXMudmlld1RvRGVsZXRlID0gbnVsbDtcbiAgfVxuXG4gIC8vIFNLUzNNQVkyNSBEZWxldGVzIHRoZSBzZWxlY3RlZCBsaXN0IHZpZXcgYWZ0ZXIgY29uZmlybWF0aW9uXG4gIGRlbGV0ZUNvbmZpcm1lZCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy52aWV3VG9EZWxldGUpIHtcbiAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5saXN0Vmlld3MuZmluZEluZGV4KHZpZXcgPT4gdmlldy5maWx0ZXJOYW1lID09PSB0aGlzLnZpZXdUb0RlbGV0ZT8uZmlsdGVyTmFtZSk7XG4gICAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgICAvLyB0aGlzLmxpc3RWaWV3cy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICBpZiAodGhpcy5zZWxlY3RlZFZpZXcgPT09IHRoaXMudmlld1RvRGVsZXRlLmZpbHRlck5hbWUpIHtcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkVmlldyA9IHRoaXMubGlzdFZpZXdzPy5sZW5ndGggPiAwID8gdGhpcy5saXN0Vmlld3NbMF0uZmlsdGVyTmFtZSA6ICcnO1xuICAgICAgICAgIHRoaXMuc2VsZWN0ZWRWaWV3UGF0aCA9IHRoaXMubGlzdFZpZXdzPy5sZW5ndGggPiAwID8gdGhpcy5saXN0Vmlld3NbMF0ubGFiZWxQYXRoIDogJycgXG4gICAgICAgICAgdGhpcy5saXN0Vmlld0VtaXQuZW1pdCh7J2FjdGlvbic6J3NlbGVjdCcsICdkYXRhJzp0aGlzLnNlbGVjdGVkVmlld30pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubGlzdFZpZXdFbWl0LmVtaXQoeydhY3Rpb24nOiAnZGVsZXRlJywgXCJkYXRhXCI6IHRoaXMudmlld1RvRGVsZXRlfSk7XG4gICAgICB9XG4gICAgICB0aGlzLmNsb3NlRGVsZXRlTW9kYWwoKTtcbiAgICB9XG4gIH1cblxuICAvLyBTS1MzTUFZMjUgUmV0dXJucyBmaWx0ZXJlZCBsaXN0IG9mIGNvbHVtbnMgYmFzZWQgb24gaW5wdXQgc2VhcmNoIHRlcm1cbiAgZ2V0RmlsdGVyZWRDb2x1bW5zKHRlcm06IHN0cmluZyk6IGFueVtdIHtcbiAgICBpZiAoIXRlcm0pIHJldHVybiB0aGlzLnRhYmxlRmlsdGVyQXJyYXlUcmFucztcbiAgICB0ZXJtID0gdGVybS50b0xvd2VyQ2FzZSgpO1xuICAgIHJldHVybiB0aGlzLnRhYmxlRmlsdGVyQXJyYXlUcmFucy5maWx0ZXIoY29sID0+XG4gICAgICBjb2wubGFiZWwudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh0ZXJtKVxuICAgICk7XG4gIH1cblxuICBnZXRDb2x1bW5Db2x1bW5zKHRlcm06IHN0cmluZyk6IGFueVtdIHtcbiAgICBjb25zb2xlLmxvZyh0ZXJtKVxuICAgIGlmICghdGVybSkgcmV0dXJuIHRoaXMuZGlzcGxheWVkQ29sdW1uc1RyYW5zO1xuICAgIHRlcm0gPSB0ZXJtLnRvTG93ZXJDYXNlKCk7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGxheWVkQ29sdW1uc1RyYW5zLmZpbHRlcihjb2wgPT5cbiAgICAgIGNvbC5sYWJlbC50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHRlcm0pXG4gICAgKTtcbiAgfSAgXG4gICAvLyBTS1MzTUFZMjUgUmV0dXJucyBwb3NzaWJsZSB2YWx1ZXMgZm9yIGEgc2VsZWN0ZWQgZmllbGQvY29sdW1uXG4gICBnZXRQb3NzaWJsZVZhbHVlcyhmaWVsZDogc3RyaW5nLCB0ZXJtOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgbWF0Y2ggPSB0aGlzLnRhYmxlRmlsdGVyQXJyYXlUcmFucy5maW5kKGNvbCA9PiBjb2wubGFiZWwgPT09IGZpZWxkKTtcbiAgICBpZiAoIW1hdGNoIHx8ICFBcnJheS5pc0FycmF5KG1hdGNoLnZhbHVlKSkgcmV0dXJuIFtdO1xuICAgIGlmICghdGVybSkgcmV0dXJuIG1hdGNoLnZhbHVlO1xuICAgIGNvbnN0IGxvd2VyVGVybSA9IHRlcm0udG9Mb3dlckNhc2UoKTtcbiAgICByZXR1cm4gbWF0Y2gudmFsdWUuZmlsdGVyKHZhbCA9PlxuICAgICAgdHlwZW9mIHZhbCA9PT0gJ3N0cmluZycgJiYgdmFsLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMobG93ZXJUZXJtKVxuICAgICk7XG4gIH0gIFxuICAvLyBTS1MzTUFZMjUgUmV0dXJucyBmaWx0ZXJlZCBsaXN0IG9mIG9wZXJhdG9ycyBiYXNlZCBvbiBpbnB1dCBzZWFyY2ggdGVybVxuICBnZXRGaWx0ZXJlZE9wZXJhdG9ycyh0ZXJtOiBzdHJpbmcpOiB7IGxhYmVsOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcgfVtdIHtcbiAgICBpZiAoIXRlcm0pIHJldHVybiB0aGlzLmF2YWlsYWJsZU9wZXJhdG9yc1RyYW5zO1xuICAgIHRlcm0gPSB0ZXJtLnRvTG93ZXJDYXNlKCk7XG4gICAgcmV0dXJuIHRoaXMuYXZhaWxhYmxlT3BlcmF0b3JzVHJhbnMuZmlsdGVyKG9wZXJhdG9yID0+XG4gICAgICBvcGVyYXRvci5sYWJlbC50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHRlcm0pXG4gICAgKTtcbiAgfSAgXG4gIG9wZXJhdG9ySW5wdXQ6IHN0cmluZ1tdID0gW107XG5cbiAgb25PcGVyYXRvcklucHV0KHZhbHVlOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpIHtcbiAgICB0aGlzLm9wZXJhdG9ySW5wdXRbaW5kZXhdID0gdmFsdWU7XG4gIH1cbiAgXG4gIGdldE9wZXJhdG9yTGFiZWwodmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgZm91bmQgPSB0aGlzLmF2YWlsYWJsZU9wZXJhdG9yc1RyYW5zLmZpbmQob3AgPT4gb3AudmFsdWUgPT09IHZhbHVlKTtcbiAgICByZXR1cm4gZm91bmQgPyBmb3VuZC5sYWJlbCA6IHZhbHVlO1xuICB9XG5cbiAgLy8gU0tTM01BWTI1IE9wZW5zIGEgZHJvcGRvd24gb24gZm9jdXMgZm9yIHRoZSBnaXZlbiBpbnB1dCB0eXBlIGFuZCBpbmRleFxuICBvbkZvY3VzKHR5cGU6IHN0cmluZywgaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGlmICh0eXBlID09PSAnZmllbGQnKSB7XG4gICAgICB0aGlzLmlzQ29sdW1uRHJvcGRvd25PcGVuW2luZGV4XSA9IHRydWU7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnb3BlcmF0b3InKSB7XG4gICAgICB0aGlzLmlzT3BlcmF0b3JEcm9wZG93bk9wZW5baW5kZXhdID0gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICd2YWx1ZScpIHtcbiAgICAgIHRoaXMuaXNWYWx1ZURyb3Bkb3duT3BlbltpbmRleF0gPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2NvbHVtbk5hbWUnKSB7XG4gICAgICB0aGlzLmlzQ29sdW1uTmFtZURyb3Bkb3duT3BlbltpbmRleF0gPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIC8vIFNLUzNNQVkyNSBEZWxheXMgY2xvc2luZyBkcm9wZG93biB0byBhbGxvdyBzZWxlY3Rpb24gb24gYmx1clxuICBvbkJsdXIodHlwZTogc3RyaW5nLCBpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBpZiAodHlwZSA9PT0gJ2ZpZWxkJykge1xuICAgICAgICB0aGlzLmlzQ29sdW1uRHJvcGRvd25PcGVuW2luZGV4XSA9IGZhbHNlO1xuICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnb3BlcmF0b3InKSB7XG4gICAgICAgIHRoaXMuaXNPcGVyYXRvckRyb3Bkb3duT3BlbltpbmRleF0gPSBmYWxzZTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3ZhbHVlJykge1xuICAgICAgICB0aGlzLmlzVmFsdWVEcm9wZG93bk9wZW5baW5kZXhdID0gZmFsc2U7XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdjb2x1bW5OYW1lJykge1xuICAgICAgICB0aGlzLmlzQ29sdW1uTmFtZURyb3Bkb3duT3BlbltpbmRleF0gPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9LCAyMDApO1xuICB9XG5cbi8vIFNLUzNNQVkyNSBTZXRzIHNlbGVjdGVkIHZhbHVlIGluIHRoZSBmb3JtIGNvbnRyb2wgYW5kIGNsb3NlcyB0aGUgZHJvcGRvd25cbiAgc2VsZWN0T3B0aW9uKHR5cGU6IHN0cmluZywgaW5kZXg6IG51bWJlciwgdmFsdWU6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICh0eXBlID09PSAnZmllbGQnKSB7XG4gICAgICB0aGlzLmNvbmRpdGlvbnMuYXQoaW5kZXgpLmdldCgnZmllbGQnKT8uc2V0VmFsdWUodmFsdWUpO1xuICAgICAgdGhpcy5pc0NvbHVtbkRyb3Bkb3duT3BlbltpbmRleF0gPSBmYWxzZTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdvcGVyYXRvcicpIHtcbiAgICAgIHRoaXMuY29uZGl0aW9ucy5hdChpbmRleCkuZ2V0KCdvcGVyYXRvcicpPy5zZXRWYWx1ZSh2YWx1ZSk7XG4gICAgICB0aGlzLmlzT3BlcmF0b3JEcm9wZG93bk9wZW5baW5kZXhdID0gZmFsc2U7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAndmFsdWUnKSB7XG4gICAgICB0aGlzLmNvbmRpdGlvbnMuYXQoaW5kZXgpLmdldCgndmFsdWUnKT8uc2V0VmFsdWUodmFsdWUpO1xuICAgICAgdGhpcy5pc1ZhbHVlRHJvcGRvd25PcGVuW2luZGV4XSA9IGZhbHNlO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2NvbHVtbk5hbWUnKSB7XG4gICAgICB0aGlzLmNvbHVtbnMuYXQoaW5kZXgpLmdldCgnbmFtZScpPy5zZXRWYWx1ZSh2YWx1ZSk7XG4gICAgICB0aGlzLmlzQ29sdW1uTmFtZURyb3Bkb3duT3BlbltpbmRleF0gPSBmYWxzZTtcbiAgICB9XG4gIH1cbiAgZ2V0TGFiZWxCeUZpZWxkTmFtZShmaWVsZE5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc29sZS5sb2coZmllbGROYW1lKVxuICAgIGNvbnN0IG1hdGNoID0gdGhpcy5kaXNwbGF5ZWRDb2x1bW5zVHJhbnMuZmluZChjb2wgPT4gY29sLmZpZWxkTmFtZSA9PT0gZmllbGROYW1lKTtcbiAgICByZXR1cm4gbWF0Y2g/LmxhYmVsID8gbWF0Y2gubGFiZWwgOiBmaWVsZE5hbWU7XG4gIH1cblxuICBvbk1hbnVhbElucHV0KGlucHV0VmFsdWU6IHN0cmluZywgaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IG1hdGNoID0gdGhpcy5kaXNwbGF5ZWRDb2x1bW5zVHJhbnMuZmluZChjb2wgPT4gY29sLmxhYmVsLnRvTG93ZXJDYXNlKCkgPT09IGlucHV0VmFsdWUudG9Mb3dlckNhc2UoKSk7XG4gICAgaWYgKG1hdGNoKSB7XG4gICAgICB0aGlzLmNvbHVtbnMuYXQoaW5kZXgpLmdldCgnbmFtZScpLnNldFZhbHVlKG1hdGNoLmxhYmVsKTtcbiAgICB9XG4gIH0gICAgXG4gIC8vIFNLUzNNQVkyNSBMaXN0ZW5zIHRvIGRvY3VtZW50IGNsaWNrIGFuZCBjbG9zZXMgdGhlIGRyb3Bkb3duIGlmIGNsaWNrZWQgb3V0c2lkZVxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDpjbGljaycsIFsnJGV2ZW50J10pXG4gIG9uRG9jdW1lbnRDbGljayhldmVudDogYW55KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuICAgIGlmICghdGFyZ2V0LmNsb3Nlc3QoJy5saXN0LXZpZXctZmlsdGVyJykpIHtcbiAgICAgIHRoaXMuaXNEcm9wZG93bk9wZW4gPSBmYWxzZTtcbiAgICB9XG4gIH1cbn0iLCI8ZGl2IGNsYXNzPVwibGlzdC12aWV3LWZpbHRlclwiPlxuICAgIDxkaXYgY2xhc3M9XCJjdXN0b20tZHJvcGRvd25cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZpbHRlci1sYWJlbFwiPnt7J0FQUC5EQVRBX1JFTEFURURfVE8nIHwgY3VzdG9tVHJhbnNsYXRlIDogJ0RhdGEgUmVsYXRlZCB0byd9fTwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2VsZWN0LXdyYXBwZXJcIj5cbiAgICAgICAgICAgIDxzdmcgY2xhc3M9XCJmaWx0ZXItaWNvblwiIHdpZHRoPVwiMjRcIiBoZWlnaHQ9XCIyNFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgICAgICAgICA8cmVjdCB3aWR0aD1cIjI0XCIgaGVpZ2h0PVwiMjRcIiByeD1cIjVcIiBmaWxsPVwiI0YxRjFGMVwiIC8+XG4gICAgICAgICAgICAgICAgPHBhdGggZD1cIk01LjUxMjg4IDQuNUgxMi4xODc5QzEyLjc0MjkgNC41IDEzLjIwMDQgNC45NTc1IDEzLjIwMDQgNS41MTI1VjYuNjIyNDlDMTMuMjAwNCA3LjAyNzQ5IDEyLjk0NTQgNy41MyAxMi42OTc5IDcuNzg1TDEwLjUyMjkgOS43MDVDMTAuMjIyOSA5Ljk2IDEwLjAyMDQgMTAuNDYyNSAxMC4wMjA0IDEwLjg2NzVWMTMuMDQyNUMxMC4wMjA0IDEzLjM0MjUgOS44MTc5IDEzLjc0NzUgOS41NjI5IDEzLjkwNUw4Ljg1Nzg5IDE0LjM2MjVDOC4xOTc4OSAxNC43Njc1IDcuMjkwMzcgMTQuMzEgNy4yOTAzNyAxMy41VjEwLjgyMjVDNy4yOTAzNyAxMC40NyA3LjA4Nzg5IDEwLjAxMjUgNi44ODUzOSA5Ljc1NzUxTDQuOTY1MzkgNy43MzI1QzQuNzEwMzkgNy40Nzc1IDQuNTA3OSA3LjAyNzQ5IDQuNTA3OSA2LjcxOTk5VjUuNTU3NUM0LjUwMDQgNC45NTc1IDQuOTU3ODggNC41IDUuNTEyODggNC41WlwiIHN0cm9rZT1cIiMyOTJEMzJcIiBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2UtbWl0ZXJsaW1pdD1cIjEwXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTQuNSAxMS45OTk5VjE0LjI0OTlDNC41IDE3Ljk5OTkgNiAxOS40OTk5IDkuNzUgMTkuNDk5OUgxNC4yNUMxOCAxOS40OTk5IDE5LjUgMTcuOTk5OSAxOS41IDE0LjI0OTlWOS43NDk5NEMxOS41IDcuNDA5OTQgMTguOTE1IDUuOTM5OTMgMTcuNTU3NSA1LjE3NDkzQzE3LjE3NSA0Ljk1NzQzIDE2LjQxIDQuNzkyNDMgMTUuNzEyNSA0LjY3OTkzXCIgc3Ryb2tlPVwiIzI5MkQzMlwiIHN0cm9rZS13aWR0aD1cIjEuNVwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgICAgICAgICAgPHBhdGggZD1cIk0xMi43NSAxMi43NUgxNi41XCIgc3Ryb2tlPVwiIzI5MkQzMlwiIHN0cm9rZS13aWR0aD1cIjEuNVwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgICAgICAgICAgPHBhdGggZD1cIk0xMS4yNSAxNS43NUgxNi41XCIgc3Ryb2tlPVwiIzI5MkQzMlwiIHN0cm9rZS13aWR0aD1cIjEuNVwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjdXN0b20tZHJvcGRvd25cIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VsZWN0ZWQtb3B0aW9uXCIgKGNsaWNrKT1cInRvZ2dsZURyb3Bkb3duKClcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7IHNlbGVjdGVkVmlldyA/IChzZWxlY3RlZFZpZXdQYXRoIHx8IHNlbGVjdGVkVmlldyB8IGN1c3RvbVRyYW5zbGF0ZSA6IHNlbGVjdGVkVmlldykgIDogKCdBUFAuU0VMRUNUX0FfVklFVycgfCBjdXN0b21UcmFuc2xhdGUgOiAnU2VsZWN0IGEgdmlldycpIH19XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8c3ZnIGNsYXNzPVwiY2hldnJvbi1pY29uXCIgd2lkdGg9XCIyNFwiIGhlaWdodD1cIjI0XCIgdmlld0JveD1cIjAgMCA0MCA0MFwiIGZpbGw9XCJub25lXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD1cIk0xOS45OTk5IDI1LjY2NjdDMjMuNjgxOCAyNS42NjY3IDI2LjY2NjYgMjIuNjgxOSAyNi42NjY2IDE5QzI2LjY2NjYgMTUuMzE4MSAyMy42ODE4IDEyLjMzMzQgMTkuOTk5OSAxMi4zMzM0QzE2LjMxOCAxMi4zMzM0IDEzLjMzMzMgMTUuMzE4MSAxMy4zMzMzIDE5QzEzLjMzMzMgMjIuNjgxOSAxNi4zMTggMjUuNjY2NyAxOS45OTk5IDI1LjY2NjdaXCIgZmlsbD1cIiMyOTJEMzJcIiBzdHJva2U9XCIjMjkyRDMyXCIgc3Ryb2tlLXdpZHRoPVwiMS41XCIgc3Ryb2tlLW1pdGVybGltaXQ9XCIxMFwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTE3LjY0NjcgMTguMTZMMjAuMDAwMSAyMC41MDY3TDIyLjM1MzQgMTguMTZcIiBzdHJva2U9XCJ3aGl0ZVwiIHN0cm9rZS13aWR0aD1cIjEuNVwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8IS0tIFNLUzNNQVkyNSBsaXN0IHZpZXcgRHJvcCBkb3duLS0+XG4gICAgICAgIDxkaXYgKm5nSWY9XCJpc0Ryb3Bkb3duT3BlblwiIGNsYXNzPVwiZHJvcGRvd24tb3B0aW9ucy1jb250YWluZXJcIj5cbiAgICAgICAgICAgIDx1bCBjbGFzcz1cImRyb3Bkb3duLW9wdGlvbnNcIj5cbiAgICAgICAgICAgICAgICA8bGkgKm5nRm9yPVwibGV0IHZpZXcgb2YgbGlzdFZpZXdzXCIgW2NsYXNzLnNlbGVjdGVkXT1cInNlbGVjdGVkVmlldyA9PT0gdmlldy5maWx0ZXJOYW1lXCIgKG1vdXNlZW50ZXIpPVwic2hvd0FjdGlvbnModmlldylcIiAobW91c2VsZWF2ZSk9XCJoaWRlQWN0aW9ucygpXCIgKGNsaWNrKT1cInNlbGVjdExpc3RWaWV3KHZpZXcpXCIgY2xhc3M9XCJsaXN0LXZpZXctaXRlbVwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZpZXctbmFtZVwiPnt7IHZpZXcubGFiZWxQYXRoIHx8IHZpZXcuZmlsdGVyTmFtZSB8IGN1c3RvbVRyYW5zbGF0ZSA6IHZpZXcuZmlsdGVyTmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cInZpZXcuc2hvd0FjdGlvbnNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhY3Rpb25zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImVkaXQtaWNvblwiIChjbGljayk9XCJzdGFydEVkaXQodmlldywgJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTZcIiBoZWlnaHQ9XCIxNlwiIHZpZXdCb3g9XCIwIDAgMTYgMTZcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNOS4zMjkyMyAzLjk4NzI2TDEyLjAxMjYgNi42NzA1OU05LjMyOTIzIDMuOTg3MjZMMi41MDAwOCAxMC44MTY0VjEzLjQ5OTdINS4xODM0MkwxMi4wMTI2IDYuNjcwNTlNOS4zMjkyMyAzLjk4NzI2TDEyLjAxMjYgMS4zMDM5MkwxNC42OTU5IDMuOTg3MjZMMTIuMDEyNiA2LjY3MDU5XCIgc3Ryb2tlPVwiIzAwMDAwMFwiIHN0cm9rZS13aWR0aD1cIjFcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGVsZXRlLWljb25cIiAoY2xpY2spPVwiY29uZmlybURlbGV0ZSh2aWV3LCAkZXZlbnQpXCIgKm5nSWY9XCJsaXN0Vmlld3MubGVuZ3RoID4gMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTZcIiBoZWlnaHQ9XCIxNlwiIHZpZXdCb3g9XCIwIDAgMTYgMTZcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMTQgMy45ODcyNkMxMS43OCAzLjc2NzI2IDkuNTQ2NjcgMy42NTM5MyA3LjMyIDMuNjUzOTNDNiAzLjY1MzkzIDQuNjggMy43MjA2IDMuMzYgMy44NTM5M0wyIDMuOTg3MjZcIiBzdHJva2U9XCIjMDAwMDAwXCIgc3Ryb2tlLXdpZHRoPVwiMS41XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNNS42NjY1IDMuMzEzNjJMNS44MTMxNyAyLjQ0MDI4QzUuOTE5ODQgMS44MDY5NSA1Ljk5OTg0IDEuMzMzNjIgNy4xMjY1IDEuMzMzNjJIOC44NzMxN0M5Ljk5OTg0IDEuMzMzNjIgMTAuMDg2NSAxLjgzMzYyIDEwLjE4NjUgMi40NDY5NUwxMC4zMzMyIDMuMzEzNjJcIiBzdHJva2U9XCIjMDAwMDAwXCIgc3Ryb2tlLXdpZHRoPVwiMS41XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMTIuNTY2NyA2LjA5Mzc1TDEyLjEzMzQgMTIuODA3MUMxMi4wNiAxMy44NTM3IDEyIDE0LjY2NzEgMTAuMTQgMTQuNjY3MUg1Ljg2MDAyQzQuMDAwMDIgMTQuNjY3MSAzLjk0MDAyIDEzLjg1MzcgMy44NjY2OCAxMi44MDcxTDMuNDMzMzUgNi4wOTM3NVwiIHN0cm9rZT1cIiMwMDAwMDBcIiBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD1cIk02Ljg4NjQ3IDExLjAwMDRIOS4xMDY0N1wiIHN0cm9rZT1cIiMwMDAwMDBcIiBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD1cIk02LjMzMzUgOC4zMzMyNUg5LjY2NjgzXCIgc3Ryb2tlPVwiIzAwMDAwMFwiIHN0cm9rZS13aWR0aD1cIjEuNVwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICA8L3VsPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFkZC1maWx0ZXJcIiAoY2xpY2spPVwic3RhcnRBZGQoKVwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhZGQtaWNvblwiPlxuICAgICAgICAgICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTZcIiBoZWlnaHQ9XCIxNlwiIHZpZXdCb3g9XCIwIDAgMTYgMTZcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNOCAzLjMzMzI1VjEyLjY2NjZcIiBzdHJva2U9XCIjMDA3YmZmXCIgc3Ryb2tlLXdpZHRoPVwiMS41XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMy4zMzMwMSA4SDEyLjY2NjNcIiBzdHJva2U9XCIjMDA3YmZmXCIgc3Ryb2tlLXdpZHRoPVwiMS41XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPHNwYW4+e3snQVBQLk5FV19MSVNUX1ZJRVcnIHwgY3VzdG9tVHJhbnNsYXRlIDogJ05ldyBMaXN0IFZpZXcnfX08L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gICAgIDwhLS0gU0tTM01BWTI1IEFkZCBOZXcgTGlzdCBWaWV3LS0+XG4gICAgPGRpdiAqbmdJZj1cImlzTW9kYWxPcGVuXCIgY2xhc3M9XCJtb2RhbFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtY29udGVudFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWhlYWRlci1kaXZcIj5cbiAgICAgICAgICAgICAgICB7eyAoaXNBZGRpbmcgPyAnQVBQLkFERF9ORVdfTElTVF9WSUVXJyA6ICdBUFAuRURJVF9MSVNUX1ZJRVcnKSAgfCBjdXN0b21UcmFuc2xhdGUgOiAoaXNBZGRpbmcgPyAnQWRkIE5ldyBMaXN0IFZpZXcnIDogJ0VkaXQgTGlzdCBWaWV3JykgfX0gXG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjbG9zZVwiIChjbGljayk9XCJjbG9zZU1vZGFsKClcIj4mdGltZXM7PC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8Zm9ybSBbZm9ybUdyb3VwXT1cImVkaXRpbmdWaWV3XCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tcm93XCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWw+e3snQVBQLk5BTUUnIHwgY3VzdG9tVHJhbnNsYXRlIDonTmFtZSd9fTo8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IGZvcm1Db250cm9sTmFtZT1cImZpbHRlck5hbWVcIiBbcGxhY2Vob2xkZXJdPVwiJ0FQUC5FTlRFUl9MSVNUX1ZJRVdfTkFNRScgfCBjdXN0b21UcmFuc2xhdGUgOiAnRW50ZXIgbGlzdCB2aWV3IG5hbWUnXCIgcmVxdWlyZWQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiZWRpdGluZ1ZpZXcuZ2V0KCdmaWx0ZXJOYW1lJyk/LmludmFsaWQgJiYgKGVkaXRpbmdWaWV3LmdldCgnZmlsdGVyTmFtZScpPy5kaXJ0eSB8fCBlZGl0aW5nVmlldy5nZXQoJ2ZpbHRlck5hbWUnKT8udG91Y2hlZClcIiBjbGFzcz1cImVycm9yLW1lc3NhZ2VcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyAnQVBQLk5BTUVfSVNfUkVRJyB8IGN1c3RvbVRyYW5zbGF0ZSA6ICdOYW1lIGlzIHJlcXVpcmVkJ319LlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsPnt7J0FQUC5PUkRFUicgfCBjdXN0b21UcmFuc2xhdGUgOiAnT3JkZXInfX06PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgZm9ybUNvbnRyb2xOYW1lPVwib3JkZXJcIiBbcGxhY2Vob2xkZXJdPVwiICdBUFAuRU5URVJfRElTUExBWV9PUkRFUicgfCBjdXN0b21UcmFuc2xhdGUgOiAnRW50ZXIgZGlzcGxheSBvcmRlcidcIiByZXF1aXJlZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJlZGl0aW5nVmlldy5nZXQoJ29yZGVyJyk/LmludmFsaWQgJiYgKGVkaXRpbmdWaWV3LmdldCgnb3JkZXInKT8uZGlydHkgfHwgZWRpdGluZ1ZpZXcuZ2V0KCdvcmRlcicpPy50b3VjaGVkKVwiIGNsYXNzPVwiZXJyb3ItbWVzc2FnZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7J0FQUC5PUkRFUl9JU19SRVFfQU5EX0JFX0FfTlVNJyB8IGN1c3RvbVRyYW5zbGF0ZSA6ICdPcmRlciBpcyByZXF1aXJlZCBhbmQgbXVzdCBiZSBhIG51bWJlcid9fS5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbD57eydBUFAuREVGQVVMVF9WSUVXJyB8IGN1c3RvbVRyYW5zbGF0ZSA6ICdEZWZhdWx0IFZpZXcnfX06PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0b2dnbGUtd3JhcHBlciBzbWFsbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBmb3JtQ29udHJvbE5hbWU9XCJpc0RlZmF1bHRcIiBpZD1cImlzRGVmYXVsdFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBmb3I9XCJpc0RlZmF1bHRcIiBjbGFzcz1cInRvZ2dsZS1idXR0b25cIj48L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlY3Rpb24taGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxoMz57eydBUFAuRklMVEVSUycgfCBjdXN0b21UcmFuc2xhdGUgOiAnRmlsdGVycyd9fTwvaDM+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2VjdGlvbi1kZXNjcmlwdGlvblwiPnt7J0FQUC5ERUZJTkVfQ09ORElUSU9OU19GT1JfRklMVEVSRURfTElTVF9WSUVXJyB8IGN1c3RvbVRyYW5zbGF0ZSA6ICdEZWZpbmUgY29uZGl0aW9ucyBmb3IgZmlsdGVyZWQgbGlzdCB2aWV3J319PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgZm9ybUFycmF5TmFtZT1cImNvbmRpdGlvbnNcIiBjbGFzcz1cInRhYmxlLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGFibGUtaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sdW1uLWNlbGxcIj57eydBUFAuQ09MVU1OJyB8IGN1c3RvbVRyYW5zbGF0ZSA6ICdDb2x1bW4nfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvcGVyYXRvci1jZWxsXCI+e3snQVBQLk9QRVJBVE9SJyB8IGN1c3RvbVRyYW5zbGF0ZSA6ICdPcGVyYXRvcid9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInZhbHVlLWNlbGxcIj57eydBUFAuVkFMVUUnIHwgY3VzdG9tVHJhbnNsYXRlIDogJ1ZhbHVlJ319PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWN0aW9uLWNlbGxcIj57eydBUFAuQUNUSU9OJyB8IGN1c3RvbVRyYW5zbGF0ZSA6ICdBY3Rpb24nfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBmaWx0ZXIgb2YgY29uZGl0aW9ucy5jb250cm9sczsgbGV0IGkgPSBpbmRleFwiIFtmb3JtR3JvdXBOYW1lXT1cImlcIiBjbGFzcz1cImZpbHRlci1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2x1bW4tY2VsbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsaXN0dmlldy1jdXN0b20tc2VsZWN0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBmb3JtQ29udHJvbE5hbWU9XCJmaWVsZFwiIFt2YWx1ZV09XCJnZXRMYWJlbEJ5RmllbGROYW1lKGNvbmRpdGlvbnMuYXQoaSkuZ2V0KCdmaWVsZCcpLnZhbHVlKVwiIChmb2N1cyk9XCJvbkZvY3VzKCdmaWVsZCcsIGkpXCIgKGJsdXIpPVwib25CbHVyKCdmaWVsZCcsIGkpXCIgW3BsYWNlaG9sZGVyXT1cIidBUFAuRU5URVJfT1JfU0VMRUNUX0NPTFVNTicgfCBjdXN0b21UcmFuc2xhdGUgOiAnRW50ZXIgb3Igc2VsZWN0IGNvbHVtbidcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRyb3Bkb3duLWxpc3RcIiAqbmdJZj1cImlzQ29sdW1uRHJvcGRvd25PcGVuW2ldXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBmaWVsZCBvZiBnZXRGaWx0ZXJlZENvbHVtbnMoY29uZGl0aW9ucy5hdChpKS5nZXQoJ2ZpZWxkJykudmFsdWUpXCIgY2xhc3M9XCJkcm9wZG93bi1pdGVtXCIgKGNsaWNrKT1cInNlbGVjdE9wdGlvbignZmllbGQnLCBpLCBmaWVsZC5sYWJlbClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBmaWVsZC5sYWJlbCB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJmaWx0ZXIuZ2V0KCdmaWVsZCcpPy5pbnZhbGlkICYmIChmaWx0ZXIuZ2V0KCdmaWVsZCcpPy5kaXJ0eSB8fCBmaWx0ZXIuZ2V0KCdmaWVsZCcpPy50b3VjaGVkKVwiIGNsYXNzPVwiZXJyb3ItbWVzc2FnZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eydBUFAuQ09MVU1OX0lTX1JFUScgfCBjdXN0b21UcmFuc2xhdGUgOiAnQ29sdW1uIGlzIHJlcXVpcmVkJ319LlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvcGVyYXRvci1jZWxsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxpc3R2aWV3LWN1c3RvbS1zZWxlY3RcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImdldE9wZXJhdG9yTGFiZWwoY29uZGl0aW9ucy5hdChpKS5nZXQoJ29wZXJhdG9yJykudmFsdWUpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW5wdXQpPVwib25PcGVyYXRvcklucHV0KCRldmVudC50YXJnZXQudmFsdWUsIGkpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZm9jdXMpPVwib25Gb2N1cygnb3BlcmF0b3InLCBpKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJsdXIpPVwib25CbHVyKCdvcGVyYXRvcicsIGkpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ0FQUC5FTlRFUl9PUl9TRUxFQ1RfT1BFUkFUT1InIHwgY3VzdG9tVHJhbnNsYXRlIDogJ0VudGVyIG9yIHNlbGVjdCBvcGVyYXRvcidcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkcm9wZG93bi1saXN0XCIgKm5nSWY9XCJpc09wZXJhdG9yRHJvcGRvd25PcGVuW2ldXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IG9wZXJhdG9yIG9mIGdldEZpbHRlcmVkT3BlcmF0b3JzKG9wZXJhdG9ySW5wdXRbaV0pXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZHJvcGRvd24taXRlbVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwic2VsZWN0T3B0aW9uKCdvcGVyYXRvcicsIGksIG9wZXJhdG9yLnZhbHVlKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgb3BlcmF0b3IubGFiZWwgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiZmlsdGVyLmdldCgnb3BlcmF0b3InKT8uaW52YWxpZCAmJiAoZmlsdGVyLmdldCgnb3BlcmF0b3InKT8uZGlydHkgfHwgZmlsdGVyLmdldCgnb3BlcmF0b3InKT8udG91Y2hlZClcIiBjbGFzcz1cImVycm9yLW1lc3NhZ2VcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3snQVBQLk9QRVJBVE9SX0lTX1JFUScgfCBjdXN0b21UcmFuc2xhdGUgOiAnT3BlcmF0b3IgaXMgcmVxdWlyZWQnfX0uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInZhbHVlLWNlbGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibGlzdHZpZXctY3VzdG9tLXNlbGVjdFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgZm9ybUNvbnRyb2xOYW1lPVwidmFsdWVcIiAoZm9jdXMpPVwib25Gb2N1cygndmFsdWUnLCBpKVwiIChibHVyKT1cIm9uQmx1cigndmFsdWUnLCBpKVwiIFtwbGFjZWhvbGRlcl09XCInQVBQLkVOVEVSX09SX1NFTEVDVF9WQUxVRScgfCBjdXN0b21UcmFuc2xhdGUgOiAnRW50ZXIgb3Igc2VsZWN0IHZhbHVlJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZHJvcGRvd24tbGlzdFwiICpuZ0lmPVwiaXNWYWx1ZURyb3Bkb3duT3BlbltpXSAmJiBnZXRQb3NzaWJsZVZhbHVlcyhjb25kaXRpb25zLmF0KGkpLmdldCgnZmllbGQnKS52YWx1ZSwgY29uZGl0aW9ucy5hdChpKS5nZXQoJ3ZhbHVlJykudmFsdWUpPy5sZW5ndGggPiAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCB2YWwgb2YgZ2V0UG9zc2libGVWYWx1ZXMoY29uZGl0aW9ucy5hdChpKS5nZXQoJ2ZpZWxkJykudmFsdWUsIGNvbmRpdGlvbnMuYXQoaSkuZ2V0KCd2YWx1ZScpLnZhbHVlKVwiIGNsYXNzPVwiZHJvcGRvd24taXRlbVwiIChjbGljayk9XCJzZWxlY3RPcHRpb24oJ3ZhbHVlJywgaSwgdmFsKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IHZhbCB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJmaWx0ZXIuZ2V0KCd2YWx1ZScpPy5pbnZhbGlkICYmIChmaWx0ZXIuZ2V0KCd2YWx1ZScpPy5kaXJ0eSB8fCBmaWx0ZXIuZ2V0KCd2YWx1ZScpPy50b3VjaGVkKVwiIGNsYXNzPVwiZXJyb3ItbWVzc2FnZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eydBUFAuVkFMVUVfSVNfUkVRVUlSRUQnIHwgY3VzdG9tVHJhbnNsYXRlIDogJ1ZhbHVlIGlzIHJlcXVpcmVkJ319LlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhY3Rpb24tY2VsbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkaWNvbi1jb250YWluZXJcIiBbbWF0VG9vbHRpcF09XCInQVBQLlJFTU9WRScgfCBjdXN0b21UcmFuc2xhdGUgOiAnUmVtb3ZlJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGVsZXRlLWljb25cIiAoY2xpY2spPVwicmVtb3ZlRmlsdGVyKGkpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTZcIiBoZWlnaHQ9XCIxNlwiIHZpZXdCb3g9XCIwIDAgMTYgMTZcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTE0IDMuOTg3MjZDMTEuNzggMy43NjcyNiA5LjU0NjY3IDMuNjUzOTMgNy4zMiAzLjY1MzkzQzYgMy42NTM5MyA0LjY4IDMuNzIwNiAzLjM2IDMuODUzOTNMMiAzLjk4NzI2XCIgc3Ryb2tlPVwiI0ZGMkMxMFwiIHN0cm9rZS13aWR0aD1cIjEuNVwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD1cIk01LjY2NjUgMy4zMTM2Mkw1LjgxMzE3IDIuNDQwMjhDNS45MTk4NCAxLjgwNjk1IDUuOTk5ODQgMS4zMzM2MiA3LjEyNjUgMS4zMzM2Mkg4Ljg3MzE3QzkuOTk5ODQgMS4zMzM2MiAxMC4wODY1IDEuODMzNjIgMTAuMTg2NSAyLjQ0Njk1TDEwLjMzMzIgMy4zMTM2MlwiIHN0cm9rZT1cIiNGRjJDMTBcIiBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMTIuNTY2NyA2LjA5Mzc1TDEyLjEzMzQgMTIuODA3MUMxMi4wNiAxMy44NTM3IDEyIDE0LjY2NzEgMTAuMTQgMTQuNjY3MUg1Ljg2MDAyQzQuMDAwMDIgMTQuNjY3MSAzLjk0MDAyIDEzLjg1MzcgMy44NjY2OCAxMi44MDcxTDMuNDMzMzUgNi4wOTM3NVwiIHN0cm9rZT1cIiNGRjJDMTBcIiBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNNi44ODY0NyAxMS4wMDA0SDkuMTA2NDdcIiBzdHJva2U9XCIjRkYyQzEwXCIgc3Ryb2tlLXdpZHRoPVwiMS41XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTYuMzMzNSA4LjMzMzI1SDkuNjY2ODNcIiBzdHJva2U9XCIjRkYyQzEwXCIgc3Ryb2tlLXdpZHRoPVwiMS41XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhZGQtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBhZGRJY29uQm9yIGN1cnNvci1wb2ludGVyXCIgKGNsaWNrKT1cImFkZEZpbHRlcigpXCIgW21hdFRvb2x0aXBdPVwiJ0FQUC5BRERfRklMVEVSJyB8IGN1c3RvbVRyYW5zbGF0ZSA6ICdBZGQgRmlsdGVyJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhZGRJY29uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgd2lkdGg9XCIxNlwiIGhlaWdodD1cIjE2XCIgdmlld0JveD1cIjAgMCAxNiAxNlwiIGZpbGw9XCJub25lXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD1cIk04IDMuMzMzMjVWMTIuNjY2NlwiIHN0cm9rZT1cIiMwMDdiZmZcIiBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD1cIk0zLjMzMzAxIDhIMTIuNjY2M1wiIHN0cm9rZT1cIiMwMDdiZmZcIiBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3snQVBQLkFERF9GSUxURVInIHwgY3VzdG9tVHJhbnNsYXRlIDogJ0FkZCBGaWx0ZXInfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlY3Rpb24taGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxoMz57eydBUFAuQ09MVU1OUycgfCBjdXN0b21UcmFuc2xhdGUgOiAnQ29sdW1ucyd9fTwvaDM+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2VjdGlvbi1kZXNjcmlwdGlvblwiPnt7J0FQUC5TRUxFQ1RfRklFTERfVE9fRElTUExBWV9JTl9UQUJMRScgfCBjdXN0b21UcmFuc2xhdGUgOiAnU2VsZWN0IGZpZWxkIHRvIGRpc3BsYXkgaW4gdGFibGUnfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBmb3JtQXJyYXlOYW1lPVwiY29sdW1uc1wiIGNsYXNzPVwidGFibGUtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0YWJsZS1oZWFkZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJuYW1lLWNlbGxcIj57eydBUFAuQ09MVU1OX05BTUUnIHwgY3VzdG9tVHJhbnNsYXRlIDogJ0NvbHVtbiBOYW1lJ319PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYm9vbC1jZWxsXCI+e3snQVBQLlNPUlRBQkxFJyB8IGN1c3RvbVRyYW5zbGF0ZSA6ICdTb3J0YWJsZSd9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJvb2wtY2VsbFwiPnt7J0FQUC5GSUxURVJBQkxFJyB8IGN1c3RvbVRyYW5zbGF0ZSA6J0ZpbHRlcmFibGUnfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhY3Rpb24tY2VsbFwiPnt7J0FQUC5BQ1RJT04nIHwgY3VzdG9tVHJhbnNsYXRlIDogJ0FjdGlvbid9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGZpZWxkIG9mIGNvbHVtbnMuY29udHJvbHM7IGxldCBpID0gaW5kZXhcIiBbZm9ybUdyb3VwTmFtZV09XCJpXCIgY2xhc3M9XCJjb2x1bW4tcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibmFtZS1jZWxsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxpc3R2aWV3LWN1c3RvbS1zZWxlY3RcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJuYW1lXCIgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmb2N1cyk9XCJvbkZvY3VzKCdjb2x1bW5OYW1lJywgaSlcIiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJsdXIpPVwib25CbHVyKCdjb2x1bW5OYW1lJywgaSlcIiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGlucHV0KT1cIm9uTWFudWFsSW5wdXQoJGV2ZW50LnRhcmdldC52YWx1ZSwgaSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ0FQUC5FTlRFUl9PUl9TRUxFQ1RfQ09MVU1OX05BTUUnIHwgY3VzdG9tVHJhbnNsYXRlIDogJ0VudGVyIG9yIHNlbGVjdCBjb2x1bW4gbmFtZSdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkcm9wZG93bi1saXN0XCIgKm5nSWY9XCJpc0NvbHVtbk5hbWVEcm9wZG93bk9wZW5baV1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGNvbE5hbWUgb2YgZ2V0Q29sdW1uQ29sdW1ucyhjb2x1bW5zLmF0KGkpLmdldCgnbmFtZScpLnZhbHVlKVwiIGNsYXNzPVwiZHJvcGRvd24taXRlbVwiIChjbGljayk9XCJzZWxlY3RPcHRpb24oJ2NvbHVtbk5hbWUnLCBpLCBjb2xOYW1lLmxhYmVsKTsgaXNDb2x1bW5OYW1lRHJvcGRvd25PcGVuW2ldID0gZmFsc2VcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBjb2xOYW1lLmxhYmVsIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImZpZWxkLmdldCgnbmFtZScpPy5pbnZhbGlkICYmIChmaWVsZC5nZXQoJ25hbWUnKT8uZGlydHkgfHwgZmllbGQuZ2V0KCduYW1lJyk/LnRvdWNoZWQpXCIgY2xhc3M9XCJlcnJvci1tZXNzYWdlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7J0FQUC5DT0xVTU5fTkFNRV9JU19SRVEnIHwgY3VzdG9tVHJhbnNsYXRlIDogJ0NvbHVtbiBuYW1lIGlzIHJlcXVpcmVkJ319LlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJib29sLWNlbGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidG9nZ2xlLXdyYXBwZXIgc21hbGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIFtpZF09XCInc29ydGFibGUtJyArIGlcIiBmb3JtQ29udHJvbE5hbWU9XCJzb3J0YWJsZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgW2Zvcl09XCInc29ydGFibGUtJyArIGlcIiBjbGFzcz1cInRvZ2dsZS1idXR0b25cIj48L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJib29sLWNlbGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidG9nZ2xlLXdyYXBwZXIgc21hbGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIFtpZF09XCInZmlsdGVyYWJsZS0nICsgaVwiIGZvcm1Db250cm9sTmFtZT1cImZpbHRlcmFibGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIFtmb3JdPVwiJ2ZpbHRlcmFibGUtJyArIGlcIiBjbGFzcz1cInRvZ2dsZS1idXR0b25cIj48L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhY3Rpb24tY2VsbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkaWNvbi1jb250YWluZXJcIiBbbWF0VG9vbHRpcF09XCInQVBQLlJFTU9WRScgfCBjdXN0b21UcmFuc2xhdGUgOiAnUmVtb3ZlJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGVsZXRlLWljb25cIiAoY2xpY2spPVwicmVtb3ZlQ29sdW1uKGkpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTZcIiBoZWlnaHQ9XCIxNlwiIHZpZXdCb3g9XCIwIDAgMTYgMTZcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTE0IDMuOTg3MjZDMTEuNzggMy43NjcyNiA5LjU0NjY3IDMuNjUzOTMgNy4zMiAzLjY1MzkzQzYgMy42NTM5MyA0LjY4IDMuNzIwNiAzLjM2IDMuODUzOTNMMiAzLjk4NzI2XCIgc3Ryb2tlPVwiI0ZGMkMxMFwiIHN0cm9rZS13aWR0aD1cIjEuNVwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD1cIk01LjY2NjUgMy4zMTM2Mkw1LjgxMzE3IDIuNDQwMjhDNS45MTk4NCAxLjgwNjk1IDUuOTk5ODQgMS4zMzM2MiA3LjEyNjUgMS4zMzM2Mkg4Ljg3MzE3QzkuOTk5ODQgMS4zMzM2MiAxMC4wODY1IDEuODMzNjIgMTAuMTg2NSAyLjQ0Njk1TDEwLjMzMzIgMy4zMTM2MlwiIHN0cm9rZT1cIiNGRjJDMTBcIiBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMTIuNTY2NyA2LjA5Mzc1TDEyLjEzMzQgMTIuODA3MUMxMi4wNiAxMy44NTM3IDEyIDE0LjY2NzEgMTAuMTQgMTQuNjY3MUg1Ljg2MDAyQzQuMDAwMDIgMTQuNjY3MSAzLjk0MDAyIDEzLjg1MzcgMy44NjY2OCAxMi44MDcxTDMuNDMzMzUgNi4wOTM3NVwiIHN0cm9rZT1cIiNGRjJDMTBcIiBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNNi44ODY0NyAxMS4wMDA0SDkuMTA2NDdcIiBzdHJva2U9XCIjRkYyQzEwXCIgc3Ryb2tlLXdpZHRoPVwiMS41XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTYuMzMzNSA4LjMzMzI1SDkuNjY2ODNcIiBzdHJva2U9XCIjRkYyQzEwXCIgc3Ryb2tlLXdpZHRoPVwiMS41XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhZGQtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBhZGRJY29uQm9yIGN1cnNvci1wb2ludGVyXCIgKGNsaWNrKT1cImFkZENvbHVtbigpXCIgW21hdFRvb2x0aXBdPVwiJ0FQUC5BRERfQ09MVU1OJyB8IGN1c3RvbVRyYW5zbGF0ZSA6ICdBZGQgQ29sdW1uJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhZGRJY29uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgd2lkdGg9XCIxNlwiIGhlaWdodD1cIjE2XCIgdmlld0JveD1cIjAgMCAxNiAxNlwiIGZpbGw9XCJub25lXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD1cIk04IDMuMzMzMjVWMTIuNjY2NlwiIHN0cm9rZT1cIiMwMDdiZmZcIiBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD1cIk0zLjMzMzAxIDhIMTIuNjY2M1wiIHN0cm9rZT1cIiMwMDdiZmZcIiBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3snQVBQLkFERF9DT0xVTU4nIHwgY3VzdG9tVHJhbnNsYXRlIDogJ0FkZCBDb2x1bW4nfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJjb25kaXRpb25zLmxlbmd0aCA9PT0gMCAmJiBjb2x1bW5zLmxlbmd0aCA9PT0gMFwiIGNsYXNzPVwiZXJyb3ItbWVzc2FnZVwiPlxuICAgICAgICAgICAgICAgICAgIHt7J0FQUC5BVF9MRUFTVF9PTkVfRklMVEVSX09SX09ORV9DT0xVTU5fSVNfUkVRJyB8IGN1c3RvbVRyYW5zbGF0ZSA6ICcgQXQgbGVhc3Qgb25lIGZpbHRlciBvciBvbmUgY29sdW1uIGlzIHJlcXVpcmVkJ319LlxuICAgICAgICAgICAgICAgIDwvZGl2PiAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWFjdGlvbnNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJzYXZlLWJ1dHRvblwiIChjbGljayk9XCJzYXZlKClcIiBbZGlzYWJsZWRdPVwiIWVkaXRpbmdWaWV3LnZhbGlkIHx8IChjb25kaXRpb25zLmxlbmd0aCA9PT0gMCAmJiBjb2x1bW5zLmxlbmd0aCA9PT0gMClcIj57eydBUFAuU0FWRScgfCBjdXN0b21UcmFuc2xhdGUgOiAnU2F2ZSd9fTwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiY2xvc2VNb2RhbCgpXCI+e3snQVBQLkNBTkNFTCcgfCBjdXN0b21UcmFuc2xhdGUgOiAnQ2FuY2VsJ319PC9idXR0b24+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Zvcm0+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICAgIDwhLS0gU0tTM01BWTI1IERlbGV0ZSBMaXN0IFZpZXctLT5cbiAgICA8ZGl2ICpuZ0lmPVwiaXNEZWxldGVNb2RhbE9wZW5cIiBjbGFzcz1cIm1vZGFsXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1jb250ZW50XCI+XG4gICAgICAgICAgICA8aDI+e3snQVBQLkRFTEVURV9MSVNUX1ZJRVcnIHwgY3VzdG9tVHJhbnNsYXRlIDogJ0RlbGV0ZSBMaXN0IFZpZXcnfX08L2gyPlxuICAgICAgICAgICAgPHA+e3snQVBQLkFSRV9ZT1VfU1VSRV9ZT1VfV0FOVF9UT19ERUxFVEUnIHwgY3VzdG9tVHJhbnNsYXRlIDogJ0FyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBkZWxldGUnfX0gXCJ7eyB2aWV3VG9EZWxldGU/LmZpbHRlck5hbWUgfX1cIj88L3A+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1kZWxldGVcIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiZGVsZXRlQ29uZmlybWVkKClcIj57eydBUFAuREVMRVRFJyB8IGN1c3RvbVRyYW5zbGF0ZSA6ICdEZWxldGUnfX08L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiY2xvc2VEZWxldGVNb2RhbCgpXCI+e3snQVBQLkNBTkNFTCcgfCBjdXN0b21UcmFuc2xhdGUgOiAnQ2FuY2VsJ319PC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG48L2Rpdj4iXX0=