@jax-data-science/sci-image-visualizer 0.16.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/esm2022/lib/contracts/display-types.mjs +4 -2
  2. package/esm2022/lib/contracts/image.contract.mjs +1 -1
  3. package/esm2022/lib/contracts/ports/spatial-data.port.mjs +1 -1
  4. package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
  5. package/esm2022/lib/contracts/region-store.contract.mjs +1 -1
  6. package/esm2022/lib/contracts/spatial-dataset.contract.mjs +1 -1
  7. package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
  8. package/esm2022/lib/geometry/cell-meshes.mjs +37 -0
  9. package/esm2022/lib/geometry/place.mjs +47 -0
  10. package/esm2022/lib/implementations/napari-js/napari-camera-depth.mjs +93 -0
  11. package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +1 -1
  12. package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +2 -2
  13. package/esm2022/lib/implementations/napari-js/napari-scene.mjs +1 -1
  14. package/esm2022/lib/implementations/napari-js/napari-spatial-2d-scene.mjs +86 -18
  15. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-cells.mjs +746 -0
  16. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +343 -18
  17. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-transcripts.mjs +427 -0
  18. package/esm2022/lib/implementations/napari-js/napari-spatial-encoding.mjs +11 -4
  19. package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +95 -5
  20. package/esm2022/lib/implementations/napari-js/napari-spatial-scene.mjs +15 -1
  21. package/esm2022/lib/implementations/napari-js/napari-spatial-tiles.mjs +35 -8
  22. package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +40 -1
  23. package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +136 -28
  24. package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +19 -3
  25. package/esm2022/lib/implementations/napari-js/spatial-tiles/cell-layers.mjs +188 -52
  26. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-layers.mjs +35 -11
  27. package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +2 -2
  28. package/esm2022/lib/implementations/spatial-data-http/spatial-data-http.service.mjs +10 -1
  29. package/esm2022/lib/region-editor/class-tree/class-tree.component.mjs +30 -3
  30. package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +15 -3
  31. package/esm2022/lib/region-editor/region-editor.component.mjs +24 -4
  32. package/esm2022/lib/region-source/region-source-ops.mjs +7 -1
  33. package/esm2022/lib/region-source/region-tiles.mjs +1 -1
  34. package/esm2022/lib/region-source/worker-region-source.mjs +24 -1
  35. package/esm2022/lib/routing-visualizer.service.mjs +404 -7
  36. package/esm2022/lib/spatial/observations-in-selection.mjs +83 -0
  37. package/esm2022/lib/spatial/plane-cells.mjs +119 -0
  38. package/esm2022/lib/spatial/spatial-controls.facade.mjs +304 -8
  39. package/esm2022/lib/spatial/spatial-encoding.mjs +52 -3
  40. package/esm2022/lib/spatial/spatial-hover.mjs +34 -1
  41. package/esm2022/lib/spatial/spatial-planes.mjs +49 -0
  42. package/esm2022/lib/spatial/spatial-selection.mjs +2 -2
  43. package/esm2022/lib/spatial/spatial-tile-merge.mjs +38 -1
  44. package/esm2022/lib/spatial/transcripts-in-selection.mjs +208 -0
  45. package/esm2022/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.mjs +42 -65
  46. package/esm2022/lib/spatial-controls/spatial-charts/spatial-charts.component.mjs +6 -2
  47. package/esm2022/lib/spatial-controls/spatial-color-by/spatial-color-by.component.mjs +187 -0
  48. package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +51 -12
  49. package/esm2022/lib/spatial-controls/spatial-gene-style/spatial-gene-style.component.mjs +7 -3
  50. package/esm2022/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.mjs +21 -6
  51. package/esm2022/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.mjs +94 -13
  52. package/esm2022/lib/spatial-controls/spatial-key/spatial-key.component.mjs +3 -3
  53. package/esm2022/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.mjs +3 -3
  54. package/esm2022/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.mjs +79 -57
  55. package/esm2022/lib/spatial-controls/spatial-selection-observations/spatial-selection-observations.component.mjs +101 -0
  56. package/esm2022/lib/spatial-controls/spatial-selection-transcripts/spatial-selection-transcripts.component.mjs +94 -0
  57. package/esm2022/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.mjs +9 -3
  58. package/esm2022/lib/store/region-source-scope.mjs +10 -1
  59. package/esm2022/lib/store/region-store.service.mjs +33 -2
  60. package/esm2022/lib/toolbar/toolbar.component.mjs +10 -3
  61. package/esm2022/lib/visualizer/spatial-region-set.mjs +95 -0
  62. package/esm2022/lib/visualizer.component.mjs +40 -4
  63. package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CYsPzX3J.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CBiLcnE6.mjs} +4838 -656
  64. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CBiLcnE6.mjs.map +1 -0
  65. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-DaZVXq1s.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-BXHjv4PE.mjs} +2 -2
  66. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-DaZVXq1s.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-BXHjv4PE.mjs.map} +1 -1
  67. package/fesm2022/jax-data-science-sci-image-visualizer.mjs +1 -1
  68. package/fesm2022/region-source.worker.js +84 -2
  69. package/lib/contracts/display-types.d.ts +99 -6
  70. package/lib/contracts/image.contract.d.ts +6 -0
  71. package/lib/contracts/ports/spatial-data.port.d.ts +7 -0
  72. package/lib/contracts/region-editor-api.contract.d.ts +9 -0
  73. package/lib/contracts/region-store.contract.d.ts +6 -0
  74. package/lib/contracts/spatial-dataset.contract.d.ts +7 -1
  75. package/lib/contracts/visualizer.contract.d.ts +43 -1
  76. package/lib/geometry/cell-meshes.d.ts +27 -0
  77. package/lib/geometry/place.d.ts +45 -0
  78. package/lib/implementations/napari-js/napari-camera-depth.d.ts +23 -0
  79. package/lib/implementations/napari-js/napari-loading-state.d.ts +1 -1
  80. package/lib/implementations/napari-js/napari-scene.d.ts +12 -0
  81. package/lib/implementations/napari-js/napari-spatial-2d-scene.d.ts +19 -3
  82. package/lib/implementations/napari-js/napari-spatial-3d-cells.d.ts +141 -0
  83. package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +89 -0
  84. package/lib/implementations/napari-js/napari-spatial-3d-transcripts.d.ts +103 -0
  85. package/lib/implementations/napari-js/napari-spatial-encoding.d.ts +9 -2
  86. package/lib/implementations/napari-js/napari-spatial-hover.d.ts +22 -0
  87. package/lib/implementations/napari-js/napari-spatial-scene.d.ts +12 -0
  88. package/lib/implementations/napari-js/napari-spatial-tiles.d.ts +20 -6
  89. package/lib/implementations/napari-js/napari-visualizer.service.d.ts +27 -1
  90. package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +48 -16
  91. package/lib/implementations/napari-js/napari-volume-scene.d.ts +2 -0
  92. package/lib/implementations/napari-js/spatial-tiles/cell-layers.d.ts +54 -1
  93. package/lib/implementations/napari-js/spatial-tiles/transcript-layers.d.ts +11 -2
  94. package/lib/implementations/spatial-data-http/spatial-data-http.service.d.ts +7 -0
  95. package/lib/region-editor/class-tree/class-tree.component.d.ts +16 -1
  96. package/lib/region-editor/classes-panel/classes-panel.component.d.ts +10 -1
  97. package/lib/region-editor/region-editor.component.d.ts +4 -0
  98. package/lib/region-source/region-source-ops.d.ts +12 -0
  99. package/lib/region-source/region-tiles.d.ts +8 -0
  100. package/lib/region-source/worker-region-source.d.ts +18 -0
  101. package/lib/routing-visualizer.service.d.ts +140 -1
  102. package/lib/spatial/observations-in-selection.d.ts +43 -0
  103. package/lib/spatial/plane-cells.d.ts +37 -0
  104. package/lib/spatial/spatial-controls.facade.d.ts +59 -0
  105. package/lib/spatial/spatial-encoding.d.ts +24 -1
  106. package/lib/spatial/spatial-hover.d.ts +23 -0
  107. package/lib/spatial/spatial-planes.d.ts +22 -0
  108. package/lib/spatial/spatial-selection.d.ts +2 -1
  109. package/lib/spatial/spatial-tile-merge.d.ts +9 -0
  110. package/lib/spatial/transcripts-in-selection.d.ts +95 -0
  111. package/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.d.ts +19 -28
  112. package/lib/spatial-controls/spatial-color-by/spatial-color-by.component.d.ts +64 -0
  113. package/lib/spatial-controls/spatial-controls.component.d.ts +19 -2
  114. package/lib/spatial-controls/spatial-gene-style/spatial-gene-style.component.d.ts +3 -1
  115. package/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.d.ts +7 -0
  116. package/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.d.ts +28 -7
  117. package/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.d.ts +26 -23
  118. package/lib/spatial-controls/spatial-selection-observations/spatial-selection-observations.component.d.ts +48 -0
  119. package/lib/spatial-controls/spatial-selection-transcripts/spatial-selection-transcripts.component.d.ts +43 -0
  120. package/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.d.ts +3 -1
  121. package/lib/store/region-source-scope.d.ts +4 -0
  122. package/lib/store/region-store.service.d.ts +21 -0
  123. package/lib/toolbar/toolbar.component.d.ts +6 -1
  124. package/lib/visualizer/spatial-region-set.d.ts +55 -0
  125. package/lib/visualizer.component.d.ts +14 -0
  126. package/package.json +2 -2
  127. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CYsPzX3J.mjs.map +0 -1
