@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,113 @@
|
|
|
1
|
+
/** Region draw/select/edit modes, routed through the backend's region overlay. The vertex
|
|
2
|
+
* tools (drawpolygon/addpoint/deletepoint/move) are handled by the OpenSeadragon overlay;
|
|
3
|
+
* Plotly's overlay maps them to no-op. */
|
|
4
|
+
const REGION_MODES = new Set([
|
|
5
|
+
'drawrect',
|
|
6
|
+
'drawclosedpath',
|
|
7
|
+
'drawopenpath',
|
|
8
|
+
'select',
|
|
9
|
+
'drawpolygon',
|
|
10
|
+
'addpoint',
|
|
11
|
+
'deletepoint',
|
|
12
|
+
'move',
|
|
13
|
+
]);
|
|
14
|
+
/**
|
|
15
|
+
* The armed tool mode (one at a time across the region overlay, the viewport drag
|
|
16
|
+
* modes and the on-canvas tools) and the toolbar's tool settings it arms them with.
|
|
17
|
+
*/
|
|
18
|
+
export class ToolModes {
|
|
19
|
+
constructor(target, record, zone,
|
|
20
|
+
/** Runs after every arm/disarm with the newly armed mode. */
|
|
21
|
+
armed, markForCheck) {
|
|
22
|
+
this.target = target;
|
|
23
|
+
this.record = record;
|
|
24
|
+
this.armed = armed;
|
|
25
|
+
/** The armed mode, or null. */
|
|
26
|
+
this.active = null;
|
|
27
|
+
/** Wand sensitivity — higher = stricter (smaller selection). Matches QuPath default. */
|
|
28
|
+
this.wandSensitivity = 2.0;
|
|
29
|
+
/** Brush diameter in image-pixel coordinates (drives the painted disc size). */
|
|
30
|
+
this.brushSize = 40;
|
|
31
|
+
/** Vertex eraser radius in image-pixel coordinates. */
|
|
32
|
+
this.vertexEraserRadius = 20;
|
|
33
|
+
/** Class the brush paints while a plot mode armed it; null = plain brush. */
|
|
34
|
+
this.brushClass = null;
|
|
35
|
+
this.plotModeTools = {
|
|
36
|
+
armBrush: (brushClass) => zone.run(() => {
|
|
37
|
+
this.brushClass = { label: brushClass?.label, color: brushClass?.color };
|
|
38
|
+
if (this.active === 'brush')
|
|
39
|
+
this.target.setBrushOptions({ size: this.brushSize, ...this.brushClass });
|
|
40
|
+
else
|
|
41
|
+
this.apply('brush');
|
|
42
|
+
markForCheck();
|
|
43
|
+
}),
|
|
44
|
+
disarm: () => zone.run(() => {
|
|
45
|
+
this.brushClass = null;
|
|
46
|
+
if (this.active !== null)
|
|
47
|
+
this.apply(null);
|
|
48
|
+
markForCheck();
|
|
49
|
+
}),
|
|
50
|
+
activeTool$: record.getActiveTool$(),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/** A tool picked by the user (always the plain tool, never a plot mode's brush class);
|
|
54
|
+
* re-picking the armed one disarms it. */
|
|
55
|
+
toggle(mode) {
|
|
56
|
+
this.brushClass = null;
|
|
57
|
+
this.apply(this.active === mode ? null : mode);
|
|
58
|
+
}
|
|
59
|
+
/** Arm `mode` (or nothing) across every tool. */
|
|
60
|
+
apply(mode) {
|
|
61
|
+
this.active = mode;
|
|
62
|
+
this.record.setActiveTool(mode);
|
|
63
|
+
const regionMode = mode !== null && REGION_MODES.has(mode);
|
|
64
|
+
this.target.getRegionOverlay()?.setMode(regionMode ? mode : 'none');
|
|
65
|
+
// Viewport drag modes (pan/box-zoom). Region modes own the drag mode via the overlay.
|
|
66
|
+
if (!regionMode)
|
|
67
|
+
this.target.setDragMode(mode === 'pan' || mode === 'zoom' ? mode : false);
|
|
68
|
+
// On-canvas tools: arm the one this mode names (none for a region or viewport mode).
|
|
69
|
+
this.target.setActiveTool(mode, this.options(mode));
|
|
70
|
+
this.armed(mode);
|
|
71
|
+
}
|
|
72
|
+
/** Disarm whatever is armed and clear every tool mode (a plot-type switch). */
|
|
73
|
+
deactivate() {
|
|
74
|
+
this.brushClass = null;
|
|
75
|
+
this.active = null;
|
|
76
|
+
this.record.setActiveTool(null);
|
|
77
|
+
this.target.getRegionOverlay()?.setMode('none');
|
|
78
|
+
this.target.setDragMode(false);
|
|
79
|
+
this.target.setActiveTool(null);
|
|
80
|
+
}
|
|
81
|
+
setWandSensitivity(value) {
|
|
82
|
+
if (value === undefined || !Number.isFinite(value))
|
|
83
|
+
return;
|
|
84
|
+
this.wandSensitivity = value;
|
|
85
|
+
this.target.setWandOptions({ sensitivity: value });
|
|
86
|
+
}
|
|
87
|
+
setBrushSize(value) {
|
|
88
|
+
if (value === undefined || !Number.isFinite(value))
|
|
89
|
+
return;
|
|
90
|
+
this.brushSize = value;
|
|
91
|
+
this.target.setBrushOptions({ size: value });
|
|
92
|
+
}
|
|
93
|
+
setVertexEraserRadius(value) {
|
|
94
|
+
if (value === undefined || !Number.isFinite(value))
|
|
95
|
+
return;
|
|
96
|
+
this.vertexEraserRadius = value;
|
|
97
|
+
this.target.setVertexEraserRadius(value);
|
|
98
|
+
}
|
|
99
|
+
/** The options a canvas tool is armed with, from the toolbar's settings. */
|
|
100
|
+
options(mode) {
|
|
101
|
+
switch (mode) {
|
|
102
|
+
case 'wand':
|
|
103
|
+
return { sensitivity: this.wandSensitivity };
|
|
104
|
+
case 'brush':
|
|
105
|
+
return { size: this.brushSize, ...this.brushClass };
|
|
106
|
+
case 'eraseVertex':
|
|
107
|
+
return { radius: this.vertexEraserRadius };
|
|
108
|
+
default:
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbC1tb2Rlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvdmlzdWFsaXplci90b29sLW1vZGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQXlCQTs7MkNBRTJDO0FBQzNDLE1BQU0sWUFBWSxHQUF3QixJQUFJLEdBQUcsQ0FBQztJQUNoRCxVQUFVO0lBQ1YsZ0JBQWdCO0lBQ2hCLGNBQWM7SUFDZCxRQUFRO0lBQ1IsYUFBYTtJQUNiLFVBQVU7SUFDVixhQUFhO0lBQ2IsTUFBTTtDQUNQLENBQUMsQ0FBQztBQUVIOzs7R0FHRztBQUNILE1BQU0sT0FBTyxTQUFTO0lBZXBCLFlBQ21CLE1BQXVCLEVBQ3ZCLE1BQXdCLEVBQ3pDLElBQVk7SUFDWiw2REFBNkQ7SUFDNUMsS0FBb0MsRUFDckQsWUFBd0I7UUFMUCxXQUFNLEdBQU4sTUFBTSxDQUFpQjtRQUN2QixXQUFNLEdBQU4sTUFBTSxDQUFrQjtRQUd4QixVQUFLLEdBQUwsS0FBSyxDQUErQjtRQW5CdkQsK0JBQStCO1FBQy9CLFdBQU0sR0FBa0IsSUFBSSxDQUFDO1FBQzdCLHdGQUF3RjtRQUN4RixvQkFBZSxHQUFHLEdBQUcsQ0FBQztRQUN0QixnRkFBZ0Y7UUFDaEYsY0FBUyxHQUFHLEVBQUUsQ0FBQztRQUNmLHVEQUF1RDtRQUN2RCx1QkFBa0IsR0FBRyxFQUFFLENBQUM7UUFJeEIsNkVBQTZFO1FBQ3JFLGVBQVUsR0FBOEIsSUFBSSxDQUFDO1FBVW5ELElBQUksQ0FBQyxhQUFhLEdBQUc7WUFDbkIsUUFBUSxFQUFFLENBQUMsVUFBK0IsRUFBRSxFQUFFLENBQzVDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFO2dCQUNaLElBQUksQ0FBQyxVQUFVLEdBQUcsRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxDQUFDO2dCQUN6RSxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUss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WUFBWSxDQUFDLEtBQXlCO1FBQ3BDLElBQUksS0FBSyxLQUFLLFNBQVMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO1lBQUUsT0FBTztRQUMzRCxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztRQUN2QixJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQy9DLENBQUM7SUFFRCxxQkFBcUIsQ0FBQyxLQUF5QjtRQUM3QyxJQUFJLEtBQUssS0FBSyxTQUFTLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQztZQUFFLE9BQU87UUFDM0QsSUFBSSxDQUFDLGtCQUFrQixHQUFHLEtBQUssQ0FBQztRQUNoQyxJQUFJLENBQUMsTUFBTSxDQUFDLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFRCw0RUFBNEU7SUFDcEUsT0FBTyxDQUFDLElBQW1CO1FBQ2pDLFFBQVEsSUFBSSxFQUFFLENBQUM7WUFDYixLQUFLLE1BQU07Z0JBQ1QsT0FBTyxFQUFFLFdBQVcsRUFBRSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDL0MsS0FBSyxPQUFPO2dCQUNWLE9BQU8sRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsRUFBRSxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUN0RCxLQUFLLGFBQWE7Z0JBQ2hCLE9BQU8sRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDN0M7Z0JBQ0UsT0FBTyxTQUFTLENBQUM7UUFDckIsQ0FBQztJQUNILENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE5nWm9uZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBDYW52YXNUb29sT3B0aW9ucyB9IGZyb20gJy4uL2NvbnRyYWN0cy9kaXNwbGF5LXR5cGVzJztcbmltcG9ydCB7IFBsb3RNb2RlQnJ1c2hDbGFzcywgUGxvdE1vZGVUb29scyB9IGZyb20gJy4uL2NvbnRyYWN0cy9wbG90LXR5cGUtY29udHJpYnV0aW9uLmNvbnRyYWN0JztcbmltcG9ydCB7IFJlZ2lvblRvb2xNb2RlIH0gZnJvbSAnLi4vY29udHJhY3RzL3JlZ2lvbi1vdmVybGF5LmNvbnRyYWN0JztcbmltcG9ydCB7IElWaXN1YWxpemVyIH0gZnJvbSAnLi4vY29udHJhY3RzL3Zpc3VhbGl6ZXIuY29udHJhY3QnO1xuXG4vKiogVGhlIGJhY2tlbmQgbWVtYmVycyB0b29sIGFybWluZyBkcml2ZXMuICovXG5leHBvcnQgdHlwZSBUb29sTW9kZXNUYXJnZXQgPSBQaWNrPFxuICBJVmlzdWFsaXplcixcbiAgfCAnZ2V0UmVnaW9uT3ZlcmxheSdcbiAgfCAnc2V0RHJhZ01vZGUnXG4gIHwgJ3NldEFjdGl2ZVRvb2wnXG4gIHwgJ3NldFdhbmRPcHRpb25zJ1xuICB8ICdzZXRCcnVzaE9wdGlvbnMnXG4gIHwgJ3NldFZlcnRleEVyYXNlclJhZGl1cydcbj47XG5cbi8qKiBXaGVyZSB0aGUgYXJtZWQgdG9vbCBpcyByZWNvcmRlZCBmb3IgZXZlcnlvbmUgZWxzZSAodGhlIHNoYXJlZCBzZXNzaW9uIHN0b3JlKS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWN0aXZlVG9vbFJlY29yZCB7XG4gIHNldEFjdGl2ZVRvb2woaWQ6IHN0cmluZyB8IG51bGwpOiB2b2lkO1xuICBnZXRBY3RpdmVUb29sJCgpOiBPYnNlcnZhYmxlPHN0cmluZyB8IG51bGw+O1xufVxuXG4vKiogUmVnaW9uIGRyYXcvc2VsZWN0L2VkaXQgbW9kZXMsIHJvdXRlZCB0aHJvdWdoIHRoZSBiYWNrZW5kJ3MgcmVnaW9uIG92ZXJsYXkuIFRoZSB2ZXJ0ZXhcbiAqICB0b29scyAoZHJhd3BvbHlnb24vYWRkcG9pbnQvZGVsZXRlcG9pbnQvbW92ZSkgYXJlIGhhbmRsZWQgYnkgdGhlIE9wZW5TZWFkcmFnb24gb3ZlcmxheTtcbiAqICBQbG90bHkncyBvdmVybGF5IG1hcHMgdGhlbSB0byBuby1vcC4gKi9cbmNvbnN0IFJFR0lPTl9NT0RFUzogUmVhZG9ubHlTZXQ8c3RyaW5nPiA9IG5ldyBTZXQoW1xuICAnZHJhd3JlY3QnLFxuICAnZHJhd2Nsb3NlZHBhdGgnLFxuICAnZHJhd29wZW5wYXRoJyxcbiAgJ3NlbGVjdCcsXG4gICdkcmF3cG9seWdvbicsXG4gICdhZGRwb2ludCcsXG4gICdkZWxldGVwb2ludCcsXG4gICdtb3ZlJyxcbl0pO1xuXG4vKipcbiAqIFRoZSBhcm1lZCB0b29sIG1vZGUgKG9uZSBhdCBhIHRpbWUgYWNyb3NzIHRoZSByZWdpb24gb3ZlcmxheSwgdGhlIHZpZXdwb3J0IGRyYWdcbiAqIG1vZGVzIGFuZCB0aGUgb24tY2FudmFzIHRvb2xzKSBhbmQgdGhlIHRvb2xiYXIncyB0b29sIHNldHRpbmdzIGl0IGFybXMgdGhlbSB3aXRoLlxuICovXG5leHBvcnQgY2xhc3MgVG9vbE1vZGVzIHtcbiAgLyoqIFRoZSBhcm1lZCBtb2RlLCBvciBudWxsLiAqL1xuICBhY3RpdmU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICAvKiogV2FuZCBzZW5zaXRpdml0eSDigJQgaGlnaGVyID0gc3RyaWN0ZXIgKHNtYWxsZXIgc2VsZWN0aW9uKS4gTWF0Y2hlcyBRdVBhdGggZGVmYXVsdC4gKi9cbiAgd2FuZFNlbnNpdGl2aXR5ID0gMi4wO1xuICAvKiogQnJ1c2ggZGlhbWV0ZXIgaW4gaW1hZ2UtcGl4ZWwgY29vcmRpbmF0ZXMgKGRyaXZlcyB0aGUgcGFpbnRlZCBkaXNjIHNpemUpLiAqL1xuICBicnVzaFNpemUgPSA0MDtcbiAgLyoqIFZlcnRleCBlcmFzZXIgcmFkaXVzIGluIGltYWdlLXBpeGVsIGNvb3JkaW5hdGVzLiAqL1xuICB2ZXJ0ZXhFcmFzZXJSYWRpdXMgPSAyMDtcbiAgLyoqIFRoZSB0b29sYmFyIHRvb2xzIGEgY29udHJpYnV0ZWQgcGxvdCBtb2RlIG1heSBhcm0uIENhbGxzIGNhbiBjb21lIGZyb20gb3V0c2lkZVxuICAgKiAgQW5ndWxhciwgaGVuY2UgdGhlIHpvbmUuICovXG4gIHJlYWRvbmx5IHBsb3RNb2RlVG9vbHM6IFBsb3RNb2RlVG9vbHM7XG4gIC8qKiBDbGFzcyB0aGUgYnJ1c2ggcGFpbnRzIHdoaWxlIGEgcGxvdCBtb2RlIGFybWVkIGl0OyBudWxsID0gcGxhaW4gYnJ1c2guICovXG4gIHByaXZhdGUgYnJ1c2hDbGFzczogUGxvdE1vZGVCcnVzaENsYXNzIHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSB0YXJnZXQ6IFRvb2xNb2Rlc1RhcmdldCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJlY29yZDogQWN0aXZlVG9vbFJlY29yZCxcbiAgICB6b25lOiBOZ1pvbmUsXG4gICAgLyoqIFJ1bnMgYWZ0ZXIgZXZlcnkgYXJtL2Rpc2FybSB3aXRoIHRoZSBuZXdseSBhcm1lZCBtb2RlLiAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgYXJtZWQ6IChtb2RlOiBzdHJpbmcgfCBudWxsKSA9PiB2b2lkLFxuICAgIG1hcmtGb3JDaGVjazogKCkgPT4gdm9pZCxcbiAgKSB7XG4gICAgdGhpcy5wbG90TW9kZVRvb2xzID0ge1xuICAgICAgYXJtQnJ1c2g6IChicnVzaENsYXNzPzogUGxvdE1vZGVCcnVzaENsYXNzKSA9PlxuICAgICAgICB6b25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgdGhpcy5icnVzaENsYXNzID0geyBsYWJlbDogYnJ1c2hDbGFzcz8ubGFiZWwsIGNvbG9yOiBicnVzaENsYXNzPy5jb2xvciB9O1xuICAgICAgICAgIGlmICh0aGlzLmFjdGl2ZSA9PT0gJ2JydXNoJykgdGhpcy50YXJnZXQuc2V0QnJ1c2hPcHRpb25zKHsgc2l6ZTogdGhpcy5icnVzaFNpemUsIC4uLnRoaXMuYnJ1c2hDbGFzcyB9KTtcbiAgICAgICAgICBlbHNlIHRoaXMuYXBwbHkoJ2JydXNoJyk7XG4gICAgICAgICAgbWFya0ZvckNoZWNrKCk7XG4gICAgICAgIH0pLFxuICAgICAgZGlzYXJtOiAoKSA9PlxuICAgICAgICB6b25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgdGhpcy5icnVzaENsYXNzID0gbnVsbDtcbiAgICAgICAgICBpZiAodGhpcy5hY3RpdmUgIT09IG51bGwpIHRoaXMuYXBwbHkobnVsbCk7XG4gICAgICAgICAgbWFya0ZvckNoZWNrKCk7XG4gICAgICAgIH0pLFxuICAgICAgYWN0aXZlVG9vbCQ6IHJlY29yZC5nZXRBY3RpdmVUb29sJCgpLFxuICAgIH07XG4gIH1cblxuICAvKiogQSB0b29sIHBpY2tlZCBieSB0aGUgdXNlciAoYWx3YXlzIHRoZSBwbGFpbiB0b29sLCBuZXZlciBhIHBsb3QgbW9kZSdzIGJydXNoIGNsYXNzKTtcbiAgICogIHJlLXBpY2tpbmcgdGhlIGFybWVkIG9uZSBkaXNhcm1zIGl0LiAqL1xuICB0b2dnbGUobW9kZTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5icnVzaENsYXNzID0gbnVsbDtcbiAgICB0aGlzLmFwcGx5KHRoaXMuYWN0aXZlID09PSBtb2RlID8gbnVsbCA6IG1vZGUpO1xuICB9XG5cbiAgLyoqIEFybSBgbW9kZWAgKG9yIG5vdGhpbmcpIGFjcm9zcyBldmVyeSB0b29sLiAqL1xuICBhcHBseShtb2RlOiBzdHJpbmcgfCBudWxsKTogdm9pZCB7XG4gICAgdGhpcy5hY3RpdmUgPSBtb2RlO1xuICAgIHRoaXMucmVjb3JkLnNldEFjdGl2ZVRvb2wobW9kZSk7XG4gICAgY29uc3QgcmVnaW9uTW9kZSA9IG1vZGUgIT09IG51bGwgJiYgUkVHSU9OX01PREVTLmhhcyhtb2RlKTtcbiAgICB0aGlzLnRhcmdldC5nZXRSZWdpb25PdmVybGF5KCk/LnNldE1vZGUocmVnaW9uTW9kZSA/IChtb2RlIGFzIFJlZ2lvblRvb2xNb2RlKSA6ICdub25lJyk7XG4gICAgLy8gVmlld3BvcnQgZHJhZyBtb2RlcyAocGFuL2JveC16b29tKS4gUmVnaW9uIG1vZGVzIG93biB0aGUgZHJhZyBtb2RlIHZpYSB0aGUgb3ZlcmxheS5cbiAgICBpZiAoIXJlZ2lvbk1vZGUpIHRoaXMudGFyZ2V0LnNldERyYWdNb2RlKG1vZGUgPT09ICdwYW4nIHx8IG1vZGUgPT09ICd6b29tJyA/IG1vZGUgOiBmYWxzZSk7XG4gICAgLy8gT24tY2FudmFzIHRvb2xzOiBhcm0gdGhlIG9uZSB0aGlzIG1vZGUgbmFtZXMgKG5vbmUgZm9yIGEgcmVnaW9uIG9yIHZpZXdwb3J0IG1vZGUpLlxuICAgIHRoaXMudGFyZ2V0LnNldEFjdGl2ZVRvb2wobW9kZSwgdGhpcy5vcHRpb25zKG1vZGUpKTtcbiAgICB0aGlzLmFybWVkKG1vZGUpO1xuICB9XG5cbiAgLyoqIERpc2FybSB3aGF0ZXZlciBpcyBhcm1lZCBhbmQgY2xlYXIgZXZlcnkgdG9vbCBtb2RlIChhIHBsb3QtdHlwZSBzd2l0Y2gpLiAqL1xuICBkZWFjdGl2YXRlKCk6IHZvaWQge1xuICAgIHRoaXMuYnJ1c2hDbGFzcyA9IG51bGw7XG4gICAgdGhpcy5hY3RpdmUgPSBudWxsO1xuICAgIHRoaXMucmVjb3JkLnNldEFjdGl2ZVRvb2wobnVsbCk7XG4gICAgdGhpcy50YXJnZXQuZ2V0UmVnaW9uT3ZlcmxheSgpPy5zZXRNb2RlKCdub25lJyk7XG4gICAgdGhpcy50YXJnZXQuc2V0RHJhZ01vZGUoZmFsc2UpO1xuICAgIHRoaXMudGFyZ2V0LnNldEFjdGl2ZVRvb2wobnVsbCk7XG4gIH1cblxuICBzZXRXYW5kU2Vuc2l0aXZpdHkodmFsdWU6IG51bWJlciB8IHVuZGVmaW5lZCk6IHZvaWQge1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8ICFOdW1iZXIuaXNGaW5pdGUodmFsdWUpKSByZXR1cm47XG4gICAgdGhpcy53YW5kU2Vuc2l0aXZpdHkgPSB2YWx1ZTtcbiAgICB0aGlzLnRhcmdldC5zZXRXYW5kT3B0aW9ucyh7IHNlbnNpdGl2aXR5OiB2YWx1ZSB9KTtcbiAgfVxuXG4gIHNldEJydXNoU2l6ZSh2YWx1ZTogbnVtYmVyIHwgdW5kZWZpbmVkKTogdm9pZCB7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHwgIU51bWJlci5pc0Zpbml0ZSh2YWx1ZSkpIHJldHVybjtcbiAgICB0aGlzLmJydXNoU2l6ZSA9IHZhbHVlO1xuICAgIHRoaXMudGFyZ2V0LnNldEJydXNoT3B0aW9ucyh7IHNpemU6IHZhbHVlIH0pO1xuICB9XG5cbiAgc2V0VmVydGV4RXJhc2VyUmFkaXVzKHZhbHVlOiBudW1iZXIgfCB1bmRlZmluZWQpOiB2b2lkIHtcbiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCB8fCAhTnVtYmVyLmlzRmluaXRlKHZhbHVlKSkgcmV0dXJuO1xuICAgIHRoaXMudmVydGV4RXJhc2VyUmFkaXVzID0gdmFsdWU7XG4gICAgdGhpcy50YXJnZXQuc2V0VmVydGV4RXJhc2VyUmFkaXVzKHZhbHVlKTtcbiAgfVxuXG4gIC8qKiBUaGUgb3B0aW9ucyBhIGNhbnZhcyB0b29sIGlzIGFybWVkIHdpdGgsIGZyb20gdGhlIHRvb2xiYXIncyBzZXR0aW5ncy4gKi9cbiAgcHJpdmF0ZSBvcHRpb25zKG1vZGU6IHN0cmluZyB8IG51bGwpOiBDYW52YXNUb29sT3B0aW9ucyB8IHVuZGVmaW5lZCB7XG4gICAgc3dpdGNoIChtb2RlKSB7XG4gICAgICBjYXNlICd3YW5kJzpcbiAgICAgICAgcmV0dXJuIHsgc2Vuc2l0aXZpdHk6IHRoaXMud2FuZFNlbnNpdGl2aXR5IH07XG4gICAgICBjYXNlICdicnVzaCc6XG4gICAgICAgIHJldHVybiB7IHNpemU6IHRoaXMuYnJ1c2hTaXplLCAuLi50aGlzLmJydXNoQ2xhc3MgfTtcbiAgICAgIGNhc2UgJ2VyYXNlVmVydGV4JzpcbiAgICAgICAgcmV0dXJuIHsgcmFkaXVzOiB0aGlzLnZlcnRleEVyYXNlclJhZGl1cyB9O1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/** Bare keys that toggle a tool mode. */
|
|
2
|
+
const TOOL_KEYS = new Map([
|
|
3
|
+
['p', 'pan'],
|
|
4
|
+
['b', 'zoomToBox'],
|
|
5
|
+
['r', 'drawrect'],
|
|
6
|
+
['f', 'drawclosedpath'],
|
|
7
|
+
['w', 'wand'],
|
|
8
|
+
['e', 'eraseVertex'],
|
|
9
|
+
['s', 'select'],
|
|
10
|
+
['l', 'drawopenpath'],
|
|
11
|
+
]);
|
|
12
|
+
/** A field the user types into: its keys are never shortcuts. */
|
|
13
|
+
function isTextField(t) {
|
|
14
|
+
return !!t && (t.tagName === 'INPUT' || t.tagName === 'TEXTAREA' || t.isContentEditable);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The viewer's keyboard, wheel and context-menu handling: one window listener each,
|
|
18
|
+
* registered OUTSIDE the Angular zone (zone-patched, every event anywhere in the host
|
|
19
|
+
* app ran app-wide change detection) and re-entering it only to act.
|
|
20
|
+
*
|
|
21
|
+
* Keys: ←/→ step the slice; Enter/Escape resolve a SAM point prompt; Ctrl/Cmd+Z undo,
|
|
22
|
+
* Ctrl/Cmd+Shift+Z or +Y redo; bare Delete/Backspace/d delete the selected region,
|
|
23
|
+
* +/= and -/_ zoom, and single letters toggle tools (`TOOL_KEYS`). Any other
|
|
24
|
+
* modified key is left to the browser (Cmd/Ctrl+D must not delete a region).
|
|
25
|
+
*
|
|
26
|
+
* Keys are per viewer: with two live viewers (a main view and a pipeline preview)
|
|
27
|
+
* one Delete must not delete in both. A key goes to the viewer that holds focus, or
|
|
28
|
+
* — focus elsewhere — to the viewer the pointer last moved over; any other viewer
|
|
29
|
+
* ignores it (review CORE-2).
|
|
30
|
+
*/
|
|
31
|
+
export class ViewerShortcuts {
|
|
32
|
+
/** Every attached instance, to find the one holding focus. */
|
|
33
|
+
static { this.live = new Set(); }
|
|
34
|
+
/** The viewer the pointer last moved over. */
|
|
35
|
+
static { this.lastHovered = null; }
|
|
36
|
+
constructor(host, zone) {
|
|
37
|
+
this.host = host;
|
|
38
|
+
this.zone = zone;
|
|
39
|
+
this.listeners = [];
|
|
40
|
+
}
|
|
41
|
+
/** Register the window listeners (outside the zone). */
|
|
42
|
+
attach() {
|
|
43
|
+
this.zone.runOutsideAngular(() => {
|
|
44
|
+
this.listen('contextmenu', (e) => this.onContextMenu(e), true);
|
|
45
|
+
this.listen('keydown', (e) => this.onKeydown(e), false);
|
|
46
|
+
this.listen('wheel', (e) => this.onWheel(e), { capture: true, passive: false });
|
|
47
|
+
// `pointerover` fires on element transitions only, not on every move.
|
|
48
|
+
this.listen('pointerover', (e) => {
|
|
49
|
+
if (this.contains(e.target))
|
|
50
|
+
ViewerShortcuts.lastHovered = this;
|
|
51
|
+
}, true);
|
|
52
|
+
});
|
|
53
|
+
ViewerShortcuts.live.add(this);
|
|
54
|
+
}
|
|
55
|
+
/** Remove every listener {@link attach} added. */
|
|
56
|
+
detach() {
|
|
57
|
+
ViewerShortcuts.live.delete(this);
|
|
58
|
+
if (ViewerShortcuts.lastHovered === this)
|
|
59
|
+
ViewerShortcuts.lastHovered = null;
|
|
60
|
+
for (const [type, listener, options] of this.listeners.splice(0)) {
|
|
61
|
+
window.removeEventListener(type, listener, options);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
listen(type, listener, options) {
|
|
65
|
+
window.addEventListener(type, listener, options);
|
|
66
|
+
this.listeners.push([type, listener, options]);
|
|
67
|
+
}
|
|
68
|
+
contains(node) {
|
|
69
|
+
const el = this.host.hostElement ?? document.getElementById(this.host.plotDivName);
|
|
70
|
+
return !!node && !!el?.contains(node);
|
|
71
|
+
}
|
|
72
|
+
/** Whether this viewer takes keys now: it holds focus, or nothing does and the
|
|
73
|
+
* pointer was last over it. */
|
|
74
|
+
ownsKeys() {
|
|
75
|
+
const active = document.activeElement;
|
|
76
|
+
const focused = active && active !== document.body ? [...ViewerShortcuts.live].find((s) => s.contains(active)) : undefined;
|
|
77
|
+
return (focused ?? ViewerShortcuts.lastHovered) === this;
|
|
78
|
+
}
|
|
79
|
+
overPlot(event) {
|
|
80
|
+
return !!document.getElementById(this.host.plotDivName)?.contains(event.target);
|
|
81
|
+
}
|
|
82
|
+
run(fn) {
|
|
83
|
+
this.zone.run(fn);
|
|
84
|
+
}
|
|
85
|
+
onContextMenu(event) {
|
|
86
|
+
if (!this.overPlot(event))
|
|
87
|
+
return;
|
|
88
|
+
event.preventDefault();
|
|
89
|
+
event.stopImmediatePropagation();
|
|
90
|
+
this.run(() => this.host.openContextMenu(event));
|
|
91
|
+
}
|
|
92
|
+
onWheel(event) {
|
|
93
|
+
if (!this.overPlot(event))
|
|
94
|
+
return;
|
|
95
|
+
// A renderer that reads the scroll delta (napari, 3D scenes) keeps its own wheel:
|
|
96
|
+
// a FIXED zoom step per wheel event is far too sensitive there.
|
|
97
|
+
if (!this.host.wheelZooms())
|
|
98
|
+
return;
|
|
99
|
+
event.preventDefault();
|
|
100
|
+
event.stopImmediatePropagation();
|
|
101
|
+
if (event.deltaY < 0)
|
|
102
|
+
this.run(() => this.host.zoomIn());
|
|
103
|
+
else if (event.deltaY > 0)
|
|
104
|
+
this.run(() => this.host.zoomOut());
|
|
105
|
+
}
|
|
106
|
+
onKeydown(event) {
|
|
107
|
+
if (!this.ownsKeys())
|
|
108
|
+
return;
|
|
109
|
+
const host = this.host;
|
|
110
|
+
const target = event.target;
|
|
111
|
+
if (this.isSliceStepKey(event, target)) {
|
|
112
|
+
event.preventDefault();
|
|
113
|
+
this.run(() => host.stepSlice(event.key === 'ArrowRight' ? 1 : -1));
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (isTextField(target))
|
|
117
|
+
return;
|
|
118
|
+
if (host.activeDragMode() === 'samPoint' && (event.key === 'Enter' || event.key === 'Escape')) {
|
|
119
|
+
this.run(() => host.resolveSamPrompt(event.key === 'Enter'));
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
if (event.ctrlKey || event.metaKey) {
|
|
123
|
+
const k = event.key.toLowerCase();
|
|
124
|
+
if (k === 'z' && !event.shiftKey) {
|
|
125
|
+
event.preventDefault();
|
|
126
|
+
this.run(() => host.undo());
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if ((k === 'z' && event.shiftKey) || k === 'y') {
|
|
130
|
+
event.preventDefault();
|
|
131
|
+
this.run(() => host.redo());
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// The bare-key shortcuts must not fire on browser/OS shortcuts.
|
|
136
|
+
if (event.ctrlKey || event.metaKey || event.altKey)
|
|
137
|
+
return;
|
|
138
|
+
const key = event.key;
|
|
139
|
+
if (key === 'Delete' || key === 'Backspace' || key === 'd' || key === 'D')
|
|
140
|
+
this.run(() => host.deleteRegion());
|
|
141
|
+
else if (key === '+' || key === '=')
|
|
142
|
+
this.run(() => host.zoomIn());
|
|
143
|
+
else if (key === '-' || key === '_')
|
|
144
|
+
this.run(() => host.zoomOut());
|
|
145
|
+
else {
|
|
146
|
+
const mode = TOOL_KEYS.get(key);
|
|
147
|
+
if (mode)
|
|
148
|
+
this.run(() => host.toggleDragMode(mode));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* ←/→ step the slice in the Image view, the same way the slider does — only for a
|
|
153
|
+
* loaded stack, and not while a form field or the slider itself has focus (it
|
|
154
|
+
* handles arrows natively; stepping here too would double-step). Up/Down are left
|
|
155
|
+
* to OpenSeadragon (panning).
|
|
156
|
+
*/
|
|
157
|
+
isSliceStepKey(e, t) {
|
|
158
|
+
if (e.key !== 'ArrowLeft' && e.key !== 'ArrowRight')
|
|
159
|
+
return false;
|
|
160
|
+
if (!this.host.canStepSlice())
|
|
161
|
+
return false;
|
|
162
|
+
if (t && (/^(INPUT|TEXTAREA|SELECT)$/.test(t.tagName) || t.isContentEditable))
|
|
163
|
+
return false;
|
|
164
|
+
return !(t && (t.getAttribute('role') === 'slider' || t.closest('.p-slider')));
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlld2VyLXNob3J0Y3V0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvdmlzdWFsaXplci92aWV3ZXItc2hvcnRjdXRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQTJCQSx5Q0FBeUM7QUFDekMsTUFBTSxTQUFTLEdBQWdDLElBQUksR0FBRyxDQUFDO0lBQ3JELENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQztJQUNaLENBQUMsR0FBRyxFQUFFLFdBQVcsQ0FBQztJQUNsQixDQUFDLEdBQUcsRUFBRSxVQUFVLENBQUM7SUFDakIsQ0FBQyxHQUFHLEVBQUUsZ0JBQWdCLENBQUM7SUFDdkIsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDO0lBQ2IsQ0FBQyxHQUFHLEVBQUUsYUFBYSxDQUFDO0lBQ3BCLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQztJQUNmLENBQUMsR0FBRyxFQUFFLGNBQWMsQ0FBQztDQUN0QixDQUFDLENBQUM7QUFFSCxpRUFBaUU7QUFDakUsU0FBUyxXQUFXLENBQUMsQ0FBcUI7SUFDeEMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyxPQUFPLElBQUksQ0FBQyxDQUFDLE9BQU8sS0FBSyxVQUFVLElBQUksQ0FBQyxDQUFDLGlCQUFpQixDQUFDLENBQUM7QUFDM0YsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBQ0gsTUFBTSxPQUFPLGVBQWU7SUFDMUIsOERBQThEO2FBQ3RDLFNBQUksR0FBRyxJQUFJLEdBQUcsRUFBbUIsQUFBN0IsQ0FBOEI7SUFDMUQsOENBQThDO2FBQy9CLGdCQUFXLEdBQTJCLElBQUksQUFBL0IsQ0FBZ0M7SUFHMUQsWUFDbUIsSUFBa0IsRUFDbEIsSUFBWTtRQURaLFNBQUksR0FBSixJQUFJLENBQWM7UUFDbEIsU0FBSSxHQUFKLElBQUksQ0FBUTtRQUpkLGNBQVMsR0FBaUUsRUFBRSxDQUFDO0lBSzNGLENBQUM7SUFF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QUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2hDLElBQUksSUFBSTtnQkFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUN0RCxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ssY0FBYyxDQUFDLENBQWdCLEVBQUUsQ0FBcUI7UUFDNUQsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLFdBQVcsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLFlBQVk7WUFBRSxPQUFPLEtBQUssQ0FBQztRQUNsRSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFBRSxPQUFPLEtBQUssQ0FBQztRQUM1QyxJQUFJLENBQUMsSUFBSSxDQUFDLDJCQUEyQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLGlCQUFpQixDQUFDO1lBQUUsT0FBTyxLQUFLLENBQUM7UUFDNUYsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsS0FBSyxRQUFRLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDakYsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE5nWm9uZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG4vKiogV2hhdCB0aGUgc2hvcnRjdXRzIGRyaXZlOiB0aGUgdmlld2VyJ3MgYWN0aW9ucyBhbmQgdGhlIHN0YXRlIHRoZXkgZ2F0ZSBvbi4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2hvcnRjdXRIb3N0IHtcbiAgLyoqIElkIG9mIHRoZSBwbG90IGRpdjsgdGhlIHdoZWVsIGFuZCB0aGUgY29udGV4dCBtZW51IGFjdCBvbmx5IG92ZXIgaXQuICovXG4gIHJlYWRvbmx5IHBsb3REaXZOYW1lOiBzdHJpbmc7XG4gIC8qKiBUaGUgdmlld2VyJ3Mgb3duIGVsZW1lbnQgKHRvb2xiYXIgKyBwbG90KTsgaXRzIGtleXMgYXJlIHNjb3BlZCB0byBpdC4gRmFsbHMgYmFja1xuICAgKiAgdG8gdGhlIHBsb3QgZGl2IHdoZW4gYWJzZW50LiAqL1xuICByZWFkb25seSBob3N0RWxlbWVudD86IEhUTUxFbGVtZW50IHwgbnVsbDtcbiAgLyoqIFRoZSBhcm1lZCB0b29sIOKAlCBTQU0gcG9pbnQgbW9kZSB0YWtlcyBFbnRlciAvIEVzY2FwZS4gKi9cbiAgYWN0aXZlRHJhZ01vZGUoKTogc3RyaW5nIHwgbnVsbDtcbiAgLyoqIOKGkC/ihpIgc3RlcCB0aGUgc2xpY2U6IGEgbG9hZGVkIHN0YWNrIGluIHRoZSBJbWFnZSB2aWV3LiAqL1xuICBjYW5TdGVwU2xpY2UoKTogYm9vbGVhbjtcbiAgLyoqIFRoZSB3aGVlbCBzdGVwcyB0aGUgem9vbTogYSAyRCB2aWV3IHdob3NlIHJlbmRlcmVyIGRvZXMgbm90IHJlYWQgdGhlIHdoZWVsIGl0c2VsZi4gKi9cbiAgd2hlZWxab29tcygpOiBib29sZWFuO1xuICBzdGVwU2xpY2UoZGVsdGE6IG51bWJlcik6IHZvaWQ7XG4gIC8qKiBTQU0gcG9pbnQgbW9kZTogY29tbWl0IChFbnRlcikgb3IgZGlzY2FyZCAoRXNjYXBlKSB0aGUgcHJvbXB0LiAqL1xuICByZXNvbHZlU2FtUHJvbXB0KGNvbW1pdDogYm9vbGVhbik6IHZvaWQ7XG4gIHVuZG8oKTogdm9pZDtcbiAgcmVkbygpOiB2b2lkO1xuICBkZWxldGVSZWdpb24oKTogdm9pZDtcbiAgem9vbUluKCk6IHZvaWQ7XG4gIHpvb21PdXQoKTogdm9pZDtcbiAgdG9nZ2xlRHJhZ01vZGUobW9kZTogc3RyaW5nKTogdm9pZDtcbiAgb3BlbkNvbnRleHRNZW51KGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZDtcbn1cblxuLyoqIEJhcmUga2V5cyB0aGF0IHRvZ2dsZSBhIHRvb2wgbW9kZS4gKi9cbmNvbnN0IFRPT0xfS0VZUzogUmVhZG9ubHlNYXA8c3RyaW5nLCBzdHJpbmc+ID0gbmV3IE1hcChbXG4gIFsncCcsICdwYW4nXSxcbiAgWydiJywgJ3pvb21Ub0JveCddLFxuICBbJ3InLCAnZHJhd3JlY3QnXSxcbiAgWydmJywgJ2RyYXdjbG9zZWRwYXRoJ10sXG4gIFsndycsICd3YW5kJ10sXG4gIFsnZScsICdlcmFzZVZlcnRleCddLFxuICBbJ3MnLCAnc2VsZWN0J10sXG4gIFsnbCcsICdkcmF3b3BlbnBhdGgnXSxcbl0pO1xuXG4vKiogQSBmaWVsZCB0aGUgdXNlciB0eXBlcyBpbnRvOiBpdHMga2V5cyBhcmUgbmV2ZXIgc2hvcnRjdXRzLiAqL1xuZnVuY3Rpb24gaXNUZXh0RmllbGQodDogSFRNTEVsZW1lbnQgfCBudWxsKTogYm9vbGVhbiB7XG4gIHJldHVybiAhIXQgJiYgKHQudGFnTmFtZSA9PT0gJ0lOUFVUJyB8fCB0LnRhZ05hbWUgPT09ICdURVhUQVJFQScgfHwgdC5pc0NvbnRlbnRFZGl0YWJsZSk7XG59XG5cbi8qKlxuICogVGhlIHZpZXdlcidzIGtleWJvYXJkLCB3aGVlbCBhbmQgY29udGV4dC1tZW51IGhhbmRsaW5nOiBvbmUgd2luZG93IGxpc3RlbmVyIGVhY2gsXG4gKiByZWdpc3RlcmVkIE9VVFNJREUgdGhlIEFuZ3VsYXIgem9uZSAoem9uZS1wYXRjaGVkLCBldmVyeSBldmVudCBhbnl3aGVyZSBpbiB0aGUgaG9zdFxuICogYXBwIHJhbiBhcHAtd2lkZSBjaGFuZ2UgZGV0ZWN0aW9uKSBhbmQgcmUtZW50ZXJpbmcgaXQgb25seSB0byBhY3QuXG4gKlxuICogS2V5czog4oaQL+KGkiBzdGVwIHRoZSBzbGljZTsgRW50ZXIvRXNjYXBlIHJlc29sdmUgYSBTQU0gcG9pbnQgcHJvbXB0OyBDdHJsL0NtZCtaIHVuZG8sXG4gKiBDdHJsL0NtZCtTaGlmdCtaIG9yICtZIHJlZG87IGJhcmUgRGVsZXRlL0JhY2tzcGFjZS9kIGRlbGV0ZSB0aGUgc2VsZWN0ZWQgcmVnaW9uLFxuICogKy89IGFuZCAtL18gem9vbSwgYW5kIHNpbmdsZSBsZXR0ZXJzIHRvZ2dsZSB0b29scyAoYFRPT0xfS0VZU2ApLiBBbnkgb3RoZXJcbiAqIG1vZGlmaWVkIGtleSBpcyBsZWZ0IHRvIHRoZSBicm93c2VyIChDbWQvQ3RybCtEIG11c3Qgbm90IGRlbGV0ZSBhIHJlZ2lvbikuXG4gKlxuICogS2V5cyBhcmUgcGVyIHZpZXdlcjogd2l0aCB0d28gbGl2ZSB2aWV3ZXJzIChhIG1haW4gdmlldyBhbmQgYSBwaXBlbGluZSBwcmV2aWV3KVxuICogb25lIERlbGV0ZSBtdXN0IG5vdCBkZWxldGUgaW4gYm90aC4gQSBrZXkgZ29lcyB0byB0aGUgdmlld2VyIHRoYXQgaG9sZHMgZm9jdXMsIG9yXG4gKiDigJQgZm9jdXMgZWxzZXdoZXJlIOKAlCB0byB0aGUgdmlld2VyIHRoZSBwb2ludGVyIGxhc3QgbW92ZWQgb3ZlcjsgYW55IG90aGVyIHZpZXdlclxuICogaWdub3JlcyBpdCAocmV2aWV3IENPUkUtMikuXG4gKi9cbmV4cG9ydCBjbGFzcyBWaWV3ZXJTaG9ydGN1dHMge1xuICAvKiogRXZlcnkgYXR0YWNoZWQgaW5zdGFuY2UsIHRvIGZpbmQgdGhlIG9uZSBob2xkaW5nIGZvY3VzLiAqL1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBsaXZlID0gbmV3IFNldDxWaWV3ZXJTaG9ydGN1dHM+KCk7XG4gIC8qKiBUaGUgdmlld2VyIHRoZSBwb2ludGVyIGxhc3QgbW92ZWQgb3Zlci4gKi9cbiAgcHJpdmF0ZSBzdGF0aWMgbGFzdEhvdmVyZWQ6IFZpZXdlclNob3J0Y3V0cyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHJlYWRvbmx5IGxpc3RlbmVyczogW3N0cmluZywgRXZlbnRMaXN0ZW5lciwgYm9vbGVhbiB8IEFkZEV2ZW50TGlzdGVuZXJPcHRpb25zXVtdID0gW107XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBob3N0OiBTaG9ydGN1dEhvc3QsXG4gICAgcHJpdmF0ZSByZWFkb25seSB6b25lOiBOZ1pvbmUsXG4gICkge31cblxuICAvKiogUmVnaXN0ZXIgdGhlIHdpbmRvdyBsaXN0ZW5lcnMgKG91dHNpZGUgdGhlIHpvbmUpLiAqL1xuICBhdHRhY2goKTogdm9pZCB7XG4gICAgdGhpcy56b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIHRoaXMubGlzdGVuKCdjb250ZXh0bWVudScsIChlKSA9PiB0aGlzLm9uQ29udGV4dE1lbnUoZSBhcyBNb3VzZUV2ZW50KSwgdHJ1ZSk7XG4gICAgICB0aGlzLmxpc3Rlbigna2V5ZG93bicsIChlKSA9PiB0aGlzLm9uS2V5ZG93bihlIGFzIEtleWJvYXJkRXZlbnQpLCBmYWxzZSk7XG4gICAgICB0aGlzLmxpc3Rlbignd2hlZWwnLCAoZSkgPT4gdGhpcy5vbldoZWVsKGUgYXMgV2hlZWxFdmVudCksIHsgY2FwdHVyZTogdHJ1ZSwgcGFzc2l2ZTogZmFsc2UgfSk7XG4gICAgICAvLyBgcG9pbnRlcm92ZXJgIGZpcmVzIG9uIGVsZW1lbnQgdHJhbnNpdGlvbnMgb25seSwgbm90IG9uIGV2ZXJ5IG1vdmUuXG4gICAgICB0aGlzLmxpc3RlbihcbiAgICAgICAgJ3BvaW50ZXJvdmVyJyxcbiAgICAgICAgKGUpID0+IHtcbiAgICAgICAgICBpZiAodGhpcy5jb250YWlucyhlLnRhcmdldCBhcyBOb2RlKSkgVmlld2VyU2hvcnRjdXRzLmxhc3RIb3ZlcmVkID0gdGhpcztcbiAgICAgICAgfSxcbiAgICAgICAgdHJ1ZSxcbiAgICAgICk7XG4gICAgfSk7XG4gICAgVmlld2VyU2hvcnRjdXRzLmxpdmUuYWRkKHRoaXMpO1xuICB9XG5cbiAgLyoqIFJlbW92ZSBldmVyeSBsaXN0ZW5lciB7QGxpbmsgYXR0YWNofSBhZGRlZC4gKi9cbiAgZGV0YWNoKCk6IHZvaWQge1xuICAgIFZpZXdlclNob3J0Y3V0cy5saXZlLmRlbGV0ZSh0aGlzKTtcbiAgICBpZiAoVmlld2VyU2hvcnRjdXRzLmxhc3RIb3ZlcmVkID09PSB0aGlzKSBWaWV3ZXJTaG9ydGN1dHMubGFzdEhvdmVyZWQgPSBudWxsO1xuICAgIGZvciAoY29uc3QgW3R5cGUsIGxpc3RlbmVyLCBvcHRpb25zXSBvZiB0aGlzLmxpc3RlbmVycy5zcGxpY2UoMCkpIHtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGxpc3Rlbih0eXBlOiBzdHJpbmcsIGxpc3RlbmVyOiBFdmVudExpc3RlbmVyLCBvcHRpb25zOiBib29sZWFuIHwgQWRkRXZlbnRMaXN0ZW5lck9wdGlvbnMpOiB2b2lkIHtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lciwgb3B0aW9ucyk7XG4gICAgdGhpcy5saXN0ZW5lcnMucHVzaChbdHlwZSwgbGlzdGVuZXIsIG9wdGlvbnNdKTtcbiAgfVxuXG4gIHByaXZhdGUgY29udGFpbnMobm9kZTogTm9kZSB8IG51bGwpOiBib29sZWFuIHtcbiAgICBjb25zdCBlbCA9IHRoaXMuaG9zdC5ob3N0RWxlbWVudCA/PyBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLmhvc3QucGxvdERpdk5hbWUpO1xuICAgIHJldHVybiAhIW5vZGUgJiYgISFlbD8uY29udGFpbnMobm9kZSk7XG4gIH1cblxuICAvKiogV2hldGhlciB0aGlzIHZpZXdlciB0YWtlcyBrZXlzIG5vdzogaXQgaG9sZHMgZm9jdXMsIG9yIG5vdGhpbmcgZG9lcyBhbmQgdGhlXG4gICAqICBwb2ludGVyIHdhcyBsYXN0IG92ZXIgaXQuICovXG4gIHByaXZhdGUgb3duc0tleXMoKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYWN0aXZlID0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudDtcbiAgICBjb25zdCBmb2N1c2VkID1cbiAgICAgIGFjdGl2ZSAmJiBhY3RpdmUgIT09IGRvY3VtZW50LmJvZHkgPyBbLi4uVmlld2VyU2hvcnRjdXRzLmxpdmVdLmZpbmQoKHMpID0+IHMuY29udGFpbnMoYWN0aXZlKSkgOiB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIChmb2N1c2VkID8/IFZpZXdlclNob3J0Y3V0cy5sYXN0SG92ZXJlZCkgPT09IHRoaXM7XG4gIH1cblxuICBwcml2YXRlIG92ZXJQbG90KGV2ZW50OiBFdmVudCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMuaG9zdC5wbG90RGl2TmFtZSk/LmNvbnRhaW5zKGV2ZW50LnRhcmdldCBhcyBOb2RlKTtcbiAgfVxuXG4gIHByaXZhdGUgcnVuKGZuOiAoKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgdGhpcy56b25lLnJ1bihmbik7XG4gIH1cblxuICBwcml2YXRlIG9uQ29udGV4dE1lbnUoZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMub3ZlclBsb3QoZXZlbnQpKSByZXR1cm47XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLnJ1bigoKSA9PiB0aGlzLmhvc3Qub3BlbkNvbnRleHRNZW51KGV2ZW50KSk7XG4gIH1cblxuICBwcml2YXRlIG9uV2hlZWwoZXZlbnQ6IFdoZWVsRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMub3ZlclBsb3QoZXZlbnQpKSByZXR1cm47XG4gICAgLy8gQSByZW5kZXJlciB0aGF0IHJlYWRzIHRoZSBzY3JvbGwgZGVsdGEgKG5hcGFyaSwgM0Qgc2NlbmVzKSBrZWVwcyBpdHMgb3duIHdoZWVsOlxuICAgIC8vIGEgRklYRUQgem9vbSBzdGVwIHBlciB3aGVlbCBldmVudCBpcyBmYXIgdG9vIHNlbnNpdGl2ZSB0aGVyZS5cbiAgICBpZiAoIXRoaXMuaG9zdC53aGVlbFpvb21zKCkpIHJldHVybjtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuICAgIGlmIChldmVudC5kZWx0YVkgPCAwKSB0aGlzLnJ1bigoKSA9PiB0aGlzLmhvc3Quem9vbUluKCkpO1xuICAgIGVsc2UgaWYgKGV2ZW50LmRlbHRhWSA+IDApIHRoaXMucnVuKCgpID0+IHRoaXMuaG9zdC56b29tT3V0KCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBvbktleWRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMub3duc0tleXMoKSkgcmV0dXJuO1xuICAgIGNvbnN0IGhvc3QgPSB0aGlzLmhvc3Q7XG4gICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50IHwgbnVsbDtcbiAgICBpZiAodGhpcy5pc1NsaWNlU3RlcEtleShldmVudCwgdGFyZ2V0KSkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHRoaXMucnVuKCgpID0+IGhvc3Quc3RlcFNsaWNlKGV2ZW50LmtleSA9PT0gJ0Fycm93UmlnaHQnID8gMSA6IC0xKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChpc1RleHRGaWVsZCh0YXJnZXQpKSByZXR1cm47XG4gICAgaWYgKGhvc3QuYWN0aXZlRHJhZ01vZGUoKSA9PT0gJ3NhbVBvaW50JyAmJiAoZXZlbnQua2V5ID09PSAnRW50ZXInIHx8IGV2ZW50LmtleSA9PT0gJ0VzY2FwZScpKSB7XG4gICAgICB0aGlzLnJ1bigoKSA9PiBob3N0LnJlc29sdmVTYW1Qcm9tcHQoZXZlbnQua2V5ID09PSAnRW50ZXInKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXkpIHtcbiAgICAgIGNvbnN0IGsgPSBldmVudC5rZXkudG9Mb3dlckNhc2UoKTtcbiAgICAgIGlmIChrID09PSAneicgJiYgIWV2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMucnVuKCgpID0+IGhvc3QudW5kbygpKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKChrID09PSAneicgJiYgZXZlbnQuc2hpZnRLZXkpIHx8IGsgPT09ICd5Jykge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLnJ1bigoKSA9PiBob3N0LnJlZG8oKSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gVGhlIGJhcmUta2V5IHNob3J0Y3V0cyBtdXN0IG5vdCBmaXJlIG9uIGJyb3dzZXIvT1Mgc2hvcnRjdXRzLlxuICAgIGlmIChldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXkgfHwgZXZlbnQuYWx0S2V5KSByZXR1cm47XG4gICAgY29uc3Qga2V5ID0gZXZlbnQua2V5O1xuICAgIGlmIChrZXkgPT09ICdEZWxldGUnIHx8IGtleSA9PT0gJ0JhY2tzcGFjZScgfHwga2V5ID09PSAnZCcgfHwga2V5ID09PSAnRCcpIHRoaXMucnVuKCgpID0+IGhvc3QuZGVsZXRlUmVnaW9uKCkpO1xuICAgIGVsc2UgaWYgKGtleSA9PT0gJysnIHx8IGtleSA9PT0gJz0nKSB0aGlzLnJ1bigoKSA9PiBob3N0Lnpvb21JbigpKTtcbiAgICBlbHNlIGlmIChrZXkgPT09ICctJyB8fCBrZXkgPT09ICdfJykgdGhpcy5ydW4oKCkgPT4gaG9zdC56b29tT3V0KCkpO1xuICAgIGVsc2Uge1xuICAgICAgY29uc3QgbW9kZSA9IFRPT0xfS0VZUy5nZXQoa2V5KTtcbiAgICAgIGlmIChtb2RlKSB0aGlzLnJ1bigoKSA9PiBob3N0LnRvZ2dsZURyYWdNb2RlKG1vZGUpKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog4oaQL+KGkiBzdGVwIHRoZSBzbGljZSBpbiB0aGUgSW1hZ2UgdmlldywgdGhlIHNhbWUgd2F5IHRoZSBzbGlkZXIgZG9lcyDigJQgb25seSBmb3IgYVxuICAgKiBsb2FkZWQgc3RhY2ssIGFuZCBub3Qgd2hpbGUgYSBmb3JtIGZpZWxkIG9yIHRoZSBzbGlkZXIgaXRzZWxmIGhhcyBmb2N1cyAoaXRcbiAgICogaGFuZGxlcyBhcnJvd3MgbmF0aXZlbHk7IHN0ZXBwaW5nIGhlcmUgdG9vIHdvdWxkIGRvdWJsZS1zdGVwKS4gVXAvRG93biBhcmUgbGVmdFxuICAgKiB0byBPcGVuU2VhZHJhZ29uIChwYW5uaW5nKS5cbiAgICovXG4gIHByaXZhdGUgaXNTbGljZVN0ZXBLZXkoZTogS2V5Ym9hcmRFdmVudCwgdDogSFRNTEVsZW1lbnQgfCBudWxsKTogYm9vbGVhbiB7XG4gICAgaWYgKGUua2V5ICE9PSAnQXJyb3dMZWZ0JyAmJiBlLmtleSAhPT0gJ0Fycm93UmlnaHQnKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKCF0aGlzLmhvc3QuY2FuU3RlcFNsaWNlKCkpIHJldHVybiBmYWxzZTtcbiAgICBpZiAodCAmJiAoL14oSU5QVVR8VEVYVEFSRUF8U0VMRUNUKSQvLnRlc3QodC50YWdOYW1lKSB8fCB0LmlzQ29udGVudEVkaXRhYmxlKSkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiAhKHQgJiYgKHQuZ2V0QXR0cmlidXRlKCdyb2xlJykgPT09ICdzbGlkZXInIHx8IHQuY2xvc2VzdCgnLnAtc2xpZGVyJykpKTtcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { PlotType } from '../contracts/plot-type';
|
|
2
|
+
import { MultiPolygon, Polygon, Rectangle } from '../models/region';
|
|
3
|
+
const ACTIVE = 'context-menu-active';
|
|
4
|
+
/** The live regions at `indices` (stale indices dropped). */
|
|
5
|
+
export function regionsAt(regions, indices) {
|
|
6
|
+
return indices.map((i) => regions[i]).filter((r) => !!r);
|
|
7
|
+
}
|
|
8
|
+
/** Regions eligible for set-ops: closed areas (rect / closed polygon / multi-polygon),
|
|
9
|
+
* excluding intensity-profile lines. */
|
|
10
|
+
export function opEligible(regions) {
|
|
11
|
+
return regions.filter((r) => r.kind !== 'profile' &&
|
|
12
|
+
(r.bounds instanceof Rectangle ||
|
|
13
|
+
r.bounds instanceof MultiPolygon ||
|
|
14
|
+
(r.bounds instanceof Polygon && r.bounds.closed !== false)));
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The right-click menu: the selected-region actions lead (2D only), then the
|
|
18
|
+
* viewport and tool toggles for a 2D view, or the camera modes for a 3D scene. The
|
|
19
|
+
* armed mode is highlighted.
|
|
20
|
+
*/
|
|
21
|
+
export function buildContextMenu(state, actions) {
|
|
22
|
+
if (!state.isHeatmap)
|
|
23
|
+
return surface3dItems(state, actions);
|
|
24
|
+
const active = state.activeDragMode;
|
|
25
|
+
const toggle = (label, icon, mode) => ({
|
|
26
|
+
label,
|
|
27
|
+
icon,
|
|
28
|
+
styleClass: active === mode ? ACTIVE : '',
|
|
29
|
+
command: () => actions.toggleDragMode(mode),
|
|
30
|
+
});
|
|
31
|
+
const isImageView = state.basePlotType === PlotType.IMAGE;
|
|
32
|
+
const items = [];
|
|
33
|
+
const regionActions = buildRegionActionItems(state, actions);
|
|
34
|
+
if (regionActions.length)
|
|
35
|
+
items.push(...regionActions, { separator: true });
|
|
36
|
+
items.push({ label: 'Autoscale', icon: 'pi pi-window-maximize', command: () => actions.autoscaleImage() }, { separator: true });
|
|
37
|
+
// 'Zoom selection' is Plotly's rubber-band zoom; it doesn't apply to the
|
|
38
|
+
// OpenSeadragon-backed Image view (use 'Zoom to box' there instead).
|
|
39
|
+
if (!isImageView)
|
|
40
|
+
items.push(toggle('Zoom selection', 'pi pi-search', 'zoom'));
|
|
41
|
+
items.push(toggle('Zoom to box', 'zoom-box-off-icon', 'zoomToBox'), toggle('Pan', 'pi pi-arrows-alt', 'pan'), { label: 'Zoom in', icon: 'pi pi-search-plus', command: () => actions.zoomIn() }, { label: 'Zoom out', icon: 'pi pi-search-minus', command: () => actions.zoomOut() }, { separator: true }, toggle('Select', 'pi pi-arrow-up-right', 'select'), toggle('Freeform', 'pi pi-pencil', 'drawclosedpath'), toggle('Brush', 'brush-icon', 'brush'), toggle('Polyline', 'polyline-icon', 'drawopenpath'), toggle('Rectangle', 'pi pi-stop', 'drawrect'), toggle('Wand', 'wand-icon', 'wand'), toggle('Vertex eraser', 'pi pi-eraser', 'eraseVertex'));
|
|
42
|
+
// Vertex editing runs on the OpenSeadragon overlay, which backs the Image plot
|
|
43
|
+
// type. Hidden for other 2D types (Plotly), where these modes are no-ops.
|
|
44
|
+
if (isImageView) {
|
|
45
|
+
items.push(toggle('Polygon (click vertices)', 'polygon-vertices-icon', 'drawpolygon'), toggle('Add vertex', 'vertex-add-icon', 'addpoint'), toggle('Delete vertex', 'vertex-delete-icon', 'deletepoint'));
|
|
46
|
+
}
|
|
47
|
+
return items;
|
|
48
|
+
}
|
|
49
|
+
/** A 3D scene's camera modes and reset. */
|
|
50
|
+
function surface3dItems(state, actions) {
|
|
51
|
+
const mode = (label, icon, m) => ({
|
|
52
|
+
label,
|
|
53
|
+
icon,
|
|
54
|
+
styleClass: state.activeSurface3dMode === m ? ACTIVE : '',
|
|
55
|
+
command: () => actions.toggleSurface3dMode(m),
|
|
56
|
+
});
|
|
57
|
+
return [
|
|
58
|
+
mode('Zoom', 'pi pi-search', 'zoom'),
|
|
59
|
+
mode('Pan', 'pi pi-arrows-alt', 'pan'),
|
|
60
|
+
mode('Orbital rotation', 'pi pi-globe', 'orbit'),
|
|
61
|
+
mode('Turntable rotation', 'pi pi-sync', 'turntable'),
|
|
62
|
+
{ separator: true },
|
|
63
|
+
{ label: 'Reset camera', icon: 'pi pi-home', command: () => actions.resetSurfaceCamera() },
|
|
64
|
+
];
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Immediate region actions on the current selection (jit-ui#85): merge, ungroup,
|
|
68
|
+
* inverse, simplify, the Bézier conversions, and delete — the one-shot geometry
|
|
69
|
+
* transforms, grouped apart from the tool/mode toggles and shown only when something
|
|
70
|
+
* is selected. Each item is gated on what the selection supports. "Select all" leads
|
|
71
|
+
* whenever the image has regions.
|
|
72
|
+
*/
|
|
73
|
+
export function buildRegionActionItems(state, actions) {
|
|
74
|
+
if (!state.regions.some((r) => r.kind !== 'profile'))
|
|
75
|
+
return [];
|
|
76
|
+
const items = [
|
|
77
|
+
{ label: 'Select all regions', icon: 'pi pi-check-square', command: () => actions.selectAllRegions() },
|
|
78
|
+
];
|
|
79
|
+
const selected = regionsAt(state.regions, state.selectedIndices);
|
|
80
|
+
if (selected.length === 0)
|
|
81
|
+
return items;
|
|
82
|
+
const eligible = opEligible(selected);
|
|
83
|
+
if (eligible.length >= 2) {
|
|
84
|
+
items.push({ label: 'Merge / group', icon: 'pi pi-link', command: () => actions.mergeRegions() });
|
|
85
|
+
}
|
|
86
|
+
if (selected.some((r) => state.canUngroup(r))) {
|
|
87
|
+
items.push({ label: 'Ungroup', icon: 'pi pi-sitemap', command: () => actions.ungroupRegions() });
|
|
88
|
+
}
|
|
89
|
+
if (eligible.length >= 1) {
|
|
90
|
+
items.push({ label: 'Inverse', icon: 'pi pi-clone', command: () => actions.inverseRegions() }, {
|
|
91
|
+
label: 'Simplify',
|
|
92
|
+
icon: 'pi pi-chart-line',
|
|
93
|
+
items: [
|
|
94
|
+
{ label: 'Light (1 px)', command: () => actions.simplifyRegions(1) },
|
|
95
|
+
{ label: 'Medium (3 px)', command: () => actions.simplifyRegions(3) },
|
|
96
|
+
{ label: 'Strong (8 px)', command: () => actions.simplifyRegions(8) },
|
|
97
|
+
{ separator: true },
|
|
98
|
+
{ label: 'Custom…', command: () => actions.openSimplifyDialog() },
|
|
99
|
+
],
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
// Bézier conversions are vertex-level edits — Image (OpenSeadragon) view only —
|
|
103
|
+
// gated on the selection's current form.
|
|
104
|
+
if (state.basePlotType === PlotType.IMAGE) {
|
|
105
|
+
if (selected.some((r) => (r.bounds instanceof Polygon && !r.bounds.bezier) || r.bounds instanceof Rectangle)) {
|
|
106
|
+
items.push({ label: 'Convert to Bézier', icon: 'to-bezier-icon', command: () => actions.toBezierRegion() });
|
|
107
|
+
}
|
|
108
|
+
if (selected.some((r) => r.bounds instanceof Polygon && r.bounds.bezier)) {
|
|
109
|
+
items.push({
|
|
110
|
+
label: 'Convert to polygon',
|
|
111
|
+
icon: 'to-polygon-icon',
|
|
112
|
+
command: () => actions.toPolygonRegion(),
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
items.push({ label: 'Delete region', icon: 'pi pi-trash', command: () => actions.deleteRegion() });
|
|
117
|
+
return items;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlzdWFsaXplci1jb250ZXh0LW1lbnUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3Zpc3VhbGl6ZXIvdmlzdWFsaXplci1jb250ZXh0LW1lbnUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ2xELE9BQU8sRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBVSxNQUFNLGtCQUFrQixDQUFDO0FBcUM1RSxNQUFNLE1BQU0sR0FBRyxxQkFBcUIsQ0FBQztBQUVyQyw2REFBNkQ7QUFDN0QsTUFBTSxVQUFVLFNBQVMsQ0FBQyxPQUFpQixFQUFFLE9BQWlCO0lBQzVELE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFlLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDeEUsQ0FBQztBQUVEO3lDQUN5QztBQUN6QyxNQUFNLFVBQVUsVUFBVSxDQUFDLE9BQWlCO0lBQzFDLE9BQU8sT0FBTyxDQUFDLE1BQU0sQ0FDbkIsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUNKLENBQUMsQ0FBQyxJQUFJLEtBQUssU0FBUztRQUNwQixDQUFDLENBQUMsQ0FBQyxNQUFNLFlBQVksU0FBUztZQUM1QixDQUFDLENBQUMsTUFBTSxZQUFZLFlBQVk7WUFDaEMsQ0FBQyxDQUFDLENBQUMsTUFBTSxZQUFZLE9BQU8sSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUNoRSxDQUFDO0FBQ0osQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsZ0JBQWdCLENBQUMsS0FBdUIsRUFBRSxPQUEyQjtJQUNuRixJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVM7UUFBRSxPQUFPLGNBQWMsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDNUQsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLGNBQWMsQ0FBQztJQUNwQyxNQUFNLE1BQU0sR0FBRyxDQUFDLEtBQWEsRUFBRSxJQUFZLEVBQUUsSUFBWSxFQUFZLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZFLEtBQUs7UUFDTCxJQUFJO1FBQ0osVUFBVSxFQUFFLE1BQU0sS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRTtRQUN6QyxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUM7S0FDNUMsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxXQUFXLEdBQUcsS0FBSyxDQUFDLFlBQVksS0FBSyxRQUFRLENBQUMsS0FBSyxDQUFDO0lBQzFELE1BQU0sS0FBSyxHQUFlLEVBQUUsQ0FBQztJQUM3QixNQUFNLGFBQWEsR0FBRyxzQkFBc0IsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDN0QsSUFBSSxhQUFhLENBQUMsTUFBTTtRQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxhQUFhLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUM1RSxLQUFLLENBQUMsSUFBSSxDQUNSLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsdUJBQXVCLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUUsRUFBRSxFQUM5RixFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FDcEIsQ0FBQztJQUNGLHlFQUF5RTtJQUN6RSxxRUFBcUU7SUFDckUsSUFBSSxDQUFDLFdBQVc7UUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsRUFBRSxjQUFjLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUMvRSxLQUFLLENBQUMsSUFBSSxDQUNSLE1BQU0sQ0FBQyxhQUFhLEVBQUUsbUJBQW1CLEVBQUUsV0FBVyxDQUFDLEVBQ3ZELE1BQU0sQ0FBQyxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsS0FBSyxDQUFDLEVBQ3hDLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsbUJBQW1CLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFBRSxFQUNoRixFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLG9CQUFvQixFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLEVBQUUsRUFDbkYsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLEVBQ25CLE1BQU0sQ0FBQyxRQUFRLEVBQUUsc0JBQXNCLEVBQUUsUUFBUSxDQUFDLEVBQ2xELE1BQU0sQ0FBQyxVQUFVLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixDQUFDLEVBQ3BELE1BQU0sQ0FBQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE9BQU8sQ0FBQyxFQUN0QyxNQUFNLENBQUMsVUFBVSxFQUFFLGVBQWUsRUFBRSxjQUFjLENBQUMsRUFDbkQsTUFBTSxDQUFDLFdBQVcsRUFBRSxZQUFZLEVBQUUsVUFBVSxDQUFDLEVBQzdDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsV0FBVyxFQUFFLE1BQU0sQ0FBQyxFQUNuQyxNQUFNLENBQUMsZUFBZSxFQUFFLGNBQWMsRUFBRSxhQUFhLENBQUMsQ0FDdkQsQ0FBQztJQUNGLCtFQUErRTtJQUMvRSwwRUFBMEU7SUFDMUUsSUFBSSxXQUFXLEVBQUUsQ0FBQztRQUNoQixLQUFLLENBQUMsSUFBSSxDQUNSLE1BQU0sQ0FBQywwQkFBMEIsRUFBRSx1QkFBdUIsRUFBRSxhQUFhLENBQUMsRUFDMUUsTUFBTSxDQUFDLFlBQVksRUFBRSxpQkFBaUIsRUFBRSxVQUFVLENBQUMsRUFDbkQsTUFBTSxDQUFDLGVBQWUsRUFBRSxvQkFBb0IsRUFBRSxhQUFhLENBQUMsQ0FDN0QsQ0FBQztJQUNKLENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRCwyQ0FBMkM7QUFDM0MsU0FBUyxjQUFjLENBQUMsS0FBdUIsRUFBRSxPQUEyQjtJQUMxRSxNQUFNLElBQUksR0FBRyxDQUFDLEtBQWEsRUFBRSxJQUFZLEVBQUUsQ0FBUyxFQUFZLEVBQUUsQ0FBQyxDQUFDO1FBQ2xFLEtBQUs7UUFDTCxJQUFJO1FBQ0osVUFBVSxFQUFFLEtBQUssQ0FBQyxtQkFBbUIsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRTtRQUN6RCxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQztLQUM5QyxDQUFDLENBQUM7SUFDSCxPQUFPO1FBQ0wsSUFBSSxDQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUUsTUFBTSxDQUFDO1FBQ3BDLElBQUksQ0FBQyxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsS0FBSyxDQUFDO1FBQ3RDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxhQUFhLEVBQUUsT0FBTyxDQUFDO1FBQ2hELElBQUksQ0FBQyxvQkFBb0IsRUFBRSxZQUFZLEVBQUUsV0FBVyxDQUFDO1FBQ3JELEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRTtRQUNuQixFQUFFLEtBQUssRUFBRSxjQUFjLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLGtCQUFrQixFQUFFLEVBQUU7S0FDM0YsQ0FBQztBQUNKLENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxNQUFNLFVBQVUsc0JBQXNCLENBQUMsS0FBdUIsRUFBRSxPQUEyQjtJQUN6RixJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssU0FBUyxDQUFDO1FBQUUsT0FBTyxFQUFFLENBQUM7SUFDaEUsTUFBTSxLQUFLLEdBQWU7UUFDeEIsRUFBRSxLQUFLLEVBQUUsb0JBQW9CLEVBQUUsSUFBSSxFQUFFLG9CQUFvQixFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLEVBQUUsRUFBRTtLQUN2RyxDQUFDO0lBQ0YsTUFBTSxRQUFRLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ2pFLElBQUksUUFBUSxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDeEMsTUFBTSxRQUFRLEdBQUcsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3RDLElBQUksUUFBUSxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUN6QixLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLGVBQWUsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ3BHLENBQUM7SUFDRCxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQzlDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxlQUFlLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDbkcsQ0FBQztJQUNELElBQUksUUFBUSxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUN6QixLQUFLLENBQUMsSUFBSSxDQUNSLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFLEVBQUUsRUFDbEY7WUFDRSxLQUFLLEVBQUUsVUFBVTtZQUNqQixJQUFJLEVBQUUsa0JBQWtCO1lBQ3hCLEtBQUssRUFBRTtnQkFDTCxFQUFFLEtBQUssRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3BFLEVBQUUsS0FBSyxFQUFFLGVBQWUsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDckUsRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUNyRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUU7Z0JBQ25CLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLGtCQUFrQixFQUFFLEVBQUU7YUFDbEU7U0FDRixDQUNGLENBQUM7SUFDSixDQUFDO0lBQ0QsZ0ZBQWdGO0lBQ2hGLHlDQUF5QztJQUN6QyxJQUFJLEtBQUssQ0FBQyxZQUFZLEtBQUssUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQzFDLElBQUksUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxZQUFZLE9BQU8sSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sWUFBWSxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQzdHLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsbUJBQW1CLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzlHLENBQUM7UUFDRCxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLFlBQVksT0FBTyxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUN6RSxLQUFLLENBQUMsSUFBSSxDQUFDO2dCQUNULEtBQUssRUFBRSxvQkFBb0I7Z0JBQzNCLElBQUksRUFBRSxpQkFBaUI7Z0JBQ3ZCLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsZUFBZSxFQUFFO2FBQ3pDLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDO0lBQ0QsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxFQUFFLENBQUMsQ0FBQztJQUNuRyxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBNZW51SXRlbSB9IGZyb20gJ3ByaW1lbmcvYXBpJztcblxuaW1wb3J0IHsgUGxvdFR5cGUgfSBmcm9tICcuLi9jb250cmFjdHMvcGxvdC10eXBlJztcbmltcG9ydCB7IE11bHRpUG9seWdvbiwgUG9seWdvbiwgUmVjdGFuZ2xlLCBSZWdpb24gfSBmcm9tICcuLi9tb2RlbHMvcmVnaW9uJztcblxuLyoqIFdoYXQgdGhlIHJpZ2h0LWNsaWNrIG1lbnUgaXMgYnVpbHQgZnJvbTogdGhlIHZpZXcsIHRoZSBhcm1lZCBtb2RlcyBhbmQgdGhlIHJlZ2lvbnMuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbnRleHRNZW51U3RhdGUge1xuICAvKiogMkQgdmlldyAocmVnaW9uIHRvb2xzLCBzdGVwIHpvb20pIHZzIGEgM0Qgc2NlbmUgKGNhbWVyYSBtb2RlcykuICovXG4gIGlzSGVhdG1hcDogYm9vbGVhbjtcbiAgLyoqIFRoZSBidWlsdC1pbiB0eXBlIG9uIHNjcmVlbjsgdGhlIEltYWdlIHZpZXcgYWRkcyB0aGUgdmVydGV4IGFuZCBCw6l6aWVyIGl0ZW1zLiAqL1xuICBiYXNlUGxvdFR5cGU6IFBsb3RUeXBlO1xuICBhY3RpdmVEcmFnTW9kZTogc3RyaW5nIHwgbnVsbDtcbiAgYWN0aXZlU3VyZmFjZTNkTW9kZTogc3RyaW5nO1xuICAvKiogRXZlcnkgcmVnaW9uIG9uIHRoZSBpbWFnZSAoaW50ZW5zaXR5LXByb2ZpbGUgbGluZXMgaW5jbHVkZWQpLiAqL1xuICByZWdpb25zOiBSZWdpb25bXTtcbiAgLyoqIFRoZSBzZWxlY3Rpb24sIGFzIGluZGljZXMgaW50byB7QGxpbmsgcmVnaW9uc30uICovXG4gIHNlbGVjdGVkSW5kaWNlczogbnVtYmVyW107XG4gIC8qKiBXaGV0aGVyIGEgcmVnaW9uIGlzIGEgbXVsdGktcGFydCByZWdpb24gdGhhdCBjYW4gYmUgc3BsaXQgYmFjayBpbnRvIHBhcnRzLiAqL1xuICBjYW5Vbmdyb3VwKHJlZ2lvbjogUmVnaW9uKTogYm9vbGVhbjtcbn1cblxuLyoqIFdoYXQgdGhlIG1lbnUncyBpdGVtcyBkbyAodGhlIHZpZXdlcidzIG93biB0b29sYmFyIGhhbmRsZXJzKS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29udGV4dE1lbnVBY3Rpb25zIHtcbiAgYXV0b3NjYWxlSW1hZ2UoKTogdm9pZDtcbiAgem9vbUluKCk6IHZvaWQ7XG4gIHpvb21PdXQoKTogdm9pZDtcbiAgdG9nZ2xlRHJhZ01vZGUobW9kZTogc3RyaW5nKTogdm9pZDtcbiAgdG9nZ2xlU3VyZmFjZTNkTW9kZShtb2RlOiBzdHJpbmcpOiB2b2lkO1xuICByZXNldFN1cmZhY2VDYW1lcmEoKTogdm9pZDtcbiAgc2VsZWN0QWxsUmVnaW9ucygpOiB2b2lkO1xuICBtZXJnZVJlZ2lvbnMoKTogdm9pZDtcbiAgdW5ncm91cFJlZ2lvbnMoKTogdm9pZDtcbiAgaW52ZXJzZVJlZ2lvbnMoKTogdm9pZDtcbiAgc2ltcGxpZnlSZWdpb25zKHRocmVzaG9sZFB4OiBudW1iZXIpOiB2b2lkO1xuICBvcGVuU2ltcGxpZnlEaWFsb2coKTogdm9pZDtcbiAgdG9CZXppZXJSZWdpb24oKTogdm9pZDtcbiAgdG9Qb2x5Z29uUmVnaW9uKCk6IHZvaWQ7XG4gIGRlbGV0ZVJlZ2lvbigpOiB2b2lkO1xufVxuXG5jb25zdCBBQ1RJVkUgPSAnY29udGV4dC1tZW51LWFjdGl2ZSc7XG5cbi8qKiBUaGUgbGl2ZSByZWdpb25zIGF0IGBpbmRpY2VzYCAoc3RhbGUgaW5kaWNlcyBkcm9wcGVkKS4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpb25zQXQocmVnaW9uczogUmVnaW9uW10sIGluZGljZXM6IG51bWJlcltdKTogUmVnaW9uW10ge1xuICByZXR1cm4gaW5kaWNlcy5tYXAoKGkpID0+IHJlZ2lvbnNbaV0pLmZpbHRlcigocik6IHIgaXMgUmVnaW9uID0+ICEhcik7XG59XG5cbi8qKiBSZWdpb25zIGVsaWdpYmxlIGZvciBzZXQtb3BzOiBjbG9zZWQgYXJlYXMgKHJlY3QgLyBjbG9zZWQgcG9seWdvbiAvIG11bHRpLXBvbHlnb24pLFxuICogIGV4Y2x1ZGluZyBpbnRlbnNpdHktcHJvZmlsZSBsaW5lcy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvcEVsaWdpYmxlKHJlZ2lvbnM6IFJlZ2lvbltdKTogUmVnaW9uW10ge1xuICByZXR1cm4gcmVnaW9ucy5maWx0ZXIoXG4gICAgKHIpID0+XG4gICAgICByLmtpbmQgIT09ICdwcm9maWxlJyAmJlxuICAgICAgKHIuYm91bmRzIGluc3RhbmNlb2YgUmVjdGFuZ2xlIHx8XG4gICAgICAgIHIuYm91bmRzIGluc3RhbmNlb2YgTXVsdGlQb2x5Z29uIHx8XG4gICAgICAgIChyLmJvdW5kcyBpbnN0YW5jZW9mIFBvbHlnb24gJiYgci5ib3VuZHMuY2xvc2VkICE9PSBmYWxzZSkpLFxuICApO1xufVxuXG4vKipcbiAqIFRoZSByaWdodC1jbGljayBtZW51OiB0aGUgc2VsZWN0ZWQtcmVnaW9uIGFjdGlvbnMgbGVhZCAoMkQgb25seSksIHRoZW4gdGhlXG4gKiB2aWV3cG9ydCBhbmQgdG9vbCB0b2dnbGVzIGZvciBhIDJEIHZpZXcsIG9yIHRoZSBjYW1lcmEgbW9kZXMgZm9yIGEgM0Qgc2NlbmUuIFRoZVxuICogYXJtZWQgbW9kZSBpcyBoaWdobGlnaHRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkQ29udGV4dE1lbnUoc3RhdGU6IENvbnRleHRNZW51U3RhdGUsIGFjdGlvbnM6IENvbnRleHRNZW51QWN0aW9ucyk6IE1lbnVJdGVtW10ge1xuICBpZiAoIXN0YXRlLmlzSGVhdG1hcCkgcmV0dXJuIHN1cmZhY2UzZEl0ZW1zKHN0YXRlLCBhY3Rpb25zKTtcbiAgY29uc3QgYWN0aXZlID0gc3RhdGUuYWN0aXZlRHJhZ01vZGU7XG4gIGNvbnN0IHRvZ2dsZSA9IChsYWJlbDogc3RyaW5nLCBpY29uOiBzdHJpbmcsIG1vZGU6IHN0cmluZyk6IE1lbnVJdGVtID0+ICh7XG4gICAgbGFiZWwsXG4gICAgaWNvbixcbiAgICBzdHlsZUNsYXNzOiBhY3RpdmUgPT09IG1vZGUgPyBBQ1RJVkUgOiAnJyxcbiAgICBjb21tYW5kOiAoKSA9PiBhY3Rpb25zLnRvZ2dsZURyYWdNb2RlKG1vZGUpLFxuICB9KTtcbiAgY29uc3QgaXNJbWFnZVZpZXcgPSBzdGF0ZS5iYXNlUGxvdFR5cGUgPT09IFBsb3RUeXBlLklNQUdFO1xuICBjb25zdCBpdGVtczogTWVudUl0ZW1bXSA9IFtdO1xuICBjb25zdCByZWdpb25BY3Rpb25zID0gYnVpbGRSZWdpb25BY3Rpb25JdGVtcyhzdGF0ZSwgYWN0aW9ucyk7XG4gIGlmIChyZWdpb25BY3Rpb25zLmxlbmd0aCkgaXRlbXMucHVzaCguLi5yZWdpb25BY3Rpb25zLCB7IHNlcGFyYXRvcjogdHJ1ZSB9KTtcbiAgaXRlbXMucHVzaChcbiAgICB7IGxhYmVsOiAnQXV0b3NjYWxlJywgaWNvbjogJ3BpIHBpLXdpbmRvdy1tYXhpbWl6ZScsIGNvbW1hbmQ6ICgpID0+IGFjdGlvbnMuYXV0b3NjYWxlSW1hZ2UoKSB9LFxuICAgIHsgc2VwYXJhdG9yOiB0cnVlIH0sXG4gICk7XG4gIC8vICdab29tIHNlbGVjdGlvbicgaXMgUGxvdGx5J3MgcnViYmVyLWJhbmQgem9vbTsgaXQgZG9lc24ndCBhcHBseSB0byB0aGVcbiAgLy8gT3BlblNlYWRyYWdvbi1iYWNrZWQgSW1hZ2UgdmlldyAodXNlICdab29tIHRvIGJveCcgdGhlcmUgaW5zdGVhZCkuXG4gIGlmICghaXNJbWFnZVZpZXcpIGl0ZW1zLnB1c2godG9nZ2xlKCdab29tIHNlbGVjdGlvbicsICdwaSBwaS1zZWFyY2gnLCAnem9vbScpKTtcbiAgaXRlbXMucHVzaChcbiAgICB0b2dnbGUoJ1pvb20gdG8gYm94JywgJ3pvb20tYm94LW9mZi1pY29uJywgJ3pvb21Ub0JveCcpLFxuICAgIHRvZ2dsZSgnUGFuJywgJ3BpIHBpLWFycm93cy1hbHQnLCAncGFuJyksXG4gICAgeyBsYWJlbDogJ1pvb20gaW4nLCBpY29uOiAncGkgcGktc2VhcmNoLXBsdXMnLCBjb21tYW5kOiAoKSA9PiBhY3Rpb25zLnpvb21JbigpIH0sXG4gICAgeyBsYWJlbDogJ1pvb20gb3V0JywgaWNvbjogJ3BpIHBpLXNlYXJjaC1taW51cycsIGNvbW1hbmQ6ICgpID0+IGFjdGlvbnMuem9vbU91dCgpIH0sXG4gICAgeyBzZXBhcmF0b3I6IHRydWUgfSxcbiAgICB0b2dnbGUoJ1NlbGVjdCcsICdwaSBwaS1hcnJvdy11cC1yaWdodCcsICdzZWxlY3QnKSxcbiAgICB0b2dnbGUoJ0ZyZWVmb3JtJywgJ3BpIHBpLXBlbmNpbCcsICdkcmF3Y2xvc2VkcGF0aCcpLFxuICAgIHRvZ2dsZSgnQnJ1c2gnLCAnYnJ1c2gtaWNvbicsICdicnVzaCcpLFxuICAgIHRvZ2dsZSgnUG9seWxpbmUnLCAncG9seWxpbmUtaWNvbicsICdkcmF3b3BlbnBhdGgnKSxcbiAgICB0b2dnbGUoJ1JlY3RhbmdsZScsICdwaSBwaS1zdG9wJywgJ2RyYXdyZWN0JyksXG4gICAgdG9nZ2xlKCdXYW5kJywgJ3dhbmQtaWNvbicsICd3YW5kJyksXG4gICAgdG9nZ2xlKCdWZXJ0ZXggZXJhc2VyJywgJ3BpIHBpLWVyYXNlcicsICdlcmFzZVZlcnRleCcpLFxuICApO1xuICAvLyBWZXJ0ZXggZWRpdGluZyBydW5zIG9uIHRoZSBPcGVuU2VhZHJhZ29uIG92ZXJsYXksIHdoaWNoIGJhY2tzIHRoZSBJbWFnZSBwbG90XG4gIC8vIHR5cGUuIEhpZGRlbiBmb3Igb3RoZXIgMkQgdHlwZXMgKFBsb3RseSksIHdoZXJlIHRoZXNlIG1vZGVzIGFyZSBuby1vcHMuXG4gIGlmIChpc0ltYWdlVmlldykge1xuICAgIGl0ZW1zLnB1c2goXG4gICAgICB0b2dnbGUoJ1BvbHlnb24gKGNsaWNrIHZlcnRpY2VzKScsICdwb2x5Z29uLXZlcnRpY2VzLWljb24nLCAnZHJhd3BvbHlnb24nKSxcbiAgICAgIHRvZ2dsZSgnQWRkIHZlcnRleCcsICd2ZXJ0ZXgtYWRkLWljb24nLCAnYWRkcG9pbnQnKSxcbiAgICAgIHRvZ2dsZSgnRGVsZXRlIHZlcnRleCcsICd2ZXJ0ZXgtZGVsZXRlLWljb24nLCAnZGVsZXRlcG9pbnQnKSxcbiAgICApO1xuICB9XG4gIHJldHVybiBpdGVtcztcbn1cblxuLyoqIEEgM0Qgc2NlbmUncyBjYW1lcmEgbW9kZXMgYW5kIHJlc2V0LiAqL1xuZnVuY3Rpb24gc3VyZmFjZTNkSXRlbXMoc3RhdGU6IENvbnRleHRNZW51U3RhdGUsIGFjdGlvbnM6IENvbnRleHRNZW51QWN0aW9ucyk6IE1lbnVJdGVtW10ge1xuICBjb25zdCBtb2RlID0gKGxhYmVsOiBzdHJpbmcsIGljb246IHN0cmluZywgbTogc3RyaW5nKTogTWVudUl0ZW0gPT4gKHtcbiAgICBsYWJlbCxcbiAgICBpY29uLFxuICAgIHN0eWxlQ2xhc3M6IHN0YXRlLmFjdGl2ZVN1cmZhY2UzZE1vZGUgPT09IG0gPyBBQ1RJVkUgOiAnJyxcbiAgICBjb21tYW5kOiAoKSA9PiBhY3Rpb25zLnRvZ2dsZVN1cmZhY2UzZE1vZGUobSksXG4gIH0pO1xuICByZXR1cm4gW1xuICAgIG1vZGUoJ1pvb20nLCAncGkgcGktc2VhcmNoJywgJ3pvb20nKSxcbiAgICBtb2RlKCdQYW4nLCAncGkgcGktYXJyb3dzLWFsdCcsICdwYW4nKSxcbiAgICBtb2RlKCdPcmJpdGFsIHJvdGF0aW9uJywgJ3BpIHBpLWdsb2JlJywgJ29yYml0JyksXG4gICAgbW9kZSgnVHVybnRhYmxlIHJvdGF0aW9uJywgJ3BpIHBpLXN5bmMnLCAndHVybnRhYmxlJyksXG4gICAgeyBzZXBhcmF0b3I6IHRydWUgfSxcbiAgICB7IGxhYmVsOiAnUmVzZXQgY2FtZXJhJywgaWNvbjogJ3BpIHBpLWhvbWUnLCBjb21tYW5kOiAoKSA9PiBhY3Rpb25zLnJlc2V0U3VyZmFjZUNhbWVyYSgpIH0sXG4gIF07XG59XG5cbi8qKlxuICogSW1tZWRpYXRlIHJlZ2lvbiBhY3Rpb25zIG9uIHRoZSBjdXJyZW50IHNlbGVjdGlvbiAoaml0LXVpIzg1KTogbWVyZ2UsIHVuZ3JvdXAsXG4gKiBpbnZlcnNlLCBzaW1wbGlmeSwgdGhlIELDqXppZXIgY29udmVyc2lvbnMsIGFuZCBkZWxldGUg4oCUIHRoZSBvbmUtc2hvdCBnZW9tZXRyeVxuICogdHJhbnNmb3JtcywgZ3JvdXBlZCBhcGFydCBmcm9tIHRoZSB0b29sL21vZGUgdG9nZ2xlcyBhbmQgc2hvd24gb25seSB3aGVuIHNvbWV0aGluZ1xuICogaXMgc2VsZWN0ZWQuIEVhY2ggaXRlbSBpcyBnYXRlZCBvbiB3aGF0IHRoZSBzZWxlY3Rpb24gc3VwcG9ydHMuIFwiU2VsZWN0IGFsbFwiIGxlYWRzXG4gKiB3aGVuZXZlciB0aGUgaW1hZ2UgaGFzIHJlZ2lvbnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFJlZ2lvbkFjdGlvbkl0ZW1zKHN0YXRlOiBDb250ZXh0TWVudVN0YXRlLCBhY3Rpb25zOiBDb250ZXh0TWVudUFjdGlvbnMpOiBNZW51SXRlbVtdIHtcbiAgaWYgKCFzdGF0ZS5yZWdpb25zLnNvbWUoKHIpID0+IHIua2luZCAhPT0gJ3Byb2ZpbGUnKSkgcmV0dXJuIFtdO1xuICBjb25zdCBpdGVtczogTWVudUl0ZW1bXSA9IFtcbiAgICB7IGxhYmVsOiAnU2VsZWN0IGFsbCByZWdpb25zJywgaWNvbjogJ3BpIHBpLWNoZWNrLXNxdWFyZScsIGNvbW1hbmQ6ICgpID0+IGFjdGlvbnMuc2VsZWN0QWxsUmVnaW9ucygpIH0sXG4gIF07XG4gIGNvbnN0IHNlbGVjdGVkID0gcmVnaW9uc0F0KHN0YXRlLnJlZ2lvbnMsIHN0YXRlLnNlbGVjdGVkSW5kaWNlcyk7XG4gIGlmIChzZWxlY3RlZC5sZW5ndGggPT09IDApIHJldHVybiBpdGVtcztcbiAgY29uc3QgZWxpZ2libGUgPSBvcEVsaWdpYmxlKHNlbGVjdGVkKTtcbiAgaWYgKGVsaWdpYmxlLmxlbmd0aCA+PSAyKSB7XG4gICAgaXRlbXMucHVzaCh7IGxhYmVsOiAnTWVyZ2UgLyBncm91cCcsIGljb246ICdwaSBwaS1saW5rJywgY29tbWFuZDogKCkgPT4gYWN0aW9ucy5tZXJnZVJlZ2lvbnMoKSB9KTtcbiAgfVxuICBpZiAoc2VsZWN0ZWQuc29tZSgocikgPT4gc3RhdGUuY2FuVW5ncm91cChyKSkpIHtcbiAgICBpdGVtcy5wdXNoKHsgbGFiZWw6ICdVbmdyb3VwJywgaWNvbjogJ3BpIHBpLXNpdGVtYXAnLCBjb21tYW5kOiAoKSA9PiBhY3Rpb25zLnVuZ3JvdXBSZWdpb25zKCkgfSk7XG4gIH1cbiAgaWYgKGVsaWdpYmxlLmxlbmd0aCA+PSAxKSB7XG4gICAgaXRlbXMucHVzaChcbiAgICAgIHsgbGFiZWw6ICdJbnZlcnNlJywgaWNvbjogJ3BpIHBpLWNsb25lJywgY29tbWFuZDogKCkgPT4gYWN0aW9ucy5pbnZlcnNlUmVnaW9ucygpIH0sXG4gICAgICB7XG4gICAgICAgIGxhYmVsOiAnU2ltcGxpZnknLFxuICAgICAgICBpY29uOiAncGkgcGktY2hhcnQtbGluZScsXG4gICAgICAgIGl0ZW1zOiBbXG4gICAgICAgICAgeyBsYWJlbDogJ0xpZ2h0ICgxIHB4KScsIGNvbW1hbmQ6ICgpID0+IGFjdGlvbnMuc2ltcGxpZnlSZWdpb25zKDEpIH0sXG4gICAgICAgICAgeyBsYWJlbDogJ01lZGl1bSAoMyBweCknLCBjb21tYW5kOiAoKSA9PiBhY3Rpb25zLnNpbXBsaWZ5UmVnaW9ucygzKSB9LFxuICAgICAgICAgIHsgbGFiZWw6ICdTdHJvbmcgKDggcHgpJywgY29tbWFuZDogKCkgPT4gYWN0aW9ucy5zaW1wbGlmeVJlZ2lvbnMoOCkgfSxcbiAgICAgICAgICB7IHNlcGFyYXRvcjogdHJ1ZSB9LFxuICAgICAgICAgIHsgbGFiZWw6ICdDdXN0b23igKYnLCBjb21tYW5kOiAoKSA9PiBhY3Rpb25zLm9wZW5TaW1wbGlmeURpYWxvZygpIH0sXG4gICAgICAgIF0sXG4gICAgICB9LFxuICAgICk7XG4gIH1cbiAgLy8gQsOpemllciBjb252ZXJzaW9ucyBhcmUgdmVydGV4LWxldmVsIGVkaXRzIOKAlCBJbWFnZSAoT3BlblNlYWRyYWdvbikgdmlldyBvbmx5IOKAlFxuICAvLyBnYXRlZCBvbiB0aGUgc2VsZWN0aW9uJ3MgY3VycmVudCBmb3JtLlxuICBpZiAoc3RhdGUuYmFzZVBsb3RUeXBlID09PSBQbG90VHlwZS5JTUFHRSkge1xuICAgIGlmIChzZWxlY3RlZC5zb21lKChyKSA9PiAoci5ib3VuZHMgaW5zdGFuY2VvZiBQb2x5Z29uICYmICFyLmJvdW5kcy5iZXppZXIpIHx8IHIuYm91bmRzIGluc3RhbmNlb2YgUmVjdGFuZ2xlKSkge1xuICAgICAgaXRlbXMucHVzaCh7IGxhYmVsOiAnQ29udmVydCB0byBCw6l6aWVyJywgaWNvbjogJ3RvLWJlemllci1pY29uJywgY29tbWFuZDogKCkgPT4gYWN0aW9ucy50b0JlemllclJlZ2lvbigpIH0pO1xuICAgIH1cbiAgICBpZiAoc2VsZWN0ZWQuc29tZSgocikgPT4gci5ib3VuZHMgaW5zdGFuY2VvZiBQb2x5Z29uICYmIHIuYm91bmRzLmJlemllcikpIHtcbiAgICAgIGl0ZW1zLnB1c2goe1xuICAgICAgICBsYWJlbDogJ0NvbnZlcnQgdG8gcG9seWdvbicsXG4gICAgICAgIGljb246ICd0by1wb2x5Z29uLWljb24nLFxuICAgICAgICBjb21tYW5kOiAoKSA9PiBhY3Rpb25zLnRvUG9seWdvblJlZ2lvbigpLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIGl0ZW1zLnB1c2goeyBsYWJlbDogJ0RlbGV0ZSByZWdpb24nLCBpY29uOiAncGkgcGktdHJhc2gnLCBjb21tYW5kOiAoKSA9PiBhY3Rpb25zLmRlbGV0ZVJlZ2lvbigpIH0pO1xuICByZXR1cm4gaXRlbXM7XG59XG4iXX0=
|