@jax-data-science/sci-image-visualizer 0.12.0 → 0.13.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 (37) hide show
  1. package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
  2. package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
  3. package/esm2022/lib/geometry/reconstruct.mjs +11 -1
  4. package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +18 -6
  5. package/esm2022/lib/implementations/napari-js/napari-tool-bridge.mjs +29 -14
  6. package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +6 -1
  7. package/esm2022/lib/implementations/napari-js/region-overlay/region-svg-renderer.mjs +9 -4
  8. package/esm2022/lib/region-editor/region-editor.component.mjs +13 -1
  9. package/esm2022/lib/routing-visualizer.service.mjs +4 -1
  10. package/esm2022/lib/spatial/spatial-controls.facade.mjs +71 -21
  11. package/esm2022/lib/spatial/spatial-selection.mjs +70 -1
  12. package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +53 -11
  13. package/esm2022/lib/store/region-selection.mjs +21 -4
  14. package/esm2022/lib/store/region-store.service.mjs +22 -3
  15. package/esm2022/lib/store/spatial-selection.service.mjs +13 -1
  16. package/esm2022/lib/toolbar/toolbar-help-dialog/toolbar-help-dialog.component.mjs +3 -3
  17. package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-a68Hw5rw.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DURPqs5a.mjs} +770 -500
  18. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DURPqs5a.mjs.map +1 -0
  19. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-CvadfzjS.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-D0IQ6PjZ.mjs} +2 -2
  20. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-CvadfzjS.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-D0IQ6PjZ.mjs.map} +1 -1
  21. package/fesm2022/jax-data-science-sci-image-visualizer.mjs +2 -2
  22. package/lib/contracts/region-editor-api.contract.d.ts +3 -0
  23. package/lib/contracts/visualizer.contract.d.ts +25 -2
  24. package/lib/geometry/reconstruct.d.ts +6 -0
  25. package/lib/implementations/napari-js/napari-region-overlay.d.ts +13 -1
  26. package/lib/implementations/napari-js/napari-tool-bridge.d.ts +11 -0
  27. package/lib/implementations/napari-js/napari-visualizer.service.d.ts +3 -0
  28. package/lib/implementations/napari-js/region-overlay/region-svg-renderer.d.ts +6 -1
  29. package/lib/routing-visualizer.service.d.ts +1 -0
  30. package/lib/spatial/spatial-controls.facade.d.ts +16 -2
  31. package/lib/spatial/spatial-selection.d.ts +16 -1
  32. package/lib/spatial-controls/spatial-controls.component.d.ts +14 -3
  33. package/lib/store/region-selection.d.ts +14 -3
  34. package/lib/store/region-store.service.d.ts +14 -1
  35. package/lib/store/spatial-selection.service.d.ts +8 -0
  36. package/package.json +1 -1
  37. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-a68Hw5rw.mjs.map +0 -1
