@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.
Files changed (66) hide show
  1. package/README.md +49 -4
  2. package/esm2022/lib/components/one-grid/one-grid.component.mjs +67 -16
  3. package/esm2022/lib/components/one-grid-body/one-grid-body.component.mjs +282 -30
  4. package/esm2022/lib/components/one-grid-cell-group-renderer/one-grid-cell-group-renderer.component.mjs +10 -7
  5. package/esm2022/lib/components/one-grid-cell-option-menu/one-grid-cell-option-menu.component.mjs +60 -4
  6. package/esm2022/lib/components/one-grid-checkbox-header/one-grid-checkbox-header.component.mjs +14 -5
  7. package/esm2022/lib/components/one-grid-header/one-grid-header.component.mjs +50 -13
  8. package/esm2022/lib/components/one-grid-pagination/one-grid-pagination.component.mjs +39 -15
  9. package/esm2022/lib/components/one-grid-row-action/one-grid-row-action.component.mjs +54 -8
  10. package/esm2022/lib/components/one-grid-row-drag-handle/one-grid-row-drag-handle.component.mjs +110 -0
  11. package/esm2022/lib/core/directives/one-cell-renderer-component.directive.mjs +9 -2
  12. package/esm2022/lib/core/directives/one-cell-text-expand.directive.mjs +33 -51
  13. package/esm2022/lib/core/instants/one-grid-api.class.mjs +429 -166
  14. package/esm2022/lib/core/instants/one-row-node.class.mjs +103 -37
  15. package/esm2022/lib/core/models/one-column-def-types.model.mjs +1 -1
  16. package/esm2022/lib/core/models/one-event-types.model.mjs +1 -1
  17. package/esm2022/lib/core/models/one-grid-types.model.mjs +1 -1
  18. package/esm2022/lib/core/models/one-row-drag.model.mjs +2 -0
  19. package/esm2022/lib/core/models/one-row.model.mjs +1 -1
  20. package/esm2022/lib/core/models/one-tree-data.model.mjs +1 -1
  21. package/esm2022/lib/core/models/one-validation.model.mjs +1 -1
  22. package/esm2022/lib/core/pipes/cell-field-value-empty.pipe.mjs +8 -3
  23. package/esm2022/lib/core/pipes/column-sort-state.pipe.mjs +3 -1
  24. package/esm2022/lib/core/services/og-column.service.mjs +120 -13
  25. package/esm2022/lib/core/services/one-grid-cell.service.mjs +123 -20
  26. package/esm2022/lib/core/services/one-grid-row-drag.service.mjs +351 -0
  27. package/esm2022/lib/core/services/one-grid-selection.service.mjs +19 -6
  28. package/esm2022/lib/helpers/one-column-def.helper.mjs +27 -2
  29. package/esm2022/lib/helpers/one-filter.helper.mjs +71 -12
  30. package/esm2022/lib/helpers/one-validation.helper.mjs +7 -2
  31. package/esm2022/lib/index.mjs +8 -1
  32. package/esm2022/lib/one-grid.module.mjs +7 -16
  33. package/fesm2022/one-grid-core-angular.mjs +2046 -503
  34. package/fesm2022/one-grid-core-angular.mjs.map +1 -1
  35. package/lib/components/one-grid/one-grid.component.d.ts +16 -1
  36. package/lib/components/one-grid-body/one-grid-body.component.d.ts +132 -5
  37. package/lib/components/one-grid-cell-group-renderer/one-grid-cell-group-renderer.component.d.ts +6 -1
  38. package/lib/components/one-grid-cell-option-menu/one-grid-cell-option-menu.component.d.ts +19 -2
  39. package/lib/components/one-grid-checkbox-header/one-grid-checkbox-header.component.d.ts +5 -2
  40. package/lib/components/one-grid-header/one-grid-header.component.d.ts +15 -7
  41. package/lib/components/one-grid-pagination/one-grid-pagination.component.d.ts +24 -5
  42. package/lib/components/one-grid-row-action/one-grid-row-action.component.d.ts +44 -0
  43. package/lib/components/one-grid-row-drag-handle/one-grid-row-drag-handle.component.d.ts +39 -0
  44. package/lib/core/directives/one-cell-text-expand.directive.d.ts +21 -9
  45. package/lib/core/instants/one-grid-api.class.d.ts +212 -26
  46. package/lib/core/instants/one-row-node.class.d.ts +67 -14
  47. package/lib/core/models/one-column-def-types.model.d.ts +89 -15
  48. package/lib/core/models/one-event-types.model.d.ts +24 -1
  49. package/lib/core/models/one-grid-types.model.d.ts +36 -1
  50. package/lib/core/models/one-row-drag.model.d.ts +44 -0
  51. package/lib/core/models/one-row.model.d.ts +0 -5
  52. package/lib/core/models/one-tree-data.model.d.ts +13 -0
  53. package/lib/core/models/one-validation.model.d.ts +12 -2
  54. package/lib/core/pipes/column-sort-state.pipe.d.ts +1 -1
  55. package/lib/core/services/og-column.service.d.ts +44 -3
  56. package/lib/core/services/one-grid-cell.service.d.ts +52 -4
  57. package/lib/core/services/one-grid-row-drag.service.d.ts +113 -0
  58. package/lib/core/services/one-grid-selection.service.d.ts +9 -0
  59. package/lib/helpers/one-column-def.helper.d.ts +19 -1
  60. package/lib/helpers/one-filter.helper.d.ts +29 -4
  61. package/lib/index.d.ts +7 -0
  62. package/lib/one-grid.module.d.ts +17 -19
  63. package/package.json +1 -2
  64. package/scss/_one-grid.scss +389 -17
  65. package/esm2022/lib/core/pipes/cell-disable-resolver.pipe.mjs +0 -26
  66. package/lib/core/pipes/cell-disable-resolver.pipe.d.ts +0 -9
@@ -1,5 +1,5 @@
1
1
  import { OneRowNode } from "./one-row-node.class";
2
- import { filterTreeNode } from "../../helpers/one-filter.helper";
2
+ import { filterTreeNode, isFilterActive } from "../../helpers/one-filter.helper";
3
3
  import { getFieldValue } from "../../helpers/one-cell.helper";
4
4
  import { v4 as uuidv4 } from 'uuid';
5
5
  import { Injectable } from "@angular/core";
@@ -11,6 +11,30 @@ import * as i4 from "../services/one-grid-event.service";
11
11
  import * as i5 from "../services/one-grid-selection.service";
12
12
  import * as i6 from "../services/one-grid-expansion.service";
