@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,163 @@
1
+ import { ChangeDetectionStrategy, Component, ElementRef, EventEmitter, Input, Output, } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { FormsModule } from '@angular/forms';
4
+ import { InputTextModule } from 'primeng/inputtext';
5
+ import { ButtonModule } from 'primeng/button';
6
+ import { TooltipModule } from 'primeng/tooltip';
7
+ import { presetKey } from '../../store/class-color.util';
8
+ import { HexColorPickerComponent } from '../../hex-color-picker/hex-color-picker.component';
9
+ import { scrollToPicked } from '../class-tree/class-tree.component';
10
+ import * as i0 from "@angular/core";
11
+ import * as i1 from "@angular/common";
12
+ import * as i2 from "@angular/forms";
13
+ import * as i3 from "primeng/button";
14
+ import * as i4 from "primeng/inputtext";
15
+ import * as i5 from "primeng/tooltip";
16
+ /**
17
+ * The Region Editor's docked "Classes" panel (jit-ui#70): every annotation
18
+ * class with its colour swatch and region count. A row click picks the active
19
+ * class (and re-classifies a selection), the swatch recolours the class, the
20
+ * trash removes it, Manage opens the full editor; the search box filters the
21
+ * rows by name; the eye hides a class's regions. For a class hierarchy the editor projects a class tree in,
22
+ * shown in place of the list while {@link treeView} is on. Presentational: the
23
+ * editor applies every action.
24
+ */
25
+ export class ClassesPanelComponent {
26
+ constructor(el) {
27
+ this.el = el;
28
+ /** The classes in display order. */
29
+ this.classes = [];
30
+ /** Region count per class, keyed by {@link presetKey} under `matchMode`. */
31
+ this.counts = new Map();
32
+ /** How labels are matched to classes (keys {@link counts}). */
33
+ this.matchMode = 'exact';
34
+ /** The active class (highlighted), or null. */
35
+ this.activeClass = null;
36
+ /** The class picked last (in the class tree, or a surface in 3D): highlighted, scrolled into view. */
37
+ this.picked = null;
38
+ /** Classes with a selected region (marked). */
39
+ this.marked = new Set();
40
+ /** Number of selected regions (changes what a row click does). */
41
+ this.selectedCount = 0;
42
+ /** The class regions revert to; it can't be removed while in use. */
43
+ this.defaultClassName = 'Region';
44
+ /** Whether a volume view is on screen: each class can then be shown in 3D. */
45
+ this.volume = false;
46
+ /** The classes shown in 3D. */
47
+ this.shown3d = new Set();
48
+ /** The classes hidden from view. */
49
+ this.hidden = new Set();
50
+ /** A class's eye (its name): hide it, or show it again. */
51
+ this.toggleHidden = new EventEmitter();
52
+ /** A class's 3D toggle (its name). */
53
+ this.toggle3d = new EventEmitter();
54
+ /** Whether the projected class tree is shown instead of the list; null: there is no tree. */
55
+ this.treeView = null;
56
+ /** The list / tree switch. */
57
+ this.treeViewChange = new EventEmitter();
58
+ /** A row was clicked: make the class active / apply it to the selection. */
59
+ this.pick = new EventEmitter();
60
+ /** A class's swatch picked a new colour. */
61
+ this.recolor = new EventEmitter();
62
+ /** A class's trash button (its name). */
63
+ this.remove = new EventEmitter();
64
+ /** Manage clicked. */
65
+ this.manage = new EventEmitter();
66
+ /** trackBy for the class rows so re-sorting doesn't re-create the pickers. */
67
+ this.trackByName = (_, c) => c.name;
68
+ /** Every class's row, rebuilt when an input changes rather than per check. */
69
+ this.rows = [];
70
+ /** The rows matching {@link query}. */
71
+ this.shownRows = [];
72
+ /** The search box's text. */
73
+ this.query = '';
74
+ }
75
+ ngOnChanges(changes = {}) {
76
+ this.rows = this.classes.map((c) => ({
77
+ name: c.name,
78
+ color: c.color,
79
+ count: this.count(c.name),
80
+ canRemove: this.canRemove(c.name),
81
+ rowTooltip: this.rowTooltip(c.name),
82
+ removeTooltip: this.removeTooltip(c.name),
83
+ }));
84
+ this.filter();
85
+ if (changes['picked'] && this.picked)
86
+ setTimeout(() => scrollToPicked(this.el.nativeElement, '.class-row.picked'));
87
+ }
88
+ onQuery(value) {
89
+ this.query = value;
90
+ this.filter();
91
+ }
92
+ /** Enter in the search box picks the first match. */
93
+ pickFirstMatch() {
94
+ if (this.query.trim() && this.shownRows.length)
95
+ this.pick.emit(this.shownRows[0].name);
96
+ }
97
+ filter() {
98
+ const q = this.query.trim().toLowerCase();
99
+ this.shownRows = q ? this.rows.filter((r) => r.name.toLowerCase().includes(q)) : this.rows;
100
+ }
101
+ count(name) {
102
+ return this.counts.get(presetKey({ matchMode: this.matchMode }, name)) ?? 0;
103
+ }
104
+ canRemove(name) {
105
+ return !(name === this.defaultClassName && this.count(name) > 0);
106
+ }
107
+ rowTooltip(name) {
108
+ return this.selectedCount
109
+ ? `Apply “${name}” to the selected region(s)`
110
+ : `Set “${name}” active — new regions use it`;
111
+ }
112
+ removeTooltip(name) {
113
+ const inUse = this.count(name) > 0;
114
+ if (name === this.defaultClassName && inUse)
115
+ return 'The default class cannot be removed while in use';
116
+ return inUse ? `Remove class — its regions revert to ${this.defaultClassName}` : 'Remove class';
117
+ }
118
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: ClassesPanelComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
119
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: ClassesPanelComponent, isStandalone: true, selector: "region-classes-panel", inputs: { classes: "classes", counts: "counts", matchMode: "matchMode", activeClass: "activeClass", picked: "picked", marked: "marked", selectedCount: "selectedCount", defaultClassName: "defaultClassName", volume: "volume", shown3d: "shown3d", hidden: "hidden", treeView: "treeView" }, outputs: { toggleHidden: "toggleHidden", toggle3d: "toggle3d", treeViewChange: "treeViewChange", pick: "pick", recolor: "recolor", remove: "remove", manage: "manage" }, usesOnChanges: true, ngImport: i0, template: "<!-- Docked \"Classes\" panel (jit-ui#70): the always-visible list of annotation\n classes above the regions table. Click a row to make it the active class\n (new regions inherit it; with rows selected it re-classifies them); recolour\n via the swatch; the badge shows how many regions use the class. \"Manage\"\n opens the full editor (fallback palette, auto-add, matching, import/export).\n A region set with a class hierarchy (an atlas ontology) can show its classes\n as a tree instead (projected in by the editor); the header switches views. -->\n<div class=\"classes-panel\">\n <div class=\"classes-panel-header\">\n <span class=\"classes-panel-title\">Classes</span>\n <button\n *ngIf=\"treeView !== null\"\n pButton\n type=\"button\"\n [icon]=\"treeView ? 'pi pi-list' : 'pi pi-sitemap'\"\n class=\"p-button-sm p-button-text\"\n [pTooltip]=\"treeView ? 'Show the classes as a list' : 'Show the classes as a tree'\"\n tooltipPosition=\"bottom\"\n [attr.aria-label]=\"treeView ? 'Show the classes as a list' : 'Show the classes as a tree'\"\n (click)=\"treeViewChange.emit(!treeView)\"\n ></button>\n <button\n pButton\n type=\"button\"\n icon=\"pi pi-cog\"\n label=\"Manage\"\n class=\"p-button-sm p-button-text\"\n pTooltip=\"Manage classes \u2014 add / remove, palette, matching, import/export\"\n tooltipPosition=\"bottom\"\n (click)=\"manage.emit()\"\n ></button>\n </div>\n <ng-container *ngIf=\"treeView; else list\"><ng-content></ng-content></ng-container>\n <ng-template #list>\n <input\n *ngIf=\"classes.length\"\n type=\"text\"\n pInputText\n class=\"p-inputtext-sm classes-search\"\n placeholder=\"Search by name\"\n aria-label=\"Search the classes\"\n [ngModel]=\"query\"\n (ngModelChange)=\"onQuery($event)\"\n (keydown.enter)=\"pickFirstMatch()\"\n />\n <div class=\"classes-panel-body\">\n <div\n *ngFor=\"let c of shownRows; trackBy: trackByName\"\n class=\"class-row\"\n [class.active]=\"activeClass === c.name\"\n [class.picked]=\"picked === c.name\"\n [class.marked]=\"marked.has(c.name)\"\n [class.hidden-class]=\"hidden.has(c.name)\"\n (click)=\"pick.emit(c.name)\"\n [pTooltip]=\"c.rowTooltip\"\n tooltipPosition=\"bottom\"\n >\n <i\n class=\"pi row-eye\"\n [ngClass]=\"hidden.has(c.name) ? 'pi-eye-slash' : 'pi-eye'\"\n role=\"button\"\n [attr.aria-pressed]=\"!hidden.has(c.name)\"\n [attr.aria-label]=\"(hidden.has(c.name) ? 'Show ' : 'Hide ') + c.name\"\n [pTooltip]=\"hidden.has(c.name) ? 'Show this class' : 'Hide this class'\"\n tooltipPosition=\"bottom\"\n (click)=\"$event.stopPropagation(); toggleHidden.emit(c.name)\"\n ></i>\n <span class=\"row-swatch\" (click)=\"$event.stopPropagation()\">\n <hex-color-picker [color]=\"c.color\" (colorChange)=\"recolor.emit({ name: c.name, color: $event })\">\n </hex-color-picker>\n </span>\n <span class=\"row-name\">{{ c.name }}</span>\n <span class=\"row-count\" [class.zero]=\"c.count === 0\">{{ c.count }}</span>\n <i\n *ngIf=\"volume\"\n class=\"pi pi-box row-3d\"\n [class.on]=\"shown3d.has(c.name)\"\n role=\"button\"\n [attr.aria-pressed]=\"shown3d.has(c.name)\"\n [attr.aria-label]=\"'Show ' + c.name + ' in 3D'\"\n pTooltip=\"Show in the volume, in 3D\"\n tooltipPosition=\"bottom\"\n (click)=\"$event.stopPropagation(); toggle3d.emit(c.name)\"\n ></i>\n <button\n pButton\n type=\"button\"\n icon=\"pi pi-trash\"\n class=\"p-button-sm p-button-text p-button-warning row-del\"\n [disabled]=\"!c.canRemove\"\n [pTooltip]=\"c.removeTooltip\"\n tooltipPosition=\"bottom\"\n [attr.aria-label]=\"'Remove class ' + c.name\"\n (click)=\"$event.stopPropagation(); remove.emit(c.name)\"\n ></button>\n </div>\n <div *ngIf=\"!classes.length\" class=\"classes-empty\">No classes yet \u2014 add one from Manage.</div>\n <div *ngIf=\"classes.length && !shownRows.length\" class=\"classes-empty\">No class matches.</div>\n </div>\n </ng-template>\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:block;flex:0 0 auto}.classes-panel{display:flex;flex-direction:column;flex:0 0 auto;border-bottom:1px solid var(--surface-border)}.classes-panel-header{display:flex;align-items:center;gap:.35rem;padding:.35rem .5rem;border-bottom:1px solid var(--surface-border)}.classes-panel-title{font-size:.75rem;font-weight:600;letter-spacing:.03em;text-transform:uppercase;color:var(--text-color-secondary);margin-right:auto}.classes-search{margin:.25rem .5rem}.classes-panel-body{height:7rem;min-height:2.5rem;max-height:60vh;overflow-x:hidden;overflow-y:auto;resize:vertical}::ng-deep region-classes-panel .classes-panel-body .hex-picker-swatch{width:1.25rem;height:1.25rem;border-width:1px}.class-row{display:flex;align-items:center;gap:.5rem;padding:.1rem .5rem;cursor:pointer;border-left:3px solid transparent}.class-row:hover{background:var(--surface-hover, rgba(0, 0, 0, .04))}.class-row.picked{background:var(--highlight-bg, rgba(51, 153, 255, .12))}.class-row.marked{box-shadow:inset 3px 0 0 var(--primary-color)}.class-row.active{background:var(--highlight-bg, rgba(51, 153, 255, .12));border-left-color:var(--primary-color)}.class-row .row-swatch{flex:0 0 auto;display:inline-flex}.class-row .row-name{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.85rem}.class-row.active .row-name{color:var(--primary-color);font-weight:600}.class-row .row-count{flex:0 0 auto;min-width:1.5rem;text-align:center;font-size:.72rem;font-variant-numeric:tabular-nums;color:var(--text-color-secondary);background:var(--surface-200, rgba(0, 0, 0, .06));border-radius:10px;padding:0 .4rem}.class-row .row-count.zero{opacity:.5}.class-row .row-del{flex:0 0 auto}.classes-empty{font-size:.8rem;color:var(--text-color-secondary);padding:.5rem}::ng-deep region-classes-panel .classes-panel-body .class-row .p-button.p-button-icon-only{width:1.75rem;height:1.75rem;padding:0}.class-row .row-3d{flex:0 0 auto;font-size:.8rem;opacity:.35;cursor:pointer}.class-row .row-3d:hover{opacity:.8}.class-row .row-3d.on{opacity:1;color:var(--primary-color)}.class-row .row-eye{flex:0 0 auto;font-size:.8rem;opacity:.4;cursor:pointer}.class-row .row-eye:hover{opacity:.9}.class-row.hidden-class .row-eye{opacity:1}.class-row.hidden-class .row-swatch,.class-row.hidden-class .row-name,.class-row.hidden-class .row-count{opacity:.45}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i3.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i4.InputText, selector: "[pInputText]", inputs: ["variant"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: HexColorPickerComponent, selector: "hex-color-picker", inputs: ["color"], outputs: ["colorChange", "colorInput"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
120
+ }
121
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: ClassesPanelComponent, decorators: [{
122
+ type: Component,
123
+ args: [{ selector: 'region-classes-panel', standalone: true, imports: [CommonModule, FormsModule, ButtonModule, InputTextModule, TooltipModule, HexColorPickerComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Docked \"Classes\" panel (jit-ui#70): the always-visible list of annotation\n classes above the regions table. Click a row to make it the active class\n (new regions inherit it; with rows selected it re-classifies them); recolour\n via the swatch; the badge shows how many regions use the class. \"Manage\"\n opens the full editor (fallback palette, auto-add, matching, import/export).\n A region set with a class hierarchy (an atlas ontology) can show its classes\n as a tree instead (projected in by the editor); the header switches views. -->\n<div class=\"classes-panel\">\n <div class=\"classes-panel-header\">\n <span class=\"classes-panel-title\">Classes</span>\n <button\n *ngIf=\"treeView !== null\"\n pButton\n type=\"button\"\n [icon]=\"treeView ? 'pi pi-list' : 'pi pi-sitemap'\"\n class=\"p-button-sm p-button-text\"\n [pTooltip]=\"treeView ? 'Show the classes as a list' : 'Show the classes as a tree'\"\n tooltipPosition=\"bottom\"\n [attr.aria-label]=\"treeView ? 'Show the classes as a list' : 'Show the classes as a tree'\"\n (click)=\"treeViewChange.emit(!treeView)\"\n ></button>\n <button\n pButton\n type=\"button\"\n icon=\"pi pi-cog\"\n label=\"Manage\"\n class=\"p-button-sm p-button-text\"\n pTooltip=\"Manage classes \u2014 add / remove, palette, matching, import/export\"\n tooltipPosition=\"bottom\"\n (click)=\"manage.emit()\"\n ></button>\n </div>\n <ng-container *ngIf=\"treeView; else list\"><ng-content></ng-content></ng-container>\n <ng-template #list>\n <input\n *ngIf=\"classes.length\"\n type=\"text\"\n pInputText\n class=\"p-inputtext-sm classes-search\"\n placeholder=\"Search by name\"\n aria-label=\"Search the classes\"\n [ngModel]=\"query\"\n (ngModelChange)=\"onQuery($event)\"\n (keydown.enter)=\"pickFirstMatch()\"\n />\n <div class=\"classes-panel-body\">\n <div\n *ngFor=\"let c of shownRows; trackBy: trackByName\"\n class=\"class-row\"\n [class.active]=\"activeClass === c.name\"\n [class.picked]=\"picked === c.name\"\n [class.marked]=\"marked.has(c.name)\"\n [class.hidden-class]=\"hidden.has(c.name)\"\n (click)=\"pick.emit(c.name)\"\n [pTooltip]=\"c.rowTooltip\"\n tooltipPosition=\"bottom\"\n >\n <i\n class=\"pi row-eye\"\n [ngClass]=\"hidden.has(c.name) ? 'pi-eye-slash' : 'pi-eye'\"\n role=\"button\"\n [attr.aria-pressed]=\"!hidden.has(c.name)\"\n [attr.aria-label]=\"(hidden.has(c.name) ? 'Show ' : 'Hide ') + c.name\"\n [pTooltip]=\"hidden.has(c.name) ? 'Show this class' : 'Hide this class'\"\n tooltipPosition=\"bottom\"\n (click)=\"$event.stopPropagation(); toggleHidden.emit(c.name)\"\n ></i>\n <span class=\"row-swatch\" (click)=\"$event.stopPropagation()\">\n <hex-color-picker [color]=\"c.color\" (colorChange)=\"recolor.emit({ name: c.name, color: $event })\">\n </hex-color-picker>\n </span>\n <span class=\"row-name\">{{ c.name }}</span>\n <span class=\"row-count\" [class.zero]=\"c.count === 0\">{{ c.count }}</span>\n <i\n *ngIf=\"volume\"\n class=\"pi pi-box row-3d\"\n [class.on]=\"shown3d.has(c.name)\"\n role=\"button\"\n [attr.aria-pressed]=\"shown3d.has(c.name)\"\n [attr.aria-label]=\"'Show ' + c.name + ' in 3D'\"\n pTooltip=\"Show in the volume, in 3D\"\n tooltipPosition=\"bottom\"\n (click)=\"$event.stopPropagation(); toggle3d.emit(c.name)\"\n ></i>\n <button\n pButton\n type=\"button\"\n icon=\"pi pi-trash\"\n class=\"p-button-sm p-button-text p-button-warning row-del\"\n [disabled]=\"!c.canRemove\"\n [pTooltip]=\"c.removeTooltip\"\n tooltipPosition=\"bottom\"\n [attr.aria-label]=\"'Remove class ' + c.name\"\n (click)=\"$event.stopPropagation(); remove.emit(c.name)\"\n ></button>\n </div>\n <div *ngIf=\"!classes.length\" class=\"classes-empty\">No classes yet \u2014 add one from Manage.</div>\n <div *ngIf=\"classes.length && !shownRows.length\" class=\"classes-empty\">No class matches.</div>\n </div>\n </ng-template>\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:block;flex:0 0 auto}.classes-panel{display:flex;flex-direction:column;flex:0 0 auto;border-bottom:1px solid var(--surface-border)}.classes-panel-header{display:flex;align-items:center;gap:.35rem;padding:.35rem .5rem;border-bottom:1px solid var(--surface-border)}.classes-panel-title{font-size:.75rem;font-weight:600;letter-spacing:.03em;text-transform:uppercase;color:var(--text-color-secondary);margin-right:auto}.classes-search{margin:.25rem .5rem}.classes-panel-body{height:7rem;min-height:2.5rem;max-height:60vh;overflow-x:hidden;overflow-y:auto;resize:vertical}::ng-deep region-classes-panel .classes-panel-body .hex-picker-swatch{width:1.25rem;height:1.25rem;border-width:1px}.class-row{display:flex;align-items:center;gap:.5rem;padding:.1rem .5rem;cursor:pointer;border-left:3px solid transparent}.class-row:hover{background:var(--surface-hover, rgba(0, 0, 0, .04))}.class-row.picked{background:var(--highlight-bg, rgba(51, 153, 255, .12))}.class-row.marked{box-shadow:inset 3px 0 0 var(--primary-color)}.class-row.active{background:var(--highlight-bg, rgba(51, 153, 255, .12));border-left-color:var(--primary-color)}.class-row .row-swatch{flex:0 0 auto;display:inline-flex}.class-row .row-name{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.85rem}.class-row.active .row-name{color:var(--primary-color);font-weight:600}.class-row .row-count{flex:0 0 auto;min-width:1.5rem;text-align:center;font-size:.72rem;font-variant-numeric:tabular-nums;color:var(--text-color-secondary);background:var(--surface-200, rgba(0, 0, 0, .06));border-radius:10px;padding:0 .4rem}.class-row .row-count.zero{opacity:.5}.class-row .row-del{flex:0 0 auto}.classes-empty{font-size:.8rem;color:var(--text-color-secondary);padding:.5rem}::ng-deep region-classes-panel .classes-panel-body .class-row .p-button.p-button-icon-only{width:1.75rem;height:1.75rem;padding:0}.class-row .row-3d{flex:0 0 auto;font-size:.8rem;opacity:.35;cursor:pointer}.class-row .row-3d:hover{opacity:.8}.class-row .row-3d.on{opacity:1;color:var(--primary-color)}.class-row .row-eye{flex:0 0 auto;font-size:.8rem;opacity:.4;cursor:pointer}.class-row .row-eye:hover{opacity:.9}.class-row.hidden-class .row-eye{opacity:1}.class-row.hidden-class .row-swatch,.class-row.hidden-class .row-name,.class-row.hidden-class .row-count{opacity:.45}\n"] }]
124
+ }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { classes: [{
125
+ type: Input
126
+ }], counts: [{
127
+ type: Input
128
+ }], matchMode: [{
129
+ type: Input
130
+ }], activeClass: [{
131
+ type: Input
132
+ }], picked: [{
133
+ type: Input
134
+ }], marked: [{
135
+ type: Input
136
+ }], selectedCount: [{
137
+ type: Input
138
+ }], defaultClassName: [{
139
+ type: Input
140
+ }], volume: [{
141
+ type: Input
142
+ }], shown3d: [{
143
+ type: Input
144
+ }], hidden: [{
145
+ type: Input
146
+ }], toggleHidden: [{
147
+ type: Output
148
+ }], toggle3d: [{
149
+ type: Output
150
+ }], treeView: [{
151
+ type: Input
152
+ }], treeViewChange: [{
153
+ type: Output
154
+ }], pick: [{
155
+ type: Output
156
+ }], recolor: [{
157
+ type: Output
158
+ }], remove: [{
159
+ type: Output
160
+ }], manage: [{
161
+ type: Output
162
+ }] } });
163
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy1wYW5lbC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL3JlZ2lvbi1lZGl0b3IvY2xhc3Nlcy1wYW5lbC9jbGFzc2VzLXBhbmVsLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvcmVnaW9uLWVkaXRvci9jbGFzc2VzLXBhbmVsL2NsYXNzZXMtcGFuZWwuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixLQUFLLEVBRUwsTUFBTSxHQUVQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3BELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFHaEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ3pELE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLG1EQUFtRCxDQUFDO0FBQzVGLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQzs7Ozs7OztBQVlwRTs7Ozs7Ozs7R0FRRztBQVNILE1BQU0sT0FBTyxxQkFBcUI7SUFtRGhDLFlBQTZCLEVBQTJCO1FBQTNCLE9BQUUsR0FBRixFQUFFLENBQXlCO1FBbER4RCxvQ0FBb0M7UUFDM0IsWUFBTyxHQUFrQixFQUFFLENBQUM7UUFDckMsNEVBQTRFO1FBQ25FLFdBQU0sR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztRQUM1QywrREFBK0Q7UUFD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RSxPQUFPLGtEQUFrRCxDQUFDO1FBQ3ZHLE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FBQyx3Q0FBd0MsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQztJQUNsRyxDQUFDOzhHQXBHVSxxQkFBcUI7a0dBQXJCLHFCQUFxQiw0aUJDaERsQyw2MElBcUdBLGc0RUQxRFksWUFBWSw2VkFBRSxXQUFXLDhtQkFBRSxZQUFZLDRPQUFFLGVBQWUsd0hBQUUsYUFBYSxzWEFBRSx1QkFBdUI7OzJGQUsvRixxQkFBcUI7a0JBUmpDLFNBQVM7K0JBQ0Usc0JBQXNCLGNBQ3BCLElBQUksV0FDUCxDQUFDLFlBQVksRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLGVBQWUsRUFBRSxhQUFhLEVBQUUsdUJBQXVCLENBQUMsbUJBRzFGLHVCQUF1QixDQUFDLE1BQU07K0VBSXRDLE9BQU87c0JBQWYsS0FBSztnQkFFRyxNQUFNO3NCQUFkLEtBQUs7Z0JBRUcsU0FBUztzQkFBakIsS0FBSztnQkFFRyxXQUFXO3NCQUFuQixLQUFLO2dCQUVHLE1BQU07c0JBQWQsS0FBSztnQkFFRyxNQUFNO3NCQUFkLEtBQUs7Z0JBRUcsYUFBYTtzQkFBckIsS0FBSztnQkFFRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBRUcsTUFBTTtzQkFBZCxLQUFLO2dCQUVHLE9BQU87c0JBQWYsS0FBSztnQkFFRyxNQUFNO3NCQUFkLEtBQUs7Z0JBRUksWUFBWTtzQkFBckIsTUFBTTtnQkFFRyxRQUFRO3NCQUFqQixNQUFNO2dCQUVFLFFBQVE7c0JBQWhCLEtBQUs7Z0JBRUksY0FBYztzQkFBdkIsTUFBTTtnQkFHRyxJQUFJO3NCQUFiLE1BQU07Z0JBRUcsT0FBTztzQkFBaEIsTUFBTTtnQkFFRyxNQUFNO3NCQUFmLE1BQU07Z0JBRUcsTUFBTTtzQkFBZixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPdXRwdXQsXG4gIFNpbXBsZUNoYW5nZXMsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgSW5wdXRUZXh0TW9kdWxlIH0gZnJvbSAncHJpbWVuZy9pbnB1dHRleHQnO1xuaW1wb3J0IHsgQnV0dG9uTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9idXR0b24nO1xuaW1wb3J0IHsgVG9vbHRpcE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvdG9vbHRpcCc7XG5cbmltcG9ydCB7IENsYXNzUHJlc2V0LCBNYXRjaE1vZGUgfSBmcm9tICcuLi8uLi9tb2RlbHMvY2xhc3MtcHJlc2V0JztcbmltcG9ydCB7IHByZXNldEtleSB9IGZyb20gJy4uLy4uL3N0b3JlL2NsYXNzLWNvbG9yLnV0aWwnO1xuaW1wb3J0IHsgSGV4Q29sb3JQaWNrZXJDb21wb25lbnQgfSBmcm9tICcuLi8uLi9oZXgtY29sb3ItcGlja2VyL2hleC1jb2xvci1waWNrZXIuY29tcG9uZW50JztcbmltcG9ydCB7IHNjcm9sbFRvUGlja2VkIH0gZnJvbSAnLi4vY2xhc3MtdHJlZS9jbGFzcy10cmVlLmNvbXBvbmVudCc7XG5cbi8qKiBPbmUgY2xhc3Mgcm93IGFzIHRoZSB0ZW1wbGF0ZSBkcmF3cyBpdCwgZGVyaXZlZCBvbmNlIHBlciBpbnB1dCBjaGFuZ2UuICovXG5pbnRlcmZhY2UgQ2xhc3NSb3cge1xuICBuYW1lOiBzdHJpbmc7XG4gIGNvbG9yOiBzdHJpbmc7XG4gIGNvdW50OiBudW1iZXI7XG4gIGNhblJlbW92ZTogYm9vbGVhbjtcbiAgcm93VG9vbHRpcDogc3RyaW5nO1xuICByZW1vdmVUb29sdGlwOiBzdHJpbmc7XG59XG5cbi8qKlxuICogVGhlIFJlZ2lvbiBFZGl0b3IncyBkb2NrZWQgXCJDbGFzc2VzXCIgcGFuZWwgKGppdC11aSM3MCk6IGV2ZXJ5IGFubm90YXRpb25cbiAqIGNsYXNzIHdpdGggaXRzIGNvbG91ciBzd2F0Y2ggYW5kIHJlZ2lvbiBjb3VudC4gQSByb3cgY2xpY2sgcGlja3MgdGhlIGFjdGl2ZVxuICogY2xhc3MgKGFuZCByZS1jbGFzc2lmaWVzIGEgc2VsZWN0aW9uKSwgdGhlIHN3YXRjaCByZWNvbG91cnMgdGhlIGNsYXNzLCB0aGVcbiAqIHRyYXNoIHJlbW92ZXMgaXQsIE1hbmFnZSBvcGVucyB0aGUgZnVsbCBlZGl0b3I7IHRoZSBzZWFyY2ggYm94IGZpbHRlcnMgdGhlXG4gKiByb3dzIGJ5IG5hbWU7IHRoZSBleWUgaGlkZXMgYSBjbGFzcydzIHJlZ2lvbnMuIEZvciBhIGNsYXNzIGhpZXJhcmNoeSB0aGUgZWRpdG9yIHByb2plY3RzIGEgY2xhc3MgdHJlZSBpbixcbiAqIHNob3duIGluIHBsYWNlIG9mIHRoZSBsaXN0IHdoaWxlIHtAbGluayB0cmVlVmlld30gaXMgb24uIFByZXNlbnRhdGlvbmFsOiB0aGVcbiAqIGVkaXRvciBhcHBsaWVzIGV2ZXJ5IGFjdGlvbi5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAncmVnaW9uLWNsYXNzZXMtcGFuZWwnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBGb3Jtc01vZHVsZSwgQnV0dG9uTW9kdWxlLCBJbnB1dFRleHRNb2R1bGUsIFRvb2x0aXBNb2R1bGUsIEhleENvbG9yUGlja2VyQ29tcG9uZW50XSxcbiAgdGVtcGxhdGVVcmw6ICcuL2NsYXNzZXMtcGFuZWwuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9jbGFzc2VzLXBhbmVsLmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBDbGFzc2VzUGFuZWxDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuICAvKiogVGhlIGNsYXNzZXMgaW4gZGlzcGxheSBvcmRlci4gKi9cbiAgQElucHV0KCkgY2xhc3NlczogQ2xhc3NQcmVzZXRbXSA9IFtdO1xuICAvKiogUmVnaW9uIGNvdW50IHBlciBjbGFzcywga2V5ZWQgYnkge0BsaW5rIHByZXNldEtleX0gdW5kZXIgYG1hdGNoTW9kZWAuICovXG4gIEBJbnB1dCgpIGNvdW50cyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gIC8qKiBIb3cgbGFiZWxzIGFyZSBtYXRjaGVkIHRvIGNsYXNzZXMgKGtleXMge0BsaW5rIGNvdW50c30pLiAqL1xuICBASW5wdXQoKSBtYXRjaE1vZGU6IE1hdGNoTW9kZSA9ICdleGFjdCc7XG4gIC8qKiBUaGUgYWN0aXZlIGNsYXNzIChoaWdobGlnaHRlZCksIG9yIG51bGwuICovXG4gIEBJbnB1dCgpIGFjdGl2ZUNsYXNzOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgLyoqIFRoZSBjbGFzcyBwaWNrZWQgbGFzdCAoaW4gdGhlIGNsYXNzIHRyZWUsIG9yIGEgc3VyZmFjZSBpbiAzRCk6IGhpZ2hsaWdodGVkLCBzY3JvbGxlZCBpbnRvIHZpZXcuICovXG4gIEBJbnB1dCgpIHBpY2tlZDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBDbGFzc2VzIHdpdGggYSBzZWxlY3RlZCByZWdpb24gKG1hcmtlZCkuICovXG4gIEBJbnB1dCgpIG1hcmtlZDogUmVhZG9ubHlTZXQ8c3RyaW5nPiA9IG5ldyBTZXQoKTtcbiAgLyoqIE51bWJlciBvZiBzZWxlY3RlZCByZWdpb25zIChjaGFuZ2VzIHdoYXQgYSByb3cgY2xpY2sgZG9lcykuICovXG4gIEBJbnB1dCgpIHNlbGVjdGVkQ291bnQgPSAwO1xuICAvKiogVGhlIGNsYXNzIHJlZ2lvbnMgcmV2ZXJ0IHRvOyBpdCBjYW4ndCBiZSByZW1vdmVkIHdoaWxlIGluIHVzZS4gKi9cbiAgQElucHV0KCkgZGVmYXVsdENsYXNzTmFtZSA9ICdSZWdpb24nO1xuICAvKiogV2hldGhlciBhIHZvbHVtZSB2aWV3IGlzIG9uIHNjcmVlbjogZWFjaCBjbGFzcyBjYW4gdGhlbiBiZSBzaG93biBpbiAzRC4gKi9cbiAgQElucHV0KCkgdm9sdW1lID0gZmFsc2U7XG4gIC8qKiBUaGUgY2xhc3NlcyBzaG93biBpbiAzRC4gKi9cbiAgQElucHV0KCkgc2hvd24zZDogUmVhZG9ubHlTZXQ8c3RyaW5nPiA9IG5ldyBTZXQoKTtcbiAgLyoqIFRoZSBjbGFzc2VzIGhpZGRlbiBmcm9tIHZpZXcuICovXG4gIEBJbnB1dCgpIGhpZGRlbjogUmVhZG9ubHlTZXQ8c3RyaW5nPiA9IG5ldyBTZXQoKTtcbiAgLyoqIEEgY2xhc3MncyBleWUgKGl0cyBuYW1lKTogaGlkZSBpdCwgb3Igc2hvdyBpdCBhZ2Fpbi4gKi9cbiAgQE91dHB1dCgpIHRvZ2dsZUhpZGRlbiA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICAvKiogQSBjbGFzcydzIDNEIHRvZ2dsZSAoaXRzIG5hbWUpLiAqL1xuICBAT3V0cHV0KCkgdG9nZ2xlM2QgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgLyoqIFdoZXRoZXIgdGhlIHByb2plY3RlZCBjbGFzcyB0cmVlIGlzIHNob3duIGluc3RlYWQgb2YgdGhlIGxpc3Q7IG51bGw6IHRoZXJlIGlzIG5vIHRyZWUuICovXG4gIEBJbnB1dCgpIHRyZWVWaWV3OiBib29sZWFuIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBUaGUgbGlzdCAvIHRyZWUgc3dpdGNoLiAqL1xuICBAT3V0cHV0KCkgdHJlZVZpZXdDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XG5cbiAgLyoqIEEgcm93IHdhcyBjbGlja2VkOiBtYWtlIHRoZSBjbGFzcyBhY3RpdmUgLyBhcHBseSBpdCB0byB0aGUgc2VsZWN0aW9uLiAqL1xuICBAT3V0cHV0KCkgcGljayA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICAvKiogQSBjbGFzcydzIHN3YXRjaCBwaWNrZWQgYSBuZXcgY29sb3VyLiAqL1xuICBAT3V0cHV0KCkgcmVjb2xvciA9IG5ldyBFdmVudEVtaXR0ZXI8eyBuYW1lOiBzdHJpbmc7IGNvbG9yOiBzdHJpbmcgfT4oKTtcbiAgLyoqIEEgY2xhc3MncyB0cmFzaCBidXR0b24gKGl0cyBuYW1lKS4gKi9cbiAgQE91dHB1dCgpIHJlbW92ZSA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICAvKiogTWFuYWdlIGNsaWNrZWQuICovXG4gIEBPdXRwdXQoKSBtYW5hZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgLyoqIHRyYWNrQnkgZm9yIHRoZSBjbGFzcyByb3dzIHNvIHJlLXNvcnRpbmcgZG9lc24ndCByZS1jcmVhdGUgdGhlIHBpY2tlcnMuICovXG4gIHByb3RlY3RlZCByZWFkb25seSB0cmFja0J5TmFtZSA9IChfOiBudW1iZXIsIGM6IENsYXNzUm93KTogc3RyaW5nID0+IGMubmFtZTtcblxuICAvKiogRXZlcnkgY2xhc3MncyByb3csIHJlYnVpbHQgd2hlbiBhbiBpbnB1dCBjaGFuZ2VzIHJhdGhlciB0aGFuIHBlciBjaGVjay4gKi9cbiAgcHJvdGVjdGVkIHJvd3M6IENsYXNzUm93W10gPSBbXTtcbiAgLyoqIFRoZSByb3dzIG1hdGNoaW5nIHtAbGluayBxdWVyeX0uICovXG4gIHByb3RlY3RlZCBzaG93blJvd3M6IENsYXNzUm93W10gPSBbXTtcbiAgLyoqIFRoZSBzZWFyY2ggYm94J3MgdGV4dC4gKi9cbiAgcHJvdGVjdGVkIHF1ZXJ5ID0gJyc7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBlbDogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4pIHt9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyA9IHt9KTogdm9pZCB7XG4gICAgdGhpcy5yb3dzID0gdGhpcy5jbGFzc2VzLm1hcCgoYykgPT4gKHtcbiAgICAgIG5hbWU6IGMubmFtZSxcbiAgICAgIGNvbG9yOiBjLmNvbG9yLFxuICAgICAgY291bnQ6IHRoaXMuY291bnQoYy5uYW1lKSxcbiAgICAgIGNhblJlbW92ZTogdGhpcy5jYW5SZW1vdmUoYy5uYW1lKSxcbiAgICAgIHJvd1Rvb2x0aXA6IHRoaXMucm93VG9vbHRpcChjLm5hbWUpLFxuICAgICAgcmVtb3ZlVG9vbHRpcDogdGhpcy5yZW1vdmVUb29sdGlwKGMubmFtZSksXG4gICAgfSkpO1xuICAgIHRoaXMuZmlsdGVyKCk7XG4gICAgaWYgKGNoYW5nZXNbJ3BpY2tlZCddICYmIHRoaXMucGlja2VkKVxuICAgICAgc2V0VGltZW91dCgoKSA9PiBzY3JvbGxUb1BpY2tlZCh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQsICcuY2xhc3Mtcm93LnBpY2tlZCcpKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvblF1ZXJ5KHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnF1ZXJ5ID0gdmFsdWU7XG4gICAgdGhpcy5maWx0ZXIoKTtcbiAgfVxuXG4gIC8qKiBFbnRlciBpbiB0aGUgc2VhcmNoIGJveCBwaWNrcyB0aGUgZmlyc3QgbWF0Y2guICovXG4gIHByb3RlY3RlZCBwaWNrRmlyc3RNYXRjaCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5xdWVyeS50cmltKCkgJiYgdGhpcy5zaG93blJvd3MubGVuZ3RoKSB0aGlzLnBpY2suZW1pdCh0aGlzLnNob3duUm93c1swXS5uYW1lKTtcbiAgfVxuXG4gIHByaXZhdGUgZmlsdGVyKCk6IHZvaWQge1xuICAgIGNvbnN0IHEgPSB0aGlzLnF1ZXJ5LnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICAgIHRoaXMuc2hvd25Sb3dzID0gcSA/IHRoaXMucm93cy5maWx0ZXIoKHIpID0+IHIubmFtZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHEpKSA6IHRoaXMucm93cztcbiAgfVxuXG4gIHByaXZhdGUgY291bnQobmFtZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5jb3VudHMuZ2V0KHByZXNldEtleSh7IG1hdGNoTW9kZTogdGhpcy5tYXRjaE1vZGUgfSwgbmFtZSkpID8/IDA7XG4gIH1cblxuICBwcml2YXRlIGNhblJlbW92ZShuYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gIShuYW1lID09PSB0aGlzLmRlZmF1bHRDbGFzc05hbWUgJiYgdGhpcy5jb3VudChuYW1lKSA+IDApO1xuICB9XG5cbiAgcHJvdGVjdGVkIHJvd1Rvb2x0aXAobmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3RlZENvdW50XG4gICAgICA/IGBBcHBseSDigJwke25hbWV94oCdIHRvIHRoZSBzZWxlY3RlZCByZWdpb24ocylgXG4gICAgICA6IGBTZXQg4oCcJHtuYW1lfeKAnSBhY3RpdmUg4oCUIG5ldyByZWdpb25zIHVzZSBpdGA7XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVtb3ZlVG9vbHRpcChuYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGluVXNlID0gdGhpcy5jb3VudChuYW1lKSA+IDA7XG4gICAgaWYgKG5hbWUgPT09IHRoaXMuZGVmYXVsdENsYXNzTmFtZSAmJiBpblVzZSkgcmV0dXJuICdUaGUgZGVmYXVsdCBjbGFzcyBjYW5ub3QgYmUgcmVtb3ZlZCB3aGlsZSBpbiB1c2UnO1xuICAgIHJldHVybiBpblVzZSA/IGBSZW1vdmUgY2xhc3Mg4oCUIGl0cyByZWdpb25zIHJldmVydCB0byAke3RoaXMuZGVmYXVsdENsYXNzTmFtZX1gIDogJ1JlbW92ZSBjbGFzcyc7XG4gIH1cbn1cbiIsIjwhLS0gRG9ja2VkIFwiQ2xhc3Nlc1wiIHBhbmVsIChqaXQtdWkjNzApOiB0aGUgYWx3YXlzLXZpc2libGUgbGlzdCBvZiBhbm5vdGF0aW9uXG4gICAgIGNsYXNzZXMgYWJvdmUgdGhlIHJlZ2lvbnMgdGFibGUuIENsaWNrIGEgcm93IHRvIG1ha2UgaXQgdGhlIGFjdGl2ZSBjbGFzc1xuICAgICAobmV3IHJlZ2lvbnMgaW5oZXJpdCBpdDsgd2l0aCByb3dzIHNlbGVjdGVkIGl0IHJlLWNsYXNzaWZpZXMgdGhlbSk7IHJlY29sb3VyXG4gICAgIHZpYSB0aGUgc3dhdGNoOyB0aGUgYmFkZ2Ugc2hvd3MgaG93IG1hbnkgcmVnaW9ucyB1c2UgdGhlIGNsYXNzLiBcIk1hbmFnZVwiXG4gICAgIG9wZW5zIHRoZSBmdWxsIGVkaXRvciAoZmFsbGJhY2sgcGFsZXR0ZSwgYXV0by1hZGQsIG1hdGNoaW5nLCBpbXBvcnQvZXhwb3J0KS5cbiAgICAgQSByZWdpb24gc2V0IHdpdGggYSBjbGFzcyBoaWVyYXJjaHkgKGFuIGF0bGFzIG9udG9sb2d5KSBjYW4gc2hvdyBpdHMgY2xhc3Nlc1xuICAgICBhcyBhIHRyZWUgaW5zdGVhZCAocHJvamVjdGVkIGluIGJ5IHRoZSBlZGl0b3IpOyB0aGUgaGVhZGVyIHN3aXRjaGVzIHZpZXdzLiAtLT5cbjxkaXYgY2xhc3M9XCJjbGFzc2VzLXBhbmVsXCI+XG4gIDxkaXYgY2xhc3M9XCJjbGFzc2VzLXBhbmVsLWhlYWRlclwiPlxuICAgIDxzcGFuIGNsYXNzPVwiY2xhc3Nlcy1wYW5lbC10aXRsZVwiPkNsYXNzZXM8L3NwYW4+XG4gICAgPGJ1dHRvblxuICAgICAgKm5nSWY9XCJ0cmVlVmlldyAhPT0gbnVsbFwiXG4gICAgICBwQnV0dG9uXG4gICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgIFtpY29uXT1cInRyZWVWaWV3ID8gJ3BpIHBpLWxpc3QnIDogJ3BpIHBpLXNpdGVtYXAnXCJcbiAgICAgIGNsYXNzPVwicC1idXR0b24tc20gcC1idXR0b24tdGV4dFwiXG4gICAgICBbcFRvb2x0aXBdPVwidHJlZVZpZXcgPyAnU2hvdyB0aGUgY2xhc3NlcyBhcyBhIGxpc3QnIDogJ1Nob3cgdGhlIGNsYXNzZXMgYXMgYSB0cmVlJ1wiXG4gICAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJ0cmVlVmlldyA/ICdTaG93IHRoZSBjbGFzc2VzIGFzIGEgbGlzdCcgOiAnU2hvdyB0aGUgY2xhc3NlcyBhcyBhIHRyZWUnXCJcbiAgICAgIChjbGljayk9XCJ0cmVlVmlld0NoYW5nZS5lbWl0KCF0cmVlVmlldylcIlxuICAgID48L2J1dHRvbj5cbiAgICA8YnV0dG9uXG4gICAgICBwQnV0dG9uXG4gICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgIGljb249XCJwaSBwaS1jb2dcIlxuICAgICAgbGFiZWw9XCJNYW5hZ2VcIlxuICAgICAgY2xhc3M9XCJwLWJ1dHRvbi1zbSBwLWJ1dHRvbi10ZXh0XCJcbiAgICAgIHBUb29sdGlwPVwiTWFuYWdlIGNsYXNzZXMg4oCUIGFkZCAvIHJlbW92ZSwgcGFsZXR0ZSwgbWF0Y2hpbmcsIGltcG9ydC9leHBvcnRcIlxuICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgIChjbGljayk9XCJtYW5hZ2UuZW1pdCgpXCJcbiAgICA+PC9idXR0b24+XG4gIDwvZGl2PlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwidHJlZVZpZXc7IGVsc2UgbGlzdFwiPjxuZy1jb250ZW50PjwvbmctY29udGVudD48L25nLWNvbnRhaW5lcj5cbiAgPG5nLXRlbXBsYXRlICNsaXN0PlxuICAgIDxpbnB1dFxuICAgICAgKm5nSWY9XCJjbGFzc2VzLmxlbmd0aFwiXG4gICAgICB0eXBlPVwidGV4dFwiXG4gICAgICBwSW5wdXRUZXh0XG4gICAgICBjbGFzcz1cInAtaW5wdXR0ZXh0LXNtIGNsYXNzZXMtc2VhcmNoXCJcbiAgICAgIHBsYWNlaG9sZGVyPVwiU2VhcmNoIGJ5IG5hbWVcIlxuICAgICAgYXJpYS1sYWJlbD1cIlNlYXJjaCB0aGUgY2xhc3Nlc1wiXG4gICAgICBbbmdNb2RlbF09XCJxdWVyeVwiXG4gICAgICAobmdNb2RlbENoYW5nZSk9XCJvblF1ZXJ5KCRldmVudClcIlxuICAgICAgKGtleWRvd24uZW50ZXIpPVwicGlja0ZpcnN0TWF0Y2goKVwiXG4gICAgLz5cbiAgICA8ZGl2IGNsYXNzPVwiY2xhc3Nlcy1wYW5lbC1ib2R5XCI+XG4gICAgICA8ZGl2XG4gICAgICAgICpuZ0Zvcj1cImxldCBjIG9mIHNob3duUm93czsgdHJhY2tCeTogdHJhY2tCeU5hbWVcIlxuICAgICAgICBjbGFzcz1cImNsYXNzLXJvd1wiXG4gICAgICAgIFtjbGFzcy5hY3RpdmVdPVwiYWN0aXZlQ2xhc3MgPT09IGMubmFtZVwiXG4gICAgICAgIFtjbGFzcy5waWNrZWRdPVwicGlja2VkID09PSBjLm5hbWVcIlxuICAgICAgICBbY2xhc3MubWFya2VkXT1cIm1hcmtlZC5oYXMoYy5uYW1lKVwiXG4gICAgICAgIFtjbGFzcy5oaWRkZW4tY2xhc3NdPVwiaGlkZGVuLmhhcyhjLm5hbWUpXCJcbiAgICAgICAgKGNsaWNrKT1cInBpY2suZW1pdChjLm5hbWUpXCJcbiAgICAgICAgW3BUb29sdGlwXT1cImMucm93VG9vbHRpcFwiXG4gICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgICA+XG4gICAgICAgIDxpXG4gICAgICAgICAgY2xhc3M9XCJwaSByb3ctZXllXCJcbiAgICAgICAgICBbbmdDbGFzc109XCJoaWRkZW4uaGFzKGMubmFtZSkgPyAncGktZXllLXNsYXNoJyA6ICdwaS1leWUnXCJcbiAgICAgICAgICByb2xlPVwiYnV0dG9uXCJcbiAgICAgICAgICBbYXR0ci5hcmlhLXByZXNzZWRdPVwiIWhpZGRlbi5oYXMoYy5uYW1lKVwiXG4gICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCIoaGlkZGVuLmhhcyhjLm5hbWUpID8gJ1Nob3cgJyA6ICdIaWRlICcpICsgYy5uYW1lXCJcbiAgICAgICAgICBbcFRvb2x0aXBdPVwiaGlkZGVuLmhhcyhjLm5hbWUpID8gJ1Nob3cgdGhpcyBjbGFzcycgOiAnSGlkZSB0aGlzIGNsYXNzJ1wiXG4gICAgICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyB0b2dnbGVIaWRkZW4uZW1pdChjLm5hbWUpXCJcbiAgICAgICAgPjwvaT5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJyb3ctc3dhdGNoXCIgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgICAgICAgIDxoZXgtY29sb3ItcGlja2VyIFtjb2xvcl09XCJjLmNvbG9yXCIgKGNvbG9yQ2hhbmdlKT1cInJlY29sb3IuZW1pdCh7IG5hbWU6IGMubmFtZSwgY29sb3I6ICRldmVudCB9KVwiPlxuICAgICAgICAgIDwvaGV4LWNvbG9yLXBpY2tlcj5cbiAgICAgICAgPC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInJvdy1uYW1lXCI+e3sgYy5uYW1lIH19PC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInJvdy1jb3VudFwiIFtjbGFzcy56ZXJvXT1cImMuY291bnQgPT09IDBcIj57eyBjLmNvdW50IH19PC9zcGFuPlxuICAgICAgICA8aVxuICAgICAgICAgICpuZ0lmPVwidm9sdW1lXCJcbiAgICAgICAgICBjbGFzcz1cInBpIHBpLWJveCByb3ctM2RcIlxuICAgICAgICAgIFtjbGFzcy5vbl09XCJzaG93bjNkLmhhcyhjLm5hbWUpXCJcbiAgICAgICAgICByb2xlPVwiYnV0dG9uXCJcbiAgICAgICAgICBbYXR0ci5hcmlhLXByZXNzZWRdPVwic2hvd24zZC5oYXMoYy5uYW1lKVwiXG4gICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCInU2hvdyAnICsgYy5uYW1lICsgJyBpbiAzRCdcIlxuICAgICAgICAgIHBUb29sdGlwPVwiU2hvdyBpbiB0aGUgdm9sdW1lLCBpbiAzRFwiXG4gICAgICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyB0b2dnbGUzZC5lbWl0KGMubmFtZSlcIlxuICAgICAgICA+PC9pPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgcEJ1dHRvblxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIGljb249XCJwaSBwaS10cmFzaFwiXG4gICAgICAgICAgY2xhc3M9XCJwLWJ1dHRvbi1zbSBwLWJ1dHRvbi10ZXh0IHAtYnV0dG9uLXdhcm5pbmcgcm93LWRlbFwiXG4gICAgICAgICAgW2Rpc2FibGVkXT1cIiFjLmNhblJlbW92ZVwiXG4gICAgICAgICAgW3BUb29sdGlwXT1cImMucmVtb3ZlVG9vbHRpcFwiXG4gICAgICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIidSZW1vdmUgY2xhc3MgJyArIGMubmFtZVwiXG4gICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgcmVtb3ZlLmVtaXQoYy5uYW1lKVwiXG4gICAgICAgID48L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiAqbmdJZj1cIiFjbGFzc2VzLmxlbmd0aFwiIGNsYXNzPVwiY2xhc3Nlcy1lbXB0eVwiPk5vIGNsYXNzZXMgeWV0IOKAlCBhZGQgb25lIGZyb20gTWFuYWdlLjwvZGl2PlxuICAgICAgPGRpdiAqbmdJZj1cImNsYXNzZXMubGVuZ3RoICYmICFzaG93blJvd3MubGVuZ3RoXCIgY2xhc3M9XCJjbGFzc2VzLWVtcHR5XCI+Tm8gY2xhc3MgbWF0Y2hlcy48L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9uZy10ZW1wbGF0ZT5cbjwvZGl2PlxuIl19
@@ -0,0 +1,13 @@
1
+ /**
2
+ * A file name without its extension: `slide.ome.tif` → `slide.ome`. A name with
3
+ * no extension — or only a leading dot, like `.hidden` — is returned whole, so
4
+ * a derived name is never a bare `.geojson`. `fallback` stands in for a missing
5
+ * name.
6
+ */
7
+ export function fileStem(name, fallback) {
8
+ if (!name)
9
+ return fallback;
10
+ const dot = name.lastIndexOf('.');
11
+ return dot > 0 ? name.substring(0, dot) : name;
12
+ }
13
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS1zdGVtLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9yZWdpb24tZWRpdG9yL2ZpbGUtc3RlbS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxRQUFRLENBQUMsSUFBK0IsRUFBRSxRQUFnQjtJQUN4RSxJQUFJLENBQUMsSUFBSTtRQUFFLE9BQU8sUUFBUSxDQUFDO0lBQzNCLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDbEMsT0FBTyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0FBQ2pELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEEgZmlsZSBuYW1lIHdpdGhvdXQgaXRzIGV4dGVuc2lvbjogYHNsaWRlLm9tZS50aWZgIOKGkiBgc2xpZGUub21lYC4gQSBuYW1lIHdpdGhcbiAqIG5vIGV4dGVuc2lvbiDigJQgb3Igb25seSBhIGxlYWRpbmcgZG90LCBsaWtlIGAuaGlkZGVuYCDigJQgaXMgcmV0dXJuZWQgd2hvbGUsIHNvXG4gKiBhIGRlcml2ZWQgbmFtZSBpcyBuZXZlciBhIGJhcmUgYC5nZW9qc29uYC4gYGZhbGxiYWNrYCBzdGFuZHMgaW4gZm9yIGEgbWlzc2luZ1xuICogbmFtZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbGVTdGVtKG5hbWU6IHN0cmluZyB8IG51bGwgfCB1bmRlZmluZWQsIGZhbGxiYWNrOiBzdHJpbmcpOiBzdHJpbmcge1xuICBpZiAoIW5hbWUpIHJldHVybiBmYWxsYmFjaztcbiAgY29uc3QgZG90ID0gbmFtZS5sYXN0SW5kZXhPZignLicpO1xuICByZXR1cm4gZG90ID4gMCA/IG5hbWUuc3Vic3RyaW5nKDAsIGRvdCkgOiBuYW1lO1xufVxuIl19
@@ -0,0 +1,118 @@
1
+ import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { FormsModule } from '@angular/forms';
4
+ import { SharedModule } from 'primeng/api';
5
+ import { ButtonModule } from 'primeng/button';
6
+ import { CheckboxModule } from 'primeng/checkbox';
7
+ import { DialogModule } from 'primeng/dialog';
8
+ import { InputTextModule } from 'primeng/inputtext';
9
+ import { SelectButtonModule } from 'primeng/selectbutton';
10
+ import { TooltipModule } from 'primeng/tooltip';
11
+ import { HexColorPickerComponent } from '../../hex-color-picker/hex-color-picker.component';
12
+ import * as i0 from "@angular/core";
13
+ import * as i1 from "@angular/common";
14
+ import * as i2 from "@angular/forms";
15
+ import * as i3 from "primeng/api";
16
+ import * as i4 from "primeng/button";
17
+ import * as i5 from "primeng/checkbox";
18
+ import * as i6 from "primeng/dialog";
19
+ import * as i7 from "primeng/inputtext";
20
+ import * as i8 from "primeng/selectbutton";
21
+ import * as i9 from "primeng/tooltip";
22
+ /**
23
+ * "Manage annotation classes" (jit-ui#70): edit the classes, the fallback
24
+ * palette, auto-add and label matching of a working copy of the preset set,
25
+ * plus reset / import / export. The editor owns the draft (`[(draft)]`); every
26
+ * edit here emits a new draft object (nothing is changed in place), and Apply
27
+ * asks the editor to persist it.
28
+ */
29
+ export class ManageClassesDialogComponent {
30
+ constructor() {
31
+ /** The dialog is open. */
32
+ this.visible = false;
33
+ /** The dialog was closed (`false`); two-way with {@link visible}. */
34
+ this.visibleChange = new EventEmitter();
35
+ /** The working copy being edited (null until the dialog is opened). */
36
+ this.draft = null;
37
+ /** Every edit: the new draft object; two-way with {@link draft}. */
38
+ this.draftChange = new EventEmitter();
39
+ /** Apply clicked: persist the draft and close. */
40
+ this.apply = new EventEmitter();
41
+ /** Reset clicked: restore the default classes. */
42
+ this.resetDefaults = new EventEmitter();
43
+ /** A preset JSON file was chosen (the input's change event). */
44
+ this.importFile = new EventEmitter();
45
+ /** Export clicked. */
46
+ this.export = new EventEmitter();
47
+ this.matchModeOptions = [
48
+ { label: 'Exact', value: 'exact' },
49
+ { label: 'Normalized', value: 'normalized' },
50
+ ];
51
+ /** Rows keep their DOM (and input focus) while their class object is replaced. */
52
+ this.trackByIndex = (i) => i;
53
+ }
54
+ addClass() {
55
+ this.update((d) => ({ classes: [...d.classes, { name: '', color: '#888888', source: 'user' }] }));
56
+ }
57
+ removeClass(i) {
58
+ this.update((d) => ({ classes: d.classes.filter((_, k) => k !== i) }));
59
+ }
60
+ patchClass(i, patch) {
61
+ this.update((d) => ({ classes: d.classes.map((c, k) => (k === i ? { ...c, ...patch } : c)) }));
62
+ }
63
+ addFallbackColor() {
64
+ this.update((d) => ({ fallbackPalette: [...d.fallbackPalette, '#888888'] }));
65
+ }
66
+ removeFallbackColor(i) {
67
+ this.update((d) => ({ fallbackPalette: d.fallbackPalette.filter((_, k) => k !== i) }));
68
+ }
69
+ setFallbackColor(i, color) {
70
+ this.update((d) => ({ fallbackPalette: d.fallbackPalette.map((c, k) => (k === i ? color : c)) }));
71
+ }
72
+ setAutoPromote(autoPromote) {
73
+ this.update(() => ({ autoPromote }));
74
+ }
75
+ setMatchMode(matchMode) {
76
+ this.update(() => ({ matchMode }));
77
+ }
78
+ update(change) {
79
+ if (!this.draft)
80
+ return;
81
+ this.draft = { ...this.draft, ...change(this.draft) };
82
+ this.draftChange.emit(this.draft);
83
+ }
84
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: ManageClassesDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
85
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: ManageClassesDialogComponent, isStandalone: true, selector: "region-manage-classes-dialog", inputs: { visible: "visible", draft: "draft" }, outputs: { visibleChange: "visibleChange", draftChange: "draftChange", apply: "apply", resetDefaults: "resetDefaults", importFile: "importFile", export: "export" }, ngImport: i0, template: "<p-dialog\n header=\"Manage annotation classes\"\n [visible]=\"visible\"\n (visibleChange)=\"visibleChange.emit($event)\"\n [modal]=\"true\"\n appendTo=\"body\"\n [style]=\"{ width: '34rem' }\"\n [draggable]=\"true\"\n [resizable]=\"false\"\n>\n <div *ngIf=\"draft\" class=\"manage-dialog flex flex-column gap-3 pt-2\">\n <div class=\"manage-classes flex flex-column gap-2\">\n <div\n *ngFor=\"let c of draft.classes; let i = index; trackBy: trackByIndex\"\n class=\"manage-class-row flex align-items-center gap-2\"\n >\n <hex-color-picker [color]=\"c.color\" (colorChange)=\"patchClass(i, { color: $event })\"></hex-color-picker>\n <input\n type=\"text\"\n pInputText\n class=\"p-inputtext-sm flex-1\"\n [ngModel]=\"c.name\"\n (ngModelChange)=\"patchClass(i, { name: $event })\"\n placeholder=\"Class name\"\n aria-label=\"Class name\"\n />\n <button\n pButton\n type=\"button\"\n icon=\"pi pi-trash\"\n class=\"p-button-sm p-button-text p-button-warning\"\n pTooltip=\"Remove class\"\n tooltipPosition=\"bottom\"\n aria-label=\"Remove class\"\n (click)=\"removeClass(i)\"\n ></button>\n </div>\n <button\n pButton\n type=\"button\"\n icon=\"pi pi-plus\"\n label=\"Add class\"\n class=\"p-button-sm p-button-text align-self-start\"\n (click)=\"addClass()\"\n ></button>\n </div>\n\n <div class=\"manage-section flex flex-column gap-2\">\n <span class=\"section-title font-medium\"\n >Fallback palette <small class=\"text-color-secondary\">\u2014 colours for classes not listed</small></span\n >\n <div class=\"fallback-palette flex align-items-center flex-wrap gap-2\">\n <span\n *ngFor=\"let col of draft.fallbackPalette; let i = index; trackBy: trackByIndex\"\n class=\"fallback-swatch flex align-items-center\"\n >\n <hex-color-picker [color]=\"col\" (colorChange)=\"setFallbackColor(i, $event)\"></hex-color-picker>\n <i\n class=\"pi pi-times icon-hover ml-1\"\n pTooltip=\"Remove\"\n tooltipPosition=\"bottom\"\n (click)=\"removeFallbackColor(i)\"\n ></i>\n </span>\n <button\n pButton\n type=\"button\"\n icon=\"pi pi-plus\"\n class=\"p-button-sm p-button-text\"\n pTooltip=\"Add fallback colour\"\n tooltipPosition=\"bottom\"\n aria-label=\"Add fallback colour\"\n (click)=\"addFallbackColor()\"\n ></button>\n </div>\n </div>\n\n <div class=\"flex align-items-center gap-2\">\n <p-checkbox\n [ngModel]=\"draft.autoPromote\"\n (ngModelChange)=\"setAutoPromote($event)\"\n [binary]=\"true\"\n inputId=\"autoPromote\"\n ></p-checkbox>\n <label for=\"autoPromote\">Auto-add detected classes to this list as they appear</label>\n </div>\n\n <div class=\"flex align-items-center gap-3\">\n <span class=\"font-medium\">Label matching</span>\n <p-selectButton\n [options]=\"matchModeOptions\"\n [ngModel]=\"draft.matchMode\"\n (ngModelChange)=\"setMatchMode($event)\"\n optionLabel=\"label\"\n optionValue=\"value\"\n ></p-selectButton>\n </div>\n </div>\n\n <ng-template pTemplate=\"footer\">\n <div class=\"manage-footer flex align-items-center flex-wrap gap-2 w-full\">\n <span class=\"flex align-items-center flex-wrap gap-1\">\n <p-button label=\"Reset\" icon=\"pi pi-refresh\" [text]=\"true\" (onClick)=\"resetDefaults.emit()\"></p-button>\n <p-button label=\"Import\" icon=\"pi pi-upload\" [text]=\"true\" (onClick)=\"presetFileInput.click()\"></p-button>\n <input\n #presetFileInput\n type=\"file\"\n accept=\".json,application/json\"\n hidden\n (change)=\"importFile.emit($event); presetFileInput.value = ''\"\n />\n <p-button label=\"Export\" icon=\"pi pi-download\" [text]=\"true\" (onClick)=\"export.emit()\"></p-button>\n </span>\n <span class=\"flex-1\"></span>\n <!-- Apply persists to the server and closes. -->\n <p-button label=\"Apply\" icon=\"pi pi-check\" (onClick)=\"apply.emit()\"></p-button>\n </div>\n </ng-template>\n</p-dialog>\n", styles: [".manage-dialog .manage-class-row hex-color-picker,.manage-dialog .fallback-palette hex-color-picker{flex:0 0 auto}.manage-dialog .fallback-palette .icon-hover{cursor:pointer;color:var(--text-color-secondary)}.manage-dialog .fallback-palette .icon-hover:hover{color:var(--primary-color)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: SharedModule }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "component", type: i4.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i5.Checkbox, selector: "p-checkbox", inputs: ["value", "name", "disabled", "binary", "label", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "styleClass", "labelStyleClass", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i6.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "visible", "style", "position"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i7.InputText, selector: "[pInputText]", inputs: ["variant"] }, { kind: "ngmodule", type: SelectButtonModule }, { kind: "component", type: i8.SelectButton, selector: "p-selectButton", inputs: ["options", "optionLabel", "optionValue", "optionDisabled", "unselectable", "tabindex", "multiple", "allowEmpty", "style", "styleClass", "ariaLabelledBy", "disabled", "dataKey", "autofocus"], outputs: ["onOptionClick", "onChange"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i9.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: HexColorPickerComponent, selector: "hex-color-picker", inputs: ["color"], outputs: ["colorChange", "colorInput"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
86
+ }
87
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: ManageClassesDialogComponent, decorators: [{
88
+ type: Component,
89
+ args: [{ selector: 'region-manage-classes-dialog', standalone: true, imports: [
90
+ CommonModule,
91
+ FormsModule,
92
+ SharedModule,
93
+ ButtonModule,
94
+ CheckboxModule,
95
+ DialogModule,
96
+ InputTextModule,
97
+ SelectButtonModule,
98
+ TooltipModule,
99
+ HexColorPickerComponent,
100
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<p-dialog\n header=\"Manage annotation classes\"\n [visible]=\"visible\"\n (visibleChange)=\"visibleChange.emit($event)\"\n [modal]=\"true\"\n appendTo=\"body\"\n [style]=\"{ width: '34rem' }\"\n [draggable]=\"true\"\n [resizable]=\"false\"\n>\n <div *ngIf=\"draft\" class=\"manage-dialog flex flex-column gap-3 pt-2\">\n <div class=\"manage-classes flex flex-column gap-2\">\n <div\n *ngFor=\"let c of draft.classes; let i = index; trackBy: trackByIndex\"\n class=\"manage-class-row flex align-items-center gap-2\"\n >\n <hex-color-picker [color]=\"c.color\" (colorChange)=\"patchClass(i, { color: $event })\"></hex-color-picker>\n <input\n type=\"text\"\n pInputText\n class=\"p-inputtext-sm flex-1\"\n [ngModel]=\"c.name\"\n (ngModelChange)=\"patchClass(i, { name: $event })\"\n placeholder=\"Class name\"\n aria-label=\"Class name\"\n />\n <button\n pButton\n type=\"button\"\n icon=\"pi pi-trash\"\n class=\"p-button-sm p-button-text p-button-warning\"\n pTooltip=\"Remove class\"\n tooltipPosition=\"bottom\"\n aria-label=\"Remove class\"\n (click)=\"removeClass(i)\"\n ></button>\n </div>\n <button\n pButton\n type=\"button\"\n icon=\"pi pi-plus\"\n label=\"Add class\"\n class=\"p-button-sm p-button-text align-self-start\"\n (click)=\"addClass()\"\n ></button>\n </div>\n\n <div class=\"manage-section flex flex-column gap-2\">\n <span class=\"section-title font-medium\"\n >Fallback palette <small class=\"text-color-secondary\">\u2014 colours for classes not listed</small></span\n >\n <div class=\"fallback-palette flex align-items-center flex-wrap gap-2\">\n <span\n *ngFor=\"let col of draft.fallbackPalette; let i = index; trackBy: trackByIndex\"\n class=\"fallback-swatch flex align-items-center\"\n >\n <hex-color-picker [color]=\"col\" (colorChange)=\"setFallbackColor(i, $event)\"></hex-color-picker>\n <i\n class=\"pi pi-times icon-hover ml-1\"\n pTooltip=\"Remove\"\n tooltipPosition=\"bottom\"\n (click)=\"removeFallbackColor(i)\"\n ></i>\n </span>\n <button\n pButton\n type=\"button\"\n icon=\"pi pi-plus\"\n class=\"p-button-sm p-button-text\"\n pTooltip=\"Add fallback colour\"\n tooltipPosition=\"bottom\"\n aria-label=\"Add fallback colour\"\n (click)=\"addFallbackColor()\"\n ></button>\n </div>\n </div>\n\n <div class=\"flex align-items-center gap-2\">\n <p-checkbox\n [ngModel]=\"draft.autoPromote\"\n (ngModelChange)=\"setAutoPromote($event)\"\n [binary]=\"true\"\n inputId=\"autoPromote\"\n ></p-checkbox>\n <label for=\"autoPromote\">Auto-add detected classes to this list as they appear</label>\n </div>\n\n <div class=\"flex align-items-center gap-3\">\n <span class=\"font-medium\">Label matching</span>\n <p-selectButton\n [options]=\"matchModeOptions\"\n [ngModel]=\"draft.matchMode\"\n (ngModelChange)=\"setMatchMode($event)\"\n optionLabel=\"label\"\n optionValue=\"value\"\n ></p-selectButton>\n </div>\n </div>\n\n <ng-template pTemplate=\"footer\">\n <div class=\"manage-footer flex align-items-center flex-wrap gap-2 w-full\">\n <span class=\"flex align-items-center flex-wrap gap-1\">\n <p-button label=\"Reset\" icon=\"pi pi-refresh\" [text]=\"true\" (onClick)=\"resetDefaults.emit()\"></p-button>\n <p-button label=\"Import\" icon=\"pi pi-upload\" [text]=\"true\" (onClick)=\"presetFileInput.click()\"></p-button>\n <input\n #presetFileInput\n type=\"file\"\n accept=\".json,application/json\"\n hidden\n (change)=\"importFile.emit($event); presetFileInput.value = ''\"\n />\n <p-button label=\"Export\" icon=\"pi pi-download\" [text]=\"true\" (onClick)=\"export.emit()\"></p-button>\n </span>\n <span class=\"flex-1\"></span>\n <!-- Apply persists to the server and closes. -->\n <p-button label=\"Apply\" icon=\"pi pi-check\" (onClick)=\"apply.emit()\"></p-button>\n </div>\n </ng-template>\n</p-dialog>\n", styles: [".manage-dialog .manage-class-row hex-color-picker,.manage-dialog .fallback-palette hex-color-picker{flex:0 0 auto}.manage-dialog .fallback-palette .icon-hover{cursor:pointer;color:var(--text-color-secondary)}.manage-dialog .fallback-palette .icon-hover:hover{color:var(--primary-color)}\n"] }]
101
+ }], propDecorators: { visible: [{
102
+ type: Input
103
+ }], visibleChange: [{
104
+ type: Output
105
+ }], draft: [{
106
+ type: Input
107
+ }], draftChange: [{
108
+ type: Output
109
+ }], apply: [{
110
+ type: Output
111
+ }], resetDefaults: [{
112
+ type: Output
113
+ }], importFile: [{
114
+ type: Output
115
+ }], export: [{
116
+ type: Output
117
+ }] } });
118
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFuYWdlLWNsYXNzZXMtZGlhbG9nLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvcmVnaW9uLWVkaXRvci9tYW5hZ2UtY2xhc3Nlcy1kaWFsb2cvbWFuYWdlLWNsYXNzZXMtZGlhbG9nLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvcmVnaW9uLWVkaXRvci9tYW5hZ2UtY2xhc3Nlcy1kaWFsb2cvbWFuYWdlLWNsYXNzZXMtZGlhbG9nLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDaEcsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUMxRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFHaEQsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sbURBQW1ELENBQUM7Ozs7Ozs7Ozs7O0FBRTVGOzs7Ozs7R0FNRztBQW9CSCxNQUFNLE9BQU8sNEJBQTRCO0lBbkJ6QztRQW9CRSwwQkFBMEI7UUFDakIsWUFBTyxHQUFH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QUF1QixDQUFDLE1BQU07OEJBSXRDLE9BQU87c0JBQWYsS0FBSztnQkFFSSxhQUFhO3NCQUF0QixNQUFNO2dCQUdFLEtBQUs7c0JBQWIsS0FBSztnQkFFSSxXQUFXO3NCQUFwQixNQUFNO2dCQUdHLEtBQUs7c0JBQWQsTUFBTTtnQkFFRyxhQUFhO3NCQUF0QixNQUFNO2dCQUVHLFVBQVU7c0JBQW5CLE1BQU07Z0JBRUcsTUFBTTtzQkFBZixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBTaGFyZWRNb2R1bGUgfSBmcm9tICdwcmltZW5nL2FwaSc7XG5pbXBvcnQgeyBCdXR0b25Nb2R1bGUgfSBmcm9tICdwcmltZW5nL2J1dHRvbic7XG5pbXBvcnQgeyBDaGVja2JveE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvY2hlY2tib3gnO1xuaW1wb3J0IHsgRGlhbG9nTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9kaWFsb2cnO1xuaW1wb3J0IHsgSW5wdXRUZXh0TW9kdWxlIH0gZnJvbSAncHJpbWVuZy9pbnB1dHRleHQnO1xuaW1wb3J0IHsgU2VsZWN0QnV0dG9uTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9zZWxlY3RidXR0b24nO1xuaW1wb3J0IHsgVG9vbHRpcE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvdG9vbHRpcCc7XG5cbmltcG9ydCB7IENsYXNzUHJlc2V0LCBNYXRjaE1vZGUsIFByZXNldFNldCB9IGZyb20gJy4uLy4uL21vZGVscy9jbGFzcy1wcmVzZXQnO1xuaW1wb3J0IHsgSGV4Q29sb3JQaWNrZXJDb21wb25lbnQgfSBmcm9tICcuLi8uLi9oZXgtY29sb3ItcGlja2VyL2hleC1jb2xvci1waWNrZXIuY29tcG9uZW50JztcblxuLyoqXG4gKiBcIk1hbmFnZSBhbm5vdGF0aW9uIGNsYXNzZXNcIiAoaml0LXVpIzcwKTogZWRpdCB0aGUgY2xhc3NlcywgdGhlIGZhbGxiYWNrXG4gKiBwYWxldHRlLCBhdXRvLWFkZCBhbmQgbGFiZWwgbWF0Y2hpbmcgb2YgYSB3b3JraW5nIGNvcHkgb2YgdGhlIHByZXNldCBzZXQsXG4gKiBwbHVzIHJlc2V0IC8gaW1wb3J0IC8gZXhwb3J0LiBUaGUgZWRpdG9yIG93bnMgdGhlIGRyYWZ0IChgWyhkcmFmdCldYCk7IGV2ZXJ5XG4gKiBlZGl0IGhlcmUgZW1pdHMgYSBuZXcgZHJhZnQgb2JqZWN0IChub3RoaW5nIGlzIGNoYW5nZWQgaW4gcGxhY2UpLCBhbmQgQXBwbHlcbiAqIGFza3MgdGhlIGVkaXRvciB0byBwZXJzaXN0IGl0LlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdyZWdpb24tbWFuYWdlLWNsYXNzZXMtZGlhbG9nJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBGb3Jtc01vZHVsZSxcbiAgICBTaGFyZWRNb2R1bGUsXG4gICAgQnV0dG9uTW9kdWxlLFxuICAgIENoZWNrYm94TW9kdWxlLFxuICAgIERpYWxvZ01vZHVsZSxcbiAgICBJbnB1dFRleHRNb2R1bGUsXG4gICAgU2VsZWN0QnV0dG9uTW9kdWxlLFxuICAgIFRvb2x0aXBNb2R1bGUsXG4gICAgSGV4Q29sb3JQaWNrZXJDb21wb25lbnQsXG4gIF0sXG4gIHRlbXBsYXRlVXJsOiAnLi9tYW5hZ2UtY2xhc3Nlcy1kaWFsb2cuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9tYW5hZ2UtY2xhc3Nlcy1kaWFsb2cuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIE1hbmFnZUNsYXNzZXNEaWFsb2dDb21wb25lbnQge1xuICAvKiogVGhlIGRpYWxvZyBpcyBvcGVuLiAqL1xuICBASW5wdXQoKSB2aXNpYmxlID0gZmFsc2U7XG4gIC8qKiBUaGUgZGlhbG9nIHdhcyBjbG9zZWQgKGBmYWxzZWApOyB0d28td2F5IHdpdGgge0BsaW5rIHZpc2libGV9LiAqL1xuICBAT3V0cHV0KCkgdmlzaWJsZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcblxuICAvKiogVGhlIHdvcmtpbmcgY29weSBiZWluZyBlZGl0ZWQgKG51bGwgdW50aWwgdGhlIGRpYWxvZyBpcyBvcGVuZWQpLiAqL1xuICBASW5wdXQoKSBkcmFmdDogUHJlc2V0U2V0IHwgbnVsbCA9IG51bGw7XG4gIC8qKiBFdmVyeSBlZGl0OiB0aGUgbmV3IGRyYWZ0IG9iamVjdDsgdHdvLXdheSB3aXRoIHtAbGluayBkcmFmdH0uICovXG4gIEBPdXRwdXQoKSBkcmFmdENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8UHJlc2V0U2V0PigpO1xuXG4gIC8qKiBBcHBseSBjbGlja2VkOiBwZXJzaXN0IHRoZSBkcmFmdCBhbmQgY2xvc2UuICovXG4gIEBPdXRwdXQoKSBhcHBseSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIFJlc2V0IGNsaWNrZWQ6IHJlc3RvcmUgdGhlIGRlZmF1bHQgY2xhc3Nlcy4gKi9cbiAgQE91dHB1dCgpIHJlc2V0RGVmYXVsdHMgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBBIHByZXNldCBKU09OIGZpbGUgd2FzIGNob3NlbiAodGhlIGlucHV0J3MgY2hhbmdlIGV2ZW50KS4gKi9cbiAgQE91dHB1dCgpIGltcG9ydEZpbGUgPSBuZXcgRXZlbnRFbWl0dGVyPEV2ZW50PigpO1xuICAvKiogRXhwb3J0IGNsaWNrZWQuICovXG4gIEBPdXRwdXQoKSBleHBvcnQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IG1hdGNoTW9kZU9wdGlvbnMgPSBbXG4gICAgeyBsYWJlbDogJ0V4YWN0JywgdmFsdWU6ICdleGFjdCcgfSxcbiAgICB7IGxhYmVsOiAnTm9ybWFsaXplZCcsIHZhbHVlOiAnbm9ybWFsaXplZCcgfSxcbiAgXTtcblxuICAvKiogUm93cyBrZWVwIHRoZWlyIERPTSAoYW5kIGlucHV0IGZvY3VzKSB3aGlsZSB0aGVpciBjbGFzcyBvYmplY3QgaXMgcmVwbGFjZWQuICovXG4gIHByb3RlY3RlZCByZWFkb25seSB0cmFja0J5SW5kZXggPSAoaTogbnVtYmVyKTogbnVtYmVyID0+IGk7XG5cbiAgcHJvdGVjdGVkIGFkZENsYXNzKCk6IHZvaWQge1xuICAgIHRoaXMudXBkYXRlKChkKSA9PiAoeyBjbGFzc2VzOiBbLi4uZC5jbGFzc2VzLCB7IG5hbWU6ICcnLCBjb2xvcjogJyM4ODg4ODgnLCBzb3VyY2U6ICd1c2VyJyB9XSB9KSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVtb3ZlQ2xhc3MoaTogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy51cGRhdGUoKGQpID0+ICh7IGNsYXNzZXM6IGQuY2xhc3Nlcy5maWx0ZXIoKF8sIGspID0+IGsgIT09IGkpIH0pKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBwYXRjaENsYXNzKGk6IG51bWJlciwgcGF0Y2g6IFBhcnRpYWw8Q2xhc3NQcmVzZXQ+KTogdm9pZCB7XG4gICAgdGhpcy51cGRhdGUoKGQpID0+ICh7IGNsYXNzZXM6IGQuY2xhc3Nlcy5tYXAoKGMsIGspID0+IChrID09PSBpID8geyAuLi5jLCAuLi5wYXRjaCB9IDogYykpIH0pKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhZGRGYWxsYmFja0NvbG9yKCk6IHZvaWQge1xuICAgIHRoaXMudXBkYXRlKChkKSA9PiAoeyBmYWxsYmFja1BhbGV0dGU6IFsuLi5kLmZhbGxiYWNrUGFsZXR0ZSwgJyM4ODg4ODgnXSB9KSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVtb3ZlRmFsbGJhY2tDb2xvcihpOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLnVwZGF0ZSgoZCkgPT4gKHsgZmFsbGJhY2tQYWxldHRlOiBkLmZhbGxiYWNrUGFsZXR0ZS5maWx0ZXIoKF8sIGspID0+IGsgIT09IGkpIH0pKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzZXRGYWxsYmFja0NvbG9yKGk6IG51bWJlciwgY29sb3I6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMudXBkYXRlKChkKSA9PiAoeyBmYWxsYmFja1BhbGV0dGU6IGQuZmFsbGJhY2tQYWxldHRlLm1hcCgoYywgaykgPT4gKGsgPT09IGkgPyBjb2xvciA6IGMpKSB9KSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2V0QXV0b1Byb21vdGUoYXV0b1Byb21vdGU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLnVwZGF0ZSgoKSA9PiAoeyBhdXRvUHJvbW90ZSB9KSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2V0TWF0Y2hNb2RlKG1hdGNoTW9kZTogTWF0Y2hNb2RlKTogdm9pZCB7XG4gICAgdGhpcy51cGRhdGUoKCkgPT4gKHsgbWF0Y2hNb2RlIH0pKTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlKGNoYW5nZTogKGQ6IFByZXNldFNldCkgPT4gUGFydGlhbDxQcmVzZXRTZXQ+KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmRyYWZ0KSByZXR1cm47XG4gICAgdGhpcy5kcmFmdCA9IHsgLi4udGhpcy5kcmFmdCwgLi4uY2hhbmdlKHRoaXMuZHJhZnQpIH07XG4gICAgdGhpcy5kcmFmdENoYW5nZS5lbWl0KHRoaXMuZHJhZnQpO1xuICB9XG59XG4iLCI8cC1kaWFsb2dcbiAgaGVhZGVyPVwiTWFuYWdlIGFubm90YXRpb24gY2xhc3Nlc1wiXG4gIFt2aXNpYmxlXT1cInZpc2libGVcIlxuICAodmlzaWJsZUNoYW5nZSk9XCJ2aXNpYmxlQ2hhbmdlLmVtaXQoJGV2ZW50KVwiXG4gIFttb2RhbF09XCJ0cnVlXCJcbiAgYXBwZW5kVG89XCJib2R5XCJcbiAgW3N0eWxlXT1cInsgd2lkdGg6ICczNHJlbScgfVwiXG4gIFtkcmFnZ2FibGVdPVwidHJ1ZVwiXG4gIFtyZXNpemFibGVdPVwiZmFsc2VcIlxuPlxuICA8ZGl2ICpuZ0lmPVwiZHJhZnRcIiBjbGFzcz1cIm1hbmFnZS1kaWFsb2cgZmxleCBmbGV4LWNvbHVtbiBnYXAtMyBwdC0yXCI+XG4gICAgPGRpdiBjbGFzcz1cIm1hbmFnZS1jbGFzc2VzIGZsZXggZmxleC1jb2x1bW4gZ2FwLTJcIj5cbiAgICAgIDxkaXZcbiAgICAgICAgKm5nRm9yPVwibGV0IGMgb2YgZHJhZnQuY2xhc3NlczsgbGV0IGkgPSBpbmRleDsgdHJhY2tCeTogdHJhY2tCeUluZGV4XCJcbiAgICAgICAgY2xhc3M9XCJtYW5hZ2UtY2xhc3Mtcm93IGZsZXggYWxpZ24taXRlbXMtY2VudGVyIGdhcC0yXCJcbiAgICAgID5cbiAgICAgICAgPGhleC1jb2xvci1waWNrZXIgW2NvbG9yXT1cImMuY29sb3JcIiAoY29sb3JDaGFuZ2UpPVwicGF0Y2hDbGFzcyhpLCB7IGNvbG9yOiAkZXZlbnQgfSlcIj48L2hleC1jb2xvci1waWNrZXI+XG4gICAgICAgIDxpbnB1dFxuICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICBwSW5wdXRUZXh0XG4gICAgICAgICAgY2xhc3M9XCJwLWlucHV0dGV4dC1zbSBmbGV4LTFcIlxuICAgICAgICAgIFtuZ01vZGVsXT1cImMubmFtZVwiXG4gICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwicGF0Y2hDbGFzcyhpLCB7IG5hbWU6ICRldmVudCB9KVwiXG4gICAgICAgICAgcGxhY2Vob2xkZXI9XCJDbGFzcyBuYW1lXCJcbiAgICAgICAgICBhcmlhLWxhYmVsPVwiQ2xhc3MgbmFtZVwiXG4gICAgICAgIC8+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICBwQnV0dG9uXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgaWNvbj1cInBpIHBpLXRyYXNoXCJcbiAgICAgICAgICBjbGFzcz1cInAtYnV0dG9uLXNtIHAtYnV0dG9uLXRleHQgcC1idXR0b24td2FybmluZ1wiXG4gICAgICAgICAgcFRvb2x0aXA9XCJSZW1vdmUgY2xhc3NcIlxuICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgICAgICAgYXJpYS1sYWJlbD1cIlJlbW92ZSBjbGFzc1wiXG4gICAgICAgICAgKGNsaWNrKT1cInJlbW92ZUNsYXNzKGkpXCJcbiAgICAgICAgPjwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIHBCdXR0b25cbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIGljb249XCJwaSBwaS1wbHVzXCJcbiAgICAgICAgbGFiZWw9XCJBZGQgY2xhc3NcIlxuICAgICAgICBjbGFzcz1cInAtYnV0dG9uLXNtIHAtYnV0dG9uLXRleHQgYWxpZ24tc2VsZi1zdGFydFwiXG4gICAgICAgIChjbGljayk9XCJhZGRDbGFzcygpXCJcbiAgICAgID48L2J1dHRvbj5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJtYW5hZ2Utc2VjdGlvbiBmbGV4IGZsZXgtY29sdW1uIGdhcC0yXCI+XG4gICAgICA8c3BhbiBjbGFzcz1cInNlY3Rpb24tdGl0bGUgZm9udC1tZWRpdW1cIlxuICAgICAgICA+RmFsbGJhY2sgcGFsZXR0ZSA8c21hbGwgY2xhc3M9XCJ0ZXh0LWNvbG9yLXNlY29uZGFyeVwiPuKAlCBjb2xvdXJzIGZvciBjbGFzc2VzIG5vdCBsaXN0ZWQ8L3NtYWxsPjwvc3BhblxuICAgICAgPlxuICAgICAgPGRpdiBjbGFzcz1cImZhbGxiYWNrLXBhbGV0dGUgZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIgZmxleC13cmFwIGdhcC0yXCI+XG4gICAgICAgIDxzcGFuXG4gICAgICAgICAgKm5nRm9yPVwibGV0IGNvbCBvZiBkcmFmdC5mYWxsYmFja1BhbGV0dGU7IGxldCBpID0gaW5kZXg7IHRyYWNrQnk6IHRyYWNrQnlJbmRleFwiXG4gICAgICAgICAgY2xhc3M9XCJmYWxsYmFjay1zd2F0Y2ggZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIlxuICAgICAgICA+XG4gICAgICAgICAgPGhleC1jb2xvci1waWNrZXIgW2NvbG9yXT1cImNvbFwiIChjb2xvckNoYW5nZSk9XCJzZXRGYWxsYmFja0NvbG9yKGksICRldmVudClcIj48L2hleC1jb2xvci1waWNrZXI+XG4gICAgICAgICAgPGlcbiAgICAgICAgICAgIGNsYXNzPVwicGkgcGktdGltZXMgaWNvbi1ob3ZlciBtbC0xXCJcbiAgICAgICAgICAgIHBUb29sdGlwPVwiUmVtb3ZlXCJcbiAgICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgICAgICAgICAoY2xpY2spPVwicmVtb3ZlRmFsbGJhY2tDb2xvcihpKVwiXG4gICAgICAgICAgPjwvaT5cbiAgICAgICAgPC9zcGFuPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgcEJ1dHRvblxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIGljb249XCJwaSBwaS1wbHVzXCJcbiAgICAgICAgICBjbGFzcz1cInAtYnV0dG9uLXNtIHAtYnV0dG9uLXRleHRcIlxuICAgICAgICAgIHBUb29sdGlwPVwiQWRkIGZhbGxiYWNrIGNvbG91clwiXG4gICAgICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAgICAgICBhcmlhLWxhYmVsPVwiQWRkIGZhbGxiYWNrIGNvbG91clwiXG4gICAgICAgICAgKGNsaWNrKT1cImFkZEZhbGxiYWNrQ29sb3IoKVwiXG4gICAgICAgID48L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cImZsZXggYWxpZ24taXRlbXMtY2VudGVyIGdhcC0yXCI+XG4gICAgICA8cC1jaGVja2JveFxuICAgICAgICBbbmdNb2RlbF09XCJkcmFmdC5hdXRvUHJvbW90ZVwiXG4gICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInNldEF1dG9Qcm9tb3RlKCRldmVudClcIlxuICAgICAgICBbYmluYXJ5XT1cInRydWVcIlxuICAgICAgICBpbnB1dElkPVwiYXV0b1Byb21vdGVcIlxuICAgICAgPjwvcC1jaGVja2JveD5cbiAgICAgIDxsYWJlbCBmb3I9XCJhdXRvUHJvbW90ZVwiPkF1dG8tYWRkIGRldGVjdGVkIGNsYXNzZXMgdG8gdGhpcyBsaXN0IGFzIHRoZXkgYXBwZWFyPC9sYWJlbD5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJmbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBnYXAtM1wiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJmb250LW1lZGl1bVwiPkxhYmVsIG1hdGNoaW5nPC9zcGFuPlxuICAgICAgPHAtc2VsZWN0QnV0dG9uXG4gICAgICAgIFtvcHRpb25zXT1cIm1hdGNoTW9kZU9wdGlvbnNcIlxuICAgICAgICBbbmdNb2RlbF09XCJkcmFmdC5tYXRjaE1vZGVcIlxuICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJzZXRNYXRjaE1vZGUoJGV2ZW50KVwiXG4gICAgICAgIG9wdGlvbkxhYmVsPVwibGFiZWxcIlxuICAgICAgICBvcHRpb25WYWx1ZT1cInZhbHVlXCJcbiAgICAgID48L3Atc2VsZWN0QnV0dG9uPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cblxuICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiZm9vdGVyXCI+XG4gICAgPGRpdiBjbGFzcz1cIm1hbmFnZS1mb290ZXIgZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIgZmxleC13cmFwIGdhcC0yIHctZnVsbFwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJmbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBmbGV4LXdyYXAgZ2FwLTFcIj5cbiAgICAgICAgPHAtYnV0dG9uIGxhYmVsPVwiUmVzZXRcIiBpY29uPVwicGkgcGktcmVmcmVzaFwiIFt0ZXh0XT1cInRydWVcIiAob25DbGljayk9XCJyZXNldERlZmF1bHRzLmVtaXQoKVwiPjwvcC1idXR0b24+XG4gICAgICAgIDxwLWJ1dHRvbiBsYWJlbD1cIkltcG9ydFwiIGljb249XCJwaSBwaS11cGxvYWRcIiBbdGV4dF09XCJ0cnVlXCIgKG9uQ2xpY2spPVwicHJlc2V0RmlsZUlucHV0LmNsaWNrKClcIj48L3AtYnV0dG9uPlxuICAgICAgICA8aW5wdXRcbiAgICAgICAgICAjcHJlc2V0RmlsZUlucHV0XG4gICAgICAgICAgdHlwZT1cImZpbGVcIlxuICAgICAgICAgIGFjY2VwdD1cIi5qc29uLGFwcGxpY2F0aW9uL2pzb25cIlxuICAgICAgICAgIGhpZGRlblxuICAgICAgICAgIChjaGFuZ2UpPVwiaW1wb3J0RmlsZS5lbWl0KCRldmVudCk7IHByZXNldEZpbGVJbnB1dC52YWx1ZSA9ICcnXCJcbiAgICAgICAgLz5cbiAgICAgICAgPHAtYnV0dG9uIGxhYmVsPVwiRXhwb3J0XCIgaWNvbj1cInBpIHBpLWRvd25sb2FkXCIgW3RleHRdPVwidHJ1ZVwiIChvbkNsaWNrKT1cImV4cG9ydC5lbWl0KClcIj48L3AtYnV0dG9uPlxuICAgICAgPC9zcGFuPlxuICAgICAgPHNwYW4gY2xhc3M9XCJmbGV4LTFcIj48L3NwYW4+XG4gICAgICA8IS0tIEFwcGx5IHBlcnNpc3RzIHRvIHRoZSBzZXJ2ZXIgYW5kIGNsb3Nlcy4gLS0+XG4gICAgICA8cC1idXR0b24gbGFiZWw9XCJBcHBseVwiIGljb249XCJwaSBwaS1jaGVja1wiIChvbkNsaWNrKT1cImFwcGx5LmVtaXQoKVwiPjwvcC1idXR0b24+XG4gICAgPC9kaXY+XG4gIDwvbmctdGVtcGxhdGU+XG48L3AtZGlhbG9nPlxuIl19
@@ -0,0 +1,98 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { Observable } from 'rxjs';
3
+ import { maskScaleFor, regionToParts, scaleParts } from './mask-raster';
4
+ import * as i0 from "@angular/core";
5
+ /**
6
+ * Rasterizes regions to a label-mask PNG in a Web Worker (jit-ui#95), so the
7
+ * full-resolution rasterize and PNG encode never freeze the UI and the job can
8
+ * be cancelled. Component-agnostic: {@link export} returns a cold Observable —
9
+ * subscribing starts a worker, unsubscribing terminates it (cancel), and a
10
+ * worker failure is an error carrying a user-facing message. Whole-slide
11
+ * images are capped to a safe pixel budget (the geometry is scaled to match).
12
+ */
13
+ export class MaskExportService {
14
+ export(request) {
15
+ return new Observable((subscriber) => {
16
+ const { imageSize: size } = request;
17
+ const scale = maskScaleFor(size.width, size.height);
18
+ const width = Math.max(1, Math.round(size.width * scale));
19
+ const height = Math.max(1, Math.round(size.height * scale));
20
+ subscriber.next({ type: 'planned', width, height, scale });
21
+ const payload = {
22
+ width,
23
+ height,
24
+ originalWidth: size.width,
25
+ originalHeight: size.height,
26
+ scale,
27
+ mode: request.mode,
28
+ sourceName: request.sourceName,
29
+ regions: request.regions.map((r) => scaleParts(regionToParts(r), scale)),
30
+ };
31
+ let worker;
32
+ let closed = false;
33
+ const stop = () => {
34
+ worker?.terminate();
35
+ worker = undefined;
36
+ };
37
+ const fail = (message) => {
38
+ stop();
39
+ subscriber.error(new Error(message));
40
+ };
41
+ // The worker is created asynchronously; a cancel while it loads
42
+ // terminates it as soon as it resolves, before it is sent any work.
43
+ this.createWorker()
44
+ .then((w) => {
45
+ if (closed) {
46
+ w.terminate();
47
+ return;
48
+ }
49
+ worker = w;
50
+ w.onmessage = ({ data }) => {
51
+ switch (data?.type) {
52
+ case 'progress':
53
+ subscriber.next({
54
+ type: 'progress',
55
+ percent: data.total ? Math.round((data.done / data.total) * 100) : 0,
56
+ });
57
+ break;
58
+ case 'encoding':
59
+ subscriber.next({ type: 'encoding' });
60
+ break;
61
+ case 'done':
62
+ stop();
63
+ subscriber.next({ type: 'done', blob: new Blob([data.png], { type: 'image/png' }) });
64
+ subscriber.complete();
65
+ break;
66
+ case 'error':
67
+ fail(data.error || 'The mask could not be generated.');
68
+ break;
69
+ }
70
+ };
71
+ w.onerror = () => fail('The mask worker failed.');
72
+ w.postMessage(payload);
73
+ })
74
+ .catch(() => {
75
+ if (!closed)
76
+ fail('The mask worker failed to start.');
77
+ });
78
+ return () => {
79
+ closed = true;
80
+ stop();
81
+ };
82
+ });
83
+ }
84
+ /** Worker factory: a dynamic import, so the worker module (and its
85
+ * `import.meta.url`, which the CommonJS test compile rejects) loads lazily.
86
+ * Overridable in tests. */
87
+ async createWorker() {
88
+ const { createMaskWorker } = await import('./mask-worker');
89
+ return createMaskWorker();
90
+ }
91
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: MaskExportService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
92
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: MaskExportService, providedIn: 'root' }); }
93
+ }
94
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: MaskExportService, decorators: [{
95
+ type: Injectable,
96
+ args: [{ providedIn: 'root' }]
97
+ }] });
98
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFzay1leHBvcnQuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvcmVnaW9uLWVkaXRvci9tYXNrLWV4cG9ydC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUdsQyxPQUFPLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBd0J4RTs7Ozs7OztHQU9HO0FBRUgsTUFBTSxPQUFPLGlCQUFpQjtJQUM1QixNQUFNLENBQUMsT0FBMEI7UUFDL0IsT0FBTyxJQUFJLFVBQVUsQ0FBa0IsQ0FBQyxVQUFVLEVBQUUsRUFBRTtZQUNwRCxNQUFNLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxHQUFHLE9BQU8sQ0FBQztZQUNwQyxNQUFNLEtBQUssR0FBRyxZQUFZLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDcEQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDMUQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDNUQsVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBRTNELE1BQU0sT0FBTyxHQUFHO2dCQUNkLEtBQUs7Z0JBQ0wsTUFBTTtnQkFDTixhQUFh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RSxDQUFDO1lBQ1QsQ0FBQyxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7O2dDQUU0QjtJQUNsQixLQUFLLENBQUMsWUFBWTtRQUMxQixNQUFNLEVBQUUsZ0JBQWdCLEVBQUUsR0FBRyxNQUFNLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUMzRCxPQUFPLGdCQUFnQixFQUFFLENBQUM7SUFDNUIsQ0FBQzs4R0FqRlUsaUJBQWlCO2tIQUFqQixpQkFBaUIsY0FESixNQUFNOzsyRkFDbkIsaUJBQWlCO2tCQUQ3QixVQUFVO21CQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgUmVnaW9uIH0gZnJvbSAnLi4vbW9kZWxzL3JlZ2lvbic7XG5pbXBvcnQgeyBtYXNrU2NhbGVGb3IsIHJlZ2lvblRvUGFydHMsIHNjYWxlUGFydHMgfSBmcm9tICcuL21hc2stcmFzdGVyJztcblxuLyoqIE1hc2sgdHlwZTogb25lIGZvcmVncm91bmQgdmFsdWUsIG9yIGEgZGlzdGluY3QgaWQgcGVyIHJlZ2lvbi4gKi9cbmV4cG9ydCB0eXBlIE1hc2tNb2RlID0gJ2JpbmFyeScgfCAnbXVsdGljbGFzcyc7XG5cbi8qKiBXaGF0IHRvIHJhc3Rlcml6ZSwgYXQgdGhlIGZ1bGwgaW1hZ2Ugc2l6ZS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWFza0V4cG9ydFJlcXVlc3Qge1xuICByZWdpb25zOiBSZWdpb25bXTtcbiAgaW1hZ2VTaXplOiB7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH07XG4gIG1vZGU6IE1hc2tNb2RlO1xuICAvKiogUmVjb3JkZWQgaW4gdGhlIFBORyBtZXRhZGF0YS4gKi9cbiAgc291cmNlTmFtZT86IHN0cmluZztcbn1cblxuLyoqIFByb2dyZXNzIG9mIG9uZSBtYXNrIGV4cG9ydCwgaW4gb3JkZXI6IHBsYW5uZWQg4oaSIHByb2dyZXNzKiDihpIgZW5jb2Rpbmcg4oaSIGRvbmUuICovXG5leHBvcnQgdHlwZSBNYXNrRXhwb3J0RXZlbnQgPVxuICAvKiogVGhlIG1hc2sgc2l6ZTsgYHNjYWxlYCA8IDEgd2hlbiB0aGUgaW1hZ2UgZXhjZWVkcyB0aGUgcGl4ZWwgYnVkZ2V0LiAqL1xuICB8IHsgdHlwZTogJ3BsYW5uZWQnOyB3aWR0aDogbnVtYmVyOyBoZWlnaHQ6IG51bWJlcjsgc2NhbGU6IG51bWJlciB9XG4gIC8qKiAw4oCTMTAwIHJhc3Rlcml6YXRpb24gcHJvZ3Jlc3MuICovXG4gIHwgeyB0eXBlOiAncHJvZ3Jlc3MnOyBwZXJjZW50OiBudW1iZXIgfVxuICAvKiogUmFzdGVyaXppbmcgZmluaXNoZWQ7IHRoZSBQTkcgaXMgYmVpbmcgZW5jb2RlZC4gKi9cbiAgfCB7IHR5cGU6ICdlbmNvZGluZycgfVxuICB8IHsgdHlwZTogJ2RvbmUnOyBibG9iOiBCbG9iIH07XG5cbi8qKlxuICogUmFzdGVyaXplcyByZWdpb25zIHRvIGEgbGFiZWwtbWFzayBQTkcgaW4gYSBXZWIgV29ya2VyIChqaXQtdWkjOTUpLCBzbyB0aGVcbiAqIGZ1bGwtcmVzb2x1dGlvbiByYXN0ZXJpemUgYW5kIFBORyBlbmNvZGUgbmV2ZXIgZnJlZXplIHRoZSBVSSBhbmQgdGhlIGpvYiBjYW5cbiAqIGJlIGNhbmNlbGxlZC4gQ29tcG9uZW50LWFnbm9zdGljOiB7QGxpbmsgZXhwb3J0fSByZXR1cm5zIGEgY29sZCBPYnNlcnZhYmxlIOKAlFxuICogc3Vic2NyaWJpbmcgc3RhcnRzIGEgd29ya2VyLCB1bnN1YnNjcmliaW5nIHRlcm1pbmF0ZXMgaXQgKGNhbmNlbCksIGFuZCBhXG4gKiB3b3JrZXIgZmFpbHVyZSBpcyBhbiBlcnJvciBjYXJyeWluZyBhIHVzZXItZmFjaW5nIG1lc3NhZ2UuIFdob2xlLXNsaWRlXG4gKiBpbWFnZXMgYXJlIGNhcHBlZCB0byBhIHNhZmUgcGl4ZWwgYnVkZ2V0ICh0aGUgZ2VvbWV0cnkgaXMgc2NhbGVkIHRvIG1hdGNoKS5cbiAqL1xuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcbmV4cG9ydCBjbGFzcyBNYXNrRXhwb3J0U2VydmljZSB7XG4gIGV4cG9ydChyZXF1ZXN0OiBNYXNrRXhwb3J0UmVxdWVzdCk6IE9ic2VydmFibGU8TWFza0V4cG9ydEV2ZW50PiB7XG4gICAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlPE1hc2tFeHBvcnRFdmVudD4oKHN1YnNjcmliZXIpID0+IHtcbiAgICAgIGNvbnN0IHsgaW1hZ2VTaXplOiBzaXplIH0gPSByZXF1ZXN0O1xuICAgICAgY29uc3Qgc2NhbGUgPSBtYXNrU2NhbGVGb3Ioc2l6ZS53aWR0aCwgc2l6ZS5oZWlnaHQpO1xuICAgICAgY29uc3Qgd2lkdGggPSBNYXRoLm1heCgxLCBNYXRoLnJvdW5kKHNpemUud2lkdGggKiBzY2FsZSkpO1xuICAgICAgY29uc3QgaGVpZ2h0ID0gTWF0aC5tYXgoMSwgTWF0aC5yb3VuZChzaXplLmhlaWdodCAqIHNjYWxlKSk7XG4gICAgICBzdWJzY3JpYmVyLm5leHQoeyB0eXBlOiAncGxhbm5lZCcsIHdpZHRoLCBoZWlnaHQsIHNjYWxlIH0pO1xuXG4gICAgICBjb25zdCBwYXlsb2FkID0ge1xuICAgICAgICB3aWR0aCxcbiAgICAgICAgaGVpZ2h0LFxuICAgICAgICBvcmlnaW5hbFdpZHRoOiBzaXplLndpZHRoLFxuICAgICAgICBvcmlnaW5hbEhlaWdodDogc2l6ZS5oZWlnaHQsXG4gICAgICAgIHNjYWxlLFxuICAgICAgICBtb2RlOiByZXF1ZXN0Lm1vZGUsXG4gICAgICAgIHNvdXJjZU5hbWU6IHJlcXVlc3Quc291cmNlTmFtZSxcbiAgICAgICAgcmVnaW9uczogcmVxdWVzdC5yZWdpb25zLm1hcCgocikgPT4gc2NhbGVQYXJ0cyhyZWdpb25Ub1BhcnRzKHIpLCBzY2FsZSkpLFxuICAgICAgfTtcblxuICAgICAgbGV0IHdvcmtlcjogV29ya2VyIHwgdW5kZWZpbmVkO1xuICAgICAgbGV0IGNsb3NlZCA9IGZhbHNlO1xuICAgICAgY29uc3Qgc3RvcCA9ICgpID0+IHtcbiAgICAgICAgd29ya2VyPy50ZXJtaW5hdGUoKTtcbiAgICAgICAgd29ya2VyID0gdW5kZWZpbmVkO1xuICAgICAgfTtcbiAgICAgIGNvbnN0IGZhaWwgPSAobWVzc2FnZTogc3RyaW5nKSA9PiB7XG4gICAgICAgIHN0b3AoKTtcbiAgICAgICAgc3Vic2NyaWJlci5lcnJvcihuZXcgRXJyb3IobWVzc2FnZSkpO1xuICAgICAgfTtcblxuICAgICAgLy8gVGhlIHdvcmtlciBpcyBjcmVhdGVkIGFzeW5jaHJvbm91c2x5OyBhIGNhbmNlbCB3aGlsZSBpdCBsb2Fkc1xuICAgICAgLy8gdGVybWluYXRlcyBpdCBhcyBzb29uIGFzIGl0IHJlc29sdmVzLCBiZWZvcmUgaXQgaXMgc2VudCBhbnkgd29yay5cbiAgICAgIHRoaXMuY3JlYXRlV29ya2VyKClcbiAgICAgICAgLnRoZW4oKHcpID0+IHtcbiAgICAgICAgICBpZiAoY2xvc2VkKSB7XG4gICAgICAgICAgICB3LnRlcm1pbmF0ZSgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICB3b3JrZXIgPSB3O1xuICAgICAgICAgIHcub25tZXNzYWdlID0gKHsgZGF0YSB9OiBNZXNzYWdlRXZlbnQpID0+IHtcbiAgICAgICAgICAgIHN3aXRjaCAoZGF0YT8udHlwZSkge1xuICAgICAgICAgICAgICBjYXNlICdwcm9ncmVzcyc6XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlci5uZXh0KHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdwcm9ncmVzcycsXG4gICAgICAgICAgICAgICAgICBwZXJjZW50OiBkYXRhLnRvdGFsID8gTWF0aC5yb3VuZCgoZGF0YS5kb25lIC8gZGF0YS50b3RhbCkgKiAxMDApIDogMCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgY2FzZSAnZW5jb2RpbmcnOlxuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIubmV4dCh7IHR5cGU6ICdlbmNvZGluZycgfSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgJ2RvbmUnOlxuICAgICAgICAgICAgICAgIHN0b3AoKTtcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVyLm5leHQoeyB0eXBlOiAnZG9uZScsIGJsb2I6IG5ldyBCbG9iKFtkYXRhLnBuZ10sIHsgdHlwZTogJ2ltYWdlL3BuZycgfSkgfSk7XG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlci5jb21wbGV0ZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBjYXNlICdlcnJvcic6XG4gICAgICAgICAgICAgICAgZmFpbChkYXRhLmVycm9yIHx8ICdUaGUgbWFzayBjb3VsZCBub3QgYmUgZ2VuZXJhdGVkLicpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH07XG4gICAgICAgICAgdy5vbmVycm9yID0gKCkgPT4gZmFpbCgnVGhlIG1hc2sgd29ya2VyIGZhaWxlZC4nKTtcbiAgICAgICAgICB3LnBvc3RNZXNzYWdlKHBheWxvYWQpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgIGlmICghY2xvc2VkKSBmYWlsKCdUaGUgbWFzayB3b3JrZXIgZmFpbGVkIHRvIHN0YXJ0LicpO1xuICAgICAgICB9KTtcblxuICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY2xvc2VkID0gdHJ1ZTtcbiAgICAgICAgc3RvcCgpO1xuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBXb3JrZXIgZmFjdG9yeTogYSBkeW5hbWljIGltcG9ydCwgc28gdGhlIHdvcmtlciBtb2R1bGUgKGFuZCBpdHNcbiAgICogIGBpbXBvcnQubWV0YS51cmxgLCB3aGljaCB0aGUgQ29tbW9uSlMgdGVzdCBjb21waWxlIHJlamVjdHMpIGxvYWRzIGxhemlseS5cbiAgICogIE92ZXJyaWRhYmxlIGluIHRlc3RzLiAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgY3JlYXRlV29ya2VyKCk6IFByb21pc2U8V29ya2VyPiB7XG4gICAgY29uc3QgeyBjcmVhdGVNYXNrV29ya2VyIH0gPSBhd2FpdCBpbXBvcnQoJy4vbWFzay13b3JrZXInKTtcbiAgICByZXR1cm4gY3JlYXRlTWFza1dvcmtlcigpO1xuICB9XG59XG4iXX0=