@jax-data-science/sci-image-visualizer 0.17.0 → 0.18.1

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.
Files changed (121) hide show
  1. package/esm2022/lib/contracts/display-types.mjs +3 -2
  2. package/esm2022/lib/contracts/image.contract.mjs +1 -1
  3. package/esm2022/lib/contracts/ports/spatial-data.port.mjs +1 -1
  4. package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
  5. package/esm2022/lib/contracts/region-store.contract.mjs +1 -1
  6. package/esm2022/lib/contracts/spatial-dataset.contract.mjs +1 -1
  7. package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
  8. package/esm2022/lib/geometry/cell-meshes.mjs +37 -0
  9. package/esm2022/lib/geometry/place.mjs +47 -0
  10. package/esm2022/lib/implementations/napari-js/napari-camera-depth.mjs +93 -0
  11. package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +1 -1
  12. package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +2 -2
  13. package/esm2022/lib/implementations/napari-js/napari-scene.mjs +1 -1
  14. package/esm2022/lib/implementations/napari-js/napari-spatial-2d-scene.mjs +81 -15
  15. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-cells.mjs +746 -0
  16. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +325 -18
  17. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-transcripts.mjs +182 -24
  18. package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +95 -5
  19. package/esm2022/lib/implementations/napari-js/napari-spatial-scene.mjs +15 -1
  20. package/esm2022/lib/implementations/napari-js/napari-spatial-tiles.mjs +30 -2
  21. package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +40 -1
  22. package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +111 -28
  23. package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +14 -2
  24. package/esm2022/lib/implementations/napari-js/spatial-tiles/cell-layers.mjs +180 -48
  25. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-layers.mjs +28 -8
  26. package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +2 -2
  27. package/esm2022/lib/implementations/spatial-data-http/spatial-data-http.service.mjs +10 -1
  28. package/esm2022/lib/region-editor/class-tree/class-tree.component.mjs +30 -3
  29. package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +15 -3
  30. package/esm2022/lib/region-editor/region-editor.component.mjs +24 -4
  31. package/esm2022/lib/region-source/region-source-ops.mjs +7 -1
  32. package/esm2022/lib/region-source/region-tiles.mjs +1 -1
  33. package/esm2022/lib/region-source/worker-region-source.mjs +24 -1
  34. package/esm2022/lib/routing-visualizer.service.mjs +404 -7
  35. package/esm2022/lib/spatial/observations-in-selection.mjs +83 -0
  36. package/esm2022/lib/spatial/plane-cells.mjs +119 -0
  37. package/esm2022/lib/spatial/spatial-controls.facade.mjs +298 -5
  38. package/esm2022/lib/spatial/spatial-encoding.mjs +35 -3
  39. package/esm2022/lib/spatial/spatial-hover.mjs +34 -1
  40. package/esm2022/lib/spatial/spatial-planes.mjs +49 -0
  41. package/esm2022/lib/spatial/spatial-selection.mjs +2 -2
  42. package/esm2022/lib/spatial/spatial-tile-merge.mjs +38 -1
  43. package/esm2022/lib/spatial/transcripts-in-selection.mjs +208 -0
  44. package/esm2022/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.mjs +42 -65
  45. package/esm2022/lib/spatial-controls/spatial-color-by/spatial-color-by.component.mjs +187 -0
  46. package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +47 -12
  47. package/esm2022/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.mjs +3 -3
  48. package/esm2022/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.mjs +38 -10
  49. package/esm2022/lib/spatial-controls/spatial-key/spatial-key.component.mjs +3 -3
  50. package/esm2022/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.mjs +3 -3
  51. package/esm2022/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.mjs +79 -57
  52. package/esm2022/lib/spatial-controls/spatial-selection-observations/spatial-selection-observations.component.mjs +101 -0
  53. package/esm2022/lib/spatial-controls/spatial-selection-transcripts/spatial-selection-transcripts.component.mjs +94 -0
  54. package/esm2022/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.mjs +9 -3
  55. package/esm2022/lib/store/region-source-scope.mjs +10 -1
  56. package/esm2022/lib/store/region-store.service.mjs +33 -2
  57. package/esm2022/lib/toolbar/toolbar.component.mjs +10 -3
  58. package/esm2022/lib/visualizer/spatial-region-set.mjs +95 -0
  59. package/esm2022/lib/visualizer.component.mjs +40 -4
  60. package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DHrHO2ay.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-YrNqv8wH.mjs} +4521 -759
  61. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-YrNqv8wH.mjs.map +1 -0
  62. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-CKEUwNta.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-Dph35S7m.mjs} +2 -2
  63. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-CKEUwNta.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-Dph35S7m.mjs.map} +1 -1
  64. package/fesm2022/jax-data-science-sci-image-visualizer.mjs +1 -1
  65. package/fesm2022/region-source.worker.js +84 -2
  66. package/lib/contracts/display-types.d.ts +90 -4
  67. package/lib/contracts/image.contract.d.ts +6 -0
  68. package/lib/contracts/ports/spatial-data.port.d.ts +7 -0
  69. package/lib/contracts/region-editor-api.contract.d.ts +9 -0
  70. package/lib/contracts/region-store.contract.d.ts +6 -0
  71. package/lib/contracts/spatial-dataset.contract.d.ts +7 -1
  72. package/lib/contracts/visualizer.contract.d.ts +43 -1
  73. package/lib/geometry/cell-meshes.d.ts +27 -0
  74. package/lib/geometry/place.d.ts +45 -0
  75. package/lib/implementations/napari-js/napari-camera-depth.d.ts +23 -0
  76. package/lib/implementations/napari-js/napari-loading-state.d.ts +1 -1
  77. package/lib/implementations/napari-js/napari-scene.d.ts +12 -0
  78. package/lib/implementations/napari-js/napari-spatial-2d-scene.d.ts +19 -3
  79. package/lib/implementations/napari-js/napari-spatial-3d-cells.d.ts +141 -0
  80. package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +87 -0
  81. package/lib/implementations/napari-js/napari-spatial-3d-transcripts.d.ts +49 -8
  82. package/lib/implementations/napari-js/napari-spatial-hover.d.ts +22 -0
  83. package/lib/implementations/napari-js/napari-spatial-scene.d.ts +12 -0
  84. package/lib/implementations/napari-js/napari-spatial-tiles.d.ts +15 -0
  85. package/lib/implementations/napari-js/napari-visualizer.service.d.ts +27 -1
  86. package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +38 -19
  87. package/lib/implementations/napari-js/napari-volume-scene.d.ts +2 -0
  88. package/lib/implementations/napari-js/spatial-tiles/cell-layers.d.ts +53 -0
  89. package/lib/implementations/napari-js/spatial-tiles/transcript-layers.d.ts +11 -2
  90. package/lib/implementations/spatial-data-http/spatial-data-http.service.d.ts +7 -0
  91. package/lib/region-editor/class-tree/class-tree.component.d.ts +16 -1
  92. package/lib/region-editor/classes-panel/classes-panel.component.d.ts +10 -1
  93. package/lib/region-editor/region-editor.component.d.ts +4 -0
  94. package/lib/region-source/region-source-ops.d.ts +12 -0
  95. package/lib/region-source/region-tiles.d.ts +8 -0
  96. package/lib/region-source/worker-region-source.d.ts +18 -0
  97. package/lib/routing-visualizer.service.d.ts +140 -1
  98. package/lib/spatial/observations-in-selection.d.ts +43 -0
  99. package/lib/spatial/plane-cells.d.ts +37 -0
  100. package/lib/spatial/spatial-controls.facade.d.ts +59 -0
  101. package/lib/spatial/spatial-encoding.d.ts +14 -1
  102. package/lib/spatial/spatial-hover.d.ts +23 -0
  103. package/lib/spatial/spatial-planes.d.ts +22 -0
  104. package/lib/spatial/spatial-selection.d.ts +2 -1
  105. package/lib/spatial/spatial-tile-merge.d.ts +9 -0
  106. package/lib/spatial/transcripts-in-selection.d.ts +95 -0
  107. package/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.d.ts +19 -28
  108. package/lib/spatial-controls/spatial-color-by/spatial-color-by.component.d.ts +64 -0
  109. package/lib/spatial-controls/spatial-controls.component.d.ts +17 -2
  110. package/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.d.ts +16 -6
  111. package/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.d.ts +26 -23
  112. package/lib/spatial-controls/spatial-selection-observations/spatial-selection-observations.component.d.ts +48 -0
  113. package/lib/spatial-controls/spatial-selection-transcripts/spatial-selection-transcripts.component.d.ts +43 -0
  114. package/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.d.ts +3 -1
  115. package/lib/store/region-source-scope.d.ts +4 -0
  116. package/lib/store/region-store.service.d.ts +21 -0
  117. package/lib/toolbar/toolbar.component.d.ts +6 -1
  118. package/lib/visualizer/spatial-region-set.d.ts +55 -0
  119. package/lib/visualizer.component.d.ts +14 -0
  120. package/package.json +1 -1
  121. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DHrHO2ay.mjs.map +0 -1
@@ -1,8 +1,10 @@
1
- import { colormapFromLut } from 'napari-js';
1
+ import { colormapFromLut, mapScalarRGBA } from 'napari-js';
2
2
  import { NO_CATEGORY, isCategoricalColumn, } from '../../../contracts/spatial-dataset.contract';
3
3
  import { DEFAULT_CATEGORICAL_PALETTE, MISSING_COLOR, categoryColorsFor, contrastWindow, parseHex, } from '../../../spatial/spatial-encoding';
4
4
  import { POLYGON_LEVEL_MIN_CELL_PX, cellTypeColumnFor, cellsShown, drawnCellSets, polygonLevelFor, tileId, tilesInRect, typicalCellDiameter, } from '../../../spatial/lod';
5
5
  import { filterRings, mergePolygonTiles } from '../../../spatial/spatial-tile-merge';
6
+ import { observationIndex, planeCellRings } from '../../../spatial/plane-cells';
7
+ import { regionLevelFor, regionTileId, regionTilesInRect } from '../../../region-source/region-tiles';
6
8
  import { geneFilterKey } from '../../../spatial/spatial-gene-filter';
7
9
  import { ContrastWindowCache } from '../napari-spatial-encoding';
8
10
  const MAX_CELL_TILES = 48;
@@ -32,11 +34,33 @@ export class CellLayers {
32
34
  /** Continuous colourings' windows, per (vector, clip, log): `contrastWindow` sorts every
33
35
  * value, and a selection or opacity change recolours with the vector unchanged (SPATIAL-12). */
34
36
  this.contrastWindows = new ContrastWindowCache();
37
+ /**
38
+ * The plane of a 3D segmentation the view shows (see {@link setPlane}), or null: every set draws
39
+ * its own tiles.
40
+ */
41
+ this.plane = null;
42
+ /** The region set opened for a boundary set's per-plane outlines: its id and the source. */
43
+ this.planeSource = null;
35
44
  }
36
45
  /** True while outlines are on screen. */
37
46
  get outlinesShown() {
38
47
  return this.polygonsShown;
39
48
  }
49
+ /**
50
+ * Show plane `plane` (an index into the region set's planes) of a 3D segmentation, or none: a
51
+ * boundary set that names its region set (`regionSource`, a cell outlined on every plane it spans)
52
+ * then draws that plane's outlines, rather than one outline per cell, so the cells follow the
53
+ * slice. Its cells keep the view's colouring, groups and selection.
54
+ */
55
+ setPlane(plane) {
56
+ this.plane = plane;
57
+ }
58
+ /** Close the region set opened for the per-plane outlines. */
59
+ dispose() {
60
+ const opened = this.planeSource;
61
+ this.planeSource = null;
62
+ void opened?.source.then((s) => s.dispose(), () => undefined);
63
+ }
40
64
  /** The viewer went away (its layers with it): the outlines are no longer shown. */
