@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,10 +1,15 @@
1
- import { firstValueFrom, of } from 'rxjs';
1
+ import { debounceTime, defer, distinctUntilChanged, EMPTY, firstValueFrom, map, merge, Observable, of, startWith, switchMap, tap, } from 'rxjs';
2
2
  import { isSpatialOmics3d } from '../contracts/plot-type';
3
3
  import { isCategoricalColumn, } from '../contracts/spatial-dataset.contract';
4
4
  import { categoryColorsFor } from './spatial-encoding';
5
5
  import { sectionsOf } from './spatial-sections';
6
6
  import { observationsInSlice, volumeImageRef } from './spatial-volume-image';
7
- import { emptySelection, selectByCategory, selectByIndices, selectInClassVolumes, selectInRegions, selectInRegionsProjected, } from './spatial-selection';
7
+ import { inBand, observationsOnPlane } from './spatial-planes';
8
+ import { emptySelection, selectByCategory, selectByIndices, selectInClassVolumes, selectInRegions, selectInRegionsProjected, regionShapes, } from './spatial-selection';
9
+ import { describeObservations, OBSERVATION_DETAIL_COLUMNS } from './observations-in-selection';
10
+ import { cellTypeColumnFor, typicalCellDiameter } from './lod';
11
+ import { planeBand } from './spatial-planes';
12
+ import { CELL_REACH_MICRONS, cellsOfCategories, countTranscripts, tileBudget, tilesAroundCells, tilesUnderShapes, } from './transcripts-in-selection';
8
13
  /**
9
14
  * The spatial-omics controls (`ISpatialControls`) over a host's `SPATIAL_DATA_PORT`.
10
15
  *
@@ -39,6 +44,16 @@ export class SpatialControlsFacade {
39
44
  const by = current.colorBy;
40
45
  if (by && !canColorBy(dataset, by))
41
46
  ctx.store.setSpatialView({ colorBy: null });
47
+ // One colouring for the markers and the cells: a segmented dataset's markers start in the
48
+ // cells' groups, not a flat colour beside them.
49
+ const view = ctx.store.currentSpatialView();
50
+ const group = dataset ? cellTypeColumnFor(dataset, view) : null;
51
+ if (!view.colorBy &&
52
+ group &&
53
+ view.cellColorMode === 'group' &&
54
+ (dataset?.polygonTiles || dataset?.polygons)) {
55
+ ctx.store.setSpatialView({ colorBy: { kind: 'column', name: group } });
56
+ }
42
57
  // The gene filter names the old dataset's genes: kept, it could hide every observation.
43
58
  if (current.observationGenes?.length)
44
59
  ctx.store.setSpatialView({ observationGenes: [] });
@@ -69,6 +84,270 @@ export class SpatialControlsFacade {
69
84
  this.ctx.napari.regionVoxelStep() !== null;
70
85
  return eligible ? 'class-volumes' : 'regions';
71
86
  }
87
+ /**
88
+ * The selections the "in selection" lists follow, as they change: the latest of three, as the user
89
+ * made them — the selected cells (a cell clicked, a legend group, a brush), the classes picked in
90
+ * the region editor (in spatial 3D the cell types of the type surfaces), or the regions selected on
91
+ * the image (2D only). Clearing the latest goes back to the one before, when it still stands. Emits
92
+ * (debounced) the sources standing, latest last, whenever the selection, the regions, the plane
93
+ * shown, the plot type, the dataset or `viewKey` of the view state change.
94
+ */
95
+ selectionChanges$(viewKey) {
96
+ const { ctx } = this;
97
+ return defer(() => {
98
+ let active = [];
99
+ const track = (source, on) => {
100
+ active = active.filter((s) => s !== source);
101
+ if (on)
102
+ active.push(source);
103
+ };
104
+ return merge(
105
+ // On subscribing, the three come in this order: of those standing, the cells come last
106
+ // (the most specific).
107
+ ctx.regionStore.getSelectedShapeIndices$().pipe(tap((i) => track('regions', i.length > 0))), ctx.regionStore.getPickedClasses$().pipe(tap((c) => track('types', c.length > 0))), ctx.selectionStore.getSelection$().pipe(tap((sel) => track('cells', sel.count > 0))), ctx.regionStore.getRegionUpdateEvent(), ctx.viewChanged$ ?? EMPTY, ctx.store.getSpatialView$().pipe(map(viewKey), distinctUntilChanged()), this.port.getDataset$()).pipe(debounceTime(150), map(() => active.slice()));
108
+ });
109
+ }
110
+ /**
111
+ * `work` as a stream: what it reports through `progress`, then its answer (or `failed`'s message);
112
+ * unsubscribing abandons it (`cancelled()` then says so).
113
+ */
114
+ runCancellable(work, failed) {
115
+ return new Observable((sub) => {
116
+ let cancelled = false;
117
+ work((state) => {
118
+ if (!cancelled)
119
+ sub.next(state);
120
+ }, () => cancelled)
121
+ .then((state) => {
122
+ if (cancelled)
123
+ return;
124
+ sub.next(state);
125
+ sub.complete();
126
+ })
127
+ .catch((err) => {
128
+ if (cancelled)
129
+ return;
130
+ sub.next(failed(String(err?.message ?? err)));
131
+ sub.complete();
132
+ });
133
+ return () => {
134
+ cancelled = true;
135
+ };
136
+ });
137
+ }
138
+ /**
139
+ * What the latest selection in `active` is (see {@link selectionChanges$}), and where it applies:
140
+ * through the whole volume in spatial 3D; on the plane shown in 2D when the dataset's planes slice
141
+ * it and what is listed carries z (`hasZ`). `what` names what is listed, for the hints.
142
+ */
143
+ async resolveSelection(dataset, active, hasZ, what) {
144
+ const is3d = isSpatialOmics3d(this.ctx.plotType());
145
+ const planes = !is3d && hasZ ? (this.ctx.slicePlanes?.() ?? null) : null;
146
+ const sliced = planes && planes.length > 1 ? planes : null;
147
+ const k = sliced ? Math.max(0, Math.min(sliced.length - 1, this.ctx.zIndex())) : 0;
148
+ const where = {
149
+ is3d,
150
+ planes: sliced,
151
+ plane: sliced ? { index: k, count: sliced.length } : null,
152
+ band: sliced ? planeBand(sliced, k) : null,
153
+ };
154
+ // Drawn regions are image shapes: they select on the image, in 2D.
155
+ const eligible = active.filter((s) => !is3d || s !== 'regions');
156
+ const source = eligible[eligible.length - 1] ?? null;
157
+ if (!source) {
158
+ return {
159
+ kind: 'empty',
160
+ where,
161
+ message: is3d
162
+ ? `Select a cell, or pick a cell type, to list the ${what} in it.`
163
+ : `Select a cell or a region${sliced ? ' on this plane' : ''} to list the ${what} in it.`,
164
+ };
165
+ }
166
+ const obs = dataset.observations;
167
+ if (source === 'cells') {
168
+ const sel = this.ctx.selectionStore.current();
169
+ if (sel.count) {
170
+ const first = sel.count === 1 ? sel.mask.indexOf(1) : -1;
171
+ const name = first >= 0 ? (obs.ids?.[first] ?? String(first)) : null;
172
+ return {
173
+ kind: 'cells',
174
+ scope: 'cells',
175
+ where,
176
+ mask: sel.mask,
177
+ count: sel.count,
178
+ label: name !== null ? `Cell ${name}` : `${sel.count.toLocaleString()} selected cells`,
179
+ };
180
+ }
181
+ }
182
+ if (source === 'types') {
183
+ const classes = this.ctx.regionStore.getPickedClasses();
184
+ const column = this.cellTypeColumnOf(dataset, classes);
185
+ const loaded = column ? await this.port.getColumn(column) : null;
186
+ if (loaded && isCategoricalColumn(loaded)) {
187
+ const cells = cellsOfCategories(loaded.codes, loaded.meta.categories, classes);
188
+ if (cells.count) {
189
+ const names = classes.length > 3 ? `${classes.slice(0, 3).join(', ')} +${classes.length - 3}` : classes.join(', ');
190
+ return {
191
+ kind: 'cells',
192
+ scope: 'types',
193
+ where,
194
+ ...cells,
195
+ label: `${classes.length > 1 ? 'Cell types' : 'Cell type'}: ${names}`,
196
+ };
197
+ }
198
+ }
199
+ // Picked classes that are no cell type: in 2D, the regions of those classes on the plane.
200
+ if (is3d) {
201
+ return {
202
+ kind: 'empty',
203
+ where,
204
+ message: `The picked classes are not cell types of this dataset: select a cell to list its ${what}.`,
205
+ };
206
+ }
207
+ }
208
+ const all = this.ctx.regionStore.getRegions();
209
+ let regions;
210
+ let label;
211
+ if (source === 'types') {
212
+ const classes = new Set(this.ctx.regionStore.getPickedClasses());
213
+ regions = all.filter((r) => !!r.label && classes.has(r.label));
214
+ label = `Class: ${[...classes].join(', ')}`;
215
+ }
216
+ else {
217
+ regions = this.ctx.regionStore
218
+ .getSelectedShapeIndices()
219
+ .map((i) => all[i])
220
+ .filter((r) => !!r);
221
+ label = `${regions.length} selected region${regions.length === 1 ? '' : 's'}`;
222
+ }
223
+ const shapes = regions.flatMap((r) => regionShapes(r));
224
+ if (!shapes.length) {
225
+ return {
226
+ kind: 'empty',
227
+ where,
228
+ message: source === 'types'
229
+ ? `No region of those classes${sliced ? ' on this plane' : ''}.`
230
+ : 'The selected regions enclose no area.',
231
+ };
232
+ }
233
+ const imageRef = dataset.volume && !dataset.imageRef
234
+ ? volumeImageRef(dataset.volume, dataset.micronsPerUnit)
235
+ : dataset.imageRef;
236
+ return { kind: 'shapes', scope: 'regions', where, label, regions, shapes, imageRef };
237
+ }
238
+ /** The transcripts of the selection, by gene (see {@link selectionChanges$}). */
239
+ transcriptsInSelection$() {
240
+ return this.selectionChanges$((v) => `${v.transcriptQuality}|${v.cellTypeColumn ?? ''}`).pipe(switchMap((active) => this.runCancellable((progress, cancelled) => this.transcriptsOf(active, progress, cancelled), (message) => ({ state: 'error', message: `The transcripts could not be counted: ${message}` }))));
241
+ }
242
+ /**
243
+ * Count the transcripts of the latest selection in `active`: through the whole volume in spatial
244
+ * 3D, on the plane shown in 2D when the dataset's planes slice it.
245
+ */
246
+ async transcriptsOf(active, progress, cancelled) {
247
+ const dataset = this.dataset;
248
+ const meta = dataset?.transcriptTiles;
249
+ if (!dataset || !meta)
250
+ return { state: 'empty', message: 'This dataset has no transcripts.' };
251
+ const target = await this.resolveSelection(dataset, active, meta.hasZ, 'transcripts');
252
+ if (cancelled())
253
+ return { state: 'loading' };
254
+ const { plane, band } = target.where;
255
+ if (target.kind === 'empty')
256
+ return { state: 'empty', plane, message: target.message };
257
+ const quality = this.ctx.store.currentSpatialView().transcriptQuality === 'all' ? 'all' : 'high';
258
+ const budget = tileBudget(meta);
259
+ const filter = target.kind === 'cells'
260
+ ? { kind: 'cells', mask: target.mask }
261
+ : { kind: 'shapes', shapes: target.shapes, imageRef: target.imageRef };
262
+ const tiles = target.kind === 'cells'
263
+ ? tilesAroundCells(dataset.observations, target.mask, this.cellReach(dataset), meta.levels, meta.bounds, budget)
264
+ : tilesUnderShapes(target.shapes, target.imageRef, meta.levels, meta.bounds, budget);
265
+ const { scope, label } = target;
266
+ progress({ state: 'loading', scope, label, plane });
267
+ const count = await countTranscripts({
268
+ port: this.port,
269
+ tiles: tiles.tiles,
270
+ quality,
271
+ filter,
272
+ band,
273
+ names: meta.genes ?? null,
274
+ cancelled,
275
+ partial: tiles.partial,
276
+ });
277
+ if (!count)
278
+ return { state: 'loading' };
279
+ return { state: 'ready', scope, label, plane, ...count };
280
+ }
281
+ /** The observations of the selection, by group (see {@link selectionChanges$}). */
282
+ observationsInSelection$() {
283
+ return this.selectionChanges$((v) => {
284
+ const by = v.colorBy?.kind === 'column' ? v.colorBy.name : '';
285
+ return `${by}|${v.cellTypeColumn ?? ''}|${JSON.stringify(v.groupColors ?? {})}`;
286
+ }).pipe(switchMap((active) => this.runCancellable((progress, cancelled) => this.observationsOf(active, progress, cancelled), (message) => ({ state: 'error', message: `The observations could not be listed: ${message}` }))));
287
+ }
288
+ /**
289
+ * The observations of the latest selection in `active`, by the grouping the observations are
290
+ * coloured by (else the cell types): every one in spatial 3D; in 2D, those on the plane shown when
291
+ * the dataset's planes slice it. One cell is described too: its id and its values.
292
+ */
293
+ async observationsOf(active, progress, cancelled) {
294
+ const dataset = this.dataset;
295
+ if (!dataset)
296
+ return { state: 'empty', message: 'No dataset is loaded.' };
297
+ const obs = dataset.observations;
298
+ const target = await this.resolveSelection(dataset, active, !!obs.z, 'observations');
299
+ if (cancelled())
300
+ return { state: 'loading' };
301
+ const { plane, band, planes } = target.where;
302
+ if (target.kind === 'empty')
303
+ return { state: 'empty', plane, message: target.message };
304
+ const { scope, label } = target;
305
+ progress({ state: 'loading', scope, label, plane });
306
+ let mask;
307
+ if (target.kind === 'cells') {
308
+ mask = target.mask;
309
+ if (band && obs.z) {
310
+ // On the plane shown: the cells the 2D view draws there.
311
+ const z = obs.z;
312
+ mask = Uint8Array.from(target.mask, (m, i) => (m && inBand(z[i], band) ? 1 : 0));
313
+ }
314
+ }
315
+ else {
316
+ const volume = !dataset.imageRef ? dataset.volume : undefined;
317
+ const k = target.where.plane?.index ?? this.ctx.zIndex();
318
+ mask = selectInRegions(obs, target.imageRef, target.regions, volume
319
+ ? observationsInSlice(obs, volume, this.ctx.zIndex())
320
+ : planes
321
+ ? observationsOnPlane(obs, planes, k)
322
+ : undefined).mask;
323
+ }
324
+ const view = this.ctx.store.currentSpatialView();
325
+ const listed = await describeObservations(this.port, dataset, view, mask, OBSERVATION_DETAIL_COLUMNS);
326
+ if (cancelled())
327
+ return { state: 'loading' };
328
+ return { state: 'ready', scope, label, plane, ...listed };
329
+ }
330
+ /**
331
+ * The categorical column the picked classes are cell types of: the dataset's cell-type column
332
+ * when it holds any of them, else the first categorical column that does; null when none does.
333
+ */
334
+ cellTypeColumnOf(dataset, classes) {
335
+ if (!classes.length)
336
+ return null;
337
+ const categorical = dataset.columns.filter((c) => c.kind === 'categorical');
338
+ const holds = (c) => classes.some((name) => c.categories.includes(name));
339
+ const preferred = cellTypeColumnFor(dataset, this.ctx.store.currentSpatialView());
340
+ const first = categorical.find((c) => c.name === preferred && holds(c)) ?? categorical.find(holds);
341
+ return first?.name ?? null;
342
+ }
343
+ /** How far from a cell's centre its transcripts are looked for, in observation units. */
344
+ cellReach(dataset) {
345
+ const ref = dataset.imageRef;
346
+ const micronsPerUnit = dataset.micronsPerUnit ?? (ref?.mppX ? ref.mppX * (ref.scale?.[0] ?? 1) : undefined);
347
+ if (micronsPerUnit && micronsPerUnit > 0)
348
+ return CELL_REACH_MICRONS / micronsPerUnit;
349
+ return typicalCellDiameter(dataset.observations.radius) * 3;
350
+ }
72
351
  build() {
73
352
  const port = this.port;
74
353
  return {
@@ -120,6 +399,14 @@ export class SpatialControlsFacade {
120
399
  getGeneCountsInView$: () => this.ctx.napari.geneCountsInView$.asObservable(),
121
400
  getDensityStats$: () => this.ctx.napari.densityStats$.asObservable(),
122
401
  getGeneFilterFailed$: () => this.ctx.napari.geneFilterFailed$?.asObservable() ?? of(false),
402
+ getCells3dStatus$: () => this.ctx.napari.cells3dStatus$?.asObservable() ?? of(null),
403
+ ...(this.ctx.viewChanged$ && this.ctx.slicePlanes
404
+ ? {
405
+ getCells3dAvailable$: () => this.ctx.viewChanged$.pipe(startWith(null), map(() => !!this.ctx.slicePlanes?.()?.length), distinctUntilChanged()),
406
+ }
407
+ : {}),
408
+ ...(port.getTranscriptTile ? { getTranscriptsInSelection$: () => this.transcriptsInSelection$() } : {}),
409
+ getObservationsInSelection$: () => this.observationsInSelection$(),
123
410
  categoryColors: async (name) => {
124
411
  const column = await port.getColumn(name);
125
412
  if (!isCategoricalColumn(column)) {
@@ -211,8 +498,14 @@ export class SpatialControlsFacade {
211
498
  else {
212
499
  // In the 2D view of a volume-backed dataset the shape was drawn over ONE
213
500
  // section, in the volume's pixel grid: it selects the cells of that
214
- // section, not the whole depth of brain standing behind them.
215
- selection = selectInRegions(dataset.observations, volume ? volumeImageRef(volume, dataset.micronsPerUnit) : dataset.imageRef, this.ctx.regionStore.getRegions(), volume ? observationsInSlice(dataset.observations, volume, this.ctx.zIndex()) : undefined);
501
+ // section, not the whole depth of brain standing behind them. Likewise over
502
+ // one of a region set's planes: the cells nearest it.
503
+ const planes = !volume ? this.ctx.planes?.() : null;
504
+ selection = selectInRegions(dataset.observations, volume ? volumeImageRef(volume, dataset.micronsPerUnit) : dataset.imageRef, this.ctx.regionStore.getRegions(), volume
505
+ ? observationsInSlice(dataset.observations, volume, this.ctx.zIndex())
506
+ : planes
507
+ ? observationsOnPlane(dataset.observations, planes, this.ctx.zIndex())
508
+ : undefined);
216
509
  }
217
510
  this.ctx.selectionStore.set(selection);
218
511
  return selection.count;
@@ -255,4 +548,4 @@ function canColorBy(dataset, by) {
255
548
  const names = dataset.features?.names;
256
549
  return !!dataset.features && (!names || names.includes(by.name));
257
550
  }
258
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhdGlhbC1jb250cm9scy5mYWNhZGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3NwYXRpYWwvc3BhdGlhbC1jb250cm9scy5mYWNhZGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGNBQWMsRUFBYyxFQUFFLEVBQWdCLE1BQU0sTUFBTSxDQUFDO0FBRXBFLE9BQU8sRUFBWSxnQkFBZ0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBR3BFLE9BQU8sRUFJTCxtQkFBbUIsR0FDcEIsTUFBTSx1Q0FBdUMsQ0FBQztBQUsvQyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDaEQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLGNBQWMsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzdFLE9BQU8sRUFDTCxjQUFjLEVBQ2QsZ0JBQWdCLEVBQ2hCLGVBQWUsRUFDZixvQkFBb0IsRUFDcEIsZUFBZSxFQUNmLHdCQUF3QixHQUN6QixNQUFNLHFCQUFxQixDQUFDO0FBNkI3Qjs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLE9BQU8scUJBQXFCO0lBVWhDLFlBQ21CLElBQXFCLEVBQ3JCLEdBQTJCO1FBRDNCLFNBQUksR0FBSixJQUFJLENBQWlCO1FBQ3JCLFFBQUcsR0FBSCxHQUFHLENBQXdCO1FBVDlDO29GQUM0RTtRQUNwRSxZQUFPLEdBQTBCLElBQUksQ0FBQztRQUU5Qyx1RkFBdUY7UUFDL0UsZUFBVSxHQUFHLENBQUMsQ0FBQztRQU1yQixpRkFBaUY7UUFDakYsd0VBQXdFO1FBQ3hFLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQ2xELE1BQU0sT0FBTyxHQUFHLE9BQU8sRUFBRSxFQUFFLEtBQUssSUFB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RyxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUU7U0FDdEQsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQUVEOzs7Ozs7R0FNRztBQUNILFNBQVMsVUFBVSxDQUFDLE9BQThCLEVBQUUsRUFBa0I7SUFDcEUsSUFBSSxDQUFDLE9BQU87UUFBRSxPQUFPLEtBQUssQ0FBQztJQUMzQixJQUFJLEVBQUUsQ0FBQyxJQUFJLEtBQUssUUFBUTtRQUFFLE9BQU8sT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2pGLE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDO0lBQ3RDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxRQUFRLElBQUksQ0FBQyxDQUFDLEtBQUssSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ25FLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBmaXJzdFZhbHVlRnJvbSwgT2JzZXJ2YWJsZSwgb2YsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBQbG90VHlwZSwgaXNTcGF0aWFsT21pY3MzZCB9IGZyb20gJy4uL2NvbnRyYWN0cy9wbG90LXR5cGUnO1xuaW1wb3J0IHsgU3BhdGlhbERhdGFQb3J0IH0gZnJvbSAnLi4vY29udHJhY3RzL3BvcnRzL3NwYXRpYWwtZGF0YS5wb3J0JztcbmltcG9ydCB7IFNwYXRpYWxDb2xvckJ5IH0gZnJvbSAnLi4vY29udHJhY3RzL2Rpc3BsYXktdHlwZXMnO1xuaW1wb3J0IHtcbiAgU3BhdGlhbERhdGFzZXQsXG4gIFNwYXRpYWxPYnNlcnZhdGlvbnMsXG4gIFNwYXRpYWxTZWxlY3Rpb25NYXNrLFxuICBpc0NhdGVnb3JpY2FsQ29sdW1uLFxufSBmcm9tICcuLi9jb250cmFjdHMvc3BhdGlhbC1kYXRhc2V0LmNvbnRyYWN0JztcbmltcG9ydCB7IElTcGF0aWFsQ29udHJvbHMsIFJvaVNlbGVjdGlvbk1vZGUgfSBmcm9tICcuLi9jb250cmFjdHMvdmlzdWFsaXplci5jb250cmFjdCc7XG5pbXBvcnQgeyBSZWdpb25TdG9yZSB9IGZyb20gJy4uL3N0b3JlL3JlZ2lvbi1zdG9yZS5zZXJ2aWNlJztcbmltcG9ydCB7IFNwYXRpYWxTZWxlY3Rpb25TdG9yZSB9IGZyb20gJy4uL3N0b3JlL3NwYXRpYWwtc2VsZWN0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHsgVmlzdWFsaXplclN0b3JlIH0gZnJvbSAnLi4vc3RvcmUvdmlzdWFsaXplci1zdG9yZS5zZXJ2aWNlJztcbmltcG9ydCB7IGNhdGVnb3J5Q29sb3JzRm9yIH0gZnJvbSAnLi9zcGF0aWFsLWVuY29kaW5nJztcbmltcG9ydCB7IHNlY3Rpb25zT2YgfSBmcm9tICcuL3NwYXRpYWwtc2VjdGlvbnMnO1xuaW1wb3J0IHsgb2JzZXJ2YXRpb25zSW5TbGljZSwgdm9sdW1lSW1hZ2VSZWYgfSBmcm9tICcuL3NwYXRpYWwtdm9sdW1lLWltYWdlJztcbmltcG9ydCB7XG4gIGVtcHR5U2VsZWN0aW9uLFxuICBzZWxlY3RCeUNhdGVnb3J5LFxuICBzZWxlY3RCeUluZGljZXMsXG4gIHNlbGVjdEluQ2xhc3NWb2x1bWVzLFxuICBzZWxlY3RJblJlZ2lvbnMsXG4gIHNlbGVjdEluUmVnaW9uc1Byb2plY3RlZCxcbn0gZnJvbSAnLi9zcGF0aWFsLXNlbGVjdGlvbic7XG5cbi8qKiBUaGUgcmVuZGVyZXItc2lkZSBzcGF0aWFsIHJlYWRvdXRzIHRoZSBjb250cm9scyBzdXJmYWNlICh0aGUgbmFwYXJpLWpzIGJhY2tlbmQpLiAqL1xuZXhwb3J0IGludGVyZmFjZSBTcGF0aWFsUmVuZGVyZXJGZWVkcyB7XG4gIHJlYWRvbmx5IHRyYW5zY3JpcHRFc3RpbWF0ZSQ6IHsgYXNPYnNlcnZhYmxlKCk6IE9ic2VydmFibGU8eyBwb2ludHM6IG51bWJlcjsgbWF4OiBudW1iZXIgfSB8IG51bGw+IH07XG4gIHJlYWRvbmx5IGdlbmVDb3VudHNJblZpZXckOiB7IGFzT2JzZXJ2YWJsZSgpOiBPYnNlcnZhYmxlPFJlY29yZDxzdHJpbmcsIG51bWJlcj4gfCBudWxsPiB9O1xuICByZWFkb25seSBkZW5zaXR5U3RhdHMkOiB7IGFzT2JzZXJ2YWJsZSgpOiBPYnNlcnZhYmxlPHsgbG86IG51bWJlcjsgaGk6IG51bWJlcjsgbWF4OiBudW1iZXIgfSB8IG51bGw+IH07XG4gIHJlYWRvbmx5IGdlbmVGaWx0ZXJGYWlsZWQkPzogeyBhc09ic2VydmFibGUoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB9O1xuICAvKiogT2JzZXJ2YXRpb25zIHByb2plY3RlZCB0byBjYW52YXMgcGl4ZWxzIGJ5IHRoZSAzRCBjYW1lcmEsIG9yIG51bGwgd2hlbiB0aGUgY2xvdWQgaXMgbm90IG1vdW50ZWQuICovXG4gIGdldFNwYXRpYWxTY3JlZW5Qcm9qZWN0aW9uKG9iczogU3BhdGlhbE9ic2VydmF0aW9ucyk6IEZsb2F0MzJBcnJheSB8IG51bGw7XG4gIC8qKiBUaGUgaWRzIG9mIHRoZSByZWdpb25zIGRyYXduIG92ZXIgdGhlIDNEIGNsb3VkIGluIHNjcmVlbiBzcGFjZSAoaXRzIGxhc3NvcykuICovXG4gIGdldFNwYXRpYWxMYXNzb0lkcygpOiBudW1iZXJbXTtcbiAgLyoqIEltYWdlIHB4IHBlciB2b3hlbCBvZiB0aGUgdm9sdW1lIHRoZSByZWdpb24gc3VyZmFjZXMgc2l0IGluOyBudWxsIHdoZW4gdGhlIHBsb3R0ZWQgaW1hZ2UgaXNcbiAgICogIG5vdCBhIHZvbHVtZSdzIHN0YWNrICh0aGUgcmVnaW9ucyBhcmUgdGhlbiBub3QgaW4gdGhlIHJlZmVyZW5jZSB2b2x1bWUncyBncmlkKS4gKi9cbiAgcmVnaW9uVm94ZWxTdGVwKCk6IG51bWJlciB8IG51bGw7XG59XG5cbi8qKiBXaGF0IHRoZSBmYWNhZGUgd29ya3Mgb3ZlcjogdGhlIHNoYXJlZCBzdG9yZXMsIHRoZSByZW5kZXJlciBmZWVkcyBhbmQgdGhlIHJvdXRlcidzIHZpZXcgc3RhdGUuICovXG5leHBvcnQgaW50ZXJmYWNlIFNwYXRpYWxDb250cm9sc0NvbnRleHQge1xuICByZWFkb25seSBzdG9yZTogVmlzdWFsaXplclN0b3JlO1xuICByZWFkb25seSByZWdpb25TdG9yZTogUmVnaW9uU3RvcmU7XG4gIHJlYWRvbmx5IHNlbGVjdGlvblN0b3JlOiBTcGF0aWFsU2VsZWN0aW9uU3RvcmU7XG4gIHJlYWRvbmx5IG5hcGFyaTogU3BhdGlhbFJlbmRlcmVyRmVlZHM7XG4gIC8qKiBUaGUgcGxvdCB0eXBlIG9uIHNjcmVlbiAodGhlIDNEIGNsb3VkIHNlbGVjdHMgaW4gc2NyZWVuIHNwYWNlKS4gKi9cbiAgcGxvdFR5cGUoKTogUGxvdFR5cGU7XG4gIC8qKiBUaGUgZGlzcGxheWVkIHNsaWNlIChhIHZvbHVtZS1iYWNrZWQgZGF0YXNldCBzZWxlY3RzIHdpdGhpbiBvbmUgc2VjdGlvbikuICovXG4gIHpJbmRleCgpOiBudW1iZXI7XG59XG5cbi8qKlxuICogVGhlIHNwYXRpYWwtb21pY3MgY29udHJvbHMgKGBJU3BhdGlhbENvbnRyb2xzYCkgb3ZlciBhIGhvc3QncyBgU1BBVElBTF9EQVRBX1BPUlRgLlxuICpcbiAqIEJhY2tlbmQtbmV1dHJhbDogdGhlIHZpZXcgc3RhdGUgbGl2ZXMgaW4gdGhlIHNoYXJlZCBgVmlzdWFsaXplclN0b3JlYCAobGlrZSB0aGVcbiAqIGNvbG9ybWFwKSBhbmQgdGhlIHNlbGVjdGlvbiBpbiB0aGUgYFNwYXRpYWxTZWxlY3Rpb25TdG9yZWAsIHNvIHRoZSBjb250cm9scyBrZWVwXG4gKiB3b3JraW5nIGFjcm9zcyBhIHBsb3QtdHlwZSBzd2l0Y2ggYW5kIGEgaG9zdCBjYW4gZHJpdmUgdGhlbSBiZWZvcmUgYW55IGJhY2tlbmQgaGFzXG4gKiBtb3VudGVkLiBPd25zIGl0cyBtaXJyb3Igb2YgdGhlIHBvcnQncyBkYXRhc2V0IOKAlCBkcm9wcGluZyBhIHN0YWxlIHNlbGVjdGlvbiBhbmQgYW5cbiAqIHVuc2F0aXNmaWFibGUgY29sb3VyIHNvdXJjZSB3aGVuIHRoZSBkYXRhc2V0IGNoYW5nZXMg4oCUIGFuZCB0aGUgc3Vic2NyaXB0aW9uIGJlaGluZFxuICogaXQsIHJlbGVhc2VkIGJ5IHtAbGluayBkaXNwb3NlfSAocmV2aWV3IENPUkUtMzApLlxuICovXG5leHBvcnQgY2xhc3MgU3BhdGlhbENvbnRyb2xzRmFjYWRlIHtcbiAgLyoqIFRoZSBjb250cm9sczsgb25lIG9iamVjdCBmb3IgdGhlIGZhY2FkZSdzIGxpZmUsIHNvIGNvbnN1bWVycyBjYW4gaG9sZCBpdC4gKi9cbiAgcmVhZG9ubHkgY29udHJvbHM6IElTcGF0aWFsQ29udHJvbHM7XG4gIC8qKiBMYXRlc3QgZGF0YXNldCwgbWlycm9yZWQgc28gYHNlbGVjdEZyb21SZWdpb25zKClgIGFuc3dlcnMgZnJvbSB0aGUgZGF0YXNldCBvblxuICAgKiAgc2NyZWVuIOKAlCBpdCBydW5zIGZyb20gYSBidXR0b24gY2xpY2sgYW5kIG11c3Qgbm90IGF3YWl0IGEgcm91bmQtdHJpcC4gKi9cbiAgcHJpdmF0ZSBkYXRhc2V0OiBTcGF0aWFsRGF0YXNldCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHJlYWRvbmx5IHN1YjogU3Vic2NyaXB0aW9uO1xuICAvKiogQnVtcGVkIHBlciBjbGFzcy12b2x1bWUgc2VsZWN0aW9uIChhbmQgb24gZGlzcG9zZSk6IG9ubHkgdGhlIGxhdGVzdCBtYXkgcHVibGlzaC4gKi9cbiAgcHJpdmF0ZSByb2lSZXF1ZXN0ID0gMDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IHBvcnQ6IFNwYXRpYWxEYXRhUG9ydCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGN0eDogU3BhdGlhbENvbnRyb2xzQ29udGV4dCxcbiAgKSB7XG4gICAgLy8gTWlycm9yIHRoZSBkYXRhc2V0IChhbmQgZHJvcCBhIHN0YWxlIHNlbGVjdGlvbiB3aGVuIGl0IGNoYW5nZXMg4oCUIHRoZSBtYXNrcyBhcmVcbiAgICAvLyBpbmRleC1iYXNlZCwgc28gdGhleSBhcmUgbWVhbmluZ2xlc3MgYWdhaW5zdCBkaWZmZXJlbnQgb2JzZXJ2YXRpb25zKS5cbiAgICB0aGlzLnN1YiA9IHBvcnQuZ2V0RGF0YXNldCQoKS5zdWJzY3JpYmUoKGRhdGFzZXQpID0+IHtcbiAgICAgIGNvbnN0IGNoYW5nZWQgPSBkYXRhc2V0Py5pZCAhPT0gdGhpcy5kYXRhc2V0Py5pZDtcbiAgICAgIHRoaXMuZGF0YXNldCA9IGRhdGFzZXQ7XG4gICAgICBpZiAoIWNoYW5nZWQpIHJldHVybjtcbiAgICAgIGN0eC5zZWxlY3Rpb25TdG9yZS5zZXQoZW1wdHlTZWxlY3Rpb24oZGF0YXNldD8ub2JzZXJ2YXRpb25zLmNvdW50ID8/IDApKTtcbiAgICAgIC8vIEEgY29sb3VyIHNvdXJjZSB0aGUgbmV3IGRhdGFzZXQgY2Fubm90IHNhdGlzZnkgd291bGQgbGVhdmUgdGhlIG1hcCBmbGF0IHdoaWxlXG4gICAgICAvLyB0aGUgcGFuZWwgYW5kIHRoZSBjaGFydHMga2VwdCBuYW1pbmcgdGhlIG9sZCBjb2x1bW4g4oCUIHNvIGRyb3AgaXQsIGFuZCBvbmx5IGl0OlxuICAgICAgLy8gcG9pbnQgc2l6ZSwgb3BhY2l0eSBhbmQgdGhlIHJlc3QgYXJlIHRoZSB1c2VyJ3MgcHJlZmVyZW5jZXMuXG4gICAgICBjb25zdCBjdXJyZW50ID0gY3R4LnN0b3JlLmN1cnJlbnRTcGF0aWFsVmlldygpO1xuICAgICAgY29uc3QgYnkgPSBjdXJyZW50LmNvbG9yQnk7XG4gICAgICBpZiAoYnkgJiYgIWNhbkNvbG9yQnkoZGF0YXNldCwgYnkpKSBjdHguc3RvcmUuc2V0U3BhdGlhbFZpZXcoeyBjb2xvckJ5OiBudWxsIH0pO1xuICAgICAgLy8gVGhlIGdlbmUgZmlsdGVyIG5hbWVzIHRoZSBvbGQgZGF0YXNldCdzIGdlbmVzOiBrZXB0LCBpdCBjb3VsZCBoaWRlIGV2ZXJ5IG9ic2VydmF0aW9uLlxuICAgICAgaWYgKGN1cnJlbnQub2JzZXJ2YXRpb25HZW5lcz8ubGVuZ3RoKSBjdHguc3RvcmUuc2V0U3BhdGlhbFZpZXcoeyBvYnNlcnZhdGlvbkdlbmVzOiBbXSB9KTtcbiAgICAgIC8vIEdyb3VwIGNvbG91cnMgYXJlIGNob3NlbiBmb3IgdGhpcyBkYXRhc2V0J3MgZ3JvdXBpbmdzOyBhbm90aGVyJ3Mgc2FtZS1uYW1lZCBjb2x1bW4gaXMgbm90IHRoZW0uXG4gICAgICBpZiAoT2JqZWN0LmtleXMoY3VycmVudC5ncm91cENvbG9ycyA/PyB7fSkubGVuZ3RoKSBjdHguc3RvcmUuc2V0U3BhdGlhbFZpZXcoeyBncm91cENvbG9yczoge30gfSk7XG4gICAgfSk7XG4gICAgdGhpcy5jb250cm9scyA9IHRoaXMuYnVpbGQoKTtcbiAgfVxuXG4gIC8qKiBSZWxlYXNlIHRoZSBwb3J0IHN1YnNjcmlwdGlvbiAodGhlIHJvdXRlcidzIGluamVjdG9yIGlzIGJlaW5nIGRlc3Ryb3llZCkuICovXG4gIGRpc3Bvc2UoKTogdm9pZCB7XG4gICAgdGhpcy5zdWIudW5zdWJzY3JpYmUoKTtcbiAgICAvLyBBIGNsYXNzLXZvbHVtZSBzZWxlY3Rpb24gc3RpbGwgcmVhZGluZyBpdHMgb3V0bGluZXMgcHVibGlzaGVzIG5vdGhpbmcuXG4gICAgdGhpcy5yb2lSZXF1ZXN0Kys7XG4gIH1cblxuICAvKipcbiAgICogSG93IFwiU2VsZWN0IGZyb20gUk9Jc1wiIHNlbGVjdHMgbm93IOKAlCB0aGUgb25lIHJ1bGUgaXRzIGV4ZWN1dG9yIGFuZCB0aGUgcGFuZWwncyBkZXNjcmlwdGlvblxuICAgKiBzaGFyZTogaW5zaWRlIHRoZSBwaWNrZWQgY2xhc3Nlcycgdm9sdW1lcyBpbiB0aGUgM0QgY2xvdWQsIHdoZW4gdGhlIGRhdGFzZXQgaGFzIGEgcmVmZXJlbmNlXG4gICAqIHZvbHVtZSAoYW5kIG5vIHRpc3N1ZSBpbWFnZSkgYW5kIHRoZSBwbG90dGVkIGltYWdlIGlzIHRoYXQgdm9sdW1lJ3Mgc3RhY2ssIHNvIHRoZSByZWdpb25zIHNpdFxuICAgKiBpbiBpdHMgZ3JpZDsgYnkgdGhlIGRyYXduIHJlZ2lvbnMgb3RoZXJ3aXNlLlxuICAgKi9cbiAgcHJpdmF0ZSByb2lTZWxlY3Rpb25Nb2RlKCk6IFJvaVNlbGVjdGlvbk1vZGUge1xuICAgIGNvbnN0IGRhdGFzZXQgPSB0aGlzLmRhdGFzZXQ7XG4gICAgY29uc3QgZWxpZ2libGUgPVxuICAgICAgISFkYXRhc2V0Py52b2x1bWUgJiZcbiAgICAgICFkYXRhc2V0LmltYWdlUmVmICYmXG4gICAgICBpc1NwYXRpYWxPbWljczNkKHRoaXMuY3R4LnBsb3RUeXBlKCkpICYmXG4gICAgICB0aGlzLmN0eC5yZWdpb25TdG9yZS5nZXRQaWNrZWRDbGFzc2VzKCkubGVuZ3RoID4gMCAmJlxuICAgICAgdGhpcy5jdHgubmFwYXJpLnJlZ2lvblZveGVsU3RlcCgpICE9PSBudWxsO1xuICAgIHJldHVybiBlbGlnaWJsZSA/ICdjbGFzcy12b2x1bWVzJyA6ICdyZWdpb25zJztcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGQoKTogSVNwYXRpYWxDb250cm9scyB7XG4gICAgY29uc3QgcG9ydCA9IHRoaXMucG9ydDtcbiAgICByZXR1cm4ge1xuICAgICAgZ2V0RGF0YXNldCQ6ICgpID0+IHBvcnQuZ2V0RGF0YXNldCQoKSxcbiAgICAgIGdldFZpZXdTdGF0ZSQ6ICgpID0+IHRoaXMuY3R4LnN0b3JlLmdldFNwYXRpYWxWaWV3JCgpLFxuICAgICAgdmlld1N0YXRlOiAoKSA9PiB0aGlzLmN0eC5zdG9yZS5jdXJyZW50U3BhdGlhbFZpZXcoKSxcbiAgICAgIHNldFZpZXdTdGF0ZTogKHBhcnRpYWwpID0+IHRoaXMuY3R4LnN0b3JlLnNldFNwYXRpYWxWaWV3KHBhcnRpYWwpLFxuICAgICAgLy8gVGhlIGhpbnQgU0VFRFMgdGhlIHRvZ2dsZSB3aGVuIHRoZSBzb3VyY2UgY2hhbmdlcywgYW5kIG5vdGhpbmcgY29uc3VsdHMgaXRcbiAgICAgIC8vIGFmdGVyd2FyZHMuIEl0IHVzZWQgdG8gYmUgT1JlZCBpbiBhdCByZW5kZXIgdGltZSwgd2hpY2ggbWVhbnQgYW4gdW5jaGVja2VkXG4gICAgICAvLyBib3ggY291bGQgbm90IHR1cm4gbG9nIHNjYWxpbmcgb2ZmIGZvciBhIGhpbnRlZCBjb2x1bW4g4oCUIGFuZCB0aGUgbGlua2VkXG4gICAgICAvLyBjaGFydCwgd2hpY2ggcmVhZHMgYGxvZ1NjYWxlYCBhbG9uZSwgZGlzYWdyZWVkIHdpdGggdGhlIG1hcCBhYm91dCB3aGF0IGl0XG4gICAgICAvLyB3YXMgc2hvd2luZy4gT25lIGF1dGhvcml0eSwgc2V0IG9uY2UgcGVyIHNvdXJjZS5cbiAgICAgIGNvbG9yQnlDb2x1bW46IChuYW1lOiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3QgbWV0YSA9IHRoaXMuZGF0YXNldD8uY29sdW1ucy5maW5kKChjKSA9PiBjLm5hbWUgPT09IG5hbWUpO1xuICAgICAgICBjb25zdCBoaW50ID0gbWV0YT8ua2luZCA9PT0gJ2NvbnRpbnVvdXMnID8gISFtZXRhLmxvZ1NjYWxlSGludCA6IGZhbHNlO1xuICAgICAgICB0aGlzLmN0eC5zdG9yZS5zZXRTcGF0aWFsVmlldyh7IGNvbG9yQnk6IHsga2luZDogJ2NvbHVtbicsIG5hbWUgfSwgbG9nU2NhbGU6IGhpbnQgfSk7XG4gICAgICB9LFxuICAgICAgY29sb3JCeUZlYXR1cmU6IChuYW1lOiBzdHJpbmcpID0+XG4gICAgICAgIHRoaXMuY3R4LnN0b3JlLnNldFNwYXRpYWxWaWV3KHtcbiAgICAgICAgICBjb2xvckJ5OiB7IGtpbmQ6ICdmZWF0dXJlJywgbmFtZSB9LFxuICAgICAgICAgIGxvZ1NjYWxlOiAhIXRoaXMuZGF0YXNldD8uZmVhdHVyZXM/LmxvZ1NjYWxlSGludCxcbiAgICAgICAgfSksXG4gICAgICBjbGVhckNvbG9yQnk6ICgpID0+IHRoaXMuY3R4LnN0b3JlLnNldFNwYXRpYWxWaWV3KHsgY29sb3JCeTogbnVsbCB9KSxcbiAgICAgIHNlYXJjaEZlYXR1cmVzOiBhc3luYyAocXVlcnk6IHN0cmluZywgbGltaXQgPSA1MCkgPT4ge1xuICAgICAgICAvLyBQcmVmZXIgdGhlIHBvcnQncyBzZWFyY2ggKGEgMzFrLWdlbmUgZGF0YXNldCBkb2VzIG5vdCBzaGlwIGl0cyBuYW1lcyk7XG4gICAgICAgIC8vIG90aGVyd2lzZSBmaWx0ZXIgd2hhdGV2ZXIgdGhlIG1hbmlmZXN0IGlubGluZWQuXG4gICAgICAgIGlmIChwb3J0LnNlYXJjaEZlYXR1cmVzKSByZXR1cm4gcG9ydC5zZWFyY2hGZWF0dXJlcyhxdWVyeSwgbGltaXQpO1xuICAgICAgICBjb25zdCBkYXRhc2V0ID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20ocG9ydC5nZXREYXRhc2V0JCgpKTtcbiAgICAgICAgY29uc3QgbmFtZXMgPSBkYXRhc2V0Py5mZWF0dXJlcz8ubmFtZXMgPz8gW107XG4gICAgICAgIGNvbnN0IHEgPSBxdWVyeS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICByZXR1cm4gbmFtZXMuZmlsdGVyKChuKSA9PiBuLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMocSkpLnNsaWNlKDAsIGxpbWl0KTtcbiAgICAgIH0sXG4gICAgICAuLi4ocG9ydC5pbXBvcnRHcm91cHNcbiAgICAgICAgPyB7XG4gICAgICAgICAgICBpbXBvcnRHcm91cHM6IChsYWJlbDogc3RyaW5nLCB0YWJsZTogc3RyaW5nKSA9PiBwb3J0LmltcG9ydEdyb3VwcyEobGFiZWwsIHRhYmxlKSxcbiAgICAgICAgICB9XG4gICAgICAgIDoge30pLFxuICAgICAgLi4uKHBvcnQuZ2V0VHJhbnNjcmlwdENvdW50c1xuICAgICAgICA/IHtcbiAgICAgICAgICAgIHRyYW5zY3JpcHRDb3VudHM6IChnZW5lczogc3RyaW5nW10pID0+IHBvcnQuZ2V0VHJhbnNjcmlwdENvdW50cyEoZ2VuZXMpLFxuICAgICAgICAgIH1cbiAgICAgICAgOiB7fSksXG4gICAgICAuLi4ocG9ydC5nZXRNYXJrZXJHZW5lc1xuICAgICAgICA/IHtcbiAgICAgICAgICAgIG1hcmtlckdlbmVzOiAoY29sdW1uOiBzdHJpbmcsIHBlckdyb3VwPzogbnVtYmVyKSA9PiBwb3J0LmdldE1hcmtlckdlbmVzIShjb2x1bW4sIHBlckdyb3VwKSxcbiAgICAgICAgICB9XG4gICAgICAgIDoge30pLFxuICAgICAgZ2V0VHJhbnNjcmlwdEVzdGltYXRlJDogKCkgPT4gdGhpcy5jdHgubmFwYXJpLnRyYW5zY3JpcHRFc3RpbWF0ZSQuYXNPYnNlcnZhYmxlKCksXG4gICAgICBnZXRHZW5lQ291bnRzSW5WaWV3JDogKCkgPT4gdGhpcy5jdHgubmFwYXJpLmdlbmVDb3VudHNJblZpZXckLmFzT2JzZXJ2YWJsZSgpLFxuICAgICAgZ2V0RGVuc2l0eVN0YXRzJDogKCkgPT4gdGhpcy5jdHgubmFwYXJpLmRlbnNpdHlTdGF0cyQuYXNPYnNlcnZhYmxlKCksXG4gICAgICBnZXRHZW5lRmlsdGVyRmFpbGVkJDogKCkgPT4gdGhpcy5jdHgubmFwYXJpLmdlbmVGaWx0ZXJGYWlsZWQkPy5hc09ic2VydmFibGUoKSA/PyBvZihmYWxzZSksXG4gICAgICBjYXRlZ29yeUNvbG9yczogYXN5bmMgKG5hbWU6IHN0cmluZykgPT4ge1xuICAgICAgICBjb25zdCBjb2x1bW4gPSBhd2FpdCBwb3J0LmdldENvbHVtbihuYW1lKTtcbiAgICAgICAgaWYgKCFpc0NhdGVnb3JpY2FsQ29sdW1uKGNvbHVtbikpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFtzcGF0aWFsXSBjb2x1bW4gXCIke25hbWV9XCIgaXMgY29udGludW91cyDigJQgaXQgaGFzIG5vIGNhdGVnb3JpZXNgKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBSZXNvbHZlZCBieSB0aGUgU0FNRSBmdW5jdGlvbiB0aGUgcmVuZGVyZXIgdXNlcywgc28gYSBsZWdlbmQgc3dhdGNoXG4gICAgICAgIC8vIGNhbiBuZXZlciBkaXNhZ3JlZSB3aXRoIHRoZSBjb2xvdXIgb24gc2NyZWVuLlxuICAgICAgICByZXR1cm4gY2F0ZWdvcnlDb2xvcnNGb3IobmFtZSwgY29sdW1uLm1ldGEsIHRoaXMuY3R4LnN0b3JlLmN1cnJlbnRTcGF0aWFsVmlldygpLmdyb3VwQ29sb3JzKTtcbiAgICAgIH0sXG5cbiAgICAgIGNvbnRpbnVvdXNWYWx1ZXM6IGFzeW5jIChzb3VyY2UpID0+IHtcbiAgICAgICAgaWYgKHNvdXJjZS5raW5kID09PSAnZmVhdHVyZScpIHJldHVybiBwb3J0LmdldEZlYXR1cmVWZWN0b3Ioc291cmNlLm5hbWUpO1xuICAgICAgICBjb25zdCBjb2x1bW4gPSBhd2FpdCBwb3J0LmdldENvbHVtbihzb3VyY2UubmFtZSk7XG4gICAgICAgIGlmIChpc0NhdGVnb3JpY2FsQ29sdW1uKGNvbHVtbikpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFtzcGF0aWFsXSBjb2x1bW4gXCIke3NvdXJjZS5uYW1lfVwiIGlzIGNhdGVnb3JpY2FsIOKAlCBpdCBoYXMgbm8gdmFsdWVzIHRvIGNoYXJ0YCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNvbHVtbi52YWx1ZXM7XG4gICAgICB9LFxuXG4gICAgICBjYXRlZ29yaWNhbFZpZXc6IGFzeW5jIChuYW1lOiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3QgY29sdW1uID0gYXdhaXQgcG9ydC5nZXRDb2x1bW4obmFtZSk7XG4gICAgICAgIGlmICghaXNDYXRlZ29yaWNhbENvbHVtbihjb2x1bW4pKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBbc3BhdGlhbF0gY29sdW1uIFwiJHtuYW1lfVwiIGlzIGNvbnRpbnVvdXMg4oCUIGl0IGhhcyBubyBjYXRlZ29yaWVzYCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBuYW1lLFxuICAgICAgICAgIGNhdGVnb3JpZXM6IGNvbHVtbi5tZXRhLmNhdGVnb3JpZXMsXG4gICAgICAgICAgY29sb3JzOiBjYXRlZ29yeUNvbG9yc0ZvcihuYW1lLCBjb2x1bW4ubWV0YSwgdGhpcy5jdHguc3RvcmUuY3VycmVudFNwYXRpYWxWaWV3KCkuZ3JvdXBDb2xvcnMpLFxuICAgICAgICAgIGNvZGVzOiBjb2x1bW4uY29kZXMsXG4gICAgICAgIH07XG4gICAgICB9LFxuXG4gICAgICAvLyBTcHJlYWQgcmF0aGVyIHRoYW4gYWx3YXlzIGRlZmluZWQ6IGBnZXRFbWJlZGRpbmdgIGlzIG9wdGlvbmFsIG9uIGJvdGggdGhlIHBvcnRcbiAgICAgIC8vIGFuZCB0aGlzIGZhY2FkZSwgYW5kIGEgcGFuZWwgY2hlY2tzIGZvciBpdHMgcHJlc2VuY2UgdG8gZGVjaWRlIHdoZXRoZXIgdGhlIHZpZXdcbiAgICAgIC8vIGlzIG9mZmVyZWQgYXQgYWxsLiBEZWZpbmluZyBpdCBhcyBhIGZ1bmN0aW9uIHRoYXQgcmVqZWN0cyB3b3VsZCBtYWtlIGFuXG4gICAgICAvLyBlbWJlZGRpbmctbGVzcyBzb3VyY2UgbG9vayBsaWtlIGEgYnJva2VuIG9uZS5cbiAgICAgIC4uLihwb3J0LmdldEVtYmVkZGluZyA/IHsgZ2V0RW1iZWRkaW5nOiAobmFtZTogc3RyaW5nKSA9PiBwb3J0LmdldEVtYmVkZGluZyEobmFtZSkgfSA6IHt9KSxcblxuICAgICAgY2F0ZWdvcmljYWxDb2x1bW5zOiAoKSA9PlxuICAgICAgICAodGhpcy5kYXRhc2V0Py5jb2x1bW5zID8/IFtdKS5maWx0ZXIoKGMpID0+IGMua2luZCA9PT0gJ2NhdGVnb3JpY2FsJykubWFwKChjKSA9PiBjLm5hbWUpLFxuXG4gICAgICAvLyBNZW1vaXplZCBvbiB0aGUgb2JzZXJ2YXRpb25zIG9iamVjdCwgc28gdGhlIHJlbmRlcmVyJ3Mgb3duIGxvb2t1cCBhbmRcbiAgICAgIC8vIHRoaXMgb25lIGFyZSB0aGUgc2FtZSBzaW5nbGUgc2NhbiBvZiB1cCB0byAzLjdNIHogdmFsdWVzLlxuICAgICAgc2FtcGxlZFNlY3Rpb25zOiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IG9icyA9IHRoaXMuZGF0YXNldD8ub2JzZXJ2YXRpb25zO1xuICAgICAgICByZXR1cm4gb2JzID8gc2VjdGlvbnNPZihvYnMpIDogbnVsbDtcbiAgICAgIH0sXG5cbiAgICAgIGdldFNlbGVjdGlvbiQ6ICgpID0+IHRoaXMuY3R4LnNlbGVjdGlvblN0b3JlLmdldFNlbGVjdGlvbiQoKSxcblxuICAgICAgc2VsZWN0RnJvbVJlZ2lvbnM6IGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgZGF0YXNldCA9IHRoaXMuZGF0YXNldDtcbiAgICAgICAgaWYgKCFkYXRhc2V0KSByZXR1cm4gMDtcbiAgICAgICAgY29uc3QgaXMzZCA9IGlzU3BhdGlhbE9taWNzM2QodGhpcy5jdHgucGxvdFR5cGUoKSk7XG4gICAgICAgIGNvbnN0IHZvbHVtZSA9ICFkYXRhc2V0LmltYWdlUmVmID8gZGF0YXNldC52b2x1bWUgOiB1bmRlZmluZWQ7XG4gICAgICAgIC8vIEluIHRoZSAzRCBjbG91ZCwgcmVnaW9uIGNsYXNzZXMgcGlja2VkIGluIHRoZSBSZWdpb24gRWRpdG9yIChhIGNsYXNzXG4gICAgICAgIC8vIHRyZWUgbm9kZSB3aXRoIGl0cyBzdWJjbGFzc2VzLCBhIHN1cmZhY2UgY2xpY2tlZCBpbiAzRCkgc2VsZWN0IHRoZVxuICAgICAgICAvLyBjZWxscyBpbnNpZGUgdGhlaXIgdm9sdW1lcyDigJQgdGhlIHN0cnVjdHVyZXMgc2hvd24gYW1vbmcgdGhlIGNlbGxzLlxuICAgICAgICBpZiAodm9sdW1lICYmIHRoaXMucm9pU2VsZWN0aW9uTW9kZSgpID09PSAnY2xhc3Mtdm9sdW1lcycpIHtcbiAgICAgICAgICBjb25zdCBjbGFzc2VzID0gdGhpcy5jdHgucmVnaW9uU3RvcmUuZ2V0UGlja2VkQ2xhc3NlcygpO1xuICAgICAgICAgIGNvbnN0IHJlcXVlc3QgPSArK3RoaXMucm9pUmVxdWVzdDtcbiAgICAgICAgICBjb25zdCByZXZpc2lvbiA9IHRoaXMuY3R4LnNlbGVjdGlvblN0b3JlLnJldmlzaW9uKCk7XG4gICAgICAgICAgY29uc3Qgb3V0bGluZXMgPSBhd2FpdCB0aGlzLmN0eC5yZWdpb25TdG9yZS5jbGFzc1NsaWNlT3V0bGluZXMoY2xhc3Nlcyk7XG4gICAgICAgICAgLy8gU3VwZXJzZWRlZCB3aGlsZSB0aGUgb3V0bGluZXMgd2VyZSByZWFkOiBhIG5ld2VyIHJlcXVlc3QsIGFueSBuZXdlciBzZWxlY3Rpb25cbiAgICAgICAgICAvLyAoYSBDbGVhciwgYSBsZWdlbmQgY2xpY2ssIGEgbGlua2VkIGNoYXJ0J3MgYnJ1c2gpLCBhbm90aGVyIGRhdGFzZXQsIHZpZXcgb3IgcGljayxcbiAgICAgICAgICAvLyBvciB0aGUgZmFjYWRlIGRpc3Bvc2VkLiBJdHMgbWFzayB3b3VsZCBvdmVyd3JpdGUgd2hhdCB0aGUgdXNlciBkaWQgc2luY2UuXG4gICAgICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuY3R4LnJlZ2lvblN0b3JlLmdldFBpY2tlZENsYXNzZXMoKTtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICByZXF1ZXN0ICE9PSB0aGlzLnJvaVJlcXVlc3QgfHxcbiAgICAgICAgICAgIHJldmlzaW9uICE9PSB0aGlzLmN0eC5zZWxlY3Rpb25TdG9yZS5yZXZpc2lvbigpIHx8XG4gICAgICAgICAgICB0aGlzLmRhdGFzZXQgIT09IGRhdGFzZXQgfHxcbiAgICAgICAgICAgIHRoaXMucm9pU2VsZWN0aW9uTW9kZSgpICE9PSAnY2xhc3Mtdm9sdW1lcycgfHxcbiAgICAgICAgICAgIGN1cnJlbnQubGVuZ3RoICE9PSBjbGFzc2VzLmxlbmd0aCB8fFxuICAgICAgICAgICAgY3VycmVudC5zb21lKChjLCBpKSA9PiBjICE9PSBjbGFzc2VzW2ldKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IHNlbGVjdGlvbiA9IHNlbGVjdEluQ2xhc3NWb2x1bWVzKGRhdGFzZXQub2JzZXJ2YXRpb25zLCB2b2x1bWUsIG91dGxpbmVzKTtcbiAgICAgICAgICB0aGlzLmN0eC5zZWxlY3Rpb25TdG9yZS5zZXQoc2VsZWN0aW9uKTtcbiAgICAgICAgICByZXR1cm4gc2VsZWN0aW9uLmNvdW50O1xuICAgICAgICB9XG4gICAgICAgIC8vIE90aGVyd2lzZSB0aGUgdW5pb24gb2YgZXZlcnkgZHJhd24gcmVnaW9uIOKAlCBzbyBldmVyeSBST0kgdG9vbCB0aGVcbiAgICAgICAgLy8gbGlicmFyeSBhbHJlYWR5IGhhcyBkb3VibGVzIGFzIGEgc3BhdGlhbCBzZWxlY3Rpb24gdG9vbC5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gSW4gdGhlIDNEIGNsb3VkIHRoZXJlIGlzIG5vIGRhdGEtc3BhY2UgYWZmaW5lIHRvIHB1c2ggYSBkcmF3biBzaGFwZVxuICAgICAgICAvLyB0aHJvdWdoLCBzbyB0aGUgb2JzZXJ2YXRpb25zIGFyZSBwcm9qZWN0ZWQgdG8gY2FudmFzIHBpeGVscyBieSB0aGVcbiAgICAgICAgLy8gcmVuZGVyZXIgKHdoaWNoIG93bnMgdGhlIGNhbWVyYSkgYW5kIHRlc3RlZCBpbiBzY3JlZW4gc3BhY2UgaW5zdGVhZCDigJRcbiAgICAgICAgLy8gYWdhaW5zdCB0aGUgbGFzc29zIGRyYXduIHRoZXJlIG9ubHk6IGV2ZXJ5IG90aGVyIHJlZ2lvbiBpcyBpbiBpbWFnZVxuICAgICAgICAvLyBzcGFjZS4gRmFsbHMgYmFjayB0byB0aGUgMkQgcGF0aCB3aGVuZXZlciB0aGUgY2xvdWQgaXMgbm90IG1vdW50ZWQuXG4gICAgICAgIGNvbnN0IHByb2plY3RlZCA9IGlzM2QgPyB0aGlzLmN0eC5uYXBhcmkuZ2V0U3BhdGlhbFNjcmVlblByb2plY3Rpb24oZGF0YXNldC5vYnNlcnZhdGlvbnMpIDogbnVsbDtcbiAgICAgICAgbGV0IHNlbGVjdGlvbjogU3BhdGlhbFNlbGVjdGlvbk1hc2s7XG4gICAgICAgIGlmIChwcm9qZWN0ZWQpIHtcbiAgICAgICAgICBjb25zdCBsYXNzb3MgPSBuZXcgU2V0KHRoaXMuY3R4Lm5hcGFyaS5nZXRTcGF0aWFsTGFzc29JZHMoKSk7XG4gICAgICAgICAgY29uc3QgcmVnaW9ucyA9IHRoaXMuY3R4LnJlZ2lvblN0b3JlLmdldFJlZ2lvbnMoKS5maWx0ZXIoKHIpID0+IGxhc3Nvcy5oYXMoci5pZCkpO1xuICAgICAgICAgIHNlbGVjdGlvbiA9IHNlbGVjdEluUmVnaW9uc1Byb2plY3RlZChwcm9qZWN0ZWQsIGRhdGFzZXQub2JzZXJ2YXRpb25zLmNvdW50LCByZWdpb25zKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBJbiB0aGUgMkQgdmlldyBvZiBhIHZvbHVtZS1iYWNrZWQgZGF0YXNldCB0aGUgc2hhcGUgd2FzIGRyYXduIG92ZXIgT05FXG4gICAgICAgICAgLy8gc2VjdGlvbiwgaW4gdGhlIHZvbHVtZSdzIHBpeGVsIGdyaWQ6IGl0IHNlbGVjdHMgdGhlIGNlbGxzIG9mIHRoYXRcbiAgICAgICAgICAvLyBzZWN0aW9uLCBub3QgdGhlIHdob2xlIGRlcHRoIG9mIGJyYWluIHN0YW5kaW5nIGJlaGluZCB0aGVtLlxuICAgICAgICAgIHNlbGVjdGlvbiA9IHNlbGVjdEluUmVnaW9ucyhcbiAgICAgICAgICAgIGRhdGFzZXQub2JzZXJ2YXRpb25zLFxuICAgICAgICAgICAgdm9sdW1lID8gdm9sdW1lSW1hZ2VSZWYodm9sdW1lLCBkYXRhc2V0Lm1pY3JvbnNQZXJVbml0KSA6IGRhdGFzZXQuaW1hZ2VSZWYsXG4gICAgICAgICAgICB0aGlzLmN0eC5yZWdpb25TdG9yZS5nZXRSZWdpb25zKCksXG4gICAgICAgICAgICB2b2x1bWUgPyBvYnNlcnZhdGlvbnNJblNsaWNlKGRhdGFzZXQub2JzZXJ2YXRpb25zLCB2b2x1bWUsIHRoaXMuY3R4LnpJbmRleCgpKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY3R4LnNlbGVjdGlvblN0b3JlLnNldChzZWxlY3Rpb24pO1xuICAgICAgICByZXR1cm4gc2VsZWN0aW9uLmNvdW50O1xuICAgICAgfSxcblxuICAgICAgcm9pU2VsZWN0aW9uTW9kZTogKCkgPT4gdGhpcy5yb2lTZWxlY3Rpb25Nb2RlKCksXG5cbiAgICAgIGdldFBpY2tlZFJlZ2lvbkNsYXNzZXMkOiAoKSA9PiB0aGlzLmN0eC5yZWdpb25TdG9yZS5nZXRQaWNrZWRDbGFzc2VzJCgpLFxuXG4gICAgICBzZWxlY3RDYXRlZ29yeTogYXN5bmMgKGNvbHVtbjogc3RyaW5nLCBjYXRlZ29yeUluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgY29uc3QgbG9hZGVkID0gYXdhaXQgcG9ydC5nZXRDb2x1bW4oY29sdW1uKTtcbiAgICAgICAgaWYgKCFpc0NhdGVnb3JpY2FsQ29sdW1uKGxvYWRlZCkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFtzcGF0aWFsXSBjb2x1bW4gXCIke2NvbHVtbn1cIiBpcyBjb250aW51b3VzIOKAlCBpdCBoYXMgbm8gY2F0ZWdvcmllc2ApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNlbGVjdGlvbiA9IHNlbGVjdEJ5Q2F0ZWdvcnkobG9hZGVkLmNvZGVzLCBjYXRlZ29yeUluZGV4KTtcbiAgICAgICAgdGhpcy5jdHguc2VsZWN0aW9uU3RvcmUuc2V0KHNlbGVjdGlvbik7XG4gICAgICAgIHJldHVybiBzZWxlY3Rpb24uY291bnQ7XG4gICAgICB9LFxuXG4gICAgICBzZWxlY3RJbmRpY2VzOiAoaW5kaWNlczogSXRlcmFibGU8bnVtYmVyPikgPT4ge1xuICAgICAgICBjb25zdCBjb3VudCA9IHRoaXMuZGF0YXNldD8ub2JzZXJ2YXRpb25zLmNvdW50ID8/IDA7XG4gICAgICAgIGlmIChjb3VudCA9PT0gMCkgcmV0dXJuIDA7XG4gICAgICAgIGNvbnN0IHNlbGVjdGlvbiA9IHNlbGVjdEJ5SW5kaWNlcyhpbmRpY2VzLCBjb3VudCk7XG4gICAgICAgIHRoaXMuY3R4LnNlbGVjdGlvblN0b3JlLnNldChzZWxlY3Rpb24pO1xuICAgICAgICByZXR1cm4gc2VsZWN0aW9uLmNvdW50O1xuICAgICAgfSxcblxuICAgICAgY2xlYXJTZWxlY3Rpb246ICgpID0+IHRoaXMuY3R4LnNlbGVjdGlvblN0b3JlLmNsZWFyKCksXG4gICAgfTtcbiAgfVxufVxuXG4vKipcbiAqIFdoZXRoZXIgYGRhdGFzZXRgIGNhbiBhbnN3ZXIgdGhpcyBjb2xvdXIgc291cmNlLiBBIGNvbHVtbiBpcyBjaGVja2FibGUgYWdhaW5zdCB0aGVcbiAqIGRlY2xhcmVkIGxpc3QuIEEgZ2VuZSBpcyBjaGVja2FibGUgb25seSB3aGVuIHRoZSBkYXRhc2V0IGlubGluZXMgaXRzIGZlYXR1cmUgbmFtZXMg4oCUXG4gKiBhIGRhdGFzZXQgdG9vIHdpZGUgdG8gaW5saW5lIHRoZW0gKHR5cGVhaGVhZC1vbmx5KSBrZWVwcyB0aGUgc291cmNlLCBhbmQgYSBuYW1lIHRoYXRcbiAqIHR1cm5zIG91dCBub3QgdG8gZXhpc3Qgc3VyZmFjZXMgYXMgdGhlIGNoYXJ0J3MgXCJjb3VsZCBub3QgYmUgY2hhcnRlZFwiIHJhdGhlciB0aGFuIGFzXG4gKiBhIHNpbGVudCByZXNldC5cbiAqL1xuZnVuY3Rpb24gY2FuQ29sb3JCeShkYXRhc2V0OiBTcGF0aWFsRGF0YXNldCB8IG51bGwsIGJ5OiBTcGF0aWFsQ29sb3JCeSk6IGJvb2xlYW4ge1xuICBpZiAoIWRhdGFzZXQpIHJldHVybiBmYWxzZTtcbiAgaWYgKGJ5LmtpbmQgPT09ICdjb2x1bW4nKSByZXR1cm4gZGF0YXNldC5jb2x1bW5zLnNvbWUoKGMpID0+IGMubmFtZSA9PT0gYnkubmFtZSk7XG4gIGNvbnN0IG5hbWVzID0gZGF0YXNldC5mZWF0dXJlcz8ubmFtZXM7XG4gIHJldHVybiAhIWRhdGFzZXQuZmVhdHVyZXMgJiYgKCFuYW1lcyB8fCBuYW1lcy5pbmNsdWRlcyhieS5uYW1lKSk7XG59XG4iXX0=
551
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhdGlhbC1jb250cm9scy5mYWNhZGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3NwYXRpYWwvc3BhdGlhbC1jb250cm9scy5mYWNhZGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBTUEsT0FBTyxFQUNMLFlBQVksRUFDWixLQUFLLEVBQ0wsb0JBQW9CLEVBQ3BCLEtBQUssRUFDTCxjQUFjLEVBQ2QsR0FBRyxFQUNILEtBQUssRUFDTCxVQUFVLEVBQ1YsRUFBRSxFQUNGLFNBQVMsRUFFVCxTQUFTLEVBQ1QsR0FBRyxHQUNKLE1BQU0sTUFBTSxDQUFDO0FBRWQsT0FBTyxFQUFZLGdCQUFnQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFHcEUsT0FBTyxFQU1MLG1CQUFtQixHQUNwQixNQUFNLHVDQUF1QyxDQUFDO0FBSy9DLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsY0FBYyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDN0UsT0FBTyxFQUFFLE1BQU0sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQy9ELE9BQU8sRUFDTCxjQUFjLEVBQ2QsZ0JBQWdCLEVBQ2hCLGVBQWUsRUFDZixvQkFBb0IsRUFDcEIsZUFBZSxFQUNmLHdCQUF3QixFQUN4QixZQUFZLEdBRWIsTUFBTSxxQkFBcUIsQ0FBQztBQUU3QixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUMvRixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxPQUFPLENBQUM7QUFDL0QsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzdDLE9BQU8sRUFDTCxrQkFBa0IsRUFDbEIsaUJBQWlC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SyxJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDbkUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHtcbiAgQ2VsbHMzZFN0YXR1cyxcbiAgT2JzZXJ2YXRpb25zSW5TZWxlY3Rpb24sXG4gIFNwYXRpYWxWaWV3U3RhdGUsXG4gIFRyYW5zY3JpcHRzSW5TZWxlY3Rpb24sXG59IGZyb20gJy4uL2NvbnRyYWN0cy9kaXNwbGF5LXR5cGVzJztcbmltcG9ydCB7XG4gIGRlYm91bmNlVGltZSxcbiAgZGVmZXIsXG4gIGRpc3RpbmN0VW50aWxDaGFuZ2VkLFxuICBFTVBUWSxcbiAgZmlyc3RWYWx1ZUZyb20sXG4gIG1hcCxcbiAgbWVyZ2UsXG4gIE9ic2VydmFibGUsXG4gIG9mLFxuICBzdGFydFdpdGgsXG4gIFN1YnNjcmlwdGlvbixcbiAgc3dpdGNoTWFwLFxuICB0YXAsXG59IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBQbG90VHlwZSwgaXNTcGF0aWFsT21pY3MzZCB9IGZyb20gJy4uL2NvbnRyYWN0cy9wbG90LXR5cGUnO1xuaW1wb3J0IHsgU3BhdGlhbERhdGFQb3J0IH0gZnJvbSAnLi4vY29udHJhY3RzL3BvcnRzL3NwYXRpYWwtZGF0YS5wb3J0JztcbmltcG9ydCB7IFNwYXRpYWxDb2xvckJ5IH0gZnJvbSAnLi4vY29udHJhY3RzL2Rpc3BsYXktdHlwZXMnO1xuaW1wb3J0IHtcbiAgQ2F0ZWdvcmljYWxDb2x1bW5NZXRhLFxuICBTcGF0aWFsRGF0YXNldCxcbiAgU3BhdGlhbEltYWdlUmVmLFxuICBTcGF0aWFsT2JzZXJ2YXRpb25zLFxuICBTcGF0aWFsU2VsZWN0aW9uTWFzayxcbiAgaXNDYXRlZ29yaWNhbENvbHVtbixcbn0gZnJvbSAnLi4vY29udHJhY3RzL3NwYXRpYWwtZGF0YXNldC5jb250cmFjdCc7XG5pbXBvcnQgeyBJU3BhdGlhbENvbnRyb2xzLCBSb2lTZWxlY3Rpb25Nb2RlIH0gZnJvbSAnLi4vY29udHJhY3RzL3Zpc3VhbGl6ZXIuY29udHJhY3QnO1xuaW1wb3J0IHsgUmVnaW9uU3RvcmUgfSBmcm9tICcuLi9zdG9yZS9yZWdpb24tc3RvcmUuc2VydmljZSc7XG5pbXBvcnQgeyBTcGF0aWFsU2VsZWN0aW9uU3RvcmUgfSBmcm9tICcuLi9zdG9yZS9zcGF0aWFsLXNlbGVjdGlvbi5zZXJ2aWNlJztcbmltcG9ydCB7IFZpc3VhbGl6ZXJTdG9yZSB9IGZyb20gJy4uL3N0b3JlL3Zpc3VhbGl6ZXItc3RvcmUuc2VydmljZSc7XG5pbXBvcnQgeyBjYXRlZ29yeUNvbG9yc0ZvciB9IGZyb20gJy4vc3BhdGlhbC1lbmNvZGluZyc7XG5pbXBvcnQgeyBzZWN0aW9uc09mIH0gZnJvbSAnLi9zcGF0aWFsLXNlY3Rpb25zJztcbmltcG9ydCB7IG9ic2VydmF0aW9uc0luU2xpY2UsIHZvbHVtZUltYWdlUmVmIH0gZnJvbSAnLi9zcGF0aWFsLXZvbHVtZS1pbWFnZSc7XG5pbXBvcnQgeyBpbkJhbmQsIG9ic2VydmF0aW9uc09uUGxhbmUgfSBmcm9tICcuL3NwYXRpYWwtcGxhbmVzJztcbmltcG9ydCB7XG4gIGVtcHR5U2VsZWN0aW9uLFxuICBzZWxlY3RCeUNhdGVnb3J5LFxuICBzZWxlY3RCeUluZGljZXMsXG4gIHNlbGVjdEluQ2xhc3NWb2x1bWVzLFxuICBzZWxlY3RJblJlZ2lvbnMsXG4gIHNlbGVjdEluUmVnaW9uc1Byb2plY3RlZCxcbiAgcmVnaW9uU2hhcGVzLFxuICB0eXBlIFNoYXBlLFxufSBmcm9tICcuL3NwYXRpYWwtc2VsZWN0aW9uJztcbmltcG9ydCB7IFJlZ2lvbiB9IGZyb20gJy4uL21vZGVscy9yZWdpb24nO1xuaW1wb3J0IHsgZGVzY3JpYmVPYnNlcnZhdGlvbnMsIE9CU0VSVkFUSU9OX0RFVEFJTF9DT0xVTU5TIH0gZnJvbSAnLi9vYnNlcnZhdGlvbnMtaW4tc2VsZWN0aW9uJztcbmltcG9ydCB7IGNlbGxUeXBlQ29sdW1uRm9yLCB0eXBpY2FsQ2VsbERpYW1ldGVyIH0gZnJvbSAnLi9sb2QnO1xuaW1wb3J0IHsgcGxhbmVCYW5kIH0gZnJvbSAnLi9zcGF0aWFsLXBsYW5lcyc7XG5pbXBvcnQge1xuICBDRUxMX1JFQUNIX01JQ1JPTlMsXG4gIGNlbGxzT2ZDYXRlZ29yaWVzLFxuICBjb3VudFRyYW5zY3JpcHRzLFxuICB0aWxlQnVkZ2V0LFxuICB0aWxlc0Fyb3VuZENlbGxzLFxuICB0aWxlc1VuZGVyU2hhcGVzLFxuICB0eXBlIFRyYW5zY3JpcHRGaWx0ZXIsXG59IGZyb20gJy4vdHJhbnNjcmlwdHMtaW4tc2VsZWN0aW9uJztcblxuLyoqIFRoZSByZW5kZXJlci1zaWRlIHNwYXRpYWwgcmVhZG91dHMgdGhlIGNvbnRyb2xzIHN1cmZhY2UgKHRoZSBuYXBhcmktanMgYmFja2VuZCkuICovXG5leHBvcnQgaW50ZXJmYWNlIFNwYXRpYWxSZW5kZXJlckZlZWRzIHtcbiAgcmVhZG9ubHkgdHJhbnNjcmlwdEVzdGltYXRlJDogeyBhc09ic2VydmFibGUoKTogT2JzZXJ2YWJsZTx7IHBvaW50czogbnVtYmVyOyBtYXg6IG51bWJlciB9IHwgbnVsbD4gfTtcbiAgcmVhZG9ubHkgZ2VuZUNvdW50c0luVmlldyQ6IHsgYXNPYnNlcnZhYmxlKCk6IE9ic2VydmFibGU8UmVjb3JkPHN0cmluZywgbnVtYmVyPiB8IG51bGw+IH07XG4gIHJlYWRvbmx5IGRlbnNpdHlTdGF0cyQ6IHsgYXNPYnNlcnZhYmxlKCk6IE9ic2VydmFibGU8eyBsbzogbnVtYmVyOyBoaTogbnVtYmVyOyBtYXg6IG51bWJlciB9IHwgbnVsbD4gfTtcbiAgcmVhZG9ubHkgZ2VuZUZpbHRlckZhaWxlZCQ/OiB7IGFzT2JzZXJ2YWJsZSgpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IH07XG4gIHJlYWRvbmx5IGNlbGxzM2RTdGF0dXMkPzogeyBhc09ic2VydmFibGUoKTogT2JzZXJ2YWJsZTxDZWxsczNkU3RhdHVzIHwgbnVsbD4gfTtcbiAgLyoqIE9ic2VydmF0aW9ucyBwcm9qZWN0ZWQgdG8gY2FudmFzIHBpeGVscyBieSB0aGUgM0QgY2FtZXJhLCBvciBudWxsIHdoZW4gdGhlIGNsb3VkIGlzIG5vdCBtb3VudGVkLiAqL1xuICBnZXRTcGF0aWFsU2NyZWVuUHJvamVjdGlvbihvYnM6IFNwYXRpYWxPYnNlcnZhdGlvbnMpOiBGbG9hdDMyQXJyYXkgfCBudWxsO1xuICAvKiogVGhlIGlkcyBvZiB0aGUgcmVnaW9ucyBkcmF3biBvdmVyIHRoZSAzRCBjbG91ZCBpbiBzY3JlZW4gc3BhY2UgKGl0cyBsYXNzb3MpLiAqL1xuICBnZXRTcGF0aWFsTGFzc29JZHMoKTogbnVtYmVyW107XG4gIC8qKiBJbWFnZSBweCBwZXIgdm94ZWwgb2YgdGhlIHZvbHVtZSB0aGUgcmVnaW9uIHN1cmZhY2VzIHNpdCBpbjsgbnVsbCB3aGVuIHRoZSBwbG90dGVkIGltYWdlIGlzXG4gICAqICBub3QgYSB2b2x1bWUncyBzdGFjayAodGhlIHJlZ2lvbnMgYXJlIHRoZW4gbm90IGluIHRoZSByZWZlcmVuY2Ugdm9sdW1lJ3MgZ3JpZCkuICovXG4gIHJlZ2lvblZveGVsU3RlcCgpOiBudW1iZXIgfCBudWxsO1xufVxuXG4vKiogV2hhdCB0aGUgZmFjYWRlIHdvcmtzIG92ZXI6IHRoZSBzaGFyZWQgc3RvcmVzLCB0aGUgcmVuZGVyZXIgZmVlZHMgYW5kIHRoZSByb3V0ZXIncyB2aWV3IHN0YXRlLiAqL1xuZXhwb3J0IGludGVyZmFjZSBTcGF0aWFsQ29udHJvbHNDb250ZXh0IHtcbiAgcmVhZG9ubHkgc3RvcmU6IFZpc3VhbGl6ZXJTdG9yZTtcbiAgcmVhZG9ubHkgcmVnaW9uU3RvcmU6IFJlZ2lvblN0b3JlO1xuICByZWFkb25seSBzZWxlY3Rpb25TdG9yZTogU3BhdGlhbFNlbGVjdGlvblN0b3JlO1xuICByZWFkb25seSBuYXBhcmk6IFNwYXRpYWxSZW5kZXJlckZlZWRzO1xuICAvKiogVGhlIHBsb3QgdHlwZSBvbiBzY3JlZW4gKHRoZSAzRCBjbG91ZCBzZWxlY3RzIGluIHNjcmVlbiBzcGFjZSkuICovXG4gIHBsb3RUeXBlKCk6IFBsb3RUeXBlO1xuICAvKiogVGhlIGRpc3BsYXllZCBzbGljZSAoYSB2b2x1bWUtYmFja2VkIGRhdGFzZXQgc2VsZWN0cyB3aXRoaW4gb25lIHNlY3Rpb24pLiAqL1xuICB6SW5kZXgoKTogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIGRhdGFzZXQgcmVnaW9uIHNldCdzIHBsYW5lcyB3aGlsZSB0aGV5IHNsaWNlIGFuIGltYWdlIG9mIG9uZSBwbGFuZSAoc2VlIHRoZSByb3V0ZXInc1xuICAgKiBgZ2V0RGF0YXNldFBsYW5lcyRgKTogdGhlIHNsaWNlIGlzIHRoZW4gb25lIG9mIHRoZW0sIGFuZCBhIHJlZ2lvbiBzZWxlY3RzIHdpdGhpbiBpdC4gT3B0aW9uYWwuXG4gICAqL1xuICBwbGFuZXM/KCk6IHJlYWRvbmx5IG51bWJlcltdIHwgbnVsbDtcbiAgLyoqXG4gICAqIFRoZSBkYXRhc2V0IHJlZ2lvbiBzZXQncyBwbGFuZXMgKGl0cyBgc2xpY2VaYCksIHdoZXRoZXIgb3Igbm90IHRoZXkgc2xpY2UgdGhlIGltYWdlIChhIHN0YWNrIG9mXG4gICAqIGFzIG1hbnkgcGxhbmVzIGlzIHNsaWNlZCBieSBpdHMgb3duIHNsaWNlcyk6IHRoZSAyRCB2aWV3IHNob3dzIHBsYW5lIGB6SW5kZXgoKWAncyB0cmFuc2NyaXB0cy5cbiAgICogT3B0aW9uYWwuXG4gICAqL1xuICBzbGljZVBsYW5lcz8oKTogcmVhZG9ubHkgbnVtYmVyW10gfCBudWxsO1xuICAvKiogRW1pdHMgd2hlbiB0aGUgcGxvdCB0eXBlLCB0aGUgc2xpY2Ugc2hvd24gb3IgdGhlIGRhdGFzZXQncyBwbGFuZXMgY2hhbmdlLiBPcHRpb25hbC4gKi9cbiAgcmVhZG9ubHkgdmlld0NoYW5nZWQkPzogT2JzZXJ2YWJsZTx1bmtub3duPjtcbn1cblxuLyoqIFdoZXJlIHRoZSBzZWxlY3Rpb24gdGhlIFwiaW4gc2VsZWN0aW9uXCIgbGlzdHMgZm9sbG93IGNvbWVzIGZyb20uICovXG50eXBlIFNlbGVjdGlvblNvdXJjZSA9ICdjZWxscycgfCAndHlwZXMnIHwgJ3JlZ2lvbnMnO1xuXG4vKiogV2hlcmUgYSBzZWxlY3Rpb24gYXBwbGllczogdGhlIHdob2xlIHZvbHVtZSAoM0QpLCBvciB0aGUgcGxhbmUgc2hvd24gb2YgdGhlIGRhdGFzZXQncyBwbGFuZXMuICovXG5pbnRlcmZhY2UgU2VsZWN0aW9uUGxhY2Uge1xuICBpczNkOiBib29sZWFuO1xuICBwbGFuZXM6IHJlYWRvbmx5IG51bWJlcltdIHwgbnVsbDtcbiAgcGxhbmU6IHsgaW5kZXg6IG51bWJlcjsgY291bnQ6IG51bWJlciB9IHwgbnVsbDtcbiAgYmFuZDogW251bWJlciwgbnVtYmVyXSB8IG51bGw7XG59XG5cbi8qKiBUaGUgbGF0ZXN0IHNlbGVjdGlvbiwgcmVzb2x2ZWQ6IGNlbGxzIChzZWxlY3RlZCwgb3Igb2YgcGlja2VkIHR5cGVzKSwgb3IgcmVnaW9uIHNoYXBlcy4gKi9cbnR5cGUgUmVzb2x2ZWRTZWxlY3Rpb24gPVxuICB8IHsga2luZDogJ2VtcHR5Jzsgd2hlcmU6IFNlbGVjdGlvblBsYWNlOyBtZXNzYWdlOiBzdHJpbmcgfVxuICB8IHtcbiAgICAgIGtpbmQ6ICdjZWxscyc7XG4gICAgICBzY29wZTogJ2NlbGxzJyB8ICd0eXBlcyc7XG4gICAgICB3aGVyZTogU2VsZWN0aW9uUGxhY2U7XG4gICAgICBsYWJlbDogc3RyaW5nO1xuICAgICAgbWFzazogVWludDhBcnJheTtcbiAgICAgIGNvdW50OiBudW1iZXI7XG4gICAgfVxuICB8IHtcbiAgICAgIGtpbmQ6ICdzaGFwZXMnO1xuICAgICAgc2NvcGU6ICdyZWdpb25zJztcbiAgICAgIHdoZXJlOiBTZWxlY3Rpb25QbGFjZTtcbiAgICAgIGxhYmVsOiBzdHJpbmc7XG4gICAgICByZWdpb25zOiBSZWdpb25bXTtcbiAgICAgIHNoYXBlczogU2hhcGVbXTtcbiAgICAgIGltYWdlUmVmOiBTcGF0aWFsSW1hZ2VSZWYgfCB1bmRlZmluZWQ7XG4gICAgfTtcblxuLyoqXG4gKiBUaGUgc3BhdGlhbC1vbWljcyBjb250cm9scyAoYElTcGF0aWFsQ29udHJvbHNgKSBvdmVyIGEgaG9zdCdzIGBTUEFUSUFMX0RBVEFfUE9SVGAuXG4gKlxuICogQmFja2VuZC1uZXV0cmFsOiB0aGUgdmlldyBzdGF0ZSBsaXZlcyBpbiB0aGUgc2hhcmVkIGBWaXN1YWxpemVyU3RvcmVgIChsaWtlIHRoZVxuICogY29sb3JtYXApIGFuZCB0aGUgc2VsZWN0aW9uIGluIHRoZSBgU3BhdGlhbFNlbGVjdGlvblN0b3JlYCwgc28gdGhlIGNvbnRyb2xzIGtlZXBcbiAqIHdvcmtpbmcgYWNyb3NzIGEgcGxvdC10eXBlIHN3aXRjaCBhbmQgYSBob3N0IGNhbiBkcml2ZSB0aGVtIGJlZm9yZSBhbnkgYmFja2VuZCBoYXNcbiAqIG1vdW50ZWQuIE93bnMgaXRzIG1pcnJvciBvZiB0aGUgcG9ydCdzIGRhdGFzZXQg4oCUIGRyb3BwaW5nIGEgc3RhbGUgc2VsZWN0aW9uIGFuZCBhblxuICogdW5zYXRpc2ZpYWJsZSBjb2xvdXIgc291cmNlIHdoZW4gdGhlIGRhdGFzZXQgY2hhbmdlcyDigJQgYW5kIHRoZSBzdWJzY3JpcHRpb24gYmVoaW5kXG4gKiBpdCwgcmVsZWFzZWQgYnkge0BsaW5rIGRpc3Bvc2V9IChyZXZpZXcgQ09SRS0zMCkuXG4gKi9cbmV4cG9ydCBjbGFzcyBTcGF0aWFsQ29udHJvbHNGYWNhZGUge1xuICAvKiogVGhlIGNvbnRyb2xzOyBvbmUgb2JqZWN0IGZvciB0aGUgZmFjYWRlJ3MgbGlmZSwgc28gY29uc3VtZXJzIGNhbiBob2xkIGl0LiAqL1xuICByZWFkb25seSBjb250cm9sczogSVNwYXRpYWxDb250cm9scztcbiAgLyoqIExhdGVzdCBkYXRhc2V0LCBtaXJyb3JlZCBzbyBgc2VsZWN0RnJvbVJlZ2lvbnMoKWAgYW5zd2VycyBmcm9tIHRoZSBkYXRhc2V0IG9uXG4gICAqICBzY3JlZW4g4oCUIGl0IHJ1bnMgZnJvbSBhIGJ1dHRvbiBjbGljayBhbmQgbXVzdCBub3QgYXdhaXQgYSByb3VuZC10cmlwLiAqL1xuICBwcml2YXRlIGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3ViOiBTdWJzY3JpcHRpb247XG4gIC8qKiBCdW1wZWQgcGVyIGNsYXNzLXZvbHVtZSBzZWxlY3Rpb24gKGFuZCBvbiBkaXNwb3NlKTogb25seSB0aGUgbGF0ZXN0IG1heSBwdWJsaXNoLiAqL1xuICBwcml2YXRlIHJvaVJlcXVlc3QgPSAwO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcG9ydDogU3BhdGlhbERhdGFQb3J0LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY3R4OiBTcGF0aWFsQ29udHJvbHNDb250ZXh0LFxuICApIHtcbiAgICAvLyBNaXJyb3IgdGhlIGRhdGFzZXQgKGFuZCBkcm9wIGEgc3RhbGUgc2VsZWN0aW9uIHdoZW4gaXQgY2hhbmdlcyDigJQgdGhlIG1hc2tzIGFyZVxuICAgIC8vIGluZGV4LWJhc2VkLCBzbyB0aGV5IGFyZSBtZWFuaW5nbGVzcyBhZ2FpbnN0IGRpZmZlcmVudCBvYnNlcnZhdGlvbnMpLlxuICAgIHRoaXMuc3ViID0gcG9ydC5nZXREYXRhc2V0JCgpLnN1YnNjcmliZSgoZGF0YXNldCkgPT4ge1xuICAgICAgY29uc3QgY2hhbmdlZCA9IGRhdGFzZXQ/LmlkICE9PSB0aGlzLmRhdGFzZXQ/LmlkO1xuICAgICAgdGhpcy5kYXRhc2V0ID0gZGF0YXNldDtcbiAgICAgIGlmICghY2hhbmdlZCkgcmV0dXJuO1xuICAgICAgY3R4LnNlbGVjdGlvblN0b3JlLnNldChlbXB0eVNlbGVjdGlvbihkYXRhc2V0Py5vYnNlcnZhdGlvbnMuY291bnQgPz8gMCkpO1xuICAgICAgLy8gQSBjb2xvdXIgc291cmNlIHRoZSBuZXcgZGF0YXNldCBjYW5ub3Qgc2F0aXNmeSB3b3VsZCBsZWF2ZSB0aGUgbWFwIGZsYXQgd2hpbGVcbiAgICAgIC8vIHRoZSBwYW5lbCBhbmQgdGhlIGNoYXJ0cyBrZXB0IG5hbWluZyB0aGUgb2xkIGNvbHVtbiDigJQgc28gZHJvcCBpdCwgYW5kIG9ubHkgaXQ6XG4gICAgICAvLyBwb2ludCBzaXplLCBvcGFjaXR5IGFuZCB0aGUgcmVzdCBhcmUgdGhlIHVzZXIncyBwcmVmZXJlbmNlcy5cbiAgICAgIGNvbnN0IGN1cnJlbnQgPSBjdHguc3RvcmUuY3VycmVudFNwYXRpYWxWaWV3KCk7XG4gICAgICBjb25zdCBieSA9IGN1cnJlbnQuY29sb3JCeTtcbiAgICAgIGlmIChieSAmJiAhY2FuQ29sb3JCeShkYXRhc2V0LCBieSkpIGN0eC5zdG9yZS5zZXRTcGF0aWFsVmlldyh7IGNvbG9yQnk6IG51bGwgfSk7XG4gICAgICAvLyBPbmUgY29sb3VyaW5nIGZvciB0aGUgbWFya2VycyBhbmQgdGhlIGNlbGxzOiBhIHNlZ21lbnRlZCBkYXRhc2V0J3MgbWFya2VycyBzdGFydCBpbiB0aGVcbiAgICAgIC8vIGNlbGxzJyBncm91cHMsIG5vdCBhIGZsYXQgY29sb3VyIGJlc2lkZSB0aGVtLlxuICAgICAgY29uc3QgdmlldyA9IGN0eC5zdG9yZS5jdXJyZW50U3BhdGlhbFZpZXcoKTtcbiAgICAgIGNvbnN0IGdyb3VwID0gZGF0YXNldCA/IGNlbGxUeXBlQ29sdW1uRm9yKGRhdGFzZXQsIHZpZXcpIDogbnVsbDtcbiAgICAgIGlmIChcbiAgICAgICAgIXZpZXcuY29sb3JCeSAmJlxuICAgICAgICBncm91cCAmJlxuICAgICAgICB2aWV3LmNlbGxDb2xvck1vZGUgPT09ICdncm91cCcgJiZcbiAgICAgICAgKGRhdGFzZXQ/LnBvbHlnb25UaWxlcyB8fCBkYXRhc2V0Py5wb2x5Z29ucylcbiAgICAgICkge1xuICAgICAgICBjdHguc3RvcmUuc2V0U3BhdGlhbFZpZXcoeyBjb2xvckJ5OiB7IGtpbmQ6ICdjb2x1bW4nLCBuYW1lOiBncm91cCB9IH0pO1xuICAgICAgfVxuICAgICAgLy8gVGhlIGdlbmUgZmlsdGVyIG5hbWVzIHRoZSBvbGQgZGF0YXNldCdzIGdlbmVzOiBrZXB0LCBpdCBjb3VsZCBoaWRlIGV2ZXJ5IG9ic2VydmF0aW9uLlxuICAgICAgaWYgKGN1cnJlbnQub2JzZXJ2YXRpb25HZW5lcz8ubGVuZ3RoKSBjdHguc3RvcmUuc2V0U3BhdGlhbFZpZXcoeyBvYnNlcnZhdGlvbkdlbmVzOiBbXSB9KTtcbiAgICAgIC8vIEdyb3VwIGNvbG91cnMgYXJlIGNob3NlbiBmb3IgdGhpcyBkYXRhc2V0J3MgZ3JvdXBpbmdzOyBhbm90aGVyJ3Mgc2FtZS1uYW1lZCBjb2x1bW4gaXMgbm90IHRoZW0uXG4gICAgICBpZiAoT2JqZWN0LmtleXMoY3VycmVudC5ncm91cENvbG9ycyA/PyB7fSkubGVuZ3RoKSBjdHguc3RvcmUuc2V0U3BhdGlhbFZpZXcoeyBncm91cENvbG9yczoge30gfSk7XG4gICAgfSk7XG4gICAgdGhpcy5jb250cm9scyA9IHRoaXMuYnVpbGQoKTtcbiAgfVxuXG4gIC8qKiBSZWxlYXNlIHRoZSBwb3J0IHN1YnNjcmlwdGlvbiAodGhlIHJvdXRlcidzIGluamVjdG9yIGlzIGJlaW5nIGRlc3Ryb3llZCkuICovXG4gIGRpc3Bvc2UoKTogdm9pZCB7XG4gICAgdGhpcy5zdWIudW5zdWJzY3JpYmUoKTtcbiAgICAvLyBBIGNsYXNzLXZvbHVtZSBzZWxlY3Rpb24gc3RpbGwgcmVhZGluZyBpdHMgb3V0bGluZXMgcHVibGlzaGVzIG5vdGhpbmcuXG4gICAgdGhpcy5yb2lSZXF1ZXN0Kys7XG4gIH1cblxuICAvKipcbiAgICogSG93IFwiU2VsZWN0IGZyb20gUk9Jc1wiIHNlbGVjdHMgbm93IOKAlCB0aGUgb25lIHJ1bGUgaXRzIGV4ZWN1dG9yIGFuZCB0aGUgcGFuZWwncyBkZXNjcmlwdGlvblxuICAgKiBzaGFyZTogaW5zaWRlIHRoZSBwaWNrZWQgY2xhc3Nlcycgdm9sdW1lcyBpbiB0aGUgM0QgY2xvdWQsIHdoZW4gdGhlIGRhdGFzZXQgaGFzIGEgcmVmZXJlbmNlXG4gICAqIHZvbHVtZSAoYW5kIG5vIHRpc3N1ZSBpbWFnZSkgYW5kIHRoZSBwbG90dGVkIGltYWdlIGlzIHRoYXQgdm9sdW1lJ3Mgc3RhY2ssIHNvIHRoZSByZWdpb25zIHNpdFxuICAgKiBpbiBpdHMgZ3JpZDsgYnkgdGhlIGRyYXduIHJlZ2lvbnMgb3RoZXJ3aXNlLlxuICAgKi9cbiAgcHJpdmF0ZSByb2lTZWxlY3Rpb25Nb2RlKCk6IFJvaVNlbGVjdGlvbk1vZGUge1xuICAgIGNvbnN0IGRhdGFzZXQgPSB0aGlzLmRhdGFzZXQ7XG4gICAgY29uc3QgZWxpZ2libGUgPVxuICAgICAgISFkYXRhc2V0Py52b2x1bWUgJiZcbiAgICAgICFkYXRhc2V0LmltYWdlUmVmICYmXG4gICAgICBpc1NwYXRpYWxPbWljczNkKHRoaXMuY3R4LnBsb3RUeXBlKCkpICYmXG4gICAgICB0aGlzLmN0eC5yZWdpb25TdG9yZS5nZXRQaWNrZWRDbGFzc2VzKCkubGVuZ3RoID4gMCAmJlxuICAgICAgdGhpcy5jdHgubmFwYXJpLnJlZ2lvblZveGVsU3RlcCgpICE9PSBudWxsO1xuICAgIHJldHVybiBlbGlnaWJsZSA/ICdjbGFzcy12b2x1bWVzJyA6ICdyZWdpb25zJztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgc2VsZWN0aW9ucyB0aGUgXCJpbiBzZWxlY3Rpb25cIiBsaXN0cyBmb2xsb3csIGFzIHRoZXkgY2hhbmdlOiB0aGUgbGF0ZXN0IG9mIHRocmVlLCBhcyB0aGUgdXNlclxuICAgKiBtYWRlIHRoZW0g4oCUIHRoZSBzZWxlY3RlZCBjZWxscyAoYSBjZWxsIGNsaWNrZWQsIGEgbGVnZW5kIGdyb3VwLCBhIGJydXNoKSwgdGhlIGNsYXNzZXMgcGlja2VkIGluXG4gICAqIHRoZSByZWdpb24gZWRpdG9yIChpbiBzcGF0aWFsIDNEIHRoZSBjZWxsIHR5cGVzIG9mIHRoZSB0eXBlIHN1cmZhY2VzKSwgb3IgdGhlIHJlZ2lvbnMgc2VsZWN0ZWQgb25cbiAgICogdGhlIGltYWdlICgyRCBvbmx5KS4gQ2xlYXJpbmcgdGhlIGxhdGVzdCBnb2VzIGJhY2sgdG8gdGhlIG9uZSBiZWZvcmUsIHdoZW4gaXQgc3RpbGwgc3RhbmRzLiBFbWl0c1xuICAgKiAoZGVib3VuY2VkKSB0aGUgc291cmNlcyBzdGFuZGluZywgbGF0ZXN0IGxhc3QsIHdoZW5ldmVyIHRoZSBzZWxlY3Rpb24sIHRoZSByZWdpb25zLCB0aGUgcGxhbmVcbiAgICogc2hvd24sIHRoZSBwbG90IHR5cGUsIHRoZSBkYXRhc2V0IG9yIGB2aWV3S2V5YCBvZiB0aGUgdmlldyBzdGF0ZSBjaGFuZ2UuXG4gICAqL1xuICBwcml2YXRlIHNlbGVjdGlvbkNoYW5nZXMkKHZpZXdLZXk6ICh2OiBTcGF0aWFsVmlld1N0YXRlKSA9PiBzdHJpbmcpOiBPYnNlcnZhYmxlPHJlYWRvbmx5IFNlbGVjdGlvblNvdXJjZVtdPiB7XG4gICAgY29uc3QgeyBjdHggfSA9IHRoaXM7XG4gICAgcmV0dXJuIGRlZmVyKCgpID0+IHtcbiAgICAgIGxldCBhY3RpdmU6IFNlbGVjdGlvblNvdXJjZVtdID0gW107XG4gICAgICBjb25zdCB0cmFjayA9IChzb3VyY2U6IFNlbGVjdGlvblNvdXJjZSwgb246IGJvb2xlYW4pID0+IHtcbiAgICAgICAgYWN0aXZlID0gYWN0aXZlLmZpbHRlcigocykgPT4gcyAhPT0gc291cmNlKTtcbiAgICAgICAgaWYgKG9uKSBhY3RpdmUucHVzaChzb3VyY2UpO1xuICAgICAgfTtcbiAgICAgIHJldHVybiBtZXJnZShcbiAgICAgICAgLy8gT24gc3Vic2NyaWJpbmcsIHRoZSB0aHJlZSBjb21lIGluIHRoaXMgb3JkZXI6IG9mIHRob3NlIHN0YW5kaW5nLCB0aGUgY2VsbHMgY29tZSBsYXN0XG4gICAgICAgIC8vICh0aGUgbW9zdCBzcGVjaWZpYykuXG4gICAgICAgIGN0eC5yZWdpb25TdG9yZS5nZXRTZWxlY3RlZFNoYXBlSW5kaWNlcyQoKS5waXBlKHRhcCgoaSkgPT4gdHJhY2soJ3JlZ2lvbnMnLCBpLmxlbmd0aCA+IDApKSksXG4gICAgICAgIGN0eC5yZWdpb25TdG9yZS5nZXRQaWNrZWRDbGFzc2VzJCgpLnBpcGUodGFwKChjKSA9PiB0cmFjaygndHlwZXMnLCBjLmxlbmd0aCA+IDApKSksXG4gICAgICAgIGN0eC5zZWxlY3Rpb25TdG9yZS5nZXRTZWxlY3Rpb24kKCkucGlwZSh0YXAoKHNlbCkgPT4gdHJhY2soJ2NlbGxzJywgc2VsLmNvdW50ID4gMCkpKSxcbiAgICAgICAgY3R4LnJlZ2lvblN0b3JlLmdldFJlZ2lvblVwZGF0ZUV2ZW50KCksXG4gICAgICAgIGN0eC52aWV3Q2hhbmdlZCQgPz8gRU1QVFksXG4gICAgICAgIGN0eC5zdG9yZS5nZXRTcGF0aWFsVmlldyQoKS5waXBlKG1hcCh2aWV3S2V5KSwgZGlzdGluY3RVbnRpbENoYW5nZWQoKSksXG4gICAgICAgIHRoaXMucG9ydC5nZXREYXRhc2V0JCgpLFxuICAgICAgKS5waXBlKFxuICAgICAgICBkZWJvdW5jZVRpbWUoMTUwKSxcbiAgICAgICAgbWFwKCgpID0+IGFjdGl2ZS5zbGljZSgpKSxcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogYHdvcmtgIGFzIGEgc3RyZWFtOiB3aGF0IGl0IHJlcG9ydHMgdGhyb3VnaCBgcHJvZ3Jlc3NgLCB0aGVuIGl0cyBhbnN3ZXIgKG9yIGBmYWlsZWRgJ3MgbWVzc2FnZSk7XG4gICAqIHVuc3Vic2NyaWJpbmcgYWJhbmRvbnMgaXQgKGBjYW5jZWxsZWQoKWAgdGhlbiBzYXlzIHNvKS5cbiAgICovXG4gIHByaXZhdGUgcnVuQ2FuY2VsbGFibGU8VD4oXG4gICAgd29yazogKHByb2dyZXNzOiAoc3RhdGU6IFQpID0+IHZvaWQsIGNhbmNlbGxlZDogKCkgPT4gYm9vbGVhbikgPT4gUHJvbWlzZTxUPixcbiAgICBmYWlsZWQ6IChtZXNzYWdlOiBzdHJpbmcpID0+IFQsXG4gICk6IE9ic2VydmFibGU8VD4ge1xuICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZTxUPigoc3ViKSA9PiB7XG4gICAgICBsZXQgY2FuY2VsbGVkID0gZmFsc2U7XG4gICAgICB3b3JrKFxuICAgICAgICAoc3RhdGUpID0+IHtcbiAgICAgICAgICBpZiAoIWNhbmNlbGxlZCkgc3ViLm5leHQoc3RhdGUpO1xuICAgICAgICB9LFxuICAgICAgICAoKSA9PiBjYW5jZWxsZWQsXG4gICAgICApXG4gICAgICAgIC50aGVuKChzdGF0ZSkgPT4ge1xuICAgICAgICAgIGlmIChjYW5jZWxsZWQpIHJldHVybjtcbiAgICAgICAgICBzdWIubmV4dChzdGF0ZSk7XG4gICAgICAgICAgc3ViLmNvbXBsZXRlKCk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgaWYgKGNhbmNlbGxlZCkgcmV0dXJuO1xuICAgICAgICAgIHN1Yi5uZXh0KGZhaWxlZChTdHJpbmcoZXJyPy5tZXNzYWdlID8/IGVycikpKTtcbiAgICAgICAgICBzdWIuY29tcGxldGUoKTtcbiAgICAgICAgfSk7XG4gICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjYW5jZWxsZWQgPSB0cnVlO1xuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGF0IHRoZSBsYXRlc3Qgc2VsZWN0aW9uIGluIGBhY3RpdmVgIGlzIChzZWUge0BsaW5rIHNlbGVjdGlvbkNoYW5nZXMkfSksIGFuZCB3aGVyZSBpdCBhcHBsaWVzOlxuICAgKiB0aHJvdWdoIHRoZSB3aG9sZSB2b2x1bWUgaW4gc3BhdGlhbCAzRDsgb24gdGhlIHBsYW5lIHNob3duIGluIDJEIHdoZW4gdGhlIGRhdGFzZXQncyBwbGFuZXMgc2xpY2VcbiAgICogaXQgYW5kIHdoYXQgaXMgbGlzdGVkIGNhcnJpZXMgeiAoYGhhc1pgKS4gYHdoYXRgIG5hbWVzIHdoYXQgaXMgbGlzdGVkLCBmb3IgdGhlIGhpbnRzLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZXNvbHZlU2VsZWN0aW9uKFxuICAgIGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0LFxuICAgIGFjdGl2ZTogcmVhZG9ubHkgU2VsZWN0aW9uU291cmNlW10sXG4gICAgaGFzWjogYm9vbGVhbixcbiAgICB3aGF0OiBzdHJpbmcsXG4gICk6IFByb21pc2U8UmVzb2x2ZWRTZWxlY3Rpb24+IHtcbiAgICBjb25zdCBpczNkID0gaXNTcGF0aWFsT21pY3MzZCh0aGlzLmN0eC5wbG90VHlwZSgpKTtcbiAgICBjb25zdCBwbGFuZXMgPSAhaXMzZCAmJiBoYXNaID8gKHRoaXMuY3R4LnNsaWNlUGxhbmVzPy4oKSA/PyBudWxsKSA6IG51bGw7XG4gICAgY29uc3Qgc2xpY2VkID0gcGxhbmVzICYmIHBsYW5lcy5sZW5ndGggPiAxID8gcGxhbmVzIDogbnVsbDtcbiAgICBjb25zdCBrID0gc2xpY2VkID8gTWF0aC5tYXgoMCwgTWF0aC5taW4oc2xpY2VkLmxlbmd0aCAtIDEsIHRoaXMuY3R4LnpJbmRleCgpKSkgOiAwO1xuICAgIGNvbnN0IHdoZXJlOiBTZWxlY3Rpb25QbGFjZSA9IHtcbiAgICAgIGlzM2QsXG4gICAgICBwbGFuZXM6IHNsaWNlZCxcbiAgICAgIHBsYW5lOiBzbGljZWQgPyB7IGluZGV4OiBrLCBjb3VudDogc2xpY2VkLmxlbmd0aCB9IDogbnVsbCxcbiAgICAgIGJhbmQ6IHNsaWNlZCA/IHBsYW5lQmFuZChzbGljZWQsIGspIDogbnVsbCxcbiAgICB9O1xuICAgIC8vIERyYXduIHJlZ2lvbnMgYXJlIGltYWdlIHNoYXBlczogdGhleSBzZWxlY3Qgb24gdGhlIGltYWdlLCBpbiAyRC5cbiAgICBjb25zdCBlbGlnaWJsZSA9IGFjdGl2ZS5maWx0ZXIoKHMpID0+ICFpczNkIHx8IHMgIT09ICdyZWdpb25zJyk7XG4gICAgY29uc3Qgc291cmNlID0gZWxpZ2libGVbZWxpZ2libGUubGVuZ3RoIC0gMV0gPz8gbnVsbDtcbiAgICBpZiAoIXNvdXJjZSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAga2luZDogJ2VtcHR5JyxcbiAgICAgICAgd2hlcmUsXG4gICAgICAgIG1lc3NhZ2U6IGlzM2RcbiAgICAgICAgICA/IGBTZWxlY3QgYSBjZWxsLCBvciBwaWNrIGEgY2VsbCB0eXBlLCB0byBsaXN0IHRoZSAke3doYXR9IGluIGl0LmBcbiAgICAgICAgICA6IGBTZWxlY3QgYSBjZWxsIG9yIGEgcmVnaW9uJHtzbGljZWQgPyAnIG9uIHRoaXMgcGxhbmUnIDogJyd9IHRvIGxpc3QgdGhlICR7d2hhdH0gaW4gaXQuYCxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3Qgb2JzID0gZGF0YXNldC5vYnNlcnZhdGlvbnM7XG4gICAgaWYgKHNvdXJjZSA9PT0gJ2NlbGxzJykge1xuICAgICAgY29uc3Qgc2VsID0gdGhpcy5jdHguc2VsZWN0aW9uU3RvcmUuY3VycmVudCgpO1xuICAgICAgaWYgKHNlbC5jb3VudCkge1xuICAgICAgICBjb25zdCBmaXJzdCA9IHNlbC5jb3VudCA9PT0gMSA/IHNlbC5tYXNrLmluZGV4T2YoMSkgOiAtMTtcbiAgICAgICAgY29uc3QgbmFtZSA9IGZpcnN0ID49IDAgPyAob2JzLmlkcz8uW2ZpcnN0XSA/PyBTdHJpbmcoZmlyc3QpKSA6IG51bGw7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAga2luZDogJ2NlbGxzJyxcbiAgICAgICAgICBzY29wZTogJ2NlbGxzJyxcbiAgICAgICAgICB3aGVyZSxcbiAgICAgICAgICBtYXNrOiBzZWwubWFzayxcbiAgICAgICAgICBjb3VudDogc2VsLmNvdW50LFxuICAgICAgICAgIGxhYmVsOiBuYW1lICE9PSBudWxsID8gYENlbGwgJHtuYW1lfWAgOiBgJHtzZWwuY291bnQudG9Mb2NhbGVTdHJpbmcoKX0gc2VsZWN0ZWQgY2VsbHNgLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoc291cmNlID09PSAndHlwZXMnKSB7XG4gICAgICBjb25zdCBjbGFzc2VzID0gdGhpcy5jdHgucmVnaW9uU3RvcmUuZ2V0UGlja2VkQ2xhc3NlcygpO1xuICAgICAgY29uc3QgY29sdW1uID0gdGhpcy5jZWxsVHlwZUNvbHVtbk9mKGRhdGFzZXQsIGNsYXNzZXMpO1xuICAgICAgY29uc3QgbG9hZGVkID0gY29sdW1uID8gYXdhaXQgdGhpcy5wb3J0LmdldENvbHVtbihjb2x1bW4pIDogbnVsbDtcbiAgICAgIGlmIChsb2FkZWQgJiYgaXNDYXRlZ29yaWNhbENvbHVtbihsb2FkZWQpKSB7XG4gICAgICAgIGNvbnN0IGNlbGxzID0gY2VsbHNPZkNhdGVnb3JpZXMobG9hZGVkLmNvZGVzLCBsb2FkZWQubWV0YS5jYXRlZ29yaWVzLCBjbGFzc2VzKTtcbiAgICAgICAgaWYgKGNlbGxzLmNvdW50KSB7XG4gICAgICAgICAgY29uc3QgbmFtZXMgPVxuICAgICAgICAgICAgY2xhc3Nlcy5sZW5ndGggPiAzID8gYCR7Y2xhc3Nlcy5zbGljZSgwLCAzKS5qb2luKCcsICcpfSArJHtjbGFzc2VzLmxlbmd0aCAtIDN9YCA6IGNsYXNzZXMuam9pbignLCAnKTtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAga2luZDogJ2NlbGxzJyxcbiAgICAgICAgICAgIHNjb3BlOiAndHlwZXMnLFxuICAgICAgICAgICAgd2hlcmUsXG4gICAgICAgICAgICAuLi5jZWxscyxcbiAgICAgICAgICAgIGxhYmVsOiBgJHtjbGFzc2VzLmxlbmd0aCA+IDEgPyAnQ2VsbCB0eXBlcycgOiAnQ2VsbCB0eXBlJ306ICR7bmFtZXN9YCxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBQaWNrZWQgY2xhc3NlcyB0aGF0IGFyZSBubyBjZWxsIHR5cGU6IGluIDJELCB0aGUgcmVnaW9ucyBvZiB0aG9zZSBjbGFzc2VzIG9uIHRoZSBwbGFuZS5cbiAgICAgIGlmIChpczNkKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAga2luZDogJ2VtcHR5JyxcbiAgICAgICAgICB3aGVyZSxcbiAgICAgICAgICBtZXNzYWdlOiBgVGhlIHBpY2tlZCBjbGFzc2VzIGFyZSBub3QgY2VsbCB0eXBlcyBvZiB0aGlzIGRhdGFzZXQ6IHNlbGVjdCBhIGNlbGwgdG8gbGlzdCBpdHMgJHt3aGF0fS5gLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGFsbCA9IHRoaXMuY3R4LnJlZ2lvblN0b3JlLmdldFJlZ2lvbnMoKTtcbiAgICBsZXQgcmVnaW9uczogUmVnaW9uW107XG4gICAgbGV0IGxhYmVsOiBzdHJpbmc7XG4gICAgaWYgKHNvdXJjZSA9PT0gJ3R5cGVzJykge1xuICAgICAgY29uc3QgY2xhc3NlcyA9IG5ldyBTZXQodGhpcy5jdHgucmVnaW9uU3RvcmUuZ2V0UGlja2VkQ2xhc3NlcygpKTtcbiAgICAgIHJlZ2lvbnMgPSBhbGwuZmlsdGVyKChyKSA9PiAhIXIubGFiZWwgJiYgY2xhc3Nlcy5oYXMoci5sYWJlbCkpO1xuICAgICAgbGFiZWwgPSBgQ2xhc3M6ICR7Wy4uLmNsYXNzZXNdLmpvaW4oJywgJyl9YDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVnaW9ucyA9IHRoaXMuY3R4LnJlZ2lvblN0b3JlXG4gICAgICAgIC5nZXRTZWxlY3RlZFNoYXBlSW5kaWNlcygpXG4gICAgICAgIC5tYXAoKGkpID0+IGFsbFtpXSlcbiAgICAgICAgLmZpbHRlcigocikgPT4gISFyKTtcbiAgICAgIGxhYmVsID0gYCR7cmVnaW9ucy5sZW5ndGh9IHNlbGVjdGVkIHJlZ2lvbiR7cmVnaW9ucy5sZW5ndGggPT09IDEgPyAnJyA6ICdzJ31gO1xuICAgIH1cbiAgICBjb25zdCBzaGFwZXMgPSByZWdpb25zLmZsYXRNYXAoKHIpID0+IHJlZ2lvblNoYXBlcyhyKSk7XG4gICAgaWYgKCFzaGFwZXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBraW5kOiAnZW1wdHknLFxuICAgICAgICB3aGVyZSxcbiAgICAgICAgbWVzc2FnZTpcbiAgICAgICAgICBzb3VyY2UgPT09ICd0eXBlcydcbiAgICAgICAgICAgID8gYE5vIHJlZ2lvbiBvZiB0aG9zZSBjbGFzc2VzJHtzbGljZWQgPyAnIG9uIHRoaXMgcGxhbmUnIDogJyd9LmBcbiAgICAgICAgICAgIDogJ1RoZSBzZWxlY3RlZCByZWdpb25zIGVuY2xvc2Ugbm8gYXJlYS4nLFxuICAgICAgfTtcbiAgICB9XG4gICAgY29uc3QgaW1hZ2VSZWYgPVxuICAgICAgZGF0YXNldC52b2x1bWUgJiYgIWRhdGFzZXQuaW1hZ2VSZWZcbiAgICAgICAgPyB2b2x1bWVJbWFnZVJlZihkYXRhc2V0LnZvbHVtZSwgZGF0YXNldC5taWNyb25zUGVyVW5pdClcbiAgICAgICAgOiBkYXRhc2V0LmltYWdlUmVmO1xuICAgIHJldHVybiB7IGtpbmQ6ICdzaGFwZXMnLCBzY29wZTogJ3JlZ2lvbnMnLCB3aGVyZSwgbGFiZWwsIHJlZ2lvbnMsIHNoYXBlcywgaW1hZ2VSZWYgfTtcbiAgfVxuXG4gIC8qKiBUaGUgdHJhbnNjcmlwdHMgb2YgdGhlIHNlbGVjdGlvbiwgYnkgZ2VuZSAoc2VlIHtAbGluayBzZWxlY3Rpb25DaGFuZ2VzJH0pLiAqL1xuICBwcml2YXRlIHRyYW5zY3JpcHRzSW5TZWxlY3Rpb24kKCk6IE9ic2VydmFibGU8VHJhbnNjcmlwdHNJblNlbGVjdGlvbj4ge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdGlvbkNoYW5nZXMkKCh2KSA9PiBgJHt2LnRyYW5zY3JpcHRRdWFsaXR5fXwke3YuY2VsbFR5cGVDb2x1bW4gPz8gJyd9YCkucGlwZShcbiAgICAgIHN3aXRjaE1hcCgoYWN0aXZlKSA9PlxuICAgICAgICB0aGlzLnJ1bkNhbmNlbGxhYmxlPFRyYW5zY3JpcHRzSW5TZWxlY3Rpb24+KFxuICAgICAgICAgIChwcm9ncmVzcywgY2FuY2VsbGVkKSA9PiB0aGlzLnRyYW5zY3JpcHRzT2YoYWN0aXZlLCBwcm9ncmVzcywgY2FuY2VsbGVkKSxcbiAgICAgICAgICAobWVzc2FnZSkgPT4gKHsgc3RhdGU6ICdlcnJvcicsIG1lc3NhZ2U6IGBUaGUgdHJhbnNjcmlwdHMgY291bGQgbm90IGJlIGNvdW50ZWQ6ICR7bWVzc2FnZX1gIH0pLFxuICAgICAgICApLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIENvdW50IHRoZSB0cmFuc2NyaXB0cyBvZiB0aGUgbGF0ZXN0IHNlbGVjdGlvbiBpbiBgYWN0aXZlYDogdGhyb3VnaCB0aGUgd2hvbGUgdm9sdW1lIGluIHNwYXRpYWxcbiAgICogM0QsIG9uIHRoZSBwbGFuZSBzaG93biBpbiAyRCB3aGVuIHRoZSBkYXRhc2V0J3MgcGxhbmVzIHNsaWNlIGl0LlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyB0cmFuc2NyaXB0c09mKFxuICAgIGFjdGl2ZTogcmVhZG9ubHkgU2VsZWN0aW9uU291cmNlW10sXG4gICAgcHJvZ3Jlc3M6IChzdGF0ZTogVHJhbnNjcmlwdHNJblNlbGVjdGlvbikgPT4gdm9pZCxcbiAgICBjYW5jZWxsZWQ6ICgpID0+IGJvb2xlYW4sXG4gICk6IFByb21pc2U8VHJhbnNjcmlwdHNJblNlbGVjdGlvbj4ge1xuICAgIGNvbnN0IGRhdGFzZXQgPSB0aGlzLmRhdGFzZXQ7XG4gICAgY29uc3QgbWV0YSA9IGRhdGFzZXQ/LnRyYW5zY3JpcHRUaWxlcztcbiAgICBpZiAoIWRhdGFzZXQgfHwgIW1ldGEpIHJldHVybiB7IHN0YXRlOiAnZW1wdHknLCBtZXNzYWdlOiAnVGhpcyBkYXRhc2V0IGhhcyBubyB0cmFuc2NyaXB0cy4nIH07XG4gICAgY29uc3QgdGFyZ2V0ID0gYXdhaXQgdGhpcy5yZXNvbHZlU2VsZWN0aW9uKGRhdGFzZXQsIGFjdGl2ZSwgbWV0YS5oYXNaLCAndHJhbnNjcmlwdHMnKTtcbiAgICBpZiAoY2FuY2VsbGVkKCkpIHJldHVybiB7IHN0YXRlOiAnbG9hZGluZycgfTtcbiAgICBjb25zdCB7IHBsYW5lLCBiYW5kIH0gPSB0YXJnZXQud2hlcmU7XG4gICAgaWYgKHRhcmdldC5raW5kID09PSAnZW1wdHknKSByZXR1cm4geyBzdGF0ZTogJ2VtcHR5JywgcGxhbmUsIG1lc3NhZ2U6IHRhcmdldC5tZXNzYWdlIH07XG5cbiAgICBjb25zdCBxdWFsaXR5ID0gdGhpcy5jdHguc3RvcmUuY3VycmVudFNwYXRpYWxWaWV3KCkudHJhbnNjcmlwdFF1YWxpdHkgPT09ICdhbGwnID8gJ2FsbCcgOiAnaGlnaCc7XG4gICAgY29uc3QgYnVkZ2V0ID0gdGlsZUJ1ZGdldChtZXRhKTtcbiAgICBjb25zdCBmaWx0ZXI6IFRyYW5zY3JpcHRGaWx0ZXIgPVxuICAgICAgdGFyZ2V0LmtpbmQgPT09ICdjZWxscydcbiAgICAgICAgPyB7IGtpbmQ6ICdjZWxscycsIG1hc2s6IHRhcmdldC5tYXNrIH1cbiAgICAgICAgOiB7IGtpbmQ6ICdzaGFwZXMnLCBzaGFwZXM6IHRhcmdldC5zaGFwZXMsIGltYWdlUmVmOiB0YXJnZXQuaW1hZ2VSZWYgfTtcbiAgICBjb25zdCB0aWxlcyA9XG4gICAgICB0YXJnZXQua2luZCA9PT0gJ2NlbGxzJ1xuICAgICAgICA/IHRpbGVzQXJvdW5kQ2VsbHMoXG4gICAgICAgICAgICBkYXRhc2V0Lm9ic2VydmF0aW9ucyxcbiAgICAgICAgICAgIHRhcmdldC5tYXNrLFxuICAgICAgICAgICAgdGhpcy5jZWxsUmVhY2goZGF0YXNldCksXG4gICAgICAgICAgICBtZXRhLmxldmVscyxcbiAgICAgICAgICAgIG1ldGEuYm91bmRzLFxuICAgICAgICAgICAgYnVkZ2V0LFxuICAgICAgICAgIClcbiAgICAgICAgOiB0aWxlc1VuZGVyU2hhcGVzKHRhcmdldC5zaGFwZXMsIHRhcmdldC5pbWFnZVJlZiwgbWV0YS5sZXZlbHMsIG1ldGEuYm91bmRzLCBidWRnZXQpO1xuICAgIGNvbnN0IHsgc2NvcGUsIGxhYmVsIH0gPSB0YXJnZXQ7XG4gICAgcHJvZ3Jlc3MoeyBzdGF0ZTogJ2xvYWRpbmcnLCBzY29wZSwgbGFiZWwsIHBsYW5lIH0pO1xuICAgIGNvbnN0IGNvdW50ID0gYXdhaXQgY291bnRUcmFuc2NyaXB0cyh7XG4gICAgICBwb3J0OiB0aGlzLnBvcnQsXG4gICAgICB0aWxlczogdGlsZXMudGlsZXMsXG4gICAgICBxdWFsaXR5LFxuICAgICAgZmlsdGVyLFxuICAgICAgYmFuZCxcbiAgICAgIG5hbWVzOiBtZXRhLmdlbmVzID8/IG51bGwsXG4gICAgICBjYW5jZWxsZWQsXG4gICAgICBwYXJ0aWFsOiB0aWxlcy5wYXJ0aWFsLFxuICAgIH0pO1xuICAgIGlmICghY291bnQpIHJldHVybiB7IHN0YXRlOiAnbG9hZGluZycgfTtcbiAgICByZXR1cm4geyBzdGF0ZTogJ3JlYWR5Jywgc2NvcGUsIGxhYmVsLCBwbGFuZSwgLi4uY291bnQgfTtcbiAgfVxuXG4gIC8qKiBUaGUgb2JzZXJ2YXRpb25zIG9mIHRoZSBzZWxlY3Rpb24sIGJ5IGdyb3VwIChzZWUge0BsaW5rIHNlbGVjdGlvbkNoYW5nZXMkfSkuICovXG4gIHByaXZhdGUgb2JzZXJ2YXRpb25zSW5TZWxlY3Rpb24kKCk6IE9ic2VydmFibGU8T2JzZXJ2YXRpb25zSW5TZWxlY3Rpb24+IHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3Rpb25DaGFuZ2VzJCgodikgPT4ge1xuICAgICAgY29uc3QgYnkgPSB2LmNvbG9yQnk/LmtpbmQgPT09ICdjb2x1bW4nID8gdi5jb2xvckJ5Lm5hbWUgOiAnJztcbiAgICAgIHJldHVybiBgJHtieX18JHt2LmNlbGxUeXBlQ29sdW1uID8/ICcnfXwke0pTT04uc3RyaW5naWZ5KHYuZ3JvdXBDb2xvcnMgPz8ge30pfWA7XG4gICAgfSkucGlwZShcbiAgICAgIHN3aXRjaE1hcCgoYWN0aXZlKSA9PlxuICAgICAgICB0aGlzLnJ1bkNhbmNlbGxhYmxlPE9ic2VydmF0aW9uc0luU2VsZWN0aW9uPihcbiAgICAgICAgICAocHJvZ3Jlc3MsIGNhbmNlbGxlZCkgPT4gdGhpcy5vYnNlcnZhdGlvbnNPZihhY3RpdmUsIHByb2dyZXNzLCBjYW5jZWxsZWQpLFxuICAgICAgICAgIChtZXNzYWdlKSA9PiAoeyBzdGF0ZTogJ2Vycm9yJywgbWVzc2FnZTogYFRoZSBvYnNlcnZhdGlvbnMgY291bGQgbm90IGJlIGxpc3RlZDogJHttZXNzYWdlfWAgfSksXG4gICAgICAgICksXG4gICAgICApLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIG9ic2VydmF0aW9ucyBvZiB0aGUgbGF0ZXN0IHNlbGVjdGlvbiBpbiBgYWN0aXZlYCwgYnkgdGhlIGdyb3VwaW5nIHRoZSBvYnNlcnZhdGlvbnMgYXJlXG4gICAqIGNvbG91cmVkIGJ5IChlbHNlIHRoZSBjZWxsIHR5cGVzKTogZXZlcnkgb25lIGluIHNwYXRpYWwgM0Q7IGluIDJELCB0aG9zZSBvbiB0aGUgcGxhbmUgc2hvd24gd2hlblxuICAgKiB0aGUgZGF0YXNldCdzIHBsYW5lcyBzbGljZSBpdC4gT25lIGNlbGwgaXMgZGVzY3JpYmVkIHRvbzogaXRzIGlkIGFuZCBpdHMgdmFsdWVzLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBvYnNlcnZhdGlvbnNPZihcbiAgICBhY3RpdmU6IHJlYWRvbmx5IFNlbGVjdGlvblNvdXJjZVtdLFxuICAgIHByb2dyZXNzOiAoc3RhdGU6IE9ic2VydmF0aW9uc0luU2VsZWN0aW9uKSA9PiB2b2lkLFxuICAgIGNhbmNlbGxlZDogKCkgPT4gYm9vbGVhbixcbiAgKTogUHJvbWlzZTxPYnNlcnZhdGlvbnNJblNlbGVjdGlvbj4ge1xuICAgIGNvbnN0IGRhdGFzZXQgPSB0aGlzLmRhdGFzZXQ7XG4gICAgaWYgKCFkYXRhc2V0KSByZXR1cm4geyBzdGF0ZTogJ2VtcHR5JywgbWVzc2FnZTogJ05vIGRhdGFzZXQgaXMgbG9hZGVkLicgfTtcbiAgICBjb25zdCBvYnMgPSBkYXRhc2V0Lm9ic2VydmF0aW9ucztcbiAgICBjb25zdCB0YXJnZXQgPSBhd2FpdCB0aGlzLnJlc29sdmVTZWxlY3Rpb24oZGF0YXNldCwgYWN0aXZlLCAhIW9icy56LCAnb2JzZXJ2YXRpb25zJyk7XG4gICAgaWYgKGNhbmNlbGxlZCgpKSByZXR1cm4geyBzdGF0ZTogJ2xvYWRpbmcnIH07XG4gICAgY29uc3QgeyBwbGFuZSwgYmFuZCwgcGxhbmVzIH0gPSB0YXJnZXQud2hlcmU7XG4gICAgaWYgKHRhcmdldC5raW5kID09PSAnZW1wdHknKSByZXR1cm4geyBzdGF0ZTogJ2VtcHR5JywgcGxhbmUsIG1lc3NhZ2U6IHRhcmdldC5tZXNzYWdlIH07XG4gICAgY29uc3QgeyBzY29wZSwgbGFiZWwgfSA9IHRhcmdldDtcbiAgICBwcm9ncmVzcyh7IHN0YXRlOiAnbG9hZGluZycsIHNjb3BlLCBsYWJlbCwgcGxhbmUgfSk7XG5cbiAgICBsZXQgbWFzazogVWludDhBcnJheTtcbiAgICBpZiAodGFyZ2V0LmtpbmQgPT09ICdjZWxscycpIHtcbiAgICAgIG1hc2sgPSB0YXJnZXQubWFzaztcbiAgICAgIGlmIChiYW5kICYmIG9icy56KSB7XG4gICAgICAgIC8vIE9uIHRoZSBwbGFuZSBzaG93bjogdGhlIGNlbGxzIHRoZSAyRCB2aWV3IGRyYXdzIHRoZXJlLlxuICAgICAgICBjb25zdCB6ID0gb2JzLno7XG4gICAgICAgIG1hc2sgPSBVaW50OEFycmF5LmZyb20odGFyZ2V0Lm1hc2ssIChtLCBpKSA9PiAobSAmJiBpbkJhbmQoeltpXSwgYmFuZCkgPyAxIDogMCkpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB2b2x1bWUgPSAhZGF0YXNldC5pbWFnZVJlZiA/IGRhdGFzZXQudm9sdW1lIDogdW5kZWZpbmVkO1xuICAgICAgY29uc3QgayA9IHRhcmdldC53aGVyZS5wbGFuZT8uaW5kZXggPz8gdGhpcy5jdHguekluZGV4KCk7XG4gICAgICBtYXNrID0gc2VsZWN0SW5SZWdpb25zKFxuICAgICAgICBvYnMsXG4gICAgICAgIHRhcmdldC5pbWFnZVJlZixcbiAgICAgICAgdGFyZ2V0LnJlZ2lvbnMsXG4gICAgICAgIHZvbHVtZVxuICAgICAgICAgID8gb2JzZXJ2YXRpb25zSW5TbGljZShvYnMsIHZvbHVtZSwgdGhpcy5jdHguekluZGV4KCkpXG4gICAgICAgICAgOiBwbGFuZXNcbiAgICAgICAgICAgID8gb2JzZXJ2YXRpb25zT25QbGFuZShvYnMsIHBsYW5lcywgaylcbiAgICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgKS5tYXNrO1xuICAgIH1cbiAgICBjb25zdCB2aWV3ID0gdGhpcy5jdHguc3RvcmUuY3VycmVudFNwYXRpYWxWaWV3KCk7XG4gICAgY29uc3QgbGlzdGVkID0gYXdhaXQgZGVzY3JpYmVPYnNlcnZhdGlvbnModGhpcy5wb3J0LCBkYXRhc2V0LCB2aWV3LCBtYXNrLCBPQlNFUlZBVElPTl9ERVRBSUxfQ09MVU1OUyk7XG4gICAgaWYgKGNhbmNlbGxlZCgpKSByZXR1cm4geyBzdGF0ZTogJ2xvYWRpbmcnIH07XG4gICAgcmV0dXJuIHsgc3RhdGU6ICdyZWFkeScsIHNjb3BlLCBsYWJlbCwgcGxhbmUsIC4uLmxpc3RlZCB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBjYXRlZ29yaWNhbCBjb2x1bW4gdGhlIHBpY2tlZCBjbGFzc2VzIGFyZSBjZWxsIHR5cGVzIG9mOiB0aGUgZGF0YXNldCdzIGNlbGwtdHlwZSBjb2x1bW5cbiAgICogd2hlbiBpdCBob2xkcyBhbnkgb2YgdGhlbSwgZWxzZSB0aGUgZmlyc3QgY2F0ZWdvcmljYWwgY29sdW1uIHRoYXQgZG9lczsgbnVsbCB3aGVuIG5vbmUgZG9lcy5cbiAgICovXG4gIHByaXZhdGUgY2VsbFR5cGVDb2x1bW5PZihkYXRhc2V0OiBTcGF0aWFsRGF0YXNldCwgY2xhc3NlczogcmVhZG9ubHkgc3RyaW5nW10pOiBzdHJpbmcgfCBudWxsIHtcbiAgICBpZiAoIWNsYXNzZXMubGVuZ3RoKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBjYXRlZ29yaWNhbCA9IGRhdGFzZXQuY29sdW1ucy5maWx0ZXIoKGMpOiBjIGlzIENhdGVnb3JpY2FsQ29sdW1uTWV0YSA9PiBjLmtpbmQgPT09ICdjYXRlZ29yaWNhbCcpO1xuICAgIGNvbnN0IGhvbGRzID0gKGM6IENhdGVnb3JpY2FsQ29sdW1uTWV0YSkgPT4gY2xhc3Nlcy5zb21lKChuYW1lKSA9PiBjLmNhdGVnb3JpZXMuaW5jbHVkZXMobmFtZSkpO1xuICAgIGNvbnN0IHByZWZlcnJlZCA9IGNlbGxUeXBlQ29sdW1uRm9yKGRhdGFzZXQsIHRoaXMuY3R4LnN0b3JlLmN1cnJlbnRTcGF0aWFsVmlldygpKTtcbiAgICBjb25zdCBmaXJzdCA9IGNhdGVnb3JpY2FsLmZpbmQoKGMpID0+IGMubmFtZSA9PT0gcHJlZmVycmVkICYmIGhvbGRzKGMpKSA/PyBjYXRlZ29yaWNhbC5maW5kKGhvbGRzKTtcbiAgICByZXR1cm4gZmlyc3Q/Lm5hbWUgPz8gbnVsbDtcbiAgfVxuXG4gIC8qKiBIb3cgZmFyIGZyb20gYSBjZWxsJ3MgY2VudHJlIGl0cyB0cmFuc2NyaXB0cyBhcmUgbG9va2VkIGZvciwgaW4gb2JzZXJ2YXRpb24gdW5pdHMuICovXG4gIHByaXZhdGUgY2VsbFJlYWNoKGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0KTogbnVtYmVyIHtcbiAgICBjb25zdCByZWYgPSBkYXRhc2V0LmltYWdlUmVmO1xuICAgIGNvbnN0IG1pY3JvbnNQZXJVbml0ID0gZGF0YXNldC5taWNyb25zUGVyVW5pdCA/PyAocmVmPy5tcHBYID8gcmVmLm1wcFggKiAocmVmLnNjYWxlPy5bMF0gPz8gMSkgOiB1bmRlZmluZWQpO1xuICAgIGlmIChtaWNyb25zUGVyVW5pdCAmJiBtaWNyb25zUGVyVW5pdCA+IDApIHJldHVybiBDRUxMX1JFQUNIX01JQ1JPTlMgLyBtaWNyb25zUGVyVW5pdDtcbiAgICByZXR1cm4gdHlwaWNhbENlbGxEaWFtZXRlcihkYXRhc2V0Lm9ic2VydmF0aW9ucy5yYWRpdXMpICogMztcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGQoKTogSVNwYXRpYWxDb250cm9scyB7XG4gICAgY29uc3QgcG9ydCA9IHRoaXMucG9ydDtcbiAgICByZXR1cm4ge1xuICAgICAgZ2V0RGF0YXNldCQ6ICgpID0+IHBvcnQuZ2V0RGF0YXNldCQoKSxcbiAgICAgIGdldFZpZXdTdGF0ZSQ6ICgpID0+IHRoaXMuY3R4LnN0b3JlLmdldFNwYXRpYWxWaWV3JCgpLFxuICAgICAgdmlld1N0YXRlOiAoKSA9PiB0aGlzLmN0eC5zdG9yZS5jdXJyZW50U3BhdGlhbFZpZXcoKSxcbiAgICAgIHNldFZpZXdTdGF0ZTogKHBhcnRpYWwpID0+IHRoaXMuY3R4LnN0b3JlLnNldFNwYXRpYWxWaWV3KHBhcnRpYWwpLFxuICAgICAgLy8gVGhlIGhpbnQgU0VFRFMgdGhlIHRvZ2dsZSB3aGVuIHRoZSBzb3VyY2UgY2hhbmdlcywgYW5kIG5vdGhpbmcgY29uc3VsdHMgaXRcbiAgICAgIC8vIGFmdGVyd2FyZHMuIEl0IHVzZWQgdG8gYmUgT1JlZCBpbiBhdCByZW5kZXIgdGltZSwgd2hpY2ggbWVhbnQgYW4gdW5jaGVja2VkXG4gICAgICAvLyBib3ggY291bGQgbm90IHR1cm4gbG9nIHNjYWxpbmcgb2ZmIGZvciBhIGhpbnRlZCBjb2x1bW4g4oCUIGFuZCB0aGUgbGlua2VkXG4gICAgICAvLyBjaGFydCwgd2hpY2ggcmVhZHMgYGxvZ1NjYWxlYCBhbG9uZSwgZGlzYWdyZWVkIHdpdGggdGhlIG1hcCBhYm91dCB3aGF0IGl0XG4gICAgICAvLyB3YXMgc2hvd2luZy4gT25lIGF1dGhvcml0eSwgc2V0IG9uY2UgcGVyIHNvdXJjZS5cbiAgICAgIGNvbG9yQnlDb2x1bW46IChuYW1lOiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3QgbWV0YSA9IHRoaXMuZGF0YXNldD8uY29sdW1ucy5maW5kKChjKSA9PiBjLm5hbWUgPT09IG5hbWUpO1xuICAgICAgICBjb25zdCBoaW50ID0gbWV0YT8ua2luZCA9PT0gJ2NvbnRpbnVvdXMnID8gISFtZXRhLmxvZ1NjYWxlSGludCA6IGZhbHNlO1xuICAgICAgICB0aGlzLmN0eC5zdG9yZS5zZXRTcGF0aWFsVmlldyh7IGNvbG9yQnk6IHsga2luZDogJ2NvbHVtbicsIG5hbWUgfSwgbG9nU2NhbGU6IGhpbnQgfSk7XG4gICAgICB9LFxuICAgICAgY29sb3JCeUZlYXR1cmU6IChuYW1lOiBzdHJpbmcpID0+XG4gICAgICAgIHRoaXMuY3R4LnN0b3JlLnNldFNwYXRpYWxWaWV3KHtcbiAgICAgICAgICBjb2xvckJ5OiB7IGtpbmQ6ICdmZWF0dXJlJywgbmFtZSB9LFxuICAgICAgICAgIGxvZ1NjYWxlOiAhIXRoaXMuZGF0YXNldD8uZmVhdHVyZXM/LmxvZ1NjYWxlSGludCxcbiAgICAgICAgfSksXG4gICAgICBjbGVhckNvbG9yQnk6ICgpID0+IHRoaXMuY3R4LnN0b3JlLnNldFNwYXRpYWxWaWV3KHsgY29sb3JCeTogbnVsbCB9KSxcbiAgICAgIHNlYXJjaEZlYXR1cmVzOiBhc3luYyAocXVlcnk6IHN0cmluZywgbGltaXQgPSA1MCkgPT4ge1xuICAgICAgICAvLyBQcmVmZXIgdGhlIHBvcnQncyBzZWFyY2ggKGEgMzFrLWdlbmUgZGF0YXNldCBkb2VzIG5vdCBzaGlwIGl0cyBuYW1lcyk7XG4gICAgICAgIC8vIG90aGVyd2lzZSBmaWx0ZXIgd2hhdGV2ZXIgdGhlIG1hbmlmZXN0IGlubGluZWQuXG4gICAgICAgIGlmIChwb3J0LnNlYXJjaEZlYXR1cmVzKSByZXR1cm4gcG9ydC5zZWFyY2hGZWF0dXJlcyhxdWVyeSwgbGltaXQpO1xuICAgICAgICBjb25zdCBkYXRhc2V0ID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20ocG9ydC5nZXREYXRhc2V0JCgpKTtcbiAgICAgICAgY29uc3QgbmFtZXMgPSBkYXRhc2V0Py5mZWF0dXJlcz8ubmFtZXMgPz8gW107XG4gICAgICAgIGNvbnN0IHEgPSBxdWVyeS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICByZXR1cm4gbmFtZXMuZmlsdGVyKChuKSA9PiBuLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMocSkpLnNsaWNlKDAsIGxpbWl0KTtcbiAgICAgIH0sXG4gICAgICAuLi4ocG9ydC5pbXBvcnRHcm91cHNcbiAgICAgICAgPyB7XG4gICAgICAgICAgICBpbXBvcnRHcm91cHM6IChsYWJlbDogc3RyaW5nLCB0YWJsZTogc3RyaW5nKSA9PiBwb3J0LmltcG9ydEdyb3VwcyEobGFiZWwsIHRhYmxlKSxcbiAgICAgICAgICB9XG4gICAgICAgIDoge30pLFxuICAgICAgLi4uKHBvcnQuZ2V0VHJhbnNjcmlwdENvdW50c1xuICAgICAgICA/IHtcbiAgICAgICAgICAgIHRyYW5zY3JpcHRDb3VudHM6IChnZW5lczogc3RyaW5nW10pID0+IHBvcnQuZ2V0VHJhbnNjcmlwdENvdW50cyEoZ2VuZXMpLFxuICAgICAgICAgIH1cbiAgICAgICAgOiB7fSksXG4gICAgICAuLi4ocG9ydC5nZXRNYXJrZXJHZW5lc1xuICAgICAgICA/IHtcbiAgICAgICAgICAgIG1hcmtlckdlbmVzOiAoY29sdW1uOiBzdHJpbmcsIHBlckdyb3VwPzogbnVtYmVyKSA9PiBwb3J0LmdldE1hcmtlckdlbmVzIShjb2x1bW4sIHBlckdyb3VwKSxcbiAgICAgICAgICB9XG4gICAgICAgIDoge30pLFxuICAgICAgZ2V0VHJhbnNjcmlwdEVzdGltYXRlJDogKCkgPT4gdGhpcy5jdHgubmFwYXJpLnRyYW5zY3JpcHRFc3RpbWF0ZSQuYXNPYnNlcnZhYmxlKCksXG4gICAgICBnZXRHZW5lQ291bnRzSW5WaWV3JDogKCkgPT4gdGhpcy5jdHgubmFwYXJpLmdlbmVDb3VudHNJblZpZXckLmFzT2JzZXJ2YWJsZSgpLFxuICAgICAgZ2V0RGVuc2l0eVN0YXRzJDogKCkgPT4gdGhpcy5jdHgubmFwYXJpLmRlbnNpdHlTdGF0cyQuYXNPYnNlcnZhYmxlKCksXG4gICAgICBnZXRHZW5lRmlsdGVyRmFpbGVkJDogKCkgPT4gdGhpcy5jdHgubmFwYXJpLmdlbmVGaWx0ZXJGYWlsZWQkPy5hc09ic2VydmFibGUoKSA/PyBvZihmYWxzZSksXG4gICAgICBnZXRDZWxsczNkU3RhdHVzJDogKCkgPT4gdGhpcy5jdHgubmFwYXJpLmNlbGxzM2RTdGF0dXMkPy5hc09ic2VydmFibGUoKSA/PyBvZihudWxsKSxcbiAgICAgIC4uLih0aGlzLmN0eC52aWV3Q2hhbmdlZCQgJiYgdGhpcy5jdHguc2xpY2VQbGFuZXNcbiAgICAgICAgPyB7XG4gICAgICAgICAgICBnZXRDZWxsczNkQXZhaWxhYmxlJDogKCkgPT5cbiAgICAgICAgICAgICAgdGhpcy5jdHgudmlld0NoYW5nZWQkIS5waXBlKFxuICAgICAgICAgICAgICAgIHN0YXJ0V2l0aChudWxsKSxcbiAgICAgICAgICAgICAgICBtYXAoKCkgPT4gISF0aGlzLmN0eC5zbGljZVBsYW5lcz8uKCk/Lmxlbmd0aCksXG4gICAgICAgICAgICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICB9XG4gICAgICAgIDoge30pLFxuICAgICAgLi4uKHBvcnQuZ2V0VHJhbnNjcmlwdFRpbGUgPyB7IGdldFRyYW5zY3JpcHRzSW5TZWxlY3Rpb24kOiAoKSA9PiB0aGlzLnRyYW5zY3JpcHRzSW5TZWxlY3Rpb24kKCkgfSA6IHt9KSxcbiAgICAgIGdldE9ic2VydmF0aW9uc0luU2VsZWN0aW9uJDogKCkgPT4gdGhpcy5vYnNlcnZhdGlvbnNJblNlbGVjdGlvbiQoKSxcbiAgICAgIGNhdGVnb3J5Q29sb3JzOiBhc3luYyAobmFtZTogc3RyaW5nKSA9PiB7XG4gICAgICAgIGNvbnN0IGNvbHVtbiA9IGF3YWl0IHBvcnQuZ2V0Q29sdW1uKG5hbWUpO1xuICAgICAgICBpZiAoIWlzQ2F0ZWdvcmljYWxDb2x1bW4oY29sdW1uKSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgW3NwYXRpYWxdIGNvbHVtbiBcIiR7bmFtZX1cIiBpcyBjb250aW51b3VzIOKAlCBpdCBoYXMgbm8gY2F0ZWdvcmllc2ApO1xuICAgICAgICB9XG4gICAgICAgIC8vIFJlc29sdmVkIGJ5IHRoZSBTQU1FIGZ1bmN0aW9uIHRoZSByZW5kZXJlciB1c2VzLCBzbyBhIGxlZ2VuZCBzd2F0Y2hcbiAgICAgICAgLy8gY2FuIG5ldmVyIGRpc2FncmVlIHdpdGggdGhlIGNvbG91ciBvbiBzY3JlZW4uXG4gICAgICAgIHJldHVybiBjYXRlZ29yeUNvbG9yc0ZvcihuYW1lLCBjb2x1bW4ubWV0YSwgdGhpcy5jdHguc3RvcmUuY3VycmVudFNwYXRpYWxWaWV3KCkuZ3JvdXBDb2xvcnMpO1xuICAgICAgfSxcblxuICAgICAgY29udGludW91c1ZhbHVlczogYXN5bmMgKHNvdXJjZSkgPT4ge1xuICAgICAgICBpZiAoc291cmNlLmtpbmQgPT09ICdmZWF0dXJlJykgcmV0dXJuIHBvcnQuZ2V0RmVhdHVyZVZlY3Rvcihzb3VyY2UubmFtZSk7XG4gICAgICAgIGNvbnN0IGNvbHVtbiA9IGF3YWl0IHBvcnQuZ2V0Q29sdW1uKHNvdXJjZS5uYW1lKTtcbiAgICAgICAgaWYgKGlzQ2F0ZWdvcmljYWxDb2x1bW4oY29sdW1uKSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgW3NwYXRpYWxdIGNvbHVtbiBcIiR7c291cmNlLm5hbWV9XCIgaXMgY2F0ZWdvcmljYWwg4oCUIGl0IGhhcyBubyB2YWx1ZXMgdG8gY2hhcnRgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY29sdW1uLnZhbHVlcztcbiAgICAgIH0sXG5cbiAgICAgIGNhdGVnb3JpY2FsVmlldzogYXN5bmMgKG5hbWU6IHN0cmluZykgPT4ge1xuICAgICAgICBjb25zdCBjb2x1bW4gPSBhd2FpdCBwb3J0LmdldENvbHVtbihuYW1lKTtcbiAgICAgICAgaWYgKCFpc0NhdGVnb3JpY2FsQ29sdW1uKGNvbHVtbikpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFtzcGF0aWFsXSBjb2x1bW4gXCIke25hbWV9XCIgaXMgY29udGludW91cyDigJQgaXQgaGFzIG5vIGNhdGVnb3JpZXNgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgY2F0ZWdvcmllczogY29sdW1uLm1ldGEuY2F0ZWdvcmllcyxcbiAgICAgICAgICBjb2xvcnM6IGNhdGVnb3J5Q29sb3JzRm9yKG5hbWUsIGNvbHVtbi5tZXRhLCB0aGlzLmN0eC5zdG9yZS5jdXJyZW50U3BhdGlhbFZpZXcoKS5ncm91cENvbG9ycyksXG4gICAgICAgICAgY29kZXM6IGNvbHVtbi5jb2RlcyxcbiAgICAgICAgfTtcbiAgICAgIH0sXG5cbiAgICAgIC8vIFNwcmVhZCByYXRoZXIgdGhhbiBhbHdheXMgZGVmaW5lZDogYGdldEVtYmVkZGluZ2AgaXMgb3B0aW9uYWwgb24gYm90aCB0aGUgcG9ydFxuICAgICAgLy8gYW5kIHRoaXMgZmFjYWRlLCBhbmQgYSBwYW5lbCBjaGVja3MgZm9yIGl0cyBwcmVzZW5jZSB0byBkZWNpZGUgd2hldGhlciB0aGUgdmlld1xuICAgICAgLy8gaXMgb2ZmZXJlZCBhdCBhbGwuIERlZmluaW5nIGl0IGFzIGEgZnVuY3Rpb24gdGhhdCByZWplY3RzIHdvdWxkIG1ha2UgYW5cbiAgICAgIC8vIGVtYmVkZGluZy1sZXNzIHNvdXJjZSBsb29rIGxpa2UgYSBicm9rZW4gb25lLlxuICAgICAgLi4uKHBvcnQuZ2V0RW1iZWRkaW5nID8geyBnZXRFbWJlZGRpbmc6IChuYW1lOiBzdHJpbmcpID0+IHBvcnQuZ2V0RW1iZWRkaW5nIShuYW1lKSB9IDoge30pLFxuXG4gICAgICBjYXRlZ29yaWNhbENvbHVtbnM6ICgpID0+XG4gICAgICAgICh0aGlzLmRhdGFzZXQ/LmNvbHVtbnMgPz8gW10pLmZpbHRlcigoYykgPT4gYy5raW5kID09PSAnY2F0ZWdvcmljYWwnKS5tYXAoKGMpID0+IGMubmFtZSksXG5cbiAgICAgIC8vIE1lbW9pemVkIG9uIHRoZSBvYnNlcnZhdGlvbnMgb2JqZWN0LCBzbyB0aGUgcmVuZGVyZXIncyBvd24gbG9va3VwIGFuZFxuICAgICAgLy8gdGhpcyBvbmUgYXJlIHRoZSBzYW1lIHNpbmdsZSBzY2FuIG9mIHVwIHRvIDMuN00geiB2YWx1ZXMuXG4gICAgICBzYW1wbGVkU2VjdGlvbnM6ICgpID0+IHtcbiAgICAgICAgY29uc3Qgb2JzID0gdGhpcy5kYXRhc2V0Py5vYnNlcnZhdGlvbnM7XG4gICAgICAgIHJldHVybiBvYnMgPyBzZWN0aW9uc09mKG9icykgOiBudWxsO1xuICAgICAgfSxcblxuICAgICAgZ2V0U2VsZWN0aW9uJDogKCkgPT4gdGhpcy5jdHguc2VsZWN0aW9uU3RvcmUuZ2V0U2VsZWN0aW9uJCgpLFxuXG4gICAgICBzZWxlY3RGcm9tUmVnaW9uczogYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBkYXRhc2V0ID0gdGhpcy5kYXRhc2V0O1xuICAgICAgICBpZiAoIWRhdGFzZXQpIHJldHVybiAwO1xuICAgICAgICBjb25zdCBpczNkID0gaXNTcGF0aWFsT21pY3MzZCh0aGlzLmN0eC5wbG90VHlwZSgpKTtcbiAgICAgICAgY29uc3Qgdm9sdW1lID0gIWRhdGFzZXQuaW1hZ2VSZWYgPyBkYXRhc2V0LnZvbHVtZSA6IHVuZGVmaW5lZDtcbiAgICAgICAgLy8gSW4gdGhlIDNEIGNsb3VkLCByZWdpb24gY2xhc3NlcyBwaWNrZWQgaW4gdGhlIFJlZ2lvbiBFZGl0b3IgKGEgY2xhc3NcbiAgICAgICAgLy8gdHJlZSBub2RlIHdpdGggaXRzIHN1YmNsYXNzZXMsIGEgc3VyZmFjZSBjbGlja2VkIGluIDNEKSBzZWxlY3QgdGhlXG4gICAgICAgIC8vIGNlbGxzIGluc2lkZSB0aGVpciB2b2x1bWVzIOKAlCB0aGUgc3RydWN0dXJlcyBzaG93biBhbW9uZyB0aGUgY2VsbHMuXG4gICAgICAgIGlmICh2b2x1bWUgJiYgdGhpcy5yb2lTZWxlY3Rpb25Nb2RlKCkgPT09ICdjbGFzcy12b2x1bWVzJykge1xuICAgICAgICAgIGNvbnN0IGNsYXNzZXMgPSB0aGlzLmN0eC5yZWdpb25TdG9yZS5nZXRQaWNrZWRDbGFzc2VzKCk7XG4gICAgICAgICAgY29uc3QgcmVxdWVzdCA9ICsrdGhpcy5yb2lSZXF1ZXN0O1xuICAgICAgICAgIGNvbnN0IHJldmlzaW9uID0gdGhpcy5jdHguc2VsZWN0aW9uU3RvcmUucmV2aXNpb24oKTtcbiAgICAgICAgICBjb25zdCBvdXRsaW5lcyA9IGF3YWl0IHRoaXMuY3R4LnJlZ2lvblN0b3JlLmNsYXNzU2xpY2VPdXRsaW5lcyhjbGFzc2VzKTtcbiAgICAgICAgICAvLyBTdXBlcnNlZGVkIHdoaWxlIHRoZSBvdXRsaW5lcyB3ZXJlIHJlYWQ6IGEgbmV3ZXIgcmVxdWVzdCwgYW55IG5ld2VyIHNlbGVjdGlvblxuICAgICAgICAgIC8vIChhIENsZWFyLCBhIGxlZ2VuZCBjbGljaywgYSBsaW5rZWQgY2hhcnQncyBicnVzaCksIGFub3RoZXIgZGF0YXNldCwgdmlldyBvciBwaWNrLFxuICAgICAgICAgIC8vIG9yIHRoZSBmYWNhZGUgZGlzcG9zZWQuIEl0cyBtYXNrIHdvdWxkIG92ZXJ3cml0ZSB3aGF0IHRoZSB1c2VyIGRpZCBzaW5jZS5cbiAgICAgICAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5jdHgucmVnaW9uU3RvcmUuZ2V0UGlja2VkQ2xhc3NlcygpO1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHJlcXVlc3QgIT09IHRoaXMucm9pUmVxdWVzdCB8fFxuICAgICAgICAgICAgcmV2aXNpb24gIT09IHRoaXMuY3R4LnNlbGVjdGlvblN0b3JlLnJldmlzaW9uKCkgfHxcbiAgICAgICAgICAgIHRoaXMuZGF0YXNldCAhPT0gZGF0YXNldCB8fFxuICAgICAgICAgICAgdGhpcy5yb2lTZWxlY3Rpb25Nb2RlKCkgIT09ICdjbGFzcy12b2x1bWVzJyB8fFxuICAgICAgICAgICAgY3VycmVudC5sZW5ndGggIT09IGNsYXNzZXMubGVuZ3RoIHx8XG4gICAgICAgICAgICBjdXJyZW50LnNvbWUoKGMsIGkpID0+IGMgIT09IGNsYXNzZXNbaV0pXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3Qgc2VsZWN0aW9uID0gc2VsZWN0SW5DbGFzc1ZvbHVtZXMoZGF0YXNldC5vYnNlcnZhdGlvbnMsIHZvbHVtZSwgb3V0bGluZXMpO1xuICAgICAgICAgIHRoaXMuY3R4LnNlbGVjdGlvblN0b3JlLnNldChzZWxlY3Rpb24pO1xuICAgICAgICAgIHJldHVybiBzZWxlY3Rpb24uY291bnQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gT3RoZXJ3aXNlIHRoZSB1bmlvbiBvZiBldmVyeSBkcmF3biByZWdpb24g4oCUIHNvIGV2ZXJ5IFJPSSB0b29sIHRoZVxuICAgICAgICAvLyBsaWJyYXJ5IGFscmVhZHkgaGFzIGRvdWJsZXMgYXMgYSBzcGF0aWFsIHNlbGVjdGlvbiB0b29sLlxuICAgICAgICAvL1xuICAgICAgICAvLyBJbiB0aGUgM0QgY2xvdWQgdGhlcmUgaXMgbm8gZGF0YS1zcGFjZSBhZmZpbmUgdG8gcHVzaCBhIGRyYXduIHNoYXBlXG4gICAgICAgIC8vIHRocm91Z2gsIHNvIHRoZSBvYnNlcnZhdGlvbnMgYXJlIHByb2plY3RlZCB0byBjYW52YXMgcGl4ZWxzIGJ5IHRoZVxuICAgICAgICAvLyByZW5kZXJlciAod2hpY2ggb3ducyB0aGUgY2FtZXJhKSBhbmQgdGVzdGVkIGluIHNjcmVlbiBzcGFjZSBpbnN0ZWFkIOKAlFxuICAgICAgICAvLyBhZ2FpbnN0IHRoZSBsYXNzb3MgZHJhd24gdGhlcmUgb25seTogZXZlcnkgb3RoZXIgcmVnaW9uIGlzIGluIGltYWdlXG4gICAgICAgIC8vIHNwYWNlLiBGYWxscyBiYWNrIHRvIHRoZSAyRCBwYXRoIHdoZW5ldmVyIHRoZSBjbG91ZCBpcyBub3QgbW91bnRlZC5cbiAgICAgICAgY29uc3QgcHJvamVjdGVkID0gaXMzZCA/IHRoaXMuY3R4Lm5hcGFyaS5nZXRTcGF0aWFsU2NyZWVuUHJvamVjdGlvbihkYXRhc2V0Lm9ic2VydmF0aW9ucykgOiBudWxsO1xuICAgICAgICBsZXQgc2VsZWN0aW9uOiBTcGF0aWFsU2VsZWN0aW9uTWFzaztcbiAgICAgICAgaWYgKHByb2plY3RlZCkge1xuICAgICAgICAgIGNvbnN0IGxhc3NvcyA9IG5ldyBTZXQodGhpcy5jdHgubmFwYXJpLmdldFNwYXRpYWxMYXNzb0lkcygpKTtcbiAgICAgICAgICBjb25zdCByZWdpb25zID0gdGhpcy5jdHgucmVnaW9uU3RvcmUuZ2V0UmVnaW9ucygpLmZpbHRlcigocikgPT4gbGFzc29zLmhhcyhyLmlkKSk7XG4gICAgICAgICAgc2VsZWN0aW9uID0gc2VsZWN0SW5SZWdpb25zUHJvamVjdGVkKHByb2plY3RlZCwgZGF0YXNldC5vYnNlcnZhdGlvbnMuY291bnQsIHJlZ2lvbnMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIEluIHRoZSAyRCB2aWV3IG9mIGEgdm9sdW1lLWJhY2tlZCBkYXRhc2V0IHRoZSBzaGFwZSB3YXMgZHJhd24gb3ZlciBPTkVcbiAgICAgICAgICAvLyBzZWN0aW9uLCBpbiB0aGUgdm9sdW1lJ3MgcGl4ZWwgZ3JpZDogaXQgc2VsZWN0cyB0aGUgY2VsbHMgb2YgdGhhdFxuICAgICAgICAgIC8vIHNlY3Rpb24sIG5vdCB0aGUgd2hvbGUgZGVwdGggb2YgYnJhaW4gc3RhbmRpbmcgYmVoaW5kIHRoZW0uIExpa2V3aXNlIG92ZXJcbiAgICAgICAgICAvLyBvbmUgb2YgYSByZWdpb24gc2V0J3MgcGxhbmVzOiB0aGUgY2VsbHMgbmVhcmVzdCBpdC5cbiAgICAgICAgICBjb25zdCBwbGFuZXMgPSAhdm9sdW1lID8gdGhpcy5jdHgucGxhbmVzPy4oKSA6IG51bGw7XG4gICAgICAgICAgc2VsZWN0aW9uID0gc2VsZWN0SW5SZWdpb25zKFxuICAgICAgICAgICAgZGF0YXNldC5vYnNlcnZhdGlvbnMsXG4gICAgICAgICAgICB2b2x1bWUgPyB2b2x1bWVJbWFnZVJlZih2b2x1bWUsIGRhdGFzZXQubWljcm9uc1BlclVuaXQpIDogZGF0YXNldC5pbWFnZVJlZixcbiAgICAgICAgICAgIHRoaXMuY3R4LnJlZ2lvblN0b3JlLmdldFJlZ2lvbnMoKSxcbiAgICAgICAgICAgIHZvbHVtZVxuICAgICAgICAgICAgICA/IG9ic2VydmF0aW9uc0luU2xpY2UoZGF0YXNldC5vYnNlcnZhdGlvbnMsIHZvbHVtZSwgdGhpcy5jdHguekluZGV4KCkpXG4gICAgICAgICAgICAgIDogcGxhbmVzXG4gICAgICAgICAgICAgICAgPyBvYnNlcnZhdGlvbnNPblBsYW5lKGRhdGFzZXQub2JzZXJ2YXRpb25zLCBwbGFuZXMsIHRoaXMuY3R4LnpJbmRleCgpKVxuICAgICAgICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jdHguc2VsZWN0aW9uU3RvcmUuc2V0KHNlbGVjdGlvbik7XG4gICAgICAgIHJldHVybiBzZWxlY3Rpb24uY291bnQ7XG4gICAgICB9LFxuXG4gICAgICByb2lTZWxlY3Rpb25Nb2RlOiAoKSA9PiB0aGlzLnJvaVNlbGVjdGlvbk1vZGUoKSxcblxuICAgICAgZ2V0UGlja2VkUmVnaW9uQ2xhc3NlcyQ6ICgpID0+IHRoaXMuY3R4LnJlZ2lvblN0b3JlLmdldFBpY2tlZENsYXNzZXMkKCksXG5cbiAgICAgIHNlbGVjdENhdGVnb3J5OiBhc3luYyAoY29sdW1uOiBzdHJpbmcsIGNhdGVnb3J5SW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICBjb25zdCBsb2FkZWQgPSBhd2FpdCBwb3J0LmdldENvbHVtbihjb2x1bW4pO1xuICAgICAgICBpZiAoIWlzQ2F0ZWdvcmljYWxDb2x1bW4obG9hZGVkKSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgW3NwYXRpYWxdIGNvbHVtbiBcIiR7Y29sdW1ufVwiIGlzIGNvbnRpbnVvdXMg4oCUIGl0IGhhcyBubyBjYXRlZ29yaWVzYCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc2VsZWN0aW9uID0gc2VsZWN0QnlDYXRlZ29yeShsb2FkZWQuY29kZXMsIGNhdGVnb3J5SW5kZXgpO1xuICAgICAgICB0aGlzLmN0eC5zZWxlY3Rpb25TdG9yZS5zZXQoc2VsZWN0aW9uKTtcbiAgICAgICAgcmV0dXJuIHNlbGVjdGlvbi5jb3VudDtcbiAgICAgIH0sXG5cbiAgICAgIHNlbGVjdEluZGljZXM6IChpbmRpY2VzOiBJdGVyYWJsZTxudW1iZXI+KSA9PiB7XG4gICAgICAgIGNvbnN0IGNvdW50ID0gdGhpcy5kYXRhc2V0Py5vYnNlcnZhdGlvbnMuY291bnQgPz8gMDtcbiAgICAgICAgaWYgKGNvdW50ID09PSAwKSByZXR1cm4gMDtcbiAgICAgICAgY29uc3Qgc2VsZWN0aW9uID0gc2VsZWN0QnlJbmRpY2VzKGluZGljZXMsIGNvdW50KTtcbiAgICAgICAgdGhpcy5jdHguc2VsZWN0aW9uU3RvcmUuc2V0KHNlbGVjdGlvbik7XG4gICAgICAgIHJldHVybiBzZWxlY3Rpb24uY291bnQ7XG4gICAgICB9LFxuXG4gICAgICBjbGVhclNlbGVjdGlvbjogKCkgPT4gdGhpcy5jdHguc2VsZWN0aW9uU3RvcmUuY2xlYXIoKSxcbiAgICB9O1xuICB9XG59XG5cbi8qKlxuICogV2hldGhlciBgZGF0YXNldGAgY2FuIGFuc3dlciB0aGlzIGNvbG91ciBzb3VyY2UuIEEgY29sdW1uIGlzIGNoZWNrYWJsZSBhZ2FpbnN0IHRoZVxuICogZGVjbGFyZWQgbGlzdC4gQSBnZW5lIGlzIGNoZWNrYWJsZSBvbmx5IHdoZW4gdGhlIGRhdGFzZXQgaW5saW5lcyBpdHMgZmVhdHVyZSBuYW1lcyDigJRcbiAqIGEgZGF0YXNldCB0b28gd2lkZSB0byBpbmxpbmUgdGhlbSAodHlwZWFoZWFkLW9ubHkpIGtlZXBzIHRoZSBzb3VyY2UsIGFuZCBhIG5hbWUgdGhhdFxuICogdHVybnMgb3V0IG5vdCB0byBleGlzdCBzdXJmYWNlcyBhcyB0aGUgY2hhcnQncyBcImNvdWxkIG5vdCBiZSBjaGFydGVkXCIgcmF0aGVyIHRoYW4gYXNcbiAqIGEgc2lsZW50IHJlc2V0LlxuICovXG5mdW5jdGlvbiBjYW5Db2xvckJ5KGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0IHwgbnVsbCwgYnk6IFNwYXRpYWxDb2xvckJ5KTogYm9vbGVhbiB7XG4gIGlmICghZGF0YXNldCkgcmV0dXJuIGZhbHNlO1xuICBpZiAoYnkua2luZCA9PT0gJ2NvbHVtbicpIHJldHVybiBkYXRhc2V0LmNvbHVtbnMuc29tZSgoYykgPT4gYy5uYW1lID09PSBieS5uYW1lKTtcbiAgY29uc3QgbmFtZXMgPSBkYXRhc2V0LmZlYXR1cmVzPy5uYW1lcztcbiAgcmV0dXJuICEhZGF0YXNldC5mZWF0dXJlcyAmJiAoIW5hbWVzIHx8IG5hbWVzLmluY2x1ZGVzKGJ5Lm5hbWUpKTtcbn1cbiJdfQ==