@jax-data-science/sci-image-visualizer 0.8.3 → 0.10.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 (579) hide show
  1. package/README.md +201 -460
  2. package/esm2022/index.mjs +34 -15
  3. package/esm2022/lib/channel-histogram/channel-histogram.component.mjs +163 -91
  4. package/esm2022/lib/contracts/capabilities.contract.mjs +4 -3
  5. package/esm2022/lib/contracts/cell-segmenter.contract.mjs +1 -1
  6. package/esm2022/lib/contracts/channel-histogram-api.contract.mjs +5 -1
  7. package/esm2022/lib/contracts/color.mjs +60 -0
  8. package/esm2022/lib/contracts/colormap-lut.mjs +213 -57
  9. package/esm2022/lib/contracts/coordinate-transform.contract.mjs +1 -1
  10. package/esm2022/lib/contracts/display-types.mjs +11 -1
  11. package/esm2022/lib/contracts/image.contract.mjs +1 -1
  12. package/esm2022/lib/contracts/instance-segmenter.contract.mjs +1 -1
  13. package/esm2022/lib/contracts/intensity.mjs +48 -5
  14. package/esm2022/lib/contracts/plot-type-contribution.contract.mjs +1 -1
  15. package/esm2022/lib/contracts/plot-type.mjs +134 -17
  16. package/esm2022/lib/contracts/ports/image-state.port.mjs +4 -1
  17. package/esm2022/lib/contracts/ports/preferences.port.mjs +5 -1
  18. package/esm2022/lib/contracts/ports/region-io.port.mjs +2 -1
  19. package/esm2022/lib/contracts/ports/spatial-data.port.mjs +5 -1
  20. package/esm2022/lib/contracts/ports/tile-access.port.mjs +2 -1
  21. package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
  22. package/esm2022/lib/contracts/region-overlay.contract.mjs +1 -1
  23. package/esm2022/lib/contracts/region-store.contract.mjs +1 -1
  24. package/esm2022/lib/contracts/sam.contract.mjs +1 -1
  25. package/esm2022/lib/contracts/section-view.contract.mjs +2 -0
  26. package/esm2022/lib/contracts/semantic-segmenter.contract.mjs +1 -1
  27. package/esm2022/lib/contracts/spatial-dataset.contract.mjs +3 -1
  28. package/esm2022/lib/contracts/toolbar-tool.contract.mjs +6 -4
  29. package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
  30. package/esm2022/lib/contracts/viz-config.mjs +2 -1
  31. package/esm2022/lib/geometry/contour.mjs +63 -0
  32. package/esm2022/lib/geometry/loft.mjs +128 -0
  33. package/esm2022/lib/geometry/polylabel.mjs +156 -0
  34. package/esm2022/lib/geometry/raster.mjs +98 -0
  35. package/esm2022/lib/geometry/reconstruct.mjs +315 -0
  36. package/esm2022/lib/geometry/reslice-image.mjs +57 -0
  37. package/esm2022/lib/geometry/ring.mjs +201 -0
  38. package/esm2022/lib/geometry/section.mjs +215 -0
  39. package/esm2022/lib/hex-color-picker/hex-color-picker.component.mjs +202 -102
  40. package/esm2022/lib/implementations/base-store-visualizer.mjs +201 -48
  41. package/esm2022/lib/implementations/napari-js/napari-axes-gizmo.mjs +65 -0
  42. package/esm2022/lib/implementations/napari-js/napari-display-state.mjs +136 -0
  43. package/esm2022/lib/implementations/napari-js/napari-helpers.mjs +199 -0
  44. package/esm2022/lib/implementations/napari-js/napari-image-2d-scene.mjs +602 -0
  45. package/esm2022/lib/implementations/napari-js/napari-loading-badge.mjs +12 -9
  46. package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +83 -0
  47. package/esm2022/lib/implementations/napari-js/napari-region-mesh-pointer.mjs +100 -0
  48. package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +180 -591
  49. package/esm2022/lib/implementations/napari-js/napari-scene.mjs +2 -0
  50. package/esm2022/lib/implementations/napari-js/napari-spatial-2d-scene.mjs +614 -0
  51. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +769 -0
  52. package/esm2022/lib/implementations/napari-js/napari-spatial-encoding.mjs +199 -0
  53. package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +270 -0
  54. package/esm2022/lib/implementations/napari-js/napari-spatial-scene.mjs +159 -0
  55. package/esm2022/lib/implementations/napari-js/napari-spatial-tiles.mjs +106 -1408
  56. package/esm2022/lib/implementations/napari-js/napari-spatial-tooltip.mjs +2 -2
  57. package/esm2022/lib/implementations/napari-js/napari-surface-scene.mjs +271 -0
  58. package/esm2022/lib/implementations/napari-js/napari-tile-client.mjs +562 -0
  59. package/esm2022/lib/implementations/napari-js/napari-tool-bridge.mjs +347 -0
  60. package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +427 -4207
  61. package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +129 -0
  62. package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +550 -0
  63. package/esm2022/lib/implementations/napari-js/napari-volume-slice-planes.mjs +103 -0
  64. package/esm2022/lib/implementations/napari-js/napari-volume-z-handle.mjs +6 -6
  65. package/esm2022/lib/implementations/napari-js/region-overlay/overlay-projection.mjs +96 -0
  66. package/esm2022/lib/implementations/napari-js/region-overlay/region-edit.mjs +35 -0
  67. package/esm2022/lib/implementations/napari-js/region-overlay/region-svg-renderer.mjs +194 -0
  68. package/esm2022/lib/implementations/napari-js/spatial-tiles/categorical-lookup.mjs +30 -0
  69. package/esm2022/lib/implementations/napari-js/spatial-tiles/cell-layers.mjs +274 -0
  70. package/esm2022/lib/implementations/napari-js/spatial-tiles/density-layer.mjs +144 -0
  71. package/esm2022/lib/implementations/napari-js/spatial-tiles/layer-groups.mjs +165 -0
  72. package/esm2022/lib/implementations/napari-js/spatial-tiles/plan-context.mjs +78 -0
  73. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-hover.mjs +182 -0
  74. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-jobs.mjs +369 -0
  75. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-layers.mjs +306 -0
  76. package/esm2022/lib/implementations/osd/display-pipeline.mjs +102 -40
  77. package/esm2022/lib/implementations/osd/histogram-sampler.mjs +56 -31
  78. package/esm2022/lib/implementations/osd/openseadragon-viewer-options.mjs +128 -0
  79. package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +333 -1685
  80. package/esm2022/lib/implementations/osd/osd-coordinate-transform.mjs +1 -1
  81. package/esm2022/lib/implementations/osd/osd-coords.mjs +5 -6
  82. package/esm2022/lib/implementations/osd/osd-export.mjs +122 -0
  83. package/esm2022/lib/implementations/osd/osd-lib.mjs +15 -1
  84. package/esm2022/lib/implementations/osd/osd-navigator-chrome.mjs +205 -0
  85. package/esm2022/lib/implementations/osd/osd-pixel-readback.mjs +68 -0
  86. package/esm2022/lib/implementations/osd/osd-region-overlay-draw.mjs +164 -0
  87. package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +213 -716
  88. package/esm2022/lib/implementations/osd/osd-scale-bar.mjs +52 -60
  89. package/esm2022/lib/implementations/osd/osd-tile-source.mjs +105 -0
  90. package/esm2022/lib/implementations/osd/osd-viewer-like.mjs +2 -0
  91. package/esm2022/lib/implementations/osd/osd-viewer-mount.mjs +44 -0
  92. package/esm2022/lib/implementations/osd/osd-viewport.mjs +184 -0
  93. package/esm2022/lib/implementations/osd/osd-zoom.mjs +7 -1
  94. package/esm2022/lib/implementations/osd/simple-source.mjs +395 -0
  95. package/esm2022/lib/implementations/osd/slice-cache.mjs +53 -48
  96. package/esm2022/lib/implementations/osd/tile-client.mjs +32 -11
  97. package/esm2022/lib/implementations/osd/tile-recolor.mjs +330 -0
  98. package/esm2022/lib/implementations/plotly/omics-trace-builders.mjs +161 -73
  99. package/esm2022/lib/implementations/plotly/plotly-coordinate-transform.mjs +1 -1
  100. package/esm2022/lib/implementations/plotly/plotly-image-loader.mjs +112 -0
  101. package/esm2022/lib/implementations/plotly/plotly-image-recolor.mjs +178 -0
  102. package/esm2022/lib/implementations/plotly/plotly-intensity-inset.mjs +33 -0
  103. package/esm2022/lib/implementations/plotly/plotly-isosurface-controls.mjs +83 -0
  104. package/esm2022/lib/implementations/plotly/plotly-layouts.mjs +121 -0
  105. package/esm2022/lib/implementations/plotly/plotly-readback.mjs +117 -0
  106. package/esm2022/lib/implementations/plotly/plotly-region-overlay.mjs +19 -10
  107. package/esm2022/lib/implementations/plotly/plotly-shape-projection.mjs +223 -0
  108. package/esm2022/lib/implementations/plotly/plotly-trace-builders.mjs +79 -19
  109. package/esm2022/lib/implementations/plotly/plotly-zoom-controller.mjs +223 -0
  110. package/esm2022/lib/implementations/plotly/plotly.service.mjs +439 -1655
  111. package/esm2022/lib/implementations/region-centroids.mjs +47 -0
  112. package/esm2022/lib/implementations/simple-slice-access.service.mjs +22 -12
  113. package/esm2022/lib/implementations/spatial-data-http/spatial-data-http.service.mjs +172 -92
  114. package/esm2022/lib/implementations/spatial-data-http/spatial-wire.mjs +103 -22
  115. package/esm2022/lib/implementations/tile-server/index.mjs +6 -0
  116. package/esm2022/lib/implementations/tile-server/native-histogram.mjs +30 -0
  117. package/esm2022/lib/implementations/tile-server/poll-descriptor.mjs +65 -0
  118. package/esm2022/lib/implementations/tile-server/tile-protocol.mjs +42 -0
  119. package/esm2022/lib/implementations/tile-server/transport.mjs +135 -0
  120. package/esm2022/lib/intensity/intensity-profile.mjs +107 -0
  121. package/esm2022/lib/intensity/intensity-profile.service.mjs +223 -0
  122. package/esm2022/lib/intensity-inset/intensity-inset.component.mjs +133 -0
  123. package/esm2022/lib/models/bezier.mjs +1 -11
  124. package/esm2022/lib/models/class-preset.mjs +41 -3
  125. package/esm2022/lib/models/geometry.mjs +27 -164
  126. package/esm2022/lib/models/polygon-edit.mjs +254 -0
  127. package/esm2022/lib/models/polygon-factory.mjs +134 -0
  128. package/esm2022/lib/models/region-clone.mjs +68 -0
  129. package/esm2022/lib/models/region-geojson.mjs +411 -0
  130. package/esm2022/lib/models/region.mjs +34 -33
  131. package/esm2022/lib/models/shape.mjs +18 -16
  132. package/esm2022/lib/plot-mode/contribution-host.mjs +297 -0
  133. package/esm2022/lib/plot-mode/plot-mode-controller.mjs +9 -6
  134. package/esm2022/lib/plot-mode/plot-type-menu.mjs +85 -0
  135. package/esm2022/lib/plot-mode/tool-params-model.mjs +87 -0
  136. package/esm2022/lib/plot.utilities.mjs +296 -473
  137. package/esm2022/lib/processing/image-crop.mjs +1 -1
  138. package/esm2022/lib/processing/processing-image.mjs +28 -15
  139. package/esm2022/lib/provide-visualization.mjs +40 -14
  140. package/esm2022/lib/region-editor/class-tree/class-tree.component.mjs +156 -0
  141. package/esm2022/lib/region-editor/class-tree/class-tree.mjs +108 -0
  142. package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +163 -0
  143. package/esm2022/lib/region-editor/file-stem.mjs +13 -0
  144. package/esm2022/lib/region-editor/manage-classes-dialog/manage-classes-dialog.component.mjs +118 -0
  145. package/esm2022/lib/region-editor/mask-export.service.mjs +98 -0
  146. package/esm2022/lib/region-editor/mask-raster.mjs +11 -5
  147. package/esm2022/lib/region-editor/region-color-dialog/region-color-dialog.component.mjs +56 -0
  148. package/esm2022/lib/region-editor/region-editor-help/region-editor-help.component.mjs +28 -0
  149. package/esm2022/lib/region-editor/region-editor.component.mjs +896 -660
  150. package/esm2022/lib/region-editor/region-metrics.mjs +86 -0
  151. package/esm2022/lib/region-editor/region-persistence.service.mjs +160 -0
  152. package/esm2022/lib/region-editor/region-table/region-table.component.mjs +169 -0
  153. package/esm2022/lib/region-editor/save-mask-dialog/save-mask-dialog.component.mjs +91 -0
  154. package/esm2022/lib/region-editor/save-regions-dialog/save-regions-dialog.component.mjs +92 -0
  155. package/esm2022/lib/region-ops.service.mjs +28 -70
  156. package/esm2022/lib/region-overlay/region-geometry.mjs +360 -0
  157. package/esm2022/lib/region-overlay/region-hit-test.mjs +103 -0
  158. package/esm2022/lib/region-overlay/region-source-layer.mjs +378 -0
  159. package/esm2022/lib/region-overlay/region-style.mjs +97 -0
  160. package/esm2022/lib/region-overlay/svg-region-renderer.mjs +228 -0
  161. package/esm2022/lib/region-source/http-region-source.mjs +104 -0
  162. package/esm2022/lib/region-source/region-source-ops.mjs +53 -0
  163. package/esm2022/lib/region-source/region-source-worker.mjs +10 -0
  164. package/esm2022/lib/region-source/region-source.mjs +67 -0
  165. package/esm2022/lib/region-source/region-tiles.mjs +708 -0
  166. package/esm2022/lib/region-source/worker-region-source.mjs +229 -0
  167. package/esm2022/lib/render-orchestrator.mjs +14 -11
  168. package/esm2022/lib/render-session.mjs +207 -0
  169. package/esm2022/lib/routing-visualizer.service.mjs +858 -414
  170. package/esm2022/lib/section-pane/section-pane.component.mjs +299 -0
  171. package/esm2022/lib/spatial/density-raster.mjs +14 -0
  172. package/esm2022/lib/spatial/embedding-compute-coordinator.mjs +239 -0
  173. package/esm2022/lib/spatial/embedding-compute.mjs +43 -10
  174. package/esm2022/lib/spatial/gene-search.mjs +1 -1
  175. package/esm2022/lib/spatial/glyphs.mjs +97 -0
  176. package/esm2022/lib/spatial/lod.mjs +187 -0
  177. package/esm2022/lib/spatial/spatial-controls.facade.mjs +200 -0
  178. package/esm2022/lib/spatial/spatial-density.mjs +25 -16
  179. package/esm2022/lib/spatial/spatial-encoding.mjs +26 -82
  180. package/esm2022/lib/spatial/spatial-expression.mjs +43 -42
  181. package/esm2022/lib/spatial/spatial-framing.mjs +1 -1
  182. package/esm2022/lib/spatial/spatial-heatmap.mjs +6 -3
  183. package/esm2022/lib/spatial/spatial-hover.mjs +5 -33
  184. package/esm2022/lib/spatial/spatial-panel-model.mjs +282 -0
  185. package/esm2022/lib/spatial/spatial-sections.mjs +1 -1
  186. package/esm2022/lib/spatial/spatial-selection.mjs +33 -46
  187. package/esm2022/lib/spatial/spatial-tile-merge.mjs +219 -0
  188. package/esm2022/lib/spatial/spatial-tiles.mjs +12 -648
  189. package/esm2022/lib/spatial/spatial-volume-image.mjs +2 -4
  190. package/esm2022/lib/spatial/stats.mjs +71 -0
  191. package/esm2022/lib/spatial/transcript-grouping.mjs +307 -0
  192. package/esm2022/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.mjs +150 -0
  193. package/esm2022/lib/spatial-controls/spatial-charts/chart-data-model.mjs +309 -0
  194. package/esm2022/lib/spatial-controls/spatial-charts/chart-help.mjs +145 -0
  195. package/esm2022/lib/spatial-controls/spatial-charts/plotly-chart-host.mjs +158 -0
  196. package/esm2022/lib/spatial-controls/spatial-charts/spatial-chart-window/spatial-chart-window.component.mjs +47 -0
  197. package/esm2022/lib/spatial-controls/spatial-charts/spatial-charts.component.mjs +297 -802
  198. package/esm2022/lib/spatial-controls/spatial-charts/spatial-embedding-controls/spatial-embedding-controls.component.mjs +89 -0
  199. package/esm2022/lib/spatial-controls/spatial-charts/spatial-heatmap-controls/spatial-heatmap-controls.component.mjs +52 -0
  200. package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +143 -1238
  201. package/esm2022/lib/spatial-controls/spatial-gene-picker.mjs +153 -0
  202. package/esm2022/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.mjs +241 -0
  203. package/esm2022/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.mjs +193 -0
  204. package/esm2022/lib/spatial-controls/spatial-key/spatial-key.component.mjs +132 -0
  205. package/esm2022/lib/spatial-controls/spatial-key/spatial-key.model.mjs +67 -0
  206. package/esm2022/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.mjs +147 -0
  207. package/esm2022/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.mjs +300 -0
  208. package/esm2022/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.mjs +370 -0
  209. package/esm2022/lib/store/class-color.util.mjs +53 -5
  210. package/esm2022/lib/store/class-signatures.mjs +63 -0
  211. package/esm2022/lib/store/region-history.mjs +146 -0
  212. package/esm2022/lib/store/region-scope-cache.mjs +144 -0
  213. package/esm2022/lib/store/region-selection.mjs +82 -0
  214. package/esm2022/lib/store/region-source-scope.mjs +171 -0
  215. package/esm2022/lib/store/region-store.service.mjs +986 -670
  216. package/esm2022/lib/store/spatial-selection.service.mjs +2 -2
  217. package/esm2022/lib/store/visualizer-store.service.mjs +81 -76
  218. package/esm2022/lib/toast-outlets.mjs +5 -4
  219. package/esm2022/lib/toolbar/brush/brush-tool.service.mjs +92 -434
  220. package/esm2022/lib/toolbar/canvas-tools.mjs +20 -0
  221. package/esm2022/lib/toolbar/crop/slide-crop.mjs +26 -42
  222. package/esm2022/lib/toolbar/plot-type-selector/plot-type-selector.component.mjs +85 -0
  223. package/esm2022/lib/toolbar/region-tools/region-tool-buttons.mjs +74 -0
  224. package/esm2022/lib/toolbar/region-tools/region-tools.component.mjs +120 -0
  225. package/esm2022/lib/toolbar/segmentation/cell-segment-tool.service.mjs +74 -78
  226. package/esm2022/lib/toolbar/segmentation/cellpose-segmenter.service.mjs +50 -8
  227. package/esm2022/lib/toolbar/segmentation/onnx-sam-session.mjs +61 -42
  228. package/esm2022/lib/toolbar/segmentation/pending-calls.mjs +47 -0
  229. package/esm2022/lib/toolbar/segmentation/sam-model-registry.mjs +12 -4
  230. package/esm2022/lib/toolbar/segmentation/sam-onnx-core.mjs +70 -14
  231. package/esm2022/lib/toolbar/segmentation/sam-point-tool.service.mjs +135 -172
  232. package/esm2022/lib/toolbar/segmentation/sam-prompt.mjs +9 -90
  233. package/esm2022/lib/toolbar/segmentation/sam-session.service.mjs +183 -0
  234. package/esm2022/lib/toolbar/segmentation/sam-tool.service.mjs +95 -150
  235. package/esm2022/lib/toolbar/segmentation/segmentation-commit.mjs +12 -0
  236. package/esm2022/lib/toolbar/segmentation/segmentation-runner.mjs +108 -0
  237. package/esm2022/lib/toolbar/segmentation-tools/segmentation-tools.component.mjs +155 -0
  238. package/esm2022/lib/toolbar/stack-controls/stack-controls.component.mjs +121 -0
  239. package/esm2022/lib/toolbar/tool-kit/async-tool-status.mjs +37 -0
  240. package/esm2022/lib/toolbar/tool-kit/canvas-tool-manager.mjs +63 -0
  241. package/esm2022/lib/toolbar/tool-kit/canvas-tool.mjs +2 -0
  242. package/esm2022/lib/toolbar/tool-kit/frame-pixels.mjs +108 -0
  243. package/esm2022/lib/toolbar/tool-kit/mask-stroke-editor.mjs +306 -0
  244. package/esm2022/lib/toolbar/tool-kit/matrix-frame.mjs +61 -0
  245. package/esm2022/lib/toolbar/tool-kit/tool-overlay.mjs +140 -0
  246. package/esm2022/lib/toolbar/tool-kit/undo-gesture.mjs +24 -0
  247. package/esm2022/lib/toolbar/tool-slider/tool-slider.component.mjs +63 -0
  248. package/esm2022/lib/toolbar/toolbar-help-dialog/toolbar-help-dialog.component.mjs +50 -0
  249. package/esm2022/lib/toolbar/toolbar.component.mjs +84 -119
  250. package/esm2022/lib/toolbar/vertex-eraser/vertex-eraser-tool.service.mjs +93 -115
  251. package/esm2022/lib/toolbar/view-controls/view-controls.component.mjs +107 -0
  252. package/esm2022/lib/toolbar/wand/wand-region-grow.mjs +321 -0
  253. package/esm2022/lib/toolbar/wand/wand-tool.service.mjs +121 -416
  254. package/esm2022/lib/toolbar/wand/wand.service.mjs +30 -894
  255. package/esm2022/lib/toolbar/zoom-to-box/zoom-to-box-tool.service.mjs +48 -90
  256. package/esm2022/lib/util/mark-for-check.mjs +17 -0
  257. package/esm2022/lib/util/supersede.mjs +56 -0
  258. package/esm2022/lib/visualization.module.mjs +39 -141
  259. package/esm2022/lib/visualizer/floating-drag.directive.mjs +58 -0
  260. package/esm2022/lib/visualizer/region-actions.mjs +149 -0
  261. package/esm2022/lib/visualizer/region-load.mjs +123 -0
  262. package/esm2022/lib/visualizer/spatial-dataset-binder.mjs +163 -0
  263. package/esm2022/lib/visualizer/tool-modes.mjs +113 -0
  264. package/esm2022/lib/visualizer/viewer-shortcuts.mjs +167 -0
  265. package/esm2022/lib/visualizer/visualizer-context-menu.mjs +119 -0
  266. package/esm2022/lib/visualizer/volume-sections.mjs +175 -0
  267. package/esm2022/lib/visualizer.component.mjs +602 -1902
  268. package/esm2022/lib/workers/spatial-math-ops.mjs +43 -0
  269. package/esm2022/lib/workers/spatial-math-worker.mjs +10 -0
  270. package/esm2022/lib/workers/spatial-math.mjs +190 -0
  271. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BKQhpbHv.mjs +47169 -0
  272. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BKQhpbHv.mjs.map +1 -0
  273. package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs +238 -0
  274. package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs.map +1 -0
  275. package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs +12 -0
  276. package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs.map +1 -0
  277. package/fesm2022/jax-data-science-sci-image-visualizer-spatial-math-worker-BzVFFqGS.mjs +12 -0
  278. package/fesm2022/jax-data-science-sci-image-visualizer-spatial-math-worker-BzVFFqGS.mjs.map +1 -0
  279. package/fesm2022/jax-data-science-sci-image-visualizer.mjs +41 -34467
  280. package/fesm2022/jax-data-science-sci-image-visualizer.mjs.map +1 -1
  281. package/fesm2022/mask.worker.js +36 -917
  282. package/fesm2022/onnx-sam.worker.js +52 -16
  283. package/fesm2022/region-source.worker.js +1067 -0
  284. package/fesm2022/spatial-math.worker.js +471 -0
  285. package/fesm2022/tsne.worker.js +32 -15
  286. package/index.d.ts +19 -10
  287. package/lib/channel-histogram/channel-histogram.component.d.ts +53 -43
  288. package/lib/contracts/capabilities.contract.d.ts +4 -2
  289. package/lib/contracts/cell-segmenter.contract.d.ts +1 -0
  290. package/lib/contracts/channel-histogram-api.contract.d.ts +4 -0
  291. package/lib/contracts/color.d.ts +27 -0
  292. package/lib/contracts/colormap-lut.d.ts +19 -4
  293. package/lib/contracts/coordinate-transform.contract.d.ts +3 -3
  294. package/lib/contracts/display-types.d.ts +21 -0
  295. package/lib/contracts/image.contract.d.ts +4 -0
  296. package/lib/contracts/instance-segmenter.contract.d.ts +5 -0
  297. package/lib/contracts/intensity.d.ts +13 -2
  298. package/lib/contracts/plot-type.d.ts +3 -1
  299. package/lib/contracts/ports/image-state.port.d.ts +6 -2
  300. package/lib/contracts/ports/preferences.port.d.ts +4 -0
  301. package/lib/contracts/ports/region-io.port.d.ts +1 -0
  302. package/lib/contracts/ports/spatial-data.port.d.ts +4 -10
  303. package/lib/contracts/ports/tile-access.port.d.ts +1 -0
  304. package/lib/contracts/region-editor-api.contract.d.ts +85 -1
  305. package/lib/contracts/region-overlay.contract.d.ts +5 -0
  306. package/lib/contracts/region-store.contract.d.ts +22 -0
  307. package/lib/contracts/sam.contract.d.ts +7 -0
  308. package/lib/contracts/section-view.contract.d.ts +44 -0
  309. package/lib/contracts/semantic-segmenter.contract.d.ts +6 -0
  310. package/lib/contracts/spatial-dataset.contract.d.ts +19 -6
  311. package/lib/contracts/toolbar-tool.contract.d.ts +1 -0
  312. package/lib/contracts/visualizer.contract.d.ts +231 -54
  313. package/lib/contracts/viz-config.d.ts +9 -0
  314. package/lib/geometry/contour.d.ts +24 -0
  315. package/lib/geometry/loft.d.ts +22 -0
  316. package/lib/geometry/polylabel.d.ts +23 -0
  317. package/lib/geometry/raster.d.ts +42 -0
  318. package/lib/geometry/reconstruct.d.ts +54 -0
  319. package/lib/geometry/reslice-image.d.ts +33 -0
  320. package/lib/geometry/ring.d.ts +67 -0
  321. package/lib/geometry/section.d.ts +52 -0
  322. package/lib/hex-color-picker/hex-color-picker.component.d.ts +61 -27
  323. package/lib/implementations/base-store-visualizer.d.ts +61 -15
  324. package/lib/implementations/napari-js/napari-axes-gizmo.d.ts +36 -0
  325. package/lib/implementations/napari-js/napari-display-state.d.ts +76 -0
  326. package/lib/implementations/napari-js/napari-helpers.d.ts +129 -0
  327. package/lib/implementations/napari-js/napari-image-2d-scene.d.ts +162 -0
  328. package/lib/implementations/napari-js/napari-loading-badge.d.ts +4 -3
  329. package/lib/implementations/napari-js/napari-loading-state.d.ts +37 -0
  330. package/lib/implementations/napari-js/napari-region-mesh-pointer.d.ts +32 -0
  331. package/lib/implementations/napari-js/napari-region-overlay.d.ts +68 -71
  332. package/lib/implementations/napari-js/napari-scene.d.ts +126 -0
  333. package/lib/implementations/napari-js/napari-spatial-2d-scene.d.ts +163 -0
  334. package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +212 -0
  335. package/lib/implementations/napari-js/napari-spatial-encoding.d.ts +114 -0
  336. package/lib/implementations/napari-js/napari-spatial-hover.d.ts +91 -0
  337. package/lib/implementations/napari-js/napari-spatial-scene.d.ts +118 -0
  338. package/lib/implementations/napari-js/napari-spatial-tiles.d.ts +56 -263
  339. package/lib/implementations/napari-js/napari-spatial-tooltip.d.ts +1 -1
  340. package/lib/implementations/napari-js/napari-surface-scene.d.ts +76 -0
  341. package/lib/implementations/napari-js/napari-tile-client.d.ts +214 -0
  342. package/lib/implementations/napari-js/napari-tool-bridge.d.ts +179 -0
  343. package/lib/implementations/napari-js/napari-visualizer.service.d.ts +169 -883
  344. package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +66 -0
  345. package/lib/implementations/napari-js/napari-volume-scene.d.ts +148 -0
  346. package/lib/implementations/napari-js/napari-volume-slice-planes.d.ts +43 -0
  347. package/lib/implementations/napari-js/napari-volume-z-handle.d.ts +8 -12
  348. package/lib/implementations/napari-js/region-overlay/overlay-projection.d.ts +59 -0
  349. package/lib/implementations/napari-js/region-overlay/region-edit.d.ts +15 -0
  350. package/lib/implementations/napari-js/region-overlay/region-svg-renderer.d.ts +54 -0
  351. package/lib/implementations/napari-js/spatial-tiles/categorical-lookup.d.ts +26 -0
  352. package/lib/implementations/napari-js/spatial-tiles/cell-layers.d.ts +70 -0
  353. package/lib/implementations/napari-js/spatial-tiles/density-layer.d.ts +61 -0
  354. package/lib/implementations/napari-js/spatial-tiles/layer-groups.d.ts +67 -0
  355. package/lib/implementations/napari-js/spatial-tiles/plan-context.d.ts +38 -0
  356. package/lib/implementations/napari-js/spatial-tiles/transcript-hover.d.ts +71 -0
  357. package/lib/implementations/napari-js/spatial-tiles/transcript-jobs.d.ts +105 -0
  358. package/lib/implementations/napari-js/spatial-tiles/transcript-layers.d.ts +56 -0
  359. package/lib/implementations/osd/display-pipeline.d.ts +38 -9
  360. package/lib/implementations/osd/histogram-sampler.d.ts +22 -12
  361. package/lib/implementations/osd/openseadragon-viewer-options.d.ts +35 -0
  362. package/lib/implementations/osd/openseadragon-visualizer.service.d.ts +78 -354
  363. package/lib/implementations/osd/osd-coordinate-transform.d.ts +2 -1
  364. package/lib/implementations/osd/osd-coords.d.ts +6 -4
  365. package/lib/implementations/osd/osd-export.d.ts +36 -0
  366. package/lib/implementations/osd/osd-lib.d.ts +7 -0
  367. package/lib/implementations/osd/osd-navigator-chrome.d.ts +69 -0
  368. package/lib/implementations/osd/osd-pixel-readback.d.ts +22 -0
  369. package/lib/implementations/osd/osd-region-overlay-draw.d.ts +38 -0
  370. package/lib/implementations/osd/osd-region-overlay.d.ts +46 -51
  371. package/lib/implementations/osd/osd-scale-bar.d.ts +8 -6
  372. package/lib/implementations/osd/osd-tile-source.d.ts +49 -0
  373. package/lib/implementations/osd/osd-viewer-like.d.ts +100 -0
  374. package/lib/implementations/osd/osd-viewer-mount.d.ts +14 -0
  375. package/lib/implementations/osd/osd-viewport.d.ts +77 -0
  376. package/lib/implementations/osd/osd-zoom.d.ts +6 -0
  377. package/lib/implementations/osd/simple-source.d.ts +161 -0
  378. package/lib/implementations/osd/slice-cache.d.ts +12 -3
  379. package/lib/implementations/osd/tile-client.d.ts +11 -14
  380. package/lib/implementations/osd/tile-recolor.d.ts +141 -0
  381. package/lib/implementations/plotly/omics-trace-builders.d.ts +32 -20
  382. package/lib/implementations/plotly/plotly-image-loader.d.ts +49 -0
  383. package/lib/implementations/plotly/plotly-image-recolor.d.ts +75 -0
  384. package/lib/implementations/plotly/plotly-intensity-inset.d.ts +8 -0
  385. package/lib/implementations/plotly/plotly-isosurface-controls.d.ts +38 -0
  386. package/lib/implementations/plotly/plotly-layouts.d.ts +188 -0
  387. package/lib/implementations/plotly/plotly-readback.d.ts +41 -0
  388. package/lib/implementations/plotly/plotly-region-overlay.d.ts +2 -2
  389. package/lib/implementations/plotly/plotly-shape-projection.d.ts +92 -0
  390. package/lib/implementations/plotly/plotly-trace-builders.d.ts +23 -12
  391. package/lib/implementations/plotly/plotly-zoom-controller.d.ts +86 -0
  392. package/lib/implementations/plotly/plotly.service.d.ts +136 -401
  393. package/lib/implementations/region-centroids.d.ts +14 -0
  394. package/lib/implementations/simple-slice-access.service.d.ts +7 -4
  395. package/lib/implementations/spatial-data-http/spatial-data-http.service.d.ts +42 -18
  396. package/lib/implementations/spatial-data-http/spatial-wire.d.ts +34 -9
  397. package/lib/implementations/tile-server/index.d.ts +5 -0
  398. package/lib/implementations/tile-server/native-histogram.d.ts +25 -0
  399. package/lib/implementations/tile-server/poll-descriptor.d.ts +39 -0
  400. package/lib/implementations/tile-server/tile-protocol.d.ts +83 -0
  401. package/lib/implementations/tile-server/transport.d.ts +62 -0
  402. package/lib/intensity/intensity-profile.d.ts +66 -0
  403. package/lib/intensity/intensity-profile.service.d.ts +108 -0
  404. package/lib/intensity-inset/intensity-inset.component.d.ts +58 -0
  405. package/lib/models/bezier.d.ts +0 -5
  406. package/lib/models/class-preset.d.ts +25 -0
  407. package/lib/models/geometry.d.ts +14 -48
  408. package/lib/models/polygon-edit.d.ts +72 -0
  409. package/lib/models/polygon-factory.d.ts +45 -0
  410. package/lib/models/region-clone.d.ts +20 -0
  411. package/lib/models/region-geojson.d.ts +57 -0
  412. package/lib/models/region.d.ts +59 -4
  413. package/lib/models/shape.d.ts +8 -0
  414. package/lib/plot-mode/contribution-host.d.ts +125 -0
  415. package/lib/plot-mode/plot-type-menu.d.ts +60 -0
  416. package/lib/plot-mode/tool-params-model.d.ts +49 -0
  417. package/lib/plot.utilities.d.ts +19 -30
  418. package/lib/processing/processing-image.d.ts +5 -2
  419. package/lib/provide-visualization.d.ts +19 -2
  420. package/lib/region-editor/class-tree/class-tree.component.d.ts +78 -0
  421. package/lib/region-editor/class-tree/class-tree.d.ts +31 -0
  422. package/lib/region-editor/classes-panel/classes-panel.component.d.ts +86 -0
  423. package/lib/region-editor/file-stem.d.ts +7 -0
  424. package/lib/region-editor/manage-classes-dialog/manage-classes-dialog.component.d.ts +45 -0
  425. package/lib/region-editor/mask-export.service.d.ts +54 -0
  426. package/lib/region-editor/mask-raster.d.ts +2 -8
  427. package/lib/region-editor/region-color-dialog/region-color-dialog.component.d.ts +29 -0
  428. package/lib/region-editor/region-editor-help/region-editor-help.component.d.ts +11 -0
  429. package/lib/region-editor/region-editor.component.d.ts +283 -200
  430. package/lib/region-editor/region-metrics.d.ts +34 -0
  431. package/lib/region-editor/region-persistence.service.d.ts +77 -0
  432. package/lib/region-editor/region-table/region-table.component.d.ts +89 -0
  433. package/lib/region-editor/save-mask-dialog/save-mask-dialog.component.d.ts +36 -0
  434. package/lib/region-editor/save-regions-dialog/save-regions-dialog.component.d.ts +37 -0
  435. package/lib/region-ops.service.d.ts +1 -7
  436. package/lib/region-overlay/region-geometry.d.ts +158 -0
  437. package/lib/region-overlay/region-hit-test.d.ts +38 -0
  438. package/lib/region-overlay/region-source-layer.d.ts +96 -0
  439. package/lib/region-overlay/region-style.d.ts +52 -0
  440. package/lib/region-overlay/svg-region-renderer.d.ts +110 -0
  441. package/lib/region-source/http-region-source.d.ts +45 -0
  442. package/lib/region-source/region-source-ops.d.ts +89 -0
  443. package/lib/region-source/region-source-worker.d.ts +7 -0
  444. package/lib/region-source/region-source.d.ts +82 -0
  445. package/lib/region-source/region-tiles.d.ts +289 -0
  446. package/lib/region-source/worker-region-source.d.ts +65 -0
  447. package/lib/render-orchestrator.d.ts +6 -2
  448. package/lib/render-session.d.ts +75 -0
  449. package/lib/routing-visualizer.service.d.ts +248 -59
  450. package/lib/section-pane/section-pane.component.d.ts +47 -0
  451. package/lib/spatial/density-raster.d.ts +6 -0
  452. package/lib/spatial/embedding-compute-coordinator.d.ts +123 -0
  453. package/lib/spatial/embedding-compute.d.ts +21 -2
  454. package/lib/spatial/glyphs.d.ts +16 -0
  455. package/lib/spatial/lod.d.ts +94 -0
  456. package/lib/spatial/spatial-controls.facade.d.ts +64 -0
  457. package/lib/spatial/spatial-density.d.ts +15 -5
  458. package/lib/spatial/spatial-encoding.d.ts +11 -44
  459. package/lib/spatial/spatial-expression.d.ts +40 -22
  460. package/lib/spatial/spatial-framing.d.ts +1 -0
  461. package/lib/spatial/spatial-heatmap.d.ts +2 -0
  462. package/lib/spatial/spatial-hover.d.ts +4 -16
  463. package/lib/spatial/spatial-panel-model.d.ts +135 -0
  464. package/lib/spatial/spatial-selection.d.ts +21 -26
  465. package/lib/spatial/spatial-tile-merge.d.ts +41 -0
  466. package/lib/spatial/spatial-tiles.d.ts +9 -256
  467. package/lib/spatial/stats.d.ts +38 -0
  468. package/lib/spatial/transcript-grouping.d.ts +119 -0
  469. package/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.d.ts +64 -0
  470. package/lib/spatial-controls/spatial-charts/chart-data-model.d.ts +153 -0
  471. package/lib/spatial-controls/spatial-charts/chart-help.d.ts +69 -0
  472. package/lib/spatial-controls/spatial-charts/plotly-chart-host.d.ts +98 -0
  473. package/lib/spatial-controls/spatial-charts/spatial-chart-window/spatial-chart-window.component.d.ts +26 -0
  474. package/lib/spatial-controls/spatial-charts/spatial-charts.component.d.ts +101 -260
  475. package/lib/spatial-controls/spatial-charts/spatial-embedding-controls/spatial-embedding-controls.component.d.ts +43 -0
  476. package/lib/spatial-controls/spatial-charts/spatial-heatmap-controls/spatial-heatmap-controls.component.d.ts +27 -0
  477. package/lib/spatial-controls/spatial-controls.component.d.ts +68 -448
  478. package/lib/spatial-controls/spatial-gene-picker.d.ts +86 -0
  479. package/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.d.ts +102 -0
  480. package/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.d.ts +72 -0
  481. package/lib/spatial-controls/spatial-key/spatial-key.component.d.ts +66 -0
  482. package/lib/spatial-controls/spatial-key/spatial-key.model.d.ts +33 -0
  483. package/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.d.ts +64 -0
  484. package/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.d.ts +117 -0
  485. package/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.d.ts +142 -0
  486. package/lib/store/class-color.util.d.ts +39 -2
  487. package/lib/store/class-signatures.d.ts +11 -0
  488. package/lib/store/region-history.d.ts +66 -0
  489. package/lib/store/region-scope-cache.d.ts +65 -0
  490. package/lib/store/region-selection.d.ts +36 -0
  491. package/lib/store/region-source-scope.d.ts +68 -0
  492. package/lib/store/region-store.service.d.ts +312 -116
  493. package/lib/store/visualizer-store.service.d.ts +32 -33
  494. package/lib/toast-outlets.d.ts +4 -3
  495. package/lib/toolbar/brush/brush-tool.service.d.ts +31 -98
  496. package/lib/toolbar/canvas-tools.d.ts +20 -0
  497. package/lib/toolbar/crop/slide-crop.d.ts +10 -4
  498. package/lib/toolbar/plot-type-selector/plot-type-selector.component.d.ts +38 -0
  499. package/lib/toolbar/region-tools/region-tool-buttons.d.ts +21 -0
  500. package/lib/toolbar/region-tools/region-tools.component.d.ts +62 -0
  501. package/lib/toolbar/segmentation/cell-segment-tool.service.d.ts +10 -14
  502. package/lib/toolbar/segmentation/cellpose-segmenter.service.d.ts +12 -2
  503. package/lib/toolbar/segmentation/onnx-sam-session.d.ts +22 -3
  504. package/lib/toolbar/segmentation/pending-calls.d.ts +31 -0
  505. package/lib/toolbar/segmentation/sam-model-registry.d.ts +9 -3
  506. package/lib/toolbar/segmentation/sam-onnx-core.d.ts +18 -5
  507. package/lib/toolbar/segmentation/sam-point-tool.service.d.ts +46 -32
  508. package/lib/toolbar/segmentation/sam-prompt.d.ts +7 -31
  509. package/lib/toolbar/segmentation/sam-session.service.d.ts +74 -0
  510. package/lib/toolbar/segmentation/sam-tool.service.d.ts +23 -30
  511. package/lib/toolbar/segmentation/segmentation-commit.d.ts +8 -0
  512. package/lib/toolbar/segmentation/segmentation-runner.d.ts +52 -0
  513. package/lib/toolbar/segmentation-tools/segmentation-tools.component.d.ts +87 -0
  514. package/lib/toolbar/stack-controls/stack-controls.component.d.ts +51 -0
  515. package/lib/toolbar/tool-kit/async-tool-status.d.ts +21 -0
  516. package/lib/toolbar/tool-kit/canvas-tool-manager.d.ts +36 -0
  517. package/lib/toolbar/tool-kit/canvas-tool.d.ts +86 -0
  518. package/lib/toolbar/tool-kit/frame-pixels.d.ts +45 -0
  519. package/lib/toolbar/tool-kit/mask-stroke-editor.d.ts +125 -0
  520. package/lib/toolbar/tool-kit/matrix-frame.d.ts +40 -0
  521. package/lib/toolbar/tool-kit/tool-overlay.d.ts +60 -0
  522. package/lib/toolbar/tool-kit/undo-gesture.d.ts +17 -0
  523. package/lib/toolbar/tool-slider/tool-slider.component.d.ts +33 -0
  524. package/lib/toolbar/toolbar-help-dialog/toolbar-help-dialog.component.d.ts +24 -0
  525. package/lib/toolbar/toolbar.component.d.ts +55 -84
  526. package/lib/toolbar/vertex-eraser/vertex-eraser-tool.service.d.ts +33 -40
  527. package/lib/toolbar/view-controls/view-controls.component.d.ts +54 -0
  528. package/lib/toolbar/wand/wand-region-grow.d.ts +49 -0
  529. package/lib/toolbar/wand/wand-tool.service.d.ts +39 -124
  530. package/lib/toolbar/wand/wand.service.d.ts +22 -116
  531. package/lib/toolbar/zoom-to-box/zoom-to-box-tool.service.d.ts +17 -37
  532. package/lib/util/mark-for-check.d.ts +11 -0
  533. package/lib/util/supersede.d.ts +53 -0
  534. package/lib/visualization.module.d.ts +18 -39
  535. package/lib/visualizer/floating-drag.directive.d.ts +30 -0
  536. package/lib/visualizer/region-actions.d.ts +54 -0
  537. package/lib/visualizer/region-load.d.ts +46 -0
  538. package/lib/visualizer/spatial-dataset-binder.d.ts +74 -0
  539. package/lib/visualizer/tool-modes.d.ts +49 -0
  540. package/lib/visualizer/viewer-shortcuts.d.ts +71 -0
  541. package/lib/visualizer/visualizer-context-menu.d.ts +55 -0
  542. package/lib/visualizer/volume-sections.d.ts +64 -0
  543. package/lib/visualizer.component.d.ts +232 -447
  544. package/lib/workers/spatial-math-ops.d.ts +65 -0
  545. package/lib/workers/spatial-math-worker.d.ts +7 -0
  546. package/lib/workers/spatial-math.d.ts +74 -0
  547. package/package.json +12 -3
  548. package/src/lib/assets/slice.svg +23 -0
  549. package/src/lib/styles/_viz-icons-rules.scss +73 -0
  550. package/src/lib/styles/viz-icons.scss +14 -0
  551. package/esm2022/lib/implementations/napari-js/napari-axes-labels.mjs +0 -97
  552. package/esm2022/lib/implementations/napari-js/napari-navigator.mjs +0 -195
  553. package/esm2022/lib/implementations/napari-js/napari-scale-bar.mjs +0 -92
  554. package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-BwP-A11m.mjs +0 -329
  555. package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-BwP-A11m.mjs.map +0 -1
  556. package/lib/implementations/napari-js/napari-axes-labels.d.ts +0 -49
  557. package/lib/implementations/napari-js/napari-navigator.d.ts +0 -72
  558. package/lib/implementations/napari-js/napari-scale-bar.d.ts +0 -35
  559. package/src/lib/assets/cell-detection.svg +0 -37
  560. package/src/lib/assets/click.svg +0 -1
  561. package/src/lib/assets/colormap-luts.json +0 -1
  562. package/src/lib/assets/edit-selection-white.svg +0 -47
  563. package/src/lib/assets/icons/colormap-earth.png +0 -0
  564. package/src/lib/assets/icons/colormap-placeholder.png +0 -0
  565. package/src/lib/assets/icons/colormap-pubu.png +0 -0
  566. package/src/lib/assets/interactive-segmentation-cursor.svg +0 -1
  567. package/src/lib/assets/picture-segmentation.svg +0 -43
  568. package/src/lib/assets/test/download-379.svg +0 -1
  569. package/src/lib/assets/test/download-98.svg +0 -1
  570. package/src/lib/assets/test/json-1.svg +0 -1
  571. package/src/lib/assets/test/load-53.svg +0 -1
  572. package/src/lib/assets/test/mask-44.svg +0 -1
  573. package/src/lib/assets/test/mask-download-44.svg +0 -15
  574. package/src/lib/assets/test/mask-save-44.svg +0 -11
  575. package/src/lib/assets/test/overlay-1.svg +0 -1
  576. package/src/lib/assets/test/overlay-4.svg +0 -1
  577. package/src/lib/assets/test/region-26.svg +0 -1
  578. package/src/lib/assets/test/save-56.svg +0 -1
  579. package/src/lib/assets/test/upload-43.svg +0 -1