41
65
  detached() {
42
66
  this.setPolygonsShown(false);
@@ -66,7 +90,7 @@ export class CellLayers {
66
90
  if (ctx.stale())
67
91
  return;
68
92
  const label = view.cellSet === 'both' ? 'Cells and nuclei' : view.cellSet === 'nucleus' ? 'Nuclei' : 'Cells';
69
- const geometry = await ctx.track(label, this.cellGeometry(dataset, view, rect, level, hidden, ctx));
93
+ const geometry = await ctx.track(label, this.cellGeometry(dataset, view, rect, level, hidden, ctx, pxPerUnit));
70
94
  if (!geometry)
71
95
  return;
72
96
  const { rings, nuclei, geometryKey } = geometry;
@@ -75,6 +99,7 @@ export class CellLayers {
75
99
  geometryKey,
76
100
  view.cellColorMode,
77
101
  view.cellColorGene,
102
+ view.cellColorMode === 'column' ? JSON.stringify(view.colorBy) : '',
78
103
  view.cellSingleColor,
79
104
  cellTypeColumnFor(dataset, view),
80
105
  this.selectionRev(selection),
@@ -149,57 +174,19 @@ export class CellLayers {
149
174
  * for "single". A selection mutes what it leaves out.
150
175
  */
151
176
  async cellColors(dataset, view, selection, owners) {
152
- const muted = selection.count > 0 ? selection.mask : null;
153
- const mode = view.cellColorMode;
154
- if (mode === 'single') {
155
- const [r, g, b] = parseHex(view.cellSingleColor);
156
- return { color: [r / 255, g / 255, b / 255, 1] };
157
- }
158
- const continuous = async (raw, log) => {
159
- const values = new Float32Array(owners.length);
160
- for (let i = 0; i < owners.length; i++) {
161
- const v = raw[owners[i]] ?? NaN;
162
- values[i] = log ? Math.log1p(Math.max(0, v)) : v;
163
- }
164
- const [clipLo, clipHi] = view.percentileClip;
165
- // Keyed by the SOURCE vector (the log copy would be new on every call), as the 3D cloud's.
166
- const [lo, hi] = this.contrastWindows.get(raw, clipLo, clipHi, log, () => contrastWindow(log ? raw.map((v) => Math.log1p(Math.max(0, v))) : raw, clipLo, clipHi));
167
- return {
168
- values,
169
- colormap: colormapFromLut('spatial-continuous', this.host.continuousLut(view)),
170
- contrastLimits: [lo, hi],
171
- };
172
- };
173
- if (mode === 'gene' && view.cellColorGene) {
174
- return continuous(await this.port.getFeatureVector(view.cellColorGene), true);
175
- }
176
- if (mode === 'transcriptDensity' && dataset.columns.some((c) => c.name === 'transcript_density')) {
177
- const column = await this.port.getColumn('transcript_density');
178
- if (!isCategoricalColumn(column))
179
- return continuous(column.values, false);
180
- }
181
- const name = mode === 'segmentation' && dataset.columns.some((c) => c.name === 'segmentation_method')
182
- ? 'segmentation_method'
183
- : cellTypeColumnFor(dataset, view);
184
- const codes = name ? await this.lookup.codes(name) : null;
185
- const palette = categoryRgba(name, codes?.meta ?? null, view.groupColors);
186
- const missing = rgba01(MISSING_COLOR);
187
- // One RGBA per shape (napari Shapes' `face_color`): any number of categories keeps its own
188
- // colour, where a colormap band per category ran out of LUT entries past ~127.
189
- const faceColor = new Float32Array(owners.length * 4);
190
- for (let i = 0; i < owners.length; i++) {
191
- const o = owners[i];
192
- const code = !codes || (muted && !muted[o]) ? NO_CATEGORY : codes.codes[o];
193
- faceColor.set(palette[code] ?? missing, i * 4);
194
- }
195
- return { faceColor };
177
+ return cellColorsFor({
178
+ port: this.port,
179
+ lookup: this.lookup,
180
+ contrastWindows: this.contrastWindows,
181
+ continuousLut: (v) => this.host.continuousLut(v),
182
+ }, dataset, view, selection, owners);
196
183
  }
197
184
  /**
198
185
  * The cell rings (and, for "both", the nucleus rings) covering `rect` at `level`, minus
199
186
  * the hidden groups — reused when nothing that decides them changed. Null when the
200
187
  * view went stale or the dataset has no set to draw.
201
188
  */
202
- async cellGeometry(dataset, view, rect, level, hidden, ctx) {
189
+ async cellGeometry(dataset, view, rect, level, hidden, ctx, pxPerUnit = 1) {
203
190
  const tiled = dataset.polygonTiles;
204
191
  const hiddenKey = `${view.hiddenGroups.join('\u0001')}|${geneFilterKey(view)}`;
205
192
  let rings;
@@ -210,6 +197,12 @@ export class CellLayers {
210
197
  if (!drawn)
211
198
  return null;
212
199
  const { set, nucleusSet } = drawn;
200
+ const regionSource = tiled.sets.find((s) => s.name === set)?.regionSource;
201
+ if (!nucleusSet && regionSource && this.plane !== null) {
202
+ const onPlane = await this.planeGeometry(dataset, set, regionSource, rect, pxPerUnit, hidden, hiddenKey, ctx);
203
+ if (onPlane !== undefined)
204
+ return onPlane;
205
+ }
213
206
  const keys = tilesInRect(rect, level, tiled.levels, tiled.bounds, MAX_CELL_TILES);
214
207
  geometryKey = `${dataset.id}|${set}|${nucleusSet ?? ''}|${hiddenKey}|${keys.map(tileId).join(',')}`;
215
208
  if (geometryKey === this.cellGeometryKey && this.currentRings) {
@@ -244,6 +237,68 @@ export class CellLayers {
244
237
  }
245
238
  return { rings, nuclei, geometryKey };
246
239
  }
240
+ /**
241
+ * The cells of boundary set `set` on the plane shown, from its region set (`regionSource`): the
242
+ * plane's tiles meeting `rect`, at the detail the zoom calls for, each outline owned by its cell
243
+ * (by its id among the observations'), minus the hidden groups. Undefined when it cannot be drawn
244
+ * so (no observation ids to tell its cells by, no port to open the set, or a plane it has not), so
245
+ * the set's own tiles are drawn; null when the view went stale.
246
+ */
247
+ async planeGeometry(dataset, set, regionSource, rect, pxPerUnit, hidden, hiddenKey, ctx) {
248
+ const index = observationIndex(dataset.observations);
249
+ const plane = this.plane;
250
+ if (!index || plane === null || !this.port.openRegionSet)
251
+ return undefined;
252
+ let source;
253
+ try {
254
+ source = await this.openPlaneSource(regionSource);
255
+ }
256
+ catch (err) {
257
+ console.warn("[napari-js] the cells' per-plane outlines could not be opened: drawn as one per cell", err);
258
+ return undefined;
259
+ }
260
+ if (ctx.stale())
261
+ return null;
262
+ const info = source.info;
263
+ const z = info.planes[plane];
264
+ if (z === undefined)
265
+ return undefined;
266
+ // The region set's coordinates are the image's pixels: the view's rectangle and zoom in them.
267
+ const ref = dataset.imageRef;
268
+ const [sx, sy] = ref?.scale ?? [1, 1];
269
+ const [tx, ty] = ref?.translate ?? [0, 0];
270
+ const box = [
271
+ rect.x0 * sx + tx,
272
+ rect.y0 * sy + ty,
273
+ rect.x1 * sx + tx,
274
+ rect.y1 * sy + ty,
275
+ ];
276
+ const level = regionLevelFor(pxPerUnit / Math.abs(sx || 1), info.levels);
277
+ const keys = regionTilesInRect(box, level, info.tileSize, info.bounds, MAX_CELL_TILES);
278
+ const geometryKey = `${dataset.id}|${set}|plane ${plane}|${hiddenKey}|${keys.map(regionTileId).join(',')}`;
279
+ if (geometryKey === this.cellGeometryKey && this.currentRings) {
280
+ return { rings: this.currentRings, nuclei: null, geometryKey };
281
+ }
282
+ const tiles = await ctx.fetchAll(keys, (k) => source.getTile(z, k));
283
+ if (ctx.stale())
284
+ return null;
285
+ const rings = filterRings(planeCellRings(tiles, index, ref), hidden);
286
+ return { rings, nuclei: null, geometryKey };
287
+ }
288
+ /** The region set `id`, opened once (another id closes the one before). */
289
+ openPlaneSource(id) {
290
+ if (this.planeSource?.id !== id) {
291
+ this.dispose();
292
+ const source = this.port.openRegionSet(id);
293
+ this.planeSource = { id, source };
294
+ // A set that failed to open is asked for again next time.
295
+ source.catch(() => {
296
+ if (this.planeSource?.source === source)
297
+ this.planeSource = null;
298
+ });
299
+ }
300
+ return this.planeSource.source;
301
+ }
247
302
  /** Remove the cell layers and forget what they showed. */
248
303
  drop() {
249
304
  this.groups.drop('cellFill');
@@ -262,6 +317,83 @@ export class CellLayers {
262
317
  this.host.polygonsShownChanged(shown);
263
318
  }
264
319
  }
320
+ /**
321
+ * The cells' colours by their owners (`owners[i]` the observation of shape i), by the view's
322
+ * cell-colour mode (Xenium Explorer's "Cell Color"): one RGBA per shape for a grouping, values +
323
+ * colormap for a measurement, one colour for "single". A selection mutes what it leaves out. The 2D
324
+ * cell outlines and the 3D cells both colour by it.
325
+ */
326
+ export async function cellColorsFor(deps, dataset, view, selection, owners) {
327
+ const muted = selection.count > 0 ? selection.mask : null;
328
+ const mode = view.cellColorMode;
329
+ if (mode === 'single') {
330
+ const [r, g, b] = parseHex(view.cellSingleColor);
331
+ return { color: [r / 255, g / 255, b / 255, 1] };
332
+ }
333
+ const continuous = async (raw, log) => {
334
+ const values = new Float32Array(owners.length);
335
+ for (let i = 0; i < owners.length; i++) {
336
+ const v = raw[owners[i]] ?? NaN;
337
+ values[i] = log ? Math.log1p(Math.max(0, v)) : v;
338
+ }
339
+ const [clipLo, clipHi] = view.percentileClip;
340
+ // Keyed by the SOURCE vector (the log copy would be new on every call), as the 3D cloud's.
341
+ const [lo, hi] = deps.contrastWindows.get(raw, clipLo, clipHi, log, () => contrastWindow(log ? raw.map((v) => Math.log1p(Math.max(0, v))) : raw, clipLo, clipHi));
342
+ return {
343
+ values,
344
+ colormap: colormapFromLut('spatial-continuous', deps.continuousLut(view)),
345
+ contrastLimits: [lo, hi],
346
+ };
347
+ };
348
+ if (mode === 'gene' && view.cellColorGene) {
349
+ return continuous(await deps.port.getFeatureVector(view.cellColorGene), true);
350
+ }
351
+ // A measurement: the numeric column the observations are coloured by, as the markers are.
352
+ if (mode === 'column' && view.colorBy?.kind === 'column') {
353
+ const column = await deps.port.getColumn(view.colorBy.name);
354
+ if (!isCategoricalColumn(column))
355
+ return continuous(column.values, view.logScale);
356
+ }
357
+ if (mode === 'transcriptDensity' && dataset.columns.some((c) => c.name === 'transcript_density')) {
358
+ const column = await deps.port.getColumn('transcript_density');
359
+ if (!isCategoricalColumn(column))
360
+ return continuous(column.values, false);
361
+ }
362
+ const name = mode === 'segmentation' && dataset.columns.some((c) => c.name === 'segmentation_method')
363
+ ? 'segmentation_method'
364
+ : cellTypeColumnFor(dataset, view);
365
+ const codes = name ? await deps.lookup.codes(name) : null;
366
+ const palette = categoryRgba(name, codes?.meta ?? null, view.groupColors);
367
+ const missing = rgba01(MISSING_COLOR);
368
+ // One RGBA per shape (napari Shapes' `face_color`): any number of categories keeps its own
369
+ // colour, where a colormap band per category ran out of LUT entries past ~127.
370
+ const faceColor = new Float32Array(owners.length * 4);
371
+ for (let i = 0; i < owners.length; i++) {
372
+ const o = owners[i];
373
+ const code = !codes || (muted && !muted[o]) ? NO_CATEGORY : codes.codes[o];
374
+ faceColor.set(palette[code] ?? missing, i * 4);
375
+ }
376
+ return { faceColor };
377
+ }
378
+ /** {@link cellColorsFor}'s colours as one RGBA (0..1) per shape, `n` shapes. */
379
+ export function cellColorsRgba(colors, n) {
380
+ if (colors.faceColor)
381
+ return colors.faceColor;
382
+ const out = new Float32Array(n * 4);
383
+ if (colors.values && colors.colormap && colors.contrastLimits) {
384
+ const [climLo, climHi] = colors.contrastLimits;
385
+ const opts = { climLo, climHi, gamma: 1, invert: false, colormap: colors.colormap };
386
+ for (let i = 0; i < n; i++) {
387
+ const v = colors.values[i];
388
+ out.set(Number.isFinite(v) ? mapScalarRGBA(v, opts) : [0.5, 0.5, 0.5, 1], i * 4);
389
+ }
390
+ return out;
391
+ }
392
+ const c = colors.color ?? [1, 1, 1, 1];
393
+ for (let i = 0; i < n; i++)
394
+ out.set(c, i * 4);
395
+ return out;
396
+ }
265
397
  /** An 8-bit RGB as an opaque 0..1 RGBA. */
266
398
  function rgba01([r, g, b]) {
267
399
  return [r / 255, g / 255, b / 255, 1];
@@ -273,4 +405,4 @@ function categoryRgba(name, meta, overrides) {
273
405
  : [DEFAULT_CATEGORICAL_PALETTE[0]];
274
406
  return hex.map((h) => rgba01(parseHex(h)));
275
407
  }
276
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VsbC1sYXllcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2ltcGxlbWVudGF0aW9ucy9uYXBhcmktanMvc3BhdGlhbC10aWxlcy9jZWxsLWxheWVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBTTVDLE9BQU8sRUFDTCxXQUFXLEVBS1gsbUJBQW1CLEdBQ3BCLE1BQU0sNkNBQTZDLENBQUM7QUFDckQsT0FBTyxFQUNMLDJCQUEyQixFQUMzQixhQUFhLEVBRWIsaUJBQWlCLEVBQ2pCLGNBQWMsRUFDZCxRQUFRLEdBQ1QsTUFBTSxtQ0FBbUMsQ0FBQztBQUUzQyxPQUFPLEVBRUwseUJBQXlCLEVBQ3pCLGlCQUFpQixFQUNqQixVQUFVLEVBQ1YsYUFBYSxFQUNiLGVBQWUsRUFDZixNQUFNLEVBQ04sV0FBVyxFQUNYLG1CQUFtQixHQUNwQixNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFBRSxXQUFXLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUNyRixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDckUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFLakUsTUFBTSxjQUFjLEdBQUcsRUFBRSxDQUFDO0FBb0IxQjs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxPQUFPLFVBQVU7SUFjckIsWUFDbUIsSUFBcUIsRUFDckIsTUFBcUMsRUFDckMsTUFBeUIsRUFDekIsSUFBb0I7UUFIcEIsU0FBSSxHQUFKLElBQUksQ0FBaUI7UUFDckIsV0FBTSxHQUFOLE1BQU0sQ0FBK0I7UUFDckMsV0FBTSxHQUFOLE1BQU0sQ0FBbUI7UUFDekIsU0FBSSxHQUFKLElBQUksQ0FBZ0I7UUFqQi9CLGtCQUFhLEdBQUcsS0FBSyxDQUFDO1FBQzlCLDBFQUEwRTtRQUNsRSxp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QUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMvQixDQUFDO0lBRU8sZ0JBQWdCLENBQUMsS0FBYztRQUNyQyxJQUFJLEtBQUssS0FBSyxJQUFJLENBQUMsYUFBYTtZQUFFLE9BQU87UUFDekMsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7UUFDM0IsSUFBSSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN4QyxDQUFDO0NBQ0Y7QUFFRCwyQ0FBMkM7QUFDM0MsU0FBUyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBb0M7SUFDMUQsT0FBTyxDQUFDLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ3hDLENBQUM7QUFFRCxxR0FBcUc7QUFDckcsU0FBUyxZQUFZLENBQ25CLElBQW1CLEVBQ25CLElBQWtDLEVBQ2xDLFNBQTBDO0lBRTFDLE1BQU0sR0FBRyxHQUNQLElBQUksSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxhQUFhO1FBQ3pDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLFNBQVMsQ0FBQztRQUMxQyxDQUFDLENBQUMsQ0FBQywyQkFBMkIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZDLE9BQU8sR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDN0MsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNvbG9ybWFwRnJvbUx1dCB9IGZyb20gJ25hcGFyaS1qcyc7XG5pbXBvcnQgdHlwZSB7IENvbG9ybWFwLCBSR0JBIH0gZnJvbSAnbmFwYXJpLWpzJztcblxuaW1wb3J0IHR5cGUgeyBSZ2IgfSBmcm9tICcuLi8uLi8uLi9jb250cmFjdHMvY29sb3JtYXAtbHV0JztcbmltcG9ydCB0eXBlIHsgU3BhdGlhbERhdGFQb3J0IH0gZnJvbSAnLi4vLi4vLi4vY29udHJhY3RzL3BvcnRzL3NwYXRpYWwtZGF0YS5wb3J0JztcbmltcG9ydCB0eXBlIHsgU3BhdGlhbFZpZXdTdGF0ZSB9IGZyb20gJy4uLy4uLy4uL2NvbnRyYWN0cy9kaXNwbGF5LXR5cGVzJztcbmltcG9ydCB7XG4gIE5PX0NBVEVHT1JZLFxuICBTcGF0aWFsQ29sdW1uLFxuICBTcGF0aWFsRGF0YXNldCxcbiAgU3BhdGlhbFBvbHlnb25UaWxlLFxuICBTcGF0aWFsUG9seWdvbnMsXG4gIGlzQ2F0ZWdvcmljYWxDb2x1bW4sXG59IGZyb20gJy4uLy4uLy4uL2NvbnRyYWN0cy9zcGF0aWFsLWRhdGFzZXQuY29udHJhY3QnO1xuaW1wb3J0IHtcbiAgREVGQVVMVF9DQVRFR09SSUNBTF9QQUxFVFRFLFxuICBNSVNTSU5HX0NPTE9SLFxuICBHcm91cENvbG9yT3ZlcnJpZGVzLFxuICBjYXRlZ29yeUNvbG9yc0ZvcixcbiAgY29udHJhc3RXaW5kb3csXG4gIHBhcnNlSGV4LFxufSBmcm9tICcuLi8uLi8uLi9zcGF0aWFsL3NwYXRpYWwtZW5jb2RpbmcnO1xuaW1wb3J0IHsgU3BhdGlhbFNlbGVjdGlvbk1hc2sgfSBmcm9tICcuLi8uLi8uLi9zcGF0aWFsL3NwYXRpYWwtc2VsZWN0aW9uJztcbmltcG9ydCB7XG4gIERhdGFSZWN0LFxuICBQT0xZR09OX0xFVkVMX01JTl9DRUxMX1BYLFxuICBjZWxsVHlwZUNvbHVtbkZvcixcbiAgY2VsbHNTaG93bixcbiAgZHJhd25DZWxsU2V0cyxcbiAgcG9seWdvbkxldmVsRm9yLFxuICB0aWxlSWQsXG4gIHRpbGVzSW5SZWN0LFxuICB0eXBpY2FsQ2VsbERpYW1ldGVyLFxufSBmcm9tICcuLi8uLi8uLi9zcGF0aWFsL2xvZCc7XG5pbXBvcnQgeyBmaWx0ZXJSaW5ncywgbWVyZ2VQb2x5Z29uVGlsZXMgfSBmcm9tICcuLi8uLi8uLi9zcGF0aWFsL3NwYXRpYWwtdGlsZS1tZXJnZSc7XG5pbXBvcnQgeyBnZW5lRmlsdGVyS2V5IH0gZnJvbSAnLi4vLi4vLi4vc3BhdGlhbC9zcGF0aWFsLWdlbmUtZmlsdGVyJztcbmltcG9ydCB7IENvbnRyYXN0V2luZG93Q2FjaGUgfSBmcm9tICcuLi9uYXBhcmktc3BhdGlhbC1lbmNvZGluZyc7XG5pbXBvcnQgdHlwZSB7IENhdGVnb3JpY2FsTG9va3VwLCBIaWRkZW5Db2RlcyB9IGZyb20gJy4vY2F0ZWdvcmljYWwtbG9va3VwJztcbmltcG9ydCB0eXBlIHsgT3JkZXJlZExheWVyR3JvdXBzLCBUaWxlR3JvdXAgfSBmcm9tICcuL2xheWVyLWdyb3Vwcyc7XG5pbXBvcnQgdHlwZSB7IFBsYW5Db250ZXh0IH0gZnJvbSAnLi9wbGFuLWNvbnRleHQnO1xuXG5jb25zdCBNQVhfQ0VMTF9USUxFUyA9IDQ4O1xuXG4vKiogVGhlIGNlbGxzJyBjb2xvdXJzIGFzIGEgc2hhcGVzIGxheWVyIHRha2VzIHRoZW06IHBlci1zaGFwZSBSR0JBLCB2YWx1ZXMgb3ZlciBhIGNvbG9ybWFwLCBvclxuICogIG9uZSBjb2xvdXIuICovXG5pbnRlcmZhY2UgQ2VsbENvbG9ycyB7XG4gIHZhbHVlcz86IEZsb2F0MzJBcnJheTtcbiAgY29sb3JtYXA/OiBDb2xvcm1hcDtcbiAgY29udHJhc3RMaW1pdHM/OiBbbnVtYmVyLCBudW1iZXJdO1xuICBjb2xvcj86IFJHQkE7XG4gIGZhY2VDb2xvcj86IEZsb2F0MzJBcnJheTtcbn1cblxuLyoqIFdoYXQgdGhlIGNlbGwgbGF5ZXJzIG5lZWQgZnJvbSB0aGUgc2VydmljZS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2VsbExheWVyc0hvc3Qge1xuICAvKiogVGhlIGNvbnRpbnVvdXMgTFVUIHRoZSB2aWV3IGlzIHVzaW5nIChzbyBjZWxscyBjb2xvdXJlZCBieSBhIGdlbmUgbWF0Y2ggdGhlIG1hcmtlcnMpLiAqL1xuICBjb250aW51b3VzTHV0KHZpZXc6IFNwYXRpYWxWaWV3U3RhdGUpOiBSZ2JbXTtcbiAgLyoqIE91dGxpbmVzIGFwcGVhcmVkIG9yIGRpc2FwcGVhcmVkOiB0aGUgbWFya2VycycgdmlzaWJpbGl0eSBmb2xsb3dzLiAqL1xuICBwb2x5Z29uc1Nob3duQ2hhbmdlZChzaG93bjogYm9vbGVhbik6IHZvaWQ7XG59XG5cbi8qKlxuICogVGhlIGNlbGwgb3V0bGluZXMgb2YgdGhlIDJEIHNwYXRpYWwgdmlldywgYXQgdGhlIHBvbHlnb24gbGV2ZWwgdGhlIHpvb20gY2FsbHMgZm9yOiBhIGZpbGwsXG4gKiBhbiBvdXRsaW5lIG9yIGJvdGggKHBsdXMgbnVjbGV1cyBvdXRsaW5lcyBmb3IgdGhlIFwiYm90aFwiIGNlbGwgc2V0KSwgY29sb3VyZWQgYnkgdGhlIHZpZXcnc1xuICogY2VsbC1jb2xvdXIgbW9kZSwgd2l0aCBzd2l0Y2hlZC1vZmYgZ3JvdXBzIGxlZnQgb3V0IG9mIHRoZSBnZW9tZXRyeS5cbiAqXG4gKiBHZW9tZXRyeSBhbmQgc3R5bGUgYXJlIGtleWVkIGFwYXJ0LCBzbyBhIHJlY29sb3VyIChhIG5ldyBjZWxsLXR5cGUgY29sdW1uLCBhIHNlbGVjdGlvbilcbiAqIHJld3JpdGVzIHRoZSBwZXItc2hhcGUgdmFsdWVzIG9mIHRoZSBleGlzdGluZyBsYXllcnMgYW5kIG5ldmVyIHJlLWV4cGFuZHMgdGhlIHJpbmdzLlxuICovXG5leHBvcnQgY2xhc3MgQ2VsbExheWVycyB7XG4gIHByaXZhdGUgcG9seWdvbnNTaG93biA9IGZhbHNlO1xuICAvKiogUmluZ3MgY3VycmVudGx5IGRyYXduIGFuZCB0aGUgKGRhdGFzZXQsIHNldCwgdGlsZXMpIHRoZXkgY2FtZSBmcm9tLiAqL1xuICBwcml2YXRlIGN1cnJlbnRSaW5nczogU3BhdGlhbFBvbHlnb25UaWxlIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgY2VsbEdlb21ldHJ5S2V5OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBjdXJyZW50TnVjbGVpOiBTcGF0aWFsUG9seWdvblRpbGUgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBjZWxsU3R5bGVLZXk6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICAvKiogU2VsZWN0aW9uIGlkZW50aXR5IOKGkiByZXZpc2lvbiwgc28gYSBjaGFuZ2Uga2V5IGNhbiBuYW1lIGEgc2VsZWN0aW9uIGNoZWFwbHkuICovXG4gIHByaXZhdGUgbGFzdFNlbGVjdGlvbjogU3BhdGlhbFNlbGVjdGlvbk1hc2sgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBzZWxlY3Rpb25SZXZpc2lvbiA9IDA7XG4gIC8qKiBDb250aW51b3VzIGNvbG91cmluZ3MnIHdpbmRvd3MsIHBlciAodmVjdG9yLCBjbGlwLCBsb2cpOiBgY29udHJhc3RXaW5kb3dgIHNvcnRzIGV2ZXJ5XG4gICAqICB2YWx1ZSwgYW5kIGEgc2VsZWN0aW9uIG9yIG9wYWNpdHkgY2hhbmdlIHJlY29sb3VycyB3aXRoIHRoZSB2ZWN0b3IgdW5jaGFuZ2VkIChTUEFUSUFMLTEyKS4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBjb250cmFzdFdpbmRvd3MgPSBuZXcgQ29udHJhc3RXaW5kb3dDYWNoZSgpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcG9ydDogU3BhdGlhbERhdGFQb3J0LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgZ3JvdXBzOiBPcmRlcmVkTGF5ZXJHcm91cHM8VGlsZUdyb3VwPixcbiAgICBwcml2YXRlIHJlYWRvbmx5IGxvb2t1cDogQ2F0ZWdvcmljYWxMb29rdXAsXG4gICAgcHJpdmF0ZSByZWFkb25seSBob3N0OiBDZWxsTGF5ZXJzSG9zdCxcbiAgKSB7fVxuXG4gIC8qKiBUcnVlIHdoaWxlIG91dGxpbmVzIGFyZSBvbiBzY3JlZW4uICovXG4gIGdldCBvdXRsaW5lc1Nob3duKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnBvbHlnb25zU2hvd247XG4gIH1cblxuICAvKiogVGhlIHZpZXdlciB3ZW50IGF3YXkgKGl0cyBsYXllcnMgd2l0aCBpdCk6IHRoZSBvdXRsaW5lcyBhcmUgbm8gbG9uZ2VyIHNob3duLiAqL1xuICBkZXRhY2hlZCgpOiB2b2lkIHtcbiAgICB0aGlzLnNldFBvbHlnb25zU2hvd24oZmFsc2UpO1xuICB9XG5cbiAgLyoqIERyYXcgdGhlIGNlbGxzIGNvdmVyaW5nIGByZWN0YCBhdCB0aGUgbGV2ZWwgYHB4UGVyVW5pdGAgY2FsbHMgZm9yLCBvciBkcm9wIHRoZW0uICovXG4gIGFzeW5jIHBsYW4oXG4gICAgZGF0YXNldDogU3BhdGlhbERhdGFzZXQsXG4gICAgdmlldzogU3BhdGlhbFZpZXdTdGF0ZSxcbiAgICBzZWxlY3Rpb246IFNwYXRpYWxTZWxlY3Rpb25NYXNrLFxuICAgIHJlY3Q6IERhdGFSZWN0LFxuICAgIHB4UGVyVW5pdDogbnVtYmVyLFxuICAgIGN0eDogUGxhbkNvbnRleHQsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHRpbGVkID0gZGF0YXNldC5wb2x5Z29uVGlsZXM7XG4gICAgY29uc3Qgd2hvbGUgPSAhdGlsZWQgJiYgZGF0YXNldC5wb2x5Z29ucyAmJiB0aGlzLnBvcnQuZ2V0UG9seWdvbnM7XG4gICAgaWYgKCFjZWxsc1Nob3duKGRhdGFzZXQsIHZpZXcpIHx8ICghdGlsZWQgJiYgIXdob2xlKSkge1xuICAgICAgdGhpcy5kcm9wKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGRpYW1ldGVyID0gdHlwaWNhbENlbGxEaWFtZXRlcihkYXRhc2V0Lm9ic2VydmF0aW9ucy5yYWRpdXMpO1xuICAgIC8vIFdob2xlLWRhdGFzZXQgcmluZ3MgaGF2ZSBvbmUgbGV2ZWwgYW5kIG5vIGNvYXJzZXIgZmFsbGJhY2ssIHNvIHRoZXkgYXJlIGRyYXduIGFzXG4gICAgLy8gc29vbiBhcyBhIGNlbGwgaXMgYmlnIGVub3VnaCB0byByZWFkIGFzIGEgc2hhcGUgcmF0aGVyIHRoYW4gYSBkb3QuXG4gICAgY29uc3QgbGV2ZWwgPSB0aWxlZFxuICAgICAgPyBwb2x5Z29uTGV2ZWxGb3IocHhQZXJVbml0LCBkaWFtZXRlciwgdGlsZWQubGV2ZWxzLmxlbmd0aClcbiAgICAgIDogcHhQZXJVbml0ICogZGlhbWV0ZXIgPj0gUE9MWUdPTl9MRVZFTF9NSU5fQ0VMTF9QWFsyXVxuICAgICAgICA/IDBcbiAgICAgICAgOiAtMTtcbiAgICBpZiAobGV2ZWwgPCAwKSB7XG4gICAgICB0aGlzLmRyb3AoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBHcm91cHMgc3dpdGNoZWQgb2ZmIGluIHRoZSBsaXN0OiB0aGVpciBjZWxscyBhcmUgbGVmdCBvdXQgb2YgdGhlIGdlb21ldHJ5LlxuICAgIGNvbnN0IGhpZGRlbiA9IGF3YWl0IHRoaXMubG9va3VwLmhpZGRlbkNvZGVzKGRhdGFzZXQsIHZpZXcpO1xuICAgIGlmIChjdHguc3RhbGUoKSkgcmV0dXJuO1xuICAgIGNvbnN0IGxhYmVsID0gdmlldy5jZWxsU2V0ID09PSAnYm90aCcgPyAnQ2VsbHMgYW5kIG51Y2xlaScgOiB2aWV3LmNlbGxTZXQgPT09ICdudWNsZXVzJyA/ICdOdWNsZWknIDogJ0NlbGxzJztcbiAgICBjb25zdCBnZW9tZXRyeSA9IGF3YWl0IGN0eC50cmFjayhsYWJlbCwgdGhpcy5jZWxsR2VvbWV0cnkoZGF0YXNldCwgdmlldywgcmVjdCwgbGV2ZWwsIGhpZGRlbiwgY3R4KSk7XG4gICAgaWYgKCFnZW9tZXRyeSkgcmV0dXJuO1xuICAgIGNvbnN0IHsgcmluZ3MsIG51Y2xlaSwgZ2VvbWV0cnlLZXkgfSA9IGdlb21ldHJ5O1xuXG4gICAgY29uc3QgZ2VvbWV0cnlDaGFuZ2VkID0gZ2VvbWV0cnlLZXkgIT09IHRoaXMuY2VsbEdlb21ldHJ5S2V5O1xuICAgIGNvbnN0IHN0eWxlS2V5ID0gW1xuICAgICAgZ2VvbWV0cnlLZXksXG4gICAgICB2aWV3LmNlbGxDb2xvck1vZGUsXG4gICAgICB2aWV3LmNlbGxDb2xvckdlbmUsXG4gICAgICB2aWV3LmNlbGxTaW5nbGVDb2xvcixcbiAgICAgIGNlbGxUeXBlQ29sdW1uRm9yKGRhdGFzZXQsIHZpZXcpLFxuICAgICAgdGhpcy5zZWxlY3Rpb25SZXYoc2VsZWN0aW9uKSxcbiAgICAgIHZpZXcubG9nU2NhbGUsXG4gICAgICB2aWV3LnBlcmNlbnRpbGVDbGlwLmpvaW4oKSxcbiAgICAgIEpTT04uc3RyaW5naWZ5KHZpZXcuY29udGludW91c0NvbG9ybWFwKSxcbiAgICAgIHZpZXcuY2VsbERyYXcsXG4gICAgICB2aWV3LmNlbGxPcGFjaXR5LFxuICAgICAgLy8gQW55IGdyb3VwaW5nJ3M6IHRoZSBjZWxscyBtYXkgYmUgY29sb3VyZWQgYnkgc2VnbWVudGF0aW9uIG1ldGhvZCByYXRoZXIgdGhhbiB0aGUgY2VsbCB0eXBlLlxuICAgICAgSlNPTi5zdHJpbmdpZnkodmlldy5ncm91cENvbG9ycyksXG4gICAgXS5qb2luKCd8Jyk7XG4gICAgY29uc3QgcHJlc2VudCA9IChbJ2NlbGxGaWxsJywgJ2NlbGxPdXRsaW5lJywgJ251Y2xldXNPdXRsaW5lJ10gYXMgY29uc3QpLnNvbWUoKGcpID0+IHRoaXMuZ3JvdXBzLnNob3duKGcpKTtcbiAgICBpZiAoIWdlb21ldHJ5Q2hhbmdlZCAmJiBzdHlsZUtleSA9PT0gdGhpcy5jZWxsU3R5bGVLZXkgJiYgcHJlc2VudCkge1xuICAgICAgdGhpcy5zZXRQb2x5Z29uc1Nob3duKHRydWUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBjb2xvcnMgPSBhd2FpdCB0aGlzLmNlbGxDb2xvcnMoZGF0YXNldCwgdmlldywgc2VsZWN0aW9uLCByaW5ncy5vYnNlcnZhdGlvbik7XG4gICAgaWYgKGN0eC5zdGFsZSgpKSByZXR1cm47XG5cbiAgICB0aGlzLmN1cnJlbnRSaW5ncyA9IHJpbmdzO1xuICAgIHRoaXMuY3VycmVudE51Y2xlaSA9IG51Y2xlaTtcbiAgICAvLyBBIGdlb21ldHJ5IG1pc3NpbmcgYSBmYWlsZWQgdGlsZSBpcyBkcmF3biBidXQgbm90IHJlbWVtYmVyZWQsIHNvIHRoZSByZXRyeSByZWZldGNoZXMgaXQuXG4gICAgdGhpcy5jZWxsR2VvbWV0cnlLZXkgPSBjdHguaW5jb21wbGV0ZSA/IG51bGwgOiBnZW9tZXRyeUtleTtcbiAgICB0aGlzLmNlbGxTdHlsZUtleSA9IHN0eWxlS2V5O1xuICAgIHRoaXMuZHJhd0NlbGxzKGRhdGFzZXQsIHZpZXcsIGdlb21ldHJ5LCBjb2xvcnMsIGdlb21ldHJ5Q2hhbmdlZCk7XG4gICAgdGhpcy5zZXRQb2x5Z29uc1Nob3duKHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBjZWxsIGxheWVyczogdGhlIGZpbGwgYW5kIHRoZSBvdXRsaW5lIHRoZSB2aWV3J3MgZHJhdyBtb2RlIGFza3MgZm9yLCBhbmQgd2l0aCBcImJvdGhcIiB0aGVcbiAgICogbnVjbGV1cyBvdXRsaW5lcyBvdmVyIHRoZW0uIEEgZ2VvbWV0cnkgY2hhbmdlIGJ1aWxkcyBuZXcgbGF5ZXJzOyBhIHN0eWxlIGNoYW5nZSByZXN0eWxlcyB0aGVtLlxuICAgKi9cbiAgcHJpdmF0ZSBkcmF3Q2VsbHMoXG4gICAgZGF0YXNldDogU3BhdGlhbERhdGFzZXQsXG4gICAgdmlldzogU3BhdGlhbFZpZXdTdGF0ZSxcbiAgICB7IHJpbmdzLCBudWNsZWkgfTogeyByaW5nczogU3BhdGlhbFBvbHlnb25UaWxlOyBudWNsZWk6IFNwYXRpYWxQb2x5Z29uVGlsZSB8IG51bGwgfSxcbiAgICBjb2xvcnM6IENlbGxDb2xvcnMsXG4gICAgZ2VvbWV0cnlDaGFuZ2VkOiBib29sZWFuLFxuICApOiB2b2lkIHtcbiAgICBjb25zdCByZWYgPSBkYXRhc2V0LmltYWdlUmVmO1xuICAgIGNvbnN0IGNvbW1vbiA9IHsgc2NhbGU6IHJlZj8uc2NhbGUgPz8gWzEsIDFdLCB0cmFuc2xhdGU6IHJlZj8udHJhbnNsYXRlID8/IFswLCAwXSB9IGFzIGNvbnN0O1xuICAgIGNvbnN0IGZpbGwgPSB2aWV3LmNlbGxEcmF3ICE9PSAnb3V0bGluZSc7XG4gICAgY29uc3Qgb3V0bGluZSA9IHZpZXcuY2VsbERyYXcgIT09ICdmaWxsJztcblxuICAgIHRoaXMuZ3JvdXBzLnVwc2VydFNoYXBlcygnY2VsbEZpbGwnLCBmaWxsLCBnZW9tZXRyeUNoYW5nZWQsIHJpbmdzLCB7XG4gICAgICBuYW1lOiAnY2VsbHMnLFxuICAgICAgZHJhdzogJ2ZpbGwnLFxuICAgICAgb3BhY2l0eTogdmlldy5jZWxsT3BhY2l0eSxcbiAgICAgIC4uLmNvbG9ycyxcbiAgICAgIC4uLmNvbW1vbixcbiAgICB9KTtcbiAgICB0aGlzLmdyb3Vwcy51cHNlcnRTaGFwZXMoXG4gICAgICAnY2VsbE91dGxpbmUnLFxuICAgICAgb3V0bGluZSxcbiAgICAgIGdlb21ldHJ5Q2hhbmdlZCxcbiAgICAgIHJpbmdzLFxuICAgICAgZmlsbFxuICAgICAgICA/IC8vIE92ZXIgYSBmaWxsLCBhIGRhcmsgb3V0bGluZSBzZXBhcmF0ZXMgbmVpZ2hib3VycyBvZiB0aGUgc2FtZSB0eXBlLlxuICAgICAgICAgIHsgbmFtZTogJ2NlbGwgb3V0bGluZXMnLCBkcmF3OiAnb3V0bGluZScsIGNvbG9yOiBbMC4wOCwgMC4wOCwgMC4xLCAxXSwgb3BhY2l0eTogMC43LCAuLi5jb21tb24gfVxuICAgICAgICA6IHsgbmFtZTogJ2NlbGwgb3V0bGluZXMnLCBkcmF3OiAnb3V0bGluZScsIG9wYWNpdHk6IDEsIC4uLmNvbG9ycywgLi4uY29tbW9uIH0sXG4gICAgKTtcbiAgICAvLyBcIkJvdGhcIjogbnVjbGVpIG91dGxpbmVkIG92ZXIgdGhlIGNlbGxzLCBsaWdodCBzbyB0aGV5IHJlYWQgYWdhaW5zdCBhbnkgZmlsbC5cbiAgICBpZiAobnVjbGVpKSB7XG4gICAgICB0aGlzLmdyb3Vwcy51cHNlcnRTaGFwZXMoJ251Y2xldXNPdXRsaW5lJywgdHJ1ZSwgZ2VvbWV0cnlDaGFuZ2VkLCBudWNsZWksIHtcbiAgICAgICAgbmFtZTogJ251Y2xldXMgb3V0bGluZXMnLFxuICAgICAgICBkcmF3OiAnb3V0bGluZScsXG4gICAgICAgIGNvbG9yOiBbMC45NSwgMC45NSwgMC45OCwgMV0sXG4gICAgICAgIG9wYWNpdHk6IDAuOCxcbiAgICAgICAgLi4uY29tbW9uLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZ3JvdXBzLmRyb3AoJ251Y2xldXNPdXRsaW5lJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzZWxlY3Rpb25SZXYoc2VsZWN0aW9uOiBTcGF0aWFsU2VsZWN0aW9uTWFzayk6IG51bWJlciB7XG4gICAgaWYgKHNlbGVjdGlvbiAhPT0gdGhpcy5sYXN0U2VsZWN0aW9uKSB7XG4gICAgICB0aGlzLmxhc3RTZWxlY3Rpb24gPSBzZWxlY3Rpb247XG4gICAgICB0aGlzLnNlbGVjdGlvblJldmlzaW9uKys7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNlbGVjdGlvblJldmlzaW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSByaW5ncycgY29sb3VycyBieSB0aGVpciBvd25lcnMsIGJ5IHRoZSB2aWV3J3MgY2VsbC1jb2xvdXIgbW9kZSAoWGVuaXVtIEV4cGxvcmVyJ3MgXCJDZWxsXG4gICAqIENvbG9yXCIpOiBvbmUgUkdCQSBwZXIgc2hhcGUgZm9yIGEgZ3JvdXBpbmcsIHZhbHVlcyArIGNvbG9ybWFwIGZvciBhIG1lYXN1cmVtZW50LCBvbmUgY29sb3VyXG4gICAqIGZvciBcInNpbmdsZVwiLiBBIHNlbGVjdGlvbiBtdXRlcyB3aGF0IGl0IGxlYXZlcyBvdXQuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGNlbGxDb2xvcnMoXG4gICAgZGF0YXNldDogU3BhdGlhbERhdGFzZXQsXG4gICAgdmlldzogU3BhdGlhbFZpZXdTdGF0ZSxcbiAgICBzZWxlY3Rpb246IFNwYXRpYWxTZWxlY3Rpb25NYXNrLFxuICAgIG93bmVyczogVWludDMyQXJyYXksXG4gICk6IFByb21pc2U8Q2VsbENvbG9ycz4ge1xuICAgIGNvbnN0IG11dGVkID0gc2VsZWN0aW9uLmNvdW50ID4gMCA/IHNlbGVjdGlvbi5tYXNrIDogbnVsbDtcbiAgICBjb25zdCBtb2RlID0gdmlldy5jZWxsQ29sb3JNb2RlO1xuXG4gICAgaWYgKG1vZGUgPT09ICdzaW5nbGUnKSB7XG4gICAgICBjb25zdCBbciwgZywgYl0gPSBwYXJzZUhleCh2aWV3LmNlbGxTaW5nbGVDb2xvcik7XG4gICAgICByZXR1cm4geyBjb2xvcjogW3IgLyAyNTUsIGcgLyAyNTUsIGIgLyAyNTUsIDFdIH07XG4gICAgfVxuXG4gICAgY29uc3QgY29udGludW91cyA9IGFzeW5jIChyYXc6IEZsb2F0MzJBcnJheSwgbG9nOiBib29sZWFuKSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZXMgPSBuZXcgRmxvYXQzMkFycmF5KG93bmVycy5sZW5ndGgpO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvd25lcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgdiA9IHJhd1tvd25lcnNbaV1dID8/IE5hTjtcbiAgICAgICAgdmFsdWVzW2ldID0gbG9nID8gTWF0aC5sb2cxcChNYXRoLm1heCgwLCB2KSkgOiB2O1xuICAgICAgfVxuICAgICAgY29uc3QgW2NsaXBMbywgY2xpcEhpXSA9IHZpZXcucGVyY2VudGlsZUNsaXA7XG4gICAgICAvLyBLZXllZCBieSB0aGUgU09VUkNFIHZlY3RvciAodGhlIGxvZyBjb3B5IHdvdWxkIGJlIG5ldyBvbiBldmVyeSBjYWxsKSwgYXMgdGhlIDNEIGNsb3VkJ3MuXG4gICAgICBjb25zdCBbbG8sIGhpXSA9IHRoaXMuY29udHJhc3RXaW5kb3dzLmdldChyYXcsIGNsaXBMbywgY2xpcEhpLCBsb2csICgpID0+XG4gICAgICAgIGNvbnRyYXN0V2luZG93KGxvZyA/IHJhdy5tYXAoKHYpID0+IE1hdGgubG9nMXAoTWF0aC5tYXgoMCwgdikpKSA6IHJhdywgY2xpcExvLCBjbGlwSGkpLFxuICAgICAgKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHZhbHVlcyxcbiAgICAgICAgY29sb3JtYXA6IGNvbG9ybWFwRnJvbUx1dCgnc3BhdGlhbC1jb250aW51b3VzJywgdGhpcy5ob3N0LmNvbnRpbnVvdXNMdXQodmlldykpLFxuICAgICAgICBjb250cmFzdExpbWl0czogW2xvLCBoaV0gYXMgW251bWJlciwgbnVtYmVyXSxcbiAgICAgIH07XG4gICAgfTtcbiAgICBpZiAobW9kZSA9PT0gJ2dlbmUnICYmIHZpZXcuY2VsbENvbG9yR2VuZSkge1xuICAgICAgcmV0dXJuIGNvbnRpbnVvdXMoYXdhaXQgdGhpcy5wb3J0LmdldEZlYXR1cmVWZWN0b3Iodmlldy5jZWxsQ29sb3JHZW5lKSwgdHJ1ZSk7XG4gICAgfVxuICAgIGlmIChtb2RlID09PSAndHJhbnNjcmlwdERlbnNpdHknICYmIGRhdGFzZXQuY29sdW1ucy5zb21lKChjKSA9PiBjLm5hbWUgPT09ICd0cmFuc2NyaXB0X2RlbnNpdHknKSkge1xuICAgICAgY29uc3QgY29sdW1uID0gYXdhaXQgdGhpcy5wb3J0LmdldENvbHVtbigndHJhbnNjcmlwdF9kZW5zaXR5Jyk7XG4gICAgICBpZiAoIWlzQ2F0ZWdvcmljYWxDb2x1bW4oY29sdW1uKSkgcmV0dXJuIGNvbnRpbnVvdXMoY29sdW1uLnZhbHVlcywgZmFsc2UpO1xuICAgIH1cblxuICAgIGNvbnN0IG5hbWUgPVxuICAgICAgbW9kZSA9PT0gJ3NlZ21lbnRhdGlvbicgJiYgZGF0YXNldC5jb2x1bW5zLnNvbWUoKGMpID0+IGMubmFtZSA9PT0gJ3NlZ21lbnRhdGlvbl9tZXRob2QnKVxuICAgICAgICA/ICdzZWdtZW50YXRpb25fbWV0aG9kJ1xuICAgICAgICA6IGNlbGxUeXBlQ29sdW1uRm9yKGRhdGFzZXQsIHZpZXcpO1xuICAgIGNvbnN0IGNvZGVzID0gbmFtZSA/IGF3YWl0IHRoaXMubG9va3VwLmNvZGVzKG5hbWUpIDogbnVsbDtcbiAgICBjb25zdCBwYWxldHRlID0gY2F0ZWdvcnlSZ2JhKG5hbWUsIGNvZGVzPy5tZXRhID8/IG51bGwsIHZpZXcuZ3JvdXBDb2xvcnMpO1xuICAgIGNvbnN0IG1pc3NpbmcgPSByZ2JhMDEoTUlTU0lOR19DT0xPUik7XG4gICAgLy8gT25lIFJHQkEgcGVyIHNoYXBlIChuYXBhcmkgU2hhcGVzJyBgZmFjZV9jb2xvcmApOiBhbnkgbnVtYmVyIG9mIGNhdGVnb3JpZXMga2VlcHMgaXRzIG93blxuICAgIC8vIGNvbG91ciwgd2hlcmUgYSBjb2xvcm1hcCBiYW5kIHBlciBjYXRlZ29yeSByYW4gb3V0IG9mIExVVCBlbnRyaWVzIHBhc3QgfjEyNy5cbiAgICBjb25zdCBmYWNlQ29sb3IgPSBuZXcgRmxvYXQzMkFycmF5KG93bmVycy5sZW5ndGggKiA0KTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG93bmVycy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgbyA9IG93bmVyc1tpXTtcbiAgICAgIGNvbnN0IGNvZGUgPSAhY29kZXMgfHwgKG11dGVkICYmICFtdXRlZFtvXSkgPyBOT19DQVRFR09SWSA6IGNvZGVzLmNvZGVzW29dO1xuICAgICAgZmFjZUNvbG9yLnNldChwYWxldHRlW2NvZGVdID8/IG1pc3NpbmcsIGkgKiA0KTtcbiAgICB9XG4gICAgcmV0dXJuIHsgZmFjZUNvbG9yIH07XG4gIH1cblxuICAvKipcbiAgICogVGhlIGNlbGwgcmluZ3MgKGFuZCwgZm9yIFwiYm90aFwiLCB0aGUgbnVjbGV1cyByaW5ncykgY292ZXJpbmcgYHJlY3RgIGF0IGBsZXZlbGAsIG1pbnVzXG4gICAqIHRoZSBoaWRkZW4gZ3JvdXBzIOKAlCByZXVzZWQgd2hlbiBub3RoaW5nIHRoYXQgZGVjaWRlcyB0aGVtIGNoYW5nZWQuIE51bGwgd2hlbiB0aGVcbiAgICogdmlldyB3ZW50IHN0YWxlIG9yIHRoZSBkYXRhc2V0IGhhcyBubyBzZXQgdG8gZHJhdy5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgY2VsbEdlb21ldHJ5KFxuICAgIGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0LFxuICAgIHZpZXc6IFNwYXRpYWxWaWV3U3RhdGUsXG4gICAgcmVjdDogRGF0YVJlY3QsXG4gICAgbGV2ZWw6IG51bWJlcixcbiAgICBoaWRkZW46IEhpZGRlbkNvZGVzIHwgbnVsbCxcbiAgICBjdHg6IFBsYW5Db250ZXh0LFxuICApOiBQcm9taXNlPHsgcmluZ3M6IFNwYXRpYWxQb2x5Z29uVGlsZTsgbnVjbGVpOiBTcGF0aWFsUG9seWdvblRpbGUgfCBudWxsOyBnZW9tZXRyeUtleTogc3RyaW5nIH0gfCBudWxsPiB7XG4gICAgY29uc3QgdGlsZWQgPSBkYXRhc2V0LnBvbHlnb25UaWxlcztcbiAgICBjb25zdCBoaWRkZW5LZXkgPSBgJHt2aWV3LmhpZGRlbkdyb3Vwcy5qb2luKCdcXHUwMDAxJyl9fCR7Z2VuZUZpbHRlcktleSh2aWV3KX1gO1xuICAgIGxldCByaW5nczogU3BhdGlhbFBvbHlnb25UaWxlO1xuICAgIGxldCBudWNsZWk6IFNwYXRpYWxQb2x5Z29uVGlsZSB8IG51bGwgPSBudWxsO1xuICAgIGxldCBnZW9tZXRyeUtleTogc3RyaW5nO1xuICAgIGlmICh0aWxlZCkge1xuICAgICAgY29uc3QgZHJhd24gPSBkcmF3bkNlbGxTZXRzKHRpbGVkLCB2aWV3LmNlbGxTZXQpO1xuICAgICAgaWYgKCFkcmF3bikgcmV0dXJuIG51bGw7XG4gICAgICBjb25zdCB7IHNldCwgbnVjbGV1c1NldCB9ID0gZHJhd247XG4gICAgICBjb25zdCBrZXlzID0gdGlsZXNJblJlY3QocmVjdCwgbGV2ZWwsIHRpbGVkLmxldmVscywgdGlsZWQuYm91bmRzLCBNQVhfQ0VMTF9USUxFUyk7XG4gICAgICBnZW9tZXRyeUtleSA9IGAke2RhdGFzZXQuaWR9fCR7c2V0fXwke251Y2xldXNTZXQgPz8gJyd9fCR7aGlkZGVuS2V5fXwke2tleXMubWFwKHRpbGVJZCkuam9pbignLCcpfWA7XG4gICAgICBpZiAoZ2VvbWV0cnlLZXkgPT09IHRoaXMuY2VsbEdlb21ldHJ5S2V5ICYmIHRoaXMuY3VycmVudFJpbmdzKSB7XG4gICAgICAgIHJpbmdzID0gdGhpcy5jdXJyZW50UmluZ3M7XG4gICAgICAgIG51Y2xlaSA9IHRoaXMuY3VycmVudE51Y2xlaTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IFt0aWxlcywgbnVjbGV1c1RpbGVzXSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgICBjdHguZmV0Y2hBbGwoa2V5cywgKGspID0+IHRoaXMucG9ydC5nZXRQb2x5Z29uVGlsZSEoc2V0LCBrLmxldmVsLCBrLmd4LCBrLmd5KSksXG4gICAgICAgICAgbnVjbGV1c1NldFxuICAgICAgICAgICAgPyBjdHguZmV0Y2hBbGwoa2V5cywgKGspID0+IHRoaXMucG9ydC5nZXRQb2x5Z29uVGlsZSEobnVjbGV1c1NldCwgay5sZXZlbCwgay5neCwgay5neSkpXG4gICAgICAgICAgICA6IFByb21pc2UucmVzb2x2ZShudWxsKSxcbiAgICAgICAgXSk7XG4gICAgICAgIGlmIChjdHguc3RhbGUoKSkgcmV0dXJuIG51bGw7XG4gICAgICAgIHJpbmdzID0gZmlsdGVyUmluZ3MobWVyZ2VQb2x5Z29uVGlsZXModGlsZXMpLCBoaWRkZW4pO1xuICAgICAgICBudWNsZWkgPSBudWNsZXVzVGlsZXMgPyBmaWx0ZXJSaW5ncyhtZXJnZVBvbHlnb25UaWxlcyhudWNsZXVzVGlsZXMpLCBoaWRkZW4pIDogbnVsbDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZ2VvbWV0cnlLZXkgPSBgJHtkYXRhc2V0LmlkfXx3aG9sZXwke2hpZGRlbktleX1gO1xuICAgICAgaWYgKGdlb21ldHJ5S2V5ID09PSB0aGlzLmNlbGxHZW9tZXRyeUtleSAmJiB0aGlzLmN1cnJlbnRSaW5ncykge1xuICAgICAgICByaW5ncyA9IHRoaXMuY3VycmVudFJpbmdzO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgcG9seXM6IFNwYXRpYWxQb2x5Z29ucyA9IGF3YWl0IHRoaXMucG9ydC5nZXRQb2x5Z29ucyEoKTtcbiAgICAgICAgaWYgKGN0eC5zdGFsZSgpKSByZXR1cm4gbnVsbDtcbiAgICAgICAgLy8gV2hvbGUtZGF0YXNldCByaW5ncyBhcmUgaW5kZXgtYWxpZ25lZCB3aXRoIHRoZSBvYnNlcnZhdGlvbnMuXG4gICAgICAgIHJpbmdzID0gZmlsdGVyUmluZ3MoXG4gICAgICAgICAgeyAuLi5wb2x5cywgb2JzZXJ2YXRpb246IFVpbnQzMkFycmF5LmZyb20oeyBsZW5ndGg6IHBvbHlzLmNvdW50IH0sIChfdiwgaSkgPT4gaSkgfSxcbiAgICAgICAgICBoaWRkZW4sXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IHJpbmdzLCBudWNsZWksIGdlb21ldHJ5S2V5IH07XG4gIH1cblxuICAvKiogUmVtb3ZlIHRoZSBjZWxsIGxheWVycyBhbmQgZm9yZ2V0IHdoYXQgdGhleSBzaG93ZWQuICovXG4gIGRyb3AoKTogdm9pZCB7XG4gICAgdGhpcy5ncm91cHMuZHJvcCgnY2VsbEZpbGwnKTtcbiAgICB0aGlzLmdyb3Vwcy5kcm9wKCdjZWxsT3V0bGluZScpO1xuICAgIHRoaXMuZ3JvdXBzLmRyb3AoJ251Y2xldXNPdXRsaW5lJyk7XG4gICAgdGhpcy5jdXJyZW50TnVjbGVpID0gbnVsbDtcbiAgICB0aGlzLmNlbGxHZW9tZXRyeUtleSA9IG51bGw7XG4gICAgdGhpcy5jZWxsU3R5bGVLZXkgPSBudWxsO1xuICAgIHRoaXMuY3VycmVudFJpbmdzID0gbnVsbDtcbiAgICB0aGlzLnNldFBvbHlnb25zU2hvd24oZmFsc2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRQb2x5Z29uc1Nob3duKHNob3duOiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKHNob3duID09PSB0aGlzLnBvbHlnb25zU2hvd24pIHJldHVybjtcbiAgICB0aGlzLnBvbHlnb25zU2hvd24gPSBzaG93bjtcbiAgICB0aGlzLmhvc3QucG9seWdvbnNTaG93bkNoYW5nZWQoc2hvd24pO1xuICB9XG59XG5cbi8qKiBBbiA4LWJpdCBSR0IgYXMgYW4gb3BhcXVlIDAuLjEgUkdCQS4gKi9cbmZ1bmN0aW9uIHJnYmEwMShbciwgZywgYl06IHJlYWRvbmx5IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSk6IFJHQkEge1xuICByZXR1cm4gW3IgLyAyNTUsIGcgLyAyNTUsIGIgLyAyNTUsIDFdO1xufVxuXG4vKiogQSBncm91cGluZydzIGNhdGVnb3J5IGNvbG91cnMsIGFzIDAuLjEgUkdCQSBieSBjYXRlZ29yeSBjb2RlIChvbmUgZGVmYXVsdCB3aXRob3V0IGEgZ3JvdXBpbmcpLiAqL1xuZnVuY3Rpb24gY2F0ZWdvcnlSZ2JhKFxuICBuYW1lOiBzdHJpbmcgfCBudWxsLFxuICBtZXRhOiBTcGF0aWFsQ29sdW1uWydtZXRhJ10gfCBudWxsLFxuICBvdmVycmlkZXM6IEdyb3VwQ29sb3JPdmVycmlkZXMgfCB1bmRlZmluZWQsXG4pOiBSR0JBW10ge1xuICBjb25zdCBoZXggPVxuICAgIG5hbWUgJiYgbWV0YSAmJiBtZXRhLmtpbmQgPT09ICdjYXRlZ29yaWNhbCdcbiAgICAgID8gY2F0ZWdvcnlDb2xvcnNGb3IobmFtZSwgbWV0YSwgb3ZlcnJpZGVzKVxuICAgICAgOiBbREVGQVVMVF9DQVRFR09SSUNBTF9QQUxFVFRFWzBdXTtcbiAgcmV0dXJuIGhleC5tYXAoKGgpID0+IHJnYmEwMShwYXJzZUhleChoKSkpO1xufVxuIl19
408
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VsbC1sYXllcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2ltcGxlbWVudGF0aW9ucy9uYXBhcmktanMvc3BhdGlhbC10aWxlcy9jZWxsLWxheWVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsZUFBZSxFQUFFLGFBQWEsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQU0zRCxPQUFPLEVBQ0wsV0FBVyxFQUtYLG1CQUFtQixHQUNwQixNQUFNLDZDQUE2QyxDQUFDO0FBQ3JELE9BQU8sRUFDTCwyQkFBMkIsRUFDM0IsYUFBYSxFQUViLGlCQUFpQixFQUNqQixjQUFjLEVBQ2QsUUFBUSxHQUNULE1BQU0sbUNBQW1DLENBQUM7QUFFM0MsT0FBTyxFQUVMLHlCQUF5QixFQUN6QixpQkFBaUIsRUFDakIsVUFBVSxFQUNWLGFBQWEsRUFDYixlQUFlLEVBQ2YsTUFBTSxFQUNOLFdBQVcsRUFDWCxtQkFBbUIsR0FDcEIsTUFBTSxzQkFBc0IsQ0FBQztBQUM5QixPQUFPLEVBQUUsV0FBVyxFQUFFLGlCQUFpQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDckYsT0FBTyxFQUFFLGdCQUFnQixFQUFFLGNBQWMsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBRWhGLE9BQU8sRUFBRSxjQUFjLEVBQUUsWUFBWSxFQUFFLGlCQUFpQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDdEcsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBS2pFLE1BQU0sY0FBYyxHQUFHLEVBQUUsQ0FBQztBQW9CMUI7Ozs7Ozs7R0FPRztBQUNILE1BQU0sT0FBTyxVQUFVO0lBcUJyQixZQUNtQixJQUFxQixFQUNyQixNQUFxQyxFQUNyQyxNQUF5QixFQUN6QixJQUFvQjtRQUhwQixTQUFJLEdBQUosSUFBSSxDQUFp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LEdBQUcsQ0FBQztBQUNiLENBQUM7QUFFRCwyQ0FBMkM7QUFDM0MsU0FBUyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBb0M7SUFDMUQsT0FBTyxDQUFDLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ3hDLENBQUM7QUFFRCxxR0FBcUc7QUFDckcsU0FBUyxZQUFZLENBQ25CLElBQW1CLEVBQ25CLElBQWtDLEVBQ2xDLFNBQTBDO0lBRTFDLE1BQU0sR0FBRyxHQUNQLElBQUksSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxhQUFhO1FBQ3pDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLFNBQVMsQ0FBQztRQUMxQyxDQUFDLENBQUMsQ0FBQywyQkFBMkIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZDLE9BQU8sR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDN0MsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNvbG9ybWFwRnJvbUx1dCwgbWFwU2NhbGFyUkdCQSB9IGZyb20gJ25hcGFyaS1qcyc7XG5pbXBvcnQgdHlwZSB7IENvbG9ybWFwLCBSR0JBIH0gZnJvbSAnbmFwYXJpLWpzJztcblxuaW1wb3J0IHR5cGUgeyBSZ2IgfSBmcm9tICcuLi8uLi8uLi9jb250cmFjdHMvY29sb3JtYXAtbHV0JztcbmltcG9ydCB0eXBlIHsgU3BhdGlhbERhdGFQb3J0IH0gZnJvbSAnLi4vLi4vLi4vY29udHJhY3RzL3BvcnRzL3NwYXRpYWwtZGF0YS5wb3J0JztcbmltcG9ydCB0eXBlIHsgU3BhdGlhbFZpZXdTdGF0ZSB9IGZyb20gJy4uLy4uLy4uL2NvbnRyYWN0cy9kaXNwbGF5LXR5cGVzJztcbmltcG9ydCB7XG4gIE5PX0NBVEVHT1JZLFxuICBTcGF0aWFsQ29sdW1uLFxuICBTcGF0aWFsRGF0YXNldCxcbiAgU3BhdGlhbFBvbHlnb25UaWxlLFxuICBTcGF0aWFsUG9seWdvbnMsXG4gIGlzQ2F0ZWdvcmljYWxDb2x1bW4sXG59IGZyb20gJy4uLy4uLy4uL2NvbnRyYWN0cy9zcGF0aWFsLWRhdGFzZXQuY29udHJhY3QnO1xuaW1wb3J0IHtcbiAgREVGQVVMVF9DQVRFR09SSUNBTF9QQUxFVFRFLFxuICBNSVNTSU5HX0NPTE9SLFxuICBHcm91cENvbG9yT3ZlcnJpZGVzLFxuICBjYXRlZ29yeUNvbG9yc0ZvcixcbiAgY29udHJhc3RXaW5kb3csXG4gIHBhcnNlSGV4LFxufSBmcm9tICcuLi8uLi8uLi9zcGF0aWFsL3NwYXRpYWwtZW5jb2RpbmcnO1xuaW1wb3J0IHsgU3BhdGlhbFNlbGVjdGlvbk1hc2sgfSBmcm9tICcuLi8uLi8uLi9zcGF0aWFsL3NwYXRpYWwtc2VsZWN0aW9uJztcbmltcG9ydCB7XG4gIERhdGFSZWN0LFxuICBQT0xZR09OX0xFVkVMX01JTl9DRUxMX1BYLFxuICBjZWxsVHlwZUNvbHVtbkZvcixcbiAgY2VsbHNTaG93bixcbiAgZHJhd25DZWxsU2V0cyxcbiAgcG9seWdvbkxldmVsRm9yLFxuICB0aWxlSWQsXG4gIHRpbGVzSW5SZWN0LFxuICB0eXBpY2FsQ2VsbERpYW1ldGVyLFxufSBmcm9tICcuLi8uLi8uLi9zcGF0aWFsL2xvZCc7XG5pbXBvcnQgeyBmaWx0ZXJSaW5ncywgbWVyZ2VQb2x5Z29uVGlsZXMgfSBmcm9tICcuLi8uLi8uLi9zcGF0aWFsL3NwYXRpYWwtdGlsZS1tZXJnZSc7XG5pbXBvcnQgeyBvYnNlcnZhdGlvbkluZGV4LCBwbGFuZUNlbGxSaW5ncyB9IGZyb20gJy4uLy4uLy4uL3NwYXRpYWwvcGxhbmUtY2VsbHMnO1xuaW1wb3J0IHR5cGUgeyBSZWdpb25Tb3VyY2UgfSBmcm9tICcuLi8uLi8uLi9yZWdpb24tc291cmNlL3JlZ2lvbi1zb3VyY2UnO1xuaW1wb3J0IHsgcmVnaW9uTGV2ZWxGb3IsIHJlZ2lvblRpbGVJZCwgcmVnaW9uVGlsZXNJblJlY3QgfSBmcm9tICcuLi8uLi8uLi9yZWdpb24tc291cmNlL3JlZ2lvbi10aWxlcyc7XG5pbXBvcnQgeyBnZW5lRmlsdGVyS2V5IH0gZnJvbSAnLi4vLi4vLi4vc3BhdGlhbC9zcGF0aWFsLWdlbmUtZmlsdGVyJztcbmltcG9ydCB7IENvbnRyYXN0V2luZG93Q2FjaGUgfSBmcm9tICcuLi9uYXBhcmktc3BhdGlhbC1lbmNvZGluZyc7XG5pbXBvcnQgdHlwZSB7IENhdGVnb3JpY2FsTG9va3VwLCBIaWRkZW5Db2RlcyB9IGZyb20gJy4vY2F0ZWdvcmljYWwtbG9va3VwJztcbmltcG9ydCB0eXBlIHsgT3JkZXJlZExheWVyR3JvdXBzLCBUaWxlR3JvdXAgfSBmcm9tICcuL2xheWVyLWdyb3Vwcyc7XG5pbXBvcnQgdHlwZSB7IFBsYW5Db250ZXh0IH0gZnJvbSAnLi9wbGFuLWNvbnRleHQnO1xuXG5jb25zdCBNQVhfQ0VMTF9USUxFUyA9IDQ4O1xuXG4vKiogVGhlIGNlbGxzJyBjb2xvdXJzIGFzIGEgc2hhcGVzIGxheWVyIHRha2VzIHRoZW06IHBlci1zaGFwZSBSR0JBLCB2YWx1ZXMgb3ZlciBhIGNvbG9ybWFwLCBvclxuICogIG9uZSBjb2xvdXIuICovXG5leHBvcnQgaW50ZXJmYWNlIENlbGxDb2xvcnMge1xuICB2YWx1ZXM/OiBGbG9hdDMyQXJyYXk7XG4gIGNvbG9ybWFwPzogQ29sb3JtYXA7XG4gIGNvbnRyYXN0TGltaXRzPzogW251bWJlciwgbnVtYmVyXTtcbiAgY29sb3I/OiBSR0JBO1xuICBmYWNlQ29sb3I/OiBGbG9hdDMyQXJyYXk7XG59XG5cbi8qKiBXaGF0IHRoZSBjZWxsIGxheWVycyBuZWVkIGZyb20gdGhlIHNlcnZpY2UuICovXG5leHBvcnQgaW50ZXJmYWNlIENlbGxMYXllcnNIb3N0IHtcbiAgLyoqIFRoZSBjb250aW51b3VzIExVVCB0aGUgdmlldyBpcyB1c2luZyAoc28gY2VsbHMgY29sb3VyZWQgYnkgYSBnZW5lIG1hdGNoIHRoZSBtYXJrZXJzKS4gKi9cbiAgY29udGludW91c0x1dCh2aWV3OiBTcGF0aWFsVmlld1N0YXRlKTogUmdiW107XG4gIC8qKiBPdXRsaW5lcyBhcHBlYXJlZCBvciBkaXNhcHBlYXJlZDogdGhlIG1hcmtlcnMnIHZpc2liaWxpdHkgZm9sbG93cy4gKi9cbiAgcG9seWdvbnNTaG93bkNoYW5nZWQoc2hvd246IGJvb2xlYW4pOiB2b2lkO1xufVxuXG4vKipcbiAqIFRoZSBjZWxsIG91dGxpbmVzIG9mIHRoZSAyRCBzcGF0aWFsIHZpZXcsIGF0IHRoZSBwb2x5Z29uIGxldmVsIHRoZSB6b29tIGNhbGxzIGZvcjogYSBmaWxsLFxuICogYW4gb3V0bGluZSBvciBib3RoIChwbHVzIG51Y2xldXMgb3V0bGluZXMgZm9yIHRoZSBcImJvdGhcIiBjZWxsIHNldCksIGNvbG91cmVkIGJ5IHRoZSB2aWV3J3NcbiAqIGNlbGwtY29sb3VyIG1vZGUsIHdpdGggc3dpdGNoZWQtb2ZmIGdyb3VwcyBsZWZ0IG91dCBvZiB0aGUgZ2VvbWV0cnkuXG4gKlxuICogR2VvbWV0cnkgYW5kIHN0eWxlIGFyZSBrZXllZCBhcGFydCwgc28gYSByZWNvbG91ciAoYSBuZXcgY2VsbC10eXBlIGNvbHVtbiwgYSBzZWxlY3Rpb24pXG4gKiByZXdyaXRlcyB0aGUgcGVyLXNoYXBlIHZhbHVlcyBvZiB0aGUgZXhpc3RpbmcgbGF5ZXJzIGFuZCBuZXZlciByZS1leHBhbmRzIHRoZSByaW5ncy5cbiAqL1xuZXhwb3J0IGNsYXNzIENlbGxMYXllcnMge1xuICBwcml2YXRlIHBvbHlnb25zU2hvd24gPSBmYWxzZTtcbiAgLyoqIFJpbmdzIGN1cnJlbnRseSBkcmF3biBhbmQgdGhlIChkYXRhc2V0LCBzZXQsIHRpbGVzKSB0aGV5IGNhbWUgZnJvbS4gKi9cbiAgcHJpdmF0ZSBjdXJyZW50UmluZ3M6IFNwYXRpYWxQb2x5Z29uVGlsZSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGNlbGxHZW9tZXRyeUtleTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgY3VycmVudE51Y2xlaTogU3BhdGlhbFBvbHlnb25UaWxlIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgY2VsbFN0eWxlS2V5OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgLyoqIFNlbGVjdGlvbiBpZGVudGl0eSDihpIgcmV2aXNpb24sIHNvIGEgY2hhbmdlIGtleSBjYW4gbmFtZSBhIHNlbGVjdGlvbiBjaGVhcGx5LiAqL1xuICBwcml2YXRlIGxhc3RTZWxlY3Rpb246IFNwYXRpYWxTZWxlY3Rpb25NYXNrIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgc2VsZWN0aW9uUmV2aXNpb24gPSAwO1xuICAvKiogQ29udGludW91cyBjb2xvdXJpbmdzJyB3aW5kb3dzLCBwZXIgKHZlY3RvciwgY2xpcCwgbG9nKTogYGNvbnRyYXN0V2luZG93YCBzb3J0cyBldmVyeVxuICAgKiAgdmFsdWUsIGFuZCBhIHNlbGVjdGlvbiBvciBvcGFjaXR5IGNoYW5nZSByZWNvbG91cnMgd2l0aCB0aGUgdmVjdG9yIHVuY2hhbmdlZCAoU1BBVElBTC0xMikuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgY29udHJhc3RXaW5kb3dzID0gbmV3IENvbnRyYXN0V2luZG93Q2FjaGUoKTtcbiAgLyoqXG4gICAqIFRoZSBwbGFuZSBvZiBhIDNEIHNlZ21lbnRhdGlvbiB0aGUgdmlldyBzaG93cyAoc2VlIHtAbGluayBzZXRQbGFuZX0pLCBvciBudWxsOiBldmVyeSBzZXQgZHJhd3NcbiAgICogaXRzIG93biB0aWxlcy5cbiAgICovXG4gIHByaXZhdGUgcGxhbmU6IG51bWJlciB8IG51bGwgPSBudWxsO1xuICAvKiogVGhlIHJlZ2lvbiBzZXQgb3BlbmVkIGZvciBhIGJvdW5kYXJ5IHNldCdzIHBlci1wbGFuZSBvdXRsaW5lczogaXRzIGlkIGFuZCB0aGUgc291cmNlLiAqL1xuICBwcml2YXRlIHBsYW5lU291cmNlOiB7IGlkOiBzdHJpbmc7IHNvdXJjZTogUHJvbWlzZTxSZWdpb25Tb3VyY2U+IH0gfCBudWxsID0gbnVsbDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IHBvcnQ6IFNwYXRpYWxEYXRhUG9ydCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGdyb3VwczogT3JkZXJlZExheWVyR3JvdXBzPFRpbGVHcm91cD4sXG4gICAgcHJpdmF0ZSByZWFkb25seSBsb29rdXA6IENhdGVnb3JpY2FsTG9va3VwLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgaG9zdDogQ2VsbExheWVyc0hvc3QsXG4gICkge31cblxuICAvKiogVHJ1ZSB3aGlsZSBvdXRsaW5lcyBhcmUgb24gc2NyZWVuLiAqL1xuICBnZXQgb3V0bGluZXNTaG93bigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5wb2x5Z29uc1Nob3duO1xuICB9XG5cbiAgLyoqXG4gICAqIFNob3cgcGxhbmUgYHBsYW5lYCAoYW4gaW5kZXggaW50byB0aGUgcmVnaW9uIHNldCdzIHBsYW5lcykgb2YgYSAzRCBzZWdtZW50YXRpb24sIG9yIG5vbmU6IGFcbiAgICogYm91bmRhcnkgc2V0IHRoYXQgbmFtZXMgaXRzIHJlZ2lvbiBzZXQgKGByZWdpb25Tb3VyY2VgLCBhIGNlbGwgb3V0bGluZWQgb24gZXZlcnkgcGxhbmUgaXQgc3BhbnMpXG4gICAqIHRoZW4gZHJhd3MgdGhhdCBwbGFuZSdzIG91dGxpbmVzLCByYXRoZXIgdGhhbiBvbmUgb3V0bGluZSBwZXIgY2VsbCwgc28gdGhlIGNlbGxzIGZvbGxvdyB0aGVcbiAgICogc2xpY2UuIEl0cyBjZWxscyBrZWVwIHRoZSB2aWV3J3MgY29sb3VyaW5nLCBncm91cHMgYW5kIHNlbGVjdGlvbi5cbiAgICovXG4gIHNldFBsYW5lKHBsYW5lOiBudW1iZXIgfCBudWxsKTogdm9pZCB7XG4gICAgdGhpcy5wbGFuZSA9IHBsYW5lO1xuICB9XG5cbiAgLyoqIENsb3NlIHRoZSByZWdpb24gc2V0IG9wZW5lZCBmb3IgdGhlIHBlci1wbGFuZSBvdXRsaW5lcy4gKi9cbiAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICBjb25zdCBvcGVuZWQgPSB0aGlzLnBsYW5lU291cmNlO1xuICAgIHRoaXMucGxhbmVTb3VyY2UgPSBudWxsO1xuICAgIHZvaWQgb3BlbmVkPy5zb3VyY2UudGhlbihcbiAgICAgIChzKSA9PiBzLmRpc3Bvc2UoKSxcbiAgICAgICgpID0+IHVuZGVmaW5lZCxcbiAgICApO1xuICB9XG5cbiAgLyoqIFRoZSB2aWV3ZXIgd2VudCBhd2F5IChpdHMgbGF5ZXJzIHdpdGggaXQpOiB0aGUgb3V0bGluZXMgYXJlIG5vIGxvbmdlciBzaG93bi4gKi9cbiAgZGV0YWNoZWQoKTogdm9pZCB7XG4gICAgdGhpcy5zZXRQb2x5Z29uc1Nob3duKGZhbHNlKTtcbiAgfVxuXG4gIC8qKiBEcmF3IHRoZSBjZWxscyBjb3ZlcmluZyBgcmVjdGAgYXQgdGhlIGxldmVsIGBweFBlclVuaXRgIGNhbGxzIGZvciwgb3IgZHJvcCB0aGVtLiAqL1xuICBhc3luYyBwbGFuKFxuICAgIGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0LFxuICAgIHZpZXc6IFNwYXRpYWxWaWV3U3RhdGUsXG4gICAgc2VsZWN0aW9uOiBTcGF0aWFsU2VsZWN0aW9uTWFzayxcbiAgICByZWN0OiBEYXRhUmVjdCxcbiAgICBweFBlclVuaXQ6IG51bWJlcixcbiAgICBjdHg6IFBsYW5Db250ZXh0LFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB0aWxlZCA9IGRhdGFzZXQucG9seWdvblRpbGVzO1xuICAgIGNvbnN0IHdob2xlID0gIXRpbGVkICYmIGRhdGFzZXQucG9seWdvbnMgJiYgdGhpcy5wb3J0LmdldFBvbHlnb25zO1xuICAgIGlmICghY2VsbHNTaG93bihkYXRhc2V0LCB2aWV3KSB8fCAoIXRpbGVkICYmICF3aG9sZSkpIHtcbiAgICAgIHRoaXMuZHJvcCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBkaWFtZXRlciA9IHR5cGljYWxDZWxsRGlhbWV0ZXIoZGF0YXNldC5vYnNlcnZhdGlvbnMucmFkaXVzKTtcbiAgICAvLyBXaG9sZS1kYXRhc2V0IHJpbmdzIGhhdmUgb25lIGxldmVsIGFuZCBubyBjb2Fyc2VyIGZhbGxiYWNrLCBzbyB0aGV5IGFyZSBkcmF3biBhc1xuICAgIC8vIHNvb24gYXMgYSBjZWxsIGlzIGJpZyBlbm91Z2ggdG8gcmVhZCBhcyBhIHNoYXBlIHJhdGhlciB0aGFuIGEgZG90LlxuICAgIGNvbnN0IGxldmVsID0gdGlsZWRcbiAgICAgID8gcG9seWdvbkxldmVsRm9yKHB4UGVyVW5pdCwgZGlhbWV0ZXIsIHRpbGVkLmxldmVscy5sZW5ndGgpXG4gICAgICA6IHB4UGVyVW5pdCAqIGRpYW1ldGVyID49IFBPTFlHT05fTEVWRUxfTUlOX0NFTExfUFhbMl1cbiAgICAgICAgPyAwXG4gICAgICAgIDogLTE7XG4gICAgaWYgKGxldmVsIDwgMCkge1xuICAgICAgdGhpcy5kcm9wKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gR3JvdXBzIHN3aXRjaGVkIG9mZiBpbiB0aGUgbGlzdDogdGhlaXIgY2VsbHMgYXJlIGxlZnQgb3V0IG9mIHRoZSBnZW9tZXRyeS5cbiAgICBjb25zdCBoaWRkZW4gPSBhd2FpdCB0aGlzLmxvb2t1cC5oaWRkZW5Db2RlcyhkYXRhc2V0LCB2aWV3KTtcbiAgICBpZiAoY3R4LnN0YWxlKCkpIHJldHVybjtcbiAgICBjb25zdCBsYWJlbCA9IHZpZXcuY2VsbFNldCA9PT0gJ2JvdGgnID8gJ0NlbGxzIGFuZCBudWNsZWknIDogdmlldy5jZWxsU2V0ID09PSAnbnVjbGV1cycgPyAnTnVjbGVpJyA6ICdDZWxscyc7XG4gICAgY29uc3QgZ2VvbWV0cnkgPSBhd2FpdCBjdHgudHJhY2sobGFiZWwsIHRoaXMuY2VsbEdlb21ldHJ5KGRhdGFzZXQsIHZpZXcsIHJlY3QsIGxldmVsLCBoaWRkZW4sIGN0eCwgcHhQZXJVbml0KSk7XG4gICAgaWYgKCFnZW9tZXRyeSkgcmV0dXJuO1xuICAgIGNvbnN0IHsgcmluZ3MsIG51Y2xlaSwgZ2VvbWV0cnlLZXkgfSA9IGdlb21ldHJ5O1xuXG4gICAgY29uc3QgZ2VvbWV0cnlDaGFuZ2VkID0gZ2VvbWV0cnlLZXkgIT09IHRoaXMuY2VsbEdlb21ldHJ5S2V5O1xuICAgIGNvbnN0IHN0eWxlS2V5ID0gW1xuICAgICAgZ2VvbWV0cnlLZXksXG4gICAgICB2aWV3LmNlbGxDb2xvck1vZGUsXG4gICAgICB2aWV3LmNlbGxDb2xvckdlbmUsXG4gICAgICB2aWV3LmNlbGxDb2xvck1vZGUgPT09ICdjb2x1bW4nID8gSlNPTi5zdHJpbmdpZnkodmlldy5jb2xvckJ5KSA6ICcnLFxuICAgICAgdmlldy5jZWxsU2luZ2xlQ29sb3IsXG4gICAgICBjZWxsVHlwZUNvbHVtbkZvcihkYXRhc2V0LCB2aWV3KSxcbiAgICAgIHRoaXMuc2VsZWN0aW9uUmV2KHNlbGVjdGlvbiksXG4gICAgICB2aWV3LmxvZ1NjYWxlLFxuICAgICAgdmlldy5wZXJjZW50aWxlQ2xpcC5qb2luKCksXG4gICAgICBKU09OLnN0cmluZ2lmeSh2aWV3LmNvbnRpbnVvdXNDb2xvcm1hcCksXG4gICAgICB2aWV3LmNlbGxEcmF3LFxuICAgICAgdmlldy5jZWxsT3BhY2l0eSxcbiAgICAgIC8vIEFueSBncm91cGluZydzOiB0aGUgY2VsbHMgbWF5IGJlIGNvbG91cmVkIGJ5IHNlZ21lbnRhdGlvbiBtZXRob2QgcmF0aGVyIHRoYW4gdGhlIGNlbGwgdHlwZS5cbiAgICAgIEpTT04uc3RyaW5naWZ5KHZpZXcuZ3JvdXBDb2xvcnMpLFxuICAgIF0uam9pbignfCcpO1xuICAgIGNvbnN0IHByZXNlbnQgPSAoWydjZWxsRmlsbCcsICdjZWxsT3V0bGluZScsICdudWNsZXVzT3V0bGluZSddIGFzIGNvbnN0KS5zb21lKChnKSA9PiB0aGlzLmdyb3Vwcy5zaG93bihnKSk7XG4gICAgaWYgKCFnZW9tZXRyeUNoYW5nZWQgJiYgc3R5bGVLZXkgPT09IHRoaXMuY2VsbFN0eWxlS2V5ICYmIHByZXNlbnQpIHtcbiAgICAgIHRoaXMuc2V0UG9seWdvbnNTaG93bih0cnVlKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgY29sb3JzID0gYXdhaXQgdGhpcy5jZWxsQ29sb3JzKGRhdGFzZXQsIHZpZXcsIHNlbGVjdGlvbiwgcmluZ3Mub2JzZXJ2YXRpb24pO1xuICAgIGlmIChjdHguc3RhbGUoKSkgcmV0dXJuO1xuXG4gICAgdGhpcy5jdXJyZW50UmluZ3MgPSByaW5ncztcbiAgICB0aGlzLmN1cnJlbnROdWNsZWkgPSBudWNsZWk7XG4gICAgLy8gQSBnZW9tZXRyeSBtaXNzaW5nIGEgZmFpbGVkIHRpbGUgaXMgZHJhd24gYnV0IG5vdCByZW1lbWJlcmVkLCBzbyB0aGUgcmV0cnkgcmVmZXRjaGVzIGl0LlxuICAgIHRoaXMuY2VsbEdlb21ldHJ5S2V5ID0gY3R4LmluY29tcGxldGUgPyBudWxsIDogZ2VvbWV0cnlLZXk7XG4gICAgdGhpcy5jZWxsU3R5bGVLZXkgPSBzdHlsZUtleTtcbiAgICB0aGlzLmRyYXdDZWxscyhkYXRhc2V0LCB2aWV3LCBnZW9tZXRyeSwgY29sb3JzLCBnZW9tZXRyeUNoYW5nZWQpO1xuICAgIHRoaXMuc2V0UG9seWdvbnNTaG93bih0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgY2VsbCBsYXllcnM6IHRoZSBmaWxsIGFuZCB0aGUgb3V0bGluZSB0aGUgdmlldydzIGRyYXcgbW9kZSBhc2tzIGZvciwgYW5kIHdpdGggXCJib3RoXCIgdGhlXG4gICAqIG51Y2xldXMgb3V0bGluZXMgb3ZlciB0aGVtLiBBIGdlb21ldHJ5IGNoYW5nZSBidWlsZHMgbmV3IGxheWVyczsgYSBzdHlsZSBjaGFuZ2UgcmVzdHlsZXMgdGhlbS5cbiAgICovXG4gIHByaXZhdGUgZHJhd0NlbGxzKFxuICAgIGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0LFxuICAgIHZpZXc6IFNwYXRpYWxWaWV3U3RhdGUsXG4gICAgeyByaW5ncywgbnVjbGVpIH06IHsgcmluZ3M6IFNwYXRpYWxQb2x5Z29uVGlsZTsgbnVjbGVpOiBTcGF0aWFsUG9seWdvblRpbGUgfCBudWxsIH0sXG4gICAgY29sb3JzOiBDZWxsQ29sb3JzLFxuICAgIGdlb21ldHJ5Q2hhbmdlZDogYm9vbGVhbixcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgcmVmID0gZGF0YXNldC5pbWFnZVJlZjtcbiAgICBjb25zdCBjb21tb24gPSB7IHNjYWxlOiByZWY/LnNjYWxlID8/IFsxLCAxXSwgdHJhbnNsYXRlOiByZWY/LnRyYW5zbGF0ZSA/PyBbMCwgMF0gfSBhcyBjb25zdDtcbiAgICBjb25zdCBmaWxsID0gdmlldy5jZWxsRHJhdyAhPT0gJ291dGxpbmUnO1xuICAgIGNvbnN0IG91dGxpbmUgPSB2aWV3LmNlbGxEcmF3ICE9PSAnZmlsbCc7XG5cbiAgICB0aGlzLmdyb3Vwcy51cHNlcnRTaGFwZXMoJ2NlbGxGaWxsJywgZmlsbCwgZ2VvbWV0cnlDaGFuZ2VkLCByaW5ncywge1xuICAgICAgbmFtZTogJ2NlbGxzJyxcbiAgICAgIGRyYXc6ICdmaWxsJyxcbiAgICAgIG9wYWNpdHk6IHZpZXcuY2VsbE9wYWNpdHksXG4gICAgICAuLi5jb2xvcnMsXG4gICAgICAuLi5jb21tb24sXG4gICAgfSk7XG4gICAgdGhpcy5ncm91cHMudXBzZXJ0U2hhcGVzKFxuICAgICAgJ2NlbGxPdXRsaW5lJyxcbiAgICAgIG91dGxpbmUsXG4gICAgICBnZW9tZXRyeUNoYW5nZWQsXG4gICAgICByaW5ncyxcbiAgICAgIGZpbGxcbiAgICAgICAgPyAvLyBPdmVyIGEgZmlsbCwgYSBkYXJrIG91dGxpbmUgc2VwYXJhdGVzIG5laWdoYm91cnMgb2YgdGhlIHNhbWUgdHlwZS5cbiAgICAgICAgICB7IG5hbWU6ICdjZWxsIG91dGxpbmVzJywgZHJhdzogJ291dGxpbmUnLCBjb2xvcjogWzAuMDgsIDAuMDgsIDAuMSwgMV0sIG9wYWNpdHk6IDAuNywgLi4uY29tbW9uIH1cbiAgICAgICAgOiB7IG5hbWU6ICdjZWxsIG91dGxpbmVzJywgZHJhdzogJ291dGxpbmUnLCBvcGFjaXR5OiAxLCAuLi5jb2xvcnMsIC4uLmNvbW1vbiB9LFxuICAgICk7XG4gICAgLy8gXCJCb3RoXCI6IG51Y2xlaSBvdXRsaW5lZCBvdmVyIHRoZSBjZWxscywgbGlnaHQgc28gdGhleSByZWFkIGFnYWluc3QgYW55IGZpbGwuXG4gICAgaWYgKG51Y2xlaSkge1xuICAgICAgdGhpcy5ncm91cHMudXBzZXJ0U2hhcGVzKCdudWNsZXVzT3V0bGluZScsIHRydWUsIGdlb21ldHJ5Q2hhbmdlZCwgbnVjbGVpLCB7XG4gICAgICAgIG5hbWU6ICdudWNsZXVzIG91dGxpbmVzJyxcbiAgICAgICAgZHJhdzogJ291dGxpbmUnLFxuICAgICAgICBjb2xvcjogWzAuOTUsIDAuOTUsIDAuOTgsIDFdLFxuICAgICAgICBvcGFjaXR5OiAwLjgsXG4gICAgICAgIC4uLmNvbW1vbixcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmdyb3Vwcy5kcm9wKCdudWNsZXVzT3V0bGluZScpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2VsZWN0aW9uUmV2KHNlbGVjdGlvbjogU3BhdGlhbFNlbGVjdGlvbk1hc2spOiBudW1iZXIge1xuICAgIGlmIChzZWxlY3Rpb24gIT09IHRoaXMubGFzdFNlbGVjdGlvbikge1xuICAgICAgdGhpcy5sYXN0U2VsZWN0aW9uID0gc2VsZWN0aW9uO1xuICAgICAgdGhpcy5zZWxlY3Rpb25SZXZpc2lvbisrO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zZWxlY3Rpb25SZXZpc2lvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgcmluZ3MnIGNvbG91cnMgYnkgdGhlaXIgb3duZXJzLCBieSB0aGUgdmlldydzIGNlbGwtY29sb3VyIG1vZGUgKFhlbml1bSBFeHBsb3JlcidzIFwiQ2VsbFxuICAgKiBDb2xvclwiKTogb25lIFJHQkEgcGVyIHNoYXBlIGZvciBhIGdyb3VwaW5nLCB2YWx1ZXMgKyBjb2xvcm1hcCBmb3IgYSBtZWFzdXJlbWVudCwgb25lIGNvbG91clxuICAgKiBmb3IgXCJzaW5nbGVcIi4gQSBzZWxlY3Rpb24gbXV0ZXMgd2hhdCBpdCBsZWF2ZXMgb3V0LlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBjZWxsQ29sb3JzKFxuICAgIGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0LFxuICAgIHZpZXc6IFNwYXRpYWxWaWV3U3RhdGUsXG4gICAgc2VsZWN0aW9uOiBTcGF0aWFsU2VsZWN0aW9uTWFzayxcbiAgICBvd25lcnM6IFVpbnQzMkFycmF5LFxuICApOiBQcm9taXNlPENlbGxDb2xvcnM+IHtcbiAgICByZXR1cm4gY2VsbENvbG9yc0ZvcihcbiAgICAgIHtcbiAgICAgICAgcG9ydDogdGhpcy5wb3J0LFxuICAgICAgICBsb29rdXA6IHRoaXMubG9va3VwLFxuICAgICAgICBjb250cmFzdFdpbmRvd3M6IHRoaXMuY29udHJhc3RXaW5kb3dzLFxuICAgICAgICBjb250aW51b3VzTHV0OiAodikgPT4gdGhpcy5ob3N0LmNvbnRpbnVvdXNMdXQodiksXG4gICAgICB9LFxuICAgICAgZGF0YXNldCxcbiAgICAgIHZpZXcsXG4gICAgICBzZWxlY3Rpb24sXG4gICAgICBvd25lcnMsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgY2VsbCByaW5ncyAoYW5kLCBmb3IgXCJib3RoXCIsIHRoZSBudWNsZXVzIHJpbmdzKSBjb3ZlcmluZyBgcmVjdGAgYXQgYGxldmVsYCwgbWludXNcbiAgICogdGhlIGhpZGRlbiBncm91cHMg4oCUIHJldXNlZCB3aGVuIG5vdGhpbmcgdGhhdCBkZWNpZGVzIHRoZW0gY2hhbmdlZC4gTnVsbCB3aGVuIHRoZVxuICAgKiB2aWV3IHdlbnQgc3RhbGUgb3IgdGhlIGRhdGFzZXQgaGFzIG5vIHNldCB0byBkcmF3LlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBjZWxsR2VvbWV0cnkoXG4gICAgZGF0YXNldDogU3BhdGlhbERhdGFzZXQsXG4gICAgdmlldzogU3BhdGlhbFZpZXdTdGF0ZSxcbiAgICByZWN0OiBEYXRhUmVjdCxcbiAgICBsZXZlbDogbnVtYmVyLFxuICAgIGhpZGRlbjogSGlkZGVuQ29kZXMgfCBudWxsLFxuICAgIGN0eDogUGxhbkNvbnRleHQsXG4gICAgcHhQZXJVbml0ID0gMSxcbiAgKTogUHJvbWlzZTx7IHJpbmdzOiBTcGF0aWFsUG9seWdvblRpbGU7IG51Y2xlaTogU3BhdGlhbFBvbHlnb25UaWxlIHwgbnVsbDsgZ2VvbWV0cnlLZXk6IHN0cmluZyB9IHwgbnVsbD4ge1xuICAgIGNvbnN0IHRpbGVkID0gZGF0YXNldC5wb2x5Z29uVGlsZXM7XG4gICAgY29uc3QgaGlkZGVuS2V5ID0gYCR7dmlldy5oaWRkZW5Hcm91cHMuam9pbignXFx1MDAwMScpfXwke2dlbmVGaWx0ZXJLZXkodmlldyl9YDtcbiAgICBsZXQgcmluZ3M6IFNwYXRpYWxQb2x5Z29uVGlsZTtcbiAgICBsZXQgbnVjbGVpOiBTcGF0aWFsUG9seWdvblRpbGUgfCBudWxsID0gbnVsbDtcbiAgICBsZXQgZ2VvbWV0cnlLZXk6IHN0cmluZztcbiAgICBpZiAodGlsZWQpIHtcbiAgICAgIGNvbnN0IGRyYXduID0gZHJhd25DZWxsU2V0cyh0aWxlZCwgdmlldy5jZWxsU2V0KTtcbiAgICAgIGlmICghZHJhd24pIHJldHVybiBudWxsO1xuICAgICAgY29uc3QgeyBzZXQsIG51Y2xldXNTZXQgfSA9IGRyYXduO1xuICAgICAgY29uc3QgcmVnaW9uU291cmNlID0gdGlsZWQuc2V0cy5maW5kKChzKSA9PiBzLm5hbWUgPT09IHNldCk/LnJlZ2lvblNvdXJjZTtcbiAgICAgIGlmICghbnVjbGV1c1NldCAmJiByZWdpb25Tb3VyY2UgJiYgdGhpcy5wbGFuZSAhPT0gbnVsbCkge1xuICAgICAgICBjb25zdCBvblBsYW5lID0gYXdhaXQgdGhpcy5wbGFuZUdlb21ldHJ5KFxuICAgICAgICAgIGRhdGFzZXQsXG4gICAgICAgICAgc2V0LFxuICAgICAgICAgIHJlZ2lvblNvdXJjZSxcbiAgICAgICAgICByZWN0LFxuICAgICAgICAgIHB4UGVyVW5pdCxcbiAgICAgICAgICBoaWRkZW4sXG4gICAgICAgICAgaGlkZGVuS2V5LFxuICAgICAgICAgIGN0eCxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKG9uUGxhbmUgIT09IHVuZGVmaW5lZCkgcmV0dXJuIG9uUGxhbmU7XG4gICAgICB9XG4gICAgICBjb25zdCBrZXlzID0gdGlsZXNJblJlY3QocmVjdCwgbGV2ZWwsIHRpbGVkLmxldmVscywgdGlsZWQuYm91bmRzLCBNQVhfQ0VMTF9USUxFUyk7XG4gICAgICBnZW9tZXRyeUtleSA9IGAke2RhdGFzZXQuaWR9fCR7c2V0fXwke251Y2xldXNTZXQgPz8gJyd9fCR7aGlkZGVuS2V5fXwke2tleXMubWFwKHRpbGVJZCkuam9pbignLCcpfWA7XG4gICAgICBpZiAoZ2VvbWV0cnlLZXkgPT09IHRoaXMuY2VsbEdlb21ldHJ5S2V5ICYmIHRoaXMuY3VycmVudFJpbmdzKSB7XG4gICAgICAgIHJpbmdzID0gdGhpcy5jdXJyZW50UmluZ3M7XG4gICAgICAgIG51Y2xlaSA9IHRoaXMuY3VycmVudE51Y2xlaTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IFt0aWxlcywgbnVjbGV1c1RpbGVzXSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgICBjdHguZmV0Y2hBbGwoa2V5cywgKGspID0+IHRoaXMucG9ydC5nZXRQb2x5Z29uVGlsZSEoc2V0LCBrLmxldmVsLCBrLmd4LCBrLmd5KSksXG4gICAgICAgICAgbnVjbGV1c1NldFxuICAgICAgICAgICAgPyBjdHguZmV0Y2hBbGwoa2V5cywgKGspID0+IHRoaXMucG9ydC5nZXRQb2x5Z29uVGlsZSEobnVjbGV1c1NldCwgay5sZXZlbCwgay5neCwgay5neSkpXG4gICAgICAgICAgICA6IFByb21pc2UucmVzb2x2ZShudWxsKSxcbiAgICAgICAgXSk7XG4gICAgICAgIGlmIChjdHguc3RhbGUoKSkgcmV0dXJuIG51bGw7XG4gICAgICAgIHJpbmdzID0gZmlsdGVyUmluZ3MobWVyZ2VQb2x5Z29uVGlsZXModGlsZXMpLCBoaWRkZW4pO1xuICAgICAgICBudWNsZWkgPSBudWNsZXVzVGlsZXMgPyBmaWx0ZXJSaW5ncyhtZXJnZVBvbHlnb25UaWxlcyhudWNsZXVzVGlsZXMpLCBoaWRkZW4pIDogbnVsbDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZ2VvbWV0cnlLZXkgPSBgJHtkYXRhc2V0LmlkfXx3aG9sZXwke2hpZGRlbktleX1gO1xuICAgICAgaWYgKGdlb21ldHJ5S2V5ID09PSB0aGlzLmNlbGxHZW9tZXRyeUtleSAmJiB0aGlzLmN1cnJlbnRSaW5ncykge1xuICAgICAgICByaW5ncyA9IHRoaXMuY3VycmVudFJpbmdzO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgcG9seXM6IFNwYXRpYWxQb2x5Z29ucyA9IGF3YWl0IHRoaXMucG9ydC5nZXRQb2x5Z29ucyEoKTtcbiAgICAgICAgaWYgKGN0eC5zdGFsZSgpKSByZXR1cm4gbnVsbDtcbiAgICAgICAgLy8gV2hvbGUtZGF0YXNldCByaW5ncyBhcmUgaW5kZXgtYWxpZ25lZCB3aXRoIHRoZSBvYnNlcnZhdGlvbnMuXG4gICAgICAgIHJpbmdzID0gZmlsdGVyUmluZ3MoXG4gICAgICAgICAgeyAuLi5wb2x5cywgb2JzZXJ2YXRpb246IFVpbnQzMkFycmF5LmZyb20oeyBsZW5ndGg6IHBvbHlzLmNvdW50IH0sIChfdiwgaSkgPT4gaSkgfSxcbiAgICAgICAgICBoaWRkZW4sXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IHJpbmdzLCBudWNsZWksIGdlb21ldHJ5S2V5IH07XG4gIH1cblxuICAvKipcbiAgICogVGhlIGNlbGxzIG9mIGJvdW5kYXJ5IHNldCBgc2V0YCBvbiB0aGUgcGxhbmUgc2hvd24sIGZyb20gaXRzIHJlZ2lvbiBzZXQgKGByZWdpb25Tb3VyY2VgKTogdGhlXG4gICAqIHBsYW5lJ3MgdGlsZXMgbWVldGluZyBgcmVjdGAsIGF0IHRoZSBkZXRhaWwgdGhlIHpvb20gY2FsbHMgZm9yLCBlYWNoIG91dGxpbmUgb3duZWQgYnkgaXRzIGNlbGxcbiAgICogKGJ5IGl0cyBpZCBhbW9uZyB0aGUgb2JzZXJ2YXRpb25zJyksIG1pbnVzIHRoZSBoaWRkZW4gZ3JvdXBzLiBVbmRlZmluZWQgd2hlbiBpdCBjYW5ub3QgYmUgZHJhd25cbiAgICogc28gKG5vIG9ic2VydmF0aW9uIGlkcyB0byB0ZWxsIGl0cyBjZWxscyBieSwgbm8gcG9ydCB0byBvcGVuIHRoZSBzZXQsIG9yIGEgcGxhbmUgaXQgaGFzIG5vdCksIHNvXG4gICAqIHRoZSBzZXQncyBvd24gdGlsZXMgYXJlIGRyYXduOyBudWxsIHdoZW4gdGhlIHZpZXcgd2VudCBzdGFsZS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcGxhbmVHZW9tZXRyeShcbiAgICBkYXRhc2V0OiBTcGF0aWFsRGF0YXNldCxcbiAgICBzZXQ6IHN0cmluZyxcbiAgICByZWdpb25Tb3VyY2U6IHN0cmluZyxcbiAgICByZWN0OiBEYXRhUmVjdCxcbiAgICBweFBlclVuaXQ6IG51bWJlcixcbiAgICBoaWRkZW46IEhpZGRlbkNvZGVzIHwgbnVsbCxcbiAgICBoaWRkZW5LZXk6IHN0cmluZyxcbiAgICBjdHg6IFBsYW5Db250ZXh0LFxuICApOiBQcm9taXNlPHsgcmluZ3M6IFNwYXRpYWxQb2x5Z29uVGlsZTsgbnVjbGVpOiBudWxsOyBnZW9tZXRyeUtleTogc3RyaW5nIH0gfCBudWxsIHwgdW5kZWZpbmVkPiB7XG4gICAgY29uc3QgaW5kZXggPSBvYnNlcnZhdGlvbkluZGV4KGRhdGFzZXQub2JzZXJ2YXRpb25zKTtcbiAgICBjb25zdCBwbGFuZSA9IHRoaXMucGxhbmU7XG4gICAgaWYgKCFpbmRleCB8fCBwbGFuZSA9PT0gbnVsbCB8fCAhdGhpcy5wb3J0Lm9wZW5SZWdpb25TZXQpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgbGV0IHNvdXJjZTogUmVnaW9uU291cmNlO1xuICAgIHRyeSB7XG4gICAgICBzb3VyY2UgPSBhd2FpdCB0aGlzLm9wZW5QbGFuZVNvdXJjZShyZWdpb25Tb3VyY2UpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc29sZS53YXJuKFwiW25hcGFyaS1qc10gdGhlIGNlbGxzJyBwZXItcGxhbmUgb3V0bGluZXMgY291bGQgbm90IGJlIG9wZW5lZDogZHJhd24gYXMgb25lIHBlciBjZWxsXCIsIGVycik7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBpZiAoY3R4LnN0YWxlKCkpIHJldHVybiBudWxsO1xuICAgIGNvbnN0IGluZm8gPSBzb3VyY2UuaW5mbztcbiAgICBjb25zdCB6ID0gaW5mby5wbGFuZXNbcGxhbmVdO1xuICAgIGlmICh6ID09PSB1bmRlZmluZWQpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgLy8gVGhlIHJlZ2lvbiBzZXQncyBjb29yZGluYXRlcyBhcmUgdGhlIGltYWdlJ3MgcGl4ZWxzOiB0aGUgdmlldydzIHJlY3RhbmdsZSBhbmQgem9vbSBpbiB0aGVtLlxuICAgIGNvbnN0IHJlZiA9IGRhdGFzZXQuaW1hZ2VSZWY7XG4gICAgY29uc3QgW3N4LCBzeV0gPSByZWY/LnNjYWxlID8/IFsxLCAxXTtcbiAgICBjb25zdCBbdHgsIHR5XSA9IHJlZj8udHJhbnNsYXRlID8/IFswLCAwXTtcbiAgICBjb25zdCBib3g6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0gW1xuICAgICAgcmVjdC54MCAqIHN4ICsgdHgsXG4gICAgICByZWN0LnkwICogc3kgKyB0eSxcbiAgICAgIHJlY3QueDEgKiBzeCArIHR4LFxuICAgICAgcmVjdC55MSAqIHN5ICsgdHksXG4gICAgXTtcbiAgICBjb25zdCBsZXZlbCA9IHJlZ2lvbkxldmVsRm9yKHB4UGVyVW5pdCAvIE1hdGguYWJzKHN4IHx8IDEpLCBpbmZvLmxldmVscyk7XG4gICAgY29uc3Qga2V5cyA9IHJlZ2lvblRpbGVzSW5SZWN0KGJveCwgbGV2ZWwsIGluZm8udGlsZVNpemUsIGluZm8uYm91bmRzLCBNQVhfQ0VMTF9USUxFUyk7XG4gICAgY29uc3QgZ2VvbWV0cnlLZXkgPSBgJHtkYXRhc2V0LmlkfXwke3NldH18cGxhbmUgJHtwbGFuZX18JHtoaWRkZW5LZXl9fCR7a2V5cy5tYXAocmVnaW9uVGlsZUlkKS5qb2luKCcsJyl9YDtcbiAgICBpZiAoZ2VvbWV0cnlLZXkgPT09IHRoaXMuY2VsbEdlb21ldHJ5S2V5ICYmIHRoaXMuY3VycmVudFJpbmdzKSB7XG4gICAgICByZXR1cm4geyByaW5nczogdGhpcy5jdXJyZW50UmluZ3MsIG51Y2xlaTogbnVsbCwgZ2VvbWV0cnlLZXkgfTtcbiAgICB9XG4gICAgY29uc3QgdGlsZXMgPSBhd2FpdCBjdHguZmV0Y2hBbGwoa2V5cywgKGspID0+IHNvdXJjZS5nZXRUaWxlKHosIGspKTtcbiAgICBpZiAoY3R4LnN0YWxlKCkpIHJldHVybiBudWxsO1xuICAgIGNvbnN0IHJpbmdzID0gZmlsdGVyUmluZ3MocGxhbmVDZWxsUmluZ3ModGlsZXMsIGluZGV4LCByZWYpLCBoaWRkZW4pO1xuICAgIHJldHVybiB7IHJpbmdzLCBudWNsZWk6IG51bGwsIGdlb21ldHJ5S2V5IH07XG4gIH1cblxuICAvKiogVGhlIHJlZ2lvbiBzZXQgYGlkYCwgb3BlbmVkIG9uY2UgKGFub3RoZXIgaWQgY2xvc2VzIHRoZSBvbmUgYmVmb3JlKS4gKi9cbiAgcHJpdmF0ZSBvcGVuUGxhbmVTb3VyY2UoaWQ6IHN0cmluZyk6IFByb21pc2U8UmVnaW9uU291cmNlPiB7XG4gICAgaWYgKHRoaXMucGxhbmVTb3VyY2U/LmlkICE9PSBpZCkge1xuICAgICAgdGhpcy5kaXNwb3NlKCk7XG4gICAgICBjb25zdCBzb3VyY2UgPSB0aGlzLnBvcnQub3BlblJlZ2lvblNldCEoaWQpO1xuICAgICAgdGhpcy5wbGFuZVNvdXJjZSA9IHsgaWQsIHNvdXJjZSB9O1xuICAgICAgLy8gQSBzZXQgdGhhdCBmYWlsZWQgdG8gb3BlbiBpcyBhc2tlZCBmb3IgYWdhaW4gbmV4dCB0aW1lLlxuICAgICAgc291cmNlLmNhdGNoKCgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMucGxhbmVTb3VyY2U/LnNvdXJjZSA9PT0gc291cmNlKSB0aGlzLnBsYW5lU291cmNlID0gbnVsbDtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5wbGFuZVNvdXJjZSEuc291cmNlO1xuICB9XG5cbiAgLyoqIFJlbW92ZSB0aGUgY2VsbCBsYXllcnMgYW5kIGZvcmdldCB3aGF0IHRoZXkgc2hvd2VkLiAqL1xuICBkcm9wKCk6IHZvaWQge1xuICAgIHRoaXMuZ3JvdXBzLmRyb3AoJ2NlbGxGaWxsJyk7XG4gICAgdGhpcy5ncm91cHMuZHJvcCgnY2VsbE91dGxpbmUnKTtcbiAgICB0aGlzLmdyb3Vwcy5kcm9wKCdudWNsZXVzT3V0bGluZScpO1xuICAgIHRoaXMuY3VycmVudE51Y2xlaSA9IG51bGw7XG4gICAgdGhpcy5jZWxsR2VvbWV0cnlLZXkgPSBudWxsO1xuICAgIHRoaXMuY2VsbFN0eWxlS2V5ID0gbnVsbDtcbiAgICB0aGlzLmN1cnJlbnRSaW5ncyA9IG51bGw7XG4gICAgdGhpcy5zZXRQb2x5Z29uc1Nob3duKGZhbHNlKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0UG9seWdvbnNTaG93bihzaG93bjogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmIChzaG93biA9PT0gdGhpcy5wb2x5Z29uc1Nob3duKSByZXR1cm47XG4gICAgdGhpcy5wb2x5Z29uc1Nob3duID0gc2hvd247XG4gICAgdGhpcy5ob3N0LnBvbHlnb25zU2hvd25DaGFuZ2VkKHNob3duKTtcbiAgfVxufVxuXG4vKiogV2hhdCB7QGxpbmsgY2VsbENvbG9yc0Zvcn0gcmVhZHMgd2l0aDogdGhlIHBvcnQsIHRoZSBjYXRlZ29yaWNhbCBjb2x1bW5zLCB0aGUgd2luZG93cyBjYWNoZSwgdGhlIExVVC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2VsbENvbG9yRGVwcyB7XG4gIHBvcnQ6IFNwYXRpYWxEYXRhUG9ydDtcbiAgbG9va3VwOiBDYXRlZ29yaWNhbExvb2t1cDtcbiAgY29udHJhc3RXaW5kb3dzOiBDb250cmFzdFdpbmRvd0NhY2hlO1xuICBjb250aW51b3VzTHV0KHZpZXc6IFNwYXRpYWxWaWV3U3RhdGUpOiBSZ2JbXTtcbn1cblxuLyoqXG4gKiBUaGUgY2VsbHMnIGNvbG91cnMgYnkgdGhlaXIgb3duZXJzIChgb3duZXJzW2ldYCB0aGUgb2JzZXJ2YXRpb24gb2Ygc2hhcGUgaSksIGJ5IHRoZSB2aWV3J3NcbiAqIGNlbGwtY29sb3VyIG1vZGUgKFhlbml1bSBFeHBsb3JlcidzIFwiQ2VsbCBDb2xvclwiKTogb25lIFJHQkEgcGVyIHNoYXBlIGZvciBhIGdyb3VwaW5nLCB2YWx1ZXMgK1xuICogY29sb3JtYXAgZm9yIGEgbWVhc3VyZW1lbnQsIG9uZSBjb2xvdXIgZm9yIFwic2luZ2xlXCIuIEEgc2VsZWN0aW9uIG11dGVzIHdoYXQgaXQgbGVhdmVzIG91dC4gVGhlIDJEXG4gKiBjZWxsIG91dGxpbmVzIGFuZCB0aGUgM0QgY2VsbHMgYm90aCBjb2xvdXIgYnkgaXQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjZWxsQ29sb3JzRm9yKFxuICBkZXBzOiBDZWxsQ29sb3JEZXBzLFxuICBkYXRhc2V0OiBTcGF0aWFsRGF0YXNldCxcbiAgdmlldzogU3BhdGlhbFZpZXdTdGF0ZSxcbiAgc2VsZWN0aW9uOiBTcGF0aWFsU2VsZWN0aW9uTWFzayxcbiAgb3duZXJzOiBVaW50MzJBcnJheSxcbik6IFByb21pc2U8Q2VsbENvbG9ycz4ge1xuICBjb25zdCBtdXRlZCA9IHNlbGVjdGlvbi5jb3VudCA+IDAgPyBzZWxlY3Rpb24ubWFzayA6IG51bGw7XG4gIGNvbnN0IG1vZGUgPSB2aWV3LmNlbGxDb2xvck1vZGU7XG5cbiAgaWYgKG1vZGUgPT09ICdzaW5nbGUnKSB7XG4gICAgY29uc3QgW3IsIGcsIGJdID0gcGFyc2VIZXgodmlldy5jZWxsU2luZ2xlQ29sb3IpO1xuICAgIHJldHVybiB7IGNvbG9yOiBbciAvIDI1NSwgZyAvIDI1NSwgYiAvIDI1NSwgMV0gfTtcbiAgfVxuXG4gIGNvbnN0IGNvbnRpbnVvdXMgPSBhc3luYyAocmF3OiBGbG9hdDMyQXJyYXksIGxvZzogYm9vbGVhbikgPT4ge1xuICAgIGNvbnN0IHZhbHVlcyA9IG5ldyBGbG9hdDMyQXJyYXkob3duZXJzLmxlbmd0aCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvd25lcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHYgPSByYXdbb3duZXJzW2ldXSA/PyBOYU47XG4gICAgICB2YWx1ZXNbaV0gPSBsb2cgPyBNYXRoLmxvZzFwKE1hdGgubWF4KDAsIHYpKSA6IHY7XG4gICAgfVxuICAgIGNvbnN0IFtjbGlwTG8sIGNsaXBIaV0gPSB2aWV3LnBlcmNlbnRpbGVDbGlwO1xuICAgIC8vIEtleWVkIGJ5IHRoZSBTT1VSQ0UgdmVjdG9yICh0aGUgbG9nIGNvcHkgd291bGQgYmUgbmV3IG9uIGV2ZXJ5IGNhbGwpLCBhcyB0aGUgM0QgY2xvdWQncy5cbiAgICBjb25zdCBbbG8sIGhpXSA9IGRlcHMuY29udHJhc3RXaW5kb3dzLmdldChyYXcsIGNsaXBMbywgY2xpcEhpLCBsb2csICgpID0+XG4gICAgICBjb250cmFzdFdpbmRvdyhsb2cgPyByYXcubWFwKCh2KSA9PiBNYXRoLmxvZzFwKE1hdGgubWF4KDAsIHYpKSkgOiByYXcsIGNsaXBMbywgY2xpcEhpKSxcbiAgICApO1xuICAgIHJldHVybiB7XG4gICAgICB2YWx1ZXMsXG4gICAgICBjb2xvcm1hcDogY29sb3JtYXBGcm9tTHV0KCdzcGF0aWFsLWNvbnRpbnVvdXMnLCBkZXBzLmNvbnRpbnVvdXNMdXQodmlldykpLFxuICAgICAgY29udHJhc3RMaW1pdHM6IFtsbywgaGldIGFzIFtudW1iZXIsIG51bWJlcl0sXG4gICAgfTtcbiAgfTtcbiAgaWYgKG1vZGUgPT09ICdnZW5lJyAmJiB2aWV3LmNlbGxDb2xvckdlbmUpIHtcbiAgICByZXR1cm4gY29udGludW91cyhhd2FpdCBkZXBzLnBvcnQuZ2V0RmVhdHVyZVZlY3Rvcih2aWV3LmNlbGxDb2xvckdlbmUpLCB0cnVlKTtcbiAgfVxuICAvLyBBIG1lYXN1cmVtZW50OiB0aGUgbnVtZXJpYyBjb2x1bW4gdGhlIG9ic2VydmF0aW9ucyBhcmUgY29sb3VyZWQgYnksIGFzIHRoZSBtYXJrZXJzIGFyZS5cbiAgaWYgKG1vZGUgPT09ICdjb2x1bW4nICYmIHZpZXcuY29sb3JCeT8ua2luZCA9PT0gJ2NvbHVtbicpIHtcbiAgICBjb25zdCBjb2x1bW4gPSBhd2FpdCBkZXBzLnBvcnQuZ2V0Q29sdW1uKHZpZXcuY29sb3JCeS5uYW1lKTtcbiAgICBpZiAoIWlzQ2F0ZWdvcmljYWxDb2x1bW4oY29sdW1uKSkgcmV0dXJuIGNvbnRpbnVvdXMoY29sdW1uLnZhbHVlcywgdmlldy5sb2dTY2FsZSk7XG4gIH1cbiAgaWYgKG1vZGUgPT09ICd0cmFuc2NyaXB0RGVuc2l0eScgJiYgZGF0YXNldC5jb2x1bW5zLnNvbWUoKGMpID0+IGMubmFtZSA9PT0gJ3RyYW5zY3JpcHRfZGVuc2l0eScpKSB7XG4gICAgY29uc3QgY29sdW1uID0gYXdhaXQgZGVwcy5wb3J0LmdldENvbHVtbigndHJhbnNjcmlwdF9kZW5zaXR5Jyk7XG4gICAgaWYgKCFpc0NhdGVnb3JpY2FsQ29sdW1uKGNvbHVtbikpIHJldHVybiBjb250aW51b3VzKGNvbHVtbi52YWx1ZXMsIGZhbHNlKTtcbiAgfVxuXG4gIGNvbnN0IG5hbWUgPVxuICAgIG1vZGUgPT09ICdzZWdtZW50YXRpb24nICYmIGRhdGFzZXQuY29sdW1ucy5zb21lKChjKSA9PiBjLm5hbWUgPT09ICdzZWdtZW50YXRpb25fbWV0aG9kJylcbiAgICAgID8gJ3NlZ21lbnRhdGlvbl9tZXRob2QnXG4gICAgICA6IGNlbGxUeXBlQ29sdW1uRm9yKGRhdGFzZXQsIHZpZXcpO1xuICBjb25zdCBjb2RlcyA9IG5hbWUgPyBhd2FpdCBkZXBzLmxvb2t1cC5jb2RlcyhuYW1lKSA6IG51bGw7XG4gIGNvbnN0IHBhbGV0dGUgPSBjYXRlZ29yeVJnYmEobmFtZSwgY29kZXM/Lm1ldGEgPz8gbnVsbCwgdmlldy5ncm91cENvbG9ycyk7XG4gIGNvbnN0IG1pc3NpbmcgPSByZ2JhMDEoTUlTU0lOR19DT0xPUik7XG4gIC8vIE9uZSBSR0JBIHBlciBzaGFwZSAobmFwYXJpIFNoYXBlcycgYGZhY2VfY29sb3JgKTogYW55IG51bWJlciBvZiBjYXRlZ29yaWVzIGtlZXBzIGl0cyBvd25cbiAgLy8gY29sb3VyLCB3aGVyZSBhIGNvbG9ybWFwIGJhbmQgcGVyIGNhdGVnb3J5IHJhbiBvdXQgb2YgTFVUIGVudHJpZXMgcGFzdCB+MTI3LlxuICBjb25zdCBmYWNlQ29sb3IgPSBuZXcgRmxvYXQzMkFycmF5KG93bmVycy5sZW5ndGggKiA0KTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBvd25lcnMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBvID0gb3duZXJzW2ldO1xuICAgIGNvbnN0IGNvZGUgPSAhY29kZXMgfHwgKG11dGVkICYmICFtdXRlZFtvXSkgPyBOT19DQVRFR09SWSA6IGNvZGVzLmNvZGVzW29dO1xuICAgIGZhY2VDb2xvci5zZXQocGFsZXR0ZVtjb2RlXSA/PyBtaXNzaW5nLCBpICogNCk7XG4gIH1cbiAgcmV0dXJuIHsgZmFjZUNvbG9yIH07XG59XG5cbi8qKiB7QGxpbmsgY2VsbENvbG9yc0Zvcn0ncyBjb2xvdXJzIGFzIG9uZSBSR0JBICgwLi4xKSBwZXIgc2hhcGUsIGBuYCBzaGFwZXMuICovXG5leHBvcnQgZnVuY3Rpb24gY2VsbENvbG9yc1JnYmEoY29sb3JzOiBDZWxsQ29sb3JzLCBuOiBudW1iZXIpOiBGbG9hdDMyQXJyYXkge1xuICBpZiAoY29sb3JzLmZhY2VDb2xvcikgcmV0dXJuIGNvbG9ycy5mYWNlQ29sb3I7XG4gIGNvbnN0IG91dCA9IG5ldyBGbG9hdDMyQXJyYXkobiAqIDQpO1xuICBpZiAoY29sb3JzLnZhbHVlcyAmJiBjb2xvcnMuY29sb3JtYXAgJiYgY29sb3JzLmNvbnRyYXN0TGltaXRzKSB7XG4gICAgY29uc3QgW2NsaW1MbywgY2xpbUhpXSA9IGNvbG9ycy5jb250cmFzdExpbWl0cztcbiAgICBjb25zdCBvcHRzID0geyBjbGltTG8sIGNsaW1IaSwgZ2FtbWE6IDEsIGludmVydDogZmFsc2UsIGNvbG9ybWFwOiBjb2xvcnMuY29sb3JtYXAgfTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykge1xuICAgICAgY29uc3QgdiA9IGNvbG9ycy52YWx1ZXNbaV07XG4gICAgICBvdXQuc2V0KE51bWJlci5pc0Zpbml0ZSh2KSA/IG1hcFNjYWxhclJHQkEodiwgb3B0cykgOiBbMC41LCAwLjUsIDAuNSwgMV0sIGkgKiA0KTtcbiAgICB9XG4gICAgcmV0dXJuIG91dDtcbiAgfVxuICBjb25zdCBjID0gY29sb3JzLmNvbG9yID8/IFsxLCAxLCAxLCAxXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIG91dC5zZXQoYywgaSAqIDQpO1xuICByZXR1cm4gb3V0O1xufVxuXG4vKiogQW4gOC1iaXQgUkdCIGFzIGFuIG9wYXF1ZSAwLi4xIFJHQkEuICovXG5mdW5jdGlvbiByZ2JhMDEoW3IsIGcsIGJdOiByZWFkb25seSBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0pOiBSR0JBIHtcbiAgcmV0dXJuIFtyIC8gMjU1LCBnIC8gMjU1LCBiIC8gMjU1LCAxXTtcbn1cblxuLyoqIEEgZ3JvdXBpbmcncyBjYXRlZ29yeSBjb2xvdXJzLCBhcyAwLi4xIFJHQkEgYnkgY2F0ZWdvcnkgY29kZSAob25lIGRlZmF1bHQgd2l0aG91dCBhIGdyb3VwaW5nKS4gKi9cbmZ1bmN0aW9uIGNhdGVnb3J5UmdiYShcbiAgbmFtZTogc3RyaW5nIHwgbnVsbCxcbiAgbWV0YTogU3BhdGlhbENvbHVtblsnbWV0YSddIHwgbnVsbCxcbiAgb3ZlcnJpZGVzOiBHcm91cENvbG9yT3ZlcnJpZGVzIHwgdW5kZWZpbmVkLFxuKTogUkdCQVtdIHtcbiAgY29uc3QgaGV4ID1cbiAgICBuYW1lICYmIG1ldGEgJiYgbWV0YS5raW5kID09PSAnY2F0ZWdvcmljYWwnXG4gICAgICA/IGNhdGVnb3J5Q29sb3JzRm9yKG5hbWUsIG1ldGEsIG92ZXJyaWRlcylcbiAgICAgIDogW0RFRkFVTFRfQ0FURUdPUklDQUxfUEFMRVRURVswXV07XG4gIHJldHVybiBoZXgubWFwKChoKSA9PiByZ2JhMDEocGFyc2VIZXgoaCkpKTtcbn1cbiJdfQ==