@@ -51,6 +51,11 @@ export class ToolbarComponent {
51
51
  this.isoRange = [0, 255];
52
52
  /** The last slice index of a stack. */
53
53
  this.maxIndex = 0;
54
+ /**
55
+ * The image is one plane, but a spatial dataset's region set slices it into planes: the live
56
+ * views offer the slider over them ({@link maxIndex} is the last plane), as over a stack.
57
+ */
58
+ this.planeSlices = false;
54
59
  /** The current slice (0-based). */
55
60
  this.zIndex = 0;
56
61
  /** True for any 2D (non Surface-3D) plot type. */
@@ -273,7 +278,7 @@ export class ToolbarComponent {
273
278
  this.displayHelpDialog = true;
274
279
  }
275
280
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: ToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
276
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: ToolbarComponent, isStandalone: true, selector: "plotting-toolbar", inputs: { imageInfo: "imageInfo", hasSpatialDataset: "hasSpatialDataset", plotTypeOptions: "plotTypeOptions", selectedPlotType: "selectedPlotType", basePlotType: "basePlotType", isoRange: "isoRange", maxIndex: "maxIndex", zIndex: "zIndex", isHeatmap: "isHeatmap", is3dRegions: "is3dRegions", isVolumeView: "isVolumeView", sliceEditor: "sliceEditor", activeDragMode: "activeDragMode", activeSurface3dMode: "activeSurface3dMode", axesVisible: "axesVisible", wireframeActive: "wireframeActive", resolutionScale: "resolutionScale", wandSensitivity: "wandSensitivity", brushSize: "brushSize", vertexEraserRadius: "vertexEraserRadius", canUndo: "canUndo", canRedo: "canRedo", stackOptions: "stackOptions", tools: "tools", imageSmoothingEnabled: "imageSmoothingEnabled", samModels: "samModels", samModelId: "samModelId", contributedTools: "contributedTools", dialogTools: "dialogTools", openDialogToolId: "openDialogToolId", toolModelIds: "toolModelIds" }, outputs: { selectPlotType: "selectPlotType", addProfileLine: "addProfileLine", toggleImageSmoothing: "toggleImageSmoothing", isoRangeChange: "isoRangeChange", openChannelHistogram: "openChannelHistogram", openSpatialControls: "openSpatialControls", openRegionEditor: "openRegionEditor", toggleSliceEditor: "toggleSliceEditor", selectStackOption: "selectStackOption", zScrub: "zScrub", zSlide: "zSlide", zIndexInput: "zIndexInput", reloadAndPlot: "reloadAndPlot", downloadImage: "downloadImage", autoscaleImage: "autoscaleImage", toggleDragMode: "toggleDragMode", zoomIn: "zoomIn", zoomOut: "zoomOut", toggleSurface3dMode: "toggleSurface3dMode", resetSurfaceCamera: "resetSurfaceCamera", toggleAxes: "toggleAxes", toggleWireframe: "toggleWireframe", selectResolution: "selectResolution", deleteRegion: "deleteRegion", undoRegion: "undoRegion", redoRegion: "redoRegion", segmentRegions: "segmentRegions", segmentCellpose: "segmentCellpose", runTool: "runTool", toggleDialogTool: "toggleDialogTool", toolModelChange: "toolModelChange", openToolParams: "openToolParams", samModelChange: "samModelChange", wandSensitivityChange: "wandSensitivityChange", brushSizeChange: "brushSizeChange", vertexEraserRadiusChange: "vertexEraserRadiusChange" }, ngImport: i0, template: "<p-toolbar>\n <div class=\"p-toolbar-group-start flex-wrap align-items-center gap-1\">\n <!-- Host-provided custom toolbar buttons, shown first (e.g. app-specific\n actions the visualization view itself doesn't own). -->\n <ng-content></ng-content>\n\n <!-- Contributed dialog tools (TOOLBAR_TOOLS, kind: 'dialog'): app-level actions\n like the host's own buttons above, so they sit right beside them. Image view\n only, the view their dialog draws over. Highlighted while the dialog is open. -->\n <ng-container *ngIf=\"isImageView\">\n <p-button\n *ngFor=\"let tool of dialogTools; trackBy: trackToolById\"\n size=\"small\"\n [text]=\"openDialogToolId !== tool.id\"\n [pTooltip]=\"tool.tooltip\"\n tooltipPosition=\"bottom\"\n [ariaLabel]=\"tool.label\"\n [attr.aria-pressed]=\"openDialogToolId === tool.id\"\n (onClick)=\"toggleDialogTool.emit(tool.id)\"\n >\n <img\n *ngIf=\"tool.icon.src\"\n [src]=\"tool.icon.src\"\n style=\"width: 1rem\"\n [alt]=\"tool.label\"\n [class]=\"openDialogToolId === tool.id ? 'toolbar-icon-active' : 'toolbar-icon-dark'\"\n />\n <i *ngIf=\"tool.icon.pi\" class=\"pi {{ tool.icon.pi }}\"></i>\n </p-button>\n </ng-container>\n\n <!-- Plot type: available for any image (grayscale or RGB), and for a spatial dataset\n that brings none (its spatial modes are still a choice). -->\n <toolbar-plot-type-selector\n *ngIf=\"showPlotTypes\"\n [options]=\"plotTypeOptions\"\n [selected]=\"selectedPlotType\"\n [isosurface]=\"isIsosurfaceMode\"\n [isoRange]=\"isoRange\"\n [intensityLines]=\"isIntensityCapable\"\n (selectPlotType)=\"selectPlotType.emit($event)\"\n (isoRangeChange)=\"isoRangeChange.emit($event)\"\n (addProfileLine)=\"addProfileLine.emit()\"\n >\n </toolbar-plot-type-selector>\n <!-- Channels & Histogram: brightness/contrast, gamma, per-channel display,\n colormap/reverse/invert \u2014 opens the floating dialog. -->\n <p-button\n *ngIf=\"tools.specialTools\"\n pRipple\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Channels &amp; Histogram\"\n pTooltip=\"Channels &amp; Histogram (brightness/contrast, colormap)\"\n tooltipPosition=\"bottom\"\n (onClick)=\"openChannelHistogram.emit()\"\n >\n <img src=\"assets/plotting/invert.svg\" class=\"toolbar-icon-dark\" style=\"width: 1rem\" />\n </p-button>\n\n <!-- Spatial-omics controls. Only meaningful in the spatial mode, which is\n itself only offered while a dataset is loaded \u2014 so this button appears\n exactly when there is something for it to control. -->\n <p-button\n *ngIf=\"tools.specialTools && isSpatialMode\"\n pRipple\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Spatial omics controls\"\n pTooltip=\"Spatial omics (colour by column or gene, legend, selection, distributions)\"\n tooltipPosition=\"bottom\"\n (onClick)=\"openSpatialControls.emit()\"\n >\n <img src=\"assets/plotting/spatial-omics.svg\" class=\"toolbar-icon-dark\" style=\"width: 1rem\" />\n </p-button>\n\n <!-- Smoothen toggle: bilinear smoothing vs nearest-neighbour raw pixels (Image\n view only \u2014 it's an OpenSeadragon drawer setting). Highlighted when smoothing on. -->\n <p-button\n *ngIf=\"tools.specialTools && isImageView\"\n size=\"small\"\n [text]=\"!imageSmoothingEnabled\"\n ariaLabel=\"Smoothen\"\n pTooltip=\"Smoothen (turn on image smoothing)\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleImageSmoothing.emit()\"\n >\n <img\n src=\"assets/plotting/smooth.svg\"\n style=\"width: 1rem\"\n [class]=\"imageSmoothingEnabled ? 'toolbar-icon-active' : 'toolbar-icon-dark'\"\n />\n </p-button>\n\n <!-- Stack controls -->\n <toolbar-stack-controls\n *ngIf=\"imageInfo?.isStack\"\n [liveScrubber]=\"showsLiveSliceScrubber\"\n [stackToggle]=\"!showsLiveSliceScrubber && !isNapariMode && !isSpatialMode\"\n [showStack]=\"!!imageInfo?.showStack\"\n [stackOptions]=\"stackOptions\"\n [zIndex]=\"zIndex\"\n [maxIndex]=\"maxIndex\"\n (zScrub)=\"zScrub.emit($event)\"\n (zSlide)=\"zSlide.emit($event)\"\n (selectStackOption)=\"selectStackOption.emit($event)\"\n (zIndexInput)=\"zIndexInput.emit($event)\"\n (reloadAndPlot)=\"reloadAndPlot.emit()\"\n >\n </toolbar-stack-controls>\n\n <!-- Image actions (special tools) -->\n <ng-container *ngIf=\"tools.specialTools\">\n <span class=\"toolbar-separator\"></span>\n <p-button\n icon=\"pi pi-download\"\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Download image as PNG\"\n pTooltip=\"Download image as PNG\"\n tooltipPosition=\"bottom\"\n (onClick)=\"downloadImage.emit()\"\n >\n </p-button>\n <p-button\n *ngIf=\"isHeatmap\"\n icon=\"pi pi-window-maximize\"\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Fit to view\"\n pTooltip=\"Fit to view\"\n tooltipPosition=\"bottom\"\n (onClick)=\"autoscaleImage.emit()\"\n >\n </p-button>\n </ng-container>\n\n <toolbar-view-controls\n [isHeatmap]=\"isHeatmap\"\n [zoomTools]=\"tools.zoomTools\"\n [isImageView]=\"isImageView\"\n [activeDragMode]=\"activeDragMode\"\n [activeSurface3dMode]=\"activeSurface3dMode\"\n [axesToggle]=\"showsAxesToggle\"\n [isNapariSurfaceMode]=\"isNapariSurfaceMode\"\n [isNapari3dMode]=\"isNapari3dMode\"\n [axesVisible]=\"axesVisible\"\n [wireframeActive]=\"wireframeActive\"\n [resolutionScale]=\"resolutionScale\"\n (toggleDragMode)=\"toggleDragMode.emit($event)\"\n (zoomIn)=\"zoomIn.emit()\"\n (zoomOut)=\"zoomOut.emit()\"\n (toggleSurface3dMode)=\"toggleSurface3dMode.emit($event)\"\n (resetSurfaceCamera)=\"resetSurfaceCamera.emit()\"\n (toggleAxes)=\"toggleAxes.emit()\"\n (toggleWireframe)=\"toggleWireframe.emit()\"\n (selectResolution)=\"selectResolution.emit($event)\"\n >\n </toolbar-view-controls>\n\n <!-- A volume view draws no regions; the Region Editor shows them in it in 3D, and the\n selection tool picks their surfaces there. The slice editor splits the view: the slice,\n with every region tool, beside the 3D view. -->\n <ng-container *ngIf=\"isVolumeView && !isHeatmap && !is3dRegions && tools.regionTools\">\n <span class=\"toolbar-separator\"></span>\n <p-button\n size=\"small\"\n [text]=\"!sliceEditor\"\n ariaLabel=\"Slice editor\"\n [attr.aria-pressed]=\"sliceEditor\"\n [pTooltip]=\"\n sliceEditor\n ? 'Close the slice editor'\n : 'Slice editor: the slice and the sections through x and y beside the 3D view'\n \"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleSliceEditor.emit()\"\n >\n <img\n src=\"assets/plotting/slice.svg\"\n style=\"width: 1rem\"\n alt=\"\"\n [class]=\"sliceEditor ? 'toolbar-icon-active' : 'toolbar-icon-dark'\"\n />\n </p-button>\n <toolbar-region-tools\n *ngIf=\"!sliceEditor\"\n [activeDragMode]=\"activeDragMode\"\n [selectOnly]=\"true\"\n [canUndo]=\"canUndo\"\n [canRedo]=\"canRedo\"\n (openRegionEditor)=\"openRegionEditor.emit()\"\n (toggleDragMode)=\"toggleDragMode.emit($event)\"\n (undoRegion)=\"undoRegion.emit()\"\n (redoRegion)=\"redoRegion.emit()\"\n (deleteRegion)=\"deleteRegion.emit()\"\n >\n </toolbar-region-tools>\n </ng-container>\n <ng-container *ngIf=\"(isHeatmap || is3dRegions || (isVolumeView && sliceEditor)) && tools.regionTools\">\n <toolbar-region-tools\n [activeDragMode]=\"activeDragMode\"\n [is3dRegions]=\"is3dRegions\"\n [vertexTools]=\"supportsRegionVertexTools || (isVolumeView && sliceEditor)\"\n [wandSensitivity]=\"wandSensitivity\"\n [brushSize]=\"brushSize\"\n [vertexEraserRadius]=\"vertexEraserRadius\"\n [canUndo]=\"canUndo\"\n [canRedo]=\"canRedo\"\n (openRegionEditor)=\"openRegionEditor.emit()\"\n (toggleDragMode)=\"toggleDragMode.emit($event)\"\n (undoRegion)=\"undoRegion.emit()\"\n (redoRegion)=\"redoRegion.emit()\"\n (deleteRegion)=\"deleteRegion.emit()\"\n (wandSensitivityChange)=\"wandSensitivityChange.emit($event)\"\n (brushSizeChange)=\"brushSizeChange.emit($event)\"\n (vertexEraserRadiusChange)=\"vertexEraserRadiusChange.emit($event)\"\n >\n </toolbar-region-tools>\n <toolbar-segmentation-tools\n [activeDragMode]=\"activeDragMode\"\n [samModels]=\"samModels\"\n [samModelId]=\"samModelId\"\n [contributedTools]=\"contributedTools\"\n [toolModelIds]=\"toolModelIds\"\n (segmentRegions)=\"segmentRegions.emit()\"\n (segmentCellpose)=\"segmentCellpose.emit()\"\n (toggleDragMode)=\"toggleDragMode.emit($event)\"\n (samModelChange)=\"samModelChange.emit($event)\"\n (runTool)=\"runTool.emit($event)\"\n (toolModelChange)=\"toolModelChange.emit($event)\"\n (openToolParams)=\"openToolParams.emit($event)\"\n >\n </toolbar-segmentation-tools>\n </ng-container>\n\n <ng-container *ngIf=\"tools.help\">\n <span class=\"toolbar-separator\"></span>\n\n <!-- Help -->\n <p-button\n icon=\"pi pi-question-circle\"\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Help\"\n pTooltip=\"Help\"\n tooltipPosition=\"bottom\"\n (onClick)=\"showHelp()\"\n >\n </p-button>\n </ng-container>\n </div>\n</p-toolbar>\n<toolbar-help-dialog\n [(visible)]=\"displayHelpDialog\"\n [contributedTools]=\"contributedTools\"\n [dialogTools]=\"dialogTools\"\n>\n</toolbar-help-dialog>\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:block}:host ::ng-deep .p-toolbar{padding:.25rem .5rem}::ng-deep .toolbar-input .p-inputtext{color:var(--primary-color);border-color:var(--primary-color)}::ng-deep .p-menu.model-menu{width:auto;min-width:12.5rem}::ng-deep .model-menu-item{display:flex;align-items:center;gap:.5rem}::ng-deep .model-menu-item .p-menuitem-text{flex:1 1 auto;white-space:nowrap}::ng-deep .model-menu-item .model-info-icon{flex:0 0 auto;font-size:.875rem;opacity:.55;cursor:help;appearance:none;background:none;border:0;padding:0;margin:0;color:inherit;line-height:1}::ng-deep .model-menu-item .model-info-icon:hover{opacity:1}::ng-deep .model-menu-item .model-info-icon:focus-visible{opacity:1;outline:2px solid var(--primary-color, #2196f3);outline-offset:2px;border-radius:2px}::ng-deep .model-info-tooltip .p-tooltip-text{min-width:18rem;max-width:24rem;line-height:1.4}::ng-deep .wand-sensitivity-slider{width:8rem;align-self:center;margin:0 .25rem}span.colormap{width:50px;height:auto;display:inline-block}img.colormap{width:50px;height:auto}.colormap{background:no-repeat;background-size:100%;vertical-align:middle}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.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: RippleModule }, { kind: "directive", type: i3.Ripple, selector: "[pRipple]" }, { kind: "ngmodule", type: ToolbarModule }, { kind: "component", type: i4.Toolbar, selector: "p-toolbar", inputs: ["style", "styleClass", "ariaLabelledBy"] }, { 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"] }, { kind: "component", type: ToolbarHelpDialogComponent, selector: "toolbar-help-dialog", inputs: ["visible", "contributedTools", "dialogTools"], outputs: ["visibleChange"] }, { kind: "component", type: PlotTypeSelectorComponent, selector: "toolbar-plot-type-selector", inputs: ["options", "selected", "isosurface", "isoRange", "intensityLines"], outputs: ["selectPlotType", "isoRangeChange", "addProfileLine"] }, { kind: "component", type: StackControlsComponent, selector: "toolbar-stack-controls", inputs: ["liveScrubber", "stackToggle", "showStack", "stackOptions", "zIndex", "maxIndex"], outputs: ["zScrub", "zSlide", "selectStackOption", "zIndexInput", "reloadAndPlot"] }, { kind: "component", type: ViewControlsComponent, selector: "toolbar-view-controls", inputs: ["isHeatmap", "zoomTools", "isImageView", "activeDragMode", "activeSurface3dMode", "isNapariSurfaceMode", "isNapari3dMode", "axesToggle", "axesVisible", "wireframeActive", "resolutionScale"], outputs: ["toggleDragMode", "zoomIn", "zoomOut", "toggleSurface3dMode", "resetSurfaceCamera", "toggleAxes", "toggleWireframe", "selectResolution"] }, { kind: "component", type: RegionToolsComponent, selector: "toolbar-region-tools", inputs: ["activeDragMode", "is3dRegions", "selectOnly", "vertexTools", "wandSensitivity", "brushSize", "vertexEraserRadius", "canUndo", "canRedo"], outputs: ["openRegionEditor", "toggleDragMode", "undoRegion", "redoRegion", "deleteRegion", "wandSensitivityChange", "brushSizeChange", "vertexEraserRadiusChange"] }, { kind: "component", type: SegmentationToolsComponent, selector: "toolbar-segmentation-tools", inputs: ["activeDragMode", "samModels", "samModelId", "contributedTools", "toolModelIds"], outputs: ["segmentRegions", "segmentCellpose", "toggleDragMode", "samModelChange", "runTool", "toolModelChange", "openToolParams"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
281
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: ToolbarComponent, isStandalone: true, selector: "plotting-toolbar", inputs: { imageInfo: "imageInfo", hasSpatialDataset: "hasSpatialDataset", plotTypeOptions: "plotTypeOptions", selectedPlotType: "selectedPlotType", basePlotType: "basePlotType", isoRange: "isoRange", maxIndex: "maxIndex", planeSlices: "planeSlices", zIndex: "zIndex", isHeatmap: "isHeatmap", is3dRegions: "is3dRegions", isVolumeView: "isVolumeView", sliceEditor: "sliceEditor", activeDragMode: "activeDragMode", activeSurface3dMode: "activeSurface3dMode", axesVisible: "axesVisible", wireframeActive: "wireframeActive", resolutionScale: "resolutionScale", wandSensitivity: "wandSensitivity", brushSize: "brushSize", vertexEraserRadius: "vertexEraserRadius", canUndo: "canUndo", canRedo: "canRedo", stackOptions: "stackOptions", tools: "tools", imageSmoothingEnabled: "imageSmoothingEnabled", samModels: "samModels", samModelId: "samModelId", contributedTools: "contributedTools", dialogTools: "dialogTools", openDialogToolId: "openDialogToolId", toolModelIds: "toolModelIds" }, outputs: { selectPlotType: "selectPlotType", addProfileLine: "addProfileLine", toggleImageSmoothing: "toggleImageSmoothing", isoRangeChange: "isoRangeChange", openChannelHistogram: "openChannelHistogram", openSpatialControls: "openSpatialControls", openRegionEditor: "openRegionEditor", toggleSliceEditor: "toggleSliceEditor", selectStackOption: "selectStackOption", zScrub: "zScrub", zSlide: "zSlide", zIndexInput: "zIndexInput", reloadAndPlot: "reloadAndPlot", downloadImage: "downloadImage", autoscaleImage: "autoscaleImage", toggleDragMode: "toggleDragMode", zoomIn: "zoomIn", zoomOut: "zoomOut", toggleSurface3dMode: "toggleSurface3dMode", resetSurfaceCamera: "resetSurfaceCamera", toggleAxes: "toggleAxes", toggleWireframe: "toggleWireframe", selectResolution: "selectResolution", deleteRegion: "deleteRegion", undoRegion: "undoRegion", redoRegion: "redoRegion", segmentRegions: "segmentRegions", segmentCellpose: "segmentCellpose", runTool: "runTool", toggleDialogTool: "toggleDialogTool", toolModelChange: "toolModelChange", openToolParams: "openToolParams", samModelChange: "samModelChange", wandSensitivityChange: "wandSensitivityChange", brushSizeChange: "brushSizeChange", vertexEraserRadiusChange: "vertexEraserRadiusChange" }, ngImport: i0, template: "<p-toolbar>\n <div class=\"p-toolbar-group-start flex-wrap align-items-center gap-1\">\n <!-- Host-provided custom toolbar buttons, shown first (e.g. app-specific\n actions the visualization view itself doesn't own). -->\n <ng-content></ng-content>\n\n <!-- Contributed dialog tools (TOOLBAR_TOOLS, kind: 'dialog'): app-level actions\n like the host's own buttons above, so they sit right beside them. Image view\n only, the view their dialog draws over. Highlighted while the dialog is open. -->\n <ng-container *ngIf=\"isImageView\">\n <p-button\n *ngFor=\"let tool of dialogTools; trackBy: trackToolById\"\n size=\"small\"\n [text]=\"openDialogToolId !== tool.id\"\n [pTooltip]=\"tool.tooltip\"\n tooltipPosition=\"bottom\"\n [ariaLabel]=\"tool.label\"\n [attr.aria-pressed]=\"openDialogToolId === tool.id\"\n (onClick)=\"toggleDialogTool.emit(tool.id)\"\n >\n <img\n *ngIf=\"tool.icon.src\"\n [src]=\"tool.icon.src\"\n style=\"width: 1rem\"\n [alt]=\"tool.label\"\n [class]=\"openDialogToolId === tool.id ? 'toolbar-icon-active' : 'toolbar-icon-dark'\"\n />\n <i *ngIf=\"tool.icon.pi\" class=\"pi {{ tool.icon.pi }}\"></i>\n </p-button>\n </ng-container>\n\n <!-- Plot type: available for any image (grayscale or RGB), and for a spatial dataset\n that brings none (its spatial modes are still a choice). -->\n <toolbar-plot-type-selector\n *ngIf=\"showPlotTypes\"\n [options]=\"plotTypeOptions\"\n [selected]=\"selectedPlotType\"\n [isosurface]=\"isIsosurfaceMode\"\n [isoRange]=\"isoRange\"\n [intensityLines]=\"isIntensityCapable\"\n (selectPlotType)=\"selectPlotType.emit($event)\"\n (isoRangeChange)=\"isoRangeChange.emit($event)\"\n (addProfileLine)=\"addProfileLine.emit()\"\n >\n </toolbar-plot-type-selector>\n <!-- Channels & Histogram: brightness/contrast, gamma, per-channel display,\n colormap/reverse/invert \u2014 opens the floating dialog. -->\n <p-button\n *ngIf=\"tools.specialTools\"\n pRipple\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Channels &amp; Histogram\"\n pTooltip=\"Channels &amp; Histogram (brightness/contrast, colormap)\"\n tooltipPosition=\"bottom\"\n (onClick)=\"openChannelHistogram.emit()\"\n >\n <img src=\"assets/plotting/invert.svg\" class=\"toolbar-icon-dark\" style=\"width: 1rem\" />\n </p-button>\n\n <!-- Spatial-omics controls. Only meaningful in the spatial mode, which is\n itself only offered while a dataset is loaded \u2014 so this button appears\n exactly when there is something for it to control. -->\n <p-button\n *ngIf=\"tools.specialTools && isSpatialMode\"\n pRipple\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Spatial omics controls\"\n pTooltip=\"Spatial omics (colour by column or gene, legend, selection, distributions)\"\n tooltipPosition=\"bottom\"\n (onClick)=\"openSpatialControls.emit()\"\n >\n <img src=\"assets/plotting/spatial-omics.svg\" class=\"toolbar-icon-dark\" style=\"width: 1rem\" />\n </p-button>\n\n <!-- Smoothen toggle: bilinear smoothing vs nearest-neighbour raw pixels (Image\n view only \u2014 it's an OpenSeadragon drawer setting). Highlighted when smoothing on. -->\n <p-button\n *ngIf=\"tools.specialTools && isImageView\"\n size=\"small\"\n [text]=\"!imageSmoothingEnabled\"\n ariaLabel=\"Smoothen\"\n pTooltip=\"Smoothen (turn on image smoothing)\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleImageSmoothing.emit()\"\n >\n <img\n src=\"assets/plotting/smooth.svg\"\n style=\"width: 1rem\"\n [class]=\"imageSmoothingEnabled ? 'toolbar-icon-active' : 'toolbar-icon-dark'\"\n />\n </p-button>\n\n <!-- Stack controls -->\n <toolbar-stack-controls\n *ngIf=\"imageInfo?.isStack || (planeSlices && showsLiveSliceScrubber)\"\n [liveScrubber]=\"showsLiveSliceScrubber\"\n [stackToggle]=\"!showsLiveSliceScrubber && !isNapariMode && !isSpatialMode\"\n [showStack]=\"!!imageInfo?.showStack\"\n [stackOptions]=\"stackOptions\"\n [zIndex]=\"zIndex\"\n [maxIndex]=\"maxIndex\"\n (zScrub)=\"zScrub.emit($event)\"\n (zSlide)=\"zSlide.emit($event)\"\n (selectStackOption)=\"selectStackOption.emit($event)\"\n (zIndexInput)=\"zIndexInput.emit($event)\"\n (reloadAndPlot)=\"reloadAndPlot.emit()\"\n >\n </toolbar-stack-controls>\n\n <!-- Image actions (special tools) -->\n <ng-container *ngIf=\"tools.specialTools\">\n <span class=\"toolbar-separator\"></span>\n <p-button\n icon=\"pi pi-download\"\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Download image as PNG\"\n pTooltip=\"Download image as PNG\"\n tooltipPosition=\"bottom\"\n (onClick)=\"downloadImage.emit()\"\n >\n </p-button>\n <p-button\n *ngIf=\"isHeatmap\"\n icon=\"pi pi-window-maximize\"\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Fit to view\"\n pTooltip=\"Fit to view\"\n tooltipPosition=\"bottom\"\n (onClick)=\"autoscaleImage.emit()\"\n >\n </p-button>\n </ng-container>\n\n <toolbar-view-controls\n [isHeatmap]=\"isHeatmap\"\n [zoomTools]=\"tools.zoomTools\"\n [isImageView]=\"isImageView\"\n [activeDragMode]=\"activeDragMode\"\n [activeSurface3dMode]=\"activeSurface3dMode\"\n [axesToggle]=\"showsAxesToggle\"\n [isNapariSurfaceMode]=\"isNapariSurfaceMode\"\n [isNapari3dMode]=\"isNapari3dMode\"\n [axesVisible]=\"axesVisible\"\n [wireframeActive]=\"wireframeActive\"\n [resolutionScale]=\"resolutionScale\"\n (toggleDragMode)=\"toggleDragMode.emit($event)\"\n (zoomIn)=\"zoomIn.emit()\"\n (zoomOut)=\"zoomOut.emit()\"\n (toggleSurface3dMode)=\"toggleSurface3dMode.emit($event)\"\n (resetSurfaceCamera)=\"resetSurfaceCamera.emit()\"\n (toggleAxes)=\"toggleAxes.emit()\"\n (toggleWireframe)=\"toggleWireframe.emit()\"\n (selectResolution)=\"selectResolution.emit($event)\"\n >\n </toolbar-view-controls>\n\n <!-- A volume view draws no regions; the Region Editor shows them in it in 3D, and the\n selection tool picks their surfaces there. The slice editor splits the view: the slice,\n with every region tool, beside the 3D view. -->\n <ng-container *ngIf=\"isVolumeView && !isHeatmap && !is3dRegions && tools.regionTools\">\n <span class=\"toolbar-separator\"></span>\n <p-button\n size=\"small\"\n [text]=\"!sliceEditor\"\n ariaLabel=\"Slice editor\"\n [attr.aria-pressed]=\"sliceEditor\"\n [pTooltip]=\"\n sliceEditor\n ? 'Close the slice editor'\n : 'Slice editor: the slice and the sections through x and y beside the 3D view'\n \"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleSliceEditor.emit()\"\n >\n <img\n src=\"assets/plotting/slice.svg\"\n style=\"width: 1rem\"\n alt=\"\"\n [class]=\"sliceEditor ? 'toolbar-icon-active' : 'toolbar-icon-dark'\"\n />\n </p-button>\n <toolbar-region-tools\n *ngIf=\"!sliceEditor\"\n [activeDragMode]=\"activeDragMode\"\n [selectOnly]=\"true\"\n [canUndo]=\"canUndo\"\n [canRedo]=\"canRedo\"\n (openRegionEditor)=\"openRegionEditor.emit()\"\n (toggleDragMode)=\"toggleDragMode.emit($event)\"\n (undoRegion)=\"undoRegion.emit()\"\n (redoRegion)=\"redoRegion.emit()\"\n (deleteRegion)=\"deleteRegion.emit()\"\n >\n </toolbar-region-tools>\n </ng-container>\n <ng-container *ngIf=\"(isHeatmap || is3dRegions || (isVolumeView && sliceEditor)) && tools.regionTools\">\n <toolbar-region-tools\n [activeDragMode]=\"activeDragMode\"\n [is3dRegions]=\"is3dRegions\"\n [vertexTools]=\"supportsRegionVertexTools || (isVolumeView && sliceEditor)\"\n [wandSensitivity]=\"wandSensitivity\"\n [brushSize]=\"brushSize\"\n [vertexEraserRadius]=\"vertexEraserRadius\"\n [canUndo]=\"canUndo\"\n [canRedo]=\"canRedo\"\n (openRegionEditor)=\"openRegionEditor.emit()\"\n (toggleDragMode)=\"toggleDragMode.emit($event)\"\n (undoRegion)=\"undoRegion.emit()\"\n (redoRegion)=\"redoRegion.emit()\"\n (deleteRegion)=\"deleteRegion.emit()\"\n (wandSensitivityChange)=\"wandSensitivityChange.emit($event)\"\n (brushSizeChange)=\"brushSizeChange.emit($event)\"\n (vertexEraserRadiusChange)=\"vertexEraserRadiusChange.emit($event)\"\n >\n </toolbar-region-tools>\n <toolbar-segmentation-tools\n [activeDragMode]=\"activeDragMode\"\n [samModels]=\"samModels\"\n [samModelId]=\"samModelId\"\n [contributedTools]=\"contributedTools\"\n [toolModelIds]=\"toolModelIds\"\n (segmentRegions)=\"segmentRegions.emit()\"\n (segmentCellpose)=\"segmentCellpose.emit()\"\n (toggleDragMode)=\"toggleDragMode.emit($event)\"\n (samModelChange)=\"samModelChange.emit($event)\"\n (runTool)=\"runTool.emit($event)\"\n (toolModelChange)=\"toolModelChange.emit($event)\"\n (openToolParams)=\"openToolParams.emit($event)\"\n >\n </toolbar-segmentation-tools>\n </ng-container>\n\n <ng-container *ngIf=\"tools.help\">\n <span class=\"toolbar-separator\"></span>\n\n <!-- Help -->\n <p-button\n icon=\"pi pi-question-circle\"\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Help\"\n pTooltip=\"Help\"\n tooltipPosition=\"bottom\"\n (onClick)=\"showHelp()\"\n >\n </p-button>\n </ng-container>\n </div>\n</p-toolbar>\n<toolbar-help-dialog\n [(visible)]=\"displayHelpDialog\"\n [contributedTools]=\"contributedTools\"\n [dialogTools]=\"dialogTools\"\n>\n</toolbar-help-dialog>\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:block}:host ::ng-deep .p-toolbar{padding:.25rem .5rem}::ng-deep .toolbar-input .p-inputtext{color:var(--primary-color);border-color:var(--primary-color)}::ng-deep .p-menu.model-menu{width:auto;min-width:12.5rem}::ng-deep .model-menu-item{display:flex;align-items:center;gap:.5rem}::ng-deep .model-menu-item .p-menuitem-text{flex:1 1 auto;white-space:nowrap}::ng-deep .model-menu-item .model-info-icon{flex:0 0 auto;font-size:.875rem;opacity:.55;cursor:help;appearance:none;background:none;border:0;padding:0;margin:0;color:inherit;line-height:1}::ng-deep .model-menu-item .model-info-icon:hover{opacity:1}::ng-deep .model-menu-item .model-info-icon:focus-visible{opacity:1;outline:2px solid var(--primary-color, #2196f3);outline-offset:2px;border-radius:2px}::ng-deep .model-info-tooltip .p-tooltip-text{min-width:18rem;max-width:24rem;line-height:1.4}::ng-deep .wand-sensitivity-slider{width:8rem;align-self:center;margin:0 .25rem}span.colormap{width:50px;height:auto;display:inline-block}img.colormap{width:50px;height:auto}.colormap{background:no-repeat;background-size:100%;vertical-align:middle}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.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: RippleModule }, { kind: "directive", type: i3.Ripple, selector: "[pRipple]" }, { kind: "ngmodule", type: ToolbarModule }, { kind: "component", type: i4.Toolbar, selector: "p-toolbar", inputs: ["style", "styleClass", "ariaLabelledBy"] }, { 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"] }, { kind: "component", type: ToolbarHelpDialogComponent, selector: "toolbar-help-dialog", inputs: ["visible", "contributedTools", "dialogTools"], outputs: ["visibleChange"] }, { kind: "component", type: PlotTypeSelectorComponent, selector: "toolbar-plot-type-selector", inputs: ["options", "selected", "isosurface", "isoRange", "intensityLines"], outputs: ["selectPlotType", "isoRangeChange", "addProfileLine"] }, { kind: "component", type: StackControlsComponent, selector: "toolbar-stack-controls", inputs: ["liveScrubber", "stackToggle", "showStack", "stackOptions", "zIndex", "maxIndex"], outputs: ["zScrub", "zSlide", "selectStackOption", "zIndexInput", "reloadAndPlot"] }, { kind: "component", type: ViewControlsComponent, selector: "toolbar-view-controls", inputs: ["isHeatmap", "zoomTools", "isImageView", "activeDragMode", "activeSurface3dMode", "isNapariSurfaceMode", "isNapari3dMode", "axesToggle", "axesVisible", "wireframeActive", "resolutionScale"], outputs: ["toggleDragMode", "zoomIn", "zoomOut", "toggleSurface3dMode", "resetSurfaceCamera", "toggleAxes", "toggleWireframe", "selectResolution"] }, { kind: "component", type: RegionToolsComponent, selector: "toolbar-region-tools", inputs: ["activeDragMode", "is3dRegions", "selectOnly", "vertexTools", "wandSensitivity", "brushSize", "vertexEraserRadius", "canUndo", "canRedo"], outputs: ["openRegionEditor", "toggleDragMode", "undoRegion", "redoRegion", "deleteRegion", "wandSensitivityChange", "brushSizeChange", "vertexEraserRadiusChange"] }, { kind: "component", type: SegmentationToolsComponent, selector: "toolbar-segmentation-tools", inputs: ["activeDragMode", "samModels", "samModelId", "contributedTools", "toolModelIds"], outputs: ["segmentRegions", "segmentCellpose", "toggleDragMode", "samModelChange", "runTool", "toolModelChange", "openToolParams"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
277
282
  }
278
283
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: ToolbarComponent, decorators: [{
279
284
  type: Component,
@@ -289,7 +294,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
289
294
  ViewControlsComponent,
290
295
  RegionToolsComponent,
291
296
  SegmentationToolsComponent,
292
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<p-toolbar>\n <div class=\"p-toolbar-group-start flex-wrap align-items-center gap-1\">\n <!-- Host-provided custom toolbar buttons, shown first (e.g. app-specific\n actions the visualization view itself doesn't own). -->\n <ng-content></ng-content>\n\n <!-- Contributed dialog tools (TOOLBAR_TOOLS, kind: 'dialog'): app-level actions\n like the host's own buttons above, so they sit right beside them. Image view\n only, the view their dialog draws over. Highlighted while the dialog is open. -->\n <ng-container *ngIf=\"isImageView\">\n <p-button\n *ngFor=\"let tool of dialogTools; trackBy: trackToolById\"\n size=\"small\"\n [text]=\"openDialogToolId !== tool.id\"\n [pTooltip]=\"tool.tooltip\"\n tooltipPosition=\"bottom\"\n [ariaLabel]=\"tool.label\"\n [attr.aria-pressed]=\"openDialogToolId === tool.id\"\n (onClick)=\"toggleDialogTool.emit(tool.id)\"\n >\n <img\n *ngIf=\"tool.icon.src\"\n [src]=\"tool.icon.src\"\n style=\"width: 1rem\"\n [alt]=\"tool.label\"\n [class]=\"openDialogToolId === tool.id ? 'toolbar-icon-active' : 'toolbar-icon-dark'\"\n />\n <i *ngIf=\"tool.icon.pi\" class=\"pi {{ tool.icon.pi }}\"></i>\n </p-button>\n </ng-container>\n\n <!-- Plot type: available for any image (grayscale or RGB), and for a spatial dataset\n that brings none (its spatial modes are still a choice). -->\n <toolbar-plot-type-selector\n *ngIf=\"showPlotTypes\"\n [options]=\"plotTypeOptions\"\n [selected]=\"selectedPlotType\"\n [isosurface]=\"isIsosurfaceMode\"\n [isoRange]=\"isoRange\"\n [intensityLines]=\"isIntensityCapable\"\n (selectPlotType)=\"selectPlotType.emit($event)\"\n (isoRangeChange)=\"isoRangeChange.emit($event)\"\n (addProfileLine)=\"addProfileLine.emit()\"\n >\n </toolbar-plot-type-selector>\n <!-- Channels & Histogram: brightness/contrast, gamma, per-channel display,\n colormap/reverse/invert \u2014 opens the floating dialog. -->\n <p-button\n *ngIf=\"tools.specialTools\"\n pRipple\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Channels &amp; Histogram\"\n pTooltip=\"Channels &amp; Histogram (brightness/contrast, colormap)\"\n tooltipPosition=\"bottom\"\n (onClick)=\"openChannelHistogram.emit()\"\n >\n <img src=\"assets/plotting/invert.svg\" class=\"toolbar-icon-dark\" style=\"width: 1rem\" />\n </p-button>\n\n <!-- Spatial-omics controls. Only meaningful in the spatial mode, which is\n itself only offered while a dataset is loaded \u2014 so this button appears\n exactly when there is something for it to control. -->\n <p-button\n *ngIf=\"tools.specialTools && isSpatialMode\"\n pRipple\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Spatial omics controls\"\n pTooltip=\"Spatial omics (colour by column or gene, legend, selection, distributions)\"\n tooltipPosition=\"bottom\"\n (onClick)=\"openSpatialControls.emit()\"\n >\n <img src=\"assets/plotting/spatial-omics.svg\" class=\"toolbar-icon-dark\" style=\"width: 1rem\" />\n </p-button>\n\n <!-- Smoothen toggle: bilinear smoothing vs nearest-neighbour raw pixels (Image\n view only \u2014 it's an OpenSeadragon drawer setting). Highlighted when smoothing on. -->\n <p-button\n *ngIf=\"tools.specialTools && isImageView\"\n size=\"small\"\n [text]=\"!imageSmoothingEnabled\"\n ariaLabel=\"Smoothen\"\n pTooltip=\"Smoothen (turn on image smoothing)\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleImageSmoothing.emit()\"\n >\n <img\n src=\"assets/plotting/smooth.svg\"\n style=\"width: 1rem\"\n [class]=\"imageSmoothingEnabled ? 'toolbar-icon-active' : 'toolbar-icon-dark'\"\n />\n </p-button>\n\n <!-- Stack controls -->\n <toolbar-stack-controls\n *ngIf=\"imageInfo?.isStack\"\n [liveScrubber]=\"showsLiveSliceScrubber\"\n [stackToggle]=\"!showsLiveSliceScrubber && !isNapariMode && !isSpatialMode\"\n [showStack]=\"!!imageInfo?.showStack\"\n [stackOptions]=\"stackOptions\"\n [zIndex]=\"zIndex\"\n [maxIndex]=\"maxIndex\"\n (zScrub)=\"zScrub.emit($event)\"\n (zSlide)=\"zSlide.emit($event)\"\n (selectStackOption)=\"selectStackOption.emit($event)\"\n (zIndexInput)=\"zIndexInput.emit($event)\"\n (reloadAndPlot)=\"reloadAndPlot.emit()\"\n >\n </toolbar-stack-controls>\n\n <!-- Image actions (special tools) -->\n <ng-container *ngIf=\"tools.specialTools\">\n <span class=\"toolbar-separator\"></span>\n <p-button\n icon=\"pi pi-download\"\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Download image as PNG\"\n pTooltip=\"Download image as PNG\"\n tooltipPosition=\"bottom\"\n (onClick)=\"downloadImage.emit()\"\n >\n </p-button>\n <p-button\n *ngIf=\"isHeatmap\"\n icon=\"pi pi-window-maximize\"\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Fit to view\"\n pTooltip=\"Fit to view\"\n tooltipPosition=\"bottom\"\n (onClick)=\"autoscaleImage.emit()\"\n >\n </p-button>\n </ng-container>\n\n <toolbar-view-controls\n [isHeatmap]=\"isHeatmap\"\n [zoomTools]=\"tools.zoomTools\"\n [isImageView]=\"isImageView\"\n [activeDragMode]=\"activeDragMode\"\n [activeSurface3dMode]=\"activeSurface3dMode\"\n [axesToggle]=\"showsAxesToggle\"\n [isNapariSurfaceMode]=\"isNapariSurfaceMode\"\n [isNapari3dMode]=\"isNapari3dMode\"\n [axesVisible]=\"axesVisible\"\n [wireframeActive]=\"wireframeActive\"\n [resolutionScale]=\"resolutionScale\"\n (toggleDragMode)=\"toggleDragMode.emit($event)\"\n (zoomIn)=\"zoomIn.emit()\"\n (zoomOut)=\"zoomOut.emit()\"\n (toggleSurface3dMode)=\"toggleSurface3dMode.emit($event)\"\n (resetSurfaceCamera)=\"resetSurfaceCamera.emit()\"\n (toggleAxes)=\"toggleAxes.emit()\"\n (toggleWireframe)=\"toggleWireframe.emit()\"\n (selectResolution)=\"selectResolution.emit($event)\"\n >\n </toolbar-view-controls>\n\n <!-- A volume view draws no regions; the Region Editor shows them in it in 3D, and the\n selection tool picks their surfaces there. The slice editor splits the view: the slice,\n with every region tool, beside the 3D view. -->\n <ng-container *ngIf=\"isVolumeView && !isHeatmap && !is3dRegions && tools.regionTools\">\n <span class=\"toolbar-separator\"></span>\n <p-button\n size=\"small\"\n [text]=\"!sliceEditor\"\n ariaLabel=\"Slice editor\"\n [attr.aria-pressed]=\"sliceEditor\"\n [pTooltip]=\"\n sliceEditor\n ? 'Close the slice editor'\n : 'Slice editor: the slice and the sections through x and y beside the 3D view'\n \"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleSliceEditor.emit()\"\n >\n <img\n src=\"assets/plotting/slice.svg\"\n style=\"width: 1rem\"\n alt=\"\"\n [class]=\"sliceEditor ? 'toolbar-icon-active' : 'toolbar-icon-dark'\"\n />\n </p-button>\n <toolbar-region-tools\n *ngIf=\"!sliceEditor\"\n [activeDragMode]=\"activeDragMode\"\n [selectOnly]=\"true\"\n [canUndo]=\"canUndo\"\n [canRedo]=\"canRedo\"\n (openRegionEditor)=\"openRegionEditor.emit()\"\n (toggleDragMode)=\"toggleDragMode.emit($event)\"\n (undoRegion)=\"undoRegion.emit()\"\n (redoRegion)=\"redoRegion.emit()\"\n (deleteRegion)=\"deleteRegion.emit()\"\n >\n </toolbar-region-tools>\n </ng-container>\n <ng-container *ngIf=\"(isHeatmap || is3dRegions || (isVolumeView && sliceEditor)) && tools.regionTools\">\n <toolbar-region-tools\n [activeDragMode]=\"activeDragMode\"\n [is3dRegions]=\"is3dRegions\"\n [vertexTools]=\"supportsRegionVertexTools || (isVolumeView && sliceEditor)\"\n [wandSensitivity]=\"wandSensitivity\"\n [brushSize]=\"brushSize\"\n [vertexEraserRadius]=\"vertexEraserRadius\"\n [canUndo]=\"canUndo\"\n [canRedo]=\"canRedo\"\n (openRegionEditor)=\"openRegionEditor.emit()\"\n (toggleDragMode)=\"toggleDragMode.emit($event)\"\n (undoRegion)=\"undoRegion.emit()\"\n (redoRegion)=\"redoRegion.emit()\"\n (deleteRegion)=\"deleteRegion.emit()\"\n (wandSensitivityChange)=\"wandSensitivityChange.emit($event)\"\n (brushSizeChange)=\"brushSizeChange.emit($event)\"\n (vertexEraserRadiusChange)=\"vertexEraserRadiusChange.emit($event)\"\n >\n </toolbar-region-tools>\n <toolbar-segmentation-tools\n [activeDragMode]=\"activeDragMode\"\n [samModels]=\"samModels\"\n [samModelId]=\"samModelId\"\n [contributedTools]=\"contributedTools\"\n [toolModelIds]=\"toolModelIds\"\n (segmentRegions)=\"segmentRegions.emit()\"\n (segmentCellpose)=\"segmentCellpose.emit()\"\n (toggleDragMode)=\"toggleDragMode.emit($event)\"\n (samModelChange)=\"samModelChange.emit($event)\"\n (runTool)=\"runTool.emit($event)\"\n (toolModelChange)=\"toolModelChange.emit($event)\"\n (openToolParams)=\"openToolParams.emit($event)\"\n >\n </toolbar-segmentation-tools>\n </ng-container>\n\n <ng-container *ngIf=\"tools.help\">\n <span class=\"toolbar-separator\"></span>\n\n <!-- Help -->\n <p-button\n icon=\"pi pi-question-circle\"\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Help\"\n pTooltip=\"Help\"\n tooltipPosition=\"bottom\"\n (onClick)=\"showHelp()\"\n >\n </p-button>\n </ng-container>\n </div>\n</p-toolbar>\n<toolbar-help-dialog\n [(visible)]=\"displayHelpDialog\"\n [contributedTools]=\"contributedTools\"\n [dialogTools]=\"dialogTools\"\n>\n</toolbar-help-dialog>\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:block}:host ::ng-deep .p-toolbar{padding:.25rem .5rem}::ng-deep .toolbar-input .p-inputtext{color:var(--primary-color);border-color:var(--primary-color)}::ng-deep .p-menu.model-menu{width:auto;min-width:12.5rem}::ng-deep .model-menu-item{display:flex;align-items:center;gap:.5rem}::ng-deep .model-menu-item .p-menuitem-text{flex:1 1 auto;white-space:nowrap}::ng-deep .model-menu-item .model-info-icon{flex:0 0 auto;font-size:.875rem;opacity:.55;cursor:help;appearance:none;background:none;border:0;padding:0;margin:0;color:inherit;line-height:1}::ng-deep .model-menu-item .model-info-icon:hover{opacity:1}::ng-deep .model-menu-item .model-info-icon:focus-visible{opacity:1;outline:2px solid var(--primary-color, #2196f3);outline-offset:2px;border-radius:2px}::ng-deep .model-info-tooltip .p-tooltip-text{min-width:18rem;max-width:24rem;line-height:1.4}::ng-deep .wand-sensitivity-slider{width:8rem;align-self:center;margin:0 .25rem}span.colormap{width:50px;height:auto;display:inline-block}img.colormap{width:50px;height:auto}.colormap{background:no-repeat;background-size:100%;vertical-align:middle}\n"] }]
297
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<p-toolbar>\n <div class=\"p-toolbar-group-start flex-wrap align-items-center gap-1\">\n <!-- Host-provided custom toolbar buttons, shown first (e.g. app-specific\n actions the visualization view itself doesn't own). -->\n <ng-content></ng-content>\n\n <!-- Contributed dialog tools (TOOLBAR_TOOLS, kind: 'dialog'): app-level actions\n like the host's own buttons above, so they sit right beside them. Image view\n only, the view their dialog draws over. Highlighted while the dialog is open. -->\n <ng-container *ngIf=\"isImageView\">\n <p-button\n *ngFor=\"let tool of dialogTools; trackBy: trackToolById\"\n size=\"small\"\n [text]=\"openDialogToolId !== tool.id\"\n [pTooltip]=\"tool.tooltip\"\n tooltipPosition=\"bottom\"\n [ariaLabel]=\"tool.label\"\n [attr.aria-pressed]=\"openDialogToolId === tool.id\"\n (onClick)=\"toggleDialogTool.emit(tool.id)\"\n >\n <img\n *ngIf=\"tool.icon.src\"\n [src]=\"tool.icon.src\"\n style=\"width: 1rem\"\n [alt]=\"tool.label\"\n [class]=\"openDialogToolId === tool.id ? 'toolbar-icon-active' : 'toolbar-icon-dark'\"\n />\n <i *ngIf=\"tool.icon.pi\" class=\"pi {{ tool.icon.pi }}\"></i>\n </p-button>\n </ng-container>\n\n <!-- Plot type: available for any image (grayscale or RGB), and for a spatial dataset\n that brings none (its spatial modes are still a choice). -->\n <toolbar-plot-type-selector\n *ngIf=\"showPlotTypes\"\n [options]=\"plotTypeOptions\"\n [selected]=\"selectedPlotType\"\n [isosurface]=\"isIsosurfaceMode\"\n [isoRange]=\"isoRange\"\n [intensityLines]=\"isIntensityCapable\"\n (selectPlotType)=\"selectPlotType.emit($event)\"\n (isoRangeChange)=\"isoRangeChange.emit($event)\"\n (addProfileLine)=\"addProfileLine.emit()\"\n >\n </toolbar-plot-type-selector>\n <!-- Channels & Histogram: brightness/contrast, gamma, per-channel display,\n colormap/reverse/invert \u2014 opens the floating dialog. -->\n <p-button\n *ngIf=\"tools.specialTools\"\n pRipple\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Channels &amp; Histogram\"\n pTooltip=\"Channels &amp; Histogram (brightness/contrast, colormap)\"\n tooltipPosition=\"bottom\"\n (onClick)=\"openChannelHistogram.emit()\"\n >\n <img src=\"assets/plotting/invert.svg\" class=\"toolbar-icon-dark\" style=\"width: 1rem\" />\n </p-button>\n\n <!-- Spatial-omics controls. Only meaningful in the spatial mode, which is\n itself only offered while a dataset is loaded \u2014 so this button appears\n exactly when there is something for it to control. -->\n <p-button\n *ngIf=\"tools.specialTools && isSpatialMode\"\n pRipple\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Spatial omics controls\"\n pTooltip=\"Spatial omics (colour by column or gene, legend, selection, distributions)\"\n tooltipPosition=\"bottom\"\n (onClick)=\"openSpatialControls.emit()\"\n >\n <img src=\"assets/plotting/spatial-omics.svg\" class=\"toolbar-icon-dark\" style=\"width: 1rem\" />\n </p-button>\n\n <!-- Smoothen toggle: bilinear smoothing vs nearest-neighbour raw pixels (Image\n view only \u2014 it's an OpenSeadragon drawer setting). Highlighted when smoothing on. -->\n <p-button\n *ngIf=\"tools.specialTools && isImageView\"\n size=\"small\"\n [text]=\"!imageSmoothingEnabled\"\n ariaLabel=\"Smoothen\"\n pTooltip=\"Smoothen (turn on image smoothing)\"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleImageSmoothing.emit()\"\n >\n <img\n src=\"assets/plotting/smooth.svg\"\n style=\"width: 1rem\"\n [class]=\"imageSmoothingEnabled ? 'toolbar-icon-active' : 'toolbar-icon-dark'\"\n />\n </p-button>\n\n <!-- Stack controls -->\n <toolbar-stack-controls\n *ngIf=\"imageInfo?.isStack || (planeSlices && showsLiveSliceScrubber)\"\n [liveScrubber]=\"showsLiveSliceScrubber\"\n [stackToggle]=\"!showsLiveSliceScrubber && !isNapariMode && !isSpatialMode\"\n [showStack]=\"!!imageInfo?.showStack\"\n [stackOptions]=\"stackOptions\"\n [zIndex]=\"zIndex\"\n [maxIndex]=\"maxIndex\"\n (zScrub)=\"zScrub.emit($event)\"\n (zSlide)=\"zSlide.emit($event)\"\n (selectStackOption)=\"selectStackOption.emit($event)\"\n (zIndexInput)=\"zIndexInput.emit($event)\"\n (reloadAndPlot)=\"reloadAndPlot.emit()\"\n >\n </toolbar-stack-controls>\n\n <!-- Image actions (special tools) -->\n <ng-container *ngIf=\"tools.specialTools\">\n <span class=\"toolbar-separator\"></span>\n <p-button\n icon=\"pi pi-download\"\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Download image as PNG\"\n pTooltip=\"Download image as PNG\"\n tooltipPosition=\"bottom\"\n (onClick)=\"downloadImage.emit()\"\n >\n </p-button>\n <p-button\n *ngIf=\"isHeatmap\"\n icon=\"pi pi-window-maximize\"\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Fit to view\"\n pTooltip=\"Fit to view\"\n tooltipPosition=\"bottom\"\n (onClick)=\"autoscaleImage.emit()\"\n >\n </p-button>\n </ng-container>\n\n <toolbar-view-controls\n [isHeatmap]=\"isHeatmap\"\n [zoomTools]=\"tools.zoomTools\"\n [isImageView]=\"isImageView\"\n [activeDragMode]=\"activeDragMode\"\n [activeSurface3dMode]=\"activeSurface3dMode\"\n [axesToggle]=\"showsAxesToggle\"\n [isNapariSurfaceMode]=\"isNapariSurfaceMode\"\n [isNapari3dMode]=\"isNapari3dMode\"\n [axesVisible]=\"axesVisible\"\n [wireframeActive]=\"wireframeActive\"\n [resolutionScale]=\"resolutionScale\"\n (toggleDragMode)=\"toggleDragMode.emit($event)\"\n (zoomIn)=\"zoomIn.emit()\"\n (zoomOut)=\"zoomOut.emit()\"\n (toggleSurface3dMode)=\"toggleSurface3dMode.emit($event)\"\n (resetSurfaceCamera)=\"resetSurfaceCamera.emit()\"\n (toggleAxes)=\"toggleAxes.emit()\"\n (toggleWireframe)=\"toggleWireframe.emit()\"\n (selectResolution)=\"selectResolution.emit($event)\"\n >\n </toolbar-view-controls>\n\n <!-- A volume view draws no regions; the Region Editor shows them in it in 3D, and the\n selection tool picks their surfaces there. The slice editor splits the view: the slice,\n with every region tool, beside the 3D view. -->\n <ng-container *ngIf=\"isVolumeView && !isHeatmap && !is3dRegions && tools.regionTools\">\n <span class=\"toolbar-separator\"></span>\n <p-button\n size=\"small\"\n [text]=\"!sliceEditor\"\n ariaLabel=\"Slice editor\"\n [attr.aria-pressed]=\"sliceEditor\"\n [pTooltip]=\"\n sliceEditor\n ? 'Close the slice editor'\n : 'Slice editor: the slice and the sections through x and y beside the 3D view'\n \"\n tooltipPosition=\"bottom\"\n (onClick)=\"toggleSliceEditor.emit()\"\n >\n <img\n src=\"assets/plotting/slice.svg\"\n style=\"width: 1rem\"\n alt=\"\"\n [class]=\"sliceEditor ? 'toolbar-icon-active' : 'toolbar-icon-dark'\"\n />\n </p-button>\n <toolbar-region-tools\n *ngIf=\"!sliceEditor\"\n [activeDragMode]=\"activeDragMode\"\n [selectOnly]=\"true\"\n [canUndo]=\"canUndo\"\n [canRedo]=\"canRedo\"\n (openRegionEditor)=\"openRegionEditor.emit()\"\n (toggleDragMode)=\"toggleDragMode.emit($event)\"\n (undoRegion)=\"undoRegion.emit()\"\n (redoRegion)=\"redoRegion.emit()\"\n (deleteRegion)=\"deleteRegion.emit()\"\n >\n </toolbar-region-tools>\n </ng-container>\n <ng-container *ngIf=\"(isHeatmap || is3dRegions || (isVolumeView && sliceEditor)) && tools.regionTools\">\n <toolbar-region-tools\n [activeDragMode]=\"activeDragMode\"\n [is3dRegions]=\"is3dRegions\"\n [vertexTools]=\"supportsRegionVertexTools || (isVolumeView && sliceEditor)\"\n [wandSensitivity]=\"wandSensitivity\"\n [brushSize]=\"brushSize\"\n [vertexEraserRadius]=\"vertexEraserRadius\"\n [canUndo]=\"canUndo\"\n [canRedo]=\"canRedo\"\n (openRegionEditor)=\"openRegionEditor.emit()\"\n (toggleDragMode)=\"toggleDragMode.emit($event)\"\n (undoRegion)=\"undoRegion.emit()\"\n (redoRegion)=\"redoRegion.emit()\"\n (deleteRegion)=\"deleteRegion.emit()\"\n (wandSensitivityChange)=\"wandSensitivityChange.emit($event)\"\n (brushSizeChange)=\"brushSizeChange.emit($event)\"\n (vertexEraserRadiusChange)=\"vertexEraserRadiusChange.emit($event)\"\n >\n </toolbar-region-tools>\n <toolbar-segmentation-tools\n [activeDragMode]=\"activeDragMode\"\n [samModels]=\"samModels\"\n [samModelId]=\"samModelId\"\n [contributedTools]=\"contributedTools\"\n [toolModelIds]=\"toolModelIds\"\n (segmentRegions)=\"segmentRegions.emit()\"\n (segmentCellpose)=\"segmentCellpose.emit()\"\n (toggleDragMode)=\"toggleDragMode.emit($event)\"\n (samModelChange)=\"samModelChange.emit($event)\"\n (runTool)=\"runTool.emit($event)\"\n (toolModelChange)=\"toolModelChange.emit($event)\"\n (openToolParams)=\"openToolParams.emit($event)\"\n >\n </toolbar-segmentation-tools>\n </ng-container>\n\n <ng-container *ngIf=\"tools.help\">\n <span class=\"toolbar-separator\"></span>\n\n <!-- Help -->\n <p-button\n icon=\"pi pi-question-circle\"\n size=\"small\"\n [text]=\"true\"\n ariaLabel=\"Help\"\n pTooltip=\"Help\"\n tooltipPosition=\"bottom\"\n (onClick)=\"showHelp()\"\n >\n </p-button>\n </ng-container>\n </div>\n</p-toolbar>\n<toolbar-help-dialog\n [(visible)]=\"displayHelpDialog\"\n [contributedTools]=\"contributedTools\"\n [dialogTools]=\"dialogTools\"\n>\n</toolbar-help-dialog>\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:block}:host ::ng-deep .p-toolbar{padding:.25rem .5rem}::ng-deep .toolbar-input .p-inputtext{color:var(--primary-color);border-color:var(--primary-color)}::ng-deep .p-menu.model-menu{width:auto;min-width:12.5rem}::ng-deep .model-menu-item{display:flex;align-items:center;gap:.5rem}::ng-deep .model-menu-item .p-menuitem-text{flex:1 1 auto;white-space:nowrap}::ng-deep .model-menu-item .model-info-icon{flex:0 0 auto;font-size:.875rem;opacity:.55;cursor:help;appearance:none;background:none;border:0;padding:0;margin:0;color:inherit;line-height:1}::ng-deep .model-menu-item .model-info-icon:hover{opacity:1}::ng-deep .model-menu-item .model-info-icon:focus-visible{opacity:1;outline:2px solid var(--primary-color, #2196f3);outline-offset:2px;border-radius:2px}::ng-deep .model-info-tooltip .p-tooltip-text{min-width:18rem;max-width:24rem;line-height:1.4}::ng-deep .wand-sensitivity-slider{width:8rem;align-self:center;margin:0 .25rem}span.colormap{width:50px;height:auto;display:inline-block}img.colormap{width:50px;height:auto}.colormap{background:no-repeat;background-size:100%;vertical-align:middle}\n"] }]
293
298
  }], propDecorators: { imageInfo: [{
294
299
  type: Input
295
300
  }], hasSpatialDataset: [{
@@ -304,6 +309,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
304
309
  type: Input
305
310
  }], maxIndex: [{
306
311
  type: Input
312
+ }], planeSlices: [{
313
+ type: Input
307
314
  }], zIndex: [{
308
315
  type: Input
309
316
  }], isHeatmap: [{
@@ -425,4 +432,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
425
432
  }], vertexEraserRadiusChange: [{
426
433
  type: Output
427
434
  }] } });