@@ -0,0 +1,58 @@
1
+ import { Directive, EventEmitter, HostListener, Input, NgZone, Output } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * Drag handle of a floating, `position: fixed` panel (the intensity inset header,
5
+ * the toolbar dock handle). On mousedown it asks {@link origin} where the panel is —
6
+ * the host may detach a docked panel right there — then emits the new position on
7
+ * every move until mouseup.
8
+ *
9
+ * The move/up listeners exist only while a drag is in progress and run outside the
10
+ * Angular zone, re-entering it per emitted position: a permanent window mousemove
11
+ * listener made every pointer move anywhere in the host app run change detection.
12
+ */
13
+ export class FloatingDragDirective {
14
+ constructor(zone) {
15
+ this.zone = zone;
16
+ /** The panel's new position, per pointer move. */
17
+ this.vizFloatingDragMove = new EventEmitter();
18
+ this.end = null;
19
+ }
20
+ onMouseDown(e) {
21
+ e.preventDefault();
22
+ this.end?.();
23
+ const from = this.origin();
24
+ const start = { mx: e.clientX, my: e.clientY, x: from.x, y: from.y };
25
+ const move = (ev) => this.zone.run(() => this.vizFloatingDragMove.emit({
26
+ x: start.x + (ev.clientX - start.mx),
27
+ y: start.y + (ev.clientY - start.my),
28
+ }));
29
+ const up = () => this.end?.();
30
+ this.zone.runOutsideAngular(() => {
31
+ window.addEventListener('mousemove', move);
32
+ window.addEventListener('mouseup', up);
33
+ });
34
+ this.end = () => {
35
+ window.removeEventListener('mousemove', move);
36
+ window.removeEventListener('mouseup', up);
37
+ this.end = null;
38
+ };
39
+ }
40
+ ngOnDestroy() {
41
+ this.end?.();
42
+ }
43
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: FloatingDragDirective, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); }
44
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.9", type: FloatingDragDirective, isStandalone: true, selector: "[vizFloatingDrag]", inputs: { origin: ["vizFloatingDrag", "origin"] }, outputs: { vizFloatingDragMove: "vizFloatingDragMove" }, host: { listeners: { "mousedown": "onMouseDown($event)" } }, ngImport: i0 }); }
45
+ }
46
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: FloatingDragDirective, decorators: [{
47
+ type: Directive,
48
+ args: [{ selector: '[vizFloatingDrag]', standalone: true }]
49
+ }], ctorParameters: () => [{ type: i0.NgZone }], propDecorators: { origin: [{
50
+ type: Input,
51
+ args: ['vizFloatingDrag']
52
+ }], vizFloatingDragMove: [{
53
+ type: Output
54
+ }], onMouseDown: [{
55
+ type: HostListener,
56
+ args: ['mousedown', ['$event']]
57
+ }] } });
58
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmxvYXRpbmctZHJhZy5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3Zpc3VhbGl6ZXIvZmxvYXRpbmctZHJhZy5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQWEsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDOztBQVF4Rzs7Ozs7Ozs7O0dBU0c7QUFFSCxNQUFNLE9BQU8scUJBQXFCO0lBUWhDLFlBQTZCLElBQVk7UUFBWixTQUFJLEdBQUosSUFBSSxDQUFRO1FBTHpDLGtEQUFrRDtRQUMvQix3QkFBbUIsR0FBRyxJQUFJLFlBQVksRUFBZSxDQUFDO1FBRWpFLFFBQUcsR0FBd0IsSUFBSSxDQUFDO0lBRUksQ0FBQztJQUc3QyxXQUFXLENBQUMsQ0FBYTtRQUN2QixDQUFDLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDbkIsSUFBSSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUM7UUFDYixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDM0IsTUFBTSxLQUFLLEdBQUcsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ3JFLE1BQU0sSUFBSSxHQUFHLENBQUMsRUFBYyxFQUFFLEVBQUUsQ0FDOUIsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQ2pCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUM7WUFDNUIsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDcEMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUM7U0FDckMsQ0FBQyxDQUNILENBQUM7UUFDSixNQUFNLEVBQUUsR0FBRyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQztRQUM5QixJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsRUFBRTtZQUMvQixNQUFNLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQzNDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDekMsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsRUFBRTtZQUNkLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDOUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUMxQyxJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQztRQUNsQixDQUFDLENBQUM7SUFDSixDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDO0lBQ2YsQ0FBQzs4R0FyQ1UscUJBQXFCO2tHQUFyQixxQkFBcUI7OzJGQUFyQixxQkFBcUI7a0JBRGpDLFNBQVM7bUJBQUMsRUFBRSxRQUFRLEVBQUUsbUJBQW1CLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRTsyRUFHbEMsTUFBTTtzQkFBL0IsS0FBSzt1QkFBQyxpQkFBaUI7Z0JBRUwsbUJBQW1CO3NCQUFyQyxNQUFNO2dCQU9QLFdBQVc7c0JBRFYsWUFBWTt1QkFBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEaXJlY3RpdmUsIEV2ZW50RW1pdHRlciwgSG9zdExpc3RlbmVyLCBJbnB1dCwgTmdab25lLCBPbkRlc3Ryb3ksIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG4vKiogQSBzY3JlZW4gcG9zaXRpb24sIGluIENTUyBwaXhlbHMuICovXG5leHBvcnQgaW50ZXJmYWNlIEZsb2F0aW5nUG9zIHtcbiAgeDogbnVtYmVyO1xuICB5OiBudW1iZXI7XG59XG5cbi8qKlxuICogRHJhZyBoYW5kbGUgb2YgYSBmbG9hdGluZywgYHBvc2l0aW9uOiBmaXhlZGAgcGFuZWwgKHRoZSBpbnRlbnNpdHkgaW5zZXQgaGVhZGVyLFxuICogdGhlIHRvb2xiYXIgZG9jayBoYW5kbGUpLiBPbiBtb3VzZWRvd24gaXQgYXNrcyB7QGxpbmsgb3JpZ2lufSB3aGVyZSB0aGUgcGFuZWwgaXMg4oCUXG4gKiB0aGUgaG9zdCBtYXkgZGV0YWNoIGEgZG9ja2VkIHBhbmVsIHJpZ2h0IHRoZXJlIOKAlCB0aGVuIGVtaXRzIHRoZSBuZXcgcG9zaXRpb24gb25cbiAqIGV2ZXJ5IG1vdmUgdW50aWwgbW91c2V1cC5cbiAqXG4gKiBUaGUgbW92ZS91cCBsaXN0ZW5lcnMgZXhpc3Qgb25seSB3aGlsZSBhIGRyYWcgaXMgaW4gcHJvZ3Jlc3MgYW5kIHJ1biBvdXRzaWRlIHRoZVxuICogQW5ndWxhciB6b25lLCByZS1lbnRlcmluZyBpdCBwZXIgZW1pdHRlZCBwb3NpdGlvbjogYSBwZXJtYW5lbnQgd2luZG93IG1vdXNlbW92ZVxuICogbGlzdGVuZXIgbWFkZSBldmVyeSBwb2ludGVyIG1vdmUgYW55d2hlcmUgaW4gdGhlIGhvc3QgYXBwIHJ1biBjaGFuZ2UgZGV0ZWN0aW9uLlxuICovXG5ARGlyZWN0aXZlKHsgc2VsZWN0b3I6ICdbdml6RmxvYXRpbmdEcmFnXScsIHN0YW5kYWxvbmU6IHRydWUgfSlcbmV4cG9ydCBjbGFzcyBGbG9hdGluZ0RyYWdEaXJlY3RpdmUgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICAvKiogQ2FsbGVkIG9uIG1vdXNlZG93bjogdGhlIHBhbmVsJ3MgcG9zaXRpb24gdGhlIGRyYWcgc3RhcnRzIGZyb20uICovXG4gIEBJbnB1dCgndml6RmxvYXRpbmdEcmFnJykgb3JpZ2luITogKCkgPT4gRmxvYXRpbmdQb3M7XG4gIC8qKiBUaGUgcGFuZWwncyBuZXcgcG9zaXRpb24sIHBlciBwb2ludGVyIG1vdmUuICovXG4gIEBPdXRwdXQoKSByZWFkb25seSB2aXpGbG9hdGluZ0RyYWdNb3ZlID0gbmV3IEV2ZW50RW1pdHRlcjxGbG9hdGluZ1Bvcz4oKTtcblxuICBwcml2YXRlIGVuZDogKCgpID0+IHZvaWQpIHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSB6b25lOiBOZ1pvbmUpIHt9XG5cbiAgQEhvc3RMaXN0ZW5lcignbW91c2Vkb3duJywgWyckZXZlbnQnXSlcbiAgb25Nb3VzZURvd24oZTogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICB0aGlzLmVuZD8uKCk7XG4gICAgY29uc3QgZnJvbSA9IHRoaXMub3JpZ2luKCk7XG4gICAgY29uc3Qgc3RhcnQgPSB7IG14OiBlLmNsaWVudFgsIG15OiBlLmNsaWVudFksIHg6IGZyb20ueCwgeTogZnJvbS55IH07XG4gICAgY29uc3QgbW92ZSA9IChldjogTW91c2VFdmVudCkgPT5cbiAgICAgIHRoaXMuem9uZS5ydW4oKCkgPT5cbiAgICAgICAgdGhpcy52aXpGbG9hdGluZ0RyYWdNb3ZlLmVtaXQoe1xuICAgICAgICAgIHg6IHN0YXJ0LnggKyAoZXYuY2xpZW50WCAtIHN0YXJ0Lm14KSxcbiAgICAgICAgICB5OiBzdGFydC55ICsgKGV2LmNsaWVudFkgLSBzdGFydC5teSksXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICBjb25zdCB1cCA9ICgpID0+IHRoaXMuZW5kPy4oKTtcbiAgICB0aGlzLnpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIG1vdmUpO1xuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB1cCk7XG4gICAgfSk7XG4gICAgdGhpcy5lbmQgPSAoKSA9PiB7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgbW92ZSk7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHVwKTtcbiAgICAgIHRoaXMuZW5kID0gbnVsbDtcbiAgICB9O1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5lbmQ/LigpO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,149 @@
1
+ import { takeUntil } from 'rxjs/operators';
2
+ import { MultiPolygon, Polygon, Rectangle } from '../models/region';
3
+ import { opEligible, regionsAt } from './visualizer-context-menu';
4
+ /**
5
+ * Region set-operations on the current selection (jit-ui#85) — select all, merge,
6
+ * ungroup, inverse, simplify — plus the store mirrors the toolbar and the context
7
+ * menu read synchronously: the selection and the undo/redo availability.
8
+ *
9
+ * Every operation commits through `setRegions`, so it is undo-tracked and the
10
+ * backend on screen re-renders; profile lines and unselected regions are kept.
11
+ */
12
+ export class RegionActions {
13
+ constructor(target, ops,
14
+ /** `[width, height]` of the image, when known — the frame inverse and merge rasterize in. */
15
+ imageSize, notify) {
16
+ this.target = target;
17
+ this.ops = ops;
18
+ this.imageSize = imageSize;
19
+ this.notify = notify;
20
+ /** Current selection (array indices), mirrored from the store. */
21
+ this.selectedIndices = [];
22
+ /** Whether a region action is available to undo / redo; drive the toolbar buttons. */
23
+ this.canUndo = false;
24
+ this.canRedo = false;
25
+ /** Custom-threshold Simplify dialog. */
26
+ this.displaySimplifyDialog = false;
27
+ this.simplifyThreshold = 3;
28
+ }
29
+ /** Mirror the store's selection and undo/redo depth until `until$` emits.
30
+ * `changed` runs after an undo/redo flip (the toolbar binds those). */
31
+ bind(until$, changed) {
32
+ this.target
33
+ .getCanUndo$()
34
+ .pipe(takeUntil(until$))
35
+ .subscribe((v) => {
36
+ this.canUndo = v;
37
+ changed();
38
+ });
39
+ this.target
40
+ .getCanRedo$()
41
+ .pipe(takeUntil(until$))
42
+ .subscribe((v) => {
43
+ this.canRedo = v;
44
+ changed();
45
+ });
46
+ this.target
47
+ .getSelectedShapeIndices$()
48
+ .pipe(takeUntil(until$))
49
+ .subscribe((indices) => {
50
+ this.selectedIndices = indices || [];
51
+ });
52
+ }
53
+ /** The currently-selected regions (live store instances). */
54
+ get selected() {
55
+ return regionsAt(this.target.getRegions(), this.selectedIndices);
56
+ }
57
+ /** Select every region on the image (excludes intensity-profile lines). */
58
+ selectAll() {
59
+ const indices = [];
60
+ this.target.getRegions().forEach((r, i) => {
61
+ if (r.kind !== 'profile')
62
+ indices.push(i);
63
+ });
64
+ this.target.setSelectedShapeIndices(indices);
65
+ }
66
+ /** Merge the selected regions into a single (possibly multi-part) region. */
67
+ merge() {
68
+ const sel = opEligible(this.selected);
69
+ if (sel.length < 2)
70
+ return;
71
+ const { w, h } = this.frame(sel);
72
+ const merged = this.ops.merge(sel, w, h);
73
+ if (merged)
74
+ this.replace(sel, [merged]);
75
+ }
76
+ /** Split each selected multi-part region into one region per part. */
77
+ ungroup() {
78
+ const sel = this.selected.filter((r) => this.ops.canUngroup(r));
79
+ if (sel.length === 0)
80
+ return;
81
+ this.replace(sel, sel.flatMap((r) => this.ops.ungroup(r)));
82
+ }
83
+ /** Replace the selection with its inverse inside the image rectangle. */
84
+ inverse() {
85
+ const sel = opEligible(this.selected);
86
+ if (sel.length === 0)
87
+ return;
88
+ const { w, h } = this.frame(sel);
89
+ const inv = this.ops.inverse(sel, w, h);
90
+ if (!inv) {
91
+ this.notify({
92
+ severity: 'warn',
93
+ summary: 'Inverse',
94
+ detail: 'Nothing to invert — select one or more closed regions first.',
95
+ });
96
+ return;
97
+ }
98
+ this.replace(sel, [inv]);
99
+ }
100
+ /** Douglas–Peucker simplify each selected region by `thresholdPx`, closing the dialog. */
101
+ simplify(thresholdPx) {
102
+ const sel = opEligible(this.selected);
103
+ if (sel.length === 0)
104
+ return;
105
+ this.replace(sel, sel.map((r) => this.ops.simplify(r, thresholdPx)));
106
+ this.displaySimplifyDialog = false;
107
+ }
108
+ openSimplifyDialog() {
109
+ this.displaySimplifyDialog = true;
110
+ }
111
+ /** Commit a set-op: drop `remove`, append `add`, and select the results. */
112
+ replace(remove, add) {
113
+ if (add.length === 0)
114
+ return;
115
+ const removeSet = new Set(remove);
116
+ const kept = this.target.getRegions().filter((r) => !removeSet.has(r));
117
+ this.target.setRegions([...kept, ...add]); // mints ids on `add`, records undo
118
+ const stored = this.target.getRegions();
119
+ this.target.setSelectedShapeIndices(add.map((r) => stored.indexOf(r)).filter((i) => i >= 0));
120
+ }
121
+ /** Image pixel dimensions for the raster ops; falls back to the selection's extent
122
+ * when the image size isn't known (keeps clamping sane). */
123
+ frame(regions) {
124
+ let [w, h] = this.imageSize() ?? [0, 0];
125
+ if (!(w > 0) || !(h > 0)) {
126
+ let maxX = 0, maxY = 0;
127
+ const scan = (xs, ys) => {
128
+ for (const x of xs)
129
+ maxX = Math.max(maxX, x);
130
+ for (const y of ys)
131
+ maxY = Math.max(maxY, y);
132
+ };
133
+ for (const r of regions) {
134
+ const b = r.bounds;
135
+ if (b instanceof Rectangle)
136
+ scan([b.x + b.width], [b.y + b.height]);
137
+ else if (b instanceof Polygon)
138
+ scan(b.xpoints, b.ypoints);
139
+ else if (b instanceof MultiPolygon)
140
+ for (const p of b.polygons)
141
+ scan(p.xpoints, p.ypoints);
142
+ }
143
+ w = Math.max(w, Math.ceil(maxX) + 2);
144
+ h = Math.max(h, Math.ceil(maxY) + 2);
145
+ }
146
+ return { w, h };
147
+ }
148
+ }
149
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaW9uLWFjdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3Zpc3VhbGl6ZXIvcmVnaW9uLWFjdGlvbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBSTNDLE9BQU8sRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBVSxNQUFNLGtCQUFrQixDQUFDO0FBRTVFLE9BQU8sRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFhbEU7Ozs7Ozs7R0FPRztBQUNILE1BQU0sT0FBTyxhQUFhO0lBVXhCLFlBQ21CLE1BQTJCLEVBQzNCLEdBQXFCO0lBQ3RDLDZGQUE2RjtJQUM1RSxTQUFxQyxFQUNyQyxNQUFrQztRQUpsQyxXQUFNLEdBQU4sTUFBTSxDQUFxQjtRQUMzQixRQUFHLEdBQUgsR0FBRyxDQUFrQjtRQUVyQixjQUFTLEdBQVQsU0FBUyxDQUE0QjtRQUNyQyxXQUFNLEdBQU4sTUFBTSxDQUE0QjtRQWRyRCxrRUFBa0U7UUFDbEUsb0JBQWUsR0FBYSxFQUFFLENBQUM7UUFDL0Isc0ZBQXNGO1FBQ3RGLFlBQU8sR0FBRyxLQUFLLENBQUM7UUFDaEIsWUFBTyxHQUFHLEtBQUssQ0FBQztRQUNoQix3Q0FBd0M7UUFDeEMsMEJBQXFCLEdBQUcsS0FBSyxDQUFDO1FBQzlCLHNCQUFpQixHQUFHLENBQUMsQ0FBQztJQVFuQixDQUFDO0lBRUo7NEVBQ3dFO0lBQ3hFLElBQUksQ0FBQyxNQUEyQixFQUFFLE9BQW1CO1FBQ25ELElBQUksQ0FBQyxNQUFNO2FBQ1IsV0FBVyxFQUFFO2FBQ2IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQzthQUN2QixTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUNmLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDO1lBQ2pCLE9BQU8s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QU0sQ0FBQyxJQUFJLE9BQU8sRUFBRSxDQUFDO2dCQUN4QixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDO2dCQUNuQixJQUFJLENBQUMsWUFBWSxTQUFTO29CQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztxQkFDL0QsSUFBSSxDQUFDLFlBQVksT0FBTztvQkFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUM7cUJBQ3JELElBQUksQ0FBQyxZQUFZLFlBQVk7b0JBQUUsS0FBSyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUTt3QkFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDN0YsQ0FBQztZQUNELENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ3JDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDLENBQUM7UUFDRCxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQ2xCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IE1lc3NhZ2UgfSBmcm9tICdwcmltZW5nL2FwaSc7XG5cbmltcG9ydCB7IElSZWdpb25TdG9yZSB9IGZyb20gJy4uL2NvbnRyYWN0cy92aXN1YWxpemVyLmNvbnRyYWN0JztcbmltcG9ydCB7IE11bHRpUG9seWdvbiwgUG9seWdvbiwgUmVjdGFuZ2xlLCBSZWdpb24gfSBmcm9tICcuLi9tb2RlbHMvcmVnaW9uJztcbmltcG9ydCB7IFJlZ2lvbk9wc1NlcnZpY2UgfSBmcm9tICcuLi9yZWdpb24tb3BzLnNlcnZpY2UnO1xuaW1wb3J0IHsgb3BFbGlnaWJsZSwgcmVnaW9uc0F0IH0gZnJvbSAnLi92aXN1YWxpemVyLWNvbnRleHQtbWVudSc7XG5cbi8qKiBUaGUgcmVnaW9uLXN0b3JlIG1lbWJlcnMgdGhlIHNldC1vcGVyYXRpb25zIHJlYWQgYW5kIHdyaXRlIHRocm91Z2guICovXG5leHBvcnQgdHlwZSBSZWdpb25BY3Rpb25zVGFyZ2V0ID0gUGljazxcbiAgSVJlZ2lvblN0b3JlLFxuICB8ICdnZXRSZWdpb25zJ1xuICB8ICdzZXRSZWdpb25zJ1xuICB8ICdzZXRTZWxlY3RlZFNoYXBlSW5kaWNlcydcbiAgfCAnZ2V0U2VsZWN0ZWRTaGFwZUluZGljZXMkJ1xuICB8ICdnZXRDYW5VbmRvJCdcbiAgfCAnZ2V0Q2FuUmVkbyQnXG4+O1xuXG4vKipcbiAqIFJlZ2lvbiBzZXQtb3BlcmF0aW9ucyBvbiB0aGUgY3VycmVudCBzZWxlY3Rpb24gKGppdC11aSM4NSkg4oCUIHNlbGVjdCBhbGwsIG1lcmdlLFxuICogdW5ncm91cCwgaW52ZXJzZSwgc2ltcGxpZnkg4oCUIHBsdXMgdGhlIHN0b3JlIG1pcnJvcnMgdGhlIHRvb2xiYXIgYW5kIHRoZSBjb250ZXh0XG4gKiBtZW51IHJlYWQgc3luY2hyb25vdXNseTogdGhlIHNlbGVjdGlvbiBhbmQgdGhlIHVuZG8vcmVkbyBhdmFpbGFiaWxpdHkuXG4gKlxuICogRXZlcnkgb3BlcmF0aW9uIGNvbW1pdHMgdGhyb3VnaCBgc2V0UmVnaW9uc2AsIHNvIGl0IGlzIHVuZG8tdHJhY2tlZCBhbmQgdGhlXG4gKiBiYWNrZW5kIG9uIHNjcmVlbiByZS1yZW5kZXJzOyBwcm9maWxlIGxpbmVzIGFuZCB1bnNlbGVjdGVkIHJlZ2lvbnMgYXJlIGtlcHQuXG4gKi9cbmV4cG9ydCBjbGFzcyBSZWdpb25BY3Rpb25zIHtcbiAgLyoqIEN1cnJlbnQgc2VsZWN0aW9uIChhcnJheSBpbmRpY2VzKSwgbWlycm9yZWQgZnJvbSB0aGUgc3RvcmUuICovXG4gIHNlbGVjdGVkSW5kaWNlczogbnVtYmVyW10gPSBbXTtcbiAgLyoqIFdoZXRoZXIgYSByZWdpb24gYWN0aW9uIGlzIGF2YWlsYWJsZSB0byB1bmRvIC8gcmVkbzsgZHJpdmUgdGhlIHRvb2xiYXIgYnV0dG9ucy4gKi9cbiAgY2FuVW5kbyA9IGZhbHNlO1xuICBjYW5SZWRvID0gZmFsc2U7XG4gIC8qKiBDdXN0b20tdGhyZXNob2xkIFNpbXBsaWZ5IGRpYWxvZy4gKi9cbiAgZGlzcGxheVNpbXBsaWZ5RGlhbG9nID0gZmFsc2U7XG4gIHNpbXBsaWZ5VGhyZXNob2xkID0gMztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IHRhcmdldDogUmVnaW9uQWN0aW9uc1RhcmdldCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IG9wczogUmVnaW9uT3BzU2VydmljZSxcbiAgICAvKiogYFt3aWR0aCwgaGVpZ2h0XWAgb2YgdGhlIGltYWdlLCB3aGVuIGtub3duIOKAlCB0aGUgZnJhbWUgaW52ZXJzZSBhbmQgbWVyZ2UgcmFzdGVyaXplIGluLiAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgaW1hZ2VTaXplOiAoKSA9PiBudW1iZXJbXSB8IHVuZGVmaW5lZCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IG5vdGlmeTogKG1lc3NhZ2U6IE1lc3NhZ2UpID0+IHZvaWQsXG4gICkge31cblxuICAvKiogTWlycm9yIHRoZSBzdG9yZSdzIHNlbGVjdGlvbiBhbmQgdW5kby9yZWRvIGRlcHRoIHVudGlsIGB1bnRpbCRgIGVtaXRzLlxuICAgKiAgYGNoYW5nZWRgIHJ1bnMgYWZ0ZXIgYW4gdW5kby9yZWRvIGZsaXAgKHRoZSB0b29sYmFyIGJpbmRzIHRob3NlKS4gKi9cbiAgYmluZCh1bnRpbCQ6IE9ic2VydmFibGU8dW5rbm93bj4sIGNoYW5nZWQ6ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLnRhcmdldFxuICAgICAgLmdldENhblVuZG8kKClcbiAgICAgIC5waXBlKHRha2VVbnRpbCh1bnRpbCQpKVxuICAgICAgLnN1YnNjcmliZSgodikgPT4ge1xuICAgICAgICB0aGlzLmNhblVuZG8gPSB2O1xuICAgICAgICBjaGFuZ2VkKCk7XG4gICAgICB9KTtcbiAgICB0aGlzLnRhcmdldFxuICAgICAgLmdldENhblJlZG8kKClcbiAgICAgIC5waXBlKHRha2VVbnRpbCh1bnRpbCQpKVxuICAgICAgLnN1YnNjcmliZSgodikgPT4ge1xuICAgICAgICB0aGlzLmNhblJlZG8gPSB2O1xuICAgICAgICBjaGFuZ2VkKCk7XG4gICAgICB9KTtcbiAgICB0aGlzLnRhcmdldFxuICAgICAgLmdldFNlbGVjdGVkU2hhcGVJbmRpY2VzJCgpXG4gICAgICAucGlwZSh0YWtlVW50aWwodW50aWwkKSlcbiAgICAgIC5zdWJzY3JpYmUoKGluZGljZXMpID0+IHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZEluZGljZXMgPSBpbmRpY2VzIHx8IFtdO1xuICAgICAgfSk7XG4gIH1cblxuICAvKiogVGhlIGN1cnJlbnRseS1zZWxlY3RlZCByZWdpb25zIChsaXZlIHN0b3JlIGluc3RhbmNlcykuICovXG4gIGdldCBzZWxlY3RlZCgpOiBSZWdpb25bXSB7XG4gICAgcmV0dXJuIHJlZ2lvbnNBdCh0aGlzLnRhcmdldC5nZXRSZWdpb25zKCksIHRoaXMuc2VsZWN0ZWRJbmRpY2VzKTtcbiAgfVxuXG4gIC8qKiBTZWxlY3QgZXZlcnkgcmVnaW9uIG9uIHRoZSBpbWFnZSAoZXhjbHVkZXMgaW50ZW5zaXR5LXByb2ZpbGUgbGluZXMpLiAqL1xuICBzZWxlY3RBbGwoKTogdm9pZCB7XG4gICAgY29uc3QgaW5kaWNlczogbnVtYmVyW10gPSBbXTtcbiAgICB0aGlzLnRhcmdldC5nZXRSZWdpb25zKCkuZm9yRWFjaCgociwgaSkgPT4ge1xuICAgICAgaWYgKHIua2luZCAhPT0gJ3Byb2ZpbGUnKSBpbmRpY2VzLnB1c2goaSk7XG4gICAgfSk7XG4gICAgdGhpcy50YXJnZXQuc2V0U2VsZWN0ZWRTaGFwZUluZGljZXMoaW5kaWNlcyk7XG4gIH1cblxuICAvKiogTWVyZ2UgdGhlIHNlbGVjdGVkIHJlZ2lvbnMgaW50byBhIHNpbmdsZSAocG9zc2libHkgbXVsdGktcGFydCkgcmVnaW9uLiAqL1xuICBtZXJnZSgpOiB2b2lkIHtcbiAgICBjb25zdCBzZWwgPSBvcEVsaWdpYmxlKHRoaXMuc2VsZWN0ZWQpO1xuICAgIGlmIChzZWwubGVuZ3RoIDwgMikgcmV0dXJuO1xuICAgIGNvbnN0IHsgdywgaCB9ID0gdGhpcy5mcmFtZShzZWwpO1xuICAgIGNvbnN0IG1lcmdlZCA9IHRoaXMub3BzLm1lcmdlKHNlbCwgdywgaCk7XG4gICAgaWYgKG1lcmdlZCkgdGhpcy5yZXBsYWNlKHNlbCwgW21lcmdlZF0pO1xuICB9XG5cbiAgLyoqIFNwbGl0IGVhY2ggc2VsZWN0ZWQgbXVsdGktcGFydCByZWdpb24gaW50byBvbmUgcmVnaW9uIHBlciBwYXJ0LiAqL1xuICB1bmdyb3VwKCk6IHZvaWQge1xuICAgIGNvbnN0IHNlbCA9IHRoaXMuc2VsZWN0ZWQuZmlsdGVyKChyKSA9PiB0aGlzLm9wcy5jYW5Vbmdyb3VwKHIpKTtcbiAgICBpZiAoc2VsLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgIHRoaXMucmVwbGFjZShcbiAgICAgIHNlbCxcbiAgICAgIHNlbC5mbGF0TWFwKChyKSA9PiB0aGlzLm9wcy51bmdyb3VwKHIpKSxcbiAgICApO1xuICB9XG5cbiAgLyoqIFJlcGxhY2UgdGhlIHNlbGVjdGlvbiB3aXRoIGl0cyBpbnZlcnNlIGluc2lkZSB0aGUgaW1hZ2UgcmVjdGFuZ2xlLiAqL1xuICBpbnZlcnNlKCk6IHZvaWQge1xuICAgIGNvbnN0IHNlbCA9IG9wRWxpZ2libGUodGhpcy5zZWxlY3RlZCk7XG4gICAgaWYgKHNlbC5sZW5ndGggPT09IDApIHJldHVybjtcbiAgICBjb25zdCB7IHcsIGggfSA9IHRoaXMuZnJhbWUoc2VsKTtcbiAgICBjb25zdCBpbnYgPSB0aGlzLm9wcy5pbnZlcnNlKHNlbCwgdywgaCk7XG4gICAgaWYgKCFpbnYpIHtcbiAgICAgIHRoaXMubm90aWZ5KHtcbiAgICAgICAgc2V2ZXJpdHk6ICd3YXJuJyxcbiAgICAgICAgc3VtbWFyeTogJ0ludmVyc2UnLFxuICAgICAgICBkZXRhaWw6ICdOb3RoaW5nIHRvIGludmVydCDigJQgc2VsZWN0IG9uZSBvciBtb3JlIGNsb3NlZCByZWdpb25zIGZpcnN0LicsXG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5yZXBsYWNlKHNlbCwgW2ludl0pO1xuICB9XG5cbiAgLyoqIERvdWdsYXPigJNQZXVja2VyIHNpbXBsaWZ5IGVhY2ggc2VsZWN0ZWQgcmVnaW9uIGJ5IGB0aHJlc2hvbGRQeGAsIGNsb3NpbmcgdGhlIGRpYWxvZy4gKi9cbiAgc2ltcGxpZnkodGhyZXNob2xkUHg6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHNlbCA9IG9wRWxpZ2libGUodGhpcy5zZWxlY3RlZCk7XG4gICAgaWYgKHNlbC5sZW5ndGggPT09IDApIHJldHVybjtcbiAgICB0aGlzLnJlcGxhY2UoXG4gICAgICBzZWwsXG4gICAgICBzZWwubWFwKChyKSA9PiB0aGlzLm9wcy5zaW1wbGlmeShyLCB0aHJlc2hvbGRQeCkpLFxuICAgICk7XG4gICAgdGhpcy5kaXNwbGF5U2ltcGxpZnlEaWFsb2cgPSBmYWxzZTtcbiAgfVxuXG4gIG9wZW5TaW1wbGlmeURpYWxvZygpOiB2b2lkIHtcbiAgICB0aGlzLmRpc3BsYXlTaW1wbGlmeURpYWxvZyA9IHRydWU7XG4gIH1cblxuICAvKiogQ29tbWl0IGEgc2V0LW9wOiBkcm9wIGByZW1vdmVgLCBhcHBlbmQgYGFkZGAsIGFuZCBzZWxlY3QgdGhlIHJlc3VsdHMuICovXG4gIHByaXZhdGUgcmVwbGFjZShyZW1vdmU6IFJlZ2lvbltdLCBhZGQ6IFJlZ2lvbltdKTogdm9pZCB7XG4gICAgaWYgKGFkZC5sZW5ndGggPT09IDApIHJldHVybjtcbiAgICBjb25zdCByZW1vdmVTZXQgPSBuZXcgU2V0KHJlbW92ZSk7XG4gICAgY29uc3Qga2VwdCA9IHRoaXMudGFyZ2V0LmdldFJlZ2lvbnMoKS5maWx0ZXIoKHIpID0+ICFyZW1vdmVTZXQuaGFzKHIpKTtcbiAgICB0aGlzLnRhcmdldC5zZXRSZWdpb25zKFsuLi5rZXB0LCAuLi5hZGRdKTsgLy8gbWludHMgaWRzIG9uIGBhZGRgLCByZWNvcmRzIHVuZG9cbiAgICBjb25zdCBzdG9yZWQgPSB0aGlzLnRhcmdldC5nZXRSZWdpb25zKCk7XG4gICAgdGhpcy50YXJnZXQuc2V0U2VsZWN0ZWRTaGFwZUluZGljZXMoYWRkLm1hcCgocikgPT4gc3RvcmVkLmluZGV4T2YocikpLmZpbHRlcigoaSkgPT4gaSA+PSAwKSk7XG4gIH1cblxuICAvKiogSW1hZ2UgcGl4ZWwgZGltZW5zaW9ucyBmb3IgdGhlIHJhc3RlciBvcHM7IGZhbGxzIGJhY2sgdG8gdGhlIHNlbGVjdGlvbidzIGV4dGVudFxuICAgKiAgd2hlbiB0aGUgaW1hZ2Ugc2l6ZSBpc24ndCBrbm93biAoa2VlcHMgY2xhbXBpbmcgc2FuZSkuICovXG4gIHByaXZhdGUgZnJhbWUocmVnaW9uczogUmVnaW9uW10pOiB7IHc6IG51bWJlcjsgaDogbnVtYmVyIH0ge1xuICAgIGxldCBbdywgaF0gPSB0aGlzLmltYWdlU2l6ZSgpID8/IFswLCAwXTtcbiAgICBpZiAoISh3ID4gMCkgfHwgIShoID4gMCkpIHtcbiAgICAgIGxldCBtYXhYID0gMCxcbiAgICAgICAgbWF4WSA9IDA7XG4gICAgICBjb25zdCBzY2FuID0gKHhzOiBudW1iZXJbXSwgeXM6IG51bWJlcltdKSA9PiB7XG4gICAgICAgIGZvciAoY29uc3QgeCBvZiB4cykgbWF4WCA9IE1hdGgubWF4KG1heFgsIHgpO1xuICAgICAgICBmb3IgKGNvbnN0IHkgb2YgeXMpIG1heFkgPSBNYXRoLm1heChtYXhZLCB5KTtcbiAgICAgIH07XG4gICAgICBmb3IgKGNvbnN0IHIgb2YgcmVnaW9ucykge1xuICAgICAgICBjb25zdCBiID0gci5ib3VuZHM7XG4gICAgICAgIGlmIChiIGluc3RhbmNlb2YgUmVjdGFuZ2xlKSBzY2FuKFtiLnggKyBiLndpZHRoXSwgW2IueSArIGIuaGVpZ2h0XSk7XG4gICAgICAgIGVsc2UgaWYgKGIgaW5zdGFuY2VvZiBQb2x5Z29uKSBzY2FuKGIueHBvaW50cywgYi55cG9pbnRzKTtcbiAgICAgICAgZWxzZSBpZiAoYiBpbnN0YW5jZW9mIE11bHRpUG9seWdvbikgZm9yIChjb25zdCBwIG9mIGIucG9seWdvbnMpIHNjYW4ocC54cG9pbnRzLCBwLnlwb2ludHMpO1xuICAgICAgfVxuICAgICAgdyA9IE1hdGgubWF4KHcsIE1hdGguY2VpbChtYXhYKSArIDIpO1xuICAgICAgaCA9IE1hdGgubWF4KGgsIE1hdGguY2VpbChtYXhZKSArIDIpO1xuICAgIH1cbiAgICByZXR1cm4geyB3LCBoIH07XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,123 @@
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();
6
+ /**
7
+ * Apply an image's saved ROIs once its render has landed, choosing the region
8
+ * layout from the image's shape:
9
+ *
10
+ * - **Folder stack** (`isStack && tiled === false`, see loadSeriesAsStack): a stack
11
+ * of self-contained per-slice files. Each slice-file may carry its own sibling
12
+ * `<stem>.geojson` (`roiJsonStrs[z]`), but a fresh folder with none yet leaves
13
+ * `roiJsonStrs` undefined — so this keys off `tiled === false`, NOT `roiJsonStrs`,
14
+ * and an unannotated folder stack still enters the per-slice-file layout (saving
15
+ * back one geojson per slice-file) rather than the combined one (jit-ui#93).
16
+ * - **Single-file z-stack**: one sibling geojson holding every slice's regions,
17
+ * indexed by QuPath's `geometry.plane.z`. Per-slice (combined) mode is entered when
18
+ * the geojson actually carries slice indices, or when there is nothing yet to
19
+ * author against. A legacy geojson whose regions are all on the default plane
20
+ * stays global (shown on every slice), so existing single-plane annotations are
21
+ * not confined to slice 0.
22
+ * - **Single plane** (or that legacy global stack): one region set for the image.
23
+ * Loading saved ROIs is not a user edit, so the undo history starts fresh and the
24
+ * first undo cannot wipe them (jit-ui#85).
25
+ *
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.
35
+ */
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;
41
+ if (info.isStack && info.tiled === false) {
42
+ const perSlice = info.roiJsonStrs;
43
+ const sliceCount = info.urls?.length ?? perSlice?.length ?? 0;
44
+ const slices = new Map();
45
+ const sourced = [];
46
+ for (let s = 0; s < sliceCount; s++) {
47
+ const json = perSlice?.[s] ?? null;
48
+ if (asSource(json))
49
+ sourced.push(s);
50
+ slices.set(s, json && !asSource(json) ? target.importRegions(json) : []);
51
+ }
52
+ target.enterStackMode(slices, z, 'per-slice-file');
53
+ for (const s of sourced)
54
+ attach?.(() => openGeoJsonRegionSource(perSlice?.[s]), { slice: s });
55
+ return;
56
+ }
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
+ }
99
+ if (info.isStack) {
100
+ const regions = roiJson ? target.importRegions(roiJson) : [];
101
+ if (!roiJson || regions.some((r) => (r.z ?? 0) !== 0)) {
102
+ target.enterStackMode(bySlice(regions), z, 'combined');
103
+ return;
104
+ }
105
+ }
106
+ if (roiJson)
107
+ target.setRegions(target.importRegions(roiJson));
108
+ target.resetUndoHistory();
109
+ }
110
+ /** Bucket regions by their zero-based {@link Region.z} (unset = slice 0). */
111
+ function bySlice(regions) {
112
+ const slices = new Map();
113
+ for (const r of regions) {
114
+ const z = r.z ?? 0;
115
+ const bucket = slices.get(z);
116
+ if (bucket)
117
+ bucket.push(r);
118
+ else
119
+ slices.set(z, [r]);
120
+ }
121
+ return slices;
122
+ }
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
@@ -0,0 +1,163 @@
1
+ import { takeUntil } from 'rxjs/operators';
2
+ import { PlotType, isSpatialOmics3d } from '../contracts/plot-type';
3
+ import { buildVolumeStackImage } from '../spatial/spatial-volume-image';
4
+ /**
5
+ * Binds the viewer to the spatial-omics dataset on `SPATIAL_DATA_PORT`: the gates it
6
+ * puts on the plot-type selector ({@link gates}), the mode an image-less dataset opens
7
+ * on, and publishing a dataset's registered volume AS the image.
8
+ *
9
+ * No-op when the host provides no port — the spatial types then stay hidden.
10
+ */
11
+ export class SpatialDatasetBinder {
12
+ constructor(port, host) {
13
+ this.port = port;
14
+ this.host = host;
15
+ /** The dataset on offer, for drawing one that brings no image. */
16
+ this.dataset = null;
17
+ /** A dataset is published — gates the spatial plot types; the toolbar binds it too. */
18
+ this.hasDataset = false;
19
+ /** Its observations carry a z, gating the 3D spatial mode. */
20
+ this.has3d = false;
21
+ /** It brings pixels of its own (see {@link SpatialGates.hasPixels}). */
22
+ this.hasPixels = false;
23
+ /** Dataset identity + capability shape the last emission was handled at, so a
24
+ * switch between two datasets of the same shape is not mistaken for a repeat. */
25
+ this.key = null;
26
+ /** Dataset + geometry the published volume image was built from, so a re-emitted
27
+ * dataset doesn't re-fetch megabytes or reset the user's scrub. */
28
+ this.volumeImageKey = null;
29
+ /** Blob URLs backing that image — ours to revoke. */
30
+ this.volumeImageUrls = [];
31
+ }
32
+ /** Follow the port's dataset until `until$` emits. */
33
+ bind(until$) {
34
+ this.port
35
+ ?.getDataset$()
36
+ .pipe(takeUntil(until$))
37
+ .subscribe((dataset) => this.onDataset(dataset ?? null));
38
+ }
39
+ /** Revoke the published volume image's blob URLs (teardown). */
40
+ dispose() {
41
+ this.revokeVolumeImageUrls();
42
+ }
43
+ onDataset(dataset) {
44
+ this.dataset = dataset;
45
+ // Only a dataset whose observations carry a z can be drawn as a cloud, so the 3D
46
+ // mode is gated on the coordinates, not merely on a dataset being present.
47
+ const has3d = !!dataset?.observations.z;
48
+ const hasVolume = !!dataset?.volume;
49
+ // The port publishes its current value on subscribe, so the initial `null` would
50
+ // otherwise recompute the selector for no change. Keyed by dataset IDENTITY as well
51
+ // as capability shape: two 3D datasets that both carry a volume have the same
52
+ // shape, and comparing only that skipped the switch — leaving the previous
53
+ // dataset's volume image on screen underneath the new one's observations.
54
+ const key = dataset
55
+ ? `${dataset.id}|${has3d}|${hasVolume}|${dataset.volume ? `${dataset.volume.width}x${dataset.volume.height}x${dataset.volume.depth}` : ''}`
56
+ : null;
57
+ if (key === this.key)
58
+ return;
59
+ this.key = key;
60
+ this.hasDataset = !!dataset;
61
+ this.has3d = has3d;
62
+ // Whether the dataset brings pixels: it registers onto a tissue image (which may
63
+ // still be on its way — the pixel modes must not flicker out while it arrives), or
64
+ // its volume is published AS a grayscale z-stack image. Either way the pixel modes
65
+ // stay on offer — Volume and Isosurface are exactly how a 3D omics dataset is read.
66
+ this.hasPixels = !!dataset?.imageRef || hasVolume;
67
+ this.host.gatesChanged();
68
+ if (dataset && !dataset.imageRef && hasVolume) {
69
+ // No section to draw observations over (a cloud registered into a common frame,
70
+ // the Allen CCF), but a registered VOLUME: make that the image and open on it,
71
+ // slice bar and all. Ordered after the gates so the type is on offer first.
72
+ void this.showVolumeAsImage(dataset);
73
+ }
74
+ else {
75
+ // Anything else means a published volume image is no longer what is on screen.
76
+ // Forget it, or coming BACK to the volume dataset would short-circuit on a
77
+ // matching key and leave the other dataset's slide up.
78
+ this.dropVolumeImage();
79
+ if (dataset && !dataset.imageRef) {
80
+ // No reference image and no volume: the observations are all there is, so open
81
+ // on whichever spatial mode their coordinates support — leaving the type alone
82
+ // strands the host on the previous slide. A one-plane assay has no z and
83
+ // cannot be a cloud.
84
+ const target = has3d ? PlotType.SPATIAL_OMICS_3D : PlotType.SPATIAL_OMICS;
85
+ if (this.host.selectedId() !== target)
86
+ this.host.selectPlotType(target);
87
+ // Same mode, another image-less dataset, nothing loaded: re-plot so its
88
+ // placeholder image info (and with it the regions' key) is this dataset's.
89
+ else if (!this.host.hasImage())
90
+ this.host.replot();
91
+ }
92
+ }
93
+ // Clearing the dataset while a spatial mode is active leaves a type that is no
94
+ // longer offered — the host falls back, as turning test mode off does.
95
+ this.host.settled();
96
+ }
97
+ /**
98
+ * Publish a dataset's reference volume AS the image, and open the 2D Image view on it:
99
+ * the slice bar scrubs z, and the contrast window, colormaps and region tools all work
100
+ * because the volume genuinely is the image now. The 3D cloud stays one pick away.
101
+ *
102
+ * Keyed by dataset + geometry: the dataset stream re-emits on things like a
103
+ * colour-column change, and rebuilding then would re-fetch the voxels and throw the
104
+ * user back to the middle slice.
105
+ */
106
+ async showVolumeAsImage(dataset) {
107
+ const meta = dataset.volume;
108
+ if (!meta || !this.port?.getVolume)
109
+ return;
110
+ const key = `${dataset.id}:${meta.width}x${meta.height}x${meta.depth}`;
111
+ if (key === this.volumeImageKey)
112
+ return;
113
+ // Claim the key BEFORE awaiting: the stream can emit again while the voxels are in
114
+ // flight, and two builds of the same volume would race to publish.
115
+ this.volumeImageKey = key;
116
+ this.host.setImageLoading(true);
117
+ try {
118
+ const built = await buildVolumeStackImage(dataset, await this.port.getVolume());
119
+ // A different dataset was selected while this one encoded: drop what we built.
120
+ if (this.volumeImageKey !== key) {
121
+ built?.urls.forEach((u) => URL.revokeObjectURL(u));
122
+ return;
123
+ }
124
+ if (!built) {
125
+ this.volumeImageKey = null;
126
+ return;
127
+ }
128
+ // Pick the mode first so the image lands in the view that will show it.
129
+ if (this.host.selectedId() !== PlotType.IMAGE)
130
+ this.host.selectPlotType(PlotType.IMAGE);
131
+ this.revokeVolumeImageUrls();
132
+ this.volumeImageUrls = built.urls;
133
+ this.host.publishImage(built.info);
134
+ }
135
+ catch (err) {
136
+ // No volume served after all: the cloud is still renderable, so fall back to it.
137
+ console.warn('[visualizer] reference volume unavailable — falling back to the 3D cloud', err);
138
+ this.volumeImageKey = null;
139
+ if (this.has3d && !isSpatialOmics3d(this.host.basePlotType())) {
140
+ this.host.selectPlotType(PlotType.SPATIAL_OMICS_3D);
141
+ }
142
+ }
143
+ finally {
144
+ // Only the build still on screen (or one that failed and released its key) may
145
+ // drop the overlay: a newer volume build that superseded this one is still encoding.
146
+ if (this.volumeImageKey === key || this.volumeImageKey === null)
147
+ this.host.setImageLoading(false);
148
+ this.host.detectChanges();
149
+ }
150
+ }
151
+ /** Forget the published volume image so re-selecting the dataset rebuilds it. The
152
+ * URLs deliberately stay alive: the host may still be displaying that image, and
153
+ * revoking under it would break every later tile read. They are freed when the next
154
+ * volume replaces them, or on {@link dispose}. */
155
+ dropVolumeImage() {
156
+ this.volumeImageKey = null;
157
+ }
158
+ revokeVolumeImageUrls() {
159
+ this.volumeImageUrls.forEach((u) => URL.revokeObjectURL(u));
160
+ this.volumeImageUrls = [];
161
+ }
162
+ }
163
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhdGlhbC1kYXRhc2V0LWJpbmRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvdmlzdWFsaXplci9zcGF0aWFsLWRhdGFzZXQtYmluZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUczQyxPQUFPLEVBQUUsUUFBUSxFQUFjLGdCQUFnQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFJaEYsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFzQnhFOzs7Ozs7R0FNRztBQUNILE1BQU0sT0FBTyxvQkFBb0I7SUFrQi9CLFlBQ21CLElBQWlDLEVBQ2pDLElBQXVCO1FBRHZCLFNBQUksR0FBSixJQUFJLENBQTZCO1FBQ2pDLFNBQUksR0FBSixJQUFJLENBQW1CO1FBbkIxQyxrRUFBa0U7UUFDbEUsWUFBTyxHQUEwQixJQUFJLENBQUM7UUFDdEMsdUZBQXVGO1FBQ3ZGLGVBQVUsR0FBRyxLQUFLLENBQUM7UUFDbkIsOERBQThEO1FBQzlELFVBQUssR0FBRyxLQUFLLENBQUM7UUFDZCx3RUFBd0U7UUFDeEUsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUNsQjswRkFDa0Y7UUFDMUUsUUFBRyxHQUFrQixJQUFJLENBQUM7UUFDbEM7NEVBQ29FO1FBQzVELG1CQUFjLEdBQWtCLElBQUksQ0FBQztRQUM3QyxxREFBcUQ7UUFDN0Msb0JBQWUsR0FBYSxFQUFFLENBQUM7SUFLcEMsQ0FBQztJQUVKLHNEQUFzRDtJQUN0RCxJQUFJLENBQUMsTUFBMkI7UUFDOUIsSUFBSSxDQUFDLElBQUk7WUFDUCxFQUFFLFdBQVcsRUFBRTthQUNkLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7YUFDdkIsU0FBUyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sSUFBSSxJ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aW1wb3J0IHsgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBJSW1hZ2VJbmZvIH0gZnJvbSAnLi4vY29udHJhY3RzL2ltYWdlLmNvbnRyYWN0JztcbmltcG9ydCB7IFBsb3RUeXBlLCBQbG90VHlwZUlkLCBpc1NwYXRpYWxPbWljczNkIH0gZnJvbSAnLi4vY29udHJhY3RzL3Bsb3QtdHlwZSc7XG5pbXBvcnQgeyBTcGF0aWFsRGF0YVBvcnQgfSBmcm9tICcuLi9jb250cmFjdHMvcG9ydHMvc3BhdGlhbC1kYXRhLnBvcnQnO1xuaW1wb3J0IHsgU3BhdGlhbERhdGFzZXQgfSBmcm9tICcuLi9jb250cmFjdHMvc3BhdGlhbC1kYXRhc2V0LmNvbnRyYWN0JztcbmltcG9ydCB7IFNwYXRpYWxHYXRlcyB9IGZyb20gJy4uL3Bsb3QtbW9kZS9wbG90LXR5cGUtbWVudSc7XG5pbXBvcnQgeyBidWlsZFZvbHVtZVN0YWNrSW1hZ2UgfSBmcm9tICcuLi9zcGF0aWFsL3NwYXRpYWwtdm9sdW1lLWltYWdlJztcblxuLyoqIFdoYXQgYSBkYXRhc2V0IHN3aXRjaCBhc2tzIG9mIHRoZSB2aWV3ZXIuICovXG5leHBvcnQgaW50ZXJmYWNlIFNwYXRpYWxCaW5kZXJIb3N0IHtcbiAgLyoqIFRoZSBwbG90LXR5cGUgZ2F0ZXMgY2hhbmdlZDogcmVjb21wdXRlIHRoZSBzZWxlY3Rvci4gKi9cbiAgZ2F0ZXNDaGFuZ2VkKCk6IHZvaWQ7XG4gIC8qKiBUaGUgc2VsZWN0b3IncyBjdXJyZW50IGlkLCBhbmQgdGhlIGJ1aWx0LWluIHR5cGUgcmVuZGVyZWQgZm9yIGl0LiAqL1xuICBzZWxlY3RlZElkKCk6IFBsb3RUeXBlSWQ7XG4gIGJhc2VQbG90VHlwZSgpOiBQbG90VHlwZTtcbiAgLyoqIFdoZXRoZXIgYW4gaW1hZ2UgaXMgbG9hZGVkLiAqL1xuICBoYXNJbWFnZSgpOiBib29sZWFuO1xuICBzZWxlY3RQbG90VHlwZSh0eXBlOiBQbG90VHlwZSk6IHZvaWQ7XG4gIC8qKiBSZS1wbG90IHRoZSBjdXJyZW50IG1vZGUuICovXG4gIHJlcGxvdCgpOiB2b2lkO1xuICAvKiogUHVibGlzaCBhbiBpbWFnZSBhcyB0aGUgaG9zdCdzIGN1cnJlbnQgb25lLiAqL1xuICBwdWJsaXNoSW1hZ2UoaW5mbzogSUltYWdlSW5mbyk6IHZvaWQ7XG4gIHNldEltYWdlTG9hZGluZyhsb2FkaW5nOiBib29sZWFuKTogdm9pZDtcbiAgLyoqIFRoZSBzd2l0Y2ggaXMgaGFuZGxlZDogcmVjb25jaWxlIHRoZSBzZWxlY3Rpb24gd2l0aCB0aGUgbmV3IGdhdGVzIGFuZCByZS1yZW5kZXIuICovXG4gIHNldHRsZWQoKTogdm9pZDtcbiAgZGV0ZWN0Q2hhbmdlcygpOiB2b2lkO1xufVxuXG4vKipcbiAqIEJpbmRzIHRoZSB2aWV3ZXIgdG8gdGhlIHNwYXRpYWwtb21pY3MgZGF0YXNldCBvbiBgU1BBVElBTF9EQVRBX1BPUlRgOiB0aGUgZ2F0ZXMgaXRcbiAqIHB1dHMgb24gdGhlIHBsb3QtdHlwZSBzZWxlY3RvciAoe0BsaW5rIGdhdGVzfSksIHRoZSBtb2RlIGFuIGltYWdlLWxlc3MgZGF0YXNldCBvcGVuc1xuICogb24sIGFuZCBwdWJsaXNoaW5nIGEgZGF0YXNldCdzIHJlZ2lzdGVyZWQgdm9sdW1lIEFTIHRoZSBpbWFnZS5cbiAqXG4gKiBOby1vcCB3aGVuIHRoZSBob3N0IHByb3ZpZGVzIG5vIHBvcnQg4oCUIHRoZSBzcGF0aWFsIHR5cGVzIHRoZW4gc3RheSBoaWRkZW4uXG4gKi9cbmV4cG9ydCBjbGFzcyBTcGF0aWFsRGF0YXNldEJpbmRlciBpbXBsZW1lbnRzIFNwYXRpYWxHYXRlcyB7XG4gIC8qKiBUaGUgZGF0YXNldCBvbiBvZmZlciwgZm9yIGRyYXdpbmcgb25lIHRoYXQgYnJpbmdzIG5vIGltYWdlLiAqL1xuICBkYXRhc2V0OiBTcGF0aWFsRGF0YXNldCB8IG51bGwgPSBudWxsO1xuICAvKiogQSBkYXRhc2V0IGlzIHB1Ymxpc2hlZCDigJQgZ2F0ZXMgdGhlIHNwYXRpYWwgcGxvdCB0eXBlczsgdGhlIHRvb2xiYXIgYmluZHMgaXQgdG9vLiAqL1xuICBoYXNEYXRhc2V0ID0gZmFsc2U7XG4gIC8qKiBJdHMgb2JzZXJ2YXRpb25zIGNhcnJ5IGEgeiwgZ2F0aW5nIHRoZSAzRCBzcGF0aWFsIG1vZGUuICovXG4gIGhhczNkID0gZmFsc2U7XG4gIC8qKiBJdCBicmluZ3MgcGl4ZWxzIG9mIGl0cyBvd24gKHNlZSB7QGxpbmsgU3BhdGlhbEdhdGVzLmhhc1BpeGVsc30pLiAqL1xuICBoYXNQaXhlbHMgPSBmYWxzZTtcbiAgLyoqIERhdGFzZXQgaWRlbnRpdHkgKyBjYXBhYmlsaXR5IHNoYXBlIHRoZSBsYXN0IGVtaXNzaW9uIHdhcyBoYW5kbGVkIGF0LCBzbyBhXG4gICAqICBzd2l0Y2ggYmV0d2VlbiB0d28gZGF0YXNldHMgb2YgdGhlIHNhbWUgc2hhcGUgaXMgbm90IG1pc3Rha2VuIGZvciBhIHJlcGVhdC4gKi9cbiAgcHJpdmF0ZSBrZXk6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICAvKiogRGF0YXNldCArIGdlb21ldHJ5IHRoZSBwdWJsaXNoZWQgdm9sdW1lIGltYWdlIHdhcyBidWlsdCBmcm9tLCBzbyBhIHJlLWVtaXR0ZWRcbiAgICogIGRhdGFzZXQgZG9lc24ndCByZS1mZXRjaCBtZWdhYnl0ZXMgb3IgcmVzZXQgdGhlIHVzZXIncyBzY3J1Yi4gKi9cbiAgcHJpdmF0ZSB2b2x1bWVJbWFnZUtleTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBCbG9iIFVSTHMgYmFja2luZyB0aGF0IGltYWdlIOKAlCBvdXJzIHRvIHJldm9rZS4gKi9cbiAgcHJpdmF0ZSB2b2x1bWVJbWFnZVVybHM6IHN0cmluZ1tdID0gW107XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBwb3J0OiBTcGF0aWFsRGF0YVBvcnQgfCB1bmRlZmluZWQsXG4gICAgcHJpdmF0ZSByZWFkb25seSBob3N0OiBTcGF0aWFsQmluZGVySG9zdCxcbiAgKSB7fVxuXG4gIC8qKiBGb2xsb3cgdGhlIHBvcnQncyBkYXRhc2V0IHVudGlsIGB1bnRpbCRgIGVtaXRzLiAqL1xuICBiaW5kKHVudGlsJDogT2JzZXJ2YWJsZTx1bmtub3duPik6IHZvaWQge1xuICAgIHRoaXMucG9ydFxuICAgICAgPy5nZXREYXRhc2V0JCgpXG4gICAgICAucGlwZSh0YWtlVW50aWwodW50aWwkKSlcbiAgICAgIC5zdWJzY3JpYmUoKGRhdGFzZXQpID0+IHRoaXMub25EYXRhc2V0KGRhdGFzZXQgPz8gbnVsbCkpO1xuICB9XG5cbiAgLyoqIFJldm9rZSB0aGUgcHVibGlzaGVkIHZvbHVtZSBpbWFnZSdzIGJsb2IgVVJMcyAodGVhcmRvd24pLiAqL1xuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIHRoaXMucmV2b2tlVm9sdW1lSW1hZ2VVcmxzKCk7XG4gIH1cblxuICBwcml2YXRlIG9uRGF0YXNldChkYXRhc2V0OiBTcGF0aWFsRGF0YXNldCB8IG51bGwpOiB2b2lkIHtcbiAgICB0aGlzLmRhdGFzZXQgPSBkYXRhc2V0O1xuICAgIC8vIE9ubHkgYSBkYXRhc2V0IHdob3NlIG9ic2VydmF0aW9ucyBjYXJyeSBhIHogY2FuIGJlIGRyYXduIGFzIGEgY2xvdWQsIHNvIHRoZSAzRFxuICAgIC8vIG1vZGUgaXMgZ2F0ZWQgb24gdGhlIGNvb3JkaW5hdGVzLCBub3QgbWVyZWx5IG9uIGEgZGF0YXNldCBiZWluZyBwcmVzZW50LlxuICAgIGNvbnN0IGhhczNkID0gISFkYXRhc2V0Py5vYnNlcnZhdGlvbnMuejtcbiAgICBjb25zdCBoYXNWb2x1bWUgPSAhIWRhdGFzZXQ/LnZvbHVtZTtcbiAgICAvLyBUaGUgcG9ydCBwdWJsaXNoZXMgaXRzIGN1cnJlbnQgdmFsdWUgb24gc3Vic2NyaWJlLCBzbyB0aGUgaW5pdGlhbCBgbnVsbGAgd291bGRcbiAgICAvLyBvdGhlcndpc2UgcmVjb21wdXRlIHRoZSBzZWxlY3RvciBmb3Igbm8gY2hhbmdlLiBLZXllZCBieSBkYXRhc2V0IElERU5USVRZIGFzIHdlbGxcbiAgICAvLyBhcyBjYXBhYmlsaXR5IHNoYXBlOiB0d28gM0QgZGF0YXNldHMgdGhhdCBib3RoIGNhcnJ5IGEgdm9sdW1lIGhhdmUgdGhlIHNhbWVcbiAgICAvLyBzaGFwZSwgYW5kIGNvbXBhcmluZyBvbmx5IHRoYXQgc2tpcHBlZCB0aGUgc3dpdGNoIOKAlCBsZWF2aW5nIHRoZSBwcmV2aW91c1xuICAgIC8vIGRhdGFzZXQncyB2b2x1bWUgaW1hZ2Ugb24gc2NyZWVuIHVuZGVybmVhdGggdGhlIG5ldyBvbmUncyBvYnNlcnZhdGlvbnMuXG4gICAgY29uc3Qga2V5ID0gZGF0YXNldFxuICAgICAgPyBgJHtkYXRhc2V0LmlkfXwke2hhczNkfXwke2hhc1ZvbHVtZX18JHtcbiAgICAgICAgICBkYXRhc2V0LnZvbHVtZSA/IGAke2RhdGFzZXQudm9sdW1lLndpZHRofXgke2RhdGFzZXQudm9sdW1lLmhlaWdodH14JHtkYXRhc2V0LnZvbHVtZS5kZXB0aH1gIDogJydcbiAgICAgICAgfWBcbiAgICAgIDogbnVsbDtcbiAgICBpZiAoa2V5ID09PSB0aGlzLmtleSkgcmV0dXJuO1xuICAgIHRoaXMua2V5ID0ga2V5O1xuICAgIHRoaXMuaGFzRGF0YXNldCA9ICEhZGF0YXNldDtcbiAgICB0aGlzLmhhczNkID0gaGFzM2Q7XG4gICAgLy8gV2hldGhlciB0aGUgZGF0YXNldCBicmluZ3MgcGl4ZWxzOiBpdCByZWdpc3RlcnMgb250byBhIHRpc3N1ZSBpbWFnZSAod2hpY2ggbWF5XG4gICAgLy8gc3RpbGwgYmUgb24gaXRzIHdheSDigJQgdGhlIHBpeGVsIG1vZGVzIG11c3Qgbm90IGZsaWNrZXIgb3V0IHdoaWxlIGl0IGFycml2ZXMpLCBvclxuICAgIC8vIGl0cyB2b2x1bWUgaXMgcHVibGlzaGVkIEFTIGEgZ3JheXNjYWxlIHotc3RhY2sgaW1hZ2UuIEVpdGhlciB3YXkgdGhlIHBpeGVsIG1vZGVzXG4gICAgLy8gc3RheSBvbiBvZmZlciDigJQgVm9sdW1lIGFuZCBJc29zdXJmYWNlIGFyZSBleGFjdGx5IGhvdyBhIDNEIG9taWNzIGRhdGFzZXQgaXMgcmVhZC5cbiAgICB0aGlzLmhhc1BpeGVscyA9ICEhZGF0YXNldD8uaW1hZ2VSZWYgfHwgaGFzVm9sdW1lO1xuICAgIHRoaXMuaG9zdC5nYXRlc0NoYW5nZWQoKTtcbiAgICBpZiAoZGF0YXNldCAmJiAhZGF0YXNldC5pbWFnZVJlZiAmJiBoYXNWb2x1bWUpIHtcbiAgICAgIC8vIE5vIHNlY3Rpb24gdG8gZHJhdyBvYnNlcnZhdGlvbnMgb3ZlciAoYSBjbG91ZCByZWdpc3RlcmVkIGludG8gYSBjb21tb24gZnJhbWUsXG4gICAgICAvLyB0aGUgQWxsZW4gQ0NGKSwgYnV0IGEgcmVnaXN0ZXJlZCBWT0xVTUU6IG1ha2UgdGhhdCB0aGUgaW1hZ2UgYW5kIG9wZW4gb24gaXQsXG4gICAgICAvLyBzbGljZSBiYXIgYW5kIGFsbC4gT3JkZXJlZCBhZnRlciB0aGUgZ2F0ZXMgc28gdGhlIHR5cGUgaXMgb24gb2ZmZXIgZmlyc3QuXG4gICAgICB2b2lkIHRoaXMuc2hvd1ZvbHVtZUFzSW1hZ2UoZGF0YXNldCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEFueXRoaW5nIGVsc2UgbWVhbnMgYSBwdWJsaXNoZWQgdm9sdW1lIGltYWdlIGlzIG5vIGxvbmdlciB3aGF0IGlzIG9uIHNjcmVlbi5cbiAgICAgIC8vIEZvcmdldCBpdCwgb3IgY29taW5nIEJBQ0sgdG8gdGhlIHZvbHVtZSBkYXRhc2V0IHdvdWxkIHNob3J0LWNpcmN1aXQgb24gYVxuICAgICAgLy8gbWF0Y2hpbmcga2V5IGFuZCBsZWF2ZSB0aGUgb3RoZXIgZGF0YXNldCdzIHNsaWRlIHVwLlxuICAgICAgdGhpcy5kcm9wVm9sdW1lSW1hZ2UoKTtcbiAgICAgIGlmIChkYXRhc2V0ICYmICFkYXRhc2V0LmltYWdlUmVmKSB7XG4gICAgICAgIC8vIE5vIHJlZmVyZW5jZSBpbWFnZSBhbmQgbm8gdm9sdW1lOiB0aGUgb2JzZXJ2YXRpb25zIGFyZSBhbGwgdGhlcmUgaXMsIHNvIG9wZW5cbiAgICAgICAgLy8gb24gd2hpY2hldmVyIHNwYXRpYWwgbW9kZSB0aGVpciBjb29yZGluYXRlcyBzdXBwb3J0IOKAlCBsZWF2aW5nIHRoZSB0eXBlIGFsb25lXG4gICAgICAgIC8vIHN0cmFuZHMgdGhlIGhvc3Qgb24gdGhlIHByZXZpb3VzIHNsaWRlLiBBIG9uZS1wbGFuZSBhc3NheSBoYXMgbm8geiBhbmRcbiAgICAgICAgLy8gY2Fubm90IGJlIGEgY2xvdWQuXG4gICAgICAgIGNvbnN0IHRhcmdldCA9IGhhczNkID8gUGxvdFR5cGUuU1BBVElBTF9PTUlDU18zRCA6IFBsb3RUeXBlLlNQQVRJQUxfT01JQ1M7XG4gICAgICAgIGlmICh0aGlzLmhvc3Quc2VsZWN0ZWRJZCgpICE9PSB0YXJnZXQpIHRoaXMuaG9zdC5zZWxlY3RQbG90VHlwZSh0YXJnZXQpO1xuICAgICAgICAvLyBTYW1lIG1vZGUsIGFub3RoZXIgaW1hZ2UtbGVzcyBkYXRhc2V0LCBub3RoaW5nIGxvYWRlZDogcmUtcGxvdCBzbyBpdHNcbiAgICAgICAgLy8gcGxhY2Vob2xkZXIgaW1hZ2UgaW5mbyAoYW5kIHdpdGggaXQgdGhlIHJlZ2lvbnMnIGtleSkgaXMgdGhpcyBkYXRhc2V0J3MuXG4gICAgICAgIGVsc2UgaWYgKCF0aGlzLmhvc3QuaGFzSW1hZ2UoKSkgdGhpcy5ob3N0LnJlcGxvdCgpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBDbGVhcmluZyB0aGUgZGF0YXNldCB3aGlsZSBhIHNwYXRpYWwgbW9kZSBpcyBhY3RpdmUgbGVhdmVzIGEgdHlwZSB0aGF0IGlzIG5vXG4gICAgLy8gbG9uZ2VyIG9mZmVyZWQg4oCUIHRoZSBob3N0IGZhbGxzIGJhY2ssIGFzIHR1cm5pbmcgdGVzdCBtb2RlIG9mZiBkb2VzLlxuICAgIHRoaXMuaG9zdC5zZXR0bGVkKCk7XG4gIH1cblxuICAvKipcbiAgICogUHVibGlzaCBhIGRhdGFzZXQncyByZWZlcmVuY2Ugdm9sdW1lIEFTIHRoZSBpbWFnZSwgYW5kIG9wZW4gdGhlIDJEIEltYWdlIHZpZXcgb24gaXQ6XG4gICAqIHRoZSBzbGljZSBiYXIgc2NydWJzIHosIGFuZCB0aGUgY29udHJhc3Qgd2luZG93LCBjb2xvcm1hcHMgYW5kIHJlZ2lvbiB0b29scyBhbGwgd29ya1xuICAgKiBiZWNhdXNlIHRoZSB2b2x1bWUgZ2VudWluZWx5IGlzIHRoZSBpbWFnZSBub3cuIFRoZSAzRCBjbG91ZCBzdGF5cyBvbmUgcGljayBhd2F5LlxuICAgKlxuICAgKiBLZXllZCBieSBkYXRhc2V0ICsgZ2VvbWV0cnk6IHRoZSBkYXRhc2V0IHN0cmVhbSByZS1lbWl0cyBvbiB0aGluZ3MgbGlrZSBhXG4gICAqIGNvbG91ci1jb2x1bW4gY2hhbmdlLCBhbmQgcmVidWlsZGluZyB0aGVuIHdvdWxkIHJlLWZldGNoIHRoZSB2b3hlbHMgYW5kIHRocm93IHRoZVxuICAgKiB1c2VyIGJhY2sgdG8gdGhlIG1pZGRsZSBzbGljZS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgc2hvd1ZvbHVtZUFzSW1hZ2UoZGF0YXNldDogU3BhdGlhbERhdGFzZXQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBtZXRhID0gZGF0YXNldC52b2x1bWU7XG4gICAgaWYgKCFtZXRhIHx8ICF0aGlzLnBvcnQ/LmdldFZvbHVtZSkgcmV0dXJuO1xuICAgIGNvbnN0IGtleSA9IGAke2RhdGFzZXQuaWR9OiR7bWV0YS53aWR0aH14JHttZXRhLmhlaWdodH14JHttZXRhLmRlcHRofWA7XG4gICAgaWYgKGtleSA9PT0gdGhpcy52b2x1bWVJbWFnZUtleSkgcmV0dXJuO1xuICAgIC8vIENsYWltIHRoZSBrZXkgQkVGT1JFIGF3YWl0aW5nOiB0aGUgc3RyZWFtIGNhbiBlbWl0IGFnYWluIHdoaWxlIHRoZSB2b3hlbHMgYXJlIGluXG4gICAgLy8gZmxpZ2h0LCBhbmQgdHdvIGJ1aWxkcyBvZiB0aGUgc2FtZSB2b2x1bWUgd291bGQgcmFjZSB0byBwdWJsaXNoLlxuICAgIHRoaXMudm9sdW1lSW1hZ2VLZXkgPSBrZXk7XG4gICAgdGhpcy5ob3N0LnNldEltYWdlTG9hZGluZyh0cnVlKTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgYnVpbHQgPSBhd2FpdCBidWlsZFZvbHVtZVN0YWNrSW1hZ2UoZGF0YXNldCwgYXdhaXQgdGhpcy5wb3J0LmdldFZvbHVtZSgpKTtcbiAgICAgIC8vIEEgZGlmZmVyZW50IGRhdGFzZXQgd2FzIHNlbGVjdGVkIHdoaWxlIHRoaXMgb25lIGVuY29kZWQ6IGRyb3Agd2hhdCB3ZSBidWlsdC5cbiAgICAgIGlmICh0aGlzLnZvbHVtZUltYWdlS2V5ICE9PSBrZXkpIHtcbiAgICAgICAgYnVpbHQ/LnVybHMuZm9yRWFjaCgodSkgPT4gVVJMLnJldm9rZU9iamVjdFVSTCh1KSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICghYnVpbHQpIHtcbiAgICAgICAgdGhpcy52b2x1bWVJbWFnZUtleSA9IG51bGw7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIC8vIFBpY2sgdGhlIG1vZGUgZmlyc3Qgc28gdGhlIGltYWdlIGxhbmRzIGluIHRoZSB2aWV3IHRoYXQgd2lsbCBzaG93IGl0LlxuICAgICAgaWYgKHRoaXMuaG9zdC5zZWxlY3RlZElkKCkgIT09IFBsb3RUeXBlLklNQUdFKSB0aGlzLmhvc3Quc2VsZWN0UGxvdFR5cGUoUGxvdFR5cGUuSU1BR0UpO1xuICAgICAgdGhpcy5yZXZva2VWb2x1bWVJbWFnZVVybHMoKTtcbiAgICAgIHRoaXMudm9sdW1lSW1hZ2VVcmxzID0gYnVpbHQudXJscztcbiAgICAgIHRoaXMuaG9zdC5wdWJsaXNoSW1hZ2UoYnVpbHQuaW5mbyk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvLyBObyB2b2x1bWUgc2VydmVkIGFmdGVyIGFsbDogdGhlIGNsb3VkIGlzIHN0aWxsIHJlbmRlcmFibGUsIHNvIGZhbGwgYmFjayB0byBpdC5cbiAgICAgIGNvbnNvbGUud2FybignW3Zpc3VhbGl6ZXJdIHJlZmVyZW5jZSB2b2x1bWUgdW5hdmFpbGFibGUg4oCUIGZhbGxpbmcgYmFjayB0byB0aGUgM0QgY2xvdWQnLCBlcnIpO1xuICAgICAgdGhpcy52b2x1bWVJbWFnZUtleSA9IG51bGw7XG4gICAgICBpZiAodGhpcy5oYXMzZCAmJiAhaXNTcGF0aWFsT21pY3MzZCh0aGlzLmhvc3QuYmFzZVBsb3RUeXBlKCkpKSB7XG4gICAgICAgIHRoaXMuaG9zdC5zZWxlY3RQbG90VHlwZShQbG90VHlwZS5TUEFUSUFMX09NSUNTXzNEKTtcbiAgICAgIH1cbiAgICB9IGZpbmFsbHkge1xuICAgICAgLy8gT25seSB0aGUgYnVpbGQgc3RpbGwgb24gc2NyZWVuIChvciBvbmUgdGhhdCBmYWlsZWQgYW5kIHJlbGVhc2VkIGl0cyBrZXkpIG1heVxuICAgICAgLy8gZHJvcCB0aGUgb3ZlcmxheTogYSBuZXdlciB2b2x1bWUgYnVpbGQgdGhhdCBzdXBlcnNlZGVkIHRoaXMgb25lIGlzIHN0aWxsIGVuY29kaW5nLlxuICAgICAgaWYgKHRoaXMudm9sdW1lSW1hZ2VLZXkgPT09IGtleSB8fCB0aGlzLnZvbHVtZUltYWdlS2V5ID09PSBudWxsKSB0aGlzLmhvc3Quc2V0SW1hZ2VMb2FkaW5nKGZhbHNlKTtcbiAgICAgIHRoaXMuaG9zdC5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEZvcmdldCB0aGUgcHVibGlzaGVkIHZvbHVtZSBpbWFnZSBzbyByZS1zZWxlY3RpbmcgdGhlIGRhdGFzZXQgcmVidWlsZHMgaXQuIFRoZVxuICAgKiAgVVJMcyBkZWxpYmVyYXRlbHkgc3RheSBhbGl2ZTogdGhlIGhvc3QgbWF5IHN0aWxsIGJlIGRpc3BsYXlpbmcgdGhhdCBpbWFnZSwgYW5kXG4gICAqICByZXZva2luZyB1bmRlciBpdCB3b3VsZCBicmVhayBldmVyeSBsYXRlciB0aWxlIHJlYWQuIFRoZXkgYXJlIGZyZWVkIHdoZW4gdGhlIG5leHRcbiAgICogIHZvbHVtZSByZXBsYWNlcyB0aGVtLCBvciBvbiB7QGxpbmsgZGlzcG9zZX0uICovXG4gIHByaXZhdGUgZHJvcFZvbHVtZUltYWdlKCk6IHZvaWQge1xuICAgIHRoaXMudm9sdW1lSW1hZ2VLZXkgPSBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSByZXZva2VWb2x1bWVJbWFnZVVybHMoKTogdm9pZCB7XG4gICAgdGhpcy52b2x1bWVJbWFnZVVybHMuZm9yRWFjaCgodSkgPT4gVVJMLnJldm9rZU9iamVjdFVSTCh1KSk7XG4gICAgdGhpcy52b2x1bWVJbWFnZVVybHMgPSBbXTtcbiAgfVxufVxuIl19