@one-grid-core/angular 0.1.0-beta.5 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +49 -4
- package/esm2022/lib/components/one-grid/one-grid.component.mjs +67 -16
- package/esm2022/lib/components/one-grid-body/one-grid-body.component.mjs +282 -30
- package/esm2022/lib/components/one-grid-cell-group-renderer/one-grid-cell-group-renderer.component.mjs +10 -7
- package/esm2022/lib/components/one-grid-cell-option-menu/one-grid-cell-option-menu.component.mjs +60 -4
- package/esm2022/lib/components/one-grid-checkbox-header/one-grid-checkbox-header.component.mjs +14 -5
- package/esm2022/lib/components/one-grid-header/one-grid-header.component.mjs +50 -13
- package/esm2022/lib/components/one-grid-pagination/one-grid-pagination.component.mjs +39 -15
- package/esm2022/lib/components/one-grid-row-action/one-grid-row-action.component.mjs +54 -8
- package/esm2022/lib/components/one-grid-row-drag-handle/one-grid-row-drag-handle.component.mjs +110 -0
- package/esm2022/lib/core/directives/one-cell-renderer-component.directive.mjs +9 -2
- package/esm2022/lib/core/directives/one-cell-text-expand.directive.mjs +33 -51
- package/esm2022/lib/core/instants/one-grid-api.class.mjs +429 -166
- package/esm2022/lib/core/instants/one-row-node.class.mjs +103 -37
- package/esm2022/lib/core/models/one-column-def-types.model.mjs +1 -1
- package/esm2022/lib/core/models/one-event-types.model.mjs +1 -1
- package/esm2022/lib/core/models/one-grid-types.model.mjs +1 -1
- package/esm2022/lib/core/models/one-row-drag.model.mjs +2 -0
- package/esm2022/lib/core/models/one-row.model.mjs +1 -1
- package/esm2022/lib/core/models/one-tree-data.model.mjs +1 -1
- package/esm2022/lib/core/models/one-validation.model.mjs +1 -1
- package/esm2022/lib/core/pipes/cell-field-value-empty.pipe.mjs +8 -3
- package/esm2022/lib/core/pipes/column-sort-state.pipe.mjs +3 -1
- package/esm2022/lib/core/services/og-column.service.mjs +120 -13
- package/esm2022/lib/core/services/one-grid-cell.service.mjs +123 -20
- package/esm2022/lib/core/services/one-grid-row-drag.service.mjs +351 -0
- package/esm2022/lib/core/services/one-grid-selection.service.mjs +19 -6
- package/esm2022/lib/helpers/one-column-def.helper.mjs +27 -2
- package/esm2022/lib/helpers/one-filter.helper.mjs +71 -12
- package/esm2022/lib/helpers/one-validation.helper.mjs +7 -2
- package/esm2022/lib/index.mjs +8 -1
- package/esm2022/lib/one-grid.module.mjs +7 -16
- package/fesm2022/one-grid-core-angular.mjs +2046 -503
- package/fesm2022/one-grid-core-angular.mjs.map +1 -1
- package/lib/components/one-grid/one-grid.component.d.ts +16 -1
- package/lib/components/one-grid-body/one-grid-body.component.d.ts +132 -5
- package/lib/components/one-grid-cell-group-renderer/one-grid-cell-group-renderer.component.d.ts +6 -1
- package/lib/components/one-grid-cell-option-menu/one-grid-cell-option-menu.component.d.ts +19 -2
- package/lib/components/one-grid-checkbox-header/one-grid-checkbox-header.component.d.ts +5 -2
- package/lib/components/one-grid-header/one-grid-header.component.d.ts +15 -7
- package/lib/components/one-grid-pagination/one-grid-pagination.component.d.ts +24 -5
- package/lib/components/one-grid-row-action/one-grid-row-action.component.d.ts +44 -0
- package/lib/components/one-grid-row-drag-handle/one-grid-row-drag-handle.component.d.ts +39 -0
- package/lib/core/directives/one-cell-text-expand.directive.d.ts +21 -9
- package/lib/core/instants/one-grid-api.class.d.ts +212 -26
- package/lib/core/instants/one-row-node.class.d.ts +67 -14
- package/lib/core/models/one-column-def-types.model.d.ts +89 -15
- package/lib/core/models/one-event-types.model.d.ts +24 -1
- package/lib/core/models/one-grid-types.model.d.ts +36 -1
- package/lib/core/models/one-row-drag.model.d.ts +44 -0
- package/lib/core/models/one-row.model.d.ts +0 -5
- package/lib/core/models/one-tree-data.model.d.ts +13 -0
- package/lib/core/models/one-validation.model.d.ts +12 -2
- package/lib/core/pipes/column-sort-state.pipe.d.ts +1 -1
- package/lib/core/services/og-column.service.d.ts +44 -3
- package/lib/core/services/one-grid-cell.service.d.ts +52 -4
- package/lib/core/services/one-grid-row-drag.service.d.ts +113 -0
- package/lib/core/services/one-grid-selection.service.d.ts +9 -0
- package/lib/helpers/one-column-def.helper.d.ts +19 -1
- package/lib/helpers/one-filter.helper.d.ts +29 -4
- package/lib/index.d.ts +7 -0
- package/lib/one-grid.module.d.ts +17 -19
- package/package.json +1 -2
- package/scss/_one-grid.scss +389 -17
- package/esm2022/lib/core/pipes/cell-disable-resolver.pipe.mjs +0 -26
- package/lib/core/pipes/cell-disable-resolver.pipe.d.ts +0 -9
|
@@ -1,33 +1,37 @@
|
|
|
1
|
-
import { ChangeDetectionStrategy, Component, EventEmitter, HostListener, Input, Output, ViewChild } from '@angular/core';
|
|
1
|
+
import { ChangeDetectionStrategy, Component, EventEmitter, HostListener, Input, Output, ViewChild, ViewChildren } from '@angular/core';
|
|
2
2
|
import { Subscription } from 'rxjs';
|
|
3
3
|
import { CellEditablePipe } from '../../core/pipes/cell-editable.pipe';
|
|
4
4
|
import { getCellKey, getFieldValue } from '../../helpers/one-cell.helper';
|
|
5
5
|
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
|
|
6
|
+
import { resolveColumnWidth } from '../../helpers/one-column-def.helper';
|
|
6
7
|
import * as i0 from "@angular/core";
|
|
7
8
|
import * as i1 from "../../core/services/og-column.service";
|
|
8
9
|
import * as i2 from "../../core/services/one-grid-cell.service";
|
|
9
10
|
import * as i3 from "../../core/services/one-grid-event.service";
|
|
10
|
-
import * as i4 from "
|
|
11
|
-
import * as i5 from "@angular/
|
|
12
|
-
import * as i6 from "
|
|
13
|
-
import * as i7 from "../one-grid-
|
|
14
|
-
import * as i8 from "../one-grid-
|
|
15
|
-
import * as i9 from "
|
|
16
|
-
import * as i10 from "../../core/directives/one-cell-
|
|
17
|
-
import * as i11 from "../../core/directives/one-cell-
|
|
18
|
-
import * as i12 from "
|
|
19
|
-
import * as i13 from "
|
|
20
|
-
import * as i14 from "
|
|
21
|
-
import * as i15 from "../../core/pipes/cell-
|
|
22
|
-
import * as i16 from "../../core/pipes/cell-
|
|
23
|
-
import * as i17 from "../../core/pipes/cell-
|
|
24
|
-
import * as i18 from "../../core/pipes/cell-
|
|
25
|
-
import * as i19 from "../../core/pipes/cell-
|
|
11
|
+
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";
|
|
26
29
|
export class OneGridBodyComponent {
|
|
27
|
-
constructor(colService, cellService, eventService, cdr) {
|
|
30
|
+
constructor(colService, cellService, eventService, rowDragService, cdr) {
|
|
28
31
|
this.colService = colService;
|
|
29
32
|
this.cellService = cellService;
|
|
30
33
|
this.eventService = eventService;
|
|
34
|
+
this.rowDragService = rowDragService;
|
|
31
35
|
this.cdr = cdr;
|
|
32
36
|
this.rowData = [];
|
|
33
37
|
this.pagination = false;
|
|
@@ -35,6 +39,14 @@ export class OneGridBodyComponent {
|
|
|
35
39
|
this.enableGroupColumnDefs = false;
|
|
36
40
|
this.submitted = false;
|
|
37
41
|
this.context = null;
|
|
42
|
+
/**
|
|
43
|
+
* Pinned rows are bound only so the component re-renders when they change;
|
|
44
|
+
* the nodes themselves come from the API, which owns them.
|
|
45
|
+
*/
|
|
46
|
+
this.pinnedTopRowData = [];
|
|
47
|
+
this.pinnedBottomRowData = [];
|
|
48
|
+
this.pinnedTopNodes = [];
|
|
49
|
+
this.pinnedBottomNodes = [];
|
|
38
50
|
this.columnDefs = [];
|
|
39
51
|
this.cellRenderer = false;
|
|
40
52
|
/**
|
|
@@ -75,11 +87,19 @@ export class OneGridBodyComponent {
|
|
|
75
87
|
this.expansionChanged = new EventEmitter();
|
|
76
88
|
this.bodyScroll = new EventEmitter();
|
|
77
89
|
this.cellOptionSelect = new EventEmitter();
|
|
90
|
+
this.rowDragEnd = new EventEmitter();
|
|
78
91
|
/**
|
|
79
92
|
* Selection Range Variables
|
|
80
93
|
*/
|
|
81
94
|
this.rowWidth = 0;
|
|
82
95
|
this.nodes = [];
|
|
96
|
+
/**
|
|
97
|
+
* Row drag state, mirrored from the service so the template can read it
|
|
98
|
+
* synchronously. `null` whenever no drag is in flight.
|
|
99
|
+
*/
|
|
100
|
+
this.dragState = null;
|
|
101
|
+
this.dragAnnouncement = '';
|
|
102
|
+
this.rowDragSuppressed = null;
|
|
83
103
|
this.selectedCells = new Set();
|
|
84
104
|
this.isMouseDown = false;
|
|
85
105
|
this.startCell = null;
|
|
@@ -107,6 +127,40 @@ export class OneGridBodyComponent {
|
|
|
107
127
|
this.itemSize = 30;
|
|
108
128
|
this.minBufferPx = 200;
|
|
109
129
|
this.maxBufferPx = 400;
|
|
130
|
+
/**
|
|
131
|
+
* Virtual Scroll Properties
|
|
132
|
+
*
|
|
133
|
+
* The buffer scales with the row count so small grids render in one pass, but
|
|
134
|
+
* it is capped: `itemSize * items * 1.5` is 1.5x the *total* content height,
|
|
135
|
+
* and CdkFixedSizeVirtualScroll expands its rendered range until the buffer is
|
|
136
|
+
* satisfied. Uncapped, that makes the viewport materialise every row and
|
|
137
|
+
* virtual scrolling stops doing anything at all (100k rows locked the tab).
|
|
138
|
+
* MAX_BUFFER_PX keeps roughly twenty rows of overscan either side instead.
|
|
139
|
+
*/
|
|
140
|
+
this.MAX_BUFFER_PX = 600;
|
|
141
|
+
/**
|
|
142
|
+
* Where to paint the drop indicator, in pixels from the top of the body.
|
|
143
|
+
*
|
|
144
|
+
* `insertAt` is a boundary, so the line sits at row-height times the number
|
|
145
|
+
* of rows above it — in content space. The indicator is a sibling of the
|
|
146
|
+
* viewport rather than a child, because anything inside it either scrolls
|
|
147
|
+
* away with the transformed content wrapper or ignores the scroll entirely,
|
|
148
|
+
* so the viewport's own scroll offset and its position within the body are
|
|
149
|
+
* both subtracted back out here.
|
|
150
|
+
*
|
|
151
|
+
* A field rather than a getter: it is read from the template on every change
|
|
152
|
+
* detection pass, and it only actually moves when the drag state or the
|
|
153
|
+
* scroll position does.
|
|
154
|
+
*/
|
|
155
|
+
this.dropIndicatorTop = null;
|
|
156
|
+
/**
|
|
157
|
+
* How wide the line is drawn. Rows are `width: fit-content`, so they are
|
|
158
|
+
* often narrower than the viewport — a full-bleed line would hang past the
|
|
159
|
+
* last column into empty space and read as part of the frame rather than the
|
|
160
|
+
* rows. This is the visible extent of the row content, which also shrinks
|
|
161
|
+
* correctly as the grid is scrolled sideways.
|
|
162
|
+
*/
|
|
163
|
+
this.dropIndicatorWidth = 0;
|
|
110
164
|
}
|
|
111
165
|
ngOnInit() {
|
|
112
166
|
/**
|
|
@@ -115,13 +169,30 @@ export class OneGridBodyComponent {
|
|
|
115
169
|
this.subscriptions.add(this.gridCopy$.subscribe((event) => {
|
|
116
170
|
this.onGridCopy(event);
|
|
117
171
|
}));
|
|
172
|
+
/**
|
|
173
|
+
* Row drag
|
|
174
|
+
*
|
|
175
|
+
* The service owns the gesture; the body only renders it and lends it the
|
|
176
|
+
* viewport, the row height and a way to apply a move. The suppression
|
|
177
|
+
* reason is re-read on every event that could change the order, so the
|
|
178
|
+
* handle disables itself the moment a sort or filter is applied.
|
|
179
|
+
*/
|
|
180
|
+
this.subscriptions.add(this.rowDragService.state$.subscribe((state) => {
|
|
181
|
+
this.dragState = state;
|
|
182
|
+
this.updateDropIndicator();
|
|
183
|
+
this.cdr.markForCheck();
|
|
184
|
+
}));
|
|
185
|
+
this.subscriptions.add(this.rowDragService.announcement$.subscribe((message) => {
|
|
186
|
+
this.dragAnnouncement = message;
|
|
187
|
+
this.cdr.markForCheck();
|
|
188
|
+
}));
|
|
118
189
|
/**
|
|
119
190
|
* Listen Column Changed Event
|
|
120
191
|
*/
|
|
121
192
|
this.subscriptions.add(this.eventService.addEventListener('columnChanged', (payload) => {
|
|
122
193
|
this.columnDefs = [...payload.columns];
|
|
123
194
|
this.cellRenderer = this.columnDefs.some(col => col.cellRendererComponent);
|
|
124
|
-
this.rowWidth = this.columnDefs.reduce((sum, col) => sum + (col
|
|
195
|
+
this.rowWidth = this.columnDefs.reduce((sum, col) => sum + resolveColumnWidth(col), 0);
|
|
125
196
|
this.cdr.markForCheck();
|
|
126
197
|
}));
|
|
127
198
|
/**
|
|
@@ -137,7 +208,9 @@ export class OneGridBodyComponent {
|
|
|
137
208
|
if (node.leaf && this.detailRendererComponent) {
|
|
138
209
|
node.detailRendererComponent = this.detailRendererComponent;
|
|
139
210
|
}
|
|
140
|
-
|
|
211
|
+
// Detail rows can still be in flight when a row is expanded, and
|
|
212
|
+
// spreading null throws. Nothing to re-seed until they arrive.
|
|
213
|
+
if (node.expanded && node.detailRowData) {
|
|
141
214
|
this.api.setDetailRowData(node, [...node.detailRowData]);
|
|
142
215
|
}
|
|
143
216
|
return node;
|
|
@@ -146,14 +219,50 @@ export class OneGridBodyComponent {
|
|
|
146
219
|
else {
|
|
147
220
|
this.nodes = nodes;
|
|
148
221
|
}
|
|
222
|
+
this.refreshRowDragSuppressed();
|
|
149
223
|
this.cdr.markForCheck();
|
|
150
224
|
});
|
|
151
225
|
}));
|
|
226
|
+
/**
|
|
227
|
+
* Listen Pinned Row Data Changed Event
|
|
228
|
+
*/
|
|
229
|
+
this.subscriptions.add(this.eventService.addEventListener('pinnedRowDataChanged', ({ side, nodes }) => {
|
|
230
|
+
if (side === 'top') {
|
|
231
|
+
this.pinnedTopNodes = nodes;
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
this.pinnedBottomNodes = nodes;
|
|
235
|
+
}
|
|
236
|
+
this.cdr.markForCheck();
|
|
237
|
+
}));
|
|
152
238
|
/**
|
|
153
239
|
* Listen Sort Changed Event
|
|
154
240
|
*/
|
|
155
241
|
this.subscriptions.add(this.eventService.addEventListener('sortChanged', ({ nodes }) => {
|
|
156
242
|
this.nodes = nodes;
|
|
243
|
+
// Sorting takes ownership of the order away from the user, so the handles
|
|
244
|
+
// have to disable in the same frame the rows re-sort.
|
|
245
|
+
this.refreshRowDragSuppressed();
|
|
246
|
+
this.cdr.markForCheck();
|
|
247
|
+
}));
|
|
248
|
+
/**
|
|
249
|
+
* Listen Row Order Changed Event
|
|
250
|
+
*
|
|
251
|
+
* Deliberately not folded into `rowDataChanged`: that path defers a frame
|
|
252
|
+
* and re-seeds detail rows, which is right for a data load and far too much
|
|
253
|
+
* for a move. A reorder is the same nodes in a different order.
|
|
254
|
+
*/
|
|
255
|
+
this.subscriptions.add(this.eventService.addEventListener('rowOrderChanged', ({ nodes }) => {
|
|
256
|
+
this.nodes = [...nodes];
|
|
257
|
+
this.cdr.markForCheck();
|
|
258
|
+
}));
|
|
259
|
+
/**
|
|
260
|
+
* Listen Cell State Changed Event
|
|
261
|
+
*
|
|
262
|
+
* The body renders OnPush, so regenerating a row's cell state is invisible
|
|
263
|
+
* until something marks the body dirty. This is that something.
|
|
264
|
+
*/
|
|
265
|
+
this.subscriptions.add(this.eventService.addEventListener('cellStateChanged', () => {
|
|
157
266
|
this.cdr.markForCheck();
|
|
158
267
|
}));
|
|
159
268
|
/**
|
|
@@ -172,9 +281,33 @@ export class OneGridBodyComponent {
|
|
|
172
281
|
const scrollLeft = event.target.scrollLeft;
|
|
173
282
|
if (scrollLeft !== this.lastScrollLeft) {
|
|
174
283
|
this.lastScrollLeft = scrollLeft;
|
|
284
|
+
this.syncPinnedRows(scrollLeft);
|
|
175
285
|
this.bodyScroll.emit(scrollLeft);
|
|
286
|
+
// The indicator is clipped to the row content, which moves sideways too.
|
|
287
|
+
if (this.dragState) {
|
|
288
|
+
this.updateDropIndicator();
|
|
289
|
+
this.cdr.markForCheck();
|
|
290
|
+
}
|
|
176
291
|
return;
|
|
177
292
|
}
|
|
293
|
+
// Vertical: the drop indicator is anchored to the body, not the content, so
|
|
294
|
+
// it has to be repositioned as the rows move beneath it — which they do on
|
|
295
|
+
// their own during auto-scroll, with the pointer standing still.
|
|
296
|
+
if (this.dragState) {
|
|
297
|
+
this.updateDropIndicator();
|
|
298
|
+
this.cdr.markForCheck();
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Keep the pinned rows in step with the body's horizontal position.
|
|
303
|
+
*
|
|
304
|
+
* Assigned rather than transformed, for the same reason as the header: sticky
|
|
305
|
+
* positioning for pinned *columns* has to resolve against a real scrollport,
|
|
306
|
+
* and a transformed ancestor is not one. Pinned rows and pinned columns
|
|
307
|
+
* therefore compose — a frozen corner cell stays frozen on both axes.
|
|
308
|
+
*/
|
|
309
|
+
syncPinnedRows(scrollLeft) {
|
|
310
|
+
this.pinnedViewports?.forEach(viewport => (viewport.nativeElement.scrollLeft = scrollLeft));
|
|
178
311
|
}
|
|
179
312
|
/**
|
|
180
313
|
* Track Rendering Row Node By Row ID
|
|
@@ -354,14 +487,56 @@ export class OneGridBodyComponent {
|
|
|
354
487
|
invokeRowActionLanguage(event) {
|
|
355
488
|
this.onRowLanguage.emit(event);
|
|
356
489
|
}
|
|
490
|
+
/**
|
|
491
|
+
* Open the cell option menu, and tell the host it was asked for.
|
|
492
|
+
*
|
|
493
|
+
* The opening is the part that was missing. Everything else existed — the
|
|
494
|
+
* trigger button behind `cellRendererParams.cellOptionButtonStatus`, the menu
|
|
495
|
+
* component, the `cellOptionMenu` column property, the selection event wired
|
|
496
|
+
* through to the grid's output — but nothing ever set the flag the template
|
|
497
|
+
* renders on, so the button did nothing at all.
|
|
498
|
+
*
|
|
499
|
+
* Done here rather than in the row-action component because this is the
|
|
500
|
+
* component whose template renders the menu, and so the one that has to be
|
|
501
|
+
* marked for check.
|
|
502
|
+
*/
|
|
357
503
|
invokeRowActionCellOption(event) {
|
|
504
|
+
const field = event.column?.field;
|
|
505
|
+
// Nothing to open when the column declared no options; the event still
|
|
506
|
+
// goes to the host, which may be driving something of its own.
|
|
507
|
+
if (field && event.node && event.column?.cellOptionMenu?.length) {
|
|
508
|
+
event.node.cellOptions[field] = true;
|
|
509
|
+
this.cdr.markForCheck();
|
|
510
|
+
}
|
|
358
511
|
this.onRowCellOption.emit(event);
|
|
359
512
|
}
|
|
513
|
+
/**
|
|
514
|
+
* The menu closed itself — on select, on Escape, or on a click outside. It
|
|
515
|
+
* has already cleared its own flag; this is what repaints without it.
|
|
516
|
+
*/
|
|
517
|
+
cellOptionMenuClosed() {
|
|
518
|
+
this.cdr.markForCheck();
|
|
519
|
+
}
|
|
360
520
|
invokeRowActionSelection(event) {
|
|
361
521
|
this.onRowSelection.emit(event);
|
|
362
522
|
}
|
|
523
|
+
/**
|
|
524
|
+
* Toggle a group / master row, then report the result.
|
|
525
|
+
*
|
|
526
|
+
* The group renderer is presentational: it says "the expander was clicked"
|
|
527
|
+
* and nothing more. Performing the state change belongs here, where the API
|
|
528
|
+
* is available. Previously this method only re-emitted, so the expander
|
|
529
|
+
* rendered, animated on hover and did nothing at all — every consumer had to
|
|
530
|
+
* discover for itself that `expansionChanged` was a request rather than the
|
|
531
|
+
* notification its past-tense name promises.
|
|
532
|
+
*
|
|
533
|
+
* The event is re-emitted *after* the toggle, so `event.node.expanded` is the
|
|
534
|
+
* new state, which is what a past-tense event should carry.
|
|
535
|
+
*/
|
|
363
536
|
invokeExpansionChangedClick(event) {
|
|
364
|
-
this.
|
|
537
|
+
const node = this.api.getRowNodeById(event.node.rowId) ?? event.node;
|
|
538
|
+
this.api.setExpandedById(node.rowId, !node.expanded);
|
|
539
|
+
this.expansionChanged.emit({ ...event, node, api: this.api });
|
|
365
540
|
}
|
|
366
541
|
cellOptionMenuSelected(event) {
|
|
367
542
|
this.cellOptionSelect.emit(event);
|
|
@@ -451,26 +626,94 @@ export class OneGridBodyComponent {
|
|
|
451
626
|
}
|
|
452
627
|
}
|
|
453
628
|
}
|
|
454
|
-
/**
|
|
455
|
-
* Virtual Scroll Properties
|
|
456
|
-
*/
|
|
457
629
|
setVirtualScroll(items = 0) {
|
|
458
|
-
this.minBufferPx = this.itemSize * items * 1.5;
|
|
630
|
+
this.minBufferPx = Math.min(this.itemSize * items * 1.5, this.MAX_BUFFER_PX);
|
|
459
631
|
this.maxBufferPx = this.minBufferPx * 2;
|
|
460
632
|
}
|
|
461
633
|
/**
|
|
462
634
|
* Unsubscribe All Subscriptions
|
|
463
635
|
*/
|
|
636
|
+
/**
|
|
637
|
+
* Hand the drag service what it needs to run a gesture.
|
|
638
|
+
*
|
|
639
|
+
* Deferred to here because the viewport element does not exist until the view
|
|
640
|
+
* is up, and `nodes` is passed as a getter rather than a value — a drag
|
|
641
|
+
* mutates the order underneath it, so a snapshot taken at attach time would
|
|
642
|
+
* go stale on the first move.
|
|
643
|
+
*/
|
|
644
|
+
ngAfterViewInit() {
|
|
645
|
+
const element = this.viewport?.elementRef?.nativeElement;
|
|
646
|
+
if (!element)
|
|
647
|
+
return;
|
|
648
|
+
this.rowDragService.attach({
|
|
649
|
+
viewport: element,
|
|
650
|
+
itemSize: this.itemSize,
|
|
651
|
+
nodes: () => this.nodes,
|
|
652
|
+
move: (fromIndex, toIndex) => {
|
|
653
|
+
const moved = this.api.moveRow(fromIndex, toIndex);
|
|
654
|
+
if (moved)
|
|
655
|
+
this.cdr.markForCheck();
|
|
656
|
+
return moved;
|
|
657
|
+
},
|
|
658
|
+
});
|
|
659
|
+
this.refreshRowDragSuppressed();
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* The params every per-cell callback receives.
|
|
663
|
+
*
|
|
664
|
+
* Built here rather than inline in the template so the whole documented
|
|
665
|
+
* shape is passed — `value`, `field`, `rowIndex`, `api` and `context` were
|
|
666
|
+
* all declared on `OneCellRendererParams` and none of them were being sent,
|
|
667
|
+
* so a `cellClass` reading `params.value` silently got `undefined`.
|
|
668
|
+
*/
|
|
669
|
+
cellParams(node, column) {
|
|
670
|
+
return this.cellService.cellParams(column, node);
|
|
671
|
+
}
|
|
672
|
+
/**
|
|
673
|
+
* Params for a component cell renderer.
|
|
674
|
+
*
|
|
675
|
+
* The cell params, plus whatever the column declared in
|
|
676
|
+
* `cellRendererParams` — a field that exists precisely so a renderer can be
|
|
677
|
+
* configured per column, and that nothing had ever forwarded to it. Column
|
|
678
|
+
* config goes first so the grid's own fields win a name collision.
|
|
679
|
+
*/
|
|
680
|
+
rendererParams(node, column) {
|
|
681
|
+
return { ...(column?.cellRendererParams ?? {}), ...this.cellParams(node, column) };
|
|
682
|
+
}
|
|
683
|
+
/** Is this the row currently being moved? */
|
|
684
|
+
isRowDragging(node) {
|
|
685
|
+
return this.dragState?.rowId === node.rowId;
|
|
686
|
+
}
|
|
687
|
+
updateDropIndicator() {
|
|
688
|
+
const state = this.dragState;
|
|
689
|
+
const element = this.viewport?.elementRef?.nativeElement;
|
|
690
|
+
if (state?.source !== 'pointer' || !element) {
|
|
691
|
+
this.dropIndicatorTop = null;
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
694
|
+
this.dropIndicatorTop = (state.insertAt * this.itemSize) - element.scrollTop + element.offsetTop;
|
|
695
|
+
this.dropIndicatorWidth = Math.max(Math.min(this.rowWidth - element.scrollLeft, element.clientWidth), 0);
|
|
696
|
+
}
|
|
697
|
+
onRowDragEnd(event) {
|
|
698
|
+
this.rowDragEnd.emit(event);
|
|
699
|
+
}
|
|
700
|
+
refreshRowDragSuppressed() {
|
|
701
|
+
const reason = this.api?.getRowDragSuppressedReason?.() ?? null;
|
|
702
|
+
if (reason === this.rowDragSuppressed)
|
|
703
|
+
return;
|
|
704
|
+
this.rowDragSuppressed = reason;
|
|
705
|
+
this.cdr.markForCheck();
|
|
706
|
+
}
|
|
464
707
|
ngOnDestroy() {
|
|
465
708
|
this.subscriptions.unsubscribe();
|
|
466
709
|
}
|
|
467
|
-
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: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
468
|
-
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$", 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" }, 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 }], ngImport: i0, template: "<div #bodyRef class=\"one-grid-body\">\n <cdk-virtual-scroll-viewport\n class=\"one-grid-body-viewport\"\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\" [attr.data-row-id]=\"node.rowId\" [class.one-row-selected]=\"node.selected\">\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 @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</div>\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 [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 }\n\n <!-- Grid Cell Template -->\n @if(column?.cellRendererComponent) {\n <ng-container\n oneCellRendererComponent\n [cellRendererComponent]=\"column?.cellRendererComponent\"\n [params]=\"{ data: node.data, field: column.field, rowIndex: node.rowIndex, columnDef: column, node: node, context: context }\">\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.resolveCellPresentation(column, { node, data: node.data, columnDef: column })._resolvedCellClass\"\n [ngStyle]=\"colService.resolveCellPresentation(column, { node, data: node.data, columnDef: column })._resolvedCellStyle\"\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 <!-- 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]=\"{ data: node.data, field: column.field, rowIndex: node.rowIndex, columnDef: column, node: node, context: context }\">\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: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { 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: i6.OneGridCheckboxComponent, selector: "one-grid-checkbox", inputs: ["node", "allowedEdit", "api"], outputs: ["onRowSelection"] }, { kind: "component", type: i7.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: i8.OneGridCellGroupRendererComponent, selector: "one-grid-cell-group-renderer", inputs: ["node", "masterDetail", "detailCellRendererParams", "detailRendererComponent"], outputs: ["expansionChanged"] }, { kind: "directive", type: i9.OneCellInputValidatorDirective, selector: "[oneCellInputValidator]", inputs: ["validationType", "regex"] }, { kind: "directive", type: i10.OneCellRendererComponentDirective, selector: "[oneCellRendererComponent]", inputs: ["cellRendererComponent", "params"] }, { kind: "directive", type: i11.OneCellTextExpandDirective, selector: "[oneCellTextExpand]" }, { kind: "component", type: i12.OneGridCellOptionMenuComponent, selector: "one-grid-cell-option-menu", inputs: ["column", "node", "options"], outputs: ["cellOptionMenuSelect", "cellOptionMenuClose"] }, { kind: "pipe", type: i13.CellEditablePipe, name: "cellEditable" }, { kind: "pipe", type: i14.CellInvalidPipe, name: "cellInvalid" }, { kind: "pipe", type: i15.CellSelectedPipe, name: "cellSelected" }, { kind: "pipe", type: i16.CellActionButtonEnablePipe, name: "cellActionButtonEnable" }, { kind: "pipe", type: i17.CellKeyPipe, name: "cellKey" }, { kind: "pipe", type: i18.CellLevelPaddingPipe, name: "cellLevelPadding" }, { kind: "pipe", type: i19.CellStateRendererPipe, name: "cellStateRenderer" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
710
|
+
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 }); }
|
|
469
712
|
}
|
|
470
713
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: OneGridBodyComponent, decorators: [{
|
|
471
714
|
type: Component,
|
|
472
|
-
args: [{ standalone: false, selector: 'one-grid-body', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div #bodyRef class=\"one-grid-body\">\n <cdk-virtual-scroll-viewport\n class=\"one-grid-body-viewport\"\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\" [attr.data-row-id]=\"node.rowId\" [class.one-row-selected]=\"node.selected\">\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 @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</div>\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 [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 }\n\n <!-- Grid Cell Template -->\n @if(column?.cellRendererComponent) {\n <ng-container\n oneCellRendererComponent\n [cellRendererComponent]=\"column?.cellRendererComponent\"\n [params]=\"{ data: node.data, field: column.field, rowIndex: node.rowIndex, columnDef: column, node: node, context: context }\">\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.resolveCellPresentation(column, { node, data: node.data, columnDef: column })._resolvedCellClass\"\n [ngStyle]=\"colService.resolveCellPresentation(column, { node, data: node.data, columnDef: column })._resolvedCellStyle\"\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 <!-- 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]=\"{ data: node.data, field: column.field, rowIndex: node.rowIndex, columnDef: column, node: node, context: context }\">\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" }]
|
|
473
|
-
}], ctorParameters: () => [{ type: i1.OgColumnService }, { type: i2.OneGridCellService }, { type: i3.OneGridEventService }, { type: i0.ChangeDetectorRef }], propDecorators: { bodyRef: [{
|
|
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" }]
|
|
716
|
+
}], ctorParameters: () => [{ type: i1.OgColumnService }, { type: i2.OneGridCellService }, { type: i3.OneGridEventService }, { type: i4.OneGridRowDragService }, { type: i0.ChangeDetectorRef }], propDecorators: { bodyRef: [{
|
|
474
717
|
type: ViewChild,
|
|
475
718
|
args: ['bodyRef', { static: true }]
|
|
476
719
|
}], rowData: [{
|
|
@@ -495,6 +738,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
495
738
|
}], gridCopy$: [{
|
|
496
739
|
type: Input,
|
|
497
740
|
args: [{ required: true }]
|
|
741
|
+
}], pinnedTopRowData: [{
|
|
742
|
+
type: Input
|
|
743
|
+
}], pinnedBottomRowData: [{
|
|
744
|
+
type: Input
|
|
745
|
+
}], pinnedViewports: [{
|
|
746
|
+
type: ViewChildren,
|
|
747
|
+
args: ['pinnedViewport']
|
|
498
748
|
}], viewport: [{
|
|
499
749
|
type: ViewChild,
|
|
500
750
|
args: [CdkVirtualScrollViewport]
|
|
@@ -560,6 +810,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
560
810
|
type: Output
|
|
561
811
|
}], cellOptionSelect: [{
|
|
562
812
|
type: Output
|
|
813
|
+
}], rowDragEnd: [{
|
|
814
|
+
type: Output
|
|
563
815
|
}], onDocumentClick: [{
|
|
564
816
|
type: HostListener,
|
|
565
817
|
args: ['document:click', ['$event']]
|
|
@@ -567,4 +819,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
567
819
|
type: HostListener,
|
|
568
820
|
args: ['document:mouseup']
|
|
569
821
|
}] } });
|
|
570
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib25lLWdyaWQtYm9keS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9vbmUtZ3JpZC9zcmMvbGliL2NvbXBvbmVudHMvb25lLWdyaWQtYm9keS9vbmUtZ3JpZC1ib2R5LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL29uZS1ncmlkL3NyYy9saWIvY29tcG9uZW50cy9vbmUtZ3JpZC1ib2R5L29uZS1ncmlkLWJvZHkuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFxQixTQUFTLEVBQWMsWUFBWSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQXFCLE1BQU0sRUFBcUIsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBSzlMLE9BQU8sRUFBVyxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFLN0MsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDdkUsT0FBTyxFQUFFLFVBQVUsRUFBRSxhQUFhLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUUxRSxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBVWxFLE1BQU0sT0FBTyxvQkFBb0I7SUFzRy9CLFlBQ1ksVUFBMkIsRUFDM0IsV0FBK0IsRUFDakMsWUFBaUMsRUFDakMsR0FBc0I7UUFIcEIsZUFBVSxHQUFWLFVBQVUsQ0FBaUI7UUFDM0IsZ0JBQVcsR0FBWCxXQUFXLENBQW9CO1FBQ2pDLGlCQUFZLEdBQVosWUFBWSxDQUFxQjtRQUNqQyxRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQXBHTCxZQUFPLEdBQVEsRUFBRSxDQUFDO1FBR3BDLGVBQVUsR0FBWSxLQUFLLENBQUM7UUFDNUIsZ0JBQVcsR0FBWSxJQUFJLENBQUM7UUFDNUIsMEJBQXFCLEdBQVksS0FBSyxDQUFD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Z0JBQ0csVUFBVTtzQkFBbkIsTUFBTTtnQkFDRyxZQUFZO3NCQUFyQixNQUFNO2dCQUNHLFdBQVc7c0JBQXBCLE1BQU07Z0JBQ0csYUFBYTtzQkFBdEIsTUFBTTtnQkFDRyxlQUFlO3NCQUF4QixNQUFNO2dCQUNHLGNBQWM7c0JBQXZCLE1BQU07Z0JBQ0csa0JBQWtCO3NCQUEzQixNQUFNO2dCQUNHLGVBQWU7c0JBQXhCLE1BQU07Z0JBRUcsZ0JBQWdCO3NCQUF6QixNQUFNO2dCQUNHLFVBQVU7c0JBQW5CLE1BQU07Z0JBQ0csZ0JBQWdCO3NCQUF6QixNQUFNO2dCQWlOUCxlQUFlO3NCQURkLFlBQVk7dUJBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBa0IxQyxlQUFlO3NCQURkLFlBQVk7dUJBQUMsa0JBQWtCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEV2ZW50RW1pdHRlciwgSG9zdExpc3RlbmVyLCBJbnB1dCwgT25EZXN0cm95LCBPbkluaXQsIE91dHB1dCwgVGVtcGxhdGVSZWYsIFR5cGUsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ2VsbFNlbGVjdGlvbiwgT25lQ2VsbFJlbmRlcmVyUGFyYW1zLCBPbmVDb2x1bW5EZWYgfSBmcm9tICcuLi8uLi9jb3JlL21vZGVscy9vbmUtY29sdW1uLWRlZi10eXBlcy5tb2RlbCc7XG5pbXBvcnQgeyBPbmVDZWxsUmVuZGVyZXJDb21wb25lbnQgfSBmcm9tICcuLi8uLi9jb3JlL21vZGVscy9vbmUtdHJlZS1kYXRhLm1vZGVsJztcbmltcG9ydCB7IE9uZVJvd05vZGUgfSBmcm9tICcuLi8uLi9jb3JlL2luc3RhbnRzL29uZS1yb3ctbm9kZS5jbGFzcyc7XG5pbXBvcnQgeyBPbmVHcmlkQXBpIH0gZnJvbSAnLi4vLi4vY29yZS9pbnN0YW50cy9vbmUtZ3JpZC1hcGkuY2xhc3MnO1xuaW1wb3J0IHsgU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBPbmVHcmlkR2V0Um93SWRQYXJhbXMsIE9uZUdyaWRSZWFkeUV2ZW50LCBPbmVHcmlkUm93QWN0aW9uRXZlbnQsIE9uZUdyaWRUeXBlIH0gZnJvbSAnLi4vLi4vY29yZS9tb2RlbHMvb25lLWdyaWQtdHlwZXMubW9kZWwnO1xuaW1wb3J0IHsgT25lR3JpZEV2ZW50U2VydmljZSB9IGZyb20gJy4uLy4uL2NvcmUvc2VydmljZXMvb25lLWdyaWQtZXZlbnQuc2VydmljZSc7XG5pbXBvcnQgeyBDZWxsT3B0aW9uTWVudVNlbGVjdGVkRXZlbnQsIENvbHVtbkNoYW5nZWRFdmVudCwgRXhwYW5zaW9uQ2hhbmdlZEV2ZW50LCBSb3dEYXRhQ2hhbmdlZEV2ZW50LCBTZWxlY3Rpb25DaGFuZ2VkRXZlbnQsIFNvcnRDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi8uLi9jb3JlL21vZGVscy9vbmUtZXZlbnQtdHlwZXMubW9kZWwnO1xuaW1wb3J0IHsgT25lRGV0YWlsQ2VsbFJlbmRlcmVyUGFyYW1zIH0gZnJvbSAnLi4vLi4vY29yZS9tb2RlbHMvb25lLW1hc3Rlci1kZXRhaWwubW9kZWwnO1xuaW1wb3J0IHsgQ2VsbEVkaXRhYmxlUGlwZSB9IGZyb20gJy4uLy4uL2NvcmUvcGlwZXMvY2VsbC1lZGl0YWJsZS5waXBlJztcbmltcG9ydCB7IGdldENlbGxLZXksIGdldEZpZWxkVmFsdWUgfSBmcm9tICcuLi8uLi9oZWxwZXJzL29uZS1jZWxsLmhlbHBlcic7XG5pbXBvcnQgeyBPbmVHcmlkQ2VsbFNlcnZpY2UgfSBmcm9tICcuLi8uLi9jb3JlL3NlcnZpY2VzL29uZS1ncmlkLWNlbGwuc2VydmljZSc7XG5pbXBvcnQgeyBDZGtWaXJ0dWFsU2Nyb2xsVmlld3BvcnQgfSBmcm9tICdAYW5ndWxhci9jZGsvc2Nyb2xsaW5nJztcbmltcG9ydCB7IE9nQ29sdW1uU2VydmljZSB9IGZyb20gJy4uLy4uL2NvcmUvc2VydmljZXMvb2ctY29sdW1uLnNlcnZpY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc3RhbmRhbG9uZTogZmFsc2UsXG4gIHNlbGVjdG9yOiAnb25lLWdyaWQtYm9keScsXG4gIHRlbXBsYXRlVXJsOiAnLi9vbmUtZ3JpZC1ib2R5LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmw6ICcuL29uZS1ncmlkLWJvZHkuY29tcG9uZW50LnNjc3MnLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgT25lR3JpZEJvZHlDb21wb25lbnQ8VD4gaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG5cbiAgLyoqXG4gICAqIENvcmUgUHJvcGVydGllc1xuICAgKi9cbiAgQFZpZXdDaGlsZCgnYm9keVJlZicsIHsgc3RhdGljOiB0cnVlIH0pIGJvZHlSZWYhOiBFbGVtZW50UmVmO1xuICBASW5wdXQoeyByZXF1aXJlZDogdHJ1ZSB9KSByb3dEYXRhOiBUW10gPSBbXTtcbiAgQElucHV0KCkgcm93TnVtYmVyOiBib29sZWFuO1xuICBASW5wdXQoKSBhcGkhOiBPbmVHcmlkQXBpPFQ+O1xuICBASW5wdXQoKSBwYWdpbmF0aW9uOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIGFsbG93ZWRFZGl0OiBib29sZWFuID0gdHJ1ZTtcbiAgQElucHV0KCkgZW5hYmxlR3JvdXBDb2x1bW5EZWZzOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIHN1Ym1pdHRlZDogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBjb250ZXh0OiBhbnkgPSBudWxsO1xuICBASW5wdXQoKSBnZXRSb3dJZDogKHBhcmFtczogT25lR3JpZEdldFJvd0lkUGFyYW1zPFQ+KSA9PiBzdHJpbmc7XG4gIEBJbnB1dCh7IHJlcXVpcmVkOiB0cnVlIH0pIGdyaWRDb3B5JCE6IFN1YmplY3Q8Q2xpcGJvYXJkRXZlbnQ+O1xuICBAVmlld0NoaWxkKENka1ZpcnR1YWxTY3JvbGxWaWV3cG9ydCkgdmlld3BvcnQhOiBDZGtWaXJ0dWFsU2Nyb2xsVmlld3BvcnQ7XG5cbiAgcHJvdGVjdGVkIGNvbHVtbkRlZnM6IE9uZUNvbHVtbkRlZjxUPltdID0gW107XG4gIHByb3RlY3RlZCBjZWxsUmVuZGVyZXI6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvKipcbiAgICogTWFzdGVyIERldGFpbCBQcm9wZXJ0aWVzXG4gICAqL1xuICBASW5wdXQoKSBncmlkVHlwZTogT25lR3JpZFR5cGUgPSAnc2ltcGxlJztcbiAgQElucHV0KCkgbWFzdGVyRGV0YWlsOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIG1hc3Rlck5vZGU6IE9uZVJvd05vZGU8VD4gPSBudWxsO1xuICAvLyBASW5wdXQoKSBkZXRhaWxSb3dIZWlnaHQ6IG51bWJlciA9IG51bGw7XG4gIC8vIEBJbnB1dCgpIGRldGFpbFJvd0F1dG9IZWlnaHQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgZGV0YWlsUm93TWF4SGVpZ2h0OiBudW1iZXIgPSBudWxsO1xuICBASW5wdXQoKSBkZXRhaWxDZWxsUmVuZGVyZXJQYXJhbXM6IE9uZURldGFpbENlbGxSZW5kZXJlclBhcmFtcztcbiAgQElucHV0KCkgZGV0YWlsR3JpZFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjx1bmtub3duPiA9IG51bGw7XG4gIEBJbnB1dCgpIGRldGFpbFJlbmRlcmVyQ29tcG9uZW50OiBUeXBlPE9uZUNlbGxSZW5kZXJlckNvbXBvbmVudD47XG5cbiAgLyoqXG4gICAqIFRyZWUgRGF0YSBQcm9wZXJ0aWVzXG4gICAqL1xuICBASW5wdXQoKSB0cmVlRGF0YTogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSB0cmVlRGF0YUNoaWxkcmVuRmllbGQ6IHN0cmluZztcbiAgQElucHV0KCkgYXV0b0dyb3VwQ29sdW1uRGVmOiBPbmVDb2x1bW5EZWY8VD47XG4gIEBJbnB1dCgpIGdyb3VwRGVmYXVsdEV4cGFuZGVkOiBudW1iZXIgPSAtMTsgLy8gSXQncyB3b3JrIHdpdGggbWFzdGVyIGRldGFpbCBhbHNvXG5cbiAgLyoqXG4gICAqIFBhc3NpbmcgUm93IEFjdGlvbiBFdmVudHMgdG8gUGFyZW50XG4gICAqL1xuICBAT3V0cHV0KCkgb25Sb3dHb3RvRGV0YWlsID0gbmV3IEV2ZW50RW1pdHRlcjxPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4+KCk7XG4gIEBPdXRwdXQoKSBvblJvd0FkZE5ldyA9IG5ldyBFdmVudEVtaXR0ZXI8T25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+PigpO1xuICBAT3V0cHV0KCkgb25Sb3dWaWV3ID0gbmV3IEV2ZW50RW1pdHRlcjxPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4+KCk7XG4gIEBPdXRwdXQoKSBvblJvd0NvcHkgPSBuZXcgRXZlbnRFbWl0dGVyPE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIG9uUm93TG9jYXRpb24gPSBuZXcgRXZlbnRFbWl0dGVyPE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIG9uUm93RG9jdW1lbnQgPSBuZXcgRXZlbnRFbWl0dGVyPE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIG9uUm93RGVsZXRlID0gbmV3IEV2ZW50RW1pdHRlcjxPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4+KCk7XG4gIEBPdXRwdXQoKSBvblJvd0dvdG9MaXN0ID0gbmV3IEV2ZW50RW1pdHRlcjxPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4+KCk7XG4gIEBPdXRwdXQoKSBvblJvd0VkaXQgPSBuZXcgRXZlbnRFbWl0dGVyPE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIG9uUm93UHJpbnQgPSBuZXcgRXZlbnRFbWl0dGVyPE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIG9uUm93SGlzdG9yeSA9IG5ldyBFdmVudEVtaXR0ZXI8T25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+PigpO1xuICBAT3V0cHV0KCkgb25Sb3dPcHRpb24gPSBuZXcgRXZlbnRFbWl0dGVyPE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIG9uUm93TGFuZ3VhZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIG9uUm93Q2VsbE9wdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8T25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+PigpO1xuICBAT3V0cHV0KCkgb25Sb3dTZWxlY3Rpb24gPSBuZXcgRXZlbnRFbWl0dGVyPE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIG9uU2hpZnREb3VibGVDbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8T25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+PigpO1xuICBAT3V0cHV0KCkgcm93Q291bnRDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG5cbiAgQE91dHB1dCgpIGV4cGFuc2lvbkNoYW5nZWQgPSBuZXcgRXZlbnRFbWl0dGVyPEV4cGFuc2lvbkNoYW5nZWRFdmVudDxUPj4oKTtcbiAgQE91dHB1dCgpIGJvZHlTY3JvbGwgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcbiAgQE91dHB1dCgpIGNlbGxPcHRpb25TZWxlY3QgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICAvKipcbiAgICogU2VsZWN0aW9uIFJhbmdlIFZhcmlhYmxlc1xuICAgKi9cbiAgcHJvdGVjdGVkIHJvd1dpZHRoOiBudW1iZXIgPSAwO1xuICBwcm90ZWN0ZWQgbm9kZXM6IE9uZVJvd05vZGU8VD5bXSA9IFtdO1xuICBwcm90ZWN0ZWQgc2VsZWN0ZWRDZWxscyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBwcml2YXRlIGlzTW91c2VEb3duID0gZmFsc2U7XG4gIHByaXZhdGUgc3RhcnRDZWxsOiBDZWxsU2VsZWN0aW9uID0gbnVsbDtcbiAgcHJpdmF0ZSBsYXN0U2Nyb2xsTGVmdCA9IDA7XG4gIHByaXZhdGUgY2VsbEVkaXRhYmxlUGlwZSA9IG5ldyBDZWxsRWRpdGFibGVQaXBlKCk7XG4gIHByaXZhdGUgc3Vic2NyaXB0aW9ucyA9IG5ldyBTdWJzY3JpcHRpb24oKTtcblxuICBwcm90ZWN0ZWQgY2VsbFJlbmRlcmVyUGFyYW1zOiBPbmVDZWxsUmVuZGVyZXJQYXJhbXMgPSB7XG4gICAgICBnb3RvRGV0YWlsQnV0dG9uU3RhdHVzOiAxLFxuICAgICAgYWRkTmV3QnV0dG9uU3RhdHVzOiAxLFxuICAgICAgdmlld0J1dHRvblN0YXR1czogMSxcbiAgICAgIGxvY2F0aW9uQnV0dG9uU3RhdHVzOiAxLFxuICAgICAgZG9jdW1lbnRCdXR0b25TdGF0dXM6IDEsXG4gICAgICBjb3B5QnV0dG9uU3RhdHVzOiAxLFxuICAgICAgZGVsZXRlQnV0dG9uU3RhdHVzOiAxLFxuICAgICAgZ290b0xpc3RCdXR0b25TdGF0dXM6IDEsXG4gICAgICBvcHRpb25CdXR0b25TdGF0dXM6IDEsXG4gICAgICBsYW5ndWFnZUJ1dHRvblN0YXR1czogMSxcbiAgICAgIGVkaXRCdXR0b25TdGF0dXM6IDEsXG4gICAgICBwcmludEJ1dHRvblN0YXR1czogMSxcbiAgICAgIGhpc3RvcnlCdXR0b25TdGF0dXM6IDEsXG4gIH1cblxuICAvKipcbiAgICogVmlydHVhbCBTY3JvbGwgUHJvcGVydGllc1xuICAgKi9cbiAgcHJvdGVjdGVkIGl0ZW1TaXplOiBudW1iZXIgPSAzMDtcbiAgcHJvdGVjdGVkIG1pbkJ1ZmZlclB4OiBudW1iZXIgPSAyMDA7XG4gIHByb3RlY3RlZCBtYXhCdWZmZXJQeDogbnVtYmVyID0gNDAwO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByb3RlY3RlZCBjb2xTZXJ2aWNlOiBPZ0NvbHVtblNlcnZpY2UsXG4gICAgcHJvdGVjdGVkIGNlbGxTZXJ2aWNlOiBPbmVHcmlkQ2VsbFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBldmVudFNlcnZpY2U6IE9uZUdyaWRFdmVudFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmXG4gICkgeyB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG5cbiAgICAvKipcbiAgICAgKiBMaXN0ZW4gR3JpZCBDb3B5IEV2ZW50XG4gICAgICovXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZCh0aGlzLmdyaWRDb3B5JC5zdWJzY3JpYmUoKGV2ZW50OiBDbGlwYm9hcmRFdmVudCkgPT4ge1xuXG4gICAgICB0aGlzLm9uR3JpZENvcHkoZXZlbnQpO1xuICAgIH0pKTtcblxuICAgIC8qKlxuICAgICAqIExpc3RlbiBDb2x1bW4gQ2hhbmdlZCBFdmVudFxuICAgICAqL1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQodGhpcy5ldmVudFNlcnZpY2UuYWRkRXZlbnRMaXN0ZW5lcignY29sdW1uQ2hhbmdlZCcsIChwYXlsb2FkOiBDb2x1bW5DaGFuZ2VkRXZlbnQpID0+IHtcblxuICAgICAgdGhpcy5jb2x1bW5EZWZzID0gWy4uLnBheWxvYWQuY29sdW1uc10gYXMgT25lQ29sdW1uRGVmW107XG5cbiAgICAgIHRoaXMuY2VsbFJlbmRlcmVyID0gdGhpcy5jb2x1bW5EZWZzLnNvbWUoY29sID0+IGNvbC5jZWxsUmVuZGVyZXJDb21wb25lbnQpO1xuXG4gICAgICB0aGlzLnJvd1dpZHRoID0gdGhpcy5jb2x1bW5EZWZzLnJlZHVjZSgoc3VtLCBjb2wpID0+IHN1bSArIChjb2wud2lkdGggPyBjb2wud2lkdGggPiBjb2wubWF4V2lkdGggPyBjb2wubWF4V2lkdGggOiBjb2wud2lkdGggPCBjb2wubWluV2lkdGggPyBjb2wubWluV2lkdGggOiBjb2wud2lkdGggOiBjb2wubWluV2lkdGgpLCAwKTtcblxuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfSkpO1xuXG4gICAgLyoqXG4gICAgICogTGlzdGVuIFJvdyBEYXRhIENoYW5nZWQgRXZlbnRcbiAgICAgKi9cbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKHRoaXMuZXZlbnRTZXJ2aWNlLmFkZEV2ZW50TGlzdGVuZXIoJ3Jvd0RhdGFDaGFuZ2VkJywgKHsgbm9kZXMgfTogUm93RGF0YUNoYW5nZWRFdmVudDxUPikgPT4ge1xuXG4gICAgICB0aGlzLnJvd0NvdW50Q2hhbmdlZC5lbWl0KG5vZGVzPy5sZW5ndGggPz8gMCk7XG5cbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuXG4gICAgICAgIHRoaXMudmlld3BvcnQ/LmNoZWNrVmlld3BvcnRTaXplKCk7XG5cbiAgICAgICAgdGhpcy5zZXRWaXJ0dWFsU2Nyb2xsKG5vZGVzPy5sZW5ndGgpO1xuXG4gICAgICAgIGlmICh0aGlzLm1hc3RlckRldGFpbCkge1xuXG4gICAgICAgICAgdGhpcy5ub2RlcyA9IG5vZGVzLm1hcCgobm9kZTogT25lUm93Tm9kZSkgPT4ge1xuXG4gICAgICAgICAgICBpZiAobm9kZS5sZWFmICYmIHRoaXMuZGV0YWlsUmVuZGVyZXJDb21wb25lbnQpIHtcblxuICAgICAgICAgICAgICBub2RlLmRldGFpbFJlbmRlcmVyQ29tcG9uZW50ID0gdGhpcy5kZXRhaWxSZW5kZXJlckNvbXBvbmVudDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKG5vZGUuZXhwYW5kZWQpIHtcblxuICAgICAgICAgICAgICB0aGlzLmFwaS5zZXREZXRhaWxSb3dEYXRhKG5vZGUsIFsuLi5ub2RlLmRldGFpbFJvd0RhdGFdKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIG5vZGU7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgIHRoaXMubm9kZXMgPSBub2RlcyBhcyBPbmVSb3dOb2RlPFQ+W107XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuICAgIH0pKTtcblxuXG4gICAgLyoqXG4gICAgICogTGlzdGVuIFNvcnQgQ2hhbmdlZCBFdmVudFxuICAgICAqL1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQodGhpcy5ldmVudFNlcnZpY2UuYWRkRXZlbnRMaXN0ZW5lcignc29ydENoYW5nZWQnLCAoeyBub2RlcyB9OiBTb3J0Q2hhbmdlZEV2ZW50KSA9PiB7XG5cbiAgICAgIHRoaXMubm9kZXMgPSBub2RlcyBhcyBPbmVSb3dOb2RlPFQ+W107XG5cbiAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH0pKTtcblxuICAgIC8qKlxuICAgICAqIExpc3RlbiBTZWxlY3Rpb24gQ2hhbmdlZCBFdmVudFxuICAgICAqL1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQodGhpcy5ldmVudFNlcnZpY2UuYWRkRXZlbnRMaXN0ZW5lcignc2VsZWN0aW9uQ2hhbmdlZCcsIChwYXlsb2FkOiBTZWxlY3Rpb25DaGFuZ2VkRXZlbnQ8VD4pID0+IHtcblxuICAgICAgaWYgKHBheWxvYWQpIHtcblxuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH1cbiAgICB9KSk7XG4gIH1cblxuICBvbkdyaWRSZWFkeShwYXJhbXM6IE9uZUdyaWRSZWFkeUV2ZW50KSB7XG5cbiAgICBwYXJhbXMuYXBpLnNldFJvd0RhdGEodGhpcy5tYXN0ZXJOb2RlPy5kZXRhaWxSb3dEYXRhID8/IFtdKTtcbiAgfVxuXG4gIG9uQm9keVNjcm9sbChldmVudDogRXZlbnQpIHtcblxuICAgIGNvbnN0IHNjcm9sbExlZnQgPSAoZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50KS5zY3JvbGxMZWZ0O1xuXG4gICAgaWYgKHNjcm9sbExlZnQgIT09IHRoaXMubGFzdFNjcm9sbExlZnQpIHtcblxuICAgICAgdGhpcy5sYXN0U2Nyb2xsTGVmdCA9IHNjcm9sbExlZnQ7XG5cbiAgICAgIHRoaXMuYm9keVNjcm9sbC5lbWl0KHNjcm9sbExlZnQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFjayBSZW5kZXJpbmcgUm93IE5vZGUgQnkgUm93IElEXG4gICAqL1xuICB0cmFja0J5Um93SWQoaW5kZXg6IG51bWJlciwgbm9kZTogT25lUm93Tm9kZTxUPik6IHN0cmluZyB7XG5cbiAgICByZXR1cm4gbm9kZS5yb3dJZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDZWxsIFNlbGVjdGlvbiBSYW5nZSBGZWF0dXJlXG4gICAqL1xuICBzdGFydFNlbGVjdGlvbihyb3dJZDogc3RyaW5nLCBmaWVsZDogc3RyaW5nKSB7XG5cbiAgICB0aGlzLmlzTW91c2VEb3duID0gdHJ1ZTtcbiAgICB0aGlzLnN0YXJ0Q2VsbCA9IHsgcm93SWQsIGZpZWxkIH07XG4gICAgdGhpcy5zZWxlY3RlZENlbGxzLmNsZWFyKCk7XG4gICAgdGhpcy5zZWxlY3RlZENlbGxzID0gbmV3IFNldCh0aGlzLnNlbGVjdGVkQ2VsbHMpLmFkZChnZXRDZWxsS2V5KHJvd0lkLCBmaWVsZCkpO1xuICB9XG5cbiAgZXh0ZW5kU2VsZWN0aW9uKHJvd0lkOiBzdHJpbmcsIGZpZWxkOiBzdHJpbmcpIHtcblxuICAgIGlmICghdGhpcy5pc01vdXNlRG93biB8fCAhdGhpcy5zdGFydENlbGwpIHJldHVybjtcblxuICAgIGNvbnN0IHJvd3MgPSB0aGlzLm5vZGVzOyAvLyBhbHJlYWR5IHNvcnRlZFxuICAgIGNvbnN0IHN0YXJ0Um93SW5kZXggPSByb3dzLmZpbmRJbmRleChyID0+IHIucm93SWQgPT09IHRoaXMuc3RhcnRDZWxsIS5yb3dJZCk7XG4gICAgY29uc3QgZW5kUm93SW5kZXggICA9IHJvd3MuZmluZEluZGV4KHIgPT4gci5yb3dJZCA9PT0gcm93SWQpO1xuXG4gICAgaWYgKHN0YXJ0Um93SW5kZXggPT09IC0xIHx8IGVuZFJvd0luZGV4ID09PSAtMSkgcmV0dXJuO1xuXG4gICAgY29uc3QgY29sU3RhcnRJbmRleCA9IHRoaXMuY29sdW1uRGVmcy5maW5kSW5kZXgoYyA9PiBjLmZpZWxkID09PSB0aGlzLnN0YXJ0Q2VsbCEuZmllbGQpO1xuICAgIGNvbnN0IGNvbEVuZEluZGV4ICAgPSB0aGlzLmNvbHVtbkRlZnMuZmluZEluZGV4KGMgPT4gYy5maWVsZCA9PT0gZmllbGQpO1xuXG4gICAgaWYgKGNvbFN0YXJ0SW5kZXggPT09IC0xIHx8IGNvbEVuZEluZGV4ID09PSAtMSkgcmV0dXJuO1xuXG4gICAgY29uc3Qgcm93U3RhcnQgPSBNYXRoLm1pbihzdGFydFJvd0luZGV4LCBlbmRSb3dJbmRleCk7XG4gICAgY29uc3Qgcm93RW5kICAgPSBNYXRoLm1heChzdGFydFJvd0luZGV4LCBlbmRSb3dJbmRleCk7XG4gICAgY29uc3QgY29sU3RhcnQgPSBNYXRoLm1pbihjb2xTdGFydEluZGV4LCBjb2xFbmRJbmRleCk7XG4gICAgY29uc3QgY29sRW5kICAgPSBNYXRoLm1heChjb2xTdGFydEluZGV4LCBjb2xFbmRJbmRleCk7XG5cbiAgICBjb25zdCBuZXh0ID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgICBmb3IgKGxldCByID0gcm93U3RhcnQ7IHIgPD0gcm93RW5kOyByKyspIHtcbiAgICAgIGZvciAobGV0IGMgPSBjb2xTdGFydDsgYyA8PSBjb2xFbmQ7IGMrKykge1xuICAgICAgICBuZXh0LmFkZChnZXRDZWxsS2V5KHJvd3Nbcl0ucm93SWQsIHRoaXMuY29sdW1uRGVmc1tjXS5maWVsZCkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuc2VsZWN0ZWRDZWxscyA9IG5leHQ7XG4gIH1cblxuXG4gIGVuZFNlbGVjdGlvbigpIHtcblxuICAgIHRoaXMuaXNNb3VzZURvd24gPSBmYWxzZTtcbiAgICB0aGlzLnN0YXJ0Q2VsbCA9IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXIgQ2VsbHMgU2VsZWN0ZWRcbiAgICovXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmNsaWNrJywgWyckZXZlbnQnXSlcbiAgb25Eb2N1bWVudENsaWNrKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG5cbiAgICBpZiAodGhpcy5ib2R5UmVmPy5uYXRpdmVFbGVtZW50KSB7XG5cbiAgICAgIGNvbnN0IGNsaWNrZWRJbnNpZGUgPSB0aGlzLmJvZHlSZWYubmF0aXZlRWxlbWVudC5jb250YWlucyhldmVudC50YXJnZXQpO1xuXG4gICAgICBpZiAoIWNsaWNrZWRJbnNpZGUpIHtcblxuICAgICAgICB0aGlzLnNlbGVjdGVkQ2VsbHMuY2xlYXIoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2VsZWN0aW9uIFJhbmdlIEV2ZW50IEhvbGQgTW91c2UgQ2xpY2tcbiAgICovXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50Om1vdXNldXAnKVxuICBvbkdsb2JhbE1vdXNlVXAoKSB7XG5cbiAgICB0aGlzLmVuZFNlbGVjdGlvbigpO1xuICB9XG5cbiAgLyoqXG4gICAqIExpc3RlbiBDb3B5IENsaXBib2FyZCBFdmVudFxuICAgKi9cbiAgb25HcmlkQ29weShldmVudDogQ2xpcGJvYXJkRXZlbnQpIHtcblxuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICBpZiAodGhpcy5zZWxlY3RlZENlbGxzLnNpemUgPiAwKSB7XG5cbiAgICAgIGNvbnN0IHRleHQgPSB0aGlzLmJ1aWxkQ2xpcGJvYXJkVGV4dCgpO1xuXG4gICAgICBldmVudC5jbGlwYm9hcmREYXRhPy5zZXREYXRhKCd0ZXh0L3BsYWluJywgdGV4dCk7XG5cbiAgICAgIHRoaXMuc2VsZWN0ZWRDZWxscy5mb3JFYWNoKGNlbGxJZCA9PiB7XG5cbiAgICAgICAgY29uc3QgY2VsbEVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGBbZGF0YS1jZWxsLWlkPVwiJHtjZWxsSWR9XCJdYCk7XG5cbiAgICAgICAgaWYgKGNlbGxFbGVtZW50KSB7XG5cbiAgICAgICAgICBjZWxsRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdvbmUtY2VsbC1jb3BpZWQnKTtcblxuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gY2VsbEVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnb25lLWNlbGwtY29waWVkJyksIDQwMCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGNvcHlUb0NsaXBib2FyZCh2YWx1ZTogc3RyaW5nKSB7XG5cbiAgICBpZiAobmF2aWdhdG9yLmNsaXBib2FyZD8ud3JpdGVUZXh0KSB7XG5cbiAgICAgIG5hdmlnYXRvci5jbGlwYm9hcmQud3JpdGVUZXh0KHZhbHVlKTtcblxuICAgIH0gZWxzZSB7XG5cbiAgICAgIC8vIEZhbGxiYWNrIChTYWZhcmkgLyBvbGRlciBicm93c2VycylcbiAgICAgIGNvbnN0IHRleHRhcmVhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGV4dGFyZWEnKTtcbiAgICAgIHRleHRhcmVhLnZhbHVlID0gdmFsdWU7XG4gICAgICB0ZXh0YXJlYS5zdHlsZS5wb3NpdGlvbiA9ICdmaXhlZCc7XG4gICAgICB0ZXh0YXJlYS5zdHlsZS5vcGFjaXR5ID0gJzAnO1xuICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh0ZXh0YXJlYSk7XG4gICAgICB0ZXh0YXJlYS5zZWxlY3QoKTtcbiAgICAgIGRvY3VtZW50LmV4ZWNDb21tYW5kKCdjb3B5Jyk7XG4gICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKHRleHRhcmVhKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgQ29weSBDZWxsIFRleHQgdG8gQ2xpcGJvYXJkXG4gICAqL1xuICBwcml2YXRlIGJ1aWxkQ2xpcGJvYXJkVGV4dCgpOiBzdHJpbmcge1xuXG4gICAgaWYgKCF0aGlzLnNlbGVjdGVkQ2VsbHMuc2l6ZSkgcmV0dXJuICcnO1xuXG4gICAgLy8gUGFyc2Ugc2VsZWN0ZWQgY2VsbHNcbiAgICBjb25zdCBzZWxlY3RlZCA9IEFycmF5LmZyb20odGhpcy5zZWxlY3RlZENlbGxzKS5tYXAoa2V5ID0+IHtcblxuICAgICAgY29uc3QgW3Jvd0lkLCBmaWVsZF0gPSBrZXkuc3BsaXQoJy0tJyk7XG4gICAgICByZXR1cm4geyByb3dJZCwgZmllbGQgfTtcbiAgICB9KTtcblxuICAgIC8vIFJlc29sdmUgdmlzdWFsIHJvdyBpbmRleGVzIGZyb20gZGlzcGxheWVkUm93c1xuICAgIGNvbnN0IHJvd0luZGV4ZXMgPSBzZWxlY3RlZFxuICAgICAgLm1hcChzID0+IHRoaXMubm9kZXMuZmluZEluZGV4KHIgPT4gci5yb3dJZCA9PT0gcy5yb3dJZCkpXG4gICAgICAuZmlsdGVyKGkgPT4gaSAhPT0gLTEpO1xuXG4gICAgY29uc3QgY29sSW5kZXhlcyA9IHNlbGVjdGVkXG4gICAgICAubWFwKHMgPT4gdGhpcy5jb2x1bW5EZWZzLmZpbmRJbmRleChjID0+IGMuZmllbGQgPT09IHMuZmllbGQpKVxuICAgICAgLmZpbHRlcihpID0+IGkgIT09IC0xKTtcblxuICAgIGlmICghcm93SW5kZXhlcy5sZW5ndGggfHwgIWNvbEluZGV4ZXMubGVuZ3RoKSByZXR1cm4gJyc7XG5cbiAgICBjb25zdCByb3dTdGFydCA9IE1hdGgubWluKC4uLnJvd0luZGV4ZXMpO1xuICAgIGNvbnN0IHJvd0VuZCAgID0gTWF0aC5tYXgoLi4ucm93SW5kZXhlcyk7XG4gICAgY29uc3QgY29sU3RhcnQgPSBNYXRoLm1pbiguLi5jb2xJbmRleGVzKTtcbiAgICBjb25zdCBjb2xFbmQgICA9IE1hdGgubWF4KC4uLmNvbEluZGV4ZXMpO1xuXG4gICAgY29uc3Qgc2VsZWN0ZWRGaWVsZHMgPSB0aGlzLmNvbHVtbkRlZnNcbiAgICAgIC5zbGljZShjb2xTdGFydCwgY29sRW5kICsgMSlcbiAgICAgIC5tYXAoYyA9PiBjLmZpZWxkKTtcblxuICAgIGNvbnN0IGNsaXBib2FyZExpbmVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgZm9yIChsZXQgciA9IHJvd1N0YXJ0OyByIDw9IHJvd0VuZDsgcisrKSB7XG5cbiAgICAgIGNvbnN0IHJvdyA9IHRoaXMubm9kZXNbcl07XG4gICAgICBjb25zdCBsaW5lID0gc2VsZWN0ZWRGaWVsZHNcbiAgICAgICAgLm1hcChmaWVsZCA9PiB7XG5cbiAgICAgICAgICBjb25zdCBrZXkgPSBgJHtyb3cucm93SWR9LS0ke2ZpZWxkfWA7XG5cbiAgICAgICAgICBpZiAoIXRoaXMuc2VsZWN0ZWRDZWxscy5oYXMoa2V5KSkge1xuXG4gICAgICAgICAgICByZXR1cm4gJyc7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IHZhbHVlID0gZ2V0RmllbGRWYWx1ZShyb3cuZGF0YSwgZmllbGQpO1xuXG4gICAgICAgICAgcmV0dXJuIHZhbHVlID8/ICcnO1xuXG4gICAgICAgIH0pLmpvaW4oJ1xcdCcpO1xuXG4gICAgICBjbGlwYm9hcmRMaW5lcy5wdXNoKGxpbmUpO1xuICAgIH1cblxuICAgIHJldHVybiBjbGlwYm9hcmRMaW5lcy5qb2luKCdcXG4nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCaW5kaW5nIEV2ZW50cyBSb3cgQWN0aW9uIHRvIFBhcmVudFxuICAgKi9cbiAgaW52b2tlUm93QWN0aW9uR290b0RldGFpbChldmVudDogT25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+KSB7XG5cbiAgICB0aGlzLm9uUm93R290b0RldGFpbC5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIGludm9rZVJvd0FjdGlvbkFkZE5ldyhldmVudDogT25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+KSB7XG5cbiAgICB0aGlzLm9uUm93QWRkTmV3LmVtaXQoZXZlbnQpO1xuICB9XG5cbiAgaW52b2tlUm93QWN0aW9uVmlldyhldmVudDogT25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+KSB7XG5cbiAgICB0aGlzLm9uUm93Vmlldy5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIGludm9rZVJvd0FjdGlvbkxvY2F0aW9uKGV2ZW50OiBPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4pIHtcblxuICAgIHRoaXMub25Sb3dMb2NhdGlvbi5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIGludm9rZVJvd0FjdGlvbkRvY3VtZW50KGV2ZW50OiBPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4pIHtcblxuICAgIHRoaXMub25Sb3dEb2N1bWVudC5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIGludm9rZVJvd0FjdGlvbkNvcHkoZXZlbnQ6IE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPikge1xuXG4gICAgdGhpcy5vblJvd0NvcHkuZW1pdChldmVudCk7XG4gIH1cblxuICBpbnZva2VSb3dBY3Rpb25EZWxldGUoZXZlbnQ6IE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPikge1xuXG4gICAgdGhpcy5vblJvd0RlbGV0ZS5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIGludm9rZVJvd0FjdGlvbkdvdG9MaXN0KGV2ZW50OiBPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4pIHtcblxuICAgIHRoaXMub25Sb3dHb3RvTGlzdC5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIGludm9rZVJvd0FjdGlvbkVkaXQoZXZlbnQ6IE9uZUdyaWRSb3dBY3Rpb25FdmVudDxUPikge1xuXG4gICAgdGhpcy5vblJvd0VkaXQuZW1pdChldmVudCk7XG4gIH1cblxuICBpbnZva2VSb3dBY3Rpb25QcmludChldmVudDogT25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+KSB7XG5cbiAgICB0aGlzLm9uUm93UHJpbnQuZW1pdChldmVudCk7XG4gIH1cblxuICBpbnZva2VSb3dBY3Rpb25IaXN0b3J5KGV2ZW50OiBPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4pIHtcblxuICAgIHRoaXMub25Sb3dIaXN0b3J5LmVtaXQoZXZlbnQpO1xuICB9XG5cbiAgaW52b2tlUm93QWN0aW9uT3B0aW9uKGV2ZW50OiBPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4pIHtcblxuICAgIHRoaXMub25Sb3dPcHRpb24uZW1pdChldmVudCk7XG4gIH1cblxuICBpbnZva2VSb3dBY3Rpb25MYW5ndWFnZShldmVudDogT25lR3JpZFJvd0FjdGlvbkV2ZW50PFQ+KSB7XG5cbiAgICB0aGlzLm9uUm93TGFuZ3VhZ2UuZW1pdChldmVudCk7XG4gIH1cblxuICBpbnZva2VSb3dBY3Rpb25DZWxsT3B0aW9uKGV2ZW50OiBPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4pIHtcblxuICAgIHRoaXMub25Sb3dDZWxsT3B0aW9uLmVtaXQoZXZlbnQpO1xuICB9XG5cbiAgaW52b2tlUm93QWN0aW9uU2VsZWN0aW9uKGV2ZW50OiBPbmVHcmlkUm93QWN0aW9uRXZlbnQ8VD4pIHtcblxuICAgIHRoaXMub25Sb3dTZWxlY3Rpb24uZW1pdChldmVudCk7XG4gIH1cblxuICBpbnZva2VFeHBhbnNpb25DaGFuZ2VkQ2xpY2soZXZlbnQ6IEV4cGFuc2lvbkNoYW5nZWRFdmVudCk6IHZvaWQge1xuXG4gICAgdGhpcy5leHBhbnNpb25DaGFuZ2VkLmVtaXQoZXZlbnQpO1xuICB9XG5cbiAgY2VsbE9wdGlvbk1lbnVTZWxlY3RlZChldmVudDogQ2VsbE9wdGlvbk1lbnVTZWxlY3RlZEV2ZW50KSB7XG5cbiAgICB0aGlzLmNlbGxPcHRpb25TZWxlY3QuZW1pdChldmVudCk7XG4gIH1cblxuICAvKipcbiAgICogU3BlY2lhbCBFdmVudHNcbiAgICovXG4gIHByaXZhdGUgaW52b2tlU2hpZnREb3VibGVDbGljayhub2RlOk9uZVJvd05vZGUsIGNvbHVtbjogT25lQ29sdW1uRGVmKTogdm9pZCB7XG5cbiAgICBsZXQgZXZlbnQ6IE9uZUdyaWRSb3dBY3Rpb25FdmVudCA9IHsgbm9kZSwgY29sdW1uLCBkYXRhOiBub2RlLmRhdGEsIHJvd0luZGV4OiBub2RlLnJvd0luZGV4LCBncmlkVHlwZTogbnVsbCB9O1xuXG4gICAgaWYgKHRoaXMubWFzdGVyRGV0YWlsKSB7XG5cbiAgICAgIGV2ZW50ID0geyAuLi5ldmVudCwgZ3JpZFR5cGU6IHRoaXMuZ3JpZFR5cGUsIG1hc3Rlck5vZGU6IHRoaXMubWFzdGVyTm9kZSB9O1xuICAgIH1cblxuICAgIHRoaXMub25TaGlmdERvdWJsZUNsaWNrLmVtaXQoZXZlbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIENlbGwgRWRpdCBGZWF0dXJlXG4gICAqL1xuICBzdGFydEVkaXQoZXZlbnQ6IE1vdXNlRXZlbnQsIG5vZGU6IE9uZVJvd05vZGU8VD4sIGNvbHVtbjogT25lQ29sdW1uRGVmPFQ+KSB7XG5cbiAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG5cbiAgICBpZiAodGFyZ2V0LnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ2knKSB7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZXZlbnQuc2hpZnRLZXkpIHtcblxuICAgICAgdGhpcy5pbnZva2VTaGlmdERvdWJsZUNsaWNrKG5vZGUsIGNvbHVtbik7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmNlbGxFZGl0YWJsZVBpcGUudHJhbnNmb3JtKG5vZGUuY2VsbFN0YXRlcywgY29sdW1uLCBub2RlLCB0aGlzLmNlbGxTZXJ2aWNlLmVkaXRhYmxlRm4sIHRoaXMuY2VsbFNlcnZpY2UudXBkYXRhYmxlRm4sIHRoaXMuYWxsb3dlZEVkaXQpKSB7XG5cbiAgICAgIHRoaXMuc2VsZWN0ZWRDZWxscy5jbGVhcigpO1xuXG4gICAgICBjb25zdCBjZWxsS2V5ID0gZ2V0Q2VsbEtleShub2RlLnJvd0lkLCBjb2x1bW4uZmllbGQpO1xuXG4gICAgICB0aGlzLnNlbGVjdGVkQ2VsbHMuYWRkKGNlbGxLZXkpO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IHJvd05vZGU6IE9uZVJvd05vZGUgPSB0aGlzLmFwaS5nZXRSb3dOb2RlQnlJZChub2RlLnJvd0lkKTtcblxuICAgIGlmIChyb3dOb2RlKSB7XG5cbiAgICAgIHJvd05vZGUuZWRpdGluZ1tjb2x1bW4uZmllbGRdID0gdHJ1ZTtcblxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG5cbiAgICAgICAgY29uc3QgaW5wdXQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yPEhUTUxJbnB1dEVsZW1lbnQ+KGBbZGF0YS1jZWxsLWlkPVwiJHsgZ2V0Q2VsbEtleShub2RlLnJvd0lkLCBjb2x1bW4uZmllbGQpIH1cIl0gaW5wdXRgKTtcblxuICAgICAgICBpZiAoaW5wdXQpIHtcblxuICAgICAgICAgIGlucHV0LmZvY3VzKCk7XG5cbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IGlucHV0LnZhbHVlO1xuXG4gICAgICAgICAgaWYgKHZhbHVlICYmIFtcInRleHRcIl0uaW5jbHVkZXMoaW5wdXQudHlwZSkpIHtcblxuICAgICAgICAgICAgaW5wdXQuc2V0U2VsZWN0aW9uUmFuZ2UodmFsdWUubGVuZ3RoLCB2YWx1ZS5sZW5ndGgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sIDEwKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2F2ZSBDZWxsIEVkaXQgTW9kZVxuICAgKi9cbiAgc3RvcEVkaXQobm9kZTogT25lUm93Tm9kZTxUPiwgY29sdW1uOiBPbmVDb2x1bW5EZWY8VD4sIGV2ZW50OiBhbnkpIHtcblxuICAgIGxldCByb3dOb2RlOiBPbmVSb3dOb2RlID0gdGhpcy5hcGkuZ2V0Um93Tm9kZUJ5SWQobm9kZS5yb3dJZCk7XG5cbiAgICBpZiAocm93Tm9kZSkge1xuXG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAgIGNvbnN0IHZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlID8/ICcnO1xuICAgICAgdGhpcy5zZXRDZWxsVmFsdWVCeVJvd0lkKG5vZGUucm93SWQsIGNvbHVtbiwgdmFsdWUpO1xuXG4gICAgICByb3dOb2RlLmNlbGxTdGF0ZXMgPSB0aGlzLmNlbGxTZXJ2aWNlLmdlbmVyYXRlQ2VsbFN0YXRlcyhyb3dOb2RlKTtcbiAgICAgIHJvd05vZGUuZWRpdGluZ1tjb2x1bW4uZmllbGRdID0gZmFsc2U7XG5cbiAgICAgIHRoaXMuZXZlbnRTZXJ2aWNlLmRpc3BhdGNoRXZlbnQoJ2NlbGxTdGF0ZUNoYW5nZWQnLCB7XG4gICAgICAgIGRhdGE6IHJvd05vZGUuZGF0YSxcbiAgICAgICAgbm9kZTogcm93Tm9kZSxcbiAgICAgICAgY29sdW1uOiBjb2x1bW5cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDYW5jZWwgQ2VsbCBFZGl0IE1vZGVcbiAgICovXG4gIGNhbmNlbEVkaXQobm9kZTogT25lUm93Tm9kZTxUPiwgY29sdW1uOiBPbmVDb2x1bW5EZWY8VD4pIHtcblxuICAgIGxldCByb3dOb2RlOiBPbmVSb3dOb2RlID0gdGhpcy5hcGkuZ2V0Um93Tm9kZUJ5SWQobm9kZS5yb3dJZCk7XG5cbiAgICBpZiAocm93Tm9kZSkge1xuXG4gICAgICByb3dOb2RlLmVkaXRpbmdbY29sdW1uLmZpZWxkXSA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgQ2VsbCBWYWx1ZVxuICAgKi9cbiAgc2V0Q2VsbFZhbHVlQnlSb3dJZChyb3dJZDogc3RyaW5nLCBjb2x1bW46IE9uZUNvbHVtbkRlZiwgdmFsdWU6IGFueSkge1xuXG4gICAgY29uc3Qgbm9kZSA9IHRoaXMuYXBpLmdldFJvd05vZGVCeUlkKHJvd0lkKTtcblxuICAgIGlmIChub2RlICYmIGNvbHVtbi5maWVsZCkge1xuXG4gICAgICBpZiAoY29sdW1uPy5jZWxsUmVuZGVyZXJQYXJhbXM/LmlucHV0VHlwZSAhPT0gJ251bWJlcicpIHtcblxuICAgICAgICBub2RlLmRhdGFbY29sdW1uLmZpZWxkXSA9IHZhbHVlID09PSAnJyA/IG51bGwgOiB2YWx1ZTtcblxuICAgICAgfSBlbHNlIHtcblxuICAgICAgICBub2RlLmRhdGFbY29sdW1uLmZpZWxkXSA9IHZhbHVlID09PSAnJyA/IG51bGwgOiBOdW1iZXIodmFsdWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWaXJ0dWFsIFNjcm9sbCBQcm9wZXJ0aWVzXG4gICAqL1xuICBzZXRWaXJ0dWFsU2Nyb2xsKGl0ZW1zOiBudW1iZXIgPSAwKTogdm9pZCB7XG5cbiAgICB0aGlzLm1pbkJ1ZmZlclB4ID0gdGhpcy5pdGVtU2l6ZSAqIGl0ZW1zICogMS41O1xuXG4gICAgdGhpcy5tYXhCdWZmZXJQeCA9IHRoaXMubWluQnVmZmVyUHggKiAyO1xuICB9XG5cbiAgLyoqXG4gICAqIFVuc3Vic2NyaWJlIEFsbCBTdWJzY3JpcHRpb25zXG4gICAqL1xuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcblxuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy51bnN1YnNjcmliZSgpO1xuICB9XG59XG4iLCI8ZGl2ICNib2R5UmVmIGNsYXNzPVwib25lLWdyaWQtYm9keVwiPlxuICAgIDxjZGstdmlydHVhbC1zY3JvbGwtdmlld3BvcnRcbiAgICAgICAgY2xhc3M9XCJvbmUtZ3JpZC1ib2R5LXZpZXdwb3J0XCJcbiAgICAgICAgW2l0ZW1TaXplXT1cIml0ZW1TaXplXCJcbiAgICAgICAgW21pbkJ1ZmZlclB4XT1cIm1pbkJ1ZmZlclB4XCJcbiAgICAgICAgW21heEJ1ZmZlclB4XT1cIm1heEJ1ZmZlclB4XCJcbiAgICAgICAgKHNjcm9sbCk9XCJvbkJvZHlTY3JvbGwoJGV2ZW50KVwiPlxuXG4gICAgICAgIDxuZy1jb250YWluZXIgKmNka1ZpcnR1YWxGb3I9XCJsZXQgbm9kZSBvZiBub2RlczsgdHJhY2tCeTogdHJhY2tCeVJvd0lkO1wiPlxuICAgICAgICAgICAgXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwib25lLXJvd1wiIFthdHRyLmRhdGEtcm93LWlkXT1cIm5vZGUucm93SWRcIiBbY2xhc3Mub25lLXJvdy1zZWxlY3RlZF09XCJub2RlLnNlbGVjdGVkXCI+XG4gICAgICAgICAgICAgICAgQGZvciAoY29sIG9mIGNvbHVtbkRlZnM7IHRyYWNrIGNvbC5maWVsZDspIHtcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJjZWxsVGVtcGxhdGVcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyBub2RlLCByb3dJbmRleDogbm9kZS5yb3dJbmRleCwgY29sdW1uOiBjb2wgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8IS0tIEN1c3RvbSBEZXRhaWwgQ29tcG9uZW50IC0tPlxuICAgICAgICAgICAgIEBpZihub2RlLmxlYWYgJiYgbm9kZS5kZXRhaWxBY3RpdmUgJiYgbm9kZT8uZGV0YWlsUmVuZGVyZXJDb21wb25lbnQpIHtcbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgIG9uZUNlbGxSZW5kZXJlckNvbXBvbmVudFxuICAgICAgICAgICAgICAgICAgICBbY2VsbFJlbmRlcmVyQ29tcG9uZW50XT1cIm5vZGU/LmRldGFpbFJlbmRlcmVyQ29tcG9uZW50XCJcbiAgICAgICAgICAgICAgICAgICAgW3BhcmFtc109XCJ7IGRhdGE6IG5vZGUuZGF0YSwgcm93SW5kZXg6IG5vZGUucm93SW5kZXgsIG5vZGU6IG5vZGUsIGNvbnRleHQ6IGNvbnRleHQgfVwiPlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICA8IS0tIE1hc3RlciBEZXRhaWwgR3JpZCAodGVtcGxhdGUgcHJvdmlkZWQgYnkgdGhlIHBhcmVudCBvbmUtZ3JpZCB0byBhdm9pZCBhIGNvbXBpbGUtdGltZSBpbXBvcnQgY3ljbGUpIC0tPlxuICAgICAgICAgICAgQGlmIChtYXN0ZXJEZXRhaWwgJiYgbm9kZS5leHBhbmRlZCAmJiBub2RlPy5kZXRhaWxSb3dEYXRhKSB7XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm9uZS1yb3ctZGV0YWlsLWNvbnRhaW5lclwiIFthdHRyLmRhdGEtcm93LWlkXT1cIm5vZGUucm93SWQgKyAnLWRldGFpbCdcIj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiZGV0YWlsR3JpZFRlbXBsYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7ICRpbXBsaWNpdDogbm9kZSwgbm9kZTogbm9kZSB9XCI+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgfVxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgQGlmICghbm9kZXM/Lmxlbmd0aCkge1xuICAgICAgICAgICAgPGRpdiBzdHlsZT1cIndpZHRoOiBtYXgtY29udGVudDsgYm9yZGVyLXRvcDogMXB4IHNvbGlkIHRyYW5zcGFyZW50O1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgW3N0eWxlLndpZHRoLnB4XT1cInJvd1dpZHRoXCI+PC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuICAgIDwvY2RrLXZpcnR1YWwtc2Nyb2xsLXZpZXdwb3J0PlxuICAgIEBpZiAoIW5vZGVzPy5sZW5ndGgpIHtcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJvbmUtZ3JpZC1lbXB0eS1tZXNzYWdlXCIgc3R5bGU9XCJwb3NpdGlvbjogYWJzb2x1dGU7IHRvcDogNTAlOyBsZWZ0OiA1MCU7IHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIC01MCUpO1wiPk5vIFJvd3MgdG8gU2hvdzwvc3Bhbj5cbiAgICB9XG48L2Rpdj5cblxuPCEtLSBNYXN0ZXIgQ29sdW1uIFRlbXBsYXRlICAtLT5cbjxuZy10ZW1wbGF0ZSAjY2VsbFRlbXBsYXRlIGxldC1ub2RlPVwibm9kZVwiIGxldC1yb3dJbmRleD1cInJvd0luZGV4XCIgbGV0LWNvbHVtbj1cImNvbHVtblwiPlxuICAgIDxkaXZcbiAgICAgICAgY2xhc3M9XCJvbmUtY29sdW1uXCJcbiAgICAgICAgW2F0dHIuZGF0YS1jZWxsLWlkXT1cIm5vZGUucm93SWQgfCBjZWxsS2V5OmNvbHVtbi5maWVsZFwiXG4gICAgICAgIFtzdHlsZS53aWR0aC5weF09XCJjb2x1bW4/LndpZHRoXCJcbiAgICAgICAgW3N0eWxlLm1pbi13aWR0aC5weF09XCJjb2x1bW4/Lm1pbldpZHRoXCJcbiAgICAgICAgW3N0eWxlLm1heC13aWR0aC5weF09XCJjb2x1bW4/Lm1heFdpZHRoXCJcbiAgICAgICAgW2NsYXNzLm9uZS1jb2x1bW4tYm9yZGVyLXRvcF09XCJtYXN0ZXJEZXRhaWwgJiYgbm9kZXM/Lmxlbmd0aCA+IDAgJiYgbm9kZXNbbm9kZS5yb3dJbmRleCAtIDFdPy5leHBhbmRlZFwiXG4gICAgICAgIFtjbGFzcy5vbmUtY2VsbC1zZWxlY3RlZF09XCJzZWxlY3RlZENlbGxzIHwgY2VsbFNlbGVjdGVkOm5vZGUucm93SWQ6Y29sdW1uLmZpZWxkXCJcbiAgICAgICAgW2NsYXNzLm9uZS1jZWxsLWludmFsaWRdPVwibm9kZS5jZWxsU3RhdGVzIHwgY2VsbEludmFsaWQ6bm9kZS5kYXRhW2NvbHVtbi5maWVsZF06Y29sdW1uOm5vZGU6YWxsb3dlZEVkaXQ6c3VibWl0dGVkXCJcbiAgICAgICAgKGRibGNsaWNrKT1cInN0YXJ0RWRpdCgkZXZlbnQsIG5vZGUsIGNvbHVtbilcIlxuICAgICAgICAobW91c2Vkb3duKT1cInN0YXJ0U2VsZWN0aW9uKG5vZGUucm93SWQsIGNvbHVtbi5maWVsZClcIlxuICAgICAgICAobW91c2VlbnRlcik9XCJleHRlbmRTZWxlY3Rpb24obm9kZS5yb3dJZCwgY29sdW1uLmZpZWxkKVwiXG4gICAgICAgIChtb3VzZXVwKT1cImVuZFNlbGVjdGlvbigpXCI+XG5cbiAgICAgICAgPCEtLSBPbmUgR3JpZCBDZWxsIE9wdGlvbiAtLT5cbiAgICAgICAgQGlmIChub2RlLmNlbGxPcHRpb25zW2NvbHVtbi5maWVsZF0pIHtcbiAgICAgICAgICAgIDxvbmUtZ3JpZC1jZWxsLW9wdGlvbi1tZW51XG4gICAgICAgICAgICAgICAgI2NvbnRleHRPcHRpb25NZW51UmVmXG4gICAgICAgICAgICAgICAgW25vZGVdPVwibm9kZVwiXG4gICAgICAgICAgICAgICAgW2NvbHVtbl09XCJjb2x1bW5cIlxuICAgICAgICAgICAgICAgIFtvcHRpb25zXT1cImNvbHVtbi5jZWxsT3B0aW9uTWVudVwiXG4gICAgICAgICAgICAgICAgKGNlbGxPcHRpb25NZW51U2VsZWN0KT1cImNlbGxPcHRpb25NZW51U2VsZWN0ZWQoJGV2ZW50KVwiLz5cbiAgICAgICAgfVxuXG4gICAgICAgIDwhLS0gR3JpZCBDZWxsIFRlbXBsYXRlIC0tPlxuICAgICAgICBAaWYoY29sdW1uPy5jZWxsUmVuZGVyZXJDb21wb25lbnQpIHtcbiAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICBvbmVDZWxsUmVuZGVyZXJDb21wb25lbnRcbiAgICAgICAgICAgICAgICBbY2VsbFJlbmRlcmVyQ29tcG9uZW50XT1cImNvbHVtbj8uY2VsbFJlbmRlcmVyQ29tcG9uZW50XCJcbiAgICAgICAgICAgICAgICBbcGFyYW1zXT1cInsgZGF0YTogbm9kZS5kYXRhLCBmaWVsZDogY29sdW1uLmZpZWxkLCByb3dJbmRleDogbm9kZS5yb3dJbmRleCwgY29sdW1uRGVmOiBjb2x1bW4sIG5vZGU6IG5vZGUsIGNvbnRleHQ6IGNvbnRleHQgfVwiPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIH1cbiAgICAgICAgQGVsc2UgaWYgKG5vZGUuZWRpdGluZ1tjb2x1bW4uZmllbGRdKSB7XG4gICAgICAgICAgICA8IS0tIENlbGwgRWRpdGluZyBJbnB1dCAtLT5cbiAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cIm9uZS1jZWxsLWlucHV0XCJcbiAgICAgICAgICAgICAgICBuYW1lPVwie3sgbm9kZS5yb3dJZCArICcnICsgY29sdW1uLmZpZWxkIH19XCJcbiAgICAgICAgICAgICAgICBvbmVDZWxsSW5wdXRWYWxpZGF0b3JcbiAgICAgICAgICAgICAgICBbdmFsaWRhdGlvblR5cGVdPVwiY29sdW1uPy5jZWxsUmVuZGVyZXJQYXJhbXM/LmlucHV0VHlwZSA9PT0gJ251bWJlcicgPyAnbnVtYmVyJyA6ICdub25lJ1wiXG4gICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cImNvbHVtbj8uY2VsbFJlbmRlcmVyUGFyYW1zPy5wbGFjZWhvbGRlclwiXG4gICAgICAgICAgICAgICAgW3R5cGVdPVwiY29sdW1uPy5jZWxsUmVuZGVyZXJQYXJhbXM/LmlucHV0VHlwZSA9PT0gJ251bWJlcicgPyAndGV4dCcgOiBjb2x1bW4/LmNlbGxSZW5kZXJlclBhcmFtcz8uaW5wdXRUeXBlXCJcbiAgICAgICAgICAgICAgICBbdmFsdWVdPVwibm9kZT8uZGF0YVtjb2x1bW4/LmZpZWxkXVwiXG4gICAgICAgICAgICAgICAgW21heExlbmd0aF09XCIyNTBcIlxuICAgICAgICAgICAgICAgIChibHVyKT1cInN0b3BFZGl0KG5vZGUsIGNvbHVtbiwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgKGtleWRvd24uZW50ZXIpPVwic3RvcEVkaXQobm9kZSwgY29sdW1uLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAoa2V5ZG93bi5lc2MpPVwiY2FuY2VsRWRpdChub2RlLCBjb2x1bW4pXCJcbiAgICAgICAgICAgIC8+XG4gICAgICAgIH1cbiAgICAgICAgQGVsc2UgaWYgKGNvbHVtbj8uY2VsbFJlbmRlcmVyKSB7XG4gICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgW25nU3R5bGVdPVwieyB3aWR0aDogY29sdW1uLndpZHRoICsgJ3B4JyAsIHBvc2l0aW9uOiAncmVsYXRpdmUnIH1cIlxuICAgICAgICAgICAgICAgIFtpbm5lckhUTUxdPVwibm9kZS5jZWxsU3RhdGVzIHwgY2VsbFN0YXRlUmVuZGVyZXI6Y29sdW1uLmZpZWxkXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MuZWRpdGFibGUtYWN0aXZlXT1cIm5vZGUuY2VsbFN0YXRlcyB8IGNlbGxFZGl0YWJsZTpjb2x1bW46bm9kZTpjZWxsU2VydmljZS5lZGl0YWJsZUZuOmNlbGxTZXJ2aWNlLnVwZGF0YWJsZUZuOmFsbG93ZWRFZGl0XCI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuICAgICAgICBAZWxzZSB7XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwib25lLWNlbGxcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5hbGlnbi1jb250ZW50LWxlZnRdPVwiY29sdW1uPy5hbGlnbkNvbnRlbnQgPT09ICdsZWZ0J1wiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmFsaWduLWNvbnRlbnQtY2VudGVyXT1cImNvbHVtbj8uYWxpZ25Db250ZW50ID09PSAnY2VudGVyJ1wiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmFsaWduLWNvbnRlbnQtcmlnaHRdPVwiY29sdW1uPy5hbGlnbkNvbnRlbnQgPT09ICdyaWdodCdcIlxuICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cImNvbFNlcnZpY2UucmVzb2x2ZUNlbGxQcmVzZW50YXRpb24oY29sdW1uLCB7IG5vZGUsIGRhdGE6IG5vZGUuZGF0YSwgY29sdW1uRGVmOiBjb2x1bW4gfSkuX3Jlc29sdmVkQ2VsbENsYXNzXCJcbiAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJjb2xTZXJ2aWNlLnJlc29sdmVDZWxsUHJlc2VudGF0aW9uKGNvbHVtbiwgeyBub2RlLCBkYXRhOiBub2RlLmRhdGEsIGNvbHVtbkRlZjogY29sdW1uIH0pLl9yZXNvbHZlZENlbGxTdHlsZVwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLnBhZGRpbmctbGVmdC5weF09XCJjb2x1bW4uYXV0b0dyb3VwRmllbGQgJiYgbm9kZS5sZXZlbCB8IGNlbGxMZXZlbFBhZGRpbmc6MjRcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5vbmUtY2VsbC1hbGxvd2VkLWVkaXQtYWN0aXZlXT1cIm5vZGUuY2VsbFN0YXRlcyB8IGNlbGxFZGl0YWJsZTpjb2x1bW46bm9kZTpjZWxsU2VydmljZS5lZGl0YWJsZUZuOmNlbGxTZXJ2aWNlLnVwZGF0YWJsZUZuOmFsbG93ZWRFZGl0XCI+XG5cbiAgICAgICAgICAgICAgICA8IS0tIENlbGwgQ2hlY2tib3ggU2VsZWN0aW9uIC0tPlxuICAgICAgICAgICAgICAgIEBpZiAoY29sdW1uPy5jaGVja2JveFNlbGVjdGlvbikge1xuICAgICAgICAgICAgICAgICAgICA8b25lLWdyaWQtY2hlY2tib3hcbiAgICAgICAgICAgICAgICAgICAgICAgIFtub2RlXT1cIm5vZGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2FsbG93ZWRFZGl0XT1cImFsbG93ZWRFZGl0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFthcGldPVwiYXBpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChvblJvd1NlbGVjdGlvbik9XCJpbnZva2VSb3dBY3Rpb25TZWxlY3Rpb24oJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgPCEtLSBFeHBhbmQgJiBDb2xsYXBzZSBJY29uIC0tPlxuICAgICAgICAgICAgICAgIEBpZiAoKChub2RlPy5ncm91cCB8fCBkZXRhaWxSZW5kZXJlckNvbXBvbmVudCkgJiYgY29sdW1uPy5hdXRvR3JvdXBGaWVsZCkgfHwgKG1hc3RlckRldGFpbCAmJiBub2RlPy5leHBhbmRhYmxlICYmIGdyaWRUeXBlID09PSAnbWFzdGVyJyAmJiBjb2x1bW4/Lm1hc3Rlckdyb3VwRmllbGQpKSB7XG4gICAgICAgICAgICAgICAgICAgIDxvbmUtZ3JpZC1jZWxsLWdyb3VwLXJlbmRlcmVyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbm9kZV09XCJub2RlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFttYXN0ZXJEZXRhaWxdPVwibWFzdGVyRGV0YWlsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtkZXRhaWxDZWxsUmVuZGVyZXJQYXJhbXNdPVwiZGV0YWlsQ2VsbFJlbmRlcmVyUGFyYW1zXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtkZXRhaWxSZW5kZXJlckNvbXBvbmVudF09XCJkZXRhaWxSZW5kZXJlckNvbXBvbmVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoZXhwYW5zaW9uQ2hhbmdlZCk9XCJpbnZva2VFeHBhbnNpb25DaGFuZ2VkQ2xpY2soJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgQGlmKGNvbHVtbj8uY2VsbFJlbmRlcmVyQ29tcG9uZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uZUNlbGxSZW5kZXJlckNvbXBvbmVudFxuICAgICAgICAgICAgICAgICAgICAgICAgW2NlbGxSZW5kZXJlckNvbXBvbmVudF09XCJjb2x1bW4/LmNlbGxSZW5kZXJlckNvbXBvbmVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbcGFyYW1zXT1cInsgZGF0YTogbm9kZS5kYXRhLCBmaWVsZDogY29sdW1uLmZpZWxkLCByb3dJbmRleDogbm9kZS5yb3dJbmRleCwgY29sdW1uRGVmOiBjb2x1bW4sIG5vZGU6IG5vZGUsIGNvbnRleHQ6IGNvbnRleHQgfVwiPlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICA8IS0tIENlbGwgVmFsdWUgT1IgUGxhY2Vob2xkZXIgLS0+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgb25lQ2VsbFRleHRFeHBhbmQgY2xhc3M9XCJvbmUtY2VsbC10ZXh0XCIgW2NsYXNzLm9uZS1jZWxsLXBsYWNlaG9sZGVyXT1cIm5vZGUuY2VsbFN0YXRlc1tjb2x1bW4uZmllbGRdPy50eXBlID09PSAncGxhY2Vob2xkZXInXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICB7eyAobm9kZS5jZWxsU3RhdGVzIHwgY2VsbFN0YXRlUmVuZGVyZXI6Y29sdW1uLmZpZWxkKSB9fVxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICA8IS0tIENlbGwgQWN0aW9uIEJ1dHRvbnMgLS0+XG4gICAgICAgICAgICAgICAgQGlmIChjb2x1bW4uY2VsbFJlbmRlcmVyUGFyYW1zIHwgY2VsbEFjdGlvbkJ1dHRvbkVuYWJsZSkge1xuICAgICAgICAgICAgICAgICAgICA8b25lLWdyaWQtcm93LWFjdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgW25nU3R5bGVdPVwieyBtYXJnaW5MZWZ0OiAnYXV0bycgfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbY29sdW1uXT1cImNvbHVtblwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbm9kZV09XCJub2RlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFthbGxvd2VkRWRpdF09XCJhbGxvd2VkRWRpdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbWFzdGVyTm9kZV09XCJtYXN0ZXJOb2RlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFttYXN0ZXJEZXRhaWxdPVwibWFzdGVyRGV0YWlsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtncmlkVHlwZV09XCJncmlkVHlwZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbY29udGV4dF09XCJjb250ZXh0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjZWxsUmVuZGVyZXJQYXJhbXNdPVwiY29sdW1uPy5jZWxsUmVuZGVyZXJQYXJhbXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKG9uUm93R290b0RldGFpbCk9XCJpbnZva2VSb3dBY3Rpb25Hb3RvRGV0YWlsKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKG9uUm93QWRkTmV3KT1cImludm9rZVJvd0FjdGlvbkFkZE5ldygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChvblJvd1ZpZXcpPVwiaW52b2tlUm93QWN0aW9uVmlldygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChvblJvd0xvY2F0aW9uKT1cImludm9rZVJvd0FjdGlvbkxvY2F0aW9uKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKG9uUm93RG9jdW1lbnQpPVwiaW52b2tlUm93QWN0aW9uRG9jdW1lbnQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAob25Sb3dDb3B5KT1cImludm9rZVJvd0FjdGlvbkNvcHkoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAob25Sb3dEZWxldGUpPVwiaW52b2tlUm93QWN0aW9uRGVsZXRlKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKG9uUm93R290b0xpc3QpPVwiaW52b2tlUm93QWN0aW9uR290b0xpc3QoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAob25Sb3dFZGl0KT1cImludm9rZVJvd0FjdGlvbkVkaXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAob25Sb3dQcmludCk9XCJpbnZva2VSb3dBY3Rpb25QcmludCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChvblJvd0hpc3RvcnkpPVwiaW52b2tlUm93QWN0aW9uSGlzdG9yeSgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChvblJvd09wdGlvbik9XCJpbnZva2VSb3dBY3Rpb25PcHRpb24oJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAob25Sb3dMYW5ndWFnZSk9XCJpbnZva2VSb3dBY3Rpb25MYW5ndWFnZSgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChvblJvd0NlbGxPcHRpb24pPVwiaW52b2tlUm93QWN0aW9uQ2VsbE9wdGlvbigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuICAgIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==
|
|
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==
|