@jax-data-science/sci-image-visualizer 0.17.0 → 0.18.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.
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-CBiLcnE6.mjs} +4521 -759
  61. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CBiLcnE6.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-BXHjv4PE.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-BXHjv4PE.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,10 +1,10 @@
1
1
  import { ALL_GENES } from '../../contracts/ports/spatial-data.port';
2
2
  import { NO_CATEGORY, NO_OBSERVATION, isCategoricalColumn, } from '../../contracts/spatial-dataset.contract';
3
- import { DEFAULT_CATEGORICAL_PALETTE, categoryColorsFor, parseHex } from '../../spatial/spatial-encoding';
3
+ import { DEFAULT_CATEGORICAL_PALETTE, DEFAULT_MUTED_OPACITY, categoryColorsFor, parseHex, } from '../../spatial/spatial-encoding';
4
4
  import { allGeneShownBy, allGenesHidden } from '../../spatial/spatial-tile-merge';
5
5
  import { cellTypeColumnFor } from '../../spatial/spatial-tiles';
6
6
  import { clusterColorMap, clusterOfGene } from '../../spatial/transcript-grouping';
7
- import { tilesInRect } from '../../spatial/lod';
7
+ import { tilesInRect, transcriptLevelFor } from '../../spatial/lod';
8
8
  import { Supersede } from '../../util/supersede';
9
9
  /** Most transcripts drawn in the 3D view: past it, every k-th one is drawn (and the console says so). */
10
10
  export const TRANSCRIPTS_3D_MAX = 2_000_000;
@@ -12,6 +12,14 @@ export const TRANSCRIPTS_3D_MAX = 2_000_000;
12
12
  export const TRANSCRIPTS_3D_MAX_TILES = 4096;
13
13
  /** Tile reads in flight at once. */
14
14
  const CONCURRENCY = 8;
15
+ /** The camera resting this long plans the transcripts' detail again. */
16
+ const CAMERA_REST_MS = 300;
17
+ /** Transcript tiles kept read. */
18
+ const TILE_CACHE_SIZE = 1024;
19
+ /** Most tiles read for one view: past them, a coarser level. */
20
+ const VIEW_TILES_MAX = 256;
21
+ /** How far along a ray that never meets the section's plane its reach is taken (world units). */
22
+ const HORIZON = 1e6;
15
23
  /** A transcript's marker in the 3D view, in screen pixels at a transcript scale of 1. */
16
24
  export const TRANSCRIPT_3D_BASE_SIZE = 2;
17
25
  /** A transcript with no colour by cell type (in no cell, or a cell in no group), as the 2D markers. */
@@ -78,12 +86,15 @@ function packed(count, at) {
78
86
  return out;
79
87
  }
80
88
  /**
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.
89
+ * The transcripts of the 3D spatial view: the molecules of the genes the Transcripts panel draws
90
+ * (its selected genes, or "All genes"), at their own x, y and z, in the cloud's box and Z stretch.
83
91
  *
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.
92
+ * By level of detail, as the 2D view reads them: the pyramid level the camera's distance calls for
93
+ * (`transcriptLevelFor`, the markers per screen kept about constant: aggregates far out, every
94
+ * molecule close in on a cell), and only the tiles of the part of the section in view (the canvas's
95
+ * corners cast onto the section's plane). Planned again when the camera rests; tiles are cached, so
96
+ * coming back reads nothing. "Loading transcripts…" shows on the canvas while they load and draw.
97
+ * Drawn only for a dataset whose transcripts carry z.
87
98
  */
