mat-table-ext 0.0.10 → 1.0.0-beta.0

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 (33) hide show
  1. package/README.md +57 -57
  2. package/assets/_theming.scss +7 -7
  3. package/assets/pinLeft.svg +11 -11
  4. package/assets/pinNone.svg +5 -5
  5. package/assets/pinRight.svg +11 -11
  6. package/assets/pinned.svg +6 -2
  7. package/fesm2022/mat-table-ext-test1.mjs +3019 -0
  8. package/fesm2022/mat-table-ext-test1.mjs.map +1 -0
  9. package/index.d.ts +774 -5
  10. package/package.json +13 -21
  11. package/esm2020/lib/components/column-pinning/column-pinning.component.mjs +0 -58
  12. package/esm2020/lib/components/editing/editing.component.mjs +0 -122
  13. package/esm2020/lib/components/filter-columns-component/filter-columns-component.component.mjs +0 -68
  14. package/esm2020/lib/directives/resize-column.directive.mjs +0 -99
  15. package/esm2020/lib/mat-table-ext.component.mjs +0 -1020
  16. package/esm2020/lib/mat-table-ext.module.mjs +0 -237
  17. package/esm2020/lib/mat-table-ext.service.mjs +0 -20
  18. package/esm2020/lib/models/tableExtModels.mjs +0 -2
  19. package/esm2020/mat-table-ext.mjs +0 -5
  20. package/esm2020/public-api.mjs +0 -11
  21. package/fesm2015/mat-table-ext.mjs +0 -1584
  22. package/fesm2015/mat-table-ext.mjs.map +0 -1
  23. package/fesm2020/mat-table-ext.mjs +0 -1581
  24. package/fesm2020/mat-table-ext.mjs.map +0 -1
  25. package/lib/components/column-pinning/column-pinning.component.d.ts +0 -27
  26. package/lib/components/editing/editing.component.d.ts +0 -42
  27. package/lib/components/filter-columns-component/filter-columns-component.component.d.ts +0 -26
  28. package/lib/directives/resize-column.directive.d.ts +0 -27
  29. package/lib/mat-table-ext.component.d.ts +0 -348
  30. package/lib/mat-table-ext.module.d.ts +0 -58
  31. package/lib/mat-table-ext.service.d.ts +0 -11
  32. package/lib/models/tableExtModels.d.ts +0 -76
  33. package/public-api.d.ts +0 -7
