@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
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A {@link RegionSource} over a GeoJSON string, parsed and tiled in the region-source Web Worker.
|
|
3
|
+
*
|
|
4
|
+
* One worker serves every open source. Where no worker can start (jsdom, SSR, a blocked worker
|
|
5
|
+
* URL) the same tables run on the main thread; if the worker dies, each source re-opens itself
|
|
6
|
+
* there from its text (which the host holds anyway: it handed it over) and carries on — whether
|
|
7
|
+
* it had a call in flight then or not (see {@link RegionSourceWorkerClient.generation}).
|
|
8
|
+
*/
|
|
9
|
+
import { RegionTileCache, abortable } from './region-source';
|
|
10
|
+
import { RegionSourceTables, } from './region-source-ops';
|
|
11
|
+
/** The worker died under a call; the caller re-opens on the main thread. */
|
|
12
|
+
class WorkerLostError extends Error {
|
|
13
|
+
constructor() {
|
|
14
|
+
super('The region-source worker stopped.');
|
|
15
|
+
this.name = 'WorkerLostError';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/** Owns the region-source worker and the calls in flight on it. */
|
|
19
|
+
export class RegionSourceWorkerClient {
|
|
20
|
+
/**
|
|
21
|
+
* `factory` is optional: without one the real worker module is imported on demand —
|
|
22
|
+
* dynamically, because it holds an `import.meta.url` that ts-jest's CommonJS compile
|
|
23
|
+
* rejects.
|
|
24
|
+
*/
|
|
25
|
+
constructor(factory) {
|
|
26
|
+
this.factory = factory;
|
|
27
|
+
this.worker = null;
|
|
28
|
+
this.starting = null;
|
|
29
|
+
this.unavailable = false;
|
|
30
|
+
this.nextId = 1;
|
|
31
|
+
this.pending = new Map();
|
|
32
|
+
/** The main-thread tables, once anything runs here. */
|
|
33
|
+
this.local = null;
|
|
34
|
+
this.tables = 0;
|
|
35
|
+
}
|
|
36
|
+
/** Whether calls now run on the main thread. */
|
|
37
|
+
get inThread() {
|
|
38
|
+
return this.unavailable;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Which table set calls run on: bumped when the worker is lost. A handle opened under another
|
|
42
|
+
* names a table that is gone (or, here, another source's), so its source must open again.
|
|
43
|
+
*/
|
|
44
|
+
get generation() {
|
|
45
|
+
return this.tables;
|
|
46
|
+
}
|
|
47
|
+
/** Run `request` in the worker, or here when there is none. */
|
|
48
|
+
async call(request) {
|
|
49
|
+
return (await this.run(request)).result;
|
|
50
|
+
}
|
|
51
|
+
/** {@link call}, with the {@link generation} the request ran on. */
|
|
52
|
+
async run(request) {
|
|
53
|
+
const started = await this.ensureWorker();
|
|
54
|
+
// The worker may have been lost while this waited for it.
|
|
55
|
+
const worker = started === this.worker ? started : null;
|
|
56
|
+
const generation = this.tables;
|
|
57
|
+
if (!worker)
|
|
58
|
+
return { result: (this.local ??= new RegionSourceTables()).run(request), generation };
|
|
59
|
+
const id = this.nextId++;
|
|
60
|
+
const result = await new Promise((resolve, reject) => {
|
|
61
|
+
this.pending.set(id, { resolve: resolve, reject });
|
|
62
|
+
worker.postMessage({ ...request, id });
|
|
63
|
+
});
|
|
64
|
+
return { result, generation };
|
|
65
|
+
}
|
|
66
|
+
/** Terminate the worker; calls in flight reject. */
|
|
67
|
+
dispose() {
|
|
68
|
+
this.lose();
|
|
69
|
+
}
|
|
70
|
+
ensureWorker() {
|
|
71
|
+
if (this.worker)
|
|
72
|
+
return Promise.resolve(this.worker);
|
|
73
|
+
if (this.unavailable || (!this.factory && typeof Worker === 'undefined')) {
|
|
74
|
+
this.unavailable = true;
|
|
75
|
+
return Promise.resolve(null);
|
|
76
|
+
}
|
|
77
|
+
if (!this.starting) {
|
|
78
|
+
const starting = this.startWorker();
|
|
79
|
+
this.starting = starting;
|
|
80
|
+
void starting.then(() => {
|
|
81
|
+
if (this.starting === starting)
|
|
82
|
+
this.starting = null;
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return this.starting;
|
|
86
|
+
}
|
|
87
|
+
async startWorker() {
|
|
88
|
+
try {
|
|
89
|
+
const made = this.factory
|
|
90
|
+
? this.factory()
|
|
91
|
+
: import('./region-source-worker').then((m) => m.createRegionSourceWorker());
|
|
92
|
+
const worker = made instanceof Promise ? await made : made;
|
|
93
|
+
worker.onmessage = (event) => this.onReply(event.data);
|
|
94
|
+
worker.onerror = (event) => {
|
|
95
|
+
event.preventDefault?.();
|
|
96
|
+
if (worker === this.worker) {
|
|
97
|
+
console.warn('[region-source] worker failed; tiling on the main thread');
|
|
98
|
+
this.lose();
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
this.worker = worker;
|
|
102
|
+
return worker;
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
console.warn('[region-source] worker unavailable; tiling on the main thread', err);
|
|
106
|
+
this.unavailable = true;
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
onReply(reply) {
|
|
111
|
+
const call = this.pending.get(reply.id);
|
|
112
|
+
if (!call)
|
|
113
|
+
return;
|
|
114
|
+
this.pending.delete(reply.id);
|
|
115
|
+
if (reply.ok)
|
|
116
|
+
call.resolve(reply.result);
|
|
117
|
+
else
|
|
118
|
+
call.reject(new Error(reply.error));
|
|
119
|
+
}
|
|
120
|
+
/** Stop the worker for good: every later call runs here, every call in flight is lost. */
|
|
121
|
+
lose() {
|
|
122
|
+
if (this.worker)
|
|
123
|
+
this.tables++;
|
|
124
|
+
this.unavailable = true;
|
|
125
|
+
this.worker?.terminate();
|
|
126
|
+
this.worker = null;
|
|
127
|
+
const calls = [...this.pending.values()];
|
|
128
|
+
this.pending.clear();
|
|
129
|
+
for (const call of calls)
|
|
130
|
+
call.reject(new WorkerLostError());
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
let shared = null;
|
|
134
|
+
/** The worker client every GeoJSON source shares. */
|
|
135
|
+
export function sharedRegionSourceClient() {
|
|
136
|
+
return (shared ??= new RegionSourceWorkerClient());
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Open a GeoJSON FeatureCollection string as a tiled region source. Rejects on invalid JSON or
|
|
140
|
+
* a collection without `features`.
|
|
141
|
+
*/
|
|
142
|
+
export async function openGeoJsonRegionSource(text, client = sharedRegionSourceClient()) {
|
|
143
|
+
// The worker lost under the open: open on the main thread instead.
|
|
144
|
+
const opened = await client
|
|
145
|
+
.run({ op: 'open', text })
|
|
146
|
+
.catch((err) => (err instanceof WorkerLostError ? client.run({ op: 'open', text }) : Promise.reject(err)));
|
|
147
|
+
const { handle, info } = opened.result;
|
|
148
|
+
return new WorkerRegionSource(client, text, handle, opened.generation, info);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* The 3D reconstruction of a region from its outlines on a stack (see `geometry/reconstruct`),
|
|
152
|
+
* meshed in the region-source worker (on the main thread where there is none).
|
|
153
|
+
*/
|
|
154
|
+
export function reconstructInWorker(slices, options, client = sharedRegionSourceClient()) {
|
|
155
|
+
return client.call({ op: 'mesh', slices, options });
|
|
156
|
+
}
|
|
157
|
+
class WorkerRegionSource {
|
|
158
|
+
constructor(client, text, handle,
|
|
159
|
+
/** The client's {@link RegionSourceWorkerClient.generation} {@link handle} was opened under. */
|
|
160
|
+
generation, info) {
|
|
161
|
+
this.client = client;
|
|
162
|
+
this.text = text;
|
|
163
|
+
this.handle = handle;
|
|
164
|
+
this.generation = generation;
|
|
165
|
+
this.info = info;
|
|
166
|
+
this.cache = new RegionTileCache();
|
|
167
|
+
this.disposed = false;
|
|
168
|
+
/** The main-thread re-open after the worker died, shared by every call that finds it so. */
|
|
169
|
+
this.reopening = null;
|
|
170
|
+
}
|
|
171
|
+
getTile(z, key, signal) {
|
|
172
|
+
const tile = this.cache.get(z, key, () => this.call((handle) => ({ op: 'tile', handle, z, level: key.level, gx: key.gx, gy: key.gy })));
|
|
173
|
+
return abortable(tile, signal);
|
|
174
|
+
}
|
|
175
|
+
getFeatures(ids) {
|
|
176
|
+
return this.call((handle) => ({ op: 'features', handle, ids }));
|
|
177
|
+
}
|
|
178
|
+
getIndex(z, query) {
|
|
179
|
+
return this.call((handle) => ({ op: 'index', handle, z, query }));
|
|
180
|
+
}
|
|
181
|
+
getClassOutlines(classes, level, exclude) {
|
|
182
|
+
return this.call((handle) => ({ op: 'outlines', handle, classes, level, exclude }));
|
|
183
|
+
}
|
|
184
|
+
getClassCounts(z, exclude) {
|
|
185
|
+
return this.call((handle) => ({ op: 'classes', handle, z, exclude }));
|
|
186
|
+
}
|
|
187
|
+
exportGeoJson(exclude, extra) {
|
|
188
|
+
return this.call((handle) => ({ op: 'export', handle, exclude, extra }));
|
|
189
|
+
}
|
|
190
|
+
dispose() {
|
|
191
|
+
if (this.disposed)
|
|
192
|
+
return;
|
|
193
|
+
this.disposed = true;
|
|
194
|
+
this.cache.clear();
|
|
195
|
+
// A handle from a lost worker's tables names nothing here, or another source's table.
|
|
196
|
+
if (this.generation !== this.client.generation)
|
|
197
|
+
return;
|
|
198
|
+
void this.client.call({ op: 'close', handle: this.handle }).catch(() => undefined);
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Run a request on this source's table; when the worker died (under this call or before it),
|
|
202
|
+
* re-open here and run it there.
|
|
203
|
+
*/
|
|
204
|
+
async call(make) {
|
|
205
|
+
for (let attempt = 0;; attempt++) {
|
|
206
|
+
if (this.generation !== this.client.generation)
|
|
207
|
+
await this.reopen();
|
|
208
|
+
try {
|
|
209
|
+
return await this.client.call(make(this.handle));
|
|
210
|
+
}
|
|
211
|
+
catch (err) {
|
|
212
|
+
if (!(err instanceof WorkerLostError) || attempt > 0)
|
|
213
|
+
throw err;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/** Open this source's text again on the client's current tables, once for every call waiting. */
|
|
218
|
+
reopen() {
|
|
219
|
+
this.reopening ??= this.client
|
|
220
|
+
.run({ op: 'open', text: this.text })
|
|
221
|
+
.then(({ result, generation }) => {
|
|
222
|
+
this.handle = result.handle;
|
|
223
|
+
this.generation = generation;
|
|
224
|
+
})
|
|
225
|
+
.finally(() => (this.reopening = null));
|
|
226
|
+
return this.reopening;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya2VyLXJlZ2lvbi1zb3VyY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3JlZ2lvbi1zb3VyY2Uvd29ya2VyLXJlZ2lvbi1zb3VyY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7R0FPRztBQUNILE9BQU8sRUFBZ0IsZUFBZSxFQUFpQixTQUFTLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMxRixPQUFPLEVBS0wsa0JBQWtCLEdBQ25CLE1BQU0scUJBQXFCLENBQUM7QUFlN0IsNEVBQTRFO0FBQzVFLE1BQU0sZUFBZ0IsU0FBUSxLQUFLO0lBQ2pDO1FBQ0UsS0FBSyxDQUFDLG1DQUFtQyxDQUFDLENBQUM7UUFDM0MsSUFBSSxDQUFDLElBQUksR0FBRyxpQkFBaUIsQ0FBQztJQUNoQyxDQUFDO0NBQ0Y7QUFPRCxtRUFBbUU7QUFDbkUsTUFBTSxPQUFPLHdCQUF3QjtJQVVuQzs7OztPQUlHO0lBQ0gsWUFBNkIsT0FBbUM7UUFBbkMsWUFBTyxHQUFQLE9BQU8sQ0FBNEI7UUFkeEQsV0FBTSxHQUFrQixJQUFJLENBQUM7UUFDN0IsYUFBUSxHQUFrQyxJQUFJLENBQUM7UUFDL0MsZ0JBQVcsR0FBRyxLQUFLLENBQUM7UUFDcEIsV0FBTSxHQUFHLENBQUMsQ0FBQztRQUNGLFlBQU8sR0FBRyxJQUFJLEdBQUcsRUFBdUIsQ0FBQztRQUMxRCx1REFBdUQ7UUFDL0MsVUFBSyxHQUE4QixJQUFJLENBQUM7UUFDeEMsV0FBTSxHQUFHLENBQUMsQ0FBQztJQU9nRCxDQUFDO0lBRXBFLGdEQUFnRDtJQUNoRCxJQUFJLFFBQVE7UUFDVixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUM7SUFDMUIsQ0FBQztJQUVEOzs7T0FHRztJQUNILElBQUksVUFBVTtRQUNaLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUNyQixDQUFDO0lBRUQsK0RBQStEO0lBQy9ELEtBQUssQ0FBQyxJQUFJLENBQWdDLE9BQVU7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SUFDSCxDQUFDO0lBRUQsaUdBQWlHO0lBQ3pGLE1BQU07UUFDWixJQUFJLENBQUMsU0FBUyxLQUFLLElBQUksQ0FBQyxNQUFNO2FBQzNCLEdBQUcsQ0FBQyxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQzthQUNwQyxJQUFJLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFO1lBQy9CLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztZQUM1QixJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztRQUMvQixDQUFDLENBQUM7YUFDRCxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDMUMsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQ3hCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQSB7QGxpbmsgUmVnaW9uU291cmNlfSBvdmVyIGEgR2VvSlNPTiBzdHJpbmcsIHBhcnNlZCBhbmQgdGlsZWQgaW4gdGhlIHJlZ2lvbi1zb3VyY2UgV2ViIFdvcmtlci5cbiAqXG4gKiBPbmUgd29ya2VyIHNlcnZlcyBldmVyeSBvcGVuIHNvdXJjZS4gV2hlcmUgbm8gd29ya2VyIGNhbiBzdGFydCAoanNkb20sIFNTUiwgYSBibG9ja2VkIHdvcmtlclxuICogVVJMKSB0aGUgc2FtZSB0YWJsZXMgcnVuIG9uIHRoZSBtYWluIHRocmVhZDsgaWYgdGhlIHdvcmtlciBkaWVzLCBlYWNoIHNvdXJjZSByZS1vcGVucyBpdHNlbGZcbiAqIHRoZXJlIGZyb20gaXRzIHRleHQgKHdoaWNoIHRoZSBob3N0IGhvbGRzIGFueXdheTogaXQgaGFuZGVkIGl0IG92ZXIpIGFuZCBjYXJyaWVzIG9uIOKAlCB3aGV0aGVyXG4gKiBpdCBoYWQgYSBjYWxsIGluIGZsaWdodCB0aGVuIG9yIG5vdCAoc2VlIHtAbGluayBSZWdpb25Tb3VyY2VXb3JrZXJDbGllbnQuZ2VuZXJhdGlvbn0pLlxuICovXG5pbXBvcnQgeyBSZWdpb25Tb3VyY2UsIFJlZ2lvblRpbGVDYWNoZSwgU291cmNlRmVhdHVyZSwgYWJvcnRhYmxlIH0gZnJvbSAnLi9yZWdpb24tc291cmNlJztcbmltcG9ydCB7XG4gIFJlZ2lvblNvdXJjZU1lc3NhZ2UsXG4gIFJlZ2lvblNvdXJjZVJlcGx5LFxuICBSZWdpb25Tb3VyY2VSZXF1ZXN0LFxuICBSZWdpb25Tb3VyY2VSZXN1bHRzLFxuICBSZWdpb25Tb3VyY2VUYWJsZXMsXG59IGZyb20gJy4vcmVnaW9uLXNvdXJjZS1vcHMnO1xuaW1wb3J0IHR5cGUge1xuICBDbGFzc091dGxpbmVzLFxuICBSZWdpb25JbmRleFBhZ2UsXG4gIFJlZ2lvbkluZGV4UXVlcnksXG4gIFJlZ2lvblNvdXJjZUluZm8sXG4gIFJlZ2lvblRpbGUsXG4gIFJlZ2lvblRpbGVLZXksXG59IGZyb20gJy4vcmVnaW9uLXRpbGVzJztcbmltcG9ydCB0eXBlIHsgUmVjb25zdHJ1Y3RPcHRpb25zLCBTbGljZU91dGxpbmVzIH0gZnJvbSAnLi4vZ2VvbWV0cnkvcmVjb25zdHJ1Y3QnO1xuaW1wb3J0IHR5cGUgeyBNZXNoIH0gZnJvbSAnbmFwYXJpLWpzL2dlb21ldHJ5JztcblxuLyoqIE1ha2VzIHRoZSB3b3JrZXI7IG1heSBiZSBhc3luYywgYXMgdGhlIGRlZmF1bHQgb25lIGlzIChpdCBpbXBvcnRzIHRoZSBmYWN0b3J5IG9uIGRlbWFuZCkuICovXG5leHBvcnQgdHlwZSBSZWdpb25Tb3VyY2VXb3JrZXJGYWN0b3J5ID0gKCkgPT4gV29ya2VyIHwgUHJvbWlzZTxXb3JrZXI+O1xuXG4vKiogVGhlIHdvcmtlciBkaWVkIHVuZGVyIGEgY2FsbDsgdGhlIGNhbGxlciByZS1vcGVucyBvbiB0aGUgbWFpbiB0aHJlYWQuICovXG5jbGFzcyBXb3JrZXJMb3N0RXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCdUaGUgcmVnaW9uLXNvdXJjZSB3b3JrZXIgc3RvcHBlZC4nKTtcbiAgICB0aGlzLm5hbWUgPSAnV29ya2VyTG9zdEVycm9yJztcbiAgfVxufVxuXG5pbnRlcmZhY2UgUGVuZGluZ0NhbGwge1xuICByZXNvbHZlOiAodmFsdWU6IHVua25vd24pID0+IHZvaWQ7XG4gIHJlamVjdDogKHJlYXNvbjogdW5rbm93bikgPT4gdm9pZDtcbn1cblxuLyoqIE93bnMgdGhlIHJlZ2lvbi1zb3VyY2Ugd29ya2VyIGFuZCB0aGUgY2FsbHMgaW4gZmxpZ2h0IG9uIGl0LiAqL1xuZXhwb3J0IGNsYXNzIFJlZ2lvblNvdXJjZVdvcmtlckNsaWVudCB7XG4gIHByaXZhdGUgd29ya2VyOiBXb3JrZXIgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBzdGFydGluZzogUHJvbWlzZTxXb3JrZXIgfCBudWxsPiB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHVuYXZhaWxhYmxlID0gZmFsc2U7XG4gIHByaXZhdGUgbmV4dElkID0gMTtcbiAgcHJpdmF0ZSByZWFkb25seSBwZW5kaW5nID0gbmV3IE1hcDxudW1iZXIsIFBlbmRpbmdDYWxsPigpO1xuICAvKiogVGhlIG1haW4tdGhyZWFkIHRhYmxlcywgb25jZSBhbnl0aGluZyBydW5zIGhlcmUuICovXG4gIHByaXZhdGUgbG9jYWw6IFJlZ2lvblNvdXJjZVRhYmxlcyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHRhYmxlcyA9IDA7XG5cbiAgLyoqXG4gICAqIGBmYWN0b3J5YCBpcyBvcHRpb25hbDogd2l0aG91dCBvbmUgdGhlIHJlYWwgd29ya2VyIG1vZHVsZSBpcyBpbXBvcnRlZCBvbiBkZW1hbmQg4oCUXG4gICAqIGR5bmFtaWNhbGx5LCBiZWNhdXNlIGl0IGhvbGRzIGFuIGBpbXBvcnQubWV0YS51cmxgIHRoYXQgdHMtamVzdCdzIENvbW1vbkpTIGNvbXBpbGVcbiAgICogcmVqZWN0cy5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgZmFjdG9yeT86IFJlZ2lvblNvdXJjZVdvcmtlckZhY3RvcnkpIHt9XG5cbiAgLyoqIFdoZXRoZXIgY2FsbHMgbm93IHJ1biBvbiB0aGUgbWFpbiB0aHJlYWQuICovXG4gIGdldCBpblRocmVhZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy51bmF2YWlsYWJsZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGljaCB0YWJsZSBzZXQgY2FsbHMgcnVuIG9uOiBidW1wZWQgd2hlbiB0aGUgd29ya2VyIGlzIGxvc3QuIEEgaGFuZGxlIG9wZW5lZCB1bmRlciBhbm90aGVyXG4gICAqIG5hbWVzIGEgdGFibGUgdGhhdCBpcyBnb25lIChvciwgaGVyZSwgYW5vdGhlciBzb3VyY2UncyksIHNvIGl0cyBzb3VyY2UgbXVzdCBvcGVuIGFnYWluLlxuICAgKi9cbiAgZ2V0IGdlbmVyYXRpb24oKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy50YWJsZXM7XG4gIH1cblxuICAvKiogUnVuIGByZXF1ZXN0YCBpbiB0aGUgd29ya2VyLCBvciBoZXJlIHdoZW4gdGhlcmUgaXMgbm9uZS4gKi9cbiAgYXN5bmMgY2FsbDxSIGV4dGVuZHMgUmVnaW9uU291cmNlUmVxdWVzdD4ocmVxdWVzdDogUik6IFByb21pc2U8UmVnaW9uU291cmNlUmVzdWx0c1tSWydvcCddXT4ge1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5ydW4ocmVxdWVzdCkpLnJlc3VsdDtcbiAgfVxuXG4gIC8qKiB7QGxpbmsgY2FsbH0sIHdpdGggdGhlIHtAbGluayBnZW5lcmF0aW9ufSB0aGUgcmVxdWVzdCByYW4gb24uICovXG4gIGFzeW5jIHJ1bjxSIGV4dGVuZHMgUmVnaW9uU291cmNlUmVxdWVzdD4oXG4gICAgcmVxdWVzdDogUixcbiAgKTogUHJvbWlzZTx7IHJlc3VsdDogUmVnaW9uU291cmNlUmVzdWx0c1tSWydvcCddXTsgZ2VuZXJhdGlvbjogbnVtYmVyIH0+IHtcbiAgICBjb25zdCBzdGFydGVkID0gYXdhaXQgdGhpcy5lbnN1cmVXb3JrZXIoKTtcbiAgICAvLyBUaGUgd29ya2VyIG1heSBoYXZlIGJlZW4gbG9zdCB3aGlsZSB0aGlzIHdhaXRlZCBmb3IgaXQuXG4gICAgY29uc3Qgd29ya2VyID0gc3RhcnRlZCA9PT0gdGhpcy53b3JrZXIgPyBzdGFydGVkIDogbnVsbDtcbiAgICBjb25zdCBnZW5lcmF0aW9uID0gdGhpcy50YWJsZXM7XG4gICAgaWYgKCF3b3JrZXIpIHJldHVybiB7IHJlc3VsdDogKHRoaXMubG9jYWwgPz89IG5ldyBSZWdpb25Tb3VyY2VUYWJsZXMoKSkucnVuKHJlcXVlc3QpLCBnZW5lcmF0aW9uIH07XG4gICAgY29uc3QgaWQgPSB0aGlzLm5leHRJZCsrO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IG5ldyBQcm9taXNlPFJlZ2lvblNvdXJjZVJlc3VsdHNbUlsnb3AnXV0+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMucGVuZGluZy5zZXQoaWQsIHsgcmVzb2x2ZTogcmVzb2x2ZSBhcyAodjogdW5rbm93bikgPT4gdm9pZCwgcmVqZWN0IH0pO1xuICAgICAgd29ya2VyLnBvc3RNZXNzYWdlKHsgLi4ucmVxdWVzdCwgaWQgfSBhcyBSZWdpb25Tb3VyY2VNZXNzYWdlKTtcbiAgICB9KTtcbiAgICByZXR1cm4geyByZXN1bHQsIGdlbmVyYXRpb24gfTtcbiAgfVxuXG4gIC8qKiBUZXJtaW5hdGUgdGhlIHdvcmtlcjsgY2FsbHMgaW4gZmxpZ2h0IHJlamVjdC4gKi9cbiAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICB0aGlzLmxvc2UoKTtcbiAgfVxuXG4gIHByaXZhdGUgZW5zdXJlV29ya2VyKCk6IFByb21pc2U8V29ya2VyIHwgbnVsbD4ge1xuICAgIGlmICh0aGlzLndvcmtlcikgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzLndvcmtlcik7XG4gICAgaWYgKHRoaXMudW5hdmFpbGFibGUgfHwgKCF0aGlzLmZhY3RvcnkgJiYgdHlwZW9mIFdvcmtlciA9PT0gJ3VuZGVmaW5lZCcpKSB7XG4gICAgICB0aGlzLnVuYXZhaWxhYmxlID0gdHJ1ZTtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobnVsbCk7XG4gICAgfVxuICAgIGlmICghdGhpcy5zdGFydGluZykge1xuICAgICAgY29uc3Qgc3RhcnRpbmcgPSB0aGlzLnN0YXJ0V29ya2VyKCk7XG4gICAgICB0aGlzLnN0YXJ0aW5nID0gc3RhcnRpbmc7XG4gICAgICB2b2lkIHN0YXJ0aW5nLnRoZW4oKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5zdGFydGluZyA9PT0gc3RhcnRpbmcpIHRoaXMuc3RhcnRpbmcgPSBudWxsO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnN0YXJ0aW5nO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzdGFydFdvcmtlcigpOiBQcm9taXNlPFdvcmtlciB8IG51bGw+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgbWFkZSA9IHRoaXMuZmFjdG9yeVxuICAgICAgICA/IHRoaXMuZmFjdG9yeSgpXG4gICAgICAgIDogaW1wb3J0KCcuL3JlZ2lvbi1zb3VyY2Utd29ya2VyJykudGhlbigobSkgPT4gbS5jcmVhdGVSZWdpb25Tb3VyY2VXb3JrZXIoKSk7XG4gICAgICBjb25zdCB3b3JrZXIgPSBtYWRlIGluc3RhbmNlb2YgUHJvbWlzZSA/IGF3YWl0IG1hZGUgOiBtYWRlO1xuICAgICAgd29ya2VyLm9ubWVzc2FnZSA9IChldmVudDogTWVzc2FnZUV2ZW50PFJlZ2lvblNvdXJjZVJlcGx5PikgPT4gdGhpcy5vblJlcGx5KGV2ZW50LmRhdGEpO1xuICAgICAgd29ya2VyLm9uZXJyb3IgPSAoZXZlbnQ6IEV2ZW50KSA9PiB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0Py4oKTtcbiAgICAgICAgaWYgKHdvcmtlciA9PT0gdGhpcy53b3JrZXIpIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oJ1tyZWdpb24tc291cmNlXSB3b3JrZXIgZmFpbGVkOyB0aWxpbmcgb24gdGhlIG1haW4gdGhyZWFkJyk7XG4gICAgICAgICAgdGhpcy5sb3NlKCk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICB0aGlzLndvcmtlciA9IHdvcmtlcjtcbiAgICAgIHJldHVybiB3b3JrZXI7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1tyZWdpb24tc291cmNlXSB3b3JrZXIgdW5hdmFpbGFibGU7IHRpbGluZyBvbiB0aGUgbWFpbiB0aHJlYWQnLCBlcnIpO1xuICAgICAgdGhpcy51bmF2YWlsYWJsZSA9IHRydWU7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG9uUmVwbHkocmVwbHk6IFJlZ2lvblNvdXJjZVJlcGx5KTogdm9pZCB7XG4gICAgY29uc3QgY2FsbCA9IHRoaXMucGVuZGluZy5nZXQocmVwbHkuaWQpO1xuICAgIGlmICghY2FsbCkgcmV0dXJuO1xuICAgIHRoaXMucGVuZGluZy5kZWxldGUocmVwbHkuaWQpO1xuICAgIGlmIChyZXBseS5vaykgY2FsbC5yZXNvbHZlKHJlcGx5LnJlc3VsdCk7XG4gICAgZWxzZSBjYWxsLnJlamVjdChuZXcgRXJyb3IocmVwbHkuZXJyb3IpKTtcbiAgfVxuXG4gIC8qKiBTdG9wIHRoZSB3b3JrZXIgZm9yIGdvb2Q6IGV2ZXJ5IGxhdGVyIGNhbGwgcnVucyBoZXJlLCBldmVyeSBjYWxsIGluIGZsaWdodCBpcyBsb3N0LiAqL1xuICBwcml2YXRlIGxvc2UoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMud29ya2VyKSB0aGlzLnRhYmxlcysrO1xuICAgIHRoaXMudW5hdmFpbGFibGUgPSB0cnVlO1xuICAgIHRoaXMud29ya2VyPy50ZXJtaW5hdGUoKTtcbiAgICB0aGlzLndvcmtlciA9IG51bGw7XG4gICAgY29uc3QgY2FsbHMgPSBbLi4udGhpcy5wZW5kaW5nLnZhbHVlcygpXTtcbiAgICB0aGlzLnBlbmRpbmcuY2xlYXIoKTtcbiAgICBmb3IgKGNvbnN0IGNhbGwgb2YgY2FsbHMpIGNhbGwucmVqZWN0KG5ldyBXb3JrZXJMb3N0RXJyb3IoKSk7XG4gIH1cbn1cblxubGV0IHNoYXJlZDogUmVnaW9uU291cmNlV29ya2VyQ2xpZW50IHwgbnVsbCA9IG51bGw7XG5cbi8qKiBUaGUgd29ya2VyIGNsaWVudCBldmVyeSBHZW9KU09OIHNvdXJjZSBzaGFyZXMuICovXG5leHBvcnQgZnVuY3Rpb24gc2hhcmVkUmVnaW9uU291cmNlQ2xpZW50KCk6IFJlZ2lvblNvdXJjZVdvcmtlckNsaWVudCB7XG4gIHJldHVybiAoc2hhcmVkID8/PSBuZXcgUmVnaW9uU291cmNlV29ya2VyQ2xpZW50KCkpO1xufVxuXG4vKipcbiAqIE9wZW4gYSBHZW9KU09OIEZlYXR1cmVDb2xsZWN0aW9uIHN0cmluZyBhcyBhIHRpbGVkIHJlZ2lvbiBzb3VyY2UuIFJlamVjdHMgb24gaW52YWxpZCBKU09OIG9yXG4gKiBhIGNvbGxlY3Rpb24gd2l0aG91dCBgZmVhdHVyZXNgLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gb3Blbkdlb0pzb25SZWdpb25Tb3VyY2UoXG4gIHRleHQ6IHN0cmluZyxcbiAgY2xpZW50OiBSZWdpb25Tb3VyY2VXb3JrZXJDbGllbnQgPSBzaGFyZWRSZWdpb25Tb3VyY2VDbGllbnQoKSxcbik6IFByb21pc2U8UmVnaW9uU291cmNlPiB7XG4gIC8vIFRoZSB3b3JrZXIgbG9zdCB1bmRlciB0aGUgb3Blbjogb3BlbiBvbiB0aGUgbWFpbiB0aHJlYWQgaW5zdGVhZC5cbiAgY29uc3Qgb3BlbmVkID0gYXdhaXQgY2xpZW50XG4gICAgLnJ1bih7IG9wOiAnb3BlbicsIHRleHQgfSlcbiAgICAuY2F0Y2goKGVycikgPT4gKGVyciBpbnN0YW5jZW9mIFdvcmtlckxvc3RFcnJvciA/IGNsaWVudC5ydW4oeyBvcDogJ29wZW4nLCB0ZXh0IH0pIDogUHJvbWlzZS5yZWplY3QoZXJyKSkpO1xuICBjb25zdCB7IGhhbmRsZSwgaW5mbyB9ID0gb3BlbmVkLnJlc3VsdDtcbiAgcmV0dXJuIG5ldyBXb3JrZXJSZWdpb25Tb3VyY2UoY2xpZW50LCB0ZXh0LCBoYW5kbGUsIG9wZW5lZC5nZW5lcmF0aW9uLCBpbmZvKTtcbn1cblxuLyoqXG4gKiBUaGUgM0QgcmVjb25zdHJ1Y3Rpb24gb2YgYSByZWdpb24gZnJvbSBpdHMgb3V0bGluZXMgb24gYSBzdGFjayAoc2VlIGBnZW9tZXRyeS9yZWNvbnN0cnVjdGApLFxuICogbWVzaGVkIGluIHRoZSByZWdpb24tc291cmNlIHdvcmtlciAob24gdGhlIG1haW4gdGhyZWFkIHdoZXJlIHRoZXJlIGlzIG5vbmUpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVjb25zdHJ1Y3RJbldvcmtlcihcbiAgc2xpY2VzOiByZWFkb25seSBTbGljZU91dGxpbmVzW10sXG4gIG9wdGlvbnM/OiBSZWNvbnN0cnVjdE9wdGlvbnMsXG4gIGNsaWVudDogUmVnaW9uU291cmNlV29ya2VyQ2xpZW50ID0gc2hhcmVkUmVnaW9uU291cmNlQ2xpZW50KCksXG4pOiBQcm9taXNlPE1lc2g+IHtcbiAgcmV0dXJuIGNsaWVudC5jYWxsKHsgb3A6ICdtZXNoJywgc2xpY2VzLCBvcHRpb25zIH0pO1xufVxuXG5jbGFzcyBXb3JrZXJSZWdpb25Tb3VyY2UgaW1wbGVtZW50cyBSZWdpb25Tb3VyY2Uge1xuICBwcml2YXRlIHJlYWRvbmx5IGNhY2hlID0gbmV3IFJlZ2lvblRpbGVDYWNoZSgpO1xuICBwcml2YXRlIGRpc3Bvc2VkID0gZmFsc2U7XG4gIC8qKiBUaGUgbWFpbi10aHJlYWQgcmUtb3BlbiBhZnRlciB0aGUgd29ya2VyIGRpZWQsIHNoYXJlZCBieSBldmVyeSBjYWxsIHRoYXQgZmluZHMgaXQgc28uICovXG4gIHByaXZhdGUgcmVvcGVuaW5nOiBQcm9taXNlPHZvaWQ+IHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBjbGllbnQ6IFJlZ2lvblNvdXJjZVdvcmtlckNsaWVudCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHRleHQ6IHN0cmluZyxcbiAgICBwcml2YXRlIGhhbmRsZTogbnVtYmVyLFxuICAgIC8qKiBUaGUgY2xpZW50J3Mge0BsaW5rIFJlZ2lvblNvdXJjZVdvcmtlckNsaWVudC5nZW5lcmF0aW9ufSB7QGxpbmsgaGFuZGxlfSB3YXMgb3BlbmVkIHVuZGVyLiAqL1xuICAgIHByaXZhdGUgZ2VuZXJhdGlvbjogbnVtYmVyLFxuICAgIHJlYWRvbmx5IGluZm86IFJlZ2lvblNvdXJjZUluZm8sXG4gICkge31cblxuICBnZXRUaWxlKHo6IG51bWJlciwga2V5OiBSZWdpb25UaWxlS2V5LCBzaWduYWw/OiBBYm9ydFNpZ25hbCk6IFByb21pc2U8UmVnaW9uVGlsZT4ge1xuICAgIGNvbnN0IHRpbGUgPSB0aGlzLmNhY2hlLmdldCh6LCBrZXksICgpID0+XG4gICAgICB0aGlzLmNhbGwoKGhhbmRsZSkgPT4gKHsgb3A6ICd0aWxlJywgaGFuZGxlLCB6LCBsZXZlbDoga2V5LmxldmVsLCBneDoga2V5Lmd4LCBneToga2V5Lmd5IH0pKSxcbiAgICApO1xuICAgIHJldHVybiBhYm9ydGFibGUodGlsZSwgc2lnbmFsKTtcbiAgfVxuXG4gIGdldEZlYXR1cmVzKGlkczogcmVhZG9ubHkgc3RyaW5nW10pOiBQcm9taXNlPFNvdXJjZUZlYXR1cmVbXT4ge1xuICAgIHJldHVybiB0aGlzLmNhbGwoKGhhbmRsZSkgPT4gKHsgb3A6ICdmZWF0dXJlcycsIGhhbmRsZSwgaWRzIH0pKTtcbiAgfVxuXG4gIGdldEluZGV4KHo6IG51bWJlciwgcXVlcnk6IFJlZ2lvbkluZGV4UXVlcnkpOiBQcm9taXNlPFJlZ2lvbkluZGV4UGFnZT4ge1xuICAgIHJldHVybiB0aGlzLmNhbGwoKGhhbmRsZSkgPT4gKHsgb3A6ICdpbmRleCcsIGhhbmRsZSwgeiwgcXVlcnkgfSkpO1xuICB9XG5cbiAgZ2V0Q2xhc3NPdXRsaW5lcyhcbiAgICBjbGFzc2VzOiByZWFkb25seSBzdHJpbmdbXSB8IG51bGwsXG4gICAgbGV2ZWw6IG51bWJlcixcbiAgICBleGNsdWRlPzogcmVhZG9ubHkgc3RyaW5nW10sXG4gICk6IFByb21pc2U8Q2xhc3NPdXRsaW5lc1tdPiB7XG4gICAgcmV0dXJuIHRoaXMuY2FsbCgoaGFuZGxlKSA9PiAoeyBvcDogJ291dGxpbmVzJywgaGFuZGxlLCBjbGFzc2VzLCBsZXZlbCwgZXhjbHVkZSB9KSk7XG4gIH1cblxuICBnZXRDbGFzc0NvdW50cyh6OiBudW1iZXIgfCBudWxsLCBleGNsdWRlPzogcmVhZG9ubHkgc3RyaW5nW10pOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIG51bWJlcj4+IHtcbiAgICByZXR1cm4gdGhpcy5jYWxsKChoYW5kbGUpID0+ICh7IG9wOiAnY2xhc3NlcycsIGhhbmRsZSwgeiwgZXhjbHVkZSB9KSk7XG4gIH1cblxuICBleHBvcnRHZW9Kc29uKGV4Y2x1ZGU6IHJlYWRvbmx5IHN0cmluZ1tdLCBleHRyYTogcmVhZG9ubHkgb2JqZWN0W10pOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHJldHVybiB0aGlzLmNhbGwoKGhhbmRsZSkgPT4gKHsgb3A6ICdleHBvcnQnLCBoYW5kbGUsIGV4Y2x1ZGUsIGV4dHJhIH0pKTtcbiAgfVxuXG4gIGRpc3Bvc2UoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZGlzcG9zZWQpIHJldHVybjtcbiAgICB0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgICB0aGlzLmNhY2hlLmNsZWFyKCk7XG4gICAgLy8gQSBoYW5kbGUgZnJvbSBhIGxvc3Qgd29ya2VyJ3MgdGFibGVzIG5hbWVzIG5vdGhpbmcgaGVyZSwgb3IgYW5vdGhlciBzb3VyY2UncyB0YWJsZS5cbiAgICBpZiAodGhpcy5nZW5lcmF0aW9uICE9PSB0aGlzLmNsaWVudC5nZW5lcmF0aW9uKSByZXR1cm47XG4gICAgdm9pZCB0aGlzLmNsaWVudC5jYWxsKHsgb3A6ICdjbG9zZScsIGhhbmRsZTogdGhpcy5oYW5kbGUgfSkuY2F0Y2goKCkgPT4gdW5kZWZpbmVkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW4gYSByZXF1ZXN0IG9uIHRoaXMgc291cmNlJ3MgdGFibGU7IHdoZW4gdGhlIHdvcmtlciBkaWVkICh1bmRlciB0aGlzIGNhbGwgb3IgYmVmb3JlIGl0KSxcbiAgICogcmUtb3BlbiBoZXJlIGFuZCBydW4gaXQgdGhlcmUuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGNhbGw8UiBleHRlbmRzIFJlZ2lvblNvdXJjZVJlcXVlc3Q+KFxuICAgIG1ha2U6IChoYW5kbGU6IG51bWJlcikgPT4gUixcbiAgKTogUHJvbWlzZTxSZWdpb25Tb3VyY2VSZXN1bHRzW1JbJ29wJ11dPiB7XG4gICAgZm9yIChsZXQgYXR0ZW1wdCA9IDA7IDsgYXR0ZW1wdCsrKSB7XG4gICAgICBpZiAodGhpcy5nZW5lcmF0aW9uICE9PSB0aGlzLmNsaWVudC5nZW5lcmF0aW9uKSBhd2FpdCB0aGlzLnJlb3BlbigpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2xpZW50LmNhbGwobWFrZSh0aGlzLmhhbmRsZSkpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGlmICghKGVyciBpbnN0YW5jZW9mIFdvcmtlckxvc3RFcnJvcikgfHwgYXR0ZW1wdCA+IDApIHRocm93IGVycjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKiogT3BlbiB0aGlzIHNvdXJjZSdzIHRleHQgYWdhaW4gb24gdGhlIGNsaWVudCdzIGN1cnJlbnQgdGFibGVzLCBvbmNlIGZvciBldmVyeSBjYWxsIHdhaXRpbmcuICovXG4gIHByaXZhdGUgcmVvcGVuKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMucmVvcGVuaW5nID8/PSB0aGlzLmNsaWVudFxuICAgICAgLnJ1bih7IG9wOiAnb3BlbicsIHRleHQ6IHRoaXMudGV4dCB9KVxuICAgICAgLnRoZW4oKHsgcmVzdWx0LCBnZW5lcmF0aW9uIH0pID0+IHtcbiAgICAgICAgdGhpcy5oYW5kbGUgPSByZXN1bHQuaGFuZGxlO1xuICAgICAgICB0aGlzLmdlbmVyYXRpb24gPSBnZW5lcmF0aW9uO1xuICAgICAgfSlcbiAgICAgIC5maW5hbGx5KCgpID0+ICh0aGlzLnJlb3BlbmluZyA9IG51bGwpKTtcbiAgICByZXR1cm4gdGhpcy5yZW9wZW5pbmc7XG4gIH1cbn1cbiJdfQ==
|