@jax-data-science/sci-image-visualizer 0.2.16 → 0.2.18
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 +6 -1
- package/esm2022/lib/contracts/semantic-segmenter.contract.mjs +11 -0
- package/esm2022/lib/toolbar/segmentation/retinal-layer-tool.service.mjs +197 -0
- package/esm2022/lib/toolbar/segmentation/retinal-model-registry.mjs +119 -0
- package/esm2022/lib/toolbar/segmentation/retinal-segmenter.service.mjs +172 -0
- package/esm2022/lib/toolbar/segmentation/yolo-detect-tool.service.mjs +19 -3
- package/esm2022/lib/toolbar/toolbar.component.mjs +31 -3
- package/esm2022/lib/visualizer.component.mjs +86 -22
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +612 -20
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs.map +1 -1
- package/index.d.ts +4 -0
- package/lib/contracts/semantic-segmenter.contract.d.ts +105 -0
- package/lib/toolbar/segmentation/retinal-layer-tool.service.d.ts +49 -0
- package/lib/toolbar/segmentation/retinal-model-registry.d.ts +71 -0
- package/lib/toolbar/segmentation/retinal-segmenter.service.d.ts +60 -0
- package/lib/toolbar/toolbar.component.d.ts +15 -1
- package/lib/visualizer.component.d.ts +38 -2
- package/package.json +2 -1
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { getOrtWasmBase } from './ort-runtime-config';
|
|
3
|
+
import { getDefaultRetinalModelId, getRetinalModel, } from './retinal-model-registry';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
/**
|
|
6
|
+
* Default in-library {@link ISemanticSegmenter}, backed by jax-ai-js.
|
|
7
|
+
*
|
|
8
|
+
* `jax-ai-js` is a regular dependency but is **lazy-imported** on first use, so
|
|
9
|
+
* apps that never segment retinal layers pay nothing for it — or for
|
|
10
|
+
* onnxruntime-web — in their initial bundle. Mirrors
|
|
11
|
+
* {@link YoloSegmenterService}, including its per-model-id cache.
|
|
12
|
+
*
|
|
13
|
+
* WEBGPU ONLY, AND A HOST MUST BE READY FOR THAT
|
|
14
|
+
* Unlike the YOLO and Cellpose services, there is no WASM fallback to degrade
|
|
15
|
+
* to: ORT-Web's WASM EP dies with `std::bad_alloc` on these graphs at 512², at
|
|
16
|
+
* every precision. jax-ai-js throws `WebGpuRequiredError` rather than trying,
|
|
17
|
+
* and it is re-thrown here unchanged so a host can show a real
|
|
18
|
+
* unsupported-browser message instead of a generic failure.
|
|
19
|
+
*/
|
|
20
|
+
export class RetinalSegmenterService {
|
|
21
|
+
constructor() {
|
|
22
|
+
this.instances = new Map();
|
|
23
|
+
this.loading = new Map();
|
|
24
|
+
}
|
|
25
|
+
async segmentSemantic(image, opts = {}, progress) {
|
|
26
|
+
const modelId = opts.modelId ?? getDefaultRetinalModelId();
|
|
27
|
+
const def = this.requireModel(modelId);
|
|
28
|
+
let announcedDownload = false;
|
|
29
|
+
const seg = await this.getModel(modelId, (loaded, total) => {
|
|
30
|
+
if (total)
|
|
31
|
+
progress?.onProgress?.(loaded / total);
|
|
32
|
+
progress?.onBytes?.(loaded, total);
|
|
33
|
+
if (loaded > 0 && !announcedDownload) {
|
|
34
|
+
announcedDownload = true;
|
|
35
|
+
// The size is in the message because it is ~590 MB — a user who
|
|
36
|
+
// clicked a button deserves to know that before it finishes.
|
|
37
|
+
progress?.onStatus?.(`Downloading ${def.label} model (~${def.sizeMb} MB)…`);
|
|
38
|
+
}
|
|
39
|
+
}, (status) => progress?.onStatus?.(status),
|
|
40
|
+
// A run cancelled mid-download should stop the download, not just the
|
|
41
|
+
// inference queued behind it.
|
|
42
|
+
opts.signal);
|
|
43
|
+
progress?.onStatus?.('Running inference…');
|
|
44
|
+
const result = await seg.segment({ data: image.data, width: image.width, height: image.height }, {
|
|
45
|
+
...(opts.classThreshold !== undefined ? { classThreshold: opts.classThreshold } : {}),
|
|
46
|
+
...(opts.classFilter ? { classFilter: opts.classFilter } : {}),
|
|
47
|
+
...(opts.simplifyTolerance !== undefined ? { simplifyTolerance: opts.simplifyTolerance } : {}),
|
|
48
|
+
...(opts.minArea !== undefined ? { minArea: opts.minArea } : {}),
|
|
49
|
+
...(opts.signal ? { signal: opts.signal } : {}),
|
|
50
|
+
// The library narrates its own phases (per patch, then tracing) because
|
|
51
|
+
// only it knows which one it is in.
|
|
52
|
+
onStatus: (s) => progress?.onStatus?.(s),
|
|
53
|
+
});
|
|
54
|
+
const regions = result.regions.map((r) => ({
|
|
55
|
+
exterior: r.exterior.map(([x, y]) => [x, y]),
|
|
56
|
+
holes: r.holes.map((h) => h.map(([x, y]) => [x, y])),
|
|
57
|
+
classId: r.classId,
|
|
58
|
+
className: r.className,
|
|
59
|
+
area: r.area,
|
|
60
|
+
}));
|
|
61
|
+
return {
|
|
62
|
+
regions,
|
|
63
|
+
classAreas: result.classAreas,
|
|
64
|
+
classNames: [...result.classNames],
|
|
65
|
+
width: result.width,
|
|
66
|
+
height: result.height,
|
|
67
|
+
unassignedFraction: result.unassignedFraction,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* The shared segmenter for a model id, created on first use and reused
|
|
72
|
+
* thereafter (deduped across concurrent callers). Exposed so a host's
|
|
73
|
+
* processing pipeline can run on the same loaded session rather than paying
|
|
74
|
+
* the ~590 MB load twice.
|
|
75
|
+
*/
|
|
76
|
+
getModel(modelId = getDefaultRetinalModelId(), onProgress, onStatus,
|
|
77
|
+
/**
|
|
78
|
+
* Abort the load. This model is ~590 MB, so a cancel has to reach the
|
|
79
|
+
* *download* — aborting only the inference that follows leaves the transfer
|
|
80
|
+
* running and the UI stuck in "Cancelling" until it completes.
|
|
81
|
+
*
|
|
82
|
+
* Deliberately not applied to a load already in flight: that promise may be
|
|
83
|
+
* shared with another caller (the toolbar tool and the pipeline both use
|
|
84
|
+
* this service), and one caller's cancel must not tear the model out from
|
|
85
|
+
* under the other. A second caller joining an in-flight load simply waits.
|
|
86
|
+
*/
|
|
87
|
+
signal) {
|
|
88
|
+
const existing = this.instances.get(modelId);
|
|
89
|
+
if (existing)
|
|
90
|
+
return Promise.resolve(existing);
|
|
91
|
+
const inFlight = this.loading.get(modelId);
|
|
92
|
+
if (inFlight)
|
|
93
|
+
return inFlight;
|
|
94
|
+
const def = this.requireModel(modelId);
|
|
95
|
+
const load = (async () => {
|
|
96
|
+
// Lazy: keep jax-ai-js + its ORT runtime out of the initial bundle.
|
|
97
|
+
const { RetinalSegmenter, configureOrt } = await import('jax-ai-js');
|
|
98
|
+
configureOrt({ wasmPaths: getOrtWasmBase() });
|
|
99
|
+
const seg = await RetinalSegmenter.fromPretrained({
|
|
100
|
+
modelUrl: def.modelUrl,
|
|
101
|
+
...(def.metaUrl ? { metaUrl: def.metaUrl } : {}),
|
|
102
|
+
...(signal ? { signal } : {}),
|
|
103
|
+
onProgress: (loaded, total) => onProgress?.(loaded, total),
|
|
104
|
+
onStatus: (s) => onStatus?.(s),
|
|
105
|
+
});
|
|
106
|
+
this.instances.set(modelId, seg);
|
|
107
|
+
return seg;
|
|
108
|
+
})();
|
|
109
|
+
this.loading.set(modelId, load);
|
|
110
|
+
// A failed load must not poison the cache — the next caller should retry
|
|
111
|
+
// rather than inherit the rejected promise forever.
|
|
112
|
+
load.catch(() => this.loading.delete(modelId));
|
|
113
|
+
return load;
|
|
114
|
+
}
|
|
115
|
+
/** Whether a model is already loaded (warm). */
|
|
116
|
+
isLoaded(modelId = getDefaultRetinalModelId()) {
|
|
117
|
+
return this.instances.has(modelId);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Release one model, or all of them. Safe to call on a model never loaded.
|
|
121
|
+
*
|
|
122
|
+
* In-flight loads are torn down too: dropping a pending promise and returning
|
|
123
|
+
* would let the load finish afterwards, re-populate {@link instances}, and
|
|
124
|
+
* strand a live ORT session that nothing owns — disposal would report success
|
|
125
|
+
* while leaking. At 590 MB that leak is not survivable.
|
|
126
|
+
*/
|
|
127
|
+
async dispose(modelId) {
|
|
128
|
+
const ids = modelId
|
|
129
|
+
? [modelId]
|
|
130
|
+
: [...new Set([...this.instances.keys(), ...this.loading.keys()])];
|
|
131
|
+
await Promise.all(ids.map((id) => this.disposeOne(id)));
|
|
132
|
+
}
|
|
133
|
+
async disposeOne(id) {
|
|
134
|
+
const pending = this.loading.get(id);
|
|
135
|
+
const loaded = this.instances.get(id);
|
|
136
|
+
this.instances.delete(id);
|
|
137
|
+
this.loading.delete(id);
|
|
138
|
+
if (loaded)
|
|
139
|
+
await loaded.dispose();
|
|
140
|
+
if (!pending)
|
|
141
|
+
return;
|
|
142
|
+
// A pending load assigns instances[id] before its promise resolves, so by
|
|
143
|
+
// the time this await returns the entry is back. Clear it only if it still
|
|
144
|
+
// points at what *this* load produced — a newer load started meanwhile owns
|
|
145
|
+
// its own entry and must not be evicted.
|
|
146
|
+
const seg = await pending.catch(() => null);
|
|
147
|
+
if (!seg || seg === loaded)
|
|
148
|
+
return;
|
|
149
|
+
if (this.instances.get(id) === seg)
|
|
150
|
+
this.instances.delete(id);
|
|
151
|
+
await seg.dispose();
|
|
152
|
+
}
|
|
153
|
+
requireModel(modelId) {
|
|
154
|
+
const def = getRetinalModel(modelId);
|
|
155
|
+
if (!def)
|
|
156
|
+
throw new Error(`Unknown retinal model id "${modelId}".`);
|
|
157
|
+
if (!def.modelUrl.trim()) {
|
|
158
|
+
// Prefer the registry's specific explanation over "not configured" — the
|
|
159
|
+
// ResUNet-a entries are disabled for a documented accuracy reason, and a
|
|
160
|
+
// user who picked one deserves to be told which.
|
|
161
|
+
throw new Error(def.unavailableReason ?? `Retinal model "${modelId}" has no modelUrl configured.`);
|
|
162
|
+
}
|
|
163
|
+
return def;
|
|
164
|
+
}
|
|
165
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: RetinalSegmenterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
166
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: RetinalSegmenterService, providedIn: 'root' }); }
|
|
167
|
+
}
|
|
168
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: RetinalSegmenterService, decorators: [{
|
|
169
|
+
type: Injectable,
|
|
170
|
+
args: [{ providedIn: 'root' }]
|
|
171
|
+
}] });
|
|
172
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmV0aW5hbC1zZWdtZW50ZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvdG9vbGJhci9zZWdtZW50YXRpb24vcmV0aW5hbC1zZWdtZW50ZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTNDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN0RCxPQUFPLEVBQ0wsd0JBQXdCLEVBQ3hCLGVBQWUsR0FFaEIsTUFBTSwwQkFBMEIsQ0FBQzs7QUFXbEM7Ozs7Ozs7Ozs7Ozs7O0dBY0c7QUFFSCxNQUFNLE9BQU8sdUJBQXVCO0lBRHBDO1FBRW1CLGNBQVMsR0FBRyxJQUFJLEdBQUcsRUFBNEIsQ0FBQztRQUNoRCxZQUFPLEdBQUcsSUFBSSxHQUFHLEVBQXFDLENBQUM7S0FtS3pFO0lBaktDLEtBQUssQ0FBQyxlQUFlLENBQ25CLEtBQWlFLEVBQ2pFLE9BQStCLEVBQUUsRUFDakMsUUFBa0M7UUFFbEMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sSUFBSSx3QkFBd0IsRUFBRSxDQUFDO1FBQzNELE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFdkMsSUFBSSxpQkFBaUIsR0FBRyxLQUFLLENBQUM7UUFDOUIsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUM3QixPQUFPLEVBQ1AsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDaEIsSUFBSSxLQUFLO2dCQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUM7WUFDbEQsUUFBUSxFQUFFLE9BQU8sRUFBRSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNuQyxJQUFJLE1BQU0sR0FBRyxDQUFD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NkIsT0FBTyxJQUFJLENBQUMsQ0FBQztRQUNwRSxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQ3pCLHlFQUF5RTtZQUN6RSx5RUFBeUU7WUFDekUsaURBQWlEO1lBQ2pELE1BQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxDQUFDLGlCQUFpQixJQUFJLGtCQUFrQixPQUFPLCtCQUErQixDQUFDLENBQUM7UUFDckcsQ0FBQztRQUNELE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQzs4R0FwS1UsdUJBQXVCO2tIQUF2Qix1QkFBdUIsY0FEVixNQUFNOzsyRkFDbkIsdUJBQXVCO2tCQURuQyxVQUFVO21CQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgZ2V0T3J0V2FzbUJhc2UgfSBmcm9tICcuL29ydC1ydW50aW1lLWNvbmZpZyc7XG5pbXBvcnQge1xuICBnZXREZWZhdWx0UmV0aW5hbE1vZGVsSWQsXG4gIGdldFJldGluYWxNb2RlbCxcbiAgdHlwZSBSZXRpbmFsTW9kZWxEZWYsXG59IGZyb20gJy4vcmV0aW5hbC1tb2RlbC1yZWdpc3RyeSc7XG5cbmltcG9ydCB0eXBlIHtcbiAgSVNlbWFudGljU2VnbWVudGVyLFxuICBTZW1hbnRpY1JlZ2lvbixcbiAgU2VtYW50aWNTZWdtZW50YXRpb24sXG4gIFNlbWFudGljU2VnbWVudE9wdGlvbnMsXG4gIFNlbWFudGljU2VnbWVudFByb2dyZXNzLFxufSBmcm9tICcuLi8uLi9jb250cmFjdHMvc2VtYW50aWMtc2VnbWVudGVyLmNvbnRyYWN0JztcbmltcG9ydCB0eXBlIHsgUmV0aW5hbFNlZ21lbnRlciB9IGZyb20gJ2pheC1haS1qcyc7XG5cbi8qKlxuICogRGVmYXVsdCBpbi1saWJyYXJ5IHtAbGluayBJU2VtYW50aWNTZWdtZW50ZXJ9LCBiYWNrZWQgYnkgamF4LWFpLWpzLlxuICpcbiAqIGBqYXgtYWktanNgIGlzIGEgcmVndWxhciBkZXBlbmRlbmN5IGJ1dCBpcyAqKmxhenktaW1wb3J0ZWQqKiBvbiBmaXJzdCB1c2UsIHNvXG4gKiBhcHBzIHRoYXQgbmV2ZXIgc2VnbWVudCByZXRpbmFsIGxheWVycyBwYXkgbm90aGluZyBmb3IgaXQg4oCUIG9yIGZvclxuICogb25ueHJ1bnRpbWUtd2ViIOKAlCBpbiB0aGVpciBpbml0aWFsIGJ1bmRsZS4gTWlycm9yc1xuICoge0BsaW5rIFlvbG9TZWdtZW50ZXJTZXJ2aWNlfSwgaW5jbHVkaW5nIGl0cyBwZXItbW9kZWwtaWQgY2FjaGUuXG4gKlxuICogV0VCR1BVIE9OTFksIEFORCBBIEhPU1QgTVVTVCBCRSBSRUFEWSBGT1IgVEhBVFxuICogVW5saWtlIHRoZSBZT0xPIGFuZCBDZWxscG9zZSBzZXJ2aWNlcywgdGhlcmUgaXMgbm8gV0FTTSBmYWxsYmFjayB0byBkZWdyYWRlXG4gKiB0bzogT1JULVdlYidzIFdBU00gRVAgZGllcyB3aXRoIGBzdGQ6OmJhZF9hbGxvY2Agb24gdGhlc2UgZ3JhcGhzIGF0IDUxMsKyLCBhdFxuICogZXZlcnkgcHJlY2lzaW9uLiBqYXgtYWktanMgdGhyb3dzIGBXZWJHcHVSZXF1aXJlZEVycm9yYCByYXRoZXIgdGhhbiB0cnlpbmcsXG4gKiBhbmQgaXQgaXMgcmUtdGhyb3duIGhlcmUgdW5jaGFuZ2VkIHNvIGEgaG9zdCBjYW4gc2hvdyBhIHJlYWxcbiAqIHVuc3VwcG9ydGVkLWJyb3dzZXIgbWVzc2FnZSBpbnN0ZWFkIG9mIGEgZ2VuZXJpYyBmYWlsdXJlLlxuICovXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46ICdyb290JyB9KVxuZXhwb3J0IGNsYXNzIFJldGluYWxTZWdtZW50ZXJTZXJ2aWNlIGltcGxlbWVudHMgSVNlbWFudGljU2VnbWVudGVyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBpbnN0YW5jZXMgPSBuZXcgTWFwPHN0cmluZywgUmV0aW5hbFNlZ21lbnRlcj4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBsb2FkaW5nID0gbmV3IE1hcDxzdHJpbmcsIFByb21pc2U8UmV0aW5hbFNlZ21lbnRlcj4+KCk7XG5cbiAgYXN5bmMgc2VnbWVudFNlbWFudGljKFxuICAgIGltYWdlOiB7IGRhdGE6IFVpbnQ4Q2xhbXBlZEFycmF5OyB3aWR0aDogbnVtYmVyOyBoZWlnaHQ6IG51bWJlciB9LFxuICAgIG9wdHM6IFNlbWFudGljU2VnbWVudE9wdGlvbnMgPSB7fSxcbiAgICBwcm9ncmVzcz86IFNlbWFudGljU2VnbWVudFByb2dyZXNzLFxuICApOiBQcm9taXNlPFNlbWFudGljU2VnbWVudGF0aW9uPiB7XG4gICAgY29uc3QgbW9kZWxJZCA9IG9wdHMubW9kZWxJZCA/PyBnZXREZWZhdWx0UmV0aW5hbE1vZGVsSWQoKTtcbiAgICBjb25zdCBkZWYgPSB0aGlzLnJlcXVpcmVNb2RlbChtb2RlbElkKTtcblxuICAgIGxldCBhbm5vdW5jZWREb3dubG9hZCA9IGZhbHNlO1xuICAgIGNvbnN0IHNlZyA9IGF3YWl0IHRoaXMuZ2V0TW9kZWwoXG4gICAgICBtb2RlbElkLFxuICAgICAgKGxvYWRlZCwgdG90YWwpID0+IHtcbiAgICAgICAgaWYgKHRvdGFsKSBwcm9ncmVzcz8ub25Qcm9ncmVzcz8uKGxvYWRlZCAvIHRvdGFsKTtcbiAgICAgICAgcHJvZ3Jlc3M/Lm9uQnl0ZXM/Lihsb2FkZWQsIHRvdGFsKTtcbiAgICAgICAgaWYgKGxvYWRlZCA+IDAgJiYgIWFubm91bmNlZERvd25sb2FkKSB7XG4gICAgICAgICAgYW5ub3VuY2VkRG93bmxvYWQgPSB0cnVlO1xuICAgICAgICAgIC8vIFRoZSBzaXplIGlzIGluIHRoZSBtZXNzYWdlIGJlY2F1c2UgaXQgaXMgfjU5MCBNQiDigJQgYSB1c2VyIHdob1xuICAgICAgICAgIC8vIGNsaWNrZWQgYSBidXR0b24gZGVzZXJ2ZXMgdG8ga25vdyB0aGF0IGJlZm9yZSBpdCBmaW5pc2hlcy5cbiAgICAgICAgICBwcm9ncmVzcz8ub25TdGF0dXM/LihgRG93bmxvYWRpbmcgJHtkZWYubGFiZWx9IG1vZGVsICh+JHtkZWYuc2l6ZU1ifSBNQinigKZgKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIChzdGF0dXMpID0+IHByb2dyZXNzPy5vblN0YXR1cz8uKHN0YXR1cyksXG4gICAgICAvLyBBIHJ1biBjYW5jZWxsZWQgbWlkLWRvd25sb2FkIHNob3VsZCBzdG9wIHRoZSBkb3dubG9hZCwgbm90IGp1c3QgdGhlXG4gICAgICAvLyBpbmZlcmVuY2UgcXVldWVkIGJlaGluZCBpdC5cbiAgICAgIG9wdHMuc2lnbmFsLFxuICAgICk7XG5cbiAgICBwcm9ncmVzcz8ub25TdGF0dXM/LignUnVubmluZyBpbmZlcmVuY2XigKYnKTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzZWcuc2VnbWVudChcbiAgICAgIHsgZGF0YTogaW1hZ2UuZGF0YSwgd2lkdGg6IGltYWdlLndpZHRoLCBoZWlnaHQ6IGltYWdlLmhlaWdodCB9LFxuICAgICAge1xuICAgICAgICAuLi4ob3B0cy5jbGFzc1RocmVzaG9sZCAhPT0gdW5kZWZpbmVkID8geyBjbGFzc1RocmVzaG9sZDogb3B0cy5jbGFzc1RocmVzaG9sZCB9IDoge30pLFxuICAgICAgICAuLi4ob3B0cy5jbGFzc0ZpbHRlciA/IHsgY2xhc3NGaWx0ZXI6IG9wdHMuY2xhc3NGaWx0ZXIgfSA6IHt9KSxcbiAgICAgICAgLi4uKG9wdHMuc2ltcGxpZnlUb2xlcmFuY2UgIT09IHVuZGVmaW5lZCA/IHsgc2ltcGxpZnlUb2xlcmFuY2U6IG9wdHMuc2ltcGxpZnlUb2xlcmFuY2UgfSA6IHt9KSxcbiAgICAgICAgLi4uKG9wdHMubWluQXJlYSAhPT0gdW5kZWZpbmVkID8geyBtaW5BcmVhOiBvcHRzLm1pbkFyZWEgfSA6IHt9KSxcbiAgICAgICAgLi4uKG9wdHMuc2lnbmFsID8geyBzaWduYWw6IG9wdHMuc2lnbmFsIH0gOiB7fSksXG4gICAgICAgIC8vIFRoZSBsaWJyYXJ5IG5hcnJhdGVzIGl0cyBvd24gcGhhc2VzIChwZXIgcGF0Y2gsIHRoZW4gdHJhY2luZykgYmVjYXVzZVxuICAgICAgICAvLyBvbmx5IGl0IGtub3dzIHdoaWNoIG9uZSBpdCBpcyBpbi5cbiAgICAgICAgb25TdGF0dXM6IChzKSA9PiBwcm9ncmVzcz8ub25TdGF0dXM/LihzKSxcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIGNvbnN0IHJlZ2lvbnM6IFNlbWFudGljUmVnaW9uW10gPSByZXN1bHQucmVnaW9ucy5tYXAoKHIpID0+ICh7XG4gICAgICBleHRlcmlvcjogci5leHRlcmlvci5tYXAoKFt4LCB5XSk6IFtudW1iZXIsIG51bWJlcl0gPT4gW3gsIHldKSxcbiAgICAgIGhvbGVzOiByLmhvbGVzLm1hcCgoaCkgPT4gaC5tYXAoKFt4LCB5XSk6IFtudW1iZXIsIG51bWJlcl0gPT4gW3gsIHldKSksXG4gICAgICBjbGFzc0lkOiByLmNsYXNzSWQsXG4gICAgICBjbGFzc05hbWU6IHIuY2xhc3NOYW1lLFxuICAgICAgYXJlYTogci5hcmVhLFxuICAgIH0pKTtcblxuICAgIHJldHVybiB7XG4gICAgICByZWdpb25zLFxuICAgICAgY2xhc3NBcmVhczogcmVzdWx0LmNsYXNzQXJlYXMsXG4gICAgICBjbGFzc05hbWVzOiBbLi4ucmVzdWx0LmNsYXNzTmFtZXNdLFxuICAgICAgd2lkdGg6IHJlc3VsdC53aWR0aCxcbiAgICAgIGhlaWdodDogcmVzdWx0LmhlaWdodCxcbiAgICAgIHVuYXNzaWduZWRGcmFjdGlvbjogcmVzdWx0LnVuYXNzaWduZWRGcmFjdGlvbixcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBzaGFyZWQgc2VnbWVudGVyIGZvciBhIG1vZGVsIGlkLCBjcmVhdGVkIG9uIGZpcnN0IHVzZSBhbmQgcmV1c2VkXG4gICAqIHRoZXJlYWZ0ZXIgKGRlZHVwZWQgYWNyb3NzIGNvbmN1cnJlbnQgY2FsbGVycykuIEV4cG9zZWQgc28gYSBob3N0J3NcbiAgICogcHJvY2Vzc2luZyBwaXBlbGluZSBjYW4gcnVuIG9uIHRoZSBzYW1lIGxvYWRlZCBzZXNzaW9uIHJhdGhlciB0aGFuIHBheWluZ1xuICAgKiB0aGUgfjU5MCBNQiBsb2FkIHR3aWNlLlxuICAgKi9cbiAgZ2V0TW9kZWwoXG4gICAgbW9kZWxJZDogc3RyaW5nID0gZ2V0RGVmYXVsdFJldGluYWxNb2RlbElkKCksXG4gICAgb25Qcm9ncmVzcz86IChsb2FkZWQ6IG51bWJlciwgdG90YWw6IG51bWJlciB8IG51bGwpID0+IHZvaWQsXG4gICAgb25TdGF0dXM/OiAoc3RhdHVzOiBzdHJpbmcpID0+IHZvaWQsXG4gICAgLyoqXG4gICAgICogQWJvcnQgdGhlIGxvYWQuIFRoaXMgbW9kZWwgaXMgfjU5MCBNQiwgc28gYSBjYW5jZWwgaGFzIHRvIHJlYWNoIHRoZVxuICAgICAqICpkb3dubG9hZCog4oCUIGFib3J0aW5nIG9ubHkgdGhlIGluZmVyZW5jZSB0aGF0IGZvbGxvd3MgbGVhdmVzIHRoZSB0cmFuc2ZlclxuICAgICAqIHJ1bm5pbmcgYW5kIHRoZSBVSSBzdHVjayBpbiBcIkNhbmNlbGxpbmdcIiB1bnRpbCBpdCBjb21wbGV0ZXMuXG4gICAgICpcbiAgICAgKiBEZWxpYmVyYXRlbHkgbm90IGFwcGxpZWQgdG8gYSBsb2FkIGFscmVhZHkgaW4gZmxpZ2h0OiB0aGF0IHByb21pc2UgbWF5IGJlXG4gICAgICogc2hhcmVkIHdpdGggYW5vdGhlciBjYWxsZXIgKHRoZSB0b29sYmFyIHRvb2wgYW5kIHRoZSBwaXBlbGluZSBib3RoIHVzZVxuICAgICAqIHRoaXMgc2VydmljZSksIGFuZCBvbmUgY2FsbGVyJ3MgY2FuY2VsIG11c3Qgbm90IHRlYXIgdGhlIG1vZGVsIG91dCBmcm9tXG4gICAgICogdW5kZXIgdGhlIG90aGVyLiBBIHNlY29uZCBjYWxsZXIgam9pbmluZyBhbiBpbi1mbGlnaHQgbG9hZCBzaW1wbHkgd2FpdHMuXG4gICAgICovXG4gICAgc2lnbmFsPzogQWJvcnRTaWduYWwsXG4gICk6IFByb21pc2U8UmV0aW5hbFNlZ21lbnRlcj4ge1xuICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy5pbnN0YW5jZXMuZ2V0KG1vZGVsSWQpO1xuICAgIGlmIChleGlzdGluZykgcmV0dXJuIFByb21pc2UucmVzb2x2ZShleGlzdGluZyk7XG5cbiAgICBjb25zdCBpbkZsaWdodCA9IHRoaXMubG9hZGluZy5nZXQobW9kZWxJZCk7XG4gICAgaWYgKGluRmxpZ2h0KSByZXR1cm4gaW5GbGlnaHQ7XG5cbiAgICBjb25zdCBkZWYgPSB0aGlzLnJlcXVpcmVNb2RlbChtb2RlbElkKTtcbiAgICBjb25zdCBsb2FkID0gKGFzeW5jICgpID0+IHtcbiAgICAgIC8vIExhenk6IGtlZXAgamF4LWFpLWpzICsgaXRzIE9SVCBydW50aW1lIG91dCBvZiB0aGUgaW5pdGlhbCBidW5kbGUuXG4gICAgICBjb25zdCB7IFJldGluYWxTZWdtZW50ZXIsIGNvbmZpZ3VyZU9ydCB9ID0gYXdhaXQgaW1wb3J0KCdqYXgtYWktanMnKTtcbiAgICAgIGNvbmZpZ3VyZU9ydCh7IHdhc21QYXRoczogZ2V0T3J0V2FzbUJhc2UoKSB9KTtcbiAgICAgIGNvbnN0IHNlZyA9IGF3YWl0IFJldGluYWxTZWdtZW50ZXIuZnJvbVByZXRyYWluZWQoe1xuICAgICAgICBtb2RlbFVybDogZGVmLm1vZGVsVXJsLFxuICAgICAgICAuLi4oZGVmLm1ldGFVcmwgPyB7IG1ldGFVcmw6IGRlZi5tZXRhVXJsIH0gOiB7fSksXG4gICAgICAgIC4uLihzaWduYWwgPyB7IHNpZ25hbCB9IDoge30pLFxuICAgICAgICBvblByb2dyZXNzOiAobG9hZGVkLCB0b3RhbCkgPT4gb25Qcm9ncmVzcz8uKGxvYWRlZCwgdG90YWwpLFxuICAgICAgICBvblN0YXR1czogKHMpID0+IG9uU3RhdHVzPy4ocyksXG4gICAgICB9KTtcbiAgICAgIHRoaXMuaW5zdGFuY2VzLnNldChtb2RlbElkLCBzZWcpO1xuICAgICAgcmV0dXJuIHNlZztcbiAgICB9KSgpO1xuXG4gICAgdGhpcy5sb2FkaW5nLnNldChtb2RlbElkLCBsb2FkKTtcbiAgICAvLyBBIGZhaWxlZCBsb2FkIG11c3Qgbm90IHBvaXNvbiB0aGUgY2FjaGUg4oCUIHRoZSBuZXh0IGNhbGxlciBzaG91bGQgcmV0cnlcbiAgICAvLyByYXRoZXIgdGhhbiBpbmhlcml0IHRoZSByZWplY3RlZCBwcm9taXNlIGZvcmV2ZXIuXG4gICAgbG9hZC5jYXRjaCgoKSA9PiB0aGlzLmxvYWRpbmcuZGVsZXRlKG1vZGVsSWQpKTtcbiAgICByZXR1cm4gbG9hZDtcbiAgfVxuXG4gIC8qKiBXaGV0aGVyIGEgbW9kZWwgaXMgYWxyZWFkeSBsb2FkZWQgKHdhcm0pLiAqL1xuICBpc0xvYWRlZChtb2RlbElkOiBzdHJpbmcgPSBnZXREZWZhdWx0UmV0aW5hbE1vZGVsSWQoKSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmluc3RhbmNlcy5oYXMobW9kZWxJZCk7XG4gIH1cblxuICAvKipcbiAgICogUmVsZWFzZSBvbmUgbW9kZWwsIG9yIGFsbCBvZiB0aGVtLiBTYWZlIHRvIGNhbGwgb24gYSBtb2RlbCBuZXZlciBsb2FkZWQuXG4gICAqXG4gICAqIEluLWZsaWdodCBsb2FkcyBhcmUgdG9ybiBkb3duIHRvbzogZHJvcHBpbmcgYSBwZW5kaW5nIHByb21pc2UgYW5kIHJldHVybmluZ1xuICAgKiB3b3VsZCBsZXQgdGhlIGxvYWQgZmluaXNoIGFmdGVyd2FyZHMsIHJlLXBvcHVsYXRlIHtAbGluayBpbnN0YW5jZXN9LCBhbmRcbiAgICogc3RyYW5kIGEgbGl2ZSBPUlQgc2Vzc2lvbiB0aGF0IG5vdGhpbmcgb3ducyDigJQgZGlzcG9zYWwgd291bGQgcmVwb3J0IHN1Y2Nlc3NcbiAgICogd2hpbGUgbGVha2luZy4gQXQgNTkwIE1CIHRoYXQgbGVhayBpcyBub3Qgc3Vydml2YWJsZS5cbiAgICovXG4gIGFzeW5jIGRpc3Bvc2UobW9kZWxJZD86IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGlkcyA9IG1vZGVsSWRcbiAgICAgID8gW21vZGVsSWRdXG4gICAgICA6IFsuLi5uZXcgU2V0KFsuLi50aGlzLmluc3RhbmNlcy5rZXlzKCksIC4uLnRoaXMubG9hZGluZy5rZXlzKCldKV07XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoaWRzLm1hcCgoaWQpID0+IHRoaXMuZGlzcG9zZU9uZShpZCkpKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZGlzcG9zZU9uZShpZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcGVuZGluZyA9IHRoaXMubG9hZGluZy5nZXQoaWQpO1xuICAgIGNvbnN0IGxvYWRlZCA9IHRoaXMuaW5zdGFuY2VzLmdldChpZCk7XG4gICAgdGhpcy5pbnN0YW5jZXMuZGVsZXRlKGlkKTtcbiAgICB0aGlzLmxvYWRpbmcuZGVsZXRlKGlkKTtcblxuICAgIGlmIChsb2FkZWQpIGF3YWl0IGxvYWRlZC5kaXNwb3NlKCk7XG4gICAgaWYgKCFwZW5kaW5nKSByZXR1cm47XG5cbiAgICAvLyBBIHBlbmRpbmcgbG9hZCBhc3NpZ25zIGluc3RhbmNlc1tpZF0gYmVmb3JlIGl0cyBwcm9taXNlIHJlc29sdmVzLCBzbyBieVxuICAgIC8vIHRoZSB0aW1lIHRoaXMgYXdhaXQgcmV0dXJucyB0aGUgZW50cnkgaXMgYmFjay4gQ2xlYXIgaXQgb25seSBpZiBpdCBzdGlsbFxuICAgIC8vIHBvaW50cyBhdCB3aGF0ICp0aGlzKiBsb2FkIHByb2R1Y2VkIOKAlCBhIG5ld2VyIGxvYWQgc3RhcnRlZCBtZWFud2hpbGUgb3duc1xuICAgIC8vIGl0cyBvd24gZW50cnkgYW5kIG11c3Qgbm90IGJlIGV2aWN0ZWQuXG4gICAgY29uc3Qgc2VnID0gYXdhaXQgcGVuZGluZy5jYXRjaCgoKSA9PiBudWxsKTtcbiAgICBpZiAoIXNlZyB8fCBzZWcgPT09IGxvYWRlZCkgcmV0dXJuO1xuICAgIGlmICh0aGlzLmluc3RhbmNlcy5nZXQoaWQpID09PSBzZWcpIHRoaXMuaW5zdGFuY2VzLmRlbGV0ZShpZCk7XG4gICAgYXdhaXQgc2VnLmRpc3Bvc2UoKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVxdWlyZU1vZGVsKG1vZGVsSWQ6IHN0cmluZyk6IFJldGluYWxNb2RlbERlZiB7XG4gICAgY29uc3QgZGVmID0gZ2V0UmV0aW5hbE1vZGVsKG1vZGVsSWQpO1xuICAgIGlmICghZGVmKSB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gcmV0aW5hbCBtb2RlbCBpZCBcIiR7bW9kZWxJZH1cIi5gKTtcbiAgICBpZiAoIWRlZi5tb2RlbFVybC50cmltKCkpIHtcbiAgICAgIC8vIFByZWZlciB0aGUgcmVnaXN0cnkncyBzcGVjaWZpYyBleHBsYW5hdGlvbiBvdmVyIFwibm90IGNvbmZpZ3VyZWRcIiDigJQgdGhlXG4gICAgICAvLyBSZXNVTmV0LWEgZW50cmllcyBhcmUgZGlzYWJsZWQgZm9yIGEgZG9jdW1lbnRlZCBhY2N1cmFjeSByZWFzb24sIGFuZCBhXG4gICAgICAvLyB1c2VyIHdobyBwaWNrZWQgb25lIGRlc2VydmVzIHRvIGJlIHRvbGQgd2hpY2guXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoZGVmLnVuYXZhaWxhYmxlUmVhc29uID8/IGBSZXRpbmFsIG1vZGVsIFwiJHttb2RlbElkfVwiIGhhcyBubyBtb2RlbFVybCBjb25maWd1cmVkLmApO1xuICAgIH1cbiAgICByZXR1cm4gZGVmO1xuICB9XG59XG4iXX0=
|
|
@@ -70,13 +70,24 @@ export class YoloDetectToolService {
|
|
|
70
70
|
// Against the pixels actually inferred on, which may be the re-crop.
|
|
71
71
|
const ratioX = rect && source.width > 0 ? rect.width / source.width : 1;
|
|
72
72
|
const ratioY = rect && source.height > 0 ? rect.height / source.height : 1;
|
|
73
|
+
// View pixels -> full-resolution image pixels, for any ring.
|
|
74
|
+
const mapRing = (ring) => ring.map(([x, y]) => [Math.round(offsetX + x * ratioX), Math.round(offsetY + y * ratioY)]);
|
|
73
75
|
const added = [];
|
|
74
76
|
for (const det of result.detections) {
|
|
75
77
|
if (det.polygons.length > 0) {
|
|
76
78
|
for (const poly of det.polygons) {
|
|
77
79
|
if (poly.exterior.length < 3)
|
|
78
80
|
continue;
|
|
79
|
-
|
|
81
|
+
const exterior = mapRing(poly.exterior);
|
|
82
|
+
added.push(this.makeRegion(exterior.map(([x]) => x), exterior.map(([, y]) => y), det.className,
|
|
83
|
+
// A mask with a void through it is a donut, and committing only
|
|
84
|
+
// the exterior fills it in silently — which reads as a detection
|
|
85
|
+
// that over-covers rather than as lost geometry. Each polygon
|
|
86
|
+
// already owns its own holes, so there is no ambiguity about
|
|
87
|
+
// which exterior a ring belongs to even when one mask splits
|
|
88
|
+
// into several polygons. Rings too small to bound anything after
|
|
89
|
+
// simplification are dropped rather than emitted.
|
|
90
|
+
poly.holes.filter((h) => h.length >= 3).map(mapRing)));
|
|
80
91
|
}
|
|
81
92
|
continue;
|
|
82
93
|
}
|
|
@@ -162,13 +173,18 @@ export class YoloDetectToolService {
|
|
|
162
173
|
return null;
|
|
163
174
|
}
|
|
164
175
|
}
|
|
165
|
-
makeRegion(xs, ys, className) {
|
|
176
|
+
makeRegion(xs, ys, className, holes = []) {
|
|
166
177
|
const poly = new Polygon();
|
|
167
178
|
poly.npoints = xs.length;
|
|
168
179
|
poly.xpoints = xs;
|
|
169
180
|
poly.ypoints = ys;
|
|
170
181
|
poly.coordinates = xs.map((x, i) => [x, ys[i]]);
|
|
171
182
|
poly.closed = true;
|
|
183
|
+
// Same closed-ring convention as the exterior: no repeated closing point.
|
|
184
|
+
// Left unset when empty so a solid region does not carry an empty array
|
|
185
|
+
// through export and round-tripping.
|
|
186
|
+
if (holes.length)
|
|
187
|
+
poly.holes = holes;
|
|
172
188
|
const region = new Region();
|
|
173
189
|
region.bounds = poly;
|
|
174
190
|
region.source = YOLO_REGION_SOURCE;
|
|
@@ -189,4 +205,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
|
|
|
189
205
|
type: Inject,
|
|
190
206
|
args: [TILE_ACCESS_PORT]
|
|
191
207
|
}] }] });
|
|
192
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieW9sby1kZXRlY3QtdG9vbC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi90b29sYmFyL3NlZ21lbnRhdGlvbi95b2xvLWRldGVjdC10b29sLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzdELE9BQU8sRUFBRSxlQUFlLEVBQUUsY0FBYyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXZELE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFhLE1BQU0scUJBQXFCLENBQUM7QUFDakUsT0FBTyxFQUFFLGdCQUFnQixFQUF1QixNQUFNLHdDQUF3QyxDQUFDOztBQUkvRjs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILDhFQUE4RTtBQUM5RSxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLENBQUM7QUFHekMsTUFBTSxPQUFPLHFCQUFxQjtJQUtoQztJQUNFOzt3REFFb0Q7SUFDTixhQUFvQyxJQUFJO1FBQXhDLGVBQVUsR0FBVixVQUFVLENBQThCO1FBUi9FLFlBQU8sR0FBRyxJQUFJLGVBQWUsQ0FBUyxFQUFFLENBQUMsQ0FBQztRQUMxQyxVQUFLLEdBQUcsSUFBSSxlQUFlLENBQVUsS0FBSyxDQUFDLENBQUM7UUFDNUMsY0FBUyxHQUFHLElBQUksZUFBZSxDQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFPbEQsQ0FBQztJQUVKOzs7O09BSUc7SUFDSCxLQUFLLENBQUMsWUFBWSxDQUNoQixHQUFnQixFQUNoQixTQUE2QixFQUM3QixPQUErQixFQUFFO1FBRWpDLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxxQkFBcUIsRUFBRSxFQUFFLENBQUM7UUFDN0MsSUFBSSxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUMsS0FBSyxLQUFLLENBQUMsSUFBSSxNQUFNLENBQUMsTUFB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LEVBQUUsTUFBTSxFQUFFOzswQkFVN0IsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxnQkFBZ0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUsIE9wdGlvbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIGZpcnN0VmFsdWVGcm9tIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IFJlZ2lvbiwgUG9seWdvbiwgUmVjdGFuZ2xlIH0gZnJvbSAnLi4vLi4vbW9kZWxzL3JlZ2lvbic7XG5pbXBvcnQgeyBUSUxFX0FDQ0VTU19QT1JULCB0eXBlIFRpbGVBY2Nlc3NQb3J0IH0gZnJvbSAnLi4vLi4vY29udHJhY3RzL3BvcnRzL3RpbGUtYWNjZXNzLnBvcnQnO1xuaW1wb3J0IHR5cGUgeyBJVmlzdWFsaXplciB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy92aXN1YWxpemVyLmNvbnRyYWN0JztcbmltcG9ydCB0eXBlIHsgSUluc3RhbmNlU2VnbWVudGVyLCBJbnN0YW5jZVNlZ21lbnRPcHRpb25zIH0gZnJvbSAnLi4vLi4vY29udHJhY3RzL2luc3RhbmNlLXNlZ21lbnRlci5jb250cmFjdCc7XG5cbi8qKlxuICogWU9MTyBvYmplY3QgZGV0ZWN0aW9uIG92ZXIgdGhlIGN1cnJlbnQgdmlldy5cbiAqXG4gKiBUaGUgY29tcGxlbWVudCB0byB7QGxpbmsgQ2VsbFNlZ21lbnRUb29sU2VydmljZX06IGNlbGxwb3NlIGF1dG8tc2VnbWVudHMgY2VsbHNcbiAqIGluc2lkZSBhIGJveCB5b3UgZHJhdywgd2hlcmVhcyBhIGRldGVjdG9yIGlzIG1lYW50IHRvIGZpbmQgb2JqZWN0cyBhY3Jvc3MgYVxuICogZmllbGQuIFNvIHRoaXMgdGFrZXMgbm8gcHJvbXB0IOKAlCBpdCBydW5zIG9uIHdoYXRldmVyIGlzIG9uIHNjcmVlbiBhbmQgdHVybnNcbiAqIGV2ZXJ5IGRldGVjdGlvbiBpbnRvIGEgcmVnaW9uLlxuICpcbiAqIERldGVjdGlvbnMgY29tZSBiYWNrIGluIHRoZSBkaXNwbGF5ZWQgaW1hZ2UncyBwaXhlbHM7IHRoZXkgYXJlIG1hcHBlZCBvbnRvXG4gKiB0aGUgZnVsbC1yZXNvbHV0aW9uIGltYWdlIHRocm91Z2ggdGhlIHZpZXdlcidzIG93biBzb3VyY2UgcmVjdCwgc28gdGhlIHJlZ2lvbnNcbiAqIGxhbmQgd2hlcmUgdGhlIG9iamVjdHMgYWN0dWFsbHkgYXJlIHJhdGhlciB0aGFuIGF0IHZpZXctbG9jYWwgY29vcmRpbmF0ZXMuXG4gKlxuICogRXhwb3NlcyB0aGUgc2FtZSBgc3RhdHVzJGAgLyBgYnVzeSRgIC8gYHByb2dyZXNzJGAgc3VyZmFjZSBhcyB0aGUgY2VsbHBvc2VcbiAqIHRvb2wgc28gdGhlIGhvc3QncyBzaGFyZWQgc2VnbWVudGF0aW9uIHRvYXN0IGRyaXZlcyBpdCB1bmNoYW5nZWQuXG4gKi9cbi8qKiBNYXJrcyByZWdpb25zIHRoaXMgdG9vbCBwcm9kdWNlZCwgc28gYSByZS1ydW4gY2FuIHJlcGxhY2Ugb25seSBpdHMgb3duLiAqL1xuZXhwb3J0IGNvbnN0IFlPTE9fUkVHSU9OX1NPVVJDRSA9ICd5b2xvJztcblxuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcbmV4cG9ydCBjbGFzcyBZb2xvRGV0ZWN0VG9vbFNlcnZpY2Uge1xuICByZWFkb25seSBzdGF0dXMkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmc+KCcnKTtcbiAgcmVhZG9ubHkgYnVzeSQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcbiAgcmVhZG9ubHkgcHJvZ3Jlc3MkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxudW1iZXI+KC0xKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICAvKiogU2VydmVyLXNpZGUgY3JvcCwgc28gZGV0ZWN0aW9uIGNhbiBydW4gYXQgdGhlIG1vZGVsJ3Mgc2NhbGUgcmF0aGVyIHRoYW5cbiAgICAgKiAgdGhlIHZpZXdlcidzLiBPcHRpb25hbDogd2l0aG91dCBpdCB0aGUgdG9vbCBmYWxscyBiYWNrIHRvIHRoZSBkaXNwbGF5ZWRcbiAgICAgKiAgcGl4ZWxzLCB3aGljaCBpcyBjb3JyZWN0IGJ1dCBzY2FsZS1kZXBlbmRlbnQuICovXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChUSUxFX0FDQ0VTU19QT1JUKSBwcml2YXRlIHRpbGVBY2Nlc3M6IFRpbGVBY2Nlc3NQb3J0IHwgbnVsbCA9IG51bGwsXG4gICkge31cblxuICAvKipcbiAgICogRGV0ZWN0IGluIHRoZSBjdXJyZW50IHZpZXcgYW5kIGFwcGVuZCB0aGUgcmVzdWx0cyBhcyByZWdpb25zLlxuICAgKlxuICAgKiBAcmV0dXJucyB0aGUgbnVtYmVyIG9mIHJlZ2lvbnMgYWRkZWQuXG4gICAqL1xuICBhc3luYyBkZXRlY3RJblZpZXcoXG4gICAgdml6OiBJVmlzdWFsaXplcixcbiAgICBzZWdtZW50ZXI6IElJbnN0YW5jZVNlZ21lbnRlcixcbiAgICBvcHRzOiBJbnN0YW5jZVNlZ21lbnRPcHRpb25zID0ge30sXG4gICk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgY29uc3QgcGl4ZWxzID0gdml6LmdldERpc3BsYXllZFBpeGVsRGF0YT8uKCk7XG4gICAgaWYgKCFwaXhlbHMgfHwgcGl4ZWxzLndpZHRoID09PSAwIHx8IHBpeGVscy5oZWlnaHQgPT09IDApIHtcbiAgICAgIHRoaXMuc3RhdHVzJC5uZXh0KCdObyBpbWFnZSBvbiBzY3JlZW4gdG8gZGV0ZWN0IGluLicpO1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgdGhpcy5idXN5JC5uZXh0KHRydWUpO1xuICAgIHRoaXMucHJvZ3Jlc3MkLm5leHQoLTEpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZWN0ID0gdml6LmdldERpc3BsYXllZFNvdXJjZVJlY3Q/LigpID8/IG51bGw7XG4gICAgICBjb25zdCB0YXJnZXQgPSBOdW1iZXIob3B0cy5kb3duc2FtcGxpbmdGYWN0b3IgPz8gMCkgfHwgMDtcbiAgICAgIGNvbnN0IHZpZXdGYWN0b3IgPSByZWN0ICYmIHBpeGVscy53aWR0aCA+IDAgPyByZWN0LndpZHRoIC8gcGl4ZWxzLndpZHRoIDogMTtcblxuICAgICAgLy8gUmUtY3JvcCBhdCB0aGUgbW9kZWwncyBzY2FsZSB3aGVuIHRoZSB2aWV3IGlzIGNvYXJzZXIgdGhhbiBpdCB3YW50cy5cbiAgICAgIC8vIFRoZSBpbWFnZSBpcyB0aWxlLWJhY2tlZCwgc28gdGhhdCBkZXRhaWwgZXhpc3RzIHNlcnZlci1zaWRlIGV2ZW4gdGhvdWdoXG4gICAgICAvLyB0aGUgZGlzcGxheWVkIHBpeGVscyBoYXZlIGRpc2NhcmRlZCBpdC5cbiAgICAgIGxldCBzb3VyY2UgPSB7IGRhdGE6IHBpeGVscy5kYXRhLCB3aWR0aDogcGl4ZWxzLndpZHRoLCBoZWlnaHQ6IHBpeGVscy5oZWlnaHQgfTtcbiAgICAgIGlmIChyZWN0ICYmIHRhcmdldCA+IDAgJiYgdGFyZ2V0IDwgdmlld0ZhY3RvciAqIDAuOTgpIHtcbiAgICAgICAgdGhpcy5zdGF0dXMkLm5leHQoJ0ZldGNoaW5nIGltYWdlIGF0IG1vZGVsIHJlc29sdXRpb27igKYnKTtcbiAgICAgICAgY29uc3QgaGkgPSBhd2FpdCB0aGlzLmZldGNoQ3JvcEF0U2NhbGUocmVjdCwgdGFyZ2V0KTtcbiAgICAgICAgaWYgKGhpKSBzb3VyY2UgPSBoaTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc2VnbWVudGVyLnNlZ21lbnRJbnN0YW5jZXMoc291cmNlLCBvcHRzLCB7XG4gICAgICAgIG9uUHJvZ3Jlc3M6IChmKSA9PiB0aGlzLnByb2dyZXNzJC5uZXh0KGYpLFxuICAgICAgICBvblN0YXR1czogKHMpID0+IHRoaXMuc3RhdHVzJC5uZXh0KHMpLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIFZpZXcgcGl4ZWxzIC0+IGZ1bGwtcmVzb2x1dGlvbiBpbWFnZSBwaXhlbHMuIFdpdGhvdXQgdGhpcyBldmVyeSByZWdpb25cbiAgICAgIC8vIHdvdWxkIHNpdCBhdCB2aWV3LWxvY2FsIGNvb3JkaW5hdGVzLCBpLmUuIHRoZSB3cm9uZyBwbGFjZSBvbiB0aGUgc2xpZGVcbiAgICAgIC8vIGZvciBhbnkgem9vbWVkIG9yIHBhbm5lZCB2aWV3LlxuICAgICAgY29uc3Qgb2Zmc2V0WCA9IHJlY3QgPyByZWN0LnggOiAwO1xuICAgICAgY29uc3Qgb2Zmc2V0WSA9IHJlY3QgPyByZWN0LnkgOiAwO1xuICAgICAgLy8gQWdhaW5zdCB0aGUgcGl4ZWxzIGFjdHVhbGx5IGluZmVycmVkIG9uLCB3aGljaCBtYXkgYmUgdGhlIHJlLWNyb3AuXG4gICAgICBjb25zdCByYXRpb1ggPSByZWN0ICYmIHNvdXJjZS53aWR0aCA+IDAgPyByZWN0LndpZHRoIC8gc291cmNlLndpZHRoIDogMTtcbiAgICAgIGNvbnN0IHJhdGlvWSA9IHJlY3QgJiYgc291cmNlLmhlaWdodCA+IDAgPyByZWN0LmhlaWdodCAvIHNvdXJjZS5oZWlnaHQgOiAxO1xuXG4gICAgICBjb25zdCBhZGRlZDogUmVnaW9uW10gPSBbXTtcbiAgICAgIGZvciAoY29uc3QgZGV0IG9mIHJlc3VsdC5kZXRlY3Rpb25zKSB7XG4gICAgICAgIGlmIChkZXQucG9seWdvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGZvciAoY29uc3QgcG9seSBvZiBkZXQucG9seWdvbnMpIHtcbiAgICAgICAgICAgIGlmIChwb2x5LmV4dGVyaW9yLmxlbmd0aCA8IDMpIGNvbnRpbnVlO1xuICAgICAgICAgICAgYWRkZWQucHVzaChcbiAgICAgICAgICAgICAgdGhpcy5tYWtlUmVnaW9uKFxuICAgICAgICAgICAgICAgIHBvbHkuZXh0ZXJpb3IubWFwKChbeF0pID0+IE1hdGgucm91bmQob2Zmc2V0WCArIHggKiByYXRpb1gpKSxcbiAgICAgICAgICAgICAgICBwb2x5LmV4dGVyaW9yLm1hcCgoWywgeV0pID0+IE1hdGgucm91bmQob2Zmc2V0WSArIHkgKiByYXRpb1kpKSxcbiAgICAgICAgICAgICAgICBkZXQuY2xhc3NOYW1lLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRGV0ZWN0aW9uIG1vZGUgeWllbGRzIG5vIG91dGxpbmU7IHRoZSBib3ggaXMgc3RpbGwgdGhlIHJlc3VsdCwgYW5kXG4gICAgICAgIC8vIG1hdGNoZXMgd2hhdCB0aGUgc2VydmVyIHdyaXRlcyBhcyBhIFwiZGV0ZWN0aW9uXCIgZmVhdHVyZS5cbiAgICAgICAgY29uc3QgW3gxLCB5MSwgeDIsIHkyXSA9IGRldC5ib3g7XG4gICAgICAgIGlmICh4MiAtIHgxIDw9IDAgfHwgeTIgLSB5MSA8PSAwKSBjb250aW51ZTtcbiAgICAgICAgYWRkZWQucHVzaChcbiAgICAgICAgICB0aGlzLm1ha2VSZWdpb24oXG4gICAgICAgICAgICBbeDEsIHgyLCB4MiwgeDFdLm1hcCgoeCkgPT4gTWF0aC5yb3VuZChvZmZzZXRYICsgeCAqIHJhdGlvWCkpLFxuICAgICAgICAgICAgW3kxLCB5MSwgeTIsIHkyXS5tYXAoKHkpID0+IE1hdGgucm91bmQob2Zmc2V0WSArIHkgKiByYXRpb1kpKSxcbiAgICAgICAgICAgIGRldC5jbGFzc05hbWUsXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGFkZGVkLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLnN0YXR1cyQubmV4dCgnTm8gb2JqZWN0cyBkZXRlY3RlZC4nKTtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG5cbiAgICAgIC8vIFJlcGxhY2UgdGhpcyB0b29sJ3Mgb3duIHByZXZpb3VzIG91dHB1dCwga2VlcCBldmVyeXRoaW5nIGVsc2UuIEFwcGVuZGluZ1xuICAgICAgLy8gdW5jb25kaXRpb25hbGx5IG1hZGUgZXZlcnkgdHVuaW5nIHJ1biBzdGFjayBvbnRvIHRoZSBsYXN0LCBzbyB0aGVcbiAgICAgIC8vIHZpZXdlciBhY2N1bXVsYXRlZCBvdmVybGFwcGluZyByZXN1bHRzIGZyb20gcGFyYW1ldGVycyBubyBsb25nZXIgaW5cbiAgICAgIC8vIGVmZmVjdC4gSGFuZC1kcmF3biByZWdpb25zIGFuZCBvdGhlciB0b29scycgb3V0cHV0IGNhcnJ5IG5vIGBzb3VyY2VgXG4gICAgICAvLyBhbmQgYXJlIHVudG91Y2hlZC5cbiAgICAgIGNvbnN0IGtlcHQgPSAodml6LmdldFJlZ2lvbnMoKSA/PyBbXSkuZmlsdGVyKChyKSA9PiByLnNvdXJjZSAhPT0gWU9MT19SRUdJT05fU09VUkNFKTtcbiAgICAgIHZpei5zZXRSZWdpb25zKFsuLi5rZXB0LCAuLi5hZGRlZF0pO1xuICAgICAgdGhpcy5zdGF0dXMkLm5leHQoYEFkZGVkICR7YWRkZWQubGVuZ3RofSByZWdpb24ocykuYCk7XG4gICAgICByZXR1cm4gYWRkZWQubGVuZ3RoO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5zdGF0dXMkLm5leHQoZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6ICdZT0xPIGRldGVjdGlvbiBmYWlsZWQuJyk7XG4gICAgICByZXR1cm4gMDtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5idXN5JC5uZXh0KGZhbHNlKTtcbiAgICAgIHRoaXMucHJvZ3Jlc3MkLm5leHQoLTEpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZS1jcm9wIGByZWN0YCBhdCBgMS90YXJnZXRgIG9mIGZ1bGwgcmVzb2x1dGlvbi4gUmV0dXJucyBudWxsIG9uIGFueVxuICAgKiBmYWlsdXJlLCBzbyB0aGUgY2FsbGVyIGZhbGxzIGJhY2sgdG8gdGhlIGRpc3BsYXllZCBwaXhlbHMg4oCUIGEgY29hcnNlciBjcm9wXG4gICAqIGJlYXRzIGEgZmFpbGVkIHJ1bi5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZmV0Y2hDcm9wQXRTY2FsZShcbiAgICByZWN0OiB7IHg6IG51bWJlcjsgeTogbnVtYmVyOyB3aWR0aDogbnVtYmVyOyBoZWlnaHQ6IG51bWJlciB9LFxuICAgIHRhcmdldDogbnVtYmVyLFxuICApOiBQcm9taXNlPHsgZGF0YTogVWludDhDbGFtcGVkQXJyYXk7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH0gfCBudWxsPiB7XG4gICAgaWYgKCF0aGlzLnRpbGVBY2Nlc3MpIHJldHVybiBudWxsO1xuICAgIGxldCB3ID0gTWF0aC5yb3VuZChyZWN0LndpZHRoIC8gdGFyZ2V0KTtcbiAgICBsZXQgaCA9IE1hdGgucm91bmQocmVjdC5oZWlnaHQgLyB0YXJnZXQpO1xuXG4gICAgLy8gQSBmYWN0b3Igb2YgMSBvdmVyIGEgd2hvbGUtc2xpZGUgUk9JIHdvdWxkIGFzayBmb3IgaHVuZHJlZHMgb2YgbWVnYXBpeGVscy5cbiAgICBjb25zdCBNQVhfUElYRUxTID0gMTZfNzc3XzIxNjsgLy8gNDA5NsKyXG4gICAgY29uc3QgcGl4ZWxzID0gdyAqIGg7XG4gICAgaWYgKHBpeGVscyA+IE1BWF9QSVhFTFMpIHtcbiAgICAgIGNvbnN0IGsgPSBNYXRoLnNxcnQoTUFYX1BJWEVMUyAvIHBpeGVscyk7XG4gICAgICB3ID0gTWF0aC5yb3VuZCh3ICogayk7XG4gICAgICBoID0gTWF0aC5yb3VuZChoICogayk7XG4gICAgfVxuICAgIGlmICh3IDwgNjQgfHwgaCA8IDY0KSByZXR1cm4gbnVsbDtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByb2kgPSB7XG4gICAgICAgIHg6IE1hdGgucm91bmQocmVjdC54KSxcbiAgICAgICAgeTogTWF0aC5yb3VuZChyZWN0LnkpLFxuICAgICAgICB3aWR0aDogTWF0aC5yb3VuZChyZWN0LndpZHRoKSxcbiAgICAgICAgaGVpZ2h0OiBNYXRoLnJvdW5kKHJlY3QuaGVpZ2h0KSxcbiAgICAgIH0gYXMgUmVjdGFuZ2xlO1xuICAgICAgY29uc3Qgc2NyZWVuID0geyB4OiAwLCB5OiAwLCB3aWR0aDogdywgaGVpZ2h0OiBoIH0gYXMgUmVjdGFuZ2xlO1xuICAgICAgY29uc3QgYnl0ZXMgPSBhd2FpdCBmaXJzdFZhbHVlRnJvbSh0aGlzLnRpbGVBY2Nlc3Muem9vbU9uUmVnaW9uKHJvaSwgc2NyZWVuLCAwKSk7XG4gICAgICBpZiAoIWJ5dGVzIHx8IGJ5dGVzLmJ5dGVMZW5ndGggPT09IDApIHJldHVybiBudWxsO1xuXG4gICAgICBjb25zdCBiaXRtYXAgPSBhd2FpdCBjcmVhdGVJbWFnZUJpdG1hcChuZXcgQmxvYihbYnl0ZXNdKSk7XG4gICAgICBjb25zdCBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICAgIGNhbnZhcy53aWR0aCA9IGJpdG1hcC53aWR0aDtcbiAgICAgIGNhbnZhcy5oZWlnaHQgPSBiaXRtYXAuaGVpZ2h0O1xuICAgICAgY29uc3QgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgICBpZiAoIWN0eCkgcmV0dXJuIG51bGw7XG4gICAgICBjdHguZHJhd0ltYWdlKGJpdG1hcCwgMCwgMCk7XG4gICAgICAvLyBSZWFkIHRoZSBkaW1lbnNpb25zIEJFRk9SRSBjbG9zZSgpOiBjbG9zaW5nIGFuIEltYWdlQml0bWFwIHplcm9lcyBpdHNcbiAgICAgIC8vIHdpZHRoL2hlaWdodCwgc28gcmV0dXJuaW5nIHRoZW0gYWZ0ZXJ3YXJkcyB5aWVsZHMgYSAweDAgaW1hZ2Ugd2l0aCBhXG4gICAgICAvLyBmdWxsIHBpeGVsIGJ1ZmZlciDigJQgaW5mZXJlbmNlIHRoZW4gcnVucyBvbiBub3RoaW5nIGFuZCBmaW5kcyBub3RoaW5nLlxuICAgICAgY29uc3Qgd2lkdGggPSBiaXRtYXAud2lkdGg7XG4gICAgICBjb25zdCBoZWlnaHQgPSBiaXRtYXAuaGVpZ2h0O1xuICAgICAgY29uc3Qgb3V0ID0gY3R4LmdldEltYWdlRGF0YSgwLCAwLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICAgIGJpdG1hcC5jbG9zZT8uKCk7XG4gICAgICByZXR1cm4geyBkYXRhOiBvdXQuZGF0YSwgd2lkdGgsIGhlaWdodCB9O1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBtYWtlUmVnaW9uKHhzOiBudW1iZXJbXSwgeXM6IG51bWJlcltdLCBjbGFzc05hbWU6IHN0cmluZyk6IFJlZ2lvbiB7XG4gICAgY29uc3QgcG9seSA9IG5ldyBQb2x5Z29uKCk7XG4gICAgcG9seS5ucG9pbnRzID0geHMubGVuZ3RoO1xuICAgIHBvbHkueHBvaW50cyA9IHhzO1xuICAgIHBvbHkueXBvaW50cyA9IHlzO1xuICAgIHBvbHkuY29vcmRpbmF0ZXMgPSB4cy5tYXAoKHgsIGkpID0+IFt4LCB5c1tpXV0pO1xuICAgIHBvbHkuY2xvc2VkID0gdHJ1ZTtcblxuICAgIGNvbnN0IHJlZ2lvbiA9IG5ldyBSZWdpb24oKTtcbiAgICByZWdpb24uYm91bmRzID0gcG9seTtcbiAgICByZWdpb24uc291cmNlID0gWU9MT19SRUdJT05fU09VUkNFO1xuICAgIC8vIFRoZSBjbGFzcyBuYW1lIGRyaXZlcyBwcmVzZXQgY29sb3VyIHJlc29sdXRpb247IGxlYXZpbmcgYGNvbG9yYCB1bnNldCBsZXRzXG4gICAgLy8gYW4gZXhpc3RpbmcgcHJlc2V0IGZvciB0aGlzIGNsYXNzIHdpbi5cbiAgICByZWdpb24ubGFiZWwgPSBjbGFzc05hbWU7XG4gICAgcmV0dXJuIHJlZ2lvbjtcbiAgfVxufVxuIl19
|
|
208
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieW9sby1kZXRlY3QtdG9vbC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi90b29sYmFyL3NlZ21lbnRhdGlvbi95b2xvLWRldGVjdC10b29sLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzdELE9BQU8sRUFBRSxlQUFlLEVBQUUsY0FBYyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXZELE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFhLE1BQU0scUJBQXFCLENBQUM7QUFDakUsT0FBTyxFQUFFLGdCQUFnQixFQUF1QixNQUFNLHdDQUF3QyxDQUFDOztBQUkvRjs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILDhFQUE4RTtBQUM5RSxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLENBQUM7QUFHekMsTUFBTSxPQUFPLHFCQUFxQjtJQUtoQztJQUNFOzt3REFFb0Q7SUFDTixhQUFvQyxJQUFJO1FBQXhDLGVBQVUsR0FBVixVQUFVLENBQThCO1FBUi9FLFlBQU8sR0FBRyxJQUFJLGVBQWUsQ0FBUyxFQUFFLENBQUMsQ0FBQztRQUMxQyxVQUFLLEdBQUcsSUFBSSxlQUFlLENBQVUsS0FBSyxDQUFDLENBQUM7UUFDNUMsY0FBUyxHQUFHLElBQUksZUFBZSxDQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFPbEQsQ0FBQztJQUVKOzs7O09BSUc7SUFDSCxLQUFLLENBQUMsWUFBWSxDQUNoQixHQUFnQixFQUNoQixTQUE2QixFQUM3QixPQUErQixFQUFFO1FBRWpDLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxxQkFBcUIsRUFBRSxFQUFFLENBQUM7UUFDN0MsSUFBSSxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUMsS0FBSyxLQUFLLENBQUMsSUFBSSxNQUFNLENBQUMsTUFB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LENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1FBQ25CLDBFQUEwRTtRQUMxRSx3RUFBd0U7UUFDeEUscUNBQXFDO1FBQ3JDLElBQUksS0FBSyxDQUFDLE1BQU07WUFBRSxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUVyQyxNQUFNLE1BQU0sR0FBRyxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQzVCLE1BQU0sQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1FBQ3JCLE1BQU0sQ0FBQyxNQUFNLEdBQUcsa0JBQWtCLENBQUM7UUFDbkMsNkVBQTZFO1FBQzdFLHlDQUF5QztRQUN6QyxNQUFNLENBQUMsS0FBSyxHQUFHLFNBQVMsQ0FBQztRQUN6QixPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDOzhHQXBNVSxxQkFBcUIsa0JBU1YsZ0JBQWdCO2tIQVQzQixxQkFBcUIsY0FEUixNQUFNOzsyRkFDbkIscUJBQXFCO2tCQURqQyxVQUFVO21CQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRTs7MEJBVTdCLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsZ0JBQWdCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlLCBPcHRpb25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBmaXJzdFZhbHVlRnJvbSB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBSZWdpb24sIFBvbHlnb24sIFJlY3RhbmdsZSB9IGZyb20gJy4uLy4uL21vZGVscy9yZWdpb24nO1xuaW1wb3J0IHsgVElMRV9BQ0NFU1NfUE9SVCwgdHlwZSBUaWxlQWNjZXNzUG9ydCB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy9wb3J0cy90aWxlLWFjY2Vzcy5wb3J0JztcbmltcG9ydCB0eXBlIHsgSVZpc3VhbGl6ZXIgfSBmcm9tICcuLi8uLi9jb250cmFjdHMvdmlzdWFsaXplci5jb250cmFjdCc7XG5pbXBvcnQgdHlwZSB7IElJbnN0YW5jZVNlZ21lbnRlciwgSW5zdGFuY2VTZWdtZW50T3B0aW9ucyB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy9pbnN0YW5jZS1zZWdtZW50ZXIuY29udHJhY3QnO1xuXG4vKipcbiAqIFlPTE8gb2JqZWN0IGRldGVjdGlvbiBvdmVyIHRoZSBjdXJyZW50IHZpZXcuXG4gKlxuICogVGhlIGNvbXBsZW1lbnQgdG8ge0BsaW5rIENlbGxTZWdtZW50VG9vbFNlcnZpY2V9OiBjZWxscG9zZSBhdXRvLXNlZ21lbnRzIGNlbGxzXG4gKiBpbnNpZGUgYSBib3ggeW91IGRyYXcsIHdoZXJlYXMgYSBkZXRlY3RvciBpcyBtZWFudCB0byBmaW5kIG9iamVjdHMgYWNyb3NzIGFcbiAqIGZpZWxkLiBTbyB0aGlzIHRha2VzIG5vIHByb21wdCDigJQgaXQgcnVucyBvbiB3aGF0ZXZlciBpcyBvbiBzY3JlZW4gYW5kIHR1cm5zXG4gKiBldmVyeSBkZXRlY3Rpb24gaW50byBhIHJlZ2lvbi5cbiAqXG4gKiBEZXRlY3Rpb25zIGNvbWUgYmFjayBpbiB0aGUgZGlzcGxheWVkIGltYWdlJ3MgcGl4ZWxzOyB0aGV5IGFyZSBtYXBwZWQgb250b1xuICogdGhlIGZ1bGwtcmVzb2x1dGlvbiBpbWFnZSB0aHJvdWdoIHRoZSB2aWV3ZXIncyBvd24gc291cmNlIHJlY3QsIHNvIHRoZSByZWdpb25zXG4gKiBsYW5kIHdoZXJlIHRoZSBvYmplY3RzIGFjdHVhbGx5IGFyZSByYXRoZXIgdGhhbiBhdCB2aWV3LWxvY2FsIGNvb3JkaW5hdGVzLlxuICpcbiAqIEV4cG9zZXMgdGhlIHNhbWUgYHN0YXR1cyRgIC8gYGJ1c3kkYCAvIGBwcm9ncmVzcyRgIHN1cmZhY2UgYXMgdGhlIGNlbGxwb3NlXG4gKiB0b29sIHNvIHRoZSBob3N0J3Mgc2hhcmVkIHNlZ21lbnRhdGlvbiB0b2FzdCBkcml2ZXMgaXQgdW5jaGFuZ2VkLlxuICovXG4vKiogTWFya3MgcmVnaW9ucyB0aGlzIHRvb2wgcHJvZHVjZWQsIHNvIGEgcmUtcnVuIGNhbiByZXBsYWNlIG9ubHkgaXRzIG93bi4gKi9cbmV4cG9ydCBjb25zdCBZT0xPX1JFR0lPTl9TT1VSQ0UgPSAneW9sbyc7XG5cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgWW9sb0RldGVjdFRvb2xTZXJ2aWNlIHtcbiAgcmVhZG9ubHkgc3RhdHVzJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8c3RyaW5nPignJyk7XG4gIHJlYWRvbmx5IGJ1c3kkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XG4gIHJlYWRvbmx5IHByb2dyZXNzJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8bnVtYmVyPigtMSk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgLyoqIFNlcnZlci1zaWRlIGNyb3AsIHNvIGRldGVjdGlvbiBjYW4gcnVuIGF0IHRoZSBtb2RlbCdzIHNjYWxlIHJhdGhlciB0aGFuXG4gICAgICogIHRoZSB2aWV3ZXIncy4gT3B0aW9uYWw6IHdpdGhvdXQgaXQgdGhlIHRvb2wgZmFsbHMgYmFjayB0byB0aGUgZGlzcGxheWVkXG4gICAgICogIHBpeGVscywgd2hpY2ggaXMgY29ycmVjdCBidXQgc2NhbGUtZGVwZW5kZW50LiAqL1xuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoVElMRV9BQ0NFU1NfUE9SVCkgcHJpdmF0ZSB0aWxlQWNjZXNzOiBUaWxlQWNjZXNzUG9ydCB8IG51bGwgPSBudWxsLFxuICApIHt9XG5cbiAgLyoqXG4gICAqIERldGVjdCBpbiB0aGUgY3VycmVudCB2aWV3IGFuZCBhcHBlbmQgdGhlIHJlc3VsdHMgYXMgcmVnaW9ucy5cbiAgICpcbiAgICogQHJldHVybnMgdGhlIG51bWJlciBvZiByZWdpb25zIGFkZGVkLlxuICAgKi9cbiAgYXN5bmMgZGV0ZWN0SW5WaWV3KFxuICAgIHZpejogSVZpc3VhbGl6ZXIsXG4gICAgc2VnbWVudGVyOiBJSW5zdGFuY2VTZWdtZW50ZXIsXG4gICAgb3B0czogSW5zdGFuY2VTZWdtZW50T3B0aW9ucyA9IHt9LFxuICApOiBQcm9taXNlPG51bWJlcj4ge1xuICAgIGNvbnN0IHBpeGVscyA9IHZpei5nZXREaXNwbGF5ZWRQaXhlbERhdGE/LigpO1xuICAgIGlmICghcGl4ZWxzIHx8IHBpeGVscy53aWR0aCA9PT0gMCB8fCBwaXhlbHMuaGVpZ2h0ID09PSAwKSB7XG4gICAgICB0aGlzLnN0YXR1cyQubmV4dCgnTm8gaW1hZ2Ugb24gc2NyZWVuIHRvIGRldGVjdCBpbi4nKTtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cblxuICAgIHRoaXMuYnVzeSQubmV4dCh0cnVlKTtcbiAgICB0aGlzLnByb2dyZXNzJC5uZXh0KC0xKTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVjdCA9IHZpei5nZXREaXNwbGF5ZWRTb3VyY2VSZWN0Py4oKSA/PyBudWxsO1xuICAgICAgY29uc3QgdGFyZ2V0ID0gTnVtYmVyKG9wdHMuZG93bnNhbXBsaW5nRmFjdG9yID8/IDApIHx8IDA7XG4gICAgICBjb25zdCB2aWV3RmFjdG9yID0gcmVjdCAmJiBwaXhlbHMud2lkdGggPiAwID8gcmVjdC53aWR0aCAvIHBpeGVscy53aWR0aCA6IDE7XG5cbiAgICAgIC8vIFJlLWNyb3AgYXQgdGhlIG1vZGVsJ3Mgc2NhbGUgd2hlbiB0aGUgdmlldyBpcyBjb2Fyc2VyIHRoYW4gaXQgd2FudHMuXG4gICAgICAvLyBUaGUgaW1hZ2UgaXMgdGlsZS1iYWNrZWQsIHNvIHRoYXQgZGV0YWlsIGV4aXN0cyBzZXJ2ZXItc2lkZSBldmVuIHRob3VnaFxuICAgICAgLy8gdGhlIGRpc3BsYXllZCBwaXhlbHMgaGF2ZSBkaXNjYXJkZWQgaXQuXG4gICAgICBsZXQgc291cmNlID0geyBkYXRhOiBwaXhlbHMuZGF0YSwgd2lkdGg6IHBpeGVscy53aWR0aCwgaGVpZ2h0OiBwaXhlbHMuaGVpZ2h0IH07XG4gICAgICBpZiAocmVjdCAmJiB0YXJnZXQgPiAwICYmIHRhcmdldCA8IHZpZXdGYWN0b3IgKiAwLjk4KSB7XG4gICAgICAgIHRoaXMuc3RhdHVzJC5uZXh0KCdGZXRjaGluZyBpbWFnZSBhdCBtb2RlbCByZXNvbHV0aW9u4oCmJyk7XG4gICAgICAgIGNvbnN0IGhpID0gYXdhaXQgdGhpcy5mZXRjaENyb3BBdFNjYWxlKHJlY3QsIHRhcmdldCk7XG4gICAgICAgIGlmIChoaSkgc291cmNlID0gaGk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHNlZ21lbnRlci5zZWdtZW50SW5zdGFuY2VzKHNvdXJjZSwgb3B0cywge1xuICAgICAgICBvblByb2dyZXNzOiAoZikgPT4gdGhpcy5wcm9ncmVzcyQubmV4dChmKSxcbiAgICAgICAgb25TdGF0dXM6IChzKSA9PiB0aGlzLnN0YXR1cyQubmV4dChzKSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBWaWV3IHBpeGVscyAtPiBmdWxsLXJlc29sdXRpb24gaW1hZ2UgcGl4ZWxzLiBXaXRob3V0IHRoaXMgZXZlcnkgcmVnaW9uXG4gICAgICAvLyB3b3VsZCBzaXQgYXQgdmlldy1sb2NhbCBjb29yZGluYXRlcywgaS5lLiB0aGUgd3JvbmcgcGxhY2Ugb24gdGhlIHNsaWRlXG4gICAgICAvLyBmb3IgYW55IHpvb21lZCBvciBwYW5uZWQgdmlldy5cbiAgICAgIGNvbnN0IG9mZnNldFggPSByZWN0ID8gcmVjdC54IDogMDtcbiAgICAgIGNvbnN0IG9mZnNldFkgPSByZWN0ID8gcmVjdC55IDogMDtcbiAgICAgIC8vIEFnYWluc3QgdGhlIHBpeGVscyBhY3R1YWxseSBpbmZlcnJlZCBvbiwgd2hpY2ggbWF5IGJlIHRoZSByZS1jcm9wLlxuICAgICAgY29uc3QgcmF0aW9YID0gcmVjdCAmJiBzb3VyY2Uud2lkdGggPiAwID8gcmVjdC53aWR0aCAvIHNvdXJjZS53aWR0aCA6IDE7XG4gICAgICBjb25zdCByYXRpb1kgPSByZWN0ICYmIHNvdXJjZS5oZWlnaHQgPiAwID8gcmVjdC5oZWlnaHQgLyBzb3VyY2UuaGVpZ2h0IDogMTtcblxuICAgICAgLy8gVmlldyBwaXhlbHMgLT4gZnVsbC1yZXNvbHV0aW9uIGltYWdlIHBpeGVscywgZm9yIGFueSByaW5nLlxuICAgICAgY29uc3QgbWFwUmluZyA9IChyaW5nOiBBcnJheTxbbnVtYmVyLCBudW1iZXJdPik6IG51bWJlcltdW10gPT5cbiAgICAgICAgcmluZy5tYXAoKFt4LCB5XSkgPT4gW01hdGgucm91bmQob2Zmc2V0WCArIHggKiByYXRpb1gpLCBNYXRoLnJvdW5kKG9mZnNldFkgKyB5ICogcmF0aW9ZKV0pO1xuXG4gICAgICBjb25zdCBhZGRlZDogUmVnaW9uW10gPSBbXTtcbiAgICAgIGZvciAoY29uc3QgZGV0IG9mIHJlc3VsdC5kZXRlY3Rpb25zKSB7XG4gICAgICAgIGlmIChkZXQucG9seWdvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGZvciAoY29uc3QgcG9seSBvZiBkZXQucG9seWdvbnMpIHtcbiAgICAgICAgICAgIGlmIChwb2x5LmV4dGVyaW9yLmxlbmd0aCA8IDMpIGNvbnRpbnVlO1xuICAgICAgICAgICAgY29uc3QgZXh0ZXJpb3IgPSBtYXBSaW5nKHBvbHkuZXh0ZXJpb3IpO1xuICAgICAgICAgICAgYWRkZWQucHVzaChcbiAgICAgICAgICAgICAgdGhpcy5tYWtlUmVnaW9uKFxuICAgICAgICAgICAgICAgIGV4dGVyaW9yLm1hcCgoW3hdKSA9PiB4KSxcbiAgICAgICAgICAgICAgICBleHRlcmlvci5tYXAoKFssIHldKSA9PiB5KSxcbiAgICAgICAgICAgICAgICBkZXQuY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgIC8vIEEgbWFzayB3aXRoIGEgdm9pZCB0aHJvdWdoIGl0IGlzIGEgZG9udXQsIGFuZCBjb21taXR0aW5nIG9ubHlcbiAgICAgICAgICAgICAgICAvLyB0aGUgZXh0ZXJpb3IgZmlsbHMgaXQgaW4gc2lsZW50bHkg4oCUIHdoaWNoIHJlYWRzIGFzIGEgZGV0ZWN0aW9uXG4gICAgICAgICAgICAgICAgLy8gdGhhdCBvdmVyLWNvdmVycyByYXRoZXIgdGhhbiBhcyBsb3N0IGdlb21ldHJ5LiBFYWNoIHBvbHlnb25cbiAgICAgICAgICAgICAgICAvLyBhbHJlYWR5IG93bnMgaXRzIG93biBob2xlcywgc28gdGhlcmUgaXMgbm8gYW1iaWd1aXR5IGFib3V0XG4gICAgICAgICAgICAgICAgLy8gd2hpY2ggZXh0ZXJpb3IgYSByaW5nIGJlbG9uZ3MgdG8gZXZlbiB3aGVuIG9uZSBtYXNrIHNwbGl0c1xuICAgICAgICAgICAgICAgIC8vIGludG8gc2V2ZXJhbCBwb2x5Z29ucy4gUmluZ3MgdG9vIHNtYWxsIHRvIGJvdW5kIGFueXRoaW5nIGFmdGVyXG4gICAgICAgICAgICAgICAgLy8gc2ltcGxpZmljYXRpb24gYXJlIGRyb3BwZWQgcmF0aGVyIHRoYW4gZW1pdHRlZC5cbiAgICAgICAgICAgICAgICBwb2x5LmhvbGVzLmZpbHRlcigoaCkgPT4gaC5sZW5ndGggPj0gMykubWFwKG1hcFJpbmcpLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRGV0ZWN0aW9uIG1vZGUgeWllbGRzIG5vIG91dGxpbmU7IHRoZSBib3ggaXMgc3RpbGwgdGhlIHJlc3VsdCwgYW5kXG4gICAgICAgIC8vIG1hdGNoZXMgd2hhdCB0aGUgc2VydmVyIHdyaXRlcyBhcyBhIFwiZGV0ZWN0aW9uXCIgZmVhdHVyZS5cbiAgICAgICAgY29uc3QgW3gxLCB5MSwgeDIsIHkyXSA9IGRldC5ib3g7XG4gICAgICAgIGlmICh4MiAtIHgxIDw9IDAgfHwgeTIgLSB5MSA8PSAwKSBjb250aW51ZTtcbiAgICAgICAgYWRkZWQucHVzaChcbiAgICAgICAgICB0aGlzLm1ha2VSZWdpb24oXG4gICAgICAgICAgICBbeDEsIHgyLCB4MiwgeDFdLm1hcCgoeCkgPT4gTWF0aC5yb3VuZChvZmZzZXRYICsgeCAqIHJhdGlvWCkpLFxuICAgICAgICAgICAgW3kxLCB5MSwgeTIsIHkyXS5tYXAoKHkpID0+IE1hdGgucm91bmQob2Zmc2V0WSArIHkgKiByYXRpb1kpKSxcbiAgICAgICAgICAgIGRldC5jbGFzc05hbWUsXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGFkZGVkLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLnN0YXR1cyQubmV4dCgnTm8gb2JqZWN0cyBkZXRlY3RlZC4nKTtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG5cbiAgICAgIC8vIFJlcGxhY2UgdGhpcyB0b29sJ3Mgb3duIHByZXZpb3VzIG91dHB1dCwga2VlcCBldmVyeXRoaW5nIGVsc2UuIEFwcGVuZGluZ1xuICAgICAgLy8gdW5jb25kaXRpb25hbGx5IG1hZGUgZXZlcnkgdHVuaW5nIHJ1biBzdGFjayBvbnRvIHRoZSBsYXN0LCBzbyB0aGVcbiAgICAgIC8vIHZpZXdlciBhY2N1bXVsYXRlZCBvdmVybGFwcGluZyByZXN1bHRzIGZyb20gcGFyYW1ldGVycyBubyBsb25nZXIgaW5cbiAgICAgIC8vIGVmZmVjdC4gSGFuZC1kcmF3biByZWdpb25zIGFuZCBvdGhlciB0b29scycgb3V0cHV0IGNhcnJ5IG5vIGBzb3VyY2VgXG4gICAgICAvLyBhbmQgYXJlIHVudG91Y2hlZC5cbiAgICAgIGNvbnN0IGtlcHQgPSAodml6LmdldFJlZ2lvbnMoKSA/PyBbXSkuZmlsdGVyKChyKSA9PiByLnNvdXJjZSAhPT0gWU9MT19SRUdJT05fU09VUkNFKTtcbiAgICAgIHZpei5zZXRSZWdpb25zKFsuLi5rZXB0LCAuLi5hZGRlZF0pO1xuICAgICAgdGhpcy5zdGF0dXMkLm5leHQoYEFkZGVkICR7YWRkZWQubGVuZ3RofSByZWdpb24ocykuYCk7XG4gICAgICByZXR1cm4gYWRkZWQubGVuZ3RoO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5zdGF0dXMkLm5leHQoZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6ICdZT0xPIGRldGVjdGlvbiBmYWlsZWQuJyk7XG4gICAgICByZXR1cm4gMDtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5idXN5JC5uZXh0KGZhbHNlKTtcbiAgICAgIHRoaXMucHJvZ3Jlc3MkLm5leHQoLTEpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZS1jcm9wIGByZWN0YCBhdCBgMS90YXJnZXRgIG9mIGZ1bGwgcmVzb2x1dGlvbi4gUmV0dXJucyBudWxsIG9uIGFueVxuICAgKiBmYWlsdXJlLCBzbyB0aGUgY2FsbGVyIGZhbGxzIGJhY2sgdG8gdGhlIGRpc3BsYXllZCBwaXhlbHMg4oCUIGEgY29hcnNlciBjcm9wXG4gICAqIGJlYXRzIGEgZmFpbGVkIHJ1bi5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZmV0Y2hDcm9wQXRTY2FsZShcbiAgICByZWN0OiB7IHg6IG51bWJlcjsgeTogbnVtYmVyOyB3aWR0aDogbnVtYmVyOyBoZWlnaHQ6IG51bWJlciB9LFxuICAgIHRhcmdldDogbnVtYmVyLFxuICApOiBQcm9taXNlPHsgZGF0YTogVWludDhDbGFtcGVkQXJyYXk7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH0gfCBudWxsPiB7XG4gICAgaWYgKCF0aGlzLnRpbGVBY2Nlc3MpIHJldHVybiBudWxsO1xuICAgIGxldCB3ID0gTWF0aC5yb3VuZChyZWN0LndpZHRoIC8gdGFyZ2V0KTtcbiAgICBsZXQgaCA9IE1hdGgucm91bmQocmVjdC5oZWlnaHQgLyB0YXJnZXQpO1xuXG4gICAgLy8gQSBmYWN0b3Igb2YgMSBvdmVyIGEgd2hvbGUtc2xpZGUgUk9JIHdvdWxkIGFzayBmb3IgaHVuZHJlZHMgb2YgbWVnYXBpeGVscy5cbiAgICBjb25zdCBNQVhfUElYRUxTID0gMTZfNzc3XzIxNjsgLy8gNDA5NsKyXG4gICAgY29uc3QgcGl4ZWxzID0gdyAqIGg7XG4gICAgaWYgKHBpeGVscyA+IE1BWF9QSVhFTFMpIHtcbiAgICAgIGNvbnN0IGsgPSBNYXRoLnNxcnQoTUFYX1BJWEVMUyAvIHBpeGVscyk7XG4gICAgICB3ID0gTWF0aC5yb3VuZCh3ICogayk7XG4gICAgICBoID0gTWF0aC5yb3VuZChoICogayk7XG4gICAgfVxuICAgIGlmICh3IDwgNjQgfHwgaCA8IDY0KSByZXR1cm4gbnVsbDtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByb2kgPSB7XG4gICAgICAgIHg6IE1hdGgucm91bmQocmVjdC54KSxcbiAgICAgICAgeTogTWF0aC5yb3VuZChyZWN0LnkpLFxuICAgICAgICB3aWR0aDogTWF0aC5yb3VuZChyZWN0LndpZHRoKSxcbiAgICAgICAgaGVpZ2h0OiBNYXRoLnJvdW5kKHJlY3QuaGVpZ2h0KSxcbiAgICAgIH0gYXMgUmVjdGFuZ2xlO1xuICAgICAgY29uc3Qgc2NyZWVuID0geyB4OiAwLCB5OiAwLCB3aWR0aDogdywgaGVpZ2h0OiBoIH0gYXMgUmVjdGFuZ2xlO1xuICAgICAgY29uc3QgYnl0ZXMgPSBhd2FpdCBmaXJzdFZhbHVlRnJvbSh0aGlzLnRpbGVBY2Nlc3Muem9vbU9uUmVnaW9uKHJvaSwgc2NyZWVuLCAwKSk7XG4gICAgICBpZiAoIWJ5dGVzIHx8IGJ5dGVzLmJ5dGVMZW5ndGggPT09IDApIHJldHVybiBudWxsO1xuXG4gICAgICBjb25zdCBiaXRtYXAgPSBhd2FpdCBjcmVhdGVJbWFnZUJpdG1hcChuZXcgQmxvYihbYnl0ZXNdKSk7XG4gICAgICBjb25zdCBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICAgIGNhbnZhcy53aWR0aCA9IGJpdG1hcC53aWR0aDtcbiAgICAgIGNhbnZhcy5oZWlnaHQgPSBiaXRtYXAuaGVpZ2h0O1xuICAgICAgY29uc3QgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgICBpZiAoIWN0eCkgcmV0dXJuIG51bGw7XG4gICAgICBjdHguZHJhd0ltYWdlKGJpdG1hcCwgMCwgMCk7XG4gICAgICAvLyBSZWFkIHRoZSBkaW1lbnNpb25zIEJFRk9SRSBjbG9zZSgpOiBjbG9zaW5nIGFuIEltYWdlQml0bWFwIHplcm9lcyBpdHNcbiAgICAgIC8vIHdpZHRoL2hlaWdodCwgc28gcmV0dXJuaW5nIHRoZW0gYWZ0ZXJ3YXJkcyB5aWVsZHMgYSAweDAgaW1hZ2Ugd2l0aCBhXG4gICAgICAvLyBmdWxsIHBpeGVsIGJ1ZmZlciDigJQgaW5mZXJlbmNlIHRoZW4gcnVucyBvbiBub3RoaW5nIGFuZCBmaW5kcyBub3RoaW5nLlxuICAgICAgY29uc3Qgd2lkdGggPSBiaXRtYXAud2lkdGg7XG4gICAgICBjb25zdCBoZWlnaHQgPSBiaXRtYXAuaGVpZ2h0O1xuICAgICAgY29uc3Qgb3V0ID0gY3R4LmdldEltYWdlRGF0YSgwLCAwLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICAgIGJpdG1hcC5jbG9zZT8uKCk7XG4gICAgICByZXR1cm4geyBkYXRhOiBvdXQuZGF0YSwgd2lkdGgsIGhlaWdodCB9O1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBtYWtlUmVnaW9uKHhzOiBudW1iZXJbXSwgeXM6IG51bWJlcltdLCBjbGFzc05hbWU6IHN0cmluZywgaG9sZXM6IG51bWJlcltdW11bXSA9IFtdKTogUmVnaW9uIHtcbiAgICBjb25zdCBwb2x5ID0gbmV3IFBvbHlnb24oKTtcbiAgICBwb2x5Lm5wb2ludHMgPSB4cy5sZW5ndGg7XG4gICAgcG9seS54cG9pbnRzID0geHM7XG4gICAgcG9seS55cG9pbnRzID0geXM7XG4gICAgcG9seS5jb29yZGluYXRlcyA9IHhzLm1hcCgoeCwgaSkgPT4gW3gsIHlzW2ldXSk7XG4gICAgcG9seS5jbG9zZWQgPSB0cnVlO1xuICAgIC8vIFNhbWUgY2xvc2VkLXJpbmcgY29udmVudGlvbiBhcyB0aGUgZXh0ZXJpb3I6IG5vIHJlcGVhdGVkIGNsb3NpbmcgcG9pbnQuXG4gICAgLy8gTGVmdCB1bnNldCB3aGVuIGVtcHR5IHNvIGEgc29saWQgcmVnaW9uIGRvZXMgbm90IGNhcnJ5IGFuIGVtcHR5IGFycmF5XG4gICAgLy8gdGhyb3VnaCBleHBvcnQgYW5kIHJvdW5kLXRyaXBwaW5nLlxuICAgIGlmIChob2xlcy5sZW5ndGgpIHBvbHkuaG9sZXMgPSBob2xlcztcblxuICAgIGNvbnN0IHJlZ2lvbiA9IG5ldyBSZWdpb24oKTtcbiAgICByZWdpb24uYm91bmRzID0gcG9seTtcbiAgICByZWdpb24uc291cmNlID0gWU9MT19SRUdJT05fU09VUkNFO1xuICAgIC8vIFRoZSBjbGFzcyBuYW1lIGRyaXZlcyBwcmVzZXQgY29sb3VyIHJlc29sdXRpb247IGxlYXZpbmcgYGNvbG9yYCB1bnNldCBsZXRzXG4gICAgLy8gYW4gZXhpc3RpbmcgcHJlc2V0IGZvciB0aGlzIGNsYXNzIHdpbi5cbiAgICByZWdpb24ubGFiZWwgPSBjbGFzc05hbWU7XG4gICAgcmV0dXJuIHJlZ2lvbjtcbiAgfVxufVxuIl19
|