@@ -113,6 +113,12 @@ export class SpatialControlsComponent {
113
113
  /** An ROI selection that matched nothing, so the UI can say so rather than
114
114
  * looking like the button did nothing. */
115
115
  this.selectionMissed = false;
116
+ /** The mode of the selection that {@link selectionMissed}: what it found nothing inside. */
117
+ this.missedMode = 'regions';
118
+ /** The region classes picked in the Region Editor: in 3D, "Select from ROIs" selects inside them. */
119
+ this.pickedClasses = [];
120
+ /** While "Select from ROIs" reads the picked classes' outlines. */
121
+ this.selectingFromRegions = false;
116
122
  /**
117
123
  * Whether the Distribution section is expanded. Collapsed by default: the
118
124
  * panel's primary job is the colour controls, and the chart roughly doubles
@@ -191,12 +197,19 @@ export class SpatialControlsComponent {
191
197
  this.controls
192
198
  .getSelection$()
193
199
  .pipe(untilDestroyed())
194
- .subscribe((selection) => {
200
+ .subscribe((selection) =>
201
+ // Set from outside the zone too: a selection from the region classes' volumes.
202
+ this.runAndMark(() => {
195
203
  this.selection = selection;
196
204
  if (selection.count === 0)
197
205
  this.selectedCategory = null;
198
- this.cdr.markForCheck();
199
- });
206
+ }));
207
+ this.controls
208
+ .getPickedRegionClasses$?.()
209
+ ?.pipe(untilDestroyed())
210
+ .subscribe((classes) => this.runAndMark(() => {
211
+ this.pickedClasses = classes;
212
+ }));
200
213
  // The colour bar must use the colormap the renderer is using.
201
214
  combineLatest([this.viz.getColormap(), this.viz.getReverseScale()])
202
215
  .pipe(untilDestroyed())
@@ -227,11 +240,40 @@ export class SpatialControlsComponent {
227
240
  return this.genes.ensureList();
228
241
  }
229
242
  // ── selection ───────────────────────────────────────────────────────────
230
- /** Select every observation inside the drawn regions (their union). */
231
- selectFromRegions() {
232
- const count = this.controls?.selectFromRegions() ?? 0;
233
- this.selectedCategory = null;
234
- this.selectionMissed = count === 0;
243
+ /** Select every observation inside the drawn regions (their union) — in 3D, inside the
244
+ * picked classes' volumes. */
245
+ async selectFromRegions() {
246
+ if (!this.controls || this.selectingFromRegions)
247
+ return;
248
+ this.selectingFromRegions = true;
249
+ // The mode the selection runs in (decided as it starts), for what a miss says it missed.
250
+ const mode = this.roiSelectionMode;
251
+ this.cdr.markForCheck();
252
+ let count = 0;
253
+ try {
254
+ count = await this.controls.selectFromRegions();
255
+ }
256
+ catch (err) {
257
+ console.warn('[spatial] could not select from the regions', err);
258
+ }
259
+ // The classes' outlines are read in a worker, whose answer lands outside the zone.
260
+ this.runAndMark(() => {
261
+ this.selectingFromRegions = false;
262
+ // Superseded (null): a newer selection stands, and says what it is itself.
263
+ if (count === null)
264
+ return;
265
+ this.selectedCategory = null;
266
+ this.selectionMissed = count === 0;
267
+ this.missedMode = mode;
268
+ });
269
+ }
270
+ /** In 3D with classes picked, "Select from ROIs" selects inside their volumes. */
271
+ get selectsClassVolumes() {
272
+ return this.roiSelectionMode === 'class-volumes';
273
+ }
274
+ /** How "Select from ROIs" selects now: the controls' own rule, the one the selection runs by. */
275
+ get roiSelectionMode() {
276
+ return this.controls?.roiSelectionMode?.() ?? 'regions';
235
277
  }
236
278
  /** Legend click: select one category. Clicking the active row clears it, so a
237
279
  * second click is an undo rather than a no-op. */
@@ -323,7 +365,7 @@ export class SpatialControlsComponent {
323
365
  return this.key.refresh(this.controls, this.dataset, this.view, this.colormap, this.reverse);
324
366
  }
325
367
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: SpatialControlsComponent, deps: [{ token: VISUALIZER }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
326
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: SpatialControlsComponent, isStandalone: true, selector: "spatial-controls", inputs: { visible: "visible", is3d: "is3d" }, outputs: { visibleChange: "visibleChange" }, viewQueries: [{ propertyName: "charts", first: true, predicate: SpatialChartsComponent, descendants: true }], ngImport: i0, template: "<p-dialog\n header=\"Spatial omics\"\n [visible]=\"visible\"\n (visibleChange)=\"onVisibleChange($event)\"\n [modal]=\"false\"\n [resizable]=\"true\"\n [draggable]=\"true\"\n position=\"left\"\n (onResizeEnd)=\"onResizeEnd()\"\n [style]=\"{ width: '30rem' }\"\n [breakpoints]=\"{ '960px': '90vw' }\"\n styleClass=\"spatial-controls-dialog\"\n>\n <!-- No port bound: say why rather than showing controls that do nothing. -->\n <div class=\"sc-empty\" *ngIf=\"!controls\">\n No spatial-omics data source is configured. A host provides one by binding\n <code>SPATIAL_DATA_PORT</code>.\n </div>\n\n <div class=\"sc-empty\" *ngIf=\"controls && !dataset\">No dataset is loaded.</div>\n\n <div class=\"sc-body\" *ngIf=\"controls && dataset as ds\">\n <div class=\"sc-dataset\">\n <span class=\"sc-dataset-name\">{{ ds.name }}</span>\n <span class=\"sc-dataset-count\">{{ ds.observations.count | number }} observations</span>\n </div>\n\n <!-- Organised as Xenium Explorer's side panel: one collapsible section per layer,\n each with its own on/off switch in the header. -->\n\n <!-- Images -->\n <div class=\"sc-panel\" *ngIf=\"ds.imageRef && !is3d\" [class.open]=\"open.images\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('images')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showImage\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowImage($event.checked)\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Images</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.images\" [class.pi-chevron-right]=\"!open.images\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.images\">\n <small class=\"sc-hint\"> Channels, colours and contrast are in the Channels &amp; Histogram dialog. </small>\n </div>\n </div>\n\n <!-- Cells -->\n <spatial-cells-panel\n *ngIf=\"hasCells && !is3d\"\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [colorBarCss]=\"colorBarCss\"\n [open]=\"open.cells\"\n (openChange)=\"setOpen('cells', $event)\"\n ></spatial-cells-panel>\n\n <!-- Transcripts -->\n <spatial-transcripts-panel\n *ngIf=\"hasTranscripts && !is3d\"\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [estimate]=\"estimate\"\n [densityStats]=\"densityStats\"\n [geneCounts]=\"geneCounts\"\n [colormapOptions]=\"colormapOptions\"\n [open]=\"open.transcripts\"\n (openChange)=\"setOpen('transcripts', $event)\"\n >\n </spatial-transcripts-panel>\n\n <!-- Annotations: the drawn regions, and selecting what they enclose. -->\n <div class=\"sc-panel\" [class.open]=\"open.annotations\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('annotations')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showAnnotations !== false\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowAnnotations($event.checked)\"\n pTooltip=\"Show the drawn regions\"\n tooltipPosition=\"top\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Annotations</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.annotations\" [class.pi-chevron-right]=\"!open.annotations\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.annotations\">\n <div class=\"sc-row\">\n <p-button\n label=\"Select from ROIs\"\n icon=\"pi pi-object-group\"\n size=\"small\"\n [outlined]=\"true\"\n (onClick)=\"selectFromRegions()\"\n pTooltip=\"Select every observation inside the drawn regions\"\n tooltipPosition=\"top\"\n ></p-button>\n <p-button\n *ngIf=\"hasSelection\"\n label=\"Clear\"\n size=\"small\"\n [text]=\"true\"\n (onClick)=\"clearSelection()\"\n ></p-button>\n </div>\n <small class=\"sc-hint\" *ngIf=\"hasSelection\">\n {{ selection.count | number }} of {{ ds.observations.count | number }} selected \u2014 the rest are muted.\n </small>\n <small class=\"sc-hint\" *ngIf=\"selectionMissed\"> No observations fell inside the drawn regions. </small>\n <small class=\"sc-hint\" *ngIf=\"is3d\">\n In 3D a region cuts through the cloud's full depth. Orbit and draw again to cut from another angle.\n </small>\n </div>\n </div>\n\n <!-- Observations, then what else draws them: the gene map, the 3D scene, and the\n continuous-only knobs. -->\n <spatial-observations-panel\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [legend]=\"legend\"\n [colorBarCss]=\"colorBarCss\"\n [selection]=\"selection\"\n [selectedCategory]=\"selectedCategory\"\n [colormapOptions]=\"colormapOptions\"\n [is3d]=\"is3d\"\n [open]=\"open.observations\"\n (openChange)=\"setOpen('observations', $event)\"\n (categoryClicked)=\"selectCategory($event)\"\n ></spatial-observations-panel>\n\n <!-- Distributions of whatever the map is coloured by. In the SAME dialog as\n the colour controls on purpose: changing the gene and watching the\n distribution move is one action, and two floating windows made that\n harder to see rather than easier. -->\n <div class=\"sc-section sc-charts\">\n <button\n type=\"button\"\n class=\"sc-disclosure\"\n (click)=\"toggleCharts()\"\n [attr.aria-expanded]=\"chartsOpen\"\n [attr.aria-controls]=\"chartsBodyId\"\n >\n <i class=\"pi\" [class.pi-chevron-right]=\"!chartsOpen\" [class.pi-chevron-down]=\"chartsOpen\"></i>\n <span>Distribution</span>\n <small *ngIf=\"!chartsOpen && view.colorBy\">of {{ colorByLabel }}</small>\n </button>\n <!-- Kept MOUNTED when collapsed, only hidden: destroying it would throw\n away the chart kind and grouping the user picked. `active` is what\n stops it drawing while it has no size. -->\n <div [id]=\"chartsBodyId\" [hidden]=\"!chartsOpen\">\n <spatial-charts [active]=\"visible && chartsOpen\"></spatial-charts>\n </div>\n </div>\n\n <div class=\"sc-btns\">\n <p-button label=\"Reset\" size=\"small\" [text]=\"true\" (onClick)=\"reset()\"></p-button>\n </div>\n </div>\n</p-dialog>\n", styles: [".sc-hint{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-error{color:var(--red-600, #c62828)}.sc-section{display:flex;flex-direction:column;gap:.35rem}.sc-lbl{font-size:.78rem;color:var(--text-color-secondary, #6c757d);white-space:nowrap}.sc-row{display:flex;align-items:center;gap:.6rem}.sc-row p-slider,.sc-row p-dropdown,.sc-row p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row p-slider .p-slider{width:100%}:host ::ng-deep .sc-row p-dropdown .p-dropdown,:host ::ng-deep .sc-row p-treeSelect .p-treeselect{width:100%}.sc-row .sc-lbl{flex:0 0 calc(50% - .6rem);min-width:0;overflow:hidden;text-overflow:ellipsis}.sc-cmap-option{display:inline-flex;align-items:center;gap:.4rem}.sc-cmap-swatch{width:3.5rem;height:.7rem;border-radius:2px;display:block}.sc-val{flex:0 0 4rem;text-align:right;font-size:.78rem;font-variant-numeric:tabular-nums;white-space:nowrap}:host ::ng-deep .sc-full,:host ::ng-deep .sc-full .p-dropdown,:host ::ng-deep .sc-full .p-autocomplete,:host ::ng-deep .sc-full input{width:100%}.sc-colorbar{height:.75rem;border-radius:2px;border:1px solid rgba(0,0,0,.2)}.sc-colorbar-ends{display:flex;justify-content:space-between;font-size:.7rem;color:var(--text-color-secondary, #6c757d);margin-top:.2rem}.sc-panel{border:1px solid var(--surface-border, #dee2e6);border-radius:6px;margin-bottom:.5rem;overflow:hidden}.sc-panel-head{display:flex;align-items:center;gap:.6rem;padding:.5rem .7rem;cursor:pointer;-webkit-user-select:none;user-select:none;background:var(--surface-100, #f5f6f7)}.sc-panel-head .sc-panel-title{flex:1;font-weight:600}.sc-panel.open>.sc-panel-head{background:var(--primary-color, #2196f3);color:var(--primary-color-text, #fff)}.sc-panel-body{display:flex;flex-direction:column;gap:.45rem;padding:.6rem .75rem .75rem}.sc-subhead{display:flex;align-items:center;gap:.5rem;margin-top:.4rem;font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-color-secondary, #6c757d)}.sc-subhead:after{content:\"\";flex:1;border-top:1px solid var(--surface-border, #dee2e6)}:host ::ng-deep .sc-buttons .p-button{padding:.35rem .75rem;font-size:.85rem}.sc-row-picker p-dropdown,.sc-row-picker p-multiSelect,.sc-row-picker p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row-picker .sc-variant{width:6.5rem}:host ::ng-deep .sc-row-picker p-multiselect .p-multiselect{width:100%}:host ::ng-deep .sc-row-picker p-dropdown:has(.sc-variant){flex:0 0 6.5rem}:host ::ng-deep .sc-row-picker p-treeselect:has(.sc-palette){flex:0 0 3rem}:host ::ng-deep .sc-palette .p-treeselect-label{width:0;padding:0}.sc-icon-btn{flex:0 0 auto;border:0;background:transparent;cursor:pointer;padding:.25rem .35rem;font:inherit;font-size:1.05rem;color:var(--text-color, #333);border-radius:4px}.sc-icon-btn:hover{background:var(--surface-200, #e9ecef)}.sc-icon-btn.active{color:var(--primary-color, #2196f3);font-weight:700}.sc-icon-btn:disabled{opacity:.5;cursor:default}.sc-small-btn{margin-left:auto;border:1px solid var(--surface-border, #ced4da);background:var(--surface-0, #fff);border-radius:4px;padding:.2rem .6rem;font:inherit;font-size:.8rem;cursor:pointer}:host ::ng-deep .sc-group-heading{font-size:.7rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;opacity:.7}.sc-group-list,.sc-gene-tree{max-height:16rem;overflow-y:auto;border:1px solid var(--surface-border, #dee2e6);border-radius:4px;padding:.25rem .4rem}.sc-group-row,.sc-gene-row{display:flex;align-items:center;gap:.45rem;padding:.15rem 0;font-size:.88rem}.sc-group-row .sc-group-label,.sc-gene-row .sc-group-label{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-group-all,.sc-gene-root,.sc-gene-group{font-weight:600}.sc-group-all .sc-icon-btn,.sc-gene-root .sc-icon-btn,.sc-gene-group .sc-icon-btn{margin-left:auto;font-size:.85rem}.sc-count{flex:0 0 auto;font-size:.78rem;color:var(--text-color-secondary, #6c757d)}.sc-glyph-option{display:inline-flex;align-items:center;gap:.4rem}.sc-glyph-svg{width:1rem;height:1rem;fill:currentColor}:host ::ng-deep .sc-glyph-pick .p-dropdown-label{padding:.2rem .4rem}.sc-color-input{width:2.5rem;height:1.8rem;border:1px solid var(--surface-border, #ced4da);border-radius:4px;padding:0;background:none}.sc-row-number p-slider,.sc-row-range p-slider{flex:1 1 0;min-width:0}:host ::ng-deep .sc-num{width:4.5rem;padding:.3rem .4rem;text-align:center}:host ::ng-deep .sc-row-number p-inputnumber,:host ::ng-deep .sc-row-range p-inputnumber{flex:0 0 auto}:host ::ng-deep .spatial-controls-dialog .p-dialog-content{padding:.75rem 1rem 1rem}.sc-empty{padding:.5rem 0;font-size:.85rem;color:var(--text-color-secondary, #6c757d);line-height:1.4}.sc-empty code{font-size:.8rem}.sc-body{display:flex;flex-direction:column;gap:.85rem}.sc-dataset{display:flex;flex-direction:column;gap:.1rem;padding-bottom:.5rem;border-bottom:1px solid var(--surface-border, #dee2e6)}.sc-dataset-name{font-weight:600;font-size:.9rem}.sc-dataset-count{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-btns{display:flex;justify-content:flex-end}.sc-charts{padding-top:.5rem;border-top:1px solid var(--surface-border, #dee2e6);gap:0}.sc-disclosure{display:flex;align-items:center;gap:.4rem;width:100%;padding:.2rem 0;font:inherit;font-size:.82rem;font-weight:600;text-align:left;background:none;border:0;cursor:pointer;color:inherit}.sc-disclosure i{font-size:.7rem;color:var(--text-color-secondary, #6c757d)}.sc-disclosure small{font-weight:400;color:var(--text-color-secondary, #6c757d);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-disclosure:hover{color:var(--primary-color, #3b82f6)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i3.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4.Checkbox, selector: "p-checkbox", inputs: ["value", "name", "disabled", "binary", "label", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "styleClass", "labelStyleClass", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i5.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "visible", "style", "position"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: SpatialCellsPanelComponent, selector: "spatial-cells-panel", inputs: ["controls", "dataset", "view", "genes", "colorBarCss", "open"], outputs: ["openChange"] }, { kind: "component", type: SpatialTranscriptsPanelComponent, selector: "spatial-transcripts-panel", inputs: ["controls", "dataset", "view", "genes", "estimate", "densityStats", "geneCounts", "colormapOptions", "open"], outputs: ["openChange"] }, { kind: "component", type: SpatialObservationsPanelComponent, selector: "spatial-observations-panel", inputs: ["controls", "dataset", "view", "genes", "legend", "colorBarCss", "selection", "selectedCategory", "colormapOptions", "is3d", "open"], outputs: ["openChange", "categoryClicked"] }, { kind: "component", type: SpatialChartsComponent, selector: "spatial-charts", inputs: ["active"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
368
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: SpatialControlsComponent, isStandalone: true, selector: "spatial-controls", inputs: { visible: "visible", is3d: "is3d" }, outputs: { visibleChange: "visibleChange" }, viewQueries: [{ propertyName: "charts", first: true, predicate: SpatialChartsComponent, descendants: true }], ngImport: i0, template: "<p-dialog\n header=\"Spatial omics\"\n [visible]=\"visible\"\n (visibleChange)=\"onVisibleChange($event)\"\n [modal]=\"false\"\n [resizable]=\"true\"\n [draggable]=\"true\"\n position=\"left\"\n (onResizeEnd)=\"onResizeEnd()\"\n [style]=\"{ width: '30rem' }\"\n [breakpoints]=\"{ '960px': '90vw' }\"\n styleClass=\"spatial-controls-dialog\"\n>\n <!-- No port bound: say why rather than showing controls that do nothing. -->\n <div class=\"sc-empty\" *ngIf=\"!controls\">\n No spatial-omics data source is configured. A host provides one by binding\n <code>SPATIAL_DATA_PORT</code>.\n </div>\n\n <div class=\"sc-empty\" *ngIf=\"controls && !dataset\">No dataset is loaded.</div>\n\n <div class=\"sc-body\" *ngIf=\"controls && dataset as ds\">\n <div class=\"sc-dataset\">\n <span class=\"sc-dataset-name\">{{ ds.name }}</span>\n <span class=\"sc-dataset-count\">{{ ds.observations.count | number }} observations</span>\n </div>\n\n <!-- Organised as Xenium Explorer's side panel: one collapsible section per layer,\n each with its own on/off switch in the header. -->\n\n <!-- Images -->\n <div class=\"sc-panel\" *ngIf=\"ds.imageRef && !is3d\" [class.open]=\"open.images\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('images')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showImage\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowImage($event.checked)\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Images</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.images\" [class.pi-chevron-right]=\"!open.images\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.images\">\n <small class=\"sc-hint\"> Channels, colours and contrast are in the Channels &amp; Histogram dialog. </small>\n </div>\n </div>\n\n <!-- Cells -->\n <spatial-cells-panel\n *ngIf=\"hasCells && !is3d\"\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [colorBarCss]=\"colorBarCss\"\n [open]=\"open.cells\"\n (openChange)=\"setOpen('cells', $event)\"\n ></spatial-cells-panel>\n\n <!-- Transcripts -->\n <spatial-transcripts-panel\n *ngIf=\"hasTranscripts && !is3d\"\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [estimate]=\"estimate\"\n [densityStats]=\"densityStats\"\n [geneCounts]=\"geneCounts\"\n [colormapOptions]=\"colormapOptions\"\n [open]=\"open.transcripts\"\n (openChange)=\"setOpen('transcripts', $event)\"\n >\n </spatial-transcripts-panel>\n\n <!-- Annotations: the drawn regions, and selecting what they enclose. -->\n <div class=\"sc-panel\" [class.open]=\"open.annotations\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('annotations')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showAnnotations !== false\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowAnnotations($event.checked)\"\n pTooltip=\"Show the drawn regions\"\n tooltipPosition=\"top\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Annotations</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.annotations\" [class.pi-chevron-right]=\"!open.annotations\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.annotations\">\n <div class=\"sc-row\">\n <p-button\n label=\"Select from ROIs\"\n icon=\"pi pi-object-group\"\n size=\"small\"\n [outlined]=\"true\"\n [loading]=\"selectingFromRegions\"\n (onClick)=\"selectFromRegions()\"\n [pTooltip]=\"\n selectsClassVolumes\n ? 'Select every observation inside the volumes of the classes picked in the Region Editor'\n : 'Select every observation inside the drawn regions'\n \"\n tooltipPosition=\"top\"\n ></p-button>\n <p-button\n *ngIf=\"hasSelection\"\n label=\"Clear\"\n size=\"small\"\n [text]=\"true\"\n (onClick)=\"clearSelection()\"\n ></p-button>\n </div>\n <small class=\"sc-hint\" *ngIf=\"hasSelection\">\n {{ selection.count | number }} of {{ ds.observations.count | number }} selected \u2014 the rest are muted.\n </small>\n <small class=\"sc-hint\" *ngIf=\"selectionMissed\">\n No observations fell inside the\n {{ missedMode === 'class-volumes' ? 'picked classes' : 'drawn regions' }}.\n </small>\n <small class=\"sc-hint\" *ngIf=\"selectsClassVolumes\">\n Selects inside the volume of {{ pickedClasses[0]\n }}{{ pickedClasses.length > 1 ? ' and ' + (pickedClasses.length - 1 | number) + ' more classes' : '' }},\n picked in the Region Editor. Draw a region to select by it instead.\n </small>\n <small class=\"sc-hint\" *ngIf=\"is3d && !selectsClassVolumes && pickedClasses.length\">\n The classes picked in the Region Editor are not on the reference volume shown here, so this selects by\n the regions drawn over the cloud instead.\n </small>\n <small class=\"sc-hint\" *ngIf=\"is3d && !selectsClassVolumes\">\n In 3D a region cuts through the cloud's full depth. Orbit and draw again to cut from another angle.\n <ng-container *ngIf=\"!pickedClasses.length\">\n Pick classes in the Region Editor's class tree to select inside their volumes.\n </ng-container>\n </small>\n </div>\n </div>\n\n <!-- Observations, then what else draws them: the gene map, the 3D scene, and the\n continuous-only knobs. -->\n <spatial-observations-panel\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [legend]=\"legend\"\n [colorBarCss]=\"colorBarCss\"\n [selection]=\"selection\"\n [selectedCategory]=\"selectedCategory\"\n [colormapOptions]=\"colormapOptions\"\n [is3d]=\"is3d\"\n [open]=\"open.observations\"\n (openChange)=\"setOpen('observations', $event)\"\n (categoryClicked)=\"selectCategory($event)\"\n ></spatial-observations-panel>\n\n <!-- Distributions of whatever the map is coloured by. In the SAME dialog as\n the colour controls on purpose: changing the gene and watching the\n distribution move is one action, and two floating windows made that\n harder to see rather than easier. -->\n <div class=\"sc-section sc-charts\">\n <button\n type=\"button\"\n class=\"sc-disclosure\"\n (click)=\"toggleCharts()\"\n [attr.aria-expanded]=\"chartsOpen\"\n [attr.aria-controls]=\"chartsBodyId\"\n >\n <i class=\"pi\" [class.pi-chevron-right]=\"!chartsOpen\" [class.pi-chevron-down]=\"chartsOpen\"></i>\n <span>Distribution</span>\n <small *ngIf=\"!chartsOpen && view.colorBy\">of {{ colorByLabel }}</small>\n </button>\n <!-- Kept MOUNTED when collapsed, only hidden: destroying it would throw\n away the chart kind and grouping the user picked. `active` is what\n stops it drawing while it has no size. -->\n <div [id]=\"chartsBodyId\" [hidden]=\"!chartsOpen\">\n <spatial-charts [active]=\"visible && chartsOpen\"></spatial-charts>\n </div>\n </div>\n\n <div class=\"sc-btns\">\n <p-button label=\"Reset\" size=\"small\" [text]=\"true\" (onClick)=\"reset()\"></p-button>\n </div>\n </div>\n</p-dialog>\n", styles: [".sc-hint{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-error{color:var(--red-600, #c62828)}.sc-section{display:flex;flex-direction:column;gap:.35rem}.sc-lbl{font-size:.78rem;color:var(--text-color-secondary, #6c757d);white-space:nowrap}.sc-row{display:flex;align-items:center;gap:.6rem}.sc-row p-slider,.sc-row p-dropdown,.sc-row p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row p-slider .p-slider{width:100%}:host ::ng-deep .sc-row p-dropdown .p-dropdown,:host ::ng-deep .sc-row p-treeSelect .p-treeselect{width:100%}.sc-row .sc-lbl{flex:0 0 calc(50% - .6rem);min-width:0;overflow:hidden;text-overflow:ellipsis}.sc-cmap-option{display:inline-flex;align-items:center;gap:.4rem}.sc-cmap-swatch{width:3.5rem;height:.7rem;border-radius:2px;display:block}.sc-val{flex:0 0 4rem;text-align:right;font-size:.78rem;font-variant-numeric:tabular-nums;white-space:nowrap}:host ::ng-deep .sc-full,:host ::ng-deep .sc-full .p-dropdown,:host ::ng-deep .sc-full .p-autocomplete,:host ::ng-deep .sc-full input{width:100%}.sc-colorbar{height:.75rem;border-radius:2px;border:1px solid rgba(0,0,0,.2)}.sc-colorbar-ends{display:flex;justify-content:space-between;font-size:.7rem;color:var(--text-color-secondary, #6c757d);margin-top:.2rem}.sc-panel{border:1px solid var(--surface-border, #dee2e6);border-radius:6px;margin-bottom:.5rem;overflow:hidden}.sc-panel-head{display:flex;align-items:center;gap:.6rem;padding:.5rem .7rem;cursor:pointer;-webkit-user-select:none;user-select:none;background:var(--surface-100, #f5f6f7)}.sc-panel-head .sc-panel-title{flex:1;font-weight:600}.sc-panel.open>.sc-panel-head{background:var(--primary-color, #2196f3);color:var(--primary-color-text, #fff)}.sc-panel-body{display:flex;flex-direction:column;gap:.45rem;padding:.6rem .75rem .75rem}.sc-subhead{display:flex;align-items:center;gap:.5rem;margin-top:.4rem;font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-color-secondary, #6c757d)}.sc-subhead:after{content:\"\";flex:1;border-top:1px solid var(--surface-border, #dee2e6)}:host ::ng-deep .sc-buttons .p-button{padding:.35rem .75rem;font-size:.85rem}.sc-row-picker p-dropdown,.sc-row-picker p-multiSelect,.sc-row-picker p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row-picker .sc-variant{width:6.5rem}:host ::ng-deep .sc-row-picker p-multiselect .p-multiselect{width:100%}:host ::ng-deep .sc-row-picker p-dropdown:has(.sc-variant){flex:0 0 6.5rem}:host ::ng-deep .sc-row-picker p-treeselect:has(.sc-palette){flex:0 0 3rem}:host ::ng-deep .sc-palette .p-treeselect-label{width:0;padding:0}.sc-icon-btn{flex:0 0 auto;border:0;background:transparent;cursor:pointer;padding:.25rem .35rem;font:inherit;font-size:1.05rem;color:var(--text-color, #333);border-radius:4px}.sc-icon-btn:hover{background:var(--surface-200, #e9ecef)}.sc-icon-btn.active{color:var(--primary-color, #2196f3);font-weight:700}.sc-icon-btn:disabled{opacity:.5;cursor:default}.sc-small-btn{margin-left:auto;border:1px solid var(--surface-border, #ced4da);background:var(--surface-0, #fff);border-radius:4px;padding:.2rem .6rem;font:inherit;font-size:.8rem;cursor:pointer}:host ::ng-deep .sc-group-heading{font-size:.7rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;opacity:.7}.sc-group-list,.sc-gene-tree{max-height:16rem;overflow-y:auto;border:1px solid var(--surface-border, #dee2e6);border-radius:4px;padding:.25rem .4rem}.sc-group-row,.sc-gene-row{display:flex;align-items:center;gap:.45rem;padding:.15rem 0;font-size:.88rem}.sc-group-row .sc-group-label,.sc-gene-row .sc-group-label{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-group-all,.sc-gene-root,.sc-gene-group{font-weight:600}.sc-group-all .sc-icon-btn,.sc-gene-root .sc-icon-btn,.sc-gene-group .sc-icon-btn{margin-left:auto;font-size:.85rem}.sc-count{flex:0 0 auto;font-size:.78rem;color:var(--text-color-secondary, #6c757d)}.sc-glyph-option{display:inline-flex;align-items:center;gap:.4rem}.sc-glyph-svg{width:1rem;height:1rem;fill:currentColor}:host ::ng-deep .sc-glyph-pick .p-dropdown-label{padding:.2rem .4rem}.sc-color-input{width:2.5rem;height:1.8rem;border:1px solid var(--surface-border, #ced4da);border-radius:4px;padding:0;background:none}.sc-row-number p-slider,.sc-row-range p-slider{flex:1 1 0;min-width:0}:host ::ng-deep .sc-num{width:4.5rem;padding:.3rem .4rem;text-align:center}:host ::ng-deep .sc-row-number p-inputnumber,:host ::ng-deep .sc-row-range p-inputnumber{flex:0 0 auto}:host ::ng-deep .spatial-controls-dialog .p-dialog-content{padding:.75rem 1rem 1rem}.sc-empty{padding:.5rem 0;font-size:.85rem;color:var(--text-color-secondary, #6c757d);line-height:1.4}.sc-empty code{font-size:.8rem}.sc-body{display:flex;flex-direction:column;gap:.85rem}.sc-dataset{display:flex;flex-direction:column;gap:.1rem;padding-bottom:.5rem;border-bottom:1px solid var(--surface-border, #dee2e6)}.sc-dataset-name{font-weight:600;font-size:.9rem}.sc-dataset-count{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-btns{display:flex;justify-content:flex-end}.sc-charts{padding-top:.5rem;border-top:1px solid var(--surface-border, #dee2e6);gap:0}.sc-disclosure{display:flex;align-items:center;gap:.4rem;width:100%;padding:.2rem 0;font:inherit;font-size:.82rem;font-weight:600;text-align:left;background:none;border:0;cursor:pointer;color:inherit}.sc-disclosure i{font-size:.7rem;color:var(--text-color-secondary, #6c757d)}.sc-disclosure small{font-weight:400;color:var(--text-color-secondary, #6c757d);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-disclosure:hover{color:var(--primary-color, #3b82f6)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i3.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4.Checkbox, selector: "p-checkbox", inputs: ["value", "name", "disabled", "binary", "label", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "styleClass", "labelStyleClass", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i5.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "visible", "style", "position"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: SpatialCellsPanelComponent, selector: "spatial-cells-panel", inputs: ["controls", "dataset", "view", "genes", "colorBarCss", "open"], outputs: ["openChange"] }, { kind: "component", type: SpatialTranscriptsPanelComponent, selector: "spatial-transcripts-panel", inputs: ["controls", "dataset", "view", "genes", "estimate", "densityStats", "geneCounts", "colormapOptions", "open"], outputs: ["openChange"] }, { kind: "component", type: SpatialObservationsPanelComponent, selector: "spatial-observations-panel", inputs: ["controls", "dataset", "view", "genes", "legend", "colorBarCss", "selection", "selectedCategory", "colormapOptions", "is3d", "open"], outputs: ["openChange", "categoryClicked"] }, { kind: "component", type: SpatialChartsComponent, selector: "spatial-charts", inputs: ["active"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
327
369
  }
328
370
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: SpatialControlsComponent, decorators: [{
329
371
  type: Component,
@@ -338,7 +380,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
338
380
  SpatialTranscriptsPanelComponent,
339
381
  SpatialObservationsPanelComponent,
340
382
  SpatialChartsComponent,
341
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<p-dialog\n header=\"Spatial omics\"\n [visible]=\"visible\"\n (visibleChange)=\"onVisibleChange($event)\"\n [modal]=\"false\"\n [resizable]=\"true\"\n [draggable]=\"true\"\n position=\"left\"\n (onResizeEnd)=\"onResizeEnd()\"\n [style]=\"{ width: '30rem' }\"\n [breakpoints]=\"{ '960px': '90vw' }\"\n styleClass=\"spatial-controls-dialog\"\n>\n <!-- No port bound: say why rather than showing controls that do nothing. -->\n <div class=\"sc-empty\" *ngIf=\"!controls\">\n No spatial-omics data source is configured. A host provides one by binding\n <code>SPATIAL_DATA_PORT</code>.\n </div>\n\n <div class=\"sc-empty\" *ngIf=\"controls && !dataset\">No dataset is loaded.</div>\n\n <div class=\"sc-body\" *ngIf=\"controls && dataset as ds\">\n <div class=\"sc-dataset\">\n <span class=\"sc-dataset-name\">{{ ds.name }}</span>\n <span class=\"sc-dataset-count\">{{ ds.observations.count | number }} observations</span>\n </div>\n\n <!-- Organised as Xenium Explorer's side panel: one collapsible section per layer,\n each with its own on/off switch in the header. -->\n\n <!-- Images -->\n <div class=\"sc-panel\" *ngIf=\"ds.imageRef && !is3d\" [class.open]=\"open.images\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('images')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showImage\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowImage($event.checked)\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Images</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.images\" [class.pi-chevron-right]=\"!open.images\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.images\">\n <small class=\"sc-hint\"> Channels, colours and contrast are in the Channels &amp; Histogram dialog. </small>\n </div>\n </div>\n\n <!-- Cells -->\n <spatial-cells-panel\n *ngIf=\"hasCells && !is3d\"\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [colorBarCss]=\"colorBarCss\"\n [open]=\"open.cells\"\n (openChange)=\"setOpen('cells', $event)\"\n ></spatial-cells-panel>\n\n <!-- Transcripts -->\n <spatial-transcripts-panel\n *ngIf=\"hasTranscripts && !is3d\"\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [estimate]=\"estimate\"\n [densityStats]=\"densityStats\"\n [geneCounts]=\"geneCounts\"\n [colormapOptions]=\"colormapOptions\"\n [open]=\"open.transcripts\"\n (openChange)=\"setOpen('transcripts', $event)\"\n >\n </spatial-transcripts-panel>\n\n <!-- Annotations: the drawn regions, and selecting what they enclose. -->\n <div class=\"sc-panel\" [class.open]=\"open.annotations\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('annotations')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showAnnotations !== false\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowAnnotations($event.checked)\"\n pTooltip=\"Show the drawn regions\"\n tooltipPosition=\"top\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Annotations</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.annotations\" [class.pi-chevron-right]=\"!open.annotations\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.annotations\">\n <div class=\"sc-row\">\n <p-button\n label=\"Select from ROIs\"\n icon=\"pi pi-object-group\"\n size=\"small\"\n [outlined]=\"true\"\n (onClick)=\"selectFromRegions()\"\n pTooltip=\"Select every observation inside the drawn regions\"\n tooltipPosition=\"top\"\n ></p-button>\n <p-button\n *ngIf=\"hasSelection\"\n label=\"Clear\"\n size=\"small\"\n [text]=\"true\"\n (onClick)=\"clearSelection()\"\n ></p-button>\n </div>\n <small class=\"sc-hint\" *ngIf=\"hasSelection\">\n {{ selection.count | number }} of {{ ds.observations.count | number }} selected \u2014 the rest are muted.\n </small>\n <small class=\"sc-hint\" *ngIf=\"selectionMissed\"> No observations fell inside the drawn regions. </small>\n <small class=\"sc-hint\" *ngIf=\"is3d\">\n In 3D a region cuts through the cloud's full depth. Orbit and draw again to cut from another angle.\n </small>\n </div>\n </div>\n\n <!-- Observations, then what else draws them: the gene map, the 3D scene, and the\n continuous-only knobs. -->\n <spatial-observations-panel\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [legend]=\"legend\"\n [colorBarCss]=\"colorBarCss\"\n [selection]=\"selection\"\n [selectedCategory]=\"selectedCategory\"\n [colormapOptions]=\"colormapOptions\"\n [is3d]=\"is3d\"\n [open]=\"open.observations\"\n (openChange)=\"setOpen('observations', $event)\"\n (categoryClicked)=\"selectCategory($event)\"\n ></spatial-observations-panel>\n\n <!-- Distributions of whatever the map is coloured by. In the SAME dialog as\n the colour controls on purpose: changing the gene and watching the\n distribution move is one action, and two floating windows made that\n harder to see rather than easier. -->\n <div class=\"sc-section sc-charts\">\n <button\n type=\"button\"\n class=\"sc-disclosure\"\n (click)=\"toggleCharts()\"\n [attr.aria-expanded]=\"chartsOpen\"\n [attr.aria-controls]=\"chartsBodyId\"\n >\n <i class=\"pi\" [class.pi-chevron-right]=\"!chartsOpen\" [class.pi-chevron-down]=\"chartsOpen\"></i>\n <span>Distribution</span>\n <small *ngIf=\"!chartsOpen && view.colorBy\">of {{ colorByLabel }}</small>\n </button>\n <!-- Kept MOUNTED when collapsed, only hidden: destroying it would throw\n away the chart kind and grouping the user picked. `active` is what\n stops it drawing while it has no size. -->\n <div [id]=\"chartsBodyId\" [hidden]=\"!chartsOpen\">\n <spatial-charts [active]=\"visible && chartsOpen\"></spatial-charts>\n </div>\n </div>\n\n <div class=\"sc-btns\">\n <p-button label=\"Reset\" size=\"small\" [text]=\"true\" (onClick)=\"reset()\"></p-button>\n </div>\n </div>\n</p-dialog>\n", styles: [".sc-hint{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-error{color:var(--red-600, #c62828)}.sc-section{display:flex;flex-direction:column;gap:.35rem}.sc-lbl{font-size:.78rem;color:var(--text-color-secondary, #6c757d);white-space:nowrap}.sc-row{display:flex;align-items:center;gap:.6rem}.sc-row p-slider,.sc-row p-dropdown,.sc-row p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row p-slider .p-slider{width:100%}:host ::ng-deep .sc-row p-dropdown .p-dropdown,:host ::ng-deep .sc-row p-treeSelect .p-treeselect{width:100%}.sc-row .sc-lbl{flex:0 0 calc(50% - .6rem);min-width:0;overflow:hidden;text-overflow:ellipsis}.sc-cmap-option{display:inline-flex;align-items:center;gap:.4rem}.sc-cmap-swatch{width:3.5rem;height:.7rem;border-radius:2px;display:block}.sc-val{flex:0 0 4rem;text-align:right;font-size:.78rem;font-variant-numeric:tabular-nums;white-space:nowrap}:host ::ng-deep .sc-full,:host ::ng-deep .sc-full .p-dropdown,:host ::ng-deep .sc-full .p-autocomplete,:host ::ng-deep .sc-full input{width:100%}.sc-colorbar{height:.75rem;border-radius:2px;border:1px solid rgba(0,0,0,.2)}.sc-colorbar-ends{display:flex;justify-content:space-between;font-size:.7rem;color:var(--text-color-secondary, #6c757d);margin-top:.2rem}.sc-panel{border:1px solid var(--surface-border, #dee2e6);border-radius:6px;margin-bottom:.5rem;overflow:hidden}.sc-panel-head{display:flex;align-items:center;gap:.6rem;padding:.5rem .7rem;cursor:pointer;-webkit-user-select:none;user-select:none;background:var(--surface-100, #f5f6f7)}.sc-panel-head .sc-panel-title{flex:1;font-weight:600}.sc-panel.open>.sc-panel-head{background:var(--primary-color, #2196f3);color:var(--primary-color-text, #fff)}.sc-panel-body{display:flex;flex-direction:column;gap:.45rem;padding:.6rem .75rem .75rem}.sc-subhead{display:flex;align-items:center;gap:.5rem;margin-top:.4rem;font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-color-secondary, #6c757d)}.sc-subhead:after{content:\"\";flex:1;border-top:1px solid var(--surface-border, #dee2e6)}:host ::ng-deep .sc-buttons .p-button{padding:.35rem .75rem;font-size:.85rem}.sc-row-picker p-dropdown,.sc-row-picker p-multiSelect,.sc-row-picker p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row-picker .sc-variant{width:6.5rem}:host ::ng-deep .sc-row-picker p-multiselect .p-multiselect{width:100%}:host ::ng-deep .sc-row-picker p-dropdown:has(.sc-variant){flex:0 0 6.5rem}:host ::ng-deep .sc-row-picker p-treeselect:has(.sc-palette){flex:0 0 3rem}:host ::ng-deep .sc-palette .p-treeselect-label{width:0;padding:0}.sc-icon-btn{flex:0 0 auto;border:0;background:transparent;cursor:pointer;padding:.25rem .35rem;font:inherit;font-size:1.05rem;color:var(--text-color, #333);border-radius:4px}.sc-icon-btn:hover{background:var(--surface-200, #e9ecef)}.sc-icon-btn.active{color:var(--primary-color, #2196f3);font-weight:700}.sc-icon-btn:disabled{opacity:.5;cursor:default}.sc-small-btn{margin-left:auto;border:1px solid var(--surface-border, #ced4da);background:var(--surface-0, #fff);border-radius:4px;padding:.2rem .6rem;font:inherit;font-size:.8rem;cursor:pointer}:host ::ng-deep .sc-group-heading{font-size:.7rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;opacity:.7}.sc-group-list,.sc-gene-tree{max-height:16rem;overflow-y:auto;border:1px solid var(--surface-border, #dee2e6);border-radius:4px;padding:.25rem .4rem}.sc-group-row,.sc-gene-row{display:flex;align-items:center;gap:.45rem;padding:.15rem 0;font-size:.88rem}.sc-group-row .sc-group-label,.sc-gene-row .sc-group-label{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-group-all,.sc-gene-root,.sc-gene-group{font-weight:600}.sc-group-all .sc-icon-btn,.sc-gene-root .sc-icon-btn,.sc-gene-group .sc-icon-btn{margin-left:auto;font-size:.85rem}.sc-count{flex:0 0 auto;font-size:.78rem;color:var(--text-color-secondary, #6c757d)}.sc-glyph-option{display:inline-flex;align-items:center;gap:.4rem}.sc-glyph-svg{width:1rem;height:1rem;fill:currentColor}:host ::ng-deep .sc-glyph-pick .p-dropdown-label{padding:.2rem .4rem}.sc-color-input{width:2.5rem;height:1.8rem;border:1px solid var(--surface-border, #ced4da);border-radius:4px;padding:0;background:none}.sc-row-number p-slider,.sc-row-range p-slider{flex:1 1 0;min-width:0}:host ::ng-deep .sc-num{width:4.5rem;padding:.3rem .4rem;text-align:center}:host ::ng-deep .sc-row-number p-inputnumber,:host ::ng-deep .sc-row-range p-inputnumber{flex:0 0 auto}:host ::ng-deep .spatial-controls-dialog .p-dialog-content{padding:.75rem 1rem 1rem}.sc-empty{padding:.5rem 0;font-size:.85rem;color:var(--text-color-secondary, #6c757d);line-height:1.4}.sc-empty code{font-size:.8rem}.sc-body{display:flex;flex-direction:column;gap:.85rem}.sc-dataset{display:flex;flex-direction:column;gap:.1rem;padding-bottom:.5rem;border-bottom:1px solid var(--surface-border, #dee2e6)}.sc-dataset-name{font-weight:600;font-size:.9rem}.sc-dataset-count{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-btns{display:flex;justify-content:flex-end}.sc-charts{padding-top:.5rem;border-top:1px solid var(--surface-border, #dee2e6);gap:0}.sc-disclosure{display:flex;align-items:center;gap:.4rem;width:100%;padding:.2rem 0;font:inherit;font-size:.82rem;font-weight:600;text-align:left;background:none;border:0;cursor:pointer;color:inherit}.sc-disclosure i{font-size:.7rem;color:var(--text-color-secondary, #6c757d)}.sc-disclosure small{font-weight:400;color:var(--text-color-secondary, #6c757d);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-disclosure:hover{color:var(--primary-color, #3b82f6)}\n"] }]
383
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<p-dialog\n header=\"Spatial omics\"\n [visible]=\"visible\"\n (visibleChange)=\"onVisibleChange($event)\"\n [modal]=\"false\"\n [resizable]=\"true\"\n [draggable]=\"true\"\n position=\"left\"\n (onResizeEnd)=\"onResizeEnd()\"\n [style]=\"{ width: '30rem' }\"\n [breakpoints]=\"{ '960px': '90vw' }\"\n styleClass=\"spatial-controls-dialog\"\n>\n <!-- No port bound: say why rather than showing controls that do nothing. -->\n <div class=\"sc-empty\" *ngIf=\"!controls\">\n No spatial-omics data source is configured. A host provides one by binding\n <code>SPATIAL_DATA_PORT</code>.\n </div>\n\n <div class=\"sc-empty\" *ngIf=\"controls && !dataset\">No dataset is loaded.</div>\n\n <div class=\"sc-body\" *ngIf=\"controls && dataset as ds\">\n <div class=\"sc-dataset\">\n <span class=\"sc-dataset-name\">{{ ds.name }}</span>\n <span class=\"sc-dataset-count\">{{ ds.observations.count | number }} observations</span>\n </div>\n\n <!-- Organised as Xenium Explorer's side panel: one collapsible section per layer,\n each with its own on/off switch in the header. -->\n\n <!-- Images -->\n <div class=\"sc-panel\" *ngIf=\"ds.imageRef && !is3d\" [class.open]=\"open.images\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('images')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showImage\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowImage($event.checked)\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Images</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.images\" [class.pi-chevron-right]=\"!open.images\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.images\">\n <small class=\"sc-hint\"> Channels, colours and contrast are in the Channels &amp; Histogram dialog. </small>\n </div>\n </div>\n\n <!-- Cells -->\n <spatial-cells-panel\n *ngIf=\"hasCells && !is3d\"\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [colorBarCss]=\"colorBarCss\"\n [open]=\"open.cells\"\n (openChange)=\"setOpen('cells', $event)\"\n ></spatial-cells-panel>\n\n <!-- Transcripts -->\n <spatial-transcripts-panel\n *ngIf=\"hasTranscripts && !is3d\"\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [estimate]=\"estimate\"\n [densityStats]=\"densityStats\"\n [geneCounts]=\"geneCounts\"\n [colormapOptions]=\"colormapOptions\"\n [open]=\"open.transcripts\"\n (openChange)=\"setOpen('transcripts', $event)\"\n >\n </spatial-transcripts-panel>\n\n <!-- Annotations: the drawn regions, and selecting what they enclose. -->\n <div class=\"sc-panel\" [class.open]=\"open.annotations\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('annotations')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showAnnotations !== false\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowAnnotations($event.checked)\"\n pTooltip=\"Show the drawn regions\"\n tooltipPosition=\"top\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Annotations</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.annotations\" [class.pi-chevron-right]=\"!open.annotations\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.annotations\">\n <div class=\"sc-row\">\n <p-button\n label=\"Select from ROIs\"\n icon=\"pi pi-object-group\"\n size=\"small\"\n [outlined]=\"true\"\n [loading]=\"selectingFromRegions\"\n (onClick)=\"selectFromRegions()\"\n [pTooltip]=\"\n selectsClassVolumes\n ? 'Select every observation inside the volumes of the classes picked in the Region Editor'\n : 'Select every observation inside the drawn regions'\n \"\n tooltipPosition=\"top\"\n ></p-button>\n <p-button\n *ngIf=\"hasSelection\"\n label=\"Clear\"\n size=\"small\"\n [text]=\"true\"\n (onClick)=\"clearSelection()\"\n ></p-button>\n </div>\n <small class=\"sc-hint\" *ngIf=\"hasSelection\">\n {{ selection.count | number }} of {{ ds.observations.count | number }} selected \u2014 the rest are muted.\n </small>\n <small class=\"sc-hint\" *ngIf=\"selectionMissed\">\n No observations fell inside the\n {{ missedMode === 'class-volumes' ? 'picked classes' : 'drawn regions' }}.\n </small>\n <small class=\"sc-hint\" *ngIf=\"selectsClassVolumes\">\n Selects inside the volume of {{ pickedClasses[0]\n }}{{ pickedClasses.length > 1 ? ' and ' + (pickedClasses.length - 1 | number) + ' more classes' : '' }},\n picked in the Region Editor. Draw a region to select by it instead.\n </small>\n <small class=\"sc-hint\" *ngIf=\"is3d && !selectsClassVolumes && pickedClasses.length\">\n The classes picked in the Region Editor are not on the reference volume shown here, so this selects by\n the regions drawn over the cloud instead.\n </small>\n <small class=\"sc-hint\" *ngIf=\"is3d && !selectsClassVolumes\">\n In 3D a region cuts through the cloud's full depth. Orbit and draw again to cut from another angle.\n <ng-container *ngIf=\"!pickedClasses.length\">\n Pick classes in the Region Editor's class tree to select inside their volumes.\n </ng-container>\n </small>\n </div>\n </div>\n\n <!-- Observations, then what else draws them: the gene map, the 3D scene, and the\n continuous-only knobs. -->\n <spatial-observations-panel\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [legend]=\"legend\"\n [colorBarCss]=\"colorBarCss\"\n [selection]=\"selection\"\n [selectedCategory]=\"selectedCategory\"\n [colormapOptions]=\"colormapOptions\"\n [is3d]=\"is3d\"\n [open]=\"open.observations\"\n (openChange)=\"setOpen('observations', $event)\"\n (categoryClicked)=\"selectCategory($event)\"\n ></spatial-observations-panel>\n\n <!-- Distributions of whatever the map is coloured by. In the SAME dialog as\n the colour controls on purpose: changing the gene and watching the\n distribution move is one action, and two floating windows made that\n harder to see rather than easier. -->\n <div class=\"sc-section sc-charts\">\n <button\n type=\"button\"\n class=\"sc-disclosure\"\n (click)=\"toggleCharts()\"\n [attr.aria-expanded]=\"chartsOpen\"\n [attr.aria-controls]=\"chartsBodyId\"\n >\n <i class=\"pi\" [class.pi-chevron-right]=\"!chartsOpen\" [class.pi-chevron-down]=\"chartsOpen\"></i>\n <span>Distribution</span>\n <small *ngIf=\"!chartsOpen && view.colorBy\">of {{ colorByLabel }}</small>\n </button>\n <!-- Kept MOUNTED when collapsed, only hidden: destroying it would throw\n away the chart kind and grouping the user picked. `active` is what\n stops it drawing while it has no size. -->\n <div [id]=\"chartsBodyId\" [hidden]=\"!chartsOpen\">\n <spatial-charts [active]=\"visible && chartsOpen\"></spatial-charts>\n </div>\n </div>\n\n <div class=\"sc-btns\">\n <p-button label=\"Reset\" size=\"small\" [text]=\"true\" (onClick)=\"reset()\"></p-button>\n </div>\n </div>\n</p-dialog>\n", styles: [".sc-hint{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-error{color:var(--red-600, #c62828)}.sc-section{display:flex;flex-direction:column;gap:.35rem}.sc-lbl{font-size:.78rem;color:var(--text-color-secondary, #6c757d);white-space:nowrap}.sc-row{display:flex;align-items:center;gap:.6rem}.sc-row p-slider,.sc-row p-dropdown,.sc-row p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row p-slider .p-slider{width:100%}:host ::ng-deep .sc-row p-dropdown .p-dropdown,:host ::ng-deep .sc-row p-treeSelect .p-treeselect{width:100%}.sc-row .sc-lbl{flex:0 0 calc(50% - .6rem);min-width:0;overflow:hidden;text-overflow:ellipsis}.sc-cmap-option{display:inline-flex;align-items:center;gap:.4rem}.sc-cmap-swatch{width:3.5rem;height:.7rem;border-radius:2px;display:block}.sc-val{flex:0 0 4rem;text-align:right;font-size:.78rem;font-variant-numeric:tabular-nums;white-space:nowrap}:host ::ng-deep .sc-full,:host ::ng-deep .sc-full .p-dropdown,:host ::ng-deep .sc-full .p-autocomplete,:host ::ng-deep .sc-full input{width:100%}.sc-colorbar{height:.75rem;border-radius:2px;border:1px solid rgba(0,0,0,.2)}.sc-colorbar-ends{display:flex;justify-content:space-between;font-size:.7rem;color:var(--text-color-secondary, #6c757d);margin-top:.2rem}.sc-panel{border:1px solid var(--surface-border, #dee2e6);border-radius:6px;margin-bottom:.5rem;overflow:hidden}.sc-panel-head{display:flex;align-items:center;gap:.6rem;padding:.5rem .7rem;cursor:pointer;-webkit-user-select:none;user-select:none;background:var(--surface-100, #f5f6f7)}.sc-panel-head .sc-panel-title{flex:1;font-weight:600}.sc-panel.open>.sc-panel-head{background:var(--primary-color, #2196f3);color:var(--primary-color-text, #fff)}.sc-panel-body{display:flex;flex-direction:column;gap:.45rem;padding:.6rem .75rem .75rem}.sc-subhead{display:flex;align-items:center;gap:.5rem;margin-top:.4rem;font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-color-secondary, #6c757d)}.sc-subhead:after{content:\"\";flex:1;border-top:1px solid var(--surface-border, #dee2e6)}:host ::ng-deep .sc-buttons .p-button{padding:.35rem .75rem;font-size:.85rem}.sc-row-picker p-dropdown,.sc-row-picker p-multiSelect,.sc-row-picker p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row-picker .sc-variant{width:6.5rem}:host ::ng-deep .sc-row-picker p-multiselect .p-multiselect{width:100%}:host ::ng-deep .sc-row-picker p-dropdown:has(.sc-variant){flex:0 0 6.5rem}:host ::ng-deep .sc-row-picker p-treeselect:has(.sc-palette){flex:0 0 3rem}:host ::ng-deep .sc-palette .p-treeselect-label{width:0;padding:0}.sc-icon-btn{flex:0 0 auto;border:0;background:transparent;cursor:pointer;padding:.25rem .35rem;font:inherit;font-size:1.05rem;color:var(--text-color, #333);border-radius:4px}.sc-icon-btn:hover{background:var(--surface-200, #e9ecef)}.sc-icon-btn.active{color:var(--primary-color, #2196f3);font-weight:700}.sc-icon-btn:disabled{opacity:.5;cursor:default}.sc-small-btn{margin-left:auto;border:1px solid var(--surface-border, #ced4da);background:var(--surface-0, #fff);border-radius:4px;padding:.2rem .6rem;font:inherit;font-size:.8rem;cursor:pointer}:host ::ng-deep .sc-group-heading{font-size:.7rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;opacity:.7}.sc-group-list,.sc-gene-tree{max-height:16rem;overflow-y:auto;border:1px solid var(--surface-border, #dee2e6);border-radius:4px;padding:.25rem .4rem}.sc-group-row,.sc-gene-row{display:flex;align-items:center;gap:.45rem;padding:.15rem 0;font-size:.88rem}.sc-group-row .sc-group-label,.sc-gene-row .sc-group-label{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-group-all,.sc-gene-root,.sc-gene-group{font-weight:600}.sc-group-all .sc-icon-btn,.sc-gene-root .sc-icon-btn,.sc-gene-group .sc-icon-btn{margin-left:auto;font-size:.85rem}.sc-count{flex:0 0 auto;font-size:.78rem;color:var(--text-color-secondary, #6c757d)}.sc-glyph-option{display:inline-flex;align-items:center;gap:.4rem}.sc-glyph-svg{width:1rem;height:1rem;fill:currentColor}:host ::ng-deep .sc-glyph-pick .p-dropdown-label{padding:.2rem .4rem}.sc-color-input{width:2.5rem;height:1.8rem;border:1px solid var(--surface-border, #ced4da);border-radius:4px;padding:0;background:none}.sc-row-number p-slider,.sc-row-range p-slider{flex:1 1 0;min-width:0}:host ::ng-deep .sc-num{width:4.5rem;padding:.3rem .4rem;text-align:center}:host ::ng-deep .sc-row-number p-inputnumber,:host ::ng-deep .sc-row-range p-inputnumber{flex:0 0 auto}:host ::ng-deep .spatial-controls-dialog .p-dialog-content{padding:.75rem 1rem 1rem}.sc-empty{padding:.5rem 0;font-size:.85rem;color:var(--text-color-secondary, #6c757d);line-height:1.4}.sc-empty code{font-size:.8rem}.sc-body{display:flex;flex-direction:column;gap:.85rem}.sc-dataset{display:flex;flex-direction:column;gap:.1rem;padding-bottom:.5rem;border-bottom:1px solid var(--surface-border, #dee2e6)}.sc-dataset-name{font-weight:600;font-size:.9rem}.sc-dataset-count{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-btns{display:flex;justify-content:flex-end}.sc-charts{padding-top:.5rem;border-top:1px solid var(--surface-border, #dee2e6);gap:0}.sc-disclosure{display:flex;align-items:center;gap:.4rem;width:100%;padding:.2rem 0;font:inherit;font-size:.82rem;font-weight:600;text-align:left;background:none;border:0;cursor:pointer;color:inherit}.sc-disclosure i{font-size:.7rem;color:var(--text-color-secondary, #6c757d)}.sc-disclosure small{font-weight:400;color:var(--text-color-secondary, #6c757d);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-disclosure:hover{color:var(--primary-color, #3b82f6)}\n"] }]
342
384
  }], ctorParameters: () => [{ type: undefined, decorators: [{
343
385
  type: Inject,
344
386
  args: [VISUALIZER]
@@ -352,4 +394,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
352
394
  }], visibleChange: [{
353
395
  type: Output
354
396
  }] } });
