@jax-data-science/sci-image-visualizer 0.8.3 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +201 -460
- package/esm2022/index.mjs +28 -15
- package/esm2022/lib/channel-histogram/channel-histogram.component.mjs +163 -91
- package/esm2022/lib/contracts/capabilities.contract.mjs +4 -3
- package/esm2022/lib/contracts/cell-segmenter.contract.mjs +1 -1
- package/esm2022/lib/contracts/channel-histogram-api.contract.mjs +5 -1
- package/esm2022/lib/contracts/color.mjs +60 -0
- package/esm2022/lib/contracts/colormap-lut.mjs +213 -57
- package/esm2022/lib/contracts/coordinate-transform.contract.mjs +1 -1
- package/esm2022/lib/contracts/display-types.mjs +11 -1
- package/esm2022/lib/contracts/instance-segmenter.contract.mjs +1 -1
- package/esm2022/lib/contracts/intensity.mjs +48 -5
- package/esm2022/lib/contracts/plot-type-contribution.contract.mjs +1 -1
- package/esm2022/lib/contracts/plot-type.mjs +134 -17
- package/esm2022/lib/contracts/ports/image-state.port.mjs +4 -1
- package/esm2022/lib/contracts/ports/preferences.port.mjs +5 -1
- package/esm2022/lib/contracts/ports/region-io.port.mjs +2 -1
- package/esm2022/lib/contracts/ports/spatial-data.port.mjs +5 -1
- package/esm2022/lib/contracts/ports/tile-access.port.mjs +2 -1
- package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
- package/esm2022/lib/contracts/region-overlay.contract.mjs +1 -1
- package/esm2022/lib/contracts/sam.contract.mjs +1 -1
- package/esm2022/lib/contracts/semantic-segmenter.contract.mjs +1 -1
- package/esm2022/lib/contracts/spatial-dataset.contract.mjs +3 -1
- package/esm2022/lib/contracts/toolbar-tool.contract.mjs +6 -4
- package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
- package/esm2022/lib/contracts/viz-config.mjs +2 -1
- package/esm2022/lib/geometry/contour.mjs +63 -0
- package/esm2022/lib/geometry/raster.mjs +98 -0
- package/esm2022/lib/geometry/ring.mjs +201 -0
- package/esm2022/lib/hex-color-picker/hex-color-picker.component.mjs +202 -102
- package/esm2022/lib/implementations/base-store-visualizer.mjs +201 -48
- package/esm2022/lib/implementations/napari-js/napari-axes-gizmo.mjs +65 -0
- package/esm2022/lib/implementations/napari-js/napari-display-state.mjs +136 -0
- package/esm2022/lib/implementations/napari-js/napari-helpers.mjs +199 -0
- package/esm2022/lib/implementations/napari-js/napari-image-2d-scene.mjs +602 -0
- package/esm2022/lib/implementations/napari-js/napari-loading-badge.mjs +3 -4
- package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +66 -0
- package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +157 -591
- package/esm2022/lib/implementations/napari-js/napari-scene.mjs +2 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-2d-scene.mjs +614 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +769 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-encoding.mjs +199 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +263 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-scene.mjs +159 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-tiles.mjs +106 -1408
- package/esm2022/lib/implementations/napari-js/napari-spatial-tooltip.mjs +2 -2
- package/esm2022/lib/implementations/napari-js/napari-surface-scene.mjs +271 -0
- package/esm2022/lib/implementations/napari-js/napari-tile-client.mjs +562 -0
- package/esm2022/lib/implementations/napari-js/napari-tool-bridge.mjs +344 -0
- package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +358 -4218
- package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +439 -0
- package/esm2022/lib/implementations/napari-js/napari-volume-z-handle.mjs +6 -6
- package/esm2022/lib/implementations/napari-js/region-overlay/overlay-projection.mjs +96 -0
- package/esm2022/lib/implementations/napari-js/region-overlay/region-edit.mjs +35 -0
- package/esm2022/lib/implementations/napari-js/region-overlay/region-svg-renderer.mjs +182 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/categorical-lookup.mjs +30 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/cell-layers.mjs +274 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/density-layer.mjs +144 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/layer-groups.mjs +165 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/plan-context.mjs +78 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-hover.mjs +182 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-jobs.mjs +369 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-layers.mjs +306 -0
- package/esm2022/lib/implementations/osd/display-pipeline.mjs +102 -40
- package/esm2022/lib/implementations/osd/histogram-sampler.mjs +56 -31
- package/esm2022/lib/implementations/osd/openseadragon-viewer-options.mjs +128 -0
- package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +333 -1685
- package/esm2022/lib/implementations/osd/osd-coordinate-transform.mjs +1 -1
- package/esm2022/lib/implementations/osd/osd-coords.mjs +5 -6
- package/esm2022/lib/implementations/osd/osd-export.mjs +122 -0
- package/esm2022/lib/implementations/osd/osd-lib.mjs +15 -1
- package/esm2022/lib/implementations/osd/osd-navigator-chrome.mjs +205 -0
- package/esm2022/lib/implementations/osd/osd-pixel-readback.mjs +68 -0
- package/esm2022/lib/implementations/osd/osd-region-overlay-draw.mjs +153 -0
- package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +185 -718
- package/esm2022/lib/implementations/osd/osd-scale-bar.mjs +52 -60
- package/esm2022/lib/implementations/osd/osd-tile-source.mjs +105 -0
- package/esm2022/lib/implementations/osd/osd-viewer-like.mjs +2 -0
- package/esm2022/lib/implementations/osd/osd-viewer-mount.mjs +44 -0
- package/esm2022/lib/implementations/osd/osd-viewport.mjs +184 -0
- package/esm2022/lib/implementations/osd/osd-zoom.mjs +7 -1
- package/esm2022/lib/implementations/osd/simple-source.mjs +395 -0
- package/esm2022/lib/implementations/osd/slice-cache.mjs +53 -48
- package/esm2022/lib/implementations/osd/tile-client.mjs +32 -11
- package/esm2022/lib/implementations/osd/tile-recolor.mjs +330 -0
- package/esm2022/lib/implementations/plotly/omics-trace-builders.mjs +161 -73
- package/esm2022/lib/implementations/plotly/plotly-coordinate-transform.mjs +1 -1
- package/esm2022/lib/implementations/plotly/plotly-image-loader.mjs +112 -0
- package/esm2022/lib/implementations/plotly/plotly-image-recolor.mjs +178 -0
- package/esm2022/lib/implementations/plotly/plotly-intensity-inset.mjs +33 -0
- package/esm2022/lib/implementations/plotly/plotly-isosurface-controls.mjs +83 -0
- package/esm2022/lib/implementations/plotly/plotly-layouts.mjs +121 -0
- package/esm2022/lib/implementations/plotly/plotly-readback.mjs +117 -0
- package/esm2022/lib/implementations/plotly/plotly-region-overlay.mjs +19 -10
- package/esm2022/lib/implementations/plotly/plotly-shape-projection.mjs +223 -0
- package/esm2022/lib/implementations/plotly/plotly-trace-builders.mjs +79 -19
- package/esm2022/lib/implementations/plotly/plotly-zoom-controller.mjs +223 -0
- package/esm2022/lib/implementations/plotly/plotly.service.mjs +439 -1655
- package/esm2022/lib/implementations/region-centroids.mjs +47 -0
- package/esm2022/lib/implementations/simple-slice-access.service.mjs +22 -12
- package/esm2022/lib/implementations/spatial-data-http/spatial-data-http.service.mjs +172 -92
- package/esm2022/lib/implementations/spatial-data-http/spatial-wire.mjs +103 -22
- package/esm2022/lib/implementations/tile-server/index.mjs +6 -0
- package/esm2022/lib/implementations/tile-server/native-histogram.mjs +30 -0
- package/esm2022/lib/implementations/tile-server/poll-descriptor.mjs +65 -0
- package/esm2022/lib/implementations/tile-server/tile-protocol.mjs +42 -0
- package/esm2022/lib/implementations/tile-server/transport.mjs +135 -0
- package/esm2022/lib/intensity/intensity-profile.mjs +107 -0
- package/esm2022/lib/intensity/intensity-profile.service.mjs +223 -0
- package/esm2022/lib/intensity-inset/intensity-inset.component.mjs +133 -0
- package/esm2022/lib/models/bezier.mjs +1 -11
- package/esm2022/lib/models/class-preset.mjs +41 -3
- package/esm2022/lib/models/geometry.mjs +27 -164
- package/esm2022/lib/models/polygon-edit.mjs +254 -0
- package/esm2022/lib/models/polygon-factory.mjs +118 -0
- package/esm2022/lib/models/region-clone.mjs +68 -0
- package/esm2022/lib/models/region-geojson.mjs +373 -0
- package/esm2022/lib/models/region.mjs +34 -33
- package/esm2022/lib/models/shape.mjs +18 -16
- package/esm2022/lib/plot-mode/contribution-host.mjs +297 -0
- package/esm2022/lib/plot-mode/plot-mode-controller.mjs +9 -6
- package/esm2022/lib/plot-mode/plot-type-menu.mjs +85 -0
- package/esm2022/lib/plot-mode/tool-params-model.mjs +87 -0
- package/esm2022/lib/plot.utilities.mjs +296 -473
- package/esm2022/lib/processing/image-crop.mjs +1 -1
- package/esm2022/lib/processing/processing-image.mjs +28 -15
- package/esm2022/lib/provide-visualization.mjs +40 -14
- package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +99 -0
- package/esm2022/lib/region-editor/file-stem.mjs +13 -0
- package/esm2022/lib/region-editor/manage-classes-dialog/manage-classes-dialog.component.mjs +118 -0
- package/esm2022/lib/region-editor/mask-export.service.mjs +98 -0
- package/esm2022/lib/region-editor/mask-raster.mjs +11 -5
- package/esm2022/lib/region-editor/region-color-dialog/region-color-dialog.component.mjs +56 -0
- package/esm2022/lib/region-editor/region-editor-help/region-editor-help.component.mjs +28 -0
- package/esm2022/lib/region-editor/region-editor.component.mjs +402 -651
- package/esm2022/lib/region-editor/region-metrics.mjs +68 -0
- package/esm2022/lib/region-editor/region-persistence.service.mjs +134 -0
- package/esm2022/lib/region-editor/region-table/region-table.component.mjs +153 -0
- package/esm2022/lib/region-editor/save-mask-dialog/save-mask-dialog.component.mjs +91 -0
- package/esm2022/lib/region-editor/save-regions-dialog/save-regions-dialog.component.mjs +92 -0
- package/esm2022/lib/region-ops.service.mjs +28 -70
- package/esm2022/lib/region-overlay/region-geometry.mjs +360 -0
- package/esm2022/lib/region-overlay/region-hit-test.mjs +103 -0
- package/esm2022/lib/region-overlay/svg-region-renderer.mjs +228 -0
- package/esm2022/lib/render-orchestrator.mjs +14 -11
- package/esm2022/lib/render-session.mjs +207 -0
- package/esm2022/lib/routing-visualizer.service.mjs +459 -411
- package/esm2022/lib/spatial/density-raster.mjs +14 -0
- package/esm2022/lib/spatial/embedding-compute-coordinator.mjs +239 -0
- package/esm2022/lib/spatial/embedding-compute.mjs +43 -10
- package/esm2022/lib/spatial/gene-search.mjs +1 -1
- package/esm2022/lib/spatial/glyphs.mjs +97 -0
- package/esm2022/lib/spatial/lod.mjs +187 -0
- package/esm2022/lib/spatial/spatial-controls.facade.mjs +200 -0
- package/esm2022/lib/spatial/spatial-density.mjs +25 -16
- package/esm2022/lib/spatial/spatial-encoding.mjs +26 -82
- package/esm2022/lib/spatial/spatial-expression.mjs +43 -42
- package/esm2022/lib/spatial/spatial-framing.mjs +1 -1
- package/esm2022/lib/spatial/spatial-heatmap.mjs +6 -3
- package/esm2022/lib/spatial/spatial-hover.mjs +5 -33
- package/esm2022/lib/spatial/spatial-panel-model.mjs +282 -0
- package/esm2022/lib/spatial/spatial-sections.mjs +1 -1
- package/esm2022/lib/spatial/spatial-selection.mjs +33 -46
- package/esm2022/lib/spatial/spatial-tile-merge.mjs +219 -0
- package/esm2022/lib/spatial/spatial-tiles.mjs +12 -648
- package/esm2022/lib/spatial/spatial-volume-image.mjs +2 -4
- package/esm2022/lib/spatial/stats.mjs +71 -0
- package/esm2022/lib/spatial/transcript-grouping.mjs +307 -0
- package/esm2022/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.mjs +150 -0
- package/esm2022/lib/spatial-controls/spatial-charts/chart-data-model.mjs +309 -0
- package/esm2022/lib/spatial-controls/spatial-charts/chart-help.mjs +145 -0
- package/esm2022/lib/spatial-controls/spatial-charts/plotly-chart-host.mjs +158 -0
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-chart-window/spatial-chart-window.component.mjs +47 -0
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-charts.component.mjs +297 -802
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-embedding-controls/spatial-embedding-controls.component.mjs +89 -0
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-heatmap-controls/spatial-heatmap-controls.component.mjs +52 -0
- package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +143 -1238
- package/esm2022/lib/spatial-controls/spatial-gene-picker.mjs +153 -0
- package/esm2022/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.mjs +241 -0
- package/esm2022/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.mjs +193 -0
- package/esm2022/lib/spatial-controls/spatial-key/spatial-key.component.mjs +132 -0
- package/esm2022/lib/spatial-controls/spatial-key/spatial-key.model.mjs +67 -0
- package/esm2022/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.mjs +147 -0
- package/esm2022/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.mjs +300 -0
- package/esm2022/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.mjs +370 -0
- package/esm2022/lib/store/class-color.util.mjs +46 -3
- package/esm2022/lib/store/region-history.mjs +146 -0
- package/esm2022/lib/store/region-scope-cache.mjs +140 -0
- package/esm2022/lib/store/region-selection.mjs +82 -0
- package/esm2022/lib/store/region-store.service.mjs +279 -675
- package/esm2022/lib/store/spatial-selection.service.mjs +2 -2
- package/esm2022/lib/store/visualizer-store.service.mjs +49 -71
- package/esm2022/lib/toast-outlets.mjs +5 -4
- package/esm2022/lib/toolbar/brush/brush-tool.service.mjs +92 -434
- package/esm2022/lib/toolbar/canvas-tools.mjs +20 -0
- package/esm2022/lib/toolbar/crop/slide-crop.mjs +26 -42
- package/esm2022/lib/toolbar/plot-type-selector/plot-type-selector.component.mjs +85 -0
- package/esm2022/lib/toolbar/region-tools/region-tool-buttons.mjs +74 -0
- package/esm2022/lib/toolbar/region-tools/region-tools.component.mjs +114 -0
- package/esm2022/lib/toolbar/segmentation/cell-segment-tool.service.mjs +74 -78
- package/esm2022/lib/toolbar/segmentation/cellpose-segmenter.service.mjs +50 -8
- package/esm2022/lib/toolbar/segmentation/onnx-sam-session.mjs +61 -42
- package/esm2022/lib/toolbar/segmentation/pending-calls.mjs +47 -0
- package/esm2022/lib/toolbar/segmentation/sam-model-registry.mjs +12 -4
- package/esm2022/lib/toolbar/segmentation/sam-onnx-core.mjs +70 -14
- package/esm2022/lib/toolbar/segmentation/sam-point-tool.service.mjs +135 -172
- package/esm2022/lib/toolbar/segmentation/sam-prompt.mjs +9 -90
- package/esm2022/lib/toolbar/segmentation/sam-session.service.mjs +183 -0
- package/esm2022/lib/toolbar/segmentation/sam-tool.service.mjs +95 -150
- package/esm2022/lib/toolbar/segmentation/segmentation-commit.mjs +12 -0
- package/esm2022/lib/toolbar/segmentation/segmentation-runner.mjs +108 -0
- package/esm2022/lib/toolbar/segmentation-tools/segmentation-tools.component.mjs +155 -0
- package/esm2022/lib/toolbar/stack-controls/stack-controls.component.mjs +81 -0
- package/esm2022/lib/toolbar/tool-kit/async-tool-status.mjs +37 -0
- package/esm2022/lib/toolbar/tool-kit/canvas-tool-manager.mjs +63 -0
- package/esm2022/lib/toolbar/tool-kit/canvas-tool.mjs +2 -0
- package/esm2022/lib/toolbar/tool-kit/frame-pixels.mjs +108 -0
- package/esm2022/lib/toolbar/tool-kit/mask-stroke-editor.mjs +306 -0
- package/esm2022/lib/toolbar/tool-kit/matrix-frame.mjs +61 -0
- package/esm2022/lib/toolbar/tool-kit/tool-overlay.mjs +140 -0
- package/esm2022/lib/toolbar/tool-kit/undo-gesture.mjs +24 -0
- package/esm2022/lib/toolbar/tool-slider/tool-slider.component.mjs +63 -0
- package/esm2022/lib/toolbar/toolbar-help-dialog/toolbar-help-dialog.component.mjs +50 -0
- package/esm2022/lib/toolbar/toolbar.component.mjs +68 -117
- package/esm2022/lib/toolbar/vertex-eraser/vertex-eraser-tool.service.mjs +93 -115
- package/esm2022/lib/toolbar/view-controls/view-controls.component.mjs +107 -0
- package/esm2022/lib/toolbar/wand/wand-region-grow.mjs +321 -0
- package/esm2022/lib/toolbar/wand/wand-tool.service.mjs +121 -416
- package/esm2022/lib/toolbar/wand/wand.service.mjs +30 -894
- package/esm2022/lib/toolbar/zoom-to-box/zoom-to-box-tool.service.mjs +48 -90
- package/esm2022/lib/util/mark-for-check.mjs +17 -0
- package/esm2022/lib/util/supersede.mjs +56 -0
- package/esm2022/lib/visualization.module.mjs +39 -141
- package/esm2022/lib/visualizer/floating-drag.directive.mjs +58 -0
- package/esm2022/lib/visualizer/region-actions.mjs +149 -0
- package/esm2022/lib/visualizer/region-load.mjs +60 -0
- package/esm2022/lib/visualizer/spatial-dataset-binder.mjs +163 -0
- package/esm2022/lib/visualizer/tool-modes.mjs +113 -0
- package/esm2022/lib/visualizer/viewer-shortcuts.mjs +167 -0
- package/esm2022/lib/visualizer/visualizer-context-menu.mjs +119 -0
- package/esm2022/lib/visualizer.component.mjs +480 -1902
- package/esm2022/lib/workers/spatial-math-ops.mjs +43 -0
- package/esm2022/lib/workers/spatial-math-worker.mjs +10 -0
- package/esm2022/lib/workers/spatial-math.mjs +190 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs +41083 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs +238 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-spatial-math-worker-BzVFFqGS.mjs +12 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-spatial-math-worker-BzVFFqGS.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +41 -34467
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs.map +1 -1
- package/fesm2022/mask.worker.js +36 -917
- package/fesm2022/onnx-sam.worker.js +52 -16
- package/fesm2022/spatial-math.worker.js +471 -0
- package/fesm2022/tsne.worker.js +32 -15
- package/index.d.ts +13 -10
- package/lib/channel-histogram/channel-histogram.component.d.ts +53 -43
- package/lib/contracts/capabilities.contract.d.ts +4 -2
- package/lib/contracts/cell-segmenter.contract.d.ts +1 -0
- package/lib/contracts/channel-histogram-api.contract.d.ts +4 -0
- package/lib/contracts/color.d.ts +27 -0
- package/lib/contracts/colormap-lut.d.ts +19 -4
- package/lib/contracts/coordinate-transform.contract.d.ts +3 -3
- package/lib/contracts/display-types.d.ts +21 -0
- package/lib/contracts/instance-segmenter.contract.d.ts +5 -0
- package/lib/contracts/intensity.d.ts +13 -2
- package/lib/contracts/plot-type.d.ts +3 -1
- package/lib/contracts/ports/image-state.port.d.ts +6 -2
- package/lib/contracts/ports/preferences.port.d.ts +4 -0
- package/lib/contracts/ports/region-io.port.d.ts +1 -0
- package/lib/contracts/ports/spatial-data.port.d.ts +4 -10
- package/lib/contracts/ports/tile-access.port.d.ts +1 -0
- package/lib/contracts/region-editor-api.contract.d.ts +1 -1
- package/lib/contracts/region-overlay.contract.d.ts +5 -0
- package/lib/contracts/sam.contract.d.ts +7 -0
- package/lib/contracts/semantic-segmenter.contract.d.ts +6 -0
- package/lib/contracts/spatial-dataset.contract.d.ts +19 -6
- package/lib/contracts/toolbar-tool.contract.d.ts +1 -0
- package/lib/contracts/visualizer.contract.d.ts +221 -54
- package/lib/contracts/viz-config.d.ts +1 -0
- package/lib/geometry/contour.d.ts +24 -0
- package/lib/geometry/raster.d.ts +42 -0
- package/lib/geometry/ring.d.ts +67 -0
- package/lib/hex-color-picker/hex-color-picker.component.d.ts +61 -27
- package/lib/implementations/base-store-visualizer.d.ts +61 -15
- package/lib/implementations/napari-js/napari-axes-gizmo.d.ts +36 -0
- package/lib/implementations/napari-js/napari-display-state.d.ts +76 -0
- package/lib/implementations/napari-js/napari-helpers.d.ts +129 -0
- package/lib/implementations/napari-js/napari-image-2d-scene.d.ts +162 -0
- package/lib/implementations/napari-js/napari-loading-badge.d.ts +0 -1
- package/lib/implementations/napari-js/napari-loading-state.d.ts +30 -0
- package/lib/implementations/napari-js/napari-region-overlay.d.ts +62 -70
- package/lib/implementations/napari-js/napari-scene.d.ts +93 -0
- package/lib/implementations/napari-js/napari-spatial-2d-scene.d.ts +163 -0
- package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +212 -0
- package/lib/implementations/napari-js/napari-spatial-encoding.d.ts +114 -0
- package/lib/implementations/napari-js/napari-spatial-hover.d.ts +89 -0
- package/lib/implementations/napari-js/napari-spatial-scene.d.ts +118 -0
- package/lib/implementations/napari-js/napari-spatial-tiles.d.ts +56 -263
- package/lib/implementations/napari-js/napari-spatial-tooltip.d.ts +1 -1
- package/lib/implementations/napari-js/napari-surface-scene.d.ts +76 -0
- package/lib/implementations/napari-js/napari-tile-client.d.ts +214 -0
- package/lib/implementations/napari-js/napari-tool-bridge.d.ts +179 -0
- package/lib/implementations/napari-js/napari-visualizer.service.d.ts +121 -883
- package/lib/implementations/napari-js/napari-volume-scene.d.ts +104 -0
- package/lib/implementations/napari-js/napari-volume-z-handle.d.ts +8 -12
- package/lib/implementations/napari-js/region-overlay/overlay-projection.d.ts +59 -0
- package/lib/implementations/napari-js/region-overlay/region-edit.d.ts +15 -0
- package/lib/implementations/napari-js/region-overlay/region-svg-renderer.d.ts +54 -0
- package/lib/implementations/napari-js/spatial-tiles/categorical-lookup.d.ts +26 -0
- package/lib/implementations/napari-js/spatial-tiles/cell-layers.d.ts +70 -0
- package/lib/implementations/napari-js/spatial-tiles/density-layer.d.ts +61 -0
- package/lib/implementations/napari-js/spatial-tiles/layer-groups.d.ts +67 -0
- package/lib/implementations/napari-js/spatial-tiles/plan-context.d.ts +38 -0
- package/lib/implementations/napari-js/spatial-tiles/transcript-hover.d.ts +71 -0
- package/lib/implementations/napari-js/spatial-tiles/transcript-jobs.d.ts +105 -0
- package/lib/implementations/napari-js/spatial-tiles/transcript-layers.d.ts +56 -0
- package/lib/implementations/osd/display-pipeline.d.ts +38 -9
- package/lib/implementations/osd/histogram-sampler.d.ts +22 -12
- package/lib/implementations/osd/openseadragon-viewer-options.d.ts +35 -0
- package/lib/implementations/osd/openseadragon-visualizer.service.d.ts +78 -354
- package/lib/implementations/osd/osd-coordinate-transform.d.ts +2 -1
- package/lib/implementations/osd/osd-coords.d.ts +6 -4
- package/lib/implementations/osd/osd-export.d.ts +36 -0
- package/lib/implementations/osd/osd-lib.d.ts +7 -0
- package/lib/implementations/osd/osd-navigator-chrome.d.ts +69 -0
- package/lib/implementations/osd/osd-pixel-readback.d.ts +22 -0
- package/lib/implementations/osd/osd-region-overlay-draw.d.ts +37 -0
- package/lib/implementations/osd/osd-region-overlay.d.ts +36 -48
- package/lib/implementations/osd/osd-scale-bar.d.ts +8 -6
- package/lib/implementations/osd/osd-tile-source.d.ts +49 -0
- package/lib/implementations/osd/osd-viewer-like.d.ts +100 -0
- package/lib/implementations/osd/osd-viewer-mount.d.ts +14 -0
- package/lib/implementations/osd/osd-viewport.d.ts +77 -0
- package/lib/implementations/osd/osd-zoom.d.ts +6 -0
- package/lib/implementations/osd/simple-source.d.ts +161 -0
- package/lib/implementations/osd/slice-cache.d.ts +12 -3
- package/lib/implementations/osd/tile-client.d.ts +11 -14
- package/lib/implementations/osd/tile-recolor.d.ts +141 -0
- package/lib/implementations/plotly/omics-trace-builders.d.ts +32 -20
- package/lib/implementations/plotly/plotly-image-loader.d.ts +49 -0
- package/lib/implementations/plotly/plotly-image-recolor.d.ts +75 -0
- package/lib/implementations/plotly/plotly-intensity-inset.d.ts +8 -0
- package/lib/implementations/plotly/plotly-isosurface-controls.d.ts +38 -0
- package/lib/implementations/plotly/plotly-layouts.d.ts +188 -0
- package/lib/implementations/plotly/plotly-readback.d.ts +41 -0
- package/lib/implementations/plotly/plotly-region-overlay.d.ts +2 -2
- package/lib/implementations/plotly/plotly-shape-projection.d.ts +92 -0
- package/lib/implementations/plotly/plotly-trace-builders.d.ts +23 -12
- package/lib/implementations/plotly/plotly-zoom-controller.d.ts +86 -0
- package/lib/implementations/plotly/plotly.service.d.ts +136 -401
- package/lib/implementations/region-centroids.d.ts +14 -0
- package/lib/implementations/simple-slice-access.service.d.ts +7 -4
- package/lib/implementations/spatial-data-http/spatial-data-http.service.d.ts +42 -18
- package/lib/implementations/spatial-data-http/spatial-wire.d.ts +34 -9
- package/lib/implementations/tile-server/index.d.ts +5 -0
- package/lib/implementations/tile-server/native-histogram.d.ts +25 -0
- package/lib/implementations/tile-server/poll-descriptor.d.ts +39 -0
- package/lib/implementations/tile-server/tile-protocol.d.ts +80 -0
- package/lib/implementations/tile-server/transport.d.ts +62 -0
- package/lib/intensity/intensity-profile.d.ts +66 -0
- package/lib/intensity/intensity-profile.service.d.ts +108 -0
- package/lib/intensity-inset/intensity-inset.component.d.ts +58 -0
- package/lib/models/bezier.d.ts +0 -5
- package/lib/models/class-preset.d.ts +18 -0
- package/lib/models/geometry.d.ts +14 -48
- package/lib/models/polygon-edit.d.ts +72 -0
- package/lib/models/polygon-factory.d.ts +40 -0
- package/lib/models/region-clone.d.ts +20 -0
- package/lib/models/region-geojson.d.ts +17 -0
- package/lib/models/region.d.ts +40 -4
- package/lib/models/shape.d.ts +8 -0
- package/lib/plot-mode/contribution-host.d.ts +125 -0
- package/lib/plot-mode/plot-type-menu.d.ts +60 -0
- package/lib/plot-mode/tool-params-model.d.ts +49 -0
- package/lib/plot.utilities.d.ts +19 -30
- package/lib/processing/processing-image.d.ts +5 -2
- package/lib/provide-visualization.d.ts +19 -2
- package/lib/region-editor/classes-panel/classes-panel.component.d.ts +56 -0
- package/lib/region-editor/file-stem.d.ts +7 -0
- package/lib/region-editor/manage-classes-dialog/manage-classes-dialog.component.d.ts +45 -0
- package/lib/region-editor/mask-export.service.d.ts +54 -0
- package/lib/region-editor/mask-raster.d.ts +2 -8
- package/lib/region-editor/region-color-dialog/region-color-dialog.component.d.ts +29 -0
- package/lib/region-editor/region-editor-help/region-editor-help.component.d.ts +11 -0
- package/lib/region-editor/region-editor.component.d.ts +166 -199
- package/lib/region-editor/region-metrics.d.ts +26 -0
- package/lib/region-editor/region-persistence.service.d.ts +69 -0
- package/lib/region-editor/region-table/region-table.component.d.ts +83 -0
- package/lib/region-editor/save-mask-dialog/save-mask-dialog.component.d.ts +36 -0
- package/lib/region-editor/save-regions-dialog/save-regions-dialog.component.d.ts +37 -0
- package/lib/region-ops.service.d.ts +1 -7
- package/lib/region-overlay/region-geometry.d.ts +157 -0
- package/lib/region-overlay/region-hit-test.d.ts +38 -0
- package/lib/region-overlay/svg-region-renderer.d.ts +110 -0
- package/lib/render-orchestrator.d.ts +6 -2
- package/lib/render-session.d.ts +75 -0
- package/lib/routing-visualizer.service.d.ts +110 -58
- package/lib/spatial/density-raster.d.ts +6 -0
- package/lib/spatial/embedding-compute-coordinator.d.ts +123 -0
- package/lib/spatial/embedding-compute.d.ts +21 -2
- package/lib/spatial/glyphs.d.ts +16 -0
- package/lib/spatial/lod.d.ts +94 -0
- package/lib/spatial/spatial-controls.facade.d.ts +64 -0
- package/lib/spatial/spatial-density.d.ts +15 -5
- package/lib/spatial/spatial-encoding.d.ts +11 -44
- package/lib/spatial/spatial-expression.d.ts +40 -22
- package/lib/spatial/spatial-framing.d.ts +1 -0
- package/lib/spatial/spatial-heatmap.d.ts +2 -0
- package/lib/spatial/spatial-hover.d.ts +4 -16
- package/lib/spatial/spatial-panel-model.d.ts +135 -0
- package/lib/spatial/spatial-selection.d.ts +21 -26
- package/lib/spatial/spatial-tile-merge.d.ts +41 -0
- package/lib/spatial/spatial-tiles.d.ts +9 -256
- package/lib/spatial/stats.d.ts +38 -0
- package/lib/spatial/transcript-grouping.d.ts +119 -0
- package/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.d.ts +64 -0
- package/lib/spatial-controls/spatial-charts/chart-data-model.d.ts +153 -0
- package/lib/spatial-controls/spatial-charts/chart-help.d.ts +69 -0
- package/lib/spatial-controls/spatial-charts/plotly-chart-host.d.ts +98 -0
- package/lib/spatial-controls/spatial-charts/spatial-chart-window/spatial-chart-window.component.d.ts +26 -0
- package/lib/spatial-controls/spatial-charts/spatial-charts.component.d.ts +101 -260
- package/lib/spatial-controls/spatial-charts/spatial-embedding-controls/spatial-embedding-controls.component.d.ts +43 -0
- package/lib/spatial-controls/spatial-charts/spatial-heatmap-controls/spatial-heatmap-controls.component.d.ts +27 -0
- package/lib/spatial-controls/spatial-controls.component.d.ts +68 -448
- package/lib/spatial-controls/spatial-gene-picker.d.ts +86 -0
- package/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.d.ts +102 -0
- package/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.d.ts +72 -0
- package/lib/spatial-controls/spatial-key/spatial-key.component.d.ts +66 -0
- package/lib/spatial-controls/spatial-key/spatial-key.model.d.ts +33 -0
- package/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.d.ts +64 -0
- package/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.d.ts +117 -0
- package/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.d.ts +142 -0
- package/lib/store/class-color.util.d.ts +35 -1
- package/lib/store/region-history.d.ts +66 -0
- package/lib/store/region-scope-cache.d.ts +63 -0
- package/lib/store/region-selection.d.ts +36 -0
- package/lib/store/region-store.service.d.ts +104 -112
- package/lib/store/visualizer-store.service.d.ts +22 -33
- package/lib/toast-outlets.d.ts +4 -3
- package/lib/toolbar/brush/brush-tool.service.d.ts +31 -98
- package/lib/toolbar/canvas-tools.d.ts +20 -0
- package/lib/toolbar/crop/slide-crop.d.ts +10 -4
- package/lib/toolbar/plot-type-selector/plot-type-selector.component.d.ts +38 -0
- package/lib/toolbar/region-tools/region-tool-buttons.d.ts +21 -0
- package/lib/toolbar/region-tools/region-tools.component.d.ts +60 -0
- package/lib/toolbar/segmentation/cell-segment-tool.service.d.ts +10 -14
- package/lib/toolbar/segmentation/cellpose-segmenter.service.d.ts +12 -2
- package/lib/toolbar/segmentation/onnx-sam-session.d.ts +22 -3
- package/lib/toolbar/segmentation/pending-calls.d.ts +31 -0
- package/lib/toolbar/segmentation/sam-model-registry.d.ts +9 -3
- package/lib/toolbar/segmentation/sam-onnx-core.d.ts +18 -5
- package/lib/toolbar/segmentation/sam-point-tool.service.d.ts +46 -32
- package/lib/toolbar/segmentation/sam-prompt.d.ts +7 -31
- package/lib/toolbar/segmentation/sam-session.service.d.ts +74 -0
- package/lib/toolbar/segmentation/sam-tool.service.d.ts +23 -30
- package/lib/toolbar/segmentation/segmentation-commit.d.ts +8 -0
- package/lib/toolbar/segmentation/segmentation-runner.d.ts +52 -0
- package/lib/toolbar/segmentation-tools/segmentation-tools.component.d.ts +87 -0
- package/lib/toolbar/stack-controls/stack-controls.component.d.ts +40 -0
- package/lib/toolbar/tool-kit/async-tool-status.d.ts +21 -0
- package/lib/toolbar/tool-kit/canvas-tool-manager.d.ts +36 -0
- package/lib/toolbar/tool-kit/canvas-tool.d.ts +86 -0
- package/lib/toolbar/tool-kit/frame-pixels.d.ts +45 -0
- package/lib/toolbar/tool-kit/mask-stroke-editor.d.ts +125 -0
- package/lib/toolbar/tool-kit/matrix-frame.d.ts +40 -0
- package/lib/toolbar/tool-kit/tool-overlay.d.ts +60 -0
- package/lib/toolbar/tool-kit/undo-gesture.d.ts +17 -0
- package/lib/toolbar/tool-slider/tool-slider.component.d.ts +33 -0
- package/lib/toolbar/toolbar-help-dialog/toolbar-help-dialog.component.d.ts +24 -0
- package/lib/toolbar/toolbar.component.d.ts +47 -83
- package/lib/toolbar/vertex-eraser/vertex-eraser-tool.service.d.ts +33 -40
- package/lib/toolbar/view-controls/view-controls.component.d.ts +54 -0
- package/lib/toolbar/wand/wand-region-grow.d.ts +49 -0
- package/lib/toolbar/wand/wand-tool.service.d.ts +39 -124
- package/lib/toolbar/wand/wand.service.d.ts +22 -116
- package/lib/toolbar/zoom-to-box/zoom-to-box-tool.service.d.ts +17 -37
- package/lib/util/mark-for-check.d.ts +11 -0
- package/lib/util/supersede.d.ts +53 -0
- package/lib/visualization.module.d.ts +18 -39
- package/lib/visualizer/floating-drag.directive.d.ts +30 -0
- package/lib/visualizer/region-actions.d.ts +54 -0
- package/lib/visualizer/region-load.d.ts +27 -0
- package/lib/visualizer/spatial-dataset-binder.d.ts +74 -0
- package/lib/visualizer/tool-modes.d.ts +49 -0
- package/lib/visualizer/viewer-shortcuts.d.ts +71 -0
- package/lib/visualizer/visualizer-context-menu.d.ts +55 -0
- package/lib/visualizer.component.d.ts +201 -447
- package/lib/workers/spatial-math-ops.d.ts +65 -0
- package/lib/workers/spatial-math-worker.d.ts +7 -0
- package/lib/workers/spatial-math.d.ts +74 -0
- package/package.json +12 -3
- package/src/lib/styles/_viz-icons-rules.scss +73 -0
- package/src/lib/styles/viz-icons.scss +14 -0
- package/esm2022/lib/implementations/napari-js/napari-axes-labels.mjs +0 -97
- package/esm2022/lib/implementations/napari-js/napari-navigator.mjs +0 -195
- package/esm2022/lib/implementations/napari-js/napari-scale-bar.mjs +0 -92
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-BwP-A11m.mjs +0 -329
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-BwP-A11m.mjs.map +0 -1
- package/lib/implementations/napari-js/napari-axes-labels.d.ts +0 -49
- package/lib/implementations/napari-js/napari-navigator.d.ts +0 -72
- package/lib/implementations/napari-js/napari-scale-bar.d.ts +0 -35
- package/src/lib/assets/cell-detection.svg +0 -37
- package/src/lib/assets/click.svg +0 -1
- package/src/lib/assets/colormap-luts.json +0 -1
- package/src/lib/assets/edit-selection-white.svg +0 -47
- package/src/lib/assets/icons/colormap-earth.png +0 -0
- package/src/lib/assets/icons/colormap-placeholder.png +0 -0
- package/src/lib/assets/icons/colormap-pubu.png +0 -0
- package/src/lib/assets/interactive-segmentation-cursor.svg +0 -1
- package/src/lib/assets/picture-segmentation.svg +0 -43
- package/src/lib/assets/test/download-379.svg +0 -1
- package/src/lib/assets/test/download-98.svg +0 -1
- package/src/lib/assets/test/json-1.svg +0 -1
- package/src/lib/assets/test/load-53.svg +0 -1
- package/src/lib/assets/test/mask-44.svg +0 -1
- package/src/lib/assets/test/mask-download-44.svg +0 -15
- package/src/lib/assets/test/mask-save-44.svg +0 -11
- package/src/lib/assets/test/overlay-1.svg +0 -1
- package/src/lib/assets/test/overlay-4.svg +0 -1
- package/src/lib/assets/test/region-26.svg +0 -1
- package/src/lib/assets/test/save-56.svg +0 -1
- package/src/lib/assets/test/upload-43.svg +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cursor tooltip naming the observation under the pointer, for the spatial-omics
|
|
3
|
-
* views — the same overlay-in-the-host pattern as
|
|
3
|
+
* views — the same overlay-in-the-host pattern as napari-js's `ScaleBarOverlay`.
|
|
4
4
|
*
|
|
5
5
|
* A 34-entry legend cannot be read back from a dot: several classes get similar
|
|
6
6
|
* colours, and matching one to a swatch by eye is the job a tooltip removes. It
|
|
@@ -96,4 +96,4 @@ export class NapariSpatialTooltip {
|
|
|
96
96
|
this.el.remove();
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFwYXJpLXNwYXRpYWwtdG9vbHRpcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvaW1wbGVtZW50YXRpb25zL25hcGFyaS1qcy9uYXBhcmktc3BhdGlhbC10b29sdGlwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsTUFBTSxPQUFPLG9CQUFvQjtJQUkvQixpRkFBaUY7YUFDekQsV0FBTSxHQUFHLEVBQUUsQ0FBQztJQUVwQyxZQUE2QixJQUFpQjtRQUFqQixTQUFJLEdBQUosSUFBSSxDQUFhO1FBQzVDLHNFQUFzRTtRQUN0RSw4RUFBOEU7UUFDOUUsNkVBQTZFO1FBQzdFLCtFQUErRTtRQUMvRSxxQ0FBcUM7UUFDckMsTUFBTSxVQUFVLEdBQUcsQ0FBQyxVQUFVLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztRQUMvRCxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1lBQzFELElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxHQUFHLFVBQVUsQ0FBQztRQUNuQyxDQUFDO1FBRUQsSUFBSSxDQUFDLEVBQUUsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3hDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUU7WUFDM0IsUUFBUSxFQUFFLFVBQVU7WUFDcEIsT0FBTyxFQUFFLE1BQU07WUFDZiw2REFBNkQ7WUFDN0QsTUFBTSxFQUFFLEdBQUc7WUFDWCxxRUFBcUU7WUFDckUsNkRBQTZEO1lBQzdELGFBQWEsRUFBRSxNQUFNO1lBQ3JCLE9BQU8sRUFBRSxTQUFTO1lBQ2xCLFlBQVksRUFBRSxLQUFLO1lBQ25CLFVBQVUsRUFBRSx3QkFBd0I7WUFDcEMsS0FBSyxFQUFFLE1BQU07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QUssR0FBRyxHQUFHLENBQUM7UUFDakYsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1FBQzdDLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQztJQUM3QyxDQUFDO0lBRUQsSUFBSTtRQUNGLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7SUFDakMsQ0FBQztJQUVELGdGQUFnRjtJQUNoRixJQUFJLE9BQU87UUFDVCxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLE9BQU8sS0FBSyxNQUFNLENBQUM7SUFDMUMsQ0FBQztJQUVELE9BQU87UUFDTCxJQUFJLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ25CLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEN1cnNvciB0b29sdGlwIG5hbWluZyB0aGUgb2JzZXJ2YXRpb24gdW5kZXIgdGhlIHBvaW50ZXIsIGZvciB0aGUgc3BhdGlhbC1vbWljc1xuICogdmlld3Mg4oCUIHRoZSBzYW1lIG92ZXJsYXktaW4tdGhlLWhvc3QgcGF0dGVybiBhcyB7QGxpbmsgTmFwYXJpU2NhbGVCYXJ9LlxuICpcbiAqIEEgMzQtZW50cnkgbGVnZW5kIGNhbm5vdCBiZSByZWFkIGJhY2sgZnJvbSBhIGRvdDogc2V2ZXJhbCBjbGFzc2VzIGdldCBzaW1pbGFyXG4gKiBjb2xvdXJzLCBhbmQgbWF0Y2hpbmcgb25lIHRvIGEgc3dhdGNoIGJ5IGV5ZSBpcyB0aGUgam9iIGEgdG9vbHRpcCByZW1vdmVzLiBJdFxuICogc2hvd3Mgd2hhdCB0aGUgY2xvdWQgaXMgQ1VSUkVOVExZIGNvbG91cmVkIGJ5LCBzbyBpdCBhbHdheXMgYWdyZWVzIHdpdGggdGhlXG4gKiBsZWdlbmQgYmVzaWRlIGl0LlxuICpcbiAqIERlbGliZXJhdGVseSBub3QgUHJpbWVORydzIGBwVG9vbHRpcGA6IHRoYXQgYmluZHMgdG8gYW4gZWxlbWVudCwgYW5kIHRoZXNlXG4gKiBwb2ludHMgYXJlIHBpeGVscyBpbiBhIFdlYkdQVSBjYW52YXMgd2l0aCBubyBET00gb2YgdGhlaXIgb3duLlxuICovXG5leHBvcnQgY2xhc3MgTmFwYXJpU3BhdGlhbFRvb2x0aXAge1xuICBwcml2YXRlIHJlYWRvbmx5IGVsOiBIVE1MRGl2RWxlbWVudDtcbiAgcHJpdmF0ZSByZWFkb25seSBwcmltYXJ5OiBIVE1MU3BhbkVsZW1lbnQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgc2Vjb25kYXJ5OiBIVE1MU3BhbkVsZW1lbnQ7XG4gIC8qKiBHYXAgYmV0d2VlbiB0aGUgY3Vyc29yIGFuZCB0aGUgYm94LCBzbyB0aGUgYm94IG5ldmVyIHNpdHMgdW5kZXIgdGhlIGFycm93LiAqL1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBPRkZTRVQgPSAxNDtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGhvc3Q6IEhUTUxFbGVtZW50KSB7XG4gICAgLy8gQWJzb2x1dGVseSBwb3NpdGlvbmVkIHdpdGhpbiB0aGUgaG9zdCwgc28gdGhlIGhvc3QgbXVzdCBlc3RhYmxpc2ggYVxuICAgIC8vIGNvbnRhaW5pbmcgYmxvY2sgKHRoZSBwbG90IGhvc3QgaXMgb2Z0ZW4gc3RhdGljYWxseSBwb3NpdGlvbmVkKS4gVGVzdGVkIGZvclxuICAgIC8vIHdoYXQgaXQgbXVzdCBOT1QgYmUgcmF0aGVyIHRoYW4gZm9yICdzdGF0aWMnOiBhIGNvbXB1dGVkIHBvc2l0aW9uIGNhbiBhbHNvXG4gICAgLy8gY29tZSBiYWNrIGVtcHR5LCBhbmQgdHJlYXRpbmcgdGhhdCBhcyBhbHJlYWR5LXBvc2l0aW9uZWQgd291bGQgbGVhdmUgdGhlIGJveFxuICAgIC8vIGFuY2hvcmVkIHRvIHNvbWUgYW5jZXN0b3IgaW5zdGVhZC5cbiAgICBjb25zdCBwb3NpdGlvbmVkID0gWydyZWxhdGl2ZScsICdhYnNvbHV0ZScsICdmaXhlZCcsICdzdGlja3knXTtcbiAgICBpZiAoIXBvc2l0aW9uZWQuaW5jbHVkZXMoZ2V0Q29tcHV0ZWRTdHlsZShob3N0KS5wb3NpdGlvbikpIHtcbiAgICAgIGhvc3Quc3R5bGUucG9zaXRpb24gPSAncmVsYXRpdmUnO1xuICAgIH1cblxuICAgIHRoaXMuZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBPYmplY3QuYXNzaWduKHRoaXMuZWwuc3R5bGUsIHtcbiAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgZGlzcGxheTogJ25vbmUnLFxuICAgICAgLy8gQWJvdmUgdGhlIGNhbnZhcyBhbmQgdGhlIHJlZ2lvbiBvdmVybGF5LCBiZWxvdyBhbnkgZGlhbG9nLlxuICAgICAgekluZGV4OiAnNicsXG4gICAgICAvLyBUaGUgcG9pbnRlciBoYXMgdG8gcmVhY2ggdGhlIGNhbnZhcyB1bmRlcm5lYXRoOiBhIHRvb2x0aXAgdGhhdCBhdGVcbiAgICAgIC8vIHBvaW50ZXIgZXZlbnRzIHdvdWxkIGtpbGwgb3JiaXRpbmcgdGhlIG1vbWVudCBpdCBhcHBlYXJlZC5cbiAgICAgIHBvaW50ZXJFdmVudHM6ICdub25lJyxcbiAgICAgIHBhZGRpbmc6ICc0cHggOHB4JyxcbiAgICAgIGJvcmRlclJhZGl1czogJzRweCcsXG4gICAgICBiYWNrZ3JvdW5kOiAncmdiYSgxNywgMTcsIDIwLCAwLjg4KScsXG4gICAgICBjb2xvcjogJyNmZmYnLFxuICAgICAgZm9udDogJzEycHgvMS4zNSBzeXN0ZW0tdWksIHNhbnMtc2VyaWYnLFxuICAgICAgd2hpdGVTcGFjZTogJ25vd3JhcCcsXG4gICAgICBib3hTaGFkb3c6ICcwIDJweCA4cHggcmdiYSgwLCAwLCAwLCAwLjM1KScsXG4gICAgICBtYXhXaWR0aDogJzIycmVtJyxcbiAgICAgIG92ZXJmbG93OiAnaGlkZGVuJyxcbiAgICAgIHRleHRPdmVyZmxvdzogJ2VsbGlwc2lzJyxcbiAgICB9IGFzIFBhcnRpYWw8Q1NTU3R5bGVEZWNsYXJhdGlvbj4pO1xuXG4gICAgdGhpcy5wcmltYXJ5ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgIE9iamVjdC5hc3NpZ24odGhpcy5wcmltYXJ5LnN0eWxlLCB7IGRpc3BsYXk6ICdibG9jaycsIGZvbnRXZWlnaHQ6ICc2MDAnIH0pO1xuICAgIHRoaXMuc2Vjb25kYXJ5ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgIE9iamVjdC5hc3NpZ24odGhpcy5zZWNvbmRhcnkuc3R5bGUsIHtcbiAgICAgIGRpc3BsYXk6ICdibG9jaycsXG4gICAgICBvcGFjaXR5OiAnMC43JyxcbiAgICAgIGZvbnRTaXplOiAnMTFweCcsXG4gICAgICAvLyBFdmVyeSBsaW5lIGFmdGVyIHRoZSBmaXJzdCBpcyBhIGRldGFpbCBsaW5lLCBvbmUgcGVyIHJvdy5cbiAgICAgIHdoaXRlU3BhY2U6ICdwcmUnLFxuICAgIH0gYXMgUGFydGlhbDxDU1NTdHlsZURlY2xhcmF0aW9uPik7XG5cbiAgICB0aGlzLmVsLmFwcGVuZCh0aGlzLnByaW1hcnksIHRoaXMuc2Vjb25kYXJ5KTtcbiAgICBob3N0LmFwcGVuZENoaWxkKHRoaXMuZWwpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNob3cgYGxpbmVzYCBhdCBhIHBvaW50IGdpdmVuIGluIEhPU1QtcmVsYXRpdmUgcGl4ZWxzLlxuICAgKlxuICAgKiBGbGlwcyB0byB0aGUgb3RoZXIgc2lkZSBvZiB0aGUgY3Vyc29yIG5lYXIgYW4gZWRnZSByYXRoZXIgdGhhbiBiZWluZyBjbGlwcGVkXG4gICAqIGJ5IHRoZSBob3N0IOKAlCBhIHRvb2x0aXAgaGFsZiBvdXRzaWRlIHRoZSBwbG90IGlzIHdvcnNlIHRoYW4gb25lIG9uIHRoZSBsZWZ0LlxuICAgKi9cbiAgc2hvdyhsaW5lczogcmVhZG9ubHkgc3RyaW5nW10sIGhvc3RYOiBudW1iZXIsIGhvc3RZOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAobGluZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLmhpZGUoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5wcmltYXJ5LnRleHRDb250ZW50ID0gbGluZXNbMF07XG4gICAgY29uc3QgZGV0YWlscyA9IGxpbmVzLnNsaWNlKDEpLmZpbHRlcihCb29sZWFuKTtcbiAgICB0aGlzLnNlY29uZGFyeS50ZXh0Q29udGVudCA9IGRldGFpbHMuam9pbignXFxuJyk7XG4gICAgdGhpcy5zZWNvbmRhcnkuc3R5bGUuZGlzcGxheSA9IGRldGFpbHMubGVuZ3RoID8gJ2Jsb2NrJyA6ICdub25lJztcbiAgICAvLyBNZWFzdXJlZCB3aGlsZSB2aXNpYmxlOiBvZmZzZXRXaWR0aCBpcyAwIG9uIGEgYGRpc3BsYXk6IG5vbmVgIGVsZW1lbnQsIHNvXG4gICAgLy8gdGhlIGZsaXAgYmVsb3cgd291bGQgYWx3YXlzIHRoaW5rIHRoZSBib3ggZml0cy5cbiAgICB0aGlzLmVsLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuXG4gICAgY29uc3QgZ2FwID0gTmFwYXJpU3BhdGlhbFRvb2x0aXAuT0ZGU0VUO1xuICAgIGNvbnN0IHcgPSB0aGlzLmVsLm9mZnNldFdpZHRoO1xuICAgIGNvbnN0IGggPSB0aGlzLmVsLm9mZnNldEhlaWdodDtcbiAgICBjb25zdCBob3N0VyA9IHRoaXMuaG9zdC5jbGllbnRXaWR0aDtcbiAgICBjb25zdCBob3N0SCA9IHRoaXMuaG9zdC5jbGllbnRIZWlnaHQ7XG4gICAgY29uc3QgbGVmdCA9IGhvc3RYICsgZ2FwICsgdyA+IGhvc3RXID8gTWF0aC5tYXgoMCwgaG9zdFggLSBnYXAgLSB3KSA6IGhvc3RYICsgZ2FwO1xuICAgIGNvbnN0IHRvcCA9IGhvc3RZICsgZ2FwICsgaCA+IGhvc3RIID8gTWF0aC5tYXgoMCwgaG9zdFkgLSBnYXAgLSBoKSA6IGhvc3RZICsgZ2FwO1xuICAgIHRoaXMuZWwuc3R5bGUubGVmdCA9IGAke01hdGgucm91bmQobGVmdCl9cHhgO1xuICAgIHRoaXMuZWwuc3R5bGUudG9wID0gYCR7TWF0aC5yb3VuZCh0b3ApfXB4YDtcbiAgfVxuXG4gIGhpZGUoKTogdm9pZCB7XG4gICAgdGhpcy5lbC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICB9XG5cbiAgLyoqIFRydWUgd2hpbGUgdGhlIGJveCBpcyBvbiBzY3JlZW4g4oCUIGZvciB0ZXN0cywgYW5kIHRvIHNraXAgcmVkdW5kYW50IGhpZGVzLiAqL1xuICBnZXQgdmlzaWJsZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5lbC5zdHlsZS5kaXNwbGF5ICE9PSAnbm9uZSc7XG4gIH1cblxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIHRoaXMuZWwucmVtb3ZlKCk7XG4gIH1cbn1cbiJdfQ==
|
|
99
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFwYXJpLXNwYXRpYWwtdG9vbHRpcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvaW1wbGVtZW50YXRpb25zL25hcGFyaS1qcy9uYXBhcmktc3BhdGlhbC10b29sdGlwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsTUFBTSxPQUFPLG9CQUFvQjtJQUkvQixpRkFBaUY7YUFDekQsV0FBTSxHQUFHLEVBQUUsQ0FBQztJQUVwQyxZQUE2QixJQUFpQjtRQUFqQixTQUFJLEdBQUosSUFBSSxDQUFhO1FBQzVDLHNFQUFzRTtRQUN0RSw4RUFBOEU7UUFDOUUsNkVBQTZFO1FBQzdFLCtFQUErRTtRQUMvRSxxQ0FBcUM7UUFDckMsTUFBTSxVQUFVLEdBQUcsQ0FBQyxVQUFVLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztRQUMvRCxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1lBQzFELElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxHQUFHLFVBQVUsQ0FBQztRQUNuQyxDQUFDO1FBRUQsSUFBSSxDQUFDLEVBQUUsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3hDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUU7WUFDM0IsUUFBUSxFQUFFLFVBQVU7WUFDcEIsT0FBTyxFQUFFLE1BQU07WUFDZiw2REFBNkQ7WUFDN0QsTUFBTSxFQUFFLEdBQUc7WUFDWCxxRUFBcUU7WUFDckUsNkRBQTZEO1lBQzdELGFBQWEsRUFBRSxNQUFNO1lBQ3JCLE9BQU8sRUFBRSxTQUFTO1lBQ2xCLFlBQVksRUFBRSxLQUFLO1lBQ25CLFVBQVUsRUFBRSx3QkFBd0I7WUFDcEMsS0FBSyxFQUFFLE1BQU07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QUssR0FBRyxHQUFHLENBQUM7UUFDakYsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1FBQzdDLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQztJQUM3QyxDQUFDO0lBRUQsSUFBSTtRQUNGLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7SUFDakMsQ0FBQztJQUVELGdGQUFnRjtJQUNoRixJQUFJLE9BQU87UUFDVCxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLE9BQU8sS0FBSyxNQUFNLENBQUM7SUFDMUMsQ0FBQztJQUVELE9BQU87UUFDTCxJQUFJLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ25CLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEN1cnNvciB0b29sdGlwIG5hbWluZyB0aGUgb2JzZXJ2YXRpb24gdW5kZXIgdGhlIHBvaW50ZXIsIGZvciB0aGUgc3BhdGlhbC1vbWljc1xuICogdmlld3Mg4oCUIHRoZSBzYW1lIG92ZXJsYXktaW4tdGhlLWhvc3QgcGF0dGVybiBhcyBuYXBhcmktanMncyBgU2NhbGVCYXJPdmVybGF5YC5cbiAqXG4gKiBBIDM0LWVudHJ5IGxlZ2VuZCBjYW5ub3QgYmUgcmVhZCBiYWNrIGZyb20gYSBkb3Q6IHNldmVyYWwgY2xhc3NlcyBnZXQgc2ltaWxhclxuICogY29sb3VycywgYW5kIG1hdGNoaW5nIG9uZSB0byBhIHN3YXRjaCBieSBleWUgaXMgdGhlIGpvYiBhIHRvb2x0aXAgcmVtb3Zlcy4gSXRcbiAqIHNob3dzIHdoYXQgdGhlIGNsb3VkIGlzIENVUlJFTlRMWSBjb2xvdXJlZCBieSwgc28gaXQgYWx3YXlzIGFncmVlcyB3aXRoIHRoZVxuICogbGVnZW5kIGJlc2lkZSBpdC5cbiAqXG4gKiBEZWxpYmVyYXRlbHkgbm90IFByaW1lTkcncyBgcFRvb2x0aXBgOiB0aGF0IGJpbmRzIHRvIGFuIGVsZW1lbnQsIGFuZCB0aGVzZVxuICogcG9pbnRzIGFyZSBwaXhlbHMgaW4gYSBXZWJHUFUgY2FudmFzIHdpdGggbm8gRE9NIG9mIHRoZWlyIG93bi5cbiAqL1xuZXhwb3J0IGNsYXNzIE5hcGFyaVNwYXRpYWxUb29sdGlwIHtcbiAgcHJpdmF0ZSByZWFkb25seSBlbDogSFRNTERpdkVsZW1lbnQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgcHJpbWFyeTogSFRNTFNwYW5FbGVtZW50O1xuICBwcml2YXRlIHJlYWRvbmx5IHNlY29uZGFyeTogSFRNTFNwYW5FbGVtZW50O1xuICAvKiogR2FwIGJldHdlZW4gdGhlIGN1cnNvciBhbmQgdGhlIGJveCwgc28gdGhlIGJveCBuZXZlciBzaXRzIHVuZGVyIHRoZSBhcnJvdy4gKi9cbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgT0ZGU0VUID0gMTQ7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBob3N0OiBIVE1MRWxlbWVudCkge1xuICAgIC8vIEFic29sdXRlbHkgcG9zaXRpb25lZCB3aXRoaW4gdGhlIGhvc3QsIHNvIHRoZSBob3N0IG11c3QgZXN0YWJsaXNoIGFcbiAgICAvLyBjb250YWluaW5nIGJsb2NrICh0aGUgcGxvdCBob3N0IGlzIG9mdGVuIHN0YXRpY2FsbHkgcG9zaXRpb25lZCkuIFRlc3RlZCBmb3JcbiAgICAvLyB3aGF0IGl0IG11c3QgTk9UIGJlIHJhdGhlciB0aGFuIGZvciAnc3RhdGljJzogYSBjb21wdXRlZCBwb3NpdGlvbiBjYW4gYWxzb1xuICAgIC8vIGNvbWUgYmFjayBlbXB0eSwgYW5kIHRyZWF0aW5nIHRoYXQgYXMgYWxyZWFkeS1wb3NpdGlvbmVkIHdvdWxkIGxlYXZlIHRoZSBib3hcbiAgICAvLyBhbmNob3JlZCB0byBzb21lIGFuY2VzdG9yIGluc3RlYWQuXG4gICAgY29uc3QgcG9zaXRpb25lZCA9IFsncmVsYXRpdmUnLCAnYWJzb2x1dGUnLCAnZml4ZWQnLCAnc3RpY2t5J107XG4gICAgaWYgKCFwb3NpdGlvbmVkLmluY2x1ZGVzKGdldENvbXB1dGVkU3R5bGUoaG9zdCkucG9zaXRpb24pKSB7XG4gICAgICBob3N0LnN0eWxlLnBvc2l0aW9uID0gJ3JlbGF0aXZlJztcbiAgICB9XG5cbiAgICB0aGlzLmVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLmVsLnN0eWxlLCB7XG4gICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgIGRpc3BsYXk6ICdub25lJyxcbiAgICAgIC8vIEFib3ZlIHRoZSBjYW52YXMgYW5kIHRoZSByZWdpb24gb3ZlcmxheSwgYmVsb3cgYW55IGRpYWxvZy5cbiAgICAgIHpJbmRleDogJzYnLFxuICAgICAgLy8gVGhlIHBvaW50ZXIgaGFzIHRvIHJlYWNoIHRoZSBjYW52YXMgdW5kZXJuZWF0aDogYSB0b29sdGlwIHRoYXQgYXRlXG4gICAgICAvLyBwb2ludGVyIGV2ZW50cyB3b3VsZCBraWxsIG9yYml0aW5nIHRoZSBtb21lbnQgaXQgYXBwZWFyZWQuXG4gICAgICBwb2ludGVyRXZlbnRzOiAnbm9uZScsXG4gICAgICBwYWRkaW5nOiAnNHB4IDhweCcsXG4gICAgICBib3JkZXJSYWRpdXM6ICc0cHgnLFxuICAgICAgYmFja2dyb3VuZDogJ3JnYmEoMTcsIDE3LCAyMCwgMC44OCknLFxuICAgICAgY29sb3I6ICcjZmZmJyxcbiAgICAgIGZvbnQ6ICcxMnB4LzEuMzUgc3lzdGVtLXVpLCBzYW5zLXNlcmlmJyxcbiAgICAgIHdoaXRlU3BhY2U6ICdub3dyYXAnLFxuICAgICAgYm94U2hhZG93OiAnMCAycHggOHB4IHJnYmEoMCwgMCwgMCwgMC4zNSknLFxuICAgICAgbWF4V2lkdGg6ICcyMnJlbScsXG4gICAgICBvdmVyZmxvdzogJ2hpZGRlbicsXG4gICAgICB0ZXh0T3ZlcmZsb3c6ICdlbGxpcHNpcycsXG4gICAgfSBhcyBQYXJ0aWFsPENTU1N0eWxlRGVjbGFyYXRpb24+KTtcblxuICAgIHRoaXMucHJpbWFyeSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICBPYmplY3QuYXNzaWduKHRoaXMucHJpbWFyeS5zdHlsZSwgeyBkaXNwbGF5OiAnYmxvY2snLCBmb250V2VpZ2h0OiAnNjAwJyB9KTtcbiAgICB0aGlzLnNlY29uZGFyeSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICBPYmplY3QuYXNzaWduKHRoaXMuc2Vjb25kYXJ5LnN0eWxlLCB7XG4gICAgICBkaXNwbGF5OiAnYmxvY2snLFxuICAgICAgb3BhY2l0eTogJzAuNycsXG4gICAgICBmb250U2l6ZTogJzExcHgnLFxuICAgICAgLy8gRXZlcnkgbGluZSBhZnRlciB0aGUgZmlyc3QgaXMgYSBkZXRhaWwgbGluZSwgb25lIHBlciByb3cuXG4gICAgICB3aGl0ZVNwYWNlOiAncHJlJyxcbiAgICB9IGFzIFBhcnRpYWw8Q1NTU3R5bGVEZWNsYXJhdGlvbj4pO1xuXG4gICAgdGhpcy5lbC5hcHBlbmQodGhpcy5wcmltYXJ5LCB0aGlzLnNlY29uZGFyeSk7XG4gICAgaG9zdC5hcHBlbmRDaGlsZCh0aGlzLmVsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTaG93IGBsaW5lc2AgYXQgYSBwb2ludCBnaXZlbiBpbiBIT1NULXJlbGF0aXZlIHBpeGVscy5cbiAgICpcbiAgICogRmxpcHMgdG8gdGhlIG90aGVyIHNpZGUgb2YgdGhlIGN1cnNvciBuZWFyIGFuIGVkZ2UgcmF0aGVyIHRoYW4gYmVpbmcgY2xpcHBlZFxuICAgKiBieSB0aGUgaG9zdCDigJQgYSB0b29sdGlwIGhhbGYgb3V0c2lkZSB0aGUgcGxvdCBpcyB3b3JzZSB0aGFuIG9uZSBvbiB0aGUgbGVmdC5cbiAgICovXG4gIHNob3cobGluZXM6IHJlYWRvbmx5IHN0cmluZ1tdLCBob3N0WDogbnVtYmVyLCBob3N0WTogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKGxpbmVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5oaWRlKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMucHJpbWFyeS50ZXh0Q29udGVudCA9IGxpbmVzWzBdO1xuICAgIGNvbnN0IGRldGFpbHMgPSBsaW5lcy5zbGljZSgxKS5maWx0ZXIoQm9vbGVhbik7XG4gICAgdGhpcy5zZWNvbmRhcnkudGV4dENvbnRlbnQgPSBkZXRhaWxzLmpvaW4oJ1xcbicpO1xuICAgIHRoaXMuc2Vjb25kYXJ5LnN0eWxlLmRpc3BsYXkgPSBkZXRhaWxzLmxlbmd0aCA/ICdibG9jaycgOiAnbm9uZSc7XG4gICAgLy8gTWVhc3VyZWQgd2hpbGUgdmlzaWJsZTogb2Zmc2V0V2lkdGggaXMgMCBvbiBhIGBkaXNwbGF5OiBub25lYCBlbGVtZW50LCBzb1xuICAgIC8vIHRoZSBmbGlwIGJlbG93IHdvdWxkIGFsd2F5cyB0aGluayB0aGUgYm94IGZpdHMuXG4gICAgdGhpcy5lbC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcblxuICAgIGNvbnN0IGdhcCA9IE5hcGFyaVNwYXRpYWxUb29sdGlwLk9GRlNFVDtcbiAgICBjb25zdCB3ID0gdGhpcy5lbC5vZmZzZXRXaWR0aDtcbiAgICBjb25zdCBoID0gdGhpcy5lbC5vZmZzZXRIZWlnaHQ7XG4gICAgY29uc3QgaG9zdFcgPSB0aGlzLmhvc3QuY2xpZW50V2lkdGg7XG4gICAgY29uc3QgaG9zdEggPSB0aGlzLmhvc3QuY2xpZW50SGVpZ2h0O1xuICAgIGNvbnN0IGxlZnQgPSBob3N0WCArIGdhcCArIHcgPiBob3N0VyA/IE1hdGgubWF4KDAsIGhvc3RYIC0gZ2FwIC0gdykgOiBob3N0WCArIGdhcDtcbiAgICBjb25zdCB0b3AgPSBob3N0WSArIGdhcCArIGggPiBob3N0SCA/IE1hdGgubWF4KDAsIGhvc3RZIC0gZ2FwIC0gaCkgOiBob3N0WSArIGdhcDtcbiAgICB0aGlzLmVsLnN0eWxlLmxlZnQgPSBgJHtNYXRoLnJvdW5kKGxlZnQpfXB4YDtcbiAgICB0aGlzLmVsLnN0eWxlLnRvcCA9IGAke01hdGgucm91bmQodG9wKX1weGA7XG4gIH1cblxuICBoaWRlKCk6IHZvaWQge1xuICAgIHRoaXMuZWwuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgfVxuXG4gIC8qKiBUcnVlIHdoaWxlIHRoZSBib3ggaXMgb24gc2NyZWVuIOKAlCBmb3IgdGVzdHMsIGFuZCB0byBza2lwIHJlZHVuZGFudCBoaWRlcy4gKi9cbiAgZ2V0IHZpc2libGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZWwuc3R5bGUuZGlzcGxheSAhPT0gJ25vbmUnO1xuICB9XG5cbiAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICB0aGlzLmVsLnJlbW92ZSgpO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import { heightField, histogramScalar } from 'napari-js';
|
|
2
|
+
import { formatLength } from 'napari-js/overlays';
|
|
3
|
+
import { Axes3dGizmo, surface3dControls } from './napari-axes-gizmo';
|
|
4
|
+
import { SURFACE_Z_ASPECT, VOLUME_FETCH_CONCURRENCY, isServerlessMultichannel, mapPool, stackDepth, surfaceResolutionFor, toIHistogram, toNapariGamma, } from './napari-helpers';
|
|
5
|
+
/**
|
|
6
|
+
* NAPARI_SURFACE (review Appendix B, cluster G): the slice as a height field. A height field is
|
|
7
|
+
* single-scalar, so for a multichannel image the surface follows ONE band — the pane-selected
|
|
8
|
+
* channel — coloured by that channel's window/colormap (like the Plotly SURFACE, which is
|
|
9
|
+
* grayscale-only). Every slice's plane is pre-loaded with a progress bar (as the volume does) so
|
|
10
|
+
* the stack slider re-slices instantly. All mesh + GPU work lives in napari-js (`heightField` +
|
|
11
|
+
* `Viewer.addSurface`); this scene supplies scalar slices.
|
|
12
|
+
*/
|
|
13
|
+
export class SurfaceScene {
|
|
14
|
+
constructor(ctx) {
|
|
15
|
+
this.ctx = ctx;
|
|
16
|
+
/** The height-field mesh (null until the first build). */
|
|
17
|
+
this.layer = null;
|
|
18
|
+
/** Which band the surface samples (a channel index for multichannel, else the composite). */
|
|
19
|
+
this.channel = undefined;
|
|
20
|
+
/** True when the surface follows one band of a multichannel image. */
|
|
21
|
+
this.multichannel = false;
|
|
22
|
+
/** Pre-loaded per-slice luminance planes (already decimated to the surface grid), keyed by z,
|
|
23
|
+
* so the stack slider rebuilds the surface instantly. Filled by {@link preloadPlanes}. */
|
|
24
|
+
this.planes = new Map();
|
|
25
|
+
/** The preload in flight; a newer one (a channel switch) aborts it. */
|
|
26
|
+
this.preload = null;
|
|
27
|
+
/** In-plane grid cap for this load (full grid ÷ the decimate factor). */
|
|
28
|
+
this.maxGrid = surfaceResolutionFor(1).maxGrid;
|
|
29
|
+
/** Contrast window [min,max] the current mesh was built with. A change reshapes the mesh (pixel
|
|
30
|
+
* height = intensity within [min,max]), so it triggers a geometry rebuild. */
|
|
31
|
+
this.window = null;
|
|
32
|
+
/** The current slice's plane, for the intensity histogram. */
|
|
33
|
+
this.histogramPlane = null;
|
|
34
|
+
this.gizmo = null;
|
|
35
|
+
this.displaySub = null;
|
|
36
|
+
}
|
|
37
|
+
async mount() {
|
|
38
|
+
const { ctx } = this;
|
|
39
|
+
const desc = await ctx.tiles.ensureDescriptor(ctx.info());
|
|
40
|
+
const info = ctx.info();
|
|
41
|
+
// Serverless multichannel (tiled:false + channelUrls) has no descriptor — detect
|
|
42
|
+
// it from imageMeta so the Surface still follows one band.
|
|
43
|
+
const simpleMc = isServerlessMultichannel(ctx.tiles.isSimple(info), info);
|
|
44
|
+
this.multichannel = simpleMc || (!!desc?.multichannel && (desc?.channels ?? 1) > 1);
|
|
45
|
+
// A height field is single-scalar → follow the pane-SELECTED channel.
|
|
46
|
+
this.channel = this.multichannel ? ctx.store.currentSelectedChannel() : undefined;
|
|
47
|
+
this.maxGrid = surfaceResolutionFor(ctx.settings.resolutionScale).maxGrid;
|
|
48
|
+
await this.preloadPlanes();
|
|
49
|
+
if (ctx.signal.aborted)
|
|
50
|
+
return;
|
|
51
|
+
await this.build(ctx.z());
|
|
52
|
+
this.installAxes();
|
|
53
|
+
// Subscribe after the first build so display-state edits target a live layer.
|
|
54
|
+
this.followDisplayState();
|
|
55
|
+
}
|
|
56
|
+
/** One slice → one mesh: re-build the height field for the new slice. Not built yet → nothing to
|
|
57
|
+
* do; the build at the end of the mount reads the current slice. */
|
|
58
|
+
setZ(z) {
|
|
59
|
+
if (!this.layer)
|
|
60
|
+
return;
|
|
61
|
+
void this.build(z).catch((err) => console.error('[napari-js] setZIndex surface failed:', err));
|
|
62
|
+
}
|
|
63
|
+
/** The current slice's intensity histogram (the plane the mesh was built from). */
|
|
64
|
+
histogram(_channel, bins) {
|
|
65
|
+
const plane = this.histogramPlane;
|
|
66
|
+
return plane ? toIHistogram(histogramScalar(plane, bins, 0, 255)) : null;
|
|
67
|
+
}
|
|
68
|
+
surface3dControls() {
|
|
69
|
+
return this.layer
|
|
70
|
+
? surface3dControls(this.ctx, () => this.gizmo, () => this.layer)
|
|
71
|
+
: null;
|
|
72
|
+
}
|
|
73
|
+
dispose() {
|
|
74
|
+
this.displaySub?.unsubscribe();
|
|
75
|
+
this.displaySub = null;
|
|
76
|
+
this.preload?.abort();
|
|
77
|
+
this.preload = null;
|
|
78
|
+
this.planes.clear();
|
|
79
|
+
this.gizmo?.destroy();
|
|
80
|
+
this.gizmo = null;
|
|
81
|
+
}
|
|
82
|
+
/** Add the axes gizmo + labels around the (origin-centered) mesh, matching the volume. The box
|
|
83
|
+
* tracks the mesh bounds, X/Y show the physical (or pixel) extent, and Z is the intensity axis. */
|
|
84
|
+
installAxes() {
|
|
85
|
+
if (!this.layer)
|
|
86
|
+
return;
|
|
87
|
+
const { ctx } = this;
|
|
88
|
+
const b = this.layer.bounds();
|
|
89
|
+
const boxW = Math.max(1, b.max[0] - b.min[0]);
|
|
90
|
+
const boxH = Math.max(1, b.max[1] - b.min[1]);
|
|
91
|
+
const boxD = Math.max(1, b.max[2] - b.min[2]);
|
|
92
|
+
const desc = ctx.tiles.currentDescriptor(ctx.info());
|
|
93
|
+
const mppX = ctx.tiles.mppX(ctx.info());
|
|
94
|
+
const imageW = ctx.imageSize().width;
|
|
95
|
+
const voxel = mppX > 0 ? (mppX * (desc?.width ?? imageW)) / Math.max(1, imageW) : 1;
|
|
96
|
+
this.gizmo = new Axes3dGizmo(ctx.viewer, ctx.host, { width: boxW, height: boxH, depth: boxD }, this.axesLabels(boxW, boxH, boxD, mppX), { visible: ctx.settings.axesVisible, voxelSize: [voxel, voxel, 1] });
|
|
97
|
+
}
|
|
98
|
+
/** X/Y/Z end-labels for the gizmo: X/Y are the physical (µm) or pixel extent of the FULL image;
|
|
99
|
+
* Z is the intensity/height axis. Anchors are in the centered box (matching AxesLayer). */
|
|
100
|
+
axesLabels(boxW, boxH, boxD, mppX) {
|
|
101
|
+
const hx = boxW / 2;
|
|
102
|
+
const hy = boxH / 2;
|
|
103
|
+
const hz = boxD / 2;
|
|
104
|
+
const desc = this.ctx.tiles.currentDescriptor(this.ctx.info());
|
|
105
|
+
const size = this.ctx.imageSize();
|
|
106
|
+
const descW = desc?.width ?? size.width;
|
|
107
|
+
const descH = desc?.height ?? size.height;
|
|
108
|
+
const len = (px) => (mppX > 0 ? formatLength(px * mppX, 'µm') : `${px} px`);
|
|
109
|
+
return [
|
|
110
|
+
{ anchor: [hx, -hy, -hz], text: `X · ${len(descW)}`, color: '#ed4545' },
|
|
111
|
+
{ anchor: [-hx, hy, -hz], text: `Y · ${len(descH)}`, color: '#4dd959' },
|
|
112
|
+
{ anchor: [-hx, -hy, hz], text: 'Z · intensity', color: '#668cff' },
|
|
113
|
+
];
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Pre-fetch every stack slice's luminance plane (decimated to the surface grid) into
|
|
117
|
+
* {@link planes}, driving the stack progress — the same load-with-progress UX as the volume, but
|
|
118
|
+
* keeping one 2D plane per slice rather than packing a 3D volume. Bounded concurrency keeps the
|
|
119
|
+
* connection pool busy without flooding it on a deep stack.
|
|
120
|
+
*/
|
|
121
|
+
async preloadPlanes() {
|
|
122
|
+
const { ctx } = this;
|
|
123
|
+
// A channel switch starts a new preload while this one may still be in flight: the newer
|
|
124
|
+
// one owns the plane cache and the progress bar from here on.
|
|
125
|
+
this.preload?.abort();
|
|
126
|
+
const preload = new AbortController();
|
|
127
|
+
this.preload = preload;
|
|
128
|
+
const loading = ctx.loading(); // bail on a Cancel / new plot while we fetch
|
|
129
|
+
const stale = () => preload.signal.aborted || loading.aborted || ctx.signal.aborted;
|
|
130
|
+
const depth = stackDepth(ctx.info()) || 1;
|
|
131
|
+
const { maxGrid } = surfaceResolutionFor(ctx.settings.resolutionScale);
|
|
132
|
+
this.planes.clear();
|
|
133
|
+
ctx.stack.loading(true);
|
|
134
|
+
ctx.stack.progress(0);
|
|
135
|
+
try {
|
|
136
|
+
let done = 0;
|
|
137
|
+
const slices = Array.from({ length: depth }, (_, z) => z);
|
|
138
|
+
await mapPool(slices, VOLUME_FETCH_CONCURRENCY, async (z) => {
|
|
139
|
+
try {
|
|
140
|
+
const plane = await this.fetchPlane(z, maxGrid);
|
|
141
|
+
// Superseded while in flight: this plane may be the OLD band, and the cache is not
|
|
142
|
+
// this preload's any more.
|
|
143
|
+
if (stale())
|
|
144
|
+
return;
|
|
145
|
+
this.planes.set(z, plane);
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
if (stale())
|
|
149
|
+
return;
|
|
150
|
+
console.warn(`[napari-js] surface slice ${z} preload failed`, err);
|
|
151
|
+
}
|
|
152
|
+
done++;
|
|
153
|
+
ctx.stack.progress(Math.round((done / depth) * 100));
|
|
154
|
+
}, stale);
|
|
155
|
+
}
|
|
156
|
+
finally {
|
|
157
|
+
// Only the newest preload ends the progress bar; a superseded one would hide it while
|
|
158
|
+
// its successor is still loading.
|
|
159
|
+
if (this.preload === preload) {
|
|
160
|
+
this.preload = null;
|
|
161
|
+
ctx.stack.loading(false);
|
|
162
|
+
ctx.stack.progress(0);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/** Slice `z` as a whole-image luminance plane of the surface's band, decimated to `maxGrid`. */
|
|
167
|
+
fetchPlane(z, maxGrid) {
|
|
168
|
+
return this.ctx.tiles.fetchPlane(this.ctx.info(), z, this.channel, maxGrid);
|
|
169
|
+
}
|
|
170
|
+
/** The channel state driving the surface: the chosen band for multichannel (matched by index),
|
|
171
|
+
* else the single grayscale channel. */
|
|
172
|
+
channelState(channels) {
|
|
173
|
+
if (this.channel == null)
|
|
174
|
+
return channels[0];
|
|
175
|
+
return channels.find((s) => s.index === this.channel) ?? channels[0];
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* (Re)build the mesh for slice `z` from the pre-loaded plane cache (instant — this is what the
|
|
179
|
+
* stack slider calls); a slice missing from the cache is fetched on demand. napari-js's pure
|
|
180
|
+
* `heightField` builds the triangle grid (z = normalized intensity), then `addSurface` renders
|
|
181
|
+
* it. The slice plane also feeds the intensity histogram.
|
|
182
|
+
*/
|
|
183
|
+
async build(z) {
|
|
184
|
+
const { ctx } = this;
|
|
185
|
+
let plane = this.planes.get(z);
|
|
186
|
+
if (!plane) {
|
|
187
|
+
ctx.stack.loading(true);
|
|
188
|
+
try {
|
|
189
|
+
plane = await this.fetchPlane(z, this.maxGrid);
|
|
190
|
+
this.planes.set(z, plane);
|
|
191
|
+
}
|
|
192
|
+
catch (err) {
|
|
193
|
+
console.error('[napari-js] surface slice fetch failed:', err);
|
|
194
|
+
}
|
|
195
|
+
finally {
|
|
196
|
+
ctx.stack.loading(false);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (!plane || plane.width < 2 || plane.height < 2 || ctx.signal.aborted)
|
|
200
|
+
return;
|
|
201
|
+
const st = this.channelState(ctx.store.currentChannelStates());
|
|
202
|
+
const win = [st?.min ?? 0, st?.max ?? 255];
|
|
203
|
+
this.window = win;
|
|
204
|
+
// Height AND colour are normalized by the same contrast window, so changing min/max reshapes the
|
|
205
|
+
// surface (a pixel's height = its intensity within [min,max]). Center it for the axes gizmo. The
|
|
206
|
+
// plane is already decimated to the grid cap → stride 1.
|
|
207
|
+
const zScale = SURFACE_Z_ASPECT * Math.max(plane.width, plane.height);
|
|
208
|
+
const { vertices, faces, values } = heightField(plane.data, plane.width, plane.height, {
|
|
209
|
+
zScale,
|
|
210
|
+
zLimits: win,
|
|
211
|
+
center: true,
|
|
212
|
+
});
|
|
213
|
+
// A re-slice / window rebuild keeps the orbit camera: the viewer's `fit3d: 'once'` frames only
|
|
214
|
+
// the scene's first 3D add, so stepping the stack or changing the window keeps the pose.
|
|
215
|
+
if (this.layer) {
|
|
216
|
+
ctx.viewer.layers.remove(this.layer);
|
|
217
|
+
this.layer = null;
|
|
218
|
+
}
|
|
219
|
+
this.layer = ctx.viewer.addSurface(vertices, faces, values, {
|
|
220
|
+
colormap: ctx.display.volumeColormap(st),
|
|
221
|
+
contrastLimits: win,
|
|
222
|
+
gamma: toNapariGamma(st?.gamma), // ImageJ γ → napari-js γ
|
|
223
|
+
invert: ctx.display.invert,
|
|
224
|
+
wireframe: ctx.settings.surfaceWireframe,
|
|
225
|
+
});
|
|
226
|
+
ctx.setImageSize(plane.width, plane.height);
|
|
227
|
+
this.histogramPlane = plane.data;
|
|
228
|
+
ctx.tools.scheduleReadback();
|
|
229
|
+
}
|
|
230
|
+
/** The store colormap / reverse / invert / channel window → the surface, so histogram & channel
|
|
231
|
+
* dialog edits update it live without a re-fetch. **min/max reshapes the surface's height** (a
|
|
232
|
+
* pixel's height = its intensity within [min,max]), so a window change rebuilds the mesh
|
|
233
|
+
* geometry (from the cached slice); colour-only edits (colormap/LUT, gamma, reverse, invert)
|
|
234
|
+
* just update the layer's uniforms. */
|
|
235
|
+
followDisplayState() {
|
|
236
|
+
const { ctx } = this;
|
|
237
|
+
this.displaySub = ctx.display.watch((channels, selected) => {
|
|
238
|
+
const layer = this.layer;
|
|
239
|
+
if (!layer || ctx.signal.aborted)
|
|
240
|
+
return;
|
|
241
|
+
// Selected channel changed (multichannel): re-fetch THAT band's planes and
|
|
242
|
+
// rebuild the height-field for the current slice.
|
|
243
|
+
if (this.multichannel && selected !== this.channel) {
|
|
244
|
+
this.channel = selected;
|
|
245
|
+
void (async () => {
|
|
246
|
+
await this.preloadPlanes();
|
|
247
|
+
if (!ctx.signal.aborted)
|
|
248
|
+
await this.build(ctx.z());
|
|
249
|
+
})().catch((err) => console.error('[napari-js] surface channel switch failed:', err));
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
const st = this.channelState(channels);
|
|
253
|
+
const win = [st?.min ?? 0, st?.max ?? 255];
|
|
254
|
+
const windowChanged = !this.window || win[0] !== this.window[0] || win[1] !== this.window[1];
|
|
255
|
+
if (windowChanged) {
|
|
256
|
+
// Height follows the contrast window → rebuild the mesh for the new [min,max] (camera kept).
|
|
257
|
+
void this.build(ctx.z()).catch((err) => console.error('[napari-js] surface window rebuild failed:', err));
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
// Colour-only change: update uniforms in place, no geometry rebuild.
|
|
261
|
+
layer.colormap = ctx.display.volumeColormap(st);
|
|
262
|
+
layer.invert = ctx.display.invert;
|
|
263
|
+
if (st) {
|
|
264
|
+
layer.contrastLimits = win;
|
|
265
|
+
layer.gamma = toNapariGamma(st.gamma); // ImageJ γ → napari-js γ
|
|
266
|
+
}
|
|
267
|
+
ctx.viewer.requestRender();
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFwYXJpLXN1cmZhY2Utc2NlbmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2ltcGxlbWVudGF0aW9ucy9uYXBhcmktanMvbmFwYXJpLXN1cmZhY2Utc2NlbmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFekQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBS2xELE9BQU8sRUFBRSxXQUFXLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNyRSxPQUFPLEVBRUwsZ0JBQWdCLEVBQ2hCLHdCQUF3QixFQUN4Qix3QkFBd0IsRUFDeEIsT0FBTyxFQUNQLFVBQVUsRUFDVixvQkFBb0IsRUFDcEIsWUFBWSxFQUNaLGFBQWEsR0FDZCxNQUFNLGtCQUFrQixDQUFDO0FBRzFCOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLE9BQU8sWUFBWTtJQXNCdkIsWUFBNkIsR0FBaUI7UUFBakIsUUFBRyxHQUFILEdBQUcsQ0FBYztRQXJCOUMsMERBQTBEO1FBQzFELFVBQUssR0FBd0IsSUFBSSxDQUFDO1FBQ2xDLDZGQUE2RjtRQUNyRixZQUFPLEdBQXVCLFNBQVMsQ0FBQztRQUNoRCxzRUFBc0U7UUFDOUQsaUJBQVksR0FBRyxLQUFLLENBQUM7UUFDN0I7bUdBQzJGO1FBQ2xGLFdBQU0sR0FBRyxJQUFJLEdBQUcsRUFBcUIsQ0FBQztRQUMvQyx1RUFBdUU7UUFDL0QsWUFBTyxHQUEyQixJQUFJLENBQUM7UUFDL0MseUVBQXlFO1FBQ2pFLFlBQU8sR0FBRyxvQkFBb0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7UUFDbEQ7dUZBQytFO1FBQ3ZFLFdBQU0sR0FBNEIsSUFBSSxDQUFDO1FBQy9DLDhEQUE4RDtRQUN0RCxtQkFBYyxHQUFzQixJQUFJLENBQUM7UUFDekMsVUFBSyxHQUF1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QUN0QixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztJQUNwQixDQUFDO0lBRUQ7d0dBQ29HO0lBQzVGLFdBQVc7UUFDakIsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLO1lBQUUsT0FBTztRQUN4QixNQUFNLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO1FBQ3JCLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDOUIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDOUMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDOUMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDOUMsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNyRCxNQUFNLElBQUksR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN4QyxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsU0FBUyxFQUFFLENBQUMsS0FBSyxDQUFDO1FBQ3JDLE1BQU0sS0FBSyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsSUFBSSxFQUFFLEtBQUssSUFBSSxNQUFN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QUksR0FBRyxDQUFDLENBQUM7WUFDN0QsTUFBTSxhQUFhLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzdGLElBQUksYUFBYSxFQUFFLENBQUM7Z0JBQ2xCLDZGQUE2RjtnQkFDN0YsS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyw0Q0FBNEMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUMxRyxPQUFPO1lBQ1QsQ0FBQztZQUNELHFFQUFxRTtZQUNyRSxLQUFLLENBQUMsUUFBUSxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2hELEtBQUssQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7WUFDbEMsSUFBSSxFQUFFLEVBQUUsQ0FBQztnQkFDUCxLQUFLLENBQUMsY0FBYyxHQUFHLEdBQUcsQ0FBQztnQkFDM0IsS0FBSyxDQUFDLEtBQUssR0FBRyxhQUFhLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMseUJBQXlCO1lBQ2xFLENBQUM7WUFDRCxHQUFHLENBQUMsTUFBTSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQzdCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBoZWlnaHRGaWVsZCwgaGlzdG9ncmFtU2NhbGFyIH0gZnJvbSAnbmFwYXJpLWpzJztcbmltcG9ydCB0eXBlIHsgU3VyZmFjZUxheWVyIH0gZnJvbSAnbmFwYXJpLWpzJztcbmltcG9ydCB7IGZvcm1hdExlbmd0aCB9IGZyb20gJ25hcGFyaS1qcy9vdmVybGF5cyc7XG5pbXBvcnQgdHlwZSB7IEF4aXNMYWJlbFNwZWMgfSBmcm9tICduYXBhcmktanMvb3ZlcmxheXMnO1xuXG5pbXBvcnQgeyBJQ2hhbm5lbFN0YXRlLCBJSGlzdG9ncmFtIH0gZnJvbSAnLi4vLi4vY29udHJhY3RzL2NoYW5uZWwtaGlzdG9ncmFtLWFwaS5jb250cmFjdCc7XG5pbXBvcnQgeyBJU3VyZmFjZTNkQ29udHJvbHMgfSBmcm9tICcuLi8uLi9jb250cmFjdHMvdmlzdWFsaXplci5jb250cmFjdCc7XG5pbXBvcnQgeyBBeGVzM2RHaXptbywgc3VyZmFjZTNkQ29udHJvbHMgfSBmcm9tICcuL25hcGFyaS1heGVzLWdpem1vJztcbmltcG9ydCB7XG4gIEx1bWFQbGFuZSxcbiAgU1VSRkFDRV9aX0FTUEVDVCxcbiAgVk9MVU1FX0ZFVENIX0NPTkNVUlJFTkNZLFxuICBpc1NlcnZlcmxlc3NNdWx0aWNoYW5uZWwsXG4gIG1hcFBvb2wsXG4gIHN0YWNrRGVwdGgsXG4gIHN1cmZhY2VSZXNvbHV0aW9uRm9yLFxuICB0b0lIaXN0b2dyYW0sXG4gIHRvTmFwYXJpR2FtbWEsXG59IGZyb20gJy4vbmFwYXJpLWhlbHBlcnMnO1xuaW1wb3J0IHR5cGUgeyBOYXBhcmlTY2VuZSwgU2NlbmVDb250ZXh0IH0gZnJvbSAnLi9uYXBhcmktc2NlbmUnO1xuXG4vKipcbiAqIE5BUEFSSV9TVVJGQUNFIChyZXZpZXcgQXBwZW5kaXggQiwgY2x1c3RlciBHKTogdGhlIHNsaWNlIGFzIGEgaGVpZ2h0IGZpZWxkLiBBIGhlaWdodCBmaWVsZCBpc1xuICogc2luZ2xlLXNjYWxhciwgc28gZm9yIGEgbXVsdGljaGFubmVsIGltYWdlIHRoZSBzdXJmYWNlIGZvbGxvd3MgT05FIGJhbmQg4oCUIHRoZSBwYW5lLXNlbGVjdGVkXG4gKiBjaGFubmVsIOKAlCBjb2xvdXJlZCBieSB0aGF0IGNoYW5uZWwncyB3aW5kb3cvY29sb3JtYXAgKGxpa2UgdGhlIFBsb3RseSBTVVJGQUNFLCB3aGljaCBpc1xuICogZ3JheXNjYWxlLW9ubHkpLiBFdmVyeSBzbGljZSdzIHBsYW5lIGlzIHByZS1sb2FkZWQgd2l0aCBhIHByb2dyZXNzIGJhciAoYXMgdGhlIHZvbHVtZSBkb2VzKSBzb1xuICogdGhlIHN0YWNrIHNsaWRlciByZS1zbGljZXMgaW5zdGFudGx5LiBBbGwgbWVzaCArIEdQVSB3b3JrIGxpdmVzIGluIG5hcGFyaS1qcyAoYGhlaWdodEZpZWxkYCArXG4gKiBgVmlld2VyLmFkZFN1cmZhY2VgKTsgdGhpcyBzY2VuZSBzdXBwbGllcyBzY2FsYXIgc2xpY2VzLlxuICovXG5leHBvcnQgY2xhc3MgU3VyZmFjZVNjZW5lIGltcGxlbWVudHMgTmFwYXJpU2NlbmUge1xuICAvKiogVGhlIGhlaWdodC1maWVsZCBtZXNoIChudWxsIHVudGlsIHRoZSBmaXJzdCBidWlsZCkuICovXG4gIGxheWVyOiBTdXJmYWNlTGF5ZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqIFdoaWNoIGJhbmQgdGhlIHN1cmZhY2Ugc2FtcGxlcyAoYSBjaGFubmVsIGluZGV4IGZvciBtdWx0aWNoYW5uZWwsIGVsc2UgdGhlIGNvbXBvc2l0ZSkuICovXG4gIHByaXZhdGUgY2hhbm5lbDogbnVtYmVyIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAvKiogVHJ1ZSB3aGVuIHRoZSBzdXJmYWNlIGZvbGxvd3Mgb25lIGJhbmQgb2YgYSBtdWx0aWNoYW5uZWwgaW1hZ2UuICovXG4gIHByaXZhdGUgbXVsdGljaGFubmVsID0gZmFsc2U7XG4gIC8qKiBQcmUtbG9hZGVkIHBlci1zbGljZSBsdW1pbmFuY2UgcGxhbmVzIChhbHJlYWR5IGRlY2ltYXRlZCB0byB0aGUgc3VyZmFjZSBncmlkKSwga2V5ZWQgYnkgeixcbiAgICogIHNvIHRoZSBzdGFjayBzbGlkZXIgcmVidWlsZHMgdGhlIHN1cmZhY2UgaW5zdGFudGx5LiBGaWxsZWQgYnkge0BsaW5rIHByZWxvYWRQbGFuZXN9LiAqL1xuICByZWFkb25seSBwbGFuZXMgPSBuZXcgTWFwPG51bWJlciwgTHVtYVBsYW5lPigpO1xuICAvKiogVGhlIHByZWxvYWQgaW4gZmxpZ2h0OyBhIG5ld2VyIG9uZSAoYSBjaGFubmVsIHN3aXRjaCkgYWJvcnRzIGl0LiAqL1xuICBwcml2YXRlIHByZWxvYWQ6IEFib3J0Q29udHJvbGxlciB8IG51bGwgPSBudWxsO1xuICAvKiogSW4tcGxhbmUgZ3JpZCBjYXAgZm9yIHRoaXMgbG9hZCAoZnVsbCBncmlkIMO3IHRoZSBkZWNpbWF0ZSBmYWN0b3IpLiAqL1xuICBwcml2YXRlIG1heEdyaWQgPSBzdXJmYWNlUmVzb2x1dGlvbkZvcigxKS5tYXhHcmlkO1xuICAvKiogQ29udHJhc3Qgd2luZG93IFttaW4sbWF4XSB0aGUgY3VycmVudCBtZXNoIHdhcyBidWlsdCB3aXRoLiBBIGNoYW5nZSByZXNoYXBlcyB0aGUgbWVzaCAocGl4ZWxcbiAgICogIGhlaWdodCA9IGludGVuc2l0eSB3aXRoaW4gW21pbixtYXhdKSwgc28gaXQgdHJpZ2dlcnMgYSBnZW9tZXRyeSByZWJ1aWxkLiAqL1xuICBwcml2YXRlIHdpbmRvdzogW251bWJlciwgbnVtYmVyXSB8IG51bGwgPSBudWxsO1xuICAvKiogVGhlIGN1cnJlbnQgc2xpY2UncyBwbGFuZSwgZm9yIHRoZSBpbnRlbnNpdHkgaGlzdG9ncmFtLiAqL1xuICBwcml2YXRlIGhpc3RvZ3JhbVBsYW5lOiBVaW50OEFycmF5IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgZ2l6bW86IEF4ZXMzZEdpem1vIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgZGlzcGxheVN1YjogU3Vic2NyaXB0aW9uIHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBjdHg6IFNjZW5lQ29udGV4dCkge31cblxuICBhc3luYyBtb3VudCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB7IGN0eCB9ID0gdGhpcztcbiAgICBjb25zdCBkZXNjID0gYXdhaXQgY3R4LnRpbGVzLmVuc3VyZURlc2NyaXB0b3IoY3R4LmluZm8oKSk7XG4gICAgY29uc3QgaW5mbyA9IGN0eC5pbmZvKCk7XG4gICAgLy8gU2VydmVybGVzcyBtdWx0aWNoYW5uZWwgKHRpbGVkOmZhbHNlICsgY2hhbm5lbFVybHMpIGhhcyBubyBkZXNjcmlwdG9yIOKAlCBkZXRlY3RcbiAgICAvLyBpdCBmcm9tIGltYWdlTWV0YSBzbyB0aGUgU3VyZmFjZSBzdGlsbCBmb2xsb3dzIG9uZSBiYW5kLlxuICAgIGNvbnN0IHNpbXBsZU1jID0gaXNTZXJ2ZXJsZXNzTXVsdGljaGFubmVsKGN0eC50aWxlcy5pc1NpbXBsZShpbmZvKSwgaW5mbyk7XG4gICAgdGhpcy5tdWx0aWNoYW5uZWwgPSBzaW1wbGVNYyB8fCAoISFkZXNjPy5tdWx0aWNoYW5uZWwgJiYgKGRlc2M/LmNoYW5uZWxzID8/IDEpID4gMSk7XG4gICAgLy8gQSBoZWlnaHQgZmllbGQgaXMgc2luZ2xlLXNjYWxhciDihpIgZm9sbG93IHRoZSBwYW5lLVNFTEVDVEVEIGNoYW5uZWwuXG4gICAgdGhpcy5jaGFubmVsID0gdGhpcy5tdWx0aWNoYW5uZWwgPyBjdHguc3RvcmUuY3VycmVudFNlbGVjdGVkQ2hhbm5lbCgpIDogdW5kZWZpbmVkO1xuICAgIHRoaXMubWF4R3JpZCA9IHN1cmZhY2VSZXNvbHV0aW9uRm9yKGN0eC5zZXR0aW5ncy5yZXNvbHV0aW9uU2NhbGUpLm1heEdyaWQ7XG4gICAgYXdhaXQgdGhpcy5wcmVsb2FkUGxhbmVzKCk7XG4gICAgaWYgKGN0eC5zaWduYWwuYWJvcnRlZCkgcmV0dXJuO1xuICAgIGF3YWl0IHRoaXMuYnVpbGQoY3R4LnooKSk7XG4gICAgdGhpcy5pbnN0YWxsQXhlcygpO1xuICAgIC8vIFN1YnNjcmliZSBhZnRlciB0aGUgZmlyc3QgYnVpbGQgc28gZGlzcGxheS1zdGF0ZSBlZGl0cyB0YXJnZXQgYSBsaXZlIGxheWVyLlxuICAgIHRoaXMuZm9sbG93RGlzcGxheVN0YXRlKCk7XG4gIH1cblxuICAvKiogT25lIHNsaWNlIOKGkiBvbmUgbWVzaDogcmUtYnVpbGQgdGhlIGhlaWdodCBmaWVsZCBmb3IgdGhlIG5ldyBzbGljZS4gTm90IGJ1aWx0IHlldCDihpIgbm90aGluZyB0b1xuICAgKiAgZG87IHRoZSBidWlsZCBhdCB0aGUgZW5kIG9mIHRoZSBtb3VudCByZWFkcyB0aGUgY3VycmVudCBzbGljZS4gKi9cbiAgc2V0Wih6OiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMubGF5ZXIpIHJldHVybjtcbiAgICB2b2lkIHRoaXMuYnVpbGQoeikuY2F0Y2goKGVycikgPT4gY29uc29sZS5lcnJvcignW25hcGFyaS1qc10gc2V0WkluZGV4IHN1cmZhY2UgZmFpbGVkOicsIGVycikpO1xuICB9XG5cbiAgLyoqIFRoZSBjdXJyZW50IHNsaWNlJ3MgaW50ZW5zaXR5IGhpc3RvZ3JhbSAodGhlIHBsYW5lIHRoZSBtZXNoIHdhcyBidWlsdCBmcm9tKS4gKi9cbiAgaGlzdG9ncmFtKF9jaGFubmVsOiBudW1iZXIsIGJpbnM6IG51bWJlcik6IElIaXN0b2dyYW0gfCBudWxsIHtcbiAgICBjb25zdCBwbGFuZSA9IHRoaXMuaGlzdG9ncmFtUGxhbmU7XG4gICAgcmV0dXJuIHBsYW5lID8gdG9JSGlzdG9ncmFtKGhpc3RvZ3JhbVNjYWxhcihwbGFuZSwgYmlucywgMCwgMjU1KSkgOiBudWxsO1xuICB9XG5cbiAgc3VyZmFjZTNkQ29udHJvbHMoKTogSVN1cmZhY2UzZENvbnRyb2xzIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMubGF5ZXJcbiAgICAgID8gc3VyZmFjZTNkQ29udHJvbHMoXG4gICAgICAgICAgdGhpcy5jdHgsXG4gICAgICAgICAgKCkgPT4gdGhpcy5naXptbyxcbiAgICAgICAgICAoKSA9PiB0aGlzLmxheWVyLFxuICAgICAgICApXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIHRoaXMuZGlzcGxheVN1Yj8udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLmRpc3BsYXlTdWIgPSBudWxsO1xuICAgIHRoaXMucHJlbG9hZD8uYWJvcnQoKTtcbiAgICB0aGlzLnByZWxvYWQgPSBudWxsO1xuICAgIHRoaXMucGxhbmVzLmNsZWFyKCk7XG4gICAgdGhpcy5naXptbz8uZGVzdHJveSgpO1xuICAgIHRoaXMuZ2l6bW8gPSBudWxsO1xuICB9XG5cbiAgLyoqIEFkZCB0aGUgYXhlcyBnaXptbyArIGxhYmVscyBhcm91bmQgdGhlIChvcmlnaW4tY2VudGVyZWQpIG1lc2gsIG1hdGNoaW5nIHRoZSB2b2x1bWUuIFRoZSBib3hcbiAgICogIHRyYWNrcyB0aGUgbWVzaCBib3VuZHMsIFgvWSBzaG93IHRoZSBwaHlzaWNhbCAob3IgcGl4ZWwpIGV4dGVudCwgYW5kIFogaXMgdGhlIGludGVuc2l0eSBheGlzLiAqL1xuICBwcml2YXRlIGluc3RhbGxBeGVzKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5sYXllcikgcmV0dXJuO1xuICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzO1xuICAgIGNvbnN0IGIgPSB0aGlzLmxheWVyLmJvdW5kcygpO1xuICAgIGNvbnN0IGJveFcgPSBNYXRoLm1heCgxLCBiLm1heFswXSAtIGIubWluWzBdKTtcbiAgICBjb25zdCBib3hIID0gTWF0aC5tYXgoMSwgYi5tYXhbMV0gLSBiLm1pblsxXSk7XG4gICAgY29uc3QgYm94RCA9IE1hdGgubWF4KDEsIGIubWF4WzJdIC0gYi5taW5bMl0pO1xuICAgIGNvbnN0IGRlc2MgPSBjdHgudGlsZXMuY3VycmVudERlc2NyaXB0b3IoY3R4LmluZm8oKSk7XG4gICAgY29uc3QgbXBwWCA9IGN0eC50aWxlcy5tcHBYKGN0eC5pbmZvKCkpO1xuICAgIGNvbnN0IGltYWdlVyA9IGN0eC5pbWFnZVNpemUoKS53aWR0aDtcbiAgICBjb25zdCB2b3hlbCA9IG1wcFggPiAwID8gKG1wcFggKiAoZGVzYz8ud2lkdGggPz8gaW1hZ2VXKSkgLyBNYXRoLm1heCgxLCBpbWFnZVcpIDogMTtcbiAgICB0aGlzLmdpem1vID0gbmV3IEF4ZXMzZEdpem1vKFxuICAgICAgY3R4LnZpZXdlcixcbiAgICAgIGN0eC5ob3N0LFxuICAgICAgeyB3aWR0aDogYm94VywgaGVpZ2h0OiBib3hILCBkZXB0aDogYm94RCB9LFxuICAgICAgdGhpcy5heGVzTGFiZWxzKGJveFcsIGJveEgsIGJveEQsIG1wcFgpLFxuICAgICAgeyB2aXNpYmxlOiBjdHguc2V0dGluZ3MuYXhlc1Zpc2libGUsIHZveGVsU2l6ZTogW3ZveGVsLCB2b3hlbCwgMV0gfSxcbiAgICApO1xuICB9XG5cbiAgLyoqIFgvWS9aIGVuZC1sYWJlbHMgZm9yIHRoZSBnaXptbzogWC9ZIGFyZSB0aGUgcGh5c2ljYWwgKMK1bSkgb3IgcGl4ZWwgZXh0ZW50IG9mIHRoZSBGVUxMIGltYWdlO1xuICAgKiAgWiBpcyB0aGUgaW50ZW5zaXR5L2hlaWdodCBheGlzLiBBbmNob3JzIGFyZSBpbiB0aGUgY2VudGVyZWQgYm94IChtYXRjaGluZyBBeGVzTGF5ZXIpLiAqL1xuICBwcml2YXRlIGF4ZXNMYWJlbHMoYm94VzogbnVtYmVyLCBib3hIOiBudW1iZXIsIGJveEQ6IG51bWJlciwgbXBwWDogbnVtYmVyKTogQXhpc0xhYmVsU3BlY1tdIHtcbiAgICBjb25zdCBoeCA9IGJveFcgLyAyO1xuICAgIGNvbnN0IGh5ID0gYm94SCAvIDI7XG4gICAgY29uc3QgaHogPSBib3hEIC8gMjtcbiAgICBjb25zdCBkZXNjID0gdGhpcy5jdHgudGlsZXMuY3VycmVudERlc2NyaXB0b3IodGhpcy5jdHguaW5mbygpKTtcbiAgICBjb25zdCBzaXplID0gdGhpcy5jdHguaW1hZ2VTaXplKCk7XG4gICAgY29uc3QgZGVzY1cgPSBkZXNjPy53aWR0aCA/PyBzaXplLndpZHRoO1xuICAgIGNvbnN0IGRlc2NIID0gZGVzYz8uaGVpZ2h0ID8/IHNpemUuaGVpZ2h0O1xuICAgIGNvbnN0IGxlbiA9IChweDogbnVtYmVyKTogc3RyaW5nID0+IChtcHBYID4gMCA/IGZvcm1hdExlbmd0aChweCAqIG1wcFgsICfCtW0nKSA6IGAke3B4fSBweGApO1xuICAgIHJldHVybiBbXG4gICAgICB7IGFuY2hvcjogW2h4LCAtaHksIC1oel0sIHRleHQ6IGBYIMK3ICR7bGVuKGRlc2NXKX1gLCBjb2xvcjogJyNlZDQ1NDUnIH0sXG4gICAgICB7IGFuY2hvcjogWy1oeCwgaHksIC1oel0sIHRleHQ6IGBZIMK3ICR7bGVuKGRlc2NIKX1gLCBjb2xvcjogJyM0ZGQ5NTknIH0sXG4gICAgICB7IGFuY2hvcjogWy1oeCwgLWh5LCBoel0sIHRleHQ6ICdaIMK3IGludGVuc2l0eScsIGNvbG9yOiAnIzY2OGNmZicgfSxcbiAgICBdO1xuICB9XG5cbiAgLyoqXG4gICAqIFByZS1mZXRjaCBldmVyeSBzdGFjayBzbGljZSdzIGx1bWluYW5jZSBwbGFuZSAoZGVjaW1hdGVkIHRvIHRoZSBzdXJmYWNlIGdyaWQpIGludG9cbiAgICoge0BsaW5rIHBsYW5lc30sIGRyaXZpbmcgdGhlIHN0YWNrIHByb2dyZXNzIOKAlCB0aGUgc2FtZSBsb2FkLXdpdGgtcHJvZ3Jlc3MgVVggYXMgdGhlIHZvbHVtZSwgYnV0XG4gICAqIGtlZXBpbmcgb25lIDJEIHBsYW5lIHBlciBzbGljZSByYXRoZXIgdGhhbiBwYWNraW5nIGEgM0Qgdm9sdW1lLiBCb3VuZGVkIGNvbmN1cnJlbmN5IGtlZXBzIHRoZVxuICAgKiBjb25uZWN0aW9uIHBvb2wgYnVzeSB3aXRob3V0IGZsb29kaW5nIGl0IG9uIGEgZGVlcCBzdGFjay5cbiAgICovXG4gIGFzeW5jIHByZWxvYWRQbGFuZXMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgeyBjdHggfSA9IHRoaXM7XG4gICAgLy8gQSBjaGFubmVsIHN3aXRjaCBzdGFydHMgYSBuZXcgcHJlbG9hZCB3aGlsZSB0aGlzIG9uZSBtYXkgc3RpbGwgYmUgaW4gZmxpZ2h0OiB0aGUgbmV3ZXJcbiAgICAvLyBvbmUgb3ducyB0aGUgcGxhbmUgY2FjaGUgYW5kIHRoZSBwcm9ncmVzcyBiYXIgZnJvbSBoZXJlIG9uLlxuICAgIHRoaXMucHJlbG9hZD8uYWJvcnQoKTtcbiAgICBjb25zdCBwcmVsb2FkID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuICAgIHRoaXMucHJlbG9hZCA9IHByZWxvYWQ7XG4gICAgY29uc3QgbG9hZGluZyA9IGN0eC5sb2FkaW5nKCk7IC8vIGJhaWwgb24gYSBDYW5jZWwgLyBuZXcgcGxvdCB3aGlsZSB3ZSBmZXRjaFxuICAgIGNvbnN0IHN0YWxlID0gKCk6IGJvb2xlYW4gPT4gcHJlbG9hZC5zaWduYWwuYWJvcnRlZCB8fCBsb2FkaW5nLmFib3J0ZWQgfHwgY3R4LnNpZ25hbC5hYm9ydGVkO1xuICAgIGNvbnN0IGRlcHRoID0gc3RhY2tEZXB0aChjdHguaW5mbygpKSB8fCAxO1xuICAgIGNvbnN0IHsgbWF4R3JpZCB9ID0gc3VyZmFjZVJlc29sdXRpb25Gb3IoY3R4LnNldHRpbmdzLnJlc29sdXRpb25TY2FsZSk7XG4gICAgdGhpcy5wbGFuZXMuY2xlYXIoKTtcbiAgICBjdHguc3RhY2subG9hZGluZyh0cnVlKTtcbiAgICBjdHguc3RhY2sucHJvZ3Jlc3MoMCk7XG4gICAgdHJ5IHtcbiAgICAgIGxldCBkb25lID0gMDtcbiAgICAgIGNvbnN0IHNsaWNlcyA9IEFycmF5LmZyb20oeyBsZW5ndGg6IGRlcHRoIH0sIChfLCB6KSA9PiB6KTtcbiAgICAgIGF3YWl0IG1hcFBvb2woXG4gICAgICAgIHNsaWNlcyxcbiAgICAgICAgVk9MVU1FX0ZFVENIX0NPTkNVUlJFTkNZLFxuICAgICAgICBhc3luYyAoeikgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBwbGFuZSA9IGF3YWl0IHRoaXMuZmV0Y2hQbGFuZSh6LCBtYXhHcmlkKTtcbiAgICAgICAgICAgIC8vIFN1cGVyc2VkZWQgd2hpbGUgaW4gZmxpZ2h0OiB0aGlzIHBsYW5lIG1heSBiZSB0aGUgT0xEIGJhbmQsIGFuZCB0aGUgY2FjaGUgaXMgbm90XG4gICAgICAgICAgICAvLyB0aGlzIHByZWxvYWQncyBhbnkgbW9yZS5cbiAgICAgICAgICAgIGlmIChzdGFsZSgpKSByZXR1cm47XG4gICAgICAgICAgICB0aGlzLnBsYW5lcy5zZXQoeiwgcGxhbmUpO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgaWYgKHN0YWxlKCkpIHJldHVybjtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihgW25hcGFyaS1qc10gc3VyZmFjZSBzbGljZSAke3p9IHByZWxvYWQgZmFpbGVkYCwgZXJyKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZG9uZSsrO1xuICAgICAgICAgIGN0eC5zdGFjay5wcm9ncmVzcyhNYXRoLnJvdW5kKChkb25lIC8gZGVwdGgpICogMTAwKSk7XG4gICAgICAgIH0sXG4gICAgICAgIHN0YWxlLFxuICAgICAgKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgLy8gT25seSB0aGUgbmV3ZXN0IHByZWxvYWQgZW5kcyB0aGUgcHJvZ3Jlc3MgYmFyOyBhIHN1cGVyc2VkZWQgb25lIHdvdWxkIGhpZGUgaXQgd2hpbGVcbiAgICAgIC8vIGl0cyBzdWNjZXNzb3IgaXMgc3RpbGwgbG9hZGluZy5cbiAgICAgIGlmICh0aGlzLnByZWxvYWQgPT09IHByZWxvYWQpIHtcbiAgICAgICAgdGhpcy5wcmVsb2FkID0gbnVsbDtcbiAgICAgICAgY3R4LnN0YWNrLmxvYWRpbmcoZmFsc2UpO1xuICAgICAgICBjdHguc3RhY2sucHJvZ3Jlc3MoMCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqIFNsaWNlIGB6YCBhcyBhIHdob2xlLWltYWdlIGx1bWluYW5jZSBwbGFuZSBvZiB0aGUgc3VyZmFjZSdzIGJhbmQsIGRlY2ltYXRlZCB0byBgbWF4R3JpZGAuICovXG4gIGZldGNoUGxhbmUoejogbnVtYmVyLCBtYXhHcmlkOiBudW1iZXIpOiBQcm9taXNlPEx1bWFQbGFuZT4ge1xuICAgIHJldHVybiB0aGlzLmN0eC50aWxlcy5mZXRjaFBsYW5lKHRoaXMuY3R4LmluZm8oKSwgeiwgdGhpcy5jaGFubmVsLCBtYXhHcmlkKTtcbiAgfVxuXG4gIC8qKiBUaGUgY2hhbm5lbCBzdGF0ZSBkcml2aW5nIHRoZSBzdXJmYWNlOiB0aGUgY2hvc2VuIGJhbmQgZm9yIG11bHRpY2hhbm5lbCAobWF0Y2hlZCBieSBpbmRleCksXG4gICAqICBlbHNlIHRoZSBzaW5nbGUgZ3JheXNjYWxlIGNoYW5uZWwuICovXG4gIHByaXZhdGUgY2hhbm5lbFN0YXRlKGNoYW5uZWxzOiBJQ2hhbm5lbFN0YXRlW10pOiBJQ2hhbm5lbFN0YXRlIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAodGhpcy5jaGFubmVsID09IG51bGwpIHJldHVybiBjaGFubmVsc1swXTtcbiAgICByZXR1cm4gY2hhbm5lbHMuZmluZCgocykgPT4gcy5pbmRleCA9PT0gdGhpcy5jaGFubmVsKSA/PyBjaGFubmVsc1swXTtcbiAgfVxuXG4gIC8qKlxuICAgKiAoUmUpYnVpbGQgdGhlIG1lc2ggZm9yIHNsaWNlIGB6YCBmcm9tIHRoZSBwcmUtbG9hZGVkIHBsYW5lIGNhY2hlIChpbnN0YW50IOKAlCB0aGlzIGlzIHdoYXQgdGhlXG4gICAqIHN0YWNrIHNsaWRlciBjYWxscyk7IGEgc2xpY2UgbWlzc2luZyBmcm9tIHRoZSBjYWNoZSBpcyBmZXRjaGVkIG9uIGRlbWFuZC4gbmFwYXJpLWpzJ3MgcHVyZVxuICAgKiBgaGVpZ2h0RmllbGRgIGJ1aWxkcyB0aGUgdHJpYW5nbGUgZ3JpZCAoeiA9IG5vcm1hbGl6ZWQgaW50ZW5zaXR5KSwgdGhlbiBgYWRkU3VyZmFjZWAgcmVuZGVyc1xuICAgKiBpdC4gVGhlIHNsaWNlIHBsYW5lIGFsc28gZmVlZHMgdGhlIGludGVuc2l0eSBoaXN0b2dyYW0uXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGJ1aWxkKHo6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzO1xuICAgIGxldCBwbGFuZSA9IHRoaXMucGxhbmVzLmdldCh6KTtcbiAgICBpZiAoIXBsYW5lKSB7XG4gICAgICBjdHguc3RhY2subG9hZGluZyh0cnVlKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHBsYW5lID0gYXdhaXQgdGhpcy5mZXRjaFBsYW5lKHosIHRoaXMubWF4R3JpZCk7XG4gICAgICAgIHRoaXMucGxhbmVzLnNldCh6LCBwbGFuZSk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignW25hcGFyaS1qc10gc3VyZmFjZSBzbGljZSBmZXRjaCBmYWlsZWQ6JywgZXJyKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGN0eC5zdGFjay5sb2FkaW5nKGZhbHNlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKCFwbGFuZSB8fCBwbGFuZS53aWR0aCA8IDIgfHwgcGxhbmUuaGVpZ2h0IDwgMiB8fCBjdHguc2lnbmFsLmFib3J0ZWQpIHJldHVybjtcblxuICAgIGNvbnN0IHN0ID0gdGhpcy5jaGFubmVsU3RhdGUoY3R4LnN0b3JlLmN1cnJlbnRDaGFubmVsU3RhdGVzKCkpO1xuICAgIGNvbnN0IHdpbjogW251bWJlciwgbnVtYmVyXSA9IFtzdD8ubWluID8/IDAsIHN0Py5tYXggPz8gMjU1XTtcbiAgICB0aGlzLndpbmRvdyA9IHdpbjtcbiAgICAvLyBIZWlnaHQgQU5EIGNvbG91ciBhcmUgbm9ybWFsaXplZCBieSB0aGUgc2FtZSBjb250cmFzdCB3aW5kb3csIHNvIGNoYW5naW5nIG1pbi9tYXggcmVzaGFwZXMgdGhlXG4gICAgLy8gc3VyZmFjZSAoYSBwaXhlbCdzIGhlaWdodCA9IGl0cyBpbnRlbnNpdHkgd2l0aGluIFttaW4sbWF4XSkuIENlbnRlciBpdCBmb3IgdGhlIGF4ZXMgZ2l6bW8uIFRoZVxuICAgIC8vIHBsYW5lIGlzIGFscmVhZHkgZGVjaW1hdGVkIHRvIHRoZSBncmlkIGNhcCDihpIgc3RyaWRlIDEuXG4gICAgY29uc3QgelNjYWxlID0gU1VSRkFDRV9aX0FTUEVDVCAqIE1hdGgubWF4KHBsYW5lLndpZHRoLCBwbGFuZS5oZWlnaHQpO1xuICAgIGNvbnN0IHsgdmVydGljZXMsIGZhY2VzLCB2YWx1ZXMgfSA9IGhlaWdodEZpZWxkKHBsYW5lLmRhdGEsIHBsYW5lLndpZHRoLCBwbGFuZS5oZWlnaHQsIHtcbiAgICAgIHpTY2FsZSxcbiAgICAgIHpMaW1pdHM6IHdpbixcbiAgICAgIGNlbnRlcjogdHJ1ZSxcbiAgICB9KTtcblxuICAgIC8vIEEgcmUtc2xpY2UgLyB3aW5kb3cgcmVidWlsZCBrZWVwcyB0aGUgb3JiaXQgY2FtZXJhOiB0aGUgdmlld2VyJ3MgYGZpdDNkOiAnb25jZSdgIGZyYW1lcyBvbmx5XG4gICAgLy8gdGhlIHNjZW5lJ3MgZmlyc3QgM0QgYWRkLCBzbyBzdGVwcGluZyB0aGUgc3RhY2sgb3IgY2hhbmdpbmcgdGhlIHdpbmRvdyBrZWVwcyB0aGUgcG9zZS5cbiAgICBpZiAodGhpcy5sYXllcikge1xuICAgICAgY3R4LnZpZXdlci5sYXllcnMucmVtb3ZlKHRoaXMubGF5ZXIpO1xuICAgICAgdGhpcy5sYXllciA9IG51bGw7XG4gICAgfVxuICAgIHRoaXMubGF5ZXIgPSBjdHgudmlld2VyLmFkZFN1cmZhY2UodmVydGljZXMsIGZhY2VzLCB2YWx1ZXMsIHtcbiAgICAgIGNvbG9ybWFwOiBjdHguZGlzcGxheS52b2x1bWVDb2xvcm1hcChzdCksXG4gICAgICBjb250cmFzdExpbWl0czogd2luLFxuICAgICAgZ2FtbWE6IHRvTmFwYXJpR2FtbWEoc3Q/LmdhbW1hKSwgLy8gSW1hZ2VKIM6zIOKGkiBuYXBhcmktanMgzrNcbiAgICAgIGludmVydDogY3R4LmRpc3BsYXkuaW52ZXJ0LFxuICAgICAgd2lyZWZyYW1lOiBjdHguc2V0dGluZ3Muc3VyZmFjZVdpcmVmcmFtZSxcbiAgICB9KTtcblxuICAgIGN0eC5zZXRJbWFnZVNpemUocGxhbmUud2lkdGgsIHBsYW5lLmhlaWdodCk7XG4gICAgdGhpcy5oaXN0b2dyYW1QbGFuZSA9IHBsYW5lLmRhdGE7XG4gICAgY3R4LnRvb2xzLnNjaGVkdWxlUmVhZGJhY2soKTtcbiAgfVxuXG4gIC8qKiBUaGUgc3RvcmUgY29sb3JtYXAgLyByZXZlcnNlIC8gaW52ZXJ0IC8gY2hhbm5lbCB3aW5kb3cg4oaSIHRoZSBzdXJmYWNlLCBzbyBoaXN0b2dyYW0gJiBjaGFubmVsXG4gICAqICBkaWFsb2cgZWRpdHMgdXBkYXRlIGl0IGxpdmUgd2l0aG91dCBhIHJlLWZldGNoLiAqKm1pbi9tYXggcmVzaGFwZXMgdGhlIHN1cmZhY2UncyBoZWlnaHQqKiAoYVxuICAgKiAgcGl4ZWwncyBoZWlnaHQgPSBpdHMgaW50ZW5zaXR5IHdpdGhpbiBbbWluLG1heF0pLCBzbyBhIHdpbmRvdyBjaGFuZ2UgcmVidWlsZHMgdGhlIG1lc2hcbiAgICogIGdlb21ldHJ5IChmcm9tIHRoZSBjYWNoZWQgc2xpY2UpOyBjb2xvdXItb25seSBlZGl0cyAoY29sb3JtYXAvTFVULCBnYW1tYSwgcmV2ZXJzZSwgaW52ZXJ0KVxuICAgKiAganVzdCB1cGRhdGUgdGhlIGxheWVyJ3MgdW5pZm9ybXMuICovXG4gIHByaXZhdGUgZm9sbG93RGlzcGxheVN0YXRlKCk6IHZvaWQge1xuICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzO1xuICAgIHRoaXMuZGlzcGxheVN1YiA9IGN0eC5kaXNwbGF5LndhdGNoKChjaGFubmVscywgc2VsZWN0ZWQpID0+IHtcbiAgICAgIGNvbnN0IGxheWVyID0gdGhpcy5sYXllcjtcbiAgICAgIGlmICghbGF5ZXIgfHwgY3R4LnNpZ25hbC5hYm9ydGVkKSByZXR1cm47XG4gICAgICAvLyBTZWxlY3RlZCBjaGFubmVsIGNoYW5nZWQgKG11bHRpY2hhbm5lbCk6IHJlLWZldGNoIFRIQVQgYmFuZCdzIHBsYW5lcyBhbmRcbiAgICAgIC8vIHJlYnVpbGQgdGhlIGhlaWdodC1maWVsZCBmb3IgdGhlIGN1cnJlbnQgc2xpY2UuXG4gICAgICBpZiAodGhpcy5tdWx0aWNoYW5uZWwgJiYgc2VsZWN0ZWQgIT09IHRoaXMuY2hhbm5lbCkge1xuICAgICAgICB0aGlzLmNoYW5uZWwgPSBzZWxlY3RlZDtcbiAgICAgICAgdm9pZCAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGF3YWl0IHRoaXMucHJlbG9hZFBsYW5lcygpO1xuICAgICAgICAgIGlmICghY3R4LnNpZ25hbC5hYm9ydGVkKSBhd2FpdCB0aGlzLmJ1aWxkKGN0eC56KCkpO1xuICAgICAgICB9KSgpLmNhdGNoKChlcnIpID0+IGNvbnNvbGUuZXJyb3IoJ1tuYXBhcmktanNdIHN1cmZhY2UgY2hhbm5lbCBzd2l0Y2ggZmFpbGVkOicsIGVycikpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBzdCA9IHRoaXMuY2hhbm5lbFN0YXRlKGNoYW5uZWxzKTtcbiAgICAgIGNvbnN0IHdpbjogW251bWJlciwgbnVtYmVyXSA9IFtzdD8ubWluID8/IDAsIHN0Py5tYXggPz8gMjU1XTtcbiAgICAgIGNvbnN0IHdpbmRvd0NoYW5nZWQgPSAhdGhpcy53aW5kb3cgfHwgd2luWzBdICE9PSB0aGlzLndpbmRvd1swXSB8fCB3aW5bMV0gIT09IHRoaXMud2luZG93WzFdO1xuICAgICAgaWYgKHdpbmRvd0NoYW5nZWQpIHtcbiAgICAgICAgLy8gSGVpZ2h0IGZvbGxvd3MgdGhlIGNvbnRyYXN0IHdpbmRvdyDihpIgcmVidWlsZCB0aGUgbWVzaCBmb3IgdGhlIG5ldyBbbWluLG1heF0gKGNhbWVyYSBrZXB0KS5cbiAgICAgICAgdm9pZCB0aGlzLmJ1aWxkKGN0eC56KCkpLmNhdGNoKChlcnIpID0+IGNvbnNvbGUuZXJyb3IoJ1tuYXBhcmktanNdIHN1cmZhY2Ugd2luZG93IHJlYnVpbGQgZmFpbGVkOicsIGVycikpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICAvLyBDb2xvdXItb25seSBjaGFuZ2U6IHVwZGF0ZSB1bmlmb3JtcyBpbiBwbGFjZSwgbm8gZ2VvbWV0cnkgcmVidWlsZC5cbiAgICAgIGxheWVyLmNvbG9ybWFwID0gY3R4LmRpc3BsYXkudm9sdW1lQ29sb3JtYXAoc3QpO1xuICAgICAgbGF5ZXIuaW52ZXJ0ID0gY3R4LmRpc3BsYXkuaW52ZXJ0O1xuICAgICAgaWYgKHN0KSB7XG4gICAgICAgIGxheWVyLmNvbnRyYXN0TGltaXRzID0gd2luO1xuICAgICAgICBsYXllci5nYW1tYSA9IHRvTmFwYXJpR2FtbWEoc3QuZ2FtbWEpOyAvLyBJbWFnZUogzrMg4oaSIG5hcGFyaS1qcyDOs1xuICAgICAgfVxuICAgICAgY3R4LnZpZXdlci5yZXF1ZXN0UmVuZGVyKCk7XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==
|