@jax-data-science/sci-image-visualizer 0.8.3 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +201 -460
- package/esm2022/index.mjs +34 -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/image.contract.mjs +1 -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/region-store.contract.mjs +1 -1
- package/esm2022/lib/contracts/sam.contract.mjs +1 -1
- package/esm2022/lib/contracts/section-view.contract.mjs +2 -0
- 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/loft.mjs +128 -0
- package/esm2022/lib/geometry/polylabel.mjs +156 -0
- package/esm2022/lib/geometry/raster.mjs +98 -0
- package/esm2022/lib/geometry/reconstruct.mjs +315 -0
- package/esm2022/lib/geometry/reslice-image.mjs +57 -0
- package/esm2022/lib/geometry/ring.mjs +201 -0
- package/esm2022/lib/geometry/section.mjs +215 -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 +12 -9
- package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +83 -0
- package/esm2022/lib/implementations/napari-js/napari-region-mesh-pointer.mjs +100 -0
- package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +180 -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 +270 -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 +347 -0
- package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +427 -4207
- package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +129 -0
- package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +550 -0
- package/esm2022/lib/implementations/napari-js/napari-volume-slice-planes.mjs +103 -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 +194 -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 +164 -0
- package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +213 -716
- 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 +134 -0
- package/esm2022/lib/models/region-clone.mjs +68 -0
- package/esm2022/lib/models/region-geojson.mjs +411 -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/class-tree/class-tree.component.mjs +156 -0
- package/esm2022/lib/region-editor/class-tree/class-tree.mjs +108 -0
- package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +163 -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 +896 -660
- package/esm2022/lib/region-editor/region-metrics.mjs +86 -0
- package/esm2022/lib/region-editor/region-persistence.service.mjs +160 -0
- package/esm2022/lib/region-editor/region-table/region-table.component.mjs +169 -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/region-source-layer.mjs +378 -0
- package/esm2022/lib/region-overlay/region-style.mjs +97 -0
- package/esm2022/lib/region-overlay/svg-region-renderer.mjs +228 -0
- package/esm2022/lib/region-source/http-region-source.mjs +104 -0
- package/esm2022/lib/region-source/region-source-ops.mjs +53 -0
- package/esm2022/lib/region-source/region-source-worker.mjs +10 -0
- package/esm2022/lib/region-source/region-source.mjs +67 -0
- package/esm2022/lib/region-source/region-tiles.mjs +708 -0
- package/esm2022/lib/region-source/worker-region-source.mjs +229 -0
- package/esm2022/lib/render-orchestrator.mjs +14 -11
- package/esm2022/lib/render-session.mjs +207 -0
- package/esm2022/lib/routing-visualizer.service.mjs +858 -414
- package/esm2022/lib/section-pane/section-pane.component.mjs +299 -0
- 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 +53 -5
- package/esm2022/lib/store/class-signatures.mjs +63 -0
- package/esm2022/lib/store/region-history.mjs +146 -0
- package/esm2022/lib/store/region-scope-cache.mjs +144 -0
- package/esm2022/lib/store/region-selection.mjs +82 -0
- package/esm2022/lib/store/region-source-scope.mjs +171 -0
- package/esm2022/lib/store/region-store.service.mjs +986 -670
- package/esm2022/lib/store/spatial-selection.service.mjs +2 -2
- package/esm2022/lib/store/visualizer-store.service.mjs +81 -76
- 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 +120 -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 +121 -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 +84 -119
- 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 +123 -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/volume-sections.mjs +175 -0
- package/esm2022/lib/visualizer.component.mjs +602 -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-BKQhpbHv.mjs +47169 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BKQhpbHv.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs +238 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs +12 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.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/region-source.worker.js +1067 -0
- package/fesm2022/spatial-math.worker.js +471 -0
- package/fesm2022/tsne.worker.js +32 -15
- package/index.d.ts +19 -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/image.contract.d.ts +4 -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 +85 -1
- package/lib/contracts/region-overlay.contract.d.ts +5 -0
- package/lib/contracts/region-store.contract.d.ts +22 -0
- package/lib/contracts/sam.contract.d.ts +7 -0
- package/lib/contracts/section-view.contract.d.ts +44 -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 +231 -54
- package/lib/contracts/viz-config.d.ts +9 -0
- package/lib/geometry/contour.d.ts +24 -0
- package/lib/geometry/loft.d.ts +22 -0
- package/lib/geometry/polylabel.d.ts +23 -0
- package/lib/geometry/raster.d.ts +42 -0
- package/lib/geometry/reconstruct.d.ts +54 -0
- package/lib/geometry/reslice-image.d.ts +33 -0
- package/lib/geometry/ring.d.ts +67 -0
- package/lib/geometry/section.d.ts +52 -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 +4 -3
- package/lib/implementations/napari-js/napari-loading-state.d.ts +37 -0
- package/lib/implementations/napari-js/napari-region-mesh-pointer.d.ts +32 -0
- package/lib/implementations/napari-js/napari-region-overlay.d.ts +68 -71
- package/lib/implementations/napari-js/napari-scene.d.ts +126 -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 +91 -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 +169 -883
- package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +66 -0
- package/lib/implementations/napari-js/napari-volume-scene.d.ts +148 -0
- package/lib/implementations/napari-js/napari-volume-slice-planes.d.ts +43 -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 +38 -0
- package/lib/implementations/osd/osd-region-overlay.d.ts +46 -51
- 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 +83 -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 +25 -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 +45 -0
- package/lib/models/region-clone.d.ts +20 -0
- package/lib/models/region-geojson.d.ts +57 -0
- package/lib/models/region.d.ts +59 -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/class-tree/class-tree.component.d.ts +78 -0
- package/lib/region-editor/class-tree/class-tree.d.ts +31 -0
- package/lib/region-editor/classes-panel/classes-panel.component.d.ts +86 -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 +283 -200
- package/lib/region-editor/region-metrics.d.ts +34 -0
- package/lib/region-editor/region-persistence.service.d.ts +77 -0
- package/lib/region-editor/region-table/region-table.component.d.ts +89 -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 +158 -0
- package/lib/region-overlay/region-hit-test.d.ts +38 -0
- package/lib/region-overlay/region-source-layer.d.ts +96 -0
- package/lib/region-overlay/region-style.d.ts +52 -0
- package/lib/region-overlay/svg-region-renderer.d.ts +110 -0
- package/lib/region-source/http-region-source.d.ts +45 -0
- package/lib/region-source/region-source-ops.d.ts +89 -0
- package/lib/region-source/region-source-worker.d.ts +7 -0
- package/lib/region-source/region-source.d.ts +82 -0
- package/lib/region-source/region-tiles.d.ts +289 -0
- package/lib/region-source/worker-region-source.d.ts +65 -0
- package/lib/render-orchestrator.d.ts +6 -2
- package/lib/render-session.d.ts +75 -0
- package/lib/routing-visualizer.service.d.ts +248 -59
- package/lib/section-pane/section-pane.component.d.ts +47 -0
- 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 +39 -2
- package/lib/store/class-signatures.d.ts +11 -0
- package/lib/store/region-history.d.ts +66 -0
- package/lib/store/region-scope-cache.d.ts +65 -0
- package/lib/store/region-selection.d.ts +36 -0
- package/lib/store/region-source-scope.d.ts +68 -0
- package/lib/store/region-store.service.d.ts +312 -116
- package/lib/store/visualizer-store.service.d.ts +32 -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 +62 -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 +51 -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 +55 -84
- 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 +46 -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/volume-sections.d.ts +64 -0
- package/lib/visualizer.component.d.ts +232 -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/assets/slice.svg +23 -0
- 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,378 @@
|
|
|
1
|
+
import { isAbortError } from '../region-source/region-source';
|
|
2
|
+
import { featureAt, featuresInRect, regionLevelFor, regionTileId, regionTilesInRect, } from '../region-source/region-tiles';
|
|
3
|
+
import { IDENTITY_AFFINE, ScreenLayer, applyAffine, svgEl } from './svg-region-renderer';
|
|
4
|
+
import { isFilled, placeInsideLabel, shapePaint } from './region-style';
|
|
5
|
+
/** Wait this long after the last camera change before planning tiles (ms). */
|
|
6
|
+
export const SOURCE_REPLAN_MS = 90;
|
|
7
|
+
/** The view is padded by this fraction on each side, so a short pan finds its tiles loaded. */
|
|
8
|
+
export const SOURCE_VIEW_MARGIN = 0.25;
|
|
9
|
+
/** At most this many tiles in view. */
|
|
10
|
+
export const SOURCE_MAX_TILES = 256;
|
|
11
|
+
/** A rubber band takes at most this many source features into the working set. */
|
|
12
|
+
export const SOURCE_MARQUEE_LIMIT = 2000;
|
|
13
|
+
/** Loaded tiles kept by the layer for drawing (the source caches more). */
|
|
14
|
+
const LAYER_TILE_LIMIT = 512;
|
|
15
|
+
/** Stroke width of a source outline, screen px (an unselected region's). */
|
|
16
|
+
const SOURCE_STROKE_PX = 2;
|
|
17
|
+
export class RegionSourceLayer {
|
|
18
|
+
constructor(svg, view$, size = () => svgSize(svg)) {
|
|
19
|
+
this.svg = svg;
|
|
20
|
+
this.size = size;
|
|
21
|
+
this.group = svgEl('g');
|
|
22
|
+
this.camera = IDENTITY_AFFINE;
|
|
23
|
+
/** Class labels inside the features, in screen space over the outlines. */
|
|
24
|
+
this.labelLayer = new ScreenLayer(svgEl('g'), (x, y) => applyAffine(this.camera, x, y));
|
|
25
|
+
/** Class name → depth in the source's class hierarchy (parents draw under their children). */
|
|
26
|
+
this.depthOf = new Map();
|
|
27
|
+
/** Class name → its parent class in the source's class hierarchy. */
|
|
28
|
+
this.parentOf = new Map();
|
|
29
|
+
this.view = null;
|
|
30
|
+
this.visible = true;
|
|
31
|
+
/** Loaded tiles of the current source and plane, by id, least recently used first. */
|
|
32
|
+
this.tiles = new Map();
|
|
33
|
+
/** The tiles the view wants now. */
|
|
34
|
+
this.wanted = [];
|
|
35
|
+
/** The features drawn, by id (each at the finest level loaded). */
|
|
36
|
+
this.drawn = new Map();
|
|
37
|
+
this.loading = null;
|
|
38
|
+
this.replanTimer = null;
|
|
39
|
+
this.drawFrame = null;
|
|
40
|
+
this.group.setAttribute('data-layer', 'region-source');
|
|
41
|
+
this.group.setAttribute('pointer-events', 'none');
|
|
42
|
+
this.labelLayer.group.setAttribute('data-layer', 'region-source-labels');
|
|
43
|
+
this.sub = view$.subscribe((view) => this.setView(view));
|
|
44
|
+
}
|
|
45
|
+
/** Follow the camera: rewrite the transform now, re-plan the tiles once it settles. */
|
|
46
|
+
setCamera(affine) {
|
|
47
|
+
if (!affine.every(Number.isFinite))
|
|
48
|
+
return;
|
|
49
|
+
if (affine.every((v, i) => v === this.camera[i]))
|
|
50
|
+
return;
|
|
51
|
+
this.camera = affine;
|
|
52
|
+
this.applyCamera();
|
|
53
|
+
this.labelLayer.reproject();
|
|
54
|
+
if (!this.view)
|
|
55
|
+
return;
|
|
56
|
+
if (this.replanTimer)
|
|
57
|
+
clearTimeout(this.replanTimer);
|
|
58
|
+
this.replanTimer = setTimeout(() => {
|
|
59
|
+
this.replanTimer = null;
|
|
60
|
+
this.replan();
|
|
61
|
+
}, SOURCE_REPLAN_MS);
|
|
62
|
+
}
|
|
63
|
+
/** Show or hide the source with the regions. */
|
|
64
|
+
setVisible(visible) {
|
|
65
|
+
if (visible === this.visible)
|
|
66
|
+
return;
|
|
67
|
+
this.visible = visible;
|
|
68
|
+
this.attach();
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* The source feature under world point (x, y) — inside an area, or within `tolerancePx`
|
|
72
|
+
* screen pixels of a polyline — from the features drawn; the innermost of nested ones.
|
|
73
|
+
*/
|
|
74
|
+
featureAt(x, y, tolerancePx = 4) {
|
|
75
|
+
if (!this.view || !this.visible)
|
|
76
|
+
return null;
|
|
77
|
+
return featureAt(this.drawn.values(), x, y, tolerancePx / this.scale());
|
|
78
|
+
}
|
|
79
|
+
/** The drawn source features whose box meets the world box (the rubber band's rule). */
|
|
80
|
+
featuresInRect(x0, y0, x1, y1) {
|
|
81
|
+
if (!this.view || !this.visible)
|
|
82
|
+
return [];
|
|
83
|
+
return featuresInRect(this.drawn.values(), [x0, y0, x1, y1]);
|
|
84
|
+
}
|
|
85
|
+
destroy() {
|
|
86
|
+
this.sub.unsubscribe();
|
|
87
|
+
this.loading?.abort();
|
|
88
|
+
if (this.replanTimer)
|
|
89
|
+
clearTimeout(this.replanTimer);
|
|
90
|
+
if (this.drawFrame !== null)
|
|
91
|
+
cancelFrame(this.drawFrame);
|
|
92
|
+
this.group.parentNode?.removeChild(this.group);
|
|
93
|
+
this.labelLayer.group.parentNode?.removeChild(this.labelLayer.group);
|
|
94
|
+
}
|
|
95
|
+
setView(view) {
|
|
96
|
+
const prev = this.view;
|
|
97
|
+
this.view = view;
|
|
98
|
+
if (!view || prev?.source !== view.source || prev.plane !== view.plane) {
|
|
99
|
+
this.tiles.clear();
|
|
100
|
+
this.loading?.abort();
|
|
101
|
+
this.loading = null;
|
|
102
|
+
}
|
|
103
|
+
if (view && prev?.source !== view.source) {
|
|
104
|
+
const hierarchy = view.source.info.hierarchy ?? [];
|
|
105
|
+
this.depthOf = hierarchyDepths(hierarchy);
|
|
106
|
+
this.parentOf = new Map(hierarchy.filter((n) => n.parent).map((n) => [n.name, n.parent]));
|
|
107
|
+
}
|
|
108
|
+
this.attach();
|
|
109
|
+
if (view)
|
|
110
|
+
this.replan();
|
|
111
|
+
else
|
|
112
|
+
this.draw();
|
|
113
|
+
}
|
|
114
|
+
/** The layer is the svg's first child (under the regions) while it shows a source. */
|
|
115
|
+
attach() {
|
|
116
|
+
const show = !!this.view && this.visible;
|
|
117
|
+
const labels = this.labelLayer.group;
|
|
118
|
+
if (!show) {
|
|
119
|
+
this.group.parentNode?.removeChild(this.group);
|
|
120
|
+
labels.parentNode?.removeChild(labels);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (this.svg.firstChild !== this.group)
|
|
124
|
+
this.svg.insertBefore(this.group, this.svg.firstChild);
|
|
125
|
+
if (this.group.nextSibling !== labels)
|
|
126
|
+
this.svg.insertBefore(labels, this.group.nextSibling);
|
|
127
|
+
}
|
|
128
|
+
applyCamera() {
|
|
129
|
+
this.group.setAttribute('transform', `matrix(${this.camera.join(' ')})`);
|
|
130
|
+
}
|
|
131
|
+
/** Screen px per world unit. */
|
|
132
|
+
scale() {
|
|
133
|
+
const [a, b, c, d] = this.camera;
|
|
134
|
+
return Math.sqrt(Math.abs(a * d - b * c)) || 1;
|
|
135
|
+
}
|
|
136
|
+
/** The world box in view, padded by the margin; null when the svg has no size yet. */
|
|
137
|
+
viewRect() {
|
|
138
|
+
const { width, height } = this.size();
|
|
139
|
+
if (!(width > 0) || !(height > 0))
|
|
140
|
+
return null;
|
|
141
|
+
const [a, b, c, d, e, f] = this.camera;
|
|
142
|
+
const det = a * d - b * c;
|
|
143
|
+
if (!det)
|
|
144
|
+
return null;
|
|
145
|
+
const toWorld = (sx, sy) => {
|
|
146
|
+
const x = sx - e, y = sy - f;
|
|
147
|
+
return [(d * x - c * y) / det, (a * y - b * x) / det];
|
|
148
|
+
};
|
|
149
|
+
const mx = width * SOURCE_VIEW_MARGIN, my = height * SOURCE_VIEW_MARGIN;
|
|
150
|
+
const corners = [
|
|
151
|
+
toWorld(-mx, -my),
|
|
152
|
+
toWorld(width + mx, -my),
|
|
153
|
+
toWorld(-mx, height + my),
|
|
154
|
+
toWorld(width + mx, height + my),
|
|
155
|
+
];
|
|
156
|
+
const xs = corners.map((p) => p[0]), ys = corners.map((p) => p[1]);
|
|
157
|
+
return [Math.min(...xs), Math.min(...ys), Math.max(...xs), Math.max(...ys)];
|
|
158
|
+
}
|
|
159
|
+
/** Work out the tiles the view needs, draw what is loaded, and load the rest. */
|
|
160
|
+
replan() {
|
|
161
|
+
const view = this.view;
|
|
162
|
+
if (!view)
|
|
163
|
+
return;
|
|
164
|
+
const rect = this.viewRect();
|
|
165
|
+
if (!rect) {
|
|
166
|
+
this.wanted = [];
|
|
167
|
+
this.draw();
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const info = view.source.info;
|
|
171
|
+
const level = regionLevelFor(this.scale(), info.levels);
|
|
172
|
+
this.wanted = regionTilesInRect(rect, level, info.tileSize, info.bounds, SOURCE_MAX_TILES);
|
|
173
|
+
this.scheduleDraw();
|
|
174
|
+
const missing = this.wanted.filter((k) => !this.tiles.has(regionTileId(k)));
|
|
175
|
+
this.loading?.abort();
|
|
176
|
+
this.loading = null;
|
|
177
|
+
if (!missing.length)
|
|
178
|
+
return;
|
|
179
|
+
const loading = new AbortController();
|
|
180
|
+
this.loading = loading;
|
|
181
|
+
for (const key of missing) {
|
|
182
|
+
view.source.getTile(view.plane, key, loading.signal).then((tile) => {
|
|
183
|
+
if (this.view?.source !== view.source || this.view.plane !== view.plane)
|
|
184
|
+
return;
|
|
185
|
+
this.keep(tile);
|
|
186
|
+
this.scheduleDraw();
|
|
187
|
+
}, (err) => {
|
|
188
|
+
if (!isAbortError(err))
|
|
189
|
+
console.warn('[regions] region tile failed', err);
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
keep(tile) {
|
|
194
|
+
const id = regionTileId(tile);
|
|
195
|
+
this.tiles.delete(id);
|
|
196
|
+
this.tiles.set(id, tile);
|
|
197
|
+
while (this.tiles.size > LAYER_TILE_LIMIT)
|
|
198
|
+
this.tiles.delete(this.tiles.keys().next().value);
|
|
199
|
+
}
|
|
200
|
+
scheduleDraw() {
|
|
201
|
+
if (this.drawFrame !== null)
|
|
202
|
+
return;
|
|
203
|
+
this.drawFrame = requestFrame(() => {
|
|
204
|
+
this.drawFrame = null;
|
|
205
|
+
this.draw();
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Rebuild the paths from the wanted tiles that are loaded, a missing tile's nearest loaded
|
|
210
|
+
* ancestor standing in for it; each feature once, at the finest level loaded.
|
|
211
|
+
*/
|
|
212
|
+
draw() {
|
|
213
|
+
const view = this.view;
|
|
214
|
+
const drawn = new Map();
|
|
215
|
+
const level = new Map();
|
|
216
|
+
if (view) {
|
|
217
|
+
const used = new Set();
|
|
218
|
+
for (const key of this.wanted) {
|
|
219
|
+
const tile = this.loadedOrAncestor(key);
|
|
220
|
+
if (!tile || used.has(regionTileId(tile)))
|
|
221
|
+
continue;
|
|
222
|
+
used.add(regionTileId(tile));
|
|
223
|
+
for (const f of tile.features) {
|
|
224
|
+
if (view.taken.has(f.id) || view.isHidden?.(f.label))
|
|
225
|
+
continue;
|
|
226
|
+
const had = level.get(f.id);
|
|
227
|
+
if (had !== undefined && had <= tile.level)
|
|
228
|
+
continue;
|
|
229
|
+
drawn.set(f.id, f);
|
|
230
|
+
level.set(f.id, tile.level);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
this.drawn = drawn;
|
|
235
|
+
const filled = !!view && isFilled(view.style);
|
|
236
|
+
const frag = document.createDocumentFragment();
|
|
237
|
+
for (const run of this.runs(drawn, filled)) {
|
|
238
|
+
const path = svgEl('path');
|
|
239
|
+
path.setAttribute('d', run.features.flatMap((f) => f.rings.map((r) => ringD(r, !f.open))).join(''));
|
|
240
|
+
path.setAttribute('fill-rule', 'evenodd');
|
|
241
|
+
path.setAttribute('stroke-linejoin', 'round');
|
|
242
|
+
path.setAttribute('vector-effect', 'non-scaling-stroke');
|
|
243
|
+
if (filled && view) {
|
|
244
|
+
const paint = shapePaint(run.color, false, view.style);
|
|
245
|
+
path.setAttribute('fill', paint.fill);
|
|
246
|
+
path.setAttribute('fill-opacity', `${paint.fillOpacity}`);
|
|
247
|
+
path.setAttribute('stroke', paint.stroke);
|
|
248
|
+
path.setAttribute('stroke-width', `${paint.strokeWidth}`);
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
path.setAttribute('fill', 'none');
|
|
252
|
+
path.setAttribute('stroke', run.color);
|
|
253
|
+
path.setAttribute('stroke-width', `${SOURCE_STROKE_PX}`);
|
|
254
|
+
}
|
|
255
|
+
frag.appendChild(path);
|
|
256
|
+
}
|
|
257
|
+
while (this.group.firstChild)
|
|
258
|
+
this.group.removeChild(this.group.firstChild);
|
|
259
|
+
this.group.appendChild(frag);
|
|
260
|
+
this.applyCamera();
|
|
261
|
+
this.drawLabels(filled);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* The drawn features as paths: one per colour when outlined; filled, in paint order — parents
|
|
265
|
+
* (by the class hierarchy) and then larger features first, so what lies inside paints over
|
|
266
|
+
* them — one path per run of a colour.
|
|
267
|
+
*/
|
|
268
|
+
runs(drawn, filled) {
|
|
269
|
+
const view = this.view;
|
|
270
|
+
const colorOf = (f) => view?.colorOf(f) ?? '#00FFFF';
|
|
271
|
+
if (!filled) {
|
|
272
|
+
const byColor = new Map();
|
|
273
|
+
for (const f of drawn.values()) {
|
|
274
|
+
const color = colorOf(f);
|
|
275
|
+
const list = byColor.get(color);
|
|
276
|
+
if (list)
|
|
277
|
+
list.push(f);
|
|
278
|
+
else
|
|
279
|
+
byColor.set(color, [f]);
|
|
280
|
+
}
|
|
281
|
+
return Array.from(byColor, ([color, features]) => ({ color, features }));
|
|
282
|
+
}
|
|
283
|
+
const area = (f) => (f.bbox[2] - f.bbox[0]) * (f.bbox[3] - f.bbox[1]);
|
|
284
|
+
const depth = (f) => this.depthOf.get(f.label ?? '') ?? 0;
|
|
285
|
+
const order = Array.from(drawn.values()).sort((a, b) => depth(a) - depth(b) || area(b) - area(a));
|
|
286
|
+
const runs = [];
|
|
287
|
+
for (const f of order) {
|
|
288
|
+
const color = colorOf(f);
|
|
289
|
+
const last = runs[runs.length - 1];
|
|
290
|
+
if (last && last.color === color)
|
|
291
|
+
last.features.push(f);
|
|
292
|
+
else
|
|
293
|
+
runs.push({ color, features: [f] });
|
|
294
|
+
}
|
|
295
|
+
return runs;
|
|
296
|
+
}
|
|
297
|
+
/** Class labels inside the drawn features (each part where it fits), when labels are on. */
|
|
298
|
+
drawLabels(filled) {
|
|
299
|
+
this.labelLayer.clear();
|
|
300
|
+
const view = this.view;
|
|
301
|
+
if (!view?.labels)
|
|
302
|
+
return;
|
|
303
|
+
// Only the deepest classes drawn are labelled: a class whose subclasses are drawn too (an
|
|
304
|
+
// atlas's "Isocortex" under its areas) would only repeat over them.
|
|
305
|
+
const covered = new Set();
|
|
306
|
+
for (const f of this.drawn.values()) {
|
|
307
|
+
let p = f.label ? this.parentOf.get(f.label) : undefined;
|
|
308
|
+
while (p && !covered.has(p)) {
|
|
309
|
+
covered.add(p);
|
|
310
|
+
p = this.parentOf.get(p);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
for (const f of this.drawn.values()) {
|
|
314
|
+
const at = f.labels;
|
|
315
|
+
if (!at || !f.label || covered.has(f.label))
|
|
316
|
+
continue;
|
|
317
|
+
const color = filled ? '#111' : view.colorOf(f);
|
|
318
|
+
for (let k = 0; k + 2 < at.length; k += 3) {
|
|
319
|
+
placeInsideLabel(this.labelLayer, f.label, { x: at[k], y: at[k + 1], room: at[k + 2] }, color);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
/** The loaded tile for `key`, else its nearest loaded coarser ancestor. */
|
|
324
|
+
loadedOrAncestor(key) {
|
|
325
|
+
const levels = this.view?.source.info.levels ?? 0;
|
|
326
|
+
let { gx, gy } = key;
|
|
327
|
+
for (let level = key.level; level < levels; level++) {
|
|
328
|
+
const tile = this.tiles.get(regionTileId({ level, gx, gy }));
|
|
329
|
+
if (tile)
|
|
330
|
+
return tile;
|
|
331
|
+
gx = Math.floor(gx / 2);
|
|
332
|
+
gy = Math.floor(gy / 2);
|
|
333
|
+
}
|
|
334
|
+
return null;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
/** Path data of one ring (`closed`) or polyline, in world units to 1/100. */
|
|
338
|
+
function ringD(ring, closed) {
|
|
339
|
+
const n = ring.length >> 1;
|
|
340
|
+
if (n < 2)
|
|
341
|
+
return '';
|
|
342
|
+
let d = `M${r2(ring[0])} ${r2(ring[1])}`;
|
|
343
|
+
for (let i = 1; i < n; i++)
|
|
344
|
+
d += `L${r2(ring[2 * i])} ${r2(ring[2 * i + 1])}`;
|
|
345
|
+
return closed ? `${d}Z` : d;
|
|
346
|
+
}
|
|
347
|
+
function r2(v) {
|
|
348
|
+
return Math.round(v * 100) / 100;
|
|
349
|
+
}
|
|
350
|
+
function svgSize(svg) {
|
|
351
|
+
const width = svg.clientWidth || svg.getBoundingClientRect().width;
|
|
352
|
+
const height = svg.clientHeight || svg.getBoundingClientRect().height;
|
|
353
|
+
return { width, height };
|
|
354
|
+
}
|
|
355
|
+
const requestFrame = (fn) => typeof requestAnimationFrame === 'function'
|
|
356
|
+
? requestAnimationFrame(fn)
|
|
357
|
+
: setTimeout(fn, 16);
|
|
358
|
+
const cancelFrame = (id) => typeof cancelAnimationFrame === 'function' ? cancelAnimationFrame(id) : clearTimeout(id);
|
|
359
|
+
/** Depth of each class in a class hierarchy (a root is 0); empty without one. */
|
|
360
|
+
function hierarchyDepths(hierarchy) {
|
|
361
|
+
const depths = new Map();
|
|
362
|
+
if (!hierarchy)
|
|
363
|
+
return depths;
|
|
364
|
+
const parent = new Map(hierarchy.map((n) => [n.name, n.parent ?? null]));
|
|
365
|
+
for (const n of hierarchy) {
|
|
366
|
+
let d = 0;
|
|
367
|
+
let p = parent.get(n.name);
|
|
368
|
+
const seen = new Set([n.name]);
|
|
369
|
+
while (p && !seen.has(p)) {
|
|
370
|
+
seen.add(p);
|
|
371
|
+
d++;
|
|
372
|
+
p = parent.get(p) ?? null;
|
|
373
|
+
}
|
|
374
|
+
depths.set(n.name, d);
|
|
375
|
+
}
|
|
376
|
+
return depths;
|
|
377
|
+
}
|
|
378
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaW9uLXNvdXJjZS1sYXllci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvcmVnaW9uLW92ZXJsYXkvcmVnaW9uLXNvdXJjZS1sYXllci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFpQkEsT0FBTyxFQUFvQixZQUFZLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNoRixPQUFPLEVBS0wsU0FBUyxFQUNULGNBQWMsRUFDZCxjQUFjLEVBQ2QsWUFBWSxFQUNaLGlCQUFpQixHQUNsQixNQUFNLCtCQUErQixDQUFDO0FBQ3ZDLE9BQU8sRUFBVSxlQUFlLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNqRyxPQUFPLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixFQUFFLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXhFLDhFQUE4RTtBQUM5RSxNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBRyxFQUFFLENBQUM7QUFDbkMsK0ZBQStGO0FBQy9GLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FBQztBQUN2Qyx1Q0FBdUM7QUFDdkMsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQUcsR0FBRyxDQUFDO0FBQ3BDLGtGQUFrRjtBQUNsRixNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLENBQUM7QUFDekMsMkVBQTJFO0FBQzNFLE1BQU0sZ0JBQWdCLEdBQUcsR0FBRyxDQUFDO0FBQzdCLDRFQUE0RTtBQUM1RSxNQUFNLGdCQUFnQixHQUFHLENBQUMsQ0FBQztBQUszQixNQUFNLE9BQU8saUJBQWlCO0lBc0I1QixZQUNtQixHQUFrQixFQUNuQyxLQUEwQyxFQUN6QixPQUFnQixHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDO1FBRmxDLFFBQUcsR0FBSCxHQUFHLENBQWU7UUFFbEIsU0FBSSxHQUFKLElBQUksQ0FBOEI7UUF4QnBD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Q0FBQyxDQUFDLENBQUM7UUFDdkMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDekIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNaLENBQUMsRUFBRSxDQUFDO1lBQ0osQ0FBQyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDO1FBQzVCLENBQUM7UUFDRCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDeEIsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIERyYXdzIGEgcmVnaW9uIHNvdXJjZSAoc2VlIGByZWdpb24tc291cmNlYCkgdW5kZXIgdGhlIGVkaXRhYmxlIHJlZ2lvbnMsIGF0IHRoZSBsZXZlbCBvZiBkZXRhaWxcbiAqIHRoZSB6b29tIGNhbGxzIGZvciwgZnJvbSB0aGUgdGlsZXMgaW4gdmlldyBvbmx5IOKAlCB0aGUgd2F5IHRoZSBzcGF0aWFsIHZpZXdzIGRyYXcgY2VsbCBvdXRsaW5lcy5cbiAqIFNoYXJlZCBieSB0aGUgT3BlblNlYWRyYWdvbiBhbmQgbmFwYXJpIG92ZXJsYXlzOiBib3RoIGhhbmQgaXQgdGhlaXIgc3ZnIGFuZCB0aGVpciB3b3JsZCDihpIgc3ZnXG4gKiBjYW1lcmEgYWZmaW5lLCBhcyB0aGV5IGRvIHRoZWlyIHtAbGluayBTdmdSZWdpb25SZW5kZXJlcn0uXG4gKlxuICogT25lIGA8cGF0aD5gIHBlciBjb2xvdXIgKGV2ZXJ5IHJpbmcgb2YgZXZlcnkgZmVhdHVyZSBvZiB0aGF0IGNvbG91ciwgZXZlbi1vZGQpLCBpbiB3b3JsZFxuICogY29vcmRpbmF0ZXMgaW5zaWRlIG9uZSB0cmFuc2Zvcm1lZCBncm91cCwgc28gYSBjYW1lcmEgbW92ZSByZXdyaXRlcyBvbmUgYXR0cmlidXRlLiBUaGUgdGlsZXMgaW5cbiAqIHZpZXcgYXJlIHJlLXBsYW5uZWQgb25jZSB0aGUgY2FtZXJhIHNldHRsZXM7IHdoaWxlIGEgZmluZXIgdGlsZSBsb2FkcyBpdHMgY29hcnNlciBwYXJlbnQgaXNcbiAqIGRyYXduIGluc3RlYWQsIHNvIHpvb21pbmcgaW4gc2hhcnBlbnMgdGhlIG91dGxpbmVzIHJhdGhlciB0aGFuIGJsYW5raW5nIHRoZW0uIEZlYXR1cmVzIHRha2VuXG4gKiBpbnRvIHRoZSB3b3JraW5nIHNldCAoc2VsZWN0ZWQsIGVkaXRlZCkgb3IgZGVsZXRlZCBhcmUgbm90IGRyYXduOiB0aGUgcmVnaW9uIHJlbmRlcmVyIGRyYXdzIHRoZVxuICogdGFrZW4gb25lcyBhcyBvcmRpbmFyeSByZWdpb25zLlxuICpcbiAqIEl0IGFsc28gYW5zd2VycyB3aGF0IGlzIHVuZGVyIGEgcG9pbnQsIGZyb20gdGhlIGZlYXR1cmVzIGRyYXduLCBmb3IgdGhlIG92ZXJsYXlzJyBzZWxlY3Rpb24uXG4gKi9cbmltcG9ydCB0eXBlIHsgT2JzZXJ2YWJsZSwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IFJlZ2lvblNvdXJjZVZpZXcsIGlzQWJvcnRFcnJvciB9IGZyb20gJy4uL3JlZ2lvbi1zb3VyY2UvcmVnaW9uLXNvdXJjZSc7XG5pbXBvcnQge1xuICBCYm94LFxuICBSZWdpb25UaWxlLFxuICBSZWdpb25UaWxlS2V5LFxuICBUaWxlRmVhdHVyZSxcbiAgZmVhdHVyZUF0LFxuICBmZWF0dXJlc0luUmVjdCxcbiAgcmVnaW9uTGV2ZWxGb3IsXG4gIHJlZ2lvblRpbGVJZCxcbiAgcmVnaW9uVGlsZXNJblJlY3QsXG59IGZyb20gJy4uL3JlZ2lvbi1zb3VyY2UvcmVnaW9uLXRpbGVzJztcbmltcG9ydCB7IEFmZmluZSwgSURFTlRJVFlfQUZGSU5FLCBTY3JlZW5MYXllciwgYXBwbHlBZmZpbmUsIHN2Z0VsIH0gZnJvbSAnLi9zdmctcmVnaW9uLXJlbmRlcmVyJztcbmltcG9ydCB7IGlzRmlsbGVkLCBwbGFjZUluc2lkZUxhYmVsLCBzaGFwZVBhaW50IH0gZnJvbSAnLi9yZWdpb24tc3R5bGUnO1xuXG4vKiogV2FpdCB0aGlzIGxvbmcgYWZ0ZXIgdGhlIGxhc3QgY2FtZXJhIGNoYW5nZSBiZWZvcmUgcGxhbm5pbmcgdGlsZXMgKG1zKS4gKi9cbmV4cG9ydCBjb25zdCBTT1VSQ0VfUkVQTEFOX01TID0gOTA7XG4vKiogVGhlIHZpZXcgaXMgcGFkZGVkIGJ5IHRoaXMgZnJhY3Rpb24gb24gZWFjaCBzaWRlLCBzbyBhIHNob3J0IHBhbiBmaW5kcyBpdHMgdGlsZXMgbG9hZGVkLiAqL1xuZXhwb3J0IGNvbnN0IFNPVVJDRV9WSUVXX01BUkdJTiA9IDAuMjU7XG4vKiogQXQgbW9zdCB0aGlzIG1hbnkgdGlsZXMgaW4gdmlldy4gKi9cbmV4cG9ydCBjb25zdCBTT1VSQ0VfTUFYX1RJTEVTID0gMjU2O1xuLyoqIEEgcnViYmVyIGJhbmQgdGFrZXMgYXQgbW9zdCB0aGlzIG1hbnkgc291cmNlIGZlYXR1cmVzIGludG8gdGhlIHdvcmtpbmcgc2V0LiAqL1xuZXhwb3J0IGNvbnN0IFNPVVJDRV9NQVJRVUVFX0xJTUlUID0gMjAwMDtcbi8qKiBMb2FkZWQgdGlsZXMga2VwdCBieSB0aGUgbGF5ZXIgZm9yIGRyYXdpbmcgKHRoZSBzb3VyY2UgY2FjaGVzIG1vcmUpLiAqL1xuY29uc3QgTEFZRVJfVElMRV9MSU1JVCA9IDUxMjtcbi8qKiBTdHJva2Ugd2lkdGggb2YgYSBzb3VyY2Ugb3V0bGluZSwgc2NyZWVuIHB4IChhbiB1bnNlbGVjdGVkIHJlZ2lvbidzKS4gKi9cbmNvbnN0IFNPVVJDRV9TVFJPS0VfUFggPSAyO1xuXG4vKiogVGhlIHN2ZyBzaXplIChsb2NhbCBweCksIGZvciB0aGUgcGFydCBvZiB0aGUgd29ybGQgaW4gdmlldy4gKi9cbmV4cG9ydCB0eXBlIFN2Z1NpemUgPSAoKSA9PiB7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH07XG5cbmV4cG9ydCBjbGFzcyBSZWdpb25Tb3VyY2VMYXllciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgZ3JvdXAgPSBzdmdFbCgnZycpO1xuICBwcml2YXRlIGNhbWVyYTogQWZmaW5lID0gSURFTlRJVFlfQUZGSU5FO1xuICAvKiogQ2xhc3MgbGFiZWxzIGluc2lkZSB0aGUgZmVhdHVyZXMsIGluIHNjcmVlbiBzcGFjZSBvdmVyIHRoZSBvdXRsaW5lcy4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBsYWJlbExheWVyID0gbmV3IFNjcmVlbkxheWVyKHN2Z0VsKCdnJyksICh4LCB5KSA9PiBhcHBseUFmZmluZSh0aGlzLmNhbWVyYSwgeCwgeSkpO1xuICAvKiogQ2xhc3MgbmFtZSDihpIgZGVwdGggaW4gdGhlIHNvdXJjZSdzIGNsYXNzIGhpZXJhcmNoeSAocGFyZW50cyBkcmF3IHVuZGVyIHRoZWlyIGNoaWxkcmVuKS4gKi9cbiAgcHJpdmF0ZSBkZXB0aE9mID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgLyoqIENsYXNzIG5hbWUg4oaSIGl0cyBwYXJlbnQgY2xhc3MgaW4gdGhlIHNvdXJjZSdzIGNsYXNzIGhpZXJhcmNoeS4gKi9cbiAgcHJpdmF0ZSBwYXJlbnRPZiA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG4gIHByaXZhdGUgdmlldzogUmVnaW9uU291cmNlVmlldyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHZpc2libGUgPSB0cnVlO1xuICBwcml2YXRlIHJlYWRvbmx5IHN1YjogU3Vic2NyaXB0aW9uO1xuICAvKiogTG9hZGVkIHRpbGVzIG9mIHRoZSBjdXJyZW50IHNvdXJjZSBhbmQgcGxhbmUsIGJ5IGlkLCBsZWFzdCByZWNlbnRseSB1c2VkIGZpcnN0LiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHRpbGVzID0gbmV3IE1hcDxzdHJpbmcsIFJlZ2lvblRpbGU+KCk7XG4gIC8qKiBUaGUgdGlsZXMgdGhlIHZpZXcgd2FudHMgbm93LiAqL1xuICBwcml2YXRlIHdhbnRlZDogUmVnaW9uVGlsZUtleVtdID0gW107XG4gIC8qKiBUaGUgZmVhdHVyZXMgZHJhd24sIGJ5IGlkIChlYWNoIGF0IHRoZSBmaW5lc3QgbGV2ZWwgbG9hZGVkKS4gKi9cbiAgcHJpdmF0ZSBkcmF3biA9IG5ldyBNYXA8c3RyaW5nLCBUaWxlRmVhdHVyZT4oKTtcbiAgcHJpdmF0ZSBsb2FkaW5nOiBBYm9ydENvbnRyb2xsZXIgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSByZXBsYW5UaW1lcjogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD4gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBkcmF3RnJhbWU6IG51bWJlciB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgc3ZnOiBTVkdTVkdFbGVtZW50LFxuICAgIHZpZXckOiBPYnNlcnZhYmxlPFJlZ2lvblNvdXJjZVZpZXcgfCBudWxsPixcbiAgICBwcml2YXRlIHJlYWRvbmx5IHNpemU6IFN2Z1NpemUgPSAoKSA9PiBzdmdTaXplKHN2ZyksXG4gICkge1xuICAgIHRoaXMuZ3JvdXAuc2V0QXR0cmlidXRlKCdkYXRhLWxheWVyJywgJ3JlZ2lvbi1zb3VyY2UnKTtcbiAgICB0aGlzLmdyb3VwLnNldEF0dHJpYnV0ZSgncG9pbnRlci1ldmVudHMnLCAnbm9uZScpO1xuICAgIHRoaXMubGFiZWxMYXllci5ncm91cC5zZXRBdHRyaWJ1dGUoJ2RhdGEtbGF5ZXInLCAncmVnaW9uLXNvdXJjZS1sYWJlbHMnKTtcbiAgICB0aGlzLnN1YiA9IHZpZXckLnN1YnNjcmliZSgodmlldykgPT4gdGhpcy5zZXRWaWV3KHZpZXcpKTtcbiAgfVxuXG4gIC8qKiBGb2xsb3cgdGhlIGNhbWVyYTogcmV3cml0ZSB0aGUgdHJhbnNmb3JtIG5vdywgcmUtcGxhbiB0aGUgdGlsZXMgb25jZSBpdCBzZXR0bGVzLiAqL1xuICBzZXRDYW1lcmEoYWZmaW5lOiBBZmZpbmUpOiB2b2lkIHtcbiAgICBpZiAoIWFmZmluZS5ldmVyeShOdW1iZXIuaXNGaW5pdGUpKSByZXR1cm47XG4gICAgaWYgKGFmZmluZS5ldmVyeSgodiwgaSkgPT4gdiA9PT0gdGhpcy5jYW1lcmFbaV0pKSByZXR1cm47XG4gICAgdGhpcy5jYW1lcmEgPSBhZmZpbmU7XG4gICAgdGhpcy5hcHBseUNhbWVyYSgpO1xuICAgIHRoaXMubGFiZWxMYXllci5yZXByb2plY3QoKTtcbiAgICBpZiAoIXRoaXMudmlldykgcmV0dXJuO1xuICAgIGlmICh0aGlzLnJlcGxhblRpbWVyKSBjbGVhclRpbWVvdXQodGhpcy5yZXBsYW5UaW1lcik7XG4gICAgdGhpcy5yZXBsYW5UaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5yZXBsYW5UaW1lciA9IG51bGw7XG4gICAgICB0aGlzLnJlcGxhbigpO1xuICAgIH0sIFNPVVJDRV9SRVBMQU5fTVMpO1xuICB9XG5cbiAgLyoqIFNob3cgb3IgaGlkZSB0aGUgc291cmNlIHdpdGggdGhlIHJlZ2lvbnMuICovXG4gIHNldFZpc2libGUodmlzaWJsZTogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmICh2aXNpYmxlID09PSB0aGlzLnZpc2libGUpIHJldHVybjtcbiAgICB0aGlzLnZpc2libGUgPSB2aXNpYmxlO1xuICAgIHRoaXMuYXR0YWNoKCk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHNvdXJjZSBmZWF0dXJlIHVuZGVyIHdvcmxkIHBvaW50ICh4LCB5KSDigJQgaW5zaWRlIGFuIGFyZWEsIG9yIHdpdGhpbiBgdG9sZXJhbmNlUHhgXG4gICAqIHNjcmVlbiBwaXhlbHMgb2YgYSBwb2x5bGluZSDigJQgZnJvbSB0aGUgZmVhdHVyZXMgZHJhd247IHRoZSBpbm5lcm1vc3Qgb2YgbmVzdGVkIG9uZXMuXG4gICAqL1xuICBmZWF0dXJlQXQoeDogbnVtYmVyLCB5OiBudW1iZXIsIHRvbGVyYW5jZVB4ID0gNCk6IFRpbGVGZWF0dXJlIHwgbnVsbCB7XG4gICAgaWYgKCF0aGlzLnZpZXcgfHwgIXRoaXMudmlzaWJsZSkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIGZlYXR1cmVBdCh0aGlzLmRyYXduLnZhbHVlcygpLCB4LCB5LCB0b2xlcmFuY2VQeCAvIHRoaXMuc2NhbGUoKSk7XG4gIH1cblxuICAvKiogVGhlIGRyYXduIHNvdXJjZSBmZWF0dXJlcyB3aG9zZSBib3ggbWVldHMgdGhlIHdvcmxkIGJveCAodGhlIHJ1YmJlciBiYW5kJ3MgcnVsZSkuICovXG4gIGZlYXR1cmVzSW5SZWN0KHgwOiBudW1iZXIsIHkwOiBudW1iZXIsIHgxOiBudW1iZXIsIHkxOiBudW1iZXIpOiBUaWxlRmVhdHVyZVtdIHtcbiAgICBpZiAoIXRoaXMudmlldyB8fCAhdGhpcy52aXNpYmxlKSByZXR1cm4gW107XG4gICAgcmV0dXJuIGZlYXR1cmVzSW5SZWN0KHRoaXMuZHJhd24udmFsdWVzKCksIFt4MCwgeTAsIHgxLCB5MV0pO1xuICB9XG5cbiAgZGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLnN1Yi51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMubG9hZGluZz8uYWJvcnQoKTtcbiAgICBpZiAodGhpcy5yZXBsYW5UaW1lcikgY2xlYXJUaW1lb3V0KHRoaXMucmVwbGFuVGltZXIpO1xuICAgIGlmICh0aGlzLmRyYXdGcmFtZSAhPT0gbnVsbCkgY2FuY2VsRnJhbWUodGhpcy5kcmF3RnJhbWUpO1xuICAgIHRoaXMuZ3JvdXAucGFyZW50Tm9kZT8ucmVtb3ZlQ2hpbGQodGhpcy5ncm91cCk7XG4gICAgdGhpcy5sYWJlbExheWVyLmdyb3VwLnBhcmVudE5vZGU/LnJlbW92ZUNoaWxkKHRoaXMubGFiZWxMYXllci5ncm91cCk7XG4gIH1cblxuICBwcml2YXRlIHNldFZpZXcodmlldzogUmVnaW9uU291cmNlVmlldyB8IG51bGwpOiB2b2lkIHtcbiAgICBjb25zdCBwcmV2ID0gdGhpcy52aWV3O1xuICAgIHRoaXMudmlldyA9IHZpZXc7XG4gICAgaWYgKCF2aWV3IHx8IHByZXY/LnNvdXJjZSAhPT0gdmlldy5zb3VyY2UgfHwgcHJldi5wbGFuZSAhPT0gdmlldy5wbGFuZSkge1xuICAgICAgdGhpcy50aWxlcy5jbGVhcigpO1xuICAgICAgdGhpcy5sb2FkaW5nPy5hYm9ydCgpO1xuICAgICAgdGhpcy5sb2FkaW5nID0gbnVsbDtcbiAgICB9XG4gICAgaWYgKHZpZXcgJiYgcHJldj8uc291cmNlICE9PSB2aWV3LnNvdXJjZSkge1xuICAgICAgY29uc3QgaGllcmFyY2h5ID0gdmlldy5zb3VyY2UuaW5mby5oaWVyYXJjaHkgPz8gW107XG4gICAgICB0aGlzLmRlcHRoT2YgPSBoaWVyYXJjaHlEZXB0aHMoaGllcmFyY2h5KTtcbiAgICAgIHRoaXMucGFyZW50T2YgPSBuZXcgTWFwKGhpZXJhcmNoeS5maWx0ZXIoKG4pID0+IG4ucGFyZW50KS5tYXAoKG4pID0+IFtuLm5hbWUsIG4ucGFyZW50IGFzIHN0cmluZ10pKTtcbiAgICB9XG4gICAgdGhpcy5hdHRhY2goKTtcbiAgICBpZiAodmlldykgdGhpcy5yZXBsYW4oKTtcbiAgICBlbHNlIHRoaXMuZHJhdygpO1xuICB9XG5cbiAgLyoqIFRoZSBsYXllciBpcyB0aGUgc3ZnJ3MgZmlyc3QgY2hpbGQgKHVuZGVyIHRoZSByZWdpb25zKSB3aGlsZSBpdCBzaG93cyBhIHNvdXJjZS4gKi9cbiAgcHJpdmF0ZSBhdHRhY2goKTogdm9pZCB7XG4gICAgY29uc3Qgc2hvdyA9ICEhdGhpcy52aWV3ICYmIHRoaXMudmlzaWJsZTtcbiAgICBjb25zdCBsYWJlbHMgPSB0aGlzLmxhYmVsTGF5ZXIuZ3JvdXA7XG4gICAgaWYgKCFzaG93KSB7XG4gICAgICB0aGlzLmdyb3VwLnBhcmVudE5vZGU/LnJlbW92ZUNoaWxkKHRoaXMuZ3JvdXApO1xuICAgICAgbGFiZWxzLnBhcmVudE5vZGU/LnJlbW92ZUNoaWxkKGxhYmVscyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLnN2Zy5maXJzdENoaWxkICE9PSB0aGlzLmdyb3VwKSB0aGlzLnN2Zy5pbnNlcnRCZWZvcmUodGhpcy5ncm91cCwgdGhpcy5zdmcuZmlyc3RDaGlsZCk7XG4gICAgaWYgKHRoaXMuZ3JvdXAubmV4dFNpYmxpbmcgIT09IGxhYmVscykgdGhpcy5zdmcuaW5zZXJ0QmVmb3JlKGxhYmVscywgdGhpcy5ncm91cC5uZXh0U2libGluZyk7XG4gIH1cblxuICBwcml2YXRlIGFwcGx5Q2FtZXJhKCk6IHZvaWQge1xuICAgIHRoaXMuZ3JvdXAuc2V0QXR0cmlidXRlKCd0cmFuc2Zvcm0nLCBgbWF0cml4KCR7dGhpcy5jYW1lcmEuam9pbignICcpfSlgKTtcbiAgfVxuXG4gIC8qKiBTY3JlZW4gcHggcGVyIHdvcmxkIHVuaXQuICovXG4gIHByaXZhdGUgc2NhbGUoKTogbnVtYmVyIHtcbiAgICBjb25zdCBbYSwgYiwgYywgZF0gPSB0aGlzLmNhbWVyYTtcbiAgICByZXR1cm4gTWF0aC5zcXJ0KE1hdGguYWJzKGEgKiBkIC0gYiAqIGMpKSB8fCAxO1xuICB9XG5cbiAgLyoqIFRoZSB3b3JsZCBib3ggaW4gdmlldywgcGFkZGVkIGJ5IHRoZSBtYXJnaW47IG51bGwgd2hlbiB0aGUgc3ZnIGhhcyBubyBzaXplIHlldC4gKi9cbiAgcHJpdmF0ZSB2aWV3UmVjdCgpOiBCYm94IHwgbnVsbCB7XG4gICAgY29uc3QgeyB3aWR0aCwgaGVpZ2h0IH0gPSB0aGlzLnNpemUoKTtcbiAgICBpZiAoISh3aWR0aCA+IDApIHx8ICEoaGVpZ2h0ID4gMCkpIHJldHVybiBudWxsO1xuICAgIGNvbnN0IFthLCBiLCBjLCBkLCBlLCBmXSA9IHRoaXMuY2FtZXJhO1xuICAgIGNvbnN0IGRldCA9IGEgKiBkIC0gYiAqIGM7XG4gICAgaWYgKCFkZXQpIHJldHVybiBudWxsO1xuICAgIGNvbnN0IHRvV29ybGQgPSAoc3g6IG51bWJlciwgc3k6IG51bWJlcik6IFtudW1iZXIsIG51bWJlcl0gPT4ge1xuICAgICAgY29uc3QgeCA9IHN4IC0gZSxcbiAgICAgICAgeSA9IHN5IC0gZjtcbiAgICAgIHJldHVybiBbKGQgKiB4IC0gYyAqIHkpIC8gZGV0LCAoYSAqIHkgLSBiICogeCkgLyBkZXRdO1xuICAgIH07XG4gICAgY29uc3QgbXggPSB3aWR0aCAqIFNPVVJDRV9WSUVXX01BUkdJTixcbiAgICAgIG15ID0gaGVpZ2h0ICogU09VUkNFX1ZJRVdfTUFSR0lOO1xuICAgIGNvbnN0IGNvcm5lcnMgPSBbXG4gICAgICB0b1dvcmxkKC1teCwgLW15KSxcbiAgICAgIHRvV29ybGQod2lkdGggKyBteCwgLW15KSxcbiAgICAgIHRvV29ybGQoLW14LCBoZWlnaHQgKyBteSksXG4gICAgICB0b1dvcmxkKHdpZHRoICsgbXgsIGhlaWdodCArIG15KSxcbiAgICBdO1xuICAgIGNvbnN0IHhzID0gY29ybmVycy5tYXAoKHApID0+IHBbMF0pLFxuICAgICAgeXMgPSBjb3JuZXJzLm1hcCgocCkgPT4gcFsxXSk7XG4gICAgcmV0dXJuIFtNYXRoLm1pbiguLi54cyksIE1hdGgubWluKC4uLnlzKSwgTWF0aC5tYXgoLi4ueHMpLCBNYXRoLm1heCguLi55cyldO1xuICB9XG5cbiAgLyoqIFdvcmsgb3V0IHRoZSB0aWxlcyB0aGUgdmlldyBuZWVkcywgZHJhdyB3aGF0IGlzIGxvYWRlZCwgYW5kIGxvYWQgdGhlIHJlc3QuICovXG4gIHByaXZhdGUgcmVwbGFuKCk6IHZvaWQge1xuICAgIGNvbnN0IHZpZXcgPSB0aGlzLnZpZXc7XG4gICAgaWYgKCF2aWV3KSByZXR1cm47XG4gICAgY29uc3QgcmVjdCA9IHRoaXMudmlld1JlY3QoKTtcbiAgICBpZiAoIXJlY3QpIHtcbiAgICAgIHRoaXMud2FudGVkID0gW107XG4gICAgICB0aGlzLmRyYXcoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaW5mbyA9IHZpZXcuc291cmNlLmluZm87XG4gICAgY29uc3QgbGV2ZWwgPSByZWdpb25MZXZlbEZvcih0aGlzLnNjYWxlKCksIGluZm8ubGV2ZWxzKTtcbiAgICB0aGlzLndhbnRlZCA9IHJlZ2lvblRpbGVzSW5SZWN0KHJlY3QsIGxldmVsLCBpbmZvLnRpbGVTaXplLCBpbmZvLmJvdW5kcywgU09VUkNFX01BWF9USUxFUyk7XG4gICAgdGhpcy5zY2hlZHVsZURyYXcoKTtcbiAgICBjb25zdCBtaXNzaW5nID0gdGhpcy53YW50ZWQuZmlsdGVyKChrKSA9PiAhdGhpcy50aWxlcy5oYXMocmVnaW9uVGlsZUlkKGspKSk7XG4gICAgdGhpcy5sb2FkaW5nPy5hYm9ydCgpO1xuICAgIHRoaXMubG9hZGluZyA9IG51bGw7XG4gICAgaWYgKCFtaXNzaW5nLmxlbmd0aCkgcmV0dXJuO1xuICAgIGNvbnN0IGxvYWRpbmcgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgdGhpcy5sb2FkaW5nID0gbG9hZGluZztcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBtaXNzaW5nKSB7XG4gICAgICB2aWV3LnNvdXJjZS5nZXRUaWxlKHZpZXcucGxhbmUsIGtleSwgbG9hZGluZy5zaWduYWwpLnRoZW4oXG4gICAgICAgICh0aWxlKSA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMudmlldz8uc291cmNlICE9PSB2aWV3LnNvdXJjZSB8fCB0aGlzLnZpZXcucGxhbmUgIT09IHZpZXcucGxhbmUpIHJldHVybjtcbiAgICAgICAgICB0aGlzLmtlZXAodGlsZSk7XG4gICAgICAgICAgdGhpcy5zY2hlZHVsZURyYXcoKTtcbiAgICAgICAgfSxcbiAgICAgICAgKGVycikgPT4ge1xuICAgICAgICAgIGlmICghaXNBYm9ydEVycm9yKGVycikpIGNvbnNvbGUud2FybignW3JlZ2lvbnNdIHJlZ2lvbiB0aWxlIGZhaWxlZCcsIGVycik7XG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUga2VlcCh0aWxlOiBSZWdpb25UaWxlKTogdm9pZCB7XG4gICAgY29uc3QgaWQgPSByZWdpb25UaWxlSWQodGlsZSk7XG4gICAgdGhpcy50aWxlcy5kZWxldGUoaWQpO1xuICAgIHRoaXMudGlsZXMuc2V0KGlkLCB0aWxlKTtcbiAgICB3aGlsZSAodGhpcy50aWxlcy5zaXplID4gTEFZRVJfVElMRV9MSU1JVCkgdGhpcy50aWxlcy5kZWxldGUodGhpcy50aWxlcy5rZXlzKCkubmV4dCgpLnZhbHVlIGFzIHN0cmluZyk7XG4gIH1cblxuICBwcml2YXRlIHNjaGVkdWxlRHJhdygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kcmF3RnJhbWUgIT09IG51bGwpIHJldHVybjtcbiAgICB0aGlzLmRyYXdGcmFtZSA9IHJlcXVlc3RGcmFtZSgoKSA9PiB7XG4gICAgICB0aGlzLmRyYXdGcmFtZSA9IG51bGw7XG4gICAgICB0aGlzLmRyYXcoKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWJ1aWxkIHRoZSBwYXRocyBmcm9tIHRoZSB3YW50ZWQgdGlsZXMgdGhhdCBhcmUgbG9hZGVkLCBhIG1pc3NpbmcgdGlsZSdzIG5lYXJlc3QgbG9hZGVkXG4gICAqIGFuY2VzdG9yIHN0YW5kaW5nIGluIGZvciBpdDsgZWFjaCBmZWF0dXJlIG9uY2UsIGF0IHRoZSBmaW5lc3QgbGV2ZWwgbG9hZGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBkcmF3KCk6IHZvaWQge1xuICAgIGNvbnN0IHZpZXcgPSB0aGlzLnZpZXc7XG4gICAgY29uc3QgZHJhd24gPSBuZXcgTWFwPHN0cmluZywgVGlsZUZlYXR1cmU+KCk7XG4gICAgY29uc3QgbGV2ZWwgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuICAgIGlmICh2aWV3KSB7XG4gICAgICBjb25zdCB1c2VkID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgICBmb3IgKGNvbnN0IGtleSBvZiB0aGlzLndhbnRlZCkge1xuICAgICAgICBjb25zdCB0aWxlID0gdGhpcy5sb2FkZWRPckFuY2VzdG9yKGtleSk7XG4gICAgICAgIGlmICghdGlsZSB8fCB1c2VkLmhhcyhyZWdpb25UaWxlSWQodGlsZSkpKSBjb250aW51ZTtcbiAgICAgICAgdXNlZC5hZGQocmVnaW9uVGlsZUlkKHRpbGUpKTtcbiAgICAgICAgZm9yIChjb25zdCBmIG9mIHRpbGUuZmVhdHVyZXMpIHtcbiAgICAgICAgICBpZiAodmlldy50YWtlbi5oYXMoZi5pZCkgfHwgdmlldy5pc0hpZGRlbj8uKGYubGFiZWwpKSBjb250aW51ZTtcbiAgICAgICAgICBjb25zdCBoYWQgPSBsZXZlbC5nZXQoZi5pZCk7XG4gICAgICAgICAgaWYgKGhhZCAhPT0gdW5kZWZpbmVkICYmIGhhZCA8PSB0aWxlLmxldmVsKSBjb250aW51ZTtcbiAgICAgICAgICBkcmF3bi5zZXQoZi5pZCwgZik7XG4gICAgICAgICAgbGV2ZWwuc2V0KGYuaWQsIHRpbGUubGV2ZWwpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuZHJhd24gPSBkcmF3bjtcbiAgICBjb25zdCBmaWxsZWQgPSAhIXZpZXcgJiYgaXNGaWxsZWQodmlldy5zdHlsZSk7XG4gICAgY29uc3QgZnJhZyA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcbiAgICBmb3IgKGNvbnN0IHJ1biBvZiB0aGlzLnJ1bnMoZHJhd24sIGZpbGxlZCkpIHtcbiAgICAgIGNvbnN0IHBhdGggPSBzdmdFbCgncGF0aCcpO1xuICAgICAgcGF0aC5zZXRBdHRyaWJ1dGUoJ2QnLCBydW4uZmVhdHVyZXMuZmxhdE1hcCgoZikgPT4gZi5yaW5ncy5tYXAoKHIpID0+IHJpbmdEKHIsICFmLm9wZW4pKSkuam9pbignJykpO1xuICAgICAgcGF0aC5zZXRBdHRyaWJ1dGUoJ2ZpbGwtcnVsZScsICdldmVub2RkJyk7XG4gICAgICBwYXRoLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLWxpbmVqb2luJywgJ3JvdW5kJyk7XG4gICAgICBwYXRoLnNldEF0dHJpYnV0ZSgndmVjdG9yLWVmZmVjdCcsICdub24tc2NhbGluZy1zdHJva2UnKTtcbiAgICAgIGlmIChmaWxsZWQgJiYgdmlldykge1xuICAgICAgICBjb25zdCBwYWludCA9IHNoYXBlUGFpbnQocnVuLmNvbG9yLCBmYWxzZSwgdmlldy5zdHlsZSk7XG4gICAgICAgIHBhdGguc2V0QXR0cmlidXRlKCdmaWxsJywgcGFpbnQuZmlsbCk7XG4gICAgICAgIHBhdGguc2V0QXR0cmlidXRlKCdmaWxsLW9wYWNpdHknLCBgJHtwYWludC5maWxsT3BhY2l0eX1gKTtcbiAgICAgICAgcGF0aC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHBhaW50LnN0cm9rZSk7XG4gICAgICAgIHBhdGguc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCBgJHtwYWludC5zdHJva2VXaWR0aH1gKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBhdGguc2V0QXR0cmlidXRlKCdmaWxsJywgJ25vbmUnKTtcbiAgICAgICAgcGF0aC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHJ1bi5jb2xvcik7XG4gICAgICAgIHBhdGguc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCBgJHtTT1VSQ0VfU1RST0tFX1BYfWApO1xuICAgICAgfVxuICAgICAgZnJhZy5hcHBlbmRDaGlsZChwYXRoKTtcbiAgICB9XG4gICAgd2hpbGUgKHRoaXMuZ3JvdXAuZmlyc3RDaGlsZCkgdGhpcy5ncm91cC5yZW1vdmVDaGlsZCh0aGlzLmdyb3VwLmZpcnN0Q2hpbGQpO1xuICAgIHRoaXMuZ3JvdXAuYXBwZW5kQ2hpbGQoZnJhZyk7XG4gICAgdGhpcy5hcHBseUNhbWVyYSgpO1xuICAgIHRoaXMuZHJhd0xhYmVscyhmaWxsZWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBkcmF3biBmZWF0dXJlcyBhcyBwYXRoczogb25lIHBlciBjb2xvdXIgd2hlbiBvdXRsaW5lZDsgZmlsbGVkLCBpbiBwYWludCBvcmRlciDigJQgcGFyZW50c1xuICAgKiAoYnkgdGhlIGNsYXNzIGhpZXJhcmNoeSkgYW5kIHRoZW4gbGFyZ2VyIGZlYXR1cmVzIGZpcnN0LCBzbyB3aGF0IGxpZXMgaW5zaWRlIHBhaW50cyBvdmVyXG4gICAqIHRoZW0g4oCUIG9uZSBwYXRoIHBlciBydW4gb2YgYSBjb2xvdXIuXG4gICAqL1xuICBwcml2YXRlIHJ1bnMoXG4gICAgZHJhd246IE1hcDxzdHJpbmcsIFRpbGVGZWF0dXJlPixcbiAgICBmaWxsZWQ6IGJvb2xlYW4sXG4gICk6IEFycmF5PHsgY29sb3I6IHN0cmluZzsgZmVhdHVyZXM6IFRpbGVGZWF0dXJlW10gfT4ge1xuICAgIGNvbnN0IHZpZXcgPSB0aGlzLnZpZXc7XG4gICAgY29uc3QgY29sb3JPZiA9IChmOiBUaWxlRmVhdHVyZSkgPT4gdmlldz8uY29sb3JPZihmKSA/PyAnIzAwRkZGRic7XG4gICAgaWYgKCFmaWxsZWQpIHtcbiAgICAgIGNvbnN0IGJ5Q29sb3IgPSBuZXcgTWFwPHN0cmluZywgVGlsZUZlYXR1cmVbXT4oKTtcbiAgICAgIGZvciAoY29uc3QgZiBvZiBkcmF3bi52YWx1ZXMoKSkge1xuICAgICAgICBjb25zdCBjb2xvciA9IGNvbG9yT2YoZik7XG4gICAgICAgIGNvbnN0IGxpc3QgPSBieUNvbG9yLmdldChjb2xvcik7XG4gICAgICAgIGlmIChsaXN0KSBsaXN0LnB1c2goZik7XG4gICAgICAgIGVsc2UgYnlDb2xvci5zZXQoY29sb3IsIFtmXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gQXJyYXkuZnJvbShieUNvbG9yLCAoW2NvbG9yLCBmZWF0dXJlc10pID0+ICh7IGNvbG9yLCBmZWF0dXJlcyB9KSk7XG4gICAgfVxuICAgIGNvbnN0IGFyZWEgPSAoZjogVGlsZUZlYXR1cmUpID0+IChmLmJib3hbMl0gLSBmLmJib3hbMF0pICogKGYuYmJveFszXSAtIGYuYmJveFsxXSk7XG4gICAgY29uc3QgZGVwdGggPSAoZjogVGlsZUZlYXR1cmUpID0+IHRoaXMuZGVwdGhPZi5nZXQoZi5sYWJlbCA/PyAnJykgPz8gMDtcbiAgICBjb25zdCBvcmRlciA9IEFycmF5LmZyb20oZHJhd24udmFsdWVzKCkpLnNvcnQoKGEsIGIpID0+IGRlcHRoKGEpIC0gZGVwdGgoYikgfHwgYXJlYShiKSAtIGFyZWEoYSkpO1xuICAgIGNvbnN0IHJ1bnM6IEFycmF5PHsgY29sb3I6IHN0cmluZzsgZmVhdHVyZXM6IFRpbGVGZWF0dXJlW10gfT4gPSBbXTtcbiAgICBmb3IgKGNvbnN0IGYgb2Ygb3JkZXIpIHtcbiAgICAgIGNvbnN0IGNvbG9yID0gY29sb3JPZihmKTtcbiAgICAgIGNvbnN0IGxhc3QgPSBydW5zW3J1bnMubGVuZ3RoIC0gMV07XG4gICAgICBpZiAobGFzdCAmJiBsYXN0LmNvbG9yID09PSBjb2xvcikgbGFzdC5mZWF0dXJlcy5wdXNoKGYpO1xuICAgICAgZWxzZSBydW5zLnB1c2goeyBjb2xvciwgZmVhdHVyZXM6IFtmXSB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHJ1bnM7XG4gIH1cblxuICAvKiogQ2xhc3MgbGFiZWxzIGluc2lkZSB0aGUgZHJhd24gZmVhdHVyZXMgKGVhY2ggcGFydCB3aGVyZSBpdCBmaXRzKSwgd2hlbiBsYWJlbHMgYXJlIG9uLiAqL1xuICBwcml2YXRlIGRyYXdMYWJlbHMoZmlsbGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5sYWJlbExheWVyLmNsZWFyKCk7XG4gICAgY29uc3QgdmlldyA9IHRoaXMudmlldztcbiAgICBpZiAoIXZpZXc/LmxhYmVscykgcmV0dXJuO1xuICAgIC8vIE9ubHkgdGhlIGRlZXBlc3QgY2xhc3NlcyBkcmF3biBhcmUgbGFiZWxsZWQ6IGEgY2xhc3Mgd2hvc2Ugc3ViY2xhc3NlcyBhcmUgZHJhd24gdG9vIChhblxuICAgIC8vIGF0bGFzJ3MgXCJJc29jb3J0ZXhcIiB1bmRlciBpdHMgYXJlYXMpIHdvdWxkIG9ubHkgcmVwZWF0IG92ZXIgdGhlbS5cbiAgICBjb25zdCBjb3ZlcmVkID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgZm9yIChjb25zdCBmIG9mIHRoaXMuZHJhd24udmFsdWVzKCkpIHtcbiAgICAgIGxldCBwID0gZi5sYWJlbCA/IHRoaXMucGFyZW50T2YuZ2V0KGYubGFiZWwpIDogdW5kZWZpbmVkO1xuICAgICAgd2hpbGUgKHAgJiYgIWNvdmVyZWQuaGFzKHApKSB7XG4gICAgICAgIGNvdmVyZWQuYWRkKHApO1xuICAgICAgICBwID0gdGhpcy5wYXJlbnRPZi5nZXQocCk7XG4gICAgICB9XG4gICAgfVxuICAgIGZvciAoY29uc3QgZiBvZiB0aGlzLmRyYXduLnZhbHVlcygpKSB7XG4gICAgICBjb25zdCBhdCA9IGYubGFiZWxzO1xuICAgICAgaWYgKCFhdCB8fCAhZi5sYWJlbCB8fCBjb3ZlcmVkLmhhcyhmLmxhYmVsKSkgY29udGludWU7XG4gICAgICBjb25zdCBjb2xvciA9IGZpbGxlZCA/ICcjMTExJyA6IHZpZXcuY29sb3JPZihmKTtcbiAgICAgIGZvciAobGV0IGsgPSAwOyBrICsgMiA8IGF0Lmxlbmd0aDsgayArPSAzKSB7XG4gICAgICAgIHBsYWNlSW5zaWRlTGFiZWwodGhpcy5sYWJlbExheWVyLCBmLmxhYmVsLCB7IHg6IGF0W2tdLCB5OiBhdFtrICsgMV0sIHJvb206IGF0W2sgKyAyXSB9LCBjb2xvcik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqIFRoZSBsb2FkZWQgdGlsZSBmb3IgYGtleWAsIGVsc2UgaXRzIG5lYXJlc3QgbG9hZGVkIGNvYXJzZXIgYW5jZXN0b3IuICovXG4gIHByaXZhdGUgbG9hZGVkT3JBbmNlc3RvcihrZXk6IFJlZ2lvblRpbGVLZXkpOiBSZWdpb25UaWxlIHwgbnVsbCB7XG4gICAgY29uc3QgbGV2ZWxzID0gdGhpcy52aWV3Py5zb3VyY2UuaW5mby5sZXZlbHMgPz8gMDtcbiAgICBsZXQgeyBneCwgZ3kgfSA9IGtleTtcbiAgICBmb3IgKGxldCBsZXZlbCA9IGtleS5sZXZlbDsgbGV2ZWwgPCBsZXZlbHM7IGxldmVsKyspIHtcbiAgICAgIGNvbnN0IHRpbGUgPSB0aGlzLnRpbGVzLmdldChyZWdpb25UaWxlSWQoeyBsZXZlbCwgZ3gsIGd5IH0pKTtcbiAgICAgIGlmICh0aWxlKSByZXR1cm4gdGlsZTtcbiAgICAgIGd4ID0gTWF0aC5mbG9vcihneCAvIDIpO1xuICAgICAgZ3kgPSBNYXRoLmZsb29yKGd5IC8gMik7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbi8qKiBQYXRoIGRhdGEgb2Ygb25lIHJpbmcgKGBjbG9zZWRgKSBvciBwb2x5bGluZSwgaW4gd29ybGQgdW5pdHMgdG8gMS8xMDAuICovXG5mdW5jdGlvbiByaW5nRChyaW5nOiBGbG9hdDMyQXJyYXksIGNsb3NlZDogYm9vbGVhbik6IHN0cmluZyB7XG4gIGNvbnN0IG4gPSByaW5nLmxlbmd0aCA+PiAxO1xuICBpZiAobiA8IDIpIHJldHVybiAnJztcbiAgbGV0IGQgPSBgTSR7cjIocmluZ1swXSl9ICR7cjIocmluZ1sxXSl9YDtcbiAgZm9yIChsZXQgaSA9IDE7IGkgPCBuOyBpKyspIGQgKz0gYEwke3IyKHJpbmdbMiAqIGldKX0gJHtyMihyaW5nWzIgKiBpICsgMV0pfWA7XG4gIHJldHVybiBjbG9zZWQgPyBgJHtkfVpgIDogZDtcbn1cblxuZnVuY3Rpb24gcjIodjogbnVtYmVyKTogbnVtYmVyIHtcbiAgcmV0dXJuIE1hdGgucm91bmQodiAqIDEwMCkgLyAxMDA7XG59XG5cbmZ1bmN0aW9uIHN2Z1NpemUoc3ZnOiBTVkdTVkdFbGVtZW50KTogeyB3aWR0aDogbnVtYmVyOyBoZWlnaHQ6IG51bWJlciB9IHtcbiAgY29uc3Qgd2lkdGggPSBzdmcuY2xpZW50V2lkdGggfHwgc3ZnLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLndpZHRoO1xuICBjb25zdCBoZWlnaHQgPSBzdmcuY2xpZW50SGVpZ2h0IHx8IHN2Zy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5oZWlnaHQ7XG4gIHJldHVybiB7IHdpZHRoLCBoZWlnaHQgfTtcbn1cblxuY29uc3QgcmVxdWVzdEZyYW1lID0gKGZuOiAoKSA9PiB2b2lkKTogbnVtYmVyID0+XG4gIHR5cGVvZiByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPT09ICdmdW5jdGlvbidcbiAgICA/IHJlcXVlc3RBbmltYXRpb25GcmFtZShmbilcbiAgICA6IChzZXRUaW1lb3V0KGZuLCAxNikgYXMgdW5rbm93biBhcyBudW1iZXIpO1xuXG5jb25zdCBjYW5jZWxGcmFtZSA9IChpZDogbnVtYmVyKTogdm9pZCA9PlxuICB0eXBlb2YgY2FuY2VsQW5pbWF0aW9uRnJhbWUgPT09ICdmdW5jdGlvbicgPyBjYW5jZWxBbmltYXRpb25GcmFtZShpZCkgOiBjbGVhclRpbWVvdXQoaWQpO1xuXG4vKiogRGVwdGggb2YgZWFjaCBjbGFzcyBpbiBhIGNsYXNzIGhpZXJhcmNoeSAoYSByb290IGlzIDApOyBlbXB0eSB3aXRob3V0IG9uZS4gKi9cbmZ1bmN0aW9uIGhpZXJhcmNoeURlcHRocyhcbiAgaGllcmFyY2h5OiBSZWFkb25seUFycmF5PHsgbmFtZTogc3RyaW5nOyBwYXJlbnQ/OiBzdHJpbmcgfCBudWxsIH0+IHwgdW5kZWZpbmVkLFxuKTogTWFwPHN0cmluZywgbnVtYmVyPiB7XG4gIGNvbnN0IGRlcHRocyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gIGlmICghaGllcmFyY2h5KSByZXR1cm4gZGVwdGhzO1xuICBjb25zdCBwYXJlbnQgPSBuZXcgTWFwKGhpZXJhcmNoeS5tYXAoKG4pID0+IFtuLm5hbWUsIG4ucGFyZW50ID8/IG51bGxdKSk7XG4gIGZvciAoY29uc3QgbiBvZiBoaWVyYXJjaHkpIHtcbiAgICBsZXQgZCA9IDA7XG4gICAgbGV0IHAgPSBwYXJlbnQuZ2V0KG4ubmFtZSk7XG4gICAgY29uc3Qgc2VlbiA9IG5ldyBTZXQ8c3RyaW5nPihbbi5uYW1lXSk7XG4gICAgd2hpbGUgKHAgJiYgIXNlZW4uaGFzKHApKSB7XG4gICAgICBzZWVuLmFkZChwKTtcbiAgICAgIGQrKztcbiAgICAgIHAgPSBwYXJlbnQuZ2V0KHApID8/IG51bGw7XG4gICAgfVxuICAgIGRlcHRocy5zZXQobi5uYW1lLCBkKTtcbiAgfVxuICByZXR1cm4gZGVwdGhzO1xufVxuIl19
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How regions are drawn, shared by the OpenSeadragon and napari overlays and the region-source
|
|
3
|
+
* layer, so a feature looks the same before and after it is taken into the regions.
|
|
4
|
+
*
|
|
5
|
+
* Two looks: **outlines** (the default — each region stroked in its colour, filled only while
|
|
6
|
+
* selected) and **filled**, an atlas's look (each region filled in its colour, with thin outlines,
|
|
7
|
+
* the selection in a highlight colour, labels centred inside each part).
|
|
8
|
+
*/
|
|
9
|
+
import { MultiPolygon, Polygon, Rectangle } from '../models/region';
|
|
10
|
+
import { polylabel } from '../geometry/polylabel';
|
|
11
|
+
import { svgEl } from './svg-region-renderer';
|
|
12
|
+
export const DEFAULT_REGION_STYLE = {
|
|
13
|
+
fillOpacity: 0,
|
|
14
|
+
stroke: null,
|
|
15
|
+
strokeWidth: null,
|
|
16
|
+
highlight: null,
|
|
17
|
+
};
|
|
18
|
+
/** A selected region's fill in the filled look, unless the style names one (the Allen atlas's). */
|
|
19
|
+
export const DEFAULT_HIGHLIGHT = '#a020f0';
|
|
20
|
+
/** Whether `style` is the filled look. */
|
|
21
|
+
export function isFilled(style) {
|
|
22
|
+
return style.fillOpacity > 0;
|
|
23
|
+
}
|
|
24
|
+
/** The paint of a region of colour `color`, selected or not, in `style`. */
|
|
25
|
+
export function shapePaint(color, selected, style = DEFAULT_REGION_STYLE) {
|
|
26
|
+
if (!isFilled(style)) {
|
|
27
|
+
return selected
|
|
28
|
+
? { fill: color, fillOpacity: 0.35, stroke: color, strokeWidth: 4 }
|
|
29
|
+
: { fill: 'none', fillOpacity: 0, stroke: color, strokeWidth: 2 };
|
|
30
|
+
}
|
|
31
|
+
const width = style.strokeWidth ?? 1;
|
|
32
|
+
return selected
|
|
33
|
+
? {
|
|
34
|
+
fill: style.highlight ?? DEFAULT_HIGHLIGHT,
|
|
35
|
+
fillOpacity: Math.max(style.fillOpacity, 0.85),
|
|
36
|
+
stroke: style.stroke ?? color,
|
|
37
|
+
strokeWidth: width + 1,
|
|
38
|
+
}
|
|
39
|
+
: { fill: color, fillOpacity: style.fillOpacity, stroke: style.stroke ?? color, strokeWidth: width };
|
|
40
|
+
}
|
|
41
|
+
/** Set `paint` on an SVG shape. */
|
|
42
|
+
export function applyPaint(el, paint) {
|
|
43
|
+
el.setAttribute('fill', paint.fill);
|
|
44
|
+
el.setAttribute('fill-opacity', `${paint.fillOpacity}`);
|
|
45
|
+
el.setAttribute('stroke', paint.stroke);
|
|
46
|
+
el.setAttribute('stroke-width', `${paint.strokeWidth}`);
|
|
47
|
+
}
|
|
48
|
+
/** Where to label `region`: each part's pole of inaccessibility (a rectangle's centre). */
|
|
49
|
+
export function regionLabelSpots(region) {
|
|
50
|
+
const b = region.bounds;
|
|
51
|
+
if (b instanceof Rectangle) {
|
|
52
|
+
const room = Math.min(Math.abs(b.width), Math.abs(b.height)) / 2;
|
|
53
|
+
return [{ x: b.x + b.width / 2, y: b.y + b.height / 2, room }];
|
|
54
|
+
}
|
|
55
|
+
const parts = b instanceof MultiPolygon ? b.polygons : b instanceof Polygon && b.closed !== false ? [b] : [];
|
|
56
|
+
const spots = [];
|
|
57
|
+
for (const p of parts) {
|
|
58
|
+
const rings = [Float64Array.from(p.xpoints.flatMap((x, i) => [x, p.ypoints[i]]))];
|
|
59
|
+
for (const hole of p.holes ?? [])
|
|
60
|
+
rings.push(Float64Array.from(hole.flat()));
|
|
61
|
+
const pole = polylabel(rings);
|
|
62
|
+
if (pole && pole.distance > 0)
|
|
63
|
+
spots.push({ x: pole.x, y: pole.y, room: pole.distance });
|
|
64
|
+
}
|
|
65
|
+
return spots;
|
|
66
|
+
}
|
|
67
|
+
/** Font size of a centred label, px. */
|
|
68
|
+
const INSIDE_LABEL_PX = 10;
|
|
69
|
+
/**
|
|
70
|
+
* A class label centred at `spot`, shown only while it fits: the room around the spot, on screen,
|
|
71
|
+
* at least half the text's width (and a few pixels). Re-checked on every camera move.
|
|
72
|
+
*/
|
|
73
|
+
export function placeInsideLabel(layer, text, spot, color = '#111') {
|
|
74
|
+
const el = svgEl('text');
|
|
75
|
+
el.setAttribute('fill', color);
|
|
76
|
+
el.setAttribute('font-size', `${INSIDE_LABEL_PX}`);
|
|
77
|
+
el.setAttribute('font-family', 'sans-serif');
|
|
78
|
+
el.setAttribute('text-anchor', 'middle');
|
|
79
|
+
el.setAttribute('dominant-baseline', 'central');
|
|
80
|
+
el.setAttribute('pointer-events', 'none');
|
|
81
|
+
el.textContent = text;
|
|
82
|
+
const halfWidth = (text.length * INSIDE_LABEL_PX * 0.6) / 2;
|
|
83
|
+
return layer.place(el, (e, project) => {
|
|
84
|
+
const [sx, sy] = project(spot.x, spot.y);
|
|
85
|
+
e.setAttribute('x', `${sx}`);
|
|
86
|
+
e.setAttribute('y', `${sy}`);
|
|
87
|
+
e.style.display = labelFits(project, spot, halfWidth) ? '' : 'none';
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
/** Whether a label `halfWidth` px wide fits around `spot` through `project`. */
|
|
91
|
+
export function labelFits(project, spot, halfWidth) {
|
|
92
|
+
const [ax, ay] = project(spot.x, spot.y);
|
|
93
|
+
const [bx, by] = project(spot.x + spot.room, spot.y);
|
|
94
|
+
const roomPx = Math.hypot(bx - ax, by - ay);
|
|
95
|
+
return roomPx >= Math.max(halfWidth * 0.8, INSIDE_LABEL_PX * 0.6);
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaW9uLXN0eWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9yZWdpb24tb3ZlcmxheS9yZWdpb24tc3R5bGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7R0FPRztBQUNILE9BQU8sRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBVSxNQUFNLGtCQUFrQixDQUFDO0FBQzVFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUVsRCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFjOUMsTUFBTSxDQUFDLE1BQU0sb0JBQW9CLEdBQWdCO0lBQy9DLFdBQVcsRUFBRSxDQUFDO0lBQ2QsTUFBTSxFQUFFLElBQUk7SUFDWixXQUFXLEVBQUUsSUFBSTtJQUNqQixTQUFTLEVBQUUsSUFBSTtDQUNoQixDQUFDO0FBRUYsbUdBQW1HO0FBQ25HLE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLFNBQVMsQ0FBQztBQUUzQywwQ0FBMEM7QUFDMUMsTUFBTSxVQUFVLFFBQVEsQ0FBQyxLQUFrQjtJQUN6QyxPQUFPLEtBQUssQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDO0FBQy9CLENBQUM7QUFVRCw0RUFBNEU7QUFDNUUsTUFBTSxVQUFVLFVBQVUsQ0FDeEIsS0FBYSxFQUNiLFFBQWlCLEVBQ2pCLFFBQXFCLG9CQUFvQjtJQUV6QyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDckIsT0FBTyxRQUFRO1lBQ2IsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLENBQUMsRUFBRTtZQUNuRSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDdEUsQ0FBQztJQUNELE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxXQUFXLElBQUksQ0FBQyxDQUFDO0lBQ3JDLE9BQU8sUUFBUTtRQUNiLENBQUMsQ0FBQztZQUNFLElBQUksRUFBRSxLQUFLLENBQUMsU0FBUyxJQUFJLGlCQUFpQjtZQUMxQyxXQUFXLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQztZQUM5QyxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU0sSUFBSSxLQUFLO1lBQzdCLFdBQVcsRUFBRSxLQUFLLEdBQUcsQ0FBQztTQUN2QjtRQUNILENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLEtBQUssQ0FBQyxXQUFXLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNLElBQUksS0FBSyxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsQ0FBQztBQUN6RyxDQUFDO0FBRUQsbUNBQW1DO0FBQ25DLE1BQU0sVUFBVSxVQUFVLENBQUMsRUFBYyxFQUFFLEtBQWlCO0lBQzFELEVBQUUsQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNwQyxFQUFFLENBQUMsWUFBWSxDQUFDLGNBQWMsRUFBRSxHQUFHLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBQ3hELEVBQUUsQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN4QyxFQUFFLENBQUMsWUFBWSxDQUFDLGNBQWMsRUFBRSxHQUFHLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO0FBQzFELENBQUM7QUFTRCwyRkFBMkY7QUFDM0YsTUFBTSxVQUFVLGdCQUFnQixDQUFDLE1BQWM7SUFDN0MsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUN4QixJQUFJLENBQUMsWUFBWSxTQUFTLEVBQUUsQ0FBQztRQUMzQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2pFLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDakUsQ0FBQztJQUNELE1BQU0sS0FBSyxHQUFHLENBQUMsWUFBWSxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxPQUFPLElBQUksQ0FBQyxDQUFDLE1BQU0sS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUM3RyxNQUFNLEtBQUssR0FBZ0IsRUFBRSxDQUFDO0lBQzlCLEtBQUssTUFBTSxDQUFDLElBQUksS0FBSyxFQUFFLENBQUM7UUFDdEIsTUFBTSxLQUFLLEdBQW1CLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsRyxLQUFLLE1BQU0sSUFBSSxJQUFJLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRTtZQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzdFLE1BQU0sSUFBSSxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM5QixJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsUUFBUSxHQUFHLENBQUM7WUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO0lBQzNGLENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRCx3Q0FBd0M7QUFDeEMsTUFBTSxlQUFlLEdBQUcsRUFBRSxDQUFDO0FBRTNCOzs7R0FHRztBQUNILE1BQU0sVUFBVSxnQkFBZ0IsQ0FDOUIsS0FBa0IsRUFDbEIsSUFBWSxFQUNaLElBQWUsRUFDZixLQUFLLEdBQUcsTUFBTTtJQUVkLE1BQU0sRUFBRSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN6QixFQUFFLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQztJQUMvQixFQUFFLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxHQUFHLGVBQWUsRUFBRSxDQUFDLENBQUM7SUFDbkQsRUFBRSxDQUFDLFlBQVksQ0FBQyxhQUFhLEVBQUUsWUFBWSxDQUFDLENBQUM7SUFDN0MsRUFBRSxDQUFDLFlBQVksQ0FBQyxhQUFhLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDekMsRUFBRSxDQUFDLFlBQVksQ0FBQyxtQkFBbUIsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUNoRCxFQUFFLENBQUMsWUFBWSxDQUFDLGdCQUFnQixFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQzFDLEVBQUUsQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO0lBQ3RCLE1BQU0sU0FBUyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxlQUFlLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzVELE9BQU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLEVBQUU7UUFDcEMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzdCLENBQUMsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUM3QixDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDdEUsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQsZ0ZBQWdGO0FBQ2hGLE1BQU0sVUFBVSxTQUFTLENBQUMsT0FBZ0IsRUFBRSxJQUFlLEVBQUUsU0FBaUI7SUFDNUUsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDekMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNyRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0lBQzVDLE9BQU8sTUFBTSxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxHQUFHLEdBQUcsRUFBRSxlQUFlLEdBQUcsR0FBRyxDQUFDLENBQUM7QUFDcEUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogSG93IHJlZ2lvbnMgYXJlIGRyYXduLCBzaGFyZWQgYnkgdGhlIE9wZW5TZWFkcmFnb24gYW5kIG5hcGFyaSBvdmVybGF5cyBhbmQgdGhlIHJlZ2lvbi1zb3VyY2VcbiAqIGxheWVyLCBzbyBhIGZlYXR1cmUgbG9va3MgdGhlIHNhbWUgYmVmb3JlIGFuZCBhZnRlciBpdCBpcyB0YWtlbiBpbnRvIHRoZSByZWdpb25zLlxuICpcbiAqIFR3byBsb29rczogKipvdXRsaW5lcyoqICh0aGUgZGVmYXVsdCDigJQgZWFjaCByZWdpb24gc3Ryb2tlZCBpbiBpdHMgY29sb3VyLCBmaWxsZWQgb25seSB3aGlsZVxuICogc2VsZWN0ZWQpIGFuZCAqKmZpbGxlZCoqLCBhbiBhdGxhcydzIGxvb2sgKGVhY2ggcmVnaW9uIGZpbGxlZCBpbiBpdHMgY29sb3VyLCB3aXRoIHRoaW4gb3V0bGluZXMsXG4gKiB0aGUgc2VsZWN0aW9uIGluIGEgaGlnaGxpZ2h0IGNvbG91ciwgbGFiZWxzIGNlbnRyZWQgaW5zaWRlIGVhY2ggcGFydCkuXG4gKi9cbmltcG9ydCB7IE11bHRpUG9seWdvbiwgUG9seWdvbiwgUmVjdGFuZ2xlLCBSZWdpb24gfSBmcm9tICcuLi9tb2RlbHMvcmVnaW9uJztcbmltcG9ydCB7IHBvbHlsYWJlbCB9IGZyb20gJy4uL2dlb21ldHJ5L3BvbHlsYWJlbCc7XG5pbXBvcnQgdHlwZSB7IFByb2plY3QsIFNjcmVlbkxheWVyIH0gZnJvbSAnLi9zdmctcmVnaW9uLXJlbmRlcmVyJztcbmltcG9ydCB7IHN2Z0VsIH0gZnJvbSAnLi9zdmctcmVnaW9uLXJlbmRlcmVyJztcblxuLyoqIFRoZSByZWdpb24gbG9vayAoc2VlIHRoZSBtb2R1bGUgZG9jKS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVnaW9uU3R5bGUge1xuICAvKiogRmlsbCBlYWNoIHJlZ2lvbiBhdCB0aGlzIG9wYWNpdHk7IDAgZHJhd3Mgb3V0bGluZXMgb25seS4gKi9cbiAgZmlsbE9wYWNpdHk6IG51bWJlcjtcbiAgLyoqIE91dGxpbmUgY29sb3VyIG9mIGEgZmlsbGVkIHJlZ2lvbjsgbnVsbDogaXRzIG93biBjb2xvdXIuICovXG4gIHN0cm9rZTogc3RyaW5nIHwgbnVsbDtcbiAgLyoqIE91dGxpbmUgd2lkdGggb2YgYSBmaWxsZWQgcmVnaW9uLCBzY3JlZW4gcHg7IG51bGw6IDEuICovXG4gIHN0cm9rZVdpZHRoOiBudW1iZXIgfCBudWxsO1xuICAvKiogRmlsbCBjb2xvdXIgb2YgYSBzZWxlY3RlZCBmaWxsZWQgcmVnaW9uOyBudWxsOiB7QGxpbmsgREVGQVVMVF9ISUdITElHSFR9LiAqL1xuICBoaWdobGlnaHQ6IHN0cmluZyB8IG51bGw7XG59XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX1JFR0lPTl9TVFlMRTogUmVnaW9uU3R5bGUgPSB7XG4gIGZpbGxPcGFjaXR5OiAwLFxuICBzdHJva2U6IG51bGwsXG4gIHN0cm9rZVdpZHRoOiBudWxsLFxuICBoaWdobGlnaHQ6IG51bGwsXG59O1xuXG4vKiogQSBzZWxlY3RlZCByZWdpb24ncyBmaWxsIGluIHRoZSBmaWxsZWQgbG9vaywgdW5sZXNzIHRoZSBzdHlsZSBuYW1lcyBvbmUgKHRoZSBBbGxlbiBhdGxhcydzKS4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX0hJR0hMSUdIVCA9ICcjYTAyMGYwJztcblxuLyoqIFdoZXRoZXIgYHN0eWxlYCBpcyB0aGUgZmlsbGVkIGxvb2suICovXG5leHBvcnQgZnVuY3Rpb24gaXNGaWxsZWQoc3R5bGU6IFJlZ2lvblN0eWxlKTogYm9vbGVhbiB7XG4gIHJldHVybiBzdHlsZS5maWxsT3BhY2l0eSA+IDA7XG59XG5cbi8qKiBUaGUgcGFpbnQgb2Ygb25lIHJlZ2lvbiBzaGFwZS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2hhcGVQYWludCB7XG4gIGZpbGw6IHN0cmluZztcbiAgZmlsbE9wYWNpdHk6IG51bWJlcjtcbiAgc3Ryb2tlOiBzdHJpbmc7XG4gIHN0cm9rZVdpZHRoOiBudW1iZXI7XG59XG5cbi8qKiBUaGUgcGFpbnQgb2YgYSByZWdpb24gb2YgY29sb3VyIGBjb2xvcmAsIHNlbGVjdGVkIG9yIG5vdCwgaW4gYHN0eWxlYC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzaGFwZVBhaW50KFxuICBjb2xvcjogc3RyaW5nLFxuICBzZWxlY3RlZDogYm9vbGVhbixcbiAgc3R5bGU6IFJlZ2lvblN0eWxlID0gREVGQVVMVF9SRUdJT05fU1RZTEUsXG4pOiBTaGFwZVBhaW50IHtcbiAgaWYgKCFpc0ZpbGxlZChzdHlsZSkpIHtcbiAgICByZXR1cm4gc2VsZWN0ZWRcbiAgICAgID8geyBmaWxsOiBjb2xvciwgZmlsbE9wYWNpdHk6IDAuMzUsIHN0cm9rZTogY29sb3IsIHN0cm9rZVdpZHRoOiA0IH1cbiAgICAgIDogeyBmaWxsOiAnbm9uZScsIGZpbGxPcGFjaXR5OiAwLCBzdHJva2U6IGNvbG9yLCBzdHJva2VXaWR0aDogMiB9O1xuICB9XG4gIGNvbnN0IHdpZHRoID0gc3R5bGUuc3Ryb2tlV2lkdGggPz8gMTtcbiAgcmV0dXJuIHNlbGVjdGVkXG4gICAgPyB7XG4gICAgICAgIGZpbGw6IHN0eWxlLmhpZ2hsaWdodCA/PyBERUZBVUxUX0hJR0hMSUdIVCxcbiAgICAgICAgZmlsbE9wYWNpdHk6IE1hdGgubWF4KHN0eWxlLmZpbGxPcGFjaXR5LCAwLjg1KSxcbiAgICAgICAgc3Ryb2tlOiBzdHlsZS5zdHJva2UgPz8gY29sb3IsXG4gICAgICAgIHN0cm9rZVdpZHRoOiB3aWR0aCArIDEsXG4gICAgICB9XG4gICAgOiB7IGZpbGw6IGNvbG9yLCBmaWxsT3BhY2l0eTogc3R5bGUuZmlsbE9wYWNpdHksIHN0cm9rZTogc3R5bGUuc3Ryb2tlID8/IGNvbG9yLCBzdHJva2VXaWR0aDogd2lkdGggfTtcbn1cblxuLyoqIFNldCBgcGFpbnRgIG9uIGFuIFNWRyBzaGFwZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcHBseVBhaW50KGVsOiBTVkdFbGVtZW50LCBwYWludDogU2hhcGVQYWludCk6IHZvaWQge1xuICBlbC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCBwYWludC5maWxsKTtcbiAgZWwuc2V0QXR0cmlidXRlKCdmaWxsLW9wYWNpdHknLCBgJHtwYWludC5maWxsT3BhY2l0eX1gKTtcbiAgZWwuc2V0QXR0cmlidXRlKCdzdHJva2UnLCBwYWludC5zdHJva2UpO1xuICBlbC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZS13aWR0aCcsIGAke3BhaW50LnN0cm9rZVdpZHRofWApO1xufVxuXG4vKiogQSBwb2ludCB0byBsYWJlbCBhIHBhcnQgYXQsIGFuZCB0aGUgcm9vbSBhcm91bmQgaXQgKGltYWdlIHB4KS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTGFiZWxTcG90IHtcbiAgeDogbnVtYmVyO1xuICB5OiBudW1iZXI7XG4gIHJvb206IG51bWJlcjtcbn1cblxuLyoqIFdoZXJlIHRvIGxhYmVsIGByZWdpb25gOiBlYWNoIHBhcnQncyBwb2xlIG9mIGluYWNjZXNzaWJpbGl0eSAoYSByZWN0YW5nbGUncyBjZW50cmUpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lvbkxhYmVsU3BvdHMocmVnaW9uOiBSZWdpb24pOiBMYWJlbFNwb3RbXSB7XG4gIGNvbnN0IGIgPSByZWdpb24uYm91bmRzO1xuICBpZiAoYiBpbnN0YW5jZW9mIFJlY3RhbmdsZSkge1xuICAgIGNvbnN0IHJvb20gPSBNYXRoLm1pbihNYXRoLmFicyhiLndpZHRoKSwgTWF0aC5hYnMoYi5oZWlnaHQpKSAvIDI7XG4gICAgcmV0dXJuIFt7IHg6IGIueCArIGIud2lkdGggLyAyLCB5OiBiLnkgKyBiLmhlaWdodCAvIDIsIHJvb20gfV07XG4gIH1cbiAgY29uc3QgcGFydHMgPSBiIGluc3RhbmNlb2YgTXVsdGlQb2x5Z29uID8gYi5wb2x5Z29ucyA6IGIgaW5zdGFuY2VvZiBQb2x5Z29uICYmIGIuY2xvc2VkICE9PSBmYWxzZSA/IFtiXSA6IFtdO1xuICBjb25zdCBzcG90czogTGFiZWxTcG90W10gPSBbXTtcbiAgZm9yIChjb25zdCBwIG9mIHBhcnRzKSB7XG4gICAgY29uc3QgcmluZ3M6IEZsb2F0NjRBcnJheVtdID0gW0Zsb2F0NjRBcnJheS5mcm9tKHAueHBvaW50cy5mbGF0TWFwKCh4LCBpKSA9PiBbeCwgcC55cG9pbnRzW2ldXSkpXTtcbiAgICBmb3IgKGNvbnN0IGhvbGUgb2YgcC5ob2xlcyA/PyBbXSkgcmluZ3MucHVzaChGbG9hdDY0QXJyYXkuZnJvbShob2xlLmZsYXQoKSkpO1xuICAgIGNvbnN0IHBvbGUgPSBwb2x5bGFiZWwocmluZ3MpO1xuICAgIGlmIChwb2xlICYmIHBvbGUuZGlzdGFuY2UgPiAwKSBzcG90cy5wdXNoKHsgeDogcG9sZS54LCB5OiBwb2xlLnksIHJvb206IHBvbGUuZGlzdGFuY2UgfSk7XG4gIH1cbiAgcmV0dXJuIHNwb3RzO1xufVxuXG4vKiogRm9udCBzaXplIG9mIGEgY2VudHJlZCBsYWJlbCwgcHguICovXG5jb25zdCBJTlNJREVfTEFCRUxfUFggPSAxMDtcblxuLyoqXG4gKiBBIGNsYXNzIGxhYmVsIGNlbnRyZWQgYXQgYHNwb3RgLCBzaG93biBvbmx5IHdoaWxlIGl0IGZpdHM6IHRoZSByb29tIGFyb3VuZCB0aGUgc3BvdCwgb24gc2NyZWVuLFxuICogYXQgbGVhc3QgaGFsZiB0aGUgdGV4dCdzIHdpZHRoIChhbmQgYSBmZXcgcGl4ZWxzKS4gUmUtY2hlY2tlZCBvbiBldmVyeSBjYW1lcmEgbW92ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBsYWNlSW5zaWRlTGFiZWwoXG4gIGxheWVyOiBTY3JlZW5MYXllcixcbiAgdGV4dDogc3RyaW5nLFxuICBzcG90OiBMYWJlbFNwb3QsXG4gIGNvbG9yID0gJyMxMTEnLFxuKTogU1ZHVGV4dEVsZW1lbnQge1xuICBjb25zdCBlbCA9IHN2Z0VsKCd0ZXh0Jyk7XG4gIGVsLnNldEF0dHJpYnV0ZSgnZmlsbCcsIGNvbG9yKTtcbiAgZWwuc2V0QXR0cmlidXRlKCdmb250LXNpemUnLCBgJHtJTlNJREVfTEFCRUxfUFh9YCk7XG4gIGVsLnNldEF0dHJpYnV0ZSgnZm9udC1mYW1pbHknLCAnc2Fucy1zZXJpZicpO1xuICBlbC5zZXRBdHRyaWJ1dGUoJ3RleHQtYW5jaG9yJywgJ21pZGRsZScpO1xuICBlbC5zZXRBdHRyaWJ1dGUoJ2RvbWluYW50LWJhc2VsaW5lJywgJ2NlbnRyYWwnKTtcbiAgZWwuc2V0QXR0cmlidXRlKCdwb2ludGVyLWV2ZW50cycsICdub25lJyk7XG4gIGVsLnRleHRDb250ZW50ID0gdGV4dDtcbiAgY29uc3QgaGFsZldpZHRoID0gKHRleHQubGVuZ3RoICogSU5TSURFX0xBQkVMX1BYICogMC42KSAvIDI7XG4gIHJldHVybiBsYXllci5wbGFjZShlbCwgKGUsIHByb2plY3QpID0+IHtcbiAgICBjb25zdCBbc3gsIHN5XSA9IHByb2plY3Qoc3BvdC54LCBzcG90LnkpO1xuICAgIGUuc2V0QXR0cmlidXRlKCd4JywgYCR7c3h9YCk7XG4gICAgZS5zZXRBdHRyaWJ1dGUoJ3knLCBgJHtzeX1gKTtcbiAgICBlLnN0eWxlLmRpc3BsYXkgPSBsYWJlbEZpdHMocHJvamVjdCwgc3BvdCwgaGFsZldpZHRoKSA/ICcnIDogJ25vbmUnO1xuICB9KTtcbn1cblxuLyoqIFdoZXRoZXIgYSBsYWJlbCBgaGFsZldpZHRoYCBweCB3aWRlIGZpdHMgYXJvdW5kIGBzcG90YCB0aHJvdWdoIGBwcm9qZWN0YC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsYWJlbEZpdHMocHJvamVjdDogUHJvamVjdCwgc3BvdDogTGFiZWxTcG90LCBoYWxmV2lkdGg6IG51bWJlcik6IGJvb2xlYW4ge1xuICBjb25zdCBbYXgsIGF5XSA9IHByb2plY3Qoc3BvdC54LCBzcG90LnkpO1xuICBjb25zdCBbYngsIGJ5XSA9IHByb2plY3Qoc3BvdC54ICsgc3BvdC5yb29tLCBzcG90LnkpO1xuICBjb25zdCByb29tUHggPSBNYXRoLmh5cG90KGJ4IC0gYXgsIGJ5IC0gYXkpO1xuICByZXR1cm4gcm9vbVB4ID49IE1hdGgubWF4KGhhbGZXaWR0aCAqIDAuOCwgSU5TSURFX0xBQkVMX1BYICogMC42KTtcbn1cbiJdfQ==
|