@jax-data-science/sci-image-visualizer 0.8.3 → 0.9.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.
- package/README.md +201 -460
- package/esm2022/index.mjs +28 -15
- package/esm2022/lib/channel-histogram/channel-histogram.component.mjs +163 -91
- package/esm2022/lib/contracts/capabilities.contract.mjs +4 -3
- package/esm2022/lib/contracts/cell-segmenter.contract.mjs +1 -1
- package/esm2022/lib/contracts/channel-histogram-api.contract.mjs +5 -1
- package/esm2022/lib/contracts/color.mjs +60 -0
- package/esm2022/lib/contracts/colormap-lut.mjs +213 -57
- package/esm2022/lib/contracts/coordinate-transform.contract.mjs +1 -1
- package/esm2022/lib/contracts/display-types.mjs +11 -1
- package/esm2022/lib/contracts/instance-segmenter.contract.mjs +1 -1
- package/esm2022/lib/contracts/intensity.mjs +48 -5
- package/esm2022/lib/contracts/plot-type-contribution.contract.mjs +1 -1
- package/esm2022/lib/contracts/plot-type.mjs +134 -17
- package/esm2022/lib/contracts/ports/image-state.port.mjs +4 -1
- package/esm2022/lib/contracts/ports/preferences.port.mjs +5 -1
- package/esm2022/lib/contracts/ports/region-io.port.mjs +2 -1
- package/esm2022/lib/contracts/ports/spatial-data.port.mjs +5 -1
- package/esm2022/lib/contracts/ports/tile-access.port.mjs +2 -1
- package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
- package/esm2022/lib/contracts/region-overlay.contract.mjs +1 -1
- package/esm2022/lib/contracts/sam.contract.mjs +1 -1
- package/esm2022/lib/contracts/semantic-segmenter.contract.mjs +1 -1
- package/esm2022/lib/contracts/spatial-dataset.contract.mjs +3 -1
- package/esm2022/lib/contracts/toolbar-tool.contract.mjs +6 -4
- package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
- package/esm2022/lib/contracts/viz-config.mjs +2 -1
- package/esm2022/lib/geometry/contour.mjs +63 -0
- package/esm2022/lib/geometry/raster.mjs +98 -0
- package/esm2022/lib/geometry/ring.mjs +201 -0
- package/esm2022/lib/hex-color-picker/hex-color-picker.component.mjs +202 -102
- package/esm2022/lib/implementations/base-store-visualizer.mjs +201 -48
- package/esm2022/lib/implementations/napari-js/napari-axes-gizmo.mjs +65 -0
- package/esm2022/lib/implementations/napari-js/napari-display-state.mjs +136 -0
- package/esm2022/lib/implementations/napari-js/napari-helpers.mjs +199 -0
- package/esm2022/lib/implementations/napari-js/napari-image-2d-scene.mjs +602 -0
- package/esm2022/lib/implementations/napari-js/napari-loading-badge.mjs +3 -4
- package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +66 -0
- package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +157 -591
- package/esm2022/lib/implementations/napari-js/napari-scene.mjs +2 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-2d-scene.mjs +614 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +769 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-encoding.mjs +199 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +263 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-scene.mjs +159 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-tiles.mjs +106 -1408
- package/esm2022/lib/implementations/napari-js/napari-spatial-tooltip.mjs +2 -2
- package/esm2022/lib/implementations/napari-js/napari-surface-scene.mjs +271 -0
- package/esm2022/lib/implementations/napari-js/napari-tile-client.mjs +562 -0
- package/esm2022/lib/implementations/napari-js/napari-tool-bridge.mjs +344 -0
- package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +358 -4218
- package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +439 -0
- package/esm2022/lib/implementations/napari-js/napari-volume-z-handle.mjs +6 -6
- package/esm2022/lib/implementations/napari-js/region-overlay/overlay-projection.mjs +96 -0
- package/esm2022/lib/implementations/napari-js/region-overlay/region-edit.mjs +35 -0
- package/esm2022/lib/implementations/napari-js/region-overlay/region-svg-renderer.mjs +182 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/categorical-lookup.mjs +30 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/cell-layers.mjs +274 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/density-layer.mjs +144 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/layer-groups.mjs +165 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/plan-context.mjs +78 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-hover.mjs +182 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-jobs.mjs +369 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-layers.mjs +306 -0
- package/esm2022/lib/implementations/osd/display-pipeline.mjs +102 -40
- package/esm2022/lib/implementations/osd/histogram-sampler.mjs +56 -31
- package/esm2022/lib/implementations/osd/openseadragon-viewer-options.mjs +128 -0
- package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +333 -1685
- package/esm2022/lib/implementations/osd/osd-coordinate-transform.mjs +1 -1
- package/esm2022/lib/implementations/osd/osd-coords.mjs +5 -6
- package/esm2022/lib/implementations/osd/osd-export.mjs +122 -0
- package/esm2022/lib/implementations/osd/osd-lib.mjs +15 -1
- package/esm2022/lib/implementations/osd/osd-navigator-chrome.mjs +205 -0
- package/esm2022/lib/implementations/osd/osd-pixel-readback.mjs +68 -0
- package/esm2022/lib/implementations/osd/osd-region-overlay-draw.mjs +153 -0
- package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +185 -718
- package/esm2022/lib/implementations/osd/osd-scale-bar.mjs +52 -60
- package/esm2022/lib/implementations/osd/osd-tile-source.mjs +105 -0
- package/esm2022/lib/implementations/osd/osd-viewer-like.mjs +2 -0
- package/esm2022/lib/implementations/osd/osd-viewer-mount.mjs +44 -0
- package/esm2022/lib/implementations/osd/osd-viewport.mjs +184 -0
- package/esm2022/lib/implementations/osd/osd-zoom.mjs +7 -1
- package/esm2022/lib/implementations/osd/simple-source.mjs +395 -0
- package/esm2022/lib/implementations/osd/slice-cache.mjs +53 -48
- package/esm2022/lib/implementations/osd/tile-client.mjs +32 -11
- package/esm2022/lib/implementations/osd/tile-recolor.mjs +330 -0
- package/esm2022/lib/implementations/plotly/omics-trace-builders.mjs +161 -73
- package/esm2022/lib/implementations/plotly/plotly-coordinate-transform.mjs +1 -1
- package/esm2022/lib/implementations/plotly/plotly-image-loader.mjs +112 -0
- package/esm2022/lib/implementations/plotly/plotly-image-recolor.mjs +178 -0
- package/esm2022/lib/implementations/plotly/plotly-intensity-inset.mjs +33 -0
- package/esm2022/lib/implementations/plotly/plotly-isosurface-controls.mjs +83 -0
- package/esm2022/lib/implementations/plotly/plotly-layouts.mjs +121 -0
- package/esm2022/lib/implementations/plotly/plotly-readback.mjs +117 -0
- package/esm2022/lib/implementations/plotly/plotly-region-overlay.mjs +19 -10
- package/esm2022/lib/implementations/plotly/plotly-shape-projection.mjs +223 -0
- package/esm2022/lib/implementations/plotly/plotly-trace-builders.mjs +79 -19
- package/esm2022/lib/implementations/plotly/plotly-zoom-controller.mjs +223 -0
- package/esm2022/lib/implementations/plotly/plotly.service.mjs +439 -1655
- package/esm2022/lib/implementations/region-centroids.mjs +47 -0
- package/esm2022/lib/implementations/simple-slice-access.service.mjs +22 -12
- package/esm2022/lib/implementations/spatial-data-http/spatial-data-http.service.mjs +172 -92
- package/esm2022/lib/implementations/spatial-data-http/spatial-wire.mjs +103 -22
- package/esm2022/lib/implementations/tile-server/index.mjs +6 -0
- package/esm2022/lib/implementations/tile-server/native-histogram.mjs +30 -0
- package/esm2022/lib/implementations/tile-server/poll-descriptor.mjs +65 -0
- package/esm2022/lib/implementations/tile-server/tile-protocol.mjs +42 -0
- package/esm2022/lib/implementations/tile-server/transport.mjs +135 -0
- package/esm2022/lib/intensity/intensity-profile.mjs +107 -0
- package/esm2022/lib/intensity/intensity-profile.service.mjs +223 -0
- package/esm2022/lib/intensity-inset/intensity-inset.component.mjs +133 -0
- package/esm2022/lib/models/bezier.mjs +1 -11
- package/esm2022/lib/models/class-preset.mjs +41 -3
- package/esm2022/lib/models/geometry.mjs +27 -164
- package/esm2022/lib/models/polygon-edit.mjs +254 -0
- package/esm2022/lib/models/polygon-factory.mjs +118 -0
- package/esm2022/lib/models/region-clone.mjs +68 -0
- package/esm2022/lib/models/region-geojson.mjs +373 -0
- package/esm2022/lib/models/region.mjs +34 -33
- package/esm2022/lib/models/shape.mjs +18 -16
- package/esm2022/lib/plot-mode/contribution-host.mjs +297 -0
- package/esm2022/lib/plot-mode/plot-mode-controller.mjs +9 -6
- package/esm2022/lib/plot-mode/plot-type-menu.mjs +85 -0
- package/esm2022/lib/plot-mode/tool-params-model.mjs +87 -0
- package/esm2022/lib/plot.utilities.mjs +296 -473
- package/esm2022/lib/processing/image-crop.mjs +1 -1
- package/esm2022/lib/processing/processing-image.mjs +28 -15
- package/esm2022/lib/provide-visualization.mjs +40 -14
- package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +99 -0
- package/esm2022/lib/region-editor/file-stem.mjs +13 -0
- package/esm2022/lib/region-editor/manage-classes-dialog/manage-classes-dialog.component.mjs +118 -0
- package/esm2022/lib/region-editor/mask-export.service.mjs +98 -0
- package/esm2022/lib/region-editor/mask-raster.mjs +11 -5
- package/esm2022/lib/region-editor/region-color-dialog/region-color-dialog.component.mjs +56 -0
- package/esm2022/lib/region-editor/region-editor-help/region-editor-help.component.mjs +28 -0
- package/esm2022/lib/region-editor/region-editor.component.mjs +402 -651
- package/esm2022/lib/region-editor/region-metrics.mjs +68 -0
- package/esm2022/lib/region-editor/region-persistence.service.mjs +134 -0
- package/esm2022/lib/region-editor/region-table/region-table.component.mjs +153 -0
- package/esm2022/lib/region-editor/save-mask-dialog/save-mask-dialog.component.mjs +91 -0
- package/esm2022/lib/region-editor/save-regions-dialog/save-regions-dialog.component.mjs +92 -0
- package/esm2022/lib/region-ops.service.mjs +28 -70
- package/esm2022/lib/region-overlay/region-geometry.mjs +360 -0
- package/esm2022/lib/region-overlay/region-hit-test.mjs +103 -0
- package/esm2022/lib/region-overlay/svg-region-renderer.mjs +228 -0
- package/esm2022/lib/render-orchestrator.mjs +14 -11
- package/esm2022/lib/render-session.mjs +207 -0
- package/esm2022/lib/routing-visualizer.service.mjs +459 -411
- package/esm2022/lib/spatial/density-raster.mjs +14 -0
- package/esm2022/lib/spatial/embedding-compute-coordinator.mjs +239 -0
- package/esm2022/lib/spatial/embedding-compute.mjs +43 -10
- package/esm2022/lib/spatial/gene-search.mjs +1 -1
- package/esm2022/lib/spatial/glyphs.mjs +97 -0
- package/esm2022/lib/spatial/lod.mjs +187 -0
- package/esm2022/lib/spatial/spatial-controls.facade.mjs +200 -0
- package/esm2022/lib/spatial/spatial-density.mjs +25 -16
- package/esm2022/lib/spatial/spatial-encoding.mjs +26 -82
- package/esm2022/lib/spatial/spatial-expression.mjs +43 -42
- package/esm2022/lib/spatial/spatial-framing.mjs +1 -1
- package/esm2022/lib/spatial/spatial-heatmap.mjs +6 -3
- package/esm2022/lib/spatial/spatial-hover.mjs +5 -33
- package/esm2022/lib/spatial/spatial-panel-model.mjs +282 -0
- package/esm2022/lib/spatial/spatial-sections.mjs +1 -1
- package/esm2022/lib/spatial/spatial-selection.mjs +33 -46
- package/esm2022/lib/spatial/spatial-tile-merge.mjs +219 -0
- package/esm2022/lib/spatial/spatial-tiles.mjs +12 -648
- package/esm2022/lib/spatial/spatial-volume-image.mjs +2 -4
- package/esm2022/lib/spatial/stats.mjs +71 -0
- package/esm2022/lib/spatial/transcript-grouping.mjs +307 -0
- package/esm2022/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.mjs +150 -0
- package/esm2022/lib/spatial-controls/spatial-charts/chart-data-model.mjs +309 -0
- package/esm2022/lib/spatial-controls/spatial-charts/chart-help.mjs +145 -0
- package/esm2022/lib/spatial-controls/spatial-charts/plotly-chart-host.mjs +158 -0
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-chart-window/spatial-chart-window.component.mjs +47 -0
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-charts.component.mjs +297 -802
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-embedding-controls/spatial-embedding-controls.component.mjs +89 -0
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-heatmap-controls/spatial-heatmap-controls.component.mjs +52 -0
- package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +143 -1238
- package/esm2022/lib/spatial-controls/spatial-gene-picker.mjs +153 -0
- package/esm2022/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.mjs +241 -0
- package/esm2022/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.mjs +193 -0
- package/esm2022/lib/spatial-controls/spatial-key/spatial-key.component.mjs +132 -0
- package/esm2022/lib/spatial-controls/spatial-key/spatial-key.model.mjs +67 -0
- package/esm2022/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.mjs +147 -0
- package/esm2022/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.mjs +300 -0
- package/esm2022/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.mjs +370 -0
- package/esm2022/lib/store/class-color.util.mjs +46 -3
- package/esm2022/lib/store/region-history.mjs +146 -0
- package/esm2022/lib/store/region-scope-cache.mjs +140 -0
- package/esm2022/lib/store/region-selection.mjs +82 -0
- package/esm2022/lib/store/region-store.service.mjs +279 -675
- package/esm2022/lib/store/spatial-selection.service.mjs +2 -2
- package/esm2022/lib/store/visualizer-store.service.mjs +49 -71
- package/esm2022/lib/toast-outlets.mjs +5 -4
- package/esm2022/lib/toolbar/brush/brush-tool.service.mjs +92 -434
- package/esm2022/lib/toolbar/canvas-tools.mjs +20 -0
- package/esm2022/lib/toolbar/crop/slide-crop.mjs +26 -42
- package/esm2022/lib/toolbar/plot-type-selector/plot-type-selector.component.mjs +85 -0
- package/esm2022/lib/toolbar/region-tools/region-tool-buttons.mjs +74 -0
- package/esm2022/lib/toolbar/region-tools/region-tools.component.mjs +114 -0
- package/esm2022/lib/toolbar/segmentation/cell-segment-tool.service.mjs +74 -78
- package/esm2022/lib/toolbar/segmentation/cellpose-segmenter.service.mjs +50 -8
- package/esm2022/lib/toolbar/segmentation/onnx-sam-session.mjs +61 -42
- package/esm2022/lib/toolbar/segmentation/pending-calls.mjs +47 -0
- package/esm2022/lib/toolbar/segmentation/sam-model-registry.mjs +12 -4
- package/esm2022/lib/toolbar/segmentation/sam-onnx-core.mjs +70 -14
- package/esm2022/lib/toolbar/segmentation/sam-point-tool.service.mjs +135 -172
- package/esm2022/lib/toolbar/segmentation/sam-prompt.mjs +9 -90
- package/esm2022/lib/toolbar/segmentation/sam-session.service.mjs +183 -0
- package/esm2022/lib/toolbar/segmentation/sam-tool.service.mjs +95 -150
- package/esm2022/lib/toolbar/segmentation/segmentation-commit.mjs +12 -0
- package/esm2022/lib/toolbar/segmentation/segmentation-runner.mjs +108 -0
- package/esm2022/lib/toolbar/segmentation-tools/segmentation-tools.component.mjs +155 -0
- package/esm2022/lib/toolbar/stack-controls/stack-controls.component.mjs +81 -0
- package/esm2022/lib/toolbar/tool-kit/async-tool-status.mjs +37 -0
- package/esm2022/lib/toolbar/tool-kit/canvas-tool-manager.mjs +63 -0
- package/esm2022/lib/toolbar/tool-kit/canvas-tool.mjs +2 -0
- package/esm2022/lib/toolbar/tool-kit/frame-pixels.mjs +108 -0
- package/esm2022/lib/toolbar/tool-kit/mask-stroke-editor.mjs +306 -0
- package/esm2022/lib/toolbar/tool-kit/matrix-frame.mjs +61 -0
- package/esm2022/lib/toolbar/tool-kit/tool-overlay.mjs +140 -0
- package/esm2022/lib/toolbar/tool-kit/undo-gesture.mjs +24 -0
- package/esm2022/lib/toolbar/tool-slider/tool-slider.component.mjs +63 -0
- package/esm2022/lib/toolbar/toolbar-help-dialog/toolbar-help-dialog.component.mjs +50 -0
- package/esm2022/lib/toolbar/toolbar.component.mjs +68 -117
- package/esm2022/lib/toolbar/vertex-eraser/vertex-eraser-tool.service.mjs +93 -115
- package/esm2022/lib/toolbar/view-controls/view-controls.component.mjs +107 -0
- package/esm2022/lib/toolbar/wand/wand-region-grow.mjs +321 -0
- package/esm2022/lib/toolbar/wand/wand-tool.service.mjs +121 -416
- package/esm2022/lib/toolbar/wand/wand.service.mjs +30 -894
- package/esm2022/lib/toolbar/zoom-to-box/zoom-to-box-tool.service.mjs +48 -90
- package/esm2022/lib/util/mark-for-check.mjs +17 -0
- package/esm2022/lib/util/supersede.mjs +56 -0
- package/esm2022/lib/visualization.module.mjs +39 -141
- package/esm2022/lib/visualizer/floating-drag.directive.mjs +58 -0
- package/esm2022/lib/visualizer/region-actions.mjs +149 -0
- package/esm2022/lib/visualizer/region-load.mjs +60 -0
- package/esm2022/lib/visualizer/spatial-dataset-binder.mjs +163 -0
- package/esm2022/lib/visualizer/tool-modes.mjs +113 -0
- package/esm2022/lib/visualizer/viewer-shortcuts.mjs +167 -0
- package/esm2022/lib/visualizer/visualizer-context-menu.mjs +119 -0
- package/esm2022/lib/visualizer.component.mjs +480 -1902
- package/esm2022/lib/workers/spatial-math-ops.mjs +43 -0
- package/esm2022/lib/workers/spatial-math-worker.mjs +10 -0
- package/esm2022/lib/workers/spatial-math.mjs +190 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs +41083 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs +238 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-spatial-math-worker-BzVFFqGS.mjs +12 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-spatial-math-worker-BzVFFqGS.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +41 -34467
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs.map +1 -1
- package/fesm2022/mask.worker.js +36 -917
- package/fesm2022/onnx-sam.worker.js +52 -16
- package/fesm2022/spatial-math.worker.js +471 -0
- package/fesm2022/tsne.worker.js +32 -15
- package/index.d.ts +13 -10
- package/lib/channel-histogram/channel-histogram.component.d.ts +53 -43
- package/lib/contracts/capabilities.contract.d.ts +4 -2
- package/lib/contracts/cell-segmenter.contract.d.ts +1 -0
- package/lib/contracts/channel-histogram-api.contract.d.ts +4 -0
- package/lib/contracts/color.d.ts +27 -0
- package/lib/contracts/colormap-lut.d.ts +19 -4
- package/lib/contracts/coordinate-transform.contract.d.ts +3 -3
- package/lib/contracts/display-types.d.ts +21 -0
- package/lib/contracts/instance-segmenter.contract.d.ts +5 -0
- package/lib/contracts/intensity.d.ts +13 -2
- package/lib/contracts/plot-type.d.ts +3 -1
- package/lib/contracts/ports/image-state.port.d.ts +6 -2
- package/lib/contracts/ports/preferences.port.d.ts +4 -0
- package/lib/contracts/ports/region-io.port.d.ts +1 -0
- package/lib/contracts/ports/spatial-data.port.d.ts +4 -10
- package/lib/contracts/ports/tile-access.port.d.ts +1 -0
- package/lib/contracts/region-editor-api.contract.d.ts +1 -1
- package/lib/contracts/region-overlay.contract.d.ts +5 -0
- package/lib/contracts/sam.contract.d.ts +7 -0
- package/lib/contracts/semantic-segmenter.contract.d.ts +6 -0
- package/lib/contracts/spatial-dataset.contract.d.ts +19 -6
- package/lib/contracts/toolbar-tool.contract.d.ts +1 -0
- package/lib/contracts/visualizer.contract.d.ts +221 -54
- package/lib/contracts/viz-config.d.ts +1 -0
- package/lib/geometry/contour.d.ts +24 -0
- package/lib/geometry/raster.d.ts +42 -0
- package/lib/geometry/ring.d.ts +67 -0
- package/lib/hex-color-picker/hex-color-picker.component.d.ts +61 -27
- package/lib/implementations/base-store-visualizer.d.ts +61 -15
- package/lib/implementations/napari-js/napari-axes-gizmo.d.ts +36 -0
- package/lib/implementations/napari-js/napari-display-state.d.ts +76 -0
- package/lib/implementations/napari-js/napari-helpers.d.ts +129 -0
- package/lib/implementations/napari-js/napari-image-2d-scene.d.ts +162 -0
- package/lib/implementations/napari-js/napari-loading-badge.d.ts +0 -1
- package/lib/implementations/napari-js/napari-loading-state.d.ts +30 -0
- package/lib/implementations/napari-js/napari-region-overlay.d.ts +62 -70
- package/lib/implementations/napari-js/napari-scene.d.ts +93 -0
- package/lib/implementations/napari-js/napari-spatial-2d-scene.d.ts +163 -0
- package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +212 -0
- package/lib/implementations/napari-js/napari-spatial-encoding.d.ts +114 -0
- package/lib/implementations/napari-js/napari-spatial-hover.d.ts +89 -0
- package/lib/implementations/napari-js/napari-spatial-scene.d.ts +118 -0
- package/lib/implementations/napari-js/napari-spatial-tiles.d.ts +56 -263
- package/lib/implementations/napari-js/napari-spatial-tooltip.d.ts +1 -1
- package/lib/implementations/napari-js/napari-surface-scene.d.ts +76 -0
- package/lib/implementations/napari-js/napari-tile-client.d.ts +214 -0
- package/lib/implementations/napari-js/napari-tool-bridge.d.ts +179 -0
- package/lib/implementations/napari-js/napari-visualizer.service.d.ts +121 -883
- package/lib/implementations/napari-js/napari-volume-scene.d.ts +104 -0
- package/lib/implementations/napari-js/napari-volume-z-handle.d.ts +8 -12
- package/lib/implementations/napari-js/region-overlay/overlay-projection.d.ts +59 -0
- package/lib/implementations/napari-js/region-overlay/region-edit.d.ts +15 -0
- package/lib/implementations/napari-js/region-overlay/region-svg-renderer.d.ts +54 -0
- package/lib/implementations/napari-js/spatial-tiles/categorical-lookup.d.ts +26 -0
- package/lib/implementations/napari-js/spatial-tiles/cell-layers.d.ts +70 -0
- package/lib/implementations/napari-js/spatial-tiles/density-layer.d.ts +61 -0
- package/lib/implementations/napari-js/spatial-tiles/layer-groups.d.ts +67 -0
- package/lib/implementations/napari-js/spatial-tiles/plan-context.d.ts +38 -0
- package/lib/implementations/napari-js/spatial-tiles/transcript-hover.d.ts +71 -0
- package/lib/implementations/napari-js/spatial-tiles/transcript-jobs.d.ts +105 -0
- package/lib/implementations/napari-js/spatial-tiles/transcript-layers.d.ts +56 -0
- package/lib/implementations/osd/display-pipeline.d.ts +38 -9
- package/lib/implementations/osd/histogram-sampler.d.ts +22 -12
- package/lib/implementations/osd/openseadragon-viewer-options.d.ts +35 -0
- package/lib/implementations/osd/openseadragon-visualizer.service.d.ts +78 -354
- package/lib/implementations/osd/osd-coordinate-transform.d.ts +2 -1
- package/lib/implementations/osd/osd-coords.d.ts +6 -4
- package/lib/implementations/osd/osd-export.d.ts +36 -0
- package/lib/implementations/osd/osd-lib.d.ts +7 -0
- package/lib/implementations/osd/osd-navigator-chrome.d.ts +69 -0
- package/lib/implementations/osd/osd-pixel-readback.d.ts +22 -0
- package/lib/implementations/osd/osd-region-overlay-draw.d.ts +37 -0
- package/lib/implementations/osd/osd-region-overlay.d.ts +36 -48
- package/lib/implementations/osd/osd-scale-bar.d.ts +8 -6
- package/lib/implementations/osd/osd-tile-source.d.ts +49 -0
- package/lib/implementations/osd/osd-viewer-like.d.ts +100 -0
- package/lib/implementations/osd/osd-viewer-mount.d.ts +14 -0
- package/lib/implementations/osd/osd-viewport.d.ts +77 -0
- package/lib/implementations/osd/osd-zoom.d.ts +6 -0
- package/lib/implementations/osd/simple-source.d.ts +161 -0
- package/lib/implementations/osd/slice-cache.d.ts +12 -3
- package/lib/implementations/osd/tile-client.d.ts +11 -14
- package/lib/implementations/osd/tile-recolor.d.ts +141 -0
- package/lib/implementations/plotly/omics-trace-builders.d.ts +32 -20
- package/lib/implementations/plotly/plotly-image-loader.d.ts +49 -0
- package/lib/implementations/plotly/plotly-image-recolor.d.ts +75 -0
- package/lib/implementations/plotly/plotly-intensity-inset.d.ts +8 -0
- package/lib/implementations/plotly/plotly-isosurface-controls.d.ts +38 -0
- package/lib/implementations/plotly/plotly-layouts.d.ts +188 -0
- package/lib/implementations/plotly/plotly-readback.d.ts +41 -0
- package/lib/implementations/plotly/plotly-region-overlay.d.ts +2 -2
- package/lib/implementations/plotly/plotly-shape-projection.d.ts +92 -0
- package/lib/implementations/plotly/plotly-trace-builders.d.ts +23 -12
- package/lib/implementations/plotly/plotly-zoom-controller.d.ts +86 -0
- package/lib/implementations/plotly/plotly.service.d.ts +136 -401
- package/lib/implementations/region-centroids.d.ts +14 -0
- package/lib/implementations/simple-slice-access.service.d.ts +7 -4
- package/lib/implementations/spatial-data-http/spatial-data-http.service.d.ts +42 -18
- package/lib/implementations/spatial-data-http/spatial-wire.d.ts +34 -9
- package/lib/implementations/tile-server/index.d.ts +5 -0
- package/lib/implementations/tile-server/native-histogram.d.ts +25 -0
- package/lib/implementations/tile-server/poll-descriptor.d.ts +39 -0
- package/lib/implementations/tile-server/tile-protocol.d.ts +80 -0
- package/lib/implementations/tile-server/transport.d.ts +62 -0
- package/lib/intensity/intensity-profile.d.ts +66 -0
- package/lib/intensity/intensity-profile.service.d.ts +108 -0
- package/lib/intensity-inset/intensity-inset.component.d.ts +58 -0
- package/lib/models/bezier.d.ts +0 -5
- package/lib/models/class-preset.d.ts +18 -0
- package/lib/models/geometry.d.ts +14 -48
- package/lib/models/polygon-edit.d.ts +72 -0
- package/lib/models/polygon-factory.d.ts +40 -0
- package/lib/models/region-clone.d.ts +20 -0
- package/lib/models/region-geojson.d.ts +17 -0
- package/lib/models/region.d.ts +40 -4
- package/lib/models/shape.d.ts +8 -0
- package/lib/plot-mode/contribution-host.d.ts +125 -0
- package/lib/plot-mode/plot-type-menu.d.ts +60 -0
- package/lib/plot-mode/tool-params-model.d.ts +49 -0
- package/lib/plot.utilities.d.ts +19 -30
- package/lib/processing/processing-image.d.ts +5 -2
- package/lib/provide-visualization.d.ts +19 -2
- package/lib/region-editor/classes-panel/classes-panel.component.d.ts +56 -0
- package/lib/region-editor/file-stem.d.ts +7 -0
- package/lib/region-editor/manage-classes-dialog/manage-classes-dialog.component.d.ts +45 -0
- package/lib/region-editor/mask-export.service.d.ts +54 -0
- package/lib/region-editor/mask-raster.d.ts +2 -8
- package/lib/region-editor/region-color-dialog/region-color-dialog.component.d.ts +29 -0
- package/lib/region-editor/region-editor-help/region-editor-help.component.d.ts +11 -0
- package/lib/region-editor/region-editor.component.d.ts +166 -199
- package/lib/region-editor/region-metrics.d.ts +26 -0
- package/lib/region-editor/region-persistence.service.d.ts +69 -0
- package/lib/region-editor/region-table/region-table.component.d.ts +83 -0
- package/lib/region-editor/save-mask-dialog/save-mask-dialog.component.d.ts +36 -0
- package/lib/region-editor/save-regions-dialog/save-regions-dialog.component.d.ts +37 -0
- package/lib/region-ops.service.d.ts +1 -7
- package/lib/region-overlay/region-geometry.d.ts +157 -0
- package/lib/region-overlay/region-hit-test.d.ts +38 -0
- package/lib/region-overlay/svg-region-renderer.d.ts +110 -0
- package/lib/render-orchestrator.d.ts +6 -2
- package/lib/render-session.d.ts +75 -0
- package/lib/routing-visualizer.service.d.ts +110 -58
- package/lib/spatial/density-raster.d.ts +6 -0
- package/lib/spatial/embedding-compute-coordinator.d.ts +123 -0
- package/lib/spatial/embedding-compute.d.ts +21 -2
- package/lib/spatial/glyphs.d.ts +16 -0
- package/lib/spatial/lod.d.ts +94 -0
- package/lib/spatial/spatial-controls.facade.d.ts +64 -0
- package/lib/spatial/spatial-density.d.ts +15 -5
- package/lib/spatial/spatial-encoding.d.ts +11 -44
- package/lib/spatial/spatial-expression.d.ts +40 -22
- package/lib/spatial/spatial-framing.d.ts +1 -0
- package/lib/spatial/spatial-heatmap.d.ts +2 -0
- package/lib/spatial/spatial-hover.d.ts +4 -16
- package/lib/spatial/spatial-panel-model.d.ts +135 -0
- package/lib/spatial/spatial-selection.d.ts +21 -26
- package/lib/spatial/spatial-tile-merge.d.ts +41 -0
- package/lib/spatial/spatial-tiles.d.ts +9 -256
- package/lib/spatial/stats.d.ts +38 -0
- package/lib/spatial/transcript-grouping.d.ts +119 -0
- package/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.d.ts +64 -0
- package/lib/spatial-controls/spatial-charts/chart-data-model.d.ts +153 -0
- package/lib/spatial-controls/spatial-charts/chart-help.d.ts +69 -0
- package/lib/spatial-controls/spatial-charts/plotly-chart-host.d.ts +98 -0
- package/lib/spatial-controls/spatial-charts/spatial-chart-window/spatial-chart-window.component.d.ts +26 -0
- package/lib/spatial-controls/spatial-charts/spatial-charts.component.d.ts +101 -260
- package/lib/spatial-controls/spatial-charts/spatial-embedding-controls/spatial-embedding-controls.component.d.ts +43 -0
- package/lib/spatial-controls/spatial-charts/spatial-heatmap-controls/spatial-heatmap-controls.component.d.ts +27 -0
- package/lib/spatial-controls/spatial-controls.component.d.ts +68 -448
- package/lib/spatial-controls/spatial-gene-picker.d.ts +86 -0
- package/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.d.ts +102 -0
- package/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.d.ts +72 -0
- package/lib/spatial-controls/spatial-key/spatial-key.component.d.ts +66 -0
- package/lib/spatial-controls/spatial-key/spatial-key.model.d.ts +33 -0
- package/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.d.ts +64 -0
- package/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.d.ts +117 -0
- package/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.d.ts +142 -0
- package/lib/store/class-color.util.d.ts +35 -1
- package/lib/store/region-history.d.ts +66 -0
- package/lib/store/region-scope-cache.d.ts +63 -0
- package/lib/store/region-selection.d.ts +36 -0
- package/lib/store/region-store.service.d.ts +104 -112
- package/lib/store/visualizer-store.service.d.ts +22 -33
- package/lib/toast-outlets.d.ts +4 -3
- package/lib/toolbar/brush/brush-tool.service.d.ts +31 -98
- package/lib/toolbar/canvas-tools.d.ts +20 -0
- package/lib/toolbar/crop/slide-crop.d.ts +10 -4
- package/lib/toolbar/plot-type-selector/plot-type-selector.component.d.ts +38 -0
- package/lib/toolbar/region-tools/region-tool-buttons.d.ts +21 -0
- package/lib/toolbar/region-tools/region-tools.component.d.ts +60 -0
- package/lib/toolbar/segmentation/cell-segment-tool.service.d.ts +10 -14
- package/lib/toolbar/segmentation/cellpose-segmenter.service.d.ts +12 -2
- package/lib/toolbar/segmentation/onnx-sam-session.d.ts +22 -3
- package/lib/toolbar/segmentation/pending-calls.d.ts +31 -0
- package/lib/toolbar/segmentation/sam-model-registry.d.ts +9 -3
- package/lib/toolbar/segmentation/sam-onnx-core.d.ts +18 -5
- package/lib/toolbar/segmentation/sam-point-tool.service.d.ts +46 -32
- package/lib/toolbar/segmentation/sam-prompt.d.ts +7 -31
- package/lib/toolbar/segmentation/sam-session.service.d.ts +74 -0
- package/lib/toolbar/segmentation/sam-tool.service.d.ts +23 -30
- package/lib/toolbar/segmentation/segmentation-commit.d.ts +8 -0
- package/lib/toolbar/segmentation/segmentation-runner.d.ts +52 -0
- package/lib/toolbar/segmentation-tools/segmentation-tools.component.d.ts +87 -0
- package/lib/toolbar/stack-controls/stack-controls.component.d.ts +40 -0
- package/lib/toolbar/tool-kit/async-tool-status.d.ts +21 -0
- package/lib/toolbar/tool-kit/canvas-tool-manager.d.ts +36 -0
- package/lib/toolbar/tool-kit/canvas-tool.d.ts +86 -0
- package/lib/toolbar/tool-kit/frame-pixels.d.ts +45 -0
- package/lib/toolbar/tool-kit/mask-stroke-editor.d.ts +125 -0
- package/lib/toolbar/tool-kit/matrix-frame.d.ts +40 -0
- package/lib/toolbar/tool-kit/tool-overlay.d.ts +60 -0
- package/lib/toolbar/tool-kit/undo-gesture.d.ts +17 -0
- package/lib/toolbar/tool-slider/tool-slider.component.d.ts +33 -0
- package/lib/toolbar/toolbar-help-dialog/toolbar-help-dialog.component.d.ts +24 -0
- package/lib/toolbar/toolbar.component.d.ts +47 -83
- package/lib/toolbar/vertex-eraser/vertex-eraser-tool.service.d.ts +33 -40
- package/lib/toolbar/view-controls/view-controls.component.d.ts +54 -0
- package/lib/toolbar/wand/wand-region-grow.d.ts +49 -0
- package/lib/toolbar/wand/wand-tool.service.d.ts +39 -124
- package/lib/toolbar/wand/wand.service.d.ts +22 -116
- package/lib/toolbar/zoom-to-box/zoom-to-box-tool.service.d.ts +17 -37
- package/lib/util/mark-for-check.d.ts +11 -0
- package/lib/util/supersede.d.ts +53 -0
- package/lib/visualization.module.d.ts +18 -39
- package/lib/visualizer/floating-drag.directive.d.ts +30 -0
- package/lib/visualizer/region-actions.d.ts +54 -0
- package/lib/visualizer/region-load.d.ts +27 -0
- package/lib/visualizer/spatial-dataset-binder.d.ts +74 -0
- package/lib/visualizer/tool-modes.d.ts +49 -0
- package/lib/visualizer/viewer-shortcuts.d.ts +71 -0
- package/lib/visualizer/visualizer-context-menu.d.ts +55 -0
- package/lib/visualizer.component.d.ts +201 -447
- package/lib/workers/spatial-math-ops.d.ts +65 -0
- package/lib/workers/spatial-math-worker.d.ts +7 -0
- package/lib/workers/spatial-math.d.ts +74 -0
- package/package.json +12 -3
- package/src/lib/styles/_viz-icons-rules.scss +73 -0
- package/src/lib/styles/viz-icons.scss +14 -0
- package/esm2022/lib/implementations/napari-js/napari-axes-labels.mjs +0 -97
- package/esm2022/lib/implementations/napari-js/napari-navigator.mjs +0 -195
- package/esm2022/lib/implementations/napari-js/napari-scale-bar.mjs +0 -92
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-BwP-A11m.mjs +0 -329
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-BwP-A11m.mjs.map +0 -1
- package/lib/implementations/napari-js/napari-axes-labels.d.ts +0 -49
- package/lib/implementations/napari-js/napari-navigator.d.ts +0 -72
- package/lib/implementations/napari-js/napari-scale-bar.d.ts +0 -35
- package/src/lib/assets/cell-detection.svg +0 -37
- package/src/lib/assets/click.svg +0 -1
- package/src/lib/assets/colormap-luts.json +0 -1
- package/src/lib/assets/edit-selection-white.svg +0 -47
- package/src/lib/assets/icons/colormap-earth.png +0 -0
- package/src/lib/assets/icons/colormap-placeholder.png +0 -0
- package/src/lib/assets/icons/colormap-pubu.png +0 -0
- package/src/lib/assets/interactive-segmentation-cursor.svg +0 -1
- package/src/lib/assets/picture-segmentation.svg +0 -43
- package/src/lib/assets/test/download-379.svg +0 -1
- package/src/lib/assets/test/download-98.svg +0 -1
- package/src/lib/assets/test/json-1.svg +0 -1
- package/src/lib/assets/test/load-53.svg +0 -1
- package/src/lib/assets/test/mask-44.svg +0 -1
- package/src/lib/assets/test/mask-download-44.svg +0 -15
- package/src/lib/assets/test/mask-save-44.svg +0 -11
- package/src/lib/assets/test/overlay-1.svg +0 -1
- package/src/lib/assets/test/overlay-4.svg +0 -1
- package/src/lib/assets/test/region-26.svg +0 -1
- package/src/lib/assets/test/save-56.svg +0 -1
- package/src/lib/assets/test/upload-43.svg +0 -1
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plotly layout builders for every plot type the Plotly backend renders. Pure:
|
|
3
|
+
* the live service state they need (screen height, aspect lock, drag mode, the
|
|
4
|
+
* current region shapes and colours) comes in through {@link ImageLayoutContext}.
|
|
5
|
+
*/
|
|
6
|
+
/** One slider step per z-plane, each showing only its own trace. */
|
|
7
|
+
export function sliderSteps(sliceCount) {
|
|
8
|
+
const steps = [];
|
|
9
|
+
for (let i = 0; i < sliceCount; i++) {
|
|
10
|
+
steps.push({
|
|
11
|
+
label: i + 1,
|
|
12
|
+
method: 'restyle',
|
|
13
|
+
args: [
|
|
14
|
+
'visible',
|
|
15
|
+
Array(sliceCount)
|
|
16
|
+
.fill(false)
|
|
17
|
+
.fill(true, i, i + 1),
|
|
18
|
+
],
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
return steps;
|
|
22
|
+
}
|
|
23
|
+
/** Image axes over `xRange`/`yRange` (pass the y range reversed for an image). */
|
|
24
|
+
function imageAxes(ctx, xRange, yRange) {
|
|
25
|
+
return {
|
|
26
|
+
xaxis: { constrain: 'range', constraintoward: 'center', side: 'top', ticks: '', range: xRange },
|
|
27
|
+
yaxis: {
|
|
28
|
+
constrain: 'range',
|
|
29
|
+
constraintoward: 'center',
|
|
30
|
+
range: yRange,
|
|
31
|
+
ticks: '',
|
|
32
|
+
ticksuffix: ' ',
|
|
33
|
+
// autorange off so that Plotly does not overwrite the range for the y axis
|
|
34
|
+
autorange: false,
|
|
35
|
+
scaleanchor: ctx.scaleratio ? 'x' : false,
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/** The heatmap / RGB image layout: image axes, the z-plane slider, the region shapes. */
|
|
40
|
+
export function heatmapLayout(ctx, xRange, yRange, sliceCount) {
|
|
41
|
+
return {
|
|
42
|
+
...imageAxes(ctx, xRange, yRange),
|
|
43
|
+
margin: { t: 30, b: 5, l: 55, r: 5 },
|
|
44
|
+
height: ctx.screenHeight,
|
|
45
|
+
sliders: [
|
|
46
|
+
{
|
|
47
|
+
pad: { t: 50 },
|
|
48
|
+
currentvalue: { visible: true, prefix: 'Z-plane:', xanchor: 'right' },
|
|
49
|
+
steps: sliderSteps(sliceCount),
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
autosize: true,
|
|
53
|
+
shapes: ctx.shapes,
|
|
54
|
+
activeshape: { fillcolor: ctx.fillColor },
|
|
55
|
+
dragmode: ctx.dragMode ? ctx.dragMode : false,
|
|
56
|
+
newshape: { line: { color: ctx.shapeColor, width: 3 } },
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/** Image-aligned 2D axes without the z-plane slider (region scatter). */
|
|
60
|
+
export function overlayLayout(ctx, xRange, yRange) {
|
|
61
|
+
return {
|
|
62
|
+
...imageAxes(ctx, xRange, yRange),
|
|
63
|
+
margin: { t: 30, b: 5, l: 55, r: 5 },
|
|
64
|
+
height: ctx.screenHeight,
|
|
65
|
+
autosize: true,
|
|
66
|
+
shapes: ctx.shapes,
|
|
67
|
+
dragmode: ctx.dragMode ? ctx.dragMode : false,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/** Plain 2D chart axes (intensity profile / line plots). */
|
|
71
|
+
export function chartLayout(screenHeight) {
|
|
72
|
+
return {
|
|
73
|
+
margin: { t: 30, b: 45, l: 60, r: 20 },
|
|
74
|
+
height: screenHeight,
|
|
75
|
+
autosize: true,
|
|
76
|
+
xaxis: { title: 'Position (px)' },
|
|
77
|
+
yaxis: { title: 'Intensity' },
|
|
78
|
+
dragmode: false,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/** 3D scene for volumetric plot types (scatter3d, isosurface). */
|
|
82
|
+
export function volumeLayout(screenHeight) {
|
|
83
|
+
return {
|
|
84
|
+
margin: { t: 0, b: 0, l: 0, r: 0 },
|
|
85
|
+
height: screenHeight,
|
|
86
|
+
autosize: true,
|
|
87
|
+
scene: {
|
|
88
|
+
xaxis: { title: 'X' },
|
|
89
|
+
yaxis: { title: 'Y' },
|
|
90
|
+
zaxis: { title: 'Z-plane' },
|
|
91
|
+
// 'cube' (not 'data'): a z-stack has far fewer planes than X/Y pixels,
|
|
92
|
+
// so 'data' squashes the volume into a near-flat slab that reads as
|
|
93
|
+
// empty edge-on. A cube gives the z dimension real height so the
|
|
94
|
+
// isosurface/voxels are actually visible.
|
|
95
|
+
aspectmode: 'cube',
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Scene layout for the surface plot: light-grey axis planes and a manual
|
|
101
|
+
* aspect ratio whose z extent is `zRatio` of the x/y extent.
|
|
102
|
+
*/
|
|
103
|
+
export function surfaceLayout(zRatio) {
|
|
104
|
+
const plane = {
|
|
105
|
+
gridcolor: 'rgb(255, 255, 255)',
|
|
106
|
+
zerolinecolor: 'rgb(255, 255, 255)',
|
|
107
|
+
showbackground: true,
|
|
108
|
+
backgroundcolor: 'rgb(230, 230,230)',
|
|
109
|
+
};
|
|
110
|
+
return {
|
|
111
|
+
margin: { t: 0, b: 0, l: 0, r: 0 },
|
|
112
|
+
scene: {
|
|
113
|
+
xaxis: { ...plane },
|
|
114
|
+
yaxis: { ...plane, backgroundcolor: 'rgb(230, 230, 230)' },
|
|
115
|
+
zaxis: { ...plane },
|
|
116
|
+
aspectratio: { x: 1, y: 1, z: zRatio },
|
|
117
|
+
aspectmode: 'manual',
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxvdGx5LWxheW91dHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2ltcGxlbWVudGF0aW9ucy9wbG90bHkvcGxvdGx5LWxheW91dHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7R0FJRztBQW9CSCxvRUFBb0U7QUFDcEUsTUFBTSxVQUFVLFdBQVcsQ0FBQyxVQUFrQjtJQUM1QyxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUM7SUFDakIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFVBQVUsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ3BDLEtBQUssQ0FBQyxJQUFJLENBQUM7WUFDVCxLQUFLLEVBQUUsQ0FBQyxHQUFHLENBQUM7WUFDWixNQUFNLEVBQUUsU0FBUztZQUNqQixJQUFJLEVBQUU7Z0JBQ0osU0FBUztnQkFDVCxLQUFLLENBQUMsVUFBVSxDQUFDO3FCQUNkLElBQUksQ0FBQyxLQUFLLENBQUM7cUJBQ1gsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQzthQUN4QjtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRCxrRkFBa0Y7QUFDbEYsU0FBUyxTQUFTLENBQUMsR0FBdUIsRUFBRSxNQUFnQixFQUFFLE1BQWdCO0lBQzVFLE9BQU87UUFDTCxLQUFLLEVBQUUsRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUU7UUFDL0YsS0FBSyxFQUFFO1lBQ0wsU0FBUyxFQUFFLE9BQU87WUFDbEIsZUFBZSxFQUFFLFFBQVE7WUFDekIsS0FBSyxFQUFFLE1BQU07WUFDYixLQUFLLEVBQUUsRUFBRTtZQUNULFVBQVUsRUFBRSxJ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Q3BCLFFBQVEsRUFBRSxJQUFJO1FBQ2QsS0FBSyxFQUFFO1lBQ0wsS0FBSyxFQUFFLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRTtZQUNyQixLQUFLLEVBQUUsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFO1lBQ3JCLEtBQUssRUFBRSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUU7WUFDM0IsdUVBQXVFO1lBQ3ZFLG9FQUFvRTtZQUNwRSxpRUFBaUU7WUFDakUsMENBQTBDO1lBQzFDLFVBQVUsRUFBRSxNQUFNO1NBQ25CO0tBQ0YsQ0FBQztBQUNKLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsYUFBYSxDQUFDLE1BQWM7SUFDMUMsTUFBTSxLQUFLLEdBQUc7UUFDWixTQUFTLEVBQUUsb0JBQW9CO1FBQy9CLGFBQWEsRUFBRSxvQkFBb0I7UUFDbkMsY0FBYyxFQUFFLElBQUk7UUFDcEIsZUFBZSxFQUFFLG1CQUFtQjtLQUNyQyxDQUFDO0lBQ0YsT0FBTztRQUNMLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7UUFDbEMsS0FBSyxFQUFFO1lBQ0wsS0FBSyxFQUFFLEVBQUUsR0FBRyxLQUFLLEVBQUU7WUFDbkIsS0FBSyxFQUFFLEVBQUUsR0FBRyxLQUFLLEVBQUUsZUFBZSxFQUFFLG9CQUFvQixFQUFFO1lBQzFELEtBQUssRUFBRSxFQUFFLEdBQUcsS0FBSyxFQUFFO1lBQ25CLFdBQVcsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFO1lBQ3RDLFVBQVUsRUFBRSxRQUFRO1NBQ3JCO0tBQ0YsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFBsb3RseSBsYXlvdXQgYnVpbGRlcnMgZm9yIGV2ZXJ5IHBsb3QgdHlwZSB0aGUgUGxvdGx5IGJhY2tlbmQgcmVuZGVycy4gUHVyZTpcbiAqIHRoZSBsaXZlIHNlcnZpY2Ugc3RhdGUgdGhleSBuZWVkIChzY3JlZW4gaGVpZ2h0LCBhc3BlY3QgbG9jaywgZHJhZyBtb2RlLCB0aGVcbiAqIGN1cnJlbnQgcmVnaW9uIHNoYXBlcyBhbmQgY29sb3VycykgY29tZXMgaW4gdGhyb3VnaCB7QGxpbmsgSW1hZ2VMYXlvdXRDb250ZXh0fS5cbiAqL1xuXG4vKiogUGxvdGx5IHNoYXBlIGRpY3RzLCBhcyBgbGF5b3V0LnNoYXBlc2AgdGFrZXMgdGhlbS4gKi9cbmV4cG9ydCB0eXBlIFBsb3RseVNoYXBlRGljdCA9IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuXG4vKiogVGhlIHNlcnZpY2Ugc3RhdGUgYW4gaW1hZ2UtYWxpZ25lZCBsYXlvdXQgZGVwZW5kcyBvbi4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSW1hZ2VMYXlvdXRDb250ZXh0IHtcbiAgc2NyZWVuSGVpZ2h0OiBudW1iZXI7XG4gIC8qKiBMb2NrIHRoZSB5IGF4aXMgdG8geCAoc3F1YXJlIGltYWdlIHBpeGVscykuICovXG4gIHNjYWxlcmF0aW86IGJvb2xlYW47XG4gIC8qKiBUaGUgYWN0aXZlIFBsb3RseSBkcmFnIG1vZGUsIG9yICcnIGZvciBub25lLiAqL1xuICBkcmFnTW9kZTogc3RyaW5nO1xuICAvKiogVGhlIHJlZ2lvbiBzaGFwZXMgdG8gZHJhdyBvdmVyIHRoZSBpbWFnZS4gKi9cbiAgc2hhcGVzOiBQbG90bHlTaGFwZURpY3RbXTtcbiAgLyoqIFRoZSBhY3RpdmUgKHNlbGVjdGVkKSBzaGFwZSdzIGZpbGwgY29sb3VyLiAqL1xuICBmaWxsQ29sb3I6IHN0cmluZztcbiAgLyoqIFRoZSBvdXRsaW5lIGNvbG91ciBvZiBhIG5ld2x5IGRyYXduIHNoYXBlLiAqL1xuICBzaGFwZUNvbG9yOiBzdHJpbmc7XG59XG5cbi8qKiBPbmUgc2xpZGVyIHN0ZXAgcGVyIHotcGxhbmUsIGVhY2ggc2hvd2luZyBvbmx5IGl0cyBvd24gdHJhY2UuICovXG5leHBvcnQgZnVuY3Rpb24gc2xpZGVyU3RlcHMoc2xpY2VDb3VudDogbnVtYmVyKTogQXJyYXk8eyBsYWJlbDogbnVtYmVyOyBtZXRob2Q6IHN0cmluZzsgYXJnczogdW5rbm93bltdIH0+IHtcbiAgY29uc3Qgc3RlcHMgPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbGljZUNvdW50OyBpKyspIHtcbiAgICBzdGVwcy5wdXNoKHtcbiAgICAgIGxhYmVsOiBpICsgMSxcbiAgICAgIG1ldGhvZDogJ3Jlc3R5bGUnLFxuICAgICAgYXJnczogW1xuICAgICAgICAndmlzaWJsZScsXG4gICAgICAgIEFycmF5KHNsaWNlQ291bnQpXG4gICAgICAgICAgLmZpbGwoZmFsc2UpXG4gICAgICAgICAgLmZpbGwodHJ1ZSwgaSwgaSArIDEpLFxuICAgICAgXSxcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gc3RlcHM7XG59XG5cbi8qKiBJbWFnZSBheGVzIG92ZXIgYHhSYW5nZWAvYHlSYW5nZWAgKHBhc3MgdGhlIHkgcmFuZ2UgcmV2ZXJzZWQgZm9yIGFuIGltYWdlKS4gKi9cbmZ1bmN0aW9uIGltYWdlQXhlcyhjdHg6IEltYWdlTGF5b3V0Q29udGV4dCwgeFJhbmdlOiBudW1iZXJbXSwgeVJhbmdlOiBudW1iZXJbXSkge1xuICByZXR1cm4ge1xuICAgIHhheGlzOiB7IGNvbnN0cmFpbjogJ3JhbmdlJywgY29uc3RyYWludG93YXJkOiAnY2VudGVyJywgc2lkZTogJ3RvcCcsIHRpY2tzOiAnJywgcmFuZ2U6IHhSYW5nZSB9LFxuICAgIHlheGlzOiB7XG4gICAgICBjb25zdHJhaW46ICdyYW5nZScsXG4gICAgICBjb25zdHJhaW50b3dhcmQ6ICdjZW50ZXInLFxuICAgICAgcmFuZ2U6IHlSYW5nZSxcbiAgICAgIHRpY2tzOiAnJyxcbiAgICAgIHRpY2tzdWZmaXg6ICcgICcsXG4gICAgICAvLyBhdXRvcmFuZ2Ugb2ZmIHNvIHRoYXQgUGxvdGx5IGRvZXMgbm90IG92ZXJ3cml0ZSB0aGUgcmFuZ2UgZm9yIHRoZSB5IGF4aXNcbiAgICAgIGF1dG9yYW5nZTogZmFsc2UsXG4gICAgICBzY2FsZWFuY2hvcjogY3R4LnNjYWxlcmF0aW8gPyAneCcgOiBmYWxzZSxcbiAgICB9LFxuICB9O1xufVxuXG4vKiogVGhlIGhlYXRtYXAgLyBSR0IgaW1hZ2UgbGF5b3V0OiBpbWFnZSBheGVzLCB0aGUgei1wbGFuZSBzbGlkZXIsIHRoZSByZWdpb24gc2hhcGVzLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhlYXRtYXBMYXlvdXQoY3R4OiBJbWFnZUxheW91dENvbnRleHQsIHhSYW5nZTogbnVtYmVyW10sIHlSYW5nZTogbnVtYmVyW10sIHNsaWNlQ291bnQ6IG51bWJlcikge1xuICByZXR1cm4ge1xuICAgIC4uLmltYWdlQXhlcyhjdHgsIHhSYW5nZSwgeVJhbmdlKSxcbiAgICBtYXJnaW46IHsgdDogMzAsIGI6IDUsIGw6IDU1LCByOiA1IH0sXG4gICAgaGVpZ2h0OiBjdHguc2NyZWVuSGVpZ2h0LFxuICAgIHNsaWRlcnM6IFtcbiAgICAgIHtcbiAgICAgICAgcGFkOiB7IHQ6IDUwIH0sXG4gICAgICAgIGN1cnJlbnR2YWx1ZTogeyB2aXNpYmxlOiB0cnVlLCBwcmVmaXg6ICdaLXBsYW5lOicsIHhhbmNob3I6ICdyaWdodCcgfSxcbiAgICAgICAgc3RlcHM6IHNsaWRlclN0ZXBzKHNsaWNlQ291bnQpLFxuICAgICAgfSxcbiAgICBdLFxuICAgIGF1dG9zaXplOiB0cnVlLFxuICAgIHNoYXBlczogY3R4LnNoYXBlcyxcbiAgICBhY3RpdmVzaGFwZTogeyBmaWxsY29sb3I6IGN0eC5maWxsQ29sb3IgfSxcbiAgICBkcmFnbW9kZTogY3R4LmRyYWdNb2RlID8gY3R4LmRyYWdNb2RlIDogZmFsc2UsXG4gICAgbmV3c2hhcGU6IHsgbGluZTogeyBjb2xvcjogY3R4LnNoYXBlQ29sb3IsIHdpZHRoOiAzIH0gfSxcbiAgfTtcbn1cblxuLyoqIEltYWdlLWFsaWduZWQgMkQgYXhlcyB3aXRob3V0IHRoZSB6LXBsYW5lIHNsaWRlciAocmVnaW9uIHNjYXR0ZXIpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG92ZXJsYXlMYXlvdXQoY3R4OiBJbWFnZUxheW91dENvbnRleHQsIHhSYW5nZTogbnVtYmVyW10sIHlSYW5nZTogbnVtYmVyW10pIHtcbiAgcmV0dXJuIHtcbiAgICAuLi5pbWFnZUF4ZXMoY3R4LCB4UmFuZ2UsIHlSYW5nZSksXG4gICAgbWFyZ2luOiB7IHQ6IDMwLCBiOiA1LCBsOiA1NSwgcjogNSB9LFxuICAgIGhlaWdodDogY3R4LnNjcmVlbkhlaWdodCxcbiAgICBhdXRvc2l6ZTogdHJ1ZSxcbiAgICBzaGFwZXM6IGN0eC5zaGFwZXMsXG4gICAgZHJhZ21vZGU6IGN0eC5kcmFnTW9kZSA/IGN0eC5kcmFnTW9kZSA6IGZhbHNlLFxuICB9O1xufVxuXG4vKiogUGxhaW4gMkQgY2hhcnQgYXhlcyAoaW50ZW5zaXR5IHByb2ZpbGUgLyBsaW5lIHBsb3RzKS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjaGFydExheW91dChzY3JlZW5IZWlnaHQ6IG51bWJlcikge1xuICByZXR1cm4ge1xuICAgIG1hcmdpbjogeyB0OiAzMCwgYjogNDUsIGw6IDYwLCByOiAyMCB9LFxuICAgIGhlaWdodDogc2NyZWVuSGVpZ2h0LFxuICAgIGF1dG9zaXplOiB0cnVlLFxuICAgIHhheGlzOiB7IHRpdGxlOiAnUG9zaXRpb24gKHB4KScgfSxcbiAgICB5YXhpczogeyB0aXRsZTogJ0ludGVuc2l0eScgfSxcbiAgICBkcmFnbW9kZTogZmFsc2UsXG4gIH07XG59XG5cbi8qKiAzRCBzY2VuZSBmb3Igdm9sdW1ldHJpYyBwbG90IHR5cGVzIChzY2F0dGVyM2QsIGlzb3N1cmZhY2UpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZvbHVtZUxheW91dChzY3JlZW5IZWlnaHQ6IG51bWJlcikge1xuICByZXR1cm4ge1xuICAgIG1hcmdpbjogeyB0OiAwLCBiOiAwLCBsOiAwLCByOiAwIH0sXG4gICAgaGVpZ2h0OiBzY3JlZW5IZWlnaHQsXG4gICAgYXV0b3NpemU6IHRydWUsXG4gICAgc2NlbmU6IHtcbiAgICAgIHhheGlzOiB7IHRpdGxlOiAnWCcgfSxcbiAgICAgIHlheGlzOiB7IHRpdGxlOiAnWScgfSxcbiAgICAgIHpheGlzOiB7IHRpdGxlOiAnWi1wbGFuZScgfSxcbiAgICAgIC8vICdjdWJlJyAobm90ICdkYXRhJyk6IGEgei1zdGFjayBoYXMgZmFyIGZld2VyIHBsYW5lcyB0aGFuIFgvWSBwaXhlbHMsXG4gICAgICAvLyBzbyAnZGF0YScgc3F1YXNoZXMgdGhlIHZvbHVtZSBpbnRvIGEgbmVhci1mbGF0IHNsYWIgdGhhdCByZWFkcyBhc1xuICAgICAgLy8gZW1wdHkgZWRnZS1vbi4gQSBjdWJlIGdpdmVzIHRoZSB6IGRpbWVuc2lvbiByZWFsIGhlaWdodCBzbyB0aGVcbiAgICAgIC8vIGlzb3N1cmZhY2Uvdm94ZWxzIGFyZSBhY3R1YWxseSB2aXNpYmxlLlxuICAgICAgYXNwZWN0bW9kZTogJ2N1YmUnLFxuICAgIH0sXG4gIH07XG59XG5cbi8qKlxuICogU2NlbmUgbGF5b3V0IGZvciB0aGUgc3VyZmFjZSBwbG90OiBsaWdodC1ncmV5IGF4aXMgcGxhbmVzIGFuZCBhIG1hbnVhbFxuICogYXNwZWN0IHJhdGlvIHdob3NlIHogZXh0ZW50IGlzIGB6UmF0aW9gIG9mIHRoZSB4L3kgZXh0ZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gc3VyZmFjZUxheW91dCh6UmF0aW86IG51bWJlcikge1xuICBjb25zdCBwbGFuZSA9IHtcbiAgICBncmlkY29sb3I6ICdyZ2IoMjU1LCAyNTUsIDI1NSknLFxuICAgIHplcm9saW5lY29sb3I6ICdyZ2IoMjU1LCAyNTUsIDI1NSknLFxuICAgIHNob3diYWNrZ3JvdW5kOiB0cnVlLFxuICAgIGJhY2tncm91bmRjb2xvcjogJ3JnYigyMzAsIDIzMCwyMzApJyxcbiAgfTtcbiAgcmV0dXJuIHtcbiAgICBtYXJnaW46IHsgdDogMCwgYjogMCwgbDogMCwgcjogMCB9LFxuICAgIHNjZW5lOiB7XG4gICAgICB4YXhpczogeyAuLi5wbGFuZSB9LFxuICAgICAgeWF4aXM6IHsgLi4ucGxhbmUsIGJhY2tncm91bmRjb2xvcjogJ3JnYigyMzAsIDIzMCwgMjMwKScgfSxcbiAgICAgIHpheGlzOiB7IC4uLnBsYW5lIH0sXG4gICAgICBhc3BlY3RyYXRpbzogeyB4OiAxLCB5OiAxLCB6OiB6UmF0aW8gfSxcbiAgICAgIGFzcGVjdG1vZGU6ICdtYW51YWwnLFxuICAgIH0sXG4gIH07XG59XG4iXX0=
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { bt601Luminance, histogram256 } from '../../contracts/intensity';
|
|
2
|
+
import { PlotType } from '../../contracts/plot-type';
|
|
3
|
+
/**
|
|
4
|
+
* Pure reads of what the Plotly backend has on screen or in memory: a trace's
|
|
5
|
+
* pixels, a frame's histogram, the image rect the axes show, and the restyle
|
|
6
|
+
* that applies the channel display state.
|
|
7
|
+
*/
|
|
8
|
+
/** A plotted trace's `z` grid as flat pixels: an RGB `image` trace keeps its
|
|
9
|
+
* channels (3 or 4), a heatmap is one rounded channel. Null when empty. */
|
|
10
|
+
export function tracePixels(trace) {
|
|
11
|
+
const zData = trace?.z;
|
|
12
|
+
if (!zData)
|
|
13
|
+
return null;
|
|
14
|
+
const height = zData.length;
|
|
15
|
+
if (height === 0)
|
|
16
|
+
return null;
|
|
17
|
+
const width = zData[0].length;
|
|
18
|
+
if (trace.type === 'image') {
|
|
19
|
+
// RGB image: z[row][col] = [r, g, b] or [r, g, b, a]
|
|
20
|
+
const sample = zData[0][0];
|
|
21
|
+
const channels = Array.isArray(sample) ? sample.length : 3;
|
|
22
|
+
const data = new Uint8ClampedArray(width * height * channels);
|
|
23
|
+
for (let y = 0; y < height; y++) {
|
|
24
|
+
for (let x = 0; x < width; x++) {
|
|
25
|
+
const pixel = zData[y][x];
|
|
26
|
+
const offset = (y * width + x) * channels;
|
|
27
|
+
for (let c = 0; c < channels; c++)
|
|
28
|
+
data[offset + c] = pixel[c];
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return { width, height, channels, data };
|
|
32
|
+
}
|
|
33
|
+
// Heatmap (grayscale): z[row][col] = scalar value
|
|
34
|
+
const data = new Uint8ClampedArray(width * height);
|
|
35
|
+
for (let y = 0; y < height; y++) {
|
|
36
|
+
for (let x = 0; x < width; x++)
|
|
37
|
+
data[y * width + x] = Math.round(zData[y][x]);
|
|
38
|
+
}
|
|
39
|
+
return { width, height, channels: 1, data };
|
|
40
|
+
}
|
|
41
|
+
/** 256-bin histogram of one channel of a frame (raw, pre-LUT). Grayscale cells
|
|
42
|
+
* are numbers; RGB cells `[r,g,b]` give channel `channelIndex`, or the BT.601
|
|
43
|
+
* luminance for an index past their channels. */
|
|
44
|
+
export function frameHistogram(frame, channelIndex) {
|
|
45
|
+
const counts = new Array(256).fill(0);
|
|
46
|
+
for (const row of frame) {
|
|
47
|
+
if (!row)
|
|
48
|
+
continue;
|
|
49
|
+
for (const cell of row) {
|
|
50
|
+
let v;
|
|
51
|
+
if (Array.isArray(cell)) {
|
|
52
|
+
v =
|
|
53
|
+
channelIndex >= 0 && channelIndex < cell.length
|
|
54
|
+
? cell[channelIndex]
|
|
55
|
+
: Math.round(bt601Luminance(cell[0], cell[1], cell[2]));
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
v = cell;
|
|
59
|
+
}
|
|
60
|
+
v = v | 0;
|
|
61
|
+
if (v < 0)
|
|
62
|
+
v = 0;
|
|
63
|
+
else if (v > 255)
|
|
64
|
+
v = 255;
|
|
65
|
+
counts[v]++;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return histogram256(counts);
|
|
69
|
+
}
|
|
70
|
+
/** 256-bin histogram of a one-byte-per-pixel plane (a channel's raw pixels). */
|
|
71
|
+
export function planeHistogram(plane) {
|
|
72
|
+
const counts = new Array(256).fill(0);
|
|
73
|
+
for (let i = 0; i < plane.length; i++)
|
|
74
|
+
counts[plane[i]]++;
|
|
75
|
+
return histogram256(counts);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* The image rect the plot shows, from the live axis ranges — after a high-def
|
|
79
|
+
* zoom the axes are relaid out to the crop's bounds, so the ranges ARE the
|
|
80
|
+
* crop — else the whole image `[x0, x1, y0, y1]`, else null.
|
|
81
|
+
*/
|
|
82
|
+
export function axesSourceRect(xr, yr, trueImgSize) {
|
|
83
|
+
if (xr && yr) {
|
|
84
|
+
const x0 = Math.min(xr[0], xr[1]);
|
|
85
|
+
const y0 = Math.min(yr[0], yr[1]); // y axis is reversed for image layouts
|
|
86
|
+
return { x: x0, y: y0, width: Math.abs(xr[1] - xr[0]), height: Math.abs(yr[1] - yr[0]) };
|
|
87
|
+
}
|
|
88
|
+
if (!trueImgSize)
|
|
89
|
+
return null;
|
|
90
|
+
return {
|
|
91
|
+
x: trueImgSize[0],
|
|
92
|
+
y: trueImgSize[2],
|
|
93
|
+
width: trueImgSize[1] - trueImgSize[0],
|
|
94
|
+
height: trueImgSize[3] - trueImgSize[2],
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* The restyle that live-applies the channel display: the colour scale, reverse
|
|
99
|
+
* (reverse-scale and invert each flip the ramp; both together cancel) and the
|
|
100
|
+
* Intensity channel's window — cmin/cmax for the 3D plot types, zmin/zmax for
|
|
101
|
+
* heatmap/contour. A trace without a colour scale ignores these attributes.
|
|
102
|
+
*/
|
|
103
|
+
export function channelDisplayRestyle(channels, reverse, invert, colorscale, plotType) {
|
|
104
|
+
const update = { reversescale: reverse !== invert };
|
|
105
|
+
if (colorscale != null)
|
|
106
|
+
update['colorscale'] = colorscale;
|
|
107
|
+
const ch = channels?.[0];
|
|
108
|
+
if (ch) {
|
|
109
|
+
const threeD = plotType === PlotType.ISOSURFACE || plotType === PlotType.SURFACE || plotType === PlotType.SCATTER3D;
|
|
110
|
+
if (threeD)
|
|
111
|
+
Object.assign(update, { cmin: ch.min, cmax: ch.max, cauto: false });
|
|
112
|
+
else
|
|
113
|
+
Object.assign(update, { zmin: ch.min, zmax: ch.max, zauto: false });
|
|
114
|
+
}
|
|
115
|
+
return update;
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxvdGx5LXJlYWRiYWNrLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9pbXBsZW1lbnRhdGlvbnMvcGxvdGx5L3Bsb3RseS1yZWFkYmFjay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsY0FBYyxFQUFFLFlBQVksRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBR3pFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUdyRDs7OztHQUlHO0FBRUg7NEVBQzRFO0FBQzVFLE1BQU0sVUFBVSxXQUFXLENBQUMsS0FBaUQ7SUFDM0UsTUFBTSxLQUFLLEdBQUcsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUN2QixJQUFJLENBQUMsS0FBSztRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQ3hCLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUM7SUFDNUIsSUFBSSxNQUFNLEtBQUssQ0FBQztRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQzlCLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDOUIsSUFBSSxLQUFNLENBQUMsSUFBSSxLQUFLLE9BQU8sRUFBRSxDQUFDO1FBQzVCLHFEQUFxRDtRQUNyRCxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0IsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNELE1BQU0sSUFBSSxHQUFHLElBQUksaUJBQWlCLENBQUMsS0FBSyxHQUFHLE1BQU0sR0FBRyxRQUFRLENBQUMsQ0FBQztRQUM5RCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDaEMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO2dCQUMvQixNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzFCLE1BQU0sTUFBTSxHQUFHLENBQUMsQ0FBQyxHQUFHLEtBQUssR0FBRyxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUM7Z0JBQzFDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxRQUFRLEVBQUUsQ0FBQyxFQUFFO29CQUFFLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2pFLENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDO0lBQzNDLENBQUM7SUFDRCxrREFBa0Q7SUFDbEQsTUFBTSxJQUFJLEdBQUcsSUFBSSxpQkFBaUIsQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDLENBQUM7SUFDbkQsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ2hDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLEVBQUUsQ0FBQyxFQUFFO1lBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNoRixDQUFDO0lBQ0QsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQztBQUM5QyxDQUFDO0FBRUQ7O2tEQUVrRDtBQUNsRCxNQUFNLFVBQVUsY0FBYyxDQUFDLEtBQVksRUFBRSxZQUFvQjtJQUMvRCxNQUFNLE1BQU0sR0FBRyxJQUFJLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDdEMsS0FBSyxNQUFNLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsR0FBRztZQUFFLFNBQVM7UUFDbkIsS0FBSyxNQUFNLElBQUksSUFBSSxHQUFHLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQVMsQ0FBQztZQUNkLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUN4QixDQUFDO29CQUNDLFlBQVksSUFBSSxDQUFDLElBQUksWUFBWSxHQUFHLElBQUksQ0FBQyxNQUFNO3dCQUM3QyxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQzt3QkFDcEIsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM5RCxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sQ0FBQyxHQUFHLElBQUksQ0FBQztZQUNYLENBQUM7WUFDRCxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNWLElBQUksQ0FBQyxHQUFHLENBQUM7Z0JBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztpQkFDWixJQUFJLENBQUMsR0FBRyxHQUFHO2dCQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7WUFDMUIsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQzlCLENBQUM7QUFFRCxnRkFBZ0Y7QUFDaEYsTUFBTSxVQUFVLGNBQWMsQ0FBQyxLQUF3QjtJQUNyRCxNQUFNLE1BQU0sR0FBRyxJQUFJLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDdEMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFO1FBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDMUQsT0FBTyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDOUIsQ0FBQztBQUlEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsY0FBYyxDQUM1QixFQUF3QixFQUN4QixFQUF3QixFQUN4QixXQUFpQztJQUVqQyxJQUFJLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQztRQUNiLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2xDLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsdUNBQXVDO1FBQzFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQzNGLENBQUM7SUFDRCxJQUFJLENBQUMsV0FBVztRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQzlCLE9BQU87UUFDTCxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUNqQixDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUNqQixLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUM7UUFDdEMsTUFBTSxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDO0tBQ3hDLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUscUJBQXFCLENBQ25DLFFBQXlCLEVBQ3pCLE9BQWdCLEVBQ2hCLE1BQWUsRUFDZixVQUFtQixFQUNuQixRQUFrQjtJQUVsQixNQUFNLE1BQU0sR0FBNEIsRUFBRSxZQUFZLEVBQUUsT0FBTyxLQUFLLE1BQU0sRUFBRSxDQUFDO0lBQzdFLElBQUksVUFBVSxJQUFJLElBQUk7UUFBRSxNQUFNLENBQUMsWUFBWSxDQUFDLEdBQUcsVUFBVSxDQUFDO0lBQzFELE1BQU0sRUFBRSxHQUFHLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3pCLElBQUksRUFBRSxFQUFFLENBQUM7UUFDUCxNQUFNLE1BQU0sR0FDVixRQUFRLEtBQUssUUFBUSxDQUFDLFVBQVUsSUFBSSxRQUFRLEtBQUssUUFBUSxDQUFDLE9BQU8sSUFBSSxRQUFRLEtBQUssUUFBUSxDQUFDLFNBQVMsQ0FBQztRQUN2RyxJQUFJLE1BQU07WUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDOztZQUMzRSxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQzNFLENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgYnQ2MDFMdW1pbmFuY2UsIGhpc3RvZ3JhbTI1NiB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy9pbnRlbnNpdHknO1xuaW1wb3J0IHsgSUhpc3RvZ3JhbSB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy9jaGFubmVsLWhpc3RvZ3JhbS1hcGkuY29udHJhY3QnO1xuaW1wb3J0IHsgUGl4ZWxEYXRhIH0gZnJvbSAnLi4vLi4vY29udHJhY3RzL3Zpc3VhbGl6ZXIuY29udHJhY3QnO1xuaW1wb3J0IHsgUGxvdFR5cGUgfSBmcm9tICcuLi8uLi9jb250cmFjdHMvcGxvdC10eXBlJztcbmltcG9ydCB7IElDaGFubmVsU3RhdGUgfSBmcm9tICcuLi8uLi9jb250cmFjdHMvY2hhbm5lbC1oaXN0b2dyYW0tYXBpLmNvbnRyYWN0JztcblxuLyoqXG4gKiBQdXJlIHJlYWRzIG9mIHdoYXQgdGhlIFBsb3RseSBiYWNrZW5kIGhhcyBvbiBzY3JlZW4gb3IgaW4gbWVtb3J5OiBhIHRyYWNlJ3NcbiAqIHBpeGVscywgYSBmcmFtZSdzIGhpc3RvZ3JhbSwgdGhlIGltYWdlIHJlY3QgdGhlIGF4ZXMgc2hvdywgYW5kIHRoZSByZXN0eWxlXG4gKiB0aGF0IGFwcGxpZXMgdGhlIGNoYW5uZWwgZGlzcGxheSBzdGF0ZS5cbiAqL1xuXG4vKiogQSBwbG90dGVkIHRyYWNlJ3MgYHpgIGdyaWQgYXMgZmxhdCBwaXhlbHM6IGFuIFJHQiBgaW1hZ2VgIHRyYWNlIGtlZXBzIGl0c1xuICogIGNoYW5uZWxzICgzIG9yIDQpLCBhIGhlYXRtYXAgaXMgb25lIHJvdW5kZWQgY2hhbm5lbC4gTnVsbCB3aGVuIGVtcHR5LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyYWNlUGl4ZWxzKHRyYWNlOiB7IHR5cGU/OiBzdHJpbmc7IHo/OiBhbnlbXVtdIH0gfCB1bmRlZmluZWQpOiBQaXhlbERhdGEgfCBudWxsIHtcbiAgY29uc3QgekRhdGEgPSB0cmFjZT8uejtcbiAgaWYgKCF6RGF0YSkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IGhlaWdodCA9IHpEYXRhLmxlbmd0aDtcbiAgaWYgKGhlaWdodCA9PT0gMCkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IHdpZHRoID0gekRhdGFbMF0ubGVuZ3RoO1xuICBpZiAodHJhY2UhLnR5cGUgPT09ICdpbWFnZScpIHtcbiAgICAvLyBSR0IgaW1hZ2U6IHpbcm93XVtjb2xdID0gW3IsIGcsIGJdIG9yIFtyLCBnLCBiLCBhXVxuICAgIGNvbnN0IHNhbXBsZSA9IHpEYXRhWzBdWzBdO1xuICAgIGNvbnN0IGNoYW5uZWxzID0gQXJyYXkuaXNBcnJheShzYW1wbGUpID8gc2FtcGxlLmxlbmd0aCA6IDM7XG4gICAgY29uc3QgZGF0YSA9IG5ldyBVaW50OENsYW1wZWRBcnJheSh3aWR0aCAqIGhlaWdodCAqIGNoYW5uZWxzKTtcbiAgICBmb3IgKGxldCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7XG4gICAgICBmb3IgKGxldCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHtcbiAgICAgICAgY29uc3QgcGl4ZWwgPSB6RGF0YVt5XVt4XTtcbiAgICAgICAgY29uc3Qgb2Zmc2V0ID0gKHkgKiB3aWR0aCArIHgpICogY2hhbm5lbHM7XG4gICAgICAgIGZvciAobGV0IGMgPSAwOyBjIDwgY2hhbm5lbHM7IGMrKykgZGF0YVtvZmZzZXQgKyBjXSA9IHBpeGVsW2NdO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4geyB3aWR0aCwgaGVpZ2h0LCBjaGFubmVscywgZGF0YSB9O1xuICB9XG4gIC8vIEhlYXRtYXAgKGdyYXlzY2FsZSk6IHpbcm93XVtjb2xdID0gc2NhbGFyIHZhbHVlXG4gIGNvbnN0IGRhdGEgPSBuZXcgVWludDhDbGFtcGVkQXJyYXkod2lkdGggKiBoZWlnaHQpO1xuICBmb3IgKGxldCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7XG4gICAgZm9yIChsZXQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSBkYXRhW3kgKiB3aWR0aCArIHhdID0gTWF0aC5yb3VuZCh6RGF0YVt5XVt4XSk7XG4gIH1cbiAgcmV0dXJuIHsgd2lkdGgsIGhlaWdodCwgY2hhbm5lbHM6IDEsIGRhdGEgfTtcbn1cblxuLyoqIDI1Ni1iaW4gaGlzdG9ncmFtIG9mIG9uZSBjaGFubmVsIG9mIGEgZnJhbWUgKHJhdywgcHJlLUxVVCkuIEdyYXlzY2FsZSBjZWxsc1xuICogIGFyZSBudW1iZXJzOyBSR0IgY2VsbHMgYFtyLGcsYl1gIGdpdmUgY2hhbm5lbCBgY2hhbm5lbEluZGV4YCwgb3IgdGhlIEJULjYwMVxuICogIGx1bWluYW5jZSBmb3IgYW4gaW5kZXggcGFzdCB0aGVpciBjaGFubmVscy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmcmFtZUhpc3RvZ3JhbShmcmFtZTogYW55W10sIGNoYW5uZWxJbmRleDogbnVtYmVyKTogSUhpc3RvZ3JhbSB7XG4gIGNvbnN0IGNvdW50cyA9IG5ldyBBcnJheSgyNTYpLmZpbGwoMCk7XG4gIGZvciAoY29uc3Qgcm93IG9mIGZyYW1lKSB7XG4gICAgaWYgKCFyb3cpIGNvbnRpbnVlO1xuICAgIGZvciAoY29uc3QgY2VsbCBvZiByb3cpIHtcbiAgICAgIGxldCB2OiBudW1iZXI7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShjZWxsKSkge1xuICAgICAgICB2ID1cbiAgICAgICAgICBjaGFubmVsSW5kZXggPj0gMCAmJiBjaGFubmVsSW5kZXggPCBjZWxsLmxlbmd0aFxuICAgICAgICAgICAgPyBjZWxsW2NoYW5uZWxJbmRleF1cbiAgICAgICAgICAgIDogTWF0aC5yb3VuZChidDYwMUx1bWluYW5jZShjZWxsWzBdLCBjZWxsWzFdLCBjZWxsWzJdKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2ID0gY2VsbDtcbiAgICAgIH1cbiAgICAgIHYgPSB2IHwgMDtcbiAgICAgIGlmICh2IDwgMCkgdiA9IDA7XG4gICAgICBlbHNlIGlmICh2ID4gMjU1KSB2ID0gMjU1O1xuICAgICAgY291bnRzW3ZdKys7XG4gICAgfVxuICB9XG4gIHJldHVybiBoaXN0b2dyYW0yNTYoY291bnRzKTtcbn1cblxuLyoqIDI1Ni1iaW4gaGlzdG9ncmFtIG9mIGEgb25lLWJ5dGUtcGVyLXBpeGVsIHBsYW5lIChhIGNoYW5uZWwncyByYXcgcGl4ZWxzKS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwbGFuZUhpc3RvZ3JhbShwbGFuZTogQXJyYXlMaWtlPG51bWJlcj4pOiBJSGlzdG9ncmFtIHtcbiAgY29uc3QgY291bnRzID0gbmV3IEFycmF5KDI1NikuZmlsbCgwKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBwbGFuZS5sZW5ndGg7IGkrKykgY291bnRzW3BsYW5lW2ldXSsrO1xuICByZXR1cm4gaGlzdG9ncmFtMjU2KGNvdW50cyk7XG59XG5cbnR5cGUgUmVjdCA9IHsgeDogbnVtYmVyOyB5OiBudW1iZXI7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH07XG5cbi8qKlxuICogVGhlIGltYWdlIHJlY3QgdGhlIHBsb3Qgc2hvd3MsIGZyb20gdGhlIGxpdmUgYXhpcyByYW5nZXMg4oCUIGFmdGVyIGEgaGlnaC1kZWZcbiAqIHpvb20gdGhlIGF4ZXMgYXJlIHJlbGFpZCBvdXQgdG8gdGhlIGNyb3AncyBib3VuZHMsIHNvIHRoZSByYW5nZXMgQVJFIHRoZVxuICogY3JvcCDigJQgZWxzZSB0aGUgd2hvbGUgaW1hZ2UgYFt4MCwgeDEsIHkwLCB5MV1gLCBlbHNlIG51bGwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBheGVzU291cmNlUmVjdChcbiAgeHI6IG51bWJlcltdIHwgdW5kZWZpbmVkLFxuICB5cjogbnVtYmVyW10gfCB1bmRlZmluZWQsXG4gIHRydWVJbWdTaXplOiBudW1iZXJbXSB8IHVuZGVmaW5lZCxcbik6IFJlY3QgfCBudWxsIHtcbiAgaWYgKHhyICYmIHlyKSB7XG4gICAgY29uc3QgeDAgPSBNYXRoLm1pbih4clswXSwgeHJbMV0pO1xuICAgIGNvbnN0IHkwID0gTWF0aC5taW4oeXJbMF0sIHlyWzFdKTsgLy8geSBheGlzIGlzIHJldmVyc2VkIGZvciBpbWFnZSBsYXlvdXRzXG4gICAgcmV0dXJuIHsgeDogeDAsIHk6IHkwLCB3aWR0aDogTWF0aC5hYnMoeHJbMV0gLSB4clswXSksIGhlaWdodDogTWF0aC5hYnMoeXJbMV0gLSB5clswXSkgfTtcbiAgfVxuICBpZiAoIXRydWVJbWdTaXplKSByZXR1cm4gbnVsbDtcbiAgcmV0dXJuIHtcbiAgICB4OiB0cnVlSW1nU2l6ZVswXSxcbiAgICB5OiB0cnVlSW1nU2l6ZVsyXSxcbiAgICB3aWR0aDogdHJ1ZUltZ1NpemVbMV0gLSB0cnVlSW1nU2l6ZVswXSxcbiAgICBoZWlnaHQ6IHRydWVJbWdTaXplWzNdIC0gdHJ1ZUltZ1NpemVbMl0sXG4gIH07XG59XG5cbi8qKlxuICogVGhlIHJlc3R5bGUgdGhhdCBsaXZlLWFwcGxpZXMgdGhlIGNoYW5uZWwgZGlzcGxheTogdGhlIGNvbG91ciBzY2FsZSwgcmV2ZXJzZVxuICogKHJldmVyc2Utc2NhbGUgYW5kIGludmVydCBlYWNoIGZsaXAgdGhlIHJhbXA7IGJvdGggdG9nZXRoZXIgY2FuY2VsKSBhbmQgdGhlXG4gKiBJbnRlbnNpdHkgY2hhbm5lbCdzIHdpbmRvdyDigJQgY21pbi9jbWF4IGZvciB0aGUgM0QgcGxvdCB0eXBlcywgem1pbi96bWF4IGZvclxuICogaGVhdG1hcC9jb250b3VyLiBBIHRyYWNlIHdpdGhvdXQgYSBjb2xvdXIgc2NhbGUgaWdub3JlcyB0aGVzZSBhdHRyaWJ1dGVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2hhbm5lbERpc3BsYXlSZXN0eWxlKFxuICBjaGFubmVsczogSUNoYW5uZWxTdGF0ZVtdLFxuICByZXZlcnNlOiBib29sZWFuLFxuICBpbnZlcnQ6IGJvb2xlYW4sXG4gIGNvbG9yc2NhbGU6IHVua25vd24sXG4gIHBsb3RUeXBlOiBQbG90VHlwZSxcbik6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgY29uc3QgdXBkYXRlOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHsgcmV2ZXJzZXNjYWxlOiByZXZlcnNlICE9PSBpbnZlcnQgfTtcbiAgaWYgKGNvbG9yc2NhbGUgIT0gbnVsbCkgdXBkYXRlWydjb2xvcnNjYWxlJ10gPSBjb2xvcnNjYWxlO1xuICBjb25zdCBjaCA9IGNoYW5uZWxzPy5bMF07XG4gIGlmIChjaCkge1xuICAgIGNvbnN0IHRocmVlRCA9XG4gICAgICBwbG90VHlwZSA9PT0gUGxvdFR5cGUuSVNPU1VSRkFDRSB8fCBwbG90VHlwZSA9PT0gUGxvdFR5cGUuU1VSRkFDRSB8fCBwbG90VHlwZSA9PT0gUGxvdFR5cGUuU0NBVFRFUjNEO1xuICAgIGlmICh0aHJlZUQpIE9iamVjdC5hc3NpZ24odXBkYXRlLCB7IGNtaW46IGNoLm1pbiwgY21heDogY2gubWF4LCBjYXV0bzogZmFsc2UgfSk7XG4gICAgZWxzZSBPYmplY3QuYXNzaWduKHVwZGF0ZSwgeyB6bWluOiBjaC5taW4sIHptYXg6IGNoLm1heCwgemF1dG86IGZhbHNlIH0pO1xuICB9XG4gIHJldHVybiB1cGRhdGU7XG59XG4iXX0=
|
|
@@ -16,16 +16,25 @@ export class PlotlyRegionOverlay {
|
|
|
16
16
|
setMode(mode) {
|
|
17
17
|
// 'select' is a neutral mode for Plotly (no drag mode); region selection is
|
|
18
18
|
// driven by the table / active-shape sampling, so just clear the drag mode.
|
|
19
|
-
const dragMode = mode === 'drawrect'
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
const dragMode = mode === 'drawrect'
|
|
20
|
+
? 'drawrect'
|
|
21
|
+
: mode === 'drawclosedpath'
|
|
22
|
+
? 'drawclosedpath'
|
|
23
|
+
: mode === 'drawopenpath'
|
|
24
|
+
? 'drawopenpath'
|
|
25
|
+
: false;
|
|
23
26
|
this.plotly.setDragMode(dragMode);
|
|
24
27
|
}
|
|
25
|
-
redraw() {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
redraw() {
|
|
29
|
+
/* Plotly re-renders its shapes natively on relayout */
|
|
30
|
+
}
|
|
31
|
+
/** Bezier regions are drawn by the SVG overlays (OpenSeadragon, napari-js);
|
|
32
|
+
* Plotly has no native curved-shape rendering, so this is a no-op here. */
|
|
33
|
+
setSelectedBezier(_bezier) {
|
|
34
|
+
/* not rendered by Plotly */
|
|
35
|
+
}
|
|
36
|
+
destroy() {
|
|
37
|
+
/* nothing to tear down — shapes live in the Plotly layout */
|
|
38
|
+
}
|
|
30
39
|
}
|
|
31
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
40
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxvdGx5LXJlZ2lvbi1vdmVybGF5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9pbXBsZW1lbnRhdGlvbnMvcGxvdGx5L3Bsb3RseS1yZWdpb24tb3ZlcmxheS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHQTs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxPQUFPLG1CQUFtQjtJQUM5QixZQUFvQixNQUFxQjtRQUFyQixXQUFNLEdBQU4sTUFBTSxDQUFlO0lBQUcsQ0FBQztJQUU3QyxPQUFPLENBQUMsSUFBb0I7UUFDMUIsNEVBQTRFO1FBQzVFLDRFQUE0RTtRQUM1RSxNQUFNLFFBQVEsR0FDWixJQUFJLEtBQUssVUFBVTtZQUNqQixDQUFDLENBQUMsVUFBVTtZQUNaLENBQUMsQ0FBQyxJQUFJLEtBQUssZ0JBQWdCO2dCQUN6QixDQUFDLENBQUMsZ0JBQWdCO2dCQUNsQixDQUFDLENBQUMsSUFBSSxLQUFLLGNBQWM7b0JBQ3ZCLENBQUMsQ0FBQyxjQUFjO29CQUNoQixDQUFDLENBQUMsS0FBSyxDQUFDO1FBQ2hCLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRCxNQUFNO1FBQ0osdURBQXVEO0lBQ3pELENBQUM7SUFFRDtnRkFDNEU7SUFDNUUsaUJBQWlCLENBQUMsT0FBZ0I7UUFDaEMsNEJBQTRCO0lBQzlCLENBQUM7SUFFRCxPQUFPO1FBQ0wsNkRBQTZEO0lBQy9ELENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBsb3RseVNlcnZpY2UgfSBmcm9tICcuL3Bsb3RseS5zZXJ2aWNlJztcbmltcG9ydCB7IElSZWdpb25PdmVybGF5LCBSZWdpb25Ub29sTW9kZSB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy9yZWdpb24tb3ZlcmxheS5jb250cmFjdCc7XG5cbi8qKlxuICogUGxvdGx5IGltcGxlbWVudGF0aW9uIG9mIHtAbGluayBJUmVnaW9uT3ZlcmxheX0uXG4gKlxuICogUGxvdGx5IHJlbmRlcnMgcmVnaW9uIHNoYXBlcyBuYXRpdmVseSBpbiBpdHMgcGxvdCBsYXlvdXQgYW5kIGVkaXRzIHRoZW0gdmlhXG4gKiBpdHMgb3duIGRyYWcgbW9kZXMsIHNvIHRoaXMgYWRhcHRlciBpcyB0aGluOiBpdCBtYXBzIHRoZSBuZXV0cmFsXG4gKiB7QGxpbmsgUmVnaW9uVG9vbE1vZGV9IG9udG8gUGxvdGx5IGRyYWcgbW9kZXMgYW5kIGxldHMgUGxvdGx5IGRyYXcuIGByZWRyYXdgXG4gKiBpcyBhIG5vLW9wIGJlY2F1c2UgUGxvdGx5IHJlLXJlbmRlcnMgaXRzIHNoYXBlcyBpdHNlbGYgb24gcmVsYXlvdXQuXG4gKlxuICogSXQgaXMgdGhlIHN5bW1ldHJpYyBjb3VudGVycGFydCB0byB7QGxpbmsgT3NkUmVnaW9uT3ZlcmxheX06IGJvdGggcmVuZGVyIHRoZVxuICogc2FtZSBzaGFyZWQgYElSZWdpb25TdG9yZWAsIGVhY2ggb250byBpdHMgb3duIGJhY2tlbmQncyBjYW52YXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBQbG90bHlSZWdpb25PdmVybGF5IGltcGxlbWVudHMgSVJlZ2lvbk92ZXJsYXkge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHBsb3RseTogUGxvdGx5U2VydmljZSkge31cblxuICBzZXRNb2RlKG1vZGU6IFJlZ2lvblRvb2xNb2RlKTogdm9pZCB7XG4gICAgLy8gJ3NlbGVjdCcgaXMgYSBuZXV0cmFsIG1vZGUgZm9yIFBsb3RseSAobm8gZHJhZyBtb2RlKTsgcmVnaW9uIHNlbGVjdGlvbiBpc1xuICAgIC8vIGRyaXZlbiBieSB0aGUgdGFibGUgLyBhY3RpdmUtc2hhcGUgc2FtcGxpbmcsIHNvIGp1c3QgY2xlYXIgdGhlIGRyYWcgbW9kZS5cbiAgICBjb25zdCBkcmFnTW9kZSA9XG4gICAgICBtb2RlID09PSAnZHJhd3JlY3QnXG4gICAgICAgID8gJ2RyYXdyZWN0J1xuICAgICAgICA6IG1vZGUgPT09ICdkcmF3Y2xvc2VkcGF0aCdcbiAgICAgICAgICA/ICdkcmF3Y2xvc2VkcGF0aCdcbiAgICAgICAgICA6IG1vZGUgPT09ICdkcmF3b3BlbnBhdGgnXG4gICAgICAgICAgICA/ICdkcmF3b3BlbnBhdGgnXG4gICAgICAgICAgICA6IGZhbHNlO1xuICAgIHRoaXMucGxvdGx5LnNldERyYWdNb2RlKGRyYWdNb2RlKTtcbiAgfVxuXG4gIHJlZHJhdygpOiB2b2lkIHtcbiAgICAvKiBQbG90bHkgcmUtcmVuZGVycyBpdHMgc2hhcGVzIG5hdGl2ZWx5IG9uIHJlbGF5b3V0ICovXG4gIH1cblxuICAvKiogQmV6aWVyIHJlZ2lvbnMgYXJlIGRyYXduIGJ5IHRoZSBTVkcgb3ZlcmxheXMgKE9wZW5TZWFkcmFnb24sIG5hcGFyaS1qcyk7XG4gICAqICBQbG90bHkgaGFzIG5vIG5hdGl2ZSBjdXJ2ZWQtc2hhcGUgcmVuZGVyaW5nLCBzbyB0aGlzIGlzIGEgbm8tb3AgaGVyZS4gKi9cbiAgc2V0U2VsZWN0ZWRCZXppZXIoX2JlemllcjogYm9vbGVhbik6IHZvaWQge1xuICAgIC8qIG5vdCByZW5kZXJlZCBieSBQbG90bHkgKi9cbiAgfVxuXG4gIGRlc3Ryb3koKTogdm9pZCB7XG4gICAgLyogbm90aGluZyB0byB0ZWFyIGRvd24g4oCUIHNoYXBlcyBsaXZlIGluIHRoZSBQbG90bHkgbGF5b3V0ICovXG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import * as Plotly from 'plotly.js-dist-min';
|
|
2
|
+
import { Subscription } from 'rxjs';
|
|
3
|
+
import { ShapeSelection } from '../../models/shape';
|
|
4
|
+
import { PlotUtilities } from '../../plot.utilities';
|
|
5
|
+
/**
|
|
6
|
+
* Plotly's render projection of the shared RegionStore: `shapes` is the dict
|
|
7
|
+
* array `Plotly.relayout` consumes, kept beside the store. Shapes edited or
|
|
8
|
+
* drawn on the Plotly canvas are mirrored INTO the store ({@link commitToStore});
|
|
9
|
+
* every other change — wherever it was made — arrives as a store update event
|
|
10
|
+
* and is projected back OUT and redrawn ({@link connect}). Also maps the store's
|
|
11
|
+
* selection onto Plotly's `_activeShapeIndex` (the shape with the edit handles)
|
|
12
|
+
* and back.
|
|
13
|
+
*/
|
|
14
|
+
export class PlotlyShapeProjection {
|
|
15
|
+
constructor(host, regionStore) {
|
|
16
|
+
this.host = host;
|
|
17
|
+
this.regionStore = regionStore;
|
|
18
|
+
/** The render projection: one Plotly shape dict per store region. */
|
|
19
|
+
this.shapes = [];
|
|
20
|
+
/** Nesting depth of {@link quietly}: region updates are not redrawn while > 0. */
|
|
21
|
+
this.muted = 0;
|
|
22
|
+
this.utils = new PlotUtilities();
|
|
23
|
+
}
|
|
24
|
+
/** The plot div, live Plotly graph or not (null when none is set). */
|
|
25
|
+
gd() {
|
|
26
|
+
const id = this.host.plotDiv();
|
|
27
|
+
return id ? document.getElementById(id) : null;
|
|
28
|
+
}
|
|
29
|
+
/** The plot div while it hosts a live Plotly graph, else null: the div stays
|
|
30
|
+
* set after it was handed to another backend, and Plotly throws on it then. */
|
|
31
|
+
liveGd() {
|
|
32
|
+
const gd = this.gd();
|
|
33
|
+
return gd?._fullLayout ? gd : null;
|
|
34
|
+
}
|
|
35
|
+
/** Rebuild the dict working-set from the store (after an image switch, or when
|
|
36
|
+
* regions changed while another backend was rendering). */
|
|
37
|
+
syncFromStore() {
|
|
38
|
+
const showLabel = this.regionStore.getShowShapeLabel();
|
|
39
|
+
this.shapes = this.regionStore.getRegions().map((r) => {
|
|
40
|
+
r.filename = this.host.fileName();
|
|
41
|
+
return { ...r.getShape(showLabel) };
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Make the shared store authoritative for the current dict working-set: convert
|
|
46
|
+
* the dicts to neutral regions and replace the store's list (the store mints
|
|
47
|
+
* ids, applies class colours, syncs its per-image cache and emits the
|
|
48
|
+
* region-update event). Store-minted ids are written back onto the dicts so the
|
|
49
|
+
* two representations stay aligned. Profile-line ROIs are ordinary regions
|
|
50
|
+
* (tagged `kind: 'profile'`) and round-trip through here too.
|
|
51
|
+
*/
|
|
52
|
+
commitToStore() {
|
|
53
|
+
const regions = this.shapes.map((s) => Object.assign(new ShapeSelection(), s).getRegion());
|
|
54
|
+
// The canvas already shows these shapes: don't redraw them from the update.
|
|
55
|
+
this.quietly(() => this.regionStore.setRegions(regions, this.regionStore.getShowShapeLabel(), true, this.regionStore.getFillColor(), false));
|
|
56
|
+
const stored = this.regionStore.getRegions();
|
|
57
|
+
for (let i = 0; i < this.shapes.length && i < stored.length; i++) {
|
|
58
|
+
if (this.shapes[i].id == null)
|
|
59
|
+
this.shapes[i].id = stored[i].id;
|
|
60
|
+
if (this.shapes[i].name == null)
|
|
61
|
+
this.shapes[i].name = stored[i].name;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Apply a `plotly_relayout` event's shape part: in-place edits
|
|
66
|
+
* (`shapes[i].x0`, `shapes[i].path`, …, rounded to whole pixels) and a shape
|
|
67
|
+
* drawn natively on the canvas (a lone `shapes` key — snapped, tagged with
|
|
68
|
+
* the file and, when labels are on, a label object), mirrored into the store.
|
|
69
|
+
*/
|
|
70
|
+
applyRelayout(event) {
|
|
71
|
+
let shapesModified = false;
|
|
72
|
+
for (const key of Object.keys(event)) {
|
|
73
|
+
if (!key.startsWith('shapes['))
|
|
74
|
+
continue;
|
|
75
|
+
const shapeNumber = +key.split('[')[1].split(']')[0];
|
|
76
|
+
const shapeChange = key.split('.')[1];
|
|
77
|
+
if (this.shapes && this.shapes[shapeNumber]) {
|
|
78
|
+
this.shapes[shapeNumber][shapeChange] =
|
|
79
|
+
shapeChange === 'path' ? this.utils.roundPathCoordinates(event[key]) : Math.round(+event[key]);
|
|
80
|
+
shapesModified = true;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (shapesModified)
|
|
84
|
+
this.commitToStore();
|
|
85
|
+
if (Object.keys(event).length === 1 && 'shapes' in event) {
|
|
86
|
+
this.shapes = event['shapes'];
|
|
87
|
+
for (let i = 0; i < this.shapes.length; i++) {
|
|
88
|
+
// A freshly Plotly-drawn shape has no id yet — give it a label object
|
|
89
|
+
// (when labels are on) before the store mints id + default name.
|
|
90
|
+
const isNew = this.shapes[i].id == null;
|
|
91
|
+
this.shapes[i].fileName = this.host.fileName();
|
|
92
|
+
this.shapes[i] = this.utils.snapRegion(this.shapes[i]);
|
|
93
|
+
if (isNew && this.regionStore.getShowShapeLabel()) {
|
|
94
|
+
this.shapes[i].label = {
|
|
95
|
+
text: this.shapes[i].label,
|
|
96
|
+
texttemplate: this.shapes[i].label,
|
|
97
|
+
font: { color: this.regionStore.getShapeColor() },
|
|
98
|
+
textposition: 'top left',
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Mint ids/names in the store, write them back onto the dicts, and emit.
|
|
103
|
+
this.commitToStore();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/** Push the dict working-set to Plotly (a no-op when another backend owns the div). */
|
|
107
|
+
render() {
|
|
108
|
+
const gd = this.liveGd();
|
|
109
|
+
if (!gd)
|
|
110
|
+
return;
|
|
111
|
+
void Plotly.relayout(gd, this.relayoutPayload(this.shapes.map((s) => ({ ...s }))));
|
|
112
|
+
}
|
|
113
|
+
/** The shapes of the image on screen, labelled (or not) for display, as fresh dicts. */
|
|
114
|
+
shapesToRedraw(showLabel = this.regionStore.getShowShapeLabel()) {
|
|
115
|
+
const shapesToRedraw = [];
|
|
116
|
+
for (const shape of this.shapes) {
|
|
117
|
+
if (JSON.stringify(shape.fileName) === JSON.stringify(this.host.fileName())) {
|
|
118
|
+
shape.label = showLabel
|
|
119
|
+
? {
|
|
120
|
+
text: `${shape.legend}`,
|
|
121
|
+
texttemplate: `${shape.legend}`,
|
|
122
|
+
textposition: 'top left',
|
|
123
|
+
font: { color: `${shape.line.color}` },
|
|
124
|
+
}
|
|
125
|
+
: {};
|
|
126
|
+
shapesToRedraw.push(shape);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// convert to dict so that plotly recognises the shapes
|
|
130
|
+
return shapesToRedraw.map((s) => ({ ...s }));
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Follow the shared store: redraw the shapes on every region update and move
|
|
134
|
+
* the edit handles on every selection change, whoever made the change (the
|
|
135
|
+
* router, an undo, the Region Editor, another backend's overlay, a canvas
|
|
136
|
+
* tool). Plotly is not on the store's write path any more — it listens, like
|
|
137
|
+
* the OpenSeadragon and napari-js overlays do. Service-lifetime: both
|
|
138
|
+
* callbacks no-op while no live Plotly graph holds the div.
|
|
139
|
+
*/
|
|
140
|
+
connect() {
|
|
141
|
+
const subs = new Subscription();
|
|
142
|
+
subs.add(this.regionStore.getRegionUpdateEvent().subscribe((regions) => this.onRegionUpdate(regions)));
|
|
143
|
+
subs.add(this.regionStore.getSelectedShapeIndices$().subscribe((indices) => this.onSelection(indices)));
|
|
144
|
+
return subs;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Run `write` — a store write this projection already reflects (a shape edited
|
|
148
|
+
* on the canvas, an image switch the next plot draws) — without redrawing from
|
|
149
|
+
* the update event it causes.
|
|
150
|
+
*/
|
|
151
|
+
quietly(write) {
|
|
152
|
+
this.muted++;
|
|
153
|
+
try {
|
|
154
|
+
write();
|
|
155
|
+
}
|
|
156
|
+
finally {
|
|
157
|
+
this.muted--;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* A region update. The stored set re-projects and redraws; a transient set
|
|
162
|
+
* (`setRegions(…, isRegionSaveOn = false)`, which the store emits without
|
|
163
|
+
* storing) is drawn as-is and leaves the working-set alone.
|
|
164
|
+
*/
|
|
165
|
+
onRegionUpdate(regions) {
|
|
166
|
+
if (this.muted > 0)
|
|
167
|
+
return;
|
|
168
|
+
const stored = this.regionStore.getRegions();
|
|
169
|
+
const isStored = regions.length === stored.length && regions.every((r, i) => r === stored[i]);
|
|
170
|
+
if (isStored) {
|
|
171
|
+
this.syncFromStore();
|
|
172
|
+
this.render();
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const gd = this.liveGd();
|
|
176
|
+
if (!gd)
|
|
177
|
+
return;
|
|
178
|
+
const showLabel = this.regionStore.getShowShapeLabel();
|
|
179
|
+
const dicts = regions.map((r) => {
|
|
180
|
+
r.filename = this.host.fileName();
|
|
181
|
+
return { ...r.getShape(showLabel) };
|
|
182
|
+
});
|
|
183
|
+
void Plotly.relayout(gd, this.relayoutPayload(dicts));
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* A selection change: Plotly's `_activeShapeIndex` points at the last selected
|
|
187
|
+
* shape so it gets the edit handles (Plotly's own active-shape rendering is the
|
|
188
|
+
* only highlight). Skipped when the plot already shows it — the change came
|
|
189
|
+
* from a click on the plot ({@link syncSelectionFromPlot}).
|
|
190
|
+
*/
|
|
191
|
+
onSelection(indices) {
|
|
192
|
+
const gd = this.liveGd();
|
|
193
|
+
if (!gd)
|
|
194
|
+
return;
|
|
195
|
+
const active = indices.length > 0 ? indices[indices.length - 1] : -1;
|
|
196
|
+
if ((gd._fullLayout._activeShapeIndex ?? -1) === active)
|
|
197
|
+
return;
|
|
198
|
+
gd._fullLayout._activeShapeIndex = active;
|
|
199
|
+
try {
|
|
200
|
+
void Plotly.redraw(gd);
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
/* noop in tests */
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Read Plotly's `_activeShapeIndex` and push it as the selection. Plotly fires
|
|
208
|
+
* no dedicated active-shape event for clicks, so this is sampled after a
|
|
209
|
+
* relayout and a click. The store no-ops when the selection is unchanged.
|
|
210
|
+
*/
|
|
211
|
+
syncSelectionFromPlot() {
|
|
212
|
+
if (!this.host.plotDiv())
|
|
213
|
+
return;
|
|
214
|
+
const raw = this.gd()?._fullLayout?._activeShapeIndex;
|
|
215
|
+
const idx = typeof raw === 'number' && raw >= 0 && raw < this.shapes.length ? raw : -1;
|
|
216
|
+
this.regionStore.setSelectedShapeIndices(idx >= 0 ? [idx] : []);
|
|
217
|
+
}
|
|
218
|
+
/** The shapes-relayout payload: the shapes plus the active-shape fill colour. */
|
|
219
|
+
relayoutPayload(shapeDicts) {
|
|
220
|
+
return { shapes: shapeDicts, activeshape: { fillcolor: this.regionStore.getFillColor() } };
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxvdGx5LXNoYXBlLXByb2plY3Rpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2ltcGxlbWVudGF0aW9ucy9wbG90bHkvcGxvdGx5LXNoYXBlLXByb2plY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE1BQU0sTUFBTSxvQkFBb0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBR3BDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVwRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFhckQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLE9BQU8scUJBQXFCO0lBT2hDLFlBQ21CLElBQXlCLEVBQ3pCLFdBQXdCO1FBRHhCLFNBQUksR0FBSixJQUFJLENBQXFCO1FBQ3pCLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBUjNDLHFFQUFxRTtRQUNyRSxXQUFNLEdBQVUsRUFBRSxDQUFDO1FBQ25CLGtGQUFrRjtRQUMxRSxVQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQ0QsVUFBSyxHQUFHLElBQUksYUFBYSxFQUFFLENBQUM7SUFLMUMsQ0FBQztJQUVKLHNFQUFzRTtJQUM5RCxFQUFFO1FBQ1IsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUMvQixPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUUsUUFBUSxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQXFCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUN0RSxDQUFDO0lBRUQ7b0ZBQ2dGO0lBQ3hFLE1BQU07UUFDWixNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDckIsT0FBTyxFQUFFLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FB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U0FBUyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsWUFBWSxFQUFFLEVBQUUsRUFBRSxDQUFDO0lBQzdGLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIFBsb3RseSBmcm9tICdwbG90bHkuanMtZGlzdC1taW4nO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IFJlZ2lvbiB9IGZyb20gJy4uLy4uL21vZGVscy9yZWdpb24nO1xuaW1wb3J0IHsgU2hhcGVTZWxlY3Rpb24gfSBmcm9tICcuLi8uLi9tb2RlbHMvc2hhcGUnO1xuaW1wb3J0IHsgUmVnaW9uU3RvcmUgfSBmcm9tICcuLi8uLi9zdG9yZS9yZWdpb24tc3RvcmUuc2VydmljZSc7XG5pbXBvcnQgeyBQbG90VXRpbGl0aWVzIH0gZnJvbSAnLi4vLi4vcGxvdC51dGlsaXRpZXMnO1xuXG4vKiogQSBQbG90bHkgZ3JhcGggZGl2LCBhcyBmYXIgYXMgdGhlIHByb2plY3Rpb24gcmVhZHMgaXQuICovXG50eXBlIEdyYXBoRGl2ID0gSFRNTEVsZW1lbnQgJiB7IF9mdWxsTGF5b3V0PzogeyBfYWN0aXZlU2hhcGVJbmRleD86IG51bWJlciB9IH07XG5cbi8qKiBUaGUgc2VydmljZSBzdGF0ZSB0aGUgcHJvamVjdGlvbiByZWFkcy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2hhcGVQcm9qZWN0aW9uSG9zdCB7XG4gIC8qKiBUaGUgcGxvdCBkaXYncyBpZCAoJycgYmVmb3JlIHRoZSBmaXJzdCBwbG90KTsgaXQgbWF5IGJlIGFub3RoZXIgYmFja2VuZCdzIG5vdy4gKi9cbiAgcGxvdERpdigpOiBzdHJpbmc7XG4gIC8qKiBUaGUgaW1hZ2Ugb24gc2NyZWVuIChzaGFwZXMgYXJlIHRhZ2dlZCB3aXRoIGl0KS4gKi9cbiAgZmlsZU5hbWUoKTogc3RyaW5nIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFBsb3RseSdzIHJlbmRlciBwcm9qZWN0aW9uIG9mIHRoZSBzaGFyZWQgUmVnaW9uU3RvcmU6IGBzaGFwZXNgIGlzIHRoZSBkaWN0XG4gKiBhcnJheSBgUGxvdGx5LnJlbGF5b3V0YCBjb25zdW1lcywga2VwdCBiZXNpZGUgdGhlIHN0b3JlLiBTaGFwZXMgZWRpdGVkIG9yXG4gKiBkcmF3biBvbiB0aGUgUGxvdGx5IGNhbnZhcyBhcmUgbWlycm9yZWQgSU5UTyB0aGUgc3RvcmUgKHtAbGluayBjb21taXRUb1N0b3JlfSk7XG4gKiBldmVyeSBvdGhlciBjaGFuZ2Ug4oCUIHdoZXJldmVyIGl0IHdhcyBtYWRlIOKAlCBhcnJpdmVzIGFzIGEgc3RvcmUgdXBkYXRlIGV2ZW50XG4gKiBhbmQgaXMgcHJvamVjdGVkIGJhY2sgT1VUIGFuZCByZWRyYXduICh7QGxpbmsgY29ubmVjdH0pLiBBbHNvIG1hcHMgdGhlIHN0b3JlJ3NcbiAqIHNlbGVjdGlvbiBvbnRvIFBsb3RseSdzIGBfYWN0aXZlU2hhcGVJbmRleGAgKHRoZSBzaGFwZSB3aXRoIHRoZSBlZGl0IGhhbmRsZXMpXG4gKiBhbmQgYmFjay5cbiAqL1xuZXhwb3J0IGNsYXNzIFBsb3RseVNoYXBlUHJvamVjdGlvbiB7XG4gIC8qKiBUaGUgcmVuZGVyIHByb2plY3Rpb246IG9uZSBQbG90bHkgc2hhcGUgZGljdCBwZXIgc3RvcmUgcmVnaW9uLiAqL1xuICBzaGFwZXM6IGFueVtdID0gW107XG4gIC8qKiBOZXN0aW5nIGRlcHRoIG9mIHtAbGluayBxdWlldGx5fTogcmVnaW9uIHVwZGF0ZXMgYXJlIG5vdCByZWRyYXduIHdoaWxlID4gMC4gKi9cbiAgcHJpdmF0ZSBtdXRlZCA9IDA7XG4gIHByaXZhdGUgcmVhZG9ubHkgdXRpbHMgPSBuZXcgUGxvdFV0aWxpdGllcygpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgaG9zdDogU2hhcGVQcm9qZWN0aW9uSG9zdCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJlZ2lvblN0b3JlOiBSZWdpb25TdG9yZSxcbiAgKSB7fVxuXG4gIC8qKiBUaGUgcGxvdCBkaXYsIGxpdmUgUGxvdGx5IGdyYXBoIG9yIG5vdCAobnVsbCB3aGVuIG5vbmUgaXMgc2V0KS4gKi9cbiAgcHJpdmF0ZSBnZCgpOiBHcmFwaERpdiB8IG51bGwge1xuICAgIGNvbnN0IGlkID0gdGhpcy5ob3N0LnBsb3REaXYoKTtcbiAgICByZXR1cm4gaWQgPyAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpIGFzIEdyYXBoRGl2IHwgbnVsbCkgOiBudWxsO1xuICB9XG5cbiAgLyoqIFRoZSBwbG90IGRpdiB3aGlsZSBpdCBob3N0cyBhIGxpdmUgUGxvdGx5IGdyYXBoLCBlbHNlIG51bGw6IHRoZSBkaXYgc3RheXNcbiAgICogIHNldCBhZnRlciBpdCB3YXMgaGFuZGVkIHRvIGFub3RoZXIgYmFja2VuZCwgYW5kIFBsb3RseSB0aHJvd3Mgb24gaXQgdGhlbi4gKi9cbiAgcHJpdmF0ZSBsaXZlR2QoKTogR3JhcGhEaXYgfCBudWxsIHtcbiAgICBjb25zdCBnZCA9IHRoaXMuZ2QoKTtcbiAgICByZXR1cm4gZ2Q/Ll9mdWxsTGF5b3V0ID8gZ2QgOiBudWxsO1xuICB9XG5cbiAgLyoqIFJlYnVpbGQgdGhlIGRpY3Qgd29ya2luZy1zZXQgZnJvbSB0aGUgc3RvcmUgKGFmdGVyIGFuIGltYWdlIHN3aXRjaCwgb3Igd2hlblxuICAgKiAgcmVnaW9ucyBjaGFuZ2VkIHdoaWxlIGFub3RoZXIgYmFja2VuZCB3YXMgcmVuZGVyaW5nKS4gKi9cbiAgc3luY0Zyb21TdG9yZSgpOiB2b2lkIHtcbiAgICBjb25zdCBzaG93TGFiZWwgPSB0aGlzLnJlZ2lvblN0b3JlLmdldFNob3dTaGFwZUxhYmVsKCk7XG4gICAgdGhpcy5zaGFwZXMgPSB0aGlzLnJlZ2lvblN0b3JlLmdldFJlZ2lvbnMoKS5tYXAoKHIpID0+IHtcbiAgICAgIHIuZmlsZW5hbWUgPSB0aGlzLmhvc3QuZmlsZU5hbWUoKTtcbiAgICAgIHJldHVybiB7IC4uLnIuZ2V0U2hhcGUoc2hvd0xhYmVsKSB9O1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ha2UgdGhlIHNoYXJlZCBzdG9yZSBhdXRob3JpdGF0aXZlIGZvciB0aGUgY3VycmVudCBkaWN0IHdvcmtpbmctc2V0OiBjb252ZXJ0XG4gICAqIHRoZSBkaWN0cyB0byBuZXV0cmFsIHJlZ2lvbnMgYW5kIHJlcGxhY2UgdGhlIHN0b3JlJ3MgbGlzdCAodGhlIHN0b3JlIG1pbnRzXG4gICAqIGlkcywgYXBwbGllcyBjbGFzcyBjb2xvdXJzLCBzeW5jcyBpdHMgcGVyLWltYWdlIGNhY2hlIGFuZCBlbWl0cyB0aGVcbiAgICogcmVnaW9uLXVwZGF0ZSBldmVudCkuIFN0b3JlLW1pbnRlZCBpZHMgYXJlIHdyaXR0ZW4gYmFjayBvbnRvIHRoZSBkaWN0cyBzbyB0aGVcbiAgICogdHdvIHJlcHJlc2VudGF0aW9ucyBzdGF5IGFsaWduZWQuIFByb2ZpbGUtbGluZSBST0lzIGFyZSBvcmRpbmFyeSByZWdpb25zXG4gICAqICh0YWdnZWQgYGtpbmQ6ICdwcm9maWxlJ2ApIGFuZCByb3VuZC10cmlwIHRocm91Z2ggaGVyZSB0b28uXG4gICAqL1xuICBjb21taXRUb1N0b3JlKCk6IHZvaWQge1xuICAgIGNvbnN0IHJlZ2lvbnMgPSB0aGlzLnNoYXBlcy5tYXAoKHMpID0+IE9iamVjdC5hc3NpZ24obmV3IFNoYXBlU2VsZWN0aW9uKCksIHMpLmdldFJlZ2lvbigpKTtcbiAgICAvLyBUaGUgY2FudmFzIGFscmVhZHkgc2hvd3MgdGhlc2Ugc2hhcGVzOiBkb24ndCByZWRyYXcgdGhlbSBmcm9tIHRoZSB1cGRhdGUuXG4gICAgdGhpcy5xdWlldGx5KCgpID0+XG4gICAgICB0aGlzLnJlZ2lvblN0b3JlLnNldFJlZ2lvbnMoXG4gICAgICAgIHJlZ2lvbnMsXG4gICAgICAgIHRoaXMucmVnaW9uU3RvcmUuZ2V0U2hvd1NoYXBlTGFiZWwoKSxcbiAgICAgICAgdHJ1ZSxcbiAgICAgICAgdGhpcy5yZWdpb25TdG9yZS5nZXRGaWxsQ29sb3IoKSxcbiAgICAgICAgZmFsc2UsXG4gICAgICApLFxuICAgICk7XG4gICAgY29uc3Qgc3RvcmVkID0gdGhpcy5yZWdpb25TdG9yZS5nZXRSZWdpb25zKCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnNoYXBlcy5sZW5ndGggJiYgaSA8IHN0b3JlZC5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHRoaXMuc2hhcGVzW2ldLmlkID09IG51bGwpIHRoaXMuc2hhcGVzW2ldLmlkID0gc3RvcmVkW2ldLmlkO1xuICAgICAgaWYgKHRoaXMuc2hhcGVzW2ldLm5hbWUgPT0gbnVsbCkgdGhpcy5zaGFwZXNbaV0ubmFtZSA9IHN0b3JlZFtpXS5uYW1lO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBcHBseSBhIGBwbG90bHlfcmVsYXlvdXRgIGV2ZW50J3Mgc2hhcGUgcGFydDogaW4tcGxhY2UgZWRpdHNcbiAgICogKGBzaGFwZXNbaV0ueDBgLCBgc2hhcGVzW2ldLnBhdGhgLCDigKYsIHJvdW5kZWQgdG8gd2hvbGUgcGl4ZWxzKSBhbmQgYSBzaGFwZVxuICAgKiBkcmF3biBuYXRpdmVseSBvbiB0aGUgY2FudmFzIChhIGxvbmUgYHNoYXBlc2Aga2V5IOKAlCBzbmFwcGVkLCB0YWdnZWQgd2l0aFxuICAgKiB0aGUgZmlsZSBhbmQsIHdoZW4gbGFiZWxzIGFyZSBvbiwgYSBsYWJlbCBvYmplY3QpLCBtaXJyb3JlZCBpbnRvIHRoZSBzdG9yZS5cbiAgICovXG4gIGFwcGx5UmVsYXlvdXQoZXZlbnQ6IFJlY29yZDxzdHJpbmcsIGFueT4pOiB2b2lkIHtcbiAgICBsZXQgc2hhcGVzTW9kaWZpZWQgPSBmYWxzZTtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhldmVudCkpIHtcbiAgICAgIGlmICgha2V5LnN0YXJ0c1dpdGgoJ3NoYXBlc1snKSkgY29udGludWU7XG4gICAgICBjb25zdCBzaGFwZU51bWJlciA9ICtrZXkuc3BsaXQoJ1snKVsxXS5zcGxpdCgnXScpWzBdO1xuICAgICAgY29uc3Qgc2hhcGVDaGFuZ2UgPSBrZXkuc3BsaXQoJy4nKVsxXTtcbiAgICAgIGlmICh0aGlzLnNoYXBlcyAmJiB0aGlzLnNoYXBlc1tzaGFwZU51bWJlcl0pIHtcbiAgICAgICAgdGhpcy5zaGFwZXNbc2hhcGVOdW1iZXJdW3NoYXBlQ2hhbmdlXSA9XG4gICAgICAgICAgc2hhcGVDaGFuZ2UgPT09ICdwYXRoJyA/IHRoaXMudXRpbHMucm91bmRQYXRoQ29vcmRpbmF0ZXMoZXZlbnRba2V5XSkgOiBNYXRoLnJvdW5kKCtldmVudFtrZXldKTtcbiAgICAgICAgc2hhcGVzTW9kaWZpZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoc2hhcGVzTW9kaWZpZWQpIHRoaXMuY29tbWl0VG9TdG9yZSgpO1xuICAgIGlmIChPYmplY3Qua2V5cyhldmVudCkubGVuZ3RoID09PSAxICYmICdzaGFwZXMnIGluIGV2ZW50KSB7XG4gICAgICB0aGlzLnNoYXBlcyA9IGV2ZW50WydzaGFwZXMnXSBhcyBhbnlbXTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zaGFwZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgLy8gQSBmcmVzaGx5IFBsb3RseS1kcmF3biBzaGFwZSBoYXMgbm8gaWQgeWV0IOKAlCBnaXZlIGl0IGEgbGFiZWwgb2JqZWN0XG4gICAgICAgIC8vICh3aGVuIGxhYmVscyBhcmUgb24pIGJlZm9yZSB0aGUgc3RvcmUgbWludHMgaWQgKyBkZWZhdWx0IG5hbWUuXG4gICAgICAgIGNvbnN0IGlzTmV3ID0gdGhpcy5zaGFwZXNbaV0uaWQgPT0gbnVsbDtcbiAgICAgICAgdGhpcy5zaGFwZXNbaV0uZmlsZU5hbWUgPSB0aGlzLmhvc3QuZmlsZU5hbWUoKTtcbiAgICAgICAgdGhpcy5zaGFwZXNbaV0gPSB0aGlzLnV0aWxzLnNuYXBSZWdpb24odGhpcy5zaGFwZXNbaV0pO1xuICAgICAgICBpZiAoaXNOZXcgJiYgdGhpcy5yZWdpb25TdG9yZS5nZXRTaG93U2hhcGVMYWJlbCgpKSB7XG4gICAgICAgICAgdGhpcy5zaGFwZXNbaV0ubGFiZWwgPSB7XG4gICAgICAgICAgICB0ZXh0OiB0aGlzLnNoYXBlc1tpXS5sYWJlbCxcbiAgICAgICAgICAgIHRleHR0ZW1wbGF0ZTogdGhpcy5zaGFwZXNbaV0ubGFiZWwsXG4gICAgICAgICAgICBmb250OiB7IGNvbG9yOiB0aGlzLnJlZ2lvblN0b3JlLmdldFNoYXBlQ29sb3IoKSB9LFxuICAgICAgICAgICAgdGV4dHBvc2l0aW9uOiAndG9wIGxlZnQnLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIE1pbnQgaWRzL25hbWVzIGluIHRoZSBzdG9yZSwgd3JpdGUgdGhlbSBiYWNrIG9udG8gdGhlIGRpY3RzLCBhbmQgZW1pdC5cbiAgICAgIHRoaXMuY29tbWl0VG9TdG9yZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBQdXNoIHRoZSBkaWN0IHdvcmtpbmctc2V0IHRvIFBsb3RseSAoYSBuby1vcCB3aGVuIGFub3RoZXIgYmFja2VuZCBvd25zIHRoZSBkaXYpLiAqL1xuICByZW5kZXIoKTogdm9pZCB7XG4gICAgY29uc3QgZ2QgPSB0aGlzLmxpdmVHZCgpO1xuICAgIGlmICghZ2QpIHJldHVybjtcbiAgICB2b2lkIFBsb3RseS5yZWxheW91dChnZCwgdGhpcy5yZWxheW91dFBheWxvYWQodGhpcy5zaGFwZXMubWFwKChzKSA9PiAoeyAuLi5zIH0pKSkgYXMgUGxvdGx5LkxheW91dCk7XG4gIH1cblxuICAvKiogVGhlIHNoYXBlcyBvZiB0aGUgaW1hZ2Ugb24gc2NyZWVuLCBsYWJlbGxlZCAob3Igbm90KSBmb3IgZGlzcGxheSwgYXMgZnJlc2ggZGljdHMuICovXG4gIHNoYXBlc1RvUmVkcmF3KHNob3dMYWJlbCA9IHRoaXMucmVnaW9uU3RvcmUuZ2V0U2hvd1NoYXBlTGFiZWwoKSk6IGFueVtdIHtcbiAgICBjb25zdCBzaGFwZXNUb1JlZHJhdzogU2hhcGVTZWxlY3Rpb25bXSA9IFtdO1xuICAgIGZvciAoY29uc3Qgc2hhcGUgb2YgdGhpcy5zaGFwZXMpIHtcbiAgICAgIGlmIChKU09OLnN0cmluZ2lmeShzaGFwZS5maWxlTmFtZSkgPT09IEpTT04uc3RyaW5naWZ5KHRoaXMuaG9zdC5maWxlTmFtZSgpKSkge1xuICAgICAgICBzaGFwZS5sYWJlbCA9IHNob3dMYWJlbFxuICAgICAgICAgID8ge1xuICAgICAgICAgICAgICB0ZXh0OiBgJHtzaGFwZS5sZWdlbmR9YCxcbiAgICAgICAgICAgICAgdGV4dHRlbXBsYXRlOiBgJHtzaGFwZS5sZWdlbmR9YCxcbiAgICAgICAgICAgICAgdGV4dHBvc2l0aW9uOiAndG9wIGxlZnQnLFxuICAgICAgICAgICAgICBmb250OiB7IGNvbG9yOiBgJHtzaGFwZS5saW5lLmNvbG9yfWAgfSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICA6IHt9O1xuICAgICAgICBzaGFwZXNUb1JlZHJhdy5wdXNoKHNoYXBlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gY29udmVydCB0byBkaWN0IHNvIHRoYXQgcGxvdGx5IHJlY29nbmlzZXMgdGhlIHNoYXBlc1xuICAgIHJldHVybiBzaGFwZXNUb1JlZHJhdy5tYXAoKHMpID0+ICh7IC4uLnMgfSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvbGxvdyB0aGUgc2hhcmVkIHN0b3JlOiByZWRyYXcgdGhlIHNoYXBlcyBvbiBldmVyeSByZWdpb24gdXBkYXRlIGFuZCBtb3ZlXG4gICAqIHRoZSBlZGl0IGhhbmRsZXMgb24gZXZlcnkgc2VsZWN0aW9uIGNoYW5nZSwgd2hvZXZlciBtYWRlIHRoZSBjaGFuZ2UgKHRoZVxuICAgKiByb3V0ZXIsIGFuIHVuZG8sIHRoZSBSZWdpb24gRWRpdG9yLCBhbm90aGVyIGJhY2tlbmQncyBvdmVybGF5LCBhIGNhbnZhc1xuICAgKiB0b29sKS4gUGxvdGx5IGlzIG5vdCBvbiB0aGUgc3RvcmUncyB3cml0ZSBwYXRoIGFueSBtb3JlIOKAlCBpdCBsaXN0ZW5zLCBsaWtlXG4gICAqIHRoZSBPcGVuU2VhZHJhZ29uIGFuZCBuYXBhcmktanMgb3ZlcmxheXMgZG8uIFNlcnZpY2UtbGlmZXRpbWU6IGJvdGhcbiAgICogY2FsbGJhY2tzIG5vLW9wIHdoaWxlIG5vIGxpdmUgUGxvdGx5IGdyYXBoIGhvbGRzIHRoZSBkaXYuXG4gICAqL1xuICBjb25uZWN0KCk6IFN1YnNjcmlwdGlvbiB7XG4gICAgY29uc3Qgc3VicyA9IG5ldyBTdWJzY3JpcHRpb24oKTtcbiAgICBzdWJzLmFkZCh0aGlzLnJlZ2lvblN0b3JlLmdldFJlZ2lvblVwZGF0ZUV2ZW50KCkuc3Vic2NyaWJlKChyZWdpb25zKSA9PiB0aGlzLm9uUmVnaW9uVXBkYXRlKHJlZ2lvbnMpKSk7XG4gICAgc3Vicy5hZGQodGhpcy5yZWdpb25TdG9yZS5nZXRTZWxlY3RlZFNoYXBlSW5kaWNlcyQoKS5zdWJzY3JpYmUoKGluZGljZXMpID0+IHRoaXMub25TZWxlY3Rpb24oaW5kaWNlcykpKTtcbiAgICByZXR1cm4gc3VicztcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW4gYHdyaXRlYCDigJQgYSBzdG9yZSB3cml0ZSB0aGlzIHByb2plY3Rpb24gYWxyZWFkeSByZWZsZWN0cyAoYSBzaGFwZSBlZGl0ZWRcbiAgICogb24gdGhlIGNhbnZhcywgYW4gaW1hZ2Ugc3dpdGNoIHRoZSBuZXh0IHBsb3QgZHJhd3MpIOKAlCB3aXRob3V0IHJlZHJhd2luZyBmcm9tXG4gICAqIHRoZSB1cGRhdGUgZXZlbnQgaXQgY2F1c2VzLlxuICAgKi9cbiAgcXVpZXRseSh3cml0ZTogKCkgPT4gdm9pZCk6IHZvaWQge1xuICAgIHRoaXMubXV0ZWQrKztcbiAgICB0cnkge1xuICAgICAgd3JpdGUoKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5tdXRlZC0tO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBIHJlZ2lvbiB1cGRhdGUuIFRoZSBzdG9yZWQgc2V0IHJlLXByb2plY3RzIGFuZCByZWRyYXdzOyBhIHRyYW5zaWVudCBzZXRcbiAgICogKGBzZXRSZWdpb25zKOKApiwgaXNSZWdpb25TYXZlT24gPSBmYWxzZSlgLCB3aGljaCB0aGUgc3RvcmUgZW1pdHMgd2l0aG91dFxuICAgKiBzdG9yaW5nKSBpcyBkcmF3biBhcy1pcyBhbmQgbGVhdmVzIHRoZSB3b3JraW5nLXNldCBhbG9uZS5cbiAgICovXG4gIHByaXZhdGUgb25SZWdpb25VcGRhdGUocmVnaW9uczogUmVnaW9uW10pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5tdXRlZCA+IDApIHJldHVybjtcbiAgICBjb25zdCBzdG9yZWQgPSB0aGlzLnJlZ2lvblN0b3JlLmdldFJlZ2lvbnMoKTtcbiAgICBjb25zdCBpc1N0b3JlZCA9IHJlZ2lvbnMubGVuZ3RoID09PSBzdG9yZWQubGVuZ3RoICYmIHJlZ2lvbnMuZXZlcnkoKHIsIGkpID0+IHIgPT09IHN0b3JlZFtpXSk7XG4gICAgaWYgKGlzU3RvcmVkKSB7XG4gICAgICB0aGlzLnN5bmNGcm9tU3RvcmUoKTtcbiAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGdkID0gdGhpcy5saXZlR2QoKTtcbiAgICBpZiAoIWdkKSByZXR1cm47XG4gICAgY29uc3Qgc2hvd0xhYmVsID0gdGhpcy5yZWdpb25TdG9yZS5nZXRTaG93U2hhcGVMYWJlbCgpO1xuICAgIGNvbnN0IGRpY3RzID0gcmVnaW9ucy5tYXAoKHIpID0+IHtcbiAgICAgIHIuZmlsZW5hbWUgPSB0aGlzLmhvc3QuZmlsZU5hbWUoKTtcbiAgICAgIHJldHVybiB7IC4uLnIuZ2V0U2hhcGUoc2hvd0xhYmVsKSB9O1xuICAgIH0pO1xuICAgIHZvaWQgUGxvdGx5LnJlbGF5b3V0KGdkLCB0aGlzLnJlbGF5b3V0UGF5bG9hZChkaWN0cykgYXMgUGxvdGx5LkxheW91dCk7XG4gIH1cblxuICAvKipcbiAgICogQSBzZWxlY3Rpb24gY2hhbmdlOiBQbG90bHkncyBgX2FjdGl2ZVNoYXBlSW5kZXhgIHBvaW50cyBhdCB0aGUgbGFzdCBzZWxlY3RlZFxuICAgKiBzaGFwZSBzbyBpdCBnZXRzIHRoZSBlZGl0IGhhbmRsZXMgKFBsb3RseSdzIG93biBhY3RpdmUtc2hhcGUgcmVuZGVyaW5nIGlzIHRoZVxuICAgKiBvbmx5IGhpZ2hsaWdodCkuIFNraXBwZWQgd2hlbiB0aGUgcGxvdCBhbHJlYWR5IHNob3dzIGl0IOKAlCB0aGUgY2hhbmdlIGNhbWVcbiAgICogZnJvbSBhIGNsaWNrIG9uIHRoZSBwbG90ICh7QGxpbmsgc3luY1NlbGVjdGlvbkZyb21QbG90fSkuXG4gICAqL1xuICBwcml2YXRlIG9uU2VsZWN0aW9uKGluZGljZXM6IG51bWJlcltdKTogdm9pZCB7XG4gICAgY29uc3QgZ2QgPSB0aGlzLmxpdmVHZCgpO1xuICAgIGlmICghZ2QpIHJldHVybjtcbiAgICBjb25zdCBhY3RpdmUgPSBpbmRpY2VzLmxlbmd0aCA+IDAgPyBpbmRpY2VzW2luZGljZXMubGVuZ3RoIC0gMV0gOiAtMTtcbiAgICBpZiAoKGdkLl9mdWxsTGF5b3V0IS5fYWN0aXZlU2hhcGVJbmRleCA/PyAtMSkgPT09IGFjdGl2ZSkgcmV0dXJuO1xuICAgIGdkLl9mdWxsTGF5b3V0IS5fYWN0aXZlU2hhcGVJbmRleCA9IGFjdGl2ZTtcbiAgICB0cnkge1xuICAgICAgdm9pZCBQbG90bHkucmVkcmF3KGdkKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8qIG5vb3AgaW4gdGVzdHMgKi9cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVhZCBQbG90bHkncyBgX2FjdGl2ZVNoYXBlSW5kZXhgIGFuZCBwdXNoIGl0IGFzIHRoZSBzZWxlY3Rpb24uIFBsb3RseSBmaXJlc1xuICAgKiBubyBkZWRpY2F0ZWQgYWN0aXZlLXNoYXBlIGV2ZW50IGZvciBjbGlja3MsIHNvIHRoaXMgaXMgc2FtcGxlZCBhZnRlciBhXG4gICAqIHJlbGF5b3V0IGFuZCBhIGNsaWNrLiBUaGUgc3RvcmUgbm8tb3BzIHdoZW4gdGhlIHNlbGVjdGlvbiBpcyB1bmNoYW5nZWQuXG4gICAqL1xuICBzeW5jU2VsZWN0aW9uRnJvbVBsb3QoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmhvc3QucGxvdERpdigpKSByZXR1cm47XG4gICAgY29uc3QgcmF3ID0gdGhpcy5nZCgpPy5fZnVsbExheW91dD8uX2FjdGl2ZVNoYXBlSW5kZXg7XG4gICAgY29uc3QgaWR4ID0gdHlwZW9mIHJhdyA9PT0gJ251bWJlcicgJiYgcmF3ID49IDAgJiYgcmF3IDwgdGhpcy5zaGFwZXMubGVuZ3RoID8gcmF3IDogLTE7XG4gICAgdGhpcy5yZWdpb25TdG9yZS5zZXRTZWxlY3RlZFNoYXBlSW5kaWNlcyhpZHggPj0gMCA/IFtpZHhdIDogW10pO1xuICB9XG5cbiAgLyoqIFRoZSBzaGFwZXMtcmVsYXlvdXQgcGF5bG9hZDogdGhlIHNoYXBlcyBwbHVzIHRoZSBhY3RpdmUtc2hhcGUgZmlsbCBjb2xvdXIuICovXG4gIHByaXZhdGUgcmVsYXlvdXRQYXlsb2FkKHNoYXBlRGljdHM6IGFueVtdKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICAgIHJldHVybiB7IHNoYXBlczogc2hhcGVEaWN0cywgYWN0aXZlc2hhcGU6IHsgZmlsbGNvbG9yOiB0aGlzLnJlZ2lvblN0b3JlLmdldEZpbGxDb2xvcigpIH0gfTtcbiAgfVxufVxuIl19
|