@one-grid-core/angular 0.2.1 → 0.5.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 (102) hide show
  1. package/README.md +55 -9
  2. package/esm2022/lib/components/one-grid/one-grid.component.mjs +244 -11
  3. package/esm2022/lib/components/one-grid-body/one-grid-body.component.mjs +446 -34
  4. package/esm2022/lib/components/one-grid-cell-currency/one-grid-cell-currency.component.mjs +6 -5
  5. package/esm2022/lib/components/one-grid-cell-group-renderer/one-grid-cell-group-renderer.component.mjs +3 -3
  6. package/esm2022/lib/components/one-grid-cell-option-menu/one-grid-cell-option-menu.component.mjs +3 -3
  7. package/esm2022/lib/components/one-grid-checkbox/one-grid-checkbox.component.mjs +7 -18
  8. package/esm2022/lib/components/one-grid-checkbox-header/one-grid-checkbox-header.component.mjs +6 -6
  9. package/esm2022/lib/components/one-grid-header/one-grid-header.component.mjs +221 -17
  10. package/esm2022/lib/components/one-grid-header-menu/one-grid-header-menu.component.mjs +137 -0
  11. package/esm2022/lib/components/one-grid-pagination/one-grid-pagination.component.mjs +6 -5
  12. package/esm2022/lib/components/one-grid-row-action/one-grid-row-action.component.mjs +4 -4
  13. package/esm2022/lib/components/one-grid-row-drag-handle/one-grid-row-drag-handle.component.mjs +5 -3
  14. package/esm2022/lib/components/one-grid-status/one-grid-status.component.mjs +4 -4
  15. package/esm2022/lib/core/directives/one-cell-input-validator.directive.mjs +3 -3
  16. package/esm2022/lib/core/directives/one-cell-renderer-component.directive.mjs +3 -3
  17. package/esm2022/lib/core/directives/one-cell-text-expand.directive.mjs +3 -3
  18. package/esm2022/lib/core/icons/one-grid-icons.mjs +38 -0
  19. package/esm2022/lib/core/instants/one-grid-api.class.mjs +339 -8
  20. package/esm2022/lib/core/models/one-column-def-types.model.mjs +1 -1
  21. package/esm2022/lib/core/models/one-event-types.model.mjs +1 -1
  22. package/esm2022/lib/core/models/one-filter.model.mjs +1 -1
  23. package/esm2022/lib/core/pipes/aria-sort.pipe.mjs +31 -0
  24. package/esm2022/lib/core/pipes/cell-action-button-enable.pipe.mjs +3 -3
  25. package/esm2022/lib/core/pipes/cell-editable.pipe.mjs +3 -3
  26. package/esm2022/lib/core/pipes/cell-invalid.pipe.mjs +3 -3
  27. package/esm2022/lib/core/pipes/cell-key.pipe.mjs +3 -3
  28. package/esm2022/lib/core/pipes/cell-level-padding.pipe.mjs +3 -3
  29. package/esm2022/lib/core/pipes/cell-selected.pipe.mjs +3 -3
  30. package/esm2022/lib/core/pipes/cell-state-renderer.pipe.mjs +3 -3
  31. package/esm2022/lib/core/pipes/column-sort-state.pipe.mjs +3 -3
  32. package/esm2022/lib/core/pipes/header-checkbox-checked.pipe.mjs +3 -3
  33. package/esm2022/lib/core/pipes/header-checkbox-disabled.pipe.mjs +3 -3
  34. package/esm2022/lib/core/pipes/header-checkbox-indeterminate.pipe.mjs +3 -3
  35. package/esm2022/lib/core/services/og-column.service.mjs +153 -30
  36. package/esm2022/lib/core/services/one-grid-cell.service.mjs +16 -14
  37. package/esm2022/lib/helpers/one-cell.helper.mjs +30 -1
  38. package/esm2022/lib/helpers/one-column-def.helper.mjs +16 -1
  39. package/esm2022/lib/helpers/one-csv.helper.mjs +58 -0
  40. package/esm2022/lib/helpers/one-filter.helper.mjs +11 -1
  41. package/esm2022/lib/helpers/one-row-grouping.helper.mjs +103 -0
  42. package/esm2022/lib/index.mjs +3 -1
  43. package/esm2022/lib/one-grid.module.mjs +24 -114
  44. package/fesm2022/one-grid-core-angular.mjs +2365 -850
  45. package/fesm2022/one-grid-core-angular.mjs.map +1 -1
  46. package/lib/components/one-grid/one-grid.component.d.ts +101 -4
  47. package/lib/components/one-grid-body/one-grid-body.component.d.ts +83 -2
  48. package/lib/components/one-grid-cell-currency/one-grid-cell-currency.component.d.ts +1 -1
  49. package/lib/components/one-grid-cell-group-renderer/one-grid-cell-group-renderer.component.d.ts +1 -1
  50. package/lib/components/one-grid-cell-option-menu/one-grid-cell-option-menu.component.d.ts +1 -1
  51. package/lib/components/one-grid-checkbox/one-grid-checkbox.component.d.ts +1 -1
  52. package/lib/components/one-grid-checkbox-header/one-grid-checkbox-header.component.d.ts +1 -1
  53. package/lib/components/one-grid-header/one-grid-header.component.d.ts +69 -4
  54. package/lib/components/one-grid-header-menu/one-grid-header-menu.component.d.ts +52 -0
  55. package/lib/components/one-grid-pagination/one-grid-pagination.component.d.ts +1 -1
  56. package/lib/components/one-grid-row-action/one-grid-row-action.component.d.ts +1 -1
  57. package/lib/components/one-grid-row-drag-handle/one-grid-row-drag-handle.component.d.ts +1 -1
  58. package/lib/components/one-grid-status/one-grid-status.component.d.ts +1 -1
  59. package/lib/core/directives/one-cell-input-validator.directive.d.ts +1 -1
  60. package/lib/core/directives/one-cell-renderer-component.directive.d.ts +1 -1
  61. package/lib/core/directives/one-cell-text-expand.directive.d.ts +1 -1
  62. package/lib/core/icons/one-grid-icons.d.ts +35 -0
  63. package/lib/core/instants/one-grid-api.class.d.ts +115 -1
  64. package/lib/core/models/one-column-def-types.model.d.ts +77 -2
  65. package/lib/core/models/one-event-types.model.d.ts +19 -0
  66. package/lib/core/models/one-filter.model.d.ts +8 -1
  67. package/lib/core/pipes/aria-sort.pipe.d.ts +15 -0
  68. package/lib/core/pipes/cell-action-button-enable.pipe.d.ts +1 -1
  69. package/lib/core/pipes/cell-editable.pipe.d.ts +1 -1
  70. package/lib/core/pipes/cell-invalid.pipe.d.ts +1 -1
  71. package/lib/core/pipes/cell-key.pipe.d.ts +1 -1
  72. package/lib/core/pipes/cell-level-padding.pipe.d.ts +1 -1
  73. package/lib/core/pipes/cell-selected.pipe.d.ts +1 -1
  74. package/lib/core/pipes/cell-state-renderer.pipe.d.ts +1 -1
  75. package/lib/core/pipes/column-sort-state.pipe.d.ts +1 -1
  76. package/lib/core/pipes/header-checkbox-checked.pipe.d.ts +1 -1
  77. package/lib/core/pipes/header-checkbox-disabled.pipe.d.ts +1 -1
  78. package/lib/core/pipes/header-checkbox-indeterminate.pipe.d.ts +1 -1
  79. package/lib/core/services/og-column.service.d.ts +46 -2
  80. package/lib/core/services/one-grid-cell.service.d.ts +0 -3
  81. package/lib/helpers/one-cell.helper.d.ts +17 -0
  82. package/lib/helpers/one-column-def.helper.d.ts +9 -0
  83. package/lib/helpers/one-csv.helper.d.ts +29 -0
  84. package/lib/helpers/one-row-grouping.helper.d.ts +35 -0
  85. package/lib/index.d.ts +2 -0
  86. package/lib/one-grid.module.d.ts +15 -37
  87. package/package.json +1 -1
  88. package/scss/_one-grid.scss +127 -0
  89. package/esm2022/lib/core/pipes/cell-action-button-visible.pipe.mjs +0 -17
  90. package/esm2022/lib/core/pipes/cell-field-value-empty.pipe.mjs +0 -26
  91. package/esm2022/lib/core/pipes/cell-field-value.pipe.mjs +0 -25
  92. package/esm2022/lib/core/pipes/cell-field.pipe.mjs +0 -20
  93. package/esm2022/lib/core/pipes/cell-number-value.pipe.mjs +0 -19
  94. package/esm2022/lib/core/pipes/cell-state-group-renderer.pipe.mjs +0 -21
  95. package/esm2022/lib/core/pipes/cell-value-getter.pipe.mjs +0 -23
  96. package/lib/core/pipes/cell-action-button-visible.pipe.d.ts +0 -9
  97. package/lib/core/pipes/cell-field-value-empty.pipe.d.ts +0 -7
  98. package/lib/core/pipes/cell-field-value.pipe.d.ts +0 -7
  99. package/lib/core/pipes/cell-field.pipe.d.ts +0 -7
  100. package/lib/core/pipes/cell-number-value.pipe.d.ts +0 -7
  101. package/lib/core/pipes/cell-state-group-renderer.pipe.d.ts +0 -9
  102. package/lib/core/pipes/cell-value-getter.pipe.d.ts +0 -9
@@ -1,31 +1,31 @@
1
1
  import { ChangeDetectionStrategy, Component, EventEmitter, HostListener, Input, Output, ViewChild, ViewChildren } from '@angular/core';
2
2
  import { Subscription } from 'rxjs';
3
+ import { filter, take } from 'rxjs/operators';
3
4
  import { CellEditablePipe } from '../../core/pipes/cell-editable.pipe';
4
5
  import { getCellKey, getFieldValue } from '../../helpers/one-cell.helper';
5
- import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
6
+ import { CdkVirtualScrollViewport, ScrollingModule } from '@angular/cdk/scrolling';
6
7
  import { resolveColumnWidth } from '../../helpers/one-column-def.helper';
8
+ import { NgClass, NgStyle, NgTemplateOutlet } from '@angular/common';
9
+ import { OneGridCheckboxComponent } from '../one-grid-checkbox/one-grid-checkbox.component';
10
+ import { OneGridCellGroupRendererComponent } from '../one-grid-cell-group-renderer/one-grid-cell-group-renderer.component';
11
+ import { OneGridCellOptionMenuComponent } from '../one-grid-cell-option-menu/one-grid-cell-option-menu.component';
12
+ import { OneGridRowActionComponent } from '../one-grid-row-action/one-grid-row-action.component';
13
+ import { OneGridRowDragHandleComponent } from '../one-grid-row-drag-handle/one-grid-row-drag-handle.component';
14
+ import { OneCellInputValidatorDirective } from '../../core/directives/one-cell-input-validator.directive';
15
+ import { OneCellRendererComponentDirective } from '../../core/directives/one-cell-renderer-component.directive';
16
+ import { OneCellTextExpandDirective } from '../../core/directives/one-cell-text-expand.directive';
17
+ import { CellActionButtonEnablePipe } from '../../core/pipes/cell-action-button-enable.pipe';
18
+ import { CellInvalidPipe } from '../../core/pipes/cell-invalid.pipe';
19
+ import { CellKeyPipe } from '../../core/pipes/cell-key.pipe';
20
+ import { CellLevelPaddingPipe } from '../../core/pipes/cell-level-padding.pipe';
21
+ import { CellSelectedPipe } from '../../core/pipes/cell-selected.pipe';
22
+ import { CellStateRendererPipe } from '../../core/pipes/cell-state-renderer.pipe';
7
23
  import * as i0 from "@angular/core";
8
24
  import * as i1 from "../../core/services/og-column.service";
9
25
  import * as i2 from "../../core/services/one-grid-cell.service";
10
26
  import * as i3 from "../../core/services/one-grid-event.service";
11
27
  import * as i4 from "../../core/services/one-grid-row-drag.service";
12
- import * as i5 from "@angular/common";
13
- import * as i6 from "@angular/cdk/scrolling";
14
- import * as i7 from "../one-grid-checkbox/one-grid-checkbox.component";
15
- import * as i8 from "../one-grid-row-action/one-grid-row-action.component";
16
- import * as i9 from "../one-grid-cell-group-renderer/one-grid-cell-group-renderer.component";
17
- import * as i10 from "../../core/directives/one-cell-input-validator.directive";
18
- import * as i11 from "../../core/directives/one-cell-renderer-component.directive";
19
- import * as i12 from "../../core/directives/one-cell-text-expand.directive";
20
- import * as i13 from "../one-grid-cell-option-menu/one-grid-cell-option-menu.component";
21
- import * as i14 from "../one-grid-row-drag-handle/one-grid-row-drag-handle.component";
22
- import * as i15 from "../../core/pipes/cell-editable.pipe";
23
- import * as i16 from "../../core/pipes/cell-invalid.pipe";
24
- import * as i17 from "../../core/pipes/cell-selected.pipe";
25
- import * as i18 from "../../core/pipes/cell-action-button-enable.pipe";
26
- import * as i19 from "../../core/pipes/cell-key.pipe";
27
- import * as i20 from "../../core/pipes/cell-level-padding.pipe";
28
- import * as i21 from "../../core/pipes/cell-state-renderer.pipe";
28
+ import * as i5 from "@angular/cdk/scrolling";
29
29
  export class OneGridBodyComponent {
30
30
  constructor(colService, cellService, eventService, rowDragService, cdr) {
31
31
  this.colService = colService;
@@ -38,6 +38,12 @@ export class OneGridBodyComponent {
38
38
  this.allowedEdit = true;
39
39
  this.enableGroupColumnDefs = false;
40
40
  this.submitted = false;
41
+ /**
42
+ * `'fullRow'`: a double-click opens every editable cell of the row, Enter or
43
+ * focus leaving the row commits them together, Escape closes them all
44
+ * without committing. Default: one cell at a time.
45
+ */
46
+ this.editType = null;
41
47
  this.context = null;
42
48
  /**
43
49
  * Pinned rows are bound only so the component re-renders when they change;
@@ -138,6 +144,22 @@ export class OneGridBodyComponent {
138
144
  * MAX_BUFFER_PX keeps roughly twenty rows of overscan either side instead.
139
145
  */
140
146
  this.MAX_BUFFER_PX = 600;
147
+ // ---------------------------------------------------------------------------
148
+ // Cell navigation
149
+ //
150
+ // The WAI-ARIA grid pattern: the whole grid is one tab stop, and the arrows
151
+ // move a focused cell within it. Before this the only tab stop was the scroll
152
+ // viewport, so a keyboard user could scroll the rows and reach nothing in
153
+ // them — and a screen reader had no cursor to read a cell from.
154
+ //
155
+ // Focus is real DOM focus on a roving tabindex rather than
156
+ // `aria-activedescendant`, because the rows are virtualised: the element a
157
+ // descendant id pointed at would keep being destroyed underneath it.
158
+ // ---------------------------------------------------------------------------
159
+ /** The cell holding the grid's tab stop. Null until something is focused. */
160
+ this.activeCell = null;
161
+ /** The row a shift-extended selection is measured from. */
162
+ this.selectionAnchorRowId = null;
141
163
  /**
142
164
  * Where to paint the drop indicator, in pixels from the top of the body.
143
165
  *
@@ -193,13 +215,20 @@ export class OneGridBodyComponent {
193
215
  this.columnDefs = [...payload.columns];
194
216
  this.cellRenderer = this.columnDefs.some(col => col.cellRendererComponent);
195
217
  this.rowWidth = this.columnDefs.reduce((sum, col) => sum + resolveColumnWidth(col), 0);
218
+ // A column change can alter the width left for flex columns (a hide, a
219
+ // resize, new defs). Re-flexing only dispatches when a width actually
220
+ // changes, so this cannot ping-pong.
221
+ this.applyFlexWidths();
196
222
  this.cdr.markForCheck();
197
223
  }));
198
224
  /**
199
225
  * Listen Row Data Changed Event
200
226
  */
201
- this.subscriptions.add(this.eventService.addEventListener('rowDataChanged', ({ nodes }) => {
202
- this.rowCountChanged.emit(nodes?.length ?? 0);
227
+ this.subscriptions.add(this.eventService.addEventListener('rowDataChanged', ({ nodes: allNodes }) => {
228
+ // The full post-filter count, reported before the page slice is taken,
229
+ // so the host's paging totals see everything.
230
+ this.rowCountChanged.emit(allNodes?.length ?? 0);
231
+ const nodes = this.api.pageNodes(allNodes);
203
232
  setTimeout(() => {
204
233
  this.viewport?.checkViewportSize();
205
234
  this.setVirtualScroll(nodes?.length);
@@ -239,7 +268,7 @@ export class OneGridBodyComponent {
239
268
  * Listen Sort Changed Event
240
269
  */
241
270
  this.subscriptions.add(this.eventService.addEventListener('sortChanged', ({ nodes }) => {
242
- this.nodes = nodes;
271
+ this.nodes = this.api.pageNodes(nodes);
243
272
  // Sorting takes ownership of the order away from the user, so the handles
244
273
  // have to disable in the same frame the rows re-sort.
245
274
  this.refreshRowDragSuppressed();
@@ -253,7 +282,7 @@ export class OneGridBodyComponent {
253
282
  * for a move. A reorder is the same nodes in a different order.
254
283
  */
255
284
  this.subscriptions.add(this.eventService.addEventListener('rowOrderChanged', ({ nodes }) => {
256
- this.nodes = [...nodes];
285
+ this.nodes = this.api.pageNodes([...nodes]);
257
286
  this.cdr.markForCheck();
258
287
  }));
259
288
  /**
@@ -571,13 +600,28 @@ export class OneGridBodyComponent {
571
600
  }
572
601
  let rowNode = this.api.getRowNodeById(node.rowId);
573
602
  if (rowNode) {
574
- rowNode.editing[column.field] = true;
603
+ if (this.editType === 'fullRow') {
604
+ // The whole row edits together, so every cell that would accept its
605
+ // own double-click opens now. The clicked one still takes focus below.
606
+ for (const col of this.columnDefs) {
607
+ if (!col.field)
608
+ continue;
609
+ if (this.cellEditablePipe.transform(rowNode.cellStates, col, rowNode, this.cellService.editableFn, this.cellService.updatableFn, this.allowedEdit)) {
610
+ rowNode.editing[col.field] = true;
611
+ }
612
+ }
613
+ }
614
+ else {
615
+ rowNode.editing[column.field] = true;
616
+ }
575
617
  setTimeout(() => {
576
- const input = document.querySelector(`[data-cell-id="${getCellKey(node.rowId, column.field)}"] input`);
618
+ const input = document.querySelector(`[data-cell-id="${getCellKey(node.rowId, column.field)}"] input, [data-cell-id="${getCellKey(node.rowId, column.field)}"] select`);
577
619
  if (input) {
578
620
  input.focus();
579
621
  const value = input.value;
580
- if (value && ["text"].includes(input.type)) {
622
+ // A select reports type 'select-one', so only a text input gets its
623
+ // caret placed.
624
+ if (value && ["text"].includes(input.type) && 'setSelectionRange' in input) {
581
625
  input.setSelectionRange(value.length, value.length);
582
626
  }
583
627
  }
@@ -588,18 +632,71 @@ export class OneGridBodyComponent {
588
632
  * Save Cell Edit Mode
589
633
  */
590
634
  stopEdit(node, column, event) {
635
+ if (this.editType === 'fullRow') {
636
+ this.stopRowEditFromEvent(node, event);
637
+ return;
638
+ }
591
639
  let rowNode = this.api.getRowNodeById(node.rowId);
592
- if (rowNode) {
640
+ // The editing guard makes a second commit for one edit a no-op: a select
641
+ // commits on (change), which closes the editor, and the (blur) that can
642
+ // follow must not commit again.
643
+ if (rowNode && rowNode.editing[column.field]) {
593
644
  event.preventDefault();
594
645
  event.stopPropagation();
595
646
  const value = event.target.value ?? '';
647
+ const oldValue = rowNode.data[column.field];
596
648
  this.setCellValueByRowId(node.rowId, column, value);
597
- rowNode.cellStates = this.cellService.generateCellStates(rowNode);
598
- rowNode.editing[column.field] = false;
599
- this.eventService.dispatchEvent('cellStateChanged', {
600
- data: rowNode.data,
649
+ this.finishEdit(rowNode, column, oldValue);
650
+ }
651
+ }
652
+ /**
653
+ * Save a `select` editor's choice.
654
+ *
655
+ * Separate from `stopEdit` because the value is not the element's string:
656
+ * the chosen index maps back into `selectOptions`, so the committed value
657
+ * keeps whatever type the option declared.
658
+ */
659
+ stopEditSelect(node, column, event) {
660
+ if (this.editType === 'fullRow') {
661
+ // (change) is not a commit in full-row mode — the choice sits in the
662
+ // select until the row commits and reads every editor at once. Only a
663
+ // blur that actually leaves the row closes it.
664
+ if (event.type === 'blur')
665
+ this.stopRowEditFromEvent(node, event);
666
+ return;
667
+ }
668
+ let rowNode = this.api.getRowNodeById(node.rowId);
669
+ if (rowNode && rowNode.editing[column.field]) {
670
+ event.stopPropagation();
671
+ const options = column?.cellRendererParams?.selectOptions ?? [];
672
+ const option = options[event.target.selectedIndex];
673
+ if (!option)
674
+ return;
675
+ const oldValue = rowNode.data[column.field];
676
+ rowNode.data[column.field] = option.value;
677
+ this.finishEdit(rowNode, column, oldValue);
678
+ }
679
+ }
680
+ /** Close the editor and announce the commit. Shared by both editor kinds. */
681
+ finishEdit(rowNode, column, oldValue) {
682
+ const newValue = rowNode.data[column.field];
683
+ rowNode.cellStates = this.cellService.generateCellStates(rowNode);
684
+ rowNode.editing[column.field] = false;
685
+ this.eventService.dispatchEvent('cellStateChanged', {
686
+ data: rowNode.data,
687
+ node: rowNode,
688
+ column: column
689
+ });
690
+ // Compared after normalisation ('' -> null, number coercion), so a blur
691
+ // that leaves the value as it was does not announce an edit.
692
+ if (newValue !== oldValue) {
693
+ this.eventService.dispatchEvent('cellValueChanged', {
601
694
  node: rowNode,
602
- column: column
695
+ data: rowNode.data,
696
+ column: column,
697
+ field: column.field,
698
+ oldValue,
699
+ newValue,
603
700
  });
604
701
  }
605
702
  }
@@ -609,9 +706,63 @@ export class OneGridBodyComponent {
609
706
  cancelEdit(node, column) {
610
707
  let rowNode = this.api.getRowNodeById(node.rowId);
611
708
  if (rowNode) {
709
+ if (this.editType === 'fullRow') {
710
+ // Escape abandons the whole row: every editor closes, nothing commits.
711
+ Object.keys(rowNode.editing).forEach(field => rowNode.editing[field] = false);
712
+ return;
713
+ }
612
714
  rowNode.editing[column.field] = false;
613
715
  }
614
716
  }
717
+ /**
718
+ * Full-row commit, routed from any one editor's Enter or blur.
719
+ *
720
+ * A blur that lands on another editor in the same row is the user tabbing
721
+ * between fields, not leaving the row — the editors stay open and their
722
+ * typed values stay in the DOM until the row commits.
723
+ */
724
+ stopRowEditFromEvent(node, event) {
725
+ if (event.type === 'blur') {
726
+ const next = event.relatedTarget;
727
+ if (next?.matches?.('input.one-cell-input, select.one-cell-input')
728
+ && next.closest?.(`[data-cell-id^="${node.rowId}--"]`)) {
729
+ return;
730
+ }
731
+ }
732
+ event.preventDefault?.();
733
+ event.stopPropagation?.();
734
+ this.stopRowEdit(node);
735
+ }
736
+ /** Commit every open editor of one row, reading each from the DOM. */
737
+ stopRowEdit(node) {
738
+ const rowNode = this.api.getRowNodeById(node.rowId);
739
+ if (!rowNode)
740
+ return;
741
+ for (const column of this.columnDefs) {
742
+ const field = column.field;
743
+ if (!field || !rowNode.editing[field])
744
+ continue;
745
+ const key = getCellKey(rowNode.rowId, field);
746
+ const editor = document.querySelector(`[data-cell-id="${key}"] input, [data-cell-id="${key}"] select`);
747
+ const oldValue = rowNode.data[field];
748
+ if (editor?.tagName === 'SELECT') {
749
+ const options = column.cellRendererParams?.selectOptions ?? [];
750
+ const option = options[editor.selectedIndex];
751
+ if (option)
752
+ rowNode.data[field] = option.value;
753
+ }
754
+ else if (editor) {
755
+ const raw = editor.value ?? '';
756
+ rowNode.data[field] = raw === ''
757
+ ? null
758
+ : column.cellRendererParams?.inputType === 'number' ? Number(raw) : raw;
759
+ }
760
+ // finishEdit closes the editor, refreshes the cell state and raises
761
+ // cellValueChanged when the value moved — one event per changed cell,
762
+ // the same contract as single-cell editing.
763
+ this.finishEdit(rowNode, column, oldValue);
764
+ }
765
+ }
615
766
  /**
616
767
  * Set Cell Value
617
768
  */
@@ -657,6 +808,24 @@ export class OneGridBodyComponent {
657
808
  },
658
809
  });
659
810
  this.refreshRowDragSuppressed();
811
+ // The CDK inserts its own content wrapper between the viewport and the
812
+ // rows. It has no template of ours to annotate, and left generic it breaks
813
+ // the `grid > row` ownership the roles depend on.
814
+ const wrapper = element.querySelector('.cdk-virtual-scroll-content-wrapper');
815
+ wrapper?.setAttribute('role', 'presentation');
816
+ // Flex columns size against this viewport, now and whenever it resizes.
817
+ // applyFlexWidths is a no-op without flex columns and dispatches only on a
818
+ // real change, so grids that never use flex pay nothing here.
819
+ this.applyFlexWidths();
820
+ if (typeof ResizeObserver !== 'undefined') {
821
+ this.flexResizeObserver = new ResizeObserver(() => this.applyFlexWidths());
822
+ this.flexResizeObserver.observe(element);
823
+ }
824
+ }
825
+ applyFlexWidths() {
826
+ const width = this.viewport?.elementRef?.nativeElement?.clientWidth ?? 0;
827
+ if (width > 0)
828
+ this.api.applyFlexWidths(width);
660
829
  }
661
830
  /**
662
831
  * The params every per-cell callback receives.
@@ -680,6 +849,226 @@ export class OneGridBodyComponent {
680
849
  rendererParams(node, column) {
681
850
  return { ...(column?.cellRendererParams ?? {}), ...this.cellParams(node, column) };
682
851
  }
852
+ /**
853
+ * `aria-rowindex` is 1-based over the whole grid, not over what is rendered.
854
+ *
855
+ * That is the point of it: the body virtualises, so the DOM holds a sliding
856
+ * window of rows and the index is how a screen reader knows where the window
857
+ * sits. Row 1 is the header, then any pinned-top rows, then the data.
858
+ */
859
+ dataRowAriaIndex(node) {
860
+ return 2 + this.pinnedTopNodes.length + node.rowIndex;
861
+ }
862
+ /** Pinned rows bracket the data: top ones follow the header, bottom ones end the grid. */
863
+ pinnedRowAriaIndex(node, side) {
864
+ const index = (side === 'top' ? this.pinnedTopNodes : this.pinnedBottomNodes).indexOf(node);
865
+ return side === 'top'
866
+ ? 2 + index
867
+ : 2 + this.pinnedTopNodes.length + this.nodes.length + index;
868
+ }
869
+ /**
870
+ * Whether rows can be selected at all.
871
+ *
872
+ * `aria-selected="false"` on every row of a grid nobody can select announces
873
+ * a selection affordance that does not exist, so the attribute is omitted
874
+ * rather than set false.
875
+ */
876
+ get rowSelectionEnabled() {
877
+ return !!this.api?.rowSelection;
878
+ }
879
+ isActiveCell(node, column) {
880
+ if (this.activeCell) {
881
+ return this.activeCell.rowId === node.rowId && this.activeCell.field === column.field;
882
+ }
883
+ // Nothing focused yet, so the first cell holds the tab stop. Without this
884
+ // fallback a grid nobody has clicked has *no* tabbable cell, and a keyboard
885
+ // user cannot get into it at all — the roving tabindex has to start
886
+ // somewhere.
887
+ return node === this.nodes[0] && column === this.navigableColumns()[0];
888
+ }
889
+ /**
890
+ * Adopt whatever the user focused, however they got there — click, tab, or
891
+ * the arrow keys below. Keeping this in one place is what stops the roving
892
+ * tabindex drifting away from the element that actually has focus.
893
+ */
894
+ onCellFocus(node, column) {
895
+ if (this.isActiveCell(node, column))
896
+ return;
897
+ this.activeCell = { rowId: node.rowId, field: column.field };
898
+ this.cdr.markForCheck();
899
+ }
900
+ onGridKeydown(event) {
901
+ // Undo/redo of committed edits, anywhere in the grid except inside an
902
+ // open editor — a text input's Ctrl+Z is the browser's, and it operates
903
+ // on the uncommitted text.
904
+ if ((event.ctrlKey || event.metaKey) && ['z', 'y'].includes(event.key.toLowerCase())) {
905
+ const tag = event.target?.tagName?.toLowerCase();
906
+ if (tag === 'input' || tag === 'select' || tag === 'textarea')
907
+ return;
908
+ event.preventDefault();
909
+ const redo = event.key.toLowerCase() === 'y' || event.shiftKey;
910
+ const applied = redo ? this.api.redoCellEditing() : this.api.undoCellEditing();
911
+ if (applied)
912
+ this.cdr.markForCheck();
913
+ return;
914
+ }
915
+ const columns = this.navigableColumns();
916
+ if (!this.nodes.length || !columns.length)
917
+ return;
918
+ // Navigate only when a cell itself holds focus. Anything focusable *inside*
919
+ // a cell owns its own keys — a text editor's caret, the row drag handle's
920
+ // reorder keys, the option menu's arrows — and all of them bubble to here.
921
+ // Checking the target rather than blocklisting tag names is what keeps this
922
+ // correct as more controls are added to cells.
923
+ const target = event.target;
924
+ if (!target?.matches?.('[role="gridcell"]'))
925
+ return;
926
+ const current = this.activeCellPosition(columns);
927
+ let row = current.row;
928
+ let col = current.col;
929
+ switch (event.key) {
930
+ case 'ArrowDown':
931
+ row += 1;
932
+ break;
933
+ case 'ArrowUp':
934
+ row -= 1;
935
+ break;
936
+ case 'ArrowRight':
937
+ col += 1;
938
+ break;
939
+ case 'ArrowLeft':
940
+ col -= 1;
941
+ break;
942
+ // Selection. Space is the grid pattern's toggle, and it has to be caught
943
+ // here or the browser scrolls the page with it.
944
+ case ' ': {
945
+ const node = this.nodes[current.row];
946
+ if (node) {
947
+ event.preventDefault();
948
+ this.toggleRowSelection(node);
949
+ }
950
+ return;
951
+ }
952
+ case 'a':
953
+ case 'A':
954
+ if (!event.ctrlKey && !event.metaKey)
955
+ return;
956
+ event.preventDefault();
957
+ this.api.selectAll();
958
+ this.cdr.markForCheck();
959
+ return;
960
+ case 'Home':
961
+ col = 0;
962
+ if (event.ctrlKey || event.metaKey)
963
+ row = 0;
964
+ break;
965
+ case 'End':
966
+ col = columns.length - 1;
967
+ if (event.ctrlKey || event.metaKey)
968
+ row = this.nodes.length - 1;
969
+ break;
970
+ // A page is what the viewport can show, which is the only definition that
971
+ // matches what the user sees move.
972
+ case 'PageDown':
973
+ row += this.rowsPerPage();
974
+ break;
975
+ case 'PageUp':
976
+ row -= this.rowsPerPage();
977
+ break;
978
+ case 'Enter':
979
+ case 'F2': {
980
+ const node = this.nodes[current.row];
981
+ const column = columns[current.col];
982
+ if (node && column) {
983
+ event.preventDefault();
984
+ this.startEdit({ target: event.target }, node, column);
985
+ }
986
+ return;
987
+ }
988
+ default: return;
989
+ }
990
+ event.preventDefault();
991
+ const targetRow = Math.min(Math.max(row, 0), this.nodes.length - 1);
992
+ this.focusCell(targetRow, Math.min(Math.max(col, 0), columns.length - 1));
993
+ // Shift with a vertical move extends the selection, anchored where the
994
+ // extension began — the same gesture a file list uses.
995
+ if (event.shiftKey && targetRow !== current.row) {
996
+ this.extendSelectionTo(current.row, targetRow);
997
+ }
998
+ }
999
+ toggleRowSelection(node) {
1000
+ if (!this.api.toggleRowSelection(node.rowId, !node.selected))
1001
+ return;
1002
+ // Where a subsequent shift-extension counts from.
1003
+ this.selectionAnchorRowId = node.rowId;
1004
+ this.cdr.markForCheck();
1005
+ }
1006
+ extendSelectionTo(fromRow, toRow) {
1007
+ const target = this.nodes[toRow];
1008
+ if (!target)
1009
+ return;
1010
+ // With nothing selected yet the row the extension started on becomes the
1011
+ // anchor, so shift+arrow selects both ends rather than only the far one.
1012
+ const anchor = this.selectionAnchorRowId ?? this.nodes[fromRow]?.rowId;
1013
+ if (!anchor)
1014
+ return;
1015
+ this.selectionAnchorRowId = anchor;
1016
+ this.api.selectRowRange(anchor, target.rowId);
1017
+ this.cdr.markForCheck();
1018
+ }
1019
+ /**
1020
+ * Columns a cell cursor can land on.
1021
+ *
1022
+ * A column with no field renders no cell state and is keyed by field, so it
1023
+ * cannot be addressed — an action-only column is a legitimate example.
1024
+ */
1025
+ navigableColumns() {
1026
+ return this.columnDefs.filter(column => !!column?.field);
1027
+ }
1028
+ activeCellPosition(columns) {
1029
+ if (!this.activeCell)
1030
+ return { row: 0, col: 0 };
1031
+ const row = this.nodes.findIndex(node => node.rowId === this.activeCell.rowId);
1032
+ const col = columns.findIndex(column => column.field === this.activeCell.field);
1033
+ return { row: row < 0 ? 0 : row, col: col < 0 ? 0 : col };
1034
+ }
1035
+ rowsPerPage() {
1036
+ const height = this.viewport?.elementRef?.nativeElement?.clientHeight ?? 0;
1037
+ return Math.max(1, Math.floor(height / this.itemSize));
1038
+ }
1039
+ /**
1040
+ * Move the cursor, scrolling the row into view first when it is outside the
1041
+ * rendered window.
1042
+ *
1043
+ * The scroll is the reason focusing is deferred: a virtualised row that is
1044
+ * not on screen has no element to focus until the viewport has rendered it.
1045
+ */
1046
+ focusCell(rowIndex, colIndex) {
1047
+ const node = this.nodes[rowIndex];
1048
+ const column = this.navigableColumns()[colIndex];
1049
+ if (!node || !column)
1050
+ return;
1051
+ this.activeCell = { rowId: node.rowId, field: column.field };
1052
+ this.cdr.markForCheck();
1053
+ const range = this.viewport?.getRenderedRange();
1054
+ const rendered = range && rowIndex >= range.start && rowIndex < range.end;
1055
+ if (rendered) {
1056
+ setTimeout(() => this.focusCellElement(node, column));
1057
+ return;
1058
+ }
1059
+ this.viewport?.scrollToIndex(rowIndex);
1060
+ // Scrolling is not enough: the CDK renders on its own schedule, so the row
1061
+ // has no element to focus until it has. Waiting for the rendered range to
1062
+ // actually contain the row is the only reliable signal — a fixed delay
1063
+ // races the viewport and silently drops focus when it loses.
1064
+ this.subscriptions.add(this.viewport?.renderedRangeStream
1065
+ .pipe(filter(next => rowIndex >= next.start && rowIndex < next.end), take(1))
1066
+ .subscribe(() => setTimeout(() => this.focusCellElement(node, column))));
1067
+ }
1068
+ focusCellElement(node, column) {
1069
+ const key = getCellKey(node.rowId, column.field);
1070
+ this.bodyRef?.nativeElement?.querySelector(`[data-cell-id="${key}"]`)?.focus();
1071
+ }
683
1072
  /** Is this the row currently being moved? */
684
1073
  isRowDragging(node) {
685
1074
  return this.dragState?.rowId === node.rowId;
@@ -705,14 +1094,35 @@ export class OneGridBodyComponent {
705
1094
  this.cdr.markForCheck();
706
1095
  }
707
1096
  ngOnDestroy() {
1097
+ this.flexResizeObserver?.disconnect();
708
1098
  this.subscriptions.unsubscribe();
709
1099
  }
710
1100
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: OneGridBodyComponent, deps: [{ token: i1.OgColumnService }, { token: i2.OneGridCellService }, { token: i3.OneGridEventService }, { token: i4.OneGridRowDragService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
711
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: OneGridBodyComponent, selector: "one-grid-body", inputs: { rowData: "rowData", rowNumber: "rowNumber", api: "api", pagination: "pagination", allowedEdit: "allowedEdit", enableGroupColumnDefs: "enableGroupColumnDefs", submitted: "submitted", context: "context", getRowId: "getRowId", gridCopy$: "gridCopy$", pinnedTopRowData: "pinnedTopRowData", pinnedBottomRowData: "pinnedBottomRowData", gridType: "gridType", masterDetail: "masterDetail", masterNode: "masterNode", detailRowMaxHeight: "detailRowMaxHeight", detailCellRendererParams: "detailCellRendererParams", detailGridTemplate: "detailGridTemplate", detailRendererComponent: "detailRendererComponent", treeData: "treeData", treeDataChildrenField: "treeDataChildrenField", autoGroupColumnDef: "autoGroupColumnDef", groupDefaultExpanded: "groupDefaultExpanded" }, outputs: { onRowGotoDetail: "onRowGotoDetail", onRowAddNew: "onRowAddNew", onRowView: "onRowView", onRowCopy: "onRowCopy", onRowLocation: "onRowLocation", onRowDocument: "onRowDocument", onRowDelete: "onRowDelete", onRowGotoList: "onRowGotoList", onRowEdit: "onRowEdit", onRowPrint: "onRowPrint", onRowHistory: "onRowHistory", onRowOption: "onRowOption", onRowLanguage: "onRowLanguage", onRowCellOption: "onRowCellOption", onRowSelection: "onRowSelection", onShiftDoubleClick: "onShiftDoubleClick", rowCountChanged: "rowCountChanged", expansionChanged: "expansionChanged", bodyScroll: "bodyScroll", cellOptionSelect: "cellOptionSelect", rowDragEnd: "rowDragEnd" }, host: { listeners: { "document:click": "onDocumentClick($event)", "document:mouseup": "onGlobalMouseUp()" } }, viewQueries: [{ propertyName: "bodyRef", first: true, predicate: ["bodyRef"], descendants: true, static: true }, { propertyName: "viewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true }, { propertyName: "pinnedViewports", predicate: ["pinnedViewport"], descendants: true }], ngImport: i0, template: "<div #bodyRef class=\"one-grid-body\">\n\n <!-- Pinned rows live outside the scroll viewport so they never scroll\n vertically, and mirror its scrollLeft so the columns stay aligned. -->\n @if (pinnedTopNodes.length) {\n <div #pinnedViewport class=\"one-pinned-rows one-pinned-rows-top\">\n <ng-container [ngTemplateOutlet]=\"pinnedRows\" [ngTemplateOutletContext]=\"{ nodes: pinnedTopNodes }\"></ng-container>\n </div>\n }\n\n <!-- tabindex makes the scroll container reachable, so a keyboard user can\n scroll the rows with the arrow keys, Page Up/Down and Home/End. Without\n it the body is scrollable by pointer only (WCAG 2.1.1). -->\n <cdk-virtual-scroll-viewport\n class=\"one-grid-body-viewport\"\n tabindex=\"0\"\n [itemSize]=\"itemSize\"\n [minBufferPx]=\"minBufferPx\"\n [maxBufferPx]=\"maxBufferPx\"\n (scroll)=\"onBodyScroll($event)\">\n\n <ng-container *cdkVirtualFor=\"let node of nodes; trackBy: trackByRowId;\">\n \n <div class=\"one-row\"\n [attr.data-row-id]=\"node.rowId\"\n [class.one-row-selected]=\"node.selected\"\n [class.one-row-dragging]=\"isRowDragging(node)\">\n @for (col of columnDefs; track col.field;) {\n <ng-container [ngTemplateOutlet]=\"cellTemplate\" [ngTemplateOutletContext]=\"{ node, rowIndex: node.rowIndex, column: col }\"></ng-container>\n }\n </div>\n\n <!-- Custom Detail Component -->\n @if(node.leaf && node.detailActive && node?.detailRendererComponent) {\n <ng-container\n oneCellRendererComponent\n [cellRendererComponent]=\"node?.detailRendererComponent\"\n [params]=\"{ data: node.data, rowIndex: node.rowIndex, node: node, context: context }\">\n </ng-container>\n }\n\n <!-- Master Detail Grid (template provided by the parent one-grid to avoid a compile-time import cycle) -->\n @if (masterDetail && node.expanded && node?.detailRowData) {\n <div class=\"one-row-detail-container\" [attr.data-row-id]=\"node.rowId + '-detail'\">\n <ng-container\n [ngTemplateOutlet]=\"detailGridTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: node, node: node }\">\n </ng-container>\n </div>\n }\n </ng-container>\n @if (!nodes?.length) {\n <div style=\"width: max-content; border-top: 1px solid transparent;\">\n <div [style.width.px]=\"rowWidth\"></div>\n </div>\n }\n </cdk-virtual-scroll-viewport>\n\n <!-- Drop indicator.\n A line at the insertion point rather than a gap opened between rows:\n the viewport is virtualised at a fixed itemSize, so shifting rows apart\n would desynchronise the scroller from its own geometry. It is also the\n clearer signal \u2014 the row lands exactly where the line is.\n Positioned against the body, with the viewport's scroll subtracted, so\n it stays put while the content moves under it during auto-scroll. -->\n @if (dropIndicatorTop !== null) {\n <div class=\"one-row-drop-indicator\" aria-hidden=\"true\"\n [style.top.px]=\"dropIndicatorTop\"\n [style.width.px]=\"dropIndicatorWidth\"></div>\n }\n\n <!-- Keyboard reordering has no drag image to watch, so it narrates instead.\n Assertive because the message is the only feedback that the row moved. -->\n <div class=\"one-grid-visually-hidden\" role=\"status\" aria-live=\"assertive\" aria-atomic=\"true\">{{ dragAnnouncement }}</div>\n @if (!nodes?.length) {\n <span class=\"one-grid-empty-message\" style=\"position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);\">No Rows to Show</span>\n }\n\n @if (pinnedBottomNodes.length) {\n <div #pinnedViewport class=\"one-pinned-rows one-pinned-rows-bottom\">\n <ng-container [ngTemplateOutlet]=\"pinnedRows\" [ngTemplateOutletContext]=\"{ nodes: pinnedBottomNodes }\"></ng-container>\n </div>\n }\n</div>\n\n<!-- Pinned rows are display-only: they render exactly what a data cell renders,\n but carry none of its interactions. A totals row should not open an editor\n on double-click or start a range selection on drag. -->\n<ng-template #pinnedRows let-nodes=\"nodes\">\n @for (node of nodes; track node.rowId) {\n <div class=\"one-row one-row-pinned\" [attr.data-row-id]=\"node.rowId\">\n @for (column of columnDefs; track column.field) {\n <div\n class=\"one-column\"\n [attr.data-cell-id]=\"node.rowId | cellKey:column.field\"\n [class.one-column-pinned-left]=\"column.pinned === 'left'\"\n [class.one-column-pinned-right]=\"column.pinned === 'right'\"\n [class.one-column-pinned-edge]=\"column._pinnedEdge\"\n [style.left.px]=\"column.pinned === 'left' ? column._pinnedOffset : null\"\n [style.right.px]=\"column.pinned === 'right' ? column._pinnedOffset : null\"\n [style.width.px]=\"column?.width\"\n [style.min-width.px]=\"column?.minWidth\"\n [style.max-width.px]=\"column?.maxWidth\">\n\n @if (column?.cellRendererComponent) {\n <ng-container\n oneCellRendererComponent\n [cellRendererComponent]=\"column?.cellRendererComponent\"\n [params]=\"rendererParams(node, column)\">\n </ng-container>\n }\n @else if (column?.cellRenderer) {\n <div\n [ngStyle]=\"{ width: column.width + 'px', position: 'relative' }\"\n [innerHTML]=\"node.cellStates | cellStateRenderer:column.field\">\n </div>\n }\n @else {\n <div class=\"one-cell\"\n [class.align-content-left]=\"column?.alignContent === 'left'\"\n [class.align-content-center]=\"column?.alignContent === 'center'\"\n [class.align-content-right]=\"column?.alignContent === 'right'\"\n [ngClass]=\"colService.resolveCellClass(column, cellParams(node, column))\"\n [ngStyle]=\"colService.resolveCellStyle(column, cellParams(node, column))\">\n <div class=\"one-cell-text\">{{ (node.cellStates | cellStateRenderer:column.field) }}</div>\n </div>\n }\n </div>\n }\n </div>\n }\n</ng-template>\n\n<!-- Master Column Template -->\n<ng-template #cellTemplate let-node=\"node\" let-rowIndex=\"rowIndex\" let-column=\"column\">\n <div\n class=\"one-column\"\n [attr.data-cell-id]=\"node.rowId | cellKey:column.field\"\n [class.one-column-pinned-left]=\"column.pinned === 'left'\"\n [class.one-column-pinned-right]=\"column.pinned === 'right'\"\n [class.one-column-pinned-edge]=\"column._pinnedEdge\"\n [style.left.px]=\"column.pinned === 'left' ? column._pinnedOffset : null\"\n [style.right.px]=\"column.pinned === 'right' ? column._pinnedOffset : null\"\n [style.width.px]=\"column?.width\"\n [style.min-width.px]=\"column?.minWidth\"\n [style.max-width.px]=\"column?.maxWidth\"\n [class.one-column-border-top]=\"masterDetail && nodes?.length > 0 && nodes[node.rowIndex - 1]?.expanded\"\n [class.one-cell-selected]=\"selectedCells | cellSelected:node.rowId:column.field\"\n [class.one-cell-invalid]=\"node.cellStates | cellInvalid:node.data[column.field]:column:node:allowedEdit:submitted\"\n (dblclick)=\"startEdit($event, node, column)\"\n (mousedown)=\"startSelection(node.rowId, column.field)\"\n (mouseenter)=\"extendSelection(node.rowId, column.field)\"\n (mouseup)=\"endSelection()\">\n\n <!-- One Grid Cell Option -->\n @if (node.cellOptions[column.field]) {\n <one-grid-cell-option-menu\n #contextOptionMenuRef\n [node]=\"node\"\n [column]=\"column\"\n [options]=\"column.cellOptionMenu\"\n (cellOptionMenuSelect)=\"cellOptionMenuSelected($event)\"\n (cellOptionMenuClose)=\"cellOptionMenuClosed()\"/>\n }\n\n <!-- Grid Cell Template -->\n @if(column?.cellRendererComponent) {\n <ng-container\n oneCellRendererComponent\n [cellRendererComponent]=\"column?.cellRendererComponent\"\n [params]=\"rendererParams(node, column)\">\n </ng-container>\n }\n @else if (node.editing[column.field]) {\n <!-- Cell Editing Input -->\n <input class=\"one-cell-input\"\n name=\"{{ node.rowId + '' + column.field }}\"\n oneCellInputValidator\n [validationType]=\"column?.cellRendererParams?.inputType === 'number' ? 'number' : 'none'\"\n [placeholder]=\"column?.cellRendererParams?.placeholder\"\n [type]=\"column?.cellRendererParams?.inputType === 'number' ? 'text' : column?.cellRendererParams?.inputType\"\n [value]=\"node?.data[column?.field]\"\n [maxLength]=\"250\"\n (blur)=\"stopEdit(node, column, $event)\"\n (keydown.enter)=\"stopEdit(node, column, $event)\"\n (keydown.esc)=\"cancelEdit(node, column)\"\n />\n }\n @else if (column?.cellRenderer) {\n <div\n [ngStyle]=\"{ width: column.width + 'px' , position: 'relative' }\"\n [innerHTML]=\"node.cellStates | cellStateRenderer:column.field\"\n [class.editable-active]=\"node.cellStates | cellEditable:column:node:cellService.editableFn:cellService.updatableFn:allowedEdit\">\n </div>\n }\n @else {\n <div class=\"one-cell\"\n [class.align-content-left]=\"column?.alignContent === 'left'\"\n [class.align-content-center]=\"column?.alignContent === 'center'\"\n [class.align-content-right]=\"column?.alignContent === 'right'\"\n [ngClass]=\"colService.resolveCellClass(column, cellParams(node, column))\"\n [ngStyle]=\"colService.resolveCellStyle(column, cellParams(node, column))\"\n [style.padding-left.px]=\"column.autoGroupField && node.level | cellLevelPadding:24\"\n [class.one-cell-allowed-edit-active]=\"node.cellStates | cellEditable:column:node:cellService.editableFn:cellService.updatableFn:allowedEdit\">\n\n <!-- Row Drag Handle -->\n @if (cellService.rowDragFn(column, node)) {\n <one-grid-row-drag-handle\n [node]=\"node\"\n [suppressedReason]=\"rowDragSuppressed\"\n (dragEnd)=\"onRowDragEnd($event)\"\n />\n }\n\n <!-- Cell Checkbox Selection -->\n @if (column?.checkboxSelection) {\n <one-grid-checkbox\n [node]=\"node\"\n [allowedEdit]=\"allowedEdit\"\n [api]=\"api\"\n (onRowSelection)=\"invokeRowActionSelection($event)\"\n />\n }\n\n <!-- Expand & Collapse Icon -->\n @if (((node?.group || detailRendererComponent) && column?.autoGroupField) || (masterDetail && node?.expandable && gridType === 'master' && column?.masterGroupField)) {\n <one-grid-cell-group-renderer\n [node]=\"node\"\n [masterDetail]=\"masterDetail\"\n [detailCellRendererParams]=\"detailCellRendererParams\"\n [detailRendererComponent]=\"detailRendererComponent\"\n (expansionChanged)=\"invokeExpansionChangedClick($event)\"\n />\n }\n\n @if(column?.cellRendererComponent) {\n <ng-container\n oneCellRendererComponent\n [cellRendererComponent]=\"column?.cellRendererComponent\"\n [params]=\"rendererParams(node, column)\">\n </ng-container>\n }\n @else {\n <!-- Cell Value OR Placeholder -->\n <div oneCellTextExpand class=\"one-cell-text\" [class.one-cell-placeholder]=\"node.cellStates[column.field]?.type === 'placeholder'\">\n {{ (node.cellStates | cellStateRenderer:column.field) }}\n </div>\n }\n\n <!-- Cell Action Buttons -->\n @if (column.cellRendererParams | cellActionButtonEnable) {\n <one-grid-row-action\n [ngStyle]=\"{ marginLeft: 'auto' }\"\n [column]=\"column\"\n [node]=\"node\"\n [allowedEdit]=\"allowedEdit\"\n [masterNode]=\"masterNode\"\n [masterDetail]=\"masterDetail\"\n [gridType]=\"gridType\"\n [context]=\"context\"\n [cellRendererParams]=\"column?.cellRendererParams\"\n (onRowGotoDetail)=\"invokeRowActionGotoDetail($event)\"\n (onRowAddNew)=\"invokeRowActionAddNew($event)\"\n (onRowView)=\"invokeRowActionView($event)\"\n (onRowLocation)=\"invokeRowActionLocation($event)\"\n (onRowDocument)=\"invokeRowActionDocument($event)\"\n (onRowCopy)=\"invokeRowActionCopy($event)\"\n (onRowDelete)=\"invokeRowActionDelete($event)\"\n (onRowGotoList)=\"invokeRowActionGotoList($event)\"\n (onRowEdit)=\"invokeRowActionEdit($event)\"\n (onRowPrint)=\"invokeRowActionPrint($event)\"\n (onRowHistory)=\"invokeRowActionHistory($event)\"\n (onRowOption)=\"invokeRowActionOption($event)\"\n (onRowLanguage)=\"invokeRowActionLanguage($event)\"\n (onRowCellOption)=\"invokeRowActionCellOption($event)\"\n />\n }\n </div>\n }\n </div>\n</ng-template>\n", styles: [""], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i6.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i6.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i6.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: i7.OneGridCheckboxComponent, selector: "one-grid-checkbox", inputs: ["node", "allowedEdit", "api"], outputs: ["onRowSelection"] }, { kind: "component", type: i8.OneGridRowActionComponent, selector: "one-grid-row-action", inputs: ["column", "node", "allowedEdit", "masterDetail", "masterNode", "cellRendererParams", "gridType", "context"], outputs: ["onRowGotoDetail", "onRowAddNew", "onRowView", "onRowLocation", "onRowDocument", "onRowCopy", "onRowDelete", "onRowGotoList", "onRowEdit", "onRowPrint", "onRowHistory", "onRowOption", "onRowLanguage", "onRowCellOption"] }, { kind: "component", type: i9.OneGridCellGroupRendererComponent, selector: "one-grid-cell-group-renderer", inputs: ["node", "masterDetail", "detailCellRendererParams", "detailRendererComponent"], outputs: ["expansionChanged"] }, { kind: "directive", type: i10.OneCellInputValidatorDirective, selector: "[oneCellInputValidator]", inputs: ["validationType", "regex"] }, { kind: "directive", type: i11.OneCellRendererComponentDirective, selector: "[oneCellRendererComponent]", inputs: ["cellRendererComponent", "params"] }, { kind: "directive", type: i12.OneCellTextExpandDirective, selector: "[oneCellTextExpand]" }, { kind: "component", type: i13.OneGridCellOptionMenuComponent, selector: "one-grid-cell-option-menu", inputs: ["column", "node", "options"], outputs: ["cellOptionMenuSelect", "cellOptionMenuClose"] }, { kind: "component", type: i14.OneGridRowDragHandleComponent, selector: "one-grid-row-drag-handle", inputs: ["node", "suppressedReason"], outputs: ["dragEnd"] }, { kind: "pipe", type: i15.CellEditablePipe, name: "cellEditable" }, { kind: "pipe", type: i16.CellInvalidPipe, name: "cellInvalid" }, { kind: "pipe", type: i17.CellSelectedPipe, name: "cellSelected" }, { kind: "pipe", type: i18.CellActionButtonEnablePipe, name: "cellActionButtonEnable" }, { kind: "pipe", type: i19.CellKeyPipe, name: "cellKey" }, { kind: "pipe", type: i20.CellLevelPaddingPipe, name: "cellLevelPadding" }, { kind: "pipe", type: i21.CellStateRendererPipe, name: "cellStateRenderer" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1101
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: OneGridBodyComponent, isStandalone: true, selector: "one-grid-body", inputs: { rowData: "rowData", rowNumber: "rowNumber", api: "api", pagination: "pagination", allowedEdit: "allowedEdit", enableGroupColumnDefs: "enableGroupColumnDefs", submitted: "submitted", editType: "editType", context: "context", getRowId: "getRowId", gridCopy$: "gridCopy$", pinnedTopRowData: "pinnedTopRowData", pinnedBottomRowData: "pinnedBottomRowData", gridType: "gridType", masterDetail: "masterDetail", masterNode: "masterNode", detailRowMaxHeight: "detailRowMaxHeight", detailCellRendererParams: "detailCellRendererParams", detailGridTemplate: "detailGridTemplate", detailRendererComponent: "detailRendererComponent", treeData: "treeData", treeDataChildrenField: "treeDataChildrenField", autoGroupColumnDef: "autoGroupColumnDef", groupDefaultExpanded: "groupDefaultExpanded" }, outputs: { onRowGotoDetail: "onRowGotoDetail", onRowAddNew: "onRowAddNew", onRowView: "onRowView", onRowCopy: "onRowCopy", onRowLocation: "onRowLocation", onRowDocument: "onRowDocument", onRowDelete: "onRowDelete", onRowGotoList: "onRowGotoList", onRowEdit: "onRowEdit", onRowPrint: "onRowPrint", onRowHistory: "onRowHistory", onRowOption: "onRowOption", onRowLanguage: "onRowLanguage", onRowCellOption: "onRowCellOption", onRowSelection: "onRowSelection", onShiftDoubleClick: "onShiftDoubleClick", rowCountChanged: "rowCountChanged", expansionChanged: "expansionChanged", bodyScroll: "bodyScroll", cellOptionSelect: "cellOptionSelect", rowDragEnd: "rowDragEnd" }, host: { attributes: { "role": "presentation" }, listeners: { "document:click": "onDocumentClick($event)", "document:mouseup": "onGlobalMouseUp()" } }, viewQueries: [{ propertyName: "bodyRef", first: true, predicate: ["bodyRef"], descendants: true, static: true }, { propertyName: "viewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true }, { propertyName: "pinnedViewports", predicate: ["pinnedViewport"], descendants: true }], ngImport: i0, template: "<div #bodyRef class=\"one-grid-body\" role=\"presentation\">\n\n <!-- Pinned rows live outside the scroll viewport so they never scroll\n vertically, and mirror its scrollLeft so the columns stay aligned. -->\n @if (pinnedTopNodes.length) {\n <div #pinnedViewport class=\"one-pinned-rows one-pinned-rows-top\" role=\"rowgroup\">\n <ng-container [ngTemplateOutlet]=\"pinnedRows\" [ngTemplateOutletContext]=\"{ nodes: pinnedTopNodes, side: 'top' }\"></ng-container>\n </div>\n }\n\n <!-- tabindex makes the scroll container reachable, so a keyboard user can\n scroll the rows with the arrow keys, Page Up/Down and Home/End. Without\n it the body is scrollable by pointer only (WCAG 2.1.1). -->\n <cdk-virtual-scroll-viewport\n class=\"one-grid-body-viewport\"\n role=\"rowgroup\"\n [attr.tabindex]=\"nodes?.length ? null : 0\"\n (keydown)=\"onGridKeydown($event)\"\n [itemSize]=\"itemSize\"\n [minBufferPx]=\"minBufferPx\"\n [maxBufferPx]=\"maxBufferPx\"\n (scroll)=\"onBodyScroll($event)\">\n\n <ng-container *cdkVirtualFor=\"let node of nodes; trackBy: trackByRowId;\">\n \n <div class=\"one-row\"\n role=\"row\"\n [attr.aria-rowindex]=\"dataRowAriaIndex(node)\"\n [attr.aria-selected]=\"rowSelectionEnabled ? node.selected : null\"\n [attr.data-row-id]=\"node.rowId\"\n [class.one-row-selected]=\"node.selected\"\n [class.one-row-dragging]=\"isRowDragging(node)\">\n @for (col of columnDefs; track col.field;) {\n <ng-container [ngTemplateOutlet]=\"cellTemplate\" [ngTemplateOutletContext]=\"{ node, rowIndex: node.rowIndex, column: col, colIndex: $index }\"></ng-container>\n }\n </div>\n\n <!-- Custom Detail Component -->\n @if(node.leaf && node.detailActive && node?.detailRendererComponent) {\n <ng-container\n oneCellRendererComponent\n [cellRendererComponent]=\"node?.detailRendererComponent\"\n [params]=\"{ data: node.data, rowIndex: node.rowIndex, node: node, context: context }\">\n </ng-container>\n }\n\n <!-- Master Detail Grid (template provided by the parent one-grid to avoid a compile-time import cycle) -->\n @if (masterDetail && node.expanded && node?.detailRowData) {\n <div class=\"one-row-detail-container\" [attr.data-row-id]=\"node.rowId + '-detail'\">\n <ng-container\n [ngTemplateOutlet]=\"detailGridTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: node, node: node }\">\n </ng-container>\n </div>\n }\n </ng-container>\n @if (!nodes?.length) {\n <div style=\"width: max-content; border-top: 1px solid transparent;\">\n <div [style.width.px]=\"rowWidth\"></div>\n </div>\n }\n </cdk-virtual-scroll-viewport>\n\n <!-- Drop indicator.\n A line at the insertion point rather than a gap opened between rows:\n the viewport is virtualised at a fixed itemSize, so shifting rows apart\n would desynchronise the scroller from its own geometry. It is also the\n clearer signal \u2014 the row lands exactly where the line is.\n Positioned against the body, with the viewport's scroll subtracted, so\n it stays put while the content moves under it during auto-scroll. -->\n @if (dropIndicatorTop !== null) {\n <div class=\"one-row-drop-indicator\" aria-hidden=\"true\"\n [style.top.px]=\"dropIndicatorTop\"\n [style.width.px]=\"dropIndicatorWidth\"></div>\n }\n\n <!-- Keyboard reordering has no drag image to watch, so it narrates instead.\n Assertive because the message is the only feedback that the row moved. -->\n <div class=\"one-grid-visually-hidden\" role=\"status\" aria-live=\"assertive\" aria-atomic=\"true\">{{ dragAnnouncement }}</div>\n @if (!nodes?.length) {\n <span class=\"one-grid-empty-message\" style=\"position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);\">No Rows to Show</span>\n }\n\n @if (pinnedBottomNodes.length) {\n <div #pinnedViewport class=\"one-pinned-rows one-pinned-rows-bottom\" role=\"rowgroup\">\n <ng-container [ngTemplateOutlet]=\"pinnedRows\" [ngTemplateOutletContext]=\"{ nodes: pinnedBottomNodes, side: 'bottom' }\"></ng-container>\n </div>\n }\n</div>\n\n<!-- Pinned rows are display-only: they render exactly what a data cell renders,\n but carry none of its interactions. A totals row should not open an editor\n on double-click or start a range selection on drag. -->\n<ng-template #pinnedRows let-nodes=\"nodes\" let-side=\"side\">\n @for (node of nodes; track node.rowId) {\n <div class=\"one-row one-row-pinned\"\n role=\"row\"\n [attr.aria-rowindex]=\"pinnedRowAriaIndex(node, side)\"\n [attr.data-row-id]=\"node.rowId\">\n @for (column of columnDefs; track column.field) {\n <div\n class=\"one-column\"\n role=\"gridcell\"\n [attr.aria-colindex]=\"$index + 1\"\n [attr.data-cell-id]=\"node.rowId | cellKey:column.field\"\n [class.one-column-pinned-left]=\"column.pinned === 'left'\"\n [class.one-column-pinned-right]=\"column.pinned === 'right'\"\n [class.one-column-pinned-edge]=\"column._pinnedEdge\"\n [style.left.px]=\"column.pinned === 'left' ? column._pinnedOffset : null\"\n [style.right.px]=\"column.pinned === 'right' ? column._pinnedOffset : null\"\n [style.width.px]=\"column?.width\"\n [style.min-width.px]=\"column?.minWidth\"\n [style.max-width.px]=\"column?.maxWidth\">\n\n @if (column?.cellRendererComponent) {\n <ng-container\n oneCellRendererComponent\n [cellRendererComponent]=\"column?.cellRendererComponent\"\n [params]=\"rendererParams(node, column)\">\n </ng-container>\n }\n @else if (column?.cellRenderer) {\n <div\n [ngStyle]=\"{ width: column.width + 'px', position: 'relative' }\"\n [innerHTML]=\"node.cellStates | cellStateRenderer:column.field\">\n </div>\n }\n @else {\n <div class=\"one-cell\"\n [class.align-content-left]=\"column?.alignContent === 'left'\"\n [class.align-content-center]=\"column?.alignContent === 'center'\"\n [class.align-content-right]=\"column?.alignContent === 'right'\"\n [ngClass]=\"colService.resolveCellClass(column, cellParams(node, column))\"\n [ngStyle]=\"colService.resolveCellStyle(column, cellParams(node, column))\">\n <div class=\"one-cell-text\">{{ (node.cellStates | cellStateRenderer:column.field) }}</div>\n </div>\n }\n </div>\n }\n </div>\n }\n</ng-template>\n\n<!-- Master Column Template -->\n<ng-template #cellTemplate let-node=\"node\" let-rowIndex=\"rowIndex\" let-column=\"column\" let-colIndex=\"colIndex\">\n <div\n class=\"one-column\"\n role=\"gridcell\"\n [attr.aria-colindex]=\"colIndex + 1\"\n [attr.tabindex]=\"isActiveCell(node, column) ? 0 : -1\"\n [class.one-cell-active]=\"isActiveCell(node, column)\"\n (focus)=\"onCellFocus(node, column)\"\n [attr.data-cell-id]=\"node.rowId | cellKey:column.field\"\n [class.one-column-pinned-left]=\"column.pinned === 'left'\"\n [class.one-column-pinned-right]=\"column.pinned === 'right'\"\n [class.one-column-pinned-edge]=\"column._pinnedEdge\"\n [style.left.px]=\"column.pinned === 'left' ? column._pinnedOffset : null\"\n [style.right.px]=\"column.pinned === 'right' ? column._pinnedOffset : null\"\n [style.width.px]=\"column?.width\"\n [style.min-width.px]=\"column?.minWidth\"\n [style.max-width.px]=\"column?.maxWidth\"\n [class.one-column-border-top]=\"masterDetail && nodes?.length > 0 && nodes[node.rowIndex - 1]?.expanded\"\n [class.one-cell-selected]=\"selectedCells | cellSelected:node.rowId:column.field\"\n [class.one-cell-invalid]=\"node.cellStates | cellInvalid:node.data[column.field]:column:node:allowedEdit:submitted\"\n (dblclick)=\"startEdit($event, node, column)\"\n (mousedown)=\"startSelection(node.rowId, column.field)\"\n (mouseenter)=\"extendSelection(node.rowId, column.field)\"\n (mouseup)=\"endSelection()\">\n\n <!-- One Grid Cell Option -->\n @if (node.cellOptions[column.field]) {\n <one-grid-cell-option-menu\n #contextOptionMenuRef\n [node]=\"node\"\n [column]=\"column\"\n [options]=\"column.cellOptionMenu\"\n (cellOptionMenuSelect)=\"cellOptionMenuSelected($event)\"\n (cellOptionMenuClose)=\"cellOptionMenuClosed()\"/>\n }\n\n <!-- Grid Cell Template -->\n @if(column?.cellRendererComponent) {\n <ng-container\n oneCellRendererComponent\n [cellRendererComponent]=\"column?.cellRendererComponent\"\n [params]=\"rendererParams(node, column)\">\n </ng-container>\n }\n @else if (node.editing[column.field]) {\n @if (column?.cellRendererParams?.inputType === 'select') {\n <!-- Cell Editing Select. Commits on change \u2014 picking an option\n is the whole edit \u2014 with blur as the keyboard fallback. -->\n <select class=\"one-cell-input\"\n name=\"{{ node.rowId + '' + column.field }}\"\n (change)=\"stopEditSelect(node, column, $event)\"\n (blur)=\"stopEditSelect(node, column, $event)\"\n (keydown.esc)=\"cancelEdit(node, column)\">\n @for (option of column?.cellRendererParams?.selectOptions ?? []; track $index) {\n <option [selected]=\"option.value === node.data[column.field]\">{{ option.label }}</option>\n }\n </select>\n }\n @else {\n <!-- Cell Editing Input -->\n <input class=\"one-cell-input\"\n name=\"{{ node.rowId + '' + column.field }}\"\n oneCellInputValidator\n [validationType]=\"column?.cellRendererParams?.inputType === 'number' ? 'number' : 'none'\"\n [placeholder]=\"column?.cellRendererParams?.placeholder\"\n [type]=\"column?.cellRendererParams?.inputType === 'number' ? 'text' : column?.cellRendererParams?.inputType\"\n [value]=\"node?.data[column?.field]\"\n [maxLength]=\"250\"\n (blur)=\"stopEdit(node, column, $event)\"\n (keydown.enter)=\"stopEdit(node, column, $event)\"\n (keydown.esc)=\"cancelEdit(node, column)\"\n />\n }\n }\n @else if (column?.cellRenderer) {\n <div\n [ngStyle]=\"{ width: column.width + 'px' , position: 'relative' }\"\n [innerHTML]=\"node.cellStates | cellStateRenderer:column.field\"\n [class.editable-active]=\"node.cellStates | cellEditable:column:node:cellService.editableFn:cellService.updatableFn:allowedEdit\">\n </div>\n }\n @else {\n <div class=\"one-cell\"\n [class.align-content-left]=\"column?.alignContent === 'left'\"\n [class.align-content-center]=\"column?.alignContent === 'center'\"\n [class.align-content-right]=\"column?.alignContent === 'right'\"\n [ngClass]=\"colService.resolveCellClass(column, cellParams(node, column))\"\n [ngStyle]=\"colService.resolveCellStyle(column, cellParams(node, column))\"\n [style.padding-left.px]=\"column.autoGroupField && node.level | cellLevelPadding:24\"\n [class.one-cell-allowed-edit-active]=\"node.cellStates | cellEditable:column:node:cellService.editableFn:cellService.updatableFn:allowedEdit\">\n\n <!-- Row Drag Handle -->\n @if (cellService.rowDragFn(column, node)) {\n <one-grid-row-drag-handle\n [node]=\"node\"\n [suppressedReason]=\"rowDragSuppressed\"\n (dragEnd)=\"onRowDragEnd($event)\"\n />\n }\n\n <!-- Cell Checkbox Selection -->\n @if (column?.checkboxSelection) {\n <one-grid-checkbox\n [node]=\"node\"\n [allowedEdit]=\"allowedEdit\"\n [api]=\"api\"\n (onRowSelection)=\"invokeRowActionSelection($event)\"\n />\n }\n\n <!-- Expand & Collapse Icon -->\n @if (((node?.group || detailRendererComponent) && column?.autoGroupField) || (masterDetail && node?.expandable && gridType === 'master' && column?.masterGroupField)) {\n <one-grid-cell-group-renderer\n [node]=\"node\"\n [masterDetail]=\"masterDetail\"\n [detailCellRendererParams]=\"detailCellRendererParams\"\n [detailRendererComponent]=\"detailRendererComponent\"\n (expansionChanged)=\"invokeExpansionChangedClick($event)\"\n />\n }\n\n @if(column?.cellRendererComponent) {\n <ng-container\n oneCellRendererComponent\n [cellRendererComponent]=\"column?.cellRendererComponent\"\n [params]=\"rendererParams(node, column)\">\n </ng-container>\n }\n @else {\n <!-- Cell Value OR Placeholder -->\n <div oneCellTextExpand class=\"one-cell-text\" [class.one-cell-placeholder]=\"node.cellStates[column.field]?.type === 'placeholder'\">\n {{ (node.cellStates | cellStateRenderer:column.field) }}\n </div>\n }\n\n <!-- Cell Action Buttons -->\n @if (column.cellRendererParams | cellActionButtonEnable) {\n <one-grid-row-action\n [ngStyle]=\"{ marginLeft: 'auto' }\"\n [column]=\"column\"\n [node]=\"node\"\n [allowedEdit]=\"allowedEdit\"\n [masterNode]=\"masterNode\"\n [masterDetail]=\"masterDetail\"\n [gridType]=\"gridType\"\n [context]=\"context\"\n [cellRendererParams]=\"column?.cellRendererParams\"\n (onRowGotoDetail)=\"invokeRowActionGotoDetail($event)\"\n (onRowAddNew)=\"invokeRowActionAddNew($event)\"\n (onRowView)=\"invokeRowActionView($event)\"\n (onRowLocation)=\"invokeRowActionLocation($event)\"\n (onRowDocument)=\"invokeRowActionDocument($event)\"\n (onRowCopy)=\"invokeRowActionCopy($event)\"\n (onRowDelete)=\"invokeRowActionDelete($event)\"\n (onRowGotoList)=\"invokeRowActionGotoList($event)\"\n (onRowEdit)=\"invokeRowActionEdit($event)\"\n (onRowPrint)=\"invokeRowActionPrint($event)\"\n (onRowHistory)=\"invokeRowActionHistory($event)\"\n (onRowOption)=\"invokeRowActionOption($event)\"\n (onRowLanguage)=\"invokeRowActionLanguage($event)\"\n (onRowCellOption)=\"invokeRowActionCellOption($event)\"\n />\n }\n </div>\n }\n </div>\n</ng-template>\n", styles: [""], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i5.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i5.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i5.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: OneGridCheckboxComponent, selector: "one-grid-checkbox", inputs: ["node", "allowedEdit", "api"], outputs: ["onRowSelection"] }, { kind: "component", type: OneGridCellGroupRendererComponent, selector: "one-grid-cell-group-renderer", inputs: ["node", "masterDetail", "detailCellRendererParams", "detailRendererComponent"], outputs: ["expansionChanged"] }, { kind: "component", type: OneGridCellOptionMenuComponent, selector: "one-grid-cell-option-menu", inputs: ["column", "node", "options"], outputs: ["cellOptionMenuSelect", "cellOptionMenuClose"] }, { kind: "component", type: OneGridRowActionComponent, selector: "one-grid-row-action", inputs: ["column", "node", "allowedEdit", "masterDetail", "masterNode", "cellRendererParams", "gridType", "context"], outputs: ["onRowGotoDetail", "onRowAddNew", "onRowView", "onRowLocation", "onRowDocument", "onRowCopy", "onRowDelete", "onRowGotoList", "onRowEdit", "onRowPrint", "onRowHistory", "onRowOption", "onRowLanguage", "onRowCellOption"] }, { kind: "component", type: OneGridRowDragHandleComponent, selector: "one-grid-row-drag-handle", inputs: ["node", "suppressedReason"], outputs: ["dragEnd"] }, { kind: "directive", type: OneCellInputValidatorDirective, selector: "[oneCellInputValidator]", inputs: ["validationType", "regex"] }, { kind: "directive", type: OneCellRendererComponentDirective, selector: "[oneCellRendererComponent]", inputs: ["cellRendererComponent", "params"] }, { kind: "directive", type: OneCellTextExpandDirective, selector: "[oneCellTextExpand]" }, { kind: "pipe", type: CellActionButtonEnablePipe, name: "cellActionButtonEnable" }, { kind: "pipe", type: CellEditablePipe, name: "cellEditable" }, { kind: "pipe", type: CellInvalidPipe, name: "cellInvalid" }, { kind: "pipe", type: CellKeyPipe, name: "cellKey" }, { kind: "pipe", type: CellLevelPaddingPipe, name: "cellLevelPadding" }, { kind: "pipe", type: CellSelectedPipe, name: "cellSelected" }, { kind: "pipe", type: CellStateRendererPipe, name: "cellStateRenderer" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
712
1102
  }
713
1103
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: OneGridBodyComponent, decorators: [{
714
1104
  type: Component,
715
- args: [{ standalone: false, selector: 'one-grid-body', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div #bodyRef class=\"one-grid-body\">\n\n <!-- Pinned rows live outside the scroll viewport so they never scroll\n vertically, and mirror its scrollLeft so the columns stay aligned. -->\n @if (pinnedTopNodes.length) {\n <div #pinnedViewport class=\"one-pinned-rows one-pinned-rows-top\">\n <ng-container [ngTemplateOutlet]=\"pinnedRows\" [ngTemplateOutletContext]=\"{ nodes: pinnedTopNodes }\"></ng-container>\n </div>\n }\n\n <!-- tabindex makes the scroll container reachable, so a keyboard user can\n scroll the rows with the arrow keys, Page Up/Down and Home/End. Without\n it the body is scrollable by pointer only (WCAG 2.1.1). -->\n <cdk-virtual-scroll-viewport\n class=\"one-grid-body-viewport\"\n tabindex=\"0\"\n [itemSize]=\"itemSize\"\n [minBufferPx]=\"minBufferPx\"\n [maxBufferPx]=\"maxBufferPx\"\n (scroll)=\"onBodyScroll($event)\">\n\n <ng-container *cdkVirtualFor=\"let node of nodes; trackBy: trackByRowId;\">\n \n <div class=\"one-row\"\n [attr.data-row-id]=\"node.rowId\"\n [class.one-row-selected]=\"node.selected\"\n [class.one-row-dragging]=\"isRowDragging(node)\">\n @for (col of columnDefs; track col.field;) {\n <ng-container [ngTemplateOutlet]=\"cellTemplate\" [ngTemplateOutletContext]=\"{ node, rowIndex: node.rowIndex, column: col }\"></ng-container>\n }\n </div>\n\n <!-- Custom Detail Component -->\n @if(node.leaf && node.detailActive && node?.detailRendererComponent) {\n <ng-container\n oneCellRendererComponent\n [cellRendererComponent]=\"node?.detailRendererComponent\"\n [params]=\"{ data: node.data, rowIndex: node.rowIndex, node: node, context: context }\">\n </ng-container>\n }\n\n <!-- Master Detail Grid (template provided by the parent one-grid to avoid a compile-time import cycle) -->\n @if (masterDetail && node.expanded && node?.detailRowData) {\n <div class=\"one-row-detail-container\" [attr.data-row-id]=\"node.rowId + '-detail'\">\n <ng-container\n [ngTemplateOutlet]=\"detailGridTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: node, node: node }\">\n </ng-container>\n </div>\n }\n </ng-container>\n @if (!nodes?.length) {\n <div style=\"width: max-content; border-top: 1px solid transparent;\">\n <div [style.width.px]=\"rowWidth\"></div>\n </div>\n }\n </cdk-virtual-scroll-viewport>\n\n <!-- Drop indicator.\n A line at the insertion point rather than a gap opened between rows:\n the viewport is virtualised at a fixed itemSize, so shifting rows apart\n would desynchronise the scroller from its own geometry. It is also the\n clearer signal \u2014 the row lands exactly where the line is.\n Positioned against the body, with the viewport's scroll subtracted, so\n it stays put while the content moves under it during auto-scroll. -->\n @if (dropIndicatorTop !== null) {\n <div class=\"one-row-drop-indicator\" aria-hidden=\"true\"\n [style.top.px]=\"dropIndicatorTop\"\n [style.width.px]=\"dropIndicatorWidth\"></div>\n }\n\n <!-- Keyboard reordering has no drag image to watch, so it narrates instead.\n Assertive because the message is the only feedback that the row moved. -->\n <div class=\"one-grid-visually-hidden\" role=\"status\" aria-live=\"assertive\" aria-atomic=\"true\">{{ dragAnnouncement }}</div>\n @if (!nodes?.length) {\n <span class=\"one-grid-empty-message\" style=\"position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);\">No Rows to Show</span>\n }\n\n @if (pinnedBottomNodes.length) {\n <div #pinnedViewport class=\"one-pinned-rows one-pinned-rows-bottom\">\n <ng-container [ngTemplateOutlet]=\"pinnedRows\" [ngTemplateOutletContext]=\"{ nodes: pinnedBottomNodes }\"></ng-container>\n </div>\n }\n</div>\n\n<!-- Pinned rows are display-only: they render exactly what a data cell renders,\n but carry none of its interactions. A totals row should not open an editor\n on double-click or start a range selection on drag. -->\n<ng-template #pinnedRows let-nodes=\"nodes\">\n @for (node of nodes; track node.rowId) {\n <div class=\"one-row one-row-pinned\" [attr.data-row-id]=\"node.rowId\">\n @for (column of columnDefs; track column.field) {\n <div\n class=\"one-column\"\n [attr.data-cell-id]=\"node.rowId | cellKey:column.field\"\n [class.one-column-pinned-left]=\"column.pinned === 'left'\"\n [class.one-column-pinned-right]=\"column.pinned === 'right'\"\n [class.one-column-pinned-edge]=\"column._pinnedEdge\"\n [style.left.px]=\"column.pinned === 'left' ? column._pinnedOffset : null\"\n [style.right.px]=\"column.pinned === 'right' ? column._pinnedOffset : null\"\n [style.width.px]=\"column?.width\"\n [style.min-width.px]=\"column?.minWidth\"\n [style.max-width.px]=\"column?.maxWidth\">\n\n @if (column?.cellRendererComponent) {\n <ng-container\n oneCellRendererComponent\n [cellRendererComponent]=\"column?.cellRendererComponent\"\n [params]=\"rendererParams(node, column)\">\n </ng-container>\n }\n @else if (column?.cellRenderer) {\n <div\n [ngStyle]=\"{ width: column.width + 'px', position: 'relative' }\"\n [innerHTML]=\"node.cellStates | cellStateRenderer:column.field\">\n </div>\n }\n @else {\n <div class=\"one-cell\"\n [class.align-content-left]=\"column?.alignContent === 'left'\"\n [class.align-content-center]=\"column?.alignContent === 'center'\"\n [class.align-content-right]=\"column?.alignContent === 'right'\"\n [ngClass]=\"colService.resolveCellClass(column, cellParams(node, column))\"\n [ngStyle]=\"colService.resolveCellStyle(column, cellParams(node, column))\">\n <div class=\"one-cell-text\">{{ (node.cellStates | cellStateRenderer:column.field) }}</div>\n </div>\n }\n </div>\n }\n </div>\n }\n</ng-template>\n\n<!-- Master Column Template -->\n<ng-template #cellTemplate let-node=\"node\" let-rowIndex=\"rowIndex\" let-column=\"column\">\n <div\n class=\"one-column\"\n [attr.data-cell-id]=\"node.rowId | cellKey:column.field\"\n [class.one-column-pinned-left]=\"column.pinned === 'left'\"\n [class.one-column-pinned-right]=\"column.pinned === 'right'\"\n [class.one-column-pinned-edge]=\"column._pinnedEdge\"\n [style.left.px]=\"column.pinned === 'left' ? column._pinnedOffset : null\"\n [style.right.px]=\"column.pinned === 'right' ? column._pinnedOffset : null\"\n [style.width.px]=\"column?.width\"\n [style.min-width.px]=\"column?.minWidth\"\n [style.max-width.px]=\"column?.maxWidth\"\n [class.one-column-border-top]=\"masterDetail && nodes?.length > 0 && nodes[node.rowIndex - 1]?.expanded\"\n [class.one-cell-selected]=\"selectedCells | cellSelected:node.rowId:column.field\"\n [class.one-cell-invalid]=\"node.cellStates | cellInvalid:node.data[column.field]:column:node:allowedEdit:submitted\"\n (dblclick)=\"startEdit($event, node, column)\"\n (mousedown)=\"startSelection(node.rowId, column.field)\"\n (mouseenter)=\"extendSelection(node.rowId, column.field)\"\n (mouseup)=\"endSelection()\">\n\n <!-- One Grid Cell Option -->\n @if (node.cellOptions[column.field]) {\n <one-grid-cell-option-menu\n #contextOptionMenuRef\n [node]=\"node\"\n [column]=\"column\"\n [options]=\"column.cellOptionMenu\"\n (cellOptionMenuSelect)=\"cellOptionMenuSelected($event)\"\n (cellOptionMenuClose)=\"cellOptionMenuClosed()\"/>\n }\n\n <!-- Grid Cell Template -->\n @if(column?.cellRendererComponent) {\n <ng-container\n oneCellRendererComponent\n [cellRendererComponent]=\"column?.cellRendererComponent\"\n [params]=\"rendererParams(node, column)\">\n </ng-container>\n }\n @else if (node.editing[column.field]) {\n <!-- Cell Editing Input -->\n <input class=\"one-cell-input\"\n name=\"{{ node.rowId + '' + column.field }}\"\n oneCellInputValidator\n [validationType]=\"column?.cellRendererParams?.inputType === 'number' ? 'number' : 'none'\"\n [placeholder]=\"column?.cellRendererParams?.placeholder\"\n [type]=\"column?.cellRendererParams?.inputType === 'number' ? 'text' : column?.cellRendererParams?.inputType\"\n [value]=\"node?.data[column?.field]\"\n [maxLength]=\"250\"\n (blur)=\"stopEdit(node, column, $event)\"\n (keydown.enter)=\"stopEdit(node, column, $event)\"\n (keydown.esc)=\"cancelEdit(node, column)\"\n />\n }\n @else if (column?.cellRenderer) {\n <div\n [ngStyle]=\"{ width: column.width + 'px' , position: 'relative' }\"\n [innerHTML]=\"node.cellStates | cellStateRenderer:column.field\"\n [class.editable-active]=\"node.cellStates | cellEditable:column:node:cellService.editableFn:cellService.updatableFn:allowedEdit\">\n </div>\n }\n @else {\n <div class=\"one-cell\"\n [class.align-content-left]=\"column?.alignContent === 'left'\"\n [class.align-content-center]=\"column?.alignContent === 'center'\"\n [class.align-content-right]=\"column?.alignContent === 'right'\"\n [ngClass]=\"colService.resolveCellClass(column, cellParams(node, column))\"\n [ngStyle]=\"colService.resolveCellStyle(column, cellParams(node, column))\"\n [style.padding-left.px]=\"column.autoGroupField && node.level | cellLevelPadding:24\"\n [class.one-cell-allowed-edit-active]=\"node.cellStates | cellEditable:column:node:cellService.editableFn:cellService.updatableFn:allowedEdit\">\n\n <!-- Row Drag Handle -->\n @if (cellService.rowDragFn(column, node)) {\n <one-grid-row-drag-handle\n [node]=\"node\"\n [suppressedReason]=\"rowDragSuppressed\"\n (dragEnd)=\"onRowDragEnd($event)\"\n />\n }\n\n <!-- Cell Checkbox Selection -->\n @if (column?.checkboxSelection) {\n <one-grid-checkbox\n [node]=\"node\"\n [allowedEdit]=\"allowedEdit\"\n [api]=\"api\"\n (onRowSelection)=\"invokeRowActionSelection($event)\"\n />\n }\n\n <!-- Expand & Collapse Icon -->\n @if (((node?.group || detailRendererComponent) && column?.autoGroupField) || (masterDetail && node?.expandable && gridType === 'master' && column?.masterGroupField)) {\n <one-grid-cell-group-renderer\n [node]=\"node\"\n [masterDetail]=\"masterDetail\"\n [detailCellRendererParams]=\"detailCellRendererParams\"\n [detailRendererComponent]=\"detailRendererComponent\"\n (expansionChanged)=\"invokeExpansionChangedClick($event)\"\n />\n }\n\n @if(column?.cellRendererComponent) {\n <ng-container\n oneCellRendererComponent\n [cellRendererComponent]=\"column?.cellRendererComponent\"\n [params]=\"rendererParams(node, column)\">\n </ng-container>\n }\n @else {\n <!-- Cell Value OR Placeholder -->\n <div oneCellTextExpand class=\"one-cell-text\" [class.one-cell-placeholder]=\"node.cellStates[column.field]?.type === 'placeholder'\">\n {{ (node.cellStates | cellStateRenderer:column.field) }}\n </div>\n }\n\n <!-- Cell Action Buttons -->\n @if (column.cellRendererParams | cellActionButtonEnable) {\n <one-grid-row-action\n [ngStyle]=\"{ marginLeft: 'auto' }\"\n [column]=\"column\"\n [node]=\"node\"\n [allowedEdit]=\"allowedEdit\"\n [masterNode]=\"masterNode\"\n [masterDetail]=\"masterDetail\"\n [gridType]=\"gridType\"\n [context]=\"context\"\n [cellRendererParams]=\"column?.cellRendererParams\"\n (onRowGotoDetail)=\"invokeRowActionGotoDetail($event)\"\n (onRowAddNew)=\"invokeRowActionAddNew($event)\"\n (onRowView)=\"invokeRowActionView($event)\"\n (onRowLocation)=\"invokeRowActionLocation($event)\"\n (onRowDocument)=\"invokeRowActionDocument($event)\"\n (onRowCopy)=\"invokeRowActionCopy($event)\"\n (onRowDelete)=\"invokeRowActionDelete($event)\"\n (onRowGotoList)=\"invokeRowActionGotoList($event)\"\n (onRowEdit)=\"invokeRowActionEdit($event)\"\n (onRowPrint)=\"invokeRowActionPrint($event)\"\n (onRowHistory)=\"invokeRowActionHistory($event)\"\n (onRowOption)=\"invokeRowActionOption($event)\"\n (onRowLanguage)=\"invokeRowActionLanguage($event)\"\n (onRowCellOption)=\"invokeRowActionCellOption($event)\"\n />\n }\n </div>\n }\n </div>\n</ng-template>\n" }]
1105
+ args: [{ standalone: true, imports: [
1106
+ NgClass,
1107
+ NgStyle,
1108
+ NgTemplateOutlet,
1109
+ ScrollingModule,
1110
+ OneGridCheckboxComponent,
1111
+ OneGridCellGroupRendererComponent,
1112
+ OneGridCellOptionMenuComponent,
1113
+ OneGridRowActionComponent,
1114
+ OneGridRowDragHandleComponent,
1115
+ OneCellInputValidatorDirective,
1116
+ OneCellRendererComponentDirective,
1117
+ OneCellTextExpandDirective,
1118
+ CellActionButtonEnablePipe,
1119
+ CellEditablePipe,
1120
+ CellInvalidPipe,
1121
+ CellKeyPipe,
1122
+ CellLevelPaddingPipe,
1123
+ CellSelectedPipe,
1124
+ CellStateRendererPipe,
1125
+ ], selector: 'one-grid-body', host: { 'role': 'presentation' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div #bodyRef class=\"one-grid-body\" role=\"presentation\">\n\n <!-- Pinned rows live outside the scroll viewport so they never scroll\n vertically, and mirror its scrollLeft so the columns stay aligned. -->\n @if (pinnedTopNodes.length) {\n <div #pinnedViewport class=\"one-pinned-rows one-pinned-rows-top\" role=\"rowgroup\">\n <ng-container [ngTemplateOutlet]=\"pinnedRows\" [ngTemplateOutletContext]=\"{ nodes: pinnedTopNodes, side: 'top' }\"></ng-container>\n </div>\n }\n\n <!-- tabindex makes the scroll container reachable, so a keyboard user can\n scroll the rows with the arrow keys, Page Up/Down and Home/End. Without\n it the body is scrollable by pointer only (WCAG 2.1.1). -->\n <cdk-virtual-scroll-viewport\n class=\"one-grid-body-viewport\"\n role=\"rowgroup\"\n [attr.tabindex]=\"nodes?.length ? null : 0\"\n (keydown)=\"onGridKeydown($event)\"\n [itemSize]=\"itemSize\"\n [minBufferPx]=\"minBufferPx\"\n [maxBufferPx]=\"maxBufferPx\"\n (scroll)=\"onBodyScroll($event)\">\n\n <ng-container *cdkVirtualFor=\"let node of nodes; trackBy: trackByRowId;\">\n \n <div class=\"one-row\"\n role=\"row\"\n [attr.aria-rowindex]=\"dataRowAriaIndex(node)\"\n [attr.aria-selected]=\"rowSelectionEnabled ? node.selected : null\"\n [attr.data-row-id]=\"node.rowId\"\n [class.one-row-selected]=\"node.selected\"\n [class.one-row-dragging]=\"isRowDragging(node)\">\n @for (col of columnDefs; track col.field;) {\n <ng-container [ngTemplateOutlet]=\"cellTemplate\" [ngTemplateOutletContext]=\"{ node, rowIndex: node.rowIndex, column: col, colIndex: $index }\"></ng-container>\n }\n </div>\n\n <!-- Custom Detail Component -->\n @if(node.leaf && node.detailActive && node?.detailRendererComponent) {\n <ng-container\n oneCellRendererComponent\n [cellRendererComponent]=\"node?.detailRendererComponent\"\n [params]=\"{ data: node.data, rowIndex: node.rowIndex, node: node, context: context }\">\n </ng-container>\n }\n\n <!-- Master Detail Grid (template provided by the parent one-grid to avoid a compile-time import cycle) -->\n @if (masterDetail && node.expanded && node?.detailRowData) {\n <div class=\"one-row-detail-container\" [attr.data-row-id]=\"node.rowId + '-detail'\">\n <ng-container\n [ngTemplateOutlet]=\"detailGridTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: node, node: node }\">\n </ng-container>\n </div>\n }\n </ng-container>\n @if (!nodes?.length) {\n <div style=\"width: max-content; border-top: 1px solid transparent;\">\n <div [style.width.px]=\"rowWidth\"></div>\n </div>\n }\n </cdk-virtual-scroll-viewport>\n\n <!-- Drop indicator.\n A line at the insertion point rather than a gap opened between rows:\n the viewport is virtualised at a fixed itemSize, so shifting rows apart\n would desynchronise the scroller from its own geometry. It is also the\n clearer signal \u2014 the row lands exactly where the line is.\n Positioned against the body, with the viewport's scroll subtracted, so\n it stays put while the content moves under it during auto-scroll. -->\n @if (dropIndicatorTop !== null) {\n <div class=\"one-row-drop-indicator\" aria-hidden=\"true\"\n [style.top.px]=\"dropIndicatorTop\"\n [style.width.px]=\"dropIndicatorWidth\"></div>\n }\n\n <!-- Keyboard reordering has no drag image to watch, so it narrates instead.\n Assertive because the message is the only feedback that the row moved. -->\n <div class=\"one-grid-visually-hidden\" role=\"status\" aria-live=\"assertive\" aria-atomic=\"true\">{{ dragAnnouncement }}</div>\n @if (!nodes?.length) {\n <span class=\"one-grid-empty-message\" style=\"position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);\">No Rows to Show</span>\n }\n\n @if (pinnedBottomNodes.length) {\n <div #pinnedViewport class=\"one-pinned-rows one-pinned-rows-bottom\" role=\"rowgroup\">\n <ng-container [ngTemplateOutlet]=\"pinnedRows\" [ngTemplateOutletContext]=\"{ nodes: pinnedBottomNodes, side: 'bottom' }\"></ng-container>\n </div>\n }\n</div>\n\n<!-- Pinned rows are display-only: they render exactly what a data cell renders,\n but carry none of its interactions. A totals row should not open an editor\n on double-click or start a range selection on drag. -->\n<ng-template #pinnedRows let-nodes=\"nodes\" let-side=\"side\">\n @for (node of nodes; track node.rowId) {\n <div class=\"one-row one-row-pinned\"\n role=\"row\"\n [attr.aria-rowindex]=\"pinnedRowAriaIndex(node, side)\"\n [attr.data-row-id]=\"node.rowId\">\n @for (column of columnDefs; track column.field) {\n <div\n class=\"one-column\"\n role=\"gridcell\"\n [attr.aria-colindex]=\"$index + 1\"\n [attr.data-cell-id]=\"node.rowId | cellKey:column.field\"\n [class.one-column-pinned-left]=\"column.pinned === 'left'\"\n [class.one-column-pinned-right]=\"column.pinned === 'right'\"\n [class.one-column-pinned-edge]=\"column._pinnedEdge\"\n [style.left.px]=\"column.pinned === 'left' ? column._pinnedOffset : null\"\n [style.right.px]=\"column.pinned === 'right' ? column._pinnedOffset : null\"\n [style.width.px]=\"column?.width\"\n [style.min-width.px]=\"column?.minWidth\"\n [style.max-width.px]=\"column?.maxWidth\">\n\n @if (column?.cellRendererComponent) {\n <ng-container\n oneCellRendererComponent\n [cellRendererComponent]=\"column?.cellRendererComponent\"\n [params]=\"rendererParams(node, column)\">\n </ng-container>\n }\n @else if (column?.cellRenderer) {\n <div\n [ngStyle]=\"{ width: column.width + 'px', position: 'relative' }\"\n [innerHTML]=\"node.cellStates | cellStateRenderer:column.field\">\n </div>\n }\n @else {\n <div class=\"one-cell\"\n [class.align-content-left]=\"column?.alignContent === 'left'\"\n [class.align-content-center]=\"column?.alignContent === 'center'\"\n [class.align-content-right]=\"column?.alignContent === 'right'\"\n [ngClass]=\"colService.resolveCellClass(column, cellParams(node, column))\"\n [ngStyle]=\"colService.resolveCellStyle(column, cellParams(node, column))\">\n <div class=\"one-cell-text\">{{ (node.cellStates | cellStateRenderer:column.field) }}</div>\n </div>\n }\n </div>\n }\n </div>\n }\n</ng-template>\n\n<!-- Master Column Template -->\n<ng-template #cellTemplate let-node=\"node\" let-rowIndex=\"rowIndex\" let-column=\"column\" let-colIndex=\"colIndex\">\n <div\n class=\"one-column\"\n role=\"gridcell\"\n [attr.aria-colindex]=\"colIndex + 1\"\n [attr.tabindex]=\"isActiveCell(node, column) ? 0 : -1\"\n [class.one-cell-active]=\"isActiveCell(node, column)\"\n (focus)=\"onCellFocus(node, column)\"\n [attr.data-cell-id]=\"node.rowId | cellKey:column.field\"\n [class.one-column-pinned-left]=\"column.pinned === 'left'\"\n [class.one-column-pinned-right]=\"column.pinned === 'right'\"\n [class.one-column-pinned-edge]=\"column._pinnedEdge\"\n [style.left.px]=\"column.pinned === 'left' ? column._pinnedOffset : null\"\n [style.right.px]=\"column.pinned === 'right' ? column._pinnedOffset : null\"\n [style.width.px]=\"column?.width\"\n [style.min-width.px]=\"column?.minWidth\"\n [style.max-width.px]=\"column?.maxWidth\"\n [class.one-column-border-top]=\"masterDetail && nodes?.length > 0 && nodes[node.rowIndex - 1]?.expanded\"\n [class.one-cell-selected]=\"selectedCells | cellSelected:node.rowId:column.field\"\n [class.one-cell-invalid]=\"node.cellStates | cellInvalid:node.data[column.field]:column:node:allowedEdit:submitted\"\n (dblclick)=\"startEdit($event, node, column)\"\n (mousedown)=\"startSelection(node.rowId, column.field)\"\n (mouseenter)=\"extendSelection(node.rowId, column.field)\"\n (mouseup)=\"endSelection()\">\n\n <!-- One Grid Cell Option -->\n @if (node.cellOptions[column.field]) {\n <one-grid-cell-option-menu\n #contextOptionMenuRef\n [node]=\"node\"\n [column]=\"column\"\n [options]=\"column.cellOptionMenu\"\n (cellOptionMenuSelect)=\"cellOptionMenuSelected($event)\"\n (cellOptionMenuClose)=\"cellOptionMenuClosed()\"/>\n }\n\n <!-- Grid Cell Template -->\n @if(column?.cellRendererComponent) {\n <ng-container\n oneCellRendererComponent\n [cellRendererComponent]=\"column?.cellRendererComponent\"\n [params]=\"rendererParams(node, column)\">\n </ng-container>\n }\n @else if (node.editing[column.field]) {\n @if (column?.cellRendererParams?.inputType === 'select') {\n <!-- Cell Editing Select. Commits on change \u2014 picking an option\n is the whole edit \u2014 with blur as the keyboard fallback. -->\n <select class=\"one-cell-input\"\n name=\"{{ node.rowId + '' + column.field }}\"\n (change)=\"stopEditSelect(node, column, $event)\"\n (blur)=\"stopEditSelect(node, column, $event)\"\n (keydown.esc)=\"cancelEdit(node, column)\">\n @for (option of column?.cellRendererParams?.selectOptions ?? []; track $index) {\n <option [selected]=\"option.value === node.data[column.field]\">{{ option.label }}</option>\n }\n </select>\n }\n @else {\n <!-- Cell Editing Input -->\n <input class=\"one-cell-input\"\n name=\"{{ node.rowId + '' + column.field }}\"\n oneCellInputValidator\n [validationType]=\"column?.cellRendererParams?.inputType === 'number' ? 'number' : 'none'\"\n [placeholder]=\"column?.cellRendererParams?.placeholder\"\n [type]=\"column?.cellRendererParams?.inputType === 'number' ? 'text' : column?.cellRendererParams?.inputType\"\n [value]=\"node?.data[column?.field]\"\n [maxLength]=\"250\"\n (blur)=\"stopEdit(node, column, $event)\"\n (keydown.enter)=\"stopEdit(node, column, $event)\"\n (keydown.esc)=\"cancelEdit(node, column)\"\n />\n }\n }\n @else if (column?.cellRenderer) {\n <div\n [ngStyle]=\"{ width: column.width + 'px' , position: 'relative' }\"\n [innerHTML]=\"node.cellStates | cellStateRenderer:column.field\"\n [class.editable-active]=\"node.cellStates | cellEditable:column:node:cellService.editableFn:cellService.updatableFn:allowedEdit\">\n </div>\n }\n @else {\n <div class=\"one-cell\"\n [class.align-content-left]=\"column?.alignContent === 'left'\"\n [class.align-content-center]=\"column?.alignContent === 'center'\"\n [class.align-content-right]=\"column?.alignContent === 'right'\"\n [ngClass]=\"colService.resolveCellClass(column, cellParams(node, column))\"\n [ngStyle]=\"colService.resolveCellStyle(column, cellParams(node, column))\"\n [style.padding-left.px]=\"column.autoGroupField && node.level | cellLevelPadding:24\"\n [class.one-cell-allowed-edit-active]=\"node.cellStates | cellEditable:column:node:cellService.editableFn:cellService.updatableFn:allowedEdit\">\n\n <!-- Row Drag Handle -->\n @if (cellService.rowDragFn(column, node)) {\n <one-grid-row-drag-handle\n [node]=\"node\"\n [suppressedReason]=\"rowDragSuppressed\"\n (dragEnd)=\"onRowDragEnd($event)\"\n />\n }\n\n <!-- Cell Checkbox Selection -->\n @if (column?.checkboxSelection) {\n <one-grid-checkbox\n [node]=\"node\"\n [allowedEdit]=\"allowedEdit\"\n [api]=\"api\"\n (onRowSelection)=\"invokeRowActionSelection($event)\"\n />\n }\n\n <!-- Expand & Collapse Icon -->\n @if (((node?.group || detailRendererComponent) && column?.autoGroupField) || (masterDetail && node?.expandable && gridType === 'master' && column?.masterGroupField)) {\n <one-grid-cell-group-renderer\n [node]=\"node\"\n [masterDetail]=\"masterDetail\"\n [detailCellRendererParams]=\"detailCellRendererParams\"\n [detailRendererComponent]=\"detailRendererComponent\"\n (expansionChanged)=\"invokeExpansionChangedClick($event)\"\n />\n }\n\n @if(column?.cellRendererComponent) {\n <ng-container\n oneCellRendererComponent\n [cellRendererComponent]=\"column?.cellRendererComponent\"\n [params]=\"rendererParams(node, column)\">\n </ng-container>\n }\n @else {\n <!-- Cell Value OR Placeholder -->\n <div oneCellTextExpand class=\"one-cell-text\" [class.one-cell-placeholder]=\"node.cellStates[column.field]?.type === 'placeholder'\">\n {{ (node.cellStates | cellStateRenderer:column.field) }}\n </div>\n }\n\n <!-- Cell Action Buttons -->\n @if (column.cellRendererParams | cellActionButtonEnable) {\n <one-grid-row-action\n [ngStyle]=\"{ marginLeft: 'auto' }\"\n [column]=\"column\"\n [node]=\"node\"\n [allowedEdit]=\"allowedEdit\"\n [masterNode]=\"masterNode\"\n [masterDetail]=\"masterDetail\"\n [gridType]=\"gridType\"\n [context]=\"context\"\n [cellRendererParams]=\"column?.cellRendererParams\"\n (onRowGotoDetail)=\"invokeRowActionGotoDetail($event)\"\n (onRowAddNew)=\"invokeRowActionAddNew($event)\"\n (onRowView)=\"invokeRowActionView($event)\"\n (onRowLocation)=\"invokeRowActionLocation($event)\"\n (onRowDocument)=\"invokeRowActionDocument($event)\"\n (onRowCopy)=\"invokeRowActionCopy($event)\"\n (onRowDelete)=\"invokeRowActionDelete($event)\"\n (onRowGotoList)=\"invokeRowActionGotoList($event)\"\n (onRowEdit)=\"invokeRowActionEdit($event)\"\n (onRowPrint)=\"invokeRowActionPrint($event)\"\n (onRowHistory)=\"invokeRowActionHistory($event)\"\n (onRowOption)=\"invokeRowActionOption($event)\"\n (onRowLanguage)=\"invokeRowActionLanguage($event)\"\n (onRowCellOption)=\"invokeRowActionCellOption($event)\"\n />\n }\n </div>\n }\n </div>\n</ng-template>\n" }]
716
1126
  }], ctorParameters: () => [{ type: i1.OgColumnService }, { type: i2.OneGridCellService }, { type: i3.OneGridEventService }, { type: i4.OneGridRowDragService }, { type: i0.ChangeDetectorRef }], propDecorators: { bodyRef: [{
717
1127
  type: ViewChild,
718
1128
  args: ['bodyRef', { static: true }]
@@ -731,6 +1141,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
731
1141
  type: Input
732
1142
  }], submitted: [{
733
1143
  type: Input
1144
+ }], editType: [{
1145
+ type: Input
734
1146
  }], context: [{
735
1147
  type: Input
736
1148
  }], getRowId: [{
@@ -819,4 +1231,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
819
1231
  type: HostListener,
820
1232
  args: ['document:mouseup']
821
1233
  }] } });
822
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib25lLWdyaWQtYm9keS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9vbmUtZ3JpZC9zcmMvbGliL2NvbXBvbmVudHMvb25lLWdyaWQtYm9keS9vbmUtZ3JpZC1ib2R5LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL29uZS1ncmlkL3NyYy9saWIvY29tcG9uZW50cy9vbmUtZ3JpZC1ib2R5L29uZS1ncmlkLWJvZHkuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFpQix1QkFBdUIsRUFBcUIsU0FBUyxFQUFjLFlBQVksRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFxQixNQUFNLEVBQWdDLFNBQVMsRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFLdE8sT0FBTyxFQUFXLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUs3QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUN2RSxPQUFPLEVBQUUsVUFBVSxFQUFFLGFBQWEsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRTFFLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRWxFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHFDQUFxQyxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQVd6RSxNQUFNLE9BQU8sb0JBQW9CO0lBK0gvQixZQUNZLFVBQTJCLEVBQzNCLFdBQStCLEVBQ2pDLFlBQWlDLEVBQy9CLGNBQXdDLEVBQzFDLEdBQXNCO1FBSnBCLGVBQVUsR0FBVixVQUFVLENBQWlCO1FBQzNCLGdCQUFXLEdBQVgsV0FBVyxDQUFvQjtRQUNqQyxpQkFBWSxHQUFaLFlBQVksQ0FBcUI7UUFDL0IsbUJBQWMsR0FBZCxjQUFjLENBQTBCO1FBQzFDLFFBQUcsR0FBSCxHQUFHLENBQW1CO1FBOUhMLFlB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c0JBQWxCLE1BQU07Z0JBQ0csYUFBYTtzQkFBdEIsTUFBTTtnQkFDRyxhQUFhO3NCQUF0QixNQUFNO2dCQUNHLFdBQVc7c0JBQXBCLE1BQU07Z0JBQ0csYUFBYTtzQkFBdEIsTUFBTTtnQkFDRyxTQUFTO3NCQUFsQixNQUFNO2dCQUNHLFVBQVU7c0JBQW5CLE1BQU07Z0JBQ0csWUFBWTtzQkFBckIsTUFBTTtnQkFDRyxXQUFXO3NCQUFwQixNQUFNO2dCQUNHLGFBQWE7c0JBQXRCLE1BQU07Z0JBQ0csZUFBZTtzQkFBeEIsTUFBTTtnQkFDRyxjQUFjO3NCQUF2QixNQUFNO2dCQUNHLGtCQUFrQjtzQkFBM0IsTUFBTTtnQkFDRyxlQUFlO3NCQUF4QixNQUFNO2dCQUVHLGdCQUFnQjtzQkFBekIsTUFBTTtnQkFDRyxVQUFVO3NCQUFuQixNQUFNO2dCQUNHLGdCQUFnQjtzQkFBekIsTUFBTTtnQkFDRyxVQUFVO3NCQUFuQixNQUFNO2dCQXNVUCxlQUFlO3NCQURkLFlBQVk7dUJBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBa0IxQyxlQUFlO3NCQURkLFlBQVk7dUJBQUMsa0JBQWtCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEV2ZW50RW1pdHRlciwgSG9zdExpc3RlbmVyLCBJbnB1dCwgT25EZXN0cm95LCBPbkluaXQsIE91dHB1dCwgUXVlcnlMaXN0LCBUZW1wbGF0ZVJlZiwgVHlwZSwgVmlld0NoaWxkLCBWaWV3Q2hpbGRyZW4gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENlbGxTZWxlY3Rpb24sIE9uZUNlbGxQcmVzZW50YXRpb25QYXJhbXMsIE9uZUNlbGxSZW5kZXJlclBhcmFtcywgT25lQ29sdW1uRGVmIH0gZnJvbSAnLi4vLi4vY29yZS9tb2RlbHMvb25lLWNvbHVtbi1kZWYtdHlwZXMubW9kZWwnO1xuaW1wb3J0IHsgT25lQ2VsbFJlbmRlcmVyQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vY29yZS9tb2RlbHMvb25lLXRyZWUtZGF0YS5tb2RlbCc7XG5pbXBvcnQgeyBPbmVSb3dOb2RlIH0gZnJvbSAnLi4vLi4vY29yZS9pbnN0YW50cy9vbmUtcm93LW5vZGUuY2xhc3MnO1xuaW1wb3J0IHsgT25lR3JpZEFwaSB9IGZyb20gJy4uLy4uL2NvcmUvaW5zdGFudHMvb25lLWdyaWQtYXBpLmNsYXNzJztcbmltcG9ydCB7IFN1YmplY3QsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgT25lR3JpZEdldFJvd0lkUGFyYW1zLCBPbmVHcmlkUmVhZHlFdmVudCwgT25lR3JpZFJvd0FjdGlvbkV2ZW50LCBPbmVHcmlkVHlwZSB9IGZyb20gJy4uLy4uL2NvcmUvbW9kZWxzL29uZS1ncmlkLXR5cGVzLm1vZGVsJztcbmltcG9ydCB7IE9uZUdyaWRFdmVudFNlcnZpY2UgfSBmcm9tICcuLi8uLi9jb3JlL3NlcnZpY2VzL29uZS1ncmlkLWV2ZW50LnNlcnZpY2UnO1xuaW1wb3J0IHsgQ2VsbE9wdGlvbk1lbnVTZWxlY3RlZEV2ZW50LCBDb2x1bW5DaGFuZ2VkRXZlbnQsIEV4cGFuc2lvbkNoYW5nZWRFdmVudCwgUGlubmVkUm93RGF0YUNoYW5nZWRFdmVudCwgUm93RGF0YUNoYW5nZWRFdmVudCwgUm93T3JkZXJDaGFuZ2VkRXZlbnQsIFNlbGVjdGlvbkNoYW5nZWRFdmVudCwgU29ydENoYW5nZWRFdmVudCB9IGZyb20gJy4uLy4uL2NvcmUvbW9kZWxzL29uZS1ldmVudC10eXBlcy5tb2RlbCc7XG5pbXBvcnQgeyBPbmVEZXRhaWxDZWxsUmVuZGVyZXJQYXJhbXMgfSBmcm9tICcuLi8uLi9jb3JlL21vZGVscy9vbmUtbWFzdGVyLWRldGFpbC5tb2RlbCc7XG5pbXBvcnQgeyBDZWxsRWRpdGFibGVQaXBlIH0gZnJvbSAnLi4vLi4vY29yZS9waXBlcy9jZWxsLWVkaXRhYmxlLnBpcGUnO1xuaW1wb3J0IHsgZ2V0Q2VsbEtleSwgZ2V0RmllbGRWYWx1ZSB9IGZyb20gJy4uLy4uL2hlbHBlcnMvb25lLWNlbGwuaGVscGVyJztcbmltcG9ydCB7IE9uZUdyaWRDZWxsU2VydmljZSB9IGZyb20gJy4uLy4uL2NvcmUvc2VydmljZXMvb25lLWdyaWQtY2VsbC5zZXJ2aWNlJztcbmltcG9ydCB7IENka1ZpcnR1YWxTY3JvbGxWaWV3cG9ydCB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9zY3JvbGxpbmcnO1xuaW1wb3J0IHsgT2dDb2x1bW5TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29yZS9zZXJ2aWNlcy9vZy1jb2x1bW4uc2VydmljZSc7XG5pbXBvcnQgeyByZXNvbHZlQ29sdW1uV2lkdGggfSBmcm9tICcuLi8uLi9oZWxwZXJzL29uZS1jb2x1bW4tZGVmLmhlbHBlcic7XG5pbXBvcnQgeyBPbmVHcmlkUm93RHJhZ1NlcnZpY2UgfSBmcm9tICcuLi8uLi9jb3JlL3NlcnZpY2VzL29uZS1ncmlkLXJvdy1kcmFnLnNlcnZpY2UnO1xuaW1wb3J0IHsgT25lUm93RHJhZ0V2ZW50LCBPbmVSb3dEcmFnU3RhdGUsIE9uZVJvd0RyYWdTdXBwcmVzc2VkUmVhc29uIH0gZnJvbSAnLi4vLi4vY29yZS9tb2RlbHMvb25lLXJvdy1kcmFnLm1vZGVsJztcblxuQENvbXBvbmVudCh7XG4gIHN0YW5kYWxvbmU6IGZhbHNlLFxuICBzZWxlY3RvcjogJ29uZS1ncmlkLWJvZHknLFxuICB0ZW1wbGF0ZVVybDogJy4vb25lLWdyaWQtYm9keS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsOiAnLi9vbmUtZ3JpZC1ib2R5LmNvbXBvbmVudC5zY3NzJyxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIE9uZUdyaWRCb2R5Q29tcG9uZW50PFQ+IGltcGxlbWVudHMgT25Jbml0LCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuXG4gIC8qKlxuICAgKiBDb3JlIFByb3BlcnRpZXNcbiAgICovXG4gIEBWaWV3Q2hpbGQoJ2JvZHlSZWYnLCB7IHN0YXRpYzogdHJ1ZSB9KSBib2R5UmVmITogRWxlbWVudFJlZjtcbiAgQElucHV0KHsgcmVxdWlyZWQ6IHRydWUgfSkgcm93RGF0YTogVFtdID0gW107XG4gIEBJbnB1dCgpIHJvd051bWJlcjogYm9vbGVhbjtcbiAgQElucHV0KCkgYXBpITogT25lR3JpZEFwaTxUPjtcbiAgQElucHV0KCkgcGFnaW5hdGlvbjogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBhbGxvd2VkRWRpdDogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCgpIGVuYWJsZUdyb3VwQ29sdW1uRGVmczogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBzdWJtaXR0ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgY29udGV4dDogYW55ID0gbnVsbDtcbiAgQElucHV0KCkgZ2V0Um93SWQ6IChwYXJhbXM6IE9uZUdyaWRHZXRSb3dJZFBhcmFtczxUPikgPT4gc3RyaW5nO1xuICBASW5wdXQoeyByZXF1aXJlZDogdHJ1ZSB9KSBncmlkQ29weSQhOiBTdWJqZWN0PENsaXBib2FyZEV2ZW50PjtcblxuICAvKipcbiAgICogUGlubmVkIHJvd3MgYXJlIGJvdW5kIG9ubHkgc28gdGhlIGNvbXBvbmVudCByZS1yZW5kZXJzIHdoZW4gdGhleSBjaGFuZ2U7XG4gICAqIHRoZSBub2RlcyB0aGVtc2VsdmVzIGNvbWUgZnJvbSB0aGUgQVBJLCB3aGljaCBvd25zIHRoZW0uXG4gICAqL1xuICBASW5wdXQoKSBwaW5uZWRUb3BSb3dEYXRhOiBUW10gPSBbXTtcbiAgQElucHV0KCkgcGlubmVkQm90dG9tUm93RGF0YTogVFtdID0gW107XG5cbiAgLyoqXG4gICAqIFRoZSBwaW5uZWQgcm93IGNvbnRhaW5lcnMgc2l0IG91dHNpZGUgdGhlIHNjcm9sbCB2aWV3cG9ydCwgc28gdGhleSBoYXZlIHRvXG4gICAqIGJlIHRvbGQgdGhlIGhvcml6b250YWwgb2Zmc2V0IOKAlCB0aGUgc2FtZSBhcnJhbmdlbWVudCB0aGUgaGVhZGVyIHVzZXMuXG4gICAqL1xuICBAVmlld0NoaWxkcmVuKCdwaW5uZWRWaWV3cG9ydCcpIHByaXZhdGUgcGlubmVkVmlld3BvcnRzPzogUXVlcnlMaXN0PEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+PjtcblxuICBwcm90ZWN0ZWQgcGlubmVkVG9wTm9kZXM6IE9uZVJvd05vZGU8VD5bXSA9IFtdO1xuICBwcm90ZWN0ZWQgcGlubmVkQm90dG9tTm9kZXM6IE9uZVJvd05vZGU8VD5bXSA9IFtdO1xuICBAVmlld0NoaWxkKENka1ZpcnR1YWxTY3JvbGxWaWV3cG9ydCkgdmlld3BvcnQhOiBDZGtWaXJ0dWFsU2Nyb2xsVmlld3BvcnQ7XG5cbiAgcHJvdGVjdGVkIGNvbHVtbkRlZnM6IE9uZUNvbHVtbkRlZjxUPltdID0gW107XG4gIHByb3RlY3RlZCBjZWxsUmVuZGVyZXI6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvKipcbiAgICogTWFzdGVyIERldGFpbCBQcm9wZXJ0aWVzXG4gICAqL1xuICBASW5wdXQoKSBncmlkVHlwZTogT25lR3JpZFR5cGUgPSAnc2ltcGxlJztcbiAgQElucHV0KCkgbWFzdGVyRGV0YWlsOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIG1hc3Rlck5vZGU6IE9uZVJvd05vZGU8VD4gPSBudWxsO1xuICAvLyBASW5wdXQoKSBkZXRhaWxSb3dIZWlnaHQ6IG51bWJlciA9IG51bGw7XG4gIC8vIEBJbnB1dCgpIGRldGFpbFJvd0F1dG9IZWlnaHQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgZGV0YWlsUm93TWF4SGVpZ2h0OiBudW1iZXIgPSBudWxsO1xuICBASW5wdXQoKSBkZXRhaWxDZWxsUmVuZGVyZXJQYXJhbXM6IE9uZURldGFpbENlbGxSZW5kZXJlclBhcmFtcztcbiAgQElucHV0KCkgZGV0YWlsR3JpZFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjx1bmtub3duPiA9IG51bGw7XG4gIEBJbnB1dCgpIGRldGFpbFJlbmRlcmVyQ29tcG9uZW50OiBUeXBlPE9uZUNlbGxSZW5kZXJlckNvbXBvbmVudD47XG5cbiAgLyoqXG4gICAqIFRyZWUgRGF0YSBQcm9wZXJ0aWVzXG4gICAqL1xuICBASW5wdXQoKSB0cmVlRGF0YTogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSB0cmVlRGF0YUNoaWxkcmVuRmllbGQ6IHN0cmluZztcbiAgQElucHV0KCkgYXV0b0dyb3VwQ29sdW1uRGVmOiBPbmVDb2x1bW5EZWY8VD47XG4gIEBJbnB1dCgpIGdyb3VwRGVmYXVsdEV4cGFuZGVkOiBudW1iZXIgPSAtMTsgLy8gSXQncyB3b3JrIHdpdGggbWFzdGVyIGRldGFpbCBhbHNvXG5cbiAgLyoqXG4gICAqIFBhc3NpbmcgUm93IEFjdGlvbiBFdmVudHMgdG8gUGFyZW50XG4gICAqL1xuICBAT3V0cHV0KCkgb25Sb3dHb3RvRGV0YWlsID0gbmV3IEV2ZW50RW1pdHRlcjxPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4+KCk7XG4gIEBPdXRwdXQoKSBvblJvd0FkZE5ldyA9IG5ldyBFdmVudEVtaXR0ZXI8T25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+PigpO1xuICBAT3V0cHV0KCkgb25Sb3dWaWV3ID0gbmV3IEV2ZW50RW1pdHRlcjxPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4+KCk7XG4gIEBPdXRwdXQoKSBvblJvd0NvcHkgPSBuZXcgRXZlbnRFbWl0dGVyPE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIG9uUm93TG9jYXRpb24gPSBuZXcgRXZlbnRFbWl0dGVyPE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIG9uUm93RG9jdW1lbnQgPSBuZXcgRXZlbnRFbWl0dGVyPE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIG9uUm93RGVsZXRlID0gbmV3IEV2ZW50RW1pdHRlcjxPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4+KCk7XG4gIEBPdXRwdXQoKSBvblJvd0dvdG9MaXN0ID0gbmV3IEV2ZW50RW1pdHRlcjxPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4+KCk7XG4gIEBPdXRwdXQoKSBvblJvd0VkaXQgPSBuZXcgRXZlbnRFbWl0dGVyPE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIG9uUm93UHJpbnQgPSBuZXcgRXZlbnRFbWl0dGVyPE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIG9uUm93SGlzdG9yeSA9IG5ldyBFdmVudEVtaXR0ZXI8T25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+PigpO1xuICBAT3V0cHV0KCkgb25Sb3dPcHRpb24gPSBuZXcgRXZlbnRFbWl0dGVyPE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIG9uUm93TGFuZ3VhZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIG9uUm93Q2VsbE9wdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8T25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+PigpO1xuICBAT3V0cHV0KCkgb25Sb3dTZWxlY3Rpb24gPSBuZXcgRXZlbnRFbWl0dGVyPE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIG9uU2hpZnREb3VibGVDbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8T25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+PigpO1xuICBAT3V0cHV0KCkgcm93Q291bnRDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG5cbiAgQE91dHB1dCgpIGV4cGFuc2lvbkNoYW5nZWQgPSBuZXcgRXZlbnRFbWl0dGVyPEV4cGFuc2lvbkNoYW5nZWRFdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIGJvZHlTY3JvbGwgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcbiAgQE91dHB1dCgpIGNlbGxPcHRpb25TZWxlY3QgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgQE91dHB1dCgpIHJvd0RyYWdFbmQgPSBuZXcgRXZlbnRFbWl0dGVyPE9uZVJvd0RyYWdFdmVudDxUPj4oKTtcblxuICAvKipcbiAgICogU2VsZWN0aW9uIFJhbmdlIFZhcmlhYmxlc1xuICAgKi9cbiAgcHJvdGVjdGVkIHJvd1dpZHRoOiBudW1iZXIgPSAwO1xuICBwcm90ZWN0ZWQgbm9kZXM6IE9uZVJvd05vZGU8VD5bXSA9IFtdO1xuXG4gIC8qKlxuICAgKiBSb3cgZHJhZyBzdGF0ZSwgbWlycm9yZWQgZnJvbSB0aGUgc2VydmljZSBzbyB0aGUgdGVtcGxhdGUgY2FuIHJlYWQgaXRcbiAgICogc3luY2hyb25vdXNseS4gYG51bGxgIHdoZW5ldmVyIG5vIGRyYWcgaXMgaW4gZmxpZ2h0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGRyYWdTdGF0ZTogT25lUm93RHJhZ1N0YXRlIHwgbnVsbCA9IG51bGw7XG4gIHByb3RlY3RlZCBkcmFnQW5ub3VuY2VtZW50ID0gJyc7XG4gIHByb3RlY3RlZCByb3dEcmFnU3VwcHJlc3NlZDogT25lUm93RHJhZ1N1cHByZXNzZWRSZWFzb24gfCBudWxsID0gbnVsbDtcbiAgcHJvdGVjdGVkIHNlbGVjdGVkQ2VsbHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgcHJpdmF0ZSBpc01vdXNlRG93biA9IGZhbHNlO1xuICBwcml2YXRlIHN0YXJ0Q2VsbDogQ2VsbFNlbGVjdGlvbiA9IG51bGw7XG4gIHByaXZhdGUgbGFzdFNjcm9sbExlZnQgPSAwO1xuICBwcml2YXRlIGNlbGxFZGl0YWJsZVBpcGUgPSBuZXcgQ2VsbEVkaXRhYmxlUGlwZSgpO1xuICBwcml2YXRlIHN1YnNjcmlwdGlvbnMgPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG5cbiAgcHJvdGVjdGVkIGNlbGxSZW5kZXJlclBhcmFtczogT25lQ2VsbFJlbmRlcmVyUGFyYW1zID0ge1xuICAgICAgZ290b0RldGFpbEJ1dHRvblN0YXR1czogMSxcbiAgICAgIGFkZE5ld0J1dHRvblN0YXR1czogMSxcbiAgICAgIHZpZXdCdXR0b25TdGF0dXM6IDEsXG4gICAgICBsb2NhdGlvbkJ1dHRvblN0YXR1czogMSxcbiAgICAgIGRvY3VtZW50QnV0dG9uU3RhdHVzOiAxLFxuICAgICAgY29weUJ1dHRvblN0YXR1czogMSxcbiAgICAgIGRlbGV0ZUJ1dHRvblN0YXR1czogMSxcbiAgICAgIGdvdG9MaXN0QnV0dG9uU3RhdHVzOiAxLFxuICAgICAgb3B0aW9uQnV0dG9uU3RhdHVzOiAxLFxuICAgICAgbGFuZ3VhZ2VCdXR0b25TdGF0dXM6IDEsXG4gICAgICBlZGl0QnV0dG9uU3RhdHVzOiAxLFxuICAgICAgcHJpbnRCdXR0b25TdGF0dXM6IDEsXG4gICAgICBoaXN0b3J5QnV0dG9uU3RhdHVzOiAxLFxuICB9XG5cbiAgLyoqXG4gICAqIFZpcnR1YWwgU2Nyb2xsIFByb3BlcnRpZXNcbiAgICovXG4gIHByb3RlY3RlZCBpdGVtU2l6ZTogbnVtYmVyID0gMzA7XG4gIHByb3RlY3RlZCBtaW5CdWZmZXJQeDogbnVtYmVyID0gMjAwO1xuICBwcm90ZWN0ZWQgbWF4QnVmZmVyUHg6IG51bWJlciA9IDQwMDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgY29sU2VydmljZTogT2dDb2x1bW5TZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBjZWxsU2VydmljZTogT25lR3JpZENlbGxTZXJ2aWNlLFxuICAgIHByaXZhdGUgZXZlbnRTZXJ2aWNlOiBPbmVHcmlkRXZlbnRTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCByb3dEcmFnU2VydmljZTogT25lR3JpZFJvd0RyYWdTZXJ2aWNlPFQ+LFxuICAgIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZlxuICApIHsgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuXG4gICAgLyoqXG4gICAgICogTGlzdGVuIEdyaWQgQ29weSBFdmVudFxuICAgICAqL1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQodGhpcy5ncmlkQ29weSQuc3Vic2NyaWJlKChldmVudDogQ2xpcGJvYXJkRXZlbnQpID0+IHtcblxuICAgICAgdGhpcy5vbkdyaWRDb3B5KGV2ZW50KTtcbiAgICB9KSk7XG5cbiAgICAvKipcbiAgICAgKiBSb3cgZHJhZ1xuICAgICAqXG4gICAgICogVGhlIHNlcnZpY2Ugb3ducyB0aGUgZ2VzdHVyZTsgdGhlIGJvZHkgb25seSByZW5kZXJzIGl0IGFuZCBsZW5kcyBpdCB0aGVcbiAgICAgKiB2aWV3cG9ydCwgdGhlIHJvdyBoZWlnaHQgYW5kIGEgd2F5IHRvIGFwcGx5IGEgbW92ZS4gVGhlIHN1cHByZXNzaW9uXG4gICAgICogcmVhc29uIGlzIHJlLXJlYWQgb24gZXZlcnkgZXZlbnQgdGhhdCBjb3VsZCBjaGFuZ2UgdGhlIG9yZGVyLCBzbyB0aGVcbiAgICAgKiBoYW5kbGUgZGlzYWJsZXMgaXRzZWxmIHRoZSBtb21lbnQgYSBzb3J0IG9yIGZpbHRlciBpcyBhcHBsaWVkLlxuICAgICAqL1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQodGhpcy5yb3dEcmFnU2VydmljZS5zdGF0ZSQuc3Vic2NyaWJlKChzdGF0ZSkgPT4ge1xuXG4gICAgICB0aGlzLmRyYWdTdGF0ZSA9IHN0YXRlO1xuXG4gICAgICB0aGlzLnVwZGF0ZURyb3BJbmRpY2F0b3IoKTtcblxuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfSkpO1xuXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZCh0aGlzLnJvd0RyYWdTZXJ2aWNlLmFubm91bmNlbWVudCQuc3Vic2NyaWJlKChtZXNzYWdlKSA9PiB7XG5cbiAgICAgIHRoaXMuZHJhZ0Fubm91bmNlbWVudCA9IG1lc3NhZ2U7XG5cbiAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH0pKTtcblxuICAgIC8qKlxuICAgICAqIExpc3RlbiBDb2x1bW4gQ2hhbmdlZCBFdmVudFxuICAgICAqL1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQodGhpcy5ldmVudFNlcnZpY2UuYWRkRXZlbnRMaXN0ZW5lcignY29sdW1uQ2hhbmdlZCcsIChwYXlsb2FkOiBDb2x1bW5DaGFuZ2VkRXZlbnQpID0+IHtcblxuICAgICAgdGhpcy5jb2x1bW5EZWZzID0gWy4uLnBheWxvYWQuY29sdW1uc10gYXMgT25lQ29sdW1uRGVmW107XG5cbiAgICAgIHRoaXMuY2VsbFJlbmRlcmVyID0gdGhpcy5jb2x1bW5EZWZzLnNvbWUoY29sID0+IGNvbC5jZWxsUmVuZGVyZXJDb21wb25lbnQpO1xuXG4gICAgICB0aGlzLnJvd1dpZHRoID0gdGhpcy5jb2x1bW5EZWZzLnJlZHVjZSgoc3VtLCBjb2wpID0+IHN1bSArIHJlc29sdmVDb2x1bW5XaWR0aChjb2wpLCAwKTtcblxuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfSkpO1xuXG4gICAgLyoqXG4gICAgICogTGlzdGVuIFJvdyBEYXRhIENoYW5nZWQgRXZlbnRcbiAgICAgKi9cbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKHRoaXMuZXZlbnRTZXJ2aWNlLmFkZEV2ZW50TGlzdGVuZXIoJ3Jvd0RhdGFDaGFuZ2VkJywgKHsgbm9kZXMgfTogUm93RGF0YUNoYW5nZWRFdmVudDxUPikgPT4ge1xuXG4gICAgICB0aGlzLnJvd0NvdW50Q2hhbmdlZC5lbWl0KG5vZGVzPy5sZW5ndGggPz8gMCk7XG5cbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuXG4gICAgICAgIHRoaXMudmlld3BvcnQ/LmNoZWNrVmlld3BvcnRTaXplKCk7XG5cbiAgICAgICAgdGhpcy5zZXRWaXJ0dWFsU2Nyb2xsKG5vZGVzPy5sZW5ndGgpO1xuXG4gICAgICAgIGlmICh0aGlzLm1hc3RlckRldGFpbCkge1xuXG4gICAgICAgICAgdGhpcy5ub2RlcyA9IG5vZGVzLm1hcCgobm9kZTogT25lUm93Tm9kZSkgPT4ge1xuXG4gICAgICAgICAgICBpZiAobm9kZS5sZWFmICYmIHRoaXMuZGV0YWlsUmVuZGVyZXJDb21wb25lbnQpIHtcblxuICAgICAgICAgICAgICBub2RlLmRldGFpbFJlbmRlcmVyQ29tcG9uZW50ID0gdGhpcy5kZXRhaWxSZW5kZXJlckNvbXBvbmVudDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRGV0YWlsIHJvd3MgY2FuIHN0aWxsIGJlIGluIGZsaWdodCB3aGVuIGEgcm93IGlzIGV4cGFuZGVkLCBhbmRcbiAgICAgICAgICAgIC8vIHNwcmVhZGluZyBudWxsIHRocm93cy4gTm90aGluZyB0byByZS1zZWVkIHVudGlsIHRoZXkgYXJyaXZlLlxuICAgICAgICAgICAgaWYgKG5vZGUuZXhwYW5kZWQgJiYgbm9kZS5kZXRhaWxSb3dEYXRhKSB7XG5cbiAgICAgICAgICAgICAgdGhpcy5hcGkuc2V0RGV0YWlsUm93RGF0YShub2RlLCBbLi4ubm9kZS5kZXRhaWxSb3dEYXRhXSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBub2RlO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICB0aGlzLm5vZGVzID0gbm9kZXMgYXMgT25lUm93Tm9kZTxUPltdO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5yZWZyZXNoUm93RHJhZ1N1cHByZXNzZWQoKTtcblxuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuICAgIH0pKTtcblxuXG4gICAgLyoqXG4gICAgICogTGlzdGVuIFBpbm5lZCBSb3cgRGF0YSBDaGFuZ2VkIEV2ZW50XG4gICAgICovXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZCh0aGlzLmV2ZW50U2VydmljZS5hZGRFdmVudExpc3RlbmVyKCdwaW5uZWRSb3dEYXRhQ2hhbmdlZCcsICh7IHNpZGUsIG5vZGVzIH06IFBpbm5lZFJvd0RhdGFDaGFuZ2VkRXZlbnQ8VD4pID0+IHtcblxuICAgICAgaWYgKHNpZGUgPT09ICd0b3AnKSB7XG5cbiAgICAgICAgdGhpcy5waW5uZWRUb3BOb2RlcyA9IG5vZGVzIGFzIE9uZVJvd05vZGU8VD5bXTtcblxuICAgICAgfSBlbHNlIHtcblxuICAgICAgICB0aGlzLnBpbm5lZEJvdHRvbU5vZGVzID0gbm9kZXMgYXMgT25lUm93Tm9kZTxUPltdO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9KSk7XG5cbiAgICAvKipcbiAgICAgKiBMaXN0ZW4gU29ydCBDaGFuZ2VkIEV2ZW50XG4gICAgICovXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZCh0aGlzLmV2ZW50U2VydmljZS5hZGRFdmVudExpc3RlbmVyKCdzb3J0Q2hhbmdlZCcsICh7IG5vZGVzIH06IFNvcnRDaGFuZ2VkRXZlbnQpID0+IHtcblxuICAgICAgdGhpcy5ub2RlcyA9IG5vZGVzIGFzIE9uZVJvd05vZGU8VD5bXTtcblxuICAgICAgLy8gU29ydGluZyB0YWtlcyBvd25lcnNoaXAgb2YgdGhlIG9yZGVyIGF3YXkgZnJvbSB0aGUgdXNlciwgc28gdGhlIGhhbmRsZXNcbiAgICAgIC8vIGhhdmUgdG8gZGlzYWJsZSBpbiB0aGUgc2FtZSBmcmFtZSB0aGUgcm93cyByZS1zb3J0LlxuICAgICAgdGhpcy5yZWZyZXNoUm93RHJhZ1N1cHByZXNzZWQoKTtcblxuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfSkpO1xuXG4gICAgLyoqXG4gICAgICogTGlzdGVuIFJvdyBPcmRlciBDaGFuZ2VkIEV2ZW50XG4gICAgICpcbiAgICAgKiBEZWxpYmVyYXRlbHkgbm90IGZvbGRlZCBpbnRvIGByb3dEYXRhQ2hhbmdlZGA6IHRoYXQgcGF0aCBkZWZlcnMgYSBmcmFtZVxuICAgICAqIGFuZCByZS1zZWVkcyBkZXRhaWwgcm93cywgd2hpY2ggaXMgcmlnaHQgZm9yIGEgZGF0YSBsb2FkIGFuZCBmYXIgdG9vIG11Y2hcbiAgICAgKiBmb3IgYSBtb3ZlLiBBIHJlb3JkZXIgaXMgdGhlIHNhbWUgbm9kZXMgaW4gYSBkaWZmZXJlbnQgb3JkZXIuXG4gICAgICovXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZCh0aGlzLmV2ZW50U2VydmljZS5hZGRFdmVudExpc3RlbmVyKCdyb3dPcmRlckNoYW5nZWQnLCAoeyBub2RlcyB9OiBSb3dPcmRlckNoYW5nZWRFdmVudDxUPikgPT4ge1xuXG4gICAgICB0aGlzLm5vZGVzID0gWy4uLm5vZGVzXSBhcyBPbmVSb3dOb2RlPFQ+W107XG5cbiAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH0pKTtcblxuICAgIC8qKlxuICAgICAqIExpc3RlbiBDZWxsIFN0YXRlIENoYW5nZWQgRXZlbnRcbiAgICAgKlxuICAgICAqIFRoZSBib2R5IHJlbmRlcnMgT25QdXNoLCBzbyByZWdlbmVyYXRpbmcgYSByb3cncyBjZWxsIHN0YXRlIGlzIGludmlzaWJsZVxuICAgICAqIHVudGlsIHNvbWV0aGluZyBtYXJrcyB0aGUgYm9keSBkaXJ0eS4gVGhpcyBpcyB0aGF0IHNvbWV0aGluZy5cbiAgICAgKi9cbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKHRoaXMuZXZlbnRTZXJ2aWNlLmFkZEV2ZW50TGlzdGVuZXIoJ2NlbGxTdGF0ZUNoYW5nZWQnLCAoKSA9PiB7XG5cbiAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH0pKTtcblxuICAgIC8qKlxuICAgICAqIExpc3RlbiBTZWxlY3Rpb24gQ2hhbmdlZCBFdmVudFxuICAgICAqL1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQodGhpcy5ldmVudFNlcnZpY2UuYWRkRXZlbnRMaXN0ZW5lcignc2VsZWN0aW9uQ2hhbmdlZCcsIChwYXlsb2FkOiBTZWxlY3Rpb25DaGFuZ2VkRXZlbnQ8VD4pID0+IHtcblxuICAgICAgaWYgKHBheWxvYWQpIHtcblxuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH1cbiAgICB9KSk7XG4gIH1cblxuICBvbkdyaWRSZWFkeShwYXJhbXM6IE9uZUdyaWRSZWFkeUV2ZW50KSB7XG5cbiAgICBwYXJhbXMuYXBpLnNldFJvd0RhdGEodGhpcy5tYXN0ZXJOb2RlPy5kZXRhaWxSb3dEYXRhID8/IFtdKTtcbiAgfVxuXG4gIG9uQm9keVNjcm9sbChldmVudDogRXZlbnQpIHtcblxuICAgIGNvbnN0IHNjcm9sbExlZnQgPSAoZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50KS5zY3JvbGxMZWZ0O1xuXG4gICAgaWYgKHNjcm9sbExlZnQgIT09IHRoaXMubGFzdFNjcm9sbExlZnQpIHtcblxuICAgICAgdGhpcy5sYXN0U2Nyb2xsTGVmdCA9IHNjcm9sbExlZnQ7XG5cbiAgICAgIHRoaXMuc3luY1Bpbm5lZFJvd3Moc2Nyb2xsTGVmdCk7XG5cbiAgICAgIHRoaXMuYm9keVNjcm9sbC5lbWl0KHNjcm9sbExlZnQpO1xuXG4gICAgICAvLyBUaGUgaW5kaWNhdG9yIGlzIGNsaXBwZWQgdG8gdGhlIHJvdyBjb250ZW50LCB3aGljaCBtb3ZlcyBzaWRld2F5cyB0b28uXG4gICAgICBpZiAodGhpcy5kcmFnU3RhdGUpIHtcblxuICAgICAgICB0aGlzLnVwZGF0ZURyb3BJbmRpY2F0b3IoKTtcblxuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFZlcnRpY2FsOiB0aGUgZHJvcCBpbmRpY2F0b3IgaXMgYW5jaG9yZWQgdG8gdGhlIGJvZHksIG5vdCB0aGUgY29udGVudCwgc29cbiAgICAvLyBpdCBoYXMgdG8gYmUgcmVwb3NpdGlvbmVkIGFzIHRoZSByb3dzIG1vdmUgYmVuZWF0aCBpdCDigJQgd2hpY2ggdGhleSBkbyBvblxuICAgIC8vIHRoZWlyIG93biBkdXJpbmcgYXV0by1zY3JvbGwsIHdpdGggdGhlIHBvaW50ZXIgc3RhbmRpbmcgc3RpbGwuXG4gICAgaWYgKHRoaXMuZHJhZ1N0YXRlKSB7XG5cbiAgICAgIHRoaXMudXBkYXRlRHJvcEluZGljYXRvcigpO1xuXG4gICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogS2VlcCB0aGUgcGlubmVkIHJvd3MgaW4gc3RlcCB3aXRoIHRoZSBib2R5J3MgaG9yaXpvbnRhbCBwb3NpdGlvbi5cbiAgICpcbiAgICogQXNzaWduZWQgcmF0aGVyIHRoYW4gdHJhbnNmb3JtZWQsIGZvciB0aGUgc2FtZSByZWFzb24gYXMgdGhlIGhlYWRlcjogc3RpY2t5XG4gICAqIHBvc2l0aW9uaW5nIGZvciBwaW5uZWQgKmNvbHVtbnMqIGhhcyB0byByZXNvbHZlIGFnYWluc3QgYSByZWFsIHNjcm9sbHBvcnQsXG4gICAqIGFuZCBhIHRyYW5zZm9ybWVkIGFuY2VzdG9yIGlzIG5vdCBvbmUuIFBpbm5lZCByb3dzIGFuZCBwaW5uZWQgY29sdW1uc1xuICAgKiB0aGVyZWZvcmUgY29tcG9zZSDigJQgYSBmcm96ZW4gY29ybmVyIGNlbGwgc3RheXMgZnJvemVuIG9uIGJvdGggYXhlcy5cbiAgICovXG4gIHByaXZhdGUgc3luY1Bpbm5lZFJvd3Moc2Nyb2xsTGVmdDogbnVtYmVyKTogdm9pZCB7XG5cbiAgICB0aGlzLnBpbm5lZFZpZXdwb3J0cz8uZm9yRWFjaCh2aWV3cG9ydCA9PiAodmlld3BvcnQubmF0aXZlRWxlbWVudC5zY3JvbGxMZWZ0ID0gc2Nyb2xsTGVmdCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYWNrIFJlbmRlcmluZyBSb3cgTm9kZSBCeSBSb3cgSURcbiAgICovXG4gIHRyYWNrQnlSb3dJZChpbmRleDogbnVtYmVyLCBub2RlOiBPbmVSb3dOb2RlPFQ+KTogc3RyaW5nIHtcblxuICAgIHJldHVybiBub2RlLnJvd0lkO1xuICB9XG5cbiAgLyoqXG4gICAqIENlbGwgU2VsZWN0aW9uIFJhbmdlIEZlYXR1cmVcbiAgICovXG4gIHN0YXJ0U2VsZWN0aW9uKHJvd0lkOiBzdHJpbmcsIGZpZWxkOiBzdHJpbmcpIHtcblxuICAgIHRoaXMuaXNNb3VzZURvd24gPSB0cnVlO1xuICAgIHRoaXMuc3RhcnRDZWxsID0geyByb3dJZCwgZmllbGQgfTtcbiAgICB0aGlzLnNlbGVjdGVkQ2VsbHMuY2xlYXIoKTtcbiAgICB0aGlzLnNlbGVjdGVkQ2VsbHMgPSBuZXcgU2V0KHRoaXMuc2VsZWN0ZWRDZWxscykuYWRkKGdldENlbGxLZXkocm93SWQsIGZpZWxkKSk7XG4gIH1cblxuICBleHRlbmRTZWxlY3Rpb24ocm93SWQ6IHN0cmluZywgZmllbGQ6IHN0cmluZykge1xuXG4gICAgaWYgKCF0aGlzLmlzTW91c2VEb3duIHx8ICF0aGlzLnN0YXJ0Q2VsbCkgcmV0dXJuO1xuXG4gICAgY29uc3Qgcm93cyA9IHRoaXMubm9kZXM7IC8vIGFscmVhZHkgc29ydGVkXG4gICAgY29uc3Qgc3RhcnRSb3dJbmRleCA9IHJvd3MuZmluZEluZGV4KHIgPT4gci5yb3dJZCA9PT0gdGhpcy5zdGFydENlbGwhLnJvd0lkKTtcbiAgICBjb25zdCBlbmRSb3dJbmRleCAgID0gcm93cy5maW5kSW5kZXgociA9PiByLnJvd0lkID09PSByb3dJZCk7XG5cbiAgICBpZiAoc3RhcnRSb3dJbmRleCA9PT0gLTEgfHwgZW5kUm93SW5kZXggPT09IC0xKSByZXR1cm47XG5cbiAgICBjb25zdCBjb2xTdGFydEluZGV4ID0gdGhpcy5jb2x1bW5EZWZzLmZpbmRJbmRleChjID0+IGMuZmllbGQgPT09IHRoaXMuc3RhcnRDZWxsIS5maWVsZCk7XG4gICAgY29uc3QgY29sRW5kSW5kZXggICA9IHRoaXMuY29sdW1uRGVmcy5maW5kSW5kZXgoYyA9PiBjLmZpZWxkID09PSBmaWVsZCk7XG5cbiAgICBpZiAoY29sU3RhcnRJbmRleCA9PT0gLTEgfHwgY29sRW5kSW5kZXggPT09IC0xKSByZXR1cm47XG5cbiAgICBjb25zdCByb3dTdGFydCA9IE1hdGgubWluKHN0YXJ0Um93SW5kZXgsIGVuZFJvd0luZGV4KTtcbiAgICBjb25zdCByb3dFbmQgICA9IE1hdGgubWF4KHN0YXJ0Um93SW5kZXgsIGVuZFJvd0luZGV4KTtcbiAgICBjb25zdCBjb2xTdGFydCA9IE1hdGgubWluKGNvbFN0YXJ0SW5kZXgsIGNvbEVuZEluZGV4KTtcbiAgICBjb25zdCBjb2xFbmQgICA9IE1hdGgubWF4KGNvbFN0YXJ0SW5kZXgsIGNvbEVuZEluZGV4KTtcblxuICAgIGNvbnN0IG5leHQgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICAgIGZvciAobGV0IHIgPSByb3dTdGFydDsgciA8PSByb3dFbmQ7IHIrKykge1xuICAgICAgZm9yIChsZXQgYyA9IGNvbFN0YXJ0OyBjIDw9IGNvbEVuZDsgYysrKSB7XG4gICAgICAgIG5leHQuYWRkKGdldENlbGxLZXkocm93c1tyXS5yb3dJZCwgdGhpcy5jb2x1bW5EZWZzW2NdLmZpZWxkKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5zZWxlY3RlZENlbGxzID0gbmV4dDtcbiAgfVxuXG5cbiAgZW5kU2VsZWN0aW9uKCkge1xuXG4gICAgdGhpcy5pc01vdXNlRG93biA9IGZhbHNlO1xuICAgIHRoaXMuc3RhcnRDZWxsID0gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhciBDZWxscyBTZWxlY3RlZFxuICAgKi9cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6Y2xpY2snLCBbJyRldmVudCddKVxuICBvbkRvY3VtZW50Q2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcblxuICAgIGlmICh0aGlzLmJvZHlSZWY/Lm5hdGl2ZUVsZW1lbnQpIHtcblxuICAgICAgY29uc3QgY2xpY2tlZEluc2lkZSA9IHRoaXMuYm9keVJlZi5uYXRpdmVFbGVtZW50LmNvbnRhaW5zKGV2ZW50LnRhcmdldCk7XG5cbiAgICAgIGlmICghY2xpY2tlZEluc2lkZSkge1xuXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRDZWxscy5jbGVhcigpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZWxlY3Rpb24gUmFuZ2UgRXZlbnQgSG9sZCBNb3VzZSBDbGlja1xuICAgKi9cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6bW91c2V1cCcpXG4gIG9uR2xvYmFsTW91c2VVcCgpIHtcblxuICAgIHRoaXMuZW5kU2VsZWN0aW9uKCk7XG4gIH1cblxuICAvKipcbiAgICogTGlzdGVuIENvcHkgQ2xpcGJvYXJkIEV2ZW50XG4gICAqL1xuICBvbkdyaWRDb3B5KGV2ZW50OiBDbGlwYm9hcmRFdmVudCkge1xuXG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIGlmICh0aGlzLnNlbGVjdGVkQ2VsbHMuc2l6ZSA+IDApIHtcblxuICAgICAgY29uc3QgdGV4dCA9IHRoaXMuYnVpbGRDbGlwYm9hcmRUZXh0KCk7XG5cbiAgICAgIGV2ZW50LmNsaXBib2FyZERhdGE/LnNldERhdGEoJ3RleHQvcGxhaW4nLCB0ZXh0KTtcblxuICAgICAgdGhpcy5zZWxlY3RlZENlbGxzLmZvckVhY2goY2VsbElkID0+IHtcblxuICAgICAgICBjb25zdCBjZWxsRWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYFtkYXRhLWNlbGwtaWQ9XCIke2NlbGxJZH1cIl1gKTtcblxuICAgICAgICBpZiAoY2VsbEVsZW1lbnQpIHtcblxuICAgICAgICAgIGNlbGxFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ29uZS1jZWxsLWNvcGllZCcpO1xuXG4gICAgICAgICAgc2V0VGltZW91dCgoKSA9PiBjZWxsRWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdvbmUtY2VsbC1jb3BpZWQnKSwgNDAwKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgY29weVRvQ2xpcGJvYXJkKHZhbHVlOiBzdHJpbmcpIHtcblxuICAgIGlmIChuYXZpZ2F0b3IuY2xpcGJvYXJkPy53cml0ZVRleHQpIHtcblxuICAgICAgbmF2aWdhdG9yLmNsaXBib2FyZC53cml0ZVRleHQodmFsdWUpO1xuXG4gICAgfSBlbHNlIHtcblxuICAgICAgLy8gRmFsbGJhY2sgKFNhZmFyaSAvIG9sZGVyIGJyb3dzZXJzKVxuICAgICAgY29uc3QgdGV4dGFyZWEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0ZXh0YXJlYScpO1xuICAgICAgdGV4dGFyZWEudmFsdWUgPSB2YWx1ZTtcbiAgICAgIHRleHRhcmVhLnN0eWxlLnBvc2l0aW9uID0gJ2ZpeGVkJztcbiAgICAgIHRleHRhcmVhLnN0eWxlLm9wYWNpdHkgPSAnMCc7XG4gICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRleHRhcmVhKTtcbiAgICAgIHRleHRhcmVhLnNlbGVjdCgpO1xuICAgICAgZG9jdW1lbnQuZXhlY0NvbW1hbmQoJ2NvcHknKTtcbiAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodGV4dGFyZWEpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCBDb3B5IENlbGwgVGV4dCB0byBDbGlwYm9hcmRcbiAgICovXG4gIHByaXZhdGUgYnVpbGRDbGlwYm9hcmRUZXh0KCk6IHN0cmluZyB7XG5cbiAgICBpZiAoIXRoaXMuc2VsZWN0ZWRDZWxscy5zaXplKSByZXR1cm4gJyc7XG5cbiAgICAvLyBQYXJzZSBzZWxlY3RlZCBjZWxsc1xuICAgIGNvbnN0IHNlbGVjdGVkID0gQXJyYXkuZnJvbSh0aGlzLnNlbGVjdGVkQ2VsbHMpLm1hcChrZXkgPT4ge1xuXG4gICAgICBjb25zdCBbcm93SWQsIGZpZWxkXSA9IGtleS5zcGxpdCgnLS0nKTtcbiAgICAgIHJldHVybiB7IHJvd0lkLCBmaWVsZCB9O1xuICAgIH0pO1xuXG4gICAgLy8gUmVzb2x2ZSB2aXN1YWwgcm93IGluZGV4ZXMgZnJvbSBkaXNwbGF5ZWRSb3dzXG4gICAgY29uc3Qgcm93SW5kZXhlcyA9IHNlbGVjdGVkXG4gICAgICAubWFwKHMgPT4gdGhpcy5ub2Rlcy5maW5kSW5kZXgociA9PiByLnJvd0lkID09PSBzLnJvd0lkKSlcbiAgICAgIC5maWx0ZXIoaSA9PiBpICE9PSAtMSk7XG5cbiAgICBjb25zdCBjb2xJbmRleGVzID0gc2VsZWN0ZWRcbiAgICAgIC5tYXAocyA9PiB0aGlzLmNvbHVtbkRlZnMuZmluZEluZGV4KGMgPT4gYy5maWVsZCA9PT0gcy5maWVsZCkpXG4gICAgICAuZmlsdGVyKGkgPT4gaSAhPT0gLTEpO1xuXG4gICAgaWYgKCFyb3dJbmRleGVzLmxlbmd0aCB8fCAhY29sSW5kZXhlcy5sZW5ndGgpIHJldHVybiAnJztcblxuICAgIGNvbnN0IHJvd1N0YXJ0ID0gTWF0aC5taW4oLi4ucm93SW5kZXhlcyk7XG4gICAgY29uc3Qgcm93RW5kICAgPSBNYXRoLm1heCguLi5yb3dJbmRleGVzKTtcbiAgICBjb25zdCBjb2xTdGFydCA9IE1hdGgubWluKC4uLmNvbEluZGV4ZXMpO1xuICAgIGNvbnN0IGNvbEVuZCAgID0gTWF0aC5tYXgoLi4uY29sSW5kZXhlcyk7XG5cbiAgICBjb25zdCBzZWxlY3RlZEZpZWxkcyA9IHRoaXMuY29sdW1uRGVmc1xuICAgICAgLnNsaWNlKGNvbFN0YXJ0LCBjb2xFbmQgKyAxKVxuICAgICAgLm1hcChjID0+IGMuZmllbGQpO1xuXG4gICAgY29uc3QgY2xpcGJvYXJkTGluZXM6IHN0cmluZ1tdID0gW107XG5cbiAgICBmb3IgKGxldCByID0gcm93U3RhcnQ7IHIgPD0gcm93RW5kOyByKyspIHtcblxuICAgICAgY29uc3Qgcm93ID0gdGhpcy5ub2Rlc1tyXTtcbiAgICAgIGNvbnN0IGxpbmUgPSBzZWxlY3RlZEZpZWxkc1xuICAgICAgICAubWFwKGZpZWxkID0+IHtcblxuICAgICAgICAgIGNvbnN0IGtleSA9IGAke3Jvdy5yb3dJZH0tLSR7ZmllbGR9YDtcblxuICAgICAgICAgIGlmICghdGhpcy5zZWxlY3RlZENlbGxzLmhhcyhrZXkpKSB7XG5cbiAgICAgICAgICAgIHJldHVybiAnJztcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgdmFsdWUgPSBnZXRGaWVsZFZhbHVlKHJvdy5kYXRhLCBmaWVsZCk7XG5cbiAgICAgICAgICByZXR1cm4gdmFsdWUgPz8gJyc7XG5cbiAgICAgICAgfSkuam9pbignXFx0Jyk7XG5cbiAgICAgIGNsaXBib2FyZExpbmVzLnB1c2gobGluZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNsaXBib2FyZExpbmVzLmpvaW4oJ1xcbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEJpbmRpbmcgRXZlbnRzIFJvdyBBY3Rpb24gdG8gUGFyZW50XG4gICAqL1xuICBpbnZva2VSb3dBY3Rpb25Hb3RvRGV0YWlsKGV2ZW50OiBPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4pIHtcblxuICAgIHRoaXMub25Sb3dHb3RvRGV0YWlsLmVtaXQoZXZlbnQpO1xuICB9XG5cbiAgaW52b2tlUm93QWN0aW9uQWRkTmV3KGV2ZW50OiBPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4pIHtcblxuICAgIHRoaXMub25Sb3dBZGROZXcuZW1pdChldmVudCk7XG4gIH1cblxuICBpbnZva2VSb3dBY3Rpb25WaWV3KGV2ZW50OiBPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4pIHtcblxuICAgIHRoaXMub25Sb3dWaWV3LmVtaXQoZXZlbnQpO1xuICB9XG5cbiAgaW52b2tlUm93QWN0aW9uTG9jYXRpb24oZXZlbnQ6IE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPikge1xuXG4gICAgdGhpcy5vblJvd0xvY2F0aW9uLmVtaXQoZXZlbnQpO1xuICB9XG5cbiAgaW52b2tlUm93QWN0aW9uRG9jdW1lbnQoZXZlbnQ6IE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPikge1xuXG4gICAgdGhpcy5vblJvd0RvY3VtZW50LmVtaXQoZXZlbnQpO1xuICB9XG5cbiAgaW52b2tlUm93QWN0aW9uQ29weShldmVudDogT25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+KSB7XG5cbiAgICB0aGlzLm9uUm93Q29weS5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIGludm9rZVJvd0FjdGlvbkRlbGV0ZShldmVudDogT25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+KSB7XG5cbiAgICB0aGlzLm9uUm93RGVsZXRlLmVtaXQoZXZlbnQpO1xuICB9XG5cbiAgaW52b2tlUm93QWN0aW9uR290b0xpc3QoZXZlbnQ6IE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPikge1xuXG4gICAgdGhpcy5vblJvd0dvdG9MaXN0LmVtaXQoZXZlbnQpO1xuICB9XG5cbiAgaW52b2tlUm93QWN0aW9uRWRpdChldmVudDogT25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+KSB7XG5cbiAgICB0aGlzLm9uUm93RWRpdC5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIGludm9rZVJvd0FjdGlvblByaW50KGV2ZW50OiBPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4pIHtcblxuICAgIHRoaXMub25Sb3dQcmludC5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIGludm9rZVJvd0FjdGlvbkhpc3RvcnkoZXZlbnQ6IE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPikge1xuXG4gICAgdGhpcy5vblJvd0hpc3RvcnkuZW1pdChldmVudCk7XG4gIH1cblxuICBpbnZva2VSb3dBY3Rpb25PcHRpb24oZXZlbnQ6IE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPikge1xuXG4gICAgdGhpcy5vblJvd09wdGlvbi5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIGludm9rZVJvd0FjdGlvbkxhbmd1YWdlKGV2ZW50OiBPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4pIHtcblxuICAgIHRoaXMub25Sb3dMYW5ndWFnZS5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPcGVuIHRoZSBjZWxsIG9wdGlvbiBtZW51LCBhbmQgdGVsbCB0aGUgaG9zdCBpdCB3YXMgYXNrZWQgZm9yLlxuICAgKlxuICAgKiBUaGUgb3BlbmluZyBpcyB0aGUgcGFydCB0aGF0IHdhcyBtaXNzaW5nLiBFdmVyeXRoaW5nIGVsc2UgZXhpc3RlZCDigJQgdGhlXG4gICAqIHRyaWdnZXIgYnV0dG9uIGJlaGluZCBgY2VsbFJlbmRlcmVyUGFyYW1zLmNlbGxPcHRpb25CdXR0b25TdGF0dXNgLCB0aGUgbWVudVxuICAgKiBjb21wb25lbnQsIHRoZSBgY2VsbE9wdGlvbk1lbnVgIGNvbHVtbiBwcm9wZXJ0eSwgdGhlIHNlbGVjdGlvbiBldmVudCB3aXJlZFxuICAgKiB0aHJvdWdoIHRvIHRoZSBncmlkJ3Mgb3V0cHV0IOKAlCBidXQgbm90aGluZyBldmVyIHNldCB0aGUgZmxhZyB0aGUgdGVtcGxhdGVcbiAgICogcmVuZGVycyBvbiwgc28gdGhlIGJ1dHRvbiBkaWQgbm90aGluZyBhdCBhbGwuXG4gICAqXG4gICAqIERvbmUgaGVyZSByYXRoZXIgdGhhbiBpbiB0aGUgcm93LWFjdGlvbiBjb21wb25lbnQgYmVjYXVzZSB0aGlzIGlzIHRoZVxuICAgKiBjb21wb25lbnQgd2hvc2UgdGVtcGxhdGUgcmVuZGVycyB0aGUgbWVudSwgYW5kIHNvIHRoZSBvbmUgdGhhdCBoYXMgdG8gYmVcbiAgICogbWFya2VkIGZvciBjaGVjay5cbiAgICovXG4gIGludm9rZVJvd0FjdGlvbkNlbGxPcHRpb24oZXZlbnQ6IE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPikge1xuXG4gICAgY29uc3QgZmllbGQgPSBldmVudC5jb2x1bW4/LmZpZWxkIGFzIHN0cmluZztcblxuICAgIC8vIE5vdGhpbmcgdG8gb3BlbiB3aGVuIHRoZSBjb2x1bW4gZGVjbGFyZWQgbm8gb3B0aW9uczsgdGhlIGV2ZW50IHN0aWxsXG4gICAgLy8gZ29lcyB0byB0aGUgaG9zdCwgd2hpY2ggbWF5IGJlIGRyaXZpbmcgc29tZXRoaW5nIG9mIGl0cyBvd24uXG4gICAgaWYgKGZpZWxkICYmIGV2ZW50Lm5vZGUgJiYgZXZlbnQuY29sdW1uPy5jZWxsT3B0aW9uTWVudT8ubGVuZ3RoKSB7XG5cbiAgICAgIGV2ZW50Lm5vZGUuY2VsbE9wdGlvbnNbZmllbGRdID0gdHJ1ZTtcblxuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuXG4gICAgdGhpcy5vblJvd0NlbGxPcHRpb24uZW1pdChldmVudCk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIG1lbnUgY2xvc2VkIGl0c2VsZiDigJQgb24gc2VsZWN0LCBvbiBFc2NhcGUsIG9yIG9uIGEgY2xpY2sgb3V0c2lkZS4gSXRcbiAgICogaGFzIGFscmVhZHkgY2xlYXJlZCBpdHMgb3duIGZsYWc7IHRoaXMgaXMgd2hhdCByZXBhaW50cyB3aXRob3V0IGl0LlxuICAgKi9cbiAgY2VsbE9wdGlvbk1lbnVDbG9zZWQoKTogdm9pZCB7XG5cbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIGludm9rZVJvd0FjdGlvblNlbGVjdGlvbihldmVudDogT25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+KSB7XG5cbiAgICB0aGlzLm9uUm93U2VsZWN0aW9uLmVtaXQoZXZlbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRvZ2dsZSBhIGdyb3VwIC8gbWFzdGVyIHJvdywgdGhlbiByZXBvcnQgdGhlIHJlc3VsdC5cbiAgICpcbiAgICogVGhlIGdyb3VwIHJlbmRlcmVyIGlzIHByZXNlbnRhdGlvbmFsOiBpdCBzYXlzIFwidGhlIGV4cGFuZGVyIHdhcyBjbGlja2VkXCJcbiAgICogYW5kIG5vdGhpbmcgbW9yZS4gUGVyZm9ybWluZyB0aGUgc3RhdGUgY2hhbmdlIGJlbG9uZ3MgaGVyZSwgd2hlcmUgdGhlIEFQSVxuICAgKiBpcyBhdmFpbGFibGUuIFByZXZpb3VzbHkgdGhpcyBtZXRob2Qgb25seSByZS1lbWl0dGVkLCBzbyB0aGUgZXhwYW5kZXJcbiAgICogcmVuZGVyZWQsIGFuaW1hdGVkIG9uIGhvdmVyIGFuZCBkaWQgbm90aGluZyBhdCBhbGwg4oCUIGV2ZXJ5IGNvbnN1bWVyIGhhZCB0b1xuICAgKiBkaXNjb3ZlciBmb3IgaXRzZWxmIHRoYXQgYGV4cGFuc2lvbkNoYW5nZWRgIHdhcyBhIHJlcXVlc3QgcmF0aGVyIHRoYW4gdGhlXG4gICAqIG5vdGlmaWNhdGlvbiBpdHMgcGFzdC10ZW5zZSBuYW1lIHByb21pc2VzLlxuICAgKlxuICAgKiBUaGUgZXZlbnQgaXMgcmUtZW1pdHRlZCAqYWZ0ZXIqIHRoZSB0b2dnbGUsIHNvIGBldmVudC5ub2RlLmV4cGFuZGVkYCBpcyB0aGVcbiAgICogbmV3IHN0YXRlLCB3aGljaCBpcyB3aGF0IGEgcGFzdC10ZW5zZSBldmVudCBzaG91bGQgY2FycnkuXG4gICAqL1xuICBpbnZva2VFeHBhbnNpb25DaGFuZ2VkQ2xpY2soZXZlbnQ6IEV4cGFuc2lvbkNoYW5nZWRFdmVudCk6IHZvaWQge1xuXG4gICAgY29uc3Qgbm9kZSA9IHRoaXMuYXBpLmdldFJvd05vZGVCeUlkKGV2ZW50Lm5vZGUucm93SWQpID8/IGV2ZW50Lm5vZGU7XG5cbiAgICB0aGlzLmFwaS5zZXRFeHBhbmRlZEJ5SWQobm9kZS5yb3dJZCwgIW5vZGUuZXhwYW5kZWQpO1xuXG4gICAgdGhpcy5leHBhbnNpb25DaGFuZ2VkLmVtaXQoeyAuLi5ldmVudCwgbm9kZSwgYXBpOiB0aGlzLmFwaSB9KTtcbiAgfVxuXG4gIGNlbGxPcHRpb25NZW51U2VsZWN0ZWQoZXZlbnQ6IENlbGxPcHRpb25NZW51U2VsZWN0ZWRFdmVudCkge1xuXG4gICAgdGhpcy5jZWxsT3B0aW9uU2VsZWN0LmVtaXQoZXZlbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNwZWNpYWwgRXZlbnRzXG4gICAqL1xuICBwcml2YXRlIGludm9rZVNoaWZ0RG91YmxlQ2xpY2sobm9kZTpPbmVSb3dOb2RlLCBjb2x1bW46IE9uZUNvbHVtbkRlZik6IHZvaWQge1xuXG4gICAgbGV0IGV2ZW50OiBPbmVHcmlkUm93QWN0aW9uRXZlbnQgPSB7IG5vZGUsIGNvbHVtbiwgZGF0YTogbm9kZS5kYXRhLCByb3dJbmRleDogbm9kZS5yb3dJbmRleCwgZ3JpZFR5cGU6IG51bGwgfTtcblxuICAgIGlmICh0aGlzLm1hc3RlckRldGFpbCkge1xuXG4gICAgICBldmVudCA9IHsgLi4uZXZlbnQsIGdyaWRUeXBlOiB0aGlzLmdyaWRUeXBlLCBtYXN0ZXJOb2RlOiB0aGlzLm1hc3Rlck5vZGUgfTtcbiAgICB9XG5cbiAgICB0aGlzLm9uU2hpZnREb3VibGVDbGljay5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDZWxsIEVkaXQgRmVhdHVyZVxuICAgKi9cbiAgc3RhcnRFZGl0KGV2ZW50OiBNb3VzZUV2ZW50LCBub2RlOiBPbmVSb3dOb2RlPFQ+LCBjb2x1bW46IE9uZUNvbHVtbkRlZjxUPikge1xuXG4gICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuXG4gICAgaWYgKHRhcmdldC50YWdOYW1lLnRvTG93ZXJDYXNlKCkgPT09ICdpJykge1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGV2ZW50LnNoaWZ0S2V5KSB7XG5cbiAgICAgIHRoaXMuaW52b2tlU2hpZnREb3VibGVDbGljayhub2RlLCBjb2x1bW4pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5jZWxsRWRpdGFibGVQaXBlLnRyYW5zZm9ybShub2RlLmNlbGxTdGF0ZXMsIGNvbHVtbiwgbm9kZSwgdGhpcy5jZWxsU2VydmljZS5lZGl0YWJsZUZuLCB0aGlzLmNlbGxTZXJ2aWNlLnVwZGF0YWJsZUZuLCB0aGlzLmFsbG93ZWRFZGl0KSkge1xuXG4gICAgICB0aGlzLnNlbGVjdGVkQ2VsbHMuY2xlYXIoKTtcblxuICAgICAgY29uc3QgY2VsbEtleSA9IGdldENlbGxLZXkobm9kZS5yb3dJZCwgY29sdW1uLmZpZWxkKTtcblxuICAgICAgdGhpcy5zZWxlY3RlZENlbGxzLmFkZChjZWxsS2V5KTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCByb3dOb2RlOiBPbmVSb3dOb2RlID0gdGhpcy5hcGkuZ2V0Um93Tm9kZUJ5SWQobm9kZS5yb3dJZCk7XG5cbiAgICBpZiAocm93Tm9kZSkge1xuXG4gICAgICByb3dOb2RlLmVkaXRpbmdbY29sdW1uLmZpZWxkXSA9IHRydWU7XG5cbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuXG4gICAgICAgIGNvbnN0IGlucHV0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcjxIVE1MSW5wdXRFbGVtZW50PihgW2RhdGEtY2VsbC1pZD1cIiR7IGdldENlbGxLZXkobm9kZS5yb3dJZCwgY29sdW1uLmZpZWxkKSB9XCJdIGlucHV0YCk7XG5cbiAgICAgICAgaWYgKGlucHV0KSB7XG5cbiAgICAgICAgICBpbnB1dC5mb2N1cygpO1xuXG4gICAgICAgICAgY29uc3QgdmFsdWUgPSBpbnB1dC52YWx1ZTtcblxuICAgICAgICAgIGlmICh2YWx1ZSAmJiBbXCJ0ZXh0XCJdLmluY2x1ZGVzKGlucHV0LnR5cGUpKSB7XG5cbiAgICAgICAgICAgIGlucHV0LnNldFNlbGVjdGlvblJhbmdlKHZhbHVlLmxlbmd0aCwgdmFsdWUubGVuZ3RoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LCAxMCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNhdmUgQ2VsbCBFZGl0IE1vZGVcbiAgICovXG4gIHN0b3BFZGl0KG5vZGU6IE9uZVJvd05vZGU8VD4sIGNvbHVtbjogT25lQ29sdW1uRGVmPFQ+LCBldmVudDogYW55KSB7XG5cbiAgICBsZXQgcm93Tm9kZTogT25lUm93Tm9kZSA9IHRoaXMuYXBpLmdldFJvd05vZGVCeUlkKG5vZGUucm93SWQpO1xuXG4gICAgaWYgKHJvd05vZGUpIHtcblxuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICBjb25zdCB2YWx1ZSA9IGV2ZW50LnRhcmdldC52YWx1ZSA/PyAnJztcbiAgICAgIHRoaXMuc2V0Q2VsbFZhbHVlQnlSb3dJZChub2RlLnJvd0lkLCBjb2x1bW4sIHZhbHVlKTtcblxuICAgICAgcm93Tm9kZS5jZWxsU3RhdGVzID0gdGhpcy5jZWxsU2VydmljZS5nZW5lcmF0ZUNlbGxTdGF0ZXMocm93Tm9kZSk7XG4gICAgICByb3dOb2RlLmVkaXRpbmdbY29sdW1uLmZpZWxkXSA9IGZhbHNlO1xuXG4gICAgICB0aGlzLmV2ZW50U2VydmljZS5kaXNwYXRjaEV2ZW50KCdjZWxsU3RhdGVDaGFuZ2VkJywge1xuICAgICAgICBkYXRhOiByb3dOb2RlLmRhdGEsXG4gICAgICAgIG5vZGU6IHJvd05vZGUsXG4gICAgICAgIGNvbHVtbjogY29sdW1uXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2FuY2VsIENlbGwgRWRpdCBNb2RlXG4gICAqL1xuICBjYW5jZWxFZGl0KG5vZGU6IE9uZVJvd05vZGU8VD4sIGNvbHVtbjogT25lQ29sdW1uRGVmPFQ+KSB7XG5cbiAgICBsZXQgcm93Tm9kZTogT25lUm93Tm9kZSA9IHRoaXMuYXBpLmdldFJvd05vZGVCeUlkKG5vZGUucm93SWQpO1xuXG4gICAgaWYgKHJvd05vZGUpIHtcblxuICAgICAgcm93Tm9kZS5lZGl0aW5nW2NvbHVtbi5maWVsZF0gPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0IENlbGwgVmFsdWVcbiAgICovXG4gIHNldENlbGxWYWx1ZUJ5Um93SWQocm93SWQ6IHN0cmluZywgY29sdW1uOiBPbmVDb2x1bW5EZWYsIHZhbHVlOiBhbnkpIHtcblxuICAgIGNvbnN0IG5vZGUgPSB0aGlzLmFwaS5nZXRSb3dOb2RlQnlJZChyb3dJZCk7XG5cbiAgICBpZiAobm9kZSAmJiBjb2x1bW4uZmllbGQpIHtcblxuICAgICAgaWYgKGNvbHVtbj8uY2VsbFJlbmRlcmVyUGFyYW1zPy5pbnB1dFR5cGUgIT09ICdudW1iZXInKSB7XG5cbiAgICAgICAgbm9kZS5kYXRhW2NvbHVtbi5maWVsZF0gPSB2YWx1ZSA9PT0gJycgPyBudWxsIDogdmFsdWU7XG5cbiAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgbm9kZS5kYXRhW2NvbHVtbi5maWVsZF0gPSB2YWx1ZSA9PT0gJycgPyBudWxsIDogTnVtYmVyKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmlydHVhbCBTY3JvbGwgUHJvcGVydGllc1xuICAgKlxuICAgKiBUaGUgYnVmZmVyIHNjYWxlcyB3aXRoIHRoZSByb3cgY291bnQgc28gc21hbGwgZ3JpZHMgcmVuZGVyIGluIG9uZSBwYXNzLCBidXRcbiAgICogaXQgaXMgY2FwcGVkOiBgaXRlbVNpemUgKiBpdGVtcyAqIDEuNWAgaXMgMS41eCB0aGUgKnRvdGFsKiBjb250ZW50IGhlaWdodCxcbiAgICogYW5kIENka0ZpeGVkU2l6ZVZpcnR1YWxTY3JvbGwgZXhwYW5kcyBpdHMgcmVuZGVyZWQgcmFuZ2UgdW50aWwgdGhlIGJ1ZmZlciBpc1xuICAgKiBzYXRpc2ZpZWQuIFVuY2FwcGVkLCB0aGF0IG1ha2VzIHRoZSB2aWV3cG9ydCBtYXRlcmlhbGlzZSBldmVyeSByb3cgYW5kXG4gICAqIHZpcnR1YWwgc2Nyb2xsaW5nIHN0b3BzIGRvaW5nIGFueXRoaW5nIGF0IGFsbCAoMTAwayByb3dzIGxvY2tlZCB0aGUgdGFiKS5cbiAgICogTUFYX0JVRkZFUl9QWCBrZWVwcyByb3VnaGx5IHR3ZW50eSByb3dzIG9mIG92ZXJzY2FuIGVpdGhlciBzaWRlIGluc3RlYWQuXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IE1BWF9CVUZGRVJfUFg6IG51bWJlciA9IDYwMDtcblxuICBzZXRWaXJ0dWFsU2Nyb2xsKGl0ZW1zOiBudW1iZXIgPSAwKTogdm9pZCB7XG5cbiAgICB0aGlzLm1pbkJ1ZmZlclB4ID0gTWF0aC5taW4odGhpcy5pdGVtU2l6ZSAqIGl0ZW1zICogMS41LCB0aGlzLk1BWF9CVUZGRVJfUFgpO1xuXG4gICAgdGhpcy5tYXhCdWZmZXJQeCA9IHRoaXMubWluQnVmZmVyUHggKiAyO1xuICB9XG5cbiAgLyoqXG4gICAqIFVuc3Vic2NyaWJlIEFsbCBTdWJzY3JpcHRpb25zXG4gICAqL1xuICAvKipcbiAgICogSGFuZCB0aGUgZHJhZyBzZXJ2aWNlIHdoYXQgaXQgbmVlZHMgdG8gcnVuIGEgZ2VzdHVyZS5cbiAgICpcbiAgICogRGVmZXJyZWQgdG8gaGVyZSBiZWNhdXNlIHRoZSB2aWV3cG9ydCBlbGVtZW50IGRvZXMgbm90IGV4aXN0IHVudGlsIHRoZSB2aWV3XG4gICAqIGlzIHVwLCBhbmQgYG5vZGVzYCBpcyBwYXNzZWQgYXMgYSBnZXR0ZXIgcmF0aGVyIHRoYW4gYSB2YWx1ZSDigJQgYSBkcmFnXG4gICAqIG11dGF0ZXMgdGhlIG9yZGVyIHVuZGVybmVhdGggaXQsIHNvIGEgc25hcHNob3QgdGFrZW4gYXQgYXR0YWNoIHRpbWUgd291bGRcbiAgICogZ28gc3RhbGUgb24gdGhlIGZpcnN0IG1vdmUuXG4gICAqL1xuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG5cbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy52aWV3cG9ydD8uZWxlbWVudFJlZj8ubmF0aXZlRWxlbWVudDtcblxuICAgIGlmICghZWxlbWVudCkgcmV0dXJuO1xuXG4gICAgdGhpcy5yb3dEcmFnU2VydmljZS5hdHRhY2goe1xuICAgICAgdmlld3BvcnQ6IGVsZW1lbnQsXG4gICAgICBpdGVtU2l6ZTogdGhpcy5pdGVtU2l6ZSxcbiAgICAgIG5vZGVzOiAoKSA9PiB0aGlzLm5vZGVzLFxuICAgICAgbW92ZTogKGZyb21JbmRleDogbnVtYmVyLCB0b0luZGV4OiBudW1iZXIpID0+IHtcblxuICAgICAgICBjb25zdCBtb3ZlZCA9IHRoaXMuYXBpLm1vdmVSb3coZnJvbUluZGV4LCB0b0luZGV4KTtcblxuICAgICAgICBpZiAobW92ZWQpIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuXG4gICAgICAgIHJldHVybiBtb3ZlZDtcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICB0aGlzLnJlZnJlc2hSb3dEcmFnU3VwcHJlc3NlZCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBwYXJhbXMgZXZlcnkgcGVyLWNlbGwgY2FsbGJhY2sgcmVjZWl2ZXMuXG4gICAqXG4gICAqIEJ1aWx0IGhlcmUgcmF0aGVyIHRoYW4gaW5saW5lIGluIHRoZSB0ZW1wbGF0ZSBzbyB0aGUgd2hvbGUgZG9jdW1lbnRlZFxuICAgKiBzaGFwZSBpcyBwYXNzZWQg4oCUIGB2YWx1ZWAsIGBmaWVsZGAsIGByb3dJbmRleGAsIGBhcGlgIGFuZCBgY29udGV4dGAgd2VyZVxuICAgKiBhbGwgZGVjbGFyZWQgb24gYE9uZUNlbGxSZW5kZXJlclBhcmFtc2AgYW5kIG5vbmUgb2YgdGhlbSB3ZXJlIGJlaW5nIHNlbnQsXG4gICAqIHNvIGEgYGNlbGxDbGFzc2AgcmVhZGluZyBgcGFyYW1zLnZhbHVlYCBzaWxlbnRseSBnb3QgYHVuZGVmaW5lZGAuXG4gICAqL1xuICBwcm90ZWN0ZWQgY2VsbFBhcmFtcyhub2RlOiBPbmVSb3dOb2RlPFQ+LCBjb2x1bW46IE9uZUNvbHVtbkRlZjxUPik6IE9uZUNlbGxQcmVzZW50YXRpb25QYXJhbXM8VD4ge1xuXG4gICAgcmV0dXJuIHRoaXMuY2VsbFNlcnZpY2UuY2VsbFBhcmFtcyhjb2x1bW4sIG5vZGUpIGFzIE9uZUNlbGxQcmVzZW50YXRpb25QYXJhbXM8VD47XG4gIH1cblxuICAvKipcbiAgICogUGFyYW1zIGZvciBhIGNvbXBvbmVudCBjZWxsIHJlbmRlcmVyLlxuICAgKlxuICAgKiBUaGUgY2VsbCBwYXJhbXMsIHBsdXMgd2hhdGV2ZXIgdGhlIGNvbHVtbiBkZWNsYXJlZCBpblxuICAgKiBgY2VsbFJlbmRlcmVyUGFyYW1zYCDigJQgYSBmaWVsZCB0aGF0IGV4aXN0cyBwcmVjaXNlbHkgc28gYSByZW5kZXJlciBjYW4gYmVcbiAgICogY29uZmlndXJlZCBwZXIgY29sdW1uLCBhbmQgdGhhdCBub3RoaW5nIGhhZCBldmVyIGZvcndhcmRlZCB0byBpdC4gQ29sdW1uXG4gICAqIGNvbmZpZyBnb2VzIGZpcnN0IHNvIHRoZSBncmlkJ3Mgb3duIGZpZWxkcyB3aW4gYSBuYW1lIGNvbGxpc2lvbi5cbiAgICovXG4gIHByb3RlY3RlZCByZW5kZXJlclBhcmFtcyhub2RlOiBPbmVSb3dOb2RlPFQ+LCBjb2x1bW46IE9uZUNvbHVtbkRlZjxUPik6IE9uZUNlbGxSZW5kZXJlclBhcmFtczxUPiB7XG5cbiAgICByZXR1cm4geyAuLi4oY29sdW1uPy5jZWxsUmVuZGVyZXJQYXJhbXMgPz8ge30pLCAuLi50aGlzLmNlbGxQYXJhbXMobm9kZSwgY29sdW1uKSB9O1xuICB9XG5cbiAgLyoqIElzIHRoaXMgdGhlIHJvdyBjdXJyZW50bHkgYmVpbmcgbW92ZWQ/ICovXG4gIHByb3RlY3RlZCBpc1Jvd0RyYWdnaW5nKG5vZGU6IE9uZVJvd05vZGU8VD4pOiBib29sZWFuIHtcblxuICAgIHJldHVybiB0aGlzLmRyYWdTdGF0ZT8ucm93SWQgPT09IG5vZGUucm93SWQ7XG4gIH1cblxuICAvKipcbiAgICogV2hlcmUgdG8gcGFpbnQgdGhlIGRyb3AgaW5kaWNhdG9yLCBpbiBwaXhlbHMgZnJvbSB0aGUgdG9wIG9mIHRoZSBib2R5LlxuICAgKlxuICAgKiBgaW5zZXJ0QXRgIGlzIGEgYm91bmRhcnksIHNvIHRoZSBsaW5lIHNpdHMgYXQgcm93LWhlaWdodCB0aW1lcyB0aGUgbnVtYmVyXG4gICAqIG9mIHJvd3MgYWJvdmUgaXQg4oCUIGluIGNvbnRlbnQgc3BhY2UuIFRoZSBpbmRpY2F0b3IgaXMgYSBzaWJsaW5nIG9mIHRoZVxuICAgKiB2aWV3cG9ydCByYXRoZXIgdGhhbiBhIGNoaWxkLCBiZWNhdXNlIGFueXRoaW5nIGluc2lkZSBpdCBlaXRoZXIgc2Nyb2xsc1xuICAgKiBhd2F5IHdpdGggdGhlIHRyYW5zZm9ybWVkIGNvbnRlbnQgd3JhcHBlciBvciBpZ25vcmVzIHRoZSBzY3JvbGwgZW50aXJlbHksXG4gICAqIHNvIHRoZSB2aWV3cG9ydCdzIG93biBzY3JvbGwgb2Zmc2V0IGFuZCBpdHMgcG9zaXRpb24gd2l0aGluIHRoZSBib2R5IGFyZVxuICAgKiBib3RoIHN1YnRyYWN0ZWQgYmFjayBvdXQgaGVyZS5cbiAgICpcbiAgICogQSBmaWVsZCByYXRoZXIgdGhhbiBhIGdldHRlcjogaXQgaXMgcmVhZCBmcm9tIHRoZSB0ZW1wbGF0ZSBvbiBldmVyeSBjaGFuZ2VcbiAgICogZGV0ZWN0aW9uIHBhc3MsIGFuZCBpdCBvbmx5IGFjdHVhbGx5IG1vdmVzIHdoZW4gdGhlIGRyYWcgc3RhdGUgb3IgdGhlXG4gICAqIHNjcm9sbCBwb3NpdGlvbiBkb2VzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGRyb3BJbmRpY2F0b3JUb3A6IG51bWJlciB8IG51bGwgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBIb3cgd2lkZSB0aGUgbGluZSBpcyBkcmF3bi4gUm93cyBhcmUgYHdpZHRoOiBmaXQtY29udGVudGAsIHNvIHRoZXkgYXJlXG4gICAqIG9mdGVuIG5hcnJvd2VyIHRoYW4gdGhlIHZpZXdwb3J0IOKAlCBhIGZ1bGwtYmxlZWQgbGluZSB3b3VsZCBoYW5nIHBhc3QgdGhlXG4gICAqIGxhc3QgY29sdW1uIGludG8gZW1wdHkgc3BhY2UgYW5kIHJlYWQgYXMgcGFydCBvZiB0aGUgZnJhbWUgcmF0aGVyIHRoYW4gdGhlXG4gICAqIHJvd3MuIFRoaXMgaXMgdGhlIHZpc2libGUgZXh0ZW50IG9mIHRoZSByb3cgY29udGVudCwgd2hpY2ggYWxzbyBzaHJpbmtzXG4gICAqIGNvcnJlY3RseSBhcyB0aGUgZ3JpZCBpcyBzY3JvbGxlZCBzaWRld2F5cy5cbiAgICovXG4gIHByb3RlY3RlZCBkcm9wSW5kaWNhdG9yV2lkdGggPSAwO1xuXG4gIHByaXZhdGUgdXBkYXRlRHJvcEluZGljYXRvcigpOiB2b2lkIHtcblxuICAgIGNvbnN0IHN0YXRlID0gdGhpcy5kcmFnU3RhdGU7XG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMudmlld3BvcnQ/LmVsZW1lbnRSZWY/Lm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICBpZiAoc3RhdGU/LnNvdXJjZSAhPT0gJ3BvaW50ZXInIHx8ICFlbGVtZW50KSB7XG5cbiAgICAgIHRoaXMuZHJvcEluZGljYXRvclRvcCA9IG51bGw7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmRyb3BJbmRpY2F0b3JUb3AgPSAoc3RhdGUuaW5zZXJ0QXQgKiB0aGlzLml0ZW1TaXplKSAtIGVsZW1lbnQuc2Nyb2xsVG9wICsgZWxlbWVudC5vZmZzZXRUb3A7XG5cbiAgICB0aGlzLmRyb3BJbmRpY2F0b3JXaWR0aCA9IE1hdGgubWF4KE1hdGgubWluKHRoaXMucm93V2lkdGggLSBlbGVtZW50LnNjcm9sbExlZnQsIGVsZW1lbnQuY2xpZW50V2lkdGgpLCAwKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvblJvd0RyYWdFbmQoZXZlbnQ6IE9uZVJvd0RyYWdFdmVudDxUPik6IHZvaWQge1xuXG4gICAgdGhpcy5yb3dEcmFnRW5kLmVtaXQoZXZlbnQpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWZyZXNoUm93RHJhZ1N1cHByZXNzZWQoKTogdm9pZCB7XG5cbiAgICBjb25zdCByZWFzb24gPSB0aGlzLmFwaT8uZ2V0Um93RHJhZ1N1cHByZXNzZWRSZWFzb24/LigpID8/IG51bGw7XG5cbiAgICBpZiAocmVhc29uID09PSB0aGlzLnJvd0RyYWdTdXBwcmVzc2VkKSByZXR1cm47XG5cbiAgICB0aGlzLnJvd0RyYWdTdXBwcmVzc2VkID0gcmVhc29uO1xuXG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcblxuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy51bnN1YnNjcmliZSgpO1xuICB9XG59XG4iLCI8ZGl2ICNib2R5UmVmIGNsYXNzPVwib25lLWdyaWQtYm9keVwiPlxuXG4gICAgPCEtLSBQaW5uZWQgcm93cyBsaXZlIG91dHNpZGUgdGhlIHNjcm9sbCB2aWV3cG9ydCBzbyB0aGV5IG5ldmVyIHNjcm9sbFxuICAgICAgICAgdmVydGljYWxseSwgYW5kIG1pcnJvciBpdHMgc2Nyb2xsTGVmdCBzbyB0aGUgY29sdW1ucyBzdGF5IGFsaWduZWQuIC0tPlxuICAgIEBpZiAocGlubmVkVG9wTm9kZXMubGVuZ3RoKSB7XG4gICAgICAgIDxkaXYgI3Bpbm5lZFZpZXdwb3J0IGNsYXNzPVwib25lLXBpbm5lZC1yb3dzIG9uZS1waW5uZWQtcm93cy10b3BcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwicGlubmVkUm93c1wiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7IG5vZGVzOiBwaW5uZWRUb3BOb2RlcyB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvZGl2PlxuICAgIH1cblxuICAgIDwhLS0gdGFiaW5kZXggbWFrZXMgdGhlIHNjcm9sbCBjb250YWluZXIgcmVhY2hhYmxlLCBzbyBhIGtleWJvYXJkIHVzZXIgY2FuXG4gICAgICAgICBzY3JvbGwgdGhlIHJvd3Mgd2l0aCB0aGUgYXJyb3cga2V5cywgUGFnZSBVcC9Eb3duIGFuZCBIb21lL0VuZC4gV2l0aG91dFxuICAgICAgICAgaXQgdGhlIGJvZHkgaXMgc2Nyb2xsYWJsZSBieSBwb2ludGVyIG9ubHkgKFdDQUcgMi4xLjEpLiAtLT5cbiAgICA8Y2RrLXZpcnR1YWwtc2Nyb2xsLXZpZXdwb3J0XG4gICAgICAgIGNsYXNzPVwib25lLWdyaWQtYm9keS12aWV3cG9ydFwiXG4gICAgICAgIHRhYmluZGV4PVwiMFwiXG4gICAgICAgIFtpdGVtU2l6ZV09XCJpdGVtU2l6ZVwiXG4gICAgICAgIFttaW5CdWZmZXJQeF09XCJtaW5CdWZmZXJQeFwiXG4gICAgICAgIFttYXhCdWZmZXJQeF09XCJtYXhCdWZmZXJQeFwiXG4gICAgICAgIChzY3JvbGwpPVwib25Cb2R5U2Nyb2xsKCRldmVudClcIj5cblxuICAgICAgICA8bmctY29udGFpbmVyICpjZGtWaXJ0dWFsRm9yPVwibGV0IG5vZGUgb2Ygbm9kZXM7IHRyYWNrQnk6IHRyYWNrQnlSb3dJZDtcIj5cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm9uZS1yb3dcIlxuICAgICAgICAgICAgICAgIFthdHRyLmRhdGEtcm93LWlkXT1cIm5vZGUucm93SWRcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5vbmUtcm93LXNlbGVjdGVkXT1cIm5vZGUuc2VsZWN0ZWRcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5vbmUtcm93LWRyYWdnaW5nXT1cImlzUm93RHJhZ2dpbmcobm9kZSlcIj5cbiAgICAgICAgICAgICAgICBAZm9yIChjb2wgb2YgY29sdW1uRGVmczsgdHJhY2sgY29sLmZpZWxkOykge1xuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNlbGxUZW1wbGF0ZVwiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7IG5vZGUsIHJvd0luZGV4OiBub2RlLnJvd0luZGV4LCBjb2x1bW46IGNvbCB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDwhLS0gQ3VzdG9tIERldGFpbCBDb21wb25lbnQgLS0+XG4gICAgICAgICAgICAgQGlmKG5vZGUubGVhZiAmJiBub2RlLmRldGFpbEFjdGl2ZSAmJiBub2RlPy5kZXRhaWxSZW5kZXJlckNvbXBvbmVudCkge1xuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgb25lQ2VsbFJlbmRlcmVyQ29tcG9uZW50XG4gICAgICAgICAgICAgICAgICAgIFtjZWxsUmVuZGVyZXJDb21wb25lbnRdPVwibm9kZT8uZGV0YWlsUmVuZGVyZXJDb21wb25lbnRcIlxuICAgICAgICAgICAgICAgICAgICBbcGFyYW1zXT1cInsgZGF0YTogbm9kZS5kYXRhLCByb3dJbmRleDogbm9kZS5yb3dJbmRleCwgbm9kZTogbm9kZSwgY29udGV4dDogY29udGV4dCB9XCI+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIDwhLS0gTWFzdGVyIERldGFpbCBHcmlkICh0ZW1wbGF0ZSBwcm92aWRlZCBieSB0aGUgcGFyZW50IG9uZS1ncmlkIHRvIGF2b2lkIGEgY29tcGlsZS10aW1lIGltcG9ydCBjeWNsZSkgLS0+XG4gICAgICAgICAgICBAaWYgKG1hc3RlckRldGFpbCAmJiBub2RlLmV4cGFuZGVkICYmIG5vZGU/LmRldGFpbFJvd0RhdGEpIHtcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwib25lLXJvdy1kZXRhaWwtY29udGFpbmVyXCIgW2F0dHIuZGF0YS1yb3ctaWRdPVwibm9kZS5yb3dJZCArICctZGV0YWlsJ1wiPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJkZXRhaWxHcmlkVGVtcGxhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgJGltcGxpY2l0OiBub2RlLCBub2RlOiBub2RlIH1cIj5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICB9XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICBAaWYgKCFub2Rlcz8ubGVuZ3RoKSB7XG4gICAgICAgICAgICA8ZGl2IHN0eWxlPVwid2lkdGg6IG1heC1jb250ZW50OyBib3JkZXItdG9wOiAxcHggc29saWQgdHJhbnNwYXJlbnQ7XCI+XG4gICAgICAgICAgICAgICAgPGRpdiBbc3R5bGUud2lkdGgucHhdPVwicm93V2lkdGhcIj48L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgPC9jZGstdmlydHVhbC1zY3JvbGwtdmlld3BvcnQ+XG5cbiAgICA8IS0tIERyb3AgaW5kaWNhdG9yLlxuICAgICAgICAgQSBsaW5lIGF0IHRoZSBpbnNlcnRpb24gcG9pbnQgcmF0aGVyIHRoYW4gYSBnYXAgb3BlbmVkIGJldHdlZW4gcm93czpcbiAgICAgICAgIHRoZSB2aWV3cG9ydCBpcyB2aXJ0dWFsaXNlZCBhdCBhIGZpeGVkIGl0ZW1TaXplLCBzbyBzaGlmdGluZyByb3dzIGFwYXJ0XG4gICAgICAgICB3b3VsZCBkZXN5bmNocm9uaXNlIHRoZSBzY3JvbGxlciBmcm9tIGl0cyBvd24gZ2VvbWV0cnkuIEl0IGlzIGFsc28gdGhlXG4gICAgICAgICBjbGVhcmVyIHNpZ25hbCDigJQgdGhlIHJvdyBsYW5kcyBleGFjdGx5IHdoZXJlIHRoZSBsaW5lIGlzLlxuICAgICAgICAgUG9zaXRpb25lZCBhZ2FpbnN0IHRoZSBib2R5LCB3aXRoIHRoZSB2aWV3cG9ydCdzIHNjcm9sbCBzdWJ0cmFjdGVkLCBzb1xuICAgICAgICAgaXQgc3RheXMgcHV0IHdoaWxlIHRoZSBjb250ZW50IG1vdmVzIHVuZGVyIGl0IGR1cmluZyBhdXRvLXNjcm9sbC4gLS0+XG4gICAgQGlmIChkcm9wSW5kaWNhdG9yVG9wICE9PSBudWxsKSB7XG4gICAgICAgIDxkaXYgY2xhc3M9XCJvbmUtcm93LWRyb3AtaW5kaWNhdG9yXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCJcbiAgICAgICAgICAgICBbc3R5bGUudG9wLnB4XT1cImRyb3BJbmRpY2F0b3JUb3BcIlxuICAgICAgICAgICAgIFtzdHlsZS53aWR0aC5weF09XCJkcm9wSW5kaWNhdG9yV2lkdGhcIj48L2Rpdj5cbiAgICB9XG5cbiAgICA8IS0tIEtleWJvYXJkIHJlb3JkZXJpbmcgaGFzIG5vIGRyYWcgaW1hZ2UgdG8gd2F0Y2gsIHNvIGl0IG5hcnJhdGVzIGluc3RlYWQuXG4gICAgICAgICBBc3NlcnRpdmUgYmVjYXVzZSB0aGUgbWVzc2FnZSBpcyB0aGUgb25seSBmZWVkYmFjayB0aGF0IHRoZSByb3cgbW92ZWQuIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJvbmUtZ3JpZC12aXN1YWxseS1oaWRkZW5cIiByb2xlPVwic3RhdHVzXCIgYXJpYS1saXZlPVwiYXNzZXJ0aXZlXCIgYXJpYS1hdG9taWM9XCJ0cnVlXCI+e3sgZHJhZ0Fubm91bmNlbWVudCB9fTwvZGl2PlxuICAgIEBpZiAoIW5vZGVzPy5sZW5ndGgpIHtcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJvbmUtZ3JpZC1lbXB0eS1tZXNzYWdlXCIgc3R5bGU9XCJwb3NpdGlvbjogYWJzb2x1dGU7IHRvcDogNTAlOyBsZWZ0OiA1MCU7IHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIC01MCUpO1wiPk5vIFJvd3MgdG8gU2hvdzwvc3Bhbj5cbiAgICB9XG5cbiAgICBAaWYgKHBpbm5lZEJvdHRvbU5vZGVzLmxlbmd0aCkge1xuICAgICAgICA8ZGl2ICNwaW5uZWRWaWV3cG9ydCBjbGFzcz1cIm9uZS1waW5uZWQtcm93cyBvbmUtcGlubmVkLXJvd3MtYm90dG9tXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyIFtuZ1RlbXBsYXRlT3V0bGV0XT1cInBpbm5lZFJvd3NcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyBub2RlczogcGlubmVkQm90dG9tTm9kZXMgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8L2Rpdj5cbiAgICB9XG48L2Rpdj5cblxuPCEtLSBQaW5uZWQgcm93cyBhcmUgZGlzcGxheS1vbmx5OiB0aGV5IHJlbmRlciBleGFjdGx5IHdoYXQgYSBkYXRhIGNlbGwgcmVuZGVycyxcbiAgICAgYnV0IGNhcnJ5IG5vbmUgb2YgaXRzIGludGVyYWN0aW9ucy4gQSB0b3RhbHMgcm93IHNob3VsZCBub3Qgb3BlbiBhbiBlZGl0b3JcbiAgICAgb24gZG91YmxlLWNsaWNrIG9yIHN0YXJ0IGEgcmFuZ2Ugc2VsZWN0aW9uIG9uIGRyYWcuIC0tPlxuPG5nLXRlbXBsYXRlICNwaW5uZWRSb3dzIGxldC1ub2Rlcz1cIm5vZGVzXCI+XG4gICAgQGZvciAobm9kZSBvZiBub2RlczsgdHJhY2sgbm9kZS5yb3dJZCkge1xuICAgICAgICA8ZGl2IGNsYXNzPVwib25lLXJvdyBvbmUtcm93LXBpbm5lZFwiIFthdHRyLmRhdGEtcm93LWlkXT1cIm5vZGUucm93SWRcIj5cbiAgICAgICAgICAgIEBmb3IgKGNvbHVtbiBvZiBjb2x1bW5EZWZzOyB0cmFjayBjb2x1bW4uZmllbGQpIHtcbiAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwib25lLWNvbHVtblwiXG4gICAgICAgICAgICAgICAgICAgIFthdHRyLmRhdGEtY2VsbC1pZF09XCJub2RlLnJvd0lkIHwgY2VsbEtleTpjb2x1bW4uZmllbGRcIlxuICAgICAgICAgICAgICAgICAgICBbY2xhc3Mub25lLWNvbHVtbi1waW5uZWQtbGVmdF09XCJjb2x1bW4ucGlubmVkID09PSAnbGVmdCdcIlxuICAgICAgICAgICAgICAgICAgICBbY2xhc3Mub25lLWNvbHVtbi1waW5uZWQtcmlnaHRdPVwiY29sdW1uLnBpbm5lZCA9PT0gJ3JpZ2h0J1wiXG4gICAgICAgICAgICAgICAgICAgIFtjbGFzcy5vbmUtY29sdW1uLXBpbm5lZC1lZGdlXT1cImNvbHVtbi5fcGlubmVkRWRnZVwiXG4gICAgICAgICAgICAgICAgICAgIFtzdHlsZS5sZWZ0LnB4XT1cImNvbHVtbi5waW5uZWQgPT09ICdsZWZ0JyA/IGNvbHVtbi5fcGlubmVkT2Zmc2V0IDogbnVsbFwiXG4gICAgICAgICAgICAgICAgICAgIFtzdHlsZS5yaWdodC5weF09XCJjb2x1bW4ucGlubmVkID09PSAncmlnaHQnID8gY29sdW1uLl9waW5uZWRPZmZzZXQgOiBudWxsXCJcbiAgICAgICAgICAgICAgICAgICAgW3N0eWxlLndpZHRoLnB4XT1cImNvbHVtbj8ud2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICBbc3R5bGUubWluLXdpZHRoLnB4XT1cImNvbHVtbj8ubWluV2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICBbc3R5bGUubWF4LXdpZHRoLnB4XT1cImNvbHVtbj8ubWF4V2lkdGhcIj5cblxuICAgICAgICAgICAgICAgICAgICBAaWYgKGNvbHVtbj8uY2VsbFJlbmRlcmVyQ29tcG9uZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25lQ2VsbFJlbmRlcmVyQ29tcG9uZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NlbGxSZW5kZXJlckNvbXBvbmVudF09XCJjb2x1bW4/LmNlbGxSZW5kZXJlckNvbXBvbmVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BhcmFtc109XCJyZW5kZXJlclBhcmFtcyhub2RlLCBjb2x1bW4pXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBAZWxzZSBpZiAoY29sdW1uPy5jZWxsUmVuZGVyZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJ7IHdpZHRoOiBjb2x1bW4ud2lkdGggKyAncHgnLCBwb3NpdGlvbjogJ3JlbGF0aXZlJyB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaW5uZXJIVE1MXT1cIm5vZGUuY2VsbFN0YXRlcyB8IGNlbGxTdGF0ZVJlbmRlcmVyOmNvbHVtbi5maWVsZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm9uZS1jZWxsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuYWxpZ24tY29udGVudC1sZWZ0XT1cImNvbHVtbj8uYWxpZ25Db250ZW50ID09PSAnbGVmdCdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5hbGlnbi1jb250ZW50LWNlbnRlcl09XCJjb2x1bW4/LmFsaWduQ29udGVudCA9PT0gJ2NlbnRlcidcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5hbGlnbi1jb250ZW50LXJpZ2h0XT1cImNvbHVtbj8uYWxpZ25Db250ZW50ID09PSAncmlnaHQnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJjb2xTZXJ2aWNlLnJlc29sdmVDZWxsQ2xhc3MoY29sdW1uLCBjZWxsUGFyYW1zKG5vZGUsIGNvbHVtbikpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJjb2xTZXJ2aWNlLnJlc29sdmVDZWxsU3R5bGUoY29sdW1uLCBjZWxsUGFyYW1zKG5vZGUsIGNvbHVtbikpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm9uZS1jZWxsLXRleHRcIj57eyAobm9kZS5jZWxsU3RhdGVzIHwgY2VsbFN0YXRlUmVuZGVyZXI6Y29sdW1uLmZpZWxkKSB9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgPC9kaXY+XG4gICAgfVxuPC9uZy10ZW1wbGF0ZT5cblxuPCEtLSBNYXN0ZXIgQ29sdW1uIFRlbXBsYXRlICAtLT5cbjxuZy10ZW1wbGF0ZSAjY2VsbFRlbXBsYXRlIGxldC1ub2RlPVwibm9kZVwiIGxldC1yb3dJbmRleD1cInJvd0luZGV4XCIgbGV0LWNvbHVtbj1cImNvbHVtblwiPlxuICAgIDxkaXZcbiAgICAgICAgY2xhc3M9XCJvbmUtY29sdW1uXCJcbiAgICAgICAgW2F0dHIuZGF0YS1jZWxsLWlkXT1cIm5vZGUucm93SWQgfCBjZWxsS2V5OmNvbHVtbi5maWVsZFwiXG4gICAgICAgIFtjbGFzcy5vbmUtY29sdW1uLXBpbm5lZC1sZWZ0XT1cImNvbHVtbi5waW5uZWQgPT09ICdsZWZ0J1wiXG4gICAgICAgIFtjbGFzcy5vbmUtY29sdW1uLXBpbm5lZC1yaWdodF09XCJjb2x1bW4ucGlubmVkID09PSAncmlnaHQnXCJcbiAgICAgICAgW2NsYXNzLm9uZS1jb2x1bW4tcGlubmVkLWVkZ2VdPVwiY29sdW1uLl9waW5uZWRFZGdlXCJcbiAgICAgICAgW3N0eWxlLmxlZnQucHhdPVwiY29sdW1uLnBpbm5lZCA9PT0gJ2xlZnQnID8gY29sdW1uLl9waW5uZWRPZmZzZXQgOiBudWxsXCJcbiAgICAgICAgW3N0eWxlLnJpZ2h0LnB4XT1cImNvbHVtbi5waW5uZWQgPT09ICdyaWdodCcgPyBjb2x1bW4uX3Bpbm5lZE9mZnNldCA6IG51bGxcIlxuICAgICAgICBbc3R5bGUud2lkdGgucHhdPVwiY29sdW1uPy53aWR0aFwiXG4gICAgICAgIFtzdHlsZS5taW4td2lkdGgucHhdPVwiY29sdW1uPy5taW5XaWR0aFwiXG4gICAgICAgIFtzdHlsZS5tYXgtd2lkdGgucHhdPVwiY29sdW1uPy5tYXhXaWR0aFwiXG4gICAgICAgIFtjbGFzcy5vbmUtY29sdW1uLWJvcmRlci10b3BdPVwibWFzdGVyRGV0YWlsICYmIG5vZGVzPy5sZW5ndGggPiAwICYmIG5vZGVzW25vZGUucm93SW5kZXggLSAxXT8uZXhwYW5kZWRcIlxuICAgICAgICBbY2xhc3Mub25lLWNlbGwtc2VsZWN0ZWRdPVwic2VsZWN0ZWRDZWxscyB8IGNlbGxTZWxlY3RlZDpub2RlLnJvd0lkOmNvbHVtbi5maWVsZFwiXG4gICAgICAgIFtjbGFzcy5vbmUtY2VsbC1pbnZhbGlkXT1cIm5vZGUuY2VsbFN0YXRlcyB8IGNlbGxJbnZhbGlkOm5vZGUuZGF0YVtjb2x1bW4uZmllbGRdOmNvbHVtbjpub2RlOmFsbG93ZWRFZGl0OnN1Ym1pdHRlZFwiXG4gICAgICAgIChkYmxjbGljayk9XCJzdGFydEVkaXQoJGV2ZW50LCBub2RlLCBjb2x1bW4pXCJcbiAgICAgICAgKG1vdXNlZG93bik9XCJzdGFydFNlbGVjdGlvbihub2RlLnJvd0lkLCBjb2x1bW4uZmllbGQpXCJcbiAgICAgICAgKG1vdXNlZW50ZXIpPVwiZXh0ZW5kU2VsZWN0aW9uKG5vZGUucm93SWQsIGNvbHVtbi5maWVsZClcIlxuICAgICAgICAobW91c2V1cCk9XCJlbmRTZWxlY3Rpb24oKVwiPlxuXG4gICAgICAgIDwhLS0gT25lIEdyaWQgQ2VsbCBPcHRpb24gLS0+XG4gICAgICAgIEBpZiAobm9kZS5jZWxsT3B0aW9uc1tjb2x1bW4uZmllbGRdKSB7XG4gICAgICAgICAgICA8b25lLWdyaWQtY2VsbC1vcHRpb24tbWVudVxuICAgICAgICAgICAgICAgICNjb250ZXh0T3B0aW9uTWVudVJlZlxuICAgICAgICAgICAgICAgIFtub2RlXT1cIm5vZGVcIlxuICAgICAgICAgICAgICAgIFtjb2x1bW5dPVwiY29sdW1uXCJcbiAgICAgICAgICAgICAgICBbb3B0aW9uc109XCJjb2x1bW4uY2VsbE9wdGlvbk1lbnVcIlxuICAgICAgICAgICAgICAgIChjZWxsT3B0aW9uTWVudVNlbGVjdCk9XCJjZWxsT3B0aW9uTWVudVNlbGVjdGVkKCRldmVudClcIlxuICAgICAgICAgICAgICAgIChjZWxsT3B0aW9uTWVudUNsb3NlKT1cImNlbGxPcHRpb25NZW51Q2xvc2VkKClcIi8+XG4gICAgICAgIH1cblxuICAgICAgICA8IS0tIEdyaWQgQ2VsbCBUZW1wbGF0ZSAtLT5cbiAgICAgICAgQGlmKGNvbHVtbj8uY2VsbFJlbmRlcmVyQ29tcG9uZW50KSB7XG4gICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgb25lQ2VsbFJlbmRlcmVyQ29tcG9uZW50XG4gICAgICAgICAgICAgICAgW2NlbGxSZW5kZXJlckNvbXBvbmVudF09XCJjb2x1bW4/LmNlbGxSZW5kZXJlckNvbXBvbmVudFwiXG4gICAgICAgICAgICAgICAgW3BhcmFtc109XCJyZW5kZXJlclBhcmFtcyhub2RlLCBjb2x1bW4pXCI+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgfVxuICAgICAgICBAZWxzZSBpZiAobm9kZS5lZGl0aW5nW2NvbHVtbi5maWVsZF0pIHtcbiAgICAgICAgICAgIDwhLS0gQ2VsbCBFZGl0aW5nIElucHV0IC0tPlxuICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwib25lLWNlbGwtaW5wdXRcIlxuICAgICAgICAgICAgICAgIG5hbWU9XCJ7eyBub2RlLnJvd0lkICsgJycgKyBjb2x1bW4uZmllbGQgfX1cIlxuICAgICAgICAgICAgICAgIG9uZUNlbGxJbnB1dFZhbGlkYXRvclxuICAgICAgICAgICAgICAgIFt2YWxpZGF0aW9uVHlwZV09XCJjb2x1bW4/LmNlbGxSZW5kZXJlclBhcmFtcz8uaW5wdXRUeXBlID09PSAnbnVtYmVyJyA/ICdudW1iZXInIDogJ25vbmUnXCJcbiAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiY29sdW1uPy5jZWxsUmVuZGVyZXJQYXJhbXM/LnBsYWNlaG9sZGVyXCJcbiAgICAgICAgICAgICAgICBbdHlwZV09XCJjb2x1bW4/LmNlbGxSZW5kZXJlclBhcmFtcz8uaW5wdXRUeXBlID09PSAnbnVtYmVyJyA/ICd0ZXh0JyA6IGNvbHVtbj8uY2VsbFJlbmRlcmVyUGFyYW1zPy5pbnB1dFR5cGVcIlxuICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJub2RlPy5kYXRhW2NvbHVtbj8uZmllbGRdXCJcbiAgICAgICAgICAgICAgICBbbWF4TGVuZ3RoXT1cIjI1MFwiXG4gICAgICAgICAgICAgICAgKGJsdXIpPVwic3RvcEVkaXQobm9kZSwgY29sdW1uLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAoa2V5ZG93bi5lbnRlcik9XCJzdG9wRWRpdChub2RlLCBjb2x1bW4sICRldmVudClcIlxuICAgICAgICAgICAgICAgIChrZXlkb3duLmVzYyk9XCJjYW5jZWxFZGl0KG5vZGUsIGNvbHVtbilcIlxuICAgICAgICAgICAgLz5cbiAgICAgICAgfVxuICAgICAgICBAZWxzZSBpZiAoY29sdW1uPy5jZWxsUmVuZGVyZXIpIHtcbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJ7IHdpZHRoOiBjb2x1bW4ud2lkdGggKyAncHgnICwgcG9zaXRpb246ICdyZWxhdGl2ZScgfVwiXG4gICAgICAgICAgICAgICAgW2lubmVySFRNTF09XCJub2RlLmNlbGxTdGF0ZXMgfCBjZWxsU3RhdGVSZW5kZXJlcjpjb2x1bW4uZmllbGRcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5lZGl0YWJsZS1hY3RpdmVdPVwibm9kZS5jZWxsU3RhdGVzIHwgY2VsbEVkaXRhYmxlOmNvbHVtbjpub2RlOmNlbGxTZXJ2aWNlLmVkaXRhYmxlRm46Y2VsbFNlcnZpY2UudXBkYXRhYmxlRm46YWxsb3dlZEVkaXRcIj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICAgIEBlbHNlIHtcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvbmUtY2VsbFwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmFsaWduLWNvbnRlbnQtbGVmdF09XCJjb2x1bW4/LmFsaWduQ29udGVudCA9PT0gJ2xlZnQnXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MuYWxpZ24tY29udGVudC1jZW50ZXJdPVwiY29sdW1uPy5hbGlnbkNvbnRlbnQgPT09ICdjZW50ZXInXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MuYWxpZ24tY29udGVudC1yaWdodF09XCJjb2x1bW4/LmFsaWduQ29udGVudCA9PT0gJ3JpZ2h0J1wiXG4gICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiY29sU2VydmljZS5yZXNvbHZlQ2VsbENsYXNzKGNvbHVtbiwgY2VsbFBhcmFtcyhub2RlLCBjb2x1bW4pKVwiXG4gICAgICAgICAgICAgICAgW25nU3R5bGVdPVwiY29sU2VydmljZS5yZXNvbHZlQ2VsbFN0eWxlKGNvbHVtbiwgY2VsbFBhcmFtcyhub2RlLCBjb2x1bW4pKVwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLnBhZGRpbmctbGVmdC5weF09XCJjb2x1bW4uYXV0b0dyb3VwRmllbGQgJiYgbm9kZS5sZXZlbCB8IGNlbGxMZXZlbFBhZGRpbmc6MjRcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5vbmUtY2VsbC1hbGxvd2VkLWVkaXQtYWN0aXZlXT1cIm5vZGUuY2VsbFN0YXRlcyB8IGNlbGxFZGl0YWJsZTpjb2x1bW46bm9kZTpjZWxsU2VydmljZS5lZGl0YWJsZUZuOmNlbGxTZXJ2aWNlLnVwZGF0YWJsZUZuOmFsbG93ZWRFZGl0XCI+XG5cbiAgICAgICAgICAgICAgICA8IS0tIFJvdyBEcmFnIEhhbmRsZSAtLT5cbiAgICAgICAgICAgICAgICBAaWYgKGNlbGxTZXJ2aWNlLnJvd0RyYWdGbihjb2x1bW4sIG5vZGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIDxvbmUtZ3JpZC1yb3ctZHJhZy1oYW5kbGVcbiAgICAgICAgICAgICAgICAgICAgICAgIFtub2RlXT1cIm5vZGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW3N1cHByZXNzZWRSZWFzb25dPVwicm93RHJhZ1N1cHByZXNzZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGRyYWdFbmQpPVwib25Sb3dEcmFnRW5kKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIDwhLS0gQ2VsbCBDaGVja2JveCBTZWxlY3Rpb24gLS0+XG4gICAgICAgICAgICAgICAgQGlmIChjb2x1bW4/LmNoZWNrYm94U2VsZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIDxvbmUtZ3JpZC1jaGVja2JveFxuICAgICAgICAgICAgICAgICAgICAgICAgW25vZGVdPVwibm9kZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbYWxsb3dlZEVkaXRdPVwiYWxsb3dlZEVkaXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2FwaV09XCJhcGlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKG9uUm93U2VsZWN0aW9uKT1cImludm9rZVJvd0FjdGlvblNlbGVjdGlvbigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICA8IS0tIEV4cGFuZCAmIENvbGxhcHNlIEljb24gLS0+XG4gICAgICAgICAgICAgICAgQGlmICgoKG5vZGU/Lmdyb3VwIHx8IGRldGFpbFJlbmRlcmVyQ29tcG9uZW50KSAmJiBjb2x1bW4/LmF1dG9Hcm91cEZpZWxkKSB8fCAobWFzdGVyRGV0YWlsICYmIG5vZGU/LmV4cGFuZGFibGUgJiYgZ3JpZFR5cGUgPT09ICdtYXN0ZXInICYmIGNvbHVtbj8ubWFzdGVyR3JvdXBGaWVsZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgPG9uZS1ncmlkLWNlbGwtZ3JvdXAtcmVuZGVyZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtub2RlXT1cIm5vZGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW21hc3RlckRldGFpbF09XCJtYXN0ZXJEZXRhaWxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2RldGFpbENlbGxSZW5kZXJlclBhcmFtc109XCJkZXRhaWxDZWxsUmVuZGVyZXJQYXJhbXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2RldGFpbFJlbmRlcmVyQ29tcG9uZW50XT1cImRldGFpbFJlbmRlcmVyQ29tcG9uZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChleHBhbnNpb25DaGFuZ2VkKT1cImludm9rZUV4cGFuc2lvbkNoYW5nZWRDbGljaygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBAaWYoY29sdW1uPy5jZWxsUmVuZGVyZXJDb21wb25lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgb25lQ2VsbFJlbmRlcmVyQ29tcG9uZW50XG4gICAgICAgICAgICAgICAgICAgICAgICBbY2VsbFJlbmRlcmVyQ29tcG9uZW50XT1cImNvbHVtbj8uY2VsbFJlbmRlcmVyQ29tcG9uZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtwYXJhbXNdPVwicmVuZGVyZXJQYXJhbXMobm9kZSwgY29sdW1uKVwiPlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICA8IS0tIENlbGwgVmFsdWUgT1IgUGxhY2Vob2xkZXIgLS0+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgb25lQ2VsbFRleHRFeHBhbmQgY2xhc3M9XCJvbmUtY2VsbC10ZXh0XCIgW2NsYXNzLm9uZS1jZWxsLXBsYWNlaG9sZGVyXT1cIm5vZGUuY2VsbFN0YXRlc1tjb2x1bW4uZmllbGRdPy50eXBlID09PSAncGxhY2Vob2xkZXInXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICB7eyAobm9kZS5jZWxsU3RhdGVzIHwgY2VsbFN0YXRlUmVuZGVyZXI6Y29sdW1uLmZpZWxkKSB9fVxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICA8IS0tIENlbGwgQWN0aW9uIEJ1dHRvbnMgLS0+XG4gICAgICAgICAgICAgICAgQGlmIChjb2x1bW4uY2VsbFJlbmRlcmVyUGFyYW1zIHwgY2VsbEFjdGlvbkJ1dHRvbkVuYWJsZSkge1xuICAgICAgICAgICAgICAgICAgICA8b25lLWdyaWQtcm93LWFjdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgW25nU3R5bGVdPVwieyBtYXJnaW5MZWZ0OiAnYXV0bycgfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbY29sdW1uXT1cImNvbHVtblwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbm9kZV09XCJub2RlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFthbGxvd2VkRWRpdF09XCJhbGxvd2VkRWRpdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbWFzdGVyTm9kZV09XCJtYXN0ZXJOb2RlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFttYXN0ZXJEZXRhaWxdPVwibWFzdGVyRGV0YWlsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtncmlkVHlwZV09XCJncmlkVHlwZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbY29udGV4dF09XCJjb250ZXh0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjZWxsUmVuZGVyZXJQYXJhbXNdPVwiY29sdW1uPy5jZWxsUmVuZGVyZXJQYXJhbXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKG9uUm93R290b0RldGFpbCk9XCJpbnZva2VSb3dBY3Rpb25Hb3RvRGV0YWlsKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKG9uUm93QWRkTmV3KT1cImludm9rZVJvd0FjdGlvbkFkZE5ldygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChvblJvd1ZpZXcpPVwiaW52b2tlUm93QWN0aW9uVmlldygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChvblJvd0xvY2F0aW9uKT1cImludm9rZVJvd0FjdGlvbkxvY2F0aW9uKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKG9uUm93RG9jdW1lbnQpPVwiaW52b2tlUm93QWN0aW9uRG9jdW1lbnQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAob25Sb3dDb3B5KT1cImludm9rZVJvd0FjdGlvbkNvcHkoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAob25Sb3dEZWxldGUpPVwiaW52b2tlUm93QWN0aW9uRGVsZXRlKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKG9uUm93R290b0xpc3QpPVwiaW52b2tlUm93QWN0aW9uR290b0xpc3QoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAob25Sb3dFZGl0KT1cImludm9rZVJvd0FjdGlvbkVkaXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAob25Sb3dQcmludCk9XCJpbnZva2VSb3dBY3Rpb25QcmludCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChvblJvd0hpc3RvcnkpPVwiaW52b2tlUm93QWN0aW9uSGlzdG9yeSgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChvblJvd09wdGlvbik9XCJpbnZva2VSb3dBY3Rpb25PcHRpb24oJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAob25Sb3dMYW5ndWFnZSk9XCJpbnZva2VSb3dBY3Rpb25MYW5ndWFnZSgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChvblJvd0NlbGxPcHRpb24pPVwiaW52b2tlUm93QWN0aW9uQ2VsbE9wdGlvbigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuICAgIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==
1234
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib25lLWdyaWQtYm9keS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9vbmUtZ3JpZC9zcmMvbGliL2NvbXBvbmVudHMvb25lLWdyaWQtYm9keS9vbmUtZ3JpZC1ib2R5LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL29uZS1ncmlkL3NyYy9saWIvY29tcG9uZW50cy9vbmUtZ3JpZC1ib2R5L29uZS1ncmlkLWJvZHkuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFpQix1QkFBdUIsRUFBcUIsU0FBUyxFQUFjLFlBQVksRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFxQixNQUFNLEVBQWdDLFNBQVMsRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFLdE8sT0FBTyxFQUFXLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUM3QyxPQUFPLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBSzlDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxVQUFVLEVBQUUsYUFBYSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFFMUUsT0FBTyxFQUFFLHdCQUF3QixFQUFFLGVBQWUsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRW5GLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBR3pFLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDckUsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sa0RBQWtELENBQUM7QUFDNUYsT0FBTyxFQUFFLGlDQUFpQyxFQUFFLE1BQU0sd0VBQXdFLENBQUM7QUFDM0gsT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0sa0VBQWtF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bEIsTUFBTTtnQkFDRyxhQUFhO3NCQUF0QixNQUFNO2dCQUNHLGFBQWE7c0JBQXRCLE1BQU07Z0JBQ0csV0FBVztzQkFBcEIsTUFBTTtnQkFDRyxhQUFhO3NCQUF0QixNQUFNO2dCQUNHLFNBQVM7c0JBQWxCLE1BQU07Z0JBQ0csVUFBVTtzQkFBbkIsTUFBTTtnQkFDRyxZQUFZO3NCQUFyQixNQUFNO2dCQUNHLFdBQVc7c0JBQXBCLE1BQU07Z0JBQ0csYUFBYTtzQkFBdEIsTUFBTTtnQkFDRyxlQUFlO3NCQUF4QixNQUFNO2dCQUNHLGNBQWM7c0JBQXZCLE1BQU07Z0JBQ0csa0JBQWtCO3NCQUEzQixNQUFNO2dCQUNHLGVBQWU7c0JBQXhCLE1BQU07Z0JBRUcsZ0JBQWdCO3NCQUF6QixNQUFNO2dCQUNHLFVBQVU7c0JBQW5CLE1BQU07Z0JBQ0csZ0JBQWdCO3NCQUF6QixNQUFNO2dCQUNHLFVBQVU7c0JBQW5CLE1BQU07Z0JBK1VQLGVBQWU7c0JBRGQsWUFBWTt1QkFBQyxnQkFBZ0IsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFrQjFDLGVBQWU7c0JBRGQsWUFBWTt1QkFBQyxrQkFBa0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBZnRlclZpZXdJbml0LCBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBIb3N0TGlzdGVuZXIsIElucHV0LCBPbkRlc3Ryb3ksIE9uSW5pdCwgT3V0cHV0LCBRdWVyeUxpc3QsIFRlbXBsYXRlUmVmLCBUeXBlLCBWaWV3Q2hpbGQsIFZpZXdDaGlsZHJlbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ2VsbFNlbGVjdGlvbiwgT25lQ2VsbFByZXNlbnRhdGlvblBhcmFtcywgT25lQ2VsbFJlbmRlcmVyUGFyYW1zLCBPbmVDb2x1bW5EZWYgfSBmcm9tICcuLi8uLi9jb3JlL21vZGVscy9vbmUtY29sdW1uLWRlZi10eXBlcy5tb2RlbCc7XG5pbXBvcnQgeyBPbmVDZWxsUmVuZGVyZXJDb21wb25lbnQgfSBmcm9tICcuLi8uLi9jb3JlL21vZGVscy9vbmUtdHJlZS1kYXRhLm1vZGVsJztcbmltcG9ydCB7IE9uZVJvd05vZGUgfSBmcm9tICcuLi8uLi9jb3JlL2luc3RhbnRzL29uZS1yb3ctbm9kZS5jbGFzcyc7XG5pbXBvcnQgeyBPbmVHcmlkQXBpIH0gZnJvbSAnLi4vLi4vY29yZS9pbnN0YW50cy9vbmUtZ3JpZC1hcGkuY2xhc3MnO1xuaW1wb3J0IHsgU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBmaWx0ZXIsIHRha2UgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBPbmVHcmlkR2V0Um93SWRQYXJhbXMsIE9uZUdyaWRSZWFkeUV2ZW50LCBPbmVHcmlkUm93QWN0aW9uRXZlbnQsIE9uZUdyaWRUeXBlIH0gZnJvbSAnLi4vLi4vY29yZS9tb2RlbHMvb25lLWdyaWQtdHlwZXMubW9kZWwnO1xuaW1wb3J0IHsgT25lR3JpZEV2ZW50U2VydmljZSB9IGZyb20gJy4uLy4uL2NvcmUvc2VydmljZXMvb25lLWdyaWQtZXZlbnQuc2VydmljZSc7XG5pbXBvcnQgeyBDZWxsT3B0aW9uTWVudVNlbGVjdGVkRXZlbnQsIENvbHVtbkNoYW5nZWRFdmVudCwgRXhwYW5zaW9uQ2hhbmdlZEV2ZW50LCBQaW5uZWRSb3dEYXRhQ2hhbmdlZEV2ZW50LCBSb3dEYXRhQ2hhbmdlZEV2ZW50LCBSb3dPcmRlckNoYW5nZWRFdmVudCwgU2VsZWN0aW9uQ2hhbmdlZEV2ZW50LCBTb3J0Q2hhbmdlZEV2ZW50IH0gZnJvbSAnLi4vLi4vY29yZS9tb2RlbHMvb25lLWV2ZW50LXR5cGVzLm1vZGVsJztcbmltcG9ydCB7IE9uZURldGFpbENlbGxSZW5kZXJlclBhcmFtcyB9IGZyb20gJy4uLy4uL2NvcmUvbW9kZWxzL29uZS1tYXN0ZXItZGV0YWlsLm1vZGVsJztcbmltcG9ydCB7IENlbGxFZGl0YWJsZVBpcGUgfSBmcm9tICcuLi8uLi9jb3JlL3BpcGVzL2NlbGwtZWRpdGFibGUucGlwZSc7XG5pbXBvcnQgeyBnZXRDZWxsS2V5LCBnZXRGaWVsZFZhbHVlIH0gZnJvbSAnLi4vLi4vaGVscGVycy9vbmUtY2VsbC5oZWxwZXInO1xuaW1wb3J0IHsgT25lR3JpZENlbGxTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29yZS9zZXJ2aWNlcy9vbmUtZ3JpZC1jZWxsLnNlcnZpY2UnO1xuaW1wb3J0IHsgQ2RrVmlydHVhbFNjcm9sbFZpZXdwb3J0LCBTY3JvbGxpbmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jZGsvc2Nyb2xsaW5nJztcbmltcG9ydCB7IE9nQ29sdW1uU2VydmljZSB9IGZyb20gJy4uLy4uL2NvcmUvc2VydmljZXMvb2ctY29sdW1uLnNlcnZpY2UnO1xuaW1wb3J0IHsgcmVzb2x2ZUNvbHVtbldpZHRoIH0gZnJvbSAnLi4vLi4vaGVscGVycy9vbmUtY29sdW1uLWRlZi5oZWxwZXInO1xuaW1wb3J0IHsgT25lR3JpZFJvd0RyYWdTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29yZS9zZXJ2aWNlcy9vbmUtZ3JpZC1yb3ctZHJhZy5zZXJ2aWNlJztcbmltcG9ydCB7IE9uZVJvd0RyYWdFdmVudCwgT25lUm93RHJhZ1N0YXRlLCBPbmVSb3dEcmFnU3VwcHJlc3NlZFJlYXNvbiB9IGZyb20gJy4uLy4uL2NvcmUvbW9kZWxzL29uZS1yb3ctZHJhZy5tb2RlbCc7XG5pbXBvcnQgeyBOZ0NsYXNzLCBOZ1N0eWxlLCBOZ1RlbXBsYXRlT3V0bGV0IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IE9uZUdyaWRDaGVja2JveENvbXBvbmVudCB9IGZyb20gJy4uL29uZS1ncmlkLWNoZWNrYm94L29uZS1ncmlkLWNoZWNrYm94LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBPbmVHcmlkQ2VsbEdyb3VwUmVuZGVyZXJDb21wb25lbnQgfSBmcm9tICcuLi9vbmUtZ3JpZC1jZWxsLWdyb3VwLXJlbmRlcmVyL29uZS1ncmlkLWNlbGwtZ3JvdXAtcmVuZGVyZXIuY29tcG9uZW50JztcbmltcG9ydCB7IE9uZUdyaWRDZWxsT3B0aW9uTWVudUNvbXBvbmVudCB9IGZyb20gJy4uL29uZS1ncmlkLWNlbGwtb3B0aW9uLW1lbnUvb25lLWdyaWQtY2VsbC1vcHRpb24tbWVudS5jb21wb25lbnQnO1xuaW1wb3J0IHsgT25lR3JpZFJvd0FjdGlvbkNvbXBvbmVudCB9IGZyb20gJy4uL29uZS1ncmlkLXJvdy1hY3Rpb24vb25lLWdyaWQtcm93LWFjdGlvbi5jb21wb25lbnQnO1xuaW1wb3J0IHsgT25lR3JpZFJvd0RyYWdIYW5kbGVDb21wb25lbnQgfSBmcm9tICcuLi9vbmUtZ3JpZC1yb3ctZHJhZy1oYW5kbGUvb25lLWdyaWQtcm93LWRyYWctaGFuZGxlLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBPbmVDZWxsSW5wdXRWYWxpZGF0b3JEaXJlY3RpdmUgfSBmcm9tICcuLi8uLi9jb3JlL2RpcmVjdGl2ZXMvb25lLWNlbGwtaW5wdXQtdmFsaWRhdG9yLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBPbmVDZWxsUmVuZGVyZXJDb21wb25lbnREaXJlY3RpdmUgfSBmcm9tICcuLi8uLi9jb3JlL2RpcmVjdGl2ZXMvb25lLWNlbGwtcmVuZGVyZXItY29tcG9uZW50LmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBPbmVDZWxsVGV4dEV4cGFuZERpcmVjdGl2ZSB9IGZyb20gJy4uLy4uL2NvcmUvZGlyZWN0aXZlcy9vbmUtY2VsbC10ZXh0LWV4cGFuZC5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgQ2VsbEFjdGlvbkJ1dHRvbkVuYWJsZVBpcGUgfSBmcm9tICcuLi8uLi9jb3JlL3BpcGVzL2NlbGwtYWN0aW9uLWJ1dHRvbi1lbmFibGUucGlwZSc7XG5pbXBvcnQgeyBDZWxsSW52YWxpZFBpcGUgfSBmcm9tICcuLi8uLi9jb3JlL3BpcGVzL2NlbGwtaW52YWxpZC5waXBlJztcbmltcG9ydCB7IENlbGxLZXlQaXBlIH0gZnJvbSAnLi4vLi4vY29yZS9waXBlcy9jZWxsLWtleS5waXBlJztcbmltcG9ydCB7IENlbGxMZXZlbFBhZGRpbmdQaXBlIH0gZnJvbSAnLi4vLi4vY29yZS9waXBlcy9jZWxsLWxldmVsLXBhZGRpbmcucGlwZSc7XG5pbXBvcnQgeyBDZWxsU2VsZWN0ZWRQaXBlIH0gZnJvbSAnLi4vLi4vY29yZS9waXBlcy9jZWxsLXNlbGVjdGVkLnBpcGUnO1xuaW1wb3J0IHsgQ2VsbFN0YXRlUmVuZGVyZXJQaXBlIH0gZnJvbSAnLi4vLi4vY29yZS9waXBlcy9jZWxsLXN0YXRlLXJlbmRlcmVyLnBpcGUnO1xuXG5AQ29tcG9uZW50KHtcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIE5nQ2xhc3MsXG4gICAgTmdTdHlsZSxcbiAgICBOZ1RlbXBsYXRlT3V0bGV0LFxuICAgIFNjcm9sbGluZ01vZHVsZSxcbiAgICBPbmVHcmlkQ2hlY2tib3hDb21wb25lbnQsXG4gICAgT25lR3JpZENlbGxHcm91cFJlbmRlcmVyQ29tcG9uZW50LFxuICAgIE9uZUdyaWRDZWxsT3B0aW9uTWVudUNvbXBvbmVudCxcbiAgICBPbmVHcmlkUm93QWN0aW9uQ29tcG9uZW50LFxuICAgIE9uZUdyaWRSb3dEcmFnSGFuZGxlQ29tcG9uZW50LFxuICAgIE9uZUNlbGxJbnB1dFZhbGlkYXRvckRpcmVjdGl2ZSxcbiAgICBPbmVDZWxsUmVuZGVyZXJDb21wb25lbnREaXJlY3RpdmUsXG4gICAgT25lQ2VsbFRleHRFeHBhbmREaXJlY3RpdmUsXG4gICAgQ2VsbEFjdGlvbkJ1dHRvbkVuYWJsZVBpcGUsXG4gICAgQ2VsbEVkaXRhYmxlUGlwZSxcbiAgICBDZWxsSW52YWxpZFBpcGUsXG4gICAgQ2VsbEtleVBpcGUsXG4gICAgQ2VsbExldmVsUGFkZGluZ1BpcGUsXG4gICAgQ2VsbFNlbGVjdGVkUGlwZSxcbiAgICBDZWxsU3RhdGVSZW5kZXJlclBpcGUsXG4gIF0sXG4gIHNlbGVjdG9yOiAnb25lLWdyaWQtYm9keScsXG4gIC8vIFRoZSBob3N0IHNpdHMgYmV0d2VlbiByb2xlPVwiZ3JpZFwiIGFuZCB0aGUgcm93cyBpdCBtdXN0IG93bjsgYSBnZW5lcmljXG4gIC8vIGVsZW1lbnQgdGhlcmUgYnJlYWtzIHRoZSBvd25lcnNoaXAgY2hhaW4sIHNvIGl0IGxlYXZlcyB0aGUgYTExeSB0cmVlLlxuICBob3N0OiB7ICdyb2xlJzogJ3ByZXNlbnRhdGlvbicgfSxcbiAgdGVtcGxhdGVVcmw6ICcuL29uZS1ncmlkLWJvZHkuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJy4vb25lLWdyaWQtYm9keS5jb21wb25lbnQuc2NzcycsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBPbmVHcmlkQm9keUNvbXBvbmVudDxUPiBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcblxuICAvKipcbiAgICogQ29yZSBQcm9wZXJ0aWVzXG4gICAqL1xuICBAVmlld0NoaWxkKCdib2R5UmVmJywgeyBzdGF0aWM6IHRydWUgfSkgYm9keVJlZiE6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+O1xuICBASW5wdXQoeyByZXF1aXJlZDogdHJ1ZSB9KSByb3dEYXRhOiBUW10gPSBbXTtcbiAgQElucHV0KCkgcm93TnVtYmVyOiBib29sZWFuO1xuICBASW5wdXQoKSBhcGkhOiBPbmVHcmlkQXBpPFQ+O1xuICBASW5wdXQoKSBwYWdpbmF0aW9uOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIGFsbG93ZWRFZGl0OiBib29sZWFuID0gdHJ1ZTtcbiAgQElucHV0KCkgZW5hYmxlR3JvdXBDb2x1bW5EZWZzOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIHN1Ym1pdHRlZDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBgJ2Z1bGxSb3cnYDogYSBkb3VibGUtY2xpY2sgb3BlbnMgZXZlcnkgZWRpdGFibGUgY2VsbCBvZiB0aGUgcm93LCBFbnRlciBvclxuICAgKiBmb2N1cyBsZWF2aW5nIHRoZSByb3cgY29tbWl0cyB0aGVtIHRvZ2V0aGVyLCBFc2NhcGUgY2xvc2VzIHRoZW0gYWxsXG4gICAqIHdpdGhvdXQgY29tbWl0dGluZy4gRGVmYXVsdDogb25lIGNlbGwgYXQgYSB0aW1lLlxuICAgKi9cbiAgQElucHV0KCkgZWRpdFR5cGU6ICdmdWxsUm93JyB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoKSBjb250ZXh0OiBhbnkgPSBudWxsO1xuICBASW5wdXQoKSBnZXRSb3dJZDogKHBhcmFtczogT25lR3JpZEdldFJvd0lkUGFyYW1zPFQ+KSA9PiBzdHJpbmc7XG4gIEBJbnB1dCh7IHJlcXVpcmVkOiB0cnVlIH0pIGdyaWRDb3B5JCE6IFN1YmplY3Q8Q2xpcGJvYXJkRXZlbnQ+O1xuXG4gIC8qKlxuICAgKiBQaW5uZWQgcm93cyBhcmUgYm91bmQgb25seSBzbyB0aGUgY29tcG9uZW50IHJlLXJlbmRlcnMgd2hlbiB0aGV5IGNoYW5nZTtcbiAgICogdGhlIG5vZGVzIHRoZW1zZWx2ZXMgY29tZSBmcm9tIHRoZSBBUEksIHdoaWNoIG93bnMgdGhlbS5cbiAgICovXG4gIEBJbnB1dCgpIHBpbm5lZFRvcFJvd0RhdGE6IFRbXSA9IFtdO1xuICBASW5wdXQoKSBwaW5uZWRCb3R0b21Sb3dEYXRhOiBUW10gPSBbXTtcblxuICAvKipcbiAgICogVGhlIHBpbm5lZCByb3cgY29udGFpbmVycyBzaXQgb3V0c2lkZSB0aGUgc2Nyb2xsIHZpZXdwb3J0LCBzbyB0aGV5IGhhdmUgdG9cbiAgICogYmUgdG9sZCB0aGUgaG9yaXpvbnRhbCBvZmZzZXQg4oCUIHRoZSBzYW1lIGFycmFuZ2VtZW50IHRoZSBoZWFkZXIgdXNlcy5cbiAgICovXG4gIEBWaWV3Q2hpbGRyZW4oJ3Bpbm5lZFZpZXdwb3J0JykgcHJpdmF0ZSBwaW5uZWRWaWV3cG9ydHM/OiBRdWVyeUxpc3Q8RWxlbWVudFJlZjxIVE1MRWxlbWVudD4+O1xuXG4gIHByb3RlY3RlZCBwaW5uZWRUb3BOb2RlczogT25lUm93Tm9kZTxUPltdID0gW107XG4gIHByb3RlY3RlZCBwaW5uZWRCb3R0b21Ob2RlczogT25lUm93Tm9kZTxUPltdID0gW107XG4gIEBWaWV3Q2hpbGQoQ2RrVmlydHVhbFNjcm9sbFZpZXdwb3J0KSB2aWV3cG9ydCE6IENka1ZpcnR1YWxTY3JvbGxWaWV3cG9ydDtcblxuICBwcm90ZWN0ZWQgY29sdW1uRGVmczogT25lQ29sdW1uRGVmPFQ+W10gPSBbXTtcbiAgcHJvdGVjdGVkIGNlbGxSZW5kZXJlcjogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBNYXN0ZXIgRGV0YWlsIFByb3BlcnRpZXNcbiAgICovXG4gIEBJbnB1dCgpIGdyaWRUeXBlOiBPbmVHcmlkVHlwZSA9ICdzaW1wbGUnO1xuICBASW5wdXQoKSBtYXN0ZXJEZXRhaWw6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgbWFzdGVyTm9kZTogT25lUm93Tm9kZTxUPiA9IG51bGw7XG4gIC8vIEBJbnB1dCgpIGRldGFpbFJvd0hlaWdodDogbnVtYmVyID0gbnVsbDtcbiAgLy8gQElucHV0KCkgZGV0YWlsUm93QXV0b0hlaWdodDogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBkZXRhaWxSb3dNYXhIZWlnaHQ6IG51bWJlciA9IG51bGw7XG4gIEBJbnB1dCgpIGRldGFpbENlbGxSZW5kZXJlclBhcmFtczogT25lRGV0YWlsQ2VsbFJlbmRlcmVyUGFyYW1zO1xuICBASW5wdXQoKSBkZXRhaWxHcmlkVGVtcGxhdGU6IFRlbXBsYXRlUmVmPHVua25vd24+ID0gbnVsbDtcbiAgQElucHV0KCkgZGV0YWlsUmVuZGVyZXJDb21wb25lbnQ6IFR5cGU8T25lQ2VsbFJlbmRlcmVyQ29tcG9uZW50PjtcblxuICAvKipcbiAgICogVHJlZSBEYXRhIFByb3BlcnRpZXNcbiAgICovXG4gIEBJbnB1dCgpIHRyZWVEYXRhOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIHRyZWVEYXRhQ2hpbGRyZW5GaWVsZDogc3RyaW5nO1xuICBASW5wdXQoKSBhdXRvR3JvdXBDb2x1bW5EZWY6IE9uZUNvbHVtbkRlZjxUPjtcbiAgQElucHV0KCkgZ3JvdXBEZWZhdWx0RXhwYW5kZWQ6IG51bWJlciA9IC0xOyAvLyBJdCdzIHdvcmsgd2l0aCBtYXN0ZXIgZGV0YWlsIGFsc29cblxuICAvKipcbiAgICogUGFzc2luZyBSb3cgQWN0aW9uIEV2ZW50cyB0byBQYXJlbnRcbiAgICovXG4gIEBPdXRwdXQoKSBvblJvd0dvdG9EZXRhaWwgPSBuZXcgRXZlbnRFbWl0dGVyPE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIG9uUm93QWRkTmV3ID0gbmV3IEV2ZW50RW1pdHRlcjxPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4+KCk7XG4gIEBPdXRwdXQoKSBvblJvd1ZpZXcgPSBuZXcgRXZlbnRFbWl0dGVyPE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIG9uUm93Q29weSA9IG5ldyBFdmVudEVtaXR0ZXI8T25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+PigpO1xuICBAT3V0cHV0KCkgb25Sb3dMb2NhdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8T25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+PigpO1xuICBAT3V0cHV0KCkgb25Sb3dEb2N1bWVudCA9IG5ldyBFdmVudEVtaXR0ZXI8T25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+PigpO1xuICBAT3V0cHV0KCkgb25Sb3dEZWxldGUgPSBuZXcgRXZlbnRFbWl0dGVyPE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIG9uUm93R290b0xpc3QgPSBuZXcgRXZlbnRFbWl0dGVyPE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIG9uUm93RWRpdCA9IG5ldyBFdmVudEVtaXR0ZXI8T25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+PigpO1xuICBAT3V0cHV0KCkgb25Sb3dQcmludCA9IG5ldyBFdmVudEVtaXR0ZXI8T25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+PigpO1xuICBAT3V0cHV0KCkgb25Sb3dIaXN0b3J5ID0gbmV3IEV2ZW50RW1pdHRlcjxPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4+KCk7XG4gIEBPdXRwdXQoKSBvblJvd09wdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8T25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+PigpO1xuICBAT3V0cHV0KCkgb25Sb3dMYW5ndWFnZSA9IG5ldyBFdmVudEVtaXR0ZXI8T25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+PigpO1xuICBAT3V0cHV0KCkgb25Sb3dDZWxsT3B0aW9uID0gbmV3IEV2ZW50RW1pdHRlcjxPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4+KCk7XG4gIEBPdXRwdXQoKSBvblJvd1NlbGVjdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8T25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+PigpO1xuICBAT3V0cHV0KCkgb25TaGlmdERvdWJsZUNsaWNrID0gbmV3IEV2ZW50RW1pdHRlcjxPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4+KCk7XG4gIEBPdXRwdXQoKSByb3dDb3VudENoYW5nZWQgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcblxuICBAT3V0cHV0KCkgZXhwYW5zaW9uQ2hhbmdlZCA9IG5ldyBFdmVudEVtaXR0ZXI8RXhwYW5zaW9uQ2hhbmdlZEV2ZW50PFQ+PigpO1xuICBAT3V0cHV0KCkgYm9keVNjcm9sbCA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuICBAT3V0cHV0KCkgY2VsbE9wdGlvblNlbGVjdCA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICBAT3V0cHV0KCkgcm93RHJhZ0VuZCA9IG5ldyBFdmVudEVtaXR0ZXI8T25lUm93RHJhZ0V2ZW50PFQ+PigpO1xuXG4gIC8qKlxuICAgKiBTZWxlY3Rpb24gUmFuZ2UgVmFyaWFibGVzXG4gICAqL1xuICBwcm90ZWN0ZWQgcm93V2lkdGg6IG51bWJlciA9IDA7XG4gIHByb3RlY3RlZCBub2RlczogT25lUm93Tm9kZTxUPltdID0gW107XG5cbiAgLyoqXG4gICAqIFJvdyBkcmFnIHN0YXRlLCBtaXJyb3JlZCBmcm9tIHRoZSBzZXJ2aWNlIHNvIHRoZSB0ZW1wbGF0ZSBjYW4gcmVhZCBpdFxuICAgKiBzeW5jaHJvbm91c2x5LiBgbnVsbGAgd2hlbmV2ZXIgbm8gZHJhZyBpcyBpbiBmbGlnaHQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZHJhZ1N0YXRlOiBPbmVSb3dEcmFnU3RhdGUgfCBudWxsID0gbnVsbDtcbiAgcHJvdGVjdGVkIGRyYWdBbm5vdW5jZW1lbnQgPSAnJztcbiAgcHJvdGVjdGVkIHJvd0RyYWdTdXBwcmVzc2VkOiBPbmVSb3dEcmFnU3VwcHJlc3NlZFJlYXNvbiB8IG51bGwgPSBudWxsO1xuICBwcm90ZWN0ZWQgc2VsZWN0ZWRDZWxscyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBwcml2YXRlIGlzTW91c2VEb3duID0gZmFsc2U7XG4gIHByaXZhdGUgc3RhcnRDZWxsOiBDZWxsU2VsZWN0aW9uID0gbnVsbDtcbiAgcHJpdmF0ZSBsYXN0U2Nyb2xsTGVmdCA9IDA7XG4gIHByaXZhdGUgY2VsbEVkaXRhYmxlUGlwZSA9IG5ldyBDZWxsRWRpdGFibGVQaXBlKCk7XG4gIHByaXZhdGUgc3Vic2NyaXB0aW9ucyA9IG5ldyBTdWJzY3JpcHRpb24oKTtcblxuICBwcm90ZWN0ZWQgY2VsbFJlbmRlcmVyUGFyYW1zOiBPbmVDZWxsUmVuZGVyZXJQYXJhbXMgPSB7XG4gICAgICBnb3RvRGV0YWlsQnV0dG9uU3RhdHVzOiAxLFxuICAgICAgYWRkTmV3QnV0dG9uU3RhdHVzOiAxLFxuICAgICAgdmlld0J1dHRvblN0YXR1czogMSxcbiAgICAgIGxvY2F0aW9uQnV0dG9uU3RhdHVzOiAxLFxuICAgICAgZG9jdW1lbnRCdXR0b25TdGF0dXM6IDEsXG4gICAgICBjb3B5QnV0dG9uU3RhdHVzOiAxLFxuICAgICAgZGVsZXRlQnV0dG9uU3RhdHVzOiAxLFxuICAgICAgZ290b0xpc3RCdXR0b25TdGF0dXM6IDEsXG4gICAgICBvcHRpb25CdXR0b25TdGF0dXM6IDEsXG4gICAgICBsYW5ndWFnZUJ1dHRvblN0YXR1czogMSxcbiAgICAgIGVkaXRCdXR0b25TdGF0dXM6IDEsXG4gICAgICBwcmludEJ1dHRvblN0YXR1czogMSxcbiAgICAgIGhpc3RvcnlCdXR0b25TdGF0dXM6IDEsXG4gIH1cblxuICAvKipcbiAgICogVmlydHVhbCBTY3JvbGwgUHJvcGVydGllc1xuICAgKi9cbiAgcHJvdGVjdGVkIGl0ZW1TaXplOiBudW1iZXIgPSAzMDtcbiAgcHJvdGVjdGVkIG1pbkJ1ZmZlclB4OiBudW1iZXIgPSAyMDA7XG4gIHByb3RlY3RlZCBtYXhCdWZmZXJQeDogbnVtYmVyID0gNDAwO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByb3RlY3RlZCBjb2xTZXJ2aWNlOiBPZ0NvbHVtblNlcnZpY2UsXG4gICAgcHJvdGVjdGVkIGNlbGxTZXJ2aWNlOiBPbmVHcmlkQ2VsbFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBldmVudFNlcnZpY2U6IE9uZUdyaWRFdmVudFNlcnZpY2UsXG4gICAgcHJvdGVjdGVkIHJvd0RyYWdTZXJ2aWNlOiBPbmVHcmlkUm93RHJhZ1NlcnZpY2U8VD4sXG4gICAgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmXG4gICkgeyB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG5cbiAgICAvKipcbiAgICAgKiBMaXN0ZW4gR3JpZCBDb3B5IEV2ZW50XG4gICAgICovXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZCh0aGlzLmdyaWRDb3B5JC5zdWJzY3JpYmUoKGV2ZW50OiBDbGlwYm9hcmRFdmVudCkgPT4ge1xuXG4gICAgICB0aGlzLm9uR3JpZENvcHkoZXZlbnQpO1xuICAgIH0pKTtcblxuICAgIC8qKlxuICAgICAqIFJvdyBkcmFnXG4gICAgICpcbiAgICAgKiBUaGUgc2VydmljZSBvd25zIHRoZSBnZXN0dXJlOyB0aGUgYm9keSBvbmx5IHJlbmRlcnMgaXQgYW5kIGxlbmRzIGl0IHRoZVxuICAgICAqIHZpZXdwb3J0LCB0aGUgcm93IGhlaWdodCBhbmQgYSB3YXkgdG8gYXBwbHkgYSBtb3ZlLiBUaGUgc3VwcHJlc3Npb25cbiAgICAgKiByZWFzb24gaXMgcmUtcmVhZCBvbiBldmVyeSBldmVudCB0aGF0IGNvdWxkIGNoYW5nZSB0aGUgb3JkZXIsIHNvIHRoZVxuICAgICAqIGhhbmRsZSBkaXNhYmxlcyBpdHNlbGYgdGhlIG1vbWVudCBhIHNvcnQgb3IgZmlsdGVyIGlzIGFwcGxpZWQuXG4gICAgICovXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZCh0aGlzLnJvd0RyYWdTZXJ2aWNlLnN0YXRlJC5zdWJzY3JpYmUoKHN0YXRlKSA9PiB7XG5cbiAgICAgIHRoaXMuZHJhZ1N0YXRlID0gc3RhdGU7XG5cbiAgICAgIHRoaXMudXBkYXRlRHJvcEluZGljYXRvcigpO1xuXG4gICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9KSk7XG5cbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKHRoaXMucm93RHJhZ1NlcnZpY2UuYW5ub3VuY2VtZW50JC5zdWJzY3JpYmUoKG1lc3NhZ2UpID0+IHtcblxuICAgICAgdGhpcy5kcmFnQW5ub3VuY2VtZW50ID0gbWVzc2FnZTtcblxuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfSkpO1xuXG4gICAgLyoqXG4gICAgICogTGlzdGVuIENvbHVtbiBDaGFuZ2VkIEV2ZW50XG4gICAgICovXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZCh0aGlzLmV2ZW50U2VydmljZS5hZGRFdmVudExpc3RlbmVyKCdjb2x1bW5DaGFuZ2VkJywgKHBheWxvYWQ6IENvbHVtbkNoYW5nZWRFdmVudCkgPT4ge1xuXG4gICAgICB0aGlzLmNvbHVtbkRlZnMgPSBbLi4ucGF5bG9hZC5jb2x1bW5zXSBhcyBPbmVDb2x1bW5EZWZbXTtcblxuICAgICAgdGhpcy5jZWxsUmVuZGVyZXIgPSB0aGlzLmNvbHVtbkRlZnMuc29tZShjb2wgPT4gY29sLmNlbGxSZW5kZXJlckNvbXBvbmVudCk7XG5cbiAgICAgIHRoaXMucm93V2lkdGggPSB0aGlzLmNvbHVtbkRlZnMucmVkdWNlKChzdW0sIGNvbCkgPT4gc3VtICsgcmVzb2x2ZUNvbHVtbldpZHRoKGNvbCksIDApO1xuXG4gICAgICAvLyBBIGNvbHVtbiBjaGFuZ2UgY2FuIGFsdGVyIHRoZSB3aWR0aCBsZWZ0IGZvciBmbGV4IGNvbHVtbnMgKGEgaGlkZSwgYVxuICAgICAgLy8gcmVzaXplLCBuZXcgZGVmcykuIFJlLWZsZXhpbmcgb25seSBkaXNwYXRjaGVzIHdoZW4gYSB3aWR0aCBhY3R1YWxseVxuICAgICAgLy8gY2hhbmdlcywgc28gdGhpcyBjYW5ub3QgcGluZy1wb25nLlxuICAgICAgdGhpcy5hcHBseUZsZXhXaWR0aHMoKTtcblxuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfSkpO1xuXG4gICAgLyoqXG4gICAgICogTGlzdGVuIFJvdyBEYXRhIENoYW5nZWQgRXZlbnRcbiAgICAgKi9cbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKHRoaXMuZXZlbnRTZXJ2aWNlLmFkZEV2ZW50TGlzdGVuZXIoJ3Jvd0RhdGFDaGFuZ2VkJywgKHsgbm9kZXM6IGFsbE5vZGVzIH06IFJvd0RhdGFDaGFuZ2VkRXZlbnQ8VD4pID0+IHtcblxuICAgICAgLy8gVGhlIGZ1bGwgcG9zdC1maWx0ZXIgY291bnQsIHJlcG9ydGVkIGJlZm9yZSB0aGUgcGFnZSBzbGljZSBpcyB0YWtlbixcbiAgICAgIC8vIHNvIHRoZSBob3N0J3MgcGFnaW5nIHRvdGFscyBzZWUgZXZlcnl0aGluZy5cbiAgICAgIHRoaXMucm93Q291bnRDaGFuZ2VkLmVtaXQoYWxsTm9kZXM/Lmxlbmd0aCA/PyAwKTtcblxuICAgICAgY29uc3Qgbm9kZXMgPSB0aGlzLmFwaS5wYWdlTm9kZXMoYWxsTm9kZXMpO1xuXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcblxuICAgICAgICB0aGlzLnZpZXdwb3J0Py5jaGVja1ZpZXdwb3J0U2l6ZSgpO1xuXG4gICAgICAgIHRoaXMuc2V0VmlydHVhbFNjcm9sbChub2Rlcz8ubGVuZ3RoKTtcblxuICAgICAgICBpZiAodGhpcy5tYXN0ZXJEZXRhaWwpIHtcblxuICAgICAgICAgIHRoaXMubm9kZXMgPSBub2Rlcy5tYXAoKG5vZGU6IE9uZVJvd05vZGUpID0+IHtcblxuICAgICAgICAgICAgaWYgKG5vZGUubGVhZiAmJiB0aGlzLmRldGFpbFJlbmRlcmVyQ29tcG9uZW50KSB7XG5cbiAgICAgICAgICAgICAgbm9kZS5kZXRhaWxSZW5kZXJlckNvbXBvbmVudCA9IHRoaXMuZGV0YWlsUmVuZGVyZXJDb21wb25lbnQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIERldGFpbCByb3dzIGNhbiBzdGlsbCBiZSBpbiBmbGlnaHQgd2hlbiBhIHJvdyBpcyBleHBhbmRlZCwgYW5kXG4gICAgICAgICAgICAvLyBzcHJlYWRpbmcgbnVsbCB0aHJvd3MuIE5vdGhpbmcgdG8gcmUtc2VlZCB1bnRpbCB0aGV5IGFycml2ZS5cbiAgICAgICAgICAgIGlmIChub2RlLmV4cGFuZGVkICYmIG5vZGUuZGV0YWlsUm93RGF0YSkge1xuXG4gICAgICAgICAgICAgIHRoaXMuYXBpLnNldERldGFpbFJvd0RhdGEobm9kZSwgWy4uLm5vZGUuZGV0YWlsUm93RGF0YV0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gbm9kZTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgdGhpcy5ub2RlcyA9IG5vZGVzIGFzIE9uZVJvd05vZGU8VD5bXTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucmVmcmVzaFJvd0RyYWdTdXBwcmVzc2VkKCk7XG5cbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICB9KTtcbiAgICB9KSk7XG5cblxuICAgIC8qKlxuICAgICAqIExpc3RlbiBQaW5uZWQgUm93IERhdGEgQ2hhbmdlZCBFdmVudFxuICAgICAqL1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQodGhpcy5ldmVudFNlcnZpY2UuYWRkRXZlbnRMaXN0ZW5lcigncGlubmVkUm93RGF0YUNoYW5nZWQnLCAoeyBzaWRlLCBub2RlcyB9OiBQaW5uZWRSb3dEYXRhQ2hhbmdlZEV2ZW50PFQ+KSA9PiB7XG5cbiAgICAgIGlmIChzaWRlID09PSAndG9wJykge1xuXG4gICAgICAgIHRoaXMucGlubmVkVG9wTm9kZXMgPSBub2RlcyBhcyBPbmVSb3dOb2RlPFQ+W107XG5cbiAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgdGhpcy5waW5uZWRCb3R0b21Ob2RlcyA9IG5vZGVzIGFzIE9uZVJvd05vZGU8VD5bXTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfSkpO1xuXG4gICAgLyoqXG4gICAgICogTGlzdGVuIFNvcnQgQ2hhbmdlZCBFdmVudFxuICAgICAqL1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQodGhpcy5ldmVudFNlcnZpY2UuYWRkRXZlbnRMaXN0ZW5lcignc29ydENoYW5nZWQnLCAoeyBub2RlcyB9OiBTb3J0Q2hhbmdlZEV2ZW50KSA9PiB7XG5cbiAgICAgIHRoaXMubm9kZXMgPSB0aGlzLmFwaS5wYWdlTm9kZXMobm9kZXMgYXMgT25lUm93Tm9kZTxUPltdKTtcblxuICAgICAgLy8gU29ydGluZyB0YWtlcyBvd25lcnNoaXAgb2YgdGhlIG9yZGVyIGF3YXkgZnJvbSB0aGUgdXNlciwgc28gdGhlIGhhbmRsZXNcbiAgICAgIC8vIGhhdmUgdG8gZGlzYWJsZSBpbiB0aGUgc2FtZSBmcmFtZSB0aGUgcm93cyByZS1zb3J0LlxuICAgICAgdGhpcy5yZWZyZXNoUm93RHJhZ1N1cHByZXNzZWQoKTtcblxuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfSkpO1xuXG4gICAgLyoqXG4gICAgICogTGlzdGVuIFJvdyBPcmRlciBDaGFuZ2VkIEV2ZW50XG4gICAgICpcbiAgICAgKiBEZWxpYmVyYXRlbHkgbm90IGZvbGRlZCBpbnRvIGByb3dEYXRhQ2hhbmdlZGA6IHRoYXQgcGF0aCBkZWZlcnMgYSBmcmFtZVxuICAgICAqIGFuZCByZS1zZWVkcyBkZXRhaWwgcm93cywgd2hpY2ggaXMgcmlnaHQgZm9yIGEgZGF0YSBsb2FkIGFuZCBmYXIgdG9vIG11Y2hcbiAgICAgKiBmb3IgYSBtb3ZlLiBBIHJlb3JkZXIgaXMgdGhlIHNhbWUgbm9kZXMgaW4gYSBkaWZmZXJlbnQgb3JkZXIuXG4gICAgICovXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZCh0aGlzLmV2ZW50U2VydmljZS5hZGRFdmVudExpc3RlbmVyKCdyb3dPcmRlckNoYW5nZWQnLCAoeyBub2RlcyB9OiBSb3dPcmRlckNoYW5nZWRFdmVudDxUPikgPT4ge1xuXG4gICAgICB0aGlzLm5vZGVzID0gdGhpcy5hcGkucGFnZU5vZGVzKFsuLi5ub2Rlc10gYXMgT25lUm93Tm9kZTxUPltdKTtcblxuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfSkpO1xuXG4gICAgLyoqXG4gICAgICogTGlzdGVuIENlbGwgU3RhdGUgQ2hhbmdlZCBFdmVudFxuICAgICAqXG4gICAgICogVGhlIGJvZHkgcmVuZGVycyBPblB1c2gsIHNvIHJlZ2VuZXJhdGluZyBhIHJvdydzIGNlbGwgc3RhdGUgaXMgaW52aXNpYmxlXG4gICAgICogdW50aWwgc29tZXRoaW5nIG1hcmtzIHRoZSBib2R5IGRpcnR5LiBUaGlzIGlzIHRoYXQgc29tZXRoaW5nLlxuICAgICAqL1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQodGhpcy5ldmVudFNlcnZpY2UuYWRkRXZlbnRMaXN0ZW5lcignY2VsbFN0YXRlQ2hhbmdlZCcsICgpID0+IHtcblxuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfSkpO1xuXG4gICAgLyoqXG4gICAgICogTGlzdGVuIFNlbGVjdGlvbiBDaGFuZ2VkIEV2ZW50XG4gICAgICovXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZCh0aGlzLmV2ZW50U2VydmljZS5hZGRFdmVudExpc3RlbmVyKCdzZWxlY3Rpb25DaGFuZ2VkJywgKHBheWxvYWQ6IFNlbGVjdGlvbkNoYW5nZWRFdmVudDxUPikgPT4ge1xuXG4gICAgICBpZiAocGF5bG9hZCkge1xuXG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfVxuICAgIH0pKTtcbiAgfVxuXG4gIG9uR3JpZFJlYWR5KHBhcmFtczogT25lR3JpZFJlYWR5RXZlbnQpIHtcblxuICAgIHBhcmFtcy5hcGkuc2V0Um93RGF0YSh0aGlzLm1hc3Rlck5vZGU/LmRldGFpbFJvd0RhdGEgPz8gW10pO1xuICB9XG5cbiAgb25Cb2R5U2Nyb2xsKGV2ZW50OiBFdmVudCkge1xuXG4gICAgY29uc3Qgc2Nyb2xsTGVmdCA9IChldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQpLnNjcm9sbExlZnQ7XG5cbiAgICBpZiAoc2Nyb2xsTGVmdCAhPT0gdGhpcy5sYXN0U2Nyb2xsTGVmdCkge1xuXG4gICAgICB0aGlzLmxhc3RTY3JvbGxMZWZ0ID0gc2Nyb2xsTGVmdDtcblxuICAgICAgdGhpcy5zeW5jUGlubmVkUm93cyhzY3JvbGxMZWZ0KTtcblxuICAgICAgdGhpcy5ib2R5U2Nyb2xsLmVtaXQoc2Nyb2xsTGVmdCk7XG5cbiAgICAgIC8vIFRoZSBpbmRpY2F0b3IgaXMgY2xpcHBlZCB0byB0aGUgcm93IGNvbnRlbnQsIHdoaWNoIG1vdmVzIHNpZGV3YXlzIHRvby5cbiAgICAgIGlmICh0aGlzLmRyYWdTdGF0ZSkge1xuXG4gICAgICAgIHRoaXMudXBkYXRlRHJvcEluZGljYXRvcigpO1xuXG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gVmVydGljYWw6IHRoZSBkcm9wIGluZGljYXRvciBpcyBhbmNob3JlZCB0byB0aGUgYm9keSwgbm90IHRoZSBjb250ZW50LCBzb1xuICAgIC8vIGl0IGhhcyB0byBiZSByZXBvc2l0aW9uZWQgYXMgdGhlIHJvd3MgbW92ZSBiZW5lYXRoIGl0IOKAlCB3aGljaCB0aGV5IGRvIG9uXG4gICAgLy8gdGhlaXIgb3duIGR1cmluZyBhdXRvLXNjcm9sbCwgd2l0aCB0aGUgcG9pbnRlciBzdGFuZGluZyBzdGlsbC5cbiAgICBpZiAodGhpcy5kcmFnU3RhdGUpIHtcblxuICAgICAgdGhpcy51cGRhdGVEcm9wSW5kaWNhdG9yKCk7XG5cbiAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBLZWVwIHRoZSBwaW5uZWQgcm93cyBpbiBzdGVwIHdpdGggdGhlIGJvZHkncyBob3Jpem9udGFsIHBvc2l0aW9uLlxuICAgKlxuICAgKiBBc3NpZ25lZCByYXRoZXIgdGhhbiB0cmFuc2Zvcm1lZCwgZm9yIHRoZSBzYW1lIHJlYXNvbiBhcyB0aGUgaGVhZGVyOiBzdGlja3lcbiAgICogcG9zaXRpb25pbmcgZm9yIHBpbm5lZCAqY29sdW1ucyogaGFzIHRvIHJlc29sdmUgYWdhaW5zdCBhIHJlYWwgc2Nyb2xscG9ydCxcbiAgICogYW5kIGEgdHJhbnNmb3JtZWQgYW5jZXN0b3IgaXMgbm90IG9uZS4gUGlubmVkIHJvd3MgYW5kIHBpbm5lZCBjb2x1bW5zXG4gICAqIHRoZXJlZm9yZSBjb21wb3NlIOKAlCBhIGZyb3plbiBjb3JuZXIgY2VsbCBzdGF5cyBmcm96ZW4gb24gYm90aCBheGVzLlxuICAgKi9cbiAgcHJpdmF0ZSBzeW5jUGlubmVkUm93cyhzY3JvbGxMZWZ0OiBudW1iZXIpOiB2b2lkIHtcblxuICAgIHRoaXMucGlubmVkVmlld3BvcnRzPy5mb3JFYWNoKHZpZXdwb3J0ID0+ICh2aWV3cG9ydC5uYXRpdmVFbGVtZW50LnNjcm9sbExlZnQgPSBzY3JvbGxMZWZ0KSk7XG4gIH1cblxuICAvKipcbiAgICogVHJhY2sgUmVuZGVyaW5nIFJvdyBOb2RlIEJ5IFJvdyBJRFxuICAgKi9cbiAgdHJhY2tCeVJvd0lkKGluZGV4OiBudW1iZXIsIG5vZGU6IE9uZVJvd05vZGU8VD4pOiBzdHJpbmcge1xuXG4gICAgcmV0dXJuIG5vZGUucm93SWQ7XG4gIH1cblxuICAvKipcbiAgICogQ2VsbCBTZWxlY3Rpb24gUmFuZ2UgRmVhdHVyZVxuICAgKi9cbiAgc3RhcnRTZWxlY3Rpb24ocm93SWQ6IHN0cmluZywgZmllbGQ6IHN0cmluZykge1xuXG4gICAgdGhpcy5pc01vdXNlRG93biA9IHRydWU7XG4gICAgdGhpcy5zdGFydENlbGwgPSB7IHJvd0lkLCBmaWVsZCB9O1xuICAgIHRoaXMuc2VsZWN0ZWRDZWxscy5jbGVhcigpO1xuICAgIHRoaXMuc2VsZWN0ZWRDZWxscyA9IG5ldyBTZXQodGhpcy5zZWxlY3RlZENlbGxzKS5hZGQoZ2V0Q2VsbEtleShyb3dJZCwgZmllbGQpKTtcbiAgfVxuXG4gIGV4dGVuZFNlbGVjdGlvbihyb3dJZDogc3RyaW5nLCBmaWVsZDogc3RyaW5nKSB7XG5cbiAgICBpZiAoIXRoaXMuaXNNb3VzZURvd24gfHwgIXRoaXMuc3RhcnRDZWxsKSByZXR1cm47XG5cbiAgICBjb25zdCByb3dzID0gdGhpcy5ub2RlczsgLy8gYWxyZWFkeSBzb3J0ZWRcbiAgICBjb25zdCBzdGFydFJvd0luZGV4ID0gcm93cy5maW5kSW5kZXgociA9PiByLnJvd0lkID09PSB0aGlzLnN0YXJ0Q2VsbCEucm93SWQpO1xuICAgIGNvbnN0IGVuZFJvd0luZGV4ICAgPSByb3dzLmZpbmRJbmRleChyID0+IHIucm93SWQgPT09IHJvd0lkKTtcblxuICAgIGlmIChzdGFydFJvd0luZGV4ID09PSAtMSB8fCBlbmRSb3dJbmRleCA9PT0gLTEpIHJldHVybjtcblxuICAgIGNvbnN0IGNvbFN0YXJ0SW5kZXggPSB0aGlzLmNvbHVtbkRlZnMuZmluZEluZGV4KGMgPT4gYy5maWVsZCA9PT0gdGhpcy5zdGFydENlbGwhLmZpZWxkKTtcbiAgICBjb25zdCBjb2xFbmRJbmRleCAgID0gdGhpcy5jb2x1bW5EZWZzLmZpbmRJbmRleChjID0+IGMuZmllbGQgPT09IGZpZWxkKTtcblxuICAgIGlmIChjb2xTdGFydEluZGV4ID09PSAtMSB8fCBjb2xFbmRJbmRleCA9PT0gLTEpIHJldHVybjtcblxuICAgIGNvbnN0IHJvd1N0YXJ0ID0gTWF0aC5taW4oc3RhcnRSb3dJbmRleCwgZW5kUm93SW5kZXgpO1xuICAgIGNvbnN0IHJvd0VuZCAgID0gTWF0aC5tYXgoc3RhcnRSb3dJbmRleCwgZW5kUm93SW5kZXgpO1xuICAgIGNvbnN0IGNvbFN0YXJ0ID0gTWF0aC5taW4oY29sU3RhcnRJbmRleCwgY29sRW5kSW5kZXgpO1xuICAgIGNvbnN0IGNvbEVuZCAgID0gTWF0aC5tYXgoY29sU3RhcnRJbmRleCwgY29sRW5kSW5kZXgpO1xuXG4gICAgY29uc3QgbmV4dCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gICAgZm9yIChsZXQgciA9IHJvd1N0YXJ0OyByIDw9IHJvd0VuZDsgcisrKSB7XG4gICAgICBmb3IgKGxldCBjID0gY29sU3RhcnQ7IGMgPD0gY29sRW5kOyBjKyspIHtcbiAgICAgICAgbmV4dC5hZGQoZ2V0Q2VsbEtleShyb3dzW3JdLnJvd0lkLCB0aGlzLmNvbHVtbkRlZnNbY10uZmllbGQpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnNlbGVjdGVkQ2VsbHMgPSBuZXh0O1xuICB9XG5cblxuICBlbmRTZWxlY3Rpb24oKSB7XG5cbiAgICB0aGlzLmlzTW91c2VEb3duID0gZmFsc2U7XG4gICAgdGhpcy5zdGFydENlbGwgPSBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFyIENlbGxzIFNlbGVjdGVkXG4gICAqL1xuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDpjbGljaycsIFsnJGV2ZW50J10pXG4gIG9uRG9jdW1lbnRDbGljayhldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuXG4gICAgaWYgKHRoaXMuYm9keVJlZj8ubmF0aXZlRWxlbWVudCkge1xuXG4gICAgICBjb25zdCBjbGlja2VkSW5zaWRlID0gdGhpcy5ib2R5UmVmLm5hdGl2ZUVsZW1lbnQuY29udGFpbnMoZXZlbnQudGFyZ2V0IGFzIE5vZGUpO1xuXG4gICAgICBpZiAoIWNsaWNrZWRJbnNpZGUpIHtcblxuICAgICAgICB0aGlzLnNlbGVjdGVkQ2VsbHMuY2xlYXIoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2VsZWN0aW9uIFJhbmdlIEV2ZW50IEhvbGQgTW91c2UgQ2xpY2tcbiAgICovXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50Om1vdXNldXAnKVxuICBvbkdsb2JhbE1vdXNlVXAoKSB7XG5cbiAgICB0aGlzLmVuZFNlbGVjdGlvbigpO1xuICB9XG5cbiAgLyoqXG4gICAqIExpc3RlbiBDb3B5IENsaXBib2FyZCBFdmVudFxuICAgKi9cbiAgb25HcmlkQ29weShldmVudDogQ2xpcGJvYXJkRXZlbnQpIHtcblxuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICBpZiAodGhpcy5zZWxlY3RlZENlbGxzLnNpemUgPiAwKSB7XG5cbiAgICAgIGNvbnN0IHRleHQgPSB0aGlzLmJ1aWxkQ2xpcGJvYXJkVGV4dCgpO1xuXG4gICAgICBldmVudC5jbGlwYm9hcmREYXRhPy5zZXREYXRhKCd0ZXh0L3BsYWluJywgdGV4dCk7XG5cbiAgICAgIHRoaXMuc2VsZWN0ZWRDZWxscy5mb3JFYWNoKGNlbGxJZCA9PiB7XG5cbiAgICAgICAgY29uc3QgY2VsbEVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGBbZGF0YS1jZWxsLWlkPVwiJHtjZWxsSWR9XCJdYCk7XG5cbiAgICAgICAgaWYgKGNlbGxFbGVtZW50KSB7XG5cbiAgICAgICAgICBjZWxsRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdvbmUtY2VsbC1jb3BpZWQnKTtcblxuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gY2VsbEVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnb25lLWNlbGwtY29waWVkJyksIDQwMCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGNvcHlUb0NsaXBib2FyZCh2YWx1ZTogc3RyaW5nKSB7XG5cbiAgICBpZiAobmF2aWdhdG9yLmNsaXBib2FyZD8ud3JpdGVUZXh0KSB7XG5cbiAgICAgIG5hdmlnYXRvci5jbGlwYm9hcmQud3JpdGVUZXh0KHZhbHVlKTtcblxuICAgIH0gZWxzZSB7XG5cbiAgICAgIC8vIEZhbGxiYWNrIChTYWZhcmkgLyBvbGRlciBicm93c2VycylcbiAgICAgIGNvbnN0IHRleHRhcmVhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGV4dGFyZWEnKTtcbiAgICAgIHRleHRhcmVhLnZhbHVlID0gdmFsdWU7XG4gICAgICB0ZXh0YXJlYS5zdHlsZS5wb3NpdGlvbiA9ICdmaXhlZCc7XG4gICAgICB0ZXh0YXJlYS5zdHlsZS5vcGFjaXR5ID0gJzAnO1xuICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh0ZXh0YXJlYSk7XG4gICAgICB0ZXh0YXJlYS5zZWxlY3QoKTtcbiAgICAgIGRvY3VtZW50LmV4ZWNDb21tYW5kKCdjb3B5Jyk7XG4gICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKHRleHRhcmVhKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgQ29weSBDZWxsIFRleHQgdG8gQ2xpcGJvYXJkXG4gICAqL1xuICBwcml2YXRlIGJ1aWxkQ2xpcGJvYXJkVGV4dCgpOiBzdHJpbmcge1xuXG4gICAgaWYgKCF0aGlzLnNlbGVjdGVkQ2VsbHMuc2l6ZSkgcmV0dXJuICcnO1xuXG4gICAgLy8gUGFyc2Ugc2VsZWN0ZWQgY2VsbHNcbiAgICBjb25zdCBzZWxlY3RlZCA9IEFycmF5LmZyb20odGhpcy5zZWxlY3RlZENlbGxzKS5tYXAoa2V5ID0+IHtcblxuICAgICAgY29uc3QgW3Jvd0lkLCBmaWVsZF0gPSBrZXkuc3BsaXQoJy0tJyk7XG4gICAgICByZXR1cm4geyByb3dJZCwgZmllbGQgfTtcbiAgICB9KTtcblxuICAgIC8vIFJlc29sdmUgdmlzdWFsIHJvdyBpbmRleGVzIGZyb20gZGlzcGxheWVkUm93c1xuICAgIGNvbnN0IHJvd0luZGV4ZXMgPSBzZWxlY3RlZFxuICAgICAgLm1hcChzID0+IHRoaXMubm9kZXMuZmluZEluZGV4KHIgPT4gci5yb3dJZCA9PT0gcy5yb3dJZCkpXG4gICAgICAuZmlsdGVyKGkgPT4gaSAhPT0gLTEpO1xuXG4gICAgY29uc3QgY29sSW5kZXhlcyA9IHNlbGVjdGVkXG4gICAgICAubWFwKHMgPT4gdGhpcy5jb2x1bW5EZWZzLmZpbmRJbmRleChjID0+IGMuZmllbGQgPT09IHMuZmllbGQpKVxuICAgICAgLmZpbHRlcihpID0+IGkgIT09IC0xKTtcblxuICAgIGlmICghcm93SW5kZXhlcy5sZW5ndGggfHwgIWNvbEluZGV4ZXMubGVuZ3RoKSByZXR1cm4gJyc7XG5cbiAgICBjb25zdCByb3dTdGFydCA9IE1hdGgubWluKC4uLnJvd0luZGV4ZXMpO1xuICAgIGNvbnN0IHJvd0VuZCAgID0gTWF0aC5tYXgoLi4ucm93SW5kZXhlcyk7XG4gICAgY29uc3QgY29sU3RhcnQgPSBNYXRoLm1pbiguLi5jb2xJbmRleGVzKTtcbiAgICBjb25zdCBjb2xFbmQgICA9IE1hdGgubWF4KC4uLmNvbEluZGV4ZXMpO1xuXG4gICAgY29uc3Qgc2VsZWN0ZWRGaWVsZHMgPSB0aGlzLmNvbHVtbkRlZnNcbiAgICAgIC5zbGljZShjb2xTdGFydCwgY29sRW5kICsgMSlcbiAgICAgIC5tYXAoYyA9PiBjLmZpZWxkKTtcblxuICAgIGNvbnN0IGNsaXBib2FyZExpbmVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgZm9yIChsZXQgciA9IHJvd1N0YXJ0OyByIDw9IHJvd0VuZDsgcisrKSB7XG5cbiAgICAgIGNvbnN0IHJvdyA9IHRoaXMubm9kZXNbcl07XG4gICAgICBjb25zdCBsaW5lID0gc2VsZWN0ZWRGaWVsZHNcbiAgICAgICAgLm1hcChmaWVsZCA9PiB7XG5cbiAgICAgICAgICBjb25zdCBrZXkgPSBgJHtyb3cucm93SWR9LS0ke2ZpZWxkfWA7XG5cbiAgICAgICAgICBpZiAoIXRoaXMuc2VsZWN0ZWRDZWxscy5oYXMoa2V5KSkge1xuXG4gICAgICAgICAgICByZXR1cm4gJyc7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IHZhbHVlID0gZ2V0RmllbGRWYWx1ZShyb3cuZGF0YSwgZmllbGQpO1xuXG4gICAgICAgICAgcmV0dXJuIHZhbHVlID8/ICcnO1xuXG4gICAgICAgIH0pLmpvaW4oJ1xcdCcpO1xuXG4gICAgICBjbGlwYm9hcmRMaW5lcy5wdXNoKGxpbmUpO1xuICAgIH1cblxuICAgIHJldHVybiBjbGlwYm9hcmRMaW5lcy5qb2luKCdcXG4nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCaW5kaW5nIEV2ZW50cyBSb3cgQWN0aW9uIHRvIFBhcmVudFxuICAgKi9cbiAgaW52b2tlUm93QWN0aW9uR290b0RldGFpbChldmVudDogT25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+KSB7XG5cbiAgICB0aGlzLm9uUm93R290b0RldGFpbC5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIGludm9rZVJvd0FjdGlvbkFkZE5ldyhldmVudDogT25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+KSB7XG5cbiAgICB0aGlzLm9uUm93QWRkTmV3LmVtaXQoZXZlbnQpO1xuICB9XG5cbiAgaW52b2tlUm93QWN0aW9uVmlldyhldmVudDogT25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+KSB7XG5cbiAgICB0aGlzLm9uUm93Vmlldy5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIGludm9rZVJvd0FjdGlvbkxvY2F0aW9uKGV2ZW50OiBPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4pIHtcblxuICAgIHRoaXMub25Sb3dMb2NhdGlvbi5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIGludm9rZVJvd0FjdGlvbkRvY3VtZW50KGV2ZW50OiBPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4pIHtcblxuICAgIHRoaXMub25Sb3dEb2N1bWVudC5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIGludm9rZVJvd0FjdGlvbkNvcHkoZXZlbnQ6IE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPikge1xuXG4gICAgdGhpcy5vblJvd0NvcHkuZW1pdChldmVudCk7XG4gIH1cblxuICBpbnZva2VSb3dBY3Rpb25EZWxldGUoZXZlbnQ6IE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPikge1xuXG4gICAgdGhpcy5vblJvd0RlbGV0ZS5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIGludm9rZVJvd0FjdGlvbkdvdG9MaXN0KGV2ZW50OiBPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4pIHtcblxuICAgIHRoaXMub25Sb3dHb3RvTGlzdC5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIGludm9rZVJvd0FjdGlvbkVkaXQoZXZlbnQ6IE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPikge1xuXG4gICAgdGhpcy5vblJvd0VkaXQuZW1pdChldmVudCk7XG4gIH1cblxuICBpbnZva2VSb3dBY3Rpb25QcmludChldmVudDogT25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+KSB7XG5cbiAgICB0aGlzLm9uUm93UHJpbnQuZW1pdChldmVudCk7XG4gIH1cblxuICBpbnZva2VSb3dBY3Rpb25IaXN0b3J5KGV2ZW50OiBPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4pIHtcblxuICAgIHRoaXMub25Sb3dIaXN0b3J5LmVtaXQoZXZlbnQpO1xuICB9XG5cbiAgaW52b2tlUm93QWN0aW9uT3B0aW9uKGV2ZW50OiBPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4pIHtcblxuICAgIHRoaXMub25Sb3dPcHRpb24uZW1pdChldmVudCk7XG4gIH1cblxuICBpbnZva2VSb3dBY3Rpb25MYW5ndWFnZShldmVudDogT25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+KSB7XG5cbiAgICB0aGlzLm9uUm93TGFuZ3VhZ2UuZW1pdChldmVudCk7XG4gIH1cblxuICAvKipcbiAgICogT3BlbiB0aGUgY2VsbCBvcHRpb24gbWVudSwgYW5kIHRlbGwgdGhlIGhvc3QgaXQgd2FzIGFza2VkIGZvci5cbiAgICpcbiAgICogVGhlIG9wZW5pbmcgaXMgdGhlIHBhcnQgdGhhdCB3YXMgbWlzc2luZy4gRXZlcnl0aGluZyBlbHNlIGV4aXN0ZWQg4oCUIHRoZVxuICAgKiB0cmlnZ2VyIGJ1dHRvbiBiZWhpbmQgYGNlbGxSZW5kZXJlclBhcmFtcy5jZWxsT3B0aW9uQnV0dG9uU3RhdHVzYCwgdGhlIG1lbnVcbiAgICogY29tcG9uZW50LCB0aGUgYGNlbGxPcHRpb25NZW51YCBjb2x1bW4gcHJvcGVydHksIHRoZSBzZWxlY3Rpb24gZXZlbnQgd2lyZWRcbiAgICogdGhyb3VnaCB0byB0aGUgZ3JpZCdzIG91dHB1dCDigJQgYnV0IG5vdGhpbmcgZXZlciBzZXQgdGhlIGZsYWcgdGhlIHRlbXBsYXRlXG4gICAqIHJlbmRlcnMgb24sIHNvIHRoZSBidXR0b24gZGlkIG5vdGhpbmcgYXQgYWxsLlxuICAgKlxuICAgKiBEb25lIGhlcmUgcmF0aGVyIHRoYW4gaW4gdGhlIHJvdy1hY3Rpb24gY29tcG9uZW50IGJlY2F1c2UgdGhpcyBpcyB0aGVcbiAgICogY29tcG9uZW50IHdob3NlIHRlbXBsYXRlIHJlbmRlcnMgdGhlIG1lbnUsIGFuZCBzbyB0aGUgb25lIHRoYXQgaGFzIHRvIGJlXG4gICAqIG1hcmtlZCBmb3IgY2hlY2suXG4gICAqL1xuICBpbnZva2VSb3dBY3Rpb25DZWxsT3B0aW9uKGV2ZW50OiBPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4pIHtcblxuICAgIGNvbnN0IGZpZWxkID0gZXZlbnQuY29sdW1uPy5maWVsZCBhcyBzdHJpbmc7XG5cbiAgICAvLyBOb3RoaW5nIHRvIG9wZW4gd2hlbiB0aGUgY29sdW1uIGRlY2xhcmVkIG5vIG9wdGlvbnM7IHRoZSBldmVudCBzdGlsbFxuICAgIC8vIGdvZXMgdG8gdGhlIGhvc3QsIHdoaWNoIG1heSBiZSBkcml2aW5nIHNvbWV0aGluZyBvZiBpdHMgb3duLlxuICAgIGlmIChmaWVsZCAmJiBldmVudC5ub2RlICYmIGV2ZW50LmNvbHVtbj8uY2VsbE9wdGlvbk1lbnU/Lmxlbmd0aCkge1xuXG4gICAgICBldmVudC5ub2RlLmNlbGxPcHRpb25zW2ZpZWxkXSA9IHRydWU7XG5cbiAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cblxuICAgIHRoaXMub25Sb3dDZWxsT3B0aW9uLmVtaXQoZXZlbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBtZW51IGNsb3NlZCBpdHNlbGYg4oCUIG9uIHNlbGVjdCwgb24gRXNjYXBlLCBvciBvbiBhIGNsaWNrIG91dHNpZGUuIEl0XG4gICAqIGhhcyBhbHJlYWR5IGNsZWFyZWQgaXRzIG93biBmbGFnOyB0aGlzIGlzIHdoYXQgcmVwYWludHMgd2l0aG91dCBpdC5cbiAgICovXG4gIGNlbGxPcHRpb25NZW51Q2xvc2VkKCk6IHZvaWQge1xuXG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBpbnZva2VSb3dBY3Rpb25TZWxlY3Rpb24oZXZlbnQ6IE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPikge1xuXG4gICAgdGhpcy5vblJvd1NlbGVjdGlvbi5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUb2dnbGUgYSBncm91cCAvIG1hc3RlciByb3csIHRoZW4gcmVwb3J0IHRoZSByZXN1bHQuXG4gICAqXG4gICAqIFRoZSBncm91cCByZW5kZXJlciBpcyBwcmVzZW50YXRpb25hbDogaXQgc2F5cyBcInRoZSBleHBhbmRlciB3YXMgY2xpY2tlZFwiXG4gICAqIGFuZCBub3RoaW5nIG1vcmUuIFBlcmZvcm1pbmcgdGhlIHN0YXRlIGNoYW5nZSBiZWxvbmdzIGhlcmUsIHdoZXJlIHRoZSBBUElcbiAgICogaXMgYXZhaWxhYmxlLiBQcmV2aW91c2x5IHRoaXMgbWV0aG9kIG9ubHkgcmUtZW1pdHRlZCwgc28gdGhlIGV4cGFuZGVyXG4gICAqIHJlbmRlcmVkLCBhbmltYXRlZCBvbiBob3ZlciBhbmQgZGlkIG5vdGhpbmcgYXQgYWxsIOKAlCBldmVyeSBjb25zdW1lciBoYWQgdG9cbiAgICogZGlzY292ZXIgZm9yIGl0c2VsZiB0aGF0IGBleHBhbnNpb25DaGFuZ2VkYCB3YXMgYSByZXF1ZXN0IHJhdGhlciB0aGFuIHRoZVxuICAgKiBub3RpZmljYXRpb24gaXRzIHBhc3QtdGVuc2UgbmFtZSBwcm9taXNlcy5cbiAgICpcbiAgICogVGhlIGV2ZW50IGlzIHJlLWVtaXR0ZWQgKmFmdGVyKiB0aGUgdG9nZ2xlLCBzbyBgZXZlbnQubm9kZS5leHBhbmRlZGAgaXMgdGhlXG4gICAqIG5ldyBzdGF0ZSwgd2hpY2ggaXMgd2hhdCBhIHBhc3QtdGVuc2UgZXZlbnQgc2hvdWxkIGNhcnJ5LlxuICAgKi9cbiAgaW52b2tlRXhwYW5zaW9uQ2hhbmdlZENsaWNrKGV2ZW50OiBFeHBhbnNpb25DaGFuZ2VkRXZlbnQpOiB2b2lkIHtcblxuICAgIGNvbnN0IG5vZGUgPSB0aGlzLmFwaS5nZXRSb3dOb2RlQnlJZChldmVudC5ub2RlLnJvd0lkKSA/PyBldmVudC5ub2RlO1xuXG4gICAgdGhpcy5hcGkuc2V0RXhwYW5kZWRCeUlkKG5vZGUucm93SWQsICFub2RlLmV4cGFuZGVkKTtcblxuICAgIHRoaXMuZXhwYW5zaW9uQ2hhbmdlZC5lbWl0KHsgLi4uZXZlbnQsIG5vZGUsIGFwaTogdGhpcy5hcGkgfSk7XG4gIH1cblxuICBjZWxsT3B0aW9uTWVudVNlbGVjdGVkKGV2ZW50OiBDZWxsT3B0aW9uTWVudVNlbGVjdGVkRXZlbnQpIHtcblxuICAgIHRoaXMuY2VsbE9wdGlvblNlbGVjdC5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTcGVjaWFsIEV2ZW50c1xuICAgKi9cbiAgcHJpdmF0ZSBpbnZva2VTaGlmdERvdWJsZUNsaWNrKG5vZGU6T25lUm93Tm9kZSwgY29sdW1uOiBPbmVDb2x1bW5EZWYpOiB2b2lkIHtcblxuICAgIGxldCBldmVudDogT25lR3JpZFJvd0FjdGlvbkV2ZW50ID0geyBub2RlLCBjb2x1bW4sIGRhdGE6IG5vZGUuZGF0YSwgcm93SW5kZXg6IG5vZGUucm93SW5kZXgsIGdyaWRUeXBlOiBudWxsIH07XG5cbiAgICBpZiAodGhpcy5tYXN0ZXJEZXRhaWwpIHtcblxuICAgICAgZXZlbnQgPSB7IC4uLmV2ZW50LCBncmlkVHlwZTogdGhpcy5ncmlkVHlwZSwgbWFzdGVyTm9kZTogdGhpcy5tYXN0ZXJOb2RlIH07XG4gICAgfVxuXG4gICAgdGhpcy5vblNoaWZ0RG91YmxlQ2xpY2suZW1pdChldmVudCk7XG4gIH1cblxuICAvKipcbiAgICogQ2VsbCBFZGl0IEZlYXR1cmVcbiAgICovXG4gIHN0YXJ0RWRpdChldmVudDogTW91c2VFdmVudCwgbm9kZTogT25lUm93Tm9kZTxUPiwgY29sdW1uOiBPbmVDb2x1bW5EZWY8VD4pIHtcblxuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudDtcblxuICAgIGlmICh0YXJnZXQudGFnTmFtZS50b0xvd2VyQ2FzZSgpID09PSAnaScpIHtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChldmVudC5zaGlmdEtleSkge1xuXG4gICAgICB0aGlzLmludm9rZVNoaWZ0RG91YmxlQ2xpY2sobm9kZSwgY29sdW1uKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuY2VsbEVkaXRhYmxlUGlwZS50cmFuc2Zvcm0obm9kZS5jZWxsU3RhdGVzLCBjb2x1bW4sIG5vZGUsIHRoaXMuY2VsbFNlcnZpY2UuZWRpdGFibGVGbiwgdGhpcy5jZWxsU2VydmljZS51cGRhdGFibGVGbiwgdGhpcy5hbGxvd2VkRWRpdCkpIHtcblxuICAgICAgdGhpcy5zZWxlY3RlZENlbGxzLmNsZWFyKCk7XG5cbiAgICAgIGNvbnN0IGNlbGxLZXkgPSBnZXRDZWxsS2V5KG5vZGUucm93SWQsIGNvbHVtbi5maWVsZCk7XG5cbiAgICAgIHRoaXMuc2VsZWN0ZWRDZWxscy5hZGQoY2VsbEtleSk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgcm93Tm9kZTogT25lUm93Tm9kZSA9IHRoaXMuYXBpLmdldFJvd05vZGVCeUlkKG5vZGUucm93SWQpO1xuXG4gICAgaWYgKHJvd05vZGUpIHtcblxuICAgICAgaWYgKHRoaXMuZWRpdFR5cGUgPT09ICdmdWxsUm93Jykge1xuXG4gICAgICAgIC8vIFRoZSB3aG9sZSByb3cgZWRpdHMgdG9nZXRoZXIsIHNvIGV2ZXJ5IGNlbGwgdGhhdCB3b3VsZCBhY2NlcHQgaXRzXG4gICAgICAgIC8vIG93biBkb3VibGUtY2xpY2sgb3BlbnMgbm93LiBUaGUgY2xpY2tlZCBvbmUgc3RpbGwgdGFrZXMgZm9jdXMgYmVsb3cuXG4gICAgICAgIGZvciAoY29uc3QgY29sIG9mIHRoaXMuY29sdW1uRGVmcykge1xuXG4gICAgICAgICAgaWYgKCFjb2wuZmllbGQpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgaWYgKHRoaXMuY2VsbEVkaXRhYmxlUGlwZS50cmFuc2Zvcm0ocm93Tm9kZS5jZWxsU3RhdGVzLCBjb2wsIHJvd05vZGUsIHRoaXMuY2VsbFNlcnZpY2UuZWRpdGFibGVGbiwgdGhpcy5jZWxsU2VydmljZS51cGRhdGFibGVGbiwgdGhpcy5hbGxvd2VkRWRpdCkpIHtcblxuICAgICAgICAgICAgcm93Tm9kZS5lZGl0aW5nW2NvbC5maWVsZF0gPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICB9IGVsc2Uge1xuXG4gICAgICAgIHJvd05vZGUuZWRpdGluZ1tjb2x1bW4uZmllbGRdID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG5cbiAgICAgICAgY29uc3QgaW5wdXQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yPEhUTUxJbnB1dEVsZW1lbnQgfCBIVE1MU2VsZWN0RWxlbWVudD4oYFtkYXRhLWNlbGwtaWQ9XCIkeyBnZXRDZWxsS2V5KG5vZGUucm93SWQsIGNvbHVtbi5maWVsZCkgfVwiXSBpbnB1dCwgW2RhdGEtY2VsbC1pZD1cIiR7IGdldENlbGxLZXkobm9kZS5yb3dJZCwgY29sdW1uLmZpZWxkKSB9XCJdIHNlbGVjdGApO1xuXG4gICAgICAgIGlmIChpbnB1dCkge1xuXG4gICAgICAgICAgaW5wdXQuZm9jdXMoKTtcblxuICAgICAgICAgIGNvbnN0IHZhbHVlID0gaW5wdXQudmFsdWU7XG5cbiAgICAgICAgICAvLyBBIHNlbGVjdCByZXBvcnRzIHR5cGUgJ3NlbGVjdC1vbmUnLCBzbyBvbmx5IGEgdGV4dCBpbnB1dCBnZXRzIGl0c1xuICAgICAgICAgIC8vIGNhcmV0IHBsYWNlZC5cbiAgICAgICAgICBpZiAodmFsdWUgJiYgW1widGV4dFwiXS5pbmNsdWRlcyhpbnB1dC50eXBlKSAmJiAnc2V0U2VsZWN0aW9uUmFuZ2UnIGluIGlucHV0KSB7XG5cbiAgICAgICAgICAgIGlucHV0LnNldFNlbGVjdGlvblJhbmdlKHZhbHVlLmxlbmd0aCwgdmFsdWUubGVuZ3RoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LCAxMCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNhdmUgQ2VsbCBFZGl0IE1vZGVcbiAgICovXG4gIHN0b3BFZGl0KG5vZGU6IE9uZVJvd05vZGU8VD4sIGNvbHVtbjogT25lQ29sdW1uRGVmPFQ+LCBldmVudDogYW55KSB7XG5cbiAgICBpZiAodGhpcy5lZGl0VHlwZSA9PT0gJ2Z1bGxSb3cnKSB7XG5cbiAgICAgIHRoaXMuc3RvcFJvd0VkaXRGcm9tRXZlbnQobm9kZSwgZXZlbnQpO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IHJvd05vZGU6IE9uZVJvd05vZGUgPSB0aGlzLmFwaS5nZXRSb3dOb2RlQnlJZChub2RlLnJvd0lkKTtcblxuICAgIC8vIFRoZSBlZGl0aW5nIGd1YXJkIG1ha2VzIGEgc2Vjb25kIGNvbW1pdCBmb3Igb25lIGVkaXQgYSBuby1vcDogYSBzZWxlY3RcbiAgICAvLyBjb21taXRzIG9uIChjaGFuZ2UpLCB3aGljaCBjbG9zZXMgdGhlIGVkaXRvciwgYW5kIHRoZSAoYmx1cikgdGhhdCBjYW5cbiAgICAvLyBmb2xsb3cgbXVzdCBub3QgY29tbWl0IGFnYWluLlxuICAgIGlmIChyb3dOb2RlICYmIHJvd05vZGUuZWRpdGluZ1tjb2x1bW4uZmllbGRdKSB7XG5cbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgY29uc3QgdmFsdWUgPSBldmVudC50YXJnZXQudmFsdWUgPz8gJyc7XG4gICAgICBjb25zdCBvbGRWYWx1ZSA9IHJvd05vZGUuZGF0YVtjb2x1bW4uZmllbGRdO1xuXG4gICAgICB0aGlzLnNldENlbGxWYWx1ZUJ5Um93SWQobm9kZS5yb3dJZCwgY29sdW1uLCB2YWx1ZSk7XG5cbiAgICAgIHRoaXMuZmluaXNoRWRpdChyb3dOb2RlLCBjb2x1bW4sIG9sZFZhbHVlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2F2ZSBhIGBzZWxlY3RgIGVkaXRvcidzIGNob2ljZS5cbiAgICpcbiAgICogU2VwYXJhdGUgZnJvbSBgc3RvcEVkaXRgIGJlY2F1c2UgdGhlIHZhbHVlIGlzIG5vdCB0aGUgZWxlbWVudCdzIHN0cmluZzpcbiAgICogdGhlIGNob3NlbiBpbmRleCBtYXBzIGJhY2sgaW50byBgc2VsZWN0T3B0aW9uc2AsIHNvIHRoZSBjb21taXR0ZWQgdmFsdWVcbiAgICoga2VlcHMgd2hhdGV2ZXIgdHlwZSB0aGUgb3B0aW9uIGRlY2xhcmVkLlxuICAgKi9cbiAgc3RvcEVkaXRTZWxlY3Qobm9kZTogT25lUm93Tm9kZTxUPiwgY29sdW1uOiBPbmVDb2x1bW5EZWY8VD4sIGV2ZW50OiBhbnkpIHtcblxuICAgIGlmICh0aGlzLmVkaXRUeXBlID09PSAnZnVsbFJvdycpIHtcblxuICAgICAgLy8gKGNoYW5nZSkgaXMgbm90IGEgY29tbWl0IGluIGZ1bGwtcm93IG1vZGUg4oCUIHRoZSBjaG9pY2Ugc2l0cyBpbiB0aGVcbiAgICAgIC8vIHNlbGVjdCB1bnRpbCB0aGUgcm93IGNvbW1pdHMgYW5kIHJlYWRzIGV2ZXJ5IGVkaXRvciBhdCBvbmNlLiBPbmx5IGFcbiAgICAgIC8vIGJsdXIgdGhhdCBhY3R1YWxseSBsZWF2ZXMgdGhlIHJvdyBjbG9zZXMgaXQuXG4gICAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ2JsdXInKSB0aGlzLnN0b3BSb3dFZGl0RnJvbUV2ZW50KG5vZGUsIGV2ZW50KTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCByb3dOb2RlOiBPbmVSb3dOb2RlID0gdGhpcy5hcGkuZ2V0Um93Tm9kZUJ5SWQobm9kZS5yb3dJZCk7XG5cbiAgICBpZiAocm93Tm9kZSAmJiByb3dOb2RlLmVkaXRpbmdbY29sdW1uLmZpZWxkXSkge1xuXG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgY29uc3Qgb3B0aW9ucyA9IGNvbHVtbj8uY2VsbFJlbmRlcmVyUGFyYW1zPy5zZWxlY3RPcHRpb25zID8/IFtdO1xuICAgICAgY29uc3Qgb3B0aW9uID0gb3B0aW9uc1soZXZlbnQudGFyZ2V0IGFzIEhUTUxTZWxlY3RFbGVtZW50KS5zZWxlY3RlZEluZGV4XTtcblxuICAgICAgaWYgKCFvcHRpb24pIHJldHVybjtcblxuICAgICAgY29uc3Qgb2xkVmFsdWUgPSByb3dOb2RlLmRhdGFbY29sdW1uLmZpZWxkXTtcblxuICAgICAgcm93Tm9kZS5kYXRhW2NvbHVtbi5maWVsZF0gPSBvcHRpb24udmFsdWU7XG5cbiAgICAgIHRoaXMuZmluaXNoRWRpdChyb3dOb2RlLCBjb2x1bW4sIG9sZFZhbHVlKTtcbiAgICB9XG4gIH1cblxuICAvKiogQ2xvc2UgdGhlIGVkaXRvciBhbmQgYW5ub3VuY2UgdGhlIGNvbW1pdC4gU2hhcmVkIGJ5IGJvdGggZWRpdG9yIGtpbmRzLiAqL1xuICBwcml2YXRlIGZpbmlzaEVkaXQocm93Tm9kZTogT25lUm93Tm9kZSwgY29sdW1uOiBPbmVDb2x1bW5EZWY8VD4sIG9sZFZhbHVlOiBhbnkpIHtcblxuICAgIGNvbnN0IG5ld1ZhbHVlID0gcm93Tm9kZS5kYXRhW2NvbHVtbi5maWVsZF07XG5cbiAgICByb3dOb2RlLmNlbGxTdGF0ZXMgPSB0aGlzLmNlbGxTZXJ2aWNlLmdlbmVyYXRlQ2VsbFN0YXRlcyhyb3dOb2RlKTtcbiAgICByb3dOb2RlLmVkaXRpbmdbY29sdW1uLmZpZWxkXSA9IGZhbHNlO1xuXG4gICAgdGhpcy5ldmVudFNlcnZpY2UuZGlzcGF0Y2hFdmVudCgnY2VsbFN0YXRlQ2hhbmdlZCcsIHtcbiAgICAgIGRhdGE6IHJvd05vZGUuZGF0YSxcbiAgICAgIG5vZGU6IHJvd05vZGUsXG4gICAgICBjb2x1bW46IGNvbHVtblxuICAgIH0pO1xuXG4gICAgLy8gQ29tcGFyZWQgYWZ0ZXIgbm9ybWFsaXNhdGlvbiAoJycgLT4gbnVsbCwgbnVtYmVyIGNvZXJjaW9uKSwgc28gYSBibHVyXG4gICAgLy8gdGhhdCBsZWF2ZXMgdGhlIHZhbHVlIGFzIGl0IHdhcyBkb2VzIG5vdCBhbm5vdW5jZSBhbiBlZGl0LlxuICAgIGlmIChuZXdWYWx1ZSAhPT0gb2xkVmFsdWUpIHtcblxuICAgICAgdGhpcy5ldmVudFNlcnZpY2UuZGlzcGF0Y2hFdmVudCgnY2VsbFZhbHVlQ2hhbmdlZCcsIHtcbiAgICAgICAgbm9kZTogcm93Tm9kZSxcbiAgICAgICAgZGF0YTogcm93Tm9kZS5kYXRhLFxuICAgICAgICBjb2x1bW46IGNvbHVtbixcbiAgICAgICAgZmllbGQ6IGNvbHVtbi5maWVsZCxcbiAgICAgICAgb2xkVmFsdWUsXG4gICAgICAgIG5ld1ZhbHVlLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENhbmNlbCBDZWxsIEVkaXQgTW9kZVxuICAgKi9cbiAgY2FuY2VsRWRpdChub2RlOiBPbmVSb3dOb2RlPFQ+LCBjb2x1bW46IE9uZUNvbHVtbkRlZjxUPikge1xuXG4gICAgbGV0IHJvd05vZGU6IE9uZVJvd05vZGUgPSB0aGlzLmFwaS5nZXRSb3dOb2RlQnlJZChub2RlLnJvd0lkKTtcblxuICAgIGlmIChyb3dOb2RlKSB7XG5cbiAgICAgIGlmICh0aGlzLmVkaXRUeXBlID09PSAnZnVsbFJvdycpIHtcblxuICAgICAgICAvLyBFc2NhcGUgYWJhbmRvbnMgdGhlIHdob2xlIHJvdzogZXZlcnkgZWRpdG9yIGNsb3Nlcywgbm90aGluZyBjb21taXRzLlxuICAgICAgICBPYmplY3Qua2V5cyhyb3dOb2RlLmVkaXRpbmcpLmZvckVhY2goZmllbGQgPT4gcm93Tm9kZS5lZGl0aW5nW2ZpZWxkXSA9IGZhbHNlKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHJvd05vZGUuZWRpdGluZ1tjb2x1bW4uZmllbGRdID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEZ1bGwtcm93IGNvbW1pdCwgcm91dGVkIGZyb20gYW55IG9uZSBlZGl0b3IncyBFbnRlciBvciBibHVyLlxuICAgKlxuICAgKiBBIGJsdXIgdGhhdCBsYW5kcyBvbiBhbm90aGVyIGVkaXRvciBpbiB0aGUgc2FtZSByb3cgaXMgdGhlIHVzZXIgdGFiYmluZ1xuICAgKiBiZXR3ZWVuIGZpZWxkcywgbm90IGxlYXZpbmcgdGhlIHJvdyDigJQgdGhlIGVkaXRvcnMgc3RheSBvcGVuIGFuZCB0aGVpclxuICAgKiB0eXBlZCB2YWx1ZXMgc3RheSBpbiB0aGUgRE9NIHVudGlsIHRoZSByb3cgY29tbWl0cy5cbiAgICovXG4gIHByaXZhdGUgc3RvcFJvd0VkaXRGcm9tRXZlbnQobm9kZTogT25lUm93Tm9kZTxUPiwgZXZlbnQ6IGFueSkge1xuXG4gICAgaWYgKGV2ZW50LnR5cGUgPT09ICdibHVyJykge1xuXG4gICAgICBjb25zdCBuZXh0ID0gKGV2ZW50IGFzIEZvY3VzRXZlbnQpLnJlbGF0ZWRUYXJnZXQgYXMgSFRNTEVsZW1lbnQgfCBudWxsO1xuXG4gICAgICBpZiAobmV4dD8ubWF0Y2hlcz8uKCdpbnB1dC5vbmUtY2VsbC1pbnB1dCwgc2VsZWN0Lm9uZS1jZWxsLWlucHV0JylcbiAgICAgICAgJiYgbmV4dC5jbG9zZXN0Py4oYFtkYXRhLWNlbGwtaWRePVwiJHtub2RlLnJvd0lkfS0tXCJdYCkpIHtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgZXZlbnQucHJldmVudERlZmF1bHQ/LigpO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbj8uKCk7XG5cbiAgICB0aGlzLnN0b3BSb3dFZGl0KG5vZGUpO1xuICB9XG5cbiAgLyoqIENvbW1pdCBldmVyeSBvcGVuIGVkaXRvciBvZiBvbmUgcm93LCByZWFkaW5nIGVhY2ggZnJvbSB0aGUgRE9NLiAqL1xuICBwcml2YXRlIHN0b3BSb3dFZGl0KG5vZGU6IE9uZVJvd05vZGU8VD4pIHtcblxuICAgIGNvbnN0IHJvd05vZGU6IE9uZVJvd05vZGUgPSB0aGlzLmFwaS5nZXRSb3dOb2RlQnlJZChub2RlLnJvd0lkKTtcblxuICAgIGlmICghcm93Tm9kZSkgcmV0dXJuO1xuXG4gICAgZm9yIChjb25zdCBjb2x1bW4gb2YgdGhpcy5jb2x1bW5EZWZzKSB7XG5cbiAgICAgIGNvbnN0IGZpZWxkID0gY29sdW1uLmZpZWxkIGFzIHN0cmluZztcblxuICAgICAgaWYgKCFmaWVsZCB8fCAhcm93Tm9kZS5lZGl0aW5nW2ZpZWxkXSkgY29udGludWU7XG5cbiAgICAgIGNvbnN0IGtleSA9IGdldENlbGxLZXkocm93Tm9kZS5yb3dJZCwgZmllbGQpO1xuICAgICAgY29uc3QgZWRpdG9yID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcjxIVE1MSW5wdXRFbGVtZW50IHwgSFRNTFNlbGVjdEVsZW1lbnQ+KFxuICAgICAgICBgW2RhdGEtY2VsbC1pZD1cIiR7a2V5fVwiXSBpbnB1dCwgW2RhdGEtY2VsbC1pZD1cIiR7a2V5fVwiXSBzZWxlY3RgKTtcblxuICAgICAgY29uc3Qgb2xkVmFsdWUgPSByb3dOb2RlLmRhdGFbZmllbGRdO1xuXG4gICAgICBpZiAoZWRpdG9yPy50YWdOYW1lID09PSAnU0VMRUNUJykge1xuXG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBjb2x1bW4uY2VsbFJlbmRlcmVyUGFyYW1zPy5zZWxlY3RPcHRpb25zID8/IFtdO1xuICAgICAgICBjb25zdCBvcHRpb24gPSBvcHRpb25zWyhlZGl0b3IgYXMgSFRNTFNlbGVjdEVsZW1lbnQpLnNlbGVjdGVkSW5kZXhdO1xuXG4gICAgICAgIGlmIChvcHRpb24pIHJvd05vZGUuZGF0YVtmaWVsZF0gPSBvcHRpb24udmFsdWU7XG5cbiAgICAgIH0gZWxzZSBpZiAoZWRpdG9yKSB7XG5cbiAgICAgICAgY29uc3QgcmF3ID0gZWRpdG9yLnZhbHVlID8/ICcnO1xuXG4gICAgICAgIHJvd05vZGUuZGF0YVtmaWVsZF0gPSByYXcgPT09ICcnXG4gICAgICAgICAgPyBudWxsXG4gICAgICAgICAgOiBjb2x1bW4uY2VsbFJlbmRlcmVyUGFyYW1zPy5pbnB1dFR5cGUgPT09ICdudW1iZXInID8gTnVtYmVyKHJhdykgOiByYXc7XG4gICAgICB9XG5cbiAgICAgIC8vIGZpbmlzaEVkaXQgY2xvc2VzIHRoZSBlZGl0b3IsIHJlZnJlc2hlcyB0aGUgY2VsbCBzdGF0ZSBhbmQgcmFpc2VzXG4gICAgICAvLyBjZWxsVmFsdWVDaGFuZ2VkIHdoZW4gdGhlIHZhbHVlIG1vdmVkIOKAlCBvbmUgZXZlbnQgcGVyIGNoYW5nZWQgY2VsbCxcbiAgICAgIC8vIHRoZSBzYW1lIGNvbnRyYWN0IGFzIHNpbmdsZS1jZWxsIGVkaXRpbmcuXG4gICAgICB0aGlzLmZpbmlzaEVkaXQocm93Tm9kZSwgY29sdW1uLCBvbGRWYWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNldCBDZWxsIFZhbHVlXG4gICAqL1xuICBzZXRDZWxsVmFsdWVCeVJvd0lkKHJvd0lkOiBzdHJpbmcsIGNvbHVtbjogT25lQ29sdW1uRGVmLCB2YWx1ZTogYW55KSB7XG5cbiAgICBjb25zdCBub2RlID0gdGhpcy5hcGkuZ2V0Um93Tm9kZUJ5SWQocm93SWQpO1xuXG4gICAgaWYgKG5vZGUgJiYgY29sdW1uLmZpZWxkKSB7XG5cbiAgICAgIGlmIChjb2x1bW4/LmNlbGxSZW5kZXJlclBhcmFtcz8uaW5wdXRUeXBlICE9PSAnbnVtYmVyJykge1xuXG4gICAgICAgIG5vZGUuZGF0YVtjb2x1bW4uZmllbGRdID0gdmFsdWUgPT09ICcnID8gbnVsbCA6IHZhbHVlO1xuXG4gICAgICB9IGVsc2Uge1xuXG4gICAgICAgIG5vZGUuZGF0YVtjb2x1bW4uZmllbGRdID0gdmFsdWUgPT09ICcnID8gbnVsbCA6IE51bWJlcih2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFZpcnR1YWwgU2Nyb2xsIFByb3BlcnRpZXNcbiAgICpcbiAgICogVGhlIGJ1ZmZlciBzY2FsZXMgd2l0aCB0aGUgcm93IGNvdW50IHNvIHNtYWxsIGdyaWRzIHJlbmRlciBpbiBvbmUgcGFzcywgYnV0XG4gICAqIGl0IGlzIGNhcHBlZDogYGl0ZW1TaXplICogaXRlbXMgKiAxLjVgIGlzIDEuNXggdGhlICp0b3RhbCogY29udGVudCBoZWlnaHQsXG4gICAqIGFuZCBDZGtGaXhlZFNpemVWaXJ0dWFsU2Nyb2xsIGV4cGFuZHMgaXRzIHJlbmRlcmVkIHJhbmdlIHVudGlsIHRoZSBidWZmZXIgaXNcbiAgICogc2F0aXNmaWVkLiBVbmNhcHBlZCwgdGhhdCBtYWtlcyB0aGUgdmlld3BvcnQgbWF0ZXJpYWxpc2UgZXZlcnkgcm93IGFuZFxuICAgKiB2aXJ0dWFsIHNjcm9sbGluZyBzdG9wcyBkb2luZyBhbnl0aGluZyBhdCBhbGwgKDEwMGsgcm93cyBsb2NrZWQgdGhlIHRhYikuXG4gICAqIE1BWF9CVUZGRVJfUFgga2VlcHMgcm91Z2hseSB0d2VudHkgcm93cyBvZiBvdmVyc2NhbiBlaXRoZXIgc2lkZSBpbnN0ZWFkLlxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBNQVhfQlVGRkVSX1BYOiBudW1iZXIgPSA2MDA7XG5cbiAgc2V0VmlydHVhbFNjcm9sbChpdGVtczogbnVtYmVyID0gMCk6IHZvaWQge1xuXG4gICAgdGhpcy5taW5CdWZmZXJQeCA9IE1hdGgubWluKHRoaXMuaXRlbVNpemUgKiBpdGVtcyAqIDEuNSwgdGhpcy5NQVhfQlVGRkVSX1BYKTtcblxuICAgIHRoaXMubWF4QnVmZmVyUHggPSB0aGlzLm1pbkJ1ZmZlclB4ICogMjtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnN1YnNjcmliZSBBbGwgU3Vic2NyaXB0aW9uc1xuICAgKi9cbiAgLyoqXG4gICAqIEhhbmQgdGhlIGRyYWcgc2VydmljZSB3aGF0IGl0IG5lZWRzIHRvIHJ1biBhIGdlc3R1cmUuXG4gICAqXG4gICAqIERlZmVycmVkIHRvIGhlcmUgYmVjYXVzZSB0aGUgdmlld3BvcnQgZWxlbWVudCBkb2VzIG5vdCBleGlzdCB1bnRpbCB0aGUgdmlld1xuICAgKiBpcyB1cCwgYW5kIGBub2Rlc2AgaXMgcGFzc2VkIGFzIGEgZ2V0dGVyIHJhdGhlciB0aGFuIGEgdmFsdWUg4oCUIGEgZHJhZ1xuICAgKiBtdXRhdGVzIHRoZSBvcmRlciB1bmRlcm5lYXRoIGl0LCBzbyBhIHNuYXBzaG90IHRha2VuIGF0IGF0dGFjaCB0aW1lIHdvdWxkXG4gICAqIGdvIHN0YWxlIG9uIHRoZSBmaXJzdCBtb3ZlLlxuICAgKi9cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuXG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMudmlld3BvcnQ/LmVsZW1lbnRSZWY/Lm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICBpZiAoIWVsZW1lbnQpIHJldHVybjtcblxuICAgIHRoaXMucm93RHJhZ1NlcnZpY2UuYXR0YWNoKHtcbiAgICAgIHZpZXdwb3J0OiBlbGVtZW50LFxuICAgICAgaXRlbVNpemU6IHRoaXMuaXRlbVNpemUsXG4gICAgICBub2RlczogKCkgPT4gdGhpcy5ub2RlcyxcbiAgICAgIG1vdmU6IChmcm9tSW5kZXg6IG51bWJlciwgdG9JbmRleDogbnVtYmVyKSA9PiB7XG5cbiAgICAgICAgY29uc3QgbW92ZWQgPSB0aGlzLmFwaS5tb3ZlUm93KGZyb21JbmRleCwgdG9JbmRleCk7XG5cbiAgICAgICAgaWYgKG1vdmVkKSB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcblxuICAgICAgICByZXR1cm4gbW92ZWQ7XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgdGhpcy5yZWZyZXNoUm93RHJhZ1N1cHByZXNzZWQoKTtcblxuICAgIC8vIFRoZSBDREsgaW5zZXJ0cyBpdHMgb3duIGNvbnRlbnQgd3JhcHBlciBiZXR3ZWVuIHRoZSB2aWV3cG9ydCBhbmQgdGhlXG4gICAgLy8gcm93cy4gSXQgaGFzIG5vIHRlbXBsYXRlIG9mIG91cnMgdG8gYW5ub3RhdGUsIGFuZCBsZWZ0IGdlbmVyaWMgaXQgYnJlYWtzXG4gICAgLy8gdGhlIGBncmlkID4gcm93YCBvd25lcnNoaXAgdGhlIHJvbGVzIGRlcGVuZCBvbi5cbiAgICBjb25zdCB3cmFwcGVyID0gZWxlbWVudC5xdWVyeVNlbGVjdG9yKCcuY2RrLXZpcnR1YWwtc2Nyb2xsLWNvbnRlbnQtd3JhcHBlcicpO1xuXG4gICAgd3JhcHBlcj8uc2V0QXR0cmlidXRlKCdyb2xlJywgJ3ByZXNlbnRhdGlvbicpO1xuXG4gICAgLy8gRmxleCBjb2x1bW5zIHNpemUgYWdhaW5zdCB0aGlzIHZpZXdwb3J0LCBub3cgYW5kIHdoZW5ldmVyIGl0IHJlc2l6ZXMuXG4gICAgLy8gYXBwbHlGbGV4V2lkdGhzIGlzIGEgbm8tb3Agd2l0aG91dCBmbGV4IGNvbHVtbnMgYW5kIGRpc3BhdGNoZXMgb25seSBvbiBhXG4gICAgLy8gcmVhbCBjaGFuZ2UsIHNvIGdyaWRzIHRoYXQgbmV2ZXIgdXNlIGZsZXggcGF5IG5vdGhpbmcgaGVyZS5cbiAgICB0aGlzLmFwcGx5RmxleFdpZHRocygpO1xuXG4gICAgaWYgKHR5cGVvZiBSZXNpemVPYnNlcnZlciAhPT0gJ3VuZGVmaW5lZCcpIHtcblxuICAgICAgdGhpcy5mbGV4UmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIoKCkgPT4gdGhpcy5hcHBseUZsZXhXaWR0aHMoKSk7XG4gICAgICB0aGlzLmZsZXhSZXNpemVPYnNlcnZlci5vYnNlcnZlKGVsZW1lbnQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZmxleFJlc2l6ZU9ic2VydmVyPzogUmVzaXplT2JzZXJ2ZXI7XG5cbiAgcHJpdmF0ZSBhcHBseUZsZXhXaWR0aHMoKTogdm9pZCB7XG5cbiAgICBjb25zdCB3aWR0aCA9IHRoaXMudmlld3BvcnQ/LmVsZW1lbnRSZWY/Lm5hdGl2ZUVsZW1lbnQ/LmNsaWVudFdpZHRoID8/IDA7XG5cbiAgICBpZiAod2lkdGggPiAwKSB0aGlzLmFwaS5hcHBseUZsZXhXaWR0aHMod2lkdGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBwYXJhbXMgZXZlcnkgcGVyLWNlbGwgY2FsbGJhY2sgcmVjZWl2ZXMuXG4gICAqXG4gICAqIEJ1aWx0IGhlcmUgcmF0aGVyIHRoYW4gaW5saW5lIGluIHRoZSB0ZW1wbGF0ZSBzbyB0aGUgd2hvbGUgZG9jdW1lbnRlZFxuICAgKiBzaGFwZSBpcyBwYXNzZWQg4oCUIGB2YWx1ZWAsIGBmaWVsZGAsIGByb3dJbmRleGAsIGBhcGlgIGFuZCBgY29udGV4dGAgd2VyZVxuICAgKiBhbGwgZGVjbGFyZWQgb24gYE9uZUNlbGxSZW5kZXJlclBhcmFtc2AgYW5kIG5vbmUgb2YgdGhlbSB3ZXJlIGJlaW5nIHNlbnQsXG4gICAqIHNvIGEgYGNlbGxDbGFzc2AgcmVhZGluZyBgcGFyYW1zLnZhbHVlYCBzaWxlbnRseSBnb3QgYHVuZGVmaW5lZGAuXG4gICAqL1xuICBwcm90ZWN0ZWQgY2VsbFBhcmFtcyhub2RlOiBPbmVSb3dOb2RlPFQ+LCBjb2x1bW46IE9uZUNvbHVtbkRlZjxUPik6IE9uZUNlbGxQcmVzZW50YXRpb25QYXJhbXM8VD4ge1xuXG4gICAgcmV0dXJuIHRoaXMuY2VsbFNlcnZpY2UuY2VsbFBhcmFtcyhjb2x1bW4sIG5vZGUpIGFzIE9uZUNlbGxQcmVzZW50YXRpb25QYXJhbXM8VD47XG4gIH1cblxuICAvKipcbiAgICogUGFyYW1zIGZvciBhIGNvbXBvbmVudCBjZWxsIHJlbmRlcmVyLlxuICAgKlxuICAgKiBUaGUgY2VsbCBwYXJhbXMsIHBsdXMgd2hhdGV2ZXIgdGhlIGNvbHVtbiBkZWNsYXJlZCBpblxuICAgKiBgY2VsbFJlbmRlcmVyUGFyYW1zYCDigJQgYSBmaWVsZCB0aGF0IGV4aXN0cyBwcmVjaXNlbHkgc28gYSByZW5kZXJlciBjYW4gYmVcbiAgICogY29uZmlndXJlZCBwZXIgY29sdW1uLCBhbmQgdGhhdCBub3RoaW5nIGhhZCBldmVyIGZvcndhcmRlZCB0byBpdC4gQ29sdW1uXG4gICAqIGNvbmZpZyBnb2VzIGZpcnN0IHNvIHRoZSBncmlkJ3Mgb3duIGZpZWxkcyB3aW4gYSBuYW1lIGNvbGxpc2lvbi5cbiAgICovXG4gIHByb3RlY3RlZCByZW5kZXJlclBhcmFtcyhub2RlOiBPbmVSb3dOb2RlPFQ+LCBjb2x1bW46IE9uZUNvbHVtbkRlZjxUPik6IE9uZUNlbGxSZW5kZXJlclBhcmFtczxUPiB7XG5cbiAgICByZXR1cm4geyAuLi4oY29sdW1uPy5jZWxsUmVuZGVyZXJQYXJhbXMgPz8ge30pLCAuLi50aGlzLmNlbGxQYXJhbXMobm9kZSwgY29sdW1uKSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIGBhcmlhLXJvd2luZGV4YCBpcyAxLWJhc2VkIG92ZXIgdGhlIHdob2xlIGdyaWQsIG5vdCBvdmVyIHdoYXQgaXMgcmVuZGVyZWQuXG4gICAqXG4gICAqIFRoYXQgaXMgdGhlIHBvaW50IG9mIGl0OiB0aGUgYm9keSB2aXJ0dWFsaXNlcywgc28gdGhlIERPTSBob2xkcyBhIHNsaWRpbmdcbiAgICogd2luZG93IG9mIHJvd3MgYW5kIHRoZSBpbmRleCBpcyBob3cgYSBzY3JlZW4gcmVhZGVyIGtub3dzIHdoZXJlIHRoZSB3aW5kb3dcbiAgICogc2l0cy4gUm93IDEgaXMgdGhlIGhlYWRlciwgdGhlbiBhbnkgcGlubmVkLXRvcCByb3dzLCB0aGVuIHRoZSBkYXRhLlxuICAgKi9cbiAgcHJvdGVjdGVkIGRhdGFSb3dBcmlhSW5kZXgobm9kZTogT25lUm93Tm9kZTxUPik6IG51bWJlciB7XG5cbiAgICByZXR1cm4gMiArIHRoaXMucGlubmVkVG9wTm9kZXMubGVuZ3RoICsgbm9kZS5yb3dJbmRleDtcbiAgfVxuXG4gIC8qKiBQaW5uZWQgcm93cyBicmFja2V0IHRoZSBkYXRhOiB0b3Agb25lcyBmb2xsb3cgdGhlIGhlYWRlciwgYm90dG9tIG9uZXMgZW5kIHRoZSBncmlkLiAqL1xuICBwcm90ZWN0ZWQgcGlubmVkUm93QXJpYUluZGV4KG5vZGU6IE9uZVJvd05vZGU8VD4sIHNpZGU6ICd0b3AnIHwgJ2JvdHRvbScpOiBudW1iZXIge1xuXG4gICAgY29uc3QgaW5kZXggPSAoc2lkZSA9PT0gJ3RvcCcgPyB0aGlzLnBpbm5lZFRvcE5vZGVzIDogdGhpcy5waW5uZWRCb3R0b21Ob2RlcykuaW5kZXhPZihub2RlKTtcblxuICAgIHJldHVybiBzaWRlID09PSAndG9wJ1xuICAgICAgPyAyICsgaW5kZXhcbiAgICAgIDogMiArIHRoaXMucGlubmVkVG9wTm9kZXMubGVuZ3RoICsgdGhpcy5ub2Rlcy5sZW5ndGggKyBpbmRleDtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHJvd3MgY2FuIGJlIHNlbGVjdGVkIGF0IGFsbC5cbiAgICpcbiAgICogYGFyaWEtc2VsZWN0ZWQ9XCJmYWxzZVwiYCBvbiBldmVyeSByb3cgb2YgYSBncmlkIG5vYm9keSBjYW4gc2VsZWN0IGFubm91bmNlc1xuICAgKiBhIHNlbGVjdGlvbiBhZmZvcmRhbmNlIHRoYXQgZG9lcyBub3QgZXhpc3QsIHNvIHRoZSBhdHRyaWJ1dGUgaXMgb21pdHRlZFxuICAgKiByYXRoZXIgdGhhbiBzZXQgZmFsc2UuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IHJvd1NlbGVjdGlvbkVuYWJsZWQoKTogYm9vbGVhbiB7XG5cbiAgICByZXR1cm4gISF0aGlzLmFwaT8ucm93U2VsZWN0aW9uO1xuICB9XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIENlbGwgbmF2aWdhdGlvblxuICAvL1xuICAvLyBUaGUgV0FJLUFSSUEgZ3JpZCBwYXR0ZXJuOiB0aGUgd2hvbGUgZ3JpZCBpcyBvbmUgdGFiIHN0b3AsIGFuZCB0aGUgYXJyb3dzXG4gIC8vIG1vdmUgYSBmb2N1c2VkIGNlbGwgd2l0aGluIGl0LiBCZWZvcmUgdGhpcyB0aGUgb25seSB0YWIgc3RvcCB3YXMgdGhlIHNjcm9sbFxuICAvLyB2aWV3cG9ydCwgc28gYSBrZXlib2FyZCB1c2VyIGNvdWxkIHNjcm9sbCB0aGUgcm93cyBhbmQgcmVhY2ggbm90aGluZyBpblxuICAvLyB0aGVtIOKAlCBhbmQgYSBzY3JlZW4gcmVhZGVyIGhhZCBubyBjdXJzb3IgdG8gcmVhZCBhIGNlbGwgZnJvbS5cbiAgLy9cbiAgLy8gRm9jdXMgaXMgcmVhbCBET00gZm9jdXMgb24gYSByb3ZpbmcgdGFiaW5kZXggcmF0aGVyIHRoYW5cbiAgLy8gYGFyaWEtYWN0aXZlZGVzY2VuZGFudGAsIGJlY2F1c2UgdGhlIHJvd3MgYXJlIHZpcnR1YWxpc2VkOiB0aGUgZWxlbWVudCBhXG4gIC8vIGRlc2NlbmRhbnQgaWQgcG9pbnRlZCBhdCB3b3VsZCBrZWVwIGJlaW5nIGRlc3Ryb3llZCB1bmRlcm5lYXRoIGl0LlxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICAvKiogVGhlIGNlbGwgaG9sZGluZyB0aGUgZ3JpZCdzIHRhYiBzdG9wLiBOdWxsIHVudGlsIHNvbWV0aGluZyBpcyBmb2N1c2VkLiAqL1xuICBwcm90ZWN0ZWQgYWN0aXZlQ2VsbDogeyByb3dJZDogc3RyaW5nOyBmaWVsZDogc3RyaW5nIH0gfCBudWxsID0gbnVsbDtcblxuICBwcm90ZWN0ZWQgaXNBY3RpdmVDZWxsKG5vZGU6IE9uZVJvd05vZGU8VD4sIGNvbHVtbjogT25lQ29sdW1uRGVmPFQ+KTogYm9vbGVhbiB7XG5cbiAgICBpZiAodGhpcy5hY3RpdmVDZWxsKSB7XG5cbiAgICAgIHJldHVybiB0aGlzLmFjdGl2ZUNlbGwucm93SWQgPT09IG5vZGUucm93SWQgJiYgdGhpcy5hY3RpdmVDZWxsLmZpZWxkID09PSBjb2x1bW4uZmllbGQ7XG4gICAgfVxuXG4gICAgLy8gTm90aGluZyBmb2N1c2VkIHlldCwgc28gdGhlIGZpcnN0IGNlbGwgaG9sZHMgdGhlIHRhYiBzdG9wLiBXaXRob3V0IHRoaXNcbiAgICAvLyBmYWxsYmFjayBhIGdyaWQgbm9ib2R5IGhhcyBjbGlja2VkIGhhcyAqbm8qIHRhYmJhYmxlIGNlbGwsIGFuZCBhIGtleWJvYXJkXG4gICAgLy8gdXNlciBjYW5ub3QgZ2V0IGludG8gaXQgYXQgYWxsIOKAlCB0aGUgcm92aW5nIHRhYmluZGV4IGhhcyB0byBzdGFydFxuICAgIC8vIHNvbWV3aGVyZS5cbiAgICByZXR1cm4gbm9kZSA9PT0gdGhpcy5ub2Rlc1swXSAmJiBjb2x1bW4gPT09IHRoaXMubmF2aWdhYmxlQ29sdW1ucygpWzBdO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkb3B0IHdoYXRldmVyIHRoZSB1c2VyIGZvY3VzZWQsIGhvd2V2ZXIgdGhleSBnb3QgdGhlcmUg4oCUIGNsaWNrLCB0YWIsIG9yXG4gICAqIHRoZSBhcnJvdyBrZXlzIGJlbG93LiBLZWVwaW5nIHRoaXMgaW4gb25lIHBsYWNlIGlzIHdoYXQgc3RvcHMgdGhlIHJvdmluZ1xuICAgKiB0YWJpbmRleCBkcmlmdGluZyBhd2F5IGZyb20gdGhlIGVsZW1lbnQgdGhhdCBhY3R1YWxseSBoYXMgZm9jdXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgb25DZWxsRm9jdXMobm9kZTogT25lUm93Tm9kZTxUPiwgY29sdW1uOiBPbmVDb2x1bW5EZWY8VD4pOiB2b2lkIHtcblxuICAgIGlmICh0aGlzLmlzQWN0aXZlQ2VsbChub2RlLCBjb2x1bW4pKSByZXR1cm47XG5cbiAgICB0aGlzLmFjdGl2ZUNlbGwgPSB7IHJvd0lkOiBub2RlLnJvd0lkLCBmaWVsZDogY29sdW1uLmZpZWxkIGFzIHN0cmluZyB9O1xuXG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb25HcmlkS2V5ZG93bihldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuXG4gICAgLy8gVW5kby9yZWRvIG9mIGNvbW1pdHRlZCBlZGl0cywgYW55d2hlcmUgaW4gdGhlIGdyaWQgZXhjZXB0IGluc2lkZSBhblxuICAgIC8vIG9wZW4gZWRpdG9yIOKAlCBhIHRleHQgaW5wdXQncyBDdHJsK1ogaXMgdGhlIGJyb3dzZXIncywgYW5kIGl0IG9wZXJhdGVzXG4gICAgLy8gb24gdGhlIHVuY29tbWl0dGVkIHRleHQuXG4gICAgaWYgKChldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXkpICYmIFsneicsICd5J10uaW5jbHVkZXMoZXZlbnQua2V5LnRvTG93ZXJDYXNlKCkpKSB7XG5cbiAgICAgIGNvbnN0IHRhZyA9IChldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQpPy50YWdOYW1lPy50b0xvd2VyQ2FzZSgpO1xuXG4gICAgICBpZiAodGFnID09PSAnaW5wdXQnIHx8IHRhZyA9PT0gJ3NlbGVjdCcgfHwgdGFnID09PSAndGV4dGFyZWEnKSByZXR1cm47XG5cbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgIGNvbnN0IHJlZG8gPSBldmVudC5rZXkudG9Mb3dlckNhc2UoKSA9PT0gJ3knIHx8IGV2ZW50LnNoaWZ0S2V5O1xuICAgICAgY29uc3QgYXBwbGllZCA9IHJlZG8gPyB0aGlzLmFwaS5yZWRvQ2VsbEVkaXRpbmcoKSA6IHRoaXMuYXBpLnVuZG9DZWxsRWRpdGluZygpO1xuXG4gICAgICBpZiAoYXBwbGllZCkgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjb2x1bW5zID0gdGhpcy5uYXZpZ2FibGVDb2x1bW5zKCk7XG5cbiAgICBpZiAoIXRoaXMubm9kZXMubGVuZ3RoIHx8ICFjb2x1bW5zLmxlbmd0aCkgcmV0dXJuO1xuXG4gICAgLy8gTmF2aWdhdGUgb25seSB3aGVuIGEgY2VsbCBpdHNlbGYgaG9sZHMgZm9jdXMuIEFueXRoaW5nIGZvY3VzYWJsZSAqaW5zaWRlKlxuICAgIC8vIGEgY2VsbCBvd25zIGl0cyBvd24ga2V5cyDigJQgYSB0ZXh0IGVkaXRvcidzIGNhcmV0LCB0aGUgcm93IGRyYWcgaGFuZGxlJ3NcbiAgICAvLyByZW9yZGVyIGtleXMsIHRoZSBvcHRpb24gbWVudSdzIGFycm93cyDigJQgYW5kIGFsbCBvZiB0aGVtIGJ1YmJsZSB0byBoZXJlLlxuICAgIC8vIENoZWNraW5nIHRoZSB0YXJnZXQgcmF0aGVyIHRoYW4gYmxvY2tsaXN0aW5nIHRhZyBuYW1lcyBpcyB3aGF0IGtlZXBzIHRoaXNcbiAgICAvLyBjb3JyZWN0IGFzIG1vcmUgY29udHJvbHMgYXJlIGFkZGVkIHRvIGNlbGxzLlxuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudCB8IG51bGw7XG5cbiAgICBpZiAoIXRhcmdldD8ubWF0Y2hlcz8uKCdbcm9sZT1cImdyaWRjZWxsXCJdJykpIHJldHVybjtcblxuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLmFjdGl2ZUNlbGxQb3NpdGlvbihjb2x1bW5zKTtcblxuICAgIGxldCByb3cgPSBjdXJyZW50LnJvdztcbiAgICBsZXQgY29sID0gY3VycmVudC5jb2w7XG5cbiAgICBzd2l0Y2ggKGV2ZW50LmtleSkge1xuXG4gICAgICBjYXNlICdBcnJvd0Rvd24nOiAgcm93ICs9IDE7IGJyZWFrO1xuICAgICAgY2FzZSAnQXJyb3dVcCc6ICAgIHJvdyAtPSAxOyBicmVhaztcbiAgICAgIGNhc2UgJ0Fycm93UmlnaHQnOiBjb2wgKz0gMTsgYnJlYWs7XG4gICAgICBjYXNlICdBcnJvd0xlZnQnOiAgY29sIC09IDE7IGJyZWFrO1xuXG4gICAgICAvLyBTZWxlY3Rpb24uIFNwYWNlIGlzIHRoZSBncmlkIHBhdHRlcm4ncyB0b2dnbGUsIGFuZCBpdCBoYXMgdG8gYmUgY2F1Z2h0XG4gICAgICAvLyBoZXJlIG9yIHRoZSBicm93c2VyIHNjcm9sbHMgdGhlIHBhZ2Ugd2l0aCBpdC5cbiAgICAgIGNhc2UgJyAnOiB7XG4gICAgICAgIGNvbnN0IG5vZGUgPSB0aGlzLm5vZGVzW2N1cnJlbnQucm93XTtcbiAgICAgICAgaWYgKG5vZGUpIHtcbiAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIHRoaXMudG9nZ2xlUm93U2VsZWN0aW9uKG5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY2FzZSAnYSc6XG4gICAgICBjYXNlICdBJzpcbiAgICAgICAgaWYgKCFldmVudC5jdHJsS2V5ICYmICFldmVudC5tZXRhS2V5KSByZXR1cm47XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuYXBpLnNlbGVjdEFsbCgpO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgcmV0dXJuO1xuXG4gICAgICBjYXNlICdIb21lJzpcbiAgICAgICAgY29sID0gMDtcbiAgICAgICAgaWYgKGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleSkgcm93ID0gMDtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ0VuZCc6XG4gICAgICAgIGNvbCA9IGNvbHVtbnMubGVuZ3RoIC0gMTtcbiAgICAgICAgaWYgKGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleSkgcm93ID0gdGhpcy5ub2Rlcy5sZW5ndGggLSAxO1xuICAgICAgICBicmVhaztcblxuICAgICAgLy8gQSBwYWdlIGlzIHdoYXQgdGhlIHZpZXdwb3J0IGNhbiBzaG93LCB3aGljaCBpcyB0aGUgb25seSBkZWZpbml0aW9uIHRoYXRcbiAgICAgIC8vIG1hdGNoZXMgd2hhdCB0aGUgdXNlciBzZWVzIG1vdmUuXG4gICAgICBjYXNlICdQYWdlRG93bic6IHJvdyArPSB0aGlzLnJvd3NQZXJQYWdlKCk7IGJyZWFrO1xuICAgICAgY2FzZSAnUGFnZVVwJzogICByb3cgLT0gdGhpcy5yb3dzUGVyUGFnZSgpOyBicmVhaztcblxuICAgICAgY2FzZSAnRW50ZXInOlxuICAgICAgY2FzZSAnRjInOiB7XG4gICAgICAgIGNvbnN0IG5vZGUgPSB0aGlzLm5vZGVzW2N1cnJlbnQucm93XTtcbiAgICAgICAgY29uc3QgY29sdW1uID0gY29sdW1uc1tjdXJyZW50LmNvbF07XG4gICAgICAgIGlmIChub2RlICYmIGNvbHVtbikge1xuICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgdGhpcy5zdGFydEVkaXQoeyB0YXJnZXQ6IGV2ZW50LnRhcmdldCB9IGFzIHVua25vd24gYXMgTW91c2VFdmVudCwgbm9kZSwgY29sdW1uKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGRlZmF1bHQ6IHJldHVybjtcbiAgICB9XG5cbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgY29uc3QgdGFyZ2V0Um93ID0gTWF0aC5taW4oTWF0aC5tYXgocm93LCAwKSwgdGhpcy5ub2Rlcy5sZW5ndGggLSAxKTtcblxuICAgIHRoaXMuZm9jdXNDZWxsKHRhcmdldFJvdywgTWF0aC5taW4oTWF0aC5tYXgoY29sLCAwKSwgY29sdW1ucy5sZW5ndGggLSAxKSk7XG5cbiAgICAvLyBTaGlmdCB3aXRoIGEgdmVydGljYWwgbW92ZSBleHRlbmRzIHRoZSBzZWxlY3Rpb24sIGFuY2hvcmVkIHdoZXJlIHRoZVxuICAgIC8vIGV4dGVuc2lvbiBiZWdhbiDigJQgdGhlIHNhbWUgZ2VzdHVyZSBhIGZpbGUgbGlzdCB1c2VzLlxuICAgIGlmIChldmVudC5zaGlmdEtleSAmJiB0YXJnZXRSb3cgIT09IGN1cnJlbnQucm93KSB7XG5cbiAgICAgIHRoaXMuZXh0ZW5kU2VsZWN0aW9uVG8oY3VycmVudC5yb3csIHRhcmdldFJvdyk7XG4gICAgfVxuICB9XG5cbiAgLyoqIFRoZSByb3cgYSBzaGlmdC1leHRlbmRlZCBzZWxlY3Rpb24gaXMgbWVhc3VyZWQgZnJvbS4gKi9cbiAgcHJpdmF0ZSBzZWxlY3Rpb25BbmNob3JSb3dJZDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSB0b2dnbGVSb3dTZWxlY3Rpb24obm9kZTogT25lUm93Tm9kZTxUPik6IHZvaWQge1xuXG4gICAgaWYgKCF0aGlzLmFwaS50b2dnbGVSb3dTZWxlY3Rpb24obm9kZS5yb3dJZCwgIW5vZGUuc2VsZWN0ZWQpKSByZXR1cm47XG5cbiAgICAvLyBXaGVyZSBhIHN1YnNlcXVlbnQgc2hpZnQtZXh0ZW5zaW9uIGNvdW50cyBmcm9tLlxuICAgIHRoaXMuc2VsZWN0aW9uQW5jaG9yUm93SWQgPSBub2RlLnJvd0lkO1xuXG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBwcml2YXRlIGV4dGVuZFNlbGVjdGlvblRvKGZyb21Sb3c6IG51bWJlciwgdG9Sb3c6IG51bWJlcik6IHZvaWQge1xuXG4gICAgY29uc3QgdGFyZ2V0ID0gdGhpcy5ub2Rlc1t0b1Jvd107XG5cbiAgICBpZiAoIXRhcmdldCkgcmV0dXJuO1xuXG4gICAgLy8gV2l0aCBub3RoaW5nIHNlbGVjdGVkIHlldCB0aGUgcm93IHRoZSBleHRlbnNpb24gc3RhcnRlZCBvbiBiZWNvbWVzIHRoZVxuICAgIC8vIGFuY2hvciwgc28gc2hpZnQrYXJyb3cgc2VsZWN0cyBib3RoIGVuZHMgcmF0aGVyIHRoYW4gb25seSB0aGUgZmFyIG9uZS5cbiAgICBjb25zdCBhbmNob3IgPSB0aGlzLnNlbGVjdGlvbkFuY2hvclJvd0lkID8/IHRoaXMubm9kZXNbZnJvbVJvd10/LnJvd0lkO1xuXG4gICAgaWYgKCFhbmNob3IpIHJldHVybjtcblxuICAgIHRoaXMuc2VsZWN0aW9uQW5jaG9yUm93SWQgPSBhbmNob3I7XG5cbiAgICB0aGlzLmFwaS5zZWxlY3RSb3dSYW5nZShhbmNob3IsIHRhcmdldC5yb3dJZCk7XG5cbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb2x1bW5zIGEgY2VsbCBjdXJzb3IgY2FuIGxhbmQgb24uXG4gICAqXG4gICAqIEEgY29sdW1uIHdpdGggbm8gZmllbGQgcmVuZGVycyBubyBjZWxsIHN0YXRlIGFuZCBpcyBrZXllZCBieSBmaWVsZCwgc28gaXRcbiAgICogY2Fubm90IGJlIGFkZHJlc3NlZCDigJQgYW4gYWN0aW9uLW9ubHkgY29sdW1uIGlzIGEgbGVnaXRpbWF0ZSBleGFtcGxlLlxuICAgKi9cbiAgcHJpdmF0ZSBuYXZpZ2FibGVDb2x1bW5zKCk6IE9uZUNvbHVtbkRlZjxUPltdIHtcblxuICAgIHJldHVybiB0aGlzLmNvbHVtbkRlZnMuZmlsdGVyKGNvbHVtbiA9PiAhIWNvbHVtbj8uZmllbGQpO1xuICB9XG5cbiAgcHJpdmF0ZSBhY3RpdmVDZWxsUG9zaXRpb24oY29sdW1uczogT25lQ29sdW1uRGVmPFQ+W10pOiB7IHJvdzogbnVtYmVyOyBjb2w6IG51bWJlciB9IHtcblxuICAgIGlmICghdGhpcy5hY3RpdmVDZWxsKSByZXR1cm4geyByb3c6IDAsIGNvbDogMCB9O1xuXG4gICAgY29uc3Qgcm93ID0gdGhpcy5ub2Rlcy5maW5kSW5kZXgobm9kZSA9PiBub2RlLnJvd0lkID09PSB0aGlzLmFjdGl2ZUNlbGwhLnJvd0lkKTtcbiAgICBjb25zdCBjb2wgPSBjb2x1bW5zLmZpbmRJbmRleChjb2x1bW4gPT4gY29sdW1uLmZpZWxkID09PSB0aGlzLmFjdGl2ZUNlbGwhLmZpZWxkKTtcblxuICAgIHJldHVybiB7IHJvdzogcm93IDwgMCA/IDAgOiByb3csIGNvbDogY29sIDwgMCA/IDAgOiBjb2wgfTtcbiAgfVxuXG4gIHByaXZhdGUgcm93c1BlclBhZ2UoKTogbnVtYmVyIHtcblxuICAgIGNvbnN0IGhlaWdodCA9IHRoaXMudmlld3BvcnQ/LmVsZW1lbnRSZWY/Lm5hdGl2ZUVsZW1lbnQ/LmNsaWVudEhlaWdodCA/PyAwO1xuXG4gICAgcmV0dXJuIE1hdGgubWF4KDEsIE1hdGguZmxvb3IoaGVpZ2h0IC8gdGhpcy5pdGVtU2l6ZSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1vdmUgdGhlIGN1cnNvciwgc2Nyb2xsaW5nIHRoZSByb3cgaW50byB2aWV3IGZpcnN0IHdoZW4gaXQgaXMgb3V0c2lkZSB0aGVcbiAgICogcmVuZGVyZWQgd2luZG93LlxuICAgKlxuICAgKiBUaGUgc2Nyb2xsIGlzIHRoZSByZWFzb24gZm9jdXNpbmcgaXMgZGVmZXJyZWQ6IGEgdmlydHVhbGlzZWQgcm93IHRoYXQgaXNcbiAgICogbm90IG9uIHNjcmVlbiBoYXMgbm8gZWxlbWVudCB0byBmb2N1cyB1bnRpbCB0aGUgdmlld3BvcnQgaGFzIHJlbmRlcmVkIGl0LlxuICAgKi9cbiAgcHJpdmF0ZSBmb2N1c0NlbGwocm93SW5kZXg6IG51bWJlciwgY29sSW5kZXg6IG51bWJlcik6IHZvaWQge1xuXG4gICAgY29uc3Qgbm9kZSA9IHRoaXMubm9kZXNbcm93SW5kZXhdO1xuICAgIGNvbnN0IGNvbHVtbiA9IHRoaXMubmF2aWdhYmxlQ29sdW1ucygpW2NvbEluZGV4XTtcblxuICAgIGlmICghbm9kZSB8fCAhY29sdW1uKSByZXR1cm47XG5cbiAgICB0aGlzLmFjdGl2ZUNlbGwgPSB7IHJvd0lkOiBub2RlLnJvd0lkLCBmaWVsZDogY29sdW1uLmZpZWxkIGFzIHN0cmluZyB9O1xuXG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG5cbiAgICBjb25zdCByYW5nZSA9IHRoaXMudmlld3BvcnQ/LmdldFJlbmRlcmVkUmFuZ2UoKTtcbiAgICBjb25zdCByZW5kZXJlZCA9IHJhbmdlICYmIHJvd0luZGV4ID49IHJhbmdlLnN0YXJ0ICYmIHJvd0luZGV4IDwgcmFuZ2UuZW5kO1xuXG4gICAgaWYgKHJlbmRlcmVkKSB7XG5cbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5mb2N1c0NlbGxFbGVtZW50KG5vZGUsIGNvbHVtbikpO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy52aWV3cG9ydD8uc2Nyb2xsVG9JbmRleChyb3dJbmRleCk7XG5cbiAgICAvLyBTY3JvbGxpbmcgaXMgbm90IGVub3VnaDogdGhlIENESyByZW5kZXJzIG9uIGl0cyBvd24gc2NoZWR1bGUsIHNvIHRoZSByb3dcbiAgICAvLyBoYXMgbm8gZWxlbWVudCB0byBmb2N1cyB1bnRpbCBpdCBoYXMuIFdhaXRpbmcgZm9yIHRoZSByZW5kZXJlZCByYW5nZSB0b1xuICAgIC8vIGFjdHVhbGx5IGNvbnRhaW4gdGhlIHJvdyBpcyB0aGUgb25seSByZWxpYWJsZSBzaWduYWwg4oCUIGEgZml4ZWQgZGVsYXlcbiAgICAvLyByYWNlcyB0aGUgdmlld3BvcnQgYW5kIHNpbGVudGx5IGRyb3BzIGZvY3VzIHdoZW4gaXQgbG9zZXMuXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZChcbiAgICAgIHRoaXMudmlld3BvcnQ/LnJlbmRlcmVkUmFuZ2VTdHJlYW1cbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgZmlsdGVyKG5leHQgPT4gcm93SW5kZXggPj0gbmV4dC5zdGFydCAmJiByb3dJbmRleCA8IG5leHQuZW5kKSxcbiAgICAgICAgICB0YWtlKDEpLFxuICAgICAgICApXG4gICAgICAgIC5zdWJzY3JpYmUoKCkgPT4gc2V0VGltZW91dCgoKSA9PiB0aGlzLmZvY3VzQ2VsbEVsZW1lbnQobm9kZSwgY29sdW1uKSkpLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGZvY3VzQ2VsbEVsZW1lbnQobm9kZTogT25lUm93Tm9kZTxUPiwgY29sdW1uOiBPbmVDb2x1bW5EZWY8VD4pOiB2b2lkIHtcblxuICAgIGNvbnN0IGtleSA9IGdldENlbGxLZXkobm9kZS5yb3dJZCwgY29sdW1uLmZpZWxkIGFzIHN0cmluZyk7XG5cbiAgICB0aGlzLmJvZHlSZWY/Lm5hdGl2ZUVsZW1lbnQ/LnF1ZXJ5U2VsZWN0b3I8SFRNTEVsZW1lbnQ+KGBbZGF0YS1jZWxsLWlkPVwiJHtrZXl9XCJdYCk/LmZvY3VzKCk7XG4gIH1cblxuICAvKiogSXMgdGhpcyB0aGUgcm93IGN1cnJlbnRseSBiZWluZyBtb3ZlZD8gKi9cbiAgcHJvdGVjdGVkIGlzUm93RHJhZ2dpbmcobm9kZTogT25lUm93Tm9kZTxUPik6IGJvb2xlYW4ge1xuXG4gICAgcmV0dXJuIHRoaXMuZHJhZ1N0YXRlPy5yb3dJZCA9PT0gbm9kZS5yb3dJZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGVyZSB0byBwYWludCB0aGUgZHJvcCBpbmRpY2F0b3IsIGluIHBpeGVscyBmcm9tIHRoZSB0b3Agb2YgdGhlIGJvZHkuXG4gICAqXG4gICAqIGBpbnNlcnRBdGAgaXMgYSBib3VuZGFyeSwgc28gdGhlIGxpbmUgc2l0cyBhdCByb3ctaGVpZ2h0IHRpbWVzIHRoZSBudW1iZXJcbiAgICogb2Ygcm93cyBhYm92ZSBpdCDigJQgaW4gY29udGVudCBzcGFjZS4gVGhlIGluZGljYXRvciBpcyBhIHNpYmxpbmcgb2YgdGhlXG4gICAqIHZpZXdwb3J0IHJhdGhlciB0aGFuIGEgY2hpbGQsIGJlY2F1c2UgYW55dGhpbmcgaW5zaWRlIGl0IGVpdGhlciBzY3JvbGxzXG4gICAqIGF3YXkgd2l0aCB0aGUgdHJhbnNmb3JtZWQgY29udGVudCB3cmFwcGVyIG9yIGlnbm9yZXMgdGhlIHNjcm9sbCBlbnRpcmVseSxcbiAgICogc28gdGhlIHZpZXdwb3J0J3Mgb3duIHNjcm9sbCBvZmZzZXQgYW5kIGl0cyBwb3NpdGlvbiB3aXRoaW4gdGhlIGJvZHkgYXJlXG4gICAqIGJvdGggc3VidHJhY3RlZCBiYWNrIG91dCBoZXJlLlxuICAgKlxuICAgKiBBIGZpZWxkIHJhdGhlciB0aGFuIGEgZ2V0dGVyOiBpdCBpcyByZWFkIGZyb20gdGhlIHRlbXBsYXRlIG9uIGV2ZXJ5IGNoYW5nZVxuICAgKiBkZXRlY3Rpb24gcGFzcywgYW5kIGl0IG9ubHkgYWN0dWFsbHkgbW92ZXMgd2hlbiB0aGUgZHJhZyBzdGF0ZSBvciB0aGVcbiAgICogc2Nyb2xsIHBvc2l0aW9uIGRvZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZHJvcEluZGljYXRvclRvcDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqXG4gICAqIEhvdyB3aWRlIHRoZSBsaW5lIGlzIGRyYXduLiBSb3dzIGFyZSBgd2lkdGg6IGZpdC1jb250ZW50YCwgc28gdGhleSBhcmVcbiAgICogb2Z0ZW4gbmFycm93ZXIgdGhhbiB0aGUgdmlld3BvcnQg4oCUIGEgZnVsbC1ibGVlZCBsaW5lIHdvdWxkIGhhbmcgcGFzdCB0aGVcbiAgICogbGFzdCBjb2x1bW4gaW50byBlbXB0eSBzcGFjZSBhbmQgcmVhZCBhcyBwYXJ0IG9mIHRoZSBmcmFtZSByYXRoZXIgdGhhbiB0aGVcbiAgICogcm93cy4gVGhpcyBpcyB0aGUgdmlzaWJsZSBleHRlbnQgb2YgdGhlIHJvdyBjb250ZW50LCB3aGljaCBhbHNvIHNocmlua3NcbiAgICogY29ycmVjdGx5IGFzIHRoZSBncmlkIGlzIHNjcm9sbGVkIHNpZGV3YXlzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGRyb3BJbmRpY2F0b3JXaWR0aCA9IDA7XG5cbiAgcHJpdmF0ZSB1cGRhdGVEcm9wSW5kaWNhdG9yKCk6IHZvaWQge1xuXG4gICAgY29uc3Qgc3RhdGUgPSB0aGlzLmRyYWdTdGF0ZTtcbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy52aWV3cG9ydD8uZWxlbWVudFJlZj8ubmF0aXZlRWxlbWVudDtcblxuICAgIGlmIChzdGF0ZT8uc291cmNlICE9PSAncG9pbnRlcicgfHwgIWVsZW1lbnQpIHtcblxuICAgICAgdGhpcy5kcm9wSW5kaWNhdG9yVG9wID0gbnVsbDtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuZHJvcEluZGljYXRvclRvcCA9IChzdGF0ZS5pbnNlcnRBdCAqIHRoaXMuaXRlbVNpemUpIC0gZWxlbWVudC5zY3JvbGxUb3AgKyBlbGVtZW50Lm9mZnNldFRvcDtcblxuICAgIHRoaXMuZHJvcEluZGljYXRvcldpZHRoID0gTWF0aC5tYXgoTWF0aC5taW4odGhpcy5yb3dXaWR0aCAtIGVsZW1lbnQuc2Nyb2xsTGVmdCwgZWxlbWVudC5jbGllbnRXaWR0aCksIDApO1xuICB9XG5cbiAgcHJvdGVjdGVkIG9uUm93RHJhZ0VuZChldmVudDogT25lUm93RHJhZ0V2ZW50PFQ+KTogdm9pZCB7XG5cbiAgICB0aGlzLnJvd0RyYWdFbmQuZW1pdChldmVudCk7XG4gIH1cblxuICBwcml2YXRlIHJlZnJlc2hSb3dEcmFnU3VwcHJlc3NlZCgpOiB2b2lkIHtcblxuICAgIGNvbnN0IHJlYXNvbiA9IHRoaXMuYXBpPy5nZXRSb3dEcmFnU3VwcHJlc3NlZFJlYXNvbj8uKCkgPz8gbnVsbDtcblxuICAgIGlmIChyZWFzb24gPT09IHRoaXMucm93RHJhZ1N1cHByZXNzZWQpIHJldHVybjtcblxuICAgIHRoaXMucm93RHJhZ1N1cHByZXNzZWQgPSByZWFzb247XG5cbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuXG4gICAgdGhpcy5mbGV4UmVzaXplT2JzZXJ2ZXI/LmRpc2Nvbm5lY3QoKTtcblxuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy51bnN1YnNjcmliZSgpO1xuICB9XG59XG4iLCI8ZGl2ICNib2R5UmVmIGNsYXNzPVwib25lLWdyaWQtYm9keVwiIHJvbGU9XCJwcmVzZW50YXRpb25cIj5cblxuICAgIDwhLS0gUGlubmVkIHJvd3MgbGl2ZSBvdXRzaWRlIHRoZSBzY3JvbGwgdmlld3BvcnQgc28gdGhleSBuZXZlciBzY3JvbGxcbiAgICAgICAgIHZlcnRpY2FsbHksIGFuZCBtaXJyb3IgaXRzIHNjcm9sbExlZnQgc28gdGhlIGNvbHVtbnMgc3RheSBhbGlnbmVkLiAtLT5cbiAgICBAaWYgKHBpbm5lZFRvcE5vZGVzLmxlbmd0aCkge1xuICAgICAgICA8ZGl2ICNwaW5uZWRWaWV3cG9ydCBjbGFzcz1cIm9uZS1waW5uZWQtcm93cyBvbmUtcGlubmVkLXJvd3MtdG9wXCIgcm9sZT1cInJvd2dyb3VwXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyIFtuZ1RlbXBsYXRlT3V0bGV0XT1cInBpbm5lZFJvd3NcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyBub2RlczogcGlubmVkVG9wTm9kZXMsIHNpZGU6ICd0b3AnIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9kaXY+XG4gICAgfVxuXG4gICAgPCEtLSB0YWJpbmRleCBtYWtlcyB0aGUgc2Nyb2xsIGNvbnRhaW5lciByZWFjaGFibGUsIHNvIGEga2V5Ym9hcmQgdXNlciBjYW5cbiAgICAgICAgIHNjcm9sbCB0aGUgcm93cyB3aXRoIHRoZSBhcnJvdyBrZXlzLCBQYWdlIFVwL0Rvd24gYW5kIEhvbWUvRW5kLiBXaXRob3V0XG4gICAgICAgICBpdCB0aGUgYm9keSBpcyBzY3JvbGxhYmxlIGJ5IHBvaW50ZXIgb25seSAoV0NBRyAyLjEuMSkuIC0tPlxuICAgIDxjZGstdmlydHVhbC1zY3JvbGwtdmlld3BvcnRcbiAgICAgICAgY2xhc3M9XCJvbmUtZ3JpZC1ib2R5LXZpZXdwb3J0XCJcbiAgICAgICAgcm9sZT1cInJvd2dyb3VwXCJcbiAgICAgICAgW2F0dHIudGFiaW5kZXhdPVwibm9kZXM/Lmxlbmd0aCA/IG51bGwgOiAwXCJcbiAgICAgICAgKGtleWRvd24pPVwib25HcmlkS2V5ZG93bigkZXZlbnQpXCJcbiAgICAgICAgW2l0ZW1TaXplXT1cIml0ZW1TaXplXCJcbiAgICAgICAgW21pbkJ1ZmZlclB4XT1cIm1pbkJ1ZmZlclB4XCJcbiAgICAgICAgW21heEJ1ZmZlclB4XT1cIm1heEJ1ZmZlclB4XCJcbiAgICAgICAgKHNjcm9sbCk9XCJvbkJvZHlTY3JvbGwoJGV2ZW50KVwiPlxuXG4gICAgICAgIDxuZy1jb250YWluZXIgKmNka1ZpcnR1YWxGb3I9XCJsZXQgbm9kZSBvZiBub2RlczsgdHJhY2tCeTogdHJhY2tCeVJvd0lkO1wiPlxuICAgICAgICAgICAgXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwib25lLXJvd1wiXG4gICAgICAgICAgICAgICAgcm9sZT1cInJvd1wiXG4gICAgICAgICAgICAgICAgW2F0dHIuYXJpYS1yb3dpbmRleF09XCJkYXRhUm93QXJpYUluZGV4KG5vZGUpXCJcbiAgICAgICAgICAgICAgICBbYXR0ci5hcmlhLXNlbGVjdGVkXT1cInJvd1NlbGVjdGlvbkVuYWJsZWQgPyBub2RlLnNlbGVjdGVkIDogbnVsbFwiXG4gICAgICAgICAgICAgICAgW2F0dHIuZGF0YS1yb3ctaWRdPVwibm9kZS5yb3dJZFwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLm9uZS1yb3ctc2VsZWN0ZWRdPVwibm9kZS5zZWxlY3RlZFwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLm9uZS1yb3ctZHJhZ2dpbmddPVwiaXNSb3dEcmFnZ2luZyhub2RlKVwiPlxuICAgICAgICAgICAgICAgIEBmb3IgKGNvbCBvZiBjb2x1bW5EZWZzOyB0cmFjayBjb2wuZmllbGQ7KSB7XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwiY2VsbFRlbXBsYXRlXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgbm9kZSwgcm93SW5kZXg6IG5vZGUucm93SW5kZXgsIGNvbHVtbjogY29sLCBjb2xJbmRleDogJGluZGV4IH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPCEtLSBDdXN0b20gRGV0YWlsIENvbXBvbmVudCAtLT5cbiAgICAgICAgICAgICBAaWYobm9kZS5sZWFmICYmIG5vZGUuZGV0YWlsQWN0aXZlICYmIG5vZGU/LmRldGFpbFJlbmRlcmVyQ29tcG9uZW50KSB7XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICBvbmVDZWxsUmVuZGVyZXJDb21wb25lbnRcbiAgICAgICAgICAgICAgICAgICAgW2NlbGxSZW5kZXJlckNvbXBvbmVudF09XCJub2RlPy5kZXRhaWxSZW5kZXJlckNvbXBvbmVudFwiXG4gICAgICAgICAgICAgICAgICAgIFtwYXJhbXNdPVwieyBkYXRhOiBub2RlLmRhdGEsIHJvd0luZGV4OiBub2RlLnJvd0luZGV4LCBub2RlOiBub2RlLCBjb250ZXh0OiBjb250ZXh0IH1cIj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgPCEtLSBNYXN0ZXIgRGV0YWlsIEdyaWQgKHRlbXBsYXRlIHByb3ZpZGVkIGJ5IHRoZSBwYXJlbnQgb25lLWdyaWQgdG8gYXZvaWQgYSBjb21waWxlLXRpbWUgaW1wb3J0IGN5Y2xlKSAtLT5cbiAgICAgICAgICAgIEBpZiAobWFzdGVyRGV0YWlsICYmIG5vZGUuZXhwYW5kZWQgJiYgbm9kZT8uZGV0YWlsUm93RGF0YSkge1xuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvbmUtcm93LWRldGFpbC1jb250YWluZXJcIiBbYXR0ci5kYXRhLXJvdy1pZF09XCJub2RlLnJvd0lkICsgJy1kZXRhaWwnXCI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImRldGFpbEdyaWRUZW1wbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyAkaW1wbGljaXQ6IG5vZGUsIG5vZGU6IG5vZGUgfVwiPlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIEBpZiAoIW5vZGVzPy5sZW5ndGgpIHtcbiAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJ3aWR0aDogbWF4LWNvbnRlbnQ7IGJvcmRlci10b3A6IDFweCBzb2xpZCB0cmFuc3BhcmVudDtcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IFtzdHlsZS53aWR0aC5weF09XCJyb3dXaWR0aFwiPjwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICA8L2Nkay12aXJ0dWFsLXNjcm9sbC12aWV3cG9ydD5cblxuICAgIDwhLS0gRHJvcCBpbmRpY2F0b3IuXG4gICAgICAgICBBIGxpbmUgYXQgdGhlIGluc2VydGlvbiBwb2ludCByYXRoZXIgdGhhbiBhIGdhcCBvcGVuZWQgYmV0d2VlbiByb3dzOlxuICAgICAgICAgdGhlIHZpZXdwb3J0IGlzIHZpcnR1YWxpc2VkIGF0IGEgZml4ZWQgaXRlbVNpemUsIHNvIHNoaWZ0aW5nIHJvd3MgYXBhcnRcbiAgICAgICAgIHdvdWxkIGRlc3luY2hyb25pc2UgdGhlIHNjcm9sbGVyIGZyb20gaXRzIG93biBnZW9tZXRyeS4gSXQgaXMgYWxzbyB0aGVcbiAgICAgICAgIGNsZWFyZXIgc2lnbmFsIOKAlCB0aGUgcm93IGxhbmRzIGV4YWN0bHkgd2hlcmUgdGhlIGxpbmUgaXMuXG4gICAgICAgICBQb3NpdGlvbmVkIGFnYWluc3QgdGhlIGJvZHksIHdpdGggdGhlIHZpZXdwb3J0J3Mgc2Nyb2xsIHN1YnRyYWN0ZWQsIHNvXG4gICAgICAgICBpdCBzdGF5cyBwdXQgd2hpbGUgdGhlIGNvbnRlbnQgbW92ZXMgdW5kZXIgaXQgZHVyaW5nIGF1dG8tc2Nyb2xsLiAtLT5cbiAgICBAaWYgKGRyb3BJbmRpY2F0b3JUb3AgIT09IG51bGwpIHtcbiAgICAgICAgPGRpdiBjbGFzcz1cIm9uZS1yb3ctZHJvcC1pbmRpY2F0b3JcIiBhcmlhLWhpZGRlbj1cInRydWVcIlxuICAgICAgICAgICAgIFtzdHlsZS50b3AucHhdPVwiZHJvcEluZGljYXRvclRvcFwiXG4gICAgICAgICAgICAgW3N0eWxlLndpZHRoLnB4XT1cImRyb3BJbmRpY2F0b3JXaWR0aFwiPjwvZGl2PlxuICAgIH1cblxuICAgIDwhLS0gS2V5Ym9hcmQgcmVvcmRlcmluZyBoYXMgbm8gZHJhZyBpbWFnZSB0byB3YXRjaCwgc28gaXQgbmFycmF0ZXMgaW5zdGVhZC5cbiAgICAgICAgIEFzc2VydGl2ZSBiZWNhdXNlIHRoZSBtZXNzYWdlIGlzIHRoZSBvbmx5IGZlZWRiYWNrIHRoYXQgdGhlIHJvdyBtb3ZlZC4gLS0+XG4gICAgPGRpdiBjbGFzcz1cIm9uZS1ncmlkLXZpc3VhbGx5LWhpZGRlblwiIHJvbGU9XCJzdGF0dXNcIiBhcmlhLWxpdmU9XCJhc3NlcnRpdmVcIiBhcmlhLWF0b21pYz1cInRydWVcIj57eyBkcmFnQW5ub3VuY2VtZW50IH19PC9kaXY+XG4gICAgQGlmICghbm9kZXM/Lmxlbmd0aCkge1xuICAgICAgICA8c3BhbiBjbGFzcz1cIm9uZS1ncmlkLWVtcHR5LW1lc3NhZ2VcIiBzdHlsZT1cInBvc2l0aW9uOiBhYnNvbHV0ZTsgdG9wOiA1MCU7IGxlZnQ6IDUwJTsgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgLTUwJSk7XCI+Tm8gUm93cyB0byBTaG93PC9zcGFuPlxuICAgIH1cblxuICAgIEBpZiAocGlubmVkQm90dG9tTm9kZXMubGVuZ3RoKSB7XG4gICAgICAgIDxkaXYgI3Bpbm5lZFZpZXdwb3J0IGNsYXNzPVwib25lLXBpbm5lZC1yb3dzIG9uZS1waW5uZWQtcm93cy1ib3R0b21cIiByb2xlPVwicm93Z3JvdXBcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwicGlubmVkUm93c1wiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7IG5vZGVzOiBwaW5uZWRCb3R0b21Ob2Rlcywgc2lkZTogJ2JvdHRvbScgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8L2Rpdj5cbiAgICB9XG48L2Rpdj5cblxuPCEtLSBQaW5uZWQgcm93cyBhcmUgZGlzcGxheS1vbmx5OiB0aGV5IHJlbmRlciBleGFjdGx5IHdoYXQgYSBkYXRhIGNlbGwgcmVuZGVycyxcbiAgICAgYnV0IGNhcnJ5IG5vbmUgb2YgaXRzIGludGVyYWN0aW9ucy4gQSB0b3RhbHMgcm93IHNob3VsZCBub3Qgb3BlbiBhbiBlZGl0b3JcbiAgICAgb24gZG91YmxlLWNsaWNrIG9yIHN0YXJ0IGEgcmFuZ2Ugc2VsZWN0aW9uIG9uIGRyYWcuIC0tPlxuPG5nLXRlbXBsYXRlICNwaW5uZWRSb3dzIGxldC1ub2Rlcz1cIm5vZGVzXCIgbGV0LXNpZGU9XCJzaWRlXCI+XG4gICAgQGZvciAobm9kZSBvZiBub2RlczsgdHJhY2sgbm9kZS5yb3dJZCkge1xuICAgICAgICA8ZGl2IGNsYXNzPVwib25lLXJvdyBvbmUtcm93LXBpbm5lZFwiXG4gICAgICAgICAgICByb2xlPVwicm93XCJcbiAgICAgICAgICAgIFthdHRyLmFyaWEtcm93aW5kZXhdPVwicGlubmVkUm93QXJpYUluZGV4KG5vZGUsIHNpZGUpXCJcbiAgICAgICAgICAgIFthdHRyLmRhdGEtcm93LWlkXT1cIm5vZGUucm93SWRcIj5cbiAgICAgICAgICAgIEBmb3IgKGNvbHVtbiBvZiBjb2x1bW5EZWZzOyB0cmFjayBjb2x1bW4uZmllbGQpIHtcbiAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwib25lLWNvbHVtblwiXG4gICAgICAgICAgICAgICAgICAgIHJvbGU9XCJncmlkY2VsbFwiXG4gICAgICAgICAgICAgICAgICAgIFthdHRyLmFyaWEtY29saW5kZXhdPVwiJGluZGV4ICsgMVwiXG4gICAgICAgICAgICAgICAgICAgIFthdHRyLmRhdGEtY2VsbC1pZF09XCJub2RlLnJvd0lkIHwgY2VsbEtleTpjb2x1bW4uZmllbGRcIlxuICAgICAgICAgICAgICAgICAgICBbY2xhc3Mub25lLWNvbHVtbi1waW5uZWQtbGVmdF09XCJjb2x1bW4ucGlubmVkID09PSAnbGVmdCdcIlxuICAgICAgICAgICAgICAgICAgICBbY2xhc3Mub25lLWNvbHVtbi1waW5uZWQtcmlnaHRdPVwiY29sdW1uLnBpbm5lZCA9PT0gJ3JpZ2h0J1wiXG4gICAgICAgICAgICAgICAgICAgIFtjbGFzcy5vbmUtY29sdW1uLXBpbm5lZC1lZGdlXT1cImNvbHVtbi5fcGlubmVkRWRnZVwiXG4gICAgICAgICAgICAgICAgICAgIFtzdHlsZS5sZWZ0LnB4XT1cImNvbHVtbi5waW5uZWQgPT09ICdsZWZ0JyA/IGNvbHVtbi5fcGlubmVkT2Zmc2V0IDogbnVsbFwiXG4gICAgICAgICAgICAgICAgICAgIFtzdHlsZS5yaWdodC5weF09XCJjb2x1bW4ucGlubmVkID09PSAncmlnaHQnID8gY29sdW1uLl9waW5uZWRPZmZzZXQgOiBudWxsXCJcbiAgICAgICAgICAgICAgICAgICAgW3N0eWxlLndpZHRoLnB4XT1cImNvbHVtbj8ud2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICBbc3R5bGUubWluLXdpZHRoLnB4XT1cImNvbHVtbj8ubWluV2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICBbc3R5bGUubWF4LXdpZHRoLnB4XT1cImNvbHVtbj8ubWF4V2lkdGhcIj5cblxuICAgICAgICAgICAgICAgICAgICBAaWYgKGNvbHVtbj8uY2VsbFJlbmRlcmVyQ29tcG9uZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25lQ2VsbFJlbmRlcmVyQ29tcG9uZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NlbGxSZW5kZXJlckNvbXBvbmVudF09XCJjb2x1bW4/LmNlbGxSZW5kZXJlckNvbXBvbmVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BhcmFtc109XCJyZW5kZXJlclBhcmFtcyhub2RlLCBjb2x1bW4pXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBAZWxzZSBpZiAoY29sdW1uPy5jZWxsUmVuZGVyZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJ7IHdpZHRoOiBjb2x1bW4ud2lkdGggKyAncHgnLCBwb3NpdGlvbjogJ3JlbGF0aXZlJyB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaW5uZXJIVE1MXT1cIm5vZGUuY2VsbFN0YXRlcyB8IGNlbGxTdGF0ZVJlbmRlcmVyOmNvbHVtbi5maWVsZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm9uZS1jZWxsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuYWxpZ24tY29udGVudC1sZWZ0XT1cImNvbHVtbj8uYWxpZ25Db250ZW50ID09PSAnbGVmdCdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5hbGlnbi1jb250ZW50LWNlbnRlcl09XCJjb2x1bW4/LmFsaWduQ29udGVudCA9PT0gJ2NlbnRlcidcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5hbGlnbi1jb250ZW50LXJpZ2h0XT1cImNvbHVtbj8uYWxpZ25Db250ZW50ID09PSAncmlnaHQnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJjb2xTZXJ2aWNlLnJlc29sdmVDZWxsQ2xhc3MoY29sdW1uLCBjZWxsUGFyYW1zKG5vZGUsIGNvbHVtbikpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJjb2xTZXJ2aWNlLnJlc29sdmVDZWxsU3R5bGUoY29sdW1uLCBjZWxsUGFyYW1zKG5vZGUsIGNvbHVtbikpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm9uZS1jZWxsLXRleHRcIj57eyAobm9kZS5jZWxsU3RhdGVzIHwgY2VsbFN0YXRlUmVuZGVyZXI6Y29sdW1uLmZpZWxkKSB9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgPC9kaXY+XG4gICAgfVxuPC9uZy10ZW1wbGF0ZT5cblxuPCEtLSBNYXN0ZXIgQ29sdW1uIFRlbXBsYXRlICAtLT5cbjxuZy10ZW1wbGF0ZSAjY2VsbFRlbXBsYXRlIGxldC1ub2RlPVwibm9kZVwiIGxldC1yb3dJbmRleD1cInJvd0luZGV4XCIgbGV0LWNvbHVtbj1cImNvbHVtblwiIGxldC1jb2xJbmRleD1cImNvbEluZGV4XCI+XG4gICAgPGRpdlxuICAgICAgICBjbGFzcz1cIm9uZS1jb2x1bW5cIlxuICAgICAgICByb2xlPVwiZ3JpZGNlbGxcIlxuICAgICAgICBbYXR0ci5hcmlhLWNvbGluZGV4XT1cImNvbEluZGV4ICsgMVwiXG4gICAgICAgIFthdHRyLnRhYmluZGV4XT1cImlzQWN0aXZlQ2VsbChub2RlLCBjb2x1bW4pID8gMCA6IC0xXCJcbiAgICAgICAgW2NsYXNzLm9uZS1jZWxsLWFjdGl2ZV09XCJpc0FjdGl2ZUNlbGwobm9kZSwgY29sdW1uKVwiXG4gICAgICAgIChmb2N1cyk9XCJvbkNlbGxGb2N1cyhub2RlLCBjb2x1bW4pXCJcbiAgICAgICAgW2F0dHIuZGF0YS1jZWxsLWlkXT1cIm5vZGUucm93SWQgfCBjZWxsS2V5OmNvbHVtbi5maWVsZFwiXG4gICAgICAgIFtjbGFzcy5vbmUtY29sdW1uLXBpbm5lZC1sZWZ0XT1cImNvbHVtbi5waW5uZWQgPT09ICdsZWZ0J1wiXG4gICAgICAgIFtjbGFzcy5vbmUtY29sdW1uLXBpbm5lZC1yaWdodF09XCJjb2x1bW4ucGlubmVkID09PSAncmlnaHQnXCJcbiAgICAgICAgW2NsYXNzLm9uZS1jb2x1bW4tcGlubmVkLWVkZ2VdPVwiY29sdW1uLl9waW5uZWRFZGdlXCJcbiAgICAgICAgW3N0eWxlLmxlZnQucHhdPVwiY29sdW1uLnBpbm5lZCA9PT0gJ2xlZnQnID8gY29sdW1uLl9waW5uZWRPZmZzZXQgOiBudWxsXCJcbiAgICAgICAgW3N0eWxlLnJpZ2h0LnB4XT1cImNvbHVtbi5waW5uZWQgPT09ICdyaWdodCcgPyBjb2x1bW4uX3Bpbm5lZE9mZnNldCA6IG51bGxcIlxuICAgICAgICBbc3R5bGUud2lkdGgucHhdPVwiY29sdW1uPy53aWR0aFwiXG4gICAgICAgIFtzdHlsZS5taW4td2lkdGgucHhdPVwiY29sdW1uPy5taW5XaWR0aFwiXG4gICAgICAgIFtzdHlsZS5tYXgtd2lkdGgucHhdPVwiY29sdW1uPy5tYXhXaWR0aFwiXG4gICAgICAgIFtjbGFzcy5vbmUtY29sdW1uLWJvcmRlci10b3BdPVwibWFzdGVyRGV0YWlsICYmIG5vZGVzPy5sZW5ndGggPiAwICYmIG5vZGVzW25vZGUucm93SW5kZXggLSAxXT8uZXhwYW5kZWRcIlxuICAgICAgICBbY2xhc3Mub25lLWNlbGwtc2VsZWN0ZWRdPVwic2VsZWN0ZWRDZWxscyB8IGNlbGxTZWxlY3RlZDpub2RlLnJvd0lkOmNvbHVtbi5maWVsZFwiXG4gICAgICAgIFtjbGFzcy5vbmUtY2VsbC1pbnZhbGlkXT1cIm5vZGUuY2VsbFN0YXRlcyB8IGNlbGxJbnZhbGlkOm5vZGUuZGF0YVtjb2x1bW4uZmllbGRdOmNvbHVtbjpub2RlOmFsbG93ZWRFZGl0OnN1Ym1pdHRlZFwiXG4gICAgICAgIChkYmxjbGljayk9XCJzdGFydEVkaXQoJGV2ZW50LCBub2RlLCBjb2x1bW4pXCJcbiAgICAgICAgKG1vdXNlZG93bik9XCJzdGFydFNlbGVjdGlvbihub2RlLnJvd0lkLCBjb2x1bW4uZmllbGQpXCJcbiAgICAgICAgKG1vdXNlZW50ZXIpPVwiZXh0ZW5kU2VsZWN0aW9uKG5vZGUucm93SWQsIGNvbHVtbi5maWVsZClcIlxuICAgICAgICAobW91c2V1cCk9XCJlbmRTZWxlY3Rpb24oKVwiPlxuXG4gICAgICAgIDwhLS0gT25lIEdyaWQgQ2VsbCBPcHRpb24gLS0+XG4gICAgICAgIEBpZiAobm9kZS5jZWxsT3B0aW9uc1tjb2x1bW4uZmllbGRdKSB7XG4gICAgICAgICAgICA8b25lLWdyaWQtY2VsbC1vcHRpb24tbWVudVxuICAgICAgICAgICAgICAgICNjb250ZXh0T3B0aW9uTWVudVJlZlxuICAgICAgICAgICAgICAgIFtub2RlXT1cIm5vZGVcIlxuICAgICAgICAgICAgICAgIFtjb2x1bW5dPVwiY29sdW1uXCJcbiAgICAgICAgICAgICAgICBbb3B0aW9uc109XCJjb2x1bW4uY2VsbE9wdGlvbk1lbnVcIlxuICAgICAgICAgICAgICAgIChjZWxsT3B0aW9uTWVudVNlbGVjdCk9XCJjZWxsT3B0aW9uTWVudVNlbGVjdGVkKCRldmVudClcIlxuICAgICAgICAgICAgICAgIChjZWxsT3B0aW9uTWVudUNsb3NlKT1cImNlbGxPcHRpb25NZW51Q2xvc2VkKClcIi8+XG4gICAgICAgIH1cblxuICAgICAgICA8IS0tIEdyaWQgQ2VsbCBUZW1wbGF0ZSAtLT5cbiAgICAgICAgQGlmKGNvbHVtbj8uY2VsbFJlbmRlcmVyQ29tcG9uZW50KSB7XG4gICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgb25lQ2VsbFJlbmRlcmVyQ29tcG9uZW50XG4gICAgICAgICAgICAgICAgW2NlbGxSZW5kZXJlckNvbXBvbmVudF09XCJjb2x1bW4/LmNlbGxSZW5kZXJlckNvbXBvbmVudFwiXG4gICAgICAgICAgICAgICAgW3BhcmFtc109XCJyZW5kZXJlclBhcmFtcyhub2RlLCBjb2x1bW4pXCI+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgfVxuICAgICAgICBAZWxzZSBpZiAobm9kZS5lZGl0aW5nW2NvbHVtbi5maWVsZF0pIHtcbiAgICAgICAgICAgIEBpZiAoY29sdW1uPy5jZWxsUmVuZGVyZXJQYXJhbXM/LmlucHV0VHlwZSA9PT0gJ3NlbGVjdCcpIHtcbiAgICAgICAgICAgICAgICA8IS0tIENlbGwgRWRpdGluZyBTZWxlY3QuIENvbW1pdHMgb24gY2hhbmdlIOKAlCBwaWNraW5nIGFuIG9wdGlvblxuICAgICAgICAgICAgICAgICAgICAgaXMgdGhlIHdob2xlIGVkaXQg4oCUIHdpdGggYmx1ciBhcyB0aGUga2V5Ym9hcmQgZmFsbGJhY2suIC0tPlxuICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJvbmUtY2VsbC1pbnB1dFwiXG4gICAgICAgICAgICAgICAgICAgIG5hbWU9XCJ7eyBub2RlLnJvd0lkICsgJycgKyBjb2x1bW4uZmllbGQgfX1cIlxuICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInN0b3BFZGl0U2VsZWN0KG5vZGUsIGNvbHVtbiwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgIChibHVyKT1cInN0b3BFZGl0U2VsZWN0KG5vZGUsIGNvbHVtbiwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgIChrZXlkb3duLmVzYyk9XCJjYW5jZWxFZGl0KG5vZGUsIGNvbHVtbilcIj5cbiAgICAgICAgICAgICAgICAgICAgQGZvciAob3B0aW9uIG9mIGNvbHVtbj8uY2VsbFJlbmRlcmVyUGFyYW1zPy5zZWxlY3RPcHRpb25zID8/IFtdOyB0cmFjayAkaW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW3NlbGVjdGVkXT1cIm9wdGlvbi52YWx1ZSA9PT0gbm9kZS5kYXRhW2NvbHVtbi5maWVsZF1cIj57eyBvcHRpb24ubGFiZWwgfX08L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGVsc2Uge1xuICAgICAgICAgICAgICAgIDwhLS0gQ2VsbCBFZGl0aW5nIElucHV0IC0tPlxuICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cIm9uZS1jZWxsLWlucHV0XCJcbiAgICAgICAgICAgICAgICAgICAgbmFtZT1cInt7IG5vZGUucm93SWQgKyAnJyArIGNvbHVtbi5maWVsZCB9fVwiXG4gICAgICAgICAgICAgICAgICAgIG9uZUNlbGxJbnB1dFZhbGlkYXRvclxuICAgICAgICAgICAgICAgICAgICBbdmFsaWRhdGlvblR5cGVdPVwiY29sdW1uPy5jZWxsUmVuZGVyZXJQYXJhbXM/LmlucHV0VHlwZSA9PT0gJ251bWJlcicgPyAnbnVtYmVyJyA6ICdub25lJ1wiXG4gICAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJjb2x1bW4/LmNlbGxSZW5kZXJlclBhcmFtcz8ucGxhY2Vob2xkZXJcIlxuICAgICAgICAgICAgICAgICAgICBbdHlwZV09XCJjb2x1bW4/LmNlbGxSZW5kZXJlclBhcmFtcz8uaW5wdXRUeXBlID09PSAnbnVtYmVyJyA/ICd0ZXh0JyA6IGNvbHVtbj8uY2VsbFJlbmRlcmVyUGFyYW1zPy5pbnB1dFR5cGVcIlxuICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwibm9kZT8uZGF0YVtjb2x1bW4/LmZpZWxkXVwiXG4gICAgICAgICAgICAgICAgICAgIFttYXhMZW5ndGhdPVwiMjUwXCJcbiAgICAgICAgICAgICAgICAgICAgKGJsdXIpPVwic3RvcEVkaXQobm9kZSwgY29sdW1uLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgKGtleWRvd24uZW50ZXIpPVwic3RvcEVkaXQobm9kZSwgY29sdW1uLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgKGtleWRvd24uZXNjKT1cImNhbmNlbEVkaXQobm9kZSwgY29sdW1uKVwiXG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBAZWxzZSBpZiAoY29sdW1uPy5jZWxsUmVuZGVyZXIpIHtcbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJ7IHdpZHRoOiBjb2x1bW4ud2lkdGggKyAncHgnICwgcG9zaXRpb246ICdyZWxhdGl2ZScgfVwiXG4gICAgICAgICAgICAgICAgW2lubmVySFRNTF09XCJub2RlLmNlbGxTdGF0ZXMgfCBjZWxsU3RhdGVSZW5kZXJlcjpjb2x1bW4uZmllbGRcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5lZGl0YWJsZS1hY3RpdmVdPVwibm9kZS5jZWxsU3RhdGVzIHwgY2VsbEVkaXRhYmxlOmNvbHVtbjpub2RlOmNlbGxTZXJ2aWNlLmVkaXRhYmxlRm46Y2VsbFNlcnZpY2UudXBkYXRhYmxlRm46YWxsb3dlZEVkaXRcIj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICAgIEBlbHNlIHtcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvbmUtY2VsbFwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmFsaWduLWNvbnRlbnQtbGVmdF09XCJjb2x1bW4/LmFsaWduQ29udGVudCA9PT0gJ2xlZnQnXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MuYWxpZ24tY29udGVudC1jZW50ZXJdPVwiY29sdW1uPy5hbGlnbkNvbnRlbnQgPT09ICdjZW50ZXInXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MuYWxpZ24tY29udGVudC1yaWdodF09XCJjb2x1bW4/LmFsaWduQ29udGVudCA9PT0gJ3JpZ2h0J1wiXG4gICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiY29sU2VydmljZS5yZXNvbHZlQ2VsbENsYXNzKGNvbHVtbiwgY2VsbFBhcmFtcyhub2RlLCBjb2x1bW4pKVwiXG4gICAgICAgICAgICAgICAgW25nU3R5bGVdPVwiY29sU2VydmljZS5yZXNvbHZlQ2VsbFN0eWxlKGNvbHVtbiwgY2VsbFBhcmFtcyhub2RlLCBjb2x1bW4pKVwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLnBhZGRpbmctbGVmdC5weF09XCJjb2x1bW4uYXV0b0dyb3VwRmllbGQgJiYgbm9kZS5sZXZlbCB8IGNlbGxMZXZlbFBhZGRpbmc6MjRcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5vbmUtY2VsbC1hbGxvd2VkLWVkaXQtYWN0aXZlXT1cIm5vZGUuY2VsbFN0YXRlcyB8IGNlbGxFZGl0YWJsZTpjb2x1bW46bm9kZTpjZWxsU2VydmljZS5lZGl0YWJsZUZuOmNlbGxTZXJ2aWNlLnVwZGF0YWJsZUZuOmFsbG93ZWRFZGl0XCI+XG5cbiAgICAgICAgICAgICAgICA8IS0tIFJvdyBEcmFnIEhhbmRsZSAtLT5cbiAgICAgICAgICAgICAgICBAaWYgKGNlbGxTZXJ2aWNlLnJvd0RyYWdGbihjb2x1bW4sIG5vZGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIDxvbmUtZ3JpZC1yb3ctZHJhZy1oYW5kbGVcbiAgICAgICAgICAgICAgICAgICAgICAgIFtub2RlXT1cIm5vZGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW3N1cHByZXNzZWRSZWFzb25dPVwicm93RHJhZ1N1cHByZXNzZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGRyYWdFbmQpPVwib25Sb3dEcmFnRW5kKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIDwhLS0gQ2VsbCBDaGVja2JveCBTZWxlY3Rpb24gLS0+XG4gICAgICAgICAgICAgICAgQGlmIChjb2x1bW4/LmNoZWNrYm94U2VsZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIDxvbmUtZ3JpZC1jaGVja2JveFxuICAgICAgICAgICAgICAgICAgICAgICAgW25vZGVdPVwibm9kZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbYWxsb3dlZEVkaXRdPVwiYWxsb3dlZEVkaXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2FwaV09XCJhcGlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKG9uUm93U2VsZWN0aW9uKT1cImludm9rZVJvd0FjdGlvblNlbGVjdGlvbigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICA8IS0tIEV4cGFuZCAmIENvbGxhcHNlIEljb24gLS0+XG4gICAgICAgICAgICAgICAgQGlmICgoKG5vZGU/Lmdyb3VwIHx8IGRldGFpbFJlbmRlcmVyQ29tcG9uZW50KSAmJiBjb2x1bW4/LmF1dG9Hcm91cEZpZWxkKSB8fCAobWFzdGVyRGV0YWlsICYmIG5vZGU/LmV4cGFuZGFibGUgJiYgZ3JpZFR5cGUgPT09ICdtYXN0ZXInICYmIGNvbHVtbj8ubWFzdGVyR3JvdXBGaWVsZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgPG9uZS1ncmlkLWNlbGwtZ3JvdXAtcmVuZGVyZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtub2RlXT1cIm5vZGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW21hc3RlckRldGFpbF09XCJtYXN0ZXJEZXRhaWxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2RldGFpbENlbGxSZW5kZXJlclBhcmFtc109XCJkZXRhaWxDZWxsUmVuZGVyZXJQYXJhbXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2RldGFpbFJlbmRlcmVyQ29tcG9uZW50XT1cImRldGFpbFJlbmRlcmVyQ29tcG9uZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChleHBhbnNpb25DaGFuZ2VkKT1cImludm9rZUV4cGFuc2lvbkNoYW5nZWRDbGljaygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBAaWYoY29sdW1uPy5jZWxsUmVuZGVyZXJDb21wb25lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgb25lQ2VsbFJlbmRlcmVyQ29tcG9uZW50XG4gICAgICAgICAgICAgICAgICAgICAgICBbY2VsbFJlbmRlcmVyQ29tcG9uZW50XT1cImNvbHVtbj8uY2VsbFJlbmRlcmVyQ29tcG9uZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtwYXJhbXNdPVwicmVuZGVyZXJQYXJhbXMobm9kZSwgY29sdW1uKVwiPlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICA8IS0tIENlbGwgVmFsdWUgT1IgUGxhY2Vob2xkZXIgLS0+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgb25lQ2VsbFRleHRFeHBhbmQgY2xhc3M9XCJvbmUtY2VsbC10ZXh0XCIgW2NsYXNzLm9uZS1jZWxsLXBsYWNlaG9sZGVyXT1cIm5vZGUuY2VsbFN0YXRlc1tjb2x1bW4uZmllbGRdPy50eXBlID09PSAncGxhY2Vob2xkZXInXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICB7eyAobm9kZS5jZWxsU3RhdGVzIHwgY2VsbFN0YXRlUmVuZGVyZXI6Y29sdW1uLmZpZWxkKSB9fVxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICA8IS0tIENlbGwgQWN0aW9uIEJ1dHRvbnMgLS0+XG4gICAgICAgICAgICAgICAgQGlmIChjb2x1bW4uY2VsbFJlbmRlcmVyUGFyYW1zIHwgY2VsbEFjdGlvbkJ1dHRvbkVuYWJsZSkge1xuICAgICAgICAgICAgICAgICAgICA8b25lLWdyaWQtcm93LWFjdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgW25nU3R5bGVdPVwieyBtYXJnaW5MZWZ0OiAnYXV0bycgfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbY29sdW1uXT1cImNvbHVtblwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbm9kZV09XCJub2RlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFthbGxvd2VkRWRpdF09XCJhbGxvd2VkRWRpdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbWFzdGVyTm9kZV09XCJtYXN0ZXJOb2RlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFttYXN0ZXJEZXRhaWxdPVwibWFzdGVyRGV0YWlsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtncmlkVHlwZV09XCJncmlkVHlwZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbY29udGV4dF09XCJjb250ZXh0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjZWxsUmVuZGVyZXJQYXJhbXNdPVwiY29sdW1uPy5jZWxsUmVuZGVyZXJQYXJhbXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKG9uUm93R290b0RldGFpbCk9XCJpbnZva2VSb3dBY3Rpb25Hb3RvRGV0YWlsKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKG9uUm93QWRkTmV3KT1cImludm9rZVJvd0FjdGlvbkFkZE5ldygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChvblJvd1ZpZXcpPVwiaW52b2tlUm93QWN0aW9uVmlldygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChvblJvd0xvY2F0aW9uKT1cImludm9rZVJvd0FjdGlvbkxvY2F0aW9uKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKG9uUm93RG9jdW1lbnQpPVwiaW52b2tlUm93QWN0aW9uRG9jdW1lbnQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAob25Sb3dDb3B5KT1cImludm9rZVJvd0FjdGlvbkNvcHkoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAob25Sb3dEZWxldGUpPVwiaW52b2tlUm93QWN0aW9uRGVsZXRlKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKG9uUm93R290b0xpc3QpPVwiaW52b2tlUm93QWN0aW9uR290b0xpc3QoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAob25Sb3dFZGl0KT1cImludm9rZVJvd0FjdGlvbkVkaXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAob25Sb3dQcmludCk9XCJpbnZva2VSb3dBY3Rpb25QcmludCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChvblJvd0hpc3RvcnkpPVwiaW52b2tlUm93QWN0aW9uSGlzdG9yeSgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChvblJvd09wdGlvbik9XCJpbnZva2VSb3dBY3Rpb25PcHRpb24oJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAob25Sb3dMYW5ndWFnZSk9XCJpbnZva2VSb3dBY3Rpb25MYW5ndWFnZSgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChvblJvd0NlbGxPcHRpb24pPVwiaW52b2tlUm93QWN0aW9uQ2VsbE9wdGlvbigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuICAgIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==