@jax-data-science/sci-image-visualizer 0.3.3 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/README.md +268 -4
  2. package/esm2022/index.mjs +21 -1
  3. package/esm2022/lib/contracts/display-types.mjs +20 -2
  4. package/esm2022/lib/contracts/image.contract.mjs +1 -1
  5. package/esm2022/lib/contracts/plot-type-contribution.contract.mjs +66 -0
  6. package/esm2022/lib/contracts/plot-type.mjs +41 -1
  7. package/esm2022/lib/contracts/ports/spatial-data.port.mjs +3 -0
  8. package/esm2022/lib/contracts/spatial-dataset.contract.mjs +45 -0
  9. package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
  10. package/esm2022/lib/implementations/napari-js/napari-axes-labels.mjs +10 -19
  11. package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +71 -7
  12. package/esm2022/lib/implementations/napari-js/napari-scale-bar.mjs +1 -1
  13. package/esm2022/lib/implementations/napari-js/napari-spatial-tooltip.mjs +96 -0
  14. package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +1934 -55
  15. package/esm2022/lib/implementations/napari-js/napari-zoom.mjs +18 -0
  16. package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +73 -8
  17. package/esm2022/lib/implementations/osd/osd-coordinate-transform.mjs +8 -1
  18. package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +3 -4
  19. package/esm2022/lib/implementations/osd/osd-zoom.mjs +20 -0
  20. package/esm2022/lib/implementations/plotly/omics-trace-builders.mjs +555 -0
  21. package/esm2022/lib/implementations/plotly/plotly.service.mjs +13 -7
  22. package/esm2022/lib/implementations/spatial-data-http/spatial-data-http.service.mjs +304 -0
  23. package/esm2022/lib/implementations/spatial-data-http/spatial-wire.mjs +179 -0
  24. package/esm2022/lib/plot-mode/plot-mode-controller.mjs +329 -0
  25. package/esm2022/lib/routing-visualizer.service.mjs +228 -12
  26. package/esm2022/lib/spatial/embedding-compute.mjs +142 -0
  27. package/esm2022/lib/spatial/gene-search.mjs +77 -0
  28. package/esm2022/lib/spatial/spatial-density.mjs +224 -0
  29. package/esm2022/lib/spatial/spatial-encoding.mjs +232 -0
  30. package/esm2022/lib/spatial/spatial-expression.mjs +257 -0
  31. package/esm2022/lib/spatial/spatial-framing.mjs +60 -0
  32. package/esm2022/lib/spatial/spatial-heatmap.mjs +185 -0
  33. package/esm2022/lib/spatial/spatial-hover.mjs +79 -0
  34. package/esm2022/lib/spatial/spatial-sections.mjs +96 -0
  35. package/esm2022/lib/spatial/spatial-selection.mjs +264 -0
  36. package/esm2022/lib/spatial/spatial-volume-image.mjs +163 -0
  37. package/esm2022/lib/spatial/tsne-worker.mjs +10 -0
  38. package/esm2022/lib/spatial/world-grid.mjs +77 -0
  39. package/esm2022/lib/spatial-controls/spatial-charts/spatial-charts.component.mjs +1278 -0
  40. package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +621 -0
  41. package/esm2022/lib/store/spatial-selection.service.mjs +47 -0
  42. package/esm2022/lib/store/visualizer-store.service.mjs +23 -1
  43. package/esm2022/lib/toolbar/toolbar.component.mjs +61 -21
  44. package/esm2022/lib/visualization.module.mjs +23 -5
  45. package/esm2022/lib/visualizer.component.mjs +527 -44
  46. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-ci1q0xnJ.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-BwP-A11m.mjs} +6 -4
  47. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-ci1q0xnJ.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-BwP-A11m.mjs.map} +1 -1
  48. package/fesm2022/jax-data-science-sci-image-visualizer-tsne-worker-B_nXDGf0.mjs +12 -0
  49. package/fesm2022/jax-data-science-sci-image-visualizer-tsne-worker-B_nXDGf0.mjs.map +1 -0
  50. package/fesm2022/jax-data-science-sci-image-visualizer.mjs +15971 -7808
  51. package/fesm2022/jax-data-science-sci-image-visualizer.mjs.map +1 -1
  52. package/fesm2022/tsne.worker.js +19091 -0
  53. package/index.d.ts +16 -0
  54. package/lib/contracts/display-types.d.ts +131 -0
  55. package/lib/contracts/image.contract.d.ts +7 -0
  56. package/lib/contracts/plot-type-contribution.contract.d.ts +172 -0
  57. package/lib/contracts/plot-type.d.ts +52 -2
  58. package/lib/contracts/ports/spatial-data.port.d.ts +90 -0
  59. package/lib/contracts/spatial-dataset.contract.d.ts +281 -0
  60. package/lib/contracts/visualizer.contract.d.ts +104 -1
  61. package/lib/implementations/napari-js/napari-axes-labels.d.ts +9 -7
  62. package/lib/implementations/napari-js/napari-region-overlay.d.ts +38 -4
  63. package/lib/implementations/napari-js/napari-scale-bar.d.ts +7 -3
  64. package/lib/implementations/napari-js/napari-spatial-tooltip.d.ts +32 -0
  65. package/lib/implementations/napari-js/napari-visualizer.service.d.ts +497 -16
  66. package/lib/implementations/napari-js/napari-zoom.d.ts +15 -0
  67. package/lib/implementations/osd/openseadragon-visualizer.service.d.ts +21 -0
  68. package/lib/implementations/osd/osd-coordinate-transform.d.ts +6 -0
  69. package/lib/implementations/osd/osd-zoom.d.ts +19 -0
  70. package/lib/implementations/plotly/omics-trace-builders.d.ts +193 -0
  71. package/lib/implementations/plotly/plotly.service.d.ts +9 -0
  72. package/lib/implementations/spatial-data-http/spatial-data-http.service.d.ts +123 -0
  73. package/lib/implementations/spatial-data-http/spatial-wire.d.ts +115 -0
  74. package/lib/plot-mode/plot-mode-controller.d.ts +130 -0
  75. package/lib/routing-visualizer.service.d.ts +49 -6
  76. package/lib/spatial/embedding-compute.d.ts +73 -0
  77. package/lib/spatial/gene-search.d.ts +48 -0
  78. package/lib/spatial/spatial-density.d.ts +73 -0
  79. package/lib/spatial/spatial-encoding.d.ts +155 -0
  80. package/lib/spatial/spatial-expression.d.ts +144 -0
  81. package/lib/spatial/spatial-framing.d.ts +37 -0
  82. package/lib/spatial/spatial-heatmap.d.ts +111 -0
  83. package/lib/spatial/spatial-hover.d.ts +49 -0
  84. package/lib/spatial/spatial-sections.d.ts +59 -0
  85. package/lib/spatial/spatial-selection.d.ts +113 -0
  86. package/lib/spatial/spatial-volume-image.d.ts +67 -0
  87. package/lib/spatial/tsne-worker.d.ts +7 -0
  88. package/lib/spatial/world-grid.d.ts +58 -0
  89. package/lib/spatial-controls/spatial-charts/spatial-charts.component.d.ts +439 -0
  90. package/lib/spatial-controls/spatial-controls.component.d.ts +257 -0
  91. package/lib/store/spatial-selection.service.d.ts +27 -0
  92. package/lib/store/visualizer-store.service.d.ts +13 -0
  93. package/lib/toolbar/toolbar.component.d.ts +36 -8
  94. package/lib/visualization.module.d.ts +28 -24
  95. package/lib/visualizer.component.d.ts +139 -7
  96. package/package.json +6 -2
  97. package/src/lib/assets/spatial-omics-3d.svg +31 -0
  98. package/src/lib/assets/spatial-omics.svg +27 -0
package/README.md CHANGED
@@ -83,7 +83,7 @@ full walkthrough (adapters, TIFF handling, the Angular-17 toolchain note).
83
83
  one `IVisualizer` contract; the host picks per plot type via `RoutingVisualizerService`.
84
84
  - **Plot types** — Image (OSD), Plotly (Heatmap, Contour, Scatter 2D, Surface 3D,
85
85
  Scatter 3D, Isosurface), and napari · WebGPU (Image, Scatter 2D, Surface,
86
- Scatter 3D, Volume, Isosurface).
86
+ Scatter 3D, Volume, Isosurface, **Spatial omics**, **Spatial omics 3D**).
87
87
  - **Region / annotation tools** — selection, rectangle, polyline, freeform,
88
88
  polygon + vertex editing, move, Bézier↔polygon, magic wand, brush, vertex eraser.
89
89
  - **Channels & histogram** — brightness/contrast/gamma, per-channel display,
@@ -143,7 +143,8 @@ data as you zoom in:
143
143
  ### napari-js — WebGPU