88
99
  export class Spatial3dTranscripts {
89
100
  constructor(viewer, begin) {
@@ -95,39 +106,151 @@ export class Spatial3dTranscripts {
95
106
  this.styleKey = null;
96
107
  this.loaded = null;
97
108
  this.loads = new Supersede();
109
+ /** Each drawn transcript's cell ({@link NO_OBSERVATION} for none), for fading by the selection. */
110
+ this.drawnCells = null;
111
+ /** The selection the layer's alphas fade by (null: none, every transcript as it is). */
112
+ this.fadedBy = null;
113
+ /** The last sync's inputs: the camera resting plans the detail again from them. */
114
+ this.last = null;
115
+ this.cameraTimer = null;
116
+ this.cameraOff = null;
117
+ /** Tiles read, by genes, quality, level and tile (least recently used dropped first). */
118
+ this.tileCache = new Map();
119
+ this.cameraOff = viewer.camera3d?.changed?.connect(() => this.cameraMoved()) ?? null;
120
+ }
121
+ /** The camera moved: once it rests, read the level and tiles it now calls for. */
122
+ cameraMoved() {
123
+ if (!this.last)
124
+ return;
125
+ if (this.cameraTimer)
126
+ clearTimeout(this.cameraTimer);
127
+ this.cameraTimer = setTimeout(() => {
128
+ this.cameraTimer = null;
129
+ const last = this.last;
130
+ if (last)
131
+ void this.sync(last.dataset, last.view, last.port, last.frame, last.selection);
132
+ }, CAMERA_REST_MS);
133
+ }
134
+ /** Stop following the camera (the scene went away). */
135
+ dispose() {
136
+ this.cameraOff?.();
137
+ this.cameraOff = null;
138
+ if (this.cameraTimer)
139
+ clearTimeout(this.cameraTimer);
140
+ this.cameraTimer = null;
141
+ this.last = null;
142
+ this.remove();
143
+ }
144
+ /**
145
+ * The level and the tiles the camera calls for: the level whose tiles come out about 512 screen
146
+ * pixels across at the target's depth, the tiles of the section in view (whole, when a corner of
147
+ * the canvas looks past the section's plane).
148
+ */
149
+ plan(meta, frame) {
150
+ const [vw, vh] = this.viewer.viewportSize?.() ?? [0, 0];
151
+ const camera = this.viewer.camera3d;
152
+ const wpp = camera && vh > 0 ? camera.worldPerPixel(vh) : 0;
153
+ let level = wpp > 0 ? transcriptLevelFor(1 / wpp, meta.levels) : meta.levels.length - 1;
154
+ const [x0, y0, x1, y1] = meta.bounds;
155
+ let rect = { x0, y0, x1: x1 + 1e-6, y1: y1 + 1e-6 };
156
+ const seen = vw > 0 && vh > 0 ? this.footprint(vw, vh, frame) : null;
157
+ if (seen)
158
+ rect = seen;
159
+ // Close in but looking far across the section: coarser, until the tiles in view are few enough.
160
+ let keys = tilesInRect(rect, level, meta.levels, meta.bounds);
161
+ while (keys.length > VIEW_TILES_MAX && level < meta.levels.length - 1) {
162
+ level++;
163
+ keys = tilesInRect(rect, level, meta.levels, meta.bounds);
164
+ }
165
+ return { level, keys };
166
+ }
167
+ /**
168
+ * The part of the section the canvas sees, in observation units: its corners and centre cast onto
169
+ * the plane through the camera's target, widened by a quarter. A corner looking past the plane
170
+ * (towards the horizon) reaches far along its ray instead (the tiles are clipped to the section).
171
+ */
172
+ footprint(vw, vh, frame) {
173
+ const z = this.viewer.camera3d?.target?.[2];
174
+ if (z === undefined || !this.viewer.canvasRay)
175
+ return null;
176
+ const [ox, oy] = frame.origin;
177
+ let xa = Infinity, ya = Infinity, xb = -Infinity, yb = -Infinity;
178
+ for (const [cx, cy] of [
179
+ [0, 0],
180
+ [vw, 0],
181
+ [0, vh],
182
+ [vw, vh],
183
+ [vw / 2, vh / 2],
184
+ ]) {
185
+ const ray = this.viewer.canvasRay(cx, cy);
186
+ if (!ray)
187
+ return null;
188
+ const hit = Math.abs(ray.dir[2]) > 1e-6 ? (z - ray.origin[2]) / ray.dir[2] : -1;
189
+ const t = hit > 0 ? hit : HORIZON;
190
+ const x = ray.origin[0] + ray.dir[0] * t - ox;
191
+ const y = ray.origin[1] + ray.dir[1] * t - oy;
192
+ xa = Math.min(xa, x);
193
+ ya = Math.min(ya, y);
194
+ xb = Math.max(xb, x);
195
+ yb = Math.max(yb, y);
196
+ }
197
+ const mx = (xb - xa) / 4;
198
+ const my = (yb - ya) / 4;
199
+ return { x0: xa - mx, y0: ya - my, x1: xb + mx, y1: yb + my };
200
+ }
201
+ /** A tile, read once (and again only once dropped from the cache). */
202
+ tile(key, read) {
203
+ let hit = this.tileCache.get(key);
204
+ if (hit) {
205
+ this.tileCache.delete(key);
206
+ this.tileCache.set(key, hit);
207
+ return hit;
208
+ }
209
+ hit = read();
210
+ hit.catch(() => this.tileCache.delete(key));
211
+ this.tileCache.set(key, hit);
212
+ while (this.tileCache.size > TILE_CACHE_SIZE)
213
+ this.tileCache.delete(this.tileCache.keys().next().value);
214
+ return hit;
98
215
  }
99
216
  /** The layer drawn, if any (for tests and the scene's Z stretch). */
100
217
  get drawn() {
101
218
  return this.layer;
102
219
  }
103
- /** Draw what `view` asks for, loading the molecules when the genes changed. */
104
- async sync(dataset, view, port, frame) {
220
+ /**
221
+ * Draw what `view` asks for, loading the molecules when the genes changed. With a `selection`
222
+ * (a cell, or a cell type's cells), the transcripts of the selected cells keep their colour and
223
+ * the others fade, as the cells do.
224
+ */
225
+ async sync(dataset, view, port, frame, selection = null) {
105
226
  const meta = dataset.transcriptTiles;
106
227
  const genes = meta?.hasZ && port?.getTranscriptTile ? transcripts3dGenes(dataset, view) : null;
107
228
  if (!meta || !genes || !port) {
229
+ // Off (or no gene shown): a camera move must not bring back the last view that drew some.
230
+ this.last = null;
231
+ if (this.cameraTimer)
232
+ clearTimeout(this.cameraTimer);
233
+ this.cameraTimer = null;
108
234
  this.remove();
109
235
  return;
110
236
  }
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
- }
237
+ this.last = { dataset, view, port, frame, selection };
116
238
  const quality = view.transcriptQuality === 'all' ? 'all' : 'high';
117
- const loadKey = `${dataset.id}|${genes.query.join('\u0001')}|${quality}`;
239
+ const { level, keys } = this.plan(meta, frame);
240
+ const genesKey = `${dataset.id}|${genes.query.join('\u0001')}|${quality}`;
241
+ const loadKey = `${genesKey}|${level}|${keys.map((k) => `${k.gx},${k.gy}`).join(';')}`;
242
+ let end = null;
118
243
  if (loadKey !== this.loadKey) {
119
244
  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
245
  if (keys.length > TRANSCRIPTS_3D_MAX_TILES) {
123
246
  console.warn(`[napari-js] ${keys.length} transcript tiles are too many to read for the 3D view`);
124
247
  this.remove();
125
248
  return;
126
249
  }
127
- const end = this.begin('Transcripts');
250
+ end = this.begin('Loading transcripts…');
128
251
  let tiles;
129
252
  try {
130
- tiles = await pooled(keys, CONCURRENCY, (k) => port.getTranscriptTile(0, k.gx, k.gy, { genes: genes.query, quality }));
253
+ tiles = await pooled(keys, CONCURRENCY, (k) => this.tile(`${genesKey}|${level}/${k.gx}/${k.gy}`, () => port.getTranscriptTile(level, k.gx, k.gy, { genes: genes.query, quality })));
131
254
  }
132
255
  catch (err) {
133
256
  console.warn('[napari-js] transcripts for the 3D view could not be read', err);
@@ -136,18 +259,26 @@ export class Spatial3dTranscripts {
136
259
  // current load may: a superseded one must not tear down what a newer one drew.
137
260
  if (task())
138
261
  this.clearLayer();
262
+ end();
139
263
  return;
140
264
  }
141
- finally {
265
+ if (!task()) {
142
266
  end();
143
- }
144
- if (!task())
145
267
  return;
268
+ }
146
269
  this.loadKey = loadKey;
147
270
  this.styleKey = null;
148
271
  this.loaded = { tiles, names: genes.allGenes ? (meta.genes ?? null) : genes.query };
149
272
  }
150
- await this.draw(dataset, view, port, frame, genes.allGenes);
273
+ try {
274
+ await this.draw(dataset, view, port, frame, genes.allGenes);
275
+ // The newest sync's selection: an older draw finishing late must not fade by a stale one.
276
+ if (this.last?.selection === selection)
277
+ this.fade(selection);
278
+ }
279
+ finally {
280
+ end?.();
281
+ }
151
282
  }
152
283
  /** Follow the scene's Z stretch (nothing is re-uploaded). */
153
284
  setZScale(s) {
@@ -166,6 +297,30 @@ export class Spatial3dTranscripts {
166
297
  this.loadKey = null;
167
298
  this.styleKey = null;
168
299
  this.loaded = null;
300
+ this.drawnCells = null;
301
+ this.fadedBy = null;
302
+ }
303
+ /**
304
+ * Fade the drawn transcripts outside the selection (their alpha only: the colours stay
305
+ * uploaded), or bring them all back without one. A no-op for the selection already applied.
306
+ */
307
+ fade(selection) {
308
+ const live = selection && selection.count > 0 ? selection : null;
309
+ const layer = this.layer;
310
+ const cells = this.drawnCells;
311
+ if (!layer || !cells || live === this.fadedBy)
312
+ return;
313
+ this.fadedBy = live;
314
+ if (!live) {
315
+ layer.alphas = null;
316
+ return;
317
+ }
318
+ const alphas = new Float32Array(cells.length);
319
+ for (let i = 0; i < cells.length; i++) {
320
+ const o = cells[i];
321
+ alphas[i] = o !== NO_OBSERVATION && o < live.mask.length && live.mask[o] ? 1 : DEFAULT_MUTED_OPACITY;
322
+ }
323
+ layer.alphas = alphas;
169
324
  }
170
325
  async draw(dataset, view, port, frame, allGenes) {
171
326
  const loaded = this.loaded;
@@ -241,9 +396,12 @@ export class Spatial3dTranscripts {
241
396
  if (this.layer)
242
397
  this.viewer.layers.remove(this.layer);
243
398
  this.layer = null;
399
+ this.drawnCells = null;
400
+ this.fadedBy = null;
244
401
  this.styleKey = styleKey;
245
402
  if (!count)
246
403
  return;
404
+ this.drawnCells = Uint32Array.from(cells);
247
405
  this.layer = this.viewer.addPoints3D(Float32Array.from(positions), new Float32Array(count), {
248
406
  name: 'transcripts',
249
407
  size,
@@ -266,4 +424,4 @@ async function pooled(items, limit, work) {
266
424
  await Promise.all(Array.from({ length: Math.min(limit, items.length) }, run));
267
425
  return out;
268
426
  }
269
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFwYXJpLXNwYXRpYWwtM2QtdHJhbnNjcmlwdHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2ltcGxlbWVudGF0aW9ucy9uYXBhcmktanMvbmFwYXJpLXNwYXRpYWwtM2QtdHJhbnNjcmlwdHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLFNBQVMsRUFBd0IsTUFBTSx5Q0FBeUMsQ0FBQztBQUUxRixPQUFPLEVBQ0wsV0FBVyxFQUNYLGNBQWMsRUFDZCxtQkFBbUIsR0FHcEIsTUFBTSwwQ0FBMEMsQ0FBQztBQUNsRCxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsaUJBQWlCLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDMUcsT0FBTyxFQUFFLGNBQWMsRUFBRSxjQUFjLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUNsRixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsZUFBZSxFQUFFLGFBQWEsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ25GLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFakQseUdBQXlHO0FBQ3pHLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLFNBQVMsQ0FBQztBQUM1QyxrR0FBa0c7QUFDbEcsTUFBTSxDQUFDLE1BQU0sd0JBQXdCLEdBQUcsSUFBSSxDQUFDO0FBQzdDLG9DQUFvQztBQUNwQyxNQUFNLFdBQVcsR0FBRyxDQUFDLENBQUM7QUFDdEIseUZBQXlGO0FBQ3pGLE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLENBQUMsQ0FBQztBQUN6Qyx1R0FBdUc7QUFDdkcsTUFBTSxlQUFlLEdBQUcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQVUsQ0FBQztB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dGVudCI6WyJpbXBvcnQgdHlwZSB7IFBvaW50czNETGF5ZXIsIFZpZXdlciB9IGZyb20gJ25hcGFyaS1qcyc7XG5cbmltcG9ydCB7IEFMTF9HRU5FUywgdHlwZSBTcGF0aWFsRGF0YVBvcnQgfSBmcm9tICcuLi8uLi9jb250cmFjdHMvcG9ydHMvc3BhdGlhbC1kYXRhLnBvcnQnO1xuaW1wb3J0IHR5cGUgeyBTcGF0aWFsVmlld1N0YXRlIH0gZnJvbSAnLi4vLi4vY29udHJhY3RzL2Rpc3BsYXktdHlwZXMnO1xuaW1wb3J0IHtcbiAgTk9fQ0FURUdPUlksXG4gIE5PX09CU0VSVkFUSU9OLFxuICBpc0NhdGVnb3JpY2FsQ29sdW1uLFxuICB0eXBlIFNwYXRpYWxEYXRhc2V0LFxuICB0eXBlIFNwYXRpYWxUcmFuc2NyaXB0VGlsZSxcbn0gZnJvbSAnLi4vLi4vY29udHJhY3RzL3NwYXRpYWwtZGF0YXNldC5jb250cmFjdCc7XG5pbXBvcnQgeyBERUZBVUxUX0NBVEVHT1JJQ0FMX1BBTEVUVEUsIGNhdGVnb3J5Q29sb3JzRm9yLCBwYXJzZUhleCB9IGZyb20gJy4uLy4uL3NwYXRpYWwvc3BhdGlhbC1lbmNvZGluZyc7XG5pbXBvcnQgeyBhbGxHZW5lU2hvd25CeSwgYWxsR2VuZXNIaWRkZW4gfSBmcm9tICcuLi8uLi9zcGF0aWFsL3NwYXRpYWwtdGlsZS1tZXJnZSc7XG5pbXBvcnQgeyBjZWxsVHlwZUNvbHVtbkZvciB9IGZyb20gJy4uLy4uL3NwYXRpYWwvc3BhdGlhbC10aWxlcyc7XG5pbXBvcnQgeyBjbHVzdGVyQ29sb3JNYXAsIGNsdXN0ZXJPZkdlbmUgfSBmcm9tICcuLi8uLi9zcGF0aWFsL3RyYW5zY3JpcHQtZ3JvdXBpbmcnO1xuaW1wb3J0IHsgdGlsZXNJblJlY3QgfSBmcm9tICcuLi8uLi9zcGF0aWFsL2xvZCc7XG5pbXBvcnQgeyBTdXBlcnNlZGUgfSBmcm9tICcuLi8uLi91dGlsL3N1cGVyc2VkZSc7XG5cbi8qKiBNb3N0IHRyYW5zY3JpcHRzIGRyYXduIGluIHRoZSAzRCB2aWV3OiBwYXN0IGl0LCBldmVyeSBrLXRoIG9uZSBpcyBkcmF3biAoYW5kIHRoZSBjb25zb2xlIHNheXMgc28pLiAqL1xuZXhwb3J0IGNvbnN0IFRSQU5TQ1JJUFRTXzNEX01BWCA9IDJfMDAwXzAwMDtcbi8qKiBNb3N0IGxldmVsLTAgdGlsZXMgcmVhZCBmb3IgdGhlIDNEIHZpZXc6IGEgZGF0YXNldCBuZWVkaW5nIG1vcmUgaXMgdG9vIGxhcmdlIHRvIGRyYXcgd2hvbGUuICovXG5leHBvcnQgY29uc3QgVFJBTlNDUklQVFNfM0RfTUFYX1RJTEVTID0gNDA5Njtcbi8qKiBUaWxlIHJlYWRzIGluIGZsaWdodCBhdCBvbmNlLiAqL1xuY29uc3QgQ09OQ1VSUkVOQ1kgPSA4O1xuLyoqIEEgdHJhbnNjcmlwdCdzIG1hcmtlciBpbiB0aGUgM0QgdmlldywgaW4gc2NyZWVuIHBpeGVscyBhdCBhIHRyYW5zY3JpcHQgc2NhbGUgb2YgMS4gKi9cbmV4cG9ydCBjb25zdCBUUkFOU0NSSVBUXzNEX0JBU0VfU0laRSA9IDI7XG4vKiogQSB0cmFuc2NyaXB0IHdpdGggbm8gY29sb3VyIGJ5IGNlbGwgdHlwZSAoaW4gbm8gY2VsbCwgb3IgYSBjZWxsIGluIG5vIGdyb3VwKSwgYXMgdGhlIDJEIG1hcmtlcnMuICovXG5jb25zdCBVTkFTU0lHTkVEX1JHQkEgPSBbMC42MiwgMC42MiwgMC42MiwgMC41NV0gYXMgY29uc3Q7XG5cbi8qKiBXaGF0IHRoZSAzRCB0cmFuc2NyaXB0cyBuZWVkIG9mIHRoZSBzY2VuZTogd2hlcmUgdGhlIGNsb3VkIHNpdHMgYW5kIGhvdyBaIGlzIHN0cmV0Y2hlZC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVHJhbnNjcmlwdHMzZEZyYW1lIHtcbiAgLyoqIE9mZnNldCBhcHBsaWVkIHRvIG9ic2VydmF0aW9uIGNvb3JkaW5hdGVzIHRvIHNpdCB0aGVtIGluIHRoZSBzY2VuZSdzIGJveC4gKi9cbiAgb3JpZ2luOiByZWFkb25seSBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gIHpTY2FsZTogbnVtYmVyO1xufVxuXG4vKiogVGhlIGdlbmVzIGEgdmlldyBkcmF3cyBpbiAzRCwgYXMgdGhlIHRpbGUgcXVlcnkgdGFrZXMgdGhlbSwgb3IgbnVsbCB3aGVuIGl0IGRyYXdzIG5vbmUuICovXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNjcmlwdHMzZEdlbmVzKFxuICBkYXRhc2V0OiBTcGF0aWFsRGF0YXNldCxcbiAgdmlldzogU3BhdGlhbFZpZXdTdGF0ZSxcbik6IHsgcXVlcnk6IHN0cmluZ1tdOyBhbGxHZW5lczogYm9vbGVhbiB9IHwgbnVsbCB7XG4gIGlmICh2aWV3LnRyYW5zY3JpcHRNb2RlID09PSAnb2ZmJykgcmV0dXJuIG51bGw7XG4gIGlmICh2aWV3LnRyYW5zY3JpcHRBbGxHZW5lcykge1xuICAgIGlmIChhbGxHZW5lc0hpZGRlbih2aWV3KSkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHsgcXVlcnk6IFtBTExfR0VORVNdLCBhbGxHZW5lczogdHJ1ZSB9O1xuICB9XG4gIGNvbnN0IGhpZGRlbiA9IG5ldyBTZXQodmlldy50cmFuc2NyaXB0SGlkZGVuR2VuZXMpO1xuICBjb25zdCBnZW5lcyA9IHZpZXcudHJhbnNjcmlwdEdlbmVzLmZpbHRlcigoZykgPT4gIWhpZGRlbi5oYXMoZykpO1xuICByZXR1cm4gZ2VuZXMubGVuZ3RoID8geyBxdWVyeTogZ2VuZXMsIGFsbEdlbmVzOiBmYWxzZSB9IDogbnVsbDtcbn1cblxuLyoqXG4gKiBFYWNoIGxvYWRlZCB0cmFuc2NyaXB0J3MgY29sb3VyLCBwYWNrZWQgUkdCQSwgYXMgdGhlIDJEIG1hcmtlcnMgY29sb3VyIHRoZW0gYnkgZ2VuZTogYSBnZW5lJ3NcbiAqIGNob3NlbiBjb2xvdXIsIGVsc2UgdGhlIHBhbGV0dGUncyBieSBpdHMgc2xvdCAodGhlIHNlbGVjdGlvbidzIG9yZGVyLCBvciB3aXRoIFwiQWxsIGdlbmVzXCIgdGhlXG4gKiBkYXRhc2V0J3MgZ2VuZSBjb2RlKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zY3JpcHRzM2RDb2xvcnMoXG4gIHZpZXc6IFNwYXRpYWxWaWV3U3RhdGUsXG4gIG5hbWVzOiByZWFkb25seSBzdHJpbmdbXSB8IG51bGwsXG4gIGdlbmU6IFVpbnQxNkFycmF5LFxuICBjb3VudDogbnVtYmVyLFxuKTogRmxvYXQzMkFycmF5IHtcbiAgY29uc3QgbiA9IG5hbWVzID8gbmFtZXMubGVuZ3RoIDogREVGQVVMVF9DQVRFR09SSUNBTF9QQUxFVFRFLmxlbmd0aDtcbiAgY29uc3QgdGFibGUgPSBBcnJheS5mcm9tKHsgbGVuZ3RoOiBuIH0sIChfZywgaSkgPT5cbiAgICByZ2JhMDEoXG4gICAgICAobmFtZXMgJiYgdmlldy50cmFuc2NyaXB0R2VuZUNvbG9yc1tuYW1lc1tpXV0pIHx8XG4gICAgICAgIERFRkFVTFRfQ0FURUdPUklDQUxfUEFMRVRURVtpICUgREVGQVVMVF9DQVRFR09SSUNBTF9QQUxFVFRFLmxlbmd0aF0sXG4gICAgKSxcbiAgKTtcbiAgcmV0dXJuIHBhY2tlZChjb3VudCwgKGkpID0+IHRhYmxlW25hbWVzID8gZ2VuZVtpXSA6IGdlbmVbaV0gJSBuXSk7XG59XG5cbi8qKlxuICogSG93IHRoZSBwYW5lbCdzIFwiQ29sb3VyIGJ5XCIgYXBwbGllcyBpbiAzRCwgYXMgaXQgZG9lcyB0byB0aGUgMkQgbWFya2VycyAoYGNvbG9yVmlld0ZvcmApOiBieVxuICogY2VsbCB0eXBlIHdoZW4gdGhlIGRhdGFzZXQgaGFzIG9uZSAoZWxzZSBieSBnZW5lKSwgYnkgY2x1c3RlciBmb3IgdGhlIHNlbGVjdGVkIGdlbmVzICh3aXRoIFwiQWxsXG4gKiBnZW5lc1wiIGEgY2x1c3RlciBpcyBpdHMgZ2VuZSksIGJ5IGdlbmUgb3RoZXJ3aXNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNjcmlwdHMzZENvbG9yQnkoXG4gIGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0LFxuICB2aWV3OiBTcGF0aWFsVmlld1N0YXRlLFxuICBhbGxHZW5lczogYm9vbGVhbixcbik6ICdjZWxsVHlwZScgfCAnY2x1c3RlcicgfCAnZ2VuZScge1xuICBjb25zdCBieSA9IHZpZXcudHJhbnNjcmlwdENvbG9yQnk7XG4gIGlmIChieSA9PT0gJ2NlbGxUeXBlJykgcmV0dXJuIGNlbGxUeXBlQ29sdW1uRm9yKGRhdGFzZXQsIHZpZXcpID8gJ2NlbGxUeXBlJyA6ICdnZW5lJztcbiAgaWYgKGJ5ID09PSAnY2x1c3RlcicgJiYgIWFsbEdlbmVzKSByZXR1cm4gJ2NsdXN0ZXInO1xuICByZXR1cm4gJ2dlbmUnO1xufVxuXG4vKiogVGhlIGNvbG91cnMgdGhlIGNlbGxzJyBncm91cGluZyBnaXZlcyBpdHMgZ3JvdXBzLCBieSBuYW1lIChub25lIHdpdGhvdXQgYSBncm91cGluZykuICovXG5hc3luYyBmdW5jdGlvbiBjZWxsR3JvdXBDb2xvcnMoXG4gIGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0LFxuICB2aWV3OiBTcGF0aWFsVmlld1N0YXRlLFxuICBwb3J0OiBTcGF0aWFsRGF0YVBvcnQsXG4pOiBQcm9taXNlPHsgY29kZXM6IFVpbnQxNkFycmF5OyBjb2xvcnM6IChyZWFkb25seSBudW1iZXJbXSlbXTsgYnlOYW1lOiBNYXA8c3RyaW5nLCBzdHJpbmc+IH0gfCBudWxsPiB7XG4gIGNvbnN0IG5hbWUgPSBjZWxsVHlwZUNvbHVtbkZvcihkYXRhc2V0LCB2aWV3KTtcbiAgaWYgKCFuYW1lKSByZXR1cm4gbnVsbDtcbiAgY29uc3QgY29sdW1uID0gYXdhaXQgcG9ydC5nZXRDb2x1bW4obmFtZSk7XG4gIGlmICghaXNDYXRlZ29yaWNhbENvbHVtbihjb2x1bW4pKSByZXR1cm4gbnVsbDtcbiAgY29uc3QgaGV4ID0gY2F0ZWdvcnlDb2xvcnNGb3IobmFtZSwgY29sdW1uLm1ldGEsIHZpZXcuZ3JvdXBDb2xvcnMpO1xuICBjb25zdCBieU5hbWUgPSBuZXcgTWFwKGNvbHVtbi5tZXRhLmNhdGVnb3JpZXMubWFwKChjLCBrKSA9PiBbYywgaGV4W2tdXSBhcyBjb25zdCkpO1xuICByZXR1cm4geyBjb2RlczogY29sdW1uLmNvZGVzLCBjb2xvcnM6IGhleC5tYXAocmdiYTAxKSwgYnlOYW1lIH07XG59XG5cbi8qKiBgI3JyZ2diYmAgYXMgYW4gb3BhcXVlIDAuLjEgUkdCQS4gKi9cbmZ1bmN0aW9uIHJnYmEwMShoZXg6IHN0cmluZyk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgY29uc3QgW3IsIGcsIGJdID0gcGFyc2VIZXgoaGV4KTtcbiAgcmV0dXJuIFtyIC8gMjU1LCBnIC8gMjU1LCBiIC8gMjU1LCAxXTtcbn1cblxuLyoqIGBjb3VudGAgY29sb3VycyBwYWNrZWQgUkdCQSwgdW5hc3NpZ25lZCB3aGVyZSBgYXRgIGhhcyBub25lLiAqL1xuZnVuY3Rpb24gcGFja2VkKGNvdW50OiBudW1iZXIsIGF0OiAoaTogbnVtYmVyKSA9PiByZWFkb25seSBudW1iZXJbXSB8IHVuZGVmaW5lZCk6IEZsb2F0MzJBcnJheSB7XG4gIGNvbnN0IG91dCA9IG5ldyBGbG9hdDMyQXJyYXkoY291bnQgKiA0KTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSBvdXQuc2V0KGF0KGkpID8/IFVOQVNTSUdORURfUkdCQSwgaSAqIDQpO1xuICByZXR1cm4gb3V0O1xufVxuXG4vKipcbiAqIFRoZSB0cmFuc2NyaXB0cyBvZiB0aGUgM0Qgc3BhdGlhbCB2aWV3OiBldmVyeSBtb2xlY3VsZSBvZiB0aGUgZ2VuZXMgdGhlIFRyYW5zY3JpcHRzIHBhbmVsIGRyYXdzXG4gKiAoaXRzIHNlbGVjdGVkIGdlbmVzLCBvciBcIkFsbCBnZW5lc1wiKSwgYXQgaXRzIG93biB4LCB5IGFuZCB6LCBpbiB0aGUgY2xvdWQncyBib3ggYW5kIFogc3RyZXRjaC5cbiAqXG4gKiBUaGUgMkQgdmlldyByZWFkcyB0cmFuc2NyaXB0cyBieSBsZXZlbCBvZiBkZXRhaWwgZm9yIHRoZSBjYW1lcmE7IGEgM0Qgb3JiaXQgaGFzIG5vIHN1Y2ggd2luZG93LFxuICogc28gdGhpcyByZWFkcyB0aGUgd2hvbGUgbGV2ZWwgMCBvbmNlIHBlciBnZW5lIHNlbGVjdGlvbiAoYSBmZXcgaHVuZHJlZCB0aG91c2FuZCBtb2xlY3VsZXMgZm9yIGFcbiAqIE1FUkZJU0ggc2VjdGlvbikgYW5kIG9ubHkgcmVzdHlsZXMgYWZ0ZXIgdGhhdC4gRHJhd24gb25seSBmb3IgYSBkYXRhc2V0IHdob3NlIHRyYW5zY3JpcHRzIGNhcnJ5IHouXG4gKi9cbmV4cG9ydCBjbGFzcyBTcGF0aWFsM2RUcmFuc2NyaXB0cyB7XG4gIHByaXZhdGUgbGF5ZXI6IFBvaW50czNETGF5ZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqIFdoYXQge0BsaW5rIGxheWVyfSB3YXMgbG9hZGVkIGZyb20gKGRhdGFzZXQsIGdlbmVzLCBxdWFsaXR5KSwgYW5kIHN0eWxlZCB3aXRoLiAqL1xuICBwcml2YXRlIGxvYWRLZXk6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHN0eWxlS2V5OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBsb2FkZWQ6IHsgdGlsZXM6IFNwYXRpYWxUcmFuc2NyaXB0VGlsZVtdOyBuYW1lczogcmVhZG9ubHkgc3RyaW5nW10gfCBudWxsIH0gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSByZWFkb25seSBsb2FkcyA9IG5ldyBTdXBlcnNlZGUoKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IHZpZXdlcjogVmlld2VyLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYmVnaW46IChsYWJlbDogJ1RyYW5zY3JpcHRzJykgPT4gKCkgPT4gdm9pZCxcbiAgKSB7fVxuXG4gIC8qKiBUaGUgbGF5ZXIgZHJhd24sIGlmIGFueSAoZm9yIHRlc3RzIGFuZCB0aGUgc2NlbmUncyBaIHN0cmV0Y2gpLiAqL1xuICBnZXQgZHJhd24oKTogUG9pbnRzM0RMYXllciB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLmxheWVyO1xuICB9XG5cbiAgLyoqIERyYXcgd2hhdCBgdmlld2AgYXNrcyBmb3IsIGxvYWRpbmcgdGhlIG1vbGVjdWxlcyB3aGVuIHRoZSBnZW5lcyBjaGFuZ2VkLiAqL1xuICBhc3luYyBzeW5jKFxuICAgIGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0LFxuICAgIHZpZXc6IFNwYXRpYWxWaWV3U3RhdGUsXG4gICAgcG9ydDogU3BhdGlhbERhdGFQb3J0IHwgbnVsbCxcbiAgICBmcmFtZTogVHJhbnNjcmlwdHMzZEZyYW1lLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBtZXRhID0gZGF0YXNldC50cmFuc2NyaXB0VGlsZXM7XG4gICAgY29uc3QgZ2VuZXMgPSBtZXRhPy5oYXNaICYmIHBvcnQ/LmdldFRyYW5zY3JpcHRUaWxlID8gdHJhbnNjcmlwdHMzZEdlbmVzKGRhdGFzZXQsIHZpZXcpIDogbnVsbDtcbiAgICBpZiAoIW1ldGEgfHwgIWdlbmVzIHx8ICFwb3J0KSB7XG4gICAgICB0aGlzLnJlbW92ZSgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoZ2VuZXMuYWxsR2VuZXMgJiYgKG1ldGEuY291bnQgPz8gMCkgPiBUUkFOU0NSSVBUU18zRF9NQVgpIHtcbiAgICAgIGNvbnNvbGUud2FybihgW25hcGFyaS1qc10gJHttZXRhLmNvdW50fSB0cmFuc2NyaXB0cyBhcmUgdG9vIG1hbnkgdG8gZHJhdyBpbiAzRDogc2VsZWN0IGdlbmVzIHRvIHNlZSB0aGVpcnNgKTtcbiAgICAgIHRoaXMucmVtb3ZlKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHF1YWxpdHkgPSB2aWV3LnRyYW5zY3JpcHRRdWFsaXR5ID09PSAnYWxsJyA/ICdhbGwnIDogJ2hpZ2gnO1xuICAgIGNvbnN0IGxvYWRLZXkgPSBgJHtkYXRhc2V0LmlkfXwke2dlbmVzLnF1ZXJ5LmpvaW4oJ1xcdTAwMDEnKX18JHtxdWFsaXR5fWA7XG4gICAgaWYgKGxvYWRLZXkgIT09IHRoaXMubG9hZEtleSkge1xuICAgICAgY29uc3QgdGFzayA9IHRoaXMubG9hZHMubmV4dCgpO1xuICAgICAgY29uc3QgW3gwLCB5MCwgeDEsIHkxXSA9IG1ldGEuYm91bmRzO1xuICAgICAgY29uc3Qga2V5cyA9IHRpbGVzSW5SZWN0KHsgeDAsIHkwLCB4MTogeDEgKyAxZS02LCB5MTogeTEgKyAxZS02IH0sIDAsIG1ldGEubGV2ZWxzLCBtZXRhLmJvdW5kcyk7XG4gICAgICBpZiAoa2V5cy5sZW5ndGggPiBUUkFOU0NSSVBUU18zRF9NQVhfVElMRVMpIHtcbiAgICAgICAgY29uc29sZS53YXJuKGBbbmFwYXJpLWpzXSAke2tleXMubGVuZ3RofSB0cmFuc2NyaXB0IHRpbGVzIGFyZSB0b28gbWFueSB0byByZWFkIGZvciB0aGUgM0Qgdmlld2ApO1xuICAgICAgICB0aGlzLnJlbW92ZSgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBlbmQgPSB0aGlzLmJlZ2luKCdUcmFuc2NyaXB0cycpO1xuICAgICAgbGV0IHRpbGVzOiBTcGF0aWFsVHJhbnNjcmlwdFRpbGVbXTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRpbGVzID0gYXdhaXQgcG9vbGVkKGtleXMsIENPTkNVUlJFTkNZLCAoaykgPT5cbiAgICAgICAgICBwb3J0LmdldFRyYW5zY3JpcHRUaWxlISgwLCBrLmd4LCBrLmd5LCB7IGdlbmVzOiBnZW5lcy5xdWVyeSwgcXVhbGl0eSB9KSxcbiAgICAgICAgKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zb2xlLndhcm4oJ1tuYXBhcmktanNdIHRyYW5zY3JpcHRzIGZvciB0aGUgM0QgdmlldyBjb3VsZCBub3QgYmUgcmVhZCcsIGVycik7XG4gICAgICAgIC8vIFRoZSBwYW5lbCBhc2tlZCBmb3Igb3RoZXIgdHJhbnNjcmlwdHMgdGhhbiB0aG9zZSBkcmF3bjogdGFrZSB0aGVtIGRvd24gcmF0aGVyIHRoYW4gbGVhdmVcbiAgICAgICAgLy8gdGhlIG9sZCBzZWxlY3Rpb24gdXAgYXMgaWYgaXQgd2VyZSB0aGUgbmV3IG9uZTsgdGhlIG5leHQgY2hhbmdlIHJlYWRzIGFnYWluLiBPbmx5IHRoZVxuICAgICAgICAvLyBjdXJyZW50IGxvYWQgbWF5OiBhIHN1cGVyc2VkZWQgb25lIG11c3Qgbm90IHRlYXIgZG93biB3aGF0IGEgbmV3ZXIgb25lIGRyZXcuXG4gICAgICAgIGlmICh0YXNrKCkpIHRoaXMuY2xlYXJMYXllcigpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBlbmQoKTtcbiAgICAgIH1cbiAgICAgIGlmICghdGFzaygpKSByZXR1cm47XG4gICAgICB0aGlzLmxvYWRLZXkgPSBsb2FkS2V5O1xuICAgICAgdGhpcy5zdHlsZUtleSA9IG51bGw7XG4gICAgICB0aGlzLmxvYWRlZCA9IHsgdGlsZXMsIG5hbWVzOiBnZW5lcy5hbGxHZW5lcyA/IChtZXRhLmdlbmVzID8/IG51bGwpIDogZ2VuZXMucXVlcnkgfTtcbiAgICB9XG4gICAgYXdhaXQgdGhpcy5kcmF3KGRhdGFzZXQsIHZpZXcsIHBvcnQsIGZyYW1lLCBnZW5lcy5hbGxHZW5lcyk7XG4gIH1cblxuICAvKiogRm9sbG93IHRoZSBzY2VuZSdzIFogc3RyZXRjaCAobm90aGluZyBpcyByZS11cGxvYWRlZCkuICovXG4gIHNldFpTY2FsZShzOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5sYXllcikgdGhpcy5sYXllci5zY2FsZTNkID0gWzEsIDEsIHNdO1xuICB9XG5cbiAgLyoqIFRha2UgdGhlIGxheWVyIGRvd24gYW5kIGZvcmdldCB3aGF0IGl0IHNob3dlZC4gKi9cbiAgcmVtb3ZlKCk6IHZvaWQge1xuICAgIHRoaXMubG9hZHMuY2FuY2VsKCk7XG4gICAgdGhpcy5jbGVhckxheWVyKCk7XG4gIH1cblxuICBwcml2YXRlIGNsZWFyTGF5ZXIoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubGF5ZXIpIHRoaXMudmlld2VyLmxheWVycy5yZW1vdmUodGhpcy5sYXllcik7XG4gICAgdGhpcy5sYXllciA9IG51bGw7XG4gICAgdGhpcy5sb2FkS2V5ID0gbnVsbDtcbiAgICB0aGlzLnN0eWxlS2V5ID0gbnVsbDtcbiAgICB0aGlzLmxvYWRlZCA9IG51bGw7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGRyYXcoXG4gICAgZGF0YXNldDogU3BhdGlhbERhdGFzZXQsXG4gICAgdmlldzogU3BhdGlhbFZpZXdTdGF0ZSxcbiAgICBwb3J0OiBTcGF0aWFsRGF0YVBvcnQsXG4gICAgZnJhbWU6IFRyYW5zY3JpcHRzM2RGcmFtZSxcbiAgICBhbGxHZW5lczogYm9vbGVhbixcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbG9hZGVkID0gdGhpcy5sb2FkZWQ7XG4gICAgaWYgKCFsb2FkZWQpIHJldHVybjtcbiAgICBjb25zdCBieSA9IHRyYW5zY3JpcHRzM2RDb2xvckJ5KGRhdGFzZXQsIHZpZXcsIGFsbEdlbmVzKTtcbiAgICBjb25zdCBzdHlsZUtleSA9IFtcbiAgICAgIGZyYW1lLm9yaWdpbi5qb2luKCcsJyksXG4gICAgICBieSxcbiAgICAgIGJ5ID09PSAnZ2VuZScgPyBKU09OLnN0cmluZ2lmeSh2aWV3LnRyYW5zY3JpcHRHZW5lQ29sb3JzKSA6ICcnLFxuICAgICAgYnkgIT09ICdnZW5lJyA/IGAke2NlbGxUeXBlQ29sdW1uRm9yKGRhdGFzZXQsIHZpZXcpfXwke0pTT04uc3RyaW5naWZ5KHZpZXcuZ3JvdXBDb2xvcnMpfWAgOiAnJyxcbiAgICAgIGJ5ID09PSAnY2x1c3RlcicgPyBKU09OLnN0cmluZ2lmeSh2aWV3LnRyYW5zY3JpcHRHZW5lR3JvdXBzKSA6ICcnLFxuICAgICAgYWxsR2VuZXMgPyB2aWV3LnRyYW5zY3JpcHRBbGxHZW5lc0hpZGRlbi5qb2luKCcsJykgOiAnJyxcbiAgICBdLmpvaW4oJ3wnKTtcbiAgICBjb25zdCBzaXplID0gVFJBTlNDUklQVF8zRF9CQVNFX1NJWkUgKiAodmlldy50cmFuc2NyaXB0U2NhbGUgPiAwID8gdmlldy50cmFuc2NyaXB0U2NhbGUgOiAxKTtcbiAgICBpZiAodGhpcy5sYXllciAmJiBzdHlsZUtleSA9PT0gdGhpcy5zdHlsZUtleSkge1xuICAgICAgdGhpcy5sYXllci5zaXplID0gc2l6ZTtcbiAgICAgIHRoaXMubGF5ZXIub3BhY2l0eSA9IHZpZXcudHJhbnNjcmlwdE9wYWNpdHk7XG4gICAgICB0aGlzLmxheWVyLnNjYWxlM2QgPSBbMSwgMSwgZnJhbWUuelNjYWxlXTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgeyBuYW1lcyB9ID0gbG9hZGVkO1xuICAgIGNvbnN0IHNob3duID0gYWxsR2VuZXMgJiYgbmFtZXMgPyBhbGxHZW5lU2hvd25CeSh2aWV3LnRyYW5zY3JpcHRBbGxHZW5lc0hpZGRlbikgOiBudWxsO1xuICAgIGNvbnN0IGtlZXAgPSBzaG93biAmJiBuYW1lcyA/IChnOiBudW1iZXIpID0+ICEhbmFtZXNbZ10gJiYgc2hvd24obmFtZXNbZ10pIDogKCkgPT4gdHJ1ZTtcbiAgICBjb25zdCB0b3RhbCA9IGxvYWRlZC50aWxlcy5yZWR1Y2UoKG4sIHQpID0+IG4gKyB0LmNvdW50LCAwKTtcbiAgICBjb25zdCBzdHJpZGUgPSBNYXRoLm1heCgxLCBNYXRoLmNlaWwodG90YWwgLyBUUkFOU0NSSVBUU18zRF9NQVgpKTtcbiAgICBpZiAoc3RyaWRlID4gMSkgY29uc29sZS53YXJuKGBbbmFwYXJpLWpzXSBkcmF3aW5nIGV2ZXJ5ICR7c3RyaWRlfXRoIG9mICR7dG90YWx9IHRyYW5zY3JpcHRzIGluIDNEYCk7XG5cbiAgICBjb25zdCBbb3gsIG95LCBvel0gPSBmcmFtZS5vcmlnaW47XG4gICAgY29uc3QgcG9zaXRpb25zOiBudW1iZXJbXSA9IFtdO1xuICAgIGNvbnN0IGdlbmVzOiBudW1iZXJbXSA9IFtdO1xuICAgIGNvbnN0IGNlbGxzOiBudW1iZXJbXSA9IFtdO1xuICAgIGxldCBzZWVuID0gMDtcbiAgICBmb3IgKGNvbnN0IHQgb2YgbG9hZGVkLnRpbGVzKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHQuY291bnQ7IGkrKykge1xuICAgICAgICBpZiAoIWtlZXAodC5nZW5lW2ldKSB8fCBzZWVuKysgJSBzdHJpZGUpIGNvbnRpbnVlO1xuICAgICAgICBwb3NpdGlvbnMucHVzaCh0LnhbaV0gKyBveCwgdC55W2ldICsgb3ksIHQueltpXSArIG96KTtcbiAgICAgICAgZ2VuZXMucHVzaCh0LmdlbmVbaV0pO1xuICAgICAgICBjZWxscy5wdXNoKHQub2JzZXJ2YXRpb25baV0pO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBjb3VudCA9IGdlbmVzLmxlbmd0aDtcbiAgICBsZXQgY29sb3JzOiBGbG9hdDMyQXJyYXk7XG4gICAgaWYgKGJ5ID09PSAnZ2VuZScpIHtcbiAgICAgIGNvbG9ycyA9IHRyYW5zY3JpcHRzM2RDb2xvcnModmlldywgbmFtZXMsIFVpbnQxNkFycmF5LmZyb20oZ2VuZXMpLCBjb3VudCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGdyb3VwcyA9IGF3YWl0IGNlbGxHcm91cENvbG9ycyhkYXRhc2V0LCB2aWV3LCBwb3J0KS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgIGNvbnNvbGUud2FybignW25hcGFyaS1qc10gdGhlIGNlbGxzIGdyb3VwaW5nIGZvciB0aGUgM0QgdHJhbnNjcmlwdHMgY291bGQgbm90IGJlIHJlYWQnLCBlcnIpO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0pO1xuICAgICAgLy8gQSBuZXdlciBkcmF3IChhbm90aGVyIHN0eWxlLCBvciB0aGUgbGF5ZXIgdGFrZW4gZG93bikgd29uIHdoaWxlIHRoZSBjb2x1bW4gbG9hZGVkLlxuICAgICAgaWYgKHRoaXMubG9hZGVkICE9PSBsb2FkZWQpIHJldHVybjtcbiAgICAgIGlmIChieSA9PT0gJ2NlbGxUeXBlJykge1xuICAgICAgICBjb2xvcnMgPSBwYWNrZWQoY291bnQsIChpKSA9PiB7XG4gICAgICAgICAgY29uc3QgbyA9IGNlbGxzW2ldO1xuICAgICAgICAgIGNvbnN0IGNvZGUgPSAhZ3JvdXBzIHx8IG8gPT09IE5PX09CU0VSVkFUSU9OID8gTk9fQ0FURUdPUlkgOiBncm91cHMuY29kZXNbb107XG4gICAgICAgICAgcmV0dXJuIGNvZGUgPT09IE5PX0NBVEVHT1JZID8gdW5kZWZpbmVkIDogZ3JvdXBzIS5jb2xvcnNbY29kZV07XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQSBjbHVzdGVyIG5hbWVkIGxpa2UgYSBncm91cCBvZiB0aGUgY2VsbHMnIGdyb3VwaW5nIHRha2VzIHRoYXQgZ3JvdXAncyBjb2xvdXIsIGFzIGluIDJELlxuICAgICAgICBjb25zdCBieUNsdXN0ZXIgPSBjbHVzdGVyQ29sb3JNYXAoXG4gICAgICAgICAgdmlldy50cmFuc2NyaXB0R2VuZXMsXG4gICAgICAgICAgdmlldy50cmFuc2NyaXB0R2VuZUdyb3VwcyxcbiAgICAgICAgICBncm91cHM/LmJ5TmFtZSA/PyBuZXcgTWFwKCksXG4gICAgICAgICAgREVGQVVMVF9DQVRFR09SSUNBTF9QQUxFVFRFLFxuICAgICAgICApO1xuICAgICAgICBjb25zdCB0YWJsZSA9IChuYW1lcyA/PyBbXSkubWFwKChnZW5lKSA9PiB7XG4gICAgICAgICAgY29uc3QgaGV4ID0gYnlDbHVzdGVyLmdldChjbHVzdGVyT2ZHZW5lKGdlbmUsIHZpZXcudHJhbnNjcmlwdEdlbmVHcm91cHMpKTtcbiAgICAgICAgICByZXR1cm4gaGV4ID8gcmdiYTAxKGhleCkgOiB1bmRlZmluZWQ7XG4gICAgICAgIH0pO1xuICAgICAgICBjb2xvcnMgPSBwYWNrZWQoY291bnQsIChpKSA9PiB0YWJsZVtnZW5lc1tpXV0pO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodGhpcy5sYXllcikgdGhpcy52aWV3ZXIubGF5ZXJzLnJlbW92ZSh0aGlzLmxheWVyKTtcbiAgICB0aGlzLmxheWVyID0gbnVsbDtcbiAgICB0aGlzLnN0eWxlS2V5ID0gc3R5bGVLZXk7XG4gICAgaWYgKCFjb3VudCkgcmV0dXJuO1xuICAgIHRoaXMubGF5ZXIgPSB0aGlzLnZpZXdlci5hZGRQb2ludHMzRChGbG9hdDMyQXJyYXkuZnJvbShwb3NpdGlvbnMpLCBuZXcgRmxvYXQzMkFycmF5KGNvdW50KSwge1xuICAgICAgbmFtZTogJ3RyYW5zY3JpcHRzJyxcbiAgICAgIHNpemUsXG4gICAgICBvcGFjaXR5OiB2aWV3LnRyYW5zY3JpcHRPcGFjaXR5LFxuICAgICAgc2NhbGUzZDogWzEsIDEsIGZyYW1lLnpTY2FsZV0sXG4gICAgICBjb2xvcnMsXG4gICAgfSk7XG4gIH1cbn1cblxuLyoqIGB3b3JrYCBvdmVyIGBpdGVtc2AsIGF0IG1vc3QgYGxpbWl0YCBhdCBvbmNlLCByZXN1bHRzIGluIG9yZGVyLiAqL1xuYXN5bmMgZnVuY3Rpb24gcG9vbGVkPFQsIFI+KGl0ZW1zOiByZWFkb25seSBUW10sIGxpbWl0OiBudW1iZXIsIHdvcms6IChpdGVtOiBUKSA9PiBQcm9taXNlPFI+KTogUHJvbWlzZTxSW10+IHtcbiAgY29uc3Qgb3V0ID0gbmV3IEFycmF5PFI+KGl0ZW1zLmxlbmd0aCk7XG4gIGxldCBuZXh0ID0gMDtcbiAgY29uc3QgcnVuID0gYXN5bmMgKCkgPT4ge1xuICAgIHdoaWxlIChuZXh0IDwgaXRlbXMubGVuZ3RoKSB7XG4gICAgICBjb25zdCBpID0gbmV4dCsrO1xuICAgICAgb3V0W2ldID0gYXdhaXQgd29yayhpdGVtc1tpXSk7XG4gICAgfVxuICB9O1xuICBhd2FpdCBQcm9taXNlLmFsbChBcnJheS5mcm9tKHsgbGVuZ3RoOiBNYXRoLm1pbihsaW1pdCwgaXRlbXMubGVuZ3RoKSB9LCBydW4pKTtcbiAgcmV0dXJuIG91dDtcbn1cbiJdfQ==
427
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFwYXJpLXNwYXRpYWwtM2QtdHJhbnNjcmlwdHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2ltcGxlbWVudGF0aW9ucy9uYXBhcmktanMvbmFwYXJpLXNwYXRpYWwtM2QtdHJhbnNjcmlwdHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLFNBQVMsRUFBd0IsTUFBTSx5Q0FBeUMsQ0FBQztBQUUxRixPQUFPLEVBQ0wsV0FBVyxFQUNYLGNBQWMsRUFDZCxtQkFBbUIsR0FHcEIsTUFBTSwwQ0FBMEMsQ0FBQztBQUNsRCxPQUFPLEVBQ0wsMkJBQTJCLEVBQzNCLHFCQUFxQixFQUNyQixpQkFBaUIsRUFDakIsUUFBUSxHQUNULE1BQU0sZ0NBQWdDLENBQUM7QUFFeEMsT0FBTyxFQUFFLGNBQWMsRUFBRSxjQUFjLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUNsRixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsZUFBZSxFQUFFLGFBQWEsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ25GLE9BQU8sRUFBWSxXQUFXLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM5RSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFakQseUdBQXlHO0FBQ3pHLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLFNBQVMsQ0FBQztBQUM1QyxrR0FBa0c7QUFDbEcsTUFBTSxDQUFDLE1BQU0sd0JBQXdCLEdBQUcsSUFBSSxDQUFDO0FBQzdDLG9DQUFvQztBQUNwQyxNQUFNLFdBQVcsR0FBRyxDQUFDLENBQUM7QUFDdEIsd0VBQXdFO0FBQ3hFLE1BQU0sY0FBYyxHQUFHLEdBQUcsQ0FBQztBQUMzQixrQ0FBa0M7QUFDbEMsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDO0FBQzdCLGdFQUFnRTtBQUNoRSxNQUFNLGNBQWMsR0FBRyxHQUFHLENBQUM7QUFDM0IsaUdBQWlHO0FBQ2pHLE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQztBQUNwQix5RkFBeUY7QUFDekYsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQUcsQ0FBQyxDQUFDO0FBQ3pDLHVHQUF1RztBQUN2RyxNQUFNLGVBQWUsR0FBRyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBVSxDQUFDO0FBUzFELDhGQUE4RjtBQUM5RixNQUFNLFVBQVUsa0JBQWtCLENBQ2hDLE9BQXVCLEVBQ3ZCLElBQXNCO0lBRXRCLElBQUksSUFBSSxDQUFDLGNBQWMsS0FBSyxLQUFLO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDL0MsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUM1QixJQUFJLGNBQWMsQ0FBQyxJQUFJLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUN0QyxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsU0FBUyxDQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDO0lBQ2hELENBQUM7SUFDRCxNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQztJQUNuRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDakUsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7QUFDakUsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsbUJBQW1CLENBQ2pDLElBQXNCLEVBQ3RCLEtBQStCLEVBQy9CLElBQWlCLEVBQ2pCLEtBQWE7SUFFYixNQUFNLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLDJCQUEyQixDQUFDLE1BQU0sQ0FBQztJQUNwRSxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQ2hELE1BQU0sQ0FDSixDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDNUMsMkJBQTJCLENBQUMsQ0FBQyxHQUFHLDJCQUEyQixDQUFDLE1BQU0sQ0FBQyxDQUN0RSxDQUNGLENBQUM7SUFDRixPQUFPLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDcEUsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsb0JBQW9CLENBQ2xDLE9BQXVCLEVBQ3ZCLElBQXNCLEVBQ3RCLFFBQWlCO0lBRWpCLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQztJQUNsQyxJQUFJLEVBQUUsS0FBSyxVQUFVO1FBQUUsT0FBTyxpQkFBaUIsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO0lBQ3JGLElBQUksRUFBRSxLQUFLLFNBQVMsSUFBSSxDQUFDLFFBQVE7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUNwRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBRUQsMkZBQTJGO0FBQzNGLEtBQUssVUFBVSxlQUFlLENBQzVCLE9BQXVCLEVBQ3ZCLElBQXNCLEVBQ3RCLElBQXFCO0lBRXJCLE1BQU0sSUFBSSxHQUFHLGlCQUFpQixDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztJQUM5QyxJQUFJLENBQUMsSUFBSTtRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQ3ZCLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMxQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDOUMsTUFBTSxHQUFHLEdBQUcsaUJBQWlCLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ25FLE1BQU0sTUFBTSxHQUFHLElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBVSxDQUFDLENBQUMsQ0FBQztJQUNuRixPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUM7QUFDbEUsQ0FBQztBQUVELHdDQUF3QztBQUN4QyxTQUFTLE1BQU0sQ0FBQyxHQUFXO0lBQ3pCLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNoQyxPQUFPLENBQUMsQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDeEMsQ0FBQztBQUVELG1FQUFtRTtBQUNuRSxTQUFTLE1BQU0sQ0FBQyxLQUFhLEVBQUUsRUFBZ0Q7SUFDN0UsTUFBTSxHQUFHLEdBQUcsSUFBSSxZQUFZLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ3hDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLEVBQUUsQ0FBQyxFQUFFO1FBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksZUFBZSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUN6RSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFFRDs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxPQUFPLG9CQUFvQjtJQXdCL0IsWUFDbUIsTUFBYyxFQUNkLEtBQXNDO1FBRHRDLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDZCxVQUFLLEdBQUwsS0FBSyxDQUFpQztRQXpCakQsVUFBSyxHQUF5QixJQUFJLENBQUM7UUFDM0MscUZBQXFGO1FBQzdFLFlBQU8sR0FBa0IsSUFBSSxDQUFDO1FBQzlCLGFBQVEsR0FBa0IsSUFBSSxDQUFDO1FBQy9CLFdBQU0sR0FBK0UsSUFBSSxDQUFDO1FBQ2pGLFVBQUssR0FBRyxJQUFJLFNBQVMsRUFBRSxDQUFDO1FBQ3pDLG1HQUFtRztRQUMzRixlQUFVLEdBQXVCLElBQUksQ0FBQztRQUM5Qyx3RkFBd0Y7UUFDaEYsWUFBTyxHQUFnQyxJQUFJLENBQUM7UUFDcEQsbUZBQW1GO1FBQzNFLFNBQUksR0FNRCxJQUFJLENBQUM7UUFDUixnQkFBVyxHQUF5QyxJQUFJLENBQUM7UUFDekQsY0FBUyxHQUF3QixJQUFJLENBQUM7UUFDOUMseUZBQXlGO1FBQ3hFLGNBQVMsR0FBRyxJQUFJLEdBQUcsRUFBMEMsQ0FBQztRQU03RSxJQUFJLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQyxRQUFRLEVBQUUsT0FBTyxFQUFFLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsSUFBSSxJQUFJLENBQUM7SUFDdkYsQ0FBQztJQUVELGtGQUFrRjtJQUMxRSxXQUFXO1FBQ2pCLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU87UUFDdkIsSUFBSSxJQUFJLENBQUMsV0FBVztZQUFFLFlBQVksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDckQsSUFBSSxDQUFDLFdBQVcsR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ2pDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO1lBQ3hCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDdkIsSUFBSSxJQUFJO2dCQUFFLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMzRixDQUFDLEVBQUUsY0FBYyxDQUFDLENBQUM7SUFDckIsQ0FBQztJQUVELHVEQUF1RDtJQUN2RCxPQUFPO1FBQ0wsSUFBSSxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUM7UUFDbkIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7UUFDdEIsSUFBSSxJQUFJLENBQUMsV0FBVztZQUFFLFlBQVksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDckQsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7UUFDeEIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ2hCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssSUFBSSxDQUFDLElBQW9ELEVBQUUsS0FBeUI7UUFDMUYsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDeEQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUM7UUFDcEMsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM1RCxJQUFJLEtBQUssR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLEdBQUcsR0FBRyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ3hGLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQ3JDLElBQUksSUFBSSxHQUFhLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLElBQUksRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLElBQUksRUFBRSxDQUFDO1FBQzlELE1BQU0sSUFBSSxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDckUsSUFBSSxJQUFJO1lBQUUsSUFBSSxHQUFHLElBQUksQ0FBQztRQUN0QixnR0FBZ0c7UUFDaEcsSUFBSSxJQUFJLEdBQUcsV0FBVyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDOUQsT0FBTyxJQUFJLENBQUMsTUFBTSxHQUFHLGNBQWMsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDdEUsS0FBSyxFQUFFLENBQUM7WUFDUixJQUFJLEdBQUcsV0FBVyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFB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LENBQUM7SUFDOUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBQb2ludHMzRExheWVyLCBWaWV3ZXIgfSBmcm9tICduYXBhcmktanMnO1xuXG5pbXBvcnQgeyBBTExfR0VORVMsIHR5cGUgU3BhdGlhbERhdGFQb3J0IH0gZnJvbSAnLi4vLi4vY29udHJhY3RzL3BvcnRzL3NwYXRpYWwtZGF0YS5wb3J0JztcbmltcG9ydCB0eXBlIHsgU3BhdGlhbFZpZXdTdGF0ZSB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy9kaXNwbGF5LXR5cGVzJztcbmltcG9ydCB7XG4gIE5PX0NBVEVHT1JZLFxuICBOT19PQlNFUlZBVElPTixcbiAgaXNDYXRlZ29yaWNhbENvbHVtbixcbiAgdHlwZSBTcGF0aWFsRGF0YXNldCxcbiAgdHlwZSBTcGF0aWFsVHJhbnNjcmlwdFRpbGUsXG59IGZyb20gJy4uLy4uL2NvbnRyYWN0cy9zcGF0aWFsLWRhdGFzZXQuY29udHJhY3QnO1xuaW1wb3J0IHtcbiAgREVGQVVMVF9DQVRFR09SSUNBTF9QQUxFVFRFLFxuICBERUZBVUxUX01VVEVEX09QQUNJVFksXG4gIGNhdGVnb3J5Q29sb3JzRm9yLFxuICBwYXJzZUhleCxcbn0gZnJvbSAnLi4vLi4vc3BhdGlhbC9zcGF0aWFsLWVuY29kaW5nJztcbmltcG9ydCB0eXBlIHsgU3BhdGlhbFNlbGVjdGlvbk1hc2sgfSBmcm9tICcuLi8uLi9zcGF0aWFsL3NwYXRpYWwtc2VsZWN0aW9uJztcbmltcG9ydCB7IGFsbEdlbmVTaG93bkJ5LCBhbGxHZW5lc0hpZGRlbiB9IGZyb20gJy4uLy4uL3NwYXRpYWwvc3BhdGlhbC10aWxlLW1lcmdlJztcbmltcG9ydCB7IGNlbGxUeXBlQ29sdW1uRm9yIH0gZnJvbSAnLi4vLi4vc3BhdGlhbC9zcGF0aWFsLXRpbGVzJztcbmltcG9ydCB7IGNsdXN0ZXJDb2xvck1hcCwgY2x1c3Rlck9mR2VuZSB9IGZyb20gJy4uLy4uL3NwYXRpYWwvdHJhbnNjcmlwdC1ncm91cGluZyc7XG5pbXBvcnQgeyBEYXRhUmVjdCwgdGlsZXNJblJlY3QsIHRyYW5zY3JpcHRMZXZlbEZvciB9IGZyb20gJy4uLy4uL3NwYXRpYWwvbG9kJztcbmltcG9ydCB7IFN1cGVyc2VkZSB9IGZyb20gJy4uLy4uL3V0aWwvc3VwZXJzZWRlJztcblxuLyoqIE1vc3QgdHJhbnNjcmlwdHMgZHJhd24gaW4gdGhlIDNEIHZpZXc6IHBhc3QgaXQsIGV2ZXJ5IGstdGggb25lIGlzIGRyYXduIChhbmQgdGhlIGNvbnNvbGUgc2F5cyBzbykuICovXG5leHBvcnQgY29uc3QgVFJBTlNDUklQVFNfM0RfTUFYID0gMl8wMDBfMDAwO1xuLyoqIE1vc3QgbGV2ZWwtMCB0aWxlcyByZWFkIGZvciB0aGUgM0QgdmlldzogYSBkYXRhc2V0IG5lZWRpbmcgbW9yZSBpcyB0b28gbGFyZ2UgdG8gZHJhdyB3aG9sZS4gKi9cbmV4cG9ydCBjb25zdCBUUkFOU0NSSVBUU18zRF9NQVhfVElMRVMgPSA0MDk2O1xuLyoqIFRpbGUgcmVhZHMgaW4gZmxpZ2h0IGF0IG9uY2UuICovXG5jb25zdCBDT05DVVJSRU5DWSA9IDg7XG4vKiogVGhlIGNhbWVyYSByZXN0aW5nIHRoaXMgbG9uZyBwbGFucyB0aGUgdHJhbnNjcmlwdHMnIGRldGFpbCBhZ2Fpbi4gKi9cbmNvbnN0IENBTUVSQV9SRVNUX01TID0gMzAwO1xuLyoqIFRyYW5zY3JpcHQgdGlsZXMga2VwdCByZWFkLiAqL1xuY29uc3QgVElMRV9DQUNIRV9TSVpFID0gMTAyNDtcbi8qKiBNb3N0IHRpbGVzIHJlYWQgZm9yIG9uZSB2aWV3OiBwYXN0IHRoZW0sIGEgY29hcnNlciBsZXZlbC4gKi9cbmNvbnN0IFZJRVdfVElMRVNfTUFYID0gMjU2O1xuLyoqIEhvdyBmYXIgYWxvbmcgYSByYXkgdGhhdCBuZXZlciBtZWV0cyB0aGUgc2VjdGlvbidzIHBsYW5lIGl0cyByZWFjaCBpcyB0YWtlbiAod29ybGQgdW5pdHMpLiAqL1xuY29uc3QgSE9SSVpPTiA9IDFlNjtcbi8qKiBBIHRyYW5zY3JpcHQncyBtYXJrZXIgaW4gdGhlIDNEIHZpZXcsIGluIHNjcmVlbiBwaXhlbHMgYXQgYSB0cmFuc2NyaXB0IHNjYWxlIG9mIDEuICovXG5leHBvcnQgY29uc3QgVFJBTlNDUklQVF8zRF9CQVNFX1NJWkUgPSAyO1xuLyoqIEEgdHJhbnNjcmlwdCB3aXRoIG5vIGNvbG91ciBieSBjZWxsIHR5cGUgKGluIG5vIGNlbGwsIG9yIGEgY2VsbCBpbiBubyBncm91cCksIGFzIHRoZSAyRCBtYXJrZXJzLiAqL1xuY29uc3QgVU5BU1NJR05FRF9SR0JBID0gWzAuNjIsIDAuNjIsIDAuNjIsIDAuNTVdIGFzIGNvbnN0O1xuXG4vKiogV2hhdCB0aGUgM0QgdHJhbnNjcmlwdHMgbmVlZCBvZiB0aGUgc2NlbmU6IHdoZXJlIHRoZSBjbG91ZCBzaXRzIGFuZCBob3cgWiBpcyBzdHJldGNoZWQuICovXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zY3JpcHRzM2RGcmFtZSB7XG4gIC8qKiBPZmZzZXQgYXBwbGllZCB0byBvYnNlcnZhdGlvbiBjb29yZGluYXRlcyB0byBzaXQgdGhlbSBpbiB0aGUgc2NlbmUncyBib3guICovXG4gIG9yaWdpbjogcmVhZG9ubHkgW251bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICB6U2NhbGU6IG51bWJlcjtcbn1cblxuLyoqIFRoZSBnZW5lcyBhIHZpZXcgZHJhd3MgaW4gM0QsIGFzIHRoZSB0aWxlIHF1ZXJ5IHRha2VzIHRoZW0sIG9yIG51bGwgd2hlbiBpdCBkcmF3cyBub25lLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zY3JpcHRzM2RHZW5lcyhcbiAgZGF0YXNldDogU3BhdGlhbERhdGFzZXQsXG4gIHZpZXc6IFNwYXRpYWxWaWV3U3RhdGUsXG4pOiB7IHF1ZXJ5OiBzdHJpbmdbXTsgYWxsR2VuZXM6IGJvb2xlYW4gfSB8IG51bGwge1xuICBpZiAodmlldy50cmFuc2NyaXB0TW9kZSA9PT0gJ29mZicpIHJldHVybiBudWxsO1xuICBpZiAodmlldy50cmFuc2NyaXB0QWxsR2VuZXMpIHtcbiAgICBpZiAoYWxsR2VuZXNIaWRkZW4odmlldykpIHJldHVybiBudWxsO1xuICAgIHJldHVybiB7IHF1ZXJ5OiBbQUxMX0dFTkVTXSwgYWxsR2VuZXM6IHRydWUgfTtcbiAgfVxuICBjb25zdCBoaWRkZW4gPSBuZXcgU2V0KHZpZXcudHJhbnNjcmlwdEhpZGRlbkdlbmVzKTtcbiAgY29uc3QgZ2VuZXMgPSB2aWV3LnRyYW5zY3JpcHRHZW5lcy5maWx0ZXIoKGcpID0+ICFoaWRkZW4uaGFzKGcpKTtcbiAgcmV0dXJuIGdlbmVzLmxlbmd0aCA/IHsgcXVlcnk6IGdlbmVzLCBhbGxHZW5lczogZmFsc2UgfSA6IG51bGw7XG59XG5cbi8qKlxuICogRWFjaCBsb2FkZWQgdHJhbnNjcmlwdCdzIGNvbG91ciwgcGFja2VkIFJHQkEsIGFzIHRoZSAyRCBtYXJrZXJzIGNvbG91ciB0aGVtIGJ5IGdlbmU6IGEgZ2VuZSdzXG4gKiBjaG9zZW4gY29sb3VyLCBlbHNlIHRoZSBwYWxldHRlJ3MgYnkgaXRzIHNsb3QgKHRoZSBzZWxlY3Rpb24ncyBvcmRlciwgb3Igd2l0aCBcIkFsbCBnZW5lc1wiIHRoZVxuICogZGF0YXNldCdzIGdlbmUgY29kZSkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2NyaXB0czNkQ29sb3JzKFxuICB2aWV3OiBTcGF0aWFsVmlld1N0YXRlLFxuICBuYW1lczogcmVhZG9ubHkgc3RyaW5nW10gfCBudWxsLFxuICBnZW5lOiBVaW50MTZBcnJheSxcbiAgY291bnQ6IG51bWJlcixcbik6IEZsb2F0MzJBcnJheSB7XG4gIGNvbnN0IG4gPSBuYW1lcyA/IG5hbWVzLmxlbmd0aCA6IERFRkFVTFRfQ0FURUdPUklDQUxfUEFMRVRURS5sZW5ndGg7XG4gIGNvbnN0IHRhYmxlID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogbiB9LCAoX2csIGkpID0+XG4gICAgcmdiYTAxKFxuICAgICAgKG5hbWVzICYmIHZpZXcudHJhbnNjcmlwdEdlbmVDb2xvcnNbbmFtZXNbaV1dKSB8fFxuICAgICAgICBERUZBVUxUX0NBVEVHT1JJQ0FMX1BBTEVUVEVbaSAlIERFRkFVTFRfQ0FURUdPUklDQUxfUEFMRVRURS5sZW5ndGhdLFxuICAgICksXG4gICk7XG4gIHJldHVybiBwYWNrZWQoY291bnQsIChpKSA9PiB0YWJsZVtuYW1lcyA/IGdlbmVbaV0gOiBnZW5lW2ldICUgbl0pO1xufVxuXG4vKipcbiAqIEhvdyB0aGUgcGFuZWwncyBcIkNvbG91ciBieVwiIGFwcGxpZXMgaW4gM0QsIGFzIGl0IGRvZXMgdG8gdGhlIDJEIG1hcmtlcnMgKGBjb2xvclZpZXdGb3JgKTogYnlcbiAqIGNlbGwgdHlwZSB3aGVuIHRoZSBkYXRhc2V0IGhhcyBvbmUgKGVsc2UgYnkgZ2VuZSksIGJ5IGNsdXN0ZXIgZm9yIHRoZSBzZWxlY3RlZCBnZW5lcyAod2l0aCBcIkFsbFxuICogZ2VuZXNcIiBhIGNsdXN0ZXIgaXMgaXRzIGdlbmUpLCBieSBnZW5lIG90aGVyd2lzZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zY3JpcHRzM2RDb2xvckJ5KFxuICBkYXRhc2V0OiBTcGF0aWFsRGF0YXNldCxcbiAgdmlldzogU3BhdGlhbFZpZXdTdGF0ZSxcbiAgYWxsR2VuZXM6IGJvb2xlYW4sXG4pOiAnY2VsbFR5cGUnIHwgJ2NsdXN0ZXInIHwgJ2dlbmUnIHtcbiAgY29uc3QgYnkgPSB2aWV3LnRyYW5zY3JpcHRDb2xvckJ5O1xuICBpZiAoYnkgPT09ICdjZWxsVHlwZScpIHJldHVybiBjZWxsVHlwZUNvbHVtbkZvcihkYXRhc2V0LCB2aWV3KSA/ICdjZWxsVHlwZScgOiAnZ2VuZSc7XG4gIGlmIChieSA9PT0gJ2NsdXN0ZXInICYmICFhbGxHZW5lcykgcmV0dXJuICdjbHVzdGVyJztcbiAgcmV0dXJuICdnZW5lJztcbn1cblxuLyoqIFRoZSBjb2xvdXJzIHRoZSBjZWxscycgZ3JvdXBpbmcgZ2l2ZXMgaXRzIGdyb3VwcywgYnkgbmFtZSAobm9uZSB3aXRob3V0IGEgZ3JvdXBpbmcpLiAqL1xuYXN5bmMgZnVuY3Rpb24gY2VsbEdyb3VwQ29sb3JzKFxuICBkYXRhc2V0OiBTcGF0aWFsRGF0YXNldCxcbiAgdmlldzogU3BhdGlhbFZpZXdTdGF0ZSxcbiAgcG9ydDogU3BhdGlhbERhdGFQb3J0LFxuKTogUHJvbWlzZTx7IGNvZGVzOiBVaW50MTZBcnJheTsgY29sb3JzOiAocmVhZG9ubHkgbnVtYmVyW10pW107IGJ5TmFtZTogTWFwPHN0cmluZywgc3RyaW5nPiB9IHwgbnVsbD4ge1xuICBjb25zdCBuYW1lID0gY2VsbFR5cGVDb2x1bW5Gb3IoZGF0YXNldCwgdmlldyk7XG4gIGlmICghbmFtZSkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IGNvbHVtbiA9IGF3YWl0IHBvcnQuZ2V0Q29sdW1uKG5hbWUpO1xuICBpZiAoIWlzQ2F0ZWdvcmljYWxDb2x1bW4oY29sdW1uKSkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IGhleCA9IGNhdGVnb3J5Q29sb3JzRm9yKG5hbWUsIGNvbHVtbi5tZXRhLCB2aWV3Lmdyb3VwQ29sb3JzKTtcbiAgY29uc3QgYnlOYW1lID0gbmV3IE1hcChjb2x1bW4ubWV0YS5jYXRlZ29yaWVzLm1hcCgoYywgaykgPT4gW2MsIGhleFtrXV0gYXMgY29uc3QpKTtcbiAgcmV0dXJuIHsgY29kZXM6IGNvbHVtbi5jb2RlcywgY29sb3JzOiBoZXgubWFwKHJnYmEwMSksIGJ5TmFtZSB9O1xufVxuXG4vKiogYCNycmdnYmJgIGFzIGFuIG9wYXF1ZSAwLi4xIFJHQkEuICovXG5mdW5jdGlvbiByZ2JhMDEoaGV4OiBzdHJpbmcpOiByZWFkb25seSBudW1iZXJbXSB7XG4gIGNvbnN0IFtyLCBnLCBiXSA9IHBhcnNlSGV4KGhleCk7XG4gIHJldHVybiBbciAvIDI1NSwgZyAvIDI1NSwgYiAvIDI1NSwgMV07XG59XG5cbi8qKiBgY291bnRgIGNvbG91cnMgcGFja2VkIFJHQkEsIHVuYXNzaWduZWQgd2hlcmUgYGF0YCBoYXMgbm9uZS4gKi9cbmZ1bmN0aW9uIHBhY2tlZChjb3VudDogbnVtYmVyLCBhdDogKGk6IG51bWJlcikgPT4gcmVhZG9ubHkgbnVtYmVyW10gfCB1bmRlZmluZWQpOiBGbG9hdDMyQXJyYXkge1xuICBjb25zdCBvdXQgPSBuZXcgRmxvYXQzMkFycmF5KGNvdW50ICogNCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgb3V0LnNldChhdChpKSA/PyBVTkFTU0lHTkVEX1JHQkEsIGkgKiA0KTtcbiAgcmV0dXJuIG91dDtcbn1cblxuLyoqXG4gKiBUaGUgdHJhbnNjcmlwdHMgb2YgdGhlIDNEIHNwYXRpYWwgdmlldzogdGhlIG1vbGVjdWxlcyBvZiB0aGUgZ2VuZXMgdGhlIFRyYW5zY3JpcHRzIHBhbmVsIGRyYXdzXG4gKiAoaXRzIHNlbGVjdGVkIGdlbmVzLCBvciBcIkFsbCBnZW5lc1wiKSwgYXQgdGhlaXIgb3duIHgsIHkgYW5kIHosIGluIHRoZSBjbG91ZCdzIGJveCBhbmQgWiBzdHJldGNoLlxuICpcbiAqIEJ5IGxldmVsIG9mIGRldGFpbCwgYXMgdGhlIDJEIHZpZXcgcmVhZHMgdGhlbTogdGhlIHB5cmFtaWQgbGV2ZWwgdGhlIGNhbWVyYSdzIGRpc3RhbmNlIGNhbGxzIGZvclxuICogKGB0cmFuc2NyaXB0TGV2ZWxGb3JgLCB0aGUgbWFya2VycyBwZXIgc2NyZWVuIGtlcHQgYWJvdXQgY29uc3RhbnQ6IGFnZ3JlZ2F0ZXMgZmFyIG91dCwgZXZlcnlcbiAqIG1vbGVjdWxlIGNsb3NlIGluIG9uIGEgY2VsbCksIGFuZCBvbmx5IHRoZSB0aWxlcyBvZiB0aGUgcGFydCBvZiB0aGUgc2VjdGlvbiBpbiB2aWV3ICh0aGUgY2FudmFzJ3NcbiAqIGNvcm5lcnMgY2FzdCBvbnRvIHRoZSBzZWN0aW9uJ3MgcGxhbmUpLiBQbGFubmVkIGFnYWluIHdoZW4gdGhlIGNhbWVyYSByZXN0czsgdGlsZXMgYXJlIGNhY2hlZCwgc29cbiAqIGNvbWluZyBiYWNrIHJlYWRzIG5vdGhpbmcuIFwiTG9hZGluZyB0cmFuc2NyaXB0c+KAplwiIHNob3dzIG9uIHRoZSBjYW52YXMgd2hpbGUgdGhleSBsb2FkIGFuZCBkcmF3LlxuICogRHJhd24gb25seSBmb3IgYSBkYXRhc2V0IHdob3NlIHRyYW5zY3JpcHRzIGNhcnJ5IHouXG4gKi9cbmV4cG9ydCBjbGFzcyBTcGF0aWFsM2RUcmFuc2NyaXB0cyB7XG4gIHByaXZhdGUgbGF5ZXI6IFBvaW50czNETGF5ZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqIFdoYXQge0BsaW5rIGxheWVyfSB3YXMgbG9hZGVkIGZyb20gKGRhdGFzZXQsIGdlbmVzLCBxdWFsaXR5KSwgYW5kIHN0eWxlZCB3aXRoLiAqL1xuICBwcml2YXRlIGxvYWRLZXk6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHN0eWxlS2V5OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBsb2FkZWQ6IHsgdGlsZXM6IFNwYXRpYWxUcmFuc2NyaXB0VGlsZVtdOyBuYW1lczogcmVhZG9ubHkgc3RyaW5nW10gfCBudWxsIH0gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSByZWFkb25seSBsb2FkcyA9IG5ldyBTdXBlcnNlZGUoKTtcbiAgLyoqIEVhY2ggZHJhd24gdHJhbnNjcmlwdCdzIGNlbGwgKHtAbGluayBOT19PQlNFUlZBVElPTn0gZm9yIG5vbmUpLCBmb3IgZmFkaW5nIGJ5IHRoZSBzZWxlY3Rpb24uICovXG4gIHByaXZhdGUgZHJhd25DZWxsczogVWludDMyQXJyYXkgfCBudWxsID0gbnVsbDtcbiAgLyoqIFRoZSBzZWxlY3Rpb24gdGhlIGxheWVyJ3MgYWxwaGFzIGZhZGUgYnkgKG51bGw6IG5vbmUsIGV2ZXJ5IHRyYW5zY3JpcHQgYXMgaXQgaXMpLiAqL1xuICBwcml2YXRlIGZhZGVkQnk6IFNwYXRpYWxTZWxlY3Rpb25NYXNrIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBUaGUgbGFzdCBzeW5jJ3MgaW5wdXRzOiB0aGUgY2FtZXJhIHJlc3RpbmcgcGxhbnMgdGhlIGRldGFpbCBhZ2FpbiBmcm9tIHRoZW0uICovXG4gIHByaXZhdGUgbGFzdDoge1xuICAgIGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0O1xuICAgIHZpZXc6IFNwYXRpYWxWaWV3U3RhdGU7XG4gICAgcG9ydDogU3BhdGlhbERhdGFQb3J0IHwgbnVsbDtcbiAgICBmcmFtZTogVHJhbnNjcmlwdHMzZEZyYW1lO1xuICAgIHNlbGVjdGlvbjogU3BhdGlhbFNlbGVjdGlvbk1hc2sgfCBudWxsO1xuICB9IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgY2FtZXJhVGltZXI6IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgY2FtZXJhT2ZmOiAoKCkgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcbiAgLyoqIFRpbGVzIHJlYWQsIGJ5IGdlbmVzLCBxdWFsaXR5LCBsZXZlbCBhbmQgdGlsZSAobGVhc3QgcmVjZW50bHkgdXNlZCBkcm9wcGVkIGZpcnN0KS4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSB0aWxlQ2FjaGUgPSBuZXcgTWFwPHN0cmluZywgUHJvbWlzZTxTcGF0aWFsVHJhbnNjcmlwdFRpbGU+PigpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgdmlld2VyOiBWaWV3ZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBiZWdpbjogKG1lc3NhZ2U6IHN0cmluZykgPT4gKCkgPT4gdm9pZCxcbiAgKSB7XG4gICAgdGhpcy5jYW1lcmFPZmYgPSB2aWV3ZXIuY2FtZXJhM2Q/LmNoYW5nZWQ/LmNvbm5lY3QoKCkgPT4gdGhpcy5jYW1lcmFNb3ZlZCgpKSA/PyBudWxsO1xuICB9XG5cbiAgLyoqIFRoZSBjYW1lcmEgbW92ZWQ6IG9uY2UgaXQgcmVzdHMsIHJlYWQgdGhlIGxldmVsIGFuZCB0aWxlcyBpdCBub3cgY2FsbHMgZm9yLiAqL1xuICBwcml2YXRlIGNhbWVyYU1vdmVkKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5sYXN0KSByZXR1cm47XG4gICAgaWYgKHRoaXMuY2FtZXJhVGltZXIpIGNsZWFyVGltZW91dCh0aGlzLmNhbWVyYVRpbWVyKTtcbiAgICB0aGlzLmNhbWVyYVRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmNhbWVyYVRpbWVyID0gbnVsbDtcbiAgICAgIGNvbnN0IGxhc3QgPSB0aGlzLmxhc3Q7XG4gICAgICBpZiAobGFzdCkgdm9pZCB0aGlzLnN5bmMobGFzdC5kYXRhc2V0LCBsYXN0LnZpZXcsIGxhc3QucG9ydCwgbGFzdC5mcmFtZSwgbGFzdC5zZWxlY3Rpb24pO1xuICAgIH0sIENBTUVSQV9SRVNUX01TKTtcbiAgfVxuXG4gIC8qKiBTdG9wIGZvbGxvd2luZyB0aGUgY2FtZXJhICh0aGUgc2NlbmUgd2VudCBhd2F5KS4gKi9cbiAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICB0aGlzLmNhbWVyYU9mZj8uKCk7XG4gICAgdGhpcy5jYW1lcmFPZmYgPSBudWxsO1xuICAgIGlmICh0aGlzLmNhbWVyYVRpbWVyKSBjbGVhclRpbWVvdXQodGhpcy5jYW1lcmFUaW1lcik7XG4gICAgdGhpcy5jYW1lcmFUaW1lciA9IG51bGw7XG4gICAgdGhpcy5sYXN0ID0gbnVsbDtcbiAgICB0aGlzLnJlbW92ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBsZXZlbCBhbmQgdGhlIHRpbGVzIHRoZSBjYW1lcmEgY2FsbHMgZm9yOiB0aGUgbGV2ZWwgd2hvc2UgdGlsZXMgY29tZSBvdXQgYWJvdXQgNTEyIHNjcmVlblxuICAgKiBwaXhlbHMgYWNyb3NzIGF0IHRoZSB0YXJnZXQncyBkZXB0aCwgdGhlIHRpbGVzIG9mIHRoZSBzZWN0aW9uIGluIHZpZXcgKHdob2xlLCB3aGVuIGEgY29ybmVyIG9mXG4gICAqIHRoZSBjYW52YXMgbG9va3MgcGFzdCB0aGUgc2VjdGlvbidzIHBsYW5lKS5cbiAgICovXG4gIHByaXZhdGUgcGxhbihtZXRhOiBOb25OdWxsYWJsZTxTcGF0aWFsRGF0YXNldFsndHJhbnNjcmlwdFRpbGVzJ10+LCBmcmFtZTogVHJhbnNjcmlwdHMzZEZyYW1lKSB7XG4gICAgY29uc3QgW3Z3LCB2aF0gPSB0aGlzLnZpZXdlci52aWV3cG9ydFNpemU/LigpID8/IFswLCAwXTtcbiAgICBjb25zdCBjYW1lcmEgPSB0aGlzLnZpZXdlci5jYW1lcmEzZDtcbiAgICBjb25zdCB3cHAgPSBjYW1lcmEgJiYgdmggPiAwID8gY2FtZXJhLndvcmxkUGVyUGl4ZWwodmgpIDogMDtcbiAgICBsZXQgbGV2ZWwgPSB3cHAgPiAwID8gdHJhbnNjcmlwdExldmVsRm9yKDEgLyB3cHAsIG1ldGEubGV2ZWxzKSA6IG1ldGEubGV2ZWxzLmxlbmd0aCAtIDE7XG4gICAgY29uc3QgW3gwLCB5MCwgeDEsIHkxXSA9IG1ldGEuYm91bmRzO1xuICAgIGxldCByZWN0OiBEYXRhUmVjdCA9IHsgeDAsIHkwLCB4MTogeDEgKyAxZS02LCB5MTogeTEgKyAxZS02IH07XG4gICAgY29uc3Qgc2VlbiA9IHZ3ID4gMCAmJiB2aCA+IDAgPyB0aGlzLmZvb3RwcmludCh2dywgdmgsIGZyYW1lKSA6IG51bGw7XG4gICAgaWYgKHNlZW4pIHJlY3QgPSBzZWVuO1xuICAgIC8vIENsb3NlIGluIGJ1dCBsb29raW5nIGZhciBhY3Jvc3MgdGhlIHNlY3Rpb246IGNvYXJzZXIsIHVudGlsIHRoZSB0aWxlcyBpbiB2aWV3IGFyZSBmZXcgZW5vdWdoLlxuICAgIGxldCBrZXlzID0gdGlsZXNJblJlY3QocmVjdCwgbGV2ZWwsIG1ldGEubGV2ZWxzLCBtZXRhLmJvdW5kcyk7XG4gICAgd2hpbGUgKGtleXMubGVuZ3RoID4gVklFV19USUxFU19NQVggJiYgbGV2ZWwgPCBtZXRhLmxldmVscy5sZW5ndGggLSAxKSB7XG4gICAgICBsZXZlbCsrO1xuICAgICAga2V5cyA9IHRpbGVzSW5SZWN0KHJlY3QsIGxldmVsLCBtZXRhLmxldmVscywgbWV0YS5ib3VuZHMpO1xuICAgIH1cbiAgICByZXR1cm4geyBsZXZlbCwga2V5cyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBwYXJ0IG9mIHRoZSBzZWN0aW9uIHRoZSBjYW52YXMgc2VlcywgaW4gb2JzZXJ2YXRpb24gdW5pdHM6IGl0cyBjb3JuZXJzIGFuZCBjZW50cmUgY2FzdCBvbnRvXG4gICAqIHRoZSBwbGFuZSB0aHJvdWdoIHRoZSBjYW1lcmEncyB0YXJnZXQsIHdpZGVuZWQgYnkgYSBxdWFydGVyLiBBIGNvcm5lciBsb29raW5nIHBhc3QgdGhlIHBsYW5lXG4gICAqICh0b3dhcmRzIHRoZSBob3Jpem9uKSByZWFjaGVzIGZhciBhbG9uZyBpdHMgcmF5IGluc3RlYWQgKHRoZSB0aWxlcyBhcmUgY2xpcHBlZCB0byB0aGUgc2VjdGlvbikuXG4gICAqL1xuICBwcml2YXRlIGZvb3RwcmludCh2dzogbnVtYmVyLCB2aDogbnVtYmVyLCBmcmFtZTogVHJhbnNjcmlwdHMzZEZyYW1lKTogRGF0YVJlY3QgfCBudWxsIHtcbiAgICBjb25zdCB6ID0gdGhpcy52aWV3ZXIuY2FtZXJhM2Q/LnRhcmdldD8uWzJdO1xuICAgIGlmICh6ID09PSB1bmRlZmluZWQgfHwgIXRoaXMudmlld2VyLmNhbnZhc1JheSkgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgW294LCBveV0gPSBmcmFtZS5vcmlnaW47XG4gICAgbGV0IHhhID0gSW5maW5pdHksXG4gICAgICB5YSA9IEluZmluaXR5LFxuICAgICAgeGIgPSAtSW5maW5pdHksXG4gICAgICB5YiA9IC1JbmZpbml0eTtcbiAgICBmb3IgKGNvbnN0IFtjeCwgY3ldIG9mIFtcbiAgICAgIFswLCAwXSxcbiAgICAgIFt2dywgMF0sXG4gICAgICBbMCwgdmhdLFxuICAgICAgW3Z3LCB2aF0sXG4gICAgICBbdncgLyAyLCB2aCAvIDJdLFxuICAgIF0pIHtcbiAgICAgIGNvbnN0IHJheSA9IHRoaXMudmlld2VyLmNhbnZhc1JheShjeCwgY3kpO1xuICAgICAgaWYgKCFyYXkpIHJldHVybiBudWxsO1xuICAgICAgY29uc3QgaGl0ID0gTWF0aC5hYnMocmF5LmRpclsyXSkgPiAxZS02ID8gKHogLSByYXkub3JpZ2luWzJdKSAvIHJheS5kaXJbMl0gOiAtMTtcbiAgICAgIGNvbnN0IHQgPSBoaXQgPiAwID8gaGl0IDogSE9SSVpPTjtcbiAgICAgIGNvbnN0IHggPSByYXkub3JpZ2luWzBdICsgcmF5LmRpclswXSAqIHQgLSBveDtcbiAgICAgIGNvbnN0IHkgPSByYXkub3JpZ2luWzFdICsgcmF5LmRpclsxXSAqIHQgLSBveTtcbiAgICAgIHhhID0gTWF0aC5taW4oeGEsIHgpO1xuICAgICAgeWEgPSBNYXRoLm1pbih5YSwgeSk7XG4gICAgICB4YiA9IE1hdGgubWF4KHhiLCB4KTtcbiAgICAgIHliID0gTWF0aC5tYXgoeWIsIHkpO1xuICAgIH1cbiAgICBjb25zdCBteCA9ICh4YiAtIHhhKSAvIDQ7XG4gICAgY29uc3QgbXkgPSAoeWIgLSB5YSkgLyA0O1xuICAgIHJldHVybiB7IHgwOiB4YSAtIG14LCB5MDogeWEgLSBteSwgeDE6IHhiICsgbXgsIHkxOiB5YiArIG15IH07XG4gIH1cblxuICAvKiogQSB0aWxlLCByZWFkIG9uY2UgKGFuZCBhZ2FpbiBvbmx5IG9uY2UgZHJvcHBlZCBmcm9tIHRoZSBjYWNoZSkuICovXG4gIHByaXZhdGUgdGlsZShrZXk6IHN0cmluZywgcmVhZDogKCkgPT4gUHJvbWlzZTxTcGF0aWFsVHJhbnNjcmlwdFRpbGU+KTogUHJvbWlzZTxTcGF0aWFsVHJhbnNjcmlwdFRpbGU+IHtcbiAgICBsZXQgaGl0ID0gdGhpcy50aWxlQ2FjaGUuZ2V0KGtleSk7XG4gICAgaWYgKGhpdCkge1xuICAgICAgdGhpcy50aWxlQ2FjaGUuZGVsZXRlKGtleSk7XG4gICAgICB0aGlzLnRpbGVDYWNoZS5zZXQoa2V5LCBoaXQpO1xuICAgICAgcmV0dXJuIGhpdDtcbiAgICB9XG4gICAgaGl0ID0gcmVhZCgpO1xuICAgIGhpdC5jYXRjaCgoKSA9PiB0aGlzLnRpbGVDYWNoZS5kZWxldGUoa2V5KSk7XG4gICAgdGhpcy50aWxlQ2FjaGUuc2V0KGtleSwgaGl0KTtcbiAgICB3aGlsZSAodGhpcy50aWxlQ2FjaGUuc2l6ZSA+IFRJTEVfQ0FDSEVfU0laRSlcbiAgICAgIHRoaXMudGlsZUNhY2hlLmRlbGV0ZSh0aGlzLnRpbGVDYWNoZS5rZXlzKCkubmV4dCgpLnZhbHVlIGFzIHN0cmluZyk7XG4gICAgcmV0dXJuIGhpdDtcbiAgfVxuXG4gIC8qKiBUaGUgbGF5ZXIgZHJhd24sIGlmIGFueSAoZm9yIHRlc3RzIGFuZCB0aGUgc2NlbmUncyBaIHN0cmV0Y2gpLiAqL1xuICBnZXQgZHJhd24oKTogUG9pbnRzM0RMYXllciB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLmxheWVyO1xuICB9XG5cbiAgLyoqXG4gICAqIERyYXcgd2hhdCBgdmlld2AgYXNrcyBmb3IsIGxvYWRpbmcgdGhlIG1vbGVjdWxlcyB3aGVuIHRoZSBnZW5lcyBjaGFuZ2VkLiBXaXRoIGEgYHNlbGVjdGlvbmBcbiAgICogKGEgY2VsbCwgb3IgYSBjZWxsIHR5cGUncyBjZWxscyksIHRoZSB0cmFuc2NyaXB0cyBvZiB0aGUgc2VsZWN0ZWQgY2VsbHMga2VlcCB0aGVpciBjb2xvdXIgYW5kXG4gICAqIHRoZSBvdGhlcnMgZmFkZSwgYXMgdGhlIGNlbGxzIGRvLlxuICAgKi9cbiAgYXN5bmMgc3luYyhcbiAgICBkYXRhc2V0OiBTcGF0aWFsRGF0YXNldCxcbiAgICB2aWV3OiBTcGF0aWFsVmlld1N0YXRlLFxuICAgIHBvcnQ6IFNwYXRpYWxEYXRhUG9ydCB8IG51bGwsXG4gICAgZnJhbWU6IFRyYW5zY3JpcHRzM2RGcmFtZSxcbiAgICBzZWxlY3Rpb246IFNwYXRpYWxTZWxlY3Rpb25NYXNrIHwgbnVsbCA9IG51bGwsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG1ldGEgPSBkYXRhc2V0LnRyYW5zY3JpcHRUaWxlcztcbiAgICBjb25zdCBnZW5lcyA9IG1ldGE/Lmhhc1ogJiYgcG9ydD8uZ2V0VHJhbnNjcmlwdFRpbGUgPyB0cmFuc2NyaXB0czNkR2VuZXMoZGF0YXNldCwgdmlldykgOiBudWxsO1xuICAgIGlmICghbWV0YSB8fCAhZ2VuZXMgfHwgIXBvcnQpIHtcbiAgICAgIC8vIE9mZiAob3Igbm8gZ2VuZSBzaG93bik6IGEgY2FtZXJhIG1vdmUgbXVzdCBub3QgYnJpbmcgYmFjayB0aGUgbGFzdCB2aWV3IHRoYXQgZHJldyBzb21lLlxuICAgICAgdGhpcy5sYXN0ID0gbnVsbDtcbiAgICAgIGlmICh0aGlzLmNhbWVyYVRpbWVyKSBjbGVhclRpbWVvdXQodGhpcy5jYW1lcmFUaW1lcik7XG4gICAgICB0aGlzLmNhbWVyYVRpbWVyID0gbnVsbDtcbiAgICAgIHRoaXMucmVtb3ZlKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMubGFzdCA9IHsgZGF0YXNldCwgdmlldywgcG9ydCwgZnJhbWUsIHNlbGVjdGlvbiB9O1xuICAgIGNvbnN0IHF1YWxpdHkgPSB2aWV3LnRyYW5zY3JpcHRRdWFsaXR5ID09PSAnYWxsJyA/ICdhbGwnIDogJ2hpZ2gnO1xuICAgIGNvbnN0IHsgbGV2ZWwsIGtleXMgfSA9IHRoaXMucGxhbihtZXRhLCBmcmFtZSk7XG4gICAgY29uc3QgZ2VuZXNLZXkgPSBgJHtkYXRhc2V0LmlkfXwke2dlbmVzLnF1ZXJ5LmpvaW4oJ1xcdTAwMDEnKX18JHtxdWFsaXR5fWA7XG4gICAgY29uc3QgbG9hZEtleSA9IGAke2dlbmVzS2V5fXwke2xldmVsfXwke2tleXMubWFwKChrKSA9PiBgJHtrLmd4fSwke2suZ3l9YCkuam9pbignOycpfWA7XG4gICAgbGV0IGVuZDogKCgpID0+IHZvaWQpIHwgbnVsbCA9IG51bGw7XG4gICAgaWYgKGxvYWRLZXkgIT09IHRoaXMubG9hZEtleSkge1xuICAgICAgY29uc3QgdGFzayA9IHRoaXMubG9hZHMubmV4dCgpO1xuICAgICAgaWYgKGtleXMubGVuZ3RoID4gVFJBTlNDUklQVFNfM0RfTUFYX1RJTEVTKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihgW25hcGFyaS1qc10gJHtrZXlzLmxlbmd0aH0gdHJhbnNjcmlwdCB0aWxlcyBhcmUgdG9vIG1hbnkgdG8gcmVhZCBmb3IgdGhlIDNEIHZpZXdgKTtcbiAgICAgICAgdGhpcy5yZW1vdmUoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZW5kID0gdGhpcy5iZWdpbignTG9hZGluZyB0cmFuc2NyaXB0c+KApicpO1xuICAgICAgbGV0IHRpbGVzOiBTcGF0aWFsVHJhbnNjcmlwdFRpbGVbXTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRpbGVzID0gYXdhaXQgcG9vbGVkKGtleXMsIENPTkNVUlJFTkNZLCAoaykgPT5cbiAgICAgICAgICB0aGlzLnRpbGUoYCR7Z2VuZXNLZXl9fCR7bGV2ZWx9LyR7ay5neH0vJHtrLmd5fWAsICgpID0+XG4gICAgICAgICAgICBwb3J0LmdldFRyYW5zY3JpcHRUaWxlIShsZXZlbCwgay5neCwgay5neSwgeyBnZW5lczogZ2VuZXMucXVlcnksIHF1YWxpdHkgfSksXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zb2xlLndhcm4oJ1tuYXBhcmktanNdIHRyYW5zY3JpcHRzIGZvciB0aGUgM0QgdmlldyBjb3VsZCBub3QgYmUgcmVhZCcsIGVycik7XG4gICAgICAgIC8vIFRoZSBwYW5lbCBhc2tlZCBmb3Igb3RoZXIgdHJhbnNjcmlwdHMgdGhhbiB0aG9zZSBkcmF3bjogdGFrZSB0aGVtIGRvd24gcmF0aGVyIHRoYW4gbGVhdmVcbiAgICAgICAgLy8gdGhlIG9sZCBzZWxlY3Rpb24gdXAgYXMgaWYgaXQgd2VyZSB0aGUgbmV3IG9uZTsgdGhlIG5leHQgY2hhbmdlIHJlYWRzIGFnYWluLiBPbmx5IHRoZVxuICAgICAgICAvLyBjdXJyZW50IGxvYWQgbWF5OiBhIHN1cGVyc2VkZWQgb25lIG11c3Qgbm90IHRlYXIgZG93biB3aGF0IGEgbmV3ZXIgb25lIGRyZXcuXG4gICAgICAgIGlmICh0YXNrKCkpIHRoaXMuY2xlYXJMYXllcigpO1xuICAgICAgICBlbmQoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKCF0YXNrKCkpIHtcbiAgICAgICAgZW5kKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMubG9hZEtleSA9IGxvYWRLZXk7XG4gICAgICB0aGlzLnN0eWxlS2V5ID0gbnVsbDtcbiAgICAgIHRoaXMubG9hZGVkID0geyB0aWxlcywgbmFtZXM6IGdlbmVzLmFsbEdlbmVzID8gKG1ldGEuZ2VuZXMgPz8gbnVsbCkgOiBnZW5lcy5xdWVyeSB9O1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5kcmF3KGRhdGFzZXQsIHZpZXcsIHBvcnQsIGZyYW1lLCBnZW5lcy5hbGxHZW5lcyk7XG4gICAgICAvLyBUaGUgbmV3ZXN0IHN5bmMncyBzZWxlY3Rpb246IGFuIG9sZGVyIGRyYXcgZmluaXNoaW5nIGxhdGUgbXVzdCBub3QgZmFkZSBieSBhIHN0YWxlIG9uZS5cbiAgICAgIGlmICh0aGlzLmxhc3Q/LnNlbGVjdGlvbiA9PT0gc2VsZWN0aW9uKSB0aGlzLmZhZGUoc2VsZWN0aW9uKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgZW5kPy4oKTtcbiAgICB9XG4gIH1cblxuICAvKiogRm9sbG93IHRoZSBzY2VuZSdzIFogc3RyZXRjaCAobm90aGluZyBpcyByZS11cGxvYWRlZCkuICovXG4gIHNldFpTY2FsZShzOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5sYXllcikgdGhpcy5sYXllci5zY2FsZTNkID0gWzEsIDEsIHNdO1xuICB9XG5cbiAgLyoqIFRha2UgdGhlIGxheWVyIGRvd24gYW5kIGZvcmdldCB3aGF0IGl0IHNob3dlZC4gKi9cbiAgcmVtb3ZlKCk6IHZvaWQge1xuICAgIHRoaXMubG9hZHMuY2FuY2VsKCk7XG4gICAgdGhpcy5jbGVhckxheWVyKCk7XG4gIH1cblxuICBwcml2YXRlIGNsZWFyTGF5ZXIoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubGF5ZXIpIHRoaXMudmlld2VyLmxheWVycy5yZW1vdmUodGhpcy5sYXllcik7XG4gICAgdGhpcy5sYXllciA9IG51bGw7XG4gICAgdGhpcy5sb2FkS2V5ID0gbnVsbDtcbiAgICB0aGlzLnN0eWxlS2V5ID0gbnVsbDtcbiAgICB0aGlzLmxvYWRlZCA9IG51bGw7XG4gICAgdGhpcy5kcmF3bkNlbGxzID0gbnVsbDtcbiAgICB0aGlzLmZhZGVkQnkgPSBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIEZhZGUgdGhlIGRyYXduIHRyYW5zY3JpcHRzIG91dHNpZGUgdGhlIHNlbGVjdGlvbiAodGhlaXIgYWxwaGEgb25seTogdGhlIGNvbG91cnMgc3RheVxuICAgKiB1cGxvYWRlZCksIG9yIGJyaW5nIHRoZW0gYWxsIGJhY2sgd2l0aG91dCBvbmUuIEEgbm8tb3AgZm9yIHRoZSBzZWxlY3Rpb24gYWxyZWFkeSBhcHBsaWVkLlxuICAgKi9cbiAgcHJpdmF0ZSBmYWRlKHNlbGVjdGlvbjogU3BhdGlhbFNlbGVjdGlvbk1hc2sgfCBudWxsKTogdm9pZCB7XG4gICAgY29uc3QgbGl2ZSA9IHNlbGVjdGlvbiAmJiBzZWxlY3Rpb24uY291bnQgPiAwID8gc2VsZWN0aW9uIDogbnVsbDtcbiAgICBjb25zdCBsYXllciA9IHRoaXMubGF5ZXI7XG4gICAgY29uc3QgY2VsbHMgPSB0aGlzLmRyYXduQ2VsbHM7XG4gICAgaWYgKCFsYXllciB8fCAhY2VsbHMgfHwgbGl2ZSA9PT0gdGhpcy5mYWRlZEJ5KSByZXR1cm47XG4gICAgdGhpcy5mYWRlZEJ5ID0gbGl2ZTtcbiAgICBpZiAoIWxpdmUpIHtcbiAgICAgIGxheWVyLmFscGhhcyA9IG51bGw7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGFscGhhcyA9IG5ldyBGbG9hdDMyQXJyYXkoY2VsbHMubGVuZ3RoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNlbGxzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBvID0gY2VsbHNbaV07XG4gICAgICBhbHBoYXNbaV0gPSBvICE9PSBOT19PQlNFUlZBVElPTiAmJiBvIDwgbGl2ZS5tYXNrLmxlbmd0aCAmJiBsaXZlLm1hc2tbb10gPyAxIDogREVGQVVMVF9NVVRFRF9PUEFDSVRZO1xuICAgIH1cbiAgICBsYXllci5hbHBoYXMgPSBhbHBoYXM7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGRyYXcoXG4gICAgZGF0YXNldDogU3BhdGlhbERhdGFzZXQsXG4gICAgdmlldzogU3BhdGlhbFZpZXdTdGF0ZSxcbiAgICBwb3J0OiBTcGF0aWFsRGF0YVBvcnQsXG4gICAgZnJhbWU6IFRyYW5zY3JpcHRzM2RGcmFtZSxcbiAgICBhbGxHZW5lczogYm9vbGVhbixcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbG9hZGVkID0gdGhpcy5sb2FkZWQ7XG4gICAgaWYgKCFsb2FkZWQpIHJldHVybjtcbiAgICBjb25zdCBieSA9IHRyYW5zY3JpcHRzM2RDb2xvckJ5KGRhdGFzZXQsIHZpZXcsIGFsbEdlbmVzKTtcbiAgICBjb25zdCBzdHlsZUtleSA9IFtcbiAgICAgIGZyYW1lLm9yaWdpbi5qb2luKCcsJyksXG4gICAgICBieSxcbiAgICAgIGJ5ID09PSAnZ2VuZScgPyBKU09OLnN0cmluZ2lmeSh2aWV3LnRyYW5zY3JpcHRHZW5lQ29sb3JzKSA6ICcnLFxuICAgICAgYnkgIT09ICdnZW5lJyA/IGAke2NlbGxUeXBlQ29sdW1uRm9yKGRhdGFzZXQsIHZpZXcpfXwke0pTT04uc3RyaW5naWZ5KHZpZXcuZ3JvdXBDb2xvcnMpfWAgOiAnJyxcbiAgICAgIGJ5ID09PSAnY2x1c3RlcicgPyBKU09OLnN0cmluZ2lmeSh2aWV3LnRyYW5zY3JpcHRHZW5lR3JvdXBzKSA6ICcnLFxuICAgICAgYWxsR2VuZXMgPyB2aWV3LnRyYW5zY3JpcHRBbGxHZW5lc0hpZGRlbi5qb2luKCcsJykgOiAnJyxcbiAgICBdLmpvaW4oJ3wnKTtcbiAgICBjb25zdCBzaXplID0gVFJBTlNDUklQVF8zRF9CQVNFX1NJWkUgKiAodmlldy50cmFuc2NyaXB0U2NhbGUgPiAwID8gdmlldy50cmFuc2NyaXB0U2NhbGUgOiAxKTtcbiAgICBpZiAodGhpcy5sYXllciAmJiBzdHlsZUtleSA9PT0gdGhpcy5zdHlsZUtleSkge1xuICAgICAgdGhpcy5sYXllci5zaXplID0gc2l6ZTtcbiAgICAgIHRoaXMubGF5ZXIub3BhY2l0eSA9IHZpZXcudHJhbnNjcmlwdE9wYWNpdHk7XG4gICAgICB0aGlzLmxheWVyLnNjYWxlM2QgPSBbMSwgMSwgZnJhbWUuelNjYWxlXTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgeyBuYW1lcyB9ID0gbG9hZGVkO1xuICAgIGNvbnN0IHNob3duID0gYWxsR2VuZXMgJiYgbmFtZXMgPyBhbGxHZW5lU2hvd25CeSh2aWV3LnRyYW5zY3JpcHRBbGxHZW5lc0hpZGRlbikgOiBudWxsO1xuICAgIGNvbnN0IGtlZXAgPSBzaG93biAmJiBuYW1lcyA/IChnOiBudW1iZXIpID0+ICEhbmFtZXNbZ10gJiYgc2hvd24obmFtZXNbZ10pIDogKCkgPT4gdHJ1ZTtcbiAgICBjb25zdCB0b3RhbCA9IGxvYWRlZC50aWxlcy5yZWR1Y2UoKG4sIHQpID0+IG4gKyB0LmNvdW50LCAwKTtcbiAgICBjb25zdCBzdHJpZGUgPSBNYXRoLm1heCgxLCBNYXRoLmNlaWwodG90YWwgLyBUUkFOU0NSSVBUU18zRF9NQVgpKTtcbiAgICBpZiAoc3RyaWRlID4gMSkgY29uc29sZS53YXJuKGBbbmFwYXJpLWpzXSBkcmF3aW5nIGV2ZXJ5ICR7c3RyaWRlfXRoIG9mICR7dG90YWx9IHRyYW5zY3JpcHRzIGluIDNEYCk7XG5cbiAgICBjb25zdCBbb3gsIG95LCBvel0gPSBmcmFtZS5vcmlnaW47XG4gICAgY29uc3QgcG9zaXRpb25zOiBudW1iZXJbXSA9IFtdO1xuICAgIGNvbnN0IGdlbmVzOiBudW1iZXJbXSA9IFtdO1xuICAgIGNvbnN0IGNlbGxzOiBudW1iZXJbXSA9IFtdO1xuICAgIGxldCBzZWVuID0gMDtcbiAgICBmb3IgKGNvbnN0IHQgb2YgbG9hZGVkLnRpbGVzKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHQuY291bnQ7IGkrKykge1xuICAgICAgICBpZiAoIWtlZXAodC5nZW5lW2ldKSB8fCBzZWVuKysgJSBzdHJpZGUpIGNvbnRpbnVlO1xuICAgICAgICBwb3NpdGlvbnMucHVzaCh0LnhbaV0gKyBveCwgdC55W2ldICsgb3ksIHQueltpXSArIG96KTtcbiAgICAgICAgZ2VuZXMucHVzaCh0LmdlbmVbaV0pO1xuICAgICAgICBjZWxscy5wdXNoKHQub2JzZXJ2YXRpb25baV0pO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBjb3VudCA9IGdlbmVzLmxlbmd0aDtcbiAgICBsZXQgY29sb3JzOiBGbG9hdDMyQXJyYXk7XG4gICAgaWYgKGJ5ID09PSAnZ2VuZScpIHtcbiAgICAgIGNvbG9ycyA9IHRyYW5zY3JpcHRzM2RDb2xvcnModmlldywgbmFtZXMsIFVpbnQxNkFycmF5LmZyb20oZ2VuZXMpLCBjb3VudCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGdyb3VwcyA9IGF3YWl0IGNlbGxHcm91cENvbG9ycyhkYXRhc2V0LCB2aWV3LCBwb3J0KS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgIGNvbnNvbGUud2FybignW25hcGFyaS1qc10gdGhlIGNlbGxzIGdyb3VwaW5nIGZvciB0aGUgM0QgdHJhbnNjcmlwdHMgY291bGQgbm90IGJlIHJlYWQnLCBlcnIpO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0pO1xuICAgICAgLy8gQSBuZXdlciBkcmF3IChhbm90aGVyIHN0eWxlLCBvciB0aGUgbGF5ZXIgdGFrZW4gZG93bikgd29uIHdoaWxlIHRoZSBjb2x1bW4gbG9hZGVkLlxuICAgICAgaWYgKHRoaXMubG9hZGVkICE9PSBsb2FkZWQpIHJldHVybjtcbiAgICAgIGlmIChieSA9PT0gJ2NlbGxUeXBlJykge1xuICAgICAgICBjb2xvcnMgPSBwYWNrZWQoY291bnQsIChpKSA9PiB7XG4gICAgICAgICAgY29uc3QgbyA9IGNlbGxzW2ldO1xuICAgICAgICAgIGNvbnN0IGNvZGUgPSAhZ3JvdXBzIHx8IG8gPT09IE5PX09CU0VSVkFUSU9OID8gTk9fQ0FURUdPUlkgOiBncm91cHMuY29kZXNbb107XG4gICAgICAgICAgcmV0dXJuIGNvZGUgPT09IE5PX0NBVEVHT1JZID8gdW5kZWZpbmVkIDogZ3JvdXBzIS5jb2xvcnNbY29kZV07XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQSBjbHVzdGVyIG5hbWVkIGxpa2UgYSBncm91cCBvZiB0aGUgY2VsbHMnIGdyb3VwaW5nIHRha2VzIHRoYXQgZ3JvdXAncyBjb2xvdXIsIGFzIGluIDJELlxuICAgICAgICBjb25zdCBieUNsdXN0ZXIgPSBjbHVzdGVyQ29sb3JNYXAoXG4gICAgICAgICAgdmlldy50cmFuc2NyaXB0R2VuZXMsXG4gICAgICAgICAgdmlldy50cmFuc2NyaXB0R2VuZUdyb3VwcyxcbiAgICAgICAgICBncm91cHM/LmJ5TmFtZSA/PyBuZXcgTWFwKCksXG4gICAgICAgICAgREVGQVVMVF9DQVRFR09SSUNBTF9QQUxFVFRFLFxuICAgICAgICApO1xuICAgICAgICBjb25zdCB0YWJsZSA9IChuYW1lcyA/PyBbXSkubWFwKChnZW5lKSA9PiB7XG4gICAgICAgICAgY29uc3QgaGV4ID0gYnlDbHVzdGVyLmdldChjbHVzdGVyT2ZHZW5lKGdlbmUsIHZpZXcudHJhbnNjcmlwdEdlbmVHcm91cHMpKTtcbiAgICAgICAgICByZXR1cm4gaGV4ID8gcmdiYTAxKGhleCkgOiB1bmRlZmluZWQ7XG4gICAgICAgIH0pO1xuICAgICAgICBjb2xvcnMgPSBwYWNrZWQoY291bnQsIChpKSA9PiB0YWJsZVtnZW5lc1tpXV0pO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodGhpcy5sYXllcikgdGhpcy52aWV3ZXIubGF5ZXJzLnJlbW92ZSh0aGlzLmxheWVyKTtcbiAgICB0aGlzLmxheWVyID0gbnVsbDtcbiAgICB0aGlzLmRyYXduQ2VsbHMgPSBudWxsO1xuICAgIHRoaXMuZmFkZWRCeSA9IG51bGw7XG4gICAgdGhpcy5zdHlsZUtleSA9IHN0eWxlS2V5O1xuICAgIGlmICghY291bnQpIHJldHVybjtcbiAgICB0aGlzLmRyYXduQ2VsbHMgPSBVaW50MzJBcnJheS5mcm9tKGNlbGxzKTtcbiAgICB0aGlzLmxheWVyID0gdGhpcy52aWV3ZXIuYWRkUG9pbnRzM0QoRmxvYXQzMkFycmF5LmZyb20ocG9zaXRpb25zKSwgbmV3IEZsb2F0MzJBcnJheShjb3VudCksIHtcbiAgICAgIG5hbWU6ICd0cmFuc2NyaXB0cycsXG4gICAgICBzaXplLFxuICAgICAgb3BhY2l0eTogdmlldy50cmFuc2NyaXB0T3BhY2l0eSxcbiAgICAgIHNjYWxlM2Q6IFsxLCAxLCBmcmFtZS56U2NhbGVdLFxuICAgICAgY29sb3JzLFxuICAgIH0pO1xuICB9XG59XG5cbi8qKiBgd29ya2Agb3ZlciBgaXRlbXNgLCBhdCBtb3N0IGBsaW1pdGAgYXQgb25jZSwgcmVzdWx0cyBpbiBvcmRlci4gKi9cbmFzeW5jIGZ1bmN0aW9uIHBvb2xlZDxULCBSPihpdGVtczogcmVhZG9ubHkgVFtdLCBsaW1pdDogbnVtYmVyLCB3b3JrOiAoaXRlbTogVCkgPT4gUHJvbWlzZTxSPik6IFByb21pc2U8UltdPiB7XG4gIGNvbnN0IG91dCA9IG5ldyBBcnJheTxSPihpdGVtcy5sZW5ndGgpO1xuICBsZXQgbmV4dCA9IDA7XG4gIGNvbnN0IHJ1biA9IGFzeW5jICgpID0+IHtcbiAgICB3aGlsZSAobmV4dCA8IGl0ZW1zLmxlbmd0aCkge1xuICAgICAgY29uc3QgaSA9IG5leHQrKztcbiAgICAgIG91dFtpXSA9IGF3YWl0IHdvcmsoaXRlbXNbaV0pO1xuICAgIH1cbiAgfTtcbiAgYXdhaXQgUHJvbWlzZS5hbGwoQXJyYXkuZnJvbSh7IGxlbmd0aDogTWF0aC5taW4obGltaXQsIGl0ZW1zLmxlbmd0aCkgfSwgcnVuKSk7XG4gIHJldHVybiBvdXQ7XG59XG4iXX0=