428
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbGJhci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3Rvb2xiYXIvdG9vbGJhci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9zcmMvbGliL3Rvb2xiYXIvdG9vbGJhci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2hHLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFHaEQsT0FBTyxFQUNMLFFBQVEsRUFFUixpQkFBaUIsRUFDakIsVUFBVSxFQUNWLGtCQUFrQixFQUNsQixlQUFlLEVBQ2YsZUFBZSxFQUNmLGNBQWMsRUFDZCx1QkFBdUIsRUFDdkIsY0FBYyxFQUNkLGdCQUFnQixHQUNqQixNQUFNLHdCQUF3QixDQUFDO0FBQ2hDLE9BQU8sRUFBeUIsaUJBQWlCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUd2RixPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxxREFBcUQsQ0FBQztBQUNqRyxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxtREFBbUQsQ0FBQztBQUM5RixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUNuRixPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUNoRixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx1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LGNBQWM7c0JBQXZCLE1BQU07Z0JBRUcsY0FBYztzQkFBdkIsTUFBTTtnQkFFRyxxQkFBcUI7c0JBQTlCLE1BQU07Z0JBRUcsZUFBZTtzQkFBeEIsTUFBTTtnQkFFRyx3QkFBd0I7c0JBQWpDLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBCdXR0b25Nb2R1bGUgfSBmcm9tICdwcmltZW5nL2J1dHRvbic7XG5pbXBvcnQgeyBSaXBwbGVNb2R1bGUgfSBmcm9tICdwcmltZW5nL3JpcHBsZSc7XG5pbXBvcnQgeyBUb29sYmFyTW9kdWxlIH0gZnJvbSAncHJpbWVuZy90b29sYmFyJztcbmltcG9ydCB7IFRvb2x0aXBNb2R1bGUgfSBmcm9tICdwcmltZW5nL3Rvb2x0aXAnO1xuXG5pbXBvcnQgeyBJSW1hZ2VJbmZvIH0gZnJvbSAnLi4vY29udHJhY3RzL2ltYWdlLmNvbnRyYWN0JztcbmltcG9ydCB7XG4gIFBsb3RUeXBlLFxuICBQbG90VHlwZUlkLFxuICBpc0J1aWx0aW5QbG90VHlwZSxcbiAgaXNOYXBhcmkzZCxcbiAgaXNOYXBhcmlJc29zdXJmYWNlLFxuICBpc05hcGFyaVN1cmZhY2UsXG4gIGlzTmFwYXJpU2NhdHRlcixcbiAgaXNOYXBhcmlWb2x1bWUsXG4gIE5BUEFSSV9ERUZBVUxUX0RFQ0lNQVRFLFxuICBpc1NwYXRpYWxPbWljcyxcbiAgaXNTcGF0aWFsT21pY3MzZCxcbn0gZnJvbSAnLi4vY29udHJhY3RzL3Bsb3QtdHlwZSc7XG5pbXBvcnQgeyBUb29sYmFyVG9vbFZpc2liaWxpdHksIEFMTF9UT09MQkFSX1RPT0xTIH0gZnJvbSAnLi4vY29udHJhY3RzL3Rvb2xiYXItY29uZmlnJztcbmltcG9ydCB7IFRvb2xiYXJEaWFsb2dUb29sQ29udHJpYnV0aW9uLCBUb29sYmFyVG9vbENvbnRyaWJ1dGlvbiB9IGZyb20gJy4uL2NvbnRyYWN0cy90b29sYmFyLXRvb2wuY29udHJhY3QnO1xuaW1wb3J0IHsgUGxvdFR5cGVPcHRpb24gfSBmcm9tICcuLi9jb250cmFjdHMvcGxvdC10eXBlLWNvbnRyaWJ1dGlvbi5jb250cmFjdCc7XG5pbXBvcnQgeyBUb29sYmFySGVscERpYWxvZ0NvbXBvbmVudCB9IGZyb20gJy4vdG9vbGJhci1oZWxwLWRpYWxvZy90b29sYmFyLWhlbHAtZGlhbG9nLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBQbG90VHlwZVNlbGVjdG9yQ29tcG9uZW50IH0gZnJvbSAnLi9wbG90LXR5cGUtc2VsZWN0b3IvcGxvdC10eXBlLXNlbGVjdG9yLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTdGFja0NvbnRyb2xzQ29tcG9uZW50IH0gZnJvbSAnLi9zdGFjay1jb250cm9scy9zdGFjay1jb250cm9scy5jb21wb25lbnQnO1xuaW1wb3J0IHsgVmlld0NvbnRyb2xzQ29tcG9uZW50IH0gZnJvbSAnLi92aWV3LWNvbnRyb2xzL3ZpZXctY29udHJvbHMuY29tcG9uZW50JztcbmltcG9ydCB7IFJlZ2lvblRvb2xzQ29tcG9uZW50IH0gZnJvbSAnLi9yZWdpb24tdG9vbHMvcmVnaW9uLXRvb2xzLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTZWdtZW50YXRpb25Ub29sc0NvbXBvbmVudCB9IGZyb20gJy4vc2VnbWVudGF0aW9uLXRvb2xzL3NlZ21lbnRhdGlvbi10b29scy5jb21wb25lbnQnO1xuXG4vKipcbiAqIFByZXNlbnRhdGlvbmFsIHRvb2xiYXIgZm9yIHRoZSBwbG90dGluZyB2aWV3cG9ydC5cbiAqXG4gKiBSZW5kZXJzIHRoZSBwbG90LXR5cGUgc2VsZWN0b3IsIGNvbG9ybWFwL0xVVCBjb250cm9scywgc3RhY2sgbmF2aWdhdGlvbixcbiAqIGltYWdlIGFjdGlvbnMgKGRvd25sb2FkIC8gYXV0b3NjYWxlIC8gcGlwZWxpbmUpLCB2aWV3cG9ydCB6b29tL3BhbiwgdGhlXG4gKiBTdXJmYWNlLTNEIGNhbWVyYSBjb250cm9scywgYW5kIHRoZSByZWdpb24tZHJhd2luZyB0b29scyDigJQgcGx1cyB0aGUgcGxvdHRpbmdcbiAqIGhlbHAgZGlhbG9nLiBJdCBvd25zIG5vIHJlbmRlcmluZyBvciB2aXN1YWxpemF0aW9uIHN0YXRlOiB0aGUgaG9zdFxuICogKFZpc3VhbGl6ZXJDb21wb25lbnQpIHN0YXlzIHRoZSBvcmNoZXN0cmF0b3IsIHBhc3Npbmcgc3RhdGUgaW4gdmlhIGBASW5wdXRgIGFuZFxuICogaGFuZGxpbmcgZXZlcnkgYWN0aW9uIHZpYSBgQE91dHB1dGAuIFRoZSBzYW1lIGFjdGlvbnMgYXJlIGFsc28gZHJpdmVuIGJ5IHRoZVxuICogZGlhZ3JhbSdzIHJpZ2h0LWNsaWNrIGNvbnRleHQgbWVudSBhbmQga2V5Ym9hcmQgc2hvcnRjdXRzLCBzbyBrZWVwaW5nIHRoZVxuICogaGFuZGxlcnMgaW4gdGhlIGhvc3QgYXZvaWRzIGR1cGxpY2F0aW5nIHRoYXQgbG9naWMuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3Bsb3R0aW5nLXRvb2xiYXInLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlLFxuICAgIEJ1dHRvbk1vZHVsZSxcbiAgICBSaXBwbGVNb2R1bGUsXG4gICAgVG9vbGJhck1vZHVsZSxcbiAgICBUb29sdGlwTW9kdWxlLFxuICAgIFRvb2xiYXJIZWxwRGlhbG9nQ29tcG9uZW50LFxuICAgIFBsb3RUeXBlU2VsZWN0b3JDb21wb25lbnQsXG4gICAgU3RhY2tDb250cm9sc0NvbXBvbmVudCxcbiAgICBWaWV3Q29udHJvbHNDb21wb25lbnQsXG4gICAgUmVnaW9uVG9vbHNDb21wb25lbnQsXG4gICAgU2VnbWVudGF0aW9uVG9vbHNDb21wb25lbnQsXG4gIF0sXG4gIHRlbXBsYXRlVXJsOiAnLi90b29sYmFyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vdG9vbGJhci5jb21wb25lbnQuc2NzcyddLFxuICAvLyBQdXJlbHkgQElucHV0L0BPdXRwdXQ6IHJlLWNoZWNrIG9ubHkgd2hlbiBhbiBpbnB1dCBjaGFuZ2VzIG9yIHRoZSB0b29sYmFyXG4gIC8vIGl0c2VsZiBoYW5kbGVzIGFuIGV2ZW50LCBub3Qgb24gZXZlcnkgYXBwIHRpY2sgKGl0cyB+MTUgZ2V0dGVycyByYW4gZWFjaFxuICAvLyB0aW1lKS4gQ29udHJvbHMgYmluZCBbbmdNb2RlbF0gb25lLXdheSBhbmQgcmVwb3J0IHRocm91Z2ggdGhlIG91dHB1dHMsIHNvXG4gIC8vIHRoZSBob3N0IHN0YXlzIHRoZSBvd25lciBvZiBldmVyeSB2YWx1ZSAoUlQtMzUpLlxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgVG9vbGJhckNvbXBvbmVudCB7XG4gIC8qKiBDdXJyZW50IGltYWdlIChnYXRlcyB3aGljaCBjb250cm9sIGdyb3VwcyBhcmUgc2hvd24pLiAqL1xuICBASW5wdXQoKSBpbWFnZUluZm86IElJbWFnZUluZm8gfCB1bmRlZmluZWQ7XG4gIC8qKiBBIHNwYXRpYWwgZGF0YXNldCBpcyBvbiBvZmZlcjogaXRzIHBsb3QgbW9kZXMgYXJlIGEgY2hvaWNlIGV2ZW4gd2l0aCBubyBpbWFnZSBsb2FkZWQuICovXG4gIEBJbnB1dCgpIGhhc1NwYXRpYWxEYXRhc2V0ID0gZmFsc2U7XG5cbiAgLyoqIFdoZXRoZXIgdGhlIHBsb3QtdHlwZSBkcm9wZG93biBzaG93czogZm9yIGFuIGltYWdlLCBvciBhIHNwYXRpYWwgZGF0YXNldCB3aXRoIG5vbmUuICovXG4gIHByb3RlY3RlZCBnZXQgc2hvd1Bsb3RUeXBlcygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISEodGhpcy5pbWFnZUluZm8gfHwgdGhpcy5oYXNTcGF0aWFsRGF0YXNldCkgJiYgISF0aGlzLnRvb2xzLnNwZWNpYWxUb29scztcbiAgfVxuICAvKiogUGxvdCB0eXBlcyB0aGUgYWN0aXZlIGJhY2tlbmQgYWR2ZXJ0aXNlcywgdGhlbiBhbnkgY29udHJpYnV0ZWQgbW9kZXMuICovXG4gIEBJbnB1dCgpIHBsb3RUeXBlT3B0aW9uczogUGxvdFR5cGVPcHRpb25bXSA9IFtdO1xuICAvKiogVGhlIHNlbGVjdG9yJ3MgdmFsdWU6IGEgYnVpbHQtaW4gdHlwZSBvciBhIGNvbnRyaWJ1dGVkIG1vZGUncyBpZC4gKi9cbiAgQElucHV0KCkgc2VsZWN0ZWRQbG90VHlwZTogUGxvdFR5cGVJZCA9IFBsb3RUeXBlLklNQUdFO1xuICAvKipcbiAgICogVGhlIGJ1aWx0LWluIHR5cGUgdGhhdCByZW5kZXJzIHtAbGluayBzZWxlY3RlZFBsb3RUeXBlfSDigJQgaXRzIGBiYXNlVHlwZWBcbiAgICogZm9yIGEgY29udHJpYnV0ZWQgbW9kZS4gRXZlcnkgdG9vbC9jb250cm9sIGRlY2lzaW9uIGJlbG93IHJlYWRzXG4gICAqIHtAbGluayBlZmZlY3RpdmVQbG90VHlwZX0sIHNvIGEgY29udHJpYnV0ZWQgbW9kZSBnZXRzIGV4YWN0bHkgaXRzIGJhc2VcbiAgICogdHlwZSdzIHRvb2xiYXIuIFdoZW4gdW5ib3VuZCwgYSBidWlsdC1pbiBzZWxlY3Rpb24gaXMgaXRzIG93biBiYXNlIGFuZFxuICAgKiBhbnl0aGluZyBlbHNlIGlzIHRyZWF0ZWQgYXMgdGhlIGRlZmF1bHQgSW1hZ2Ugdmlldy5cbiAgICovXG4gIEBJbnB1dCgpIGJhc2VQbG90VHlwZTogUGxvdFR5cGUgfCBudWxsID0gbnVsbDtcbiAgLyoqIElzb3N1cmZhY2UgYmFuZCBhcyBhIDDigJMyNTUgc2xpZGVyIHBvc2l0aW9uIChtYXBwZWQgb250byB0aGUgdm9sdW1lJ3MgcmVhbFxuICAgKiAgaW50ZW5zaXR5IHJhbmdlIGJ5IHRoZSByZW5kZXJlcikuIERlZmF1bHRzIHRvIHRoZSBmdWxsIHJhbmdlLiAqL1xuICBASW5wdXQoKSBpc29SYW5nZTogbnVtYmVyW10gPSBbMCwgMjU1XTtcbiAgLyoqIFRoZSBsYXN0IHNsaWNlIGluZGV4IG9mIGEgc3RhY2suICovXG4gIEBJbnB1dCgpIG1heEluZGV4ID0gMDtcbiAgLyoqIFRoZSBjdXJyZW50IHNsaWNlICgwLWJhc2VkKS4gKi9cbiAgQElucHV0KCkgekluZGV4ID0gMDtcbiAgLyoqIFRydWUgZm9yIGFueSAyRCAobm9uIFN1cmZhY2UtM0QpIHBsb3QgdHlwZS4gKi9cbiAgQElucHV0KCkgaXNIZWF0bWFwID0gdHJ1ZTtcbiAgLyoqXG4gICAqIFJlZ2lvbiB0b29scyBhcHBseSBldmVuIHRob3VnaCB0aGlzIGlzIGEgM0QgdmlldywgYmVjYXVzZSB0aGV5IGRyYXcgYVxuICAgKiBTQ1JFRU4tU1BBQ0UgbGFzc28gKHRoZSAzRCBzcGF0aWFsIGNsb3VkKS4gU2VwYXJhdGUgZnJvbSB7QGxpbmsgaXNIZWF0bWFwfSxcbiAgICogd2hpY2ggbWVhbnMgXCIyRCB2aWV3XCIgYW5kIGFsc28gZHJpdmVzIHRoZSB6b29tIHRvb2xzIGFuZCB0aGUgM0QgY2FtZXJhXG4gICAqIGNvbnRyb2xzIOKAlCBmbGlwcGluZyB0aGF0IHdvdWxkIHNob3cgMkQgcGFuL3pvb20gYW5kIGhpZGUgdGhlIG9yYml0IGNvbnRyb2xzLlxuICAgKi9cbiAgQElucHV0KCkgaXMzZFJlZ2lvbnMgPSBmYWxzZTtcbiAgLyoqIEEgbmFwYXJpIHZvbHVtZSAvIGlzb3N1cmZhY2UgdmlldzogdGhlIFJlZ2lvbiBFZGl0b3IgKHJlZ2lvbnMgaW4gM0QpIHdpdGhvdXQgZHJhd2luZyB0b29scy4gKi9cbiAgQElucHV0KCkgaXNWb2x1bWVWaWV3ID0gZmFsc2U7XG4gIC8qKiBXaGV0aGVyIHRoZSB2b2x1bWUgdmlldyBpcyBzcGxpdCB3aXRoIHRoZSBzbGljZSBlZGl0b3IgKHRoZSBzbGljZSwgd2l0aCBldmVyeSByZWdpb24gdG9vbCkuICovXG4gIEBJbnB1dCgpIHNsaWNlRWRpdG9yID0gZmFsc2U7XG4gIC8qKiBUaGUgYXJtZWQgdG9vbCdzIG1vZGUgKHpvb20sIHBhbiwgYSBkcmF3aW5nIHRvb2wsIGBzYW1Qb2ludGAsIOKApiksIG9yIG51bGwuICovXG4gIEBJbnB1dCgpIGFjdGl2ZURyYWdNb2RlOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgLyoqIFRoZSAzRCBjYW1lcmEgbW9kZSAoYHR1cm50YWJsZWAgLyBgb3JiaXRgIC8g4oCmKS4gKi9cbiAgQElucHV0KCkgYWN0aXZlU3VyZmFjZTNkTW9kZSA9ICd0dXJudGFibGUnO1xuICAvKiogV2hldGhlciB0aGUgbmFwYXJpIDNEIGF4ZXMvc2NhbGUgZ2l6bW8gaXMgY3VycmVudGx5IHNob3duIChkcml2ZXMgdGhlIHRvZ2dsZSdzIGxvb2spLiAqL1xuICBASW5wdXQoKSBheGVzVmlzaWJsZSA9IHRydWU7XG4gIC8qKiBUaGUgbmFwYXJpIHN1cmZhY2Ugd2lyZWZyYW1lIGlzIG9uLiAqL1xuICBASW5wdXQoKSB3aXJlZnJhbWVBY3RpdmUgPSBmYWxzZTtcbiAgLyoqIEFjdGl2ZSBuYXBhcmkgM0QgZGVjaW1hdGUgZmFjdG9yICgxID0gRnVsbCDigKYgOCA9IOKFmzsgZGVmYXVsdCDCvSkuICovXG4gIEBJbnB1dCgpIHJlc29sdXRpb25TY2FsZSA9IE5BUEFSSV9ERUZBVUxUX0RFQ0lNQVRFO1xuICAvKiogTWFnaWMtd2FuZCBzZW5zaXRpdml0eS4gKi9cbiAgQElucHV0KCkgd2FuZFNlbnNpdGl2aXR5ID0gMi4wO1xuICAvKiogQnJ1c2ggZGlhbWV0ZXIgaW4gaW1hZ2UgcGl4ZWxzLiAqL1xuICBASW5wdXQoKSBicnVzaFNpemUgPSA0MDtcbiAgLyoqIFZlcnRleC1lcmFzZXIgcmFkaXVzIGluIGltYWdlIHBpeGVscy4gKi9cbiAgQElucHV0KCkgdmVydGV4RXJhc2VyUmFkaXVzID0gMjA7XG4gIC8qKiBXaGV0aGVyIGEgcmVnaW9uIGFjdGlvbiBpcyBhdmFpbGFibGUgdG8gdW5kbyAoaml0LXVpIzg1KS4gR3JleXMgb3V0IHRoZVxuICAgKiAgVW5kbyBidXR0b24gd2hlbiBmYWxzZSAobm90aGluZyBkb25lIHlldCwgb3IgYWxsIHN0ZXBzIGFscmVhZHkgdW5kb25lKS4gKi9cbiAgQElucHV0KCkgY2FuVW5kbyA9IGZhbHNlO1xuICAvKiogV2hldGhlciBhbiB1bmRvbmUgcmVnaW9uIGFjdGlvbiBpcyBhdmFpbGFibGUgdG8gcmVkbyAoaml0LXVpIzg1KS4gR3JleXNcbiAgICogIG91dCB0aGUgUmVkbyBidXR0b24gd2hlbiBmYWxzZS4gKi9cbiAgQElucHV0KCkgY2FuUmVkbyA9IGZhbHNlO1xuICAvKiogVGhlIHNpbmdsZS1pbWFnZSAvIHN0YWNrIGNob2ljZXMgb2YgdGhlIFBsb3RseSBzdGFjayB0b2dnbGUuICovXG4gIEBJbnB1dCgpIHN0YWNrT3B0aW9uczogeyBuYW1lOiBzdHJpbmc7IHZhbDogc3RyaW5nIH1bXSA9IFtcbiAgICB7IG5hbWU6ICdTaW5nbGUgaW1hZ2UnLCB2YWw6ICdmYWxzZScgfSxcbiAgICB7IG5hbWU6ICdTdGFjaycsIHZhbDogJ3RydWUnIH0sXG4gIF07XG4gIC8qKiBXaGljaCB0b29sYmFyIGdyb3VwcyB0byBzaG93LiBEZWZhdWx0cyB0byB0aGUgZnVsbCB0b29sYmFyOyB0aGUgaG9zdCBmb3J3YXJkc1xuICAgKiAgdGhlIGNvbnN1bWVyJ3MgY2hvaWNlIChlLmcuIHRoZSBwaXBlbGluZSBzaG93cyBvbmx5IHpvb20gKyByZWdpb24gdG9vbHMpLiAqL1xuICBASW5wdXQoKSB0b29sczogUmVxdWlyZWQ8VG9vbGJhclRvb2xWaXNpYmlsaXR5PiA9IEFMTF9UT09MQkFSX1RPT0xTO1xuICAvKiogQ3VycmVudCBpbWFnZS1zbW9vdGhpbmcgc3RhdGUgKGRyaXZlcyB0aGUgU21vb3RoZW4gdG9nZ2xlIGJ1dHRvbiBsb29rKS5cbiAgICogIGBmYWxzZWAgPSBuZWFyZXN0LW5laWdoYm91ciAoY3Jpc3AgcmF3IHBpeGVscyksIHRoZSBkZWZhdWx0LiAqL1xuICBASW5wdXQoKSBpbWFnZVNtb290aGluZ0VuYWJsZWQgPSBmYWxzZTtcbiAgLyoqIFNBTSBtb2RlbCBwaWNrZXIgb3B0aW9ucyArIGN1cnJlbnQgc2VsZWN0aW9uIChqaXQtdWkjOTAgUDEpLiAqL1xuICBASW5wdXQoKSBzYW1Nb2RlbHM6IHsgaWQ6IHN0cmluZzsgbGFiZWw6IHN0cmluZyB9W10gPSBbXTtcbiAgLyoqIFRoZSBzZWxlY3RlZCBTQU0gbW9kZWwgaWQuICovXG4gIEBJbnB1dCgpIHNhbU1vZGVsSWQgPSAnJztcbiAgLyoqXG4gICAqIFRvb2xzIGNvbnRyaWJ1dGVkIHRocm91Z2gge0BsaW5rIFRPT0xCQVJfVE9PTFN9LCBhbHJlYWR5IGZpbHRlcmVkIHRvIHRoZVxuICAgKiBvbmVzIHdpdGggbW9kZWxzIGFuZCBzb3J0ZWQuIFRoZSBob3N0IHJlc29sdmVzIHRoZW0gc28gaXQgY2FuIG93biB0aGVcbiAgICogcGVyLXRvb2wgcGFyYW1ldGVyIHN0YXRlOyB0aGlzIGNvbXBvbmVudCBvbmx5IGRyYXdzIHRoZW0uXG4gICAqL1xuICBASW5wdXQoKSBjb250cmlidXRlZFRvb2xzOiBUb29sYmFyVG9vbENvbnRyaWJ1dGlvbltdID0gW107XG4gIC8qKiBEaWFsb2cgdG9vbHMgKFRPT0xCQVJfVE9PTFMsIGtpbmQ6ICdkaWFsb2cnKSwgc29ydGVkOyBzaG93biBpbiB0aGUgSW1hZ2Ugdmlldy4gKi9cbiAgQElucHV0KCkgZGlhbG9nVG9vbHM6IFRvb2xiYXJEaWFsb2dUb29sQ29udHJpYnV0aW9uW10gPSBbXTtcbiAgLyoqIElkIG9mIHRoZSBkaWFsb2cgdG9vbCB3aG9zZSBkaWFsb2cgaXMgb3Blbiwgb3IgbnVsbC4gKi9cbiAgQElucHV0KCkgb3BlbkRpYWxvZ1Rvb2xJZDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBBY3RpdmUgY2hlY2twb2ludCBwZXIgY29udHJpYnV0ZWQgdG9vbCwga2V5ZWQgYnkgdG9vbCBpZC4gKi9cbiAgQElucHV0KCkgdG9vbE1vZGVsSWRzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG5cbiAgLyoqIEEgcGxvdCB0eXBlIG9yIGNvbnRyaWJ1dGVkIG1vZGUgd2FzIHBpY2tlZC4gKi9cbiAgQE91dHB1dCgpIHNlbGVjdFBsb3RUeXBlID0gbmV3IEV2ZW50RW1pdHRlcjxQbG90VHlwZUlkPigpO1xuICAvKiogSW50ZW5zaXR5IChMSU5FKSBtb2RlOiBhZGQgYW5vdGhlciBjb2xvcmVkIGxpbmUgUk9JICsgaW5zZXQgdHJhY2UuICovXG4gIEBPdXRwdXQoKSBhZGRQcm9maWxlTGluZSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIFRvZ2dsZSBpbWFnZSBzbW9vdGhpbmcgKGJpbGluZWFyKSB2cyBuZWFyZXN0LW5laWdoYm91ciAoY3Jpc3AgcGl4ZWxzKS4gKi9cbiAgQE91dHB1dCgpIHRvZ2dsZUltYWdlU21vb3RoaW5nID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvLyBQcmltZU5HIHNsaWRlci9pbnB1dE51bWJlciBjaGFuZ2UgZXZlbnRzIGNhcnJ5IG9wdGlvbmFsIHZhbHVlcywgbWlycm9yZWQgYnlcbiAgLy8gdGhlIGhvc3QgaGFuZGxlcnMgKHdoaWNoIGFjY2VwdCBgfCB1bmRlZmluZWRgKS5cbiAgLyoqIFRoZSBpc29zdXJmYWNlIGJhbmQgc2xpZGVyIG1vdmVkOiB0aGUgbmV3IGBbbG93LCBoaWdoXWAgcGFpci4gKi9cbiAgQE91dHB1dCgpIGlzb1JhbmdlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXJbXSB8IHVuZGVmaW5lZD4oKTtcbiAgLyoqIE9wZW4gdGhlIENoYW5uZWxzICYgSGlzdG9ncmFtIGRpYWxvZyAoYnJpZ2h0bmVzcy9jb250cmFzdCwgY29sb3JtYXAsIOKApikuICovXG4gIEBPdXRwdXQoKSBvcGVuQ2hhbm5lbEhpc3RvZ3JhbSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIE9wZW4gdGhlIHNwYXRpYWwtb21pY3MgY29udHJvbHMgKGNvbG91ci1ieSwgbGVnZW5kLCBwb2ludCBkaXNwbGF5KS4gKi9cbiAgQE91dHB1dCgpIG9wZW5TcGF0aWFsQ29udHJvbHMgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBPcGVuIHRoZSBSZWdpb24gRWRpdG9yIGRpYWxvZy4gKi9cbiAgQE91dHB1dCgpIG9wZW5SZWdpb25FZGl0b3IgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBTcGxpdCB0aGUgdm9sdW1lIHZpZXcgd2l0aCB0aGUgc2xpY2UgZWRpdG9yLCBvciBjbG9zZSBpdC4gKi9cbiAgQE91dHB1dCgpIHRvZ2dsZVNsaWNlRWRpdG9yID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogQSBzaW5nbGUtaW1hZ2UgLyBzdGFjayBjaG9pY2Ugd2FzIHBpY2tlZC4gKi9cbiAgQE91dHB1dCgpIHNlbGVjdFN0YWNrT3B0aW9uID0gbmV3IEV2ZW50RW1pdHRlcjx7IG5hbWU6IHN0cmluZzsgdmFsOiBzdHJpbmcgfT4oKTtcbiAgLyoqIFRoZSBsaXZlIHNsaWNlIHNjcnViYmVyIG1vdmVkIChmaXJlcyB3aGlsZSBkcmFnZ2luZykuICovXG4gIEBPdXRwdXQoKSB6U2NydWIgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlciB8IHVuZGVmaW5lZD4oKTtcbiAgLyoqIFRoZSBsaXZlIHNsaWNlIHNjcnViYmVyIHdhcyByZWxlYXNlZCBvbiBhIHNsaWNlLiAqL1xuICBAT3V0cHV0KCkgelNsaWRlID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXIgfCB1bmRlZmluZWQ+KCk7XG4gIC8qKiBBIHNsaWNlIG51bWJlciB3YXMgdHlwZWQuICovXG4gIEBPdXRwdXQoKSB6SW5kZXhJbnB1dCA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuICAvKiogUmUtcGxvdCBhdCB0aGUgdHlwZWQgc2xpY2UuICovXG4gIEBPdXRwdXQoKSByZWxvYWRBbmRQbG90ID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogRG93bmxvYWQgdGhlIGN1cnJlbnQgdmlldyBhcyBQTkcuICovXG4gIEBPdXRwdXQoKSBkb3dubG9hZEltYWdlID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogRml0IHRoZSBpbWFnZSB0byB0aGUgdmlldy4gKi9cbiAgQE91dHB1dCgpIGF1dG9zY2FsZUltYWdlID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogQSB6b29tIC8gcGFuIC8gZHJhd2luZyB0b29sIGJ1dHRvbiB3YXMgY2xpY2tlZCAoaXRzIG1vZGUpLiAqL1xuICBAT3V0cHV0KCkgdG9nZ2xlRHJhZ01vZGUgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgLyoqIFpvb20gaW4gb25lIHN0ZXAuICovXG4gIEBPdXRwdXQoKSB6b29tSW4gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBab29tIG91dCBvbmUgc3RlcC4gKi9cbiAgQE91dHB1dCgpIHpvb21PdXQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBBIDNEIGNhbWVyYSBtb2RlIGJ1dHRvbiB3YXMgY2xpY2tlZCAoaXRzIG1vZGUpLiAqL1xuICBAT3V0cHV0KCkgdG9nZ2xlU3VyZmFjZTNkTW9kZSA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICAvKiogUmVzZXQgdGhlIDNEIGNhbWVyYS4gKi9cbiAgQE91dHB1dCgpIHJlc2V0U3VyZmFjZUNhbWVyYSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIFRvZ2dsZSB0aGUgbmFwYXJpIDNEIGNvb3JkaW5hdGUtYXhlcyAvIHNjYWxlIGdpem1vIG9uL29mZi4gKi9cbiAgQE91dHB1dCgpIHRvZ2dsZUF4ZXMgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBUb2dnbGUgdGhlIG5hcGFyaSBzdXJmYWNlIHdpcmVmcmFtZSAoZWRnZXMpIG9uL29mZi4gKi9cbiAgQE91dHB1dCgpIHRvZ2dsZVdpcmVmcmFtZSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIENoYW5nZSB0aGUgbmFwYXJpIDNEIGRlY2ltYXRlIGZhY3RvciAocmVsb2FkcyBhdCB0aGUgbmV3IHJlc29sdXRpb24pLiAqL1xuICBAT3V0cHV0KCkgc2VsZWN0UmVzb2x1dGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuICAvKiogRGVsZXRlIHRoZSBzZWxlY3RlZCByZWdpb24uICovXG4gIEBPdXRwdXQoKSBkZWxldGVSZWdpb24gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBVbmRvIHRoZSBsYXN0IHJlZ2lvbiBhY3Rpb24gKGppdC11aSM4NSkuICovXG4gIEBPdXRwdXQoKSB1bmRvUmVnaW9uID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogUmVkbyB0aGUgbGFzdCB1bmRvbmUgcmVnaW9uIGFjdGlvbiAoaml0LXVpIzg1KS4gKi9cbiAgQE91dHB1dCgpIHJlZG9SZWdpb24gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBSdW4gYm94LXByb21wdGVkIFNBTSBzZWdtZW50YXRpb24gb24gdGhlIGRyYXduIHJlY3RhbmdsZXMgKGppdC11aSM5MCkuICovXG4gIEBPdXRwdXQoKSBzZWdtZW50UmVnaW9ucyA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIFJ1biBjZWxscG9zZS1TQU0gKGF1dG8pIGluc2lkZSBlYWNoIGRyYXduIHJlY3RhbmdsZSdzIGNyb3AgKGppdC11aSM5MCkuICovXG4gIEBPdXRwdXQoKSBzZWdtZW50Q2VsbHBvc2UgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBSdW4gYSBjb250cmlidXRlZCB0b29sIG92ZXIgdGhlIGN1cnJlbnQgdmlldywgYnkgdG9vbCBpZC4gKi9cbiAgQE91dHB1dCgpIHJ1blRvb2wgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgLyoqIEEgZGlhbG9nIHRvb2wncyBidXR0b24gd2FzIGNsaWNrZWQ6IG9wZW4gaXRzIGRpYWxvZywgb3IgY2xvc2UgaXQgaWYgb3Blbi4gKi9cbiAgQE91dHB1dCgpIHRvZ2dsZURpYWxvZ1Rvb2wgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgLyoqIFBpY2sgYSBjb250cmlidXRlZCB0b29sJ3MgY2hlY2twb2ludC4gKi9cbiAgQE91dHB1dCgpIHRvb2xNb2RlbENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8eyB0b29sSWQ6IHN0cmluZzsgbW9kZWxJZDogc3RyaW5nIH0+KCk7XG4gIC8qKiBPcGVuIGEgY29udHJpYnV0ZWQgdG9vbCdzIHBhcmFtZXRlciBkaWFsb2csIGJ5IHRvb2wgaWQuICovXG4gIEBPdXRwdXQoKSBvcGVuVG9vbFBhcmFtcyA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICAvKiogU0FNIG1vZGVsIHBpY2tlciAoaml0LXVpIzkwIFAxKS4gKi9cbiAgQE91dHB1dCgpIHNhbU1vZGVsQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIC8qKiBUaGUgd2FuZCBzZW5zaXRpdml0eSBzbGlkZXIgbW92ZWQuICovXG4gIEBPdXRwdXQoKSB3YW5kU2Vuc2l0aXZpdHlDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlciB8IHVuZGVmaW5lZD4oKTtcbiAgLyoqIFRoZSBicnVzaCBzaXplIHNsaWRlciBtb3ZlZC4gKi9cbiAgQE91dHB1dCgpIGJydXNoU2l6ZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyIHwgdW5kZWZpbmVkPigpO1xuICAvKiogVGhlIHZlcnRleC1lcmFzZXIgcmFkaXVzIHNsaWRlciBtb3ZlZC4gKi9cbiAgQE91dHB1dCgpIHZlcnRleEVyYXNlclJhZGl1c0NoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyIHwgdW5kZWZpbmVkPigpO1xuXG4gIHByb3RlY3RlZCBkaXNwbGF5SGVscERpYWxvZyA9IGZhbHNlO1xuXG4gIC8qKiB0cmFja0J5IGZvciB0aGUgZGlhbG9nIHRvb2xzJyBidXR0b25zLiAqL1xuICBwcm90ZWN0ZWQgdHJhY2tUb29sQnlJZChfaW5kZXg6IG51bWJlciwgdG9vbDogeyBpZDogc3RyaW5nIH0pOiBzdHJpbmcge1xuICAgIHJldHVybiB0b29sLmlkO1xuICB9XG5cbiAgLyoqIFRoZSBidWlsdC1pbiB0eXBlIHdob3NlIHRvb2xzIGFuZCBjb250cm9scyBhcHBseSB0byB0aGUgY3VycmVudCBzZWxlY3Rpb24uICovXG4gIHByb3RlY3RlZCBnZXQgZWZmZWN0aXZlUGxvdFR5cGUoKTogUGxvdFR5cGUge1xuICAgIGlmICh0aGlzLmJhc2VQbG90VHlwZSkgcmV0dXJuIHRoaXMuYmFzZVBsb3RUeXBlO1xuICAgIHJldHVybiBpc0J1aWx0aW5QbG90VHlwZSh0aGlzLnNlbGVjdGVkUGxvdFR5cGUpID8gdGhpcy5zZWxlY3RlZFBsb3RUeXBlIDogUGxvdFR5cGUuSU1BR0U7XG4gIH1cblxuICAvKiogVGhlIEltYWdlIHBsb3QgdHlwZSByZW5kZXJzIGFzIGEgbmF0aXZlbHkgcGFuL3pvb20tYWJsZSByYXN0ZXIsIHNvIHRoZVxuICAgKiAgZ2VuZXJpYyB6b29tL3BhbiB0b29scyBhcmUgaGlkZGVuLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGlzSW1hZ2VWaWV3KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlID09PSBQbG90VHlwZS5JTUFHRTtcbiAgfVxuXG4gIC8qKiBFaXRoZXIgc3BhdGlhbC1vbWljcyBtb2RlIGlzIGFjdGl2ZSwgc28gaXRzIGNvbnRyb2xzIGFyZSB3b3J0aCBvZmZlcmluZy5cbiAgICogIFRoZSAzRCBjbG91ZCBuZWVkcyB0aGUgcGFuZWwgTU9SRSB0aGFuIHRoZSAyRCB2aWV3IGRvZXMsIG5vdCBsZXNzOiBjb2xvdXJpbmcsXG4gICAqICB0aGUgbGVnZW5kIGFuZCBjYXRlZ29yeSBzaG93L2hpZGUgYXJlIHRoZSBvbmx5IHdheSB0byBtYWtlIHNlbnNlIG9mIGFcbiAgICogIG1pbGxpb24gb3ZlcmxhcHBpbmcgcG9pbnRzLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGlzU3BhdGlhbE1vZGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGlzU3BhdGlhbE9taWNzKHRoaXMuZWZmZWN0aXZlUGxvdFR5cGUpIHx8IGlzU3BhdGlhbE9taWNzM2QodGhpcy5lZmZlY3RpdmVQbG90VHlwZSk7XG4gIH1cblxuICAvKiogQmFja2VuZHMgd2l0aCBhIHZlcnRleC1lZGl0aW5nIHJlZ2lvbiBvdmVybGF5OiBPU0QgSW1hZ2UgYW5kIG5hcGFyaS1qcyBXZWJHUFUgaW1hZ2VcbiAgICogIChqaXQtdWkjMTAyKS4gR2F0ZXMgdGhlIHBvbHlnb24gLyBhZGQtdmVydGV4IC8gZGVsZXRlLXZlcnRleCAvIELDqXppZXItY29udmVydCB0b29scy4gKi9cbiAgcHJvdGVjdGVkIGdldCBzdXBwb3J0c1JlZ2lvblZlcnRleFRvb2xzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlID09PSBQbG90VHlwZS5JTUFHRSB8fCB0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlID09PSBQbG90VHlwZS5OQVBBUklfSU1BR0U7XG4gIH1cblxuICAvKiogUGxvdCB0eXBlcyB0aGF0IHNjcnViIGEgei1zdGFjayBsaXZlICh0aGUgcmVuZGVyZXIgc3dhcHMgdGhlIHNsaWNlIGluIHBsYWNlKTogdGhlIE9TRCBJbWFnZVxuICAgKiAgdmlldywgdGhlIG5hcGFyaS1qcyBXZWJHUFUgaW1hZ2UsIHRoZSBuYXBhcmktanMgc3VyZmFjZSDigJQgd2hpY2ggcmVidWlsZHMgdGhlIGhlaWdodCBmaWVsZFxuICAgKiAgZnJvbSB0aGUgcGlja2VkIHNsaWNlIChqaXQtdWkjMTAyKSDigJQgYW5kIHRoZSAyRCBzcGF0aWFsLW9taWNzIHZpZXcsIHdoZXJlIGEgM0QgZGF0YXNldCdzXG4gICAqICByZWdpc3RlcmVkIHZvbHVtZSBpcyB0aGUgaW1hZ2UgYW5kIHRoZSBzbGlkZXIgcGlja3MgdGhlIHNlY3Rpb24gd2hvc2Ugb2JzZXJ2YXRpb25zIGFyZVxuICAgKiAgZHJhd24uIEFsc28gYSBzcGxpdCB2b2x1bWUgdmlldywgd2hvc2Ugc2xpY2UgZWRpdG9yIHNob3dzIHRoZSBzbGljZSBwaWNrZWQuIERyaXZlcyB0aGVcbiAgICogIHBlci1zbGljZSBzbGlkZXIuICovXG4gIHByb3RlY3RlZCBnZXQgc2hvd3NMaXZlU2xpY2VTY3J1YmJlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKFxuICAgICAgKHRoaXMuaXNWb2x1bWVWaWV3ICYmIHRoaXMuc2xpY2VFZGl0b3IpIHx8XG4gICAgICB0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlID09PSBQbG90VHlwZS5JTUFHRSB8fFxuICAgICAgdGhpcy5lZmZlY3RpdmVQbG90VHlwZSA9PT0gUGxvdFR5cGUuTkFQQVJJX0lNQUdFIHx8XG4gICAgICBpc05hcGFyaVN1cmZhY2UodGhpcy5lZmZlY3RpdmVQbG90VHlwZSkgfHxcbiAgICAgIGlzTmFwYXJpU2NhdHRlcih0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlKSB8fFxuICAgICAgaXNTcGF0aWFsT21pY3ModGhpcy5lZmZlY3RpdmVQbG90VHlwZSlcbiAgICApO1xuICB9XG5cbiAgLyoqIEFueSBuYXBhcmktanMgV2ViR1BVIHBsb3QgdHlwZS4gVGhlIHNpbmdsZS1pbWFnZS9zdGFjayB0b2dnbGUgKyBzbGljZS1udW1iZXIgZmllbGQgYXJlXG4gICAqICBQbG90bHktb25seSBzdGFjayBjb250cm9scywgc28gdGhleSdyZSBoaWRkZW4gZm9yIG5hcGFyaSAoaml0LXVpIzEwMikuICovXG4gIHByb3RlY3RlZCBnZXQgaXNOYXBhcmlNb2RlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlID09PSBQbG90VHlwZS5OQVBBUklfSU1BR0UgfHxcbiAgICAgIGlzTmFwYXJpU2NhdHRlcih0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlKSB8fFxuICAgICAgaXNOYXBhcmkzZCh0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlKVxuICAgICk7XG4gIH1cblxuICAvKiogSVNPU1VSRkFDRSAoUGxvdGx5IG9yIG5hcGFyaS1qcyBXZWJHUFUsIGVpdGhlciByZXNvbHV0aW9uKSBzaG93cyB0aGUgaXNvdmFsdWUgcmFuZ2Ugc2xpZGVyLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGlzSXNvc3VyZmFjZU1vZGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZWZmZWN0aXZlUGxvdFR5cGUgPT09IFBsb3RUeXBlLklTT1NVUkZBQ0UgfHwgaXNOYXBhcmlJc29zdXJmYWNlKHRoaXMuZWZmZWN0aXZlUGxvdFR5cGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSB2aWV3cyB0aGF0IGRyYXcgdGhlIDNEIGF4ZXMgZ2l6bW8gKGFuIGBBeGVzM2RHaXptb2ApOiBuYXBhcmktanMncyB2b2x1bWUsIGlzb3N1cmZhY2UgYW5kXG4gICAqIHN1cmZhY2UsIGFuZCB0aGUgM0Qgc3BhdGlhbCBjbG91ZC4gTm90IGV2ZXJ5IG5hcGFyaS1qcyB2aWV3OiBpdHMgMkQgaW1hZ2UgYW5kIHNjYXR0ZXIgYW5kIGl0c1xuICAgKiAzRCBzY2F0dGVyIGRyYXcgbm9uZSwgYW5kIGEgdG9nZ2xlIHRoZXJlIHdvdWxkIGRvIG5vdGhpbmcuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IHNob3dzQXhlc1RvZ2dsZSgpOiBib29sZWFuIHtcbiAgICBjb25zdCB0eXBlID0gdGhpcy5lZmZlY3RpdmVQbG90VHlwZTtcbiAgICByZXR1cm4gaXNOYXBhcmlWb2x1bWUodHlwZSkgfHwgaXNOYXBhcmlJc29zdXJmYWNlKHR5cGUpIHx8IGlzTmFwYXJpU3VyZmFjZSh0eXBlKSB8fCBpc1NwYXRpYWxPbWljczNkKHR5cGUpO1xuICB9XG5cbiAgLyoqIFRoZSBuYXBhcmktanMgV2ViR1BVIHN1cmZhY2Ug4oCUIHNob3dzIHRoZSB3aXJlZnJhbWUgdG9nZ2xlLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGlzTmFwYXJpU3VyZmFjZU1vZGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGlzTmFwYXJpU3VyZmFjZSh0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlKTtcbiAgfVxuXG4gIC8qKiBBbnkgbmFwYXJpLWpzIFdlYkdQVSAzRCB0eXBlICh2b2x1bWUvaXNvc3VyZmFjZS9zdXJmYWNlKSDigJQgc2hvd3MgdGhlIFJlc29sdXRpb24gY29udHJvbC4gKi9cbiAgcHJvdGVjdGVkIGdldCBpc05hcGFyaTNkTW9kZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaXNOYXBhcmkzZCh0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlKTtcbiAgfVxuXG4gIC8qKiBJbnRlbnNpdHkgcHJvZmlsZSBsaW5lcyBhcmUgUmVnaW9uLWJhc2VkIGFuZCBhdmFpbGFibGUgaW4gdGhlIEhlYXRtYXAgYW5kXG4gICAqICBJbWFnZSBwbG90IHR5cGVzLCB3aGljaCBzaG93IHRoZSBJbnRlbnNpdHkgdG9vbCBncm91cC4gKi9cbiAgcHJvdGVjdGVkIGdldCBpc0ludGVuc2l0eUNhcGFibGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZWZmZWN0aXZlUGxvdFR5cGUgPT09IFBsb3RUeXBlLkhFQVRNQVAgfHwgdGhpcy5lZmZlY3RpdmVQbG90VHlwZSA9PT0gUGxvdFR5cGUuSU1BR0U7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2hvd0hlbHAoKTogdm9pZCB7XG4gICAgdGhpcy5kaXNwbGF5SGVscERpYWxvZyA9IHRydWU7XG4gIH1cbn1cbiIsIjxwLXRvb2xiYXI+XG4gIDxkaXYgY2xhc3M9XCJwLXRvb2xiYXItZ3JvdXAtc3RhcnQgZmxleC13cmFwIGFsaWduLWl0ZW1zLWNlbnRlciBnYXAtMVwiPlxuICAgIDwhLS0gSG9zdC1wcm92aWRlZCBjdXN0b20gdG9vbGJhciBidXR0b25zLCBzaG93biBmaXJzdCAoZS5nLiBhcHAtc3BlY2lmaWNcbiAgICAgICAgIGFjdGlvbnMgdGhlIHZpc3VhbGl6YXRpb24gdmlldyBpdHNlbGYgZG9lc24ndCBvd24pLiAtLT5cbiAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG5cbiAgICA8IS0tIENvbnRyaWJ1dGVkIGRpYWxvZyB0b29scyAoVE9PTEJBUl9UT09MUywga2luZDogJ2RpYWxvZycpOiBhcHAtbGV2ZWwgYWN0aW9uc1xuICAgICAgICAgbGlrZSB0aGUgaG9zdCdzIG93biBidXR0b25zIGFib3ZlLCBzbyB0aGV5IHNpdCByaWdodCBiZXNpZGUgdGhlbS4gSW1hZ2Ugdmlld1xuICAgICAgICAgb25seSwgdGhlIHZpZXcgdGhlaXIgZGlhbG9nIGRyYXdzIG92ZXIuIEhpZ2hsaWdodGVkIHdoaWxlIHRoZSBkaWFsb2cgaXMgb3Blbi4gLS0+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzSW1hZ2VWaWV3XCI+XG4gICAgICA8cC1idXR0b25cbiAgICAgICAgKm5nRm9yPVwibGV0IHRvb2wgb2YgZGlhbG9nVG9vbHM7IHRyYWNrQnk6IHRyYWNrVG9vbEJ5SWRcIlxuICAgICAgICBzaXplPVwic21hbGxcIlxuICAgICAgICBbdGV4dF09XCJvcGVuRGlhbG9nVG9vbElkICE9PSB0b29sLmlkXCJcbiAgICAgICAgW3BUb29sdGlwXT1cInRvb2wudG9vbHRpcFwiXG4gICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgICAgIFthcmlhTGFiZWxdPVwidG9vbC5sYWJlbFwiXG4gICAgICAgIFthdHRyLmFyaWEtcHJlc3NlZF09XCJvcGVuRGlhbG9nVG9vbElkID09PSB0b29sLmlkXCJcbiAgICAgICAgKG9uQ2xpY2spPVwidG9nZ2xlRGlhbG9nVG9vbC5lbWl0KHRvb2wuaWQpXCJcbiAgICAgID5cbiAgICAgICAgPGltZ1xuICAgICAgICAgICpuZ0lmPVwidG9vbC5pY29uLnNyY1wiXG4gICAgICAgICAgW3NyY109XCJ0b29sLmljb24uc3JjXCJcbiAgICAgICAgICBzdHlsZT1cIndpZHRoOiAxcmVtXCJcbiAgICAgICAgICBbYWx0XT1cInRvb2wubGFiZWxcIlxuICAgICAgICAgIFtjbGFzc109XCJvcGVuRGlhbG9nVG9vbElkID09PSB0b29sLmlkID8gJ3Rvb2xiYXItaWNvbi1hY3RpdmUnIDogJ3Rvb2xiYXItaWNvbi1kYXJrJ1wiXG4gICAgICAgIC8+XG4gICAgICAgIDxpICpuZ0lmPVwidG9vbC5pY29uLnBpXCIgY2xhc3M9XCJwaSB7eyB0b29sLmljb24ucGkgfX1cIj48L2k+XG4gICAgICA8L3AtYnV0dG9uPlxuICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgPCEtLSBQbG90IHR5cGU6IGF2YWlsYWJsZSBmb3IgYW55IGltYWdlIChncmF5c2NhbGUgb3IgUkdCKSwgYW5kIGZvciBhIHNwYXRpYWwgZGF0YXNldFxuICAgICAgICAgdGhhdCBicmluZ3Mgbm9uZSAoaXRzIHNwYXRpYWwgbW9kZXMgYXJlIHN0aWxsIGEgY2hvaWNlKS4gLS0+XG4gICAgPHRvb2xiYXItcGxvdC10eXBlLXNlbGVjdG9yXG4gICAgICAqbmdJZj1cInNob3dQbG90VHlwZXNcIlxuICAgICAgW29wdGlvbnNdPVwicGxvdFR5cGVPcHRpb25zXCJcbiAgICAgIFtzZWxlY3RlZF09XCJzZWxlY3RlZFBsb3RUeXBlXCJcbiAgICAgIFtpc29zdXJmYWNlXT1cImlzSXNvc3VyZmFjZU1vZGVcIlxuICAgICAgW2lzb1JhbmdlXT1cImlzb1JhbmdlXCJcbiAgICAgIFtpbnRlbnNpdHlMaW5lc109XCJpc0ludGVuc2l0eUNhcGFibGVcIlxuICAgICAgKHNlbGVjdFBsb3RUeXBlKT1cInNlbGVjdFBsb3RUeXBlLmVtaXQoJGV2ZW50KVwiXG4gICAgICAoaXNvUmFuZ2VDaGFuZ2UpPVwiaXNvUmFuZ2VDaGFuZ2UuZW1pdCgkZXZlbnQpXCJcbiAgICAgIChhZGRQcm9maWxlTGluZSk9XCJhZGRQcm9maWxlTGluZS5lbWl0KClcIlxuICAgID5cbiAgICA8L3Rvb2xiYXItcGxvdC10eXBlLXNlbGVjdG9yPlxuICAgIDwhLS0gQ2hhbm5lbHMgJiBIaXN0b2dyYW06IGJyaWdodG5lc3MvY29udHJhc3QsIGdhbW1hLCBwZXItY2hhbm5lbCBkaXNwbGF5LFxuICAgICAgICAgY29sb3JtYXAvcmV2ZXJzZS9pbnZlcnQg4oCUIG9wZW5zIHRoZSBmbG9hdGluZyBkaWFsb2cuIC0tPlxuICAgIDxwLWJ1dHRvblxuICAgICAgKm5nSWY9XCJ0b29scy5zcGVjaWFsVG9vbHNcIlxuICAgICAgcFJpcHBsZVxuICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgIFt0ZXh0XT1cInRydWVcIlxuICAgICAgYXJpYUxhYmVsPVwiQ2hhbm5lbHMgJmFtcDsgSGlzdG9ncmFtXCJcbiAgICAgIHBUb29sdGlwPVwiQ2hhbm5lbHMgJmFtcDsgSGlzdG9ncmFtIChicmlnaHRuZXNzL2NvbnRyYXN0LCBjb2xvcm1hcClcIlxuICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgIChvbkNsaWNrKT1cIm9wZW5DaGFubmVsSGlzdG9ncmFtLmVtaXQoKVwiXG4gICAgPlxuICAgICAgPGltZyBzcmM9XCJhc3NldHMvcGxvdHRpbmcvaW52ZXJ0LnN2Z1wiIGNsYXNzPVwidG9vbGJhci1pY29uLWRhcmtcIiBzdHlsZT1cIndpZHRoOiAxcmVtXCIgLz5cbiAgICA8L3AtYnV0dG9uPlxuXG4gICAgPCEtLSBTcGF0aWFsLW9taWNzIGNvbnRyb2xzLiBPbmx5IG1lYW5pbmdmdWwgaW4gdGhlIHNwYXRpYWwgbW9kZSwgd2hpY2ggaXNcbiAgICAgICAgIGl0c2VsZiBvbmx5IG9mZmVyZWQgd2hpbGUgYSBkYXRhc2V0IGlzIGxvYWRlZCDigJQgc28gdGhpcyBidXR0b24gYXBwZWFyc1xuICAgICAgICAgZXhhY3RseSB3aGVuIHRoZXJlIGlzIHNvbWV0aGluZyBmb3IgaXQgdG8gY29udHJvbC4gLS0+XG4gICAgPHAtYnV0dG9uXG4gICAgICAqbmdJZj1cInRvb2xzLnNwZWNpYWxUb29scyAmJiBpc1NwYXRpYWxNb2RlXCJcbiAgICAgIHBSaXBwbGVcbiAgICAgIHNpemU9XCJzbWFsbFwiXG4gICAgICBbdGV4dF09XCJ0cnVlXCJcbiAgICAgIGFyaWFMYWJlbD1cIlNwYXRpYWwgb21pY3MgY29udHJvbHNcIlxuICAgICAgcFRvb2x0aXA9XCJTcGF0aWFsIG9taWNzIChjb2xvdXIgYnkgY29sdW1uIG9yIGdlbmUsIGxlZ2VuZCwgc2VsZWN0aW9uLCBkaXN0cmlidXRpb25zKVwiXG4gICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgICAgKG9uQ2xpY2spPVwib3BlblNwYXRpYWxDb250cm9scy5lbWl0KClcIlxuICAgID5cbiAgICAgIDxpbWcgc3JjPVwiYXNzZXRzL3Bsb3R0aW5nL3NwYXRpYWwtb21pY3Muc3ZnXCIgY2xhc3M9XCJ0b29sYmFyLWljb24tZGFya1wiIHN0eWxlPVwid2lkdGg6IDFyZW1cIiAvPlxuICAgIDwvcC1idXR0b24+XG5cbiAgICA8IS0tIFNtb290aGVuIHRvZ2dsZTogYmlsaW5lYXIgc21vb3RoaW5nIHZzIG5lYXJlc3QtbmVpZ2hib3VyIHJhdyBwaXhlbHMgKEltYWdlXG4gICAgICAgICB2aWV3IG9ubHkg4oCUIGl0J3MgYW4gT3BlblNlYWRyYWdvbiBkcmF3ZXIgc2V0dGluZykuIEhpZ2hsaWdodGVkIHdoZW4gc21vb3RoaW5nIG9uLiAtLT5cbiAgICA8cC1idXR0b25cbiAgICAgICpuZ0lmPVwidG9vbHMuc3BlY2lhbFRvb2xzICYmIGlzSW1hZ2VWaWV3XCJcbiAgICAgIHNpemU9XCJzbWFsbFwiXG4gICAgICBbdGV4dF09XCIhaW1hZ2VTbW9vdGhpbmdFbmFibGVkXCJcbiAgICAgIGFyaWFMYWJlbD1cIlNtb290aGVuXCJcbiAgICAgIHBUb29sdGlwPVwiU21vb3RoZW4gKHR1cm4gb24gaW1hZ2Ugc21vb3RoaW5nKVwiXG4gICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgICAgKG9uQ2xpY2spPVwidG9nZ2xlSW1hZ2VTbW9vdGhpbmcuZW1pdCgpXCJcbiAgICA+XG4gICAgICA8aW1nXG4gICAgICAgIHNyYz1cImFzc2V0cy9wbG90dGluZy9zbW9vdGguc3ZnXCJcbiAgICAgICAgc3R5bGU9XCJ3aWR0aDogMXJlbVwiXG4gICAgICAgIFtjbGFzc109XCJpbWFnZVNtb290aGluZ0VuYWJsZWQgPyAndG9vbGJhci1pY29uLWFjdGl2ZScgOiAndG9vbGJhci1pY29uLWRhcmsnXCJcbiAgICAgIC8+XG4gICAgPC9wLWJ1dHRvbj5cblxuICAgIDwhLS0gU3RhY2sgY29udHJvbHMgLS0+XG4gICAgPHRvb2xiYXItc3RhY2stY29udHJvbHNcbiAgICAgICpuZ0lmPVwiaW1hZ2VJbmZvPy5pc1N0YWNrXCJcbiAgICAgIFtsaXZlU2NydWJiZXJdPVwic2hvd3NMaXZlU2xpY2VTY3J1YmJlclwiXG4gICAgICBbc3RhY2tUb2dnbGVdPVwiIXNob3dzTGl2ZVNsaWNlU2NydWJiZXIgJiYgIWlzTmFwYXJpTW9kZSAmJiAhaXNTcGF0aWFsTW9kZVwiXG4gICAgICBbc2hvd1N0YWNrXT1cIiEhaW1hZ2VJbmZvPy5zaG93U3RhY2tcIlxuICAgICAgW3N0YWNrT3B0aW9uc109XCJzdGFja09wdGlvbnNcIlxuICAgICAgW3pJbmRleF09XCJ6SW5kZXhcIlxuICAgICAgW21heEluZGV4XT1cIm1heEluZGV4XCJcbiAgICAgICh6U2NydWIpPVwielNjcnViLmVtaXQoJGV2ZW50KVwiXG4gICAgICAoelNsaWRlKT1cInpTbGlkZS5lbWl0KCRldmVudClcIlxuICAgICAgKHNlbGVjdFN0YWNrT3B0aW9uKT1cInNlbGVjdFN0YWNrT3B0aW9uLmVtaXQoJGV2ZW50KVwiXG4gICAgICAoekluZGV4SW5wdXQpPVwiekluZGV4SW5wdXQuZW1pdCgkZXZlbnQpXCJcbiAgICAgIChyZWxvYWRBbmRQbG90KT1cInJlbG9hZEFuZFBsb3QuZW1pdCgpXCJcbiAgICA+XG4gICAgPC90b29sYmFyLXN0YWNrLWNvbnRyb2xzPlxuXG4gICAgPCEtLSBJbWFnZSBhY3Rpb25zIChzcGVjaWFsIHRvb2xzKSAtLT5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwidG9vbHMuc3BlY2lhbFRvb2xzXCI+XG4gICAgICA8c3BhbiBjbGFzcz1cInRvb2xiYXItc2VwYXJhdG9yXCI+PC9zcGFuPlxuICAgICAgPHAtYnV0dG9uXG4gICAgICAgIGljb249XCJwaSBwaS1kb3dubG9hZFwiXG4gICAgICAgIHNpemU9XCJzbWFsbFwiXG4gICAgICAgIFt0ZXh0XT1cInRydWVcIlxuICAgICAgICBhcmlhTGFiZWw9XCJEb3dubG9hZCBpbWFnZSBhcyBQTkdcIlxuICAgICAgICBwVG9vbHRpcD1cIkRvd25sb2FkIGltYWdlIGFzIFBOR1wiXG4gICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgICAgIChvbkNsaWNrKT1cImRvd25sb2FkSW1hZ2UuZW1pdCgpXCJcbiAgICAgID5cbiAgICAgIDwvcC1idXR0b24+XG4gICAgICA8cC1idXR0b25cbiAgICAgICAgKm5nSWY9XCJpc0hlYXRtYXBcIlxuICAgICAgICBpY29uPVwicGkgcGktd2luZG93LW1heGltaXplXCJcbiAgICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgICAgW3RleHRdPVwidHJ1ZVwiXG4gICAgICAgIGFyaWFMYWJlbD1cIkZpdCB0byB2aWV3XCJcbiAgICAgICAgcFRvb2x0aXA9XCJGaXQgdG8gdmlld1wiXG4gICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgICAgIChvbkNsaWNrKT1cImF1dG9zY2FsZUltYWdlLmVtaXQoKVwiXG4gICAgICA+XG4gICAgICA8L3AtYnV0dG9uPlxuICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgPHRvb2xiYXItdmlldy1jb250cm9sc1xuICAgICAgW2lzSGVhdG1hcF09XCJpc0hlYXRtYXBcIlxuICAgICAgW3pvb21Ub29sc109XCJ0b29scy56b29tVG9vbHNcIlxuICAgICAgW2lzSW1hZ2VWaWV3XT1cImlzSW1hZ2VWaWV3XCJcbiAgICAgIFthY3RpdmVEcmFnTW9kZV09XCJhY3RpdmVEcmFnTW9kZVwiXG4gICAgICBbYWN0aXZlU3VyZmFjZTNkTW9kZV09XCJhY3RpdmVTdXJmYWNlM2RNb2RlXCJcbiAgICAgIFtheGVzVG9nZ2xlXT1cInNob3dzQXhlc1RvZ2dsZVwiXG4gICAgICBbaXNOYXBhcmlTdXJmYWNlTW9kZV09XCJpc05hcGFyaVN1cmZhY2VNb2RlXCJcbiAgICAgIFtpc05hcGFyaTNkTW9kZV09XCJpc05hcGFyaTNkTW9kZVwiXG4gICAgICBbYXhlc1Zpc2libGVdPVwiYXhlc1Zpc2libGVcIlxuICAgICAgW3dpcmVmcmFtZUFjdGl2ZV09XCJ3aXJlZnJhbWVBY3RpdmVcIlxuICAgICAgW3Jlc29sdXRpb25TY2FsZV09XCJyZXNvbHV0aW9uU2NhbGVcIlxuICAgICAgKHRvZ2dsZURyYWdNb2RlKT1cInRvZ2dsZURyYWdNb2RlLmVtaXQoJGV2ZW50KVwiXG4gICAgICAoem9vbUluKT1cInpvb21Jbi5lbWl0KClcIlxuICAgICAgKHpvb21PdXQpPVwiem9vbU91dC5lbWl0KClcIlxuICAgICAgKHRvZ2dsZVN1cmZhY2UzZE1vZGUpPVwidG9nZ2xlU3VyZmFjZTNkTW9kZS5lbWl0KCRldmVudClcIlxuICAgICAgKHJlc2V0U3VyZmFjZUNhbWVyYSk9XCJyZXNldFN1cmZhY2VDYW1lcmEuZW1pdCgpXCJcbiAgICAgICh0b2dnbGVBeGVzKT1cInRvZ2dsZUF4ZXMuZW1pdCgpXCJcbiAgICAgICh0b2dnbGVXaXJlZnJhbWUpPVwidG9nZ2xlV2lyZWZyYW1lLmVtaXQoKVwiXG4gICAgICAoc2VsZWN0UmVzb2x1dGlvbik9XCJzZWxlY3RSZXNvbHV0aW9uLmVtaXQoJGV2ZW50KVwiXG4gICAgPlxuICAgIDwvdG9vbGJhci12aWV3LWNvbnRyb2xzPlxuXG4gICAgPCEtLSBBIHZvbHVtZSB2aWV3IGRyYXdzIG5vIHJlZ2lvbnM7IHRoZSBSZWdpb24gRWRpdG9yIHNob3dzIHRoZW0gaW4gaXQgaW4gM0QsIGFuZCB0aGVcbiAgICAgICAgIHNlbGVjdGlvbiB0b29sIHBpY2tzIHRoZWlyIHN1cmZhY2VzIHRoZXJlLiBUaGUgc2xpY2UgZWRpdG9yIHNwbGl0cyB0aGUgdmlldzogdGhlIHNsaWNlLFxuICAgICAgICAgd2l0aCBldmVyeSByZWdpb24gdG9vbCwgYmVzaWRlIHRoZSAzRCB2aWV3LiAtLT5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNWb2x1bWVWaWV3ICYmICFpc0hlYXRtYXAgJiYgIWlzM2RSZWdpb25zICYmIHRvb2xzLnJlZ2lvblRvb2xzXCI+XG4gICAgICA8c3BhbiBjbGFzcz1cInRvb2xiYXItc2VwYXJhdG9yXCI+PC9zcGFuPlxuICAgICAgPHAtYnV0dG9uXG4gICAgICAgIHNpemU9XCJzbWFsbFwiXG4gICAgICAgIFt0ZXh0XT1cIiFzbGljZUVkaXRvclwiXG4gICAgICAgIGFyaWFMYWJlbD1cIlNsaWNlIGVkaXRvclwiXG4gICAgICAgIFthdHRyLmFyaWEtcHJlc3NlZF09XCJzbGljZUVkaXRvclwiXG4gICAgICAgIFtwVG9vbHRpcF09XCJcbiAgICAgICAgICBzbGljZUVkaXRvclxuICAgICAgICAgICAgPyAnQ2xvc2UgdGhlIHNsaWNlIGVkaXRvcidcbiAgICAgICAgICAgIDogJ1NsaWNlIGVkaXRvcjogdGhlIHNsaWNlIGFuZCB0aGUgc2VjdGlvbnMgdGhyb3VnaCB4IGFuZCB5IGJlc2lkZSB0aGUgM0QgdmlldydcbiAgICAgICAgXCJcbiAgICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgICAgKG9uQ2xpY2spPVwidG9nZ2xlU2xpY2VFZGl0b3IuZW1pdCgpXCJcbiAgICAgID5cbiAgICAgICAgPGltZ1xuICAgICAgICAgIHNyYz1cImFzc2V0cy9wbG90dGluZy9zbGljZS5zdmdcIlxuICAgICAgICAgIHN0eWxlPVwid2lkdGg6IDFyZW1cIlxuICAgICAgICAgIGFsdD1cIlwiXG4gICAgICAgICAgW2NsYXNzXT1cInNsaWNlRWRpdG9yID8gJ3Rvb2xiYXItaWNvbi1hY3RpdmUnIDogJ3Rvb2xiYXItaWNvbi1kYXJrJ1wiXG4gICAgICAgIC8+XG4gICAgICA8L3AtYnV0dG9uPlxuICAgICAgPHRvb2xiYXItcmVnaW9uLXRvb2xzXG4gICAgICAgICpuZ0lmPVwiIXNsaWNlRWRpdG9yXCJcbiAgICAgICAgW2FjdGl2ZURyYWdNb2RlXT1cImFjdGl2ZURyYWdNb2RlXCJcbiAgICAgICAgW3NlbGVjdE9ubHldPVwidHJ1ZVwiXG4gICAgICAgIFtjYW5VbmRvXT1cImNhblVuZG9cIlxuICAgICAgICBbY2FuUmVkb109XCJjYW5SZWRvXCJcbiAgICAgICAgKG9wZW5SZWdpb25FZGl0b3IpPVwib3BlblJlZ2lvbkVkaXRvci5lbWl0KClcIlxuICAgICAgICAodG9nZ2xlRHJhZ01vZGUpPVwidG9nZ2xlRHJhZ01vZGUuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgKHVuZG9SZWdpb24pPVwidW5kb1JlZ2lvbi5lbWl0KClcIlxuICAgICAgICAocmVkb1JlZ2lvbik9XCJyZWRvUmVnaW9uLmVtaXQoKVwiXG4gICAgICAgIChkZWxldGVSZWdpb24pPVwiZGVsZXRlUmVnaW9uLmVtaXQoKVwiXG4gICAgICA+XG4gICAgICA8L3Rvb2xiYXItcmVnaW9uLXRvb2xzPlxuICAgIDwvbmctY29udGFpbmVyPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIoaXNIZWF0bWFwIHx8IGlzM2RSZWdpb25zIHx8IChpc1ZvbHVtZVZpZXcgJiYgc2xpY2VFZGl0b3IpKSAmJiB0b29scy5yZWdpb25Ub29sc1wiPlxuICAgICAgPHRvb2xiYXItcmVnaW9uLXRvb2xzXG4gICAgICAgIFthY3RpdmVEcmFnTW9kZV09XCJhY3RpdmVEcmFnTW9kZVwiXG4gICAgICAgIFtpczNkUmVnaW9uc109XCJpczNkUmVnaW9uc1wiXG4gICAgICAgIFt2ZXJ0ZXhUb29sc109XCJzdXBwb3J0c1JlZ2lvblZlcnRleFRvb2xzIHx8IChpc1ZvbHVtZVZpZXcgJiYgc2xpY2VFZGl0b3IpXCJcbiAgICAgICAgW3dhbmRTZW5zaXRpdml0eV09XCJ3YW5kU2Vuc2l0aXZpdHlcIlxuICAgICAgICBbYnJ1c2hTaXplXT1cImJydXNoU2l6ZVwiXG4gICAgICAgIFt2ZXJ0ZXhFcmFzZXJSYWRpdXNdPVwidmVydGV4RXJhc2VyUmFkaXVzXCJcbiAgICAgICAgW2NhblVuZG9dPVwiY2FuVW5kb1wiXG4gICAgICAgIFtjYW5SZWRvXT1cImNhblJlZG9cIlxuICAgICAgICAob3BlblJlZ2lvbkVkaXRvcik9XCJvcGVuUmVnaW9uRWRpdG9yLmVtaXQoKVwiXG4gICAgICAgICh0b2dnbGVEcmFnTW9kZSk9XCJ0b2dnbGVEcmFnTW9kZS5lbWl0KCRldmVudClcIlxuICAgICAgICAodW5kb1JlZ2lvbik9XCJ1bmRvUmVnaW9uLmVtaXQoKVwiXG4gICAgICAgIChyZWRvUmVnaW9uKT1cInJlZG9SZWdpb24uZW1pdCgpXCJcbiAgICAgICAgKGRlbGV0ZVJlZ2lvbik9XCJkZWxldGVSZWdpb24uZW1pdCgpXCJcbiAgICAgICAgKHdhbmRTZW5zaXRpdml0eUNoYW5nZSk9XCJ3YW5kU2Vuc2l0aXZpdHlDaGFuZ2UuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgKGJydXNoU2l6ZUNoYW5nZSk9XCJicnVzaFNpemVDaGFuZ2UuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgKHZlcnRleEVyYXNlclJhZGl1c0NoYW5nZSk9XCJ2ZXJ0ZXhFcmFzZXJSYWRpdXNDaGFuZ2UuZW1pdCgkZXZlbnQpXCJcbiAgICAgID5cbiAgICAgIDwvdG9vbGJhci1yZWdpb24tdG9vbHM+XG4gICAgICA8dG9vbGJhci1zZWdtZW50YXRpb24tdG9vbHNcbiAgICAgICAgW2FjdGl2ZURyYWdNb2RlXT1cImFjdGl2ZURyYWdNb2RlXCJcbiAgICAgICAgW3NhbU1vZGVsc109XCJzYW1Nb2RlbHNcIlxuICAgICAgICBbc2FtTW9kZWxJZF09XCJzYW1Nb2RlbElkXCJcbiAgICAgICAgW2NvbnRyaWJ1dGVkVG9vbHNdPVwiY29udHJpYnV0ZWRUb29sc1wiXG4gICAgICAgIFt0b29sTW9kZWxJZHNdPVwidG9vbE1vZGVsSWRzXCJcbiAgICAgICAgKHNlZ21lbnRSZWdpb25zKT1cInNlZ21lbnRSZWdpb25zLmVtaXQoKVwiXG4gICAgICAgIChzZWdtZW50Q2VsbHBvc2UpPVwic2VnbWVudENlbGxwb3NlLmVtaXQoKVwiXG4gICAgICAgICh0b2dnbGVEcmFnTW9kZSk9XCJ0b2dnbGVEcmFnTW9kZS5lbWl0KCRldmVudClcIlxuICAgICAgICAoc2FtTW9kZWxDaGFuZ2UpPVwic2FtTW9kZWxDaGFuZ2UuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgKHJ1blRvb2wpPVwicnVuVG9vbC5lbWl0KCRldmVudClcIlxuICAgICAgICAodG9vbE1vZGVsQ2hhbmdlKT1cInRvb2xNb2RlbENoYW5nZS5lbWl0KCRldmVudClcIlxuICAgICAgICAob3BlblRvb2xQYXJhbXMpPVwib3BlblRvb2xQYXJhbXMuZW1pdCgkZXZlbnQpXCJcbiAgICAgID5cbiAgICAgIDwvdG9vbGJhci1zZWdtZW50YXRpb24tdG9vbHM+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwidG9vbHMuaGVscFwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJ0b29sYmFyLXNlcGFyYXRvclwiPjwvc3Bhbj5cblxuICAgICAgPCEtLSBIZWxwIC0tPlxuICAgICAgPHAtYnV0dG9uXG4gICAgICAgIGljb249XCJwaSBwaS1xdWVzdGlvbi1jaXJjbGVcIlxuICAgICAgICBzaXplPVwic21hbGxcIlxuICAgICAgICBbdGV4dF09XCJ0cnVlXCJcbiAgICAgICAgYXJpYUxhYmVsPVwiSGVscFwiXG4gICAgICAgIHBUb29sdGlwPVwiSGVscFwiXG4gICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgICAgIChvbkNsaWNrKT1cInNob3dIZWxwKClcIlxuICAgICAgPlxuICAgICAgPC9wLWJ1dHRvbj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9kaXY+XG48L3AtdG9vbGJhcj5cbjx0b29sYmFyLWhlbHAtZGlhbG9nXG4gIFsodmlzaWJsZSldPVwiZGlzcGxheUhlbHBEaWFsb2dcIlxuICBbY29udHJpYnV0ZWRUb29sc109XCJjb250cmlidXRlZFRvb2xzXCJcbiAgW2RpYWxvZ1Rvb2xzXT1cImRpYWxvZ1Rvb2xzXCJcbj5cbjwvdG9vbGJhci1oZWxwLWRpYWxvZz5cbiJdfQ==
435
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbGJhci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3Rvb2xiYXIvdG9vbGJhci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9zcmMvbGliL3Rvb2xiYXIvdG9vbGJhci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2hHLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFHaEQsT0FBTyxFQUNMLFFBQVEsRUFFUixpQkFBaUIsRUFDakIsVUFBVSxFQUNWLGtCQUFrQixFQUNsQixlQUFlLEVBQ2YsZUFBZSxFQUNmLGNBQWMsRUFDZCx1QkFBdUIsRUFDdkIsY0FBYyxFQUNkLGdCQUFnQixHQUNqQixNQUFNLHdCQUF3QixDQUFDO0FBQ2hDLE9BQU8sRUFBeUIsaUJBQWlCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUd2RixPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxxREFBcUQsQ0FBQztBQUNqRyxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxtREFBbUQsQ0FBQztBQUM5RixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUNuRixPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUNoRixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx1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QWhCLE1BQU07Z0JBRUcsZ0JBQWdCO3NCQUF6QixNQUFNO2dCQUVHLGVBQWU7c0JBQXhCLE1BQU07Z0JBRUcsY0FBYztzQkFBdkIsTUFBTTtnQkFFRyxjQUFjO3NCQUF2QixNQUFNO2dCQUVHLHFCQUFxQjtzQkFBOUIsTUFBTTtnQkFFRyxlQUFlO3NCQUF4QixNQUFNO2dCQUVHLHdCQUF3QjtzQkFBakMsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEJ1dHRvbk1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvYnV0dG9uJztcbmltcG9ydCB7IFJpcHBsZU1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvcmlwcGxlJztcbmltcG9ydCB7IFRvb2xiYXJNb2R1bGUgfSBmcm9tICdwcmltZW5nL3Rvb2xiYXInO1xuaW1wb3J0IHsgVG9vbHRpcE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvdG9vbHRpcCc7XG5cbmltcG9ydCB7IElJbWFnZUluZm8gfSBmcm9tICcuLi9jb250cmFjdHMvaW1hZ2UuY29udHJhY3QnO1xuaW1wb3J0IHtcbiAgUGxvdFR5cGUsXG4gIFBsb3RUeXBlSWQsXG4gIGlzQnVpbHRpblBsb3RUeXBlLFxuICBpc05hcGFyaTNkLFxuICBpc05hcGFyaUlzb3N1cmZhY2UsXG4gIGlzTmFwYXJpU3VyZmFjZSxcbiAgaXNOYXBhcmlTY2F0dGVyLFxuICBpc05hcGFyaVZvbHVtZSxcbiAgTkFQQVJJX0RFRkFVTFRfREVDSU1BVEUsXG4gIGlzU3BhdGlhbE9taWNzLFxuICBpc1NwYXRpYWxPbWljczNkLFxufSBmcm9tICcuLi9jb250cmFjdHMvcGxvdC10eXBlJztcbmltcG9ydCB7IFRvb2xiYXJUb29sVmlzaWJpbGl0eSwgQUxMX1RPT0xCQVJfVE9PTFMgfSBmcm9tICcuLi9jb250cmFjdHMvdG9vbGJhci1jb25maWcnO1xuaW1wb3J0IHsgVG9vbGJhckRpYWxvZ1Rvb2xDb250cmlidXRpb24sIFRvb2xiYXJUb29sQ29udHJpYnV0aW9uIH0gZnJvbSAnLi4vY29udHJhY3RzL3Rvb2xiYXItdG9vbC5jb250cmFjdCc7XG5pbXBvcnQgeyBQbG90VHlwZU9wdGlvbiB9IGZyb20gJy4uL2NvbnRyYWN0cy9wbG90LXR5cGUtY29udHJpYnV0aW9uLmNvbnRyYWN0JztcbmltcG9ydCB7IFRvb2xiYXJIZWxwRGlhbG9nQ29tcG9uZW50IH0gZnJvbSAnLi90b29sYmFyLWhlbHAtZGlhbG9nL3Rvb2xiYXItaGVscC1kaWFsb2cuY29tcG9uZW50JztcbmltcG9ydCB7IFBsb3RUeXBlU2VsZWN0b3JDb21wb25lbnQgfSBmcm9tICcuL3Bsb3QtdHlwZS1zZWxlY3Rvci9wbG90LXR5cGUtc2VsZWN0b3IuY29tcG9uZW50JztcbmltcG9ydCB7IFN0YWNrQ29udHJvbHNDb21wb25lbnQgfSBmcm9tICcuL3N0YWNrLWNvbnRyb2xzL3N0YWNrLWNvbnRyb2xzLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBWaWV3Q29udHJvbHNDb21wb25lbnQgfSBmcm9tICcuL3ZpZXctY29udHJvbHMvdmlldy1jb250cm9scy5jb21wb25lbnQnO1xuaW1wb3J0IHsgUmVnaW9uVG9vbHNDb21wb25lbnQgfSBmcm9tICcuL3JlZ2lvbi10b29scy9yZWdpb24tdG9vbHMuY29tcG9uZW50JztcbmltcG9ydCB7IFNlZ21lbnRhdGlvblRvb2xzQ29tcG9uZW50IH0gZnJvbSAnLi9zZWdtZW50YXRpb24tdG9vbHMvc2VnbWVudGF0aW9uLXRvb2xzLmNvbXBvbmVudCc7XG5cbi8qKlxuICogUHJlc2VudGF0aW9uYWwgdG9vbGJhciBmb3IgdGhlIHBsb3R0aW5nIHZpZXdwb3J0LlxuICpcbiAqIFJlbmRlcnMgdGhlIHBsb3QtdHlwZSBzZWxlY3RvciwgY29sb3JtYXAvTFVUIGNvbnRyb2xzLCBzdGFjayBuYXZpZ2F0aW9uLFxuICogaW1hZ2UgYWN0aW9ucyAoZG93bmxvYWQgLyBhdXRvc2NhbGUgLyBwaXBlbGluZSksIHZpZXdwb3J0IHpvb20vcGFuLCB0aGVcbiAqIFN1cmZhY2UtM0QgY2FtZXJhIGNvbnRyb2xzLCBhbmQgdGhlIHJlZ2lvbi1kcmF3aW5nIHRvb2xzIOKAlCBwbHVzIHRoZSBwbG90dGluZ1xuICogaGVscCBkaWFsb2cuIEl0IG93bnMgbm8gcmVuZGVyaW5nIG9yIHZpc3VhbGl6YXRpb24gc3RhdGU6IHRoZSBob3N0XG4gKiAoVmlzdWFsaXplckNvbXBvbmVudCkgc3RheXMgdGhlIG9yY2hlc3RyYXRvciwgcGFzc2luZyBzdGF0ZSBpbiB2aWEgYEBJbnB1dGAgYW5kXG4gKiBoYW5kbGluZyBldmVyeSBhY3Rpb24gdmlhIGBAT3V0cHV0YC4gVGhlIHNhbWUgYWN0aW9ucyBhcmUgYWxzbyBkcml2ZW4gYnkgdGhlXG4gKiBkaWFncmFtJ3MgcmlnaHQtY2xpY2sgY29udGV4dCBtZW51IGFuZCBrZXlib2FyZCBzaG9ydGN1dHMsIHNvIGtlZXBpbmcgdGhlXG4gKiBoYW5kbGVycyBpbiB0aGUgaG9zdCBhdm9pZHMgZHVwbGljYXRpbmcgdGhhdCBsb2dpYy5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAncGxvdHRpbmctdG9vbGJhcicsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGUsXG4gICAgQnV0dG9uTW9kdWxlLFxuICAgIFJpcHBsZU1vZHVsZSxcbiAgICBUb29sYmFyTW9kdWxlLFxuICAgIFRvb2x0aXBNb2R1bGUsXG4gICAgVG9vbGJhckhlbHBEaWFsb2dDb21wb25lbnQsXG4gICAgUGxvdFR5cGVTZWxlY3RvckNvbXBvbmVudCxcbiAgICBTdGFja0NvbnRyb2xzQ29tcG9uZW50LFxuICAgIFZpZXdDb250cm9sc0NvbXBvbmVudCxcbiAgICBSZWdpb25Ub29sc0NvbXBvbmVudCxcbiAgICBTZWdtZW50YXRpb25Ub29sc0NvbXBvbmVudCxcbiAgXSxcbiAgdGVtcGxhdGVVcmw6ICcuL3Rvb2xiYXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi90b29sYmFyLmNvbXBvbmVudC5zY3NzJ10sXG4gIC8vIFB1cmVseSBASW5wdXQvQE91dHB1dDogcmUtY2hlY2sgb25seSB3aGVuIGFuIGlucHV0IGNoYW5nZXMgb3IgdGhlIHRvb2xiYXJcbiAgLy8gaXRzZWxmIGhhbmRsZXMgYW4gZXZlbnQsIG5vdCBvbiBldmVyeSBhcHAgdGljayAoaXRzIH4xNSBnZXR0ZXJzIHJhbiBlYWNoXG4gIC8vIHRpbWUpLiBDb250cm9scyBiaW5kIFtuZ01vZGVsXSBvbmUtd2F5IGFuZCByZXBvcnQgdGhyb3VnaCB0aGUgb3V0cHV0cywgc29cbiAgLy8gdGhlIGhvc3Qgc3RheXMgdGhlIG93bmVyIG9mIGV2ZXJ5IHZhbHVlIChSVC0zNSkuXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBUb29sYmFyQ29tcG9uZW50IHtcbiAgLyoqIEN1cnJlbnQgaW1hZ2UgKGdhdGVzIHdoaWNoIGNvbnRyb2wgZ3JvdXBzIGFyZSBzaG93bikuICovXG4gIEBJbnB1dCgpIGltYWdlSW5mbzogSUltYWdlSW5mbyB8IHVuZGVmaW5lZDtcbiAgLyoqIEEgc3BhdGlhbCBkYXRhc2V0IGlzIG9uIG9mZmVyOiBpdHMgcGxvdCBtb2RlcyBhcmUgYSBjaG9pY2UgZXZlbiB3aXRoIG5vIGltYWdlIGxvYWRlZC4gKi9cbiAgQElucHV0KCkgaGFzU3BhdGlhbERhdGFzZXQgPSBmYWxzZTtcblxuICAvKiogV2hldGhlciB0aGUgcGxvdC10eXBlIGRyb3Bkb3duIHNob3dzOiBmb3IgYW4gaW1hZ2UsIG9yIGEgc3BhdGlhbCBkYXRhc2V0IHdpdGggbm9uZS4gKi9cbiAgcHJvdGVjdGVkIGdldCBzaG93UGxvdFR5cGVzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhISh0aGlzLmltYWdlSW5mbyB8fCB0aGlzLmhhc1NwYXRpYWxEYXRhc2V0KSAmJiAhIXRoaXMudG9vbHMuc3BlY2lhbFRvb2xzO1xuICB9XG4gIC8qKiBQbG90IHR5cGVzIHRoZSBhY3RpdmUgYmFja2VuZCBhZHZlcnRpc2VzLCB0aGVuIGFueSBjb250cmlidXRlZCBtb2Rlcy4gKi9cbiAgQElucHV0KCkgcGxvdFR5cGVPcHRpb25zOiBQbG90VHlwZU9wdGlvbltdID0gW107XG4gIC8qKiBUaGUgc2VsZWN0b3IncyB2YWx1ZTogYSBidWlsdC1pbiB0eXBlIG9yIGEgY29udHJpYnV0ZWQgbW9kZSdzIGlkLiAqL1xuICBASW5wdXQoKSBzZWxlY3RlZFBsb3RUeXBlOiBQbG90VHlwZUlkID0gUGxvdFR5cGUuSU1BR0U7XG4gIC8qKlxuICAgKiBUaGUgYnVpbHQtaW4gdHlwZSB0aGF0IHJlbmRlcnMge0BsaW5rIHNlbGVjdGVkUGxvdFR5cGV9IOKAlCBpdHMgYGJhc2VUeXBlYFxuICAgKiBmb3IgYSBjb250cmlidXRlZCBtb2RlLiBFdmVyeSB0b29sL2NvbnRyb2wgZGVjaXNpb24gYmVsb3cgcmVhZHNcbiAgICoge0BsaW5rIGVmZmVjdGl2ZVBsb3RUeXBlfSwgc28gYSBjb250cmlidXRlZCBtb2RlIGdldHMgZXhhY3RseSBpdHMgYmFzZVxuICAgKiB0eXBlJ3MgdG9vbGJhci4gV2hlbiB1bmJvdW5kLCBhIGJ1aWx0LWluIHNlbGVjdGlvbiBpcyBpdHMgb3duIGJhc2UgYW5kXG4gICAqIGFueXRoaW5nIGVsc2UgaXMgdHJlYXRlZCBhcyB0aGUgZGVmYXVsdCBJbWFnZSB2aWV3LlxuICAgKi9cbiAgQElucHV0KCkgYmFzZVBsb3RUeXBlOiBQbG90VHlwZSB8IG51bGwgPSBudWxsO1xuICAvKiogSXNvc3VyZmFjZSBiYW5kIGFzIGEgMOKAkzI1NSBzbGlkZXIgcG9zaXRpb24gKG1hcHBlZCBvbnRvIHRoZSB2b2x1bWUncyByZWFsXG4gICAqICBpbnRlbnNpdHkgcmFuZ2UgYnkgdGhlIHJlbmRlcmVyKS4gRGVmYXVsdHMgdG8gdGhlIGZ1bGwgcmFuZ2UuICovXG4gIEBJbnB1dCgpIGlzb1JhbmdlOiBudW1iZXJbXSA9IFswLCAyNTVdO1xuICAvKiogVGhlIGxhc3Qgc2xpY2UgaW5kZXggb2YgYSBzdGFjay4gKi9cbiAgQElucHV0KCkgbWF4SW5kZXggPSAwO1xuICAvKipcbiAgICogVGhlIGltYWdlIGlzIG9uZSBwbGFuZSwgYnV0IGEgc3BhdGlhbCBkYXRhc2V0J3MgcmVnaW9uIHNldCBzbGljZXMgaXQgaW50byBwbGFuZXM6IHRoZSBsaXZlXG4gICAqIHZpZXdzIG9mZmVyIHRoZSBzbGlkZXIgb3ZlciB0aGVtICh7QGxpbmsgbWF4SW5kZXh9IGlzIHRoZSBsYXN0IHBsYW5lKSwgYXMgb3ZlciBhIHN0YWNrLlxuICAgKi9cbiAgQElucHV0KCkgcGxhbmVTbGljZXMgPSBmYWxzZTtcbiAgLyoqIFRoZSBjdXJyZW50IHNsaWNlICgwLWJhc2VkKS4gKi9cbiAgQElucHV0KCkgekluZGV4ID0gMDtcbiAgLyoqIFRydWUgZm9yIGFueSAyRCAobm9uIFN1cmZhY2UtM0QpIHBsb3QgdHlwZS4gKi9cbiAgQElucHV0KCkgaXNIZWF0bWFwID0gdHJ1ZTtcbiAgLyoqXG4gICAqIFJlZ2lvbiB0b29scyBhcHBseSBldmVuIHRob3VnaCB0aGlzIGlzIGEgM0QgdmlldywgYmVjYXVzZSB0aGV5IGRyYXcgYVxuICAgKiBTQ1JFRU4tU1BBQ0UgbGFzc28gKHRoZSAzRCBzcGF0aWFsIGNsb3VkKS4gU2VwYXJhdGUgZnJvbSB7QGxpbmsgaXNIZWF0bWFwfSxcbiAgICogd2hpY2ggbWVhbnMgXCIyRCB2aWV3XCIgYW5kIGFsc28gZHJpdmVzIHRoZSB6b29tIHRvb2xzIGFuZCB0aGUgM0QgY2FtZXJhXG4gICAqIGNvbnRyb2xzIOKAlCBmbGlwcGluZyB0aGF0IHdvdWxkIHNob3cgMkQgcGFuL3pvb20gYW5kIGhpZGUgdGhlIG9yYml0IGNvbnRyb2xzLlxuICAgKi9cbiAgQElucHV0KCkgaXMzZFJlZ2lvbnMgPSBmYWxzZTtcbiAgLyoqIEEgbmFwYXJpIHZvbHVtZSAvIGlzb3N1cmZhY2UgdmlldzogdGhlIFJlZ2lvbiBFZGl0b3IgKHJlZ2lvbnMgaW4gM0QpIHdpdGhvdXQgZHJhd2luZyB0b29scy4gKi9cbiAgQElucHV0KCkgaXNWb2x1bWVWaWV3ID0gZmFsc2U7XG4gIC8qKiBXaGV0aGVyIHRoZSB2b2x1bWUgdmlldyBpcyBzcGxpdCB3aXRoIHRoZSBzbGljZSBlZGl0b3IgKHRoZSBzbGljZSwgd2l0aCBldmVyeSByZWdpb24gdG9vbCkuICovXG4gIEBJbnB1dCgpIHNsaWNlRWRpdG9yID0gZmFsc2U7XG4gIC8qKiBUaGUgYXJtZWQgdG9vbCdzIG1vZGUgKHpvb20sIHBhbiwgYSBkcmF3aW5nIHRvb2wsIGBzYW1Qb2ludGAsIOKApiksIG9yIG51bGwuICovXG4gIEBJbnB1dCgpIGFjdGl2ZURyYWdNb2RlOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgLyoqIFRoZSAzRCBjYW1lcmEgbW9kZSAoYHR1cm50YWJsZWAgLyBgb3JiaXRgIC8g4oCmKS4gKi9cbiAgQElucHV0KCkgYWN0aXZlU3VyZmFjZTNkTW9kZSA9ICd0dXJudGFibGUnO1xuICAvKiogV2hldGhlciB0aGUgbmFwYXJpIDNEIGF4ZXMvc2NhbGUgZ2l6bW8gaXMgY3VycmVudGx5IHNob3duIChkcml2ZXMgdGhlIHRvZ2dsZSdzIGxvb2spLiAqL1xuICBASW5wdXQoKSBheGVzVmlzaWJsZSA9IHRydWU7XG4gIC8qKiBUaGUgbmFwYXJpIHN1cmZhY2Ugd2lyZWZyYW1lIGlzIG9uLiAqL1xuICBASW5wdXQoKSB3aXJlZnJhbWVBY3RpdmUgPSBmYWxzZTtcbiAgLyoqIEFjdGl2ZSBuYXBhcmkgM0QgZGVjaW1hdGUgZmFjdG9yICgxID0gRnVsbCDigKYgOCA9IOKFmzsgZGVmYXVsdCDCvSkuICovXG4gIEBJbnB1dCgpIHJlc29sdXRpb25TY2FsZSA9IE5BUEFSSV9ERUZBVUxUX0RFQ0lNQVRFO1xuICAvKiogTWFnaWMtd2FuZCBzZW5zaXRpdml0eS4gKi9cbiAgQElucHV0KCkgd2FuZFNlbnNpdGl2aXR5ID0gMi4wO1xuICAvKiogQnJ1c2ggZGlhbWV0ZXIgaW4gaW1hZ2UgcGl4ZWxzLiAqL1xuICBASW5wdXQoKSBicnVzaFNpemUgPSA0MDtcbiAgLyoqIFZlcnRleC1lcmFzZXIgcmFkaXVzIGluIGltYWdlIHBpeGVscy4gKi9cbiAgQElucHV0KCkgdmVydGV4RXJhc2VyUmFkaXVzID0gMjA7XG4gIC8qKiBXaGV0aGVyIGEgcmVnaW9uIGFjdGlvbiBpcyBhdmFpbGFibGUgdG8gdW5kbyAoaml0LXVpIzg1KS4gR3JleXMgb3V0IHRoZVxuICAgKiAgVW5kbyBidXR0b24gd2hlbiBmYWxzZSAobm90aGluZyBkb25lIHlldCwgb3IgYWxsIHN0ZXBzIGFscmVhZHkgdW5kb25lKS4gKi9cbiAgQElucHV0KCkgY2FuVW5kbyA9IGZhbHNlO1xuICAvKiogV2hldGhlciBhbiB1bmRvbmUgcmVnaW9uIGFjdGlvbiBpcyBhdmFpbGFibGUgdG8gcmVkbyAoaml0LXVpIzg1KS4gR3JleXNcbiAgICogIG91dCB0aGUgUmVkbyBidXR0b24gd2hlbiBmYWxzZS4gKi9cbiAgQElucHV0KCkgY2FuUmVkbyA9IGZhbHNlO1xuICAvKiogVGhlIHNpbmdsZS1pbWFnZSAvIHN0YWNrIGNob2ljZXMgb2YgdGhlIFBsb3RseSBzdGFjayB0b2dnbGUuICovXG4gIEBJbnB1dCgpIHN0YWNrT3B0aW9uczogeyBuYW1lOiBzdHJpbmc7IHZhbDogc3RyaW5nIH1bXSA9IFtcbiAgICB7IG5hbWU6ICdTaW5nbGUgaW1hZ2UnLCB2YWw6ICdmYWxzZScgfSxcbiAgICB7IG5hbWU6ICdTdGFjaycsIHZhbDogJ3RydWUnIH0sXG4gIF07XG4gIC8qKiBXaGljaCB0b29sYmFyIGdyb3VwcyB0byBzaG93LiBEZWZhdWx0cyB0byB0aGUgZnVsbCB0b29sYmFyOyB0aGUgaG9zdCBmb3J3YXJkc1xuICAgKiAgdGhlIGNvbnN1bWVyJ3MgY2hvaWNlIChlLmcuIHRoZSBwaXBlbGluZSBzaG93cyBvbmx5IHpvb20gKyByZWdpb24gdG9vbHMpLiAqL1xuICBASW5wdXQoKSB0b29sczogUmVxdWlyZWQ8VG9vbGJhclRvb2xWaXNpYmlsaXR5PiA9IEFMTF9UT09MQkFSX1RPT0xTO1xuICAvKiogQ3VycmVudCBpbWFnZS1zbW9vdGhpbmcgc3RhdGUgKGRyaXZlcyB0aGUgU21vb3RoZW4gdG9nZ2xlIGJ1dHRvbiBsb29rKS5cbiAgICogIGBmYWxzZWAgPSBuZWFyZXN0LW5laWdoYm91ciAoY3Jpc3AgcmF3IHBpeGVscyksIHRoZSBkZWZhdWx0LiAqL1xuICBASW5wdXQoKSBpbWFnZVNtb290aGluZ0VuYWJsZWQgPSBmYWxzZTtcbiAgLyoqIFNBTSBtb2RlbCBwaWNrZXIgb3B0aW9ucyArIGN1cnJlbnQgc2VsZWN0aW9uIChqaXQtdWkjOTAgUDEpLiAqL1xuICBASW5wdXQoKSBzYW1Nb2RlbHM6IHsgaWQ6IHN0cmluZzsgbGFiZWw6IHN0cmluZyB9W10gPSBbXTtcbiAgLyoqIFRoZSBzZWxlY3RlZCBTQU0gbW9kZWwgaWQuICovXG4gIEBJbnB1dCgpIHNhbU1vZGVsSWQgPSAnJztcbiAgLyoqXG4gICAqIFRvb2xzIGNvbnRyaWJ1dGVkIHRocm91Z2gge0BsaW5rIFRPT0xCQVJfVE9PTFN9LCBhbHJlYWR5IGZpbHRlcmVkIHRvIHRoZVxuICAgKiBvbmVzIHdpdGggbW9kZWxzIGFuZCBzb3J0ZWQuIFRoZSBob3N0IHJlc29sdmVzIHRoZW0gc28gaXQgY2FuIG93biB0aGVcbiAgICogcGVyLXRvb2wgcGFyYW1ldGVyIHN0YXRlOyB0aGlzIGNvbXBvbmVudCBvbmx5IGRyYXdzIHRoZW0uXG4gICAqL1xuICBASW5wdXQoKSBjb250cmlidXRlZFRvb2xzOiBUb29sYmFyVG9vbENvbnRyaWJ1dGlvbltdID0gW107XG4gIC8qKiBEaWFsb2cgdG9vbHMgKFRPT0xCQVJfVE9PTFMsIGtpbmQ6ICdkaWFsb2cnKSwgc29ydGVkOyBzaG93biBpbiB0aGUgSW1hZ2Ugdmlldy4gKi9cbiAgQElucHV0KCkgZGlhbG9nVG9vbHM6IFRvb2xiYXJEaWFsb2dUb29sQ29udHJpYnV0aW9uW10gPSBbXTtcbiAgLyoqIElkIG9mIHRoZSBkaWFsb2cgdG9vbCB3aG9zZSBkaWFsb2cgaXMgb3Blbiwgb3IgbnVsbC4gKi9cbiAgQElucHV0KCkgb3BlbkRpYWxvZ1Rvb2xJZDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBBY3RpdmUgY2hlY2twb2ludCBwZXIgY29udHJpYnV0ZWQgdG9vbCwga2V5ZWQgYnkgdG9vbCBpZC4gKi9cbiAgQElucHV0KCkgdG9vbE1vZGVsSWRzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG5cbiAgLyoqIEEgcGxvdCB0eXBlIG9yIGNvbnRyaWJ1dGVkIG1vZGUgd2FzIHBpY2tlZC4gKi9cbiAgQE91dHB1dCgpIHNlbGVjdFBsb3RUeXBlID0gbmV3IEV2ZW50RW1pdHRlcjxQbG90VHlwZUlkPigpO1xuICAvKiogSW50ZW5zaXR5IChMSU5FKSBtb2RlOiBhZGQgYW5vdGhlciBjb2xvcmVkIGxpbmUgUk9JICsgaW5zZXQgdHJhY2UuICovXG4gIEBPdXRwdXQoKSBhZGRQcm9maWxlTGluZSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIFRvZ2dsZSBpbWFnZSBzbW9vdGhpbmcgKGJpbGluZWFyKSB2cyBuZWFyZXN0LW5laWdoYm91ciAoY3Jpc3AgcGl4ZWxzKS4gKi9cbiAgQE91dHB1dCgpIHRvZ2dsZUltYWdlU21vb3RoaW5nID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvLyBQcmltZU5HIHNsaWRlci9pbnB1dE51bWJlciBjaGFuZ2UgZXZlbnRzIGNhcnJ5IG9wdGlvbmFsIHZhbHVlcywgbWlycm9yZWQgYnlcbiAgLy8gdGhlIGhvc3QgaGFuZGxlcnMgKHdoaWNoIGFjY2VwdCBgfCB1bmRlZmluZWRgKS5cbiAgLyoqIFRoZSBpc29zdXJmYWNlIGJhbmQgc2xpZGVyIG1vdmVkOiB0aGUgbmV3IGBbbG93LCBoaWdoXWAgcGFpci4gKi9cbiAgQE91dHB1dCgpIGlzb1JhbmdlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXJbXSB8IHVuZGVmaW5lZD4oKTtcbiAgLyoqIE9wZW4gdGhlIENoYW5uZWxzICYgSGlzdG9ncmFtIGRpYWxvZyAoYnJpZ2h0bmVzcy9jb250cmFzdCwgY29sb3JtYXAsIOKApikuICovXG4gIEBPdXRwdXQoKSBvcGVuQ2hhbm5lbEhpc3RvZ3JhbSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIE9wZW4gdGhlIHNwYXRpYWwtb21pY3MgY29udHJvbHMgKGNvbG91ci1ieSwgbGVnZW5kLCBwb2ludCBkaXNwbGF5KS4gKi9cbiAgQE91dHB1dCgpIG9wZW5TcGF0aWFsQ29udHJvbHMgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBPcGVuIHRoZSBSZWdpb24gRWRpdG9yIGRpYWxvZy4gKi9cbiAgQE91dHB1dCgpIG9wZW5SZWdpb25FZGl0b3IgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBTcGxpdCB0aGUgdm9sdW1lIHZpZXcgd2l0aCB0aGUgc2xpY2UgZWRpdG9yLCBvciBjbG9zZSBpdC4gKi9cbiAgQE91dHB1dCgpIHRvZ2dsZVNsaWNlRWRpdG9yID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogQSBzaW5nbGUtaW1hZ2UgLyBzdGFjayBjaG9pY2Ugd2FzIHBpY2tlZC4gKi9cbiAgQE91dHB1dCgpIHNlbGVjdFN0YWNrT3B0aW9uID0gbmV3IEV2ZW50RW1pdHRlcjx7IG5hbWU6IHN0cmluZzsgdmFsOiBzdHJpbmcgfT4oKTtcbiAgLyoqIFRoZSBsaXZlIHNsaWNlIHNjcnViYmVyIG1vdmVkIChmaXJlcyB3aGlsZSBkcmFnZ2luZykuICovXG4gIEBPdXRwdXQoKSB6U2NydWIgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlciB8IHVuZGVmaW5lZD4oKTtcbiAgLyoqIFRoZSBsaXZlIHNsaWNlIHNjcnViYmVyIHdhcyByZWxlYXNlZCBvbiBhIHNsaWNlLiAqL1xuICBAT3V0cHV0KCkgelNsaWRlID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXIgfCB1bmRlZmluZWQ+KCk7XG4gIC8qKiBBIHNsaWNlIG51bWJlciB3YXMgdHlwZWQuICovXG4gIEBPdXRwdXQoKSB6SW5kZXhJbnB1dCA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuICAvKiogUmUtcGxvdCBhdCB0aGUgdHlwZWQgc2xpY2UuICovXG4gIEBPdXRwdXQoKSByZWxvYWRBbmRQbG90ID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogRG93bmxvYWQgdGhlIGN1cnJlbnQgdmlldyBhcyBQTkcuICovXG4gIEBPdXRwdXQoKSBkb3dubG9hZEltYWdlID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogRml0IHRoZSBpbWFnZSB0byB0aGUgdmlldy4gKi9cbiAgQE91dHB1dCgpIGF1dG9zY2FsZUltYWdlID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogQSB6b29tIC8gcGFuIC8gZHJhd2luZyB0b29sIGJ1dHRvbiB3YXMgY2xpY2tlZCAoaXRzIG1vZGUpLiAqL1xuICBAT3V0cHV0KCkgdG9nZ2xlRHJhZ01vZGUgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgLyoqIFpvb20gaW4gb25lIHN0ZXAuICovXG4gIEBPdXRwdXQoKSB6b29tSW4gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBab29tIG91dCBvbmUgc3RlcC4gKi9cbiAgQE91dHB1dCgpIHpvb21PdXQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBBIDNEIGNhbWVyYSBtb2RlIGJ1dHRvbiB3YXMgY2xpY2tlZCAoaXRzIG1vZGUpLiAqL1xuICBAT3V0cHV0KCkgdG9nZ2xlU3VyZmFjZTNkTW9kZSA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICAvKiogUmVzZXQgdGhlIDNEIGNhbWVyYS4gKi9cbiAgQE91dHB1dCgpIHJlc2V0U3VyZmFjZUNhbWVyYSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIFRvZ2dsZSB0aGUgbmFwYXJpIDNEIGNvb3JkaW5hdGUtYXhlcyAvIHNjYWxlIGdpem1vIG9uL29mZi4gKi9cbiAgQE91dHB1dCgpIHRvZ2dsZUF4ZXMgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBUb2dnbGUgdGhlIG5hcGFyaSBzdXJmYWNlIHdpcmVmcmFtZSAoZWRnZXMpIG9uL29mZi4gKi9cbiAgQE91dHB1dCgpIHRvZ2dsZVdpcmVmcmFtZSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIENoYW5nZSB0aGUgbmFwYXJpIDNEIGRlY2ltYXRlIGZhY3RvciAocmVsb2FkcyBhdCB0aGUgbmV3IHJlc29sdXRpb24pLiAqL1xuICBAT3V0cHV0KCkgc2VsZWN0UmVzb2x1dGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuICAvKiogRGVsZXRlIHRoZSBzZWxlY3RlZCByZWdpb24uICovXG4gIEBPdXRwdXQoKSBkZWxldGVSZWdpb24gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBVbmRvIHRoZSBsYXN0IHJlZ2lvbiBhY3Rpb24gKGppdC11aSM4NSkuICovXG4gIEBPdXRwdXQoKSB1bmRvUmVnaW9uID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogUmVkbyB0aGUgbGFzdCB1bmRvbmUgcmVnaW9uIGFjdGlvbiAoaml0LXVpIzg1KS4gKi9cbiAgQE91dHB1dCgpIHJlZG9SZWdpb24gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBSdW4gYm94LXByb21wdGVkIFNBTSBzZWdtZW50YXRpb24gb24gdGhlIGRyYXduIHJlY3RhbmdsZXMgKGppdC11aSM5MCkuICovXG4gIEBPdXRwdXQoKSBzZWdtZW50UmVnaW9ucyA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIFJ1biBjZWxscG9zZS1TQU0gKGF1dG8pIGluc2lkZSBlYWNoIGRyYXduIHJlY3RhbmdsZSdzIGNyb3AgKGppdC11aSM5MCkuICovXG4gIEBPdXRwdXQoKSBzZWdtZW50Q2VsbHBvc2UgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBSdW4gYSBjb250cmlidXRlZCB0b29sIG92ZXIgdGhlIGN1cnJlbnQgdmlldywgYnkgdG9vbCBpZC4gKi9cbiAgQE91dHB1dCgpIHJ1blRvb2wgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgLyoqIEEgZGlhbG9nIHRvb2wncyBidXR0b24gd2FzIGNsaWNrZWQ6IG9wZW4gaXRzIGRpYWxvZywgb3IgY2xvc2UgaXQgaWYgb3Blbi4gKi9cbiAgQE91dHB1dCgpIHRvZ2dsZURpYWxvZ1Rvb2wgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgLyoqIFBpY2sgYSBjb250cmlidXRlZCB0b29sJ3MgY2hlY2twb2ludC4gKi9cbiAgQE91dHB1dCgpIHRvb2xNb2RlbENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8eyB0b29sSWQ6IHN0cmluZzsgbW9kZWxJZDogc3RyaW5nIH0+KCk7XG4gIC8qKiBPcGVuIGEgY29udHJpYnV0ZWQgdG9vbCdzIHBhcmFtZXRlciBkaWFsb2csIGJ5IHRvb2wgaWQuICovXG4gIEBPdXRwdXQoKSBvcGVuVG9vbFBhcmFtcyA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICAvKiogU0FNIG1vZGVsIHBpY2tlciAoaml0LXVpIzkwIFAxKS4gKi9cbiAgQE91dHB1dCgpIHNhbU1vZGVsQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIC8qKiBUaGUgd2FuZCBzZW5zaXRpdml0eSBzbGlkZXIgbW92ZWQuICovXG4gIEBPdXRwdXQoKSB3YW5kU2Vuc2l0aXZpdHlDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlciB8IHVuZGVmaW5lZD4oKTtcbiAgLyoqIFRoZSBicnVzaCBzaXplIHNsaWRlciBtb3ZlZC4gKi9cbiAgQE91dHB1dCgpIGJydXNoU2l6ZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyIHwgdW5kZWZpbmVkPigpO1xuICAvKiogVGhlIHZlcnRleC1lcmFzZXIgcmFkaXVzIHNsaWRlciBtb3ZlZC4gKi9cbiAgQE91dHB1dCgpIHZlcnRleEVyYXNlclJhZGl1c0NoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyIHwgdW5kZWZpbmVkPigpO1xuXG4gIHByb3RlY3RlZCBkaXNwbGF5SGVscERpYWxvZyA9IGZhbHNlO1xuXG4gIC8qKiB0cmFja0J5IGZvciB0aGUgZGlhbG9nIHRvb2xzJyBidXR0b25zLiAqL1xuICBwcm90ZWN0ZWQgdHJhY2tUb29sQnlJZChfaW5kZXg6IG51bWJlciwgdG9vbDogeyBpZDogc3RyaW5nIH0pOiBzdHJpbmcge1xuICAgIHJldHVybiB0b29sLmlkO1xuICB9XG5cbiAgLyoqIFRoZSBidWlsdC1pbiB0eXBlIHdob3NlIHRvb2xzIGFuZCBjb250cm9scyBhcHBseSB0byB0aGUgY3VycmVudCBzZWxlY3Rpb24uICovXG4gIHByb3RlY3RlZCBnZXQgZWZmZWN0aXZlUGxvdFR5cGUoKTogUGxvdFR5cGUge1xuICAgIGlmICh0aGlzLmJhc2VQbG90VHlwZSkgcmV0dXJuIHRoaXMuYmFzZVBsb3RUeXBlO1xuICAgIHJldHVybiBpc0J1aWx0aW5QbG90VHlwZSh0aGlzLnNlbGVjdGVkUGxvdFR5cGUpID8gdGhpcy5zZWxlY3RlZFBsb3RUeXBlIDogUGxvdFR5cGUuSU1BR0U7XG4gIH1cblxuICAvKiogVGhlIEltYWdlIHBsb3QgdHlwZSByZW5kZXJzIGFzIGEgbmF0aXZlbHkgcGFuL3pvb20tYWJsZSByYXN0ZXIsIHNvIHRoZVxuICAgKiAgZ2VuZXJpYyB6b29tL3BhbiB0b29scyBhcmUgaGlkZGVuLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGlzSW1hZ2VWaWV3KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlID09PSBQbG90VHlwZS5JTUFHRTtcbiAgfVxuXG4gIC8qKiBFaXRoZXIgc3BhdGlhbC1vbWljcyBtb2RlIGlzIGFjdGl2ZSwgc28gaXRzIGNvbnRyb2xzIGFyZSB3b3J0aCBvZmZlcmluZy5cbiAgICogIFRoZSAzRCBjbG91ZCBuZWVkcyB0aGUgcGFuZWwgTU9SRSB0aGFuIHRoZSAyRCB2aWV3IGRvZXMsIG5vdCBsZXNzOiBjb2xvdXJpbmcsXG4gICAqICB0aGUgbGVnZW5kIGFuZCBjYXRlZ29yeSBzaG93L2hpZGUgYXJlIHRoZSBvbmx5IHdheSB0byBtYWtlIHNlbnNlIG9mIGFcbiAgICogIG1pbGxpb24gb3ZlcmxhcHBpbmcgcG9pbnRzLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGlzU3BhdGlhbE1vZGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGlzU3BhdGlhbE9taWNzKHRoaXMuZWZmZWN0aXZlUGxvdFR5cGUpIHx8IGlzU3BhdGlhbE9taWNzM2QodGhpcy5lZmZlY3RpdmVQbG90VHlwZSk7XG4gIH1cblxuICAvKiogQmFja2VuZHMgd2l0aCBhIHZlcnRleC1lZGl0aW5nIHJlZ2lvbiBvdmVybGF5OiBPU0QgSW1hZ2UgYW5kIG5hcGFyaS1qcyBXZWJHUFUgaW1hZ2VcbiAgICogIChqaXQtdWkjMTAyKS4gR2F0ZXMgdGhlIHBvbHlnb24gLyBhZGQtdmVydGV4IC8gZGVsZXRlLXZlcnRleCAvIELDqXppZXItY29udmVydCB0b29scy4gKi9cbiAgcHJvdGVjdGVkIGdldCBzdXBwb3J0c1JlZ2lvblZlcnRleFRvb2xzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlID09PSBQbG90VHlwZS5JTUFHRSB8fCB0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlID09PSBQbG90VHlwZS5OQVBBUklfSU1BR0U7XG4gIH1cblxuICAvKiogUGxvdCB0eXBlcyB0aGF0IHNjcnViIGEgei1zdGFjayBsaXZlICh0aGUgcmVuZGVyZXIgc3dhcHMgdGhlIHNsaWNlIGluIHBsYWNlKTogdGhlIE9TRCBJbWFnZVxuICAgKiAgdmlldywgdGhlIG5hcGFyaS1qcyBXZWJHUFUgaW1hZ2UsIHRoZSBuYXBhcmktanMgc3VyZmFjZSDigJQgd2hpY2ggcmVidWlsZHMgdGhlIGhlaWdodCBmaWVsZFxuICAgKiAgZnJvbSB0aGUgcGlja2VkIHNsaWNlIChqaXQtdWkjMTAyKSDigJQgYW5kIHRoZSAyRCBzcGF0aWFsLW9taWNzIHZpZXcsIHdoZXJlIGEgM0QgZGF0YXNldCdzXG4gICAqICByZWdpc3RlcmVkIHZvbHVtZSBpcyB0aGUgaW1hZ2UgYW5kIHRoZSBzbGlkZXIgcGlja3MgdGhlIHNlY3Rpb24gd2hvc2Ugb2JzZXJ2YXRpb25zIGFyZVxuICAgKiAgZHJhd24uIEFsc28gYSBzcGxpdCB2b2x1bWUgdmlldywgd2hvc2Ugc2xpY2UgZWRpdG9yIHNob3dzIHRoZSBzbGljZSBwaWNrZWQuIERyaXZlcyB0aGVcbiAgICogIHBlci1zbGljZSBzbGlkZXIuICovXG4gIHByb3RlY3RlZCBnZXQgc2hvd3NMaXZlU2xpY2VTY3J1YmJlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKFxuICAgICAgKHRoaXMuaXNWb2x1bWVWaWV3ICYmIHRoaXMuc2xpY2VFZGl0b3IpIHx8XG4gICAgICB0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlID09PSBQbG90VHlwZS5JTUFHRSB8fFxuICAgICAgdGhpcy5lZmZlY3RpdmVQbG90VHlwZSA9PT0gUGxvdFR5cGUuTkFQQVJJX0lNQUdFIHx8XG4gICAgICBpc05hcGFyaVN1cmZhY2UodGhpcy5lZmZlY3RpdmVQbG90VHlwZSkgfHxcbiAgICAgIGlzTmFwYXJpU2NhdHRlcih0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlKSB8fFxuICAgICAgaXNTcGF0aWFsT21pY3ModGhpcy5lZmZlY3RpdmVQbG90VHlwZSlcbiAgICApO1xuICB9XG5cbiAgLyoqIEFueSBuYXBhcmktanMgV2ViR1BVIHBsb3QgdHlwZS4gVGhlIHNpbmdsZS1pbWFnZS9zdGFjayB0b2dnbGUgKyBzbGljZS1udW1iZXIgZmllbGQgYXJlXG4gICAqICBQbG90bHktb25seSBzdGFjayBjb250cm9scywgc28gdGhleSdyZSBoaWRkZW4gZm9yIG5hcGFyaSAoaml0LXVpIzEwMikuICovXG4gIHByb3RlY3RlZCBnZXQgaXNOYXBhcmlNb2RlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlID09PSBQbG90VHlwZS5OQVBBUklfSU1BR0UgfHxcbiAgICAgIGlzTmFwYXJpU2NhdHRlcih0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlKSB8fFxuICAgICAgaXNOYXBhcmkzZCh0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlKVxuICAgICk7XG4gIH1cblxuICAvKiogSVNPU1VSRkFDRSAoUGxvdGx5IG9yIG5hcGFyaS1qcyBXZWJHUFUsIGVpdGhlciByZXNvbHV0aW9uKSBzaG93cyB0aGUgaXNvdmFsdWUgcmFuZ2Ugc2xpZGVyLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGlzSXNvc3VyZmFjZU1vZGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZWZmZWN0aXZlUGxvdFR5cGUgPT09IFBsb3RUeXBlLklTT1NVUkZBQ0UgfHwgaXNOYXBhcmlJc29zdXJmYWNlKHRoaXMuZWZmZWN0aXZlUGxvdFR5cGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSB2aWV3cyB0aGF0IGRyYXcgdGhlIDNEIGF4ZXMgZ2l6bW8gKGFuIGBBeGVzM2RHaXptb2ApOiBuYXBhcmktanMncyB2b2x1bWUsIGlzb3N1cmZhY2UgYW5kXG4gICAqIHN1cmZhY2UsIGFuZCB0aGUgM0Qgc3BhdGlhbCBjbG91ZC4gTm90IGV2ZXJ5IG5hcGFyaS1qcyB2aWV3OiBpdHMgMkQgaW1hZ2UgYW5kIHNjYXR0ZXIgYW5kIGl0c1xuICAgKiAzRCBzY2F0dGVyIGRyYXcgbm9uZSwgYW5kIGEgdG9nZ2xlIHRoZXJlIHdvdWxkIGRvIG5vdGhpbmcuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IHNob3dzQXhlc1RvZ2dsZSgpOiBib29sZWFuIHtcbiAgICBjb25zdCB0eXBlID0gdGhpcy5lZmZlY3RpdmVQbG90VHlwZTtcbiAgICByZXR1cm4gaXNOYXBhcmlWb2x1bWUodHlwZSkgfHwgaXNOYXBhcmlJc29zdXJmYWNlKHR5cGUpIHx8IGlzTmFwYXJpU3VyZmFjZSh0eXBlKSB8fCBpc1NwYXRpYWxPbWljczNkKHR5cGUpO1xuICB9XG5cbiAgLyoqIFRoZSBuYXBhcmktanMgV2ViR1BVIHN1cmZhY2Ug4oCUIHNob3dzIHRoZSB3aXJlZnJhbWUgdG9nZ2xlLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGlzTmFwYXJpU3VyZmFjZU1vZGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGlzTmFwYXJpU3VyZmFjZSh0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlKTtcbiAgfVxuXG4gIC8qKiBBbnkgbmFwYXJpLWpzIFdlYkdQVSAzRCB0eXBlICh2b2x1bWUvaXNvc3VyZmFjZS9zdXJmYWNlKSDigJQgc2hvd3MgdGhlIFJlc29sdXRpb24gY29udHJvbC4gKi9cbiAgcHJvdGVjdGVkIGdldCBpc05hcGFyaTNkTW9kZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaXNOYXBhcmkzZCh0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlKTtcbiAgfVxuXG4gIC8qKiBJbnRlbnNpdHkgcHJvZmlsZSBsaW5lcyBhcmUgUmVnaW9uLWJhc2VkIGFuZCBhdmFpbGFibGUgaW4gdGhlIEhlYXRtYXAgYW5kXG4gICAqICBJbWFnZSBwbG90IHR5cGVzLCB3aGljaCBzaG93IHRoZSBJbnRlbnNpdHkgdG9vbCBncm91cC4gKi9cbiAgcHJvdGVjdGVkIGdldCBpc0ludGVuc2l0eUNhcGFibGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZWZmZWN0aXZlUGxvdFR5cGUgPT09IFBsb3RUeXBlLkhFQVRNQVAgfHwgdGhpcy5lZmZlY3RpdmVQbG90VHlwZSA9PT0gUGxvdFR5cGUuSU1BR0U7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2hvd0hlbHAoKTogdm9pZCB7XG4gICAgdGhpcy5kaXNwbGF5SGVscERpYWxvZyA9IHRydWU7XG4gIH1cbn1cbiIsIjxwLXRvb2xiYXI+XG4gIDxkaXYgY2xhc3M9XCJwLXRvb2xiYXItZ3JvdXAtc3RhcnQgZmxleC13cmFwIGFsaWduLWl0ZW1zLWNlbnRlciBnYXAtMVwiPlxuICAgIDwhLS0gSG9zdC1wcm92aWRlZCBjdXN0b20gdG9vbGJhciBidXR0b25zLCBzaG93biBmaXJzdCAoZS5nLiBhcHAtc3BlY2lmaWNcbiAgICAgICAgIGFjdGlvbnMgdGhlIHZpc3VhbGl6YXRpb24gdmlldyBpdHNlbGYgZG9lc24ndCBvd24pLiAtLT5cbiAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG5cbiAgICA8IS0tIENvbnRyaWJ1dGVkIGRpYWxvZyB0b29scyAoVE9PTEJBUl9UT09MUywga2luZDogJ2RpYWxvZycpOiBhcHAtbGV2ZWwgYWN0aW9uc1xuICAgICAgICAgbGlrZSB0aGUgaG9zdCdzIG93biBidXR0b25zIGFib3ZlLCBzbyB0aGV5IHNpdCByaWdodCBiZXNpZGUgdGhlbS4gSW1hZ2Ugdmlld1xuICAgICAgICAgb25seSwgdGhlIHZpZXcgdGhlaXIgZGlhbG9nIGRyYXdzIG92ZXIuIEhpZ2hsaWdodGVkIHdoaWxlIHRoZSBkaWFsb2cgaXMgb3Blbi4gLS0+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzSW1hZ2VWaWV3XCI+XG4gICAgICA8cC1idXR0b25cbiAgICAgICAgKm5nRm9yPVwibGV0IHRvb2wgb2YgZGlhbG9nVG9vbHM7IHRyYWNrQnk6IHRyYWNrVG9vbEJ5SWRcIlxuICAgICAgICBzaXplPVwic21hbGxcIlxuICAgICAgICBbdGV4dF09XCJvcGVuRGlhbG9nVG9vbElkICE9PSB0b29sLmlkXCJcbiAgICAgICAgW3BUb29sdGlwXT1cInRvb2wudG9vbHRpcFwiXG4gICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgICAgIFthcmlhTGFiZWxdPVwidG9vbC5sYWJlbFwiXG4gICAgICAgIFthdHRyLmFyaWEtcHJlc3NlZF09XCJvcGVuRGlhbG9nVG9vbElkID09PSB0b29sLmlkXCJcbiAgICAgICAgKG9uQ2xpY2spPVwidG9nZ2xlRGlhbG9nVG9vbC5lbWl0KHRvb2wuaWQpXCJcbiAgICAgID5cbiAgICAgICAgPGltZ1xuICAgICAgICAgICpuZ0lmPVwidG9vbC5pY29uLnNyY1wiXG4gICAgICAgICAgW3NyY109XCJ0b29sLmljb24uc3JjXCJcbiAgICAgICAgICBzdHlsZT1cIndpZHRoOiAxcmVtXCJcbiAgICAgICAgICBbYWx0XT1cInRvb2wubGFiZWxcIlxuICAgICAgICAgIFtjbGFzc109XCJvcGVuRGlhbG9nVG9vbElkID09PSB0b29sLmlkID8gJ3Rvb2xiYXItaWNvbi1hY3RpdmUnIDogJ3Rvb2xiYXItaWNvbi1kYXJrJ1wiXG4gICAgICAgIC8+XG4gICAgICAgIDxpICpuZ0lmPVwidG9vbC5pY29uLnBpXCIgY2xhc3M9XCJwaSB7eyB0b29sLmljb24ucGkgfX1cIj48L2k+XG4gICAgICA8L3AtYnV0dG9uPlxuICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgPCEtLSBQbG90IHR5cGU6IGF2YWlsYWJsZSBmb3IgYW55IGltYWdlIChncmF5c2NhbGUgb3IgUkdCKSwgYW5kIGZvciBhIHNwYXRpYWwgZGF0YXNldFxuICAgICAgICAgdGhhdCBicmluZ3Mgbm9uZSAoaXRzIHNwYXRpYWwgbW9kZXMgYXJlIHN0aWxsIGEgY2hvaWNlKS4gLS0+XG4gICAgPHRvb2xiYXItcGxvdC10eXBlLXNlbGVjdG9yXG4gICAgICAqbmdJZj1cInNob3dQbG90VHlwZXNcIlxuICAgICAgW29wdGlvbnNdPVwicGxvdFR5cGVPcHRpb25zXCJcbiAgICAgIFtzZWxlY3RlZF09XCJzZWxlY3RlZFBsb3RUeXBlXCJcbiAgICAgIFtpc29zdXJmYWNlXT1cImlzSXNvc3VyZmFjZU1vZGVcIlxuICAgICAgW2lzb1JhbmdlXT1cImlzb1JhbmdlXCJcbiAgICAgIFtpbnRlbnNpdHlMaW5lc109XCJpc0ludGVuc2l0eUNhcGFibGVcIlxuICAgICAgKHNlbGVjdFBsb3RUeXBlKT1cInNlbGVjdFBsb3RUeXBlLmVtaXQoJGV2ZW50KVwiXG4gICAgICAoaXNvUmFuZ2VDaGFuZ2UpPVwiaXNvUmFuZ2VDaGFuZ2UuZW1pdCgkZXZlbnQpXCJcbiAgICAgIChhZGRQcm9maWxlTGluZSk9XCJhZGRQcm9maWxlTGluZS5lbWl0KClcIlxuICAgID5cbiAgICA8L3Rvb2xiYXItcGxvdC10eXBlLXNlbGVjdG9yPlxuICAgIDwhLS0gQ2hhbm5lbHMgJiBIaXN0b2dyYW06IGJyaWdodG5lc3MvY29udHJhc3QsIGdhbW1hLCBwZXItY2hhbm5lbCBkaXNwbGF5LFxuICAgICAgICAgY29sb3JtYXAvcmV2ZXJzZS9pbnZlcnQg4oCUIG9wZW5zIHRoZSBmbG9hdGluZyBkaWFsb2cuIC0tPlxuICAgIDxwLWJ1dHRvblxuICAgICAgKm5nSWY9XCJ0b29scy5zcGVjaWFsVG9vbHNcIlxuICAgICAgcFJpcHBsZVxuICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgIFt0ZXh0XT1cInRydWVcIlxuICAgICAgYXJpYUxhYmVsPVwiQ2hhbm5lbHMgJmFtcDsgSGlzdG9ncmFtXCJcbiAgICAgIHBUb29sdGlwPVwiQ2hhbm5lbHMgJmFtcDsgSGlzdG9ncmFtIChicmlnaHRuZXNzL2NvbnRyYXN0LCBjb2xvcm1hcClcIlxuICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgIChvbkNsaWNrKT1cIm9wZW5DaGFubmVsSGlzdG9ncmFtLmVtaXQoKVwiXG4gICAgPlxuICAgICAgPGltZyBzcmM9XCJhc3NldHMvcGxvdHRpbmcvaW52ZXJ0LnN2Z1wiIGNsYXNzPVwidG9vbGJhci1pY29uLWRhcmtcIiBzdHlsZT1cIndpZHRoOiAxcmVtXCIgLz5cbiAgICA8L3AtYnV0dG9uPlxuXG4gICAgPCEtLSBTcGF0aWFsLW9taWNzIGNvbnRyb2xzLiBPbmx5IG1lYW5pbmdmdWwgaW4gdGhlIHNwYXRpYWwgbW9kZSwgd2hpY2ggaXNcbiAgICAgICAgIGl0c2VsZiBvbmx5IG9mZmVyZWQgd2hpbGUgYSBkYXRhc2V0IGlzIGxvYWRlZCDigJQgc28gdGhpcyBidXR0b24gYXBwZWFyc1xuICAgICAgICAgZXhhY3RseSB3aGVuIHRoZXJlIGlzIHNvbWV0aGluZyBmb3IgaXQgdG8gY29udHJvbC4gLS0+XG4gICAgPHAtYnV0dG9uXG4gICAgICAqbmdJZj1cInRvb2xzLnNwZWNpYWxUb29scyAmJiBpc1NwYXRpYWxNb2RlXCJcbiAgICAgIHBSaXBwbGVcbiAgICAgIHNpemU9XCJzbWFsbFwiXG4gICAgICBbdGV4dF09XCJ0cnVlXCJcbiAgICAgIGFyaWFMYWJlbD1cIlNwYXRpYWwgb21pY3MgY29udHJvbHNcIlxuICAgICAgcFRvb2x0aXA9XCJTcGF0aWFsIG9taWNzIChjb2xvdXIgYnkgY29sdW1uIG9yIGdlbmUsIGxlZ2VuZCwgc2VsZWN0aW9uLCBkaXN0cmlidXRpb25zKVwiXG4gICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgICAgKG9uQ2xpY2spPVwib3BlblNwYXRpYWxDb250cm9scy5lbWl0KClcIlxuICAgID5cbiAgICAgIDxpbWcgc3JjPVwiYXNzZXRzL3Bsb3R0aW5nL3NwYXRpYWwtb21pY3Muc3ZnXCIgY2xhc3M9XCJ0b29sYmFyLWljb24tZGFya1wiIHN0eWxlPVwid2lkdGg6IDFyZW1cIiAvPlxuICAgIDwvcC1idXR0b24+XG5cbiAgICA8IS0tIFNtb290aGVuIHRvZ2dsZTogYmlsaW5lYXIgc21vb3RoaW5nIHZzIG5lYXJlc3QtbmVpZ2hib3VyIHJhdyBwaXhlbHMgKEltYWdlXG4gICAgICAgICB2aWV3IG9ubHkg4oCUIGl0J3MgYW4gT3BlblNlYWRyYWdvbiBkcmF3ZXIgc2V0dGluZykuIEhpZ2hsaWdodGVkIHdoZW4gc21vb3RoaW5nIG9uLiAtLT5cbiAgICA8cC1idXR0b25cbiAgICAgICpuZ0lmPVwidG9vbHMuc3BlY2lhbFRvb2xzICYmIGlzSW1hZ2VWaWV3XCJcbiAgICAgIHNpemU9XCJzbWFsbFwiXG4gICAgICBbdGV4dF09XCIhaW1hZ2VTbW9vdGhpbmdFbmFibGVkXCJcbiAgICAgIGFyaWFMYWJlbD1cIlNtb290aGVuXCJcbiAgICAgIHBUb29sdGlwPVwiU21vb3RoZW4gKHR1cm4gb24gaW1hZ2Ugc21vb3RoaW5nKVwiXG4gICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgICAgKG9uQ2xpY2spPVwidG9nZ2xlSW1hZ2VTbW9vdGhpbmcuZW1pdCgpXCJcbiAgICA+XG4gICAgICA8aW1nXG4gICAgICAgIHNyYz1cImFzc2V0cy9wbG90dGluZy9zbW9vdGguc3ZnXCJcbiAgICAgICAgc3R5bGU9XCJ3aWR0aDogMXJlbVwiXG4gICAgICAgIFtjbGFzc109XCJpbWFnZVNtb290aGluZ0VuYWJsZWQgPyAndG9vbGJhci1pY29uLWFjdGl2ZScgOiAndG9vbGJhci1pY29uLWRhcmsnXCJcbiAgICAgIC8+XG4gICAgPC9wLWJ1dHRvbj5cblxuICAgIDwhLS0gU3RhY2sgY29udHJvbHMgLS0+XG4gICAgPHRvb2xiYXItc3RhY2stY29udHJvbHNcbiAgICAgICpuZ0lmPVwiaW1hZ2VJbmZvPy5pc1N0YWNrIHx8IChwbGFuZVNsaWNlcyAmJiBzaG93c0xpdmVTbGljZVNjcnViYmVyKVwiXG4gICAgICBbbGl2ZVNjcnViYmVyXT1cInNob3dzTGl2ZVNsaWNlU2NydWJiZXJcIlxuICAgICAgW3N0YWNrVG9nZ2xlXT1cIiFzaG93c0xpdmVTbGljZVNjcnViYmVyICYmICFpc05hcGFyaU1vZGUgJiYgIWlzU3BhdGlhbE1vZGVcIlxuICAgICAgW3Nob3dTdGFja109XCIhIWltYWdlSW5mbz8uc2hvd1N0YWNrXCJcbiAgICAgIFtzdGFja09wdGlvbnNdPVwic3RhY2tPcHRpb25zXCJcbiAgICAgIFt6SW5kZXhdPVwiekluZGV4XCJcbiAgICAgIFttYXhJbmRleF09XCJtYXhJbmRleFwiXG4gICAgICAoelNjcnViKT1cInpTY3J1Yi5lbWl0KCRldmVudClcIlxuICAgICAgKHpTbGlkZSk9XCJ6U2xpZGUuZW1pdCgkZXZlbnQpXCJcbiAgICAgIChzZWxlY3RTdGFja09wdGlvbik9XCJzZWxlY3RTdGFja09wdGlvbi5lbWl0KCRldmVudClcIlxuICAgICAgKHpJbmRleElucHV0KT1cInpJbmRleElucHV0LmVtaXQoJGV2ZW50KVwiXG4gICAgICAocmVsb2FkQW5kUGxvdCk9XCJyZWxvYWRBbmRQbG90LmVtaXQoKVwiXG4gICAgPlxuICAgIDwvdG9vbGJhci1zdGFjay1jb250cm9scz5cblxuICAgIDwhLS0gSW1hZ2UgYWN0aW9ucyAoc3BlY2lhbCB0b29scykgLS0+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInRvb2xzLnNwZWNpYWxUb29sc1wiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJ0b29sYmFyLXNlcGFyYXRvclwiPjwvc3Bhbj5cbiAgICAgIDxwLWJ1dHRvblxuICAgICAgICBpY29uPVwicGkgcGktZG93bmxvYWRcIlxuICAgICAgICBzaXplPVwic21hbGxcIlxuICAgICAgICBbdGV4dF09XCJ0cnVlXCJcbiAgICAgICAgYXJpYUxhYmVsPVwiRG93bmxvYWQgaW1hZ2UgYXMgUE5HXCJcbiAgICAgICAgcFRvb2x0aXA9XCJEb3dubG9hZCBpbWFnZSBhcyBQTkdcIlxuICAgICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgICAgICAob25DbGljayk9XCJkb3dubG9hZEltYWdlLmVtaXQoKVwiXG4gICAgICA+XG4gICAgICA8L3AtYnV0dG9uPlxuICAgICAgPHAtYnV0dG9uXG4gICAgICAgICpuZ0lmPVwiaXNIZWF0bWFwXCJcbiAgICAgICAgaWNvbj1cInBpIHBpLXdpbmRvdy1tYXhpbWl6ZVwiXG4gICAgICAgIHNpemU9XCJzbWFsbFwiXG4gICAgICAgIFt0ZXh0XT1cInRydWVcIlxuICAgICAgICBhcmlhTGFiZWw9XCJGaXQgdG8gdmlld1wiXG4gICAgICAgIHBUb29sdGlwPVwiRml0IHRvIHZpZXdcIlxuICAgICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgICAgICAob25DbGljayk9XCJhdXRvc2NhbGVJbWFnZS5lbWl0KClcIlxuICAgICAgPlxuICAgICAgPC9wLWJ1dHRvbj5cbiAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgIDx0b29sYmFyLXZpZXctY29udHJvbHNcbiAgICAgIFtpc0hlYXRtYXBdPVwiaXNIZWF0bWFwXCJcbiAgICAgIFt6b29tVG9vbHNdPVwidG9vbHMuem9vbVRvb2xzXCJcbiAgICAgIFtpc0ltYWdlVmlld109XCJpc0ltYWdlVmlld1wiXG4gICAgICBbYWN0aXZlRHJhZ01vZGVdPVwiYWN0aXZlRHJhZ01vZGVcIlxuICAgICAgW2FjdGl2ZVN1cmZhY2UzZE1vZGVdPVwiYWN0aXZlU3VyZmFjZTNkTW9kZVwiXG4gICAgICBbYXhlc1RvZ2dsZV09XCJzaG93c0F4ZXNUb2dnbGVcIlxuICAgICAgW2lzTmFwYXJpU3VyZmFjZU1vZGVdPVwiaXNOYXBhcmlTdXJmYWNlTW9kZVwiXG4gICAgICBbaXNOYXBhcmkzZE1vZGVdPVwiaXNOYXBhcmkzZE1vZGVcIlxuICAgICAgW2F4ZXNWaXNpYmxlXT1cImF4ZXNWaXNpYmxlXCJcbiAgICAgIFt3aXJlZnJhbWVBY3RpdmVdPVwid2lyZWZyYW1lQWN0aXZlXCJcbiAgICAgIFtyZXNvbHV0aW9uU2NhbGVdPVwicmVzb2x1dGlvblNjYWxlXCJcbiAgICAgICh0b2dnbGVEcmFnTW9kZSk9XCJ0b2dnbGVEcmFnTW9kZS5lbWl0KCRldmVudClcIlxuICAgICAgKHpvb21Jbik9XCJ6b29tSW4uZW1pdCgpXCJcbiAgICAgICh6b29tT3V0KT1cInpvb21PdXQuZW1pdCgpXCJcbiAgICAgICh0b2dnbGVTdXJmYWNlM2RNb2RlKT1cInRvZ2dsZVN1cmZhY2UzZE1vZGUuZW1pdCgkZXZlbnQpXCJcbiAgICAgIChyZXNldFN1cmZhY2VDYW1lcmEpPVwicmVzZXRTdXJmYWNlQ2FtZXJhLmVtaXQoKVwiXG4gICAgICAodG9nZ2xlQXhlcyk9XCJ0b2dnbGVBeGVzLmVtaXQoKVwiXG4gICAgICAodG9nZ2xlV2lyZWZyYW1lKT1cInRvZ2dsZVdpcmVmcmFtZS5lbWl0KClcIlxuICAgICAgKHNlbGVjdFJlc29sdXRpb24pPVwic2VsZWN0UmVzb2x1dGlvbi5lbWl0KCRldmVudClcIlxuICAgID5cbiAgICA8L3Rvb2xiYXItdmlldy1jb250cm9scz5cblxuICAgIDwhLS0gQSB2b2x1bWUgdmlldyBkcmF3cyBubyByZWdpb25zOyB0aGUgUmVnaW9uIEVkaXRvciBzaG93cyB0aGVtIGluIGl0IGluIDNELCBhbmQgdGhlXG4gICAgICAgICBzZWxlY3Rpb24gdG9vbCBwaWNrcyB0aGVpciBzdXJmYWNlcyB0aGVyZS4gVGhlIHNsaWNlIGVkaXRvciBzcGxpdHMgdGhlIHZpZXc6IHRoZSBzbGljZSxcbiAgICAgICAgIHdpdGggZXZlcnkgcmVnaW9uIHRvb2wsIGJlc2lkZSB0aGUgM0Qgdmlldy4gLS0+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzVm9sdW1lVmlldyAmJiAhaXNIZWF0bWFwICYmICFpczNkUmVnaW9ucyAmJiB0b29scy5yZWdpb25Ub29sc1wiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJ0b29sYmFyLXNlcGFyYXRvclwiPjwvc3Bhbj5cbiAgICAgIDxwLWJ1dHRvblxuICAgICAgICBzaXplPVwic21hbGxcIlxuICAgICAgICBbdGV4dF09XCIhc2xpY2VFZGl0b3JcIlxuICAgICAgICBhcmlhTGFiZWw9XCJTbGljZSBlZGl0b3JcIlxuICAgICAgICBbYXR0ci5hcmlhLXByZXNzZWRdPVwic2xpY2VFZGl0b3JcIlxuICAgICAgICBbcFRvb2x0aXBdPVwiXG4gICAgICAgICAgc2xpY2VFZGl0b3JcbiAgICAgICAgICAgID8gJ0Nsb3NlIHRoZSBzbGljZSBlZGl0b3InXG4gICAgICAgICAgICA6ICdTbGljZSBlZGl0b3I6IHRoZSBzbGljZSBhbmQgdGhlIHNlY3Rpb25zIHRocm91Z2ggeCBhbmQgeSBiZXNpZGUgdGhlIDNEIHZpZXcnXG4gICAgICAgIFwiXG4gICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgICAgIChvbkNsaWNrKT1cInRvZ2dsZVNsaWNlRWRpdG9yLmVtaXQoKVwiXG4gICAgICA+XG4gICAgICAgIDxpbWdcbiAgICAgICAgICBzcmM9XCJhc3NldHMvcGxvdHRpbmcvc2xpY2Uuc3ZnXCJcbiAgICAgICAgICBzdHlsZT1cIndpZHRoOiAxcmVtXCJcbiAgICAgICAgICBhbHQ9XCJcIlxuICAgICAgICAgIFtjbGFzc109XCJzbGljZUVkaXRvciA/ICd0b29sYmFyLWljb24tYWN0aXZlJyA6ICd0b29sYmFyLWljb24tZGFyaydcIlxuICAgICAgICAvPlxuICAgICAgPC9wLWJ1dHRvbj5cbiAgICAgIDx0b29sYmFyLXJlZ2lvbi10b29sc1xuICAgICAgICAqbmdJZj1cIiFzbGljZUVkaXRvclwiXG4gICAgICAgIFthY3RpdmVEcmFnTW9kZV09XCJhY3RpdmVEcmFnTW9kZVwiXG4gICAgICAgIFtzZWxlY3RPbmx5XT1cInRydWVcIlxuICAgICAgICBbY2FuVW5kb109XCJjYW5VbmRvXCJcbiAgICAgICAgW2NhblJlZG9dPVwiY2FuUmVkb1wiXG4gICAgICAgIChvcGVuUmVnaW9uRWRpdG9yKT1cIm9wZW5SZWdpb25FZGl0b3IuZW1pdCgpXCJcbiAgICAgICAgKHRvZ2dsZURyYWdNb2RlKT1cInRvZ2dsZURyYWdNb2RlLmVtaXQoJGV2ZW50KVwiXG4gICAgICAgICh1bmRvUmVnaW9uKT1cInVuZG9SZWdpb24uZW1pdCgpXCJcbiAgICAgICAgKHJlZG9SZWdpb24pPVwicmVkb1JlZ2lvbi5lbWl0KClcIlxuICAgICAgICAoZGVsZXRlUmVnaW9uKT1cImRlbGV0ZVJlZ2lvbi5lbWl0KClcIlxuICAgICAgPlxuICAgICAgPC90b29sYmFyLXJlZ2lvbi10b29scz5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiKGlzSGVhdG1hcCB8fCBpczNkUmVnaW9ucyB8fCAoaXNWb2x1bWVWaWV3ICYmIHNsaWNlRWRpdG9yKSkgJiYgdG9vbHMucmVnaW9uVG9vbHNcIj5cbiAgICAgIDx0b29sYmFyLXJlZ2lvbi10b29sc1xuICAgICAgICBbYWN0aXZlRHJhZ01vZGVdPVwiYWN0aXZlRHJhZ01vZGVcIlxuICAgICAgICBbaXMzZFJlZ2lvbnNdPVwiaXMzZFJlZ2lvbnNcIlxuICAgICAgICBbdmVydGV4VG9vbHNdPVwic3VwcG9ydHNSZWdpb25WZXJ0ZXhUb29scyB8fCAoaXNWb2x1bWVWaWV3ICYmIHNsaWNlRWRpdG9yKVwiXG4gICAgICAgIFt3YW5kU2Vuc2l0aXZpdHldPVwid2FuZFNlbnNpdGl2aXR5XCJcbiAgICAgICAgW2JydXNoU2l6ZV09XCJicnVzaFNpemVcIlxuICAgICAgICBbdmVydGV4RXJhc2VyUmFkaXVzXT1cInZlcnRleEVyYXNlclJhZGl1c1wiXG4gICAgICAgIFtjYW5VbmRvXT1cImNhblVuZG9cIlxuICAgICAgICBbY2FuUmVkb109XCJjYW5SZWRvXCJcbiAgICAgICAgKG9wZW5SZWdpb25FZGl0b3IpPVwib3BlblJlZ2lvbkVkaXRvci5lbWl0KClcIlxuICAgICAgICAodG9nZ2xlRHJhZ01vZGUpPVwidG9nZ2xlRHJhZ01vZGUuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgKHVuZG9SZWdpb24pPVwidW5kb1JlZ2lvbi5lbWl0KClcIlxuICAgICAgICAocmVkb1JlZ2lvbik9XCJyZWRvUmVnaW9uLmVtaXQoKVwiXG4gICAgICAgIChkZWxldGVSZWdpb24pPVwiZGVsZXRlUmVnaW9uLmVtaXQoKVwiXG4gICAgICAgICh3YW5kU2Vuc2l0aXZpdHlDaGFuZ2UpPVwid2FuZFNlbnNpdGl2aXR5Q2hhbmdlLmVtaXQoJGV2ZW50KVwiXG4gICAgICAgIChicnVzaFNpemVDaGFuZ2UpPVwiYnJ1c2hTaXplQ2hhbmdlLmVtaXQoJGV2ZW50KVwiXG4gICAgICAgICh2ZXJ0ZXhFcmFzZXJSYWRpdXNDaGFuZ2UpPVwidmVydGV4RXJhc2VyUmFkaXVzQ2hhbmdlLmVtaXQoJGV2ZW50KVwiXG4gICAgICA+XG4gICAgICA8L3Rvb2xiYXItcmVnaW9uLXRvb2xzPlxuICAgICAgPHRvb2xiYXItc2VnbWVudGF0aW9uLXRvb2xzXG4gICAgICAgIFthY3RpdmVEcmFnTW9kZV09XCJhY3RpdmVEcmFnTW9kZVwiXG4gICAgICAgIFtzYW1Nb2RlbHNdPVwic2FtTW9kZWxzXCJcbiAgICAgICAgW3NhbU1vZGVsSWRdPVwic2FtTW9kZWxJZFwiXG4gICAgICAgIFtjb250cmlidXRlZFRvb2xzXT1cImNvbnRyaWJ1dGVkVG9vbHNcIlxuICAgICAgICBbdG9vbE1vZGVsSWRzXT1cInRvb2xNb2RlbElkc1wiXG4gICAgICAgIChzZWdtZW50UmVnaW9ucyk9XCJzZWdtZW50UmVnaW9ucy5lbWl0KClcIlxuICAgICAgICAoc2VnbWVudENlbGxwb3NlKT1cInNlZ21lbnRDZWxscG9zZS5lbWl0KClcIlxuICAgICAgICAodG9nZ2xlRHJhZ01vZGUpPVwidG9nZ2xlRHJhZ01vZGUuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgKHNhbU1vZGVsQ2hhbmdlKT1cInNhbU1vZGVsQ2hhbmdlLmVtaXQoJGV2ZW50KVwiXG4gICAgICAgIChydW5Ub29sKT1cInJ1blRvb2wuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgKHRvb2xNb2RlbENoYW5nZSk9XCJ0b29sTW9kZWxDaGFuZ2UuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgKG9wZW5Ub29sUGFyYW1zKT1cIm9wZW5Ub29sUGFyYW1zLmVtaXQoJGV2ZW50KVwiXG4gICAgICA+XG4gICAgICA8L3Rvb2xiYXItc2VnbWVudGF0aW9uLXRvb2xzPlxuICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInRvb2xzLmhlbHBcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwidG9vbGJhci1zZXBhcmF0b3JcIj48L3NwYW4+XG5cbiAgICAgIDwhLS0gSGVscCAtLT5cbiAgICAgIDxwLWJ1dHRvblxuICAgICAgICBpY29uPVwicGkgcGktcXVlc3Rpb24tY2lyY2xlXCJcbiAgICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgICAgW3RleHRdPVwidHJ1ZVwiXG4gICAgICAgIGFyaWFMYWJlbD1cIkhlbHBcIlxuICAgICAgICBwVG9vbHRpcD1cIkhlbHBcIlxuICAgICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgICAgICAob25DbGljayk9XCJzaG93SGVscCgpXCJcbiAgICAgID5cbiAgICAgIDwvcC1idXR0b24+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvZGl2PlxuPC9wLXRvb2xiYXI+XG48dG9vbGJhci1oZWxwLWRpYWxvZ1xuICBbKHZpc2libGUpXT1cImRpc3BsYXlIZWxwRGlhbG9nXCJcbiAgW2NvbnRyaWJ1dGVkVG9vbHNdPVwiY29udHJpYnV0ZWRUb29sc1wiXG4gIFtkaWFsb2dUb29sc109XCJkaWFsb2dUb29sc1wiXG4+XG48L3Rvb2xiYXItaGVscC1kaWFsb2c+XG4iXX0=
@@ -0,0 +1,95 @@
1
+ import { takeUntil } from 'rxjs/operators';
2
+ /**
3
+ * The region set a spatial dataset's boundaries name (a 3D segmentation's cells, see
4
+ * `SpatialPolygonTilesMeta.sets`): the default set's when it names one, else the first that does.
5
+ */
6
+ export function datasetRegionSet(dataset) {
7
+ const tiles = dataset?.polygonTiles;
8
+ if (!tiles)
9
+ return null;
10
+ const named = tiles.sets.filter((s) => !!s.regionSource);
11
+ const set = named.find((s) => s.name === tiles.defaultSet) ?? named[0];
12
+ return set?.regionSource ?? null;
13
+ }
14
+ /**
15
+ * Whether `info` is the dataset's own image, the one its `imageRef` names. Exactly, when the host
16
+ * gives the image's id ({@link IImageInfo.imageId}); otherwise by the file name the id ends in (the
17
+ * host opens the image by that id, a path), which images of other datasets can share: then the link
18
+ * only takes an image that landed after the dataset was selected (see {@link SpatialRegionSetLink}).
19
+ * Not the reference volume's stack, which a dataset without an `imageRef` is drawn over: the region
20
+ * set's coordinates are not its pixels.
21
+ */
22
+ export function isDatasetImage(info, dataset) {
23
+ const id = dataset?.imageRef?.imageId;
24
+ if (!id || !info)
25
+ return false;
26
+ if (info.imageId)
27
+ return info.imageId === id;
28
+ const name = info.fileName;
29
+ if (!name)
30
+ return false;
31
+ return id === name || id.slice(id.lastIndexOf('/') + 1) === name;
32
+ }
33
+ /**
34
+ * Attaches a spatial dataset's region set to its image in the region editor, once both are there:
35
+ * the dataset (the port's) and its image, landed. Each time either changes it asks again; the
36
+ * target attaches once per image and set.
37
+ *
38
+ * An image that landed while another dataset was selected is not taken for this one by its file name,
39
+ * only by its id ({@link IImageInfo.imageId}): a host selects the dataset and then opens its image,
40
+ * and until that lands the image on screen is the previous dataset's, though its file name may be the
41
+ * same (every converted bundle's is `plate.ome.tif`). One that landed with no dataset selected may be.
42
+ */
43
+ export class SpatialRegionSetLink {
44
+ constructor(port, target) {
45
+ this.port = port;
46
+ this.target = target;
47
+ this.dataset = null;
48
+ this.image = null;
49
+ /** The dataset selected when the image landed (its id), or null: none was. */
50
+ this.imageDataset = null;
51
+ /** The region set last asked to be attached, until the dataset stops naming it. */
52
+ this.asked = null;
53
+ }
54
+ /** Follow the port's dataset until `until$` emits. */
55
+ bind(until$) {
56
+ this.port
57
+ ?.getDataset$()
58
+ .pipe(takeUntil(until$))
59
+ .subscribe((dataset) => {
60
+ this.dataset = dataset ?? null;
61
+ // Cleared, or another dataset that names another set (or none): the set attached for the
62
+ // last one is not this one's.
63
+ const id = datasetRegionSet(this.dataset);
64
+ if (this.asked && id !== this.asked) {
65
+ this.asked = null;
66
+ this.target.releaseDatasetRegionSet?.(id);
67
+ }
68
+ this.sync();
69
+ });
70
+ }
71
+ /** An image landed (its render settled): the dataset's own, perhaps. */
72
+ imageLanded(info) {
73
+ this.image = info;
74
+ this.imageDataset = this.dataset?.id ?? null;
75
+ this.sync();
76
+ }
77
+ /**
78
+ * Whether the landed image may be the dataset's: by its id when the host gives one, else only when
79
+ * it landed under this dataset or under none (see the class's note).
80
+ */
81
+ imageOf(dataset) {
82
+ if (!dataset || !isDatasetImage(this.image, dataset))
83
+ return false;
84
+ return !!this.image?.imageId || this.imageDataset === null || this.imageDataset === dataset.id;
85
+ }
86
+ sync() {
87
+ const port = this.port;
88
+ const id = datasetRegionSet(this.dataset);
89
+ if (!id || !port?.openRegionSet || !this.imageOf(this.dataset))
90
+ return;
91
+ this.asked = id;
92
+ void this.target.attachDatasetRegionSet?.(() => port.openRegionSet(id), id);
93
+ }
94
+ }
95
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhdGlhbC1yZWdpb24tc2V0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi92aXN1YWxpemVyL3NwYXRpYWwtcmVnaW9uLXNldC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFhM0M7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLGdCQUFnQixDQUFDLE9BQTBDO0lBQ3pFLE1BQU0sS0FBSyxHQUFHLE9BQU8sRUFBRSxZQUFZLENBQUM7SUFDcEMsSUFBSSxDQUFDLEtBQUs7UUFBRSxPQUFPLElBQUksQ0FBQztJQUN4QixNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUN6RCxNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDdkUsT0FBTyxHQUFHLEVBQUUsWUFBWSxJQUFJLElBQUksQ0FBQztBQUNuQyxDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxjQUFjLENBQzVCLElBQW1DLEVBQ25DLE9BQTBDO0lBRTFDLE1BQU0sRUFBRSxHQUFHLE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxDQUFDO0lBQ3RDLElBQUksQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDL0IsSUFBSSxJQUFJLENBQUMsT0FBTztRQUFFLE9BQU8sSUFBSSxDQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7SUFDN0MsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUMzQixJ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cnhqcyc7XG5pbXBvcnQgeyB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IElJbWFnZUluZm8gfSBmcm9tICcuLi9jb250cmFjdHMvaW1hZ2UuY29udHJhY3QnO1xuaW1wb3J0IHsgU3BhdGlhbERhdGFQb3J0IH0gZnJvbSAnLi4vY29udHJhY3RzL3BvcnRzL3NwYXRpYWwtZGF0YS5wb3J0JztcbmltcG9ydCB7IFNwYXRpYWxEYXRhc2V0IH0gZnJvbSAnLi4vY29udHJhY3RzL3NwYXRpYWwtZGF0YXNldC5jb250cmFjdCc7XG5pbXBvcnQgdHlwZSB7IFJlZ2lvblNvdXJjZU9wZW5lciB9IGZyb20gJy4uL3N0b3JlL3JlZ2lvbi1zb3VyY2Utc2NvcGUnO1xuXG4vKiogV2hhdCB7QGxpbmsgU3BhdGlhbFJlZ2lvblNldExpbmt9IGF0dGFjaGVzIGEgZGF0YXNldCdzIHJlZ2lvbiBzZXQgdGhyb3VnaCAodGhlIHJvdXRlcikuICovXG5leHBvcnQgaW50ZXJmYWNlIERhdGFzZXRSZWdpb25TZXRUYXJnZXQge1xuICBhdHRhY2hEYXRhc2V0UmVnaW9uU2V0PyhvcGVuOiBSZWdpb25Tb3VyY2VPcGVuZXIsIGtleTogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPjtcbiAgcmVsZWFzZURhdGFzZXRSZWdpb25TZXQ/KGtlZXA6IHN0cmluZyB8IG51bGwpOiB2b2lkO1xufVxuXG4vKipcbiAqIFRoZSByZWdpb24gc2V0IGEgc3BhdGlhbCBkYXRhc2V0J3MgYm91bmRhcmllcyBuYW1lIChhIDNEIHNlZ21lbnRhdGlvbidzIGNlbGxzLCBzZWVcbiAqIGBTcGF0aWFsUG9seWdvblRpbGVzTWV0YS5zZXRzYCk6IHRoZSBkZWZhdWx0IHNldCdzIHdoZW4gaXQgbmFtZXMgb25lLCBlbHNlIHRoZSBmaXJzdCB0aGF0IGRvZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkYXRhc2V0UmVnaW9uU2V0KGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0IHwgbnVsbCB8IHVuZGVmaW5lZCk6IHN0cmluZyB8IG51bGwge1xuICBjb25zdCB0aWxlcyA9IGRhdGFzZXQ/LnBvbHlnb25UaWxlcztcbiAgaWYgKCF0aWxlcykgcmV0dXJuIG51bGw7XG4gIGNvbnN0IG5hbWVkID0gdGlsZXMuc2V0cy5maWx0ZXIoKHMpID0+ICEhcy5yZWdpb25Tb3VyY2UpO1xuICBjb25zdCBzZXQgPSBuYW1lZC5maW5kKChzKSA9PiBzLm5hbWUgPT09IHRpbGVzLmRlZmF1bHRTZXQpID8/IG5hbWVkWzBdO1xuICByZXR1cm4gc2V0Py5yZWdpb25Tb3VyY2UgPz8gbnVsbDtcbn1cblxuLyoqXG4gKiBXaGV0aGVyIGBpbmZvYCBpcyB0aGUgZGF0YXNldCdzIG93biBpbWFnZSwgdGhlIG9uZSBpdHMgYGltYWdlUmVmYCBuYW1lcy4gRXhhY3RseSwgd2hlbiB0aGUgaG9zdFxuICogZ2l2ZXMgdGhlIGltYWdlJ3MgaWQgKHtAbGluayBJSW1hZ2VJbmZvLmltYWdlSWR9KTsgb3RoZXJ3aXNlIGJ5IHRoZSBmaWxlIG5hbWUgdGhlIGlkIGVuZHMgaW4gKHRoZVxuICogaG9zdCBvcGVucyB0aGUgaW1hZ2UgYnkgdGhhdCBpZCwgYSBwYXRoKSwgd2hpY2ggaW1hZ2VzIG9mIG90aGVyIGRhdGFzZXRzIGNhbiBzaGFyZTogdGhlbiB0aGUgbGlua1xuICogb25seSB0YWtlcyBhbiBpbWFnZSB0aGF0IGxhbmRlZCBhZnRlciB0aGUgZGF0YXNldCB3YXMgc2VsZWN0ZWQgKHNlZSB7QGxpbmsgU3BhdGlhbFJlZ2lvblNldExpbmt9KS5cbiAqIE5vdCB0aGUgcmVmZXJlbmNlIHZvbHVtZSdzIHN0YWNrLCB3aGljaCBhIGRhdGFzZXQgd2l0aG91dCBhbiBgaW1hZ2VSZWZgIGlzIGRyYXduIG92ZXI6IHRoZSByZWdpb25cbiAqIHNldCdzIGNvb3JkaW5hdGVzIGFyZSBub3QgaXRzIHBpeGVscy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRGF0YXNldEltYWdlKFxuICBpbmZvOiBJSW1hZ2VJbmZvIHwgbnVsbCB8IHVuZGVmaW5lZCxcbiAgZGF0YXNldDogU3BhdGlhbERhdGFzZXQgfCBudWxsIHwgdW5kZWZpbmVkLFxuKTogYm9vbGVhbiB7XG4gIGNvbnN0IGlkID0gZGF0YXNldD8uaW1hZ2VSZWY/LmltYWdlSWQ7XG4gIGlmICghaWQgfHwgIWluZm8pIHJldHVybiBmYWxzZTtcbiAgaWYgKGluZm8uaW1hZ2VJZCkgcmV0dXJuIGluZm8uaW1hZ2VJZCA9PT0gaWQ7XG4gIGNvbnN0IG5hbWUgPSBpbmZvLmZpbGVOYW1lO1xuICBpZiAoIW5hbWUpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIGlkID09PSBuYW1lIHx8IGlkLnNsaWNlKGlkLmxhc3RJbmRleE9mKCcvJykgKyAxKSA9PT0gbmFtZTtcbn1cblxuLyoqXG4gKiBBdHRhY2hlcyBhIHNwYXRpYWwgZGF0YXNldCdzIHJlZ2lvbiBzZXQgdG8gaXRzIGltYWdlIGluIHRoZSByZWdpb24gZWRpdG9yLCBvbmNlIGJvdGggYXJlIHRoZXJlOlxuICogdGhlIGRhdGFzZXQgKHRoZSBwb3J0J3MpIGFuZCBpdHMgaW1hZ2UsIGxhbmRlZC4gRWFjaCB0aW1lIGVpdGhlciBjaGFuZ2VzIGl0IGFza3MgYWdhaW47IHRoZVxuICogdGFyZ2V0IGF0dGFjaGVzIG9uY2UgcGVyIGltYWdlIGFuZCBzZXQuXG4gKlxuICogQW4gaW1hZ2UgdGhhdCBsYW5kZWQgd2hpbGUgYW5vdGhlciBkYXRhc2V0IHdhcyBzZWxlY3RlZCBpcyBub3QgdGFrZW4gZm9yIHRoaXMgb25lIGJ5IGl0cyBmaWxlIG5hbWUsXG4gKiBvbmx5IGJ5IGl0cyBpZCAoe0BsaW5rIElJbWFnZUluZm8uaW1hZ2VJZH0pOiBhIGhvc3Qgc2VsZWN0cyB0aGUgZGF0YXNldCBhbmQgdGhlbiBvcGVucyBpdHMgaW1hZ2UsXG4gKiBhbmQgdW50aWwgdGhhdCBsYW5kcyB0aGUgaW1hZ2Ugb24gc2NyZWVuIGlzIHRoZSBwcmV2aW91cyBkYXRhc2V0J3MsIHRob3VnaCBpdHMgZmlsZSBuYW1lIG1heSBiZSB0aGVcbiAqIHNhbWUgKGV2ZXJ5IGNvbnZlcnRlZCBidW5kbGUncyBpcyBgcGxhdGUub21lLnRpZmApLiBPbmUgdGhhdCBsYW5kZWQgd2l0aCBubyBkYXRhc2V0IHNlbGVjdGVkIG1heSBiZS5cbiAqL1xuZXhwb3J0IGNsYXNzIFNwYXRpYWxSZWdpb25TZXRMaW5rIHtcbiAgcHJpdmF0ZSBkYXRhc2V0OiBTcGF0aWFsRGF0YXNldCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGltYWdlOiBJSW1hZ2VJbmZvIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBUaGUgZGF0YXNldCBzZWxlY3RlZCB3aGVuIHRoZSBpbWFnZSBsYW5kZWQgKGl0cyBpZCksIG9yIG51bGw6IG5vbmUgd2FzLiAqL1xuICBwcml2YXRlIGltYWdlRGF0YXNldDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBUaGUgcmVnaW9uIHNldCBsYXN0IGFza2VkIHRvIGJlIGF0dGFjaGVkLCB1bnRpbCB0aGUgZGF0YXNldCBzdG9wcyBuYW1pbmcgaXQuICovXG4gIHByaXZhdGUgYXNrZWQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcG9ydDogU3BhdGlhbERhdGFQb3J0IHwgdW5kZWZpbmVkLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgdGFyZ2V0OiBEYXRhc2V0UmVnaW9uU2V0VGFyZ2V0LFxuICApIHt9XG5cbiAgLyoqIEZvbGxvdyB0aGUgcG9ydCdzIGRhdGFzZXQgdW50aWwgYHVudGlsJGAgZW1pdHMuICovXG4gIGJpbmQodW50aWwkOiBPYnNlcnZhYmxlPHVua25vd24+KTogdm9pZCB7XG4gICAgdGhpcy5wb3J0XG4gICAgICA/LmdldERhdGFzZXQkKClcbiAgICAgIC5waXBlKHRha2VVbnRpbCh1bnRpbCQpKVxuICAgICAgLnN1YnNjcmliZSgoZGF0YXNldCkgPT4ge1xuICAgICAgICB0aGlzLmRhdGFzZXQgPSBkYXRhc2V0ID8/IG51bGw7XG4gICAgICAgIC8vIENsZWFyZWQsIG9yIGFub3RoZXIgZGF0YXNldCB0aGF0IG5hbWVzIGFub3RoZXIgc2V0IChvciBub25lKTogdGhlIHNldCBhdHRhY2hlZCBmb3IgdGhlXG4gICAgICAgIC8vIGxhc3Qgb25lIGlzIG5vdCB0aGlzIG9uZSdzLlxuICAgICAgICBjb25zdCBpZCA9IGRhdGFzZXRSZWdpb25TZXQodGhpcy5kYXRhc2V0KTtcbiAgICAgICAgaWYgKHRoaXMuYXNrZWQgJiYgaWQgIT09IHRoaXMuYXNrZWQpIHtcbiAgICAgICAgICB0aGlzLmFza2VkID0gbnVsbDtcbiAgICAgICAgICB0aGlzLnRhcmdldC5yZWxlYXNlRGF0YXNldFJlZ2lvblNldD8uKGlkKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN5bmMoKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqIEFuIGltYWdlIGxhbmRlZCAoaXRzIHJlbmRlciBzZXR0bGVkKTogdGhlIGRhdGFzZXQncyBvd24sIHBlcmhhcHMuICovXG4gIGltYWdlTGFuZGVkKGluZm86IElJbWFnZUluZm8pOiB2b2lkIHtcbiAgICB0aGlzLmltYWdlID0gaW5mbztcbiAgICB0aGlzLmltYWdlRGF0YXNldCA9IHRoaXMuZGF0YXNldD8uaWQgPz8gbnVsbDtcbiAgICB0aGlzLnN5bmMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBsYW5kZWQgaW1hZ2UgbWF5IGJlIHRoZSBkYXRhc2V0J3M6IGJ5IGl0cyBpZCB3aGVuIHRoZSBob3N0IGdpdmVzIG9uZSwgZWxzZSBvbmx5IHdoZW5cbiAgICogaXQgbGFuZGVkIHVuZGVyIHRoaXMgZGF0YXNldCBvciB1bmRlciBub25lIChzZWUgdGhlIGNsYXNzJ3Mgbm90ZSkuXG4gICAqL1xuICBwcml2YXRlIGltYWdlT2YoZGF0YXNldDogU3BhdGlhbERhdGFzZXQgfCBudWxsKTogYm9vbGVhbiB7XG4gICAgaWYgKCFkYXRhc2V0IHx8ICFpc0RhdGFzZXRJbWFnZSh0aGlzLmltYWdlLCBkYXRhc2V0KSkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiAhIXRoaXMuaW1hZ2U/LmltYWdlSWQgfHwgdGhpcy5pbWFnZURhdGFzZXQgPT09IG51bGwgfHwgdGhpcy5pbWFnZURhdGFzZXQgPT09IGRhdGFzZXQuaWQ7XG4gIH1cblxuICBwcml2YXRlIHN5bmMoKTogdm9pZCB7XG4gICAgY29uc3QgcG9ydCA9IHRoaXMucG9ydDtcbiAgICBjb25zdCBpZCA9IGRhdGFzZXRSZWdpb25TZXQodGhpcy5kYXRhc2V0KTtcbiAgICBpZiAoIWlkIHx8ICFwb3J0Py5vcGVuUmVnaW9uU2V0IHx8ICF0aGlzLmltYWdlT2YodGhpcy5kYXRhc2V0KSkgcmV0dXJuO1xuICAgIHRoaXMuYXNrZWQgPSBpZDtcbiAgICB2b2lkIHRoaXMudGFyZ2V0LmF0dGFjaERhdGFzZXRSZWdpb25TZXQ/LigoKSA9PiBwb3J0Lm9wZW5SZWdpb25TZXQhKGlkKSwgaWQpO1xuICB9XG59XG4iXX0=