13
13
  export class OneGridApi {
14
+ /** Unique per grid instance, assigned during `init`. */
15
+ get id() {
16
+ return this._id;
17
+ }
18
+ /** The `[context]` the grid was given. */
19
+ get context() {
20
+ return this._context;
21
+ }
22
+ /** Selection mode, captured during `init`. Changing the input later has no effect. */
23
+ get rowSelection() {
24
+ return this._rowSelection;
25
+ }
26
+ /** Which role this instance plays: simple, master, detail or tree. */
27
+ get apiType() {
28
+ return this._apiType;
29
+ }
30
+ /** Every node the grid holds, in flattened order. */
31
+ get rowNodes() {
32
+ return this._rowNodes;
33
+ }
34
+ /** The sort model currently applied. Change it with `onSortChanged`. */
35
+ get sortModel() {
36
+ return this._sortModel;
37
+ }
14
38
  constructor(columnService, rowService, cellService, eventService, selectionService, expansionService) {
15
39
  this.columnService = columnService;
16
40
  this.rowService = rowService;
@@ -18,17 +42,18 @@ export class OneGridApi {
18
42
  this.eventService = eventService;
19
43
  this.selectionService = selectionService;
20
44
  this.expansionService = expansionService;
21
- this.context = null;
22
- this.rowSelection = null;
23
- this.apiType = null;
24
- this.rowNodes = [];
25
- this.sortModel = [];
45
+ this._context = null;
46
+ this._rowSelection = null;
47
+ this._apiType = null;
48
+ this._rowNodes = [];
49
+ this._sortModel = [];
26
50
  this.rowHeight = 26;
27
51
  this.headerRowHeight = 32;
28
52
  this._currentIndex = 0;
29
53
  this._quickFilterValue = null;
30
54
  this._activeFilters = [];
31
55
  this._visibleRowNodes = [];
56
+ this._pinnedRowNodes = { top: [], bottom: [] };
32
57
  this._originalRowNodes = new Map();
33
58
  this._nodeCleanupMap = new Map(); // Cleanup registry (prevents memory leaks)
34
59
  this._destroyed = false;
@@ -38,63 +63,83 @@ export class OneGridApi {
38
63
  this.groupDefaultExpanded = 0;
39
64
  this.masterDetail = false;
40
65
  }
41
- init(gridApiType, rowSelection, columnDefs, defaultColumnDef, context, masterDetail, detailCellRendererParams, detailRendererComponent, treeData, groupColumnDefs) {
42
- this.id = uuidv4();
43
- this.apiType = gridApiType;
44
- this.rowSelection = rowSelection;
45
- this.context = context;
66
+ /**
67
+ * Stand the grid up. Called by `OneGridComponent` from `ngOnInit`.
68
+ *
69
+ * Takes a single `OneGridInitOptions` rather than the ten positional
70
+ * arguments it used to, so a call site reads as the configuration it is and
71
+ * a new option no longer means editing every caller.
72
+ *
73
+ * @internal Applications obtain a ready-made API from `(onGridReady)`; they
74
+ * should never call this themselves.
75
+ */
76
+ init(options) {
77
+ const { gridType, columnDefs, defaultColumnDef = {}, groupColumnDefs = [], context = null, rowSelection = null, masterDetail = false, detailCellRendererParams = null, detailRendererComponent = null, treeData = false, } = options;
78
+ this._id = uuidv4();
79
+ this._apiType = gridType;
80
+ this._rowSelection = rowSelection;
81
+ this._context = context;
46
82
  this.masterDetail = masterDetail;
47
83
  this.detailCellRendererParams = detailCellRendererParams;
48
84
  this.detailRendererComponent = detailRendererComponent;
49
85
  this.treeData = treeData;
50
- this.selectionService.setSelectionMode(this.rowSelection);
51
- this.rowService.setGetRowIdFn(this.context?.componentParent?.getRowId ?? null);
86
+ this.selectionService.setSelectionMode(rowSelection);
87
+ this.rowService.setGetRowIdFn(context?.componentParent?.getRowId ?? null);
52
88
  this.cellService.applyColumnDefs(columnDefs, context);
53
- this.columnService.initColumnDefs(defaultColumnDef, columnDefs, groupColumnDefs);
89
+ this.cellService.setGridApi(this);
90
+ this.columnService.initColumnDefs(defaultColumnDef, columnDefs, groupColumnDefs, context);
54
91
  const columnState = this.columnService.getColumnState();
55
92
  setTimeout(() => this.eventService.dispatchEvent('columnChanged', columnState));
56
93
  }
57
94
  /**
58
- * Create Row Node & Clear All State IDS
95
+ * Replace every row, discarding selection and expansion.
96
+ *
97
+ * Use this when the rows represent something new. To swap the data while
98
+ * keeping what the user has selected and opened, use `updateRowData`.
59
99
  */
60
100
  setRowData(rowData) {
61
- const validRowIds = new Set();
62
- // Clear All State IDS
63
- this.selectionService.deselectAll();
64
- this.expansionService.clear();
65
- // Build New Row Nodes
66
- this.buildRowNodes(rowData, null, 0, validRowIds);
67
- // Apply Filter
68
- this.applyFilters();
69
- // Remove invalid nodes from map
70
- for (const rowId of this._originalRowNodes.keys()) {
71
- if (!validRowIds.has(rowId)) {
72
- this._originalRowNodes.delete(rowId);
73
- }
74
- }
101
+ this.rebuildRows(rowData, true);
75
102
  }
76
103
  /**
77
- * Create Row Nodes & Not Clear State IDS
104
+ * Replace every row, keeping selection and expansion.
105
+ *
106
+ * State is keyed by row id, so this only preserves anything if the grid has a
107
+ * `context.componentParent.getRowId` — otherwise each rebuild mints new ids
108
+ * and there is nothing left to match against.
78
109
  */
79
110
  updateRowData(rowData) {
111
+ this.rebuildRows(rowData, false);
112
+ }
113
+ /**
114
+ * The one row-loading path. `setRowData` and `updateRowData` differed only in
115
+ * whether they cleared the state services first, so everything else — build,
116
+ * filter, prune — lives here once.
117
+ */
118
+ rebuildRows(rowData, resetState) {
119
+ if (this._destroyed)
120
+ return;
121
+ if (resetState) {
122
+ this.selectionService.deselectAll();
123
+ this.expansionService.clear();
124
+ }
80
125
  const validRowIds = new Set();
81
- // Build New Row Nodes
82
126
  this.buildRowNodes(rowData, null, 0, validRowIds);
83
- // Apply Filter
127
+ // Re-apply the active sort. `buildRowNodes` rebuilds the row list in the
128
+ // order the data arrived, so without this a data update silently returned
129
+ // the rows to that order while `sortModel` — and therefore the header's
130
+ // sort arrow — still said they were sorted. Sorting before filtering
131
+ // because filtering only sets visibility on whatever order this leaves.
132
+ if (this._sortModel.length > 0)
133
+ this.applySorting();
84
134
  this.applyFilters();
85
- // Remove invalid nodes from map
86
- for (const rowId of this._originalRowNodes.keys()) {
87
- if (!validRowIds.has(rowId)) {
88
- this._originalRowNodes.delete(rowId);
89
- }
90
- }
135
+ this.pruneRemovedNodes(validRowIds);
91
136
  }
92
137
  /**
93
138
  * Recursive Build Row Nodes (Optimized)
94
139
  */
95
140
  buildRowNodes(rowData, parent = null, level = 0, validRowIds = new Set(), expandedIds = new Set(this.expansionService.getExpandedIds()), collapsedIds = new Set(this.expansionService.getCollapsedIds()), selectedIds = new Set(this.selectionService.getSelectedIds())) {
96
141
  if (parent === null) {
97
- this.rowNodes = [];
142
+ this._rowNodes = [];
98
143
  this._currentIndex = 0;
99
144
  }
100
145
  if (!rowData?.length)
@@ -120,7 +165,11 @@ export class OneGridApi {
120
165
  }
121
166
  }
122
167
  const childrenExist = children && children.length >= 0;
123
- node.group = this.masterDetail ? false : childrenExist;
168
+ // Coerced, because `childrenExist` is `children && children.length >= 0`
169
+ // — which is `null` for a row with no children field, not `false`. These
170
+ // are declared `boolean`, and assigning null made every consumer compare
171
+ // truthiness instead of the value.
172
+ node.group = this.masterDetail ? false : !!childrenExist;
124
173
  node.leaf = this.masterDetail ? true : !node.group;
125
174
  node.leafGroup = this.masterDetail ? false : (node.group && !childrenExist);
126
175
  node.expandable = this.masterDetail ? true : (node.group && !node.leafGroup);
@@ -128,11 +177,11 @@ export class OneGridApi {
128
177
  node.setExpanded(expandedIds.has(rowId) ? true : collapsedIds.has(rowId) ? false : defaultExpanded);
129
178
  node.setSelected(selectedIds.has(rowId));
130
179
  node.setCellStates(this.cellService.generateCellStates(node));
131
- if (this.masterDetail && this.apiType === 'master') {
132
- this.getDetailRowData({ data, node: node, successCallback: (detailRowData) => node.setDetailRowData(detailRowData) });
180
+ if (this.masterDetail && this._apiType === 'master') {
181
+ this._getDetailRowData({ data, node: node, successCallback: (detailRowData) => node.setDetailRowData(detailRowData) });
133
182
  }
134
183
  this._currentIndex++;
135
- this.rowNodes.push(node);
184
+ this._rowNodes.push(node);
136
185
  nodes.push(node);
137
186
  node.children = this.treeData && childrenExist ? this.buildRowNodes(children || [], node, level + 1, validRowIds, expandedIds, collapsedIds, selectedIds) : [];
138
187
  }
@@ -144,19 +193,37 @@ export class OneGridApi {
144
193
  applyFilters() {
145
194
  const filters = this._activeFilters;
146
195
  const quick = this._quickFilterValue?.toLowerCase() ?? '';
147
- this.rowNodes.forEach(node => filterTreeNode(node, filters, quick));
196
+ // The fields the grid actually shows. Without them the quick filter falls
197
+ // back to every property on the row, which lets a user match on data that
198
+ // has no column and never appears on screen.
199
+ const fields = this.quickFilterFields();
200
+ this._rowNodes.forEach(node => filterTreeNode(node, filters, quick, fields));
148
201
  this.refreshVisibleNodes();
149
202
  }
203
+ /**
204
+ * Which fields the quick filter searches: every column that has one.
205
+ *
206
+ * Empty while the columns are still being registered, in which case the
207
+ * helper falls back to searching the row — the same behaviour as before, and
208
+ * the only sensible answer when the grid does not yet know its columns.
209
+ */
210
+ quickFilterFields() {
211
+ return this.columnService
212
+ .getColumnState()
213
+ .columns
214
+ .map(column => column.field)
215
+ .filter((field) => !!field && field !== '_oneRowNumber');
216
+ }
150
217
  /**
151
218
  * Update Row Nodes Display
152
219
  */
153
- refreshVisibleNodes() {
220
+ refreshVisibleNodes(dispatch = true) {
154
221
  if (this._destroyed)
155
222
  return;
156
223
  const visibleNodes = [];
157
224
  let rowNumber = 1;
158
225
  const visibilityCache = new Map();
159
- for (const node of this.rowNodes) {
226
+ for (const node of this._rowNodes) {
160
227
  const parentVisible = node.parent ? visibilityCache.get(node.parent.rowId) : true;
161
228
  const isVisible = node.visible && parentVisible && (!node.parent || node.parent.expanded);
162
229
  visibilityCache.set(node.rowId, isVisible);
@@ -170,7 +237,132 @@ export class OneGridApi {
170
237
  }
171
238
  }
172
239
  this._visibleRowNodes = [...visibleNodes];
173
- this.eventService.dispatchEvent('rowDataChanged', { nodes: visibleNodes });
240
+ if (dispatch)
241
+ this.eventService.dispatchEvent('rowDataChanged', { nodes: visibleNodes });
242
+ }
243
+ /**
244
+ * Replace the rows anchored to one edge of the grid.
245
+ *
246
+ * Pinned rows are deliberately kept out of `rowNodes` and
247
+ * `_originalRowNodes`: they are not data. Sorting, filtering, selection,
248
+ * expansion, pagination and the visible row count all ignore them, which is
249
+ * the whole point of a summary row. They render with the same column
250
+ * definitions, so renderers and value getters work as they do everywhere
251
+ * else.
252
+ */
253
+ setPinnedRowData(side, rowData) {
254
+ if (this._destroyed)
255
+ return;
256
+ for (const node of this._pinnedRowNodes[side])
257
+ node.destroy();
258
+ this._pinnedRowNodes[side] = (rowData ?? []).map((data, index) => {
259
+ // Ids are namespaced by side and position. They never collide with a data
260
+ // row's id, and they are stable across rebuilds, which keeps the rendered
261
+ // `data-cell-id` attributes stable too.
262
+ const node = new OneRowNode(`one-pinned-${side}-${index}`, data, index);
263
+ node.level = 0;
264
+ node.leaf = true;
265
+ node.visible = true;
266
+ node.setCellStates(this.cellService.generateCellStates(node));
267
+ return node;
268
+ });
269
+ this.eventService.dispatchEvent('pinnedRowDataChanged', {
270
+ side,
271
+ nodes: this._pinnedRowNodes[side],
272
+ });
273
+ }
274
+ /** The rows anchored to one edge. Read-only; change them with `setPinnedRowData`. */
275
+ getPinnedRowNodes(side) {
276
+ return this._pinnedRowNodes[side];
277
+ }
278
+ /**
279
+ * Row reordering
280
+ * --------------------------------------------------------------------------
281
+ *
282
+ * `_originalRowNodes` is the source of truth for row order: its insertion
283
+ * order is what `applySorting` falls back to when the sort model empties, and
284
+ * what a rebuild walks. `_rowNodes` is only the current display order. A move
285
+ * that touched one and not the other would either be undone by the next sort
286
+ * change or invisible until one happened, so both are rewritten together.
287
+ */
288
+ /**
289
+ * Whether the displayed order is the data order, and so whether a manual move
290
+ * would survive.
291
+ *
292
+ * @returns the reason reordering is unavailable, or `null` when it is fine.
293
+ */
294
+ getRowDragSuppressedReason() {
295
+ if (this.treeData)
296
+ return 'treeData';
297
+ if (this._sortModel.length > 0)
298
+ return 'sorted';
299
+ if (isFilterActive(this._activeFilters, this._quickFilterValue ?? ''))
300
+ return 'filtered';
301
+ return null;
302
+ }
303
+ /** Convenience inverse of {@link getRowDragSuppressedReason}. */
304
+ canReorderRows() {
305
+ return this.getRowDragSuppressedReason() === null;
306
+ }
307
+ /**
308
+ * Move a row from one position to another.
309
+ *
310
+ * Indices are positions in the grid's row order, the same order
311
+ * `getAllRowNodes()` returns. `targetIndex` is where the row ends up *after*
312
+ * it has been lifted out of `sourceIndex` — dragging row 0 to the bottom of a
313
+ * 5-row grid is `moveRow(0, 4)`, not `moveRow(0, 5)`.
314
+ *
315
+ * @returns `true` if the rows moved. `false` when the move was rejected —
316
+ * out-of-range indices, a no-op, or an order the grid does not own
317
+ * (see {@link getRowDragSuppressedReason}) — so a caller can tell a
318
+ * refused move from an applied one.
319
+ */
320
+ moveRow(sourceIndex, targetIndex) {
321
+ if (this._destroyed)
322
+ return false;
323
+ if (!this.canReorderRows())
324
+ return false;
325
+ const order = [...this._originalRowNodes.values()];
326
+ if (!Number.isInteger(sourceIndex) || !Number.isInteger(targetIndex))
327
+ return false;
328
+ if (sourceIndex < 0 || sourceIndex >= order.length)
329
+ return false;
330
+ if (targetIndex < 0 || targetIndex >= order.length)
331
+ return false;
332
+ if (sourceIndex === targetIndex)
333
+ return false;
334
+ const [moved] = order.splice(sourceIndex, 1);
335
+ order.splice(targetIndex, 0, moved);
336
+ // Rebuilt rather than mutated: a Map preserves insertion order, and there
337
+ // is no way to reposition a key within one.
338
+ this._originalRowNodes = new Map(order.map(node => [node.rowId, node]));
339
+ this._rowNodes = order;
340
+ this.reindexRows();
341
+ this.eventService.dispatchEvent('rowOrderChanged', { nodes: this._visibleRowNodes, node: moved, fromIndex: sourceIndex, toIndex: targetIndex });
342
+ return true;
343
+ }
344
+ /**
345
+ * Move a row identified by id. Convenient when the caller holds a node rather
346
+ * than a position — the index it was built with goes stale after any move.
347
+ */
348
+ moveRowById(rowId, targetIndex) {
349
+ const sourceIndex = [...this._originalRowNodes.values()].findIndex(node => node.rowId === rowId);
350
+ return sourceIndex === -1 ? false : this.moveRow(sourceIndex, targetIndex);
351
+ }
352
+ /**
353
+ * Re-stamp `rowIndex` from the current order.
354
+ *
355
+ * Row index is denormalised onto every node, and half the grid reads it —
356
+ * cell params, the range selection, the detail lookup. Leaving it stale after
357
+ * a move puts every row below the drop point one out.
358
+ */
359
+ reindexRows() {
360
+ this._rowNodes.forEach((node, index) => node.setRowIndex(index));
361
+ // Silent: row numbers and the visible list have to be rebuilt, but the
362
+ // `rowDataChanged` that normally follows defers a frame and re-seeds detail
363
+ // rows. A keyboard drag fires one of these per arrow key, and `moveRow`
364
+ // announces itself through `rowOrderChanged` instead.
365
+ this.refreshVisibleNodes(false);
174
366
  }
175
367
  getVisibleRowNodes() {
176
368
  return this._visibleRowNodes;
@@ -179,17 +371,19 @@ export class OneGridApi {
179
371
  * Sorting Model Feature
180
372
  */
181
373
  onSortChanged(sortModel) {
182
- this.sortModel = sortModel;
374
+ if (this._destroyed)
375
+ return;
376
+ this._sortModel = sortModel;
183
377
  this.applySorting();
184
- this.eventService.dispatchEvent('sortChanged', { nodes: this.rowNodes });
378
+ this.eventService.dispatchEvent('sortChanged', { nodes: this._rowNodes });
185
379
  }
186
380
  applySorting() {
187
- if (this.sortModel.length === 0) {
188
- this.rowNodes = [...this._originalRowNodes.values()];
381
+ if (this._sortModel.length === 0) {
382
+ this._rowNodes = [...this._originalRowNodes.values()];
189
383
  return;
190
384
  }
191
- this.rowNodes = [...this._originalRowNodes.values()].sort((a, b) => {
192
- for (const sortItem of this.sortModel) {
385
+ this._rowNodes = [...this._originalRowNodes.values()].sort((a, b) => {
386
+ for (const sortItem of this._sortModel) {
193
387
  const { colId, sort } = sortItem;
194
388
  const valA = getFieldValue(a.data, colId);
195
389
  const valB = getFieldValue(b.data, colId);
@@ -202,11 +396,17 @@ export class OneGridApi {
202
396
  });
203
397
  }
204
398
  compareValues(valA, valB, sortDirection) {
205
- if (valA === null && valB === null)
399
+ // `undefined` has to be treated as empty alongside `null`: getFieldValue
400
+ // returns undefined for a missing field or an unresolved dotted path, and
401
+ // comparing undefined with < / > yields false both ways, which made such
402
+ // rows settle in whatever order the sort happened to encounter them.
403
+ const aEmpty = valA === null || valA === undefined;
404
+ const bEmpty = valB === null || valB === undefined;
405
+ if (aEmpty && bEmpty)
206
406
  return 0;
207
- if (valA === null)
407
+ if (aEmpty)
208
408
  return sortDirection === 'asc' ? 1 : -1;
209
- if (valB === null)
409
+ if (bEmpty)
210
410
  return sortDirection === 'asc' ? -1 : 1;
211
411
  if (typeof valA === 'string' && typeof valB === 'string') {
212
412
  const comparison = valA.localeCompare(valB, undefined, { numeric: true });
@@ -261,7 +461,7 @@ export class OneGridApi {
261
461
  const node = this.getRowNodeById(rowId);
262
462
  if (node) {
263
463
  if (this.selectionService.getSelectionMode() === 'single') {
264
- this.rowNodes.forEach(rowNode => rowNode.setSelected(rowNode.rowId === node.rowId));
464
+ this._rowNodes.forEach(rowNode => rowNode.setSelected(rowNode.rowId === node.rowId));
265
465
  this._originalRowNodes.forEach(rowNode => rowNode.setSelected(rowNode.rowId === node.rowId));
266
466
  }
267
467
  else {
@@ -286,13 +486,13 @@ export class OneGridApi {
286
486
  * Get & Set Functions
287
487
  */
288
488
  getAllRowNodes() {
289
- return this.rowNodes?.length > 0 ? [...this.rowNodes] : [];
489
+ return this._rowNodes?.length > 0 ? [...this._rowNodes] : [];
290
490
  }
291
491
  getRowDataSelected() {
292
- return this.rowNodes.filter(node => node.selected).map(node => ({ ...node.data }));
492
+ return this._rowNodes.filter(node => node.selected).map(node => ({ ...node.data }));
293
493
  }
294
494
  getSelectedRowNodes() {
295
- const nodes = this.rowNodes.filter(node => node.selected);
495
+ const nodes = this._rowNodes.filter(node => node.selected);
296
496
  return nodes && nodes.length > 0 ? [...nodes] : [];
297
497
  }
298
498
  /**
@@ -302,6 +502,8 @@ export class OneGridApi {
302
502
  return this._activeFilters;
303
503
  }
304
504
  setFilterModel(model) {
505
+ if (this._destroyed)
506
+ return;
305
507
  this._activeFilters = model;
306
508
  this.applyFilters();
307
509
  }
@@ -312,76 +514,69 @@ export class OneGridApi {
312
514
  * Quick filter
313
515
  */
314
516
  setQuickFilter(value) {
517
+ if (this._destroyed)
518
+ return;
315
519
  this._quickFilterValue = (value || '').toLowerCase();
316
520
  this.applyFilters();
317
521
  }
318
522
  /**
319
- * Validation Feature
523
+ * Run the column validators over one row.
524
+ *
525
+ * Rules run in order and stop at the first failure, so a field appears at
526
+ * most once. Fields that passed are absent rather than mapped to `null`.
527
+ *
528
+ * The row type comes from the grid's own `T` — this used to declare its own
529
+ * `<T>`, which shadowed the class parameter and let an `OneGridApi<Employee>`
530
+ * happily validate an unrelated shape against employee columns.
320
531
  */
321
532
  validateRow(row, columns) {
322
533
  const errors = {};
323
- columns.forEach(col => {
324
- // Only check columns with validationRule
325
- if (!col.validationRules || col.validationRules.length === 0)
326
- return;
327
- const rules = col.validationRules;
328
- for (const rule of rules) {
329
- const error = rule(row[col.field], row);
534
+ for (const column of columns) {
535
+ // A column can only contribute an error if it has both rules and a field
536
+ // to key them under.
537
+ if (!column.field || !column.validationRules?.length)
538
+ continue;
539
+ for (const rule of column.validationRules) {
540
+ const error = rule(row[column.field], row);
330
541
  if (error) {
331
- errors[col.field] = error;
332
- break; // stop at first error for this column
542
+ errors[column.field] = error;
543
+ break; // first failure per column wins
333
544
  }
334
545
  }
335
- });
546
+ }
336
547
  return errors;
337
548
  }
338
549
  /**
339
- * Validate all rows and return both errors and a flag indicating if there are any errors
550
+ * Run the column validators over a whole dataset.
551
+ *
552
+ * Delegates to `validateRow` so the two can never disagree about what counts
553
+ * as invalid — they previously carried separate copies of the same loop.
340
554
  */
341
555
  validateAllRows(rowData, columns) {
342
- const allErrors = rowData.map(row => {
343
- const errors = {};
344
- columns.forEach(col => {
345
- if (!col.validationRules || col.validationRules.length === 0)
346
- return;
347
- for (const rule of col.validationRules) {
348
- const error = rule(row[col.field], row);
349
- if (error) {
350
- errors[col.field] = error;
351
- break;
352
- }
353
- }
354
- });
355
- return errors;
356
- });
357
- const hasErrors = allErrors.some(err => Object.keys(err).length > 0);
556
+ const allErrors = rowData.map(row => this.validateRow(row, columns));
557
+ const hasErrors = allErrors.some(errors => Object.keys(errors).length > 0);
358
558
  return { errors: allErrors, valid: !hasErrors, invalid: hasErrors };
359
559
  }
360
- /** Traverse all nodes */
560
+ /**
561
+ * Traverse every node, depth-first, once each.
562
+ *
563
+ * `rowNodes` is already the flattened tree — `buildRowNodes` pushes every
564
+ * node into it as it descends — so walking it is the whole traversal. The
565
+ * previous implementation walked that flat list *and* recursed into
566
+ * `children`, visiting every nested node twice and every depth-3 node three
567
+ * times. `index` is the node's position in the flattened order, matching
568
+ * `node.rowIndex`, rather than its position among its siblings.
569
+ */
361
570
  forEachNode(callback) {
362
- const visit = (nodes) => {
363
- nodes.forEach((node, index) => {
364
- callback(node, index);
365
- if (node?.children?.length)
366
- visit(node.children);
367
- });
368
- };
369
- visit(this.rowNodes);
571
+ this._rowNodes.forEach((node, index) => callback(node, index));
370
572
  }
371
- /** Traverse only leaf nodes */
573
+ /** Traverse only leaf nodes, once each, in flattened order. */
372
574
  forEachLeafNode(callback) {
373
575
  let leafIndex = 0;
374
- const visit = (nodes) => {
375
- nodes.forEach(node => {
376
- if (node.leaf) {
377
- callback(node, leafIndex++);
378
- }
379
- else if (node.group && node?.children?.length) {
380
- visit(node.children);
381
- }
382
- });
383
- };
384
- visit(this.rowNodes);
576
+ for (const node of this._rowNodes) {
577
+ if (node.leaf)
578
+ callback(node, leafIndex++);
579
+ }
385
580
  }
386
581
  getRowNodeById(rowId) {
387
582
  return this._originalRowNodes.get(rowId);
@@ -395,8 +590,25 @@ export class OneGridApi {
395
590
  setGroupDefaultExpanded(defaultExpanded) {
396
591
  this.groupDefaultExpanded = defaultExpanded;
397
592
  }
593
+ /**
594
+ * Expansion state lives in two places, and they answer different questions.
595
+ *
596
+ * `OneGridExpansionService` records only *deliberate* changes — a click, or
597
+ * one of the methods below. It is an override layer: `buildRowNodes` consults
598
+ * it first and falls back to `groupDefaultExpanded` for every row the user
599
+ * has not touched. That is what lets a later `groupDefaultExpanded` change
600
+ * take effect, and what lets a collapse survive a rebuild.
601
+ *
602
+ * `node.expanded` is the resolved truth for a row, defaults included. Public
603
+ * reads report that; the override sets stay internal.
604
+ *
605
+ * The invariant the setters below maintain: `expanded` is only ever true for
606
+ * a node that can expand.
607
+ */
398
608
  toggleExpandAll(expanded) {
399
609
  this.forEachNode(node => {
610
+ if (!node.expandable)
611
+ return;
400
612
  node.setExpanded(expanded);
401
613
  this.expansionService.toggleExpanded(node.rowId, expanded);
402
614
  });
@@ -404,7 +616,7 @@ export class OneGridApi {
404
616
  }
405
617
  setExpandedById(rowId, expanded) {
406
618
  const node = this._originalRowNodes.get(rowId);
407
- if (node) {
619
+ if (node?.expandable) {
408
620
  node.setExpanded(expanded);
409
621
  this.expansionService.toggleExpanded(rowId, expanded);
410
622
  }
@@ -414,7 +626,7 @@ export class OneGridApi {
414
626
  if (rowIds && rowIds.length > 0) {
415
627
  for (let rowId of rowIds) {
416
628
  const node = this._originalRowNodes.get(rowId);
417
- if (node) {
629
+ if (node?.expandable) {
418
630
  node.setExpanded(expanded);
419
631
  this.expansionService.toggleExpanded(rowId, expanded);
420
632
  }
@@ -422,20 +634,32 @@ export class OneGridApi {
422
634
  this.refreshVisibleNodes();
423
635
  }
424
636
  }
637
+ /**
638
+ * Every currently expanded row, in tree order.
639
+ *
640
+ * Derived from the nodes rather than read off the override record, so rows
641
+ * opened by `groupDefaultExpanded` are included — previously this returned
642
+ * only rows someone had explicitly toggled, and came back empty on first load
643
+ * while the first level was visibly open.
644
+ */
425
645
  getExpandedByIds() {
426
- return Array.from(this.expansionService.getExpandedIds());
646
+ return this._rowNodes
647
+ .filter(node => node.expandable && node.expanded)
648
+ .map(node => node.rowId);
427
649
  }
428
650
  /**
429
651
  * Master Detail Feature
430
652
  */
431
653
  setDetailRowData(node, detailData) {
654
+ if (this._destroyed)
655
+ return;
432
656
  const rowNode = this.getRowNodeById(node.rowId);
433
657
  if (rowNode) {
434
658
  rowNode.setDetailRowData(detailData);
435
659
  }
436
660
  }
437
661
  setGetDetailRowData(getDetailRowData) {
438
- this.getDetailRowData = getDetailRowData;
662
+ this._getDetailRowData = getDetailRowData;
439
663
  }
440
664
  /**
441
665
  * Columns State
@@ -444,15 +668,17 @@ export class OneGridApi {
444
668
  return this.columnService.getColumnState();
445
669
  }
446
670
  setColumnDefs(columnDefs) {
671
+ if (this._destroyed)
672
+ return;
447
673
  this.columnService.setColumnDefs(columnDefs);
448
674
  const columnState = this.columnService.getColumnState();
449
- this.cellService.applyColumnDefs(columnState.columns, this.context);
675
+ this.cellService.applyColumnDefs(columnState.columns, this._context);
450
676
  this.eventService.dispatchEvent('columnChanged', columnState);
451
677
  }
452
678
  updateColumn(id, changes) {
453
679
  this.columnService.updateColumnDef(id, changes);
454
680
  const columnState = this.columnService.getColumnState();
455
- this.cellService.applyColumnDefs(columnState.columns, this.context);
681
+ this.cellService.applyColumnDefs(columnState.columns, this._context);
456
682
  this.eventService.dispatchEvent('columnChanged', columnState);
457
683
  }
458
684
  reorderColumnDefs(fromIndex, toIndex) {
@@ -474,11 +700,12 @@ export class OneGridApi {
474
700
  collect(node);
475
701
  this.setSelectedByIds(Array.from(rowIds), selected);
476
702
  }
703
+ /**
704
+ * @deprecated Identical to `updateCellStates`. Kept as an alias so existing
705
+ * callers keep working; prefer `updateCellStates`, which says what it does.
706
+ */
477
707
  updateNodeStates(node) {
478
- const rowNode = this.getRowNodeById(node.rowId);
479
- if (rowNode) {
480
- rowNode.cellStates = this.cellService.generateCellStates(rowNode);
481
- }
708
+ this.updateCellStates(node);
482
709
  }
483
710
  updateCellState(node, column) {
484
711
  const rowNode = this.getRowNodeById(node.rowId);
@@ -486,34 +713,42 @@ export class OneGridApi {
486
713
  rowNode.cellStates[column.field] = this.cellService.generateCellState(rowNode, column);
487
714
  }
488
715
  }
716
+ /**
717
+ * Recompute every cell of one row and repaint it.
718
+ *
719
+ * The repaint is the point: this is what a caller reaches for after mutating
720
+ * a row in place, and it used to regenerate the state and stop there. The
721
+ * body renders with OnPush, so nothing marked it dirty and the new state sat
722
+ * unread until some unrelated event happened to trigger change detection —
723
+ * which is why callers ended up nudging the grid with a synthetic DOM event.
724
+ */
489
725
  updateCellStates(node) {
726
+ if (this._destroyed)
727
+ return;
490
728
  const rowNode = this.getRowNodeById(node.rowId);
491
- if (rowNode) {
492
- rowNode.cellStates = this.cellService.generateCellStates(rowNode);
493
- }
729
+ if (!rowNode)
730
+ return;
731
+ rowNode.cellStates = this.cellService.generateCellStates(rowNode);
732
+ this.eventService.dispatchEvent('cellStateChanged', { data: rowNode.data, node: rowNode });
494
733
  }
495
734
  /**
496
735
  * Handler that Reacts to Detail Changes
497
736
  */
737
+ /**
738
+ * Keep a master row's reserved height in step with its detail rows.
739
+ *
740
+ * Two listeners used to be registered here and thrown away: an empty
741
+ * `rowDataChanged` handler whose unsubscribe was never kept, and an
742
+ * `expandedChanged` handler whose body was entirely commented out. Both are
743
+ * gone — a listener with no behaviour is a leak with no upside.
744
+ */
498
745
  subscribeToDetailChanges(node) {
499
- const unsubRowData = node.on('rowDataChanged', ({ node, data, previousData }) => {
500
- });
501
- // When detail data arrives
502
- const unsubDetail = node.on('detailRowDataChanged', ({ node, detailRowData, previousDetailRowData }) => {
503
- if (this.apiType === 'master') {
504
- this._resolvedDetailRowHeight(node);
746
+ const unsubscribeDetail = node.on('detailRowDataChanged', ({ node }) => {
747
+ if (this._apiType === 'master') {
748
+ this.resolveDetailRowHeight(node);
505
749
  }
506
750
  });
507
- // When row expands
508
- const unsubExpand = node.on('expandedChanged', ({ node, expanded }) => {
509
- // if (!expanded) return;
510
- // // Only fetch if detail data not already loaded
511
- // if (!node.detailRowData) {
512
- // this.getDetailRowData({ data: node.data, node, successCallback: (detailRowData) => node.setDetailRowData(detailRowData) });
513
- // }
514
- });
515
- // // Cleanup when node is removed from grid
516
- this.registerNodeCleanup(node.rowId, [unsubDetail, unsubExpand]);
751
+ this.registerNodeCleanup(node.rowId, [unsubscribeDetail]);
517
752
  }
518
753
  registerNodeCleanup(rowId, unsubs) {
519
754
  // Merge with any existing cleanups for this rowId
@@ -525,7 +760,14 @@ export class OneGridApi {
525
760
  cleanups?.forEach(fn => fn());
526
761
  this._nodeCleanupMap.delete(rowId);
527
762
  }
528
- // Call this when rows are removed
763
+ /**
764
+ * Drop nodes that are no longer in the data, releasing what they hold.
765
+ *
766
+ * This existed but was never called: `setRowData` and `updateRowData` each
767
+ * deleted straight out of `_originalRowNodes`, so a removed node kept its
768
+ * listeners and its entry in `_nodeCleanupMap` for the lifetime of the grid.
769
+ * Both now come through here, which unsubscribes and clears the node first.
770
+ */
529
771
  pruneRemovedNodes(validRowIds) {
530
772
  for (const [rowId, node] of this._originalRowNodes) {
531
773
  if (!validRowIds.has(rowId)) {
@@ -536,51 +778,72 @@ export class OneGridApi {
536
778
  }
537
779
  }
538
780
  /**
539
- * Resolve Detail Row Height
781
+ * Height a master row must reserve for its detail grid:
782
+ * rowHeight x clamp(rows, minRows, maxRows) + headerHeight.
540
783
  */
541
- _resolvedDetailRowHeight(node) {
542
- const minRows = this.detailCellRendererParams.detailGridOptions.detailRowHeightOptions.minRows;
543
- const maxRows = this.detailCellRendererParams.detailGridOptions.detailRowHeightOptions.maxRows;
784
+ resolveDetailRowHeight(node) {
785
+ const heightOptions = this.detailCellRendererParams?.detailGridOptions?.detailRowHeightOptions;
786
+ // Reachable whenever masterDetail is on but detailCellRendererParams is
787
+ // incomplete; without the guard this threw from inside an event listener.
788
+ if (!heightOptions)
789
+ return;
790
+ const minRows = heightOptions.minRows;
791
+ const maxRows = heightOptions.maxRows;
544
792
  const minHeight = (this.rowHeight * minRows) + this.headerRowHeight;
545
793
  const maxHeight = (this.rowHeight * maxRows) + this.headerRowHeight;
546
794
  const rows = node.detailRowData && node.detailRowData.length ? node.detailRowData.length : 0;
547
795
  node.detailRowHeight = rows <= minRows ? minHeight : rows >= maxRows ? maxHeight : (this.rowHeight * rows) + this.headerRowHeight;
548
796
  }
549
797
  /**
550
- * On Destroy
798
+ * Release everything the grid holds. Called by `OneGridComponent.ngOnDestroy`.
799
+ *
800
+ * The services are deliberately *not* nulled out any more. They are injected,
801
+ * Angular owns their lifetime, and nulling them only guaranteed a
802
+ * `TypeError` for any callback that arrived after teardown — a detail-row
803
+ * fetch resolving late, or the body's deferred update. `_destroyed` makes
804
+ * those calls no-ops instead, which is what a torn-down object should do.
551
805
  */
552
806
  destroy() {
553
807
  if (this._destroyed)
554
808
  return;
555
809
  this._destroyed = true;
556
- this.rowNodes.forEach(node => {
557
- node.children = [];
558
- node.parent = null;
559
- });
560
- this.rowNodes = [];
561
- this._originalRowNodes.clear();
562
- this._currentIndex = null;
563
- // Clear services
564
- if (this.selectionService) {
565
- this.selectionService.deselectAll();
810
+ // Unsubscribe every per-node listener before dropping the nodes.
811
+ for (const rowId of Array.from(this._nodeCleanupMap.keys())) {
812
+ this.cleanupNode(rowId);
566
813
  }
567
- this.selectionService = null;
568
- if (this.expansionService) {
569
- this.expansionService.clear();
814
+ // `destroy` drops the tree links and the listeners; the API no longer has
815
+ // to reach in and unpick each node itself.
816
+ this._originalRowNodes.forEach(node => node.destroy());
817
+ this._rowNodes.forEach(node => node.destroy());
818
+ for (const side of ['top', 'bottom']) {
819
+ this._pinnedRowNodes[side].forEach(node => node.destroy());
820
+ this._pinnedRowNodes[side] = [];
570
821
  }
571
- this.expansionService = null;
572
- this.eventService = null;
573
- this.rowService = null;
574
- this.cellService = null;
575
- // Clear filters, sorting, context
822
+ this._rowNodes = [];
823
+ this._visibleRowNodes = [];
824
+ this._originalRowNodes.clear();
825
+ this._nodeCleanupMap.clear();
826
+ this._currentIndex = 0;
827
+ // Release the back-reference the cell service holds, so a torn-down api is
828
+ // not kept alive by the service that outlives this call.
829
+ this.cellService.setGridApi(null);
830
+ this.selectionService.deselectAll();
831
+ this.expansionService.clear();
576
832
  this._activeFilters = [];
577
833
  this._quickFilterValue = null;
578
- this.sortModel = [];
579
- // Clear master/detail/treeData
834
+ this._sortModel = [];
835
+ this._context = null;
580
836
  this.masterDetail = false;
581
837
  this.treeData = false;
582
- this.treeDataChildrenField = '';
838
+ this.treeDataChildrenField = null;
583
839
  this.groupDefaultExpanded = 0;
840
+ this.detailCellRendererParams = null;
841
+ this.detailRendererComponent = null;
842
+ this._getDetailRowData = null;
843
+ }
844
+ /** Whether `destroy` has run. Late callbacks check this before doing work. */
845
+ get destroyed() {
846
+ return this._destroyed;
584
847
  }
585
848
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: OneGridApi, deps: [{ token: i1.OgColumnService }, { token: i2.OneGridRowService }, { token: i3.OneGridCellService }, { token: i4.OneGridEventService }, { token: i5.OneGridSelectionService }, { token: i6.OneGridExpansionService }], target: i0.ɵɵFactoryTarget.Injectable }); }
586
849
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: OneGridApi }); }
@@ -588,4 +851,4 @@ export class OneGridApi {
588
851
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: OneGridApi, decorators: [{
589
852
  type: Injectable
590
853
  }], ctorParameters: () => [{ type: i1.OgColumnService }, { type: i2.OneGridRowService }, { type: i3.OneGridCellService }, { type: i4.OneGridEventService }, { type: i5.OneGridSelectionService }, { type: i6.OneGridExpansionService }] });
591
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib25lLWdyaWQtYXBpLmNsYXNzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvb25lLWdyaWQvc3JjL2xpYi9jb3JlL2luc3RhbnRzL29uZS1ncmlkLWFwaS5jbGFzcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFTbEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ2pFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUU5RCxPQUFPLEVBQUUsRUFBRSxJQUFJLE1BQU0sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNwQyxPQUFPLEVBQUUsVUFBVSxFQUFRLE1BQU0sZUFBZSxDQUFDOzs7Ozs7OztBQU1qRCxNQUFNLE9BQU8sVUFBVTtJQWtDckIsWUFDVSxhQUE4QixFQUM5QixVQUE2QixFQUM3QixXQUErQixFQUMvQixZQUFpQyxFQUNqQyxnQkFBeUMsRUFDekMsZ0JBQXlDO1FBTHpDLGtCQUFhLEdBQWIsYUFBYSxDQUFpQjtRQUM5QixlQUFVLEdBQVYsVUFBVSxDQUFtQjtRQUM3QixnQkFBVyxHQUFYLFdBQVcsQ0FBb0I7UUFDL0IsaUJBQVksR0FBWixZQUFZLENBQXFCO1FBQ2pDLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBeUI7UUFDekMscUJBQWdCLEdBQWhCLGdCQUFnQixDQUF5QjtRQXBDNUMsWUFBTyxHQUFRLElBQUksQ0FBQztRQUNwQixpQkFBWSxHQUFxQixJQUFJLENBQUM7UUFDdEMsWUFBTyxHQUFnQixJQUFJLENBQUM7UUFDNUIsYUFBUSxHQUFvQixFQUFFLENBQUM7UUFDL0IsY0FBUyxHQUFzQixFQUFFLENBQUM7UUFHakMsY0FBUyxHQUFXLEVBQUUsQ0FBQztRQUN2QixvQkFBZSxHQUFXLEVBQUUsQ0FBQztRQUM3QixrQkFBYSxHQUFXLENBQUMsQ0FBQztRQUMx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LFdBQVcsRUFBRSxDQUFDO1FBQ3RDLENBQUM7UUFDRCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBVyxDQUFDO1FBRXBDLElBQUksSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDMUIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2hDLENBQUM7UUFDRCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBVyxDQUFDO1FBRXBDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBVyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBVyxDQUFDO1FBQzlCLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBVyxDQUFDO1FBRS9CLGtDQUFrQztRQUNsQyxJQUFJLENBQUMsY0FBYyxHQUFHLEVBQUUsQ0FBQztRQUN6QixJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDO1FBQzlCLElBQUksQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFDO1FBRXBCLCtCQUErQjtRQUMvQixJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztRQUMxQixJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQztRQUN0QixJQUFJLENBQUMscUJBQXFCLEdBQUcsRUFBRSxDQUFDO1FBQ2hDLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxDQUFDLENBQUM7SUFDaEMsQ0FBQzsrR0FsM0JVLFVBQVU7bUhBQVYsVUFBVTs7NEZBQVYsVUFBVTtrQkFEdEIsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE9uZUNlbGxSZW5kZXJlckNvbXBvbmVudCB9IGZyb20gJy4uL21vZGVscy9vbmUtdHJlZS1kYXRhLm1vZGVsJztcbmltcG9ydCB7IE9uZUNvbHVtbkRlZiB9IGZyb20gJy4uL21vZGVscy9vbmUtY29sdW1uLWRlZi10eXBlcy5tb2RlbCc7XG5pbXBvcnQgeyBPbmVSb3dOb2RlIH0gZnJvbSBcIi4vb25lLXJvdy1ub2RlLmNsYXNzXCI7XG5pbXBvcnQgeyBPbmVHcmlkVHlwZSwgT25lU29ydE1vZGVsIH0gZnJvbSAnLi4vbW9kZWxzL29uZS1ncmlkLXR5cGVzLm1vZGVsJztcbmltcG9ydCB7IE9uZUdyaWRFdmVudFNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9vbmUtZ3JpZC1ldmVudC5zZXJ2aWNlJztcbmltcG9ydCB7IE9uZUdyaWRTZWxlY3Rpb25TZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvb25lLWdyaWQtc2VsZWN0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHsgT25lVmFsaWRhdGlvblJlc3VsdCB9IGZyb20gJy4uL21vZGVscy9vbmUtdmFsaWRhdGlvbi5tb2RlbCc7XG5pbXBvcnQgeyBPbmVGaWx0ZXJNb2RlbCB9IGZyb20gXCIuLi9tb2RlbHMvb25lLWZpbHRlci5tb2RlbFwiO1xuaW1wb3J0IHsgT25lR3JpZEV4cGFuc2lvblNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9vbmUtZ3JpZC1leHBhbnNpb24uc2VydmljZSc7XG5pbXBvcnQgeyBPbmVEZXRhaWxDZWxsUmVuZGVyZXJQYXJhbXMsIE9uZUdldERldGFpbFJvd0RhdGFQYXJhbXMgfSBmcm9tIFwiLi4vbW9kZWxzL29uZS1tYXN0ZXItZGV0YWlsLm1vZGVsXCI7XG5pbXBvcnQgeyBPbmVHcmlkUm93U2VydmljZSB9IGZyb20gXCIuLi9zZXJ2aWNlcy9vbmUtZ3JpZC1yb3cuc2VydmljZVwiO1xuaW1wb3J0IHsgZmlsdGVyVHJlZU5vZGUgfSBmcm9tIFwiLi4vLi4vaGVscGVycy9vbmUtZmlsdGVyLmhlbHBlclwiO1xuaW1wb3J0IHsgZ2V0RmllbGRWYWx1ZSB9IGZyb20gXCIuLi8uLi9oZWxwZXJzL29uZS1jZWxsLmhlbHBlclwiO1xuaW1wb3J0IHsgT25lR3JpZENlbGxTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvb25lLWdyaWQtY2VsbC5zZXJ2aWNlJztcbmltcG9ydCB7IHY0IGFzIHV1aWR2NCB9IGZyb20gJ3V1aWQnO1xuaW1wb3J0IHsgSW5qZWN0YWJsZSwgVHlwZSB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBDb2x1bW5DaGFuZ2VkRXZlbnQsIFJvd1NlbGVjdGlvbk1vZGUgfSBmcm9tIFwiLi4vbW9kZWxzL29uZS1ldmVudC10eXBlcy5tb2RlbFwiO1xuaW1wb3J0IHsgT25lR3JvdXBDb2x1bW5EZWYgfSBmcm9tIFwiLi4vbW9kZWxzL29uZS1jb2x1bW4tZGVmLXR5cGVzLm1vZGVsXCI7XG5pbXBvcnQgeyBPZ0NvbHVtblNlcnZpY2UgfSBmcm9tIFwiLi4vc2VydmljZXMvb2ctY29sdW1uLnNlcnZpY2VcIjtcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIE9uZUdyaWRBcGk8VCA9IGFueT4ge1xuXG4gIC8vIENvcmUgRmVhdHVyZXNcbiAgcHVibGljIGlkOiBzdHJpbmc7XG4gIHB1YmxpYyBjb250ZXh0OiBhbnkgPSBudWxsO1xuICBwdWJsaWMgcm93U2VsZWN0aW9uOiBSb3dTZWxlY3Rpb25Nb2RlID0gbnVsbDtcbiAgcHVibGljIGFwaVR5cGU6IE9uZUdyaWRUeXBlID0gbnVsbDtcbiAgcHVibGljIHJvd05vZGVzOiBPbmVSb3dOb2RlPFQ+W10gPSBbXTtcbiAgcHVibGljIHNvcnRNb2RlbDogT25lU29ydE1vZGVsPFQ+W10gPSBbXTtcblxuXG4gIHByaXZhdGUgcm93SGVpZ2h0OiBudW1iZXIgPSAyNjtcbiAgcHJpdmF0ZSBoZWFkZXJSb3dIZWlnaHQ6IG51bWJlciA9IDMyO1xuICBwcml2YXRlIF9jdXJyZW50SW5kZXg6IG51bWJlciA9IDA7XG4gIHByaXZhdGUgX3F1aWNrRmlsdGVyVmFsdWU6IHN0cmluZyA9IG51bGw7XG4gIHByaXZhdGUgX2FjdGl2ZUZpbHRlcnM6IE9uZUZpbHRlck1vZGVsW10gPSBbXTtcblxuICBwcml2YXRlIF92aXNpYmxlUm93Tm9kZXM6IE9uZVJvd05vZGU8VD5bXSA9IFtdO1xuICBwcml2YXRlIF9vcmlnaW5hbFJvd05vZGVzOiBNYXA8c3RyaW5nLCBPbmVSb3dOb2RlPFQ+PiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSBfbm9kZUNsZWFudXBNYXAgPSBuZXcgTWFwPHN0cmluZywgQXJyYXk8KCkgPT4gdm9pZD4+KCk7IC8vIENsZWFudXAgcmVnaXN0cnkgKHByZXZlbnRzIG1lbW9yeSBsZWFrcylcbiAgcHJpdmF0ZSBfZGVzdHJveWVkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgLy8gQWR2YW5jZWQgRmVhdHVyZXNcbiAgcHJpdmF0ZSB0cmVlRGF0YTogYm9vbGVhbiA9IGZhbHNlO1xuICBwcml2YXRlIHRyZWVEYXRhQ2hpbGRyZW5GaWVsZDogc3RyaW5nID0gbnVsbDtcbiAgcHJpdmF0ZSBncm91cERlZmF1bHRFeHBhbmRlZDogbnVtYmVyID0gMDtcblxuICBwcml2YXRlIG1hc3RlckRldGFpbDogYm9vbGVhbiA9IGZhbHNlO1xuICBwcml2YXRlIGRldGFpbENlbGxSZW5kZXJlclBhcmFtczogT25lRGV0YWlsQ2VsbFJlbmRlcmVyUGFyYW1zO1xuICBwcml2YXRlIGRldGFpbFJlbmRlcmVyQ29tcG9uZW50PzogVHlwZTxPbmVDZWxsUmVuZGVyZXJDb21wb25lbnQ+O1xuXG4gIC8vIEhlbHBlciBGdW5jdGlvbnNcbiAgcHVibGljIGdldERldGFpbFJvd0RhdGE6IChwYXJhbXM6IE9uZUdldERldGFpbFJvd0RhdGFQYXJhbXMpID0+IHZvaWQ7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBjb2x1bW5TZXJ2aWNlOiBPZ0NvbHVtblNlcnZpY2UsXG4gICAgcHJpdmF0ZSByb3dTZXJ2aWNlOiBPbmVHcmlkUm93U2VydmljZSxcbiAgICBwcml2YXRlIGNlbGxTZXJ2aWNlOiBPbmVHcmlkQ2VsbFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBldmVudFNlcnZpY2U6IE9uZUdyaWRFdmVudFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBzZWxlY3Rpb25TZXJ2aWNlOiBPbmVHcmlkU2VsZWN0aW9uU2VydmljZSxcbiAgICBwcml2YXRlIGV4cGFuc2lvblNlcnZpY2U6IE9uZUdyaWRFeHBhbnNpb25TZXJ2aWNlXG4gICkgeyB9XG5cbiAgaW5pdChcbiAgICBncmlkQXBpVHlwZTogT25lR3JpZFR5cGUsXG4gICAgcm93U2VsZWN0aW9uOiBSb3dTZWxlY3Rpb25Nb2RlLFxuICAgIGNvbHVtbkRlZnM6IE9uZUNvbHVtbkRlZjxUPltdLFxuICAgIGRlZmF1bHRDb2x1bW5EZWY6IE9uZUNvbHVtbkRlZjxUPixcbiAgICBjb250ZXh0OiBhbnksXG4gICAgbWFzdGVyRGV0YWlsOiBib29sZWFuLFxuICAgIGRldGFpbENlbGxSZW5kZXJlclBhcmFtczogT25lRGV0YWlsQ2VsbFJlbmRlcmVyUGFyYW1zLFxuICAgIGRldGFpbFJlbmRlcmVyQ29tcG9uZW50OiBUeXBlPE9uZUNlbGxSZW5kZXJlckNvbXBvbmVudD4sXG4gICAgdHJlZURhdGE6IGJvb2xlYW4sXG4gICAgZ3JvdXBDb2x1bW5EZWZzOiBPbmVHcm91cENvbHVtbkRlZltdXG4gICkge1xuXG4gICAgdGhpcy5pZCA9IHV1aWR2NCgpO1xuICAgIHRoaXMuYXBpVHlwZSA9IGdyaWRBcGlUeXBlO1xuICAgIHRoaXMucm93U2VsZWN0aW9uID0gcm93U2VsZWN0aW9uO1xuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gICAgdGhpcy5tYXN0ZXJEZXRhaWwgPSBtYXN0ZXJEZXRhaWw7XG4gICAgdGhpcy5kZXRhaWxDZWxsUmVuZGVyZXJQYXJhbXMgPSBkZXRhaWxDZWxsUmVuZGVyZXJQYXJhbXM7XG4gICAgdGhpcy5kZXRhaWxSZW5kZXJlckNvbXBvbmVudCA9IGRldGFpbFJlbmRlcmVyQ29tcG9uZW50O1xuICAgIHRoaXMudHJlZURhdGEgPSB0cmVlRGF0YTtcblxuICAgIHRoaXMuc2VsZWN0aW9uU2VydmljZS5zZXRTZWxlY3Rpb25Nb2RlKHRoaXMucm93U2VsZWN0aW9uKTtcbiAgICB0aGlzLnJvd1NlcnZpY2Uuc2V0R2V0Um93SWRGbih0aGlzLmNvbnRleHQ/LmNvbXBvbmVudFBhcmVudD8uZ2V0Um93SWQgPz8gbnVsbCk7XG5cbiAgICB0aGlzLmNlbGxTZXJ2aWNlLmFwcGx5Q29sdW1uRGVmcyhjb2x1bW5EZWZzLCBjb250ZXh0KTtcbiAgICB0aGlzLmNvbHVtblNlcnZpY2UuaW5pdENvbHVtbkRlZnMoZGVmYXVsdENvbHVtbkRlZiwgY29sdW1uRGVmcywgZ3JvdXBDb2x1bW5EZWZzKTtcblxuICAgIGNvbnN0IGNvbHVtblN0YXRlID0gdGhpcy5jb2x1bW5TZXJ2aWNlLmdldENvbHVtblN0YXRlKCk7XG5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuZXZlbnRTZXJ2aWNlLmRpc3BhdGNoRXZlbnQoJ2NvbHVtbkNoYW5nZWQnLCBjb2x1bW5TdGF0ZSBhcyBDb2x1bW5DaGFuZ2VkRXZlbnQpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgUm93IE5vZGUgJiBDbGVhciBBbGwgU3RhdGUgSURTXG4gICAqL1xuICBwdWJsaWMgc2V0Um93RGF0YShyb3dEYXRhOiBUW10pIHtcblxuICAgIGNvbnN0IHZhbGlkUm93SWRzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgICAvLyBDbGVhciBBbGwgU3RhdGUgSURTXG4gICAgdGhpcy5zZWxlY3Rpb25TZXJ2aWNlLmRlc2VsZWN0QWxsKCk7XG4gICAgdGhpcy5leHBhbnNpb25TZXJ2aWNlLmNsZWFyKCk7XG5cbiAgICAvLyBCdWlsZCBOZXcgUm93IE5vZGVzXG4gICAgdGhpcy5idWlsZFJvd05vZGVzKHJvd0RhdGEsIG51bGwsIDAsIHZhbGlkUm93SWRzKTtcblxuICAgIC8vIEFwcGx5IEZpbHRlclxuICAgIHRoaXMuYXBwbHlGaWx0ZXJzKCk7XG5cbiAgICAvLyBSZW1vdmUgaW52YWxpZCBub2RlcyBmcm9tIG1hcFxuICAgIGZvciAoY29uc3Qgcm93SWQgb2YgdGhpcy5fb3JpZ2luYWxSb3dOb2Rlcy5rZXlzKCkpIHtcblxuICAgICAgaWYgKCF2YWxpZFJvd0lkcy5oYXMocm93SWQpKSB7XG5cbiAgICAgICAgdGhpcy5fb3JpZ2luYWxSb3dOb2Rlcy5kZWxldGUocm93SWQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgUm93IE5vZGVzICYgTm90IENsZWFyIFN0YXRlIElEU1xuICAgKi9cbiAgcHVibGljIHVwZGF0ZVJvd0RhdGEocm93RGF0YTogVFtdKSB7XG5cbiAgICBjb25zdCB2YWxpZFJvd0lkcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gICAgLy8gQnVpbGQgTmV3IFJvdyBOb2Rlc1xuICAgIHRoaXMuYnVpbGRSb3dOb2Rlcyhyb3dEYXRhLCBudWxsLCAwLCB2YWxpZFJvd0lkcyk7XG5cbiAgICAvLyBBcHBseSBGaWx0ZXJcbiAgICB0aGlzLmFwcGx5RmlsdGVycygpO1xuXG4gICAgLy8gUmVtb3ZlIGludmFsaWQgbm9kZXMgZnJvbSBtYXBcbiAgICBmb3IgKGNvbnN0IHJvd0lkIG9mIHRoaXMuX29yaWdpbmFsUm93Tm9kZXMua2V5cygpKSB7XG5cbiAgICAgIGlmICghdmFsaWRSb3dJZHMuaGFzKHJvd0lkKSkge1xuXG4gICAgICAgIHRoaXMuX29yaWdpbmFsUm93Tm9kZXMuZGVsZXRlKHJvd0lkKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVjdXJzaXZlIEJ1aWxkIFJvdyBOb2RlcyAoT3B0aW1pemVkKVxuICAgKi9cbiAgcHJpdmF0ZSBidWlsZFJvd05vZGVzPFQ+KFxuICAgIHJvd0RhdGE6IFRbXSxcbiAgICBwYXJlbnQ6IE9uZVJvd05vZGU8VD4gfCBudWxsID0gbnVsbCxcbiAgICBsZXZlbDogbnVtYmVyID0gMCxcbiAgICB2YWxpZFJvd0lkczogU2V0PHN0cmluZz4gPSBuZXcgU2V0KCksXG4gICAgZXhwYW5kZWRJZHM6IFNldDxzdHJpbmc+ID0gbmV3IFNldCh0aGlzLmV4cGFuc2lvblNlcnZpY2UuZ2V0RXhwYW5kZWRJZHMoKSksXG4gICAgY29sbGFwc2VkSWRzOiBTZXQ8c3RyaW5nPiA9IG5ldyBTZXQodGhpcy5leHBhbnNpb25TZXJ2aWNlLmdldENvbGxhcHNlZElkcygpKSxcbiAgICBzZWxlY3RlZElkczogU2V0PHN0cmluZz4gPSBuZXcgU2V0KHRoaXMuc2VsZWN0aW9uU2VydmljZS5nZXRTZWxlY3RlZElkcygpKVxuICApOiBPbmVSb3dOb2RlW10ge1xuXG4gICAgaWYgKHBhcmVudCA9PT0gbnVsbCkge1xuXG4gICAgICB0aGlzLnJvd05vZGVzID0gW107XG4gICAgICB0aGlzLl9jdXJyZW50SW5kZXggPSAwO1xuICAgIH1cblxuICAgIGlmICghcm93RGF0YT8ubGVuZ3RoKSByZXR1cm4gW107XG5cbiAgICBjb25zdCBub2RlczogT25lUm93Tm9kZTxUPltdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IGRhdGEgb2Ygcm93RGF0YSkge1xuXG4gICAgICBjb25zdCByb3dJZCA9IHRoaXMucm93U2VydmljZS5nZW5lcmF0ZVJvd0lkKGRhdGEsIHRoaXMuX2N1cnJlbnRJbmRleCk7XG4gICAgICBjb25zdCBjaGlsZHJlbiA9IChkYXRhIGFzIGFueSlbdGhpcy50cmVlRGF0YUNoaWxkcmVuRmllbGRdIHx8IG51bGw7XG5cbiAgICAgIGxldCBub2RlOiBPbmVSb3dOb2RlID0gdGhpcy5fb3JpZ2luYWxSb3dOb2Rlcy5nZXQocm93SWQpO1xuXG4gICAgICB2YWxpZFJvd0lkcy5hZGQocm93SWQpO1xuXG4gICAgICBpZiAobm9kZSkge1xuXG4gICAgICAgIG5vZGUuZGF0YSA9IGRhdGE7XG4gICAgICAgIG5vZGUuc2V0Um93SW5kZXgodGhpcy5fY3VycmVudEluZGV4KTtcblxuICAgICAgfSBlbHNlIHtcblxuICAgICAgICBub2RlID0gbmV3IE9uZVJvd05vZGU8VD4ocm93SWQsIGRhdGEsIHRoaXMuX2N1cnJlbnRJbmRleCk7XG4gICAgICAgIG5vZGUubGV2ZWwgPSBsZXZlbDtcbiAgICAgICAgbm9kZS5wYXJlbnQgPSBwYXJlbnQ7XG4gICAgICAgIG5vZGUuZGV0YWlsUmVuZGVyZXJDb21wb25lbnQgPSB0aGlzLmRldGFpbFJlbmRlcmVyQ29tcG9uZW50O1xuXG4gICAgICAgIHRoaXMuX29yaWdpbmFsUm93Tm9kZXMuc2V0KHJvd0lkLCBub2RlKTtcblxuICAgICAgICBpZiAodGhpcy5tYXN0ZXJEZXRhaWwpIHtcblxuICAgICAgICAgIHRoaXMuc3Vic2NyaWJlVG9EZXRhaWxDaGFuZ2VzKG5vZGUpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNoaWxkcmVuRXhpc3QgPSBjaGlsZHJlbiAmJiBjaGlsZHJlbi5sZW5ndGggPj0gMDtcblxuICAgICAgbm9kZS5ncm91cCA9IHRoaXMubWFzdGVyRGV0YWlsID8gZmFsc2UgOiBjaGlsZHJlbkV4aXN0O1xuICAgICAgbm9kZS5sZWFmID0gdGhpcy5tYXN0ZXJEZXRhaWwgPyB0cnVlIDogIW5vZGUuZ3JvdXA7XG4gICAgICBub2RlLmxlYWZHcm91cCA9IHRoaXMubWFzdGVyRGV0YWlsID8gZmFsc2UgOiAobm9kZS5ncm91cCAmJiAhY2hpbGRyZW5FeGlzdCk7XG4gICAgICBub2RlLmV4cGFuZGFibGUgPSB0aGlzLm1hc3RlckRldGFpbCA/IHRydWUgOiAobm9kZS5ncm91cCAmJiAhbm9kZS5sZWFmR3JvdXApO1xuXG4gICAgICBjb25zdCBkZWZhdWx0RXhwYW5kZWQgPSBub2RlLmV4cGFuZGFibGUgJiYgKGxldmVsIDwgdGhpcy5ncm91cERlZmF1bHRFeHBhbmRlZCB8fCB0aGlzLmdyb3VwRGVmYXVsdEV4cGFuZGVkID09PSAtMSk7XG5cbiAgICAgIG5vZGUuc2V0RXhwYW5kZWQoZXhwYW5kZWRJZHMuaGFzKHJvd0lkKSA/IHRydWUgOiBjb2xsYXBzZWRJZHMuaGFzKHJvd0lkKSA/IGZhbHNlIDogZGVmYXVsdEV4cGFuZGVkKTtcbiAgICAgIG5vZGUuc2V0U2VsZWN0ZWQoc2VsZWN0ZWRJZHMuaGFzKHJvd0lkKSk7XG4gICAgICBub2RlLnNldENlbGxTdGF0ZXModGhpcy5jZWxsU2VydmljZS5nZW5lcmF0ZUNlbGxTdGF0ZXMobm9kZSkpO1xuXG4gICAgICBpZiAodGhpcy5tYXN0ZXJEZXRhaWwgJiYgdGhpcy5hcGlUeXBlID09PSAnbWFzdGVyJykge1xuXG4gICAgICAgIHRoaXMuZ2V0RGV0YWlsUm93RGF0YSh7IGRhdGEsIG5vZGU6IG5vZGUsIHN1Y2Nlc3NDYWxsYmFjazogKGRldGFpbFJvd0RhdGEpID0+IG5vZGUuc2V0RGV0YWlsUm93RGF0YShkZXRhaWxSb3dEYXRhKSB9KTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fY3VycmVudEluZGV4Kys7XG4gICAgICB0aGlzLnJvd05vZGVzLnB1c2gobm9kZSk7XG5cbiAgICAgIG5vZGVzLnB1c2gobm9kZSk7XG5cbiAgICAgIG5vZGUuY2hpbGRyZW4gPSB0aGlzLnRyZWVEYXRhICYmIGNoaWxkcmVuRXhpc3QgPyB0aGlzLmJ1aWxkUm93Tm9kZXMoY2hpbGRyZW4gfHwgW10sIG5vZGUsIGxldmVsICsgMSwgdmFsaWRSb3dJZHMsIGV4cGFuZGVkSWRzLCBjb2xsYXBzZWRJZHMsIHNlbGVjdGVkSWRzKSA6IFtdO1xuICAgIH1cblxuICAgIHJldHVybiBub2RlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXIgRmVhdHVyZVxuICAgKi9cbiAgcHJpdmF0ZSBhcHBseUZpbHRlcnMoKTogdm9pZCB7XG5cbiAgICBjb25zdCBmaWx0ZXJzID0gdGhpcy5fYWN0aXZlRmlsdGVycztcblxuICAgIGNvbnN0IHF1aWNrID0gdGhpcy5fcXVpY2tGaWx0ZXJWYWx1ZT8udG9Mb3dlckNhc2UoKSA/PyAnJztcblxuICAgIHRoaXMucm93Tm9kZXMuZm9yRWFjaChub2RlID0+IGZpbHRlclRyZWVOb2RlKG5vZGUsIGZpbHRlcnMsIHF1aWNrKSk7XG5cbiAgICB0aGlzLnJlZnJlc2hWaXNpYmxlTm9kZXMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgUm93IE5vZGVzIERpc3BsYXlcbiAgICovXG4gIHByaXZhdGUgcmVmcmVzaFZpc2libGVOb2RlcygpOiB2b2lkIHtcblxuICAgIGlmICh0aGlzLl9kZXN0cm95ZWQpIHJldHVybjtcblxuICAgIGNvbnN0IHZpc2libGVOb2RlczogT25lUm93Tm9kZVtdID0gW107XG5cbiAgICBsZXQgcm93TnVtYmVyID0gMTtcblxuICAgIGNvbnN0IHZpc2liaWxpdHlDYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBib29sZWFuPigpO1xuXG4gICAgZm9yIChjb25zdCBub2RlIG9mIHRoaXMucm93Tm9kZXMpIHtcblxuICAgICAgY29uc3QgcGFyZW50VmlzaWJsZSA9IG5vZGUucGFyZW50ID8gdmlzaWJpbGl0eUNhY2hlLmdldChub2RlLnBhcmVudC5yb3dJZCkgOiB0cnVlO1xuXG4gICAgICBjb25zdCBpc1Zpc2libGUgPSBub2RlLnZpc2libGUgJiYgcGFyZW50VmlzaWJsZSAmJiAoIW5vZGUucGFyZW50IHx8IG5vZGUucGFyZW50LmV4cGFuZGVkKTtcblxuICAgICAgdmlzaWJpbGl0eUNhY2hlLnNldChub2RlLnJvd0lkLCBpc1Zpc2libGUpO1xuXG4gICAgICBpZiAoaXNWaXNpYmxlKSB7XG5cbiAgICAgICAgbm9kZS5jZWxsU3RhdGVzWydfb25lUm93TnVtYmVyJ10gPSB7IHR5cGU6ICd0ZXh0JywgdmFsdWU6IHJvd051bWJlcisrIH07XG5cbiAgICAgICAgbm9kZS5jZWxsU3RhdGVzID0geyAuLi5ub2RlLmNlbGxTdGF0ZXMgfTtcblxuICAgICAgICB2aXNpYmxlTm9kZXMucHVzaChub2RlKTtcblxuICAgICAgfSBlbHNlIHtcblxuICAgICAgICBub2RlLmNlbGxTdGF0ZXNbJ19vbmVSb3dOdW1iZXInXSA9IHsgdHlwZTogJ25vbmUnLCB2YWx1ZTogbnVsbCB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuX3Zpc2libGVSb3dOb2RlcyA9IFsuLi52aXNpYmxlTm9kZXNdO1xuXG4gICAgdGhpcy5ldmVudFNlcnZpY2UuZGlzcGF0Y2hFdmVudCgncm93RGF0YUNoYW5nZWQnLCB7IG5vZGVzOiB2aXNpYmxlTm9kZXMgfSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0VmlzaWJsZVJvd05vZGVzKCk6IE9uZVJvd05vZGU8VD5bXSB7XG5cbiAgICByZXR1cm4gdGhpcy5fdmlzaWJsZVJvd05vZGVzO1xuICB9XG5cbiAgLyoqXG4gICAqIFNvcnRpbmcgTW9kZWwgRmVhdHVyZVxuICAgKi9cbiAgcHVibGljIG9uU29ydENoYW5nZWQoc29ydE1vZGVsOiBPbmVTb3J0TW9kZWw8VD5bXSkge1xuXG4gICAgdGhpcy5zb3J0TW9kZWwgPSBzb3J0TW9kZWw7XG5cbiAgICB0aGlzLmFwcGx5U29ydGluZygpO1xuXG4gICAgdGhpcy5ldmVudFNlcnZpY2UuZGlzcGF0Y2hFdmVudCgnc29ydENoYW5nZWQnLCB7IG5vZGVzOiB0aGlzLnJvd05vZGVzIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhcHBseVNvcnRpbmcoKTogdm9pZCB7XG5cbiAgICBpZiAodGhpcy5zb3J0TW9kZWwubGVuZ3RoID09PSAwKSB7XG5cbiAgICAgIHRoaXMucm93Tm9kZXMgPSBbLi4udGhpcy5fb3JpZ2luYWxSb3dOb2Rlcy52YWx1ZXMoKV07XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnJvd05vZGVzID0gWy4uLnRoaXMuX29yaWdpbmFsUm93Tm9kZXMudmFsdWVzKCldLnNvcnQoKGEsIGIpID0+IHtcblxuICAgICAgZm9yIChjb25zdCBzb3J0SXRlbSBvZiB0aGlzLnNvcnRNb2RlbCkge1xuXG4gICAgICAgIGNvbnN0IHsgY29sSWQsIHNvcnQgfSA9IHNvcnRJdGVtO1xuICAgICAgICBjb25zdCB2YWxBID0gZ2V0RmllbGRWYWx1ZShhLmRhdGEsIGNvbElkIGFzIHN0cmluZyk7XG4gICAgICAgIGNvbnN0IHZhbEIgPSBnZXRGaWVsZFZhbHVlKGIuZGF0YSwgY29sSWQgYXMgc3RyaW5nKTtcbiAgICAgICAgY29uc3QgY29tcGFyaXNvblJlc3VsdCA9IHRoaXMuY29tcGFyZVZhbHVlcyh2YWxBLCB2YWxCLCBzb3J0KTtcblxuICAgICAgICBpZiAoY29tcGFyaXNvblJlc3VsdCAhPT0gMCkge1xuXG4gICAgICAgICAgcmV0dXJuIGNvbXBhcmlzb25SZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiAwO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBjb21wYXJlVmFsdWVzKHZhbEE6IGFueSwgdmFsQjogYW55LCBzb3J0RGlyZWN0aW9uOiAnYXNjJyB8ICdkZXNjJyk6IG51bWJlciB7XG5cbiAgICBpZiAodmFsQSA9PT0gbnVsbCAmJiB2YWxCID09PSBudWxsKSByZXR1cm4gMDtcbiAgICBpZiAodmFsQSA9PT0gbnVsbCkgcmV0dXJuIHNvcnREaXJlY3Rpb24gPT09ICdhc2MnID8gMSA6IC0xO1xuICAgIGlmICh2YWxCID09PSBudWxsKSByZXR1cm4gc29ydERpcmVjdGlvbiA9PT0gJ2FzYycgPyAtMSA6IDE7XG5cbiAgICBpZiAodHlwZW9mIHZhbEEgPT09ICdzdHJpbmcnICYmIHR5cGVvZiB2YWxCID09PSAnc3RyaW5nJykge1xuXG4gICAgICBjb25zdCBjb21wYXJpc29uID0gdmFsQS5sb2NhbGVDb21wYXJlKHZhbEIsIHVuZGVmaW5lZCwgeyBudW1lcmljOiB0cnVlIH0pO1xuICAgICAgcmV0dXJuIHNvcnREaXJlY3Rpb24gPT09ICdhc2MnID8gY29tcGFyaXNvbiA6IC1jb21wYXJpc29uO1xuICAgIH1cblxuICAgIGlmICh2YWxBIDwgdmFsQikgcmV0dXJuIHNvcnREaXJlY3Rpb24gPT09ICdhc2MnID8gLTEgOiAxO1xuICAgIGlmICh2YWxBID4gdmFsQikgcmV0dXJuIHNvcnREaXJlY3Rpb24gPT09ICdhc2MnID8gMSA6IC0xO1xuICAgIHJldHVybiAwO1xuICB9XG5cbiAgLyoqXG4gICAqIFJvdyBTZWxlY3Rpb24gRmVhdHVyZSAoT3B0aW1pemVkKVxuICAgKi9cbiAgcHVibGljIHNlbGVjdEFsbCgpOiB2b2lkIHtcblxuICAgIGNvbnN0IHJvd0lkczogc3RyaW5nW10gPSBbXTtcblxuICAgIHRoaXMuX29yaWdpbmFsUm93Tm9kZXMuZm9yRWFjaChub2RlID0+IHtcblxuICAgICAgbm9kZS5zZXRTZWxlY3RlZCh0cnVlKTtcblxuICAgICAgbm9kZS5jZWxsU3RhdGVzID0geyAuLi5ub2RlLmNlbGxTdGF0ZXMgfTtcblxuICAgICAgcm93SWRzLnB1c2gobm9kZS5yb3dJZCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnNlbGVjdGlvblNlcnZpY2Uuc2VsZWN0QWxsKHJvd0lkcyk7XG5cbiAgICB0aGlzLmV2ZW50U2VydmljZS5kaXNwYXRjaEV2ZW50KCdzZWxlY3Rpb25DaGFuZ2VkJywgeyBhbGxOb2Rlc05vdFNlbGVjdGVkOiBmYWxzZSwgYWxsTm9kZXNTZWxlY3RlZDogdHJ1ZSwgc2VsZWN0ZWQ6IHRydWUsIG5vZGU6IG51bGwgfSk7XG4gIH1cblxuICAvKipcbiAgICogRGVzZWxlY3QgYWxsIG5vZGVzIChvcHRpbWl6ZWQpXG4gICAqL1xuICBwdWJsaWMgZGVzZWxlY3RBbGwoKTogdm9pZCB7XG5cbiAgICB0aGlzLl9vcmlnaW5hbFJvd05vZGVzLmZvckVhY2gobm9kZSA9PiB7XG5cbiAgICAgIG5vZGUuc2V0U2VsZWN0ZWQoZmFsc2UpO1xuXG4gICAgICBub2RlLmNlbGxTdGF0ZXMgPSB7IC4uLm5vZGUuY2VsbFN0YXRlcyB9O1xuICAgIH0pO1xuXG4gICAgdGhpcy5zZWxlY3Rpb25TZXJ2aWNlLmRlc2VsZWN0QWxsKCk7XG5cbiAgICBpZiAodGhpcy5zZWxlY3Rpb25TZXJ2aWNlLmdldFNlbGVjdGlvbk1vZGUoKSA9PT0gJ211bHRpcGxlJykge1xuXG4gICAgICB0aGlzLmV2ZW50U2VydmljZS5kaXNwYXRjaEV2ZW50KCdzZWxlY3Rpb25DaGFuZ2VkJywge1xuICAgICAgICBhbGxOb2Rlc05vdFNlbGVjdGVkOiB0cnVlLFxuICAgICAgICBhbGxOb2Rlc1NlbGVjdGVkOiBmYWxzZSxcbiAgICAgICAgc2VsZWN0ZWQ6IGZhbHNlLFxuICAgICAgICBub2RlOiBudWxsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgdG9nZ2xlU2VsZWN0aW9uKHJvd0lkOiBzdHJpbmcsIHNlbGVjdGVkOiBib29sZWFuKTogdm9pZCB7XG5cbiAgICBjb25zdCBub2RlID0gdGhpcy5nZXRSb3dOb2RlQnlJZChyb3dJZCk7XG5cbiAgICBpZiAobm9kZSkge1xuXG4gICAgICBub2RlLnNldFNlbGVjdGVkKHNlbGVjdGVkKTtcblxuICAgICAgdGhpcy5zZWxlY3Rpb25TZXJ2aWNlLnRvZ2dsZVNlbGVjdGlvbihyb3dJZCwgc2VsZWN0ZWQpO1xuXG4gICAgICB0aGlzLmV2ZW50U2VydmljZS5kaXNwYXRjaEV2ZW50KCdzZWxlY3Rpb25DaGFuZ2VkJywgeyBub2RlLCBkYXRhOiBub2RlLmRhdGEsIHNlbGVjdGVkIH0pO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBzZXRTZWxlY3RlZEJ5SWQocm93SWQ6IHN0cmluZykge1xuXG4gICAgY29uc3Qgbm9kZSA9IHRoaXMuZ2V0Um93Tm9kZUJ5SWQocm93SWQpO1xuXG4gICAgaWYgKG5vZGUpIHtcblxuICAgICAgaWYgKHRoaXMuc2VsZWN0aW9uU2VydmljZS5nZXRTZWxlY3Rpb25Nb2RlKCkgPT09ICdzaW5nbGUnKSB7XG5cbiAgICAgICAgdGhpcy5yb3dOb2Rlcy5mb3JFYWNoKHJvd05vZGUgPT4gcm93Tm9kZS5zZXRTZWxlY3RlZChyb3dOb2RlLnJvd0lkID09PSBub2RlLnJvd0lkKSk7XG5cbiAgICAgICAgdGhpcy5fb3JpZ2luYWxSb3dOb2Rlcy5mb3JFYWNoKHJvd05vZGUgPT4gcm93Tm9kZS5zZXRTZWxlY3RlZChyb3dOb2RlLnJvd0lkID09PSBub2RlLnJvd0lkKSk7XG5cbiAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgbm9kZS5zZXRTZWxlY3RlZCh0cnVlKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zZWxlY3Rpb25TZXJ2aWNlLnRvZ2dsZVNlbGVjdGlvbihyb3dJZCwgdHJ1ZSk7XG5cbiAgICAgIHRoaXMuZXZlbnRTZXJ2aWNlLmRpc3BhdGNoRXZlbnQoJ3NlbGVjdGlvbkNoYW5nZWQnLCB7IG5vZGUsIHNlbGVjdGVkOiB0cnVlIH0pO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBzZXRTZWxlY3RlZEJ5SWRzKHJvd0lkczogc3RyaW5nW10sIHNlbGVjdGVkOiBib29sZWFuID0gdHJ1ZSkge1xuXG4gICAgcm93SWRzLmZvckVhY2gocm93SWQgPT4ge1xuXG4gICAgICBjb25zdCBub2RlID0gdGhpcy5fb3JpZ2luYWxSb3dOb2Rlcy5nZXQocm93SWQpO1xuXG4gICAgICBpZiAobm9kZSkge1xuXG4gICAgICAgIG5vZGUuc2V0U2VsZWN0ZWQoc2VsZWN0ZWQpO1xuXG4gICAgICAgIG5vZGUuY2VsbFN0YXRlcyA9IHsgLi4ubm9kZS5jZWxsU3RhdGVzIH07XG5cbiAgICAgICAgdGhpcy5zZWxlY3Rpb25TZXJ2aWNlLnRvZ2dsZVNlbGVjdGlvbihyb3dJZCwgc2VsZWN0ZWQpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy5ldmVudFNlcnZpY2UuZGlzcGF0Y2hFdmVudCgnc2VsZWN0aW9uQ2hhbmdlZCcsIHsgbm9kZTogbnVsbCB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgJiBTZXQgRnVuY3Rpb25zXG4gICAqL1xuICBwdWJsaWMgZ2V0QWxsUm93Tm9kZXMoKTogT25lUm93Tm9kZTxUPltdIHtcblxuICAgIHJldHVybiB0aGlzLnJvd05vZGVzPy5sZW5ndGggPiAwID8gWy4uLnRoaXMucm93Tm9kZXNdIDogW107XG4gIH1cblxuICBwdWJsaWMgZ2V0Um93RGF0YVNlbGVjdGVkKCk6IFRbXSB7XG5cbiAgICByZXR1cm4gdGhpcy5yb3dOb2Rlcy5maWx0ZXIobm9kZSA9PiBub2RlLnNlbGVjdGVkKS5tYXAobm9kZSA9PiAoeyAuLi5ub2RlLmRhdGEgfSkpO1xuICB9XG5cbiAgcHVibGljIGdldFNlbGVjdGVkUm93Tm9kZXMoKTogT25lUm93Tm9kZTxUPltdIHtcblxuICAgIGNvbnN0IG5vZGVzID0gdGhpcy5yb3dOb2Rlcy5maWx0ZXIobm9kZSA9PiBub2RlLnNlbGVjdGVkKTtcblxuICAgIHJldHVybiBub2RlcyAmJiBub2Rlcy5sZW5ndGggPiAwID8gWy4uLm5vZGVzXSA6IFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbHVtbiBmaWx0ZXJzXG4gICAqL1xuICBwdWJsaWMgZ2V0RmlsdGVyTW9kZWwoKTogT25lRmlsdGVyTW9kZWxbXSB7XG5cbiAgICByZXR1cm4gdGhpcy5fYWN0aXZlRmlsdGVycztcbiAgfVxuXG4gIHB1YmxpYyBzZXRGaWx0ZXJNb2RlbChtb2RlbDogT25lRmlsdGVyTW9kZWxbXSk6IHZvaWQge1xuXG4gICAgdGhpcy5fYWN0aXZlRmlsdGVycyA9IG1vZGVsO1xuXG4gICAgdGhpcy5hcHBseUZpbHRlcnMoKTtcbiAgfVxuXG4gIHB1YmxpYyBmaWx0ZXJBY3RpdmUoZmllbGQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuXG4gICAgcmV0dXJuIHRoaXMuX2FjdGl2ZUZpbHRlcnMuc29tZShmID0+IGYuZmllbGQgPT09IGZpZWxkICYmIGYuY29uZGl0aW9ucy5sZW5ndGggPiAwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBRdWljayBmaWx0ZXJcbiAgICovXG4gIHB1YmxpYyBzZXRRdWlja0ZpbHRlcih2YWx1ZTogc3RyaW5nKTogdm9pZCB7XG5cbiAgICB0aGlzLl9xdWlja0ZpbHRlclZhbHVlID0gKHZhbHVlIHx8ICcnKS50b0xvd2VyQ2FzZSgpO1xuXG4gICAgdGhpcy5hcHBseUZpbHRlcnMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0aW9uIEZlYXR1cmVcbiAgICovXG4gIHB1YmxpYyB2YWxpZGF0ZVJvdzxUPihyb3c6IFQsIGNvbHVtbnM6IE9uZUNvbHVtbkRlZjxUPltdKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG5cbiAgICBjb25zdCBlcnJvcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblxuICAgIGNvbHVtbnMuZm9yRWFjaChjb2wgPT4ge1xuXG4gICAgICAvLyBPbmx5IGNoZWNrIGNvbHVtbnMgd2l0aCB2YWxpZGF0aW9uUnVsZVxuICAgICAgaWYgKCFjb2wudmFsaWRhdGlvblJ1bGVzIHx8IGNvbC52YWxpZGF0aW9uUnVsZXMubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICAgIGNvbnN0IHJ1bGVzID0gY29sLnZhbGlkYXRpb25SdWxlcztcblxuICAgICAgZm9yIChjb25zdCBydWxlIG9mIHJ1bGVzKSB7XG5cbiAgICAgICAgY29uc3QgZXJyb3IgPSBydWxlKHJvd1tjb2wuZmllbGRdLCByb3cpO1xuXG4gICAgICAgIGlmIChlcnJvcikge1xuXG4gICAgICAgICAgZXJyb3JzW2NvbC5maWVsZCBhcyBzdHJpbmddID0gZXJyb3I7XG5cbiAgICAgICAgICBicmVhazsgLy8gc3RvcCBhdCBmaXJzdCBlcnJvciBmb3IgdGhpcyBjb2x1bW5cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGVycm9ycztcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBhbGwgcm93cyBhbmQgcmV0dXJuIGJvdGggZXJyb3JzIGFuZCBhIGZsYWcgaW5kaWNhdGluZyBpZiB0aGVyZSBhcmUgYW55IGVycm9yc1xuICAgKi9cbiAgcHVibGljIHZhbGlkYXRlQWxsUm93czxUPihyb3dEYXRhOiBUW10sIGNvbHVtbnM6IE9uZUNvbHVtbkRlZjxUPltdKTogT25lVmFsaWRhdGlvblJlc3VsdDxUPiB7XG5cbiAgICBjb25zdCBhbGxFcnJvcnMgPSByb3dEYXRhLm1hcChyb3cgPT4ge1xuXG4gICAgICBjb25zdCBlcnJvcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblxuICAgICAgY29sdW1ucy5mb3JFYWNoKGNvbCA9PiB7XG5cbiAgICAgICAgaWYgKCFjb2wudmFsaWRhdGlvblJ1bGVzIHx8IGNvbC52YWxpZGF0aW9uUnVsZXMubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICAgICAgZm9yIChjb25zdCBydWxlIG9mIGNvbC52YWxpZGF0aW9uUnVsZXMpIHtcblxuICAgICAgICAgIGNvbnN0IGVycm9yID0gcnVsZShyb3dbY29sLmZpZWxkXSwgcm93KTtcblxuICAgICAgICAgIGlmIChlcnJvcikge1xuXG4gICAgICAgICAgICBlcnJvcnNbY29sLmZpZWxkIGFzIHN0cmluZ10gPSBlcnJvcjtcblxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGVycm9ycztcbiAgICB9KTtcblxuICAgIGNvbnN0IGhhc0Vycm9ycyA9IGFsbEVycm9ycy5zb21lKGVyciA9PiBPYmplY3Qua2V5cyhlcnIpLmxlbmd0aCA+IDApO1xuXG4gICAgcmV0dXJuIHsgZXJyb3JzOiBhbGxFcnJvcnMsIHZhbGlkOiAhaGFzRXJyb3JzLCBpbnZhbGlkOiBoYXNFcnJvcnMgfTtcbiAgfVxuXG4gIC8qKiBUcmF2ZXJzZSBhbGwgbm9kZXMgKi9cbiAgcHVibGljIGZvckVhY2hOb2RlKGNhbGxiYWNrOiAobm9kZTogT25lUm93Tm9kZTxUPiwgaW5kZXg6IG51bWJlcikgPT4gdm9pZCkge1xuXG4gICAgY29uc3QgdmlzaXQgPSAobm9kZXM6IE9uZVJvd05vZGU8VD5bXSkgPT4ge1xuXG4gICAgICBub2Rlcy5mb3JFYWNoKChub2RlLCBpbmRleCkgPT4ge1xuXG4gICAgICAgIGNhbGxiYWNrKG5vZGUsIGluZGV4KTtcblxuICAgICAgICBpZiAobm9kZT8uY2hpbGRyZW4/Lmxlbmd0aCkgdmlzaXQobm9kZS5jaGlsZHJlbik7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgdmlzaXQodGhpcy5yb3dOb2Rlcyk7XG4gIH1cblxuICAvKiogVHJhdmVyc2Ugb25seSBsZWFmIG5vZGVzICovXG4gIHB1YmxpYyBmb3JFYWNoTGVhZk5vZGUoY2FsbGJhY2s6IChub2RlOiBPbmVSb3dOb2RlPFQ+LCBpbmRleDogbnVtYmVyKSA9PiB2b2lkKSB7XG5cbiAgICBsZXQgbGVhZkluZGV4ID0gMDtcblxuICAgIGNvbnN0IHZpc2l0ID0gKG5vZGVzOiBPbmVSb3dOb2RlPFQ+W10pID0+IHtcblxuICAgICAgbm9kZXMuZm9yRWFjaChub2RlID0+IHtcblxuICAgICAgICBpZiAobm9kZS5sZWFmKSB7XG5cbiAgICAgICAgICBjYWxsYmFjayhub2RlLCBsZWFmSW5kZXgrKyk7XG5cbiAgICAgICAgfSBlbHNlIGlmIChub2RlLmdyb3VwICYmIG5vZGU/LmNoaWxkcmVuPy5sZW5ndGgpIHtcblxuICAgICAgICAgIHZpc2l0KG5vZGUuY2hpbGRyZW4pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgdmlzaXQodGhpcy5yb3dOb2Rlcyk7XG4gIH1cblxuICBwdWJsaWMgZ2V0Um93Tm9kZUJ5SWQocm93SWQ6IHN0cmluZyk6IE9uZVJvd05vZGU8VD4ge1xuXG4gICAgcmV0dXJuIHRoaXMuX29yaWdpbmFsUm93Tm9kZXMuZ2V0KHJvd0lkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBhbmQvY29sbGFwc2UgYSBub2RlXG4gICAqL1xuICBwdWJsaWMgc2V0VHJlZURhdGFDaGlsZHJlbkZpZWxkKGZpZWxkOiBzdHJpbmcpIHtcblxuICAgIHRoaXMudHJlZURhdGFDaGlsZHJlbkZpZWxkID0gZmllbGQ7XG4gIH1cblxuICBwdWJsaWMgc2V0R3JvdXBEZWZhdWx0RXhwYW5kZWQoZGVmYXVsdEV4cGFuZGVkOiBudW1iZXIpIHtcblxuICAgIHRoaXMuZ3JvdXBEZWZhdWx0RXhwYW5kZWQgPSBkZWZhdWx0RXhwYW5kZWQ7XG4gIH1cblxuICBwdWJsaWMgdG9nZ2xlRXhwYW5kQWxsKGV4cGFuZGVkOiBib29sZWFuKSB7XG5cbiAgICB0aGlzLmZvckVhY2hOb2RlKG5vZGUgPT4ge1xuXG4gICAgICBub2RlLnNldEV4cGFuZGVkKGV4cGFuZGVkKTtcblxuICAgICAgdGhpcy5leHBhbnNpb25TZXJ2aWNlLnRvZ2dsZUV4cGFuZGVkKG5vZGUucm93SWQsIGV4cGFuZGVkKVxuICAgIH0pO1xuXG4gICAgdGhpcy5yZWZyZXNoVmlzaWJsZU5vZGVzKCk7XG4gIH1cblxuICBwdWJsaWMgc2V0RXhwYW5kZWRCeUlkKHJvd0lkOiBzdHJpbmcsIGV4cGFuZGVkOiBib29sZWFuKSB7XG5cbiAgICBjb25zdCBub2RlID0gdGhpcy5fb3JpZ2luYWxSb3dOb2Rlcy5nZXQocm93SWQpO1xuXG4gICAgaWYgKG5vZGUpIHtcblxuICAgICAgbm9kZS5zZXRFeHBhbmRlZChleHBhbmRlZCk7XG5cbiAgICAgIHRoaXMuZXhwYW5zaW9uU2VydmljZS50b2dnbGVFeHBhbmRlZChyb3dJZCwgZXhwYW5kZWQpO1xuICAgIH1cblxuICAgIHRoaXMucmVmcmVzaFZpc2libGVOb2RlcygpO1xuICB9XG5cbiAgcHVibGljIHNldEV4cGFuZGVkQnlJZHMocm93SWRzOiBzdHJpbmdbXSwgZXhwYW5kZWQ6IGJvb2xlYW4pIHtcblxuICAgIGlmIChyb3dJZHMgJiYgcm93SWRzLmxlbmd0aCA+IDApIHtcblxuICAgICAgZm9yIChsZXQgcm93SWQgb2Ygcm93SWRzKSB7XG5cbiAgICAgICAgY29uc3Qgbm9kZSA9IHRoaXMuX29yaWdpbmFsUm93Tm9kZXMuZ2V0KHJvd0lkKTtcblxuICAgICAgICBpZiAobm9kZSkge1xuXG4gICAgICAgICAgbm9kZS5zZXRFeHBhbmRlZChleHBhbmRlZCk7XG5cbiAgICAgICAgICB0aGlzLmV4cGFuc2lvblNlcnZpY2UudG9nZ2xlRXhwYW5kZWQocm93SWQsIGV4cGFuZGVkKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLnJlZnJlc2hWaXNpYmxlTm9kZXMoKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZ2V0RXhwYW5kZWRCeUlkcygpOiBzdHJpbmdbXSB7XG5cbiAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLmV4cGFuc2lvblNlcnZpY2UuZ2V0RXhwYW5kZWRJZHMoKSk7XG4gIH1cblxuICAvKipcbiAgICogTWFzdGVyIERldGFpbCBGZWF0dXJlXG4gICAqL1xuICBwdWJsaWMgc2V0RGV0YWlsUm93RGF0YShub2RlOiBPbmVSb3dOb2RlPFQ+LCBkZXRhaWxEYXRhOiBhbnlbXSkge1xuXG4gICAgY29uc3Qgcm93Tm9kZSA9IHRoaXMuZ2V0Um93Tm9kZUJ5SWQobm9kZS5yb3dJZCk7XG5cbiAgICBpZiAocm93Tm9kZSkge1xuXG4gICAgICByb3dOb2RlLnNldERldGFpbFJvd0RhdGEoZGV0YWlsRGF0YSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHNldEdldERldGFpbFJvd0RhdGEoZ2V0RGV0YWlsUm93RGF0YTogKHBhcmFtczogT25lR2V0RGV0YWlsUm93RGF0YVBhcmFtcykgPT4gdm9pZCkge1xuXG4gICAgdGhpcy5nZXREZXRhaWxSb3dEYXRhID0gZ2V0RGV0YWlsUm93RGF0YTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb2x1bW5zIFN0YXRlXG4gICAqL1xuICBwdWJsaWMgZ2V0Q29sdW1uU3RhdGUoKTogQ29sdW1uQ2hhbmdlZEV2ZW50IHtcblxuICAgIHJldHVybiB0aGlzLmNvbHVtblNlcnZpY2UuZ2V0Q29sdW1uU3RhdGUoKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRDb2x1bW5EZWZzKGNvbHVtbkRlZnM6IE9uZUNvbHVtbkRlZjxUPltdKTogdm9pZCB7XG5cbiAgICB0aGlzLmNvbHVtblNlcnZpY2Uuc2V0Q29sdW1uRGVmcyhjb2x1bW5EZWZzKTtcblxuICAgIGNvbnN0IGNvbHVtblN0YXRlID0gdGhpcy5jb2x1bW5TZXJ2aWNlLmdldENvbHVtblN0YXRlKCk7XG5cbiAgICB0aGlzLmNlbGxTZXJ2aWNlLmFwcGx5Q29sdW1uRGVmcyhjb2x1bW5TdGF0ZS5jb2x1bW5zLCB0aGlzLmNvbnRleHQpO1xuXG4gICAgdGhpcy5ldmVudFNlcnZpY2UuZGlzcGF0Y2hFdmVudCgnY29sdW1uQ2hhbmdlZCcsIGNvbHVtblN0YXRlKTtcbiAgfVxuXG4gIHB1YmxpYyB1cGRhdGVDb2x1bW4oaWQ6IHN0cmluZywgY2hhbmdlczogUGFydGlhbDxPbmVDb2x1bW5EZWY8VD4+KTogdm9pZCB7XG5cbiAgICB0aGlzLmNvbHVtblNlcnZpY2UudXBkYXRlQ29sdW1uRGVmKGlkLCBjaGFuZ2VzKTtcblxuICAgIGNvbnN0IGNvbHVtblN0YXRlID0gdGhpcy5jb2x1bW5TZXJ2aWNlLmdldENvbHVtblN0YXRlKCk7XG5cbiAgICB0aGlzLmNlbGxTZXJ2aWNlLmFwcGx5Q29sdW1uRGVmcyhjb2x1bW5TdGF0ZS5jb2x1bW5zLCB0aGlzLmNvbnRleHQpO1xuXG4gICAgdGhpcy5ldmVudFNlcnZpY2UuZGlzcGF0Y2hFdmVudCgnY29sdW1uQ2hhbmdlZCcsIGNvbHVtblN0YXRlKTtcbiAgfVxuXG4gIHB1YmxpYyByZW9yZGVyQ29sdW1uRGVmcyhmcm9tSW5kZXg6IG51bWJlciwgdG9JbmRleDogbnVtYmVyKTogdm9pZCB7XG5cbiAgICB0aGlzLmNvbHVtblNlcnZpY2UucmVvcmRlckNvbHVtbkRlZnMoZnJvbUluZGV4LCB0b0luZGV4KTtcblxuICAgIGNvbnN0IGNvbHVtblN0YXRlID0gdGhpcy5jb2x1bW5TZXJ2aWNlLmdldENvbHVtblN0YXRlKCk7XG5cbiAgICB0aGlzLmV2ZW50U2VydmljZS5kaXNwYXRjaEV2ZW50KCdjb2x1bW5DaGFuZ2VkJywgY29sdW1uU3RhdGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSBjaGVja2JveCBzZWxlY3Rpb24gZmVhdHVyZXNcbiAgICovXG4gIHB1YmxpYyBzZXROb2RlQW5kQ2hpbGRyZW5TZWxlY3RlZChub2RlOiBPbmVSb3dOb2RlLCBzZWxlY3RlZDogYm9vbGVhbikge1xuXG4gICAgY29uc3Qgcm93SWRzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgICBjb25zdCBjb2xsZWN0ID0gKG46IE9uZVJvd05vZGUpID0+IHtcblxuICAgICAgcm93SWRzLmFkZChuLnJvd0lkKTtcblxuICAgICAgaWYgKG4uY2hpbGRyZW4gJiYgbi5jaGlsZHJlbi5sZW5ndGgpIHtcblxuICAgICAgICBuLmNoaWxkcmVuLmZvckVhY2goY2hpbGQgPT4gY29sbGVjdChjaGlsZCkpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBjb2xsZWN0KG5vZGUpO1xuXG4gICAgdGhpcy5zZXRTZWxlY3RlZEJ5SWRzKEFycmF5LmZyb20ocm93SWRzKSwgc2VsZWN0ZWQpO1xuICB9XG5cbiAgcHVibGljIHVwZGF0ZU5vZGVTdGF0ZXMobm9kZTogT25lUm93Tm9kZSkge1xuXG4gICAgY29uc3Qgcm93Tm9kZSA9IHRoaXMuZ2V0Um93Tm9kZUJ5SWQobm9kZS5yb3dJZCk7XG5cbiAgICBpZiAocm93Tm9kZSkge1xuXG4gICAgICByb3dOb2RlLmNlbGxTdGF0ZXMgPSB0aGlzLmNlbGxTZXJ2aWNlLmdlbmVyYXRlQ2VsbFN0YXRlcyhyb3dOb2RlKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgdXBkYXRlQ2VsbFN0YXRlKG5vZGU6IE9uZVJvd05vZGUsIGNvbHVtbjogT25lQ29sdW1uRGVmKTogdm9pZCB7XG5cbiAgICBjb25zdCByb3dOb2RlID0gdGhpcy5nZXRSb3dOb2RlQnlJZChub2RlLnJvd0lkKTtcblxuICAgIGlmIChyb3dOb2RlKSB7XG5cbiAgICAgIHJvd05vZGUuY2VsbFN0YXRlc1tjb2x1bW4uZmllbGRdID0gdGhpcy5jZWxsU2VydmljZS5nZW5lcmF0ZUNlbGxTdGF0ZShyb3dOb2RlLCBjb2x1bW4pO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyB1cGRhdGVDZWxsU3RhdGVzKG5vZGU6IE9uZVJvd05vZGUpOiB2b2lkIHtcblxuICAgIGNvbnN0IHJvd05vZGUgPSB0aGlzLmdldFJvd05vZGVCeUlkKG5vZGUucm93SWQpO1xuXG4gICAgaWYgKHJvd05vZGUpIHtcblxuICAgICAgcm93Tm9kZS5jZWxsU3RhdGVzID0gdGhpcy5jZWxsU2VydmljZS5nZW5lcmF0ZUNlbGxTdGF0ZXMocm93Tm9kZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZXIgdGhhdCBSZWFjdHMgdG8gRGV0YWlsIENoYW5nZXNcbiAgICovXG4gIHByaXZhdGUgc3Vic2NyaWJlVG9EZXRhaWxDaGFuZ2VzKG5vZGU6IE9uZVJvd05vZGUpOiB2b2lkIHtcblxuICAgIGNvbnN0IHVuc3ViUm93RGF0YSA9IG5vZGUub24oJ3Jvd0RhdGFDaGFuZ2VkJywgKHsgbm9kZSwgZGF0YSwgcHJldmlvdXNEYXRhIH0pID0+IHtcblxuXG4gICAgfSk7XG5cbiAgICAvLyBXaGVuIGRldGFpbCBkYXRhIGFycml2ZXNcbiAgICBjb25zdCB1bnN1YkRldGFpbCA9IG5vZGUub24oJ2RldGFpbFJvd0RhdGFDaGFuZ2VkJywgKHsgbm9kZSwgZGV0YWlsUm93RGF0YSwgcHJldmlvdXNEZXRhaWxSb3dEYXRhIH0pID0+IHtcblxuICAgICAgaWYgKHRoaXMuYXBpVHlwZSA9PT0gJ21hc3RlcicpIHtcblxuICAgICAgICB0aGlzLl9yZXNvbHZlZERldGFpbFJvd0hlaWdodChub2RlKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIFdoZW4gcm93IGV4cGFuZHNcbiAgICBjb25zdCB1bnN1YkV4cGFuZCA9IG5vZGUub24oJ2V4cGFuZGVkQ2hhbmdlZCcsICh7IG5vZGUsIGV4cGFuZGVkIH0pID0+IHtcblxuICAgICAgLy8gaWYgKCFleHBhbmRlZCkgcmV0dXJuO1xuXG4gICAgICAvLyAvLyBPbmx5IGZldGNoIGlmIGRldGFpbCBkYXRhIG5vdCBhbHJlYWR5IGxvYWRlZFxuICAgICAgLy8gaWYgKCFub2RlLmRldGFpbFJvd0RhdGEpIHtcblxuICAgICAgLy8gICB0aGlzLmdldERldGFpbFJvd0RhdGEoeyBkYXRhOiBub2RlLmRhdGEsIG5vZGUsIHN1Y2Nlc3NDYWxsYmFjazogKGRldGFpbFJvd0RhdGEpID0+IG5vZGUuc2V0RGV0YWlsUm93RGF0YShkZXRhaWxSb3dEYXRhKSB9KTtcbiAgICAgIC8vIH1cbiAgICB9KTtcblxuICAgIC8vIC8vIENsZWFudXAgd2hlbiBub2RlIGlzIHJlbW92ZWQgZnJvbSBncmlkXG4gICAgdGhpcy5yZWdpc3Rlck5vZGVDbGVhbnVwKG5vZGUucm93SWQsIFt1bnN1YkRldGFpbCwgdW5zdWJFeHBhbmRdKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVnaXN0ZXJOb2RlQ2xlYW51cChyb3dJZDogc3RyaW5nLCB1bnN1YnM6IEFycmF5PCgpID0+IHZvaWQ+KTogdm9pZCB7XG5cbiAgICAvLyBNZXJnZSB3aXRoIGFueSBleGlzdGluZyBjbGVhbnVwcyBmb3IgdGhpcyByb3dJZFxuICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy5fbm9kZUNsZWFudXBNYXAuZ2V0KHJvd0lkKSA/PyBbXTtcblxuICAgIHRoaXMuX25vZGVDbGVhbnVwTWFwLnNldChyb3dJZCwgWy4uLmV4aXN0aW5nLCAuLi51bnN1YnNdKTtcbiAgfVxuXG4gIHByaXZhdGUgY2xlYW51cE5vZGUocm93SWQ6IHN0cmluZyk6IHZvaWQge1xuXG4gICAgY29uc3QgY2xlYW51cHMgPSB0aGlzLl9ub2RlQ2xlYW51cE1hcC5nZXQocm93SWQpO1xuXG4gICAgY2xlYW51cHM/LmZvckVhY2goZm4gPT4gZm4oKSk7XG5cbiAgICB0aGlzLl9ub2RlQ2xlYW51cE1hcC5kZWxldGUocm93SWQpO1xuICB9XG5cbiAgLy8gQ2FsbCB0aGlzIHdoZW4gcm93cyBhcmUgcmVtb3ZlZFxuICBwcml2YXRlIHBydW5lUmVtb3ZlZE5vZGVzKHZhbGlkUm93SWRzOiBTZXQ8c3RyaW5nPik6IHZvaWQge1xuXG4gICAgZm9yIChjb25zdCBbcm93SWQsIG5vZGVdIG9mIHRoaXMuX29yaWdpbmFsUm93Tm9kZXMpIHtcblxuICAgICAgaWYgKCF2YWxpZFJvd0lkcy5oYXMocm93SWQpKSB7XG5cbiAgICAgICAgdGhpcy5jbGVhbnVwTm9kZShyb3dJZCk7ICAvLyB1bnN1YnNjcmliZSBsaXN0ZW5lcnNcblxuICAgICAgICBub2RlLmRlc3Ryb3koKTsgICAgICAgICAgIC8vIGNsZWFyIG5vZGUncyBvd24gbGlzdGVuZXIgbWFwXG5cbiAgICAgICAgdGhpcy5fb3JpZ2luYWxSb3dOb2Rlcy5kZWxldGUocm93SWQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlIERldGFpbCBSb3cgSGVpZ2h0XG4gICAqL1xuICBwcml2YXRlIF9yZXNvbHZlZERldGFpbFJvd0hlaWdodChub2RlOiBPbmVSb3dOb2RlKTogdm9pZCB7XG5cbiAgICBjb25zdCBtaW5Sb3dzID0gdGhpcy5kZXRhaWxDZWxsUmVuZGVyZXJQYXJhbXMuZGV0YWlsR3JpZE9wdGlvbnMuZGV0YWlsUm93SGVpZ2h0T3B0aW9ucy5taW5Sb3dzO1xuICAgIGNvbnN0IG1heFJvd3MgPSB0aGlzLmRldGFpbENlbGxSZW5kZXJlclBhcmFtcy5kZXRhaWxHcmlkT3B0aW9ucy5kZXRhaWxSb3dIZWlnaHRPcHRpb25zLm1heFJvd3M7XG5cbiAgICBjb25zdCBtaW5IZWlnaHQgPSAodGhpcy5yb3dIZWlnaHQgKiBtaW5Sb3dzKSArIHRoaXMuaGVhZGVyUm93SGVpZ2h0O1xuICAgIGNvbnN0IG1heEhlaWdodCA9ICh0aGlzLnJvd0hlaWdodCAqIG1heFJvd3MpICsgdGhpcy5oZWFkZXJSb3dIZWlnaHQ7XG5cbiAgICBjb25zdCByb3dzID0gbm9kZS5kZXRhaWxSb3dEYXRhICYmIG5vZGUuZGV0YWlsUm93RGF0YS5sZW5ndGggPyBub2RlLmRldGFpbFJvd0RhdGEubGVuZ3RoIDogMDtcblxuICAgIG5vZGUuZGV0YWlsUm93SGVpZ2h0ID0gcm93cyA8PSBtaW5Sb3dzID8gbWluSGVpZ2h0IDogcm93cyA+PSBtYXhSb3dzID8gbWF4SGVpZ2h0IDogKHRoaXMucm93SGVpZ2h0ICogcm93cykgKyB0aGlzLmhlYWRlclJvd0hlaWdodDtcbiAgfVxuXG4gIC8qKlxuICAgKiBPbiBEZXN0cm95XG4gICAqL1xuICBwdWJsaWMgZGVzdHJveSgpOiB2b2lkIHtcblxuICAgIGlmICh0aGlzLl9kZXN0cm95ZWQpIHJldHVybjtcblxuICAgIHRoaXMuX2Rlc3Ryb3llZCA9IHRydWU7XG5cbiAgICB0aGlzLnJvd05vZGVzLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICBub2RlLmNoaWxkcmVuID0gW107XG4gICAgICBub2RlLnBhcmVudCA9IG51bGw7XG4gICAgfSk7XG5cbiAgICB0aGlzLnJvd05vZGVzID0gW107XG4gICAgdGhpcy5fb3JpZ2luYWxSb3dOb2Rlcy5jbGVhcigpO1xuICAgIHRoaXMuX2N1cnJlbnRJbmRleCA9IG51bGw7XG5cbiAgICAvLyBDbGVhciBzZXJ2aWNlc1xuICAgIGlmICh0aGlzLnNlbGVjdGlvblNlcnZpY2UpIHtcbiAgICAgIHRoaXMuc2VsZWN0aW9uU2VydmljZS5kZXNlbGVjdEFsbCgpO1xuICAgIH1cbiAgICB0aGlzLnNlbGVjdGlvblNlcnZpY2UgPSBudWxsIGFzIGFueTtcblxuICAgIGlmICh0aGlzLmV4cGFuc2lvblNlcnZpY2UpIHtcbiAgICAgIHRoaXMuZXhwYW5zaW9uU2VydmljZS5jbGVhcigpO1xuICAgIH1cbiAgICB0aGlzLmV4cGFuc2lvblNlcnZpY2UgPSBudWxsIGFzIGFueTtcblxuICAgIHRoaXMuZXZlbnRTZXJ2aWNlID0gbnVsbCBhcyBhbnk7XG4gICAgdGhpcy5yb3dTZXJ2aWNlID0gbnVsbCBhcyBhbnk7XG4gICAgdGhpcy5jZWxsU2VydmljZSA9IG51bGwgYXMgYW55O1xuXG4gICAgLy8gQ2xlYXIgZmlsdGVycywgc29ydGluZywgY29udGV4dFxuICAgIHRoaXMuX2FjdGl2ZUZpbHRlcnMgPSBbXTtcbiAgICB0aGlzLl9xdWlja0ZpbHRlclZhbHVlID0gbnVsbDtcbiAgICB0aGlzLnNvcnRNb2RlbCA9IFtdO1xuXG4gICAgLy8gQ2xlYXIgbWFzdGVyL2RldGFpbC90cmVlRGF0YVxuICAgIHRoaXMubWFzdGVyRGV0YWlsID0gZmFsc2U7XG4gICAgdGhpcy50cmVlRGF0YSA9IGZhbHNlO1xuICAgIHRoaXMudHJlZURhdGFDaGlsZHJlbkZpZWxkID0gJyc7XG4gICAgdGhpcy5ncm91cERlZmF1bHRFeHBhbmRlZCA9IDA7XG4gIH1cbn1cbiJdfQ==
854
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib25lLWdyaWQtYXBpLmNsYXNzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvb25lLWdyaWQvc3JjL2xpYi9jb3JlL2luc3RhbnRzL29uZS1ncmlkLWFwaS5jbGFzcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFTbEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxjQUFjLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUVqRixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFFOUQsT0FBTyxFQUFFLEVBQUUsSUFBSSxNQUFNLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDcEMsT0FBTyxFQUFFLFVBQVUsRUFBUSxNQUFNLGVBQWUsQ0FBQzs7Ozs7Ozs7QUFNakQsTUFBTSxPQUFPLFVBQVU7SUFxQnJCLHdEQUF3RDtJQUN4RCxJQUFXLEVBQUU7UUFDWCxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUM7SUFDbEIsQ0FBQztJQUVELDBDQUEwQztJQUMxQyxJQUFXLE9BQU87UUFDaEIsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxzRkFBc0Y7SUFDdEYsSUFBVyxZQUFZO1FBQ3JCLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztJQUM1QixDQUFDO0lBRUQsc0VBQXNFO0lBQ3RFLElBQVcsT0FBTztRQUNoQixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUM7SUFDdkIsQ0FBQztJQUVELHFEQUFxRDtJQUNyRCxJQUFXLFFBQVE7UUFDakIsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQ3hCLENBQUM7SUFFRCx3RUFBd0U7SUFDeEUsSUFBVyxTQUFTO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUN6QixDQUFDO0lBK0JELFlBQ1UsYUFBOEIsRUFDOUIsVUFBNkIsRUFDN0IsV0FBK0IsRUFDL0IsWUFBaUMsRUFDakMsZ0JBQXlDLEVBQ3pDLGdCQUF5QztRQUx6QyxrQkFBYSxHQUFiLGFBQWEsQ0FBaUI7UUFDOUIsZUFBVSxHQUFWLFVBQVUsQ0FBbUI7UUFDN0IsZ0JBQVcsR0FBWCxXQUFXLENBQW9CO1FBQy9CLGlCQUFZLEdBQVosWUFBWSxDQUFxQjtRQUNqQyxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQXlCO1FBQ3pDLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBeUI7UUF2RTNDLGFBQVEsR0FBUSxJQUFJLENBQUM7UUFDckIsa0JBQWEsR0FBcUIsSUFBSSxDQUFDO1FBQ3ZDLGFBQVEsR0FBZ0IsSUFBSSxDQUFDO1FBQzdCLGNBQVMsR0FBb0IsRUFBRSxDQUFDO1FBQ2hDLGVBQVUsR0FBc0IsRUFBRSxDQUFDO1FBaUNuQyxjQUFTLEdBQVcsRUFBRSxDQUFDO1FBQ3ZCLG9CQUFlLEdBQVcsRUFBRSxDQUFDO1FBQzdCLGtCQUFhLEdBQVcsQ0FBQyxDQUFDO1FBQzFCLHNCQUFpQixHQUFXLElBQUksQ0FBQztRQUNqQyxtQkFBYyxHQUFxQixFQUFFLENBQUM7UUFFdEMscUJBQWdCLEdBQW9CLEVBQUUsQ0FBQztRQUM5QixvQkFBZSxHQUE4QyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxDQUFDO1FBQzlGLHNCQUFpQixHQUErQixJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQzFELG9CQUFlLEdBQUcsSUFBSSxHQUFHLEVBQTZCLENBQUMsQ0FBQywyQ0FBMkM7UUFDbkcsZUFBVSxHQUFZLEtBQUssQ0FBQztRQUVwQyxvQkFBb0I7UUFDWixhQUFRLEdBQVksS0FBSyxDQUFDO1FBQzFCLDBCQUFxQixHQUFXLElBQUksQ0FBQztRQUNyQyx5QkFBb0IsR0FBVyxDQUFDLENBQUM7UUFFakMsaUJBQVksR0FBWSxLQUFLLENBQUM7SUFrQmxDLENBQUM7SUFFTDs7Ozs7Ozs7O09BU0c7SUFDSCxJQUFJLENBQUMsT0FBOEI7UUFFakMsTUFBTSxFQUNKLFFBQVEsRUFDUixVQUFVLEVBQ1YsZ0JBQWdCLEdBQUcsRUFBRSxFQUNyQixlQUFlLEdBQUcsRUFBRSxFQUNwQixPQUFPLEdBQUcsSUFBSSxFQUNkLFlBQVksR0FBRyxJQUFJLEVBQ25CLFlBQVksR0FBRyxLQUFLLEVBQ3BCLHdCQUF3QixHQUFHLElBQUksRUFDL0IsdUJBQXVCLEdBQUcsSUFBSSxFQUM5QixRQUFRLEdBQUcsS0FBSyxHQUNqQixHQUFHLE9BQU8sQ0FBQztRQUVaLElBQUksQ0FBQyxHQUFHLEdBQUcsTUFBTSxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFDekIsSUFBSSxDQUFDLGFBQWEsR0FBRyxZQUFZLENBQUM7UUFDbEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUM7UUFDeEIsSUFBSSxDQUFDLFlBQVksR0FBRyxZQUFZLENBQUM7UUFDakMsSUFBSSxDQUFDLHdCQUF3QixHQUFHLHdCQUF3QixDQUFDO1FBQ3pELElBQUksQ0FBQyx1QkFBdUIsR0FBRyx1QkFBdUIsQ0FBQztRQUN2RCxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUV6QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDckQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsT0FBTyxFQUFFLGVBQWUsRUFBRSxRQUFRLElBQUksSUFBSSxDQUFDLENBQUM7UUFFMUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQUMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ3RELElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2xDLElBQUksQ0FBQyxhQUFhLENBQUMsY0FBYyxDQUFDLGdCQUFnQixFQUFFLFVBQVUsRUFBRSxlQUFlLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFMUYsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUV4RCxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhLENBQUMsZUFBZSxFQUFFLFdBQWlDLENBQUMsQ0FBQyxDQUFDO0lBQ3hHLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNJLFVBQVUsQ0FBQyxPQUFZO1FBRTVCLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxhQUFhLENBQUMsT0FBWTtRQUUvQixJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLFdBQVcsQ0FBQyxPQUFZLEVBQUUsVUFBbUI7UUFFbkQsSUFBSSxJQUFJLENBQUMsVUFBVTtZQUFFLE9BQU87UUFFNUIsSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUVmLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNwQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDaEMsQ0FBQztRQUVELE1BQU0sV0FBVyxHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7UUFFdEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FBQztRQUVsRCx5RUFBeUU7UUFDekUsMEVBQTBFO1FBQzFFLHdFQUF3RTtRQUN4RSxxRUFBcUU7UUFDckUsd0VBQXdFO1FBQ3hFLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQztZQUFFLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUVwRCxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFFcEIsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFRDs7T0FFRztJQUNLLGFBQWEsQ0FDbkIsT0FBWSxFQUNaLFNBQStCLElBQUksRUFDbkMsUUFBZ0IsQ0FBQyxFQUNqQixjQUEyQixJQUFJLEdBQUcsRUFBRSxFQUNwQyxjQUEyQixJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsY0FBYyxFQUFFLENBQUMsRUFDMUUsZUFBNEIsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGVBQWUsRUFBRSxDQUFDLEVBQzVFLGNBQTJCLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUcxRSxJQUFJLE1BQU0sS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUVwQixJQUFJLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQztZQUNwQixJQUFJLENBQUMsYUFBYSxHQUFHLENBQUMsQ0FBQztRQUN6QixDQUFDO1FBRUQsSUFBSSxDQUFDLE9BQU8sRUFBRSxNQUFNO1lBQUUsT0FBTyxFQUFFLENBQUM7UUFFaEMsTUFBTSxLQUFLLEdBQW9CLEVBQUUsQ0FBQztRQUVsQyxLQUFLLE1BQU0sSUFBSSxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBRTNCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDdEUsTUFBTSxRQUFRLEdBQUksSUFBWSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLElBQUksQ0FBQztZQUVuRSxJQUFJLElBQUksR0FBZSxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRXpELFdBQVcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFdkIsSUFBSSxJQUFJLEVBQUUsQ0FBQztnQkFFVCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztnQkFDakIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7WUFFdkMsQ0FBQztpQkFBTSxDQUFDO2dCQUVOLElBQUksR0FBRyxJQUFJLFVBQVUsQ0FBSSxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztnQkFDMUQsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7Z0JBQ25CLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO2dCQUNyQixJQUFJLENBQUMsdUJBQXVCLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDO2dCQUU1RCxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFFeEMsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7b0JBRXRCLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDdEMsQ0FBQztZQUNILENBQUM7WUFFRCxNQUFNLGFBQWEsR0FBRyxRQUFRLElBQUksUUFBUSxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUM7WUFFdkQseUVBQXlFO1lBQ3pFLHlFQUF5RTtZQUN6RSx5RUFBeUU7WUFDekUsbUNBQW1DO1lBQ25DLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDO1lBQ3pELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7WUFDbkQsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQzVFLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7WUFFN0UsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLFVBQVUsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsb0JBQW9CLElBQUksSUFBSSxDQUFDLG9CQUFvQixLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFbkgsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDcEcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDekMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7WUFFOUQsSUFBSSxJQUFJLENBQUMsWUFBWSxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBRXBELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLGVBQWUsRUFBRSxDQUFDLGFBQWEsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUN6SCxDQUFDO1lBRUQsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3JCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBRTFCLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFFakIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxJQUFJLGFBQWEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLElBQUksRUFBRSxFQUFFLElBQUksRUFBRSxLQUFLLEdBQUcsQ0FBQyxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDakssQ0FBQztRQUVELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVEOztPQUVHO0lBQ0ssWUFBWTtRQUVsQixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDO1FBRXBDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLENBQUM7UUFFMUQsMEVBQTBFO1FBQzFFLDBFQUEwRTtRQUMxRSw2Q0FBNkM7UUFDN0MsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFFeEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUU3RSxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztJQUM3QixDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ssaUJBQWlCO1FBRXZCLE9BQU8sSUFBSSxDQUFDLGFBQWE7YUFDdEIsY0FBYyxFQUFFO2FBQ2hCLE9BQU87YUFDUCxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBZSxDQUFDO2FBQ3JDLE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBbUIsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksS0FBSyxLQUFLLGVBQWUsQ0FBQyxDQUFDO0lBQzlFLENBQUM7SUFFRDs7T0FFRztJQUNLLG1CQUFtQixDQUFDLFdBQW9CLElBQUk7UUFFbEQsSUFBSSxJQUFJLENBQUMsVUFBVTtZQUFFLE9BQU87UUFFNUIsTUFBTSxZQUFZLEdBQWlCLEVBQUUsQ0FBQztRQUV0QyxJQUFJLFNBQVMsR0FBRyxDQUFDLENBQUM7UUFFbEIsTUFBTSxlQUFlLEdBQUcsSUFBSSxHQUFHLEVBQW1CLENBQUM7UUFFbkQsS0FBSyxNQUFNLElBQUksSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFFbEMsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7WUFFbEYsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLE9BQU8sSUFBSSxhQUFhLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUUxRixlQUFlLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFFM0MsSUFBSSxTQUFTLEVBQUUsQ0FBQztnQkFFZCxJQUFJLENBQUMsVUFBVSxDQUFDLGVBQWUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLEVBQUUsQ0FBQztnQkFFeEUsSUFBSSxDQUFDLFVBQVUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO2dCQUV6QyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBRTFCLENBQUM7aUJBQU0sQ0FBQztnQkFFTixJQUFJLENBQUMsVUFBVSxDQUFDLGVBQWUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUM7WUFDbkUsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsQ0FBQyxHQUFHLFlBQVksQ0FBQyxDQUFDO1FBRTFDLElBQUksUUFBUTtZQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLGdCQUFnQixFQUFFLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUM7SUFDM0YsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNJLGdCQUFnQixDQUFDLElBQXNCLEVBQUUsT0FBWTtRQUUxRCxJQUFJLElBQUksQ0FBQyxVQUFVO1lBQUUsT0FBTztRQUU1QixLQUFLLE1BQU0sSUFBSSxJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDO1lBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBRTlELElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFO1lBRS9ELDBFQUEwRTtZQUMxRSwwRUFBMEU7WUFDMUUsd0NBQXdDO1lBQ3hDLE1BQU0sSUFBSSxHQUFHLElBQUksVUFBVSxDQUFJLGNBQWMsSUFBSSxJQUFJLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztZQUUzRSxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQztZQUNmLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1lBQ2pCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO1lBQ3BCLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBRTlELE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxzQkFBc0IsRUFBRTtZQUN0RCxJQUFJO1lBQ0osS0FBSyxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDO1NBQ2xDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxxRkFBcUY7SUFDOUUsaUJBQWlCLENBQUMsSUFBc0I7UUFFN0MsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRDs7Ozs7Ozs7O09BU0c7SUFFSDs7Ozs7T0FLRztJQUNJLDBCQUEwQjtRQUUvQixJQUFJLElBQUksQ0FBQyxRQUFRO1lBQUUsT0FBTyxVQUFVLENBQUM7UUFFckMsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDO1lBQUUsT0FBTyxRQUFRLENBQUM7UUFFaEQsSUFBSSxjQUFjLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxJQUFJLENBQUMsaUJBQWlCLElBQUksRUFBRSxDQUFDO1lBQUUsT0FBTyxVQUFVLENBQUM7UUFFekYsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsaUVBQWlFO0lBQzFELGNBQWM7UUFFbkIsT0FBTyxJQUFJLENBQUMsMEJBQTBCLEVBQUUsS0FBSyxJQUFJLENBQUM7SUFDcEQsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7T0FZRztJQUNJLE9BQU8sQ0FBQyxXQUFtQixFQUFFLFdBQW1CO1FBRXJELElBQUksSUFBSSxDQUFDLFVBQVU7WUFBRSxPQUFPLEtBQUssQ0FBQztRQUVsQyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRTtZQUFFLE9BQU8sS0FBSyxDQUFDO1FBRXpDLE1BQU0sS0FBSyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUVuRCxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDO1lBQUUsT0FBTyxLQUFLLENBQUM7UUFFbkYsSUFBSSxXQUFXLEdBQUcsQ0FBQyxJQUFJLFdBQVcsSUFBSSxLQUFLLENBQUMsTUFBTTtZQUFFLE9BQU8sS0FBSyxDQUFDO1FBRWpFLElBQUksV0FBVyxHQUFHLENBQUMsSUFBSSxXQUFXLElBQUksS0FBSyxDQUFDLE1BQU07WUFBRSxPQUFPLEtBQUssQ0FBQztRQUVqRSxJQUFJLFdBQVcsS0FBSyxXQUFXO1lBQUUsT0FBTyxLQUFLLENBQUM7UUFFOUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRTdDLEtBQUssQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUVwQywwRUFBMEU7UUFDMUUsNENBQTRDO1FBQzVDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV4RSxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztRQUV2QixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFFbkIsSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhLENBQUMsaUJBQWlCLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLGdCQUFtQyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQztRQUVuSyxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7O09BR0c7SUFDSSxXQUFXLENBQUMsS0FBYSxFQUFFLFdBQW1CO1FBRW5ELE1BQU0sV0FBVyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxLQUFLLEtBQUssQ0FBQyxDQUFDO1FBRWpHLE9BQU8sV0FBVyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQzdFLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSyxXQUFXO1FBRWpCLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBRWpFLHVFQUF1RTtRQUN2RSw0RUFBNEU7UUFDNUUsd0VBQXdFO1FBQ3hFLHNEQUFzRDtRQUN0RCxJQUFJLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDbEMsQ0FBQztJQUVNLGtCQUFrQjtRQUV2QixPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztJQUMvQixDQUFDO0lBRUQ7O09BRUc7SUFDSSxhQUFhLENBQUMsU0FBNEI7UUFFL0MsSUFBSSxJQUFJLENBQUMsVUFBVTtZQUFFLE9BQU87UUFFNUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUM7UUFFNUIsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBRXBCLElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLGFBQWEsRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQztJQUM1RSxDQUFDO0lBRU8sWUFBWTtRQUVsQixJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBRWpDLElBQUksQ0FBQyxTQUFTLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1lBRXRELE9BQU87UUFDVCxDQUFDO1FBRUQsSUFBSSxDQUFDLFNBQVMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO1lBRWxFLEtBQUssTUFBTSxRQUFRLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO2dCQUV2QyxNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxHQUFHLFFBQVEsQ0FBQztnQkFDakMsTUFBTSxJQUFJLEdBQUcsYUFBYSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsS0FBZSxDQUFDLENBQUM7Z0JBQ3BELE1BQU0sSUFBSSxHQUFHLGFBQWEsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLEtBQWUsQ0FBQyxDQUFDO2dCQUNwRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFFOUQsSUFBSSxnQkFBZ0IsS0FBSyxDQUFDLEVBQUUsQ0FBQztvQkFFM0IsT0FBTyxnQkFBZ0IsQ0FBQztnQkFDMUIsQ0FBQztZQUNILENBQUM7WUFDRCxPQUFPLENBQUMsQ0FBQztRQUNYLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLGFBQWEsQ0FBQyxJQUFTLEVBQUUsSUFBUyxFQUFFLGFBQTZCO1FBRXZFLHlFQUF5RTtRQUN6RSwwRUFBMEU7UUFDMUUseUVBQXlFO1FBQ3pFLHFFQUFxRTtRQUNyRSxNQUFNLE1BQU0sR0FBRyxJQUFJLEtBQUssSUFBSSxJQUFJLElBQUksS0FBSyxTQUFTLENBQUM7UUFDbkQsTUFBTSxNQUFNLEdBQUcsSUFBSSxLQUFLLElBQUksSUFBSSxJQUFJLEtBQUssU0FBUyxDQUFDO1FBRW5ELElBQUksTUFBTSxJQUFJLE1BQU07WUFBRSxPQUFPLENBQUMsQ0FBQztRQUMvQixJQUFJLE1BQU07WUFBRSxPQUFPLGFBQWEsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDcEQsSUFBSSxNQUFNO1lBQUUsT0FBTyxhQUFhLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRXBELElBQUksT0FBTyxJQUFJLEtBQUssUUFBUSxJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBRXpELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQzFFLE9BQU8sYUFBYSxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQztRQUM1RCxDQUFDO1FBRUQsSUFBSSxJQUFJLEdBQUcsSUFBSTtZQUFFLE9BQU8sYUFBYSxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN6RCxJQUFJLElBQUksR0FBRyxJQUFJO1lBQUUsT0FBTyxhQUFhLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3pELE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQztJQUVEOztPQUVHO0lBQ0ksU0FBUztRQUVkLE1BQU0sTUFBTSxHQUFhLEVBQUUsQ0FBQztRQUU1QixJQUFJLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFO1lBRXBDLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7WUFFdkIsSUFBSSxDQUFDLFVBQVUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBRXpDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzFCLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUV4QyxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxrQkFBa0IsRUFBRSxFQUFFLG1CQUFtQixFQUFFLEtBQUssRUFBRSxnQkFBZ0IsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUMxSSxDQUFDO0lBRUQ7O09BRUc7SUFDSSxXQUFXO1FBRWhCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFFcEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUV4QixJQUFJLENBQUMsVUFBVSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDM0MsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLENBQUM7UUFFcEMsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsZ0JBQWdCLEVBQUUsS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUU1RCxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxrQkFBa0IsRUFBRTtnQkFDbEQsbUJBQW1CLEVBQUUsSUFBSTtnQkFDekIsZ0JBQWdCLEVBQUUsS0FBSztnQkFDdkIsUUFBUSxFQUFFLEtBQUs7Z0JBQ2YsSUFBSSxFQUFFLElBQUk7YUFDWCxDQUFDLENBQUM7UUFDTCxDQUFDO0lBQ0gsQ0FBQztJQUVNLGVBQWUsQ0FBQyxLQUFhLEVBQUUsUUFBaUI7UUFFckQsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUV4QyxJQUFJLElBQUksRUFBRSxDQUFDO1lBRVQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUUzQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsZUFBZSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztZQUV2RCxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxrQkFBa0IsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQzNGLENBQUM7SUFDSCxDQUFDO0lBRU0sZUFBZSxDQUFDLEtBQWE7UUFFbEMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUV4QyxJQUFJLElBQUksRUFBRSxDQUFDO1lBRVQsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsZ0JBQWdCLEVBQUUsS0FBSyxRQUFRLEVBQUUsQ0FBQztnQkFFMUQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7Z0JBRXJGLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFFL0YsQ0FBQztpQkFBTSxDQUFDO2dCQUVOLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDekIsQ0FBQztZQUVELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBRW5ELElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLGtCQUFrQixFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ2hGLENBQUM7SUFDSCxDQUFDO0lBRU0sZ0JBQWdCLENBQUMsTUFBZ0IsRUFBRSxXQUFvQixJQUFJO1FBRWhFLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFFckIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUUvQyxJQUFJLElBQUksRUFBRSxDQUFDO2dCQUVULElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBRTNCLElBQUksQ0FBQyxVQUFVLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztnQkFFekMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDekQsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhLENBQUMsa0JBQWtCLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUN0RSxDQUFDO0lBRUQ7O09BRUc7SUFDSSxjQUFjO1FBRW5CLE9BQU8sSUFBSSxDQUFDLFNBQVMsRUFBRSxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDL0QsQ0FBQztJQUVNLGtCQUFrQjtRQUV2QixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDdEYsQ0FBQztJQUVNLG1CQUFtQjtRQUV4QixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUUzRCxPQUFPLEtBQUssSUFBSSxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDckQsQ0FBQztJQUVEOztPQUVHO0lBQ0ksY0FBYztRQUVuQixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUM7SUFDN0IsQ0FBQztJQUVNLGNBQWMsQ0FBQyxLQUF1QjtRQUUzQyxJQUFJLElBQUksQ0FBQyxVQUFVO1lBQUUsT0FBTztRQUU1QixJQUFJLENBQUMsY0FBYyxHQUFHLEtBQUssQ0FBQztRQUU1QixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDdEIsQ0FBQztJQUVNLFlBQVksQ0FBQyxLQUFhO1FBRS9CLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxLQUFLLEtBQUssSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNyRixDQUFDO0lBRUQ7O09BRUc7SUFDSSxjQUFjLENBQUMsS0FBYTtRQUVqQyxJQUFJLElBQUksQ0FBQyxVQUFVO1lBQUUsT0FBTztRQUU1QixJQUFJLENBQUMsaUJBQWlCLEdBQUcsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7UUFFckQsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ3RCLENBQUM7SUFFRDs7Ozs7Ozs7O09BU0c7SUFDSSxXQUFXLENBQUMsR0FBTSxFQUFFLE9BQTBCO1FBRW5ELE1BQU0sTUFBTSxHQUE4QixFQUFFLENBQUM7UUFFN0MsS0FBSyxNQUFNLE1BQU0sSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUU3Qix5RUFBeUU7WUFDekUscUJBQXFCO1lBQ3JCLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsRUFBRSxNQUFNO2dCQUFFLFNBQVM7WUFFL0QsS0FBSyxNQUFNLElBQUksSUFBSSxNQUFNLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBRTFDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUUzQyxJQUFJLEtBQUssRUFBRSxDQUFDO29CQUVWLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsS0FBSyxDQUFDO29CQUU3QixNQUFNLENBQUMsZ0NBQWdDO2dCQUN6QyxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSSxlQUFlLENBQUMsT0FBWSxFQUFFLE9BQTBCO1FBRTdELE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBRXJFLE1BQU0sU0FBUyxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztRQUUzRSxPQUFPLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxTQUFTLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxDQUFDO0lBQ3RFLENBQUM7SUFFRDs7Ozs7Ozs7O09BU0c7SUFDSSxXQUFXLENBQUMsUUFBc0Q7UUFFdkUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFDakUsQ0FBQztJQUVELCtEQUErRDtJQUN4RCxlQUFlLENBQUMsUUFBc0Q7UUFFM0UsSUFBSSxTQUFTLEdBQUcsQ0FBQyxDQUFDO1FBRWxCLEtBQUssTUFBTSxJQUFJLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBRWxDLElBQUksSUFBSSxDQUFDLElBQUk7Z0JBQUUsUUFBUSxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQzdDLENBQUM7SUFDSCxDQUFDO0lBRU0sY0FBYyxDQUFDLEtBQWE7UUFFakMsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFRDs7T0FFRztJQUNJLHdCQUF3QixDQUFDLEtBQWE7UUFFM0MsSUFBSSxDQUFDLHFCQUFxQixHQUFHLEtBQUssQ0FBQztJQUNyQyxDQUFDO0lBRU0sdUJBQXVCLENBQUMsZUFBdUI7UUFFcEQsSUFBSSxDQUFDLG9CQUFvQixHQUFHLGVBQWUsQ0FBQztJQUM5QyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7O09BY0c7SUFDSSxlQUFlLENBQUMsUUFBaUI7UUFFdEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUV0QixJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVU7Z0JBQUUsT0FBTztZQUU3QixJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRTNCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQTtRQUM1RCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO0lBQzdCLENBQUM7SUFFTSxlQUFlLENBQUMsS0FBYSxFQUFFLFFBQWlCO1FBRXJELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFL0MsSUFBSSxJQUFJLEVBQUUsVUFBVSxFQUFFLENBQUM7WUFFckIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUUzQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztRQUN4RCxDQUFDO1FBRUQsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7SUFDN0IsQ0FBQztJQUVNLGdCQUFnQixDQUFDLE1BQWdCLEVBQUUsUUFBaUI7UUFFekQsSUFBSSxNQUFNLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUVoQyxLQUFLLElBQUksS0FBSyxJQUFJLE1BQU0sRUFBRSxDQUFDO2dCQUV6QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUUvQyxJQUFJLElBQUksRUFBRSxVQUFVLEVBQUUsQ0FBQztvQkFFckIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFFM0IsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUM7Z0JBQ3hELENBQUM7WUFDSCxDQUFDO1lBRUQsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7UUFDN0IsQ0FBQztJQUNILENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0ksZ0JBQWdCO1FBRXJCLE9BQU8sSUFBSSxDQUFDLFNBQVM7YUFFbEIsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDO2FBRWhELEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM3QixDQUFDO0lBRUQ7O09BRUc7SUFDSSxnQkFBZ0IsQ0FBQyxJQUFtQixFQUFFLFVBQWlCO1FBRTVELElBQUksSUFBSSxDQUFDLFVBQVU7WUFBRSxPQUFPO1FBRTVCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRWhELElBQUksT0FBTyxFQUFFLENBQUM7WUFFWixPQUFPLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDdkMsQ0FBQztJQUNILENBQUM7SUFFTSxtQkFBbUIsQ0FBQyxnQkFBNkQ7UUFFdEYsSUFBSSxDQUFDLGlCQUFpQixHQUFHLGdCQUFnQixDQUFDO0lBQzVDLENBQUM7SUFFRDs7T0FFRztJQUNJLGNBQWM7UUFFbkIsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLGNBQWMsRUFBRSxDQUFDO0lBQzdDLENBQUM7SUFFTSxhQUFhLENBQUMsVUFBNkI7UUFFaEQsSUFBSSxJQUFJLENBQUMsVUFBVTtZQUFFLE9BQU87UUFFNUIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLENBQUM7UUFFN0MsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUV4RCxJQUFJLENBQUMsV0FBVyxDQUFDLGVBQWUsQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUVyRSxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxlQUFlLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUVNLFlBQVksQ0FBQyxFQUFVLEVBQUUsT0FBaUM7UUFFL0QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQUMsRUFBRSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBRWhELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsY0FBYyxFQUFFLENBQUM7UUFFeEQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFckUsSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhLENBQUMsZUFBZSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQ2hFLENBQUM7SUFFTSxpQkFBaUIsQ0FBQyxTQUFpQixFQUFFLE9BQWU7UUFFekQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFekQsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUV4RCxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxlQUFlLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUVEOztPQUVHO0lBQ0ksMEJBQTBCLENBQUMsSUFBZ0IsRUFBRSxRQUFpQjtRQUVuRSxNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO1FBRWpDLE1BQU0sT0FBTyxHQUFHLENBQUMsQ0FBYSxFQUFFLEVBQUU7WUFFaEMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFcEIsSUFBSSxDQUFDLENBQUMsUUFBUSxJQUFJLENBQUMsQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBRXBDLENBQUMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDOUMsQ0FBQztRQUNILENBQUMsQ0FBQztRQUVGLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVkLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ3RELENBQUM7SUFFRDs7O09BR0c7SUFDSSxnQkFBZ0IsQ0FBQyxJQUFnQjtRQUV0QyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDOUIsQ0FBQztJQUVNLGVBQWUsQ0FBQyxJQUFnQixFQUFFLE1BQW9CO1FBRTNELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRWhELElBQUksT0FBTyxFQUFFLENBQUM7WUFFWixPQUFPLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLGlCQUFpQixDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztRQUN6RixDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0ksZ0JBQWdCLENBQUMsSUFBZ0I7UUFFdEMsSUFBSSxJQUFJLENBQUMsVUFBVTtZQUFFLE9BQU87UUFFNUIsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFaEQsSUFBSSxDQUFDLE9BQU87WUFBRSxPQUFPO1FBRXJCLE9BQU8sQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUVsRSxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxrQkFBa0IsRUFBRSxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQzdGLENBQUM7SUFFRDs7T0FFRztJQUNIOzs7Ozs7O09BT0c7SUFDSyx3QkFBd0IsQ0FBQyxJQUFnQjtRQUUvQyxNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsc0JBQXNCLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUU7WUFFckUsSUFBSSxJQUFJLENBQUMsUUFBUSxLQUFLLFFBQVEsRUFBRSxDQUFDO2dCQUUvQixJQUFJLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDcEMsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUVPLG1CQUFtQixDQUFDLEtBQWEsRUFBRSxNQUF5QjtRQUVsRSxrREFBa0Q7UUFDbEQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO1FBRXZELElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxDQUFDLEdBQUcsUUFBUSxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBRU8sV0FBVyxDQUFDLEtBQWE7UUFFL0IsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFakQsUUFBUSxFQUFFLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFOUIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSyxpQkFBaUIsQ0FBQyxXQUF3QjtRQUVoRCxLQUFLLE1BQU0sQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7WUFFbkQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFFNUIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFFLHdCQUF3QjtnQkFFbEQsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQVcsZ0NBQWdDO2dCQUUxRCxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3ZDLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7T0FHRztJQUNLLHNCQUFzQixDQUFDLElBQWdCO1FBRTdDLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxpQkFBaUIsRUFBRSxzQkFBc0IsQ0FBQztRQUUvRix3RUFBd0U7UUFDeEUsMEVBQTBFO1FBQzFFLElBQUksQ0FBQyxhQUFhO1lBQUUsT0FBTztRQUUzQixNQUFNLE9BQU8sR0FBRyxhQUFhLENBQUMsT0FBTyxDQUFDO1FBQ3RDLE1BQU0sT0FBTyxHQUFHLGFBQWEsQ0FBQyxPQUFPLENBQUM7UUFFdEMsTUFBTSxTQUFTLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7UUFDcEUsTUFBTSxTQUFTLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7UUFFcEUsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGFBQWEsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUU3RixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQztJQUNwSSxDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSSxPQUFPO1FBRVosSUFBSSxJQUFJLENBQUMsVUFBVTtZQUFFLE9BQU87UUFFNUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7UUFFdkIsaUVBQWlFO1FBQ2pFLEtBQUssTUFBTSxLQUFLLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUU1RCxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzFCLENBQUM7UUFFRCwwRUFBMEU7UUFDMUUsMkNBQTJDO1FBQzNDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUN2RCxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBRS9DLEtBQUssTUFBTSxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUF1QixFQUFFLENBQUM7WUFFM0QsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUMzRCxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNsQyxDQUFDO1FBRUQsSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLEVBQUUsQ0FBQztRQUMzQixJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUM3QixJQUFJLENBQUMsYUFBYSxHQUFHLENBQUMsQ0FBQztRQUV2QiwyRUFBMkU7UUFDM0UseURBQXlEO1FBQ3pELElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRWxDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNwQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLENBQUM7UUFFOUIsSUFBSSxDQUFDLGNBQWMsR0FBRyxFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQztRQUM5QixJQUFJLENBQUMsVUFBVSxHQUFHLEVBQUUsQ0FBQztRQUNyQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztRQUVyQixJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztRQUMxQixJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQztRQUN0QixJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxDQUFDLENBQUM7UUFDOUIsSUFBSSxDQUFDLHdCQUF3QixHQUFHLElBQUksQ0FBQztRQUNyQyxJQUFJLENBQUMsdUJBQXVCLEdBQUcsSUFBSSxDQUFDO1FBQ3BDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUM7SUFDaEMsQ0FBQztJQUVELDhFQUE4RTtJQUM5RSxJQUFXLFNBQVM7UUFFbEIsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDO0lBQ3pCLENBQUM7K0dBeHBDVSxVQUFVO21IQUFWLFVBQVU7OzRGQUFWLFVBQVU7a0JBRHRCLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBPbmVDZWxsUmVuZGVyZXJDb21wb25lbnQgfSBmcm9tICcuLi9tb2RlbHMvb25lLXRyZWUtZGF0YS5tb2RlbCc7XG5pbXBvcnQgeyBPbmVDb2x1bW5EZWYgfSBmcm9tICcuLi9tb2RlbHMvb25lLWNvbHVtbi1kZWYtdHlwZXMubW9kZWwnO1xuaW1wb3J0IHsgT25lUm93Tm9kZSB9IGZyb20gXCIuL29uZS1yb3ctbm9kZS5jbGFzc1wiO1xuaW1wb3J0IHsgT25lR3JpZEluaXRPcHRpb25zLCBPbmVHcmlkVHlwZSwgT25lU29ydE1vZGVsIH0gZnJvbSAnLi4vbW9kZWxzL29uZS1ncmlkLXR5cGVzLm1vZGVsJztcbmltcG9ydCB7IE9uZUdyaWRFdmVudFNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9vbmUtZ3JpZC1ldmVudC5zZXJ2aWNlJztcbmltcG9ydCB7IE9uZUdyaWRTZWxlY3Rpb25TZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvb25lLWdyaWQtc2VsZWN0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHsgT25lUm93VmFsaWRhdGlvbkVycm9ycywgT25lVmFsaWRhdGlvblJlc3VsdCB9IGZyb20gJy4uL21vZGVscy9vbmUtdmFsaWRhdGlvbi5tb2RlbCc7XG5pbXBvcnQgeyBPbmVGaWx0ZXJNb2RlbCB9IGZyb20gXCIuLi9tb2RlbHMvb25lLWZpbHRlci5tb2RlbFwiO1xuaW1wb3J0IHsgT25lR3JpZEV4cGFuc2lvblNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9vbmUtZ3JpZC1leHBhbnNpb24uc2VydmljZSc7XG5pbXBvcnQgeyBPbmVEZXRhaWxDZWxsUmVuZGVyZXJQYXJhbXMsIE9uZUdldERldGFpbFJvd0RhdGFQYXJhbXMgfSBmcm9tIFwiLi4vbW9kZWxzL29uZS1tYXN0ZXItZGV0YWlsLm1vZGVsXCI7XG5pbXBvcnQgeyBPbmVHcmlkUm93U2VydmljZSB9IGZyb20gXCIuLi9zZXJ2aWNlcy9vbmUtZ3JpZC1yb3cuc2VydmljZVwiO1xuaW1wb3J0IHsgZmlsdGVyVHJlZU5vZGUsIGlzRmlsdGVyQWN0aXZlIH0gZnJvbSBcIi4uLy4uL2hlbHBlcnMvb25lLWZpbHRlci5oZWxwZXJcIjtcbmltcG9ydCB7IE9uZVJvd0RyYWdTdXBwcmVzc2VkUmVhc29uIH0gZnJvbSBcIi4uL21vZGVscy9vbmUtcm93LWRyYWcubW9kZWxcIjtcbmltcG9ydCB7IGdldEZpZWxkVmFsdWUgfSBmcm9tIFwiLi4vLi4vaGVscGVycy9vbmUtY2VsbC5oZWxwZXJcIjtcbmltcG9ydCB7IE9uZUdyaWRDZWxsU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL29uZS1ncmlkLWNlbGwuc2VydmljZSc7XG5pbXBvcnQgeyB2NCBhcyB1dWlkdjQgfSBmcm9tICd1dWlkJztcbmltcG9ydCB7IEluamVjdGFibGUsIFR5cGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgQ29sdW1uQ2hhbmdlZEV2ZW50LCBPbmVQaW5uZWRSb3dTaWRlLCBSb3dTZWxlY3Rpb25Nb2RlIH0gZnJvbSBcIi4uL21vZGVscy9vbmUtZXZlbnQtdHlwZXMubW9kZWxcIjtcbmltcG9ydCB7IE9uZUdyb3VwQ29sdW1uRGVmIH0gZnJvbSBcIi4uL21vZGVscy9vbmUtY29sdW1uLWRlZi10eXBlcy5tb2RlbFwiO1xuaW1wb3J0IHsgT2dDb2x1bW5TZXJ2aWNlIH0gZnJvbSBcIi4uL3NlcnZpY2VzL29nLWNvbHVtbi5zZXJ2aWNlXCI7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBPbmVHcmlkQXBpPFQgPSBhbnk+IHtcblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gUHVibGljIHN0YXRlXG4gIC8vXG4gIC8vIEV4cG9zZWQgYXMgZ2V0dGVycywgbm90IGZpZWxkcy4gVGhlc2Ugd2VyZSB3cml0YWJsZSwgc28gYSBjb25zdW1lciBjb3VsZFxuICAvLyBjb3JydXB0IHRoZSBncmlkIGJ5IGFzc2lnbmluZyB0byB0aGVtIOKAlCBzd2FwcGluZyBgcm93Tm9kZXNgIGZvciBhblxuICAvLyB1bnJlbGF0ZWQgYXJyYXksIG9yIHNldHRpbmcgYHNvcnRNb2RlbGAgd2l0aG91dCB0aGUgcm93cyBldmVyIGJlaW5nXG4gIC8vIHJlLXNvcnRlZC4gUmVhZHMgYXJlIHVuY2hhbmdlZDsgb25seSBhc3NpZ25tZW50IGlzIG5vdyBhIGNvbXBpbGUgZXJyb3IuXG4gIC8vXG4gIC8vIFRoZSBhcnJheS12YWx1ZWQgb25lcyBhcmUgdHlwZWQgYHJlYWRvbmx5IFRbXWAsIHdoaWNoIHN0b3BzIGBwdXNoYCBhbmRcbiAgLy8gYHNwbGljZWAgYXQgY29tcGlsZSB0aW1lIHdpdGhvdXQgY29weWluZyBvbiBldmVyeSByZWFkLiBVc2VcbiAgLy8gYGdldEFsbFJvd05vZGVzKClgIHdoZW4geW91IHdhbnQgYSBjb3B5IHlvdSBvd24uXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICBwcml2YXRlIF9pZDogc3RyaW5nO1xuICBwcml2YXRlIF9jb250ZXh0OiBhbnkgPSBudWxsO1xuICBwcml2YXRlIF9yb3dTZWxlY3Rpb246IFJvd1NlbGVjdGlvbk1vZGUgPSBudWxsO1xuICBwcml2YXRlIF9hcGlUeXBlOiBPbmVHcmlkVHlwZSA9IG51bGw7XG4gIHByaXZhdGUgX3Jvd05vZGVzOiBPbmVSb3dOb2RlPFQ+W10gPSBbXTtcbiAgcHJpdmF0ZSBfc29ydE1vZGVsOiBPbmVTb3J0TW9kZWw8VD5bXSA9IFtdO1xuXG4gIC8qKiBVbmlxdWUgcGVyIGdyaWQgaW5zdGFuY2UsIGFzc2lnbmVkIGR1cmluZyBgaW5pdGAuICovXG4gIHB1YmxpYyBnZXQgaWQoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5faWQ7XG4gIH1cblxuICAvKiogVGhlIGBbY29udGV4dF1gIHRoZSBncmlkIHdhcyBnaXZlbi4gKi9cbiAgcHVibGljIGdldCBjb250ZXh0KCk6IGFueSB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbnRleHQ7XG4gIH1cblxuICAvKiogU2VsZWN0aW9uIG1vZGUsIGNhcHR1cmVkIGR1cmluZyBgaW5pdGAuIENoYW5naW5nIHRoZSBpbnB1dCBsYXRlciBoYXMgbm8gZWZmZWN0LiAqL1xuICBwdWJsaWMgZ2V0IHJvd1NlbGVjdGlvbigpOiBSb3dTZWxlY3Rpb25Nb2RlIHtcbiAgICByZXR1cm4gdGhpcy5fcm93U2VsZWN0aW9uO1xuICB9XG5cbiAgLyoqIFdoaWNoIHJvbGUgdGhpcyBpbnN0YW5jZSBwbGF5czogc2ltcGxlLCBtYXN0ZXIsIGRldGFpbCBvciB0cmVlLiAqL1xuICBwdWJsaWMgZ2V0IGFwaVR5cGUoKTogT25lR3JpZFR5cGUge1xuICAgIHJldHVybiB0aGlzLl9hcGlUeXBlO1xuICB9XG5cbiAgLyoqIEV2ZXJ5IG5vZGUgdGhlIGdyaWQgaG9sZHMsIGluIGZsYXR0ZW5lZCBvcmRlci4gKi9cbiAgcHVibGljIGdldCByb3dOb2RlcygpOiByZWFkb25seSBPbmVSb3dOb2RlPFQ+W10ge1xuICAgIHJldHVybiB0aGlzLl9yb3dOb2RlcztcbiAgfVxuXG4gIC8qKiBUaGUgc29ydCBtb2RlbCBjdXJyZW50bHkgYXBwbGllZC4gQ2hhbmdlIGl0IHdpdGggYG9uU29ydENoYW5nZWRgLiAqL1xuICBwdWJsaWMgZ2V0IHNvcnRNb2RlbCgpOiByZWFkb25seSBPbmVTb3J0TW9kZWw8VD5bXSB7XG4gICAgcmV0dXJuIHRoaXMuX3NvcnRNb2RlbDtcbiAgfVxuXG5cbiAgcHJpdmF0ZSByb3dIZWlnaHQ6IG51bWJlciA9IDI2O1xuICBwcml2YXRlIGhlYWRlclJvd0hlaWdodDogbnVtYmVyID0gMzI7XG4gIHByaXZhdGUgX2N1cnJlbnRJbmRleDogbnVtYmVyID0gMDtcbiAgcHJpdmF0ZSBfcXVpY2tGaWx0ZXJWYWx1ZTogc3RyaW5nID0gbnVsbDtcbiAgcHJpdmF0ZSBfYWN0aXZlRmlsdGVyczogT25lRmlsdGVyTW9kZWxbXSA9IFtdO1xuXG4gIHByaXZhdGUgX3Zpc2libGVSb3dOb2RlczogT25lUm93Tm9kZTxUPltdID0gW107XG4gIHByaXZhdGUgcmVhZG9ubHkgX3Bpbm5lZFJvd05vZGVzOiBSZWNvcmQ8T25lUGlubmVkUm93U2lkZSwgT25lUm93Tm9kZTxUPltdPiA9IHsgdG9wOiBbXSwgYm90dG9tOiBbXSB9O1xuICBwcml2YXRlIF9vcmlnaW5hbFJvd05vZGVzOiBNYXA8c3RyaW5nLCBPbmVSb3dOb2RlPFQ+PiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSBfbm9kZUNsZWFudXBNYXAgPSBuZXcgTWFwPHN0cmluZywgQXJyYXk8KCkgPT4gdm9pZD4+KCk7IC8vIENsZWFudXAgcmVnaXN0cnkgKHByZXZlbnRzIG1lbW9yeSBsZWFrcylcbiAgcHJpdmF0ZSBfZGVzdHJveWVkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgLy8gQWR2YW5jZWQgRmVhdHVyZXNcbiAgcHJpdmF0ZSB0cmVlRGF0YTogYm9vbGVhbiA9IGZhbHNlO1xuICBwcml2YXRlIHRyZWVEYXRhQ2hpbGRyZW5GaWVsZDogc3RyaW5nID0gbnVsbDtcbiAgcHJpdmF0ZSBncm91cERlZmF1bHRFeHBhbmRlZDogbnVtYmVyID0gMDtcblxuICBwcml2YXRlIG1hc3RlckRldGFpbDogYm9vbGVhbiA9IGZhbHNlO1xuICBwcml2YXRlIGRldGFpbENlbGxSZW5kZXJlclBhcmFtczogT25lRGV0YWlsQ2VsbFJlbmRlcmVyUGFyYW1zO1xuICBwcml2YXRlIGRldGFpbFJlbmRlcmVyQ29tcG9uZW50PzogVHlwZTxPbmVDZWxsUmVuZGVyZXJDb21wb25lbnQ+O1xuXG4gIC8qKlxuICAgKiBTdXBwbGllcyBhIG1hc3RlciByb3cncyBkZXRhaWwgcm93cy4gU2V0IHRocm91Z2ggYHNldEdldERldGFpbFJvd0RhdGFgO1xuICAgKiBwcmV2aW91c2x5IGEgd3JpdGFibGUgcHVibGljIGZpZWxkIHdpdGggYSBzZXR0ZXIgYmVzaWRlIGl0LCB3aGljaCBsZWZ0IHR3b1xuICAgKiB3YXlzIHRvIGRvIHRoZSBzYW1lIHRoaW5nIGFuZCBvbmUgb2YgdGhlbSB1bmNoZWNrZWQuXG4gICAqL1xuICBwcml2YXRlIF9nZXREZXRhaWxSb3dEYXRhOiAocGFyYW1zOiBPbmVHZXREZXRhaWxSb3dEYXRhUGFyYW1zKSA9PiB2b2lkO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgY29sdW1uU2VydmljZTogT2dDb2x1bW5TZXJ2aWNlLFxuICAgIHByaXZhdGUgcm93U2VydmljZTogT25lR3JpZFJvd1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBjZWxsU2VydmljZTogT25lR3JpZENlbGxTZXJ2aWNlLFxuICAgIHByaXZhdGUgZXZlbnRTZXJ2aWNlOiBPbmVHcmlkRXZlbnRTZXJ2aWNlLFxuICAgIHByaXZhdGUgc2VsZWN0aW9uU2VydmljZTogT25lR3JpZFNlbGVjdGlvblNlcnZpY2UsXG4gICAgcHJpdmF0ZSBleHBhbnNpb25TZXJ2aWNlOiBPbmVHcmlkRXhwYW5zaW9uU2VydmljZVxuICApIHsgfVxuXG4gIC8qKlxuICAgKiBTdGFuZCB0aGUgZ3JpZCB1cC4gQ2FsbGVkIGJ5IGBPbmVHcmlkQ29tcG9uZW50YCBmcm9tIGBuZ09uSW5pdGAuXG4gICAqXG4gICAqIFRha2VzIGEgc2luZ2xlIGBPbmVHcmlkSW5pdE9wdGlvbnNgIHJhdGhlciB0aGFuIHRoZSB0ZW4gcG9zaXRpb25hbFxuICAgKiBhcmd1bWVudHMgaXQgdXNlZCB0bywgc28gYSBjYWxsIHNpdGUgcmVhZHMgYXMgdGhlIGNvbmZpZ3VyYXRpb24gaXQgaXMgYW5kXG4gICAqIGEgbmV3IG9wdGlvbiBubyBsb25nZXIgbWVhbnMgZWRpdGluZyBldmVyeSBjYWxsZXIuXG4gICAqXG4gICAqIEBpbnRlcm5hbCBBcHBsaWNhdGlvbnMgb2J0YWluIGEgcmVhZHktbWFkZSBBUEkgZnJvbSBgKG9uR3JpZFJlYWR5KWA7IHRoZXlcbiAgICogc2hvdWxkIG5ldmVyIGNhbGwgdGhpcyB0aGVtc2VsdmVzLlxuICAgKi9cbiAgaW5pdChvcHRpb25zOiBPbmVHcmlkSW5pdE9wdGlvbnM8VD4pOiB2b2lkIHtcblxuICAgIGNvbnN0IHtcbiAgICAgIGdyaWRUeXBlLFxuICAgICAgY29sdW1uRGVmcyxcbiAgICAgIGRlZmF1bHRDb2x1bW5EZWYgPSB7fSxcbiAgICAgIGdyb3VwQ29sdW1uRGVmcyA9IFtdLFxuICAgICAgY29udGV4dCA9IG51bGwsXG4gICAgICByb3dTZWxlY3Rpb24gPSBudWxsLFxuICAgICAgbWFzdGVyRGV0YWlsID0gZmFsc2UsXG4gICAgICBkZXRhaWxDZWxsUmVuZGVyZXJQYXJhbXMgPSBudWxsLFxuICAgICAgZGV0YWlsUmVuZGVyZXJDb21wb25lbnQgPSBudWxsLFxuICAgICAgdHJlZURhdGEgPSBmYWxzZSxcbiAgICB9ID0gb3B0aW9ucztcblxuICAgIHRoaXMuX2lkID0gdXVpZHY0KCk7XG4gICAgdGhpcy5fYXBpVHlwZSA9IGdyaWRUeXBlO1xuICAgIHRoaXMuX3Jvd1NlbGVjdGlvbiA9IHJvd1NlbGVjdGlvbjtcbiAgICB0aGlzLl9jb250ZXh0ID0gY29udGV4dDtcbiAgICB0aGlzLm1hc3RlckRldGFpbCA9IG1hc3RlckRldGFpbDtcbiAgICB0aGlzLmRldGFpbENlbGxSZW5kZXJlclBhcmFtcyA9IGRldGFpbENlbGxSZW5kZXJlclBhcmFtcztcbiAgICB0aGlzLmRldGFpbFJlbmRlcmVyQ29tcG9uZW50ID0gZGV0YWlsUmVuZGVyZXJDb21wb25lbnQ7XG4gICAgdGhpcy50cmVlRGF0YSA9IHRyZWVEYXRhO1xuXG4gICAgdGhpcy5zZWxlY3Rpb25TZXJ2aWNlLnNldFNlbGVjdGlvbk1vZGUocm93U2VsZWN0aW9uKTtcbiAgICB0aGlzLnJvd1NlcnZpY2Uuc2V0R2V0Um93SWRGbihjb250ZXh0Py5jb21wb25lbnRQYXJlbnQ/LmdldFJvd0lkID8/IG51bGwpO1xuXG4gICAgdGhpcy5jZWxsU2VydmljZS5hcHBseUNvbHVtbkRlZnMoY29sdW1uRGVmcywgY29udGV4dCk7XG4gICAgdGhpcy5jZWxsU2VydmljZS5zZXRHcmlkQXBpKHRoaXMpO1xuICAgIHRoaXMuY29sdW1uU2VydmljZS5pbml0Q29sdW1uRGVmcyhkZWZhdWx0Q29sdW1uRGVmLCBjb2x1bW5EZWZzLCBncm91cENvbHVtbkRlZnMsIGNvbnRleHQpO1xuXG4gICAgY29uc3QgY29sdW1uU3RhdGUgPSB0aGlzLmNvbHVtblNlcnZpY2UuZ2V0Q29sdW1uU3RhdGUoKTtcblxuICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5ldmVudFNlcnZpY2UuZGlzcGF0Y2hFdmVudCgnY29sdW1uQ2hhbmdlZCcsIGNvbHVtblN0YXRlIGFzIENvbHVtbkNoYW5nZWRFdmVudCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcGxhY2UgZXZlcnkgcm93LCBkaXNjYXJkaW5nIHNlbGVjdGlvbiBhbmQgZXhwYW5zaW9uLlxuICAgKlxuICAgKiBVc2UgdGhpcyB3aGVuIHRoZSByb3dzIHJlcHJlc2VudCBzb21ldGhpbmcgbmV3LiBUbyBzd2FwIHRoZSBkYXRhIHdoaWxlXG4gICAqIGtlZXBpbmcgd2hhdCB0aGUgdXNlciBoYXMgc2VsZWN0ZWQgYW5kIG9wZW5lZCwgdXNlIGB1cGRhdGVSb3dEYXRhYC5cbiAgICovXG4gIHB1YmxpYyBzZXRSb3dEYXRhKHJvd0RhdGE6IFRbXSkge1xuXG4gICAgdGhpcy5yZWJ1aWxkUm93cyhyb3dEYXRhLCB0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBsYWNlIGV2ZXJ5IHJvdywga2VlcGluZyBzZWxlY3Rpb24gYW5kIGV4cGFuc2lvbi5cbiAgICpcbiAgICogU3RhdGUgaXMga2V5ZWQgYnkgcm93IGlkLCBzbyB0aGlzIG9ubHkgcHJlc2VydmVzIGFueXRoaW5nIGlmIHRoZSBncmlkIGhhcyBhXG4gICAqIGBjb250ZXh0LmNvbXBvbmVudFBhcmVudC5nZXRSb3dJZGAg4oCUIG90aGVyd2lzZSBlYWNoIHJlYnVpbGQgbWludHMgbmV3IGlkc1xuICAgKiBhbmQgdGhlcmUgaXMgbm90aGluZyBsZWZ0IHRvIG1hdGNoIGFnYWluc3QuXG4gICAqL1xuICBwdWJsaWMgdXBkYXRlUm93RGF0YShyb3dEYXRhOiBUW10pIHtcblxuICAgIHRoaXMucmVidWlsZFJvd3Mocm93RGF0YSwgZmFsc2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBvbmUgcm93LWxvYWRpbmcgcGF0aC4gYHNldFJvd0RhdGFgIGFuZCBgdXBkYXRlUm93RGF0YWAgZGlmZmVyZWQgb25seSBpblxuICAgKiB3aGV0aGVyIHRoZXkgY2xlYXJlZCB0aGUgc3RhdGUgc2VydmljZXMgZmlyc3QsIHNvIGV2ZXJ5dGhpbmcgZWxzZSDigJQgYnVpbGQsXG4gICAqIGZpbHRlciwgcHJ1bmUg4oCUIGxpdmVzIGhlcmUgb25jZS5cbiAgICovXG4gIHByaXZhdGUgcmVidWlsZFJvd3Mocm93RGF0YTogVFtdLCByZXNldFN0YXRlOiBib29sZWFuKTogdm9pZCB7XG5cbiAgICBpZiAodGhpcy5fZGVzdHJveWVkKSByZXR1cm47XG5cbiAgICBpZiAocmVzZXRTdGF0ZSkge1xuXG4gICAgICB0aGlzLnNlbGVjdGlvblNlcnZpY2UuZGVzZWxlY3RBbGwoKTtcbiAgICAgIHRoaXMuZXhwYW5zaW9uU2VydmljZS5jbGVhcigpO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbGlkUm93SWRzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgICB0aGlzLmJ1aWxkUm93Tm9kZXMocm93RGF0YSwgbnVsbCwgMCwgdmFsaWRSb3dJZHMpO1xuXG4gICAgLy8gUmUtYXBwbHkgdGhlIGFjdGl2ZSBzb3J0LiBgYnVpbGRSb3dOb2Rlc2AgcmVidWlsZHMgdGhlIHJvdyBsaXN0IGluIHRoZVxuICAgIC8vIG9yZGVyIHRoZSBkYXRhIGFycml2ZWQsIHNvIHdpdGhvdXQgdGhpcyBhIGRhdGEgdXBkYXRlIHNpbGVudGx5IHJldHVybmVkXG4gICAgLy8gdGhlIHJvd3MgdG8gdGhhdCBvcmRlciB3aGlsZSBgc29ydE1vZGVsYCDigJQgYW5kIHRoZXJlZm9yZSB0aGUgaGVhZGVyJ3NcbiAgICAvLyBzb3J0IGFycm93IOKAlCBzdGlsbCBzYWlkIHRoZXkgd2VyZSBzb3J0ZWQuIFNvcnRpbmcgYmVmb3JlIGZpbHRlcmluZ1xuICAgIC8vIGJlY2F1c2UgZmlsdGVyaW5nIG9ubHkgc2V0cyB2aXNpYmlsaXR5IG9uIHdoYXRldmVyIG9yZGVyIHRoaXMgbGVhdmVzLlxuICAgIGlmICh0aGlzLl9zb3J0TW9kZWwubGVuZ3RoID4gMCkgdGhpcy5hcHBseVNvcnRpbmcoKTtcblxuICAgIHRoaXMuYXBwbHlGaWx0ZXJzKCk7XG5cbiAgICB0aGlzLnBydW5lUmVtb3ZlZE5vZGVzKHZhbGlkUm93SWRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWN1cnNpdmUgQnVpbGQgUm93IE5vZGVzIChPcHRpbWl6ZWQpXG4gICAqL1xuICBwcml2YXRlIGJ1aWxkUm93Tm9kZXMoXG4gICAgcm93RGF0YTogVFtdLFxuICAgIHBhcmVudDogT25lUm93Tm9kZTxUPiB8IG51bGwgPSBudWxsLFxuICAgIGxldmVsOiBudW1iZXIgPSAwLFxuICAgIHZhbGlkUm93SWRzOiBTZXQ8c3RyaW5nPiA9IG5ldyBTZXQoKSxcbiAgICBleHBhbmRlZElkczogU2V0PHN0cmluZz4gPSBuZXcgU2V0KHRoaXMuZXhwYW5zaW9uU2VydmljZS5nZXRFeHBhbmRlZElkcygpKSxcbiAgICBjb2xsYXBzZWRJZHM6IFNldDxzdHJpbmc+ID0gbmV3IFNldCh0aGlzLmV4cGFuc2lvblNlcnZpY2UuZ2V0Q29sbGFwc2VkSWRzKCkpLFxuICAgIHNlbGVjdGVkSWRzOiBTZXQ8c3RyaW5nPiA9IG5ldyBTZXQodGhpcy5zZWxlY3Rpb25TZXJ2aWNlLmdldFNlbGVjdGVkSWRzKCkpXG4gICk6IE9uZVJvd05vZGVbXSB7XG5cbiAgICBpZiAocGFyZW50ID09PSBudWxsKSB7XG5cbiAgICAgIHRoaXMuX3Jvd05vZGVzID0gW107XG4gICAgICB0aGlzLl9jdXJyZW50SW5kZXggPSAwO1xuICAgIH1cblxuICAgIGlmICghcm93RGF0YT8ubGVuZ3RoKSByZXR1cm4gW107XG5cbiAgICBjb25zdCBub2RlczogT25lUm93Tm9kZTxUPltdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IGRhdGEgb2Ygcm93RGF0YSkge1xuXG4gICAgICBjb25zdCByb3dJZCA9IHRoaXMucm93U2VydmljZS5nZW5lcmF0ZVJvd0lkKGRhdGEsIHRoaXMuX2N1cnJlbnRJbmRleCk7XG4gICAgICBjb25zdCBjaGlsZHJlbiA9IChkYXRhIGFzIGFueSlbdGhpcy50cmVlRGF0YUNoaWxkcmVuRmllbGRdIHx8IG51bGw7XG5cbiAgICAgIGxldCBub2RlOiBPbmVSb3dOb2RlID0gdGhpcy5fb3JpZ2luYWxSb3dOb2Rlcy5nZXQocm93SWQpO1xuXG4gICAgICB2YWxpZFJvd0lkcy5hZGQocm93SWQpO1xuXG4gICAgICBpZiAobm9kZSkge1xuXG4gICAgICAgIG5vZGUuZGF0YSA9IGRhdGE7XG4gICAgICAgIG5vZGUuc2V0Um93SW5kZXgodGhpcy5fY3VycmVudEluZGV4KTtcblxuICAgICAgfSBlbHNlIHtcblxuICAgICAgICBub2RlID0gbmV3IE9uZVJvd05vZGU8VD4ocm93SWQsIGRhdGEsIHRoaXMuX2N1cnJlbnRJbmRleCk7XG4gICAgICAgIG5vZGUubGV2ZWwgPSBsZXZlbDtcbiAgICAgICAgbm9kZS5wYXJlbnQgPSBwYXJlbnQ7XG4gICAgICAgIG5vZGUuZGV0YWlsUmVuZGVyZXJDb21wb25lbnQgPSB0aGlzLmRldGFpbFJlbmRlcmVyQ29tcG9uZW50O1xuXG4gICAgICAgIHRoaXMuX29yaWdpbmFsUm93Tm9kZXMuc2V0KHJvd0lkLCBub2RlKTtcblxuICAgICAgICBpZiAodGhpcy5tYXN0ZXJEZXRhaWwpIHtcblxuICAgICAgICAgIHRoaXMuc3Vic2NyaWJlVG9EZXRhaWxDaGFuZ2VzKG5vZGUpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNoaWxkcmVuRXhpc3QgPSBjaGlsZHJlbiAmJiBjaGlsZHJlbi5sZW5ndGggPj0gMDtcblxuICAgICAgLy8gQ29lcmNlZCwgYmVjYXVzZSBgY2hpbGRyZW5FeGlzdGAgaXMgYGNoaWxkcmVuICYmIGNoaWxkcmVuLmxlbmd0aCA+PSAwYFxuICAgICAgLy8g4oCUIHdoaWNoIGlzIGBudWxsYCBmb3IgYSByb3cgd2l0aCBubyBjaGlsZHJlbiBmaWVsZCwgbm90IGBmYWxzZWAuIFRoZXNlXG4gICAgICAvLyBhcmUgZGVjbGFyZWQgYGJvb2xlYW5gLCBhbmQgYXNzaWduaW5nIG51bGwgbWFkZSBldmVyeSBjb25zdW1lciBjb21wYXJlXG4gICAgICAvLyB0cnV0aGluZXNzIGluc3RlYWQgb2YgdGhlIHZhbHVlLlxuICAgICAgbm9kZS5ncm91cCA9IHRoaXMubWFzdGVyRGV0YWlsID8gZmFsc2UgOiAhIWNoaWxkcmVuRXhpc3Q7XG4gICAgICBub2RlLmxlYWYgPSB0aGlzLm1hc3RlckRldGFpbCA/IHRydWUgOiAhbm9kZS5ncm91cDtcbiAgICAgIG5vZGUubGVhZkdyb3VwID0gdGhpcy5tYXN0ZXJEZXRhaWwgPyBmYWxzZSA6IChub2RlLmdyb3VwICYmICFjaGlsZHJlbkV4aXN0KTtcbiAgICAgIG5vZGUuZXhwYW5kYWJsZSA9IHRoaXMubWFzdGVyRGV0YWlsID8gdHJ1ZSA6IChub2RlLmdyb3VwICYmICFub2RlLmxlYWZHcm91cCk7XG5cbiAgICAgIGNvbnN0IGRlZmF1bHRFeHBhbmRlZCA9IG5vZGUuZXhwYW5kYWJsZSAmJiAobGV2ZWwgPCB0aGlzLmdyb3VwRGVmYXVsdEV4cGFuZGVkIHx8IHRoaXMuZ3JvdXBEZWZhdWx0RXhwYW5kZWQgPT09IC0xKTtcblxuICAgICAgbm9kZS5zZXRFeHBhbmRlZChleHBhbmRlZElkcy5oYXMocm93SWQpID8gdHJ1ZSA6IGNvbGxhcHNlZElkcy5oYXMocm93SWQpID8gZmFsc2UgOiBkZWZhdWx0RXhwYW5kZWQpO1xuICAgICAgbm9kZS5zZXRTZWxlY3RlZChzZWxlY3RlZElkcy5oYXMocm93SWQpKTtcbiAgICAgIG5vZGUuc2V0Q2VsbFN0YXRlcyh0aGlzLmNlbGxTZXJ2aWNlLmdlbmVyYXRlQ2VsbFN0YXRlcyhub2RlKSk7XG5cbiAgICAgIGlmICh0aGlzLm1hc3RlckRldGFpbCAmJiB0aGlzLl9hcGlUeXBlID09PSAnbWFzdGVyJykge1xuXG4gICAgICAgIHRoaXMuX2dldERldGFpbFJvd0RhdGEoeyBkYXRhLCBub2RlOiBub2RlLCBzdWNjZXNzQ2FsbGJhY2s6IChkZXRhaWxSb3dEYXRhKSA9PiBub2RlLnNldERldGFpbFJvd0RhdGEoZGV0YWlsUm93RGF0YSkgfSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX2N1cnJlbnRJbmRleCsrO1xuICAgICAgdGhpcy5fcm93Tm9kZXMucHVzaChub2RlKTtcblxuICAgICAgbm9kZXMucHVzaChub2RlKTtcblxuICAgICAgbm9kZS5jaGlsZHJlbiA9IHRoaXMudHJlZURhdGEgJiYgY2hpbGRyZW5FeGlzdCA/IHRoaXMuYnVpbGRSb3dOb2RlcyhjaGlsZHJlbiB8fCBbXSwgbm9kZSwgbGV2ZWwgKyAxLCB2YWxpZFJvd0lkcywgZXhwYW5kZWRJZHMsIGNvbGxhcHNlZElkcywgc2VsZWN0ZWRJZHMpIDogW107XG4gICAgfVxuXG4gICAgcmV0dXJuIG5vZGVzO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlciBGZWF0dXJlXG4gICAqL1xuICBwcml2YXRlIGFwcGx5RmlsdGVycygpOiB2b2lkIHtcblxuICAgIGNvbnN0IGZpbHRlcnMgPSB0aGlzLl9hY3RpdmVGaWx0ZXJzO1xuXG4gICAgY29uc3QgcXVpY2sgPSB0aGlzLl9xdWlja0ZpbHRlclZhbHVlPy50b0xvd2VyQ2FzZSgpID8/ICcnO1xuXG4gICAgLy8gVGhlIGZpZWxkcyB0aGUgZ3JpZCBhY3R1YWxseSBzaG93cy4gV2l0aG91dCB0aGVtIHRoZSBxdWljayBmaWx0ZXIgZmFsbHNcbiAgICAvLyBiYWNrIHRvIGV2ZXJ5IHByb3BlcnR5IG9uIHRoZSByb3csIHdoaWNoIGxldHMgYSB1c2VyIG1hdGNoIG9uIGRhdGEgdGhhdFxuICAgIC8vIGhhcyBubyBjb2x1bW4gYW5kIG5ldmVyIGFwcGVhcnMgb24gc2NyZWVuLlxuICAgIGNvbnN0IGZpZWxkcyA9IHRoaXMucXVpY2tGaWx0ZXJGaWVsZHMoKTtcblxuICAgIHRoaXMuX3Jvd05vZGVzLmZvckVhY2gobm9kZSA9PiBmaWx0ZXJUcmVlTm9kZShub2RlLCBmaWx0ZXJzLCBxdWljaywgZmllbGRzKSk7XG5cbiAgICB0aGlzLnJlZnJlc2hWaXNpYmxlTm9kZXMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGljaCBmaWVsZHMgdGhlIHF1aWNrIGZpbHRlciBzZWFyY2hlczogZXZlcnkgY29sdW1uIHRoYXQgaGFzIG9uZS5cbiAgICpcbiAgICogRW1wdHkgd2hpbGUgdGhlIGNvbHVtbnMgYXJlIHN0aWxsIGJlaW5nIHJlZ2lzdGVyZWQsIGluIHdoaWNoIGNhc2UgdGhlXG4gICAqIGhlbHBlciBmYWxscyBiYWNrIHRvIHNlYXJjaGluZyB0aGUgcm93IOKAlCB0aGUgc2FtZSBiZWhhdmlvdXIgYXMgYmVmb3JlLCBhbmRcbiAgICogdGhlIG9ubHkgc2Vuc2libGUgYW5zd2VyIHdoZW4gdGhlIGdyaWQgZG9lcyBub3QgeWV0IGtub3cgaXRzIGNvbHVtbnMuXG4gICAqL1xuICBwcml2YXRlIHF1aWNrRmlsdGVyRmllbGRzKCk6IHN0cmluZ1tdIHtcblxuICAgIHJldHVybiB0aGlzLmNvbHVtblNlcnZpY2VcbiAgICAgIC5nZXRDb2x1bW5TdGF0ZSgpXG4gICAgICAuY29sdW1uc1xuICAgICAgLm1hcChjb2x1bW4gPT4gY29sdW1uLmZpZWxkIGFzIHN0cmluZylcbiAgICAgIC5maWx0ZXIoKGZpZWxkKTogZmllbGQgaXMgc3RyaW5nID0+ICEhZmllbGQgJiYgZmllbGQgIT09ICdfb25lUm93TnVtYmVyJyk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIFJvdyBOb2RlcyBEaXNwbGF5XG4gICAqL1xuICBwcml2YXRlIHJlZnJlc2hWaXNpYmxlTm9kZXMoZGlzcGF0Y2g6IGJvb2xlYW4gPSB0cnVlKTogdm9pZCB7XG5cbiAgICBpZiAodGhpcy5fZGVzdHJveWVkKSByZXR1cm47XG5cbiAgICBjb25zdCB2aXNpYmxlTm9kZXM6IE9uZVJvd05vZGVbXSA9IFtdO1xuXG4gICAgbGV0IHJvd051bWJlciA9IDE7XG5cbiAgICBjb25zdCB2aXNpYmlsaXR5Q2FjaGUgPSBuZXcgTWFwPHN0cmluZywgYm9vbGVhbj4oKTtcblxuICAgIGZvciAoY29uc3Qgbm9kZSBvZiB0aGlzLl9yb3dOb2Rlcykge1xuXG4gICAgICBjb25zdCBwYXJlbnRWaXNpYmxlID0gbm9kZS5wYXJlbnQgPyB2aXNpYmlsaXR5Q2FjaGUuZ2V0KG5vZGUucGFyZW50LnJvd0lkKSA6IHRydWU7XG5cbiAgICAgIGNvbnN0IGlzVmlzaWJsZSA9IG5vZGUudmlzaWJsZSAmJiBwYXJlbnRWaXNpYmxlICYmICghbm9kZS5wYXJlbnQgfHwgbm9kZS5wYXJlbnQuZXhwYW5kZWQpO1xuXG4gICAgICB2aXNpYmlsaXR5Q2FjaGUuc2V0KG5vZGUucm93SWQsIGlzVmlzaWJsZSk7XG5cbiAgICAgIGlmIChpc1Zpc2libGUpIHtcblxuICAgICAgICBub2RlLmNlbGxTdGF0ZXNbJ19vbmVSb3dOdW1iZXInXSA9IHsgdHlwZTogJ3RleHQnLCB2YWx1ZTogcm93TnVtYmVyKysgfTtcblxuICAgICAgICBub2RlLmNlbGxTdGF0ZXMgPSB7IC4uLm5vZGUuY2VsbFN0YXRlcyB9O1xuXG4gICAgICAgIHZpc2libGVOb2Rlcy5wdXNoKG5vZGUpO1xuXG4gICAgICB9IGVsc2Uge1xuXG4gICAgICAgIG5vZGUuY2VsbFN0YXRlc1snX29uZVJvd051bWJlciddID0geyB0eXBlOiAnbm9uZScsIHZhbHVlOiBudWxsIH07XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5fdmlzaWJsZVJvd05vZGVzID0gWy4uLnZpc2libGVOb2Rlc107XG5cbiAgICBpZiAoZGlzcGF0Y2gpIHRoaXMuZXZlbnRTZXJ2aWNlLmRpc3BhdGNoRXZlbnQoJ3Jvd0RhdGFDaGFuZ2VkJywgeyBub2RlczogdmlzaWJsZU5vZGVzIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcGxhY2UgdGhlIHJvd3MgYW5jaG9yZWQgdG8gb25lIGVkZ2Ugb2YgdGhlIGdyaWQuXG4gICAqXG4gICAqIFBpbm5lZCByb3dzIGFyZSBkZWxpYmVyYXRlbHkga2VwdCBvdXQgb2YgYHJvd05vZGVzYCBhbmRcbiAgICogYF9vcmlnaW5hbFJvd05vZGVzYDogdGhleSBhcmUgbm90IGRhdGEuIFNvcnRpbmcsIGZpbHRlcmluZywgc2VsZWN0aW9uLFxuICAgKiBleHBhbnNpb24sIHBhZ2luYXRpb24gYW5kIHRoZSB2aXNpYmxlIHJvdyBjb3VudCBhbGwgaWdub3JlIHRoZW0sIHdoaWNoIGlzXG4gICAqIHRoZSB3aG9sZSBwb2ludCBvZiBhIHN1bW1hcnkgcm93LiBUaGV5IHJlbmRlciB3aXRoIHRoZSBzYW1lIGNvbHVtblxuICAgKiBkZWZpbml0aW9ucywgc28gcmVuZGVyZXJzIGFuZCB2YWx1ZSBnZXR0ZXJzIHdvcmsgYXMgdGhleSBkbyBldmVyeXdoZXJlXG4gICAqIGVsc2UuXG4gICAqL1xuICBwdWJsaWMgc2V0UGlubmVkUm93RGF0YShzaWRlOiBPbmVQaW5uZWRSb3dTaWRlLCByb3dEYXRhOiBUW10pOiB2b2lkIHtcblxuICAgIGlmICh0aGlzLl9kZXN0cm95ZWQpIHJldHVybjtcblxuICAgIGZvciAoY29uc3Qgbm9kZSBvZiB0aGlzLl9waW5uZWRSb3dOb2Rlc1tzaWRlXSkgbm9kZS5kZXN0cm95KCk7XG5cbiAgICB0aGlzLl9waW5uZWRSb3dOb2Rlc1tzaWRlXSA9IChyb3dEYXRhID8/IFtdKS5tYXAoKGRhdGEsIGluZGV4KSA9PiB7XG5cbiAgICAgIC8vIElkcyBhcmUgbmFtZXNwYWNlZCBieSBzaWRlIGFuZCBwb3NpdGlvbi4gVGhleSBuZXZlciBjb2xsaWRlIHdpdGggYSBkYXRhXG4gICAgICAvLyByb3cncyBpZCwgYW5kIHRoZXkgYXJlIHN0YWJsZSBhY3Jvc3MgcmVidWlsZHMsIHdoaWNoIGtlZXBzIHRoZSByZW5kZXJlZFxuICAgICAgLy8gYGRhdGEtY2VsbC1pZGAgYXR0cmlidXRlcyBzdGFibGUgdG9vLlxuICAgICAgY29uc3Qgbm9kZSA9IG5ldyBPbmVSb3dOb2RlPFQ+KGBvbmUtcGlubmVkLSR7c2lkZX0tJHtpbmRleH1gLCBkYXRhLCBpbmRleCk7XG5cbiAgICAgIG5vZGUubGV2ZWwgPSAwO1xuICAgICAgbm9kZS5sZWFmID0gdHJ1ZTtcbiAgICAgIG5vZGUudmlzaWJsZSA9IHRydWU7XG4gICAgICBub2RlLnNldENlbGxTdGF0ZXModGhpcy5jZWxsU2VydmljZS5nZW5lcmF0ZUNlbGxTdGF0ZXMobm9kZSkpO1xuXG4gICAgICByZXR1cm4gbm9kZTtcbiAgICB9KTtcblxuICAgIHRoaXMuZXZlbnRTZXJ2aWNlLmRpc3BhdGNoRXZlbnQoJ3Bpbm5lZFJvd0RhdGFDaGFuZ2VkJywge1xuICAgICAgc2lkZSxcbiAgICAgIG5vZGVzOiB0aGlzLl9waW5uZWRSb3dOb2Rlc1tzaWRlXSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBUaGUgcm93cyBhbmNob3JlZCB0byBvbmUgZWRnZS4gUmVhZC1vbmx5OyBjaGFuZ2UgdGhlbSB3aXRoIGBzZXRQaW5uZWRSb3dEYXRhYC4gKi9cbiAgcHVibGljIGdldFBpbm5lZFJvd05vZGVzKHNpZGU6IE9uZVBpbm5lZFJvd1NpZGUpOiByZWFkb25seSBPbmVSb3dOb2RlPFQ+W10ge1xuXG4gICAgcmV0dXJuIHRoaXMuX3Bpbm5lZFJvd05vZGVzW3NpZGVdO1xuICB9XG5cbiAgLyoqXG4gICAqIFJvdyByZW9yZGVyaW5nXG4gICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAqXG4gICAqIGBfb3JpZ2luYWxSb3dOb2Rlc2AgaXMgdGhlIHNvdXJjZSBvZiB0cnV0aCBmb3Igcm93IG9yZGVyOiBpdHMgaW5zZXJ0aW9uXG4gICAqIG9yZGVyIGlzIHdoYXQgYGFwcGx5U29ydGluZ2AgZmFsbHMgYmFjayB0byB3aGVuIHRoZSBzb3J0IG1vZGVsIGVtcHRpZXMsIGFuZFxuICAgKiB3aGF0IGEgcmVidWlsZCB3YWxrcy4gYF9yb3dOb2Rlc2AgaXMgb25seSB0aGUgY3VycmVudCBkaXNwbGF5IG9yZGVyLiBBIG1vdmVcbiAgICogdGhhdCB0b3VjaGVkIG9uZSBhbmQgbm90IHRoZSBvdGhlciB3b3VsZCBlaXRoZXIgYmUgdW5kb25lIGJ5IHRoZSBuZXh0IHNvcnRcbiAgICogY2hhbmdlIG9yIGludmlzaWJsZSB1bnRpbCBvbmUgaGFwcGVuZWQsIHNvIGJvdGggYXJlIHJld3JpdHRlbiB0b2dldGhlci5cbiAgICovXG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIGRpc3BsYXllZCBvcmRlciBpcyB0aGUgZGF0YSBvcmRlciwgYW5kIHNvIHdoZXRoZXIgYSBtYW51YWwgbW92ZVxuICAgKiB3b3VsZCBzdXJ2aXZlLlxuICAgKlxuICAgKiBAcmV0dXJucyB0aGUgcmVhc29uIHJlb3JkZXJpbmcgaXMgdW5hdmFpbGFibGUsIG9yIGBudWxsYCB3aGVuIGl0IGlzIGZpbmUuXG4gICAqL1xuICBwdWJsaWMgZ2V0Um93RHJhZ1N1cHByZXNzZWRSZWFzb24oKTogT25lUm93RHJhZ1N1cHByZXNzZWRSZWFzb24gfCBudWxsIHtcblxuICAgIGlmICh0aGlzLnRyZWVEYXRhKSByZXR1cm4gJ3RyZWVEYXRhJztcblxuICAgIGlmICh0aGlzLl9zb3J0TW9kZWwubGVuZ3RoID4gMCkgcmV0dXJuICdzb3J0ZWQnO1xuXG4gICAgaWYgKGlzRmlsdGVyQWN0aXZlKHRoaXMuX2FjdGl2ZUZpbHRlcnMsIHRoaXMuX3F1aWNrRmlsdGVyVmFsdWUgPz8gJycpKSByZXR1cm4gJ2ZpbHRlcmVkJztcblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqIENvbnZlbmllbmNlIGludmVyc2Ugb2Yge0BsaW5rIGdldFJvd0RyYWdTdXBwcmVzc2VkUmVhc29ufS4gKi9cbiAgcHVibGljIGNhblJlb3JkZXJSb3dzKCk6IGJvb2xlYW4ge1xuXG4gICAgcmV0dXJuIHRoaXMuZ2V0Um93RHJhZ1N1cHByZXNzZWRSZWFzb24oKSA9PT0gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb3ZlIGEgcm93IGZyb20gb25lIHBvc2l0aW9uIHRvIGFub3RoZXIuXG4gICAqXG4gICAqIEluZGljZXMgYXJlIHBvc2l0aW9ucyBpbiB0aGUgZ3JpZCdzIHJvdyBvcmRlciwgdGhlIHNhbWUgb3JkZXJcbiAgICogYGdldEFsbFJvd05vZGVzKClgIHJldHVybnMuIGB0YXJnZXRJbmRleGAgaXMgd2hlcmUgdGhlIHJvdyBlbmRzIHVwICphZnRlcipcbiAgICogaXQgaGFzIGJlZW4gbGlmdGVkIG91dCBvZiBgc291cmNlSW5kZXhgIOKAlCBkcmFnZ2luZyByb3cgMCB0byB0aGUgYm90dG9tIG9mIGFcbiAgICogNS1yb3cgZ3JpZCBpcyBgbW92ZVJvdygwLCA0KWAsIG5vdCBgbW92ZVJvdygwLCA1KWAuXG4gICAqXG4gICAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgcm93cyBtb3ZlZC4gYGZhbHNlYCB3aGVuIHRoZSBtb3ZlIHdhcyByZWplY3RlZCDigJRcbiAgICogICAgICAgICAgb3V0LW9mLXJhbmdlIGluZGljZXMsIGEgbm8tb3AsIG9yIGFuIG9yZGVyIHRoZSBncmlkIGRvZXMgbm90IG93blxuICAgKiAgICAgICAgICAoc2VlIHtAbGluayBnZXRSb3dEcmFnU3VwcHJlc3NlZFJlYXNvbn0pIOKAlCBzbyBhIGNhbGxlciBjYW4gdGVsbCBhXG4gICAqICAgICAgICAgIHJlZnVzZWQgbW92ZSBmcm9tIGFuIGFwcGxpZWQgb25lLlxuICAgKi9cbiAgcHVibGljIG1vdmVSb3coc291cmNlSW5kZXg6IG51bWJlciwgdGFyZ2V0SW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuXG4gICAgaWYgKHRoaXMuX2Rlc3Ryb3llZCkgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKCF0aGlzLmNhblJlb3JkZXJSb3dzKCkpIHJldHVybiBmYWxzZTtcblxuICAgIGNvbnN0IG9yZGVyID0gWy4uLnRoaXMuX29yaWdpbmFsUm93Tm9kZXMudmFsdWVzKCldO1xuXG4gICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKHNvdXJjZUluZGV4KSB8fCAhTnVtYmVyLmlzSW50ZWdlcih0YXJnZXRJbmRleCkpIHJldHVybiBmYWxzZTtcblxuICAgIGlmIChzb3VyY2VJbmRleCA8IDAgfHwgc291cmNlSW5kZXggPj0gb3JkZXIubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG5cbiAgICBpZiAodGFyZ2V0SW5kZXggPCAwIHx8IHRhcmdldEluZGV4ID49IG9yZGVyLmxlbmd0aCkgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKHNvdXJjZUluZGV4ID09PSB0YXJnZXRJbmRleCkgcmV0dXJuIGZhbHNlO1xuXG4gICAgY29uc3QgW21vdmVkXSA9IG9yZGVyLnNwbGljZShzb3VyY2VJbmRleCwgMSk7XG5cbiAgICBvcmRlci5zcGxpY2UodGFyZ2V0SW5kZXgsIDAsIG1vdmVkKTtcblxuICAgIC8vIFJlYnVpbHQgcmF0aGVyIHRoYW4gbXV0YXRlZDogYSBNYXAgcHJlc2VydmVzIGluc2VydGlvbiBvcmRlciwgYW5kIHRoZXJlXG4gICAgLy8gaXMgbm8gd2F5IHRvIHJlcG9zaXRpb24gYSBrZXkgd2l0aGluIG9uZS5cbiAgICB0aGlzLl9vcmlnaW5hbFJvd05vZGVzID0gbmV3IE1hcChvcmRlci5tYXAobm9kZSA9PiBbbm9kZS5yb3dJZCwgbm9kZV0pKTtcblxuICAgIHRoaXMuX3Jvd05vZGVzID0gb3JkZXI7XG5cbiAgICB0aGlzLnJlaW5kZXhSb3dzKCk7XG5cbiAgICB0aGlzLmV2ZW50U2VydmljZS5kaXNwYXRjaEV2ZW50KCdyb3dPcmRlckNoYW5nZWQnLCB7IG5vZGVzOiB0aGlzLl92aXNpYmxlUm93Tm9kZXMgYXMgT25lUm93Tm9kZTxUPltdLCBub2RlOiBtb3ZlZCwgZnJvbUluZGV4OiBzb3VyY2VJbmRleCwgdG9JbmRleDogdGFyZ2V0SW5kZXggfSk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb3ZlIGEgcm93IGlkZW50aWZpZWQgYnkgaWQuIENvbnZlbmllbnQgd2hlbiB0aGUgY2FsbGVyIGhvbGRzIGEgbm9kZSByYXRoZXJcbiAgICogdGhhbiBhIHBvc2l0aW9uIOKAlCB0aGUgaW5kZXggaXQgd2FzIGJ1aWx0IHdpdGggZ29lcyBzdGFsZSBhZnRlciBhbnkgbW92ZS5cbiAgICovXG4gIHB1YmxpYyBtb3ZlUm93QnlJZChyb3dJZDogc3RyaW5nLCB0YXJnZXRJbmRleDogbnVtYmVyKTogYm9vbGVhbiB7XG5cbiAgICBjb25zdCBzb3VyY2VJbmRleCA9IFsuLi50aGlzLl9vcmlnaW5hbFJvd05vZGVzLnZhbHVlcygpXS5maW5kSW5kZXgobm9kZSA9PiBub2RlLnJvd0lkID09PSByb3dJZCk7XG5cbiAgICByZXR1cm4gc291cmNlSW5kZXggPT09IC0xID8gZmFsc2UgOiB0aGlzLm1vdmVSb3coc291cmNlSW5kZXgsIHRhcmdldEluZGV4KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZS1zdGFtcCBgcm93SW5kZXhgIGZyb20gdGhlIGN1cnJlbnQgb3JkZXIuXG4gICAqXG4gICAqIFJvdyBpbmRleCBpcyBkZW5vcm1hbGlzZWQgb250byBldmVyeSBub2RlLCBhbmQgaGFsZiB0aGUgZ3JpZCByZWFkcyBpdCDigJRcbiAgICogY2VsbCBwYXJhbXMsIHRoZSByYW5nZSBzZWxlY3Rpb24sIHRoZSBkZXRhaWwgbG9va3VwLiBMZWF2aW5nIGl0IHN0YWxlIGFmdGVyXG4gICAqIGEgbW92ZSBwdXRzIGV2ZXJ5IHJvdyBiZWxvdyB0aGUgZHJvcCBwb2ludCBvbmUgb3V0LlxuICAgKi9cbiAgcHJpdmF0ZSByZWluZGV4Um93cygpOiB2b2lkIHtcblxuICAgIHRoaXMuX3Jvd05vZGVzLmZvckVhY2goKG5vZGUsIGluZGV4KSA9PiBub2RlLnNldFJvd0luZGV4KGluZGV4KSk7XG5cbiAgICAvLyBTaWxlbnQ6IHJvdyBudW1iZXJzIGFuZCB0aGUgdmlzaWJsZSBsaXN0IGhhdmUgdG8gYmUgcmVidWlsdCwgYnV0IHRoZVxuICAgIC8vIGByb3dEYXRhQ2hhbmdlZGAgdGhhdCBub3JtYWxseSBmb2xsb3dzIGRlZmVycyBhIGZyYW1lIGFuZCByZS1zZWVkcyBkZXRhaWxcbiAgICAvLyByb3dzLiBBIGtleWJvYXJkIGRyYWcgZmlyZXMgb25lIG9mIHRoZXNlIHBlciBhcnJvdyBrZXksIGFuZCBgbW92ZVJvd2BcbiAgICAvLyBhbm5vdW5jZXMgaXRzZWxmIHRocm91Z2ggYHJvd09yZGVyQ2hhbmdlZGAgaW5zdGVhZC5cbiAgICB0aGlzLnJlZnJlc2hWaXNpYmxlTm9kZXMoZmFsc2UpO1xuICB9XG5cbiAgcHVibGljIGdldFZpc2libGVSb3dOb2RlcygpOiBPbmVSb3dOb2RlPFQ+W10ge1xuXG4gICAgcmV0dXJuIHRoaXMuX3Zpc2libGVSb3dOb2RlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTb3J0aW5nIE1vZGVsIEZlYXR1cmVcbiAgICovXG4gIHB1YmxpYyBvblNvcnRDaGFuZ2VkKHNvcnRNb2RlbDogT25lU29ydE1vZGVsPFQ+W10pIHtcblxuICAgIGlmICh0aGlzLl9kZXN0cm95ZWQpIHJldHVybjtcblxuICAgIHRoaXMuX3NvcnRNb2RlbCA9IHNvcnRNb2RlbDtcblxuICAgIHRoaXMuYXBwbHlTb3J0aW5nKCk7XG5cbiAgICB0aGlzLmV2ZW50U2VydmljZS5kaXNwYXRjaEV2ZW50KCdzb3J0Q2hhbmdlZCcsIHsgbm9kZXM6IHRoaXMuX3Jvd05vZGVzIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhcHBseVNvcnRpbmcoKTogdm9pZCB7XG5cbiAgICBpZiAodGhpcy5fc29ydE1vZGVsLmxlbmd0aCA9PT0gMCkge1xuXG4gICAgICB0aGlzLl9yb3dOb2RlcyA9IFsuLi50aGlzLl9vcmlnaW5hbFJvd05vZGVzLnZhbHVlcygpXTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX3Jvd05vZGVzID0gWy4uLnRoaXMuX29yaWdpbmFsUm93Tm9kZXMudmFsdWVzKCldLnNvcnQoKGEsIGIpID0+IHtcblxuICAgICAgZm9yIChjb25zdCBzb3J0SXRlbSBvZiB0aGlzLl9zb3J0TW9kZWwpIHtcblxuICAgICAgICBjb25zdCB7IGNvbElkLCBzb3J0IH0gPSBzb3J0SXRlbTtcbiAgICAgICAgY29uc3QgdmFsQSA9IGdldEZpZWxkVmFsdWUoYS5kYXRhLCBjb2xJZCBhcyBzdHJpbmcpO1xuICAgICAgICBjb25zdCB2YWxCID0gZ2V0RmllbGRWYWx1ZShiLmRhdGEsIGNvbElkIGFzIHN0cmluZyk7XG4gICAgICAgIGNvbnN0IGNvbXBhcmlzb25SZXN1bHQgPSB0aGlzLmNvbXBhcmVWYWx1ZXModmFsQSwgdmFsQiwgc29ydCk7XG5cbiAgICAgICAgaWYgKGNvbXBhcmlzb25SZXN1bHQgIT09IDApIHtcblxuICAgICAgICAgIHJldHVybiBjb21wYXJpc29uUmVzdWx0O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gMDtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgY29tcGFyZVZhbHVlcyh2YWxBOiBhbnksIHZhbEI6IGFueSwgc29ydERpcmVjdGlvbjogJ2FzYycgfCAnZGVzYycpOiBudW1iZXIge1xuXG4gICAgLy8gYHVuZGVmaW5lZGAgaGFzIHRvIGJlIHRyZWF0ZWQgYXMgZW1wdHkgYWxvbmdzaWRlIGBudWxsYDogZ2V0RmllbGRWYWx1ZVxuICAgIC8vIHJldHVybnMgdW5kZWZpbmVkIGZvciBhIG1pc3NpbmcgZmllbGQgb3IgYW4gdW5yZXNvbHZlZCBkb3R0ZWQgcGF0aCwgYW5kXG4gICAgLy8gY29tcGFyaW5nIHVuZGVmaW5lZCB3aXRoIDwgLyA+IHlpZWxkcyBmYWxzZSBib3RoIHdheXMsIHdoaWNoIG1hZGUgc3VjaFxuICAgIC8vIHJvd3Mgc2V0dGxlIGluIHdoYXRldmVyIG9yZGVyIHRoZSBzb3J0IGhhcHBlbmVkIHRvIGVuY291bnRlciB0aGVtLlxuICAgIGNvbnN0IGFFbXB0eSA9IHZhbEEgPT09IG51bGwgfHwgdmFsQSA9PT0gdW5kZWZpbmVkO1xuICAgIGNvbnN0IGJFbXB0eSA9IHZhbEIgPT09IG51bGwgfHwgdmFsQiA9PT0gdW5kZWZpbmVkO1xuXG4gICAgaWYgKGFFbXB0eSAmJiBiRW1wdHkpIHJldHVybiAwO1xuICAgIGlmIChhRW1wdHkpIHJldHVybiBzb3J0RGlyZWN0aW9uID09PSAnYXNjJyA/IDEgOiAtMTtcbiAgICBpZiAoYkVtcHR5KSByZXR1cm4gc29ydERpcmVjdGlvbiA9PT0gJ2FzYycgPyAtMSA6IDE7XG5cbiAgICBpZiAodHlwZW9mIHZhbEEgPT09ICdzdHJpbmcnICYmIHR5cGVvZiB2YWxCID09PSAnc3RyaW5nJykge1xuXG4gICAgICBjb25zdCBjb21wYXJpc29uID0gdmFsQS5sb2NhbGVDb21wYXJlKHZhbEIsIHVuZGVmaW5lZCwgeyBudW1lcmljOiB0cnVlIH0pO1xuICAgICAgcmV0dXJuIHNvcnREaXJlY3Rpb24gPT09ICdhc2MnID8gY29tcGFyaXNvbiA6IC1jb21wYXJpc29uO1xuICAgIH1cblxuICAgIGlmICh2YWxBIDwgdmFsQikgcmV0dXJuIHNvcnREaXJlY3Rpb24gPT09ICdhc2MnID8gLTEgOiAxO1xuICAgIGlmICh2YWxBID4gdmFsQikgcmV0dXJuIHNvcnREaXJlY3Rpb24gPT09ICdhc2MnID8gMSA6IC0xO1xuICAgIHJldHVybiAwO1xuICB9XG5cbiAgLyoqXG4gICAqIFJvdyBTZWxlY3Rpb24gRmVhdHVyZSAoT3B0aW1pemVkKVxuICAgKi9cbiAgcHVibGljIHNlbGVjdEFsbCgpOiB2b2lkIHtcblxuICAgIGNvbnN0IHJvd0lkczogc3RyaW5nW10gPSBbXTtcblxuICAgIHRoaXMuX29yaWdpbmFsUm93Tm9kZXMuZm9yRWFjaChub2RlID0+IHtcblxuICAgICAgbm9kZS5zZXRTZWxlY3RlZCh0cnVlKTtcblxuICAgICAgbm9kZS5jZWxsU3RhdGVzID0geyAuLi5ub2RlLmNlbGxTdGF0ZXMgfTtcblxuICAgICAgcm93SWRzLnB1c2gobm9kZS5yb3dJZCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnNlbGVjdGlvblNlcnZpY2Uuc2VsZWN0QWxsKHJvd0lkcyk7XG5cbiAgICB0aGlzLmV2ZW50U2VydmljZS5kaXNwYXRjaEV2ZW50KCdzZWxlY3Rpb25DaGFuZ2VkJywgeyBhbGxOb2Rlc05vdFNlbGVjdGVkOiBmYWxzZSwgYWxsTm9kZXNTZWxlY3RlZDogdHJ1ZSwgc2VsZWN0ZWQ6IHRydWUsIG5vZGU6IG51bGwgfSk7XG4gIH1cblxuICAvKipcbiAgICogRGVzZWxlY3QgYWxsIG5vZGVzIChvcHRpbWl6ZWQpXG4gICAqL1xuICBwdWJsaWMgZGVzZWxlY3RBbGwoKTogdm9pZCB7XG5cbiAgICB0aGlzLl9vcmlnaW5hbFJvd05vZGVzLmZvckVhY2gobm9kZSA9PiB7XG5cbiAgICAgIG5vZGUuc2V0U2VsZWN0ZWQoZmFsc2UpO1xuXG4gICAgICBub2RlLmNlbGxTdGF0ZXMgPSB7IC4uLm5vZGUuY2VsbFN0YXRlcyB9O1xuICAgIH0pO1xuXG4gICAgdGhpcy5zZWxlY3Rpb25TZXJ2aWNlLmRlc2VsZWN0QWxsKCk7XG5cbiAgICBpZiAodGhpcy5zZWxlY3Rpb25TZXJ2aWNlLmdldFNlbGVjdGlvbk1vZGUoKSA9PT0gJ211bHRpcGxlJykge1xuXG4gICAgICB0aGlzLmV2ZW50U2VydmljZS5kaXNwYXRjaEV2ZW50KCdzZWxlY3Rpb25DaGFuZ2VkJywge1xuICAgICAgICBhbGxOb2Rlc05vdFNlbGVjdGVkOiB0cnVlLFxuICAgICAgICBhbGxOb2Rlc1NlbGVjdGVkOiBmYWxzZSxcbiAgICAgICAgc2VsZWN0ZWQ6IGZhbHNlLFxuICAgICAgICBub2RlOiBudWxsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgdG9nZ2xlU2VsZWN0aW9uKHJvd0lkOiBzdHJpbmcsIHNlbGVjdGVkOiBib29sZWFuKTogdm9pZCB7XG5cbiAgICBjb25zdCBub2RlID0gdGhpcy5nZXRSb3dOb2RlQnlJZChyb3dJZCk7XG5cbiAgICBpZiAobm9kZSkge1xuXG4gICAgICBub2RlLnNldFNlbGVjdGVkKHNlbGVjdGVkKTtcblxuICAgICAgdGhpcy5zZWxlY3Rpb25TZXJ2aWNlLnRvZ2dsZVNlbGVjdGlvbihyb3dJZCwgc2VsZWN0ZWQpO1xuXG4gICAgICB0aGlzLmV2ZW50U2VydmljZS5kaXNwYXRjaEV2ZW50KCdzZWxlY3Rpb25DaGFuZ2VkJywgeyBub2RlLCBkYXRhOiBub2RlLmRhdGEsIHNlbGVjdGVkIH0pO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBzZXRTZWxlY3RlZEJ5SWQocm93SWQ6IHN0cmluZykge1xuXG4gICAgY29uc3Qgbm9kZSA9IHRoaXMuZ2V0Um93Tm9kZUJ5SWQocm93SWQpO1xuXG4gICAgaWYgKG5vZGUpIHtcblxuICAgICAgaWYgKHRoaXMuc2VsZWN0aW9uU2VydmljZS5nZXRTZWxlY3Rpb25Nb2RlKCkgPT09ICdzaW5nbGUnKSB7XG5cbiAgICAgICAgdGhpcy5fcm93Tm9kZXMuZm9yRWFjaChyb3dOb2RlID0+IHJvd05vZGUuc2V0U2VsZWN0ZWQocm93Tm9kZS5yb3dJZCA9PT0gbm9kZS5yb3dJZCkpO1xuXG4gICAgICAgIHRoaXMuX29yaWdpbmFsUm93Tm9kZXMuZm9yRWFjaChyb3dOb2RlID0+IHJvd05vZGUuc2V0U2VsZWN0ZWQocm93Tm9kZS5yb3dJZCA9PT0gbm9kZS5yb3dJZCkpO1xuXG4gICAgICB9IGVsc2Uge1xuXG4gICAgICAgIG5vZGUuc2V0U2VsZWN0ZWQodHJ1ZSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc2VsZWN0aW9uU2VydmljZS50b2dnbGVTZWxlY3Rpb24ocm93SWQsIHRydWUpO1xuXG4gICAgICB0aGlzLmV2ZW50U2VydmljZS5kaXNwYXRjaEV2ZW50KCdzZWxlY3Rpb25DaGFuZ2VkJywgeyBub2RlLCBzZWxlY3RlZDogdHJ1ZSB9KTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgc2V0U2VsZWN0ZWRCeUlkcyhyb3dJZHM6IHN0cmluZ1tdLCBzZWxlY3RlZDogYm9vbGVhbiA9IHRydWUpIHtcblxuICAgIHJvd0lkcy5mb3JFYWNoKHJvd0lkID0+IHtcblxuICAgICAgY29uc3Qgbm9kZSA9IHRoaXMuX29yaWdpbmFsUm93Tm9kZXMuZ2V0KHJvd0lkKTtcblxuICAgICAgaWYgKG5vZGUpIHtcblxuICAgICAgICBub2RlLnNldFNlbGVjdGVkKHNlbGVjdGVkKTtcblxuICAgICAgICBub2RlLmNlbGxTdGF0ZXMgPSB7IC4uLm5vZGUuY2VsbFN0YXRlcyB9O1xuXG4gICAgICAgIHRoaXMuc2VsZWN0aW9uU2VydmljZS50b2dnbGVTZWxlY3Rpb24ocm93SWQsIHNlbGVjdGVkKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMuZXZlbnRTZXJ2aWNlLmRpc3BhdGNoRXZlbnQoJ3NlbGVjdGlvbkNoYW5nZWQnLCB7IG5vZGU6IG51bGwgfSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0ICYgU2V0IEZ1bmN0aW9uc1xuICAgKi9cbiAgcHVibGljIGdldEFsbFJvd05vZGVzKCk6IE9uZVJvd05vZGU8VD5bXSB7XG5cbiAgICByZXR1cm4gdGhpcy5fcm93Tm9kZXM/Lmxlbmd0aCA+IDAgPyBbLi4udGhpcy5fcm93Tm9kZXNdIDogW107XG4gIH1cblxuICBwdWJsaWMgZ2V0Um93RGF0YVNlbGVjdGVkKCk6IFRbXSB7XG5cbiAgICByZXR1cm4gdGhpcy5fcm93Tm9kZXMuZmlsdGVyKG5vZGUgPT4gbm9kZS5zZWxlY3RlZCkubWFwKG5vZGUgPT4gKHsgLi4ubm9kZS5kYXRhIH0pKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRTZWxlY3RlZFJvd05vZGVzKCk6IE9uZVJvd05vZGU8VD5bXSB7XG5cbiAgICBjb25zdCBub2RlcyA9IHRoaXMuX3Jvd05vZGVzLmZpbHRlcihub2RlID0+IG5vZGUuc2VsZWN0ZWQpO1xuXG4gICAgcmV0dXJuIG5vZGVzICYmIG5vZGVzLmxlbmd0aCA+IDAgPyBbLi4ubm9kZXNdIDogW107XG4gIH1cblxuICAvKipcbiAgICogQ29sdW1uIGZpbHRlcnNcbiAgICovXG4gIHB1YmxpYyBnZXRGaWx0ZXJNb2RlbCgpOiBPbmVGaWx0ZXJNb2RlbFtdIHtcblxuICAgIHJldHVybiB0aGlzLl9hY3RpdmVGaWx0ZXJzO1xuICB9XG5cbiAgcHVibGljIHNldEZpbHRlck1vZGVsKG1vZGVsOiBPbmVGaWx0ZXJNb2RlbFtdKTogdm9pZCB7XG5cbiAgICBpZiAodGhpcy5fZGVzdHJveWVkKSByZXR1cm47XG5cbiAgICB0aGlzLl9hY3RpdmVGaWx0ZXJzID0gbW9kZWw7XG5cbiAgICB0aGlzLmFwcGx5RmlsdGVycygpO1xuICB9XG5cbiAgcHVibGljIGZpbHRlckFjdGl2ZShmaWVsZDogc3RyaW5nKTogYm9vbGVhbiB7XG5cbiAgICByZXR1cm4gdGhpcy5fYWN0aXZlRmlsdGVycy5zb21lKGYgPT4gZi5maWVsZCA9PT0gZmllbGQgJiYgZi5jb25kaXRpb25zLmxlbmd0aCA+IDApO1xuICB9XG5cbiAgLyoqXG4gICAqIFF1aWNrIGZpbHRlclxuICAgKi9cbiAgcHVibGljIHNldFF1aWNrRmlsdGVyKHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcblxuICAgIGlmICh0aGlzLl9kZXN0cm95ZWQpIHJldHVybjtcblxuICAgIHRoaXMuX3F1aWNrRmlsdGVyVmFsdWUgPSAodmFsdWUgfHwgJycpLnRvTG93ZXJDYXNlKCk7XG5cbiAgICB0aGlzLmFwcGx5RmlsdGVycygpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1biB0aGUgY29sdW1uIHZhbGlkYXRvcnMgb3ZlciBvbmUgcm93LlxuICAgKlxuICAgKiBSdWxlcyBydW4gaW4gb3JkZXIgYW5kIHN0b3AgYXQgdGhlIGZpcnN0IGZhaWx1cmUsIHNvIGEgZmllbGQgYXBwZWFycyBhdFxuICAgKiBtb3N0IG9uY2UuIEZpZWxkcyB0aGF0IHBhc3NlZCBhcmUgYWJzZW50IHJhdGhlciB0aGFuIG1hcHBlZCB0byBgbnVsbGAuXG4gICAqXG4gICAqIFRoZSByb3cgdHlwZSBjb21lcyBmcm9tIHRoZSBncmlkJ3Mgb3duIGBUYCDigJQgdGhpcyB1c2VkIHRvIGRlY2xhcmUgaXRzIG93blxuICAgKiBgPFQ+YCwgd2hpY2ggc2hhZG93ZWQgdGhlIGNsYXNzIHBhcmFtZXRlciBhbmQgbGV0IGFuIGBPbmVHcmlkQXBpPEVtcGxveWVlPmBcbiAgICogaGFwcGlseSB2YWxpZGF0ZSBhbiB1bnJlbGF0ZWQgc2hhcGUgYWdhaW5zdCBlbXBsb3llZSBjb2x1bW5zLlxuICAgKi9cbiAgcHVibGljIHZhbGlkYXRlUm93KHJvdzogVCwgY29sdW1uczogT25lQ29sdW1uRGVmPFQ+W10pOiBPbmVSb3dWYWxpZGF0aW9uRXJyb3JzPFQ+IHtcblxuICAgIGNvbnN0IGVycm9yczogT25lUm93VmFsaWRhdGlvbkVycm9yczxUPiA9IHt9O1xuXG4gICAgZm9yIChjb25zdCBjb2x1bW4gb2YgY29sdW1ucykge1xuXG4gICAgICAvLyBBIGNvbHVtbiBjYW4gb25seSBjb250cmlidXRlIGFuIGVycm9yIGlmIGl0IGhhcyBib3RoIHJ1bGVzIGFuZCBhIGZpZWxkXG4gICAgICAvLyB0byBrZXkgdGhlbSB1bmRlci5cbiAgICAgIGlmICghY29sdW1uLmZpZWxkIHx8ICFjb2x1bW4udmFsaWRhdGlvblJ1bGVzPy5sZW5ndGgpIGNvbnRpbnVlO1xuXG4gICAgICBmb3IgKGNvbnN0IHJ1bGUgb2YgY29sdW1uLnZhbGlkYXRpb25SdWxlcykge1xuXG4gICAgICAgIGNvbnN0IGVycm9yID0gcnVsZShyb3dbY29sdW1uLmZpZWxkXSwgcm93KTtcblxuICAgICAgICBpZiAoZXJyb3IpIHtcblxuICAgICAgICAgIGVycm9yc1tjb2x1bW4uZmllbGRdID0gZXJyb3I7XG5cbiAgICAgICAgICBicmVhazsgLy8gZmlyc3QgZmFpbHVyZSBwZXIgY29sdW1uIHdpbnNcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBlcnJvcnM7XG4gIH1cblxuICAvKipcbiAgICogUnVuIHRoZSBjb2x1bW4gdmFsaWRhdG9ycyBvdmVyIGEgd2hvbGUgZGF0YXNldC5cbiAgICpcbiAgICogRGVsZWdhdGVzIHRvIGB2YWxpZGF0ZVJvd2Agc28gdGhlIHR3byBjYW4gbmV2ZXIgZGlzYWdyZWUgYWJvdXQgd2hhdCBjb3VudHNcbiAgICogYXMgaW52YWxpZCDigJQgdGhleSBwcmV2aW91c2x5IGNhcnJpZWQgc2VwYXJhdGUgY29waWVzIG9mIHRoZSBzYW1lIGxvb3AuXG4gICAqL1xuICBwdWJsaWMgdmFsaWRhdGVBbGxSb3dzKHJvd0RhdGE6IFRbXSwgY29sdW1uczogT25lQ29sdW1uRGVmPFQ+W10pOiBPbmVWYWxpZGF0aW9uUmVzdWx0PFQ+IHtcblxuICAgIGNvbnN0IGFsbEVycm9ycyA9IHJvd0RhdGEubWFwKHJvdyA9PiB0aGlzLnZhbGlkYXRlUm93KHJvdywgY29sdW1ucykpO1xuXG4gICAgY29uc3QgaGFzRXJyb3JzID0gYWxsRXJyb3JzLnNvbWUoZXJyb3JzID0+IE9iamVjdC5rZXlzKGVycm9ycykubGVuZ3RoID4gMCk7XG5cbiAgICByZXR1cm4geyBlcnJvcnM6IGFsbEVycm9ycywgdmFsaWQ6ICFoYXNFcnJvcnMsIGludmFsaWQ6IGhhc0Vycm9ycyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYXZlcnNlIGV2ZXJ5IG5vZGUsIGRlcHRoLWZpcnN0LCBvbmNlIGVhY2guXG4gICAqXG4gICAqIGByb3dOb2Rlc2AgaXMgYWxyZWFkeSB0aGUgZmxhdHRlbmVkIHRyZWUg4oCUIGBidWlsZFJvd05vZGVzYCBwdXNoZXMgZXZlcnlcbiAgICogbm9kZSBpbnRvIGl0IGFzIGl0IGRlc2NlbmRzIOKAlCBzbyB3YWxraW5nIGl0IGlzIHRoZSB3aG9sZSB0cmF2ZXJzYWwuIFRoZVxuICAgKiBwcmV2aW91cyBpbXBsZW1lbnRhdGlvbiB3YWxrZWQgdGhhdCBmbGF0IGxpc3QgKmFuZCogcmVjdXJzZWQgaW50b1xuICAgKiBgY2hpbGRyZW5gLCB2aXNpdGluZyBldmVyeSBuZXN0ZWQgbm9kZSB0d2ljZSBhbmQgZXZlcnkgZGVwdGgtMyBub2RlIHRocmVlXG4gICAqIHRpbWVzLiBgaW5kZXhgIGlzIHRoZSBub2RlJ3MgcG9zaXRpb24gaW4gdGhlIGZsYXR0ZW5lZCBvcmRlciwgbWF0Y2hpbmdcbiAgICogYG5vZGUucm93SW5kZXhgLCByYXRoZXIgdGhhbiBpdHMgcG9zaXRpb24gYW1vbmcgaXRzIHNpYmxpbmdzLlxuICAgKi9cbiAgcHVibGljIGZvckVhY2hOb2RlKGNhbGxiYWNrOiAobm9kZTogT25lUm93Tm9kZTxUPiwgaW5kZXg6IG51bWJlcikgPT4gdm9pZCkge1xuXG4gICAgdGhpcy5fcm93Tm9kZXMuZm9yRWFjaCgobm9kZSwgaW5kZXgpID0+IGNhbGxiYWNrKG5vZGUsIGluZGV4KSk7XG4gIH1cblxuICAvKiogVHJhdmVyc2Ugb25seSBsZWFmIG5vZGVzLCBvbmNlIGVhY2gsIGluIGZsYXR0ZW5lZCBvcmRlci4gKi9cbiAgcHVibGljIGZvckVhY2hMZWFmTm9kZShjYWxsYmFjazogKG5vZGU6IE9uZVJvd05vZGU8VD4sIGluZGV4OiBudW1iZXIpID0+IHZvaWQpIHtcblxuICAgIGxldCBsZWFmSW5kZXggPSAwO1xuXG4gICAgZm9yIChjb25zdCBub2RlIG9mIHRoaXMuX3Jvd05vZGVzKSB7XG5cbiAgICAgIGlmIChub2RlLmxlYWYpIGNhbGxiYWNrKG5vZGUsIGxlYWZJbmRleCsrKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZ2V0Um93Tm9kZUJ5SWQocm93SWQ6IHN0cmluZyk6IE9uZVJvd05vZGU8VD4ge1xuXG4gICAgcmV0dXJuIHRoaXMuX29yaWdpbmFsUm93Tm9kZXMuZ2V0KHJvd0lkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBhbmQvY29sbGFwc2UgYSBub2RlXG4gICAqL1xuICBwdWJsaWMgc2V0VHJlZURhdGFDaGlsZHJlbkZpZWxkKGZpZWxkOiBzdHJpbmcpIHtcblxuICAgIHRoaXMudHJlZURhdGFDaGlsZHJlbkZpZWxkID0gZmllbGQ7XG4gIH1cblxuICBwdWJsaWMgc2V0R3JvdXBEZWZhdWx0RXhwYW5kZWQoZGVmYXVsdEV4cGFuZGVkOiBudW1iZXIpIHtcblxuICAgIHRoaXMuZ3JvdXBEZWZhdWx0RXhwYW5kZWQgPSBkZWZhdWx0RXhwYW5kZWQ7XG4gIH1cblxuICAvKipcbiAgICogRXhwYW5zaW9uIHN0YXRlIGxpdmVzIGluIHR3byBwbGFjZXMsIGFuZCB0aGV5IGFuc3dlciBkaWZmZXJlbnQgcXVlc3Rpb25zLlxuICAgKlxuICAgKiBgT25lR3JpZEV4cGFuc2lvblNlcnZpY2VgIHJlY29yZHMgb25seSAqZGVsaWJlcmF0ZSogY2hhbmdlcyDigJQgYSBjbGljaywgb3JcbiAgICogb25lIG9mIHRoZSBtZXRob2RzIGJlbG93LiBJdCBpcyBhbiBvdmVycmlkZSBsYXllcjogYGJ1aWxkUm93Tm9kZXNgIGNvbnN1bHRzXG4gICAqIGl0IGZpcnN0IGFuZCBmYWxscyBiYWNrIHRvIGBncm91cERlZmF1bHRFeHBhbmRlZGAgZm9yIGV2ZXJ5IHJvdyB0aGUgdXNlclxuICAgKiBoYXMgbm90IHRvdWNoZWQuIFRoYXQgaXMgd2hhdCBsZXRzIGEgbGF0ZXIgYGdyb3VwRGVmYXVsdEV4cGFuZGVkYCBjaGFuZ2VcbiAgICogdGFrZSBlZmZlY3QsIGFuZCB3aGF0IGxldHMgYSBjb2xsYXBzZSBzdXJ2aXZlIGEgcmVidWlsZC5cbiAgICpcbiAgICogYG5vZGUuZXhwYW5kZWRgIGlzIHRoZSByZXNvbHZlZCB0cnV0aCBmb3IgYSByb3csIGRlZmF1bHRzIGluY2x1ZGVkLiBQdWJsaWNcbiAgICogcmVhZHMgcmVwb3J0IHRoYXQ7IHRoZSBvdmVycmlkZSBzZXRzIHN0YXkgaW50ZXJuYWwuXG4gICAqXG4gICAqIFRoZSBpbnZhcmlhbnQgdGhlIHNldHRlcnMgYmVsb3cgbWFpbnRhaW46IGBleHBhbmRlZGAgaXMgb25seSBldmVyIHRydWUgZm9yXG4gICAqIGEgbm9kZSB0aGF0IGNhbiBleHBhbmQuXG4gICAqL1xuICBwdWJsaWMgdG9nZ2xlRXhwYW5kQWxsKGV4cGFuZGVkOiBib29sZWFuKSB7XG5cbiAgICB0aGlzLmZvckVhY2hOb2RlKG5vZGUgPT4ge1xuXG4gICAgICBpZiAoIW5vZGUuZXhwYW5kYWJsZSkgcmV0dXJuO1xuXG4gICAgICBub2RlLnNldEV4cGFuZGVkKGV4cGFuZGVkKTtcblxuICAgICAgdGhpcy5leHBhbnNpb25TZXJ2aWNlLnRvZ2dsZUV4cGFuZGVkKG5vZGUucm93SWQsIGV4cGFuZGVkKVxuICAgIH0pO1xuXG4gICAgdGhpcy5yZWZyZXNoVmlzaWJsZU5vZGVzKCk7XG4gIH1cblxuICBwdWJsaWMgc2V0RXhwYW5kZWRCeUlkKHJvd0lkOiBzdHJpbmcsIGV4cGFuZGVkOiBib29sZWFuKSB7XG5cbiAgICBjb25zdCBub2RlID0gdGhpcy5fb3JpZ2luYWxSb3dOb2Rlcy5nZXQocm93SWQpO1xuXG4gICAgaWYgKG5vZGU/LmV4cGFuZGFibGUpIHtcblxuICAgICAgbm9kZS5zZXRFeHBhbmRlZChleHBhbmRlZCk7XG5cbiAgICAgIHRoaXMuZXhwYW5zaW9uU2VydmljZS50b2dnbGVFeHBhbmRlZChyb3dJZCwgZXhwYW5kZWQpO1xuICAgIH1cblxuICAgIHRoaXMucmVmcmVzaFZpc2libGVOb2RlcygpO1xuICB9XG5cbiAgcHVibGljIHNldEV4cGFuZGVkQnlJZHMocm93SWRzOiBzdHJpbmdbXSwgZXhwYW5kZWQ6IGJvb2xlYW4pIHtcblxuICAgIGlmIChyb3dJZHMgJiYgcm93SWRzLmxlbmd0aCA+IDApIHtcblxuICAgICAgZm9yIChsZXQgcm93SWQgb2Ygcm93SWRzKSB7XG5cbiAgICAgICAgY29uc3Qgbm9kZSA9IHRoaXMuX29yaWdpbmFsUm93Tm9kZXMuZ2V0KHJvd0lkKTtcblxuICAgICAgICBpZiAobm9kZT8uZXhwYW5kYWJsZSkge1xuXG4gICAgICAgICAgbm9kZS5zZXRFeHBhbmRlZChleHBhbmRlZCk7XG5cbiAgICAgICAgICB0aGlzLmV4cGFuc2lvblNlcnZpY2UudG9nZ2xlRXhwYW5kZWQocm93SWQsIGV4cGFuZGVkKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLnJlZnJlc2hWaXNpYmxlTm9kZXMoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRXZlcnkgY3VycmVudGx5IGV4cGFuZGVkIHJvdywgaW4gdHJlZSBvcmRlci5cbiAgICpcbiAgICogRGVyaXZlZCBmcm9tIHRoZSBub2RlcyByYXRoZXIgdGhhbiByZWFkIG9mZiB0aGUgb3ZlcnJpZGUgcmVjb3JkLCBzbyByb3dzXG4gICAqIG9wZW5lZCBieSBgZ3JvdXBEZWZhdWx0RXhwYW5kZWRgIGFyZSBpbmNsdWRlZCDigJQgcHJldmlvdXNseSB0aGlzIHJldHVybmVkXG4gICAqIG9ubHkgcm93cyBzb21lb25lIGhhZCBleHBsaWNpdGx5IHRvZ2dsZWQsIGFuZCBjYW1lIGJhY2sgZW1wdHkgb24gZmlyc3QgbG9hZFxuICAgKiB3aGlsZSB0aGUgZmlyc3QgbGV2ZWwgd2FzIHZpc2libHkgb3Blbi5cbiAgICovXG4gIHB1YmxpYyBnZXRFeHBhbmRlZEJ5SWRzKCk6IHN0cmluZ1tdIHtcblxuICAgIHJldHVybiB0aGlzLl9yb3dOb2Rlc1xuXG4gICAgICAuZmlsdGVyKG5vZGUgPT4gbm9kZS5leHBhbmRhYmxlICYmIG5vZGUuZXhwYW5kZWQpXG5cbiAgICAgIC5tYXAobm9kZSA9PiBub2RlLnJvd0lkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYXN0ZXIgRGV0YWlsIEZlYXR1cmVcbiAgICovXG4gIHB1YmxpYyBzZXREZXRhaWxSb3dEYXRhKG5vZGU6IE9uZVJvd05vZGU8VD4sIGRldGFpbERhdGE6IGFueVtdKSB7XG5cbiAgICBpZiAodGhpcy5fZGVzdHJveWVkKSByZXR1cm47XG5cbiAgICBjb25zdCByb3dOb2RlID0gdGhpcy5nZXRSb3dOb2RlQnlJZChub2RlLnJvd0lkKTtcblxuICAgIGlmIChyb3dOb2RlKSB7XG5cbiAgICAgIHJvd05vZGUuc2V0RGV0YWlsUm93RGF0YShkZXRhaWxEYXRhKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgc2V0R2V0RGV0YWlsUm93RGF0YShnZXREZXRhaWxSb3dEYXRhOiAocGFyYW1zOiBPbmVHZXREZXRhaWxSb3dEYXRhUGFyYW1zKSA9PiB2b2lkKSB7XG5cbiAgICB0aGlzLl9nZXREZXRhaWxSb3dEYXRhID0gZ2V0RGV0YWlsUm93RGF0YTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb2x1bW5zIFN0YXRlXG4gICAqL1xuICBwdWJsaWMgZ2V0Q29sdW1uU3RhdGUoKTogQ29sdW1uQ2hhbmdlZEV2ZW50IHtcblxuICAgIHJldHVybiB0aGlzLmNvbHVtblNlcnZpY2UuZ2V0Q29sdW1uU3RhdGUoKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRDb2x1bW5EZWZzKGNvbHVtbkRlZnM6IE9uZUNvbHVtbkRlZjxUPltdKTogdm9pZCB7XG5cbiAgICBpZiAodGhpcy5fZGVzdHJveWVkKSByZXR1cm47XG5cbiAgICB0aGlzLmNvbHVtblNlcnZpY2Uuc2V0Q29sdW1uRGVmcyhjb2x1bW5EZWZzKTtcblxuICAgIGNvbnN0IGNvbHVtblN0YXRlID0gdGhpcy5jb2x1bW5TZXJ2aWNlLmdldENvbHVtblN0YXRlKCk7XG5cbiAgICB0aGlzLmNlbGxTZXJ2aWNlLmFwcGx5Q29sdW1uRGVmcyhjb2x1bW5TdGF0ZS5jb2x1bW5zLCB0aGlzLl9jb250ZXh0KTtcblxuICAgIHRoaXMuZXZlbnRTZXJ2aWNlLmRpc3BhdGNoRXZlbnQoJ2NvbHVtbkNoYW5nZWQnLCBjb2x1bW5TdGF0ZSk7XG4gIH1cblxuICBwdWJsaWMgdXBkYXRlQ29sdW1uKGlkOiBzdHJpbmcsIGNoYW5nZXM6IFBhcnRpYWw8T25lQ29sdW1uRGVmPFQ+Pik6IHZvaWQge1xuXG4gICAgdGhpcy5jb2x1bW5TZXJ2aWNlLnVwZGF0ZUNvbHVtbkRlZihpZCwgY2hhbmdlcyk7XG5cbiAgICBjb25zdCBjb2x1bW5TdGF0ZSA9IHRoaXMuY29sdW1uU2VydmljZS5nZXRDb2x1bW5TdGF0ZSgpO1xuXG4gICAgdGhpcy5jZWxsU2VydmljZS5hcHBseUNvbHVtbkRlZnMoY29sdW1uU3RhdGUuY29sdW1ucywgdGhpcy5fY29udGV4dCk7XG5cbiAgICB0aGlzLmV2ZW50U2VydmljZS5kaXNwYXRjaEV2ZW50KCdjb2x1bW5DaGFuZ2VkJywgY29sdW1uU3RhdGUpO1xuICB9XG5cbiAgcHVibGljIHJlb3JkZXJDb2x1bW5EZWZzKGZyb21JbmRleDogbnVtYmVyLCB0b0luZGV4OiBudW1iZXIpOiB2b2lkIHtcblxuICAgIHRoaXMuY29sdW1uU2VydmljZS5yZW9yZGVyQ29sdW1uRGVmcyhmcm9tSW5kZXgsIHRvSW5kZXgpO1xuXG4gICAgY29uc3QgY29sdW1uU3RhdGUgPSB0aGlzLmNvbHVtblNlcnZpY2UuZ2V0Q29sdW1uU3RhdGUoKTtcblxuICAgIHRoaXMuZXZlbnRTZXJ2aWNlLmRpc3BhdGNoRXZlbnQoJ2NvbHVtbkNoYW5nZWQnLCBjb2x1bW5TdGF0ZSk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIGNoZWNrYm94IHNlbGVjdGlvbiBmZWF0dXJlc1xuICAgKi9cbiAgcHVibGljIHNldE5vZGVBbmRDaGlsZHJlblNlbGVjdGVkKG5vZGU6IE9uZVJvd05vZGUsIHNlbGVjdGVkOiBib29sZWFuKSB7XG5cbiAgICBjb25zdCByb3dJZHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICAgIGNvbnN0IGNvbGxlY3QgPSAobjogT25lUm93Tm9kZSkgPT4ge1xuXG4gICAgICByb3dJZHMuYWRkKG4ucm93SWQpO1xuXG4gICAgICBpZiAobi5jaGlsZHJlbiAmJiBuLmNoaWxkcmVuLmxlbmd0aCkge1xuXG4gICAgICAgIG4uY2hpbGRyZW4uZm9yRWFjaChjaGlsZCA9PiBjb2xsZWN0KGNoaWxkKSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGNvbGxlY3Qobm9kZSk7XG5cbiAgICB0aGlzLnNldFNlbGVjdGVkQnlJZHMoQXJyYXkuZnJvbShyb3dJZHMpLCBzZWxlY3RlZCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgSWRlbnRpY2FsIHRvIGB1cGRhdGVDZWxsU3RhdGVzYC4gS2VwdCBhcyBhbiBhbGlhcyBzbyBleGlzdGluZ1xuICAgKiBjYWxsZXJzIGtlZXAgd29ya2luZzsgcHJlZmVyIGB1cGRhdGVDZWxsU3RhdGVzYCwgd2hpY2ggc2F5cyB3aGF0IGl0IGRvZXMuXG4gICAqL1xuICBwdWJsaWMgdXBkYXRlTm9kZVN0YXRlcyhub2RlOiBPbmVSb3dOb2RlKSB7XG5cbiAgICB0aGlzLnVwZGF0ZUNlbGxTdGF0ZXMobm9kZSk7XG4gIH1cblxuICBwdWJsaWMgdXBkYXRlQ2VsbFN0YXRlKG5vZGU6IE9uZVJvd05vZGUsIGNvbHVtbjogT25lQ29sdW1uRGVmKTogdm9pZCB7XG5cbiAgICBjb25zdCByb3dOb2RlID0gdGhpcy5nZXRSb3dOb2RlQnlJZChub2RlLnJvd0lkKTtcblxuICAgIGlmIChyb3dOb2RlKSB7XG5cbiAgICAgIHJvd05vZGUuY2VsbFN0YXRlc1tjb2x1bW4uZmllbGRdID0gdGhpcy5jZWxsU2VydmljZS5nZW5lcmF0ZUNlbGxTdGF0ZShyb3dOb2RlLCBjb2x1bW4pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvbXB1dGUgZXZlcnkgY2VsbCBvZiBvbmUgcm93IGFuZCByZXBhaW50IGl0LlxuICAgKlxuICAgKiBUaGUgcmVwYWludCBpcyB0aGUgcG9pbnQ6IHRoaXMgaXMgd2hhdCBhIGNhbGxlciByZWFjaGVzIGZvciBhZnRlciBtdXRhdGluZ1xuICAgKiBhIHJvdyBpbiBwbGFjZSwgYW5kIGl0IHVzZWQgdG8gcmVnZW5lcmF0ZSB0aGUgc3RhdGUgYW5kIHN0b3AgdGhlcmUuIFRoZVxuICAgKiBib2R5IHJlbmRlcnMgd2l0aCBPblB1c2gsIHNvIG5vdGhpbmcgbWFya2VkIGl0IGRpcnR5IGFuZCB0aGUgbmV3IHN0YXRlIHNhdFxuICAgKiB1bnJlYWQgdW50aWwgc29tZSB1bnJlbGF0ZWQgZXZlbnQgaGFwcGVuZWQgdG8gdHJpZ2dlciBjaGFuZ2UgZGV0ZWN0aW9uIOKAlFxuICAgKiB3aGljaCBpcyB3aHkgY2FsbGVycyBlbmRlZCB1cCBudWRnaW5nIHRoZSBncmlkIHdpdGggYSBzeW50aGV0aWMgRE9NIGV2ZW50LlxuICAgKi9cbiAgcHVibGljIHVwZGF0ZUNlbGxTdGF0ZXMobm9kZTogT25lUm93Tm9kZSk6IHZvaWQge1xuXG4gICAgaWYgKHRoaXMuX2Rlc3Ryb3llZCkgcmV0dXJuO1xuXG4gICAgY29uc3Qgcm93Tm9kZSA9IHRoaXMuZ2V0Um93Tm9kZUJ5SWQobm9kZS5yb3dJZCk7XG5cbiAgICBpZiAoIXJvd05vZGUpIHJldHVybjtcblxuICAgIHJvd05vZGUuY2VsbFN0YXRlcyA9IHRoaXMuY2VsbFNlcnZpY2UuZ2VuZXJhdGVDZWxsU3RhdGVzKHJvd05vZGUpO1xuXG4gICAgdGhpcy5ldmVudFNlcnZpY2UuZGlzcGF0Y2hFdmVudCgnY2VsbFN0YXRlQ2hhbmdlZCcsIHsgZGF0YTogcm93Tm9kZS5kYXRhLCBub2RlOiByb3dOb2RlIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZXIgdGhhdCBSZWFjdHMgdG8gRGV0YWlsIENoYW5nZXNcbiAgICovXG4gIC8qKlxuICAgKiBLZWVwIGEgbWFzdGVyIHJvdydzIHJlc2VydmVkIGhlaWdodCBpbiBzdGVwIHdpdGggaXRzIGRldGFpbCByb3dzLlxuICAgKlxuICAgKiBUd28gbGlzdGVuZXJzIHVzZWQgdG8gYmUgcmVnaXN0ZXJlZCBoZXJlIGFuZCB0aHJvd24gYXdheTogYW4gZW1wdHlcbiAgICogYHJvd0RhdGFDaGFuZ2VkYCBoYW5kbGVyIHdob3NlIHVuc3Vic2NyaWJlIHdhcyBuZXZlciBrZXB0LCBhbmQgYW5cbiAgICogYGV4cGFuZGVkQ2hhbmdlZGAgaGFuZGxlciB3aG9zZSBib2R5IHdhcyBlbnRpcmVseSBjb21tZW50ZWQgb3V0LiBCb3RoIGFyZVxuICAgKiBnb25lIOKAlCBhIGxpc3RlbmVyIHdpdGggbm8gYmVoYXZpb3VyIGlzIGEgbGVhayB3aXRoIG5vIHVwc2lkZS5cbiAgICovXG4gIHByaXZhdGUgc3Vic2NyaWJlVG9EZXRhaWxDaGFuZ2VzKG5vZGU6IE9uZVJvd05vZGUpOiB2b2lkIHtcblxuICAgIGNvbnN0IHVuc3Vic2NyaWJlRGV0YWlsID0gbm9kZS5vbignZGV0YWlsUm93RGF0YUNoYW5nZWQnLCAoeyBub2RlIH0pID0+IHtcblxuICAgICAgaWYgKHRoaXMuX2FwaVR5cGUgPT09ICdtYXN0ZXInKSB7XG5cbiAgICAgICAgdGhpcy5yZXNvbHZlRGV0YWlsUm93SGVpZ2h0KG5vZGUpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy5yZWdpc3Rlck5vZGVDbGVhbnVwKG5vZGUucm93SWQsIFt1bnN1YnNjcmliZURldGFpbF0pO1xuICB9XG5cbiAgcHJpdmF0ZSByZWdpc3Rlck5vZGVDbGVhbnVwKHJvd0lkOiBzdHJpbmcsIHVuc3ViczogQXJyYXk8KCkgPT4gdm9pZD4pOiB2b2lkIHtcblxuICAgIC8vIE1lcmdlIHdpdGggYW55IGV4aXN0aW5nIGNsZWFudXBzIGZvciB0aGlzIHJvd0lkXG4gICAgY29uc3QgZXhpc3RpbmcgPSB0aGlzLl9ub2RlQ2xlYW51cE1hcC5nZXQocm93SWQpID8/IFtdO1xuXG4gICAgdGhpcy5fbm9kZUNsZWFudXBNYXAuc2V0KHJvd0lkLCBbLi4uZXhpc3RpbmcsIC4uLnVuc3Vic10pO1xuICB9XG5cbiAgcHJpdmF0ZSBjbGVhbnVwTm9kZShyb3dJZDogc3RyaW5nKTogdm9pZCB7XG5cbiAgICBjb25zdCBjbGVhbnVwcyA9IHRoaXMuX25vZGVDbGVhbnVwTWFwLmdldChyb3dJZCk7XG5cbiAgICBjbGVhbnVwcz8uZm9yRWFjaChmbiA9PiBmbigpKTtcblxuICAgIHRoaXMuX25vZGVDbGVhbnVwTWFwLmRlbGV0ZShyb3dJZCk7XG4gIH1cblxuICAvKipcbiAgICogRHJvcCBub2RlcyB0aGF0IGFyZSBubyBsb25nZXIgaW4gdGhlIGRhdGEsIHJlbGVhc2luZyB3aGF0IHRoZXkgaG9sZC5cbiAgICpcbiAgICogVGhpcyBleGlzdGVkIGJ1dCB3YXMgbmV2ZXIgY2FsbGVkOiBgc2V0Um93RGF0YWAgYW5kIGB1cGRhdGVSb3dEYXRhYCBlYWNoXG4gICAqIGRlbGV0ZWQgc3RyYWlnaHQgb3V0IG9mIGBfb3JpZ2luYWxSb3dOb2Rlc2AsIHNvIGEgcmVtb3ZlZCBub2RlIGtlcHQgaXRzXG4gICAqIGxpc3RlbmVycyBhbmQgaXRzIGVudHJ5IGluIGBfbm9kZUNsZWFudXBNYXBgIGZvciB0aGUgbGlmZXRpbWUgb2YgdGhlIGdyaWQuXG4gICAqIEJvdGggbm93IGNvbWUgdGhyb3VnaCBoZXJlLCB3aGljaCB1bnN1YnNjcmliZXMgYW5kIGNsZWFycyB0aGUgbm9kZSBmaXJzdC5cbiAgICovXG4gIHByaXZhdGUgcHJ1bmVSZW1vdmVkTm9kZXModmFsaWRSb3dJZHM6IFNldDxzdHJpbmc+KTogdm9pZCB7XG5cbiAgICBmb3IgKGNvbnN0IFtyb3dJZCwgbm9kZV0gb2YgdGhpcy5fb3JpZ2luYWxSb3dOb2Rlcykge1xuXG4gICAgICBpZiAoIXZhbGlkUm93SWRzLmhhcyhyb3dJZCkpIHtcblxuICAgICAgICB0aGlzLmNsZWFudXBOb2RlKHJvd0lkKTsgIC8vIHVuc3Vic2NyaWJlIGxpc3RlbmVyc1xuXG4gICAgICAgIG5vZGUuZGVzdHJveSgpOyAgICAgICAgICAgLy8gY2xlYXIgbm9kZSdzIG93biBsaXN0ZW5lciBtYXBcblxuICAgICAgICB0aGlzLl9vcmlnaW5hbFJvd05vZGVzLmRlbGV0ZShyb3dJZCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEhlaWdodCBhIG1hc3RlciByb3cgbXVzdCByZXNlcnZlIGZvciBpdHMgZGV0YWlsIGdyaWQ6XG4gICAqIHJvd0hlaWdodCB4IGNsYW1wKHJvd3MsIG1pblJvd3MsIG1heFJvd3MpICsgaGVhZGVySGVpZ2h0LlxuICAgKi9cbiAgcHJpdmF0ZSByZXNvbHZlRGV0YWlsUm93SGVpZ2h0KG5vZGU6IE9uZVJvd05vZGUpOiB2b2lkIHtcblxuICAgIGNvbnN0IGhlaWdodE9wdGlvbnMgPSB0aGlzLmRldGFpbENlbGxSZW5kZXJlclBhcmFtcz8uZGV0YWlsR3JpZE9wdGlvbnM/LmRldGFpbFJvd0hlaWdodE9wdGlvbnM7XG5cbiAgICAvLyBSZWFjaGFibGUgd2hlbmV2ZXIgbWFzdGVyRGV0YWlsIGlzIG9uIGJ1dCBkZXRhaWxDZWxsUmVuZGVyZXJQYXJhbXMgaXNcbiAgICAvLyBpbmNvbXBsZXRlOyB3aXRob3V0IHRoZSBndWFyZCB0aGlzIHRocmV3IGZyb20gaW5zaWRlIGFuIGV2ZW50IGxpc3RlbmVyLlxuICAgIGlmICghaGVpZ2h0T3B0aW9ucykgcmV0dXJuO1xuXG4gICAgY29uc3QgbWluUm93cyA9IGhlaWdodE9wdGlvbnMubWluUm93cztcbiAgICBjb25zdCBtYXhSb3dzID0gaGVpZ2h0T3B0aW9ucy5tYXhSb3dzO1xuXG4gICAgY29uc3QgbWluSGVpZ2h0ID0gKHRoaXMucm93SGVpZ2h0ICogbWluUm93cykgKyB0aGlzLmhlYWRlclJvd0hlaWdodDtcbiAgICBjb25zdCBtYXhIZWlnaHQgPSAodGhpcy5yb3dIZWlnaHQgKiBtYXhSb3dzKSArIHRoaXMuaGVhZGVyUm93SGVpZ2h0O1xuXG4gICAgY29uc3Qgcm93cyA9IG5vZGUuZGV0YWlsUm93RGF0YSAmJiBub2RlLmRldGFpbFJvd0RhdGEubGVuZ3RoID8gbm9kZS5kZXRhaWxSb3dEYXRhLmxlbmd0aCA6IDA7XG5cbiAgICBub2RlLmRldGFpbFJvd0hlaWdodCA9IHJvd3MgPD0gbWluUm93cyA/IG1pbkhlaWdodCA6IHJvd3MgPj0gbWF4Um93cyA/IG1heEhlaWdodCA6ICh0aGlzLnJvd0hlaWdodCAqIHJvd3MpICsgdGhpcy5oZWFkZXJSb3dIZWlnaHQ7XG4gIH1cblxuICAvKipcbiAgICogUmVsZWFzZSBldmVyeXRoaW5nIHRoZSBncmlkIGhvbGRzLiBDYWxsZWQgYnkgYE9uZUdyaWRDb21wb25lbnQubmdPbkRlc3Ryb3lgLlxuICAgKlxuICAgKiBUaGUgc2VydmljZXMgYXJlIGRlbGliZXJhdGVseSAqbm90KiBudWxsZWQgb3V0IGFueSBtb3JlLiBUaGV5IGFyZSBpbmplY3RlZCxcbiAgICogQW5ndWxhciBvd25zIHRoZWlyIGxpZmV0aW1lLCBhbmQgbnVsbGluZyB0aGVtIG9ubHkgZ3VhcmFudGVlZCBhXG4gICAqIGBUeXBlRXJyb3JgIGZvciBhbnkgY2FsbGJhY2sgdGhhdCBhcnJpdmVkIGFmdGVyIHRlYXJkb3duIOKAlCBhIGRldGFpbC1yb3dcbiAgICogZmV0Y2ggcmVzb2x2aW5nIGxhdGUsIG9yIHRoZSBib2R5J3MgZGVmZXJyZWQgdXBkYXRlLiBgX2Rlc3Ryb3llZGAgbWFrZXNcbiAgICogdGhvc2UgY2FsbHMgbm8tb3BzIGluc3RlYWQsIHdoaWNoIGlzIHdoYXQgYSB0b3JuLWRvd24gb2JqZWN0IHNob3VsZCBkby5cbiAgICovXG4gIHB1YmxpYyBkZXN0cm95KCk6IHZvaWQge1xuXG4gICAgaWYgKHRoaXMuX2Rlc3Ryb3llZCkgcmV0dXJuO1xuXG4gICAgdGhpcy5fZGVzdHJveWVkID0gdHJ1ZTtcblxuICAgIC8vIFVuc3Vic2NyaWJlIGV2ZXJ5IHBlci1ub2RlIGxpc3RlbmVyIGJlZm9yZSBkcm9wcGluZyB0aGUgbm9kZXMuXG4gICAgZm9yIChjb25zdCByb3dJZCBvZiBBcnJheS5mcm9tKHRoaXMuX25vZGVDbGVhbnVwTWFwLmtleXMoKSkpIHtcblxuICAgICAgdGhpcy5jbGVhbnVwTm9kZShyb3dJZCk7XG4gICAgfVxuXG4gICAgLy8gYGRlc3Ryb3lgIGRyb3BzIHRoZSB0cmVlIGxpbmtzIGFuZCB0aGUgbGlzdGVuZXJzOyB0aGUgQVBJIG5vIGxvbmdlciBoYXNcbiAgICAvLyB0byByZWFjaCBpbiBhbmQgdW5waWNrIGVhY2ggbm9kZSBpdHNlbGYuXG4gICAgdGhpcy5fb3JpZ2luYWxSb3dOb2Rlcy5mb3JFYWNoKG5vZGUgPT4gbm9kZS5kZXN0cm95KCkpO1xuICAgIHRoaXMuX3Jvd05vZGVzLmZvckVhY2gobm9kZSA9PiBub2RlLmRlc3Ryb3koKSk7XG5cbiAgICBmb3IgKGNvbnN0IHNpZGUgb2YgWyd0b3AnLCAnYm90dG9tJ10gYXMgT25lUGlubmVkUm93U2lkZVtdKSB7XG5cbiAgICAgIHRoaXMuX3Bpbm5lZFJvd05vZGVzW3NpZGVdLmZvckVhY2gobm9kZSA9PiBub2RlLmRlc3Ryb3koKSk7XG4gICAgICB0aGlzLl9waW5uZWRSb3dOb2Rlc1tzaWRlXSA9IFtdO1xuICAgIH1cblxuICAgIHRoaXMuX3Jvd05vZGVzID0gW107XG4gICAgdGhpcy5fdmlzaWJsZVJvd05vZGVzID0gW107XG4gICAgdGhpcy5fb3JpZ2luYWxSb3dOb2Rlcy5jbGVhcigpO1xuICAgIHRoaXMuX25vZGVDbGVhbnVwTWFwLmNsZWFyKCk7XG4gICAgdGhpcy5fY3VycmVudEluZGV4ID0gMDtcblxuICAgIC8vIFJlbGVhc2UgdGhlIGJhY2stcmVmZXJlbmNlIHRoZSBjZWxsIHNlcnZpY2UgaG9sZHMsIHNvIGEgdG9ybi1kb3duIGFwaSBpc1xuICAgIC8vIG5vdCBrZXB0IGFsaXZlIGJ5IHRoZSBzZXJ2aWNlIHRoYXQgb3V0bGl2ZXMgdGhpcyBjYWxsLlxuICAgIHRoaXMuY2VsbFNlcnZpY2Uuc2V0R3JpZEFwaShudWxsKTtcblxuICAgIHRoaXMuc2VsZWN0aW9uU2VydmljZS5kZXNlbGVjdEFsbCgpO1xuICAgIHRoaXMuZXhwYW5zaW9uU2VydmljZS5jbGVhcigpO1xuXG4gICAgdGhpcy5fYWN0aXZlRmlsdGVycyA9IFtdO1xuICAgIHRoaXMuX3F1aWNrRmlsdGVyVmFsdWUgPSBudWxsO1xuICAgIHRoaXMuX3NvcnRNb2RlbCA9IFtdO1xuICAgIHRoaXMuX2NvbnRleHQgPSBudWxsO1xuXG4gICAgdGhpcy5tYXN0ZXJEZXRhaWwgPSBmYWxzZTtcbiAgICB0aGlzLnRyZWVEYXRhID0gZmFsc2U7XG4gICAgdGhpcy50cmVlRGF0YUNoaWxkcmVuRmllbGQgPSBudWxsO1xuICAgIHRoaXMuZ3JvdXBEZWZhdWx0RXhwYW5kZWQgPSAwO1xuICAgIHRoaXMuZGV0YWlsQ2VsbFJlbmRlcmVyUGFyYW1zID0gbnVsbDtcbiAgICB0aGlzLmRldGFpbFJlbmRlcmVyQ29tcG9uZW50ID0gbnVsbDtcbiAgICB0aGlzLl9nZXREZXRhaWxSb3dEYXRhID0gbnVsbDtcbiAgfVxuXG4gIC8qKiBXaGV0aGVyIGBkZXN0cm95YCBoYXMgcnVuLiBMYXRlIGNhbGxiYWNrcyBjaGVjayB0aGlzIGJlZm9yZSBkb2luZyB3b3JrLiAqL1xuICBwdWJsaWMgZ2V0IGRlc3Ryb3llZCgpOiBib29sZWFuIHtcblxuICAgIHJldHVybiB0aGlzLl9kZXN0cm95ZWQ7XG4gIH1cbn1cbiJdfQ==