@jax-data-science/sci-image-visualizer 0.9.0 → 0.11.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 (149) hide show
  1. package/esm2022/index.mjs +10 -1
  2. package/esm2022/lib/contracts/image.contract.mjs +1 -1
  3. package/esm2022/lib/contracts/ports/region-io.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/section-view.contract.mjs +2 -0
  7. package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
  8. package/esm2022/lib/contracts/viz-config.mjs +1 -1
  9. package/esm2022/lib/geometry/loft.mjs +128 -0
  10. package/esm2022/lib/geometry/polylabel.mjs +156 -0
  11. package/esm2022/lib/geometry/reconstruct.mjs +315 -0
  12. package/esm2022/lib/geometry/reslice-image.mjs +57 -0
  13. package/esm2022/lib/geometry/section.mjs +215 -0
  14. package/esm2022/lib/implementations/napari-js/napari-loading-badge.mjs +11 -7
  15. package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +20 -3
  16. package/esm2022/lib/implementations/napari-js/napari-region-mesh-pointer.mjs +100 -0
  17. package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +28 -5
  18. package/esm2022/lib/implementations/napari-js/napari-scene.mjs +1 -1
  19. package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +9 -2
  20. package/esm2022/lib/implementations/napari-js/napari-tool-bridge.mjs +5 -2
  21. package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +81 -1
  22. package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +129 -0
  23. package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +115 -4
  24. package/esm2022/lib/implementations/napari-js/napari-volume-slice-planes.mjs +103 -0
  25. package/esm2022/lib/implementations/napari-js/region-overlay/region-svg-renderer.mjs +15 -3
  26. package/esm2022/lib/implementations/osd/openseadragon-viewer-options.mjs +18 -2
  27. package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +9 -1
  28. package/esm2022/lib/implementations/osd/osd-region-overlay-draw.mjs +18 -7
  29. package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +38 -8
  30. package/esm2022/lib/implementations/osd/osd-tile-loading.mjs +71 -0
  31. package/esm2022/lib/implementations/osd/osd-viewer-like.mjs +1 -1
  32. package/esm2022/lib/implementations/osd/slice-cache.mjs +35 -6
  33. package/esm2022/lib/implementations/tile-server/tile-protocol.mjs +1 -1
  34. package/esm2022/lib/models/class-preset.mjs +1 -1
  35. package/esm2022/lib/models/polygon-factory.mjs +17 -1
  36. package/esm2022/lib/models/region-geojson.mjs +44 -6
  37. package/esm2022/lib/models/region.mjs +1 -1
  38. package/esm2022/lib/region-editor/class-tree/class-tree.component.mjs +156 -0
  39. package/esm2022/lib/region-editor/class-tree/class-tree.mjs +108 -0
  40. package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +77 -13
  41. package/esm2022/lib/region-editor/region-editor.component.mjs +670 -42
  42. package/esm2022/lib/region-editor/region-metrics.mjs +20 -2
  43. package/esm2022/lib/region-editor/region-persistence.service.mjs +44 -10
  44. package/esm2022/lib/region-editor/region-table/region-table.component.mjs +24 -8
  45. package/esm2022/lib/region-import/label-classes.mjs +149 -0
  46. package/esm2022/lib/region-import/label-volume.mjs +194 -0
  47. package/esm2022/lib/region-import/region-import.mjs +71 -0
  48. package/esm2022/lib/region-overlay/region-geometry.mjs +3 -3
  49. package/esm2022/lib/region-overlay/region-source-layer.mjs +378 -0
  50. package/esm2022/lib/region-overlay/region-style.mjs +97 -0
  51. package/esm2022/lib/region-source/http-region-source.mjs +104 -0
  52. package/esm2022/lib/region-source/region-source-ops.mjs +53 -0
  53. package/esm2022/lib/region-source/region-source-worker.mjs +10 -0
  54. package/esm2022/lib/region-source/region-source.mjs +67 -0
  55. package/esm2022/lib/region-source/region-tiles.mjs +708 -0
  56. package/esm2022/lib/region-source/worker-region-source.mjs +229 -0
  57. package/esm2022/lib/routing-visualizer.service.mjs +510 -22
  58. package/esm2022/lib/section-pane/section-pane.component.mjs +299 -0
  59. package/esm2022/lib/store/class-color.util.mjs +10 -5
  60. package/esm2022/lib/store/class-signatures.mjs +63 -0
  61. package/esm2022/lib/store/region-scope-cache.mjs +5 -1
  62. package/esm2022/lib/store/region-source-scope.mjs +186 -0
  63. package/esm2022/lib/store/region-store.service.mjs +774 -12
  64. package/esm2022/lib/store/visualizer-store.service.mjs +33 -6
  65. package/esm2022/lib/toolbar/region-tools/region-tools.component.mjs +8 -2
  66. package/esm2022/lib/toolbar/stack-controls/stack-controls.component.mjs +55 -15
  67. package/esm2022/lib/toolbar/toolbar.component.mjs +19 -5
  68. package/esm2022/lib/visualizer/region-load.mjs +67 -4
  69. package/esm2022/lib/visualizer/volume-sections.mjs +175 -0
  70. package/esm2022/lib/visualizer.component.mjs +155 -7
  71. package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BELcx0jv.mjs} +9851 -2904
  72. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BELcx0jv.mjs.map +1 -0
  73. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-DEDSm_NL.mjs} +4 -4
  74. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-DEDSm_NL.mjs.map} +1 -1
  75. package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs +12 -0
  76. package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs.map +1 -0
  77. package/fesm2022/jax-data-science-sci-image-visualizer.mjs +3 -3
  78. package/fesm2022/region-source.worker.js +1067 -0
  79. package/index.d.ts +12 -0
  80. package/lib/contracts/image.contract.d.ts +4 -0
  81. package/lib/contracts/ports/region-io.port.d.ts +24 -0
  82. package/lib/contracts/region-editor-api.contract.d.ts +102 -0
  83. package/lib/contracts/region-store.contract.d.ts +22 -0
  84. package/lib/contracts/section-view.contract.d.ts +44 -0
  85. package/lib/contracts/visualizer.contract.d.ts +10 -0
  86. package/lib/contracts/viz-config.d.ts +8 -0
  87. package/lib/geometry/loft.d.ts +22 -0
  88. package/lib/geometry/polylabel.d.ts +23 -0
  89. package/lib/geometry/reconstruct.d.ts +54 -0
  90. package/lib/geometry/reslice-image.d.ts +33 -0
  91. package/lib/geometry/section.d.ts +52 -0
  92. package/lib/implementations/napari-js/napari-loading-badge.d.ts +4 -2
  93. package/lib/implementations/napari-js/napari-loading-state.d.ts +8 -1
  94. package/lib/implementations/napari-js/napari-region-mesh-pointer.d.ts +32 -0
  95. package/lib/implementations/napari-js/napari-region-overlay.d.ts +6 -1
  96. package/lib/implementations/napari-js/napari-scene.d.ts +33 -0
  97. package/lib/implementations/napari-js/napari-spatial-hover.d.ts +3 -1
  98. package/lib/implementations/napari-js/napari-visualizer.service.d.ts +48 -0
  99. package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +66 -0
  100. package/lib/implementations/napari-js/napari-volume-scene.d.ts +45 -1
  101. package/lib/implementations/napari-js/napari-volume-slice-planes.d.ts +43 -0
  102. package/lib/implementations/osd/openseadragon-viewer-options.d.ts +2 -0
  103. package/lib/implementations/osd/openseadragon-visualizer.service.d.ts +2 -0
  104. package/lib/implementations/osd/osd-region-overlay-draw.d.ts +4 -3
  105. package/lib/implementations/osd/osd-region-overlay.d.ts +10 -3
  106. package/lib/implementations/osd/osd-tile-loading.d.ts +43 -0
  107. package/lib/implementations/osd/osd-viewer-like.d.ts +14 -0
  108. package/lib/implementations/osd/slice-cache.d.ts +13 -3
  109. package/lib/implementations/tile-server/tile-protocol.d.ts +3 -0
  110. package/lib/models/class-preset.d.ts +7 -0
  111. package/lib/models/polygon-factory.d.ts +5 -0
  112. package/lib/models/region-geojson.d.ts +40 -0
  113. package/lib/models/region.d.ts +19 -0
  114. package/lib/region-editor/class-tree/class-tree.component.d.ts +78 -0
  115. package/lib/region-editor/class-tree/class-tree.d.ts +31 -0
  116. package/lib/region-editor/classes-panel/classes-panel.component.d.ts +36 -6
  117. package/lib/region-editor/region-editor.component.d.ts +159 -17
  118. package/lib/region-editor/region-metrics.d.ts +8 -0
  119. package/lib/region-editor/region-persistence.service.d.ts +17 -5
  120. package/lib/region-editor/region-table/region-table.component.d.ts +10 -4
  121. package/lib/region-import/label-classes.d.ts +39 -0
  122. package/lib/region-import/label-volume.d.ts +31 -0
  123. package/lib/region-import/region-import.d.ts +46 -0
  124. package/lib/region-overlay/region-geometry.d.ts +4 -3
  125. package/lib/region-overlay/region-source-layer.d.ts +96 -0
  126. package/lib/region-overlay/region-style.d.ts +52 -0
  127. package/lib/region-source/http-region-source.d.ts +45 -0
  128. package/lib/region-source/region-source-ops.d.ts +89 -0
  129. package/lib/region-source/region-source-worker.d.ts +7 -0
  130. package/lib/region-source/region-source.d.ts +82 -0
  131. package/lib/region-source/region-tiles.d.ts +289 -0
  132. package/lib/region-source/worker-region-source.d.ts +65 -0
  133. package/lib/routing-visualizer.service.d.ts +168 -1
  134. package/lib/section-pane/section-pane.component.d.ts +47 -0
  135. package/lib/store/class-color.util.d.ts +6 -3
  136. package/lib/store/class-signatures.d.ts +11 -0
  137. package/lib/store/region-scope-cache.d.ts +2 -0
  138. package/lib/store/region-source-scope.d.ts +74 -0
  139. package/lib/store/region-store.service.d.ts +216 -2
  140. package/lib/store/visualizer-store.service.d.ts +10 -0
  141. package/lib/toolbar/region-tools/region-tools.component.d.ts +3 -1
  142. package/lib/toolbar/stack-controls/stack-controls.component.d.ts +20 -9
  143. package/lib/toolbar/toolbar.component.d.ts +9 -2
  144. package/lib/visualizer/region-load.d.ts +23 -4
  145. package/lib/visualizer/volume-sections.d.ts +64 -0
  146. package/lib/visualizer.component.d.ts +40 -0
  147. package/package.json +2 -2
  148. package/src/lib/assets/slice.svg +23 -0
  149. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs.map +0 -1
@@ -62,6 +62,10 @@ export class ToolbarComponent {
62
62
  * controls — flipping that would show 2D pan/zoom and hide the orbit controls.
63
63
  */
64
64
  this.is3dRegions = false;
65
+ /** A napari volume / isosurface view: the Region Editor (regions in 3D) without drawing tools. */
66
+ this.isVolumeView = false;
67
+ /** Whether the volume view is split with the slice editor (the slice, with every region tool). */
68
+ this.sliceEditor = false;
65
69
  /** The armed tool's mode (zoom, pan, a drawing tool, `samPoint`, …), or null. */
66
70
  this.activeDragMode = null;
67
71
  /** The 3D camera mode (`turntable` / `orbit` / …). */
@@ -127,6 +131,8 @@ export class ToolbarComponent {
127
131
  this.openSpatialControls = new EventEmitter();
128
132
  /** Open the Region Editor dialog. */
129
133
  this.openRegionEditor = new EventEmitter();
134
+ /** Split the volume view with the slice editor, or close it. */
135
+ this.toggleSliceEditor = new EventEmitter();
130
136
  /** A single-image / stack choice was picked. */
131
137
  this.selectStackOption = new EventEmitter();
132
138
  /** The live slice scrubber moved (fires while dragging). */
@@ -220,9 +226,11 @@ export class ToolbarComponent {
220
226
  * view, the napari-js WebGPU image, the napari-js surface — which rebuilds the height field
221
227
  * from the picked slice (jit-ui#102) — and the 2D spatial-omics view, where a 3D dataset's
222
228
  * registered volume is the image and the slider picks the section whose observations are
223
- * drawn. Drives the per-slice slider. */
229
+ * drawn. Also a split volume view, whose slice editor shows the slice picked. Drives the
230
+ * per-slice slider. */
224
231
  get showsLiveSliceScrubber() {
225
- return (this.effectivePlotType === PlotType.IMAGE ||
232
+ return ((this.isVolumeView && this.sliceEditor) ||
233
+ this.effectivePlotType === PlotType.IMAGE ||
226
234
  this.effectivePlotType === PlotType.NAPARI_IMAGE ||
227
235
  isNapariSurface(this.effectivePlotType) ||
228
236
  isNapariScatter(this.effectivePlotType) ||
@@ -256,7 +264,7 @@ export class ToolbarComponent {
256
264
  this.displayHelpDialog = true;
257
265
  }
258
266
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: ToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
259
- 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", 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", 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 [isNapariMode]=\"isNapariMode\"\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 <ng-container *ngIf=\"(isHeatmap || is3dRegions) && tools.regionTools\">\n <toolbar-region-tools\n [activeDragMode]=\"activeDragMode\"\n [is3dRegions]=\"is3dRegions\"\n [vertexTools]=\"supportsRegionVertexTools\"\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", "isNapariMode", "isNapariSurfaceMode", "isNapari3dMode", "axesVisible", "wireframeActive", "resolutionScale"], outputs: ["toggleDragMode", "zoomIn", "zoomOut", "toggleSurface3dMode", "resetSurfaceCamera", "toggleAxes", "toggleWireframe", "selectResolution"] }, { kind: "component", type: RegionToolsComponent, selector: "toolbar-region-tools", inputs: ["activeDragMode", "is3dRegions", "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 }); }
267
+ 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 [isNapariMode]=\"isNapariMode\"\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", "isNapariMode", "isNapariSurfaceMode", "isNapari3dMode", "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 }); }
260
268
  }
261
269
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: ToolbarComponent, decorators: [{
262
270
  type: Component,
@@ -272,7 +280,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
272
280
  ViewControlsComponent,
273
281
  RegionToolsComponent,
274
282
  SegmentationToolsComponent,
275
- ], 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 [isNapariMode]=\"isNapariMode\"\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 <ng-container *ngIf=\"(isHeatmap || is3dRegions) && tools.regionTools\">\n <toolbar-region-tools\n [activeDragMode]=\"activeDragMode\"\n [is3dRegions]=\"is3dRegions\"\n [vertexTools]=\"supportsRegionVertexTools\"\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"] }]
283
+ ], 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 [isNapariMode]=\"isNapariMode\"\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"] }]
276
284
  }], propDecorators: { imageInfo: [{
277
285
  type: Input
278
286
  }], hasSpatialDataset: [{
@@ -293,6 +301,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
293
301
  type: Input
294
302
  }], is3dRegions: [{
295
303
  type: Input
304
+ }], isVolumeView: [{
305
+ type: Input
306
+ }], sliceEditor: [{
307
+ type: Input
296
308
  }], activeDragMode: [{
297
309
  type: Input
298
310
  }], activeSurface3dMode: [{
@@ -345,6 +357,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
345
357
  type: Output
346
358
  }], openRegionEditor: [{
347
359
  type: Output
360
+ }], toggleSliceEditor: [{
361
+ type: Output
348
362
  }], selectStackOption: [{
349
363
  type: Output
350
364
  }], zScrub: [{
@@ -402,4 +416,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
402
416
  }], vertexEraserRadiusChange: [{
403
417
  type: Output
404
418
  }] } });
