@jax-data-science/sci-image-visualizer 0.14.0 → 0.16.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 (34) hide show
  1. package/esm2022/lib/channel-histogram/channel-histogram.component.mjs +39 -3
  2. package/esm2022/lib/channel-histogram/channel-tree.mjs +65 -0
  3. package/esm2022/lib/contracts/channel-histogram-api.contract.mjs +1 -1
  4. package/esm2022/lib/contracts/image.contract.mjs +1 -1
  5. package/esm2022/lib/implementations/napari-js/napari-scene.mjs +1 -1
  6. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +202 -33
  7. package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +2 -1
  8. package/esm2022/lib/implementations/napari-js/spatial-tiles/cell-layers.mjs +5 -8
  9. package/esm2022/lib/spatial/lod.mjs +19 -1
  10. package/esm2022/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.mjs +47 -10
  11. package/esm2022/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.mjs +49 -16
  12. package/esm2022/lib/store/visualizer-store.service.mjs +20 -3
  13. package/esm2022/lib/toolbar/toolbar.component.mjs +13 -4
  14. package/esm2022/lib/toolbar/view-controls/view-controls.component.mjs +7 -7
  15. package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DvFp1jNH.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CYsPzX3J.mjs} +462 -83
  16. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CYsPzX3J.mjs.map +1 -0
  17. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-D7lSUAM1.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-DaZVXq1s.mjs} +3 -2
  18. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-D7lSUAM1.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-DaZVXq1s.mjs.map} +1 -1
  19. package/fesm2022/jax-data-science-sci-image-visualizer.mjs +2 -1
  20. package/fesm2022/jax-data-science-sci-image-visualizer.mjs.map +1 -1
  21. package/lib/channel-histogram/channel-histogram.component.d.ts +14 -0
  22. package/lib/channel-histogram/channel-tree.d.ts +30 -0
  23. package/lib/contracts/channel-histogram-api.contract.d.ts +2 -0
  24. package/lib/contracts/image.contract.d.ts +6 -0
  25. package/lib/implementations/napari-js/napari-scene.d.ts +2 -0
  26. package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +80 -9
  27. package/lib/spatial/lod.d.ts +11 -1
  28. package/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.d.ts +18 -1
  29. package/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.d.ts +18 -0
  30. package/lib/store/visualizer-store.service.d.ts +7 -1
  31. package/lib/toolbar/toolbar.component.d.ts +6 -0
  32. package/lib/toolbar/view-controls/view-controls.component.d.ts +3 -3
  33. package/package.json +2 -2
  34. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DvFp1jNH.mjs.map +0 -1