355
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhdGlhbC1jb250cm9scy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3NwYXRpYWwtY29udHJvbHMvc3BhdGlhbC1jb250cm9scy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9zcmMvbGliL3NwYXRpYWwtY29udHJvbHMvc3BhdGlhbC1jb250cm9scy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixNQUFNLEVBQ04sS0FBSyxFQUNMLE1BQU0sRUFFTixNQUFNLEVBQ04sU0FBUyxFQUNULE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXJDLE9BQU8sRUFBRSxVQUFVLEVBQWlDLE1BQU0sa0NBQWtDLENBQUM7QUFDN0YsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sMkNBQTJDLENBQUM7QUFFbkYsT0FBTyxFQUFrQyxvQkFBb0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ2xHLE9BQU8sRUFBZSxlQUFlLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUM5RSxPQUFPLEVBQXdCLGNBQWMsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ3BGLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsZUFBZSxFQUFzQixNQUFNLGlDQUFpQyxDQUFDO0FBQ3RGLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUNuRSxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxxREFBcUQsQ0FBQztBQUNqRyxPQUFPLEVBQUUsZ0NBQWdDLEVBQUUsTUFBTSxpRUFBaUUsQ0FBQztBQUNuSCxPQUFPLEVBQUUsaUNBQWlDLEVBQUUsTUFBTSxtRUFBbUUsQ0FBQzs7Ozs7Ozs7QUFLdEgsdUZBQXVGO0FBQ3ZGLE9BQU8sRUFBRSxlQUFlLEVBQUUsQ0FBQztBQUUzQixrRkFBa0Y7QUFDbEYsSUFBSSxtQkFBbUIsR0FBRyxDQUFDLENBQUM7QUFFNUI7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQkc7QUFvQkgsTUFBTSxPQUFPLHdCQUF3QjtJQUluQzs7Ozs7Ozs7T0FRRztJQUNPLFdBQVc7UUFDbkIsSUFBSSxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBNkJELG1DQUFtQztJQUNuQyxJQUFJLFdBQVc7UUFDYixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDO0lBQzVCLENBQUM7SUFDRCwwRkFBMEY7SUFDMUYsSUFBSSxjQUFjO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7SUFDM0IsQ0FBQztJQUNELElBQUksZ0JBQWdCO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7SUFDM0IsQ0FBQztJQU1ELHdFQUF3RTtJQUN4RSxJQUFjLE1BQU07UUFDbEIsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQztJQUN6QixDQUFDO0lBQ0QseUVBQXlFO0lBQ3pFLElBQWMsV0FBVztRQUN2QixPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDO0lBQzlCLENBQUM7SUE2QkQsWUFDdUMsR0FBZ0IsRUFDcEMsSUFBWTtRQURRLFFBQUcsR0FBSCxHQUFHLENBQWE7UUFDcEMsU0FBSSxHQUFKLElBQUksQ0FBUTtRQWpGL0Isd0VBQXdFO1FBQy9ELFlBQU8sR0FBRyxLQUFLLENBQUM7UUFDekI7O2lGQUV5RTtRQUNoRSxTQUFJLEdBQUcsS0FBSyxDQUFDO1FBQ3RCLHFFQUFxRTtRQUMzRCxrQkFBYSxHQUFHLElBQUksWUFBWSxFQUFXLENBQUM7UUFFdEQsdURBQXVEO1FBQzdDLGFBQVEsR0FBNEIsSUFBSSxDQUFDO1FBQ3pDLFlBQU8sR0FBMEIsSUFBSSxDQUFDO1FBQ3RDLFNBQUksR0FBcUIsRUFBRSxHQUFHLG9CQUFvQixFQUFFLENBQUM7UUFFL0Q7Ozs7V0FJRztRQUNnQixVQUFLLEdBQUcsSUFBSSxlQUFlLENBQzVDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQ25CLEdBQUcsRUFBRSxDQUFDO1lBQ0osR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsZUFBZSxJQUFJLEVBQUUsQ0FBQztZQUNyQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsSUFBSSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1NBQzVFLEVBQ0QsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLENBQzVCLENBQUM7UUFhRjs7cUVBRTZEO1FBQ3BELFFBQUcsR0FBRyxJQUFJLGVBQWUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBVWhFLDZFQUE2RTtRQUNuRSxjQUFTLEdBQXlCLGNBQWMsRUFBRSxDQUFDO1FBQzdELDZFQUE2RTtRQUNuRSxxQkFBZ0IsR0FBa0IsSUFBSSxDQUFDO1FBQ2pEO21EQUMyQztRQUNqQyxvQkFBZSxHQUFHLEtBQUssQ0FBQztRQUVsQzs7OztXQUlHO1FBQ08sZUFBVSxHQUFHLEtBQUssQ0FBQztRQUM3QjswRkFDa0Y7UUFDL0QsaUJBQVksR0FBRyxrQkFBa0IsRUFBRSxtQkFBbUIsRUFBRSxDQUFDO1FBRTVFO3NDQUM4QjtRQUNwQixvQkFBZSxHQUFtQixFQUFFLENBQUM7UUFFdkMsYUFBUSxHQUF3QixJQUFJLENBQUM7UUFDckMsWUFBTyxHQUFHLEtBQUssQ0FBQztRQUNQLGVBQVUsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDaEMsUUFBRyxHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBbUxqRCwrRUFBK0U7UUFDckUsU0FBSSxHQUF5RjtZQUNyRyxNQUFNLEVBQUUsS0FBSztZQUNiLEtBQUssRUFBRSxJQUFJO1lBQ1gsV0FBVyxFQUFFLEtBQUs7WUFDbEIsV0FBVyxFQUFFLEtBQUs7WUFDbEIsWUFBWSxFQUFFLEtBQUs7U0FDcEIsQ0FBQztRQVdGLHlFQUF5RTtRQUV6RSxpRkFBaUY7UUFDdkUsYUFBUSxHQUEyQyxJQUFJLENBQUM7UUFDbEUsZ0ZBQWdGO1FBQ3RFLGlCQUFZLEdBQW1ELElBQUksQ0FBQztRQUM5RSxnRkFBZ0Y7UUFDdEUsZUFBVSxHQUFrQyxJQUFJLENBQUM7SUF2TXhELENBQUM7SUFFSixRQUFRO1FBQ04sSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLGtCQUFrQixFQUFFLEVBQUUsSUFBSSxJQUFJLENBQUM7UUFDeEQsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLGtCQUFrQixFQUFFLEVBQUUsSUFBSSxFQUFFLENBQUM7UUFDN0QsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRO1lBQUUsT0FBTztRQUUzQixNQUFNLGNBQWMsR0FBRyxHQUFNLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBSSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDdkUsSUFBSSxDQUFDLFFBQVE7YUFDVixXQUFXLEVBQUU7YUFDYixJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7YUFDdEIsU0FBUyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDckIsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7WUFDdkIsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDL0Isa0VBQWtFO1lBQ2xFLElBQUksQ0FBQyxJQUFJLEdBQUc7Z0JBQ1YsR0FBRyxJQUFJLENBQUMsSUFBSTtnQkFDWixLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLFlBQVksSUFBSSxPQUFPLEVBQUUsUUFBUSxDQUFDO2dCQUNyRCxZQUFZLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxZQUFZLElBQUksT0FBTyxFQUFFLFFBQVEsQ0FBQzthQUM1RCxDQUFDO1lBQ0YsS0FBSyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUMxQixDQUFDLENBQUMsQ0FBQztRQUVMLElBQUksQ0FBQyxRQUFRO2FBQ1YsYUFBYSxFQUFFO2FBQ2YsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO2FBQ3RCLFNBQVMsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1lBQ2xCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1lBQ2pCLEtBQUssSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDMUIsQ0FBQyxDQUFDLENBQUM7UUFFTCxtRkFBbUY7UUFDbkYseUJBQXlCO1FBQ3pCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsc0JBQXNCLEVBQUUsRUFBRSxDQUFDO1FBQzNELFNBQVMsRUFBRSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUNoRCxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUNuQixJQUFJLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQztRQUNwQixDQUFDLENBQUMsQ0FDSCxDQUFDO1FBQ0YsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsRUFBRSxFQUFFLENBQUM7UUFDdkQsT0FBTyxFQUFFLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQzlDLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ25CLElBQUksQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDO1FBQ3RCLENBQUMsQ0FBQyxDQUNILENBQUM7UUFDRixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGdCQUFnQixFQUFFLEVBQUUsQ0FBQztRQUNwRCxRQUFRLEVBQUUsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FDL0MsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDbkIsSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLENBQUM7UUFDeEIsQ0FBQyxDQUFDLENBQ0gsQ0FBQztRQUVGLElBQUksQ0FBQyxRQUFRO2FBQ1YsYUFBYSxFQUFFO2FBQ2YsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO2FBQ3RCLFNBQVMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFO1lBQ3ZCLElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO1lBQzNCLElBQUksU0FBUyxDQUFDLEtBQUssS0FBSyxDQUFDO2dCQUFFLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7WUFDeEQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUMxQixDQUFDLENBQUMsQ0FBQztRQUVMLDhEQUE4RDtRQUM5RCxhQUFhLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQzthQUNoRSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7YUFDdEIsU0FBUyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLEVBQUUsRUFBRTtZQUNqQyxJQUFJLENBQUMsUUFBUSxHQUFJLFFBQXlCLElBQUksSUFBSSxDQUFDO1lBQ25ELElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQztZQUN6QixLQUFLLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUN6QixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRCw4RUFBOEU7SUFDdEUsVUFBVSxDQUFDLEVBQWM7UUFDL0IsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFO1lBQ2pCLEVBQUUsRUFBRSxDQUFDO1lBQ0wsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUMxQixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFUyxlQUFlLENBQUMsS0FBYztRQUN0QyxJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztRQUNyQixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNqQyxDQUFDO0lBRUQsMkVBQTJFO0lBRTNFLDBGQUEwRjtJQUMxRixZQUFZLENBQUMsS0FBYTtRQUN4QixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRCx1RUFBdUU7SUFDdkUsY0FBYztRQUNaLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUNqQyxDQUFDO0lBRUQsMkVBQTJFO0lBRTNFLHVFQUF1RTtJQUM3RCxpQkFBaUI7UUFDekIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRSxpQkFBaUIsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUN0RCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO1FBQzdCLElBQUksQ0FBQyxlQUFlLEdBQUcsS0FBSyxLQUFLLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQ7dURBQ21EO0lBQ3pDLEtBQUssQ0FBQyxjQUFjLENBQUMsS0FBYTtRQUMxQyxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztRQUM3QixJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsSUFBSSxFQUFFLEVBQUUsSUFBSSxLQUFLLFFBQVE7WUFBRSxPQUFPO1FBQ3BELElBQUksSUFBSSxDQUFDLGdCQUFnQixLQUFLLEtBQUssRUFBRSxDQUFDO1lBQ3BDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN0QixPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksQ0FBQztZQUNILE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNuRCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsS0FBSyxDQUFDO1lBQzlCLElBQUksQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDO1FBQy9CLENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO1FBQy9CLENBQUM7UUFDRCxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQzFCLENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNPLFlBQVk7UUFDcEIsSUFBSSxDQUFDLFVBQVUsR0FBRyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUM7UUFDbkMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVO1lBQUUsT0FBTztRQUM3QixVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ2QsUUFBUSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsY0FBYyxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUNuRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDUixDQUFDO0lBRVMsY0FBYztRQUN0QixJQUFJLENBQUMsUUFBUSxFQUFFLGNBQWMsRUFBRSxDQUFDO1FBQ2hDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFDN0IsSUFBSSxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUM7SUFDL0IsQ0FBQztJQUVELHdFQUF3RTtJQUN4RSxJQUFjLFlBQVk7UUFDeEIsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUM7SUFDbEMsQ0FBQztJQUVELDJFQUEyRTtJQUUzRSwyRUFBMkU7SUFDM0UsSUFBYyxRQUFRO1FBQ3BCLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxZQUFZLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNsRSxDQUFDO0lBRUQsNkRBQTZEO0lBQzdELElBQWMsY0FBYztRQUMxQixPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLGVBQWUsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUM7SUFDcEUsQ0FBQztJQUVTLFdBQVcsQ0FBQyxFQUFXO1FBQy9CLElBQUksQ0FBQyxRQUFRLEVBQUUsWUFBWSxDQUFDLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDakQsQ0FBQztJQUVTLGlCQUFpQixDQUFDLEVBQVc7UUFDckMsSUFBSSxDQUFDLFFBQVEsRUFBRSxZQUFZLENBQUMsRUFBRSxlQUFlLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBV1MsYUFBYSxDQUFDLElBQTRDO1FBQ2xFLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxxRUFBcUU7SUFDM0QsT0FBTyxDQUFDLElBQTRDLEVBQUUsRUFBVztRQUN6RSxJQUFJLENBQUMsSUFBSSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUM7SUFDM0MsQ0FBQztJQVdTLEtBQUs7UUFDYixJQUFJLENBQUMsUUFBUSxFQUFFLFlBQVksQ0FBQyxFQUFFLEdBQUcsb0JBQW9CLEVBQUUsQ0FBQyxDQUFDO1FBQ3pELElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBRUQscUVBQXFFO0lBQ3JFLElBQWMsWUFBWTtRQUN4QixPQUFPLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVELCtFQUErRTtJQUMvRSxJQUFJLGFBQWE7UUFDZixPQUFPLElBQUksQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDO0lBQzlCLENBQUM7SUFFRCwrREFBK0Q7SUFDL0QsSUFBSSxZQUFZO1FBQ2QsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxJQUFJLENBQUM7SUFDckQsQ0FBQztJQUVELDJFQUEyRTtJQUUzRSxrRUFBa0U7SUFDMUQsVUFBVTtRQUNoQixPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQy9GLENBQUM7OEdBclVVLHdCQUF3QixrQkFpR3pCLFVBQVU7a0dBakdULHdCQUF3QiwrTUFFeEIsc0JBQXNCLGdEQ25GbkMsaStNQXFLQSx5akxEbkdJLFlBQVksMExBQ1osV0FBVyw4VkFDWCxZQUFZLDZYQUNaLGNBQWMsZ1pBQ2QsWUFBWSx1dUJBQ1osYUFBYSxzWEFDYiwwQkFBMEIsa0tBQzFCLGdDQUFnQyxzTkFDaEMsaUNBQWlDLGtRQUNqQyxzQkFBc0I7OzJGQU1iLHdCQUF3QjtrQkFuQnBDLFNBQVM7K0JBQ0Usa0JBQWtCLGNBQ2hCLElBQUksV0FDUDt3QkFDUCxZQUFZO3dCQUNaLFdBQVc7d0JBQ1gsWUFBWTt3QkFDWixjQUFjO3dCQUNkLFlBQVk7d0JBQ1osYUFBYTt3QkFDYiwwQkFBMEI7d0JBQzFCLGdDQUFnQzt3QkFDaEMsaUNBQWlDO3dCQUNqQyxzQkFBc0I7cUJBQ3ZCLG1CQUdnQix1QkFBdUIsQ0FBQyxNQUFNOzswQkFtRzVDLE1BQU07MkJBQUMsVUFBVTs4REEvRnVCLE1BQU07c0JBQWhELFNBQVM7dUJBQUMsc0JBQXNCO2dCQWdCeEIsT0FBTztzQkFBZixLQUFLO2dCQUlHLElBQUk7c0JBQVosS0FBSztnQkFFSSxhQUFhO3NCQUF0QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIERlc3Ryb3lSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgVmlld0NoaWxkLFxuICBpbmplY3QsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQnV0dG9uTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9idXR0b24nO1xuaW1wb3J0IHsgQ2hlY2tib3hNb2R1bGUgfSBmcm9tICdwcmltZW5nL2NoZWNrYm94JztcbmltcG9ydCB7IERpYWxvZ01vZHVsZSB9IGZyb20gJ3ByaW1lbmcvZGlhbG9nJztcbmltcG9ydCB7IFRvb2x0aXBNb2R1bGUgfSBmcm9tICdwcmltZW5nL3Rvb2x0aXAnO1xuaW1wb3J0IHsgY29tYmluZUxhdGVzdCB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBWSVNVQUxJWkVSLCBJVmlzdWFsaXplciwgSVNwYXRpYWxDb250cm9scyB9IGZyb20gJy4uL2NvbnRyYWN0cy92aXN1YWxpemVyLmNvbnRyYWN0JztcbmltcG9ydCB7IFNwYXRpYWxDaGFydHNDb21wb25lbnQgfSBmcm9tICcuL3NwYXRpYWwtY2hhcnRzL3NwYXRpYWwtY2hhcnRzLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTcGF0aWFsRGF0YXNldCB9IGZyb20gJy4uL2NvbnRyYWN0cy9zcGF0aWFsLWRhdGFzZXQuY29udHJhY3QnO1xuaW1wb3J0IHsgQ29sb3JtYXBOb2RlLCBTcGF0aWFsVmlld1N0YXRlLCBERUZBVUxUX1NQQVRJQUxfVklFVyB9IGZyb20gJy4uL2NvbnRyYWN0cy9kaXNwbGF5LXR5cGVzJztcbmltcG9ydCB7IFBhbmVsT3B0aW9uLCBwYXJzZUdlbmVHcm91cHMgfSBmcm9tICcuLi9zcGF0aWFsL3NwYXRpYWwtcGFuZWwtbW9kZWwnO1xuaW1wb3J0IHsgU3BhdGlhbFNlbGVjdGlvbk1hc2ssIGVtcHR5U2VsZWN0aW9uIH0gZnJvbSAnLi4vc3BhdGlhbC9zcGF0aWFsLXNlbGVjdGlvbic7XG5pbXBvcnQgeyBHZW5lUGlja2VyTW9kZWwgfSBmcm9tICcuL3NwYXRpYWwtZ2VuZS1waWNrZXInO1xuaW1wb3J0IHsgU3BhdGlhbEtleU1vZGVsLCBTcGF0aWFsTGVnZW5kRW50cnkgfSBmcm9tICcuL3NwYXRpYWwta2V5L3NwYXRpYWwta2V5Lm1vZGVsJztcbmltcG9ydCB7IGNvbG9yQnlMYWJlbCB9IGZyb20gJy4vc3BhdGlhbC1rZXkvc3BhdGlhbC1rZXkuY29tcG9uZW50JztcbmltcG9ydCB7IFNwYXRpYWxDZWxsc1BhbmVsQ29tcG9uZW50IH0gZnJvbSAnLi9zcGF0aWFsLWNlbGxzLXBhbmVsL3NwYXRpYWwtY2VsbHMtcGFuZWwuY29tcG9uZW50JztcbmltcG9ydCB7IFNwYXRpYWxUcmFuc2NyaXB0c1BhbmVsQ29tcG9uZW50IH0gZnJvbSAnLi9zcGF0aWFsLXRyYW5zY3JpcHRzLXBhbmVsL3NwYXRpYWwtdHJhbnNjcmlwdHMtcGFuZWwuY29tcG9uZW50JztcbmltcG9ydCB7IFNwYXRpYWxPYnNlcnZhdGlvbnNQYW5lbENvbXBvbmVudCB9IGZyb20gJy4vc3BhdGlhbC1vYnNlcnZhdGlvbnMtcGFuZWwvc3BhdGlhbC1vYnNlcnZhdGlvbnMtcGFuZWwuY29tcG9uZW50JztcblxuLyoqIEBkZXByZWNhdGVkIE1vdmVkIHRvIGBzcGF0aWFsLWtleS9zcGF0aWFsLWtleS5tb2RlbGA7IHJlLWV4cG9ydGVkIGZvciBvbmUgcmVsZWFzZS4gKi9cbmV4cG9ydCB0eXBlIHsgU3BhdGlhbExlZ2VuZEVudHJ5IH07XG5cbi8qKiBAZGVwcmVjYXRlZCBNb3ZlZCB0byBgc3BhdGlhbC9zcGF0aWFsLXBhbmVsLW1vZGVsYDsgcmUtZXhwb3J0ZWQgZm9yIG9uZSByZWxlYXNlLiAqL1xuZXhwb3J0IHsgcGFyc2VHZW5lR3JvdXBzIH07XG5cbi8qKiBQZXItaW5zdGFuY2UgaWQgc291cmNlIOKAlCBzZWUge0BsaW5rIFNwYXRpYWxDb250cm9sc0NvbXBvbmVudC5jaGFydHNCb2R5SWR9LiAqL1xubGV0IGNvbnRyb2xzSW5zdGFuY2VTZXEgPSAwO1xuXG4vKipcbiAqIFNwYXRpYWwtb21pY3MgY29udHJvbHM6IGEgbm9uLW1vZGFsLCByZXNpemFibGUsIGRyYWdnYWJsZSBkaWFsb2cgZm9yIGNob29zaW5nXG4gKiB3aGF0IHRoZSBvYnNlcnZhdGlvbiBtYXJrZXJzIGFyZSBjb2xvdXJlZCBieSwgYW5kIGhvdyB0aGV5IGFyZSBkcmF3bi5cbiAqXG4gKiBEZXBlbmRzIG9ubHkgb24ge0BsaW5rIElTcGF0aWFsQ29udHJvbHN9LCByZWFjaGVkIHRocm91Z2ggdGhlIGBWSVNVQUxJWkVSYFxuICogY29udHJhY3QgdG9rZW4g4oCUIG5ldmVyIGEgY29uY3JldGUgYmFja2VuZCDigJQgbWlycm9yaW5nIGhvd1xuICogYENoYW5uZWxIaXN0b2dyYW1Db21wb25lbnRgIGRlcGVuZHMgb25seSBvbiBgQ0hBTk5FTF9ISVNUT0dSQU1fQVBJYC4gV2hlbiBub1xuICogaG9zdCBoYXMgYm91bmQgYFNQQVRJQUxfREFUQV9QT1JUYCwgYGdldFNwYXRpYWxDb250cm9scygpYCByZXR1cm5zIG51bGwgYW5kXG4gKiB0aGUgZGlhbG9nIHJlbmRlcnMgYW4gZXhwbGFuYXRvcnkgZW1wdHkgc3RhdGUgcmF0aGVyIHRoYW4gZGVhZCBjb250cm9scy5cbiAqXG4gKiBUaGUgbGVnZW5kIHN3YXRjaGVzIGFuZCB0aGUgY29udGludW91cyBjb2xvdXIgYmFyIGFyZSBidWlsdCB3aXRoIHRoZSBTQU1FXG4gKiBmdW5jdGlvbnMgdGhlIHJlbmRlcmVyIHVzZXMgKGBjYXRlZ29yeUNvbG9yc2Ag4oaSIGByZXNvbHZlQ2F0ZWdvcnlDb2xvcnNgLFxuICogYHNwYXRpYWxDb250aW51b3VzTHV0YCksIHNvIHRoZSBrZXkgY2Fubm90IGRyaWZ0IGZyb20gd2hhdCBpcyBvbiBzY3JlZW4uXG4gKlxuICogT25QdXNoOiB0aGUgY29udHJvbHMnIHN0cmVhbXMsIHRoZSBrZXkgYW5kIGdlbmUtbGlzdCBtb2RlbHMgKHdoaWNoIHJlLWVudGVyIHRoZSB6b25lXG4gKiB3aGVuIHRoZWlyIGFzeW5jIHdvcmsgbGFuZHMpIGFuZCBhbiBhd2FpdGVkIGNhdGVnb3J5IHNlbGVjdGlvbiBtYXJrIGl0IGZvciBjaGVjay5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnc3BhdGlhbC1jb250cm9scycsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGUsXG4gICAgRm9ybXNNb2R1bGUsXG4gICAgQnV0dG9uTW9kdWxlLFxuICAgIENoZWNrYm94TW9kdWxlLFxuICAgIERpYWxvZ01vZHVsZSxcbiAgICBUb29sdGlwTW9kdWxlLFxuICAgIFNwYXRpYWxDZWxsc1BhbmVsQ29tcG9uZW50LFxuICAgIFNwYXRpYWxUcmFuc2NyaXB0c1BhbmVsQ29tcG9uZW50LFxuICAgIFNwYXRpYWxPYnNlcnZhdGlvbnNQYW5lbENvbXBvbmVudCxcbiAgICBTcGF0aWFsQ2hhcnRzQ29tcG9uZW50LFxuICBdLFxuICB0ZW1wbGF0ZVVybDogJy4vc3BhdGlhbC1jb250cm9scy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3NwYXRpYWwtY29udHJvbHMuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIFNwYXRpYWxDb250cm9sc0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIC8qKiBUaGUgZW1iZWRkZWQgY2hhcnQsIHNvIGEgZGlhbG9nIHJlc2l6ZSBjYW4gcmUtZml0IGl0LiAqL1xuICBAVmlld0NoaWxkKFNwYXRpYWxDaGFydHNDb21wb25lbnQpIHByaXZhdGUgY2hhcnRzPzogU3BhdGlhbENoYXJ0c0NvbXBvbmVudDtcblxuICAvKipcbiAgICogUmUtZml0IHRoZSBjaGFydCBhZnRlciB0aGUgZGlhbG9nIGlzIHJlc2l6ZWQuXG4gICAqXG4gICAqIFBsb3RseSBkb2VzIG5vdCBmb2xsb3cgYSBjb250YWluZXIgcmVzaXplIG9uIGl0cyBvd24g4oCUIGl0cyBgcmVzcG9uc2l2ZWBcbiAgICogb3B0aW9uIGxpc3RlbnMgZm9yIFdJTkRPVyByZXNpemVzIG9ubHksIHNvIGRyYWdnaW5nIHRoZSBkaWFsb2cncyBoYW5kbGVcbiAgICogcmVhY2hlcyBpdCB0aHJvdWdoIG5vdGhpbmcuIFByaW1lTkcgdGVsbHMgdXMgd2hlbiB0aGUgZHJhZyBlbmRzLCB3aGljaCBpcyBhXG4gICAqIGZhciBtb3JlIGRpcmVjdCBzaWduYWwgdGhhbiB3YXRjaGluZyBib3hlcywgYW5kIGZpcmluZyBvbmNlIG9uIHJlbGVhc2UgbWVhbnNcbiAgICogbm8gcmVsYXlvdXQgY2h1cm4gZHVyaW5nIHRoZSBkcmFnLlxuICAgKi9cbiAgcHJvdGVjdGVkIG9uUmVzaXplRW5kKCk6IHZvaWQge1xuICAgIHRoaXMuY2hhcnRzPy5yZXNpemUoKTtcbiAgfVxuXG4gIC8qKiBEaWFsb2cgdmlzaWJpbGl0eSwgdHdvLXdheSBib3VuZCBzbyBhIHRvb2xiYXIgYnV0dG9uIGNhbiBvcGVuIGl0LiAqL1xuICBASW5wdXQoKSB2aXNpYmxlID0gZmFsc2U7XG4gIC8qKiBTZXQgd2hpbGUgdGhlIDNEIGNsb3VkIGlzIHRoZSBhY3RpdmUgbW9kZS4gQ2hhbmdlcyB3aGF0IHRoZSBST0kgc2VsZWN0aW9uXG4gICAqICBNRUFOUyDigJQgYSBzY3JlZW4tc3BhY2UgbGFzc28gY3V0dGluZyB0aHJvdWdoIHRoZSBjbG91ZCdzIGZ1bGwgZGVwdGggcmF0aGVyXG4gICAqICB0aGFuIGEgc2hhcGUgaW4gdGlzc3VlIGNvb3JkaW5hdGVzIOKAlCBzbyB0aGUgaGludCBiZWxvdyBpdCBzYXlzIHNvLiAqL1xuICBASW5wdXQoKSBpczNkID0gZmFsc2U7XG4gIC8qKiBUaGUgZGlhbG9nIHdhcyBvcGVuZWQgb3IgY2xvc2VkOyB0d28td2F5IHdpdGgge0BsaW5rIHZpc2libGV9LiAqL1xuICBAT3V0cHV0KCkgdmlzaWJsZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcblxuICAvKiogTnVsbCB3aGVuIHRoZSBob3N0IGJvdW5kIG5vIGBTUEFUSUFMX0RBVEFfUE9SVGAuICovXG4gIHByb3RlY3RlZCBjb250cm9sczogSVNwYXRpYWxDb250cm9scyB8IG51bGwgPSBudWxsO1xuICBwcm90ZWN0ZWQgZGF0YXNldDogU3BhdGlhbERhdGFzZXQgfCBudWxsID0gbnVsbDtcbiAgcHJvdGVjdGVkIHZpZXc6IFNwYXRpYWxWaWV3U3RhdGUgPSB7IC4uLkRFRkFVTFRfU1BBVElBTF9WSUVXIH07XG5cbiAgLyoqXG4gICAqIEdlbmUgcGlja2VyOiBhIGZpbHRlcmFibGUgZHJvcGRvd24gcmF0aGVyIHRoYW4gYSBmcmVlLXRleHQgdHlwZWFoZWFkLCBzbyB0aGVcbiAgICogb3B0aW9ucyBhcmUgdmlzaWJsZSBiZWZvcmUgYW55dGhpbmcgaXMgdHlwZWQgYW5kIGVhY2gga2V5c3Ryb2tlIG5hcnJvd3MgYSBsaXN0XG4gICAqIHRoZSB1c2VyIGNhbiBzZWUuIE9uZSBtb2RlbCBmZWVkcyBldmVyeSBnZW5lIGRyb3Bkb3duIG9mIHRoZSBwYW5lbC5cbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSBnZW5lcyA9IG5ldyBHZW5lUGlja2VyTW9kZWwoXG4gICAgKCkgPT4gdGhpcy5jb250cm9scyxcbiAgICAoKSA9PiBbXG4gICAgICAuLi4odGhpcy52aWV3Py50cmFuc2NyaXB0R2VuZXMgPz8gW10pLFxuICAgICAgLi4uKHRoaXMudmlldz8uY29sb3JCeT8ua2luZCA9PT0gJ2ZlYXR1cmUnID8gW3RoaXMudmlldy5jb2xvckJ5Lm5hbWVdIDogW10pLFxuICAgIF0sXG4gICAgKGZuKSA9PiB0aGlzLnJ1bkFuZE1hcmsoZm4pLFxuICApO1xuICAvKiogVGhlIGdlbmUgZHJvcGRvd25zJyBvcHRpb25zLiAqL1xuICBnZXQgZ2VuZU9wdGlvbnMoKTogUGFuZWxPcHRpb248c3RyaW5nPltdIHtcbiAgICByZXR1cm4gdGhpcy5nZW5lcy5vcHRpb25zO1xuICB9XG4gIC8qKiBUcnVlIHdoZW4gdGhlIG9wdGlvbnMgY29tZSBmcm9tIHRoZSBwb3J0IHBlciBrZXlzdHJva2UgcmF0aGVyIHRoYW4gYSByZXNpZGVudCBsaXN0LiAqL1xuICBnZXQgZ2VuZXNBcmVSZW1vdGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZ2VuZXMucmVtb3RlO1xuICB9XG4gIGdldCBnZW5lU2VhcmNoRmFpbGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmdlbmVzLmZhaWxlZDtcbiAgfVxuXG4gIC8qKiBUaGUga2V5IOKAlCBsZWdlbmQgb3IgY29sb3VyIGJhciDigJQgZm9yIHRoZSBhY3RpdmUgY29sb3VyaW5nLiBLZXB0IGhlcmUsIG5vdCBpblxuICAgKiAgYDxzcGF0aWFsLWtleT5gOiB3aGV0aGVyIHRoZSBjb2xvdXJpbmcgaXMgY2F0ZWdvcmljYWwgZGVjaWRlcyB3aGljaCBrbm9icyB0aGUgcmVzdCBvZlxuICAgKiAgdGhlIHBhbmVsIG9mZmVycywgd2hldGhlciBvciBub3QgdGhlIGtleSBpcyBvbiBzY3JlZW4uICovXG4gIHJlYWRvbmx5IGtleSA9IG5ldyBTcGF0aWFsS2V5TW9kZWwoKGZuKSA9PiB0aGlzLnJ1bkFuZE1hcmsoZm4pKTtcbiAgLyoqIENhdGVnb3JpY2FsIGtleSwgb3IgbnVsbCB3aGVuIHRoZSBhY3RpdmUgY29sb3VyaW5nIGlzIGNvbnRpbnVvdXMuICovXG4gIHByb3RlY3RlZCBnZXQgbGVnZW5kKCk6IFNwYXRpYWxMZWdlbmRFbnRyeVtdIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMua2V5LmxlZ2VuZDtcbiAgfVxuICAvKiogQ1NTIGdyYWRpZW50IGZvciBhIGNvbnRpbnVvdXMgY29sb3VyaW5nLCBvciBudWxsIHdoZW4gY2F0ZWdvcmljYWwuICovXG4gIHByb3RlY3RlZCBnZXQgY29sb3JCYXJDc3MoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMua2V5LmNvbG9yQmFyQ3NzO1xuICB9XG5cbiAgLyoqIEN1cnJlbnQgc2VsZWN0aW9uIOKAlCBkcml2ZXMgdGhlIGNvdW50LCB0aGUgQ2xlYXIgYnV0dG9uIGFuZCB0aGUgbXV0aW5nLiAqL1xuICBwcm90ZWN0ZWQgc2VsZWN0aW9uOiBTcGF0aWFsU2VsZWN0aW9uTWFzayA9IGVtcHR5U2VsZWN0aW9uKCk7XG4gIC8qKiBUaGUgbGVnZW5kIHJvdyB3aG9zZSBjYXRlZ29yeSBpcyBjdXJyZW50bHkgc2VsZWN0ZWQsIGZvciBoaWdobGlnaHRpbmcuICovXG4gIHByb3RlY3RlZCBzZWxlY3RlZENhdGVnb3J5OiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqIEFuIFJPSSBzZWxlY3Rpb24gdGhhdCBtYXRjaGVkIG5vdGhpbmcsIHNvIHRoZSBVSSBjYW4gc2F5IHNvIHJhdGhlciB0aGFuXG4gICAqICBsb29raW5nIGxpa2UgdGhlIGJ1dHRvbiBkaWQgbm90aGluZy4gKi9cbiAgcHJvdGVjdGVkIHNlbGVjdGlvbk1pc3NlZCA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBEaXN0cmlidXRpb24gc2VjdGlvbiBpcyBleHBhbmRlZC4gQ29sbGFwc2VkIGJ5IGRlZmF1bHQ6IHRoZVxuICAgKiBwYW5lbCdzIHByaW1hcnkgam9iIGlzIHRoZSBjb2xvdXIgY29udHJvbHMsIGFuZCB0aGUgY2hhcnQgcm91Z2hseSBkb3VibGVzXG4gICAqIGl0cyBoZWlnaHQuXG4gICAqL1xuICBwcm90ZWN0ZWQgY2hhcnRzT3BlbiA9IGZhbHNlO1xuICAvKiogUGVyLWluc3RhbmNlIGlkIGZvciB0aGUgY29sbGFwc2libGUgYm9keSwgc28gYGFyaWEtY29udHJvbHNgIHBvaW50cyBhdCBvbmVcbiAgICogIGVsZW1lbnQgYW5kIGV4cGFuZGluZyB0aGUgc2Vjb25kIHBhbmVsIGNhbm5vdCBzY3JvbGwgdGhlIGZpcnN0IG9uZSdzIGNoYXJ0LiAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgY2hhcnRzQm9keUlkID0gYHNjLWNoYXJ0cy1ib2R5LSR7Kytjb250cm9sc0luc3RhbmNlU2VxfWA7XG5cbiAgLyoqIENvbG9ybWFwIHRyZWUgZm9yIHRoZSBjb250aW51b3VzIGNvbG91ciBzY2FsZSBhbmQgdGhlIGRlbnNpdHkgbWFwOiB0aGUgbGlicmFyeSdzXG4gICAqICBvd24gYENPTE9STUFQX09QVElPTlNgLiAqL1xuICBwcm90ZWN0ZWQgY29sb3JtYXBPcHRpb25zOiBDb2xvcm1hcE5vZGVbXSA9IFtdO1xuXG4gIHByaXZhdGUgY29sb3JtYXA6IENvbG9ybWFwTm9kZSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHJldmVyc2UgPSBmYWxzZTtcbiAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuICBwcml2YXRlIHJlYWRvbmx5IGNkciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChWSVNVQUxJWkVSKSBwcml2YXRlIHJlYWRvbmx5IHZpejogSVZpc3VhbGl6ZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSB6b25lOiBOZ1pvbmUsXG4gICkge31cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRyb2xzID0gdGhpcy52aXouZ2V0U3BhdGlhbENvbnRyb2xzPy4oKSA/PyBudWxsO1xuICAgIHRoaXMuY29sb3JtYXBPcHRpb25zID0gdGhpcy52aXouZ2V0Q29sb3JtYXBPcHRpb25zPy4oKSA/PyBbXTtcbiAgICBpZiAoIXRoaXMuY29udHJvbHMpIHJldHVybjtcblxuICAgIGNvbnN0IHVudGlsRGVzdHJveWVkID0gPFQ+KCkgPT4gdGFrZVVudGlsRGVzdHJveWVkPFQ+KHRoaXMuZGVzdHJveVJlZik7XG4gICAgdGhpcy5jb250cm9sc1xuICAgICAgLmdldERhdGFzZXQkKClcbiAgICAgIC5waXBlKHVudGlsRGVzdHJveWVkKCkpXG4gICAgICAuc3Vic2NyaWJlKChkYXRhc2V0KSA9PiB7XG4gICAgICAgIHRoaXMuZGF0YXNldCA9IGRhdGFzZXQ7XG4gICAgICAgIHRoaXMuZ2VuZXMuc2V0RGF0YXNldChkYXRhc2V0KTtcbiAgICAgICAgLy8gQSBkYXRhc2V0IHdpdGggbm8gY2VsbHMgdG8gb3V0bGluZSBsZWFkcyB3aXRoIGl0cyBvYnNlcnZhdGlvbnMuXG4gICAgICAgIHRoaXMub3BlbiA9IHtcbiAgICAgICAgICAuLi50aGlzLm9wZW4sXG4gICAgICAgICAgY2VsbHM6ICEhKGRhdGFzZXQ/LnBvbHlnb25UaWxlcyB8fCBkYXRhc2V0Py5wb2x5Z29ucyksXG4gICAgICAgICAgb2JzZXJ2YXRpb25zOiAhKGRhdGFzZXQ/LnBvbHlnb25UaWxlcyB8fCBkYXRhc2V0Py5wb2x5Z29ucyksXG4gICAgICAgIH07XG4gICAgICAgIHZvaWQgdGhpcy5yZWZyZXNoS2V5KCk7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSk7XG5cbiAgICB0aGlzLmNvbnRyb2xzXG4gICAgICAuZ2V0Vmlld1N0YXRlJCgpXG4gICAgICAucGlwZSh1bnRpbERlc3Ryb3llZCgpKVxuICAgICAgLnN1YnNjcmliZSgodmlldykgPT4ge1xuICAgICAgICB0aGlzLnZpZXcgPSB2aWV3O1xuICAgICAgICB2b2lkIHRoaXMucmVmcmVzaEtleSgpO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuXG4gICAgLy8gVGhlIHJlbmRlcmVyJ3Mgb3duIHN0cmVhbXMgbWF5IGVtaXQgb3V0c2lkZSB0aGUgem9uZTogcmUtZW50ZXJlZCBoZXJlLCBvbmNlLCBmb3JcbiAgICAvLyBldmVyeSBwYW5lbCB0aGV5IGZlZWQuXG4gICAgY29uc3QgZXN0aW1hdGUkID0gdGhpcy5jb250cm9scy5nZXRUcmFuc2NyaXB0RXN0aW1hdGUkPy4oKTtcbiAgICBlc3RpbWF0ZSQ/LnBpcGUodW50aWxEZXN0cm95ZWQoKSkuc3Vic2NyaWJlKChlKSA9PlxuICAgICAgdGhpcy5ydW5BbmRNYXJrKCgpID0+IHtcbiAgICAgICAgdGhpcy5lc3RpbWF0ZSA9IGU7XG4gICAgICB9KSxcbiAgICApO1xuICAgIGNvbnN0IGNvdW50cyQgPSB0aGlzLmNvbnRyb2xzLmdldEdlbmVDb3VudHNJblZpZXckPy4oKTtcbiAgICBjb3VudHMkPy5waXBlKHVudGlsRGVzdHJveWVkKCkpLnN1YnNjcmliZSgoYykgPT5cbiAgICAgIHRoaXMucnVuQW5kTWFyaygoKSA9PiB7XG4gICAgICAgIHRoaXMuZ2VuZUNvdW50cyA9IGM7XG4gICAgICB9KSxcbiAgICApO1xuICAgIGNvbnN0IGRlbnNpdHkkID0gdGhpcy5jb250cm9scy5nZXREZW5zaXR5U3RhdHMkPy4oKTtcbiAgICBkZW5zaXR5JD8ucGlwZSh1bnRpbERlc3Ryb3llZCgpKS5zdWJzY3JpYmUoKGQpID0+XG4gICAgICB0aGlzLnJ1bkFuZE1hcmsoKCkgPT4ge1xuICAgICAgICB0aGlzLmRlbnNpdHlTdGF0cyA9IGQ7XG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgdGhpcy5jb250cm9sc1xuICAgICAgLmdldFNlbGVjdGlvbiQoKVxuICAgICAgLnBpcGUodW50aWxEZXN0cm95ZWQoKSlcbiAgICAgIC5zdWJzY3JpYmUoKHNlbGVjdGlvbikgPT4ge1xuICAgICAgICB0aGlzLnNlbGVjdGlvbiA9IHNlbGVjdGlvbjtcbiAgICAgICAgaWYgKHNlbGVjdGlvbi5jb3VudCA9PT0gMCkgdGhpcy5zZWxlY3RlZENhdGVnb3J5ID0gbnVsbDtcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICB9KTtcblxuICAgIC8vIFRoZSBjb2xvdXIgYmFyIG11c3QgdXNlIHRoZSBjb2xvcm1hcCB0aGUgcmVuZGVyZXIgaXMgdXNpbmcuXG4gICAgY29tYmluZUxhdGVzdChbdGhpcy52aXouZ2V0Q29sb3JtYXAoKSwgdGhpcy52aXouZ2V0UmV2ZXJzZVNjYWxlKCldKVxuICAgICAgLnBpcGUodW50aWxEZXN0cm95ZWQoKSlcbiAgICAgIC5zdWJzY3JpYmUoKFtjb2xvcm1hcCwgcmV2ZXJzZV0pID0+IHtcbiAgICAgICAgdGhpcy5jb2xvcm1hcCA9IChjb2xvcm1hcCBhcyBDb2xvcm1hcE5vZGUpID8/IG51bGw7XG4gICAgICAgIHRoaXMucmV2ZXJzZSA9ICEhcmV2ZXJzZTtcbiAgICAgICAgdm9pZCB0aGlzLnJlZnJlc2hLZXkoKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqIEFwcGx5IGFuIGFzeW5jIHJlc3VsdCBpbnNpZGUgdGhlIHpvbmUgYW5kIHJlLXJlbmRlciB0aGlzIE9uUHVzaCBkaWFsb2cuICovXG4gIHByaXZhdGUgcnVuQW5kTWFyayhmbjogKCkgPT4gdm9pZCk6IHZvaWQge1xuICAgIHRoaXMuem9uZS5ydW4oKCkgPT4ge1xuICAgICAgZm4oKTtcbiAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIG9uVmlzaWJsZUNoYW5nZSh2YWx1ZTogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMudmlzaWJsZSA9IHZhbHVlO1xuICAgIHRoaXMudmlzaWJsZUNoYW5nZS5lbWl0KHZhbHVlKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCB0aGUgc2hhcmVkIGdlbmUgbGlzdCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKiogQSBrZXlzdHJva2UgaW4gYSBnZW5lIGRyb3Bkb3duJ3MgZmlsdGVyIGJveCDigJQgc2VlIHtAbGluayBHZW5lUGlja2VyTW9kZWwub25GaWx0ZXJ9LiAqL1xuICBvbkdlbmVGaWx0ZXIocXVlcnk6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLmdlbmVzLm9uRmlsdGVyKHF1ZXJ5KTtcbiAgfVxuXG4gIC8qKiBBIGdlbmUgZHJvcGRvd24gb3BlbmVkIOKAlCBzZWUge0BsaW5rIEdlbmVQaWNrZXJNb2RlbC5lbnN1cmVMaXN0fS4gKi9cbiAgZW5zdXJlR2VuZUxpc3QoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuZ2VuZXMuZW5zdXJlTGlzdCgpO1xuICB9XG5cbiAgLy8g4pSA4pSAIHNlbGVjdGlvbiDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKiogU2VsZWN0IGV2ZXJ5IG9ic2VydmF0aW9uIGluc2lkZSB0aGUgZHJhd24gcmVnaW9ucyAodGhlaXIgdW5pb24pLiAqL1xuICBwcm90ZWN0ZWQgc2VsZWN0RnJvbVJlZ2lvbnMoKTogdm9pZCB7XG4gICAgY29uc3QgY291bnQgPSB0aGlzLmNvbnRyb2xzPy5zZWxlY3RGcm9tUmVnaW9ucygpID8/IDA7XG4gICAgdGhpcy5zZWxlY3RlZENhdGVnb3J5ID0gbnVsbDtcbiAgICB0aGlzLnNlbGVjdGlvbk1pc3NlZCA9IGNvdW50ID09PSAwO1xuICB9XG5cbiAgLyoqIExlZ2VuZCBjbGljazogc2VsZWN0IG9uZSBjYXRlZ29yeS4gQ2xpY2tpbmcgdGhlIGFjdGl2ZSByb3cgY2xlYXJzIGl0LCBzbyBhXG4gICAqICBzZWNvbmQgY2xpY2sgaXMgYW4gdW5kbyByYXRoZXIgdGhhbiBhIG5vLW9wLiAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgc2VsZWN0Q2F0ZWdvcnkoaW5kZXg6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGJ5ID0gdGhpcy52aWV3LmNvbG9yQnk7XG4gICAgaWYgKCF0aGlzLmNvbnRyb2xzIHx8IGJ5Py5raW5kICE9PSAnY29sdW1uJykgcmV0dXJuO1xuICAgIGlmICh0aGlzLnNlbGVjdGVkQ2F0ZWdvcnkgPT09IGluZGV4KSB7XG4gICAgICB0aGlzLmNsZWFyU2VsZWN0aW9uKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmNvbnRyb2xzLnNlbGVjdENhdGVnb3J5KGJ5Lm5hbWUsIGluZGV4KTtcbiAgICAgIHRoaXMuc2VsZWN0ZWRDYXRlZ29yeSA9IGluZGV4O1xuICAgICAgdGhpcy5zZWxlY3Rpb25NaXNzZWQgPSBmYWxzZTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRDYXRlZ29yeSA9IG51bGw7XG4gICAgfVxuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cGFuZCBvciBjb2xsYXBzZSB0aGUgZGlzdHJpYnV0aW9uIHNlY3Rpb24uXG4gICAqXG4gICAqIEV4cGFuZGluZyBTQ1JPTExTIGl0IGludG8gdmlldywgYmVjYXVzZSB0aGUgcGFuZWwgaXMgdGFsbGVyIHRoYW4gdGhlIHZpZXdwb3J0XG4gICAqIG9uY2UgdGhpcyBzZWN0aW9uIGlzIG9wZW4gYW5kIHRoZSBjaGFydCBpcyBpdHMgbGFzdCByb3c6IGV4cGFuZGluZyBpdCBkcmV3IGFcbiAgICogY2hhcnQgfjMwMCBweCBiZWxvdyB0aGUgZm9sZCwgd2hpY2ggcmVhZHMgYXMgdGhlIHNlY3Rpb24gYmVpbmcgZW1wdHkuIFRoZVxuICAgKiBzY3JvbGwgaXMgZGVmZXJyZWQgYSB0YXNrIHNvIHRoZSBjaGFydCdzIG93biBkZWZlcnJlZCBmaXJzdCBkcmF3IGhhcyBnaXZlbiB0aGVcbiAgICogYm9keSBpdHMgaGVpZ2h0LlxuICAgKi9cbiAgcHJvdGVjdGVkIHRvZ2dsZUNoYXJ0cygpOiB2b2lkIHtcbiAgICB0aGlzLmNoYXJ0c09wZW4gPSAhdGhpcy5jaGFydHNPcGVuO1xuICAgIGlmICghdGhpcy5jaGFydHNPcGVuKSByZXR1cm47XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLmNoYXJ0c0JvZHlJZCk/LnNjcm9sbEludG9WaWV3KHsgYmxvY2s6ICdlbmQnLCBiZWhhdmlvcjogJ3Ntb290aCcgfSk7XG4gICAgfSwgMCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY2xlYXJTZWxlY3Rpb24oKTogdm9pZCB7XG4gICAgdGhpcy5jb250cm9scz8uY2xlYXJTZWxlY3Rpb24oKTtcbiAgICB0aGlzLnNlbGVjdGVkQ2F0ZWdvcnkgPSBudWxsO1xuICAgIHRoaXMuc2VsZWN0aW9uTWlzc2VkID0gZmFsc2U7XG4gIH1cblxuICAvKiogVHJ1ZSB3aGlsZSBhIHNlbGVjdGlvbiBpcyBhY3RpdmUg4oCUIGV2ZXJ5dGhpbmcgZWxzZSByZW5kZXJzIG11dGVkLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGhhc1NlbGVjdGlvbigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3Rpb24uY291bnQgPiAwO1xuICB9XG5cbiAgLy8g4pSA4pSAIHNlY3Rpb25zIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKiBCb3VuZGFyaWVzIG9uIG9mZmVyOiB0aWxlZCAobGV2ZWwtb2YtZGV0YWlsKSBvciB3aG9sZS1kYXRhc2V0IHJpbmdzLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGhhc0NlbGxzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhISh0aGlzLmRhdGFzZXQ/LnBvbHlnb25UaWxlcyB8fCB0aGlzLmRhdGFzZXQ/LnBvbHlnb25zKTtcbiAgfVxuXG4gIC8qKiBUcmFuc2NyaXB0cyBvbiBvZmZlcjogdGlsZXMgdG8gZHJhdywgb3IgYSBkZW5zaXR5IG1hcC4gKi9cbiAgcHJvdGVjdGVkIGdldCBoYXNUcmFuc2NyaXB0cygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmRhdGFzZXQ/LnRyYW5zY3JpcHRUaWxlcyB8fCAhIXRoaXMuZGF0YXNldD8uZGVuc2l0eTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvblNob3dJbWFnZShvbjogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuY29udHJvbHM/LnNldFZpZXdTdGF0ZSh7IHNob3dJbWFnZTogb24gfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb25TaG93QW5ub3RhdGlvbnMob246IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRyb2xzPy5zZXRWaWV3U3RhdGUoeyBzaG93QW5ub3RhdGlvbnM6IG9uIH0pO1xuICB9XG5cbiAgLyoqIFdoaWNoIGNvbGxhcHNpYmxlIHNlY3Rpb25zIGFyZSBvcGVuLiBQZXIgZGlhbG9nIGluc3RhbmNlLCBub3QgcGVyc2lzdGVkLiAqL1xuICBwcm90ZWN0ZWQgb3BlbjogUmVjb3JkPCdpbWFnZXMnIHwgJ2NlbGxzJyB8ICd0cmFuc2NyaXB0cycgfCAnYW5ub3RhdGlvbnMnIHwgJ29ic2VydmF0aW9ucycsIGJvb2xlYW4+ID0ge1xuICAgIGltYWdlczogZmFsc2UsXG4gICAgY2VsbHM6IHRydWUsXG4gICAgdHJhbnNjcmlwdHM6IGZhbHNlLFxuICAgIGFubm90YXRpb25zOiBmYWxzZSxcbiAgICBvYnNlcnZhdGlvbnM6IGZhbHNlLFxuICB9O1xuXG4gIHByb3RlY3RlZCB0b2dnbGVTZWN0aW9uKG5hbWU6IGtleW9mIFNwYXRpYWxDb250cm9sc0NvbXBvbmVudFsnb3BlbiddKTogdm9pZCB7XG4gICAgdGhpcy5zZXRPcGVuKG5hbWUsICF0aGlzLm9wZW5bbmFtZV0pO1xuICB9XG5cbiAgLyoqIEV4cGFuZCBvciBjb2xsYXBzZSBhIHNlY3Rpb24g4oCUIHdoYXQgYSBwYW5lbCdzIGhlYWRlciBhc2tzIGZvci4gKi9cbiAgcHJvdGVjdGVkIHNldE9wZW4obmFtZToga2V5b2YgU3BhdGlhbENvbnRyb2xzQ29tcG9uZW50WydvcGVuJ10sIG9uOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5vcGVuID0geyAuLi50aGlzLm9wZW4sIFtuYW1lXTogb24gfTtcbiAgfVxuXG4gIC8vIOKUgOKUgCByZW5kZXJlciByZWFkb3V0cywgZm9yIHRoZSBUcmFuc2NyaXB0cyBzZWN0aW9uIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKiBFc3RpbWF0ZWQgdHJhbnNjcmlwdHMgaW4gdmlldywgYWdhaW5zdCB0aGUgYnVkZ2V0IOKAlCBFeHBsb3JlcidzIHBvaW50cyBiYXIuICovXG4gIHByb3RlY3RlZCBlc3RpbWF0ZTogeyBwb2ludHM6IG51bWJlcjsgbWF4OiBudW1iZXIgfSB8IG51bGwgPSBudWxsO1xuICAvKiogVGhlIGRlbnNpdHkgd2luZG93IGluIHVzZSBhbmQgaXRzIGRlbnNlc3QgYmluLCBmb3IgdGhlIHRocmVzaG9sZCBjb250cm9sLiAqL1xuICBwcm90ZWN0ZWQgZGVuc2l0eVN0YXRzOiB7IGxvOiBudW1iZXI7IGhpOiBudW1iZXI7IG1heDogbnVtYmVyIH0gfCBudWxsID0gbnVsbDtcbiAgLyoqIFRyYW5zY3JpcHRzIG9mIGVhY2ggc2VsZWN0ZWQgZ2VuZSBpbiB0aGUgY3VycmVudCB2aWV3LCBmcm9tIHRoZSByZW5kZXJlci4gKi9cbiAgcHJvdGVjdGVkIGdlbmVDb3VudHM6IFJlY29yZDxzdHJpbmcsIG51bWJlcj4gfCBudWxsID0gbnVsbDtcblxuICBwcm90ZWN0ZWQgcmVzZXQoKTogdm9pZCB7XG4gICAgdGhpcy5jb250cm9scz8uc2V0Vmlld1N0YXRlKHsgLi4uREVGQVVMVF9TUEFUSUFMX1ZJRVcgfSk7XG4gICAgdGhpcy5jbGVhclNlbGVjdGlvbigpO1xuICB9XG5cbiAgLyoqIExhYmVsIGZvciB0aGUgY3VycmVudCBjb2xvdXJpbmcsIGZvciB0aGUgRGlzdHJpYnV0aW9uIGhlYWRpbmcuICovXG4gIHByb3RlY3RlZCBnZXQgY29sb3JCeUxhYmVsKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGNvbG9yQnlMYWJlbCh0aGlzLnZpZXcpO1xuICB9XG5cbiAgLyoqIFRydWUgd2hlbiB0aGUgYWN0aXZlIGNvbG91cmluZyBpcyBhIGNhdGVnb3JpY2FsIGNvbHVtbiAoZHJpdmVzIHRoZSBrZXkpLiAqL1xuICBnZXQgaXNDYXRlZ29yaWNhbCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5sZWdlbmQgIT09IG51bGw7XG4gIH1cblxuICAvKiogV2hldGhlciBsb2cvY2xpcCBhcHBseSDigJQgdGhleSBhcmUgY29udGludW91cy1vbmx5IGtub2JzLiAqL1xuICBnZXQgaXNDb250aW51b3VzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMudmlldy5jb2xvckJ5ICYmIHRoaXMubGVnZW5kID09PSBudWxsO1xuICB9XG5cbiAgLy8g4pSA4pSAIGludGVybmFscyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKiogUmVidWlsZCB0aGUgbGVnZW5kIG9yIGNvbG91ciBiYXIgZm9yIHRoZSBjdXJyZW50IGNvbG91cmluZy4gKi9cbiAgcHJpdmF0ZSByZWZyZXNoS2V5KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLmtleS5yZWZyZXNoKHRoaXMuY29udHJvbHMsIHRoaXMuZGF0YXNldCwgdGhpcy52aWV3LCB0aGlzLmNvbG9ybWFwLCB0aGlzLnJldmVyc2UpO1xuICB9XG59XG4iLCI8cC1kaWFsb2dcbiAgaGVhZGVyPVwiU3BhdGlhbCBvbWljc1wiXG4gIFt2aXNpYmxlXT1cInZpc2libGVcIlxuICAodmlzaWJsZUNoYW5nZSk9XCJvblZpc2libGVDaGFuZ2UoJGV2ZW50KVwiXG4gIFttb2RhbF09XCJmYWxzZVwiXG4gIFtyZXNpemFibGVdPVwidHJ1ZVwiXG4gIFtkcmFnZ2FibGVdPVwidHJ1ZVwiXG4gIHBvc2l0aW9uPVwibGVmdFwiXG4gIChvblJlc2l6ZUVuZCk9XCJvblJlc2l6ZUVuZCgpXCJcbiAgW3N0eWxlXT1cInsgd2lkdGg6ICczMHJlbScgfVwiXG4gIFticmVha3BvaW50c109XCJ7ICc5NjBweCc6ICc5MHZ3JyB9XCJcbiAgc3R5bGVDbGFzcz1cInNwYXRpYWwtY29udHJvbHMtZGlhbG9nXCJcbj5cbiAgPCEtLSBObyBwb3J0IGJvdW5kOiBzYXkgd2h5IHJhdGhlciB0aGFuIHNob3dpbmcgY29udHJvbHMgdGhhdCBkbyBub3RoaW5nLiAtLT5cbiAgPGRpdiBjbGFzcz1cInNjLWVtcHR5XCIgKm5nSWY9XCIhY29udHJvbHNcIj5cbiAgICBObyBzcGF0aWFsLW9taWNzIGRhdGEgc291cmNlIGlzIGNvbmZpZ3VyZWQuIEEgaG9zdCBwcm92aWRlcyBvbmUgYnkgYmluZGluZ1xuICAgIDxjb2RlPlNQQVRJQUxfREFUQV9QT1JUPC9jb2RlPi5cbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cInNjLWVtcHR5XCIgKm5nSWY9XCJjb250cm9scyAmJiAhZGF0YXNldFwiPk5vIGRhdGFzZXQgaXMgbG9hZGVkLjwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJzYy1ib2R5XCIgKm5nSWY9XCJjb250cm9scyAmJiBkYXRhc2V0IGFzIGRzXCI+XG4gICAgPGRpdiBjbGFzcz1cInNjLWRhdGFzZXRcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwic2MtZGF0YXNldC1uYW1lXCI+e3sgZHMubmFtZSB9fTwvc3Bhbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwic2MtZGF0YXNldC1jb3VudFwiPnt7IGRzLm9ic2VydmF0aW9ucy5jb3VudCB8IG51bWJlciB9fSBvYnNlcnZhdGlvbnM8L3NwYW4+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIE9yZ2FuaXNlZCBhcyBYZW5pdW0gRXhwbG9yZXIncyBzaWRlIHBhbmVsOiBvbmUgY29sbGFwc2libGUgc2VjdGlvbiBwZXIgbGF5ZXIsXG4gICAgICAgICBlYWNoIHdpdGggaXRzIG93biBvbi9vZmYgc3dpdGNoIGluIHRoZSBoZWFkZXIuIC0tPlxuXG4gICAgPCEtLSBJbWFnZXMgLS0+XG4gICAgPGRpdiBjbGFzcz1cInNjLXBhbmVsXCIgKm5nSWY9XCJkcy5pbWFnZVJlZiAmJiAhaXMzZFwiIFtjbGFzcy5vcGVuXT1cIm9wZW4uaW1hZ2VzXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwic2MtcGFuZWwtaGVhZFwiIChjbGljayk9XCJ0b2dnbGVTZWN0aW9uKCdpbWFnZXMnKVwiPlxuICAgICAgICA8cC1jaGVja2JveFxuICAgICAgICAgIFtiaW5hcnldPVwidHJ1ZVwiXG4gICAgICAgICAgW25nTW9kZWxdPVwidmlldy5zaG93SW1hZ2VcIlxuICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgICAgIChvbkNoYW5nZSk9XCJvblNob3dJbWFnZSgkZXZlbnQuY2hlY2tlZClcIlxuICAgICAgICA+PC9wLWNoZWNrYm94PlxuICAgICAgICA8c3BhbiBjbGFzcz1cInNjLXBhbmVsLXRpdGxlXCI+SW1hZ2VzPC9zcGFuPlxuICAgICAgICA8aSBjbGFzcz1cInBpXCIgW2NsYXNzLnBpLWNoZXZyb24tZG93bl09XCJvcGVuLmltYWdlc1wiIFtjbGFzcy5waS1jaGV2cm9uLXJpZ2h0XT1cIiFvcGVuLmltYWdlc1wiPjwvaT5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cInNjLXBhbmVsLWJvZHlcIiAqbmdJZj1cIm9wZW4uaW1hZ2VzXCI+XG4gICAgICAgIDxzbWFsbCBjbGFzcz1cInNjLWhpbnRcIj4gQ2hhbm5lbHMsIGNvbG91cnMgYW5kIGNvbnRyYXN0IGFyZSBpbiB0aGUgQ2hhbm5lbHMgJmFtcDsgSGlzdG9ncmFtIGRpYWxvZy4gPC9zbWFsbD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBDZWxscyAtLT5cbiAgICA8c3BhdGlhbC1jZWxscy1wYW5lbFxuICAgICAgKm5nSWY9XCJoYXNDZWxscyAmJiAhaXMzZFwiXG4gICAgICBbY29udHJvbHNdPVwiY29udHJvbHNcIlxuICAgICAgW2RhdGFzZXRdPVwiZHNcIlxuICAgICAgW3ZpZXddPVwidmlld1wiXG4gICAgICBbZ2VuZXNdPVwiZ2VuZXNcIlxuICAgICAgW2NvbG9yQmFyQ3NzXT1cImNvbG9yQmFyQ3NzXCJcbiAgICAgIFtvcGVuXT1cIm9wZW4uY2VsbHNcIlxuICAgICAgKG9wZW5DaGFuZ2UpPVwic2V0T3BlbignY2VsbHMnLCAkZXZlbnQpXCJcbiAgICA+PC9zcGF0aWFsLWNlbGxzLXBhbmVsPlxuXG4gICAgPCEtLSBUcmFuc2NyaXB0cyAtLT5cbiAgICA8c3BhdGlhbC10cmFuc2NyaXB0cy1wYW5lbFxuICAgICAgKm5nSWY9XCJoYXNUcmFuc2NyaXB0cyAmJiAhaXMzZFwiXG4gICAgICBbY29udHJvbHNdPVwiY29udHJvbHNcIlxuICAgICAgW2RhdGFzZXRdPVwiZHNcIlxuICAgICAgW3ZpZXddPVwidmlld1wiXG4gICAgICBbZ2VuZXNdPVwiZ2VuZXNcIlxuICAgICAgW2VzdGltYXRlXT1cImVzdGltYXRlXCJcbiAgICAgIFtkZW5zaXR5U3RhdHNdPVwiZGVuc2l0eVN0YXRzXCJcbiAgICAgIFtnZW5lQ291bnRzXT1cImdlbmVDb3VudHNcIlxuICAgICAgW2NvbG9ybWFwT3B0aW9uc109XCJjb2xvcm1hcE9wdGlvbnNcIlxuICAgICAgW29wZW5dPVwib3Blbi50cmFuc2NyaXB0c1wiXG4gICAgICAob3BlbkNoYW5nZSk9XCJzZXRPcGVuKCd0cmFuc2NyaXB0cycsICRldmVudClcIlxuICAgID5cbiAgICA8L3NwYXRpYWwtdHJhbnNjcmlwdHMtcGFuZWw+XG5cbiAgICA8IS0tIEFubm90YXRpb25zOiB0aGUgZHJhd24gcmVnaW9ucywgYW5kIHNlbGVjdGluZyB3aGF0IHRoZXkgZW5jbG9zZS4gLS0+XG4gICAgPGRpdiBjbGFzcz1cInNjLXBhbmVsXCIgW2NsYXNzLm9wZW5dPVwib3Blbi5hbm5vdGF0aW9uc1wiPlxuICAgICAgPGRpdiBjbGFzcz1cInNjLXBhbmVsLWhlYWRcIiAoY2xpY2spPVwidG9nZ2xlU2VjdGlvbignYW5ub3RhdGlvbnMnKVwiPlxuICAgICAgICA8cC1jaGVja2JveFxuICAgICAgICAgIFtiaW5hcnldPVwidHJ1ZVwiXG4gICAgICAgICAgW25nTW9kZWxdPVwidmlldy5zaG93QW5ub3RhdGlvbnMgIT09IGZhbHNlXCJcbiAgICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAgICAob25DaGFuZ2UpPVwib25TaG93QW5ub3RhdGlvbnMoJGV2ZW50LmNoZWNrZWQpXCJcbiAgICAgICAgICBwVG9vbHRpcD1cIlNob3cgdGhlIGRyYXduIHJlZ2lvbnNcIlxuICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cInRvcFwiXG4gICAgICAgID48L3AtY2hlY2tib3g+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwic2MtcGFuZWwtdGl0bGVcIj5Bbm5vdGF0aW9uczwvc3Bhbj5cbiAgICAgICAgPGkgY2xhc3M9XCJwaVwiIFtjbGFzcy5waS1jaGV2cm9uLWRvd25dPVwib3Blbi5hbm5vdGF0aW9uc1wiIFtjbGFzcy5waS1jaGV2cm9uLXJpZ2h0XT1cIiFvcGVuLmFubm90YXRpb25zXCI+PC9pPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwic2MtcGFuZWwtYm9keVwiICpuZ0lmPVwib3Blbi5hbm5vdGF0aW9uc1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2Mtcm93XCI+XG4gICAgICAgICAgPHAtYnV0dG9uXG4gICAgICAgICAgICBsYWJlbD1cIlNlbGVjdCBmcm9tIFJPSXNcIlxuICAgICAgICAgICAgaWNvbj1cInBpIHBpLW9iamVjdC1ncm91cFwiXG4gICAgICAgICAgICBzaXplPVwic21hbGxcIlxuICAgICAgICAgICAgW291dGxpbmVkXT1cInRydWVcIlxuICAgICAgICAgICAgKG9uQ2xpY2spPVwic2VsZWN0RnJvbVJlZ2lvbnMoKVwiXG4gICAgICAgICAgICBwVG9vbHRpcD1cIlNlbGVjdCBldmVyeSBvYnNlcnZhdGlvbiBpbnNpZGUgdGhlIGRyYXduIHJlZ2lvbnNcIlxuICAgICAgICAgICAgdG9vbHRpcFBvc2l0aW9uPVwidG9wXCJcbiAgICAgICAgICA+PC9wLWJ1dHRvbj5cbiAgICAgICAgICA8cC1idXR0b25cbiAgICAgICAgICAgICpuZ0lmPVwiaGFzU2VsZWN0aW9uXCJcbiAgICAgICAgICAgIGxhYmVsPVwiQ2xlYXJcIlxuICAgICAgICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgICAgICAgIFt0ZXh0XT1cInRydWVcIlxuICAgICAgICAgICAgKG9uQ2xpY2spPVwiY2xlYXJTZWxlY3Rpb24oKVwiXG4gICAgICAgICAgPjwvcC1idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8c21hbGwgY2xhc3M9XCJzYy1oaW50XCIgKm5nSWY9XCJoYXNTZWxlY3Rpb25cIj5cbiAgICAgICAgICB7eyBzZWxlY3Rpb24uY291bnQgfCBudW1iZXIgfX0gb2Yge3sgZHMub2JzZXJ2YXRpb25zLmNvdW50IHwgbnVtYmVyIH19IHNlbGVjdGVkIOKAlCB0aGUgcmVzdCBhcmUgbXV0ZWQuXG4gICAgICAgIDwvc21hbGw+XG4gICAgICAgIDxzbWFsbCBjbGFzcz1cInNjLWhpbnRcIiAqbmdJZj1cInNlbGVjdGlvbk1pc3NlZFwiPiBObyBvYnNlcnZhdGlvbnMgZmVsbCBpbnNpZGUgdGhlIGRyYXduIHJlZ2lvbnMuIDwvc21hbGw+XG4gICAgICAgIDxzbWFsbCBjbGFzcz1cInNjLWhpbnRcIiAqbmdJZj1cImlzM2RcIj5cbiAgICAgICAgICBJbiAzRCBhIHJlZ2lvbiBjdXRzIHRocm91Z2ggdGhlIGNsb3VkJ3MgZnVsbCBkZXB0aC4gT3JiaXQgYW5kIGRyYXcgYWdhaW4gdG8gY3V0IGZyb20gYW5vdGhlciBhbmdsZS5cbiAgICAgICAgPC9zbWFsbD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBPYnNlcnZhdGlvbnMsIHRoZW4gd2hhdCBlbHNlIGRyYXdzIHRoZW06IHRoZSBnZW5lIG1hcCwgdGhlIDNEIHNjZW5lLCBhbmQgdGhlXG4gICAgICAgICBjb250aW51b3VzLW9ubHkga25vYnMuIC0tPlxuICAgIDxzcGF0aWFsLW9ic2VydmF0aW9ucy1wYW5lbFxuICAgICAgW2NvbnRyb2xzXT1cImNvbnRyb2xzXCJcbiAgICAgIFtkYXRhc2V0XT1cImRzXCJcbiAgICAgIFt2aWV3XT1cInZpZXdcIlxuICAgICAgW2dlbmVzXT1cImdlbmVzXCJcbiAgICAgIFtsZWdlbmRdPVwibGVnZW5kXCJcbiAgICAgIFtjb2xvckJhckNzc109XCJjb2xvckJhckNzc1wiXG4gICAgICBbc2VsZWN0aW9uXT1cInNlbGVjdGlvblwiXG4gICAgICBbc2VsZWN0ZWRDYXRlZ29yeV09XCJzZWxlY3RlZENhdGVnb3J5XCJcbiAgICAgIFtjb2xvcm1hcE9wdGlvbnNdPVwiY29sb3JtYXBPcHRpb25zXCJcbiAgICAgIFtpczNkXT1cImlzM2RcIlxuICAgICAgW29wZW5dPVwib3Blbi5vYnNlcnZhdGlvbnNcIlxuICAgICAgKG9wZW5DaGFuZ2UpPVwic2V0T3Blbignb2JzZXJ2YXRpb25zJywgJGV2ZW50KVwiXG4gICAgICAoY2F0ZWdvcnlDbGlja2VkKT1cInNlbGVjdENhdGVnb3J5KCRldmVudClcIlxuICAgID48L3NwYXRpYWwtb2JzZXJ2YXRpb25zLXBhbmVsPlxuXG4gICAgPCEtLSBEaXN0cmlidXRpb25zIG9mIHdoYXRldmVyIHRoZSBtYXAgaXMgY29sb3VyZWQgYnkuIEluIHRoZSBTQU1FIGRpYWxvZyBhc1xuICAgICAgICAgdGhlIGNvbG91ciBjb250cm9scyBvbiBwdXJwb3NlOiBjaGFuZ2luZyB0aGUgZ2VuZSBhbmQgd2F0Y2hpbmcgdGhlXG4gICAgICAgICBkaXN0cmlidXRpb24gbW92ZSBpcyBvbmUgYWN0aW9uLCBhbmQgdHdvIGZsb2F0aW5nIHdpbmRvd3MgbWFkZSB0aGF0XG4gICAgICAgICBoYXJkZXIgdG8gc2VlIHJhdGhlciB0aGFuIGVhc2llci4gLS0+XG4gICAgPGRpdiBjbGFzcz1cInNjLXNlY3Rpb24gc2MtY2hhcnRzXCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzcz1cInNjLWRpc2Nsb3N1cmVcIlxuICAgICAgICAoY2xpY2spPVwidG9nZ2xlQ2hhcnRzKClcIlxuICAgICAgICBbYXR0ci5hcmlhLWV4cGFuZGVkXT1cImNoYXJ0c09wZW5cIlxuICAgICAgICBbYXR0ci5hcmlhLWNvbnRyb2xzXT1cImNoYXJ0c0JvZHlJZFwiXG4gICAgICA+XG4gICAgICAgIDxpIGNsYXNzPVwicGlcIiBbY2xhc3MucGktY2hldnJvbi1yaWdodF09XCIhY2hhcnRzT3BlblwiIFtjbGFzcy5waS1jaGV2cm9uLWRvd25dPVwiY2hhcnRzT3BlblwiPjwvaT5cbiAgICAgICAgPHNwYW4+RGlzdHJpYnV0aW9uPC9zcGFuPlxuICAgICAgICA8c21hbGwgKm5nSWY9XCIhY2hhcnRzT3BlbiAmJiB2aWV3LmNvbG9yQnlcIj5vZiB7eyBjb2xvckJ5TGFiZWwgfX08L3NtYWxsPlxuICAgICAgPC9idXR0b24+XG4gICAgICA8IS0tIEtlcHQgTU9VTlRFRCB3aGVuIGNvbGxhcHNlZCwgb25seSBoaWRkZW46IGRlc3Ryb3lpbmcgaXQgd291bGQgdGhyb3dcbiAgICAgICAgICAgYXdheSB0aGUgY2hhcnQga2luZCBhbmQgZ3JvdXBpbmcgdGhlIHVzZXIgcGlja2VkLiBgYWN0aXZlYCBpcyB3aGF0XG4gICAgICAgICAgIHN0b3BzIGl0IGRyYXdpbmcgd2hpbGUgaXQgaGFzIG5vIHNpemUuIC0tPlxuICAgICAgPGRpdiBbaWRdPVwiY2hhcnRzQm9keUlkXCIgW2hpZGRlbl09XCIhY2hhcnRzT3BlblwiPlxuICAgICAgICA8c3BhdGlhbC1jaGFydHMgW2FjdGl2ZV09XCJ2aXNpYmxlICYmIGNoYXJ0c09wZW5cIj48L3NwYXRpYWwtY2hhcnRzPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwic2MtYnRuc1wiPlxuICAgICAgPHAtYnV0dG9uIGxhYmVsPVwiUmVzZXRcIiBzaXplPVwic21hbGxcIiBbdGV4dF09XCJ0cnVlXCIgKG9uQ2xpY2spPVwicmVzZXQoKVwiPjwvcC1idXR0b24+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9wLWRpYWxvZz5cbiJdfQ==
397
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhdGlhbC1jb250cm9scy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3NwYXRpYWwtY29udHJvbHMvc3BhdGlhbC1jb250cm9scy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9zcmMvbGliL3NwYXRpYWwtY29udHJvbHMvc3BhdGlhbC1jb250cm9scy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixNQUFNLEVBQ04sS0FBSyxFQUNMLE1BQU0sRUFFTixNQUFNLEVBQ04sU0FBUyxFQUNULE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXJDLE9BQU8sRUFBRSxVQUFVLEVBQW1ELE1BQU0sa0NBQWtDLENBQUM7QUFDL0csT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sMkNBQTJDLENBQUM7QUFFbkYsT0FBTyxFQUFrQyxvQkFBb0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ2xHLE9BQU8sRUFBZSxlQUFlLEVBQUUsTUFBTSxn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QVU7a0dBdkdULHdCQUF3QiwrTUFFeEIsc0JBQXNCLGdEQ25GbkMsdWxQQXlMQSx5akxEdkhJLFlBQVksMExBQ1osV0FBVyw4VkFDWCxZQUFZLDZYQUNaLGNBQWMsZ1pBQ2QsWUFBWSx1dUJBQ1osYUFBYSxzWEFDYiwwQkFBMEIsa0tBQzFCLGdDQUFnQyxzTkFDaEMsaUNBQWlDLGtRQUNqQyxzQkFBc0I7OzJGQU1iLHdCQUF3QjtrQkFuQnBDLFNBQVM7K0JBQ0Usa0JBQWtCLGNBQ2hCLElBQUksV0FDUDt3QkFDUCxZQUFZO3dCQUNaLFdBQVc7d0JBQ1gsWUFBWTt3QkFDWixjQUFjO3dCQUNkLFlBQVk7d0JBQ1osYUFBYTt3QkFDYiwwQkFBMEI7d0JBQzFCLGdDQUFnQzt3QkFDaEMsaUNBQWlDO3dCQUNqQyxzQkFBc0I7cUJBQ3ZCLG1CQUdnQix1QkFBdUIsQ0FBQyxNQUFNOzswQkF5RzVDLE1BQU07MkJBQUMsVUFBVTs4REFyR3VCLE1BQU07c0JBQWhELFNBQVM7dUJBQUMsc0JBQXNCO2dCQWdCeEIsT0FBTztzQkFBZixLQUFLO2dCQUlHLElBQUk7c0JBQVosS0FBSztnQkFFSSxhQUFhO3NCQUF0QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIERlc3Ryb3lSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgVmlld0NoaWxkLFxuICBpbmplY3QsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQnV0dG9uTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9idXR0b24nO1xuaW1wb3J0IHsgQ2hlY2tib3hNb2R1bGUgfSBmcm9tICdwcmltZW5nL2NoZWNrYm94JztcbmltcG9ydCB7IERpYWxvZ01vZHVsZSB9IGZyb20gJ3ByaW1lbmcvZGlhbG9nJztcbmltcG9ydCB7IFRvb2x0aXBNb2R1bGUgfSBmcm9tICdwcmltZW5nL3Rvb2x0aXAnO1xuaW1wb3J0IHsgY29tYmluZUxhdGVzdCB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBWSVNVQUxJWkVSLCBJVmlzdWFsaXplciwgSVNwYXRpYWxDb250cm9scywgUm9pU2VsZWN0aW9uTW9kZSB9IGZyb20gJy4uL2NvbnRyYWN0cy92aXN1YWxpemVyLmNvbnRyYWN0JztcbmltcG9ydCB7IFNwYXRpYWxDaGFydHNDb21wb25lbnQgfSBmcm9tICcuL3NwYXRpYWwtY2hhcnRzL3NwYXRpYWwtY2hhcnRzLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTcGF0aWFsRGF0YXNldCB9IGZyb20gJy4uL2NvbnRyYWN0cy9zcGF0aWFsLWRhdGFzZXQuY29udHJhY3QnO1xuaW1wb3J0IHsgQ29sb3JtYXBOb2RlLCBTcGF0aWFsVmlld1N0YXRlLCBERUZBVUxUX1NQQVRJQUxfVklFVyB9IGZyb20gJy4uL2NvbnRyYWN0cy9kaXNwbGF5LXR5cGVzJztcbmltcG9ydCB7IFBhbmVsT3B0aW9uLCBwYXJzZUdlbmVHcm91cHMgfSBmcm9tICcuLi9zcGF0aWFsL3NwYXRpYWwtcGFuZWwtbW9kZWwnO1xuaW1wb3J0IHsgU3BhdGlhbFNlbGVjdGlvbk1hc2ssIGVtcHR5U2VsZWN0aW9uIH0gZnJvbSAnLi4vc3BhdGlhbC9zcGF0aWFsLXNlbGVjdGlvbic7XG5pbXBvcnQgeyBHZW5lUGlja2VyTW9kZWwgfSBmcm9tICcuL3NwYXRpYWwtZ2VuZS1waWNrZXInO1xuaW1wb3J0IHsgU3BhdGlhbEtleU1vZGVsLCBTcGF0aWFsTGVnZW5kRW50cnkgfSBmcm9tICcuL3NwYXRpYWwta2V5L3NwYXRpYWwta2V5Lm1vZGVsJztcbmltcG9ydCB7IGNvbG9yQnlMYWJlbCB9IGZyb20gJy4vc3BhdGlhbC1rZXkvc3BhdGlhbC1rZXkuY29tcG9uZW50JztcbmltcG9ydCB7IFNwYXRpYWxDZWxsc1BhbmVsQ29tcG9uZW50IH0gZnJvbSAnLi9zcGF0aWFsLWNlbGxzLXBhbmVsL3NwYXRpYWwtY2VsbHMtcGFuZWwuY29tcG9uZW50JztcbmltcG9ydCB7IFNwYXRpYWxUcmFuc2NyaXB0c1BhbmVsQ29tcG9uZW50IH0gZnJvbSAnLi9zcGF0aWFsLXRyYW5zY3JpcHRzLXBhbmVsL3NwYXRpYWwtdHJhbnNjcmlwdHMtcGFuZWwuY29tcG9uZW50JztcbmltcG9ydCB7IFNwYXRpYWxPYnNlcnZhdGlvbnNQYW5lbENvbXBvbmVudCB9IGZyb20gJy4vc3BhdGlhbC1vYnNlcnZhdGlvbnMtcGFuZWwvc3BhdGlhbC1vYnNlcnZhdGlvbnMtcGFuZWwuY29tcG9uZW50JztcblxuLyoqIEBkZXByZWNhdGVkIE1vdmVkIHRvIGBzcGF0aWFsLWtleS9zcGF0aWFsLWtleS5tb2RlbGA7IHJlLWV4cG9ydGVkIGZvciBvbmUgcmVsZWFzZS4gKi9cbmV4cG9ydCB0eXBlIHsgU3BhdGlhbExlZ2VuZEVudHJ5IH07XG5cbi8qKiBAZGVwcmVjYXRlZCBNb3ZlZCB0byBgc3BhdGlhbC9zcGF0aWFsLXBhbmVsLW1vZGVsYDsgcmUtZXhwb3J0ZWQgZm9yIG9uZSByZWxlYXNlLiAqL1xuZXhwb3J0IHsgcGFyc2VHZW5lR3JvdXBzIH07XG5cbi8qKiBQZXItaW5zdGFuY2UgaWQgc291cmNlIOKAlCBzZWUge0BsaW5rIFNwYXRpYWxDb250cm9sc0NvbXBvbmVudC5jaGFydHNCb2R5SWR9LiAqL1xubGV0IGNvbnRyb2xzSW5zdGFuY2VTZXEgPSAwO1xuXG4vKipcbiAqIFNwYXRpYWwtb21pY3MgY29udHJvbHM6IGEgbm9uLW1vZGFsLCByZXNpemFibGUsIGRyYWdnYWJsZSBkaWFsb2cgZm9yIGNob29zaW5nXG4gKiB3aGF0IHRoZSBvYnNlcnZhdGlvbiBtYXJrZXJzIGFyZSBjb2xvdXJlZCBieSwgYW5kIGhvdyB0aGV5IGFyZSBkcmF3bi5cbiAqXG4gKiBEZXBlbmRzIG9ubHkgb24ge0BsaW5rIElTcGF0aWFsQ29udHJvbHN9LCByZWFjaGVkIHRocm91Z2ggdGhlIGBWSVNVQUxJWkVSYFxuICogY29udHJhY3QgdG9rZW4g4oCUIG5ldmVyIGEgY29uY3JldGUgYmFja2VuZCDigJQgbWlycm9yaW5nIGhvd1xuICogYENoYW5uZWxIaXN0b2dyYW1Db21wb25lbnRgIGRlcGVuZHMgb25seSBvbiBgQ0hBTk5FTF9ISVNUT0dSQU1fQVBJYC4gV2hlbiBub1xuICogaG9zdCBoYXMgYm91bmQgYFNQQVRJQUxfREFUQV9QT1JUYCwgYGdldFNwYXRpYWxDb250cm9scygpYCByZXR1cm5zIG51bGwgYW5kXG4gKiB0aGUgZGlhbG9nIHJlbmRlcnMgYW4gZXhwbGFuYXRvcnkgZW1wdHkgc3RhdGUgcmF0aGVyIHRoYW4gZGVhZCBjb250cm9scy5cbiAqXG4gKiBUaGUgbGVnZW5kIHN3YXRjaGVzIGFuZCB0aGUgY29udGludW91cyBjb2xvdXIgYmFyIGFyZSBidWlsdCB3aXRoIHRoZSBTQU1FXG4gKiBmdW5jdGlvbnMgdGhlIHJlbmRlcmVyIHVzZXMgKGBjYXRlZ29yeUNvbG9yc2Ag4oaSIGByZXNvbHZlQ2F0ZWdvcnlDb2xvcnNgLFxuICogYHNwYXRpYWxDb250aW51b3VzTHV0YCksIHNvIHRoZSBrZXkgY2Fubm90IGRyaWZ0IGZyb20gd2hhdCBpcyBvbiBzY3JlZW4uXG4gKlxuICogT25QdXNoOiB0aGUgY29udHJvbHMnIHN0cmVhbXMsIHRoZSBrZXkgYW5kIGdlbmUtbGlzdCBtb2RlbHMgKHdoaWNoIHJlLWVudGVyIHRoZSB6b25lXG4gKiB3aGVuIHRoZWlyIGFzeW5jIHdvcmsgbGFuZHMpIGFuZCBhbiBhd2FpdGVkIGNhdGVnb3J5IHNlbGVjdGlvbiBtYXJrIGl0IGZvciBjaGVjay5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnc3BhdGlhbC1jb250cm9scycsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGUsXG4gICAgRm9ybXNNb2R1bGUsXG4gICAgQnV0dG9uTW9kdWxlLFxuICAgIENoZWNrYm94TW9kdWxlLFxuICAgIERpYWxvZ01vZHVsZSxcbiAgICBUb29sdGlwTW9kdWxlLFxuICAgIFNwYXRpYWxDZWxsc1BhbmVsQ29tcG9uZW50LFxuICAgIFNwYXRpYWxUcmFuc2NyaXB0c1BhbmVsQ29tcG9uZW50LFxuICAgIFNwYXRpYWxPYnNlcnZhdGlvbnNQYW5lbENvbXBvbmVudCxcbiAgICBTcGF0aWFsQ2hhcnRzQ29tcG9uZW50LFxuICBdLFxuICB0ZW1wbGF0ZVVybDogJy4vc3BhdGlhbC1jb250cm9scy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3NwYXRpYWwtY29udHJvbHMuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIFNwYXRpYWxDb250cm9sc0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIC8qKiBUaGUgZW1iZWRkZWQgY2hhcnQsIHNvIGEgZGlhbG9nIHJlc2l6ZSBjYW4gcmUtZml0IGl0LiAqL1xuICBAVmlld0NoaWxkKFNwYXRpYWxDaGFydHNDb21wb25lbnQpIHByaXZhdGUgY2hhcnRzPzogU3BhdGlhbENoYXJ0c0NvbXBvbmVudDtcblxuICAvKipcbiAgICogUmUtZml0IHRoZSBjaGFydCBhZnRlciB0aGUgZGlhbG9nIGlzIHJlc2l6ZWQuXG4gICAqXG4gICAqIFBsb3RseSBkb2VzIG5vdCBmb2xsb3cgYSBjb250YWluZXIgcmVzaXplIG9uIGl0cyBvd24g4oCUIGl0cyBgcmVzcG9uc2l2ZWBcbiAgICogb3B0aW9uIGxpc3RlbnMgZm9yIFdJTkRPVyByZXNpemVzIG9ubHksIHNvIGRyYWdnaW5nIHRoZSBkaWFsb2cncyBoYW5kbGVcbiAgICogcmVhY2hlcyBpdCB0aHJvdWdoIG5vdGhpbmcuIFByaW1lTkcgdGVsbHMgdXMgd2hlbiB0aGUgZHJhZyBlbmRzLCB3aGljaCBpcyBhXG4gICAqIGZhciBtb3JlIGRpcmVjdCBzaWduYWwgdGhhbiB3YXRjaGluZyBib3hlcywgYW5kIGZpcmluZyBvbmNlIG9uIHJlbGVhc2UgbWVhbnNcbiAgICogbm8gcmVsYXlvdXQgY2h1cm4gZHVyaW5nIHRoZSBkcmFnLlxuICAgKi9cbiAgcHJvdGVjdGVkIG9uUmVzaXplRW5kKCk6IHZvaWQge1xuICAgIHRoaXMuY2hhcnRzPy5yZXNpemUoKTtcbiAgfVxuXG4gIC8qKiBEaWFsb2cgdmlzaWJpbGl0eSwgdHdvLXdheSBib3VuZCBzbyBhIHRvb2xiYXIgYnV0dG9uIGNhbiBvcGVuIGl0LiAqL1xuICBASW5wdXQoKSB2aXNpYmxlID0gZmFsc2U7XG4gIC8qKiBTZXQgd2hpbGUgdGhlIDNEIGNsb3VkIGlzIHRoZSBhY3RpdmUgbW9kZS4gQ2hhbmdlcyB3aGF0IHRoZSBST0kgc2VsZWN0aW9uXG4gICAqICBNRUFOUyDigJQgYSBzY3JlZW4tc3BhY2UgbGFzc28gY3V0dGluZyB0aHJvdWdoIHRoZSBjbG91ZCdzIGZ1bGwgZGVwdGggcmF0aGVyXG4gICAqICB0aGFuIGEgc2hhcGUgaW4gdGlzc3VlIGNvb3JkaW5hdGVzIOKAlCBzbyB0aGUgaGludCBiZWxvdyBpdCBzYXlzIHNvLiAqL1xuICBASW5wdXQoKSBpczNkID0gZmFsc2U7XG4gIC8qKiBUaGUgZGlhbG9nIHdhcyBvcGVuZWQgb3IgY2xvc2VkOyB0d28td2F5IHdpdGgge0BsaW5rIHZpc2libGV9LiAqL1xuICBAT3V0cHV0KCkgdmlzaWJsZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcblxuICAvKiogTnVsbCB3aGVuIHRoZSBob3N0IGJvdW5kIG5vIGBTUEFUSUFMX0RBVEFfUE9SVGAuICovXG4gIHByb3RlY3RlZCBjb250cm9sczogSVNwYXRpYWxDb250cm9scyB8IG51bGwgPSBudWxsO1xuICBwcm90ZWN0ZWQgZGF0YXNldDogU3BhdGlhbERhdGFzZXQgfCBudWxsID0gbnVsbDtcbiAgcHJvdGVjdGVkIHZpZXc6IFNwYXRpYWxWaWV3U3RhdGUgPSB7IC4uLkRFRkFVTFRfU1BBVElBTF9WSUVXIH07XG5cbiAgLyoqXG4gICAqIEdlbmUgcGlja2VyOiBhIGZpbHRlcmFibGUgZHJvcGRvd24gcmF0aGVyIHRoYW4gYSBmcmVlLXRleHQgdHlwZWFoZWFkLCBzbyB0aGVcbiAgICogb3B0aW9ucyBhcmUgdmlzaWJsZSBiZWZvcmUgYW55dGhpbmcgaXMgdHlwZWQgYW5kIGVhY2gga2V5c3Ryb2tlIG5hcnJvd3MgYSBsaXN0XG4gICAqIHRoZSB1c2VyIGNhbiBzZWUuIE9uZSBtb2RlbCBmZWVkcyBldmVyeSBnZW5lIGRyb3Bkb3duIG9mIHRoZSBwYW5lbC5cbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSBnZW5lcyA9IG5ldyBHZW5lUGlja2VyTW9kZWwoXG4gICAgKCkgPT4gdGhpcy5jb250cm9scyxcbiAgICAoKSA9PiBbXG4gICAgICAuLi4odGhpcy52aWV3Py50cmFuc2NyaXB0R2VuZXMgPz8gW10pLFxuICAgICAgLi4uKHRoaXMudmlldz8uY29sb3JCeT8ua2luZCA9PT0gJ2ZlYXR1cmUnID8gW3RoaXMudmlldy5jb2xvckJ5Lm5hbWVdIDogW10pLFxuICAgIF0sXG4gICAgKGZuKSA9PiB0aGlzLnJ1bkFuZE1hcmsoZm4pLFxuICApO1xuICAvKiogVGhlIGdlbmUgZHJvcGRvd25zJyBvcHRpb25zLiAqL1xuICBnZXQgZ2VuZU9wdGlvbnMoKTogUGFuZWxPcHRpb248c3RyaW5nPltdIHtcbiAgICByZXR1cm4gdGhpcy5nZW5lcy5vcHRpb25zO1xuICB9XG4gIC8qKiBUcnVlIHdoZW4gdGhlIG9wdGlvbnMgY29tZSBmcm9tIHRoZSBwb3J0IHBlciBrZXlzdHJva2UgcmF0aGVyIHRoYW4gYSByZXNpZGVudCBsaXN0LiAqL1xuICBnZXQgZ2VuZXNBcmVSZW1vdGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZ2VuZXMucmVtb3RlO1xuICB9XG4gIGdldCBnZW5lU2VhcmNoRmFpbGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmdlbmVzLmZhaWxlZDtcbiAgfVxuXG4gIC8qKiBUaGUga2V5IOKAlCBsZWdlbmQgb3IgY29sb3VyIGJhciDigJQgZm9yIHRoZSBhY3RpdmUgY29sb3VyaW5nLiBLZXB0IGhlcmUsIG5vdCBpblxuICAgKiAgYDxzcGF0aWFsLWtleT5gOiB3aGV0aGVyIHRoZSBjb2xvdXJpbmcgaXMgY2F0ZWdvcmljYWwgZGVjaWRlcyB3aGljaCBrbm9icyB0aGUgcmVzdCBvZlxuICAgKiAgdGhlIHBhbmVsIG9mZmVycywgd2hldGhlciBvciBub3QgdGhlIGtleSBpcyBvbiBzY3JlZW4uICovXG4gIHJlYWRvbmx5IGtleSA9IG5ldyBTcGF0aWFsS2V5TW9kZWwoKGZuKSA9PiB0aGlzLnJ1bkFuZE1hcmsoZm4pKTtcbiAgLyoqIENhdGVnb3JpY2FsIGtleSwgb3IgbnVsbCB3aGVuIHRoZSBhY3RpdmUgY29sb3VyaW5nIGlzIGNvbnRpbnVvdXMuICovXG4gIHByb3RlY3RlZCBnZXQgbGVnZW5kKCk6IFNwYXRpYWxMZWdlbmRFbnRyeVtdIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMua2V5LmxlZ2VuZDtcbiAgfVxuICAvKiogQ1NTIGdyYWRpZW50IGZvciBhIGNvbnRpbnVvdXMgY29sb3VyaW5nLCBvciBudWxsIHdoZW4gY2F0ZWdvcmljYWwuICovXG4gIHByb3RlY3RlZCBnZXQgY29sb3JCYXJDc3MoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMua2V5LmNvbG9yQmFyQ3NzO1xuICB9XG5cbiAgLyoqIEN1cnJlbnQgc2VsZWN0aW9uIOKAlCBkcml2ZXMgdGhlIGNvdW50LCB0aGUgQ2xlYXIgYnV0dG9uIGFuZCB0aGUgbXV0aW5nLiAqL1xuICBwcm90ZWN0ZWQgc2VsZWN0aW9uOiBTcGF0aWFsU2VsZWN0aW9uTWFzayA9IGVtcHR5U2VsZWN0aW9uKCk7XG4gIC8qKiBUaGUgbGVnZW5kIHJvdyB3aG9zZSBjYXRlZ29yeSBpcyBjdXJyZW50bHkgc2VsZWN0ZWQsIGZvciBoaWdobGlnaHRpbmcuICovXG4gIHByb3RlY3RlZCBzZWxlY3RlZENhdGVnb3J5OiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqIEFuIFJPSSBzZWxlY3Rpb24gdGhhdCBtYXRjaGVkIG5vdGhpbmcsIHNvIHRoZSBVSSBjYW4gc2F5IHNvIHJhdGhlciB0aGFuXG4gICAqICBsb29raW5nIGxpa2UgdGhlIGJ1dHRvbiBkaWQgbm90aGluZy4gKi9cbiAgcHJvdGVjdGVkIHNlbGVjdGlvbk1pc3NlZCA9IGZhbHNlO1xuICAvKiogVGhlIG1vZGUgb2YgdGhlIHNlbGVjdGlvbiB0aGF0IHtAbGluayBzZWxlY3Rpb25NaXNzZWR9OiB3aGF0IGl0IGZvdW5kIG5vdGhpbmcgaW5zaWRlLiAqL1xuICBwcm90ZWN0ZWQgbWlzc2VkTW9kZTogUm9pU2VsZWN0aW9uTW9kZSA9ICdyZWdpb25zJztcbiAgLyoqIFRoZSByZWdpb24gY2xhc3NlcyBwaWNrZWQgaW4gdGhlIFJlZ2lvbiBFZGl0b3I6IGluIDNELCBcIlNlbGVjdCBmcm9tIFJPSXNcIiBzZWxlY3RzIGluc2lkZSB0aGVtLiAqL1xuICBwcm90ZWN0ZWQgcGlja2VkQ2xhc3NlczogcmVhZG9ubHkgc3RyaW5nW10gPSBbXTtcbiAgLyoqIFdoaWxlIFwiU2VsZWN0IGZyb20gUk9Jc1wiIHJlYWRzIHRoZSBwaWNrZWQgY2xhc3Nlcycgb3V0bGluZXMuICovXG4gIHByb3RlY3RlZCBzZWxlY3RpbmdGcm9tUmVnaW9ucyA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBEaXN0cmlidXRpb24gc2VjdGlvbiBpcyBleHBhbmRlZC4gQ29sbGFwc2VkIGJ5IGRlZmF1bHQ6IHRoZVxuICAgKiBwYW5lbCdzIHByaW1hcnkgam9iIGlzIHRoZSBjb2xvdXIgY29udHJvbHMsIGFuZCB0aGUgY2hhcnQgcm91Z2hseSBkb3VibGVzXG4gICAqIGl0cyBoZWlnaHQuXG4gICAqL1xuICBwcm90ZWN0ZWQgY2hhcnRzT3BlbiA9IGZhbHNlO1xuICAvKiogUGVyLWluc3RhbmNlIGlkIGZvciB0aGUgY29sbGFwc2libGUgYm9keSwgc28gYGFyaWEtY29udHJvbHNgIHBvaW50cyBhdCBvbmVcbiAgICogIGVsZW1lbnQgYW5kIGV4cGFuZGluZyB0aGUgc2Vjb25kIHBhbmVsIGNhbm5vdCBzY3JvbGwgdGhlIGZpcnN0IG9uZSdzIGNoYXJ0LiAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgY2hhcnRzQm9keUlkID0gYHNjLWNoYXJ0cy1ib2R5LSR7Kytjb250cm9sc0luc3RhbmNlU2VxfWA7XG5cbiAgLyoqIENvbG9ybWFwIHRyZWUgZm9yIHRoZSBjb250aW51b3VzIGNvbG91ciBzY2FsZSBhbmQgdGhlIGRlbnNpdHkgbWFwOiB0aGUgbGlicmFyeSdzXG4gICAqICBvd24gYENPTE9STUFQX09QVElPTlNgLiAqL1xuICBwcm90ZWN0ZWQgY29sb3JtYXBPcHRpb25zOiBDb2xvcm1hcE5vZGVbXSA9IFtdO1xuXG4gIHByaXZhdGUgY29sb3JtYXA6IENvbG9ybWFwTm9kZSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHJldmVyc2UgPSBmYWxzZTtcbiAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuICBwcml2YXRlIHJlYWRvbmx5IGNkciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChWSVNVQUxJWkVSKSBwcml2YXRlIHJlYWRvbmx5IHZpejogSVZpc3VhbGl6ZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSB6b25lOiBOZ1pvbmUsXG4gICkge31cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRyb2xzID0gdGhpcy52aXouZ2V0U3BhdGlhbENvbnRyb2xzPy4oKSA/PyBudWxsO1xuICAgIHRoaXMuY29sb3JtYXBPcHRpb25zID0gdGhpcy52aXouZ2V0Q29sb3JtYXBPcHRpb25zPy4oKSA/PyBbXTtcbiAgICBpZiAoIXRoaXMuY29udHJvbHMpIHJldHVybjtcblxuICAgIGNvbnN0IHVudGlsRGVzdHJveWVkID0gPFQ+KCkgPT4gdGFrZVVudGlsRGVzdHJveWVkPFQ+KHRoaXMuZGVzdHJveVJlZik7XG4gICAgdGhpcy5jb250cm9sc1xuICAgICAgLmdldERhdGFzZXQkKClcbiAgICAgIC5waXBlKHVudGlsRGVzdHJveWVkKCkpXG4gICAgICAuc3Vic2NyaWJlKChkYXRhc2V0KSA9PiB7XG4gICAgICAgIHRoaXMuZGF0YXNldCA9IGRhdGFzZXQ7XG4gICAgICAgIHRoaXMuZ2VuZXMuc2V0RGF0YXNldChkYXRhc2V0KTtcbiAgICAgICAgLy8gQSBkYXRhc2V0IHdpdGggbm8gY2VsbHMgdG8gb3V0bGluZSBsZWFkcyB3aXRoIGl0cyBvYnNlcnZhdGlvbnMuXG4gICAgICAgIHRoaXMub3BlbiA9IHtcbiAgICAgICAgICAuLi50aGlzLm9wZW4sXG4gICAgICAgICAgY2VsbHM6ICEhKGRhdGFzZXQ/LnBvbHlnb25UaWxlcyB8fCBkYXRhc2V0Py5wb2x5Z29ucyksXG4gICAgICAgICAgb2JzZXJ2YXRpb25zOiAhKGRhdGFzZXQ/LnBvbHlnb25UaWxlcyB8fCBkYXRhc2V0Py5wb2x5Z29ucyksXG4gICAgICAgIH07XG4gICAgICAgIHZvaWQgdGhpcy5yZWZyZXNoS2V5KCk7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSk7XG5cbiAgICB0aGlzLmNvbnRyb2xzXG4gICAgICAuZ2V0Vmlld1N0YXRlJCgpXG4gICAgICAucGlwZSh1bnRpbERlc3Ryb3llZCgpKVxuICAgICAgLnN1YnNjcmliZSgodmlldykgPT4ge1xuICAgICAgICB0aGlzLnZpZXcgPSB2aWV3O1xuICAgICAgICB2b2lkIHRoaXMucmVmcmVzaEtleSgpO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuXG4gICAgLy8gVGhlIHJlbmRlcmVyJ3Mgb3duIHN0cmVhbXMgbWF5IGVtaXQgb3V0c2lkZSB0aGUgem9uZTogcmUtZW50ZXJlZCBoZXJlLCBvbmNlLCBmb3JcbiAgICAvLyBldmVyeSBwYW5lbCB0aGV5IGZlZWQuXG4gICAgY29uc3QgZXN0aW1hdGUkID0gdGhpcy5jb250cm9scy5nZXRUcmFuc2NyaXB0RXN0aW1hdGUkPy4oKTtcbiAgICBlc3RpbWF0ZSQ/LnBpcGUodW50aWxEZXN0cm95ZWQoKSkuc3Vic2NyaWJlKChlKSA9PlxuICAgICAgdGhpcy5ydW5BbmRNYXJrKCgpID0+IHtcbiAgICAgICAgdGhpcy5lc3RpbWF0ZSA9IGU7XG4gICAgICB9KSxcbiAgICApO1xuICAgIGNvbnN0IGNvdW50cyQgPSB0aGlzLmNvbnRyb2xzLmdldEdlbmVDb3VudHNJblZpZXckPy4oKTtcbiAgICBjb3VudHMkPy5waXBlKHVudGlsRGVzdHJveWVkKCkpLnN1YnNjcmliZSgoYykgPT5cbiAgICAgIHRoaXMucnVuQW5kTWFyaygoKSA9PiB7XG4gICAgICAgIHRoaXMuZ2VuZUNvdW50cyA9IGM7XG4gICAgICB9KSxcbiAgICApO1xuICAgIGNvbnN0IGRlbnNpdHkkID0gdGhpcy5jb250cm9scy5nZXREZW5zaXR5U3RhdHMkPy4oKTtcbiAgICBkZW5zaXR5JD8ucGlwZSh1bnRpbERlc3Ryb3llZCgpKS5zdWJzY3JpYmUoKGQpID0+XG4gICAgICB0aGlzLnJ1bkFuZE1hcmsoKCkgPT4ge1xuICAgICAgICB0aGlzLmRlbnNpdHlTdGF0cyA9IGQ7XG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgdGhpcy5jb250cm9sc1xuICAgICAgLmdldFNlbGVjdGlvbiQoKVxuICAgICAgLnBpcGUodW50aWxEZXN0cm95ZWQoKSlcbiAgICAgIC5zdWJzY3JpYmUoKHNlbGVjdGlvbikgPT5cbiAgICAgICAgLy8gU2V0IGZyb20gb3V0c2lkZSB0aGUgem9uZSB0b286IGEgc2VsZWN0aW9uIGZyb20gdGhlIHJlZ2lvbiBjbGFzc2VzJyB2b2x1bWVzLlxuICAgICAgICB0aGlzLnJ1bkFuZE1hcmsoKCkgPT4ge1xuICAgICAgICAgIHRoaXMuc2VsZWN0aW9uID0gc2VsZWN0aW9uO1xuICAgICAgICAgIGlmIChzZWxlY3Rpb24uY291bnQgPT09IDApIHRoaXMuc2VsZWN0ZWRDYXRlZ29yeSA9IG51bGw7XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgIHRoaXMuY29udHJvbHNcbiAgICAgIC5nZXRQaWNrZWRSZWdpb25DbGFzc2VzJD8uKClcbiAgICAgID8ucGlwZSh1bnRpbERlc3Ryb3llZCgpKVxuICAgICAgLnN1YnNjcmliZSgoY2xhc3NlcykgPT5cbiAgICAgICAgdGhpcy5ydW5BbmRNYXJrKCgpID0+IHtcbiAgICAgICAgICB0aGlzLnBpY2tlZENsYXNzZXMgPSBjbGFzc2VzO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAvLyBUaGUgY29sb3VyIGJhciBtdXN0IHVzZSB0aGUgY29sb3JtYXAgdGhlIHJlbmRlcmVyIGlzIHVzaW5nLlxuICAgIGNvbWJpbmVMYXRlc3QoW3RoaXMudml6LmdldENvbG9ybWFwKCksIHRoaXMudml6LmdldFJldmVyc2VTY2FsZSgpXSlcbiAgICAgIC5waXBlKHVudGlsRGVzdHJveWVkKCkpXG4gICAgICAuc3Vic2NyaWJlKChbY29sb3JtYXAsIHJldmVyc2VdKSA9PiB7XG4gICAgICAgIHRoaXMuY29sb3JtYXAgPSAoY29sb3JtYXAgYXMgQ29sb3JtYXBOb2RlKSA/PyBudWxsO1xuICAgICAgICB0aGlzLnJldmVyc2UgPSAhIXJldmVyc2U7XG4gICAgICAgIHZvaWQgdGhpcy5yZWZyZXNoS2V5KCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKiBBcHBseSBhbiBhc3luYyByZXN1bHQgaW5zaWRlIHRoZSB6b25lIGFuZCByZS1yZW5kZXIgdGhpcyBPblB1c2ggZGlhbG9nLiAqL1xuICBwcml2YXRlIHJ1bkFuZE1hcmsoZm46ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLnpvbmUucnVuKCgpID0+IHtcbiAgICAgIGZuKCk7XG4gICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvblZpc2libGVDaGFuZ2UodmFsdWU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLnZpc2libGUgPSB2YWx1ZTtcbiAgICB0aGlzLnZpc2libGVDaGFuZ2UuZW1pdCh2YWx1ZSk7XG4gIH1cblxuICAvLyDilIDilIAgdGhlIHNoYXJlZCBnZW5lIGxpc3Qg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqIEEga2V5c3Ryb2tlIGluIGEgZ2VuZSBkcm9wZG93bidzIGZpbHRlciBib3gg4oCUIHNlZSB7QGxpbmsgR2VuZVBpY2tlck1vZGVsLm9uRmlsdGVyfS4gKi9cbiAgb25HZW5lRmlsdGVyKHF1ZXJ5OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5nZW5lcy5vbkZpbHRlcihxdWVyeSk7XG4gIH1cblxuICAvKiogQSBnZW5lIGRyb3Bkb3duIG9wZW5lZCDigJQgc2VlIHtAbGluayBHZW5lUGlja2VyTW9kZWwuZW5zdXJlTGlzdH0uICovXG4gIGVuc3VyZUdlbmVMaXN0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLmdlbmVzLmVuc3VyZUxpc3QoKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBzZWxlY3Rpb24g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqIFNlbGVjdCBldmVyeSBvYnNlcnZhdGlvbiBpbnNpZGUgdGhlIGRyYXduIHJlZ2lvbnMgKHRoZWlyIHVuaW9uKSDigJQgaW4gM0QsIGluc2lkZSB0aGVcbiAgICogIHBpY2tlZCBjbGFzc2VzJyB2b2x1bWVzLiAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgc2VsZWN0RnJvbVJlZ2lvbnMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCF0aGlzLmNvbnRyb2xzIHx8IHRoaXMuc2VsZWN0aW5nRnJvbVJlZ2lvbnMpIHJldHVybjtcbiAgICB0aGlzLnNlbGVjdGluZ0Zyb21SZWdpb25zID0gdHJ1ZTtcbiAgICAvLyBUaGUgbW9kZSB0aGUgc2VsZWN0aW9uIHJ1bnMgaW4gKGRlY2lkZWQgYXMgaXQgc3RhcnRzKSwgZm9yIHdoYXQgYSBtaXNzIHNheXMgaXQgbWlzc2VkLlxuICAgIGNvbnN0IG1vZGUgPSB0aGlzLnJvaVNlbGVjdGlvbk1vZGU7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgbGV0IGNvdW50OiBudW1iZXIgfCBudWxsID0gMDtcbiAgICB0cnkge1xuICAgICAgY291bnQgPSBhd2FpdCB0aGlzLmNvbnRyb2xzLnNlbGVjdEZyb21SZWdpb25zKCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1tzcGF0aWFsXSBjb3VsZCBub3Qgc2VsZWN0IGZyb20gdGhlIHJlZ2lvbnMnLCBlcnIpO1xuICAgIH1cbiAgICAvLyBUaGUgY2xhc3Nlcycgb3V0bGluZXMgYXJlIHJlYWQgaW4gYSB3b3JrZXIsIHdob3NlIGFuc3dlciBsYW5kcyBvdXRzaWRlIHRoZSB6b25lLlxuICAgIHRoaXMucnVuQW5kTWFyaygoKSA9PiB7XG4gICAgICB0aGlzLnNlbGVjdGluZ0Zyb21SZWdpb25zID0gZmFsc2U7XG4gICAgICAvLyBTdXBlcnNlZGVkIChudWxsKTogYSBuZXdlciBzZWxlY3Rpb24gc3RhbmRzLCBhbmQgc2F5cyB3aGF0IGl0IGlzIGl0c2VsZi5cbiAgICAgIGlmIChjb3VudCA9PT0gbnVsbCkgcmV0dXJuO1xuICAgICAgdGhpcy5zZWxlY3RlZENhdGVnb3J5ID0gbnVsbDtcbiAgICAgIHRoaXMuc2VsZWN0aW9uTWlzc2VkID0gY291bnQgPT09IDA7XG4gICAgICB0aGlzLm1pc3NlZE1vZGUgPSBtb2RlO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqIEluIDNEIHdpdGggY2xhc3NlcyBwaWNrZWQsIFwiU2VsZWN0IGZyb20gUk9Jc1wiIHNlbGVjdHMgaW5zaWRlIHRoZWlyIHZvbHVtZXMuICovXG4gIHByb3RlY3RlZCBnZXQgc2VsZWN0c0NsYXNzVm9sdW1lcygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5yb2lTZWxlY3Rpb25Nb2RlID09PSAnY2xhc3Mtdm9sdW1lcyc7XG4gIH1cblxuICAvKiogSG93IFwiU2VsZWN0IGZyb20gUk9Jc1wiIHNlbGVjdHMgbm93OiB0aGUgY29udHJvbHMnIG93biBydWxlLCB0aGUgb25lIHRoZSBzZWxlY3Rpb24gcnVucyBieS4gKi9cbiAgcHJpdmF0ZSBnZXQgcm9pU2VsZWN0aW9uTW9kZSgpOiBSb2lTZWxlY3Rpb25Nb2RlIHtcbiAgICByZXR1cm4gdGhpcy5jb250cm9scz8ucm9pU2VsZWN0aW9uTW9kZT8uKCkgPz8gJ3JlZ2lvbnMnO1xuICB9XG5cbiAgLyoqIExlZ2VuZCBjbGljazogc2VsZWN0IG9uZSBjYXRlZ29yeS4gQ2xpY2tpbmcgdGhlIGFjdGl2ZSByb3cgY2xlYXJzIGl0LCBzbyBhXG4gICAqICBzZWNvbmQgY2xpY2sgaXMgYW4gdW5kbyByYXRoZXIgdGhhbiBhIG5vLW9wLiAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgc2VsZWN0Q2F0ZWdvcnkoaW5kZXg6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGJ5ID0gdGhpcy52aWV3LmNvbG9yQnk7XG4gICAgaWYgKCF0aGlzLmNvbnRyb2xzIHx8IGJ5Py5raW5kICE9PSAnY29sdW1uJykgcmV0dXJuO1xuICAgIGlmICh0aGlzLnNlbGVjdGVkQ2F0ZWdvcnkgPT09IGluZGV4KSB7XG4gICAgICB0aGlzLmNsZWFyU2VsZWN0aW9uKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmNvbnRyb2xzLnNlbGVjdENhdGVnb3J5KGJ5Lm5hbWUsIGluZGV4KTtcbiAgICAgIHRoaXMuc2VsZWN0ZWRDYXRlZ29yeSA9IGluZGV4O1xuICAgICAgdGhpcy5zZWxlY3Rpb25NaXNzZWQgPSBmYWxzZTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRDYXRlZ29yeSA9IG51bGw7XG4gICAgfVxuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cGFuZCBvciBjb2xsYXBzZSB0aGUgZGlzdHJpYnV0aW9uIHNlY3Rpb24uXG4gICAqXG4gICAqIEV4cGFuZGluZyBTQ1JPTExTIGl0IGludG8gdmlldywgYmVjYXVzZSB0aGUgcGFuZWwgaXMgdGFsbGVyIHRoYW4gdGhlIHZpZXdwb3J0XG4gICAqIG9uY2UgdGhpcyBzZWN0aW9uIGlzIG9wZW4gYW5kIHRoZSBjaGFydCBpcyBpdHMgbGFzdCByb3c6IGV4cGFuZGluZyBpdCBkcmV3IGFcbiAgICogY2hhcnQgfjMwMCBweCBiZWxvdyB0aGUgZm9sZCwgd2hpY2ggcmVhZHMgYXMgdGhlIHNlY3Rpb24gYmVpbmcgZW1wdHkuIFRoZVxuICAgKiBzY3JvbGwgaXMgZGVmZXJyZWQgYSB0YXNrIHNvIHRoZSBjaGFydCdzIG93biBkZWZlcnJlZCBmaXJzdCBkcmF3IGhhcyBnaXZlbiB0aGVcbiAgICogYm9keSBpdHMgaGVpZ2h0LlxuICAgKi9cbiAgcHJvdGVjdGVkIHRvZ2dsZUNoYXJ0cygpOiB2b2lkIHtcbiAgICB0aGlzLmNoYXJ0c09wZW4gPSAhdGhpcy5jaGFydHNPcGVuO1xuICAgIGlmICghdGhpcy5jaGFydHNPcGVuKSByZXR1cm47XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLmNoYXJ0c0JvZHlJZCk/LnNjcm9sbEludG9WaWV3KHsgYmxvY2s6ICdlbmQnLCBiZWhhdmlvcjogJ3Ntb290aCcgfSk7XG4gICAgfSwgMCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY2xlYXJTZWxlY3Rpb24oKTogdm9pZCB7XG4gICAgdGhpcy5jb250cm9scz8uY2xlYXJTZWxlY3Rpb24oKTtcbiAgICB0aGlzLnNlbGVjdGVkQ2F0ZWdvcnkgPSBudWxsO1xuICAgIHRoaXMuc2VsZWN0aW9uTWlzc2VkID0gZmFsc2U7XG4gIH1cblxuICAvKiogVHJ1ZSB3aGlsZSBhIHNlbGVjdGlvbiBpcyBhY3RpdmUg4oCUIGV2ZXJ5dGhpbmcgZWxzZSByZW5kZXJzIG11dGVkLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGhhc1NlbGVjdGlvbigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3Rpb24uY291bnQgPiAwO1xuICB9XG5cbiAgLy8g4pSA4pSAIHNlY3Rpb25zIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKiBCb3VuZGFyaWVzIG9uIG9mZmVyOiB0aWxlZCAobGV2ZWwtb2YtZGV0YWlsKSBvciB3aG9sZS1kYXRhc2V0IHJpbmdzLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGhhc0NlbGxzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhISh0aGlzLmRhdGFzZXQ/LnBvbHlnb25UaWxlcyB8fCB0aGlzLmRhdGFzZXQ/LnBvbHlnb25zKTtcbiAgfVxuXG4gIC8qKiBUcmFuc2NyaXB0cyBvbiBvZmZlcjogdGlsZXMgdG8gZHJhdywgb3IgYSBkZW5zaXR5IG1hcC4gKi9cbiAgcHJvdGVjdGVkIGdldCBoYXNUcmFuc2NyaXB0cygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmRhdGFzZXQ/LnRyYW5zY3JpcHRUaWxlcyB8fCAhIXRoaXMuZGF0YXNldD8uZGVuc2l0eTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvblNob3dJbWFnZShvbjogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuY29udHJvbHM/LnNldFZpZXdTdGF0ZSh7IHNob3dJbWFnZTogb24gfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb25TaG93QW5ub3RhdGlvbnMob246IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRyb2xzPy5zZXRWaWV3U3RhdGUoeyBzaG93QW5ub3RhdGlvbnM6IG9uIH0pO1xuICB9XG5cbiAgLyoqIFdoaWNoIGNvbGxhcHNpYmxlIHNlY3Rpb25zIGFyZSBvcGVuLiBQZXIgZGlhbG9nIGluc3RhbmNlLCBub3QgcGVyc2lzdGVkLiAqL1xuICBwcm90ZWN0ZWQgb3BlbjogUmVjb3JkPCdpbWFnZXMnIHwgJ2NlbGxzJyB8ICd0cmFuc2NyaXB0cycgfCAnYW5ub3RhdGlvbnMnIHwgJ29ic2VydmF0aW9ucycsIGJvb2xlYW4+ID0ge1xuICAgIGltYWdlczogZmFsc2UsXG4gICAgY2VsbHM6IHRydWUsXG4gICAgdHJhbnNjcmlwdHM6IGZhbHNlLFxuICAgIGFubm90YXRpb25zOiBmYWxzZSxcbiAgICBvYnNlcnZhdGlvbnM6IGZhbHNlLFxuICB9O1xuXG4gIHByb3RlY3RlZCB0b2dnbGVTZWN0aW9uKG5hbWU6IGtleW9mIFNwYXRpYWxDb250cm9sc0NvbXBvbmVudFsnb3BlbiddKTogdm9pZCB7XG4gICAgdGhpcy5zZXRPcGVuKG5hbWUsICF0aGlzLm9wZW5bbmFtZV0pO1xuICB9XG5cbiAgLyoqIEV4cGFuZCBvciBjb2xsYXBzZSBhIHNlY3Rpb24g4oCUIHdoYXQgYSBwYW5lbCdzIGhlYWRlciBhc2tzIGZvci4gKi9cbiAgcHJvdGVjdGVkIHNldE9wZW4obmFtZToga2V5b2YgU3BhdGlhbENvbnRyb2xzQ29tcG9uZW50WydvcGVuJ10sIG9uOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5vcGVuID0geyAuLi50aGlzLm9wZW4sIFtuYW1lXTogb24gfTtcbiAgfVxuXG4gIC8vIOKUgOKUgCByZW5kZXJlciByZWFkb3V0cywgZm9yIHRoZSBUcmFuc2NyaXB0cyBzZWN0aW9uIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKiBFc3RpbWF0ZWQgdHJhbnNjcmlwdHMgaW4gdmlldywgYWdhaW5zdCB0aGUgYnVkZ2V0IOKAlCBFeHBsb3JlcidzIHBvaW50cyBiYXIuICovXG4gIHByb3RlY3RlZCBlc3RpbWF0ZTogeyBwb2ludHM6IG51bWJlcjsgbWF4OiBudW1iZXIgfSB8IG51bGwgPSBudWxsO1xuICAvKiogVGhlIGRlbnNpdHkgd2luZG93IGluIHVzZSBhbmQgaXRzIGRlbnNlc3QgYmluLCBmb3IgdGhlIHRocmVzaG9sZCBjb250cm9sLiAqL1xuICBwcm90ZWN0ZWQgZGVuc2l0eVN0YXRzOiB7IGxvOiBudW1iZXI7IGhpOiBudW1iZXI7IG1heDogbnVtYmVyIH0gfCBudWxsID0gbnVsbDtcbiAgLyoqIFRyYW5zY3JpcHRzIG9mIGVhY2ggc2VsZWN0ZWQgZ2VuZSBpbiB0aGUgY3VycmVudCB2aWV3LCBmcm9tIHRoZSByZW5kZXJlci4gKi9cbiAgcHJvdGVjdGVkIGdlbmVDb3VudHM6IFJlY29yZDxzdHJpbmcsIG51bWJlcj4gfCBudWxsID0gbnVsbDtcblxuICBwcm90ZWN0ZWQgcmVzZXQoKTogdm9pZCB7XG4gICAgdGhpcy5jb250cm9scz8uc2V0Vmlld1N0YXRlKHsgLi4uREVGQVVMVF9TUEFUSUFMX1ZJRVcgfSk7XG4gICAgdGhpcy5jbGVhclNlbGVjdGlvbigpO1xuICB9XG5cbiAgLyoqIExhYmVsIGZvciB0aGUgY3VycmVudCBjb2xvdXJpbmcsIGZvciB0aGUgRGlzdHJpYnV0aW9uIGhlYWRpbmcuICovXG4gIHByb3RlY3RlZCBnZXQgY29sb3JCeUxhYmVsKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGNvbG9yQnlMYWJlbCh0aGlzLnZpZXcpO1xuICB9XG5cbiAgLyoqIFRydWUgd2hlbiB0aGUgYWN0aXZlIGNvbG91cmluZyBpcyBhIGNhdGVnb3JpY2FsIGNvbHVtbiAoZHJpdmVzIHRoZSBrZXkpLiAqL1xuICBnZXQgaXNDYXRlZ29yaWNhbCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5sZWdlbmQgIT09IG51bGw7XG4gIH1cblxuICAvKiogV2hldGhlciBsb2cvY2xpcCBhcHBseSDigJQgdGhleSBhcmUgY29udGludW91cy1vbmx5IGtub2JzLiAqL1xuICBnZXQgaXNDb250aW51b3VzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMudmlldy5jb2xvckJ5ICYmIHRoaXMubGVnZW5kID09PSBudWxsO1xuICB9XG5cbiAgLy8g4pSA4pSAIGludGVybmFscyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKiogUmVidWlsZCB0aGUgbGVnZW5kIG9yIGNvbG91ciBiYXIgZm9yIHRoZSBjdXJyZW50IGNvbG91cmluZy4gKi9cbiAgcHJpdmF0ZSByZWZyZXNoS2V5KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLmtleS5yZWZyZXNoKHRoaXMuY29udHJvbHMsIHRoaXMuZGF0YXNldCwgdGhpcy52aWV3LCB0aGlzLmNvbG9ybWFwLCB0aGlzLnJldmVyc2UpO1xuICB9XG59XG4iLCI8cC1kaWFsb2dcbiAgaGVhZGVyPVwiU3BhdGlhbCBvbWljc1wiXG4gIFt2aXNpYmxlXT1cInZpc2libGVcIlxuICAodmlzaWJsZUNoYW5nZSk9XCJvblZpc2libGVDaGFuZ2UoJGV2ZW50KVwiXG4gIFttb2RhbF09XCJmYWxzZVwiXG4gIFtyZXNpemFibGVdPVwidHJ1ZVwiXG4gIFtkcmFnZ2FibGVdPVwidHJ1ZVwiXG4gIHBvc2l0aW9uPVwibGVmdFwiXG4gIChvblJlc2l6ZUVuZCk9XCJvblJlc2l6ZUVuZCgpXCJcbiAgW3N0eWxlXT1cInsgd2lkdGg6ICczMHJlbScgfVwiXG4gIFticmVha3BvaW50c109XCJ7ICc5NjBweCc6ICc5MHZ3JyB9XCJcbiAgc3R5bGVDbGFzcz1cInNwYXRpYWwtY29udHJvbHMtZGlhbG9nXCJcbj5cbiAgPCEtLSBObyBwb3J0IGJvdW5kOiBzYXkgd2h5IHJhdGhlciB0aGFuIHNob3dpbmcgY29udHJvbHMgdGhhdCBkbyBub3RoaW5nLiAtLT5cbiAgPGRpdiBjbGFzcz1cInNjLWVtcHR5XCIgKm5nSWY9XCIhY29udHJvbHNcIj5cbiAgICBObyBzcGF0aWFsLW9taWNzIGRhdGEgc291cmNlIGlzIGNvbmZpZ3VyZWQuIEEgaG9zdCBwcm92aWRlcyBvbmUgYnkgYmluZGluZ1xuICAgIDxjb2RlPlNQQVRJQUxfREFUQV9QT1JUPC9jb2RlPi5cbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cInNjLWVtcHR5XCIgKm5nSWY9XCJjb250cm9scyAmJiAhZGF0YXNldFwiPk5vIGRhdGFzZXQgaXMgbG9hZGVkLjwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJzYy1ib2R5XCIgKm5nSWY9XCJjb250cm9scyAmJiBkYXRhc2V0IGFzIGRzXCI+XG4gICAgPGRpdiBjbGFzcz1cInNjLWRhdGFzZXRcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwic2MtZGF0YXNldC1uYW1lXCI+e3sgZHMubmFtZSB9fTwvc3Bhbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwic2MtZGF0YXNldC1jb3VudFwiPnt7IGRzLm9ic2VydmF0aW9ucy5jb3VudCB8IG51bWJlciB9fSBvYnNlcnZhdGlvbnM8L3NwYW4+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIE9yZ2FuaXNlZCBhcyBYZW5pdW0gRXhwbG9yZXIncyBzaWRlIHBhbmVsOiBvbmUgY29sbGFwc2libGUgc2VjdGlvbiBwZXIgbGF5ZXIsXG4gICAgICAgICBlYWNoIHdpdGggaXRzIG93biBvbi9vZmYgc3dpdGNoIGluIHRoZSBoZWFkZXIuIC0tPlxuXG4gICAgPCEtLSBJbWFnZXMgLS0+XG4gICAgPGRpdiBjbGFzcz1cInNjLXBhbmVsXCIgKm5nSWY9XCJkcy5pbWFnZVJlZiAmJiAhaXMzZFwiIFtjbGFzcy5vcGVuXT1cIm9wZW4uaW1hZ2VzXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwic2MtcGFuZWwtaGVhZFwiIChjbGljayk9XCJ0b2dnbGVTZWN0aW9uKCdpbWFnZXMnKVwiPlxuICAgICAgICA8cC1jaGVja2JveFxuICAgICAgICAgIFtiaW5hcnldPVwidHJ1ZVwiXG4gICAgICAgICAgW25nTW9kZWxdPVwidmlldy5zaG93SW1hZ2VcIlxuICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgICAgIChvbkNoYW5nZSk9XCJvblNob3dJbWFnZSgkZXZlbnQuY2hlY2tlZClcIlxuICAgICAgICA+PC9wLWNoZWNrYm94PlxuICAgICAgICA8c3BhbiBjbGFzcz1cInNjLXBhbmVsLXRpdGxlXCI+SW1hZ2VzPC9zcGFuPlxuICAgICAgICA8aSBjbGFzcz1cInBpXCIgW2NsYXNzLnBpLWNoZXZyb24tZG93bl09XCJvcGVuLmltYWdlc1wiIFtjbGFzcy5waS1jaGV2cm9uLXJpZ2h0XT1cIiFvcGVuLmltYWdlc1wiPjwvaT5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cInNjLXBhbmVsLWJvZHlcIiAqbmdJZj1cIm9wZW4uaW1hZ2VzXCI+XG4gICAgICAgIDxzbWFsbCBjbGFzcz1cInNjLWhpbnRcIj4gQ2hhbm5lbHMsIGNvbG91cnMgYW5kIGNvbnRyYXN0IGFyZSBpbiB0aGUgQ2hhbm5lbHMgJmFtcDsgSGlzdG9ncmFtIGRpYWxvZy4gPC9zbWFsbD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBDZWxscyAtLT5cbiAgICA8c3BhdGlhbC1jZWxscy1wYW5lbFxuICAgICAgKm5nSWY9XCJoYXNDZWxscyAmJiAhaXMzZFwiXG4gICAgICBbY29udHJvbHNdPVwiY29udHJvbHNcIlxuICAgICAgW2RhdGFzZXRdPVwiZHNcIlxuICAgICAgW3ZpZXddPVwidmlld1wiXG4gICAgICBbZ2VuZXNdPVwiZ2VuZXNcIlxuICAgICAgW2NvbG9yQmFyQ3NzXT1cImNvbG9yQmFyQ3NzXCJcbiAgICAgIFtvcGVuXT1cIm9wZW4uY2VsbHNcIlxuICAgICAgKG9wZW5DaGFuZ2UpPVwic2V0T3BlbignY2VsbHMnLCAkZXZlbnQpXCJcbiAgICA+PC9zcGF0aWFsLWNlbGxzLXBhbmVsPlxuXG4gICAgPCEtLSBUcmFuc2NyaXB0cyAtLT5cbiAgICA8c3BhdGlhbC10cmFuc2NyaXB0cy1wYW5lbFxuICAgICAgKm5nSWY9XCJoYXNUcmFuc2NyaXB0cyAmJiAhaXMzZFwiXG4gICAgICBbY29udHJvbHNdPVwiY29udHJvbHNcIlxuICAgICAgW2RhdGFzZXRdPVwiZHNcIlxuICAgICAgW3ZpZXddPVwidmlld1wiXG4gICAgICBbZ2VuZXNdPVwiZ2VuZXNcIlxuICAgICAgW2VzdGltYXRlXT1cImVzdGltYXRlXCJcbiAgICAgIFtkZW5zaXR5U3RhdHNdPVwiZGVuc2l0eVN0YXRzXCJcbiAgICAgIFtnZW5lQ291bnRzXT1cImdlbmVDb3VudHNcIlxuICAgICAgW2NvbG9ybWFwT3B0aW9uc109XCJjb2xvcm1hcE9wdGlvbnNcIlxuICAgICAgW29wZW5dPVwib3Blbi50cmFuc2NyaXB0c1wiXG4gICAgICAob3BlbkNoYW5nZSk9XCJzZXRPcGVuKCd0cmFuc2NyaXB0cycsICRldmVudClcIlxuICAgID5cbiAgICA8L3NwYXRpYWwtdHJhbnNjcmlwdHMtcGFuZWw+XG5cbiAgICA8IS0tIEFubm90YXRpb25zOiB0aGUgZHJhd24gcmVnaW9ucywgYW5kIHNlbGVjdGluZyB3aGF0IHRoZXkgZW5jbG9zZS4gLS0+XG4gICAgPGRpdiBjbGFzcz1cInNjLXBhbmVsXCIgW2NsYXNzLm9wZW5dPVwib3Blbi5hbm5vdGF0aW9uc1wiPlxuICAgICAgPGRpdiBjbGFzcz1cInNjLXBhbmVsLWhlYWRcIiAoY2xpY2spPVwidG9nZ2xlU2VjdGlvbignYW5ub3RhdGlvbnMnKVwiPlxuICAgICAgICA8cC1jaGVja2JveFxuICAgICAgICAgIFtiaW5hcnldPVwidHJ1ZVwiXG4gICAgICAgICAgW25nTW9kZWxdPVwidmlldy5zaG93QW5ub3RhdGlvbnMgIT09IGZhbHNlXCJcbiAgICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAgICAob25DaGFuZ2UpPVwib25TaG93QW5ub3RhdGlvbnMoJGV2ZW50LmNoZWNrZWQpXCJcbiAgICAgICAgICBwVG9vbHRpcD1cIlNob3cgdGhlIGRyYXduIHJlZ2lvbnNcIlxuICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cInRvcFwiXG4gICAgICAgID48L3AtY2hlY2tib3g+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwic2MtcGFuZWwtdGl0bGVcIj5Bbm5vdGF0aW9uczwvc3Bhbj5cbiAgICAgICAgPGkgY2xhc3M9XCJwaVwiIFtjbGFzcy5waS1jaGV2cm9uLWRvd25dPVwib3Blbi5hbm5vdGF0aW9uc1wiIFtjbGFzcy5waS1jaGV2cm9uLXJpZ2h0XT1cIiFvcGVuLmFubm90YXRpb25zXCI+PC9pPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwic2MtcGFuZWwtYm9keVwiICpuZ0lmPVwib3Blbi5hbm5vdGF0aW9uc1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2Mtcm93XCI+XG4gICAgICAgICAgPHAtYnV0dG9uXG4gICAgICAgICAgICBsYWJlbD1cIlNlbGVjdCBmcm9tIFJPSXNcIlxuICAgICAgICAgICAgaWNvbj1cInBpIHBpLW9iamVjdC1ncm91cFwiXG4gICAgICAgICAgICBzaXplPVwic21hbGxcIlxuICAgICAgICAgICAgW291dGxpbmVkXT1cInRydWVcIlxuICAgICAgICAgICAgW2xvYWRpbmddPVwic2VsZWN0aW5nRnJvbVJlZ2lvbnNcIlxuICAgICAgICAgICAgKG9uQ2xpY2spPVwic2VsZWN0RnJvbVJlZ2lvbnMoKVwiXG4gICAgICAgICAgICBbcFRvb2x0aXBdPVwiXG4gICAgICAgICAgICAgIHNlbGVjdHNDbGFzc1ZvbHVtZXNcbiAgICAgICAgICAgICAgICA/ICdTZWxlY3QgZXZlcnkgb2JzZXJ2YXRpb24gaW5zaWRlIHRoZSB2b2x1bWVzIG9mIHRoZSBjbGFzc2VzIHBpY2tlZCBpbiB0aGUgUmVnaW9uIEVkaXRvcidcbiAgICAgICAgICAgICAgICA6ICdTZWxlY3QgZXZlcnkgb2JzZXJ2YXRpb24gaW5zaWRlIHRoZSBkcmF3biByZWdpb25zJ1xuICAgICAgICAgICAgXCJcbiAgICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cInRvcFwiXG4gICAgICAgICAgPjwvcC1idXR0b24+XG4gICAgICAgICAgPHAtYnV0dG9uXG4gICAgICAgICAgICAqbmdJZj1cImhhc1NlbGVjdGlvblwiXG4gICAgICAgICAgICBsYWJlbD1cIkNsZWFyXCJcbiAgICAgICAgICAgIHNpemU9XCJzbWFsbFwiXG4gICAgICAgICAgICBbdGV4dF09XCJ0cnVlXCJcbiAgICAgICAgICAgIChvbkNsaWNrKT1cImNsZWFyU2VsZWN0aW9uKClcIlxuICAgICAgICAgID48L3AtYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPHNtYWxsIGNsYXNzPVwic2MtaGludFwiICpuZ0lmPVwiaGFzU2VsZWN0aW9uXCI+XG4gICAgICAgICAge3sgc2VsZWN0aW9uLmNvdW50IHwgbnVtYmVyIH19IG9mIHt7IGRzLm9ic2VydmF0aW9ucy5jb3VudCB8IG51bWJlciB9fSBzZWxlY3RlZCDigJQgdGhlIHJlc3QgYXJlIG11dGVkLlxuICAgICAgICA8L3NtYWxsPlxuICAgICAgICA8c21hbGwgY2xhc3M9XCJzYy1oaW50XCIgKm5nSWY9XCJzZWxlY3Rpb25NaXNzZWRcIj5cbiAgICAgICAgICBObyBvYnNlcnZhdGlvbnMgZmVsbCBpbnNpZGUgdGhlXG4gICAgICAgICAge3sgbWlzc2VkTW9kZSA9PT0gJ2NsYXNzLXZvbHVtZXMnID8gJ3BpY2tlZCBjbGFzc2VzJyA6ICdkcmF3biByZWdpb25zJyB9fS5cbiAgICAgICAgPC9zbWFsbD5cbiAgICAgICAgPHNtYWxsIGNsYXNzPVwic2MtaGludFwiICpuZ0lmPVwic2VsZWN0c0NsYXNzVm9sdW1lc1wiPlxuICAgICAgICAgIFNlbGVjdHMgaW5zaWRlIHRoZSB2b2x1bWUgb2Yge3sgcGlja2VkQ2xhc3Nlc1swXVxuICAgICAgICAgIH19e3sgcGlja2VkQ2xhc3Nlcy5sZW5ndGggPiAxID8gJyBhbmQgJyArIChwaWNrZWRDbGFzc2VzLmxlbmd0aCAtIDEgfCBudW1iZXIpICsgJyBtb3JlIGNsYXNzZXMnIDogJycgfX0sXG4gICAgICAgICAgcGlja2VkIGluIHRoZSBSZWdpb24gRWRpdG9yLiBEcmF3IGEgcmVnaW9uIHRvIHNlbGVjdCBieSBpdCBpbnN0ZWFkLlxuICAgICAgICA8L3NtYWxsPlxuICAgICAgICA8c21hbGwgY2xhc3M9XCJzYy1oaW50XCIgKm5nSWY9XCJpczNkICYmICFzZWxlY3RzQ2xhc3NWb2x1bWVzICYmIHBpY2tlZENsYXNzZXMubGVuZ3RoXCI+XG4gICAgICAgICAgVGhlIGNsYXNzZXMgcGlja2VkIGluIHRoZSBSZWdpb24gRWRpdG9yIGFyZSBub3Qgb24gdGhlIHJlZmVyZW5jZSB2b2x1bWUgc2hvd24gaGVyZSwgc28gdGhpcyBzZWxlY3RzIGJ5XG4gICAgICAgICAgdGhlIHJlZ2lvbnMgZHJhd24gb3ZlciB0aGUgY2xvdWQgaW5zdGVhZC5cbiAgICAgICAgPC9zbWFsbD5cbiAgICAgICAgPHNtYWxsIGNsYXNzPVwic2MtaGludFwiICpuZ0lmPVwiaXMzZCAmJiAhc2VsZWN0c0NsYXNzVm9sdW1lc1wiPlxuICAgICAgICAgIEluIDNEIGEgcmVnaW9uIGN1dHMgdGhyb3VnaCB0aGUgY2xvdWQncyBmdWxsIGRlcHRoLiBPcmJpdCBhbmQgZHJhdyBhZ2FpbiB0byBjdXQgZnJvbSBhbm90aGVyIGFuZ2xlLlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhcGlja2VkQ2xhc3Nlcy5sZW5ndGhcIj5cbiAgICAgICAgICAgIFBpY2sgY2xhc3NlcyBpbiB0aGUgUmVnaW9uIEVkaXRvcidzIGNsYXNzIHRyZWUgdG8gc2VsZWN0IGluc2lkZSB0aGVpciB2b2x1bWVzLlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L3NtYWxsPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIE9ic2VydmF0aW9ucywgdGhlbiB3aGF0IGVsc2UgZHJhd3MgdGhlbTogdGhlIGdlbmUgbWFwLCB0aGUgM0Qgc2NlbmUsIGFuZCB0aGVcbiAgICAgICAgIGNvbnRpbnVvdXMtb25seSBrbm9icy4gLS0+XG4gICAgPHNwYXRpYWwtb2JzZXJ2YXRpb25zLXBhbmVsXG4gICAgICBbY29udHJvbHNdPVwiY29udHJvbHNcIlxuICAgICAgW2RhdGFzZXRdPVwiZHNcIlxuICAgICAgW3ZpZXddPVwidmlld1wiXG4gICAgICBbZ2VuZXNdPVwiZ2VuZXNcIlxuICAgICAgW2xlZ2VuZF09XCJsZWdlbmRcIlxuICAgICAgW2NvbG9yQmFyQ3NzXT1cImNvbG9yQmFyQ3NzXCJcbiAgICAgIFtzZWxlY3Rpb25dPVwic2VsZWN0aW9uXCJcbiAgICAgIFtzZWxlY3RlZENhdGVnb3J5XT1cInNlbGVjdGVkQ2F0ZWdvcnlcIlxuICAgICAgW2NvbG9ybWFwT3B0aW9uc109XCJjb2xvcm1hcE9wdGlvbnNcIlxuICAgICAgW2lzM2RdPVwiaXMzZFwiXG4gICAgICBbb3Blbl09XCJvcGVuLm9ic2VydmF0aW9uc1wiXG4gICAgICAob3BlbkNoYW5nZSk9XCJzZXRPcGVuKCdvYnNlcnZhdGlvbnMnLCAkZXZlbnQpXCJcbiAgICAgIChjYXRlZ29yeUNsaWNrZWQpPVwic2VsZWN0Q2F0ZWdvcnkoJGV2ZW50KVwiXG4gICAgPjwvc3BhdGlhbC1vYnNlcnZhdGlvbnMtcGFuZWw+XG5cbiAgICA8IS0tIERpc3RyaWJ1dGlvbnMgb2Ygd2hhdGV2ZXIgdGhlIG1hcCBpcyBjb2xvdXJlZCBieS4gSW4gdGhlIFNBTUUgZGlhbG9nIGFzXG4gICAgICAgICB0aGUgY29sb3VyIGNvbnRyb2xzIG9uIHB1cnBvc2U6IGNoYW5naW5nIHRoZSBnZW5lIGFuZCB3YXRjaGluZyB0aGVcbiAgICAgICAgIGRpc3RyaWJ1dGlvbiBtb3ZlIGlzIG9uZSBhY3Rpb24sIGFuZCB0d28gZmxvYXRpbmcgd2luZG93cyBtYWRlIHRoYXRcbiAgICAgICAgIGhhcmRlciB0byBzZWUgcmF0aGVyIHRoYW4gZWFzaWVyLiAtLT5cbiAgICA8ZGl2IGNsYXNzPVwic2Mtc2VjdGlvbiBzYy1jaGFydHNcIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIGNsYXNzPVwic2MtZGlzY2xvc3VyZVwiXG4gICAgICAgIChjbGljayk9XCJ0b2dnbGVDaGFydHMoKVwiXG4gICAgICAgIFthdHRyLmFyaWEtZXhwYW5kZWRdPVwiY2hhcnRzT3BlblwiXG4gICAgICAgIFthdHRyLmFyaWEtY29udHJvbHNdPVwiY2hhcnRzQm9keUlkXCJcbiAgICAgID5cbiAgICAgICAgPGkgY2xhc3M9XCJwaVwiIFtjbGFzcy5waS1jaGV2cm9uLXJpZ2h0XT1cIiFjaGFydHNPcGVuXCIgW2NsYXNzLnBpLWNoZXZyb24tZG93bl09XCJjaGFydHNPcGVuXCI+PC9pPlxuICAgICAgICA8c3Bhbj5EaXN0cmlidXRpb248L3NwYW4+XG4gICAgICAgIDxzbWFsbCAqbmdJZj1cIiFjaGFydHNPcGVuICYmIHZpZXcuY29sb3JCeVwiPm9mIHt7IGNvbG9yQnlMYWJlbCB9fTwvc21hbGw+XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDwhLS0gS2VwdCBNT1VOVEVEIHdoZW4gY29sbGFwc2VkLCBvbmx5IGhpZGRlbjogZGVzdHJveWluZyBpdCB3b3VsZCB0aHJvd1xuICAgICAgICAgICBhd2F5IHRoZSBjaGFydCBraW5kIGFuZCBncm91cGluZyB0aGUgdXNlciBwaWNrZWQuIGBhY3RpdmVgIGlzIHdoYXRcbiAgICAgICAgICAgc3RvcHMgaXQgZHJhd2luZyB3aGlsZSBpdCBoYXMgbm8gc2l6ZS4gLS0+XG4gICAgICA8ZGl2IFtpZF09XCJjaGFydHNCb2R5SWRcIiBbaGlkZGVuXT1cIiFjaGFydHNPcGVuXCI+XG4gICAgICAgIDxzcGF0aWFsLWNoYXJ0cyBbYWN0aXZlXT1cInZpc2libGUgJiYgY2hhcnRzT3BlblwiPjwvc3BhdGlhbC1jaGFydHM+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJzYy1idG5zXCI+XG4gICAgICA8cC1idXR0b24gbGFiZWw9XCJSZXNldFwiIHNpemU9XCJzbWFsbFwiIFt0ZXh0XT1cInRydWVcIiAob25DbGljayk9XCJyZXNldCgpXCI+PC9wLWJ1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L3AtZGlhbG9nPlxuIl19
@@ -6,13 +6,26 @@ import { BehaviorSubject } from 'rxjs';
6
6
  * owner calls {@link sync} once the region array it projects onto is final,