405
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbGJhci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3Rvb2xiYXIvdG9vbGJhci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9zcmMvbGliL3Rvb2xiYXIvdG9vbGJhci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2hHLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFHaEQsT0FBTyxFQUNMLFFBQVEsRUFFUixpQkFBaUIsRUFDakIsVUFBVSxFQUNWLGtCQUFrQixFQUNsQixlQUFlLEVBQ2YsZUFBZSxFQUNmLHVCQUF1QixFQUN2QixjQUFjLEVBQ2QsZ0JBQWdCLEdBQ2pCLE1BQU0sd0JBQXdCLENBQUM7QUFDaEMsT0FBTyxFQUF5QixpQkFBaUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBR3ZGLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLHFEQUFxRCxDQUFDO0FBQ2pHLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLG1EQUFtRCxDQUFDO0FBQzlGLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLDJDQUEyQyxDQUFDO0FBQ25GLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHlDQUF5QyxDQUFDO0FBQ2hGLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHVDQUF1QyxDQUFD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O3NCQUF0QixNQUFNO2dCQUVHLGFBQWE7c0JBQXRCLE1BQU07Z0JBRUcsY0FBYztzQkFBdkIsTUFBTTtnQkFFRyxjQUFjO3NCQUF2QixNQUFNO2dCQUVHLE1BQU07c0JBQWYsTUFBTTtnQkFFRyxPQUFPO3NCQUFoQixNQUFNO2dCQUVHLG1CQUFtQjtzQkFBNUIsTUFBTTtnQkFFRyxrQkFBa0I7c0JBQTNCLE1BQU07Z0JBRUcsVUFBVTtzQkFBbkIsTUFBTTtnQkFFRyxlQUFlO3NCQUF4QixNQUFNO2dCQUVHLGdCQUFnQjtzQkFBekIsTUFBTTtnQkFFRyxZQUFZO3NCQUFyQixNQUFNO2dCQUVHLFVBQVU7c0JBQW5CLE1BQU07Z0JBRUcsVUFBVTtzQkFBbkIsTUFBTTtnQkFFRyxjQUFjO3NCQUF2QixNQUFNO2dCQUVHLGVBQWU7c0JBQXhCLE1BQU07Z0JBRUcsT0FBTztzQkFBaEIsTUFBTTtnQkFFRyxnQkFBZ0I7c0JBQXpCLE1BQU07Z0JBRUcsZUFBZTtzQkFBeEIsTUFBTTtnQkFFRyxjQUFjO3NCQUF2QixNQUFNO2dCQUVHLGNBQWM7c0JBQXZCLE1BQU07Z0JBRUcscUJBQXFCO3NCQUE5QixNQUFNO2dCQUVHLGVBQWU7c0JBQXhCLE1BQU07Z0JBRUcsd0JBQXdCO3NCQUFqQyxNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQnV0dG9uTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9idXR0b24nO1xuaW1wb3J0IHsgUmlwcGxlTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9yaXBwbGUnO1xuaW1wb3J0IHsgVG9vbGJhck1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvdG9vbGJhcic7XG5pbXBvcnQgeyBUb29sdGlwTW9kdWxlIH0gZnJvbSAncHJpbWVuZy90b29sdGlwJztcblxuaW1wb3J0IHsgSUltYWdlSW5mbyB9IGZyb20gJy4uL2NvbnRyYWN0cy9pbWFnZS5jb250cmFjdCc7XG5pbXBvcnQge1xuICBQbG90VHlwZSxcbiAgUGxvdFR5cGVJZCxcbiAgaXNCdWlsdGluUGxvdFR5cGUsXG4gIGlzTmFwYXJpM2QsXG4gIGlzTmFwYXJpSXNvc3VyZmFjZSxcbiAgaXNOYXBhcmlTdXJmYWNlLFxuICBpc05hcGFyaVNjYXR0ZXIsXG4gIE5BUEFSSV9ERUZBVUxUX0RFQ0lNQVRFLFxuICBpc1NwYXRpYWxPbWljcyxcbiAgaXNTcGF0aWFsT21pY3MzZCxcbn0gZnJvbSAnLi4vY29udHJhY3RzL3Bsb3QtdHlwZSc7XG5pbXBvcnQgeyBUb29sYmFyVG9vbFZpc2liaWxpdHksIEFMTF9UT09MQkFSX1RPT0xTIH0gZnJvbSAnLi4vY29udHJhY3RzL3Rvb2xiYXItY29uZmlnJztcbmltcG9ydCB7IFRvb2xiYXJEaWFsb2dUb29sQ29udHJpYnV0aW9uLCBUb29sYmFyVG9vbENvbnRyaWJ1dGlvbiB9IGZyb20gJy4uL2NvbnRyYWN0cy90b29sYmFyLXRvb2wuY29udHJhY3QnO1xuaW1wb3J0IHsgUGxvdFR5cGVPcHRpb24gfSBmcm9tICcuLi9jb250cmFjdHMvcGxvdC10eXBlLWNvbnRyaWJ1dGlvbi5jb250cmFjdCc7XG5pbXBvcnQgeyBUb29sYmFySGVscERpYWxvZ0NvbXBvbmVudCB9IGZyb20gJy4vdG9vbGJhci1oZWxwLWRpYWxvZy90b29sYmFyLWhlbHAtZGlhbG9nLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBQbG90VHlwZVNlbGVjdG9yQ29tcG9uZW50IH0gZnJvbSAnLi9wbG90LXR5cGUtc2VsZWN0b3IvcGxvdC10eXBlLXNlbGVjdG9yLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTdGFja0NvbnRyb2xzQ29tcG9uZW50IH0gZnJvbSAnLi9zdGFjay1jb250cm9scy9zdGFjay1jb250cm9scy5jb21wb25lbnQnO1xuaW1wb3J0IHsgVmlld0NvbnRyb2xzQ29tcG9uZW50IH0gZnJvbSAnLi92aWV3LWNvbnRyb2xzL3ZpZXctY29udHJvbHMuY29tcG9uZW50JztcbmltcG9ydCB7IFJlZ2lvblRvb2xzQ29tcG9uZW50IH0gZnJvbSAnLi9yZWdpb24tdG9vbHMvcmVnaW9uLXRvb2xzLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTZWdtZW50YXRpb25Ub29sc0NvbXBvbmVudCB9IGZyb20gJy4vc2VnbWVudGF0aW9uLXRvb2xzL3NlZ21lbnRhdGlvbi10b29scy5jb21wb25lbnQnO1xuXG4vKipcbiAqIFByZXNlbnRhdGlvbmFsIHRvb2xiYXIgZm9yIHRoZSBwbG90dGluZyB2aWV3cG9ydC5cbiAqXG4gKiBSZW5kZXJzIHRoZSBwbG90LXR5cGUgc2VsZWN0b3IsIGNvbG9ybWFwL0xVVCBjb250cm9scywgc3RhY2sgbmF2aWdhdGlvbixcbiAqIGltYWdlIGFjdGlvbnMgKGRvd25sb2FkIC8gYXV0b3NjYWxlIC8gcGlwZWxpbmUpLCB2aWV3cG9ydCB6b29tL3BhbiwgdGhlXG4gKiBTdXJmYWNlLTNEIGNhbWVyYSBjb250cm9scywgYW5kIHRoZSByZWdpb24tZHJhd2luZyB0b29scyDigJQgcGx1cyB0aGUgcGxvdHRpbmdcbiAqIGhlbHAgZGlhbG9nLiBJdCBvd25zIG5vIHJlbmRlcmluZyBvciB2aXN1YWxpemF0aW9uIHN0YXRlOiB0aGUgaG9zdFxuICogKFZpc3VhbGl6ZXJDb21wb25lbnQpIHN0YXlzIHRoZSBvcmNoZXN0cmF0b3IsIHBhc3Npbmcgc3RhdGUgaW4gdmlhIGBASW5wdXRgIGFuZFxuICogaGFuZGxpbmcgZXZlcnkgYWN0aW9uIHZpYSBgQE91dHB1dGAuIFRoZSBzYW1lIGFjdGlvbnMgYXJlIGFsc28gZHJpdmVuIGJ5IHRoZVxuICogZGlhZ3JhbSdzIHJpZ2h0LWNsaWNrIGNvbnRleHQgbWVudSBhbmQga2V5Ym9hcmQgc2hvcnRjdXRzLCBzbyBrZWVwaW5nIHRoZVxuICogaGFuZGxlcnMgaW4gdGhlIGhvc3QgYXZvaWRzIGR1cGxpY2F0aW5nIHRoYXQgbG9naWMuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3Bsb3R0aW5nLXRvb2xiYXInLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlLFxuICAgIEJ1dHRvbk1vZHVsZSxcbiAgICBSaXBwbGVNb2R1bGUsXG4gICAgVG9vbGJhck1vZHVsZSxcbiAgICBUb29sdGlwTW9kdWxlLFxuICAgIFRvb2xiYXJIZWxwRGlhbG9nQ29tcG9uZW50LFxuICAgIFBsb3RUeXBlU2VsZWN0b3JDb21wb25lbnQsXG4gICAgU3RhY2tDb250cm9sc0NvbXBvbmVudCxcbiAgICBWaWV3Q29udHJvbHNDb21wb25lbnQsXG4gICAgUmVnaW9uVG9vbHNDb21wb25lbnQsXG4gICAgU2VnbWVudGF0aW9uVG9vbHNDb21wb25lbnQsXG4gIF0sXG4gIHRlbXBsYXRlVXJsOiAnLi90b29sYmFyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vdG9vbGJhci5jb21wb25lbnQuc2NzcyddLFxuICAvLyBQdXJlbHkgQElucHV0L0BPdXRwdXQ6IHJlLWNoZWNrIG9ubHkgd2hlbiBhbiBpbnB1dCBjaGFuZ2VzIG9yIHRoZSB0b29sYmFyXG4gIC8vIGl0c2VsZiBoYW5kbGVzIGFuIGV2ZW50LCBub3Qgb24gZXZlcnkgYXBwIHRpY2sgKGl0cyB+MTUgZ2V0dGVycyByYW4gZWFjaFxuICAvLyB0aW1lKS4gQ29udHJvbHMgYmluZCBbbmdNb2RlbF0gb25lLXdheSBhbmQgcmVwb3J0IHRocm91Z2ggdGhlIG91dHB1dHMsIHNvXG4gIC8vIHRoZSBob3N0IHN0YXlzIHRoZSBvd25lciBvZiBldmVyeSB2YWx1ZSAoUlQtMzUpLlxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgVG9vbGJhckNvbXBvbmVudCB7XG4gIC8qKiBDdXJyZW50IGltYWdlIChnYXRlcyB3aGljaCBjb250cm9sIGdyb3VwcyBhcmUgc2hvd24pLiAqL1xuICBASW5wdXQoKSBpbWFnZUluZm86IElJbWFnZUluZm8gfCB1bmRlZmluZWQ7XG4gIC8qKiBBIHNwYXRpYWwgZGF0YXNldCBpcyBvbiBvZmZlcjogaXRzIHBsb3QgbW9kZXMgYXJlIGEgY2hvaWNlIGV2ZW4gd2l0aCBubyBpbWFnZSBsb2FkZWQuICovXG4gIEBJbnB1dCgpIGhhc1NwYXRpYWxEYXRhc2V0ID0gZmFsc2U7XG5cbiAgLyoqIFdoZXRoZXIgdGhlIHBsb3QtdHlwZSBkcm9wZG93biBzaG93czogZm9yIGFuIGltYWdlLCBvciBhIHNwYXRpYWwgZGF0YXNldCB3aXRoIG5vbmUuICovXG4gIHByb3RlY3RlZCBnZXQgc2hvd1Bsb3RUeXBlcygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISEodGhpcy5pbWFnZUluZm8gfHwgdGhpcy5oYXNTcGF0aWFsRGF0YXNldCkgJiYgISF0aGlzLnRvb2xzLnNwZWNpYWxUb29scztcbiAgfVxuICAvKiogUGxvdCB0eXBlcyB0aGUgYWN0aXZlIGJhY2tlbmQgYWR2ZXJ0aXNlcywgdGhlbiBhbnkgY29udHJpYnV0ZWQgbW9kZXMuICovXG4gIEBJbnB1dCgpIHBsb3RUeXBlT3B0aW9uczogUGxvdFR5cGVPcHRpb25bXSA9IFtdO1xuICAvKiogVGhlIHNlbGVjdG9yJ3MgdmFsdWU6IGEgYnVpbHQtaW4gdHlwZSBvciBhIGNvbnRyaWJ1dGVkIG1vZGUncyBpZC4gKi9cbiAgQElucHV0KCkgc2VsZWN0ZWRQbG90VHlwZTogUGxvdFR5cGVJZCA9IFBsb3RUeXBlLklNQUdFO1xuICAvKipcbiAgICogVGhlIGJ1aWx0LWluIHR5cGUgdGhhdCByZW5kZXJzIHtAbGluayBzZWxlY3RlZFBsb3RUeXBlfSDigJQgaXRzIGBiYXNlVHlwZWBcbiAgICogZm9yIGEgY29udHJpYnV0ZWQgbW9kZS4gRXZlcnkgdG9vbC9jb250cm9sIGRlY2lzaW9uIGJlbG93IHJlYWRzXG4gICAqIHtAbGluayBlZmZlY3RpdmVQbG90VHlwZX0sIHNvIGEgY29udHJpYnV0ZWQgbW9kZSBnZXRzIGV4YWN0bHkgaXRzIGJhc2VcbiAgICogdHlwZSdzIHRvb2xiYXIuIFdoZW4gdW5ib3VuZCwgYSBidWlsdC1pbiBzZWxlY3Rpb24gaXMgaXRzIG93biBiYXNlIGFuZFxuICAgKiBhbnl0aGluZyBlbHNlIGlzIHRyZWF0ZWQgYXMgdGhlIGRlZmF1bHQgSW1hZ2Ugdmlldy5cbiAgICovXG4gIEBJbnB1dCgpIGJhc2VQbG90VHlwZTogUGxvdFR5cGUgfCBudWxsID0gbnVsbDtcbiAgLyoqIElzb3N1cmZhY2UgYmFuZCBhcyBhIDDigJMyNTUgc2xpZGVyIHBvc2l0aW9uIChtYXBwZWQgb250byB0aGUgdm9sdW1lJ3MgcmVhbFxuICAgKiAgaW50ZW5zaXR5IHJhbmdlIGJ5IHRoZSByZW5kZXJlcikuIERlZmF1bHRzIHRvIHRoZSBmdWxsIHJhbmdlLiAqL1xuICBASW5wdXQoKSBpc29SYW5nZTogbnVtYmVyW10gPSBbMCwgMjU1XTtcbiAgLyoqIFRoZSBsYXN0IHNsaWNlIGluZGV4IG9mIGEgc3RhY2suICovXG4gIEBJbnB1dCgpIG1heEluZGV4ID0gMDtcbiAgLyoqIFRoZSBjdXJyZW50IHNsaWNlICgwLWJhc2VkKS4gKi9cbiAgQElucHV0KCkgekluZGV4ID0gMDtcbiAgLyoqIFRydWUgZm9yIGFueSAyRCAobm9uIFN1cmZhY2UtM0QpIHBsb3QgdHlwZS4gKi9cbiAgQElucHV0KCkgaXNIZWF0bWFwID0gdHJ1ZTtcbiAgLyoqXG4gICAqIFJlZ2lvbiB0b29scyBhcHBseSBldmVuIHRob3VnaCB0aGlzIGlzIGEgM0QgdmlldywgYmVjYXVzZSB0aGV5IGRyYXcgYVxuICAgKiBTQ1JFRU4tU1BBQ0UgbGFzc28gKHRoZSAzRCBzcGF0aWFsIGNsb3VkKS4gU2VwYXJhdGUgZnJvbSB7QGxpbmsgaXNIZWF0bWFwfSxcbiAgICogd2hpY2ggbWVhbnMgXCIyRCB2aWV3XCIgYW5kIGFsc28gZHJpdmVzIHRoZSB6b29tIHRvb2xzIGFuZCB0aGUgM0QgY2FtZXJhXG4gICAqIGNvbnRyb2xzIOKAlCBmbGlwcGluZyB0aGF0IHdvdWxkIHNob3cgMkQgcGFuL3pvb20gYW5kIGhpZGUgdGhlIG9yYml0IGNvbnRyb2xzLlxuICAgKi9cbiAgQElucHV0KCkgaXMzZFJlZ2lvbnMgPSBmYWxzZTtcbiAgLyoqIFRoZSBhcm1lZCB0b29sJ3MgbW9kZSAoem9vbSwgcGFuLCBhIGRyYXdpbmcgdG9vbCwgYHNhbVBvaW50YCwg4oCmKSwgb3IgbnVsbC4gKi9cbiAgQElucHV0KCkgYWN0aXZlRHJhZ01vZGU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICAvKiogVGhlIDNEIGNhbWVyYSBtb2RlIChgdHVybnRhYmxlYCAvIGBvcmJpdGAgLyDigKYpLiAqL1xuICBASW5wdXQoKSBhY3RpdmVTdXJmYWNlM2RNb2RlID0gJ3R1cm50YWJsZSc7XG4gIC8qKiBXaGV0aGVyIHRoZSBuYXBhcmkgM0QgYXhlcy9zY2FsZSBnaXptbyBpcyBjdXJyZW50bHkgc2hvd24gKGRyaXZlcyB0aGUgdG9nZ2xlJ3MgbG9vaykuICovXG4gIEBJbnB1dCgpIGF4ZXNWaXNpYmxlID0gdHJ1ZTtcbiAgLyoqIFRoZSBuYXBhcmkgc3VyZmFjZSB3aXJlZnJhbWUgaXMgb24uICovXG4gIEBJbnB1dCgpIHdpcmVmcmFtZUFjdGl2ZSA9IGZhbHNlO1xuICAvKiogQWN0aXZlIG5hcGFyaSAzRCBkZWNpbWF0ZSBmYWN0b3IgKDEgPSBGdWxsIOKApiA4ID0g4oWbOyBkZWZhdWx0IMK9KS4gKi9cbiAgQElucHV0KCkgcmVzb2x1dGlvblNjYWxlID0gTkFQQVJJX0RFRkFVTFRfREVDSU1BVEU7XG4gIC8qKiBNYWdpYy13YW5kIHNlbnNpdGl2aXR5LiAqL1xuICBASW5wdXQoKSB3YW5kU2Vuc2l0aXZpdHkgPSAyLjA7XG4gIC8qKiBCcnVzaCBkaWFtZXRlciBpbiBpbWFnZSBwaXhlbHMuICovXG4gIEBJbnB1dCgpIGJydXNoU2l6ZSA9IDQwO1xuICAvKiogVmVydGV4LWVyYXNlciByYWRpdXMgaW4gaW1hZ2UgcGl4ZWxzLiAqL1xuICBASW5wdXQoKSB2ZXJ0ZXhFcmFzZXJSYWRpdXMgPSAyMDtcbiAgLyoqIFdoZXRoZXIgYSByZWdpb24gYWN0aW9uIGlzIGF2YWlsYWJsZSB0byB1bmRvIChqaXQtdWkjODUpLiBHcmV5cyBvdXQgdGhlXG4gICAqICBVbmRvIGJ1dHRvbiB3aGVuIGZhbHNlIChub3RoaW5nIGRvbmUgeWV0LCBvciBhbGwgc3RlcHMgYWxyZWFkeSB1bmRvbmUpLiAqL1xuICBASW5wdXQoKSBjYW5VbmRvID0gZmFsc2U7XG4gIC8qKiBXaGV0aGVyIGFuIHVuZG9uZSByZWdpb24gYWN0aW9uIGlzIGF2YWlsYWJsZSB0byByZWRvIChqaXQtdWkjODUpLiBHcmV5c1xuICAgKiAgb3V0IHRoZSBSZWRvIGJ1dHRvbiB3aGVuIGZhbHNlLiAqL1xuICBASW5wdXQoKSBjYW5SZWRvID0gZmFsc2U7XG4gIC8qKiBUaGUgc2luZ2xlLWltYWdlIC8gc3RhY2sgY2hvaWNlcyBvZiB0aGUgUGxvdGx5IHN0YWNrIHRvZ2dsZS4gKi9cbiAgQElucHV0KCkgc3RhY2tPcHRpb25zOiB7IG5hbWU6IHN0cmluZzsgdmFsOiBzdHJpbmcgfVtdID0gW1xuICAgIHsgbmFtZTogJ1NpbmdsZSBpbWFnZScsIHZhbDogJ2ZhbHNlJyB9LFxuICAgIHsgbmFtZTogJ1N0YWNrJywgdmFsOiAndHJ1ZScgfSxcbiAgXTtcbiAgLyoqIFdoaWNoIHRvb2xiYXIgZ3JvdXBzIHRvIHNob3cuIERlZmF1bHRzIHRvIHRoZSBmdWxsIHRvb2xiYXI7IHRoZSBob3N0IGZvcndhcmRzXG4gICAqICB0aGUgY29uc3VtZXIncyBjaG9pY2UgKGUuZy4gdGhlIHBpcGVsaW5lIHNob3dzIG9ubHkgem9vbSArIHJlZ2lvbiB0b29scykuICovXG4gIEBJbnB1dCgpIHRvb2xzOiBSZXF1aXJlZDxUb29sYmFyVG9vbFZpc2liaWxpdHk+ID0gQUxMX1RPT0xCQVJfVE9PTFM7XG4gIC8qKiBDdXJyZW50IGltYWdlLXNtb290aGluZyBzdGF0ZSAoZHJpdmVzIHRoZSBTbW9vdGhlbiB0b2dnbGUgYnV0dG9uIGxvb2spLlxuICAgKiAgYGZhbHNlYCA9IG5lYXJlc3QtbmVpZ2hib3VyIChjcmlzcCByYXcgcGl4ZWxzKSwgdGhlIGRlZmF1bHQuICovXG4gIEBJbnB1dCgpIGltYWdlU21vb3RoaW5nRW5hYmxlZCA9IGZhbHNlO1xuICAvKiogU0FNIG1vZGVsIHBpY2tlciBvcHRpb25zICsgY3VycmVudCBzZWxlY3Rpb24gKGppdC11aSM5MCBQMSkuICovXG4gIEBJbnB1dCgpIHNhbU1vZGVsczogeyBpZDogc3RyaW5nOyBsYWJlbDogc3RyaW5nIH1bXSA9IFtdO1xuICAvKiogVGhlIHNlbGVjdGVkIFNBTSBtb2RlbCBpZC4gKi9cbiAgQElucHV0KCkgc2FtTW9kZWxJZCA9ICcnO1xuICAvKipcbiAgICogVG9vbHMgY29udHJpYnV0ZWQgdGhyb3VnaCB7QGxpbmsgVE9PTEJBUl9UT09MU30sIGFscmVhZHkgZmlsdGVyZWQgdG8gdGhlXG4gICAqIG9uZXMgd2l0aCBtb2RlbHMgYW5kIHNvcnRlZC4gVGhlIGhvc3QgcmVzb2x2ZXMgdGhlbSBzbyBpdCBjYW4gb3duIHRoZVxuICAgKiBwZXItdG9vbCBwYXJhbWV0ZXIgc3RhdGU7IHRoaXMgY29tcG9uZW50IG9ubHkgZHJhd3MgdGhlbS5cbiAgICovXG4gIEBJbnB1dCgpIGNvbnRyaWJ1dGVkVG9vbHM6IFRvb2xiYXJUb29sQ29udHJpYnV0aW9uW10gPSBbXTtcbiAgLyoqIERpYWxvZyB0b29scyAoVE9PTEJBUl9UT09MUywga2luZDogJ2RpYWxvZycpLCBzb3J0ZWQ7IHNob3duIGluIHRoZSBJbWFnZSB2aWV3LiAqL1xuICBASW5wdXQoKSBkaWFsb2dUb29sczogVG9vbGJhckRpYWxvZ1Rvb2xDb250cmlidXRpb25bXSA9IFtdO1xuICAvKiogSWQgb2YgdGhlIGRpYWxvZyB0b29sIHdob3NlIGRpYWxvZyBpcyBvcGVuLCBvciBudWxsLiAqL1xuICBASW5wdXQoKSBvcGVuRGlhbG9nVG9vbElkOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgLyoqIEFjdGl2ZSBjaGVja3BvaW50IHBlciBjb250cmlidXRlZCB0b29sLCBrZXllZCBieSB0b29sIGlkLiAqL1xuICBASW5wdXQoKSB0b29sTW9kZWxJZHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblxuICAvKiogQSBwbG90IHR5cGUgb3IgY29udHJpYnV0ZWQgbW9kZSB3YXMgcGlja2VkLiAqL1xuICBAT3V0cHV0KCkgc2VsZWN0UGxvdFR5cGUgPSBuZXcgRXZlbnRFbWl0dGVyPFBsb3RUeXBlSWQ+KCk7XG4gIC8qKiBJbnRlbnNpdHkgKExJTkUpIG1vZGU6IGFkZCBhbm90aGVyIGNvbG9yZWQgbGluZSBST0kgKyBpbnNldCB0cmFjZS4gKi9cbiAgQE91dHB1dCgpIGFkZFByb2ZpbGVMaW5lID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogVG9nZ2xlIGltYWdlIHNtb290aGluZyAoYmlsaW5lYXIpIHZzIG5lYXJlc3QtbmVpZ2hib3VyIChjcmlzcCBwaXhlbHMpLiAqL1xuICBAT3V0cHV0KCkgdG9nZ2xlSW1hZ2VTbW9vdGhpbmcgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8vIFByaW1lTkcgc2xpZGVyL2lucHV0TnVtYmVyIGNoYW5nZSBldmVudHMgY2Fycnkgb3B0aW9uYWwgdmFsdWVzLCBtaXJyb3JlZCBieVxuICAvLyB0aGUgaG9zdCBoYW5kbGVycyAod2hpY2ggYWNjZXB0IGB8IHVuZGVmaW5lZGApLlxuICAvKiogVGhlIGlzb3N1cmZhY2UgYmFuZCBzbGlkZXIgbW92ZWQ6IHRoZSBuZXcgYFtsb3csIGhpZ2hdYCBwYWlyLiAqL1xuICBAT3V0cHV0KCkgaXNvUmFuZ2VDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcltdIHwgdW5kZWZpbmVkPigpO1xuICAvKiogT3BlbiB0aGUgQ2hhbm5lbHMgJiBIaXN0b2dyYW0gZGlhbG9nIChicmlnaHRuZXNzL2NvbnRyYXN0LCBjb2xvcm1hcCwg4oCmKS4gKi9cbiAgQE91dHB1dCgpIG9wZW5DaGFubmVsSGlzdG9ncmFtID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogT3BlbiB0aGUgc3BhdGlhbC1vbWljcyBjb250cm9scyAoY29sb3VyLWJ5LCBsZWdlbmQsIHBvaW50IGRpc3BsYXkpLiAqL1xuICBAT3V0cHV0KCkgb3BlblNwYXRpYWxDb250cm9scyA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIE9wZW4gdGhlIFJlZ2lvbiBFZGl0b3IgZGlhbG9nLiAqL1xuICBAT3V0cHV0KCkgb3BlblJlZ2lvbkVkaXRvciA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIEEgc2luZ2xlLWltYWdlIC8gc3RhY2sgY2hvaWNlIHdhcyBwaWNrZWQuICovXG4gIEBPdXRwdXQoKSBzZWxlY3RTdGFja09wdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8eyBuYW1lOiBzdHJpbmc7IHZhbDogc3RyaW5nIH0+KCk7XG4gIC8qKiBUaGUgbGl2ZSBzbGljZSBzY3J1YmJlciBtb3ZlZCAoZmlyZXMgd2hpbGUgZHJhZ2dpbmcpLiAqL1xuICBAT3V0cHV0KCkgelNjcnViID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXIgfCB1bmRlZmluZWQ+KCk7XG4gIC8qKiBUaGUgbGl2ZSBzbGljZSBzY3J1YmJlciB3YXMgcmVsZWFzZWQgb24gYSBzbGljZS4gKi9cbiAgQE91dHB1dCgpIHpTbGlkZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyIHwgdW5kZWZpbmVkPigpO1xuICAvKiogQSBzbGljZSBudW1iZXIgd2FzIHR5cGVkLiAqL1xuICBAT3V0cHV0KCkgekluZGV4SW5wdXQgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcbiAgLyoqIFJlLXBsb3QgYXQgdGhlIHR5cGVkIHNsaWNlLiAqL1xuICBAT3V0cHV0KCkgcmVsb2FkQW5kUGxvdCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIERvd25sb2FkIHRoZSBjdXJyZW50IHZpZXcgYXMgUE5HLiAqL1xuICBAT3V0cHV0KCkgZG93bmxvYWRJbWFnZSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIEZpdCB0aGUgaW1hZ2UgdG8gdGhlIHZpZXcuICovXG4gIEBPdXRwdXQoKSBhdXRvc2NhbGVJbWFnZSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIEEgem9vbSAvIHBhbiAvIGRyYXdpbmcgdG9vbCBidXR0b24gd2FzIGNsaWNrZWQgKGl0cyBtb2RlKS4gKi9cbiAgQE91dHB1dCgpIHRvZ2dsZURyYWdNb2RlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIC8qKiBab29tIGluIG9uZSBzdGVwLiAqL1xuICBAT3V0cHV0KCkgem9vbUluID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogWm9vbSBvdXQgb25lIHN0ZXAuICovXG4gIEBPdXRwdXQoKSB6b29tT3V0ID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogQSAzRCBjYW1lcmEgbW9kZSBidXR0b24gd2FzIGNsaWNrZWQgKGl0cyBtb2RlKS4gKi9cbiAgQE91dHB1dCgpIHRvZ2dsZVN1cmZhY2UzZE1vZGUgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgLyoqIFJlc2V0IHRoZSAzRCBjYW1lcmEuICovXG4gIEBPdXRwdXQoKSByZXNldFN1cmZhY2VDYW1lcmEgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBUb2dnbGUgdGhlIG5hcGFyaSAzRCBjb29yZGluYXRlLWF4ZXMgLyBzY2FsZSBnaXptbyBvbi9vZmYuICovXG4gIEBPdXRwdXQoKSB0b2dnbGVBeGVzID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogVG9nZ2xlIHRoZSBuYXBhcmkgc3VyZmFjZSB3aXJlZnJhbWUgKGVkZ2VzKSBvbi9vZmYuICovXG4gIEBPdXRwdXQoKSB0b2dnbGVXaXJlZnJhbWUgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBDaGFuZ2UgdGhlIG5hcGFyaSAzRCBkZWNpbWF0ZSBmYWN0b3IgKHJlbG9hZHMgYXQgdGhlIG5ldyByZXNvbHV0aW9uKS4gKi9cbiAgQE91dHB1dCgpIHNlbGVjdFJlc29sdXRpb24gPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcbiAgLyoqIERlbGV0ZSB0aGUgc2VsZWN0ZWQgcmVnaW9uLiAqL1xuICBAT3V0cHV0KCkgZGVsZXRlUmVnaW9uID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogVW5kbyB0aGUgbGFzdCByZWdpb24gYWN0aW9uIChqaXQtdWkjODUpLiAqL1xuICBAT3V0cHV0KCkgdW5kb1JlZ2lvbiA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIFJlZG8gdGhlIGxhc3QgdW5kb25lIHJlZ2lvbiBhY3Rpb24gKGppdC11aSM4NSkuICovXG4gIEBPdXRwdXQoKSByZWRvUmVnaW9uID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogUnVuIGJveC1wcm9tcHRlZCBTQU0gc2VnbWVudGF0aW9uIG9uIHRoZSBkcmF3biByZWN0YW5nbGVzIChqaXQtdWkjOTApLiAqL1xuICBAT3V0cHV0KCkgc2VnbWVudFJlZ2lvbnMgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBSdW4gY2VsbHBvc2UtU0FNIChhdXRvKSBpbnNpZGUgZWFjaCBkcmF3biByZWN0YW5nbGUncyBjcm9wIChqaXQtdWkjOTApLiAqL1xuICBAT3V0cHV0KCkgc2VnbWVudENlbGxwb3NlID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogUnVuIGEgY29udHJpYnV0ZWQgdG9vbCBvdmVyIHRoZSBjdXJyZW50IHZpZXcsIGJ5IHRvb2wgaWQuICovXG4gIEBPdXRwdXQoKSBydW5Ub29sID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIC8qKiBBIGRpYWxvZyB0b29sJ3MgYnV0dG9uIHdhcyBjbGlja2VkOiBvcGVuIGl0cyBkaWFsb2csIG9yIGNsb3NlIGl0IGlmIG9wZW4uICovXG4gIEBPdXRwdXQoKSB0b2dnbGVEaWFsb2dUb29sID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIC8qKiBQaWNrIGEgY29udHJpYnV0ZWQgdG9vbCdzIGNoZWNrcG9pbnQuICovXG4gIEBPdXRwdXQoKSB0b29sTW9kZWxDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHsgdG9vbElkOiBzdHJpbmc7IG1vZGVsSWQ6IHN0cmluZyB9PigpO1xuICAvKiogT3BlbiBhIGNvbnRyaWJ1dGVkIHRvb2wncyBwYXJhbWV0ZXIgZGlhbG9nLCBieSB0b29sIGlkLiAqL1xuICBAT3V0cHV0KCkgb3BlblRvb2xQYXJhbXMgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgLyoqIFNBTSBtb2RlbCBwaWNrZXIgKGppdC11aSM5MCBQMSkuICovXG4gIEBPdXRwdXQoKSBzYW1Nb2RlbENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICAvKiogVGhlIHdhbmQgc2Vuc2l0aXZpdHkgc2xpZGVyIG1vdmVkLiAqL1xuICBAT3V0cHV0KCkgd2FuZFNlbnNpdGl2aXR5Q2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXIgfCB1bmRlZmluZWQ+KCk7XG4gIC8qKiBUaGUgYnJ1c2ggc2l6ZSBzbGlkZXIgbW92ZWQuICovXG4gIEBPdXRwdXQoKSBicnVzaFNpemVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlciB8IHVuZGVmaW5lZD4oKTtcbiAgLyoqIFRoZSB2ZXJ0ZXgtZXJhc2VyIHJhZGl1cyBzbGlkZXIgbW92ZWQuICovXG4gIEBPdXRwdXQoKSB2ZXJ0ZXhFcmFzZXJSYWRpdXNDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlciB8IHVuZGVmaW5lZD4oKTtcblxuICBwcm90ZWN0ZWQgZGlzcGxheUhlbHBEaWFsb2cgPSBmYWxzZTtcblxuICAvKiogdHJhY2tCeSBmb3IgdGhlIGRpYWxvZyB0b29scycgYnV0dG9ucy4gKi9cbiAgcHJvdGVjdGVkIHRyYWNrVG9vbEJ5SWQoX2luZGV4OiBudW1iZXIsIHRvb2w6IHsgaWQ6IHN0cmluZyB9KTogc3RyaW5nIHtcbiAgICByZXR1cm4gdG9vbC5pZDtcbiAgfVxuXG4gIC8qKiBUaGUgYnVpbHQtaW4gdHlwZSB3aG9zZSB0b29scyBhbmQgY29udHJvbHMgYXBwbHkgdG8gdGhlIGN1cnJlbnQgc2VsZWN0aW9uLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGVmZmVjdGl2ZVBsb3RUeXBlKCk6IFBsb3RUeXBlIHtcbiAgICBpZiAodGhpcy5iYXNlUGxvdFR5cGUpIHJldHVybiB0aGlzLmJhc2VQbG90VHlwZTtcbiAgICByZXR1cm4gaXNCdWlsdGluUGxvdFR5cGUodGhpcy5zZWxlY3RlZFBsb3RUeXBlKSA/IHRoaXMuc2VsZWN0ZWRQbG90VHlwZSA6IFBsb3RUeXBlLklNQUdFO1xuICB9XG5cbiAgLyoqIFRoZSBJbWFnZSBwbG90IHR5cGUgcmVuZGVycyBhcyBhIG5hdGl2ZWx5IHBhbi96b29tLWFibGUgcmFzdGVyLCBzbyB0aGVcbiAgICogIGdlbmVyaWMgem9vbS9wYW4gdG9vbHMgYXJlIGhpZGRlbi4gKi9cbiAgcHJvdGVjdGVkIGdldCBpc0ltYWdlVmlldygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5lZmZlY3RpdmVQbG90VHlwZSA9PT0gUGxvdFR5cGUuSU1BR0U7XG4gIH1cblxuICAvKiogRWl0aGVyIHNwYXRpYWwtb21pY3MgbW9kZSBpcyBhY3RpdmUsIHNvIGl0cyBjb250cm9scyBhcmUgd29ydGggb2ZmZXJpbmcuXG4gICAqICBUaGUgM0QgY2xvdWQgbmVlZHMgdGhlIHBhbmVsIE1PUkUgdGhhbiB0aGUgMkQgdmlldyBkb2VzLCBub3QgbGVzczogY29sb3VyaW5nLFxuICAgKiAgdGhlIGxlZ2VuZCBhbmQgY2F0ZWdvcnkgc2hvdy9oaWRlIGFyZSB0aGUgb25seSB3YXkgdG8gbWFrZSBzZW5zZSBvZiBhXG4gICAqICBtaWxsaW9uIG92ZXJsYXBwaW5nIHBvaW50cy4gKi9cbiAgcHJvdGVjdGVkIGdldCBpc1NwYXRpYWxNb2RlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpc1NwYXRpYWxPbWljcyh0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlKSB8fCBpc1NwYXRpYWxPbWljczNkKHRoaXMuZWZmZWN0aXZlUGxvdFR5cGUpO1xuICB9XG5cbiAgLyoqIEJhY2tlbmRzIHdpdGggYSB2ZXJ0ZXgtZWRpdGluZyByZWdpb24gb3ZlcmxheTogT1NEIEltYWdlIGFuZCBuYXBhcmktanMgV2ViR1BVIGltYWdlXG4gICAqICAoaml0LXVpIzEwMikuIEdhdGVzIHRoZSBwb2x5Z29uIC8gYWRkLXZlcnRleCAvIGRlbGV0ZS12ZXJ0ZXggLyBCw6l6aWVyLWNvbnZlcnQgdG9vbHMuICovXG4gIHByb3RlY3RlZCBnZXQgc3VwcG9ydHNSZWdpb25WZXJ0ZXhUb29scygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5lZmZlY3RpdmVQbG90VHlwZSA9PT0gUGxvdFR5cGUuSU1BR0UgfHwgdGhpcy5lZmZlY3RpdmVQbG90VHlwZSA9PT0gUGxvdFR5cGUuTkFQQVJJX0lNQUdFO1xuICB9XG5cbiAgLyoqIFBsb3QgdHlwZXMgdGhhdCBzY3J1YiBhIHotc3RhY2sgbGl2ZSAodGhlIHJlbmRlcmVyIHN3YXBzIHRoZSBzbGljZSBpbiBwbGFjZSk6IHRoZSBPU0QgSW1hZ2VcbiAgICogIHZpZXcsIHRoZSBuYXBhcmktanMgV2ViR1BVIGltYWdlLCB0aGUgbmFwYXJpLWpzIHN1cmZhY2Ug4oCUIHdoaWNoIHJlYnVpbGRzIHRoZSBoZWlnaHQgZmllbGRcbiAgICogIGZyb20gdGhlIHBpY2tlZCBzbGljZSAoaml0LXVpIzEwMikg4oCUIGFuZCB0aGUgMkQgc3BhdGlhbC1vbWljcyB2aWV3LCB3aGVyZSBhIDNEIGRhdGFzZXQnc1xuICAgKiAgcmVnaXN0ZXJlZCB2b2x1bWUgaXMgdGhlIGltYWdlIGFuZCB0aGUgc2xpZGVyIHBpY2tzIHRoZSBzZWN0aW9uIHdob3NlIG9ic2VydmF0aW9ucyBhcmVcbiAgICogIGRyYXduLiBEcml2ZXMgdGhlIHBlci1zbGljZSBzbGlkZXIuICovXG4gIHByb3RlY3RlZCBnZXQgc2hvd3NMaXZlU2xpY2VTY3J1YmJlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5lZmZlY3RpdmVQbG90VHlwZSA9PT0gUGxvdFR5cGUuSU1BR0UgfHxcbiAgICAgIHRoaXMuZWZmZWN0aXZlUGxvdFR5cGUgPT09IFBsb3RUeXBlLk5BUEFSSV9JTUFHRSB8fFxuICAgICAgaXNOYXBhcmlTdXJmYWNlKHRoaXMuZWZmZWN0aXZlUGxvdFR5cGUpIHx8XG4gICAgICBpc05hcGFyaVNjYXR0ZXIodGhpcy5lZmZlY3RpdmVQbG90VHlwZSkgfHxcbiAgICAgIGlzU3BhdGlhbE9taWNzKHRoaXMuZWZmZWN0aXZlUGxvdFR5cGUpXG4gICAgKTtcbiAgfVxuXG4gIC8qKiBBbnkgbmFwYXJpLWpzIFdlYkdQVSBwbG90IHR5cGUuIFRoZSBzaW5nbGUtaW1hZ2Uvc3RhY2sgdG9nZ2xlICsgc2xpY2UtbnVtYmVyIGZpZWxkIGFyZVxuICAgKiAgUGxvdGx5LW9ubHkgc3RhY2sgY29udHJvbHMsIHNvIHRoZXkncmUgaGlkZGVuIGZvciBuYXBhcmkgKGppdC11aSMxMDIpLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGlzTmFwYXJpTW9kZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5lZmZlY3RpdmVQbG90VHlwZSA9PT0gUGxvdFR5cGUuTkFQQVJJX0lNQUdFIHx8XG4gICAgICBpc05hcGFyaVNjYXR0ZXIodGhpcy5lZmZlY3RpdmVQbG90VHlwZSkgfHxcbiAgICAgIGlzTmFwYXJpM2QodGhpcy5lZmZlY3RpdmVQbG90VHlwZSlcbiAgICApO1xuICB9XG5cbiAgLyoqIElTT1NVUkZBQ0UgKFBsb3RseSBvciBuYXBhcmktanMgV2ViR1BVLCBlaXRoZXIgcmVzb2x1dGlvbikgc2hvd3MgdGhlIGlzb3ZhbHVlIHJhbmdlIHNsaWRlci4gKi9cbiAgcHJvdGVjdGVkIGdldCBpc0lzb3N1cmZhY2VNb2RlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlID09PSBQbG90VHlwZS5JU09TVVJGQUNFIHx8IGlzTmFwYXJpSXNvc3VyZmFjZSh0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlKTtcbiAgfVxuXG4gIC8qKiBUaGUgbmFwYXJpLWpzIFdlYkdQVSBzdXJmYWNlIOKAlCBzaG93cyB0aGUgd2lyZWZyYW1lIHRvZ2dsZS4gKi9cbiAgcHJvdGVjdGVkIGdldCBpc05hcGFyaVN1cmZhY2VNb2RlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpc05hcGFyaVN1cmZhY2UodGhpcy5lZmZlY3RpdmVQbG90VHlwZSk7XG4gIH1cblxuICAvKiogQW55IG5hcGFyaS1qcyBXZWJHUFUgM0QgdHlwZSAodm9sdW1lL2lzb3N1cmZhY2Uvc3VyZmFjZSkg4oCUIHNob3dzIHRoZSBSZXNvbHV0aW9uIGNvbnRyb2wuICovXG4gIHByb3RlY3RlZCBnZXQgaXNOYXBhcmkzZE1vZGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGlzTmFwYXJpM2QodGhpcy5lZmZlY3RpdmVQbG90VHlwZSk7XG4gIH1cblxuICAvKiogSW50ZW5zaXR5IHByb2ZpbGUgbGluZXMgYXJlIFJlZ2lvbi1iYXNlZCBhbmQgYXZhaWxhYmxlIGluIHRoZSBIZWF0bWFwIGFuZFxuICAgKiAgSW1hZ2UgcGxvdCB0eXBlcywgd2hpY2ggc2hvdyB0aGUgSW50ZW5zaXR5IHRvb2wgZ3JvdXAuICovXG4gIHByb3RlY3RlZCBnZXQgaXNJbnRlbnNpdHlDYXBhYmxlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlID09PSBQbG90VHlwZS5IRUFUTUFQIHx8IHRoaXMuZWZmZWN0aXZlUGxvdFR5cGUgPT09IFBsb3RUeXBlLklNQUdFO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNob3dIZWxwKCk6IHZvaWQge1xuICAgIHRoaXMuZGlzcGxheUhlbHBEaWFsb2cgPSB0cnVlO1xuICB9XG59XG4iLCI8cC10b29sYmFyPlxuICA8ZGl2IGNsYXNzPVwicC10b29sYmFyLWdyb3VwLXN0YXJ0IGZsZXgtd3JhcCBhbGlnbi1pdGVtcy1jZW50ZXIgZ2FwLTFcIj5cbiAgICA8IS0tIEhvc3QtcHJvdmlkZWQgY3VzdG9tIHRvb2xiYXIgYnV0dG9ucywgc2hvd24gZmlyc3QgKGUuZy4gYXBwLXNwZWNpZmljXG4gICAgICAgICBhY3Rpb25zIHRoZSB2aXN1YWxpemF0aW9uIHZpZXcgaXRzZWxmIGRvZXNuJ3Qgb3duKS4gLS0+XG4gICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuXG4gICAgPCEtLSBDb250cmlidXRlZCBkaWFsb2cgdG9vbHMgKFRPT0xCQVJfVE9PTFMsIGtpbmQ6ICdkaWFsb2cnKTogYXBwLWxldmVsIGFjdGlvbnNcbiAgICAgICAgIGxpa2UgdGhlIGhvc3QncyBvd24gYnV0dG9ucyBhYm92ZSwgc28gdGhleSBzaXQgcmlnaHQgYmVzaWRlIHRoZW0uIEltYWdlIHZpZXdcbiAgICAgICAgIG9ubHksIHRoZSB2aWV3IHRoZWlyIGRpYWxvZyBkcmF3cyBvdmVyLiBIaWdobGlnaHRlZCB3aGlsZSB0aGUgZGlhbG9nIGlzIG9wZW4uIC0tPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc0ltYWdlVmlld1wiPlxuICAgICAgPHAtYnV0dG9uXG4gICAgICAgICpuZ0Zvcj1cImxldCB0b29sIG9mIGRpYWxvZ1Rvb2xzOyB0cmFja0J5OiB0cmFja1Rvb2xCeUlkXCJcbiAgICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgICAgW3RleHRdPVwib3BlbkRpYWxvZ1Rvb2xJZCAhPT0gdG9vbC5pZFwiXG4gICAgICAgIFtwVG9vbHRpcF09XCJ0b29sLnRvb2x0aXBcIlxuICAgICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgICAgICBbYXJpYUxhYmVsXT1cInRvb2wubGFiZWxcIlxuICAgICAgICBbYXR0ci5hcmlhLXByZXNzZWRdPVwib3BlbkRpYWxvZ1Rvb2xJZCA9PT0gdG9vbC5pZFwiXG4gICAgICAgIChvbkNsaWNrKT1cInRvZ2dsZURpYWxvZ1Rvb2wuZW1pdCh0b29sLmlkKVwiXG4gICAgICA+XG4gICAgICAgIDxpbWdcbiAgICAgICAgICAqbmdJZj1cInRvb2wuaWNvbi5zcmNcIlxuICAgICAgICAgIFtzcmNdPVwidG9vbC5pY29uLnNyY1wiXG4gICAgICAgICAgc3R5bGU9XCJ3aWR0aDogMXJlbVwiXG4gICAgICAgICAgW2FsdF09XCJ0b29sLmxhYmVsXCJcbiAgICAgICAgICBbY2xhc3NdPVwib3BlbkRpYWxvZ1Rvb2xJZCA9PT0gdG9vbC5pZCA/ICd0b29sYmFyLWljb24tYWN0aXZlJyA6ICd0b29sYmFyLWljb24tZGFyaydcIlxuICAgICAgICAvPlxuICAgICAgICA8aSAqbmdJZj1cInRvb2wuaWNvbi5waVwiIGNsYXNzPVwicGkge3sgdG9vbC5pY29uLnBpIH19XCI+PC9pPlxuICAgICAgPC9wLWJ1dHRvbj5cbiAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgIDwhLS0gUGxvdCB0eXBlOiBhdmFpbGFibGUgZm9yIGFueSBpbWFnZSAoZ3JheXNjYWxlIG9yIFJHQiksIGFuZCBmb3IgYSBzcGF0aWFsIGRhdGFzZXRcbiAgICAgICAgIHRoYXQgYnJpbmdzIG5vbmUgKGl0cyBzcGF0aWFsIG1vZGVzIGFyZSBzdGlsbCBhIGNob2ljZSkuIC0tPlxuICAgIDx0b29sYmFyLXBsb3QtdHlwZS1zZWxlY3RvclxuICAgICAgKm5nSWY9XCJzaG93UGxvdFR5cGVzXCJcbiAgICAgIFtvcHRpb25zXT1cInBsb3RUeXBlT3B0aW9uc1wiXG4gICAgICBbc2VsZWN0ZWRdPVwic2VsZWN0ZWRQbG90VHlwZVwiXG4gICAgICBbaXNvc3VyZmFjZV09XCJpc0lzb3N1cmZhY2VNb2RlXCJcbiAgICAgIFtpc29SYW5nZV09XCJpc29SYW5nZVwiXG4gICAgICBbaW50ZW5zaXR5TGluZXNdPVwiaXNJbnRlbnNpdHlDYXBhYmxlXCJcbiAgICAgIChzZWxlY3RQbG90VHlwZSk9XCJzZWxlY3RQbG90VHlwZS5lbWl0KCRldmVudClcIlxuICAgICAgKGlzb1JhbmdlQ2hhbmdlKT1cImlzb1JhbmdlQ2hhbmdlLmVtaXQoJGV2ZW50KVwiXG4gICAgICAoYWRkUHJvZmlsZUxpbmUpPVwiYWRkUHJvZmlsZUxpbmUuZW1pdCgpXCJcbiAgICA+XG4gICAgPC90b29sYmFyLXBsb3QtdHlwZS1zZWxlY3Rvcj5cbiAgICA8IS0tIENoYW5uZWxzICYgSGlzdG9ncmFtOiBicmlnaHRuZXNzL2NvbnRyYXN0LCBnYW1tYSwgcGVyLWNoYW5uZWwgZGlzcGxheSxcbiAgICAgICAgIGNvbG9ybWFwL3JldmVyc2UvaW52ZXJ0IOKAlCBvcGVucyB0aGUgZmxvYXRpbmcgZGlhbG9nLiAtLT5cbiAgICA8cC1idXR0b25cbiAgICAgICpuZ0lmPVwidG9vbHMuc3BlY2lhbFRvb2xzXCJcbiAgICAgIHBSaXBwbGVcbiAgICAgIHNpemU9XCJzbWFsbFwiXG4gICAgICBbdGV4dF09XCJ0cnVlXCJcbiAgICAgIGFyaWFMYWJlbD1cIkNoYW5uZWxzICZhbXA7IEhpc3RvZ3JhbVwiXG4gICAgICBwVG9vbHRpcD1cIkNoYW5uZWxzICZhbXA7IEhpc3RvZ3JhbSAoYnJpZ2h0bmVzcy9jb250cmFzdCwgY29sb3JtYXApXCJcbiAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgICAob25DbGljayk9XCJvcGVuQ2hhbm5lbEhpc3RvZ3JhbS5lbWl0KClcIlxuICAgID5cbiAgICAgIDxpbWcgc3JjPVwiYXNzZXRzL3Bsb3R0aW5nL2ludmVydC5zdmdcIiBjbGFzcz1cInRvb2xiYXItaWNvbi1kYXJrXCIgc3R5bGU9XCJ3aWR0aDogMXJlbVwiIC8+XG4gICAgPC9wLWJ1dHRvbj5cblxuICAgIDwhLS0gU3BhdGlhbC1vbWljcyBjb250cm9scy4gT25seSBtZWFuaW5nZnVsIGluIHRoZSBzcGF0aWFsIG1vZGUsIHdoaWNoIGlzXG4gICAgICAgICBpdHNlbGYgb25seSBvZmZlcmVkIHdoaWxlIGEgZGF0YXNldCBpcyBsb2FkZWQg4oCUIHNvIHRoaXMgYnV0dG9uIGFwcGVhcnNcbiAgICAgICAgIGV4YWN0bHkgd2hlbiB0aGVyZSBpcyBzb21ldGhpbmcgZm9yIGl0IHRvIGNvbnRyb2wuIC0tPlxuICAgIDxwLWJ1dHRvblxuICAgICAgKm5nSWY9XCJ0b29scy5zcGVjaWFsVG9vbHMgJiYgaXNTcGF0aWFsTW9kZVwiXG4gICAgICBwUmlwcGxlXG4gICAgICBzaXplPVwic21hbGxcIlxuICAgICAgW3RleHRdPVwidHJ1ZVwiXG4gICAgICBhcmlhTGFiZWw9XCJTcGF0aWFsIG9taWNzIGNvbnRyb2xzXCJcbiAgICAgIHBUb29sdGlwPVwiU3BhdGlhbCBvbWljcyAoY29sb3VyIGJ5IGNvbHVtbiBvciBnZW5lLCBsZWdlbmQsIHNlbGVjdGlvbiwgZGlzdHJpYnV0aW9ucylcIlxuICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgIChvbkNsaWNrKT1cIm9wZW5TcGF0aWFsQ29udHJvbHMuZW1pdCgpXCJcbiAgICA+XG4gICAgICA8aW1nIHNyYz1cImFzc2V0cy9wbG90dGluZy9zcGF0aWFsLW9taWNzLnN2Z1wiIGNsYXNzPVwidG9vbGJhci1pY29uLWRhcmtcIiBzdHlsZT1cIndpZHRoOiAxcmVtXCIgLz5cbiAgICA8L3AtYnV0dG9uPlxuXG4gICAgPCEtLSBTbW9vdGhlbiB0b2dnbGU6IGJpbGluZWFyIHNtb290aGluZyB2cyBuZWFyZXN0LW5laWdoYm91ciByYXcgcGl4ZWxzIChJbWFnZVxuICAgICAgICAgdmlldyBvbmx5IOKAlCBpdCdzIGFuIE9wZW5TZWFkcmFnb24gZHJhd2VyIHNldHRpbmcpLiBIaWdobGlnaHRlZCB3aGVuIHNtb290aGluZyBvbi4gLS0+XG4gICAgPHAtYnV0dG9uXG4gICAgICAqbmdJZj1cInRvb2xzLnNwZWNpYWxUb29scyAmJiBpc0ltYWdlVmlld1wiXG4gICAgICBzaXplPVwic21hbGxcIlxuICAgICAgW3RleHRdPVwiIWltYWdlU21vb3RoaW5nRW5hYmxlZFwiXG4gICAgICBhcmlhTGFiZWw9XCJTbW9vdGhlblwiXG4gICAgICBwVG9vbHRpcD1cIlNtb290aGVuICh0dXJuIG9uIGltYWdlIHNtb290aGluZylcIlxuICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgIChvbkNsaWNrKT1cInRvZ2dsZUltYWdlU21vb3RoaW5nLmVtaXQoKVwiXG4gICAgPlxuICAgICAgPGltZ1xuICAgICAgICBzcmM9XCJhc3NldHMvcGxvdHRpbmcvc21vb3RoLnN2Z1wiXG4gICAgICAgIHN0eWxlPVwid2lkdGg6IDFyZW1cIlxuICAgICAgICBbY2xhc3NdPVwiaW1hZ2VTbW9vdGhpbmdFbmFibGVkID8gJ3Rvb2xiYXItaWNvbi1hY3RpdmUnIDogJ3Rvb2xiYXItaWNvbi1kYXJrJ1wiXG4gICAgICAvPlxuICAgIDwvcC1idXR0b24+XG5cbiAgICA8IS0tIFN0YWNrIGNvbnRyb2xzIC0tPlxuICAgIDx0b29sYmFyLXN0YWNrLWNvbnRyb2xzXG4gICAgICAqbmdJZj1cImltYWdlSW5mbz8uaXNTdGFja1wiXG4gICAgICBbbGl2ZVNjcnViYmVyXT1cInNob3dzTGl2ZVNsaWNlU2NydWJiZXJcIlxuICAgICAgW3N0YWNrVG9nZ2xlXT1cIiFzaG93c0xpdmVTbGljZVNjcnViYmVyICYmICFpc05hcGFyaU1vZGUgJiYgIWlzU3BhdGlhbE1vZGVcIlxuICAgICAgW3Nob3dTdGFja109XCIhIWltYWdlSW5mbz8uc2hvd1N0YWNrXCJcbiAgICAgIFtzdGFja09wdGlvbnNdPVwic3RhY2tPcHRpb25zXCJcbiAgICAgIFt6SW5kZXhdPVwiekluZGV4XCJcbiAgICAgIFttYXhJbmRleF09XCJtYXhJbmRleFwiXG4gICAgICAoelNjcnViKT1cInpTY3J1Yi5lbWl0KCRldmVudClcIlxuICAgICAgKHpTbGlkZSk9XCJ6U2xpZGUuZW1pdCgkZXZlbnQpXCJcbiAgICAgIChzZWxlY3RTdGFja09wdGlvbik9XCJzZWxlY3RTdGFja09wdGlvbi5lbWl0KCRldmVudClcIlxuICAgICAgKHpJbmRleElucHV0KT1cInpJbmRleElucHV0LmVtaXQoJGV2ZW50KVwiXG4gICAgICAocmVsb2FkQW5kUGxvdCk9XCJyZWxvYWRBbmRQbG90LmVtaXQoKVwiXG4gICAgPlxuICAgIDwvdG9vbGJhci1zdGFjay1jb250cm9scz5cblxuICAgIDwhLS0gSW1hZ2UgYWN0aW9ucyAoc3BlY2lhbCB0b29scykgLS0+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInRvb2xzLnNwZWNpYWxUb29sc1wiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJ0b29sYmFyLXNlcGFyYXRvclwiPjwvc3Bhbj5cbiAgICAgIDxwLWJ1dHRvblxuICAgICAgICBpY29uPVwicGkgcGktZG93bmxvYWRcIlxuICAgICAgICBzaXplPVwic21hbGxcIlxuICAgICAgICBbdGV4dF09XCJ0cnVlXCJcbiAgICAgICAgYXJpYUxhYmVsPVwiRG93bmxvYWQgaW1hZ2UgYXMgUE5HXCJcbiAgICAgICAgcFRvb2x0aXA9XCJEb3dubG9hZCBpbWFnZSBhcyBQTkdcIlxuICAgICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgICAgICAob25DbGljayk9XCJkb3dubG9hZEltYWdlLmVtaXQoKVwiXG4gICAgICA+XG4gICAgICA8L3AtYnV0dG9uPlxuICAgICAgPHAtYnV0dG9uXG4gICAgICAgICpuZ0lmPVwiaXNIZWF0bWFwXCJcbiAgICAgICAgaWNvbj1cInBpIHBpLXdpbmRvdy1tYXhpbWl6ZVwiXG4gICAgICAgIHNpemU9XCJzbWFsbFwiXG4gICAgICAgIFt0ZXh0XT1cInRydWVcIlxuICAgICAgICBhcmlhTGFiZWw9XCJGaXQgdG8gdmlld1wiXG4gICAgICAgIHBUb29sdGlwPVwiRml0IHRvIHZpZXdcIlxuICAgICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgICAgICAob25DbGljayk9XCJhdXRvc2NhbGVJbWFnZS5lbWl0KClcIlxuICAgICAgPlxuICAgICAgPC9wLWJ1dHRvbj5cbiAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgIDx0b29sYmFyLXZpZXctY29udHJvbHNcbiAgICAgIFtpc0hlYXRtYXBdPVwiaXNIZWF0bWFwXCJcbiAgICAgIFt6b29tVG9vbHNdPVwidG9vbHMuem9vbVRvb2xzXCJcbiAgICAgIFtpc0ltYWdlVmlld109XCJpc0ltYWdlVmlld1wiXG4gICAgICBbYWN0aXZlRHJhZ01vZGVdPVwiYWN0aXZlRHJhZ01vZGVcIlxuICAgICAgW2FjdGl2ZVN1cmZhY2UzZE1vZGVdPVwiYWN0aXZlU3VyZmFjZTNkTW9kZVwiXG4gICAgICBbaXNOYXBhcmlNb2RlXT1cImlzTmFwYXJpTW9kZVwiXG4gICAgICBbaXNOYXBhcmlTdXJmYWNlTW9kZV09XCJpc05hcGFyaVN1cmZhY2VNb2RlXCJcbiAgICAgIFtpc05hcGFyaTNkTW9kZV09XCJpc05hcGFyaTNkTW9kZVwiXG4gICAgICBbYXhlc1Zpc2libGVdPVwiYXhlc1Zpc2libGVcIlxuICAgICAgW3dpcmVmcmFtZUFjdGl2ZV09XCJ3aXJlZnJhbWVBY3RpdmVcIlxuICAgICAgW3Jlc29sdXRpb25TY2FsZV09XCJyZXNvbHV0aW9uU2NhbGVcIlxuICAgICAgKHRvZ2dsZURyYWdNb2RlKT1cInRvZ2dsZURyYWdNb2RlLmVtaXQoJGV2ZW50KVwiXG4gICAgICAoem9vbUluKT1cInpvb21Jbi5lbWl0KClcIlxuICAgICAgKHpvb21PdXQpPVwiem9vbU91dC5lbWl0KClcIlxuICAgICAgKHRvZ2dsZVN1cmZhY2UzZE1vZGUpPVwidG9nZ2xlU3VyZmFjZTNkTW9kZS5lbWl0KCRldmVudClcIlxuICAgICAgKHJlc2V0U3VyZmFjZUNhbWVyYSk9XCJyZXNldFN1cmZhY2VDYW1lcmEuZW1pdCgpXCJcbiAgICAgICh0b2dnbGVBeGVzKT1cInRvZ2dsZUF4ZXMuZW1pdCgpXCJcbiAgICAgICh0b2dnbGVXaXJlZnJhbWUpPVwidG9nZ2xlV2lyZWZyYW1lLmVtaXQoKVwiXG4gICAgICAoc2VsZWN0UmVzb2x1dGlvbik9XCJzZWxlY3RSZXNvbHV0aW9uLmVtaXQoJGV2ZW50KVwiXG4gICAgPlxuICAgIDwvdG9vbGJhci12aWV3LWNvbnRyb2xzPlxuXG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIihpc0hlYXRtYXAgfHwgaXMzZFJlZ2lvbnMpICYmIHRvb2xzLnJlZ2lvblRvb2xzXCI+XG4gICAgICA8dG9vbGJhci1yZWdpb24tdG9vbHNcbiAgICAgICAgW2FjdGl2ZURyYWdNb2RlXT1cImFjdGl2ZURyYWdNb2RlXCJcbiAgICAgICAgW2lzM2RSZWdpb25zXT1cImlzM2RSZWdpb25zXCJcbiAgICAgICAgW3ZlcnRleFRvb2xzXT1cInN1cHBvcnRzUmVnaW9uVmVydGV4VG9vbHNcIlxuICAgICAgICBbd2FuZFNlbnNpdGl2aXR5XT1cIndhbmRTZW5zaXRpdml0eVwiXG4gICAgICAgIFticnVzaFNpemVdPVwiYnJ1c2hTaXplXCJcbiAgICAgICAgW3ZlcnRleEVyYXNlclJhZGl1c109XCJ2ZXJ0ZXhFcmFzZXJSYWRpdXNcIlxuICAgICAgICBbY2FuVW5kb109XCJjYW5VbmRvXCJcbiAgICAgICAgW2NhblJlZG9dPVwiY2FuUmVkb1wiXG4gICAgICAgIChvcGVuUmVnaW9uRWRpdG9yKT1cIm9wZW5SZWdpb25FZGl0b3IuZW1pdCgpXCJcbiAgICAgICAgKHRvZ2dsZURyYWdNb2RlKT1cInRvZ2dsZURyYWdNb2RlLmVtaXQoJGV2ZW50KVwiXG4gICAgICAgICh1bmRvUmVnaW9uKT1cInVuZG9SZWdpb24uZW1pdCgpXCJcbiAgICAgICAgKHJlZG9SZWdpb24pPVwicmVkb1JlZ2lvbi5lbWl0KClcIlxuICAgICAgICAoZGVsZXRlUmVnaW9uKT1cImRlbGV0ZVJlZ2lvbi5lbWl0KClcIlxuICAgICAgICAod2FuZFNlbnNpdGl2aXR5Q2hhbmdlKT1cIndhbmRTZW5zaXRpdml0eUNoYW5nZS5lbWl0KCRldmVudClcIlxuICAgICAgICAoYnJ1c2hTaXplQ2hhbmdlKT1cImJydXNoU2l6ZUNoYW5nZS5lbWl0KCRldmVudClcIlxuICAgICAgICAodmVydGV4RXJhc2VyUmFkaXVzQ2hhbmdlKT1cInZlcnRleEVyYXNlclJhZGl1c0NoYW5nZS5lbWl0KCRldmVudClcIlxuICAgICAgPlxuICAgICAgPC90b29sYmFyLXJlZ2lvbi10b29scz5cbiAgICAgIDx0b29sYmFyLXNlZ21lbnRhdGlvbi10b29sc1xuICAgICAgICBbYWN0aXZlRHJhZ01vZGVdPVwiYWN0aXZlRHJhZ01vZGVcIlxuICAgICAgICBbc2FtTW9kZWxzXT1cInNhbU1vZGVsc1wiXG4gICAgICAgIFtzYW1Nb2RlbElkXT1cInNhbU1vZGVsSWRcIlxuICAgICAgICBbY29udHJpYnV0ZWRUb29sc109XCJjb250cmlidXRlZFRvb2xzXCJcbiAgICAgICAgW3Rvb2xNb2RlbElkc109XCJ0b29sTW9kZWxJZHNcIlxuICAgICAgICAoc2VnbWVudFJlZ2lvbnMpPVwic2VnbWVudFJlZ2lvbnMuZW1pdCgpXCJcbiAgICAgICAgKHNlZ21lbnRDZWxscG9zZSk9XCJzZWdtZW50Q2VsbHBvc2UuZW1pdCgpXCJcbiAgICAgICAgKHRvZ2dsZURyYWdNb2RlKT1cInRvZ2dsZURyYWdNb2RlLmVtaXQoJGV2ZW50KVwiXG4gICAgICAgIChzYW1Nb2RlbENoYW5nZSk9XCJzYW1Nb2RlbENoYW5nZS5lbWl0KCRldmVudClcIlxuICAgICAgICAocnVuVG9vbCk9XCJydW5Ub29sLmVtaXQoJGV2ZW50KVwiXG4gICAgICAgICh0b29sTW9kZWxDaGFuZ2UpPVwidG9vbE1vZGVsQ2hhbmdlLmVtaXQoJGV2ZW50KVwiXG4gICAgICAgIChvcGVuVG9vbFBhcmFtcyk9XCJvcGVuVG9vbFBhcmFtcy5lbWl0KCRldmVudClcIlxuICAgICAgPlxuICAgICAgPC90b29sYmFyLXNlZ21lbnRhdGlvbi10b29scz5cbiAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJ0b29scy5oZWxwXCI+XG4gICAgICA8c3BhbiBjbGFzcz1cInRvb2xiYXItc2VwYXJhdG9yXCI+PC9zcGFuPlxuXG4gICAgICA8IS0tIEhlbHAgLS0+XG4gICAgICA8cC1idXR0b25cbiAgICAgICAgaWNvbj1cInBpIHBpLXF1ZXN0aW9uLWNpcmNsZVwiXG4gICAgICAgIHNpemU9XCJzbWFsbFwiXG4gICAgICAgIFt0ZXh0XT1cInRydWVcIlxuICAgICAgICBhcmlhTGFiZWw9XCJIZWxwXCJcbiAgICAgICAgcFRvb2x0aXA9XCJIZWxwXCJcbiAgICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgICAgKG9uQ2xpY2spPVwic2hvd0hlbHAoKVwiXG4gICAgICA+XG4gICAgICA8L3AtYnV0dG9uPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L2Rpdj5cbjwvcC10b29sYmFyPlxuPHRvb2xiYXItaGVscC1kaWFsb2dcbiAgWyh2aXNpYmxlKV09XCJkaXNwbGF5SGVscERpYWxvZ1wiXG4gIFtjb250cmlidXRlZFRvb2xzXT1cImNvbnRyaWJ1dGVkVG9vbHNcIlxuICBbZGlhbG9nVG9vbHNdPVwiZGlhbG9nVG9vbHNcIlxuPlxuPC90b29sYmFyLWhlbHAtZGlhbG9nPlxuIl19
419
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbGJhci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3Rvb2xiYXIvdG9vbGJhci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9zcmMvbGliL3Rvb2xiYXIvdG9vbGJhci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2hHLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFHaEQsT0FBTyxFQUNMLFFBQVEsRUFFUixpQkFBaUIsRUFDakIsVUFBVSxFQUNWLGtCQUFrQixFQUNsQixlQUFlLEVBQ2YsZUFBZSxFQUNmLHVCQUF1QixFQUN2QixjQUFjLEVBQ2QsZ0JBQWdCLEdBQ2pCLE1BQU0sd0JBQXdCLENBQUM7QUFDaEMsT0FBTyxFQUF5QixpQkFBaUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBR3ZGLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLHFEQUFxRCxDQUFDO0FBQ2pHLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLG1EQUFtRCxDQUFDO0FBQzlGLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLDJDQUEyQyxDQUFDO0FBQ25GLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHlDQUF5QyxDQUFDO0FBQ2hGLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHVDQUF1QyxDQUFD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QUFNO2dCQUVHLG9CQUFvQjtzQkFBN0IsTUFBTTtnQkFJRyxjQUFjO3NCQUF2QixNQUFNO2dCQUVHLG9CQUFvQjtzQkFBN0IsTUFBTTtnQkFFRyxtQkFBbUI7c0JBQTVCLE1BQU07Z0JBRUcsZ0JBQWdCO3NCQUF6QixNQUFNO2dCQUVHLGlCQUFpQjtzQkFBMUIsTUFBTTtnQkFFRyxpQkFBaUI7c0JBQTFCLE1BQU07Z0JBRUcsTUFBTTtzQkFBZixNQUFNO2dCQUVHLE1BQU07c0JBQWYsTUFBTTtnQkFFRyxXQUFXO3NCQUFwQixNQUFNO2dCQUVHLGFBQWE7c0JBQXRCLE1BQU07Z0JBRUcsYUFBYTtzQkFBdEIsTUFBTTtnQkFFRyxjQUFjO3NCQUF2QixNQUFNO2dCQUVHLGNBQWM7c0JBQXZCLE1BQU07Z0JBRUcsTUFBTTtzQkFBZixNQUFNO2dCQUVHLE9BQU87c0JBQWhCLE1BQU07Z0JBRUcsbUJBQW1CO3NCQUE1QixNQUFNO2dCQUVHLGtCQUFrQjtzQkFBM0IsTUFBTTtnQkFFRyxVQUFVO3NCQUFuQixNQUFNO2dCQUVHLGVBQWU7c0JBQXhCLE1BQU07Z0JBRUcsZ0JBQWdCO3NCQUF6QixNQUFNO2dCQUVHLFlBQVk7c0JBQXJCLE1BQU07Z0JBRUcsVUFBVTtzQkFBbkIsTUFBTTtnQkFFRyxVQUFVO3NCQUFuQixNQUFNO2dCQUVHLGNBQWM7c0JBQXZCLE1BQU07Z0JBRUcsZUFBZTtzQkFBeEIsTUFBTTtnQkFFRyxPQUFPO3NCQUFoQixNQUFNO2dCQUVHLGdCQUFnQjtzQkFBekIsTUFBTTtnQkFFRyxlQUFlO3NCQUF4QixNQUFNO2dCQUVHLGNBQWM7c0JBQXZCLE1BQU07Z0JBRUcsY0FBYztzQkFBdkIsTUFBTTtnQkFFRyxxQkFBcUI7c0JBQTlCLE1BQU07Z0JBRUcsZUFBZTtzQkFBeEIsTUFBTTtnQkFFRyx3QkFBd0I7c0JBQWpDLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBCdXR0b25Nb2R1bGUgfSBmcm9tICdwcmltZW5nL2J1dHRvbic7XG5pbXBvcnQgeyBSaXBwbGVNb2R1bGUgfSBmcm9tICdwcmltZW5nL3JpcHBsZSc7XG5pbXBvcnQgeyBUb29sYmFyTW9kdWxlIH0gZnJvbSAncHJpbWVuZy90b29sYmFyJztcbmltcG9ydCB7IFRvb2x0aXBNb2R1bGUgfSBmcm9tICdwcmltZW5nL3Rvb2x0aXAnO1xuXG5pbXBvcnQgeyBJSW1hZ2VJbmZvIH0gZnJvbSAnLi4vY29udHJhY3RzL2ltYWdlLmNvbnRyYWN0JztcbmltcG9ydCB7XG4gIFBsb3RUeXBlLFxuICBQbG90VHlwZUlkLFxuICBpc0J1aWx0aW5QbG90VHlwZSxcbiAgaXNOYXBhcmkzZCxcbiAgaXNOYXBhcmlJc29zdXJmYWNlLFxuICBpc05hcGFyaVN1cmZhY2UsXG4gIGlzTmFwYXJpU2NhdHRlcixcbiAgTkFQQVJJX0RFRkFVTFRfREVDSU1BVEUsXG4gIGlzU3BhdGlhbE9taWNzLFxuICBpc1NwYXRpYWxPbWljczNkLFxufSBmcm9tICcuLi9jb250cmFjdHMvcGxvdC10eXBlJztcbmltcG9ydCB7IFRvb2xiYXJUb29sVmlzaWJpbGl0eSwgQUxMX1RPT0xCQVJfVE9PTFMgfSBmcm9tICcuLi9jb250cmFjdHMvdG9vbGJhci1jb25maWcnO1xuaW1wb3J0IHsgVG9vbGJhckRpYWxvZ1Rvb2xDb250cmlidXRpb24sIFRvb2xiYXJUb29sQ29udHJpYnV0aW9uIH0gZnJvbSAnLi4vY29udHJhY3RzL3Rvb2xiYXItdG9vbC5jb250cmFjdCc7XG5pbXBvcnQgeyBQbG90VHlwZU9wdGlvbiB9IGZyb20gJy4uL2NvbnRyYWN0cy9wbG90LXR5cGUtY29udHJpYnV0aW9uLmNvbnRyYWN0JztcbmltcG9ydCB7IFRvb2xiYXJIZWxwRGlhbG9nQ29tcG9uZW50IH0gZnJvbSAnLi90b29sYmFyLWhlbHAtZGlhbG9nL3Rvb2xiYXItaGVscC1kaWFsb2cuY29tcG9uZW50JztcbmltcG9ydCB7IFBsb3RUeXBlU2VsZWN0b3JDb21wb25lbnQgfSBmcm9tICcuL3Bsb3QtdHlwZS1zZWxlY3Rvci9wbG90LXR5cGUtc2VsZWN0b3IuY29tcG9uZW50JztcbmltcG9ydCB7IFN0YWNrQ29udHJvbHNDb21wb25lbnQgfSBmcm9tICcuL3N0YWNrLWNvbnRyb2xzL3N0YWNrLWNvbnRyb2xzLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBWaWV3Q29udHJvbHNDb21wb25lbnQgfSBmcm9tICcuL3ZpZXctY29udHJvbHMvdmlldy1jb250cm9scy5jb21wb25lbnQnO1xuaW1wb3J0IHsgUmVnaW9uVG9vbHNDb21wb25lbnQgfSBmcm9tICcuL3JlZ2lvbi10b29scy9yZWdpb24tdG9vbHMuY29tcG9uZW50JztcbmltcG9ydCB7IFNlZ21lbnRhdGlvblRvb2xzQ29tcG9uZW50IH0gZnJvbSAnLi9zZWdtZW50YXRpb24tdG9vbHMvc2VnbWVudGF0aW9uLXRvb2xzLmNvbXBvbmVudCc7XG5cbi8qKlxuICogUHJlc2VudGF0aW9uYWwgdG9vbGJhciBmb3IgdGhlIHBsb3R0aW5nIHZpZXdwb3J0LlxuICpcbiAqIFJlbmRlcnMgdGhlIHBsb3QtdHlwZSBzZWxlY3RvciwgY29sb3JtYXAvTFVUIGNvbnRyb2xzLCBzdGFjayBuYXZpZ2F0aW9uLFxuICogaW1hZ2UgYWN0aW9ucyAoZG93bmxvYWQgLyBhdXRvc2NhbGUgLyBwaXBlbGluZSksIHZpZXdwb3J0IHpvb20vcGFuLCB0aGVcbiAqIFN1cmZhY2UtM0QgY2FtZXJhIGNvbnRyb2xzLCBhbmQgdGhlIHJlZ2lvbi1kcmF3aW5nIHRvb2xzIOKAlCBwbHVzIHRoZSBwbG90dGluZ1xuICogaGVscCBkaWFsb2cuIEl0IG93bnMgbm8gcmVuZGVyaW5nIG9yIHZpc3VhbGl6YXRpb24gc3RhdGU6IHRoZSBob3N0XG4gKiAoVmlzdWFsaXplckNvbXBvbmVudCkgc3RheXMgdGhlIG9yY2hlc3RyYXRvciwgcGFzc2luZyBzdGF0ZSBpbiB2aWEgYEBJbnB1dGAgYW5kXG4gKiBoYW5kbGluZyBldmVyeSBhY3Rpb24gdmlhIGBAT3V0cHV0YC4gVGhlIHNhbWUgYWN0aW9ucyBhcmUgYWxzbyBkcml2ZW4gYnkgdGhlXG4gKiBkaWFncmFtJ3MgcmlnaHQtY2xpY2sgY29udGV4dCBtZW51IGFuZCBrZXlib2FyZCBzaG9ydGN1dHMsIHNvIGtlZXBpbmcgdGhlXG4gKiBoYW5kbGVycyBpbiB0aGUgaG9zdCBhdm9pZHMgZHVwbGljYXRpbmcgdGhhdCBsb2dpYy5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAncGxvdHRpbmctdG9vbGJhcicsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGUsXG4gICAgQnV0dG9uTW9kdWxlLFxuICAgIFJpcHBsZU1vZHVsZSxcbiAgICBUb29sYmFyTW9kdWxlLFxuICAgIFRvb2x0aXBNb2R1bGUsXG4gICAgVG9vbGJhckhlbHBEaWFsb2dDb21wb25lbnQsXG4gICAgUGxvdFR5cGVTZWxlY3RvckNvbXBvbmVudCxcbiAgICBTdGFja0NvbnRyb2xzQ29tcG9uZW50LFxuICAgIFZpZXdDb250cm9sc0NvbXBvbmVudCxcbiAgICBSZWdpb25Ub29sc0NvbXBvbmVudCxcbiAgICBTZWdtZW50YXRpb25Ub29sc0NvbXBvbmVudCxcbiAgXSxcbiAgdGVtcGxhdGVVcmw6ICcuL3Rvb2xiYXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi90b29sYmFyLmNvbXBvbmVudC5zY3NzJ10sXG4gIC8vIFB1cmVseSBASW5wdXQvQE91dHB1dDogcmUtY2hlY2sgb25seSB3aGVuIGFuIGlucHV0IGNoYW5nZXMgb3IgdGhlIHRvb2xiYXJcbiAgLy8gaXRzZWxmIGhhbmRsZXMgYW4gZXZlbnQsIG5vdCBvbiBldmVyeSBhcHAgdGljayAoaXRzIH4xNSBnZXR0ZXJzIHJhbiBlYWNoXG4gIC8vIHRpbWUpLiBDb250cm9scyBiaW5kIFtuZ01vZGVsXSBvbmUtd2F5IGFuZCByZXBvcnQgdGhyb3VnaCB0aGUgb3V0cHV0cywgc29cbiAgLy8gdGhlIGhvc3Qgc3RheXMgdGhlIG93bmVyIG9mIGV2ZXJ5IHZhbHVlIChSVC0zNSkuXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBUb29sYmFyQ29tcG9uZW50IHtcbiAgLyoqIEN1cnJlbnQgaW1hZ2UgKGdhdGVzIHdoaWNoIGNvbnRyb2wgZ3JvdXBzIGFyZSBzaG93bikuICovXG4gIEBJbnB1dCgpIGltYWdlSW5mbzogSUltYWdlSW5mbyB8IHVuZGVmaW5lZDtcbiAgLyoqIEEgc3BhdGlhbCBkYXRhc2V0IGlzIG9uIG9mZmVyOiBpdHMgcGxvdCBtb2RlcyBhcmUgYSBjaG9pY2UgZXZlbiB3aXRoIG5vIGltYWdlIGxvYWRlZC4gKi9cbiAgQElucHV0KCkgaGFzU3BhdGlhbERhdGFzZXQgPSBmYWxzZTtcblxuICAvKiogV2hldGhlciB0aGUgcGxvdC10eXBlIGRyb3Bkb3duIHNob3dzOiBmb3IgYW4gaW1hZ2UsIG9yIGEgc3BhdGlhbCBkYXRhc2V0IHdpdGggbm9uZS4gKi9cbiAgcHJvdGVjdGVkIGdldCBzaG93UGxvdFR5cGVzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhISh0aGlzLmltYWdlSW5mbyB8fCB0aGlzLmhhc1NwYXRpYWxEYXRhc2V0KSAmJiAhIXRoaXMudG9vbHMuc3BlY2lhbFRvb2xzO1xuICB9XG4gIC8qKiBQbG90IHR5cGVzIHRoZSBhY3RpdmUgYmFja2VuZCBhZHZlcnRpc2VzLCB0aGVuIGFueSBjb250cmlidXRlZCBtb2Rlcy4gKi9cbiAgQElucHV0KCkgcGxvdFR5cGVPcHRpb25zOiBQbG90VHlwZU9wdGlvbltdID0gW107XG4gIC8qKiBUaGUgc2VsZWN0b3IncyB2YWx1ZTogYSBidWlsdC1pbiB0eXBlIG9yIGEgY29udHJpYnV0ZWQgbW9kZSdzIGlkLiAqL1xuICBASW5wdXQoKSBzZWxlY3RlZFBsb3RUeXBlOiBQbG90VHlwZUlkID0gUGxvdFR5cGUuSU1BR0U7XG4gIC8qKlxuICAgKiBUaGUgYnVpbHQtaW4gdHlwZSB0aGF0IHJlbmRlcnMge0BsaW5rIHNlbGVjdGVkUGxvdFR5cGV9IOKAlCBpdHMgYGJhc2VUeXBlYFxuICAgKiBmb3IgYSBjb250cmlidXRlZCBtb2RlLiBFdmVyeSB0b29sL2NvbnRyb2wgZGVjaXNpb24gYmVsb3cgcmVhZHNcbiAgICoge0BsaW5rIGVmZmVjdGl2ZVBsb3RUeXBlfSwgc28gYSBjb250cmlidXRlZCBtb2RlIGdldHMgZXhhY3RseSBpdHMgYmFzZVxuICAgKiB0eXBlJ3MgdG9vbGJhci4gV2hlbiB1bmJvdW5kLCBhIGJ1aWx0LWluIHNlbGVjdGlvbiBpcyBpdHMgb3duIGJhc2UgYW5kXG4gICAqIGFueXRoaW5nIGVsc2UgaXMgdHJlYXRlZCBhcyB0aGUgZGVmYXVsdCBJbWFnZSB2aWV3LlxuICAgKi9cbiAgQElucHV0KCkgYmFzZVBsb3RUeXBlOiBQbG90VHlwZSB8IG51bGwgPSBudWxsO1xuICAvKiogSXNvc3VyZmFjZSBiYW5kIGFzIGEgMOKAkzI1NSBzbGlkZXIgcG9zaXRpb24gKG1hcHBlZCBvbnRvIHRoZSB2b2x1bWUncyByZWFsXG4gICAqICBpbnRlbnNpdHkgcmFuZ2UgYnkgdGhlIHJlbmRlcmVyKS4gRGVmYXVsdHMgdG8gdGhlIGZ1bGwgcmFuZ2UuICovXG4gIEBJbnB1dCgpIGlzb1JhbmdlOiBudW1iZXJbXSA9IFswLCAyNTVdO1xuICAvKiogVGhlIGxhc3Qgc2xpY2UgaW5kZXggb2YgYSBzdGFjay4gKi9cbiAgQElucHV0KCkgbWF4SW5kZXggPSAwO1xuICAvKiogVGhlIGN1cnJlbnQgc2xpY2UgKDAtYmFzZWQpLiAqL1xuICBASW5wdXQoKSB6SW5kZXggPSAwO1xuICAvKiogVHJ1ZSBmb3IgYW55IDJEIChub24gU3VyZmFjZS0zRCkgcGxvdCB0eXBlLiAqL1xuICBASW5wdXQoKSBpc0hlYXRtYXAgPSB0cnVlO1xuICAvKipcbiAgICogUmVnaW9uIHRvb2xzIGFwcGx5IGV2ZW4gdGhvdWdoIHRoaXMgaXMgYSAzRCB2aWV3LCBiZWNhdXNlIHRoZXkgZHJhdyBhXG4gICAqIFNDUkVFTi1TUEFDRSBsYXNzbyAodGhlIDNEIHNwYXRpYWwgY2xvdWQpLiBTZXBhcmF0ZSBmcm9tIHtAbGluayBpc0hlYXRtYXB9LFxuICAgKiB3aGljaCBtZWFucyBcIjJEIHZpZXdcIiBhbmQgYWxzbyBkcml2ZXMgdGhlIHpvb20gdG9vbHMgYW5kIHRoZSAzRCBjYW1lcmFcbiAgICogY29udHJvbHMg4oCUIGZsaXBwaW5nIHRoYXQgd291bGQgc2hvdyAyRCBwYW4vem9vbSBhbmQgaGlkZSB0aGUgb3JiaXQgY29udHJvbHMuXG4gICAqL1xuICBASW5wdXQoKSBpczNkUmVnaW9ucyA9IGZhbHNlO1xuICAvKiogQSBuYXBhcmkgdm9sdW1lIC8gaXNvc3VyZmFjZSB2aWV3OiB0aGUgUmVnaW9uIEVkaXRvciAocmVnaW9ucyBpbiAzRCkgd2l0aG91dCBkcmF3aW5nIHRvb2xzLiAqL1xuICBASW5wdXQoKSBpc1ZvbHVtZVZpZXcgPSBmYWxzZTtcbiAgLyoqIFdoZXRoZXIgdGhlIHZvbHVtZSB2aWV3IGlzIHNwbGl0IHdpdGggdGhlIHNsaWNlIGVkaXRvciAodGhlIHNsaWNlLCB3aXRoIGV2ZXJ5IHJlZ2lvbiB0b29sKS4gKi9cbiAgQElucHV0KCkgc2xpY2VFZGl0b3IgPSBmYWxzZTtcbiAgLyoqIFRoZSBhcm1lZCB0b29sJ3MgbW9kZSAoem9vbSwgcGFuLCBhIGRyYXdpbmcgdG9vbCwgYHNhbVBvaW50YCwg4oCmKSwgb3IgbnVsbC4gKi9cbiAgQElucHV0KCkgYWN0aXZlRHJhZ01vZGU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICAvKiogVGhlIDNEIGNhbWVyYSBtb2RlIChgdHVybnRhYmxlYCAvIGBvcmJpdGAgLyDigKYpLiAqL1xuICBASW5wdXQoKSBhY3RpdmVTdXJmYWNlM2RNb2RlID0gJ3R1cm50YWJsZSc7XG4gIC8qKiBXaGV0aGVyIHRoZSBuYXBhcmkgM0QgYXhlcy9zY2FsZSBnaXptbyBpcyBjdXJyZW50bHkgc2hvd24gKGRyaXZlcyB0aGUgdG9nZ2xlJ3MgbG9vaykuICovXG4gIEBJbnB1dCgpIGF4ZXNWaXNpYmxlID0gdHJ1ZTtcbiAgLyoqIFRoZSBuYXBhcmkgc3VyZmFjZSB3aXJlZnJhbWUgaXMgb24uICovXG4gIEBJbnB1dCgpIHdpcmVmcmFtZUFjdGl2ZSA9IGZhbHNlO1xuICAvKiogQWN0aXZlIG5hcGFyaSAzRCBkZWNpbWF0ZSBmYWN0b3IgKDEgPSBGdWxsIOKApiA4ID0g4oWbOyBkZWZhdWx0IMK9KS4gKi9cbiAgQElucHV0KCkgcmVzb2x1dGlvblNjYWxlID0gTkFQQVJJX0RFRkFVTFRfREVDSU1BVEU7XG4gIC8qKiBNYWdpYy13YW5kIHNlbnNpdGl2aXR5LiAqL1xuICBASW5wdXQoKSB3YW5kU2Vuc2l0aXZpdHkgPSAyLjA7XG4gIC8qKiBCcnVzaCBkaWFtZXRlciBpbiBpbWFnZSBwaXhlbHMuICovXG4gIEBJbnB1dCgpIGJydXNoU2l6ZSA9IDQwO1xuICAvKiogVmVydGV4LWVyYXNlciByYWRpdXMgaW4gaW1hZ2UgcGl4ZWxzLiAqL1xuICBASW5wdXQoKSB2ZXJ0ZXhFcmFzZXJSYWRpdXMgPSAyMDtcbiAgLyoqIFdoZXRoZXIgYSByZWdpb24gYWN0aW9uIGlzIGF2YWlsYWJsZSB0byB1bmRvIChqaXQtdWkjODUpLiBHcmV5cyBvdXQgdGhlXG4gICAqICBVbmRvIGJ1dHRvbiB3aGVuIGZhbHNlIChub3RoaW5nIGRvbmUgeWV0LCBvciBhbGwgc3RlcHMgYWxyZWFkeSB1bmRvbmUpLiAqL1xuICBASW5wdXQoKSBjYW5VbmRvID0gZmFsc2U7XG4gIC8qKiBXaGV0aGVyIGFuIHVuZG9uZSByZWdpb24gYWN0aW9uIGlzIGF2YWlsYWJsZSB0byByZWRvIChqaXQtdWkjODUpLiBHcmV5c1xuICAgKiAgb3V0IHRoZSBSZWRvIGJ1dHRvbiB3aGVuIGZhbHNlLiAqL1xuICBASW5wdXQoKSBjYW5SZWRvID0gZmFsc2U7XG4gIC8qKiBUaGUgc2luZ2xlLWltYWdlIC8gc3RhY2sgY2hvaWNlcyBvZiB0aGUgUGxvdGx5IHN0YWNrIHRvZ2dsZS4gKi9cbiAgQElucHV0KCkgc3RhY2tPcHRpb25zOiB7IG5hbWU6IHN0cmluZzsgdmFsOiBzdHJpbmcgfVtdID0gW1xuICAgIHsgbmFtZTogJ1NpbmdsZSBpbWFnZScsIHZhbDogJ2ZhbHNlJyB9LFxuICAgIHsgbmFtZTogJ1N0YWNrJywgdmFsOiAndHJ1ZScgfSxcbiAgXTtcbiAgLyoqIFdoaWNoIHRvb2xiYXIgZ3JvdXBzIHRvIHNob3cuIERlZmF1bHRzIHRvIHRoZSBmdWxsIHRvb2xiYXI7IHRoZSBob3N0IGZvcndhcmRzXG4gICAqICB0aGUgY29uc3VtZXIncyBjaG9pY2UgKGUuZy4gdGhlIHBpcGVsaW5lIHNob3dzIG9ubHkgem9vbSArIHJlZ2lvbiB0b29scykuICovXG4gIEBJbnB1dCgpIHRvb2xzOiBSZXF1aXJlZDxUb29sYmFyVG9vbFZpc2liaWxpdHk+ID0gQUxMX1RPT0xCQVJfVE9PTFM7XG4gIC8qKiBDdXJyZW50IGltYWdlLXNtb290aGluZyBzdGF0ZSAoZHJpdmVzIHRoZSBTbW9vdGhlbiB0b2dnbGUgYnV0dG9uIGxvb2spLlxuICAgKiAgYGZhbHNlYCA9IG5lYXJlc3QtbmVpZ2hib3VyIChjcmlzcCByYXcgcGl4ZWxzKSwgdGhlIGRlZmF1bHQuICovXG4gIEBJbnB1dCgpIGltYWdlU21vb3RoaW5nRW5hYmxlZCA9IGZhbHNlO1xuICAvKiogU0FNIG1vZGVsIHBpY2tlciBvcHRpb25zICsgY3VycmVudCBzZWxlY3Rpb24gKGppdC11aSM5MCBQMSkuICovXG4gIEBJbnB1dCgpIHNhbU1vZGVsczogeyBpZDogc3RyaW5nOyBsYWJlbDogc3RyaW5nIH1bXSA9IFtdO1xuICAvKiogVGhlIHNlbGVjdGVkIFNBTSBtb2RlbCBpZC4gKi9cbiAgQElucHV0KCkgc2FtTW9kZWxJZCA9ICcnO1xuICAvKipcbiAgICogVG9vbHMgY29udHJpYnV0ZWQgdGhyb3VnaCB7QGxpbmsgVE9PTEJBUl9UT09MU30sIGFscmVhZHkgZmlsdGVyZWQgdG8gdGhlXG4gICAqIG9uZXMgd2l0aCBtb2RlbHMgYW5kIHNvcnRlZC4gVGhlIGhvc3QgcmVzb2x2ZXMgdGhlbSBzbyBpdCBjYW4gb3duIHRoZVxuICAgKiBwZXItdG9vbCBwYXJhbWV0ZXIgc3RhdGU7IHRoaXMgY29tcG9uZW50IG9ubHkgZHJhd3MgdGhlbS5cbiAgICovXG4gIEBJbnB1dCgpIGNvbnRyaWJ1dGVkVG9vbHM6IFRvb2xiYXJUb29sQ29udHJpYnV0aW9uW10gPSBbXTtcbiAgLyoqIERpYWxvZyB0b29scyAoVE9PTEJBUl9UT09MUywga2luZDogJ2RpYWxvZycpLCBzb3J0ZWQ7IHNob3duIGluIHRoZSBJbWFnZSB2aWV3LiAqL1xuICBASW5wdXQoKSBkaWFsb2dUb29sczogVG9vbGJhckRpYWxvZ1Rvb2xDb250cmlidXRpb25bXSA9IFtdO1xuICAvKiogSWQgb2YgdGhlIGRpYWxvZyB0b29sIHdob3NlIGRpYWxvZyBpcyBvcGVuLCBvciBudWxsLiAqL1xuICBASW5wdXQoKSBvcGVuRGlhbG9nVG9vbElkOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgLyoqIEFjdGl2ZSBjaGVja3BvaW50IHBlciBjb250cmlidXRlZCB0b29sLCBrZXllZCBieSB0b29sIGlkLiAqL1xuICBASW5wdXQoKSB0b29sTW9kZWxJZHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblxuICAvKiogQSBwbG90IHR5cGUgb3IgY29udHJpYnV0ZWQgbW9kZSB3YXMgcGlja2VkLiAqL1xuICBAT3V0cHV0KCkgc2VsZWN0UGxvdFR5cGUgPSBuZXcgRXZlbnRFbWl0dGVyPFBsb3RUeXBlSWQ+KCk7XG4gIC8qKiBJbnRlbnNpdHkgKExJTkUpIG1vZGU6IGFkZCBhbm90aGVyIGNvbG9yZWQgbGluZSBST0kgKyBpbnNldCB0cmFjZS4gKi9cbiAgQE91dHB1dCgpIGFkZFByb2ZpbGVMaW5lID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogVG9nZ2xlIGltYWdlIHNtb290aGluZyAoYmlsaW5lYXIpIHZzIG5lYXJlc3QtbmVpZ2hib3VyIChjcmlzcCBwaXhlbHMpLiAqL1xuICBAT3V0cHV0KCkgdG9nZ2xlSW1hZ2VTbW9vdGhpbmcgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8vIFByaW1lTkcgc2xpZGVyL2lucHV0TnVtYmVyIGNoYW5nZSBldmVudHMgY2Fycnkgb3B0aW9uYWwgdmFsdWVzLCBtaXJyb3JlZCBieVxuICAvLyB0aGUgaG9zdCBoYW5kbGVycyAod2hpY2ggYWNjZXB0IGB8IHVuZGVmaW5lZGApLlxuICAvKiogVGhlIGlzb3N1cmZhY2UgYmFuZCBzbGlkZXIgbW92ZWQ6IHRoZSBuZXcgYFtsb3csIGhpZ2hdYCBwYWlyLiAqL1xuICBAT3V0cHV0KCkgaXNvUmFuZ2VDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcltdIHwgdW5kZWZpbmVkPigpO1xuICAvKiogT3BlbiB0aGUgQ2hhbm5lbHMgJiBIaXN0b2dyYW0gZGlhbG9nIChicmlnaHRuZXNzL2NvbnRyYXN0LCBjb2xvcm1hcCwg4oCmKS4gKi9cbiAgQE91dHB1dCgpIG9wZW5DaGFubmVsSGlzdG9ncmFtID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogT3BlbiB0aGUgc3BhdGlhbC1vbWljcyBjb250cm9scyAoY29sb3VyLWJ5LCBsZWdlbmQsIHBvaW50IGRpc3BsYXkpLiAqL1xuICBAT3V0cHV0KCkgb3BlblNwYXRpYWxDb250cm9scyA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIE9wZW4gdGhlIFJlZ2lvbiBFZGl0b3IgZGlhbG9nLiAqL1xuICBAT3V0cHV0KCkgb3BlblJlZ2lvbkVkaXRvciA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIFNwbGl0IHRoZSB2b2x1bWUgdmlldyB3aXRoIHRoZSBzbGljZSBlZGl0b3IsIG9yIGNsb3NlIGl0LiAqL1xuICBAT3V0cHV0KCkgdG9nZ2xlU2xpY2VFZGl0b3IgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBBIHNpbmdsZS1pbWFnZSAvIHN0YWNrIGNob2ljZSB3YXMgcGlja2VkLiAqL1xuICBAT3V0cHV0KCkgc2VsZWN0U3RhY2tPcHRpb24gPSBuZXcgRXZlbnRFbWl0dGVyPHsgbmFtZTogc3RyaW5nOyB2YWw6IHN0cmluZyB9PigpO1xuICAvKiogVGhlIGxpdmUgc2xpY2Ugc2NydWJiZXIgbW92ZWQgKGZpcmVzIHdoaWxlIGRyYWdnaW5nKS4gKi9cbiAgQE91dHB1dCgpIHpTY3J1YiA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyIHwgdW5kZWZpbmVkPigpO1xuICAvKiogVGhlIGxpdmUgc2xpY2Ugc2NydWJiZXIgd2FzIHJlbGVhc2VkIG9uIGEgc2xpY2UuICovXG4gIEBPdXRwdXQoKSB6U2xpZGUgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlciB8IHVuZGVmaW5lZD4oKTtcbiAgLyoqIEEgc2xpY2UgbnVtYmVyIHdhcyB0eXBlZC4gKi9cbiAgQE91dHB1dCgpIHpJbmRleElucHV0ID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG4gIC8qKiBSZS1wbG90IGF0IHRoZSB0eXBlZCBzbGljZS4gKi9cbiAgQE91dHB1dCgpIHJlbG9hZEFuZFBsb3QgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBEb3dubG9hZCB0aGUgY3VycmVudCB2aWV3IGFzIFBORy4gKi9cbiAgQE91dHB1dCgpIGRvd25sb2FkSW1hZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBGaXQgdGhlIGltYWdlIHRvIHRoZSB2aWV3LiAqL1xuICBAT3V0cHV0KCkgYXV0b3NjYWxlSW1hZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBBIHpvb20gLyBwYW4gLyBkcmF3aW5nIHRvb2wgYnV0dG9uIHdhcyBjbGlja2VkIChpdHMgbW9kZSkuICovXG4gIEBPdXRwdXQoKSB0b2dnbGVEcmFnTW9kZSA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICAvKiogWm9vbSBpbiBvbmUgc3RlcC4gKi9cbiAgQE91dHB1dCgpIHpvb21JbiA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIFpvb20gb3V0IG9uZSBzdGVwLiAqL1xuICBAT3V0cHV0KCkgem9vbU91dCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIEEgM0QgY2FtZXJhIG1vZGUgYnV0dG9uIHdhcyBjbGlja2VkIChpdHMgbW9kZSkuICovXG4gIEBPdXRwdXQoKSB0b2dnbGVTdXJmYWNlM2RNb2RlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIC8qKiBSZXNldCB0aGUgM0QgY2FtZXJhLiAqL1xuICBAT3V0cHV0KCkgcmVzZXRTdXJmYWNlQ2FtZXJhID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogVG9nZ2xlIHRoZSBuYXBhcmkgM0QgY29vcmRpbmF0ZS1heGVzIC8gc2NhbGUgZ2l6bW8gb24vb2ZmLiAqL1xuICBAT3V0cHV0KCkgdG9nZ2xlQXhlcyA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIFRvZ2dsZSB0aGUgbmFwYXJpIHN1cmZhY2Ugd2lyZWZyYW1lIChlZGdlcykgb24vb2ZmLiAqL1xuICBAT3V0cHV0KCkgdG9nZ2xlV2lyZWZyYW1lID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogQ2hhbmdlIHRoZSBuYXBhcmkgM0QgZGVjaW1hdGUgZmFjdG9yIChyZWxvYWRzIGF0IHRoZSBuZXcgcmVzb2x1dGlvbikuICovXG4gIEBPdXRwdXQoKSBzZWxlY3RSZXNvbHV0aW9uID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG4gIC8qKiBEZWxldGUgdGhlIHNlbGVjdGVkIHJlZ2lvbi4gKi9cbiAgQE91dHB1dCgpIGRlbGV0ZVJlZ2lvbiA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIFVuZG8gdGhlIGxhc3QgcmVnaW9uIGFjdGlvbiAoaml0LXVpIzg1KS4gKi9cbiAgQE91dHB1dCgpIHVuZG9SZWdpb24gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBSZWRvIHRoZSBsYXN0IHVuZG9uZSByZWdpb24gYWN0aW9uIChqaXQtdWkjODUpLiAqL1xuICBAT3V0cHV0KCkgcmVkb1JlZ2lvbiA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIFJ1biBib3gtcHJvbXB0ZWQgU0FNIHNlZ21lbnRhdGlvbiBvbiB0aGUgZHJhd24gcmVjdGFuZ2xlcyAoaml0LXVpIzkwKS4gKi9cbiAgQE91dHB1dCgpIHNlZ21lbnRSZWdpb25zID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAvKiogUnVuIGNlbGxwb3NlLVNBTSAoYXV0bykgaW5zaWRlIGVhY2ggZHJhd24gcmVjdGFuZ2xlJ3MgY3JvcCAoaml0LXVpIzkwKS4gKi9cbiAgQE91dHB1dCgpIHNlZ21lbnRDZWxscG9zZSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIFJ1biBhIGNvbnRyaWJ1dGVkIHRvb2wgb3ZlciB0aGUgY3VycmVudCB2aWV3LCBieSB0b29sIGlkLiAqL1xuICBAT3V0cHV0KCkgcnVuVG9vbCA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICAvKiogQSBkaWFsb2cgdG9vbCdzIGJ1dHRvbiB3YXMgY2xpY2tlZDogb3BlbiBpdHMgZGlhbG9nLCBvciBjbG9zZSBpdCBpZiBvcGVuLiAqL1xuICBAT3V0cHV0KCkgdG9nZ2xlRGlhbG9nVG9vbCA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICAvKiogUGljayBhIGNvbnRyaWJ1dGVkIHRvb2wncyBjaGVja3BvaW50LiAqL1xuICBAT3V0cHV0KCkgdG9vbE1vZGVsQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjx7IHRvb2xJZDogc3RyaW5nOyBtb2RlbElkOiBzdHJpbmcgfT4oKTtcbiAgLyoqIE9wZW4gYSBjb250cmlidXRlZCB0b29sJ3MgcGFyYW1ldGVyIGRpYWxvZywgYnkgdG9vbCBpZC4gKi9cbiAgQE91dHB1dCgpIG9wZW5Ub29sUGFyYW1zID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIC8qKiBTQU0gbW9kZWwgcGlja2VyIChqaXQtdWkjOTAgUDEpLiAqL1xuICBAT3V0cHV0KCkgc2FtTW9kZWxDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgLyoqIFRoZSB3YW5kIHNlbnNpdGl2aXR5IHNsaWRlciBtb3ZlZC4gKi9cbiAgQE91dHB1dCgpIHdhbmRTZW5zaXRpdml0eUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyIHwgdW5kZWZpbmVkPigpO1xuICAvKiogVGhlIGJydXNoIHNpemUgc2xpZGVyIG1vdmVkLiAqL1xuICBAT3V0cHV0KCkgYnJ1c2hTaXplQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXIgfCB1bmRlZmluZWQ+KCk7XG4gIC8qKiBUaGUgdmVydGV4LWVyYXNlciByYWRpdXMgc2xpZGVyIG1vdmVkLiAqL1xuICBAT3V0cHV0KCkgdmVydGV4RXJhc2VyUmFkaXVzQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXIgfCB1bmRlZmluZWQ+KCk7XG5cbiAgcHJvdGVjdGVkIGRpc3BsYXlIZWxwRGlhbG9nID0gZmFsc2U7XG5cbiAgLyoqIHRyYWNrQnkgZm9yIHRoZSBkaWFsb2cgdG9vbHMnIGJ1dHRvbnMuICovXG4gIHByb3RlY3RlZCB0cmFja1Rvb2xCeUlkKF9pbmRleDogbnVtYmVyLCB0b29sOiB7IGlkOiBzdHJpbmcgfSk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRvb2wuaWQ7XG4gIH1cblxuICAvKiogVGhlIGJ1aWx0LWluIHR5cGUgd2hvc2UgdG9vbHMgYW5kIGNvbnRyb2xzIGFwcGx5IHRvIHRoZSBjdXJyZW50IHNlbGVjdGlvbi4gKi9cbiAgcHJvdGVjdGVkIGdldCBlZmZlY3RpdmVQbG90VHlwZSgpOiBQbG90VHlwZSB7XG4gICAgaWYgKHRoaXMuYmFzZVBsb3RUeXBlKSByZXR1cm4gdGhpcy5iYXNlUGxvdFR5cGU7XG4gICAgcmV0dXJuIGlzQnVpbHRpblBsb3RUeXBlKHRoaXMuc2VsZWN0ZWRQbG90VHlwZSkgPyB0aGlzLnNlbGVjdGVkUGxvdFR5cGUgOiBQbG90VHlwZS5JTUFHRTtcbiAgfVxuXG4gIC8qKiBUaGUgSW1hZ2UgcGxvdCB0eXBlIHJlbmRlcnMgYXMgYSBuYXRpdmVseSBwYW4vem9vbS1hYmxlIHJhc3Rlciwgc28gdGhlXG4gICAqICBnZW5lcmljIHpvb20vcGFuIHRvb2xzIGFyZSBoaWRkZW4uICovXG4gIHByb3RlY3RlZCBnZXQgaXNJbWFnZVZpZXcoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZWZmZWN0aXZlUGxvdFR5cGUgPT09IFBsb3RUeXBlLklNQUdFO1xuICB9XG5cbiAgLyoqIEVpdGhlciBzcGF0aWFsLW9taWNzIG1vZGUgaXMgYWN0aXZlLCBzbyBpdHMgY29udHJvbHMgYXJlIHdvcnRoIG9mZmVyaW5nLlxuICAgKiAgVGhlIDNEIGNsb3VkIG5lZWRzIHRoZSBwYW5lbCBNT1JFIHRoYW4gdGhlIDJEIHZpZXcgZG9lcywgbm90IGxlc3M6IGNvbG91cmluZyxcbiAgICogIHRoZSBsZWdlbmQgYW5kIGNhdGVnb3J5IHNob3cvaGlkZSBhcmUgdGhlIG9ubHkgd2F5IHRvIG1ha2Ugc2Vuc2Ugb2YgYVxuICAgKiAgbWlsbGlvbiBvdmVybGFwcGluZyBwb2ludHMuICovXG4gIHByb3RlY3RlZCBnZXQgaXNTcGF0aWFsTW9kZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaXNTcGF0aWFsT21pY3ModGhpcy5lZmZlY3RpdmVQbG90VHlwZSkgfHwgaXNTcGF0aWFsT21pY3MzZCh0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlKTtcbiAgfVxuXG4gIC8qKiBCYWNrZW5kcyB3aXRoIGEgdmVydGV4LWVkaXRpbmcgcmVnaW9uIG92ZXJsYXk6IE9TRCBJbWFnZSBhbmQgbmFwYXJpLWpzIFdlYkdQVSBpbWFnZVxuICAgKiAgKGppdC11aSMxMDIpLiBHYXRlcyB0aGUgcG9seWdvbiAvIGFkZC12ZXJ0ZXggLyBkZWxldGUtdmVydGV4IC8gQsOpemllci1jb252ZXJ0IHRvb2xzLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IHN1cHBvcnRzUmVnaW9uVmVydGV4VG9vbHMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZWZmZWN0aXZlUGxvdFR5cGUgPT09IFBsb3RUeXBlLklNQUdFIHx8IHRoaXMuZWZmZWN0aXZlUGxvdFR5cGUgPT09IFBsb3RUeXBlLk5BUEFSSV9JTUFHRTtcbiAgfVxuXG4gIC8qKiBQbG90IHR5cGVzIHRoYXQgc2NydWIgYSB6LXN0YWNrIGxpdmUgKHRoZSByZW5kZXJlciBzd2FwcyB0aGUgc2xpY2UgaW4gcGxhY2UpOiB0aGUgT1NEIEltYWdlXG4gICAqICB2aWV3LCB0aGUgbmFwYXJpLWpzIFdlYkdQVSBpbWFnZSwgdGhlIG5hcGFyaS1qcyBzdXJmYWNlIOKAlCB3aGljaCByZWJ1aWxkcyB0aGUgaGVpZ2h0IGZpZWxkXG4gICAqICBmcm9tIHRoZSBwaWNrZWQgc2xpY2UgKGppdC11aSMxMDIpIOKAlCBhbmQgdGhlIDJEIHNwYXRpYWwtb21pY3Mgdmlldywgd2hlcmUgYSAzRCBkYXRhc2V0J3NcbiAgICogIHJlZ2lzdGVyZWQgdm9sdW1lIGlzIHRoZSBpbWFnZSBhbmQgdGhlIHNsaWRlciBwaWNrcyB0aGUgc2VjdGlvbiB3aG9zZSBvYnNlcnZhdGlvbnMgYXJlXG4gICAqICBkcmF3bi4gQWxzbyBhIHNwbGl0IHZvbHVtZSB2aWV3LCB3aG9zZSBzbGljZSBlZGl0b3Igc2hvd3MgdGhlIHNsaWNlIHBpY2tlZC4gRHJpdmVzIHRoZVxuICAgKiAgcGVyLXNsaWNlIHNsaWRlci4gKi9cbiAgcHJvdGVjdGVkIGdldCBzaG93c0xpdmVTbGljZVNjcnViYmVyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICAodGhpcy5pc1ZvbHVtZVZpZXcgJiYgdGhpcy5zbGljZUVkaXRvcikgfHxcbiAgICAgIHRoaXMuZWZmZWN0aXZlUGxvdFR5cGUgPT09IFBsb3RUeXBlLklNQUdFIHx8XG4gICAgICB0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlID09PSBQbG90VHlwZS5OQVBBUklfSU1BR0UgfHxcbiAgICAgIGlzTmFwYXJpU3VyZmFjZSh0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlKSB8fFxuICAgICAgaXNOYXBhcmlTY2F0dGVyKHRoaXMuZWZmZWN0aXZlUGxvdFR5cGUpIHx8XG4gICAgICBpc1NwYXRpYWxPbWljcyh0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlKVxuICAgICk7XG4gIH1cblxuICAvKiogQW55IG5hcGFyaS1qcyBXZWJHUFUgcGxvdCB0eXBlLiBUaGUgc2luZ2xlLWltYWdlL3N0YWNrIHRvZ2dsZSArIHNsaWNlLW51bWJlciBmaWVsZCBhcmVcbiAgICogIFBsb3RseS1vbmx5IHN0YWNrIGNvbnRyb2xzLCBzbyB0aGV5J3JlIGhpZGRlbiBmb3IgbmFwYXJpIChqaXQtdWkjMTAyKS4gKi9cbiAgcHJvdGVjdGVkIGdldCBpc05hcGFyaU1vZGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuZWZmZWN0aXZlUGxvdFR5cGUgPT09IFBsb3RUeXBlLk5BUEFSSV9JTUFHRSB8fFxuICAgICAgaXNOYXBhcmlTY2F0dGVyKHRoaXMuZWZmZWN0aXZlUGxvdFR5cGUpIHx8XG4gICAgICBpc05hcGFyaTNkKHRoaXMuZWZmZWN0aXZlUGxvdFR5cGUpXG4gICAgKTtcbiAgfVxuXG4gIC8qKiBJU09TVVJGQUNFIChQbG90bHkgb3IgbmFwYXJpLWpzIFdlYkdQVSwgZWl0aGVyIHJlc29sdXRpb24pIHNob3dzIHRoZSBpc292YWx1ZSByYW5nZSBzbGlkZXIuICovXG4gIHByb3RlY3RlZCBnZXQgaXNJc29zdXJmYWNlTW9kZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5lZmZlY3RpdmVQbG90VHlwZSA9PT0gUGxvdFR5cGUuSVNPU1VSRkFDRSB8fCBpc05hcGFyaUlzb3N1cmZhY2UodGhpcy5lZmZlY3RpdmVQbG90VHlwZSk7XG4gIH1cblxuICAvKiogVGhlIG5hcGFyaS1qcyBXZWJHUFUgc3VyZmFjZSDigJQgc2hvd3MgdGhlIHdpcmVmcmFtZSB0b2dnbGUuICovXG4gIHByb3RlY3RlZCBnZXQgaXNOYXBhcmlTdXJmYWNlTW9kZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaXNOYXBhcmlTdXJmYWNlKHRoaXMuZWZmZWN0aXZlUGxvdFR5cGUpO1xuICB9XG5cbiAgLyoqIEFueSBuYXBhcmktanMgV2ViR1BVIDNEIHR5cGUgKHZvbHVtZS9pc29zdXJmYWNlL3N1cmZhY2UpIOKAlCBzaG93cyB0aGUgUmVzb2x1dGlvbiBjb250cm9sLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGlzTmFwYXJpM2RNb2RlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpc05hcGFyaTNkKHRoaXMuZWZmZWN0aXZlUGxvdFR5cGUpO1xuICB9XG5cbiAgLyoqIEludGVuc2l0eSBwcm9maWxlIGxpbmVzIGFyZSBSZWdpb24tYmFzZWQgYW5kIGF2YWlsYWJsZSBpbiB0aGUgSGVhdG1hcCBhbmRcbiAgICogIEltYWdlIHBsb3QgdHlwZXMsIHdoaWNoIHNob3cgdGhlIEludGVuc2l0eSB0b29sIGdyb3VwLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGlzSW50ZW5zaXR5Q2FwYWJsZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5lZmZlY3RpdmVQbG90VHlwZSA9PT0gUGxvdFR5cGUuSEVBVE1BUCB8fCB0aGlzLmVmZmVjdGl2ZVBsb3RUeXBlID09PSBQbG90VHlwZS5JTUFHRTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzaG93SGVscCgpOiB2b2lkIHtcbiAgICB0aGlzLmRpc3BsYXlIZWxwRGlhbG9nID0gdHJ1ZTtcbiAgfVxufVxuIiwiPHAtdG9vbGJhcj5cbiAgPGRpdiBjbGFzcz1cInAtdG9vbGJhci1ncm91cC1zdGFydCBmbGV4LXdyYXAgYWxpZ24taXRlbXMtY2VudGVyIGdhcC0xXCI+XG4gICAgPCEtLSBIb3N0LXByb3ZpZGVkIGN1c3RvbSB0b29sYmFyIGJ1dHRvbnMsIHNob3duIGZpcnN0IChlLmcuIGFwcC1zcGVjaWZpY1xuICAgICAgICAgYWN0aW9ucyB0aGUgdmlzdWFsaXphdGlvbiB2aWV3IGl0c2VsZiBkb2Vzbid0IG93bikuIC0tPlxuICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cblxuICAgIDwhLS0gQ29udHJpYnV0ZWQgZGlhbG9nIHRvb2xzIChUT09MQkFSX1RPT0xTLCBraW5kOiAnZGlhbG9nJyk6IGFwcC1sZXZlbCBhY3Rpb25zXG4gICAgICAgICBsaWtlIHRoZSBob3N0J3Mgb3duIGJ1dHRvbnMgYWJvdmUsIHNvIHRoZXkgc2l0IHJpZ2h0IGJlc2lkZSB0aGVtLiBJbWFnZSB2aWV3XG4gICAgICAgICBvbmx5LCB0aGUgdmlldyB0aGVpciBkaWFsb2cgZHJhd3Mgb3Zlci4gSGlnaGxpZ2h0ZWQgd2hpbGUgdGhlIGRpYWxvZyBpcyBvcGVuLiAtLT5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNJbWFnZVZpZXdcIj5cbiAgICAgIDxwLWJ1dHRvblxuICAgICAgICAqbmdGb3I9XCJsZXQgdG9vbCBvZiBkaWFsb2dUb29sczsgdHJhY2tCeTogdHJhY2tUb29sQnlJZFwiXG4gICAgICAgIHNpemU9XCJzbWFsbFwiXG4gICAgICAgIFt0ZXh0XT1cIm9wZW5EaWFsb2dUb29sSWQgIT09IHRvb2wuaWRcIlxuICAgICAgICBbcFRvb2x0aXBdPVwidG9vbC50b29sdGlwXCJcbiAgICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgICAgW2FyaWFMYWJlbF09XCJ0b29sLmxhYmVsXCJcbiAgICAgICAgW2F0dHIuYXJpYS1wcmVzc2VkXT1cIm9wZW5EaWFsb2dUb29sSWQgPT09IHRvb2wuaWRcIlxuICAgICAgICAob25DbGljayk9XCJ0b2dnbGVEaWFsb2dUb29sLmVtaXQodG9vbC5pZClcIlxuICAgICAgPlxuICAgICAgICA8aW1nXG4gICAgICAgICAgKm5nSWY9XCJ0b29sLmljb24uc3JjXCJcbiAgICAgICAgICBbc3JjXT1cInRvb2wuaWNvbi5zcmNcIlxuICAgICAgICAgIHN0eWxlPVwid2lkdGg6IDFyZW1cIlxuICAgICAgICAgIFthbHRdPVwidG9vbC5sYWJlbFwiXG4gICAgICAgICAgW2NsYXNzXT1cIm9wZW5EaWFsb2dUb29sSWQgPT09IHRvb2wuaWQgPyAndG9vbGJhci1pY29uLWFjdGl2ZScgOiAndG9vbGJhci1pY29uLWRhcmsnXCJcbiAgICAgICAgLz5cbiAgICAgICAgPGkgKm5nSWY9XCJ0b29sLmljb24ucGlcIiBjbGFzcz1cInBpIHt7IHRvb2wuaWNvbi5waSB9fVwiPjwvaT5cbiAgICAgIDwvcC1idXR0b24+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8IS0tIFBsb3QgdHlwZTogYXZhaWxhYmxlIGZvciBhbnkgaW1hZ2UgKGdyYXlzY2FsZSBvciBSR0IpLCBhbmQgZm9yIGEgc3BhdGlhbCBkYXRhc2V0XG4gICAgICAgICB0aGF0IGJyaW5ncyBub25lIChpdHMgc3BhdGlhbCBtb2RlcyBhcmUgc3RpbGwgYSBjaG9pY2UpLiAtLT5cbiAgICA8dG9vbGJhci1wbG90LXR5cGUtc2VsZWN0b3JcbiAgICAgICpuZ0lmPVwic2hvd1Bsb3RUeXBlc1wiXG4gICAgICBbb3B0aW9uc109XCJwbG90VHlwZU9wdGlvbnNcIlxuICAgICAgW3NlbGVjdGVkXT1cInNlbGVjdGVkUGxvdFR5cGVcIlxuICAgICAgW2lzb3N1cmZhY2VdPVwiaXNJc29zdXJmYWNlTW9kZVwiXG4gICAgICBbaXNvUmFuZ2VdPVwiaXNvUmFuZ2VcIlxuICAgICAgW2ludGVuc2l0eUxpbmVzXT1cImlzSW50ZW5zaXR5Q2FwYWJsZVwiXG4gICAgICAoc2VsZWN0UGxvdFR5cGUpPVwic2VsZWN0UGxvdFR5cGUuZW1pdCgkZXZlbnQpXCJcbiAgICAgIChpc29SYW5nZUNoYW5nZSk9XCJpc29SYW5nZUNoYW5nZS5lbWl0KCRldmVudClcIlxuICAgICAgKGFkZFByb2ZpbGVMaW5lKT1cImFkZFByb2ZpbGVMaW5lLmVtaXQoKVwiXG4gICAgPlxuICAgIDwvdG9vbGJhci1wbG90LXR5cGUtc2VsZWN0b3I+XG4gICAgPCEtLSBDaGFubmVscyAmIEhpc3RvZ3JhbTogYnJpZ2h0bmVzcy9jb250cmFzdCwgZ2FtbWEsIHBlci1jaGFubmVsIGRpc3BsYXksXG4gICAgICAgICBjb2xvcm1hcC9yZXZlcnNlL2ludmVydCDigJQgb3BlbnMgdGhlIGZsb2F0aW5nIGRpYWxvZy4gLS0+XG4gICAgPHAtYnV0dG9uXG4gICAgICAqbmdJZj1cInRvb2xzLnNwZWNpYWxUb29sc1wiXG4gICAgICBwUmlwcGxlXG4gICAgICBzaXplPVwic21hbGxcIlxuICAgICAgW3RleHRdPVwidHJ1ZVwiXG4gICAgICBhcmlhTGFiZWw9XCJDaGFubmVscyAmYW1wOyBIaXN0b2dyYW1cIlxuICAgICAgcFRvb2x0aXA9XCJDaGFubmVscyAmYW1wOyBIaXN0b2dyYW0gKGJyaWdodG5lc3MvY29udHJhc3QsIGNvbG9ybWFwKVwiXG4gICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgICAgKG9uQ2xpY2spPVwib3BlbkNoYW5uZWxIaXN0b2dyYW0uZW1pdCgpXCJcbiAgICA+XG4gICAgICA8aW1nIHNyYz1cImFzc2V0cy9wbG90dGluZy9pbnZlcnQuc3ZnXCIgY2xhc3M9XCJ0b29sYmFyLWljb24tZGFya1wiIHN0eWxlPVwid2lkdGg6IDFyZW1cIiAvPlxuICAgIDwvcC1idXR0b24+XG5cbiAgICA8IS0tIFNwYXRpYWwtb21pY3MgY29udHJvbHMuIE9ubHkgbWVhbmluZ2Z1bCBpbiB0aGUgc3BhdGlhbCBtb2RlLCB3aGljaCBpc1xuICAgICAgICAgaXRzZWxmIG9ubHkgb2ZmZXJlZCB3aGlsZSBhIGRhdGFzZXQgaXMgbG9hZGVkIOKAlCBzbyB0aGlzIGJ1dHRvbiBhcHBlYXJzXG4gICAgICAgICBleGFjdGx5IHdoZW4gdGhlcmUgaXMgc29tZXRoaW5nIGZvciBpdCB0byBjb250cm9sLiAtLT5cbiAgICA8cC1idXR0b25cbiAgICAgICpuZ0lmPVwidG9vbHMuc3BlY2lhbFRvb2xzICYmIGlzU3BhdGlhbE1vZGVcIlxuICAgICAgcFJpcHBsZVxuICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgIFt0ZXh0XT1cInRydWVcIlxuICAgICAgYXJpYUxhYmVsPVwiU3BhdGlhbCBvbWljcyBjb250cm9sc1wiXG4gICAgICBwVG9vbHRpcD1cIlNwYXRpYWwgb21pY3MgKGNvbG91ciBieSBjb2x1bW4gb3IgZ2VuZSwgbGVnZW5kLCBzZWxlY3Rpb24sIGRpc3RyaWJ1dGlvbnMpXCJcbiAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgICAob25DbGljayk9XCJvcGVuU3BhdGlhbENvbnRyb2xzLmVtaXQoKVwiXG4gICAgPlxuICAgICAgPGltZyBzcmM9XCJhc3NldHMvcGxvdHRpbmcvc3BhdGlhbC1vbWljcy5zdmdcIiBjbGFzcz1cInRvb2xiYXItaWNvbi1kYXJrXCIgc3R5bGU9XCJ3aWR0aDogMXJlbVwiIC8+XG4gICAgPC9wLWJ1dHRvbj5cblxuICAgIDwhLS0gU21vb3RoZW4gdG9nZ2xlOiBiaWxpbmVhciBzbW9vdGhpbmcgdnMgbmVhcmVzdC1uZWlnaGJvdXIgcmF3IHBpeGVscyAoSW1hZ2VcbiAgICAgICAgIHZpZXcgb25seSDigJQgaXQncyBhbiBPcGVuU2VhZHJhZ29uIGRyYXdlciBzZXR0aW5nKS4gSGlnaGxpZ2h0ZWQgd2hlbiBzbW9vdGhpbmcgb24uIC0tPlxuICAgIDxwLWJ1dHRvblxuICAgICAgKm5nSWY9XCJ0b29scy5zcGVjaWFsVG9vbHMgJiYgaXNJbWFnZVZpZXdcIlxuICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgIFt0ZXh0XT1cIiFpbWFnZVNtb290aGluZ0VuYWJsZWRcIlxuICAgICAgYXJpYUxhYmVsPVwiU21vb3RoZW5cIlxuICAgICAgcFRvb2x0aXA9XCJTbW9vdGhlbiAodHVybiBvbiBpbWFnZSBzbW9vdGhpbmcpXCJcbiAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgICAob25DbGljayk9XCJ0b2dnbGVJbWFnZVNtb290aGluZy5lbWl0KClcIlxuICAgID5cbiAgICAgIDxpbWdcbiAgICAgICAgc3JjPVwiYXNzZXRzL3Bsb3R0aW5nL3Ntb290aC5zdmdcIlxuICAgICAgICBzdHlsZT1cIndpZHRoOiAxcmVtXCJcbiAgICAgICAgW2NsYXNzXT1cImltYWdlU21vb3RoaW5nRW5hYmxlZCA/ICd0b29sYmFyLWljb24tYWN0aXZlJyA6ICd0b29sYmFyLWljb24tZGFyaydcIlxuICAgICAgLz5cbiAgICA8L3AtYnV0dG9uPlxuXG4gICAgPCEtLSBTdGFjayBjb250cm9scyAtLT5cbiAgICA8dG9vbGJhci1zdGFjay1jb250cm9sc1xuICAgICAgKm5nSWY9XCJpbWFnZUluZm8/LmlzU3RhY2tcIlxuICAgICAgW2xpdmVTY3J1YmJlcl09XCJzaG93c0xpdmVTbGljZVNjcnViYmVyXCJcbiAgICAgIFtzdGFja1RvZ2dsZV09XCIhc2hvd3NMaXZlU2xpY2VTY3J1YmJlciAmJiAhaXNOYXBhcmlNb2RlICYmICFpc1NwYXRpYWxNb2RlXCJcbiAgICAgIFtzaG93U3RhY2tdPVwiISFpbWFnZUluZm8/LnNob3dTdGFja1wiXG4gICAgICBbc3RhY2tPcHRpb25zXT1cInN0YWNrT3B0aW9uc1wiXG4gICAgICBbekluZGV4XT1cInpJbmRleFwiXG4gICAgICBbbWF4SW5kZXhdPVwibWF4SW5kZXhcIlxuICAgICAgKHpTY3J1Yik9XCJ6U2NydWIuZW1pdCgkZXZlbnQpXCJcbiAgICAgICh6U2xpZGUpPVwielNsaWRlLmVtaXQoJGV2ZW50KVwiXG4gICAgICAoc2VsZWN0U3RhY2tPcHRpb24pPVwic2VsZWN0U3RhY2tPcHRpb24uZW1pdCgkZXZlbnQpXCJcbiAgICAgICh6SW5kZXhJbnB1dCk9XCJ6SW5kZXhJbnB1dC5lbWl0KCRldmVudClcIlxuICAgICAgKHJlbG9hZEFuZFBsb3QpPVwicmVsb2FkQW5kUGxvdC5lbWl0KClcIlxuICAgID5cbiAgICA8L3Rvb2xiYXItc3RhY2stY29udHJvbHM+XG5cbiAgICA8IS0tIEltYWdlIGFjdGlvbnMgKHNwZWNpYWwgdG9vbHMpIC0tPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJ0b29scy5zcGVjaWFsVG9vbHNcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwidG9vbGJhci1zZXBhcmF0b3JcIj48L3NwYW4+XG4gICAgICA8cC1idXR0b25cbiAgICAgICAgaWNvbj1cInBpIHBpLWRvd25sb2FkXCJcbiAgICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgICAgW3RleHRdPVwidHJ1ZVwiXG4gICAgICAgIGFyaWFMYWJlbD1cIkRvd25sb2FkIGltYWdlIGFzIFBOR1wiXG4gICAgICAgIHBUb29sdGlwPVwiRG93bmxvYWQgaW1hZ2UgYXMgUE5HXCJcbiAgICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgICAgKG9uQ2xpY2spPVwiZG93bmxvYWRJbWFnZS5lbWl0KClcIlxuICAgICAgPlxuICAgICAgPC9wLWJ1dHRvbj5cbiAgICAgIDxwLWJ1dHRvblxuICAgICAgICAqbmdJZj1cImlzSGVhdG1hcFwiXG4gICAgICAgIGljb249XCJwaSBwaS13aW5kb3ctbWF4aW1pemVcIlxuICAgICAgICBzaXplPVwic21hbGxcIlxuICAgICAgICBbdGV4dF09XCJ0cnVlXCJcbiAgICAgICAgYXJpYUxhYmVsPVwiRml0IHRvIHZpZXdcIlxuICAgICAgICBwVG9vbHRpcD1cIkZpdCB0byB2aWV3XCJcbiAgICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgICAgKG9uQ2xpY2spPVwiYXV0b3NjYWxlSW1hZ2UuZW1pdCgpXCJcbiAgICAgID5cbiAgICAgIDwvcC1idXR0b24+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8dG9vbGJhci12aWV3LWNvbnRyb2xzXG4gICAgICBbaXNIZWF0bWFwXT1cImlzSGVhdG1hcFwiXG4gICAgICBbem9vbVRvb2xzXT1cInRvb2xzLnpvb21Ub29sc1wiXG4gICAgICBbaXNJbWFnZVZpZXddPVwiaXNJbWFnZVZpZXdcIlxuICAgICAgW2FjdGl2ZURyYWdNb2RlXT1cImFjdGl2ZURyYWdNb2RlXCJcbiAgICAgIFthY3RpdmVTdXJmYWNlM2RNb2RlXT1cImFjdGl2ZVN1cmZhY2UzZE1vZGVcIlxuICAgICAgW2lzTmFwYXJpTW9kZV09XCJpc05hcGFyaU1vZGVcIlxuICAgICAgW2lzTmFwYXJpU3VyZmFjZU1vZGVdPVwiaXNOYXBhcmlTdXJmYWNlTW9kZVwiXG4gICAgICBbaXNOYXBhcmkzZE1vZGVdPVwiaXNOYXBhcmkzZE1vZGVcIlxuICAgICAgW2F4ZXNWaXNpYmxlXT1cImF4ZXNWaXNpYmxlXCJcbiAgICAgIFt3aXJlZnJhbWVBY3RpdmVdPVwid2lyZWZyYW1lQWN0aXZlXCJcbiAgICAgIFtyZXNvbHV0aW9uU2NhbGVdPVwicmVzb2x1dGlvblNjYWxlXCJcbiAgICAgICh0b2dnbGVEcmFnTW9kZSk9XCJ0b2dnbGVEcmFnTW9kZS5lbWl0KCRldmVudClcIlxuICAgICAgKHpvb21Jbik9XCJ6b29tSW4uZW1pdCgpXCJcbiAgICAgICh6b29tT3V0KT1cInpvb21PdXQuZW1pdCgpXCJcbiAgICAgICh0b2dnbGVTdXJmYWNlM2RNb2RlKT1cInRvZ2dsZVN1cmZhY2UzZE1vZGUuZW1pdCgkZXZlbnQpXCJcbiAgICAgIChyZXNldFN1cmZhY2VDYW1lcmEpPVwicmVzZXRTdXJmYWNlQ2FtZXJhLmVtaXQoKVwiXG4gICAgICAodG9nZ2xlQXhlcyk9XCJ0b2dnbGVBeGVzLmVtaXQoKVwiXG4gICAgICAodG9nZ2xlV2lyZWZyYW1lKT1cInRvZ2dsZVdpcmVmcmFtZS5lbWl0KClcIlxuICAgICAgKHNlbGVjdFJlc29sdXRpb24pPVwic2VsZWN0UmVzb2x1dGlvbi5lbWl0KCRldmVudClcIlxuICAgID5cbiAgICA8L3Rvb2xiYXItdmlldy1jb250cm9scz5cblxuICAgIDwhLS0gQSB2b2x1bWUgdmlldyBkcmF3cyBubyByZWdpb25zOyB0aGUgUmVnaW9uIEVkaXRvciBzaG93cyB0aGVtIGluIGl0IGluIDNELCBhbmQgdGhlXG4gICAgICAgICBzZWxlY3Rpb24gdG9vbCBwaWNrcyB0aGVpciBzdXJmYWNlcyB0aGVyZS4gVGhlIHNsaWNlIGVkaXRvciBzcGxpdHMgdGhlIHZpZXc6IHRoZSBzbGljZSxcbiAgICAgICAgIHdpdGggZXZlcnkgcmVnaW9uIHRvb2wsIGJlc2lkZSB0aGUgM0Qgdmlldy4gLS0+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzVm9sdW1lVmlldyAmJiAhaXNIZWF0bWFwICYmICFpczNkUmVnaW9ucyAmJiB0b29scy5yZWdpb25Ub29sc1wiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJ0b29sYmFyLXNlcGFyYXRvclwiPjwvc3Bhbj5cbiAgICAgIDxwLWJ1dHRvblxuICAgICAgICBzaXplPVwic21hbGxcIlxuICAgICAgICBbdGV4dF09XCIhc2xpY2VFZGl0b3JcIlxuICAgICAgICBhcmlhTGFiZWw9XCJTbGljZSBlZGl0b3JcIlxuICAgICAgICBbYXR0ci5hcmlhLXByZXNzZWRdPVwic2xpY2VFZGl0b3JcIlxuICAgICAgICBbcFRvb2x0aXBdPVwiXG4gICAgICAgICAgc2xpY2VFZGl0b3JcbiAgICAgICAgICAgID8gJ0Nsb3NlIHRoZSBzbGljZSBlZGl0b3InXG4gICAgICAgICAgICA6ICdTbGljZSBlZGl0b3I6IHRoZSBzbGljZSBhbmQgdGhlIHNlY3Rpb25zIHRocm91Z2ggeCBhbmQgeSBiZXNpZGUgdGhlIDNEIHZpZXcnXG4gICAgICAgIFwiXG4gICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgICAgIChvbkNsaWNrKT1cInRvZ2dsZVNsaWNlRWRpdG9yLmVtaXQoKVwiXG4gICAgICA+XG4gICAgICAgIDxpbWdcbiAgICAgICAgICBzcmM9XCJhc3NldHMvcGxvdHRpbmcvc2xpY2Uuc3ZnXCJcbiAgICAgICAgICBzdHlsZT1cIndpZHRoOiAxcmVtXCJcbiAgICAgICAgICBhbHQ9XCJcIlxuICAgICAgICAgIFtjbGFzc109XCJzbGljZUVkaXRvciA/ICd0b29sYmFyLWljb24tYWN0aXZlJyA6ICd0b29sYmFyLWljb24tZGFyaydcIlxuICAgICAgICAvPlxuICAgICAgPC9wLWJ1dHRvbj5cbiAgICAgIDx0b29sYmFyLXJlZ2lvbi10b29sc1xuICAgICAgICAqbmdJZj1cIiFzbGljZUVkaXRvclwiXG4gICAgICAgIFthY3RpdmVEcmFnTW9kZV09XCJhY3RpdmVEcmFnTW9kZVwiXG4gICAgICAgIFtzZWxlY3RPbmx5XT1cInRydWVcIlxuICAgICAgICBbY2FuVW5kb109XCJjYW5VbmRvXCJcbiAgICAgICAgW2NhblJlZG9dPVwiY2FuUmVkb1wiXG4gICAgICAgIChvcGVuUmVnaW9uRWRpdG9yKT1cIm9wZW5SZWdpb25FZGl0b3IuZW1pdCgpXCJcbiAgICAgICAgKHRvZ2dsZURyYWdNb2RlKT1cInRvZ2dsZURyYWdNb2RlLmVtaXQoJGV2ZW50KVwiXG4gICAgICAgICh1bmRvUmVnaW9uKT1cInVuZG9SZWdpb24uZW1pdCgpXCJcbiAgICAgICAgKHJlZG9SZWdpb24pPVwicmVkb1JlZ2lvbi5lbWl0KClcIlxuICAgICAgICAoZGVsZXRlUmVnaW9uKT1cImRlbGV0ZVJlZ2lvbi5lbWl0KClcIlxuICAgICAgPlxuICAgICAgPC90b29sYmFyLXJlZ2lvbi10b29scz5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiKGlzSGVhdG1hcCB8fCBpczNkUmVnaW9ucyB8fCAoaXNWb2x1bWVWaWV3ICYmIHNsaWNlRWRpdG9yKSkgJiYgdG9vbHMucmVnaW9uVG9vbHNcIj5cbiAgICAgIDx0b29sYmFyLXJlZ2lvbi10b29sc1xuICAgICAgICBbYWN0aXZlRHJhZ01vZGVdPVwiYWN0aXZlRHJhZ01vZGVcIlxuICAgICAgICBbaXMzZFJlZ2lvbnNdPVwiaXMzZFJlZ2lvbnNcIlxuICAgICAgICBbdmVydGV4VG9vbHNdPVwic3VwcG9ydHNSZWdpb25WZXJ0ZXhUb29scyB8fCAoaXNWb2x1bWVWaWV3ICYmIHNsaWNlRWRpdG9yKVwiXG4gICAgICAgIFt3YW5kU2Vuc2l0aXZpdHldPVwid2FuZFNlbnNpdGl2aXR5XCJcbiAgICAgICAgW2JydXNoU2l6ZV09XCJicnVzaFNpemVcIlxuICAgICAgICBbdmVydGV4RXJhc2VyUmFkaXVzXT1cInZlcnRleEVyYXNlclJhZGl1c1wiXG4gICAgICAgIFtjYW5VbmRvXT1cImNhblVuZG9cIlxuICAgICAgICBbY2FuUmVkb109XCJjYW5SZWRvXCJcbiAgICAgICAgKG9wZW5SZWdpb25FZGl0b3IpPVwib3BlblJlZ2lvbkVkaXRvci5lbWl0KClcIlxuICAgICAgICAodG9nZ2xlRHJhZ01vZGUpPVwidG9nZ2xlRHJhZ01vZGUuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgKHVuZG9SZWdpb24pPVwidW5kb1JlZ2lvbi5lbWl0KClcIlxuICAgICAgICAocmVkb1JlZ2lvbik9XCJyZWRvUmVnaW9uLmVtaXQoKVwiXG4gICAgICAgIChkZWxldGVSZWdpb24pPVwiZGVsZXRlUmVnaW9uLmVtaXQoKVwiXG4gICAgICAgICh3YW5kU2Vuc2l0aXZpdHlDaGFuZ2UpPVwid2FuZFNlbnNpdGl2aXR5Q2hhbmdlLmVtaXQoJGV2ZW50KVwiXG4gICAgICAgIChicnVzaFNpemVDaGFuZ2UpPVwiYnJ1c2hTaXplQ2hhbmdlLmVtaXQoJGV2ZW50KVwiXG4gICAgICAgICh2ZXJ0ZXhFcmFzZXJSYWRpdXNDaGFuZ2UpPVwidmVydGV4RXJhc2VyUmFkaXVzQ2hhbmdlLmVtaXQoJGV2ZW50KVwiXG4gICAgICA+XG4gICAgICA8L3Rvb2xiYXItcmVnaW9uLXRvb2xzPlxuICAgICAgPHRvb2xiYXItc2VnbWVudGF0aW9uLXRvb2xzXG4gICAgICAgIFthY3RpdmVEcmFnTW9kZV09XCJhY3RpdmVEcmFnTW9kZVwiXG4gICAgICAgIFtzYW1Nb2RlbHNdPVwic2FtTW9kZWxzXCJcbiAgICAgICAgW3NhbU1vZGVsSWRdPVwic2FtTW9kZWxJZFwiXG4gICAgICAgIFtjb250cmlidXRlZFRvb2xzXT1cImNvbnRyaWJ1dGVkVG9vbHNcIlxuICAgICAgICBbdG9vbE1vZGVsSWRzXT1cInRvb2xNb2RlbElkc1wiXG4gICAgICAgIChzZWdtZW50UmVnaW9ucyk9XCJzZWdtZW50UmVnaW9ucy5lbWl0KClcIlxuICAgICAgICAoc2VnbWVudENlbGxwb3NlKT1cInNlZ21lbnRDZWxscG9zZS5lbWl0KClcIlxuICAgICAgICAodG9nZ2xlRHJhZ01vZGUpPVwidG9nZ2xlRHJhZ01vZGUuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgKHNhbU1vZGVsQ2hhbmdlKT1cInNhbU1vZGVsQ2hhbmdlLmVtaXQoJGV2ZW50KVwiXG4gICAgICAgIChydW5Ub29sKT1cInJ1blRvb2wuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgKHRvb2xNb2RlbENoYW5nZSk9XCJ0b29sTW9kZWxDaGFuZ2UuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgKG9wZW5Ub29sUGFyYW1zKT1cIm9wZW5Ub29sUGFyYW1zLmVtaXQoJGV2ZW50KVwiXG4gICAgICA+XG4gICAgICA8L3Rvb2xiYXItc2VnbWVudGF0aW9uLXRvb2xzPlxuICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInRvb2xzLmhlbHBcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwidG9vbGJhci1zZXBhcmF0b3JcIj48L3NwYW4+XG5cbiAgICAgIDwhLS0gSGVscCAtLT5cbiAgICAgIDxwLWJ1dHRvblxuICAgICAgICBpY29uPVwicGkgcGktcXVlc3Rpb24tY2lyY2xlXCJcbiAgICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgICAgW3RleHRdPVwidHJ1ZVwiXG4gICAgICAgIGFyaWFMYWJlbD1cIkhlbHBcIlxuICAgICAgICBwVG9vbHRpcD1cIkhlbHBcIlxuICAgICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgICAgICAob25DbGljayk9XCJzaG93SGVscCgpXCJcbiAgICAgID5cbiAgICAgIDwvcC1idXR0b24+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvZGl2PlxuPC9wLXRvb2xiYXI+XG48dG9vbGJhci1oZWxwLWRpYWxvZ1xuICBbKHZpc2libGUpXT1cImRpc3BsYXlIZWxwRGlhbG9nXCJcbiAgW2NvbnRyaWJ1dGVkVG9vbHNdPVwiY29udHJpYnV0ZWRUb29sc1wiXG4gIFtkaWFsb2dUb29sc109XCJkaWFsb2dUb29sc1wiXG4+XG48L3Rvb2xiYXItaGVscC1kaWFsb2c+XG4iXX0=
@@ -1,3 +1,8 @@
1
+ import { openHttpRegionSource } from '../region-source/http-region-source';
2
+ import { REGION_SOURCE_MIN_CHARS } from '../region-source/region-source';
3
+ import { openGeoJsonRegionSource } from '../region-source/worker-region-source';
4
+ /** Per target, the latest {@link applyImageRois}: a stack source that opens after a later load is dropped. */
5
+ const loads = new WeakMap();
1
6
  /**
2
7
  * Apply an image's saved ROIs once its render has landed, choosing the region
3
8
  * layout from the image's shape:
@@ -18,21 +23,79 @@
18
23
  * Loading saved ROIs is not a user edit, so the undo history starts fresh and the
19
24
  * first undo cannot wipe them (jit-ui#85).
20
25
  *
21
- * `z` is the slice shown now; entering stack mode makes it live and resets undo.
26
+ * Large ROI files (`minSourceChars` and up) and a server-side source (`regionSourceUrl`)
27
+ * become tiled region sources instead of regions; a z-indexed one serves each slice its own
28
+ * plane. On a single-file stack the source is opened first, to tell which: one on the default
29
+ * plane only stays global, as its regions would. A folder stack's sources open lazily, the first
30
+ * time their slice is shown.
31
+ *
32
+ * `z` is the slice shown now; entering stack mode makes it live and resets undo. `http`, the
33
+ * host's `HttpClient`, carries a server-side source's requests, so the host's interceptors (its
34
+ * auth) apply to them as to the image tiles.
22
35
  */