@@ -28,12 +28,12 @@ export class ViewControlsComponent {
28
28
  this.activeDragMode = null;
29
29
  /** The 3D camera mode (`turntable` / `orbit` / …). */
30
30
  this.activeSurface3dMode = 'turntable';
31
- /** A napari-js WebGPU view (axes toggle, napari camera). */
32
- this.isNapariMode = false;
33
31
  /** The napari-js surface (shows the wireframe toggle). */
34
32
  this.isNapariSurfaceMode = false;
35
33
  /** A napari-js 3D view (shows the Resolution dropdown). */
36
34
  this.isNapari3dMode = false;
35
+ /** Whether the view draws the 3D axes gizmo (shows its toggle). */
36
+ this.axesToggle = false;
37
37
  /** The napari 3D axes gizmo is shown. */
38
38
  this.axesVisible = true;
39
39
  /** The napari surface wireframe is on. */
@@ -60,11 +60,11 @@ export class ViewControlsComponent {
60
60
  this.decimateOptions = NAPARI_DECIMATE_OPTIONS;
61
61
  }
62
62
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: ViewControlsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
63
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: ViewControlsComponent, isStandalone: true, selector: "toolbar-view-controls", inputs: { isHeatmap: "isHeatmap", zoomTools: "zoomTools", isImageView: "isImageView", activeDragMode: "activeDragMode", activeSurface3dMode: "activeSurface3dMode", isNapariMode: "isNapariMode", isNapariSurfaceMode: "isNapariSurfaceMode", isNapari3dMode: "isNapari3dMode", axesVisible: "axesVisible", wireframeActive: "wireframeActive", resolutionScale: "resolutionScale" }, outputs: { toggleDragMode: "toggleDragMode", zoomIn: "zoomIn", zoomOut: "zoomOut", toggleSurface3dMode: "toggleSurface3dMode", resetSurfaceCamera: "resetSurfaceCamera", toggleAxes: "toggleAxes", toggleWireframe: "toggleWireframe", selectResolution: "selectResolution" }, ngImport: i0, template: "<!-- Zoom tools. Plotly rubber-band drag-zoom: on OpenSeadragon the box-zoom\n covers this and a bare drag pans natively, so it's hidden in image view. -->\n<ng-container *ngIf=\"isHeatmap && zoomTools\">\n <span class=\"toolbar-separator\"></span>\n <p-button\n *ngIf=\"!isImageView\"\n icon=\"pi pi-search\"\n size=\"small\"\n [text]=\"activeDragMode !== 'zoom'\"\n ariaLabel=\"Zoom drag\"\n pTooltip=\"Zoom drag\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleDragMode.emit('zoom')\"\n >\n </p-button>\n <p-button\n size=\"small\"\n [text]=\"activeDragMode !== 'zoomToBox'\"\n ariaLabel=\"Zoom box\"\n pTooltip=\"Zoom box (<kbd>b</kbd>)\"\n [escape]=\"false\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleDragMode.emit('zoomToBox')\"\n >\n <img\n src=\"assets/plotting/zoom-box.svg\"\n [class]=\"activeDragMode === 'zoomToBox' ? 'toolbar-icon-active' : 'toolbar-icon-dark'\"\n style=\"width: 1rem\"\n />\n </p-button>\n <p-button\n icon=\"pi pi-arrows-alt\"\n size=\"small\"\n [text]=\"activeDragMode !== 'pan'\"\n ariaLabel=\"Pan the image\"\n pTooltip=\"Pan the image (<kbd>p</kbd>)\"\n [escape]=\"false\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleDragMode.emit('pan')\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-search-plus\"\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Zoom in\"\n pTooltip=\"Zoom in (<kbd>+</kbd>)\"\n [escape]=\"false\"\n tooltipPosition=\"bottom\"\n (onClick)=\"zoomIn.emit()\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-search-minus\"\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Zoom out\"\n pTooltip=\"Zoom out (<kbd>-</kbd>)\"\n [escape]=\"false\"\n tooltipPosition=\"bottom\"\n (onClick)=\"zoomOut.emit()\"\n >\n </p-button>\n</ng-container>\n\n<!-- Surface 3D controls -->\n<ng-container *ngIf=\"!isHeatmap\">\n <span class=\"toolbar-separator\"></span>\n <p-button\n icon=\"pi pi-search\"\n size=\"small\"\n [text]=\"activeSurface3dMode !== 'zoom'\"\n ariaLabel=\"Zoom\"\n pTooltip=\"Zoom\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleSurface3dMode.emit('zoom')\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-arrows-alt\"\n size=\"small\"\n [text]=\"activeSurface3dMode !== 'pan'\"\n ariaLabel=\"Pan\"\n pTooltip=\"Pan\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleSurface3dMode.emit('pan')\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-globe\"\n size=\"small\"\n [text]=\"activeSurface3dMode !== 'orbit'\"\n ariaLabel=\"Orbital rotation\"\n pTooltip=\"Orbital rotation\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleSurface3dMode.emit('orbit')\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-sync\"\n size=\"small\"\n [text]=\"activeSurface3dMode !== 'turntable'\"\n ariaLabel=\"Turntable rotation\"\n pTooltip=\"Turntable rotation\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleSurface3dMode.emit('turntable')\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-home\"\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Reset camera\"\n pTooltip=\"Reset camera to default\"\n tooltipPosition=\"bottom\"\n (onClick)=\"resetSurfaceCamera.emit()\"\n >\n </p-button>\n <!-- 3D coordinate-axes / scale gizmo toggle (napari-js WebGPU volume/isosurface only).\n `p-button-icon-only` gives the same square sizing as the neighbouring pi-icon buttons\n (the projected <img> doesn't trigger PrimeNG's automatic icon-only sizing). -->\n <p-button\n size=\"small\"\n *ngIf=\"isNapariMode\"\n styleClass=\"p-button-icon-only\"\n [text]=\"!axesVisible\"\n ariaLabel=\"Toggle 3D axes\"\n pTooltip=\"Toggle 3D axes / scale\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleAxes.emit()\"\n >\n <img\n src=\"assets/plotting/3d-coordinates.svg\"\n [class]=\"axesVisible ? 'toolbar-icon-active' : 'toolbar-icon-dark'\"\n style=\"width: 1rem\"\n />\n </p-button>\n <!-- Surface wireframe toggle (napari-js WebGPU surface only). -->\n <p-button\n icon=\"pi pi-share-alt\"\n size=\"small\"\n *ngIf=\"isNapariSurfaceMode\"\n [text]=\"!wireframeActive\"\n ariaLabel=\"Toggle wireframe\"\n pTooltip=\"Toggle wireframe\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleWireframe.emit()\"\n >\n </p-button>\n <!-- Resolution (decimate factor) for the napari 3D types \u2014 reloads at coarser/finer sampling. -->\n <ng-container *ngIf=\"isNapari3dMode\">\n <span class=\"flex align-items-center mx-1 toolbar-text\">Res</span>\n <p-dropdown\n [options]=\"decimateOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [ngModel]=\"resolutionScale\"\n appendTo=\"body\"\n ariaLabel=\"Resolution\"\n pTooltip=\"Resolution (decimate factor)\"\n tooltipPosition=\"bottom\"\n [style]=\"{ 'min-width': '6rem' }\"\n (onChange)=\"selectResolution.emit($event.value)\"\n >\n </p-dropdown>\n </ng-container>\n</ng-container>\n", styles: [".toolbar-text{color:var(--primary-color);font-size:.875rem}.toolbar-separator{border-left:1px solid var(--surface-border);height:1.5rem;margin:0 .25rem;align-self:center}.toolbar-icon-dark{filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}.toolbar-icon-active{filter:brightness(0) invert(1)}.wand-sensitivity-value{min-width:2rem;text-align:right}:host{display:contents}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { 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: DropdownModule }, { kind: "component", type: i4.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "autoShowPanelOnPrintableCharacterKeyDown", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
63
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: ViewControlsComponent, isStandalone: true, selector: "toolbar-view-controls", inputs: { isHeatmap: "isHeatmap", zoomTools: "zoomTools", isImageView: "isImageView", activeDragMode: "activeDragMode", activeSurface3dMode: "activeSurface3dMode", isNapariSurfaceMode: "isNapariSurfaceMode", isNapari3dMode: "isNapari3dMode", axesToggle: "axesToggle", axesVisible: "axesVisible", wireframeActive: "wireframeActive", resolutionScale: "resolutionScale" }, outputs: { toggleDragMode: "toggleDragMode", zoomIn: "zoomIn", zoomOut: "zoomOut", toggleSurface3dMode: "toggleSurface3dMode", resetSurfaceCamera: "resetSurfaceCamera", toggleAxes: "toggleAxes", toggleWireframe: "toggleWireframe", selectResolution: "selectResolution" }, ngImport: i0, template: "<!-- Zoom tools. Plotly rubber-band drag-zoom: on OpenSeadragon the box-zoom\n covers this and a bare drag pans natively, so it's hidden in image view. -->\n<ng-container *ngIf=\"isHeatmap && zoomTools\">\n <span class=\"toolbar-separator\"></span>\n <p-button\n *ngIf=\"!isImageView\"\n icon=\"pi pi-search\"\n size=\"small\"\n [text]=\"activeDragMode !== 'zoom'\"\n ariaLabel=\"Zoom drag\"\n pTooltip=\"Zoom drag\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleDragMode.emit('zoom')\"\n >\n </p-button>\n <p-button\n size=\"small\"\n [text]=\"activeDragMode !== 'zoomToBox'\"\n ariaLabel=\"Zoom box\"\n pTooltip=\"Zoom box (<kbd>b</kbd>)\"\n [escape]=\"false\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleDragMode.emit('zoomToBox')\"\n >\n <img\n src=\"assets/plotting/zoom-box.svg\"\n [class]=\"activeDragMode === 'zoomToBox' ? 'toolbar-icon-active' : 'toolbar-icon-dark'\"\n style=\"width: 1rem\"\n />\n </p-button>\n <p-button\n icon=\"pi pi-arrows-alt\"\n size=\"small\"\n [text]=\"activeDragMode !== 'pan'\"\n ariaLabel=\"Pan the image\"\n pTooltip=\"Pan the image (<kbd>p</kbd>)\"\n [escape]=\"false\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleDragMode.emit('pan')\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-search-plus\"\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Zoom in\"\n pTooltip=\"Zoom in (<kbd>+</kbd>)\"\n [escape]=\"false\"\n tooltipPosition=\"bottom\"\n (onClick)=\"zoomIn.emit()\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-search-minus\"\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Zoom out\"\n pTooltip=\"Zoom out (<kbd>-</kbd>)\"\n [escape]=\"false\"\n tooltipPosition=\"bottom\"\n (onClick)=\"zoomOut.emit()\"\n >\n </p-button>\n</ng-container>\n\n<!-- Surface 3D controls -->\n<ng-container *ngIf=\"!isHeatmap\">\n <span class=\"toolbar-separator\"></span>\n <p-button\n icon=\"pi pi-search\"\n size=\"small\"\n [text]=\"activeSurface3dMode !== 'zoom'\"\n ariaLabel=\"Zoom\"\n pTooltip=\"Zoom\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleSurface3dMode.emit('zoom')\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-arrows-alt\"\n size=\"small\"\n [text]=\"activeSurface3dMode !== 'pan'\"\n ariaLabel=\"Pan\"\n pTooltip=\"Pan\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleSurface3dMode.emit('pan')\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-globe\"\n size=\"small\"\n [text]=\"activeSurface3dMode !== 'orbit'\"\n ariaLabel=\"Orbital rotation\"\n pTooltip=\"Orbital rotation\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleSurface3dMode.emit('orbit')\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-sync\"\n size=\"small\"\n [text]=\"activeSurface3dMode !== 'turntable'\"\n ariaLabel=\"Turntable rotation\"\n pTooltip=\"Turntable rotation\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleSurface3dMode.emit('turntable')\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-home\"\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Reset camera\"\n pTooltip=\"Reset camera to default\"\n tooltipPosition=\"bottom\"\n (onClick)=\"resetSurfaceCamera.emit()\"\n >\n </p-button>\n <!-- 3D coordinate-axes / scale gizmo toggle (napari-js WebGPU volume/isosurface, and the 3D\n spatial cloud).\n `p-button-icon-only` gives the same square sizing as the neighbouring pi-icon buttons\n (the projected <img> doesn't trigger PrimeNG's automatic icon-only sizing). -->\n <p-button\n size=\"small\"\n *ngIf=\"axesToggle\"\n styleClass=\"p-button-icon-only\"\n [text]=\"!axesVisible\"\n ariaLabel=\"Toggle 3D axes\"\n pTooltip=\"Toggle 3D axes / scale\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleAxes.emit()\"\n >\n <img\n src=\"assets/plotting/3d-coordinates.svg\"\n [class]=\"axesVisible ? 'toolbar-icon-active' : 'toolbar-icon-dark'\"\n style=\"width: 1rem\"\n />\n </p-button>\n <!-- Surface wireframe toggle (napari-js WebGPU surface only). -->\n <p-button\n icon=\"pi pi-share-alt\"\n size=\"small\"\n *ngIf=\"isNapariSurfaceMode\"\n [text]=\"!wireframeActive\"\n ariaLabel=\"Toggle wireframe\"\n pTooltip=\"Toggle wireframe\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleWireframe.emit()\"\n >\n </p-button>\n <!-- Resolution (decimate factor) for the napari 3D types \u2014 reloads at coarser/finer sampling. -->\n <ng-container *ngIf=\"isNapari3dMode\">\n <span class=\"flex align-items-center mx-1 toolbar-text\">Res</span>\n <p-dropdown\n [options]=\"decimateOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [ngModel]=\"resolutionScale\"\n appendTo=\"body\"\n ariaLabel=\"Resolution\"\n pTooltip=\"Resolution (decimate factor)\"\n tooltipPosition=\"bottom\"\n [style]=\"{ 'min-width': '6rem' }\"\n (onChange)=\"selectResolution.emit($event.value)\"\n >\n </p-dropdown>\n </ng-container>\n</ng-container>\n", styles: [".toolbar-text{color:var(--primary-color);font-size:.875rem}.toolbar-separator{border-left:1px solid var(--surface-border);height:1.5rem;margin:0 .25rem;align-self:center}.toolbar-icon-dark{filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}.toolbar-icon-active{filter:brightness(0) invert(1)}.wand-sensitivity-value{min-width:2rem;text-align:right}:host{display:contents}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { 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: DropdownModule }, { kind: "component", type: i4.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "autoShowPanelOnPrintableCharacterKeyDown", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
64
64
  }
65
65
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: ViewControlsComponent, decorators: [{
66
66
  type: Component,
67
- args: [{ selector: 'toolbar-view-controls', standalone: true, imports: [CommonModule, FormsModule, ButtonModule, DropdownModule, TooltipModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Zoom tools. Plotly rubber-band drag-zoom: on OpenSeadragon the box-zoom\n covers this and a bare drag pans natively, so it's hidden in image view. -->\n<ng-container *ngIf=\"isHeatmap && zoomTools\">\n <span class=\"toolbar-separator\"></span>\n <p-button\n *ngIf=\"!isImageView\"\n icon=\"pi pi-search\"\n size=\"small\"\n [text]=\"activeDragMode !== 'zoom'\"\n ariaLabel=\"Zoom drag\"\n pTooltip=\"Zoom drag\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleDragMode.emit('zoom')\"\n >\n </p-button>\n <p-button\n size=\"small\"\n [text]=\"activeDragMode !== 'zoomToBox'\"\n ariaLabel=\"Zoom box\"\n pTooltip=\"Zoom box (<kbd>b</kbd>)\"\n [escape]=\"false\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleDragMode.emit('zoomToBox')\"\n >\n <img\n src=\"assets/plotting/zoom-box.svg\"\n [class]=\"activeDragMode === 'zoomToBox' ? 'toolbar-icon-active' : 'toolbar-icon-dark'\"\n style=\"width: 1rem\"\n />\n </p-button>\n <p-button\n icon=\"pi pi-arrows-alt\"\n size=\"small\"\n [text]=\"activeDragMode !== 'pan'\"\n ariaLabel=\"Pan the image\"\n pTooltip=\"Pan the image (<kbd>p</kbd>)\"\n [escape]=\"false\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleDragMode.emit('pan')\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-search-plus\"\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Zoom in\"\n pTooltip=\"Zoom in (<kbd>+</kbd>)\"\n [escape]=\"false\"\n tooltipPosition=\"bottom\"\n (onClick)=\"zoomIn.emit()\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-search-minus\"\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Zoom out\"\n pTooltip=\"Zoom out (<kbd>-</kbd>)\"\n [escape]=\"false\"\n tooltipPosition=\"bottom\"\n (onClick)=\"zoomOut.emit()\"\n >\n </p-button>\n</ng-container>\n\n<!-- Surface 3D controls -->\n<ng-container *ngIf=\"!isHeatmap\">\n <span class=\"toolbar-separator\"></span>\n <p-button\n icon=\"pi pi-search\"\n size=\"small\"\n [text]=\"activeSurface3dMode !== 'zoom'\"\n ariaLabel=\"Zoom\"\n pTooltip=\"Zoom\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleSurface3dMode.emit('zoom')\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-arrows-alt\"\n size=\"small\"\n [text]=\"activeSurface3dMode !== 'pan'\"\n ariaLabel=\"Pan\"\n pTooltip=\"Pan\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleSurface3dMode.emit('pan')\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-globe\"\n size=\"small\"\n [text]=\"activeSurface3dMode !== 'orbit'\"\n ariaLabel=\"Orbital rotation\"\n pTooltip=\"Orbital rotation\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleSurface3dMode.emit('orbit')\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-sync\"\n size=\"small\"\n [text]=\"activeSurface3dMode !== 'turntable'\"\n ariaLabel=\"Turntable rotation\"\n pTooltip=\"Turntable rotation\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleSurface3dMode.emit('turntable')\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-home\"\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Reset camera\"\n pTooltip=\"Reset camera to default\"\n tooltipPosition=\"bottom\"\n (onClick)=\"resetSurfaceCamera.emit()\"\n >\n </p-button>\n <!-- 3D coordinate-axes / scale gizmo toggle (napari-js WebGPU volume/isosurface only).\n `p-button-icon-only` gives the same square sizing as the neighbouring pi-icon buttons\n (the projected <img> doesn't trigger PrimeNG's automatic icon-only sizing). -->\n <p-button\n size=\"small\"\n *ngIf=\"isNapariMode\"\n styleClass=\"p-button-icon-only\"\n [text]=\"!axesVisible\"\n ariaLabel=\"Toggle 3D axes\"\n pTooltip=\"Toggle 3D axes / scale\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleAxes.emit()\"\n >\n <img\n src=\"assets/plotting/3d-coordinates.svg\"\n [class]=\"axesVisible ? 'toolbar-icon-active' : 'toolbar-icon-dark'\"\n style=\"width: 1rem\"\n />\n </p-button>\n <!-- Surface wireframe toggle (napari-js WebGPU surface only). -->\n <p-button\n icon=\"pi pi-share-alt\"\n size=\"small\"\n *ngIf=\"isNapariSurfaceMode\"\n [text]=\"!wireframeActive\"\n ariaLabel=\"Toggle wireframe\"\n pTooltip=\"Toggle wireframe\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleWireframe.emit()\"\n >\n </p-button>\n <!-- Resolution (decimate factor) for the napari 3D types \u2014 reloads at coarser/finer sampling. -->\n <ng-container *ngIf=\"isNapari3dMode\">\n <span class=\"flex align-items-center mx-1 toolbar-text\">Res</span>\n <p-dropdown\n [options]=\"decimateOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [ngModel]=\"resolutionScale\"\n appendTo=\"body\"\n ariaLabel=\"Resolution\"\n pTooltip=\"Resolution (decimate factor)\"\n tooltipPosition=\"bottom\"\n [style]=\"{ 'min-width': '6rem' }\"\n (onChange)=\"selectResolution.emit($event.value)\"\n >\n </p-dropdown>\n </ng-container>\n</ng-container>\n", styles: [".toolbar-text{color:var(--primary-color);font-size:.875rem}.toolbar-separator{border-left:1px solid var(--surface-border);height:1.5rem;margin:0 .25rem;align-self:center}.toolbar-icon-dark{filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}.toolbar-icon-active{filter:brightness(0) invert(1)}.wand-sensitivity-value{min-width:2rem;text-align:right}:host{display:contents}\n"] }]
67
+ args: [{ selector: 'toolbar-view-controls', standalone: true, imports: [CommonModule, FormsModule, ButtonModule, DropdownModule, TooltipModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Zoom tools. Plotly rubber-band drag-zoom: on OpenSeadragon the box-zoom\n covers this and a bare drag pans natively, so it's hidden in image view. -->\n<ng-container *ngIf=\"isHeatmap && zoomTools\">\n <span class=\"toolbar-separator\"></span>\n <p-button\n *ngIf=\"!isImageView\"\n icon=\"pi pi-search\"\n size=\"small\"\n [text]=\"activeDragMode !== 'zoom'\"\n ariaLabel=\"Zoom drag\"\n pTooltip=\"Zoom drag\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleDragMode.emit('zoom')\"\n >\n </p-button>\n <p-button\n size=\"small\"\n [text]=\"activeDragMode !== 'zoomToBox'\"\n ariaLabel=\"Zoom box\"\n pTooltip=\"Zoom box (<kbd>b</kbd>)\"\n [escape]=\"false\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleDragMode.emit('zoomToBox')\"\n >\n <img\n src=\"assets/plotting/zoom-box.svg\"\n [class]=\"activeDragMode === 'zoomToBox' ? 'toolbar-icon-active' : 'toolbar-icon-dark'\"\n style=\"width: 1rem\"\n />\n </p-button>\n <p-button\n icon=\"pi pi-arrows-alt\"\n size=\"small\"\n [text]=\"activeDragMode !== 'pan'\"\n ariaLabel=\"Pan the image\"\n pTooltip=\"Pan the image (<kbd>p</kbd>)\"\n [escape]=\"false\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleDragMode.emit('pan')\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-search-plus\"\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Zoom in\"\n pTooltip=\"Zoom in (<kbd>+</kbd>)\"\n [escape]=\"false\"\n tooltipPosition=\"bottom\"\n (onClick)=\"zoomIn.emit()\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-search-minus\"\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Zoom out\"\n pTooltip=\"Zoom out (<kbd>-</kbd>)\"\n [escape]=\"false\"\n tooltipPosition=\"bottom\"\n (onClick)=\"zoomOut.emit()\"\n >\n </p-button>\n</ng-container>\n\n<!-- Surface 3D controls -->\n<ng-container *ngIf=\"!isHeatmap\">\n <span class=\"toolbar-separator\"></span>\n <p-button\n icon=\"pi pi-search\"\n size=\"small\"\n [text]=\"activeSurface3dMode !== 'zoom'\"\n ariaLabel=\"Zoom\"\n pTooltip=\"Zoom\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleSurface3dMode.emit('zoom')\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-arrows-alt\"\n size=\"small\"\n [text]=\"activeSurface3dMode !== 'pan'\"\n ariaLabel=\"Pan\"\n pTooltip=\"Pan\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleSurface3dMode.emit('pan')\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-globe\"\n size=\"small\"\n [text]=\"activeSurface3dMode !== 'orbit'\"\n ariaLabel=\"Orbital rotation\"\n pTooltip=\"Orbital rotation\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleSurface3dMode.emit('orbit')\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-sync\"\n size=\"small\"\n [text]=\"activeSurface3dMode !== 'turntable'\"\n ariaLabel=\"Turntable rotation\"\n pTooltip=\"Turntable rotation\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleSurface3dMode.emit('turntable')\"\n >\n </p-button>\n <p-button\n icon=\"pi pi-home\"\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Reset camera\"\n pTooltip=\"Reset camera to default\"\n tooltipPosition=\"bottom\"\n (onClick)=\"resetSurfaceCamera.emit()\"\n >\n </p-button>\n <!-- 3D coordinate-axes / scale gizmo toggle (napari-js WebGPU volume/isosurface, and the 3D\n spatial cloud).\n `p-button-icon-only` gives the same square sizing as the neighbouring pi-icon buttons\n (the projected <img> doesn't trigger PrimeNG's automatic icon-only sizing). -->\n <p-button\n size=\"small\"\n *ngIf=\"axesToggle\"\n styleClass=\"p-button-icon-only\"\n [text]=\"!axesVisible\"\n ariaLabel=\"Toggle 3D axes\"\n pTooltip=\"Toggle 3D axes / scale\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleAxes.emit()\"\n >\n <img\n src=\"assets/plotting/3d-coordinates.svg\"\n [class]=\"axesVisible ? 'toolbar-icon-active' : 'toolbar-icon-dark'\"\n style=\"width: 1rem\"\n />\n </p-button>\n <!-- Surface wireframe toggle (napari-js WebGPU surface only). -->\n <p-button\n icon=\"pi pi-share-alt\"\n size=\"small\"\n *ngIf=\"isNapariSurfaceMode\"\n [text]=\"!wireframeActive\"\n ariaLabel=\"Toggle wireframe\"\n pTooltip=\"Toggle wireframe\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleWireframe.emit()\"\n >\n </p-button>\n <!-- Resolution (decimate factor) for the napari 3D types \u2014 reloads at coarser/finer sampling. -->\n <ng-container *ngIf=\"isNapari3dMode\">\n <span class=\"flex align-items-center mx-1 toolbar-text\">Res</span>\n <p-dropdown\n [options]=\"decimateOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [ngModel]=\"resolutionScale\"\n appendTo=\"body\"\n ariaLabel=\"Resolution\"\n pTooltip=\"Resolution (decimate factor)\"\n tooltipPosition=\"bottom\"\n [style]=\"{ 'min-width': '6rem' }\"\n (onChange)=\"selectResolution.emit($event.value)\"\n >\n </p-dropdown>\n </ng-container>\n</ng-container>\n", styles: [".toolbar-text{color:var(--primary-color);font-size:.875rem}.toolbar-separator{border-left:1px solid var(--surface-border);height:1.5rem;margin:0 .25rem;align-self:center}.toolbar-icon-dark{filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}.toolbar-icon-active{filter:brightness(0) invert(1)}.wand-sensitivity-value{min-width:2rem;text-align:right}:host{display:contents}\n"] }]
68
68
  }], propDecorators: { isHeatmap: [{
69
69
  type: Input
70
70
  }], zoomTools: [{
@@ -75,12 +75,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
75
75
  type: Input
76
76
  }], activeSurface3dMode: [{
77
77
  type: Input
78
- }], isNapariMode: [{
79
- type: Input
80
78
  }], isNapariSurfaceMode: [{
81
79
  type: Input
82
80
  }], isNapari3dMode: [{
83
81
  type: Input
82
+ }], axesToggle: [{
83
+ type: Input
84
84
  }], axesVisible: [{
85
85
  type: Input
86
86
  }], wireframeActive: [{
@@ -104,4 +104,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
104
104
  }], selectResolution: [{
105
105
  type: Output
106
106
  }] } });
107
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlldy1jb250cm9scy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL3Rvb2xiYXIvdmlldy1jb250cm9scy92aWV3LWNvbnRyb2xzLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvdG9vbGJhci92aWV3LWNvbnRyb2xzL3ZpZXctY29udHJvbHMuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNoRyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRWhELE9BQU8sRUFBRSx1QkFBdUIsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLDJCQUEyQixDQUFDOzs7Ozs7O0FBRTdGOzs7O0dBSUc7QUFTSCxNQUFNLE9BQU8scUJBQXFCO0lBUmxDO1FBU0UscUVBQXFFO1FBQzVELGNBQVMsR0FBRyxJQUFJLENBQUM7UUFDMUIscUNBQXFDO1FBQzVCLGNBQVMsR0FBRyxJQUFJLENBQUM7UUFDMUIsK0RBQStEO1FBQ3RELGdCQUFXLEdBQUcsSUFBSSxDQUFDO1FBQzVCLDJEQUEyRDtRQUNsRCxtQkFBYyxHQUFrQixJQUFJLENBQUM7UUFDOUMsc0RBQXNEO1FBQzdDLHdCQUFtQixHQUFHLFdBQVcsQ0FBQztRQUMzQyw0REFBNEQ7UUFDbkQsaUJBQVksR0FBRyxLQUFLLENBQUM7UUFDOUIsMERBQTBEO1FBQ2pELHdCQUFtQixHQUFHLEtBQUssQ0FBQztRQUNyQywyREFBMkQ7UUFDbEQsbUJBQWMsR0FBRyxLQUFLLENBQUM7UUFDaEMseUNBQXlDO1FBQ2hDLGdCQUFXLEdBQUcsSUFBSSxDQUFDO1FBQzVCLDBDQUEwQztRQUNqQyxvQkFBZSxHQUFHLEtBQUssQ0FBQztRQUNqQywyREFBMkQ7UUFDbEQsb0JBQWUsR0FBRyx1QkFBdUIsQ0FBQztRQUVuRCxxREFBcUQ7UUFDM0MsbUJBQWMsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBQ3RELHdCQUF3QjtRQUNkLFdBQU0sR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBQzVDLHlCQUF5QjtRQUNmLFlBQU8sR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBQzdDLHNEQUFzRDtRQUM1Qyx3QkFBbUIsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBQzNELDJCQUEyQjtRQUNqQix1QkFBa0IsR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBQ3hELHVDQUF1QztRQUM3QixlQUFVLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUNoRCwyQ0FBMkM7UUFDakMsb0JBQWUsR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBQ3JELDhDQUE4QztRQUNwQyxxQkFBZ0IsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBRXhELDJEQUEyRDtRQUN4QyxvQkFBZSxHQUFHLHVCQUF1QixDQUFDO0tBQzlEOzhHQTNDWSxxQkFBcUI7a0dBQXJCLHFCQUFxQixzdEJDdEJsQyw2K0pBdUtBLHdlRHRKWSxZQUFZLGtJQUFFLFdBQVcsOFZBQUUsWUFBWSw2WEFBRSxjQUFjLHV0Q0FBRSxhQUFhOzsyRkFLckUscUJBQXFCO2tCQVJqQyxTQUFTOytCQUNFLHVCQUF1QixjQUNyQixJQUFJLFdBQ1AsQ0FBQyxZQUFZLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxjQUFjLEVBQUUsYUFBYSxDQUFDLG1CQUdoRSx1QkFBdUIsQ0FBQyxNQUFNOzhCQUl0QyxTQUFTO3NCQUFqQixLQUFLO2dCQUVHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBRUcsV0FBVztzQkFBbkIsS0FBSztnQkFFRyxjQUFjO3NCQUF0QixLQUFLO2dCQUVHLG1CQUFtQjtzQkFBM0IsS0FBSztnQkFFRyxZQUFZO3NCQUFwQixLQUFLO2dCQUVHLG1CQUFtQjtzQkFBM0IsS0FBSztnQkFFRyxjQUFjO3NCQUF0QixLQUFLO2dCQUVHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBRUcsZUFBZTtzQkFBdkIsS0FBSztnQkFFRyxlQUFlO3NCQUF2QixLQUFLO2dCQUdJLGNBQWM7c0JBQXZCLE1BQU07Z0JBRUcsTUFBTTtzQkFBZixNQUFNO2dCQUVHLE9BQU87c0JBQWhCLE1BQU07Z0JBRUcsbUJBQW1CO3NCQUE1QixNQUFNO2dCQUVHLGtCQUFrQjtzQkFBM0IsTUFBTTtnQkFFRyxVQUFVO3NCQUFuQixNQUFNO2dCQUVHLGVBQWU7c0JBQXhCLE1BQU07Z0JBRUcsZ0JBQWdCO3NCQUF6QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBCdXR0b25Nb2R1bGUgfSBmcm9tICdwcmltZW5nL2J1dHRvbic7XG5pbXBvcnQgeyBEcm9wZG93bk1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvZHJvcGRvd24nO1xuaW1wb3J0IHsgVG9vbHRpcE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvdG9vbHRpcCc7XG5cbmltcG9ydCB7IE5BUEFSSV9ERUNJTUFURV9PUFRJT05TLCBOQVBBUklfREVGQVVMVF9ERUNJTUFURSB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy9wbG90LXR5cGUnO1xuXG4vKipcbiAqIFRoZSB0b29sYmFyJ3MgdmlldyBncm91cDogMkQgem9vbSAvIHBhbiB0b29scywgb3IgZm9yIGEgM0QgdmlldyB0aGUgY2FtZXJhXG4gKiBtb2RlcyBhbmQgcmVzZXQsIHRoZSBuYXBhcmkgYXhlcyBhbmQgd2lyZWZyYW1lIHRvZ2dsZXMgYW5kIHRoZSAzRFxuICogcmVzb2x1dGlvbi4gUHJlc2VudGF0aW9uYWw6IHRoZSBob3N0IG93bnMgZXZlcnkgdmFsdWUuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3Rvb2xiYXItdmlldy1jb250cm9scycsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIEZvcm1zTW9kdWxlLCBCdXR0b25Nb2R1bGUsIERyb3Bkb3duTW9kdWxlLCBUb29sdGlwTW9kdWxlXSxcbiAgdGVtcGxhdGVVcmw6ICcuL3ZpZXctY29udHJvbHMuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi92aWV3LWNvbnRyb2xzLmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBWaWV3Q29udHJvbHNDb21wb25lbnQge1xuICAvKiogQSAyRCB2aWV3ICh6b29tIHRvb2xzKSByYXRoZXIgdGhhbiBhIDNEIG9uZSAoY2FtZXJhIGNvbnRyb2xzKS4gKi9cbiAgQElucHV0KCkgaXNIZWF0bWFwID0gdHJ1ZTtcbiAgLyoqIFRoZSBob3N0IHNob3dzIHRoZSB6b29tIHRvb2xzLiAqL1xuICBASW5wdXQoKSB6b29tVG9vbHMgPSB0cnVlO1xuICAvKiogVGhlIE9TRCBJbWFnZSB2aWV3IChwYW5zIG5hdGl2ZWx5OyBubyBQbG90bHkgZHJhZy16b29tKS4gKi9cbiAgQElucHV0KCkgaXNJbWFnZVZpZXcgPSB0cnVlO1xuICAvKiogVGhlIGFybWVkIHpvb20vcGFuIHRvb2wgKGB6b29tYCwgYHBhbmAsIOKApiksIG9yIG51bGwuICovXG4gIEBJbnB1dCgpIGFjdGl2ZURyYWdNb2RlOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgLyoqIFRoZSAzRCBjYW1lcmEgbW9kZSAoYHR1cm50YWJsZWAgLyBgb3JiaXRgIC8g4oCmKS4gKi9cbiAgQElucHV0KCkgYWN0aXZlU3VyZmFjZTNkTW9kZSA9ICd0dXJudGFibGUnO1xuICAvKiogQSBuYXBhcmktanMgV2ViR1BVIHZpZXcgKGF4ZXMgdG9nZ2xlLCBuYXBhcmkgY2FtZXJhKS4gKi9cbiAgQElucHV0KCkgaXNOYXBhcmlNb2RlID0gZmFsc2U7XG4gIC8qKiBUaGUgbmFwYXJpLWpzIHN1cmZhY2UgKHNob3dzIHRoZSB3aXJlZnJhbWUgdG9nZ2xlKS4gKi9cbiAgQElucHV0KCkgaXNOYXBhcmlTdXJmYWNlTW9kZSA9IGZhbHNlO1xuICAvKiogQSBuYXBhcmktanMgM0QgdmlldyAoc2hvd3MgdGhlIFJlc29sdXRpb24gZHJvcGRvd24pLiAqL1xuICBASW5wdXQoKSBpc05hcGFyaTNkTW9kZSA9IGZhbHNlO1xuICAvKiogVGhlIG5hcGFyaSAzRCBheGVzIGdpem1vIGlzIHNob3duLiAqL1xuICBASW5wdXQoKSBheGVzVmlzaWJsZSA9IHRydWU7XG4gIC8qKiBUaGUgbmFwYXJpIHN1cmZhY2Ugd2lyZWZyYW1lIGlzIG9uLiAqL1xuICBASW5wdXQoKSB3aXJlZnJhbWVBY3RpdmUgPSBmYWxzZTtcbiAgLyoqIEFjdGl2ZSBuYXBhcmkgM0QgZGVjaW1hdGUgZmFjdG9yICgxID0gRnVsbCDigKYgOCA9IOKFmykuICovXG4gIEBJbnB1dCgpIHJlc29sdXRpb25TY2FsZSA9IE5BUEFSSV9ERUZBVUxUX0RFQ0lNQVRFO1xuXG4gIC8qKiBBIHpvb20vcGFuIHRvb2wgYnV0dG9uIHdhcyBjbGlja2VkIChpdHMgbW9kZSkuICovXG4gIEBPdXRwdXQoKSB0b2dnbGVEcmFnTW9kZSA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICAvKiogWm9vbSBpbiBvbmUgc3RlcC4gKi9cbiAgQE91dHB1dCgpIHpvb21JbiA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIFpvb20gb3V0IG9uZSBzdGVwLiAqL1xuICBAT3V0cHV0KCkgem9vbU91dCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIEEgM0QgY2FtZXJhIG1vZGUgYnV0dG9uIHdhcyBjbGlja2VkIChpdHMgbW9kZSkuICovXG4gIEBPdXRwdXQoKSB0b2dnbGVTdXJmYWNlM2RNb2RlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIC8qKiBSZXNldCB0aGUgM0QgY2FtZXJhLiAqL1xuICBAT3V0cHV0KCkgcmVzZXRTdXJmYWNlQ2FtZXJhID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogVG9nZ2xlIHRoZSBuYXBhcmkgM0QgYXhlcyBnaXptby4gKi9cbiAgQE91dHB1dCgpIHRvZ2dsZUF4ZXMgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBUb2dnbGUgdGhlIG5hcGFyaSBzdXJmYWNlIHdpcmVmcmFtZS4gKi9cbiAgQE91dHB1dCgpIHRvZ2dsZVdpcmVmcmFtZSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIEEgbmFwYXJpIDNEIGRlY2ltYXRlIGZhY3RvciB3YXMgcGlja2VkLiAqL1xuICBAT3V0cHV0KCkgc2VsZWN0UmVzb2x1dGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuXG4gIC8qKiBEZWNpbWF0ZS1mYWN0b3Igb3B0aW9ucyBmb3IgdGhlIFJlc29sdXRpb24gZHJvcGRvd24uICovXG4gIHByb3RlY3RlZCByZWFkb25seSBkZWNpbWF0ZU9wdGlvbnMgPSBOQVBBUklfREVDSU1BVEVfT1BUSU9OUztcbn1cbiIsIjwhLS0gWm9vbSB0b29scy4gUGxvdGx5IHJ1YmJlci1iYW5kIGRyYWctem9vbTogb24gT3BlblNlYWRyYWdvbiB0aGUgYm94LXpvb21cbiAgICAgY292ZXJzIHRoaXMgYW5kIGEgYmFyZSBkcmFnIHBhbnMgbmF0aXZlbHksIHNvIGl0J3MgaGlkZGVuIGluIGltYWdlIHZpZXcuIC0tPlxuPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzSGVhdG1hcCAmJiB6b29tVG9vbHNcIj5cbiAgPHNwYW4gY2xhc3M9XCJ0b29sYmFyLXNlcGFyYXRvclwiPjwvc3Bhbj5cbiAgPHAtYnV0dG9uXG4gICAgKm5nSWY9XCIhaXNJbWFnZVZpZXdcIlxuICAgIGljb249XCJwaSBwaS1zZWFyY2hcIlxuICAgIHNpemU9XCJzbWFsbFwiXG4gICAgW3RleHRdPVwiYWN0aXZlRHJhZ01vZGUgIT09ICd6b29tJ1wiXG4gICAgYXJpYUxhYmVsPVwiWm9vbSBkcmFnXCJcbiAgICBwVG9vbHRpcD1cIlpvb20gZHJhZ1wiXG4gICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAob25DbGljayk9XCJ0b2dnbGVEcmFnTW9kZS5lbWl0KCd6b29tJylcIlxuICA+XG4gIDwvcC1idXR0b24+XG4gIDxwLWJ1dHRvblxuICAgIHNpemU9XCJzbWFsbFwiXG4gICAgW3RleHRdPVwiYWN0aXZlRHJhZ01vZGUgIT09ICd6b29tVG9Cb3gnXCJcbiAgICBhcmlhTGFiZWw9XCJab29tIGJveFwiXG4gICAgcFRvb2x0aXA9XCJab29tIGJveCAoPGtiZD5iPC9rYmQ+KVwiXG4gICAgW2VzY2FwZV09XCJmYWxzZVwiXG4gICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAob25DbGljayk9XCJ0b2dnbGVEcmFnTW9kZS5lbWl0KCd6b29tVG9Cb3gnKVwiXG4gID5cbiAgICA8aW1nXG4gICAgICBzcmM9XCJhc3NldHMvcGxvdHRpbmcvem9vbS1ib3guc3ZnXCJcbiAgICAgIFtjbGFzc109XCJhY3RpdmVEcmFnTW9kZSA9PT0gJ3pvb21Ub0JveCcgPyAndG9vbGJhci1pY29uLWFjdGl2ZScgOiAndG9vbGJhci1pY29uLWRhcmsnXCJcbiAgICAgIHN0eWxlPVwid2lkdGg6IDFyZW1cIlxuICAgIC8+XG4gIDwvcC1idXR0b24+XG4gIDxwLWJ1dHRvblxuICAgIGljb249XCJwaSBwaS1hcnJvd3MtYWx0XCJcbiAgICBzaXplPVwic21hbGxcIlxuICAgIFt0ZXh0XT1cImFjdGl2ZURyYWdNb2RlICE9PSAncGFuJ1wiXG4gICAgYXJpYUxhYmVsPVwiUGFuIHRoZSBpbWFnZVwiXG4gICAgcFRvb2x0aXA9XCJQYW4gdGhlIGltYWdlICg8a2JkPnA8L2tiZD4pXCJcbiAgICBbZXNjYXBlXT1cImZhbHNlXCJcbiAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgIChvbkNsaWNrKT1cInRvZ2dsZURyYWdNb2RlLmVtaXQoJ3BhbicpXCJcbiAgPlxuICA8L3AtYnV0dG9uPlxuICA8cC1idXR0b25cbiAgICBpY29uPVwicGkgcGktc2VhcmNoLXBsdXNcIlxuICAgIHNpemU9XCJzbWFsbFwiXG4gICAgW3RleHRdPVwidHJ1ZVwiXG4gICAgYXJpYUxhYmVsPVwiWm9vbSBpblwiXG4gICAgcFRvb2x0aXA9XCJab29tIGluICg8a2JkPis8L2tiZD4pXCJcbiAgICBbZXNjYXBlXT1cImZhbHNlXCJcbiAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgIChvbkNsaWNrKT1cInpvb21Jbi5lbWl0KClcIlxuICA+XG4gIDwvcC1idXR0b24+XG4gIDxwLWJ1dHRvblxuICAgIGljb249XCJwaSBwaS1zZWFyY2gtbWludXNcIlxuICAgIHNpemU9XCJzbWFsbFwiXG4gICAgW3RleHRdPVwidHJ1ZVwiXG4gICAgYXJpYUxhYmVsPVwiWm9vbSBvdXRcIlxuICAgIHBUb29sdGlwPVwiWm9vbSBvdXQgKDxrYmQ+LTwva2JkPilcIlxuICAgIFtlc2NhcGVdPVwiZmFsc2VcIlxuICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgKG9uQ2xpY2spPVwiem9vbU91dC5lbWl0KClcIlxuICA+XG4gIDwvcC1idXR0b24+XG48L25nLWNvbnRhaW5lcj5cblxuPCEtLSBTdXJmYWNlIDNEIGNvbnRyb2xzIC0tPlxuPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpc0hlYXRtYXBcIj5cbiAgPHNwYW4gY2xhc3M9XCJ0b29sYmFyLXNlcGFyYXRvclwiPjwvc3Bhbj5cbiAgPHAtYnV0dG9uXG4gICAgaWNvbj1cInBpIHBpLXNlYXJjaFwiXG4gICAgc2l6ZT1cInNtYWxsXCJcbiAgICBbdGV4dF09XCJhY3RpdmVTdXJmYWNlM2RNb2RlICE9PSAnem9vbSdcIlxuICAgIGFyaWFMYWJlbD1cIlpvb21cIlxuICAgIHBUb29sdGlwPVwiWm9vbVwiXG4gICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAob25DbGljayk9XCJ0b2dnbGVTdXJmYWNlM2RNb2RlLmVtaXQoJ3pvb20nKVwiXG4gID5cbiAgPC9wLWJ1dHRvbj5cbiAgPHAtYnV0dG9uXG4gICAgaWNvbj1cInBpIHBpLWFycm93cy1hbHRcIlxuICAgIHNpemU9XCJzbWFsbFwiXG4gICAgW3RleHRdPVwiYWN0aXZlU3VyZmFjZTNkTW9kZSAhPT0gJ3BhbidcIlxuICAgIGFyaWFMYWJlbD1cIlBhblwiXG4gICAgcFRvb2x0aXA9XCJQYW5cIlxuICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgKG9uQ2xpY2spPVwidG9nZ2xlU3VyZmFjZTNkTW9kZS5lbWl0KCdwYW4nKVwiXG4gID5cbiAgPC9wLWJ1dHRvbj5cbiAgPHAtYnV0dG9uXG4gICAgaWNvbj1cInBpIHBpLWdsb2JlXCJcbiAgICBzaXplPVwic21hbGxcIlxuICAgIFt0ZXh0XT1cImFjdGl2ZVN1cmZhY2UzZE1vZGUgIT09ICdvcmJpdCdcIlxuICAgIGFyaWFMYWJlbD1cIk9yYml0YWwgcm90YXRpb25cIlxuICAgIHBUb29sdGlwPVwiT3JiaXRhbCByb3RhdGlvblwiXG4gICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAob25DbGljayk9XCJ0b2dnbGVTdXJmYWNlM2RNb2RlLmVtaXQoJ29yYml0JylcIlxuICA+XG4gIDwvcC1idXR0b24+XG4gIDxwLWJ1dHRvblxuICAgIGljb249XCJwaSBwaS1zeW5jXCJcbiAgICBzaXplPVwic21hbGxcIlxuICAgIFt0ZXh0XT1cImFjdGl2ZVN1cmZhY2UzZE1vZGUgIT09ICd0dXJudGFibGUnXCJcbiAgICBhcmlhTGFiZWw9XCJUdXJudGFibGUgcm90YXRpb25cIlxuICAgIHBUb29sdGlwPVwiVHVybnRhYmxlIHJvdGF0aW9uXCJcbiAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgIChvbkNsaWNrKT1cInRvZ2dsZVN1cmZhY2UzZE1vZGUuZW1pdCgndHVybnRhYmxlJylcIlxuICA+XG4gIDwvcC1idXR0b24+XG4gIDxwLWJ1dHRvblxuICAgIGljb249XCJwaSBwaS1ob21lXCJcbiAgICBzaXplPVwic21hbGxcIlxuICAgIFt0ZXh0XT1cInRydWVcIlxuICAgIGFyaWFMYWJlbD1cIlJlc2V0IGNhbWVyYVwiXG4gICAgcFRvb2x0aXA9XCJSZXNldCBjYW1lcmEgdG8gZGVmYXVsdFwiXG4gICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAob25DbGljayk9XCJyZXNldFN1cmZhY2VDYW1lcmEuZW1pdCgpXCJcbiAgPlxuICA8L3AtYnV0dG9uPlxuICA8IS0tIDNEIGNvb3JkaW5hdGUtYXhlcyAvIHNjYWxlIGdpem1vIHRvZ2dsZSAobmFwYXJpLWpzIFdlYkdQVSB2b2x1bWUvaXNvc3VyZmFjZSBvbmx5KS5cbiAgICAgICBgcC1idXR0b24taWNvbi1vbmx5YCBnaXZlcyB0aGUgc2FtZSBzcXVhcmUgc2l6aW5nIGFzIHRoZSBuZWlnaGJvdXJpbmcgcGktaWNvbiBidXR0b25zXG4gICAgICAgKHRoZSBwcm9qZWN0ZWQgPGltZz4gZG9lc24ndCB0cmlnZ2VyIFByaW1lTkcncyBhdXRvbWF0aWMgaWNvbi1vbmx5IHNpemluZykuIC0tPlxuICA8cC1idXR0b25cbiAgICBzaXplPVwic21hbGxcIlxuICAgICpuZ0lmPVwiaXNOYXBhcmlNb2RlXCJcbiAgICBzdHlsZUNsYXNzPVwicC1idXR0b24taWNvbi1vbmx5XCJcbiAgICBbdGV4dF09XCIhYXhlc1Zpc2libGVcIlxuICAgIGFyaWFMYWJlbD1cIlRvZ2dsZSAzRCBheGVzXCJcbiAgICBwVG9vbHRpcD1cIlRvZ2dsZSAzRCBheGVzIC8gc2NhbGVcIlxuICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgKG9uQ2xpY2spPVwidG9nZ2xlQXhlcy5lbWl0KClcIlxuICA+XG4gICAgPGltZ1xuICAgICAgc3JjPVwiYXNzZXRzL3Bsb3R0aW5nLzNkLWNvb3JkaW5hdGVzLnN2Z1wiXG4gICAgICBbY2xhc3NdPVwiYXhlc1Zpc2libGUgPyAndG9vbGJhci1pY29uLWFjdGl2ZScgOiAndG9vbGJhci1pY29uLWRhcmsnXCJcbiAgICAgIHN0eWxlPVwid2lkdGg6IDFyZW1cIlxuICAgIC8+XG4gIDwvcC1idXR0b24+XG4gIDwhLS0gU3VyZmFjZSB3aXJlZnJhbWUgdG9nZ2xlIChuYXBhcmktanMgV2ViR1BVIHN1cmZhY2Ugb25seSkuIC0tPlxuICA8cC1idXR0b25cbiAgICBpY29uPVwicGkgcGktc2hhcmUtYWx0XCJcbiAgICBzaXplPVwic21hbGxcIlxuICAgICpuZ0lmPVwiaXNOYXBhcmlTdXJmYWNlTW9kZVwiXG4gICAgW3RleHRdPVwiIXdpcmVmcmFtZUFjdGl2ZVwiXG4gICAgYXJpYUxhYmVsPVwiVG9nZ2xlIHdpcmVmcmFtZVwiXG4gICAgcFRvb2x0aXA9XCJUb2dnbGUgd2lyZWZyYW1lXCJcbiAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgIChvbkNsaWNrKT1cInRvZ2dsZVdpcmVmcmFtZS5lbWl0KClcIlxuICA+XG4gIDwvcC1idXR0b24+XG4gIDwhLS0gUmVzb2x1dGlvbiAoZGVjaW1hdGUgZmFjdG9yKSBmb3IgdGhlIG5hcGFyaSAzRCB0eXBlcyDigJQgcmVsb2FkcyBhdCBjb2Fyc2VyL2ZpbmVyIHNhbXBsaW5nLiAtLT5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzTmFwYXJpM2RNb2RlXCI+XG4gICAgPHNwYW4gY2xhc3M9XCJmbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBteC0xIHRvb2xiYXItdGV4dFwiPlJlczwvc3Bhbj5cbiAgICA8cC1kcm9wZG93blxuICAgICAgW29wdGlvbnNdPVwiZGVjaW1hdGVPcHRpb25zXCJcbiAgICAgIG9wdGlvbkxhYmVsPVwibGFiZWxcIlxuICAgICAgb3B0aW9uVmFsdWU9XCJ2YWx1ZVwiXG4gICAgICBbbmdNb2RlbF09XCJyZXNvbHV0aW9uU2NhbGVcIlxuICAgICAgYXBwZW5kVG89XCJib2R5XCJcbiAgICAgIGFyaWFMYWJlbD1cIlJlc29sdXRpb25cIlxuICAgICAgcFRvb2x0aXA9XCJSZXNvbHV0aW9uIChkZWNpbWF0ZSBmYWN0b3IpXCJcbiAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgICBbc3R5bGVdPVwieyAnbWluLXdpZHRoJzogJzZyZW0nIH1cIlxuICAgICAgKG9uQ2hhbmdlKT1cInNlbGVjdFJlc29sdXRpb24uZW1pdCgkZXZlbnQudmFsdWUpXCJcbiAgICA+XG4gICAgPC9wLWRyb3Bkb3duPlxuICA8L25nLWNvbnRhaW5lcj5cbjwvbmctY29udGFpbmVyPlxuIl19
107
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlldy1jb250cm9scy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL3Rvb2xiYXIvdmlldy1jb250cm9scy92aWV3LWNvbnRyb2xzLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvdG9vbGJhci92aWV3LWNvbnRyb2xzL3ZpZXctY29udHJvbHMuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNoRyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRWhELE9BQU8sRUFBRSx1QkFBdUIsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLDJCQUEyQixDQUFDOzs7Ozs7O0FBRTdGOzs7O0dBSUc7QUFTSCxNQUFNLE9BQU8scUJBQXFCO0lBUmxDO1FBU0UscUVBQXFFO1FBQzVELGNBQVMsR0FBRyxJQUFJLENBQUM7UUFDMUIscUNBQXFDO1FBQzVCLGNBQVMsR0FBRyxJQUFJLENBQUM7UUFDMUIsK0RBQStEO1FBQ3RELGdCQUFXLEdBQUcsSUFBSSxDQUFDO1FBQzVCLDJEQUEyRDtRQUNsRCxtQkFBYyxHQUFrQixJQUFJLENBQUM7UUFDOUMsc0RBQXNEO1FBQzdDLHdCQUFtQixHQUFHLFdBQVcsQ0FBQztRQUMzQywwREFBMEQ7UUFDakQsd0JBQW1CLEdBQUcsS0FBSyxDQUFDO1FBQ3JDLDJEQUEyRDtRQUNsRCxtQkFBYyxHQUFHLEtBQUssQ0FBQztRQUNoQyxtRUFBbUU7UUFDMUQsZUFBVSxHQUFHLEtBQUssQ0FBQztRQUM1Qix5Q0FBeUM7UUFDaEMsZ0JBQVcsR0FBRyxJQUFJLENBQUM7UUFDNUIsMENBQTBDO1FBQ2pDLG9CQUFlLEdBQUcsS0FBSyxDQUFDO1FBQ2pDLDJEQUEyRDtRQUNsRCxvQkFBZSxHQUFHLHVCQUF1QixDQUFDO1FBRW5ELHFEQUFxRDtRQUMzQyxtQkFBYyxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7UUFDdEQsd0JBQXdCO1FBQ2QsV0FBTSxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7UUFDNUMseUJBQXlCO1FBQ2YsWUFBTyxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7UUFDN0Msc0RBQXNEO1FBQzVDLHdCQUFtQixHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7UUFDM0QsMkJBQTJCO1FBQ2pCLHVCQUFrQixHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7UUFDeEQsdUNBQXVDO1FBQzdCLGVBQVUsR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBQ2hELDJDQUEyQztRQUNqQyxvQkFBZSxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7UUFDckQsOENBQThDO1FBQ3BDLHFCQUFnQixHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7UUFFeEQsMkRBQTJEO1FBQ3hDLG9CQUFlLEdBQUcsdUJBQXVCLENBQUM7S0FDOUQ7OEdBM0NZLHFCQUFxQjtrR0FBckIscUJBQXFCLGt0QkN0QmxDLHdnS0F3S0Esd2VEdkpZLFlBQVksa0lBQUUsV0FBVyw4VkFBRSxZQUFZLDZYQUFFLGNBQWMsdXRDQUFFLGFBQWE7OzJGQUtyRSxxQkFBcUI7a0JBUmpDLFNBQVM7K0JBQ0UsdUJBQXVCLGNBQ3JCLElBQUksV0FDUCxDQUFDLFlBQVksRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLGNBQWMsRUFBRSxhQUFhLENBQUMsbUJBR2hFLHVCQUF1QixDQUFDLE1BQU07OEJBSXRDLFNBQVM7c0JBQWpCLEtBQUs7Z0JBRUcsU0FBUztzQkFBakIsS0FBSztnQkFFRyxXQUFXO3NCQUFuQixLQUFLO2dCQUVHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBRUcsbUJBQW1CO3NCQUEzQixLQUFLO2dCQUVHLG1CQUFtQjtzQkFBM0IsS0FBSztnQkFFRyxjQUFjO3NCQUF0QixLQUFLO2dCQUVHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBRUcsV0FBVztzQkFBbkIsS0FBSztnQkFFRyxlQUFlO3NCQUF2QixLQUFLO2dCQUVHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBR0ksY0FBYztzQkFBdkIsTUFBTTtnQkFFRyxNQUFNO3NCQUFmLE1BQU07Z0JBRUcsT0FBTztzQkFBaEIsTUFBTTtnQkFFRyxtQkFBbUI7c0JBQTVCLE1BQU07Z0JBRUcsa0JBQWtCO3NCQUEzQixNQUFNO2dCQUVHLFVBQVU7c0JBQW5CLE1BQU07Z0JBRUcsZUFBZTtzQkFBeEIsTUFBTTtnQkFFRyxnQkFBZ0I7c0JBQXpCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IEJ1dHRvbk1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvYnV0dG9uJztcbmltcG9ydCB7IERyb3Bkb3duTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9kcm9wZG93bic7XG5pbXBvcnQgeyBUb29sdGlwTW9kdWxlIH0gZnJvbSAncHJpbWVuZy90b29sdGlwJztcblxuaW1wb3J0IHsgTkFQQVJJX0RFQ0lNQVRFX09QVElPTlMsIE5BUEFSSV9ERUZBVUxUX0RFQ0lNQVRFIH0gZnJvbSAnLi4vLi4vY29udHJhY3RzL3Bsb3QtdHlwZSc7XG5cbi8qKlxuICogVGhlIHRvb2xiYXIncyB2aWV3IGdyb3VwOiAyRCB6b29tIC8gcGFuIHRvb2xzLCBvciBmb3IgYSAzRCB2aWV3IHRoZSBjYW1lcmFcbiAqIG1vZGVzIGFuZCByZXNldCwgdGhlIG5hcGFyaSBheGVzIGFuZCB3aXJlZnJhbWUgdG9nZ2xlcyBhbmQgdGhlIDNEXG4gKiByZXNvbHV0aW9uLiBQcmVzZW50YXRpb25hbDogdGhlIGhvc3Qgb3ducyBldmVyeSB2YWx1ZS5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndG9vbGJhci12aWV3LWNvbnRyb2xzJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgRm9ybXNNb2R1bGUsIEJ1dHRvbk1vZHVsZSwgRHJvcGRvd25Nb2R1bGUsIFRvb2x0aXBNb2R1bGVdLFxuICB0ZW1wbGF0ZVVybDogJy4vdmlldy1jb250cm9scy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3ZpZXctY29udHJvbHMuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIFZpZXdDb250cm9sc0NvbXBvbmVudCB7XG4gIC8qKiBBIDJEIHZpZXcgKHpvb20gdG9vbHMpIHJhdGhlciB0aGFuIGEgM0Qgb25lIChjYW1lcmEgY29udHJvbHMpLiAqL1xuICBASW5wdXQoKSBpc0hlYXRtYXAgPSB0cnVlO1xuICAvKiogVGhlIGhvc3Qgc2hvd3MgdGhlIHpvb20gdG9vbHMuICovXG4gIEBJbnB1dCgpIHpvb21Ub29scyA9IHRydWU7XG4gIC8qKiBUaGUgT1NEIEltYWdlIHZpZXcgKHBhbnMgbmF0aXZlbHk7IG5vIFBsb3RseSBkcmFnLXpvb20pLiAqL1xuICBASW5wdXQoKSBpc0ltYWdlVmlldyA9IHRydWU7XG4gIC8qKiBUaGUgYXJtZWQgem9vbS9wYW4gdG9vbCAoYHpvb21gLCBgcGFuYCwg4oCmKSwgb3IgbnVsbC4gKi9cbiAgQElucHV0KCkgYWN0aXZlRHJhZ01vZGU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICAvKiogVGhlIDNEIGNhbWVyYSBtb2RlIChgdHVybnRhYmxlYCAvIGBvcmJpdGAgLyDigKYpLiAqL1xuICBASW5wdXQoKSBhY3RpdmVTdXJmYWNlM2RNb2RlID0gJ3R1cm50YWJsZSc7XG4gIC8qKiBUaGUgbmFwYXJpLWpzIHN1cmZhY2UgKHNob3dzIHRoZSB3aXJlZnJhbWUgdG9nZ2xlKS4gKi9cbiAgQElucHV0KCkgaXNOYXBhcmlTdXJmYWNlTW9kZSA9IGZhbHNlO1xuICAvKiogQSBuYXBhcmktanMgM0QgdmlldyAoc2hvd3MgdGhlIFJlc29sdXRpb24gZHJvcGRvd24pLiAqL1xuICBASW5wdXQoKSBpc05hcGFyaTNkTW9kZSA9IGZhbHNlO1xuICAvKiogV2hldGhlciB0aGUgdmlldyBkcmF3cyB0aGUgM0QgYXhlcyBnaXptbyAoc2hvd3MgaXRzIHRvZ2dsZSkuICovXG4gIEBJbnB1dCgpIGF4ZXNUb2dnbGUgPSBmYWxzZTtcbiAgLyoqIFRoZSBuYXBhcmkgM0QgYXhlcyBnaXptbyBpcyBzaG93bi4gKi9cbiAgQElucHV0KCkgYXhlc1Zpc2libGUgPSB0cnVlO1xuICAvKiogVGhlIG5hcGFyaSBzdXJmYWNlIHdpcmVmcmFtZSBpcyBvbi4gKi9cbiAgQElucHV0KCkgd2lyZWZyYW1lQWN0aXZlID0gZmFsc2U7XG4gIC8qKiBBY3RpdmUgbmFwYXJpIDNEIGRlY2ltYXRlIGZhY3RvciAoMSA9IEZ1bGwg4oCmIDggPSDihZspLiAqL1xuICBASW5wdXQoKSByZXNvbHV0aW9uU2NhbGUgPSBOQVBBUklfREVGQVVMVF9ERUNJTUFURTtcblxuICAvKiogQSB6b29tL3BhbiB0b29sIGJ1dHRvbiB3YXMgY2xpY2tlZCAoaXRzIG1vZGUpLiAqL1xuICBAT3V0cHV0KCkgdG9nZ2xlRHJhZ01vZGUgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgLyoqIFpvb20gaW4gb25lIHN0ZXAuICovXG4gIEBPdXRwdXQoKSB6b29tSW4gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBab29tIG91dCBvbmUgc3RlcC4gKi9cbiAgQE91dHB1dCgpIHpvb21PdXQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBBIDNEIGNhbWVyYSBtb2RlIGJ1dHRvbiB3YXMgY2xpY2tlZCAoaXRzIG1vZGUpLiAqL1xuICBAT3V0cHV0KCkgdG9nZ2xlU3VyZmFjZTNkTW9kZSA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICAvKiogUmVzZXQgdGhlIDNEIGNhbWVyYS4gKi9cbiAgQE91dHB1dCgpIHJlc2V0U3VyZmFjZUNhbWVyYSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIFRvZ2dsZSB0aGUgbmFwYXJpIDNEIGF4ZXMgZ2l6bW8uICovXG4gIEBPdXRwdXQoKSB0b2dnbGVBeGVzID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogVG9nZ2xlIHRoZSBuYXBhcmkgc3VyZmFjZSB3aXJlZnJhbWUuICovXG4gIEBPdXRwdXQoKSB0b2dnbGVXaXJlZnJhbWUgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBBIG5hcGFyaSAzRCBkZWNpbWF0ZSBmYWN0b3Igd2FzIHBpY2tlZC4gKi9cbiAgQE91dHB1dCgpIHNlbGVjdFJlc29sdXRpb24gPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcblxuICAvKiogRGVjaW1hdGUtZmFjdG9yIG9wdGlvbnMgZm9yIHRoZSBSZXNvbHV0aW9uIGRyb3Bkb3duLiAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZGVjaW1hdGVPcHRpb25zID0gTkFQQVJJX0RFQ0lNQVRFX09QVElPTlM7XG59XG4iLCI8IS0tIFpvb20gdG9vbHMuIFBsb3RseSBydWJiZXItYmFuZCBkcmFnLXpvb206IG9uIE9wZW5TZWFkcmFnb24gdGhlIGJveC16b29tXG4gICAgIGNvdmVycyB0aGlzIGFuZCBhIGJhcmUgZHJhZyBwYW5zIG5hdGl2ZWx5LCBzbyBpdCdzIGhpZGRlbiBpbiBpbWFnZSB2aWV3LiAtLT5cbjxuZy1jb250YWluZXIgKm5nSWY9XCJpc0hlYXRtYXAgJiYgem9vbVRvb2xzXCI+XG4gIDxzcGFuIGNsYXNzPVwidG9vbGJhci1zZXBhcmF0b3JcIj48L3NwYW4+XG4gIDxwLWJ1dHRvblxuICAgICpuZ0lmPVwiIWlzSW1hZ2VWaWV3XCJcbiAgICBpY29uPVwicGkgcGktc2VhcmNoXCJcbiAgICBzaXplPVwic21hbGxcIlxuICAgIFt0ZXh0XT1cImFjdGl2ZURyYWdNb2RlICE9PSAnem9vbSdcIlxuICAgIGFyaWFMYWJlbD1cIlpvb20gZHJhZ1wiXG4gICAgcFRvb2x0aXA9XCJab29tIGRyYWdcIlxuICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgKG9uQ2xpY2spPVwidG9nZ2xlRHJhZ01vZGUuZW1pdCgnem9vbScpXCJcbiAgPlxuICA8L3AtYnV0dG9uPlxuICA8cC1idXR0b25cbiAgICBzaXplPVwic21hbGxcIlxuICAgIFt0ZXh0XT1cImFjdGl2ZURyYWdNb2RlICE9PSAnem9vbVRvQm94J1wiXG4gICAgYXJpYUxhYmVsPVwiWm9vbSBib3hcIlxuICAgIHBUb29sdGlwPVwiWm9vbSBib3ggKDxrYmQ+Yjwva2JkPilcIlxuICAgIFtlc2NhcGVdPVwiZmFsc2VcIlxuICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgKG9uQ2xpY2spPVwidG9nZ2xlRHJhZ01vZGUuZW1pdCgnem9vbVRvQm94JylcIlxuICA+XG4gICAgPGltZ1xuICAgICAgc3JjPVwiYXNzZXRzL3Bsb3R0aW5nL3pvb20tYm94LnN2Z1wiXG4gICAgICBbY2xhc3NdPVwiYWN0aXZlRHJhZ01vZGUgPT09ICd6b29tVG9Cb3gnID8gJ3Rvb2xiYXItaWNvbi1hY3RpdmUnIDogJ3Rvb2xiYXItaWNvbi1kYXJrJ1wiXG4gICAgICBzdHlsZT1cIndpZHRoOiAxcmVtXCJcbiAgICAvPlxuICA8L3AtYnV0dG9uPlxuICA8cC1idXR0b25cbiAgICBpY29uPVwicGkgcGktYXJyb3dzLWFsdFwiXG4gICAgc2l6ZT1cInNtYWxsXCJcbiAgICBbdGV4dF09XCJhY3RpdmVEcmFnTW9kZSAhPT0gJ3BhbidcIlxuICAgIGFyaWFMYWJlbD1cIlBhbiB0aGUgaW1hZ2VcIlxuICAgIHBUb29sdGlwPVwiUGFuIHRoZSBpbWFnZSAoPGtiZD5wPC9rYmQ+KVwiXG4gICAgW2VzY2FwZV09XCJmYWxzZVwiXG4gICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAob25DbGljayk9XCJ0b2dnbGVEcmFnTW9kZS5lbWl0KCdwYW4nKVwiXG4gID5cbiAgPC9wLWJ1dHRvbj5cbiAgPHAtYnV0dG9uXG4gICAgaWNvbj1cInBpIHBpLXNlYXJjaC1wbHVzXCJcbiAgICBzaXplPVwic21hbGxcIlxuICAgIFt0ZXh0XT1cInRydWVcIlxuICAgIGFyaWFMYWJlbD1cIlpvb20gaW5cIlxuICAgIHBUb29sdGlwPVwiWm9vbSBpbiAoPGtiZD4rPC9rYmQ+KVwiXG4gICAgW2VzY2FwZV09XCJmYWxzZVwiXG4gICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAob25DbGljayk9XCJ6b29tSW4uZW1pdCgpXCJcbiAgPlxuICA8L3AtYnV0dG9uPlxuICA8cC1idXR0b25cbiAgICBpY29uPVwicGkgcGktc2VhcmNoLW1pbnVzXCJcbiAgICBzaXplPVwic21hbGxcIlxuICAgIFt0ZXh0XT1cInRydWVcIlxuICAgIGFyaWFMYWJlbD1cIlpvb20gb3V0XCJcbiAgICBwVG9vbHRpcD1cIlpvb20gb3V0ICg8a2JkPi08L2tiZD4pXCJcbiAgICBbZXNjYXBlXT1cImZhbHNlXCJcbiAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgIChvbkNsaWNrKT1cInpvb21PdXQuZW1pdCgpXCJcbiAgPlxuICA8L3AtYnV0dG9uPlxuPC9uZy1jb250YWluZXI+XG5cbjwhLS0gU3VyZmFjZSAzRCBjb250cm9scyAtLT5cbjxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNIZWF0bWFwXCI+XG4gIDxzcGFuIGNsYXNzPVwidG9vbGJhci1zZXBhcmF0b3JcIj48L3NwYW4+XG4gIDxwLWJ1dHRvblxuICAgIGljb249XCJwaSBwaS1zZWFyY2hcIlxuICAgIHNpemU9XCJzbWFsbFwiXG4gICAgW3RleHRdPVwiYWN0aXZlU3VyZmFjZTNkTW9kZSAhPT0gJ3pvb20nXCJcbiAgICBhcmlhTGFiZWw9XCJab29tXCJcbiAgICBwVG9vbHRpcD1cIlpvb21cIlxuICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgKG9uQ2xpY2spPVwidG9nZ2xlU3VyZmFjZTNkTW9kZS5lbWl0KCd6b29tJylcIlxuICA+XG4gIDwvcC1idXR0b24+XG4gIDxwLWJ1dHRvblxuICAgIGljb249XCJwaSBwaS1hcnJvd3MtYWx0XCJcbiAgICBzaXplPVwic21hbGxcIlxuICAgIFt0ZXh0XT1cImFjdGl2ZVN1cmZhY2UzZE1vZGUgIT09ICdwYW4nXCJcbiAgICBhcmlhTGFiZWw9XCJQYW5cIlxuICAgIHBUb29sdGlwPVwiUGFuXCJcbiAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgIChvbkNsaWNrKT1cInRvZ2dsZVN1cmZhY2UzZE1vZGUuZW1pdCgncGFuJylcIlxuICA+XG4gIDwvcC1idXR0b24+XG4gIDxwLWJ1dHRvblxuICAgIGljb249XCJwaSBwaS1nbG9iZVwiXG4gICAgc2l6ZT1cInNtYWxsXCJcbiAgICBbdGV4dF09XCJhY3RpdmVTdXJmYWNlM2RNb2RlICE9PSAnb3JiaXQnXCJcbiAgICBhcmlhTGFiZWw9XCJPcmJpdGFsIHJvdGF0aW9uXCJcbiAgICBwVG9vbHRpcD1cIk9yYml0YWwgcm90YXRpb25cIlxuICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgKG9uQ2xpY2spPVwidG9nZ2xlU3VyZmFjZTNkTW9kZS5lbWl0KCdvcmJpdCcpXCJcbiAgPlxuICA8L3AtYnV0dG9uPlxuICA8cC1idXR0b25cbiAgICBpY29uPVwicGkgcGktc3luY1wiXG4gICAgc2l6ZT1cInNtYWxsXCJcbiAgICBbdGV4dF09XCJhY3RpdmVTdXJmYWNlM2RNb2RlICE9PSAndHVybnRhYmxlJ1wiXG4gICAgYXJpYUxhYmVsPVwiVHVybnRhYmxlIHJvdGF0aW9uXCJcbiAgICBwVG9vbHRpcD1cIlR1cm50YWJsZSByb3RhdGlvblwiXG4gICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAob25DbGljayk9XCJ0b2dnbGVTdXJmYWNlM2RNb2RlLmVtaXQoJ3R1cm50YWJsZScpXCJcbiAgPlxuICA8L3AtYnV0dG9uPlxuICA8cC1idXR0b25cbiAgICBpY29uPVwicGkgcGktaG9tZVwiXG4gICAgc2l6ZT1cInNtYWxsXCJcbiAgICBbdGV4dF09XCJ0cnVlXCJcbiAgICBhcmlhTGFiZWw9XCJSZXNldCBjYW1lcmFcIlxuICAgIHBUb29sdGlwPVwiUmVzZXQgY2FtZXJhIHRvIGRlZmF1bHRcIlxuICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgKG9uQ2xpY2spPVwicmVzZXRTdXJmYWNlQ2FtZXJhLmVtaXQoKVwiXG4gID5cbiAgPC9wLWJ1dHRvbj5cbiAgPCEtLSAzRCBjb29yZGluYXRlLWF4ZXMgLyBzY2FsZSBnaXptbyB0b2dnbGUgKG5hcGFyaS1qcyBXZWJHUFUgdm9sdW1lL2lzb3N1cmZhY2UsIGFuZCB0aGUgM0RcbiAgICAgICBzcGF0aWFsIGNsb3VkKS5cbiAgICAgICBgcC1idXR0b24taWNvbi1vbmx5YCBnaXZlcyB0aGUgc2FtZSBzcXVhcmUgc2l6aW5nIGFzIHRoZSBuZWlnaGJvdXJpbmcgcGktaWNvbiBidXR0b25zXG4gICAgICAgKHRoZSBwcm9qZWN0ZWQgPGltZz4gZG9lc24ndCB0cmlnZ2VyIFByaW1lTkcncyBhdXRvbWF0aWMgaWNvbi1vbmx5IHNpemluZykuIC0tPlxuICA8cC1idXR0b25cbiAgICBzaXplPVwic21hbGxcIlxuICAgICpuZ0lmPVwiYXhlc1RvZ2dsZVwiXG4gICAgc3R5bGVDbGFzcz1cInAtYnV0dG9uLWljb24tb25seVwiXG4gICAgW3RleHRdPVwiIWF4ZXNWaXNpYmxlXCJcbiAgICBhcmlhTGFiZWw9XCJUb2dnbGUgM0QgYXhlc1wiXG4gICAgcFRvb2x0aXA9XCJUb2dnbGUgM0QgYXhlcyAvIHNjYWxlXCJcbiAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgIChvbkNsaWNrKT1cInRvZ2dsZUF4ZXMuZW1pdCgpXCJcbiAgPlxuICAgIDxpbWdcbiAgICAgIHNyYz1cImFzc2V0cy9wbG90dGluZy8zZC1jb29yZGluYXRlcy5zdmdcIlxuICAgICAgW2NsYXNzXT1cImF4ZXNWaXNpYmxlID8gJ3Rvb2xiYXItaWNvbi1hY3RpdmUnIDogJ3Rvb2xiYXItaWNvbi1kYXJrJ1wiXG4gICAgICBzdHlsZT1cIndpZHRoOiAxcmVtXCJcbiAgICAvPlxuICA8L3AtYnV0dG9uPlxuICA8IS0tIFN1cmZhY2Ugd2lyZWZyYW1lIHRvZ2dsZSAobmFwYXJpLWpzIFdlYkdQVSBzdXJmYWNlIG9ubHkpLiAtLT5cbiAgPHAtYnV0dG9uXG4gICAgaWNvbj1cInBpIHBpLXNoYXJlLWFsdFwiXG4gICAgc2l6ZT1cInNtYWxsXCJcbiAgICAqbmdJZj1cImlzTmFwYXJpU3VyZmFjZU1vZGVcIlxuICAgIFt0ZXh0XT1cIiF3aXJlZnJhbWVBY3RpdmVcIlxuICAgIGFyaWFMYWJlbD1cIlRvZ2dsZSB3aXJlZnJhbWVcIlxuICAgIHBUb29sdGlwPVwiVG9nZ2xlIHdpcmVmcmFtZVwiXG4gICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAob25DbGljayk9XCJ0b2dnbGVXaXJlZnJhbWUuZW1pdCgpXCJcbiAgPlxuICA8L3AtYnV0dG9uPlxuICA8IS0tIFJlc29sdXRpb24gKGRlY2ltYXRlIGZhY3RvcikgZm9yIHRoZSBuYXBhcmkgM0QgdHlwZXMg4oCUIHJlbG9hZHMgYXQgY29hcnNlci9maW5lciBzYW1wbGluZy4gLS0+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc05hcGFyaTNkTW9kZVwiPlxuICAgIDxzcGFuIGNsYXNzPVwiZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIgbXgtMSB0b29sYmFyLXRleHRcIj5SZXM8L3NwYW4+XG4gICAgPHAtZHJvcGRvd25cbiAgICAgIFtvcHRpb25zXT1cImRlY2ltYXRlT3B0aW9uc1wiXG4gICAgICBvcHRpb25MYWJlbD1cImxhYmVsXCJcbiAgICAgIG9wdGlvblZhbHVlPVwidmFsdWVcIlxuICAgICAgW25nTW9kZWxdPVwicmVzb2x1dGlvblNjYWxlXCJcbiAgICAgIGFwcGVuZFRvPVwiYm9keVwiXG4gICAgICBhcmlhTGFiZWw9XCJSZXNvbHV0aW9uXCJcbiAgICAgIHBUb29sdGlwPVwiUmVzb2x1dGlvbiAoZGVjaW1hdGUgZmFjdG9yKVwiXG4gICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgICAgW3N0eWxlXT1cInsgJ21pbi13aWR0aCc6ICc2cmVtJyB9XCJcbiAgICAgIChvbkNoYW5nZSk9XCJzZWxlY3RSZXNvbHV0aW9uLmVtaXQoJGV2ZW50LnZhbHVlKVwiXG4gICAgPlxuICAgIDwvcC1kcm9wZG93bj5cbiAgPC9uZy1jb250YWluZXI+XG48L25nLWNvbnRhaW5lcj5cbiJdfQ==