7
7
  * which prunes ids that no longer exist and emits {@link indices$} only when
8
8
  * the index set changed.
9
+ *
10
+ * A selection made by picking classes (the class tree, a surface in 3D) also
11
+ * holds those classes: a class is a volume through the whole stack, whether or
12
+ * not it has a region on the slice. Any other selection drops them; an edit
13
+ * ({@link retain}, {@link sync}) keeps them.
9
14
  */
10
15
  export class RegionSelection {
11
16
  constructor() {
12
17
  this.selected = [];
18
+ this.picked = [];
13
19
  this.indicesSubject = new BehaviorSubject([]);
20
+ this.classesSubject = new BehaviorSubject([]);
14
21
  /** The selected regions' current array indices (emits on change only). */
15
22
  this.indices$ = this.indicesSubject.asObservable();
23
+ /** The classes the selection was picked as ([] for any other selection; emits on change only). */
24
+ this.classes$ = this.classesSubject.asObservable();
25
+ }
26
+ /** The classes the selection was picked as, as last emitted by {@link sync}. */
27
+ get classes() {
28
+ return this.classesSubject.value;
16
29
  }
17
30
  /** The selected indices as last projected by {@link sync}. */
18
31
  get indices() {
@@ -22,9 +35,10 @@ export class RegionSelection {
22
35
  get ids() {
23
36
  return this.selected;
24
37
  }
25
- /** Replace the selected ids (no emit until {@link sync}). */
26
- replace(ids) {
38
+ /** Replace the selected ids, picked as `classes` if they were (no emit until {@link sync}). */
39
+ replace(ids, classes = []) {
27
40
  this.selected = ids.slice();
41
+ this.picked = classes.slice();
28
42
  }
29
43
  /** Keep only the ids `keep` accepts (no emit until {@link sync}). */
30
44
  retain(keep) {
@@ -47,10 +61,11 @@ export class RegionSelection {
47
61
  }
48
62
  }
49
63
  this.selected = ids;
64
+ this.picked = [];
50
65
  this.sync(regions);
51
66
  }
52
67
  /** Project the selected ids onto `regions`, pruning ids it no longer holds,
53
- * and emit if the index set changed. */
68
+ * and emit if the index set (or the picked classes) changed. */
54
69
  sync(regions) {
55
70
  const indexOf = new Map();
56
71
  regions.forEach((r, i) => {
@@ -69,6 +84,8 @@ export class RegionSelection {
69
84
  this.selected = live;
70
85
  if (!sameIndices(this.indicesSubject.value, indices))
71
86
  this.indicesSubject.next(indices);
87
+ if (!sameIndices(this.classesSubject.value, this.picked))
88
+ this.classesSubject.next(this.picked);
72
89
  }
73
90
  }
74
91
  function sameIndices(a, b) {
@@ -79,4 +96,4 @@ function sameIndices(a, b) {
79
96
  return false;
80
97
  return true;
81
98
  }
82
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaW9uLXNlbGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvc3RvcmUvcmVnaW9uLXNlbGVjdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsZUFBZSxFQUFjLE1BQU0sTUFBTSxDQUFDO0FBT25EOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLE9BQU8sZUFBZTtJQUE1QjtRQUNVLGFBQVEsR0FBYSxFQUFFLENBQUM7UUFDZixtQkFBYyxHQUFHLElBQUksZUFBZSxDQUFXLEVBQUUsQ0FBQyxDQUFDO1FBRXBFLDBFQUEwRTtRQUNqRSxhQUFRLEdBQXlCLElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxFQUFFLENBQUM7SUE0RC9FLENBQUM7SUExREMsOERBQThEO0lBQzlELElBQUksT0FBTztRQUNULE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUM7SUFDbkMsQ0FBQztJQUVELDRDQUE0QztJQUM1QyxJQUFJLEdBQUc7UUFDTCxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUM7SUFDdkIsQ0FBQztJQUVELDZEQUE2RDtJQUM3RCxPQUFPLENBQUMsR0FBYTtRQUNuQixJQUFJLENBQUMsUUFBUSxHQUFHLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUM5QixDQUFDO0lBRUQscUVBQXFFO0lBQ3JFLE1BQU0sQ0FBQyxJQUE2QjtRQUNsQyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFRDs7O09BR0c7SUFDSCxhQUFhLENBQUMsT0FBaUIsRUFBRSxPQUF5QjtRQUN4RCxNQUFNLEdBQUcsR0FBYSxFQUFFLENBQUM7UUFDekIsTUFBTSxJQUFJLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztRQUMvQixLQUFLLE1BQU0sQ0FBQyxJQUFJLE9BQU8sSUFBSSxFQUFFLEVBQUUsQ0FBQztZQUM5QixJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxPQUFPLENBQUMsTUFBTTtnQkFBRSxTQUFTO1lBQ2xFLE1BQU0sRUFBRSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDekIsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztnQkFDbEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDYixHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2YsQ0FBQztRQUNILENBQUM7UUFDRCxJQUFJLENBQUMsUUFBUSxHQUFHLEdBQUcsQ0FBQztRQUNwQixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3JCLENBQUM7SUFFRDs2Q0FDeUM7SUFDekMsSUFBSSxDQUFDLE9BQXlCO1FBQzVCLE1BQU0sT0FBTyxHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO1FBQzFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDdkIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDL0MsQ0FBQyxDQUFDLENBQUM7UUFDSCxNQUFNLE9BQU8sR0FBYSxFQUFFLENBQUM7UUFDN0IsTUFBTSxJQUFJLEdBQWEsRUFBRSxDQUFDO1FBQzFCLEtBQUssTUFBTSxFQUFFLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQy9CLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDNUIsSUFBSSxHQUFHLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3RCLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ2xCLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDaEIsQ0FBQztRQUNILENBQUM7UUFDRCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztRQUNyQixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQztZQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzFGLENBQUM7Q0FDRjtBQUVELFNBQVMsV0FBVyxDQUFDLENBQVcsRUFBRSxDQUFXO0lBQzNDLElBQUksQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUMsTUFBTTtRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQ3hDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRTtRQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFBRSxPQUFPLEtBQUssQ0FBQztJQUNuRSxPQUFPLElBQUksQ0FBQztBQUNkLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcblxuLyoqIFRoZSBwYXJ0IG9mIGEgcmVnaW9uIHRoZSBzZWxlY3Rpb24gcmVhZHM6IGl0cyBzdGFibGUgaWQuICovXG5pbnRlcmZhY2UgSGFzSWQge1xuICBpZDogbnVtYmVyO1xufVxuXG4vKipcbiAqIFJlZ2lvbiBzZWxlY3Rpb24sIGhlbGQgYnkgcmVnaW9uICppZCogKHN0YWJsZSBhY3Jvc3MgZWRpdHMsIHJlb3JkZXJzIGFuZFxuICogZGVsZXRlL2FkZCBjeWNsZXMpIGFuZCBwcm9qZWN0ZWQgdG8gYXJyYXkgaW5kaWNlcyBmb3IgdGhlIElSZWdpb25TdG9yZVxuICogYm91bmRhcnkuIENoYW5naW5nIHRoZSBpZHMgKHtAbGluayByZXBsYWNlfSwge0BsaW5rIHJldGFpbn0pIGlzIHNpbGVudDsgdGhlXG4gKiBvd25lciBjYWxscyB7QGxpbmsgc3luY30gb25jZSB0aGUgcmVnaW9uIGFycmF5IGl0IHByb2plY3RzIG9udG8gaXMgZmluYWwsXG4gKiB3aGljaCBwcnVuZXMgaWRzIHRoYXQgbm8gbG9uZ2VyIGV4aXN0IGFuZCBlbWl0cyB7QGxpbmsgaW5kaWNlcyR9IG9ubHkgd2hlblxuICogdGhlIGluZGV4IHNldCBjaGFuZ2VkLlxuICovXG5leHBvcnQgY2xhc3MgUmVnaW9uU2VsZWN0aW9uIHtcbiAgcHJpdmF0ZSBzZWxlY3RlZDogbnVtYmVyW10gPSBbXTtcbiAgcHJpdmF0ZSByZWFkb25seSBpbmRpY2VzU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8bnVtYmVyW10+KFtdKTtcblxuICAvKiogVGhlIHNlbGVjdGVkIHJlZ2lvbnMnIGN1cnJlbnQgYXJyYXkgaW5kaWNlcyAoZW1pdHMgb24gY2hhbmdlIG9ubHkpLiAqL1xuICByZWFkb25seSBpbmRpY2VzJDogT2JzZXJ2YWJsZTxudW1iZXJbXT4gPSB0aGlzLmluZGljZXNTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIC8qKiBUaGUgc2VsZWN0ZWQgaW5kaWNlcyBhcyBsYXN0IHByb2plY3RlZCBieSB7QGxpbmsgc3luY30uICovXG4gIGdldCBpbmRpY2VzKCk6IG51bWJlcltdIHtcbiAgICByZXR1cm4gdGhpcy5pbmRpY2VzU3ViamVjdC52YWx1ZTtcbiAgfVxuXG4gIC8qKiBUaGUgc2VsZWN0ZWQgaWRzLCBpbiBzZWxlY3Rpb24gb3JkZXIuICovXG4gIGdldCBpZHMoKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdGVkO1xuICB9XG5cbiAgLyoqIFJlcGxhY2UgdGhlIHNlbGVjdGVkIGlkcyAobm8gZW1pdCB1bnRpbCB7QGxpbmsgc3luY30pLiAqL1xuICByZXBsYWNlKGlkczogbnVtYmVyW10pOiB2b2lkIHtcbiAgICB0aGlzLnNlbGVjdGVkID0gaWRzLnNsaWNlKCk7XG4gIH1cblxuICAvKiogS2VlcCBvbmx5IHRoZSBpZHMgYGtlZXBgIGFjY2VwdHMgKG5vIGVtaXQgdW50aWwge0BsaW5rIHN5bmN9KS4gKi9cbiAgcmV0YWluKGtlZXA6IChpZDogbnVtYmVyKSA9PiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3RlZCA9IHRoaXMuc2VsZWN0ZWQuZmlsdGVyKGtlZXApO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlbGVjdCBieSBhcnJheSBpbmRleCBpbnRvIGByZWdpb25zYDogaW52YWxpZCBhbmQgZHVwbGljYXRlIGluZGljZXMgYXJlXG4gICAqIGRyb3BwZWQsIHRoZSBnaXZlbiBvcmRlciBpcyBrZXB0LiBQcm9qZWN0cyBhbmQgZW1pdHMuXG4gICAqL1xuICBzZWxlY3RJbmRpY2VzKGluZGljZXM6IG51bWJlcltdLCByZWdpb25zOiByZWFkb25seSBIYXNJZFtdKTogdm9pZCB7XG4gICAgY29uc3QgaWRzOiBudW1iZXJbXSA9IFtdO1xuICAgIGNvbnN0IHNlZW4gPSBuZXcgU2V0PG51bWJlcj4oKTtcbiAgICBmb3IgKGNvbnN0IGkgb2YgaW5kaWNlcyB8fCBbXSkge1xuICAgICAgaWYgKCFOdW1iZXIuaXNGaW5pdGUoaSkgfHwgaSA8IDAgfHwgaSA+PSByZWdpb25zLmxlbmd0aCkgY29udGludWU7XG4gICAgICBjb25zdCBpZCA9IHJlZ2lvbnNbaV0uaWQ7XG4gICAgICBpZiAoIXNlZW4uaGFzKGlkKSkge1xuICAgICAgICBzZWVuLmFkZChpZCk7XG4gICAgICAgIGlkcy5wdXNoKGlkKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5zZWxlY3RlZCA9IGlkcztcbiAgICB0aGlzLnN5bmMocmVnaW9ucyk7XG4gIH1cblxuICAvKiogUHJvamVjdCB0aGUgc2VsZWN0ZWQgaWRzIG9udG8gYHJlZ2lvbnNgLCBwcnVuaW5nIGlkcyBpdCBubyBsb25nZXIgaG9sZHMsXG4gICAqICBhbmQgZW1pdCBpZiB0aGUgaW5kZXggc2V0IGNoYW5nZWQuICovXG4gIHN5bmMocmVnaW9uczogcmVhZG9ubHkgSGFzSWRbXSk6IHZvaWQge1xuICAgIGNvbnN0IGluZGV4T2YgPSBuZXcgTWFwPG51bWJlciwgbnVtYmVyPigpO1xuICAgIHJlZ2lvbnMuZm9yRWFjaCgociwgaSkgPT4ge1xuICAgICAgaWYgKCFpbmRleE9mLmhhcyhyLmlkKSkgaW5kZXhPZi5zZXQoci5pZCwgaSk7XG4gICAgfSk7XG4gICAgY29uc3QgaW5kaWNlczogbnVtYmVyW10gPSBbXTtcbiAgICBjb25zdCBsaXZlOiBudW1iZXJbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgaWQgb2YgdGhpcy5zZWxlY3RlZCkge1xuICAgICAgY29uc3QgaWR4ID0gaW5kZXhPZi5nZXQoaWQpO1xuICAgICAgaWYgKGlkeCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGluZGljZXMucHVzaChpZHgpO1xuICAgICAgICBsaXZlLnB1c2goaWQpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnNlbGVjdGVkID0gbGl2ZTtcbiAgICBpZiAoIXNhbWVJbmRpY2VzKHRoaXMuaW5kaWNlc1N1YmplY3QudmFsdWUsIGluZGljZXMpKSB0aGlzLmluZGljZXNTdWJqZWN0Lm5leHQoaW5kaWNlcyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2FtZUluZGljZXMoYTogbnVtYmVyW10sIGI6IG51bWJlcltdKTogYm9vbGVhbiB7XG4gIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHJldHVybiBmYWxzZTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKSBpZiAoYVtpXSAhPT0gYltpXSkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gdHJ1ZTtcbn1cbiJdfQ==
99
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaW9uLXNlbGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvc3RvcmUvcmVnaW9uLXNlbGVjdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsZUFBZSxFQUFjLE1BQU0sTUFBTSxDQUFDO0FBT25EOzs7Ozs7Ozs7Ozs7R0FZRztBQUNILE1BQU0sT0FBTyxlQUFlO0lBQTVCO1FBQ1UsYUFBUSxHQUFhLEVBQUUsQ0FBQztRQUN4QixXQUFNLEdBQXNCLEVBQUUsQ0FBQztRQUN0QixtQkFBYyxHQUFHLElBQUksZUFBZSxDQUFXLEVBQUUsQ0FBQyxDQUFDO1FBQ25ELG1CQUFjLEdBQUcsSUFBSSxlQUFlLENBQW9CLEVBQUUsQ0FBQyxDQUFDO1FBRTdFLDBFQUEwRTtRQUNqRSxhQUFRLEdBQXlCLElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxFQUFFLENBQUM7UUFFN0Usa0dBQWtHO1FBQ3pGLGFBQVEsR0FBa0MsSUFBSSxDQUFDLGNBQWMsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQW9FeEYsQ0FBQztJQWxFQyxnRkFBZ0Y7SUFDaEYsSUFBSSxPQUFPO1FBQ1QsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQztJQUNuQyxDQUFDO0lBRUQsOERBQThEO0lBQzlELElBQUksT0FBTztRQUNULE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUM7SUFDbkMsQ0FBQztJQUVELDRDQUE0QztJQUM1QyxJQUFJLEdBQUc7UUFDTCxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUM7SUFDdkIsQ0FBQztJQUVELCtGQUErRjtJQUMvRixPQUFPLENBQUMsR0FBYSxFQUFFLFVBQTZCLEVBQUU7UUFDcEQsSUFBSSxDQUFDLFFBQVEsR0FBRyxHQUFHLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDNUIsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7SUFD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SUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUFFLE9BQU8sS0FBSyxDQUFDO0lBQ25FLE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuXG4vKiogVGhlIHBhcnQgb2YgYSByZWdpb24gdGhlIHNlbGVjdGlvbiByZWFkczogaXRzIHN0YWJsZSBpZC4gKi9cbmludGVyZmFjZSBIYXNJZCB7XG4gIGlkOiBudW1iZXI7XG59XG5cbi8qKlxuICogUmVnaW9uIHNlbGVjdGlvbiwgaGVsZCBieSByZWdpb24gKmlkKiAoc3RhYmxlIGFjcm9zcyBlZGl0cywgcmVvcmRlcnMgYW5kXG4gKiBkZWxldGUvYWRkIGN5Y2xlcykgYW5kIHByb2plY3RlZCB0byBhcnJheSBpbmRpY2VzIGZvciB0aGUgSVJlZ2lvblN0b3JlXG4gKiBib3VuZGFyeS4gQ2hhbmdpbmcgdGhlIGlkcyAoe0BsaW5rIHJlcGxhY2V9LCB7QGxpbmsgcmV0YWlufSkgaXMgc2lsZW50OyB0aGVcbiAqIG93bmVyIGNhbGxzIHtAbGluayBzeW5jfSBvbmNlIHRoZSByZWdpb24gYXJyYXkgaXQgcHJvamVjdHMgb250byBpcyBmaW5hbCxcbiAqIHdoaWNoIHBydW5lcyBpZHMgdGhhdCBubyBsb25nZXIgZXhpc3QgYW5kIGVtaXRzIHtAbGluayBpbmRpY2VzJH0gb25seSB3aGVuXG4gKiB0aGUgaW5kZXggc2V0IGNoYW5nZWQuXG4gKlxuICogQSBzZWxlY3Rpb24gbWFkZSBieSBwaWNraW5nIGNsYXNzZXMgKHRoZSBjbGFzcyB0cmVlLCBhIHN1cmZhY2UgaW4gM0QpIGFsc29cbiAqIGhvbGRzIHRob3NlIGNsYXNzZXM6IGEgY2xhc3MgaXMgYSB2b2x1bWUgdGhyb3VnaCB0aGUgd2hvbGUgc3RhY2ssIHdoZXRoZXIgb3JcbiAqIG5vdCBpdCBoYXMgYSByZWdpb24gb24gdGhlIHNsaWNlLiBBbnkgb3RoZXIgc2VsZWN0aW9uIGRyb3BzIHRoZW07IGFuIGVkaXRcbiAqICh7QGxpbmsgcmV0YWlufSwge0BsaW5rIHN5bmN9KSBrZWVwcyB0aGVtLlxuICovXG5leHBvcnQgY2xhc3MgUmVnaW9uU2VsZWN0aW9uIHtcbiAgcHJpdmF0ZSBzZWxlY3RlZDogbnVtYmVyW10gPSBbXTtcbiAgcHJpdmF0ZSBwaWNrZWQ6IHJlYWRvbmx5IHN0cmluZ1tdID0gW107XG4gIHByaXZhdGUgcmVhZG9ubHkgaW5kaWNlc1N1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcltdPihbXSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2xhc3Nlc1N1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PHJlYWRvbmx5IHN0cmluZ1tdPihbXSk7XG5cbiAgLyoqIFRoZSBzZWxlY3RlZCByZWdpb25zJyBjdXJyZW50IGFycmF5IGluZGljZXMgKGVtaXRzIG9uIGNoYW5nZSBvbmx5KS4gKi9cbiAgcmVhZG9ubHkgaW5kaWNlcyQ6IE9ic2VydmFibGU8bnVtYmVyW10+ID0gdGhpcy5pbmRpY2VzU3ViamVjdC5hc09ic2VydmFibGUoKTtcblxuICAvKiogVGhlIGNsYXNzZXMgdGhlIHNlbGVjdGlvbiB3YXMgcGlja2VkIGFzIChbXSBmb3IgYW55IG90aGVyIHNlbGVjdGlvbjsgZW1pdHMgb24gY2hhbmdlIG9ubHkpLiAqL1xuICByZWFkb25seSBjbGFzc2VzJDogT2JzZXJ2YWJsZTxyZWFkb25seSBzdHJpbmdbXT4gPSB0aGlzLmNsYXNzZXNTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIC8qKiBUaGUgY2xhc3NlcyB0aGUgc2VsZWN0aW9uIHdhcyBwaWNrZWQgYXMsIGFzIGxhc3QgZW1pdHRlZCBieSB7QGxpbmsgc3luY30uICovXG4gIGdldCBjbGFzc2VzKCk6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5jbGFzc2VzU3ViamVjdC52YWx1ZTtcbiAgfVxuXG4gIC8qKiBUaGUgc2VsZWN0ZWQgaW5kaWNlcyBhcyBsYXN0IHByb2plY3RlZCBieSB7QGxpbmsgc3luY30uICovXG4gIGdldCBpbmRpY2VzKCk6IG51bWJlcltdIHtcbiAgICByZXR1cm4gdGhpcy5pbmRpY2VzU3ViamVjdC52YWx1ZTtcbiAgfVxuXG4gIC8qKiBUaGUgc2VsZWN0ZWQgaWRzLCBpbiBzZWxlY3Rpb24gb3JkZXIuICovXG4gIGdldCBpZHMoKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdGVkO1xuICB9XG5cbiAgLyoqIFJlcGxhY2UgdGhlIHNlbGVjdGVkIGlkcywgcGlja2VkIGFzIGBjbGFzc2VzYCBpZiB0aGV5IHdlcmUgKG5vIGVtaXQgdW50aWwge0BsaW5rIHN5bmN9KS4gKi9cbiAgcmVwbGFjZShpZHM6IG51bWJlcltdLCBjbGFzc2VzOiByZWFkb25seSBzdHJpbmdbXSA9IFtdKTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3RlZCA9IGlkcy5zbGljZSgpO1xuICAgIHRoaXMucGlja2VkID0gY2xhc3Nlcy5zbGljZSgpO1xuICB9XG5cbiAgLyoqIEtlZXAgb25seSB0aGUgaWRzIGBrZWVwYCBhY2NlcHRzIChubyBlbWl0IHVudGlsIHtAbGluayBzeW5jfSkuICovXG4gIHJldGFpbihrZWVwOiAoaWQ6IG51bWJlcikgPT4gYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuc2VsZWN0ZWQgPSB0aGlzLnNlbGVjdGVkLmZpbHRlcihrZWVwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZWxlY3QgYnkgYXJyYXkgaW5kZXggaW50byBgcmVnaW9uc2A6IGludmFsaWQgYW5kIGR1cGxpY2F0ZSBpbmRpY2VzIGFyZVxuICAgKiBkcm9wcGVkLCB0aGUgZ2l2ZW4gb3JkZXIgaXMga2VwdC4gUHJvamVjdHMgYW5kIGVtaXRzLlxuICAgKi9cbiAgc2VsZWN0SW5kaWNlcyhpbmRpY2VzOiBudW1iZXJbXSwgcmVnaW9uczogcmVhZG9ubHkgSGFzSWRbXSk6IHZvaWQge1xuICAgIGNvbnN0IGlkczogbnVtYmVyW10gPSBbXTtcbiAgICBjb25zdCBzZWVuID0gbmV3IFNldDxudW1iZXI+KCk7XG4gICAgZm9yIChjb25zdCBpIG9mIGluZGljZXMgfHwgW10pIHtcbiAgICAgIGlmICghTnVtYmVyLmlzRmluaXRlKGkpIHx8IGkgPCAwIHx8IGkgPj0gcmVnaW9ucy5sZW5ndGgpIGNvbnRpbnVlO1xuICAgICAgY29uc3QgaWQgPSByZWdpb25zW2ldLmlkO1xuICAgICAgaWYgKCFzZWVuLmhhcyhpZCkpIHtcbiAgICAgICAgc2Vlbi5hZGQoaWQpO1xuICAgICAgICBpZHMucHVzaChpZCk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuc2VsZWN0ZWQgPSBpZHM7XG4gICAgdGhpcy5waWNrZWQgPSBbXTtcbiAgICB0aGlzLnN5bmMocmVnaW9ucyk7XG4gIH1cblxuICAvKiogUHJvamVjdCB0aGUgc2VsZWN0ZWQgaWRzIG9udG8gYHJlZ2lvbnNgLCBwcnVuaW5nIGlkcyBpdCBubyBsb25nZXIgaG9sZHMsXG4gICAqICBhbmQgZW1pdCBpZiB0aGUgaW5kZXggc2V0IChvciB0aGUgcGlja2VkIGNsYXNzZXMpIGNoYW5nZWQuICovXG4gIHN5bmMocmVnaW9uczogcmVhZG9ubHkgSGFzSWRbXSk6IHZvaWQge1xuICAgIGNvbnN0IGluZGV4T2YgPSBuZXcgTWFwPG51bWJlciwgbnVtYmVyPigpO1xuICAgIHJlZ2lvbnMuZm9yRWFjaCgociwgaSkgPT4ge1xuICAgICAgaWYgKCFpbmRleE9mLmhhcyhyLmlkKSkgaW5kZXhPZi5zZXQoci5pZCwgaSk7XG4gICAgfSk7XG4gICAgY29uc3QgaW5kaWNlczogbnVtYmVyW10gPSBbXTtcbiAgICBjb25zdCBsaXZlOiBudW1iZXJbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgaWQgb2YgdGhpcy5zZWxlY3RlZCkge1xuICAgICAgY29uc3QgaWR4ID0gaW5kZXhPZi5nZXQoaWQpO1xuICAgICAgaWYgKGlkeCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGluZGljZXMucHVzaChpZHgpO1xuICAgICAgICBsaXZlLnB1c2goaWQpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnNlbGVjdGVkID0gbGl2ZTtcbiAgICBpZiAoIXNhbWVJbmRpY2VzKHRoaXMuaW5kaWNlc1N1YmplY3QudmFsdWUsIGluZGljZXMpKSB0aGlzLmluZGljZXNTdWJqZWN0Lm5leHQoaW5kaWNlcyk7XG4gICAgaWYgKCFzYW1lSW5kaWNlcyh0aGlzLmNsYXNzZXNTdWJqZWN0LnZhbHVlLCB0aGlzLnBpY2tlZCkpIHRoaXMuY2xhc3Nlc1N1YmplY3QubmV4dCh0aGlzLnBpY2tlZCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2FtZUluZGljZXM8VD4oYTogcmVhZG9ubHkgVFtdLCBiOiByZWFkb25seSBUW10pOiBib29sZWFuIHtcbiAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkgcmV0dXJuIGZhbHNlO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGEubGVuZ3RoOyBpKyspIGlmIChhW2ldICE9PSBiW2ldKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiB0cnVlO1xufVxuIl19