@jax-data-science/sci-image-visualizer 0.16.0 → 0.17.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/lib/contracts/display-types.mjs +2 -1
- package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +1 -1
- package/esm2022/lib/implementations/napari-js/napari-spatial-2d-scene.mjs +10 -8
- package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +25 -7
- package/esm2022/lib/implementations/napari-js/napari-spatial-3d-transcripts.mjs +269 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-encoding.mjs +11 -4
- package/esm2022/lib/implementations/napari-js/napari-spatial-tiles.mjs +6 -7
- package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +33 -8
- package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +6 -2
- package/esm2022/lib/implementations/napari-js/spatial-tiles/cell-layers.mjs +10 -6
- package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-layers.mjs +9 -5
- package/esm2022/lib/spatial/spatial-controls.facade.mjs +7 -4
- package/esm2022/lib/spatial/spatial-encoding.mjs +18 -1
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-charts.component.mjs +6 -2
- package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +7 -3
- package/esm2022/lib/spatial-controls/spatial-gene-style/spatial-gene-style.component.mjs +7 -3
- package/esm2022/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.mjs +21 -6
- package/esm2022/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.mjs +61 -8
- package/esm2022/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.mjs +3 -3
- package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CYsPzX3J.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DHrHO2ay.mjs} +533 -113
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DHrHO2ay.mjs.map +1 -0
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-DaZVXq1s.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-CKEUwNta.mjs} +2 -2
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-DaZVXq1s.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-CKEUwNta.mjs.map} +1 -1
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +1 -1
- package/lib/contracts/display-types.d.ts +9 -2
- package/lib/implementations/napari-js/napari-loading-state.d.ts +1 -1
- package/lib/implementations/napari-js/napari-spatial-2d-scene.d.ts +3 -3
- package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +2 -0
- package/lib/implementations/napari-js/napari-spatial-3d-transcripts.d.ts +62 -0
- package/lib/implementations/napari-js/napari-spatial-encoding.d.ts +9 -2
- package/lib/implementations/napari-js/napari-spatial-tiles.d.ts +5 -6
- package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +16 -3
- package/lib/implementations/napari-js/spatial-tiles/cell-layers.d.ts +1 -1
- package/lib/spatial/spatial-encoding.d.ts +10 -0
- package/lib/spatial-controls/spatial-controls.component.d.ts +2 -0
- package/lib/spatial-controls/spatial-gene-style/spatial-gene-style.component.d.ts +3 -1
- package/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.d.ts +7 -0
- package/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.d.ts +14 -3
- package/package.json +2 -2
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CYsPzX3J.mjs.map +0 -1
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { ALL_GENES } from '../../contracts/ports/spatial-data.port';
|
|
2
|
+
import { NO_CATEGORY, NO_OBSERVATION, isCategoricalColumn, } from '../../contracts/spatial-dataset.contract';
|
|
3
|
+
import { DEFAULT_CATEGORICAL_PALETTE, categoryColorsFor, parseHex } from '../../spatial/spatial-encoding';
|
|
4
|
+
import { allGeneShownBy, allGenesHidden } from '../../spatial/spatial-tile-merge';
|
|
5
|
+
import { cellTypeColumnFor } from '../../spatial/spatial-tiles';
|
|
6
|
+
import { clusterColorMap, clusterOfGene } from '../../spatial/transcript-grouping';
|
|
7
|
+
import { tilesInRect } from '../../spatial/lod';
|
|
8
|
+
import { Supersede } from '../../util/supersede';
|
|
9
|
+
/** Most transcripts drawn in the 3D view: past it, every k-th one is drawn (and the console says so). */
|
|
10
|
+
export const TRANSCRIPTS_3D_MAX = 2_000_000;
|
|
11
|
+
/** Most level-0 tiles read for the 3D view: a dataset needing more is too large to draw whole. */
|
|
12
|
+
export const TRANSCRIPTS_3D_MAX_TILES = 4096;
|
|
13
|
+
/** Tile reads in flight at once. */
|
|
14
|
+
const CONCURRENCY = 8;
|
|
15
|
+
/** A transcript's marker in the 3D view, in screen pixels at a transcript scale of 1. */
|
|
16
|
+
export const TRANSCRIPT_3D_BASE_SIZE = 2;
|
|
17
|
+
/** A transcript with no colour by cell type (in no cell, or a cell in no group), as the 2D markers. */
|
|
18
|
+
const UNASSIGNED_RGBA = [0.62, 0.62, 0.62, 0.55];
|
|
19
|
+
/** The genes a view draws in 3D, as the tile query takes them, or null when it draws none. */
|
|
20
|
+
export function transcripts3dGenes(dataset, view) {
|
|
21
|
+
if (view.transcriptMode === 'off')
|
|
22
|
+
return null;
|
|
23
|
+
if (view.transcriptAllGenes) {
|
|
24
|
+
if (allGenesHidden(view))
|
|
25
|
+
return null;
|
|
26
|
+
return { query: [ALL_GENES], allGenes: true };
|
|
27
|
+
}
|
|
28
|
+
const hidden = new Set(view.transcriptHiddenGenes);
|
|
29
|
+
const genes = view.transcriptGenes.filter((g) => !hidden.has(g));
|
|
30
|
+
return genes.length ? { query: genes, allGenes: false } : null;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Each loaded transcript's colour, packed RGBA, as the 2D markers colour them by gene: a gene's
|
|
34
|
+
* chosen colour, else the palette's by its slot (the selection's order, or with "All genes" the
|
|
35
|
+
* dataset's gene code).
|
|
36
|
+
*/
|
|
37
|
+
export function transcripts3dColors(view, names, gene, count) {
|
|
38
|
+
const n = names ? names.length : DEFAULT_CATEGORICAL_PALETTE.length;
|
|
39
|
+
const table = Array.from({ length: n }, (_g, i) => rgba01((names && view.transcriptGeneColors[names[i]]) ||
|
|
40
|
+
DEFAULT_CATEGORICAL_PALETTE[i % DEFAULT_CATEGORICAL_PALETTE.length]));
|
|
41
|
+
return packed(count, (i) => table[names ? gene[i] : gene[i] % n]);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* How the panel's "Colour by" applies in 3D, as it does to the 2D markers (`colorViewFor`): by
|
|
45
|
+
* cell type when the dataset has one (else by gene), by cluster for the selected genes (with "All
|
|
46
|
+
* genes" a cluster is its gene), by gene otherwise.
|
|
47
|
+
*/
|
|
48
|
+
export function transcripts3dColorBy(dataset, view, allGenes) {
|
|
49
|
+
const by = view.transcriptColorBy;
|
|
50
|
+
if (by === 'cellType')
|
|
51
|
+
return cellTypeColumnFor(dataset, view) ? 'cellType' : 'gene';
|
|
52
|
+
if (by === 'cluster' && !allGenes)
|
|
53
|
+
return 'cluster';
|
|
54
|
+
return 'gene';
|
|
55
|
+
}
|
|
56
|
+
/** The colours the cells' grouping gives its groups, by name (none without a grouping). */
|
|
57
|
+
async function cellGroupColors(dataset, view, port) {
|
|
58
|
+
const name = cellTypeColumnFor(dataset, view);
|
|
59
|
+
if (!name)
|
|
60
|
+
return null;
|
|
61
|
+
const column = await port.getColumn(name);
|
|
62
|
+
if (!isCategoricalColumn(column))
|
|
63
|
+
return null;
|
|
64
|
+
const hex = categoryColorsFor(name, column.meta, view.groupColors);
|
|
65
|
+
const byName = new Map(column.meta.categories.map((c, k) => [c, hex[k]]));
|
|
66
|
+
return { codes: column.codes, colors: hex.map(rgba01), byName };
|
|
67
|
+
}
|
|
68
|
+
/** `#rrggbb` as an opaque 0..1 RGBA. */
|
|
69
|
+
function rgba01(hex) {
|
|
70
|
+
const [r, g, b] = parseHex(hex);
|
|
71
|
+
return [r / 255, g / 255, b / 255, 1];
|
|
72
|
+
}
|
|
73
|
+
/** `count` colours packed RGBA, unassigned where `at` has none. */
|
|
74
|
+
function packed(count, at) {
|
|
75
|
+
const out = new Float32Array(count * 4);
|
|
76
|
+
for (let i = 0; i < count; i++)
|
|
77
|
+
out.set(at(i) ?? UNASSIGNED_RGBA, i * 4);
|
|
78
|
+
return out;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* The transcripts of the 3D spatial view: every molecule of the genes the Transcripts panel draws
|
|
82
|
+
* (its selected genes, or "All genes"), at its own x, y and z, in the cloud's box and Z stretch.
|
|
83
|
+
*
|
|
84
|
+
* The 2D view reads transcripts by level of detail for the camera; a 3D orbit has no such window,
|
|
85
|
+
* so this reads the whole level 0 once per gene selection (a few hundred thousand molecules for a
|
|
86
|
+
* MERFISH section) and only restyles after that. Drawn only for a dataset whose transcripts carry z.
|
|
87
|
+
*/
|
|
88
|
+
export class Spatial3dTranscripts {
|
|
89
|
+
constructor(viewer, begin) {
|
|
90
|
+
this.viewer = viewer;
|
|
91
|
+
this.begin = begin;
|
|
92
|
+
this.layer = null;
|
|
93
|
+
/** What {@link layer} was loaded from (dataset, genes, quality), and styled with. */
|
|
94
|
+
this.loadKey = null;
|
|
95
|
+
this.styleKey = null;
|
|
96
|
+
this.loaded = null;
|
|
97
|
+
this.loads = new Supersede();
|
|
98
|
+
}
|
|
99
|
+
/** The layer drawn, if any (for tests and the scene's Z stretch). */
|
|
100
|
+
get drawn() {
|
|
101
|
+
return this.layer;
|
|
102
|
+
}
|
|
103
|
+
/** Draw what `view` asks for, loading the molecules when the genes changed. */
|
|
104
|
+
async sync(dataset, view, port, frame) {
|
|
105
|
+
const meta = dataset.transcriptTiles;
|
|
106
|
+
const genes = meta?.hasZ && port?.getTranscriptTile ? transcripts3dGenes(dataset, view) : null;
|
|
107
|
+
if (!meta || !genes || !port) {
|
|
108
|
+
this.remove();
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (genes.allGenes && (meta.count ?? 0) > TRANSCRIPTS_3D_MAX) {
|
|
112
|
+
console.warn(`[napari-js] ${meta.count} transcripts are too many to draw in 3D: select genes to see theirs`);
|
|
113
|
+
this.remove();
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const quality = view.transcriptQuality === 'all' ? 'all' : 'high';
|
|
117
|
+
const loadKey = `${dataset.id}|${genes.query.join('\u0001')}|${quality}`;
|
|
118
|
+
if (loadKey !== this.loadKey) {
|
|
119
|
+
const task = this.loads.next();
|
|
120
|
+
const [x0, y0, x1, y1] = meta.bounds;
|
|
121
|
+
const keys = tilesInRect({ x0, y0, x1: x1 + 1e-6, y1: y1 + 1e-6 }, 0, meta.levels, meta.bounds);
|
|
122
|
+
if (keys.length > TRANSCRIPTS_3D_MAX_TILES) {
|
|
123
|
+
console.warn(`[napari-js] ${keys.length} transcript tiles are too many to read for the 3D view`);
|
|
124
|
+
this.remove();
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const end = this.begin('Transcripts');
|
|
128
|
+
let tiles;
|
|
129
|
+
try {
|
|
130
|
+
tiles = await pooled(keys, CONCURRENCY, (k) => port.getTranscriptTile(0, k.gx, k.gy, { genes: genes.query, quality }));
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
console.warn('[napari-js] transcripts for the 3D view could not be read', err);
|
|
134
|
+
// The panel asked for other transcripts than those drawn: take them down rather than leave
|
|
135
|
+
// the old selection up as if it were the new one; the next change reads again. Only the
|
|
136
|
+
// current load may: a superseded one must not tear down what a newer one drew.
|
|
137
|
+
if (task())
|
|
138
|
+
this.clearLayer();
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
finally {
|
|
142
|
+
end();
|
|
143
|
+
}
|
|
144
|
+
if (!task())
|
|
145
|
+
return;
|
|
146
|
+
this.loadKey = loadKey;
|
|
147
|
+
this.styleKey = null;
|
|
148
|
+
this.loaded = { tiles, names: genes.allGenes ? (meta.genes ?? null) : genes.query };
|
|
149
|
+
}
|
|
150
|
+
await this.draw(dataset, view, port, frame, genes.allGenes);
|
|
151
|
+
}
|
|
152
|
+
/** Follow the scene's Z stretch (nothing is re-uploaded). */
|
|
153
|
+
setZScale(s) {
|
|
154
|
+
if (this.layer)
|
|
155
|
+
this.layer.scale3d = [1, 1, s];
|
|
156
|
+
}
|
|
157
|
+
/** Take the layer down and forget what it showed. */
|
|
158
|
+
remove() {
|
|
159
|
+
this.loads.cancel();
|
|
160
|
+
this.clearLayer();
|
|
161
|
+
}
|
|
162
|
+
clearLayer() {
|
|
163
|
+
if (this.layer)
|
|
164
|
+
this.viewer.layers.remove(this.layer);
|
|
165
|
+
this.layer = null;
|
|
166
|
+
this.loadKey = null;
|
|
167
|
+
this.styleKey = null;
|
|
168
|
+
this.loaded = null;
|
|
169
|
+
}
|
|
170
|
+
async draw(dataset, view, port, frame, allGenes) {
|
|
171
|
+
const loaded = this.loaded;
|
|
172
|
+
if (!loaded)
|
|
173
|
+
return;
|
|
174
|
+
const by = transcripts3dColorBy(dataset, view, allGenes);
|
|
175
|
+
const styleKey = [
|
|
176
|
+
frame.origin.join(','),
|
|
177
|
+
by,
|
|
178
|
+
by === 'gene' ? JSON.stringify(view.transcriptGeneColors) : '',
|
|
179
|
+
by !== 'gene' ? `${cellTypeColumnFor(dataset, view)}|${JSON.stringify(view.groupColors)}` : '',
|
|
180
|
+
by === 'cluster' ? JSON.stringify(view.transcriptGeneGroups) : '',
|
|
181
|
+
allGenes ? view.transcriptAllGenesHidden.join(',') : '',
|
|
182
|
+
].join('|');
|
|
183
|
+
const size = TRANSCRIPT_3D_BASE_SIZE * (view.transcriptScale > 0 ? view.transcriptScale : 1);
|
|
184
|
+
if (this.layer && styleKey === this.styleKey) {
|
|
185
|
+
this.layer.size = size;
|
|
186
|
+
this.layer.opacity = view.transcriptOpacity;
|
|
187
|
+
this.layer.scale3d = [1, 1, frame.zScale];
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const { names } = loaded;
|
|
191
|
+
const shown = allGenes && names ? allGeneShownBy(view.transcriptAllGenesHidden) : null;
|
|
192
|
+
const keep = shown && names ? (g) => !!names[g] && shown(names[g]) : () => true;
|
|
193
|
+
const total = loaded.tiles.reduce((n, t) => n + t.count, 0);
|
|
194
|
+
const stride = Math.max(1, Math.ceil(total / TRANSCRIPTS_3D_MAX));
|
|
195
|
+
if (stride > 1)
|
|
196
|
+
console.warn(`[napari-js] drawing every ${stride}th of ${total} transcripts in 3D`);
|
|
197
|
+
const [ox, oy, oz] = frame.origin;
|
|
198
|
+
const positions = [];
|
|
199
|
+
const genes = [];
|
|
200
|
+
const cells = [];
|
|
201
|
+
let seen = 0;
|
|
202
|
+
for (const t of loaded.tiles) {
|
|
203
|
+
for (let i = 0; i < t.count; i++) {
|
|
204
|
+
if (!keep(t.gene[i]) || seen++ % stride)
|
|
205
|
+
continue;
|
|
206
|
+
positions.push(t.x[i] + ox, t.y[i] + oy, t.z[i] + oz);
|
|
207
|
+
genes.push(t.gene[i]);
|
|
208
|
+
cells.push(t.observation[i]);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
const count = genes.length;
|
|
212
|
+
let colors;
|
|
213
|
+
if (by === 'gene') {
|
|
214
|
+
colors = transcripts3dColors(view, names, Uint16Array.from(genes), count);
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
const groups = await cellGroupColors(dataset, view, port).catch((err) => {
|
|
218
|
+
console.warn('[napari-js] the cells grouping for the 3D transcripts could not be read', err);
|
|
219
|
+
return null;
|
|
220
|
+
});
|
|
221
|
+
// A newer draw (another style, or the layer taken down) won while the column loaded.
|
|
222
|
+
if (this.loaded !== loaded)
|
|
223
|
+
return;
|
|
224
|
+
if (by === 'cellType') {
|
|
225
|
+
colors = packed(count, (i) => {
|
|
226
|
+
const o = cells[i];
|
|
227
|
+
const code = !groups || o === NO_OBSERVATION ? NO_CATEGORY : groups.codes[o];
|
|
228
|
+
return code === NO_CATEGORY ? undefined : groups.colors[code];
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
// A cluster named like a group of the cells' grouping takes that group's colour, as in 2D.
|
|
233
|
+
const byCluster = clusterColorMap(view.transcriptGenes, view.transcriptGeneGroups, groups?.byName ?? new Map(), DEFAULT_CATEGORICAL_PALETTE);
|
|
234
|
+
const table = (names ?? []).map((gene) => {
|
|
235
|
+
const hex = byCluster.get(clusterOfGene(gene, view.transcriptGeneGroups));
|
|
236
|
+
return hex ? rgba01(hex) : undefined;
|
|
237
|
+
});
|
|
238
|
+
colors = packed(count, (i) => table[genes[i]]);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
if (this.layer)
|
|
242
|
+
this.viewer.layers.remove(this.layer);
|
|
243
|
+
this.layer = null;
|
|
244
|
+
this.styleKey = styleKey;
|
|
245
|
+
if (!count)
|
|
246
|
+
return;
|
|
247
|
+
this.layer = this.viewer.addPoints3D(Float32Array.from(positions), new Float32Array(count), {
|
|
248
|
+
name: 'transcripts',
|
|
249
|
+
size,
|
|
250
|
+
opacity: view.transcriptOpacity,
|
|
251
|
+
scale3d: [1, 1, frame.zScale],
|
|
252
|
+
colors,
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
/** `work` over `items`, at most `limit` at once, results in order. */
|
|
257
|
+
async function pooled(items, limit, work) {
|
|
258
|
+
const out = new Array(items.length);
|
|
259
|
+
let next = 0;
|
|
260
|
+
const run = async () => {
|
|
261
|
+
while (next < items.length) {
|
|
262
|
+
const i = next++;
|
|
263
|
+
out[i] = await work(items[i]);
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
await Promise.all(Array.from({ length: Math.min(limit, items.length) }, run));
|
|
267
|
+
return out;
|
|
268
|
+
}
|
|
269
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFwYXJpLXNwYXRpYWwtM2QtdHJhbnNjcmlwdHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2ltcGxlbWVudGF0aW9ucy9uYXBhcmktanMvbmFwYXJpLXNwYXRpYWwtM2QtdHJhbnNjcmlwdHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLFNBQVMsRUFBd0IsTUFBTSx5Q0FBeUMsQ0FBQztBQUUxRixPQUFPLEVBQ0wsV0FBVyxFQUNYLGNBQWMsRUFDZCxtQkFBbUIsR0FHcEIsTUFBTSwwQ0FBMEMsQ0FBQztBQUNsRCxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsaUJBQWlCLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDMUcsT0FBTyxFQUFFLGNBQWMsRUFBRSxjQUFjLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUNsRixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsZUFBZSxFQUFFLGFBQWEsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ25GLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFakQseUdBQXlHO0FBQ3pHLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLFNBQVMsQ0FBQztBQUM1QyxrR0FBa0c7QUFDbEcsTUFBTSxDQUFDLE1BQU0sd0JBQXdCLEdBQUcsSUFBSSxDQUFDO0FBQzdDLG9DQUFvQztBQUNwQyxNQUFNLFdBQVcsR0FBRyxDQUFDLENBQUM7QUFDdEIseUZBQXlGO0FBQ3pGLE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLENBQUMsQ0FBQztBQUN6Qyx1R0FBdUc7QUFDdkcsTUFBTSxlQUFlLEdBQUcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQVUsQ0FBQztBQVMxRCw4RkFBOEY7QUFDOUYsTUFBTSxVQUFVLGtCQUFrQixDQUNoQyxPQUF1QixFQUN2QixJQUFzQjtJQUV0QixJQUFJLElBQUksQ0FBQyxjQUFjLEtBQUssS0FBSztRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQy9DLElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDNUIsSUFBSSxjQUFjLENBQUMsSUFBSSxDQUFDO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFDdEMsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUNoRCxDQUFDO0lBQ0QsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUM7SUFDbkQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2pFLE9BQU8sS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0FBQ2pFLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLG1CQUFtQixDQUNqQyxJQUFzQixFQUN0QixLQUErQixFQUMvQixJQUFpQixFQUNqQixLQUFhO0lBRWIsTUFBTSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQywyQkFBMkIsQ0FBQyxNQUFNLENBQUM7SUFDcEUsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUNoRCxNQUFNLENBQ0osQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzVDLDJCQUEyQixDQUFDLENBQUMsR0FBRywyQkFBMkIsQ0FBQyxNQUFNLENBQUMsQ0FDdEUsQ0FDRixDQUFDO0lBQ0YsT0FBTyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3BFLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQixDQUNsQyxPQUF1QixFQUN2QixJQUFzQixFQUN0QixRQUFpQjtJQUVqQixNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUM7SUFDbEMsSUFBSSxFQUFFLEtBQUssVUFBVTtRQUFFLE9BQU8saUJBQWlCLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUNyRixJQUFJLEVBQUUsS0FBSyxTQUFTLElBQUksQ0FBQyxRQUFRO1FBQUUsT0FBTyxTQUFTLENBQUM7SUFDcEQsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVELDJGQUEyRjtBQUMzRixLQUFLLFVBQVUsZUFBZSxDQUM1QixPQUF1QixFQUN2QixJQUFzQixFQUN0QixJQUFxQjtJQUVyQixNQUFNLElBQUksR0FBRyxpQkFBaUIsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDOUMsSUFBSSxDQUFDLElBQUk7UUFBRSxPQUFPLElBQUksQ0FBQztJQUN2QixNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDMUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQztRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQzlDLE1BQU0sR0FBRyxHQUFHLGlCQUFpQixDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUNuRSxNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQVUsQ0FBQyxDQUFDLENBQUM7SUFDbkYsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDO0FBQ2xFLENBQUM7QUFFRCx3Q0FBd0M7QUFDeEMsU0FBUyxNQUFNLENBQUMsR0FBVztJQUN6QixNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDaEMsT0FBTyxDQUFDLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ3hDLENBQUM7QUFFRCxtRUFBbUU7QUFDbkUsU0FBUyxNQUFNLENBQUMsS0FBYSxFQUFFLEVBQWdEO0lBQzdFLE1BQU0sR0FBRyxHQUFHLElBQUksWUFBWSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQztJQUN4QyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxFQUFFLENBQUMsRUFBRTtRQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLGVBQWUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDekUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sT0FBTyxvQkFBb0I7SUFRL0IsWUFDbUIsTUFBYyxFQUNkLEtBQTJDO1FBRDNDLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDZCxVQUFLLEdBQUwsS0FBSyxDQUFzQztRQVR0RCxVQUFLLEdBQXlCLElBQUksQ0FBQztRQUMzQyxxRkFBcUY7UUFDN0UsWUFBTyxHQUFrQixJQUFJLENBQUM7UUFDOUIsYUFBUSxHQUFrQixJQUFJLENBQUM7UUFDL0IsV0FBTSxHQUErRSxJQUFJLENBQUM7UUFDakYsVUFBSyxHQUFHLElBQUksU0FBUyxFQUFFLENBQUM7SUFLdEMsQ0FBQztJQUVKLHFFQUFxRTtJQUNyRSxJQUFJLEtBQUs7UUFDUCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7SUFDcEIsQ0FBQztJQUVELCtFQUErRTtJQUMvRSxLQUFLLENBQUMsSUFBSSxDQUNSLE9BQXVCLEVBQ3ZCLElBQXNCLEVBQ3RCLElBQTRCLEVBQzVCLEtBQXlCO1FBRXpCLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUM7UUFDckMsTUFBTSxLQUFLLEdBQUcsSUFBSSxFQUFFLElBQUksSUFBSSxJQUFJLEVBQUUsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQy9GLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUM3QixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDZCxPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksS0FBSyxDQUFDLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLEdBQUcsa0JBQWtCLEVBQUUsQ0FBQztZQUM3RCxPQUFPLENBQUMsSUFBSSxDQUFDLGVBQWUsSUFBSSxDQUFDLEtBQUsscUVBQXFFLENBQUMsQ0FBQztZQUM3RyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDZCxPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO1FBQ2xFLE1BQU0sT0FBTyxHQUFHLEdBQUcsT0FBTyxDQUFDLEVBQUUsSUFBSSxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQUN6RSxJQUFJLE9BQU8sS0FBSyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDN0IsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUMvQixNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztZQUNyQyxNQUFNLElBQUksR0FBRyxXQUFXLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsSUFBSSxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsSUFBSSxFQUFFLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ2hHLElBQUksSUFBSSxDQUFDLE1BQU0sR0FBRyx3QkFBd0IsRUFBRSxDQUFDO2dCQUMzQyxPQUFPLENBQUMsSUFBSSxDQUFDLGVBQWUsSUFBSSxDQUFDLE1BQU0sd0RBQXdELENBQUMsQ0FBQztnQkFDakcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUNkLE9BQU87WUFDVCxDQUFDO1lBQ0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUN0QyxJQUFJLEtBQThCLENBQUM7WUFDbkMsSUFBSSxDQUFDO2dCQUNILEtBQUssR0FBRyxNQUFNLE1BQU0sQ0FBQyxJQUFJLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FDNUMsSUFBSSxDQUFDLGlCQUFrQixDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUN4RSxDQUFDO1lBQ0osQ0FBQztZQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7Z0JBQ2IsT0FBTyxDQUFDLElBQUksQ0FBQywyREFBMkQsRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDL0UsMkZBQTJGO2dCQUMzRix3RkFBd0Y7Z0JBQ3hGLCtFQUErRTtnQkFDL0UsSUFBSSxJQUFJLEVBQUU7b0JBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO2dCQUM5QixPQUFPO1lBQ1QsQ0FBQztvQkFBUyxDQUFDO2dCQUNULEdBQUcsRUFBRSxDQUFDO1lBQ1IsQ0FBQztZQUNELElBQUksQ0FBQyxJQUFJLEVBQUU7Z0JBQUUsT0FBTztZQUNwQixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztZQUN2QixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztZQUNyQixJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUN0RixDQUFDO1FBQ0QsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDOUQsQ0FBQztJQUVELDZEQUE2RDtJQUM3RCxTQUFTLENBQUMsQ0FBUztRQUNqQixJQUFJLElBQUksQ0FBQyxLQUFLO1lBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFFRCxxREFBcUQ7SUFDckQsTUFBTTtRQUNKLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ3BCLENBQUM7SUFFTyxVQUFVO1FBQ2hCLElBQUksSUFBSSxDQUFDLEtBQUs7WUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3RELElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1FBQ2xCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO1FBQ3BCLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO0lBQ3JCLENBQUM7SUFFTyxLQUFLLENBQUMsSUFBSSxDQUNoQixPQUF1QixFQUN2QixJQUFzQixFQUN0QixJQUFxQixFQUNyQixLQUF5QixFQUN6QixRQUFpQjtRQUVqQixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQzNCLElBQUksQ0FBQyxNQUFNO1lBQUUsT0FBTztRQUNwQixNQUFNLEVBQUUsR0FBRyxvQkFBb0IsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ3pELE1BQU0sUUFBUSxHQUFHO1lBQ2YsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO1lBQ3RCLEVBQUU7WUFDRixFQUFFLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQzlELEVBQUUsS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsaUJBQWlCLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDOUYsRUFBRSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNqRSxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7U0FDeEQsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDWixNQUFNLElBQUksR0FBRyx1QkFBdUIsR0FBRyxDQUFDLElBQUksQ0FBQyxlQUFlLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3RixJQUFJLElBQUksQ0FBQyxLQUFLLElBQUksUUFBUSxLQUFLLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUM3QyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7WUFDdkIsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDO1lBQzVDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDMUMsT0FBTztRQUNULENBQUM7UUFDRCxNQUFNLEVBQUUsS0FBSyxFQUFFLEdBQUcsTUFBTSxDQUFDO1FBQ3pCLE1BQU0sS0FBSyxHQUFHLFFBQVEsSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ3ZGLE1BQU0sSUFBSSxHQUFHLEtBQUssSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDO1FBQ3hGLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDNUQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsa0JBQWtCLENBQUMsQ0FBQyxDQUFDO1FBQ2xFLElBQUksTUFBTSxHQUFHLENBQUM7WUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLDZCQUE2QixNQUFNLFNBQVMsS0FBSyxvQkFBb0IsQ0FBQyxDQUFDO1FBRXBHLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUM7UUFDbEMsTUFBTSxTQUFTLEdBQWEsRUFBRSxDQUFDO1FBQy9CLE1BQU0sS0FBSyxHQUFhLEVBQUUsQ0FBQztRQUMzQixNQUFNLEtBQUssR0FBYSxFQUFFLENBQUM7UUFDM0IsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDO1FBQ2IsS0FBSyxNQUFNLENBQUMsSUFBSSxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDN0IsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQkFDakMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxFQUFFLEdBQUcsTUFBTTtvQkFBRSxTQUFTO2dCQUNsRCxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7Z0JBQ3RELEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN0QixLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMvQixDQUFDO1FBQ0gsQ0FBQztRQUNELE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUM7UUFDM0IsSUFBSSxNQUFvQixDQUFDO1FBQ3pCLElBQUksRUFBRSxLQUFLLE1BQU0sRUFBRSxDQUFDO1lBQ2xCLE1BQU0sR0FBRyxtQkFBbUIsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDNUUsQ0FBQzthQUFNLENBQUM7WUFDTixNQUFNLE1BQU0sR0FBRyxNQUFNLGVBQWUsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO2dCQUN0RSxPQUFPLENBQUMsSUFBSSxDQUFDLHlFQUF5RSxFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUM3RixPQUFPLElBQUksQ0FBQztZQUNkLENBQUMsQ0FBQyxDQUFDO1lBQ0gscUZBQXFGO1lBQ3JGLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxNQUFNO2dCQUFFLE9BQU87WUFDbkMsSUFBSSxFQUFFLEtBQUssVUFBVSxFQUFFLENBQUM7Z0JBQ3RCLE1BQU0sR0FBRyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUU7b0JBQzNCLE1BQU0sQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDbkIsTUFBTSxJQUFJLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQyxLQUFLLGNBQWMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUM3RSxPQUFPLElBQUksS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsTUFBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDakUsQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sMkZBQTJGO2dCQUMzRixNQUFNLFNBQVMsR0FBRyxlQUFlLENBQy9CLElBQUksQ0FBQyxlQUFlLEVBQ3BCLElBQUksQ0FBQyxvQkFBb0IsRUFDekIsTUFBTSxFQUFFLE1BQU0sSUFBSSxJQUFJLEdBQUcsRUFBRSxFQUMzQiwyQkFBMkIsQ0FDNUIsQ0FBQztnQkFDRixNQUFNLEtBQUssR0FBRyxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtvQkFDdkMsTUFBTSxHQUFHLEdBQUcsU0FBUyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLENBQUM7b0JBQzFFLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztnQkFDdkMsQ0FBQyxDQUFDLENBQUM7Z0JBQ0gsTUFBTSxHQUFHLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2pELENBQUM7UUFDSCxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsS0FBSztZQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDdEQsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7UUFDbEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFDekIsSUFBSSxDQUFDLEtBQUs7WUFBRSxPQUFPO1FBQ25CLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxJQUFJLFlBQVksQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUMxRixJQUFJLEVBQUUsYUFBYTtZQUNuQixJQUFJO1lBQ0osT0FBTyxFQUFFLElBQUksQ0FBQyxpQkFBaUI7WUFDL0IsT0FBTyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDO1lBQzdCLE1BQU07U0FDUCxDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0Y7QUFFRCxzRUFBc0U7QUFDdEUsS0FBSyxVQUFVLE1BQU0sQ0FBTyxLQUFtQixFQUFFLEtBQWEsRUFBRSxJQUE2QjtJQUMzRixNQUFNLEdBQUcsR0FBRyxJQUFJLEtBQUssQ0FBSSxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDdkMsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDO0lBQ2IsTUFBTSxHQUFHLEdBQUcsS0FBSyxJQUFJLEVBQUU7UUFDckIsT0FBTyxJQUFJLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzNCLE1BQU0sQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDO1lBQ2pCLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNoQyxDQUFDO0lBQ0gsQ0FBQyxDQUFDO0lBQ0YsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUM5RSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IFBvaW50czNETGF5ZXIsIFZpZXdlciB9IGZyb20gJ25hcGFyaS1qcyc7XG5cbmltcG9ydCB7IEFMTF9HRU5FUywgdHlwZSBTcGF0aWFsRGF0YVBvcnQgfSBmcm9tICcuLi8uLi9jb250cmFjdHMvcG9ydHMvc3BhdGlhbC1kYXRhLnBvcnQnO1xuaW1wb3J0IHR5cGUgeyBTcGF0aWFsVmlld1N0YXRlIH0gZnJvbSAnLi4vLi4vY29udHJhY3RzL2Rpc3BsYXktdHlwZXMnO1xuaW1wb3J0IHtcbiAgTk9fQ0FURUdPUlksXG4gIE5PX09CU0VSVkFUSU9OLFxuICBpc0NhdGVnb3JpY2FsQ29sdW1uLFxuICB0eXBlIFNwYXRpYWxEYXRhc2V0LFxuICB0eXBlIFNwYXRpYWxUcmFuc2NyaXB0VGlsZSxcbn0gZnJvbSAnLi4vLi4vY29udHJhY3RzL3NwYXRpYWwtZGF0YXNldC5jb250cmFjdCc7XG5pbXBvcnQgeyBERUZBVUxUX0NBVEVHT1JJQ0FMX1BBTEVUVEUsIGNhdGVnb3J5Q29sb3JzRm9yLCBwYXJzZUhleCB9IGZyb20gJy4uLy4uL3NwYXRpYWwvc3BhdGlhbC1lbmNvZGluZyc7XG5pbXBvcnQgeyBhbGxHZW5lU2hvd25CeSwgYWxsR2VuZXNIaWRkZW4gfSBmcm9tICcuLi8uLi9zcGF0aWFsL3NwYXRpYWwtdGlsZS1tZXJnZSc7XG5pbXBvcnQgeyBjZWxsVHlwZUNvbHVtbkZvciB9IGZyb20gJy4uLy4uL3NwYXRpYWwvc3BhdGlhbC10aWxlcyc7XG5pbXBvcnQgeyBjbHVzdGVyQ29sb3JNYXAsIGNsdXN0ZXJPZkdlbmUgfSBmcm9tICcuLi8uLi9zcGF0aWFsL3RyYW5zY3JpcHQtZ3JvdXBpbmcnO1xuaW1wb3J0IHsgdGlsZXNJblJlY3QgfSBmcm9tICcuLi8uLi9zcGF0aWFsL2xvZCc7XG5pbXBvcnQgeyBTdXBlcnNlZGUgfSBmcm9tICcuLi8uLi91dGlsL3N1cGVyc2VkZSc7XG5cbi8qKiBNb3N0IHRyYW5zY3JpcHRzIGRyYXduIGluIHRoZSAzRCB2aWV3OiBwYXN0IGl0LCBldmVyeSBrLXRoIG9uZSBpcyBkcmF3biAoYW5kIHRoZSBjb25zb2xlIHNheXMgc28pLiAqL1xuZXhwb3J0IGNvbnN0IFRSQU5TQ1JJUFRTXzNEX01BWCA9IDJfMDAwXzAwMDtcbi8qKiBNb3N0IGxldmVsLTAgdGlsZXMgcmVhZCBmb3IgdGhlIDNEIHZpZXc6IGEgZGF0YXNldCBuZWVkaW5nIG1vcmUgaXMgdG9vIGxhcmdlIHRvIGRyYXcgd2hvbGUuICovXG5leHBvcnQgY29uc3QgVFJBTlNDUklQVFNfM0RfTUFYX1RJTEVTID0gNDA5Njtcbi8qKiBUaWxlIHJlYWRzIGluIGZsaWdodCBhdCBvbmNlLiAqL1xuY29uc3QgQ09OQ1VSUkVOQ1kgPSA4O1xuLyoqIEEgdHJhbnNjcmlwdCdzIG1hcmtlciBpbiB0aGUgM0QgdmlldywgaW4gc2NyZWVuIHBpeGVscyBhdCBhIHRyYW5zY3JpcHQgc2NhbGUgb2YgMS4gKi9cbmV4cG9ydCBjb25zdCBUUkFOU0NSSVBUXzNEX0JBU0VfU0laRSA9IDI7XG4vKiogQSB0cmFuc2NyaXB0IHdpdGggbm8gY29sb3VyIGJ5IGNlbGwgdHlwZSAoaW4gbm8gY2VsbCwgb3IgYSBjZWxsIGluIG5vIGdyb3VwKSwgYXMgdGhlIDJEIG1hcmtlcnMuICovXG5jb25zdCBVTkFTU0lHTkVEX1JHQkEgPSBbMC42MiwgMC42MiwgMC42MiwgMC41NV0gYXMgY29uc3Q7XG5cbi8qKiBXaGF0IHRoZSAzRCB0cmFuc2NyaXB0cyBuZWVkIG9mIHRoZSBzY2VuZTogd2hlcmUgdGhlIGNsb3VkIHNpdHMgYW5kIGhvdyBaIGlzIHN0cmV0Y2hlZC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVHJhbnNjcmlwdHMzZEZyYW1lIHtcbiAgLyoqIE9mZnNldCBhcHBsaWVkIHRvIG9ic2VydmF0aW9uIGNvb3JkaW5hdGVzIHRvIHNpdCB0aGVtIGluIHRoZSBzY2VuZSdzIGJveC4gKi9cbiAgb3JpZ2luOiByZWFkb25seSBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gIHpTY2FsZTogbnVtYmVyO1xufVxuXG4vKiogVGhlIGdlbmVzIGEgdmlldyBkcmF3cyBpbiAzRCwgYXMgdGhlIHRpbGUgcXVlcnkgdGFrZXMgdGhlbSwgb3IgbnVsbCB3aGVuIGl0IGRyYXdzIG5vbmUuICovXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNjcmlwdHMzZEdlbmVzKFxuICBkYXRhc2V0OiBTcGF0aWFsRGF0YXNldCxcbiAgdmlldzogU3BhdGlhbFZpZXdTdGF0ZSxcbik6IHsgcXVlcnk6IHN0cmluZ1tdOyBhbGxHZW5lczogYm9vbGVhbiB9IHwgbnVsbCB7XG4gIGlmICh2aWV3LnRyYW5zY3JpcHRNb2RlID09PSAnb2ZmJykgcmV0dXJuIG51bGw7XG4gIGlmICh2aWV3LnRyYW5zY3JpcHRBbGxHZW5lcykge1xuICAgIGlmIChhbGxHZW5lc0hpZGRlbih2aWV3KSkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHsgcXVlcnk6IFtBTExfR0VORVNdLCBhbGxHZW5lczogdHJ1ZSB9O1xuICB9XG4gIGNvbnN0IGhpZGRlbiA9IG5ldyBTZXQodmlldy50cmFuc2NyaXB0SGlkZGVuR2VuZXMpO1xuICBjb25zdCBnZW5lcyA9IHZpZXcudHJhbnNjcmlwdEdlbmVzLmZpbHRlcigoZykgPT4gIWhpZGRlbi5oYXMoZykpO1xuICByZXR1cm4gZ2VuZXMubGVuZ3RoID8geyBxdWVyeTogZ2VuZXMsIGFsbEdlbmVzOiBmYWxzZSB9IDogbnVsbDtcbn1cblxuLyoqXG4gKiBFYWNoIGxvYWRlZCB0cmFuc2NyaXB0J3MgY29sb3VyLCBwYWNrZWQgUkdCQSwgYXMgdGhlIDJEIG1hcmtlcnMgY29sb3VyIHRoZW0gYnkgZ2VuZTogYSBnZW5lJ3NcbiAqIGNob3NlbiBjb2xvdXIsIGVsc2UgdGhlIHBhbGV0dGUncyBieSBpdHMgc2xvdCAodGhlIHNlbGVjdGlvbidzIG9yZGVyLCBvciB3aXRoIFwiQWxsIGdlbmVzXCIgdGhlXG4gKiBkYXRhc2V0J3MgZ2VuZSBjb2RlKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zY3JpcHRzM2RDb2xvcnMoXG4gIHZpZXc6IFNwYXRpYWxWaWV3U3RhdGUsXG4gIG5hbWVzOiByZWFkb25seSBzdHJpbmdbXSB8IG51bGwsXG4gIGdlbmU6IFVpbnQxNkFycmF5LFxuICBjb3VudDogbnVtYmVyLFxuKTogRmxvYXQzMkFycmF5IHtcbiAgY29uc3QgbiA9IG5hbWVzID8gbmFtZXMubGVuZ3RoIDogREVGQVVMVF9DQVRFR09SSUNBTF9QQUxFVFRFLmxlbmd0aDtcbiAgY29uc3QgdGFibGUgPSBBcnJheS5mcm9tKHsgbGVuZ3RoOiBuIH0sIChfZywgaSkgPT5cbiAgICByZ2JhMDEoXG4gICAgICAobmFtZXMgJiYgdmlldy50cmFuc2NyaXB0R2VuZUNvbG9yc1tuYW1lc1tpXV0pIHx8XG4gICAgICAgIERFRkFVTFRfQ0FURUdPUklDQUxfUEFMRVRURVtpICUgREVGQVVMVF9DQVRFR09SSUNBTF9QQUxFVFRFLmxlbmd0aF0sXG4gICAgKSxcbiAgKTtcbiAgcmV0dXJuIHBhY2tlZChjb3VudCwgKGkpID0+IHRhYmxlW25hbWVzID8gZ2VuZVtpXSA6IGdlbmVbaV0gJSBuXSk7XG59XG5cbi8qKlxuICogSG93IHRoZSBwYW5lbCdzIFwiQ29sb3VyIGJ5XCIgYXBwbGllcyBpbiAzRCwgYXMgaXQgZG9lcyB0byB0aGUgMkQgbWFya2VycyAoYGNvbG9yVmlld0ZvcmApOiBieVxuICogY2VsbCB0eXBlIHdoZW4gdGhlIGRhdGFzZXQgaGFzIG9uZSAoZWxzZSBieSBnZW5lKSwgYnkgY2x1c3RlciBmb3IgdGhlIHNlbGVjdGVkIGdlbmVzICh3aXRoIFwiQWxsXG4gKiBnZW5lc1wiIGEgY2x1c3RlciBpcyBpdHMgZ2VuZSksIGJ5IGdlbmUgb3RoZXJ3aXNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNjcmlwdHMzZENvbG9yQnkoXG4gIGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0LFxuICB2aWV3OiBTcGF0aWFsVmlld1N0YXRlLFxuICBhbGxHZW5lczogYm9vbGVhbixcbik6ICdjZWxsVHlwZScgfCAnY2x1c3RlcicgfCAnZ2VuZScge1xuICBjb25zdCBieSA9IHZpZXcudHJhbnNjcmlwdENvbG9yQnk7XG4gIGlmIChieSA9PT0gJ2NlbGxUeXBlJykgcmV0dXJuIGNlbGxUeXBlQ29sdW1uRm9yKGRhdGFzZXQsIHZpZXcpID8gJ2NlbGxUeXBlJyA6ICdnZW5lJztcbiAgaWYgKGJ5ID09PSAnY2x1c3RlcicgJiYgIWFsbEdlbmVzKSByZXR1cm4gJ2NsdXN0ZXInO1xuICByZXR1cm4gJ2dlbmUnO1xufVxuXG4vKiogVGhlIGNvbG91cnMgdGhlIGNlbGxzJyBncm91cGluZyBnaXZlcyBpdHMgZ3JvdXBzLCBieSBuYW1lIChub25lIHdpdGhvdXQgYSBncm91cGluZykuICovXG5hc3luYyBmdW5jdGlvbiBjZWxsR3JvdXBDb2xvcnMoXG4gIGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0LFxuICB2aWV3OiBTcGF0aWFsVmlld1N0YXRlLFxuICBwb3J0OiBTcGF0aWFsRGF0YVBvcnQsXG4pOiBQcm9taXNlPHsgY29kZXM6IFVpbnQxNkFycmF5OyBjb2xvcnM6IChyZWFkb25seSBudW1iZXJbXSlbXTsgYnlOYW1lOiBNYXA8c3RyaW5nLCBzdHJpbmc+IH0gfCBudWxsPiB7XG4gIGNvbnN0IG5hbWUgPSBjZWxsVHlwZUNvbHVtbkZvcihkYXRhc2V0LCB2aWV3KTtcbiAgaWYgKCFuYW1lKSByZXR1cm4gbnVsbDtcbiAgY29uc3QgY29sdW1uID0gYXdhaXQgcG9ydC5nZXRDb2x1bW4obmFtZSk7XG4gIGlmICghaXNDYXRlZ29yaWNhbENvbHVtbihjb2x1bW4pKSByZXR1cm4gbnVsbDtcbiAgY29uc3QgaGV4ID0gY2F0ZWdvcnlDb2xvcnNGb3IobmFtZSwgY29sdW1uLm1ldGEsIHZpZXcuZ3JvdXBDb2xvcnMpO1xuICBjb25zdCBieU5hbWUgPSBuZXcgTWFwKGNvbHVtbi5tZXRhLmNhdGVnb3JpZXMubWFwKChjLCBrKSA9PiBbYywgaGV4W2tdXSBhcyBjb25zdCkpO1xuICByZXR1cm4geyBjb2RlczogY29sdW1uLmNvZGVzLCBjb2xvcnM6IGhleC5tYXAocmdiYTAxKSwgYnlOYW1lIH07XG59XG5cbi8qKiBgI3JyZ2diYmAgYXMgYW4gb3BhcXVlIDAuLjEgUkdCQS4gKi9cbmZ1bmN0aW9uIHJnYmEwMShoZXg6IHN0cmluZyk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgY29uc3QgW3IsIGcsIGJdID0gcGFyc2VIZXgoaGV4KTtcbiAgcmV0dXJuIFtyIC8gMjU1LCBnIC8gMjU1LCBiIC8gMjU1LCAxXTtcbn1cblxuLyoqIGBjb3VudGAgY29sb3VycyBwYWNrZWQgUkdCQSwgdW5hc3NpZ25lZCB3aGVyZSBgYXRgIGhhcyBub25lLiAqL1xuZnVuY3Rpb24gcGFja2VkKGNvdW50OiBudW1iZXIsIGF0OiAoaTogbnVtYmVyKSA9PiByZWFkb25seSBudW1iZXJbXSB8IHVuZGVmaW5lZCk6IEZsb2F0MzJBcnJheSB7XG4gIGNvbnN0IG91dCA9IG5ldyBGbG9hdDMyQXJyYXkoY291bnQgKiA0KTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSBvdXQuc2V0KGF0KGkpID8/IFVOQVNTSUdORURfUkdCQSwgaSAqIDQpO1xuICByZXR1cm4gb3V0O1xufVxuXG4vKipcbiAqIFRoZSB0cmFuc2NyaXB0cyBvZiB0aGUgM0Qgc3BhdGlhbCB2aWV3OiBldmVyeSBtb2xlY3VsZSBvZiB0aGUgZ2VuZXMgdGhlIFRyYW5zY3JpcHRzIHBhbmVsIGRyYXdzXG4gKiAoaXRzIHNlbGVjdGVkIGdlbmVzLCBvciBcIkFsbCBnZW5lc1wiKSwgYXQgaXRzIG93biB4LCB5IGFuZCB6LCBpbiB0aGUgY2xvdWQncyBib3ggYW5kIFogc3RyZXRjaC5cbiAqXG4gKiBUaGUgMkQgdmlldyByZWFkcyB0cmFuc2NyaXB0cyBieSBsZXZlbCBvZiBkZXRhaWwgZm9yIHRoZSBjYW1lcmE7IGEgM0Qgb3JiaXQgaGFzIG5vIHN1Y2ggd2luZG93LFxuICogc28gdGhpcyByZWFkcyB0aGUgd2hvbGUgbGV2ZWwgMCBvbmNlIHBlciBnZW5lIHNlbGVjdGlvbiAoYSBmZXcgaHVuZHJlZCB0aG91c2FuZCBtb2xlY3VsZXMgZm9yIGFcbiAqIE1FUkZJU0ggc2VjdGlvbikgYW5kIG9ubHkgcmVzdHlsZXMgYWZ0ZXIgdGhhdC4gRHJhd24gb25seSBmb3IgYSBkYXRhc2V0IHdob3NlIHRyYW5zY3JpcHRzIGNhcnJ5IHouXG4gKi9cbmV4cG9ydCBjbGFzcyBTcGF0aWFsM2RUcmFuc2NyaXB0cyB7XG4gIHByaXZhdGUgbGF5ZXI6IFBvaW50czNETGF5ZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqIFdoYXQge0BsaW5rIGxheWVyfSB3YXMgbG9hZGVkIGZyb20gKGRhdGFzZXQsIGdlbmVzLCBxdWFsaXR5KSwgYW5kIHN0eWxlZCB3aXRoLiAqL1xuICBwcml2YXRlIGxvYWRLZXk6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHN0eWxlS2V5OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBsb2FkZWQ6IHsgdGlsZXM6IFNwYXRpYWxUcmFuc2NyaXB0VGlsZVtdOyBuYW1lczogcmVhZG9ubHkgc3RyaW5nW10gfCBudWxsIH0gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSByZWFkb25seSBsb2FkcyA9IG5ldyBTdXBlcnNlZGUoKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IHZpZXdlcjogVmlld2VyLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYmVnaW46IChsYWJlbDogJ1RyYW5zY3JpcHRzJykgPT4gKCkgPT4gdm9pZCxcbiAgKSB7fVxuXG4gIC8qKiBUaGUgbGF5ZXIgZHJhd24sIGlmIGFueSAoZm9yIHRlc3RzIGFuZCB0aGUgc2NlbmUncyBaIHN0cmV0Y2gpLiAqL1xuICBnZXQgZHJhd24oKTogUG9pbnRzM0RMYXllciB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLmxheWVyO1xuICB9XG5cbiAgLyoqIERyYXcgd2hhdCBgdmlld2AgYXNrcyBmb3IsIGxvYWRpbmcgdGhlIG1vbGVjdWxlcyB3aGVuIHRoZSBnZW5lcyBjaGFuZ2VkLiAqL1xuICBhc3luYyBzeW5jKFxuICAgIGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0LFxuICAgIHZpZXc6IFNwYXRpYWxWaWV3U3RhdGUsXG4gICAgcG9ydDogU3BhdGlhbERhdGFQb3J0IHwgbnVsbCxcbiAgICBmcmFtZTogVHJhbnNjcmlwdHMzZEZyYW1lLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBtZXRhID0gZGF0YXNldC50cmFuc2NyaXB0VGlsZXM7XG4gICAgY29uc3QgZ2VuZXMgPSBtZXRhPy5oYXNaICYmIHBvcnQ/LmdldFRyYW5zY3JpcHRUaWxlID8gdHJhbnNjcmlwdHMzZEdlbmVzKGRhdGFzZXQsIHZpZXcpIDogbnVsbDtcbiAgICBpZiAoIW1ldGEgfHwgIWdlbmVzIHx8ICFwb3J0KSB7XG4gICAgICB0aGlzLnJlbW92ZSgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoZ2VuZXMuYWxsR2VuZXMgJiYgKG1ldGEuY291bnQgPz8gMCkgPiBUUkFOU0NSSVBUU18zRF9NQVgpIHtcbiAgICAgIGNvbnNvbGUud2FybihgW25hcGFyaS1qc10gJHttZXRhLmNvdW50fSB0cmFuc2NyaXB0cyBhcmUgdG9vIG1hbnkgdG8gZHJhdyBpbiAzRDogc2VsZWN0IGdlbmVzIHRvIHNlZSB0aGVpcnNgKTtcbiAgICAgIHRoaXMucmVtb3ZlKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHF1YWxpdHkgPSB2aWV3LnRyYW5zY3JpcHRRdWFsaXR5ID09PSAnYWxsJyA/ICdhbGwnIDogJ2hpZ2gnO1xuICAgIGNvbnN0IGxvYWRLZXkgPSBgJHtkYXRhc2V0LmlkfXwke2dlbmVzLnF1ZXJ5LmpvaW4oJ1xcdTAwMDEnKX18JHtxdWFsaXR5fWA7XG4gICAgaWYgKGxvYWRLZXkgIT09IHRoaXMubG9hZEtleSkge1xuICAgICAgY29uc3QgdGFzayA9IHRoaXMubG9hZHMubmV4dCgpO1xuICAgICAgY29uc3QgW3gwLCB5MCwgeDEsIHkxXSA9IG1ldGEuYm91bmRzO1xuICAgICAgY29uc3Qga2V5cyA9IHRpbGVzSW5SZWN0KHsgeDAsIHkwLCB4MTogeDEgKyAxZS02LCB5MTogeTEgKyAxZS02IH0sIDAsIG1ldGEubGV2ZWxzLCBtZXRhLmJvdW5kcyk7XG4gICAgICBpZiAoa2V5cy5sZW5ndGggPiBUUkFOU0NSSVBUU18zRF9NQVhfVElMRVMpIHtcbiAgICAgICAgY29uc29sZS53YXJuKGBbbmFwYXJpLWpzXSAke2tleXMubGVuZ3RofSB0cmFuc2NyaXB0IHRpbGVzIGFyZSB0b28gbWFueSB0byByZWFkIGZvciB0aGUgM0Qgdmlld2ApO1xuICAgICAgICB0aGlzLnJlbW92ZSgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBlbmQgPSB0aGlzLmJlZ2luKCdUcmFuc2NyaXB0cycpO1xuICAgICAgbGV0IHRpbGVzOiBTcGF0aWFsVHJhbnNjcmlwdFRpbGVbXTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRpbGVzID0gYXdhaXQgcG9vbGVkKGtleXMsIENPTkNVUlJFTkNZLCAoaykgPT5cbiAgICAgICAgICBwb3J0LmdldFRyYW5zY3JpcHRUaWxlISgwLCBrLmd4LCBrLmd5LCB7IGdlbmVzOiBnZW5lcy5xdWVyeSwgcXVhbGl0eSB9KSxcbiAgICAgICAgKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zb2xlLndhcm4oJ1tuYXBhcmktanNdIHRyYW5zY3JpcHRzIGZvciB0aGUgM0QgdmlldyBjb3VsZCBub3QgYmUgcmVhZCcsIGVycik7XG4gICAgICAgIC8vIFRoZSBwYW5lbCBhc2tlZCBmb3Igb3RoZXIgdHJhbnNjcmlwdHMgdGhhbiB0aG9zZSBkcmF3bjogdGFrZSB0aGVtIGRvd24gcmF0aGVyIHRoYW4gbGVhdmVcbiAgICAgICAgLy8gdGhlIG9sZCBzZWxlY3Rpb24gdXAgYXMgaWYgaXQgd2VyZSB0aGUgbmV3IG9uZTsgdGhlIG5leHQgY2hhbmdlIHJlYWRzIGFnYWluLiBPbmx5IHRoZVxuICAgICAgICAvLyBjdXJyZW50IGxvYWQgbWF5OiBhIHN1cGVyc2VkZWQgb25lIG11c3Qgbm90IHRlYXIgZG93biB3aGF0IGEgbmV3ZXIgb25lIGRyZXcuXG4gICAgICAgIGlmICh0YXNrKCkpIHRoaXMuY2xlYXJMYXllcigpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBlbmQoKTtcbiAgICAgIH1cbiAgICAgIGlmICghdGFzaygpKSByZXR1cm47XG4gICAgICB0aGlzLmxvYWRLZXkgPSBsb2FkS2V5O1xuICAgICAgdGhpcy5zdHlsZUtleSA9IG51bGw7XG4gICAgICB0aGlzLmxvYWRlZCA9IHsgdGlsZXMsIG5hbWVzOiBnZW5lcy5hbGxHZW5lcyA/IChtZXRhLmdlbmVzID8/IG51bGwpIDogZ2VuZXMucXVlcnkgfTtcbiAgICB9XG4gICAgYXdhaXQgdGhpcy5kcmF3KGRhdGFzZXQsIHZpZXcsIHBvcnQsIGZyYW1lLCBnZW5lcy5hbGxHZW5lcyk7XG4gIH1cblxuICAvKiogRm9sbG93IHRoZSBzY2VuZSdzIFogc3RyZXRjaCAobm90aGluZyBpcyByZS11cGxvYWRlZCkuICovXG4gIHNldFpTY2FsZShzOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5sYXllcikgdGhpcy5sYXllci5zY2FsZTNkID0gWzEsIDEsIHNdO1xuICB9XG5cbiAgLyoqIFRha2UgdGhlIGxheWVyIGRvd24gYW5kIGZvcmdldCB3aGF0IGl0IHNob3dlZC4gKi9cbiAgcmVtb3ZlKCk6IHZvaWQge1xuICAgIHRoaXMubG9hZHMuY2FuY2VsKCk7XG4gICAgdGhpcy5jbGVhckxheWVyKCk7XG4gIH1cblxuICBwcml2YXRlIGNsZWFyTGF5ZXIoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubGF5ZXIpIHRoaXMudmlld2VyLmxheWVycy5yZW1vdmUodGhpcy5sYXllcik7XG4gICAgdGhpcy5sYXllciA9IG51bGw7XG4gICAgdGhpcy5sb2FkS2V5ID0gbnVsbDtcbiAgICB0aGlzLnN0eWxlS2V5ID0gbnVsbDtcbiAgICB0aGlzLmxvYWRlZCA9IG51bGw7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGRyYXcoXG4gICAgZGF0YXNldDogU3BhdGlhbERhdGFzZXQsXG4gICAgdmlldzogU3BhdGlhbFZpZXdTdGF0ZSxcbiAgICBwb3J0OiBTcGF0aWFsRGF0YVBvcnQsXG4gICAgZnJhbWU6IFRyYW5zY3JpcHRzM2RGcmFtZSxcbiAgICBhbGxHZW5lczogYm9vbGVhbixcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbG9hZGVkID0gdGhpcy5sb2FkZWQ7XG4gICAgaWYgKCFsb2FkZWQpIHJldHVybjtcbiAgICBjb25zdCBieSA9IHRyYW5zY3JpcHRzM2RDb2xvckJ5KGRhdGFzZXQsIHZpZXcsIGFsbEdlbmVzKTtcbiAgICBjb25zdCBzdHlsZUtleSA9IFtcbiAgICAgIGZyYW1lLm9yaWdpbi5qb2luKCcsJyksXG4gICAgICBieSxcbiAgICAgIGJ5ID09PSAnZ2VuZScgPyBKU09OLnN0cmluZ2lmeSh2aWV3LnRyYW5zY3JpcHRHZW5lQ29sb3JzKSA6ICcnLFxuICAgICAgYnkgIT09ICdnZW5lJyA/IGAke2NlbGxUeXBlQ29sdW1uRm9yKGRhdGFzZXQsIHZpZXcpfXwke0pTT04uc3RyaW5naWZ5KHZpZXcuZ3JvdXBDb2xvcnMpfWAgOiAnJyxcbiAgICAgIGJ5ID09PSAnY2x1c3RlcicgPyBKU09OLnN0cmluZ2lmeSh2aWV3LnRyYW5zY3JpcHRHZW5lR3JvdXBzKSA6ICcnLFxuICAgICAgYWxsR2VuZXMgPyB2aWV3LnRyYW5zY3JpcHRBbGxHZW5lc0hpZGRlbi5qb2luKCcsJykgOiAnJyxcbiAgICBdLmpvaW4oJ3wnKTtcbiAgICBjb25zdCBzaXplID0gVFJBTlNDUklQVF8zRF9CQVNFX1NJWkUgKiAodmlldy50cmFuc2NyaXB0U2NhbGUgPiAwID8gdmlldy50cmFuc2NyaXB0U2NhbGUgOiAxKTtcbiAgICBpZiAodGhpcy5sYXllciAmJiBzdHlsZUtleSA9PT0gdGhpcy5zdHlsZUtleSkge1xuICAgICAgdGhpcy5sYXllci5zaXplID0gc2l6ZTtcbiAgICAgIHRoaXMubGF5ZXIub3BhY2l0eSA9IHZpZXcudHJhbnNjcmlwdE9wYWNpdHk7XG4gICAgICB0aGlzLmxheWVyLnNjYWxlM2QgPSBbMSwgMSwgZnJhbWUuelNjYWxlXTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgeyBuYW1lcyB9ID0gbG9hZGVkO1xuICAgIGNvbnN0IHNob3duID0gYWxsR2VuZXMgJiYgbmFtZXMgPyBhbGxHZW5lU2hvd25CeSh2aWV3LnRyYW5zY3JpcHRBbGxHZW5lc0hpZGRlbikgOiBudWxsO1xuICAgIGNvbnN0IGtlZXAgPSBzaG93biAmJiBuYW1lcyA/IChnOiBudW1iZXIpID0+ICEhbmFtZXNbZ10gJiYgc2hvd24obmFtZXNbZ10pIDogKCkgPT4gdHJ1ZTtcbiAgICBjb25zdCB0b3RhbCA9IGxvYWRlZC50aWxlcy5yZWR1Y2UoKG4sIHQpID0+IG4gKyB0LmNvdW50LCAwKTtcbiAgICBjb25zdCBzdHJpZGUgPSBNYXRoLm1heCgxLCBNYXRoLmNlaWwodG90YWwgLyBUUkFOU0NSSVBUU18zRF9NQVgpKTtcbiAgICBpZiAoc3RyaWRlID4gMSkgY29uc29sZS53YXJuKGBbbmFwYXJpLWpzXSBkcmF3aW5nIGV2ZXJ5ICR7c3RyaWRlfXRoIG9mICR7dG90YWx9IHRyYW5zY3JpcHRzIGluIDNEYCk7XG5cbiAgICBjb25zdCBbb3gsIG95LCBvel0gPSBmcmFtZS5vcmlnaW47XG4gICAgY29uc3QgcG9zaXRpb25zOiBudW1iZXJbXSA9IFtdO1xuICAgIGNvbnN0IGdlbmVzOiBudW1iZXJbXSA9IFtdO1xuICAgIGNvbnN0IGNlbGxzOiBudW1iZXJbXSA9IFtdO1xuICAgIGxldCBzZWVuID0gMDtcbiAgICBmb3IgKGNvbnN0IHQgb2YgbG9hZGVkLnRpbGVzKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHQuY291bnQ7IGkrKykge1xuICAgICAgICBpZiAoIWtlZXAodC5nZW5lW2ldKSB8fCBzZWVuKysgJSBzdHJpZGUpIGNvbnRpbnVlO1xuICAgICAgICBwb3NpdGlvbnMucHVzaCh0LnhbaV0gKyBveCwgdC55W2ldICsgb3ksIHQueltpXSArIG96KTtcbiAgICAgICAgZ2VuZXMucHVzaCh0LmdlbmVbaV0pO1xuICAgICAgICBjZWxscy5wdXNoKHQub2JzZXJ2YXRpb25baV0pO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBjb3VudCA9IGdlbmVzLmxlbmd0aDtcbiAgICBsZXQgY29sb3JzOiBGbG9hdDMyQXJyYXk7XG4gICAgaWYgKGJ5ID09PSAnZ2VuZScpIHtcbiAgICAgIGNvbG9ycyA9IHRyYW5zY3JpcHRzM2RDb2xvcnModmlldywgbmFtZXMsIFVpbnQxNkFycmF5LmZyb20oZ2VuZXMpLCBjb3VudCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGdyb3VwcyA9IGF3YWl0IGNlbGxHcm91cENvbG9ycyhkYXRhc2V0LCB2aWV3LCBwb3J0KS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgIGNvbnNvbGUud2FybignW25hcGFyaS1qc10gdGhlIGNlbGxzIGdyb3VwaW5nIGZvciB0aGUgM0QgdHJhbnNjcmlwdHMgY291bGQgbm90IGJlIHJlYWQnLCBlcnIpO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0pO1xuICAgICAgLy8gQSBuZXdlciBkcmF3IChhbm90aGVyIHN0eWxlLCBvciB0aGUgbGF5ZXIgdGFrZW4gZG93bikgd29uIHdoaWxlIHRoZSBjb2x1bW4gbG9hZGVkLlxuICAgICAgaWYgKHRoaXMubG9hZGVkICE9PSBsb2FkZWQpIHJldHVybjtcbiAgICAgIGlmIChieSA9PT0gJ2NlbGxUeXBlJykge1xuICAgICAgICBjb2xvcnMgPSBwYWNrZWQoY291bnQsIChpKSA9PiB7XG4gICAgICAgICAgY29uc3QgbyA9IGNlbGxzW2ldO1xuICAgICAgICAgIGNvbnN0IGNvZGUgPSAhZ3JvdXBzIHx8IG8gPT09IE5PX09CU0VSVkFUSU9OID8gTk9fQ0FURUdPUlkgOiBncm91cHMuY29kZXNbb107XG4gICAgICAgICAgcmV0dXJuIGNvZGUgPT09IE5PX0NBVEVHT1JZID8gdW5kZWZpbmVkIDogZ3JvdXBzIS5jb2xvcnNbY29kZV07XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQSBjbHVzdGVyIG5hbWVkIGxpa2UgYSBncm91cCBvZiB0aGUgY2VsbHMnIGdyb3VwaW5nIHRha2VzIHRoYXQgZ3JvdXAncyBjb2xvdXIsIGFzIGluIDJELlxuICAgICAgICBjb25zdCBieUNsdXN0ZXIgPSBjbHVzdGVyQ29sb3JNYXAoXG4gICAgICAgICAgdmlldy50cmFuc2NyaXB0R2VuZXMsXG4gICAgICAgICAgdmlldy50cmFuc2NyaXB0R2VuZUdyb3VwcyxcbiAgICAgICAgICBncm91cHM/LmJ5TmFtZSA/PyBuZXcgTWFwKCksXG4gICAgICAgICAgREVGQVVMVF9DQVRFR09SSUNBTF9QQUxFVFRFLFxuICAgICAgICApO1xuICAgICAgICBjb25zdCB0YWJsZSA9IChuYW1lcyA/PyBbXSkubWFwKChnZW5lKSA9PiB7XG4gICAgICAgICAgY29uc3QgaGV4ID0gYnlDbHVzdGVyLmdldChjbHVzdGVyT2ZHZW5lKGdlbmUsIHZpZXcudHJhbnNjcmlwdEdlbmVHcm91cHMpKTtcbiAgICAgICAgICByZXR1cm4gaGV4ID8gcmdiYTAxKGhleCkgOiB1bmRlZmluZWQ7XG4gICAgICAgIH0pO1xuICAgICAgICBjb2xvcnMgPSBwYWNrZWQoY291bnQsIChpKSA9PiB0YWJsZVtnZW5lc1tpXV0pO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodGhpcy5sYXllcikgdGhpcy52aWV3ZXIubGF5ZXJzLnJlbW92ZSh0aGlzLmxheWVyKTtcbiAgICB0aGlzLmxheWVyID0gbnVsbDtcbiAgICB0aGlzLnN0eWxlS2V5ID0gc3R5bGVLZXk7XG4gICAgaWYgKCFjb3VudCkgcmV0dXJuO1xuICAgIHRoaXMubGF5ZXIgPSB0aGlzLnZpZXdlci5hZGRQb2ludHMzRChGbG9hdDMyQXJyYXkuZnJvbShwb3NpdGlvbnMpLCBuZXcgRmxvYXQzMkFycmF5KGNvdW50KSwge1xuICAgICAgbmFtZTogJ3RyYW5zY3JpcHRzJyxcbiAgICAgIHNpemUsXG4gICAgICBvcGFjaXR5OiB2aWV3LnRyYW5zY3JpcHRPcGFjaXR5LFxuICAgICAgc2NhbGUzZDogWzEsIDEsIGZyYW1lLnpTY2FsZV0sXG4gICAgICBjb2xvcnMsXG4gICAgfSk7XG4gIH1cbn1cblxuLyoqIGB3b3JrYCBvdmVyIGBpdGVtc2AsIGF0IG1vc3QgYGxpbWl0YCBhdCBvbmNlLCByZXN1bHRzIGluIG9yZGVyLiAqL1xuYXN5bmMgZnVuY3Rpb24gcG9vbGVkPFQsIFI+KGl0ZW1zOiByZWFkb25seSBUW10sIGxpbWl0OiBudW1iZXIsIHdvcms6IChpdGVtOiBUKSA9PiBQcm9taXNlPFI+KTogUHJvbWlzZTxSW10+IHtcbiAgY29uc3Qgb3V0ID0gbmV3IEFycmF5PFI+KGl0ZW1zLmxlbmd0aCk7XG4gIGxldCBuZXh0ID0gMDtcbiAgY29uc3QgcnVuID0gYXN5bmMgKCkgPT4ge1xuICAgIHdoaWxlIChuZXh0IDwgaXRlbXMubGVuZ3RoKSB7XG4gICAgICBjb25zdCBpID0gbmV4dCsrO1xuICAgICAgb3V0W2ldID0gYXdhaXQgd29yayhpdGVtc1tpXSk7XG4gICAgfVxuICB9O1xuICBhd2FpdCBQcm9taXNlLmFsbChBcnJheS5mcm9tKHsgbGVuZ3RoOiBNYXRoLm1pbihsaW1pdCwgaXRlbXMubGVuZ3RoKSB9LCBydW4pKTtcbiAgcmV0dXJuIG91dDtcbn1cbiJdfQ==
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { colormapFromLut } from 'napari-js';
|
|
2
2
|
import { NO_CATEGORY } from '../../contracts/spatial-dataset.contract';
|
|
3
|
-
import { contrastWindow, encodeCategorical, encodeContinuous,
|
|
3
|
+
import { contrastWindow, encodeCategorical, encodeContinuous, categoryColorsFor, } from '../../spatial/spatial-encoding';
|
|
4
4
|
import { maskToIndices } from '../../spatial/spatial-selection';
|
|
5
5
|
/**
|
|
6
6
|
* The spatial scenes' pure colour and grouping math: what the 2D markers, the 3D cloud and the
|
|
@@ -14,6 +14,13 @@ export const SPATIAL_FALLBACK_RADIUS = 4;
|
|
|
14
14
|
* 40 µm/px template, so drawing them to scale would put every cell a fifth of a pixel wide
|
|
15
15
|
* and the section would come up empty. The point-size control scales up from this floor. */
|
|
16
16
|
export const SPATIAL_SLICE_MIN_DIAMETER_PX = 1.5;
|
|
17
|
+
/**
|
|
18
|
+
* Smallest drawn marker diameter in the 2D view, in SCREEN pixels, at any zoom. A marker's size is
|
|
19
|
+
* the cell's own (data units), so zoomed out over a whole Cytos plate or Xenium section every cell
|
|
20
|
+
* fell below a pixel and the observations vanished; with the floor they stay a dense field of
|
|
21
|
+
* dots, coloured as they are, at every zoom (the GPU applies it per frame: no rebuild on zoom).
|
|
22
|
+
*/
|
|
23
|
+
export const SPATIAL_MARKER_MIN_SCREEN_PX = 2;
|
|
17
24
|
/** Longest side of the gene-map raster, in field pixels. A gene map is a smooth
|
|
18
25
|
* field read as territory, so it gains nothing from matching a 2 Gpx slide's
|
|
19
26
|
* resolution — and the estimate costs one pass over this many pixels. */
|
|
@@ -181,9 +188,9 @@ export function totalDensityGroup(selection) {
|
|
|
181
188
|
* {@link DENSITY_MAX_CLUSTERS}, each with its legend colour — restricted to the selection when
|
|
182
189
|
* there is one, so "select a region, check the box" answers which clusters live there.
|
|
183
190
|
*/
|
|
184
|
-
export function rankDensityGroups(columnName, column, count, selection) {
|
|
191
|
+
export function rankDensityGroups(columnName, column, count, selection, groupColors) {
|
|
185
192
|
const inSelection = selection.count > 0 ? selection.mask : null;
|
|
186
|
-
const colors =
|
|
193
|
+
const colors = categoryColorsFor(columnName, column.meta, groupColors);
|
|
187
194
|
const counts = new Uint32Array(column.meta.categories.length);
|
|
188
195
|
for (let i = 0; i < count; i++) {
|
|
189
196
|
if (inSelection && !inSelection[i])
|
|
@@ -216,4 +223,4 @@ export function rankDensityGroups(columnName, column, count, selection) {
|
|
|
216
223
|
};
|
|
217
224
|
});
|
|
218
225
|
}
|
|
219
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFwYXJpLXNwYXRpYWwtZW5jb2RpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2ltcGxlbWVudGF0aW9ucy9uYXBhcmktanMvbmFwYXJpLXNwYXRpYWwtZW5jb2RpbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUk1QyxPQUFPLEVBQXFCLFdBQVcsRUFBRSxNQUFNLDBDQUEwQyxDQUFDO0FBRTFGLE9BQU8sRUFDTCxjQUFjLEVBQ2QsaUJBQWlCLEVBQ2pCLGdCQUFnQixFQUNoQixxQkFBcUIsR0FFdEIsTUFBTSxnQ0FBZ0MsQ0FBQztBQUN4QyxPQUFPLEVBQXdCLGFBQWEsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRXRGOzs7O0dBSUc7QUFFSCwrRkFBK0Y7QUFDL0YsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQUcsQ0FBQyxDQUFDO0FBQ3pDOzs7NkZBRzZGO0FBQzdGLE1BQU0sQ0FBQyxNQUFNLDZCQUE2QixHQUFHLEdBQUcsQ0FBQztBQUNqRDs7MEVBRTBFO0FBQzFFLE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLEdBQUcsQ0FBQztBQUNyQzsrREFDK0Q7QUFDL0QsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUFHLEdBQUcsQ0FBQztBQUNsQzs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxNQUFNLHNCQUFzQixHQUFHLENBQUMsQ0FBQztBQUN4QztpRkFDaUY7QUFDakYsTUFBTSxDQUFDLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxDQUFDO0FBQ3RDO29EQUNvRDtBQUNwRCxNQUFNLENBQUMsTUFBTSwyQkFBMkIsR0FBRyxHQUFHLENBQUM7QUFDL0Msa0ZBQWtGO0FBQ2xGLE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHLENBQUMsQ0FBQztBQUV0Qzt1Q0FDdUM7QUFDdkMsTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQXFDLENB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QUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2pELENBQUM7UUFDRCxPQUFPO1lBQ0wsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQztZQUNsQyxLQUFLLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLFNBQVM7WUFDaEMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztTQUNoQyxDQUFDO0lBQ0osQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY29sb3JtYXBGcm9tTHV0IH0gZnJvbSAnbmFwYXJpLWpzJztcbmltcG9ydCB0eXBlIHsgQ29sb3JtYXAgfSBmcm9tICduYXBhcmktanMnO1xuXG5pbXBvcnQgeyBSZ2IgfSBmcm9tICcuLi8uLi9jb250cmFjdHMvY29sb3JtYXAtbHV0JztcbmltcG9ydCB7IENhdGVnb3JpY2FsQ29sdW1uLCBOT19DQVRFR09SWSB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy9zcGF0aWFsLWRhdGFzZXQuY29udHJhY3QnO1xuaW1wb3J0IHsgU3BhdGlhbFZpZXdTdGF0ZSB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy9kaXNwbGF5LXR5cGVzJztcbmltcG9ydCB7XG4gIGNvbnRyYXN0V2luZG93LFxuICBlbmNvZGVDYXRlZ29yaWNhbCxcbiAgZW5jb2RlQ29udGludW91cyxcbiAgcmVzb2x2ZUNhdGVnb3J5Q29sb3JzLFxuICB0eXBlIFJHQkEsXG59IGZyb20gJy4uLy4uL3NwYXRpYWwvc3BhdGlhbC1lbmNvZGluZyc7XG5pbXBvcnQgeyBTcGF0aWFsU2VsZWN0aW9uTWFzaywgbWFza1RvSW5kaWNlcyB9IGZyb20gJy4uLy4uL3NwYXRpYWwvc3BhdGlhbC1zZWxlY3Rpb24nO1xuXG4vKipcbiAqIFRoZSBzcGF0aWFsIHNjZW5lcycgcHVyZSBjb2xvdXIgYW5kIGdyb3VwaW5nIG1hdGg6IHdoYXQgdGhlIDJEIG1hcmtlcnMsIHRoZSAzRCBjbG91ZCBhbmQgdGhlXG4gKiBkZW5zaXR5IHZvbHVtZXMgYXJlIGNvbG91cmVkIHdpdGgsIGFzIGZ1bmN0aW9ucyBvZiB0aGUgZGF0YSwgdGhlIHZpZXcgYW5kIGEgTFVULiBObyB2aWV3ZXIsIG5vXG4gKiBwb3J0LCBubyBzdG9yZSAocmV2aWV3IEFwcGVuZGl4IEIsIHN0ZXAgMSkuXG4gKi9cblxuLyoqIE1hcmtlciByYWRpdXMgKGltYWdlIHB4KSBmb3IgYSBkYXRhc2V0IHRoYXQgZGVjbGFyZXMgbm9uZSDigJQgc2VnbWVudGVkIGNlbGxzIG9mdGVuIGRvbid0LiAqL1xuZXhwb3J0IGNvbnN0IFNQQVRJQUxfRkFMTEJBQ0tfUkFESVVTID0gNDtcbi8qKiBTbWFsbGVzdCBtYXJrZXIgRElBTUVURVIsIGluIHNsaWNlIHBpeGVscywgb3ZlciBhIHZvbHVtZS1iYWNrZWQgZGF0YXNldC4gQSBjZWxsJ3MgcmVhbFxuICogIHNpemUgaXMgaG9ub3VyZWQgd2hlcmV2ZXIgaXQgc3Vydml2ZXMgdGhlIGdyaWQ6IHRoZSBBQkMgYXRsYXMgc2VydmVzIDUgwrVtIHJhZGlpIG9uIGFcbiAqICA0MCDCtW0vcHggdGVtcGxhdGUsIHNvIGRyYXdpbmcgdGhlbSB0byBzY2FsZSB3b3VsZCBwdXQgZXZlcnkgY2VsbCBhIGZpZnRoIG9mIGEgcGl4ZWwgd2lkZVxuICogIGFuZCB0aGUgc2VjdGlvbiB3b3VsZCBjb21lIHVwIGVtcHR5LiBUaGUgcG9pbnQtc2l6ZSBjb250cm9sIHNjYWxlcyB1cCBmcm9tIHRoaXMgZmxvb3IuICovXG5leHBvcnQgY29uc3QgU1BBVElBTF9TTElDRV9NSU5fRElBTUVURVJfUFggPSAxLjU7XG4vKiogTG9uZ2VzdCBzaWRlIG9mIHRoZSBnZW5lLW1hcCByYXN0ZXIsIGluIGZpZWxkIHBpeGVscy4gQSBnZW5lIG1hcCBpcyBhIHNtb290aFxuICogIGZpZWxkIHJlYWQgYXMgdGVycml0b3J5LCBzbyBpdCBnYWlucyBub3RoaW5nIGZyb20gbWF0Y2hpbmcgYSAyIEdweCBzbGlkZSdzXG4gKiAgcmVzb2x1dGlvbiDigJQgYW5kIHRoZSBlc3RpbWF0ZSBjb3N0cyBvbmUgcGFzcyBvdmVyIHRoaXMgbWFueSBwaXhlbHMuICovXG5leHBvcnQgY29uc3QgR0VORV9NQVBfTUFYX1NJREUgPSA1MTI7XG4vKiogS2VybmVsIM+DIGluIGZpZWxkIHBpeGVscyBhdCBzbW9vdGhpbmcgMTogd2lkZSBlbm91Z2ggdG8gcmVhZCBiZXR3ZWVuIGNlbGxzLFxuICogIHRpZ2h0IGVub3VnaCB0byBrZWVwIGEgbnVjbGV1cy1zY2FsZSBzdHJ1Y3R1cmUgZGlzdGluY3QuICovXG5leHBvcnQgY29uc3QgR0VORV9NQVBfU0lHTUEgPSAyLjU7XG4vKipcbiAqIEluLXBsYW5lIGNvYXJzZW5pbmcgb2YgdGhlIDNEIGdlbmUgbWFwJ3MgbGF0dGljZSwgcmVsYXRpdmUgdG8gdGhlIHJlZmVyZW5jZVxuICogdm9sdW1lLiBUaGUgZmllbGQgaXMgc21vb3RoLCBzbyBpdHMgZGV0YWlsIGlzIHNldCBieSB0aGUga2VybmVsIHJhdGhlciB0aGFuIHRoZVxuICogcmFzdGVyIOKAlCBhbmQgdGhlIGVzdGltYXRlIGlzIGEgcGFpciBvZiBzZXBhcmFibGUgYmx1cnMsIHdoaWNoIGF0IHRoZSB0ZW1wbGF0ZSdzXG4gKiBmdWxsIHJlc29sdXRpb24gbWVhbnMgc2Vjb25kcyBvZiB3b3JrIHBlciB0b2dnbGUuXG4gKi9cbmV4cG9ydCBjb25zdCBHRU5FX01BUF9WT0xVTUVfU1RSSURFID0gMjtcbi8qKiBDbHVzdGVycyBkcmF3biBhcyBkZW5zaXR5IHZvbHVtZXMgYXQgb25jZS4gUGFzdCBhIGhhbmRmdWwsIGFkZGl0aXZlIHRyYW5zbHVjZW50XG4gKiAgY2xvdWRzIHN0b3AgYmVpbmcgc2VwYXJhYmxlIGJ5IGV5ZSDigJQgYW5kIGVhY2ggb25lIGlzIGEgZnVsbCByYXN0ZXJpc2F0aW9uLiAqL1xuZXhwb3J0IGNvbnN0IERFTlNJVFlfTUFYX0NMVVNURVJTID0gNjtcbi8qKiBIb3cgbXVjaCBsYXJnZXIgYSBzZWxlY3RlZCBtYXJrZXIgaXMgZHJhd24sIHNvIGEgc21hbGwgc2VsZWN0aW9uIGlzIGZpbmRhYmxlIGluc2lkZSBhXG4gKiAgMy43TS1wb2ludCBjbG91ZCByYXRoZXIgdGhhbiBtZXJlbHkgYnJpZ2h0ZXIuICovXG5leHBvcnQgY29uc3QgU1BBVElBTF9TRUxFQ1RFRF9TSVpFX1NDQUxFID0gMS42O1xuLyoqIEJhc2UgbWFya2VyIGRpYW1ldGVyIGZvciB0aGUgM0QgY2xvdWQsIGluIFNDUkVFTiBwaXhlbHMgKHRoZSBsYXllcidzIHVuaXQpLiAqL1xuZXhwb3J0IGNvbnN0IFNQQVRJQUxfM0RfQkFTRV9TSVpFID0gMztcblxuLyoqIENvbG91ciBmb3Igb2JzZXJ2YXRpb25zIHdoZW4gbm90aGluZyBpcyBzZWxlY3RlZCB0byBjb2xvdXIgYnk6IHZpc2libGUsIG5ldXRyYWwsIGFuZFxuICogIG9idmlvdXNseSBub3QgZW5jb2RpbmcgYW55dGhpbmcuICovXG5leHBvcnQgY29uc3QgU1BBVElBTF9ORVVUUkFMX0NPTE9SOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFswLjM1LCAwLjcyLCAwLjk1LCAwLjldO1xuLyoqIHtAbGluayBTUEFUSUFMX05FVVRSQUxfQ09MT1J9IGFzIGEgaGV4IGNvbG91ciAoYWxwaGEgZHJvcHBlZCksIGZvciB0aGUgZW5jb2RlcnMgYW5kIHRoZVxuICogIGRlbnNpdHktdm9sdW1lIHRpbnQuICovXG5leHBvcnQgY29uc3QgU1BBVElBTF9ORVVUUkFMX0hFWCA9IGAjJHtTUEFUSUFMX05FVVRSQUxfQ09MT1Iuc2xpY2UoMCwgMylcbiAgLm1hcCgoYykgPT5cbiAgICBNYXRoLnJvdW5kKGMgKiAyNTUpXG4gICAgICAudG9TdHJpbmcoMTYpXG4gICAgICAucGFkU3RhcnQoMiwgJzAnKSxcbiAgKVxuICAuam9pbignJyl9YDtcblxuLyoqXG4gKiBDb250cmFzdCB3aW5kb3dzIG1lbW9pc2VkIHBlciAodmFsdWVzIGFycmF5LCBsbywgaGksIGxvZykuIGBjb250cmFzdFdpbmRvd2Agc29ydHMgZXZlcnkgdmFsdWUsXG4gKiBhbmQgdGhlIHNwYXRpYWwgY29sb3VyaW5nIHJlLXJ1bnMgaXQgb24gZWFjaCBvcGFjaXR5LCBzZWxlY3Rpb24gb3IgY29sb3JtYXAgY2hhbmdlIHdoaWxlIHRoZVxuICogY29sb3VyZWQgdmVjdG9yIGl0c2VsZiBpcyB1bmNoYW5nZWQgKHJldmlldyBTUEFUSUFMLTEyKS4gS2V5ZWQgYnkgdGhlIHZlY3RvcidzIGlkZW50aXR5LCBzbyBhXG4gKiBuZXcgY29sdW1uIG9yIGdlbmUgdmVjdG9yIGlzIGEgbWlzcyBhbmQgYW4gb2xkIG9uZSBpcyBjb2xsZWN0ZWQgd2l0aCBpdHMgd2luZG93cy5cbiAqL1xuZXhwb3J0IGNsYXNzIENvbnRyYXN0V2luZG93Q2FjaGUge1xuICBwcml2YXRlIHJlYWRvbmx5IGJ5VmVjdG9yID0gbmV3IFdlYWtNYXA8RmxvYXQzMkFycmF5LCBNYXA8c3RyaW5nLCBbbnVtYmVyLCBudW1iZXJdPj4oKTtcblxuICBnZXQoXG4gICAgdmFsdWVzOiBGbG9hdDMyQXJyYXksXG4gICAgbG86IG51bWJlcixcbiAgICBoaTogbnVtYmVyLFxuICAgIGxvZzogYm9vbGVhbixcbiAgICBjb21wdXRlOiAoKSA9PiBbbnVtYmVyLCBudW1iZXJdLFxuICApOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgICBsZXQgd2luZG93cyA9IHRoaXMuYnlWZWN0b3IuZ2V0KHZhbHVlcyk7XG4gICAgaWYgKCF3aW5kb3dzKSB7XG4gICAgICB3aW5kb3dzID0gbmV3IE1hcCgpO1xuICAgICAgdGhpcy5ieVZlY3Rvci5zZXQodmFsdWVzLCB3aW5kb3dzKTtcbiAgICB9XG4gICAgY29uc3Qga2V5ID0gYCR7bG99fCR7aGl9fCR7bG9nID8gMSA6IDB9YDtcbiAgICBsZXQgdyA9IHdpbmRvd3MuZ2V0KGtleSk7XG4gICAgaWYgKCF3KSB7XG4gICAgICB3ID0gY29tcHV0ZSgpO1xuICAgICAgd2luZG93cy5zZXQoa2V5LCB3KTtcbiAgICB9XG4gICAgcmV0dXJuIHc7XG4gIH1cbn1cblxuLyoqXG4gKiBXaGF0IHRoZSAzRCBwb2ludHMgbGF5ZXIgbmVlZHMgdG8gY29sb3VyIGEgY2xvdWQ6IGZvciBjb250aW51b3VzIGRhdGEsIG9uZSBzY2FsYXIgcGVyIHBvaW50LCBhXG4gKiBjb2xvcm1hcCBhbmQgdGhlIHdpbmRvdyB0aGF0IG1hcHMgc2NhbGFycyBvbnRvIGl0OyBmb3IgY2F0ZWdvcmljYWwgZGF0YSwgb25lIHBhY2tlZCBSR0JBIHBlclxuICogcG9pbnQgKGBQb2ludHMzRExheWVyLmNvbG9yc2AsIHdoaWNoIHdpbnMgb3ZlciB0aGUgc2NhbGFycykuXG4gKi9cbmV4cG9ydCB0eXBlIFNwYXRpYWwzZEVuY29kaW5nID0gU3BhdGlhbDNkU2NhbGFycyB8IFNwYXRpYWwzZENvbG9ycztcblxuLyoqIEEgY2xvdWQgY29sb3VyZWQgdGhyb3VnaCB0aGUgY29sb3JtYXA6IHNjYWxhcnMsIGNvbG9ybWFwIGFuZCB3aW5kb3cuICovXG5leHBvcnQgaW50ZXJmYWNlIFNwYXRpYWwzZFNjYWxhcnMge1xuICBraW5kOiAnc2NhbGFycyc7XG4gIHZhbHVlczogRmxvYXQzMkFycmF5O1xuICBjb2xvcm1hcDogQ29sb3JtYXA7XG4gIGNvbnRyYXN0TGltaXRzOiBbbnVtYmVyLCBudW1iZXJdO1xufVxuXG4vKiogQSBjbG91ZCBjb2xvdXJlZCBwb2ludCBieSBwb2ludDogcGFja2VkIFJHQkEsIDQgZmxvYXRzIHBlciBwb2ludC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3BhdGlhbDNkQ29sb3JzIHtcbiAga2luZDogJ2NvbG9ycyc7XG4gIGNvbG9yczogRmxvYXQzMkFycmF5O1xufVxuXG4vKiogQSBvbmUtY29sb3VyIGNvbG9ybWFwLCBmb3IgdGhlIFwibm90aGluZyB0byBjb2xvdXIgYnlcIiBzdGF0ZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzcGF0aWFsRmxhdENvbG9ybWFwKCk6IENvbG9ybWFwIHtcbiAgY29uc3QgW3IsIGcsIGJdID0gU1BBVElBTF9ORVVUUkFMX0NPTE9SO1xuICBjb25zdCByZ2I6IFJnYiA9IFtNYXRoLnJvdW5kKHIgKiAyNTUpLCBNYXRoLnJvdW5kKGcgKiAyNTUpLCBNYXRoLnJvdW5kKGIgKiAyNTUpXTtcbiAgLy8gVHdvIGlkZW50aWNhbCBzdG9wczogY29sb3JtYXBGcm9tTHV0IG5lZWRzIGF0IGxlYXN0IHR3bywgYW5kIGVxdWFsIGVuZHNcbiAgLy8gbWFrZSBldmVyeSB2YWx1ZSByZXNvbHZlIHRvIHRoZSBzYW1lIGNvbG91ci5cbiAgcmV0dXJuIGNvbG9ybWFwRnJvbUx1dCgnc3BhdGlhbC1mbGF0JywgW3JnYiwgcmdiXSk7XG59XG5cbi8qKlxuICogQ2F0ZWdvcnkgY29kZXMg4oaSIG9uZSBSR0JBIHBlciBwb2ludCwgZm9yIGFueSBudW1iZXIgb2YgY2F0ZWdvcmllcy5cbiAqXG4gKiBUaGUgMkQgbWFya2VycycgZW5jb2RpbmcsIHdpdGggb25lIGRpZmZlcmVuY2U6IGEgcG9pbnQgd2l0aCBubyBjYXRlZ29yeSBzdGF5cyBvcGFxdWUgKGdyZXkpLFxuICogYXMgaXQgYWx3YXlzIGhhcyBpbiB0aGUgY2xvdWQsIHdoZXJlIHRoZSBzZWxlY3Rpb24gZGltcyB0aHJvdWdoIHRoZSBsYXllcidzIHBlci1wb2ludCBhbHBoYXNcbiAqIGluc3RlYWQuIEl0IHVzZWQgdG8gYmUgc211Z2dsZWQgdGhyb3VnaCB0aGUgc2NhbGFyIGNoYW5uZWwgYXMgYSBzdGVwcGVkIDI1Ni1lbnRyeSBMVVQsIHdoaWNoXG4gKiBrZXB0IGF0IG1vc3QgOTUgY2F0ZWdvcmllcyBhcGFydCAocmV2aWV3IFNQQVRJQUwtMTEsIE5BUEFSSS1TVkMtMTgpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZW5jb2RlU3BhdGlhbDNkQ2F0ZWdvcmljYWwoY29kZXM6IFVpbnQxNkFycmF5LCBjb2xvcnM6IHN0cmluZ1tdKTogU3BhdGlhbDNkQ29sb3JzIHtcbiAgcmV0dXJuIHsga2luZDogJ2NvbG9ycycsIGNvbG9yczogZW5jb2RlQ2F0ZWdvcmljYWwoY29kZXMsIHsgY29sb3JzLCBtdXRlZE9wYWNpdHk6IDEgfSkgfTtcbn1cblxuLyoqIENvbnRpbnVvdXMgdmFsdWVzIOKGkiBgbHV0YCBvdmVyIGEgcGVyY2VudGlsZS1jbGlwcGVkIHdpbmRvdyAobG9nMXAgZmlyc3Qgd2hlbiB0aGUgdmlldydzIGxvZ1xuICogIHNjYWxlIGlzIG9uKSwgZm9yIHRoZSAzRCBjbG91ZCdzIHNjYWxhciBjaGFubmVsLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVuY29kZVNwYXRpYWwzZENvbnRpbnVvdXMoXG4gIHNvdXJjZTogRmxvYXQzMkFycmF5LFxuICB2aWV3OiBTcGF0aWFsVmlld1N0YXRlLFxuICBsdXQ6IFJnYltdLFxuICB3aW5kb3dzOiBDb250cmFzdFdpbmRvd0NhY2hlLFxuKTogU3BhdGlhbDNkU2NhbGFycyB7XG4gIGNvbnN0IFtsbywgaGldID0gdmlldy5wZXJjZW50aWxlQ2xpcCA/PyBbMC4wMSwgMC45OV07XG4gIGNvbnN0IGxvZyA9ICEhdmlldy5sb2dTY2FsZTtcbiAgbGV0IHZhbHVlcyA9IHNvdXJjZTtcbiAgaWYgKGxvZykge1xuICAgIHZhbHVlcyA9IG5ldyBGbG9hdDMyQXJyYXkoc291cmNlLmxlbmd0aCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzb3VyY2UubGVuZ3RoOyBpKyspIHZhbHVlc1tpXSA9IE1hdGgubG9nMXAoTWF0aC5tYXgoMCwgc291cmNlW2ldKSk7XG4gIH1cbiAgLy8gS2V5ZWQgYnkgdGhlIFNPVVJDRSB2ZWN0b3I6IHRoZSBsb2cgY29weSBhYm92ZSBpcyBuZXcgb24gZXZlcnkgY2FsbC5cbiAgY29uc3QgW21pbiwgbWF4XSA9IHdpbmRvd3MuZ2V0KHNvdXJjZSwgbG8sIGhpLCBsb2csICgpID0+IGNvbnRyYXN0V2luZG93KHZhbHVlcywgbG8sIGhpKSk7XG4gIHJldHVybiB7XG4gICAga2luZDogJ3NjYWxhcnMnLFxuICAgIHZhbHVlcyxcbiAgICBjb2xvcm1hcDogY29sb3JtYXBGcm9tTHV0KCdzcGF0aWFsLWNvbnRpbnVvdXMnLCBsdXQpLFxuICAgIC8vIEEgZGVnZW5lcmF0ZSB3aW5kb3cgd291bGQgZGl2aWRlIGJ5IHplcm8gaW4gdGhlIHNoYWRlcidzIG5vcm1hbGlzYXRpb24uXG4gICAgY29udHJhc3RMaW1pdHM6IG1heCA+IG1pbiA/IFttaW4sIG1heF0gOiBbbWluLCBtaW4gKyAxXSxcbiAgfTtcbn1cblxuLyoqIENvbnRpbnVvdXMgdmFsdWVzIOKGkiBwZXItcG9pbnQgUkdCQSB0aHJvdWdoIGBsdXRgIGFuZCBhIGNsaXBwZWQgd2luZG93IChsb2cgc2NhbGUgcGVyIHRoZVxuICogIHZpZXcpLCBmb3IgdGhlIDJEIG1hcmtlcnMuICovXG5leHBvcnQgZnVuY3Rpb24gZW5jb2RlU3BhdGlhbENvbnRpbnVvdXMoXG4gIHZhbHVlczogRmxvYXQzMkFycmF5LFxuICB2aWV3OiBTcGF0aWFsVmlld1N0YXRlLFxuICBsdXQ6IFJnYltdLFxuICB3aW5kb3dzOiBDb250cmFzdFdpbmRvd0NhY2hlLFxuICBtdXRlZDogVWludDhBcnJheSB8IG51bGwgPSBudWxsLFxuKTogRmxvYXQzMkFycmF5IHtcbiAgY29uc3QgW2xvLCBoaV0gPSB2aWV3LnBlcmNlbnRpbGVDbGlwID8/IFswLjAxLCAwLjk5XTtcbiAgLy8gVGhlIHdpbmRvdyBpcyB0YWtlbiBvbiB0aGUgcmF3IHZhbHVlcyAoZW5jb2RlQ29udGludW91cyBhcHBsaWVzIHRoZSBsb2cgaXRzZWxmKS5cbiAgY29uc3QgW21pbiwgbWF4XSA9IHdpbmRvd3MuZ2V0KHZhbHVlcywgbG8sIGhpLCBmYWxzZSwgKCkgPT4gY29udHJhc3RXaW5kb3codmFsdWVzLCBsbywgaGkpKTtcbiAgcmV0dXJuIGVuY29kZUNvbnRpbnVvdXModmFsdWVzLCB7XG4gICAgbHV0LFxuICAgIG1pbixcbiAgICBtYXgsXG4gICAgbG9nOiB2aWV3LmxvZ1NjYWxlLFxuICAgIG9wYWNpdHk6IHZpZXcub3BhY2l0eSxcbiAgICBtdXRlZCxcbiAgfSk7XG59XG5cbi8qKiBNYXJrZXIgY29sb3VyczogcGFja2VkIHBlci1wb2ludCBSR0JBICg0IGZsb2F0cyBwZXIgcG9pbnQsIHRoZSBzaGFwZSBuYXBhcmktanMgY29waWVzIHN0cmFpZ2h0XG4gKiAgaW50byBpdHMgaW5zdGFuY2UgYnVmZmVyKSwgb3Igb25lIFJHQkEgYnJvYWRjYXN0IHRvIGV2ZXJ5IHBvaW50LiAqL1xuZXhwb3J0IHR5cGUgUG9pbnRDb2xvcnMgPSBGbG9hdDMyQXJyYXkgfCBSR0JBO1xuXG4vKiogV2hldGhlciBhIGNvbG91ciBpbnB1dCBpcyBvbmUgUkdCQSBwZXIgcG9pbnQgcmF0aGVyIHRoYW4gb25lIGJyb2FkY2FzdCBSR0JBLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzUGVyUG9pbnQoY29sb3JzOiBQb2ludENvbG9ycyk6IGNvbG9ycyBpcyBGbG9hdDMyQXJyYXkge1xuICByZXR1cm4gY29sb3JzIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5O1xufVxuXG4vKipcbiAqIGBjb2xvcnNgIHdpdGggZXZlcnkgb2JzZXJ2YXRpb24gYHNob3duYCBsZWF2ZXMgYXQgMCBtYWRlIHRyYW5zcGFyZW50OiB0aGUgb2JzZXJ2YXRpb25zIGEgZ2VuZVxuICogZmlsdGVyIGxlYXZlcyBvdXQuIEEgYnJvYWRjYXN0IGNvbG91ciBiZWNvbWVzIHBlci1wb2ludCwgc2luY2UgdGhlIHBvaW50cyBub3cgZGlmZmVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaGlkZVVuc2hvd24oY29sb3JzOiBQb2ludENvbG9ycywgc2hvd246IFVpbnQ4QXJyYXkpOiBGbG9hdDMyQXJyYXkge1xuICBjb25zdCBjb3VudCA9IHNob3duLmxlbmd0aDtcbiAgbGV0IG91dDogRmxvYXQzMkFycmF5O1xuICBpZiAoaXNQZXJQb2ludChjb2xvcnMpKSB7XG4gICAgb3V0ID0gY29sb3JzLnNsaWNlKCk7IC8vIHRoZSBpbnB1dCBtYXkgYmUgaGVsZCBlbHNld2hlcmVcbiAgfSBlbHNlIHtcbiAgICBvdXQgPSBuZXcgRmxvYXQzMkFycmF5KGNvdW50ICogNCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSBvdXQuc2V0KGNvbG9ycywgaSAqIDQpO1xuICB9XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgaWYgKCFzaG93bltpXSkgb3V0WzQgKiBpICsgM10gPSAwO1xuICByZXR1cm4gb3V0O1xufVxuXG4vKiogUGVyLXBvaW50IGNvbG91cnMgZm9yIHRoZSBkcmF3biBzdWJzZXQuIEEgYnJvYWRjYXN0IHR1cGxlIHN0YXlzIGJyb2FkY2FzdCDigJRcbiAqICBpdCBpcyBvbmUgY29sb3VyIGZvciBldmVyeSBwb2ludCBlaXRoZXIgd2F5LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdhdGhlckNvbG9ycyhjb2xvcnM6IFBvaW50Q29sb3JzLCBpbmRpY2VzPzogVWludDMyQXJyYXkpOiBQb2ludENvbG9ycyB7XG4gIGlmICghaW5kaWNlcyB8fCAhaXNQZXJQb2ludChjb2xvcnMpKSByZXR1cm4gY29sb3JzO1xuICBjb25zdCBvdXQgPSBuZXcgRmxvYXQzMkFycmF5KGluZGljZXMubGVuZ3RoICogNCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5kaWNlcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHMgPSBpbmRpY2VzW2ldICogNDtcbiAgICBjb25zdCBvID0gaSAqIDQ7XG4gICAgb3V0W29dID0gY29sb3JzW3NdO1xuICAgIG91dFtvICsgMV0gPSBjb2xvcnNbcyArIDFdO1xuICAgIG91dFtvICsgMl0gPSBjb2xvcnNbcyArIDJdO1xuICAgIG91dFtvICsgM10gPSBjb2xvcnNbcyArIDNdO1xuICB9XG4gIHJldHVybiBvdXQ7XG59XG5cbi8qKiBPbmUgZGVuc2l0eSB2b2x1bWUncyBvYnNlcnZhdGlvbnM6IGEgY2x1c3RlciAob3IgYWxsIGNlbGxzKSwgd2l0aCBpdHMgbGVnZW5kIGNvbG91ci4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRGVuc2l0eUdyb3VwIHtcbiAgbmFtZTogc3RyaW5nO1xuICBjb2xvcjogc3RyaW5nO1xuICBpbmRpY2VzPzogVWludDMyQXJyYXk7XG59XG5cbi8qKiBUaGUgc2luZ2xlIGdyb3VwIGRyYXduIHdoZW4gdGhlIGNvbG91cmluZyBpcyBub3QgY2F0ZWdvcmljYWw6IHRvdGFsIGNlbGwgZGVuc2l0eSwgd2l0aGluIHRoZVxuICogIHNlbGVjdGlvbiB3aGVuIHRoZXJlIGlzIG9uZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b3RhbERlbnNpdHlHcm91cChzZWxlY3Rpb246IFNwYXRpYWxTZWxlY3Rpb25NYXNrKTogRGVuc2l0eUdyb3VwIHtcbiAgY29uc3QgaW5TZWxlY3Rpb24gPSBzZWxlY3Rpb24uY291bnQgPiAwID8gc2VsZWN0aW9uLm1hc2sgOiBudWxsO1xuICByZXR1cm4ge1xuICAgIG5hbWU6IGluU2VsZWN0aW9uID8gJ3NlbGVjdGVkIGNlbGxzJyA6ICdhbGwgY2VsbHMnLFxuICAgIGNvbG9yOiBTUEFUSUFMX05FVVRSQUxfSEVYLFxuICAgIGluZGljZXM6IGluU2VsZWN0aW9uID8gbWFza1RvSW5kaWNlcyhpblNlbGVjdGlvbikgOiB1bmRlZmluZWQsXG4gIH07XG59XG5cbi8qKlxuICogVGhlIGNsdXN0ZXJzIG9mIGEgY2F0ZWdvcmljYWwgY29sdW1uIHRvIHJhc3RlcmlzZSwgYmlnZ2VzdCBmaXJzdCBhbmQgY2FwcGVkIGF0XG4gKiB7QGxpbmsgREVOU0lUWV9NQVhfQ0xVU1RFUlN9LCBlYWNoIHdpdGggaXRzIGxlZ2VuZCBjb2xvdXIg4oCUIHJlc3RyaWN0ZWQgdG8gdGhlIHNlbGVjdGlvbiB3aGVuXG4gKiB0aGVyZSBpcyBvbmUsIHNvIFwic2VsZWN0IGEgcmVnaW9uLCBjaGVjayB0aGUgYm94XCIgYW5zd2VycyB3aGljaCBjbHVzdGVycyBsaXZlIHRoZXJlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmFua0RlbnNpdHlHcm91cHMoXG4gIGNvbHVtbk5hbWU6IHN0cmluZyxcbiAgY29sdW1uOiBDYXRlZ29yaWNhbENvbHVtbixcbiAgY291bnQ6IG51bWJlcixcbiAgc2VsZWN0aW9uOiBTcGF0aWFsU2VsZWN0aW9uTWFzayxcbik6IERlbnNpdHlHcm91cFtdIHtcbiAgY29uc3QgaW5TZWxlY3Rpb24gPSBzZWxlY3Rpb24uY291bnQgPiAwID8gc2VsZWN0aW9uLm1hc2sgOiBudWxsO1xuICBjb25zdCBjb2xvcnMgPSByZXNvbHZlQ2F0ZWdvcnlDb2xvcnMoY29sdW1uLm1ldGEpO1xuICBjb25zdCBjb3VudHMgPSBuZXcgVWludDMyQXJyYXkoY29sdW1uLm1ldGEuY2F0ZWdvcmllcy5sZW5ndGgpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcbiAgICBpZiAoaW5TZWxlY3Rpb24gJiYgIWluU2VsZWN0aW9uW2ldKSBjb250aW51ZTtcbiAgICBjb25zdCBjb2RlID0gY29sdW1uLmNvZGVzW2ldO1xuICAgIGlmIChjb2RlICE9PSBOT19DQVRFR09SWSAmJiBjb2RlIDwgY291bnRzLmxlbmd0aCkgY291bnRzW2NvZGVdKys7XG4gIH1cbiAgY29uc3QgcmFua2VkID0gQXJyYXkuZnJvbShjb3VudHMsIChuLCBjb2RlKSA9PiAoeyBjb2RlLCBuIH0pKVxuICAgIC5maWx0ZXIoKGMpID0+IGMubiA+IDApXG4gICAgLnNvcnQoKGEsIGIpID0+IGIubiAtIGEubilcbiAgICAuc2xpY2UoMCwgREVOU0lUWV9NQVhfQ0xVU1RFUlMpO1xuICBpZiAoY291bnRzLmZpbHRlcigoYykgPT4gYyA+IDApLmxlbmd0aCA+IHJhbmtlZC5sZW5ndGgpIHtcbiAgICBjb25zb2xlLndhcm4oXG4gICAgICBgW25hcGFyaS1qc10gJHtjb2x1bW5OYW1lfTogZHJhd2luZyB0aGUgJHtyYW5rZWQubGVuZ3RofSBsYXJnZXN0IGNsdXN0ZXJzIGFzIGRlbnNpdHkgYCArXG4gICAgICAgICd2b2x1bWVzOyBtb3JlIHRoYW4gdGhhdCBzdG9wIGJlaW5nIHNlcGFyYWJsZSBieSBleWUnLFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIHJhbmtlZC5tYXAoKHsgY29kZSB9KSA9PiB7XG4gICAgY29uc3QgaW5kaWNlcyA9IG5ldyBVaW50MzJBcnJheShjb3VudHNbY29kZV0pO1xuICAgIGxldCBrID0gMDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcbiAgICAgIGlmIChpblNlbGVjdGlvbiAmJiAhaW5TZWxlY3Rpb25baV0pIGNvbnRpbnVlO1xuICAgICAgaWYgKGNvbHVtbi5jb2Rlc1tpXSA9PT0gY29kZSkgaW5kaWNlc1trKytdID0gaTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIG5hbWU6IGNvbHVtbi5tZXRhLmNhdGVnb3JpZXNbY29kZV0sXG4gICAgICBjb2xvcjogY29sb3JzW2NvZGVdID8/ICcjODg4ODg4JyxcbiAgICAgIGluZGljZXM6IGluZGljZXMuc3ViYXJyYXkoMCwgayksXG4gICAgfTtcbiAgfSk7XG59XG4iXX0=
|
|
226
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFwYXJpLXNwYXRpYWwtZW5jb2RpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2ltcGxlbWVudGF0aW9ucy9uYXBhcmktanMvbmFwYXJpLXNwYXRpYWwtZW5jb2RpbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUk1QyxPQUFPLEVBQXFCLFdBQVcsRUFBRSxNQUFNLDBDQUEwQyxDQUFDO0FBRTFGLE9BQU8sRUFDTCxjQUFjLEVBQ2QsaUJBQWlCLEVBQ2pCLGdCQUFnQixFQUVoQixpQkFBaUIsR0FFbEIsTUFBTSxnQ0FBZ0MsQ0FBQztBQUN4QyxPQUFPLEVBQXdCLGFBQWEsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRXRGOzs7O0dBSUc7QUFFSCwrRkFBK0Y7QUFDL0YsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQUcsQ0FBQyxDQUFDO0FBQ3pDOzs7NkZBRzZGO0FBQzdGLE1BQU0sQ0FBQyxNQUFNLDZCQUE2QixHQUFHLEdBQUcsQ0FBQztBQUNqRDs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxNQUFNLDRCQUE0QixHQUFHLENBQUMsQ0FBQztBQUM5Qzs7MEVBRTBFO0FBQzFFLE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLEdBQUcsQ0FBQztBQUNyQzsrREFDK0Q7QUFDL0QsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUFHLEdBQUcsQ0FBQztBQUNsQzs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxNQUFNLHNCQUFzQixHQUFHLENBQUMsQ0FBQztBQUN4QztpRkFDaUY7QUFDakYsTUFBTSxDQUFDLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxDQUFDO0FBQ3RDO29EQUNvRDtBQUNwRCxNQUFNLENBQUMsTUFBTSwyQkFBMkIsR0FBRyxHQUFHLENBQUM7QUFDL0Msa0ZBQWtGO0FBQ2xGLE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHLENB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QUFDLENBQUM7Z0JBQUUsU0FBUztZQUM3QyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSTtnQkFBRSxPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDakQsQ0FBQztRQUNELE9BQU87WUFDTCxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDO1lBQ2xDLEtBQUssRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksU0FBUztZQUNoQyxPQUFPLEVBQUUsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1NBQ2hDLENBQUM7SUFDSixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjb2xvcm1hcEZyb21MdXQgfSBmcm9tICduYXBhcmktanMnO1xuaW1wb3J0IHR5cGUgeyBDb2xvcm1hcCB9IGZyb20gJ25hcGFyaS1qcyc7XG5cbmltcG9ydCB7IFJnYiB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy9jb2xvcm1hcC1sdXQnO1xuaW1wb3J0IHsgQ2F0ZWdvcmljYWxDb2x1bW4sIE5PX0NBVEVHT1JZIH0gZnJvbSAnLi4vLi4vY29udHJhY3RzL3NwYXRpYWwtZGF0YXNldC5jb250cmFjdCc7XG5pbXBvcnQgeyBTcGF0aWFsVmlld1N0YXRlIH0gZnJvbSAnLi4vLi4vY29udHJhY3RzL2Rpc3BsYXktdHlwZXMnO1xuaW1wb3J0IHtcbiAgY29udHJhc3RXaW5kb3csXG4gIGVuY29kZUNhdGVnb3JpY2FsLFxuICBlbmNvZGVDb250aW51b3VzLFxuICBHcm91cENvbG9yT3ZlcnJpZGVzLFxuICBjYXRlZ29yeUNvbG9yc0ZvcixcbiAgdHlwZSBSR0JBLFxufSBmcm9tICcuLi8uLi9zcGF0aWFsL3NwYXRpYWwtZW5jb2RpbmcnO1xuaW1wb3J0IHsgU3BhdGlhbFNlbGVjdGlvbk1hc2ssIG1hc2tUb0luZGljZXMgfSBmcm9tICcuLi8uLi9zcGF0aWFsL3NwYXRpYWwtc2VsZWN0aW9uJztcblxuLyoqXG4gKiBUaGUgc3BhdGlhbCBzY2VuZXMnIHB1cmUgY29sb3VyIGFuZCBncm91cGluZyBtYXRoOiB3aGF0IHRoZSAyRCBtYXJrZXJzLCB0aGUgM0QgY2xvdWQgYW5kIHRoZVxuICogZGVuc2l0eSB2b2x1bWVzIGFyZSBjb2xvdXJlZCB3aXRoLCBhcyBmdW5jdGlvbnMgb2YgdGhlIGRhdGEsIHRoZSB2aWV3IGFuZCBhIExVVC4gTm8gdmlld2VyLCBub1xuICogcG9ydCwgbm8gc3RvcmUgKHJldmlldyBBcHBlbmRpeCBCLCBzdGVwIDEpLlxuICovXG5cbi8qKiBNYXJrZXIgcmFkaXVzIChpbWFnZSBweCkgZm9yIGEgZGF0YXNldCB0aGF0IGRlY2xhcmVzIG5vbmUg4oCUIHNlZ21lbnRlZCBjZWxscyBvZnRlbiBkb24ndC4gKi9cbmV4cG9ydCBjb25zdCBTUEFUSUFMX0ZBTExCQUNLX1JBRElVUyA9IDQ7XG4vKiogU21hbGxlc3QgbWFya2VyIERJQU1FVEVSLCBpbiBzbGljZSBwaXhlbHMsIG92ZXIgYSB2b2x1bWUtYmFja2VkIGRhdGFzZXQuIEEgY2VsbCdzIHJlYWxcbiAqICBzaXplIGlzIGhvbm91cmVkIHdoZXJldmVyIGl0IHN1cnZpdmVzIHRoZSBncmlkOiB0aGUgQUJDIGF0bGFzIHNlcnZlcyA1IMK1bSByYWRpaSBvbiBhXG4gKiAgNDAgwrVtL3B4IHRlbXBsYXRlLCBzbyBkcmF3aW5nIHRoZW0gdG8gc2NhbGUgd291bGQgcHV0IGV2ZXJ5IGNlbGwgYSBmaWZ0aCBvZiBhIHBpeGVsIHdpZGVcbiAqICBhbmQgdGhlIHNlY3Rpb24gd291bGQgY29tZSB1cCBlbXB0eS4gVGhlIHBvaW50LXNpemUgY29udHJvbCBzY2FsZXMgdXAgZnJvbSB0aGlzIGZsb29yLiAqL1xuZXhwb3J0IGNvbnN0IFNQQVRJQUxfU0xJQ0VfTUlOX0RJQU1FVEVSX1BYID0gMS41O1xuLyoqXG4gKiBTbWFsbGVzdCBkcmF3biBtYXJrZXIgZGlhbWV0ZXIgaW4gdGhlIDJEIHZpZXcsIGluIFNDUkVFTiBwaXhlbHMsIGF0IGFueSB6b29tLiBBIG1hcmtlcidzIHNpemUgaXNcbiAqIHRoZSBjZWxsJ3Mgb3duIChkYXRhIHVuaXRzKSwgc28gem9vbWVkIG91dCBvdmVyIGEgd2hvbGUgQ3l0b3MgcGxhdGUgb3IgWGVuaXVtIHNlY3Rpb24gZXZlcnkgY2VsbFxuICogZmVsbCBiZWxvdyBhIHBpeGVsIGFuZCB0aGUgb2JzZXJ2YXRpb25zIHZhbmlzaGVkOyB3aXRoIHRoZSBmbG9vciB0aGV5IHN0YXkgYSBkZW5zZSBmaWVsZCBvZlxuICogZG90cywgY29sb3VyZWQgYXMgdGhleSBhcmUsIGF0IGV2ZXJ5IHpvb20gKHRoZSBHUFUgYXBwbGllcyBpdCBwZXIgZnJhbWU6IG5vIHJlYnVpbGQgb24gem9vbSkuXG4gKi9cbmV4cG9ydCBjb25zdCBTUEFUSUFMX01BUktFUl9NSU5fU0NSRUVOX1BYID0gMjtcbi8qKiBMb25nZXN0IHNpZGUgb2YgdGhlIGdlbmUtbWFwIHJhc3RlciwgaW4gZmllbGQgcGl4ZWxzLiBBIGdlbmUgbWFwIGlzIGEgc21vb3RoXG4gKiAgZmllbGQgcmVhZCBhcyB0ZXJyaXRvcnksIHNvIGl0IGdhaW5zIG5vdGhpbmcgZnJvbSBtYXRjaGluZyBhIDIgR3B4IHNsaWRlJ3NcbiAqICByZXNvbHV0aW9uIOKAlCBhbmQgdGhlIGVzdGltYXRlIGNvc3RzIG9uZSBwYXNzIG92ZXIgdGhpcyBtYW55IHBpeGVscy4gKi9cbmV4cG9ydCBjb25zdCBHRU5FX01BUF9NQVhfU0lERSA9IDUxMjtcbi8qKiBLZXJuZWwgz4MgaW4gZmllbGQgcGl4ZWxzIGF0IHNtb290aGluZyAxOiB3aWRlIGVub3VnaCB0byByZWFkIGJldHdlZW4gY2VsbHMsXG4gKiAgdGlnaHQgZW5vdWdoIHRvIGtlZXAgYSBudWNsZXVzLXNjYWxlIHN0cnVjdHVyZSBkaXN0aW5jdC4gKi9cbmV4cG9ydCBjb25zdCBHRU5FX01BUF9TSUdNQSA9IDIuNTtcbi8qKlxuICogSW4tcGxhbmUgY29hcnNlbmluZyBvZiB0aGUgM0QgZ2VuZSBtYXAncyBsYXR0aWNlLCByZWxhdGl2ZSB0byB0aGUgcmVmZXJlbmNlXG4gKiB2b2x1bWUuIFRoZSBmaWVsZCBpcyBzbW9vdGgsIHNvIGl0cyBkZXRhaWwgaXMgc2V0IGJ5IHRoZSBrZXJuZWwgcmF0aGVyIHRoYW4gdGhlXG4gKiByYXN0ZXIg4oCUIGFuZCB0aGUgZXN0aW1hdGUgaXMgYSBwYWlyIG9mIHNlcGFyYWJsZSBibHVycywgd2hpY2ggYXQgdGhlIHRlbXBsYXRlJ3NcbiAqIGZ1bGwgcmVzb2x1dGlvbiBtZWFucyBzZWNvbmRzIG9mIHdvcmsgcGVyIHRvZ2dsZS5cbiAqL1xuZXhwb3J0IGNvbnN0IEdFTkVfTUFQX1ZPTFVNRV9TVFJJREUgPSAyO1xuLyoqIENsdXN0ZXJzIGRyYXduIGFzIGRlbnNpdHkgdm9sdW1lcyBhdCBvbmNlLiBQYXN0IGEgaGFuZGZ1bCwgYWRkaXRpdmUgdHJhbnNsdWNlbnRcbiAqICBjbG91ZHMgc3RvcCBiZWluZyBzZXBhcmFibGUgYnkgZXllIOKAlCBhbmQgZWFjaCBvbmUgaXMgYSBmdWxsIHJhc3RlcmlzYXRpb24uICovXG5leHBvcnQgY29uc3QgREVOU0lUWV9NQVhfQ0xVU1RFUlMgPSA2O1xuLyoqIEhvdyBtdWNoIGxhcmdlciBhIHNlbGVjdGVkIG1hcmtlciBpcyBkcmF3biwgc28gYSBzbWFsbCBzZWxlY3Rpb24gaXMgZmluZGFibGUgaW5zaWRlIGFcbiAqICAzLjdNLXBvaW50IGNsb3VkIHJhdGhlciB0aGFuIG1lcmVseSBicmlnaHRlci4gKi9cbmV4cG9ydCBjb25zdCBTUEFUSUFMX1NFTEVDVEVEX1NJWkVfU0NBTEUgPSAxLjY7XG4vKiogQmFzZSBtYXJrZXIgZGlhbWV0ZXIgZm9yIHRoZSAzRCBjbG91ZCwgaW4gU0NSRUVOIHBpeGVscyAodGhlIGxheWVyJ3MgdW5pdCkuICovXG5leHBvcnQgY29uc3QgU1BBVElBTF8zRF9CQVNFX1NJWkUgPSAzO1xuXG4vKiogQ29sb3VyIGZvciBvYnNlcnZhdGlvbnMgd2hlbiBub3RoaW5nIGlzIHNlbGVjdGVkIHRvIGNvbG91ciBieTogdmlzaWJsZSwgbmV1dHJhbCwgYW5kXG4gKiAgb2J2aW91c2x5IG5vdCBlbmNvZGluZyBhbnl0aGluZy4gKi9cbmV4cG9ydCBjb25zdCBTUEFUSUFMX05FVVRSQUxfQ09MT1I6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzAuMzUsIDAuNzIsIDAuOTUsIDAuOV07XG4vKioge0BsaW5rIFNQQVRJQUxfTkVVVFJBTF9DT0xPUn0gYXMgYSBoZXggY29sb3VyIChhbHBoYSBkcm9wcGVkKSwgZm9yIHRoZSBlbmNvZGVycyBhbmQgdGhlXG4gKiAgZGVuc2l0eS12b2x1bWUgdGludC4gKi9cbmV4cG9ydCBjb25zdCBTUEFUSUFMX05FVVRSQUxfSEVYID0gYCMke1NQQVRJQUxfTkVVVFJBTF9DT0xPUi5zbGljZSgwLCAzKVxuICAubWFwKChjKSA9PlxuICAgIE1hdGgucm91bmQoYyAqIDI1NSlcbiAgICAgIC50b1N0cmluZygxNilcbiAgICAgIC5wYWRTdGFydCgyLCAnMCcpLFxuICApXG4gIC5qb2luKCcnKX1gO1xuXG4vKipcbiAqIENvbnRyYXN0IHdpbmRvd3MgbWVtb2lzZWQgcGVyICh2YWx1ZXMgYXJyYXksIGxvLCBoaSwgbG9nKS4gYGNvbnRyYXN0V2luZG93YCBzb3J0cyBldmVyeSB2YWx1ZSxcbiAqIGFuZCB0aGUgc3BhdGlhbCBjb2xvdXJpbmcgcmUtcnVucyBpdCBvbiBlYWNoIG9wYWNpdHksIHNlbGVjdGlvbiBvciBjb2xvcm1hcCBjaGFuZ2Ugd2hpbGUgdGhlXG4gKiBjb2xvdXJlZCB2ZWN0b3IgaXRzZWxmIGlzIHVuY2hhbmdlZCAocmV2aWV3IFNQQVRJQUwtMTIpLiBLZXllZCBieSB0aGUgdmVjdG9yJ3MgaWRlbnRpdHksIHNvIGFcbiAqIG5ldyBjb2x1bW4gb3IgZ2VuZSB2ZWN0b3IgaXMgYSBtaXNzIGFuZCBhbiBvbGQgb25lIGlzIGNvbGxlY3RlZCB3aXRoIGl0cyB3aW5kb3dzLlxuICovXG5leHBvcnQgY2xhc3MgQ29udHJhc3RXaW5kb3dDYWNoZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgYnlWZWN0b3IgPSBuZXcgV2Vha01hcDxGbG9hdDMyQXJyYXksIE1hcDxzdHJpbmcsIFtudW1iZXIsIG51bWJlcl0+PigpO1xuXG4gIGdldChcbiAgICB2YWx1ZXM6IEZsb2F0MzJBcnJheSxcbiAgICBsbzogbnVtYmVyLFxuICAgIGhpOiBudW1iZXIsXG4gICAgbG9nOiBib29sZWFuLFxuICAgIGNvbXB1dGU6ICgpID0+IFtudW1iZXIsIG51bWJlcl0sXG4gICk6IFtudW1iZXIsIG51bWJlcl0ge1xuICAgIGxldCB3aW5kb3dzID0gdGhpcy5ieVZlY3Rvci5nZXQodmFsdWVzKTtcbiAgICBpZiAoIXdpbmRvd3MpIHtcbiAgICAgIHdpbmRvd3MgPSBuZXcgTWFwKCk7XG4gICAgICB0aGlzLmJ5VmVjdG9yLnNldCh2YWx1ZXMsIHdpbmRvd3MpO1xuICAgIH1cbiAgICBjb25zdCBrZXkgPSBgJHtsb318JHtoaX18JHtsb2cgPyAxIDogMH1gO1xuICAgIGxldCB3ID0gd2luZG93cy5nZXQoa2V5KTtcbiAgICBpZiAoIXcpIHtcbiAgICAgIHcgPSBjb21wdXRlKCk7XG4gICAgICB3aW5kb3dzLnNldChrZXksIHcpO1xuICAgIH1cbiAgICByZXR1cm4gdztcbiAgfVxufVxuXG4vKipcbiAqIFdoYXQgdGhlIDNEIHBvaW50cyBsYXllciBuZWVkcyB0byBjb2xvdXIgYSBjbG91ZDogZm9yIGNvbnRpbnVvdXMgZGF0YSwgb25lIHNjYWxhciBwZXIgcG9pbnQsIGFcbiAqIGNvbG9ybWFwIGFuZCB0aGUgd2luZG93IHRoYXQgbWFwcyBzY2FsYXJzIG9udG8gaXQ7IGZvciBjYXRlZ29yaWNhbCBkYXRhLCBvbmUgcGFja2VkIFJHQkEgcGVyXG4gKiBwb2ludCAoYFBvaW50czNETGF5ZXIuY29sb3JzYCwgd2hpY2ggd2lucyBvdmVyIHRoZSBzY2FsYXJzKS5cbiAqL1xuZXhwb3J0IHR5cGUgU3BhdGlhbDNkRW5jb2RpbmcgPSBTcGF0aWFsM2RTY2FsYXJzIHwgU3BhdGlhbDNkQ29sb3JzO1xuXG4vKiogQSBjbG91ZCBjb2xvdXJlZCB0aHJvdWdoIHRoZSBjb2xvcm1hcDogc2NhbGFycywgY29sb3JtYXAgYW5kIHdpbmRvdy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3BhdGlhbDNkU2NhbGFycyB7XG4gIGtpbmQ6ICdzY2FsYXJzJztcbiAgdmFsdWVzOiBGbG9hdDMyQXJyYXk7XG4gIGNvbG9ybWFwOiBDb2xvcm1hcDtcbiAgY29udHJhc3RMaW1pdHM6IFtudW1iZXIsIG51bWJlcl07XG59XG5cbi8qKiBBIGNsb3VkIGNvbG91cmVkIHBvaW50IGJ5IHBvaW50OiBwYWNrZWQgUkdCQSwgNCBmbG9hdHMgcGVyIHBvaW50LiAqL1xuZXhwb3J0IGludGVyZmFjZSBTcGF0aWFsM2RDb2xvcnMge1xuICBraW5kOiAnY29sb3JzJztcbiAgY29sb3JzOiBGbG9hdDMyQXJyYXk7XG59XG5cbi8qKiBBIG9uZS1jb2xvdXIgY29sb3JtYXAsIGZvciB0aGUgXCJub3RoaW5nIHRvIGNvbG91ciBieVwiIHN0YXRlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNwYXRpYWxGbGF0Q29sb3JtYXAoKTogQ29sb3JtYXAge1xuICBjb25zdCBbciwgZywgYl0gPSBTUEFUSUFMX05FVVRSQUxfQ09MT1I7XG4gIGNvbnN0IHJnYjogUmdiID0gW01hdGgucm91bmQociAqIDI1NSksIE1hdGgucm91bmQoZyAqIDI1NSksIE1hdGgucm91bmQoYiAqIDI1NSldO1xuICAvLyBUd28gaWRlbnRpY2FsIHN0b3BzOiBjb2xvcm1hcEZyb21MdXQgbmVlZHMgYXQgbGVhc3QgdHdvLCBhbmQgZXF1YWwgZW5kc1xuICAvLyBtYWtlIGV2ZXJ5IHZhbHVlIHJlc29sdmUgdG8gdGhlIHNhbWUgY29sb3VyLlxuICByZXR1cm4gY29sb3JtYXBGcm9tTHV0KCdzcGF0aWFsLWZsYXQnLCBbcmdiLCByZ2JdKTtcbn1cblxuLyoqXG4gKiBDYXRlZ29yeSBjb2RlcyDihpIgb25lIFJHQkEgcGVyIHBvaW50LCBmb3IgYW55IG51bWJlciBvZiBjYXRlZ29yaWVzLlxuICpcbiAqIFRoZSAyRCBtYXJrZXJzJyBlbmNvZGluZywgd2l0aCBvbmUgZGlmZmVyZW5jZTogYSBwb2ludCB3aXRoIG5vIGNhdGVnb3J5IHN0YXlzIG9wYXF1ZSAoZ3JleSksXG4gKiBhcyBpdCBhbHdheXMgaGFzIGluIHRoZSBjbG91ZCwgd2hlcmUgdGhlIHNlbGVjdGlvbiBkaW1zIHRocm91Z2ggdGhlIGxheWVyJ3MgcGVyLXBvaW50IGFscGhhc1xuICogaW5zdGVhZC4gSXQgdXNlZCB0byBiZSBzbXVnZ2xlZCB0aHJvdWdoIHRoZSBzY2FsYXIgY2hhbm5lbCBhcyBhIHN0ZXBwZWQgMjU2LWVudHJ5IExVVCwgd2hpY2hcbiAqIGtlcHQgYXQgbW9zdCA5NSBjYXRlZ29yaWVzIGFwYXJ0IChyZXZpZXcgU1BBVElBTC0xMSwgTkFQQVJJLVNWQy0xOCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbmNvZGVTcGF0aWFsM2RDYXRlZ29yaWNhbChjb2RlczogVWludDE2QXJyYXksIGNvbG9yczogc3RyaW5nW10pOiBTcGF0aWFsM2RDb2xvcnMge1xuICByZXR1cm4geyBraW5kOiAnY29sb3JzJywgY29sb3JzOiBlbmNvZGVDYXRlZ29yaWNhbChjb2RlcywgeyBjb2xvcnMsIG11dGVkT3BhY2l0eTogMSB9KSB9O1xufVxuXG4vKiogQ29udGludW91cyB2YWx1ZXMg4oaSIGBsdXRgIG92ZXIgYSBwZXJjZW50aWxlLWNsaXBwZWQgd2luZG93IChsb2cxcCBmaXJzdCB3aGVuIHRoZSB2aWV3J3MgbG9nXG4gKiAgc2NhbGUgaXMgb24pLCBmb3IgdGhlIDNEIGNsb3VkJ3Mgc2NhbGFyIGNoYW5uZWwuICovXG5leHBvcnQgZnVuY3Rpb24gZW5jb2RlU3BhdGlhbDNkQ29udGludW91cyhcbiAgc291cmNlOiBGbG9hdDMyQXJyYXksXG4gIHZpZXc6IFNwYXRpYWxWaWV3U3RhdGUsXG4gIGx1dDogUmdiW10sXG4gIHdpbmRvd3M6IENvbnRyYXN0V2luZG93Q2FjaGUsXG4pOiBTcGF0aWFsM2RTY2FsYXJzIHtcbiAgY29uc3QgW2xvLCBoaV0gPSB2aWV3LnBlcmNlbnRpbGVDbGlwID8/IFswLjAxLCAwLjk5XTtcbiAgY29uc3QgbG9nID0gISF2aWV3LmxvZ1NjYWxlO1xuICBsZXQgdmFsdWVzID0gc291cmNlO1xuICBpZiAobG9nKSB7XG4gICAgdmFsdWVzID0gbmV3IEZsb2F0MzJBcnJheShzb3VyY2UubGVuZ3RoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNvdXJjZS5sZW5ndGg7IGkrKykgdmFsdWVzW2ldID0gTWF0aC5sb2cxcChNYXRoLm1heCgwLCBzb3VyY2VbaV0pKTtcbiAgfVxuICAvLyBLZXllZCBieSB0aGUgU09VUkNFIHZlY3RvcjogdGhlIGxvZyBjb3B5IGFib3ZlIGlzIG5ldyBvbiBldmVyeSBjYWxsLlxuICBjb25zdCBbbWluLCBtYXhdID0gd2luZG93cy5nZXQoc291cmNlLCBsbywgaGksIGxvZywgKCkgPT4gY29udHJhc3RXaW5kb3codmFsdWVzLCBsbywgaGkpKTtcbiAgcmV0dXJuIHtcbiAgICBraW5kOiAnc2NhbGFycycsXG4gICAgdmFsdWVzLFxuICAgIGNvbG9ybWFwOiBjb2xvcm1hcEZyb21MdXQoJ3NwYXRpYWwtY29udGludW91cycsIGx1dCksXG4gICAgLy8gQSBkZWdlbmVyYXRlIHdpbmRvdyB3b3VsZCBkaXZpZGUgYnkgemVybyBpbiB0aGUgc2hhZGVyJ3Mgbm9ybWFsaXNhdGlvbi5cbiAgICBjb250cmFzdExpbWl0czogbWF4ID4gbWluID8gW21pbiwgbWF4XSA6IFttaW4sIG1pbiArIDFdLFxuICB9O1xufVxuXG4vKiogQ29udGludW91cyB2YWx1ZXMg4oaSIHBlci1wb2ludCBSR0JBIHRocm91Z2ggYGx1dGAgYW5kIGEgY2xpcHBlZCB3aW5kb3cgKGxvZyBzY2FsZSBwZXIgdGhlXG4gKiAgdmlldyksIGZvciB0aGUgMkQgbWFya2Vycy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbmNvZGVTcGF0aWFsQ29udGludW91cyhcbiAgdmFsdWVzOiBGbG9hdDMyQXJyYXksXG4gIHZpZXc6IFNwYXRpYWxWaWV3U3RhdGUsXG4gIGx1dDogUmdiW10sXG4gIHdpbmRvd3M6IENvbnRyYXN0V2luZG93Q2FjaGUsXG4gIG11dGVkOiBVaW50OEFycmF5IHwgbnVsbCA9IG51bGwsXG4pOiBGbG9hdDMyQXJyYXkge1xuICBjb25zdCBbbG8sIGhpXSA9IHZpZXcucGVyY2VudGlsZUNsaXAgPz8gWzAuMDEsIDAuOTldO1xuICAvLyBUaGUgd2luZG93IGlzIHRha2VuIG9uIHRoZSByYXcgdmFsdWVzIChlbmNvZGVDb250aW51b3VzIGFwcGxpZXMgdGhlIGxvZyBpdHNlbGYpLlxuICBjb25zdCBbbWluLCBtYXhdID0gd2luZG93cy5nZXQodmFsdWVzLCBsbywgaGksIGZhbHNlLCAoKSA9PiBjb250cmFzdFdpbmRvdyh2YWx1ZXMsIGxvLCBoaSkpO1xuICByZXR1cm4gZW5jb2RlQ29udGludW91cyh2YWx1ZXMsIHtcbiAgICBsdXQsXG4gICAgbWluLFxuICAgIG1heCxcbiAgICBsb2c6IHZpZXcubG9nU2NhbGUsXG4gICAgb3BhY2l0eTogdmlldy5vcGFjaXR5LFxuICAgIG11dGVkLFxuICB9KTtcbn1cblxuLyoqIE1hcmtlciBjb2xvdXJzOiBwYWNrZWQgcGVyLXBvaW50IFJHQkEgKDQgZmxvYXRzIHBlciBwb2ludCwgdGhlIHNoYXBlIG5hcGFyaS1qcyBjb3BpZXMgc3RyYWlnaHRcbiAqICBpbnRvIGl0cyBpbnN0YW5jZSBidWZmZXIpLCBvciBvbmUgUkdCQSBicm9hZGNhc3QgdG8gZXZlcnkgcG9pbnQuICovXG5leHBvcnQgdHlwZSBQb2ludENvbG9ycyA9IEZsb2F0MzJBcnJheSB8IFJHQkE7XG5cbi8qKiBXaGV0aGVyIGEgY29sb3VyIGlucHV0IGlzIG9uZSBSR0JBIHBlciBwb2ludCByYXRoZXIgdGhhbiBvbmUgYnJvYWRjYXN0IFJHQkEuICovXG5leHBvcnQgZnVuY3Rpb24gaXNQZXJQb2ludChjb2xvcnM6IFBvaW50Q29sb3JzKTogY29sb3JzIGlzIEZsb2F0MzJBcnJheSB7XG4gIHJldHVybiBjb2xvcnMgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXk7XG59XG5cbi8qKlxuICogYGNvbG9yc2Agd2l0aCBldmVyeSBvYnNlcnZhdGlvbiBgc2hvd25gIGxlYXZlcyBhdCAwIG1hZGUgdHJhbnNwYXJlbnQ6IHRoZSBvYnNlcnZhdGlvbnMgYSBnZW5lXG4gKiBmaWx0ZXIgbGVhdmVzIG91dC4gQSBicm9hZGNhc3QgY29sb3VyIGJlY29tZXMgcGVyLXBvaW50LCBzaW5jZSB0aGUgcG9pbnRzIG5vdyBkaWZmZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoaWRlVW5zaG93bihjb2xvcnM6IFBvaW50Q29sb3JzLCBzaG93bjogVWludDhBcnJheSk6IEZsb2F0MzJBcnJheSB7XG4gIGNvbnN0IGNvdW50ID0gc2hvd24ubGVuZ3RoO1xuICBsZXQgb3V0OiBGbG9hdDMyQXJyYXk7XG4gIGlmIChpc1BlclBvaW50KGNvbG9ycykpIHtcbiAgICBvdXQgPSBjb2xvcnMuc2xpY2UoKTsgLy8gdGhlIGlucHV0IG1heSBiZSBoZWxkIGVsc2V3aGVyZVxuICB9IGVsc2Uge1xuICAgIG91dCA9IG5ldyBGbG9hdDMyQXJyYXkoY291bnQgKiA0KTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvdW50OyBpKyspIG91dC5zZXQoY29sb3JzLCBpICogNCk7XG4gIH1cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSBpZiAoIXNob3duW2ldKSBvdXRbNCAqIGkgKyAzXSA9IDA7XG4gIHJldHVybiBvdXQ7XG59XG5cbi8qKiBQZXItcG9pbnQgY29sb3VycyBmb3IgdGhlIGRyYXduIHN1YnNldC4gQSBicm9hZGNhc3QgdHVwbGUgc3RheXMgYnJvYWRjYXN0IOKAlFxuICogIGl0IGlzIG9uZSBjb2xvdXIgZm9yIGV2ZXJ5IHBvaW50IGVpdGhlciB3YXkuICovXG5leHBvcnQgZnVuY3Rpb24gZ2F0aGVyQ29sb3JzKGNvbG9yczogUG9pbnRDb2xvcnMsIGluZGljZXM/OiBVaW50MzJBcnJheSk6IFBvaW50Q29sb3JzIHtcbiAgaWYgKCFpbmRpY2VzIHx8ICFpc1BlclBvaW50KGNvbG9ycykpIHJldHVybiBjb2xvcnM7XG4gIGNvbnN0IG91dCA9IG5ldyBGbG9hdDMyQXJyYXkoaW5kaWNlcy5sZW5ndGggKiA0KTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbmRpY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgcyA9IGluZGljZXNbaV0gKiA0O1xuICAgIGNvbnN0IG8gPSBpICogNDtcbiAgICBvdXRbb10gPSBjb2xvcnNbc107XG4gICAgb3V0W28gKyAxXSA9IGNvbG9yc1tzICsgMV07XG4gICAgb3V0W28gKyAyXSA9IGNvbG9yc1tzICsgMl07XG4gICAgb3V0W28gKyAzXSA9IGNvbG9yc1tzICsgM107XG4gIH1cbiAgcmV0dXJuIG91dDtcbn1cblxuLyoqIE9uZSBkZW5zaXR5IHZvbHVtZSdzIG9ic2VydmF0aW9uczogYSBjbHVzdGVyIChvciBhbGwgY2VsbHMpLCB3aXRoIGl0cyBsZWdlbmQgY29sb3VyLiAqL1xuZXhwb3J0IGludGVyZmFjZSBEZW5zaXR5R3JvdXAge1xuICBuYW1lOiBzdHJpbmc7XG4gIGNvbG9yOiBzdHJpbmc7XG4gIGluZGljZXM/OiBVaW50MzJBcnJheTtcbn1cblxuLyoqIFRoZSBzaW5nbGUgZ3JvdXAgZHJhd24gd2hlbiB0aGUgY29sb3VyaW5nIGlzIG5vdCBjYXRlZ29yaWNhbDogdG90YWwgY2VsbCBkZW5zaXR5LCB3aXRoaW4gdGhlXG4gKiAgc2VsZWN0aW9uIHdoZW4gdGhlcmUgaXMgb25lLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvdGFsRGVuc2l0eUdyb3VwKHNlbGVjdGlvbjogU3BhdGlhbFNlbGVjdGlvbk1hc2spOiBEZW5zaXR5R3JvdXAge1xuICBjb25zdCBpblNlbGVjdGlvbiA9IHNlbGVjdGlvbi5jb3VudCA+IDAgPyBzZWxlY3Rpb24ubWFzayA6IG51bGw7XG4gIHJldHVybiB7XG4gICAgbmFtZTogaW5TZWxlY3Rpb24gPyAnc2VsZWN0ZWQgY2VsbHMnIDogJ2FsbCBjZWxscycsXG4gICAgY29sb3I6IFNQQVRJQUxfTkVVVFJBTF9IRVgsXG4gICAgaW5kaWNlczogaW5TZWxlY3Rpb24gPyBtYXNrVG9JbmRpY2VzKGluU2VsZWN0aW9uKSA6IHVuZGVmaW5lZCxcbiAgfTtcbn1cblxuLyoqXG4gKiBUaGUgY2x1c3RlcnMgb2YgYSBjYXRlZ29yaWNhbCBjb2x1bW4gdG8gcmFzdGVyaXNlLCBiaWdnZXN0IGZpcnN0IGFuZCBjYXBwZWQgYXRcbiAqIHtAbGluayBERU5TSVRZX01BWF9DTFVTVEVSU30sIGVhY2ggd2l0aCBpdHMgbGVnZW5kIGNvbG91ciDigJQgcmVzdHJpY3RlZCB0byB0aGUgc2VsZWN0aW9uIHdoZW5cbiAqIHRoZXJlIGlzIG9uZSwgc28gXCJzZWxlY3QgYSByZWdpb24sIGNoZWNrIHRoZSBib3hcIiBhbnN3ZXJzIHdoaWNoIGNsdXN0ZXJzIGxpdmUgdGhlcmUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByYW5rRGVuc2l0eUdyb3VwcyhcbiAgY29sdW1uTmFtZTogc3RyaW5nLFxuICBjb2x1bW46IENhdGVnb3JpY2FsQ29sdW1uLFxuICBjb3VudDogbnVtYmVyLFxuICBzZWxlY3Rpb246IFNwYXRpYWxTZWxlY3Rpb25NYXNrLFxuICBncm91cENvbG9ycz86IEdyb3VwQ29sb3JPdmVycmlkZXMgfCBudWxsLFxuKTogRGVuc2l0eUdyb3VwW10ge1xuICBjb25zdCBpblNlbGVjdGlvbiA9IHNlbGVjdGlvbi5jb3VudCA+IDAgPyBzZWxlY3Rpb24ubWFzayA6IG51bGw7XG4gIGNvbnN0IGNvbG9ycyA9IGNhdGVnb3J5Q29sb3JzRm9yKGNvbHVtbk5hbWUsIGNvbHVtbi5tZXRhLCBncm91cENvbG9ycyk7XG4gIGNvbnN0IGNvdW50cyA9IG5ldyBVaW50MzJBcnJheShjb2x1bW4ubWV0YS5jYXRlZ29yaWVzLmxlbmd0aCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICAgIGlmIChpblNlbGVjdGlvbiAmJiAhaW5TZWxlY3Rpb25baV0pIGNvbnRpbnVlO1xuICAgIGNvbnN0IGNvZGUgPSBjb2x1bW4uY29kZXNbaV07XG4gICAgaWYgKGNvZGUgIT09IE5PX0NBVEVHT1JZICYmIGNvZGUgPCBjb3VudHMubGVuZ3RoKSBjb3VudHNbY29kZV0rKztcbiAgfVxuICBjb25zdCByYW5rZWQgPSBBcnJheS5mcm9tKGNvdW50cywgKG4sIGNvZGUpID0+ICh7IGNvZGUsIG4gfSkpXG4gICAgLmZpbHRlcigoYykgPT4gYy5uID4gMClcbiAgICAuc29ydCgoYSwgYikgPT4gYi5uIC0gYS5uKVxuICAgIC5zbGljZSgwLCBERU5TSVRZX01BWF9DTFVTVEVSUyk7XG4gIGlmIChjb3VudHMuZmlsdGVyKChjKSA9PiBjID4gMCkubGVuZ3RoID4gcmFua2VkLmxlbmd0aCkge1xuICAgIGNvbnNvbGUud2FybihcbiAgICAgIGBbbmFwYXJpLWpzXSAke2NvbHVtbk5hbWV9OiBkcmF3aW5nIHRoZSAke3JhbmtlZC5sZW5ndGh9IGxhcmdlc3QgY2x1c3RlcnMgYXMgZGVuc2l0eSBgICtcbiAgICAgICAgJ3ZvbHVtZXM7IG1vcmUgdGhhbiB0aGF0IHN0b3AgYmVpbmcgc2VwYXJhYmxlIGJ5IGV5ZScsXG4gICAgKTtcbiAgfVxuICByZXR1cm4gcmFua2VkLm1hcCgoeyBjb2RlIH0pID0+IHtcbiAgICBjb25zdCBpbmRpY2VzID0gbmV3IFVpbnQzMkFycmF5KGNvdW50c1tjb2RlXSk7XG4gICAgbGV0IGsgPSAwO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICAgICAgaWYgKGluU2VsZWN0aW9uICYmICFpblNlbGVjdGlvbltpXSkgY29udGludWU7XG4gICAgICBpZiAoY29sdW1uLmNvZGVzW2ldID09PSBjb2RlKSBpbmRpY2VzW2srK10gPSBpO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgbmFtZTogY29sdW1uLm1ldGEuY2F0ZWdvcmllc1tjb2RlXSxcbiAgICAgIGNvbG9yOiBjb2xvcnNbY29kZV0gPz8gJyM4ODg4ODgnLFxuICAgICAgaW5kaWNlczogaW5kaWNlcy5zdWJhcnJheSgwLCBrKSxcbiAgICB9O1xuICB9KTtcbn1cbiJdfQ==
|