@jax-data-science/sci-image-visualizer 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/index.mjs +7 -1
- package/esm2022/lib/contracts/image.contract.mjs +1 -1
- package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
- package/esm2022/lib/contracts/region-store.contract.mjs +1 -1
- package/esm2022/lib/contracts/section-view.contract.mjs +2 -0
- package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
- package/esm2022/lib/contracts/viz-config.mjs +1 -1
- package/esm2022/lib/geometry/loft.mjs +128 -0
- package/esm2022/lib/geometry/polylabel.mjs +156 -0
- package/esm2022/lib/geometry/reconstruct.mjs +315 -0
- package/esm2022/lib/geometry/reslice-image.mjs +57 -0
- package/esm2022/lib/geometry/section.mjs +215 -0
- package/esm2022/lib/implementations/napari-js/napari-loading-badge.mjs +11 -7
- package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +20 -3
- package/esm2022/lib/implementations/napari-js/napari-region-mesh-pointer.mjs +100 -0
- package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +28 -5
- package/esm2022/lib/implementations/napari-js/napari-scene.mjs +1 -1
- package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +9 -2
- package/esm2022/lib/implementations/napari-js/napari-tool-bridge.mjs +5 -2
- package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +81 -1
- package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +129 -0
- package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +115 -4
- package/esm2022/lib/implementations/napari-js/napari-volume-slice-planes.mjs +103 -0
- package/esm2022/lib/implementations/napari-js/region-overlay/region-svg-renderer.mjs +15 -3
- package/esm2022/lib/implementations/osd/osd-region-overlay-draw.mjs +18 -7
- package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +38 -8
- package/esm2022/lib/implementations/tile-server/tile-protocol.mjs +1 -1
- package/esm2022/lib/models/class-preset.mjs +1 -1
- package/esm2022/lib/models/polygon-factory.mjs +17 -1
- package/esm2022/lib/models/region-geojson.mjs +44 -6
- package/esm2022/lib/models/region.mjs +1 -1
- package/esm2022/lib/region-editor/class-tree/class-tree.component.mjs +156 -0
- package/esm2022/lib/region-editor/class-tree/class-tree.mjs +108 -0
- package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +77 -13
- package/esm2022/lib/region-editor/region-editor.component.mjs +527 -42
- package/esm2022/lib/region-editor/region-metrics.mjs +20 -2
- package/esm2022/lib/region-editor/region-persistence.service.mjs +36 -10
- package/esm2022/lib/region-editor/region-table/region-table.component.mjs +24 -8
- package/esm2022/lib/region-overlay/region-geometry.mjs +3 -3
- package/esm2022/lib/region-overlay/region-source-layer.mjs +378 -0
- package/esm2022/lib/region-overlay/region-style.mjs +97 -0
- package/esm2022/lib/region-source/http-region-source.mjs +104 -0
- package/esm2022/lib/region-source/region-source-ops.mjs +53 -0
- package/esm2022/lib/region-source/region-source-worker.mjs +10 -0
- package/esm2022/lib/region-source/region-source.mjs +67 -0
- package/esm2022/lib/region-source/region-tiles.mjs +708 -0
- package/esm2022/lib/region-source/worker-region-source.mjs +229 -0
- package/esm2022/lib/routing-visualizer.service.mjs +418 -22
- package/esm2022/lib/section-pane/section-pane.component.mjs +299 -0
- package/esm2022/lib/store/class-color.util.mjs +10 -5
- package/esm2022/lib/store/class-signatures.mjs +63 -0
- package/esm2022/lib/store/region-scope-cache.mjs +5 -1
- package/esm2022/lib/store/region-source-scope.mjs +171 -0
- package/esm2022/lib/store/region-store.service.mjs +724 -12
- package/esm2022/lib/store/visualizer-store.service.mjs +33 -6
- package/esm2022/lib/toolbar/region-tools/region-tools.component.mjs +8 -2
- package/esm2022/lib/toolbar/stack-controls/stack-controls.component.mjs +55 -15
- package/esm2022/lib/toolbar/toolbar.component.mjs +19 -5
- package/esm2022/lib/visualizer/region-load.mjs +67 -4
- package/esm2022/lib/visualizer/volume-sections.mjs +175 -0
- package/esm2022/lib/visualizer.component.mjs +128 -6
- package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BKQhpbHv.mjs} +7239 -1153
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BKQhpbHv.mjs.map +1 -0
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs} +4 -4
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs.map} +1 -1
- package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs +12 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +3 -3
- package/fesm2022/region-source.worker.js +1067 -0
- package/index.d.ts +6 -0
- package/lib/contracts/image.contract.d.ts +4 -0
- package/lib/contracts/region-editor-api.contract.d.ts +84 -0
- package/lib/contracts/region-store.contract.d.ts +22 -0
- package/lib/contracts/section-view.contract.d.ts +44 -0
- package/lib/contracts/visualizer.contract.d.ts +10 -0
- package/lib/contracts/viz-config.d.ts +8 -0
- package/lib/geometry/loft.d.ts +22 -0
- package/lib/geometry/polylabel.d.ts +23 -0
- package/lib/geometry/reconstruct.d.ts +54 -0
- package/lib/geometry/reslice-image.d.ts +33 -0
- package/lib/geometry/section.d.ts +52 -0
- package/lib/implementations/napari-js/napari-loading-badge.d.ts +4 -2
- package/lib/implementations/napari-js/napari-loading-state.d.ts +8 -1
- package/lib/implementations/napari-js/napari-region-mesh-pointer.d.ts +32 -0
- package/lib/implementations/napari-js/napari-region-overlay.d.ts +6 -1
- package/lib/implementations/napari-js/napari-scene.d.ts +33 -0
- package/lib/implementations/napari-js/napari-spatial-hover.d.ts +3 -1
- package/lib/implementations/napari-js/napari-visualizer.service.d.ts +48 -0
- package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +66 -0
- package/lib/implementations/napari-js/napari-volume-scene.d.ts +45 -1
- package/lib/implementations/napari-js/napari-volume-slice-planes.d.ts +43 -0
- package/lib/implementations/osd/osd-region-overlay-draw.d.ts +4 -3
- package/lib/implementations/osd/osd-region-overlay.d.ts +10 -3
- package/lib/implementations/tile-server/tile-protocol.d.ts +3 -0
- package/lib/models/class-preset.d.ts +7 -0
- package/lib/models/polygon-factory.d.ts +5 -0
- package/lib/models/region-geojson.d.ts +40 -0
- package/lib/models/region.d.ts +19 -0
- package/lib/region-editor/class-tree/class-tree.component.d.ts +78 -0
- package/lib/region-editor/class-tree/class-tree.d.ts +31 -0
- package/lib/region-editor/classes-panel/classes-panel.component.d.ts +36 -6
- package/lib/region-editor/region-editor.component.d.ts +133 -17
- package/lib/region-editor/region-metrics.d.ts +8 -0
- package/lib/region-editor/region-persistence.service.d.ts +12 -4
- package/lib/region-editor/region-table/region-table.component.d.ts +10 -4
- package/lib/region-overlay/region-geometry.d.ts +4 -3
- package/lib/region-overlay/region-source-layer.d.ts +96 -0
- package/lib/region-overlay/region-style.d.ts +52 -0
- package/lib/region-source/http-region-source.d.ts +45 -0
- package/lib/region-source/region-source-ops.d.ts +89 -0
- package/lib/region-source/region-source-worker.d.ts +7 -0
- package/lib/region-source/region-source.d.ts +82 -0
- package/lib/region-source/region-tiles.d.ts +289 -0
- package/lib/region-source/worker-region-source.d.ts +65 -0
- package/lib/routing-visualizer.service.d.ts +138 -1
- package/lib/section-pane/section-pane.component.d.ts +47 -0
- package/lib/store/class-color.util.d.ts +6 -3
- package/lib/store/class-signatures.d.ts +11 -0
- package/lib/store/region-scope-cache.d.ts +2 -0
- package/lib/store/region-source-scope.d.ts +68 -0
- package/lib/store/region-store.service.d.ts +206 -2
- package/lib/store/visualizer-store.service.d.ts +10 -0
- package/lib/toolbar/region-tools/region-tools.component.d.ts +3 -1
- package/lib/toolbar/stack-controls/stack-controls.component.d.ts +20 -9
- package/lib/toolbar/toolbar.component.d.ts +9 -2
- package/lib/visualizer/region-load.d.ts +23 -4
- package/lib/visualizer/volume-sections.d.ts +64 -0
- package/lib/visualizer.component.d.ts +31 -0
- package/package.json +2 -2
- package/src/lib/assets/slice.svg +23 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs.map +0 -1
|
@@ -1,17 +1,74 @@
|
|
|
1
1
|
import { Injectable } from '@angular/core';
|
|
2
|
-
import { Subject } from 'rxjs';
|
|
2
|
+
import { BehaviorSubject, Subject } from 'rxjs';
|
|
3
3
|
import { Rectangle, Polygon, hydrateBounds } from '../models/region';
|
|
4
|
-
import { downloadGeoJson, regionsFromGeoJson, regionsToGeoJson } from '../models/region-geojson';
|
|
4
|
+
import { downloadGeoJson, featureFromRegion, regionFromGeoJsonFeature, regionsFromGeoJson, regionsToGeoJson, } from '../models/region-geojson';
|
|
5
5
|
import { VisualizerStore } from './visualizer-store.service';
|
|
6
|
-
import { applyPresetColors } from './class-color.util';
|
|
7
|
-
import { cloneBounds, makePolygon, rectToRing, regionPolygons, replaceBounds } from '../models/polygon-factory';
|
|
6
|
+
import { applyPresetColors, colorForLabel, presetKey } from './class-color.util';
|
|
7
|
+
import { cloneBounds, makePolygon, rectToRing, regionPolygons, regionPolylines, replaceBounds, } from '../models/polygon-factory';
|
|
8
|
+
import { outlinesArea } from '../geometry/reconstruct';
|
|
9
|
+
import { reconstructInWorker } from '../region-source/worker-region-source';
|
|
8
10
|
import * as edit from '../models/polygon-edit';
|
|
9
11
|
import { regionsEqual, withRegionPatch, withRegionZ } from '../models/region-clone';
|
|
10
12
|
import { RegionHistory } from './region-history';
|
|
11
13
|
import { RegionSelection } from './region-selection';
|
|
12
14
|
import { RegionScopeCache } from './region-scope-cache';
|
|
15
|
+
import { RegionSourceScope } from './region-source-scope';
|
|
16
|
+
import { DEFAULT_REGION_STYLE } from '../region-overlay/region-style';
|
|
13
17
|
import * as i0 from "@angular/core";
|
|
14
18
|
import * as i1 from "./visualizer-store.service";
|
|
19
|
+
/** Selecting classes takes at most this many region-source features into the regions. */
|
|
20
|
+
export const SELECT_CLASSES_LIMIT = 5000;
|
|
21
|
+
/** Class sets whose region-source outlines are kept for rebuilding their surfaces. */
|
|
22
|
+
const SOURCE_OUTLINE_CACHE_SIZE = 8;
|
|
23
|
+
/** Classes whose region-source part of the volume is kept (see RegionStore.classVolumes). */
|
|
24
|
+
const SOURCE_VOLUME_CACHE_SIZE = 64;
|
|
25
|
+
/**
|
|
26
|
+
* Feature ids unique across outlines read from several places: each call gives one part's
|
|
27
|
+
* renumbering of its own ids (a part without them is one feature).
|
|
28
|
+
*/
|
|
29
|
+
function featureIds() {
|
|
30
|
+
let next = 0;
|
|
31
|
+
return () => {
|
|
32
|
+
const ids = new Map();
|
|
33
|
+
return (own) => {
|
|
34
|
+
let id = ids.get(own);
|
|
35
|
+
if (id === undefined)
|
|
36
|
+
ids.set(own, (id = next++));
|
|
37
|
+
return id;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/** A slice's parts as outlines. */
|
|
42
|
+
function sliceOutlines(z, s) {
|
|
43
|
+
return {
|
|
44
|
+
z,
|
|
45
|
+
rings: s.rings,
|
|
46
|
+
...(s.rings.length ? { ringGroups: s.ringGroups } : {}),
|
|
47
|
+
...(s.lines.length ? { lines: s.lines } : {}),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Outlines by slice merged into one entry per slice (rings, then lines), in slice order, each
|
|
52
|
+
* part's features apart from the others' (they fill as their union).
|
|
53
|
+
*/
|
|
54
|
+
function mergeOutlines(parts) {
|
|
55
|
+
const byZ = new Map();
|
|
56
|
+
const nextPart = featureIds();
|
|
57
|
+
for (const part of parts) {
|
|
58
|
+
if (!part.rings.length && !part.lines?.length)
|
|
59
|
+
continue;
|
|
60
|
+
let slice = byZ.get(part.z);
|
|
61
|
+
if (!slice)
|
|
62
|
+
byZ.set(part.z, (slice = { rings: [], ringGroups: [], lines: [] }));
|
|
63
|
+
const id = nextPart();
|
|
64
|
+
part.rings.forEach((r, i) => {
|
|
65
|
+
slice.rings.push(r);
|
|
66
|
+
slice.ringGroups.push(id(part.ringGroups?.[i]));
|
|
67
|
+
});
|
|
68
|
+
slice.lines.push(...(part.lines ?? []));
|
|
69
|
+
}
|
|
70
|
+
return Array.from(byZ, ([z, s]) => sliceOutlines(z, s)).sort((a, b) => a.z - b.z);
|
|
71
|
+
}
|
|
15
72
|
/**
|
|
16
73
|
* Backend-neutral region store — the single source of truth for region state.
|
|
17
74
|
*
|
|
@@ -85,6 +142,40 @@ export class RegionStore {
|
|
|
85
142
|
/** Emit coalescing for live drags (see IRegionEditApi.beginBatch). */
|
|
86
143
|
this.batchDepth = 0;
|
|
87
144
|
this.pendingEmit = false;
|
|
145
|
+
/**
|
|
146
|
+
* Large region sets held as tiled region sources rather than as regions (see
|
|
147
|
+
* {@link attachRegionSource}): per image and slice, with the ids taken out of each.
|
|
148
|
+
*/
|
|
149
|
+
this.sources = new RegionSourceScope();
|
|
150
|
+
this.sourceView$ = new BehaviorSubject(null);
|
|
151
|
+
/** The region look the user chose (overrides the source's hint), field by field. */
|
|
152
|
+
this.userStyle = {};
|
|
153
|
+
this.regionStyle$ = new BehaviorSubject(DEFAULT_REGION_STYLE);
|
|
154
|
+
/** Bumped on every change of the slice's source, so a late open is dropped. */
|
|
155
|
+
this.sourceGeneration = 0;
|
|
156
|
+
/** The source last published as the view: a source shown again does not turn the labels back on. */
|
|
157
|
+
this.shownSource = null;
|
|
158
|
+
/** Bumped when a region source is attached or dropped: what is read from the sources is stale. */
|
|
159
|
+
this.sourcesVersion = 0;
|
|
160
|
+
/**
|
|
161
|
+
* The region sources' part of {@link classVolumes}, by class and what the sources hold (see
|
|
162
|
+
* {@link sourceStateKey}): an edit of the regions leaves it, so the volumes of a slice being drawn
|
|
163
|
+
* on cost no source reads.
|
|
164
|
+
*/
|
|
165
|
+
this.sourceVolumeCache = new Map();
|
|
166
|
+
/** The region sources' outlines of the class sets reconstructed last (see {@link sourceOutlines}). */
|
|
167
|
+
this.sourceOutlineCache = new Map();
|
|
168
|
+
/** The classes hidden from view (names as given); every class is shown at first. */
|
|
169
|
+
this.hiddenClasses$ = new BehaviorSubject(new Set());
|
|
170
|
+
/** {@link hiddenClasses$} by {@link presetKey}, as a region's label is matched. */
|
|
171
|
+
this.hiddenKeys = new Set();
|
|
172
|
+
this.coveredFor = null;
|
|
173
|
+
// A class colour change recolours the source's features as it recolours regions.
|
|
174
|
+
this.store.getPresetSet$().subscribe(() => {
|
|
175
|
+
const view = this.sourceView$.value;
|
|
176
|
+
if (view)
|
|
177
|
+
this.sourceView$.next({ ...view });
|
|
178
|
+
});
|
|
88
179
|
}
|
|
89
180
|
// ── IRegionStore: CRUD ─────────────────────────────────────────────────
|
|
90
181
|
/**
|
|
@@ -104,7 +195,10 @@ export class RegionStore {
|
|
|
104
195
|
this.isRegionSavedOn = isRegionSaveOn;
|
|
105
196
|
if (isRegionSaveOn) {
|
|
106
197
|
this.recordUndoSnapshot();
|
|
107
|
-
this.showShapeLabel
|
|
198
|
+
if (this.showShapeLabel !== showRegionLabel) {
|
|
199
|
+
this.showShapeLabel = showRegionLabel;
|
|
200
|
+
this.republishView();
|
|
201
|
+
}
|
|
108
202
|
this.fillColor = fillColor;
|
|
109
203
|
if (append) {
|
|
110
204
|
// Reject by id collision (already tracked) or geometry equality (same
|
|
@@ -169,10 +263,12 @@ export class RegionStore {
|
|
|
169
263
|
this.resetUndoHistory();
|
|
170
264
|
this.emitSelection();
|
|
171
265
|
this.emit();
|
|
266
|
+
this.refreshSourceView();
|
|
172
267
|
}
|
|
173
268
|
/** Leave stack mode (single-plane image, or the stack was closed). */
|
|
174
269
|
exitStackMode() {
|
|
175
270
|
this.scope.exitStack();
|
|
271
|
+
this.refreshSourceView();
|
|
176
272
|
}
|
|
177
273
|
/** The live-set swap of {@link setDisplaySlice}. */
|
|
178
274
|
showSlice(z) {
|
|
@@ -185,6 +281,7 @@ export class RegionStore {
|
|
|
185
281
|
this.resetUndoHistory();
|
|
186
282
|
this.emitSelection();
|
|
187
283
|
this.emit();
|
|
284
|
+
this.refreshSourceView();
|
|
188
285
|
}
|
|
189
286
|
/**
|
|
190
287
|
* Show a different slice: capture the current slice's (possibly edited)
|
|
@@ -216,7 +313,14 @@ export class RegionStore {
|
|
|
216
313
|
* the current live slice is captured first. Empty outside stack mode.
|
|
217
314
|
*/
|
|
218
315
|
getStackSaveSlices() {
|
|
219
|
-
|
|
316
|
+
const slices = this.scope.stackSaveSlices(this.regions);
|
|
317
|
+
// A slice whose region source lost features (taken, deleted) is re-written too.
|
|
318
|
+
const changed = this.sources.slicesWithTaken(this.scope.activeImage).filter((z) => !slices.has(z));
|
|
319
|
+
if (!changed.length)
|
|
320
|
+
return slices;
|
|
321
|
+
for (const z of changed)
|
|
322
|
+
slices.set(z, []);
|
|
323
|
+
return new Map(Array.from(slices).sort((a, b) => a[0] - b[0]));
|
|
220
324
|
}
|
|
221
325
|
/** Mint ids/names + apply classification colours + tag the slice index, as
|
|
222
326
|
* {@link setRegions} does, for regions entering the per-slice store. */
|
|
@@ -328,6 +432,7 @@ export class RegionStore {
|
|
|
328
432
|
* @deprecated Nothing in the library calls it; will be removed next minor. */
|
|
329
433
|
setShowShapeLabel(show) {
|
|
330
434
|
this.showShapeLabel = show;
|
|
435
|
+
this.republishView();
|
|
331
436
|
}
|
|
332
437
|
getClassificationColors() {
|
|
333
438
|
return this.store.getClassificationColors();
|
|
@@ -364,7 +469,7 @@ export class RegionStore {
|
|
|
364
469
|
* nothing is left to undo.
|
|
365
470
|
*/
|
|
366
471
|
undo() {
|
|
367
|
-
const snapshot = this.history.undo(this.
|
|
472
|
+
const snapshot = this.history.undo(this.snapshot());
|
|
368
473
|
if (snapshot)
|
|
369
474
|
this.restoreSnapshot(snapshot);
|
|
370
475
|
this.regionSetReplaced$.next();
|
|
@@ -376,7 +481,7 @@ export class RegionStore {
|
|
|
376
481
|
* fresh region action).
|
|
377
482
|
*/
|
|
378
483
|
redo() {
|
|
379
|
-
const snapshot = this.history.redo(this.
|
|
484
|
+
const snapshot = this.history.redo(this.snapshot());
|
|
380
485
|
if (snapshot)
|
|
381
486
|
this.restoreSnapshot(snapshot);
|
|
382
487
|
this.regionSetReplaced$.next();
|
|
@@ -390,7 +495,8 @@ export class RegionStore {
|
|
|
390
495
|
* {@link undo} and {@link redo}; nothing records history while it runs. */
|
|
391
496
|
restoreSnapshot(snapshot) {
|
|
392
497
|
this.history.restore(() => {
|
|
393
|
-
this.regions = snapshot.slice();
|
|
498
|
+
this.regions = snapshot.regions.slice();
|
|
499
|
+
this.setTaken(snapshot.taken);
|
|
394
500
|
this.syncCache();
|
|
395
501
|
// Drops any selected ids the restored set no longer contains.
|
|
396
502
|
this.emitSelection();
|
|
@@ -407,11 +513,25 @@ export class RegionStore {
|
|
|
407
513
|
* region it edits) rather than changing them, so it never changes after this.
|
|
408
514
|
*/
|
|
409
515
|
recordUndoSnapshot() {
|
|
410
|
-
this.history.record(this.
|
|
516
|
+
this.history.record(this.snapshot());
|
|
517
|
+
}
|
|
518
|
+
/** The state an undo step restores. */
|
|
519
|
+
snapshot() {
|
|
520
|
+
return { regions: this.regions, taken: this.currentTaken() };
|
|
411
521
|
}
|
|
412
522
|
// ── IRegionStore: GeoJSON I/O (models/region-geojson) ──────────────────
|
|
523
|
+
/** Parse GeoJSON into regions, remembering the class colours the file carries so they are
|
|
524
|
+
* kept for classes with no preset (see VisualizerStore.rememberImportedClassColors). */
|
|
413
525
|
importRegions(geoJsonStr) {
|
|
414
|
-
|
|
526
|
+
const regions = regionsFromGeoJson(geoJsonStr);
|
|
527
|
+
const colors = new Map();
|
|
528
|
+
for (const r of regions) {
|
|
529
|
+
if (r.label && r.color && !colors.has(r.label))
|
|
530
|
+
colors.set(r.label, r.color);
|
|
531
|
+
}
|
|
532
|
+
if (colors.size)
|
|
533
|
+
this.store.rememberImportedClassColors(colors);
|
|
534
|
+
return regions;
|
|
415
535
|
}
|
|
416
536
|
/** Download `regions` as GeoJSON, named after `fileName` (extension
|
|
417
537
|
* replaced by `.geojson`) or `rois.geojson` without one. */
|
|
@@ -576,6 +696,597 @@ export class RegionStore {
|
|
|
576
696
|
endGesture() {
|
|
577
697
|
this.history.endGesture();
|
|
578
698
|
}
|
|
699
|
+
// ── Region sources: large region sets, tiled by level of detail ─────────
|
|
700
|
+
/**
|
|
701
|
+
* Hold a large region set as a tiled region source instead of as regions: the backends that
|
|
702
|
+
* draw sources (OpenSeadragon, napari) draw its features at the detail the zoom shows, from
|
|
703
|
+
* the tiles in view, and a feature joins the regions — exactly, as an ordinary editable
|
|
704
|
+
* {@link Region} with its {@link Region.sourceId} — only when it is selected or edited
|
|
705
|
+
* ({@link takeSourceFeatures}). Until then {@link getRegions} does not include it.
|
|
706
|
+
*
|
|
707
|
+
* `source` may be an opener, called the first time its slice is shown (and again if the
|
|
708
|
+
* source was closed to save memory). `slices` says which slice of the current image it
|
|
709
|
+
* serves: one (default: the slice shown; plane 0 of the source), or `'planes'`, every slice z
|
|
710
|
+
* from plane z of a z-indexed source. Replaces the source those slices had.
|
|
711
|
+
*/
|
|
712
|
+
attachRegionSource(source, slices = { slice: this.sourceSlice }) {
|
|
713
|
+
const image = this.scope.activeImage;
|
|
714
|
+
if (!image)
|
|
715
|
+
return;
|
|
716
|
+
const open = typeof source === 'function' ? source : () => Promise.resolve(source);
|
|
717
|
+
this.sources.attach(image, open, slices);
|
|
718
|
+
this.sourcesVersion++;
|
|
719
|
+
this.refreshSourceView();
|
|
720
|
+
}
|
|
721
|
+
/** Drop the current image's region sources (closing them) and what was taken from them. */
|
|
722
|
+
detachRegionSources() {
|
|
723
|
+
const image = this.scope.activeImage;
|
|
724
|
+
if (!image)
|
|
725
|
+
return;
|
|
726
|
+
this.sources.detachImage(image);
|
|
727
|
+
this.sourcesVersion++;
|
|
728
|
+
this.refreshSourceView();
|
|
729
|
+
}
|
|
730
|
+
/**
|
|
731
|
+
* Drop the slice's region source, for regions imported in place of the slice's (a small file
|
|
732
|
+
* replacing a large one): a source of the slice's own is detached; a z-indexed source over every
|
|
733
|
+
* slice has this slice's features taken out (as deleted). The other slices keep theirs.
|
|
734
|
+
*/
|
|
735
|
+
async dropSliceRegionSource() {
|
|
736
|
+
const image = this.scope.activeImage;
|
|
737
|
+
const slice = this.sourceSlice;
|
|
738
|
+
if (!image || !this.sources.has(image, slice))
|
|
739
|
+
return;
|
|
740
|
+
if (this.sources.hasOwnSource(image, slice)) {
|
|
741
|
+
this.sources.detachSlice(image, slice);
|
|
742
|
+
this.sourcesVersion++;
|
|
743
|
+
this.refreshSourceView();
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
746
|
+
const generation = this.sourceGeneration;
|
|
747
|
+
const binding = await this.sources.binding(image, slice);
|
|
748
|
+
if (!binding || generation !== this.sourceGeneration)
|
|
749
|
+
return;
|
|
750
|
+
const all = await binding.source.getIndex(binding.plane, {
|
|
751
|
+
offset: 0,
|
|
752
|
+
limit: binding.source.info.featureCount,
|
|
753
|
+
});
|
|
754
|
+
if (generation !== this.sourceGeneration)
|
|
755
|
+
return;
|
|
756
|
+
this.setTaken(new Set([...this.currentTaken(), ...all.rows.map((r) => r.id)]));
|
|
757
|
+
}
|
|
758
|
+
/** Whether the slice shown has a region source. */
|
|
759
|
+
hasRegionSource() {
|
|
760
|
+
return this.sources.has(this.scope.activeImage, this.sourceSlice);
|
|
761
|
+
}
|
|
762
|
+
/** The slice's region source as a source layer draws it; null without one (or until it opens). */
|
|
763
|
+
getRegionSourceView() {
|
|
764
|
+
return this.sourceView$.value;
|
|
765
|
+
}
|
|
766
|
+
/** {@link getRegionSourceView} and every change of it (slice, taken ids, class colours). */
|
|
767
|
+
getRegionSourceView$() {
|
|
768
|
+
return this.sourceView$.asObservable();
|
|
769
|
+
}
|
|
770
|
+
/**
|
|
771
|
+
* Take source features into the working set for editing: their exact geometry becomes
|
|
772
|
+
* ordinary regions (minted, coloured and slice-tagged as any region entering the store) and
|
|
773
|
+
* the source stops drawing them. Not an undo step of its own — undoing past it puts the
|
|
774
|
+
* features back in the source. Resolves the region ids, in the order asked (a feature already
|
|
775
|
+
* taken resolves to its region); [] when the slice changed meanwhile.
|
|
776
|
+
*/
|
|
777
|
+
async takeSourceFeatures(ids) {
|
|
778
|
+
const view = this.sourceView$.value;
|
|
779
|
+
if (!view || !ids.length)
|
|
780
|
+
return [];
|
|
781
|
+
const generation = this.sourceGeneration;
|
|
782
|
+
const wanted = ids.filter((id) => !view.taken.has(id));
|
|
783
|
+
const features = wanted.length ? await view.source.getFeatures(wanted) : [];
|
|
784
|
+
if (generation !== this.sourceGeneration)
|
|
785
|
+
return [];
|
|
786
|
+
const taken = this.currentTaken();
|
|
787
|
+
const fresh = features.filter((f) => !taken.has(f.id));
|
|
788
|
+
if (fresh.length) {
|
|
789
|
+
const regions = fresh.map((f) => {
|
|
790
|
+
const region = regionFromGeoJsonFeature(f.feature, 0, f.id);
|
|
791
|
+
if (this.scope.stackMode)
|
|
792
|
+
region.z = this.scope.displaySlice;
|
|
793
|
+
return region;
|
|
794
|
+
});
|
|
795
|
+
const admitted = this.admit(regions);
|
|
796
|
+
// Fresh instances, completed in place: named after their new id like a drawn region.
|
|
797
|
+
for (const r of admitted)
|
|
798
|
+
r.name = `shape${r.id}`;
|
|
799
|
+
this.regions = this.regions.concat(admitted);
|
|
800
|
+
this.setTaken(new Set([...taken, ...fresh.map((f) => f.id)]));
|
|
801
|
+
this.syncCache();
|
|
802
|
+
this.emitSelection();
|
|
803
|
+
this.emit();
|
|
804
|
+
}
|
|
805
|
+
const bySource = new Map(this.regions.filter((r) => r.sourceId !== undefined).map((r) => [r.sourceId, r.id]));
|
|
806
|
+
return ids.map((id) => bySource.get(id)).filter((id) => id !== undefined);
|
|
807
|
+
}
|
|
808
|
+
/** {@link takeSourceFeatures}, then select them (added to the selection with `additive`). */
|
|
809
|
+
async selectSourceFeatures(ids, additive = false) {
|
|
810
|
+
const taken = await this.takeSourceFeatures(ids);
|
|
811
|
+
if (!taken.length)
|
|
812
|
+
return taken;
|
|
813
|
+
this.selection.replace(additive ? [...new Set([...this.selection.ids, ...taken])] : taken);
|
|
814
|
+
this.emitSelection();
|
|
815
|
+
return taken;
|
|
816
|
+
}
|
|
817
|
+
/**
|
|
818
|
+
* Features per class still in the slice's region source (not taken); {} without one. With
|
|
819
|
+
* `stack`, a z-stack's over every slice: its source's planes, or each slice's source added up.
|
|
820
|
+
*/
|
|
821
|
+
async getRegionSourceClassCounts(stack = false) {
|
|
822
|
+
const view = this.sourceView$.value;
|
|
823
|
+
const image = this.scope.activeImage;
|
|
824
|
+
if (!stack || !this.scope.stackMode) {
|
|
825
|
+
return view ? view.source.getClassCounts(view.plane, Array.from(view.taken)) : {};
|
|
826
|
+
}
|
|
827
|
+
if (this.sources.hasPlanesSource(image)) {
|
|
828
|
+
const binding = await this.sources.binding(image, this.sourceSlice);
|
|
829
|
+
if (!binding)
|
|
830
|
+
return {};
|
|
831
|
+
try {
|
|
832
|
+
return await binding.source.getClassCounts(null, this.sources.allTaken(image));
|
|
833
|
+
}
|
|
834
|
+
catch (err) {
|
|
835
|
+
// A tile server that predates counting every plane: the slice's counts.
|
|
836
|
+
console.warn('[regions] could not count the classes of every slice', err);
|
|
837
|
+
return view ? view.source.getClassCounts(view.plane, Array.from(view.taken)) : {};
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
const counts = {};
|
|
841
|
+
for (const slice of this.sources.slicesWithSource(image)) {
|
|
842
|
+
const binding = await this.sources.binding(image, slice);
|
|
843
|
+
if (!binding)
|
|
844
|
+
continue;
|
|
845
|
+
const own = await binding.source.getClassCounts(binding.plane, Array.from(this.sources.taken(image, slice)));
|
|
846
|
+
for (const [label, n] of Object.entries(own))
|
|
847
|
+
counts[label] = (counts[label] ?? 0) + n;
|
|
848
|
+
}
|
|
849
|
+
return counts;
|
|
850
|
+
}
|
|
851
|
+
/**
|
|
852
|
+
* Select every region of these classes on the slice — the regions', and the region source's,
|
|
853
|
+
* which are taken into the regions (at most {@link SELECT_CLASSES_LIMIT} of them). Added to the
|
|
854
|
+
* selection with `additive`. Resolves the selected region ids.
|
|
855
|
+
*/
|
|
856
|
+
async selectClasses(classes, additive = false) {
|
|
857
|
+
const wanted = new Set(classes);
|
|
858
|
+
const view = this.sourceView$.value;
|
|
859
|
+
if (view && classes.length) {
|
|
860
|
+
const page = await view.source.getIndex(view.plane, {
|
|
861
|
+
offset: 0,
|
|
862
|
+
limit: SELECT_CLASSES_LIMIT,
|
|
863
|
+
classes,
|
|
864
|
+
exclude: Array.from(view.taken),
|
|
865
|
+
});
|
|
866
|
+
if (page.rows.length)
|
|
867
|
+
await this.takeSourceFeatures(page.rows.map((r) => r.id));
|
|
868
|
+
}
|
|
869
|
+
const ids = this.regions.filter((r) => !r.isProfile?.() && r.label && wanted.has(r.label)).map((r) => r.id);
|
|
870
|
+
this.selection.replace(additive ? [...new Set([...this.selection.ids, ...ids])] : ids);
|
|
871
|
+
this.emitSelection();
|
|
872
|
+
return ids;
|
|
873
|
+
}
|
|
874
|
+
/**
|
|
875
|
+
* The 3D reconstruction of each group of classes over every slice of the stack (an atlas
|
|
876
|
+
* structure with its substructures, say): the outlines of the regions of those classes on every
|
|
877
|
+
* slice — the region sources' and those drawn or taken — stacked and meshed in a worker. Meshes
|
|
878
|
+
* are in image px (x, y) and slice indices (z). `pixelStep` is the in-plane voxel size (image
|
|
879
|
+
* px); the outlines are read at the matching level of detail. A group with no outline gets an
|
|
880
|
+
* empty mesh.
|
|
881
|
+
*/
|
|
882
|
+
async reconstructClasses(groups, pixelStep = 1) {
|
|
883
|
+
const level = Math.max(0, Math.floor(Math.log2(Math.max(1, pixelStep))));
|
|
884
|
+
const out = [];
|
|
885
|
+
for (const group of groups) {
|
|
886
|
+
const slices = await this.classOutlines(group.classes, level);
|
|
887
|
+
out.push({ key: group.key, mesh: await reconstructInWorker(slices, { pixelStep }) });
|
|
888
|
+
}
|
|
889
|
+
return out;
|
|
890
|
+
}
|
|
891
|
+
/**
|
|
892
|
+
* Each class's volume over the whole stack, in px² × slices: its outlines' area on every slice
|
|
893
|
+
* (its features' union, see `outlinesArea`), one slice thick (Cavalieri's estimator), from the
|
|
894
|
+
* exact outlines. Where a feature is, a region source's or a drawn or taken region, does not
|
|
895
|
+
* change it: taking one leaves the volume as it was. The region sources' part is cached until
|
|
896
|
+
* what they hold changes (a feature taken or deleted, another source); only the slices with
|
|
897
|
+
* drawn or taken regions of the class are measured again.
|
|
898
|
+
*/
|
|
899
|
+
async classVolumes(classes) {
|
|
900
|
+
const state = this.sourceStateKey();
|
|
901
|
+
const out = new Map();
|
|
902
|
+
await Promise.all([...new Set(classes)].map(async (name) => {
|
|
903
|
+
const source = await this.sourceVolume(state, name);
|
|
904
|
+
let volume = source.total;
|
|
905
|
+
for (const regions of mergeOutlines(this.regionOutlines([name]))) {
|
|
906
|
+
const under = source.slices.get(regions.z);
|
|
907
|
+
const [both] = under ? mergeOutlines([under.outlines, regions]) : [regions];
|
|
908
|
+
volume += outlinesArea(both.rings, both.ringGroups) - (under?.area ?? 0);
|
|
909
|
+
}
|
|
910
|
+
out.set(name, volume);
|
|
911
|
+
}));
|
|
912
|
+
return out;
|
|
913
|
+
}
|
|
914
|
+
/** The region sources' part of a class's volume, cached by what they hold (see classVolumes). */
|
|
915
|
+
sourceVolume(state, name) {
|
|
916
|
+
const key = `${state}\n${name}`;
|
|
917
|
+
let source = this.sourceVolumeCache.get(key);
|
|
918
|
+
if (source) {
|
|
919
|
+
// Most recently used last.
|
|
920
|
+
this.sourceVolumeCache.delete(key);
|
|
921
|
+
this.sourceVolumeCache.set(key, source);
|
|
922
|
+
return source;
|
|
923
|
+
}
|
|
924
|
+
source = this.sourceOutlines([name], 0).then((parts) => {
|
|
925
|
+
const slices = new Map();
|
|
926
|
+
let total = 0;
|
|
927
|
+
for (const outlines of mergeOutlines(parts)) {
|
|
928
|
+
const area = outlinesArea(outlines.rings, outlines.ringGroups);
|
|
929
|
+
slices.set(outlines.z, { area, outlines });
|
|
930
|
+
total += area;
|
|
931
|
+
}
|
|
932
|
+
return { total, slices };
|
|
933
|
+
});
|
|
934
|
+
this.sourceVolumeCache.set(key, source);
|
|
935
|
+
source.catch(() => this.sourceVolumeCache.delete(key));
|
|
936
|
+
while (this.sourceVolumeCache.size > SOURCE_VOLUME_CACHE_SIZE) {
|
|
937
|
+
this.sourceVolumeCache.delete(this.sourceVolumeCache.keys().next().value);
|
|
938
|
+
}
|
|
939
|
+
return source;
|
|
940
|
+
}
|
|
941
|
+
/**
|
|
942
|
+
* Every slice's outlines of these classes, the region sources' then the regions': closed shapes'
|
|
943
|
+
* rings, and open polylines as `lines`.
|
|
944
|
+
*/
|
|
945
|
+
async classOutlines(classes, level) {
|
|
946
|
+
return mergeOutlines([...(await this.sourceOutlines(classes, level)), ...this.regionOutlines(classes)]);
|
|
947
|
+
}
|
|
948
|
+
/**
|
|
949
|
+
* The region sources' outlines of these classes on every slice, without the features taken or
|
|
950
|
+
* deleted. The last few class sets are kept until what the sources hold changes: rebuilding a
|
|
951
|
+
* surface after an edit reads nothing again.
|
|
952
|
+
*/
|
|
953
|
+
sourceOutlines(classes, level) {
|
|
954
|
+
const key = `${this.sourceStateKey()}\n${level}\n${classes ? classes.join('\n') : '*'}`;
|
|
955
|
+
const cached = this.sourceOutlineCache.get(key);
|
|
956
|
+
if (cached) {
|
|
957
|
+
// Most recently used last.
|
|
958
|
+
this.sourceOutlineCache.delete(key);
|
|
959
|
+
this.sourceOutlineCache.set(key, cached);
|
|
960
|
+
return cached;
|
|
961
|
+
}
|
|
962
|
+
const read = this.readSourceOutlines(classes, level);
|
|
963
|
+
this.sourceOutlineCache.set(key, read);
|
|
964
|
+
read.catch(() => this.sourceOutlineCache.delete(key));
|
|
965
|
+
while (this.sourceOutlineCache.size > SOURCE_OUTLINE_CACHE_SIZE) {
|
|
966
|
+
this.sourceOutlineCache.delete(this.sourceOutlineCache.keys().next().value);
|
|
967
|
+
}
|
|
968
|
+
return read;
|
|
969
|
+
}
|
|
970
|
+
async readSourceOutlines(classes, level) {
|
|
971
|
+
const out = [];
|
|
972
|
+
const image = this.scope.activeImage;
|
|
973
|
+
if (this.sources.hasPlanesSource(image)) {
|
|
974
|
+
const binding = await this.sources.binding(image, this.sourceSlice);
|
|
975
|
+
const outlines = await binding?.source.getClassOutlines(classes, level, this.sources.allTaken(image));
|
|
976
|
+
out.push(...(outlines ?? []));
|
|
977
|
+
}
|
|
978
|
+
for (const z of this.sources.slicesWithSource(image)) {
|
|
979
|
+
const binding = await this.sources.binding(image, z);
|
|
980
|
+
if (!binding)
|
|
981
|
+
continue;
|
|
982
|
+
const outlines = await binding.source.getClassOutlines(classes, level, Array.from(this.sources.taken(image, z)));
|
|
983
|
+
for (const s of outlines)
|
|
984
|
+
if (s.z === binding.plane)
|
|
985
|
+
out.push({ ...s, z });
|
|
986
|
+
}
|
|
987
|
+
return out;
|
|
988
|
+
}
|
|
989
|
+
/**
|
|
990
|
+
* Every class's outlines on every slice, by class: the region sources' (one read for all, kept
|
|
991
|
+
* like {@link sourceOutlines}) and the drawn and taken regions'. What a section through the
|
|
992
|
+
* stack cuts (see `geometry/section`).
|
|
993
|
+
*/
|
|
994
|
+
async outlinesByClass(level) {
|
|
995
|
+
const byClass = new Map();
|
|
996
|
+
const slot = (label, z) => {
|
|
997
|
+
let slices = byClass.get(label);
|
|
998
|
+
if (!slices)
|
|
999
|
+
byClass.set(label, (slices = new Map()));
|
|
1000
|
+
let slice = slices.get(z);
|
|
1001
|
+
if (!slice)
|
|
1002
|
+
slices.set(z, (slice = { rings: [], ringGroups: [], lines: [] }));
|
|
1003
|
+
return slice;
|
|
1004
|
+
};
|
|
1005
|
+
const nextPart = featureIds();
|
|
1006
|
+
for (const s of await this.sourceOutlines(null, level)) {
|
|
1007
|
+
const id = nextPart();
|
|
1008
|
+
s.rings.forEach((r, i) => {
|
|
1009
|
+
const label = s.ringLabels?.[i];
|
|
1010
|
+
if (!label)
|
|
1011
|
+
return;
|
|
1012
|
+
const slice = slot(label, s.z);
|
|
1013
|
+
slice.rings.push(r);
|
|
1014
|
+
slice.ringGroups.push(id(s.ringGroups?.[i]));
|
|
1015
|
+
});
|
|
1016
|
+
(s.lines ?? []).forEach((l, i) => {
|
|
1017
|
+
const label = s.lineLabels?.[i];
|
|
1018
|
+
if (label)
|
|
1019
|
+
slot(label, s.z).lines.push(l);
|
|
1020
|
+
});
|
|
1021
|
+
}
|
|
1022
|
+
for (const { label, outlines } of this.labelledRegionOutlines(null)) {
|
|
1023
|
+
// A region is one feature.
|
|
1024
|
+
const id = nextPart()(undefined);
|
|
1025
|
+
const slice = slot(label, outlines.z);
|
|
1026
|
+
slice.rings.push(...outlines.rings);
|
|
1027
|
+
slice.ringGroups.push(...outlines.rings.map(() => id));
|
|
1028
|
+
slice.lines.push(...(outlines.lines ?? []));
|
|
1029
|
+
}
|
|
1030
|
+
return new Map(Array.from(byClass, ([label, slices]) => [label, Array.from(slices, ([z, s]) => sliceOutlines(z, s))]));
|
|
1031
|
+
}
|
|
1032
|
+
/** The drawn and taken regions' outlines of these classes, by slice. */
|
|
1033
|
+
regionOutlines(classes) {
|
|
1034
|
+
return this.labelledRegionOutlines(new Set(classes)).map((o) => o.outlines);
|
|
1035
|
+
}
|
|
1036
|
+
/** Each drawn or taken region's outlines (of the `wanted` classes; null: every class) with its class. */
|
|
1037
|
+
labelledRegionOutlines(wanted) {
|
|
1038
|
+
const out = [];
|
|
1039
|
+
for (const r of this.scope.stackMode ? this.getSliceRegions() : this.regions) {
|
|
1040
|
+
if (r.isProfile?.() || !r.label || (wanted && !wanted.has(r.label)))
|
|
1041
|
+
continue;
|
|
1042
|
+
const rings = [];
|
|
1043
|
+
for (const p of regionPolygons(r)) {
|
|
1044
|
+
rings.push(Float64Array.from(p.xpoints.flatMap((x, i) => [x, p.ypoints[i]])));
|
|
1045
|
+
for (const hole of p.holes ?? [])
|
|
1046
|
+
rings.push(Float64Array.from(hole.flat()));
|
|
1047
|
+
}
|
|
1048
|
+
const lines = regionPolylines(r);
|
|
1049
|
+
out.push({ label: r.label, outlines: { z: r.z ?? 0, rings, ...(lines.length ? { lines } : {}) } });
|
|
1050
|
+
}
|
|
1051
|
+
return out;
|
|
1052
|
+
}
|
|
1053
|
+
/** What the region sources of the image hold (see {@link sourceStateKey}): it changes when a
|
|
1054
|
+
* feature is taken or deleted, or that is undone. */
|
|
1055
|
+
getSourceStateKey() {
|
|
1056
|
+
return this.sourceStateKey();
|
|
1057
|
+
}
|
|
1058
|
+
/**
|
|
1059
|
+
* What the region sources of the image hold: the image, its sources (one attached or dropped
|
|
1060
|
+
* bumps the version) and the features taken from them. A key for what is read from them.
|
|
1061
|
+
*/
|
|
1062
|
+
sourceStateKey() {
|
|
1063
|
+
const image = this.scope.activeImage;
|
|
1064
|
+
let taken = 2166136261;
|
|
1065
|
+
for (const z of this.sources.slicesWithTaken(image)) {
|
|
1066
|
+
for (const id of [...this.sources.taken(image, z)].sort()) {
|
|
1067
|
+
const s = `${z}:${id};`;
|
|
1068
|
+
for (let i = 0; i < s.length; i++)
|
|
1069
|
+
taken = Math.imul(taken ^ s.charCodeAt(i), 16777619) >>> 0;
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
return `${image}\n${this.sourcesVersion}\n${taken}`;
|
|
1073
|
+
}
|
|
1074
|
+
/** Delete source features without taking them (one undo step). */
|
|
1075
|
+
deleteSourceFeatures(ids) {
|
|
1076
|
+
const taken = this.currentTaken();
|
|
1077
|
+
const drop = ids.filter((id) => !taken.has(id));
|
|
1078
|
+
if (!drop.length || !this.sourceView$.value)
|
|
1079
|
+
return;
|
|
1080
|
+
this.recordUndoSnapshot();
|
|
1081
|
+
this.setTaken(new Set([...taken, ...drop]));
|
|
1082
|
+
this.emit();
|
|
1083
|
+
}
|
|
1084
|
+
/**
|
|
1085
|
+
* A page of the slice source's features not taken from it (file order), e.g. for the Region
|
|
1086
|
+
* Editor's list; an empty page without a source.
|
|
1087
|
+
*/
|
|
1088
|
+
async getRegionSourceIndex(query) {
|
|
1089
|
+
const view = this.sourceView$.value;
|
|
1090
|
+
if (!view)
|
|
1091
|
+
return { total: 0, rows: [] };
|
|
1092
|
+
return view.source.getIndex(view.plane, { ...query, exclude: Array.from(view.taken) });
|
|
1093
|
+
}
|
|
1094
|
+
/**
|
|
1095
|
+
* `regions` as a GeoJSON FeatureCollection string merged with the region source behind them:
|
|
1096
|
+
* the source's features that were not taken (or deleted), then `regions`. Without a source,
|
|
1097
|
+
* {@link getGeoJsonString}. `slice` names a folder stack's slice (default the one shown);
|
|
1098
|
+
* on a z-indexed stack's source (`'planes'`) the export spans every slice.
|
|
1099
|
+
*/
|
|
1100
|
+
async getGeoJsonWithSource(regions, slice = this.sourceSlice) {
|
|
1101
|
+
const image = this.scope.activeImage;
|
|
1102
|
+
const planes = this.scope.stackMode && this.sources.hasPlanesSource(image);
|
|
1103
|
+
const binding = await this.sources.binding(image, slice);
|
|
1104
|
+
if (!binding)
|
|
1105
|
+
return regionsToGeoJson(regions);
|
|
1106
|
+
const features = regions
|
|
1107
|
+
.filter((r) => !r.isProfile?.())
|
|
1108
|
+
.map((r) => featureFromRegion(r))
|
|
1109
|
+
.filter((f) => !!f);
|
|
1110
|
+
const exclude = planes ? this.sources.allTaken(image) : Array.from(this.sources.taken(image, slice));
|
|
1111
|
+
return binding.source.exportGeoJson(exclude, features);
|
|
1112
|
+
}
|
|
1113
|
+
// ── Region look ────────────────────────────────────────────────────────
|
|
1114
|
+
/**
|
|
1115
|
+
* Whether a region of class `label` goes unlabelled because a subclass of it (by the region
|
|
1116
|
+
* source's class hierarchy) is among the regions too — an atlas's "Isocortex" under its areas.
|
|
1117
|
+
* False without a hierarchy.
|
|
1118
|
+
*/
|
|
1119
|
+
isLabelCovered(label) {
|
|
1120
|
+
if (!label)
|
|
1121
|
+
return false;
|
|
1122
|
+
const hierarchy = this.sourceView$.value?.source.info.hierarchy;
|
|
1123
|
+
if (!hierarchy)
|
|
1124
|
+
return false;
|
|
1125
|
+
if (this.coveredFor?.regions !== this.regions || this.coveredFor.hierarchy !== hierarchy) {
|
|
1126
|
+
const parent = new Map(hierarchy.filter((n) => n.parent).map((n) => [n.name, n.parent]));
|
|
1127
|
+
const covered = new Set();
|
|
1128
|
+
for (const r of this.regions) {
|
|
1129
|
+
let p = r.label ? parent.get(r.label) : undefined;
|
|
1130
|
+
while (p && !covered.has(p)) {
|
|
1131
|
+
covered.add(p);
|
|
1132
|
+
p = parent.get(p);
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
this.coveredFor = { regions: this.regions, hierarchy, covered };
|
|
1136
|
+
}
|
|
1137
|
+
return this.coveredFor.covered.has(label);
|
|
1138
|
+
}
|
|
1139
|
+
/** The classes hidden from view (see {@link setClassesHidden}). */
|
|
1140
|
+
getHiddenClasses() {
|
|
1141
|
+
return this.hiddenClasses$.value;
|
|
1142
|
+
}
|
|
1143
|
+
/** {@link getHiddenClasses} and every change of it. */
|
|
1144
|
+
getHiddenClasses$() {
|
|
1145
|
+
return this.hiddenClasses$.asObservable();
|
|
1146
|
+
}
|
|
1147
|
+
/**
|
|
1148
|
+
* Hide (or show again) these classes' regions: the overlays and the region source's layer stop
|
|
1149
|
+
* drawing them, and a hidden region can be neither picked nor kept selected. The regions stay in
|
|
1150
|
+
* the set (the table lists them; a save keeps them).
|
|
1151
|
+
*/
|
|
1152
|
+
setClassesHidden(classes, hidden) {
|
|
1153
|
+
const cur = this.hiddenClasses$.value;
|
|
1154
|
+
const next = new Set(cur);
|
|
1155
|
+
for (const c of classes) {
|
|
1156
|
+
if (hidden)
|
|
1157
|
+
next.add(c);
|
|
1158
|
+
else
|
|
1159
|
+
next.delete(c);
|
|
1160
|
+
}
|
|
1161
|
+
if (next.size === cur.size && [...next].every((c) => cur.has(c)))
|
|
1162
|
+
return;
|
|
1163
|
+
const set = this.store.getPresetSet();
|
|
1164
|
+
this.hiddenKeys = new Set([...next].map((c) => presetKey(set, c)));
|
|
1165
|
+
this.hiddenClasses$.next(next);
|
|
1166
|
+
if (hidden) {
|
|
1167
|
+
const shown = this.selection.indices.filter((i) => !this.isClassHidden(this.regions[i]?.label));
|
|
1168
|
+
if (shown.length !== this.selection.indices.length)
|
|
1169
|
+
this.setSelectedShapeIndices(shown);
|
|
1170
|
+
}
|
|
1171
|
+
this.republishView();
|
|
1172
|
+
this.regionUpdate$.next(this.getRegions());
|
|
1173
|
+
}
|
|
1174
|
+
/** Whether regions labelled `label` are hidden (an unlabelled region never is). */
|
|
1175
|
+
isClassHidden(label) {
|
|
1176
|
+
return !!label && this.hiddenKeys.size > 0 && this.hiddenKeys.has(presetKey(this.store.getPresetSet(), label));
|
|
1177
|
+
}
|
|
1178
|
+
/** The region look: outlines, or filled (an atlas's look); see `region-style`. */
|
|
1179
|
+
getRegionStyle() {
|
|
1180
|
+
return this.regionStyle$.value;
|
|
1181
|
+
}
|
|
1182
|
+
/** {@link getRegionStyle} and every change of it. */
|
|
1183
|
+
getRegionStyle$() {
|
|
1184
|
+
return this.regionStyle$.asObservable();
|
|
1185
|
+
}
|
|
1186
|
+
/**
|
|
1187
|
+
* Choose the region look, field by field; it overrides a region source's hint for the session.
|
|
1188
|
+
* The overlays redraw.
|
|
1189
|
+
*/
|
|
1190
|
+
setRegionStyle(patch) {
|
|
1191
|
+
this.userStyle = { ...this.userStyle, ...patch };
|
|
1192
|
+
this.restyle();
|
|
1193
|
+
}
|
|
1194
|
+
/** The look now: the user's choice, else the source's hint, else outlines. */
|
|
1195
|
+
effectiveStyle() {
|
|
1196
|
+
const hint = this.hintStyle ?? {};
|
|
1197
|
+
return {
|
|
1198
|
+
fillOpacity: this.userStyle.fillOpacity ?? hint.fillOpacity ?? DEFAULT_REGION_STYLE.fillOpacity,
|
|
1199
|
+
stroke: this.userStyle.stroke !== undefined ? this.userStyle.stroke : (hint.stroke ?? null),
|
|
1200
|
+
strokeWidth: this.userStyle.strokeWidth !== undefined ? this.userStyle.strokeWidth : (hint.strokeWidth ?? null),
|
|
1201
|
+
highlight: this.userStyle.highlight !== undefined ? this.userStyle.highlight : (hint.highlight ?? null),
|
|
1202
|
+
};
|
|
1203
|
+
}
|
|
1204
|
+
/** Publish the look when it changed: the overlays redraw the regions, the source layer its features. */
|
|
1205
|
+
restyle(redraw = false) {
|
|
1206
|
+
const next = this.effectiveStyle();
|
|
1207
|
+
const cur = this.regionStyle$.value;
|
|
1208
|
+
const same = Object.keys(next).every((k) => next[k] === cur[k]);
|
|
1209
|
+
if (!same)
|
|
1210
|
+
this.regionStyle$.next(next);
|
|
1211
|
+
const view = this.sourceView$.value;
|
|
1212
|
+
if (redraw || !same || (view && view.labels !== this.showShapeLabel)) {
|
|
1213
|
+
this.republishView();
|
|
1214
|
+
this.regionUpdate$.next(this.getRegions());
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
/** Re-emit the source view with the current look and label setting. */
|
|
1218
|
+
republishView() {
|
|
1219
|
+
const view = this.sourceView$.value;
|
|
1220
|
+
if (view)
|
|
1221
|
+
this.sourceView$.next({ ...view, style: this.regionStyle$.value, labels: this.showShapeLabel });
|
|
1222
|
+
}
|
|
1223
|
+
/** The slice a region source is keyed by: the display slice in stack mode, else 0. */
|
|
1224
|
+
get sourceSlice() {
|
|
1225
|
+
return this.scope.stackMode ? this.scope.displaySlice : 0;
|
|
1226
|
+
}
|
|
1227
|
+
currentTaken() {
|
|
1228
|
+
return this.sources.taken(this.scope.activeImage, this.sourceSlice);
|
|
1229
|
+
}
|
|
1230
|
+
/** Replace the slice's taken ids and tell the source layers. */
|
|
1231
|
+
setTaken(taken) {
|
|
1232
|
+
if (taken === this.currentTaken())
|
|
1233
|
+
return;
|
|
1234
|
+
this.sources.setTaken(this.scope.activeImage, this.sourceSlice, taken);
|
|
1235
|
+
const view = this.sourceView$.value;
|
|
1236
|
+
if (view)
|
|
1237
|
+
this.sourceView$.next({ ...view, taken });
|
|
1238
|
+
}
|
|
1239
|
+
/**
|
|
1240
|
+
* Look up (opening it if needed) the slice's source and publish it as the source view. The view
|
|
1241
|
+
* is withdrawn at once: until the incoming source opens, nothing reads, takes or deletes from the
|
|
1242
|
+
* outgoing one into the slice now shown.
|
|
1243
|
+
*/
|
|
1244
|
+
refreshSourceView() {
|
|
1245
|
+
const generation = ++this.sourceGeneration;
|
|
1246
|
+
const image = this.scope.activeImage;
|
|
1247
|
+
const slice = this.sourceSlice;
|
|
1248
|
+
if (this.sourceView$.value)
|
|
1249
|
+
this.sourceView$.next(null);
|
|
1250
|
+
this.sources.show(image, slice);
|
|
1251
|
+
if (!this.sources.has(image, slice)) {
|
|
1252
|
+
this.hintStyle = undefined;
|
|
1253
|
+
this.restyle();
|
|
1254
|
+
return;
|
|
1255
|
+
}
|
|
1256
|
+
this.sources.binding(image, slice).then((binding) => {
|
|
1257
|
+
if (generation !== this.sourceGeneration)
|
|
1258
|
+
return;
|
|
1259
|
+
if (!binding) {
|
|
1260
|
+
this.sourceView$.next(null);
|
|
1261
|
+
return;
|
|
1262
|
+
}
|
|
1263
|
+
const info = binding.source.info;
|
|
1264
|
+
const classColors = Object.entries(info.classColors);
|
|
1265
|
+
if (classColors.length)
|
|
1266
|
+
this.store.rememberImportedClassColors(new Map(classColors));
|
|
1267
|
+
// A source that asks for labels gets them when it opens (the toggle still turns them off).
|
|
1268
|
+
const labelsOn = !!info.style?.labels && !this.showShapeLabel && this.shownSource !== binding.source;
|
|
1269
|
+
if (labelsOn)
|
|
1270
|
+
this.showShapeLabel = true;
|
|
1271
|
+
this.shownSource = binding.source;
|
|
1272
|
+
this.hintStyle = info.style;
|
|
1273
|
+
this.sourceView$.next({
|
|
1274
|
+
source: binding.source,
|
|
1275
|
+
plane: binding.plane,
|
|
1276
|
+
taken: this.sources.taken(image, slice),
|
|
1277
|
+
colorOf: (f) => f.label ? colorForLabel(f.label, this.store.getPresetSet()) : f.color || this.shapeColor,
|
|
1278
|
+
style: this.regionStyle$.value,
|
|
1279
|
+
labels: this.showShapeLabel,
|
|
1280
|
+
isHidden: (label) => this.isClassHidden(label),
|
|
1281
|
+
});
|
|
1282
|
+
this.restyle(labelsOn);
|
|
1283
|
+
}, (err) => {
|
|
1284
|
+
if (generation !== this.sourceGeneration)
|
|
1285
|
+
return;
|
|
1286
|
+
console.warn('[regions] could not open the region source', err);
|
|
1287
|
+
this.sourceView$.next(null);
|
|
1288
|
+
});
|
|
1289
|
+
}
|
|
579
1290
|
// ── per-image lifecycle ────────────────────────────────────────────────
|
|
580
1291
|
/**
|
|
581
1292
|
* Switch the active image: snapshot the outgoing regions, restore the
|
|
@@ -593,6 +1304,7 @@ export class RegionStore {
|
|
|
593
1304
|
this.resetUndoHistory();
|
|
594
1305
|
this.emitSelection();
|
|
595
1306
|
this.regionUpdate$.next(this.getRegions());
|
|
1307
|
+
this.refreshSourceView();
|
|
596
1308
|
}
|
|
597
1309
|
// ── internals ──────────────────────────────────────────────────────────
|
|
598
1310
|
/** Apply the preset set's class colours (see {@link applyPresetColors}),
|
|
@@ -636,4 +1348,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
|
|
|
636
1348
|
type: Injectable,
|
|
637
1349
|
args: [{ providedIn: 'root' }]
|
|
638
1350
|
}], ctorParameters: () => [{ type: i1.VisualizerStore }] });
|
|
639
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaW9uLXN0b3JlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3N0b3JlL3JlZ2lvbi1zdG9yZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFjLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUczQyxPQUFPLEVBQVUsU0FBUyxFQUFFLE9BQU8sRUFBZ0IsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDM0YsT0FBTyxFQUFFLGVBQWUsRUFBRSxrQkFBa0IsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ2pHLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUc3RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQUUsY0FBYyxFQUFFLGFBQWEsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ2hILE9BQU8sS0FBSyxJQUFJLE1BQU0sd0JBQXdCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFlBQVksRUFBRSxlQUFlLEVBQUUsV0FBVyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDcEYsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQW1CLE1BQU0sc0JBQXNCLENBQUM7OztBQUV6RTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMkJHO0FBRUgsTUFBTSxPQUFPLFdBQVc7YUFDRSxlQUFVLEdBQUcsRUFBRSxBQUFMLENBQU07YUFDaEIscUJBQWdCLEdBQUcsR0FBRyxBQUFOLENBQU87SUFpRC9DLFlBQW9C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QUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNoQyxDQUFDO0lBRU8sSUFBSTtRQUNWLHdFQUF3RTtRQUN4RSx5RUFBeUU7UUFDekUsNEVBQTRFO1FBQzVFLGtFQUFrRTtRQUNsRSxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDaEQsSUFBSSxJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3hCLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO1lBQ3hCLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVEOytDQUMyQztJQUNuQyxhQUFhO1FBQ25CLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRU8sUUFBUSxDQUFDLEVBQVU7UUFDekIsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUMvQyxDQUFDO0lBRU8sU0FBUyxDQUFDLEVBQVU7UUFDMUIsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUNwRCxDQUFDOzhHQWhwQlUsV0FBVztrSEFBWCxXQUFXLGNBREUsTUFBTTs7MkZBQ25CLFdBQVc7a0JBRHZCLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBJSW1hZ2VJbmZvIH0gZnJvbSAnLi4vY29udHJhY3RzL2ltYWdlLmNvbnRyYWN0JztcbmltcG9ydCB7IFJlZ2lvbiwgUmVjdGFuZ2xlLCBQb2x5Z29uLCBNdWx0aVBvbHlnb24sIGh5ZHJhdGVCb3VuZHMgfSBmcm9tICcuLi9tb2RlbHMvcmVnaW9uJztcbmltcG9ydCB7IGRvd25sb2FkR2VvSnNvbiwgcmVnaW9uc0Zyb21HZW9Kc29uLCByZWdpb25zVG9HZW9Kc29uIH0gZnJvbSAnLi4vbW9kZWxzL3JlZ2lvbi1nZW9qc29uJztcbmltcG9ydCB7IFZpc3VhbGl6ZXJTdG9yZSB9IGZyb20gJy4vdmlzdWFsaXplci1zdG9yZS5zZXJ2aWNlJztcbmltcG9ydCB7IElSZWdpb25TdG9yZSB9IGZyb20gJy4uL2NvbnRyYWN0cy92aXN1YWxpemVyLmNvbnRyYWN0JztcbmltcG9ydCB7IElSZWdpb25FZGl0QXBpIH0gZnJvbSAnLi4vY29udHJhY3RzL3JlZ2lvbi1zdG9yZS5jb250cmFjdCc7XG5pbXBvcnQgeyBhcHBseVByZXNldENvbG9ycyB9IGZyb20gJy4vY2xhc3MtY29sb3IudXRpbCc7XG5pbXBvcnQgeyBjbG9uZUJvdW5kcywgbWFrZVBvbHlnb24sIHJlY3RUb1JpbmcsIHJlZ2lvblBvbHlnb25zLCByZXBsYWNlQm91bmRzIH0gZnJvbSAnLi4vbW9kZWxzL3BvbHlnb24tZmFjdG9yeSc7XG5pbXBvcnQgKiBhcyBlZGl0IGZyb20gJy4uL21vZGVscy9wb2x5Z29uLWVkaXQnO1xuaW1wb3J0IHsgcmVnaW9uc0VxdWFsLCB3aXRoUmVnaW9uUGF0Y2gsIHdpdGhSZWdpb25aIH0gZnJvbSAnLi4vbW9kZWxzL3JlZ2lvbi1jbG9uZSc7XG5pbXBvcnQgeyBSZWdpb25IaXN0b3J5IH0gZnJvbSAnLi9yZWdpb24taGlzdG9yeSc7XG5pbXBvcnQgeyBSZWdpb25TZWxlY3Rpb24gfSBmcm9tICcuL3JlZ2lvbi1zZWxlY3Rpb24nO1xuaW1wb3J0IHsgUmVnaW9uU2NvcGVDYWNoZSwgU3RhY2tTYXZlTGF5b3V0IH0gZnJvbSAnLi9yZWdpb24tc2NvcGUtY2FjaGUnO1xuXG4vKipcbiAqIEJhY2tlbmQtbmV1dHJhbCByZWdpb24gc3RvcmUg4oCUIHRoZSBzaW5nbGUgc291cmNlIG9mIHRydXRoIGZvciByZWdpb24gc3RhdGUuXG4gKlxuICogSG9sZHMgdGhlIG5ldXRyYWwge0BsaW5rIFJlZ2lvbn0gbW9kZWwgKG5ldmVyIGEgYmFja2VuZCdzIG93biBzaGFwZVxuICogcmVwcmVzZW50YXRpb24pLCBrZXllZCBwZXIgaW1hZ2Ugc28gcmVnaW9ucyBwZXJzaXN0IGFzIHRoZSB1c2VyIHN3aXRjaGVzXG4gKiBmaWxlcyBhbmQgc3Vydml2ZSBhIFBsb3RseeKHhE9wZW5TZWFkcmFnb24gYmFja2VuZCBzd2l0Y2ggKGJvdGggYmFja2VuZHMgcmVhZFxuICogYW5kIHdyaXRlICp0aGlzKiBzdG9yZSwgc28gbm8gbWlncmF0aW9uIGlzIG5lZWRlZCkuIEJhY2tlbmRzIG93biAqcmVuZGVyaW5nKlxuICogYW5kIHJlYWN0IHRvIHtAbGluayBnZXRSZWdpb25VcGRhdGVFdmVudH07IHRoaXMgc2VydmljZSBvd25zICpzdGF0ZSogYW5kIHRoZVxuICogZWRpdGluZyBvcGVyYXRpb25zLlxuICpcbiAqIEltcGxlbWVudHM6XG4gKiAgLSB7QGxpbmsgSVJlZ2lvblN0b3JlfSDigJQgdGhlIGNyb3NzLWJhY2tlbmQgQ1JVRC9zZWxlY3Rpb24vY29sb3VyIGNvbnRyYWN0XG4gKiAgICBldmVyeSBjb25zdW1lciAoUmVnaW9uIEVkaXRvciwgc2VnbWVudGF0aW9uLCBldGMuKSBhbHJlYWR5IHVzZXMuXG4gKiAgLSB7QGxpbmsgSVJlZ2lvbkVkaXRBcGl9IOKAlCBSZWdpb24tbmF0aXZlIGdlb21ldHJ5IGVkaXRzIChtb3ZlL3Jlc2l6ZSwgYW5kXG4gKiAgICBhZGQvZGVsZXRlL21vdmUgdmVydGV4KSB0aGUgT1NEIG92ZXJsYXkgZHJpdmVzLlxuICpcbiAqIENvcHktb24td3JpdGUgKHJldmlldyBSVC0xMyk6IG5vIG9wZXJhdGlvbiBjaGFuZ2VzIGEgc3RvcmVkIHtAbGluayBSZWdpb259XG4gKiAob3IgdGhlIHJlZ2lvbnMgYXJyYXkpIGluIHBsYWNlLiBBbiBlZGl0IGJ1aWxkcyBhIHJlcGxhY2VtZW50IOKAlCB0aGUgZ2VvbWV0cnlcbiAqIHRocm91Z2ggdGhlIHB1cmUgYG1vZGVscy9wb2x5Z29uLWVkaXRgIGZ1bmN0aW9ucyDigJQgYW5kIHN3YXBzIGl0IGluLCBzbyB0aGVcbiAqIHVuZG8gaGlzdG9yeSAoe0BsaW5rIFJlZ2lvbkhpc3Rvcnl9KSBjYW4ga2VlcCBzaGFsbG93IHNuYXBzaG90cyB0aGF0IHNoYXJlXG4gKiBldmVyeSB1bnRvdWNoZWQgcmVnaW9uIGluc3RlYWQgb2YgZGVlcC1jbG9uaW5nIHRoZSB3aG9sZSBzZXQgcGVyIHN0ZXAuXG4gKiBDYWxsZXJzIG11c3QgZm9sbG93IHRoZSBzYW1lIHJ1bGUgd2l0aCB0aGUgaW5zdGFuY2VzIHtAbGluayBnZXRSZWdpb25zfVxuICogcmV0dXJuczogdHJlYXQgdGhlbSBhcyByZWFkLW9ubHksIGFuZCBjb21taXQgYSBjaGFuZ2VkIGNvcHkuXG4gKlxuICogQ2xhc3NpZmljYXRpb24gY29sb3VycyBsaXZlIGluIHtAbGluayBWaXN1YWxpemVyU3RvcmV9IChzaGFyZWQgYnkgYm90aFxuICogYmFja2VuZHMpOyBHZW9KU09OIGltcG9ydC9leHBvcnQgaXMgYG1vZGVscy9yZWdpb24tZ2VvanNvbmAuIEFsbCBjb29yZGluYXRlc1xuICogYXJlIGltYWdlIHBpeGVscy5cbiAqL1xuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcbmV4cG9ydCBjbGFzcyBSZWdpb25TdG9yZSBpbXBsZW1lbnRzIElSZWdpb25TdG9yZSwgSVJlZ2lvbkVkaXRBcGkge1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBVTkRPX0xJTUlUID0gMTA7XG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IFVORE9fQ09BTEVTQ0VfTVMgPSAyNTA7XG5cbiAgLyoqIFRoZSBjdXJyZW50IGltYWdlJ3MgcmVnaW9ucyDigJQgdGhlIGxpdmUsIGVkaXRlZCBhcnJheS4gKi9cbiAgcHJpdmF0ZSByZWdpb25zOiBSZWdpb25bXSA9IFtdO1xuXG4gIC8qKlxuICAgKiBVbmRvL3JlZG8gaGlzdG9yeSAoaml0LXVpIzg1KTogdXAgdG8ge0BsaW5rIFVORE9fTElNSVR9IHNuYXBzaG90cyBvZiB0aGVcbiAgICogcmVnaW9uIHNldCwgZWFjaCB0YWtlbiBqdXN0ICpiZWZvcmUqIGEgcmVnaW9uLWVkaXRpbmcgYWN0aW9uOyBjb250aW51b3VzXG4gICAqIGdlc3R1cmVzIGFuZCByYXBpZCBjb21taXRzIGNvYWxlc2NlIChzZWUge0BsaW5rIFJlZ2lvbkhpc3Rvcnl9KS4gU25hcHNob3RzXG4gICAqIGFyZSBzaGFsbG93IOKAlCB0aGUgcmVnaW9ucyBhcnJheSBhcyBpdCB3YXMg4oCUIHdoaWNoIGlzIHNhZmUgYmVjYXVzZSBub3RoaW5nXG4gICAqIGhlcmUgbXV0YXRlcyBhIHJlZ2lvbiBvciBhbiBhcnJheSBpbiBwbGFjZSAoUlQtMTMpLiBIaXN0b3J5IG5ldmVyIGNyb3NzZXMgYW5cbiAgICogaW1hZ2UgbG9hZC9zd2l0Y2gg4oCUIHtAbGluayByZXNldFVuZG9IaXN0b3J5fSBjbGVhcnMgaXQuXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGhpc3RvcnkgPSBuZXcgUmVnaW9uSGlzdG9yeTxSZWdpb25bXT4oUmVnaW9uU3RvcmUuVU5ET19MSU1JVCwgUmVnaW9uU3RvcmUuVU5ET19DT0FMRVNDRV9NUyk7XG5cbiAgLyoqIE1vbm90b25pYyBpZCBzb3VyY2Ug4oCUIGlkcyBuZXZlciByZXBlYXQgd2l0aGluIHRoZSBzZXJ2aWNlIGxpZmV0aW1lLCBzb1xuICAgKiAgc2VsZWN0aW9uIHN0YXlzIGNvcnJlY3QgYWNyb3NzIGRlbGV0ZS9hZGQgY3ljbGVzIGV2ZW4gd2hlbiBuYW1lcyBjb2xsaWRlLiAqL1xuICBwcml2YXRlIG5leHRJZCA9IDE7XG5cbiAgcHJpdmF0ZSBzaG93U2hhcGVMYWJlbCA9IGZhbHNlO1xuICBwcml2YXRlIHNoYXBlQ29sb3IgPSAnIzAwRkZGRic7XG4gIHByaXZhdGUgZmlsbENvbG9yID0gJyNmZjAwZmYnO1xuICBwcml2YXRlIGlzUmVnaW9uU2F2ZWRPbiA9IHRydWU7XG5cbiAgLyoqXG4gICAqIFBlci1pbWFnZSBjYWNoZSBhbmQsIGZvciB6LXN0YWNrcywgcGVyLXNsaWNlIHJlZ2lvbnMgKGppdC11aSM5MykuIEluIHN0YWNrXG4gICAqIG1vZGUgdGhlIGxpdmUgYHJlZ2lvbnNgIGFycmF5IGhvbGRzIE9ORSBzbGljZSDigJQgdGhlIGRpc3BsYXkgc2xpY2Ug4oCUIHNvIHRoZVxuICAgKiBvdmVybGF5cywgdGhlIHNlbGVjdGlvbiBwcm9qZWN0aW9uIGFuZCB0aGUgUmVnaW9ucyB0YWJsZSB3b3JrIHVuY2hhbmdlZFxuICAgKiAodGhleSBhbGwgcmVhZCB7QGxpbmsgZ2V0UmVnaW9uc30pOyB7QGxpbmsgc2V0RGlzcGxheVNsaWNlfSBzd2FwcyB0aGUgbGl2ZVxuICAgKiBzZXQgb24gc2NydWIgYW5kIHtAbGluayBnZXRTbGljZVJlZ2lvbnN9IGZsYXR0ZW5zIGV2ZXJ5IHNsaWNlIChlYWNoIHRhZ2dlZFxuICAgKiB3aXRoIGl0cyB6ZXJvLWJhc2VkIHtAbGluayBSZWdpb24uen0pIGZvciBzYXZlL2V4cG9ydC4gT2ZmIGJ5IGRlZmF1bHQsIHNvXG4gICAqIHNpbmdsZS1wbGFuZSBpbWFnZXMgYXJlIHVuYWZmZWN0ZWQuXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHNjb3BlID0gbmV3IFJlZ2lvblNjb3BlQ2FjaGUoKTtcblxuICAvKiogU2VsZWN0aW9uIGJ5IHJlZ2lvbiAqaWQqIChzdGFibGUgYWNyb3NzIGVkaXRzKSwgcHJvamVjdGVkIHRvIGFycmF5XG4gICAqICBpbmRpY2VzIG9uIHRoZSBJUmVnaW9uU3RvcmUgYm91bmRhcnkuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgc2VsZWN0aW9uID0gbmV3IFJlZ2lvblNlbGVjdGlvbigpO1xuICBwcml2YXRlIHJlYWRvbmx5IHJlZ2lvblVwZGF0ZSQgPSBuZXcgU3ViamVjdDxSZWdpb25bXT4oKTtcbiAgLyoqIE5vbi1jb2FsZXNjZWQgc2libGluZyBvZiByZWdpb25VcGRhdGUkOiBmaXJlcyBvbiBldmVyeSBjaGFuZ2UgZXZlbiBkdXJpbmcgYVxuICAgKiAgYmF0Y2hlZCBkcmFnLCBzbyBsaXZlIGNvbnN1bWVycyAoaW50ZW5zaXR5IGluc2V0KSB1cGRhdGUgcGVyIGZyYW1lLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHJlZ2lvbkxpdmVFZGl0JCA9IG5ldyBTdWJqZWN0PFJlZ2lvbltdPigpO1xuICAvKiogU2VlIHtAbGluayBnZXRSZWdpb25TZXRSZXBsYWNlZCR9LiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHJlZ2lvblNldFJlcGxhY2VkJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgLyoqIEVtaXQgY29hbGVzY2luZyBmb3IgbGl2ZSBkcmFncyAoc2VlIElSZWdpb25FZGl0QXBpLmJlZ2luQmF0Y2gpLiAqL1xuICBwcml2YXRlIGJhdGNoRGVwdGggPSAwO1xuICBwcml2YXRlIHBlbmRpbmdFbWl0ID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBzdG9yZTogVmlzdWFsaXplclN0b3JlKSB7fVxuXG4gIC8vIOKUgOKUgCBJUmVnaW9uU3RvcmU6IENSVUQg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqXG4gICAqIFJlcGxhY2UgKG9yLCB3aXRoIGBhcHBlbmRgLCBhZGQgdG8pIHRoZSBjdXJyZW50IGltYWdlJ3MgcmVnaW9ucy4gTWludHMgaWRzXG4gICAqIGFuZCBkZWZhdWx0IG5hbWVzLCBhcHBsaWVzIHN0b3JlZCBjbGFzc2lmaWNhdGlvbiBjb2xvdXJzLCBhbmQgZW1pdHMuIFdoZW5cbiAgICogYGlzUmVnaW9uU2F2ZU9uYCBpcyBmYWxzZSB0aGUgcmVnaW9ucyBhcmUgc2hvd24gdHJhbnNpZW50bHkgKGVtaXR0ZWQpIGJ1dFxuICAgKiBub3Qgc3RvcmVkIOKAlCBtaXJyb3JzIHRoZSBwcmV2aW91cyBQbG90bHkgYmVoYXZpb3VyLlxuICAgKi9cbiAgc2V0UmVnaW9ucyhcbiAgICByZWdpb25zOiBSZWdpb25bXSxcbiAgICBzaG93UmVnaW9uTGFiZWw/OiBib29sZWFuLFxuICAgIGlzUmVnaW9uU2F2ZU9uPzogYm9vbGVhbixcbiAgICBmaWxsQ29sb3I/OiBzdHJpbmcsXG4gICAgYXBwZW5kOiBib29sZWFuID0gZmFsc2UsXG4gICk6IHZvaWQge1xuICAgIGlmIChzaG93UmVnaW9uTGFiZWwgPT09IHVuZGVmaW5lZCkgc2hvd1JlZ2lvbkxhYmVsID0gdGhpcy5zaG93U2hhcGVMYWJlbDtcbiAgICBpZiAoaXNSZWdpb25TYXZlT24gPT09IHVuZGVmaW5lZCkgaXNSZWdpb25TYXZlT24gPSB0aGlzLmlzUmVnaW9uU2F2ZWRPbjtcbiAgICBpZiAoZmlsbENvbG9yID09PSB1bmRlZmluZWQpIGZpbGxDb2xvciA9IHRoaXMuZmlsbENvbG9yO1xuXG4gICAgcmVnaW9ucyA9IHRoaXMuYWRtaXQocmVnaW9ucyk7XG5cbiAgICB0aGlzLmlzUmVnaW9uU2F2ZWRPbiA9IGlzUmVnaW9uU2F2ZU9uO1xuICAgIGlmIChpc1JlZ2lvblNhdmVPbikge1xuICAgICAgdGhpcy5yZWNvcmRVbmRvU25hcHNob3QoKTtcbiAgICAgIHRoaXMuc2hvd1NoYXBlTGFiZWwgPSBzaG93UmVnaW9uTGFiZWw7XG4gICAgICB0aGlzLmZpbGxDb2xvciA9IGZpbGxDb2xvcjtcbiAgICAgIGlmIChhcHBlbmQpIHtcbiAgICAgICAgLy8gUmVqZWN0IGJ5IGlkIGNvbGxpc2lvbiAoYWxyZWFkeSB0cmFja2VkKSBvciBnZW9tZXRyeSBlcXVhbGl0eSAoc2FtZVxuICAgICAgICAvLyBjb29yZGluYXRlcykg4oCUIHRoZSBmaW5kIGJ1dHRvbiBjYW4gcHVzaCB0aGUgc2FtZSByZWdpb24gcmVwZWF0ZWRseS5cbiAgICAgICAgY29uc3QgYWRkZWQgPSByZWdpb25zLmZpbHRlcihcbiAgICAgICAgICAocikgPT4gIXRoaXMucmVnaW9ucy5zb21lKChleGlzdGluZykgPT4gZXhpc3RpbmcuaWQgPT09IHIuaWQgfHwgcmVnaW9uc0VxdWFsKGV4aXN0aW5nLCByKSksXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMucmVnaW9ucyA9IHRoaXMucmVnaW9ucy5jb25jYXQoYWRkZWQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5yZWdpb25zID0gcmVnaW9ucy5zbGljZSgpO1xuICAgICAgfVxuICAgICAgdGhpcy5zeW5jQ2FjaGUoKTtcbiAgICAgIHRoaXMuZW1pdFNlbGVjdGlvbigpO1xuICAgICAgdGhpcy5lbWl0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFRyYW5zaWVudCBkaXNwbGF5IG9ubHkg4oCUIGRvbid0IHRvdWNoIHN0b3JlZCBzdGF0ZS5cbiAgICAgIHRoaXMucmVnaW9uVXBkYXRlJC5uZXh0KHJlZ2lvbnMuc2xpY2UoKSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBjYW5vbmljYWwgYWNjZXNzb3I6IHRoZSBjdXJyZW50IGltYWdlJ3MgcmVnaW9ucy4gQSBmcmVzaCBhcnJheSwgYnV0IHRoZVxuICAgKiBpbnN0YW5jZXMgYXJlIHRoZSBzdG9yZWQgb25lcywgc2hhcmVkIHdpdGggdGhlIHVuZG8gaGlzdG9yeTogdHJlYXQgdGhlbSBhc1xuICAgKiByZWFkLW9ubHkgYW5kIGNoYW5nZSBhIHJlZ2lvbiB0aHJvdWdoIHRoZSBzdG9yZSdzIG9wZXJhdGlvbnMgKG9yIGJ5XG4gICAqIGNvbW1pdHRpbmcgYSBjb3B5KS4gVHlwZWQgYFJlZ2lvbltdYCByYXRoZXIgdGhhblxuICAgKiBgUmVhZG9ubHlBcnJheTxSZWFkb25seTxSZWdpb24+PmAgYmVjYXVzZSB0aGUgSVJlZ2lvblN0b3JlIGNvbnRyYWN0IGFuZCB0aGVcbiAgICogYmFja2VuZHMgc3RpbGwgdGFrZSBhIG11dGFibGUgYXJyYXkuXG4gICAqL1xuICBnZXRSZWdpb25zKCk6IFJlZ2lvbltdIHtcbiAgICByZXR1cm4gdGhpcy5yZWdpb25zLnNsaWNlKCk7XG4gIH1cblxuICAvLyDilIDilIAgUGVyLXNsaWNlIHJlZ2lvbnMgZm9yIHotc3RhY2tzIChqaXQtdWkjOTMpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKiBUcnVlIHdoaWxlIGEgei1zdGFjayBpcyBsb2FkZWQgYW5kIHRoZSBzdG9yZSBob2xkcyByZWdpb25zIHBlciBzbGljZS4gKi9cbiAgaXNTdGFja01vZGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc2NvcGUuc3RhY2tNb2RlO1xuICB9XG5cbiAgLyoqIFRoZSBjdXJyZW50IGRpc3BsYXkgc2xpY2UgKHplcm8tYmFzZWQpLiAqL1xuICBnZXREaXNwbGF5U2xpY2UoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5zY29wZS5kaXNwbGF5U2xpY2U7XG4gIH1cblxuICAvKiogSG93IHRoZSBjdXJyZW50IHN0YWNrIHBlcnNpc3RzIHRvIGRpc2sgKGppdC11aSM5Myk6IGBjb21iaW5lZGAgPSBvbmVcbiAgICogIHotaW5kZXhlZCBnZW9qc29uIChzaW5nbGUtZmlsZSB6LXN0YWNrKTsgYHBlci1zbGljZS1maWxlYCA9IG9uZSBnZW9qc29uIHBlclxuICAgKiAgc2xpY2UtZmlsZSAoZm9sZGVyIHN0YWNrKS4gTWVhbmluZ2xlc3Mgb3V0c2lkZSBzdGFjayBtb2RlLiAqL1xuICBnZXRTdGFja1NhdmVMYXlvdXQoKTogU3RhY2tTYXZlTGF5b3V0IHtcbiAgICByZXR1cm4gdGhpcy5zY29wZS5zYXZlTGF5b3V0O1xuICB9XG5cbiAgLyoqXG4gICAqIEVudGVyIHBlci1zbGljZSBzdGFjayBtb2RlLiBgc2xpY2VzYCBtYXBzIGVhY2ggemVyby1iYXNlZCBzbGljZSBpbmRleCB0b1xuICAgKiB0aGUgcmVnaW9ucyBpbXBvcnRlZCBmb3IgdGhhdCBzbGljZTsgdGhlIHN0b3JlIG1ha2VzIGBpbml0aWFsWmAncyBzbGljZSB0aGVcbiAgICogbGl2ZSBzZXQsIHNvIHRoZSBvdmVybGF5cyAvIHNlbGVjdGlvbiAvIFJlZ2lvbnMgdGFibGUgYXJlIHVuY2hhbmdlZCAodGhleVxuICAgKiBzdGlsbCByZWFkIHtAbGluayBnZXRSZWdpb25zfSkuIEZyZXNobHktY3JlYXRlZCByZWdpb25zIGFyZSB0YWdnZWQgd2l0aCB0aGVcbiAgICogY3VycmVudCBzbGljZSBzbyB0aGV5IHBlcnNpc3Qgb24gaXQsIGFuZCB7QGxpbmsgZ2V0U2xpY2VSZWdpb25zfSByZXR1cm5zXG4gICAqIGV2ZXJ5IHNsaWNlIGZvciBzYXZlL2V4cG9ydC4gSWRzL25hbWVzL2NsYXNzaWZpY2F0aW9uIGNvbG91cnMgYXJlIG1pbnRlZFxuICAgKiBleGFjdGx5IGFzIHtAbGluayBzZXRSZWdpb25zfSBkb2VzLlxuICAgKi9cbiAgZW50ZXJTdGFja01vZGUoc2xpY2VzOiBNYXA8bnVtYmVyLCBSZWdpb25bXT4sIGluaXRpYWxaID0gMCwgc2F2ZUxheW91dDogU3RhY2tTYXZlTGF5b3V0ID0gJ2NvbWJpbmVkJyk6IHZvaWQge1xuICAgIGNvbnN0IGFkbWl0dGVkID0gbmV3IE1hcDxudW1iZXIsIFJlZ2lvbltdPigpO1xuICAgIGZvciAoY29uc3QgW3osIHJlZ3NdIG9mIHNsaWNlcykgYWRtaXR0ZWQuc2V0KHosIHRoaXMubm9ybWFsaXplU2xpY2UocmVncyB8fCBbXSwgeikpO1xuICAgIHRoaXMucmVnaW9ucyA9IHRoaXMuc2NvcGUuZW50ZXJTdGFjayhhZG1pdHRlZCwgaW5pdGlhbFosIHNhdmVMYXlvdXQpO1xuICAgIHRoaXMuc2VsZWN0aW9uLnJlcGxhY2UoW10pO1xuICAgIHRoaXMuc3luY0NhY2hlKCk7XG4gICAgdGhpcy5yZXNldFVuZG9IaXN0b3J5KCk7XG4gICAgdGhpcy5lbWl0U2VsZWN0aW9uKCk7XG4gICAgdGhpcy5lbWl0KCk7XG4gIH1cblxuICAvKiogTGVhdmUgc3RhY2sgbW9kZSAoc2luZ2xlLXBsYW5lIGltYWdlLCBvciB0aGUgc3RhY2sgd2FzIGNsb3NlZCkuICovXG4gIGV4aXRTdGFja01vZGUoKTogdm9pZCB7XG4gICAgdGhpcy5zY29wZS5leGl0U3RhY2soKTtcbiAgfVxuXG4gIC8qKiBUaGUgbGl2ZS1zZXQgc3dhcCBvZiB7QGxpbmsgc2V0RGlzcGxheVNsaWNlfS4gKi9cbiAgcHJpdmF0ZSBzaG93U2xpY2UoejogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgbmV4dCA9IHRoaXMuc2NvcGUuc2hvd1NsaWNlKHosIHRoaXMucmVnaW9ucyk7XG4gICAgaWYgKCFuZXh0KSByZXR1cm47XG4gICAgdGhpcy5yZWdpb25zID0gbmV4dDtcbiAgICB0aGlzLnNlbGVjdGlvbi5yZXBsYWNlKFtdKTtcbiAgICB0aGlzLnN5bmNDYWNoZSgpO1xuICAgIHRoaXMucmVzZXRVbmRvSGlzdG9yeSgpO1xuICAgIHRoaXMuZW1pdFNlbGVjdGlvbigpO1xuICAgIHRoaXMuZW1pdCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNob3cgYSBkaWZmZXJlbnQgc2xpY2U6IGNhcHR1cmUgdGhlIGN1cnJlbnQgc2xpY2UncyAocG9zc2libHkgZWRpdGVkKVxuICAgKiByZWdpb25zIGJhY2sgaW50byB0aGUgcGVyLXNsaWNlIHN0b3JlLCB0aGVuIGxvYWQgdGhlIHRhcmdldCBzbGljZSdzIHJlZ2lvbnNcbiAgICogYXMgdGhlIGxpdmUgc2V0IGFuZCBlbWl0LiBVbmRvIG5ldmVyIGNyb3NzZXMgYSBzbGljZS4gT3V0c2lkZSBzdGFjayBtb2RlXG4gICAqIHRoaXMgb25seSByZWNvcmRzIHRoZSByZXF1ZXN0ZWQgc2xpY2UgaW5kZXggKGEgbm8tb3Agb3RoZXJ3aXNlOiBzaW5nbGUtcGxhbmVcbiAgICogcmVnaW9ucyBzdGF5IG9uIHRoZSBkZWZhdWx0IHBsYW5lIOKAlCBhZGRSZWdpb24gdGFncyBSZWdpb24ueiBvbmx5IGluIHN0YWNrXG4gICAqIG1vZGUsIHNvIHRoZSByZWNvcmRlZCBpbmRleCBpcyB1bnVzZWQgdW50aWwgYSBzdGFjayBpcyBlbnRlcmVkKS4gKGppdC11aSM5MylcbiAgICogRWl0aGVyIHdheSB7QGxpbmsgZ2V0UmVnaW9uU2V0UmVwbGFjZWQkfSBlbWl0czogdGhlIHNsaWNlIG9uIHNjcmVlbiBjaGFuZ2VkXG4gICAqIHVuZGVyIGFueSBpbi1wcm9ncmVzcyB0b29sIHdvcmsuXG4gICAqL1xuICBzZXREaXNwbGF5U2xpY2UoejogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5zaG93U2xpY2Uoeik7XG4gICAgdGhpcy5yZWdpb25TZXRSZXBsYWNlZCQubmV4dCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV2ZXJ5IHNsaWNlJ3MgcmVnaW9ucyBmb3Igc2F2ZS9leHBvcnQsIGVhY2ggdGFnZ2VkIHdpdGggaXRzIHplcm8tYmFzZWRcbiAgICogc2xpY2UgaW5kZXggaW4ge0BsaW5rIFJlZ2lvbi56fS4gQ2FwdHVyZXMgdGhlIGN1cnJlbnQgc2xpY2UncyBsaXZlIGVkaXRzXG4gICAqIGZpcnN0LiBSZXR1cm5zIHRoZSBmbGF0IHNpbmdsZS1wbGFuZSBzZXQgd2hlbiBub3QgaW4gc3RhY2sgbW9kZS4gKGppdC11aSM5MylcbiAgICovXG4gIGdldFNsaWNlUmVnaW9ucygpOiBSZWdpb25bXSB7XG4gICAgcmV0dXJuIHRoaXMuc2NvcGUuc2xpY2VSZWdpb25zKHRoaXMucmVnaW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogU2xpY2VzIHRvIHdyaXRlIG9uIGEgcGVyLXNsaWNlLWZpbGUgc2F2ZSAoZm9sZGVyIHN0YWNrLCBqaXQtdWkjOTMpOiBldmVyeVxuICAgKiBzbGljZSB0aGF0IGN1cnJlbnRseSBoYXMgcmVnaW9ucywgUExVUyBzbGljZXMgdGhhdCB3ZXJlIGxvYWRlZCBub24tZW1wdHkgYnV0XG4gICAqIGFyZSBub3cgZW1wdHkgKHNvIHRoZWlyIGZpbGUgaXMgcmUtd3JpdHRlbiBlbXB0eSwgY2xlYXJpbmcgYSBzbGljZSB3aG9zZVxuICAgKiByZWdpb25zIHRoZSB1c2VyIGRlbGV0ZWQpLiBFYWNoIHJldHVybmVkIHJlZ2lvbiBpcyB0YWdnZWQgd2l0aCBpdHMgeiwgYW5kXG4gICAqIHRoZSBjdXJyZW50IGxpdmUgc2xpY2UgaXMgY2FwdHVyZWQgZmlyc3QuIEVtcHR5IG91dHNpZGUgc3RhY2sgbW9kZS5cbiAgICovXG4gIGdldFN0YWNrU2F2ZVNsaWNlcygpOiBNYXA8bnVtYmVyLCBSZWdpb25bXT4ge1xuICAgIHJldHVybiB0aGlzLnNjb3BlLnN0YWNrU2F2ZVNsaWNlcyh0aGlzLnJlZ2lvbnMpO1xuICB9XG5cbiAgLyoqIE1pbnQgaWRzL25hbWVzICsgYXBwbHkgY2xhc3NpZmljYXRpb24gY29sb3VycyArIHRhZyB0aGUgc2xpY2UgaW5kZXgsIGFzXG4gICAqICB7QGxpbmsgc2V0UmVnaW9uc30gZG9lcywgZm9yIHJlZ2lvbnMgZW50ZXJpbmcgdGhlIHBlci1zbGljZSBzdG9yZS4gKi9cbiAgcHJpdmF0ZSBub3JtYWxpemVTbGljZShyZWdpb25zOiBSZWdpb25bXSwgejogbnVtYmVyKTogUmVnaW9uW10ge1xuICAgIC8vIEEgZnJlc2ggKGltcG9ydGVkKSByZWdpb24gaXMgdGFnZ2VkIGluIHBsYWNlOyBhIHN0b3JlZCBvbmUgaXMgY29waWVkLlxuICAgIHJldHVybiB0aGlzLmFkbWl0KHJlZ2lvbnMubWFwKChyKSA9PiAoci5pZCA9PSBudWxsID8gT2JqZWN0LmFzc2lnbihyLCB7IHogfSkgOiB3aXRoUmVnaW9uWihyLCB6KSkpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpb25zIGVudGVyaW5nIHRoZSBzdG9yZTogbWludCBpZHMgYW5kIGRlZmF1bHQgbmFtZXMsIGh5ZHJhdGUgSlNPTiBib3VuZHNcbiAgICogaW50byBjbGFzcyBpbnN0YW5jZXMg4oCUIGV2ZXJ5dGhpbmcgZG93bnN0cmVhbSAocmVuZGVyaW5nLCBnZW9tZXRyeSBkZS1kdXAsXG4gICAqIG1vdmVSZWdpb24sIEdlb0pTT04gZXhwb3J0KSBkaXNjcmltaW5hdGVzIHRoZW0gd2l0aCBgaW5zdGFuY2VvZmBcbiAgICogKGppdC11aSMxMjQpIOKAlCBhbmQgYXBwbHkgY2xhc3NpZmljYXRpb24gY29sb3Vycy4gQSByZWdpb24gdGhhdCBpcyBuZXcgdG9cbiAgICogdGhlIHN0b3JlIChubyBpZCB5ZXQpIGlzIGNvbXBsZXRlZCBpbiBwbGFjZTsgb25lIHRoYXQgYWxyZWFkeSBoYXMgYW4gaWQgbWF5XG4gICAqIGJlIGEgc3RvcmVkIGluc3RhbmNlIHNoYXJlZCB3aXRoIHRoZSB1bmRvIGhpc3RvcnksIHNvIGl0IGlzIGNvcGllZCBpZiBpdFxuICAgKiBjaGFuZ2VzLlxuICAgKi9cbiAgcHJpdmF0ZSBhZG1pdChyZWdpb25zOiBSZWdpb25bXSk6IFJlZ2lvbltdIHtcbiAgICBjb25zdCBmcmVzaCA9IG5ldyBTZXQ8UmVnaW9uPigpO1xuICAgIGNvbnN0IGFkbWl0dGVkID0gcmVnaW9ucy5tYXAoKHJlZ2lvbikgPT4ge1xuICAgICAgaWYgKHJlZ2lvbi5pZCA9PSBudWxsKSB7XG4gICAgICAgIHJlZ2lvbi5pZCA9IHRoaXMubmV4dElkKys7XG4gICAgICAgIGlmIChyZWdpb24ubmFtZSA9PSBudWxsKSByZWdpb24ubmFtZSA9IGBzaGFwZSR7cmVnaW9uLmlkfWA7XG4gICAgICAgIHJlZ2lvbi5ib3VuZHMgPSBoeWRyYXRlQm91bmRzKHJlZ2lvbi5ib3VuZHMpO1xuICAgICAgICBmcmVzaC5hZGQocmVnaW9uKTtcbiAgICAgICAgcmV0dXJuIHJlZ2lvbjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGJvdW5kcyA9IGh5ZHJhdGVCb3VuZHMocmVnaW9uLmJvdW5kcyk7XG4gICAgICByZXR1cm4gcmVnaW9uLm5hbWUgPT0gbnVsbCB8fCBib3VuZHMgIT09IHJlZ2lvbi5ib3VuZHNcbiAgICAgICAgPyB3aXRoUmVnaW9uUGF0Y2gocmVnaW9uLCB7IG5hbWU6IHJlZ2lvbi5uYW1lID8/IGBzaGFwZSR7cmVnaW9uLmlkfWAsIGJvdW5kcyB9KVxuICAgICAgICA6IHJlZ2lvbjtcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcy53aXRoQ2xhc3NpZmljYXRpb25Db2xvcnMoYWRtaXR0ZWQsIChyKSA9PiBmcmVzaC5oYXMocikpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlZCBwb2x5Z29ucyBwcm9qZWN0ZWQgZm9yIGltYWdlLXByb2Nlc3NpbmcgY29uc3VtZXJzIChzZWdtZW50YXRpb24sXG4gICAqIGNyb3AgcmVxdWVzdHMsIHRyYWNlIGJ1aWxkZXJzKSwgc3RyYWlnaHQgZnJvbSBlYWNoIHJlZ2lvbidzIGJvdW5kczogYVxuICAgKiByZWN0YW5nbGUncyBjb3JuZXJzLCBhIHBvbHlnb24gd2l0aCBpdHMgaG9sZXMgKGEgYsOpemllciBhcyBpdHMgY3VydmUpLCBvbmVcbiAgICogcG9seWdvbiBwZXIgcGFydCBvZiBhIG11bHRpLXBvbHlnb24uIE9wZW4gcG9seWxpbmVzIGFyZSBhbm5vdGF0aW9uLW9ubHkgYW5kXG4gICAqIGV4Y2x1ZGVkLiBDb29yZGluYXRlcyBhcmUgcm91bmRlZCB0byB3aG9sZSBwaXhlbHMuXG4gICAqL1xuICBnZXRSZWdpb25Qb2x5Z29ucygpOiBQb2x5Z29uW10ge1xuICAgIHJldHVybiB0aGlzLnJlZ2lvbnMuZmxhdE1hcCgocmVnaW9uKSA9PiByZWdpb25Qb2x5Z29ucyhyZWdpb24pKTtcbiAgfVxuXG4gIGdldFJlZ2lvblVwZGF0ZUV2ZW50KCk6IE9ic2VydmFibGU8YW55W10+IHtcbiAgICByZXR1cm4gdGhpcy5yZWdpb25VcGRhdGUkLmFzT2JzZXJ2YWJsZSgpO1xuICB9XG5cbiAgLyoqIExpdmUgKG5vbi1jb2FsZXNjZWQpIHJlZ2lvbi1jaGFuZ2Ugc3RyZWFtIOKAlCBmaXJlcyBwZXIgZnJhbWUgZHVyaW5nIGEgZHJhZy5cbiAgICogIFVzZWQgYnkgdGhlIGludGVuc2l0eS1wcm9maWxlIGluc2V0IHNvIGl0IHRyYWNrcyBsaW5lIFJPSXMgbGl2ZS4gKi9cbiAgZ2V0UmVnaW9uTGl2ZUVkaXQkKCk6IE9ic2VydmFibGU8UmVnaW9uW10+IHtcbiAgICByZXR1cm4gdGhpcy5yZWdpb25MaXZlRWRpdCQuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICAvKipcbiAgICogRW1pdHMgYWZ0ZXIgZXZlcnkge0BsaW5rIHVuZG99LCB7QGxpbmsgcmVkb30gYW5kIHtAbGluayBzZXREaXNwbGF5U2xpY2V9IGNhbGxcbiAgICogKGV2ZW4gb25lIHRoYXQgY2hhbmdlZCBub3RoaW5nKTogdGhlIHJlZ2lvbiBzZXQgd2FzIHJlcGxhY2VkIHVuZGVyIHdoYXRldmVyXG4gICAqIGEgY2FudmFzIHRvb2wgd2FzIGJ1aWxkaW5nIG9uIChhIGJydXNoIHN0cm9rZSwgYSBTQU0gcG9pbnQgcHJvbXB0KSwgc28gdGhlXG4gICAqIGJhY2tlbmRzIHJlc2V0IHRoZWlyIGNhbnZhcyB0b29scyBvbiBpdC4gTm90IGVtaXR0ZWQgZm9yIG9yZGluYXJ5IGVkaXRzIOKAlFxuICAgKiBhIHRvb2wncyBvd24gY29tbWl0IG11c3Qgbm90IHJlc2V0IGl0LlxuICAgKi9cbiAgZ2V0UmVnaW9uU2V0UmVwbGFjZWQkKCk6IE9ic2VydmFibGU8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLnJlZ2lvblNldFJlcGxhY2VkJC5hc09ic2VydmFibGUoKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBJUmVnaW9uU3RvcmU6IHNlbGVjdGlvbiDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKiogU2VsZWN0IHJlZ2lvbnMgYnkgYXJyYXkgaW5kZXggKG9yIFtdIHRvIGNsZWFyKS4gU3RvcmVkIGludGVybmFsbHkgYnkgaWRcbiAgICogIHNvIHRoZSBzZWxlY3Rpb24gc3Vydml2ZXMgc3Vic2VxdWVudCBlZGl0cy9yZW9yZGVycy4gKi9cbiAgc2V0U2VsZWN0ZWRTaGFwZUluZGljZXMoaW5kaWNlczogbnVtYmVyW10pOiB2b2lkIHtcbiAgICB0aGlzLnNlbGVjdGlvbi5zZWxlY3RJbmRpY2VzKGluZGljZXMsIHRoaXMucmVnaW9ucyk7XG4gIH1cblxuICAvKiogU2VsZWN0IGEgc2luZ2xlIHJlZ2lvbiBieSBpZGVudGl0eSAoaWQpLiBCYWNrZW5kcyBjYWxsIHRoaXMgZnJvbSB0aGVpclxuICAgKiAgYHNlbGVjdFJlZ2lvbigpYDsgdGhlIE9TRCBvdmVybGF5ICsgcmVnaW9uIGVkaXRvciBoaWdobGlnaHQgb2ZmIHRoZVxuICAgKiAgcmVzdWx0aW5nIHNlbGVjdGlvbiBlbWl0LiBOby1vcCBpZiB0aGUgcmVnaW9uIGlzbid0IGluIHRoZSBzdG9yZS4gKi9cbiAgc2VsZWN0UmVnaW9uKHJlZ2lvbjogUmVnaW9uKTogdm9pZCB7XG4gICAgaWYgKHJlZ2lvbj8uaWQgPT0gbnVsbCB8fCB0aGlzLmluZGV4T2ZJZChyZWdpb24uaWQpIDwgMCkgcmV0dXJuO1xuICAgIHRoaXMuc2VsZWN0aW9uLnJlcGxhY2UoW3JlZ2lvbi5pZF0pO1xuICAgIHRoaXMuZW1pdFNlbGVjdGlvbigpO1xuICB9XG5cbiAgZ2V0U2VsZWN0ZWRTaGFwZUluZGljZXMkKCk6IE9ic2VydmFibGU8bnVtYmVyW10+IHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3Rpb24uaW5kaWNlcyQ7XG4gIH1cblxuICAvKiogU3luY2hyb25vdXMgY3VycmVudCBzZWxlY3Rpb24gKGFycmF5IGluZGljZXMpIOKAlCBmb3IgY2FsbGVycyB0aGF0IG5lZWQgdG9cbiAgICogIHJlYWQgdGhlIHNlbGVjdGlvbiB3aXRob3V0IHN1YnNjcmliaW5nLiAqL1xuICBnZXRTZWxlY3RlZFNoYXBlSW5kaWNlcygpOiBudW1iZXJbXSB7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0aW9uLmluZGljZXM7XG4gIH1cblxuICAvKiogRGVsZXRlIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgcmVnaW9ucyBhbmQgY2xlYXIgdGhlIHNlbGVjdGlvbi4gKi9cbiAgZGVsZXRlQWN0aXZlU2hhcGUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2VsZWN0aW9uLmlkcy5sZW5ndGggPT09IDApIHJldHVybjtcbiAgICB0aGlzLnJlY29yZFVuZG9TbmFwc2hvdCgpO1xuICAgIGNvbnN0IGlkcyA9IG5ldyBTZXQodGhpcy5zZWxlY3Rpb24uaWRzKTtcbiAgICB0aGlzLnJlZ2lvbnMgPSB0aGlzLnJlZ2lvbnMuZmlsdGVyKChyKSA9PiAhaWRzLmhhcyhyLmlkKSk7XG4gICAgdGhpcy5zZWxlY3Rpb24ucmVwbGFjZShbXSk7XG4gICAgdGhpcy5zeW5jQ2FjaGUoKTtcbiAgICB0aGlzLmVtaXRTZWxlY3Rpb24oKTtcbiAgICB0aGlzLmVtaXQoKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBJUmVnaW9uU3RvcmU6IGNvbG91cnMgLyBsYWJlbHMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgZ2V0U2hvd1NoYXBlTGFiZWwoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc2hvd1NoYXBlTGFiZWw7XG4gIH1cbiAgZ2V0U2hhcGVDb2xvcigpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnNoYXBlQ29sb3I7XG4gIH1cbiAgZ2V0RmlsbENvbG9yKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuZmlsbENvbG9yO1xuICB9XG5cbiAgLyoqIFNob3cgb3IgaGlkZSByZWdpb24gbGFiZWxzIChub3Qgb24gdGhlIGNvbnRyYWN0OyBzcGVjcyBkcml2ZSBpdCBkaXJlY3RseSkuXG4gICAqICBAZGVwcmVjYXRlZCBOb3RoaW5nIGluIHRoZSBsaWJyYXJ5IGNhbGxzIGl0OyB3aWxsIGJlIHJlbW92ZWQgbmV4dCBtaW5vci4gKi9cbiAgc2V0U2hvd1NoYXBlTGFiZWwoc2hvdzogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuc2hvd1NoYXBlTGFiZWwgPSBzaG93O1xuICB9XG5cbiAgZ2V0Q2xhc3NpZmljYXRpb25Db2xvcnMoKTogTWFwPHN0cmluZywgc3RyaW5nPiB7XG4gICAgcmV0dXJuIHRoaXMuc3RvcmUuZ2V0Q2xhc3NpZmljYXRpb25Db2xvcnMoKTtcbiAgfVxuICBzZXRDbGFzc2lmaWNhdGlvbkNvbG9yKGxhYmVsOiBzdHJpbmcsIGNvbG9yOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnN0b3JlLnNldENsYXNzaWZpY2F0aW9uQ29sb3IobGFiZWwsIGNvbG9yKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBJUmVnaW9uU3RvcmU6IHVuZG8gLyByZWRvIChqaXQtdWkjODUpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKiBFbWl0cyB3aGV0aGVyIGFuIHVuZG8gc3RlcCBpcyBjdXJyZW50bHkgYXZhaWxhYmxlIOKAlCBkcml2ZXMgdGhlIHRvb2xiYXJcbiAgICogIFVuZG8gYnV0dG9uJ3MgZW5hYmxlZCBzdGF0ZSAoZ3JleWVkIG91dCB3aGVuIGZhbHNlKS4gKi9cbiAgZ2V0Q2FuVW5kbyQoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRoaXMuaGlzdG9yeS5jYW5VbmRvJDtcbiAgfVxuXG4gIC8qKiBFbWl0cyB3aGV0aGVyIGEgcmVkbyBzdGVwIGlzIGN1cnJlbnRseSBhdmFpbGFibGUg4oCUIGRyaXZlcyB0aGUgdG9vbGJhclxuICAgKiAgUmVkbyBidXR0b24ncyBlbmFibGVkIHN0YXRlLiAqL1xuICBnZXRDYW5SZWRvJCgpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy5oaXN0b3J5LmNhblJlZG8kO1xuICB9XG5cbiAgLyoqIFN5bmNocm9ub3VzIHJlYWQgb2Yge0BsaW5rIGdldENhblVuZG8kfSDigJQgdHJ1ZSB3aGVuIGF0IGxlYXN0IG9uZSByZWdpb25cbiAgICogIGFjdGlvbiBjYW4gYmUgdW5kb25lLiAqL1xuICBjYW5VbmRvKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmhpc3RvcnkuY2FuVW5kbygpO1xuICB9XG5cbiAgLyoqIFN5bmNocm9ub3VzIHJlYWQgb2Yge0BsaW5rIGdldENhblJlZG8kfSDigJQgdHJ1ZSB3aGVuIGFuIHVuZG9uZSBhY3Rpb24gY2FuXG4gICAqICBiZSByZS1hcHBsaWVkLiAqL1xuICBjYW5SZWRvKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmhpc3RvcnkuY2FuUmVkbygpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVuZG8gdGhlIG1vc3QgcmVjZW50IHJlZ2lvbiBhY3Rpb24sIHJlc3RvcmluZyB0aGUgcmVnaW9uIHNldCB0byBpdHMgc3RhdGVcbiAgICoganVzdCBiZWZvcmUgdGhhdCBhY3Rpb24gYW5kIHB1c2hpbmcgdGhlIGN1cnJlbnQgc3RhdGUgb250byB0aGUgcmVkbyBzdGFjay5cbiAgICogVXAgdG8ge0BsaW5rIFVORE9fTElNSVR9IHN0ZXBzIGFyZSByZXRhaW5lZCwgc28gdGhpcyBjYW4gYmUgY2FsbGVkIHVwIHRvXG4gICAqIHtAbGluayBVTkRPX0xJTUlUfSB0aW1lcyBpbiBhIHJvdyBiZWZvcmUgdGhlIGhpc3RvcnkgZW1wdGllcy4gTm8tb3Agd2hlblxuICAgKiBub3RoaW5nIGlzIGxlZnQgdG8gdW5kby5cbiAgICovXG4gIHVuZG8oKTogdm9pZCB7XG4gICAgY29uc3Qgc25hcHNob3QgPSB0aGlzLmhpc3RvcnkudW5kbyh0aGlzLnJlZ2lvbnMpO1xuICAgIGlmIChzbmFwc2hvdCkgdGhpcy5yZXN0b3JlU25hcHNob3Qoc25hcHNob3QpO1xuICAgIHRoaXMucmVnaW9uU2V0UmVwbGFjZWQkLm5leHQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWRvIHRoZSBhY3Rpb24gbW9zdCByZWNlbnRseSB1bmRvbmUsIHJlc3RvcmluZyB0aGUgcmVnaW9uIHNldCB0byB0aGUgc3RhdGVcbiAgICogaXQgaGFkIGJlZm9yZSB0aGF0IHVuZG8gYW5kIHB1c2hpbmcgdGhlIGN1cnJlbnQgc3RhdGUgYmFjayBvbnRvIHRoZSB1bmRvXG4gICAqIHN0YWNrLiBOby1vcCB3aGVuIHRoZXJlJ3Mgbm90aGluZyB0byByZWRvICh0aGUgcmVkbyBzdGFjayBpcyBjbGVhcmVkIGJ5IGFueVxuICAgKiBmcmVzaCByZWdpb24gYWN0aW9uKS5cbiAgICovXG4gIHJlZG8oKTogdm9pZCB7XG4gICAgY29uc3Qgc25hcHNob3QgPSB0aGlzLmhpc3RvcnkucmVkbyh0aGlzLnJlZ2lvbnMpO1xuICAgIGlmIChzbmFwc2hvdCkgdGhpcy5yZXN0b3JlU25hcHNob3Qoc25hcHNob3QpO1xuICAgIHRoaXMucmVnaW9uU2V0UmVwbGFjZWQkLm5leHQoKTtcbiAgfVxuXG4gIC8qKiBEaXNjYXJkIHRoZSB1bmRvL3JlZG8gaGlzdG9yeSAoZS5nLiBvbiBpbWFnZSBsb2FkL3N3aXRjaCDigJQgaGlzdG9yeSBuZXZlclxuICAgKiAgY3Jvc3NlcyBpbWFnZXMpLiAqL1xuICByZXNldFVuZG9IaXN0b3J5KCk6IHZvaWQge1xuICAgIHRoaXMuaGlzdG9yeS5yZXNldCgpO1xuICB9XG5cbiAgLyoqIE1ha2UgYHNuYXBzaG90YCB0aGUgbGl2ZSByZWdpb24gc2V0IGFuZCBub3RpZnkgYm90aCBiYWNrZW5kcy4gU2hhcmVkIGJ5XG4gICAqICB7QGxpbmsgdW5kb30gYW5kIHtAbGluayByZWRvfTsgbm90aGluZyByZWNvcmRzIGhpc3Rvcnkgd2hpbGUgaXQgcnVucy4gKi9cbiAgcHJpdmF0ZSByZXN0b3JlU25hcHNob3Qoc25hcHNob3Q6IFJlZ2lvbltdKTogdm9pZCB7XG4gICAgdGhpcy5oaXN0b3J5LnJlc3RvcmUoKCkgPT4ge1xuICAgICAgdGhpcy5yZWdpb25zID0gc25hcHNob3Quc2xpY2UoKTtcbiAgICAgIHRoaXMuc3luY0NhY2hlKCk7XG4gICAgICAvLyBEcm9wcyBhbnkgc2VsZWN0ZWQgaWRzIHRoZSByZXN0b3JlZCBzZXQgbm8gbG9uZ2VyIGNvbnRhaW5zLlxuICAgICAgdGhpcy5lbWl0U2VsZWN0aW9uKCk7XG4gICAgfSk7XG4gICAgLy8gTm90aWZ5IHRoZSBsaXZlICsgY29hbGVzY2VkIHN0cmVhbXMgc28gd2hpY2hldmVyIGJhY2tlbmQgaXMgb24gc2NyZWVuXG4gICAgLy8gcmUtcmVuZGVycyBmcm9tIHRoZSByZXN0b3JlZCBzdG9yZSBzdGF0ZS5cbiAgICB0aGlzLnJlZ2lvbkxpdmVFZGl0JC5uZXh0KHRoaXMucmVnaW9ucy5zbGljZSgpKTtcbiAgICB0aGlzLnJlZ2lvblVwZGF0ZSQubmV4dCh0aGlzLmdldFJlZ2lvbnMoKSk7XG4gIH1cblxuICAvKipcbiAgICogQ2FwdHVyZSB0aGUgcHJlLWFjdGlvbiByZWdpb24gc2V0IGludG8gdGhlIGJvdW5kZWQgdW5kbyBoaXN0b3J5LiBDYWxsZWQgYXRcbiAgICogdGhlIHRvcCBvZiBldmVyeSBtdXRhdGluZyBvcGVyYXRpb24sICpiZWZvcmUqIGl0IGNoYW5nZXMgYHJlZ2lvbnNgLiBUaGVcbiAgICogc25hcHNob3QgaXMgdGhlIGFycmF5IGl0c2VsZjogZXZlcnkgb3BlcmF0aW9uIHJlcGxhY2VzIGByZWdpb25zYCAoYW5kIGFueVxuICAgKiByZWdpb24gaXQgZWRpdHMpIHJhdGhlciB0aGFuIGNoYW5naW5nIHRoZW0sIHNvIGl0IG5ldmVyIGNoYW5nZXMgYWZ0ZXIgdGhpcy5cbiAgICovXG4gIHByaXZhdGUgcmVjb3JkVW5kb1NuYXBzaG90KCk6IHZvaWQge1xuICAgIHRoaXMuaGlzdG9yeS5yZWNvcmQodGhpcy5yZWdpb25zKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBJUmVnaW9uU3RvcmU6IEdlb0pTT04gSS9PIChtb2RlbHMvcmVnaW9uLWdlb2pzb24pIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIGltcG9ydFJlZ2lvbnMoZ2VvSnNvblN0cjogc3RyaW5nKTogUmVnaW9uW10ge1xuICAgIHJldHVybiByZWdpb25zRnJvbUdlb0pzb24oZ2VvSnNvblN0cik7XG4gIH1cbiAgLyoqIERvd25sb2FkIGByZWdpb25zYCBhcyBHZW9KU09OLCBuYW1lZCBhZnRlciBgZmlsZU5hbWVgIChleHRlbnNpb25cbiAgICogIHJlcGxhY2VkIGJ5IGAuZ2VvanNvbmApIG9yIGByb2lzLmdlb2pzb25gIHdpdGhvdXQgb25lLiAqL1xuICBleHBvcnRSZWdpb25zKHJlZ2lvbnM6IFJlZ2lvbltdLCBmaWxlTmFtZT86IHN0cmluZyk6IHZvaWQge1xuICAgIGRvd25sb2FkR2VvSnNvbihyZWdpb25zVG9HZW9Kc29uKHJlZ2lvbnMpLCBmaWxlTmFtZSk7XG4gIH1cbiAgZ2V0R2VvSnNvblN0cmluZyhyZWdpb25zOiBSZWdpb25bXSk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHJlZ2lvbnNUb0dlb0pzb24ocmVnaW9ucyk7XG4gIH1cblxuICAvLyDilIDilIAgSVJlZ2lvbkVkaXRBcGk6IHN0cnVjdHVyYWwgZWRpdHMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgYWRkUmVnaW9uKHJlZ2lvbjogUmVnaW9uKTogbnVtYmVyIHtcbiAgICB0aGlzLnJlY29yZFVuZG9TbmFwc2hvdCgpO1xuICAgIGlmIChyZWdpb24uaWQgPT0gbnVsbCkgcmVnaW9uLmlkID0gdGhpcy5uZXh0SWQrKztcbiAgICBpZiAocmVnaW9uLm5hbWUgPT0gbnVsbCkgcmVnaW9uLm5hbWUgPSBgc2hhcGUke3JlZ2lvbi5pZH1gO1xuICAgIHJlZ2lvbi5ib3VuZHMgPSBoeWRyYXRlQm91bmRzKHJlZ2lvbi5ib3VuZHMpOyAvLyBqaXQtdWkjMTI0XG4gICAgLy8gQSByZWdpb24gZHJhd24gb24gYSBzdGFjayBiZWxvbmdzIHRvIHRoZSBzbGljZSBjdXJyZW50bHkgZGlzcGxheWVkLCBzb1xuICAgIC8vIGl0IHNhdmVzL3JlbG9hZHMgb24gdGhhdCBzbGljZSAoaml0LXVpIzkzKS4gTm8tb3AgZm9yIHNpbmdsZS1wbGFuZSBpbWFnZXNcbiAgICAvLyAodGhlIGRpc3BsYXkgc2xpY2Ugc3RheXMgMCkuXG4gICAgaWYgKHRoaXMuc2NvcGUuc3RhY2tNb2RlKSByZWdpb24ueiA9IHRoaXMuc2NvcGUuZGlzcGxheVNsaWNlO1xuICAgIC8vIFRoZSBjYWxsZXIncyBpbnN0YW5jZSBiZWNvbWVzIHRoZSBzdG9yZWQgb25lIChjb21wbGV0ZWQgaW4gcGxhY2UpLlxuICAgIGNvbnN0IFtzdG9yZWRdID0gdGhpcy53aXRoQ2xhc3NpZmljYXRpb25Db2xvcnMoW3JlZ2lvbl0sICgpID0+IHRydWUpO1xuICAgIHRoaXMucmVnaW9ucyA9IFsuLi50aGlzLnJlZ2lvbnMsIHN0b3JlZF07XG4gICAgdGhpcy5zZWxlY3Rpb24ucmVwbGFjZShbc3RvcmVkLmlkXSk7XG4gICAgdGhpcy5zeW5jQ2FjaGUoKTtcbiAgICB0aGlzLmVtaXRTZWxlY3Rpb24oKTtcbiAgICB0aGlzLmVtaXQoKTtcbiAgICByZXR1cm4gc3RvcmVkLmlkO1xuICB9XG5cbiAgcmVtb3ZlUmVnaW9uKGlkOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLnJlbW92ZVJlZ2lvbnMoW2lkXSk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIHRoZSByZWdpb25zIHdpdGggdGhlc2UgaWRzLCBpZiBwcmVzZW50LiBXaXRoIGB7IHJlY29yZFVuZG86IGZhbHNlIH1gXG4gICAqIG5vIHVuZG8gc3RlcCBpcyB0YWtlbiDigJQgZm9yIGNsZWFyaW5nIHRyYW5zaWVudCBzaGFwZXMgdGhhdCB3ZXJlIG5ldmVyIHRoZVxuICAgKiB1c2VyJ3Mgd29yayAodGhlIDNEIHZpZXcncyBzY3JlZW4tc3BhY2UgbGFzc29zIG9uIGFuIG9yYml0LCBOQVBBUkktU1ZDLTExKS5cbiAgICovXG4gIHJlbW92ZVJlZ2lvbnMoaWRzOiBJdGVyYWJsZTxudW1iZXI+LCBvcHRzOiB7IHJlY29yZFVuZG8/OiBib29sZWFuIH0gPSB7fSk6IHZvaWQge1xuICAgIGNvbnN0IGRyb3AgPSBuZXcgU2V0KGlkcyk7XG4gICAgaWYgKCF0aGlzLnJlZ2lvbnMuc29tZSgocikgPT4gZHJvcC5oYXMoci5pZCkpKSByZXR1cm47XG4gICAgaWYgKG9wdHMucmVjb3JkVW5kbyAhPT0gZmFsc2UpIHRoaXMucmVjb3JkVW5kb1NuYXBzaG90KCk7XG4gICAgdGhpcy5yZWdpb25zID0gdGhpcy5yZWdpb25zLmZpbHRlcigocikgPT4gIWRyb3AuaGFzKHIuaWQpKTtcbiAgICB0aGlzLnNlbGVjdGlvbi5yZXRhaW4oKHMpID0+ICFkcm9wLmhhcyhzKSk7XG4gICAgdGhpcy5zeW5jQ2FjaGUoKTtcbiAgICB0aGlzLmVtaXRTZWxlY3Rpb24oKTtcbiAgICB0aGlzLmVtaXQoKTtcbiAgfVxuXG4gIHVwZGF0ZUJvdW5kcyhpZDogbnVtYmVyLCBib3VuZHM6IFJlY3RhbmdsZSB8IFBvbHlnb24gfCBNdWx0aVBvbHlnb24pOiB2b2lkIHtcbiAgICBjb25zdCByID0gdGhpcy5maW5kQnlJZChpZCk7XG4gICAgaWYgKCFyKSByZXR1cm47XG4gICAgdGhpcy5yZWNvcmRVbmRvU25hcHNob3QoKTtcbiAgICAvLyBBIGNvcHksIHNvIHRoZSBjYWxsZXIgY2FuIGtlZXAgdXNpbmcgKGFuZCBjaGFuZ2luZykgdGhlIGJvdW5kcyBpdCBwYXNzZWQuXG4gICAgdGhpcy5yZXBsYWNlUmVnaW9uKHJlcGxhY2VCb3VuZHMociwgY2xvbmVCb3VuZHMoYm91bmRzKSkpO1xuICB9XG5cbiAgbW92ZVJlZ2lvbihpZDogbnVtYmVyLCBkeDogbnVtYmVyLCBkeTogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgciA9IHRoaXMuZmluZEJ5SWQoaWQpO1xuICAgIGlmICghciB8fCAhci5ib3VuZHMpIHJldHVybjtcbiAgICB0aGlzLnJlY29yZFVuZG9TbmFwc2hvdCgpO1xuICAgIC8vIEV2ZXJ5IHBhcnQgKGFuZCBpdHMgaG9sZXMpIG1vdmVzIHRvZ2V0aGVyIChqaXQtdWkjODUpLlxuICAgIHRoaXMucmVwbGFjZVJlZ2lvbihyZXBsYWNlQm91bmRzKHIsIGVkaXQudHJhbnNsYXRlQm91bmRzKHIuYm91bmRzLCBkeCwgZHkpKSk7XG4gIH1cblxuICAvLyDilIDilIAgSVJlZ2lvbkVkaXRBcGk6IHZlcnRleCBlZGl0cyAocG9seWdvbnMgb25seSkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gIC8vIEVhY2ggb25lIGlzIGEgcHVyZSBjb3B5LW9uLXdyaXRlIGVkaXQgZnJvbSBtb2RlbHMvcG9seWdvbi1lZGl0OyBhIG51bGxcbiAgLy8gcmVzdWx0IChvdXQgb2YgcmFuZ2UsIHdvdWxkIGRlZ2VuZXJhdGUpIHJlY29yZHMgbm90aGluZyBhbmQgZW1pdHMgbm90aGluZy5cblxuICBtb3ZlVmVydGV4KGlkOiBudW1iZXIsIGluZGV4OiBudW1iZXIsIHg6IG51bWJlciwgeTogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5lZGl0UG9seWdvbihpZCwgKHApID0+IGVkaXQubW92ZVZlcnRleChwLCBpbmRleCwgeCwgeSkpO1xuICB9XG5cbiAgLyoqIE1vdmUgYSB2ZXJ0ZXggb24gYSBwb2x5Z29uJ3MgaW50ZXJpb3IgcmluZyAoaG9sZSkg4oCUIGppdC11aSM4NS4gKi9cbiAgbW92ZUhvbGVWZXJ0ZXgoaWQ6IG51bWJlciwgaG9sZUluZGV4OiBudW1iZXIsIGluZGV4OiBudW1iZXIsIHg6IG51bWJlciwgeTogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5lZGl0UG9seWdvbihpZCwgKHApID0+IGVkaXQubW92ZUhvbGVWZXJ0ZXgocCwgaG9sZUluZGV4LCBpbmRleCwgeCwgeSkpO1xuICB9XG5cbiAgLyoqIEluc2VydCBhIHZlcnRleCBvbiBhIHBvbHlnb24ncyBpbnRlcmlvciByaW5nIChob2xlKSwgYWZ0ZXIgYHNlZ0luZGV4YFxuICAgKiAgKHRoZSBlZGdlJ3Mgc3RhcnQgdmVydGV4KS4gTm8tb3AgZm9yIGFuIG91dC1vZi1yYW5nZSBob2xlIOKAlCBqaXQtdWkjODUuICovXG4gIGFkZEhvbGVWZXJ0ZXgoaWQ6IG51bWJlciwgaG9sZUluZGV4OiBudW1iZXIsIHNlZ0luZGV4OiBudW1iZXIsIHg6IG51bWJlciwgeTogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5lZGl0UG9seWdvbihpZCwgKHApID0+IGVkaXQuYWRkSG9sZVZlcnRleChwLCBob2xlSW5kZXgsIHNlZ0luZGV4LCB4LCB5KSk7XG4gIH1cblxuICAvKiogRGVsZXRlIHRoZSB2ZXJ0ZXggYXQgYGluZGV4YCBvbiBhIHBvbHlnb24ncyBpbnRlcmlvciByaW5nIChob2xlKS4gUmVtb3ZpbmdcbiAgICogIGl0IGJlbG93IDMgdmVydGljZXMgZHJvcHMgdGhlIHdob2xlIGhvbGUgKGEgcmluZyB3aXRoIDwgMyBwb2ludHMgYm91bmRzIG5vXG4gICAqICBhcmVhKSDigJQgaml0LXVpIzg1LiAqL1xuICBkZWxldGVIb2xlVmVydGV4KGlkOiBudW1iZXIsIGhvbGVJbmRleDogbnVtYmVyLCBpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5lZGl0UG9seWdvbihpZCwgKHApID0+IGVkaXQuZGVsZXRlSG9sZVZlcnRleChwLCBob2xlSW5kZXgsIGluZGV4KSk7XG4gIH1cblxuICBhZGRWZXJ0ZXgoaWQ6IG51bWJlciwgc2VnSW5kZXg6IG51bWJlciwgeDogbnVtYmVyLCB5OiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmVkaXRQb2x5Z29uKGlkLCAocCkgPT4gZWRpdC5hZGRWZXJ0ZXgocCwgc2VnSW5kZXgsIHgsIHkpKTtcbiAgfVxuXG4gIGRlbGV0ZVZlcnRleChpZDogbnVtYmVyLCBpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5lZGl0UG9seWdvbihpZCwgKHApID0+IGVkaXQuZGVsZXRlVmVydGV4KHAsIGluZGV4KSk7XG4gIH1cblxuICBzZXRCZXppZXIoaWQ6IG51bWJlciwgYmV6aWVyOiBib29sZWFuKTogdm9pZCB7XG4gICAgY29uc3QgciA9IHRoaXMuZmluZEJ5SWQoaWQpO1xuICAgIGlmICghciB8fCAhci5ib3VuZHMpIHJldHVybjtcbiAgICBsZXQgbmV4dDogUG9seWdvbiB8IG51bGwgPSBudWxsO1xuICAgIGlmIChyLmJvdW5kcyBpbnN0YW5jZW9mIFBvbHlnb24pIHtcbiAgICAgIG5leHQgPSBlZGl0LnNldEJlemllcihyLmJvdW5kcywgYmV6aWVyKTtcbiAgICB9IGVsc2UgaWYgKHIuYm91bmRzIGluc3RhbmNlb2YgUmVjdGFuZ2xlICYmIGJlemllcikge1xuICAgICAgLy8gU21vb3RoaW5nIGEgcmVjdGFuZ2xlOiBjb252ZXJ0IGl0IHRvIGEgNC1hbmNob3IgY2xvc2VkIHBvbHlnb24gZmlyc3QuXG4gICAgICBjb25zdCByaW5nID0gcmVjdFRvUmluZyhyLmJvdW5kcyk7XG4gICAgICBuZXh0ID0gZWRpdC5zZXRCZXppZXIobWFrZVBvbHlnb24ocmluZy54cywgcmluZy55cyksIHRydWUpO1xuICAgIH1cbiAgICBpZiAoIW5leHQpIHJldHVybjsgLy8gYWxyZWFkeSBpbiB0aGF0IHN0YXRlLCBvciBiZXppZXI9ZmFsc2Ugb24gYSByZWN0YW5nbGVcbiAgICB0aGlzLnJlY29yZFVuZG9TbmFwc2hvdCgpO1xuICAgIHRoaXMucmVwbGFjZVJlZ2lvbihyZXBsYWNlQm91bmRzKHIsIG5leHQpKTtcbiAgfVxuXG4gIC8qKiBEcmFnIGEgYmV6aWVyIGNvbnRyb2wgcG9pbnQgb24gYSBob2xlIHJpbmcgdmVydGV4IChkb251dCBiZXppZXIgZWRpdGluZykuICovXG4gIG1vdmVIb2xlQmV6aWVySGFuZGxlKFxuICAgIGlkOiBudW1iZXIsXG4gICAgaG9sZUluZGV4OiBudW1iZXIsXG4gICAgaW5kZXg6IG51bWJlcixcbiAgICBzaWRlOiAnaW4nIHwgJ291dCcsXG4gICAgeDogbnVtYmVyLFxuICAgIHk6IG51bWJlcixcbiAgKTogdm9pZCB7XG4gICAgdGhpcy5lZGl0UG9seWdvbihpZCwgKHApID0+IGVkaXQubW92ZUhvbGVCZXppZXJIYW5kbGUocCwgaG9sZUluZGV4LCBpbmRleCwgc2lkZSwgeCwgeSkpO1xuICB9XG5cbiAgbW92ZUJlemllckhhbmRsZShpZDogbnVtYmVyLCBpbmRleDogbnVtYmVyLCBzaWRlOiAnaW4nIHwgJ291dCcsIHg6IG51bWJlciwgeTogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5lZGl0UG9seWdvbihpZCwgKHApID0+IGVkaXQubW92ZUJlemllckhhbmRsZShwLCBpbmRleCwgc2lkZSwgeCwgeSkpO1xuICB9XG5cbiAgLyoqIEFwcGx5IGEgY29weS1vbi13cml0ZSBwb2x5Z29uIGVkaXQgdG8gcmVnaW9uIGBpZGA6IHJlY29yZCwgc3dhcCBpbiwgZW1pdC4gKi9cbiAgcHJpdmF0ZSBlZGl0UG9seWdvbihpZDogbnVtYmVyLCBhcHBseTogKHA6IFBvbHlnb24pID0+IFBvbHlnb24gfCBudWxsKTogdm9pZCB7XG4gICAgY29uc3QgciA9IHRoaXMuZmluZEJ5SWQoaWQpO1xuICAgIGlmICghciB8fCAhKHIuYm91bmRzIGluc3RhbmNlb2YgUG9seWdvbikpIHJldHVybjtcbiAgICBjb25zdCBuZXh0ID0gYXBwbHkoci5ib3VuZHMpO1xuICAgIGlmICghbmV4dCkgcmV0dXJuO1xuICAgIHRoaXMucmVjb3JkVW5kb1NuYXBzaG90KCk7XG4gICAgdGhpcy5yZXBsYWNlUmVnaW9uKHJlcGxhY2VCb3VuZHMociwgbmV4dCkpO1xuICB9XG5cbiAgLyoqIFN3YXAgYG5leHRgIGluIGZvciB0aGUgc3RvcmVkIHJlZ2lvbiB3aXRoIGl0cyBpZCAoYSBuZXcgYXJyYXkpLCB0aGVuIHN5bmMgYW5kIGVtaXQuICovXG4gIHByaXZhdGUgcmVwbGFjZVJlZ2lvbihuZXh0OiBSZWdpb24pOiB2b2lkIHtcbiAgICB0aGlzLnJlZ2lvbnMgPSB0aGlzLnJlZ2lvbnMubWFwKChyKSA9PiAoci5pZCA9PT0gbmV4dC5pZCA/IG5leHQgOiByKSk7XG4gICAgdGhpcy5zeW5jQ2FjaGUoKTtcbiAgICB0aGlzLmVtaXQoKTtcbiAgfVxuXG4gIC8qKiBDb2FsZXNjZSBgcmVnaW9uVXBkYXRlJGAgdW50aWwgdGhlIG1hdGNoaW5nIHtAbGluayBlbmRCYXRjaH0gKGxpdmUgZHJhZ3MpO1xuICAgKiAgdGhlIGJhdGNoIGlzIGFsc28gb25lIHVuZG8gZ2VzdHVyZSAoe0BsaW5rIGJlZ2luR2VzdHVyZX0pLiAqL1xuICBiZWdpbkJhdGNoKCk6IHZvaWQge1xuICAgIHRoaXMuYmF0Y2hEZXB0aCsrO1xuICAgIHRoaXMuYmVnaW5HZXN0dXJlKCk7XG4gIH1cbiAgZW5kQmF0Y2goKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYmF0Y2hEZXB0aCA+IDApIHRoaXMuYmF0Y2hEZXB0aC0tO1xuICAgIHRoaXMuZW5kR2VzdHVyZSgpO1xuICAgIGlmICh0aGlzLmJhdGNoRGVwdGggPT09IDAgJiYgdGhpcy5wZW5kaW5nRW1pdCkge1xuICAgICAgdGhpcy5wZW5kaW5nRW1pdCA9IGZhbHNlO1xuICAgICAgdGhpcy5yZWdpb25VcGRhdGUkLm5leHQodGhpcy5nZXRSZWdpb25zKCkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNYXJrIHRoZSBzdGFydCBvZiBvbmUgdXNlciBnZXN0dXJlIChlLmcuIGEgd2FuZC9icnVzaCBtb3VzZWRvd24pOiBldmVyeVxuICAgKiBjb21taXQgdW50aWwgdGhlIG1hdGNoaW5nIHtAbGluayBlbmRHZXN0dXJlfSBiZWNvbWVzIGEgc2luZ2xlIHVuZG8gc3RlcCxcbiAgICogd2l0aG91dCBkZWxheWluZyBgcmVnaW9uVXBkYXRlJGAgKHRvb2xzIHJlbmRlciB0aHJvdWdoIGl0IHdoaWxlIGRyYWdnaW5nKS5cbiAgICogQ2FsbHMgbmVzdC4gQSBnZXN0dXJlIG5ldmVyIGZvbGRzIGludG8gYW4gZWFybGllciB0aW1lZCBidXJzdC5cbiAgICovXG4gIGJlZ2luR2VzdHVyZSgpOiB2b2lkIHtcbiAgICB0aGlzLmhpc3RvcnkuYmVnaW5HZXN0dXJlKCk7XG4gIH1cblxuICAvKiogRW5kIHRoZSBnZXN0dXJlIG9wZW5lZCBieSB7QGxpbmsgYmVnaW5HZXN0dXJlfTsgdGhlIG5leHQgY29tbWl0IHN0YXJ0cyBhIG5ldyBzdGVwLiAqL1xuICBlbmRHZXN0dXJlKCk6IHZvaWQge1xuICAgIHRoaXMuaGlzdG9yeS5lbmRHZXN0dXJlKCk7XG4gIH1cblxuICAvLyDilIDilIAgcGVyLWltYWdlIGxpZmVjeWNsZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKipcbiAgICogU3dpdGNoIHRoZSBhY3RpdmUgaW1hZ2U6IHNuYXBzaG90IHRoZSBvdXRnb2luZyByZWdpb25zLCByZXN0b3JlIHRoZVxuICAgKiBpbmNvbWluZyBpbWFnZSdzIChvciBbXSBpZiBub25lKSwgY2xlYXIgc2VsZWN0aW9uLCBhbmQgbm90aWZ5LiBJZGVtcG90ZW50XG4gICAqIGZvciB0aGUgc2FtZSBpbWFnZSAoc28gcmVwZWF0ZWQgcmVwbG90cyBvZiBvbmUgaW1hZ2Uga2VlcCBpdHMgcmVnaW9ucykuXG4gICAqL1xuICBzZXRBY3RpdmVJbWFnZShpbWFnZUluZm86IElJbWFnZUluZm8pOiB2b2lkIHtcbiAgICAvLyBTd2l0Y2hpbmcgaW1hZ2VzIGFsc28gZW5kcyBhbnkgcGVyLXNsaWNlIHN0YWNrIHNlc3Npb24gKGppdC11aSM5MykuXG4gICAgY29uc3QgaW5jb21pbmcgPSB0aGlzLnNjb3BlLnN3aXRjaEltYWdlKFJlZ2lvblNjb3BlQ2FjaGUuaW1hZ2VLZXkoaW1hZ2VJbmZvKSwgdGhpcy5yZWdpb25zKTtcbiAgICBpZiAoIWluY29taW5nKSByZXR1cm47XG4gICAgdGhpcy5yZWdpb25zID0gaW5jb21pbmc7XG4gICAgdGhpcy5zZWxlY3Rpb24ucmVwbGFjZShbXSk7XG4gICAgLy8gVW5kbyBuZXZlciBjcm9zc2VzIGFuIGltYWdlIHN3aXRjaC5cbiAgICB0aGlzLnJlc2V0VW5kb0hpc3RvcnkoKTtcbiAgICB0aGlzLmVtaXRTZWxlY3Rpb24oKTtcbiAgICB0aGlzLnJlZ2lvblVwZGF0ZSQubmV4dCh0aGlzLmdldFJlZ2lvbnMoKSk7XG4gIH1cblxuICAvLyDilIDilIAgaW50ZXJuYWxzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKiBBcHBseSB0aGUgcHJlc2V0IHNldCdzIGNsYXNzIGNvbG91cnMgKHNlZSB7QGxpbmsgYXBwbHlQcmVzZXRDb2xvcnN9KSxcbiAgICogIHByb21vdGluZyB1bmtub3duIGNsYXNzZXMgaW50byB0aGUgc2hhcmVkIHN0b3JlIHdoZW4gdGhlIHNldCBhc2tzIGZvciBpdC4gKi9cbiAgcHJpdmF0ZSB3aXRoQ2xhc3NpZmljYXRpb25Db2xvcnMocmVnaW9uczogUmVnaW9uW10sIGluUGxhY2U6IChyOiBSZWdpb24pID0+IGJvb2xlYW4pOiBSZWdpb25bXSB7XG4gICAgcmV0dXJuIGFwcGx5UHJlc2V0Q29sb3JzKHJlZ2lvbnMsIHRoaXMuc3RvcmUuZ2V0UHJlc2V0U2V0KCksIHtcbiAgICAgIGluUGxhY2UsXG4gICAgICBvblByb21vdGU6IChwcmVzZXQpID0+IHRoaXMuc3RvcmUudXBzZXJ0Q2xhc3MocHJlc2V0KSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc3luY0NhY2hlKCk6IHZvaWQge1xuICAgIHRoaXMuc2NvcGUuc3luYyh0aGlzLnJlZ2lvbnMpO1xuICB9XG5cbiAgcHJpdmF0ZSBlbWl0KCk6IHZvaWQge1xuICAgIC8vIExpdmUtZWRpdCBsaXN0ZW5lcnMgKGUuZy4gdGhlIGludGVuc2l0eS1wcm9maWxlIGluc2V0KSByZWFjdCBvbiBFVkVSWVxuICAgIC8vIGNoYW5nZSDigJQgaW5jbHVkaW5nIHBlci1mcmFtZSBkdXJpbmcgYSBiYXRjaGVkIGRyYWcg4oCUIHNvIHRoZXkgdHJhY2sgdGhlXG4gICAgLy8gcmVnaW9uIGxpdmUuIFRoZSBtYWluIHJlZ2lvblVwZGF0ZSQgc3RheXMgY29hbGVzY2VkIGR1cmluZyBhIGJhdGNoIChmaXJlc1xuICAgIC8vIG9uY2Ugb24gZW5kQmF0Y2gpIHRvIGtlZXAgaGVhdmllciBjb25zdW1lcnMgKFJlZ2lvbnMgdGFiKSBjYWxtLlxuICAgIHRoaXMucmVnaW9uTGl2ZUVkaXQkLm5leHQodGhpcy5yZWdpb25zLnNsaWNlKCkpO1xuICAgIGlmICh0aGlzLmJhdGNoRGVwdGggPiAwKSB7XG4gICAgICB0aGlzLnBlbmRpbmdFbWl0ID0gdHJ1ZTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5yZWdpb25VcGRhdGUkLm5leHQodGhpcy5nZXRSZWdpb25zKCkpO1xuICB9XG5cbiAgLyoqIFByb2plY3QgdGhlIHNlbGVjdGVkIGlkcyBvbnRvIHRoZSBjdXJyZW50IHJlZ2lvbnMgKHBydW5pbmcgZ29uZSBvbmVzKTtcbiAgICogIGVtaXRzIG9ubHkgaWYgdGhlIGluZGV4IHNldCBjaGFuZ2VkLiAqL1xuICBwcml2YXRlIGVtaXRTZWxlY3Rpb24oKTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3Rpb24uc3luYyh0aGlzLnJlZ2lvbnMpO1xuICB9XG5cbiAgcHJpdmF0ZSBmaW5kQnlJZChpZDogbnVtYmVyKTogUmVnaW9uIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5yZWdpb25zLmZpbmQoKHIpID0+IHIuaWQgPT09IGlkKTtcbiAgfVxuXG4gIHByaXZhdGUgaW5kZXhPZklkKGlkOiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnJlZ2lvbnMuZmluZEluZGV4KChyKSA9PiByLmlkID09PSBpZCk7XG4gIH1cbn1cbiJdfQ==
|
|
1351
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaW9uLXN0b3JlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3N0b3JlL3JlZ2lvbi1zdG9yZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLGVBQWUsRUFBYyxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFHNUQsT0FBTyxFQUFVLFNBQVMsRUFBRSxPQUFPLEVBQWdCLGFBQWEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzNGLE9BQU8sRUFFTCxlQUFlLEVBQ2YsaUJBQWlCLEVBQ2pCLHdCQUF3QixFQUN4QixrQkFBa0IsRUFDbEIsZ0JBQWdCLEdBQ2pCLE1BQU0sMEJBQTBCLENBQUM7QUFDbEMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRzdELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxhQUFhLEVBQUUsU0FBUyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDakYsT0FBTyxFQUNMLFdBQVcsRUFDWCxXQUFXLEVBQ1gsVUFBVSxFQUNWLGNBQWMsRUFDZCxlQUFlLEVBQ2YsYUFBYSxHQUNkLE1BQU0sMkJBQTJCLENBQUM7QUFFbkMsT0FBTyxFQUFpQixZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN0RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUM1RSxPQUFPLEtBQUssSUFBSSxNQUFNLHdCQUF3QixDQUFDO0FBQy9DLE9BQU8sRUFBRSxZQUFZLEVBQUUsZUFBZSxFQUFFLFdBQVcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3BGLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDckQsT0FBTyxFQUFFLGdCQUFnQixF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LENBQUM7WUFDeEIsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBRUQ7K0NBQzJDO0lBQ25DLGFBQWE7UUFDbkIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFTyxRQUFRLENBQUMsRUFBVTtRQUN6QixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQy9DLENBQUM7SUFFTyxTQUFTLENBQUMsRUFBVTtRQUMxQixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQ3BELENBQUM7OEdBdnpDVSxXQUFXO2tIQUFYLFdBQVcsY0FERSxNQUFNOzsyRkFDbkIsV0FBVztrQkFEdkIsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIE9ic2VydmFibGUsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgSUltYWdlSW5mbyB9IGZyb20gJy4uL2NvbnRyYWN0cy9pbWFnZS5jb250cmFjdCc7XG5pbXBvcnQgeyBSZWdpb24sIFJlY3RhbmdsZSwgUG9seWdvbiwgTXVsdGlQb2x5Z29uLCBoeWRyYXRlQm91bmRzIH0gZnJvbSAnLi4vbW9kZWxzL3JlZ2lvbic7XG5pbXBvcnQge1xuICBHZW9Kc29uRmVhdHVyZSxcbiAgZG93bmxvYWRHZW9Kc29uLFxuICBmZWF0dXJlRnJvbVJlZ2lvbixcbiAgcmVnaW9uRnJvbUdlb0pzb25GZWF0dXJlLFxuICByZWdpb25zRnJvbUdlb0pzb24sXG4gIHJlZ2lvbnNUb0dlb0pzb24sXG59IGZyb20gJy4uL21vZGVscy9yZWdpb24tZ2VvanNvbic7XG5pbXBvcnQgeyBWaXN1YWxpemVyU3RvcmUgfSBmcm9tICcuL3Zpc3VhbGl6ZXItc3RvcmUuc2VydmljZSc7XG5pbXBvcnQgeyBJUmVnaW9uU3RvcmUgfSBmcm9tICcuLi9jb250cmFjdHMvdmlzdWFsaXplci5jb250cmFjdCc7XG5pbXBvcnQgeyBJUmVnaW9uRWRpdEFwaSwgSVJlZ2lvblNvdXJjZUFwaSB9IGZyb20gJy4uL2NvbnRyYWN0cy9yZWdpb24tc3RvcmUuY29udHJhY3QnO1xuaW1wb3J0IHsgYXBwbHlQcmVzZXRDb2xvcnMsIGNvbG9yRm9yTGFiZWwsIHByZXNldEtleSB9IGZyb20gJy4vY2xhc3MtY29sb3IudXRpbCc7XG5pbXBvcnQge1xuICBjbG9uZUJvdW5kcyxcbiAgbWFrZVBvbHlnb24sXG4gIHJlY3RUb1JpbmcsXG4gIHJlZ2lvblBvbHlnb25zLFxuICByZWdpb25Qb2x5bGluZXMsXG4gIHJlcGxhY2VCb3VuZHMsXG59IGZyb20gJy4uL21vZGVscy9wb2x5Z29uLWZhY3RvcnknO1xuaW1wb3J0IHR5cGUgeyBNZXNoIH0gZnJvbSAnbmFwYXJpLWpzL2dlb21ldHJ5JztcbmltcG9ydCB7IFNsaWNlT3V0bGluZXMsIG91dGxpbmVzQXJlYSB9IGZyb20gJy4uL2dlb21ldHJ5L3JlY29uc3RydWN0JztcbmltcG9ydCB7IHJlY29uc3RydWN0SW5Xb3JrZXIgfSBmcm9tICcuLi9yZWdpb24tc291cmNlL3dvcmtlci1yZWdpb24tc291cmNlJztcbmltcG9ydCAqIGFzIGVkaXQgZnJvbSAnLi4vbW9kZWxzL3BvbHlnb24tZWRpdCc7XG5pbXBvcnQgeyByZWdpb25zRXF1YWwsIHdpdGhSZWdpb25QYXRjaCwgd2l0aFJlZ2lvblogfSBmcm9tICcuLi9tb2RlbHMvcmVnaW9uLWNsb25lJztcbmltcG9ydCB7IFJlZ2lvbkhpc3RvcnkgfSBmcm9tICcuL3JlZ2lvbi1oaXN0b3J5JztcbmltcG9ydCB7IFJlZ2lvblNlbGVjdGlvbiB9IGZyb20gJy4vcmVnaW9uLXNlbGVjdGlvbic7XG5pbXBvcnQgeyBSZWdpb25TY29wZUNhY2hlLCBTdGFja1NhdmVMYXlvdXQgfSBmcm9tICcuL3JlZ2lvbi1zY29wZS1jYWNoZSc7XG5pbXBvcnQgeyBSZWdpb25Tb3VyY2VPcGVuZXIsIFJlZ2lvblNvdXJjZVNjb3BlLCBSZWdpb25Tb3VyY2VTbGljZXMgfSBmcm9tICcuL3JlZ2lvbi1zb3VyY2Utc2NvcGUnO1xuaW1wb3J0IHR5cGUgeyBSZWdpb25Tb3VyY2UsIFJlZ2lvblNvdXJjZVZpZXcgfSBmcm9tICcuLi9yZWdpb24tc291cmNlL3JlZ2lvbi1zb3VyY2UnO1xuaW1wb3J0IHR5cGUgeyBSZWdpb25JbmRleFBhZ2UsIFJlZ2lvbkluZGV4UXVlcnksIFJlZ2lvblNvdXJjZVN0eWxlIH0gZnJvbSAnLi4vcmVnaW9uLXNvdXJjZS9yZWdpb24tdGlsZXMnO1xuaW1wb3J0IHsgREVGQVVMVF9SRUdJT05fU1RZTEUsIFJlZ2lvblN0eWxlIH0gZnJvbSAnLi4vcmVnaW9uLW92ZXJsYXkvcmVnaW9uLXN0eWxlJztcblxuLyoqIFNlbGVjdGluZyBjbGFzc2VzIHRha2VzIGF0IG1vc3QgdGhpcyBtYW55IHJlZ2lvbi1zb3VyY2UgZmVhdHVyZXMgaW50byB0aGUgcmVnaW9ucy4gKi9cbmV4cG9ydCBjb25zdCBTRUxFQ1RfQ0xBU1NFU19MSU1JVCA9IDUwMDA7XG4vKiogQSByZWdpb24gc291cmNlJ3Mgb3V0bGluZXMgb24gYSBzbGljZSwgZWFjaCByaW5nJ3MgYW5kIGxpbmUncyBjbGFzcyB3aXRoIGl0IHdoZW4gcmVhZCBmb3IgYWxsLiAqL1xudHlwZSBMYWJlbGxlZE91dGxpbmVzID0gU2xpY2VPdXRsaW5lcyAmIHsgcmluZ0xhYmVscz86IHN0cmluZ1tdOyBsaW5lTGFiZWxzPzogc3RyaW5nW10gfTtcblxuLyoqIENsYXNzIHNldHMgd2hvc2UgcmVnaW9uLXNvdXJjZSBvdXRsaW5lcyBhcmUga2VwdCBmb3IgcmVidWlsZGluZyB0aGVpciBzdXJmYWNlcy4gKi9cbmNvbnN0IFNPVVJDRV9PVVRMSU5FX0NBQ0hFX1NJWkUgPSA4O1xuLyoqIENsYXNzZXMgd2hvc2UgcmVnaW9uLXNvdXJjZSBwYXJ0IG9mIHRoZSB2b2x1bWUgaXMga2VwdCAoc2VlIFJlZ2lvblN0b3JlLmNsYXNzVm9sdW1lcykuICovXG5jb25zdCBTT1VSQ0VfVk9MVU1FX0NBQ0hFX1NJWkUgPSA2NDtcblxuLyoqIEEgc2xpY2UncyByaW5ncywgZWFjaCB3aXRoIGl0cyBmZWF0dXJlIChzZWUgU2xpY2VPdXRsaW5lcy5yaW5nR3JvdXBzKSwgYW5kIGl0cyBsaW5lcy4gKi9cbmludGVyZmFjZSBTbGljZVBhcnRzIHtcbiAgcmluZ3M6IEFycmF5TGlrZTxudW1iZXI+W107XG4gIHJpbmdHcm91cHM6IG51bWJlcltdO1xuICBsaW5lczogQXJyYXlMaWtlPG51bWJlcj5bXTtcbn1cblxuLyoqXG4gKiBGZWF0dXJlIGlkcyB1bmlxdWUgYWNyb3NzIG91dGxpbmVzIHJlYWQgZnJvbSBzZXZlcmFsIHBsYWNlczogZWFjaCBjYWxsIGdpdmVzIG9uZSBwYXJ0J3NcbiAqIHJlbnVtYmVyaW5nIG9mIGl0cyBvd24gaWRzIChhIHBhcnQgd2l0aG91dCB0aGVtIGlzIG9uZSBmZWF0dXJlKS5cbiAqL1xuZnVuY3Rpb24gZmVhdHVyZUlkcygpOiAoKSA9PiAob3duOiBudW1iZXIgfCB1bmRlZmluZWQpID0+IG51bWJlciB7XG4gIGxldCBuZXh0ID0gMDtcbiAgcmV0dXJuICgpID0+IHtcbiAgICBjb25zdCBpZHMgPSBuZXcgTWFwPG51bWJlciB8IHVuZGVmaW5lZCwgbnVtYmVyPigpO1xuICAgIHJldHVybiAob3duKSA9PiB7XG4gICAgICBsZXQgaWQgPSBpZHMuZ2V0KG93bik7XG4gICAgICBpZiAoaWQgPT09IHVuZGVmaW5lZCkgaWRzLnNldChvd24sIChpZCA9IG5leHQrKykpO1xuICAgICAgcmV0dXJuIGlkO1xuICAgIH07XG4gIH07XG59XG5cbi8qKiBBIHNsaWNlJ3MgcGFydHMgYXMgb3V0bGluZXMuICovXG5mdW5jdGlvbiBzbGljZU91dGxpbmVzKHo6IG51bWJlciwgczogU2xpY2VQYXJ0cyk6IFNsaWNlT3V0bGluZXMge1xuICByZXR1cm4ge1xuICAgIHosXG4gICAgcmluZ3M6IHMucmluZ3MsXG4gICAgLi4uKHMucmluZ3MubGVuZ3RoID8geyByaW5nR3JvdXBzOiBzLnJpbmdHcm91cHMgfSA6IHt9KSxcbiAgICAuLi4ocy5saW5lcy5sZW5ndGggPyB7IGxpbmVzOiBzLmxpbmVzIH0gOiB7fSksXG4gIH07XG59XG5cbi8qKlxuICogT3V0bGluZXMgYnkgc2xpY2UgbWVyZ2VkIGludG8gb25lIGVudHJ5IHBlciBzbGljZSAocmluZ3MsIHRoZW4gbGluZXMpLCBpbiBzbGljZSBvcmRlciwgZWFjaFxuICogcGFydCdzIGZlYXR1cmVzIGFwYXJ0IGZyb20gdGhlIG90aGVycycgKHRoZXkgZmlsbCBhcyB0aGVpciB1bmlvbikuXG4gKi9cbmZ1bmN0aW9uIG1lcmdlT3V0bGluZXMocGFydHM6IHJlYWRvbmx5IFNsaWNlT3V0bGluZXNbXSk6IFNsaWNlT3V0bGluZXNbXSB7XG4gIGNvbnN0IGJ5WiA9IG5ldyBNYXA8bnVtYmVyLCBTbGljZVBhcnRzPigpO1xuICBjb25zdCBuZXh0UGFydCA9IGZlYXR1cmVJZHMoKTtcbiAgZm9yIChjb25zdCBwYXJ0IG9mIHBhcnRzKSB7XG4gICAgaWYgKCFwYXJ0LnJpbmdzLmxlbmd0aCAmJiAhcGFydC5saW5lcz8ubGVuZ3RoKSBjb250aW51ZTtcbiAgICBsZXQgc2xpY2UgPSBieVouZ2V0KHBhcnQueik7XG4gICAgaWYgKCFzbGljZSkgYnlaLnNldChwYXJ0LnosIChzbGljZSA9IHsgcmluZ3M6IFtdLCByaW5nR3JvdXBzOiBbXSwgbGluZXM6IFtdIH0pKTtcbiAgICBjb25zdCBpZCA9IG5leHRQYXJ0KCk7XG4gICAgcGFydC5yaW5ncy5mb3JFYWNoKChyLCBpKSA9PiB7XG4gICAgICBzbGljZS5yaW5ncy5wdXNoKHIpO1xuICAgICAgc2xpY2UucmluZ0dyb3Vwcy5wdXNoKGlkKHBhcnQucmluZ0dyb3Vwcz8uW2ldKSk7XG4gICAgfSk7XG4gICAgc2xpY2UubGluZXMucHVzaCguLi4ocGFydC5saW5lcyA/PyBbXSkpO1xuICB9XG4gIHJldHVybiBBcnJheS5mcm9tKGJ5WiwgKFt6LCBzXSkgPT4gc2xpY2VPdXRsaW5lcyh6LCBzKSkuc29ydCgoYSwgYikgPT4gYS56IC0gYi56KTtcbn1cblxuLyoqIFRoZSByZWdpb24gc291cmNlcycgcGFydCBvZiBhIGNsYXNzJ3Mgdm9sdW1lOiBpdHMgYXJlYSBvbiBlYWNoIHNsaWNlLCB3aXRoIHRoZSBvdXRsaW5lcy4gKi9cbmludGVyZmFjZSBTb3VyY2VWb2x1bWUge1xuICB0b3RhbDogbnVtYmVyO1xuICBzbGljZXM6IFJlYWRvbmx5TWFwPG51bWJlciwgeyBhcmVhOiBudW1iZXI7IG91dGxpbmVzOiBTbGljZU91dGxpbmVzIH0+O1xufVxuXG4vKiogT25lIHVuZG8gc3RlcDogdGhlIHJlZ2lvbiBzZXQgYW5kLCBmb3IgYSBzbGljZSB3aXRoIGEgcmVnaW9uIHNvdXJjZSwgd2hhdCB3YXMgdGFrZW4gZnJvbSBpdC4gKi9cbmludGVyZmFjZSBSZWdpb25TbmFwc2hvdCB7XG4gIHJlZ2lvbnM6IFJlZ2lvbltdO1xuICB0YWtlbjogUmVhZG9ubHlTZXQ8c3RyaW5nPjtcbn1cblxuLyoqXG4gKiBCYWNrZW5kLW5ldXRyYWwgcmVnaW9uIHN0b3JlIOKAlCB0aGUgc2luZ2xlIHNvdXJjZSBvZiB0cnV0aCBmb3IgcmVnaW9uIHN0YXRlLlxuICpcbiAqIEhvbGRzIHRoZSBuZXV0cmFsIHtAbGluayBSZWdpb259IG1vZGVsIChuZXZlciBhIGJhY2tlbmQncyBvd24gc2hhcGVcbiAqIHJlcHJlc2VudGF0aW9uKSwga2V5ZWQgcGVyIGltYWdlIHNvIHJlZ2lvbnMgcGVyc2lzdCBhcyB0aGUgdXNlciBzd2l0Y2hlc1xuICogZmlsZXMgYW5kIHN1cnZpdmUgYSBQbG90bHnih4RPcGVuU2VhZHJhZ29uIGJhY2tlbmQgc3dpdGNoIChib3RoIGJhY2tlbmRzIHJlYWRcbiAqIGFuZCB3cml0ZSAqdGhpcyogc3RvcmUsIHNvIG5vIG1pZ3JhdGlvbiBpcyBuZWVkZWQpLiBCYWNrZW5kcyBvd24gKnJlbmRlcmluZypcbiAqIGFuZCByZWFjdCB0byB7QGxpbmsgZ2V0UmVnaW9uVXBkYXRlRXZlbnR9OyB0aGlzIHNlcnZpY2Ugb3ducyAqc3RhdGUqIGFuZCB0aGVcbiAqIGVkaXRpbmcgb3BlcmF0aW9ucy5cbiAqXG4gKiBJbXBsZW1lbnRzOlxuICogIC0ge0BsaW5rIElSZWdpb25TdG9yZX0g4oCUIHRoZSBjcm9zcy1iYWNrZW5kIENSVUQvc2VsZWN0aW9uL2NvbG91ciBjb250cmFjdFxuICogICAgZXZlcnkgY29uc3VtZXIgKFJlZ2lvbiBFZGl0b3IsIHNlZ21lbnRhdGlvbiwgZXRjLikgYWxyZWFkeSB1c2VzLlxuICogIC0ge0BsaW5rIElSZWdpb25FZGl0QXBpfSDigJQgUmVnaW9uLW5hdGl2ZSBnZW9tZXRyeSBlZGl0cyAobW92ZS9yZXNpemUsIGFuZFxuICogICAgYWRkL2RlbGV0ZS9tb3ZlIHZlcnRleCkgdGhlIE9TRCBvdmVybGF5IGRyaXZlcy5cbiAqXG4gKiBDb3B5LW9uLXdyaXRlIChyZXZpZXcgUlQtMTMpOiBubyBvcGVyYXRpb24gY2hhbmdlcyBhIHN0b3JlZCB7QGxpbmsgUmVnaW9ufVxuICogKG9yIHRoZSByZWdpb25zIGFycmF5KSBpbiBwbGFjZS4gQW4gZWRpdCBidWlsZHMgYSByZXBsYWNlbWVudCDigJQgdGhlIGdlb21ldHJ5XG4gKiB0aHJvdWdoIHRoZSBwdXJlIGBtb2RlbHMvcG9seWdvbi1lZGl0YCBmdW5jdGlvbnMg4oCUIGFuZCBzd2FwcyBpdCBpbiwgc28gdGhlXG4gKiB1bmRvIGhpc3RvcnkgKHtAbGluayBSZWdpb25IaXN0b3J5fSkgY2FuIGtlZXAgc2hhbGxvdyBzbmFwc2hvdHMgdGhhdCBzaGFyZVxuICogZXZlcnkgdW50b3VjaGVkIHJlZ2lvbiBpbnN0ZWFkIG9mIGRlZXAtY2xvbmluZyB0aGUgd2hvbGUgc2V0IHBlciBzdGVwLlxuICogQ2FsbGVycyBtdXN0IGZvbGxvdyB0aGUgc2FtZSBydWxlIHdpdGggdGhlIGluc3RhbmNlcyB7QGxpbmsgZ2V0UmVnaW9uc31cbiAqIHJldHVybnM6IHRyZWF0IHRoZW0gYXMgcmVhZC1vbmx5LCBhbmQgY29tbWl0IGEgY2hhbmdlZCBjb3B5LlxuICpcbiAqIENsYXNzaWZpY2F0aW9uIGNvbG91cnMgbGl2ZSBpbiB7QGxpbmsgVmlzdWFsaXplclN0b3JlfSAoc2hhcmVkIGJ5IGJvdGhcbiAqIGJhY2tlbmRzKTsgR2VvSlNPTiBpbXBvcnQvZXhwb3J0IGlzIGBtb2RlbHMvcmVnaW9uLWdlb2pzb25gLiBBbGwgY29vcmRpbmF0ZXNcbiAqIGFyZSBpbWFnZSBwaXhlbHMuXG4gKi9cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgUmVnaW9uU3RvcmUgaW1wbGVtZW50cyBJUmVnaW9uU3RvcmUsIElSZWdpb25FZGl0QXBpLCBJUmVnaW9uU291cmNlQXBpIHtcbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgVU5ET19MSU1JVCA9IDEwO1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBVTkRPX0NPQUxFU0NFX01TID0gMjUwO1xuXG4gIC8qKiBUaGUgY3VycmVudCBpbWFnZSdzIHJlZ2lvbnMg4oCUIHRoZSBsaXZlLCBlZGl0ZWQgYXJyYXkuICovXG4gIHByaXZhdGUgcmVnaW9uczogUmVnaW9uW10gPSBbXTtcblxuICAvKipcbiAgICogVW5kby9yZWRvIGhpc3RvcnkgKGppdC11aSM4NSk6IHVwIHRvIHtAbGluayBVTkRPX0xJTUlUfSBzbmFwc2hvdHMgb2YgdGhlXG4gICAqIHJlZ2lvbiBzZXQsIGVhY2ggdGFrZW4ganVzdCAqYmVmb3JlKiBhIHJlZ2lvbi1lZGl0aW5nIGFjdGlvbjsgY29udGludW91c1xuICAgKiBnZXN0dXJlcyBhbmQgcmFwaWQgY29tbWl0cyBjb2FsZXNjZSAoc2VlIHtAbGluayBSZWdpb25IaXN0b3J5fSkuIFNuYXBzaG90c1xuICAgKiBhcmUgc2hhbGxvdyDigJQgdGhlIHJlZ2lvbnMgYXJyYXkgYXMgaXQgd2FzIOKAlCB3aGljaCBpcyBzYWZlIGJlY2F1c2Ugbm90aGluZ1xuICAgKiBoZXJlIG11dGF0ZXMgYSByZWdpb24gb3IgYW4gYXJyYXkgaW4gcGxhY2UgKFJULTEzKS4gSGlzdG9yeSBuZXZlciBjcm9zc2VzIGFuXG4gICAqIGltYWdlIGxvYWQvc3dpdGNoIOKAlCB7QGxpbmsgcmVzZXRVbmRvSGlzdG9yeX0gY2xlYXJzIGl0LlxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBoaXN0b3J5ID0gbmV3IFJlZ2lvbkhpc3Rvcnk8UmVnaW9uU25hcHNob3Q+KFxuICAgIFJlZ2lvblN0b3JlLlVORE9fTElNSVQsXG4gICAgUmVnaW9uU3RvcmUuVU5ET19DT0FMRVNDRV9NUyxcbiAgKTtcblxuICAvKiogTW9ub3RvbmljIGlkIHNvdXJjZSDigJQgaWRzIG5ldmVyIHJlcGVhdCB3aXRoaW4gdGhlIHNlcnZpY2UgbGlmZXRpbWUsIHNvXG4gICAqICBzZWxlY3Rpb24gc3RheXMgY29ycmVjdCBhY3Jvc3MgZGVsZXRlL2FkZCBjeWNsZXMgZXZlbiB3aGVuIG5hbWVzIGNvbGxpZGUuICovXG4gIHByaXZhdGUgbmV4dElkID0gMTtcblxuICBwcml2YXRlIHNob3dTaGFwZUxhYmVsID0gZmFsc2U7XG4gIHByaXZhdGUgc2hhcGVDb2xvciA9ICcjMDBGRkZGJztcbiAgcHJpdmF0ZSBmaWxsQ29sb3IgPSAnI2ZmMDBmZic7XG4gIHByaXZhdGUgaXNSZWdpb25TYXZlZE9uID0gdHJ1ZTtcblxuICAvKipcbiAgICogUGVyLWltYWdlIGNhY2hlIGFuZCwgZm9yIHotc3RhY2tzLCBwZXItc2xpY2UgcmVnaW9ucyAoaml0LXVpIzkzKS4gSW4gc3RhY2tcbiAgICogbW9kZSB0aGUgbGl2ZSBgcmVnaW9uc2AgYXJyYXkgaG9sZHMgT05FIHNsaWNlIOKAlCB0aGUgZGlzcGxheSBzbGljZSDigJQgc28gdGhlXG4gICAqIG92ZXJsYXlzLCB0aGUgc2VsZWN0aW9uIHByb2plY3Rpb24gYW5kIHRoZSBSZWdpb25zIHRhYmxlIHdvcmsgdW5jaGFuZ2VkXG4gICAqICh0aGV5IGFsbCByZWFkIHtAbGluayBnZXRSZWdpb25zfSk7IHtAbGluayBzZXREaXNwbGF5U2xpY2V9IHN3YXBzIHRoZSBsaXZlXG4gICAqIHNldCBvbiBzY3J1YiBhbmQge0BsaW5rIGdldFNsaWNlUmVnaW9uc30gZmxhdHRlbnMgZXZlcnkgc2xpY2UgKGVhY2ggdGFnZ2VkXG4gICAqIHdpdGggaXRzIHplcm8tYmFzZWQge0BsaW5rIFJlZ2lvbi56fSkgZm9yIHNhdmUvZXhwb3J0LiBPZmYgYnkgZGVmYXVsdCwgc29cbiAgICogc2luZ2xlLXBsYW5lIGltYWdlcyBhcmUgdW5hZmZlY3RlZC5cbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgc2NvcGUgPSBuZXcgUmVnaW9uU2NvcGVDYWNoZSgpO1xuXG4gIC8qKiBTZWxlY3Rpb24gYnkgcmVnaW9uICppZCogKHN0YWJsZSBhY3Jvc3MgZWRpdHMpLCBwcm9qZWN0ZWQgdG8gYXJyYXlcbiAgICogIGluZGljZXMgb24gdGhlIElSZWdpb25TdG9yZSBib3VuZGFyeS4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBzZWxlY3Rpb24gPSBuZXcgUmVnaW9uU2VsZWN0aW9uKCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVnaW9uVXBkYXRlJCA9IG5ldyBTdWJqZWN0PFJlZ2lvbltdPigpO1xuICAvKiogTm9uLWNvYWxlc2NlZCBzaWJsaW5nIG9mIHJlZ2lvblVwZGF0ZSQ6IGZpcmVzIG9uIGV2ZXJ5IGNoYW5nZSBldmVuIGR1cmluZyBhXG4gICAqICBiYXRjaGVkIGRyYWcsIHNvIGxpdmUgY29uc3VtZXJzIChpbnRlbnNpdHkgaW5zZXQpIHVwZGF0ZSBwZXIgZnJhbWUuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgcmVnaW9uTGl2ZUVkaXQkID0gbmV3IFN1YmplY3Q8UmVnaW9uW10+KCk7XG4gIC8qKiBTZWUge0BsaW5rIGdldFJlZ2lvblNldFJlcGxhY2VkJH0uICovXG4gIHByaXZhdGUgcmVhZG9ubHkgcmVnaW9uU2V0UmVwbGFjZWQkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICAvKiogRW1pdCBjb2FsZXNjaW5nIGZvciBsaXZlIGRyYWdzIChzZWUgSVJlZ2lvbkVkaXRBcGkuYmVnaW5CYXRjaCkuICovXG4gIHByaXZhdGUgYmF0Y2hEZXB0aCA9IDA7XG4gIHByaXZhdGUgcGVuZGluZ0VtaXQgPSBmYWxzZTtcblxuICAvKipcbiAgICogTGFyZ2UgcmVnaW9uIHNldHMgaGVsZCBhcyB0aWxlZCByZWdpb24gc291cmNlcyByYXRoZXIgdGhhbiBhcyByZWdpb25zIChzZWVcbiAgICoge0BsaW5rIGF0dGFjaFJlZ2lvblNvdXJjZX0pOiBwZXIgaW1hZ2UgYW5kIHNsaWNlLCB3aXRoIHRoZSBpZHMgdGFrZW4gb3V0IG9mIGVhY2guXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHNvdXJjZXMgPSBuZXcgUmVnaW9uU291cmNlU2NvcGUoKTtcbiAgcHJpdmF0ZSByZWFkb25seSBzb3VyY2VWaWV3JCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8UmVnaW9uU291cmNlVmlldyB8IG51bGw+KG51bGwpO1xuICAvKiogVGhlIHJlZ2lvbiBsb29rIHRoZSB1c2VyIGNob3NlIChvdmVycmlkZXMgdGhlIHNvdXJjZSdzIGhpbnQpLCBmaWVsZCBieSBmaWVsZC4gKi9cbiAgcHJpdmF0ZSB1c2VyU3R5bGU6IFBhcnRpYWw8UmVnaW9uU3R5bGU+ID0ge307XG4gIC8qKiBUaGUgY3VycmVudCBzb3VyY2UncyBzdHlsZSBoaW50LiAqL1xuICBwcml2YXRlIGhpbnRTdHlsZTogUmVnaW9uU291cmNlU3R5bGUgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVnaW9uU3R5bGUkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxSZWdpb25TdHlsZT4oREVGQVVMVF9SRUdJT05fU1RZTEUpO1xuICAvKiogQnVtcGVkIG9uIGV2ZXJ5IGNoYW5nZSBvZiB0aGUgc2xpY2UncyBzb3VyY2UsIHNvIGEgbGF0ZSBvcGVuIGlzIGRyb3BwZWQuICovXG4gIHByaXZhdGUgc291cmNlR2VuZXJhdGlvbiA9IDA7XG4gIC8qKiBUaGUgc291cmNlIGxhc3QgcHVibGlzaGVkIGFzIHRoZSB2aWV3OiBhIHNvdXJjZSBzaG93biBhZ2FpbiBkb2VzIG5vdCB0dXJuIHRoZSBsYWJlbHMgYmFjayBvbi4gKi9cbiAgcHJpdmF0ZSBzaG93blNvdXJjZTogUmVnaW9uU291cmNlIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBCdW1wZWQgd2hlbiBhIHJlZ2lvbiBzb3VyY2UgaXMgYXR0YWNoZWQgb3IgZHJvcHBlZDogd2hhdCBpcyByZWFkIGZyb20gdGhlIHNvdXJjZXMgaXMgc3RhbGUuICovXG4gIHByaXZhdGUgc291cmNlc1ZlcnNpb24gPSAwO1xuXG4gIC8qKlxuICAgKiBUaGUgcmVnaW9uIHNvdXJjZXMnIHBhcnQgb2Yge0BsaW5rIGNsYXNzVm9sdW1lc30sIGJ5IGNsYXNzIGFuZCB3aGF0IHRoZSBzb3VyY2VzIGhvbGQgKHNlZVxuICAgKiB7QGxpbmsgc291cmNlU3RhdGVLZXl9KTogYW4gZWRpdCBvZiB0aGUgcmVnaW9ucyBsZWF2ZXMgaXQsIHNvIHRoZSB2b2x1bWVzIG9mIGEgc2xpY2UgYmVpbmcgZHJhd25cbiAgICogb24gY29zdCBubyBzb3VyY2UgcmVhZHMuXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHNvdXJjZVZvbHVtZUNhY2hlID0gbmV3IE1hcDxzdHJpbmcsIFByb21pc2U8U291cmNlVm9sdW1lPj4oKTtcbiAgLyoqIFRoZSByZWdpb24gc291cmNlcycgb3V0bGluZXMgb2YgdGhlIGNsYXNzIHNldHMgcmVjb25zdHJ1Y3RlZCBsYXN0IChzZWUge0BsaW5rIHNvdXJjZU91dGxpbmVzfSkuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgc291cmNlT3V0bGluZUNhY2hlID0gbmV3IE1hcDxzdHJpbmcsIFByb21pc2U8TGFiZWxsZWRPdXRsaW5lc1tdPj4oKTtcblxuICAvKiogVGhlIGNsYXNzZXMgaGlkZGVuIGZyb20gdmlldyAobmFtZXMgYXMgZ2l2ZW4pOyBldmVyeSBjbGFzcyBpcyBzaG93biBhdCBmaXJzdC4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBoaWRkZW5DbGFzc2VzJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8UmVhZG9ubHlTZXQ8c3RyaW5nPj4obmV3IFNldCgpKTtcbiAgLyoqIHtAbGluayBoaWRkZW5DbGFzc2VzJH0gYnkge0BsaW5rIHByZXNldEtleX0sIGFzIGEgcmVnaW9uJ3MgbGFiZWwgaXMgbWF0Y2hlZC4gKi9cbiAgcHJpdmF0ZSBoaWRkZW5LZXlzOiBSZWFkb25seVNldDxzdHJpbmc+ID0gbmV3IFNldCgpO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgc3RvcmU6IFZpc3VhbGl6ZXJTdG9yZSkge1xuICAgIC8vIEEgY2xhc3MgY29sb3VyIGNoYW5nZSByZWNvbG91cnMgdGhlIHNvdXJjZSdzIGZlYXR1cmVzIGFzIGl0IHJlY29sb3VycyByZWdpb25zLlxuICAgIHRoaXMuc3RvcmUuZ2V0UHJlc2V0U2V0JCgpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICBjb25zdCB2aWV3ID0gdGhpcy5zb3VyY2VWaWV3JC52YWx1ZTtcbiAgICAgIGlmICh2aWV3KSB0aGlzLnNvdXJjZVZpZXckLm5leHQoeyAuLi52aWV3IH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLy8g4pSA4pSAIElSZWdpb25TdG9yZTogQ1JVRCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKipcbiAgICogUmVwbGFjZSAob3IsIHdpdGggYGFwcGVuZGAsIGFkZCB0bykgdGhlIGN1cnJlbnQgaW1hZ2UncyByZWdpb25zLiBNaW50cyBpZHNcbiAgICogYW5kIGRlZmF1bHQgbmFtZXMsIGFwcGxpZXMgc3RvcmVkIGNsYXNzaWZpY2F0aW9uIGNvbG91cnMsIGFuZCBlbWl0cy4gV2hlblxuICAgKiBgaXNSZWdpb25TYXZlT25gIGlzIGZhbHNlIHRoZSByZWdpb25zIGFyZSBzaG93biB0cmFuc2llbnRseSAoZW1pdHRlZCkgYnV0XG4gICAqIG5vdCBzdG9yZWQg4oCUIG1pcnJvcnMgdGhlIHByZXZpb3VzIFBsb3RseSBiZWhhdmlvdXIuXG4gICAqL1xuICBzZXRSZWdpb25zKFxuICAgIHJlZ2lvbnM6IFJlZ2lvbltdLFxuICAgIHNob3dSZWdpb25MYWJlbD86IGJvb2xlYW4sXG4gICAgaXNSZWdpb25TYXZlT24/OiBib29sZWFuLFxuICAgIGZpbGxDb2xvcj86IHN0cmluZyxcbiAgICBhcHBlbmQ6IGJvb2xlYW4gPSBmYWxzZSxcbiAgKTogdm9pZCB7XG4gICAgaWYgKHNob3dSZWdpb25MYWJlbCA9PT0gdW5kZWZpbmVkKSBzaG93UmVnaW9uTGFiZWwgPSB0aGlzLnNob3dTaGFwZUxhYmVsO1xuICAgIGlmIChpc1JlZ2lvblNhdmVPbiA9PT0gdW5kZWZpbmVkKSBpc1JlZ2lvblNhdmVPbiA9IHRoaXMuaXNSZWdpb25TYXZlZE9uO1xuICAgIGlmIChmaWxsQ29sb3IgPT09IHVuZGVmaW5lZCkgZmlsbENvbG9yID0gdGhpcy5maWxsQ29sb3I7XG5cbiAgICByZWdpb25zID0gdGhpcy5hZG1pdChyZWdpb25zKTtcblxuICAgIHRoaXMuaXNSZWdpb25TYXZlZE9uID0gaXNSZWdpb25TYXZlT247XG4gICAgaWYgKGlzUmVnaW9uU2F2ZU9uKSB7XG4gICAgICB0aGlzLnJlY29yZFVuZG9TbmFwc2hvdCgpO1xuICAgICAgaWYgKHRoaXMuc2hvd1NoYXBlTGFiZWwgIT09IHNob3dSZWdpb25MYWJlbCkge1xuICAgICAgICB0aGlzLnNob3dTaGFwZUxhYmVsID0gc2hvd1JlZ2lvbkxhYmVsO1xuICAgICAgICB0aGlzLnJlcHVibGlzaFZpZXcoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZmlsbENvbG9yID0gZmlsbENvbG9yO1xuICAgICAgaWYgKGFwcGVuZCkge1xuICAgICAgICAvLyBSZWplY3QgYnkgaWQgY29sbGlzaW9uIChhbHJlYWR5IHRyYWNrZWQpIG9yIGdlb21ldHJ5IGVxdWFsaXR5IChzYW1lXG4gICAgICAgIC8vIGNvb3JkaW5hdGVzKSDigJQgdGhlIGZpbmQgYnV0dG9uIGNhbiBwdXNoIHRoZSBzYW1lIHJlZ2lvbiByZXBlYXRlZGx5LlxuICAgICAgICBjb25zdCBhZGRlZCA9IHJlZ2lvbnMuZmlsdGVyKFxuICAgICAgICAgIChyKSA9PiAhdGhpcy5yZWdpb25zLnNvbWUoKGV4aXN0aW5nKSA9PiBleGlzdGluZy5pZCA9PT0gci5pZCB8fCByZWdpb25zRXF1YWwoZXhpc3RpbmcsIHIpKSxcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5yZWdpb25zID0gdGhpcy5yZWdpb25zLmNvbmNhdChhZGRlZCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnJlZ2lvbnMgPSByZWdpb25zLnNsaWNlKCk7XG4gICAgICB9XG4gICAgICB0aGlzLnN5bmNDYWNoZSgpO1xuICAgICAgdGhpcy5lbWl0U2VsZWN0aW9uKCk7XG4gICAgICB0aGlzLmVtaXQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVHJhbnNpZW50IGRpc3BsYXkgb25seSDigJQgZG9uJ3QgdG91Y2ggc3RvcmVkIHN0YXRlLlxuICAgICAgdGhpcy5yZWdpb25VcGRhdGUkLm5leHQocmVnaW9ucy5zbGljZSgpKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVGhlIGNhbm9uaWNhbCBhY2Nlc3NvcjogdGhlIGN1cnJlbnQgaW1hZ2UncyByZWdpb25zLiBBIGZyZXNoIGFycmF5LCBidXQgdGhlXG4gICAqIGluc3RhbmNlcyBhcmUgdGhlIHN0b3JlZCBvbmVzLCBzaGFyZWQgd2l0aCB0aGUgdW5kbyBoaXN0b3J5OiB0cmVhdCB0aGVtIGFzXG4gICAqIHJlYWQtb25seSBhbmQgY2hhbmdlIGEgcmVnaW9uIHRocm91Z2ggdGhlIHN0b3JlJ3Mgb3BlcmF0aW9ucyAob3IgYnlcbiAgICogY29tbWl0dGluZyBhIGNvcHkpLiBUeXBlZCBgUmVnaW9uW11gIHJhdGhlciB0aGFuXG4gICAqIGBSZWFkb25seUFycmF5PFJlYWRvbmx5PFJlZ2lvbj4+YCBiZWNhdXNlIHRoZSBJUmVnaW9uU3RvcmUgY29udHJhY3QgYW5kIHRoZVxuICAgKiBiYWNrZW5kcyBzdGlsbCB0YWtlIGEgbXV0YWJsZSBhcnJheS5cbiAgICovXG4gIGdldFJlZ2lvbnMoKTogUmVnaW9uW10ge1xuICAgIHJldHVybiB0aGlzLnJlZ2lvbnMuc2xpY2UoKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBQZXItc2xpY2UgcmVnaW9ucyBmb3Igei1zdGFja3MgKGppdC11aSM5Mykg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqIFRydWUgd2hpbGUgYSB6LXN0YWNrIGlzIGxvYWRlZCBhbmQgdGhlIHN0b3JlIGhvbGRzIHJlZ2lvbnMgcGVyIHNsaWNlLiAqL1xuICBpc1N0YWNrTW9kZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zY29wZS5zdGFja01vZGU7XG4gIH1cblxuICAvKiogVGhlIGN1cnJlbnQgZGlzcGxheSBzbGljZSAoemVyby1iYXNlZCkuICovXG4gIGdldERpc3BsYXlTbGljZSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnNjb3BlLmRpc3BsYXlTbGljZTtcbiAgfVxuXG4gIC8qKiBIb3cgdGhlIGN1cnJlbnQgc3RhY2sgcGVyc2lzdHMgdG8gZGlzayAoaml0LXVpIzkzKTogYGNvbWJpbmVkYCA9IG9uZVxuICAgKiAgei1pbmRleGVkIGdlb2pzb24gKHNpbmdsZS1maWxlIHotc3RhY2spOyBgcGVyLXNsaWNlLWZpbGVgID0gb25lIGdlb2pzb24gcGVyXG4gICAqICBzbGljZS1maWxlIChmb2xkZXIgc3RhY2spLiBNZWFuaW5nbGVzcyBvdXRzaWRlIHN0YWNrIG1vZGUuICovXG4gIGdldFN0YWNrU2F2ZUxheW91dCgpOiBTdGFja1NhdmVMYXlvdXQge1xuICAgIHJldHVybiB0aGlzLnNjb3BlLnNhdmVMYXlvdXQ7XG4gIH1cblxuICAvKipcbiAgICogRW50ZXIgcGVyLXNsaWNlIHN0YWNrIG1vZGUuIGBzbGljZXNgIG1hcHMgZWFjaCB6ZXJvLWJhc2VkIHNsaWNlIGluZGV4IHRvXG4gICAqIHRoZSByZWdpb25zIGltcG9ydGVkIGZvciB0aGF0IHNsaWNlOyB0aGUgc3RvcmUgbWFrZXMgYGluaXRpYWxaYCdzIHNsaWNlIHRoZVxuICAgKiBsaXZlIHNldCwgc28gdGhlIG92ZXJsYXlzIC8gc2VsZWN0aW9uIC8gUmVnaW9ucyB0YWJsZSBhcmUgdW5jaGFuZ2VkICh0aGV5XG4gICAqIHN0aWxsIHJlYWQge0BsaW5rIGdldFJlZ2lvbnN9KS4gRnJlc2hseS1jcmVhdGVkIHJlZ2lvbnMgYXJlIHRhZ2dlZCB3aXRoIHRoZVxuICAgKiBjdXJyZW50IHNsaWNlIHNvIHRoZXkgcGVyc2lzdCBvbiBpdCwgYW5kIHtAbGluayBnZXRTbGljZVJlZ2lvbnN9IHJldHVybnNcbiAgICogZXZlcnkgc2xpY2UgZm9yIHNhdmUvZXhwb3J0LiBJZHMvbmFtZXMvY2xhc3NpZmljYXRpb24gY29sb3VycyBhcmUgbWludGVkXG4gICAqIGV4YWN0bHkgYXMge0BsaW5rIHNldFJlZ2lvbnN9IGRvZXMuXG4gICAqL1xuICBlbnRlclN0YWNrTW9kZShzbGljZXM6IE1hcDxudW1iZXIsIFJlZ2lvbltdPiwgaW5pdGlhbFogPSAwLCBzYXZlTGF5b3V0OiBTdGFja1NhdmVMYXlvdXQgPSAnY29tYmluZWQnKTogdm9pZCB7XG4gICAgY29uc3QgYWRtaXR0ZWQgPSBuZXcgTWFwPG51bWJlciwgUmVnaW9uW10+KCk7XG4gICAgZm9yIChjb25zdCBbeiwgcmVnc10gb2Ygc2xpY2VzKSBhZG1pdHRlZC5zZXQoeiwgdGhpcy5ub3JtYWxpemVTbGljZShyZWdzIHx8IFtdLCB6KSk7XG4gICAgdGhpcy5yZWdpb25zID0gdGhpcy5zY29wZS5lbnRlclN0YWNrKGFkbWl0dGVkLCBpbml0aWFsWiwgc2F2ZUxheW91dCk7XG4gICAgdGhpcy5zZWxlY3Rpb24ucmVwbGFjZShbXSk7XG4gICAgdGhpcy5zeW5jQ2FjaGUoKTtcbiAgICB0aGlzLnJlc2V0VW5kb0hpc3RvcnkoKTtcbiAgICB0aGlzLmVtaXRTZWxlY3Rpb24oKTtcbiAgICB0aGlzLmVtaXQoKTtcbiAgICB0aGlzLnJlZnJlc2hTb3VyY2VWaWV3KCk7XG4gIH1cblxuICAvKiogTGVhdmUgc3RhY2sgbW9kZSAoc2luZ2xlLXBsYW5lIGltYWdlLCBvciB0aGUgc3RhY2sgd2FzIGNsb3NlZCkuICovXG4gIGV4aXRTdGFja01vZGUoKTogdm9pZCB7XG4gICAgdGhpcy5zY29wZS5leGl0U3RhY2soKTtcbiAgICB0aGlzLnJlZnJlc2hTb3VyY2VWaWV3KCk7XG4gIH1cblxuICAvKiogVGhlIGxpdmUtc2V0IHN3YXAgb2Yge0BsaW5rIHNldERpc3BsYXlTbGljZX0uICovXG4gIHByaXZhdGUgc2hvd1NsaWNlKHo6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IG5leHQgPSB0aGlzLnNjb3BlLnNob3dTbGljZSh6LCB0aGlzLnJlZ2lvbnMpO1xuICAgIGlmICghbmV4dCkgcmV0dXJuO1xuICAgIHRoaXMucmVnaW9ucyA9IG5leHQ7XG4gICAgdGhpcy5zZWxlY3Rpb24ucmVwbGFjZShbXSk7XG4gICAgdGhpcy5zeW5jQ2FjaGUoKTtcbiAgICB0aGlzLnJlc2V0VW5kb0hpc3RvcnkoKTtcbiAgICB0aGlzLmVtaXRTZWxlY3Rpb24oKTtcbiAgICB0aGlzLmVtaXQoKTtcbiAgICB0aGlzLnJlZnJlc2hTb3VyY2VWaWV3KCk7XG4gIH1cblxuICAvKipcbiAgICogU2hvdyBhIGRpZmZlcmVudCBzbGljZTogY2FwdHVyZSB0aGUgY3VycmVudCBzbGljZSdzIChwb3NzaWJseSBlZGl0ZWQpXG4gICAqIHJlZ2lvbnMgYmFjayBpbnRvIHRoZSBwZXItc2xpY2Ugc3RvcmUsIHRoZW4gbG9hZCB0aGUgdGFyZ2V0IHNsaWNlJ3MgcmVnaW9uc1xuICAgKiBhcyB0aGUgbGl2ZSBzZXQgYW5kIGVtaXQuIFVuZG8gbmV2ZXIgY3Jvc3NlcyBhIHNsaWNlLiBPdXRzaWRlIHN0YWNrIG1vZGVcbiAgICogdGhpcyBvbmx5IHJlY29yZHMgdGhlIHJlcXVlc3RlZCBzbGljZSBpbmRleCAoYSBuby1vcCBvdGhlcndpc2U6IHNpbmdsZS1wbGFuZVxuICAgKiByZWdpb25zIHN0YXkgb24gdGhlIGRlZmF1bHQgcGxhbmUg4oCUIGFkZFJlZ2lvbiB0YWdzIFJlZ2lvbi56IG9ubHkgaW4gc3RhY2tcbiAgICogbW9kZSwgc28gdGhlIHJlY29yZGVkIGluZGV4IGlzIHVudXNlZCB1bnRpbCBhIHN0YWNrIGlzIGVudGVyZWQpLiAoaml0LXVpIzkzKVxuICAgKiBFaXRoZXIgd2F5IHtAbGluayBnZXRSZWdpb25TZXRSZXBsYWNlZCR9IGVtaXRzOiB0aGUgc2xpY2Ugb24gc2NyZWVuIGNoYW5nZWRcbiAgICogdW5kZXIgYW55IGluLXByb2dyZXNzIHRvb2wgd29yay5cbiAgICovXG4gIHNldERpc3BsYXlTbGljZSh6OiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLnNob3dTbGljZSh6KTtcbiAgICB0aGlzLnJlZ2lvblNldFJlcGxhY2VkJC5uZXh0KCk7XG4gIH1cblxuICAvKipcbiAgICogRXZlcnkgc2xpY2UncyByZWdpb25zIGZvciBzYXZlL2V4cG9ydCwgZWFjaCB0YWdnZWQgd2l0aCBpdHMgemVyby1iYXNlZFxuICAgKiBzbGljZSBpbmRleCBpbiB7QGxpbmsgUmVnaW9uLnp9LiBDYXB0dXJlcyB0aGUgY3VycmVudCBzbGljZSdzIGxpdmUgZWRpdHNcbiAgICogZmlyc3QuIFJldHVybnMgdGhlIGZsYXQgc2luZ2xlLXBsYW5lIHNldCB3aGVuIG5vdCBpbiBzdGFjayBtb2RlLiAoaml0LXVpIzkzKVxuICAgKi9cbiAgZ2V0U2xpY2VSZWdpb25zKCk6IFJlZ2lvbltdIHtcbiAgICByZXR1cm4gdGhpcy5zY29wZS5zbGljZVJlZ2lvbnModGhpcy5yZWdpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTbGljZXMgdG8gd3JpdGUgb24gYSBwZXItc2xpY2UtZmlsZSBzYXZlIChmb2xkZXIgc3RhY2ssIGppdC11aSM5Myk6IGV2ZXJ5XG4gICAqIHNsaWNlIHRoYXQgY3VycmVudGx5IGhhcyByZWdpb25zLCBQTFVTIHNsaWNlcyB0aGF0IHdlcmUgbG9hZGVkIG5vbi1lbXB0eSBidXRcbiAgICogYXJlIG5vdyBlbXB0eSAoc28gdGhlaXIgZmlsZSBpcyByZS13cml0dGVuIGVtcHR5LCBjbGVhcmluZyBhIHNsaWNlIHdob3NlXG4gICAqIHJlZ2lvbnMgdGhlIHVzZXIgZGVsZXRlZCkuIEVhY2ggcmV0dXJuZWQgcmVnaW9uIGlzIHRhZ2dlZCB3aXRoIGl0cyB6LCBhbmRcbiAgICogdGhlIGN1cnJlbnQgbGl2ZSBzbGljZSBpcyBjYXB0dXJlZCBmaXJzdC4gRW1wdHkgb3V0c2lkZSBzdGFjayBtb2RlLlxuICAgKi9cbiAgZ2V0U3RhY2tTYXZlU2xpY2VzKCk6IE1hcDxudW1iZXIsIFJlZ2lvbltdPiB7XG4gICAgY29uc3Qgc2xpY2VzID0gdGhpcy5zY29wZS5zdGFja1NhdmVTbGljZXModGhpcy5yZWdpb25zKTtcbiAgICAvLyBBIHNsaWNlIHdob3NlIHJlZ2lvbiBzb3VyY2UgbG9zdCBmZWF0dXJlcyAodGFrZW4sIGRlbGV0ZWQpIGlzIHJlLXdyaXR0ZW4gdG9vLlxuICAgIGNvbnN0IGNoYW5nZWQgPSB0aGlzLnNvdXJjZXMuc2xpY2VzV2l0aFRha2VuKHRoaXMuc2NvcGUuYWN0aXZlSW1hZ2UpLmZpbHRlcigoeikgPT4gIXNsaWNlcy5oYXMoeikpO1xuICAgIGlmICghY2hhbmdlZC5sZW5ndGgpIHJldHVybiBzbGljZXM7XG4gICAgZm9yIChjb25zdCB6IG9mIGNoYW5nZWQpIHNsaWNlcy5zZXQoeiwgW10pO1xuICAgIHJldHVybiBuZXcgTWFwKEFycmF5LmZyb20oc2xpY2VzKS5zb3J0KChhLCBiKSA9PiBhWzBdIC0gYlswXSkpO1xuICB9XG5cbiAgLyoqIE1pbnQgaWRzL25hbWVzICsgYXBwbHkgY2xhc3NpZmljYXRpb24gY29sb3VycyArIHRhZyB0aGUgc2xpY2UgaW5kZXgsIGFzXG4gICAqICB7QGxpbmsgc2V0UmVnaW9uc30gZG9lcywgZm9yIHJlZ2lvbnMgZW50ZXJpbmcgdGhlIHBlci1zbGljZSBzdG9yZS4gKi9cbiAgcHJpdmF0ZSBub3JtYWxpemVTbGljZShyZWdpb25zOiBSZWdpb25bXSwgejogbnVtYmVyKTogUmVnaW9uW10ge1xuICAgIC8vIEEgZnJlc2ggKGltcG9ydGVkKSByZWdpb24gaXMgdGFnZ2VkIGluIHBsYWNlOyBhIHN0b3JlZCBvbmUgaXMgY29waWVkLlxuICAgIHJldHVybiB0aGlzLmFkbWl0KHJlZ2lvbnMubWFwKChyKSA9PiAoci5pZCA9PSBudWxsID8gT2JqZWN0LmFzc2lnbihyLCB7IHogfSkgOiB3aXRoUmVnaW9uWihyLCB6KSkpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpb25zIGVudGVyaW5nIHRoZSBzdG9yZTogbWludCBpZHMgYW5kIGRlZmF1bHQgbmFtZXMsIGh5ZHJhdGUgSlNPTiBib3VuZHNcbiAgICogaW50byBjbGFzcyBpbnN0YW5jZXMg4oCUIGV2ZXJ5dGhpbmcgZG93bnN0cmVhbSAocmVuZGVyaW5nLCBnZW9tZXRyeSBkZS1kdXAsXG4gICAqIG1vdmVSZWdpb24sIEdlb0pTT04gZXhwb3J0KSBkaXNjcmltaW5hdGVzIHRoZW0gd2l0aCBgaW5zdGFuY2VvZmBcbiAgICogKGppdC11aSMxMjQpIOKAlCBhbmQgYXBwbHkgY2xhc3NpZmljYXRpb24gY29sb3Vycy4gQSByZWdpb24gdGhhdCBpcyBuZXcgdG9cbiAgICogdGhlIHN0b3JlIChubyBpZCB5ZXQpIGlzIGNvbXBsZXRlZCBpbiBwbGFjZTsgb25lIHRoYXQgYWxyZWFkeSBoYXMgYW4gaWQgbWF5XG4gICAqIGJlIGEgc3RvcmVkIGluc3RhbmNlIHNoYXJlZCB3aXRoIHRoZSB1bmRvIGhpc3RvcnksIHNvIGl0IGlzIGNvcGllZCBpZiBpdFxuICAgKiBjaGFuZ2VzLlxuICAgKi9cbiAgcHJpdmF0ZSBhZG1pdChyZWdpb25zOiBSZWdpb25bXSk6IFJlZ2lvbltdIHtcbiAgICBjb25zdCBmcmVzaCA9IG5ldyBTZXQ8UmVnaW9uPigpO1xuICAgIGNvbnN0IGFkbWl0dGVkID0gcmVnaW9ucy5tYXAoKHJlZ2lvbikgPT4ge1xuICAgICAgaWYgKHJlZ2lvbi5pZCA9PSBudWxsKSB7XG4gICAgICAgIHJlZ2lvbi5pZCA9IHRoaXMubmV4dElkKys7XG4gICAgICAgIGlmIChyZWdpb24ubmFtZSA9PSBudWxsKSByZWdpb24ubmFtZSA9IGBzaGFwZSR7cmVnaW9uLmlkfWA7XG4gICAgICAgIHJlZ2lvbi5ib3VuZHMgPSBoeWRyYXRlQm91bmRzKHJlZ2lvbi5ib3VuZHMpO1xuICAgICAgICBmcmVzaC5hZGQocmVnaW9uKTtcbiAgICAgICAgcmV0dXJuIHJlZ2lvbjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGJvdW5kcyA9IGh5ZHJhdGVCb3VuZHMocmVnaW9uLmJvdW5kcyk7XG4gICAgICByZXR1cm4gcmVnaW9uLm5hbWUgPT0gbnVsbCB8fCBib3VuZHMgIT09IHJlZ2lvbi5ib3VuZHNcbiAgICAgICAgPyB3aXRoUmVnaW9uUGF0Y2gocmVnaW9uLCB7IG5hbWU6IHJlZ2lvbi5uYW1lID8/IGBzaGFwZSR7cmVnaW9uLmlkfWAsIGJvdW5kcyB9KVxuICAgICAgICA6IHJlZ2lvbjtcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcy53aXRoQ2xhc3NpZmljYXRpb25Db2xvcnMoYWRtaXR0ZWQsIChyKSA9PiBmcmVzaC5oYXMocikpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlZCBwb2x5Z29ucyBwcm9qZWN0ZWQgZm9yIGltYWdlLXByb2Nlc3NpbmcgY29uc3VtZXJzIChzZWdtZW50YXRpb24sXG4gICAqIGNyb3AgcmVxdWVzdHMsIHRyYWNlIGJ1aWxkZXJzKSwgc3RyYWlnaHQgZnJvbSBlYWNoIHJlZ2lvbidzIGJvdW5kczogYVxuICAgKiByZWN0YW5nbGUncyBjb3JuZXJzLCBhIHBvbHlnb24gd2l0aCBpdHMgaG9sZXMgKGEgYsOpemllciBhcyBpdHMgY3VydmUpLCBvbmVcbiAgICogcG9seWdvbiBwZXIgcGFydCBvZiBhIG11bHRpLXBvbHlnb24uIE9wZW4gcG9seWxpbmVzIGFyZSBhbm5vdGF0aW9uLW9ubHkgYW5kXG4gICAqIGV4Y2x1ZGVkLiBDb29yZGluYXRlcyBhcmUgcm91bmRlZCB0byB3aG9sZSBwaXhlbHMuXG4gICAqL1xuICBnZXRSZWdpb25Qb2x5Z29ucygpOiBQb2x5Z29uW10ge1xuICAgIHJldHVybiB0aGlzLnJlZ2lvbnMuZmxhdE1hcCgocmVnaW9uKSA9PiByZWdpb25Qb2x5Z29ucyhyZWdpb24pKTtcbiAgfVxuXG4gIGdldFJlZ2lvblVwZGF0ZUV2ZW50KCk6IE9ic2VydmFibGU8YW55W10+IHtcbiAgICByZXR1cm4gdGhpcy5yZWdpb25VcGRhdGUkLmFzT2JzZXJ2YWJsZSgpO1xuICB9XG5cbiAgLyoqIExpdmUgKG5vbi1jb2FsZXNjZWQpIHJlZ2lvbi1jaGFuZ2Ugc3RyZWFtIOKAlCBmaXJlcyBwZXIgZnJhbWUgZHVyaW5nIGEgZHJhZy5cbiAgICogIFVzZWQgYnkgdGhlIGludGVuc2l0eS1wcm9maWxlIGluc2V0IHNvIGl0IHRyYWNrcyBsaW5lIFJPSXMgbGl2ZS4gKi9cbiAgZ2V0UmVnaW9uTGl2ZUVkaXQkKCk6IE9ic2VydmFibGU8UmVnaW9uW10+IHtcbiAgICByZXR1cm4gdGhpcy5yZWdpb25MaXZlRWRpdCQuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICAvKipcbiAgICogRW1pdHMgYWZ0ZXIgZXZlcnkge0BsaW5rIHVuZG99LCB7QGxpbmsgcmVkb30gYW5kIHtAbGluayBzZXREaXNwbGF5U2xpY2V9IGNhbGxcbiAgICogKGV2ZW4gb25lIHRoYXQgY2hhbmdlZCBub3RoaW5nKTogdGhlIHJlZ2lvbiBzZXQgd2FzIHJlcGxhY2VkIHVuZGVyIHdoYXRldmVyXG4gICAqIGEgY2FudmFzIHRvb2wgd2FzIGJ1aWxkaW5nIG9uIChhIGJydXNoIHN0cm9rZSwgYSBTQU0gcG9pbnQgcHJvbXB0KSwgc28gdGhlXG4gICAqIGJhY2tlbmRzIHJlc2V0IHRoZWlyIGNhbnZhcyB0b29scyBvbiBpdC4gTm90IGVtaXR0ZWQgZm9yIG9yZGluYXJ5IGVkaXRzIOKAlFxuICAgKiBhIHRvb2wncyBvd24gY29tbWl0IG11c3Qgbm90IHJlc2V0IGl0LlxuICAgKi9cbiAgZ2V0UmVnaW9uU2V0UmVwbGFjZWQkKCk6IE9ic2VydmFibGU8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLnJlZ2lvblNldFJlcGxhY2VkJC5hc09ic2VydmFibGUoKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBJUmVnaW9uU3RvcmU6IHNlbGVjdGlvbiDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKiogU2VsZWN0IHJlZ2lvbnMgYnkgYXJyYXkgaW5kZXggKG9yIFtdIHRvIGNsZWFyKS4gU3RvcmVkIGludGVybmFsbHkgYnkgaWRcbiAgICogIHNvIHRoZSBzZWxlY3Rpb24gc3Vydml2ZXMgc3Vic2VxdWVudCBlZGl0cy9yZW9yZGVycy4gKi9cbiAgc2V0U2VsZWN0ZWRTaGFwZUluZGljZXMoaW5kaWNlczogbnVtYmVyW10pOiB2b2lkIHtcbiAgICB0aGlzLnNlbGVjdGlvbi5zZWxlY3RJbmRpY2VzKGluZGljZXMsIHRoaXMucmVnaW9ucyk7XG4gIH1cblxuICAvKiogU2VsZWN0IGEgc2luZ2xlIHJlZ2lvbiBieSBpZGVudGl0eSAoaWQpLiBCYWNrZW5kcyBjYWxsIHRoaXMgZnJvbSB0aGVpclxuICAgKiAgYHNlbGVjdFJlZ2lvbigpYDsgdGhlIE9TRCBvdmVybGF5ICsgcmVnaW9uIGVkaXRvciBoaWdobGlnaHQgb2ZmIHRoZVxuICAgKiAgcmVzdWx0aW5nIHNlbGVjdGlvbiBlbWl0LiBOby1vcCBpZiB0aGUgcmVnaW9uIGlzbid0IGluIHRoZSBzdG9yZS4gKi9cbiAgc2VsZWN0UmVnaW9uKHJlZ2lvbjogUmVnaW9uKTogdm9pZCB7XG4gICAgaWYgKHJlZ2lvbj8uaWQgPT0gbnVsbCB8fCB0aGlzLmluZGV4T2ZJZChyZWdpb24uaWQpIDwgMCkgcmV0dXJuO1xuICAgIHRoaXMuc2VsZWN0aW9uLnJlcGxhY2UoW3JlZ2lvbi5pZF0pO1xuICAgIHRoaXMuZW1pdFNlbGVjdGlvbigpO1xuICB9XG5cbiAgZ2V0U2VsZWN0ZWRTaGFwZUluZGljZXMkKCk6IE9ic2VydmFibGU8bnVtYmVyW10+IHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3Rpb24uaW5kaWNlcyQ7XG4gIH1cblxuICAvKiogU3luY2hyb25vdXMgY3VycmVudCBzZWxlY3Rpb24gKGFycmF5IGluZGljZXMpIOKAlCBmb3IgY2FsbGVycyB0aGF0IG5lZWQgdG9cbiAgICogIHJlYWQgdGhlIHNlbGVjdGlvbiB3aXRob3V0IHN1YnNjcmliaW5nLiAqL1xuICBnZXRTZWxlY3RlZFNoYXBlSW5kaWNlcygpOiBudW1iZXJbXSB7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0aW9uLmluZGljZXM7XG4gIH1cblxuICAvKiogRGVsZXRlIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgcmVnaW9ucyBhbmQgY2xlYXIgdGhlIHNlbGVjdGlvbi4gKi9cbiAgZGVsZXRlQWN0aXZlU2hhcGUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2VsZWN0aW9uLmlkcy5sZW5ndGggPT09IDApIHJldHVybjtcbiAgICB0aGlzLnJlY29yZFVuZG9TbmFwc2hvdCgpO1xuICAgIGNvbnN0IGlkcyA9IG5ldyBTZXQodGhpcy5zZWxlY3Rpb24uaWRzKTtcbiAgICB0aGlzLnJlZ2lvbnMgPSB0aGlzLnJlZ2lvbnMuZmlsdGVyKChyKSA9PiAhaWRzLmhhcyhyLmlkKSk7XG4gICAgdGhpcy5zZWxlY3Rpb24ucmVwbGFjZShbXSk7XG4gICAgdGhpcy5zeW5jQ2FjaGUoKTtcbiAgICB0aGlzLmVtaXRTZWxlY3Rpb24oKTtcbiAgICB0aGlzLmVtaXQoKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBJUmVnaW9uU3RvcmU6IGNvbG91cnMgLyBsYWJlbHMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgZ2V0U2hvd1NoYXBlTGFiZWwoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc2hvd1NoYXBlTGFiZWw7XG4gIH1cbiAgZ2V0U2hhcGVDb2xvcigpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnNoYXBlQ29sb3I7XG4gIH1cbiAgZ2V0RmlsbENvbG9yKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuZmlsbENvbG9yO1xuICB9XG5cbiAgLyoqIFNob3cgb3IgaGlkZSByZWdpb24gbGFiZWxzIChub3Qgb24gdGhlIGNvbnRyYWN0OyBzcGVjcyBkcml2ZSBpdCBkaXJlY3RseSkuXG4gICAqICBAZGVwcmVjYXRlZCBOb3RoaW5nIGluIHRoZSBsaWJyYXJ5IGNhbGxzIGl0OyB3aWxsIGJlIHJlbW92ZWQgbmV4dCBtaW5vci4gKi9cbiAgc2V0U2hvd1NoYXBlTGFiZWwoc2hvdzogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuc2hvd1NoYXBlTGFiZWwgPSBzaG93O1xuICAgIHRoaXMucmVwdWJsaXNoVmlldygpO1xuICB9XG5cbiAgZ2V0Q2xhc3NpZmljYXRpb25Db2xvcnMoKTogTWFwPHN0cmluZywgc3RyaW5nPiB7XG4gICAgcmV0dXJuIHRoaXMuc3RvcmUuZ2V0Q2xhc3NpZmljYXRpb25Db2xvcnMoKTtcbiAgfVxuICBzZXRDbGFzc2lmaWNhdGlvbkNvbG9yKGxhYmVsOiBzdHJpbmcsIGNvbG9yOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnN0b3JlLnNldENsYXNzaWZpY2F0aW9uQ29sb3IobGFiZWwsIGNvbG9yKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBJUmVnaW9uU3RvcmU6IHVuZG8gLyByZWRvIChqaXQtdWkjODUpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKiBFbWl0cyB3aGV0aGVyIGFuIHVuZG8gc3RlcCBpcyBjdXJyZW50bHkgYXZhaWxhYmxlIOKAlCBkcml2ZXMgdGhlIHRvb2xiYXJcbiAgICogIFVuZG8gYnV0dG9uJ3MgZW5hYmxlZCBzdGF0ZSAoZ3JleWVkIG91dCB3aGVuIGZhbHNlKS4gKi9cbiAgZ2V0Q2FuVW5kbyQoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRoaXMuaGlzdG9yeS5jYW5VbmRvJDtcbiAgfVxuXG4gIC8qKiBFbWl0cyB3aGV0aGVyIGEgcmVkbyBzdGVwIGlzIGN1cnJlbnRseSBhdmFpbGFibGUg4oCUIGRyaXZlcyB0aGUgdG9vbGJhclxuICAgKiAgUmVkbyBidXR0b24ncyBlbmFibGVkIHN0YXRlLiAqL1xuICBnZXRDYW5SZWRvJCgpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy5oaXN0b3J5LmNhblJlZG8kO1xuICB9XG5cbiAgLyoqIFN5bmNocm9ub3VzIHJlYWQgb2Yge0BsaW5rIGdldENhblVuZG8kfSDigJQgdHJ1ZSB3aGVuIGF0IGxlYXN0IG9uZSByZWdpb25cbiAgICogIGFjdGlvbiBjYW4gYmUgdW5kb25lLiAqL1xuICBjYW5VbmRvKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmhpc3RvcnkuY2FuVW5kbygpO1xuICB9XG5cbiAgLyoqIFN5bmNocm9ub3VzIHJlYWQgb2Yge0BsaW5rIGdldENhblJlZG8kfSDigJQgdHJ1ZSB3aGVuIGFuIHVuZG9uZSBhY3Rpb24gY2FuXG4gICAqICBiZSByZS1hcHBsaWVkLiAqL1xuICBjYW5SZWRvKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmhpc3RvcnkuY2FuUmVkbygpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVuZG8gdGhlIG1vc3QgcmVjZW50IHJlZ2lvbiBhY3Rpb24sIHJlc3RvcmluZyB0aGUgcmVnaW9uIHNldCB0byBpdHMgc3RhdGVcbiAgICoganVzdCBiZWZvcmUgdGhhdCBhY3Rpb24gYW5kIHB1c2hpbmcgdGhlIGN1cnJlbnQgc3RhdGUgb250byB0aGUgcmVkbyBzdGFjay5cbiAgICogVXAgdG8ge0BsaW5rIFVORE9fTElNSVR9IHN0ZXBzIGFyZSByZXRhaW5lZCwgc28gdGhpcyBjYW4gYmUgY2FsbGVkIHVwIHRvXG4gICAqIHtAbGluayBVTkRPX0xJTUlUfSB0aW1lcyBpbiBhIHJvdyBiZWZvcmUgdGhlIGhpc3RvcnkgZW1wdGllcy4gTm8tb3Agd2hlblxuICAgKiBub3RoaW5nIGlzIGxlZnQgdG8gdW5kby5cbiAgICovXG4gIHVuZG8oKTogdm9pZCB7XG4gICAgY29uc3Qgc25hcHNob3QgPSB0aGlzLmhpc3RvcnkudW5kbyh0aGlzLnNuYXBzaG90KCkpO1xuICAgIGlmIChzbmFwc2hvdCkgdGhpcy5yZXN0b3JlU25hcHNob3Qoc25hcHNob3QpO1xuICAgIHRoaXMucmVnaW9uU2V0UmVwbGFjZWQkLm5leHQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWRvIHRoZSBhY3Rpb24gbW9zdCByZWNlbnRseSB1bmRvbmUsIHJlc3RvcmluZyB0aGUgcmVnaW9uIHNldCB0byB0aGUgc3RhdGVcbiAgICogaXQgaGFkIGJlZm9yZSB0aGF0IHVuZG8gYW5kIHB1c2hpbmcgdGhlIGN1cnJlbnQgc3RhdGUgYmFjayBvbnRvIHRoZSB1bmRvXG4gICAqIHN0YWNrLiBOby1vcCB3aGVuIHRoZXJlJ3Mgbm90aGluZyB0byByZWRvICh0aGUgcmVkbyBzdGFjayBpcyBjbGVhcmVkIGJ5IGFueVxuICAgKiBmcmVzaCByZWdpb24gYWN0aW9uKS5cbiAgICovXG4gIHJlZG8oKTogdm9pZCB7XG4gICAgY29uc3Qgc25hcHNob3QgPSB0aGlzLmhpc3RvcnkucmVkbyh0aGlzLnNuYXBzaG90KCkpO1xuICAgIGlmIChzbmFwc2hvdCkgdGhpcy5yZXN0b3JlU25hcHNob3Qoc25hcHNob3QpO1xuICAgIHRoaXMucmVnaW9uU2V0UmVwbGFjZWQkLm5leHQoKTtcbiAgfVxuXG4gIC8qKiBEaXNjYXJkIHRoZSB1bmRvL3JlZG8gaGlzdG9yeSAoZS5nLiBvbiBpbWFnZSBsb2FkL3N3aXRjaCDigJQgaGlzdG9yeSBuZXZlclxuICAgKiAgY3Jvc3NlcyBpbWFnZXMpLiAqL1xuICByZXNldFVuZG9IaXN0b3J5KCk6IHZvaWQge1xuICAgIHRoaXMuaGlzdG9yeS5yZXNldCgpO1xuICB9XG5cbiAgLyoqIE1ha2UgYHNuYXBzaG90YCB0aGUgbGl2ZSByZWdpb24gc2V0IGFuZCBub3RpZnkgYm90aCBiYWNrZW5kcy4gU2hhcmVkIGJ5XG4gICAqICB7QGxpbmsgdW5kb30gYW5kIHtAbGluayByZWRvfTsgbm90aGluZyByZWNvcmRzIGhpc3Rvcnkgd2hpbGUgaXQgcnVucy4gKi9cbiAgcHJpdmF0ZSByZXN0b3JlU25hcHNob3Qoc25hcHNob3Q6IFJlZ2lvblNuYXBzaG90KTogdm9pZCB7XG4gICAgdGhpcy5oaXN0b3J5LnJlc3RvcmUoKCkgPT4ge1xuICAgICAgdGhpcy5yZWdpb25zID0gc25hcHNob3QucmVnaW9ucy5zbGljZSgpO1xuICAgICAgdGhpcy5zZXRUYWtlbihzbmFwc2hvdC50YWtlbik7XG4gICAgICB0aGlzLnN5bmNDYWNoZSgpO1xuICAgICAgLy8gRHJvcHMgYW55IHNlbGVjdGVkIGlkcyB0aGUgcmVzdG9yZWQgc2V0IG5vIGxvbmdlciBjb250YWlucy5cbiAgICAgIHRoaXMuZW1pdFNlbGVjdGlvbigpO1xuICAgIH0pO1xuICAgIC8vIE5vdGlmeSB0aGUgbGl2ZSArIGNvYWxlc2NlZCBzdHJlYW1zIHNvIHdoaWNoZXZlciBiYWNrZW5kIGlzIG9uIHNjcmVlblxuICAgIC8vIHJlLXJlbmRlcnMgZnJvbSB0aGUgcmVzdG9yZWQgc3RvcmUgc3RhdGUuXG4gICAgdGhpcy5yZWdpb25MaXZlRWRpdCQubmV4dCh0aGlzLnJlZ2lvbnMuc2xpY2UoKSk7XG4gICAgdGhpcy5yZWdpb25VcGRhdGUkLm5leHQodGhpcy5nZXRSZWdpb25zKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIENhcHR1cmUgdGhlIHByZS1hY3Rpb24gcmVnaW9uIHNldCBpbnRvIHRoZSBib3VuZGVkIHVuZG8gaGlzdG9yeS4gQ2FsbGVkIGF0XG4gICAqIHRoZSB0b3Agb2YgZXZlcnkgbXV0YXRpbmcgb3BlcmF0aW9uLCAqYmVmb3JlKiBpdCBjaGFuZ2VzIGByZWdpb25zYC4gVGhlXG4gICAqIHNuYXBzaG90IGlzIHRoZSBhcnJheSBpdHNlbGY6IGV2ZXJ5IG9wZXJhdGlvbiByZXBsYWNlcyBgcmVnaW9uc2AgKGFuZCBhbnlcbiAgICogcmVnaW9uIGl0IGVkaXRzKSByYXRoZXIgdGhhbiBjaGFuZ2luZyB0aGVtLCBzbyBpdCBuZXZlciBjaGFuZ2VzIGFmdGVyIHRoaXMuXG4gICAqL1xuICBwcml2YXRlIHJlY29yZFVuZG9TbmFwc2hvdCgpOiB2b2lkIHtcbiAgICB0aGlzLmhpc3RvcnkucmVjb3JkKHRoaXMuc25hcHNob3QoKSk7XG4gIH1cblxuICAvKiogVGhlIHN0YXRlIGFuIHVuZG8gc3RlcCByZXN0b3Jlcy4gKi9cbiAgcHJpdmF0ZSBzbmFwc2hvdCgpOiBSZWdpb25TbmFwc2hvdCB7XG4gICAgcmV0dXJuIHsgcmVnaW9uczogdGhpcy5yZWdpb25zLCB0YWtlbjogdGhpcy5jdXJyZW50VGFrZW4oKSB9O1xuICB9XG5cbiAgLy8g4pSA4pSAIElSZWdpb25TdG9yZTogR2VvSlNPTiBJL08gKG1vZGVscy9yZWdpb24tZ2VvanNvbikg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqIFBhcnNlIEdlb0pTT04gaW50byByZWdpb25zLCByZW1lbWJlcmluZyB0aGUgY2xhc3MgY29sb3VycyB0aGUgZmlsZSBjYXJyaWVzIHNvIHRoZXkgYXJlXG4gICAqICBrZXB0IGZvciBjbGFzc2VzIHdpdGggbm8gcHJlc2V0IChzZWUgVmlzdWFsaXplclN0b3JlLnJlbWVtYmVySW1wb3J0ZWRDbGFzc0NvbG9ycykuICovXG4gIGltcG9ydFJlZ2lvbnMoZ2VvSnNvblN0cjogc3RyaW5nKTogUmVnaW9uW10ge1xuICAgIGNvbnN0IHJlZ2lvbnMgPSByZWdpb25zRnJvbUdlb0pzb24oZ2VvSnNvblN0cik7XG4gICAgY29uc3QgY29sb3JzID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcbiAgICBmb3IgKGNvbnN0IHIgb2YgcmVnaW9ucykge1xuICAgICAgaWYgKHIubGFiZWwgJiYgci5jb2xvciAmJiAhY29sb3JzLmhhcyhyLmxhYmVsKSkgY29sb3JzLnNldChyLmxhYmVsLCByLmNvbG9yKTtcbiAgICB9XG4gICAgaWYgKGNvbG9ycy5zaXplKSB0aGlzLnN0b3JlLnJlbWVtYmVySW1wb3J0ZWRDbGFzc0NvbG9ycyhjb2xvcnMpO1xuICAgIHJldHVybiByZWdpb25zO1xuICB9XG4gIC8qKiBEb3dubG9hZCBgcmVnaW9uc2AgYXMgR2VvSlNPTiwgbmFtZWQgYWZ0ZXIgYGZpbGVOYW1lYCAoZXh0ZW5zaW9uXG4gICAqICByZXBsYWNlZCBieSBgLmdlb2pzb25gKSBvciBgcm9pcy5nZW9qc29uYCB3aXRob3V0IG9uZS4gKi9cbiAgZXhwb3J0UmVnaW9ucyhyZWdpb25zOiBSZWdpb25bXSwgZmlsZU5hbWU/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBkb3dubG9hZEdlb0pzb24ocmVnaW9uc1RvR2VvSnNvbihyZWdpb25zKSwgZmlsZU5hbWUpO1xuICB9XG4gIGdldEdlb0pzb25TdHJpbmcocmVnaW9uczogUmVnaW9uW10pOiBzdHJpbmcge1xuICAgIHJldHVybiByZWdpb25zVG9HZW9Kc29uKHJlZ2lvbnMpO1xuICB9XG5cbiAgLy8g4pSA4pSAIElSZWdpb25FZGl0QXBpOiBzdHJ1Y3R1cmFsIGVkaXRzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIGFkZFJlZ2lvbihyZWdpb246IFJlZ2lvbik6IG51bWJlciB7XG4gICAgdGhpcy5yZWNvcmRVbmRvU25hcHNob3QoKTtcbiAgICBpZiAocmVnaW9uLmlkID09IG51bGwpIHJlZ2lvbi5pZCA9IHRoaXMubmV4dElkKys7XG4gICAgaWYgKHJlZ2lvbi5uYW1lID09IG51bGwpIHJlZ2lvbi5uYW1lID0gYHNoYXBlJHtyZWdpb24uaWR9YDtcbiAgICByZWdpb24uYm91bmRzID0gaHlkcmF0ZUJvdW5kcyhyZWdpb24uYm91bmRzKTsgLy8gaml0LXVpIzEyNFxuICAgIC8vIEEgcmVnaW9uIGRyYXduIG9uIGEgc3RhY2sgYmVsb25ncyB0byB0aGUgc2xpY2UgY3VycmVudGx5IGRpc3BsYXllZCwgc29cbiAgICAvLyBpdCBzYXZlcy9yZWxvYWRzIG9uIHRoYXQgc2xpY2UgKGppdC11aSM5MykuIE5vLW9wIGZvciBzaW5nbGUtcGxhbmUgaW1hZ2VzXG4gICAgLy8gKHRoZSBkaXNwbGF5IHNsaWNlIHN0YXlzIDApLlxuICAgIGlmICh0aGlzLnNjb3BlLnN0YWNrTW9kZSkgcmVnaW9uLnogPSB0aGlzLnNjb3BlLmRpc3BsYXlTbGljZTtcbiAgICAvLyBUaGUgY2FsbGVyJ3MgaW5zdGFuY2UgYmVjb21lcyB0aGUgc3RvcmVkIG9uZSAoY29tcGxldGVkIGluIHBsYWNlKS5cbiAgICBjb25zdCBbc3RvcmVkXSA9IHRoaXMud2l0aENsYXNzaWZpY2F0aW9uQ29sb3JzKFtyZWdpb25dLCAoKSA9PiB0cnVlKTtcbiAgICB0aGlzLnJlZ2lvbnMgPSBbLi4udGhpcy5yZWdpb25zLCBzdG9yZWRdO1xuICAgIHRoaXMuc2VsZWN0aW9uLnJlcGxhY2UoW3N0b3JlZC5pZF0pO1xuICAgIHRoaXMuc3luY0NhY2hlKCk7XG4gICAgdGhpcy5lbWl0U2VsZWN0aW9uKCk7XG4gICAgdGhpcy5lbWl0KCk7XG4gICAgcmV0dXJuIHN0b3JlZC5pZDtcbiAgfVxuXG4gIHJlbW92ZVJlZ2lvbihpZDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5yZW1vdmVSZWdpb25zKFtpZF0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSB0aGUgcmVnaW9ucyB3aXRoIHRoZXNlIGlkcywgaWYgcHJlc2VudC4gV2l0aCBgeyByZWNvcmRVbmRvOiBmYWxzZSB9YFxuICAgKiBubyB1bmRvIHN0ZXAgaXMgdGFrZW4g4oCUIGZvciBjbGVhcmluZyB0cmFuc2llbnQgc2hhcGVzIHRoYXQgd2VyZSBuZXZlciB0aGVcbiAgICogdXNlcidzIHdvcmsgKHRoZSAzRCB2aWV3J3Mgc2NyZWVuLXNwYWNlIGxhc3NvcyBvbiBhbiBvcmJpdCwgTkFQQVJJLVNWQy0xMSkuXG4gICAqL1xuICByZW1vdmVSZWdpb25zKGlkczogSXRlcmFibGU8bnVtYmVyPiwgb3B0czogeyByZWNvcmRVbmRvPzogYm9vbGVhbiB9ID0ge30pOiB2b2lkIHtcbiAgICBjb25zdCBkcm9wID0gbmV3IFNldChpZHMpO1xuICAgIGlmICghdGhpcy5yZWdpb25zLnNvbWUoKHIpID0+IGRyb3AuaGFzKHIuaWQpKSkgcmV0dXJuO1xuICAgIGlmIChvcHRzLnJlY29yZFVuZG8gIT09IGZhbHNlKSB0aGlzLnJlY29yZFVuZG9TbmFwc2hvdCgpO1xuICAgIHRoaXMucmVnaW9ucyA9IHRoaXMucmVnaW9ucy5maWx0ZXIoKHIpID0+ICFkcm9wLmhhcyhyLmlkKSk7XG4gICAgdGhpcy5zZWxlY3Rpb24ucmV0YWluKChzKSA9PiAhZHJvcC5oYXMocykpO1xuICAgIHRoaXMuc3luY0NhY2hlKCk7XG4gICAgdGhpcy5lbWl0U2VsZWN0aW9uKCk7XG4gICAgdGhpcy5lbWl0KCk7XG4gIH1cblxuICB1cGRhdGVCb3VuZHMoaWQ6IG51bWJlciwgYm91bmRzOiBSZWN0YW5nbGUgfCBQb2x5Z29uIHwgTXVsdGlQb2x5Z29uKTogdm9pZCB7XG4gICAgY29uc3QgciA9IHRoaXMuZmluZEJ5SWQoaWQpO1xuICAgIGlmICghcikgcmV0dXJuO1xuICAgIHRoaXMucmVjb3JkVW5kb1NuYXBzaG90KCk7XG4gICAgLy8gQSBjb3B5LCBzbyB0aGUgY2FsbGVyIGNhbiBrZWVwIHVzaW5nIChhbmQgY2hhbmdpbmcpIHRoZSBib3VuZHMgaXQgcGFzc2VkLlxuICAgIHRoaXMucmVwbGFjZVJlZ2lvbihyZXBsYWNlQm91bmRzKHIsIGNsb25lQm91bmRzKGJvdW5kcykpKTtcbiAgfVxuXG4gIG1vdmVSZWdpb24oaWQ6IG51bWJlciwgZHg6IG51bWJlciwgZHk6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHIgPSB0aGlzLmZpbmRCeUlkKGlkKTtcbiAgICBpZiAoIXIgfHwgIXIuYm91bmRzKSByZXR1cm47XG4gICAgdGhpcy5yZWNvcmRVbmRvU25hcHNob3QoKTtcbiAgICAvLyBFdmVyeSBwYXJ0IChhbmQgaXRzIGhvbGVzKSBtb3ZlcyB0b2dldGhlciAoaml0LXVpIzg1KS5cbiAgICB0aGlzLnJlcGxhY2VSZWdpb24ocmVwbGFjZUJvdW5kcyhyLCBlZGl0LnRyYW5zbGF0ZUJvdW5kcyhyLmJvdW5kcywgZHgsIGR5KSkpO1xuICB9XG5cbiAgLy8g4pSA4pSAIElSZWdpb25FZGl0QXBpOiB2ZXJ0ZXggZWRpdHMgKHBvbHlnb25zIG9ubHkpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAvLyBFYWNoIG9uZSBpcyBhIHB1cmUgY29weS1vbi13cml0ZSBlZGl0IGZyb20gbW9kZWxzL3BvbHlnb24tZWRpdDsgYSBudWxsXG4gIC8vIHJlc3VsdCAob3V0IG9mIHJhbmdlLCB3b3VsZCBkZWdlbmVyYXRlKSByZWNvcmRzIG5vdGhpbmcgYW5kIGVtaXRzIG5vdGhpbmcuXG5cbiAgbW92ZVZlcnRleChpZDogbnVtYmVyLCBpbmRleDogbnVtYmVyLCB4OiBudW1iZXIsIHk6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuZWRpdFBvbHlnb24oaWQsIChwKSA9PiBlZGl0Lm1vdmVWZXJ0ZXgocCwgaW5kZXgsIHgsIHkpKTtcbiAgfVxuXG4gIC8qKiBNb3ZlIGEgdmVydGV4IG9uIGEgcG9seWdvbidzIGludGVyaW9yIHJpbmcgKGhvbGUpIOKAlCBqaXQtdWkjODUuICovXG4gIG1vdmVIb2xlVmVydGV4KGlkOiBudW1iZXIsIGhvbGVJbmRleDogbnVtYmVyLCBpbmRleDogbnVtYmVyLCB4OiBudW1iZXIsIHk6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuZWRpdFBvbHlnb24oaWQsIChwKSA9PiBlZGl0Lm1vdmVIb2xlVmVydGV4KHAsIGhvbGVJbmRleCwgaW5kZXgsIHgsIHkpKTtcbiAgfVxuXG4gIC8qKiBJbnNlcnQgYSB2ZXJ0ZXggb24gYSBwb2x5Z29uJ3MgaW50ZXJpb3IgcmluZyAoaG9sZSksIGFmdGVyIGBzZWdJbmRleGBcbiAgICogICh0aGUgZWRnZSdzIHN0YXJ0IHZlcnRleCkuIE5vLW9wIGZvciBhbiBvdXQtb2YtcmFuZ2UgaG9sZSDigJQgaml0LXVpIzg1LiAqL1xuICBhZGRIb2xlVmVydGV4KGlkOiBudW1iZXIsIGhvbGVJbmRleDogbnVtYmVyLCBzZWdJbmRleDogbnVtYmVyLCB4OiBudW1iZXIsIHk6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuZWRpdFBvbHlnb24oaWQsIChwKSA9PiBlZGl0LmFkZEhvbGVWZXJ0ZXgocCwgaG9sZUluZGV4LCBzZWdJbmRleCwgeCwgeSkpO1xuICB9XG5cbiAgLyoqIERlbGV0ZSB0aGUgdmVydGV4IGF0IGBpbmRleGAgb24gYSBwb2x5Z29uJ3MgaW50ZXJpb3IgcmluZyAoaG9sZSkuIFJlbW92aW5nXG4gICAqICBpdCBiZWxvdyAzIHZlcnRpY2VzIGRyb3BzIHRoZSB3aG9sZSBob2xlIChhIHJpbmcgd2l0aCA8IDMgcG9pbnRzIGJvdW5kcyBub1xuICAgKiAgYXJlYSkg4oCUIGppdC11aSM4NS4gKi9cbiAgZGVsZXRlSG9sZVZlcnRleChpZDogbnVtYmVyLCBob2xlSW5kZXg6IG51bWJlciwgaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuZWRpdFBvbHlnb24oaWQsIChwKSA9PiBlZGl0LmRlbGV0ZUhvbGVWZXJ0ZXgocCwgaG9sZUluZGV4LCBpbmRleCkpO1xuICB9XG5cbiAgYWRkVmVydGV4KGlkOiBudW1iZXIsIHNlZ0luZGV4OiBudW1iZXIsIHg6IG51bWJlciwgeTogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5lZGl0UG9seWdvbihpZCwgKHApID0+IGVkaXQuYWRkVmVydGV4KHAsIHNlZ0luZGV4LCB4LCB5KSk7XG4gIH1cblxuICBkZWxldGVWZXJ0ZXgoaWQ6IG51bWJlciwgaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuZWRpdFBvbHlnb24oaWQsIChwKSA9PiBlZGl0LmRlbGV0ZVZlcnRleChwLCBpbmRleCkpO1xuICB9XG5cbiAgc2V0QmV6aWVyKGlkOiBudW1iZXIsIGJlemllcjogYm9vbGVhbik6IHZvaWQge1xuICAgIGNvbnN0IHIgPSB0aGlzLmZpbmRCeUlkKGlkKTtcbiAgICBpZiAoIXIgfHwgIXIuYm91bmRzKSByZXR1cm47XG4gICAgbGV0IG5leHQ6IFBvbHlnb24gfCBudWxsID0gbnVsbDtcbiAgICBpZiAoci5ib3VuZHMgaW5zdGFuY2VvZiBQb2x5Z29uKSB7XG4gICAgICBuZXh0ID0gZWRpdC5zZXRCZXppZXIoci5ib3VuZHMsIGJlemllcik7XG4gICAgfSBlbHNlIGlmIChyLmJvdW5kcyBpbnN0YW5jZW9mIFJlY3RhbmdsZSAmJiBiZXppZXIpIHtcbiAgICAgIC8vIFNtb290aGluZyBhIHJlY3RhbmdsZTogY29udmVydCBpdCB0byBhIDQtYW5jaG9yIGNsb3NlZCBwb2x5Z29uIGZpcnN0LlxuICAgICAgY29uc3QgcmluZyA9IHJlY3RUb1Jpbmcoci5ib3VuZHMpO1xuICAgICAgbmV4dCA9IGVkaXQuc2V0QmV6aWVyKG1ha2VQb2x5Z29uKHJpbmcueHMsIHJpbmcueXMpLCB0cnVlKTtcbiAgICB9XG4gICAgaWYgKCFuZXh0KSByZXR1cm47IC8vIGFscmVhZHkgaW4gdGhhdCBzdGF0ZSwgb3IgYmV6aWVyPWZhbHNlIG9uIGEgcmVjdGFuZ2xlXG4gICAgdGhpcy5yZWNvcmRVbmRvU25hcHNob3QoKTtcbiAgICB0aGlzLnJlcGxhY2VSZWdpb24ocmVwbGFjZUJvdW5kcyhyLCBuZXh0KSk7XG4gIH1cblxuICAvKiogRHJhZyBhIGJlemllciBjb250cm9sIHBvaW50IG9uIGEgaG9sZSByaW5nIHZlcnRleCAoZG9udXQgYmV6aWVyIGVkaXRpbmcpLiAqL1xuICBtb3ZlSG9sZUJlemllckhhbmRsZShcbiAgICBpZDogbnVtYmVyLFxuICAgIGhvbGVJbmRleDogbnVtYmVyLFxuICAgIGluZGV4OiBudW1iZXIsXG4gICAgc2lkZTogJ2luJyB8ICdvdXQnLFxuICAgIHg6IG51bWJlcixcbiAgICB5OiBudW1iZXIsXG4gICk6IHZvaWQge1xuICAgIHRoaXMuZWRpdFBvbHlnb24oaWQsIChwKSA9PiBlZGl0Lm1vdmVIb2xlQmV6aWVySGFuZGxlKHAsIGhvbGVJbmRleCwgaW5kZXgsIHNpZGUsIHgsIHkpKTtcbiAgfVxuXG4gIG1vdmVCZXppZXJIYW5kbGUoaWQ6IG51bWJlciwgaW5kZXg6IG51bWJlciwgc2lkZTogJ2luJyB8ICdvdXQnLCB4OiBudW1iZXIsIHk6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuZWRpdFBvbHlnb24oaWQsIChwKSA9PiBlZGl0Lm1vdmVCZXppZXJIYW5kbGUocCwgaW5kZXgsIHNpZGUsIHgsIHkpKTtcbiAgfVxuXG4gIC8qKiBBcHBseSBhIGNvcHktb24td3JpdGUgcG9seWdvbiBlZGl0IHRvIHJlZ2lvbiBgaWRgOiByZWNvcmQsIHN3YXAgaW4sIGVtaXQuICovXG4gIHByaXZhdGUgZWRpdFBvbHlnb24oaWQ6IG51bWJlciwgYXBwbHk6IChwOiBQb2x5Z29uKSA9PiBQb2x5Z29uIHwgbnVsbCk6IHZvaWQge1xuICAgIGNvbnN0IHIgPSB0aGlzLmZpbmRCeUlkKGlkKTtcbiAgICBpZiAoIXIgfHwgIShyLmJvdW5kcyBpbnN0YW5jZW9mIFBvbHlnb24pKSByZXR1cm47XG4gICAgY29uc3QgbmV4dCA9IGFwcGx5KHIuYm91bmRzKTtcbiAgICBpZiAoIW5leHQpIHJldHVybjtcbiAgICB0aGlzLnJlY29yZFVuZG9TbmFwc2hvdCgpO1xuICAgIHRoaXMucmVwbGFjZVJlZ2lvbihyZXBsYWNlQm91bmRzKHIsIG5leHQpKTtcbiAgfVxuXG4gIC8qKiBTd2FwIGBuZXh0YCBpbiBmb3IgdGhlIHN0b3JlZCByZWdpb24gd2l0aCBpdHMgaWQgKGEgbmV3IGFycmF5KSwgdGhlbiBzeW5jIGFuZCBlbWl0LiAqL1xuICBwcml2YXRlIHJlcGxhY2VSZWdpb24obmV4dDogUmVnaW9uKTogdm9pZCB7XG4gICAgdGhpcy5yZWdpb25zID0gdGhpcy5yZWdpb25zLm1hcCgocikgPT4gKHIuaWQgPT09IG5leHQuaWQgPyBuZXh0IDogcikpO1xuICAgIHRoaXMuc3luY0NhY2hlKCk7XG4gICAgdGhpcy5lbWl0KCk7XG4gIH1cblxuICAvKiogQ29hbGVzY2UgYHJlZ2lvblVwZGF0ZSRgIHVudGlsIHRoZSBtYXRjaGluZyB7QGxpbmsgZW5kQmF0Y2h9IChsaXZlIGRyYWdzKTtcbiAgICogIHRoZSBiYXRjaCBpcyBhbHNvIG9uZSB1bmRvIGdlc3R1cmUgKHtAbGluayBiZWdpbkdlc3R1cmV9KS4gKi9cbiAgYmVnaW5CYXRjaCgpOiB2b2lkIHtcbiAgICB0aGlzLmJhdGNoRGVwdGgrKztcbiAgICB0aGlzLmJlZ2luR2VzdHVyZSgpO1xuICB9XG4gIGVuZEJhdGNoKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmJhdGNoRGVwdGggPiAwKSB0aGlzLmJhdGNoRGVwdGgtLTtcbiAgICB0aGlzLmVuZEdlc3R1cmUoKTtcbiAgICBpZiAodGhpcy5iYXRjaERlcHRoID09PSAwICYmIHRoaXMucGVuZGluZ0VtaXQpIHtcbiAgICAgIHRoaXMucGVuZGluZ0VtaXQgPSBmYWxzZTtcbiAgICAgIHRoaXMucmVnaW9uVXBkYXRlJC5uZXh0KHRoaXMuZ2V0UmVnaW9ucygpKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTWFyayB0aGUgc3RhcnQgb2Ygb25lIHVzZXIgZ2VzdHVyZSAoZS5nLiBhIHdhbmQvYnJ1c2ggbW91c2Vkb3duKTogZXZlcnlcbiAgICogY29tbWl0IHVudGlsIHRoZSBtYXRjaGluZyB7QGxpbmsgZW5kR2VzdHVyZX0gYmVjb21lcyBhIHNpbmdsZSB1bmRvIHN0ZXAsXG4gICAqIHdpdGhvdXQgZGVsYXlpbmcgYHJlZ2lvblVwZGF0ZSRgICh0b29scyByZW5kZXIgdGhyb3VnaCBpdCB3aGlsZSBkcmFnZ2luZykuXG4gICAqIENhbGxzIG5lc3QuIEEgZ2VzdHVyZSBuZXZlciBmb2xkcyBpbnRvIGFuIGVhcmxpZXIgdGltZWQgYnVyc3QuXG4gICAqL1xuICBiZWdpbkdlc3R1cmUoKTogdm9pZCB7XG4gICAgdGhpcy5oaXN0b3J5LmJlZ2luR2VzdHVyZSgpO1xuICB9XG5cbiAgLyoqIEVuZCB0aGUgZ2VzdHVyZSBvcGVuZWQgYnkge0BsaW5rIGJlZ2luR2VzdHVyZX07IHRoZSBuZXh0IGNvbW1pdCBzdGFydHMgYSBuZXcgc3RlcC4gKi9cbiAgZW5kR2VzdHVyZSgpOiB2b2lkIHtcbiAgICB0aGlzLmhpc3RvcnkuZW5kR2VzdHVyZSgpO1xuICB9XG5cbiAgLy8g4pSA4pSAIFJlZ2lvbiBzb3VyY2VzOiBsYXJnZSByZWdpb24gc2V0cywgdGlsZWQgYnkgbGV2ZWwgb2YgZGV0YWlsIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKlxuICAgKiBIb2xkIGEgbGFyZ2UgcmVnaW9uIHNldCBhcyBhIHRpbGVkIHJlZ2lvbiBzb3VyY2UgaW5zdGVhZCBvZiBhcyByZWdpb25zOiB0aGUgYmFja2VuZHMgdGhhdFxuICAgKiBkcmF3IHNvdXJjZXMgKE9wZW5TZWFkcmFnb24sIG5hcGFyaSkgZHJhdyBpdHMgZmVhdHVyZXMgYXQgdGhlIGRldGFpbCB0aGUgem9vbSBzaG93cywgZnJvbVxuICAgKiB0aGUgdGlsZXMgaW4gdmlldywgYW5kIGEgZmVhdHVyZSBqb2lucyB0aGUgcmVnaW9ucyDigJQgZXhhY3RseSwgYXMgYW4gb3JkaW5hcnkgZWRpdGFibGVcbiAgICoge0BsaW5rIFJlZ2lvbn0gd2l0aCBpdHMge0BsaW5rIFJlZ2lvbi5zb3VyY2VJZH0g4oCUIG9ubHkgd2hlbiBpdCBpcyBzZWxlY3RlZCBvciBlZGl0ZWRcbiAgICogKHtAbGluayB0YWtlU291cmNlRmVhdHVyZXN9KS4gVW50aWwgdGhlbiB7QGxpbmsgZ2V0UmVnaW9uc30gZG9lcyBub3QgaW5jbHVkZSBpdC5cbiAgICpcbiAgICogYHNvdXJjZWAgbWF5IGJlIGFuIG9wZW5lciwgY2FsbGVkIHRoZSBmaXJzdCB0aW1lIGl0cyBzbGljZSBpcyBzaG93biAoYW5kIGFnYWluIGlmIHRoZVxuICAgKiBzb3VyY2Ugd2FzIGNsb3NlZCB0byBzYXZlIG1lbW9yeSkuIGBzbGljZXNgIHNheXMgd2hpY2ggc2xpY2Ugb2YgdGhlIGN1cnJlbnQgaW1hZ2UgaXRcbiAgICogc2VydmVzOiBvbmUgKGRlZmF1bHQ6IHRoZSBzbGljZSBzaG93bjsgcGxhbmUgMCBvZiB0aGUgc291cmNlKSwgb3IgYCdwbGFuZXMnYCwgZXZlcnkgc2xpY2UgelxuICAgKiBmcm9tIHBsYW5lIHogb2YgYSB6LWluZGV4ZWQgc291cmNlLiBSZXBsYWNlcyB0aGUgc291cmNlIHRob3NlIHNsaWNlcyBoYWQuXG4gICAqL1xuICBhdHRhY2hSZWdpb25Tb3VyY2UoXG4gICAgc291cmNlOiBSZWdpb25Tb3VyY2UgfCBSZWdpb25Tb3VyY2VPcGVuZXIsXG4gICAgc2xpY2VzOiBSZWdpb25Tb3VyY2VTbGljZXMgPSB7IHNsaWNlOiB0aGlzLnNvdXJjZVNsaWNlIH0sXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IGltYWdlID0gdGhpcy5zY29wZS5hY3RpdmVJbWFnZTtcbiAgICBpZiAoIWltYWdlKSByZXR1cm47XG4gICAgY29uc3Qgb3BlbjogUmVnaW9uU291cmNlT3BlbmVyID0gdHlwZW9mIHNvdXJjZSA9PT0gJ2Z1bmN0aW9uJyA/IHNvdXJjZSA6ICgpID0+IFByb21pc2UucmVzb2x2ZShzb3VyY2UpO1xuICAgIHRoaXMuc291cmNlcy5hdHRhY2goaW1hZ2UsIG9wZW4sIHNsaWNlcyk7XG4gICAgdGhpcy5zb3VyY2VzVmVyc2lvbisrO1xuICAgIHRoaXMucmVmcmVzaFNvdXJjZVZpZXcoKTtcbiAgfVxuXG4gIC8qKiBEcm9wIHRoZSBjdXJyZW50IGltYWdlJ3MgcmVnaW9uIHNvdXJjZXMgKGNsb3NpbmcgdGhlbSkgYW5kIHdoYXQgd2FzIHRha2VuIGZyb20gdGhlbS4gKi9cbiAgZGV0YWNoUmVnaW9uU291cmNlcygpOiB2b2lkIHtcbiAgICBjb25zdCBpbWFnZSA9IHRoaXMuc2NvcGUuYWN0aXZlSW1hZ2U7XG4gICAgaWYgKCFpbWFnZSkgcmV0dXJuO1xuICAgIHRoaXMuc291cmNlcy5kZXRhY2hJbWFnZShpbWFnZSk7XG4gICAgdGhpcy5zb3VyY2VzVmVyc2lvbisrO1xuICAgIHRoaXMucmVmcmVzaFNvdXJjZVZpZXcoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEcm9wIHRoZSBzbGljZSdzIHJlZ2lvbiBzb3VyY2UsIGZvciByZWdpb25zIGltcG9ydGVkIGluIHBsYWNlIG9mIHRoZSBzbGljZSdzIChhIHNtYWxsIGZpbGVcbiAgICogcmVwbGFjaW5nIGEgbGFyZ2Ugb25lKTogYSBzb3VyY2Ugb2YgdGhlIHNsaWNlJ3Mgb3duIGlzIGRldGFjaGVkOyBhIHotaW5kZXhlZCBzb3VyY2Ugb3ZlciBldmVyeVxuICAgKiBzbGljZSBoYXMgdGhpcyBzbGljZSdzIGZlYXR1cmVzIHRha2VuIG91dCAoYXMgZGVsZXRlZCkuIFRoZSBvdGhlciBzbGljZXMga2VlcCB0aGVpcnMuXG4gICAqL1xuICBhc3luYyBkcm9wU2xpY2VSZWdpb25Tb3VyY2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgaW1hZ2UgPSB0aGlzLnNjb3BlLmFjdGl2ZUltYWdlO1xuICAgIGNvbnN0IHNsaWNlID0gdGhpcy5zb3VyY2VTbGljZTtcbiAgICBpZiAoIWltYWdlIHx8ICF0aGlzLnNvdXJjZXMuaGFzKGltYWdlLCBzbGljZSkpIHJldHVybjtcbiAgICBpZiAodGhpcy5zb3VyY2VzLmhhc093blNvdXJjZShpbWFnZSwgc2xpY2UpKSB7XG4gICAgICB0aGlzLnNvdXJjZXMuZGV0YWNoU2xpY2UoaW1hZ2UsIHNsaWNlKTtcbiAgICAgIHRoaXMuc291cmNlc1ZlcnNpb24rKztcbiAgICAgIHRoaXMucmVmcmVzaFNvdXJjZVZpZXcoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgZ2VuZXJhdGlvbiA9IHRoaXMuc291cmNlR2VuZXJhdGlvbjtcbiAgICBjb25zdCBiaW5kaW5nID0gYXdhaXQgdGhpcy5zb3VyY2VzLmJpbmRpbmcoaW1hZ2UsIHNsaWNlKTtcbiAgICBpZiAoIWJpbmRpbmcgfHwgZ2VuZXJhdGlvbiAhPT0gdGhpcy5zb3VyY2VHZW5lcmF0aW9uKSByZXR1cm47XG4gICAgY29uc3QgYWxsID0gYXdhaXQgYmluZGluZy5zb3VyY2UuZ2V0SW5kZXgoYmluZGluZy5wbGFuZSwge1xuICAgICAgb2Zmc2V0OiAwLFxuICAgICAgbGltaXQ6IGJpbmRpbmcuc291cmNlLmluZm8uZmVhdHVyZUNvdW50LFxuICAgIH0pO1xuICAgIGlmIChnZW5lcmF0aW9uICE9PSB0aGlzLnNvdXJjZUdlbmVyYXRpb24pIHJldHVybjtcbiAgICB0aGlzLnNldFRha2VuKG5ldyBTZXQoWy4uLnRoaXMuY3VycmVudFRha2VuKCksIC4uLmFsbC5yb3dzLm1hcCgocikgPT4gci5pZCldKSk7XG4gIH1cblxuICAvKiogV2hldGhlciB0aGUgc2xpY2Ugc2hvd24gaGFzIGEgcmVnaW9uIHNvdXJjZS4gKi9cbiAgaGFzUmVnaW9uU291cmNlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnNvdXJjZXMuaGFzKHRoaXMuc2NvcGUuYWN0aXZlSW1hZ2UsIHRoaXMuc291cmNlU2xpY2UpO1xuICB9XG5cbiAgLyoqIFRoZSBzbGljZSdzIHJlZ2lvbiBzb3VyY2UgYXMgYSBzb3VyY2UgbGF5ZXIgZHJhd3MgaXQ7IG51bGwgd2l0aG91dCBvbmUgKG9yIHVudGlsIGl0IG9wZW5zKS4gKi9cbiAgZ2V0UmVnaW9uU291cmNlVmlldygpOiBSZWdpb25Tb3VyY2VWaWV3IHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuc291cmNlVmlldyQudmFsdWU7XG4gIH1cblxuICAvKioge0BsaW5rIGdldFJlZ2lvblNvdXJjZVZpZXd9IGFuZCBldmVyeSBjaGFuZ2Ugb2YgaXQgKHNsaWNlLCB0YWtlbiBpZHMsIGNsYXNzIGNvbG91cnMpLiAqL1xuICBnZXRSZWdpb25Tb3VyY2VWaWV3JCgpOiBPYnNlcnZhYmxlPFJlZ2lvblNvdXJjZVZpZXcgfCBudWxsPiB7XG4gICAgcmV0dXJuIHRoaXMuc291cmNlVmlldyQuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICAvKipcbiAgICogVGFrZSBzb3VyY2UgZmVhdHVyZXMgaW50byB0aGUgd29ya2luZyBzZXQgZm9yIGVkaXRpbmc6IHRoZWlyIGV4YWN0IGdlb21ldHJ5IGJlY29tZXNcbiAgICogb3JkaW5hcnkgcmVnaW9ucyAobWludGVkLCBjb2xvdXJlZCBhbmQgc2xpY2UtdGFnZ2VkIGFzIGFueSByZWdpb24gZW50ZXJpbmcgdGhlIHN0b3JlKSBhbmRcbiAgICogdGhlIHNvdXJjZSBzdG9wcyBkcmF3aW5nIHRoZW0uIE5vdCBhbiB1bmRvIHN0ZXAgb2YgaXRzIG93biDigJQgdW5kb2luZyBwYXN0IGl0IHB1dHMgdGhlXG4gICAqIGZlYXR1cmVzIGJhY2sgaW4gdGhlIHNvdXJjZS4gUmVzb2x2ZXMgdGhlIHJlZ2lvbiBpZHMsIGluIHRoZSBvcmRlciBhc2tlZCAoYSBmZWF0dXJlIGFscmVhZHlcbiAgICogdGFrZW4gcmVzb2x2ZXMgdG8gaXRzIHJlZ2lvbik7IFtdIHdoZW4gdGhlIHNsaWNlIGNoYW5nZWQgbWVhbndoaWxlLlxuICAgKi9cbiAgYXN5bmMgdGFrZVNvdXJjZUZlYXR1cmVzKGlkczogcmVhZG9ubHkgc3RyaW5nW10pOiBQcm9taXNlPG51bWJlcltdPiB7XG4gICAgY29uc3QgdmlldyA9IHRoaXMuc291cmNlVmlldyQudmFsdWU7XG4gICAgaWYgKCF2aWV3IHx8ICFpZHMubGVuZ3RoKSByZXR1cm4gW107XG4gICAgY29uc3QgZ2VuZXJhdGlvbiA9IHRoaXMuc291cmNlR2VuZXJhdGlvbjtcbiAgICBjb25zdCB3YW50ZWQgPSBpZHMuZmlsdGVyKChpZCkgPT4gIXZpZXcudGFrZW4uaGFzKGlkKSk7XG4gICAgY29uc3QgZmVhdHVyZXMgPSB3YW50ZWQubGVuZ3RoID8gYXdhaXQgdmlldy5zb3VyY2UuZ2V0RmVhdHVyZXMod2FudGVkKSA6IFtdO1xuICAgIGlmIChnZW5lcmF0aW9uICE9PSB0aGlzLnNvdXJjZUdlbmVyYXRpb24pIHJldHVybiBbXTtcbiAgICBjb25zdCB0YWtlbiA9IHRoaXMuY3VycmVudFRha2VuKCk7XG4gICAgY29uc3QgZnJlc2ggPSBmZWF0dXJlcy5maWx0ZXIoKGYpID0+ICF0YWtlbi5oYXMoZi5pZCkpO1xuICAgIGlmIChmcmVzaC5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IHJlZ2lvbnMgPSBmcmVzaC5tYXAoKGYpID0+IHtcbiAgICAgICAgY29uc3QgcmVnaW9uID0gcmVnaW9uRnJvbUdlb0pzb25GZWF0dXJlKGYuZmVhdHVyZSBhcyBHZW9Kc29uRmVhdHVyZSwgMCwgZi5pZCk7XG4gICAgICAgIGlmICh0aGlzLnNjb3BlLnN0YWNrTW9kZSkgcmVnaW9uLnogPSB0aGlzLnNjb3BlLmRpc3BsYXlTbGljZTtcbiAgICAgICAgcmV0dXJuIHJlZ2lvbjtcbiAgICAgIH0pO1xuICAgICAgY29uc3QgYWRtaXR0ZWQgPSB0aGlzLmFkbWl0KHJlZ2lvbnMpO1xuICAgICAgLy8gRnJlc2ggaW5zdGFuY2VzLCBjb21wbGV0ZWQgaW4gcGxhY2U6IG5hbWVkIGFmdGVyIHRoZWlyIG5ldyBpZCBsaWtlIGEgZHJhd24gcmVnaW9uLlxuICAgICAgZm9yIChjb25zdCByIG9mIGFkbWl0dGVkKSByLm5hbWUgPSBgc2hhcGUke3IuaWR9YDtcbiAgICAgIHRoaXMucmVnaW9ucyA9IHRoaXMucmVnaW9ucy5jb25jYXQoYWRtaXR0ZWQpO1xuICAgICAgdGhpcy5zZXRUYWtlbihuZXcgU2V0KFsuLi50YWtlbiwgLi4uZnJlc2gubWFwKChmKSA9PiBmLmlkKV0pKTtcbiAgICAgIHRoaXMuc3luY0NhY2hlKCk7XG4gICAgICB0aGlzLmVtaXRTZWxlY3Rpb24oKTtcbiAgICAgIHRoaXMuZW1pdCgpO1xuICAgIH1cbiAgICBjb25zdCBieVNvdXJjZSA9IG5ldyBNYXAodGhpcy5yZWdpb25zLmZpbHRlcigocikgPT4gci5zb3VyY2VJZCAhPT0gdW5kZWZpbmVkKS5tYXAoKHIpID0+IFtyLnNvdXJjZUlkLCByLmlkXSkpO1xuICAgIHJldHVybiBpZHMubWFwKChpZCkgPT4gYnlTb3VyY2UuZ2V0KGlkKSkuZmlsdGVyKChpZCk6IGlkIGlzIG51bWJlciA9PiBpZCAhPT0gdW5kZWZpbmVkKTtcbiAgfVxuXG4gIC8qKiB7QGxpbmsgdGFrZVNvdXJjZUZlYXR1cmVzfSwgdGhlbiBzZWxlY3QgdGhlbSAoYWRkZWQgdG8gdGhlIHNlbGVjdGlvbiB3aXRoIGBhZGRpdGl2ZWApLiAqL1xuICBhc3luYyBzZWxlY3RTb3VyY2VGZWF0dXJlcyhpZHM6IHJlYWRvbmx5IHN0cmluZ1tdLCBhZGRpdGl2ZSA9IGZhbHNlKTogUHJvbWlzZTxudW1iZXJbXT4ge1xuICAgIGNvbnN0IHRha2VuID0gYXdhaXQgdGhpcy50YWtlU291cmNlRmVhdHVyZXMoaWRzKTtcbiAgICBpZiAoIXRha2VuLmxlbmd0aCkgcmV0dXJuIHRha2VuO1xuICAgIHRoaXMuc2VsZWN0aW9uLnJlcGxhY2UoYWRkaXRpdmUgPyBbLi4ubmV3IFNldChbLi4udGhpcy5zZWxlY3Rpb24uaWRzLCAuLi50YWtlbl0pXSA6IHRha2VuKTtcbiAgICB0aGlzLmVtaXRTZWxlY3Rpb24oKTtcbiAgICByZXR1cm4gdGFrZW47XG4gIH1cblxuICAvKipcbiAgICogRmVhdHVyZXMgcGVyIGNsYXNzIHN0aWxsIGluIHRoZSBzbGljZSdzIHJlZ2lvbiBzb3VyY2UgKG5vdCB0YWtlbik7IHt9IHdpdGhvdXQgb25lLiBXaXRoXG4gICAqIGBzdGFja2AsIGEgei1zdGFjaydzIG92ZXIgZXZlcnkgc2xpY2U6IGl0cyBzb3VyY2UncyBwbGFuZXMsIG9yIGVhY2ggc2xpY2UncyBzb3VyY2UgYWRkZWQgdXAuXG4gICAqL1xuICBhc3luYyBnZXRSZWdpb25Tb3VyY2VDbGFzc0NvdW50cyhzdGFjayA9IGZhbHNlKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBudW1iZXI+PiB7XG4gICAgY29uc3QgdmlldyA9IHRoaXMuc291cmNlVmlldyQudmFsdWU7XG4gICAgY29uc3QgaW1hZ2UgPSB0aGlzLnNjb3BlLmFjdGl2ZUltYWdlO1xuICAgIGlmICghc3RhY2sgfHwgIXRoaXMuc2NvcGUuc3RhY2tNb2RlKSB7XG4gICAgICByZXR1cm4gdmlldyA/IHZpZXcuc291cmNlLmdldENsYXNzQ291bnRzKHZpZXcucGxhbmUsIEFycmF5LmZyb20odmlldy50YWtlbikpIDoge307XG4gICAgfVxuICAgIGlmICh0aGlzLnNvdXJjZXMuaGFzUGxhbmVzU291cmNlKGltYWdlKSkge1xuICAgICAgY29uc3QgYmluZGluZyA9IGF3YWl0IHRoaXMuc291cmNlcy5iaW5kaW5nKGltYWdlLCB0aGlzLnNvdXJjZVNsaWNlKTtcbiAgICAgIGlmICghYmluZGluZykgcmV0dXJuIHt9O1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGJpbmRpbmcuc291cmNlLmdldENsYXNzQ291bnRzKG51bGwsIHRoaXMuc291cmNlcy5hbGxUYWtlbihpbWFnZSkpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIC8vIEEgdGlsZSBzZXJ2ZXIgdGhhdCBwcmVkYXRlcyBjb3VudGluZyBldmVyeSBwbGFuZTogdGhlIHNsaWNlJ3MgY291bnRzLlxuICAgICAgICBjb25zb2xlLndhcm4oJ1tyZWdpb25zXSBjb3VsZCBub3QgY291bnQgdGhlIGNsYXNzZXMgb2YgZXZlcnkgc2xpY2UnLCBlcnIpO1xuICAgICAgICByZXR1cm4gdmlldyA/IHZpZXcuc291cmNlLmdldENsYXNzQ291bnRzKHZpZXcucGxhbmUsIEFycmF5LmZyb20odmlldy50YWtlbikpIDoge307XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IGNvdW50czogUmVjb3JkPHN0cmluZywgbnVtYmVyPiA9IHt9O1xuICAgIGZvciAoY29uc3Qgc2xpY2Ugb2YgdGhpcy5zb3VyY2VzLnNsaWNlc1dpdGhTb3VyY2UoaW1hZ2UpKSB7XG4gICAgICBjb25zdCBiaW5kaW5nID0gYXdhaXQgdGhpcy5zb3VyY2VzLmJpbmRpbmcoaW1hZ2UsIHNsaWNlKTtcbiAgICAgIGlmICghYmluZGluZykgY29udGludWU7XG4gICAgICBjb25zdCBvd24gPSBhd2FpdCBiaW5kaW5nLnNvdXJjZS5nZXRDbGFzc0NvdW50cyhiaW5kaW5nLnBsYW5lLCBBcnJheS5mcm9tKHRoaXMuc291cmNlcy50YWtlbihpbWFnZSwgc2xpY2UpKSk7XG4gICAgICBmb3IgKGNvbnN0IFtsYWJlbCwgbl0gb2YgT2JqZWN0LmVudHJpZXMob3duKSkgY291bnRzW2xhYmVsXSA9IChjb3VudHNbbGFiZWxdID8/IDApICsgbjtcbiAgICB9XG4gICAgcmV0dXJuIGNvdW50cztcbiAgfVxuXG4gIC8qKlxuICAgKiBTZWxlY3QgZXZlcnkgcmVnaW9uIG9mIHRoZXNlIGNsYXNzZXMgb24gdGhlIHNsaWNlIOKAlCB0aGUgcmVnaW9ucycsIGFuZCB0aGUgcmVnaW9uIHNvdXJjZSdzLFxuICAgKiB3aGljaCBhcmUgdGFrZW4gaW50byB0aGUgcmVnaW9ucyAoYXQgbW9zdCB7QGxpbmsgU0VMRUNUX0NMQVNTRVNfTElNSVR9IG9mIHRoZW0pLiBBZGRlZCB0byB0aGVcbiAgICogc2VsZWN0aW9uIHdpdGggYGFkZGl0aXZlYC4gUmVzb2x2ZXMgdGhlIHNlbGVjdGVkIHJlZ2lvbiBpZHMuXG4gICAqL1xuICBhc3luYyBzZWxlY3RDbGFzc2VzKGNsYXNzZXM6IHJlYWRvbmx5IHN0cmluZ1tdLCBhZGRpdGl2ZSA9IGZhbHNlKTogUHJvbWlzZTxudW1iZXJbXT4ge1xuICAgIGNvbnN0IHdhbnRlZCA9IG5ldyBTZXQoY2xhc3Nlcyk7XG4gICAgY29uc3QgdmlldyA9IHRoaXMuc291cmNlVmlldyQudmFsdWU7XG4gICAgaWYgKHZpZXcgJiYgY2xhc3Nlcy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCB2aWV3LnNvdXJjZS5nZXRJbmRleCh2aWV3LnBsYW5lLCB7XG4gICAgICAgIG9mZnNldDogMCxcbiAgICAgICAgbGltaXQ6IFNFTEVDVF9DTEFTU0VTX0xJTUlULFxuICAgICAgICBjbGFzc2VzLFxuICAgICAgICBleGNsdWRlOiBBcnJheS5mcm9tKHZpZXcudGFrZW4pLFxuICAgICAgfSk7XG4gICAgICBpZiAocGFnZS5yb3dzLmxlbmd0aCkgYXdhaXQgdGhpcy50YWtlU291cmNlRmVhdHVyZXMocGFnZS5yb3dzLm1hcCgocikgPT4gci5pZCkpO1xuICAgIH1cbiAgICBjb25zdCBpZHMgPSB0aGlzLnJlZ2lvbnMuZmlsdGVyKChyKSA9PiAhci5pc1Byb2ZpbGU/LigpICYmIHIubGFiZWwgJiYgd2FudGVkLmhhcyhyLmxhYmVsKSkubWFwKChyKSA9PiByLmlkKTtcbiAgICB0aGlzLnNlbGVjdGlvbi5yZXBsYWNlKGFkZGl0aXZlID8gWy4uLm5ldyBTZXQoWy4uLnRoaXMuc2VsZWN0aW9uLmlkcywgLi4uaWRzXSldIDogaWRzKTtcbiAgICB0aGlzLmVtaXRTZWxlY3Rpb24oKTtcbiAgICByZXR1cm4gaWRzO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSAzRCByZWNvbnN0cnVjdGlvbiBvZiBlYWNoIGdyb3VwIG9mIGNsYXNzZXMgb3ZlciBldmVyeSBzbGljZSBvZiB0aGUgc3RhY2sgKGFuIGF0bGFzXG4gICAqIHN0cnVjdHVyZSB3aXRoIGl0cyBzdWJzdHJ1Y3R1cmVzLCBzYXkpOiB0aGUgb3V0bGluZXMgb2YgdGhlIHJlZ2lvbnMgb2YgdGhvc2UgY2xhc3NlcyBvbiBldmVyeVxuICAgKiBzbGljZSDigJQgdGhlIHJlZ2lvbiBzb3VyY2VzJyBhbmQgdGhvc2UgZHJhd24gb3IgdGFrZW4g4oCUIHN0YWNrZWQgYW5kIG1lc2hlZCBpbiBhIHdvcmtlci4gTWVzaGVzXG4gICAqIGFyZSBpbiBpbWFnZSBweCAoeCwgeSkgYW5kIHNsaWNlIGluZGljZXMgKHopLiBgcGl4ZWxTdGVwYCBpcyB0aGUgaW4tcGxhbmUgdm94ZWwgc2l6ZSAoaW1hZ2VcbiAgICogcHgpOyB0aGUgb3V0bGluZXMgYXJlIHJlYWQgYXQgdGhlIG1hdGNoaW5nIGxldmVsIG9mIGRldGFpbC4gQSBncm91cCB3aXRoIG5vIG91dGxpbmUgZ2V0cyBhblxuICAgKiBlbXB0eSBtZXNoLlxuICAgKi9cbiAgYXN5bmMgcmVjb25zdHJ1Y3RDbGFzc2VzKFxuICAgIGdyb3VwczogUmVhZG9ubHlBcnJheTx7IGtleTogc3RyaW5nOyBjbGFzc2VzOiByZWFkb25seSBzdHJpbmdbXSB9PixcbiAgICBwaXhlbFN0ZXAgPSAxLFxuICApOiBQcm9taXNlPEFycmF5PHsga2V5OiBzdHJpbmc7IG1lc2g6IE1lc2ggfT4+IHtcbiAgICBjb25zdCBsZXZlbCA9IE1hdGgubWF4KDAsIE1hdGguZmxvb3IoTWF0aC5sb2cyKE1hdGgubWF4KDEsIHBpeGVsU3RlcCkpKSk7XG4gICAgY29uc3Qgb3V0OiBBcnJheTx7IGtleTogc3RyaW5nOyBtZXNoOiBNZXNoIH0+ID0gW107XG4gICAgZm9yIChjb25zdCBncm91cCBvZiBncm91cHMpIHtcbiAgICAgIGNvbnN0IHNsaWNlcyA9IGF3YWl0IHRoaXMuY2xhc3NPdXRsaW5lcyhncm91cC5jbGFzc2VzLCBsZXZlbCk7XG4gICAgICBvdXQucHVzaCh7IGtleTogZ3JvdXAua2V5LCBtZXNoOiBhd2FpdCByZWNvbnN0cnVjdEluV29ya2VyKHNsaWNlcywgeyBwaXhlbFN0ZXAgfSkgfSk7XG4gICAgfVxuICAgIHJldHVybiBvdXQ7XG4gIH1cblxuICAvKipcbiAgICogRWFjaCBjbGFzcydzIHZvbHVtZSBvdmVyIHRoZSB3aG9sZSBzdGFjaywgaW4gcHjCsiDDlyBzbGljZXM6IGl0cyBvdXRsaW5lcycgYXJlYSBvbiBldmVyeSBzbGljZVxuICAgKiAoaXRzIGZlYXR1cmVzJyB1bmlvbiwgc2VlIGBvdXRsaW5lc0FyZWFgKSwgb25lIHNsaWNlIHRoaWNrIChDYXZhbGllcmkncyBlc3RpbWF0b3IpLCBmcm9tIHRoZVxuICAgKiBleGFjdCBvdXRsaW5lcy4gV2hlcmUgYSBmZWF0dXJlIGlzLCBhIHJlZ2lvbiBzb3VyY2UncyBvciBhIGRyYXduIG9yIHRha2VuIHJlZ2lvbiwgZG9lcyBub3RcbiAgICogY2hhbmdlIGl0OiB0YWtpbmcgb25lIGxlYXZlcyB0aGUgdm9sdW1lIGFzIGl0IHdhcy4gVGhlIHJlZ2lvbiBzb3VyY2VzJyBwYXJ0IGlzIGNhY2hlZCB1bnRpbFxuICAgKiB3aGF0IHRoZXkgaG9sZCBjaGFuZ2VzIChhIGZlYXR1cmUgdGFrZW4gb3IgZGVsZXRlZCwgYW5vdGhlciBzb3VyY2UpOyBvbmx5IHRoZSBzbGljZXMgd2l0aFxuICAgKiBkcmF3biBvciB0YWtlbiByZWdpb25zIG9mIHRoZSBjbGFzcyBhcmUgbWVhc3VyZWQgYWdhaW4uXG4gICAqL1xuICBhc3luYyBjbGFzc1ZvbHVtZXMoY2xhc3NlczogcmVhZG9ubHkgc3RyaW5nW10pOiBQcm9taXNlPE1hcDxzdHJpbmcsIG51bWJlcj4+IHtcbiAgICBjb25zdCBzdGF0ZSA9IHRoaXMuc291cmNlU3RhdGVLZXkoKTtcbiAgICBjb25zdCBvdXQgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgWy4uLm5ldyBTZXQoY2xhc3NlcyldLm1hcChhc3luYyAobmFtZSkgPT4ge1xuICAgICAgICBjb25zdCBzb3VyY2UgPSBhd2FpdCB0aGlzLnNvdXJjZVZvbHVtZShzdGF0ZSwgbmFtZSk7XG4gICAgICAgIGxldCB2b2x1bWUgPSBzb3VyY2UudG90YWw7XG4gICAgICAgIGZvciAoY29uc3QgcmVnaW9ucyBvZiBtZXJnZU91dGxpbmVzKHRoaXMucmVnaW9uT3V0bGluZXMoW25hbWVdKSkpIHtcbiAgICAgICAgICBjb25zdCB1bmRlciA9IHNvdXJjZS5zbGljZXMuZ2V0KHJlZ2lvbnMueik7XG4gICAgICAgICAgY29uc3QgW2JvdGhdID0gdW5kZXIgPyBtZXJnZU91dGxpbmVzKFt1bmRlci5vdXRsaW5lcywgcmVnaW9uc10pIDogW3JlZ2lvbnNdO1xuICAgICAgICAgIHZvbHVtZSArPSBvdXRsaW5lc0FyZWEoYm90aC5yaW5ncywgYm90aC5yaW5nR3JvdXBzKSAtICh1bmRlcj8uYXJlYSA/PyAwKTtcbiAgICAgICAgfVxuICAgICAgICBvdXQuc2V0KG5hbWUsIHZvbHVtZSk7XG4gICAgICB9KSxcbiAgICApO1xuICAgIHJldHVybiBvdXQ7XG4gIH1cblxuICAvKiogVGhlIHJlZ2lvbiBzb3VyY2VzJyBwYXJ0IG9mIGEgY2xhc3MncyB2b2x1bWUsIGNhY2hlZCBieSB3aGF0IHRoZXkgaG9sZCAoc2VlIGNsYXNzVm9sdW1lcykuICovXG4gIHByaXZhdGUgc291cmNlVm9sdW1lKHN0YXRlOiBzdHJpbmcsIG5hbWU6IHN0cmluZyk6IFByb21pc2U8U291cmNlVm9sdW1lPiB7XG4gICAgY29uc3Qga2V5ID0gYCR7c3RhdGV9XFxuJHtuYW1lfWA7XG4gICAgbGV0IHNvdXJjZSA9IHRoaXMuc291cmNlVm9sdW1lQ2FjaGUuZ2V0KGtleSk7XG4gICAgaWYgKHNvdXJjZSkge1xuICAgICAgLy8gTW9zdCByZWNlbnRseSB1c2VkIGxhc3QuXG4gICAgICB0aGlzLnNvdXJjZVZvbHVtZUNhY2hlLmRlbGV0ZShrZXkpO1xuICAgICAgdGhpcy5zb3VyY2VWb2x1bWVDYWNoZS5zZXQoa2V5LCBzb3VyY2UpO1xuICAgICAgcmV0dXJuIHNvdXJjZTtcbiAgICB9XG4gICAgc291cmNlID0gdGhpcy5zb3VyY2VPdXRsaW5lcyhbbmFtZV0sIDApLnRoZW4oKHBhcnRzKSA9PiB7XG4gICAgICBjb25zdCBzbGljZXMgPSBuZXcgTWFwPG51bWJlciwgeyBhcmVhOiBudW1iZXI7IG91dGxpbmVzOiBTbGljZU91dGxpbmVzIH0+KCk7XG4gICAgICBsZXQgdG90YWwgPSAwO1xuICAgICAgZm9yIChjb25zdCBvdXRsaW5lcyBvZiBtZXJnZU91dGxpbmVzKHBhcnRzKSkge1xuICAgICAgICBjb25zdCBhcmVhID0gb3V0bGluZXNBcmVhKG91dGxpbmVzLnJpbmdzLCBvdXRsaW5lcy5yaW5nR3JvdXBzKTtcbiAgICAgICAgc2xpY2VzLnNldChvdXRsaW5lcy56LCB7IGFyZWEsIG91dGxpbmVzIH0pO1xuICAgICAgICB0b3RhbCArPSBhcmVhO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsgdG90YWwsIHNsaWNlcyB9O1xuICAgIH0pO1xuICAgIHRoaXMuc291cmNlVm9sdW1lQ2FjaGUuc2V0KGtleSwgc291cmNlKTtcbiAgICBzb3VyY2UuY2F0Y2goKCkgPT4gdGhpcy5zb3VyY2VWb2x1bWVDYWNoZS5kZWxldGUoa2V5KSk7XG4gICAgd2hpbGUgKHRoaXMuc291cmNlVm9sdW1lQ2FjaGUuc2l6ZSA+IFNPVVJDRV9WT0xVTUVfQ0FDSEVfU0laRSkge1xuICAgICAgdGhpcy5zb3VyY2VWb2x1bWVDYWNoZS5kZWxldGUodGhpcy5zb3VyY2VWb2x1bWVDYWNoZS5rZXlzKCkubmV4dCgpLnZhbHVlIGFzIHN0cmluZyk7XG4gICAgfVxuICAgIHJldHVybiBzb3VyY2U7XG4gIH1cblxuICAvKipcbiAgICogRXZlcnkgc2xpY2UncyBvdXRsaW5lcyBvZiB0aGVzZSBjbGFzc2VzLCB0aGUgcmVnaW9uIHNvdXJjZXMnIHRoZW4gdGhlIHJlZ2lvbnMnOiBjbG9zZWQgc2hhcGVzJ1xuICAgKiByaW5ncywgYW5kIG9wZW4gcG9seWxpbmVzIGFzIGBsaW5lc2AuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGNsYXNzT3V0bGluZXMoY2xhc3NlczogcmVhZG9ubHkgc3RyaW5nW10sIGxldmVsOiBudW1iZXIpOiBQcm9taXNlPFNsaWNlT3V0bGluZXNbXT4ge1xuICAgIHJldHVybiBtZXJnZU91dGxpbmVzKFsuLi4oYXdhaXQgdGhpcy5zb3VyY2VPdXRsaW5lcyhjbGFzc2VzLCBsZXZlbCkpLCAuLi50aGlzLnJlZ2lvbk91dGxpbmVzKGNsYXNzZXMpXSk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHJlZ2lvbiBzb3VyY2VzJyBvdXRsaW5lcyBvZiB0aGVzZSBjbGFzc2VzIG9uIGV2ZXJ5IHNsaWNlLCB3aXRob3V0IHRoZSBmZWF0dXJlcyB0YWtlbiBvclxuICAgKiBkZWxldGVkLiBUaGUgbGFzdCBmZXcgY2xhc3Mgc2V0cyBhcmUga2VwdCB1bnRpbCB3aGF0IHRoZSBzb3VyY2VzIGhvbGQgY2hhbmdlczogcmVidWlsZGluZyBhXG4gICAqIHN1cmZhY2UgYWZ0ZXIgYW4gZWRpdCByZWFkcyBub3RoaW5nIGFnYWluLlxuICAgKi9cbiAgcHJpdmF0ZSBzb3VyY2VPdXRsaW5lcyhjbGFzc2VzOiByZWFkb25seSBzdHJpbmdbXSB8IG51bGwsIGxldmVsOiBudW1iZXIpOiBQcm9taXNlPExhYmVsbGVkT3V0bGluZXNbXT4ge1xuICAgIGNvbnN0IGtleSA9IGAke3RoaXMuc291cmNlU3RhdGVLZXkoKX1cXG4ke2xldmVsfVxcbiR7Y2xhc3NlcyA/IGNsYXNzZXMuam9pbignXFxuJykgOiAnKid9YDtcbiAgICBjb25zdCBjYWNoZWQgPSB0aGlzLnNvdXJjZU91dGxpbmVDYWNoZS5nZXQoa2V5KTtcbiAgICBpZiAoY2FjaGVkKSB7XG4gICAgICAvLyBNb3N0IHJlY2VudGx5IHVzZWQgbGFzdC5cbiAgICAgIHRoaXMuc291cmNlT3V0bGluZUNhY2hlLmRlbGV0ZShrZXkpO1xuICAgICAgdGhpcy5zb3VyY2VPdXRsaW5lQ2FjaGUuc2V0KGtleSwgY2FjaGVkKTtcbiAgICAgIHJldHVybiBjYWNoZWQ7XG4gICAgfVxuICAgIGNvbnN0IHJlYWQgPSB0aGlzLnJlYWRTb3VyY2VPdXRsaW5lcyhjbGFzc2VzLCBsZXZlbCk7XG4gICAgdGhpcy5zb3VyY2VPdXRsaW5lQ2FjaGUuc2V0KGtleSwgcmVhZCk7XG4gICAgcmVhZC5jYXRjaCgoKSA9PiB0aGlzLnNvdXJjZU91dGxpbmVDYWNoZS5kZWxldGUoa2V5KSk7XG4gICAgd2hpbGUgKHRoaXMuc291cmNlT3V0bGluZUNhY2hlLnNpemUgPiBTT1VSQ0VfT1VUTElORV9DQUNIRV9TSVpFKSB7XG4gICAgICB0aGlzLnNvdXJjZU91dGxpbmVDYWNoZS5kZWxldGUodGhpcy5zb3VyY2VPdXRsaW5lQ2FjaGUua2V5cygpLm5leHQoKS52YWx1ZSBhcyBzdHJpbmcpO1xuICAgIH1cbiAgICByZXR1cm4gcmVhZDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVhZFNvdXJjZU91dGxpbmVzKGNsYXNzZXM6IHJlYWRvbmx5IHN0cmluZ1tdIHwgbnVsbCwgbGV2ZWw6IG51bWJlcik6IFByb21pc2U8TGFiZWxsZWRPdXRsaW5lc1tdPiB7XG4gICAgY29uc3Qgb3V0OiBMYWJlbGxlZE91dGxpbmVzW10gPSBbXTtcbiAgICBjb25zdCBpbWFnZSA9IHRoaXMuc2NvcGUuYWN0aXZlSW1hZ2U7XG4gICAgaWYgKHRoaXMuc291cmNlcy5oYXNQbGFuZXNTb3VyY2UoaW1hZ2UpKSB7XG4gICAgICBjb25zdCBiaW5kaW5nID0gYXdhaXQgdGhpcy5zb3VyY2VzLmJpbmRpbmcoaW1hZ2UsIHRoaXMuc291cmNlU2xpY2UpO1xuICAgICAgY29uc3Qgb3V0bGluZXMgPSBhd2FpdCBiaW5kaW5nPy5zb3VyY2UuZ2V0Q2xhc3NPdXRsaW5lcyhjbGFzc2VzLCBsZXZlbCwgdGhpcy5zb3VyY2VzLmFsbFRha2VuKGltYWdlKSk7XG4gICAgICBvdXQucHVzaCguLi4ob3V0bGluZXMgPz8gW10pKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCB6IG9mIHRoaXMuc291cmNlcy5zbGljZXNXaXRoU291cmNlKGltYWdlKSkge1xuICAgICAgY29uc3QgYmluZGluZyA9IGF3YWl0IHRoaXMuc291cmNlcy5iaW5kaW5nKGltYWdlLCB6KTtcbiAgICAgIGlmICghYmluZGluZykgY29udGludWU7XG4gICAgICBjb25zdCBvdXRsaW5lcyA9IGF3YWl0IGJpbmRpbmcuc291cmNlLmdldENsYXNzT3V0bGluZXMoXG4gICAgICAgIGNsYXNzZXMsXG4gICAgICAgIGxldmVsLFxuICAgICAgICBBcnJheS5mcm9tKHRoaXMuc291cmNlcy50YWtlbihpbWFnZSwgeikpLFxuICAgICAgKTtcbiAgICAgIGZvciAoY29uc3QgcyBvZiBvdXRsaW5lcykgaWYgKHMueiA9PT0gYmluZGluZy5wbGFuZSkgb3V0LnB1c2goeyAuLi5zLCB6IH0pO1xuICAgIH1cbiAgICByZXR1cm4gb3V0O1xuICB9XG5cbiAgLyoqXG4gICAqIEV2ZXJ5IGNsYXNzJ3Mgb3V0bGluZXMgb24gZXZlcnkgc2xpY2UsIGJ5IGNsYXNzOiB0aGUgcmVnaW9uIHNvdXJjZXMnIChvbmUgcmVhZCBmb3IgYWxsLCBrZXB0XG4gICAqIGxpa2Uge0BsaW5rIHNvdXJjZU91dGxpbmVzfSkgYW5kIHRoZSBkcmF3biBhbmQgdGFrZW4gcmVnaW9ucycuIFdoYXQgYSBzZWN0aW9uIHRocm91Z2ggdGhlXG4gICAqIHN0YWNrIGN1dHMgKHNlZSBgZ2VvbWV0cnkvc2VjdGlvbmApLlxuICAgKi9cbiAgYXN5bmMgb3V0bGluZXNCeUNsYXNzKGxldmVsOiBudW1iZXIpOiBQcm9taXNlPE1hcDxzdHJpbmcsIFNsaWNlT3V0bGluZXNbXT4+IHtcbiAgICBjb25zdCBieUNsYXNzID0gbmV3IE1hcDxzdHJpbmcsIE1hcDxudW1iZXIsIFNsaWNlUGFydHM+PigpO1xuICAgIGNvbnN0IHNsb3QgPSAobGFiZWw6IHN0cmluZywgejogbnVtYmVyKSA9PiB7XG4gICAgICBsZXQgc2xpY2VzID0gYnlDbGFzcy5nZXQobGFiZWwpO1xuICAgICAgaWYgKCFzbGljZXMpIGJ5Q2xhc3Muc2V0KGxhYmVsLCAoc2xpY2VzID0gbmV3IE1hcCgpKSk7XG4gICAgICBsZXQgc2xpY2UgPSBzbGljZXMuZ2V0KHopO1xuICAgICAgaWYgKCFzbGljZSkgc2xpY2VzLnNldCh6LCAoc2xpY2UgPSB7IHJpbmdzOiBbXSwgcmluZ0dyb3VwczogW10sIGxpbmVzOiBbXSB9KSk7XG4gICAgICByZXR1cm4gc2xpY2U7XG4gICAgfTtcbiAgICBjb25zdCBuZXh0UGFydCA9IGZlYXR1cmVJZHMoKTtcbiAgICBmb3IgKGNvbnN0IHMgb2YgYXdhaXQgdGhpcy5zb3VyY2VPdXRsaW5lcyhudWxsLCBsZXZlbCkpIHtcbiAgICAgIGNvbnN0IGlkID0gbmV4dFBhcnQoKTtcbiAgICAgIHMucmluZ3MuZm9yRWFjaCgociwgaSkgPT4ge1xuICAgICAgICBjb25zdCBsYWJlbCA9IHMucmluZ0xhYmVscz8uW2ldO1xuICAgICAgICBpZiAoIWxhYmVsKSByZXR1cm47XG4gICAgICAgIGNvbnN0IHNsaWNlID0gc2xvdChsYWJlbCwgcy56KTtcbiAgICAgICAgc2xpY2UucmluZ3MucHVzaChyKTtcbiAgICAgICAgc2xpY2UucmluZ0dyb3Vwcy5wdXNoKGlkKHMucmluZ0dyb3Vwcz8uW2ldKSk7XG4gICAgICB9KTtcbiAgICAgIChzLmxpbmVzID8/IFtdKS5mb3JFYWNoKChsLCBpKSA9PiB7XG4gICAgICAgIGNvbnN0IGxhYmVsID0gcy5saW5lTGFiZWxzPy5baV07XG4gICAgICAgIGlmIChsYWJlbCkgc2xvdChsYWJlbCwgcy56KS5saW5lcy5wdXNoKGwpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgeyBsYWJlbCwgb3V0bGluZXMgfSBvZiB0aGlzLmxhYmVsbGVkUmVnaW9uT3V0bGluZXMobnVsbCkpIHtcbiAgICAgIC8vIEEgcmVnaW9uIGlzIG9uZSBmZWF0dXJlLlxuICAgICAgY29uc3QgaWQgPSBuZXh0UGFydCgpKHVuZGVmaW5lZCk7XG4gICAgICBjb25zdCBzbGljZSA9IHNsb3QobGFiZWwsIG91dGxpbmVzLnopO1xuICAgICAgc2xpY2UucmluZ3MucHVzaCguLi5vdXRsaW5lcy5yaW5ncyk7XG4gICAgICBzbGljZS5yaW5nR3JvdXBzLnB1c2goLi4ub3V0bGluZXMucmluZ3MubWFwKCgpID0+IGlkKSk7XG4gICAgICBzbGljZS5saW5lcy5wdXNoKC4uLihvdXRsaW5lcy5saW5lcyA/PyBbXSkpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IE1hcChcbiAgICAgIEFycmF5LmZyb20oYnlDbGFzcywgKFtsYWJlbCwgc2xpY2VzXSkgPT4gW2xhYmVsLCBBcnJheS5mcm9tKHNsaWNlcywgKFt6LCBzXSkgPT4gc2xpY2VPdXRsaW5lcyh6LCBzKSldKSxcbiAgICApO1xuICB9XG5cbiAgLyoqIFRoZSBkcmF3biBhbmQgdGFrZW4gcmVnaW9ucycgb3V0bGluZXMgb2YgdGhlc2UgY2xhc3NlcywgYnkgc2xpY2UuICovXG4gIHByaXZhdGUgcmVnaW9uT3V0bGluZXMoY2xhc3NlczogcmVhZG9ubHkgc3RyaW5nW10pOiBTbGljZU91dGxpbmVzW10ge1xuICAgIHJldHVybiB0aGlzLmxhYmVsbGVkUmVnaW9uT3V0bGluZXMobmV3IFNldChjbGFzc2VzKSkubWFwKChvKSA9PiBvLm91dGxpbmVzKTtcbiAgfVxuXG4gIC8qKiBFYWNoIGRyYXduIG9yIHRha2VuIHJlZ2lvbidzIG91dGxpbmVzIChvZiB0aGUgYHdhbnRlZGAgY2xhc3NlczsgbnVsbDogZXZlcnkgY2xhc3MpIHdpdGggaXRzIGNsYXNzLiAqL1xuICBwcml2YXRlIGxhYmVsbGVkUmVnaW9uT3V0bGluZXMoXG4gICAgd2FudGVkOiBSZWFkb25seVNldDxzdHJpbmc+IHwgbnVsbCxcbiAgKTogQXJyYXk8eyBsYWJlbDogc3RyaW5nOyBvdXRsaW5lczogU2xpY2VPdXRsaW5lcyB9PiB7XG4gICAgY29uc3Qgb3V0OiBBcnJheTx7IGxhYmVsOiBzdHJpbmc7IG91dGxpbmVzOiBTbGljZU91dGxpbmVzIH0+ID0gW107XG4gICAgZm9yIChjb25zdCByIG9mIHRoaXMuc2NvcGUuc3RhY2tNb2RlID8gdGhpcy5nZXRTbGljZVJlZ2lvbnMoKSA6IHRoaXMucmVnaW9ucykge1xuICAgICAgaWYgKHIuaXNQcm9maWxlPy4oKSB8fCAhci5sYWJlbCB8fCAod2FudGVkICYmICF3YW50ZWQuaGFzKHIubGFiZWwpKSkgY29udGludWU7XG4gICAgICBjb25zdCByaW5nczogRmxvYXQ2NEFycmF5W10gPSBbXTtcbiAgICAgIGZvciAoY29uc3QgcCBvZiByZWdpb25Qb2x5Z29ucyhyKSkge1xuICAgICAgICByaW5ncy5wdXNoKEZsb2F0NjRBcnJheS5mcm9tKHAueHBvaW50cy5mbGF0TWFwKCh4LCBpKSA9PiBbeCwgcC55cG9pbnRzW2ldXSkpKTtcbiAgICAgICAgZm9yIChjb25zdCBob2xlIG9mIHAuaG9sZXMgPz8gW10pIHJpbmdzLnB1c2goRmxvYXQ2NEFycmF5LmZyb20oaG9sZS5mbGF0KCkpKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGxpbmVzID0gcmVnaW9uUG9seWxpbmVzKHIpO1xuICAgICAgb3V0LnB1c2goeyBsYWJlbDogci5sYWJlbCwgb3V0bGluZXM6IHsgejogci56ID8/IDAsIHJpbmdzLCAuLi4obGluZXMubGVuZ3RoID8geyBsaW5lcyB9IDoge30pIH0gfSk7XG4gICAgfVxuICAgIHJldHVybiBvdXQ7XG4gIH1cblxuICAvKiogV2hhdCB0aGUgcmVnaW9uIHNvdXJjZXMgb2YgdGhlIGltYWdlIGhvbGQgKHNlZSB7QGxpbmsgc291cmNlU3RhdGVLZXl9KTogaXQgY2hhbmdlcyB3aGVuIGFcbiAgICogIGZlYXR1cmUgaXMgdGFrZW4gb3IgZGVsZXRlZCwgb3IgdGhhdCBpcyB1bmRvbmUuICovXG4gIGdldFNvdXJjZVN0YXRlS2V5KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc291cmNlU3RhdGVLZXkoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGF0IHRoZSByZWdpb24gc291cmNlcyBvZiB0aGUgaW1hZ2UgaG9sZDogdGhlIGltYWdlLCBpdHMgc291cmNlcyAob25lIGF0dGFjaGVkIG9yIGRyb3BwZWRcbiAgICogYnVtcHMgdGhlIHZlcnNpb24pIGFuZCB0aGUgZmVhdHVyZXMgdGFrZW4gZnJvbSB0aGVtLiBBIGtleSBmb3Igd2hhdCBpcyByZWFkIGZyb20gdGhlbS5cbiAgICovXG4gIHByaXZhdGUgc291cmNlU3RhdGVLZXkoKTogc3RyaW5nIHtcbiAgICBjb25zdCBpbWFnZSA9IHRoaXMuc2NvcGUuYWN0aXZlSW1hZ2U7XG4gICAgbGV0IHRha2VuID0gMjE2NjEzNjI2MTtcbiAgICBmb3IgKGNvbnN0IHogb2YgdGhpcy5zb3VyY2VzLnNsaWNlc1dpdGhUYWtlbihpbWFnZSkpIHtcbiAgICAgIGZvciAoY29uc3QgaWQgb2YgWy4uLnRoaXMuc291cmNlcy50YWtlbihpbWFnZSwgeildLnNvcnQoKSkge1xuICAgICAgICBjb25zdCBzID0gYCR7en06JHtpZH07YDtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzLmxlbmd0aDsgaSsrKSB0YWtlbiA9IE1hdGguaW11bCh0YWtlbiBeIHMuY2hhckNvZGVBdChpKSwgMTY3Nzc2MTkpID4+PiAwO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYCR7aW1hZ2V9XFxuJHt0aGlzLnNvdXJjZXNWZXJzaW9ufVxcbiR7dGFrZW59YDtcbiAgfVxuXG4gIC8qKiBEZWxldGUgc291cmNlIGZlYXR1cmVzIHdpdGhvdXQgdGFraW5nIHRoZW0gKG9uZSB1bmRvIHN0ZXApLiAqL1xuICBkZWxldGVTb3VyY2VGZWF0dXJlcyhpZHM6IHJlYWRvbmx5IHN0cmluZ1tdKTogdm9pZCB7XG4gICAgY29uc3QgdGFrZW4gPSB0aGlzLmN1cnJlbnRUYWtlbigpO1xuICAgIGNvbnN0IGRyb3AgPSBpZHMuZmlsdGVyKChpZCkgPT4gIXRha2VuLmhhcyhpZCkpO1xuICAgIGlmICghZHJvcC5sZW5ndGggfHwgIXRoaXMuc291cmNlVmlldyQudmFsdWUpIHJldHVybjtcbiAgICB0aGlzLnJlY29yZFVuZG9TbmFwc2hvdCgpO1xuICAgIHRoaXMuc2V0VGFrZW4obmV3IFNldChbLi4udGFrZW4sIC4uLmRyb3BdKSk7XG4gICAgdGhpcy5lbWl0KCk7XG4gIH1cblxuICAvKipcbiAgICogQSBwYWdlIG9mIHRoZSBzbGljZSBzb3VyY2UncyBmZWF0dXJlcyBub3QgdGFrZW4gZnJvbSBpdCAoZmlsZSBvcmRlciksIGUuZy4gZm9yIHRoZSBSZWdpb25cbiAgICogRWRpdG9yJ3MgbGlzdDsgYW4gZW1wdHkgcGFnZSB3aXRob3V0IGEgc291cmNlLlxuICAgKi9cbiAgYXN5bmMgZ2V0UmVnaW9uU291cmNlSW5kZXgocXVlcnk6IE9taXQ8UmVnaW9uSW5kZXhRdWVyeSwgJ2V4Y2x1ZGUnPik6IFByb21pc2U8UmVnaW9uSW5kZXhQYWdlPiB7XG4gICAgY29uc3QgdmlldyA9IHRoaXMuc291cmNlVmlldyQudmFsdWU7XG4gICAgaWYgKCF2aWV3KSByZXR1cm4geyB0b3RhbDogMCwgcm93czogW10gfTtcbiAgICByZXR1cm4gdmlldy5zb3VyY2UuZ2V0SW5kZXgodmlldy5wbGFuZSwgeyAuLi5xdWVyeSwgZXhjbHVkZTogQXJyYXkuZnJvbSh2aWV3LnRha2VuKSB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBgcmVnaW9uc2AgYXMgYSBHZW9KU09OIEZlYXR1cmVDb2xsZWN0aW9uIHN0cmluZyBtZXJnZWQgd2l0aCB0aGUgcmVnaW9uIHNvdXJjZSBiZWhpbmQgdGhlbTpcbiAgICogdGhlIHNvdXJjZSdzIGZlYXR1cmVzIHRoYXQgd2VyZSBub3QgdGFrZW4gKG9yIGRlbGV0ZWQpLCB0aGVuIGByZWdpb25zYC4gV2l0aG91dCBhIHNvdXJjZSxcbiAgICoge0BsaW5rIGdldEdlb0pzb25TdHJpbmd9LiBgc2xpY2VgIG5hbWVzIGEgZm9sZGVyIHN0YWNrJ3Mgc2xpY2UgKGRlZmF1bHQgdGhlIG9uZSBzaG93bik7XG4gICAqIG9uIGEgei1pbmRleGVkIHN0YWNrJ3Mgc291cmNlIChgJ3BsYW5lcydgKSB0aGUgZXhwb3J0IHNwYW5zIGV2ZXJ5IHNsaWNlLlxuICAgKi9cbiAgYXN5bmMgZ2V0R2VvSnNvbldpdGhTb3VyY2UocmVnaW9uczogUmVnaW9uW10sIHNsaWNlID0gdGhpcy5zb3VyY2VTbGljZSk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3QgaW1hZ2UgPSB0aGlzLnNjb3BlLmFjdGl2ZUltYWdlO1xuICAgIGNvbnN0IHBsYW5lcyA9IHRoaXMuc2NvcGUuc3RhY2tNb2RlICYmIHRoaXMuc291cmNlcy5oYXNQbGFuZXNTb3VyY2UoaW1hZ2UpO1xuICAgIGNvbnN0IGJpbmRpbmcgPSBhd2FpdCB0aGlzLnNvdXJjZXMuYmluZGluZyhpbWFnZSwgc2xpY2UpO1xuICAgIGlmICghYmluZGluZykgcmV0dXJuIHJlZ2lvbnNUb0dlb0pzb24ocmVnaW9ucyk7XG4gICAgY29uc3QgZmVhdHVyZXMgPSByZWdpb25zXG4gICAgICAuZmlsdGVyKChyKSA9PiAhci5pc1Byb2ZpbGU/LigpKVxuICAgICAgLm1hcCgocikgPT4gZmVhdHVyZUZyb21SZWdpb24ocikpXG4gICAgICAuZmlsdGVyKChmKTogZiBpcyBvYmplY3QgPT4gISFmKTtcbiAgICBjb25zdCBleGNsdWRlID0gcGxhbmVzID8gdGhpcy5zb3VyY2VzLmFsbFRha2VuKGltYWdlKSA6IEFycmF5LmZyb20odGhpcy5zb3VyY2VzLnRha2VuKGltYWdlLCBzbGljZSkpO1xuICAgIHJldHVybiBiaW5kaW5nLnNvdXJjZS5leHBvcnRHZW9Kc29uKGV4Y2x1ZGUsIGZlYXR1cmVzKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBSZWdpb24gbG9vayDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKipcbiAgICogV2hldGhlciBhIHJlZ2lvbiBvZiBjbGFzcyBgbGFiZWxgIGdvZXMgdW5sYWJlbGxlZCBiZWNhdXNlIGEgc3ViY2xhc3Mgb2YgaXQgKGJ5IHRoZSByZWdpb25cbiAgICogc291cmNlJ3MgY2xhc3MgaGllcmFyY2h5KSBpcyBhbW9uZyB0aGUgcmVnaW9ucyB0b28g4oCUIGFuIGF0bGFzJ3MgXCJJc29jb3J0ZXhcIiB1bmRlciBpdHMgYXJlYXMuXG4gICAqIEZhbHNlIHdpdGhvdXQgYSBoaWVyYXJjaHkuXG4gICAqL1xuICBpc0xhYmVsQ292ZXJlZChsYWJlbDogc3RyaW5nIHwgdW5kZWZpbmVkKTogYm9vbGVhbiB7XG4gICAgaWYgKCFsYWJlbCkgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IGhpZXJhcmNoeSA9IHRoaXMuc291cmNlVmlldyQudmFsdWU/LnNvdXJjZS5pbmZvLmhpZXJhcmNoeTtcbiAgICBpZiAoIWhpZXJhcmNoeSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmICh0aGlzLmNvdmVyZWRGb3I/LnJlZ2lvbnMgIT09IHRoaXMucmVnaW9ucyB8fCB0aGlzLmNvdmVyZWRGb3IuaGllcmFyY2h5ICE9PSBoaWVyYXJjaHkpIHtcbiAgICAgIGNvbnN0IHBhcmVudCA9IG5ldyBNYXAoaGllcmFyY2h5LmZpbHRlcigobikgPT4gbi5wYXJlbnQpLm1hcCgobikgPT4gW24ubmFtZSwgbi5wYXJlbnQgYXMgc3RyaW5nXSkpO1xuICAgICAgY29uc3QgY292ZXJlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgICAgZm9yIChjb25zdCByIG9mIHRoaXMucmVnaW9ucykge1xuICAgICAgICBsZXQgcCA9IHIubGFiZWwgPyBwYXJlbnQuZ2V0KHIubGFiZWwpIDogdW5kZWZpbmVkO1xuICAgICAgICB3aGlsZSAocCAmJiAhY292ZXJlZC5oYXMocCkpIHtcbiAgICAgICAgICBjb3ZlcmVkLmFkZChwKTtcbiAgICAgICAgICBwID0gcGFyZW50LmdldChwKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5jb3ZlcmVkRm9yID0geyByZWdpb25zOiB0aGlzLnJlZ2lvbnMsIGhpZXJhcmNoeSwgY292ZXJlZCB9O1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jb3ZlcmVkRm9yLmNvdmVyZWQuaGFzKGxhYmVsKTtcbiAgfVxuICBwcml2YXRlIGNvdmVyZWRGb3I6IHsgcmVnaW9uczogUmVnaW9uW107IGhpZXJhcmNoeTogcmVhZG9ubHkgb2JqZWN0W107IGNvdmVyZWQ6IFNldDxzdHJpbmc+IH0gfCBudWxsID0gbnVsbDtcblxuICAvKiogVGhlIGNsYXNzZXMgaGlkZGVuIGZyb20gdmlldyAoc2VlIHtAbGluayBzZXRDbGFzc2VzSGlkZGVufSkuICovXG4gIGdldEhpZGRlbkNsYXNzZXMoKTogUmVhZG9ubHlTZXQ8c3RyaW5nPiB7XG4gICAgcmV0dXJuIHRoaXMuaGlkZGVuQ2xhc3NlcyQudmFsdWU7XG4gIH1cblxuICAvKioge0BsaW5rIGdldEhpZGRlbkNsYXNzZXN9IGFuZCBldmVyeSBjaGFuZ2Ugb2YgaXQuICovXG4gIGdldEhpZGRlbkNsYXNzZXMkKCk6IE9ic2VydmFibGU8UmVhZG9ubHlTZXQ8c3RyaW5nPj4ge1xuICAgIHJldHVybiB0aGlzLmhpZGRlbkNsYXNzZXMkLmFzT2JzZXJ2YWJsZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhpZGUgKG9yIHNob3cgYWdhaW4pIHRoZXNlIGNsYXNzZXMnIHJlZ2lvbnM6IHRoZSBvdmVybGF5cyBhbmQgdGhlIHJlZ2lvbiBzb3VyY2UncyBsYXllciBzdG9wXG4gICAqIGRyYXdpbmcgdGhlbSwgYW5kIGEgaGlkZGVuIHJlZ2lvbiBjYW4gYmUgbmVpdGhlciBwaWNrZWQgbm9yIGtlcHQgc2VsZWN0ZWQuIFRoZSByZWdpb25zIHN0YXkgaW5cbiAgICogdGhlIHNldCAodGhlIHRhYmxlIGxpc3RzIHRoZW07IGEgc2F2ZSBrZWVwcyB0aGVtKS5cbiAgICovXG4gIHNldENsYXNzZXNIaWRkZW4oY2xhc3NlczogcmVhZG9ubHkgc3RyaW5nW10sIGhpZGRlbjogYm9vbGVhbik6IHZvaWQge1xuICAgIGNvbnN0IGN1ciA9IHRoaXMuaGlkZGVuQ2xhc3NlcyQudmFsdWU7XG4gICAgY29uc3QgbmV4dCA9IG5ldyBTZXQoY3VyKTtcbiAgICBmb3IgKGNvbnN0IGMgb2YgY2xhc3Nlcykge1xuICAgICAgaWYgKGhpZGRlbikgbmV4dC5hZGQoYyk7XG4gICAgICBlbHNlIG5leHQuZGVsZXRlKGMpO1xuICAgIH1cbiAgICBpZiAobmV4dC5zaXplID09PSBjdXIuc2l6ZSAmJiBbLi4ubmV4dF0uZXZlcnkoKGMpID0+IGN1ci5oYXMoYykpKSByZXR1cm47XG4gICAgY29uc3Qgc2V0ID0gdGhpcy5zdG9yZS5nZXRQcmVzZXRTZXQoKTtcbiAgICB0aGlzLmhpZGRlbktleXMgPSBuZXcgU2V0KFsuLi5uZXh0XS5tYXAoKGMpID0+IHByZXNldEtleShzZXQsIGMpKSk7XG4gICAgdGhpcy5oaWRkZW5DbGFzc2VzJC5uZXh0KG5leHQpO1xuICAgIGlmIChoaWRkZW4pIHtcbiAgICAgIGNvbnN0IHNob3duID0gdGhpcy5zZWxlY3Rpb24uaW5kaWNlcy5maWx0ZXIoKGkpID0+ICF0aGlzLmlzQ2xhc3NIaWRkZW4odGhpcy5yZWdpb25zW2ldPy5sYWJlbCkpO1xuICAgICAgaWYgKHNob3duLmxlbmd0aCAhPT0gdGhpcy5zZWxlY3Rpb24uaW5kaWNlcy5sZW5ndGgpIHRoaXMuc2V0U2VsZWN0ZWRTaGFwZUluZGljZXMoc2hvd24pO1xuICAgIH1cbiAgICB0aGlzLnJlcHVibGlzaFZpZXcoKTtcbiAgICB0aGlzLnJlZ2lvblVwZGF0ZSQubmV4dCh0aGlzLmdldFJlZ2lvbnMoKSk7XG4gIH1cblxuICAvKiogV2hldGhlciByZWdpb25zIGxhYmVsbGVkIGBsYWJlbGAgYXJlIGhpZGRlbiAoYW4gdW5sYWJlbGxlZCByZWdpb24gbmV2ZXIgaXMpLiAqL1xuICBpc0NsYXNzSGlkZGVuKGxhYmVsOiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhbGFiZWwgJiYgdGhpcy5oaWRkZW5LZXlzLnNpemUgPiAwICYmIHRoaXMuaGlkZGVuS2V5cy5oYXMocHJlc2V0S2V5KHRoaXMuc3RvcmUuZ2V0UHJlc2V0U2V0KCksIGxhYmVsKSk7XG4gIH1cblxuICAvKiogVGhlIHJlZ2lvbiBsb29rOiBvdXRsaW5lcywgb3IgZmlsbGVkIChhbiBhdGxhcydzIGxvb2spOyBzZWUgYHJlZ2lvbi1zdHlsZWAuICovXG4gIGdldFJlZ2lvblN0eWxlKCk6IFJlZ2lvblN0eWxlIHtcbiAgICByZXR1cm4gdGhpcy5yZWdpb25TdHlsZSQudmFsdWU7XG4gIH1cblxuICAvKioge0BsaW5rIGdldFJlZ2lvblN0eWxlfSBhbmQgZXZlcnkgY2hhbmdlIG9mIGl0LiAqL1xuICBnZXRSZWdpb25TdHlsZSQoKTogT2JzZXJ2YWJsZTxSZWdpb25TdHlsZT4ge1xuICAgIHJldHVybiB0aGlzLnJlZ2lvblN0eWxlJC5hc09ic2VydmFibGUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaG9vc2UgdGhlIHJlZ2lvbiBsb29rLCBmaWVsZCBieSBmaWVsZDsgaXQgb3ZlcnJpZGVzIGEgcmVnaW9uIHNvdXJjZSdzIGhpbnQgZm9yIHRoZSBzZXNzaW9uLlxuICAgKiBUaGUgb3ZlcmxheXMgcmVkcmF3LlxuICAgKi9cbiAgc2V0UmVnaW9uU3R5bGUocGF0Y2g6IFBhcnRpYWw8UmVnaW9uU3R5bGU+KTogdm9pZCB7XG4gICAgdGhpcy51c2VyU3R5bGUgPSB7IC4uLnRoaXMudXNlclN0eWxlLCAuLi5wYXRjaCB9O1xuICAgIHRoaXMucmVzdHlsZSgpO1xuICB9XG5cbiAgLyoqIFRoZSBsb29rIG5vdzogdGhlIHVzZXIncyBjaG9pY2UsIGVsc2UgdGhlIHNvdXJjZSdzIGhpbnQsIGVsc2Ugb3V0bGluZXMuICovXG4gIHByaXZhdGUgZWZmZWN0aXZlU3R5bGUoKTogUmVnaW9uU3R5bGUge1xuICAgIGNvbnN0IGhpbnQgPSB0aGlzLmhpbnRTdHlsZSA/PyB7fTtcbiAgICByZXR1cm4ge1xuICAgICAgZmlsbE9wYWNpdHk6IHRoaXMudXNlclN0eWxlLmZpbGxPcGFjaXR5ID8/IGhpbnQuZmlsbE9wYWNpdHkgPz8gREVGQVVMVF9SRUdJT05fU1RZTEUuZmlsbE9wYWNpdHksXG4gICAgICBzdHJva2U6IHRoaXMudXNlclN0eWxlLnN0cm9rZSAhPT0gdW5kZWZpbmVkID8gdGhpcy51c2VyU3R5bGUuc3Ryb2tlIDogKGhpbnQuc3Ryb2tlID8/IG51bGwpLFxuICAgICAgc3Ryb2tlV2lkdGg6XG4gICAgICAgIHRoaXMudXNlclN0eWxlLnN0cm9rZVdpZHRoICE9PSB1bmRlZmluZWQgPyB0aGlzLnVzZXJTdHlsZS5zdHJva2VXaWR0aCA6IChoaW50LnN0cm9rZVdpZHRoID8/IG51bGwpLFxuICAgICAgaGlnaGxpZ2h0OiB0aGlzLnVzZXJTdHlsZS5oaWdobGlnaHQgIT09IHVuZGVmaW5lZCA/IHRoaXMudXNlclN0eWxlLmhpZ2hsaWdodCA6IChoaW50LmhpZ2hsaWdodCA/PyBudWxsKSxcbiAgICB9O1xuICB9XG5cbiAgLyoqIFB1Ymxpc2ggdGhlIGxvb2sgd2hlbiBpdCBjaGFuZ2VkOiB0aGUgb3ZlcmxheXMgcmVkcmF3IHRoZSByZWdpb25zLCB0aGUgc291cmNlIGxheWVyIGl0cyBmZWF0dXJlcy4gKi9cbiAgcHJpdmF0ZSByZXN0eWxlKHJlZHJhdyA9IGZhbHNlKTogdm9pZCB7XG4gICAgY29uc3QgbmV4dCA9IHRoaXMuZWZmZWN0aXZlU3R5bGUoKTtcbiAgICBjb25zdCBjdXIgPSB0aGlzLnJlZ2lvblN0eWxlJC52YWx1ZTtcbiAgICBjb25zdCBzYW1lID0gKE9iamVjdC5rZXlzKG5leHQpIGFzIEFycmF5PGtleW9mIFJlZ2lvblN0eWxlPikuZXZlcnkoKGspID0+IG5leHRba10gPT09IGN1cltrXSk7XG4gICAgaWYgKCFzYW1lKSB0aGlzLnJlZ2lvblN0eWxlJC5uZXh0KG5leHQpO1xuICAgIGNvbnN0IHZpZXcgPSB0aGlzLnNvdXJjZVZpZXckLnZhbHVlO1xuICAgIGlmIChyZWRyYXcgfHwgIXNhbWUgfHwgKHZpZXcgJiYgdmlldy5sYWJlbHMgIT09IHRoaXMuc2hvd1NoYXBlTGFiZWwpKSB7XG4gICAgICB0aGlzLnJlcHVibGlzaFZpZXcoKTtcbiAgICAgIHRoaXMucmVnaW9uVXBkYXRlJC5uZXh0KHRoaXMuZ2V0UmVnaW9ucygpKTtcbiAgICB9XG4gIH1cblxuICAvKiogUmUtZW1pdCB0aGUgc291cmNlIHZpZXcgd2l0aCB0aGUgY3VycmVudCBsb29rIGFuZCBsYWJlbCBzZXR0aW5nLiAqL1xuICBwcml2YXRlIHJlcHVibGlzaFZpZXcoKTogdm9pZCB7XG4gICAgY29uc3QgdmlldyA9IHRoaXMuc291cmNlVmlldyQudmFsdWU7XG4gICAgaWYgKHZpZXcpIHRoaXMuc291cmNlVmlldyQubmV4dCh7IC4uLnZpZXcsIHN0eWxlOiB0aGlzLnJlZ2lvblN0eWxlJC52YWx1ZSwgbGFiZWxzOiB0aGlzLnNob3dTaGFwZUxhYmVsIH0pO1xuICB9XG5cbiAgLyoqIFRoZSBzbGljZSBhIHJlZ2lvbiBzb3VyY2UgaXMga2V5ZWQgYnk6IHRoZSBkaXNwbGF5IHNsaWNlIGluIHN0YWNrIG1vZGUsIGVsc2UgMC4gKi9cbiAgcHJpdmF0ZSBnZXQgc291cmNlU2xpY2UoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5zY29wZS5zdGFja01vZGUgPyB0aGlzLnNjb3BlLmRpc3BsYXlTbGljZSA6IDA7XG4gIH1cblxuICBwcml2YXRlIGN1cnJlbnRUYWtlbigpOiBSZWFkb25seVNldDxzdHJpbmc+IHtcbiAgICByZXR1cm4gdGhpcy5zb3VyY2VzLnRha2VuKHRoaXMuc2NvcGUuYWN0aXZlSW1hZ2UsIHRoaXMuc291cmNlU2xpY2UpO1xuICB9XG5cbiAgLyoqIFJlcGxhY2UgdGhlIHNsaWNlJ3MgdGFrZW4gaWRzIGFuZCB0ZWxsIHRoZSBzb3VyY2UgbGF5ZXJzLiAqL1xuICBwcml2YXRlIHNldFRha2VuKHRha2VuOiBSZWFkb25seVNldDxzdHJpbmc+KTogdm9pZCB7XG4gICAgaWYgKHRha2VuID09PSB0aGlzLmN1cnJlbnRUYWtlbigpKSByZXR1cm47XG4gICAgdGhpcy5zb3VyY2VzLnNldFRha2VuKHRoaXMuc2NvcGUuYWN0aXZlSW1hZ2UsIHRoaXMuc291cmNlU2xpY2UsIHRha2VuKTtcbiAgICBjb25zdCB2aWV3ID0gdGhpcy5zb3VyY2VWaWV3JC52YWx1ZTtcbiAgICBpZiAodmlldykgdGhpcy5zb3VyY2VWaWV3JC5uZXh0KHsgLi4udmlldywgdGFrZW4gfSk7XG4gIH1cblxuICAvKipcbiAgICogTG9vayB1cCAob3BlbmluZyBpdCBpZiBuZWVkZWQpIHRoZSBzbGljZSdzIHNvdXJjZSBhbmQgcHVibGlzaCBpdCBhcyB0aGUgc291cmNlIHZpZXcuIFRoZSB2aWV3XG4gICAqIGlzIHdpdGhkcmF3biBhdCBvbmNlOiB1bnRpbCB0aGUgaW5jb21pbmcgc291cmNlIG9wZW5zLCBub3RoaW5nIHJlYWRzLCB0YWtlcyBvciBkZWxldGVzIGZyb20gdGhlXG4gICAqIG91dGdvaW5nIG9uZSBpbnRvIHRoZSBzbGljZSBub3cgc2hvd24uXG4gICAqL1xuICBwcml2YXRlIHJlZnJlc2hTb3VyY2VWaWV3KCk6IHZvaWQge1xuICAgIGNvbnN0IGdlbmVyYXRpb24gPSArK3RoaXMuc291cmNlR2VuZXJhdGlvbjtcbiAgICBjb25zdCBpbWFnZSA9IHRoaXMuc2NvcGUuYWN0aXZlSW1hZ2U7XG4gICAgY29uc3Qgc2xpY2UgPSB0aGlzLnNvdXJjZVNsaWNlO1xuICAgIGlmICh0aGlzLnNvdXJjZVZpZXckLnZhbHVlKSB0aGlzLnNvdXJjZVZpZXckLm5leHQobnVsbCk7XG4gICAgdGhpcy5zb3VyY2VzLnNob3coaW1hZ2UsIHNsaWNlKTtcbiAgICBpZiAoIXRoaXMuc291cmNlcy5oYXMoaW1hZ2UsIHNsaWNlKSkge1xuICAgICAgdGhpcy5oaW50U3R5bGUgPSB1bmRlZmluZWQ7XG4gICAgICB0aGlzLnJlc3R5bGUoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5zb3VyY2VzLmJpbmRpbmcoaW1hZ2UsIHNsaWNlKS50aGVuKFxuICAgICAgKGJpbmRpbmcpID0+IHtcbiAgICAgICAgaWYgKGdlbmVyYXRpb24gIT09IHRoaXMuc291cmNlR2VuZXJhdGlvbikgcmV0dXJuO1xuICAgICAgICBpZiAoIWJpbmRpbmcpIHtcbiAgICAgICAgICB0aGlzLnNvdXJjZVZpZXckLm5leHQobnVsbCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGluZm8gPSBiaW5kaW5nLnNvdXJjZS5pbmZvO1xuICAgICAgICBjb25zdCBjbGFzc0NvbG9ycyA9IE9iamVjdC5lbnRyaWVzKGluZm8uY2xhc3NDb2xvcnMpO1xuICAgICAgICBpZiAoY2xhc3NDb2xvcnMubGVuZ3RoKSB0aGlzLnN0b3JlLnJlbWVtYmVySW1wb3J0ZWRDbGFzc0NvbG9ycyhuZXcgTWFwKGNsYXNzQ29sb3JzKSk7XG4gICAgICAgIC8vIEEgc291cmNlIHRoYXQgYXNrcyBmb3IgbGFiZWxzIGdldHMgdGhlbSB3aGVuIGl0IG9wZW5zICh0aGUgdG9nZ2xlIHN0aWxsIHR1cm5zIHRoZW0gb2ZmKS5cbiAgICAgICAgY29uc3QgbGFiZWxzT24gPSAhIWluZm8uc3R5bGU/LmxhYmVscyAmJiAhdGhpcy5zaG93U2hhcGVMYWJlbCAmJiB0aGlzLnNob3duU291cmNlICE9PSBiaW5kaW5nLnNvdXJjZTtcbiAgICAgICAgaWYgKGxhYmVsc09uKSB0aGlzLnNob3dTaGFwZUxhYmVsID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5zaG93blNvdXJjZSA9IGJpbmRpbmcuc291cmNlO1xuICAgICAgICB0aGlzLmhpbnRTdHlsZSA9IGluZm8uc3R5bGU7XG4gICAgICAgIHRoaXMuc291cmNlVmlldyQubmV4dCh7XG4gICAgICAgICAgc291cmNlOiBiaW5kaW5nLnNvdXJjZSxcbiAgICAgICAgICBwbGFuZTogYmluZGluZy5wbGFuZSxcbiAgICAgICAgICB0YWtlbjogdGhpcy5zb3VyY2VzLnRha2VuKGltYWdlLCBzbGljZSksXG4gICAgICAgICAgY29sb3JPZjogKGYpID0+XG4gICAgICAgICAgICBmLmxhYmVsID8gY29sb3JGb3JMYWJlbChmLmxhYmVsLCB0aGlzLnN0b3JlLmdldFByZXNldFNldCgpKSA6IGYuY29sb3IgfHwgdGhpcy5zaGFwZUNvbG9yLFxuICAgICAgICAgIHN0eWxlOiB0aGlzLnJlZ2lvblN0eWxlJC52YWx1ZSxcbiAgICAgICAgICBsYWJlbHM6IHRoaXMuc2hvd1NoYXBlTGFiZWwsXG4gICAgICAgICAgaXNIaWRkZW46IChsYWJlbCkgPT4gdGhpcy5pc0NsYXNzSGlkZGVuKGxhYmVsKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucmVzdHlsZShsYWJlbHNPbik7XG4gICAgICB9LFxuICAgICAgKGVycikgPT4ge1xuICAgICAgICBpZiAoZ2VuZXJhdGlvbiAhPT0gdGhpcy5zb3VyY2VHZW5lcmF0aW9uKSByZXR1cm47XG4gICAgICAgIGNvbnNvbGUud2FybignW3JlZ2lvbnNdIGNvdWxkIG5vdCBvcGVuIHRoZSByZWdpb24gc291cmNlJywgZXJyKTtcbiAgICAgICAgdGhpcy5zb3VyY2VWaWV3JC5uZXh0KG51bGwpO1xuICAgICAgfSxcbiAgICApO1xuICB9XG5cbiAgLy8g4pSA4pSAIHBlci1pbWFnZSBsaWZlY3ljbGUg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqXG4gICAqIFN3aXRjaCB0aGUgYWN0aXZlIGltYWdlOiBzbmFwc2hvdCB0aGUgb3V0Z29pbmcgcmVnaW9ucywgcmVzdG9yZSB0aGVcbiAgICogaW5jb21pbmcgaW1hZ2UncyAob3IgW10gaWYgbm9uZSksIGNsZWFyIHNlbGVjdGlvbiwgYW5kIG5vdGlmeS4gSWRlbXBvdGVudFxuICAgKiBmb3IgdGhlIHNhbWUgaW1hZ2UgKHNvIHJlcGVhdGVkIHJlcGxvdHMgb2Ygb25lIGltYWdlIGtlZXAgaXRzIHJlZ2lvbnMpLlxuICAgKi9cbiAgc2V0QWN0aXZlSW1hZ2UoaW1hZ2VJbmZvOiBJSW1hZ2VJbmZvKTogdm9pZCB7XG4gICAgLy8gU3dpdGNoaW5nIGltYWdlcyBhbHNvIGVuZHMgYW55IHBlci1zbGljZSBzdGFjayBzZXNzaW9uIChqaXQtdWkjOTMpLlxuICAgIGNvbnN0IGluY29taW5nID0gdGhpcy5zY29wZS5zd2l0Y2hJbWFnZShSZWdpb25TY29wZUNhY2hlLmltYWdlS2V5KGltYWdlSW5mbyksIHRoaXMucmVnaW9ucyk7XG4gICAgaWYgKCFpbmNvbWluZykgcmV0dXJuO1xuICAgIHRoaXMucmVnaW9ucyA9IGluY29taW5nO1xuICAgIHRoaXMuc2VsZWN0aW9uLnJlcGxhY2UoW10pO1xuICAgIC8vIFVuZG8gbmV2ZXIgY3Jvc3NlcyBhbiBpbWFnZSBzd2l0Y2guXG4gICAgdGhpcy5yZXNldFVuZG9IaXN0b3J5KCk7XG4gICAgdGhpcy5lbWl0U2VsZWN0aW9uKCk7XG4gICAgdGhpcy5yZWdpb25VcGRhdGUkLm5leHQodGhpcy5nZXRSZWdpb25zKCkpO1xuICAgIHRoaXMucmVmcmVzaFNvdXJjZVZpZXcoKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBpbnRlcm5hbHMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqIEFwcGx5IHRoZSBwcmVzZXQgc2V0J3MgY2xhc3MgY29sb3VycyAoc2VlIHtAbGluayBhcHBseVByZXNldENvbG9yc30pLFxuICAgKiAgcHJvbW90aW5nIHVua25vd24gY2xhc3NlcyBpbnRvIHRoZSBzaGFyZWQgc3RvcmUgd2hlbiB0aGUgc2V0IGFza3MgZm9yIGl0LiAqL1xuICBwcml2YXRlIHdpdGhDbGFzc2lmaWNhdGlvbkNvbG9ycyhyZWdpb25zOiBSZWdpb25bXSwgaW5QbGFjZTogKHI6IFJlZ2lvbikgPT4gYm9vbGVhbik6IFJlZ2lvbltdIHtcbiAgICByZXR1cm4gYXBwbHlQcmVzZXRDb2xvcnMocmVnaW9ucywgdGhpcy5zdG9yZS5nZXRQcmVzZXRTZXQoKSwge1xuICAgICAgaW5QbGFjZSxcbiAgICAgIG9uUHJvbW90ZTogKHByZXNldCkgPT4gdGhpcy5zdG9yZS51cHNlcnRDbGFzcyhwcmVzZXQpLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzeW5jQ2FjaGUoKTogdm9pZCB7XG4gICAgdGhpcy5zY29wZS5zeW5jKHRoaXMucmVnaW9ucyk7XG4gIH1cblxuICBwcml2YXRlIGVtaXQoKTogdm9pZCB7XG4gICAgLy8gTGl2ZS1lZGl0IGxpc3RlbmVycyAoZS5nLiB0aGUgaW50ZW5zaXR5LXByb2ZpbGUgaW5zZXQpIHJlYWN0IG9uIEVWRVJZXG4gICAgLy8gY2hhbmdlIOKAlCBpbmNsdWRpbmcgcGVyLWZyYW1lIGR1cmluZyBhIGJhdGNoZWQgZHJhZyDigJQgc28gdGhleSB0cmFjayB0aGVcbiAgICAvLyByZWdpb24gbGl2ZS4gVGhlIG1haW4gcmVnaW9uVXBkYXRlJCBzdGF5cyBjb2FsZXNjZWQgZHVyaW5nIGEgYmF0Y2ggKGZpcmVzXG4gICAgLy8gb25jZSBvbiBlbmRCYXRjaCkgdG8ga2VlcCBoZWF2aWVyIGNvbnN1bWVycyAoUmVnaW9ucyB0YWIpIGNhbG0uXG4gICAgdGhpcy5yZWdpb25MaXZlRWRpdCQubmV4dCh0aGlzLnJlZ2lvbnMuc2xpY2UoKSk7XG4gICAgaWYgKHRoaXMuYmF0Y2hEZXB0aCA+IDApIHtcbiAgICAgIHRoaXMucGVuZGluZ0VtaXQgPSB0cnVlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnJlZ2lvblVwZGF0ZSQubmV4dCh0aGlzLmdldFJlZ2lvbnMoKSk7XG4gIH1cblxuICAvKiogUHJvamVjdCB0aGUgc2VsZWN0ZWQgaWRzIG9udG8gdGhlIGN1cnJlbnQgcmVnaW9ucyAocHJ1bmluZyBnb25lIG9uZXMpO1xuICAgKiAgZW1pdHMgb25seSBpZiB0aGUgaW5kZXggc2V0IGNoYW5nZWQuICovXG4gIHByaXZhdGUgZW1pdFNlbGVjdGlvbigpOiB2b2lkIHtcbiAgICB0aGlzLnNlbGVjdGlvbi5zeW5jKHRoaXMucmVnaW9ucyk7XG4gIH1cblxuICBwcml2YXRlIGZpbmRCeUlkKGlkOiBudW1iZXIpOiBSZWdpb24gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnJlZ2lvbnMuZmluZCgocikgPT4gci5pZCA9PT0gaWQpO1xuICB9XG5cbiAgcHJpdmF0ZSBpbmRleE9mSWQoaWQ6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMucmVnaW9ucy5maW5kSW5kZXgoKHIpID0+IHIuaWQgPT09IGlkKTtcbiAgfVxufVxuIl19
|