23
- export function applyImageRois(info, target, z) {
36
+ export function applyImageRois(info, target, z, minSourceChars = REGION_SOURCE_MIN_CHARS, http) {
37
+ const attach = target.attachRegionSource?.bind(target);
38
+ const load = (loads.get(target) ?? 0) + 1;
39
+ loads.set(target, load);
40
+ const asSource = (json) => !!attach && !!json && json.length >= minSourceChars;
24
41
  if (info.isStack && info.tiled === false) {
25
42
  const perSlice = info.roiJsonStrs;
26
43
  const sliceCount = info.urls?.length ?? perSlice?.length ?? 0;
27
44
  const slices = new Map();
45
+ const sourced = [];
28
46
  for (let s = 0; s < sliceCount; s++) {
29
47
  const json = perSlice?.[s] ?? null;
30
- slices.set(s, json ? target.importRegions(json) : []);
48
+ if (asSource(json))
49
+ sourced.push(s);
50
+ slices.set(s, json && !asSource(json) ? target.importRegions(json) : []);
31
51
  }
32
52
  target.enterStackMode(slices, z, 'per-slice-file');
53
+ for (const s of sourced)
54
+ attach?.(() => openGeoJsonRegionSource(perSlice?.[s]), { slice: s });
33
55
  return;
34
56
  }
35
57
  const roiJson = info.roiJsonStr;
58
+ if (attach && (info.regionSourceUrl || asSource(roiJson))) {
59
+ const url = info.regionSourceUrl;
60
+ const open = url
61
+ ? () => openHttpRegionSource(url, { http })
62
+ : () => openGeoJsonRegionSource(roiJson);
63
+ // As loading a file of regions replaces the regions, a source starts the image afresh.
64
+ target.setRegions([]);
65
+ target.resetUndoHistory();
66
+ if (!info.isStack) {
67
+ attach(open, { slice: 0 });
68
+ return;
69
+ }
70
+ // A stack: per slice when the source is z-indexed, else global (as its regions would be).
71
+ // The store learns the slice the image opened on (a host may open a stack on any slice), so
72
+ // the source, laid out on the store's slice once it opens, shows that one; a scrub meanwhile
73
+ // records its own, which then wins.
74
+ if (!target.isStackMode?.())
75
+ target.setDisplaySlice?.(z);
76
+ let first = open();
77
+ const reuse = () => {
78
+ const opening = first;
79
+ first = null;
80
+ return opening ?? open();
81
+ };
82
+ const lay = (zIndexed) => {
83
+ if (loads.get(target) !== load) {
84
+ void first?.then((source) => source.dispose(), () => undefined);
85
+ return;
86
+ }
87
+ if (zIndexed) {
88
+ target.enterStackMode(new Map(), target.getDisplaySlice?.() ?? z, 'combined');
89
+ attach(reuse, 'planes');
90
+ }
91
+ else {
92
+ attach(reuse, { slice: 0 });
93
+ }
94
+ };
95
+ // One that cannot be opened is attached as a single plane (its slice reports the failure).
96
+ first.then((source) => lay(source.info.planes.some((p) => p !== 0)), () => lay(false));
97
+ return;
98
+ }
36
99
  if (info.isStack) {
37
100
  const regions = roiJson ? target.importRegions(roiJson) : [];
38
101
  if (!roiJson || regions.some((r) => (r.z ?? 0) !== 0)) {
@@ -57,4 +120,4 @@ function bySlice(regions) {
57
120
  }
58
121
  return slices;
59
122
  }
60
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaW9uLWxvYWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3Zpc3VhbGl6ZXIvcmVnaW9uLWxvYWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBVUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFCRztBQUNILE1BQU0sVUFBVSxjQUFjLENBQUMsSUFBZ0IsRUFBRSxNQUF3QixFQUFFLENBQVM7SUFDbEYsSUFBSSxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssS0FBSyxFQUFFLENBQUM7UUFDekMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQztRQUNsQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLE1BQU0sSUFBSSxRQUFRLEVBQUUsTUFBTSxJQUFJLENBQUMsQ0FBQztRQUM5RCxNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBb0IsQ0FBQztRQUMzQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsVUFBVSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDcEMsTUFBTSxJQUFJLEdBQUcsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDO1lBQ25DLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDeEQsQ0FBQztRQUNELE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1FBQ25ELE9BQU87SUFDVCxDQUFDO0lBQ0QsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUNoQyxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNqQixNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUM3RCxJQUFJLENBQUMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ3RELE1BQU0sQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxVQUFVLENBQUMsQ0FBQztZQUN2RCxPQUFPO1FBQ1QsQ0FBQztJQUNILENBQUM7SUFDRCxJQUFJLE9BQU87UUFBRSxNQUFNLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUM5RCxNQUFNLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztBQUM1QixDQUFDO0FBRUQsNkVBQTZFO0FBQzdFLFNBQVMsT0FBTyxDQUFDLE9BQWlCO0lBQ2hDLE1BQU0sTUFBTSxHQUFHLElBQUksR0FBRyxFQUFvQixDQUFDO0lBQzNDLEtBQUssTUFBTSxDQUFDLElBQUksT0FBTyxFQUFFLENBQUM7UUFDeEIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbkIsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3QixJQUFJLE1BQU07WUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDOztZQUN0QixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDMUIsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJSW1hZ2VJbmZvIH0gZnJvbSAnLi4vY29udHJhY3RzL2ltYWdlLmNvbnRyYWN0JztcbmltcG9ydCB7IElSZWdpb25TdG9yZSB9IGZyb20gJy4uL2NvbnRyYWN0cy92aXN1YWxpemVyLmNvbnRyYWN0JztcbmltcG9ydCB7IFJlZ2lvbiB9IGZyb20gJy4uL21vZGVscy9yZWdpb24nO1xuXG4vKiogVGhlIHJlZ2lvbi1zdG9yZSBtZW1iZXJzIHtAbGluayBhcHBseUltYWdlUm9pc30gd3JpdGVzIHRocm91Z2guICovXG5leHBvcnQgdHlwZSBSZWdpb25Mb2FkVGFyZ2V0ID0gUGljazxcbiAgSVJlZ2lvblN0b3JlLFxuICAnaW1wb3J0UmVnaW9ucycgfCAnZW50ZXJTdGFja01vZGUnIHwgJ3NldFJlZ2lvbnMnIHwgJ3Jlc2V0VW5kb0hpc3RvcnknXG4+O1xuXG4vKipcbiAqIEFwcGx5IGFuIGltYWdlJ3Mgc2F2ZWQgUk9JcyBvbmNlIGl0cyByZW5kZXIgaGFzIGxhbmRlZCwgY2hvb3NpbmcgdGhlIHJlZ2lvblxuICogbGF5b3V0IGZyb20gdGhlIGltYWdlJ3Mgc2hhcGU6XG4gKlxuICogIC0gKipGb2xkZXIgc3RhY2sqKiAoYGlzU3RhY2sgJiYgdGlsZWQgPT09IGZhbHNlYCwgc2VlIGxvYWRTZXJpZXNBc1N0YWNrKTogYSBzdGFja1xuICogICAgb2Ygc2VsZi1jb250YWluZWQgcGVyLXNsaWNlIGZpbGVzLiBFYWNoIHNsaWNlLWZpbGUgbWF5IGNhcnJ5IGl0cyBvd24gc2libGluZ1xuICogICAgYDxzdGVtPi5nZW9qc29uYCAoYHJvaUpzb25TdHJzW3pdYCksIGJ1dCBhIGZyZXNoIGZvbGRlciB3aXRoIG5vbmUgeWV0IGxlYXZlc1xuICogICAgYHJvaUpzb25TdHJzYCB1bmRlZmluZWQg4oCUIHNvIHRoaXMga2V5cyBvZmYgYHRpbGVkID09PSBmYWxzZWAsIE5PVCBgcm9pSnNvblN0cnNgLFxuICogICAgYW5kIGFuIHVuYW5ub3RhdGVkIGZvbGRlciBzdGFjayBzdGlsbCBlbnRlcnMgdGhlIHBlci1zbGljZS1maWxlIGxheW91dCAoc2F2aW5nXG4gKiAgICBiYWNrIG9uZSBnZW9qc29uIHBlciBzbGljZS1maWxlKSByYXRoZXIgdGhhbiB0aGUgY29tYmluZWQgb25lIChqaXQtdWkjOTMpLlxuICogIC0gKipTaW5nbGUtZmlsZSB6LXN0YWNrKio6IG9uZSBzaWJsaW5nIGdlb2pzb24gaG9sZGluZyBldmVyeSBzbGljZSdzIHJlZ2lvbnMsXG4gKiAgICBpbmRleGVkIGJ5IFF1UGF0aCdzIGBnZW9tZXRyeS5wbGFuZS56YC4gUGVyLXNsaWNlIChjb21iaW5lZCkgbW9kZSBpcyBlbnRlcmVkIHdoZW5cbiAqICAgIHRoZSBnZW9qc29uIGFjdHVhbGx5IGNhcnJpZXMgc2xpY2UgaW5kaWNlcywgb3Igd2hlbiB0aGVyZSBpcyBub3RoaW5nIHlldCB0b1xuICogICAgYXV0aG9yIGFnYWluc3QuIEEgbGVnYWN5IGdlb2pzb24gd2hvc2UgcmVnaW9ucyBhcmUgYWxsIG9uIHRoZSBkZWZhdWx0IHBsYW5lXG4gKiAgICBzdGF5cyBnbG9iYWwgKHNob3duIG9uIGV2ZXJ5IHNsaWNlKSwgc28gZXhpc3Rpbmcgc2luZ2xlLXBsYW5lIGFubm90YXRpb25zIGFyZVxuICogICAgbm90IGNvbmZpbmVkIHRvIHNsaWNlIDAuXG4gKiAgLSAqKlNpbmdsZSBwbGFuZSoqIChvciB0aGF0IGxlZ2FjeSBnbG9iYWwgc3RhY2spOiBvbmUgcmVnaW9uIHNldCBmb3IgdGhlIGltYWdlLlxuICogICAgTG9hZGluZyBzYXZlZCBST0lzIGlzIG5vdCBhIHVzZXIgZWRpdCwgc28gdGhlIHVuZG8gaGlzdG9yeSBzdGFydHMgZnJlc2ggYW5kIHRoZVxuICogICAgZmlyc3QgdW5kbyBjYW5ub3Qgd2lwZSB0aGVtIChqaXQtdWkjODUpLlxuICpcbiAqIGB6YCBpcyB0aGUgc2xpY2Ugc2hvd24gbm93OyBlbnRlcmluZyBzdGFjayBtb2RlIG1ha2VzIGl0IGxpdmUgYW5kIHJlc2V0cyB1bmRvLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlJbWFnZVJvaXMoaW5mbzogSUltYWdlSW5mbywgdGFyZ2V0OiBSZWdpb25Mb2FkVGFyZ2V0LCB6OiBudW1iZXIpOiB2b2lkIHtcbiAgaWYgKGluZm8uaXNTdGFjayAmJiBpbmZvLnRpbGVkID09PSBmYWxzZSkge1xuICAgIGNvbnN0IHBlclNsaWNlID0gaW5mby5yb2lKc29uU3RycztcbiAgICBjb25zdCBzbGljZUNvdW50ID0gaW5mby51cmxzPy5sZW5ndGggPz8gcGVyU2xpY2U/Lmxlbmd0aCA/PyAwO1xuICAgIGNvbnN0IHNsaWNlcyA9IG5ldyBNYXA8bnVtYmVyLCBSZWdpb25bXT4oKTtcbiAgICBmb3IgKGxldCBzID0gMDsgcyA8IHNsaWNlQ291bnQ7IHMrKykge1xuICAgICAgY29uc3QganNvbiA9IHBlclNsaWNlPy5bc10gPz8gbnVsbDtcbiAgICAgIHNsaWNlcy5zZXQocywganNvbiA/IHRhcmdldC5pbXBvcnRSZWdpb25zKGpzb24pIDogW10pO1xuICAgIH1cbiAgICB0YXJnZXQuZW50ZXJTdGFja01vZGUoc2xpY2VzLCB6LCAncGVyLXNsaWNlLWZpbGUnKTtcbiAgICByZXR1cm47XG4gIH1cbiAgY29uc3Qgcm9pSnNvbiA9IGluZm8ucm9pSnNvblN0cjtcbiAgaWYgKGluZm8uaXNTdGFjaykge1xuICAgIGNvbnN0IHJlZ2lvbnMgPSByb2lKc29uID8gdGFyZ2V0LmltcG9ydFJlZ2lvbnMocm9pSnNvbikgOiBbXTtcbiAgICBpZiAoIXJvaUpzb24gfHwgcmVnaW9ucy5zb21lKChyKSA9PiAoci56ID8/IDApICE9PSAwKSkge1xuICAgICAgdGFyZ2V0LmVudGVyU3RhY2tNb2RlKGJ5U2xpY2UocmVnaW9ucyksIHosICdjb21iaW5lZCcpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuICBpZiAocm9pSnNvbikgdGFyZ2V0LnNldFJlZ2lvbnModGFyZ2V0LmltcG9ydFJlZ2lvbnMocm9pSnNvbikpO1xuICB0YXJnZXQucmVzZXRVbmRvSGlzdG9yeSgpO1xufVxuXG4vKiogQnVja2V0IHJlZ2lvbnMgYnkgdGhlaXIgemVyby1iYXNlZCB7QGxpbmsgUmVnaW9uLnp9ICh1bnNldCA9IHNsaWNlIDApLiAqL1xuZnVuY3Rpb24gYnlTbGljZShyZWdpb25zOiBSZWdpb25bXSk6IE1hcDxudW1iZXIsIFJlZ2lvbltdPiB7XG4gIGNvbnN0IHNsaWNlcyA9IG5ldyBNYXA8bnVtYmVyLCBSZWdpb25bXT4oKTtcbiAgZm9yIChjb25zdCByIG9mIHJlZ2lvbnMpIHtcbiAgICBjb25zdCB6ID0gci56ID8/IDA7XG4gICAgY29uc3QgYnVja2V0ID0gc2xpY2VzLmdldCh6KTtcbiAgICBpZiAoYnVja2V0KSBidWNrZXQucHVzaChyKTtcbiAgICBlbHNlIHNsaWNlcy5zZXQoeiwgW3JdKTtcbiAgfVxuICByZXR1cm4gc2xpY2VzO1xufVxuIl19
123
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaW9uLWxvYWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3Zpc3VhbGl6ZXIvcmVnaW9uLWxvYWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBSUEsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDM0UsT0FBTyxFQUFFLHVCQUF1QixFQUFnQixNQUFNLGdDQUFnQyxDQUFDO0FBQ3ZGLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBaUJoRiw4R0FBOEc7QUFDOUcsTUFBTSxLQUFLLEdBQUcsSUFBSSxPQUFPLEVBQTRCLENBQUM7QUFFdEQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBNkJHO0FBQ0gsTUFBTSxVQUFVLGNBQWMsQ0FDNUIsSUFBZ0IsRUFDaEIsTUFBd0IsRUFDeEIsQ0FBUyxFQUNULGNBQWMsR0FBRyx1QkFBdUIsRUFDeEMsSUFBaUI7SUFFakIsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLGtCQUFrQixFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN2RCxNQUFNLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzFDLEtBQUssQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3hCLE1BQU0sUUFBUSxHQUFHLENBQUMsSUFBK0IsRUFBa0IsRUFBRSxDQUNuRSxDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLE1BQU0sSUFBSSxjQUFjLENBQUM7SUFFdEQsSUFBSSxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssS0FBSyxFQUFFLENBQUM7UUFDekMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQztRQUNsQyxNQUFNLFVB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O0lBQ0QsSUFBSSxPQUFPO1FBQUUsTUFBTSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDOUQsTUFBTSxDQUFDLGdCQUFnQixFQUFFLENBQUM7QUFDNUIsQ0FBQztBQUVELDZFQUE2RTtBQUM3RSxTQUFTLE9BQU8sQ0FBQyxPQUFpQjtJQUNoQyxNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBb0IsQ0FBQztJQUMzQyxLQUFLLE1BQU0sQ0FBQyxJQUFJLE9BQU8sRUFBRSxDQUFDO1FBQ3hCLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ25CLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDN0IsSUFBSSxNQUFNO1lBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQzs7WUFDdEIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzFCLENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgSUltYWdlSW5mbyB9IGZyb20gJy4uL2NvbnRyYWN0cy9pbWFnZS5jb250cmFjdCc7XG5pbXBvcnQgeyBJUmVnaW9uU3RvcmUgfSBmcm9tICcuLi9jb250cmFjdHMvdmlzdWFsaXplci5jb250cmFjdCc7XG5pbXBvcnQgeyBSZWdpb24gfSBmcm9tICcuLi9tb2RlbHMvcmVnaW9uJztcbmltcG9ydCB7IG9wZW5IdHRwUmVnaW9uU291cmNlIH0gZnJvbSAnLi4vcmVnaW9uLXNvdXJjZS9odHRwLXJlZ2lvbi1zb3VyY2UnO1xuaW1wb3J0IHsgUkVHSU9OX1NPVVJDRV9NSU5fQ0hBUlMsIFJlZ2lvblNvdXJjZSB9IGZyb20gJy4uL3JlZ2lvbi1zb3VyY2UvcmVnaW9uLXNvdXJjZSc7XG5pbXBvcnQgeyBvcGVuR2VvSnNvblJlZ2lvblNvdXJjZSB9IGZyb20gJy4uL3JlZ2lvbi1zb3VyY2Uvd29ya2VyLXJlZ2lvbi1zb3VyY2UnO1xuaW1wb3J0IHR5cGUgeyBSZWdpb25Tb3VyY2VPcGVuZXIsIFJlZ2lvblNvdXJjZVNsaWNlcyB9IGZyb20gJy4uL3N0b3JlL3JlZ2lvbi1zb3VyY2Utc2NvcGUnO1xuXG4vKiogVGhlIHJlZ2lvbi1zdG9yZSBtZW1iZXJzIHtAbGluayBhcHBseUltYWdlUm9pc30gd3JpdGVzIHRocm91Z2guIEEgdGFyZ2V0IHdpdGhvdXRcbiAqICBgYXR0YWNoUmVnaW9uU291cmNlYCBsb2FkcyBldmVyeSBST0kgZmlsZSBhcyByZWdpb25zLiAqL1xuZXhwb3J0IHR5cGUgUmVnaW9uTG9hZFRhcmdldCA9IFBpY2s8XG4gIElSZWdpb25TdG9yZSxcbiAgJ2ltcG9ydFJlZ2lvbnMnIHwgJ2VudGVyU3RhY2tNb2RlJyB8ICdzZXRSZWdpb25zJyB8ICdyZXNldFVuZG9IaXN0b3J5J1xuPiAmIHtcbiAgYXR0YWNoUmVnaW9uU291cmNlPyhzb3VyY2U6IFJlZ2lvblNvdXJjZSB8IFJlZ2lvblNvdXJjZU9wZW5lciwgc2xpY2VzPzogUmVnaW9uU291cmNlU2xpY2VzKTogdm9pZDtcbiAgLyoqIFRoZSBzbGljZSBzaG93biBub3cgKHdoYXQgYSBzdGFjaydzIHNvdXJjZSwgbGFpZCBvdXQgb25jZSBpdCBvcGVucywgbWFrZXMgbGl2ZSkuICovXG4gIGdldERpc3BsYXlTbGljZT8oKTogbnVtYmVyO1xuICAvKiogUmVjb3JkIHRoZSBzbGljZSBzaG93biAob3V0c2lkZSBzdGFjayBtb2RlIGl0IG9ubHkgcmVjb3JkcyBpdCk6IHNlZSB7QGxpbmsgYXBwbHlJbWFnZVJvaXN9LiAqL1xuICBzZXREaXNwbGF5U2xpY2U/KHo6IG51bWJlcik6IHZvaWQ7XG4gIGlzU3RhY2tNb2RlPygpOiBib29sZWFuO1xufTtcblxuLyoqIFBlciB0YXJnZXQsIHRoZSBsYXRlc3Qge0BsaW5rIGFwcGx5SW1hZ2VSb2lzfTogYSBzdGFjayBzb3VyY2UgdGhhdCBvcGVucyBhZnRlciBhIGxhdGVyIGxvYWQgaXMgZHJvcHBlZC4gKi9cbmNvbnN0IGxvYWRzID0gbmV3IFdlYWtNYXA8UmVnaW9uTG9hZFRhcmdldCwgbnVtYmVyPigpO1xuXG4vKipcbiAqIEFwcGx5IGFuIGltYWdlJ3Mgc2F2ZWQgUk9JcyBvbmNlIGl0cyByZW5kZXIgaGFzIGxhbmRlZCwgY2hvb3NpbmcgdGhlIHJlZ2lvblxuICogbGF5b3V0IGZyb20gdGhlIGltYWdlJ3Mgc2hhcGU6XG4gKlxuICogIC0gKipGb2xkZXIgc3RhY2sqKiAoYGlzU3RhY2sgJiYgdGlsZWQgPT09IGZhbHNlYCwgc2VlIGxvYWRTZXJpZXNBc1N0YWNrKTogYSBzdGFja1xuICogICAgb2Ygc2VsZi1jb250YWluZWQgcGVyLXNsaWNlIGZpbGVzLiBFYWNoIHNsaWNlLWZpbGUgbWF5IGNhcnJ5IGl0cyBvd24gc2libGluZ1xuICogICAgYDxzdGVtPi5nZW9qc29uYCAoYHJvaUpzb25TdHJzW3pdYCksIGJ1dCBhIGZyZXNoIGZvbGRlciB3aXRoIG5vbmUgeWV0IGxlYXZlc1xuICogICAgYHJvaUpzb25TdHJzYCB1bmRlZmluZWQg4oCUIHNvIHRoaXMga2V5cyBvZmYgYHRpbGVkID09PSBmYWxzZWAsIE5PVCBgcm9pSnNvblN0cnNgLFxuICogICAgYW5kIGFuIHVuYW5ub3RhdGVkIGZvbGRlciBzdGFjayBzdGlsbCBlbnRlcnMgdGhlIHBlci1zbGljZS1maWxlIGxheW91dCAoc2F2aW5nXG4gKiAgICBiYWNrIG9uZSBnZW9qc29uIHBlciBzbGljZS1maWxlKSByYXRoZXIgdGhhbiB0aGUgY29tYmluZWQgb25lIChqaXQtdWkjOTMpLlxuICogIC0gKipTaW5nbGUtZmlsZSB6LXN0YWNrKio6IG9uZSBzaWJsaW5nIGdlb2pzb24gaG9sZGluZyBldmVyeSBzbGljZSdzIHJlZ2lvbnMsXG4gKiAgICBpbmRleGVkIGJ5IFF1UGF0aCdzIGBnZW9tZXRyeS5wbGFuZS56YC4gUGVyLXNsaWNlIChjb21iaW5lZCkgbW9kZSBpcyBlbnRlcmVkIHdoZW5cbiAqICAgIHRoZSBnZW9qc29uIGFjdHVhbGx5IGNhcnJpZXMgc2xpY2UgaW5kaWNlcywgb3Igd2hlbiB0aGVyZSBpcyBub3RoaW5nIHlldCB0b1xuICogICAgYXV0aG9yIGFnYWluc3QuIEEgbGVnYWN5IGdlb2pzb24gd2hvc2UgcmVnaW9ucyBhcmUgYWxsIG9uIHRoZSBkZWZhdWx0IHBsYW5lXG4gKiAgICBzdGF5cyBnbG9iYWwgKHNob3duIG9uIGV2ZXJ5IHNsaWNlKSwgc28gZXhpc3Rpbmcgc2luZ2xlLXBsYW5lIGFubm90YXRpb25zIGFyZVxuICogICAgbm90IGNvbmZpbmVkIHRvIHNsaWNlIDAuXG4gKiAgLSAqKlNpbmdsZSBwbGFuZSoqIChvciB0aGF0IGxlZ2FjeSBnbG9iYWwgc3RhY2spOiBvbmUgcmVnaW9uIHNldCBmb3IgdGhlIGltYWdlLlxuICogICAgTG9hZGluZyBzYXZlZCBST0lzIGlzIG5vdCBhIHVzZXIgZWRpdCwgc28gdGhlIHVuZG8gaGlzdG9yeSBzdGFydHMgZnJlc2ggYW5kIHRoZVxuICogICAgZmlyc3QgdW5kbyBjYW5ub3Qgd2lwZSB0aGVtIChqaXQtdWkjODUpLlxuICpcbiAqIExhcmdlIFJPSSBmaWxlcyAoYG1pblNvdXJjZUNoYXJzYCBhbmQgdXApIGFuZCBhIHNlcnZlci1zaWRlIHNvdXJjZSAoYHJlZ2lvblNvdXJjZVVybGApXG4gKiBiZWNvbWUgdGlsZWQgcmVnaW9uIHNvdXJjZXMgaW5zdGVhZCBvZiByZWdpb25zOyBhIHotaW5kZXhlZCBvbmUgc2VydmVzIGVhY2ggc2xpY2UgaXRzIG93blxuICogcGxhbmUuIE9uIGEgc2luZ2xlLWZpbGUgc3RhY2sgdGhlIHNvdXJjZSBpcyBvcGVuZWQgZmlyc3QsIHRvIHRlbGwgd2hpY2g6IG9uZSBvbiB0aGUgZGVmYXVsdFxuICogcGxhbmUgb25seSBzdGF5cyBnbG9iYWwsIGFzIGl0cyByZWdpb25zIHdvdWxkLiBBIGZvbGRlciBzdGFjaydzIHNvdXJjZXMgb3BlbiBsYXppbHksIHRoZSBmaXJzdFxuICogdGltZSB0aGVpciBzbGljZSBpcyBzaG93bi5cbiAqXG4gKiBgemAgaXMgdGhlIHNsaWNlIHNob3duIG5vdzsgZW50ZXJpbmcgc3RhY2sgbW9kZSBtYWtlcyBpdCBsaXZlIGFuZCByZXNldHMgdW5kby4gYGh0dHBgLCB0aGVcbiAqIGhvc3QncyBgSHR0cENsaWVudGAsIGNhcnJpZXMgYSBzZXJ2ZXItc2lkZSBzb3VyY2UncyByZXF1ZXN0cywgc28gdGhlIGhvc3QncyBpbnRlcmNlcHRvcnMgKGl0c1xuICogYXV0aCkgYXBwbHkgdG8gdGhlbSBhcyB0byB0aGUgaW1hZ2UgdGlsZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcHBseUltYWdlUm9pcyhcbiAgaW5mbzogSUltYWdlSW5mbyxcbiAgdGFyZ2V0OiBSZWdpb25Mb2FkVGFyZ2V0LFxuICB6OiBudW1iZXIsXG4gIG1pblNvdXJjZUNoYXJzID0gUkVHSU9OX1NPVVJDRV9NSU5fQ0hBUlMsXG4gIGh0dHA/OiBIdHRwQ2xpZW50LFxuKTogdm9pZCB7XG4gIGNvbnN0IGF0dGFjaCA9IHRhcmdldC5hdHRhY2hSZWdpb25Tb3VyY2U/LmJpbmQodGFyZ2V0KTtcbiAgY29uc3QgbG9hZCA9IChsb2Fkcy5nZXQodGFyZ2V0KSA/PyAwKSArIDE7XG4gIGxvYWRzLnNldCh0YXJnZXQsIGxvYWQpO1xuICBjb25zdCBhc1NvdXJjZSA9IChqc29uOiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkKToganNvbiBpcyBzdHJpbmcgPT5cbiAgICAhIWF0dGFjaCAmJiAhIWpzb24gJiYganNvbi5sZW5ndGggPj0gbWluU291cmNlQ2hhcnM7XG5cbiAgaWYgKGluZm8uaXNTdGFjayAmJiBpbmZvLnRpbGVkID09PSBmYWxzZSkge1xuICAgIGNvbnN0IHBlclNsaWNlID0gaW5mby5yb2lKc29uU3RycztcbiAgICBjb25zdCBzbGljZUNvdW50ID0gaW5mby51cmxzPy5sZW5ndGggPz8gcGVyU2xpY2U/Lmxlbmd0aCA/PyAwO1xuICAgIGNvbnN0IHNsaWNlcyA9IG5ldyBNYXA8bnVtYmVyLCBSZWdpb25bXT4oKTtcbiAgICBjb25zdCBzb3VyY2VkOiBudW1iZXJbXSA9IFtdO1xuICAgIGZvciAobGV0IHMgPSAwOyBzIDwgc2xpY2VDb3VudDsgcysrKSB7XG4gICAgICBjb25zdCBqc29uID0gcGVyU2xpY2U/LltzXSA/PyBudWxsO1xuICAgICAgaWYgKGFzU291cmNlKGpzb24pKSBzb3VyY2VkLnB1c2gocyk7XG4gICAgICBzbGljZXMuc2V0KHMsIGpzb24gJiYgIWFzU291cmNlKGpzb24pID8gdGFyZ2V0LmltcG9ydFJlZ2lvbnMoanNvbikgOiBbXSk7XG4gICAgfVxuICAgIHRhcmdldC5lbnRlclN0YWNrTW9kZShzbGljZXMsIHosICdwZXItc2xpY2UtZmlsZScpO1xuICAgIGZvciAoY29uc3QgcyBvZiBzb3VyY2VkKSBhdHRhY2g/LigoKSA9PiBvcGVuR2VvSnNvblJlZ2lvblNvdXJjZShwZXJTbGljZT8uW3NdIGFzIHN0cmluZyksIHsgc2xpY2U6IHMgfSk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3Qgcm9pSnNvbiA9IGluZm8ucm9pSnNvblN0cjtcbiAgaWYgKGF0dGFjaCAmJiAoaW5mby5yZWdpb25Tb3VyY2VVcmwgfHwgYXNTb3VyY2Uocm9pSnNvbikpKSB7XG4gICAgY29uc3QgdXJsID0gaW5mby5yZWdpb25Tb3VyY2VVcmw7XG4gICAgY29uc3Qgb3BlbjogUmVnaW9uU291cmNlT3BlbmVyID0gdXJsXG4gICAgICA/ICgpID0+IG9wZW5IdHRwUmVnaW9uU291cmNlKHVybCwgeyBodHRwIH0pXG4gICAgICA6ICgpID0+IG9wZW5HZW9Kc29uUmVnaW9uU291cmNlKHJvaUpzb24gYXMgc3RyaW5nKTtcbiAgICAvLyBBcyBsb2FkaW5nIGEgZmlsZSBvZiByZWdpb25zIHJlcGxhY2VzIHRoZSByZWdpb25zLCBhIHNvdXJjZSBzdGFydHMgdGhlIGltYWdlIGFmcmVzaC5cbiAgICB0YXJnZXQuc2V0UmVnaW9ucyhbXSk7XG4gICAgdGFyZ2V0LnJlc2V0VW5kb0hpc3RvcnkoKTtcbiAgICBpZiAoIWluZm8uaXNTdGFjaykge1xuICAgICAgYXR0YWNoKG9wZW4sIHsgc2xpY2U6IDAgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIEEgc3RhY2s6IHBlciBzbGljZSB3aGVuIHRoZSBzb3VyY2UgaXMgei1pbmRleGVkLCBlbHNlIGdsb2JhbCAoYXMgaXRzIHJlZ2lvbnMgd291bGQgYmUpLlxuICAgIC8vIFRoZSBzdG9yZSBsZWFybnMgdGhlIHNsaWNlIHRoZSBpbWFnZSBvcGVuZWQgb24gKGEgaG9zdCBtYXkgb3BlbiBhIHN0YWNrIG9uIGFueSBzbGljZSksIHNvXG4gICAgLy8gdGhlIHNvdXJjZSwgbGFpZCBvdXQgb24gdGhlIHN0b3JlJ3Mgc2xpY2Ugb25jZSBpdCBvcGVucywgc2hvd3MgdGhhdCBvbmU7IGEgc2NydWIgbWVhbndoaWxlXG4gICAgLy8gcmVjb3JkcyBpdHMgb3duLCB3aGljaCB0aGVuIHdpbnMuXG4gICAgaWYgKCF0YXJnZXQuaXNTdGFja01vZGU/LigpKSB0YXJnZXQuc2V0RGlzcGxheVNsaWNlPy4oeik7XG4gICAgbGV0IGZpcnN0OiBQcm9taXNlPFJlZ2lvblNvdXJjZT4gfCBudWxsID0gb3BlbigpO1xuICAgIGNvbnN0IHJldXNlOiBSZWdpb25Tb3VyY2VPcGVuZXIgPSAoKSA9PiB7XG4gICAgICBjb25zdCBvcGVuaW5nID0gZmlyc3Q7XG4gICAgICBmaXJzdCA9IG51bGw7XG4gICAgICByZXR1cm4gb3BlbmluZyA/PyBvcGVuKCk7XG4gICAgfTtcbiAgICBjb25zdCBsYXkgPSAoekluZGV4ZWQ6IGJvb2xlYW4pID0+IHtcbiAgICAgIGlmIChsb2Fkcy5nZXQodGFyZ2V0KSAhPT0gbG9hZCkge1xuICAgICAgICB2b2lkIGZpcnN0Py50aGVuKFxuICAgICAgICAgIChzb3VyY2UpID0+IHNvdXJjZS5kaXNwb3NlKCksXG4gICAgICAgICAgKCkgPT4gdW5kZWZpbmVkLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoekluZGV4ZWQpIHtcbiAgICAgICAgdGFyZ2V0LmVudGVyU3RhY2tNb2RlKG5ldyBNYXAoKSwgdGFyZ2V0LmdldERpc3BsYXlTbGljZT8uKCkgPz8geiwgJ2NvbWJpbmVkJyk7XG4gICAgICAgIGF0dGFjaChyZXVzZSwgJ3BsYW5lcycpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXR0YWNoKHJldXNlLCB7IHNsaWNlOiAwIH0pO1xuICAgICAgfVxuICAgIH07XG4gICAgLy8gT25lIHRoYXQgY2Fubm90IGJlIG9wZW5lZCBpcyBhdHRhY2hlZCBhcyBhIHNpbmdsZSBwbGFuZSAoaXRzIHNsaWNlIHJlcG9ydHMgdGhlIGZhaWx1cmUpLlxuICAgIGZpcnN0LnRoZW4oXG4gICAgICAoc291cmNlKSA9PiBsYXkoc291cmNlLmluZm8ucGxhbmVzLnNvbWUoKHApID0+IHAgIT09IDApKSxcbiAgICAgICgpID0+IGxheShmYWxzZSksXG4gICAgKTtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKGluZm8uaXNTdGFjaykge1xuICAgIGNvbnN0IHJlZ2lvbnMgPSByb2lKc29uID8gdGFyZ2V0LmltcG9ydFJlZ2lvbnMocm9pSnNvbikgOiBbXTtcbiAgICBpZiAoIXJvaUpzb24gfHwgcmVnaW9ucy5zb21lKChyKSA9PiAoci56ID8/IDApICE9PSAwKSkge1xuICAgICAgdGFyZ2V0LmVudGVyU3RhY2tNb2RlKGJ5U2xpY2UocmVnaW9ucyksIHosICdjb21iaW5lZCcpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuICBpZiAocm9pSnNvbikgdGFyZ2V0LnNldFJlZ2lvbnModGFyZ2V0LmltcG9ydFJlZ2lvbnMocm9pSnNvbikpO1xuICB0YXJnZXQucmVzZXRVbmRvSGlzdG9yeSgpO1xufVxuXG4vKiogQnVja2V0IHJlZ2lvbnMgYnkgdGhlaXIgemVyby1iYXNlZCB7QGxpbmsgUmVnaW9uLnp9ICh1bnNldCA9IHNsaWNlIDApLiAqL1xuZnVuY3Rpb24gYnlTbGljZShyZWdpb25zOiBSZWdpb25bXSk6IE1hcDxudW1iZXIsIFJlZ2lvbltdPiB7XG4gIGNvbnN0IHNsaWNlcyA9IG5ldyBNYXA8bnVtYmVyLCBSZWdpb25bXT4oKTtcbiAgZm9yIChjb25zdCByIG9mIHJlZ2lvbnMpIHtcbiAgICBjb25zdCB6ID0gci56ID8/IDA7XG4gICAgY29uc3QgYnVja2V0ID0gc2xpY2VzLmdldCh6KTtcbiAgICBpZiAoYnVja2V0KSBidWNrZXQucHVzaChyKTtcbiAgICBlbHNlIHNsaWNlcy5zZXQoeiwgW3JdKTtcbiAgfVxuICByZXR1cm4gc2xpY2VzO1xufVxuIl19