@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,306 @@
1
+ import { pointSymbolCode } from 'napari-js';
2
+ import { ALL_GENES } from '../../../contracts/ports/spatial-data.port';
3
+ import { NO_CATEGORY, NO_OBSERVATION, } from '../../../contracts/spatial-dataset.contract';
4
+ import { DEFAULT_CATEGORICAL_PALETTE, parseHex, resolveCategoryColors } from '../../../spatial/spatial-encoding';
5
+ import { cellTypeColumnFor } from '../../../spatial/lod';
6
+ import { clusterColorMap } from '../../../spatial/transcript-grouping';
7
+ import { defaultGlyphFor } from '../../../spatial/glyphs';
8
+ import { filterTranscripts, hiddenGeneSlots, median } from '../../../spatial/spatial-tile-merge';
9
+ import { groupSelection } from './transcript-jobs';
10
+ /** Icons get a dark rim only while there are at most this many, at least this big (px). */
11
+ const GLYPH_OUTLINE_MAX = 20_000;
12
+ const GLYPH_OUTLINE_MIN_PX = 8;
13
+ /** The dark rim of a marker. */
14
+ const RIM_COLOR = [0.04, 0.04, 0.05, 0.9];
15
+ /**
16
+ * The napari-js point symbol each transcript icon is drawn as. Every icon has a counterpart of
17
+ * the same outline (`circle` is napari's `disc`); see {@link GLYPH_SIZE} for the one whose size
18
+ * differs.
19
+ */
20
+ export const GLYPH_SYMBOLS = {
21
+ circle: 'disc',
22
+ star: 'star',
23
+ triangle: 'triangle_up',
24
+ square: 'square',
25
+ diamond: 'diamond',
26
+ cross: 'cross',
27
+ hexagon: 'hexagon',
28
+ 'triangle-down': 'triangle_down',
29
+ pentagon: 'pentagon',
30
+ x: 'x',
31
+ };
32
+ /**
33
+ * Marker diameter per icon, as a fraction of the entry's: napari's `square` fills the marker's
34
+ * whole box, where the icon it replaces had a 0.8 half-side, as heavy as the other icons.
35
+ */
36
+ const GLYPH_SIZE = { square: 0.8 };
37
+ /**
38
+ * What a transcript plan draws, as a key: an unchanged one is a no-op. Marker sizes follow the
39
+ * zoom, so the zoom is part of it; a pan that keeps the same tiles on screen changes nothing.
40
+ */
41
+ function transcriptPlanKey(dataset, view, job, pxPerUnit) {
42
+ return [
43
+ dataset.id,
44
+ view.transcriptMode,
45
+ job.key,
46
+ view.transcriptColorBy,
47
+ cellTypeColumnFor(dataset, view),
48
+ view.transcriptScale,
49
+ view.transcriptOpacity,
50
+ JSON.stringify(view.transcriptGlyphs),
51
+ pxPerUnit.toPrecision(4),
52
+ view.hiddenGroups.join('\u0001'),
53
+ view.transcriptHiddenGenes.join(','),
54
+ JSON.stringify(view.transcriptGeneColors),
55
+ JSON.stringify(view.transcriptGeneGroups),
56
+ ].join('|');
57
+ }
58
+ /** The view the markers are coloured by, for what was loaded. */
59
+ function colorViewFor(view, kind, clustered) {
60
+ // A bin of the all-gene pyramid mixes genes and carries none, so it cannot be coloured
61
+ // by gene: colour it by its dominant cell's type until individual transcripts show.
62
+ if (kind === 'bins' && view.transcriptColorBy !== 'cellType')
63
+ return { ...view, transcriptColorBy: 'cellType' };
64
+ // Density-grid markers have no cell to take a type from: they take their cluster's colour.
65
+ if (clustered && view.transcriptColorBy === 'cellType')
66
+ return { ...view, transcriptColorBy: 'cluster' };
67
+ return view;
68
+ }
69
+ const UNASSIGNED_RGBA = [0.62, 0.62, 0.62, 0.55];
70
+ /**
71
+ * The transcript markers of the 2D spatial view: runs the planner's job, drops hidden groups
72
+ * and genes, groups a selection under the marker budget, colours the entries and draws them as
73
+ * one points layer: sized circles, or gene icons as per-point symbols (with a dark rim while
74
+ * there are few enough).
75
+ *
76
+ * Hands what it drew to the hover one way ({@link TranscriptHover.setDrawn}), and keeps the
77
+ * loaded per-gene transcripts the in-view gene counts are taken from.
78
+ */
79
+ export class TranscriptLayers {
80
+ constructor(groups, jobs, lookup, hover) {
81
+ this.groups = groups;
82
+ this.jobs = jobs;
83
+ this.lookup = lookup;
84
+ this.hover = hover;
85
+ /** The loaded per-gene transcripts the in-view counts are taken from. */
86
+ this.countSource = null;
87
+ }
88
+ /**
89
+ * Transcripts of each selected gene inside `rect`: each entry counts for the transcripts it
90
+ * stands for (an aggregate at a coarse level holds several). Null without per-gene data.
91
+ */
92
+ geneCountsIn(rect) {
93
+ const src = this.countSource;
94
+ if (!src)
95
+ return null;
96
+ const out = {};
97
+ for (const g of src.genes)
98
+ out[g] = 0;
99
+ const { x, y, weight, gene } = src.merged;
100
+ for (let i = 0; i < src.merged.count; i++) {
101
+ if (x[i] < rect.x0 || x[i] > rect.x1 || y[i] < rect.y0 || y[i] > rect.y1)
102
+ continue;
103
+ const name = src.genes[gene[i]];
104
+ if (name !== undefined)
105
+ out[name] += weight[i];
106
+ }
107
+ return out;
108
+ }
109
+ /** The viewer went away: no counts until the next plan. */
110
+ detached() {
111
+ this.countSource = null;
112
+ }
113
+ /** Draw the view's transcript markers (or drop them); an unchanged plan key is a no-op. */
114
+ async plan(dataset, view, rect, pxPerUnit, ctx) {
115
+ const mode = view.transcriptMode;
116
+ const job = this.jobs.jobFor(dataset, view, rect, pxPerUnit);
117
+ if (!job) {
118
+ this.groups.drop('transcripts');
119
+ this.hover.clear();
120
+ this.countSource = null;
121
+ return;
122
+ }
123
+ const planKey = transcriptPlanKey(dataset, view, job, pxPerUnit);
124
+ if (planKey === this.groups.key('transcripts') && this.groups.shown('transcripts')) {
125
+ return;
126
+ }
127
+ const loaded = await ctx.track('Transcripts', job.load(ctx));
128
+ if (ctx.stale())
129
+ return;
130
+ // Per-gene counts in view come from what was loaded, before hidden genes are dropped:
131
+ // a hidden gene still has transcripts there. Summed density grids (no per-gene levels,
132
+ // zoomed out) hold clusters, not genes: no per-gene counts there, rather than a guess.
133
+ this.countSource =
134
+ (loaded.kind ?? job.kind) === 'genes' && !loaded.clustered
135
+ ? { merged: loaded.merged, genes: [...view.transcriptGenes] }
136
+ : null;
137
+ const hidden = await this.lookup.hiddenCodes(dataset, view);
138
+ if (ctx.stale())
139
+ return;
140
+ // Density-grid markers carry no cells and were built from the visible genes only.
141
+ const filtered = loaded.clustered
142
+ ? { merged: loaded.merged, px: loaded.px }
143
+ : filterTranscripts(loaded.merged, loaded.px, hidden, (loaded.kind ?? job.kind) === 'genes' ? hiddenGeneSlots(view) : null);
144
+ let { merged, px } = filtered;
145
+ let selectionBin = loaded.clustered?.bin ?? null;
146
+ let entryGroup = loaded.clustered?.group ?? null;
147
+ let groupNames = loaded.clustered?.names ?? null;
148
+ if (loaded.ladder) {
149
+ const g = groupSelection(merged, view, loaded.ladder, pxPerUnit);
150
+ if (g)
151
+ ({ merged, px, bin: selectionBin, group: entryGroup, names: groupNames } = g);
152
+ }
153
+ const kind = loaded.kind ?? job.kind;
154
+ const colorView = colorViewFor(view, kind, !!loaded.clustered);
155
+ // Each entry's cluster: its marker's group, or the gene-tree group its gene is in.
156
+ const geneCluster = view.transcriptGenes.map((g) => view.transcriptGeneGroups.find((x) => x.genes.includes(g))?.name ?? g);
157
+ const clusterOf = (i) => entryGroup && groupNames ? (groupNames[entryGroup[i]] ?? null) : (geneCluster[merged.gene[i]] ?? null);
158
+ const rgba = await this.transcriptColors(dataset, colorView, merged, kind === 'genes' ? clusterOf : undefined);
159
+ const typeColumn = cellTypeColumnFor(dataset, view);
160
+ const types = typeColumn ? await this.lookup.codes(typeColumn).catch(() => null) : null;
161
+ // Nothing is recorded before the last await: a superseded plan that had already keyed the
162
+ // group would make the newer plan of the same view take the old layer for its own.
163
+ if (ctx.stale())
164
+ return;
165
+ if (ctx.incomplete)
166
+ this.groups.forgetKey('transcripts');
167
+ else
168
+ this.groups.setKey('transcripts', planKey);
169
+ const diam = px.map((d) => d / pxPerUnit);
170
+ const ref = dataset.imageRef;
171
+ const place = { scale: ref?.scale ?? [1, 1], translate: ref?.translate ?? [0, 0] };
172
+ const layer = mode === 'circles'
173
+ ? // A dark rim: a transcript coloured by its cell's type is otherwise the same colour as
174
+ // the cell fill it sits on, and vanishes into it.
175
+ this.drawTranscripts(merged, diam, rgba, view, place, null, 0.18 * median(diam))
176
+ : this.drawTranscriptGlyphs(merged, diam, rgba, view, place, pxPerUnit);
177
+ this.hover.setDrawn({
178
+ kind: loaded.kind ?? job.kind,
179
+ bin: selectionBin
180
+ ? { size: selectionBin, origin: loaded.clustered?.origin ?? [0, 0] }
181
+ : loaded.kind
182
+ ? loaded.bin
183
+ : job.bin,
184
+ merged,
185
+ layer,
186
+ genes: [...view.transcriptGenes],
187
+ ...(entryGroup && groupNames ? { entryGroup, groupNames } : {}),
188
+ ...(loaded.clustered ? { groupGenes: loaded.clustered.genes } : {}),
189
+ }, dataset.micronsPerUnit ?? null);
190
+ this.hover.setTypes(types);
191
+ }
192
+ /**
193
+ * Gene icons: each entry drawn as its gene's napari-js point symbol, in the same one points
194
+ * layer as the circles. With every gene drawn there is one icon for all of them — 18,000
195
+ * shapes would say nothing.
196
+ */
197
+ drawTranscriptGlyphs(merged, diam, rgba, view, place, pxPerUnit) {
198
+ const genes = view.transcriptGenes;
199
+ const glyphFor = (slot) => view.transcriptGlyphs[genes[slot]] ?? defaultGlyphFor(slot);
200
+ const single = view.transcriptAllGenes
201
+ ? (view.transcriptGlyphs[ALL_GENES] ?? 'circle')
202
+ : null;
203
+ const slots = single ? [single] : genes.map((_g, slot) => glyphFor(slot));
204
+ const codes = slots.map((g) => pointSymbolCode(GLYPH_SYMBOLS[g]));
205
+ const sizes = slots.map((g) => GLYPH_SIZE[g] ?? 1);
206
+ const symbols = new Uint8Array(merged.count);
207
+ const size = new Float32Array(merged.count);
208
+ for (let i = 0; i < merged.count; i++) {
209
+ const slot = single ? 0 : merged.gene[i];
210
+ symbols[i] = codes[slot];
211
+ size[i] = diam[i] * sizes[slot];
212
+ }
213
+ // A dark rim, one screen pixel wide, keeps a few large icons readable over the tissue; on
214
+ // many small ones the rims merge into a solid dark sheet that hides every colour, so they
215
+ // are left off.
216
+ const medianPx = median(diam) * pxPerUnit;
217
+ const rim = merged.count > GLYPH_OUTLINE_MAX || medianPx < GLYPH_OUTLINE_MIN_PX ? 0 : 1 / pxPerUnit;
218
+ return this.drawTranscripts(merged, size, rgba, view, place, symbols, rim);
219
+ }
220
+ /**
221
+ * The one transcripts layer: a marker per entry, `size` saying how many transcripts it stands
222
+ * for, drawn as the layer's disc or as each entry's `symbols` code.
223
+ */
224
+ drawTranscripts(merged, size, rgba, view, { scale, translate }, symbols, borderWidth) {
225
+ const positions = new Float32Array(merged.count * 2);
226
+ for (let i = 0; i < merged.count; i++) {
227
+ positions[2 * i] = merged.x[i];
228
+ positions[2 * i + 1] = merged.y[i];
229
+ }
230
+ const layer = this.groups.viewer.addPoints(positions, {
231
+ name: 'transcripts',
232
+ size,
233
+ faceColor: rgba,
234
+ borderColor: RIM_COLOR,
235
+ borderWidth,
236
+ symbols,
237
+ opacity: view.transcriptOpacity,
238
+ scale,
239
+ translate,
240
+ });
241
+ this.groups.replace('transcripts', layer);
242
+ return layer;
243
+ }
244
+ /** Per-entry colours, as packed RGBA. */
245
+ async transcriptColors(dataset, view, t, clusterOf) {
246
+ let rgb;
247
+ let codeOf;
248
+ if (view.transcriptColorBy === 'cluster' && clusterOf) {
249
+ // A cluster named like a group of the cells' grouping takes that group's colour, so a
250
+ // cluster's transcripts and its cells agree; any other cluster takes a palette colour.
251
+ const name = cellTypeColumnFor(dataset, view);
252
+ const codes = name ? await this.lookup.codes(name).catch(() => null) : null;
253
+ const cellColor = new Map();
254
+ if (codes?.meta.kind === 'categorical') {
255
+ const colors = resolveCategoryColors(codes.meta);
256
+ codes.meta.categories.forEach((c, k) => cellColor.set(c, colors[k]));
257
+ }
258
+ const colors = clusterColorMap(view.transcriptGenes, view.transcriptGeneGroups, cellColor, DEFAULT_CATEGORICAL_PALETTE);
259
+ const index = new Map();
260
+ const hex = [];
261
+ const codeFor = (cluster) => {
262
+ let k = index.get(cluster);
263
+ if (k === undefined) {
264
+ k = hex.length;
265
+ index.set(cluster, k);
266
+ hex.push(colors.get(cluster) ?? cellColor.get(cluster) ?? DEFAULT_CATEGORICAL_PALETTE[0]);
267
+ }
268
+ return k;
269
+ };
270
+ const code = new Int32Array(t.count);
271
+ for (let i = 0; i < t.count; i++) {
272
+ const c = clusterOf(i);
273
+ code[i] = c === null ? -1 : codeFor(c);
274
+ }
275
+ rgb = hex.map(parseHex);
276
+ codeOf = (i) => code[i];
277
+ }
278
+ else if (view.transcriptColorBy === 'gene' || view.transcriptColorBy === 'cluster') {
279
+ // All genes: codes are the dataset's gene indices, folded onto the palette.
280
+ const n = view.transcriptAllGenes ? DEFAULT_CATEGORICAL_PALETTE.length : view.transcriptGenes.length;
281
+ rgb = Array.from({ length: n }, (_g, i) => parseHex((!view.transcriptAllGenes && view.transcriptGeneColors[view.transcriptGenes[i]]) ||
282
+ DEFAULT_CATEGORICAL_PALETTE[i % DEFAULT_CATEGORICAL_PALETTE.length]));
283
+ codeOf = view.transcriptAllGenes ? (i) => t.gene[i] % n : (i) => t.gene[i];
284
+ }
285
+ else {
286
+ const name = cellTypeColumnFor(dataset, view);
287
+ const codes = name ? await this.lookup.codes(name) : null;
288
+ rgb = codes?.meta.kind === 'categorical' ? resolveCategoryColors(codes.meta).map(parseHex) : [];
289
+ codeOf = (i) => {
290
+ const o = t.observation[i];
291
+ if (!codes || o === NO_OBSERVATION)
292
+ return -1;
293
+ const c = codes.codes[o];
294
+ return c === NO_CATEGORY ? -1 : c;
295
+ };
296
+ }
297
+ const rgba = new Float32Array(t.count * 4);
298
+ const tuples = rgb.map(([r, g, b]) => [r / 255, g / 255, b / 255, 1]);
299
+ for (let i = 0; i < t.count; i++) {
300
+ const c = codeOf(i);
301
+ rgba.set(c < 0 ? UNASSIGNED_RGBA : tuples[c], i * 4);
302
+ }
303
+ return rgba;
304
+ }
305
+ }
306
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNjcmlwdC1sYXllcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2ltcGxlbWVudGF0aW9ucy9uYXBhcmktanMvc3BhdGlhbC10aWxlcy90cmFuc2NyaXB0LWxheWVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBSTVDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUV2RSxPQUFPLEVBQ0wsV0FBVyxFQUNYLGNBQWMsR0FHZixNQUFNLDZDQUE2QyxDQUFDO0FBQ3JELE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxRQUFRLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUNqSCxPQUFPLEVBQVksaUJBQWlCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNuRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDdkUsT0FBTyxFQUFtQixlQUFlLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUMzRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsZUFBZSxFQUFFLE1BQU0sRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBS2pHLE9BQU8sRUFBaUQsY0FBYyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFbEcsMkZBQTJGO0FBQzNGLE1BQU0saUJBQWlCLEdBQUcsTUFBTSxDQUFDO0FBQ2pDLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxDQUFDO0FBRS9CLGdDQUFnQztBQUNoQyxNQUFNLFNBQVMsR0FBUyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBRWhEOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxhQUFhLEdBQW1EO0lBQzNFLE1BQU0sRUFBRSxNQUFNO0lBQ2QsSUFBSSxFQUFFLE1BQU07SUFDWixRQUFRLEVBQUUsYUFBYTtJQUN2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QUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN2RCxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBwb2ludFN5bWJvbENvZGUgfSBmcm9tICduYXBhcmktanMnO1xuaW1wb3J0IHR5cGUgeyBQb2ludFN5bWJvbCwgUG9pbnRzTGF5ZXIsIFJHQkEgfSBmcm9tICduYXBhcmktanMnO1xuXG5pbXBvcnQgdHlwZSB7IFJnYiB9IGZyb20gJy4uLy4uLy4uL2NvbnRyYWN0cy9jb2xvcm1hcC1sdXQnO1xuaW1wb3J0IHsgQUxMX0dFTkVTIH0gZnJvbSAnLi4vLi4vLi4vY29udHJhY3RzL3BvcnRzL3NwYXRpYWwtZGF0YS5wb3J0JztcbmltcG9ydCB0eXBlIHsgU3BhdGlhbFZpZXdTdGF0ZSB9IGZyb20gJy4uLy4uLy4uL2NvbnRyYWN0cy9kaXNwbGF5LXR5cGVzJztcbmltcG9ydCB7XG4gIE5PX0NBVEVHT1JZLFxuICBOT19PQlNFUlZBVElPTixcbiAgU3BhdGlhbERhdGFzZXQsXG4gIFNwYXRpYWxUcmFuc2NyaXB0VGlsZSxcbn0gZnJvbSAnLi4vLi4vLi4vY29udHJhY3RzL3NwYXRpYWwtZGF0YXNldC5jb250cmFjdCc7XG5pbXBvcnQgeyBERUZBVUxUX0NBVEVHT1JJQ0FMX1BBTEVUVEUsIHBhcnNlSGV4LCByZXNvbHZlQ2F0ZWdvcnlDb2xvcnMgfSBmcm9tICcuLi8uLi8uLi9zcGF0aWFsL3NwYXRpYWwtZW5jb2RpbmcnO1xuaW1wb3J0IHsgRGF0YVJlY3QsIGNlbGxUeXBlQ29sdW1uRm9yIH0gZnJvbSAnLi4vLi4vLi4vc3BhdGlhbC9sb2QnO1xuaW1wb3J0IHsgY2x1c3RlckNvbG9yTWFwIH0gZnJvbSAnLi4vLi4vLi4vc3BhdGlhbC90cmFuc2NyaXB0LWdyb3VwaW5nJztcbmltcG9ydCB7IFRyYW5zY3JpcHRHbHlwaCwgZGVmYXVsdEdseXBoRm9yIH0gZnJvbSAnLi4vLi4vLi4vc3BhdGlhbC9nbHlwaHMnO1xuaW1wb3J0IHsgZmlsdGVyVHJhbnNjcmlwdHMsIGhpZGRlbkdlbmVTbG90cywgbWVkaWFuIH0gZnJvbSAnLi4vLi4vLi4vc3BhdGlhbC9zcGF0aWFsLXRpbGUtbWVyZ2UnO1xuaW1wb3J0IHR5cGUgeyBDYXRlZ29yaWNhbExvb2t1cCB9IGZyb20gJy4vY2F0ZWdvcmljYWwtbG9va3VwJztcbmltcG9ydCB0eXBlIHsgT3JkZXJlZExheWVyR3JvdXBzLCBUaWxlR3JvdXAgfSBmcm9tICcuL2xheWVyLWdyb3Vwcyc7XG5pbXBvcnQgdHlwZSB7IFBsYW5Db250ZXh0IH0gZnJvbSAnLi9wbGFuLWNvbnRleHQnO1xuaW1wb3J0IHR5cGUgeyBUcmFuc2NyaXB0SG92ZXIsIFRyYW5zY3JpcHRLaW5kIH0gZnJvbSAnLi90cmFuc2NyaXB0LWhvdmVyJztcbmltcG9ydCB7IHR5cGUgVHJhbnNjcmlwdEpvYiwgdHlwZSBUcmFuc2NyaXB0Sm9iUGxhbm5lciwgZ3JvdXBTZWxlY3Rpb24gfSBmcm9tICcuL3RyYW5zY3JpcHQtam9icyc7XG5cbi8qKiBJY29ucyBnZXQgYSBkYXJrIHJpbSBvbmx5IHdoaWxlIHRoZXJlIGFyZSBhdCBtb3N0IHRoaXMgbWFueSwgYXQgbGVhc3QgdGhpcyBiaWcgKHB4KS4gKi9cbmNvbnN0IEdMWVBIX09VVExJTkVfTUFYID0gMjBfMDAwO1xuY29uc3QgR0xZUEhfT1VUTElORV9NSU5fUFggPSA4O1xuXG4vKiogVGhlIGRhcmsgcmltIG9mIGEgbWFya2VyLiAqL1xuY29uc3QgUklNX0NPTE9SOiBSR0JBID0gWzAuMDQsIDAuMDQsIDAuMDUsIDAuOV07XG5cbi8qKlxuICogVGhlIG5hcGFyaS1qcyBwb2ludCBzeW1ib2wgZWFjaCB0cmFuc2NyaXB0IGljb24gaXMgZHJhd24gYXMuIEV2ZXJ5IGljb24gaGFzIGEgY291bnRlcnBhcnQgb2ZcbiAqIHRoZSBzYW1lIG91dGxpbmUgKGBjaXJjbGVgIGlzIG5hcGFyaSdzIGBkaXNjYCk7IHNlZSB7QGxpbmsgR0xZUEhfU0laRX0gZm9yIHRoZSBvbmUgd2hvc2Ugc2l6ZVxuICogZGlmZmVycy5cbiAqL1xuZXhwb3J0IGNvbnN0IEdMWVBIX1NZTUJPTFM6IFJlYWRvbmx5PFJlY29yZDxUcmFuc2NyaXB0R2x5cGgsIFBvaW50U3ltYm9sPj4gPSB7XG4gIGNpcmNsZTogJ2Rpc2MnLFxuICBzdGFyOiAnc3RhcicsXG4gIHRyaWFuZ2xlOiAndHJpYW5nbGVfdXAnLFxuICBzcXVhcmU6ICdzcXVhcmUnLFxuICBkaWFtb25kOiAnZGlhbW9uZCcsXG4gIGNyb3NzOiAnY3Jvc3MnLFxuICBoZXhhZ29uOiAnaGV4YWdvbicsXG4gICd0cmlhbmdsZS1kb3duJzogJ3RyaWFuZ2xlX2Rvd24nLFxuICBwZW50YWdvbjogJ3BlbnRhZ29uJyxcbiAgeDogJ3gnLFxufTtcblxuLyoqXG4gKiBNYXJrZXIgZGlhbWV0ZXIgcGVyIGljb24sIGFzIGEgZnJhY3Rpb24gb2YgdGhlIGVudHJ5J3M6IG5hcGFyaSdzIGBzcXVhcmVgIGZpbGxzIHRoZSBtYXJrZXInc1xuICogd2hvbGUgYm94LCB3aGVyZSB0aGUgaWNvbiBpdCByZXBsYWNlcyBoYWQgYSAwLjggaGFsZi1zaWRlLCBhcyBoZWF2eSBhcyB0aGUgb3RoZXIgaWNvbnMuXG4gKi9cbmNvbnN0IEdMWVBIX1NJWkU6IFJlYWRvbmx5PFBhcnRpYWw8UmVjb3JkPFRyYW5zY3JpcHRHbHlwaCwgbnVtYmVyPj4+ID0geyBzcXVhcmU6IDAuOCB9O1xuXG4vKipcbiAqIFdoYXQgYSB0cmFuc2NyaXB0IHBsYW4gZHJhd3MsIGFzIGEga2V5OiBhbiB1bmNoYW5nZWQgb25lIGlzIGEgbm8tb3AuIE1hcmtlciBzaXplcyBmb2xsb3cgdGhlXG4gKiB6b29tLCBzbyB0aGUgem9vbSBpcyBwYXJ0IG9mIGl0OyBhIHBhbiB0aGF0IGtlZXBzIHRoZSBzYW1lIHRpbGVzIG9uIHNjcmVlbiBjaGFuZ2VzIG5vdGhpbmcuXG4gKi9cbmZ1bmN0aW9uIHRyYW5zY3JpcHRQbGFuS2V5KFxuICBkYXRhc2V0OiBTcGF0aWFsRGF0YXNldCxcbiAgdmlldzogU3BhdGlhbFZpZXdTdGF0ZSxcbiAgam9iOiBUcmFuc2NyaXB0Sm9iLFxuICBweFBlclVuaXQ6IG51bWJlcixcbik6IHN0cmluZyB7XG4gIHJldHVybiBbXG4gICAgZGF0YXNldC5pZCxcbiAgICB2aWV3LnRyYW5zY3JpcHRNb2RlLFxuICAgIGpvYi5rZXksXG4gICAgdmlldy50cmFuc2NyaXB0Q29sb3JCeSxcbiAgICBjZWxsVHlwZUNvbHVtbkZvcihkYXRhc2V0LCB2aWV3KSxcbiAgICB2aWV3LnRyYW5zY3JpcHRTY2FsZSxcbiAgICB2aWV3LnRyYW5zY3JpcHRPcGFjaXR5LFxuICAgIEpTT04uc3RyaW5naWZ5KHZpZXcudHJhbnNjcmlwdEdseXBocyksXG4gICAgcHhQZXJVbml0LnRvUHJlY2lzaW9uKDQpLFxuICAgIHZpZXcuaGlkZGVuR3JvdXBzLmpvaW4oJ1xcdTAwMDEnKSxcbiAgICB2aWV3LnRyYW5zY3JpcHRIaWRkZW5HZW5lcy5qb2luKCcsJyksXG4gICAgSlNPTi5zdHJpbmdpZnkodmlldy50cmFuc2NyaXB0R2VuZUNvbG9ycyksXG4gICAgSlNPTi5zdHJpbmdpZnkodmlldy50cmFuc2NyaXB0R2VuZUdyb3VwcyksXG4gIF0uam9pbignfCcpO1xufVxuXG4vKiogVGhlIHZpZXcgdGhlIG1hcmtlcnMgYXJlIGNvbG91cmVkIGJ5LCBmb3Igd2hhdCB3YXMgbG9hZGVkLiAqL1xuZnVuY3Rpb24gY29sb3JWaWV3Rm9yKHZpZXc6IFNwYXRpYWxWaWV3U3RhdGUsIGtpbmQ6IFRyYW5zY3JpcHRLaW5kLCBjbHVzdGVyZWQ6IGJvb2xlYW4pOiBTcGF0aWFsVmlld1N0YXRlIHtcbiAgLy8gQSBiaW4gb2YgdGhlIGFsbC1nZW5lIHB5cmFtaWQgbWl4ZXMgZ2VuZXMgYW5kIGNhcnJpZXMgbm9uZSwgc28gaXQgY2Fubm90IGJlIGNvbG91cmVkXG4gIC8vIGJ5IGdlbmU6IGNvbG91ciBpdCBieSBpdHMgZG9taW5hbnQgY2VsbCdzIHR5cGUgdW50aWwgaW5kaXZpZHVhbCB0cmFuc2NyaXB0cyBzaG93LlxuICBpZiAoa2luZCA9PT0gJ2JpbnMnICYmIHZpZXcudHJhbnNjcmlwdENvbG9yQnkgIT09ICdjZWxsVHlwZScpIHJldHVybiB7IC4uLnZpZXcsIHRyYW5zY3JpcHRDb2xvckJ5OiAnY2VsbFR5cGUnIH07XG4gIC8vIERlbnNpdHktZ3JpZCBtYXJrZXJzIGhhdmUgbm8gY2VsbCB0byB0YWtlIGEgdHlwZSBmcm9tOiB0aGV5IHRha2UgdGhlaXIgY2x1c3RlcidzIGNvbG91ci5cbiAgaWYgKGNsdXN0ZXJlZCAmJiB2aWV3LnRyYW5zY3JpcHRDb2xvckJ5ID09PSAnY2VsbFR5cGUnKSByZXR1cm4geyAuLi52aWV3LCB0cmFuc2NyaXB0Q29sb3JCeTogJ2NsdXN0ZXInIH07XG4gIHJldHVybiB2aWV3O1xufVxuXG4vKiogV2hlcmUgYSBsYXllciBzaXRzIGluIHdvcmxkIHNwYWNlOiB0aGUgZGF0YXNldCdzIGFmZmluZSBvbnRvIGl0cyB0aXNzdWUgaW1hZ2UuICovXG5pbnRlcmZhY2UgUGxhY2VtZW50IHtcbiAgc2NhbGU6IFtudW1iZXIsIG51bWJlcl07XG4gIHRyYW5zbGF0ZTogW251bWJlciwgbnVtYmVyXTtcbn1cblxuY29uc3QgVU5BU1NJR05FRF9SR0JBOiBSR0JBID0gWzAuNjIsIDAuNjIsIDAuNjIsIDAuNTVdO1xuXG4vKipcbiAqIFRoZSB0cmFuc2NyaXB0IG1hcmtlcnMgb2YgdGhlIDJEIHNwYXRpYWwgdmlldzogcnVucyB0aGUgcGxhbm5lcidzIGpvYiwgZHJvcHMgaGlkZGVuIGdyb3Vwc1xuICogYW5kIGdlbmVzLCBncm91cHMgYSBzZWxlY3Rpb24gdW5kZXIgdGhlIG1hcmtlciBidWRnZXQsIGNvbG91cnMgdGhlIGVudHJpZXMgYW5kIGRyYXdzIHRoZW0gYXNcbiAqIG9uZSBwb2ludHMgbGF5ZXI6IHNpemVkIGNpcmNsZXMsIG9yIGdlbmUgaWNvbnMgYXMgcGVyLXBvaW50IHN5bWJvbHMgKHdpdGggYSBkYXJrIHJpbSB3aGlsZVxuICogdGhlcmUgYXJlIGZldyBlbm91Z2gpLlxuICpcbiAqIEhhbmRzIHdoYXQgaXQgZHJldyB0byB0aGUgaG92ZXIgb25lIHdheSAoe0BsaW5rIFRyYW5zY3JpcHRIb3Zlci5zZXREcmF3bn0pLCBhbmQga2VlcHMgdGhlXG4gKiBsb2FkZWQgcGVyLWdlbmUgdHJhbnNjcmlwdHMgdGhlIGluLXZpZXcgZ2VuZSBjb3VudHMgYXJlIHRha2VuIGZyb20uXG4gKi9cbmV4cG9ydCBjbGFzcyBUcmFuc2NyaXB0TGF5ZXJzIHtcbiAgLyoqIFRoZSBsb2FkZWQgcGVyLWdlbmUgdHJhbnNjcmlwdHMgdGhlIGluLXZpZXcgY291bnRzIGFyZSB0YWtlbiBmcm9tLiAqL1xuICBwcml2YXRlIGNvdW50U291cmNlOiB7IG1lcmdlZDogU3BhdGlhbFRyYW5zY3JpcHRUaWxlOyBnZW5lczogc3RyaW5nW10gfSB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgZ3JvdXBzOiBPcmRlcmVkTGF5ZXJHcm91cHM8VGlsZUdyb3VwPixcbiAgICBwcml2YXRlIHJlYWRvbmx5IGpvYnM6IFRyYW5zY3JpcHRKb2JQbGFubmVyLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgbG9va3VwOiBDYXRlZ29yaWNhbExvb2t1cCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGhvdmVyOiBUcmFuc2NyaXB0SG92ZXIsXG4gICkge31cblxuICAvKipcbiAgICogVHJhbnNjcmlwdHMgb2YgZWFjaCBzZWxlY3RlZCBnZW5lIGluc2lkZSBgcmVjdGA6IGVhY2ggZW50cnkgY291bnRzIGZvciB0aGUgdHJhbnNjcmlwdHMgaXRcbiAgICogc3RhbmRzIGZvciAoYW4gYWdncmVnYXRlIGF0IGEgY29hcnNlIGxldmVsIGhvbGRzIHNldmVyYWwpLiBOdWxsIHdpdGhvdXQgcGVyLWdlbmUgZGF0YS5cbiAgICovXG4gIGdlbmVDb3VudHNJbihyZWN0OiBEYXRhUmVjdCk6IFJlY29yZDxzdHJpbmcsIG51bWJlcj4gfCBudWxsIHtcbiAgICBjb25zdCBzcmMgPSB0aGlzLmNvdW50U291cmNlO1xuICAgIGlmICghc3JjKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBvdXQ6IFJlY29yZDxzdHJpbmcsIG51bWJlcj4gPSB7fTtcbiAgICBmb3IgKGNvbnN0IGcgb2Ygc3JjLmdlbmVzKSBvdXRbZ10gPSAwO1xuICAgIGNvbnN0IHsgeCwgeSwgd2VpZ2h0LCBnZW5lIH0gPSBzcmMubWVyZ2VkO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3JjLm1lcmdlZC5jb3VudDsgaSsrKSB7XG4gICAgICBpZiAoeFtpXSA8IHJlY3QueDAgfHwgeFtpXSA+IHJlY3QueDEgfHwgeVtpXSA8IHJlY3QueTAgfHwgeVtpXSA+IHJlY3QueTEpIGNvbnRpbnVlO1xuICAgICAgY29uc3QgbmFtZSA9IHNyYy5nZW5lc1tnZW5lW2ldXTtcbiAgICAgIGlmIChuYW1lICE9PSB1bmRlZmluZWQpIG91dFtuYW1lXSArPSB3ZWlnaHRbaV07XG4gICAgfVxuICAgIHJldHVybiBvdXQ7XG4gIH1cblxuICAvKiogVGhlIHZpZXdlciB3ZW50IGF3YXk6IG5vIGNvdW50cyB1bnRpbCB0aGUgbmV4dCBwbGFuLiAqL1xuICBkZXRhY2hlZCgpOiB2b2lkIHtcbiAgICB0aGlzLmNvdW50U291cmNlID0gbnVsbDtcbiAgfVxuXG4gIC8qKiBEcmF3IHRoZSB2aWV3J3MgdHJhbnNjcmlwdCBtYXJrZXJzIChvciBkcm9wIHRoZW0pOyBhbiB1bmNoYW5nZWQgcGxhbiBrZXkgaXMgYSBuby1vcC4gKi9cbiAgYXN5bmMgcGxhbihcbiAgICBkYXRhc2V0OiBTcGF0aWFsRGF0YXNldCxcbiAgICB2aWV3OiBTcGF0aWFsVmlld1N0YXRlLFxuICAgIHJlY3Q6IERhdGFSZWN0LFxuICAgIHB4UGVyVW5pdDogbnVtYmVyLFxuICAgIGN0eDogUGxhbkNvbnRleHQsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG1vZGUgPSB2aWV3LnRyYW5zY3JpcHRNb2RlO1xuICAgIGNvbnN0IGpvYiA9IHRoaXMuam9icy5qb2JGb3IoZGF0YXNldCwgdmlldywgcmVjdCwgcHhQZXJVbml0KTtcbiAgICBpZiAoIWpvYikge1xuICAgICAgdGhpcy5ncm91cHMuZHJvcCgndHJhbnNjcmlwdHMnKTtcbiAgICAgIHRoaXMuaG92ZXIuY2xlYXIoKTtcbiAgICAgIHRoaXMuY291bnRTb3VyY2UgPSBudWxsO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBwbGFuS2V5ID0gdHJhbnNjcmlwdFBsYW5LZXkoZGF0YXNldCwgdmlldywgam9iLCBweFBlclVuaXQpO1xuICAgIGlmIChwbGFuS2V5ID09PSB0aGlzLmdyb3Vwcy5rZXkoJ3RyYW5zY3JpcHRzJykgJiYgdGhpcy5ncm91cHMuc2hvd24oJ3RyYW5zY3JpcHRzJykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgbG9hZGVkID0gYXdhaXQgY3R4LnRyYWNrKCdUcmFuc2NyaXB0cycsIGpvYi5sb2FkKGN0eCkpO1xuICAgIGlmIChjdHguc3RhbGUoKSkgcmV0dXJuO1xuICAgIC8vIFBlci1nZW5lIGNvdW50cyBpbiB2aWV3IGNvbWUgZnJvbSB3aGF0IHdhcyBsb2FkZWQsIGJlZm9yZSBoaWRkZW4gZ2VuZXMgYXJlIGRyb3BwZWQ6XG4gICAgLy8gYSBoaWRkZW4gZ2VuZSBzdGlsbCBoYXMgdHJhbnNjcmlwdHMgdGhlcmUuIFN1bW1lZCBkZW5zaXR5IGdyaWRzIChubyBwZXItZ2VuZSBsZXZlbHMsXG4gICAgLy8gem9vbWVkIG91dCkgaG9sZCBjbHVzdGVycywgbm90IGdlbmVzOiBubyBwZXItZ2VuZSBjb3VudHMgdGhlcmUsIHJhdGhlciB0aGFuIGEgZ3Vlc3MuXG4gICAgdGhpcy5jb3VudFNvdXJjZSA9XG4gICAgICAobG9hZGVkLmtpbmQgPz8gam9iLmtpbmQpID09PSAnZ2VuZXMnICYmICFsb2FkZWQuY2x1c3RlcmVkXG4gICAgICAgID8geyBtZXJnZWQ6IGxvYWRlZC5tZXJnZWQsIGdlbmVzOiBbLi4udmlldy50cmFuc2NyaXB0R2VuZXNdIH1cbiAgICAgICAgOiBudWxsO1xuICAgIGNvbnN0IGhpZGRlbiA9IGF3YWl0IHRoaXMubG9va3VwLmhpZGRlbkNvZGVzKGRhdGFzZXQsIHZpZXcpO1xuICAgIGlmIChjdHguc3RhbGUoKSkgcmV0dXJuO1xuICAgIC8vIERlbnNpdHktZ3JpZCBtYXJrZXJzIGNhcnJ5IG5vIGNlbGxzIGFuZCB3ZXJlIGJ1aWx0IGZyb20gdGhlIHZpc2libGUgZ2VuZXMgb25seS5cbiAgICBjb25zdCBmaWx0ZXJlZCA9IGxvYWRlZC5jbHVzdGVyZWRcbiAgICAgID8geyBtZXJnZWQ6IGxvYWRlZC5tZXJnZWQsIHB4OiBsb2FkZWQucHggfVxuICAgICAgOiBmaWx0ZXJUcmFuc2NyaXB0cyhcbiAgICAgICAgICBsb2FkZWQubWVyZ2VkLFxuICAgICAgICAgIGxvYWRlZC5weCxcbiAgICAgICAgICBoaWRkZW4sXG4gICAgICAgICAgKGxvYWRlZC5raW5kID8/IGpvYi5raW5kKSA9PT0gJ2dlbmVzJyA/IGhpZGRlbkdlbmVTbG90cyh2aWV3KSA6IG51bGwsXG4gICAgICAgICk7XG4gICAgbGV0IHsgbWVyZ2VkLCBweCB9ID0gZmlsdGVyZWQ7XG4gICAgbGV0IHNlbGVjdGlvbkJpbjogbnVtYmVyIHwgbnVsbCA9IGxvYWRlZC5jbHVzdGVyZWQ/LmJpbiA/PyBudWxsO1xuICAgIGxldCBlbnRyeUdyb3VwOiBJbnQzMkFycmF5IHwgbnVsbCA9IGxvYWRlZC5jbHVzdGVyZWQ/Lmdyb3VwID8/IG51bGw7XG4gICAgbGV0IGdyb3VwTmFtZXM6IHN0cmluZ1tdIHwgbnVsbCA9IGxvYWRlZC5jbHVzdGVyZWQ/Lm5hbWVzID8/IG51bGw7XG4gICAgaWYgKGxvYWRlZC5sYWRkZXIpIHtcbiAgICAgIGNvbnN0IGcgPSBncm91cFNlbGVjdGlvbihtZXJnZWQsIHZpZXcsIGxvYWRlZC5sYWRkZXIsIHB4UGVyVW5pdCk7XG4gICAgICBpZiAoZykgKHsgbWVyZ2VkLCBweCwgYmluOiBzZWxlY3Rpb25CaW4sIGdyb3VwOiBlbnRyeUdyb3VwLCBuYW1lczogZ3JvdXBOYW1lcyB9ID0gZyk7XG4gICAgfVxuICAgIGNvbnN0IGtpbmQgPSBsb2FkZWQua2luZCA/PyBqb2Iua2luZDtcbiAgICBjb25zdCBjb2xvclZpZXcgPSBjb2xvclZpZXdGb3Iodmlldywga2luZCwgISFsb2FkZWQuY2x1c3RlcmVkKTtcbiAgICAvLyBFYWNoIGVudHJ5J3MgY2x1c3RlcjogaXRzIG1hcmtlcidzIGdyb3VwLCBvciB0aGUgZ2VuZS10cmVlIGdyb3VwIGl0cyBnZW5lIGlzIGluLlxuICAgIGNvbnN0IGdlbmVDbHVzdGVyID0gdmlldy50cmFuc2NyaXB0R2VuZXMubWFwKFxuICAgICAgKGcpID0+IHZpZXcudHJhbnNjcmlwdEdlbmVHcm91cHMuZmluZCgoeCkgPT4geC5nZW5lcy5pbmNsdWRlcyhnKSk/Lm5hbWUgPz8gZyxcbiAgICApO1xuICAgIGNvbnN0IGNsdXN0ZXJPZiA9IChpOiBudW1iZXIpOiBzdHJpbmcgfCBudWxsID0+XG4gICAgICBlbnRyeUdyb3VwICYmIGdyb3VwTmFtZXMgPyAoZ3JvdXBOYW1lc1tlbnRyeUdyb3VwW2ldXSA/PyBudWxsKSA6IChnZW5lQ2x1c3RlclttZXJnZWQuZ2VuZVtpXV0gPz8gbnVsbCk7XG4gICAgY29uc3QgcmdiYSA9IGF3YWl0IHRoaXMudHJhbnNjcmlwdENvbG9ycyhkYXRhc2V0LCBjb2xvclZpZXcsIG1lcmdlZCwga2luZCA9PT0gJ2dlbmVzJyA/IGNsdXN0ZXJPZiA6IHVuZGVmaW5lZCk7XG4gICAgY29uc3QgdHlwZUNvbHVtbiA9IGNlbGxUeXBlQ29sdW1uRm9yKGRhdGFzZXQsIHZpZXcpO1xuICAgIGNvbnN0IHR5cGVzID0gdHlwZUNvbHVtbiA/IGF3YWl0IHRoaXMubG9va3VwLmNvZGVzKHR5cGVDb2x1bW4pLmNhdGNoKCgpID0+IG51bGwpIDogbnVsbDtcbiAgICAvLyBOb3RoaW5nIGlzIHJlY29yZGVkIGJlZm9yZSB0aGUgbGFzdCBhd2FpdDogYSBzdXBlcnNlZGVkIHBsYW4gdGhhdCBoYWQgYWxyZWFkeSBrZXllZCB0aGVcbiAgICAvLyBncm91cCB3b3VsZCBtYWtlIHRoZSBuZXdlciBwbGFuIG9mIHRoZSBzYW1lIHZpZXcgdGFrZSB0aGUgb2xkIGxheWVyIGZvciBpdHMgb3duLlxuICAgIGlmIChjdHguc3RhbGUoKSkgcmV0dXJuO1xuXG4gICAgaWYgKGN0eC5pbmNvbXBsZXRlKSB0aGlzLmdyb3Vwcy5mb3JnZXRLZXkoJ3RyYW5zY3JpcHRzJyk7XG4gICAgZWxzZSB0aGlzLmdyb3Vwcy5zZXRLZXkoJ3RyYW5zY3JpcHRzJywgcGxhbktleSk7XG4gICAgY29uc3QgZGlhbSA9IHB4Lm1hcCgoZCkgPT4gZCAvIHB4UGVyVW5pdCk7XG4gICAgY29uc3QgcmVmID0gZGF0YXNldC5pbWFnZVJlZjtcbiAgICBjb25zdCBwbGFjZTogUGxhY2VtZW50ID0geyBzY2FsZTogcmVmPy5zY2FsZSA/PyBbMSwgMV0sIHRyYW5zbGF0ZTogcmVmPy50cmFuc2xhdGUgPz8gWzAsIDBdIH07XG4gICAgY29uc3QgbGF5ZXIgPVxuICAgICAgbW9kZSA9PT0gJ2NpcmNsZXMnXG4gICAgICAgID8gLy8gQSBkYXJrIHJpbTogYSB0cmFuc2NyaXB0IGNvbG91cmVkIGJ5IGl0cyBjZWxsJ3MgdHlwZSBpcyBvdGhlcndpc2UgdGhlIHNhbWUgY29sb3VyIGFzXG4gICAgICAgICAgLy8gdGhlIGNlbGwgZmlsbCBpdCBzaXRzIG9uLCBhbmQgdmFuaXNoZXMgaW50byBpdC5cbiAgICAgICAgICB0aGlzLmRyYXdUcmFuc2NyaXB0cyhtZXJnZWQsIGRpYW0sIHJnYmEsIHZpZXcsIHBsYWNlLCBudWxsLCAwLjE4ICogbWVkaWFuKGRpYW0pKVxuICAgICAgICA6IHRoaXMuZHJhd1RyYW5zY3JpcHRHbHlwaHMobWVyZ2VkLCBkaWFtLCByZ2JhLCB2aWV3LCBwbGFjZSwgcHhQZXJVbml0KTtcbiAgICB0aGlzLmhvdmVyLnNldERyYXduKFxuICAgICAge1xuICAgICAgICBraW5kOiBsb2FkZWQua2luZCA/PyBqb2Iua2luZCxcbiAgICAgICAgYmluOiBzZWxlY3Rpb25CaW5cbiAgICAgICAgICA/IHsgc2l6ZTogc2VsZWN0aW9uQmluLCBvcmlnaW46IGxvYWRlZC5jbHVzdGVyZWQ/Lm9yaWdpbiA/PyBbMCwgMF0gfVxuICAgICAgICAgIDogbG9hZGVkLmtpbmRcbiAgICAgICAgICAgID8gbG9hZGVkLmJpblxuICAgICAgICAgICAgOiBqb2IuYmluLFxuICAgICAgICBtZXJnZWQsXG4gICAgICAgIGxheWVyLFxuICAgICAgICBnZW5lczogWy4uLnZpZXcudHJhbnNjcmlwdEdlbmVzXSxcbiAgICAgICAgLi4uKGVudHJ5R3JvdXAgJiYgZ3JvdXBOYW1lcyA/IHsgZW50cnlHcm91cCwgZ3JvdXBOYW1lcyB9IDoge30pLFxuICAgICAgICAuLi4obG9hZGVkLmNsdXN0ZXJlZCA/IHsgZ3JvdXBHZW5lczogbG9hZGVkLmNsdXN0ZXJlZC5nZW5lcyB9IDoge30pLFxuICAgICAgfSxcbiAgICAgIGRhdGFzZXQubWljcm9uc1BlclVuaXQgPz8gbnVsbCxcbiAgICApO1xuICAgIHRoaXMuaG92ZXIuc2V0VHlwZXModHlwZXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmUgaWNvbnM6IGVhY2ggZW50cnkgZHJhd24gYXMgaXRzIGdlbmUncyBuYXBhcmktanMgcG9pbnQgc3ltYm9sLCBpbiB0aGUgc2FtZSBvbmUgcG9pbnRzXG4gICAqIGxheWVyIGFzIHRoZSBjaXJjbGVzLiBXaXRoIGV2ZXJ5IGdlbmUgZHJhd24gdGhlcmUgaXMgb25lIGljb24gZm9yIGFsbCBvZiB0aGVtIOKAlCAxOCwwMDBcbiAgICogc2hhcGVzIHdvdWxkIHNheSBub3RoaW5nLlxuICAgKi9cbiAgcHJpdmF0ZSBkcmF3VHJhbnNjcmlwdEdseXBocyhcbiAgICBtZXJnZWQ6IFNwYXRpYWxUcmFuc2NyaXB0VGlsZSxcbiAgICBkaWFtOiBGbG9hdDMyQXJyYXksXG4gICAgcmdiYTogRmxvYXQzMkFycmF5LFxuICAgIHZpZXc6IFNwYXRpYWxWaWV3U3RhdGUsXG4gICAgcGxhY2U6IFBsYWNlbWVudCxcbiAgICBweFBlclVuaXQ6IG51bWJlcixcbiAgKTogUG9pbnRzTGF5ZXIge1xuICAgIGNvbnN0IGdlbmVzID0gdmlldy50cmFuc2NyaXB0R2VuZXM7XG4gICAgY29uc3QgZ2x5cGhGb3IgPSAoc2xvdDogbnVtYmVyKTogVHJhbnNjcmlwdEdseXBoID0+XG4gICAgICAodmlldy50cmFuc2NyaXB0R2x5cGhzW2dlbmVzW3Nsb3RdXSBhcyBUcmFuc2NyaXB0R2x5cGggfCB1bmRlZmluZWQpID8/IGRlZmF1bHRHbHlwaEZvcihzbG90KTtcbiAgICBjb25zdCBzaW5nbGUgPSB2aWV3LnRyYW5zY3JpcHRBbGxHZW5lc1xuICAgICAgPyAoKHZpZXcudHJhbnNjcmlwdEdseXBoc1tBTExfR0VORVNdIGFzIFRyYW5zY3JpcHRHbHlwaCB8IHVuZGVmaW5lZCkgPz8gJ2NpcmNsZScpXG4gICAgICA6IG51bGw7XG4gICAgY29uc3Qgc2xvdHMgPSBzaW5nbGUgPyBbc2luZ2xlXSA6IGdlbmVzLm1hcCgoX2csIHNsb3QpID0+IGdseXBoRm9yKHNsb3QpKTtcbiAgICBjb25zdCBjb2RlcyA9IHNsb3RzLm1hcCgoZykgPT4gcG9pbnRTeW1ib2xDb2RlKEdMWVBIX1NZTUJPTFNbZ10pKTtcbiAgICBjb25zdCBzaXplcyA9IHNsb3RzLm1hcCgoZykgPT4gR0xZUEhfU0laRVtnXSA/PyAxKTtcbiAgICBjb25zdCBzeW1ib2xzID0gbmV3IFVpbnQ4QXJyYXkobWVyZ2VkLmNvdW50KTtcbiAgICBjb25zdCBzaXplID0gbmV3IEZsb2F0MzJBcnJheShtZXJnZWQuY291bnQpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWVyZ2VkLmNvdW50OyBpKyspIHtcbiAgICAgIGNvbnN0IHNsb3QgPSBzaW5nbGUgPyAwIDogbWVyZ2VkLmdlbmVbaV07XG4gICAgICBzeW1ib2xzW2ldID0gY29kZXNbc2xvdF07XG4gICAgICBzaXplW2ldID0gZGlhbVtpXSAqIHNpemVzW3Nsb3RdO1xuICAgIH1cbiAgICAvLyBBIGRhcmsgcmltLCBvbmUgc2NyZWVuIHBpeGVsIHdpZGUsIGtlZXBzIGEgZmV3IGxhcmdlIGljb25zIHJlYWRhYmxlIG92ZXIgdGhlIHRpc3N1ZTsgb25cbiAgICAvLyBtYW55IHNtYWxsIG9uZXMgdGhlIHJpbXMgbWVyZ2UgaW50byBhIHNvbGlkIGRhcmsgc2hlZXQgdGhhdCBoaWRlcyBldmVyeSBjb2xvdXIsIHNvIHRoZXlcbiAgICAvLyBhcmUgbGVmdCBvZmYuXG4gICAgY29uc3QgbWVkaWFuUHggPSBtZWRpYW4oZGlhbSkgKiBweFBlclVuaXQ7XG4gICAgY29uc3QgcmltID0gbWVyZ2VkLmNvdW50ID4gR0xZUEhfT1VUTElORV9NQVggfHwgbWVkaWFuUHggPCBHTFlQSF9PVVRMSU5FX01JTl9QWCA/IDAgOiAxIC8gcHhQZXJVbml0O1xuICAgIHJldHVybiB0aGlzLmRyYXdUcmFuc2NyaXB0cyhtZXJnZWQsIHNpemUsIHJnYmEsIHZpZXcsIHBsYWNlLCBzeW1ib2xzLCByaW0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBvbmUgdHJhbnNjcmlwdHMgbGF5ZXI6IGEgbWFya2VyIHBlciBlbnRyeSwgYHNpemVgIHNheWluZyBob3cgbWFueSB0cmFuc2NyaXB0cyBpdCBzdGFuZHNcbiAgICogZm9yLCBkcmF3biBhcyB0aGUgbGF5ZXIncyBkaXNjIG9yIGFzIGVhY2ggZW50cnkncyBgc3ltYm9sc2AgY29kZS5cbiAgICovXG4gIHByaXZhdGUgZHJhd1RyYW5zY3JpcHRzKFxuICAgIG1lcmdlZDogU3BhdGlhbFRyYW5zY3JpcHRUaWxlLFxuICAgIHNpemU6IEZsb2F0MzJBcnJheSxcbiAgICByZ2JhOiBGbG9hdDMyQXJyYXksXG4gICAgdmlldzogU3BhdGlhbFZpZXdTdGF0ZSxcbiAgICB7IHNjYWxlLCB0cmFuc2xhdGUgfTogUGxhY2VtZW50LFxuICAgIHN5bWJvbHM6IFVpbnQ4QXJyYXkgfCBudWxsLFxuICAgIGJvcmRlcldpZHRoOiBudW1iZXIsXG4gICk6IFBvaW50c0xheWVyIHtcbiAgICBjb25zdCBwb3NpdGlvbnMgPSBuZXcgRmxvYXQzMkFycmF5KG1lcmdlZC5jb3VudCAqIDIpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWVyZ2VkLmNvdW50OyBpKyspIHtcbiAgICAgIHBvc2l0aW9uc1syICogaV0gPSBtZXJnZWQueFtpXTtcbiAgICAgIHBvc2l0aW9uc1syICogaSArIDFdID0gbWVyZ2VkLnlbaV07XG4gICAgfVxuICAgIGNvbnN0IGxheWVyID0gdGhpcy5ncm91cHMudmlld2VyIS5hZGRQb2ludHMocG9zaXRpb25zLCB7XG4gICAgICBuYW1lOiAndHJhbnNjcmlwdHMnLFxuICAgICAgc2l6ZSxcbiAgICAgIGZhY2VDb2xvcjogcmdiYSxcbiAgICAgIGJvcmRlckNvbG9yOiBSSU1fQ09MT1IsXG4gICAgICBib3JkZXJXaWR0aCxcbiAgICAgIHN5bWJvbHMsXG4gICAgICBvcGFjaXR5OiB2aWV3LnRyYW5zY3JpcHRPcGFjaXR5LFxuICAgICAgc2NhbGUsXG4gICAgICB0cmFuc2xhdGUsXG4gICAgfSk7XG4gICAgdGhpcy5ncm91cHMucmVwbGFjZSgndHJhbnNjcmlwdHMnLCBsYXllcik7XG4gICAgcmV0dXJuIGxheWVyO1xuICB9XG5cbiAgLyoqIFBlci1lbnRyeSBjb2xvdXJzLCBhcyBwYWNrZWQgUkdCQS4gKi9cbiAgcHJpdmF0ZSBhc3luYyB0cmFuc2NyaXB0Q29sb3JzKFxuICAgIGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0LFxuICAgIHZpZXc6IFNwYXRpYWxWaWV3U3RhdGUsXG4gICAgdDogU3BhdGlhbFRyYW5zY3JpcHRUaWxlLFxuICAgIGNsdXN0ZXJPZj86IChpOiBudW1iZXIpID0+IHN0cmluZyB8IG51bGwsXG4gICk6IFByb21pc2U8RmxvYXQzMkFycmF5PiB7XG4gICAgbGV0IHJnYjogUmdiW107XG4gICAgbGV0IGNvZGVPZjogKGk6IG51bWJlcikgPT4gbnVtYmVyO1xuICAgIGlmICh2aWV3LnRyYW5zY3JpcHRDb2xvckJ5ID09PSAnY2x1c3RlcicgJiYgY2x1c3Rlck9mKSB7XG4gICAgICAvLyBBIGNsdXN0ZXIgbmFtZWQgbGlrZSBhIGdyb3VwIG9mIHRoZSBjZWxscycgZ3JvdXBpbmcgdGFrZXMgdGhhdCBncm91cCdzIGNvbG91ciwgc28gYVxuICAgICAgLy8gY2x1c3RlcidzIHRyYW5zY3JpcHRzIGFuZCBpdHMgY2VsbHMgYWdyZWU7IGFueSBvdGhlciBjbHVzdGVyIHRha2VzIGEgcGFsZXR0ZSBjb2xvdXIuXG4gICAgICBjb25zdCBuYW1lID0gY2VsbFR5cGVDb2x1bW5Gb3IoZGF0YXNldCwgdmlldyk7XG4gICAgICBjb25zdCBjb2RlcyA9IG5hbWUgPyBhd2FpdCB0aGlzLmxvb2t1cC5jb2RlcyhuYW1lKS5jYXRjaCgoKSA9PiBudWxsKSA6IG51bGw7XG4gICAgICBjb25zdCBjZWxsQ29sb3IgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xuICAgICAgaWYgKGNvZGVzPy5tZXRhLmtpbmQgPT09ICdjYXRlZ29yaWNhbCcpIHtcbiAgICAgICAgY29uc3QgY29sb3JzID0gcmVzb2x2ZUNhdGVnb3J5Q29sb3JzKGNvZGVzLm1ldGEpO1xuICAgICAgICBjb2Rlcy5tZXRhLmNhdGVnb3JpZXMuZm9yRWFjaCgoYywgaykgPT4gY2VsbENvbG9yLnNldChjLCBjb2xvcnNba10pKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGNvbG9ycyA9IGNsdXN0ZXJDb2xvck1hcChcbiAgICAgICAgdmlldy50cmFuc2NyaXB0R2VuZXMsXG4gICAgICAgIHZpZXcudHJhbnNjcmlwdEdlbmVHcm91cHMsXG4gICAgICAgIGNlbGxDb2xvcixcbiAgICAgICAgREVGQVVMVF9DQVRFR09SSUNBTF9QQUxFVFRFLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGluZGV4ID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgICAgIGNvbnN0IGhleDogc3RyaW5nW10gPSBbXTtcbiAgICAgIGNvbnN0IGNvZGVGb3IgPSAoY2x1c3Rlcjogc3RyaW5nKSA9PiB7XG4gICAgICAgIGxldCBrID0gaW5kZXguZ2V0KGNsdXN0ZXIpO1xuICAgICAgICBpZiAoayA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgayA9IGhleC5sZW5ndGg7XG4gICAgICAgICAgaW5kZXguc2V0KGNsdXN0ZXIsIGspO1xuICAgICAgICAgIGhleC5wdXNoKGNvbG9ycy5nZXQoY2x1c3RlcikgPz8gY2VsbENvbG9yLmdldChjbHVzdGVyKSA/PyBERUZBVUxUX0NBVEVHT1JJQ0FMX1BBTEVUVEVbMF0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBrO1xuICAgICAgfTtcbiAgICAgIGNvbnN0IGNvZGUgPSBuZXcgSW50MzJBcnJheSh0LmNvdW50KTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdC5jb3VudDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGMgPSBjbHVzdGVyT2YoaSk7XG4gICAgICAgIGNvZGVbaV0gPSBjID09PSBudWxsID8gLTEgOiBjb2RlRm9yKGMpO1xuICAgICAgfVxuICAgICAgcmdiID0gaGV4Lm1hcChwYXJzZUhleCk7XG4gICAgICBjb2RlT2YgPSAoaSkgPT4gY29kZVtpXTtcbiAgICB9IGVsc2UgaWYgKHZpZXcudHJhbnNjcmlwdENvbG9yQnkgPT09ICdnZW5lJyB8fCB2aWV3LnRyYW5zY3JpcHRDb2xvckJ5ID09PSAnY2x1c3RlcicpIHtcbiAgICAgIC8vIEFsbCBnZW5lczogY29kZXMgYXJlIHRoZSBkYXRhc2V0J3MgZ2VuZSBpbmRpY2VzLCBmb2xkZWQgb250byB0aGUgcGFsZXR0ZS5cbiAgICAgIGNvbnN0IG4gPSB2aWV3LnRyYW5zY3JpcHRBbGxHZW5lcyA/IERFRkFVTFRfQ0FURUdPUklDQUxfUEFMRVRURS5sZW5ndGggOiB2aWV3LnRyYW5zY3JpcHRHZW5lcy5sZW5ndGg7XG4gICAgICByZ2IgPSBBcnJheS5mcm9tKHsgbGVuZ3RoOiBuIH0sIChfZywgaSkgPT5cbiAgICAgICAgcGFyc2VIZXgoXG4gICAgICAgICAgKCF2aWV3LnRyYW5zY3JpcHRBbGxHZW5lcyAmJiB2aWV3LnRyYW5zY3JpcHRHZW5lQ29sb3JzW3ZpZXcudHJhbnNjcmlwdEdlbmVzW2ldXSkgfHxcbiAgICAgICAgICAgIERFRkFVTFRfQ0FURUdPUklDQUxfUEFMRVRURVtpICUgREVGQVVMVF9DQVRFR09SSUNBTF9QQUxFVFRFLmxlbmd0aF0sXG4gICAgICAgICksXG4gICAgICApO1xuICAgICAgY29kZU9mID0gdmlldy50cmFuc2NyaXB0QWxsR2VuZXMgPyAoaSkgPT4gdC5nZW5lW2ldICUgbiA6IChpKSA9PiB0LmdlbmVbaV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IG5hbWUgPSBjZWxsVHlwZUNvbHVtbkZvcihkYXRhc2V0LCB2aWV3KTtcbiAgICAgIGNvbnN0IGNvZGVzID0gbmFtZSA/IGF3YWl0IHRoaXMubG9va3VwLmNvZGVzKG5hbWUpIDogbnVsbDtcbiAgICAgIHJnYiA9IGNvZGVzPy5tZXRhLmtpbmQgPT09ICdjYXRlZ29yaWNhbCcgPyByZXNvbHZlQ2F0ZWdvcnlDb2xvcnMoY29kZXMubWV0YSkubWFwKHBhcnNlSGV4KSA6IFtdO1xuICAgICAgY29kZU9mID0gKGkpID0+IHtcbiAgICAgICAgY29uc3QgbyA9IHQub2JzZXJ2YXRpb25baV07XG4gICAgICAgIGlmICghY29kZXMgfHwgbyA9PT0gTk9fT0JTRVJWQVRJT04pIHJldHVybiAtMTtcbiAgICAgICAgY29uc3QgYyA9IGNvZGVzLmNvZGVzW29dO1xuICAgICAgICByZXR1cm4gYyA9PT0gTk9fQ0FURUdPUlkgPyAtMSA6IGM7XG4gICAgICB9O1xuICAgIH1cbiAgICBjb25zdCByZ2JhID0gbmV3IEZsb2F0MzJBcnJheSh0LmNvdW50ICogNCk7XG4gICAgY29uc3QgdHVwbGVzOiBSR0JBW10gPSByZ2IubWFwKChbciwgZywgYl0pID0+IFtyIC8gMjU1LCBnIC8gMjU1LCBiIC8gMjU1LCAxXSk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0LmNvdW50OyBpKyspIHtcbiAgICAgIGNvbnN0IGMgPSBjb2RlT2YoaSk7XG4gICAgICByZ2JhLnNldChjIDwgMCA/IFVOQVNTSUdORURfUkdCQSA6IHR1cGxlc1tjXSwgaSAqIDQpO1xuICAgIH1cbiAgICByZXR1cm4gcmdiYTtcbiAgfVxufVxuIl19