@impartner/design-components 2.1.2 → 2.2.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 (53) hide show
  1. package/esm2022/lib/alert/alert.component.mjs +11 -4
  2. package/esm2022/lib/datetime-picker/components/datetime-picker/datetime-picker.component.mjs +10 -10
  3. package/esm2022/lib/datetime-picker/constants/datetime-picker-defaults.mjs +2 -2
  4. package/esm2022/lib/file-upload/file-upload.module.mjs +14 -6
  5. package/esm2022/lib/modal/modal.component.mjs +9 -3
  6. package/esm2022/lib/progress-bar/progress-bar.component.mjs +19 -3
  7. package/esm2022/lib/table/components/bulk-actions/bulk-actions.component.mjs +6 -1
  8. package/esm2022/lib/table/constants/table.constants.mjs +1 -2
  9. package/esm2022/lib/table/containers/table.component.mjs +91 -20
  10. package/esm2022/lib/table/directives/collapse-monitor.directive.mjs +42 -0
  11. package/esm2022/lib/table/directives/index.mjs +2 -1
  12. package/esm2022/lib/table/directives/table-inject-component.directive.mjs +1 -1
  13. package/esm2022/lib/table/directives/table.directive.mjs +24 -4
  14. package/esm2022/lib/table/index.mjs +2 -2
  15. package/esm2022/lib/table/interfaces/cell-renderer.interface.mjs +1 -1
  16. package/esm2022/lib/table/interfaces/collapsible-row-content-context.interface.mjs +2 -0
  17. package/esm2022/lib/table/interfaces/index.mjs +3 -1
  18. package/esm2022/lib/table/interfaces/sort-by-payload.interface.mjs +1 -1
  19. package/esm2022/lib/table/interfaces/table-column-defs.type.mjs +1 -1
  20. package/esm2022/lib/table/interfaces/table-event-payload.interface.mjs +1 -1
  21. package/esm2022/lib/table/interfaces/table-row-action-payload.interface.mjs +1 -1
  22. package/esm2022/lib/table/interfaces/table-row-action.interface.mjs +1 -1
  23. package/esm2022/lib/table/interfaces/table-row-collapse-change.interface.mjs +2 -0
  24. package/esm2022/lib/table/interfaces/table-row-item.interface.mjs +1 -1
  25. package/esm2022/lib/table/table.module.mjs +12 -7
  26. package/fesm2022/impartner-design-components.mjs +215 -42
  27. package/fesm2022/impartner-design-components.mjs.map +1 -1
  28. package/lib/alert/alert.component.d.ts +5 -1
  29. package/lib/datetime-picker/components/datetime-picker/datetime-picker.component.d.ts +3 -3
  30. package/lib/datetime-picker/constants/datetime-picker-defaults.d.ts +1 -1
  31. package/lib/file-upload/file-upload.module.d.ts +1 -1
  32. package/lib/modal/modal.component.d.ts +5 -1
  33. package/lib/progress-bar/progress-bar.component.d.ts +10 -1
  34. package/lib/table/components/bulk-actions/bulk-actions.component.d.ts +5 -0
  35. package/lib/table/constants/table.constants.d.ts +0 -1
  36. package/lib/table/containers/table.component.d.ts +58 -13
  37. package/lib/table/directives/collapse-monitor.directive.d.ts +12 -0
  38. package/lib/table/directives/index.d.ts +1 -0
  39. package/lib/table/directives/table-inject-component.directive.d.ts +2 -2
  40. package/lib/table/directives/table.directive.d.ts +11 -3
  41. package/lib/table/index.d.ts +1 -1
  42. package/lib/table/interfaces/cell-renderer.interface.d.ts +10 -3
  43. package/lib/table/interfaces/collapsible-row-content-context.interface.d.ts +39 -0
  44. package/lib/table/interfaces/index.d.ts +2 -0
  45. package/lib/table/interfaces/sort-by-payload.interface.d.ts +6 -0
  46. package/lib/table/interfaces/table-column-defs.type.d.ts +30 -6
  47. package/lib/table/interfaces/table-event-payload.interface.d.ts +8 -1
  48. package/lib/table/interfaces/table-row-action-payload.interface.d.ts +8 -1
  49. package/lib/table/interfaces/table-row-action.interface.d.ts +10 -2
  50. package/lib/table/interfaces/table-row-collapse-change.interface.d.ts +11 -0
  51. package/lib/table/interfaces/table-row-item.interface.d.ts +3 -4
  52. package/lib/table/table.module.d.ts +18 -17
  53. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  import { Component, ContentChild, EventEmitter, Host, Input, Optional, Output } from '@angular/core';
2
2
  import { get as getNestedValue, set as setNestedValue } from 'lodash';
3
3
  import { debounceTime } from 'rxjs/operators';
4
- import { DEBOUNCE_TIME, SORT_COLUMN_INDEX } from '../constants/index';
4
+ import { DEBOUNCE_TIME } from '../constants/index';
5
5
  import { TableColumnType } from '../enumerations/index';
6
6
  import { TableThemeHelper } from '../helpers';
7
7
  import { ComponentTheme } from '../../../types';
@@ -19,10 +19,11 @@ import * as i8 from "../../form-field/controls/input/input.directive";
19
19
  import * as i9 from "@angular/forms";
20
20
  import * as i10 from "../../spinner/spinner.component";
21
21
  import * as i11 from "../../badge/badge.component";
22
- import * as i12 from "../directives/table.directive";
23
- import * as i13 from "../components/column-heading/column-heading.component";
24
- import * as i14 from "../directives/table-inject-component.directive";
25
- import * as i15 from "../components/row-actions/row-actions.component";
22
+ import * as i12 from "../directives/collapse-monitor.directive";
23
+ import * as i13 from "../directives/table.directive";
24
+ import * as i14 from "../components/column-heading/column-heading.component";
25
+ import * as i15 from "../directives/table-inject-component.directive";
26
+ import * as i16 from "../components/row-actions/row-actions.component";
26
27
  /**
27
28
  * The `TableComponent` (`<impdc-table`) is a data table component.
28
29
  * To use, import `TableModule` from `@impartner/design-components`.
@@ -65,9 +66,14 @@ export class TableComponent {
65
66
  }
66
67
  /** @ignore */
67
68
  get tableSpan() {
68
- return this.canSelectRows
69
- ? this.columnDefs.length + 1
70
- : this.columnDefs.length;
69
+ let cols = this.columnDefs.length;
70
+ if (this.canSelectRows) {
71
+ cols++;
72
+ }
73
+ if (this.collapsibleTemplate) {
74
+ cols++;
75
+ }
76
+ return cols;
71
77
  }