144
144
  GPU-accelerated renderings via [napari-js](https://www.npmjs.com/package/napari-js)
145
145
  (WebGPU), selectable from the plot-type menu as the "napari · WebGPU" variants of
146
- Image, Scatter 2D, Surface, Scatter 3D, **Volume**, and **Isosurface**. It
146
+ Image, Scatter 2D, Surface, Scatter 3D, **Volume**, **Isosurface**, and the two
147
+ spatial-omics modes ([below](#spatial-omics)). It
147
148
  assembles the volume from the slice endpoints with a runtime **decimate factor**
148
149
  (resolution slider, default ½), a surface **wireframe** toggle, a 3D **axes / scale
149
150
  gizmo**, an in-view **Z-height drag handle** for the volume, **cancellable** loading,
@@ -151,8 +152,16 @@ and **multichannel volume** compositing (one additive tinted layer per channel).
151
152
  Regions and display options stay in sync with the other backends via the shared
152
153
  stores.
153
154
 
154
- When a stack is open, a slice slider (Image view) or single-image/stack toggle
155
- (other views) navigates the z-dimension. A stack may be one server-tiled file
155
+ Volume and Isosurface take their voxels from the **image stack**, and only from
156
+ it — there is one voxel path, so a dataset reaches those modes by being a stack.
157
+ A stack that declares its slice spacing (`imageMeta[0].mppZ`, alongside
158
+ `mppX`/`mppY`) is rendered at its **true physical extent**, so 40 × 40 × 200 µm
159
+ voxels read as anatomy rather than as a cube-aspect brick, and the axis labels
160
+ read in real units on all three axes. Without it the world box is
161
+ resolution-invariant but shape-only, and Z is labelled in slices.
162
+
163
+ When a stack is open, a slice slider (Image view, and the 2D Spatial omics view)
164
+ or single-image/stack toggle (other views) navigates the z-dimension. A stack may be one server-tiled file
156
165
  (internal z) or a set of self-contained per-slice URLs (`IImageInfo.tiled ===
157
166
  false`) — the latter (e.g. a host-assembled folder of numbered files) fetches
158
167
  `urls[z]` per slice on demand. For a per-slice stack the host can also supply a
@@ -164,6 +173,187 @@ A line-ROI tool draws coloured lines and plots intensity along each one in a liv
164
173
  floating inset chart that re-samples at the current zoom. It works today but the
165
174
  API/UX are still stabilizing (see [In progress / roadmap](#in-progress--roadmap)).
166
175
 
176
+ ## Spatial omics
177
+
178
+ Contracts for **spatial-omics datasets**: N observations (Visium spots,
179
+ segmented cells) positioned in a tissue image's pixel space, each carrying
180
+ categorical and continuous annotations plus a lazily-fetched feature (gene)
181
+ matrix.
182
+
183
+ ```ts
184
+ import {
185
+ SPATIAL_DATA_PORT, SpatialDataHttpService, SpatialDataset,
186
+ } from '@jax-data-science/sci-image-visualizer';
187
+
188
+ providers: [
189
+ SpatialDataHttpService,
190
+ { provide: SPATIAL_DATA_PORT, useExisting: SpatialDataHttpService },
191
+ ]
192
+ ```
193
+
194
+ Like `TILE_ACCESS_PORT`, this is a **port**: the library consumes typed arrays
195
+ and never learns how the data is stored. `SpatialDataHttpService` is an optional
196
+ reference adapter for the format the bundled example server speaks; a host with
197
+ its own backend implements `SpatialDataPort` instead and imports neither.
198
+
199
+ Two properties the design turns on:
200
+
201
+ - **Metadata is eager, values are lazy.** A `SpatialDataset` holds coordinates
202
+ plus column and feature *descriptors*; vectors arrive one at a time, for the
203
+ one column or gene being displayed. A Visium table is ~31k genes wide — the
204
+ dense matrix is ~800 MB — so loading a dataset can never mean loading its
205
+ matrix.
206
+ - **Struct-of-arrays, not object-per-cell.** Datasets run 10³ (Visium) to 10⁶
207
+ (Xenium/CosMx) observations; two `Float32Array`s beat 500k `{x, y}` objects
208
+ and upload to the GPU without a copy.
209
+
210
+ Once a dataset is published, the spatial plot types appear in the selector (and
211
+ disappear when it is cleared — the same gating that hides Volume without a
212
+ z-stack):
213
+
214
+ - **Spatial omics** — one marker per observation over the tissue image the
215
+ coordinates live in, positioned through `imageRef`'s affine.
216
+ - **Spatial omics 3D** — gated additionally on the observations carrying a `z`
217
+ (`requiresSpatial3d`): the same observations as a point cloud under an orbit
218
+ camera, inside the dataset's reference volume if it has one.
219
+
220
+ **A dataset whose 3D data is one file gets an image made from it.** A registered
221
+ volume (`SpatialDataset.volume` + `SpatialDataPort.getVolume()`) is published *as*
222
+ a grayscale z-stack image — one plane per slice, opened mid-volume — so the whole
223
+ image surface applies to it: the toolbar slice slider, the contrast window,
224
+ colormaps, the region tools, the physical scale bar, and Volume / Isosurface
225
+ through the ordinary stack path. In the 2D mode the displayed plane then draws
226
+ **that plane's** observations over that plane's anatomy, in the volume's own pixel
227
+ grid, and a region drawn there selects that plane's cells rather than the whole
228
+ depth behind them.
229
+
230
+ **Cluster density volumes** *(3D mode, optional)* — a checkbox that raymarches
231
+ each cluster as a smooth density field beside the cloud, tinted with its legend
232
+ colour and blended additively. Serial sections hundreds of microns apart cannot be
233
+ read as an anatomical distribution from points alone: the eye will not integrate a
234
+ stack of discs into a shape, and every gap between sections reads as absence.
235
+ Individual cells are never interpolated — consecutive sections sample different
236
+ cells, so there is nothing to interpolate along — but a density *field* is an
237
+ estimate legitimately defined between the imaged planes, and it renders as a
238
+ translucent cloud so it cannot be mistaken for measurement. The kernel is
239
+ anisotropic (σ along z clears one section gap) and the field is coverage-normalised
240
+ along z, so unimaged planes do not read as empty tissue.
241
+
242
+ In **3D** the same `Gene map` checkbox draws one field per imaged section, at its
243
+ own depth, with the gaps between sections empty — the measured slides, stacked.
244
+ `One map section at a time` isolates a single sheet (its own control, separate from
245
+ the cloud's, so every combination stays reachable), and `Volume rendering
246
+ (interpolate along z)` smooths the sheets into a continuous volume. The last is a
247
+ different object and the panel labels it as one: the planes between sections then
248
+ carry an estimate smoothed from their neighbours' mean, nothing is drawn past the
249
+ outermost section, and the section restriction is ignored because a volume built
250
+ from one slide would smear it through the whole specimen. It is estimated on the
251
+ reference volume's lattice — coarsened in-plane but never along z, so one plane is
252
+ one section — and shares the 2D map's bandwidth, window and colormap.
253
+
254
+ **Show** *(3D mode)* — the reference volume, the observation cloud and the cluster
255
+ density volumes share one space, so any two of them hide each other; 374k points
256
+ drawn as a stack of discs hide the density volumes almost entirely. Each is
257
+ toggled independently, so every combination is reachable — the estimated fields
258
+ alone, the fields with the anatomy behind them, the anatomy on its own. These are
259
+ visibility only: the layers stay built, so a toggle never re-fetches the template
260
+ or re-rasterises a field, and none of them re-frames the orbit camera. (The
261
+ density checkbox is the exception and still gates construction, since building six
262
+ volumes is not free.) **Volume opacity** is the backdrop's own slider, separate
263
+ from the markers': reading the cloud or a density field *through* the anatomy
264
+ means turning the anatomy down, not the data over it. **One section at a time** restricts the cloud to a single
265
+ imaged section, which is how you check whether the estimated field follows the
266
+ cells that were actually measured. Sections are the distinct z of the
267
+ observations — every cell on a slide shares that slide's registered z, so no
268
+ section-label column is needed — and a dataset whose z is continuous rather than
269
+ sectioned is offered no section control instead of having one invented for it.
270
+
271
+ **Hover and click** — hovering an observation names it in a cursor tooltip: the
272
+ class for a categorical column, the value with its unit for a gene or numeric one,
273
+ and nothing at all when no colour source is set (there is no cluster to name).
274
+ Clicking a marker selects that whole class, the same selection the legend's rows
275
+ produce, and clicking it again clears. Because a click means "select" here,
276
+ napari's click-to-zoom is off in the spatial modes — the wheel, the zoom buttons
277
+ and the zoom-box tool still zoom. A gene cannot be clicked to select: no set of
278
+ cells "is" a value.
279
+
280
+ **Colormap** *(continuous colouring)* — the low→high gradient for a gene or a
281
+ numeric column, chosen from the library's own `COLORMAP_OPTIONS` with the same
282
+ swatch previews the image's colormap picker uses. It defaults to following the
283
+ image's colormap (with a Viridis fallback, since a grey measurement over grey
284
+ anatomy cannot be told apart from it), and clearing the picker returns to that.
285
+ One setting drives the markers, both gene maps and the panel's colour bar, so none
286
+ of them can disagree about what a colour means.
287
+
288
+ **Gene map** *(2D mode, optional, with a gene selected)* — a checkbox that draws
289
+ the selected gene's expression as a smooth field *beneath* the cells. Coloured
290
+ markers answer "which cells express this gene"; they do not answer "where is it
291
+ expressed", because the eye cannot integrate thousands of small dots into a
292
+ territory. The field is the kernel-weighted **mean per cell, not a sum** — a sum
293
+ would make a crowded region glow whatever its cells were doing — and smoothing the
294
+ numerator and denominator together spreads *where*, not *how much*. That
295
+ denominator is also what lets the layer say nothing: where no cell was measured the
296
+ mean is undefined rather than zero, so those pixels stay fully transparent instead
297
+ of taking the colormap's low end, and alpha ramps with local support so a thinly
298
+ sampled pixel reads as tentative. `Smoothing` sets the kernel σ; `Map opacity` is
299
+ the field's own opacity, separate from the markers' — turn the markers down to read
300
+ the field under them. On a volume-backed dataset the field is re-estimated per
301
+ plane from that plane's cells.
302
+
303
+ Colour it through `getSpatialControls()`:
304
+
305
+ ```ts
306
+ const controls = viz.getSpatialControls(); // null unless a port is bound
307
+ controls?.colorByColumn('region'); // categorical -> the column's palette
308
+ controls?.colorByFeature('Ttr'); // gene -> colormap, log, percentile-clipped
309
+ controls?.setViewState({ pointScale: 2 });
310
+ ```
311
+
312
+ The view state lives in the shared store, so the controls work before any
313
+ backend has mounted and survive a plot-type switch.
314
+
315
+ The [example server](examples/tile-server/README.md#spatial-omics-endpoints)
316
+ implements the endpoints, and `npm run make-spatial-demo` generates a synthetic
317
+ Visium-geometry dataset **and a matching tissue image** so the
318
+ [browser example](examples/browser-image/README.md#spatial-omics-demo) runs the
319
+ whole path with no download. A converter for real SpatialData Zarr stores ships
320
+ alongside it.
321
+
322
+ A **Spatial omics** controls panel (`<spatial-controls>`, opened from the
323
+ toolbar) drives all of this from the UI: a column dropdown, a gene search over
324
+ the feature panel, a legend for categorical colourings and a colour bar for
325
+ continuous ones, plus point-size, opacity, log-scale and outlier-clip controls.
326
+ Its legend swatches and colour bar are built with the same functions the
327
+ renderer uses, so the key cannot drift from the canvas.
328
+
329
+ **Selection** reuses the region tools you already have: draw a rectangle,
330
+ polygon, freehand shape, wand or brush region, then *Select from ROIs* selects
331
+ every observation inside their union and mutes the rest. Legend rows select
332
+ their category on click.
333
+
334
+ **Linked distributions** sit in the same panel, below the colour controls, over
335
+ whatever the map is coloured by: histogram, violin or box for a continuous column
336
+ or a gene, and per-category **counts** for a categorical one — a histogram of a
337
+ category code would be meaningless, but "how many cells per class" is the question
338
+ the legend implies and never answers. Violin and box are splittable by a
339
+ categorical column. One dialog on purpose — changing the gene
340
+ and watching the distribution move is a single action. They follow the selection: the histogram
341
+ overlays *Selected* on the full distribution, violin and box narrow to it. The
342
+ chart's subject is the map's colour source rather than an independent picker, so
343
+ the two cannot disagree about what is being shown.
344
+
345
+ Categorical colouring has one renderer-specific limit worth knowing: the 3D
346
+ points layer maps a per-point scalar through a 256-entry LUT, which keeps 96
347
+ blocks apart exactly — one of them reserved for a missing value, so **95
348
+ categories** fit — and above that the cloud draws flat and the panel says so.
349
+ The 2D markers (per-point RGBA) and the density volumes (a scalar field per
350
+ cluster) have no such limit — which is why the example server serves `subclass`
351
+ (338) even though the cloud cannot colour by it.
352
+
353
+ Still to build: hover tooltips, chart → map brushing, and a GPU layer for cell
354
+ boundary polygons (they are served, not yet drawn) — see
355
+ [docs/spatial-omics-plot-mode-design.md](docs/spatial-omics-plot-mode-design.md).
356
+
167
357
  ## Regions & annotation
168
358
 
169
359
  Regions are stored in a shared **region store** and use a GeoJSON-friendly model
@@ -270,6 +460,16 @@ Work that is landed-but-unstable or planned (not yet available):
270
460
  and browser-side SAM/cellpose segmentation) against sample images — so the
271
461
  library can be evaluated and developed standalone, outside jit-ui. Tracked in
272
462
  the library-extraction SOW ([docs/JIT_UI_visualization_library_SOW.docx](docs/JIT_UI_visualization_library_SOW.docx)).
463
+ - **Spatial-omics follow-ons** *(planned — the modes themselves shipped in
464
+ 0.4.0, see [Spatial omics](#spatial-omics))* — hover tooltips over
465
+ observations, brushing a chart selection back onto the map, and a GPU shapes
466
+ layer for cell-boundary polygons (the example server serves them; nothing draws
467
+ them yet, since a DOM overlay will not hold 10⁴–10⁵ outlines). The GPU layer is
468
+ measured as feasible — generating the geometry in a compute pass is bit-exact
469
+ and ~16× faster than JS, and 10⁵–10⁶ outlines draw in single-digit
470
+ milliseconds; the constraint is napari-js's closed renderer, not WebGPU. See
471
+ [.planning/research/cell-boundary-polygons-webgpu.md](.planning/research/cell-boundary-polygons-webgpu.md)
472
+ and [docs/spatial-omics-plot-mode-design.md](docs/spatial-omics-plot-mode-design.md).
273
473
  - **SAM 3 model** *(planned)* — a `variant: 'sam3'` decoder path + export tooling
274
474
  (SAM 2/3 use a different mask I/O than the current SAM-v1 path). See
275
475
  [docs/sam-segmentation-design.md](docs/sam-segmentation-design.md).
@@ -284,6 +484,10 @@ Design, architecture, and planning docs for the library:
284
484
  - **[docs/sam-segmentation-design.md](docs/sam-segmentation-design.md)** — design of
285
485
  the browser SAM segmentation: model choice, ONNX export/quantization recipe,
286
486
  encoder/decoder I/O, the engine/session architecture, and the rollout phases.
487
+ - **[docs/spatial-omics-plot-mode-design.md](docs/spatial-omics-plot-mode-design.md)** —
488
+ design and phased plan for the spatial-omics plot mode: current-state audit,
489
+ what the CosMx / Spatial-Live / SpatialData references contribute, the data
490
+ plane, MoSCoW requirements, and the open questions still to settle.
287
491
  - **Architecture diagrams**
288
492
  - [docs/jit-ui-visualization-architecture.mmd](docs/jit-ui-visualization-architecture.mmd)
289
493
  ([PNG](docs/img/jit-ui-visualization-architecture.png) ·
@@ -376,6 +580,66 @@ jit-ui's `app.module.ts` for a full wiring example.
376
580
  Each embeddable component uses a plain, unprefixed selector: `visualizer`,
377
581
  `region-editor`, `plotting-toolbar`, `channel-histogram`, `hex-color-picker`.
378
582
 
583
+ ## Contributed plot types
584
+
585
+ Another package can add a mode to the plot-type selector at runtime, through
586
+ Angular DI — the same way `TOOLBAR_TOOLS` contributes toolbar tools. Nothing
587
+ registers at import time: a mode appears only when the host provides it on the
588
+ `PLOT_TYPE_CONTRIBUTIONS` multi-provider token, and with no provider the
589
+ library behaves exactly as before. A contribution is a plain object, so the
590
+ contributing package needs no Angular compiler and no decorators.
591
+
592
+ ```ts
593
+ import {
594
+ PLOT_TYPE_CONTRIBUTIONS, PlotType, PlotTypeContribution,
595
+ } from '@jax-data-science/sci-image-visualizer';
596
+
597
+ const myMode: PlotTypeContribution = {
598
+ descriptor: {
599
+ type: 'my-mode', // namespaced; must not clash with a PlotType
600
+ label: 'Image + my overlay', // test-mode label
601
+ productionLabel: 'My overlay', // omit to make the mode test-only
602
+ icon: 'pi pi-pencil',
603
+ dimensions: '2d',
604
+ baseType: PlotType.IMAGE, // v1: only the OpenSeadragon Image view
605
+ },
606
+ activate(ctx) {
607
+ // ctx.visualizer — the public IVisualizer (regions, region overlay, undo…)
608
+ // ctx.viewport — overlay container, dataToClient / clientToData, frame$ / settled$
609
+ // ctx.imageInfo$ — the current image
610
+ const sub = ctx.viewport.frame$.subscribe((visible) => redraw(visible));
611
+ return { deactivate: () => sub.unsubscribe() };
612
+ },
613
+ // Optional side panel, in the right-hand panel area while the mode is active.
614
+ // Either an Angular component (it can inject PLOT_MODE_CONTEXT / PLOT_MODE_SESSION)…
615
+ // panel: { title: 'My overlay', component: MyPanelComponent },
616
+ // …or plain DOM, for a package built without the Angular compiler:
617
+ panel: {
618
+ title: 'My overlay',
619
+ mount(host, ctx, session) {
620
+ host.textContent = 'Hello';
621
+ return () => { host.textContent = ''; }; // teardown
622
+ },
623
+ },
624
+ };
625
+
626
+ // Host composition root:
627
+ providers: [{ provide: PLOT_TYPE_CONTRIBUTIONS, useValue: myMode, multi: true }]
628
+ ```
629
+
630
+ Selecting the mode plots exactly as its `baseType` would (same backend, toolbar,
631
+ region tools and wheel handling), then calls `activate(ctx)` once the viewport
632
+ is ready. `session.deactivate()` runs exactly once when the user leaves the
633
+ mode, when the image changes (a fresh session starts for the new image), or
634
+ when the visualizer is destroyed. Anything a contribution throws or rejects is
635
+ caught and logged. Failing to start falls back to `baseType`, and so does failing
636
+ to clean up when the same mode is about to be re-activated (re-render, image
637
+ switch). Contributed descriptors take the same `requiresGrayscale`,
638
+ `requiresStack`, `requiresSpatialData` and `requiresSpatial3d` gates as the
639
+ built-ins. The full contract
640
+ and its guarantees are documented in
641
+ [`plot-type-contribution.contract.ts`](./src/lib/contracts/plot-type-contribution.contract.ts).
642
+
379
643
  ## Development
380
644
 
381
645
  ```bash
package/esm2022/index.mjs CHANGED
@@ -12,18 +12,33 @@ export * from './lib/contracts/ports/image-state.port';
12
12
  export * from './lib/contracts/ports/tile-access.port';
13
13
  export * from './lib/contracts/ports/region-io.port';
14
14
  export * from './lib/contracts/ports/preferences.port';
15
+ export * from './lib/contracts/ports/spatial-data.port';
16
+ export * from './lib/contracts/spatial-dataset.contract';
15
17
  export * from './lib/contracts/channel-histogram-api.contract';
16
18
  export * from './lib/contracts/viz-config';
17
19
  export * from './lib/contracts/image.contract';
18
20
  export * from './lib/contracts/plot-type';
19
21
  export * from './lib/contracts/toolbar-config';
20
22
  export * from './lib/contracts/toolbar-tool.contract';
23
+ export * from './lib/contracts/plot-type-contribution.contract';
21
24
  export * from './lib/contracts/capabilities.contract';
22
25
  export * from './lib/contracts/region-overlay.contract';
23
26
  export * from './lib/contracts/display-types';
24
27
  export * from './lib/contracts/sam.contract';
25
28
  export * from './lib/contracts/cell-segmenter.contract';
26
29
  export { CellposeSegmenterService } from './lib/toolbar/segmentation/cellpose-segmenter.service';
30
+ // ── Spatial-omics data plane ─────────────────────────────────────────────
31
+ // The wire format the bundled example server speaks, plus a ready-made
32
+ // SpatialDataPort adapter for it. Both are OPTIONAL: a host with its own
33
+ // backend implements SpatialDataPort directly and imports neither.
34
+ export { SpatialDataHttpService, SupersededError } from './lib/implementations/spatial-data-http/spatial-data-http.service';
35
+ export { SPATIAL_WIRE_VERSION, isLittleEndian, assertManifestVersion, datasetFromManifest, decodeCoords, decodeRadius, decodeColumn, decodeFeatureVector, decodePolygons, } from './lib/implementations/spatial-data-http/spatial-wire';
36
+ // Backend-neutral encodings: columns/genes -> per-point colours and sizes.
37
+ export { encodeCategorical, encodeContinuous, resolveCategoryColors, contrastWindow, markerDiameters, toRgbaTuples, lutFor, DEFAULT_CATEGORICAL_PALETTE, DEFAULT_MUTED_OPACITY, MISSING_COLOR, } from './lib/spatial/spatial-encoding';
38
+ // Selection: which observations fall inside the drawn ROIs, and the shared store
39
+ // that holds the answer.
40
+ export { selectInRegions, selectByCategory, mutedFromSelection, pointInRing, emptySelection, countMask, maskToIndices, } from './lib/spatial/spatial-selection';
41
+ export { SpatialSelectionStore } from './lib/store/spatial-selection.service';
27
42
  export * from './lib/contracts/instance-segmenter.contract';
28
43
  export * from './lib/contracts/semantic-segmenter.contract';
29
44
  // ── Generic client-side image utilities (shared with the host's pipeline) ──
@@ -52,4 +67,9 @@ export { VisualizerComponent } from './lib/visualizer.component';
52
67
  export { RegionEditorComponent } from './lib/region-editor/region-editor.component';
53
68
  export { HexColorPickerComponent } from './lib/hex-color-picker/hex-color-picker.component';
54
69
  export { ChannelHistogramComponent } from './lib/channel-histogram/channel-histogram.component';
55
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgsNEVBQTRFO0FBQzVFLGNBQWMscUNBQXFDLENBQUM7QUFDcEQsY0FBYyw0Q0FBNEMsQ0FBQztBQUMzRCxjQUFjLHdDQUF3QyxDQUFDO0FBQ3ZELGNBQWMsd0NBQXdDLENBQUM7QUFDdkQsY0FBYyxzQ0FBc0MsQ0FBQztBQUNyRCxjQUFjLHdDQUF3QyxDQUFDO0FBQ3ZELGNBQWMsZ0RBQWdELENBQUM7QUFDL0QsY0FBYyw0QkFBNEIsQ0FBQztBQUMzQyxjQUFjLGdDQUFnQyxDQUFDO0FBQy9DLGNBQWMsMkJBQTJCLENBQUM7QUFDMUMsY0FBYyxnQ0FBZ0MsQ0FBQztBQUMvQyxjQUFjLHVDQUF1QyxDQUFDO0FBQ3RELGNBQWMsdUNBQXVDLENBQUM7QUFDdEQsY0FBYyx5Q0FBeUMsQ0FBQztBQUN4RCxjQUFjLCtCQUErQixDQUFDO0FBQzlDLGNBQWMsOEJBQThCLENBQUM7QUFDN0MsY0FBYyx5Q0FBeUMsQ0FBQztBQUN4RCxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSx1REFBdUQsQ0FBQztBQUNqRyxjQUFjLDZDQUE2QyxDQUFDO0FBQzVELGNBQWMsNkNBQTZDLENBQUM7QUFFNUQsOEVBQThFO0FBQzlFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUNwRSxPQUFPLEVBQUUsU0FBUyxFQUFvQixNQUFNLDZCQUE2QixDQUFDO0FBQzFFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDBDQUEwQyxDQUFDO0FBRWpGLDZFQUE2RTtBQUM3RSxPQUFPLEVBQ0wsVUFBVSxFQUFFLG9CQUFvQixFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsZUFBZSxFQUMvRSxrQkFBa0IsRUFBRSxvQkFBb0IsR0FDekMsTUFBTSwrQ0FBK0MsQ0FBQztBQUV2RCw4RUFBOEU7QUFDOUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxjQUFjLEVBQUUsTUFBTSwrQ0FBK0MsQ0FBQztBQUUvRiw0RUFBNEU7QUFDNUUsY0FBYyxxQkFBcUIsQ0FBQztBQUNwQyxjQUFjLDJCQUEyQixDQUFDO0FBQzFDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVwRCw0RUFBNEU7QUFDNUUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDakUsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDNUUsNkVBQTZFO0FBQzdFLG1FQUFtRTtBQUNuRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUVuRSw2RUFBNkU7QUFDN0UsMEVBQTBFO0FBQzFFLDhFQUE4RTtBQUM5RSw2REFBNkQ7QUFDN0QsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDakUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sNkNBQTZDLENBQUM7QUFDcEYsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sbURBQW1ELENBQUM7QUFDNUYsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0scURBQXFELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFB1YmxpYyBBUEkgb2YgdGhlIGpheC1pbWFnZS12aXN1YWxpemF0aW9uIGxpYnJhcnkuIEV4dGVybmFsIGNvbnN1bWVycyBpbXBvcnRcbiAqIE9OTFkgZnJvbSBoZXJlIChgQGpheC1kYXRhLXNjaWVuY2Uvc2NpLWltYWdlLXZpc3VhbGl6ZXJgKTsgZXZlcnl0aGluZyBlbHNlIHVuZGVyIGBsaWIvYCBpc1xuICogaW50ZXJuYWwuIFRoZSBzdXJmYWNlIGlzIGNvbnRyYWN0cyArIHRva2VucyArIG5ldXRyYWwgbW9kZWxzICsgdGhlIEFuZ3VsYXJcbiAqIG1vZHVsZSwgcGx1cyB0aGUgcm91dGluZyBzZXJ2aWNlIHRoZSBob3N0J3MgY29tcG9zaXRpb24gcm9vdCBiaW5kcyB0aGUgdG9rZW5zXG4gKiB0byAoYHVzZUV4aXN0aW5nYCkuXG4gKi9cblxuLy8g4pSA4pSAIENvbnRyYWN0cyAmIERJIHRva2VucyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbmV4cG9ydCAqIGZyb20gJy4vbGliL2NvbnRyYWN0cy92aXN1YWxpemVyLmNvbnRyYWN0JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2NvbnRyYWN0cy9yZWdpb24tZWRpdG9yLWFwaS5jb250cmFjdCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb250cmFjdHMvcG9ydHMvaW1hZ2Utc3RhdGUucG9ydCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb250cmFjdHMvcG9ydHMvdGlsZS1hY2Nlc3MucG9ydCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb250cmFjdHMvcG9ydHMvcmVnaW9uLWlvLnBvcnQnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvY29udHJhY3RzL3BvcnRzL3ByZWZlcmVuY2VzLnBvcnQnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvY29udHJhY3RzL2NoYW5uZWwtaGlzdG9ncmFtLWFwaS5jb250cmFjdCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb250cmFjdHMvdml6LWNvbmZpZyc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb250cmFjdHMvaW1hZ2UuY29udHJhY3QnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvY29udHJhY3RzL3Bsb3QtdHlwZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb250cmFjdHMvdG9vbGJhci1jb25maWcnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvY29udHJhY3RzL3Rvb2xiYXItdG9vbC5jb250cmFjdCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb250cmFjdHMvY2FwYWJpbGl0aWVzLmNvbnRyYWN0JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2NvbnRyYWN0cy9yZWdpb24tb3ZlcmxheS5jb250cmFjdCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb250cmFjdHMvZGlzcGxheS10eXBlcyc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb250cmFjdHMvc2FtLmNvbnRyYWN0JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2NvbnRyYWN0cy9jZWxsLXNlZ21lbnRlci5jb250cmFjdCc7XG5leHBvcnQgeyBDZWxscG9zZVNlZ21lbnRlclNlcnZpY2UgfSBmcm9tICcuL2xpYi90b29sYmFyL3NlZ21lbnRhdGlvbi9jZWxscG9zZS1zZWdtZW50ZXIuc2VydmljZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb250cmFjdHMvaW5zdGFuY2Utc2VnbWVudGVyLmNvbnRyYWN0JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2NvbnRyYWN0cy9zZW1hbnRpYy1zZWdtZW50ZXIuY29udHJhY3QnO1xuXG4vLyDilIDilIAgR2VuZXJpYyBjbGllbnQtc2lkZSBpbWFnZSB1dGlsaXRpZXMgKHNoYXJlZCB3aXRoIHRoZSBob3N0J3MgcGlwZWxpbmUpIOKUgOKUgFxuZXhwb3J0IHsgUHJvY2Vzc2luZ0ltYWdlIH0gZnJvbSAnLi9saWIvcHJvY2Vzc2luZy9wcm9jZXNzaW5nLWltYWdlJztcbmV4cG9ydCB7IGNyb3BJbWFnZSwgQ3JvcEltYWdlT3B0aW9ucyB9IGZyb20gJy4vbGliL3Byb2Nlc3NpbmcvaW1hZ2UtY3JvcCc7XG5leHBvcnQgeyBJbWFnZUNvbnZlcnRlclNlcnZpY2UgfSBmcm9tICcuL2xpYi9wcm9jZXNzaW5nL2ltYWdlLWNvbnZlcnRlci5zZXJ2aWNlJztcblxuLy8g4pSA4pSAIFNBTSBtb2RlbCByZWdpc3RyeSAoaG9zdCBjb25maWd1cmVzIGhvc3RlZCBPTk5YIFVSTHMgb25jZSBhdmFpbGFibGUpIOKUgOKUgFxuZXhwb3J0IHtcbiAgU0FNX01PREVMUywgREVGQVVMVF9TQU1fTU9ERUxfSUQsIGdldFNhbU1vZGVsLCBpc1NhbU1vZGVsUmVhZHksIHNldFNhbU1vZGVsVXJscyxcbiAgc2V0RGVmYXVsdFNhbU1vZGVsLCBnZXREZWZhdWx0U2FtTW9kZWxJZCxcbn0gZnJvbSAnLi9saWIvdG9vbGJhci9zZWdtZW50YXRpb24vc2FtLW1vZGVsLXJlZ2lzdHJ5JztcblxuLy8g4pSA4pSAIG9ubnhydW50aW1lLXdlYiBXQVNNIGxvY2F0aW9uIChob3N0IG92ZXJyaWRlcyBvbmNlLCBhdCBhcHAgaW5pdCkg4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5leHBvcnQgeyBzZXRPcnRXYXNtQmFzZSwgZ2V0T3J0V2FzbUJhc2UgfSBmcm9tICcuL2xpYi90b29sYmFyL3NlZ21lbnRhdGlvbi9vcnQtcnVudGltZS1jb25maWcnO1xuXG4vLyDilIDilIAgTmV1dHJhbCBkYXRhIG1vZGVscyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbmV4cG9ydCAqIGZyb20gJy4vbGliL21vZGVscy9yZWdpb24nO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvbW9kZWxzL2NsYXNzLXByZXNldCc7XG5leHBvcnQgeyBTaGFwZVNlbGVjdGlvbiB9IGZyb20gJy4vbGliL21vZGVscy9zaGFwZSc7XG5cbi8vIOKUgOKUgCBBbmd1bGFyIG1vZHVsZSArIGNvbXBvc2l0aW9uLXJvb3Qgc2VydmljZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbmV4cG9ydCB7IFZpc3VhbGl6YXRpb25Nb2R1bGUgfSBmcm9tICcuL2xpYi92aXN1YWxpemF0aW9uLm1vZHVsZSc7XG5leHBvcnQgeyBSb3V0aW5nVmlzdWFsaXplclNlcnZpY2UgfSBmcm9tICcuL2xpYi9yb3V0aW5nLXZpc3VhbGl6ZXIuc2VydmljZSc7XG4vLyBQcm92aWRlciBmYWN0b3J5IGZvciBhbiBpc29sYXRlZCwgY29tcG9uZW50LXNjb3BlZCB2aWV3ZXIgaW5zdGFuY2UgKGUuZy4gYVxuLy8gbW9kYWwgdGhhdCBtdXN0IG5vdCBzaGFyZSB0aGUgbWFpbiB2aWV3ZXIncyByZWdpb24vaW1hZ2Ugc3RhdGUpLlxuZXhwb3J0IHsgcHJvdmlkZVZpc3VhbGl6YXRpb24gfSBmcm9tICcuL2xpYi9wcm92aWRlLXZpc3VhbGl6YXRpb24nO1xuXG4vLyDilIDilIAgUHVibGljIGNvbXBvbmVudHMgKGV4cG9ydGVkIGJ5IFZpc3VhbGl6YXRpb25Nb2R1bGUpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuLy8gbmctcGFja2FnciByZXF1aXJlcyBtb2R1bGUtZXhwb3J0ZWQgY29tcG9uZW50cyB0byBiZSByZWFjaGFibGUgZnJvbSB0aGVcbi8vIGVudHJ5IHBvaW50IHNvIGNvbnN1bWVycyBnZXQgdGhlaXIgdHlwZXM7IHRoZXNlIGFyZSB0aGUgZW1iZWRkYWJsZSBlbGVtZW50c1xuLy8gKGA8dmlzdWFsaXplcj5gLCBgPHJlZ2lvbi1lZGl0b3I+YCwgYDxoZXgtY29sb3ItcGlja2VyPmApLlxuZXhwb3J0IHsgVmlzdWFsaXplckNvbXBvbmVudCB9IGZyb20gJy4vbGliL3Zpc3VhbGl6ZXIuY29tcG9uZW50JztcbmV4cG9ydCB7IFJlZ2lvbkVkaXRvckNvbXBvbmVudCB9IGZyb20gJy4vbGliL3JlZ2lvbi1lZGl0b3IvcmVnaW9uLWVkaXRvci5jb21wb25lbnQnO1xuZXhwb3J0IHsgSGV4Q29sb3JQaWNrZXJDb21wb25lbnQgfSBmcm9tICcuL2xpYi9oZXgtY29sb3ItcGlja2VyL2hleC1jb2xvci1waWNrZXIuY29tcG9uZW50JztcbmV4cG9ydCB7IENoYW5uZWxIaXN0b2dyYW1Db21wb25lbnQgfSBmcm9tICcuL2xpYi9jaGFubmVsLWhpc3RvZ3JhbS9jaGFubmVsLWhpc3RvZ3JhbS5jb21wb25lbnQnO1xuIl19
70
+ export { SpatialControlsComponent, } from './lib/spatial-controls/spatial-controls.component';
71
+ export { SpatialChartsComponent } from './lib/spatial-controls/spatial-charts/spatial-charts.component';
72
+ // Pure chart builders, exported so a host can render the same distributions
73
+ // wherever it likes (a report, a different charting surface).
74
+ export { buildOmicsTraces, omicsLayout, benefitsFromGrouping, } from './lib/implementations/plotly/omics-trace-builders';
75
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgsNEVBQTRFO0FBQzVFLGNBQWMscUNBQXFDLENBQUM7QUFDcEQsY0FBYyw0Q0FBNEMsQ0FBQztBQUMzRCxjQUFjLHdDQUF3QyxDQUFDO0FBQ3ZELGNBQWMsd0NBQXdDLENBQUM7QUFDdkQsY0FBYyxzQ0FBc0MsQ0FBQztBQUNyRCxjQUFjLHdDQUF3QyxDQUFDO0FBQ3ZELGNBQWMseUNBQXlDLENBQUM7QUFDeEQsY0FBYywwQ0FBMEMsQ0FBQztBQUN6RCxjQUFjLGdEQUFnRCxDQUFDO0FBQy9ELGNBQWMsNEJBQTRCLENBQUM7QUFDM0MsY0FBYyxnQ0FBZ0MsQ0FBQztBQUMvQyxjQUFjLDJCQUEyQixDQUFDO0FBQzFDLGNBQWMsZ0NBQWdDLENBQUM7QUFDL0MsY0FBYyx1Q0FBdUMsQ0FBQztBQUN0RCxjQUFjLGlEQUFpRCxDQUFDO0FBQ2hFLGNBQWMsdUNBQXVDLENBQUM7QUFDdEQsY0FBYyx5Q0FBeUMsQ0FBQztBQUN4RCxjQUFjLCtCQUErQixDQUFDO0FBQzlDLGNBQWMsOEJBQThCLENBQUM7QUFDN0MsY0FBYyx5Q0FBeUMsQ0FBQztBQUN4RCxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSx1REFBdUQsQ0FBQztBQUVqRyw0RUFBNEU7QUFDNUUsdUVBQXVFO0FBQ3ZFLHlFQUF5RTtBQUN6RSxtRUFBbUU7QUFDbkUsT0FBTyxFQUFFLHNCQUFzQixFQUFFLGVBQWUsRUFBRSxNQUFNLG1FQUFtRSxDQUFDO0FBQzVILE9BQU8sRUFDTCxvQkFBb0IsRUFBRSxjQUFjLEVBQUUscUJBQXFCLEVBQUUsbUJBQW1CLEVBQ2hGLFlBQVksRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLG1CQUFtQixFQUFFLGNBQWMsR0FDOUUsTUFBTSxzREFBc0QsQ0FBQztBQUk5RCwyRUFBMkU7QUFDM0UsT0FBTyxFQUNMLGlCQUFpQixFQUFFLGdCQUFnQixFQUFFLHFCQUFxQixFQUFFLGNBQWMsRUFDMUUsZUFBZSxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQ3JDLDJCQUEyQixFQUFFLHFCQUFxQixFQUFFLGFBQWEsR0FDbEUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUl4QyxpRkFBaUY7QUFDakYseUJBQXlCO0FBQ3pCLE9BQU8sRUFDTCxlQUFlLEVBQUUsZ0JBQWdCLEVBQUUsa0JBQWtCLEVBQUUsV0FBVyxFQUNsRSxjQUFjLEVBQUUsU0FBUyxFQUFFLGFBQWEsR0FDekMsTUFBTSxpQ0FBaUMsQ0FBQztBQUV6QyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUM5RSxjQUFjLDZDQUE2QyxDQUFDO0FBQzVELGNBQWMsNkNBQTZDLENBQUM7QUFFNUQsOEVBQThFO0FBQzlFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUNwRSxPQUFPLEVBQUUsU0FBUyxFQUFvQixNQUFNLDZCQUE2QixDQUFDO0FBQzFFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDBDQUEwQyxDQUFDO0FBRWpGLDZFQUE2RTtBQUM3RSxPQUFPLEVBQ0wsVUFBVSxFQUFFLG9CQUFvQixFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsZUFBZSxFQUMvRSxrQkFBa0IsRUFBRSxvQkFBb0IsR0FDekMsTUFBTSwrQ0FBK0MsQ0FBQztBQUV2RCw4RUFBOEU7QUFDOUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxjQUFjLEVBQUUsTUFBTSwrQ0FBK0MsQ0FBQztBQUUvRiw0RUFBNEU7QUFDNUUsY0FBYyxxQkFBcUIsQ0FBQztBQUNwQyxjQUFjLDJCQUEyQixDQUFDO0FBQzFDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVwRCw0RUFBNEU7QUFDNUUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDakUsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDNUUsNkVBQTZFO0FBQzdFLG1FQUFtRTtBQUNuRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUVuRSw2RUFBNkU7QUFDN0UsMEVBQTBFO0FBQzFFLDhFQUE4RTtBQUM5RSw2REFBNkQ7QUFDN0QsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDakUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sNkNBQTZDLENBQUM7QUFDcEYsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sbURBQW1ELENBQUM7QUFDNUYsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0scURBQXFELENBQUM7QUFDaEcsT0FBTyxFQUNMLHdCQUF3QixHQUN6QixNQUFNLG1EQUFtRCxDQUFDO0FBRTNELE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGdFQUFnRSxDQUFDO0FBQ3hHLDRFQUE0RTtBQUM1RSw4REFBOEQ7QUFDOUQsT0FBTyxFQUNMLGdCQUFnQixFQUFFLFdBQVcsRUFBRSxvQkFBb0IsR0FDcEQsTUFBTSxtREFBbUQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUHVibGljIEFQSSBvZiB0aGUgamF4LWltYWdlLXZpc3VhbGl6YXRpb24gbGlicmFyeS4gRXh0ZXJuYWwgY29uc3VtZXJzIGltcG9ydFxuICogT05MWSBmcm9tIGhlcmUgKGBAamF4LWRhdGEtc2NpZW5jZS9zY2ktaW1hZ2UtdmlzdWFsaXplcmApOyBldmVyeXRoaW5nIGVsc2UgdW5kZXIgYGxpYi9gIGlzXG4gKiBpbnRlcm5hbC4gVGhlIHN1cmZhY2UgaXMgY29udHJhY3RzICsgdG9rZW5zICsgbmV1dHJhbCBtb2RlbHMgKyB0aGUgQW5ndWxhclxuICogbW9kdWxlLCBwbHVzIHRoZSByb3V0aW5nIHNlcnZpY2UgdGhlIGhvc3QncyBjb21wb3NpdGlvbiByb290IGJpbmRzIHRoZSB0b2tlbnNcbiAqIHRvIChgdXNlRXhpc3RpbmdgKS5cbiAqL1xuXG4vLyDilIDilIAgQ29udHJhY3RzICYgREkgdG9rZW5zIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuZXhwb3J0ICogZnJvbSAnLi9saWIvY29udHJhY3RzL3Zpc3VhbGl6ZXIuY29udHJhY3QnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvY29udHJhY3RzL3JlZ2lvbi1lZGl0b3ItYXBpLmNvbnRyYWN0JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2NvbnRyYWN0cy9wb3J0cy9pbWFnZS1zdGF0ZS5wb3J0JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2NvbnRyYWN0cy9wb3J0cy90aWxlLWFjY2Vzcy5wb3J0JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2NvbnRyYWN0cy9wb3J0cy9yZWdpb24taW8ucG9ydCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb250cmFjdHMvcG9ydHMvcHJlZmVyZW5jZXMucG9ydCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb250cmFjdHMvcG9ydHMvc3BhdGlhbC1kYXRhLnBvcnQnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvY29udHJhY3RzL3NwYXRpYWwtZGF0YXNldC5jb250cmFjdCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb250cmFjdHMvY2hhbm5lbC1oaXN0b2dyYW0tYXBpLmNvbnRyYWN0JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2NvbnRyYWN0cy92aXotY29uZmlnJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2NvbnRyYWN0cy9pbWFnZS5jb250cmFjdCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb250cmFjdHMvcGxvdC10eXBlJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2NvbnRyYWN0cy90b29sYmFyLWNvbmZpZyc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb250cmFjdHMvdG9vbGJhci10b29sLmNvbnRyYWN0JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2NvbnRyYWN0cy9wbG90LXR5cGUtY29udHJpYnV0aW9uLmNvbnRyYWN0JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2NvbnRyYWN0cy9jYXBhYmlsaXRpZXMuY29udHJhY3QnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvY29udHJhY3RzL3JlZ2lvbi1vdmVybGF5LmNvbnRyYWN0JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2NvbnRyYWN0cy9kaXNwbGF5LXR5cGVzJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2NvbnRyYWN0cy9zYW0uY29udHJhY3QnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvY29udHJhY3RzL2NlbGwtc2VnbWVudGVyLmNvbnRyYWN0JztcbmV4cG9ydCB7IENlbGxwb3NlU2VnbWVudGVyU2VydmljZSB9IGZyb20gJy4vbGliL3Rvb2xiYXIvc2VnbWVudGF0aW9uL2NlbGxwb3NlLXNlZ21lbnRlci5zZXJ2aWNlJztcblxuLy8g4pSA4pSAIFNwYXRpYWwtb21pY3MgZGF0YSBwbGFuZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbi8vIFRoZSB3aXJlIGZvcm1hdCB0aGUgYnVuZGxlZCBleGFtcGxlIHNlcnZlciBzcGVha3MsIHBsdXMgYSByZWFkeS1tYWRlXG4vLyBTcGF0aWFsRGF0YVBvcnQgYWRhcHRlciBmb3IgaXQuIEJvdGggYXJlIE9QVElPTkFMOiBhIGhvc3Qgd2l0aCBpdHMgb3duXG4vLyBiYWNrZW5kIGltcGxlbWVudHMgU3BhdGlhbERhdGFQb3J0IGRpcmVjdGx5IGFuZCBpbXBvcnRzIG5laXRoZXIuXG5leHBvcnQgeyBTcGF0aWFsRGF0YUh0dHBTZXJ2aWNlLCBTdXBlcnNlZGVkRXJyb3IgfSBmcm9tICcuL2xpYi9pbXBsZW1lbnRhdGlvbnMvc3BhdGlhbC1kYXRhLWh0dHAvc3BhdGlhbC1kYXRhLWh0dHAuc2VydmljZSc7XG5leHBvcnQge1xuICBTUEFUSUFMX1dJUkVfVkVSU0lPTiwgaXNMaXR0bGVFbmRpYW4sIGFzc2VydE1hbmlmZXN0VmVyc2lvbiwgZGF0YXNldEZyb21NYW5pZmVzdCxcbiAgZGVjb2RlQ29vcmRzLCBkZWNvZGVSYWRpdXMsIGRlY29kZUNvbHVtbiwgZGVjb2RlRmVhdHVyZVZlY3RvciwgZGVjb2RlUG9seWdvbnMsXG59IGZyb20gJy4vbGliL2ltcGxlbWVudGF0aW9ucy9zcGF0aWFsLWRhdGEtaHR0cC9zcGF0aWFsLXdpcmUnO1xuZXhwb3J0IHR5cGUge1xuICBTcGF0aWFsTWFuaWZlc3QsIFNwYXRpYWxEYXRhc2V0U3VtbWFyeSwgU3BhdGlhbFJhZGl1c1NwZWMsXG59IGZyb20gJy4vbGliL2ltcGxlbWVudGF0aW9ucy9zcGF0aWFsLWRhdGEtaHR0cC9zcGF0aWFsLXdpcmUnO1xuLy8gQmFja2VuZC1uZXV0cmFsIGVuY29kaW5nczogY29sdW1ucy9nZW5lcyAtPiBwZXItcG9pbnQgY29sb3VycyBhbmQgc2l6ZXMuXG5leHBvcnQge1xuICBlbmNvZGVDYXRlZ29yaWNhbCwgZW5jb2RlQ29udGludW91cywgcmVzb2x2ZUNhdGVnb3J5Q29sb3JzLCBjb250cmFzdFdpbmRvdyxcbiAgbWFya2VyRGlhbWV0ZXJzLCB0b1JnYmFUdXBsZXMsIGx1dEZvcixcbiAgREVGQVVMVF9DQVRFR09SSUNBTF9QQUxFVFRFLCBERUZBVUxUX01VVEVEX09QQUNJVFksIE1JU1NJTkdfQ09MT1IsXG59IGZyb20gJy4vbGliL3NwYXRpYWwvc3BhdGlhbC1lbmNvZGluZyc7XG5leHBvcnQgdHlwZSB7XG4gIFJHQkEsIENhdGVnb3JpY2FsRW5jb2RpbmdPcHRpb25zLCBDb250aW51b3VzRW5jb2RpbmdPcHRpb25zLFxufSBmcm9tICcuL2xpYi9zcGF0aWFsL3NwYXRpYWwtZW5jb2RpbmcnO1xuLy8gU2VsZWN0aW9uOiB3aGljaCBvYnNlcnZhdGlvbnMgZmFsbCBpbnNpZGUgdGhlIGRyYXduIFJPSXMsIGFuZCB0aGUgc2hhcmVkIHN0b3JlXG4vLyB0aGF0IGhvbGRzIHRoZSBhbnN3ZXIuXG5leHBvcnQge1xuICBzZWxlY3RJblJlZ2lvbnMsIHNlbGVjdEJ5Q2F0ZWdvcnksIG11dGVkRnJvbVNlbGVjdGlvbiwgcG9pbnRJblJpbmcsXG4gIGVtcHR5U2VsZWN0aW9uLCBjb3VudE1hc2ssIG1hc2tUb0luZGljZXMsXG59IGZyb20gJy4vbGliL3NwYXRpYWwvc3BhdGlhbC1zZWxlY3Rpb24nO1xuZXhwb3J0IHR5cGUgeyBTcGF0aWFsU2VsZWN0aW9uTWFzayB9IGZyb20gJy4vbGliL3NwYXRpYWwvc3BhdGlhbC1zZWxlY3Rpb24nO1xuZXhwb3J0IHsgU3BhdGlhbFNlbGVjdGlvblN0b3JlIH0gZnJvbSAnLi9saWIvc3RvcmUvc3BhdGlhbC1zZWxlY3Rpb24uc2VydmljZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb250cmFjdHMvaW5zdGFuY2Utc2VnbWVudGVyLmNvbnRyYWN0JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2NvbnRyYWN0cy9zZW1hbnRpYy1zZWdtZW50ZXIuY29udHJhY3QnO1xuXG4vLyDilIDilIAgR2VuZXJpYyBjbGllbnQtc2lkZSBpbWFnZSB1dGlsaXRpZXMgKHNoYXJlZCB3aXRoIHRoZSBob3N0J3MgcGlwZWxpbmUpIOKUgOKUgFxuZXhwb3J0IHsgUHJvY2Vzc2luZ0ltYWdlIH0gZnJvbSAnLi9saWIvcHJvY2Vzc2luZy9wcm9jZXNzaW5nLWltYWdlJztcbmV4cG9ydCB7IGNyb3BJbWFnZSwgQ3JvcEltYWdlT3B0aW9ucyB9IGZyb20gJy4vbGliL3Byb2Nlc3NpbmcvaW1hZ2UtY3JvcCc7XG5leHBvcnQgeyBJbWFnZUNvbnZlcnRlclNlcnZpY2UgfSBmcm9tICcuL2xpYi9wcm9jZXNzaW5nL2ltYWdlLWNvbnZlcnRlci5zZXJ2aWNlJztcblxuLy8g4pSA4pSAIFNBTSBtb2RlbCByZWdpc3RyeSAoaG9zdCBjb25maWd1cmVzIGhvc3RlZCBPTk5YIFVSTHMgb25jZSBhdmFpbGFibGUpIOKUgOKUgFxuZXhwb3J0IHtcbiAgU0FNX01PREVMUywgREVGQVVMVF9TQU1fTU9ERUxfSUQsIGdldFNhbU1vZGVsLCBpc1NhbU1vZGVsUmVhZHksIHNldFNhbU1vZGVsVXJscyxcbiAgc2V0RGVmYXVsdFNhbU1vZGVsLCBnZXREZWZhdWx0U2FtTW9kZWxJZCxcbn0gZnJvbSAnLi9saWIvdG9vbGJhci9zZWdtZW50YXRpb24vc2FtLW1vZGVsLXJlZ2lzdHJ5JztcblxuLy8g4pSA4pSAIG9ubnhydW50aW1lLXdlYiBXQVNNIGxvY2F0aW9uIChob3N0IG92ZXJyaWRlcyBvbmNlLCBhdCBhcHAgaW5pdCkg4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5leHBvcnQgeyBzZXRPcnRXYXNtQmFzZSwgZ2V0T3J0V2FzbUJhc2UgfSBmcm9tICcuL2xpYi90b29sYmFyL3NlZ21lbnRhdGlvbi9vcnQtcnVudGltZS1jb25maWcnO1xuXG4vLyDilIDilIAgTmV1dHJhbCBkYXRhIG1vZGVscyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbmV4cG9ydCAqIGZyb20gJy4vbGliL21vZGVscy9yZWdpb24nO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvbW9kZWxzL2NsYXNzLXByZXNldCc7XG5leHBvcnQgeyBTaGFwZVNlbGVjdGlvbiB9IGZyb20gJy4vbGliL21vZGVscy9zaGFwZSc7XG5cbi8vIOKUgOKUgCBBbmd1bGFyIG1vZHVsZSArIGNvbXBvc2l0aW9uLXJvb3Qgc2VydmljZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbmV4cG9ydCB7IFZpc3VhbGl6YXRpb25Nb2R1bGUgfSBmcm9tICcuL2xpYi92aXN1YWxpemF0aW9uLm1vZHVsZSc7XG5leHBvcnQgeyBSb3V0aW5nVmlzdWFsaXplclNlcnZpY2UgfSBmcm9tICcuL2xpYi9yb3V0aW5nLXZpc3VhbGl6ZXIuc2VydmljZSc7XG4vLyBQcm92aWRlciBmYWN0b3J5IGZvciBhbiBpc29sYXRlZCwgY29tcG9uZW50LXNjb3BlZCB2aWV3ZXIgaW5zdGFuY2UgKGUuZy4gYVxuLy8gbW9kYWwgdGhhdCBtdXN0IG5vdCBzaGFyZSB0aGUgbWFpbiB2aWV3ZXIncyByZWdpb24vaW1hZ2Ugc3RhdGUpLlxuZXhwb3J0IHsgcHJvdmlkZVZpc3VhbGl6YXRpb24gfSBmcm9tICcuL2xpYi9wcm92aWRlLXZpc3VhbGl6YXRpb24nO1xuXG4vLyDilIDilIAgUHVibGljIGNvbXBvbmVudHMgKGV4cG9ydGVkIGJ5IFZpc3VhbGl6YXRpb25Nb2R1bGUpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuLy8gbmctcGFja2FnciByZXF1aXJlcyBtb2R1bGUtZXhwb3J0ZWQgY29tcG9uZW50cyB0byBiZSByZWFjaGFibGUgZnJvbSB0aGVcbi8vIGVudHJ5IHBvaW50IHNvIGNvbnN1bWVycyBnZXQgdGhlaXIgdHlwZXM7IHRoZXNlIGFyZSB0aGUgZW1iZWRkYWJsZSBlbGVtZW50c1xuLy8gKGA8dmlzdWFsaXplcj5gLCBgPHJlZ2lvbi1lZGl0b3I+YCwgYDxoZXgtY29sb3ItcGlja2VyPmApLlxuZXhwb3J0IHsgVmlzdWFsaXplckNvbXBvbmVudCB9IGZyb20gJy4vbGliL3Zpc3VhbGl6ZXIuY29tcG9uZW50JztcbmV4cG9ydCB7IFJlZ2lvbkVkaXRvckNvbXBvbmVudCB9IGZyb20gJy4vbGliL3JlZ2lvbi1lZGl0b3IvcmVnaW9uLWVkaXRvci5jb21wb25lbnQnO1xuZXhwb3J0IHsgSGV4Q29sb3JQaWNrZXJDb21wb25lbnQgfSBmcm9tICcuL2xpYi9oZXgtY29sb3ItcGlja2VyL2hleC1jb2xvci1waWNrZXIuY29tcG9uZW50JztcbmV4cG9ydCB7IENoYW5uZWxIaXN0b2dyYW1Db21wb25lbnQgfSBmcm9tICcuL2xpYi9jaGFubmVsLWhpc3RvZ3JhbS9jaGFubmVsLWhpc3RvZ3JhbS5jb21wb25lbnQnO1xuZXhwb3J0IHtcbiAgU3BhdGlhbENvbnRyb2xzQ29tcG9uZW50LFxufSBmcm9tICcuL2xpYi9zcGF0aWFsLWNvbnRyb2xzL3NwYXRpYWwtY29udHJvbHMuY29tcG9uZW50JztcbmV4cG9ydCB0eXBlIHsgU3BhdGlhbExlZ2VuZEVudHJ5IH0gZnJvbSAnLi9saWIvc3BhdGlhbC1jb250cm9scy9zcGF0aWFsLWNvbnRyb2xzLmNvbXBvbmVudCc7XG5leHBvcnQgeyBTcGF0aWFsQ2hhcnRzQ29tcG9uZW50IH0gZnJvbSAnLi9saWIvc3BhdGlhbC1jb250cm9scy9zcGF0aWFsLWNoYXJ0cy9zcGF0aWFsLWNoYXJ0cy5jb21wb25lbnQnO1xuLy8gUHVyZSBjaGFydCBidWlsZGVycywgZXhwb3J0ZWQgc28gYSBob3N0IGNhbiByZW5kZXIgdGhlIHNhbWUgZGlzdHJpYnV0aW9uc1xuLy8gd2hlcmV2ZXIgaXQgbGlrZXMgKGEgcmVwb3J0LCBhIGRpZmZlcmVudCBjaGFydGluZyBzdXJmYWNlKS5cbmV4cG9ydCB7XG4gIGJ1aWxkT21pY3NUcmFjZXMsIG9taWNzTGF5b3V0LCBiZW5lZml0c0Zyb21Hcm91cGluZyxcbn0gZnJvbSAnLi9saWIvaW1wbGVtZW50YXRpb25zL3Bsb3RseS9vbWljcy10cmFjZS1idWlsZGVycyc7XG5leHBvcnQgdHlwZSB7XG4gIE9taWNzQ2hhcnRLaW5kLCBPbWljc0dyb3VwaW5nLCBPbWljc1RyYWNlSW5wdXQsXG59IGZyb20gJy4vbGliL2ltcGxlbWVudGF0aW9ucy9wbG90bHkvb21pY3MtdHJhY2UtYnVpbGRlcnMnO1xuIl19
@@ -4,5 +4,23 @@
4
4
  * so existing hosts (which pass PrimeNG `TreeNode`s and plain option objects)
5
5
  * keep compiling unchanged while consumers finally get named shapes.
6
6
  */
7
- export {};
8
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzcGxheS10eXBlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvY29udHJhY3RzL2Rpc3BsYXktdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7O0dBS0ciLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFB1YmxpY2F0aW9uLWNyaXRpY2FsIHR5cGVzIHRoYXQgd2VyZSBgYW55YCBvbiB0aGUgcHVibGljIGNvbnRyYWN0c1xuICogKHJlZmFjdG9yaW5nIHBsYW4sIFN0ZXAgNikuIERlbGliZXJhdGVseSBwZXJtaXNzaXZlIOKAlCBldmVyeSBmaWVsZCBvcHRpb25hbCDigJRcbiAqIHNvIGV4aXN0aW5nIGhvc3RzICh3aGljaCBwYXNzIFByaW1lTkcgYFRyZWVOb2RlYHMgYW5kIHBsYWluIG9wdGlvbiBvYmplY3RzKVxuICoga2VlcCBjb21waWxpbmcgdW5jaGFuZ2VkIHdoaWxlIGNvbnN1bWVycyBmaW5hbGx5IGdldCBuYW1lZCBzaGFwZXMuXG4gKi9cblxuLyoqIEEgY29sb3JtYXAgdmFsdWUgYXMgUGxvdGx5IHVuZGVyc3RhbmRzIGl0OiBhIGJ1aWx0LWluIHNjYWxlIG5hbWUgKGUuZy5cbiAqICAnVmlyaWRpcycpIG9yIGFuIGlubGluZSBhcnJheSBvZiBgW3N0b3AsIGNvbG9yXWAgcGFpcnMuICovXG5leHBvcnQgdHlwZSBDb2xvcm1hcFZhbHVlID0gc3RyaW5nIHwgQXJyYXk8W251bWJlciwgc3RyaW5nXT47XG5cbi8qKiBPbmUgbm9kZSBvZiB0aGUgY29sb3JtYXAgc2VsZWN0b3IgdHJlZSAoc3RydWN0dXJhbGx5IGNvbXBhdGlibGUgd2l0aCB0aGVcbiAqICBQcmltZU5HIGBUcmVlTm9kZWBzIHRoZSBob3N0IHBhc3Nlcyk6IGdyb3VwIG5vZGVzIGNhcnJ5IGBjaGlsZHJlbmAsIGxlYWZcbiAqICBub2RlcyBjYXJyeSB0aGUgc2NhbGUgaW4gYGRhdGEudmFsdWVgICgrIGEgcHJldmlldyBpbWFnZSBpbiBgZGF0YS5zcmNgKS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29sb3JtYXBOb2RlIHtcbiAgbGFiZWw/OiBzdHJpbmc7XG4gIGRhdGE/OiB7IHZhbHVlPzogQ29sb3JtYXBWYWx1ZTsgc3JjPzogc3RyaW5nIH07XG4gIGNoaWxkcmVuPzogQ29sb3JtYXBOb2RlW107XG59XG5cbi8qKiBNYWdpYy13YW5kIHBpeGVsLWNvbXBhcmlzb24gc3BhY2UuICovXG5leHBvcnQgdHlwZSBXYW5kVHlwZSA9ICdHUkFZJyB8ICdSR0InIHwgJ0xBQl9ESVNUQU5DRSc7XG5cbi8qKiBPcHRpb25zIGZvciB0aGUgbWFnaWMtd2FuZCB0b29sIChRdVBhdGgtc3R5bGUpLiAqL1xuZXhwb3J0IGludGVyZmFjZSBJV2FuZE9wdGlvbnMge1xuICB0eXBlPzogV2FuZFR5cGU7XG4gIC8qKiBHYXVzc2lhbiBzaWdtYSBhcHBsaWVkIHRvIHRoZSBwYXRjaCBiZWZvcmUgdGhyZXNob2xkaW5nLiAqL1xuICBzaWdtYT86IG51bWJlcjtcbiAgLyoqIEhpZ2hlciA9IHN0cmljdGVyIChzbWFsbGVyIHNlbGVjdGlvbikgZm9yIEdSQVkvUkdCOyBoaWdoZXIgPSBsb29zZXIgZm9yXG4gICAqICBMQUJfRElTVEFOQ0Ug4oCUIG1hdGNoZXMgUXVQYXRoLiAqL1xuICBzZW5zaXRpdml0eT86IG51bWJlcjtcbiAgLyoqIFNxdWFyZSBwYXRjaCBzaXplIGluIHBpeGVscyAobXVzdCBiZSBvZGQpLiAqL1xuICBwYXRjaFNpemU/OiBudW1iZXI7XG4gIC8qKiBXaGVuIHRydWUsIHNraXAgYmx1ci90aHJlc2hvbGQgYW5kIGZsb29kLWZpbGwgYXQgZXhhY3QtbWF0Y2hcbiAgICogIChDbWQvQ3RybC1jbGljayBpbiBRdVBhdGgpLiAqL1xuICBzaW1wbGVNb2RlPzogYm9vbGVhbjtcbn1cblxuLyoqIE9wdGlvbnMgZm9yIHRoZSBicnVzaCByZWdpb24gdG9vbCAoUXVQYXRoLXN0eWxlKS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSUJydXNoT3B0aW9ucyB7XG4gIC8qKiBCcnVzaCBkaWFtZXRlciBpbiBtYXRyaXggKGltYWdlKSBwaXhlbHMuICovXG4gIHNpemU/OiBudW1iZXI7XG59XG4iXX0=
7
+ export const DEFAULT_SPATIAL_VIEW = {
8
+ colorBy: null,
9
+ pointScale: 1,
10
+ opacity: 1,
11
+ logScale: false,
12
+ percentileClip: [0.01, 0.99],
13
+ continuousColormap: null,
14
+ showVolume: true,
15
+ volumeOpacity: 0.5,
16
+ showPoints: true,
17
+ pointSection: null,
18
+ densityVolume: false,
19
+ densitySmoothing: 1,
20
+ geneMap: false,
21
+ geneMapSection: null,
22
+ geneMapVolume: false,
23
+ geneMapSmoothing: 1,
24
+ geneMapOpacity: 0.85,
25
+ };
26
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzcGxheS10eXBlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvY29udHJhY3RzL2Rpc3BsYXktdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7O0dBS0c7QUEyS0gsTUFBTSxDQUFDLE1BQU0sb0JBQW9CLEdBQXFCO0lBQ3BELE9BQU8sRUFBRSxJQUFJO0lBQ2IsVUFBVSxFQUFFLENBQUM7SUFDYixPQUFPLEVBQUUsQ0FBQztJQUNWLFFBQVEsRUFBRSxLQUFLO0lBQ2YsY0FBYyxFQUFFLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQztJQUM1QixrQkFBa0IsRUFBRSxJQUFJO0lBQ3hCLFVBQVUsRUFBRSxJQUFJO0lBQ2hCLGFBQWEsRUFBRSxHQUFHO0lBQ2xCLFVBQVUsRUFBRSxJQUFJO0lBQ2hCLFlBQVksRUFBRSxJQUFJO0lBQ2xCLGFBQWEsRUFBRSxLQUFLO0lBQ3BCLGdCQUFnQixFQUFFLENBQUM7SUFDbkIsT0FBTyxFQUFFLEtBQUs7SUFDZCxjQUFjLEVBQUUsSUFBSTtJQUNwQixhQUFhLEVBQUUsS0FBSztJQUNwQixnQkFBZ0IsRUFBRSxDQUFDO0lBQ25CLGNBQWMsRUFBRSxJQUFJO0NBQ3JCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFB1YmxpY2F0aW9uLWNyaXRpY2FsIHR5cGVzIHRoYXQgd2VyZSBgYW55YCBvbiB0aGUgcHVibGljIGNvbnRyYWN0c1xuICogKHJlZmFjdG9yaW5nIHBsYW4sIFN0ZXAgNikuIERlbGliZXJhdGVseSBwZXJtaXNzaXZlIOKAlCBldmVyeSBmaWVsZCBvcHRpb25hbCDigJRcbiAqIHNvIGV4aXN0aW5nIGhvc3RzICh3aGljaCBwYXNzIFByaW1lTkcgYFRyZWVOb2RlYHMgYW5kIHBsYWluIG9wdGlvbiBvYmplY3RzKVxuICoga2VlcCBjb21waWxpbmcgdW5jaGFuZ2VkIHdoaWxlIGNvbnN1bWVycyBmaW5hbGx5IGdldCBuYW1lZCBzaGFwZXMuXG4gKi9cblxuLyoqIEEgY29sb3JtYXAgdmFsdWUgYXMgUGxvdGx5IHVuZGVyc3RhbmRzIGl0OiBhIGJ1aWx0LWluIHNjYWxlIG5hbWUgKGUuZy5cbiAqICAnVmlyaWRpcycpIG9yIGFuIGlubGluZSBhcnJheSBvZiBgW3N0b3AsIGNvbG9yXWAgcGFpcnMuICovXG5leHBvcnQgdHlwZSBDb2xvcm1hcFZhbHVlID0gc3RyaW5nIHwgQXJyYXk8W251bWJlciwgc3RyaW5nXT47XG5cbi8qKiBPbmUgbm9kZSBvZiB0aGUgY29sb3JtYXAgc2VsZWN0b3IgdHJlZSAoc3RydWN0dXJhbGx5IGNvbXBhdGlibGUgd2l0aCB0aGVcbiAqICBQcmltZU5HIGBUcmVlTm9kZWBzIHRoZSBob3N0IHBhc3Nlcyk6IGdyb3VwIG5vZGVzIGNhcnJ5IGBjaGlsZHJlbmAsIGxlYWZcbiAqICBub2RlcyBjYXJyeSB0aGUgc2NhbGUgaW4gYGRhdGEudmFsdWVgICgrIGEgcHJldmlldyBpbWFnZSBpbiBgZGF0YS5zcmNgKS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29sb3JtYXBOb2RlIHtcbiAgbGFiZWw/OiBzdHJpbmc7XG4gIGRhdGE/OiB7IHZhbHVlPzogQ29sb3JtYXBWYWx1ZTsgc3JjPzogc3RyaW5nIH07XG4gIGNoaWxkcmVuPzogQ29sb3JtYXBOb2RlW107XG59XG5cbi8qKiBNYWdpYy13YW5kIHBpeGVsLWNvbXBhcmlzb24gc3BhY2UuICovXG5leHBvcnQgdHlwZSBXYW5kVHlwZSA9ICdHUkFZJyB8ICdSR0InIHwgJ0xBQl9ESVNUQU5DRSc7XG5cbi8qKiBPcHRpb25zIGZvciB0aGUgbWFnaWMtd2FuZCB0b29sIChRdVBhdGgtc3R5bGUpLiAqL1xuZXhwb3J0IGludGVyZmFjZSBJV2FuZE9wdGlvbnMge1xuICB0eXBlPzogV2FuZFR5cGU7XG4gIC8qKiBHYXVzc2lhbiBzaWdtYSBhcHBsaWVkIHRvIHRoZSBwYXRjaCBiZWZvcmUgdGhyZXNob2xkaW5nLiAqL1xuICBzaWdtYT86IG51bWJlcjtcbiAgLyoqIEhpZ2hlciA9IHN0cmljdGVyIChzbWFsbGVyIHNlbGVjdGlvbikgZm9yIEdSQVkvUkdCOyBoaWdoZXIgPSBsb29zZXIgZm9yXG4gICAqICBMQUJfRElTVEFOQ0Ug4oCUIG1hdGNoZXMgUXVQYXRoLiAqL1xuICBzZW5zaXRpdml0eT86IG51bWJlcjtcbiAgLyoqIFNxdWFyZSBwYXRjaCBzaXplIGluIHBpeGVscyAobXVzdCBiZSBvZGQpLiAqL1xuICBwYXRjaFNpemU/OiBudW1iZXI7XG4gIC8qKiBXaGVuIHRydWUsIHNraXAgYmx1ci90aHJlc2hvbGQgYW5kIGZsb29kLWZpbGwgYXQgZXhhY3QtbWF0Y2hcbiAgICogIChDbWQvQ3RybC1jbGljayBpbiBRdVBhdGgpLiAqL1xuICBzaW1wbGVNb2RlPzogYm9vbGVhbjtcbn1cblxuLyoqIE9wdGlvbnMgZm9yIHRoZSBicnVzaCByZWdpb24gdG9vbCAoUXVQYXRoLXN0eWxlKS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSUJydXNoT3B0aW9ucyB7XG4gIC8qKiBCcnVzaCBkaWFtZXRlciBpbiBtYXRyaXggKGltYWdlKSBwaXhlbHMuICovXG4gIHNpemU/OiBudW1iZXI7XG59XG5cbi8qKiBXaGF0IGRyaXZlcyBwb2ludCBjb2xvdXIgaW4gdGhlIHNwYXRpYWwtb21pY3MgbW9kZTogYW4gYW5ub3RhdGlvbiBjb2x1bW5cbiAqICBmcm9tIHRoZSBkYXRhc2V0LCBvciBvbmUgZmVhdHVyZSAoZ2VuZSkgdmVjdG9yIGZldGNoZWQgb24gZGVtYW5kLiAqL1xuZXhwb3J0IGludGVyZmFjZSBTcGF0aWFsQ29sb3JCeSB7XG4gIGtpbmQ6ICdjb2x1bW4nIHwgJ2ZlYXR1cmUnO1xuICBuYW1lOiBzdHJpbmc7XG59XG5cbi8qKiBEaXNwbGF5IHN0YXRlIGZvciB0aGUgc3BhdGlhbC1vbWljcyBwbG90IG1vZGUuIExpdmVzIGluIGBWaXN1YWxpemVyU3RvcmVgXG4gKiAgYWxvbmdzaWRlIHRoZSBjb2xvcm1hcC9jaGFubmVsIHN0YXRlIHNvIHRoZSByZW5kZXJlciByZWFjdHMgdG8gZWRpdHMgdGhlXG4gKiAgc2FtZSB3YXkgaXQgZG9lcyBmb3IgYW4gaW1hZ2UuICovXG5leHBvcnQgaW50ZXJmYWNlIFNwYXRpYWxWaWV3U3RhdGUge1xuICAvKiogQ29sb3VyIHNvdXJjZTsgYG51bGxgIHJlbmRlcnMgZXZlcnkgb2JzZXJ2YXRpb24gaW4gb25lIG5ldXRyYWwgY29sb3VyXG4gICAqICAodXNlZnVsIG9uIGl0cyBvd24g4oCUIGl0IHNob3dzIHdoZXJlIHRoZSB0aXNzdWUgYWN0dWFsbHkgaXMpLiAqL1xuICBjb2xvckJ5OiBTcGF0aWFsQ29sb3JCeSB8IG51bGw7XG4gIC8qKiBNdWx0aXBsaWVyIG9uIHRoZSBkYXRhc2V0J3MgcGh5c2ljYWwgbWFya2VyIHNpemUuIDEgPSB0cnVlIHNpemUsIHdoaWNoIGZvclxuICAgKiAgYSA1NSDCtW0gVmlzaXVtIHNwb3QgaXMgY29ycmVjdCBidXQgY2FuIGJlIGludmlzaWJsZSB3aGVuIHpvb21lZCBvdXQuICovXG4gIHBvaW50U2NhbGU6IG51bWJlcjtcbiAgLyoqIEFscGhhIGZvciBwb2ludHMgdGhhdCBhcmUgbm90IG11dGVkLiAqL1xuICBvcGFjaXR5OiBudW1iZXI7XG4gIC8qKiBMb2ctc2NhbGUgY29udGludW91cyB2YWx1ZXMgYmVmb3JlIG1hcHBpbmcgdGhlbSBvbnRvIHRoZSBjb2xvcm1hcC4gU2VlZGVkXG4gICAqICBmcm9tIHRoZSBjb2x1bW4ncyBgbG9nU2NhbGVIaW50YCDigJQgY291bnQgZGF0YSBuZWVkcyBpdC4gKi9cbiAgbG9nU2NhbGU6IGJvb2xlYW47XG4gIC8qKiBQZXJjZW50aWxlIGNsaXAgZm9yIHRoZSBjb250cmFzdCB3aW5kb3cgYXMgYFtsbywgaGldYCBmcmFjdGlvbnMsIHNvIGFcbiAgICogIGhhbmRmdWwgb2Ygc2F0dXJhdGVkIG9ic2VydmF0aW9ucyBkb24ndCBmbGF0dGVuIHRoZSByZXN0LiAqL1xuICAgcGVyY2VudGlsZUNsaXA6IFtudW1iZXIsIG51bWJlcl07XG4gIC8qKlxuICAgKiBDb2xvcm1hcCBmb3IgQ09OVElOVU9VUyBzcGF0aWFsIGNvbG91cmluZyDigJQgYSBnZW5lLCBhIG51bWVyaWMgY29sdW1uIOKAlCBhcyBhXG4gICAqIHtAbGluayBDb2xvcm1hcFZhbHVlfSwgdGhlIHNhbWUgc2hhcGUgdGhlIGRpc3BsYXkgY29sb3JtYXAgY2FycmllczogYSBzY2FsZVxuICAgKiBOQU1FIGZvciB0aGUgYnVpbHQtaW5zLCBvciBhbiBpbmxpbmUgYFtzdG9wLCBjb2xvdXJdYCBhcnJheSBmb3IgdGhlIHJlc3QuXG4gICAqIE51bGwgZm9sbG93cyB0aGUgZGlzcGxheSBjb2xvcm1hcC5cbiAgICpcbiAgICogSXRzIG93biBzZXR0aW5nIGJlY2F1c2UgdGhlIGRpc3BsYXkgY29sb3JtYXAgYmVsb25ncyB0byB0aGUgdGlzc3VlIGltYWdlIGFuZFxuICAgKiBpcyB1c3VhbGx5IGEgZ3JleSByYW1wLCB3aGljaCBpcyB0aGUgd3JvbmcgdGhpbmcgdG8gcmVhZCBhIG1lYXN1cmVtZW50XG4gICAqIHRocm91Z2g6IGdyZXkgb3ZlciBncmV5IGNhbm5vdCBiZSB0b2xkIGFwYXJ0IGZyb20gdGhlIGFuYXRvbXkuIEZvbGxvd2luZyBpdFxuICAgKiAod2l0aCBhIFZpcmlkaXMgZmFsbGJhY2sgZm9yIGV4YWN0bHkgdGhhdCBjYXNlKSBpcyBhIHJlYXNvbmFibGUgZGVmYXVsdCBhbmQgYVxuICAgKiBwb29yIGNlaWxpbmcsIHNpbmNlIHdoaWNoIGdyYWRpZW50IHJlYWRzIGJlc3QgaXMgYSBqdWRnZW1lbnQgYWJvdXQgdGhlIGRhdGEuXG4gICAqXG4gICAqIE9uZSBzZXR0aW5nIGZvciB0aGUgbWFya2VycywgdGhlIDJEIGdlbmUgbWFwIGFuZCB0aGUgM0QgZ2VuZSBtYXAgdG9nZXRoZXIsIHNvXG4gICAqIHRoZSBmaWVsZCB1bmRlciB0aGUgY2VsbHMgYW5kIHRoZSBjZWxscyBvdmVyIGl0IGNhbm5vdCBkaXNhZ3JlZSBhYm91dCB3aGF0IGFcbiAgICogY29sb3VyIG1lYW5zIOKAlCBhbmQgdGhlIHBhbmVsJ3Mgb3duIGNvbG91ciBiYXIgaXMgYnVpbHQgZnJvbSBpdCB0b28uXG4gICAqL1xuICBjb250aW51b3VzQ29sb3JtYXA6IENvbG9ybWFwVmFsdWUgfCBudWxsO1xuICAvKipcbiAgICogV2hhdCB0aGUgM0Qgc2NlbmUgZHJhd3MuIFRoZSB0aHJlZSB0aGluZ3MgaW4gaXQg4oCUIHRoZSByZWZlcmVuY2Ugdm9sdW1lLCB0aGVcbiAgICogb2JzZXJ2YXRpb24gY2xvdWQgYW5kIHRoZSBjbHVzdGVyIGRlbnNpdHkgdm9sdW1lcyDigJQgb2NjdXB5IHRoZSBzYW1lIHNwYWNlLCBzb1xuICAgKiBhbnkgdHdvIG9mIHRoZW0gaGlkZSBlYWNoIG90aGVyIHRvIHNvbWUgZGVncmVlLiBUaGVzZSBhcmUgaW5kZXBlbmRlbnQgYmVjYXVzZVxuICAgKiB0aGUgdXNlZnVsIHZpZXdzIGFyZSB0aGUgY29tYmluYXRpb25zOiB0aGUgdm9sdW1lcyBhbG9uZSB0byByZWFkIGFuIGVzdGltYXRlZFxuICAgKiBkaXN0cmlidXRpb24sIG9uZSBzZWN0aW9uJ3MgY2VsbHMgb3ZlciB0aGVtIHRvIGNoZWNrIHRoYXQgZXN0aW1hdGUgYWdhaW5zdCB0aGVcbiAgICogbWVhc3VyZW1lbnQsIHRoZSBhbmF0b215IGFsb25lIHRvIGZpbmQgYSBsYW5kbWFyay5cbiAgICpcbiAgICogVmlzaWJpbGl0eSBvbmx5IOKAlCB0aGUgbGF5ZXJzIHN0YXkgYnVpbHQsIHNvIHRvZ2dsaW5nIG9uZSBiYWNrIG9uIGlzIGltbWVkaWF0ZVxuICAgKiBhbmQgZG9lcyBub3QgcmUtcnVuIGEgcmFzdGVyaXNhdGlvbi4ge0BsaW5rIGRlbnNpdHlWb2x1bWV9IGlzIHRoZSBleGNlcHRpb24gYW5kXG4gICAqIGdlbnVpbmVseSBnYXRlcyBjb25zdHJ1Y3Rpb24sIGJlY2F1c2UgYnVpbGRpbmcgc2l4IHZvbHVtZXMgaXMgbm90IGZyZWUuXG4gICAqL1xuICBzaG93Vm9sdW1lOiBib29sZWFuO1xuICAvKipcbiAgICogVGhlIHJlZmVyZW5jZSB2b2x1bWUncyBvcGFjaXR5LlxuICAgKlxuICAgKiBJdHMgb3duLCBub3Qge0BsaW5rIG9wYWNpdHl9ICh3aGljaCBiZWxvbmdzIHRvIHRoZSBtYXJrZXJzKTogdGhlIHZvbHVtZSBpcyBhXG4gICAqIEJBQ0tEUk9QLCBhbmQgcmVhZGluZyB0aGUgY2xvdWQgb3IgYSBkZW5zaXR5IGZpZWxkIHRocm91Z2ggaXQgbWVhbnMgdHVybmluZ1xuICAgKiB0aGUgYW5hdG9teSBkb3duIHdpdGhvdXQgdG91Y2hpbmcgdGhlIGRhdGEgZHJhd24gb3ZlciBpdC4gUmFuZ2VzIGxvd2VyIHRoYW5cbiAgICogdGhlIG1hcmtlcnMnIHNsaWRlciBmb3IgdGhlIHNhbWUgcmVhc29uIOKAlCBhIGZhaW50IGFuYXRvbWljYWwgaGludCBpcyBhIHVzZWZ1bFxuICAgKiBzZXR0aW5nIGZvciBhIGJhY2tkcm9wIGFuZCBhIHVzZWxlc3Mgb25lIGZvciB0aGUgbWVhc3VyZW1lbnQuXG4gICAqL1xuICB2b2x1bWVPcGFjaXR5OiBudW1iZXI7XG4gIC8qKiBEcmF3IHRoZSBvYnNlcnZhdGlvbiBjbG91ZCAoM0QpLiAqL1xuICBzaG93UG9pbnRzOiBib29sZWFuO1xuICAvKipcbiAgICogUmVzdHJpY3QgdGhlIGNsb3VkIHRvIE9ORSBpbWFnZWQgc2VjdGlvbiwgYnkgaW5kZXggaW50byB0aGUgZGF0YXNldCdzIHNhbXBsZWRcbiAgICogc2VjdGlvbnM7IG51bGwgZHJhd3MgZXZlcnkgc2VjdGlvbi5cbiAgICpcbiAgICogVGhlIHdob2xlIGNsb3VkIGlzIGEgc3RhY2sgb2YgZGlzY3MgdGhhdCBoaWRlcyB3aGF0ZXZlciBpcyBkcmF3biBiZXR3ZWVuIHRoZW0uXG4gICAqIE9uZSBzZWN0aW9uIGF0IGEgdGltZSBpcyB0aGUgdmlldyB0aGF0IGFuc3dlcnMgXCJkb2VzIHRoZSBlc3RpbWF0ZWQgZmllbGRcbiAgICogYWN0dWFsbHkgZm9sbG93IHRoZSBjZWxscyBJIG1lYXN1cmVkXCIg4oCUIGFuZCBpdCBpcyBvbmx5IG9mZmVyZWQgZm9yIGRhdGEgdGhhdFxuICAgKiByZWFsbHkgaXMgc2VjdGlvbmVkIChzZWUgYHNhbXBsZWRTZWN0aW9uc2ApLlxuICAgKi9cbiAgcG9pbnRTZWN0aW9uOiBudW1iZXIgfCBudWxsO1xuICAvKipcbiAgICogRHJhdyBlYWNoIGNsdXN0ZXIgYXMgYSB0cmFuc2x1Y2VudCBERU5TSVRZIHZvbHVtZSBhbG9uZ3NpZGUgdGhlIDNEIGNsb3VkLlxuICAgKlxuICAgKiBTZXJpYWwgc2VjdGlvbnMgaHVuZHJlZHMgb2YgbWljcm9ucyBhcGFydCBtYWtlIGEgY2xvdWQgaGFyZCB0byByZWFkIGFzIGFuXG4gICAqIGFuYXRvbWljYWwgZGlzdHJpYnV0aW9uIOKAlCB0aGUgZXllIGNhbm5vdCBpbnRlZ3JhdGUgZGlzY3MgaW50byBhIHNoYXBlLiBBXG4gICAqIGRlbnNpdHkgZmllbGQgY2FuIGJlIGVzdGltYXRlZCBiZXR3ZWVuIHRoZSBpbWFnZWQgcGxhbmVzIChhIGNvbnRpbnVvdXNcbiAgICogZXN0aW1hdGUsIHVubGlrZSBpbmRpdmlkdWFsIGNlbGxzLCB3aGljaCBoYXZlIG5vIGNvcnJlc3BvbmRlbmNlIHRvXG4gICAqIGludGVycG9sYXRlIGFsb25nKSBhbmQgcmVuZGVycyBhcyBhIGNsb3VkIHRoYXQgcmVhZHMgYXMgYW4gZXN0aW1hdGUuXG4gICAqL1xuICBkZW5zaXR5Vm9sdW1lOiBib29sZWFuO1xuICAvKiogTXVsdGlwbGllciBvbiB0aGUgZGVmYXVsdCBrZXJuZWwgYmFuZHdpZHRoLiBBYm92ZSAxIGlzIHNtb290aGVyIGFuZCBsZXNzXG4gICAqICBjb21taXR0YWw7IGJlbG93IDEgZXhwb3NlcyB0aGUgaW5kaXZpZHVhbCBzZWN0aW9ucy4gKi9cbiAgZGVuc2l0eVNtb290aGluZzogbnVtYmVyO1xuICAvKipcbiAgICogRHJhdyB0aGUgYWN0aXZlIEdFTkUgYXMgYSBjb250aW51b3VzIGZpZWxkIHVuZGVyIHRoZSBvYnNlcnZhdGlvbnMgKDJEKS5cbiAgICpcbiAgICogQ29sb3VyaW5nIHRoZSBtYXJrZXJzIGJ5IGEgZ2VuZSBzYXlzIHdoaWNoIGNlbGxzIGV4cHJlc3MgaXQ7IGl0IGNhbm5vdCBzYXlcbiAgICogd2hlcmUsIGJlY2F1c2UgdGhlIGV5ZSB3aWxsIG5vdCBpbnRlZ3JhdGUgdGhvdXNhbmRzIG9mIGRvdHMgaW50byBhIHRlcnJpdG9yeS5cbiAgICogVGhlIGZpZWxkIGlzIGFuIGVzdGltYXRlIOKAlCBhIGtlcm5lbC13ZWlnaHRlZCBtZWFuIHBlciBjZWxsLCB0cmFuc3BhcmVudCB3aGVyZVxuICAgKiBubyBjZWxsIHdhcyBtZWFzdXJlZCDigJQgYW5kIGl0IGlzIGRyYXduIGJlbmVhdGggdGhlIGNlbGxzLCBub3QgaW5zdGVhZCBvZiB0aGVtLFxuICAgKiBzbyB0aGUgbWVhc3VyZW1lbnQgc3RheXMgb24gc2NyZWVuIG5leHQgdG8gdGhlIGludGVycG9sYXRpb24uXG4gICAqXG4gICAqIElnbm9yZWQgdW5sZXNzIHRoZSBjb2xvdXIgc291cmNlIGlzIGEgZ2VuZTogdGhlcmUgaXMgbm90aGluZyBlbHNlIHRvIG1hcC5cbiAgICovXG4gIGdlbmVNYXA6IGJvb2xlYW47XG4gIC8qKlxuICAgKiBSZXN0cmljdCB0aGUgM0QgZ2VuZSBtYXAgdG8gT05FIGltYWdlZCBzZWN0aW9uLCBieSBpbmRleCBpbnRvIHRoZSBkYXRhc2V0J3NcbiAgICogc2FtcGxlZCBzZWN0aW9uczsgbnVsbCBkcmF3cyBldmVyeSBzZWN0aW9uJ3Mgc2hlZXQuXG4gICAqXG4gICAqIFNlcGFyYXRlIGZyb20ge0BsaW5rIHBvaW50U2VjdGlvbn0gc28gdGhlIGNvbWJpbmF0aW9ucyBzdGF5IG9wZW46IGFsbCB0aGVcbiAgICogc2hlZXRzIHdpdGggb25lIHNlY3Rpb24ncyBjZWxscyBvdmVyIHRoZW0gaXMgYSB1c2VmdWwgdmlldywgYW5kIHNvIGlzIG9uZVxuICAgKiBzaGVldCBpbnNpZGUgdGhlIHdob2xlIGNsb3VkLiBJZ25vcmVkIHdoaWxlIHtAbGluayBnZW5lTWFwVm9sdW1lfSBpcyBzZXQg4oCUXG4gICAqIGludGVycG9sYXRpbmcgYSBzaW5nbGUgc2VjdGlvbiBhbG9uZyB6IHdvdWxkIHNtZWFyIG9uZSBzbGlkZSB0aHJvdWdoIHRoZVxuICAgKiBzcGVjaW1lbidzIHdob2xlIGRlcHRoIGFuZCBjYWxsIGl0IGFuIGVzdGltYXRlLlxuICAgKi9cbiAgZ2VuZU1hcFNlY3Rpb246IG51bWJlciB8IG51bGw7XG4gIC8qKlxuICAgKiBTbW9vdGggdGhlIHBlci1zZWN0aW9uIGdlbmUgbWFwcyBhbG9uZyB6IGludG8gYSBjb250aW51b3VzIFZPTFVNRSAoM0QpLlxuICAgKlxuICAgKiBUaGUgc2hlZXRzIGFyZSB3aGF0IHdhcyBtZWFzdXJlZCDigJQgb25lIGZpZWxkIHBlciBpbWFnZWQgc2xpZGUsIHdpdGggdGhlIGdhcHNcbiAgICogYmV0d2VlbiB0aGVtIGVtcHR5LiBUaGlzIHR1cm5zIHRoZW0gaW50byBhbiBlc3RpbWF0ZSBkZWZpbmVkIGJldHdlZW4gdGhlXG4gICAqIHNsaWRlcywgdGhlIHNhbWUgbW92ZSB0aGUgY2x1c3RlciBkZW5zaXR5IHZvbHVtZXMgbWFrZSBhbmQgd2l0aCB0aGUgc2FtZVxuICAgKiBjYXZlYXQ6IGEgZmllbGQgbWF5IGJlIGludGVycG9sYXRlZCBiZXR3ZWVuIHNlY3Rpb25zLCBpbmRpdmlkdWFsIGNlbGxzIG1heVxuICAgKiBub3QsIGFuZCB0aGUgcmVzdWx0IGlzIGRyYXduIGFzIGEgdHJhbnNsdWNlbnQgY2xvdWQgc28gaXQgY2Fubm90IGJlIG1pc3Rha2VuXG4gICAqIGZvciBtZWFzdXJlbWVudC5cbiAgICovXG4gIGdlbmVNYXBWb2x1bWU6IGJvb2xlYW47XG4gIC8qKiBNdWx0aXBsaWVyIG9uIHRoZSBnZW5lIG1hcCdzIGtlcm5lbCBiYW5kd2lkdGguICovXG4gIGdlbmVNYXBTbW9vdGhpbmc6IG51bWJlcjtcbiAgLyoqIFRoZSBnZW5lIG1hcCdzIG93biBvcGFjaXR5LiBTZXBhcmF0ZSBmcm9tIHtAbGluayBvcGFjaXR5fSwgd2hpY2ggYmVsb25ncyB0b1xuICAgKiAgdGhlIG1hcmtlcnM6IHR1cm5pbmcgdGhlIGNlbGxzIGRvd24gdG8gcmVhZCB0aGUgZmllbGQgdW5kZXJuZWF0aCBtdXN0IG5vdFxuICAgKiAgdHVybiB0aGUgZmllbGQgZG93biB3aXRoIHRoZW0uICovXG4gIGdlbmVNYXBPcGFjaXR5OiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX1NQQVRJQUxfVklFVzogU3BhdGlhbFZpZXdTdGF0ZSA9IHtcbiAgY29sb3JCeTogbnVsbCxcbiAgcG9pbnRTY2FsZTogMSxcbiAgb3BhY2l0eTogMSxcbiAgbG9nU2NhbGU6IGZhbHNlLFxuICBwZXJjZW50aWxlQ2xpcDogWzAuMDEsIDAuOTldLFxuICBjb250aW51b3VzQ29sb3JtYXA6IG51bGwsXG4gIHNob3dWb2x1bWU6IHRydWUsXG4gIHZvbHVtZU9wYWNpdHk6IDAuNSxcbiAgc2hvd1BvaW50czogdHJ1ZSxcbiAgcG9pbnRTZWN0aW9uOiBudWxsLFxuICBkZW5zaXR5Vm9sdW1lOiBmYWxzZSxcbiAgZGVuc2l0eVNtb290aGluZzogMSxcbiAgZ2VuZU1hcDogZmFsc2UsXG4gIGdlbmVNYXBTZWN0aW9uOiBudWxsLFxuICBnZW5lTWFwVm9sdW1lOiBmYWxzZSxcbiAgZ2VuZU1hcFNtb290aGluZzogMSxcbiAgZ2VuZU1hcE9wYWNpdHk6IDAuODUsXG59O1xuIl19
@@ -8,4 +8,4 @@
8
8
  * structurally, so the host keeps passing its own instances unchanged.
9
9
  */
10
10
  export {};
11
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2UuY29udHJhY3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL2NvbnRyYWN0cy9pbWFnZS5jb250cmFjdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7R0FRRyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTGlicmFyeS1vd25lZCBkYXRhIGludGVyZmFjZXMgZm9yIHRoZSBpbWFnZSB0aGUgdmlzdWFsaXphdGlvbiByZW5kZXJzLlxuICpcbiAqIFRoZSB2aXN1YWxpemF0aW9uIHBhY2thZ2UgbXVzdCBub3QgaW1wb3J0IHRoZSBob3N0IGFwcCdzIGNvbmNyZXRlIG1vZGVsc1xuICogKGBtYWluL21vZGVscy9maWxlLWluZm9gKSwgb3IgaXQgY2FuJ3QgYmVjb21lIGEgc3RhbmRhbG9uZSBsaWJyYXJ5LiBUaGVzZVxuICogc2xpbSBpbnRlcmZhY2VzIGRlY2xhcmUgb25seSB0aGUgZmllbGRzIHRoZSBsaWJyYXJ5IHJlYWRzL3dyaXRlczsgdGhlIGhvc3Qnc1xuICogYEltYWdlSW5mb2AvYEltYWdlTWV0YWRhdGFgIGNsYXNzZXMgYXJlIHB1cmUgZGF0YSBob2xkZXJzIHRoYXQgc2F0aXNmeSB0aGVtXG4gKiBzdHJ1Y3R1cmFsbHksIHNvIHRoZSBob3N0IGtlZXBzIHBhc3NpbmcgaXRzIG93biBpbnN0YW5jZXMgdW5jaGFuZ2VkLlxuICovXG5cbi8qKiBQZXItY2hhbm5lbCBtZXRhZGF0YSBmcm9tIHRoZSBzZXJ2ZXIgZGVzY3JpcHRvciAoaXNzdWUgIzc2KS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSUNoYW5uZWxJbmZvIHtcbiAgbmFtZTogc3RyaW5nO1xuICAvKiogU3VnZ2VzdGVkIGRpc3BsYXkgdGludCBhcyBcIiNSUkdHQkJcIi4gKi9cbiAgY29sb3I6IHN0cmluZztcbiAgLyoqIEVtYmVkZGVkIDI1Ni1lbnRyeSBkaXNwbGF5IExVVCBhcyBcIiNSUkdHQkJcIiAoaW50ZW5zaXR54oaSY29sb3IpLCBvclxuICAgKiAgbnVsbC91bmRlZmluZWQgd2hlbiB0aGUgZmlsZSBoYXMgbm8gcGFsZXR0ZSBmb3IgdGhpcyBjaGFubmVsLiAqL1xuICBsdXQ/OiBzdHJpbmdbXSB8IG51bGw7XG4gIGJpdERlcHRoPzogbnVtYmVyO1xuICAvKiogUGl4ZWwtdHlwZSBtaW5pbXVtIChlLmcuIDAgZm9yIHVuc2lnbmVkKS4gTmF0aXZlLXVuaXQgZmxvb3Igb2YgdGhlIHdpbmRvdy4gKi9cbiAgbWluQWxsb3dlZD86IG51bWJlcjtcbiAgLyoqIFBpeGVsLXR5cGUgbWF4aW11bSAoZS5nLiA2NTUzNSBmb3IgdW5zaWduZWQgMTYtYml0KS4gTmF0aXZlLXVuaXQgY2VpbGluZy4gKi9cbiAgbWF4QWxsb3dlZD86IG51bWJlcjtcbn1cblxuLyoqIFBlci1zZXJpZXMgaW1hZ2UgbWV0YWRhdGEgKHBoeXNpY2FsIHNpemUgKyBkaW1lbnNpb25zKS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSUltYWdlTWV0YWRhdGEge1xuICBjaGFubmVsQ291bnQ6IG51bWJlcjtcbiAgcmdiQ2hhbm5lbHM6IG51bWJlcjtcbiAgeDogbnVtYmVyO1xuICB5OiBudW1iZXI7XG4gIHo6IG51bWJlcjtcbiAgLyoqIFBoeXNpY2FsIHBpeGVsIHNpemUgaW4gwrVtOyBudWxsL3VuZGVmaW5lZCB3aGVuIHRoZSBmb3JtYXQgcmVwb3J0cyBub25lLiAqL1xuICBtcHBYPzogbnVtYmVyIHwgbnVsbDtcbiAgbXBwWT86IG51bWJlciB8IG51bGw7XG4gIC8qKiBQZXItY2hhbm5lbCBuYW1lL2NvbG9yL0xVVCBmb3IgbXVsdGljaGFubmVsIChub24tUkdCKSBpbWFnZXMsIHdoZW4ga25vd24uICovXG4gIGNoYW5uZWxJbmZvPzogSUNoYW5uZWxJbmZvW10gfCBudWxsO1xufVxuXG4vKiogVGhlIGltYWdlIGN1cnJlbnRseSBiZWluZyB2aXN1YWxpemVkLiBGaWVsZCBvcHRpb25hbGl0eSBtaXJyb3JzIHRoZSBob3N0J3NcbiAqICBgSW1hZ2VJbmZvYCBzbyBpdHMgaW5zdGFuY2VzIGFyZSBhc3NpZ25hYmxlIHRvIHRoaXMgaW50ZXJmYWNlLiAqL1xuZXhwb3J0IGludGVyZmFjZSBJSW1hZ2VJbmZvIHtcbiAgaXNHcmF5c2NhbGU6IGJvb2xlYW47XG4gIHRydWVJbWFnZVNpemU6IG51bWJlcltdO1xuICB1cmxzOiBzdHJpbmdbXTtcbiAgLyoqIE9wdGlvbmFsIHNtYWxsLXRpZXIgVVJMcyAoZmFzdCBibHVycnkgcGxhY2Vob2xkZXIpLCAxOjEgd2l0aCBgdXJsc2AuICovXG4gIHNtYWxsVXJscz86IHN0cmluZ1tdO1xuICBpc1N0YWNrOiBib29sZWFuO1xuICBzaG93U3RhY2s6IGJvb2xlYW47XG4gIHNjYWxlUmF0aW86IGJvb2xlYW47XG4gIGZpbGVOYW1lOiBzdHJpbmc7XG4gIHJvaUpzb25TdHI/OiBzdHJpbmc7XG4gIC8qKiBQZXItc2xpY2UgUk9JIEdlb0pTT04sIGFsaWduZWQgMToxIHdpdGggYHVybHNgLCBmb3IgYSBmb2xkZXIgc3RhY2sgd2hlcmVcbiAgICogIGVhY2ggc2xpY2UgaXMgYSBzZXBhcmF0ZSBmaWxlIHdpdGggaXRzIG93biBzaWJsaW5nIGA8c3RlbT4uZ2VvanNvbmBcbiAgICogIChgbnVsbGAgZm9yIHNsaWNlcyB3aXRob3V0IG9uZSkuIFdoZW4gcHJlc2VudCwgdGhlIGNvbXBvbmVudCBhcHBsaWVzXG4gICAqICBgcm9pSnNvblN0cnNbel1gIGZvciB0aGUgZGlzcGxheWVkIHNsaWNlIGFuZCBzd2FwcyBpdCBvbiBzY3J1YiDigJQgYXNcbiAgICogIG9wcG9zZWQgdG8gdGhlIHNjYWxhciBgcm9pSnNvblN0cmAsIHdoaWNoIGlzIG9uZSBST0kgc2V0IGZvciB0aGUgd2hvbGVcbiAgICogIGltYWdlIChhIHNpbmdsZSBmaWxlIG9yIGEgc2VydmVyIHotc3RhY2spLiAoaml0LXVpIzkzKSAqL1xuICByb2lKc29uU3Rycz86IChzdHJpbmcgfCBudWxsKVtdO1xuICAvKiogUGVyLXNsaWNlLCBwZXItY2hhbm5lbCBwbGFuZSBVUkxzIGZvciBhIFNFUlZFUkxFU1MgbXVsdGljaGFubmVsIGltYWdlXG4gICAqICAoYHRpbGVkOiBmYWxzZWAgKyBgaW1hZ2VNZXRhWzBdLmNoYW5uZWxDb3VudCA+IDFgKS4gYGNoYW5uZWxVcmxzW3pdW2NdYFxuICAgKiAgaXMgYSBjb21wbGV0ZSBzaW5nbGUtYmFuZCBpbWFnZSBvZiBjaGFubmVsIGMgYXQgc2xpY2Ugei4gVGhlIE9TRCBzaW1wbGVcbiAgICogIHBhdGggY29tcG9zaXRlcyB0aGVtIGNsaWVudC1zaWRlIOKAlCBwZXItY2hhbm5lbCBjb2xvdXIvd2luZG93L2dhbW1hIGZyb21cbiAgICogIHRoZSBjaGFubmVsIHBhbmUg4oCUIGluc3RlYWQgb2Ygb3BlbmluZyB0aGUgZmxhdCBgdXJsc1t6XWAuIChqaXQtdWkjNzYpICovXG4gIGNoYW5uZWxVcmxzPzogc3RyaW5nW11bXTtcbiAgaW1hZ2VNZXRhOiBJSW1hZ2VNZXRhZGF0YVtdO1xuICAvKiogSG93IHRoZSBPcGVuU2VhZHJhZ29uIGJhY2tlbmQgc2hvdWxkIHNvdXJjZSB0aGlzIGltYWdlLlxuICAgKiAgLSBgdHJ1ZWAvYWJzZW50IChkZWZhdWx0KTogc2VydmVyLXRpbGVkIOKAlCBPU0QgcG9sbHMgYC90aWxlcy9pbmZvYCBmb3IgYVxuICAgKiAgICBweXJhbWlkIGFuZCBmZXRjaGVzIHRpbGVzIGZyb20gdGhlIHNsaWRlLWNyb3Agc2VydmVyICh3aG9sZS1zbGlkZSBwYXRoKS5cbiAgICogIC0gYGZhbHNlYDogYSBzZWxmLWNvbnRhaW5lZCwgZGlyZWN0bHktbG9hZGFibGUgaW1hZ2Ug4oCUIGB1cmxzW3pJbmRleF1gIGlzIGFcbiAgICogICAgY29tcGxldGUgaW1hZ2UgKGUuZy4gYSBgYmxvYjpgIFVSTCBidWlsdCBmcm9tIGEgY2xpZW50LXNpZGUgcGl4ZWwgYnVmZmVyKSxcbiAgICogICAgb3BlbmVkIHZpYSBPU0QncyBzaW5nbGUtaW1hZ2Ugc291cmNlIHdpdGggbm8gdGlsZSBzZXJ2ZXIuIExldHMgaW4tbWVtb3J5XG4gICAqICAgIGltYWdlcyAodGhlIHByb2Nlc3NpbmcgcGlwZWxpbmUpIHVzZSB0aGUgT1NEIHZpZXdlciB3aXRob3V0IGEgcm91bmQtdHJpcC4gKi9cbiAgdGlsZWQ/OiBib29sZWFuO1xuICAvKiogT25lLXNob3QgaGludDogb3BlbiB0aGUgc3RhY2sgb24gdGhpcyBzbGljZSBpbnN0ZWFkIG9mIHNsaWNlIDAgKGUuZy4gdGhlXG4gICAqICBob3N0IGNsaWNrZWQgYSBzcGVjaWZpYyBmaWxlIHdpdGhpbiBhIG51bWJlcmVkIGltYWdlIHNlcmllcykuIFRoZVxuICAgKiAgY29tcG9uZW50IGNvbnN1bWVzIGFuZCBjbGVhcnMgdGhpcyB0aGUgZmlyc3QgdGltZSBpdCBzZWVzIHRoZSBvYmplY3QsIHNvXG4gICAqICByZS1kZWxpdmVyaW5nIHRoZSBzYW1lIEltYWdlSW5mbyAoZS5nLiBhIHBsb3QtdHlwZSBzd2l0Y2gpIGRvZXNuJ3QgcmVzZXRcbiAgICogIHRoZSB1c2VyJ3MgY3VycmVudCBzY3J1YiBwb3NpdGlvbi4gKi9cbiAgaW5pdGlhbFpJbmRleD86IG51bWJlcjtcbn1cbiJdfQ==
11
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2UuY29udHJhY3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL2NvbnRyYWN0cy9pbWFnZS5jb250cmFjdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7R0FRRyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTGlicmFyeS1vd25lZCBkYXRhIGludGVyZmFjZXMgZm9yIHRoZSBpbWFnZSB0aGUgdmlzdWFsaXphdGlvbiByZW5kZXJzLlxuICpcbiAqIFRoZSB2aXN1YWxpemF0aW9uIHBhY2thZ2UgbXVzdCBub3QgaW1wb3J0IHRoZSBob3N0IGFwcCdzIGNvbmNyZXRlIG1vZGVsc1xuICogKGBtYWluL21vZGVscy9maWxlLWluZm9gKSwgb3IgaXQgY2FuJ3QgYmVjb21lIGEgc3RhbmRhbG9uZSBsaWJyYXJ5LiBUaGVzZVxuICogc2xpbSBpbnRlcmZhY2VzIGRlY2xhcmUgb25seSB0aGUgZmllbGRzIHRoZSBsaWJyYXJ5IHJlYWRzL3dyaXRlczsgdGhlIGhvc3Qnc1xuICogYEltYWdlSW5mb2AvYEltYWdlTWV0YWRhdGFgIGNsYXNzZXMgYXJlIHB1cmUgZGF0YSBob2xkZXJzIHRoYXQgc2F0aXNmeSB0aGVtXG4gKiBzdHJ1Y3R1cmFsbHksIHNvIHRoZSBob3N0IGtlZXBzIHBhc3NpbmcgaXRzIG93biBpbnN0YW5jZXMgdW5jaGFuZ2VkLlxuICovXG5cbi8qKiBQZXItY2hhbm5lbCBtZXRhZGF0YSBmcm9tIHRoZSBzZXJ2ZXIgZGVzY3JpcHRvciAoaXNzdWUgIzc2KS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSUNoYW5uZWxJbmZvIHtcbiAgbmFtZTogc3RyaW5nO1xuICAvKiogU3VnZ2VzdGVkIGRpc3BsYXkgdGludCBhcyBcIiNSUkdHQkJcIi4gKi9cbiAgY29sb3I6IHN0cmluZztcbiAgLyoqIEVtYmVkZGVkIDI1Ni1lbnRyeSBkaXNwbGF5IExVVCBhcyBcIiNSUkdHQkJcIiAoaW50ZW5zaXR54oaSY29sb3IpLCBvclxuICAgKiAgbnVsbC91bmRlZmluZWQgd2hlbiB0aGUgZmlsZSBoYXMgbm8gcGFsZXR0ZSBmb3IgdGhpcyBjaGFubmVsLiAqL1xuICBsdXQ/OiBzdHJpbmdbXSB8IG51bGw7XG4gIGJpdERlcHRoPzogbnVtYmVyO1xuICAvKiogUGl4ZWwtdHlwZSBtaW5pbXVtIChlLmcuIDAgZm9yIHVuc2lnbmVkKS4gTmF0aXZlLXVuaXQgZmxvb3Igb2YgdGhlIHdpbmRvdy4gKi9cbiAgbWluQWxsb3dlZD86IG51bWJlcjtcbiAgLyoqIFBpeGVsLXR5cGUgbWF4aW11bSAoZS5nLiA2NTUzNSBmb3IgdW5zaWduZWQgMTYtYml0KS4gTmF0aXZlLXVuaXQgY2VpbGluZy4gKi9cbiAgbWF4QWxsb3dlZD86IG51bWJlcjtcbn1cblxuLyoqIFBlci1zZXJpZXMgaW1hZ2UgbWV0YWRhdGEgKHBoeXNpY2FsIHNpemUgKyBkaW1lbnNpb25zKS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSUltYWdlTWV0YWRhdGEge1xuICBjaGFubmVsQ291bnQ6IG51bWJlcjtcbiAgcmdiQ2hhbm5lbHM6IG51bWJlcjtcbiAgeDogbnVtYmVyO1xuICB5OiBudW1iZXI7XG4gIHo6IG51bWJlcjtcbiAgLyoqIFBoeXNpY2FsIHBpeGVsIHNpemUgaW4gwrVtOyBudWxsL3VuZGVmaW5lZCB3aGVuIHRoZSBmb3JtYXQgcmVwb3J0cyBub25lLiAqL1xuICBtcHBYPzogbnVtYmVyIHwgbnVsbDtcbiAgbXBwWT86IG51bWJlciB8IG51bGw7XG4gIC8qKiBQaHlzaWNhbCBzcGFjaW5nIEJFVFdFRU4gc2xpY2VzIGluIMK1bSDigJQgdGhlIHogY291bnRlcnBhcnQgb2YgYG1wcFhgL2BtcHBZYCxcbiAgICogIGZvciBhIHN0YWNrIHRoYXQga25vd3MgaXQgKGEgcmVzYW1wbGVkIHZvbHVtZSwgYSBjb25mb2NhbCBzdGFjaykuIEl0IGlzIHdoYXRcbiAgICogIGxldHMgdGhlIDNEIHZvbHVtZSB2aWV3IHJlbmRlciB0cnVlIGFuaXNvdHJvcHk6IHdpdGggYWxsIHRocmVlIHByZXNlbnQgdGhlXG4gICAqICB3b3JsZCBib3ggaXMgdGhlIGltYWdlJ3MgcmVhbCBwaHlzaWNhbCBleHRlbnQsIHNvIDQwIHggNDAgeCAyMDAgwrVtIHZveGVsc1xuICAgKiAgcmVhZCBhcyBhIGJyYWluIGFuZCBub3QgYXMgYSBjdWJlLWFzcGVjdCBicmljay4gQWJzZW50LCB0aGUgdmlldyBmYWxscyBiYWNrXG4gICAqICB0byBpdHMgcmVzb2x1dGlvbi1pbnZhcmlhbnQgcmVmZXJlbmNlIGJveCwgd2hpY2ggaXMgc2hhcGUtb25seS4gKi9cbiAgbXBwWj86IG51bWJlciB8IG51bGw7XG4gIC8qKiBQZXItY2hhbm5lbCBuYW1lL2NvbG9yL0xVVCBmb3IgbXVsdGljaGFubmVsIChub24tUkdCKSBpbWFnZXMsIHdoZW4ga25vd24uICovXG4gIGNoYW5uZWxJbmZvPzogSUNoYW5uZWxJbmZvW10gfCBudWxsO1xufVxuXG4vKiogVGhlIGltYWdlIGN1cnJlbnRseSBiZWluZyB2aXN1YWxpemVkLiBGaWVsZCBvcHRpb25hbGl0eSBtaXJyb3JzIHRoZSBob3N0J3NcbiAqICBgSW1hZ2VJbmZvYCBzbyBpdHMgaW5zdGFuY2VzIGFyZSBhc3NpZ25hYmxlIHRvIHRoaXMgaW50ZXJmYWNlLiAqL1xuZXhwb3J0IGludGVyZmFjZSBJSW1hZ2VJbmZvIHtcbiAgaXNHcmF5c2NhbGU6IGJvb2xlYW47XG4gIHRydWVJbWFnZVNpemU6IG51bWJlcltdO1xuICB1cmxzOiBzdHJpbmdbXTtcbiAgLyoqIE9wdGlvbmFsIHNtYWxsLXRpZXIgVVJMcyAoZmFzdCBibHVycnkgcGxhY2Vob2xkZXIpLCAxOjEgd2l0aCBgdXJsc2AuICovXG4gIHNtYWxsVXJscz86IHN0cmluZ1tdO1xuICBpc1N0YWNrOiBib29sZWFuO1xuICBzaG93U3RhY2s6IGJvb2xlYW47XG4gIHNjYWxlUmF0aW86IGJvb2xlYW47XG4gIGZpbGVOYW1lOiBzdHJpbmc7XG4gIHJvaUpzb25TdHI/OiBzdHJpbmc7XG4gIC8qKiBQZXItc2xpY2UgUk9JIEdlb0pTT04sIGFsaWduZWQgMToxIHdpdGggYHVybHNgLCBmb3IgYSBmb2xkZXIgc3RhY2sgd2hlcmVcbiAgICogIGVhY2ggc2xpY2UgaXMgYSBzZXBhcmF0ZSBmaWxlIHdpdGggaXRzIG93biBzaWJsaW5nIGA8c3RlbT4uZ2VvanNvbmBcbiAgICogIChgbnVsbGAgZm9yIHNsaWNlcyB3aXRob3V0IG9uZSkuIFdoZW4gcHJlc2VudCwgdGhlIGNvbXBvbmVudCBhcHBsaWVzXG4gICAqICBgcm9pSnNvblN0cnNbel1gIGZvciB0aGUgZGlzcGxheWVkIHNsaWNlIGFuZCBzd2FwcyBpdCBvbiBzY3J1YiDigJQgYXNcbiAgICogIG9wcG9zZWQgdG8gdGhlIHNjYWxhciBgcm9pSnNvblN0cmAsIHdoaWNoIGlzIG9uZSBST0kgc2V0IGZvciB0aGUgd2hvbGVcbiAgICogIGltYWdlIChhIHNpbmdsZSBmaWxlIG9yIGEgc2VydmVyIHotc3RhY2spLiAoaml0LXVpIzkzKSAqL1xuICByb2lKc29uU3Rycz86IChzdHJpbmcgfCBudWxsKVtdO1xuICAvKiogUGVyLXNsaWNlLCBwZXItY2hhbm5lbCBwbGFuZSBVUkxzIGZvciBhIFNFUlZFUkxFU1MgbXVsdGljaGFubmVsIGltYWdlXG4gICAqICAoYHRpbGVkOiBmYWxzZWAgKyBgaW1hZ2VNZXRhWzBdLmNoYW5uZWxDb3VudCA+IDFgKS4gYGNoYW5uZWxVcmxzW3pdW2NdYFxuICAgKiAgaXMgYSBjb21wbGV0ZSBzaW5nbGUtYmFuZCBpbWFnZSBvZiBjaGFubmVsIGMgYXQgc2xpY2Ugei4gVGhlIE9TRCBzaW1wbGVcbiAgICogIHBhdGggY29tcG9zaXRlcyB0aGVtIGNsaWVudC1zaWRlIOKAlCBwZXItY2hhbm5lbCBjb2xvdXIvd2luZG93L2dhbW1hIGZyb21cbiAgICogIHRoZSBjaGFubmVsIHBhbmUg4oCUIGluc3RlYWQgb2Ygb3BlbmluZyB0aGUgZmxhdCBgdXJsc1t6XWAuIChqaXQtdWkjNzYpICovXG4gIGNoYW5uZWxVcmxzPzogc3RyaW5nW11bXTtcbiAgaW1hZ2VNZXRhOiBJSW1hZ2VNZXRhZGF0YVtdO1xuICAvKiogSG93IHRoZSBPcGVuU2VhZHJhZ29uIGJhY2tlbmQgc2hvdWxkIHNvdXJjZSB0aGlzIGltYWdlLlxuICAgKiAgLSBgdHJ1ZWAvYWJzZW50IChkZWZhdWx0KTogc2VydmVyLXRpbGVkIOKAlCBPU0QgcG9sbHMgYC90aWxlcy9pbmZvYCBmb3IgYVxuICAgKiAgICBweXJhbWlkIGFuZCBmZXRjaGVzIHRpbGVzIGZyb20gdGhlIHNsaWRlLWNyb3Agc2VydmVyICh3aG9sZS1zbGlkZSBwYXRoKS5cbiAgICogIC0gYGZhbHNlYDogYSBzZWxmLWNvbnRhaW5lZCwgZGlyZWN0bHktbG9hZGFibGUgaW1hZ2Ug4oCUIGB1cmxzW3pJbmRleF1gIGlzIGFcbiAgICogICAgY29tcGxldGUgaW1hZ2UgKGUuZy4gYSBgYmxvYjpgIFVSTCBidWlsdCBmcm9tIGEgY2xpZW50LXNpZGUgcGl4ZWwgYnVmZmVyKSxcbiAgICogICAgb3BlbmVkIHZpYSBPU0QncyBzaW5nbGUtaW1hZ2Ugc291cmNlIHdpdGggbm8gdGlsZSBzZXJ2ZXIuIExldHMgaW4tbWVtb3J5XG4gICAqICAgIGltYWdlcyAodGhlIHByb2Nlc3NpbmcgcGlwZWxpbmUpIHVzZSB0aGUgT1NEIHZpZXdlciB3aXRob3V0IGEgcm91bmQtdHJpcC4gKi9cbiAgdGlsZWQ/OiBib29sZWFuO1xuICAvKiogT25lLXNob3QgaGludDogb3BlbiB0aGUgc3RhY2sgb24gdGhpcyBzbGljZSBpbnN0ZWFkIG9mIHNsaWNlIDAgKGUuZy4gdGhlXG4gICAqICBob3N0IGNsaWNrZWQgYSBzcGVjaWZpYyBmaWxlIHdpdGhpbiBhIG51bWJlcmVkIGltYWdlIHNlcmllcykuIFRoZVxuICAgKiAgY29tcG9uZW50IGNvbnN1bWVzIGFuZCBjbGVhcnMgdGhpcyB0aGUgZmlyc3QgdGltZSBpdCBzZWVzIHRoZSBvYmplY3QsIHNvXG4gICAqICByZS1kZWxpdmVyaW5nIHRoZSBzYW1lIEltYWdlSW5mbyAoZS5nLiBhIHBsb3QtdHlwZSBzd2l0Y2gpIGRvZXNuJ3QgcmVzZXRcbiAgICogIHRoZSB1c2VyJ3MgY3VycmVudCBzY3J1YiBwb3NpdGlvbi4gKi9cbiAgaW5pdGlhbFpJbmRleD86IG51bWJlcjtcbn1cbiJdfQ==
@@ -0,0 +1,66 @@
1
+ /**
2
+ * How a plot mode gets into the plot-type selector without this library knowing
3
+ * what it is.
4
+ *
5
+ * A package contributes a mode by providing a {@link PlotTypeContribution} on the
6
+ * {@link PLOT_TYPE_CONTRIBUTIONS} multi-provider token, the same way
7
+ * `TOOLBAR_TOOLS` contributes toolbar tools. Nothing registers at import time:
8
+ * installing a package makes a mode available, and adding its provider turns it
9
+ * on. A plain object works, so the contributing package needs no Angular
10
+ * compiler and no decorators:
11
+ *
12
+ * { provide: PLOT_TYPE_CONTRIBUTIONS, useValue: myContribution, multi: true }
13
+ * { provide: PLOT_TYPE_CONTRIBUTIONS, useFactory: () => makeContribution(), multi: true }
14
+ *
15
+ * Provide nothing and the selector, the render path and the panel area behave
16
+ * exactly as they did before this extension point existed.
17
+ *
18
+ * WHY A CONTRIBUTED MODE RIDES ON A BUILT-IN ONE
19
+ * A contributed mode does not bring a renderer. It names a built-in
20
+ * {@link ContributedPlotTypeDescriptor.baseType} — in v1 only `PlotType.IMAGE`,
21
+ * the OpenSeadragon view — and the visualizer plots exactly as if that type had
22
+ * been selected: same backend, same toolbar, same region tools, same wheel
23
+ * handling. The contribution then draws over it through the
24
+ * {@link PlotModeViewport} and talks to the viewer through the public
25
+ * {@link IVisualizer}. That keeps every rendering decision in one place and means
26
+ * a contribution can never be half-supported by some code path that switches on
27
+ * the plot type.
28
+ *
29
+ * WHAT THE VISUALIZER GUARANTEES
30
+ * 1. Contributed descriptors are appended after the built-in ones and curated by
31
+ * the same `productionLabel` / test-mode / `requires*` rules.
32
+ * 2. Selecting one plots with `baseType`'s backend, then calls `activate(ctx)`
33
+ * once the viewport is ready.
34
+ * 3. Leaving the mode — another type, an image switch (or any re-render of the
35
+ * base view), or the visualizer being destroyed — calls `session.deactivate()`
36
+ * exactly once, before the next mode draws. If the mode is still selected
37
+ * when the new image has plotted, a fresh session is activated for it.
38
+ * 4. `panel` is shown only while a session is live.
39
+ * 5. A thrown error or rejected promise from `activate`, `deactivate`, `mount`
40
+ * or a mount's teardown is caught and logged; none escapes, so a contribution
41
+ * cannot break the viewer. Failing to start (`activate`, `mount`, or a panel
42
+ * component throwing while it is created / first rendered) falls back
43
+ * to `baseType`. Failing to clean up falls back when that same mode is being
44
+ * re-activated (base re-render, image switch) — immediately if it already is
45
+ * live again — and is only logged when the user has moved to another mode; the
46
+ * user explicitly selecting it again gets a fresh attempt.
47
+ * 6. {@link PLOT_TYPE_CONTRIBUTIONS} has no factory: no providers, no modes.
48
+ */
49
+ import { InjectionToken } from '@angular/core';
50
+ /**
51
+ * Multi-provider token for contributed plot modes.
52
+ *
53
+ * Deliberately has no `factory`: unregistered means no contributed modes, and the
54
+ * library behaves exactly as before. The visualizer injects it `{ optional: true }`
55
+ * and treats null as empty.
56
+ */
57
+ export const PLOT_TYPE_CONTRIBUTIONS = new InjectionToken('PLOT_TYPE_CONTRIBUTIONS');
58
+ /** The active mode's context, in a component panel's injector. */
59
+ export const PLOT_MODE_CONTEXT = new InjectionToken('PLOT_MODE_CONTEXT');
60
+ /** The active mode's session, in a component panel's injector. */
61
+ export const PLOT_MODE_SESSION = new InjectionToken('PLOT_MODE_SESSION');
62
+ /** The selector entry for a contributed mode, given its base type's descriptor. */
63
+ export function contributedPlotTypeOption(d, base) {
64
+ return { ...d, source: base.source };
65
+ }
66
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxvdC10eXBlLWNvbnRyaWJ1dGlvbi5jb250cmFjdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvY29udHJhY3RzL3Bsb3QtdHlwZS1jb250cmlidXRpb24uY29udHJhY3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBK0NHO0FBQ0gsT0FBTyxFQUFFLGNBQWMsRUFBUSxNQUFNLGVBQWUsQ0FBQztBQXNHckQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQ2xDLElBQUksY0FBYyxDQUFrQyx5QkFBeUIsQ0FBQyxDQUFDO0FBQ2pGLGtFQUFrRTtBQUNsRSxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLGNBQWMsQ0FBa0IsbUJBQW1CLENBQUMsQ0FBQztBQUMxRixrRUFBa0U7QUFDbEUsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxjQUFjLENBQWtCLG1CQUFtQixDQUFDLENBQUM7QUFhMUYsbUZBQW1GO0FBQ25GLE1BQU0sVUFBVSx5QkFBeUIsQ0FDdkMsQ0FBZ0MsRUFDaEMsSUFBd0I7SUFFeEIsT0FBTyxFQUFFLEdBQUcsQ0FBQyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7QUFDdkMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogSG93IGEgcGxvdCBtb2RlIGdldHMgaW50byB0aGUgcGxvdC10eXBlIHNlbGVjdG9yIHdpdGhvdXQgdGhpcyBsaWJyYXJ5IGtub3dpbmdcbiAqIHdoYXQgaXQgaXMuXG4gKlxuICogQSBwYWNrYWdlIGNvbnRyaWJ1dGVzIGEgbW9kZSBieSBwcm92aWRpbmcgYSB7QGxpbmsgUGxvdFR5cGVDb250cmlidXRpb259IG9uIHRoZVxuICoge0BsaW5rIFBMT1RfVFlQRV9DT05UUklCVVRJT05TfSBtdWx0aS1wcm92aWRlciB0b2tlbiwgdGhlIHNhbWUgd2F5XG4gKiBgVE9PTEJBUl9UT09MU2AgY29udHJpYnV0ZXMgdG9vbGJhciB0b29scy4gTm90aGluZyByZWdpc3RlcnMgYXQgaW1wb3J0IHRpbWU6XG4gKiBpbnN0YWxsaW5nIGEgcGFja2FnZSBtYWtlcyBhIG1vZGUgYXZhaWxhYmxlLCBhbmQgYWRkaW5nIGl0cyBwcm92aWRlciB0dXJucyBpdFxuICogb24uIEEgcGxhaW4gb2JqZWN0IHdvcmtzLCBzbyB0aGUgY29udHJpYnV0aW5nIHBhY2thZ2UgbmVlZHMgbm8gQW5ndWxhclxuICogY29tcGlsZXIgYW5kIG5vIGRlY29yYXRvcnM6XG4gKlxuICogICAgIHsgcHJvdmlkZTogUExPVF9UWVBFX0NPTlRSSUJVVElPTlMsIHVzZVZhbHVlOiBteUNvbnRyaWJ1dGlvbiwgbXVsdGk6IHRydWUgfVxuICogICAgIHsgcHJvdmlkZTogUExPVF9UWVBFX0NPTlRSSUJVVElPTlMsIHVzZUZhY3Rvcnk6ICgpID0+IG1ha2VDb250cmlidXRpb24oKSwgbXVsdGk6IHRydWUgfVxuICpcbiAqIFByb3ZpZGUgbm90aGluZyBhbmQgdGhlIHNlbGVjdG9yLCB0aGUgcmVuZGVyIHBhdGggYW5kIHRoZSBwYW5lbCBhcmVhIGJlaGF2ZVxuICogZXhhY3RseSBhcyB0aGV5IGRpZCBiZWZvcmUgdGhpcyBleHRlbnNpb24gcG9pbnQgZXhpc3RlZC5cbiAqXG4gKiBXSFkgQSBDT05UUklCVVRFRCBNT0RFIFJJREVTIE9OIEEgQlVJTFQtSU4gT05FXG4gKiBBIGNvbnRyaWJ1dGVkIG1vZGUgZG9lcyBub3QgYnJpbmcgYSByZW5kZXJlci4gSXQgbmFtZXMgYSBidWlsdC1pblxuICoge0BsaW5rIENvbnRyaWJ1dGVkUGxvdFR5cGVEZXNjcmlwdG9yLmJhc2VUeXBlfSDigJQgaW4gdjEgb25seSBgUGxvdFR5cGUuSU1BR0VgLFxuICogdGhlIE9wZW5TZWFkcmFnb24gdmlldyDigJQgYW5kIHRoZSB2aXN1YWxpemVyIHBsb3RzIGV4YWN0bHkgYXMgaWYgdGhhdCB0eXBlIGhhZFxuICogYmVlbiBzZWxlY3RlZDogc2FtZSBiYWNrZW5kLCBzYW1lIHRvb2xiYXIsIHNhbWUgcmVnaW9uIHRvb2xzLCBzYW1lIHdoZWVsXG4gKiBoYW5kbGluZy4gVGhlIGNvbnRyaWJ1dGlvbiB0aGVuIGRyYXdzIG92ZXIgaXQgdGhyb3VnaCB0aGVcbiAqIHtAbGluayBQbG90TW9kZVZpZXdwb3J0fSBhbmQgdGFsa3MgdG8gdGhlIHZpZXdlciB0aHJvdWdoIHRoZSBwdWJsaWNcbiAqIHtAbGluayBJVmlzdWFsaXplcn0uIFRoYXQga2VlcHMgZXZlcnkgcmVuZGVyaW5nIGRlY2lzaW9uIGluIG9uZSBwbGFjZSBhbmQgbWVhbnNcbiAqIGEgY29udHJpYnV0aW9uIGNhbiBuZXZlciBiZSBoYWxmLXN1cHBvcnRlZCBieSBzb21lIGNvZGUgcGF0aCB0aGF0IHN3aXRjaGVzIG9uXG4gKiB0aGUgcGxvdCB0eXBlLlxuICpcbiAqIFdIQVQgVEhFIFZJU1VBTElaRVIgR1VBUkFOVEVFU1xuICogIDEuIENvbnRyaWJ1dGVkIGRlc2NyaXB0b3JzIGFyZSBhcHBlbmRlZCBhZnRlciB0aGUgYnVpbHQtaW4gb25lcyBhbmQgY3VyYXRlZCBieVxuICogICAgIHRoZSBzYW1lIGBwcm9kdWN0aW9uTGFiZWxgIC8gdGVzdC1tb2RlIC8gYHJlcXVpcmVzKmAgcnVsZXMuXG4gKiAgMi4gU2VsZWN0aW5nIG9uZSBwbG90cyB3aXRoIGBiYXNlVHlwZWAncyBiYWNrZW5kLCB0aGVuIGNhbGxzIGBhY3RpdmF0ZShjdHgpYFxuICogICAgIG9uY2UgdGhlIHZpZXdwb3J0IGlzIHJlYWR5LlxuICogIDMuIExlYXZpbmcgdGhlIG1vZGUg4oCUIGFub3RoZXIgdHlwZSwgYW4gaW1hZ2Ugc3dpdGNoIChvciBhbnkgcmUtcmVuZGVyIG9mIHRoZVxuICogICAgIGJhc2UgdmlldyksIG9yIHRoZSB2aXN1YWxpemVyIGJlaW5nIGRlc3Ryb3llZCDigJQgY2FsbHMgYHNlc3Npb24uZGVhY3RpdmF0ZSgpYFxuICogICAgIGV4YWN0bHkgb25jZSwgYmVmb3JlIHRoZSBuZXh0IG1vZGUgZHJhd3MuIElmIHRoZSBtb2RlIGlzIHN0aWxsIHNlbGVjdGVkXG4gKiAgICAgd2hlbiB0aGUgbmV3IGltYWdlIGhhcyBwbG90dGVkLCBhIGZyZXNoIHNlc3Npb24gaXMgYWN0aXZhdGVkIGZvciBpdC5cbiAqICA0LiBgcGFuZWxgIGlzIHNob3duIG9ubHkgd2hpbGUgYSBzZXNzaW9uIGlzIGxpdmUuXG4gKiAgNS4gQSB0aHJvd24gZXJyb3Igb3IgcmVqZWN0ZWQgcHJvbWlzZSBmcm9tIGBhY3RpdmF0ZWAsIGBkZWFjdGl2YXRlYCwgYG1vdW50YFxuICogICAgIG9yIGEgbW91bnQncyB0ZWFyZG93biBpcyBjYXVnaHQgYW5kIGxvZ2dlZDsgbm9uZSBlc2NhcGVzLCBzbyBhIGNvbnRyaWJ1dGlvblxuICogICAgIGNhbm5vdCBicmVhayB0aGUgdmlld2VyLiBGYWlsaW5nIHRvIHN0YXJ0IChgYWN0aXZhdGVgLCBgbW91bnRgLCBvciBhIHBhbmVsXG4gKiAgICAgY29tcG9uZW50IHRocm93aW5nIHdoaWxlIGl0IGlzIGNyZWF0ZWQgLyBmaXJzdCByZW5kZXJlZCkgZmFsbHMgYmFja1xuICogICAgIHRvIGBiYXNlVHlwZWAuIEZhaWxpbmcgdG8gY2xlYW4gdXAgZmFsbHMgYmFjayB3aGVuIHRoYXQgc2FtZSBtb2RlIGlzIGJlaW5nXG4gKiAgICAgcmUtYWN0aXZhdGVkIChiYXNlIHJlLXJlbmRlciwgaW1hZ2Ugc3dpdGNoKSDigJQgaW1tZWRpYXRlbHkgaWYgaXQgYWxyZWFkeSBpc1xuICogICAgIGxpdmUgYWdhaW4g4oCUIGFuZCBpcyBvbmx5IGxvZ2dlZCB3aGVuIHRoZSB1c2VyIGhhcyBtb3ZlZCB0byBhbm90aGVyIG1vZGU7IHRoZVxuICogICAgIHVzZXIgZXhwbGljaXRseSBzZWxlY3RpbmcgaXQgYWdhaW4gZ2V0cyBhIGZyZXNoIGF0dGVtcHQuXG4gKiAgNi4ge0BsaW5rIFBMT1RfVFlQRV9DT05UUklCVVRJT05TfSBoYXMgbm8gZmFjdG9yeTogbm8gcHJvdmlkZXJzLCBubyBtb2Rlcy5cbiAqL1xuaW1wb3J0IHsgSW5qZWN0aW9uVG9rZW4sIFR5cGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB0eXBlIHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgdHlwZSB7IElJbWFnZUluZm8gfSBmcm9tICcuL2ltYWdlLmNvbnRyYWN0JztcbmltcG9ydCB0eXBlIHsgUGxvdFR5cGUsIFBsb3RUeXBlRGVzY3JpcHRvciwgUGxvdFR5cGVJZCB9IGZyb20gJy4vcGxvdC10eXBlJztcbmltcG9ydCB0eXBlIHsgSVZpc3VhbGl6ZXIgfSBmcm9tICcuL3Zpc3VhbGl6ZXIuY29udHJhY3QnO1xuXG4vKiogQSByZWN0YW5nbGUgaW4gbGV2ZWwtMCBpbWFnZSBwaXhlbHMuICovXG5leHBvcnQgaW50ZXJmYWNlIFBsb3RNb2RlUmVjdCB7XG4gIHg6IG51bWJlcjtcbiAgeTogbnVtYmVyO1xuICB3aWR0aDogbnVtYmVyO1xuICBoZWlnaHQ6IG51bWJlcjtcbn1cblxuLyoqIFNlbGVjdG9yIG1ldGFkYXRhIGZvciBhIGNvbnRyaWJ1dGVkIHBsb3QgbW9kZS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29udHJpYnV0ZWRQbG90VHlwZURlc2NyaXB0b3Ige1xuICAvKiogVW5pcXVlIGlkLCBuYW1lc3BhY2VkLCBlLmcuICdkaWFubmUnLiBNdXN0IG5vdCBjbGFzaCB3aXRoIFBsb3RUeXBlIHZhbHVlcy4gKi9cbiAgdHlwZTogc3RyaW5nO1xuICAvKiogVGVzdC1tb2RlIGxhYmVsLCBlLmcuICdEaWdpdGFsIFBhdGhvbG9neSAtIERJQU5ORScuICovXG4gIGxhYmVsOiBzdHJpbmc7XG4gIC8qKiBEZWZhdWx0LXNlbGVjdG9yIGxhYmVsOyBvbWl0IHRvIG1ha2UgdGhlIG1vZGUgdGVzdC1vbmx5IChzYW1lIHJ1bGUgYXMgYnVpbHQtaW5zKS4gKi9cbiAgcHJvZHVjdGlvbkxhYmVsPzogc3RyaW5nO1xuICAvKiogJ3BpIHBpLeKApicgY2xhc3Mgb3IgYXNzZXQgcGF0aCwgc2FtZSBhcyBQbG90VHlwZURlc2NyaXB0b3IuaWNvbi4gKi9cbiAgaWNvbj86IHN0cmluZztcbiAgLyoqIEFsd2F5cyAnMmQnIGluIHYxLiAqL1xuICBkaW1lbnNpb25zOiAnMmQnO1xuICAvKiogQnVpbHQtaW4gdHlwZSB3aG9zZSBiYWNrZW5kIHJlbmRlcnMgdGhlIGJhc2UgaW1hZ2UuIHYxIHN1cHBvcnRzIFBsb3RUeXBlLklNQUdFIChPU0QpLiAqL1xuICBiYXNlVHlwZTogUGxvdFR5cGU7XG4gIC8qKiBTYW1lIGdhdGVzIGFzIFBsb3RUeXBlRGVzY3JpcHRvciwgZXZhbHVhdGVkIGluIGFkZGl0aW9uIHRvIHRoZSBiYXNlIHR5cGUncyBvd24uICovXG4gIHJlcXVpcmVzR3JheXNjYWxlPzogYm9vbGVhbjtcbiAgcmVxdWlyZXNTdGFjaz86IGJvb2xlYW47XG4gIC8qKiBIaWRkZW4gdW50aWwgYSBgU3BhdGlhbERhdGFzZXRgIGlzIHB1Ymxpc2hlZCBvbiBTUEFUSUFMX0RBVEFfUE9SVCAoYW4gb3ZlcmxheSBvZiBzcGF0aWFsIG9ic2VydmF0aW9ucykuICovXG4gIHJlcXVpcmVzU3BhdGlhbERhdGE/OiBib29sZWFuO1xuICAvKiogSGlkZGVuIHVubGVzcyB0aGUgcHVibGlzaGVkIGRhdGFzZXQgY2FycmllcyBgb2JzZXJ2YXRpb25zLnpgLiAqL1xuICByZXF1aXJlc1NwYXRpYWwzZD86IGJvb2xlYW47XG59XG5cbi8qKiBUaGUgYmFzZSB2aWV3J3Mgdmlld3BvcnQsIGFzIGEgY29udHJpYnV0ZWQgbW9kZSBzZWVzIGl0LiAqL1xuZXhwb3J0IGludGVyZmFjZSBQbG90TW9kZVZpZXdwb3J0IHtcbiAgLyoqIEVsZW1lbnQgdGhlIG1vZGUncyBvdmVybGF5IGNhbnZhcy9TVkcgYXR0YWNoZXMgdG87IGZpbGxzIHRoZSBwbG90IGFyZWEuICovXG4gIGdldE92ZXJsYXlDb250YWluZXIoKTogSFRNTEVsZW1lbnQgfCBudWxsO1xuICAvKiogTGV2ZWwtMCBpbWFnZSBweCAtPiBjbGllbnQgcHgsIGFuZCB0aGUgcmV2ZXJzZS4gKi9cbiAgZGF0YVRvQ2xpZW50KHg6IG51bWJlciwgeTogbnVtYmVyKTogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9O1xuICBjbGllbnRUb0RhdGEoY2xpZW50WDogbnVtYmVyLCBjbGllbnRZOiBudW1iZXIpOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH07XG4gIC8qKiBTY3JlZW4gcHggcGVyIGltYWdlIHB4IGF0IHRoZSBjdXJyZW50IHpvb20uICovXG4gIGRhdGFMZW5ndGhUb1NjcmVlbihsZW46IG51bWJlcik6IG51bWJlcjtcbiAgaXNSZWFkeSgpOiBib29sZWFuO1xuICAvKiogVmlzaWJsZSBpbWFnZSByZWN0IGluIGxldmVsLTAgcHgsIGVtaXR0ZWQgb24gZXZlcnkgcmVkcmF3IGZyYW1lIChwYW4vem9vbSBhbmltYXRpb24pLlxuICAgKiAgQSBuZXcgc3Vic2NyaWJlciBmaXJzdCByZWNlaXZlcyB0aGUgY3VycmVudCByZWN0IHdoZW4gdGhlIHZpZXdwb3J0IGlzIHJlYWR5LiAqL1xuICBmcmFtZSQ6IE9ic2VydmFibGU8UGxvdE1vZGVSZWN0PjtcbiAgLyoqIFNhbWUgcmVjdCwgZW1pdHRlZCBvbmNlIHRoZSB2aWV3cG9ydCBzZXR0bGVzIChleGlzdGluZyBnZXRWaWV3cG9ydENoYW5nZSQgc2VtYW50aWNzKS5cbiAgICogIEEgbmV3IHN1YnNjcmliZXIgZmlyc3QgcmVjZWl2ZXMgdGhlIGN1cnJlbnQgcmVjdCB3aGVuIHRoZSB2aWV3cG9ydCBpcyByZWFkeS4gKi9cbiAgc2V0dGxlZCQ6IE9ic2VydmFibGU8UGxvdE1vZGVSZWN0Pjtcbn1cblxuLyoqIEV2ZXJ5dGhpbmcgYSBjb250cmlidXRlZCBtb2RlIGdldHMgdG8gd29yayB3aXRoIHdoaWxlIGl0IGlzIGFjdGl2ZS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGxvdE1vZGVDb250ZXh0IHtcbiAgLyoqIEZ1bGwgcHVibGljIHZpc3VhbGl6ZXIgQVBJOiByZWdpb25zLCByZWdpb24gb3ZlcmxheSAodG9vbCBtb2RlcyksIHVuZG8sIGV0Yy4gKi9cbiAgdmlzdWFsaXplcjogSVZpc3VhbGl6ZXI7XG4gIHZpZXdwb3J0OiBQbG90TW9kZVZpZXdwb3J0O1xuICAvKiogQ3VycmVudCBpbWFnZSBpbmZvIGZyb20gSU1BR0VfU1RBVEVfUE9SVCAobnVsbCB1bnRpbCBhbiBpbWFnZSBpcyBsb2FkZWQpLiAqL1xuICBpbWFnZUluZm8kOiBPYnNlcnZhYmxlPElJbWFnZUluZm8gfCBudWxsPjtcbn1cblxuLyoqIEEgbGl2ZSBhY3RpdmF0aW9uIG9mIGEgY29udHJpYnV0ZWQgbW9kZS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGxvdE1vZGVTZXNzaW9uIHtcbiAgLyoqIENhbGxlZCB3aGVuIHRoZSB1c2VyIGxlYXZlcyB0aGUgbW9kZSwgdGhlIGltYWdlIGNoYW5nZXMsIG9yIHRoZSB2aXN1YWxpemVyIGlzIGRlc3Ryb3llZC4gKi9cbiAgZGVhY3RpdmF0ZSgpOiB2b2lkO1xufVxuXG4vKipcbiAqIFRoZSBtb2RlJ3Mgc2lkZSBwYW5lbCwgc2hvd24gaW4gdGhlIHZpc3VhbGl6ZXIncyByaWdodC1oYW5kIHBhbmVsIGFyZWEgd2hpbGVcbiAqIGEgc2Vzc2lvbiBpcyBsaXZlLiBUd28gZm9ybXM6XG4gKlxuICogIC0gYGNvbXBvbmVudGA6IGFuIEFuZ3VsYXIgY29tcG9uZW50LCByZW5kZXJlZCB0aHJvdWdoIGBOZ0NvbXBvbmVudE91dGxldGBcbiAqICAgIHdpdGgge0BsaW5rIFBMT1RfTU9ERV9DT05URVhUfSBhbmQge0BsaW5rIFBMT1RfTU9ERV9TRVNTSU9OfSBpbiBpdHNcbiAqICAgIGluamVjdG9yLiBOZWVkcyBhbiBBT1QtY29tcGlsZWQgKHBhcnRpYWwtSXZ5KSBjb21wb25lbnQuXG4gKiAgLSBgbW91bnRgOiBmcmFtZXdvcmstYWdub3N0aWMuIFRoZSB2aXN1YWxpemVyIGhhbmRzIG92ZXIgYW4gZW1wdHkgaG9zdFxuICogICAgZWxlbWVudCBhZnRlciBgYWN0aXZhdGVgIHJlc29sdmVzOyB0aGUgZnVuY3Rpb24gcmVuZGVycyBpbnRvIGl0IGFuZCByZXR1cm5zXG4gKiAgICBhIHRlYXJkb3duLiBUaGUgdGVhcmRvd24gaXMgY2FsbGVkIGV4YWN0bHkgb25jZSB3aGVuIHRoZSBtb2RlIGRlYWN0aXZhdGVzLFxuICogICAgYmVmb3JlIGBzZXNzaW9uLmRlYWN0aXZhdGUoKWAsIGFuZCB0aGUgaG9zdCBlbGVtZW50IGlzIHRoZW4gcmVtb3ZlZC5cbiAqL1xuZXhwb3J0IHR5cGUgUGxvdE1vZGVQYW5lbCA9XG4gIHwgeyB0aXRsZTogc3RyaW5nOyBjb21wb25lbnQ6IFR5cGU8dW5rbm93bj4gfVxuICB8IHtcbiAgICAgIHRpdGxlOiBzdHJpbmc7XG4gICAgICBtb3VudChob3N0OiBIVE1MRWxlbWVudCwgY3R4OiBQbG90TW9kZUNvbnRleHQsIHNlc3Npb246IFBsb3RNb2RlU2Vzc2lvbik6ICgpID0+IHZvaWQ7XG4gICAgfTtcblxuLyoqIEEgcGxvdCBtb2RlIGNvbnRyaWJ1dGVkIHRvIHRoZSBzZWxlY3Rvci4gQSBwbGFpbiBvYmplY3QgaXMgZW5vdWdoLiAqL1xuZXhwb3J0IGludGVyZmFjZSBQbG90VHlwZUNvbnRyaWJ1dGlvbiB7XG4gIGRlc2NyaXB0b3I6IENvbnRyaWJ1dGVkUGxvdFR5cGVEZXNjcmlwdG9yO1xuICAvKiogQ2FsbGVkIGFmdGVyIHRoZSBiYXNlIGJhY2tlbmQgaGFzIHBsb3R0ZWQgdGhlIGltYWdlIGluIHRoaXMgbW9kZS4gKi9cbiAgYWN0aXZhdGUoY3R4OiBQbG90TW9kZUNvbnRleHQpOiBQbG90TW9kZVNlc3Npb24gfCBQcm9taXNlPFBsb3RNb2RlU2Vzc2lvbj47XG4gIC8qKlxuICAgKiBPcHRpb25hbCBzaWRlIHBhbmVsLCByZW5kZXJlZCBpbiB0aGUgdmlzdWFsaXplcidzIHJpZ2h0LWhhbmQgcGFuZWwgYXJlYSB3aGlsZSB0aGVcbiAgICogbW9kZSBpcyBhY3RpdmUuIEEgY29tcG9uZW50IHBhbmVsIGNhbiBpbmplY3QgUExPVF9NT0RFX0NPTlRFWFQgYW5kIFBMT1RfTU9ERV9TRVNTSU9OLlxuICAgKi9cbiAgcGFuZWw/OiBQbG90TW9kZVBhbmVsO1xufVxuXG4vKipcbiAqIE11bHRpLXByb3ZpZGVyIHRva2VuIGZvciBjb250cmlidXRlZCBwbG90IG1vZGVzLlxuICpcbiAqIERlbGliZXJhdGVseSBoYXMgbm8gYGZhY3RvcnlgOiB1bnJlZ2lzdGVyZWQgbWVhbnMgbm8gY29udHJpYnV0ZWQgbW9kZXMsIGFuZCB0aGVcbiAqIGxpYnJhcnkgYmVoYXZlcyBleGFjdGx5IGFzIGJlZm9yZS4gVGhlIHZpc3VhbGl6ZXIgaW5qZWN0cyBpdCBgeyBvcHRpb25hbDogdHJ1ZSB9YFxuICogYW5kIHRyZWF0cyBudWxsIGFzIGVtcHR5LlxuICovXG5leHBvcnQgY29uc3QgUExPVF9UWVBFX0NPTlRSSUJVVElPTlMgPVxuICBuZXcgSW5qZWN0aW9uVG9rZW48cmVhZG9ubHkgUGxvdFR5cGVDb250cmlidXRpb25bXT4oJ1BMT1RfVFlQRV9DT05UUklCVVRJT05TJyk7XG4vKiogVGhlIGFjdGl2ZSBtb2RlJ3MgY29udGV4dCwgaW4gYSBjb21wb25lbnQgcGFuZWwncyBpbmplY3Rvci4gKi9cbmV4cG9ydCBjb25zdCBQTE9UX01PREVfQ09OVEVYVCA9IG5ldyBJbmplY3Rpb25Ub2tlbjxQbG90TW9kZUNvbnRleHQ+KCdQTE9UX01PREVfQ09OVEVYVCcpO1xuLyoqIFRoZSBhY3RpdmUgbW9kZSdzIHNlc3Npb24sIGluIGEgY29tcG9uZW50IHBhbmVsJ3MgaW5qZWN0b3IuICovXG5leHBvcnQgY29uc3QgUExPVF9NT0RFX1NFU1NJT04gPSBuZXcgSW5qZWN0aW9uVG9rZW48UGxvdE1vZGVTZXNzaW9uPignUExPVF9NT0RFX1NFU1NJT04nKTtcblxuLyoqXG4gKiBPbmUgZW50cnkgaW4gdGhlIHBsb3QtdHlwZSBzZWxlY3RvcjogYSBidWlsdC1pbiB7QGxpbmsgUGxvdFR5cGVEZXNjcmlwdG9yfVxuICogYXMtaXMsIG9yIGEgY29udHJpYnV0ZWQgZGVzY3JpcHRvciBjb21wbGV0ZWQgd2l0aCBpdHMgYmFzZSB0eXBlJ3MgYHNvdXJjZWAuXG4gKiBFdmVyeSBlbnRyeSB0aGVyZWZvcmUgY2FycmllcyB0aGUgc2FtZSBmaWVsZHMgdGhlIHNlbGVjdG9yIGN1cmF0ZXMgYnkuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGxvdFR5cGVPcHRpb24gZXh0ZW5kcyBPbWl0PFBsb3RUeXBlRGVzY3JpcHRvciwgJ3R5cGUnPiB7XG4gIHR5cGU6IFBsb3RUeXBlSWQ7XG4gIC8qKiBTZXQgb25seSBmb3IgYSBjb250cmlidXRlZCBtb2RlOiB0aGUgYnVpbHQtaW4gdHlwZSB0aGF0IHJlbmRlcnMgaXQuICovXG4gIGJhc2VUeXBlPzogUGxvdFR5cGU7XG59XG5cbi8qKiBUaGUgc2VsZWN0b3IgZW50cnkgZm9yIGEgY29udHJpYnV0ZWQgbW9kZSwgZ2l2ZW4gaXRzIGJhc2UgdHlwZSdzIGRlc2NyaXB0b3IuICovXG5leHBvcnQgZnVuY3Rpb24gY29udHJpYnV0ZWRQbG90VHlwZU9wdGlvbihcbiAgZDogQ29udHJpYnV0ZWRQbG90VHlwZURlc2NyaXB0b3IsXG4gIGJhc2U6IFBsb3RUeXBlRGVzY3JpcHRvcixcbik6IFBsb3RUeXBlT3B0aW9uIHtcbiAgcmV0dXJuIHsgLi4uZCwgc291cmNlOiBiYXNlLnNvdXJjZSB9O1xufVxuIl19