@jax-data-science/sci-image-visualizer 0.9.0 → 0.11.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 +10 -1
- package/esm2022/lib/contracts/image.contract.mjs +1 -1
- package/esm2022/lib/contracts/ports/region-io.port.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/openseadragon-viewer-options.mjs +18 -2
- package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +9 -1
- 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/osd/osd-tile-loading.mjs +71 -0
- package/esm2022/lib/implementations/osd/osd-viewer-like.mjs +1 -1
- package/esm2022/lib/implementations/osd/slice-cache.mjs +35 -6
- 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 +670 -42
- package/esm2022/lib/region-editor/region-metrics.mjs +20 -2
- package/esm2022/lib/region-editor/region-persistence.service.mjs +44 -10
- package/esm2022/lib/region-editor/region-table/region-table.component.mjs +24 -8
- package/esm2022/lib/region-import/label-classes.mjs +149 -0
- package/esm2022/lib/region-import/label-volume.mjs +194 -0
- package/esm2022/lib/region-import/region-import.mjs +71 -0
- 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 +510 -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 +186 -0
- package/esm2022/lib/store/region-store.service.mjs +774 -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 +155 -7
- 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-BELcx0jv.mjs} +9851 -2904
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BELcx0jv.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-DEDSm_NL.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-DEDSm_NL.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 +12 -0
- package/lib/contracts/image.contract.d.ts +4 -0
- package/lib/contracts/ports/region-io.port.d.ts +24 -0
- package/lib/contracts/region-editor-api.contract.d.ts +102 -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/openseadragon-viewer-options.d.ts +2 -0
- package/lib/implementations/osd/openseadragon-visualizer.service.d.ts +2 -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/osd/osd-tile-loading.d.ts +43 -0
- package/lib/implementations/osd/osd-viewer-like.d.ts +14 -0
- package/lib/implementations/osd/slice-cache.d.ts +13 -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 +159 -17
- package/lib/region-editor/region-metrics.d.ts +8 -0
- package/lib/region-editor/region-persistence.service.d.ts +17 -5
- package/lib/region-editor/region-table/region-table.component.d.ts +10 -4
- package/lib/region-import/label-classes.d.ts +39 -0
- package/lib/region-import/label-volume.d.ts +31 -0
- package/lib/region-import/region-import.d.ts +46 -0
- 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 +168 -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 +74 -0
- package/lib/store/region-store.service.d.ts +216 -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 +40 -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,186 @@
|
|
|
1
|
+
/** Sources held open, past which the least recently used one is closed (never the one shown). */
|
|
2
|
+
export const OPEN_REGION_SOURCES = 6;
|
|
3
|
+
const NONE = new Set();
|
|
4
|
+
/**
|
|
5
|
+
* The region sources of every image the store has seen, per slice, and per slice the ids of
|
|
6
|
+
* the source features taken out of the source (into the working set, or deleted) — those the
|
|
7
|
+
* source no longer draws and an export leaves out.
|
|
8
|
+
*
|
|
9
|
+
* Sources open lazily, the first time their slice is shown or read, and at most
|
|
10
|
+
* {@link OPEN_REGION_SOURCES} stay open: the least recently used are closed and re-opened from
|
|
11
|
+
* their opener when used again (a source's ids are stable, so what was taken stays taken). The
|
|
12
|
+
* source of the slice on screen ({@link show}) is never closed for another: a read across every
|
|
13
|
+
* slice must not close the source the viewer draws and takes from.
|
|
14
|
+
*/
|
|
15
|
+
export class RegionSourceScope {
|
|
16
|
+
constructor() {
|
|
17
|
+
this.images = new Map();
|
|
18
|
+
/** Open entries, least recently used first. */
|
|
19
|
+
this.openOrder = [];
|
|
20
|
+
/** The entry of the slice on screen: kept open. */
|
|
21
|
+
this.shown = null;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Attach `open` to `image` for `slices`, replacing (and closing) what was there. `imported` names
|
|
25
|
+
* the slices it brings that a save must write (see {@link importedSlices}): for a source of one
|
|
26
|
+
* slice, that slice when non-empty; for a `'planes'` source, the slices its planes cover.
|
|
27
|
+
*/
|
|
28
|
+
attach(image, open, slices, imported = []) {
|
|
29
|
+
const sources = this.imageSources(image);
|
|
30
|
+
const entry = { open, source: null, ready: null };
|
|
31
|
+
if (slices === 'planes') {
|
|
32
|
+
if (sources.planes)
|
|
33
|
+
this.close(sources.planes);
|
|
34
|
+
sources.planes = entry;
|
|
35
|
+
sources.perSlice.forEach((e) => this.close(e));
|
|
36
|
+
sources.perSlice.clear();
|
|
37
|
+
sources.taken.clear();
|
|
38
|
+
sources.imported = new Set(imported);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
const old = sources.perSlice.get(slices.slice);
|
|
42
|
+
if (old)
|
|
43
|
+
this.close(old);
|
|
44
|
+
entry.plane = slices.plane ?? 0;
|
|
45
|
+
sources.perSlice.set(slices.slice, entry);
|
|
46
|
+
sources.taken.delete(slices.slice);
|
|
47
|
+
if (imported.length)
|
|
48
|
+
sources.imported.add(slices.slice);
|
|
49
|
+
else
|
|
50
|
+
sources.imported.delete(slices.slice);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/** Drop every source of `image` (closing the open ones) and what was taken from them. */
|
|
54
|
+
detachImage(image) {
|
|
55
|
+
const sources = this.images.get(image);
|
|
56
|
+
if (!sources)
|
|
57
|
+
return;
|
|
58
|
+
if (sources.planes)
|
|
59
|
+
this.close(sources.planes);
|
|
60
|
+
sources.perSlice.forEach((e) => this.close(e));
|
|
61
|
+
this.images.delete(image);
|
|
62
|
+
}
|
|
63
|
+
/** Drop the source of one slice of `image`. */
|
|
64
|
+
detachSlice(image, slice) {
|
|
65
|
+
const sources = this.images.get(image);
|
|
66
|
+
const entry = sources?.perSlice.get(slice);
|
|
67
|
+
if (!sources || !entry)
|
|
68
|
+
return;
|
|
69
|
+
this.close(entry);
|
|
70
|
+
sources.perSlice.delete(slice);
|
|
71
|
+
sources.taken.delete(slice);
|
|
72
|
+
sources.imported.delete(slice);
|
|
73
|
+
}
|
|
74
|
+
/** The slice on screen (null: none): its source stays open while others are read. */
|
|
75
|
+
show(image, slice) {
|
|
76
|
+
this.shown = image && slice !== null ? this.entry(image, slice) : null;
|
|
77
|
+
}
|
|
78
|
+
/** Whether `image` has a source for `slice`. */
|
|
79
|
+
has(image, slice) {
|
|
80
|
+
return !!image && !!this.entry(image, slice);
|
|
81
|
+
}
|
|
82
|
+
/** Whether `slice` of `image` has a source of its own (not a `'planes'` source's plane). */
|
|
83
|
+
hasOwnSource(image, slice) {
|
|
84
|
+
return !!image && !!this.images.get(image)?.perSlice.has(slice);
|
|
85
|
+
}
|
|
86
|
+
/** Every slice of `image` with a source of its own (not counting a `'planes'` source). */
|
|
87
|
+
slicesWithSource(image) {
|
|
88
|
+
if (!image)
|
|
89
|
+
return [];
|
|
90
|
+
return Array.from(this.images.get(image)?.perSlice.keys() ?? []).sort((a, b) => a - b);
|
|
91
|
+
}
|
|
92
|
+
/** Whether `image` has one source over all its slices. */
|
|
93
|
+
hasPlanesSource(image) {
|
|
94
|
+
return !!image && !!this.images.get(image)?.planes;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The source behind `slice` of `image`, opening it if needed. Resolves null when there is
|
|
98
|
+
* none, and rejects when it cannot be opened.
|
|
99
|
+
*/
|
|
100
|
+
async binding(image, slice) {
|
|
101
|
+
const entry = image ? this.entry(image, slice) : null;
|
|
102
|
+
if (!entry)
|
|
103
|
+
return null;
|
|
104
|
+
const source = await this.openEntry(entry);
|
|
105
|
+
return { source, plane: entry.plane ?? slice };
|
|
106
|
+
}
|
|
107
|
+
/** The ids taken from `slice`'s source. */
|
|
108
|
+
taken(image, slice) {
|
|
109
|
+
return (image && this.images.get(image)?.taken.get(slice)) || NONE;
|
|
110
|
+
}
|
|
111
|
+
/** Every id taken from any slice of `image` (a `'planes'` source's ids are unique across them). */
|
|
112
|
+
allTaken(image) {
|
|
113
|
+
const taken = image ? this.images.get(image)?.taken : undefined;
|
|
114
|
+
return taken ? Array.from(taken.values()).flatMap((ids) => Array.from(ids)) : [];
|
|
115
|
+
}
|
|
116
|
+
/** The slices of `image` whose source was imported (see {@link attach}), in order. */
|
|
117
|
+
importedSlices(image) {
|
|
118
|
+
const imported = image ? this.images.get(image)?.imported : undefined;
|
|
119
|
+
return imported ? Array.from(imported).sort((a, b) => a - b) : [];
|
|
120
|
+
}
|
|
121
|
+
/** The slices of `image` with anything taken from their source. */
|
|
122
|
+
slicesWithTaken(image) {
|
|
123
|
+
const taken = image ? this.images.get(image)?.taken : undefined;
|
|
124
|
+
return taken ? Array.from(taken.keys()) : [];
|
|
125
|
+
}
|
|
126
|
+
/** Replace the ids taken from `slice`'s source (copy-on-write: `ids` is kept as given). */
|
|
127
|
+
setTaken(image, slice, ids) {
|
|
128
|
+
if (!image)
|
|
129
|
+
return;
|
|
130
|
+
const sources = this.images.get(image);
|
|
131
|
+
if (!sources)
|
|
132
|
+
return;
|
|
133
|
+
if (ids.size)
|
|
134
|
+
sources.taken.set(slice, ids);
|
|
135
|
+
else
|
|
136
|
+
sources.taken.delete(slice);
|
|
137
|
+
}
|
|
138
|
+
entry(image, slice) {
|
|
139
|
+
const sources = this.images.get(image);
|
|
140
|
+
return sources?.perSlice.get(slice) ?? sources?.planes ?? null;
|
|
141
|
+
}
|
|
142
|
+
imageSources(image) {
|
|
143
|
+
let sources = this.images.get(image);
|
|
144
|
+
if (!sources) {
|
|
145
|
+
sources = { planes: null, perSlice: new Map(), taken: new Map(), imported: new Set() };
|
|
146
|
+
this.images.set(image, sources);
|
|
147
|
+
}
|
|
148
|
+
return sources;
|
|
149
|
+
}
|
|
150
|
+
openEntry(entry) {
|
|
151
|
+
const at = this.openOrder.indexOf(entry);
|
|
152
|
+
if (at >= 0)
|
|
153
|
+
this.openOrder.splice(at, 1);
|
|
154
|
+
this.openOrder.push(entry);
|
|
155
|
+
if (!entry.source) {
|
|
156
|
+
const opening = entry.open();
|
|
157
|
+
entry.source = opening;
|
|
158
|
+
opening.then((source) => {
|
|
159
|
+
if (entry.source === opening)
|
|
160
|
+
entry.ready = source;
|
|
161
|
+
else
|
|
162
|
+
source.dispose(); // closed while it opened
|
|
163
|
+
}, () => {
|
|
164
|
+
if (entry.source === opening)
|
|
165
|
+
entry.source = null; // try again next time
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
while (this.openOrder.length > OPEN_REGION_SOURCES) {
|
|
169
|
+
const [oldest] = this.openOrder.splice(this.openOrder.findIndex((e) => e !== this.shown), 1);
|
|
170
|
+
this.closeSource(oldest);
|
|
171
|
+
}
|
|
172
|
+
return entry.source;
|
|
173
|
+
}
|
|
174
|
+
close(entry) {
|
|
175
|
+
const at = this.openOrder.indexOf(entry);
|
|
176
|
+
if (at >= 0)
|
|
177
|
+
this.openOrder.splice(at, 1);
|
|
178
|
+
this.closeSource(entry);
|
|
179
|
+
}
|
|
180
|
+
closeSource(entry) {
|
|
181
|
+
entry.ready?.dispose();
|
|
182
|
+
entry.ready = null;
|
|
183
|
+
entry.source = null;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaW9uLXNvdXJjZS1zY29wZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvc3RvcmUvcmVnaW9uLXNvdXJjZS1zY29wZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFlQSxpR0FBaUc7QUFDakcsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxDQUFDO0FBc0JyQyxNQUFNLElBQUksR0FBd0IsSUFBSSxHQUFHLEVBQVUsQ0FBQztBQUVwRDs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxPQUFPLGlCQUFpQjtJQUE5QjtRQUNtQixXQUFNLEdBQUcsSUFBSSxHQUFHLEVBQXdCLENBQUM7UUFDMUQsK0NBQStDO1FBQzlCLGNBQVMsR0FBWSxFQUFFLENBQUM7UUFDekMsbURBQW1EO1FBQzNDLFVBQUssR0FBaUIsSUFBSSxDQUFDO0lBOEtyQyxDQUFDO0lBNUtDOzs7O09BSUc7SUFDSCxNQUFNLENBQ0osS0FBYSxFQUNiLElBQXdCLEVBQ3hCLE1BQTBCLEVBQzFCLFdBQThCLEVBQUU7UUFFaEMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN6QyxNQUFNLEtBQUssR0FBVSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQztRQUN6RCxJQUFJLE1BQU0sS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUN4QixJQUFJLE9BQU8sQ0FBQyxNQUFNO2dCQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQy9DLE9BQU8sQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO1lBQ3ZCLE9BQU8sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDL0MsT0FBTyxDQUFDLFFB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QUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FDcEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQ2pELENBQUMsQ0FDRixDQUFDO1lBQ0YsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMzQixDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDO0lBQ3RCLENBQUM7SUFFTyxLQUFLLENBQUMsS0FBWTtRQUN4QixNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN6QyxJQUFJLEVBQUUsSUFBSSxDQUFDO1lBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzFDLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDMUIsQ0FBQztJQUVPLFdBQVcsQ0FBQyxLQUFZO1FBQzlCLEtBQUssQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLENBQUM7UUFDdkIsS0FBSyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7UUFDbkIsS0FBSyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7SUFDdEIsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBSZWdpb25Tb3VyY2UgfSBmcm9tICcuLi9yZWdpb24tc291cmNlL3JlZ2lvbi1zb3VyY2UnO1xuXG4vKiogT3BlbnMgYSByZWdpb24gc291cmNlIG9uIGRlbWFuZCAoYW5kIGFnYWluIGFmdGVyIGl0IHdhcyBjbG9zZWQgdG8gc2F2ZSBtZW1vcnkpLiAqL1xuZXhwb3J0IHR5cGUgUmVnaW9uU291cmNlT3BlbmVyID0gKCkgPT4gUHJvbWlzZTxSZWdpb25Tb3VyY2U+O1xuXG4vKiogV2hpY2ggc2xpY2VzIGEgc291cmNlIHNlcnZlczogb25lIHNsaWNlIChwbGFuZSBgcGxhbmVgIG9mIHRoZSBzb3VyY2UpLCBvciBldmVyeSBzbGljZSB6XG4gKiAgZnJvbSB0aGUgc291cmNlJ3MgcGxhbmUgeiAoYSB6LWluZGV4ZWQgR2VvSlNPTiBvdmVyIGEgd2hvbGUgc3RhY2spLiAqL1xuZXhwb3J0IHR5cGUgUmVnaW9uU291cmNlU2xpY2VzID0geyBzbGljZTogbnVtYmVyOyBwbGFuZT86IG51bWJlciB9IHwgJ3BsYW5lcyc7XG5cbi8qKiBUaGUgcmVnaW9uIHNvdXJjZSBiZWhpbmQgb25lIHNsaWNlOiB0aGUgc291cmNlIGFuZCB3aGljaCBvZiBpdHMgcGxhbmVzIHRoZSBzbGljZSBzaG93cy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVnaW9uU291cmNlQmluZGluZyB7XG4gIHNvdXJjZTogUmVnaW9uU291cmNlO1xuICBwbGFuZTogbnVtYmVyO1xufVxuXG4vKiogU291cmNlcyBoZWxkIG9wZW4sIHBhc3Qgd2hpY2ggdGhlIGxlYXN0IHJlY2VudGx5IHVzZWQgb25lIGlzIGNsb3NlZCAobmV2ZXIgdGhlIG9uZSBzaG93bikuICovXG5leHBvcnQgY29uc3QgT1BFTl9SRUdJT05fU09VUkNFUyA9IDY7XG5cbmludGVyZmFjZSBFbnRyeSB7XG4gIG9wZW46IFJlZ2lvblNvdXJjZU9wZW5lcjtcbiAgLyoqIFRoZSBwbGFuZSBlYWNoIHNsaWNlIHNob3dzOyB1bmRlZmluZWQgPSB0aGUgc2xpY2UncyBvd24gaW5kZXguICovXG4gIHBsYW5lPzogbnVtYmVyO1xuICBzb3VyY2U6IFByb21pc2U8UmVnaW9uU291cmNlPiB8IG51bGw7XG4gIC8qKiBUaGUgcmVzb2x2ZWQgc291cmNlLCBvbmNlIG9wZW4uICovXG4gIHJlYWR5OiBSZWdpb25Tb3VyY2UgfCBudWxsO1xufVxuXG5pbnRlcmZhY2UgSW1hZ2VTb3VyY2VzIHtcbiAgLyoqIFRoZSBzb3VyY2Ugb3ZlciBldmVyeSBzbGljZSAoYCdwbGFuZXMnYCksIGlmIGFueS4gKi9cbiAgcGxhbmVzOiBFbnRyeSB8IG51bGw7XG4gIHBlclNsaWNlOiBNYXA8bnVtYmVyLCBFbnRyeT47XG4gIC8qKiBTb3VyY2UgZmVhdHVyZSBpZHMgdGFrZW4gaW50byB0aGUgd29ya2luZyBzZXQgKG9yIGRlbGV0ZWQpLCBwZXIgc2xpY2UuICovXG4gIHRha2VuOiBNYXA8bnVtYmVyLCBSZWFkb25seVNldDxzdHJpbmc+PjtcbiAgLyoqIFNsaWNlcyB3aG9zZSBzb3VyY2Ugd2FzIGltcG9ydGVkIChub3QgdGhlIGltYWdlJ3Mgb3duIHJlZ2lvbnMpOiBhIHNhdmUgd3JpdGVzIHRoZW0sIHRob3VnaFxuICAgKiAgbm90aGluZyB3YXMgdGFrZW4sIHNpbmNlIHRoZXkgYXJlIG9uIG5vIGZpbGUgeWV0LiAqL1xuICBpbXBvcnRlZDogU2V0PG51bWJlcj47XG59XG5cbmNvbnN0IE5PTkU6IFJlYWRvbmx5U2V0PHN0cmluZz4gPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuLyoqXG4gKiBUaGUgcmVnaW9uIHNvdXJjZXMgb2YgZXZlcnkgaW1hZ2UgdGhlIHN0b3JlIGhhcyBzZWVuLCBwZXIgc2xpY2UsIGFuZCBwZXIgc2xpY2UgdGhlIGlkcyBvZlxuICogdGhlIHNvdXJjZSBmZWF0dXJlcyB0YWtlbiBvdXQgb2YgdGhlIHNvdXJjZSAoaW50byB0aGUgd29ya2luZyBzZXQsIG9yIGRlbGV0ZWQpIOKAlCB0aG9zZSB0aGVcbiAqIHNvdXJjZSBubyBsb25nZXIgZHJhd3MgYW5kIGFuIGV4cG9ydCBsZWF2ZXMgb3V0LlxuICpcbiAqIFNvdXJjZXMgb3BlbiBsYXppbHksIHRoZSBmaXJzdCB0aW1lIHRoZWlyIHNsaWNlIGlzIHNob3duIG9yIHJlYWQsIGFuZCBhdCBtb3N0XG4gKiB7QGxpbmsgT1BFTl9SRUdJT05fU09VUkNFU30gc3RheSBvcGVuOiB0aGUgbGVhc3QgcmVjZW50bHkgdXNlZCBhcmUgY2xvc2VkIGFuZCByZS1vcGVuZWQgZnJvbVxuICogdGhlaXIgb3BlbmVyIHdoZW4gdXNlZCBhZ2FpbiAoYSBzb3VyY2UncyBpZHMgYXJlIHN0YWJsZSwgc28gd2hhdCB3YXMgdGFrZW4gc3RheXMgdGFrZW4pLiBUaGVcbiAqIHNvdXJjZSBvZiB0aGUgc2xpY2Ugb24gc2NyZWVuICh7QGxpbmsgc2hvd30pIGlzIG5ldmVyIGNsb3NlZCBmb3IgYW5vdGhlcjogYSByZWFkIGFjcm9zcyBldmVyeVxuICogc2xpY2UgbXVzdCBub3QgY2xvc2UgdGhlIHNvdXJjZSB0aGUgdmlld2VyIGRyYXdzIGFuZCB0YWtlcyBmcm9tLlxuICovXG5leHBvcnQgY2xhc3MgUmVnaW9uU291cmNlU2NvcGUge1xuICBwcml2YXRlIHJlYWRvbmx5IGltYWdlcyA9IG5ldyBNYXA8c3RyaW5nLCBJbWFnZVNvdXJjZXM+KCk7XG4gIC8qKiBPcGVuIGVudHJpZXMsIGxlYXN0IHJlY2VudGx5IHVzZWQgZmlyc3QuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgb3Blbk9yZGVyOiBFbnRyeVtdID0gW107XG4gIC8qKiBUaGUgZW50cnkgb2YgdGhlIHNsaWNlIG9uIHNjcmVlbjoga2VwdCBvcGVuLiAqL1xuICBwcml2YXRlIHNob3duOiBFbnRyeSB8IG51bGwgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBBdHRhY2ggYG9wZW5gIHRvIGBpbWFnZWAgZm9yIGBzbGljZXNgLCByZXBsYWNpbmcgKGFuZCBjbG9zaW5nKSB3aGF0IHdhcyB0aGVyZS4gYGltcG9ydGVkYCBuYW1lc1xuICAgKiB0aGUgc2xpY2VzIGl0IGJyaW5ncyB0aGF0IGEgc2F2ZSBtdXN0IHdyaXRlIChzZWUge0BsaW5rIGltcG9ydGVkU2xpY2VzfSk6IGZvciBhIHNvdXJjZSBvZiBvbmVcbiAgICogc2xpY2UsIHRoYXQgc2xpY2Ugd2hlbiBub24tZW1wdHk7IGZvciBhIGAncGxhbmVzJ2Agc291cmNlLCB0aGUgc2xpY2VzIGl0cyBwbGFuZXMgY292ZXIuXG4gICAqL1xuICBhdHRhY2goXG4gICAgaW1hZ2U6IHN0cmluZyxcbiAgICBvcGVuOiBSZWdpb25Tb3VyY2VPcGVuZXIsXG4gICAgc2xpY2VzOiBSZWdpb25Tb3VyY2VTbGljZXMsXG4gICAgaW1wb3J0ZWQ6IHJlYWRvbmx5IG51bWJlcltdID0gW10sXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IHNvdXJjZXMgPSB0aGlzLmltYWdlU291cmNlcyhpbWFnZSk7XG4gICAgY29uc3QgZW50cnk6IEVudHJ5ID0geyBvcGVuLCBzb3VyY2U6IG51bGwsIHJlYWR5OiBudWxsIH07XG4gICAgaWYgKHNsaWNlcyA9PT0gJ3BsYW5lcycpIHtcbiAgICAgIGlmIChzb3VyY2VzLnBsYW5lcykgdGhpcy5jbG9zZShzb3VyY2VzLnBsYW5lcyk7XG4gICAgICBzb3VyY2VzLnBsYW5lcyA9IGVudHJ5O1xuICAgICAgc291cmNlcy5wZXJTbGljZS5mb3JFYWNoKChlKSA9PiB0aGlzLmNsb3NlKGUpKTtcbiAgICAgIHNvdXJjZXMucGVyU2xpY2UuY2xlYXIoKTtcbiAgICAgIHNvdXJjZXMudGFrZW4uY2xlYXIoKTtcbiAgICAgIHNvdXJjZXMuaW1wb3J0ZWQgPSBuZXcgU2V0KGltcG9ydGVkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3Qgb2xkID0gc291cmNlcy5wZXJTbGljZS5nZXQoc2xpY2VzLnNsaWNlKTtcbiAgICAgIGlmIChvbGQpIHRoaXMuY2xvc2Uob2xkKTtcbiAgICAgIGVudHJ5LnBsYW5lID0gc2xpY2VzLnBsYW5lID8/IDA7XG4gICAgICBzb3VyY2VzLnBlclNsaWNlLnNldChzbGljZXMuc2xpY2UsIGVudHJ5KTtcbiAgICAgIHNvdXJjZXMudGFrZW4uZGVsZXRlKHNsaWNlcy5zbGljZSk7XG4gICAgICBpZiAoaW1wb3J0ZWQubGVuZ3RoKSBzb3VyY2VzLmltcG9ydGVkLmFkZChzbGljZXMuc2xpY2UpO1xuICAgICAgZWxzZSBzb3VyY2VzLmltcG9ydGVkLmRlbGV0ZShzbGljZXMuc2xpY2UpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBEcm9wIGV2ZXJ5IHNvdXJjZSBvZiBgaW1hZ2VgIChjbG9zaW5nIHRoZSBvcGVuIG9uZXMpIGFuZCB3aGF0IHdhcyB0YWtlbiBmcm9tIHRoZW0uICovXG4gIGRldGFjaEltYWdlKGltYWdlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBzb3VyY2VzID0gdGhpcy5pbWFnZXMuZ2V0KGltYWdlKTtcbiAgICBpZiAoIXNvdXJjZXMpIHJldHVybjtcbiAgICBpZiAoc291cmNlcy5wbGFuZXMpIHRoaXMuY2xvc2Uoc291cmNlcy5wbGFuZXMpO1xuICAgIHNvdXJjZXMucGVyU2xpY2UuZm9yRWFjaCgoZSkgPT4gdGhpcy5jbG9zZShlKSk7XG4gICAgdGhpcy5pbWFnZXMuZGVsZXRlKGltYWdlKTtcbiAgfVxuXG4gIC8qKiBEcm9wIHRoZSBzb3VyY2Ugb2Ygb25lIHNsaWNlIG9mIGBpbWFnZWAuICovXG4gIGRldGFjaFNsaWNlKGltYWdlOiBzdHJpbmcsIHNsaWNlOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBzb3VyY2VzID0gdGhpcy5pbWFnZXMuZ2V0KGltYWdlKTtcbiAgICBjb25zdCBlbnRyeSA9IHNvdXJjZXM/LnBlclNsaWNlLmdldChzbGljZSk7XG4gICAgaWYgKCFzb3VyY2VzIHx8ICFlbnRyeSkgcmV0dXJuO1xuICAgIHRoaXMuY2xvc2UoZW50cnkpO1xuICAgIHNvdXJjZXMucGVyU2xpY2UuZGVsZXRlKHNsaWNlKTtcbiAgICBzb3VyY2VzLnRha2VuLmRlbGV0ZShzbGljZSk7XG4gICAgc291cmNlcy5pbXBvcnRlZC5kZWxldGUoc2xpY2UpO1xuICB9XG5cbiAgLyoqIFRoZSBzbGljZSBvbiBzY3JlZW4gKG51bGw6IG5vbmUpOiBpdHMgc291cmNlIHN0YXlzIG9wZW4gd2hpbGUgb3RoZXJzIGFyZSByZWFkLiAqL1xuICBzaG93KGltYWdlOiBzdHJpbmcgfCB1bmRlZmluZWQsIHNsaWNlOiBudW1iZXIgfCBudWxsKTogdm9pZCB7XG4gICAgdGhpcy5zaG93biA9IGltYWdlICYmIHNsaWNlICE9PSBudWxsID8gdGhpcy5lbnRyeShpbWFnZSwgc2xpY2UpIDogbnVsbDtcbiAgfVxuXG4gIC8qKiBXaGV0aGVyIGBpbWFnZWAgaGFzIGEgc291cmNlIGZvciBgc2xpY2VgLiAqL1xuICBoYXMoaW1hZ2U6IHN0cmluZyB8IHVuZGVmaW5lZCwgc2xpY2U6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIWltYWdlICYmICEhdGhpcy5lbnRyeShpbWFnZSwgc2xpY2UpO1xuICB9XG5cbiAgLyoqIFdoZXRoZXIgYHNsaWNlYCBvZiBgaW1hZ2VgIGhhcyBhIHNvdXJjZSBvZiBpdHMgb3duIChub3QgYSBgJ3BsYW5lcydgIHNvdXJjZSdzIHBsYW5lKS4gKi9cbiAgaGFzT3duU291cmNlKGltYWdlOiBzdHJpbmcgfCB1bmRlZmluZWQsIHNsaWNlOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISFpbWFnZSAmJiAhIXRoaXMuaW1hZ2VzLmdldChpbWFnZSk/LnBlclNsaWNlLmhhcyhzbGljZSk7XG4gIH1cblxuICAvKiogRXZlcnkgc2xpY2Ugb2YgYGltYWdlYCB3aXRoIGEgc291cmNlIG9mIGl0cyBvd24gKG5vdCBjb3VudGluZyBhIGAncGxhbmVzJ2Agc291cmNlKS4gKi9cbiAgc2xpY2VzV2l0aFNvdXJjZShpbWFnZTogc3RyaW5nIHwgdW5kZWZpbmVkKTogbnVtYmVyW10ge1xuICAgIGlmICghaW1hZ2UpIHJldHVybiBbXTtcbiAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLmltYWdlcy5nZXQoaW1hZ2UpPy5wZXJTbGljZS5rZXlzKCkgPz8gW10pLnNvcnQoKGEsIGIpID0+IGEgLSBiKTtcbiAgfVxuXG4gIC8qKiBXaGV0aGVyIGBpbWFnZWAgaGFzIG9uZSBzb3VyY2Ugb3ZlciBhbGwgaXRzIHNsaWNlcy4gKi9cbiAgaGFzUGxhbmVzU291cmNlKGltYWdlOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISFpbWFnZSAmJiAhIXRoaXMuaW1hZ2VzLmdldChpbWFnZSk/LnBsYW5lcztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgc291cmNlIGJlaGluZCBgc2xpY2VgIG9mIGBpbWFnZWAsIG9wZW5pbmcgaXQgaWYgbmVlZGVkLiBSZXNvbHZlcyBudWxsIHdoZW4gdGhlcmUgaXNcbiAgICogbm9uZSwgYW5kIHJlamVjdHMgd2hlbiBpdCBjYW5ub3QgYmUgb3BlbmVkLlxuICAgKi9cbiAgYXN5bmMgYmluZGluZyhpbWFnZTogc3RyaW5nIHwgdW5kZWZpbmVkLCBzbGljZTogbnVtYmVyKTogUHJvbWlzZTxSZWdpb25Tb3VyY2VCaW5kaW5nIHwgbnVsbD4ge1xuICAgIGNvbnN0IGVudHJ5ID0gaW1hZ2UgPyB0aGlzLmVudHJ5KGltYWdlLCBzbGljZSkgOiBudWxsO1xuICAgIGlmICghZW50cnkpIHJldHVybiBudWxsO1xuICAgIGNvbnN0IHNvdXJjZSA9IGF3YWl0IHRoaXMub3BlbkVudHJ5KGVudHJ5KTtcbiAgICByZXR1cm4geyBzb3VyY2UsIHBsYW5lOiBlbnRyeS5wbGFuZSA/PyBzbGljZSB9O1xuICB9XG5cbiAgLyoqIFRoZSBpZHMgdGFrZW4gZnJvbSBgc2xpY2VgJ3Mgc291cmNlLiAqL1xuICB0YWtlbihpbWFnZTogc3RyaW5nIHwgdW5kZWZpbmVkLCBzbGljZTogbnVtYmVyKTogUmVhZG9ubHlTZXQ8c3RyaW5nPiB7XG4gICAgcmV0dXJuIChpbWFnZSAmJiB0aGlzLmltYWdlcy5nZXQoaW1hZ2UpPy50YWtlbi5nZXQoc2xpY2UpKSB8fCBOT05FO1xuICB9XG5cbiAgLyoqIEV2ZXJ5IGlkIHRha2VuIGZyb20gYW55IHNsaWNlIG9mIGBpbWFnZWAgKGEgYCdwbGFuZXMnYCBzb3VyY2UncyBpZHMgYXJlIHVuaXF1ZSBhY3Jvc3MgdGhlbSkuICovXG4gIGFsbFRha2VuKGltYWdlOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgdGFrZW4gPSBpbWFnZSA/IHRoaXMuaW1hZ2VzLmdldChpbWFnZSk/LnRha2VuIDogdW5kZWZpbmVkO1xuICAgIHJldHVybiB0YWtlbiA/IEFycmF5LmZyb20odGFrZW4udmFsdWVzKCkpLmZsYXRNYXAoKGlkcykgPT4gQXJyYXkuZnJvbShpZHMpKSA6IFtdO1xuICB9XG5cbiAgLyoqIFRoZSBzbGljZXMgb2YgYGltYWdlYCB3aG9zZSBzb3VyY2Ugd2FzIGltcG9ydGVkIChzZWUge0BsaW5rIGF0dGFjaH0pLCBpbiBvcmRlci4gKi9cbiAgaW1wb3J0ZWRTbGljZXMoaW1hZ2U6IHN0cmluZyB8IHVuZGVmaW5lZCk6IG51bWJlcltdIHtcbiAgICBjb25zdCBpbXBvcnRlZCA9IGltYWdlID8gdGhpcy5pbWFnZXMuZ2V0KGltYWdlKT8uaW1wb3J0ZWQgOiB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIGltcG9ydGVkID8gQXJyYXkuZnJvbShpbXBvcnRlZCkuc29ydCgoYSwgYikgPT4gYSAtIGIpIDogW107XG4gIH1cblxuICAvKiogVGhlIHNsaWNlcyBvZiBgaW1hZ2VgIHdpdGggYW55dGhpbmcgdGFrZW4gZnJvbSB0aGVpciBzb3VyY2UuICovXG4gIHNsaWNlc1dpdGhUYWtlbihpbWFnZTogc3RyaW5nIHwgdW5kZWZpbmVkKTogbnVtYmVyW10ge1xuICAgIGNvbnN0IHRha2VuID0gaW1hZ2UgPyB0aGlzLmltYWdlcy5nZXQoaW1hZ2UpPy50YWtlbiA6IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gdGFrZW4gPyBBcnJheS5mcm9tKHRha2VuLmtleXMoKSkgOiBbXTtcbiAgfVxuXG4gIC8qKiBSZXBsYWNlIHRoZSBpZHMgdGFrZW4gZnJvbSBgc2xpY2VgJ3Mgc291cmNlIChjb3B5LW9uLXdyaXRlOiBgaWRzYCBpcyBrZXB0IGFzIGdpdmVuKS4gKi9cbiAgc2V0VGFrZW4oaW1hZ2U6IHN0cmluZyB8IHVuZGVmaW5lZCwgc2xpY2U6IG51bWJlciwgaWRzOiBSZWFkb25seVNldDxzdHJpbmc+KTogdm9pZCB7XG4gICAgaWYgKCFpbWFnZSkgcmV0dXJuO1xuICAgIGNvbnN0IHNvdXJjZXMgPSB0aGlzLmltYWdlcy5nZXQoaW1hZ2UpO1xuICAgIGlmICghc291cmNlcykgcmV0dXJuO1xuICAgIGlmIChpZHMuc2l6ZSkgc291cmNlcy50YWtlbi5zZXQoc2xpY2UsIGlkcyk7XG4gICAgZWxzZSBzb3VyY2VzLnRha2VuLmRlbGV0ZShzbGljZSk7XG4gIH1cblxuICBwcml2YXRlIGVudHJ5KGltYWdlOiBzdHJpbmcsIHNsaWNlOiBudW1iZXIpOiBFbnRyeSB8IG51bGwge1xuICAgIGNvbnN0IHNvdXJjZXMgPSB0aGlzLmltYWdlcy5nZXQoaW1hZ2UpO1xuICAgIHJldHVybiBzb3VyY2VzPy5wZXJTbGljZS5nZXQoc2xpY2UpID8/IHNvdXJjZXM/LnBsYW5lcyA/PyBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBpbWFnZVNvdXJjZXMoaW1hZ2U6IHN0cmluZyk6IEltYWdlU291cmNlcyB7XG4gICAgbGV0IHNvdXJjZXMgPSB0aGlzLmltYWdlcy5nZXQoaW1hZ2UpO1xuICAgIGlmICghc291cmNlcykge1xuICAgICAgc291cmNlcyA9IHsgcGxhbmVzOiBudWxsLCBwZXJTbGljZTogbmV3IE1hcCgpLCB0YWtlbjogbmV3IE1hcCgpLCBpbXBvcnRlZDogbmV3IFNldCgpIH07XG4gICAgICB0aGlzLmltYWdlcy5zZXQoaW1hZ2UsIHNvdXJjZXMpO1xuICAgIH1cbiAgICByZXR1cm4gc291cmNlcztcbiAgfVxuXG4gIHByaXZhdGUgb3BlbkVudHJ5KGVudHJ5OiBFbnRyeSk6IFByb21pc2U8UmVnaW9uU291cmNlPiB7XG4gICAgY29uc3QgYXQgPSB0aGlzLm9wZW5PcmRlci5pbmRleE9mKGVudHJ5KTtcbiAgICBpZiAoYXQgPj0gMCkgdGhpcy5vcGVuT3JkZXIuc3BsaWNlKGF0LCAxKTtcbiAgICB0aGlzLm9wZW5PcmRlci5wdXNoKGVudHJ5KTtcbiAgICBpZiAoIWVudHJ5LnNvdXJjZSkge1xuICAgICAgY29uc3Qgb3BlbmluZyA9IGVudHJ5Lm9wZW4oKTtcbiAgICAgIGVudHJ5LnNvdXJjZSA9IG9wZW5pbmc7XG4gICAgICBvcGVuaW5nLnRoZW4oXG4gICAgICAgIChzb3VyY2UpID0+IHtcbiAgICAgICAgICBpZiAoZW50cnkuc291cmNlID09PSBvcGVuaW5nKSBlbnRyeS5yZWFkeSA9IHNvdXJjZTtcbiAgICAgICAgICBlbHNlIHNvdXJjZS5kaXNwb3NlKCk7IC8vIGNsb3NlZCB3aGlsZSBpdCBvcGVuZWRcbiAgICAgICAgfSxcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIGlmIChlbnRyeS5zb3VyY2UgPT09IG9wZW5pbmcpIGVudHJ5LnNvdXJjZSA9IG51bGw7IC8vIHRyeSBhZ2FpbiBuZXh0IHRpbWVcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgfVxuICAgIHdoaWxlICh0aGlzLm9wZW5PcmRlci5sZW5ndGggPiBPUEVOX1JFR0lPTl9TT1VSQ0VTKSB7XG4gICAgICBjb25zdCBbb2xkZXN0XSA9IHRoaXMub3Blbk9yZGVyLnNwbGljZShcbiAgICAgICAgdGhpcy5vcGVuT3JkZXIuZmluZEluZGV4KChlKSA9PiBlICE9PSB0aGlzLnNob3duKSxcbiAgICAgICAgMSxcbiAgICAgICk7XG4gICAgICB0aGlzLmNsb3NlU291cmNlKG9sZGVzdCk7XG4gICAgfVxuICAgIHJldHVybiBlbnRyeS5zb3VyY2U7XG4gIH1cblxuICBwcml2YXRlIGNsb3NlKGVudHJ5OiBFbnRyeSk6IHZvaWQge1xuICAgIGNvbnN0IGF0ID0gdGhpcy5vcGVuT3JkZXIuaW5kZXhPZihlbnRyeSk7XG4gICAgaWYgKGF0ID49IDApIHRoaXMub3Blbk9yZGVyLnNwbGljZShhdCwgMSk7XG4gICAgdGhpcy5jbG9zZVNvdXJjZShlbnRyeSk7XG4gIH1cblxuICBwcml2YXRlIGNsb3NlU291cmNlKGVudHJ5OiBFbnRyeSk6IHZvaWQge1xuICAgIGVudHJ5LnJlYWR5Py5kaXNwb3NlKCk7XG4gICAgZW50cnkucmVhZHkgPSBudWxsO1xuICAgIGVudHJ5LnNvdXJjZSA9IG51bGw7XG4gIH1cbn1cbiJdfQ==
|