@@ -1,1020 +0,0 @@
1
- import { animate, state, style, transition, trigger, } from '@angular/animations';
2
- import { SelectionModel } from '@angular/cdk/collections';
3
- import { moveItemInArray } from '@angular/cdk/drag-drop';
4
- import { EventEmitter, Output, } from '@angular/core';
5
- import { Component, Input, ViewChild, ViewEncapsulation, } from '@angular/core';
6
- import { MatDialogConfig } from '@angular/material/dialog';
7
- import { MatMenuTrigger } from '@angular/material/menu';
8
- import { MatPaginator } from '@angular/material/paginator';
9
- import { MatSort } from '@angular/material/sort';
10
- import { MatTableDataSource } from '@angular/material/table';
11
- import { EditingComponent } from '../lib/components/editing/editing.component';
12
- import * as XLSX from 'xlsx';
13
- import * as i0 from "@angular/core";
14
- import * as i1 from "@angular/material/dialog";
15
- import * as i2 from "../lib/mat-table-ext.service";
16
- import * as i3 from "@angular/forms";
17
- import * as i4 from "@angular/platform-browser";
18
- import * as i5 from "@angular/material/icon";
19
- import * as i6 from "@angular/common";
20
- import * as i7 from "@angular/material/table";
21
- import * as i8 from "@angular/cdk/drag-drop";
22
- import * as i9 from "@angular/material/core";
23
- import * as i10 from "@angular/material/button";
24
- import * as i11 from "@angular/material/checkbox";
25
- import * as i12 from "@angular/material/form-field";
26
- import * as i13 from "@angular/material/input";
27
- import * as i14 from "@angular/material/menu";
28
- import * as i15 from "@angular/material/paginator";
29
- import * as i16 from "@angular/material/progress-bar";
30
- import * as i17 from "@angular/material/select";
31
- import * as i18 from "@angular/material/sort";
32
- import * as i19 from "@angular/material/toolbar";
33
- import * as i20 from "@angular/material/tooltip";
34
- import * as i21 from "./directives/resize-column.directive";
35
- import * as i22 from "./components/column-pinning/column-pinning.component";
36
- import * as i23 from "./components/filter-columns-component/filter-columns-component.component";
37
- export class MatTableExtComponent {
38
- constructor(dialog, service, formBuildersService, domSanitizer, matIconRegistry, cdr) {
39
- this.dialog = dialog;
40
- this.service = service;
41
- this.formBuildersService = formBuildersService;
42
- this.domSanitizer = domSanitizer;
43
- this.matIconRegistry = matIconRegistry;
44
- this.cdr = cdr;
45
- this.columns = [];
46
- this.columnResizable = false;
47
- this.stripedRows = false;
48
- this.rowHover = false;
49
- this.inlineRowEditing = false;
50
- this.inCellEditing = false;
51
- this.popupRowEditing = false;
52
- this.enableDelete = false;
53
- this.rowSelection = false;
54
- this.multiRowSelection = false;
55
- this.stickyFooter = false;
56
- this.stickyHeader = false;
57
- this.showFooterRow = false;
58
- this.columnFilter = false;
59
- this.loadingIndicator = false;
60
- this.sorting = false;
61
- this.showToolbar = false;
62
- this.toolbarTitle = '';
63
- this.tableHeight = '';
64
- this.toolbarHeight = '50px';
65
- this.tableWidth = '100%';
66
- this.scrollbarH = false;
67
- this.columnHidable = false;
68
- this.columnPinnable = false;
69
- this.globalSearch = false;
70
- this.expandRows = false;
71
- this.dndColumns = false;
72
- this.showPaginator = true;
73
- this.showFirstLastButtons = false;
74
- this.exportButtonEnable = false;
75
- this.pageSizeOptions = [10, 50, 100];
76
- this.cellTemplateRefMap = {};
77
- // Table outputs
78
- this.inlineChange = new EventEmitter();
79
- this.cellChange = new EventEmitter();
80
- this.popupChange = new EventEmitter();
81
- this.rowDeleted = new EventEmitter();
82
- this.scroll = new EventEmitter();
83
- this.selectionChanged = new EventEmitter();
84
- this.expansionChange = new EventEmitter();
85
- this.tableID = new Date().getTime();
86
- this.columnPinningOptions = [];
87
- this.exportMenuCtrl = false;
88
- this.columnPinMenuCtrl = false;
89
- this.hideShowMenuCtrl = false;
90
- this.columnFilterBySelection = false;
91
- this.rowDataTemp = {};
92
- this.inlineEditingTemplateRefData = {};
93
- this.displayedColumns = [];
94
- this.showHideColumnsArray = [];
95
- this.columnsList = [];
96
- this.columnsArray = [];
97
- this.headersFiltersIds = [];
98
- this.columnsToDisplayWithExpand = [];
99
- this.selection = new SelectionModel(false, []);
100
- this.hiddenCtrl = new SelectionModel(true, []);
101
- this.tableData = [];
102
- this.filterValues = {};
103
- this.globalFilter = '';
104
- this.showHideFilter = '';
105
- this.individualFilter = '';
106
- this.toggleFilters = false;
107
- this.hideRows = false;
108
- this.currentRowIndex = -1;
109
- this.currentRow = {};
110
- this.cellEditing = {};
111
- this.menuX = 0;
112
- this.menuY = 0;
113
- this.dynamicDisplayedColumns = [
114
- { filter: false, name: 'select', show: false },
115
- { filter: false, name: 'edit', show: false },
116
- { filter: false, name: 'popup', show: false },
117
- { filter: false, name: 'delete', show: false },
118
- { filter: false, name: 'expand', show: false },
119
- ];
120
- this.inputPropertyKeys = [
121
- 'dataSource',
122
- 'columns',
123
- 'inlineRowEditing',
124
- 'popupRowEditing',
125
- 'enableDelete',
126
- 'rowSelection',
127
- 'multiRowSelection',
128
- 'stickyHeader',
129
- 'stickyFooter',
130
- 'columnFilter',
131
- 'globalSearch',
132
- 'expandRows',
133
- 'sorting',
134
- ];
135
- /**
136
- * @description This mapping is used to set and update changesin the table.
137
- */
138
- this.setPropertiesMap = {
139
- dataSource: (value) => this.setTableDataSource(value),
140
- columns: (value) => this.setColumnsData(value.currentValue),
141
- inlineRowEditing: (value) => this.showHideColumn('edit', value.currentValue),
142
- popupRowEditing: (value) => this.showHideColumn('popup', value.currentValue),
143
- enableDelete: (value) => this.showHideColumn('delete', value.currentValue),
144
- rowSelection: (value) => this.setRowSelection(value.currentValue),
145
- multiRowSelection: (value) => {
146
- this.selection = new SelectionModel(value.currentValue, []);
147
- },
148
- stickyHeader: (value) => {
149
- this.stickyHeader = value.currentValue;
150
- },
151
- stickyFooter: (value) => {
152
- this.stickyFooter = value.currentValue;
153
- },
154
- columnFilter: (value) => this.setColumnFilter(value.currentValue),
155
- globalSearch: (value) => (this.dataSource.filterPredicate = this.createFilter()),
156
- expandRows: (value) => {
157
- this.loadingIndicator = true;
158
- this.dataSource = new MatTableDataSource(this.tableData);
159
- if (value.currentValue == true) {
160
- if (!this.displayedColumns.includes('expand')) {
161
- this.displayedColumns.push('expand');
162
- this.columnsToDisplayWithExpand = [...this.displayedColumns];
163
- }
164
- }
165
- else {
166
- this.columnsToDisplayWithExpand = [...this.displayedColumns];
167
- if (this.displayedColumns.includes('expand')) {
168
- let index = this.displayedColumns.indexOf('expand');
169
- this.displayedColumns.splice(index, 1);
170
- }
171
- this.expandedElement = null;
172
- }
173
- setTimeout(() => {
174
- this.loadingIndicator = false;
175
- }, 200);
176
- },
177
- sorting: (value) => (this.dataSource.sort = this.sort),
178
- };
179
- /**
180
- * @description This method will take data from inline editing template and update in table data source.
181
- * @param row updated row from inline editing template.
182
- */
183
- this.updateInlineTemplateData = (row) => {
184
- this.service.selectedRow.next(row);
185
- };
186
- this.addIconsToRegistry();
187
- if (this.dataSource) {
188
- this.tableData = this.dataSource.data;
189
- }
190
- }
191
- /**
192
- *
193
- * @param changes changes captured each time user changes property value.
194
- */
195
- ngOnChanges(changes) {
196
- this.setPropertyValue(changes);
197
- }
198
- ngOnInit() {
199
- if (this.dataSource) {
200
- this.dataSource.filterPredicate = this.createFilter();
201
- }
202
- }
203
- ngAfterViewInit() {
204
- if (this.dataSource) {
205
- this.dataSource.paginator = this.paginator;
206
- this.dataSource.sort = this.sort;
207
- }
208
- }
209
- /**
210
- * @description checks and updates the the column's hide and show properties.
211
- */
212
- setColumnHideShow() {
213
- if (this.hideShowMenuGroup !== undefined &&
214
- this.hideShowMenuGroup !== null) {
215
- this.updateColumnsHideShow(this.hideShowMenuGroup.value);
216
- }
217
- }
218
- /**
219
- * @description set the properties of the table.
220
- * @param changes changes captured each time user changes property value.
221
- */
222
- setPropertyValue(changes) {
223
- let keys = Object.keys(changes);
224
- keys.forEach((property) => {
225
- if (this.inputPropertyKeys.includes(property)) {
226
- this.setPropertiesMap[property](changes[property]);
227
- }
228
- else if (property == 'showToolbar') {
229
- if (changes['columns']) {
230
- this.setToolbarMenuControls(changes['columns'].currentValue);
231
- }
232
- else {
233
- this.setToolbarMenuControls(this.columnsArray);
234
- }
235
- }
236
- });
237
- }
238
- /**
239
- * @description used set data source for table.
240
- * @param value data source value from user.
241
- */
242
- setTableDataSource(value) {
243
- if (value.currentValue) {
244
- this.tableData = value.currentValue.data;
245
- this.dataSource = value.currentValue;
246
- this.reCal();
247
- }
248
- else {
249
- this.dataSource = new MatTableDataSource([{}]);
250
- }
251
- }
252
- /**
253
- * @description used create seletion model and set selection column visibility.
254
- * @param value boolean value to show or hide selection Column from table.
255
- */
256
- setRowSelection(value) {
257
- this.selection = new SelectionModel(true, []);
258
- this.updateSelectionColumnVisibility(value);
259
- }
260
- /**
261
- * @description create filter header row and assigns filter predicate to table data source.
262
- * @param value boolean value to change visibility of column filter row.
263
- */
264
- setColumnFilter(value) {
265
- if (value) {
266
- let array = [];
267
- this.columnsArray.forEach((column, i) => {
268
- if (this.dynamicDisplayedColumns.filter((a) => a.name == column?.field)[0]
269
- .show) {
270
- array.push(column?.field + '_' + i);
271
- }
272
- });
273
- this.headersFiltersIds = array;
274
- this.dataSource.filterPredicate = this.createFilter();
275
- }
276
- else {
277
- this.headersFiltersIds = [];
278
- this.dataSource.filter = '';
279
- }
280
- this.toggleFilters = value;
281
- }
282
- /**
283
- * @description This method returns the list of visible column names.
284
- * @returns list of visible column names.
285
- */
286
- getDisplayedColumns() {
287
- let list = this.dynamicDisplayedColumns
288
- .filter((cd) => cd.show)
289
- .map((cd) => cd.name);
290
- return list;
291
- }
292
- /**
293
- * @param menuType type of menu to open from toolbar.
294
- * @param event mouse event to open menu on that location.
295
- */
296
- openMenu(menuType, event) {
297
- this.menuX = event.clientX;
298
- this.menuY = event.clientY;
299
- switch (menuType) {
300
- case 'export': {
301
- this.exportMenuCtrl = true;
302
- this.menuTrigger.openMenu();
303
- break;
304
- }
305
- case 'hideShow': {
306
- this.hideShowMenuCtrl = true;
307
- this.openHideShowMenu(this.columnsArray);
308
- break;
309
- }
310
- case 'columnPin': {
311
- this.columnPinMenuCtrl = true;
312
- this.openHideShowMenu(this.columnsArray);
313
- break;
314
- }
315
- }
316
- }
317
- /**
318
- * @description triggers when menu is closed and reset the required controls.
319
- */
320
- menuClosed() {
321
- this.exportMenuCtrl = false;
322
- }
323
- /**
324
- * @description set list of columns to display in table.
325
- * @param columns columns array from user input.
326
- */
327
- setColumnsData(columns) {
328
- if (columns.length) {
329
- this.columnsArray = [...columns];
330
- this.setColumnsList(columns);
331
- }
332
- }
333
- /**
334
- * @description set list of columns to display in table.
335
- * @param columns columns array from user input with configurations.
336
- */
337
- setColumnsList(columns) {
338
- this.columnsList = [];
339
- this.displayedColumns = ['select', 'edit', 'popup', 'delete'];
340
- let columnsArray = [];
341
- columns.forEach((col) => {
342
- if (typeof col?.header == 'string') {
343
- this.columnsList.push(col?.header);
344
- this.displayedColumns.push(col?.field);
345
- columnsArray.push({ filter: true, name: col?.field, show: !col.hide });
346
- }
347
- });
348
- this.dynamicDisplayedColumns = [
349
- { filter: false, name: 'select', show: false },
350
- { filter: false, name: 'edit', show: false },
351
- { filter: false, name: 'popup', show: false },
352
- { filter: false, name: 'delete', show: false },
353
- ];
354
- this.dynamicDisplayedColumns = columnsArray.concat(this.dynamicDisplayedColumns);
355
- }
356
- /**
357
- * @description Take boolean value and name column and update its visibility status in table.
358
- * @param name name of the column to set visibility.
359
- * @param value boolean value to set visibility of the column.
360
- */
361
- showHideColumn(name, value) {
362
- this.dynamicDisplayedColumns.filter((a) => a.name == name)[0].show = value;
363
- if (this.columnFilter) {
364
- this.setColumnFilter(true);
365
- }
366
- }
367
- /**
368
- * @description This method will position the selection column to first and also update its visibility.
369
- * @param value value used to set visibility of the selection column.
370
- */
371
- updateSelectionColumnVisibility(value) {
372
- let columnName = 'select';
373
- let column = this.dynamicDisplayedColumns.filter((a) => a.name == columnName)[0];
374
- let index = this.dynamicDisplayedColumns.findIndex((column) => column.name == columnName);
375
- if (index > -1) {
376
- this.dynamicDisplayedColumns.splice(index, 1);
377
- this.dynamicDisplayedColumns.unshift(column);
378
- this.dynamicDisplayedColumns.filter((column) => column.name == columnName)[0].show = value;
379
- }
380
- }
381
- /**
382
- * @description This method is used to update the position of column in columns array according to its dropped position.
383
- * @param event CdkDragDrop used to update column position in columns array.
384
- */
385
- onDrop(event) {
386
- if (this.dndColumns) {
387
- let adjustedValue = 0;
388
- if (this.dynamicDisplayedColumns[0].name == 'select' &&
389
- this.dynamicDisplayedColumns[0].show == false) {
390
- adjustedValue = 1;
391
- }
392
- moveItemInArray(this.dynamicDisplayedColumns, event.previousIndex + adjustedValue, event.currentIndex + adjustedValue);
393
- }
394
- }
395
- /**
396
- * @description This method create filter predicate function which will set search value to table filters
397
- * for both global and individual colum filtering.
398
- * @returns returns boolean value to filter rows in table.
399
- */
400
- createFilter() {
401
- const tableFilterPredicate = (data, filter) => {
402
- let result = true;
403
- // search all column fields
404
- if (this.globalFilter) {
405
- let expression = '';
406
- let keys = Object.keys(data);
407
- keys.forEach((key) => {
408
- expression =
409
- expression +
410
- `data.${key}.toString().trim().toLowerCase().indexOf(this.globalFilter.toLowerCase()) !== -1 ||`;
411
- });
412
- if (expression.charAt(expression.length - 2) +
413
- expression.charAt(expression.length - 1) ==
414
- '||') {
415
- expression = expression.substring(0, expression.length - 2);
416
- }
417
- result = eval(expression);
418
- }
419
- if (!result) {
420
- return false;
421
- }
422
- let searchString = JSON.parse(filter);
423
- //search single column field
424
- if (this.individualFilter) {
425
- return (data[this.individualFilter]
426
- .toString()
427
- .trim()
428
- .toLowerCase()
429
- .indexOf(searchString[this.individualFilter].toString().toLowerCase()) !== -1);
430
- }
431
- return true;
432
- };
433
- return tableFilterPredicate;
434
- }
435
- /**
436
- * @description assigns the search value to mat table data source to apply the filter.
437
- * @param searchValue value to be searched from table rows.
438
- */
439
- applyGlobalFilter(searchValue) {
440
- this.globalFilter = searchValue;
441
- let columns = {};
442
- this.columnsArray.forEach((column) => {
443
- if (column.field)
444
- columns[column.field] = searchValue;
445
- });
446
- this.dataSource.filter = JSON.stringify(columns);
447
- }
448
- /**
449
- * @description This method is used to apply column based filtering
450
- * @param searchValue value to be searched from table rows.
451
- * @param column filter will be applied based on this column field.
452
- */
453
- applyColumnFilter(searchValue, column) {
454
- this.individualFilter = column.field;
455
- this.filterValues[column.field] = searchValue[column.field];
456
- this.dataSource.filter = JSON.stringify(this.filterValues);
457
- }
458
- /**
459
- * @description This method will take row and its index enable inline editing tools on that row.
460
- * @param row row on which user wants to do edit.
461
- * @param index index of the row where inline editing will be enabled.
462
- */
463
- enableInlineEditing(row, index) {
464
- const rowData = {};
465
- rowData['e' + index] = { ...row };
466
- this.rowDataTemp = rowData;
467
- setTimeout(() => {
468
- this.tableData[index]['editable'] = !this.tableData[index]['editable'];
469
- }, 0);
470
- }
471
- /**
472
- * @description This method will create and return data to inline editing template.
473
- * @param row row on which user wants to do edit.
474
- * @param index index of the row where inline editing will be enabled.
475
- * @param column current column of the table.
476
- */
477
- getInlineEditingData(row, index, column) {
478
- this.inlineEditingTemplateRefData = {
479
- row: { ...row },
480
- column: { ...column },
481
- index: index,
482
- updateFunc: this.updateInlineTemplateData,
483
- };
484
- return this.inlineEditingTemplateRefData;
485
- }
486
- /**
487
- * @description This method set data for in-cell editing.
488
- * @param row row on which user wants to do edit.
489
- * @param index index of the row where inline editing will be enabled.
490
- */
491
- setCellData(row, index) {
492
- this.currentRow = { ...row };
493
- this.currentRowIndex = index;
494
- this.rowDataTemp['e' + index] = { ...row };
495
- }
496
- /**
497
- * @description This will restore the data and cencel the inline editing.
498
- * @param row row on which user wants to do edit.
499
- * @param index index of the row where inline editing will be enabled.
500
- */
501
- cancelInlineEditing(row, index) {
502
- this.tableData.filter((a, i) => i == index)[0]['editable'] =
503
- !this.tableData.filter((a, i) => i == index)[0]['editable'];
504
- this.dataSource = new MatTableDataSource(this.tableData);
505
- this.rowDataTemp['e' + index] = {};
506
- this.service.selectedRow.next(undefined);
507
- }
508
- /**
509
- * @description This method will save and update the inline editing data and emit the update row and index.
510
- * @param row row on which user wants to do edit.
511
- * @param index index of the row where inline editing will be enabled.
512
- */
513
- saveInlineEditing(row, index) {
514
- if (!this.inlineEditingTemplateRef) {
515
- this.tableData[index] = { ...this.rowDataTemp['e' + index] };
516
- row = { ...this.rowDataTemp['e' + index] };
517
- }
518
- else {
519
- let changedData = this.service.selectedRow.value;
520
- if (changedData) {
521
- this.tableData[index] = { ...changedData };
522
- }
523
- }
524
- this.dataSource = new MatTableDataSource(this.tableData);
525
- this.rowDataTemp['e' + index] = {};
526
- let data = {
527
- row: row,
528
- index: index,
529
- };
530
- this.inlineChange.emit(data);
531
- this.tableData[index]['editable'] = false;
532
- }
533
- /**
534
- * @description This method will save and update the cell editing data and emit the update row and index.
535
- */
536
- saveCellEditing() {
537
- this.cellEditing = {};
538
- let index = this.currentRowIndex;
539
- if (index > -1) {
540
- if (this.cellEditingTemplateRef) {
541
- let changedData = this.service.selectedRow.value;
542
- if (changedData) {
543
- this.tableData[index] = { ...changedData };
544
- }
545
- }
546
- else {
547
- this.tableData[index] = { ...this.rowDataTemp['e' + index] };
548
- }
549
- this.dataSource = new MatTableDataSource(this.tableData);
550
- this.rowDataTemp['e' + index] = {};
551
- let data = {
552
- row: { ...this.tableData[index] },
553
- index: index,
554
- };
555
- this.currentRowIndex = -1;
556
- this.cellChange.emit(data);
557
- }
558
- }
559
- /**
560
- * @description This method will delete the row from the given index and emit the deleted row and index.
561
- * @param row row to be deleted.
562
- * @param index index of the row to be deleted.
563
- */
564
- deleteRow(row, index) {
565
- this.tableData.splice(index, 1);
566
- this.dataSource = new MatTableDataSource(this.tableData);
567
- this.dataSource.paginator = this.paginator;
568
- this.dataSource.sort = this.sort;
569
- this.rowDeleted.emit({ removedRow: row, fromIndex: index });
570
- }
571
- /**
572
- * @description This method will expand or collapse the row and emit expand event.
573
- * @param row row to be expanded or collapsed.
574
- * @param expand value used to expand or collapse the row.
575
- * @param index index of the row.
576
- */
577
- expandRow(row, expand, index) {
578
- if (this.expandRows) {
579
- this.expansionChange.emit({ data: row, expanded: expand, index: index });
580
- this.expandedElement = this.expandedElement === row ? null : row;
581
- }
582
- }
583
- /**
584
- * @description This method is used to set data for popup component and open editing dialog.
585
- * @param row row which used want to edit.
586
- */
587
- openEditingDialog(row) {
588
- const dialogConfig = new MatDialogConfig();
589
- dialogConfig.disableClose = true;
590
- dialogConfig.width = '40%';
591
- dialogConfig.height = '70%';
592
- dialogConfig.maxWidth = '100%';
593
- let rowData = { ...row };
594
- dialogConfig.data = {
595
- row: rowData,
596
- columns: [...this.columnsArray],
597
- templateRef: this.popupEditingTemplateRef,
598
- };
599
- this.dialog
600
- .open(EditingComponent, dialogConfig)
601
- .afterClosed()
602
- .subscribe((data) => {
603
- let index = this.tableData.indexOf(row);
604
- if (data && index > -1) {
605
- this.tableData[index] = data;
606
- this.dataSource = new MatTableDataSource(this.tableData);
607
- let dataChange = {
608
- row: data,
609
- index: index,
610
- };
611
- this.popupChange.emit(dataChange);
612
- }
613
- });
614
- }
615
- /**
616
- * @description used to check whether all rows are selected.
617
- */
618
- isAllSelected() {
619
- const numSelected = this.selection.selected.length;
620
- const numRows = this.dataSource.data.length;
621
- return numSelected === numRows;
622
- }
623
- /**
624
- * @description this method is used to toggle the all and no rows selection.
625
- */
626
- toggleAllRows() {
627
- if (this.isAllSelected()) {
628
- this.selection.clear();
629
- return;
630
- }
631
- this.selection.select(...this.dataSource.data);
632
- }
633
- /**
634
- * @description This method is used return aria-label for selection column checkboxs.
635
- * @param row row from table.
636
- * @returns labels for selection column checkboxs.
637
- */
638
- checkboxLabel(row) {
639
- if (!row) {
640
- return `${this.isAllSelected() ? 'deselect' : 'select'} all`;
641
- }
642
- return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${row.position + 1}`;
643
- }
644
- /**
645
- * @description create form control for columns for hiding and and pinning purpose
646
- * @param columns list of columns to be displayed
647
- */
648
- setToolbarMenuControls(columns) {
649
- if (columns.length > 0 && this.showToolbar) {
650
- const group = this.formBuildersService.group({});
651
- columns.forEach((column) => {
652
- const control = this.formBuildersService.control(true);
653
- group.addControl(column.field, control);
654
- });
655
- this.hideShowMenuGroup = group;
656
- }
657
- }
658
- /**
659
- * @param column current column
660
- * @param event mouse event used to set the menu position
661
- */
662
- openPinnablePropertyMenu(column, event) {
663
- this.menuX = event.clientX;
664
- this.menuY = event.clientY;
665
- let options = [
666
- {
667
- label: 'Pin Left',
668
- value: 'left',
669
- selected: false,
670
- field: column.field,
671
- },
672
- {
673
- label: 'Pin Right',
674
- value: 'right',
675
- selected: false,
676
- field: column.field,
677
- },
678
- { label: 'No Pin', value: null, selected: false, field: column.field },
679
- ];
680
- if (column.pinned && column.pinned !== null) {
681
- options.forEach((opt) => {
682
- if (opt.value === column.pinned) {
683
- opt.selected = true;
684
- }
685
- });
686
- }
687
- else if (column.pinned == null || column.pinned == 'null') {
688
- options[2].selected = true;
689
- }
690
- this.columnPinningOptions = options;
691
- this.columnMenuTrigger.openMenu();
692
- }
693
- /**
694
- * @description This method is used to reset menu checks when required.
695
- */
696
- resetMenuChecks() {
697
- this.hideShowMenuCtrl = false;
698
- this.showHideColumnsArray = [];
699
- this.columnPinMenuCtrl = false;
700
- this.columnPinningOptions = [];
701
- }
702
- /**
703
- * @description This method is used to filter columns for menus like pinning or hide show menu.
704
- * @param value search value to filter colunms
705
- */
706
- filterColumns(value) {
707
- if (value !== '') {
708
- this.showHideColumnsArray = this.columnsArray.filter((col) => {
709
- return col.header.toLowerCase().includes(value.toLowerCase());
710
- });
711
- }
712
- else {
713
- this.showHideColumnsArray = this.columnsArray;
714
- }
715
- }
716
- /**
717
- * @description This method is used to open hide show column menu.
718
- * @param columns columns array to display in hide show menu.
719
- */
720
- openHideShowMenu(columns) {
721
- this.showHideColumnsArray = [...columns];
722
- this.columnMenuTrigger.openMenu();
723
- }
724
- /**
725
- * @param values columns
726
- */
727
- updateColumnsHideShow(values) {
728
- let keys = Object.keys(values);
729
- keys.forEach((key) => {
730
- this.showHideColumn(key, values[key]);
731
- });
732
- }
733
- /**
734
- * @description This method is called when the table rows are scrolled.
735
- * @param event scroll event
736
- */
737
- onScroll(event) {
738
- this.scroll.emit(event);
739
- }
740
- /**
741
- * @param row row to be toggled
742
- * @param index index of toggled row
743
- */
744
- setSelectedRows(row, index) {
745
- this.selection.toggle(row);
746
- if (this.selection.isSelected(row)) {
747
- this.selectionChanged.emit({ row: row, index: index, isSelected: true });
748
- }
749
- else {
750
- this.selectionChanged.emit({ row: row, index: index, isSelected: false });
751
- }
752
- }
753
- /**
754
- * @description This method is used to display all hidden rows.
755
- */
756
- showHiddenRows() {
757
- this.hideRows = false;
758
- this.selection.clear();
759
- this.hiddenCtrl.clear();
760
- }
761
- /**
762
- * @description This method is used to hide all selected rows.
763
- */
764
- hideSelectedRows() {
765
- if (!this.selection.isEmpty()) {
766
- let values = [...this.selection.selected];
767
- values.forEach((value) => {
768
- if (!this.hiddenCtrl.isSelected(value)) {
769
- this.hiddenCtrl.toggle(value);
770
- }
771
- });
772
- this.selection.clear();
773
- this.hideRows = true;
774
- }
775
- }
776
- /**
777
- * @description This method is used to recalculate the required values for table.
778
- */
779
- reCal() {
780
- if (this.showPaginator) {
781
- this.dataSource.paginator = this.paginator;
782
- }
783
- if (this.sorting) {
784
- this.dataSource.sort = this.sort;
785
- }
786
- if (this.columnFilter) {
787
- this.dataSource.filterPredicate = this.createFilter();
788
- }
789
- }
790
- /**
791
- * @description This method is called in constructor method to add SVGs into icon registration.
792
- */
793
- addIconsToRegistry() {
794
- let y = this.domSanitizer.bypassSecurityTrustResourceUrl(`assets/pinRight.svg`);
795
- let iconNames = ['pinLeft', 'pinRight', 'pinNone', 'pinned', 'pinIcon'];
796
- iconNames.forEach((icon) => {
797
- this.matIconRegistry.addSvgIcon(icon, this.domSanitizer.bypassSecurityTrustResourceUrl(`assets/${icon}.svg`));
798
- });
799
- }
800
- /**
801
- * @description This method is used to export table data.
802
- * @param type type of file to be exported.
803
- */
804
- exportTable(type) {
805
- var element = document.getElementById('matTableExt' + this.tableID);
806
- var ws = XLSX.utils.table_to_sheet(element);
807
- ws = this.writeSheetData(ws);
808
- const wb = XLSX.utils.book_new();
809
- XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
810
- XLSX.writeFile(wb, `tablesheets.${type}`);
811
- }
812
- /**
813
- * @description This method is used to split name of filter row header to get index.
814
- * @param value value to be splited for index.
815
- * @returns Will return index of column from value.
816
- */
817
- returnIndex(value) {
818
- return Number(value.split('_')[1]);
819
- }
820
- /**
821
- * @description This method is used to manage column filtering, expanded data for exporting.
822
- * @param ws work sheet
823
- * @returns custom generated worksheet to be used in export.
824
- */
825
- writeSheetData(ws) {
826
- let displayedColumns = this.getDisplayedColumns();
827
- var nMerges = this.getMergeIndex(ws['!merges'] || []);
828
- var merges = ws['!merges'] || [];
829
- let data = {
830
- '!cols': [],
831
- '!rows': [],
832
- '!merges': nMerges,
833
- };
834
- var range = XLSX.utils.decode_range(ws['!ref'] || '');
835
- let extracolumns = ['popup', 'delete', 'select', 'edit'];
836
- let keys = Object.keys(ws);
837
- let nKey = 'A';
838
- keys.forEach((key, i) => {
839
- if (ws[key]?.v && typeof ws[key]?.v === 'string') {
840
- if (!extracolumns.includes(ws[key].v.toLowerCase()) &&
841
- displayedColumns.includes(ws[key].v.toLowerCase())) {
842
- let lastRowIndex = range?.e?.r;
843
- data[key] = ws[key];
844
- let chr = key.charAt(0);
845
- for (let j = 2; j <= lastRowIndex; j++) {
846
- if (ws[chr + (j + 1)] !== undefined &&
847
- (typeof ws[chr + (j + 1)].v === 'string' ||
848
- typeof ws[chr + (j + 1)].v === 'number')) {
849
- data[nKey + j] = ws[chr + (j + 1)];
850
- }
851
- }
852
- nKey = String.fromCharCode(nKey.charCodeAt(0) + 1);
853
- }
854
- }
855
- });
856
- if (this.rowSelection) {
857
- let chr = 'A';
858
- for (let i = 1; i < range.e.c + 1; i++) {
859
- data[chr + 1] = data[String.fromCharCode(chr.charCodeAt(0) + 1) + 1];
860
- chr = String.fromCharCode(chr.charCodeAt(0) + 1);
861
- if (i == range.e.c) {
862
- data[chr + 1] = undefined;
863
- }
864
- }
865
- }
866
- if (this.rowSelection && this.expandRows) {
867
- merges.forEach((merge) => {
868
- data['A' + merge.s.r] = ws['A' + (merge.s.r + 1)];
869
- });
870
- }
871
- range.e.r--;
872
- let nRef = XLSX.utils.encode_range(range);
873
- data['!ref'] = nRef;
874
- data['!fullref'] = nRef;
875
- return data;
876
- }
877
- getMergeIndex(merges) {
878
- var arr = [];
879
- merges.forEach((element) => {
880
- arr.push({
881
- e: {
882
- r: element.e.r == 0 ? element.e.r : element.e.r - 1,
883
- c: element.e.c,
884
- },
885
- s: {
886
- r: element.s.r == 0 ? element.s.r : element.s.r - 1,
887
- c: element.s.c,
888
- },
889
- });
890
- });
891
- return arr;
892
- }
893
- }
894
- MatTableExtComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: MatTableExtComponent, deps: [{ token: i1.MatDialog }, { token: i2.MatTableExtService }, { token: i3.FormBuilder }, { token: i4.DomSanitizer }, { token: i5.MatIconRegistry }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
895
- MatTableExtComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: MatTableExtComponent, selector: "mat-table-ext", inputs: { dataSource: "dataSource", columns: "columns", columnResizable: "columnResizable", stripedRows: "stripedRows", rowHover: "rowHover", inlineRowEditing: "inlineRowEditing", inCellEditing: "inCellEditing", popupRowEditing: "popupRowEditing", enableDelete: "enableDelete", rowSelection: "rowSelection", multiRowSelection: "multiRowSelection", stickyFooter: "stickyFooter", stickyHeader: "stickyHeader", showFooterRow: "showFooterRow", columnFilter: "columnFilter", loadingIndicator: "loadingIndicator", sorting: "sorting", showToolbar: "showToolbar", toolbarTitle: "toolbarTitle", tableHeight: "tableHeight", toolbarHeight: "toolbarHeight", tableWidth: "tableWidth", scrollbarH: "scrollbarH", toolbarTemplate: "toolbarTemplate", columnHidable: "columnHidable", columnPinnable: "columnPinnable", globalSearch: "globalSearch", expandRows: "expandRows", dndColumns: "dndColumns", showPaginator: "showPaginator", showFirstLastButtons: "showFirstLastButtons", exportButtonEnable: "exportButtonEnable", pageSizeOptions: "pageSizeOptions", toolbarTemplateRef: "toolbarTemplateRef", headerTemplateRef: "headerTemplateRef", cellTemplateRef: "cellTemplateRef", expansionTemplateRef: "expansionTemplateRef", popupEditingTemplateRef: "popupEditingTemplateRef", inlineEditingTemplateRef: "inlineEditingTemplateRef", cellEditingTemplateRef: "cellEditingTemplateRef", cellTemplateRefMap: "cellTemplateRefMap" }, outputs: { inlineChange: "inlineChange", cellChange: "cellChange", popupChange: "popupChange", rowDeleted: "rowDeleted", scroll: "scroll", selectionChanged: "selectionChanged", expansionChange: "expansionChange" }, viewQueries: [{ propertyName: "menuTrigger", first: true, predicate: MatMenuTrigger, descendants: true }, { propertyName: "columnMenuTrigger", first: true, predicate: ["columnMenuTrigger"], descendants: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true }, { propertyName: "sort", first: true, predicate: MatSort, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div [style.width]=\"tableWidth\">\r\n <mat-form-field class=\"global-search-field\" appearance=\"fill\" *ngIf=\"globalSearch\">\r\n <mat-label>Search</mat-label>\r\n <input matInput [ngModel]=\"globalFilter\" (ngModelChange)=\"applyGlobalFilter($event)\" placeholder=\"Ex. Mia\" #input>\r\n </mat-form-field>\r\n <mat-toolbar class=\"toolbar-container\" *ngIf=\"showToolbar\" [style.height]=\"toolbarHeight?toolbarHeight:'50px'\">\r\n <span class=\"toolbar-title\" *ngIf=\"toolbarTitle\">{{toolbarTitle}}</span>\r\n <ng-container *ngIf=\"toolbarTemplateRef\" [ngTemplateOutlet]=\"toolbarTemplateRef\"></ng-container>\r\n <span class=\"example-spacer\"></span>\r\n <ng-container *ngIf=\"rowSelection || multiRowSelection\">\r\n <button class=\"hide-button\" mat-stroked-button color=\"primary\" (click)=\"hideSelectedRows()\">\r\n Hide Rows\r\n </button>\r\n <button class=\"hide-button\" mat-stroked-button color=\"primary\" (click)=\"showHiddenRows()\">\r\n Show All Rows\r\n </button>\r\n </ng-container>\r\n <button *ngIf=\"columnHidable\" class=\"hide-button\" mat-stroked-button color=\"primary\"\r\n (click)=\"openMenu('hideShow',$event)\" matTooltip=\"Column Visibility\" matTooltipPosition=\"above\">\r\n <mat-icon>visibility</mat-icon>\r\n </button>\r\n <button *ngIf=\"columnPinnable\" class=\"pin-button\" mat-stroked-button color=\"primary\"\r\n (click)=\"openMenu('columnPin',$event)\" matTooltip=\"Column Pinning\">\r\n <mat-icon svgIcon=\"pinIcon\"></mat-icon>\r\n </button>\r\n <button *ngIf=\"exportButtonEnable\" class=\"export-button\" mat-stroked-button color=\"primary\"\r\n (click)=\"openMenu('export',$event)\" matTooltip=\"Table Data Export\">\r\n <mat-icon>import_export</mat-icon> <span>Export</span>\r\n <mat-icon>expand_more</mat-icon>\r\n </button>\r\n <div style=\"visibility: hidden; position:fixed\" [matMenuTriggerFor]=\"menu\" [style.left.px]=\"menuX\"\r\n [style.top.px]=\"menuY\"></div>\r\n </mat-toolbar>\r\n <mat-menu #menu=\"matMenu\" (closed)=\"menuClosed()\" id=\"exportMenu\">\r\n <ng-container *ngIf=\"exportMenuCtrl\">\r\n <mat-option (click)=\"exportTable('xlsx')\">Export to Excel</mat-option>\r\n <mat-option (click)=\"exportTable('csv')\">Export to CSV</mat-option>\r\n </ng-container>\r\n </mat-menu>\r\n <div style=\"visibility: hidden; position:fixed\" #columnMenuTrigger=\"matMenuTrigger\" [matMenuTriggerFor]=\"columnMenu\"\r\n [style.left.px]=\"menuX\" [style.top.px]=\"menuY\">\r\n </div>\r\n <mat-menu #columnMenu=\"matMenu\" (closed)=\"resetMenuChecks()\">\r\n <div class=\"toolbar-menu-container\" *ngIf=\"hideShowMenuCtrl\" [formGroup]=\"hideShowMenuGroup\"\r\n (click)=\"$event.stopPropagation()\">\r\n <h4 class=\"column-headers\">Visible Columns</h4>\r\n <mat-form-field appearance=\"fill\" style=\"width: -webkit-fill-available;\">\r\n <mat-label>Filter Columns</mat-label>\r\n <input matInput [(ngModel)]=\"showHideFilter\" (ngModelChange)=\"filterColumns($event)\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <div class=\"showHide-menu-columns-list\">\r\n <div class=\"toolbar-menu-item\" *ngFor=\"let column of showHideColumnsArray\">\r\n <mat-checkbox color=\"primary\" class=\"toolbar-menu-checkbox\" style=\"width: max-content;\"\r\n [formControlName]=\"column.field\" (change)=\"setColumnHideShow()\">{{column.header}}</mat-checkbox>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"toolbar-menu-container\" *ngIf=\"columnPinMenuCtrl\" (click)=\"$event.stopPropagation()\">\r\n <h4 class=\"column-headers\">Pin Columns</h4>\r\n <form class=\"example-form\">\r\n <mat-form-field appearance=\"fill\" style=\"width: -webkit-fill-available;\">\r\n <mat-label>Filter Columns</mat-label>\r\n <input matInput [(ngModel)]=\"showHideFilter\" (ngModelChange)=\"filterColumns($event)\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n </form>\r\n <div class=\"showHide-menu-columns-list\">\r\n <app-column-pinning [columns]=\"showHideColumnsArray\"></app-column-pinning>\r\n </div>\r\n </div>\r\n </mat-menu>\r\n\r\n <mat-progress-bar *ngIf=\"loadingIndicator\" mode=\"indeterminate\"></mat-progress-bar>\r\n <section id=\"tableContainer\" class=\"mat-table-ext-container\" (scroll)=\"onScroll($event)\"\r\n [style.height]=\"tableHeight ? tableHeight :'max-content'\">\r\n <table mat-table [id]=\"'matTableExt'+tableID\" [dataSource]=\"dataSource\" matSort cdkDropList\r\n cdkDropListOrientation=\"horizontal\" multiTemplateDataRows (cdkDropListDropped)=\"onDrop($event)\"\r\n (click)=\"saveCellEditing()\" [style.width]=\"scrollbarH?'max-content':'100%'\">\r\n <!-- Row selection column -->\r\n <ng-container matColumnDef=\"select\">\r\n <th mat-header-cell *matHeaderCellDef cdkDragLockAxis=\"x\" cdkDrag [cdkDragDisabled]=\"!dndColumns\">\r\n <mat-checkbox (change)=\"$event ? toggleAllRows() : null\"\r\n [checked]=\"selection.hasValue() && isAllSelected()\"\r\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\" [aria-label]=\"checkboxLabel()\">\r\n </mat-checkbox>\r\n </th>\r\n <td mat-cell *matCellDef=\"let row;let i = dataIndex\">\r\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? setSelectedRows(row,i) : null\"\r\n [checked]=\"selection.isSelected(row)\" [aria-label]=\"checkboxLabel(row)\">\r\n </mat-checkbox>\r\n </td>\r\n <ng-container *ngIf=\"showFooterRow\">\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n </ng-container>\r\n <!--dynamic columns are being generated here-->\r\n <div matColumnDef=\"{{column['field']}}\" [sticky]=\"column.pinned == 'left' ? true:false\"\r\n [stickyEnd]=\"column.pinned == 'right' ? true:false\" *ngFor=\"let column of columnsArray; let i = index\">\r\n <th mat-header-cell *matHeaderCellDef [style.width]=\"column.width\" [style.maxWidth]=\"column.maxWidth\"\r\n [style.minWidth]=\"column.minWidth\" cdkDragLockAxis=\"x\" cdkDrag [cdkDragDisabled]=\"!dndColumns\"\r\n [columnsResizable]=\"columnResizable\" [index]=\"i\">\r\n <span *ngIf=\"!headerTemplateRef\" matTooltip=\"{{column.headerTooltip?.value}}\"\r\n [matTooltipPosition]=\"column?.headerTooltip?.tooltipPosition!\" mat-sort-header\r\n [disabled]=\"!sorting || column.disabled === true\">{{column.header}}</span>\r\n <ng-container *ngIf=\"headerTemplateRef\" [ngTemplateOutlet]=\"headerTemplateRef\"\r\n [ngTemplateOutletContext]=\"{data:column}\"></ng-container>\r\n <ng-container *ngIf=\"column.headerTemplate\" [ngTemplateOutlet]=\"column.headerTemplate\"\r\n [ngTemplateOutletContext]=\"{data:column}\"></ng-container>\r\n </th>\r\n <td mat-cell *matCellDef=\"let row ;let i=dataIndex\">\r\n <div *ngIf=\"!row.editable && !cellEditing[i +'_'+column.field]\"\r\n (dblclick)=\"cellEditing[i +'_'+column.field] = inCellEditing;setCellData(row,i)\"\r\n matTooltip=\"{{column.cellTooltip?.value}}\"\r\n [matTooltipPosition]=\"column?.cellTooltip?.tooltipPosition!\">\r\n <span\r\n *ngIf=\"!cellTemplateRef && !column?.cellTemplate && !cellTemplateRefMap[column.field]\">{{row[column.field]}}</span>\r\n <ng-container *ngIf=\"cellTemplateRefMap[column.field]\"\r\n [ngTemplateOutlet]=\"cellTemplateRefMap[column.field]\"\r\n [ngTemplateOutletContext]=\"{row:row,column:column,index:i}\">\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"cellTemplateRef && column.cellTemplate && !cellTemplateRefMap[column.field]\"\r\n [ngTemplateOutlet]=\"column.cellTemplate\"\r\n [ngTemplateOutletContext]=\"{row:row,column:column,index:i}\">\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"!cellTemplateRef && column.cellTemplate && !cellTemplateRefMap[column.field]\"\r\n [ngTemplateOutlet]=\"column.cellTemplate\"\r\n [ngTemplateOutletContext]=\"{row:row,column:column,index:i}\">\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"cellTemplateRef && !column.cellTemplate && !cellTemplateRefMap[column.field]\"\r\n [ngTemplateOutlet]=\"cellTemplateRef\"\r\n [ngTemplateOutletContext]=\"{row:row,column:column,index:i}\">\r\n </ng-container>\r\n </div>\r\n <div *ngIf=\"row.editable || cellEditing[i +'_'+column.field]\" (click)=\"$event.stopPropagation()\">\r\n <ng-container *ngIf=\"inlineEditingTemplateRef && !cellEditing[i +'_'+column.field]\"\r\n [ngTemplateOutlet]=\"inlineEditingTemplateRef\"\r\n [ngTemplateOutletContext]=\"{data:getInlineEditingData(row,i,column)}\"></ng-container>\r\n <ng-container *ngIf=\"cellEditingTemplateRef && !(row.editable)\"\r\n [ngTemplateOutlet]=\"cellEditingTemplateRef\"\r\n [ngTemplateOutletContext]=\"{data:getInlineEditingData(row,i,column)}\"></ng-container>\r\n <ng-container *ngIf=\"!inlineEditingTemplateRef && (row.editable) && rowDataTemp['e'+i]\">\r\n <mat-form-field *ngIf=\"column.type == 'number'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <input matInput type=\"number\" [(ngModel)]=\"rowDataTemp['e'+i][column.field]\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <mat-form-field style=\"width: 100%;\" *ngIf=\"column.type == 'string'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <input matInput type=\"text\" [(ngModel)]=\"rowDataTemp['e'+i][column.field]\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <mat-form-field *ngIf=\"column.type == 'date'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <input matInput type=\"date\" [(ngModel)]=\"rowDataTemp['e'+i][column.field]\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <mat-form-field *ngIf=\"column.type == 'selection'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <mat-select [value]=\"rowDataTemp['e'+i][column.field]\"\r\n [(ngModel)]=\"rowDataTemp['e'+i][column.field]\">\r\n <mat-option *ngFor=\"let option of column.options\" [value]=\"option\">\r\n {{option}}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n <mat-checkbox (click)=\"$event.stopPropagation()\" *ngIf=\"column.type == 'boolean'\"\r\n color=\"primary\" [(ngModel)]=\"row[column.field]\"></mat-checkbox>\r\n </ng-container>\r\n <ng-container *ngIf=\"!cellEditingTemplateRef && cellEditing[i +'_'+column.field]\">\r\n <mat-form-field *ngIf=\"column.type == 'number'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <input matInput type=\"number\" [(ngModel)]=\"rowDataTemp['e'+i][column.field]\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <mat-form-field *ngIf=\"column.type == 'string'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <input matInput type=\"text\" [(ngModel)]=\"rowDataTemp['e'+i][column.field]\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <mat-form-field *ngIf=\"column.type == 'date'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <input matInput type=\"date\" [(ngModel)]=\"rowDataTemp['e'+i][column.field]\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <mat-form-field *ngIf=\"column.type == 'selection'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <mat-select [value]=\"rowDataTemp['e'+i][column.field]\"\r\n [(ngModel)]=\"rowDataTemp['e'+i][column.field]\">\r\n <mat-option *ngFor=\"let option of column.options\" [value]=\"option\">\r\n {{option}}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n <mat-checkbox (click)=\"$event.stopPropagation()\" *ngIf=\"column.type == 'boolean'\"\r\n color=\"primary\" [(ngModel)]=\"row[column.field]\"></mat-checkbox>\r\n </ng-container>\r\n </div>\r\n </td>\r\n <ng-container *ngIf=\"showFooterRow\">\r\n <td mat-footer-cell *matFooterCellDef> {{column.footerText}} </td>\r\n </ng-container>\r\n </div>\r\n <ng-container matColumnDef=\"edit\" stickyEnd=\"false\">\r\n <th mat-header-cell cdkDragLockAxis=\"x\" cdkDrag [cdkDragDisabled]=\"true\" *matHeaderCellDef\r\n class=\"action-column-cells\"> Edit </th>\r\n <td mat-cell *matCellDef=\"let row; let i = dataIndex\" class=\"inline-edit-column-cell\">\r\n <mat-icon class=\"edit-column-icons\" *ngIf=\"!row.editable && !row.editmodal\" aria-hidden=\"false\"\r\n (click)=\"enableInlineEditing(row,i)\" fontIcon=\"edit_note\">\r\n </mat-icon>\r\n <div class=\"inline-editing-controls\" *ngIf=\"row.editable && !row.editmodal\">\r\n <mat-icon class=\"edit-column-icons\" aria-hidden=\"false\" (click)=\"saveInlineEditing(row,i)\"\r\n fontIcon=\"done\"></mat-icon>\r\n <mat-icon class=\"edit-column-icons\" aria-hidden=\"false\" (click)=\"cancelInlineEditing(row,i)\"\r\n fontIcon=\"close\"></mat-icon>\r\n </div>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef> edit </td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"popup\" stickyEnd=\"false\">\r\n <th mat-header-cell cdkDragLockAxis=\"x\" cdkDrag [cdkDragDisabled]=\"true\" *matHeaderCellDef\r\n class=\"action-column-cells\"> Popup\r\n </th>\r\n <td mat-cell *matCellDef=\"let row; let i = index\">\r\n <mat-icon aria-hidden=\"false\" (click)=\"openEditingDialog(row)\" fontIcon=\"edit\">\r\n </mat-icon>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n\r\n <ng-container matColumnDef=\"delete\">\r\n <th mat-header-cell cdkDragLockAxis=\"x\" cdkDrag [cdkDragDisabled]=\"true\" *matHeaderCellDef\r\n class=\"action-column-cells\"> Delete\r\n </th>\r\n <td mat-cell *matCellDef=\"let row;let i=dataIndex\">\r\n <mat-icon (click)=\"deleteRow(row,i)\" aria-hidden=\"false\" aria-label=\"Example home icon\"\r\n fontIcon=\"delete\">\r\n </mat-icon>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <!-- Expanded Content Column - The detail row is made up of this one column that spans across all columns -->\r\n <ng-container *ngIf=\"expandRows\" matColumnDef=\"expandedDetail\">\r\n <td mat-cell *matCellDef=\"let element;let i=dataIndex \"\r\n [attr.colspan]=\"columnsToDisplayWithExpand.length\">\r\n <div class=\"example-element-detail\"\r\n [@detailExpand]=\"element == expandedElement ? 'expanded' : 'collapsed'\">\r\n <ng-container *ngIf=\"expansionTemplateRef\" [ngTemplateOutlet]=\"expansionTemplateRef\"\r\n [ngTemplateOutletContext]=\"{$explicit:element,row:element,index:i}\">\r\n </ng-container>\r\n </div>\r\n </td>\r\n </ng-container>\r\n <ng-container *ngFor=\"let ids of headersFiltersIds; let i=index\" [matColumnDef]=\"ids\">\r\n <th mat-header-cell *matHeaderCellDef>\r\n <div class=\"filters-container\" [class.animate]=\"toggleFilters\">\r\n <app-filter-columns-component [obj]=\"columnsArray[returnIndex(ids)]\"\r\n (filterOutput)=\"applyColumnFilter($event,columnsArray[returnIndex(ids)])\"></app-filter-columns-component>\r\n </div>\r\n </th>\r\n </ng-container>\r\n <tr mat-header-row *matHeaderRowDef=\" getDisplayedColumns(); sticky: stickyHeader\"></tr>\r\n <tr mat-row *matRowDef=\"let row; columns:getDisplayedColumns(); let i=dataIndex;\" class=\"data-row\"\r\n [ngClass]=\"{'data-row':expandRows,'stripedRows':(stripedRows && i % 2 == 1),'hoverClass':rowHover, 'hidden':hiddenCtrl.isSelected(row) && hideRows,'example-expanded-row':expandedElement === row}\"\r\n (click)=\"expandRow(row, row !== expandedElement,i)\">\r\n </tr>\r\n <tr style=\"height: 0px;\" mat-header-row class=\"no-default-height\" *matHeaderRowDef=\"headersFiltersIds\">\r\n </tr>\r\n <ng-container *ngIf=\"expandRows\">\r\n <tr style=\"height: 0px;\" mat-row *matRowDef=\"let row; columns: ['expandedDetail']\"\r\n [ngClass]=\"{'example-detail-row': (expandRows && row === expandedElement),'expand-row':row !== expandedElement}\">\r\n </tr>\r\n </ng-container>\r\n <ng-container *ngIf=\"showFooterRow\">\r\n <tr mat-footer-row *matFooterRowDef=\"getDisplayedColumns(); sticky: stickyFooter\"></tr>\r\n </ng-container>\r\n </table>\r\n </section>\r\n <mat-paginator *ngIf=\"showPaginator\" [pageSizeOptions]=\"pageSizeOptions\"\r\n [showFirstLastButtons]=\"showFirstLastButtons\">\r\n </mat-paginator>\r\n</div>", styles: ["table{min-width:100%}.mat-table-sticky-border-elem-right{border-left:1px solid #e0e0e0}.mat-table-sticky-border-elem-left{border-right:1px solid #e0e0e0}tr.example-detail-row{display:table-row!important}.example-element-detail{overflow:hidden;display:flex}.hidden{display:none}.stripedRows{background:#eaeaea!important}.hoverClass:hover{background:#dbdbdb!important}.filters-container{overflow:hidden;max-height:0px;transition:max-height .5s ease-in-out}.animate{max-height:50px!important}.resize-handle{display:inline-block;border-right:2px solid rgb(140,140,140);position:absolute;top:0;right:0;height:100%;cursor:col-resize;opacity:0}.resize-handle:hover{width:20px}table th:hover .resize-handle{opacity:1;transition:.3s ease-in-out}.mat-table.resizing{-webkit-user-select:none;user-select:none;cursor:col-resize}.mat-table .mat-header-cell{position:relative}.mat-table .mat-header-cell:not(:last-child) .resize-holder{cursor:col-resize;width:20px;height:100%;position:absolute;right:-10px;top:0;z-index:1}.toolbar-container{display:flex;padding:0 15px;gap:1rem;grid-auto-rows:10px;justify-content:flex-end;align-items:center}.mat-table-ext-container{width:100%;max-width:100%;overflow:auto}.column-headers{font-family:Roboto,Helvetica Neue,sans-serif}.example-spacer{flex:1 1 auto}.export-button .mat-button-wrapper{display:flex!important;width:8em;justify-content:space-around;align-items:center}.toolbar-menu-container{display:flex;flex-direction:column;margin:auto .8em;width:15em;height:20em}.toolbar-menu-item{display:flex;height:3em}.toolbar-menu-checkbox{margin-left:8%}.toolbar-menu-checkbox.mat-checkbox{width:max-content;display:flex;align-items:center}.hide-button .mat-button-wrapper,.pin-button .mat-button-wrapper{display:flex!important;width:5em;justify-content:space-around;align-items:center}.hide-button,.pin-button,.export-button{height:3em;border:2px solid currentColor!important}.showHide-menu-columns-list{height:10em;max-height:10em;overflow-y:auto}.mat-column-select{width:50px!important}.data-row td,.example-expanded-row td{border-bottom-width:0!important}.action-column-cells{width:40px;height:inherit}.inline-editing-controls{display:flex}.global-search-field{width:-webkit-fill-available}\n"], dependencies: [{ kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i7.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i7.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i7.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i7.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i7.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i7.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i7.MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "directive", type: i7.MatFooterRowDef, selector: "[matFooterRowDef]", inputs: ["matFooterRowDef", "matFooterRowDefSticky"] }, { kind: "directive", type: i7.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i7.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: i7.MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "component", type: i7.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i7.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i7.MatFooterRow, selector: "mat-footer-row, tr[mat-footer-row]", exportAs: ["matFooterRow"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i8.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i8.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: i9.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i10.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i11.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i12.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i12.MatLabel, selector: "mat-label" }, { kind: "directive", type: i13.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i14.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "directive", type: i14.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "component", type: i15.MatPaginator, selector: "mat-paginator", inputs: ["disabled"], exportAs: ["matPaginator"] }, { kind: "component", type: i16.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: i17.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "directive", type: i18.MatSort, selector: "[matSort]", inputs: ["matSortDisabled", "matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i18.MatSortHeader, selector: "[mat-sort-header]", inputs: ["disabled", "mat-sort-header", "arrowPosition", "start", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i19.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "directive", type: i20.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "directive", type: i21.ResizeColumnDirective, selector: "[columnsResizable]", inputs: ["columnsResizable", "index"] }, { kind: "component", type: i22.ColumnPinningComponent, selector: "app-column-pinning", inputs: ["columns"], outputs: ["columnsChanged"] }, { kind: "component", type: i23.FilterColumnsComponentComponent, selector: "app-filter-columns-component", inputs: ["obj"], outputs: ["filterOutput"] }], animations: [
896
- trigger('detailExpand', [
897
- state('collapsed', style({ height: '0px', minHeight: '0' })),
898
- state('expanded', style({ height: '*' })),
899
- transition('expanded <=> collapsed', animate('300ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
900
- ]),
901
- ], encapsulation: i0.ViewEncapsulation.None });
902
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: MatTableExtComponent, decorators: [{
903
- type: Component,
904
- args: [{ selector: 'mat-table-ext', encapsulation: ViewEncapsulation.None, animations: [
905
- trigger('detailExpand', [
906
- state('collapsed', style({ height: '0px', minHeight: '0' })),
907
- state('expanded', style({ height: '*' })),
908
- transition('expanded <=> collapsed', animate('300ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
909
- ]),
910
- ], template: "<div [style.width]=\"tableWidth\">\r\n <mat-form-field class=\"global-search-field\" appearance=\"fill\" *ngIf=\"globalSearch\">\r\n <mat-label>Search</mat-label>\r\n <input matInput [ngModel]=\"globalFilter\" (ngModelChange)=\"applyGlobalFilter($event)\" placeholder=\"Ex. Mia\" #input>\r\n </mat-form-field>\r\n <mat-toolbar class=\"toolbar-container\" *ngIf=\"showToolbar\" [style.height]=\"toolbarHeight?toolbarHeight:'50px'\">\r\n <span class=\"toolbar-title\" *ngIf=\"toolbarTitle\">{{toolbarTitle}}</span>\r\n <ng-container *ngIf=\"toolbarTemplateRef\" [ngTemplateOutlet]=\"toolbarTemplateRef\"></ng-container>\r\n <span class=\"example-spacer\"></span>\r\n <ng-container *ngIf=\"rowSelection || multiRowSelection\">\r\n <button class=\"hide-button\" mat-stroked-button color=\"primary\" (click)=\"hideSelectedRows()\">\r\n Hide Rows\r\n </button>\r\n <button class=\"hide-button\" mat-stroked-button color=\"primary\" (click)=\"showHiddenRows()\">\r\n Show All Rows\r\n </button>\r\n </ng-container>\r\n <button *ngIf=\"columnHidable\" class=\"hide-button\" mat-stroked-button color=\"primary\"\r\n (click)=\"openMenu('hideShow',$event)\" matTooltip=\"Column Visibility\" matTooltipPosition=\"above\">\r\n <mat-icon>visibility</mat-icon>\r\n </button>\r\n <button *ngIf=\"columnPinnable\" class=\"pin-button\" mat-stroked-button color=\"primary\"\r\n (click)=\"openMenu('columnPin',$event)\" matTooltip=\"Column Pinning\">\r\n <mat-icon svgIcon=\"pinIcon\"></mat-icon>\r\n </button>\r\n <button *ngIf=\"exportButtonEnable\" class=\"export-button\" mat-stroked-button color=\"primary\"\r\n (click)=\"openMenu('export',$event)\" matTooltip=\"Table Data Export\">\r\n <mat-icon>import_export</mat-icon> <span>Export</span>\r\n <mat-icon>expand_more</mat-icon>\r\n </button>\r\n <div style=\"visibility: hidden; position:fixed\" [matMenuTriggerFor]=\"menu\" [style.left.px]=\"menuX\"\r\n [style.top.px]=\"menuY\"></div>\r\n </mat-toolbar>\r\n <mat-menu #menu=\"matMenu\" (closed)=\"menuClosed()\" id=\"exportMenu\">\r\n <ng-container *ngIf=\"exportMenuCtrl\">\r\n <mat-option (click)=\"exportTable('xlsx')\">Export to Excel</mat-option>\r\n <mat-option (click)=\"exportTable('csv')\">Export to CSV</mat-option>\r\n </ng-container>\r\n </mat-menu>\r\n <div style=\"visibility: hidden; position:fixed\" #columnMenuTrigger=\"matMenuTrigger\" [matMenuTriggerFor]=\"columnMenu\"\r\n [style.left.px]=\"menuX\" [style.top.px]=\"menuY\">\r\n </div>\r\n <mat-menu #columnMenu=\"matMenu\" (closed)=\"resetMenuChecks()\">\r\n <div class=\"toolbar-menu-container\" *ngIf=\"hideShowMenuCtrl\" [formGroup]=\"hideShowMenuGroup\"\r\n (click)=\"$event.stopPropagation()\">\r\n <h4 class=\"column-headers\">Visible Columns</h4>\r\n <mat-form-field appearance=\"fill\" style=\"width: -webkit-fill-available;\">\r\n <mat-label>Filter Columns</mat-label>\r\n <input matInput [(ngModel)]=\"showHideFilter\" (ngModelChange)=\"filterColumns($event)\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <div class=\"showHide-menu-columns-list\">\r\n <div class=\"toolbar-menu-item\" *ngFor=\"let column of showHideColumnsArray\">\r\n <mat-checkbox color=\"primary\" class=\"toolbar-menu-checkbox\" style=\"width: max-content;\"\r\n [formControlName]=\"column.field\" (change)=\"setColumnHideShow()\">{{column.header}}</mat-checkbox>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"toolbar-menu-container\" *ngIf=\"columnPinMenuCtrl\" (click)=\"$event.stopPropagation()\">\r\n <h4 class=\"column-headers\">Pin Columns</h4>\r\n <form class=\"example-form\">\r\n <mat-form-field appearance=\"fill\" style=\"width: -webkit-fill-available;\">\r\n <mat-label>Filter Columns</mat-label>\r\n <input matInput [(ngModel)]=\"showHideFilter\" (ngModelChange)=\"filterColumns($event)\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n </form>\r\n <div class=\"showHide-menu-columns-list\">\r\n <app-column-pinning [columns]=\"showHideColumnsArray\"></app-column-pinning>\r\n </div>\r\n </div>\r\n </mat-menu>\r\n\r\n <mat-progress-bar *ngIf=\"loadingIndicator\" mode=\"indeterminate\"></mat-progress-bar>\r\n <section id=\"tableContainer\" class=\"mat-table-ext-container\" (scroll)=\"onScroll($event)\"\r\n [style.height]=\"tableHeight ? tableHeight :'max-content'\">\r\n <table mat-table [id]=\"'matTableExt'+tableID\" [dataSource]=\"dataSource\" matSort cdkDropList\r\n cdkDropListOrientation=\"horizontal\" multiTemplateDataRows (cdkDropListDropped)=\"onDrop($event)\"\r\n (click)=\"saveCellEditing()\" [style.width]=\"scrollbarH?'max-content':'100%'\">\r\n <!-- Row selection column -->\r\n <ng-container matColumnDef=\"select\">\r\n <th mat-header-cell *matHeaderCellDef cdkDragLockAxis=\"x\" cdkDrag [cdkDragDisabled]=\"!dndColumns\">\r\n <mat-checkbox (change)=\"$event ? toggleAllRows() : null\"\r\n [checked]=\"selection.hasValue() && isAllSelected()\"\r\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\" [aria-label]=\"checkboxLabel()\">\r\n </mat-checkbox>\r\n </th>\r\n <td mat-cell *matCellDef=\"let row;let i = dataIndex\">\r\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? setSelectedRows(row,i) : null\"\r\n [checked]=\"selection.isSelected(row)\" [aria-label]=\"checkboxLabel(row)\">\r\n </mat-checkbox>\r\n </td>\r\n <ng-container *ngIf=\"showFooterRow\">\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n </ng-container>\r\n <!--dynamic columns are being generated here-->\r\n <div matColumnDef=\"{{column['field']}}\" [sticky]=\"column.pinned == 'left' ? true:false\"\r\n [stickyEnd]=\"column.pinned == 'right' ? true:false\" *ngFor=\"let column of columnsArray; let i = index\">\r\n <th mat-header-cell *matHeaderCellDef [style.width]=\"column.width\" [style.maxWidth]=\"column.maxWidth\"\r\n [style.minWidth]=\"column.minWidth\" cdkDragLockAxis=\"x\" cdkDrag [cdkDragDisabled]=\"!dndColumns\"\r\n [columnsResizable]=\"columnResizable\" [index]=\"i\">\r\n <span *ngIf=\"!headerTemplateRef\" matTooltip=\"{{column.headerTooltip?.value}}\"\r\n [matTooltipPosition]=\"column?.headerTooltip?.tooltipPosition!\" mat-sort-header\r\n [disabled]=\"!sorting || column.disabled === true\">{{column.header}}</span>\r\n <ng-container *ngIf=\"headerTemplateRef\" [ngTemplateOutlet]=\"headerTemplateRef\"\r\n [ngTemplateOutletContext]=\"{data:column}\"></ng-container>\r\n <ng-container *ngIf=\"column.headerTemplate\" [ngTemplateOutlet]=\"column.headerTemplate\"\r\n [ngTemplateOutletContext]=\"{data:column}\"></ng-container>\r\n </th>\r\n <td mat-cell *matCellDef=\"let row ;let i=dataIndex\">\r\n <div *ngIf=\"!row.editable && !cellEditing[i +'_'+column.field]\"\r\n (dblclick)=\"cellEditing[i +'_'+column.field] = inCellEditing;setCellData(row,i)\"\r\n matTooltip=\"{{column.cellTooltip?.value}}\"\r\n [matTooltipPosition]=\"column?.cellTooltip?.tooltipPosition!\">\r\n <span\r\n *ngIf=\"!cellTemplateRef && !column?.cellTemplate && !cellTemplateRefMap[column.field]\">{{row[column.field]}}</span>\r\n <ng-container *ngIf=\"cellTemplateRefMap[column.field]\"\r\n [ngTemplateOutlet]=\"cellTemplateRefMap[column.field]\"\r\n [ngTemplateOutletContext]=\"{row:row,column:column,index:i}\">\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"cellTemplateRef && column.cellTemplate && !cellTemplateRefMap[column.field]\"\r\n [ngTemplateOutlet]=\"column.cellTemplate\"\r\n [ngTemplateOutletContext]=\"{row:row,column:column,index:i}\">\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"!cellTemplateRef && column.cellTemplate && !cellTemplateRefMap[column.field]\"\r\n [ngTemplateOutlet]=\"column.cellTemplate\"\r\n [ngTemplateOutletContext]=\"{row:row,column:column,index:i}\">\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"cellTemplateRef && !column.cellTemplate && !cellTemplateRefMap[column.field]\"\r\n [ngTemplateOutlet]=\"cellTemplateRef\"\r\n [ngTemplateOutletContext]=\"{row:row,column:column,index:i}\">\r\n </ng-container>\r\n </div>\r\n <div *ngIf=\"row.editable || cellEditing[i +'_'+column.field]\" (click)=\"$event.stopPropagation()\">\r\n <ng-container *ngIf=\"inlineEditingTemplateRef && !cellEditing[i +'_'+column.field]\"\r\n [ngTemplateOutlet]=\"inlineEditingTemplateRef\"\r\n [ngTemplateOutletContext]=\"{data:getInlineEditingData(row,i,column)}\"></ng-container>\r\n <ng-container *ngIf=\"cellEditingTemplateRef && !(row.editable)\"\r\n [ngTemplateOutlet]=\"cellEditingTemplateRef\"\r\n [ngTemplateOutletContext]=\"{data:getInlineEditingData(row,i,column)}\"></ng-container>\r\n <ng-container *ngIf=\"!inlineEditingTemplateRef && (row.editable) && rowDataTemp['e'+i]\">\r\n <mat-form-field *ngIf=\"column.type == 'number'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <input matInput type=\"number\" [(ngModel)]=\"rowDataTemp['e'+i][column.field]\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <mat-form-field style=\"width: 100%;\" *ngIf=\"column.type == 'string'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <input matInput type=\"text\" [(ngModel)]=\"rowDataTemp['e'+i][column.field]\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <mat-form-field *ngIf=\"column.type == 'date'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <input matInput type=\"date\" [(ngModel)]=\"rowDataTemp['e'+i][column.field]\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <mat-form-field *ngIf=\"column.type == 'selection'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <mat-select [value]=\"rowDataTemp['e'+i][column.field]\"\r\n [(ngModel)]=\"rowDataTemp['e'+i][column.field]\">\r\n <mat-option *ngFor=\"let option of column.options\" [value]=\"option\">\r\n {{option}}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n <mat-checkbox (click)=\"$event.stopPropagation()\" *ngIf=\"column.type == 'boolean'\"\r\n color=\"primary\" [(ngModel)]=\"row[column.field]\"></mat-checkbox>\r\n </ng-container>\r\n <ng-container *ngIf=\"!cellEditingTemplateRef && cellEditing[i +'_'+column.field]\">\r\n <mat-form-field *ngIf=\"column.type == 'number'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <input matInput type=\"number\" [(ngModel)]=\"rowDataTemp['e'+i][column.field]\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <mat-form-field *ngIf=\"column.type == 'string'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <input matInput type=\"text\" [(ngModel)]=\"rowDataTemp['e'+i][column.field]\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <mat-form-field *ngIf=\"column.type == 'date'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <input matInput type=\"date\" [(ngModel)]=\"rowDataTemp['e'+i][column.field]\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </mat-form-field>\r\n <mat-form-field *ngIf=\"column.type == 'selection'\" appearance=\"outline\"\r\n class=\"inline-editing-field\">\r\n <mat-select [value]=\"rowDataTemp['e'+i][column.field]\"\r\n [(ngModel)]=\"rowDataTemp['e'+i][column.field]\">\r\n <mat-option *ngFor=\"let option of column.options\" [value]=\"option\">\r\n {{option}}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n <mat-checkbox (click)=\"$event.stopPropagation()\" *ngIf=\"column.type == 'boolean'\"\r\n color=\"primary\" [(ngModel)]=\"row[column.field]\"></mat-checkbox>\r\n </ng-container>\r\n </div>\r\n </td>\r\n <ng-container *ngIf=\"showFooterRow\">\r\n <td mat-footer-cell *matFooterCellDef> {{column.footerText}} </td>\r\n </ng-container>\r\n </div>\r\n <ng-container matColumnDef=\"edit\" stickyEnd=\"false\">\r\n <th mat-header-cell cdkDragLockAxis=\"x\" cdkDrag [cdkDragDisabled]=\"true\" *matHeaderCellDef\r\n class=\"action-column-cells\"> Edit </th>\r\n <td mat-cell *matCellDef=\"let row; let i = dataIndex\" class=\"inline-edit-column-cell\">\r\n <mat-icon class=\"edit-column-icons\" *ngIf=\"!row.editable && !row.editmodal\" aria-hidden=\"false\"\r\n (click)=\"enableInlineEditing(row,i)\" fontIcon=\"edit_note\">\r\n </mat-icon>\r\n <div class=\"inline-editing-controls\" *ngIf=\"row.editable && !row.editmodal\">\r\n <mat-icon class=\"edit-column-icons\" aria-hidden=\"false\" (click)=\"saveInlineEditing(row,i)\"\r\n fontIcon=\"done\"></mat-icon>\r\n <mat-icon class=\"edit-column-icons\" aria-hidden=\"false\" (click)=\"cancelInlineEditing(row,i)\"\r\n fontIcon=\"close\"></mat-icon>\r\n </div>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef> edit </td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"popup\" stickyEnd=\"false\">\r\n <th mat-header-cell cdkDragLockAxis=\"x\" cdkDrag [cdkDragDisabled]=\"true\" *matHeaderCellDef\r\n class=\"action-column-cells\"> Popup\r\n </th>\r\n <td mat-cell *matCellDef=\"let row; let i = index\">\r\n <mat-icon aria-hidden=\"false\" (click)=\"openEditingDialog(row)\" fontIcon=\"edit\">\r\n </mat-icon>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n\r\n <ng-container matColumnDef=\"delete\">\r\n <th mat-header-cell cdkDragLockAxis=\"x\" cdkDrag [cdkDragDisabled]=\"true\" *matHeaderCellDef\r\n class=\"action-column-cells\"> Delete\r\n </th>\r\n <td mat-cell *matCellDef=\"let row;let i=dataIndex\">\r\n <mat-icon (click)=\"deleteRow(row,i)\" aria-hidden=\"false\" aria-label=\"Example home icon\"\r\n fontIcon=\"delete\">\r\n </mat-icon>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <!-- Expanded Content Column - The detail row is made up of this one column that spans across all columns -->\r\n <ng-container *ngIf=\"expandRows\" matColumnDef=\"expandedDetail\">\r\n <td mat-cell *matCellDef=\"let element;let i=dataIndex \"\r\n [attr.colspan]=\"columnsToDisplayWithExpand.length\">\r\n <div class=\"example-element-detail\"\r\n [@detailExpand]=\"element == expandedElement ? 'expanded' : 'collapsed'\">\r\n <ng-container *ngIf=\"expansionTemplateRef\" [ngTemplateOutlet]=\"expansionTemplateRef\"\r\n [ngTemplateOutletContext]=\"{$explicit:element,row:element,index:i}\">\r\n </ng-container>\r\n </div>\r\n </td>\r\n </ng-container>\r\n <ng-container *ngFor=\"let ids of headersFiltersIds; let i=index\" [matColumnDef]=\"ids\">\r\n <th mat-header-cell *matHeaderCellDef>\r\n <div class=\"filters-container\" [class.animate]=\"toggleFilters\">\r\n <app-filter-columns-component [obj]=\"columnsArray[returnIndex(ids)]\"\r\n (filterOutput)=\"applyColumnFilter($event,columnsArray[returnIndex(ids)])\"></app-filter-columns-component>\r\n </div>\r\n </th>\r\n </ng-container>\r\n <tr mat-header-row *matHeaderRowDef=\" getDisplayedColumns(); sticky: stickyHeader\"></tr>\r\n <tr mat-row *matRowDef=\"let row; columns:getDisplayedColumns(); let i=dataIndex;\" class=\"data-row\"\r\n [ngClass]=\"{'data-row':expandRows,'stripedRows':(stripedRows && i % 2 == 1),'hoverClass':rowHover, 'hidden':hiddenCtrl.isSelected(row) && hideRows,'example-expanded-row':expandedElement === row}\"\r\n (click)=\"expandRow(row, row !== expandedElement,i)\">\r\n </tr>\r\n <tr style=\"height: 0px;\" mat-header-row class=\"no-default-height\" *matHeaderRowDef=\"headersFiltersIds\">\r\n </tr>\r\n <ng-container *ngIf=\"expandRows\">\r\n <tr style=\"height: 0px;\" mat-row *matRowDef=\"let row; columns: ['expandedDetail']\"\r\n [ngClass]=\"{'example-detail-row': (expandRows && row === expandedElement),'expand-row':row !== expandedElement}\">\r\n </tr>\r\n </ng-container>\r\n <ng-container *ngIf=\"showFooterRow\">\r\n <tr mat-footer-row *matFooterRowDef=\"getDisplayedColumns(); sticky: stickyFooter\"></tr>\r\n </ng-container>\r\n </table>\r\n </section>\r\n <mat-paginator *ngIf=\"showPaginator\" [pageSizeOptions]=\"pageSizeOptions\"\r\n [showFirstLastButtons]=\"showFirstLastButtons\">\r\n </mat-paginator>\r\n</div>", styles: ["table{min-width:100%}.mat-table-sticky-border-elem-right{border-left:1px solid #e0e0e0}.mat-table-sticky-border-elem-left{border-right:1px solid #e0e0e0}tr.example-detail-row{display:table-row!important}.example-element-detail{overflow:hidden;display:flex}.hidden{display:none}.stripedRows{background:#eaeaea!important}.hoverClass:hover{background:#dbdbdb!important}.filters-container{overflow:hidden;max-height:0px;transition:max-height .5s ease-in-out}.animate{max-height:50px!important}.resize-handle{display:inline-block;border-right:2px solid rgb(140,140,140);position:absolute;top:0;right:0;height:100%;cursor:col-resize;opacity:0}.resize-handle:hover{width:20px}table th:hover .resize-handle{opacity:1;transition:.3s ease-in-out}.mat-table.resizing{-webkit-user-select:none;user-select:none;cursor:col-resize}.mat-table .mat-header-cell{position:relative}.mat-table .mat-header-cell:not(:last-child) .resize-holder{cursor:col-resize;width:20px;height:100%;position:absolute;right:-10px;top:0;z-index:1}.toolbar-container{display:flex;padding:0 15px;gap:1rem;grid-auto-rows:10px;justify-content:flex-end;align-items:center}.mat-table-ext-container{width:100%;max-width:100%;overflow:auto}.column-headers{font-family:Roboto,Helvetica Neue,sans-serif}.example-spacer{flex:1 1 auto}.export-button .mat-button-wrapper{display:flex!important;width:8em;justify-content:space-around;align-items:center}.toolbar-menu-container{display:flex;flex-direction:column;margin:auto .8em;width:15em;height:20em}.toolbar-menu-item{display:flex;height:3em}.toolbar-menu-checkbox{margin-left:8%}.toolbar-menu-checkbox.mat-checkbox{width:max-content;display:flex;align-items:center}.hide-button .mat-button-wrapper,.pin-button .mat-button-wrapper{display:flex!important;width:5em;justify-content:space-around;align-items:center}.hide-button,.pin-button,.export-button{height:3em;border:2px solid currentColor!important}.showHide-menu-columns-list{height:10em;max-height:10em;overflow-y:auto}.mat-column-select{width:50px!important}.data-row td,.example-expanded-row td{border-bottom-width:0!important}.action-column-cells{width:40px;height:inherit}.inline-editing-controls{display:flex}.global-search-field{width:-webkit-fill-available}\n"] }]
911
- }], ctorParameters: function () { return [{ type: i1.MatDialog }, { type: i2.MatTableExtService }, { type: i3.FormBuilder }, { type: i4.DomSanitizer }, { type: i5.MatIconRegistry }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { menuTrigger: [{
912
- type: ViewChild,
913
- args: [MatMenuTrigger]
914
- }], columnMenuTrigger: [{
915
- type: ViewChild,
916
- args: ['columnMenuTrigger']
917
- }], paginator: [{
918
- type: ViewChild,
919
- args: [MatPaginator]
920
- }], sort: [{
921
- type: ViewChild,
922
- args: [MatSort]
923
- }], dataSource: [{
924
- type: Input
925
- }], columns: [{
926
- type: Input
927
- }], columnResizable: [{
928
- type: Input
929
- }], stripedRows: [{
930
- type: Input
931
- }], rowHover: [{
932
- type: Input
933
- }], inlineRowEditing: [{
934
- type: Input
935
- }], inCellEditing: [{
936
- type: Input
937
- }], popupRowEditing: [{
938
- type: Input
939
- }], enableDelete: [{
940
- type: Input
941
- }], rowSelection: [{
942
- type: Input
943
- }], multiRowSelection: [{
944
- type: Input
945
- }], stickyFooter: [{
946
- type: Input
947
- }], stickyHeader: [{
948
- type: Input
949
- }], showFooterRow: [{
950
- type: Input
951
- }], columnFilter: [{
952
- type: Input
953
- }], loadingIndicator: [{
954
- type: Input
955
- }], sorting: [{
956
- type: Input
957
- }], showToolbar: [{
958
- type: Input
959
- }], toolbarTitle: [{
960
- type: Input
961
- }], tableHeight: [{
962
- type: Input
963
- }], toolbarHeight: [{
964
- type: Input
965
- }], tableWidth: [{
966
- type: Input
967
- }], scrollbarH: [{
968
- type: Input
969
- }], toolbarTemplate: [{
970
- type: Input
971
- }], columnHidable: [{
972
- type: Input
973
- }], columnPinnable: [{
974
- type: Input
975
- }], globalSearch: [{
976
- type: Input
977
- }], expandRows: [{
978
- type: Input
979
- }], dndColumns: [{
980
- type: Input
981
- }], showPaginator: [{
982
- type: Input
983
- }], showFirstLastButtons: [{
984
- type: Input
985
- }], exportButtonEnable: [{
986
- type: Input
987
- }], pageSizeOptions: [{
988
- type: Input
989
- }], toolbarTemplateRef: [{
990
- type: Input
991
- }], headerTemplateRef: [{
992
- type: Input
993
- }], cellTemplateRef: [{
994
- type: Input
995
- }], expansionTemplateRef: [{
996
- type: Input
997
- }], popupEditingTemplateRef: [{
998
- type: Input
999
- }], inlineEditingTemplateRef: [{
1000
- type: Input
1001
- }], cellEditingTemplateRef: [{
1002
- type: Input
1003
- }], cellTemplateRefMap: [{
1004
- type: Input
1005
- }], inlineChange: [{
1006
- type: Output
1007
- }], cellChange: [{
1008
- type: Output
1009
- }], popupChange: [{
1010
- type: Output
1011
- }], rowDeleted: [{
1012
- type: Output
1013
- }], scroll: [{
1014
- type: Output
1015
- }], selectionChanged: [{
1016
- type: Output
1017
- }], expansionChange: [{
1018
- type: Output
1019
- }] } });
1020
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0LXRhYmxlLWV4dC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9tYXQtdGFibGUtZXh0L3NyYy9saWIvbWF0LXRhYmxlLWV4dC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9tYXQtdGFibGUtZXh0L3NyYy9saWIvbWF0LXRhYmxlLWV4dC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsT0FBTyxFQUNQLEtBQUssRUFDTCxLQUFLLEVBQ0wsVUFBVSxFQUNWLE9BQU8sR0FDUixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMxRCxPQUFPLEVBQWUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdEUsT0FBTyxFQUdMLFlBQVksRUFDWixNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUNMLFNBQVMsRUFDVCxLQUFLLEVBS0wsU0FBUyxFQUNULGlCQUFpQixHQUNsQixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQWEsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDdEUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3hELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDakQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDN0QsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sNkNBQTZDLENBQUM7QUFnQi9FLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBaUI3QixNQUFNLE9BQU8sb0JBQW9CO0lBaUgvQixZQUNTLE1B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S0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDRyxvQkFBb0I7c0JBQTVCLEtBQUs7Z0JBQ0csa0JBQWtCO3NCQUExQixLQUFLO2dCQUNHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBQ0csa0JBQWtCO3NCQUExQixLQUFLO2dCQUNHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLG9CQUFvQjtzQkFBNUIsS0FBSztnQkFDRyx1QkFBdUI7c0JBQS9CLEtBQUs7Z0JBQ0csd0JBQXdCO3NCQUFoQyxLQUFLO2dCQUNHLHNCQUFzQjtzQkFBOUIsS0FBSztnQkFDRyxrQkFBa0I7c0JBQTFCLEtBQUs7Z0JBR0ksWUFBWTtzQkFBckIsTUFBTTtnQkFDRyxVQUFVO3NCQUFuQixNQUFNO2dCQUNHLFdBQVc7c0JBQXBCLE1BQU07Z0JBQ0csVUFBVTtzQkFBbkIsTUFBTTtnQkFDRyxNQUFNO3NCQUFmLE1BQU07Z0JBQ0csZ0JBQWdCO3NCQUF6QixNQUFNO2dCQUVHLGVBQWU7c0JBQXhCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIGFuaW1hdGUsXHJcbiAgc3RhdGUsXHJcbiAgc3R5bGUsXHJcbiAgdHJhbnNpdGlvbixcclxuICB0cmlnZ2VyLFxyXG59IGZyb20gJ0Bhbmd1bGFyL2FuaW1hdGlvbnMnO1xyXG5pbXBvcnQgeyBTZWxlY3Rpb25Nb2RlbCB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9jb2xsZWN0aW9ucyc7XHJcbmltcG9ydCB7IENka0RyYWdEcm9wLCBtb3ZlSXRlbUluQXJyYXkgfSBmcm9tICdAYW5ndWxhci9jZGsvZHJhZy1kcm9wJztcclxuaW1wb3J0IHtcclxuICBBZnRlclZpZXdJbml0LFxyXG4gIENoYW5nZURldGVjdG9yUmVmLFxyXG4gIEV2ZW50RW1pdHRlcixcclxuICBPdXRwdXQsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7XHJcbiAgQ29tcG9uZW50LFxyXG4gIElucHV0LFxyXG4gIE9uQ2hhbmdlcyxcclxuICBPbkluaXQsXHJcbiAgU2ltcGxlQ2hhbmdlcyxcclxuICBUZW1wbGF0ZVJlZixcclxuICBWaWV3Q2hpbGQsXHJcbiAgVmlld0VuY2Fwc3VsYXRpb24sXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEZvcm1CdWlsZGVyLCBGb3JtR3JvdXAgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IE1hdERpYWxvZywgTWF0RGlhbG9nQ29uZmlnIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcclxuaW1wb3J0IHsgTWF0TWVudVRyaWdnZXIgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9tZW51JztcclxuaW1wb3J0IHsgTWF0UGFnaW5hdG9yIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvcGFnaW5hdG9yJztcclxuaW1wb3J0IHsgTWF0U29ydCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3NvcnQnO1xyXG5pbXBvcnQgeyBNYXRUYWJsZURhdGFTb3VyY2UgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC90YWJsZSc7XHJcbmltcG9ydCB7IEVkaXRpbmdDb21wb25lbnQgfSBmcm9tICcuLi9saWIvY29tcG9uZW50cy9lZGl0aW5nL2VkaXRpbmcuY29tcG9uZW50JztcclxuaW1wb3J0IHtcclxuICBSb3dDaGFuZ2UsXHJcbiAgRGlzcGxheUNvbHVtbixcclxuICBNVEV4Q29sdW1uLFxyXG4gIE1URXhDb2x1bW5QaW5PcHRpb24sXHJcbiAgUm93U2VsZWN0aW9uQ2hhbmdlLFxyXG4gIENlbGxUZW1wbGF0ZVJlZk1hcCxcclxuICBFeHBhbnNpb25DaGFuZ2UsXHJcbiAgRmlsdGVyU2VhcmNoVmFsdWUsXHJcbiAgTVRFeFJvdyxcclxuICBDb2x1bW5WaXNpYmlsaXR5LFxyXG59IGZyb20gJy4uL2xpYi9tb2RlbHMvdGFibGVFeHRNb2RlbHMnO1xyXG5pbXBvcnQgeyBNYXRUYWJsZUV4dFNlcnZpY2UgfSBmcm9tICcuLi9saWIvbWF0LXRhYmxlLWV4dC5zZXJ2aWNlJztcclxuaW1wb3J0IHsgRG9tU2FuaXRpemVyIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XHJcbmltcG9ydCB7IE1hdEljb25SZWdpc3RyeSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2ljb24nO1xyXG5pbXBvcnQgKiBhcyBYTFNYIGZyb20gJ3hsc3gnO1xyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ21hdC10YWJsZS1leHQnLFxyXG4gIHRlbXBsYXRlVXJsOiAnbWF0LXRhYmxlLWV4dC5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJ21hdC10YWJsZS1leHQuc2NzcyddLFxyXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXHJcbiAgYW5pbWF0aW9uczogW1xyXG4gICAgdHJpZ2dlcignZGV0YWlsRXhwYW5kJywgW1xyXG4gICAgICBzdGF0ZSgnY29sbGFwc2VkJywgc3R5bGUoeyBoZWlnaHQ6ICcwcHgnLCBtaW5IZWlnaHQ6ICcwJyB9KSksXHJcbiAgICAgIHN0YXRlKCdleHBhbmRlZCcsIHN0eWxlKHsgaGVpZ2h0OiAnKicgfSkpLFxyXG4gICAgICB0cmFuc2l0aW9uKFxyXG4gICAgICAgICdleHBhbmRlZCA8PT4gY29sbGFwc2VkJyxcclxuICAgICAgICBhbmltYXRlKCczMDBtcyBjdWJpYy1iZXppZXIoMC40LCAwLjAsIDAuMiwgMSknKVxyXG4gICAgICApLFxyXG4gICAgXSksXHJcbiAgXSxcclxufSlcclxuZXhwb3J0IGNsYXNzIE1hdFRhYmxlRXh0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIEFmdGVyVmlld0luaXQge1xyXG4gIEBWaWV3Q2hpbGQoTWF0TWVudVRyaWdnZXIpIG1lbnVUcmlnZ2VyITogTWF0TWVudVRyaWdnZXI7XHJcbiAgQFZpZXdDaGlsZCgnY29sdW1uTWVudVRyaWdnZXInKSBjb2x1bW5NZW51VHJpZ2dlciE6IE1hdE1lbnVUcmlnZ2VyO1xyXG4gIEBWaWV3Q2hpbGQoTWF0UGFnaW5hdG9yKSBwYWdpbmF0b3IhOiBNYXRQYWdpbmF0b3I7XHJcbiAgQFZpZXdDaGlsZChNYXRTb3J0KSBzb3J0ITogTWF0U29ydDtcclxuXHJcbiAgLy8gVGFibGUgaW5wdXRzXHJcbiAgQElucHV0KCkgZGF0YVNvdXJjZSE6IE1hdFRhYmxlRGF0YVNvdXJjZTxhbnk+O1xyXG4gIEBJbnB1dCgpIGNvbHVtbnM6IE1URXhDb2x1bW5bXSA9IFtdO1xyXG4gIEBJbnB1dCgpIGNvbHVtblJlc2l6YWJsZTogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIHN0cmlwZWRSb3dzOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgcm93SG92ZXI6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSBpbmxpbmVSb3dFZGl0aW5nOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgaW5DZWxsRWRpdGluZzogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIHBvcHVwUm93RWRpdGluZzogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIGVuYWJsZURlbGV0ZTogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIHJvd1NlbGVjdGlvbjogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIG11bHRpUm93U2VsZWN0aW9uOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgc3RpY2t5Rm9vdGVyOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgc3RpY2t5SGVhZGVyOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgc2hvd0Zvb3RlclJvdzogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIGNvbHVtbkZpbHRlcjogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIGxvYWRpbmdJbmRpY2F0b3I6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSBzb3J0aW5nOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgc2hvd1Rvb2xiYXI6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSB0b29sYmFyVGl0bGU6IHN0cmluZyA9ICcnO1xyXG4gIEBJbnB1dCgpIHRhYmxlSGVpZ2h0OiBzdHJpbmcgPSAnJztcclxuICBASW5wdXQoKSB0b29sYmFySGVpZ2h0OiBzdHJpbmcgPSAnNTBweCc7XHJcbiAgQElucHV0KCkgdGFibGVXaWR0aDogc3RyaW5nID0gJzEwMCUnO1xyXG4gIEBJbnB1dCgpIHNjcm9sbGJhckg6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSB0b29sYmFyVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT4gfCB1bmRlZmluZWQ7XHJcbiAgQElucHV0KCkgY29sdW1uSGlkYWJsZTogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIGNvbHVtblBpbm5hYmxlOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgZ2xvYmFsU2VhcmNoOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgZXhwYW5kUm93czogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIGRuZENvbHVtbnM6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSBzaG93UGFnaW5hdG9yOiBib29sZWFuID0gdHJ1ZTtcclxuICBASW5wdXQoKSBzaG93Rmlyc3RMYXN0QnV0dG9uczogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIGV4cG9ydEJ1dHRvbkVuYWJsZTogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIHBhZ2VTaXplT3B0aW9uczogbnVtYmVyW10gPSBbMTAsIDUwLCAxMDBdO1xyXG4gIEBJbnB1dCgpIHRvb2xiYXJUZW1wbGF0ZVJlZiE6IFRlbXBsYXRlUmVmPGFueT4gfCB1bmRlZmluZWQ7XHJcbiAgQElucHV0KCkgaGVhZGVyVGVtcGxhdGVSZWYhOiBUZW1wbGF0ZVJlZjxhbnk+IHwgdW5kZWZpbmVkO1xyXG4gIEBJbnB1dCgpIGNlbGxUZW1wbGF0ZVJlZiE6IFRlbXBsYXRlUmVmPGFueT4gfCB1bmRlZmluZWQ7XHJcbiAgQElucHV0KCkgZXhwYW5zaW9uVGVtcGxhdGVSZWYhOiBUZW1wbGF0ZVJlZjxhbnk+IHwgdW5kZWZpbmVkO1xyXG4gIEBJbnB1dCgpIHBvcHVwRWRpdGluZ1RlbXBsYXRlUmVmITogVGVtcGxhdGVSZWY8YW55PiB8IHVuZGVmaW5lZDtcclxuICBASW5wdXQoKSBpbmxpbmVFZGl0aW5nVGVtcGxhdGVSZWYhOiBUZW1wbGF0ZVJlZjxhbnk+IHwgdW5kZWZpbmVkO1xyXG4gIEBJbnB1dCgpIGNlbGxFZGl0aW5nVGVtcGxhdGVSZWYhOiBUZW1wbGF0ZVJlZjxhbnk+IHwgdW5kZWZpbmVkO1xyXG4gIEBJbnB1dCgpIGNlbGxUZW1wbGF0ZVJlZk1hcDogQ2VsbFRlbXBsYXRlUmVmTWFwID0ge307XHJcblxyXG4gIC8vIFRhYmxlIG91dHB1dHNcclxuICBAT3V0cHV0KCkgaW5saW5lQ2hhbmdlOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8Um93Q2hhbmdlPigpO1xyXG4gIEBPdXRwdXQoKSBjZWxsQ2hhbmdlOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8Um93Q2hhbmdlPigpO1xyXG4gIEBPdXRwdXQoKSBwb3B1cENoYW5nZTogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPFJvd0NoYW5nZT4oKTtcclxuICBAT3V0cHV0KCkgcm93RGVsZXRlZDogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuICBAT3V0cHV0KCkgc2Nyb2xsOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xyXG4gIEBPdXRwdXQoKSBzZWxlY3Rpb25DaGFuZ2VkOiBFdmVudEVtaXR0ZXI8Um93U2VsZWN0aW9uQ2hhbmdlPiA9XHJcbiAgICBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuICBAT3V0cHV0KCkgZXhwYW5zaW9uQ2hhbmdlOiBFdmVudEVtaXR0ZXI8RXhwYW5zaW9uQ2hhbmdlPiA9XHJcbiAgICBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuICB0YWJsZUlEID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XHJcbiAgY29sdW1uUGlubmluZ09wdGlvbnM6IE1URXhDb2x1bW5QaW5PcHRpb25bXSA9IFtdO1xyXG4gIGV4cG9ydE1lbnVDdHJsOiBib29sZWFuID0gZmFsc2U7XHJcbiAgY29sdW1uUGluTWVudUN0cmw6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBoaWRlU2hvd01lbnVDdHJsOiBib29sZWFuID0gZmFsc2U7XHJcbiAgY29sdW1uRmlsdGVyQnlTZWxlY3Rpb246IGFueSA9IGZhbHNlO1xyXG4gIHJvd0RhdGFUZW1wOiBhbnkgPSB7fTtcclxuICBpbmxpbmVFZGl0aW5nVGVtcGxhdGVSZWZEYXRhOiBhbnkgPSB7fTtcclxuICBkaXNwbGF5ZWRDb2x1bW5zOiBzdHJpbmdbXSA9IFtdO1xyXG4gIHNob3dIaWRlQ29sdW1uc0FycmF5OiBNVEV4Q29sdW1uW10gPSBbXTtcclxuICBjb2x1bW5zTGlzdDogc3RyaW5nW10gPSBbXTtcclxuICBjb2x1bW5zQXJyYXk6IE1URXhDb2x1bW5bXSA9IFtdO1xyXG4gIGhlYWRlcnNGaWx0ZXJzSWRzOiBzdHJpbmdbXSA9IFtdO1xyXG4gIGNvbHVtbnNUb0Rpc3BsYXlXaXRoRXhwYW5kOiBzdHJpbmdbXSA9IFtdO1xyXG4gIHNlbGVjdGlvbiA9IG5ldyBTZWxlY3Rpb25Nb2RlbDxhbnk+KGZhbHNlLCBbXSk7XHJcbiAgaGlkZGVuQ3RybCA9IG5ldyBTZWxlY3Rpb25Nb2RlbDxhbnk+KHRydWUsIFtdKTtcclxuICB0YWJsZURhdGE6IGFueSA9IFtdO1xyXG4gIGZpbHRlclZhbHVlczogYW55ID0ge307XHJcbiAgZ2xvYmFsRmlsdGVyID0gJyc7XHJcbiAgc2hvd0hpZGVGaWx0ZXIgPSAnJztcclxuICBpbmRpdmlkdWFsRmlsdGVyID0gJyc7XHJcbiAgdG9nZ2xlRmlsdGVycyA9IGZhbHNlO1xyXG4gIGhpZGVSb3dzID0gZmFsc2U7XHJcbiAgZXhwYW5kZWRFbGVtZW50OiBhbnkgfCBudWxsO1xyXG4gIGN1cnJlbnRSb3dJbmRleDogbnVtYmVyID0gLTE7XHJcbiAgY3VycmVudFJvdzogYW55ID0ge307XHJcbiAgY2VsbEVkaXRpbmc6IGFueSA9IHt9O1xyXG4gIGhpZGVTaG93TWVudUdyb3VwITogRm9ybUdyb3VwO1xyXG4gIGNlbGxUZW1wbGF0ZSE6IFRlbXBsYXRlUmVmPGFueT47XHJcbiAgbWVudVg6IG51bWJlciA9IDA7XHJcbiAgbWVudVk6IG51bWJlciA9IDA7XHJcbiAgZHluYW1pY0Rpc3BsYXllZENvbHVtbnM6IGFueVtdID0gW1xyXG4gICAgeyBmaWx0ZXI6IGZhbHNlLCBuYW1lOiAnc2VsZWN0Jywgc2hvdzogZmFsc2UgfSxcclxuICAgIHsgZmlsdGVyOiBmYWxzZSwgbmFtZTogJ2VkaXQnLCBzaG93OiBmYWxzZSB9LFxyXG4gICAgeyBmaWx0ZXI6IGZhbHNlLCBuYW1lOiAncG9wdXAnLCBzaG93OiBmYWxzZSB9LFxyXG4gICAgeyBmaWx0ZXI6IGZhbHNlLCBuYW1lOiAnZGVsZXRlJywgc2hvdzogZmFsc2UgfSxcclxuICAgIHsgZmlsdGVyOiBmYWxzZSwgbmFtZTogJ2V4cGFuZCcsIHNob3c6IGZhbHNlIH0sXHJcbiAgXTtcclxuICBpbnB1dFByb3BlcnR5S2V5czogc3RyaW5nW10gPSBbXHJcbiAgICAnZGF0YVNvdXJjZScsXHJcbiAgICAnY29sdW1ucycsXHJcbiAgICAnaW5saW5lUm93RWRpdGluZycsXHJcbiAgICAncG9wdXBSb3dFZGl0aW5nJyxcclxuICAgICdlbmFibGVEZWxldGUnLFxyXG4gICAgJ3Jvd1NlbGVjdGlvbicsXHJcbiAgICAnbXVsdGlSb3dTZWxlY3Rpb24nLFxyXG4gICAgJ3N0aWNreUhlYWRlcicsXHJcbiAgICAnc3RpY2t5Rm9vdGVyJyxcclxuICAgICdjb2x1bW5GaWx0ZXInLFxyXG4gICAgJ2dsb2JhbFNlYXJjaCcsXHJcbiAgICAnZXhwYW5kUm93cycsXHJcbiAgICAnc29ydGluZycsXHJcbiAgXTtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwdWJsaWMgZGlhbG9nOiBNYXREaWFsb2csXHJcbiAgICBwdWJsaWMgc2VydmljZTogTWF0VGFibGVFeHRTZXJ2aWNlLFxyXG4gICAgcHVibGljIGZvcm1CdWlsZGVyc1NlcnZpY2U6IEZvcm1CdWlsZGVyLFxyXG4gICAgcHVibGljIGRvbVNhbml0aXplcjogRG9tU2FuaXRpemVyLFxyXG4gICAgcHVibGljIG1hdEljb25SZWdpc3RyeTogTWF0SWNvblJlZ2lzdHJ5LFxyXG4gICAgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmXHJcbiAgKSB7XHJcbiAgICB0aGlzLmFkZEljb25zVG9SZWdpc3RyeSgpO1xyXG4gICAgaWYgKHRoaXMuZGF0YVNvdXJjZSkge1xyXG4gICAgICB0aGlzLnRhYmxlRGF0YSA9IHRoaXMuZGF0YVNvdXJjZS5kYXRhO1xyXG4gICAgfVxyXG4gIH1cclxuICAvKipcclxuICAgKlxyXG4gICAqIEBwYXJhbSBjaGFuZ2VzIGNoYW5nZXMgY2FwdHVyZWQgZWFjaCB0aW1lIHVzZXIgY2hhbmdlcyBwcm9wZXJ0eSB2YWx1ZS5cclxuICAgKi9cclxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XHJcbiAgICB0aGlzLnNldFByb3BlcnR5VmFsdWUoY2hhbmdlcyk7XHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpIHtcclxuICAgIGlmICh0aGlzLmRhdGFTb3VyY2UpIHtcclxuICAgICAgdGhpcy5kYXRhU291cmNlLmZpbHRlclByZWRpY2F0ZSA9IHRoaXMuY3JlYXRlRmlsdGVyKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBuZ0FmdGVyVmlld0luaXQoKSB7XHJcbiAgICBpZiAodGhpcy5kYXRhU291cmNlKSB7XHJcbiAgICAgIHRoaXMuZGF0YVNvdXJjZS5wYWdpbmF0b3IgPSB0aGlzLnBhZ2luYXRvcjtcclxuICAgICAgdGhpcy5kYXRhU291cmNlLnNvcnQgPSB0aGlzLnNvcnQ7XHJcbiAgICB9XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiBjaGVja3MgYW5kIHVwZGF0ZXMgdGhlIHRoZSBjb2x1bW4ncyBoaWRlIGFuZCBzaG93IHByb3BlcnRpZXMuXHJcbiAgICovXHJcbiAgc2V0Q29sdW1uSGlkZVNob3coKSB7XHJcbiAgICBpZiAoXHJcbiAgICAgIHRoaXMuaGlkZVNob3dNZW51R3JvdXAgIT09IHVuZGVmaW5lZCAmJlxyXG4gICAgICB0aGlzLmhpZGVTaG93TWVudUdyb3VwICE9PSBudWxsXHJcbiAgICApIHtcclxuICAgICAgdGhpcy51cGRhdGVDb2x1bW5zSGlkZVNob3codGhpcy5oaWRlU2hvd01lbnVHcm91cC52YWx1ZSk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiBzZXQgdGhlIHByb3BlcnRpZXMgb2YgdGhlIHRhYmxlLlxyXG4gICAqIEBwYXJhbSBjaGFuZ2VzIGNoYW5nZXMgY2FwdHVyZWQgZWFjaCB0aW1lIHVzZXIgY2hhbmdlcyBwcm9wZXJ0eSB2YWx1ZS5cclxuICAgKi9cclxuICBzZXRQcm9wZXJ0eVZhbHVlKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcclxuICAgIGxldCBrZXlzID0gT2JqZWN0LmtleXMoY2hhbmdlcyk7XHJcbiAgICBrZXlzLmZvckVhY2goKHByb3BlcnR5KSA9PiB7XHJcbiAgICAgIGlmICh0aGlzLmlucHV0UHJvcGVydHlLZXlzLmluY2x1ZGVzKHByb3BlcnR5KSkge1xyXG4gICAgICAgIHRoaXMuc2V0UHJvcGVydGllc01hcFtwcm9wZXJ0eV0oY2hhbmdlc1twcm9wZXJ0eV0pO1xyXG4gICAgICB9IGVsc2UgaWYgKHByb3BlcnR5ID09ICdzaG93VG9vbGJhcicpIHtcclxuICAgICAgICBpZiAoY2hhbmdlc1snY29sdW1ucyddKSB7XHJcbiAgICAgICAgICB0aGlzLnNldFRvb2xiYXJNZW51Q29udHJvbHMoY2hhbmdlc1snY29sdW1ucyddLmN1cnJlbnRWYWx1ZSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRoaXMuc2V0VG9vbGJhck1lbnVDb250cm9scyh0aGlzLmNvbHVtbnNBcnJheSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcbiAgLyoqXHJcbiAgICogQGRlc2NyaXB0aW9uIFRoaXMgbWFwcGluZyBpcyB1c2VkIHRvIHNldCBhbmQgdXBkYXRlIGNoYW5nZXNpbiB0aGUgdGFibGUuXHJcbiAgICovXHJcbiAgc2V0UHJvcGVydGllc01hcDogYW55ID0ge1xyXG4gICAgZGF0YVNvdXJjZTogKHZhbHVlOiBhbnkpID0+IHRoaXMuc2V0VGFibGVEYXRhU291cmNlKHZhbHVlKSxcclxuICAgIGNvbHVtbnM6ICh2YWx1ZTogYW55KSA9PiB0aGlzLnNldENvbHVtbnNEYXRhKHZhbHVlLmN1cnJlbnRWYWx1ZSksXHJcbiAgICBpbmxpbmVSb3dFZGl0aW5nOiAodmFsdWU6IGFueSkgPT5cclxuICAgICAgdGhpcy5zaG93SGlkZUNvbHVtbignZWRpdCcsIHZhbHVlLmN1cnJlbnRWYWx1ZSksXHJcbiAgICBwb3B1cFJvd0VkaXRpbmc6ICh2YWx1ZTogYW55KSA9PlxyXG4gICAgICB0aGlzLnNob3dIaWRlQ29sdW1uKCdwb3B1cCcsIHZhbHVlLmN1cnJlbnRWYWx1ZSksXHJcbiAgICBlbmFibGVEZWxldGU6ICh2YWx1ZTogYW55KSA9PlxyXG4gICAgICB0aGlzLnNob3dIaWRlQ29sdW1uKCdkZWxldGUnLCB2YWx1ZS5jdXJyZW50VmFsdWUpLFxyXG4gICAgcm93U2VsZWN0aW9uOiAodmFsdWU6IGFueSkgPT4gdGhpcy5zZXRSb3dTZWxlY3Rpb24odmFsdWUuY3VycmVudFZhbHVlKSxcclxuICAgIG11bHRpUm93U2VsZWN0aW9uOiAodmFsdWU6IGFueSkgPT4ge1xyXG4gICAgICB0aGlzLnNlbGVjdGlvbiA9IG5ldyBTZWxlY3Rpb25Nb2RlbDxhbnk+KHZhbHVlLmN1cnJlbnRWYWx1ZSwgW10pO1xyXG4gICAgfSxcclxuICAgIHN0aWNreUhlYWRlcjogKHZhbHVlOiBhbnkpID0+IHtcclxuICAgICAgdGhpcy5zdGlja3lIZWFkZXIgPSB2YWx1ZS5jdXJyZW50VmFsdWU7XHJcbiAgICB9LFxyXG4gICAgc3RpY2t5Rm9vdGVyOiAodmFsdWU6IGFueSkgPT4ge1xyXG4gICAgICB0aGlzLnN0aWNreUZvb3RlciA9IHZhbHVlLmN1cnJlbnRWYWx1ZTtcclxuICAgIH0sXHJcbiAgICBjb2x1bW5GaWx0ZXI6ICh2YWx1ZTogYW55KSA9PiB0aGlzLnNldENvbHVtbkZpbHRlcih2YWx1ZS5jdXJyZW50VmFsdWUpLFxyXG4gICAgZ2xvYmFsU2VhcmNoOiAodmFsdWU6IGFueSkgPT5cclxuICAgICAgKHRoaXMuZGF0YVNvdXJjZS5maWx0ZXJQcmVkaWNhdGUgPSB0aGlzLmNyZWF0ZUZpbHRlcigpKSxcclxuICAgIGV4cGFuZFJvd3M6ICh2YWx1ZTogYW55KSA9PiB7XHJcbiAgICAgIHRoaXMubG9hZGluZ0luZGljYXRvciA9IHRydWU7XHJcbiAgICAgIHRoaXMuZGF0YVNvdXJjZSA9IG5ldyBNYXRUYWJsZURhdGFTb3VyY2UodGhpcy50YWJsZURhdGEpO1xyXG4gICAgICBpZiAodmFsdWUuY3VycmVudFZhbHVlID09IHRydWUpIHtcclxuICAgICAgICBpZiAoIXRoaXMuZGlzcGxheWVkQ29sdW1ucy5pbmNsdWRlcygnZXhwYW5kJykpIHtcclxuICAgICAgICAgIHRoaXMuZGlzcGxheWVkQ29sdW1ucy5wdXNoKCdleHBhbmQnKTtcclxuICAgICAgICAgIHRoaXMuY29sdW1uc1RvRGlzcGxheVdpdGhFeHBhbmQgPSBbLi4udGhpcy5kaXNwbGF5ZWRDb2x1bW5zXTtcclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5jb2x1bW5zVG9EaXNwbGF5V2l0aEV4cGFuZCA9IFsuLi50aGlzLmRpc3BsYXllZENvbHVtbnNdO1xyXG4gICAgICAgIGlmICh0aGlzLmRpc3BsYXllZENvbHVtbnMuaW5jbHVkZXMoJ2V4cGFuZCcpKSB7XHJcbiAgICAgICAgICBsZXQgaW5kZXggPSB0aGlzLmRpc3BsYXllZENvbHVtbnMuaW5kZXhPZignZXhwYW5kJyk7XHJcbiAgICAgICAgICB0aGlzLmRpc3BsYXllZENvbHVtbnMuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5leHBhbmRlZEVsZW1lbnQgPSBudWxsO1xyXG4gICAgICB9XHJcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgIHRoaXMubG9hZGluZ0luZGljYXRvciA9IGZhbHNlO1xyXG4gICAgICB9LCAyMDApO1xyXG4gICAgfSxcclxuICAgIHNvcnRpbmc6ICh2YWx1ZTogYW55KSA9PiAodGhpcy5kYXRhU291cmNlLnNvcnQgPSB0aGlzLnNvcnQpLFxyXG4gIH07XHJcbiAgLyoqXHJcbiAgICogQGRlc2NyaXB0aW9uIHVzZWQgc2V0IGRhdGEgc291cmNlIGZvciB0YWJsZS5cclxuICAgKiBAcGFyYW0gdmFsdWUgZGF0YSBzb3VyY2UgdmFsdWUgZnJvbSB1c2VyLlxyXG4gICAqL1xyXG4gIHNldFRhYmxlRGF0YVNvdXJjZSh2YWx1ZTogYW55KSB7XHJcbiAgICBpZiAodmFsdWUuY3VycmVudFZhbHVlKSB7XHJcbiAgICAgIHRoaXMudGFibGVEYXRhID0gdmFsdWUuY3VycmVudFZhbHVlLmRhdGE7XHJcbiAgICAgIHRoaXMuZGF0YVNvdXJjZSA9IHZhbHVlLmN1cnJlbnRWYWx1ZTtcclxuICAgICAgdGhpcy5yZUNhbCgpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5kYXRhU291cmNlID0gbmV3IE1hdFRhYmxlRGF0YVNvdXJjZShbe31dKTtcclxuICAgIH1cclxuICB9XHJcbiAgLyoqXHJcbiAgICogQGRlc2NyaXB0aW9uIHVzZWQgY3JlYXRlIHNlbGV0aW9uIG1vZGVsIGFuZCBzZXQgc2VsZWN0aW9uIGNvbHVtbiB2aXNpYmlsaXR5LlxyXG4gICAqIEBwYXJhbSB2YWx1ZSBib29sZWFuIHZhbHVlIHRvIHNob3cgb3IgaGlkZSBzZWxlY3Rpb24gQ29sdW1uIGZyb20gdGFibGUuXHJcbiAgICovXHJcbiAgc2V0Um93U2VsZWN0aW9uKHZhbHVlOiBib29sZWFuKSB7XHJcbiAgICB0aGlzLnNlbGVjdGlvbiA9IG5ldyBTZWxlY3Rpb25Nb2RlbDxhbnk+KHRydWUsIFtdKTtcclxuICAgIHRoaXMudXBkYXRlU2VsZWN0aW9uQ29sdW1uVmlzaWJpbGl0eSh2YWx1ZSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBAZGVzY3JpcHRpb24gY3JlYXRlIGZpbHRlciBoZWFkZXIgcm93IGFuZCBhc3NpZ25zIGZpbHRlciBwcmVkaWNhdGUgdG8gdGFibGUgZGF0YSBzb3VyY2UuXHJcbiAgICogQHBhcmFtIHZhbHVlIGJvb2xlYW4gdmFsdWUgdG8gY2hhbmdlICB2aXNpYmlsaXR5IG9mIGNvbHVtbiBmaWx0ZXIgcm93LlxyXG4gICAqL1xyXG4gIHNldENvbHVtbkZpbHRlcih2YWx1ZTogYm9vbGVhbikge1xyXG4gICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgIGxldCBhcnJheTogc3RyaW5nW10gPSBbXTtcclxuICAgICAgdGhpcy5jb2x1bW5zQXJyYXkuZm9yRWFjaCgoY29sdW1uLCBpKSA9PiB7XHJcbiAgICAgICAgaWYgKFxyXG4gICAgICAgICAgdGhpcy5keW5hbWljRGlzcGxheWVkQ29sdW1ucy5maWx0ZXIoKGEpID0+IGEubmFtZSA9PSBjb2x1bW4/LmZpZWxkKVswXVxyXG4gICAgICAgICAgICAuc2hvd1xyXG4gICAgICAgICkge1xyXG4gICAgICAgICAgYXJyYXkucHVzaChjb2x1bW4/LmZpZWxkICsgJ18nICsgaSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgICAgdGhpcy5oZWFkZXJzRmlsdGVyc0lkcyA9IGFycmF5O1xyXG4gICAgICB0aGlzLmRhdGFTb3VyY2UuZmlsdGVyUHJlZGljYXRlID0gdGhpcy5jcmVhdGVGaWx0ZXIoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuaGVhZGVyc0ZpbHRlcnNJZHMgPSBbXTtcclxuICAgICAgdGhpcy5kYXRhU291cmNlLmZpbHRlciA9ICcnO1xyXG4gICAgfVxyXG4gICAgdGhpcy50b2dnbGVGaWx0ZXJzID0gdmFsdWU7XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBsaXN0IG9mIHZpc2libGUgY29sdW1uIG5hbWVzLlxyXG4gICAqIEByZXR1cm5zIGxpc3Qgb2YgdmlzaWJsZSBjb2x1bW4gbmFtZXMuXHJcbiAgICovXHJcbiAgZ2V0RGlzcGxheWVkQ29sdW1ucygpOiBzdHJpbmdbXSB7XHJcbiAgICBsZXQgbGlzdCA9IHRoaXMuZHluYW1pY0Rpc3BsYXllZENvbHVtbnNcclxuICAgICAgLmZpbHRlcigoY2QpID0+IGNkLnNob3cpXHJcbiAgICAgIC5tYXAoKGNkKSA9PiBjZC5uYW1lKTtcclxuICAgIHJldHVybiBsaXN0O1xyXG4gIH1cclxuICAvKipcclxuICAgKiBAcGFyYW0gbWVudVR5cGUgdHlwZSBvZiBtZW51IHRvIG9wZW4gZnJvbSB0b29sYmFyLlxyXG4gICAqIEBwYXJhbSBldmVudCBtb3VzZSBldmVudCB0byBvcGVuIG1lbnUgb24gdGhhdCBsb2NhdGlvbi5cclxuICAgKi9cclxuICBvcGVuTWVudShtZW51VHlwZTogc3RyaW5nLCBldmVudDogTW91c2VFdmVudCkge1xyXG4gICAgdGhpcy5tZW51WCA9IGV2ZW50LmNsaWVudFg7XHJcbiAgICB0aGlzLm1lbnVZID0gZXZlbnQuY2xpZW50WTtcclxuICAgIHN3aXRjaCAobWVudVR5cGUpIHtcclxuICAgICAgY2FzZSAnZXhwb3J0Jzoge1xyXG4gICAgICAgIHRoaXMuZXhwb3J0TWVudUN0cmwgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMubWVudVRyaWdnZXIub3Blbk1lbnUoKTtcclxuICAgICAgICBicmVhaztcclxuICAgICAgfVxyXG4gICAgICBjYXNlICdoaWRlU2hvdyc6IHtcclxuICAgICAgICB0aGlzLmhpZGVTaG93TWVudUN0cmwgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMub3BlbkhpZGVTaG93TWVudSh0aGlzLmNvbHVtbnNBcnJheSk7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIH1cclxuICAgICAgY2FzZSAnY29sdW1uUGluJzoge1xyXG4gICAgICAgIHRoaXMuY29sdW1uUGluTWVudUN0cmwgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMub3BlbkhpZGVTaG93TWVudSh0aGlzLmNvbHVtbnNBcnJheSk7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbiAgLyoqXHJcbiAgICogQGRlc2NyaXB0aW9uIHRyaWdnZXJzIHdoZW4gbWVudSBpcyBjbG9zZWQgYW5kIHJlc2V0IHRoZSByZXF1aXJlZCBjb250cm9scy5cclxuICAgKi9cclxuICBtZW51Q2xvc2VkKCkge1xyXG4gICAgdGhpcy5leHBvcnRNZW51Q3RybCA9IGZhbHNlO1xyXG4gIH1cclxuICAvKipcclxuICAgKiBAZGVzY3JpcHRpb24gc2V0IGxpc3Qgb2YgY29sdW1ucyB0byBkaXNwbGF5IGluIHRhYmxlLlxyXG4gICAqIEBwYXJhbSBjb2x1bW5zIGNvbHVtbnMgYXJyYXkgZnJvbSB1c2VyIGlucHV0LlxyXG4gICAqL1xyXG4gIHNldENvbHVtbnNEYXRhKGNvbHVtbnM6IE1URXhDb2x1bW5bXSkge1xyXG4gICAgaWYgKGNvbHVtbnMubGVuZ3RoKSB7XHJcbiAgICAgIHRoaXMuY29sdW1uc0FycmF5ID0gWy4uLmNvbHVtbnNdO1xyXG4gICAgICB0aGlzLnNldENvbHVtbnNMaXN0KGNvbHVtbnMpO1xyXG4gICAgfVxyXG4gIH1cclxuICAvKipcclxuICAgKiBAZGVzY3JpcHRpb24gc2V0IGxpc3Qgb2YgY29sdW1ucyB0byBkaXNwbGF5IGluIHRhYmxlLlxyXG4gICAqIEBwYXJhbSBjb2x1bW5zIGNvbHVtbnMgYXJyYXkgZnJvbSB1c2VyIGlucHV0IHdpdGggY29uZmlndXJhdGlvbnMuXHJcbiAgICovXHJcbiAgc2V0Q29sdW1uc0xpc3QoY29sdW1uczogTVRFeENvbHVtbltdKSB7XHJcbiAgICB0aGlzLmNvbHVtbnNMaXN0ID0gW107XHJcbiAgICB0aGlzLmRpc3BsYXllZENvbHVtbnMgPSBbJ3NlbGVjdCcsICdlZGl0JywgJ3BvcHVwJywgJ2RlbGV0ZSddO1xyXG4gICAgbGV0IGNvbHVtbnNBcnJheTogRGlzcGxheUNvbHVtbltdID0gW107XHJcbiAgICBjb2x1bW5zLmZvckVhY2goKGNvbCkgPT4ge1xyXG4gICAgICBpZiAodHlwZW9mIGNvbD8uaGVhZGVyID09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgdGhpcy5jb2x1bW5zTGlzdC5wdXNoKGNvbD8uaGVhZGVyKTtcclxuICAgICAgICB0aGlzLmRpc3BsYXllZENvbHVtbnMucHVzaChjb2w/LmZpZWxkKTtcclxuICAgICAgICBjb2x1bW5zQXJyYXkucHVzaCh7IGZpbHRlcjogdHJ1ZSwgbmFtZTogY29sPy5maWVsZCwgc2hvdzogIWNvbC5oaWRlIH0pO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICAgIHRoaXMuZHluYW1pY0Rpc3BsYXllZENvbHVtbnMgPSBbXHJcbiAgICAgIHsgZmlsdGVyOiBmYWxzZSwgbmFtZTogJ3NlbGVjdCcsIHNob3c6IGZhbHNlIH0sXHJcbiAgICAgIHsgZmlsdGVyOiBmYWxzZSwgbmFtZTogJ2VkaXQnLCBzaG93OiBmYWxzZSB9LFxyXG4gICAgICB7IGZpbHRlcjogZmFsc2UsIG5hbWU6ICdwb3B1cCcsIHNob3c6IGZhbHNlIH0sXHJcbiAgICAgIHsgZmlsdGVyOiBmYWxzZSwgbmFtZTogJ2RlbGV0ZScsIHNob3c6IGZhbHNlIH0sXHJcbiAgICBdO1xyXG4gICAgdGhpcy5keW5hbWljRGlzcGxheWVkQ29sdW1ucyA9IGNvbHVtbnNBcnJheS5jb25jYXQoXHJcbiAgICAgIHRoaXMuZHluYW1pY0Rpc3BsYXllZENvbHVtbnNcclxuICAgICk7XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiBUYWtlIGJvb2xlYW4gdmFsdWUgYW5kIG5hbWUgY29sdW1uIGFuZCB1cGRhdGUgaXRzIHZpc2liaWxpdHkgc3RhdHVzIGluIHRhYmxlLlxyXG4gICAqIEBwYXJhbSBuYW1lIG5hbWUgb2YgdGhlIGNvbHVtbiB0byBzZXQgdmlzaWJpbGl0eS5cclxuICAgKiBAcGFyYW0gdmFsdWUgYm9vbGVhbiB2YWx1ZSB0byBzZXQgdmlzaWJpbGl0eSBvZiB0aGUgY29sdW1uLlxyXG4gICAqL1xyXG4gIHNob3dIaWRlQ29sdW1uKG5hbWU6IHN0cmluZywgdmFsdWU6IGJvb2xlYW4pIHtcclxuICAgIHRoaXMuZHluYW1pY0Rpc3BsYXllZENvbHVtbnMuZmlsdGVyKChhKSA9PiBhLm5hbWUgPT0gbmFtZSlbMF0uc2hvdyA9IHZhbHVlO1xyXG4gICAgaWYgKHRoaXMuY29sdW1uRmlsdGVyKSB7XHJcbiAgICAgIHRoaXMuc2V0Q29sdW1uRmlsdGVyKHRydWUpO1xyXG4gICAgfVxyXG4gIH1cclxuICAvKipcclxuICAgKiBAZGVzY3JpcHRpb24gVGhpcyBtZXRob2Qgd2lsbCBwb3NpdGlvbiB0aGUgc2VsZWN0aW9uIGNvbHVtbiB0byBmaXJzdCBhbmQgYWxzbyB1cGRhdGUgaXRzIHZpc2liaWxpdHkuXHJcbiAgICogQHBhcmFtIHZhbHVlIHZhbHVlIHVzZWQgdG8gc2V0IHZpc2liaWxpdHkgb2YgdGhlIHNlbGVjdGlvbiBjb2x1bW4uXHJcbiAgICovXHJcbiAgdXBkYXRlU2VsZWN0aW9uQ29sdW1uVmlzaWJpbGl0eSh2YWx1ZTogYm9vbGVhbikge1xyXG4gICAgbGV0IGNvbHVtbk5hbWUgPSAnc2VsZWN0JztcclxuICAgIGxldCBjb2x1bW4gPSB0aGlzLmR5bmFtaWNEaXNwbGF5ZWRDb2x1bW5zLmZpbHRlcihcclxuICAgICAgKGEpID0+IGEubmFtZSA9PSBjb2x1bW5OYW1lXHJcbiAgICApWzBdO1xyXG4gICAgbGV0IGluZGV4ID0gdGhpcy5keW5hbWljRGlzcGxheWVkQ29sdW1ucy5maW5kSW5kZXgoXHJcbiAgICAgIChjb2x1bW46IGFueSkgPT4gY29sdW1uLm5hbWUgPT0gY29sdW1uTmFtZVxyXG4gICAgKTtcclxuICAgIGlmIChpbmRleCA+IC0xKSB7XHJcbiAgICAgIHRoaXMuZHluYW1pY0Rpc3BsYXllZENvbHVtbnMuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgdGhpcy5keW5hbWljRGlzcGxheWVkQ29sdW1ucy51bnNoaWZ0KGNvbHVtbik7XHJcbiAgICAgIHRoaXMuZHluYW1pY0Rpc3BsYXllZENvbHVtbnMuZmlsdGVyKFxyXG4gICAgICAgIChjb2x1bW4pID0+IGNvbHVtbi5uYW1lID09IGNvbHVtbk5hbWVcclxuICAgICAgKVswXS5zaG93ID0gdmFsdWU7XHJcbiAgICB9XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIHVwZGF0ZSB0aGUgcG9zaXRpb24gb2YgIGNvbHVtbiBpbiBjb2x1bW5zIGFycmF5IGFjY29yZGluZyB0byBpdHMgZHJvcHBlZCBwb3NpdGlvbi5cclxuICAgKiBAcGFyYW0gZXZlbnQgQ2RrRHJhZ0Ryb3AgdXNlZCB0byB1cGRhdGUgY29sdW1uIHBvc2l0aW9uIGluIGNvbHVtbnMgYXJyYXkuXHJcbiAgICovXHJcbiAgb25Ecm9wKGV2ZW50OiBDZGtEcmFnRHJvcDxhbnk+KSB7XHJcbiAgICBpZiAodGhpcy5kbmRDb2x1bW5zKSB7XHJcbiAgICAgIGxldCBhZGp1c3RlZFZhbHVlID0gMDtcclxuICAgICAgaWYgKFxyXG4gICAgICAgIHRoaXMuZHluYW1pY0Rpc3BsYXllZENvbHVtbnNbMF0ubmFtZSA9PSAnc2VsZWN0JyAmJlxyXG4gICAgICAgIHRoaXMuZHluYW1pY0Rpc3BsYXllZENvbHVtbnNbMF0uc2hvdyA9PSBmYWxzZVxyXG4gICAgICApIHtcclxuICAgICAgICBhZGp1c3RlZFZhbHVlID0gMTtcclxuICAgICAgfVxyXG4gICAgICBtb3ZlSXRlbUluQXJyYXkoXHJcbiAgICAgICAgdGhpcy5keW5hbWljRGlzcGxheWVkQ29sdW1ucyxcclxuICAgICAgICBldmVudC5wcmV2aW91c0luZGV4ICsgYWRqdXN0ZWRWYWx1ZSxcclxuICAgICAgICBldmVudC5jdXJyZW50SW5kZXggKyBhZGp1c3RlZFZhbHVlXHJcbiAgICAgICk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCBjcmVhdGUgZmlsdGVyIHByZWRpY2F0ZSBmdW5jdGlvbiB3aGljaCB3aWxsIHNldCBzZWFyY2ggdmFsdWUgdG8gdGFibGUgZmlsdGVyc1xyXG4gICAqIGZvciBib3RoIGdsb2JhbCBhbmQgaW5kaXZpZHVhbCBjb2x1bSBmaWx0ZXJpbmcuXHJcbiAgICogQHJldHVybnMgcmV0dXJucyBib29sZWFuIHZhbHVlIHRvIGZpbHRlciByb3dzIGluIHRhYmxlLlxyXG4gICAqL1xyXG4gIGNyZWF0ZUZpbHRlcigpOiAoZGF0YTogYW55LCBmaWx0ZXI6IHN0cmluZykgPT4gYm9vbGVhbiB7XHJcbiAgICBjb25zdCB0YWJsZUZpbHRlclByZWRpY2F0ZSA9IChkYXRhOiBhbnksIGZpbHRlcjogc3RyaW5nKTogYm9vbGVhbiA9PiB7XHJcbiAgICAgIGxldCByZXN1bHQ6IGJvb2xlYW4gPSB0cnVlO1xyXG4gICAgICAvLyBzZWFyY2ggYWxsIGNvbHVtbiBmaWVsZHNcclxuICAgICAgaWYgKHRoaXMuZ2xvYmFsRmlsdGVyKSB7XHJcbiAgICAgICAgbGV0IGV4cHJlc3Npb24gPSAnJztcclxuICAgICAgICBsZXQga2V5cyA9IE9iamVjdC5rZXlzKGRhdGEpO1xyXG4gICAgICAgIGtleXMuZm9yRWFjaCgoa2V5KSA9PiB7XHJcbiAgICAgICAgICBleHByZXNzaW9uID1cclxuICAgICAgICAgICAgZXhwcmVzc2lvbiArXHJcbiAgICAgICAgICAgIGBkYXRhLiR7a2V5fS50b1N0cmluZygpLnRyaW0oKS50b0xvd2VyQ2FzZSgpLmluZGV4T2YodGhpcy5nbG9iYWxGaWx0ZXIudG9Mb3dlckNhc2UoKSkgIT09IC0xIHx8YDtcclxuICAgICAgICB9KTtcclxuICAgICAgICBpZiAoXHJcbiAgICAgICAgICBleHByZXNzaW9uLmNoYXJBdChleHByZXNzaW9uLmxlbmd0aCAtIDIpICtcclxuICAgICAgICAgICAgZXhwcmVzc2lvbi5jaGFyQXQoZXhwcmVzc2lvbi5sZW5ndGggLSAxKSA9PVxyXG4gICAgICAgICAgJ3x8J1xyXG4gICAgICAgICkge1xyXG4gICAgICAgICAgZXhwcmVzc2lvbiA9IGV4cHJlc3Npb24uc3Vic3RyaW5nKDAsIGV4cHJlc3Npb24ubGVuZ3RoIC0gMik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJlc3VsdCA9IGV2YWwoZXhwcmVzc2lvbik7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKCFyZXN1bHQpIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgIH1cclxuICAgICAgbGV0IHNlYXJjaFN0cmluZyA9IEpTT04ucGFyc2UoZmlsdGVyKTtcclxuICAgICAgLy9zZWFyY2ggc2luZ2xlIGNvbHVtbiBmaWVsZFxyXG4gICAgICBpZiAodGhpcy5pbmRpdmlkdWFsRmlsdGVyKSB7XHJcbiAgICAgICAgcmV0dXJuIChcclxuICAgICAgICAgIGRhdGFbdGhpcy5pbmRpdmlkdWFsRmlsdGVyXVxyXG4gICAgICAgICAgICAudG9TdHJpbmcoKVxyXG4gICAgICAgICAgICAudHJpbSgpXHJcbiAgICAgICAgICAgIC50b0xvd2VyQ2FzZSgpXHJcbiAgICAgICAgICAgIC5pbmRleE9mKFxyXG4gICAgICAgICAgICAgIHNlYXJjaFN0cmluZ1t0aGlzLmluZGl2aWR1YWxGaWx0ZXJdLnRvU3RyaW5nKCkudG9Mb3dlckNhc2UoKVxyXG4gICAgICAgICAgICApICE9PSAtMVxyXG4gICAgICAgICk7XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIHRhYmxlRmlsdGVyUHJlZGljYXRlO1xyXG4gIH1cclxuICAvKipcclxuICAgKiBAZGVzY3JpcHRpb24gYXNzaWducyB0aGUgc2VhcmNoIHZhbHVlIHRvIG1hdCB0YWJsZSBkYXRhIHNvdXJjZSB0byBhcHBseSB0aGUgZmlsdGVyLlxyXG4gICAqIEBwYXJhbSBzZWFyY2hWYWx1ZSB2YWx1ZSB0byBiZSBzZWFyY2hlZCBmcm9tIHRhYmxlIHJvd3MuXHJcbiAgICovXHJcbiAgYXBwbHlHbG9iYWxGaWx0ZXIoc2VhcmNoVmFsdWU6IHN0cmluZykge1xyXG4gICAgdGhpcy5nbG9iYWxGaWx0ZXIgPSBzZWFyY2hWYWx1ZTtcclxuICAgIGxldCBjb2x1bW5zOiBhbnkgPSB7fTtcclxuICAgIHRoaXMuY29sdW1uc0FycmF5LmZvckVhY2goKGNvbHVtbjogTVRFeENvbHVtbikgPT4ge1xyXG4gICAgICBpZiAoY29sdW1uLmZpZWxkKSBjb2x1bW5zW2NvbHVtbi5maWVsZF0gPSBzZWFyY2hWYWx1ZTtcclxuICAgIH0pO1xyXG4gICAgdGhpcy5kYXRhU291cmNlLmZpbHRlciA9IEpTT04uc3RyaW5naWZ5KGNvbHVtbnMpO1xyXG4gIH1cclxuICAvKipcclxuICAgKiBAZGVzY3JpcHRpb24gVGhpcyBtZXRob2QgaXMgdXNlZCB0byBhcHBseSBjb2x1bW4gYmFzZWQgZmlsdGVyaW5nXHJcbiAgICogQHBhcmFtIHNlYXJjaFZhbHVlIHZhbHVlIHRvIGJlIHNlYXJjaGVkIGZyb20gdGFibGUgcm93cy5cclxuICAgKiBAcGFyYW0gY29sdW1uIGZpbHRlciB3aWxsIGJlIGFwcGxpZWQgYmFzZWQgb24gdGhpcyBjb2x1bW4gZmllbGQuXHJcbiAgICovXHJcbiAgYXBwbHlDb2x1bW5GaWx0ZXIoc2VhcmNoVmFsdWU6IEZpbHRlclNlYXJjaFZhbHVlLCBjb2x1bW46IE1URXhDb2x1bW4pIHtcclxuICAgIHRoaXMuaW5kaXZpZHVhbEZpbHRlciA9IGNvbHVtbi5maWVsZDtcclxuICAgIHRoaXMuZmlsdGVyVmFsdWVzW2NvbHVtbi5maWVsZF0gPSBzZWFyY2hWYWx1ZVtjb2x1bW4uZmllbGRdO1xyXG4gICAgdGhpcy5kYXRhU291cmNlLmZpbHRlciA9IEpTT04uc3RyaW5naWZ5KHRoaXMuZmlsdGVyVmFsdWVzKTtcclxuICB9XHJcbiAgLyoqXHJcbiAgICogQGRlc2NyaXB0aW9uIFRoaXMgbWV0aG9kIHdpbGwgdGFrZSByb3cgYW5kIGl0cyBpbmRleCBlbmFibGUgaW5saW5lIGVkaXRpbmcgdG9vbHMgb24gdGhhdCByb3cuXHJcbiAgICogQHBhcmFtIHJvdyByb3cgb24gd2hpY2ggdXNlciB3YW50cyB0byBkbyBlZGl0LlxyXG4gICAqIEBwYXJhbSBpbmRleCBpbmRleCBvZiB0aGUgcm93IHdoZXJlIGlubGluZSBlZGl0aW5nIHdpbGwgYmUgZW5hYmxlZC5cclxuICAgKi9cclxuICBlbmFibGVJbmxpbmVFZGl0aW5nKHJvdzogYW55LCBpbmRleDogbnVtYmVyKSB7XHJcbiAgICBjb25zdCByb3dEYXRhOiBhbnkgPSB7fTtcclxuICAgIHJvd0RhdGFbJ2UnICsgaW5kZXhdID0geyAuLi5yb3cgfTtcclxuICAgIHRoaXMucm93RGF0YVRlbXAgPSByb3dEYXRhO1xyXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgIHRoaXMudGFibGVEYXRhW2luZGV4XVsnZWRpdGFibGUnXSA9ICF0aGlzLnRhYmxlRGF0YVtpbmRleF1bJ2VkaXRhYmxlJ107XHJcbiAgICB9LCAwKTtcclxuICB9XHJcbiAgLyoqXHJcbiAgICogQGRlc2NyaXB0aW9uIFRoaXMgbWV0aG9kIHdpbGwgY3JlYXRlIGFuZCByZXR1cm4gZGF0YSB0byBpbmxpbmUgZWRpdGluZyB0ZW1wbGF0ZS5cclxuICAgKiBAcGFyYW0gcm93IHJvdyBvbiB3aGljaCB1c2VyIHdhbnRzIHRvIGRvIGVkaXQuXHJcbiAgICogQHBhcmFtIGluZGV4IGluZGV4IG9mIHRoZSByb3cgd2hlcmUgaW5saW5lIGVkaXRpbmcgd2lsbCBiZSBlbmFibGVkLlxyXG4gICAqIEBwYXJhbSBjb2x1bW4gY3VycmVudCBjb2x1bW4gb2YgdGhlIHRhYmxlLlxyXG4gICAqL1xyXG4gIGdldElubGluZUVkaXRpbmdEYXRhKHJvdzogTVRFeFJvdywgaW5kZXg6IG51bWJlciwgY29sdW1uOiBNVEV4Q29sdW1uKSB7XHJcbiAgICB0aGlzLmlubGluZUVkaXRpbmdUZW1wbGF0ZVJlZkRhdGEgPSB7XHJcbiAgICAgIHJvdzogeyAuLi5yb3cgfSxcclxuICAgICAgY29sdW1uOiB7IC4uLmNvbHVtbiB9LFxyXG4gICAgICBpbmRleDogaW5kZXgsXHJcbiAgICAgIHVwZGF0ZUZ1bmM6IHRoaXMudXBkYXRlSW5saW5lVGVtcGxhdGVEYXRhLFxyXG4gICAgfTtcclxuICAgIHJldHVybiB0aGlzLmlubGluZUVkaXRpbmdUZW1wbGF0ZVJlZkRhdGE7XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCB3aWxsIHRha2UgZGF0YSBmcm9tIGlubGluZSBlZGl0aW5nIHRlbXBsYXRlIGFuZCB1cGRhdGUgaW4gdGFibGUgZGF0YSBzb3VyY2UuXHJcbiAgICogQHBhcmFtIHJvdyB1cGRhdGVkIHJvdyBmcm9tIGlubGluZSBlZGl0aW5nIHRlbXBsYXRlLlxyXG4gICAqL1xyXG4gIHVwZGF0ZUlubGluZVRlbXBsYXRlRGF0YSA9IChyb3c6IE1URXhSb3cpID0+IHtcclxuICAgIHRoaXMuc2VydmljZS5zZWxlY3RlZFJvdy5uZXh0KHJvdyk7XHJcbiAgfTtcclxuICAvKipcclxuICAgKiBAZGVzY3JpcHRpb24gVGhpcyBtZXRob2Qgc2V0IGRhdGEgZm9yIGluLWNlbGwgZWRpdGluZy5cclxuICAgKiBAcGFyYW0gcm93IHJvdyBvbiB3aGljaCB1c2VyIHdhbnRzIHRvIGRvIGVkaXQuXHJcbiAgICogQHBhcmFtIGluZGV4IGluZGV4IG9mIHRoZSByb3cgd2hlcmUgaW5saW5lIGVkaXRpbmcgd2lsbCBiZSBlbmFibGVkLlxyXG4gICAqL1xyXG4gIHNldENlbGxEYXRhKHJvdzogTVRFeFJvdywgaW5kZXg6IG51bWJlcikge1xyXG4gICAgdGhpcy5jdXJyZW50Um93ID0geyAuLi5yb3cgfTtcclxuICAgIHRoaXMuY3VycmVudFJvd0luZGV4ID0gaW5kZXg7XHJcbiAgICB0aGlzLnJvd0RhdGFUZW1wWydlJyArIGluZGV4XSA9IHsgLi4ucm93IH07XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiBUaGlzIHdpbGwgcmVzdG9yZSB0aGUgZGF0YSBhbmQgY2VuY2VsIHRoZSBpbmxpbmUgZWRpdGluZy5cclxuICAgKiBAcGFyYW0gcm93IHJvdyBvbiB3aGljaCB1c2VyIHdhbnRzIHRvIGRvIGVkaXQuXHJcbiAgICogQHBhcmFtIGluZGV4IGluZGV4IG9mIHRoZSByb3cgd2hlcmUgaW5saW5lIGVkaXRpbmcgd2lsbCBiZSBlbmFibGVkLlxyXG4gICAqL1xyXG4gIGNhbmNlbElubGluZUVkaXRpbmcocm93OiBNVEV4Um93LCBpbmRleDogbnVtYmVyKSB7XHJcbiAgICB0aGlzLnRhYmxlRGF0YS5maWx0ZXIoKGE6IGFueSwgaTogbnVtYmVyKSA9PiBpID09IGluZGV4KVswXVsnZWRpdGFibGUnXSA9XHJcbiAgICAgICF0aGlzLnRhYmxlRGF0YS5maWx0ZXIoKGE6IGFueSwgaTogbnVtYmVyKSA9PiBpID09IGluZGV4KVswXVsnZWRpdGFibGUnXTtcclxuICAgIHRoaXMuZGF0YVNvdXJjZSA9IG5ldyBNYXRUYWJsZURhdGFTb3VyY2UodGhpcy50YWJsZURhdGEpO1xyXG4gICAgdGhpcy5yb3dEYXRhVGVtcFsnZScgKyBpbmRleF0gPSB7fTtcclxuICAgIHRoaXMuc2VydmljZS5zZWxlY3RlZFJvdy5uZXh0KHVuZGVmaW5lZCk7XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCB3aWxsIHNhdmUgYW5kIHVwZGF0ZSB0aGUgaW5saW5lIGVkaXRpbmcgZGF0YSBhbmQgZW1pdCB0aGUgdXBkYXRlIHJvdyBhbmQgaW5kZXguXHJcbiAgICogQHBhcmFtIHJvdyByb3cgb24gd2hpY2ggdXNlciB3YW50cyB0byBkbyBlZGl0LlxyXG4gICAqIEBwYXJhbSBpbmRleCBpbmRleCBvZiB0aGUgcm93IHdoZXJlIGlubGluZSBlZGl0aW5nIHdpbGwgYmUgZW5hYmxlZC5cclxuICAgKi9cclxuICBzYXZlSW5saW5lRWRpdGluZyhyb3c6IE1URXhSb3csIGluZGV4OiBudW1iZXIpIHtcclxuICAgIGlmICghdGhpcy5pbmxpbmVFZGl0aW5nVGVtcGxhdGVSZWYpIHtcclxuICAgICAgdGhpcy50YWJsZURhdGFbaW5kZXhdID0geyAuLi50aGlzLnJvd0RhdGFUZW1wWydlJyArIGluZGV4XSB9O1xyXG4gICAgICByb3cgPSB7IC4uLnRoaXMucm93RGF0YVRlbXBbJ2UnICsgaW5kZXhdIH07XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBsZXQgY2hhbmdlZERhdGEgPSB0aGlzLnNlcnZpY2Uuc2VsZWN0ZWRSb3cudmFsdWU7XHJcbiAgICAgIGlmIChjaGFuZ2VkRGF0YSkge1xyXG4gICAgICAgIHRoaXMudGFibGVEYXRhW2luZGV4XSA9IHsgLi4uY2hhbmdlZERhdGEgfTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgdGhpcy5kYXRhU291cmNlID0gbmV3IE1hdFRhYmxlRGF0YVNvdXJjZSh0aGlzLnRhYmxlRGF0YSk7XHJcbiAgICB0aGlzLnJvd0RhdGFUZW1wWydlJyArIGluZGV4XSA9IHt9O1xyXG4gICAgbGV0IGRhdGE6IFJvd0NoYW5nZSA9IHtcclxuICAgICAgcm93OiByb3csXHJcbiAgICAgIGluZGV4OiBpbmRleCxcclxuICAgIH07XHJcbiAgICB0aGlzLmlubGluZUNoYW5nZS5lbWl0KGRhdGEpO1xyXG4gICAgdGhpcy50YWJsZURhdGFbaW5kZXhdWydlZGl0YWJsZSddID0gZmFsc2U7XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCB3aWxsIHNhdmUgYW5kIHVwZGF0ZSB0aGUgY2VsbCBlZGl0aW5nIGRhdGEgYW5kIGVtaXQgdGhlIHVwZGF0ZSByb3cgYW5kIGluZGV4LlxyXG4gICAqL1xyXG4gIHNhdmVDZWxsRWRpdGluZygpIHtcclxuICAgIHRoaXMuY2VsbEVkaXRpbmcgPSB7fTtcclxuICAgIGxldCBpbmRleCA9IHRoaXMuY3VycmVudFJvd0luZGV4O1xyXG4gICAgaWYgKGluZGV4ID4gLTEpIHtcclxuICAgICAgaWYgKHRoaXMuY2VsbEVkaXRpbmdUZW1wbGF0ZVJlZikge1xyXG4gICAgICAgIGxldCBjaGFuZ2VkRGF0YSA9IHRoaXMuc2VydmljZS5zZWxlY3RlZFJvdy52YWx1ZTtcclxuICAgICAgICBpZiAoY2hhbmdlZERhdGEpIHtcclxuICAgICAgICAgIHRoaXMudGFibGVEYXRhW2luZGV4XSA9IHsgLi4uY2hhbmdlZERhdGEgfTtcclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy50YWJsZURhdGFbaW5kZXhdID0geyAuLi50aGlzLnJvd0RhdGFUZW1wWydlJyArIGluZGV4XSB9O1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuZGF0YVNvdXJjZSA9IG5ldyBNYXRUYWJsZURhdGFTb3VyY2UodGhpcy50YWJsZURhdGEpO1xyXG4gICAgICB0aGlzLnJvd0RhdGFUZW1wWydlJyArIGluZGV4XSA9IHt9O1xyXG4gICAgICBsZXQgZGF0YTogUm93Q2hhbmdlID0ge1xyXG4gICAgICAgIHJvdzogeyAuLi50aGlzLnRhYmxlRGF0YVtpbmRleF0gfSxcclxuICAgICAgICBpbmRleDogaW5kZXgsXHJcbiAgICAgIH07XHJcbiAgICAgIHRoaXMuY3VycmVudFJvd0luZGV4ID0gLTE7XHJcbiAgICAgIHRoaXMuY2VsbENoYW5nZS5lbWl0KGRhdGEpO1xyXG4gICAgfVxyXG4gIH1cclxuICAvKipcclxuICAgKiBAZGVzY3JpcHRpb24gVGhpcyBtZXRob2Qgd2lsbCBkZWxldGUgdGhlIHJvdyBmcm9tIHRoZSBnaXZlbiBpbmRleCBhbmQgZW1pdCB0aGUgZGVsZXRlZCByb3cgYW5kIGluZGV4LlxyXG4gICAqIEBwYXJhbSByb3cgcm93IHRvIGJlIGRlbGV0ZWQuXHJcbiAgICogQHBhcmFtIGluZGV4IGluZGV4IG9mIHRoZSByb3cgdG8gYmUgZGVsZXRlZC5cclxuICAgKi9cclxuICBkZWxldGVSb3cocm93OiBhbnksIGluZGV4OiBudW1iZXIpIHtcclxuICAgIHRoaXMudGFibGVEYXRhLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICB0aGlzLmRhdGFTb3VyY2UgPSBuZXcgTWF0VGFibGVEYXRhU291cmNlKHRoaXMudGFibGVEYXRhKTtcclxuICAgIHRoaXMuZGF0YVNvdXJjZS5wYWdpbmF0b3IgPSB0aGlzLnBhZ2luYXRvcjtcclxuICAgIHRoaXMuZGF0YVNvdXJjZS5zb3J0ID0gdGhpcy5zb3J0O1xyXG4gICAgdGhpcy5yb3dEZWxldGVkLmVtaXQoeyByZW1vdmVkUm93OiByb3csIGZyb21JbmRleDogaW5kZXggfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBAZGVzY3JpcHRpb24gVGhpcyBtZXRob2Qgd2lsbCBleHBhbmQgb3IgY29sbGFwc2UgdGhlIHJvdyBhbmQgZW1pdCBleHBhbmQgZXZlbnQuXHJcbiAgICogQHBhcmFtIHJvdyByb3cgdG8gYmUgZXhwYW5kZWQgb3IgY29sbGFwc2VkLlxyXG4gICAqIEBwYXJhbSBleHBhbmQgdmFsdWUgdXNlZCB0byBleHBhbmQgb3IgY29sbGFwc2UgdGhlIHJvdy5cclxuICAgKiBAcGFyYW0gaW5kZXggaW5kZXggb2YgdGhlIHJvdy5cclxuICAgKi9cclxuICBleHBhbmRSb3cocm93OiBNVEV4Um93LCBleHBhbmQ6IGJvb2xlYW4sIGluZGV4OiBudW1iZXIpIHtcclxuICAgIGlmICh0aGlzLmV4cGFuZFJvd3MpIHtcclxuICAgICAgdGhpcy5leHBhbnNpb25DaGFuZ2UuZW1pdCh7IGRhdGE6IHJvdywgZXhwYW5kZWQ6IGV4cGFuZCwgaW5kZXg6IGluZGV4IH0pO1xyXG4gICAgICB0aGlzLmV4cGFuZGVkRWxlbWVudCA9IHRoaXMuZXhwYW5kZWRFbGVtZW50ID09PSByb3cgPyBudWxsIDogcm93O1xyXG4gICAgfVxyXG4gIH1cclxuICAvKipcclxuICAgKiBAZGVzY3JpcHRpb24gVGhpcyBtZXRob2QgaXMgdXNlZCB0byBzZXQgZGF0YSBmb3IgcG9wdXAgY29tcG9uZW50IGFuZCBvcGVuIGVkaXRpbmcgZGlhbG9nLlxyXG4gICAqIEBwYXJhbSByb3cgcm93IHdoaWNoIHVzZWQgd2FudCB0byBlZGl0LlxyXG4gICAqL1xyXG4gIG9wZW5FZGl0aW5nRGlhbG9nKHJvdzogTVRFeFJvdykge1xyXG4gICAgY29uc3QgZGlhbG9nQ29uZmlnID0gbmV3IE1hdERpYWxvZ0NvbmZpZygpO1xyXG4gICAgZGlhbG9nQ29uZmlnLmRpc2FibGVDbG9zZSA9IHRydWU7XHJcbiAgICBkaWFsb2dDb25maWcud2lkdGggPSAnNDAlJztcclxuICAgIGRpYWxvZ0NvbmZpZy5oZWlnaHQgPSAnNzAlJztcclxuICAgIGRpYWxvZ0NvbmZpZy5tYXhXaWR0aCA9ICcxMDAlJztcclxuICAgIGxldCByb3dEYXRhID0geyAuLi5yb3cgfTtcclxuICAgIGRpYWxvZ0NvbmZpZy5kYXRhID0ge1xyXG4gICAgICByb3c6IHJvd0RhdGEsXHJcbiAgICAgIGNvbHVtbnM6IFsuLi50aGlzLmNvbHVtbnNBcnJheV0sXHJcbiAgICAgIHRlbXBsYXRlUmVmOiB0aGlzLnBvcHVwRWRpdGluZ1RlbXBsYXRlUmVmLFxyXG4gICAgfTtcclxuICAgIHRoaXMuZGlhbG9nXHJcbiAgICAgIC5vcGVuKEVkaXRpbmdDb21wb25lbnQsIGRpYWxvZ0NvbmZpZylcclxuICAgICAgLmFmdGVyQ2xvc2VkKClcclxuICAgICAgLnN1YnNjcmliZSgoZGF0YSkgPT4ge1xyXG4gICAgICAgIGxldCBpbmRleCA9IHRoaXMudGFibGVEYXRhLmluZGV4T2Yocm93KTtcclxuICAgICAgICBpZiAoZGF0YSAmJiBpbmRleCA+IC0xKSB7XHJcbiAgICAgICAgICB0aGlzLnRhYmxlRGF0YVtpbmRleF0gPSBkYXRhO1xyXG4gICAgICAgICAgdGhpcy5kYXRhU291cmNlID0gbmV3IE1hdFRhYmxlRGF0YVNvdXJjZSh0aGlzLnRhYmxlRGF0YSk7XHJcbiAgICAgICAgICBsZXQgZGF0YUNoYW5nZTogUm93Q2hhbmdlID0ge1xyXG4gICAgICAgICAgICByb3c6IGRhdGEsXHJcbiAgICAgICAgICAgIGluZGV4OiBpbmRleCxcclxuICAgICAgICAgIH07XHJcbiAgICAgICAgICB0aGlzLnBvcHVwQ2hhbmdlLmVtaXQoZGF0YUNoYW5nZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICB9XHJcbiAgLyoqXHJcbiAgICogQGRlc2NyaXB0aW9uIHVzZWQgdG8gY2hlY2sgd2hldGhlciBhbGwgcm93cyBhcmUgc2VsZWN0ZWQuXHJcbiAgICovXHJcbiAgaXNBbGxTZWxlY3RlZCgpIHtcclxuICAgIGNvbnN0IG51bVNlbGVjdGVkID0gdGhpcy5zZWxlY3Rpb24uc2VsZWN0ZWQubGVuZ3RoO1xyXG4gICAgY29uc3QgbnVtUm93cyA9IHRoaXMuZGF0YVNvdXJjZS5kYXRhLmxlbmd0aDtcclxuICAgIHJldHVybiBudW1TZWxlY3RlZCA9PT0gbnVtUm93cztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiB0aGlzIG1ldGhvZCBpcyB1c2VkIHRvIHRvZ2dsZSB0aGUgYWxsIGFuZCBubyByb3dzIHNlbGVjdGlvbi5cclxuICAgKi9cclxuICB0b2dnbGVBbGxSb3dzKCkge1xyXG4gICAgaWYgKHRoaXMuaXNBbGxTZWxlY3RlZCgpKSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0aW9uLmNsZWFyKCk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIHRoaXMuc2VsZWN0aW9uLnNlbGVjdCguLi50aGlzLmRhdGFTb3VyY2UuZGF0YSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBAZGVzY3JpcHRpb24gVGhpcyBtZXRob2QgaXMgdXNlZCByZXR1cm4gYXJpYS1sYWJlbCBmb3Igc2VsZWN0aW9uIGNvbHVtbiBjaGVja2JveHMuXHJcbiAgICogQHBhcmFtIHJvdyByb3cgZnJvbSB0YWJsZS5cclxuICAgKiBAcmV0dXJucyBsYWJlbHMgZm9yIHNlbGVjdGlvbiBjb2x1bW4gY2hlY2tib3hzLlxyXG4gICAqL1xyXG4gIGNoZWNrYm94TGFiZWwocm93PzogYW55KTogc3RyaW5nIHtcclxuICAgIGlmICghcm93KSB7XHJcbiAgICAgIHJldHVybiBgJHt0aGlzLmlzQWxsU2VsZWN0ZWQoKSA/ICdkZXNlbGVjdCcgOiAnc2VsZWN0J30gYWxsYDtcclxuICAgIH1cclxuICAgIHJldHVybiBgJHt0aGlzLnNlbGVjdGlvbi5pc1NlbGVjdGVkKHJvdykgPyAnZGVzZWxlY3QnIDogJ3NlbGVjdCd9IHJvdyAke1xyXG4gICAgICByb3cucG9zaXRpb24gKyAxXHJcbiAgICB9YDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiBjcmVhdGUgZm9ybSBjb250cm9sIGZvciBjb2x1bW5zIGZvciBoaWRpbmcgYW5kIGFuZCBwaW5uaW5nIHB1cnBvc2VcclxuICAgKiBAcGFyYW0gY29sdW1ucyBsaXN0IG9mIGNvbHVtbnMgdG8gYmUgZGlzcGxheWVkXHJcbiAgICovXHJcbiAgc2V0VG9vbGJhck1lbnVDb250cm9scyhjb2x1bW5zOiBNVEV4Q29sdW1uW10pIHtcclxuICAgIGlmIChjb2x1bW5zLmxlbmd0aCA+IDAgJiYgdGhpcy5zaG93VG9vbGJhcikge1xyXG4gICAgICBjb25zdCBncm91cCA9IHRoaXMuZm9ybUJ1aWxkZXJzU2VydmljZS5ncm91cCh7fSk7XHJcbiAgICAgIGNvbHVtbnMuZm9yRWFjaCgoY29sdW1uOiBNVEV4Q29sdW1uKSA9PiB7XHJcbiAgICAgICAgY29uc3QgY29udHJvbCA9IHRoaXMuZm9ybUJ1aWxkZXJzU2VydmljZS5jb250cm9sKHRydWUpO1xyXG4gICAgICAgIGdyb3VwLmFkZENvbnRyb2woY29sdW1uLmZpZWxkLCBjb250cm9sKTtcclxuICAgICAgfSk7XHJcbiAgICAgIHRoaXMuaGlkZVNob3dNZW51R3JvdXAgPSBncm91cDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEBwYXJhbSBjb2x1bW4gY3VycmVudCBjb2x1bW5cclxuICAgKiBAcGFyYW0gZXZlbnQgbW91c2UgZXZlbnQgdXNlZCB0byBzZXQgdGhlIG1lbnUgcG9zaXRpb25cclxuICAgKi9cclxuICBvcGVuUGlubmFibGVQcm9wZXJ0eU1lbnUoY29sdW1uOiBNVEV4Q29sdW1uLCBldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xyXG4gICAgdGhpcy5tZW51WCA9IGV2ZW50LmNsaWVudFg7XHJcbiAgICB0aGlzLm1lbnVZID0gZXZlbnQuY2xpZW50WTtcclxuICAgIGxldCBvcHRpb25zOiBNVEV4Q29sdW1uUGluT3B0aW9uW10gPSBbXHJcbiAgICAgIHtcclxuICAgICAgICBsYWJlbDogJ1BpbiBMZWZ0JyxcclxuICAgICAgICB2YWx1ZTogJ2xlZnQnLFxyXG4gICAgICAgIHNlbGVjdGVkOiBmYWxzZSxcclxuICAgICAgICBmaWVsZDogY29sdW1uLmZpZWxkLFxyXG4gICAgICB9LFxyXG4gICAgICB7XHJcbiAgICAgICAgbGFiZWw6ICdQaW4gUmlnaHQnLFxyXG4gICAgICAgIHZhbHVlOiAncmlnaHQnLFxyXG4gICAgICAgIHNlbGVjdGVkOiBmYWxzZSxcclxuICAgICAgICBmaWVsZDogY29sdW1uLmZpZWxkLFxyXG4gICAgICB9LFxyXG4gICAgICB7IGxhYmVsOiAnTm8gUGluJywgdmFsdWU6IG51bGwsIHNlbGVjdGVkOiBmYWxzZSwgZmllbGQ6IGNvbHVtbi5maWVsZCB9LFxyXG4gICAgXTtcclxuICAgIGlmIChjb2x1bW4ucGlubmVkICYmIGNvbHVtbi5waW5uZWQgIT09IG51bGwpIHtcclxuICAgICAgb3B0aW9ucy5mb3JFYWNoKChvcHQ6IE1URXhDb2x1bW5QaW5PcHRpb24pID0+IHtcclxuICAgICAgICBpZiAob3B0LnZhbHVlID09PSBjb2x1bW4ucGlubmVkKSB7XHJcbiAgICAgICAgICBvcHQuc2VsZWN0ZWQgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9IGVsc2UgaWYgKGNvbHVtbi5waW5uZWQgPT0gbnVsbCB8fCBjb2x1bW4ucGlubmVkID09ICdudWxsJykge1xyXG4gICAgICBvcHRpb25zWzJdLnNlbGVjdGVkID0gdHJ1ZTtcclxuICAgIH1cclxuICAgIHRoaXMuY29sdW1uUGlubmluZ09wdGlvbnMgPSBvcHRpb25zO1xyXG4gICAgdGhpcy5jb2x1bW5NZW51VHJpZ2dlci5vcGVuTWVudSgpO1xyXG4gIH1cclxuICAvKipcclxuICAgKiBAZGVzY3JpcHRpb24gVGhpcyBtZXRob2QgaXMgdXNlZCB0byByZXNldCBtZW51IGNoZWNrcyB3aGVuIHJlcXVpcmVkLlxyXG4gICAqL1xyXG4gIHJlc2V0TWVudUNoZWNrcygpIHtcclxuICAgIHRoaXMuaGlkZVNob3dNZW51Q3RybCA9IGZhbHNlO1xyXG4gICAgdGhpcy5zaG93SGlkZUNvbHVtbnNBcnJheSA9IFtdO1xyXG4gICAgdGhpcy5jb2x1bW5QaW5NZW51Q3RybCA9IGZhbHNlO1xyXG4gICAgdGhpcy5jb2x1bW5QaW5uaW5nT3B0aW9ucyA9IFtdO1xyXG4gIH1cclxuICAvKipcclxuICAgKiBAZGVzY3JpcHRpb24gVGhpcyBtZXRob2QgaXMgdXNlZCB0byBmaWx0ZXIgY29sdW1ucyBmb3IgbWVudXMgbGlrZSBwaW5uaW5nIG9yIGhpZGUgc2hvdyBtZW51LlxyXG4gICAqIEBwYXJhbSB2YWx1ZSBzZWFyY2ggdmFsdWUgdG8gZmlsdGVyIGNvbHVubXNcclxuICAgKi9cclxuICBmaWx0ZXJDb2x1bW5zKHZhbHVlOiBzdHJpbmcpIHtcclxuICAgIGlmICh2YWx1ZSAhPT0gJycpIHtcclxuICAgICAgdGhpcy5zaG93SGlkZUNvbHVtbnNBcnJheSA9IHRoaXMuY29sdW1uc0FycmF5LmZpbHRlcihcclxuICAgICAgICAoY29sOiBNVEV4Q29sdW1uKSA9PiB7XHJcbiAgICAgICAgICByZXR1cm4gY29sLmhlYWRlciEudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh2YWx1ZS50b0xvd2VyQ2FzZSgpKTtcclxuICAgICAgICB9XHJcbiAgICAgICk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLnNob3dIaWRlQ29sdW1uc0FycmF5ID0gdGhpcy5jb2x1bW5zQXJyYXk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIG9wZW4gaGlkZSBzaG93IGNvbHVtbiBtZW51LlxyXG4gICAqIEBwYXJhbSBjb2x1bW5zIGNvbHVtbnMgYXJyYXkgdG8gZGlzcGxheSBpbiBoaWRlIHNob3cgbWVudS5cclxuICAgKi9cclxuICBvcGVuSGlkZVNob3dNZW51KGNvbHVtbnM6IE1URXhDb2x1bW5bXSkge1xyXG4gICAgdGhpcy5zaG93SGlkZUNvbHVtbnNBcnJheSA9IFsuLi5jb2x1bW5zXTtcclxuICAgIHRoaXMuY29sdW1uTWVudVRyaWdnZXIub3Blbk1lbnUoKTtcclxuICB9XHJcbiAgLyoqXHJcbiAgICogQHBhcmFtIHZhbHVlcyBjb2x1bW5zXHJcbiAgICovXHJcbiAgdXBkYXRlQ29sdW1uc0hpZGVTaG93KHZhbHVlczogQ29sdW1uVmlzaWJpbGl0eSkge1xyXG4gICAgbGV0IGtleXMgPSBPYmplY3Qua2V5cyh2YWx1ZXMpO1xyXG4gICAga2V5cy5mb3JFYWNoKChrZXk6IHN0cmluZykgPT4ge1xyXG4gICAgICB0aGlzLnNob3dIaWRlQ29sdW1uKGtleSwgdmFsdWVzW2tleV0pO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBAZGVzY3JpcHRpb24gVGhpcyBtZXRob2QgaXMgY2FsbGVkIHdoZW4gdGhlIHRhYmxlIHJvd3MgYXJlIHNjcm9sbGVkLlxyXG4gICAqIEBwYXJhbSBldmVudCBzY3JvbGwgZXZlbnRcclxuICAgKi9cclxuICBvblNjcm9sbChldmVudDogYW55KSB7XHJcbiAgICB0aGlzLnNjcm9sbC5lbWl0KGV2ZW50KTtcclxuICB9XHJcbiAgLyoqXHJcbiAgICogQHBhcmFtIHJvdyByb3cgdG8gYmUgdG9nZ2xlZFxyXG4gICAqIEBwYXJhbSBpbmRleCBpbmRleCBvZiB0b2dnbGVkIHJvd1xyXG4gICAqL1xyXG4gIHNldFNlbGVjdGVkUm93cyhyb3c6IGFueSwgaW5kZXg6IG51bWJlcikge1xyXG4gICAgdGhpcy5zZWxlY3Rpb24udG9nZ2xlKHJvdyk7XHJcbiAgICBpZiAodGhpcy5zZWxlY3Rpb24uaXNTZWxlY3RlZChyb3cpKSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0aW9uQ2hhbmdlZC5lbWl0KHsgcm93OiByb3csIGluZGV4OiBpbmRleCwgaXNTZWxlY3RlZDogdHJ1ZSB9KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0aW9uQ2hhbmdlZC5lbWl0KHsgcm93OiByb3csIGluZGV4OiBpbmRleCwgaXNTZWxlY3RlZDogZmFsc2UgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG4vKipcclxuICogQGRlc2NyaXB0aW9uIFRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gZGlzcGxheSBhbGwgaGlkZGVuIHJvd3MuXHJcbiAqL1xyXG4gIHNob3dIaWRkZW5Sb3dzKCkge1xyXG4gICAgdGhpcy5oaWRlUm93cyA9IGZhbHNlO1xyXG4gICAgdGhpcy5zZWxlY3Rpb24uY2xlYXIoKTtcclxuICAgIHRoaXMuaGlkZGVuQ3RybC5jbGVhcigpO1xyXG4gIH1cclxuLyoqXHJcbiAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIGhpZGUgYWxsIHNlbGVjdGVkIHJvd3MuXHJcbiAqL1xyXG4gIGhpZGVTZWxlY3RlZFJvd3MoKSB7XHJcbiAgICBpZiAoIXRoaXMuc2VsZWN0aW9uLmlzRW1wdHkoKSkge1xyXG4gICAgICBsZXQgdmFsdWVzID0gWy4uLnRoaXMuc2VsZWN0aW9uLnNlbGVjdGVkXTtcclxuICAgICAgdmFsdWVzLmZvckVhY2goKHZhbHVlKSA9PiB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmhpZGRlbkN0cmwuaXNTZWxlY3RlZCh2YWx1ZSkpIHtcclxuICAgICAgICAgIHRoaXMuaGlkZGVuQ3RybC50b2dnbGUodmFsdWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICAgIHRoaXMuc2VsZWN0aW9uLmNsZWFyKCk7XHJcbiAgICAgIHRoaXMuaGlkZVJvd3MgPSB0cnVlO1xyXG4gICAgfVxyXG4gIH1cclxuLyoqXHJcbiAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIHJlY2FsY3VsYXRlIHRoZSByZXF1aXJlZCB2YWx1ZXMgZm9yIHRhYmxlLlxyXG4gKi9cclxuICByZUNhbCgpIHtcclxuICAgIGlmICh0aGlzLnNob3dQYWdpbmF0b3IpIHtcclxuICAgICAgdGhpcy5kYXRhU291cmNlLnBhZ2luYXRvciA9IHRoaXMucGFnaW5hdG9yO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMuc29ydGluZykge1xyXG4gICAgICB0aGlzLmRhdGFTb3VyY2Uuc29ydCA9IHRoaXMuc29ydDtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLmNvbHVtbkZpbHRlcikge1xyXG4gICAgICB0aGlzLmRhdGFTb3VyY2UuZmlsdGVyUHJlZGljYXRlID0gdGhpcy5jcmVhdGVGaWx0ZXIoKTtcclxuICAgIH1cclxuICB9XHJcbi8qKlxyXG4gKiBAZGVzY3JpcHRpb24gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGluIGNvbnN0cnVjdG9yIG1ldGhvZCB0byBhZGQgU1ZHcyBpbnRvIGljb24gcmVnaXN0cmF0aW9uLlxyXG4gKi9cclxuICBhZGRJY29uc1RvUmVnaXN0cnkoKSB7XHJcbiAgICBsZXQgeSA9IHRoaXMuZG9tU2FuaXRpemVyLmJ5cGFzc1NlY3VyaXR5VHJ1c3RSZXNvdXJjZVVybChcclxuICAgICAgYGFzc2V0cy9waW5SaWdodC5zdmdgXHJcbiAgICApO1xyXG4gICAgbGV0IGljb25OYW1lcyA9IFsncGluTGVmdCcsICdwaW5SaWdodCcsICdwaW5Ob25lJywgJ3Bpbm5lZCcsICdwaW5JY29uJ107XHJcbiAgICBpY29uTmFtZXMuZm9yRWFjaCgoaWNvbikgPT4ge1xyXG4gICAgICB0aGlzLm1hdEljb25SZWdpc3RyeS5hZGRTdmdJY29uKFxyXG4gICAgICAgIGljb24sXHJcbiAgICAgICAgdGhpcy5kb21TYW5pdGl6ZXIuYnlwYXNzU2VjdXJpdHlUcnVzdFJlc291cmNlVXJsKFxyXG4gICAgICAgICAgYGFzc2V0cy8ke2ljb259LnN2Z2BcclxuICAgICAgICApXHJcbiAgICAgICk7XHJcbiAgICB9KTtcclxuICB9XHJcbi8qKlxyXG4gKiBAZGVzY3JpcHRpb24gVGhpcyBtZXRob2QgaXMgdXNlZCB0byBleHBvcnQgdGFibGUgZGF0YS5cclxuICogQHBhcmFtIHR5cGUgdHlwZSBvZiBmaWxlIHRvIGJlIGV4cG9ydGVkLlxyXG4gKi9cclxuICBleHBvcnRUYWJsZSh0eXBlOiBzdHJpbmcpIHtcclxuICAgIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21hdFRhYmxlRXh0JyArIHRoaXMudGFibGVJRCk7XHJcbiAgICB2YXIgd3M6IFhMU1guV29ya1NoZWV0ID0gWExTWC51dGlscy50YWJsZV90b19zaGVldChlbGVtZW50KTtcclxuICAgIHdzID0gdGhpcy53cml0ZVNoZWV0RGF0YSh3cyk7XHJcbiAgICBjb25zdCB3YjogWExTWC5Xb3JrQm9vayA9IFhMU1gudXRpbHMuYm9va19uZXcoKTtcclxuICAgIFhMU1gudXRpbHMuYm9va19hcHBlbmRfc2hlZXQod2IsIHdzLCAnU2hlZXQxJyk7XHJcbiAgICBYTFNYLndyaXRlRmlsZSh3YiwgYHRhYmxlc2hlZXRzLiR7dHlwZX1gKTtcclxuICB9XHJcbiAgLyoqXHJcbiAgICogQGRlc2NyaXB0aW9uIFRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gc3BsaXQgbmFtZSBvZiBmaWx0ZXIgcm93IGhlYWRlciB0byBnZXQgaW5kZXguXHJcbiAgICogQHBhcmFtIHZhbHVlIHZhbHVlIHRvIGJlIHNwbGl0ZWQgZm9yIGluZGV4LlxyXG4gICAqIEByZXR1cm5zIFdpbGwgcmV0dXJuIGluZGV4IG9mIGNvbHVtbiBmcm9tIHZhbHVlLlxyXG4gICAqL1xyXG4gIHJldHVybkluZGV4KHZhbHVlOiBzdHJpbmcpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIE51bWJlcih2YWx1ZS5zcGxpdCgnXycpWzFdKTtcclxuICB9XHJcbi8qKlxyXG4gKiBAZGVzY3JpcHRpb24gVGhpcyBtZXRob2QgaXMgdXNlZCB0byBtYW5hZ2UgY29sdW1uIGZpbHRlcmluZywgZXhwYW5kZWQgZGF0YSBmb3IgZXhwb3J0aW5nLlxyXG4gKiBAcGFyYW0gd3Mgd29yayBzaGVldFxyXG4gKiBAcmV0dXJucyBjdXN0b20gZ2VuZXJhdGVkIHdvcmtzaGVldCB0byBiZSB1c2VkIGluIGV4cG9ydC5cclxuICovXHJcbiAgd3JpdGVTaGVldERhdGEod3M6IFhMU1guV29ya1NoZWV0KTogWExTWC5Xb3JrU2hlZXQge1xyXG4gICAgbGV0IGRpc3BsYXllZENvbHVtbnMgPSB0aGlzLmdldERpc3BsYXllZENvbHVtbnMoKTtcclxuICAgIHZhciBuTWVyZ2VzID0gdGhpcy5nZXRNZXJnZUluZGV4KHdzWychbWVyZ2VzJ10gfHwgW10pO1xyXG4gICAgdmFyIG1lcmdlcyA9IHdzWychbWVyZ2VzJ10gfHwgW107XHJcbiAgICBsZXQgZGF0YTogWExTWC5Xb3JrU2hlZXQgPSB7XHJcbiAgICAgICchY29scyc6IFtdLFxyXG4gICAgICAnIXJvd3MnOiBbXSxcclxuICAgICAgJyFtZXJnZXMnOiBuTWVyZ2VzLFxyXG4gICAgfTtcclxuICAgIHZhciByYW5nZSA9IFhMU1gudXRpbHMuZGVjb2RlX3JhbmdlKHdzWychcmVmJ10gfHwgJycpO1xyXG4gICAgbGV0IGV4dHJhY29sdW1ucyA9IFsncG9wdXAnLCAnZGVsZXRlJywgJ3NlbGVjdCcsICdlZGl0J107XHJcbiAgICBsZXQga2V5cyA9IE9iamVjdC5rZXlzKHdzKTtcclxuICAgIGxldCBuS2V5ID0gJ0EnO1xyXG4gICAga2V5cy5mb3JFYWNoKChrZXksIGkpID0+IHtcclxuICAgICAgaWYgKHdzW2tleV0/LnYgJiYgdHlwZW9mIHdzW2tleV0/LnYgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgaWYgKFxyXG4gICAgICAgICAgIWV4dHJhY29sdW1ucy5pbmNsdWRlcyh3c1trZXldLnYudG9Mb3dlckNhc2UoKSkgJiZcclxuICAgICAgICAgIGRpc3BsYXllZENvbHVtbnMuaW5jbHVkZXMod3Nba2V5XS52LnRvTG93ZXJDYXNlKCkpXHJcbiAgICAgICAgKSB7XHJcbiAgICAgICAgICBsZXQgbGFzdFJvd0luZGV4ID0gcmFuZ2U/LmU/LnI7XHJcbiAgICAgICAgICBkYXRhW2tleV0gPSB3c1trZXldO1xyXG4gICAgICAgICAgbGV0IGNociA9IGtleS5jaGFyQXQoMCk7XHJcbiAgICAgICAgICBmb3IgKGxldCBqID0gMjsgaiA8PSBsYXN0Um93SW5kZXg7IGorKykge1xyXG4gICAgICAgICAgICBpZiAoXHJcbiAgICAgICAgICAgICAgd3NbY2hyICsgKGogKyAxKV0gIT09IHVuZGVmaW5lZCAmJlxyXG4gICAgICAgICAgICAgICh0eXBlb2Ygd3NbY2hyICsgKGogKyAxKV0udiA9PT0gJ3N0cmluZycgfHxcclxuICAgICAgICAgICAgICAgIHR5cGVvZiB3c1tjaHIgKyAoaiArIDEpXS52ID09PSAnbnVtYmVyJylcclxuICAgICAgICAgICAgKSB7XHJcbiAgICAgICAgICAgICAgZGF0YVtuS2V5ICsgal0gPSB3c1tjaHIgKyAoaiArIDEpXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgbktleSA9IFN0cmluZy5mcm9tQ2hhckNvZGUobktleS5jaGFyQ29kZUF0KDApICsgMSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICAgIGlmICh0aGlzLnJvd1NlbGVjdGlvbikge1xyXG4gICAgICBsZXQgY2hyID0gJ0EnO1xyXG4gICAgICBmb3IgKGxldCBpID0gMTsgaSA8IHJhbmdlLmUuYyArIDE7IGkrKykge1xyXG4gICAgICAgIGRhdGFbY2hyICsgMV0gPSBkYXRhW1N0cmluZy5mcm9tQ2hhckNvZGUoY2hyLmNoYXJDb2RlQXQoMCkgKyAxKSArIDFdO1xyXG4gICAgICAgIGNociA9IFN0cmluZy5mcm9tQ2hhckNvZGUoY2hyLmNoYXJDb2RlQXQoMCkgKyAxKTtcclxuICAgICAgICBpZiAoaSA9PSByYW5nZS5lLmMpIHtcclxuICAgICAgICAgIGRhdGFbY2hyICsgMV0gPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5yb3dTZWxlY3Rpb24gJiYgdGhpcy5leHBhbmRSb3dzKSB7XHJcbiAgICAgIG1lcmdlcy5mb3JFYWNoKChtZXJnZSkgPT4ge1xyXG4gICAgICAgIGRhdGFbJ0EnICsgbWVyZ2Uucy5yXSA9IHdzWydBJyArIChtZXJnZS5zLnIgKyAxKV07XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgcmFuZ2UuZS5yLS07XHJcbiAgICBsZXQgblJlZiA9IFhMU1gudXRpbHMuZW5jb2RlX3JhbmdlKHJhbmdlKTtcclxuICAgIGRhdGFbJyFyZWYnXSA9IG5SZWY7XHJcbiAgICBkYXRhWychZnVsbHJlZiddID0gblJlZjtcclxuICAgIHJldHVybiBkYXRhO1xyXG4gIH1cclxuICBnZXRNZXJnZUluZGV4KG1lcmdlczogYW55W10pIHtcclxuICAgIHZhciBhcnI6IGFueVtdID0gW107XHJcbiAgICBtZXJnZXMuZm9yRWFjaCgoZWxlbWVudDogYW55KSA9PiB7XHJcbiAgICAgIGFyci5wdXNoKHtcclxuICAgICAgICBlOiB7XHJcbiAgICAgICAgICByOiBlbGVtZW50LmUuciA9PSAwID8gZWxlbWVudC5lLnIgOiBlbGVtZW50LmUuciAtIDEsXHJcbiAgICAgICAgICBjOiBlbGVtZW50LmUuYyxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHM6IHtcclxuICAgICAgICAgIHI6IGVsZW1lbnQucy5yID09IDAgPyBlbGVtZW50LnMuciA6IGVsZW1lbnQucy5yIC0gMSxcclxuICAgICAgICAgIGM6IGVsZW1lbnQucy5jLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gYXJyO1xyXG4gIH1cclxufVxyXG4iLCI8ZGl2ICBbc3R5bGUud2lkdGhdPVwidGFibGVXaWR0aFwiPlxyXG4gICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZ2xvYmFsLXNlYXJjaC1maWVsZFwiIGFwcGVhcmFuY2U9XCJmaWxsXCIgKm5nSWY9XCJnbG9iYWxTZWFyY2hcIj5cclxuICAgICAgICA8bWF0LWxhYmVsPlNlYXJjaDwvbWF0LWxhYmVsPlxyXG4gICAgICAgIDxpbnB1dCBtYXRJbnB1dCBbbmdNb2RlbF09XCJnbG9iYWxGaWx0ZXJcIiAobmdNb2RlbENoYW5nZSk9XCJhcHBseUdsb2JhbEZpbHRlcigkZXZlbnQpXCIgcGxhY2Vob2xkZXI9XCJFeC4gTWlhXCIgI2lucHV0PlxyXG4gICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgIDxtYXQtdG9vbGJhciBjbGFzcz1cInRvb2xiYXItY29udGFpbmVyXCIgKm5nSWY9XCJzaG93VG9vbGJhclwiIFtzdHlsZS5oZWlnaHRdPVwidG9vbGJhckhlaWdodD90b29sYmFySGVpZ2h0Oic1MHB4J1wiPlxyXG4gICAgICAgIDxzcGFuIGNsYXNzPVwidG9vbGJhci10aXRsZVwiICpuZ0lmPVwidG9vbGJhclRpdGxlXCI+e3t0b29sYmFyVGl0bGV9fTwvc3Bhbj5cclxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwidG9vbGJhclRlbXBsYXRlUmVmXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwidG9vbGJhclRlbXBsYXRlUmVmXCI+PC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJleGFtcGxlLXNwYWNlclwiPjwvc3Bhbj5cclxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwicm93U2VsZWN0aW9uIHx8IG11bHRpUm93U2VsZWN0aW9uXCI+XHJcbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJoaWRlLWJ1dHRvblwiIG1hdC1zdHJva2VkLWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiAoY2xpY2spPVwiaGlkZVNlbGVjdGVkUm93cygpXCI+XHJcbiAgICAgICAgICAgICAgICBIaWRlIFJvd3NcclxuICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJoaWRlLWJ1dHRvblwiIG1hdC1zdHJva2VkLWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiAoY2xpY2spPVwic2hvd0hpZGRlblJvd3MoKVwiPlxyXG4gICAgICAgICAgICAgICAgU2hvdyBBbGwgUm93c1xyXG4gICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICA8YnV0dG9uICpuZ0lmPVwiY29sdW1uSGlkYWJsZVwiIGNsYXNzPVwiaGlkZS1idXR0b25cIiBtYXQtc3Ryb2tlZC1idXR0b24gY29sb3I9XCJwcmltYXJ5XCJcclxuICAgICAgICAgICAgKGNsaWNrKT1cIm9wZW5NZW51KCdoaWRlU2hvdycsJGV2ZW50KVwiIG1hdFRvb2x0aXA9XCJDb2x1bW4gVmlzaWJpbGl0eVwiIG1hdFRvb2x0aXBQb3NpdGlvbj1cImFib3ZlXCI+XHJcbiAgICAgICAgICAgIDxtYXQtaWNvbj52aXNpYmlsaXR5PC9tYXQtaWNvbj5cclxuICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICA8YnV0dG9uICpuZ0lmPVwiY29sdW1uUGlubmFibGVcIiBjbGFzcz1cInBpbi1idXR0b25cIiBtYXQtc3Ryb2tlZC1idXR0b24gY29sb3I9XCJwcmltYXJ5XCJcclxuICAgICAgICAgICAgKGNsaWNrKT1cIm9wZW5NZW51KCdjb2x1bW5QaW4nLCRldmVudClcIiBtYXRUb29sdGlwPVwiQ29sdW1uIFBpbm5pbmdcIj5cclxuICAgICAgICAgICAgPG1hdC1pY29uIHN2Z0ljb249XCJwaW5JY29uXCI+PC9tYXQtaWNvbj5cclxuICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICA8YnV0dG9uICpuZ0lmPVwiZXhwb3J0QnV0dG9uRW5hYmxlXCIgY2xhc3M9XCJleHBvcnQtYnV0dG9uXCIgbWF0LXN0cm9rZWQtYnV0dG9uIGNvbG9yPVwicHJpbWFyeVwiXHJcbiAgICAgICAgICAgIChjbGljayk9XCJvcGVuTWVudSgnZXhwb3J0JywkZXZlbnQpXCIgbWF0VG9vbHRpcD1cIlRhYmxlIERhdGEgRXhwb3J0XCI+XHJcbiAgICAgICAgICAgIDxtYXQtaWNvbj5pbXBvcnRfZXhwb3J0PC9tYXQtaWNvbj4gPHNwYW4+RXhwb3J0PC9zcGFuPlxyXG4gICAgICAgICAgICA8bWF0LWljb24+ZXhwYW5kX21vcmU8L21hdC1pY29uPlxyXG4gICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgIDxkaXYgc3R5bGU9XCJ2aXNpYmlsaXR5OiBoaWRkZW47IHBvc2l0aW9uOmZpeGVkXCIgW21hdE1lbnVUcmlnZ2VyRm9yXT1cIm1lbnVcIiBbc3R5bGUubGVmdC5weF09XCJtZW51WFwiXHJcbiAgICAgICAgICAgIFtzdHlsZS50b3AucHhdPVwibWVudVlcIj48L2Rpdj5cclxuICAgIDwvbWF0LXRvb2xiYXI+XHJcbiAgICA8bWF0LW1lbnUgI21lbnU9XCJtYXRNZW51XCIgKGNsb3NlZCk9XCJtZW51Q2xvc2VkKClcIiBpZD1cImV4cG9ydE1lbnVcIj5cclxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZXhwb3J0TWVudUN0cmxcIj5cclxuICAgICAgICAgICAgPG1hdC1vcHRpb24gKGNsaWNrKT1cImV4cG9ydFRhYmxlKCd4bHN4JylcIj5FeHBvcnQgdG8gRXhjZWw8L21hdC1vcHRpb24+XHJcbiAgICAgICAgICAgIDxtYXQtb3B0aW9uIChjbGljayk9XCJleHBvcnRUYWJsZSgnY3N2JylcIj5FeHBvcnQgdG8gQ1NWPC9tYXQtb3B0aW9uPlxyXG4gICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgPC9tYXQtbWVudT5cclxuICAgIDxkaXYgc3R5bGU9XCJ2aXNpYmlsaXR5OiBoaWRkZW47IHBvc2l0aW9uOmZpeGVkXCIgI2NvbHVtbk1lbnVUcmlnZ2VyPVwibWF0TWVudVRyaWdnZXJcIiBbbWF0TWVudVRyaWdnZXJGb3JdPVwiY29sdW1uTWVudVwiXHJcbiAgICAgICAgW3N0eWxlLmxlZnQucHhdPVwibWVudVhcIiBbc3R5bGUudG9wLnB4XT1cIm1lbnVZXCI+XHJcbiAgICA8L2Rpdj5cclxuICAgIDxtYXQtbWVudSAjY29sdW1uTWVudT1cIm1hdE1lbnVcIiAoY2xvc2VkKT1cInJlc2V0TWVudUNoZWNrcygpXCI+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInRvb2xiYXItbWVudS1jb250YWluZXJcIiAqbmdJZj1cImhpZGVTaG93TWVudUN0cmxcIiBbZm9ybUdyb3VwXT1cImhpZGVTaG93TWVudUdyb3VwXCJcclxuICAgICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxyXG4gICAgICAgICAgICA8aDQgY2xhc3M9XCJjb2x1bW4taGVhZGVyc1wiPlZpc2libGUgQ29sdW1uczwvaDQ+XHJcbiAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBhcHBlYXJhbmNlPVwiZmlsbFwiIHN0eWxlPVwid2lkdGg6IC13ZWJraXQtZmlsbC1hdmFpbGFibGU7XCI+XHJcbiAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPkZpbHRlciBDb2x1bW5zPC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgWyhuZ01vZGVsKV09XCJzaG93SGlkZUZpbHRlclwiIChuZ01vZGVsQ2hhbmdlKT1cImZpbHRlckNvbHVtbnMoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxPcHRpb25zXT1cIntzdGFuZGFsb25lOiB0cnVlfVwiPlxyXG4gICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2hvd0hpZGUtbWVudS1jb2x1bW5zLWxpc3RcIj5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0b29sYmFyLW1lbnUtaXRlbVwiICpuZ0Zvcj1cImxldCBjb2x1bW4gb2Ygc2hvd0hpZGVDb2x1bW5zQXJyYXlcIj5cclxuICAgICAgICAgICAgICAgICAgICA8bWF0LWNoZWNrYm94IGNvbG9yPVwicHJpbWFyeVwiIGNsYXNzPVwidG9vbGJhci1tZW51LWNoZWNrYm94XCIgc3R5bGU9XCJ3aWR0aDogbWF4LWNvbnRlbnQ7XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sTmFtZV09XCJjb2x1bW4uZmllbGRcIiAoY2hhbmdlKT1cInNldENvbHVtbkhpZGVTaG93KClcIj57e2NvbHVtbi5oZWFkZXJ9fTwvbWF0LWNoZWNrYm94PlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0b29sYmFyLW1lbnUtY29udGFpbmVyXCIgKm5nSWY9XCJjb2x1bW5QaW5NZW51Q3RybFwiIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cclxuICAgICAgICAgICAgPGg0IGNsYXNzPVwiY29sdW1uLWhlYWRlcnNcIj5QaW4gQ29sdW1uczwvaDQ+XHJcbiAgICAgICAgICAgIDxmb3JtIGNsYXNzPVwiZXhhbXBsZS1mb3JtXCI+XHJcbiAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT1cImZpbGxcIiBzdHlsZT1cIndpZHRoOiAtd2Via2l0LWZpbGwtYXZhaWxhYmxlO1wiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+RmlsdGVyIENvbHVtbnM8L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgWyhuZ01vZGVsKV09XCJzaG93SGlkZUZpbHRlclwiIChuZ01vZGVsQ2hhbmdlKT1cImZpbHRlckNvbHVtbnMoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsT3B0aW9uc109XCJ7c3RhbmRhbG9uZTogdHJ1ZX1cIj5cclxuICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgIDwvZm9ybT5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNob3dIaWRlLW1lbnUtY29sdW1ucy1saXN0XCI+XHJcbiAgICAgICAgICAgICAgICA8YXBwLWNvbHVtbi1waW5uaW5nIFtjb2x1bW5zXT1cInNob3dIaWRlQ29sdW1uc0FycmF5XCI+PC9hcHAtY29sdW1uLXBpbm5pbmc+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgPC9tYXQtbWVudT5cclxuXHJcbiAgICA8bWF0LXByb2dyZXNzLWJhciAqbmdJZj1cImxvYWRpbmdJbmRpY2F0b3JcIiBtb2RlPVwiaW5kZXRlcm1pbmF0ZVwiPjwvbWF0LXByb2dyZXNzLWJhcj5cclxuICAgIDxzZWN0aW9uIGlkPVwidGFibGVDb250YWluZXJcIiBjbGFzcz1cIm1hdC10YWJsZS1leHQtY29udGFpbmVyXCIgKHNjcm9sbCk9XCJvblNjcm9sbCgkZXZlbnQpXCJcclxuICAgICAgICBbc3R5bGUuaGVpZ2h0XT1cInRhYmxlSGVpZ2h0ID8gdGFibGVIZWlnaHQgOidtYXgtY29udGVudCdcIj5cclxuICAgICAgICA8dGFibGUgbWF0LXRhYmxlIFtpZF09XCInbWF0VGFibGVFeHQnK3RhYmxlSURcIiBbZGF0YVNvdXJjZV09XCJkYXRhU291cmNlXCIgbWF0U29ydCBjZGtEcm9wTGlzdFxyXG4gICAgICAgICAgICBjZGtEcm9wTGlzdE9yaWVudGF0aW9uPVwiaG9yaXpvbnRhbFwiIG11bHRpVGVtcGxhdGVEYXRhUm93cyAoY2RrRHJvcExpc3REcm9wcGVkKT1cIm9uRHJvcCgkZXZlbnQpXCJcclxuICAgICAgICAgICAgKGNsaWNrKT1cInNhdmVDZWxsRWRpdGluZygpXCIgW3N0eWxlLndpZHRoXT1cInNjcm9sbGJhckg/J21heC1jb250ZW50JzonMTAwJSdcIj5cclxuICAgICAgICAgICAgPCEtLSBSb3cgc2VsZWN0aW9uIGNvbHVtbiAtLT5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJzZWxlY3RcIj5cclxuICAgICAgICAgICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgY2RrRHJhZ0xvY2tBeGlzPVwieFwiIGNka0RyYWcgW2Nka0RyYWdEaXNhYmxlZF09XCIhZG5kQ29sdW1uc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggKGNoYW5nZSk9XCIkZXZlbnQgPyB0b2dnbGVBbGxSb3dzKCkgOiBudWxsXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW2NoZWNrZWRdPVwic2VsZWN0aW9uLmhhc1ZhbHVlKCkgJiYgaXNBbGxTZWxlY3RlZCgpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW2luZGV0ZXJtaW5hdGVdPVwic2VsZWN0aW9uLmhhc1ZhbHVlKCkgJiYgIWlzQWxsU2VsZWN0ZWQoKVwiIFthcmlhLWxhYmVsXT1cImNoZWNrYm94TGFiZWwoKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvbWF0LWNoZWNrYm94PlxyXG4gICAgICAgICAgICAgICAgPC90aD5cclxuICAgICAgICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCByb3c7bGV0IGkgPSBkYXRhSW5kZXhcIj5cclxuICAgICAgICAgICAgICAgICAgICA8bWF0LWNoZWNrYm94IChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIiAoY2hhbmdlKT1cIiRldmVudCA/IHNldFNlbGVjdGVkUm93cyhyb3csaSkgOiBudWxsXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW2NoZWNrZWRdPVwic2VsZWN0aW9uLmlzU2VsZWN0ZWQocm93KVwiIFthcmlhLWxhYmVsXT1cImNoZWNrYm94TGFiZWwocm93KVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvbWF0LWNoZWNrYm94PlxyXG4gICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzaG93Rm9vdGVyUm93XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPHRkIG1hdC1mb290ZXItY2VsbCAqbWF0Rm9vdGVyQ2VsbERlZj48L3RkPlxyXG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICA8IS0tZHluYW1pYyBjb2x1bW5zIGFyZSBiZWluZyBnZW5lcmF0ZWQgaGVyZS0tPlxyXG4gICAgICAgICAgICA8ZGl2IG1hdENvbHVtbkRlZj1cInt7Y29sdW1uWydmaWVsZCddfX1cIiBbc3RpY2t5XT1cImNvbHVtbi5waW5uZWQgPT0gJ2xlZnQnID8gdHJ1ZTpmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICBbc3RpY2t5RW5kXT1cImNvbHVtbi5waW5uZWQgPT0gJ3JpZ2h0JyA/IHRydWU6ZmFsc2VcIiAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGNvbHVtbnNBcnJheTsgbGV0IGkgPSBpbmRleFwiPlxyXG4gICAgICAgICAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBbc3R5bGUud2lkdGhdPVwiY29sdW1uLndpZHRoXCIgW3N0eWxlLm1heFdpZHRoXT1cImNvbHVtbi5tYXhXaWR0aFwiXHJcbiAgICAgICAgICAgICAgICAgICAgW3N0eWxlLm1pbldpZHRoXT1cImNvbHVtbi5taW5XaWR0aFwiIGNka0RyYWdMb2NrQXhpcz1cInhcIiBjZGtEcmFnIFtjZGtEcmFnRGlzYWJsZWRdPVwiIWRuZENvbHVtbnNcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtjb2x1bW5zUmVzaXphYmxlXT1cImNvbHVtblJlc2l6YWJsZVwiIFtpbmRleF09XCJpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCIhaGVhZGVyVGVtcGxhdGVSZWZcIiBtYXRUb29sdGlwPVwie3tjb2x1bW4uaGVhZGVyVG9vbHRpcD8udmFsdWV9fVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFttYXRUb29sdGlwUG9zaXRpb25dPVwiY29sdW1uPy5oZWFkZXJUb29sdGlwPy50b29sdGlwUG9zaXRpb24hXCIgbWF0LXNvcnQtaGVhZGVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCIhc29ydGluZyB8fCBjb2x1bW4uZGlzYWJsZWQgPT09IHRydWVcIj57e2NvbHVtbi5oZWFkZXJ9fTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaGVhZGVyVGVtcGxhdGVSZWZcIiBbbmdUZW1wbGF0ZU91dGxldF09XCJoZWFkZXJUZW1wbGF0ZVJlZlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7ZGF0YTpjb2x1bW59XCI+PC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbHVtbi5oZWFkZXJUZW1wbGF0ZVwiIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNvbHVtbi5oZWFkZXJUZW1wbGF0ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7ZGF0YTpjb2x1bW59XCI+PC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICA8L3RoPlxyXG4gICAgICAgICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IHJvdyA7bGV0IGk9ZGF0YUluZGV4XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cIiFyb3cuZWRpdGFibGUgJiYgIWNlbGxFZGl0aW5nW2kgKydfJytjb2x1bW4uZmllbGRdXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgKGRibGNsaWNrKT1cImNlbGxFZGl0aW5nW2kgKydfJytjb2x1bW4uZmllbGRdID0gaW5DZWxsRWRpdGluZztzZXRDZWxsRGF0YShyb3csaSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBtYXRUb29sdGlwPVwie3tjb2x1bW4uY2VsbFRvb2x0aXA/LnZhbHVlfX1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbWF0VG9vbHRpcFBvc2l0aW9uXT1cImNvbHVtbj8uY2VsbFRvb2x0aXA/LnRvb2x0aXBQb3NpdGlvbiFcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIWNlbGxUZW1wbGF0ZVJlZiAmJiAhY29sdW1uPy5jZWxsVGVtcGxhdGUgJiYgIWNlbGxUZW1wbGF0ZVJlZk1hcFtjb2x1bW4uZmllbGRdXCI+e3tyb3dbY29sdW1uLmZpZWxkXX19PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY2VsbFRlbXBsYXRlUmVmTWFwW2NvbHVtbi5maWVsZF1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiY2VsbFRlbXBsYXRlUmVmTWFwW2NvbHVtbi5maWVsZF1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIntyb3c6cm93LGNvbHVtbjpjb2x1bW4saW5kZXg6aX1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY2VsbFRlbXBsYXRlUmVmICYmIGNvbHVtbi5jZWxsVGVtcGxhdGUgJiYgIWNlbGxUZW1wbGF0ZVJlZk1hcFtjb2x1bW4uZmllbGRdXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNvbHVtbi5jZWxsVGVtcGxhdGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIntyb3c6cm93LGNvbHVtbjpjb2x1bW4saW5kZXg6aX1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIWNlbGxUZW1wbGF0ZVJlZiAmJiBjb2x1bW4uY2VsbFRlbXBsYXRlICYmICFjZWxsVGVtcGxhdGVSZWZNYXBbY29sdW1uLmZpZWxkXVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJjb2x1bW4uY2VsbFRlbXBsYXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7cm93OnJvdyxjb2x1bW46Y29sdW1uLGluZGV4Oml9XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNlbGxUZW1wbGF0ZVJlZiAmJiAhY29sdW1uLmNlbGxUZW1wbGF0ZSAmJiAhY2VsbFRlbXBsYXRlUmVmTWFwW2NvbHVtbi5maWVsZF1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiY2VsbFRlbXBsYXRlUmVmXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7cm93OnJvdyxjb2x1bW46Y29sdW1uLGluZGV4Oml9XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJyb3cuZWRpdGFibGUgfHwgY2VsbEVkaXRpbmdbaSArJ18nK2NvbHVtbi5maWVsZF1cIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpbmxpbmVFZGl0aW5nVGVtcGxhdGVSZWYgJiYgIWNlbGxFZGl0aW5nW2kgKydfJytjb2x1bW4uZmllbGRdXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImlubGluZUVkaXRpbmdUZW1wbGF0ZVJlZlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie2RhdGE6Z2V0SW5saW5lRWRpdGluZ0RhdGEocm93LGksY29sdW1uKX1cIj48L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNlbGxFZGl0aW5nVGVtcGxhdGVSZWYgJiYgIShyb3cuZWRpdGFibGUpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNlbGxFZGl0aW5nVGVtcGxhdGVSZWZcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIntkYXRhOmdldElubGluZUVkaXRpbmdEYXRhKHJvdyxpLGNvbHVtbil9XCI+PC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhaW5saW5lRWRpdGluZ1RlbXBsYXRlUmVmICYmIChyb3cuZWRpdGFibGUpICYmIHJvd0RhdGFUZW1wWydlJytpXVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ0lmPVwiY29sdW1uLnR5cGUgPT0gJ251bWJlcidcIiBhcHBlYXJhbmNlPVwib3V0bGluZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJpbmxpbmUtZWRpdGluZy1maWVsZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCB0eXBlPVwibnVtYmVyXCIgWyhuZ01vZGVsKV09XCJyb3dEYXRhVGVtcFsnZScraV1bY29sdW1uLmZpZWxkXVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsT3B0aW9uc109XCJ7c3RhbmRhbG9uZTogdHJ1ZX1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgc3R5bGU9XCJ3aWR0aDogMTAwJTtcIiAqbmdJZj1cImNvbHVtbi50eXBlID09ICdzdHJpbmcnXCIgYXBwZWFyYW5jZT1cIm91dGxpbmVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaW5saW5lLWVkaXRpbmctZmllbGRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgdHlwZT1cInRleHRcIiBbKG5nTW9kZWwpXT1cInJvd0RhdGFUZW1wWydlJytpXVtjb2x1bW4uZmllbGRdXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxPcHRpb25zXT1cIntzdGFuZGFsb25lOiB0cnVlfVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCAqbmdJZj1cImNvbHVtbi50eXBlID09ICdkYXRlJ1wiIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImlubGluZS1lZGl0aW5nLWZpZWxkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IHR5cGU9XCJkYXRlXCIgWyhuZ01vZGVsKV09XCJyb3dEYXRhVGVtcFsnZScraV1bY29sdW1uLmZpZWxkXVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsT3B0aW9uc109XCJ7c3RhbmRhbG9uZTogdHJ1ZX1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nSWY9XCJjb2x1bW4udHlwZSA9PSAnc2VsZWN0aW9uJ1wiIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImlubGluZS1lZGl0aW5nLWZpZWxkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zZWxlY3QgW3ZhbHVlXT1cInJvd0RhdGFUZW1wWydlJytpXVtjb2x1bW4uZmllbGRdXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJyb3dEYXRhVGVtcFsnZScraV1bY29sdW1uLmZpZWxkXVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIGNvbHVtbi5vcHRpb25zXCIgW3ZhbHVlXT1cIm9wdGlvblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tvcHRpb259fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiICpuZ0lmPVwiY29sdW1uLnR5cGUgPT0gJ2Jvb2xlYW4nXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj1cInByaW1hcnlcIiBbKG5nTW9kZWwpXT1cInJvd1tjb2x1bW4uZmllbGRdXCI+PC9tYXQtY2hlY2tib3g+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWNlbGxFZGl0aW5nVGVtcGxhdGVSZWYgJiYgY2VsbEVkaXRpbmdbaSArJ18nK2NvbHVtbi5maWVsZF1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCAqbmdJZj1cImNvbHVtbi50eXBlID09ICdudW1iZXInXCIgYXBwZWFyYW5jZT1cIm91dGxpbmVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaW5saW5lLWVkaXRpbmctZmllbGRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgdHlwZT1cIm51bWJlclwiIFsobmdNb2RlbCldPVwicm93RGF0YVRlbXBbJ2UnK2ldW2NvbHVtbi5maWVsZF1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbE9wdGlvbnNdPVwie3N0YW5kYWxvbmU6IHRydWV9XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ0lmPVwiY29sdW1uLnR5cGUgPT0gJ3N0cmluZydcIiBhcHBlYXJhbmNlPVwib3V0bGluZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJpbmxpbmUtZWRpdGluZy1maWVsZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCB0eXBlPVwidGV4dFwiIFsobmdNb2RlbCldPVwicm93RGF0YVRlbXBbJ2UnK2ldW2NvbHVtbi5maWVsZF1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbE9wdGlvbnNdPVwie3N0YW5kYWxvbmU6IHRydWV9XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ0lmPVwiY29sdW1uLnR5cGUgPT0gJ2RhdGUnXCIgYXBwZWFyYW5jZT1cIm91dGxpbmVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaW5saW5lLWVkaXRpbmctZmllbGRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgdHlwZT1cImRhdGVcIiBbKG5nTW9kZWwpXT1cInJvd0RhdGFUZW1wWydlJytpXVtjb2x1bW4uZmllbGRdXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxPcHRpb25zXT1cIntzdGFuZGFsb25lOiB0cnVlfVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCAqbmdJZj1cImNvbHVtbi50eXBlID09ICdzZWxlY3Rpb24nXCIgYXBwZWFyYW5jZT1cIm91dGxpbmVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaW5saW5lLWVkaXRpbmctZmllbGRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdCBbdmFsdWVdPVwicm93RGF0YVRlbXBbJ2UnK2ldW2NvbHVtbi5maWVsZF1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInJvd0RhdGFUZW1wWydlJytpXVtjb2x1bW4uZmllbGRdXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uICpuZ0Zvcj1cImxldCBvcHRpb24gb2YgY29sdW1uLm9wdGlvbnNcIiBbdmFsdWVdPVwib3B0aW9uXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e29wdGlvbn19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGVja2JveCAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCIgKm5nSWY9XCJjb2x1bW4udHlwZSA9PSAnYm9vbGVhbidcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yPVwicHJpbWFyeVwiIFsobmdNb2RlbCldPVwicm93W2NvbHVtbi5maWVsZF1cIj48L21hdC1jaGVja2JveD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNob3dGb290ZXJSb3dcIj5cclxuICAgICAgICAgICAgICAgICAgICA8dGQgbWF0LWZvb3Rlci1jZWxsICptYXRGb290ZXJDZWxsRGVmPiB7e2NvbHVtbi5mb290ZXJUZXh0fX0gPC90ZD5cclxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJlZGl0XCIgc3RpY2t5RW5kPVwiZmFsc2VcIj5cclxuICAgICAgICAgICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgY2RrRHJhZ0xvY2tBeGlzPVwieFwiIGNka0RyYWcgW2Nka0RyYWdEaXNhYmxlZF09XCJ0cnVlXCIgKm1hdEhlYWRlckNlbGxEZWZcclxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImFjdGlvbi1jb2x1bW4tY2VsbHNcIj4gRWRpdCA8L3RoPlxyXG4gICAgICAgICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IHJvdzsgbGV0IGkgPSBkYXRhSW5kZXhcIiBjbGFzcz1cImlubGluZS1lZGl0LWNvbHVtbi1jZWxsXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwiZWRpdC1jb2x1bW4taWNvbnNcIiAqbmdJZj1cIiFyb3cuZWRpdGFibGUgJiYgIXJvdy5lZGl0bW9kYWxcIiBhcmlhLWhpZGRlbj1cImZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImVuYWJsZUlubGluZUVkaXRpbmcocm93LGkpXCIgZm9udEljb249XCJlZGl0X25vdGVcIj5cclxuICAgICAgICAgICAgICAgICAgICA8L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbmxpbmUtZWRpdGluZy1jb250cm9sc1wiICpuZ0lmPVwicm93LmVkaXRhYmxlICYmICFyb3cuZWRpdG1vZGFsXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cImVkaXQtY29sdW1uLWljb25zXCIgYXJpYS1oaWRkZW49XCJmYWxzZVwiIChjbGljayk9XCJzYXZlSW5saW5lRWRpdGluZyhyb3csaSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9udEljb249XCJkb25lXCI+PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwiZWRpdC1jb2x1bW4taWNvbnNcIiBhcmlhLWhpZGRlbj1cImZhbHNlXCIgKGNsaWNrKT1cImNhbmNlbElubGluZUVkaXRpbmcocm93LGkpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvbnRJY29uPVwiY2xvc2VcIj48L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICAgIDx0ZCBtYXQtZm9vdGVyLWNlbGwgKm1hdEZvb3RlckNlbGxEZWY+IGVkaXQgPC90ZD5cclxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwicG9wdXBcIiBzdGlja3lFbmQ9XCJmYWxzZVwiPlxyXG4gICAgICAgICAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCBjZGtEcmFnTG9ja0F4aXM9XCJ4XCIgY2RrRHJhZyBbY2RrRHJhZ0Rpc2FibGVkXT1cInRydWVcIiAqbWF0SGVhZGVyQ2VsbERlZlxyXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYWN0aW9uLWNvbHVtbi1jZWxsc1wiPiBQb3B1cFxyXG4gICAgICAgICAgICAgICAgPC90aD5cclxuICAgICAgICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCByb3c7IGxldCBpID0gaW5kZXhcIj5cclxuICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gYXJpYS1oaWRkZW49XCJmYWxzZVwiIChjbGljayk9XCJvcGVuRWRpdGluZ0RpYWxvZyhyb3cpXCIgZm9udEljb249XCJlZGl0XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgICA8dGQgbWF0LWZvb3Rlci1jZWxsICptYXRGb290ZXJDZWxsRGVmPjwvdGQ+XHJcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJkZWxldGVcIj5cclxuICAgICAgICAgICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgY2RrRHJhZ0xvY2tBeGlzPVwieFwiIGNka0RyYWcgW2Nka0RyYWdEaXNhYmxlZF09XCJ0cnVlXCIgKm1hdEhlYWRlckNlbGxEZWZcclxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImFjdGlvbi1jb2x1bW4tY2VsbHNcIj4gRGVsZXRlXHJcbiAgICAgICAgICAgICAgICA8L3RoPlxyXG4gICAgICAgICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IHJvdztsZXQgaT1kYXRhSW5kZXhcIj5cclxuICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKGNsaWNrKT1cImRlbGV0ZVJvdyhyb3csaSlcIiBhcmlhLWhpZGRlbj1cImZhbHNlXCIgYXJpYS1sYWJlbD1cIkV4YW1wbGUgaG9tZSBpY29uXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9udEljb249XCJkZWxldGVcIj5cclxuICAgICAgICAgICAgICAgICAgICA8L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICAgIDx0ZCBtYXQtZm9vdGVyLWNlbGwgKm1hdEZvb3RlckNlbGxEZWY+PC90ZD5cclxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgIDwhLS0gRXhwYW5kZWQgQ29udGVudCBDb2x1bW4gLSBUaGUgZGV0YWlsIHJvdyBpcyBtYWRlIHVwIG9mIHRoaXMgb25lIGNvbHVtbiB0aGF0IHNwYW5zIGFjcm9zcyBhbGwgY29sdW1ucyAtLT5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImV4cGFuZFJvd3NcIiBtYXRDb2x1bW5EZWY9XCJleHBhbmRlZERldGFpbFwiPlxyXG4gICAgICAgICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnQ7bGV0IGk9ZGF0YUluZGV4IFwiXHJcbiAgICAgICAgICAgICAgICAgICAgW2F0dHIuY29sc3Bhbl09XCJjb2x1bW5zVG9EaXNwbGF5V2l0aEV4cGFuZC5sZW5ndGhcIj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZXhhbXBsZS1lbGVtZW50LWRldGFpbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtAZGV0YWlsRXhwYW5kXT1cImVsZW1lbnQgPT0gZXhwYW5kZWRFbGVtZW50ID8gJ2V4cGFuZGVkJyA6ICdjb2xsYXBzZWQnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJleHBhbnNpb25UZW1wbGF0ZVJlZlwiIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImV4cGFuc2lvblRlbXBsYXRlUmVmXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7JGV4cGxpY2l0OmVsZW1lbnQscm93OmVsZW1lbnQsaW5kZXg6aX1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgaWRzIG9mIGhlYWRlcnNGaWx0ZXJzSWRzOyBsZXQgaT1pbmRleFwiIFttYXRDb2x1bW5EZWZdPVwiaWRzXCI+XHJcbiAgICAgICAgICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWx0ZXJzLWNvbnRhaW5lclwiIFtjbGFzcy5hbmltYXRlXT1cInRvZ2dsZUZpbHRlcnNcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGFwcC1maWx0ZXItY29sdW1ucy1jb21wb25lbnQgW29ial09XCJjb2x1bW5zQXJyYXlbcmV0dXJuSW5kZXgoaWRzKV1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZpbHRlck91dHB1dCk9XCJhcHBseUNvbHVtbkZpbHRlcigkZXZlbnQsY29sdW1uc0FycmF5W3JldHVybkluZGV4KGlkcyldKVwiPjwvYXBwLWZpbHRlci1jb2x1bW5zLWNvbXBvbmVudD5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwvdGg+XHJcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICA8dHIgbWF0LWhlYWRlci1yb3cgKm1hdEhlYWRlclJvd0RlZj1cIiBnZXREaXNwbGF5ZWRDb2x1bW5zKCk7IHN0aWNreTogc3RpY2t5SGVhZGVyXCI+PC90cj5cclxuICAgICAgICAgICAgPHRyIG1hdC1yb3cgKm1hdFJvd0RlZj1cImxldCByb3c7IGNvbHVtbnM6Z2V0RGlzcGxheWVkQ29sdW1ucygpOyBsZXQgaT1kYXRhSW5kZXg7XCIgY2xhc3M9XCJkYXRhLXJvd1wiXHJcbiAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J2RhdGEtcm93JzpleHBhbmRSb3dzLCdzdHJpcGVkUm93cyc6KHN0cmlwZWRSb3dzICYmICBpICUgMiA9PSAxKSwnaG92ZXJDbGFzcyc6cm93SG92ZXIsICdoaWRkZW4nOmhpZGRlbkN0cmwuaXNTZWxlY3RlZChyb3cpICYmIGhpZGVSb3dzLCdleGFtcGxlLWV4cGFuZGVkLXJvdyc6ZXhwYW5kZWRFbGVtZW50ID09PSByb3d9XCJcclxuICAgICAgICAgICAgICAgIChjbGljayk9XCJleHBhbmRSb3cocm93LCByb3cgIT09IGV4cGFuZGVkRWxlbWVudCxpKVwiPlxyXG4gICAgICAgICAgICA8L3RyPlxyXG4gICAgICAgICAgICA8dHIgc3R5bGU9XCJoZWlnaHQ6IDBweDtcIiBtYXQtaGVhZGVyLXJvdyBjbGFzcz1cIm5vLWRlZmF1bHQtaGVpZ2h0XCIgKm1hdEhlYWRlclJvd0RlZj1cImhlYWRlcnNGaWx0ZXJzSWRzXCI+XHJcbiAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJleHBhbmRSb3dzXCI+XHJcbiAgICAgICAgICAgICAgICA8dHIgc3R5bGU9XCJoZWlnaHQ6IDBweDtcIiBtYXQtcm93ICptYXRSb3dEZWY9XCJsZXQgcm93OyBjb2x1bW5zOiBbJ2V4cGFuZGVkRGV0YWlsJ11cIlxyXG4gICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnZXhhbXBsZS1kZXRhaWwtcm93JzogKGV4cGFuZFJvd3MgJiYgcm93ID09PSBleHBhbmRlZEVsZW1lbnQpLCdleHBhbmQtcm93Jzpyb3cgIT09IGV4cGFuZGVkRWxlbWVudH1cIj5cclxuICAgICAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic2hvd0Zvb3RlclJvd1wiPlxyXG4gICAgICAgICAgICAgICAgPHRyIG1hdC1mb290ZXItcm93ICptYXRGb290ZXJSb3dEZWY9XCJnZXREaXNwbGF5ZWRDb2x1bW5zKCk7IHN0aWNreTogc3RpY2t5Rm9vdGVyXCI+PC90cj5cclxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPC90YWJsZT5cclxuICAgIDwvc2VjdGlvbj5cclxuICAgIDxtYXQtcGFnaW5hdG9yICpuZ0lmPVwic2hvd1BhZ2luYXRvclwiIFtwYWdlU2l6ZU9wdGlvbnNdPVwicGFnZVNpemVPcHRpb25zXCJcclxuICAgICAgICBbc2hvd0ZpcnN0TGFzdEJ1dHRvbnNdPVwic2hvd0ZpcnN0TGFzdEJ1dHRvbnNcIj5cclxuICAgIDwvbWF0LXBhZ2luYXRvcj5cclxuPC9kaXY+Il19