72
78
  constructor(_datePipe, _percentPipe, _decmialPipe, _changeDetectorRef, _branded) {
73
79
  this._datePipe = _datePipe;
@@ -91,6 +97,14 @@ export class TableComponent {
91
97
  * Whether the table is striped.
92
98
  */
93
99
  this.striped = true;
100
+ /**
101
+ * Whether table rows should apply hover styles when hovered over via cursor.
102
+ */
103
+ this.hover = true;
104
+ /**
105
+ * The layout algorithm to be used when rendering the table.
106
+ */
107
+ this.layout = 'auto';
94
108
  /**
95
109
  * The placeholder text and empty value display text for `<impdc-select>` instances in cells with a `ITableColumnDef` `columnType` = `SingleSelect` or `MultiSelect`.
96
110
  */
@@ -98,7 +112,7 @@ export class TableComponent {
98
112
  /**
99
113
  * The `columnDefs` index of the currently sorted column.
100
114
  */
101
- this.sortColumnIndex = SORT_COLUMN_INDEX;
115
+ this.sortColumnIndex = 0;
102
116
  /**
103
117
  * The direction of the currently sorted column.
104
118
  */
@@ -107,6 +121,18 @@ export class TableComponent {
107
121
  * The table row data as an array of `ITableRowItem`.
108
122
  */
109
123
  this.tableData = [];
124
+ /**
125
+ * An optional template for content that may be rendered below a row in an collapsible view. Value can either be an Angular template or a function that can evaluated
126
+ * to resolve to a template. The template will be rendered with a provided `ICollapsibleRowContentContext` object as template context, with the current `ITableRowData`
127
+ * implicitly available as a default template key.
128
+ */
129
+ this.collapsibleTemplate = null;
130
+ /**
131
+ * The clickable control that will trigger expansion and collapse of content when using `collapsibleTemplate` functionality.
132
+ * When set to `button`, the collapsible content's state can only be toggled from a clickable button at the start of the row.
133
+ * When set to `row`, the entire row will become a clickable trigger.
134
+ */
135
+ this.collapsibleTrigger = 'button';
110
136
  /**
111
137
  * Event emitted when one or multiple rows are selected. Emits `(string | number)[]` payload.
112
138
  */
@@ -123,15 +149,19 @@ export class TableComponent {
123
149
  * Event emitted when a row action is clicked. Emits an `ITableRowActionPayload` payload.
124
150
  */
125
151
  this.rowActionClick = new EventEmitter();
126
- /** @ignore */
127
- this.paginationComponent = undefined;
128
- /** @ignore */
129
- this.bulkActions = undefined;
130
152
  /**
131
- * Event emitted when a row input value is changed. Emitted cells of `columnType` `SinglSelect`, `MultiSelect`, `Input`, `Boolean` or `Icon`.
153
+ * Event emitted when a row input value is changed. Emitted cells of `columnType` `SingleSelect`, `MultiSelect`, `Input`, `Boolean` or `Icon`.
132
154
  * Not emitted if column definition property `disabled` = `true`. Emits `ITableEventPayload` payload.
133
155
  */
134
156
  this.inputChange = new EventEmitter();
157
+ /**
158
+ * Event emitted when a row with collapsible content has its collapse state changed.
159
+ */
160
+ this.rowCollapseChange = new EventEmitter();
161
+ /** @ignore */
162
+ this.paginationComponent = undefined;
163
+ /** @ignore */
164
+ this.bulkActions = undefined;
135
165
  /** @ignore */
136
166
  this.cellType = TableColumnType;
137
167
  /** @ignore */
@@ -160,6 +190,7 @@ export class TableComponent {
160
190
  }
161
191
  }
162
192
  }
193
+ /** @ignore */
163
194
  getMailToValue(columnIndex, currentRow) {
164
195
  const { columnType, truncated: truncated } = this._getColumnDefByIndex(columnIndex);
165
196
  let value = this._getValue(columnIndex, currentRow);
@@ -169,6 +200,7 @@ export class TableComponent {
169
200
  value = value ? `mailto:${value}` : value;
170
201
  return String(value);
171
202
  }
203
+ /** @ignore */
172
204
  getStringValue(columnIndex, currentRow) {
173
205
  const value = this.getValue(columnIndex, currentRow);
174
206
  if (Array.isArray(value)) {
@@ -176,6 +208,7 @@ export class TableComponent {
176
208
  }
177
209
  return String(value);
178
210
  }
211
+ /** @ignore */
179
212
  getValue(columnIndex, currentRow) {
180
213
  const { columnType, truncated: truncated } = this._getColumnDefByIndex(columnIndex);
181
214
  let value = this._getValue(columnIndex, currentRow);
@@ -237,6 +270,7 @@ export class TableComponent {
237
270
  }
238
271
  return String(value);
239
272
  }
273
+ /** @ignore */
240
274
  getRawValue(columnIndex, currentRow) {
241
275
  const { field } = this._getColumnDefByIndex(columnIndex);
242
276
  if (!field) {
@@ -244,19 +278,24 @@ export class TableComponent {
244
278
  }
245
279
  return currentRow[field] || '';
246
280
  }
281
+ /** @ignore */
247
282
  getCellColor(columnDefinition, item) {
248
283
  return TableThemeHelper.getCellColor(columnDefinition, item);
249
284
  }
285
+ /** @ignore */
250
286
  getTheme(columnDefinition, item) {
251
287
  return (TableThemeHelper.getTheme(columnDefinition, item) ||
252
288
  ComponentTheme.Primary);
253
289
  }
290
+ /** @ignore */
254
291
  isSortedColumn(columnIndex) {
255
292
  return columnIndex === this.sortColumnIndex;
256
293
  }
294
+ /** @ignore */
257
295
  isRowSelected(id) {
258
296
  return this.selectedRowIds.includes(id);
259
297
  }
298
+ /** @ignore */
260
299
  handleSelectAll(event) {
261
300
  if (!this.canSelectAllRows || !this.tableData) {
262
301
  return;
@@ -271,6 +310,7 @@ export class TableComponent {
271
310
  this.allSelected = this.selectedRowIds.length >= this.tableData.length;
272
311
  this.rowSelect.emit(this.selectedRowIds);
273
312
  }
313
+ /** @ignore */
274
314
  handleSort(columnIndex) {
275
315
  if (columnIndex === this.sortColumnIndex) {
276
316
  this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';
@@ -286,6 +326,7 @@ export class TableComponent {
286
326
  direction: this.sortDirection
287
327
  });
288
328
  }
329
+ /** @ignore */
289
330
  handleRowSelect(event, rowId) {
290
331
  if (!this.canSelectRows) {
291
332
  return;
@@ -305,6 +346,7 @@ export class TableComponent {
305
346
  this.allSelected = this.selectedRowIds.length >= this.tableData.length;
306
347
  this.rowSelect.emit(this.selectedRowIds);
307
348
  }
349
+ /** @ignore */
308
350
  handleCellValueChange(columnIndex, rowIndex, value) {
309
351
  const { field, columnType } = this._getColumnDefByIndex(columnIndex);
310
352
  let currentValue = value;
@@ -320,12 +362,16 @@ export class TableComponent {
320
362
  });
321
363
  this._changeDetectorRef.detectChanges();
322
364
  }
323
- handleLinkClick(columnIndex, item) {
365
+ /** @ignore */
366
+ handleLinkClick(columnIndex, item, event) {
367
+ event.preventDefault();
368
+ event.stopPropagation();
324
369
  this.linkClick.emit({
325
370
  item,
326
371
  columnIndex
327
372
  });
328
373
  }
374
+ /** @ignore */
329
375
  handleActionClick(columnIndex, item, actionApiName) {
330
376
  this.rowActionClick.emit({
331
377
  item,
@@ -336,6 +382,21 @@ export class TableComponent {
336
382
  columnDefIsActions(columnDef) {
337
383
  return columnDef.columnType === TableColumnType.Actions;
338
384
  }
385
+ tryToggleCollapse(collapsibleForRowResult, ngbCollapse, event, source) {
386
+ if (collapsibleForRowResult.template &&
387
+ (this.collapsibleTrigger === 'row' || this.collapsibleTrigger === source)) {
388
+ ngbCollapse.toggle();
389
+ event.stopPropagation();
390
+ }
391
+ }
392
+ getCollapsibleTemplateForRow(row) {
393
+ return {
394
+ template: this.collapsibleTemplate &&
395
+ typeof this.collapsibleTemplate === 'function'
396
+ ? this.collapsibleTemplate(row)
397
+ : this.collapsibleTemplate
398
+ };
399
+ }
339
400
  _getColumnDefByIndex(columnIndex) {
340
401
  return this.columnDefs[columnIndex];
341
402
  }
@@ -352,11 +413,11 @@ export class TableComponent {
352
413
  }
353
414
  }
354
415
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: TableComponent, deps: [{ token: i1.DatePipe }, { token: i1.PercentPipe }, { token: i1.DecimalPipe }, { token: i0.ChangeDetectorRef }, { token: i2.BrandedDirective, host: true, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
355
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.0.1", type: TableComponent, selector: "impdc-table", inputs: { loading: "loading", columnDefs: "columnDefs", striped: "striped", canSelectRows: "canSelectRows", canSelectAllRows: "canSelectAllRows", selectPlaceholder: "selectPlaceholder", sortColumnIndex: "sortColumnIndex", sortDirection: "sortDirection", tableData: "tableData", selectedRowIds: "selectedRowIds", customCellComponents: "customCellComponents" }, outputs: { rowSelect: "rowSelect", sortBy: "sortBy", linkClick: "linkClick", rowActionClick: "rowActionClick", inputChange: "inputChange" }, queries: [{ propertyName: "paginationComponent", first: true, predicate: PaginationComponent, descendants: true }, { propertyName: "bulkActions", first: true, predicate: TableBulkActionsComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (tableData) {\n<table impdcTable [striped]=\"striped\">\n <thead>\n @if (!!bulkActions) {\n <tr>\n <th [attr.colspan]=\"tableSpan\" scope=\"col\" class=\"bulk-action-column\">\n <ng-content select=\"impdc-table-bulk-actions\"></ng-content>\n <ng-content select=\"[impdcTableBulkActions]\"></ng-content>\n </th>\n </tr>\n }\n <tr>\n @if (canSelectRows) {\n <th\n scope=\"col\"\n [ngClass]=\"{\n 'heading-below-bulk-actions': !!bulkActions\n }\">\n @if (canSelectAllRows) {\n <div>\n <impdc-checkbox\n ngModel\n [checked]=\"allSelected\"\n [indeterminate]=\"someSelected\"\n (change)=\"handleSelectAll($event)\"></impdc-checkbox>\n </div>\n }\n </th>\n } @for (columnDef of columnDefs; track columnDef; let columnIndex =\n $index) {\n <th\n scope=\"col\"\n [ngClass]=\"{\n 'sorted-column': isSortedColumn(columnIndex),\n 'sortable-column': columnDef.sorted,\n 'heading-below-bulk-actions': !!bulkActions\n }\"\n (click)=\"handleSort(columnIndex)\">\n <impdc-column-heading\n [isSortable]=\"columnDef.sorted || false\"\n [columnIndex]=\"columnIndex\"\n [sortColumnIndex]=\"sortColumnIndex\"\n [direction]=\"sortDirection\"\n [text]=\"columnDef.title\"\n (sort)=\"handleSort($event)\">\n </impdc-column-heading>\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @if (loading) {\n <tr>\n <td [attr.colspan]=\"tableSpan\" class=\"data-loading\">\n <impdc-spinner></impdc-spinner>\n </td>\n </tr>\n } @else { @for (row of tableData; track row; let rowIndex = $index) {\n <tr>\n @if (canSelectRows) {\n <td>\n <div class=\"select-column\">\n <impdc-checkbox\n [ngModel]=\"isRowSelected(row.id)\"\n (change)=\"handleRowSelect($event, row.id)\"></impdc-checkbox>\n </div>\n </td>\n }\n <td\n *ngFor=\"let columnDef of columnDefs; index as colIndex; last as isLast\"\n [ngClass]=\"{\n 'col-no-padding': !!columnDef.noPadding,\n 'actions-column': columnDef.columnType === cellType.Actions\n }\">\n <div>\n @switch (columnDef.columnType) { @case (cellType.Badge) {\n <span>\n <impdc-badge\n [text]=\"getStringValue(colIndex, row)\"\n [theme]=\"getTheme(columnDef, row)\">\n </impdc-badge>\n </span>\n } @case (cellType.Link) {\n <span (click)=\"handleLinkClick(colIndex, row)\">\n @if (!branded) {\n <a>\n {{ getValue(colIndex, row) }}\n </a>\n } @else {\n <a impdcBranded>\n {{ getValue(colIndex, row) }}\n </a>\n }\n </span>\n } @case (cellType.Url) {\n <span>\n @if (!branded) {\n <a target=\"_blank\" [attr.href]=\"getValue(colIndex, row)\">\n {{ getValue(colIndex, row) }}\n </a>\n } @else {\n <a\n impdcBranded\n target=\"_blank\"\n [attr.href]=\"getValue(colIndex, row)\">\n {{ getValue(colIndex, row) }}\n </a>\n }\n </span>\n } @case (cellType.Email) {\n <span>\n @if (!branded) {\n <a\n target=\"_blank\"\n [attr.href]=\"'mailto:' + getValue(colIndex, row)\">\n {{ getValue(colIndex, row) }}\n </a>\n } @else {\n <a impdcBranded [attr.href]=\"getMailToValue(colIndex, row)\">\n {{ getValue(colIndex, row) }}\n </a>\n }\n </span>\n } @case (cellType.Input) {\n <span>\n <input\n impdcInput\n type=\"text\"\n class=\"{{ getCellColor(columnDef, row) }}\"\n [ngModel]=\"getValue(colIndex, row)\"\n (ngModelChange)=\"\n handleCellValueChange(colIndex, rowIndex, $event)\n \" />\n </span>\n } @case (cellType.Boolean) {\n <span>\n @if (columnDef.disabled && getValue(colIndex, row) === 'true') {\n <span\n impdc-icon\n name=\"check\"\n class=\"{{ getCellColor(columnDef, row) }}\"></span>\n } @else if (!columnDef.disabled) {\n <impdc-checkbox\n [checked]=\"getValue(colIndex, row) === 'true'\"\n [isSwitch]=\"true\"\n (change)=\"\n handleCellValueChange(colIndex, rowIndex, $event.checked)\n \"></impdc-checkbox>\n }\n </span>\n } @case (cellType.SingleSelect) {\n <span>\n <impdc-select\n [ngModel]=\"getValue(colIndex, row)\"\n [disabled]=\"columnDef.disabled || false\"\n [placeholder]=\"selectPlaceholder\"\n allowClear=\"true\"\n (selectionChange)=\"\n handleCellValueChange(colIndex, rowIndex, $event.value)\n \">\n @for (value of (columnDef.values || []); track value) {\n <impdc-select-option\n [value]=\"value.value\"\n [label]=\"value.label\"></impdc-select-option>\n }\n </impdc-select>\n </span>\n } @case (cellType.MultiSelect) {\n <span>\n <impdc-select\n [ngModel]=\"getValue(colIndex, row)\"\n [disabled]=\"columnDef.disabled || false\"\n [placeholder]=\"selectPlaceholder\"\n multiple=\"true\"\n (selectionChange)=\"\n handleCellValueChange(colIndex, rowIndex, $event.value)\n \">\n @for (value of (columnDef.values || []); track value) {\n <impdc-select-option\n [value]=\"value.value\"\n [label]=\"value.label\"></impdc-select-option>\n }\n </impdc-select>\n </span>\n } @case (cellType.CellRender) {\n <span class=\"{{ getCellColor(columnDef, row) }}\">\n <ng-template\n impdcTableInjectComponent\n [columnDef]=\"columnDef\"\n [rowItem]=\"row\"\n [customCellComponents]=\"customCellComponents || {}\"\n [value]=\"getRawValue(colIndex, row)\"></ng-template>\n </span>\n } @case (cellType.Icon) {\n <span>\n <span\n impdc-icon\n [name]=\"columnDef.iconName\"\n class=\"{{ getCellColor(columnDef, row) }}\"></span>\n </span>\n } @case (cellType.Actions) {\n <span>\n <!-- will always return 'true', but needed to satisfy the type engine -->\n @if (columnDefIsActions(columnDef)) {\n <impdc-row-actions\n [columnDef]=\"columnDef\"\n [rowItem]=\"row\"\n [lastColumn]=\"isLast\"\n (actionClick)=\"\n handleActionClick(colIndex, row, $event)\n \"></impdc-row-actions>\n }\n </span>\n } @default {\n <span class=\"{{ getCellColor(columnDef, row) }}\">\n {{ getValue(colIndex, row) }}\n </span>\n } }\n </div>\n </td>\n </tr>\n } @empty {\n <tr>\n <td [attr.colspan]=\"tableSpan\" class=\"no-data\">\n <ng-content select=\"[noData]\"></ng-content>\n </td>\n </tr>\n } }\n </tbody>\n <tfoot>\n @if (paginationComponent) {\n <tr>\n <td [attr.colspan]=\"tableSpan\">\n <ng-content\n select=\"impdc-pagination, div[impdc-pagination]\"></ng-content>\n </td>\n </tr>\n }\n </tfoot>\n</table>\n}\n", styles: [".bulk-action-container{display:flex;flex-direction:row;border:1px solid var(--impd-color-gray-200);border-top-left-radius:.6rem;border-top-right-radius:.6rem;border-bottom:0px}.bulk-action-container .bulk-action-checkbox{padding:1.6rem 2rem}.bulk-action-container .bulk-actions{display:flex;flex-direction:row;gap:.4rem}.col-no-padding{padding:0!important}.data-loading{height:var(--impd-size-80);vertical-align:middle;text-align:center}.no-data{vertical-align:middle;text-align:center}.select-row{display:flex;height:var(--impd-size-4);align-items:center;justify-items:end;border-radius:var(--impd-border-radius-default)}.heading-with-checkbox{padding-left:5px;padding-right:10px}.actions-column{width:.1%;white-space:nowrap}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.BrandedDirective, selector: "[impdcBranded]" }, { kind: "component", type: i4.IconComponent, selector: "impdc-icon, [impdc-icon]", inputs: ["name", "theme", "size"] }, { kind: "component", type: i5.CheckboxComponent, selector: "impdc-checkbox", inputs: ["tabIndex", "id", "label", "description", "isSwitch", "switchIcons", "inline", "layout", "checked", "indeterminate", "disabled", "errorStateMatcher", "required"], outputs: ["change", "indeterminateChange"], exportAs: ["impdcCheckControl"] }, { kind: "component", type: i6.SelectOptionComponent, selector: "impdc-select-option", inputs: ["value", "label", "disabled"] }, { kind: "component", type: i7.SelectComponent, selector: "impdc-select", inputs: ["disabled", "tabIndex", "search", "placeholder", "required", "compareWith", "dropdownContainer", "errorStateMatcher", "allowClear", "multiple", "multipleDisplay"], outputs: ["selectionChange", "valueChange", "searchTextChanges"], exportAs: ["impdcSelect"] }, { kind: "directive", type: i8.InputDirective, selector: "input[impdcInput], textarea[impdcInput], select[impdcNativeSelect]", inputs: ["disabled", "id", "type", "required", "readonly", "errorStateMatcher", "value"], exportAs: ["impdcInput"] }, { kind: "directive", type: i9.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: i9.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i9.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i10.SpinnerComponent, selector: "impdc-spinner, div[impdc-spinner]", inputs: ["accessibilityText"] }, { kind: "component", type: i11.BadgeComponent, selector: "impdc-badge, [impdc-badge]", inputs: ["text", "icon", "theme", "size", "hideBg", "rounded", "dismissable"], outputs: ["dismiss"] }, { kind: "directive", type: i12.TableDirective, selector: "table[impdcTable]", inputs: ["striped"] }, { kind: "component", type: i13.ColumnHeadingComponent, selector: "impdc-column-heading", inputs: ["isSortable", "columnIndex", "sortColumnIndex", "direction", "text"], outputs: ["sort"] }, { kind: "directive", type: i14.TableInjectComponentDirective, selector: "[impdcTableInjectComponent]", inputs: ["columnDef", "value", "rowItem", "customCellComponents"] }, { kind: "component", type: i15.RowActionsComponent, selector: "impdc-row-actions", inputs: ["columnDef", "rowItem", "lastColumn"], outputs: ["actionClick"] }] }); }
416
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.0.1", type: TableComponent, selector: "impdc-table", inputs: { loading: "loading", columnDefs: "columnDefs", striped: "striped", hover: "hover", layout: "layout", canSelectRows: "canSelectRows", canSelectAllRows: "canSelectAllRows", selectPlaceholder: "selectPlaceholder", sortColumnIndex: "sortColumnIndex", sortDirection: "sortDirection", tableData: "tableData", selectedRowIds: "selectedRowIds", customCellComponents: "customCellComponents", collapsibleTemplate: "collapsibleTemplate", collapsibleTrigger: "collapsibleTrigger" }, outputs: { rowSelect: "rowSelect", sortBy: "sortBy", linkClick: "linkClick", rowActionClick: "rowActionClick", inputChange: "inputChange", rowCollapseChange: "rowCollapseChange" }, queries: [{ propertyName: "paginationComponent", first: true, predicate: PaginationComponent, descendants: true }, { propertyName: "bulkActions", first: true, predicate: TableBulkActionsComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (tableData) {\n<table\n impdcTable\n [striped]=\"striped && !collapsibleTemplate\"\n [layout]=\"layout\"\n [hover]=\"hover\">\n <thead>\n @if (!!bulkActions) {\n <tr>\n <th [attr.colspan]=\"tableSpan\" scope=\"col\" class=\"bulk-action-column\">\n <ng-content select=\"impdc-table-bulk-actions\"></ng-content>\n <ng-content select=\"[impdcTableBulkActions]\"></ng-content>\n </th>\n </tr>\n }\n <tr>\n @if (collapsibleTemplate) {\n <th\n scope=\"col\"\n [class.heading-below-bulk-actions]=\"!!bulkActions\"\n class=\"impdc-table-collapsible-content-row-button-container\"></th>\n } @if (canSelectRows) {\n <th\n scope=\"col\"\n class=\"impdc-table-selectable-row-toggle-container\"\n [ngClass]=\"{\n 'heading-below-bulk-actions': !!bulkActions\n }\">\n @if (canSelectAllRows) {\n <div>\n <impdc-checkbox\n ngModel\n [checked]=\"allSelected\"\n [indeterminate]=\"someSelected\"\n (change)=\"handleSelectAll($event)\"></impdc-checkbox>\n </div>\n }\n </th>\n } @for (columnDef of columnDefs; track columnDef; let columnIndex =\n $index) {\n <th\n scope=\"col\"\n [ngClass]=\"{\n 'sorted-column': isSortedColumn(columnIndex),\n 'sortable-column': columnDef.sorted,\n 'heading-below-bulk-actions': !!bulkActions\n }\"\n (click)=\"handleSort(columnIndex)\">\n <impdc-column-heading\n [isSortable]=\"columnDef.sorted || false\"\n [columnIndex]=\"columnIndex\"\n [sortColumnIndex]=\"sortColumnIndex\"\n [direction]=\"sortDirection\"\n [text]=\"columnDef.title\"\n (sort)=\"handleSort($event)\">\n </impdc-column-heading>\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @if (loading) {\n <tr>\n <td [attr.colspan]=\"tableSpan\" class=\"data-loading\">\n <impdc-spinner></impdc-spinner>\n </td>\n </tr>\n } @else { @for (row of tableData; track row.id; let rowIndex = $index; let\n rowFirst = $first; let rowLast = $last; let rowEven = $even; let rowOdd =\n $odd) { @if (getCollapsibleTemplateForRow(row); as\n collapsibleTemplateForRow) {\n <tr\n [class.impdc-table-collapsible-row-trigger]=\"collapsibleTrigger === 'row'\"\n [class.table-active]=\"isRowSelected(row.id)\"\n (click)=\"\n tryToggleCollapse(collapsibleTemplateForRow, ngbCollapse, $event, 'row')\n \">\n @if (collapsibleTemplate) {\n <td\n class=\"impdc-table-collapsible-content-row-button-container\"\n [class.opened]=\"!collapseMonitor.ngbCollapsing()\">\n @if (collapsibleTemplateForRow.template) {\n <div>\n <button\n type=\"button\"\n (click)=\"\n tryToggleCollapse(\n collapsibleTemplateForRow,\n ngbCollapse,\n $event,\n 'button'\n )\n \"\n class=\"impdc-table-collapsible-content-row-button btn btn-link\">\n <span\n class=\"far fa-chevron-right\"\n [class.fa-rotate-90]=\"!collapseMonitor.ngbCollapsing()\"></span>\n </button>\n </div>\n }\n </td>\n } @if (canSelectRows) {\n <td class=\"impdc-table-selectable-row-toggle-container\">\n <div class=\"select-column\">\n <impdc-checkbox\n [ngModel]=\"isRowSelected(row.id)\"\n (change)=\"handleRowSelect($event, row.id)\"\n (click)=\"$event.stopPropagation()\"></impdc-checkbox>\n </div>\n </td>\n }\n <td\n *ngFor=\"let columnDef of columnDefs; index as colIndex; last as isLast\"\n [ngClass]=\"{\n 'col-no-padding': !!columnDef.noPadding,\n 'actions-column': columnDef.columnType === cellType.Actions\n }\">\n <div>\n @switch (columnDef.columnType) { @case (cellType.Badge) {\n <span>\n <impdc-badge\n [text]=\"getStringValue(colIndex, row)\"\n [theme]=\"getTheme(columnDef, row)\">\n </impdc-badge>\n </span>\n } @case (cellType.Link) {\n <span (click)=\"handleLinkClick(colIndex, row, $event)\">\n @if (!branded) {\n <a class=\"link-primary\">\n {{ getValue(colIndex, row) }}\n </a>\n } @else {\n <a impdcBranded>\n {{ getValue(colIndex, row) }}\n </a>\n }\n </span>\n } @case (cellType.Url) {\n <span>\n @if (!branded) {\n <a\n target=\"_blank\"\n [attr.href]=\"getValue(colIndex, row)\"\n (click)=\"$event.stopPropagation()\">\n {{ getValue(colIndex, row) }}\n </a>\n } @else {\n <a\n impdcBranded\n target=\"_blank\"\n [attr.href]=\"getValue(colIndex, row)\"\n (click)=\"$event.stopPropagation()\">\n {{ getValue(colIndex, row) }}\n </a>\n }\n </span>\n } @case (cellType.Email) {\n <span>\n @if (!branded) {\n <a\n target=\"_blank\"\n [attr.href]=\"'mailto:' + getValue(colIndex, row)\"\n (click)=\"$event.stopPropagation()\">\n {{ getValue(colIndex, row) }}\n </a>\n } @else {\n <a\n impdcBranded\n [attr.href]=\"getMailToValue(colIndex, row)\"\n (click)=\"$event.stopPropagation()\">\n {{ getValue(colIndex, row) }}\n </a>\n }\n </span>\n } @case (cellType.Input) {\n <span>\n <input\n impdcInput\n type=\"text\"\n class=\"{{ getCellColor(columnDef, row) }}\"\n [ngModel]=\"getValue(colIndex, row)\"\n (ngModelChange)=\"\n handleCellValueChange(colIndex, rowIndex, $event)\n \"\n (click)=\"$event.stopPropagation()\" />\n </span>\n } @case (cellType.Boolean) {\n <span>\n @if (columnDef.disabled && getValue(colIndex, row) === 'true') {\n <span\n impdc-icon\n name=\"check\"\n class=\"{{ getCellColor(columnDef, row) }}\"></span>\n } @else if (!columnDef.disabled) {\n <impdc-checkbox\n [checked]=\"getValue(colIndex, row) === 'true'\"\n [isSwitch]=\"true\"\n (change)=\"\n handleCellValueChange(colIndex, rowIndex, $event.checked)\n \"\n (click)=\"$event.stopPropagation()\"></impdc-checkbox>\n }\n </span>\n } @case (cellType.SingleSelect) {\n <span>\n <impdc-select\n [ngModel]=\"getValue(colIndex, row)\"\n [disabled]=\"columnDef.disabled || false\"\n [placeholder]=\"selectPlaceholder\"\n allowClear=\"true\"\n (selectionChange)=\"\n handleCellValueChange(colIndex, rowIndex, $event.value)\n \"\n (click)=\"$event.stopPropagation()\">\n @for (value of (columnDef.values || []); track value) {\n <impdc-select-option\n [value]=\"value.value\"\n [label]=\"value.label\"></impdc-select-option>\n }\n </impdc-select>\n </span>\n } @case (cellType.MultiSelect) {\n <span>\n <impdc-select\n [ngModel]=\"getValue(colIndex, row)\"\n [disabled]=\"columnDef.disabled || false\"\n [placeholder]=\"selectPlaceholder\"\n multiple=\"true\"\n (selectionChange)=\"\n handleCellValueChange(colIndex, rowIndex, $event.value)\n \"\n (click)=\"$event.stopPropagation()\">\n @for (value of (columnDef.values || []); track value) {\n <impdc-select-option\n [value]=\"value.value\"\n [label]=\"value.label\"></impdc-select-option>\n }\n </impdc-select>\n </span>\n } @case (cellType.CellRender) {\n <span class=\"{{ getCellColor(columnDef, row) }}\">\n <ng-template\n impdcTableInjectComponent\n [columnDef]=\"columnDef\"\n [rowItem]=\"row\"\n [customCellComponents]=\"customCellComponents || {}\"\n [value]=\"getRawValue(colIndex, row)\"></ng-template>\n </span>\n } @case (cellType.Icon) {\n <span>\n <span\n impdc-icon\n [name]=\"columnDef.iconName\"\n class=\"{{ getCellColor(columnDef, row) }}\"></span>\n </span>\n } @case (cellType.Actions) {\n <span>\n <!-- will always return 'true', but needed to satisfy the type engine -->\n @if (columnDefIsActions(columnDef)) {\n <impdc-row-actions\n [columnDef]=\"columnDef\"\n [rowItem]=\"row\"\n [lastColumn]=\"isLast\"\n (actionClick)=\"handleActionClick(colIndex, row, $event)\"\n (click)=\"$event.stopPropagation()\"></impdc-row-actions>\n }\n </span>\n } @default {\n <span class=\"{{ getCellColor(columnDef, row) }}\">\n {{ getValue(colIndex, row) }}\n </span>\n } }\n </div>\n </td>\n </tr>\n <tr\n class=\"impdc-table-collapsible-content-row\"\n [class.opened]=\"!collapseMonitor.ngbCollapsing()\">\n <td class=\"w-100 p-0\" [attr.colspan]=\"tableSpan\">\n <div\n class=\"impdc-table-collapsible-content-container\"\n #ngbCollapse=\"ngbCollapse\"\n #collapseMonitor=\"impdcCollapseMonitor\"\n [impdcCollapseMonitor]=\"true\"\n (collapseChange)=\"rowCollapseChange.emit({ row, collapsed: $event })\">\n @if (collapsibleTemplateForRow.template) {\n <div>\n <ng-container\n *ngTemplateOutlet=\"\n collapsibleTemplateForRow.template;\n context: {\n $implicit: row,\n collapsed: collapseMonitor.collapsed(),\n selected: isRowSelected(row.id),\n index: rowIndex,\n first: !!rowFirst,\n last: !!rowLast,\n even: !!rowEven,\n odd: !!rowOdd\n }\n \"></ng-container>\n </div>\n }\n </div>\n </td>\n </tr>\n } } @empty {\n <tr>\n <td [attr.colspan]=\"tableSpan\" class=\"no-data\">\n <ng-content select=\"[noData]\"></ng-content>\n </td>\n </tr>\n } }\n </tbody>\n <tfoot>\n @if (paginationComponent) {\n <tr>\n <td [attr.colspan]=\"tableSpan\">\n <ng-content\n select=\"impdc-pagination, div[impdc-pagination]\"></ng-content>\n </td>\n </tr>\n }\n </tfoot>\n</table>\n}\n", styles: [".bulk-action-container{display:flex;flex-direction:row;border:1px solid var(--impd-color-gray-200);border-top-left-radius:.6rem;border-top-right-radius:.6rem;border-bottom:0px}.bulk-action-container .bulk-action-checkbox{padding:1.6rem 2rem}.bulk-action-container .bulk-actions{display:flex;flex-direction:row;gap:.4rem}.col-no-padding{padding:0!important}.data-loading{height:var(--impd-size-80);vertical-align:middle;text-align:center}.no-data{vertical-align:middle;text-align:center}.select-row{display:flex;height:var(--impd-size-4);align-items:center;justify-items:end;border-radius:var(--impd-border-radius-default)}.heading-with-checkbox{padding-left:5px;padding-right:10px}.actions-column{width:.1%;white-space:nowrap}tr.impdc-table-collapsible-content-row:has(>td>div.impdc-table-collapsible-content-container.collapse:not(.show)){display:none}tr:has(td.impdc-table-collapsible-content-row-button-container),tr.impdc-table-collapsible-content-row{transition:background-color .35s ease-in-out}tr:has(td.impdc-table-collapsible-content-row-button-container.opened),tr.impdc-table-collapsible-content-row.opened{background-color:var(--impd-color-gray-50)}tr.impdc-table-collapsible-row-trigger{cursor:pointer}table ::ng-deep tbody>tr>td.impdc-table-selectable-row-toggle-container,table ::ng-deep tr>td.impdc-table-selectable-row-toggle-container,table ::ng-deep thead>tr>th.impdc-table-selectable-row-toggle-container,table ::ng-deep tr>th.impdc-table-selectable-row-toggle-container{padding-left:var(--impd-size-5);padding-right:var(--impd-size-1);width:var(--impd-size-10)}table ::ng-deep tbody>tr>td.impdc-table-collapsible-content-row-button-container,table ::ng-deep tr>td.impdc-table-collapsible-content-row-button-container,table ::ng-deep thead>tr>th.impdc-table-collapsible-content-row-button-container,table ::ng-deep tr>th.impdc-table-collapsible-content-row-button-container{padding-left:var(--impd-size-5);padding-right:0;width:var(--impd-size-10)}table ::ng-deep tbody>tr>td.impdc-table-collapsible-content-row-button-container:empty,table ::ng-deep tr>td.impdc-table-collapsible-content-row-button-container:empty,table ::ng-deep thead>tr>th.impdc-table-collapsible-content-row-button-container:empty,table ::ng-deep tr>th.impdc-table-collapsible-content-row-button-container:empty{padding:0}table ::ng-deep tbody>tr>td.impdc-table-collapsible-content-row-button-container+.impdc-table-selectable-row-toggle-container,table ::ng-deep tr>td.impdc-table-collapsible-content-row-button-container+.impdc-table-selectable-row-toggle-container,table ::ng-deep thead>tr>th.impdc-table-collapsible-content-row-button-container+.impdc-table-selectable-row-toggle-container,table ::ng-deep tr>th.impdc-table-collapsible-content-row-button-container+.impdc-table-selectable-row-toggle-container{padding-left:var(--impd-size-3);width:var(--impd-size-8)}.impdc-table-collapsible-content-row-button{align-items:center;border-radius:var(--impd-border-radius-2xl);color:var(--impd-color-gray-700)!important;display:flex;height:var(--impd-size-5);justify-content:center;padding:0;width:var(--impd-size-5);box-shadow:none}.impdc-table-collapsible-content-row-button:hover,.impdc-table-collapsible-content-row-button:focus,.impdc-table-collapsible-content-row-button:active{background-color:var(--impd-color-gray-100)}.impdc-table-collapsible-content-row-button impdc-icon{line-height:1}.impdc-table-collapsible-content-row-button>span.fa-chevron-right{font-size:1.6rem;transition:transform .35s}table.table-striped>tbody>tr:nth-of-type(4n+3)>*{--impartner-hex-table-bg-type: var(--impd-color-gray-50)}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3.BrandedDirective, selector: "[impdcBranded]" }, { kind: "component", type: i4.IconComponent, selector: "impdc-icon, [impdc-icon]", inputs: ["name", "theme", "size"] }, { kind: "component", type: i5.CheckboxComponent, selector: "impdc-checkbox", inputs: ["tabIndex", "id", "label", "description", "isSwitch", "switchIcons", "inline", "layout", "checked", "indeterminate", "disabled", "errorStateMatcher", "required"], outputs: ["change", "indeterminateChange"], exportAs: ["impdcCheckControl"] }, { kind: "component", type: i6.SelectOptionComponent, selector: "impdc-select-option", inputs: ["value", "label", "disabled"] }, { kind: "component", type: i7.SelectComponent, selector: "impdc-select", inputs: ["disabled", "tabIndex", "search", "placeholder", "required", "compareWith", "dropdownContainer", "errorStateMatcher", "allowClear", "multiple", "multipleDisplay"], outputs: ["selectionChange", "valueChange", "searchTextChanges"], exportAs: ["impdcSelect"] }, { kind: "directive", type: i8.InputDirective, selector: "input[impdcInput], textarea[impdcInput], select[impdcNativeSelect]", inputs: ["disabled", "id", "type", "required", "readonly", "errorStateMatcher", "value"], exportAs: ["impdcInput"] }, { kind: "directive", type: i9.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: i9.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i9.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i10.SpinnerComponent, selector: "impdc-spinner, div[impdc-spinner]", inputs: ["accessibilityText"] }, { kind: "component", type: i11.BadgeComponent, selector: "impdc-badge, [impdc-badge]", inputs: ["text", "icon", "theme", "size", "hideBg", "rounded", "dismissable"], outputs: ["dismiss"] }, { kind: "directive", type: i12.CollapseMonitorDirective, selector: "[impdcCollapseMonitor]", outputs: ["collapseChange"], exportAs: ["impdcCollapseMonitor"] }, { kind: "directive", type: i13.TableDirective, selector: "table[impdcTable]", inputs: ["striped", "hover", "layout"] }, { kind: "component", type: i14.ColumnHeadingComponent, selector: "impdc-column-heading", inputs: ["isSortable", "columnIndex", "sortColumnIndex", "direction", "text"], outputs: ["sort"] }, { kind: "directive", type: i15.TableInjectComponentDirective, selector: "[impdcTableInjectComponent]", inputs: ["columnDef", "value", "rowItem", "customCellComponents"] }, { kind: "component", type: i16.RowActionsComponent, selector: "impdc-row-actions", inputs: ["columnDef", "rowItem", "lastColumn"], outputs: ["actionClick"] }] }); }
356
417
  }
357
418
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: TableComponent, decorators: [{
358
419
  type: Component,
359
- args: [{ selector: 'impdc-table', template: "@if (tableData) {\n<table impdcTable [striped]=\"striped\">\n <thead>\n @if (!!bulkActions) {\n <tr>\n <th [attr.colspan]=\"tableSpan\" scope=\"col\" class=\"bulk-action-column\">\n <ng-content select=\"impdc-table-bulk-actions\"></ng-content>\n <ng-content select=\"[impdcTableBulkActions]\"></ng-content>\n </th>\n </tr>\n }\n <tr>\n @if (canSelectRows) {\n <th\n scope=\"col\"\n [ngClass]=\"{\n 'heading-below-bulk-actions': !!bulkActions\n }\">\n @if (canSelectAllRows) {\n <div>\n <impdc-checkbox\n ngModel\n [checked]=\"allSelected\"\n [indeterminate]=\"someSelected\"\n (change)=\"handleSelectAll($event)\"></impdc-checkbox>\n </div>\n }\n </th>\n } @for (columnDef of columnDefs; track columnDef; let columnIndex =\n $index) {\n <th\n scope=\"col\"\n [ngClass]=\"{\n 'sorted-column': isSortedColumn(columnIndex),\n 'sortable-column': columnDef.sorted,\n 'heading-below-bulk-actions': !!bulkActions\n }\"\n (click)=\"handleSort(columnIndex)\">\n <impdc-column-heading\n [isSortable]=\"columnDef.sorted || false\"\n [columnIndex]=\"columnIndex\"\n [sortColumnIndex]=\"sortColumnIndex\"\n [direction]=\"sortDirection\"\n [text]=\"columnDef.title\"\n (sort)=\"handleSort($event)\">\n </impdc-column-heading>\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @if (loading) {\n <tr>\n <td [attr.colspan]=\"tableSpan\" class=\"data-loading\">\n <impdc-spinner></impdc-spinner>\n </td>\n </tr>\n } @else { @for (row of tableData; track row; let rowIndex = $index) {\n <tr>\n @if (canSelectRows) {\n <td>\n <div class=\"select-column\">\n <impdc-checkbox\n [ngModel]=\"isRowSelected(row.id)\"\n (change)=\"handleRowSelect($event, row.id)\"></impdc-checkbox>\n </div>\n </td>\n }\n <td\n *ngFor=\"let columnDef of columnDefs; index as colIndex; last as isLast\"\n [ngClass]=\"{\n 'col-no-padding': !!columnDef.noPadding,\n 'actions-column': columnDef.columnType === cellType.Actions\n }\">\n <div>\n @switch (columnDef.columnType) { @case (cellType.Badge) {\n <span>\n <impdc-badge\n [text]=\"getStringValue(colIndex, row)\"\n [theme]=\"getTheme(columnDef, row)\">\n </impdc-badge>\n </span>\n } @case (cellType.Link) {\n <span (click)=\"handleLinkClick(colIndex, row)\">\n @if (!branded) {\n <a>\n {{ getValue(colIndex, row) }}\n </a>\n } @else {\n <a impdcBranded>\n {{ getValue(colIndex, row) }}\n </a>\n }\n </span>\n } @case (cellType.Url) {\n <span>\n @if (!branded) {\n <a target=\"_blank\" [attr.href]=\"getValue(colIndex, row)\">\n {{ getValue(colIndex, row) }}\n </a>\n } @else {\n <a\n impdcBranded\n target=\"_blank\"\n [attr.href]=\"getValue(colIndex, row)\">\n {{ getValue(colIndex, row) }}\n </a>\n }\n </span>\n } @case (cellType.Email) {\n <span>\n @if (!branded) {\n <a\n target=\"_blank\"\n [attr.href]=\"'mailto:' + getValue(colIndex, row)\">\n {{ getValue(colIndex, row) }}\n </a>\n } @else {\n <a impdcBranded [attr.href]=\"getMailToValue(colIndex, row)\">\n {{ getValue(colIndex, row) }}\n </a>\n }\n </span>\n } @case (cellType.Input) {\n <span>\n <input\n impdcInput\n type=\"text\"\n class=\"{{ getCellColor(columnDef, row) }}\"\n [ngModel]=\"getValue(colIndex, row)\"\n (ngModelChange)=\"\n handleCellValueChange(colIndex, rowIndex, $event)\n \" />\n </span>\n } @case (cellType.Boolean) {\n <span>\n @if (columnDef.disabled && getValue(colIndex, row) === 'true') {\n <span\n impdc-icon\n name=\"check\"\n class=\"{{ getCellColor(columnDef, row) }}\"></span>\n } @else if (!columnDef.disabled) {\n <impdc-checkbox\n [checked]=\"getValue(colIndex, row) === 'true'\"\n [isSwitch]=\"true\"\n (change)=\"\n handleCellValueChange(colIndex, rowIndex, $event.checked)\n \"></impdc-checkbox>\n }\n </span>\n } @case (cellType.SingleSelect) {\n <span>\n <impdc-select\n [ngModel]=\"getValue(colIndex, row)\"\n [disabled]=\"columnDef.disabled || false\"\n [placeholder]=\"selectPlaceholder\"\n allowClear=\"true\"\n (selectionChange)=\"\n handleCellValueChange(colIndex, rowIndex, $event.value)\n \">\n @for (value of (columnDef.values || []); track value) {\n <impdc-select-option\n [value]=\"value.value\"\n [label]=\"value.label\"></impdc-select-option>\n }\n </impdc-select>\n </span>\n } @case (cellType.MultiSelect) {\n <span>\n <impdc-select\n [ngModel]=\"getValue(colIndex, row)\"\n [disabled]=\"columnDef.disabled || false\"\n [placeholder]=\"selectPlaceholder\"\n multiple=\"true\"\n (selectionChange)=\"\n handleCellValueChange(colIndex, rowIndex, $event.value)\n \">\n @for (value of (columnDef.values || []); track value) {\n <impdc-select-option\n [value]=\"value.value\"\n [label]=\"value.label\"></impdc-select-option>\n }\n </impdc-select>\n </span>\n } @case (cellType.CellRender) {\n <span class=\"{{ getCellColor(columnDef, row) }}\">\n <ng-template\n impdcTableInjectComponent\n [columnDef]=\"columnDef\"\n [rowItem]=\"row\"\n [customCellComponents]=\"customCellComponents || {}\"\n [value]=\"getRawValue(colIndex, row)\"></ng-template>\n </span>\n } @case (cellType.Icon) {\n <span>\n <span\n impdc-icon\n [name]=\"columnDef.iconName\"\n class=\"{{ getCellColor(columnDef, row) }}\"></span>\n </span>\n } @case (cellType.Actions) {\n <span>\n <!-- will always return 'true', but needed to satisfy the type engine -->\n @if (columnDefIsActions(columnDef)) {\n <impdc-row-actions\n [columnDef]=\"columnDef\"\n [rowItem]=\"row\"\n [lastColumn]=\"isLast\"\n (actionClick)=\"\n handleActionClick(colIndex, row, $event)\n \"></impdc-row-actions>\n }\n </span>\n } @default {\n <span class=\"{{ getCellColor(columnDef, row) }}\">\n {{ getValue(colIndex, row) }}\n </span>\n } }\n </div>\n </td>\n </tr>\n } @empty {\n <tr>\n <td [attr.colspan]=\"tableSpan\" class=\"no-data\">\n <ng-content select=\"[noData]\"></ng-content>\n </td>\n </tr>\n } }\n </tbody>\n <tfoot>\n @if (paginationComponent) {\n <tr>\n <td [attr.colspan]=\"tableSpan\">\n <ng-content\n select=\"impdc-pagination, div[impdc-pagination]\"></ng-content>\n </td>\n </tr>\n }\n </tfoot>\n</table>\n}\n", styles: [".bulk-action-container{display:flex;flex-direction:row;border:1px solid var(--impd-color-gray-200);border-top-left-radius:.6rem;border-top-right-radius:.6rem;border-bottom:0px}.bulk-action-container .bulk-action-checkbox{padding:1.6rem 2rem}.bulk-action-container .bulk-actions{display:flex;flex-direction:row;gap:.4rem}.col-no-padding{padding:0!important}.data-loading{height:var(--impd-size-80);vertical-align:middle;text-align:center}.no-data{vertical-align:middle;text-align:center}.select-row{display:flex;height:var(--impd-size-4);align-items:center;justify-items:end;border-radius:var(--impd-border-radius-default)}.heading-with-checkbox{padding-left:5px;padding-right:10px}.actions-column{width:.1%;white-space:nowrap}\n"] }]
420
+ args: [{ selector: 'impdc-table', template: "@if (tableData) {\n<table\n impdcTable\n [striped]=\"striped && !collapsibleTemplate\"\n [layout]=\"layout\"\n [hover]=\"hover\">\n <thead>\n @if (!!bulkActions) {\n <tr>\n <th [attr.colspan]=\"tableSpan\" scope=\"col\" class=\"bulk-action-column\">\n <ng-content select=\"impdc-table-bulk-actions\"></ng-content>\n <ng-content select=\"[impdcTableBulkActions]\"></ng-content>\n </th>\n </tr>\n }\n <tr>\n @if (collapsibleTemplate) {\n <th\n scope=\"col\"\n [class.heading-below-bulk-actions]=\"!!bulkActions\"\n class=\"impdc-table-collapsible-content-row-button-container\"></th>\n } @if (canSelectRows) {\n <th\n scope=\"col\"\n class=\"impdc-table-selectable-row-toggle-container\"\n [ngClass]=\"{\n 'heading-below-bulk-actions': !!bulkActions\n }\">\n @if (canSelectAllRows) {\n <div>\n <impdc-checkbox\n ngModel\n [checked]=\"allSelected\"\n [indeterminate]=\"someSelected\"\n (change)=\"handleSelectAll($event)\"></impdc-checkbox>\n </div>\n }\n </th>\n } @for (columnDef of columnDefs; track columnDef; let columnIndex =\n $index) {\n <th\n scope=\"col\"\n [ngClass]=\"{\n 'sorted-column': isSortedColumn(columnIndex),\n 'sortable-column': columnDef.sorted,\n 'heading-below-bulk-actions': !!bulkActions\n }\"\n (click)=\"handleSort(columnIndex)\">\n <impdc-column-heading\n [isSortable]=\"columnDef.sorted || false\"\n [columnIndex]=\"columnIndex\"\n [sortColumnIndex]=\"sortColumnIndex\"\n [direction]=\"sortDirection\"\n [text]=\"columnDef.title\"\n (sort)=\"handleSort($event)\">\n </impdc-column-heading>\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @if (loading) {\n <tr>\n <td [attr.colspan]=\"tableSpan\" class=\"data-loading\">\n <impdc-spinner></impdc-spinner>\n </td>\n </tr>\n } @else { @for (row of tableData; track row.id; let rowIndex = $index; let\n rowFirst = $first; let rowLast = $last; let rowEven = $even; let rowOdd =\n $odd) { @if (getCollapsibleTemplateForRow(row); as\n collapsibleTemplateForRow) {\n <tr\n [class.impdc-table-collapsible-row-trigger]=\"collapsibleTrigger === 'row'\"\n [class.table-active]=\"isRowSelected(row.id)\"\n (click)=\"\n tryToggleCollapse(collapsibleTemplateForRow, ngbCollapse, $event, 'row')\n \">\n @if (collapsibleTemplate) {\n <td\n class=\"impdc-table-collapsible-content-row-button-container\"\n [class.opened]=\"!collapseMonitor.ngbCollapsing()\">\n @if (collapsibleTemplateForRow.template) {\n <div>\n <button\n type=\"button\"\n (click)=\"\n tryToggleCollapse(\n collapsibleTemplateForRow,\n ngbCollapse,\n $event,\n 'button'\n )\n \"\n class=\"impdc-table-collapsible-content-row-button btn btn-link\">\n <span\n class=\"far fa-chevron-right\"\n [class.fa-rotate-90]=\"!collapseMonitor.ngbCollapsing()\"></span>\n </button>\n </div>\n }\n </td>\n } @if (canSelectRows) {\n <td class=\"impdc-table-selectable-row-toggle-container\">\n <div class=\"select-column\">\n <impdc-checkbox\n [ngModel]=\"isRowSelected(row.id)\"\n (change)=\"handleRowSelect($event, row.id)\"\n (click)=\"$event.stopPropagation()\"></impdc-checkbox>\n </div>\n </td>\n }\n <td\n *ngFor=\"let columnDef of columnDefs; index as colIndex; last as isLast\"\n [ngClass]=\"{\n 'col-no-padding': !!columnDef.noPadding,\n 'actions-column': columnDef.columnType === cellType.Actions\n }\">\n <div>\n @switch (columnDef.columnType) { @case (cellType.Badge) {\n <span>\n <impdc-badge\n [text]=\"getStringValue(colIndex, row)\"\n [theme]=\"getTheme(columnDef, row)\">\n </impdc-badge>\n </span>\n } @case (cellType.Link) {\n <span (click)=\"handleLinkClick(colIndex, row, $event)\">\n @if (!branded) {\n <a class=\"link-primary\">\n {{ getValue(colIndex, row) }}\n </a>\n } @else {\n <a impdcBranded>\n {{ getValue(colIndex, row) }}\n </a>\n }\n </span>\n } @case (cellType.Url) {\n <span>\n @if (!branded) {\n <a\n target=\"_blank\"\n [attr.href]=\"getValue(colIndex, row)\"\n (click)=\"$event.stopPropagation()\">\n {{ getValue(colIndex, row) }}\n </a>\n } @else {\n <a\n impdcBranded\n target=\"_blank\"\n [attr.href]=\"getValue(colIndex, row)\"\n (click)=\"$event.stopPropagation()\">\n {{ getValue(colIndex, row) }}\n </a>\n }\n </span>\n } @case (cellType.Email) {\n <span>\n @if (!branded) {\n <a\n target=\"_blank\"\n [attr.href]=\"'mailto:' + getValue(colIndex, row)\"\n (click)=\"$event.stopPropagation()\">\n {{ getValue(colIndex, row) }}\n </a>\n } @else {\n <a\n impdcBranded\n [attr.href]=\"getMailToValue(colIndex, row)\"\n (click)=\"$event.stopPropagation()\">\n {{ getValue(colIndex, row) }}\n </a>\n }\n </span>\n } @case (cellType.Input) {\n <span>\n <input\n impdcInput\n type=\"text\"\n class=\"{{ getCellColor(columnDef, row) }}\"\n [ngModel]=\"getValue(colIndex, row)\"\n (ngModelChange)=\"\n handleCellValueChange(colIndex, rowIndex, $event)\n \"\n (click)=\"$event.stopPropagation()\" />\n </span>\n } @case (cellType.Boolean) {\n <span>\n @if (columnDef.disabled && getValue(colIndex, row) === 'true') {\n <span\n impdc-icon\n name=\"check\"\n class=\"{{ getCellColor(columnDef, row) }}\"></span>\n } @else if (!columnDef.disabled) {\n <impdc-checkbox\n [checked]=\"getValue(colIndex, row) === 'true'\"\n [isSwitch]=\"true\"\n (change)=\"\n handleCellValueChange(colIndex, rowIndex, $event.checked)\n \"\n (click)=\"$event.stopPropagation()\"></impdc-checkbox>\n }\n </span>\n } @case (cellType.SingleSelect) {\n <span>\n <impdc-select\n [ngModel]=\"getValue(colIndex, row)\"\n [disabled]=\"columnDef.disabled || false\"\n [placeholder]=\"selectPlaceholder\"\n allowClear=\"true\"\n (selectionChange)=\"\n handleCellValueChange(colIndex, rowIndex, $event.value)\n \"\n (click)=\"$event.stopPropagation()\">\n @for (value of (columnDef.values || []); track value) {\n <impdc-select-option\n [value]=\"value.value\"\n [label]=\"value.label\"></impdc-select-option>\n }\n </impdc-select>\n </span>\n } @case (cellType.MultiSelect) {\n <span>\n <impdc-select\n [ngModel]=\"getValue(colIndex, row)\"\n [disabled]=\"columnDef.disabled || false\"\n [placeholder]=\"selectPlaceholder\"\n multiple=\"true\"\n (selectionChange)=\"\n handleCellValueChange(colIndex, rowIndex, $event.value)\n \"\n (click)=\"$event.stopPropagation()\">\n @for (value of (columnDef.values || []); track value) {\n <impdc-select-option\n [value]=\"value.value\"\n [label]=\"value.label\"></impdc-select-option>\n }\n </impdc-select>\n </span>\n } @case (cellType.CellRender) {\n <span class=\"{{ getCellColor(columnDef, row) }}\">\n <ng-template\n impdcTableInjectComponent\n [columnDef]=\"columnDef\"\n [rowItem]=\"row\"\n [customCellComponents]=\"customCellComponents || {}\"\n [value]=\"getRawValue(colIndex, row)\"></ng-template>\n </span>\n } @case (cellType.Icon) {\n <span>\n <span\n impdc-icon\n [name]=\"columnDef.iconName\"\n class=\"{{ getCellColor(columnDef, row) }}\"></span>\n </span>\n } @case (cellType.Actions) {\n <span>\n <!-- will always return 'true', but needed to satisfy the type engine -->\n @if (columnDefIsActions(columnDef)) {\n <impdc-row-actions\n [columnDef]=\"columnDef\"\n [rowItem]=\"row\"\n [lastColumn]=\"isLast\"\n (actionClick)=\"handleActionClick(colIndex, row, $event)\"\n (click)=\"$event.stopPropagation()\"></impdc-row-actions>\n }\n </span>\n } @default {\n <span class=\"{{ getCellColor(columnDef, row) }}\">\n {{ getValue(colIndex, row) }}\n </span>\n } }\n </div>\n </td>\n </tr>\n <tr\n class=\"impdc-table-collapsible-content-row\"\n [class.opened]=\"!collapseMonitor.ngbCollapsing()\">\n <td class=\"w-100 p-0\" [attr.colspan]=\"tableSpan\">\n <div\n class=\"impdc-table-collapsible-content-container\"\n #ngbCollapse=\"ngbCollapse\"\n #collapseMonitor=\"impdcCollapseMonitor\"\n [impdcCollapseMonitor]=\"true\"\n (collapseChange)=\"rowCollapseChange.emit({ row, collapsed: $event })\">\n @if (collapsibleTemplateForRow.template) {\n <div>\n <ng-container\n *ngTemplateOutlet=\"\n collapsibleTemplateForRow.template;\n context: {\n $implicit: row,\n collapsed: collapseMonitor.collapsed(),\n selected: isRowSelected(row.id),\n index: rowIndex,\n first: !!rowFirst,\n last: !!rowLast,\n even: !!rowEven,\n odd: !!rowOdd\n }\n \"></ng-container>\n </div>\n }\n </div>\n </td>\n </tr>\n } } @empty {\n <tr>\n <td [attr.colspan]=\"tableSpan\" class=\"no-data\">\n <ng-content select=\"[noData]\"></ng-content>\n </td>\n </tr>\n } }\n </tbody>\n <tfoot>\n @if (paginationComponent) {\n <tr>\n <td [attr.colspan]=\"tableSpan\">\n <ng-content\n select=\"impdc-pagination, div[impdc-pagination]\"></ng-content>\n </td>\n </tr>\n }\n </tfoot>\n</table>\n}\n", styles: [".bulk-action-container{display:flex;flex-direction:row;border:1px solid var(--impd-color-gray-200);border-top-left-radius:.6rem;border-top-right-radius:.6rem;border-bottom:0px}.bulk-action-container .bulk-action-checkbox{padding:1.6rem 2rem}.bulk-action-container .bulk-actions{display:flex;flex-direction:row;gap:.4rem}.col-no-padding{padding:0!important}.data-loading{height:var(--impd-size-80);vertical-align:middle;text-align:center}.no-data{vertical-align:middle;text-align:center}.select-row{display:flex;height:var(--impd-size-4);align-items:center;justify-items:end;border-radius:var(--impd-border-radius-default)}.heading-with-checkbox{padding-left:5px;padding-right:10px}.actions-column{width:.1%;white-space:nowrap}tr.impdc-table-collapsible-content-row:has(>td>div.impdc-table-collapsible-content-container.collapse:not(.show)){display:none}tr:has(td.impdc-table-collapsible-content-row-button-container),tr.impdc-table-collapsible-content-row{transition:background-color .35s ease-in-out}tr:has(td.impdc-table-collapsible-content-row-button-container.opened),tr.impdc-table-collapsible-content-row.opened{background-color:var(--impd-color-gray-50)}tr.impdc-table-collapsible-row-trigger{cursor:pointer}table ::ng-deep tbody>tr>td.impdc-table-selectable-row-toggle-container,table ::ng-deep tr>td.impdc-table-selectable-row-toggle-container,table ::ng-deep thead>tr>th.impdc-table-selectable-row-toggle-container,table ::ng-deep tr>th.impdc-table-selectable-row-toggle-container{padding-left:var(--impd-size-5);padding-right:var(--impd-size-1);width:var(--impd-size-10)}table ::ng-deep tbody>tr>td.impdc-table-collapsible-content-row-button-container,table ::ng-deep tr>td.impdc-table-collapsible-content-row-button-container,table ::ng-deep thead>tr>th.impdc-table-collapsible-content-row-button-container,table ::ng-deep tr>th.impdc-table-collapsible-content-row-button-container{padding-left:var(--impd-size-5);padding-right:0;width:var(--impd-size-10)}table ::ng-deep tbody>tr>td.impdc-table-collapsible-content-row-button-container:empty,table ::ng-deep tr>td.impdc-table-collapsible-content-row-button-container:empty,table ::ng-deep thead>tr>th.impdc-table-collapsible-content-row-button-container:empty,table ::ng-deep tr>th.impdc-table-collapsible-content-row-button-container:empty{padding:0}table ::ng-deep tbody>tr>td.impdc-table-collapsible-content-row-button-container+.impdc-table-selectable-row-toggle-container,table ::ng-deep tr>td.impdc-table-collapsible-content-row-button-container+.impdc-table-selectable-row-toggle-container,table ::ng-deep thead>tr>th.impdc-table-collapsible-content-row-button-container+.impdc-table-selectable-row-toggle-container,table ::ng-deep tr>th.impdc-table-collapsible-content-row-button-container+.impdc-table-selectable-row-toggle-container{padding-left:var(--impd-size-3);width:var(--impd-size-8)}.impdc-table-collapsible-content-row-button{align-items:center;border-radius:var(--impd-border-radius-2xl);color:var(--impd-color-gray-700)!important;display:flex;height:var(--impd-size-5);justify-content:center;padding:0;width:var(--impd-size-5);box-shadow:none}.impdc-table-collapsible-content-row-button:hover,.impdc-table-collapsible-content-row-button:focus,.impdc-table-collapsible-content-row-button:active{background-color:var(--impd-color-gray-100)}.impdc-table-collapsible-content-row-button impdc-icon{line-height:1}.impdc-table-collapsible-content-row-button>span.fa-chevron-right{font-size:1.6rem;transition:transform .35s}table.table-striped>tbody>tr:nth-of-type(4n+3)>*{--impartner-hex-table-bg-type: var(--impd-color-gray-50)}\n"] }]
360
421
  }], ctorParameters: () => [{ type: i1.DatePipe }, { type: i1.PercentPipe }, { type: i1.DecimalPipe }, { type: i0.ChangeDetectorRef }, { type: i2.BrandedDirective, decorators: [{
361
422
  type: Optional
362
423
  }, {
@@ -367,6 +428,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.1", ngImpor
367
428
  type: Input
368
429
  }], striped: [{
369
430
  type: Input
431
+ }], hover: [{
432
+ type: Input
433
+ }], layout: [{
434
+ type: Input
370
435
  }], canSelectRows: [{
371
436
  type: Input
372
437
  }], canSelectAllRows: [{
@@ -383,6 +448,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.1", ngImpor
383
448
  type: Input
384
449
  }], customCellComponents: [{
385
450
  type: Input
451
+ }], collapsibleTemplate: [{
452
+ type: Input
453
+ }], collapsibleTrigger: [{
454
+ type: Input
386
455
  }], rowSelect: [{
387
456
  type: Output
388
457
  }], sortBy: [{
@@ -391,13 +460,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.1", ngImpor
391
460
  type: Output
392
461
  }], rowActionClick: [{
393
462
  type: Output
463
+ }], inputChange: [{
464
+ type: Output
465
+ }], rowCollapseChange: [{
466
+ type: Output
394
467
  }], paginationComponent: [{
395
468
  type: ContentChild,
396
469
  args: [PaginationComponent]
397
470
  }], bulkActions: [{
398
471
  type: ContentChild,
399
472
  args: [TableBulkActionsComponent]
400
- }], inputChange: [{
401
- type: Output
402
473
  }] } });
403
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZGVzaWduLWNvbXBvbmVudHMvc3JjL2xpYi90YWJsZS9jb250YWluZXJzL3RhYmxlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Rlc2lnbi1jb21wb25lbnRzL3NyYy9saWIvdGFibGUvY29udGFpbmVycy90YWJsZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBRUwsU0FBUyxFQUNULFlBQVksRUFDWixZQUFZLEVBQ1osSUFBSSxFQUNKLEtBQUssRUFFTCxRQUFRLEVBQ1IsTUFBTSxFQUVQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxHQUFHLElBQUksY0FBYyxFQUFFLEdBQUcsSUFBSSxjQUFjLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDdEUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTlDLE9BQU8sRUFBRSxhQUFhLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN0RSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFheEQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQzlDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVoRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxlQUFlLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRTFEOzs7R0FHRztBQU1ILE1BQU0sT0FBTyxjQUFjO0lBb0J6Qjs7T0FFRztJQUNILElBQW9CLGFBQWEsQ0FBQyxLQUFjO1FBQzlDLElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDO0lBQzlCLENB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SUFBSSxFQUFFLENBQUM7U0FDcEI7UUFBQyxPQUFPLENBQUMsRUFBRTtZQUNWLE9BQU8sRUFBRSxDQUFDO1NBQ1g7SUFDSCxDQUFDOzhHQXZiVSxjQUFjO2tHQUFkLGNBQWMseWxCQXFHWCxtQkFBbUIsOEVBSW5CLHlCQUF5QixxRUN0SnpDLDY1UEFpUEE7OzJGRHBNYSxjQUFjO2tCQUwxQixTQUFTOytCQUNFLGFBQWE7OzBCQXlKcEIsUUFBUTs7MEJBQUksSUFBSTt5Q0FqSkgsT0FBTztzQkFBdEIsS0FBSztnQkFTVSxVQUFVO3NCQUF6QixLQUFLO2dCQUtVLE9BQU87c0JBQXRCLEtBQUs7Z0JBS2MsYUFBYTtzQkFBaEMsS0FBSztnQkFXSyxnQkFBZ0I7c0JBRDFCLEtBQUs7Z0JBWVUsaUJBQWlCO3NCQUFoQyxLQUFLO2dCQUtVLGVBQWU7c0JBQTlCLEtBQUs7Z0JBS1UsYUFBYTtzQkFBNUIsS0FBSztnQkFLVSxTQUFTO3NCQUF4QixLQUFLO2dCQU1LLGNBQWM7c0JBRHhCLEtBQUs7Z0JBWVUsb0JBQW9CO3NCQUFuQyxLQUFLO2dCQUtvQixTQUFTO3NCQUFsQyxNQUFNO2dCQUttQixNQUFNO3NCQUEvQixNQUFNO2dCQUttQixTQUFTO3NCQUFsQyxNQUFNO2dCQUttQixjQUFjO3NCQUF2QyxNQUFNO2dCQUtBLG1CQUFtQjtzQkFEekIsWUFBWTt1QkFBQyxtQkFBbUI7Z0JBSzFCLFdBQVc7c0JBRGpCLFlBQVk7dUJBQUMseUJBQXlCO2dCQU9iLFdBQVc7c0JBQXBDLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEYXRlUGlwZSwgRGVjaW1hbFBpcGUsIFBlcmNlbnRQaXBlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIENvbnRlbnRDaGlsZCxcbiAgRXZlbnRFbWl0dGVyLFxuICBIb3N0LFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPcHRpb25hbCxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2VzXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgZ2V0IGFzIGdldE5lc3RlZFZhbHVlLCBzZXQgYXMgc2V0TmVzdGVkVmFsdWUgfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgZGVib3VuY2VUaW1lIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBERUJPVU5DRV9USU1FLCBTT1JUX0NPTFVNTl9JTkRFWCB9IGZyb20gJy4uL2NvbnN0YW50cy9pbmRleCc7XG5pbXBvcnQgeyBUYWJsZUNvbHVtblR5cGUgfSBmcm9tICcuLi9lbnVtZXJhdGlvbnMvaW5kZXgnO1xuaW1wb3J0IHtcbiAgSUN1c3RvbUNlbGxSZW5kZXJlckNvbXBvbmVudHMsXG4gIElTb3J0QnlQYXlsb2FkLFxuICBJVGFibGVBY3Rpb25zQ29sdW1uRGVmLFxuICBJVGFibGVFdmVudFBheWxvYWQsXG4gIElUYWJsZVJvd0FjdGlvblBheWxvYWQsXG4gIElUYWJsZVJvd0l0ZW0sXG4gIElUYWJsZVJvd0l0ZW1WYWx1ZSxcbiAgSVRhYmxlUm93SXRlbVZhbHVlVHlwZXMsXG4gIFRhYmxlQ29sdW1uRGVmXG59IGZyb20gJy4uL2ludGVyZmFjZXMvaW5kZXgnO1xuaW1wb3J0IHsgQ2hlY2tib3hDaGFuZ2VFdmVudCB9IGZyb20gJy4uLy4uL2Zvcm0tZmllbGQnO1xuaW1wb3J0IHsgVGFibGVUaGVtZUhlbHBlciB9IGZyb20gJy4uL2hlbHBlcnMnO1xuaW1wb3J0IHsgQ29tcG9uZW50VGhlbWUgfSBmcm9tICcuLi8uLi8uLi90eXBlcyc7XG5pbXBvcnQgeyBCcmFuZGVkRGlyZWN0aXZlIH0gZnJvbSAnLi4vLi4vYnJhbmRpbmcnO1xuaW1wb3J0IHsgUGFnaW5hdGlvbkNvbXBvbmVudCB9IGZyb20gJy4uLy4uL3BhZ2luYXRpb24nO1xuaW1wb3J0IHsgVGFibGVCdWxrQWN0aW9uc0NvbXBvbmVudCB9IGZyb20gJy4uL2NvbXBvbmVudHMnO1xuXG4vKipcbiAqIFRoZSBgVGFibGVDb21wb25lbnRgIChgPGltcGRjLXRhYmxlYCkgaXMgYSBkYXRhIHRhYmxlIGNvbXBvbmVudC5cbiAqIFRvIHVzZSwgaW1wb3J0IGBUYWJsZU1vZHVsZWAgZnJvbSBgQGltcGFydG5lci9kZXNpZ24tY29tcG9uZW50c2AuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2ltcGRjLXRhYmxlJyxcbiAgc3R5bGVVcmxzOiBbJy4vdGFibGUuY29tcG9uZW50LnNjc3MnXSxcbiAgdGVtcGxhdGVVcmw6ICcuL3RhYmxlLmNvbXBvbmVudC5odG1sJ1xufSlcbmV4cG9ydCBjbGFzcyBUYWJsZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSB0YWJsZSBkYXRhIGlzIGN1cnJlbnRseSBiZWluZyBsb2FkZWQuIFRoZSBgPGltcGRjLXNwaW5uZXI+YCB3aWxsIHNob3cgaWYgZGF0YSBpcyBsb2FkaW5nLlxuICAgKi9cbiAgQElucHV0KCkgcHVibGljIGxvYWRpbmcgPSBmYWxzZTtcblxuICAvKipcbiAgICogVGhlIHZpc2libGUgY29sdW1ucyBvZiB0aGUgdGFibGUuICBFYWNoIGBJVGFibGVDb2x1bW5EZWZgIGRlZmluZXMgcHJvcGVydGllcyByZWdhcmRpbmcgdGhlIGRpc3BsYXksIGZvcm1hdHRpbmcgYW5kIGludGVyYWN0aW9uIG9mIHRoZSBjb2x1bW4ncyBjZWxscy5cbiAgICogQ29sdW1uL2NlbGwgY29sb3IgcHJlY2VkZW5jZSBpczpcbiAgICogMSkgYGZpZWxkQ29sb3JgIC0gYWxsb3dzIGFuIGBJVGFibGVDb2x1bW5EZWZgIHRvIGRlbGVnYXRlIHRoZSByZXNwb25zaWJpbGl0eSBvZiBjZWxsIGNvbG9yIHRvIGFuIGBJVGFibGVSb3dJdGVtYCBwcm9wZXJ0eS5cbiAgICogMikgYGNvbG9yR2V0dGVyYC0gYWxsb3dzIGFuIGBJVGFibGVDb2x1bW5EZWZgIHRvIGRlbGVnYXRlIHRoZSByZXNwb25zaWJpbGl0eSBvZiBjZWxsIGNvbG9yIHRvIGEgZnVuY3Rpb24gb2YgdGhlIGBJVGFibGVSb3dJdGVtYCBkZXRlcm1pbmVkIGJ5IHRoZSBkZXZlbG9wZXIuXG4gICAqIDMpIGBjb2xvcmAgLSBhIHByb3BlcnR5IG9mIGFuIGBJVGFibGVDb2x1bW5EZWZgLlxuICAgKi9cbiAgQElucHV0KCkgcHVibGljIGNvbHVtbkRlZnM6IFRhYmxlQ29sdW1uRGVmW10gPSBbXTtcblxuICAvKipcbiAgICogV2hldGhlciB0aGUgdGFibGUgaXMgc3RyaXBlZC5cbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyBzdHJpcGVkID0gdHJ1ZTtcblxuICAvKipcbiAgICogV2hldGhlciBpbmRpdmlkdWFsIHJvd3MgY2FuIGJlIHNlbGVjdGVkLiBXaWxsIGJlIGB0cnVlYCBpZiBleHBsaWNpdGx5IHNldCB0byBgdHJ1ZWAgb3IgYGNhblNlbGVjdEFsbFJvd3NgIGlzIGB0cnVlYC5cbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyBzZXQgY2FuU2VsZWN0Um93cyh2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMuX2NhblNlbGVjdFJvd3MgPSB2YWx1ZTtcbiAgfVxuICBwdWJsaWMgZ2V0IGNhblNlbGVjdFJvd3MoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuY2FuU2VsZWN0QWxsUm93cyB8fCB0aGlzLl9jYW5TZWxlY3RSb3dzIHx8ICEhdGhpcy5idWxrQWN0aW9ucztcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIGFsbCByb3dzIGNhbiBiZSBzZWxlY3RlZCBhdCBvbmNlLiBXaWxsIGJlIGB0cnVlYCBpZiBleHBsaWNpdGx5IHNldCB0byBgdHJ1ZWAgb3IgaWYgYFRhYmxlQnVsa0FjdGlvbnNDb21wb25lbnRgIGlzIGNvbnRlbnQgcHJvamVjdGVkLlxuICAgKi9cbiAgQElucHV0KClcbiAgcHVibGljIHNldCBjYW5TZWxlY3RBbGxSb3dzKHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5fY2FuU2VsZWN0QWxsUm93cyA9IHZhbHVlO1xuICB9XG5cbiAgcHVibGljIGdldCBjYW5TZWxlY3RBbGxSb3dzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9jYW5TZWxlY3RBbGxSb3dzIHx8ICEhdGhpcy5idWxrQWN0aW9ucztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgcGxhY2Vob2xkZXIgdGV4dCBhbmQgZW1wdHkgdmFsdWUgZGlzcGxheSB0ZXh0IGZvciBgPGltcGRjLXNlbGVjdD5gIGluc3RhbmNlcyBpbiBjZWxscyB3aXRoIGEgYElUYWJsZUNvbHVtbkRlZmAgYGNvbHVtblR5cGVgID0gYFNpbmdsZVNlbGVjdGAgb3IgYE11bHRpU2VsZWN0YC5cbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyBzZWxlY3RQbGFjZWhvbGRlciA9ICcnO1xuXG4gIC8qKlxuICAgKiBUaGUgYGNvbHVtbkRlZnNgIGluZGV4IG9mIHRoZSBjdXJyZW50bHkgc29ydGVkIGNvbHVtbi5cbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyBzb3J0Q29sdW1uSW5kZXggPSBTT1JUX0NPTFVNTl9JTkRFWDtcblxuICAvKipcbiAgICogVGhlIGRpcmVjdGlvbiBvZiB0aGUgY3VycmVudGx5IHNvcnRlZCBjb2x1bW4uXG4gICAqL1xuICBASW5wdXQoKSBwdWJsaWMgc29ydERpcmVjdGlvbjogJ2FzYycgfCAnZGVzYycgPSAnYXNjJztcblxuICAvKipcbiAgICogVGhlIHRhYmxlIHJvdyBkYXRhIGFzIGFuIGFycmF5IG9mIGBJVGFibGVSb3dJdGVtYC5cbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyB0YWJsZURhdGE6IElUYWJsZVJvd0l0ZW1bXSA9IFtdO1xuXG4gIC8qKlxuICAgKiBBbiBhcnJheSBvZiBjdXJyZW50bHkgc2VsZWN0ZWQgSURzIGZyb20gdGhlIGB0YWJsZURhdGFgIGlucHV0LiAgQXJyYXkgbXVzdCBiZSBvZiB0eXBlIGAoc3RyaW5nIHwgbnVtYmVyKVtdYC5cbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBzZXQgc2VsZWN0ZWRSb3dJZHModmFsdWU6IChzdHJpbmcgfCBudW1iZXIpW10pIHtcbiAgICB0aGlzLl9zZWxlY3RlZFJvd0lkcyA9IFsuLi52YWx1ZV07XG4gIH1cbiAgcHVibGljIGdldCBzZWxlY3RlZFJvd0lkcygpOiAoc3RyaW5nIHwgbnVtYmVyKVtdIHtcbiAgICByZXR1cm4gWy4uLnRoaXMuX3NlbGVjdGVkUm93SWRzXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgcmVnaXN0ZXJlZCBjdXN0b20gY2VsbCByZW5kZXJlciBjb21wb25lbnRzIGF2YWlsYWJsZSB0byBiZSB1c2VkIGluIHRoZSB0YWJsZSBpbnN0YW5jZS5cbiAgICogRm9yIGEgZ2l2ZW4gYElUYWJsZUNvbHVtbkRlZmAgaW4gdGhlIGBjb2x1bW5EZWZzYCBpbnB1dCwgdGhlIGBjZWxsUmVuZGVyZXJDb21wb25lbnRgIHByb3BlcnR5IHNob3VsZCBiZSBzZXQgdG8gdGhlIGtleSBvZiB0aGUgcmVnaXN0ZXJlZCBjb21wb25lbnQgaW4gdGhpcyBpbnB1dC5cbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyBjdXN0b21DZWxsQ29tcG9uZW50cz86IElDdXN0b21DZWxsUmVuZGVyZXJDb21wb25lbnRzO1xuXG4gIC8qKlxuICAgKiBFdmVudCBlbWl0dGVkIHdoZW4gb25lIG9yIG11bHRpcGxlIHJvd3MgYXJlIHNlbGVjdGVkLiBFbWl0cyBgKHN0cmluZyB8IG51bWJlcilbXWAgcGF5bG9hZC5cbiAgICovXG4gIEBPdXRwdXQoKSBwdWJsaWMgcmVhZG9ubHkgcm93U2VsZWN0ID0gbmV3IEV2ZW50RW1pdHRlcjwoc3RyaW5nIHwgbnVtYmVyKVtdPigpO1xuXG4gIC8qKlxuICAgKiBFdmVudCBlbWl0dGVkIHdoZW4gYSBjb2x1bW4gaXMgc29ydGVkLiBFbWl0cyBgSVNvcnRCeVBheWxvYWRgIHBheWxvYWQuXG4gICAqL1xuICBAT3V0cHV0KCkgcHVibGljIHJlYWRvbmx5IHNvcnRCeSA9IG5ldyBFdmVudEVtaXR0ZXI8SVNvcnRCeVBheWxvYWQ+KCk7XG5cbiAgLyoqXG4gICAqIEV2ZW50IGVtaXR0ZWQgd2hlbiBhIHJvdyBsaW5rIGlzIGNsaWNrZWQuIEVtaXRzIGBJVGFibGVFdmVudFBheWxvYWRgIHBheWxvYWQuXG4gICAqL1xuICBAT3V0cHV0KCkgcHVibGljIHJlYWRvbmx5IGxpbmtDbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8SVRhYmxlRXZlbnRQYXlsb2FkPigpO1xuXG4gIC8qKlxuICAgKiBFdmVudCBlbWl0dGVkIHdoZW4gYSByb3cgYWN0aW9uIGlzIGNsaWNrZWQuIEVtaXRzIGFuIGBJVGFibGVSb3dBY3Rpb25QYXlsb2FkYCBwYXlsb2FkLlxuICAgKi9cbiAgQE91dHB1dCgpIHB1YmxpYyByZWFkb25seSByb3dBY3Rpb25DbGljayA9XG4gICAgbmV3IEV2ZW50RW1pdHRlcjxJVGFibGVSb3dBY3Rpb25QYXlsb2FkPigpO1xuXG4gIC8qKiBAaWdub3JlICovXG4gIEBDb250ZW50Q2hpbGQoUGFnaW5hdGlvbkNvbXBvbmVudClcbiAgcHVibGljIHBhZ2luYXRpb25Db21wb25lbnQ/OiBQYWdpbmF0aW9uQ29tcG9uZW50ID0gdW5kZWZpbmVkO1xuXG4gIC8qKiBAaWdub3JlICovXG4gIEBDb250ZW50Q2hpbGQoVGFibGVCdWxrQWN0aW9uc0NvbXBvbmVudClcbiAgcHVibGljIGJ1bGtBY3Rpb25zPzogVGFibGVCdWxrQWN0aW9uc0NvbXBvbmVudCA9IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogRXZlbnQgZW1pdHRlZCB3aGVuIGEgcm93IGlucHV0IHZhbHVlIGlzIGNoYW5nZWQuIEVtaXR0ZWQgY2VsbHMgb2YgYGNvbHVtblR5cGVgIGBTaW5nbFNlbGVjdGAsIGBNdWx0aVNlbGVjdGAsIGBJbnB1dGAsIGBCb29sZWFuYCBvciBgSWNvbmAuXG4gICAqIE5vdCBlbWl0dGVkIGlmIGNvbHVtbiBkZWZpbml0aW9uIHByb3BlcnR5IGBkaXNhYmxlZGAgPSBgdHJ1ZWAuIEVtaXRzIGBJVGFibGVFdmVudFBheWxvYWRgIHBheWxvYWQuXG4gICAqL1xuICBAT3V0cHV0KCkgcHVibGljIHJlYWRvbmx5IGlucHV0Q2hhbmdlID1cbiAgICBuZXcgRXZlbnRFbWl0dGVyPElUYWJsZUV2ZW50UGF5bG9hZD4oKTtcblxuICAvKiogQGlnbm9yZSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgY2VsbFR5cGUgPSBUYWJsZUNvbHVtblR5cGU7XG4gIC8qKiBAaWdub3JlICovXG4gIHB1YmxpYyBhbGxTZWxlY3RlZCA9IHRydWU7XG4gIC8qKiBAaWdub3JlICovXG4gIHB1YmxpYyBnZXQgc29tZVNlbGVjdGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICAhIXRoaXMuX3NlbGVjdGVkUm93SWRzICYmXG4gICAgICB0aGlzLl9zZWxlY3RlZFJvd0lkcy5sZW5ndGggPiAwICYmXG4gICAgICAhIXRoaXMudGFibGVEYXRhICYmXG4gICAgICB0aGlzLnRhYmxlRGF0YS5sZW5ndGggPiAwICYmXG4gICAgICB0aGlzLl9zZWxlY3RlZFJvd0lkcy5sZW5ndGggPCB0aGlzLnRhYmxlRGF0YS5sZW5ndGhcbiAgICApO1xuICB9XG4gIC8qKiBAaWdub3JlICovXG4gIHB1YmxpYyByZWFkb25seSBicmFuZGVkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgLyoqIEBpZ25vcmUgKi9cbiAgcHVibGljIGdldCB0YWJsZVNwYW4oKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5jYW5TZWxlY3RSb3dzXG4gICAgICA/IHRoaXMuY29sdW1uRGVmcy5sZW5ndGggKyAxXG4gICAgICA6IHRoaXMuY29sdW1uRGVmcy5sZW5ndGg7XG4gIH1cblxuICBwcml2YXRlIF9jYW5TZWxlY3RSb3dzID0gZmFsc2U7XG4gIHByaXZhdGUgX2NhblNlbGVjdEFsbFJvd3MgPSBmYWxzZTtcbiAgcHJpdmF0ZSBfc2VsZWN0ZWRSb3dJZHM6IChzdHJpbmcgfCBudW1iZXIpW10gPSBbXTtcbiAgcHJpdmF0ZSByZWFkb25seSBfaW5wdXRDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPElUYWJsZUV2ZW50UGF5bG9hZD4oKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9kYXRlUGlwZTogRGF0ZVBpcGUsXG4gICAgcHJpdmF0ZSByZWFkb25seSBfcGVyY2VudFBpcGU6IFBlcmNlbnRQaXBlLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2RlY21pYWxQaXBlOiBEZWNpbWFsUGlwZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9jaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgQE9wdGlvbmFsKCkgQEhvc3QoKSBwcml2YXRlIF9icmFuZGVkOiBCcmFuZGVkRGlyZWN0aXZlXG4gICkge1xuICAgIHRoaXMuYnJhbmRlZCA9IF9icmFuZGVkID8gdHJ1ZSA6IGZhbHNlO1xuICAgIHRoaXMuX2lucHV0Q2hhbmdlXG4gICAgICAucGlwZShkZWJvdW5jZVRpbWUoREVCT1VOQ0VfVElNRSkpXG4gICAgICAuc3Vic2NyaWJlKHRoaXMuaW5wdXRDaGFuZ2UpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChjaGFuZ2VzWydzZWxlY3RlZFJvd0lkcyddIHx8IGNoYW5nZXNbJ3RhYmxlRGF0YSddKSB7XG4gICAgICBpZiAoXG4gICAgICAgICF0aGlzLnRhYmxlRGF0YSB8fFxuICAgICAgICAhdGhpcy50YWJsZURhdGEubGVuZ3RoIHx8XG4gICAgICAgICF0aGlzLnNlbGVjdGVkUm93SWRzIHx8XG4gICAgICAgICF0aGlzLnNlbGVjdGVkUm93SWRzLmxlbmd0aFxuICAgICAgKSB7XG4gICAgICAgIHRoaXMuYWxsU2VsZWN0ZWQgPSBmYWxzZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuYWxsU2VsZWN0ZWQgPSB0aGlzLnNlbGVjdGVkUm93SWRzLmxlbmd0aCA+PSB0aGlzLnRhYmxlRGF0YS5sZW5ndGg7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGdldE1haWxUb1ZhbHVlKFxuICAgIGNvbHVtbkluZGV4OiBudW1iZXIsXG4gICAgY3VycmVudFJvdzogSVRhYmxlUm93SXRlbVxuICApOiBzdHJpbmcge1xuICAgIGNvbnN0IHsgY29sdW1uVHlwZSwgdHJ1bmNhdGVkOiB0cnVuY2F0ZWQgfSA9XG4gICAgICB0aGlzLl9nZXRDb2x1bW5EZWZCeUluZGV4KGNvbHVtbkluZGV4KTtcbiAgICBsZXQgdmFsdWUgPSB0aGlzLl9nZXRWYWx1ZShjb2x1bW5JbmRleCwgY3VycmVudFJvdyk7XG5cbiAgICBpZiAoY29sdW1uVHlwZSAhPT0gVGFibGVDb2x1bW5UeXBlLkVtYWlsKSB7XG4gICAgICByZXR1cm4gU3RyaW5nKHZhbHVlKTtcbiAgICB9XG4gICAgdmFsdWUgPSB2YWx1ZSA/IGBtYWlsdG86JHt2YWx1ZX1gIDogdmFsdWU7XG5cbiAgICByZXR1cm4gU3RyaW5nKHZhbHVlKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRTdHJpbmdWYWx1ZShcbiAgICBjb2x1bW5JbmRleDogbnVtYmVyLFxuICAgIGN1cnJlbnRSb3c6IElUYWJsZVJvd0l0ZW1cbiAgKTogc3RyaW5nIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZ2V0VmFsdWUoY29sdW1uSW5kZXgsIGN1cnJlbnRSb3cpO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdmFsdWUuam9pbignOycpO1xuICAgIH1cblxuICAgIHJldHVybiBTdHJpbmcodmFsdWUpO1xuICB9XG5cbiAgcHVibGljIGdldFZhbHVlKFxuICAgIGNvbHVtbkluZGV4OiBudW1iZXIsXG4gICAgY3VycmVudFJvdzogSVRhYmxlUm93SXRlbVxuICApOiBzdHJpbmcgfCBzdHJpbmdbXSB7XG4gICAgY29uc3QgeyBjb2x1bW5UeXBlLCB0cnVuY2F0ZWQ6IHRydW5jYXRlZCB9ID1cbiAgICAgIHRoaXMuX2dldENvbHVtbkRlZkJ5SW5kZXgoY29sdW1uSW5kZXgpO1xuICAgIGxldCB2YWx1ZSA9IHRoaXMuX2dldFZhbHVlKGNvbHVtbkluZGV4LCBjdXJyZW50Um93KTtcblxuICAgIHN3aXRjaCAoY29sdW1uVHlwZSkge1xuICAgICAgY2FzZSBUYWJsZUNvbHVtblR5cGUuRGVjaW1hbDoge1xuICAgICAgICB2YWx1ZSA9IHRoaXMuX2RlY21pYWxQaXBlLnRyYW5zZm9ybShOdW1iZXIodmFsdWUpIHx8IDApIHx8ICcnO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgVGFibGVDb2x1bW5UeXBlLkRhdGU6IHtcbiAgICAgICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKFN0cmluZyh2YWx1ZSkpO1xuICAgICAgICBjb25zdCB2YWxpZERhdGUgPSBkYXRlIGluc3RhbmNlb2YgRGF0ZSAmJiAhaXNOYU4oZGF0ZS5nZXRUaW1lKCkpO1xuICAgICAgICB2YWx1ZSA9IHZhbGlkRGF0ZVxuICAgICAgICAgID8gdGhpcy5fZGF0ZVBpcGUudHJhbnNmb3JtKGRhdGUsICdNTS9kZC95eXl5JykgfHwgJydcbiAgICAgICAgICA6IFN0cmluZyh2YWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSBUYWJsZUNvbHVtblR5cGUuRGF0ZVRpbWU6IHtcbiAgICAgICAgY29uc3QgZGF0ZVRpbWUgPSBuZXcgRGF0ZShTdHJpbmcodmFsdWUpKTtcbiAgICAgICAgY29uc3QgdmFsaWREYXRlVGltZSA9XG4gICAgICAgICAgZGF0ZVRpbWUgaW5zdGFuY2VvZiBEYXRlICYmICFpc05hTihkYXRlVGltZS5nZXRUaW1lKCkpO1xuICAgICAgICB2YWx1ZSA9IHZhbGlkRGF0ZVRpbWVcbiAgICAgICAgICA/IHRoaXMuX2RhdGVQaXBlLnRyYW5zZm9ybShkYXRlVGltZSwgJ01NL2RkL3l5eXkgaDptbTpzcyBhJykgfHwgJydcbiAgICAgICAgICA6IFN0cmluZyh2YWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSBUYWJsZUNvbHVtblR5cGUuTGluazoge1xuICAgICAgICB2YWx1ZSA9IFN0cmluZyh2YWx1ZSkucmVwbGFjZSgvKF5cXHcrOnxeKVxcL1xcLy8sICcnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlIFRhYmxlQ29sdW1uVHlwZS5QZXJjZW50YWdlOiB7XG4gICAgICAgIHZhbHVlID0gdGhpcy5fcGVyY2VudFBpcGUudHJhbnNmb3JtKE51bWJlcih2YWx1ZSkgfHwgMCkgfHwgJyc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSBUYWJsZUNvbHVtblR5cGUuVXJsOiB7XG4gICAgICAgIGlmICghLyhodHRwKHM/KSk6XFwvXFwvL2kudGVzdChTdHJpbmcodmFsdWUpKSkge1xuICAgICAgICAgIHZhbHVlID0gYGh0dHBzOi8vJHt2YWx1ZX1gO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSBUYWJsZUNvbHVtblR5cGUuVGV4dDoge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICB2YWx1ZSA9IHZhbHVlLmpvaW4oJzsgJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRydW5jYXRlZCkge1xuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRydW5jYXRlU3RyaW5nID0gKHN0cmluZyA9ICcnLCBtYXhMZW5ndGggPSB0cnVuY2F0ZWQpID0+XG4gICAgICAgICAgc3RyaW5nLmxlbmd0aCA+IG1heExlbmd0aFxuICAgICAgICAgICAgPyBgJHtzdHJpbmcuc3Vic3RyaW5nKDAsIG1heExlbmd0aCl94oCmYFxuICAgICAgICAgICAgOiBzdHJpbmc7XG5cbiAgICAgICAgISF0cnVuY2F0ZWRcbiAgICAgICAgICA/ICh2YWx1ZSA9IHRydW5jYXRlU3RyaW5nKFN0cmluZyh2YWx1ZSksIHRydW5jYXRlZCkpXG4gICAgICAgICAgOiB2YWx1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlIFRhYmxlQ29sdW1uVHlwZS5NdWx0aVNlbGVjdDpcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnNwbGl0KCc7Jyk/Lm1hcCh2ID0+IHYudHJpbSgpKSB8fCBbXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIFN0cmluZyh2YWx1ZSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0UmF3VmFsdWUoXG4gICAgY29sdW1uSW5kZXg6IG51bWJlcixcbiAgICBjdXJyZW50Um93OiBJVGFibGVSb3dJdGVtXG4gICk6IElUYWJsZVJvd0l0ZW1WYWx1ZVR5cGVzPElUYWJsZVJvd0l0ZW1WYWx1ZT4ge1xuICAgIGNvbnN0IHsgZmllbGQgfSA9IHRoaXMuX2dldENvbHVtbkRlZkJ5SW5kZXgoY29sdW1uSW5kZXgpO1xuXG4gICAgaWYgKCFmaWVsZCkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIHJldHVybiBjdXJyZW50Um93W2ZpZWxkXSB8fCAnJztcbiAgfVxuXG4gIHB1YmxpYyBnZXRDZWxsQ29sb3IoXG4gICAgY29sdW1uRGVmaW5pdGlvbjogVGFibGVDb2x1bW5EZWYsXG4gICAgaXRlbTogSVRhYmxlUm93SXRlbVxuICApOiBzdHJpbmcge1xuICAgIHJldHVybiBUYWJsZVRoZW1lSGVscGVyLmdldENlbGxDb2xvcihjb2x1bW5EZWZpbml0aW9uLCBpdGVtKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRUaGVtZShcbiAgICBjb2x1bW5EZWZpbml0aW9uOiBUYWJsZUNvbHVtbkRlZixcbiAgICBpdGVtOiBJVGFibGVSb3dJdGVtXG4gICk6IENvbXBvbmVudFRoZW1lIHtcbiAgICByZXR1cm4gKFxuICAgICAgVGFibGVUaGVtZUhlbHBlci5nZXRUaGVtZShjb2x1bW5EZWZpbml0aW9uLCBpdGVtKSB8fFxuICAgICAgQ29tcG9uZW50VGhlbWUuUHJpbWFyeVxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgaXNTb3J0ZWRDb2x1bW4oY29sdW1uSW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiBjb2x1bW5JbmRleCA9PT0gdGhpcy5zb3J0Q29sdW1uSW5kZXg7XG4gIH1cblxuICBwdWJsaWMgaXNSb3dTZWxlY3RlZChpZDogc3RyaW5nIHwgbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWRSb3dJZHMuaW5jbHVkZXMoaWQpO1xuICB9XG5cbiAgcHVibGljIGhhbmRsZVNlbGVjdEFsbChldmVudDogQ2hlY2tib3hDaGFuZ2VFdmVudCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5jYW5TZWxlY3RBbGxSb3dzIHx8ICF0aGlzLnRhYmxlRGF0YSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChldmVudC5jaGVja2VkKSB7XG4gICAgICB0aGlzLl9zZWxlY3RlZFJvd0lkcyA9IHRoaXMudGFibGVEYXRhPy5tYXAocm93ID0+IHJvdy5pZCkgfHwgW107XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3NlbGVjdGVkUm93SWRzID0gW107XG4gICAgfVxuXG4gICAgdGhpcy5fc2VsZWN0ZWRSb3dJZHMuc29ydCgpO1xuICAgIHRoaXMuYWxsU2VsZWN0ZWQgPSB0aGlzLnNlbGVjdGVkUm93SWRzLmxlbmd0aCA+PSB0aGlzLnRhYmxlRGF0YS5sZW5ndGg7XG5cbiAgICB0aGlzLnJvd1NlbGVjdC5lbWl0KHRoaXMuc2VsZWN0ZWRSb3dJZHMpO1xuICB9XG5cbiAgcHVibGljIGhhbmRsZVNvcnQoY29sdW1uSW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGlmIChjb2x1bW5JbmRleCA9PT0gdGhpcy5zb3J0Q29sdW1uSW5kZXgpIHtcbiAgICAgIHRoaXMuc29ydERpcmVjdGlvbiA9IHRoaXMuc29ydERpcmVjdGlvbiA9PT0gJ2FzYycgPyAnZGVzYycgOiAnYXNjJztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zb3J0Q29sdW1uSW5kZXggPSBjb2x1bW5JbmRleDtcbiAgICAgIHRoaXMuc29ydERpcmVjdGlvbiA9ICdhc2MnO1xuICAgIH1cblxuICAgIGNvbnN0IGZpZWxkID0gdGhpcy5fZ2V0Q29sdW1uRGVmQnlJbmRleChjb2x1bW5JbmRleCkuZmllbGQgfHwgJyc7XG5cbiAgICB0aGlzLnNvcnRCeS5lbWl0KHtcbiAgICAgIGNvbHVtbkluZGV4LFxuICAgICAgZmllbGQsXG4gICAgICBkaXJlY3Rpb246IHRoaXMuc29ydERpcmVjdGlvblxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGhhbmRsZVJvd1NlbGVjdChcbiAgICBldmVudDogQ2hlY2tib3hDaGFuZ2VFdmVudCxcbiAgICByb3dJZDogbnVtYmVyIHwgc3RyaW5nXG4gICk6IHZvaWQge1xuICAgIGlmICghdGhpcy5jYW5TZWxlY3RSb3dzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGV2ZW50LmNoZWNrZWQgJiYgIXRoaXMuX3NlbGVjdGVkUm93SWRzLmluY2x1ZGVzKHJvd0lkKSkge1xuICAgICAgdGhpcy5fc2VsZWN0ZWRSb3dJZHMucHVzaChyb3dJZCk7XG4gICAgfSBlbHNlIGlmICghZXZlbnQuY2hlY2tlZCAmJiB0aGlzLl9zZWxlY3RlZFJvd0lkcy5pbmNsdWRlcyhyb3dJZCkpIHtcbiAgICAgIGNvbnN0IGlkeCA9IHRoaXMuX3NlbGVjdGVkUm93SWRzLmluZGV4T2Yocm93SWQpO1xuICAgICAgaWYgKGlkeCA+IC0xKSB7XG4gICAgICAgIHRoaXMuX3NlbGVjdGVkUm93SWRzLnNwbGljZShpZHgsIDEpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLl9zZWxlY3RlZFJvd0lkcy5sZW5ndGgpIHtcbiAgICAgIHRoaXMuX3NlbGVjdGVkUm93SWRzLnNvcnQoKTtcbiAgICB9XG5cbiAgICB0aGlzLmFsbFNlbGVjdGVkID0gdGhpcy5zZWxlY3RlZFJvd0lkcy5sZW5ndGggPj0gdGhpcy50YWJsZURhdGEubGVuZ3RoO1xuICAgIHRoaXMucm93U2VsZWN0LmVtaXQodGhpcy5zZWxlY3RlZFJvd0lkcyk7XG4gIH1cblxuICBwdWJsaWMgaGFuZGxlQ2VsbFZhbHVlQ2hhbmdlKFxuICAgIGNvbHVtbkluZGV4OiBudW1iZXIsXG4gICAgcm93SW5kZXg6IG51bWJlcixcbiAgICB2YWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbiB8IHN0cmluZ1tdXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IHsgZmllbGQsIGNvbHVtblR5cGUgfSA9IHRoaXMuX2dldENvbHVtbkRlZkJ5SW5kZXgoY29sdW1uSW5kZXgpO1xuICAgIGxldCBjdXJyZW50VmFsdWU6IHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4gfCBzdHJpbmdbXSA9IHZhbHVlO1xuXG4gICAgaWYgKGNvbHVtblR5cGUgIT09IFRhYmxlQ29sdW1uVHlwZS5Cb29sZWFuICYmICFBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgY3VycmVudFZhbHVlID0gaXNOYU4oTnVtYmVyKHZhbHVlKSkgPyB2YWx1ZSA6IE51bWJlcih2YWx1ZSk7XG4gICAgfVxuICAgIGNvbnN0IGl0ZW0gPSB0aGlzLnRhYmxlRGF0YVtyb3dJbmRleF07XG5cbiAgICBzZXROZXN0ZWRWYWx1ZShpdGVtLCBTdHJpbmcoZmllbGQpLCBjdXJyZW50VmFsdWUpO1xuXG4gICAgdGhpcy5faW5wdXRDaGFuZ2UuZW1pdCh7XG4gICAgICBjb2x1bW5JbmRleCxcbiAgICAgIGl0ZW0sXG4gICAgICB2YWx1ZTogY3VycmVudFZhbHVlXG4gICAgfSk7XG5cbiAgICB0aGlzLl9jaGFuZ2VEZXRlY3RvclJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICBwdWJsaWMgaGFuZGxlTGlua0NsaWNrKGNvbHVtbkluZGV4OiBudW1iZXIsIGl0ZW06IElUYWJsZVJvd0l0ZW0pOiB2b2lkIHtcbiAgICB0aGlzLmxpbmtDbGljay5lbWl0KHtcbiAgICAgIGl0ZW0sXG4gICAgICBjb2x1bW5JbmRleFxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGhhbmRsZUFjdGlvbkNsaWNrKFxuICAgIGNvbHVtbkluZGV4OiBudW1iZXIsXG4gICAgaXRlbTogSVRhYmxlUm93SXRlbSxcbiAgICBhY3Rpb25BcGlOYW1lOiBzdHJpbmdcbiAgKSB7XG4gICAgdGhpcy5yb3dBY3Rpb25DbGljay5lbWl0KHtcbiAgICAgIGl0ZW0sXG4gICAgICBjb2x1bW5JbmRleCxcbiAgICAgIGFjdGlvbkFwaU5hbWVcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjb2x1bW5EZWZJc0FjdGlvbnMoXG4gICAgY29sdW1uRGVmOiBUYWJsZUNvbHVtbkRlZjxhbnk+XG4gICk6IGNvbHVtbkRlZiBpcyBJVGFibGVBY3Rpb25zQ29sdW1uRGVmPGFueT4ge1xuICAgIHJldHVybiBjb2x1bW5EZWYuY29sdW1uVHlwZSA9PT0gVGFibGVDb2x1bW5UeXBlLkFjdGlvbnM7XG4gIH1cblxuICBwcml2YXRlIF9nZXRDb2x1bW5EZWZCeUluZGV4KGNvbHVtbkluZGV4OiBudW1iZXIpOiBUYWJsZUNvbHVtbkRlZiB7XG4gICAgcmV0dXJuIHRoaXMuY29sdW1uRGVmc1tjb2x1bW5JbmRleF07XG4gIH1cblxuICBwcml2YXRlIF9nZXRWYWx1ZShcbiAgICBjb2x1bW5JbmRleDogbnVtYmVyLFxuICAgIGN1cnJlbnRSb3c6IElUYWJsZVJvd0l0ZW1cbiAgKTogc3RyaW5nIHwgc3RyaW5nW10ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB7IGZpZWxkLCB2YWx1ZUdldHRlciB9ID0gdGhpcy5fZ2V0Q29sdW1uRGVmQnlJbmRleChjb2x1bW5JbmRleCk7XG5cbiAgICAgIGNvbnN0IHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSA9IHZhbHVlR2V0dGVyXG4gICAgICAgID8gdmFsdWVHZXR0ZXIoY3VycmVudFJvdylcbiAgICAgICAgOiAoZ2V0TmVzdGVkVmFsdWUoY3VycmVudFJvdywgU3RyaW5nKGZpZWxkKSwgJycpIGFzIHN0cmluZyB8IHN0cmluZ1tdKTtcblxuICAgICAgcmV0dXJuIHZhbHVlIHx8ICcnO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gIH1cbn1cbiIsIkBpZiAodGFibGVEYXRhKSB7XG48dGFibGUgaW1wZGNUYWJsZSBbc3RyaXBlZF09XCJzdHJpcGVkXCI+XG4gIDx0aGVhZD5cbiAgICBAaWYgKCEhYnVsa0FjdGlvbnMpIHtcbiAgICA8dHI+XG4gICAgICA8dGggW2F0dHIuY29sc3Bhbl09XCJ0YWJsZVNwYW5cIiBzY29wZT1cImNvbFwiIGNsYXNzPVwiYnVsay1hY3Rpb24tY29sdW1uXCI+XG4gICAgICAgIDxuZy1jb250ZW50IHNlbGVjdD1cImltcGRjLXRhYmxlLWJ1bGstYWN0aW9uc1wiPjwvbmctY29udGVudD5cbiAgICAgICAgPG5nLWNvbnRlbnQgc2VsZWN0PVwiW2ltcGRjVGFibGVCdWxrQWN0aW9uc11cIj48L25nLWNvbnRlbnQ+XG4gICAgICA8L3RoPlxuICAgIDwvdHI+XG4gICAgfVxuICAgIDx0cj5cbiAgICAgIEBpZiAoY2FuU2VsZWN0Um93cykge1xuICAgICAgPHRoXG4gICAgICAgIHNjb3BlPVwiY29sXCJcbiAgICAgICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAgICdoZWFkaW5nLWJlbG93LWJ1bGstYWN0aW9ucyc6ICEhYnVsa0FjdGlvbnNcbiAgICAgICAgfVwiPlxuICAgICAgICBAaWYgKGNhblNlbGVjdEFsbFJvd3MpIHtcbiAgICAgICAgPGRpdj5cbiAgICAgICAgICA8aW1wZGMtY2hlY2tib3hcbiAgICAgICAgICAgIG5nTW9kZWxcbiAgICAgICAgICAgIFtjaGVja2VkXT1cImFsbFNlbGVjdGVkXCJcbiAgICAgICAgICAgIFtpbmRldGVybWluYXRlXT1cInNvbWVTZWxlY3RlZFwiXG4gICAgICAgICAgICAoY2hhbmdlKT1cImhhbmRsZVNlbGVjdEFsbCgkZXZlbnQpXCI+PC9pbXBkYy1jaGVja2JveD5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgIDwvdGg+XG4gICAgICB9IEBmb3IgKGNvbHVtbkRlZiBvZiBjb2x1bW5EZWZzOyB0cmFjayBjb2x1bW5EZWY7IGxldCBjb2x1bW5JbmRleCA9XG4gICAgICAkaW5kZXgpIHtcbiAgICAgIDx0aFxuICAgICAgICBzY29wZT1cImNvbFwiXG4gICAgICAgIFtuZ0NsYXNzXT1cIntcbiAgICAgICAgICAnc29ydGVkLWNvbHVtbic6IGlzU29ydGVkQ29sdW1uKGNvbHVtbkluZGV4KSxcbiAgICAgICAgICAnc29ydGFibGUtY29sdW1uJzogY29sdW1uRGVmLnNvcnRlZCxcbiAgICAgICAgICAnaGVhZGluZy1iZWxvdy1idWxrLWFjdGlvbnMnOiAhIWJ1bGtBY3Rpb25zXG4gICAgICAgIH1cIlxuICAgICAgICAoY2xpY2spPVwiaGFuZGxlU29ydChjb2x1bW5JbmRleClcIj5cbiAgICAgICAgPGltcGRjLWNvbHVtbi1oZWFkaW5nXG4gICAgICAgICAgW2lzU29ydGFibGVdPVwiY29sdW1uRGVmLnNvcnRlZCB8fCBmYWxzZVwiXG4gICAgICAgICAgW2NvbHVtbkluZGV4XT1cImNvbHVtbkluZGV4XCJcbiAgICAgICAgICBbc29ydENvbHVtbkluZGV4XT1cInNvcnRDb2x1bW5JbmRleFwiXG4gICAgICAgICAgW2RpcmVjdGlvbl09XCJzb3J0RGlyZWN0aW9uXCJcbiAgICAgICAgICBbdGV4dF09XCJjb2x1bW5EZWYudGl0bGVcIlxuICAgICAgICAgIChzb3J0KT1cImhhbmRsZVNvcnQoJGV2ZW50KVwiPlxuICAgICAgICA8L2ltcGRjLWNvbHVtbi1oZWFkaW5nPlxuICAgICAgPC90aD5cbiAgICAgIH1cbiAgICA8L3RyPlxuICA8L3RoZWFkPlxuICA8dGJvZHk+XG4gICAgQGlmIChsb2FkaW5nKSB7XG4gICAgPHRyPlxuICAgICAgPHRkIFthdHRyLmNvbHNwYW5dPVwidGFibGVTcGFuXCIgY2xhc3M9XCJkYXRhLWxvYWRpbmdcIj5cbiAgICAgICAgPGltcGRjLXNwaW5uZXI+PC9pbXBkYy1zcGlubmVyPlxuICAgICAgPC90ZD5cbiAgICA8L3RyPlxuICAgIH0gQGVsc2UgeyBAZm9yIChyb3cgb2YgdGFibGVEYXRhOyB0cmFjayByb3c7IGxldCByb3dJbmRleCA9ICRpbmRleCkge1xuICAgIDx0cj5cbiAgICAgIEBpZiAoY2FuU2VsZWN0Um93cykge1xuICAgICAgPHRkPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2VsZWN0LWNvbHVtblwiPlxuICAgICAgICAgIDxpbXBkYy1jaGVja2JveFxuICAgICAgICAgICAgW25nTW9kZWxdPVwiaXNSb3dTZWxlY3RlZChyb3cuaWQpXCJcbiAgICAgICAgICAgIChjaGFuZ2UpPVwiaGFuZGxlUm93U2VsZWN0KCRldmVudCwgcm93LmlkKVwiPjwvaW1wZGMtY2hlY2tib3g+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC90ZD5cbiAgICAgIH1cbiAgICAgIDx0ZFxuICAgICAgICAqbmdGb3I9XCJsZXQgY29sdW1uRGVmIG9mIGNvbHVtbkRlZnM7IGluZGV4IGFzIGNvbEluZGV4OyBsYXN0IGFzIGlzTGFzdFwiXG4gICAgICAgIFtuZ0NsYXNzXT1cIntcbiAgICAgICAgICAnY29sLW5vLXBhZGRpbmcnOiAhIWNvbHVtbkRlZi5ub1BhZGRpbmcsXG4gICAgICAgICAgJ2FjdGlvbnMtY29sdW1uJzogY29sdW1uRGVmLmNvbHVtblR5cGUgPT09IGNlbGxUeXBlLkFjdGlvbnNcbiAgICAgICAgfVwiPlxuICAgICAgICA8ZGl2PlxuICAgICAgICAgIEBzd2l0Y2ggKGNvbHVtbkRlZi5jb2x1bW5UeXBlKSB7IEBjYXNlIChjZWxsVHlwZS5CYWRnZSkge1xuICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgPGltcGRjLWJhZGdlXG4gICAgICAgICAgICAgIFt0ZXh0XT1cImdldFN0cmluZ1ZhbHVlKGNvbEluZGV4LCByb3cpXCJcbiAgICAgICAgICAgICAgW3RoZW1lXT1cImdldFRoZW1lKGNvbHVtbkRlZiwgcm93KVwiPlxuICAgICAgICAgICAgPC9pbXBkYy1iYWRnZT5cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgfSBAY2FzZSAoY2VsbFR5cGUuTGluaykge1xuICAgICAgICAgIDxzcGFuIChjbGljayk9XCJoYW5kbGVMaW5rQ2xpY2soY29sSW5kZXgsIHJvdylcIj5cbiAgICAgICAgICAgIEBpZiAoIWJyYW5kZWQpIHtcbiAgICAgICAgICAgIDxhPlxuICAgICAgICAgICAgICB7eyBnZXRWYWx1ZShjb2xJbmRleCwgcm93KSB9fVxuICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICA8YSBpbXBkY0JyYW5kZWQ+XG4gICAgICAgICAgICAgIHt7IGdldFZhbHVlKGNvbEluZGV4LCByb3cpIH19XG4gICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIH0gQGNhc2UgKGNlbGxUeXBlLlVybCkge1xuICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgQGlmICghYnJhbmRlZCkge1xuICAgICAgICAgICAgPGEgdGFyZ2V0PVwiX2JsYW5rXCIgW2F0dHIuaHJlZl09XCJnZXRWYWx1ZShjb2xJbmRleCwgcm93KVwiPlxuICAgICAgICAgICAgICB7eyBnZXRWYWx1ZShjb2xJbmRleCwgcm93KSB9fVxuICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICA8YVxuICAgICAgICAgICAgICBpbXBkY0JyYW5kZWRcbiAgICAgICAgICAgICAgdGFyZ2V0PVwiX2JsYW5rXCJcbiAgICAgICAgICAgICAgW2F0dHIuaHJlZl09XCJnZXRWYWx1ZShjb2xJbmRleCwgcm93KVwiPlxuICAgICAgICAgICAgICB7eyBnZXRWYWx1ZShjb2xJbmRleCwgcm93KSB9fVxuICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICB9IEBjYXNlIChjZWxsVHlwZS5FbWFpbCkge1xuICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgQGlmICghYnJhbmRlZCkge1xuICAgICAgICAgICAgPGFcbiAgICAgICAgICAgICAgdGFyZ2V0PVwiX2JsYW5rXCJcbiAgICAgICAgICAgICAgW2F0dHIuaHJlZl09XCInbWFpbHRvOicgKyBnZXRWYWx1ZShjb2xJbmRleCwgcm93KVwiPlxuICAgICAgICAgICAgICB7eyBnZXRWYWx1ZShjb2xJbmRleCwgcm93KSB9fVxuICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICA8YSBpbXBkY0JyYW5kZWQgW2F0dHIuaHJlZl09XCJnZXRNYWlsVG9WYWx1ZShjb2xJbmRleCwgcm93KVwiPlxuICAgICAgICAgICAgICB7eyBnZXRWYWx1ZShjb2xJbmRleCwgcm93KSB9fVxuICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICB9IEBjYXNlIChjZWxsVHlwZS5JbnB1dCkge1xuICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgIGltcGRjSW5wdXRcbiAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICBjbGFzcz1cInt7IGdldENlbGxDb2xvcihjb2x1bW5EZWYsIHJvdykgfX1cIlxuICAgICAgICAgICAgICBbbmdNb2RlbF09XCJnZXRWYWx1ZShjb2xJbmRleCwgcm93KVwiXG4gICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIlxuICAgICAgICAgICAgICAgIGhhbmRsZUNlbGxWYWx1ZUNoYW5nZShjb2xJbmRleCwgcm93SW5kZXgsICRldmVudClcbiAgICAgICAgICAgICAgXCIgLz5cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgfSBAY2FzZSAoY2VsbFR5cGUuQm9vbGVhbikge1xuICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgQGlmIChjb2x1bW5EZWYuZGlzYWJsZWQgJiYgZ2V0VmFsdWUoY29sSW5kZXgsIHJvdykgPT09ICd0cnVlJykge1xuICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgaW1wZGMtaWNvblxuICAgICAgICAgICAgICBuYW1lPVwiY2hlY2tcIlxuICAgICAgICAgICAgICBjbGFzcz1cInt7IGdldENlbGxDb2xvcihjb2x1bW5EZWYsIHJvdykgfX1cIj48L3NwYW4+XG4gICAgICAgICAgICB9IEBlbHNlIGlmICghY29sdW1uRGVmLmRpc2FibGVkKSB7XG4gICAgICAgICAgICA8aW1wZGMtY2hlY2tib3hcbiAgICAgICAgICAgICAgW2NoZWNrZWRdPVwiZ2V0VmFsdWUoY29sSW5kZXgsIHJvdykgPT09ICd0cnVlJ1wiXG4gICAgICAgICAgICAgIFtpc1N3aXRjaF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgKGNoYW5nZSk9XCJcbiAgICAgICAgICAgICAgICBoYW5kbGVDZWxsVmFsdWVDaGFuZ2UoY29sSW5kZXgsIHJvd0luZGV4LCAkZXZlbnQuY2hlY2tlZClcbiAgICAgICAgICAgICAgXCI+PC9pbXBkYy1jaGVja2JveD5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgfSBAY2FzZSAoY2VsbFR5cGUuU2luZ2xlU2VsZWN0KSB7XG4gICAgICAgICAgPHNwYW4+XG4gICAgICAgICAgICA8aW1wZGMtc2VsZWN0XG4gICAgICAgICAgICAgIFtuZ01vZGVsXT1cImdldFZhbHVlKGNvbEluZGV4LCByb3cpXCJcbiAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImNvbHVtbkRlZi5kaXNhYmxlZCB8fCBmYWxzZVwiXG4gICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJzZWxlY3RQbGFjZWhvbGRlclwiXG4gICAgICAgICAgICAgIGFsbG93Q2xlYXI9XCJ0cnVlXCJcbiAgICAgICAgICAgICAgKHNlbGVjdGlvbkNoYW5nZSk9XCJcbiAgICAgICAgICAgICAgICBoYW5kbGVDZWxsVmFsdWVDaGFuZ2UoY29sSW5kZXgsIHJvd0luZGV4LCAkZXZlbnQudmFsdWUpXG4gICAgICAgICAgICAgIFwiPlxuICAgICAgICAgICAgICBAZm9yICh2YWx1ZSBvZiAoY29sdW1uRGVmLnZhbHVlcyB8fCBbXSk7IHRyYWNrIHZhbHVlKSB7XG4gICAgICAgICAgICAgIDxpbXBkYy1zZWxlY3Qtb3B0aW9uXG4gICAgICAgICAgICAgICAgW3ZhbHVlXT1cInZhbHVlLnZhbHVlXCJcbiAgICAgICAgICAgICAgICBbbGFiZWxdPVwidmFsdWUubGFiZWxcIj48L2ltcGRjLXNlbGVjdC1vcHRpb24+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvaW1wZGMtc2VsZWN0PlxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICB9IEBjYXNlIChjZWxsVHlwZS5NdWx0aVNlbGVjdCkge1xuICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgPGltcGRjLXNlbGVjdFxuICAgICAgICAgICAgICBbbmdNb2RlbF09XCJnZXRWYWx1ZShjb2xJbmRleCwgcm93KVwiXG4gICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJjb2x1bW5EZWYuZGlzYWJsZWQgfHwgZmFsc2VcIlxuICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwic2VsZWN0UGxhY2Vob2xkZXJcIlxuICAgICAgICAgICAgICBtdWx0aXBsZT1cInRydWVcIlxuICAgICAgICAgICAgICAoc2VsZWN0aW9uQ2hhbmdlKT1cIlxuICAgICAgICAgICAgICAgIGhhbmRsZUNlbGxWYWx1ZUNoYW5nZShjb2xJbmRleCwgcm93SW5kZXgsICRldmVudC52YWx1ZSlcbiAgICAgICAgICAgICAgXCI+XG4gICAgICAgICAgICAgIEBmb3IgKHZhbHVlIG9mIChjb2x1bW5EZWYudmFsdWVzIHx8IFtdKTsgdHJhY2sgdmFsdWUpIHtcbiAgICAgICAgICAgICAgPGltcGRjLXNlbGVjdC1vcHRpb25cbiAgICAgICAgICAgICAgICBbdmFsdWVdPVwidmFsdWUudmFsdWVcIlxuICAgICAgICAgICAgICAgIFtsYWJlbF09XCJ2YWx1ZS5sYWJlbFwiPjwvaW1wZGMtc2VsZWN0LW9wdGlvbj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9pbXBkYy1zZWxlY3Q+XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIH0gQGNhc2UgKGNlbGxUeXBlLkNlbGxSZW5kZXIpIHtcbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInt7IGdldENlbGxDb2xvcihjb2x1bW5EZWYsIHJvdykgfX1cIj5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgICBpbXBkY1RhYmxlSW5qZWN0Q29tcG9uZW50XG4gICAgICAgICAgICAgIFtjb2x1bW5EZWZdPVwiY29sdW1uRGVmXCJcbiAgICAgICAgICAgICAgW3Jvd0l0ZW1dPVwicm93XCJcbiAgICAgICAgICAgICAgW2N1c3RvbUNlbGxDb21wb25lbnRzXT1cImN1c3RvbUNlbGxDb21wb25lbnRzIHx8IHt9XCJcbiAgICAgICAgICAgICAgW3ZhbHVlXT1cImdldFJhd1ZhbHVlKGNvbEluZGV4LCByb3cpXCI+PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgfSBAY2FzZSAoY2VsbFR5cGUuSWNvbikge1xuICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgaW1wZGMtaWNvblxuICAgICAgICAgICAgICBbbmFtZV09XCJjb2x1bW5EZWYuaWNvbk5hbWVcIlxuICAgICAgICAgICAgICBjbGFzcz1cInt7IGdldENlbGxDb2xvcihjb2x1bW5EZWYsIHJvdykgfX1cIj48L3NwYW4+XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIH0gQGNhc2UgKGNlbGxUeXBlLkFjdGlvbnMpIHtcbiAgICAgICAgICA8c3Bhbj5cbiAgICAgICAgICAgIDwhLS0gd2lsbCBhbHdheXMgcmV0dXJuICd0cnVlJywgYnV0IG5lZWRlZCB0byBzYXRpc2Z5IHRoZSB0eXBlIGVuZ2luZSAtLT5cbiAgICAgICAgICAgIEBpZiAoY29sdW1uRGVmSXNBY3Rpb25zKGNvbHVtbkRlZikpIHtcbiAgICAgICAgICAgIDxpbXBkYy1yb3ctYWN0aW9uc1xuICAgICAgICAgICAgICBbY29sdW1uRGVmXT1cImNvbHVtbkRlZlwiXG4gICAgICAgICAgICAgIFtyb3dJdGVtXT1cInJvd1wiXG4gICAgICAgICAgICAgIFtsYXN0Q29sdW1uXT1cImlzTGFzdFwiXG4gICAgICAgICAgICAgIChhY3Rpb25DbGljayk9XCJcbiAgICAgICAgICAgICAgICBoYW5kbGVBY3Rpb25DbGljayhjb2xJbmRleCwgcm93LCAkZXZlbnQpXG4gICAgICAgICAgICAgIFwiPjwvaW1wZGMtcm93LWFjdGlvbnM+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIH0gQGRlZmF1bHQge1xuICAgICAgICAgIDxzcGFuIGNsYXNzPVwie3sgZ2V0Q2VsbENvbG9yKGNvbHVtbkRlZiwgcm93KSB9fVwiPlxuICAgICAgICAgICAge3sgZ2V0VmFsdWUoY29sSW5kZXgsIHJvdykgfX1cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgfSB9XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC90ZD5cbiAgICA8L3RyPlxuICAgIH0gQGVtcHR5IHtcbiAgICA8dHI+XG4gICAgICA8dGQgW2F0dHIuY29sc3Bhbl09XCJ0YWJsZVNwYW5cIiBjbGFzcz1cIm5vLWRhdGFcIj5cbiAgICAgICAgPG5nLWNvbnRlbnQgc2VsZWN0PVwiW25vRGF0YV1cIj48L25nLWNvbnRlbnQ+XG4gICAgICA8L3RkPlxuICAgIDwvdHI+XG4gICAgfSB9XG4gIDwvdGJvZHk+XG4gIDx0Zm9vdD5cbiAgICBAaWYgKHBhZ2luYXRpb25Db21wb25lbnQpIHtcbiAgICA8dHI+XG4gICAgICA8dGQgW2F0dHIuY29sc3Bhbl09XCJ0YWJsZVNwYW5cIj5cbiAgICAgICAgPG5nLWNvbnRlbnRcbiAgICAgICAgICBzZWxlY3Q9XCJpbXBkYy1wYWdpbmF0aW9uLCBkaXZbaW1wZGMtcGFnaW5hdGlvbl1cIj48L25nLWNvbnRlbnQ+XG4gICAgICA8L3RkPlxuICAgIDwvdHI+XG4gICAgfVxuICA8L3Rmb290PlxuPC90YWJsZT5cbn1cbiJdfQ==
474
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZGVzaWduLWNvbXBvbmVudHMvc3JjL2xpYi90YWJsZS9jb250YWluZXJzL3RhYmxlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Rlc2lnbi1jb21wb25lbnRzL3NyYy9saWIvdGFibGUvY29udGFpbmVycy90YWJsZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBRUwsU0FBUyxFQUNULFlBQVksRUFDWixZQUFZLEVBQ1osSUFBSSxFQUNKLEtBQUssRUFFTCxRQUFRLEVBQ1IsTUFBTSxFQUdQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxHQUFHLElBQUksY0FBYyxFQUFFLEdBQUcsSUFBSSxjQUFjLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDdEUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTlDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNuRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFjeEQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQzlDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVoRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxlQUFlLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUcxRDs7O0dBR0c7QUFNSCxNQUFNLE9BQU8sY0FBYztJQThCekI7O09BRUc7SUFDSCxJQUFvQixhQUFhLENBQUMsS0FBYztRQUM5QyxJQUFJLENBQUMsY0FBYyxHQUFHLEtBQUssQ0FBQztJQUM5QixDQUFDO0lBQ0QsSUFB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QUF1QixDQUFDO1lBRXpFLE9BQU8sS0FBSyxJQUFJLEVBQUUsQ0FBQztTQUNwQjtRQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ1YsT0FBTyxFQUFFLENBQUM7U0FDWDtJQUNILENBQUM7OEdBM2hCVSxjQUFjO2tHQUFkLGNBQWMseXZCQXNKWCxtQkFBbUIsOEVBSW5CLHlCQUF5QixxRUMxTXpDLDhxV0FzVUE7OzJGRHRSYSxjQUFjO2tCQUwxQixTQUFTOytCQUNFLGFBQWE7OzBCQTJNcEIsUUFBUTs7MEJBQUksSUFBSTt5Q0FuTUgsT0FBTztzQkFBdEIsS0FBSztnQkFTVSxVQUFVO3NCQUF6QixLQUFLO2dCQUtVLE9BQU87c0JBQXRCLEtBQUs7Z0JBS1UsS0FBSztzQkFBcEIsS0FBSztnQkFLVSxNQUFNO3NCQUFyQixLQUFLO2dCQUtjLGFBQWE7c0JBQWhDLEtBQUs7Z0JBV0ssZ0JBQWdCO3NCQUQxQixLQUFLO2dCQVlVLGlCQUFpQjtzQkFBaEMsS0FBSztnQkFLVSxlQUFlO3NCQUE5QixLQUFLO2dCQUtVLGFBQWE7c0JBQTVCLEtBQUs7Z0JBS1UsU0FBUztzQkFBeEIsS0FBSztnQkFNSyxjQUFjO3NCQUR4QixLQUFLO2dCQVlVLG9CQUFvQjtzQkFBbkMsS0FBSztnQkFPVSxtQkFBbUI7c0JBQWxDLEtBQUs7Z0JBWUMsa0JBQWtCO3NCQUR4QixLQUFLO2dCQU1vQixTQUFTO3NCQUFsQyxNQUFNO2dCQU1tQixNQUFNO3NCQUEvQixNQUFNO2dCQU1tQixTQUFTO3NCQUFsQyxNQUFNO2dCQU9TLGNBQWM7c0JBRDdCLE1BQU07Z0JBU1MsV0FBVztzQkFEMUIsTUFBTTtnQkFRUyxpQkFBaUI7c0JBRGhDLE1BQU07Z0JBT0EsbUJBQW1CO3NCQUR6QixZQUFZO3VCQUFDLG1CQUFtQjtnQkFLMUIsV0FBVztzQkFEakIsWUFBWTt1QkFBQyx5QkFBeUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEYXRlUGlwZSwgRGVjaW1hbFBpcGUsIFBlcmNlbnRQaXBlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIENvbnRlbnRDaGlsZCxcbiAgRXZlbnRFbWl0dGVyLFxuICBIb3N0LFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPcHRpb25hbCxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2VzLFxuICBUZW1wbGF0ZVJlZlxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGdldCBhcyBnZXROZXN0ZWRWYWx1ZSwgc2V0IGFzIHNldE5lc3RlZFZhbHVlIH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IGRlYm91bmNlVGltZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgREVCT1VOQ0VfVElNRSB9IGZyb20gJy4uL2NvbnN0YW50cy9pbmRleCc7XG5pbXBvcnQgeyBUYWJsZUNvbHVtblR5cGUgfSBmcm9tICcuLi9lbnVtZXJhdGlvbnMvaW5kZXgnO1xuaW1wb3J0IHtcbiAgSUNvbGxhcHNpYmxlUm93Q29udGVudENvbnRleHQsXG4gIElDdXN0b21DZWxsUmVuZGVyZXJDb21wb25lbnRzLFxuICBJU29ydEJ5UGF5bG9hZCxcbiAgSVRhYmxlQWN0aW9uc0NvbHVtbkRlZixcbiAgSVRhYmxlRXZlbnRQYXlsb2FkLFxuICBJVGFibGVSb3dBY3Rpb25QYXlsb2FkLFxuICBJVGFibGVSb3dDb2xsYXBzZUNoYW5nZSxcbiAgSVRhYmxlUm93SXRlbSxcbiAgSVRhYmxlUm93SXRlbVZhbHVlVHlwZXMsXG4gIFRhYmxlQ29sdW1uRGVmXG59IGZyb20gJy4uL2ludGVyZmFjZXMvaW5kZXgnO1xuaW1wb3J0IHsgQ2hlY2tib3hDaGFuZ2VFdmVudCB9IGZyb20gJy4uLy4uL2Zvcm0tZmllbGQnO1xuaW1wb3J0IHsgVGFibGVUaGVtZUhlbHBlciB9IGZyb20gJy4uL2hlbHBlcnMnO1xuaW1wb3J0IHsgQ29tcG9uZW50VGhlbWUgfSBmcm9tICcuLi8uLi8uLi90eXBlcyc7XG5pbXBvcnQgeyBCcmFuZGVkRGlyZWN0aXZlIH0gZnJvbSAnLi4vLi4vYnJhbmRpbmcnO1xuaW1wb3J0IHsgUGFnaW5hdGlvbkNvbXBvbmVudCB9IGZyb20gJy4uLy4uL3BhZ2luYXRpb24nO1xuaW1wb3J0IHsgVGFibGVCdWxrQWN0aW9uc0NvbXBvbmVudCB9IGZyb20gJy4uL2NvbXBvbmVudHMnO1xuaW1wb3J0IHsgTmdiQ29sbGFwc2UgfSBmcm9tICdAbmctYm9vdHN0cmFwL25nLWJvb3RzdHJhcCc7XG5cbi8qKlxuICogVGhlIGBUYWJsZUNvbXBvbmVudGAgKGA8aW1wZGMtdGFibGVgKSBpcyBhIGRhdGEgdGFibGUgY29tcG9uZW50LlxuICogVG8gdXNlLCBpbXBvcnQgYFRhYmxlTW9kdWxlYCBmcm9tIGBAaW1wYXJ0bmVyL2Rlc2lnbi1jb21wb25lbnRzYC5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnaW1wZGMtdGFibGUnLFxuICBzdHlsZVVybHM6IFsnLi90YWJsZS5jb21wb25lbnQuc2NzcyddLFxuICB0ZW1wbGF0ZVVybDogJy4vdGFibGUuY29tcG9uZW50Lmh0bWwnXG59KVxuZXhwb3J0IGNsYXNzIFRhYmxlQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIHRhYmxlIGRhdGEgaXMgY3VycmVudGx5IGJlaW5nIGxvYWRlZC4gVGhlIGA8aW1wZGMtc3Bpbm5lcj5gIHdpbGwgc2hvdyBpZiBkYXRhIGlzIGxvYWRpbmcuXG4gICAqL1xuICBASW5wdXQoKSBwdWJsaWMgbG9hZGluZyA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBUaGUgdmlzaWJsZSBjb2x1bW5zIG9mIHRoZSB0YWJsZS4gIEVhY2ggYElUYWJsZUNvbHVtbkRlZmAgZGVmaW5lcyBwcm9wZXJ0aWVzIHJlZ2FyZGluZyB0aGUgZGlzcGxheSwgZm9ybWF0dGluZyBhbmQgaW50ZXJhY3Rpb24gb2YgdGhlIGNvbHVtbidzIGNlbGxzLlxuICAgKiBDb2x1bW4vY2VsbCBjb2xvciBwcmVjZWRlbmNlIGlzOlxuICAgKiAxKSBgZmllbGRDb2xvcmAgLSBhbGxvd3MgYW4gYElUYWJsZUNvbHVtbkRlZmAgdG8gZGVsZWdhdGUgdGhlIHJlc3BvbnNpYmlsaXR5IG9mIGNlbGwgY29sb3IgdG8gYW4gYElUYWJsZVJvd0l0ZW1gIHByb3BlcnR5LlxuICAgKiAyKSBgY29sb3JHZXR0ZXJgLSBhbGxvd3MgYW4gYElUYWJsZUNvbHVtbkRlZmAgdG8gZGVsZWdhdGUgdGhlIHJlc3BvbnNpYmlsaXR5IG9mIGNlbGwgY29sb3IgdG8gYSBmdW5jdGlvbiBvZiB0aGUgYElUYWJsZVJvd0l0ZW1gIGRldGVybWluZWQgYnkgdGhlIGRldmVsb3Blci5cbiAgICogMykgYGNvbG9yYCAtIGEgcHJvcGVydHkgb2YgYW4gYElUYWJsZUNvbHVtbkRlZmAuXG4gICAqL1xuICBASW5wdXQoKSBwdWJsaWMgY29sdW1uRGVmczogVGFibGVDb2x1bW5EZWY8YW55PltdID0gW107XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIHRhYmxlIGlzIHN0cmlwZWQuXG4gICAqL1xuICBASW5wdXQoKSBwdWJsaWMgc3RyaXBlZCA9IHRydWU7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGFibGUgcm93cyBzaG91bGQgYXBwbHkgaG92ZXIgc3R5bGVzIHdoZW4gaG92ZXJlZCBvdmVyIHZpYSBjdXJzb3IuXG4gICAqL1xuICBASW5wdXQoKSBwdWJsaWMgaG92ZXIgPSB0cnVlO1xuXG4gIC8qKlxuICAgKiBUaGUgbGF5b3V0IGFsZ29yaXRobSB0byBiZSB1c2VkIHdoZW4gcmVuZGVyaW5nIHRoZSB0YWJsZS5cbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyBsYXlvdXQ6ICdhdXRvJyB8ICdmaXhlZCcgPSAnYXV0byc7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgaW5kaXZpZHVhbCByb3dzIGNhbiBiZSBzZWxlY3RlZC4gV2lsbCBiZSBgdHJ1ZWAgaWYgZXhwbGljaXRseSBzZXQgdG8gYHRydWVgIG9yIGBjYW5TZWxlY3RBbGxSb3dzYCBpcyBgdHJ1ZWAuXG4gICAqL1xuICBASW5wdXQoKSBwdWJsaWMgc2V0IGNhblNlbGVjdFJvd3ModmFsdWU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLl9jYW5TZWxlY3RSb3dzID0gdmFsdWU7XG4gIH1cbiAgcHVibGljIGdldCBjYW5TZWxlY3RSb3dzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmNhblNlbGVjdEFsbFJvd3MgfHwgdGhpcy5fY2FuU2VsZWN0Um93cyB8fCAhIXRoaXMuYnVsa0FjdGlvbnM7XG4gIH1cblxuICAvKipcbiAgICogV2hldGhlciBhbGwgcm93cyBjYW4gYmUgc2VsZWN0ZWQgYXQgb25jZS4gV2lsbCBiZSBgdHJ1ZWAgaWYgZXhwbGljaXRseSBzZXQgdG8gYHRydWVgIG9yIGlmIGBUYWJsZUJ1bGtBY3Rpb25zQ29tcG9uZW50YCBpcyBjb250ZW50IHByb2plY3RlZC5cbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBzZXQgY2FuU2VsZWN0QWxsUm93cyh2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMuX2NhblNlbGVjdEFsbFJvd3MgPSB2YWx1ZTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgY2FuU2VsZWN0QWxsUm93cygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fY2FuU2VsZWN0QWxsUm93cyB8fCAhIXRoaXMuYnVsa0FjdGlvbnM7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHBsYWNlaG9sZGVyIHRleHQgYW5kIGVtcHR5IHZhbHVlIGRpc3BsYXkgdGV4dCBmb3IgYDxpbXBkYy1zZWxlY3Q+YCBpbnN0YW5jZXMgaW4gY2VsbHMgd2l0aCBhIGBJVGFibGVDb2x1bW5EZWZgIGBjb2x1bW5UeXBlYCA9IGBTaW5nbGVTZWxlY3RgIG9yIGBNdWx0aVNlbGVjdGAuXG4gICAqL1xuICBASW5wdXQoKSBwdWJsaWMgc2VsZWN0UGxhY2Vob2xkZXIgPSAnJztcblxuICAvKipcbiAgICogVGhlIGBjb2x1bW5EZWZzYCBpbmRleCBvZiB0aGUgY3VycmVudGx5IHNvcnRlZCBjb2x1bW4uXG4gICAqL1xuICBASW5wdXQoKSBwdWJsaWMgc29ydENvbHVtbkluZGV4OiBudW1iZXIgPSAwO1xuXG4gIC8qKlxuICAgKiBUaGUgZGlyZWN0aW9uIG9mIHRoZSBjdXJyZW50bHkgc29ydGVkIGNvbHVtbi5cbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyBzb3J0RGlyZWN0aW9uOiAnYXNjJyB8ICdkZXNjJyA9ICdhc2MnO1xuXG4gIC8qKlxuICAgKiBUaGUgdGFibGUgcm93IGRhdGEgYXMgYW4gYXJyYXkgb2YgYElUYWJsZVJvd0l0ZW1gLlxuICAgKi9cbiAgQElucHV0KCkgcHVibGljIHRhYmxlRGF0YTogSVRhYmxlUm93SXRlbVtdID0gW107XG5cbiAgLyoqXG4gICAqIEFuIGFycmF5IG9mIGN1cnJlbnRseSBzZWxlY3RlZCBJRHMgZnJvbSB0aGUgYHRhYmxlRGF0YWAgaW5wdXQuICBBcnJheSBtdXN0IGJlIG9mIHR5cGUgYChzdHJpbmcgfCBudW1iZXIpW11gLlxuICAgKi9cbiAgQElucHV0KClcbiAgcHVibGljIHNldCBzZWxlY3RlZFJvd0lkcyh2YWx1ZTogKHN0cmluZyB8IG51bWJlcilbXSkge1xuICAgIHRoaXMuX3NlbGVjdGVkUm93SWRzID0gWy4uLnZhbHVlXTtcbiAgfVxuICBwdWJsaWMgZ2V0IHNlbGVjdGVkUm93SWRzKCk6IChzdHJpbmcgfCBudW1iZXIpW10ge1xuICAgIHJldHVybiBbLi4udGhpcy5fc2VsZWN0ZWRSb3dJZHNdO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSByZWdpc3RlcmVkIGN1c3RvbSBjZWxsIHJlbmRlcmVyIGNvbXBvbmVudHMgYXZhaWxhYmxlIHRvIGJlIHVzZWQgaW4gdGhlIHRhYmxlIGluc3RhbmNlLlxuICAgKiBGb3IgYSBnaXZlbiBgSVRhYmxlQ29sdW1uRGVmYCBpbiB0aGUgYGNvbHVtbkRlZnNgIGlucHV0LCB0aGUgYGNlbGxSZW5kZXJlckNvbXBvbmVudGAgcHJvcGVydHkgc2hvdWxkIGJlIHNldCB0byB0aGUga2V5IG9mIHRoZSByZWdpc3RlcmVkIGNvbXBvbmVudCBpbiB0aGlzIGlucHV0LlxuICAgKi9cbiAgQElucHV0KCkgcHVibGljIGN1c3RvbUNlbGxDb21wb25lbnRzPzogSUN1c3RvbUNlbGxSZW5kZXJlckNvbXBvbmVudHM7XG5cbiAgLyoqXG4gICAqIEFuIG9wdGlvbmFsIHRlbXBsYXRlIGZvciBjb250ZW50IHRoYXQgbWF5IGJlIHJlbmRlcmVkIGJlbG93IGEgcm93IGluIGFuIGNvbGxhcHNpYmxlIHZpZXcuIFZhbHVlIGNhbiBlaXRoZXIgYmUgYW4gQW5ndWxhciB0ZW1wbGF0ZSBvciBhIGZ1bmN0aW9uIHRoYXQgY2FuIGV2YWx1YXRlZFxuICAgKiB0byByZXNvbHZlIHRvIGEgdGVtcGxhdGUuIFRoZSB0ZW1wbGF0ZSB3aWxsIGJlIHJlbmRlcmVkIHdpdGggYSBwcm92aWRlZCBgSUNvbGxhcHNpYmxlUm93Q29udGVudENvbnRleHRgIG9iamVjdCBhcyB0ZW1wbGF0ZSBjb250ZXh0LCB3aXRoIHRoZSBjdXJyZW50IGBJVGFibGVSb3dEYXRhYFxuICAgKiBpbXBsaWNpdGx5IGF2YWlsYWJsZSBhcyBhIGRlZmF1bHQgdGVtcGxhdGUga2V5LlxuICAgKi9cbiAgQElucHV0KCkgcHVibGljIGNvbGxhcHNpYmxlVGVtcGxhdGU6XG4gICAgfCBUZW1wbGF0ZVJlZjxJQ29sbGFwc2libGVSb3dDb250ZW50Q29udGV4dDxhbnk+PlxuICAgIHwgbnVsbFxuICAgIHwgKChyb3c6IGFueSkgPT4gVGVtcGxhdGVSZWY8SUNvbGxhcHNpYmxlUm93Q29udGVudENvbnRleHQ8YW55Pj4gfCBudWxsKSA9XG4gICAgbnVsbDtcblxuICAvKipcbiAgICogVGhlIGNsaWNrYWJsZSBjb250cm9sIHRoYXQgd2lsbCB0cmlnZ2VyIGV4cGFuc2lvbiBhbmQgY29sbGFwc2Ugb2YgY29udGVudCB3aGVuIHVzaW5nIGBjb2xsYXBzaWJsZVRlbXBsYXRlYCBmdW5jdGlvbmFsaXR5LlxuICAgKiBXaGVuIHNldCB0byBgYnV0dG9uYCwgdGhlIGNvbGxhcHNpYmxlIGNvbnRlbnQncyBzdGF0ZSBjYW4gb25seSBiZSB0b2dnbGVkIGZyb20gYSBjbGlja2FibGUgYnV0dG9uIGF0IHRoZSBzdGFydCBvZiB0aGUgcm93LlxuICAgKiBXaGVuIHNldCB0byBgcm93YCwgdGhlIGVudGlyZSByb3cgd2lsbCBiZWNvbWUgYSBjbGlja2FibGUgdHJpZ2dlci5cbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBjb2xsYXBzaWJsZVRyaWdnZXI6ICdidXR0b24nIHwgJ3JvdycgPSAnYnV0dG9uJztcblxuICAvKipcbiAgICogRXZlbnQgZW1pdHRlZCB3aGVuIG9uZSBvciBtdWx0aXBsZSByb3dzIGFyZSBzZWxlY3RlZC4gRW1pdHMgYChzdHJpbmcgfCBudW1iZXIpW11gIHBheWxvYWQuXG4gICAqL1xuICBAT3V0cHV0KCkgcHVibGljIHJlYWRvbmx5IHJvd1NlbGVjdDogRXZlbnRFbWl0dGVyPChzdHJpbmcgfCBudW1iZXIpW10+ID1cbiAgICBuZXcgRXZlbnRFbWl0dGVyPChzdHJpbmcgfCBudW1iZXIpW10+KCk7XG5cbiAgLyoqXG4gICAqIEV2ZW50IGVtaXR0ZWQgd2hlbiBhIGNvbHVtbiBpcyBzb3J0ZWQuIEVtaXRzIGBJU29ydEJ5UGF5bG9hZGAgcGF5bG9hZC5cbiAgICovXG4gIEBPdXRwdXQoKSBwdWJsaWMgcmVhZG9ubHkgc29ydEJ5OiBFdmVudEVtaXR0ZXI8SVNvcnRCeVBheWxvYWQ+ID1cbiAgICBuZXcgRXZlbnRFbWl0dGVyPElTb3J0QnlQYXlsb2FkPigpO1xuXG4gIC8qKlxuICAgKiBFdmVudCBlbWl0dGVkIHdoZW4gYSByb3cgbGluayBpcyBjbGlja2VkLiBFbWl0cyBgSVRhYmxlRXZlbnRQYXlsb2FkYCBwYXlsb2FkLlxuICAgKi9cbiAgQE91dHB1dCgpIHB1YmxpYyByZWFkb25seSBsaW5rQ2xpY2s6IEV2ZW50RW1pdHRlcjxJVGFibGVFdmVudFBheWxvYWQ8YW55Pj4gPVxuICAgIG5ldyBFdmVudEVtaXR0ZXI8SVRhYmxlRXZlbnRQYXlsb2FkPGFueT4+KCk7XG5cbiAgLyoqXG4gICAqIEV2ZW50IGVtaXR0ZWQgd2hlbiBhIHJvdyBhY3Rpb24gaXMgY2xpY2tlZC4gRW1pdHMgYW4gYElUYWJsZVJvd0FjdGlvblBheWxvYWRgIHBheWxvYWQuXG4gICAqL1xuICBAT3V0cHV0KClcbiAgcHVibGljIHJlYWRvbmx5IHJvd0FjdGlvbkNsaWNrOiBFdmVudEVtaXR0ZXI8SVRhYmxlUm93QWN0aW9uUGF5bG9hZDxhbnk+PiA9XG4gICAgbmV3IEV2ZW50RW1pdHRlcjxJVGFibGVSb3dBY3Rpb25QYXlsb2FkPGFueT4+KCk7XG5cbiAgLyoqXG4gICAqIEV2ZW50IGVtaXR0ZWQgd2hlbiBhIHJvdyBpbnB1dCB2YWx1ZSBpcyBjaGFuZ2VkLiBFbWl0dGVkIGNlbGxzIG9mIGBjb2x1bW5UeXBlYCBgU2luZ2xlU2VsZWN0YCwgYE11bHRpU2VsZWN0YCwgYElucHV0YCwgYEJvb2xlYW5gIG9yIGBJY29uYC5cbiAgICogTm90IGVtaXR0ZWQgaWYgY29sdW1uIGRlZmluaXRpb24gcHJvcGVydHkgYGRpc2FibGVkYCA9IGB0cnVlYC4gRW1pdHMgYElUYWJsZUV2ZW50UGF5bG9hZGAgcGF5bG9hZC5cbiAgICovXG4gIEBPdXRwdXQoKVxuICBwdWJsaWMgcmVhZG9ubHkgaW5wdXRDaGFuZ2U6IEV2ZW50RW1pdHRlcjxJVGFibGVFdmVudFBheWxvYWQ8YW55Pj4gPVxuICAgIG5ldyBFdmVudEVtaXR0ZXI8SVRhYmxlRXZlbnRQYXlsb2FkPGFueT4+KCk7XG5cbiAgLyoqXG4gICAqIEV2ZW50IGVtaXR0ZWQgd2hlbiBhIHJvdyB3aXRoIGNvbGxhcHNpYmxlIGNvbnRlbnQgaGFzIGl0cyBjb2xsYXBzZSBzdGF0ZSBjaGFuZ2VkLlxuICAgKi9cbiAgQE91dHB1dCgpXG4gIHB1YmxpYyByZWFkb25seSByb3dDb2xsYXBzZUNoYW5nZTogRXZlbnRFbWl0dGVyPFxuICAgIElUYWJsZVJvd0NvbGxhcHNlQ2hhbmdlPGFueT5cbiAgPiA9IG5ldyBFdmVudEVtaXR0ZXI8SVRhYmxlUm93Q29sbGFwc2VDaGFuZ2U8YW55Pj4oKTtcblxuICAvKiogQGlnbm9yZSAqL1xuICBAQ29udGVudENoaWxkKFBhZ2luYXRpb25Db21wb25lbnQpXG4gIHB1YmxpYyBwYWdpbmF0aW9uQ29tcG9uZW50PzogUGFnaW5hdGlvbkNvbXBvbmVudCA9IHVuZGVmaW5lZDtcblxuICAvKiogQGlnbm9yZSAqL1xuICBAQ29udGVudENoaWxkKFRhYmxlQnVsa0FjdGlvbnNDb21wb25lbnQpXG4gIHB1YmxpYyBidWxrQWN0aW9ucz86IFRhYmxlQnVsa0FjdGlvbnNDb21wb25lbnQgPSB1bmRlZmluZWQ7XG5cbiAgLyoqIEBpZ25vcmUgKi9cbiAgcHVibGljIHJlYWRvbmx5IGNlbGxUeXBlID0gVGFibGVDb2x1bW5UeXBlO1xuICAvKiogQGlnbm9yZSAqL1xuICBwdWJsaWMgYWxsU2VsZWN0ZWQgPSB0cnVlO1xuICAvKiogQGlnbm9yZSAqL1xuICBwdWJsaWMgZ2V0IHNvbWVTZWxlY3RlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKFxuICAgICAgISF0aGlzLl9zZWxlY3RlZFJvd0lkcyAmJlxuICAgICAgdGhpcy5fc2VsZWN0ZWRSb3dJZHMubGVuZ3RoID4gMCAmJlxuICAgICAgISF0aGlzLnRhYmxlRGF0YSAmJlxuICAgICAgdGhpcy50YWJsZURhdGEubGVuZ3RoID4gMCAmJlxuICAgICAgdGhpcy5fc2VsZWN0ZWRSb3dJZHMubGVuZ3RoIDwgdGhpcy50YWJsZURhdGEubGVuZ3RoXG4gICAgKTtcbiAgfVxuICAvKiogQGlnbm9yZSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYnJhbmRlZDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8qKiBAaWdub3JlICovXG4gIHB1YmxpYyBnZXQgdGFibGVTcGFuKCk6IG51bWJlciB7XG4gICAgbGV0IGNvbHMgPSB0aGlzLmNvbHVtbkRlZnMubGVuZ3RoO1xuXG4gICAgaWYgKHRoaXMuY2FuU2VsZWN0Um93cykge1xuICAgICAgY29scysrO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbGxhcHNpYmxlVGVtcGxhdGUpIHtcbiAgICAgIGNvbHMrKztcbiAgICB9XG5cbiAgICByZXR1cm4gY29scztcbiAgfVxuXG4gIHByaXZhdGUgX2NhblNlbGVjdFJvd3MgPSBmYWxzZTtcbiAgcHJpdmF0ZSBfY2FuU2VsZWN0QWxsUm93cyA9IGZhbHNlO1xuICBwcml2YXRlIF9zZWxlY3RlZFJvd0lkczogKHN0cmluZyB8IG51bWJlcilbXSA9IFtdO1xuICBwcml2YXRlIHJlYWRvbmx5IF9pbnB1dENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8SVRhYmxlRXZlbnRQYXlsb2FkPigpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2RhdGVQaXBlOiBEYXRlUGlwZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9wZXJjZW50UGlwZTogUGVyY2VudFBpcGUsXG4gICAgcHJpdmF0ZSByZWFkb25seSBfZGVjbWlhbFBpcGU6IERlY2ltYWxQaXBlLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2NoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBAT3B0aW9uYWwoKSBASG9zdCgpIHByaXZhdGUgX2JyYW5kZWQ6IEJyYW5kZWREaXJlY3RpdmVcbiAgKSB7XG4gICAgdGhpcy5icmFuZGVkID0gX2JyYW5kZWQgPyB0cnVlIDogZmFsc2U7XG4gICAgdGhpcy5faW5wdXRDaGFuZ2VcbiAgICAgIC5waXBlKGRlYm91bmNlVGltZShERUJPVU5DRV9USU1FKSlcbiAgICAgIC5zdWJzY3JpYmUodGhpcy5pbnB1dENoYW5nZSk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKGNoYW5nZXNbJ3NlbGVjdGVkUm93SWRzJ10gfHwgY2hhbmdlc1sndGFibGVEYXRhJ10pIHtcbiAgICAgIGlmIChcbiAgICAgICAgIXRoaXMudGFibGVEYXRhIHx8XG4gICAgICAgICF0aGlzLnRhYmxlRGF0YS5sZW5ndGggfHxcbiAgICAgICAgIXRoaXMuc2VsZWN0ZWRSb3dJZHMgfHxcbiAgICAgICAgIXRoaXMuc2VsZWN0ZWRSb3dJZHMubGVuZ3RoXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5hbGxTZWxlY3RlZCA9IGZhbHNlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5hbGxTZWxlY3RlZCA9IHRoaXMuc2VsZWN0ZWRSb3dJZHMubGVuZ3RoID49IHRoaXMudGFibGVEYXRhLmxlbmd0aDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKiogQGlnbm9yZSAqL1xuICBwdWJsaWMgZ2V0TWFpbFRvVmFsdWUoXG4gICAgY29sdW1uSW5kZXg6IG51bWJlcixcbiAgICBjdXJyZW50Um93OiBJVGFibGVSb3dJdGVtXG4gICk6IHN0cmluZyB7XG4gICAgY29uc3QgeyBjb2x1bW5UeXBlLCB0cnVuY2F0ZWQ6IHRydW5jYXRlZCB9ID1cbiAgICAgIHRoaXMuX2dldENvbHVtbkRlZkJ5SW5kZXgoY29sdW1uSW5kZXgpO1xuICAgIGxldCB2YWx1ZSA9IHRoaXMuX2dldFZhbHVlKGNvbHVtbkluZGV4LCBjdXJyZW50Um93KTtcblxuICAgIGlmIChjb2x1bW5UeXBlICE9PSBUYWJsZUNvbHVtblR5cGUuRW1haWwpIHtcbiAgICAgIHJldHVybiBTdHJpbmcodmFsdWUpO1xuICAgIH1cbiAgICB2YWx1ZSA9IHZhbHVlID8gYG1haWx0bzoke3ZhbHVlfWAgOiB2YWx1ZTtcblxuICAgIHJldHVybiBTdHJpbmcodmFsdWUpO1xuICB9XG5cbiAgLyoqIEBpZ25vcmUgKi9cbiAgcHVibGljIGdldFN0cmluZ1ZhbHVlKFxuICAgIGNvbHVtbkluZGV4OiBudW1iZXIsXG4gICAgY3VycmVudFJvdzogSVRhYmxlUm93SXRlbVxuICApOiBzdHJpbmcge1xuICAgIGNvbnN0IHZhbHVlID0gdGhpcy5nZXRWYWx1ZShjb2x1bW5JbmRleCwgY3VycmVudFJvdyk7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZS5qb2luKCc7Jyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIFN0cmluZyh2YWx1ZSk7XG4gIH1cblxuICAvKiogQGlnbm9yZSAqL1xuICBwdWJsaWMgZ2V0VmFsdWUoXG4gICAgY29sdW1uSW5kZXg6IG51bWJlcixcbiAgICBjdXJyZW50Um93OiBJVGFibGVSb3dJdGVtXG4gICk6IHN0cmluZyB8IHN0cmluZ1tdIHtcbiAgICBjb25zdCB7IGNvbHVtblR5cGUsIHRydW5jYXRlZDogdHJ1bmNhdGVkIH0gPVxuICAgICAgdGhpcy5fZ2V0Q29sdW1uRGVmQnlJbmRleChjb2x1bW5JbmRleCk7XG4gICAgbGV0IHZhbHVlID0gdGhpcy5fZ2V0VmFsdWUoY29sdW1uSW5kZXgsIGN1cnJlbnRSb3cpO1xuXG4gICAgc3dpdGNoIChjb2x1bW5UeXBlKSB7XG4gICAgICBjYXNlIFRhYmxlQ29sdW1uVHlwZS5EZWNpbWFsOiB7XG4gICAgICAgIHZhbHVlID0gdGhpcy5fZGVjbWlhbFBpcGUudHJhbnNmb3JtKE51bWJlcih2YWx1ZSkgfHwgMCkgfHwgJyc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSBUYWJsZUNvbHVtblR5cGUuRGF0ZToge1xuICAgICAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoU3RyaW5nKHZhbHVlKSk7XG4gICAgICAgIGNvbnN0IHZhbGlkRGF0ZSA9IGRhdGUgaW5zdGFuY2VvZiBEYXRlICYmICFpc05hTihkYXRlLmdldFRpbWUoKSk7XG4gICAgICAgIHZhbHVlID0gdmFsaWREYXRlXG4gICAgICAgICAgPyB0aGlzLl9kYXRlUGlwZS50cmFuc2Zvcm0oZGF0ZSwgJ01NL2RkL3l5eXknKSB8fCAnJ1xuICAgICAgICAgIDogU3RyaW5nKHZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlIFRhYmxlQ29sdW1uVHlwZS5EYXRlVGltZToge1xuICAgICAgICBjb25zdCBkYXRlVGltZSA9IG5ldyBEYXRlKFN0cmluZyh2YWx1ZSkpO1xuICAgICAgICBjb25zdCB2YWxpZERhdGVUaW1lID1cbiAgICAgICAgICBkYXRlVGltZSBpbnN0YW5jZW9mIERhdGUgJiYgIWlzTmFOKGRhdGVUaW1lLmdldFRpbWUoKSk7XG4gICAgICAgIHZhbHVlID0gdmFsaWREYXRlVGltZVxuICAgICAgICAgID8gdGhpcy5fZGF0ZVBpcGUudHJhbnNmb3JtKGRhdGVUaW1lLCAnTU0vZGQveXl5eSBoOm1tOnNzIGEnKSB8fCAnJ1xuICAgICAgICAgIDogU3RyaW5nKHZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlIFRhYmxlQ29sdW1uVHlwZS5MaW5rOiB7XG4gICAgICAgIHZhbHVlID0gU3RyaW5nKHZhbHVlKS5yZXBsYWNlKC8oXlxcdys6fF4pXFwvXFwvLywgJycpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgVGFibGVDb2x1bW5UeXBlLlBlcmNlbnRhZ2U6IHtcbiAgICAgICAgdmFsdWUgPSB0aGlzLl9wZXJjZW50UGlwZS50cmFuc2Zvcm0oTnVtYmVyKHZhbHVlKSB8fCAwKSB8fCAnJztcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlIFRhYmxlQ29sdW1uVHlwZS5Vcmw6IHtcbiAgICAgICAgaWYgKCEvKGh0dHAocz8pKTpcXC9cXC8vaS50ZXN0KFN0cmluZyh2YWx1ZSkpKSB7XG4gICAgICAgICAgdmFsdWUgPSBgaHR0cHM6Ly8ke3ZhbHVlfWA7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlIFRhYmxlQ29sdW1uVHlwZS5UZXh0OiB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgIHZhbHVlID0gdmFsdWUuam9pbignOyAnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdHJ1bmNhdGVkKSB7XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdHJ1bmNhdGVTdHJpbmcgPSAoc3RyaW5nID0gJycsIG1heExlbmd0aCA9IHRydW5jYXRlZCkgPT5cbiAgICAgICAgICBzdHJpbmcubGVuZ3RoID4gbWF4TGVuZ3RoXG4gICAgICAgICAgICA/IGAke3N0cmluZy5zdWJzdHJpbmcoMCwgbWF4TGVuZ3RoKX3igKZgXG4gICAgICAgICAgICA6IHN0cmluZztcblxuICAgICAgICAhIXRydW5jYXRlZFxuICAgICAgICAgID8gKHZhbHVlID0gdHJ1bmNhdGVTdHJpbmcoU3RyaW5nKHZhbHVlKSwgdHJ1bmNhdGVkKSlcbiAgICAgICAgICA6IHZhbHVlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgVGFibGVDb2x1bW5UeXBlLk11bHRpU2VsZWN0OlxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIHZhbHVlID0gdmFsdWUuc3BsaXQoJzsnKT8ubWFwKHYgPT4gdi50cmltKCkpIHx8IFtdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gU3RyaW5nKHZhbHVlKTtcbiAgfVxuXG4gIC8qKiBAaWdub3JlICovXG4gIHB1YmxpYyBnZXRSYXdWYWx1ZShcbiAgICBjb2x1bW5JbmRleDogbnVtYmVyLFxuICAgIGN1cnJlbnRSb3c6IElUYWJsZVJvd0l0ZW1cbiAgKTogSVRhYmxlUm93SXRlbVZhbHVlVHlwZXMge1xuICAgIGNvbnN0IHsgZmllbGQgfSA9IHRoaXMuX2dldENvbHVtbkRlZkJ5SW5kZXgoY29sdW1uSW5kZXgpO1xuXG4gICAgaWYgKCFmaWVsZCkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIHJldHVybiBjdXJyZW50Um93W2ZpZWxkXSB8fCAnJztcbiAgfVxuXG4gIC8qKiBAaWdub3JlICovXG4gIHB1YmxpYyBnZXRDZWxsQ29sb3IoXG4gICAgY29sdW1uRGVmaW5pdGlvbjogVGFibGVDb2x1bW5EZWYsXG4gICAgaXRlbTogSVRhYmxlUm93SXRlbVxuICApOiBzdHJpbmcge1xuICAgIHJldHVybiBUYWJsZVRoZW1lSGVscGVyLmdldENlbGxDb2xvcihjb2x1bW5EZWZpbml0aW9uLCBpdGVtKTtcbiAgfVxuXG4gIC8qKiBAaWdub3JlICovXG4gIHB1YmxpYyBnZXRUaGVtZShcbiAgICBjb2x1bW5EZWZpbml0aW9uOiBUYWJsZUNvbHVtbkRlZixcbiAgICBpdGVtOiBJVGFibGVSb3dJdGVtXG4gICk6IENvbXBvbmVudFRoZW1lIHtcbiAgICByZXR1cm4gKFxuICAgICAgVGFibGVUaGVtZUhlbHBlci5nZXRUaGVtZShjb2x1bW5EZWZpbml0aW9uLCBpdGVtKSB8fFxuICAgICAgQ29tcG9uZW50VGhlbWUuUHJpbWFyeVxuICAgICk7XG4gIH1cblxuICAvKiogQGlnbm9yZSAqL1xuICBwdWJsaWMgaXNTb3J0ZWRDb2x1bW4oY29sdW1uSW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiBjb2x1bW5JbmRleCA9PT0gdGhpcy5zb3J0Q29sdW1uSW5kZXg7XG4gIH1cblxuICAvKiogQGlnbm9yZSAqL1xuICBwdWJsaWMgaXNSb3dTZWxlY3RlZChpZDogc3RyaW5nIHwgbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWRSb3dJZHMuaW5jbHVkZXMoaWQpO1xuICB9XG5cbiAgLyoqIEBpZ25vcmUgKi9cbiAgcHVibGljIGhhbmRsZVNlbGVjdEFsbChldmVudDogQ2hlY2tib3hDaGFuZ2VFdmVudCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5jYW5TZWxlY3RBbGxSb3dzIHx8ICF0aGlzLnRhYmxlRGF0YSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChldmVudC5jaGVja2VkKSB7XG4gICAgICB0aGlzLl9zZWxlY3RlZFJvd0lkcyA9IHRoaXMudGFibGVEYXRhPy5tYXAocm93ID0+IHJvdy5pZCkgfHwgW107XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3NlbGVjdGVkUm93SWRzID0gW107XG4gICAgfVxuXG4gICAgdGhpcy5fc2VsZWN0ZWRSb3dJZHMuc29ydCgpO1xuICAgIHRoaXMuYWxsU2VsZWN0ZWQgPSB0aGlzLnNlbGVjdGVkUm93SWRzLmxlbmd0aCA+PSB0aGlzLnRhYmxlRGF0YS5sZW5ndGg7XG5cbiAgICB0aGlzLnJvd1NlbGVjdC5lbWl0KHRoaXMuc2VsZWN0ZWRSb3dJZHMpO1xuICB9XG5cbiAgLyoqIEBpZ25vcmUgKi9cbiAgcHVibGljIGhhbmRsZVNvcnQoY29sdW1uSW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGlmIChjb2x1bW5JbmRleCA9PT0gdGhpcy5zb3J0Q29sdW1uSW5kZXgpIHtcbiAgICAgIHRoaXMuc29ydERpcmVjdGlvbiA9IHRoaXMuc29ydERpcmVjdGlvbiA9PT0gJ2FzYycgPyAnZGVzYycgOiAnYXNjJztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zb3J0Q29sdW1uSW5kZXggPSBjb2x1bW5JbmRleDtcbiAgICAgIHRoaXMuc29ydERpcmVjdGlvbiA9ICdhc2MnO1xuICAgIH1cblxuICAgIGNvbnN0IGZpZWxkID0gdGhpcy5fZ2V0Q29sdW1uRGVmQnlJbmRleChjb2x1bW5JbmRleCkuZmllbGQgfHwgJyc7XG5cbiAgICB0aGlzLnNvcnRCeS5lbWl0KHtcbiAgICAgIGNvbHVtbkluZGV4LFxuICAgICAgZmllbGQsXG4gICAgICBkaXJlY3Rpb246IHRoaXMuc29ydERpcmVjdGlvblxuICAgIH0pO1xuICB9XG5cbiAgLyoqIEBpZ25vcmUgKi9cbiAgcHVibGljIGhhbmRsZVJvd1NlbGVjdChcbiAgICBldmVudDogQ2hlY2tib3hDaGFuZ2VFdmVudCxcbiAgICByb3dJZDogbnVtYmVyIHwgc3RyaW5nXG4gICk6IHZvaWQge1xuICAgIGlmICghdGhpcy5jYW5TZWxlY3RSb3dzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGV2ZW50LmNoZWNrZWQgJiYgIXRoaXMuX3NlbGVjdGVkUm93SWRzLmluY2x1ZGVzKHJvd0lkKSkge1xuICAgICAgdGhpcy5fc2VsZWN0ZWRSb3dJZHMucHVzaChyb3dJZCk7XG4gICAgfSBlbHNlIGlmICghZXZlbnQuY2hlY2tlZCAmJiB0aGlzLl9zZWxlY3RlZFJvd0lkcy5pbmNsdWRlcyhyb3dJZCkpIHtcbiAgICAgIGNvbnN0IGlkeCA9IHRoaXMuX3NlbGVjdGVkUm93SWRzLmluZGV4T2Yocm93SWQpO1xuICAgICAgaWYgKGlkeCA+IC0xKSB7XG4gICAgICAgIHRoaXMuX3NlbGVjdGVkUm93SWRzLnNwbGljZShpZHgsIDEpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLl9zZWxlY3RlZFJvd0lkcy5sZW5ndGgpIHtcbiAgICAgIHRoaXMuX3NlbGVjdGVkUm93SWRzLnNvcnQoKTtcbiAgICB9XG5cbiAgICB0aGlzLmFsbFNlbGVjdGVkID0gdGhpcy5zZWxlY3RlZFJvd0lkcy5sZW5ndGggPj0gdGhpcy50YWJsZURhdGEubGVuZ3RoO1xuICAgIHRoaXMucm93U2VsZWN0LmVtaXQodGhpcy5zZWxlY3RlZFJvd0lkcyk7XG4gIH1cblxuICAvKiogQGlnbm9yZSAqL1xuICBwdWJsaWMgaGFuZGxlQ2VsbFZhbHVlQ2hhbmdlKFxuICAgIGNvbHVtbkluZGV4OiBudW1iZXIsXG4gICAgcm93SW5kZXg6IG51bWJlcixcbiAgICB2YWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbiB8IHN0cmluZ1tdXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IHsgZmllbGQsIGNvbHVtblR5cGUgfSA9IHRoaXMuX2dldENvbHVtbkRlZkJ5SW5kZXgoY29sdW1uSW5kZXgpO1xuICAgIGxldCBjdXJyZW50VmFsdWU6IHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4gfCBzdHJpbmdbXSA9IHZhbHVlO1xuXG4gICAgaWYgKGNvbHVtblR5cGUgIT09IFRhYmxlQ29sdW1uVHlwZS5Cb29sZWFuICYmICFBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgY3VycmVudFZhbHVlID0gaXNOYU4oTnVtYmVyKHZhbHVlKSkgPyB2YWx1ZSA6IE51bWJlcih2YWx1ZSk7XG4gICAgfVxuICAgIGNvbnN0IGl0ZW0gPSB0aGlzLnRhYmxlRGF0YVtyb3dJbmRleF07XG5cbiAgICBzZXROZXN0ZWRWYWx1ZShpdGVtLCBTdHJpbmcoZmllbGQpLCBjdXJyZW50VmFsdWUpO1xuXG4gICAgdGhpcy5faW5wdXRDaGFuZ2UuZW1pdCh7XG4gICAgICBjb2x1bW5JbmRleCxcbiAgICAgIGl0ZW0sXG4gICAgICB2YWx1ZTogY3VycmVudFZhbHVlXG4gICAgfSk7XG5cbiAgICB0aGlzLl9jaGFuZ2VEZXRlY3RvclJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICAvKiogQGlnbm9yZSAqL1xuICBwdWJsaWMgaGFuZGxlTGlua0NsaWNrKFxuICAgIGNvbHVtbkluZGV4OiBudW1iZXIsXG4gICAgaXRlbTogSVRhYmxlUm93SXRlbSxcbiAgICBldmVudDogRXZlbnRcbiAgKTogdm9pZCB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgIHRoaXMubGlua0NsaWNrLmVtaXQoe1xuICAgICAgaXRlbSxcbiAgICAgIGNvbHVtbkluZGV4XG4gICAgfSk7XG4gIH1cblxuICAvKiogQGlnbm9yZSAqL1xuICBwdWJsaWMgaGFuZGxlQWN0aW9uQ2xpY2soXG4gICAgY29sdW1uSW5kZXg6IG51bWJlcixcbiAgICBpdGVtOiBJVGFibGVSb3dJdGVtLFxuICAgIGFjdGlvbkFwaU5hbWU6IHN0cmluZ1xuICApIHtcbiAgICB0aGlzLnJvd0FjdGlvbkNsaWNrLmVtaXQoe1xuICAgICAgaXRlbSxcbiAgICAgIGNvbHVtbkluZGV4LFxuICAgICAgYWN0aW9uQXBpTmFtZVxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNvbHVtbkRlZklzQWN0aW9ucyhcbiAgICBjb2x1bW5EZWY6IFRhYmxlQ29sdW1uRGVmPGFueT5cbiAgKTogY29sdW1uRGVmIGlzIElUYWJsZUFjdGlvbnNDb2x1bW5EZWY8YW55PiB7XG4gICAgcmV0dXJuIGNvbHVtbkRlZi5jb2x1bW5UeXBlID09PSBUYWJsZUNvbHVtblR5cGUuQWN0aW9ucztcbiAgfVxuXG4gIHByb3RlY3RlZCB0cnlUb2dnbGVDb2xsYXBzZShcbiAgICBjb2xsYXBzaWJsZUZvclJvd1Jlc3VsdDoge1xuICAgICAgdGVtcGxhdGU6IFRlbXBsYXRlUmVmPElDb2xsYXBzaWJsZVJvd0NvbnRlbnRDb250ZXh0PiB8IG51bGw7XG4gICAgfSxcbiAgICBuZ2JDb2xsYXBzZTogTmdiQ29sbGFwc2UsXG4gICAgZXZlbnQ6IEV2ZW50LFxuICAgIHNvdXJjZTogJ2J1dHRvbicgfCAncm93J1xuICApOiB2b2lkIHtcbiAgICBpZiAoXG4gICAgICBjb2xsYXBzaWJsZUZvclJvd1Jlc3VsdC50ZW1wbGF0ZSAmJlxuICAgICAgKHRoaXMuY29sbGFwc2libGVUcmlnZ2VyID09PSAncm93JyB8fCB0aGlzLmNvbGxhcHNpYmxlVHJpZ2dlciA9PT0gc291cmNlKVxuICAgICkge1xuICAgICAgbmdiQ29sbGFwc2UudG9nZ2xlKCk7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0Q29sbGFwc2libGVUZW1wbGF0ZUZvclJvdyhyb3c6IElUYWJsZVJvd0l0ZW0pOiB7XG4gICAgdGVtcGxhdGU6IFRlbXBsYXRlUmVmPElDb2xsYXBzaWJsZVJvd0NvbnRlbnRDb250ZXh0PiB8IG51bGw7XG4gIH0ge1xuICAgIHJldHVybiB7XG4gICAgICB0ZW1wbGF0ZTpcbiAgICAgICAgdGhpcy5jb2xsYXBzaWJsZVRlbXBsYXRlICYmXG4gICAgICAgIHR5cGVvZiB0aGlzLmNvbGxhcHNpYmxlVGVtcGxhdGUgPT09ICdmdW5jdGlvbidcbiAgICAgICAgICA/IHRoaXMuY29sbGFwc2libGVUZW1wbGF0ZShyb3cpXG4gICAgICAgICAgOiB0aGlzLmNvbGxhcHNpYmxlVGVtcGxhdGVcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0Q29sdW1uRGVmQnlJbmRleChjb2x1bW5JbmRleDogbnVtYmVyKTogVGFibGVDb2x1bW5EZWYge1xuICAgIHJldHVybiB0aGlzLmNvbHVtbkRlZnNbY29sdW1uSW5kZXhdO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0VmFsdWUoXG4gICAgY29sdW1uSW5kZXg6IG51bWJlcixcbiAgICBjdXJyZW50Um93OiBJVGFibGVSb3dJdGVtXG4gICk6IHN0cmluZyB8IHN0cmluZ1tdIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgeyBmaWVsZCwgdmFsdWVHZXR0ZXIgfSA9IHRoaXMuX2dldENvbHVtbkRlZkJ5SW5kZXgoY29sdW1uSW5kZXgpO1xuXG4gICAgICBjb25zdCB2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10gPSB2YWx1ZUdldHRlclxuICAgICAgICA/IHZhbHVlR2V0dGVyKGN1cnJlbnRSb3cpXG4gICAgICAgIDogKGdldE5lc3RlZFZhbHVlKGN1cnJlbnRSb3csIFN0cmluZyhmaWVsZCksICcnKSBhcyBzdHJpbmcgfCBzdHJpbmdbXSk7XG5cbiAgICAgIHJldHVybiB2YWx1ZSB8fCAnJztcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuICB9XG59XG4iLCJAaWYgKHRhYmxlRGF0YSkge1xuPHRhYmxlXG4gIGltcGRjVGFibGVcbiAgW3N0cmlwZWRdPVwic3RyaXBlZCAmJiAhY29sbGFwc2libGVUZW1wbGF0ZVwiXG4gIFtsYXlvdXRdPVwibGF5b3V0XCJcbiAgW2hvdmVyXT1cImhvdmVyXCI+XG4gIDx0aGVhZD5cbiAgICBAaWYgKCEhYnVsa0FjdGlvbnMpIHtcbiAgICA8dHI+XG4gICAgICA8dGggW2F0dHIuY29sc3Bhbl09XCJ0YWJsZVNwYW5cIiBzY29wZT1cImNvbFwiIGNsYXNzPVwiYnVsay1hY3Rpb24tY29sdW1uXCI+XG4gICAgICAgIDxuZy1jb250ZW50IHNlbGVjdD1cImltcGRjLXRhYmxlLWJ1bGstYWN0aW9uc1wiPjwvbmctY29udGVudD5cbiAgICAgICAgPG5nLWNvbnRlbnQgc2VsZWN0PVwiW2ltcGRjVGFibGVCdWxrQWN0aW9uc11cIj48L25nLWNvbnRlbnQ+XG4gICAgICA8L3RoPlxuICAgIDwvdHI+XG4gICAgfVxuICAgIDx0cj5cbiAgICAgIEBpZiAoY29sbGFwc2libGVUZW1wbGF0ZSkge1xuICAgICAgPHRoXG4gICAgICAgIHNjb3BlPVwiY29sXCJcbiAgICAgICAgW2NsYXNzLmhlYWRpbmctYmVsb3ctYnVsay1hY3Rpb25zXT1cIiEhYnVsa0FjdGlvbnNcIlxuICAgICAgICBjbGFzcz1cImltcGRjLXRhYmxlLWNvbGxhcHNpYmxlLWNvbnRlbnQtcm93LWJ1dHRvbi1jb250YWluZXJcIj48L3RoPlxuICAgICAgfSBAaWYgKGNhblNlbGVjdFJvd3MpIHtcbiAgICAgIDx0aFxuICAgICAgICBzY29wZT1cImNvbFwiXG4gICAgICAgIGNsYXNzPVwiaW1wZGMtdGFibGUtc2VsZWN0YWJsZS1yb3ctdG9nZ2xlLWNvbnRhaW5lclwiXG4gICAgICAgIFtuZ0NsYXNzXT1cIntcbiAgICAgICAgICAnaGVhZGluZy1iZWxvdy1idWxrLWFjdGlvbnMnOiAhIWJ1bGtBY3Rpb25zXG4gICAgICAgIH1cIj5cbiAgICAgICAgQGlmIChjYW5TZWxlY3RBbGxSb3dzKSB7XG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgPGltcGRjLWNoZWNrYm94XG4gICAgICAgICAgICBuZ01vZGVsXG4gICAgICAgICAgICBbY2hlY2tlZF09XCJhbGxTZWxlY3RlZFwiXG4gICAgICAgICAgICBbaW5kZXRlcm1pbmF0ZV09XCJzb21lU2VsZWN0ZWRcIlxuICAgICAgICAgICAgKGNoYW5nZSk9XCJoYW5kbGVTZWxlY3RBbGwoJGV2ZW50KVwiPjwvaW1wZGMtY2hlY2tib3g+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICA8L3RoPlxuICAgICAgfSBAZm9yIChjb2x1bW5EZWYgb2YgY29sdW1uRGVmczsgdHJhY2sgY29sdW1uRGVmOyBsZXQgY29sdW1uSW5kZXggPVxuICAgICAgJGluZGV4KSB7XG4gICAgICA8dGhcbiAgICAgICAgc2NvcGU9XCJjb2xcIlxuICAgICAgICBbbmdDbGFzc109XCJ7XG4gICAgICAgICAgJ3NvcnRlZC1jb2x1bW4nOiBpc1NvcnRlZENvbHVtbihjb2x1bW5JbmRleCksXG4gICAgICAgICAgJ3NvcnRhYmxlLWNvbHVtbic6IGNvbHVtbkRlZi5zb3J0ZWQsXG4gICAgICAgICAgJ2hlYWRpbmctYmVsb3ctYnVsay1hY3Rpb25zJzogISFidWxrQWN0aW9uc1xuICAgICAgICB9XCJcbiAgICAgICAgKGNsaWNrKT1cImhhbmRsZVNvcnQoY29sdW1uSW5kZXgpXCI+XG4gICAgICAgIDxpbXBkYy1jb2x1bW4taGVhZGluZ1xuICAgICAgICAgIFtpc1NvcnRhYmxlXT1cImNvbHVtbkRlZi5zb3J0ZWQgfHwgZmFsc2VcIlxuICAgICAgICAgIFtjb2x1bW5JbmRleF09XCJjb2x1bW5JbmRleFwiXG4gICAgICAgICAgW3NvcnRDb2x1bW5JbmRleF09XCJzb3J0Q29sdW1uSW5kZXhcIlxuICAgICAgICAgIFtkaXJlY3Rpb25dPVwic29ydERpcmVjdGlvblwiXG4gICAgICAgICAgW3RleHRdPVwiY29sdW1uRGVmLnRpdGxlXCJcbiAgICAgICAgICAoc29ydCk9XCJoYW5kbGVTb3J0KCRldmVudClcIj5cbiAgICAgICAgPC9pbXBkYy1jb2x1bW4taGVhZGluZz5cbiAgICAgIDwvdGg+XG4gICAgICB9XG4gICAgPC90cj5cbiAgPC90aGVhZD5cbiAgPHRib2R5PlxuICAgIEBpZiAobG9hZGluZykge1xuICAgIDx0cj5cbiAgICAgIDx0ZCBbYXR0ci5jb2xzcGFuXT1cInRhYmxlU3BhblwiIGNsYXNzPVwiZGF0YS1sb2FkaW5nXCI+XG4gICAgICAgIDxpbXBkYy1zcGlubmVyPjwvaW1wZGMtc3Bpbm5lcj5cbiAgICAgIDwvdGQ+XG4gICAgPC90cj5cbiAgICB9IEBlbHNlIHsgQGZvciAocm93IG9mIHRhYmxlRGF0YTsgdHJhY2sgcm93LmlkOyBsZXQgcm93SW5kZXggPSAkaW5kZXg7IGxldFxuICAgIHJvd0ZpcnN0ID0gJGZpcnN0OyBsZXQgcm93TGFzdCA9ICRsYXN0OyBsZXQgcm93RXZlbiA9ICRldmVuOyBsZXQgcm93T2RkID1cbiAgICAkb2RkKSB7IEBpZiAoZ2V0Q29sbGFwc2libGVUZW1wbGF0ZUZvclJvdyhyb3cpOyBhc1xuICAgIGNvbGxhcHNpYmxlVGVtcGxhdGVGb3JSb3cpIHtcbiAgICA8dHJcbiAgICAgIFtjbGFzcy5pbXBkYy10YWJsZS1jb2xsYXBzaWJsZS1yb3ctdHJpZ2dlcl09XCJjb2xsYXBzaWJsZVRyaWdnZXIgPT09ICdyb3cnXCJcbiAgICAgIFtjbGFzcy50YWJsZS1hY3RpdmVdPVwiaXNSb3dTZWxlY3RlZChyb3cuaWQpXCJcbiAgICAgIChjbGljayk9XCJcbiAgICAgICAgdHJ5VG9nZ2xlQ29sbGFwc2UoY29sbGFwc2libGVUZW1wbGF0ZUZvclJvdywgbmdiQ29sbGFwc2UsICRldmVudCwgJ3JvdycpXG4gICAgICBcIj5cbiAgICAgIEBpZiAoY29sbGFwc2libGVUZW1wbGF0ZSkge1xuICAgICAgPHRkXG4gICAgICAgIGNsYXNzPVwiaW1wZGMtdGFibGUtY29sbGFwc2libGUtY29udGVudC1yb3ctYnV0dG9uLWNvbnRhaW5lclwiXG4gICAgICAgIFtjbGFzcy5vcGVuZWRdPVwiIWNvbGxhcHNlTW9uaXRvci5uZ2JDb2xsYXBzaW5nKClcIj5cbiAgICAgICAgQGlmIChjb2xsYXBzaWJsZVRlbXBsYXRlRm9yUm93LnRlbXBsYXRlKSB7XG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAoY2xpY2spPVwiXG4gICAgICAgICAgICAgIHRyeVRvZ2dsZUNvbGxhcHNlKFxuICAgICAgICAgICAgICAgIGNvbGxhcHNpYmxlVGVtcGxhdGVGb3JSb3csXG4gICAgICAgICAgICAgICAgbmdiQ29sbGFwc2UsXG4gICAgICAgICAgICAgICAgJGV2ZW50LFxuICAgICAgICAgICAgICAgICdidXR0b24nXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIFwiXG4gICAgICAgICAgICBjbGFzcz1cImltcGRjLXRhYmxlLWNvbGxhcHNpYmxlLWNvbnRlbnQtcm93LWJ1dHRvbiBidG4gYnRuLWxpbmtcIj5cbiAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgIGNsYXNzPVwiZmFyIGZhLWNoZXZyb24tcmlnaHRcIlxuICAgICAgICAgICAgICBbY2xhc3MuZmEtcm90YXRlLTkwXT1cIiFjb2xsYXBzZU1vbml0b3IubmdiQ29sbGFwc2luZygpXCI+PC9zcGFuPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuICAgICAgPC90ZD5cbiAgICAgIH0gQGlmIChjYW5TZWxlY3RSb3dzKSB7XG4gICAgICA8dGQgY2xhc3M9XCJpbXBkYy10YWJsZS1zZWxlY3RhYmxlLXJvdy10b2dnbGUtY29udGFpbmVyXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJzZWxlY3QtY29sdW1uXCI+XG4gICAgICAgICAgPGltcGRjLWNoZWNrYm94XG4gICAgICAgICAgICBbbmdNb2RlbF09XCJpc1Jvd1NlbGVjdGVkKHJvdy5pZClcIlxuICAgICAgICAgICAgKGNoYW5nZSk9XCJoYW5kbGVSb3dTZWxlY3QoJGV2ZW50LCByb3cuaWQpXCJcbiAgICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj48L2ltcGRjLWNoZWNrYm94PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvdGQ+XG4gICAgICB9XG4gICAgICA8dGRcbiAgICAgICAgKm5nRm9yPVwibGV0IGNvbHVtbkRlZiBvZiBjb2x1bW5EZWZzOyBpbmRleCBhcyBjb2xJbmRleDsgbGFzdCBhcyBpc0xhc3RcIlxuICAgICAgICBbbmdDbGFzc109XCJ7XG4gICAgICAgICAgJ2NvbC1uby1wYWRkaW5nJzogISFjb2x1bW5EZWYubm9QYWRkaW5nLFxuICAgICAgICAgICdhY3Rpb25zLWNvbHVtbic6IGNvbHVtbkRlZi5jb2x1bW5UeXBlID09PSBjZWxsVHlwZS5BY3Rpb25zXG4gICAgICAgIH1cIj5cbiAgICAgICAgPGRpdj5cbiAgICAgICAgICBAc3dpdGNoIChjb2x1bW5EZWYuY29sdW1uVHlwZSkgeyBAY2FzZSAoY2VsbFR5cGUuQmFkZ2UpIHtcbiAgICAgICAgICA8c3Bhbj5cbiAgICAgICAgICAgIDxpbXBkYy1iYWRnZVxuICAgICAgICAgICAgICBbdGV4dF09XCJnZXRTdHJpbmdWYWx1ZShjb2xJbmRleCwgcm93KVwiXG4gICAgICAgICAgICAgIFt0aGVtZV09XCJnZXRUaGVtZShjb2x1bW5EZWYsIHJvdylcIj5cbiAgICAgICAgICAgIDwvaW1wZGMtYmFkZ2U+XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIH0gQGNhc2UgKGNlbGxUeXBlLkxpbmspIHtcbiAgICAgICAgICA8c3BhbiAoY2xpY2spPVwiaGFuZGxlTGlua0NsaWNrKGNvbEluZGV4LCByb3csICRldmVudClcIj5cbiAgICAgICAgICAgIEBpZiAoIWJyYW5kZWQpIHtcbiAgICAgICAgICAgIDxhIGNsYXNzPVwibGluay1wcmltYXJ5XCI+XG4gICAgICAgICAgICAgIHt7IGdldFZhbHVlKGNvbEluZGV4LCByb3cpIH19XG4gICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgIDxhIGltcGRjQnJhbmRlZD5cbiAgICAgICAgICAgICAge3sgZ2V0VmFsdWUoY29sSW5kZXgsIHJvdykgfX1cbiAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgfSBAY2FzZSAoY2VsbFR5cGUuVXJsKSB7XG4gICAgICAgICAgPHNwYW4+XG4gICAgICAgICAgICBAaWYgKCFicmFuZGVkKSB7XG4gICAgICAgICAgICA8YVxuICAgICAgICAgICAgICB0YXJnZXQ9XCJfYmxhbmtcIlxuICAgICAgICAgICAgICBbYXR0ci5ocmVmXT1cImdldFZhbHVlKGNvbEluZGV4LCByb3cpXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgICAgICAgICAgICB7eyBnZXRWYWx1ZShjb2xJbmRleCwgcm93KSB9fVxuICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICA8YVxuICAgICAgICAgICAgICBpbXBkY0JyYW5kZWRcbiAgICAgICAgICAgICAgdGFyZ2V0PVwiX2JsYW5rXCJcbiAgICAgICAgICAgICAgW2F0dHIuaHJlZl09XCJnZXRWYWx1ZShjb2xJbmRleCwgcm93KVwiXG4gICAgICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cbiAgICAgICAgICAgICAge3sgZ2V0VmFsdWUoY29sSW5kZXgsIHJvdykgfX1cbiAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgfSBAY2FzZSAoY2VsbFR5cGUuRW1haWwpIHtcbiAgICAgICAgICA8c3Bhbj5cbiAgICAgICAgICAgIEBpZiAoIWJyYW5kZWQpIHtcbiAgICAgICAgICAgIDxhXG4gICAgICAgICAgICAgIHRhcmdldD1cIl9ibGFua1wiXG4gICAgICAgICAgICAgIFthdHRyLmhyZWZdPVwiJ21haWx0bzonICsgZ2V0VmFsdWUoY29sSW5kZXgsIHJvdylcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgICAgICAgICAgIHt7IGdldFZhbHVlKGNvbEluZGV4LCByb3cpIH19XG4gICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgIDxhXG4gICAgICAgICAgICAgIGltcGRjQnJhbmRlZFxuICAgICAgICAgICAgICBbYXR0ci5ocmVmXT1cImdldE1haWxUb1ZhbHVlKGNvbEluZGV4LCByb3cpXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgICAgICAgICAgICB7eyBnZXRWYWx1ZShjb2xJbmRleCwgcm93KSB9fVxuICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICB9IEBjYXNlIChjZWxsVHlwZS5JbnB1dCkge1xuICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgIGltcGRjSW5wdXRcbiAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICBjbGFzcz1cInt7IGdldENlbGxDb2xvcihjb2x1bW5EZWYsIHJvdykgfX1cIlxuICAgICAgICAgICAgICBbbmdNb2RlbF09XCJnZXRWYWx1ZShjb2xJbmRleCwgcm93KVwiXG4gICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIlxuICAgICAgICAgICAgICAgIGhhbmRsZUNlbGxWYWx1ZUNoYW5nZShjb2xJbmRleCwgcm93SW5kZXgsICRldmVudClcbiAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiIC8+XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIH0gQGNhc2UgKGNlbGxUeXBlLkJvb2xlYW4pIHtcbiAgICAgICAgICA8c3Bhbj5cbiAgICAgICAgICAgIEBpZiAoY29sdW1uRGVmLmRpc2FibGVkICYmIGdldFZhbHVlKGNvbEluZGV4LCByb3cpID09PSAndHJ1ZScpIHtcbiAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgIGltcGRjLWljb25cbiAgICAgICAgICAgICAgbmFtZT1cImNoZWNrXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJ7eyBnZXRDZWxsQ29sb3IoY29sdW1uRGVmLCByb3cpIH19XCI+PC9zcGFuPlxuICAgICAgICAgICAgfSBAZWxzZSBpZiAoIWNvbHVtbkRlZi5kaXNhYmxlZCkge1xuICAgICAgICAgICAgPGltcGRjLWNoZWNrYm94XG4gICAgICAgICAgICAgIFtjaGVja2VkXT1cImdldFZhbHVlKGNvbEluZGV4LCByb3cpID09PSAndHJ1ZSdcIlxuICAgICAgICAgICAgICBbaXNTd2l0Y2hdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgIChjaGFuZ2UpPVwiXG4gICAgICAgICAgICAgICAgaGFuZGxlQ2VsbFZhbHVlQ2hhbmdlKGNvbEluZGV4LCByb3dJbmRleCwgJGV2ZW50LmNoZWNrZWQpXG4gICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj48L2ltcGRjLWNoZWNrYm94PlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICB9IEBjYXNlIChjZWxsVHlwZS5TaW5nbGVTZWxlY3QpIHtcbiAgICAgICAgICA8c3Bhbj5cbiAgICAgICAgICAgIDxpbXBkYy1zZWxlY3RcbiAgICAgICAgICAgICAgW25nTW9kZWxdPVwiZ2V0VmFsdWUoY29sSW5kZXgsIHJvdylcIlxuICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiY29sdW1uRGVmLmRpc2FibGVkIHx8IGZhbHNlXCJcbiAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cInNlbGVjdFBsYWNlaG9sZGVyXCJcbiAgICAgICAgICAgICAgYWxsb3dDbGVhcj1cInRydWVcIlxuICAgICAgICAgICAgICAoc2VsZWN0aW9uQ2hhbmdlKT1cIlxuICAgICAgICAgICAgICAgIGhhbmRsZUNlbGxWYWx1ZUNoYW5nZShjb2xJbmRleCwgcm93SW5kZXgsICRldmVudC52YWx1ZSlcbiAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgICAgICAgICAgICBAZm9yICh2YWx1ZSBvZiAoY29sdW1uRGVmLnZhbHVlcyB8fCBbXSk7IHRyYWNrIHZhbHVlKSB7XG4gICAgICAgICAgICAgIDxpbXBkYy1zZWxlY3Qtb3B0aW9uXG4gICAgICAgICAgICAgICAgW3ZhbHVlXT1cInZhbHVlLnZhbHVlXCJcbiAgICAgICAgICAgICAgICBbbGFiZWxdPVwidmFsdWUubGFiZWxcIj48L2ltcGRjLXNlbGVjdC1vcHRpb24+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvaW1wZGMtc2VsZWN0PlxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICB9IEBjYXNlIChjZWxsVHlwZS5NdWx0aVNlbGVjdCkge1xuICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgPGltcGRjLXNlbGVjdFxuICAgICAgICAgICAgICBbbmdNb2RlbF09XCJnZXRWYWx1ZShjb2xJbmRleCwgcm93KVwiXG4gICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJjb2x1bW5EZWYuZGlzYWJsZWQgfHwgZmFsc2VcIlxuICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwic2VsZWN0UGxhY2Vob2xkZXJcIlxuICAgICAgICAgICAgICBtdWx0aXBsZT1cInRydWVcIlxuICAgICAgICAgICAgICAoc2VsZWN0aW9uQ2hhbmdlKT1cIlxuICAgICAgICAgICAgICAgIGhhbmRsZUNlbGxWYWx1ZUNoYW5nZShjb2xJbmRleCwgcm93SW5kZXgsICRldmVudC52YWx1ZSlcbiAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgICAgICAgICAgICBAZm9yICh2YWx1ZSBvZiAoY29sdW1uRGVmLnZhbHVlcyB8fCBbXSk7IHRyYWNrIHZhbHVlKSB7XG4gICAgICAgICAgICAgIDxpbXBkYy1zZWxlY3Qtb3B0aW9uXG4gICAgICAgICAgICAgICAgW3ZhbHVlXT1cInZhbHVlLnZhbHVlXCJcbiAgICAgICAgICAgICAgICBbbGFiZWxdPVwidmFsdWUubGFiZWxcIj48L2ltcGRjLXNlbGVjdC1vcHRpb24+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvaW1wZGMtc2VsZWN0PlxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICB9IEBjYXNlIChjZWxsVHlwZS5DZWxsUmVuZGVyKSB7XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJ7eyBnZXRDZWxsQ29sb3IoY29sdW1uRGVmLCByb3cpIH19XCI+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICAgaW1wZGNUYWJsZUluamVjdENvbXBvbmVudFxuICAgICAgICAgICAgICBbY29sdW1uRGVmXT1cImNvbHVtbkRlZlwiXG4gICAgICAgICAgICAgIFtyb3dJdGVtXT1cInJvd1wiXG4gICAgICAgICAgICAgIFtjdXN0b21DZWxsQ29tcG9uZW50c109XCJjdXN0b21DZWxsQ29tcG9uZW50cyB8fCB7fVwiXG4gICAgICAgICAgICAgIFt2YWx1ZV09XCJnZXRSYXdWYWx1ZShjb2xJbmRleCwgcm93KVwiPjwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIH0gQGNhc2UgKGNlbGxUeXBlLkljb24pIHtcbiAgICAgICAgICA8c3Bhbj5cbiAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgIGltcGRjLWljb25cbiAgICAgICAgICAgICAgW25hbWVdPVwiY29sdW1uRGVmLmljb25OYW1lXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJ7eyBnZXRDZWxsQ29sb3IoY29sdW1uRGVmLCByb3cpIH19XCI+PC9zcGFuPlxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICB9IEBjYXNlIChjZWxsVHlwZS5BY3Rpb25zKSB7XG4gICAgICAgICAgPHNwYW4+XG4gICAgICAgICAgICA8IS0tIHdpbGwgYWx3YXlzIHJldHVybiAndHJ1ZScsIGJ1dCBuZWVkZWQgdG8gc2F0aXNmeSB0aGUgdHlwZSBlbmdpbmUgLS0+XG4gICAgICAgICAgICBAaWYgKGNvbHVtbkRlZklzQWN0aW9ucyhjb2x1bW5EZWYpKSB7XG4gICAgICAgICAgICA8aW1wZGMtcm93LWFjdGlvbnNcbiAgICAgICAgICAgICAgW2NvbHVtbkRlZl09XCJjb2x1bW5EZWZcIlxuICAgICAgICAgICAgICBbcm93SXRlbV09XCJyb3dcIlxuICAgICAgICAgICAgICBbbGFzdENvbHVtbl09XCJpc0xhc3RcIlxuICAgICAgICAgICAgICAoYWN0aW9uQ2xpY2spPVwiaGFuZGxlQWN0aW9uQ2xpY2soY29sSW5kZXgsIHJvdywgJGV2ZW50KVwiXG4gICAgICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj48L2ltcGRjLXJvdy1hY3Rpb25zPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICB9IEBkZWZhdWx0IHtcbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInt7IGdldENlbGxDb2xvcihjb2x1bW5EZWYsIHJvdykgfX1cIj5cbiAgICAgICAgICAgIHt7IGdldFZhbHVlKGNvbEluZGV4LCByb3cpIH19XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIH0gfVxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvdGQ+XG4gICAgPC90cj5cbiAgICA8dHJcbiAgICAgIGNsYXNzPVwiaW1wZGMtdGFibGUtY29sbGFwc2libGUtY29udGVudC1yb3dcIlxuICAgICAgW2NsYXNzLm9wZW5lZF09XCIhY29sbGFwc2VNb25pdG9yLm5nYkNvbGxhcHNpbmcoKVwiPlxuICAgICAgPHRkIGNsYXNzPVwidy0xMDAgcC0wXCIgW2F0dHIuY29sc3Bhbl09XCJ0YWJsZVNwYW5cIj5cbiAgICAgICAgPGRpdlxuICAgICAgICAgIGNsYXNzPVwiaW1wZGMtdGFibGUtY29sbGFwc2libGUtY29udGVudC1jb250YWluZXJcIlxuICAgICAgICAgICNuZ2JDb2xsYXBzZT1cIm5nYkNvbGxhcHNlXCJcbiAgICAgICAgICAjY29sbGFwc2VNb25pdG9yPVwiaW1wZGNDb2xsYXBzZU1vbml0b3JcIlxuICAgICAgICAgIFtpbXBkY0NvbGxhcHNlTW9uaXRvcl09XCJ0cnVlXCJcbiAgICAgICAgICAoY29sbGFwc2VDaGFuZ2UpPVwicm93Q29sbGFwc2VDaGFuZ2UuZW1pdCh7IHJvdywgY29sbGFwc2VkOiAkZXZlbnQgfSlcIj5cbiAgICAgICAgICBAaWYgKGNvbGxhcHNpYmxlVGVtcGxhdGVGb3JSb3cudGVtcGxhdGUpIHtcbiAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAqbmdUZW1wbGF0ZU91dGxldD1cIlxuICAgICAgICAgICAgICAgIGNvbGxhcHNpYmxlVGVtcGxhdGVGb3JSb3cudGVtcGxhdGU7XG4gICAgICAgICAgICAgICAgY29udGV4dDoge1xuICAgICAgICAgICAgICAgICAgJGltcGxpY2l0OiByb3csXG4gICAgICAgICAgICAgICAgICBjb2xsYXBzZWQ6IGNvbGxhcHNlTW9uaXRvci5jb2xsYXBzZWQoKSxcbiAgICAgICAgICAgICAgICAgIHNlbGVjdGVkOiBpc1Jvd1NlbGVjdGVkKHJvdy5pZCksXG4gICAgICAgICAgICAgICAgICBpbmRleDogcm93SW5kZXgsXG4gICAgICAgICAgICAgICAgICBmaXJzdDogISFyb3dGaXJzdCxcbiAgICAgICAgICAgICAgICAgIGxhc3Q6ICEhcm93TGFzdCxcbiAgICAgICAgICAgICAgICAgIGV2ZW46ICEhcm93RXZlbixcbiAgICAgICAgICAgICAgICAgIG9kZDogISFyb3dPZGRcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIFwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIH1cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L3RkPlxuICAgIDwvdHI+XG4gICAgfSB9IEBlbXB0eSB7XG4gICAgPHRyPlxuICAgICAgPHRkIFthdHRyLmNvbHNwYW5dPVwidGFibGVTcGFuXCIgY2xhc3M9XCJuby1kYXRhXCI+XG4gICAgICAgIDxuZy1jb250ZW50IHNlbGVjdD1cIltub0RhdGFdXCI+PC9uZy1jb250ZW50PlxuICAgICAgPC90ZD5cbiAgICA8L3RyPlxuICAgIH0gfVxuICA8L3Rib2R5PlxuICA8dGZvb3Q+XG4gICAgQGlmIChwYWdpbmF0aW9uQ29tcG9uZW50KSB7XG4gICAgPHRyPlxuICAgICAgPHRkIFthdHRyLmNvbHNwYW5dPVwidGFibGVTcGFuXCI+XG4gICAgICAgIDxuZy1jb250ZW50XG4gICAgICAgICAgc2VsZWN0PVwiaW1wZGMtcGFnaW5hdGlvbiwgZGl2W2ltcGRjLXBhZ2luYXRpb25dXCI+PC9uZy1jb250ZW50PlxuICAgICAgPC90ZD5cbiAgICA8L3RyPlxuICAgIH1cbiAgPC90Zm9vdD5cbjwvdGFibGU+XG59XG4iXX0=