@jax-data-science/sci-image-visualizer 0.8.2 → 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 +361 -4184
- 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 -34430
- 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 -878
- 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
|
@@ -95,9 +95,7 @@ export async function buildVolumeStackImage(dataset, voxels) {
|
|
|
95
95
|
// and a name SHARED by two datasets (only `id` is required to be unique)
|
|
96
96
|
// would serve one dataset's slices for the other.
|
|
97
97
|
fileName: `${dataset.name} · reference volume [${dataset.id}]`,
|
|
98
|
-
imageMeta: [
|
|
99
|
-
{ channelCount: 1, rgbChannels: 1, x: width, y: height, z: depth, mppX, mppY, mppZ },
|
|
100
|
-
],
|
|
98
|
+
imageMeta: [{ channelCount: 1, rgbChannels: 1, x: width, y: height, z: depth, mppX, mppY, mppZ }],
|
|
101
99
|
// Blob URLs are complete images: OSD must open them directly, not ask a tile
|
|
102
100
|
// server for a pyramid that does not exist.
|
|
103
101
|
tiled: false,
|
|
@@ -160,4 +158,4 @@ export function observationsInSlice(obs, volume, slice) {
|
|
|
160
158
|
}
|
|
161
159
|
return out.subarray(0, n);
|
|
162
160
|
}
|
|
163
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhdGlhbC12b2x1bWUtaW1hZ2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3NwYXRpYWwvc3BhdGlhbC12b2x1bWUtaW1hZ2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBa0JBLHVGQUF1RjtBQUN2RixLQUFLLFVBQVUsU0FBUyxDQUFDLE1BQTJDO0lBQ2xFLElBQUksZUFBZSxJQUFJLE1BQU07UUFBRSxPQUFPLE1BQU0sQ0FBQyxhQUFhLENBQUMsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQztJQUNsRixPQUFPLElBQUksT0FBTyxDQUFPLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1FBQzNDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FBQztJQUM5RyxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQkc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLHFCQUFxQixDQUN6QyxPQUF1QixFQUN2QixNQUFrQjtJQUVsQixNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDO0lBQzVCLElBQUksQ0FBQyxJQUFJO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDdkIsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLEdBQUcsSUFBSSxDQUFDO0lBQ3RDLE1BQU0sS0FBSyxHQUFHLEtBQUssR0FBRyxNQUFNLENBQUM7SUFDN0IsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLEtBQUssR0FBRyxLQUFLLEVBQUUsQ0FBQztRQUNwQyxPQUFPLENBQUMsSUFBSSxD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QztRQUNuQyxJQUFJLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLEtBQUssS0FBSztZQUFFLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN6RCxDQUFDO0lBQ0QsT0FBTyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUM1QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSUltYWdlSW5mbyB9IGZyb20gJy4uL2NvbnRyYWN0cy9pbWFnZS5jb250cmFjdCc7XG5pbXBvcnQge1xuICBTcGF0aWFsRGF0YXNldCwgU3BhdGlhbEltYWdlUmVmLCBTcGF0aWFsT2JzZXJ2YXRpb25zLCBTcGF0aWFsVm9sdW1lTWV0YSxcbn0gZnJvbSAnLi4vY29udHJhY3RzL3NwYXRpYWwtZGF0YXNldC5jb250cmFjdCc7XG5cbi8qKlxuICogQSBkYXRhc2V0J3MgcmVmZXJlbmNlIHZvbHVtZSwgZW5jb2RlZCBhcyB0aGUgei1zdGFjayBpbWFnZSB0aGUgMkQgcGF0aCByZW5kZXJzLFxuICogcGx1cyB0aGUgYmxvYiBVUkxzIGJhY2tpbmcgaXQuXG4gKlxuICogVGhlIFVSTHMgYmVsb25nIHRvIHRoZSBDQUxMRVI6IG5vdGhpbmcgZWxzZSBjYW4ga25vdyB3aGVuIHRoZSBpbWFnZSBzdG9wcyBiZWluZ1xuICogZGlzcGxheWVkLCBhbmQgYSBkYXRhc2V0IHN3aXRjaCB0aGF0IGZvcmdldHMgdG8gcmV2b2tlIHRoZW0gbGVha3MgYSB2b2x1bWUnc1xuICogd29ydGggb2YgUE5HcyBwZXIgc3dpdGNoLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFZvbHVtZVN0YWNrSW1hZ2Uge1xuICBpbmZvOiBJSW1hZ2VJbmZvO1xuICB1cmxzOiBzdHJpbmdbXTtcbn1cblxuLyoqIEVuY29kZSBvbmUgY2FudmFzIGFzIGEgUE5HIGJsb2IsIG92ZXIgd2hpY2hldmVyIGNhbnZhcyBmbGF2b3VyIHRoaXMgcnVudGltZSBoYXMuICovXG5hc3luYyBmdW5jdGlvbiB0b1BuZ0Jsb2IoY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCB8IE9mZnNjcmVlbkNhbnZhcyk6IFByb21pc2U8QmxvYj4ge1xuICBpZiAoJ2NvbnZlcnRUb0Jsb2InIGluIGNhbnZhcykgcmV0dXJuIGNhbnZhcy5jb252ZXJ0VG9CbG9iKHsgdHlwZTogJ2ltYWdlL3BuZycgfSk7XG4gIHJldHVybiBuZXcgUHJvbWlzZTxCbG9iPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY2FudmFzLnRvQmxvYigoYmxvYikgPT4gKGJsb2IgPyByZXNvbHZlKGJsb2IpIDogcmVqZWN0KG5ldyBFcnJvcigndG9CbG9iIHByb2R1Y2VkIG5vdGhpbmcnKSkpLCAnaW1hZ2UvcG5nJyk7XG4gIH0pO1xufVxuXG4vKipcbiAqIFR1cm4gYSBzcGF0aWFsIGRhdGFzZXQncyByZWdpc3RlcmVkIHZvbHVtZSBpbnRvIGEgc2NydWJiYWJsZSB6LXN0YWNrIGltYWdlLlxuICpcbiAqIEEgM0Qgb21pY3MgZGF0YXNldCBhcnJpdmVzIGFzIG9uZSB2b2x1bWUgYW5kIE5PIGBpbWFnZVJlZmAsIHNvIHRoZXJlIGlzIG5vIGltYWdlXG4gKiBiZWhpbmQgaXQg4oCUIHdoaWNoIGxlZnQgZXZlcnkgaW1hZ2Utc2hhcGVkIHN1cmZhY2UgKHRoZSBJbWFnZSB2aWV3LCB0aGUgc2xpY2VcbiAqIGJhciwgdGhlIGNvbnRyYXN0IHdpbmRvdywgcmVnaW9ucykgd2l0aCBub3RoaW5nIHRvIHdvcmsgb24sIGFuZCB0aGUgSW1hZ2Ugdmlld1xuICogc2hvd2luZyB3aGF0ZXZlciBzbGlkZSBoYXBwZW5lZCB0byBiZSBsb2FkZWQgYmVmb3JlLiBFbmNvZGluZyBlYWNoIHogcGxhbmUgYXMgYVxuICogYmxvYiBQTkcgbWFrZXMgdGhlIHZvbHVtZSBpdHNlbGYgdGhlIGltYWdlLCBzbyB0aGUgZXhpc3Rpbmcgc3RhY2sgbWFjaGluZXJ5XG4gKiBkcml2ZXMgaXQgdW5jaGFuZ2VkOiB0aGUgc2FtZSBgdXJsc1t6XWAgKyBgaXNTdGFja2Agc2hhcGUgYSBob3N0IGVtaXRzIGZvciBhXG4gKiBtdWx0aS1wYWdlIFRJRkYsIHdoaWNoIGlzIGV4YWN0bHkgd2hhdCB0aGlzIHZvbHVtZSBpcy5cbiAqXG4gKiBFdmVyeSBwbGFuZSBpcyBlbmNvZGVkIHVwIGZyb250IHJhdGhlciB0aGFuIG9uIGRlbWFuZCwgYmVjYXVzZSB0aGUgc2xpY2UgY291bnRcbiAqIGNvbWVzIGZyb20gYHVybHMubGVuZ3RoYCDigJQgdGhlIGNvbXBvbmVudCBoYXMgdG8ga25vdyB0aGUgZGVwdGggYmVmb3JlIHRoZSB1c2VyXG4gKiBzY3J1YnMuIFRoZSB2b3hlbHMgYXJlIGFscmVhZHkgcmVzaWRlbnQgKG1lZ2FieXRlcywgZmV0Y2hlZCBpbiBvbmUgY2FsbCksIGFuZCBhXG4gKiBwbGFuZSBpcyBhIGZldyBLQiBvZiBQTkcsIHNvIHRoZSBjb3N0IGlzIGJvdW5kZWQgYnkgdGhlIHZvbHVtZSB0aGUgaG9zdCBhbHJlYWR5XG4gKiBjaG9zZSB0byBmZXRjaC5cbiAqXG4gKiBSZXR1cm5zIG51bGwgd2hlbiB0aGUgZGF0YXNldCBkZWNsYXJlcyBubyB2b2x1bWUsIG9yIHRoZSBieXRlIGNvdW50IGNvbnRyYWRpY3RzXG4gKiB0aGUgZGVjbGFyZWQgZ2VvbWV0cnkg4oCUIGEgc2hvcnQgYnVmZmVyIHdvdWxkIHNpbGVudGx5IHByb2R1Y2Ugc2xpY2VzIG9mIHNoaWZ0ZWRcbiAqIGFuYXRvbXksIHdoaWNoIGlzIHdvcnNlIHRoYW4gbm8gaW1hZ2UgYXQgYWxsLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYnVpbGRWb2x1bWVTdGFja0ltYWdlKFxuICBkYXRhc2V0OiBTcGF0aWFsRGF0YXNldCxcbiAgdm94ZWxzOiBVaW50OEFycmF5LFxuKTogUHJvbWlzZTxWb2x1bWVTdGFja0ltYWdlIHwgbnVsbD4ge1xuICBjb25zdCBtZXRhID0gZGF0YXNldC52b2x1bWU7XG4gIGlmICghbWV0YSkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IHsgd2lkdGgsIGhlaWdodCwgZGVwdGggfSA9IG1ldGE7XG4gIGNvbnN0IHBsYW5lID0gd2lkdGggKiBoZWlnaHQ7XG4gIGlmICh2b3hlbHMubGVuZ3RoICE9PSBwbGFuZSAqIGRlcHRoKSB7XG4gICAgY29uc29sZS53YXJuKFxuICAgICAgYFtzcGF0aWFsXSB2b2x1bWUgaXMgJHt2b3hlbHMubGVuZ3RofSBieXRlcyBidXQgaXRzIGdlb21ldHJ5IGRlY2xhcmVzIGAgK1xuICAgICAgICBgJHtwbGFuZSAqIGRlcHRofSAoJHt3aWR0aH14JHtoZWlnaHR9eCR7ZGVwdGh9KSDigJQgbm90IHJlbmRlcmluZyBpdCBhcyBhbiBpbWFnZWAsXG4gICAgKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGxldCBjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50IHwgT2Zmc2NyZWVuQ2FudmFzO1xuICBpZiAodHlwZW9mIE9mZnNjcmVlbkNhbnZhcyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBjYW52YXMgPSBuZXcgT2Zmc2NyZWVuQ2FudmFzKHdpZHRoLCBoZWlnaHQpO1xuICB9IGVsc2Uge1xuICAgIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgIGNhbnZhcy53aWR0aCA9IHdpZHRoO1xuICAgIGNhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7XG4gIH1cbiAgY29uc3QgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJykgYXNcbiAgICB8IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRFxuICAgIHwgT2Zmc2NyZWVuQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEXG4gICAgfCBudWxsO1xuICBpZiAoIWN0eCkgdGhyb3cgbmV3IEVycm9yKCdbc3BhdGlhbF0gdm9sdW1lIHNsaWNlIGVuY29kZTogMkQgY29udGV4dCB1bmF2YWlsYWJsZScpO1xuXG4gIC8vIE9uZSBjYW52YXMgYW5kIG9uZSBSR0JBIGJ1ZmZlciBmb3IgdGhlIHdob2xlIHN0YWNrIOKAlCBhIGNhbnZhcyBwZXIgcGxhbmUgd291bGRcbiAgLy8gYmUgYGRlcHRoYCBHUFUtYmFja2VkIHN1cmZhY2VzIGFsaXZlIGF0IG9uY2UgZm9yIG5vIGdhaW4uXG4gIGNvbnN0IHJnYmEgPSBuZXcgVWludDhDbGFtcGVkQXJyYXkocGxhbmUgKiA0KTtcbiAgY29uc3QgdXJsczogc3RyaW5nW10gPSBbXTtcbiAgZm9yIChsZXQgeiA9IDA7IHogPCBkZXB0aDsgeisrKSB7XG4gICAgY29uc3QgYmFzZSA9IHogKiBwbGFuZTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBsYW5lOyBpKyspIHtcbiAgICAgIGNvbnN0IHYgPSB2b3hlbHNbYmFzZSArIGldO1xuICAgICAgY29uc3QgbyA9IGkgKiA0O1xuICAgICAgcmdiYVtvXSA9IHY7XG4gICAgICByZ2JhW28gKyAxXSA9IHY7XG4gICAgICByZ2JhW28gKyAyXSA9IHY7XG4gICAgICByZ2JhW28gKyAzXSA9IDI1NTtcbiAgICB9XG4gICAgY3R4LnB1dEltYWdlRGF0YShuZXcgSW1hZ2VEYXRhKHJnYmEsIHdpZHRoLCBoZWlnaHQpLCAwLCAwKTtcbiAgICB1cmxzLnB1c2goVVJMLmNyZWF0ZU9iamVjdFVSTChhd2FpdCB0b1BuZ0Jsb2IoY2FudmFzKSkpO1xuICB9XG5cbiAgLy8gdm94ZWxTaXplIGlzIGluIHRoZSBPQlNFUlZBVElPTlMnIHVuaXRzLCBzbyBpdCBvbmx5IG1lYW5zIG1pY3JvbnMgb25jZVxuICAvLyBgbWljcm9uc1BlclVuaXRgIHNheXMgc28uIEFic2VudCwgdGhlIHVuaXQgaXMgdW5rbm93biBhbmQgbXBwIHN0YXlzIG51bGwg4oCUXG4gIC8vIHRoZSBjb250cmFjdCdzIHJ1bGUgZm9yIHRoZSBzY2FsZSBiYXI6IG5vIGJhciBiZWF0cyBhIGJhciB0aGF0IGxvb2tzIGxpa2UgYVxuICAvLyBtZWFzdXJlbWVudCBhbmQgaXMgbm90IG9uZS5cbiAgY29uc3QgcGVyVW5pdCA9IGRhdGFzZXQubWljcm9uc1BlclVuaXQ7XG4gIGNvbnN0IG1wcFggPSBwZXJVbml0ICE9IG51bGwgPyBtZXRhLnZveGVsU2l6ZVswXSAqIHBlclVuaXQgOiBudWxsO1xuICBjb25zdCBtcHBZID0gcGVyVW5pdCAhPSBudWxsID8gbWV0YS52b3hlbFNpemVbMV0gKiBwZXJVbml0IDogbnVsbDtcbiAgLy8gVGhlIHogY291bnRlcnBhcnQsIHdoaWNoIGlzIHdoYXQgY2FycmllcyB0aGUgdm9sdW1lJ3MgYW5pc290cm9weSBpbnRvIHRoZVxuICAvLyBWb2x1bWUgLyBJc29zdXJmYWNlIHZpZXdzOiB0aGV5IHJheW1hcmNoIHRoZSBpbWFnZSBzdGFjaywgYW5kIGEgc3RhY2sgd2l0aCBub1xuICAvLyBkZWNsYXJlZCBzbGljZSBzcGFjaW5nIGNhbiBvbmx5IGJlIGdpdmVuIGEgc2hhcGUtb25seSB3b3JsZCBib3guXG4gIGNvbnN0IG1wcFogPSBwZXJVbml0ICE9IG51bGwgPyBtZXRhLnZveGVsU2l6ZVsyXSAqIHBlclVuaXQgOiBudWxsO1xuXG4gIHJldHVybiB7XG4gICAgdXJscyxcbiAgICBpbmZvOiB7XG4gICAgICAvLyBBIHNjYWxhciBmaWVsZDogb25lIGJhbmQsIG5vIGNvbG91ciBvZiBpdHMgb3duIOKAlCB3aGljaCBpcyBhbHNvIHdoYXQgcHV0c1xuICAgICAgLy8gdGhlIHNjYWxhciBtb2RlcyAoSGVhdG1hcCAvIENvbnRvdXIgLyBTdXJmYWNlIC8gVm9sdW1lKSBsZWdpdGltYXRlbHkgb25cbiAgICAgIC8vIG9mZmVyIGZvciBhIGRhdGFzZXQgdGhhdCBoYXMgbm8gY2FtZXJhIGltYWdlIGFueXdoZXJlIGluIGl0LlxuICAgICAgaXNHcmF5c2NhbGU6IHRydWUsXG4gICAgICB0cnVlSW1hZ2VTaXplOiBbd2lkdGgsIGhlaWdodF0sXG4gICAgICB1cmxzLFxuICAgICAgaXNTdGFjazogZGVwdGggPiAxLFxuICAgICAgc2hvd1N0YWNrOiBmYWxzZSxcbiAgICAgIHNjYWxlUmF0aW86IHRydWUsXG4gICAgICAvLyBTdGFibGUgQU5EIHVuaXF1ZSBwZXIgZGF0YXNldDogdGhlIHNsaWNlLWJsb2IgY2FjaGUga2V5cyBvZmYgdGhlIGZpbGUgbmFtZSxcbiAgICAgIC8vIHNvIGEgbmFtZSB0aGF0IGNoYW5nZWQgcGVyIGxvYWQgd291bGQgcmUtZmV0Y2ggYSB2b2x1bWUgdGhhdCBuZXZlciBtb3ZlZCDigJRcbiAgICAgIC8vIGFuZCBhIG5hbWUgU0hBUkVEIGJ5IHR3byBkYXRhc2V0cyAob25seSBgaWRgIGlzIHJlcXVpcmVkIHRvIGJlIHVuaXF1ZSlcbiAgICAgIC8vIHdvdWxkIHNlcnZlIG9uZSBkYXRhc2V0J3Mgc2xpY2VzIGZvciB0aGUgb3RoZXIuXG4gICAgICBmaWxlTmFtZTogYCR7ZGF0YXNldC5uYW1lfSDCtyByZWZlcmVuY2Ugdm9sdW1lIFske2RhdGFzZXQuaWR9XWAsXG4gICAgICBpbWFnZU1ldGE6IFtcbiAgICAgICAgeyBjaGFubmVsQ291bnQ6IDEsIHJnYkNoYW5uZWxzOiAxLCB4OiB3aWR0aCwgeTogaGVpZ2h0LCB6OiBkZXB0aCwgbXBwWCwgbXBwWSwgbXBwWiB9LFxuICAgICAgXSxcbiAgICAgIC8vIEJsb2IgVVJMcyBhcmUgY29tcGxldGUgaW1hZ2VzOiBPU0QgbXVzdCBvcGVuIHRoZW0gZGlyZWN0bHksIG5vdCBhc2sgYSB0aWxlXG4gICAgICAvLyBzZXJ2ZXIgZm9yIGEgcHlyYW1pZCB0aGF0IGRvZXMgbm90IGV4aXN0LlxuICAgICAgdGlsZWQ6IGZhbHNlLFxuICAgICAgLy8gT3BlbiBtaWQtdm9sdW1lLiBUaGUgZmlyc3QgYW5kIGxhc3QgcGxhbmVzIG9mIGFuIGFuYXRvbWljYWwgdm9sdW1lIGFyZVxuICAgICAgLy8gb3V0c2lkZSB0aGUgc3BlY2ltZW4g4oCUIG9wZW5pbmcgb24gc2xpY2UgMCBzaG93cyBhbiBlbXB0eSBmcmFtZSBhbmQgcmVhZHNcbiAgICAgIC8vIGFzIGEgZmFpbGVkIGxvYWQuXG4gICAgICBpbml0aWFsWkluZGV4OiBkZXB0aCA+IDEgPyBkZXB0aCA+PiAxIDogdW5kZWZpbmVkLFxuICAgIH0sXG4gIH07XG59XG5cbi8qKlxuICogVGhlIGRhdGHihpJpbWFnZSBhZmZpbmUgYSByZWdpc3RlcmVkIHZvbHVtZSBpbXBsaWVzLlxuICpcbiAqIE9uY2UgdGhlIHZvbHVtZSBJUyB0aGUgaW1hZ2UgKHtAbGluayBidWlsZFZvbHVtZVN0YWNrSW1hZ2V9KSwgb25lIHNsaWNlIGlzIGFcbiAqIGB3aWR0aCB4IGhlaWdodGAgcGl4ZWwgZ3JpZCB3aG9zZSB2b3hlbCBgKGksIGopYCBjb3ZlcnNcbiAqIGBbaSAqIHZveGVsU2l6ZVswXSwgKGkgKyAxKSAqIHZveGVsU2l6ZVswXSlgIG9mIHRoZSBvYnNlcnZhdGlvbnMnIGNvb3JkaW5hdGVcbiAqIHNwYWNlIOKAlCB0aGUgY29udHJhY3QncyBydWxlIHRoYXQgdGhlIHZvbHVtZSdzIG5lYXIgY29ybmVyIHNpdHMgYXQgdGhlXG4gKiBjb29yZGluYXRlIG9yaWdpbi4gU28gb2JzZXJ2YXRpb25zIHJlYWNoIHBpeGVsIHNwYWNlIGJ5IGRpdmlkaW5nIG91dCB0aGUgdm94ZWxcbiAqIHNpemUsIGFuZCBub3RoaW5nIGhhcyB0byBtb3ZlLlxuICpcbiAqIFNoYXBlZCBhcyBhIGBTcGF0aWFsSW1hZ2VSZWZgIG9uIHB1cnBvc2U6IHRoZSBtYXJrZXIgbGF5ZXIgYW5kIHRoZSBST0lcbiAqIHNlbGVjdGlvbiB0aGVuIHRha2UgdGhlIFNBTUUgdHJhbnNmb3JtIHRoZXkgdGFrZSBmb3IgYSBkYXRhc2V0IHRoYXQgc2hpcHMgYVxuICogcmVhbCBgaW1hZ2VSZWZgLCBpbnN0ZWFkIG9mIGVhY2ggZ3Jvd2luZyBhIHZvbHVtZSBzcGVjaWFsIGNhc2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2b2x1bWVJbWFnZVJlZihcbiAgdm9sdW1lOiBTcGF0aWFsVm9sdW1lTWV0YSwgbWljcm9uc1BlclVuaXQ/OiBudW1iZXIsXG4pOiBTcGF0aWFsSW1hZ2VSZWYge1xuICBjb25zdCBbdngsIHZ5XSA9IHZvbHVtZS52b3hlbFNpemU7XG4gIHJldHVybiB7XG4gICAgc2NhbGU6IFsxIC8gdngsIDEgLyB2eV0sXG4gICAgdHJhbnNsYXRlOiBbMCwgMF0sXG4gICAgLi4uKG1pY3JvbnNQZXJVbml0ICE9IG51bGwgPyB7IG1wcFg6IHZ4ICogbWljcm9uc1BlclVuaXQsIG1wcFk6IHZ5ICogbWljcm9uc1BlclVuaXQgfSA6IHt9KSxcbiAgfTtcbn1cblxuLyoqIFRoZSB2b3hlbCBwbGFuZSBhIGNvb3JkaW5hdGUgZmFsbHMgaW4sIGNsYW1wZWQgaW50byB0aGUgdm9sdW1lLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNsaWNlSW5kZXhPZih6OiBudW1iZXIsIHZvbHVtZTogU3BhdGlhbFZvbHVtZU1ldGEpOiBudW1iZXIge1xuICBjb25zdCBrID0gTWF0aC5mbG9vcih6IC8gdm9sdW1lLnZveGVsU2l6ZVsyXSk7XG4gIHJldHVybiBNYXRoLm1heCgwLCBNYXRoLm1pbih2b2x1bWUuZGVwdGggLSAxLCBrKSk7XG59XG5cbi8qKlxuICogSW5kaWNlcyBvZiB0aGUgb2JzZXJ2YXRpb25zIHRoYXQgZmFsbCBpbiBvbmUgdm94ZWwgcGxhbmUgb2YgdGhlIHZvbHVtZS5cbiAqXG4gKiBBIDJEIHZpZXcgb2YgYSAzRCBkYXRhc2V0IHNob3dzIE9ORSBwbGFuZSwgc28gaXQgbXVzdCBkcmF3IG9uZSBwbGFuZSdzXG4gKiBvYnNlcnZhdGlvbnM6IHdpdGhvdXQgdGhpcyB0aGUgd2hvbGUgZGVwdGggb2YgdGhlIHNwZWNpbWVuIHBpbGVzIG9udG8gYSBzaW5nbGVcbiAqIHNlY3Rpb24gYW5kIHJlYWRzIGFzIGEgc29saWQgc21lYXIgcmF0aGVyIHRoYW4gYSBzZWN0aW9uJ3MgY2VsbHMuIFRoZSBwbGFuZSBpc1xuICogYSBzbGFiIGB2b3hlbFNpemVbMl1gIHRoaWNrLCB3aGljaCBpcyBleGFjdGx5IHRoZSBzYW1wbGluZyB0aGUgdm9sdW1lIGl0c2VsZlxuICogaGFzIOKAlCBmb3Igc2VyaWFsIHNlY3Rpb25zIHJlZ2lzdGVyZWQgaW50byBhIGNvbW1vbiBmcmFtZSwgb25lIHNsYWIgaXMgb25lXG4gKiBzZWN0aW9uLlxuICpcbiAqIEV2ZXJ5IG9ic2VydmF0aW9uIGlzIGluIHRoZSBwbGFuZSB3aGVuIHRoZSBkYXRhc2V0IGNhcnJpZXMgbm8gejogYSBnZW51aW5lbHlcbiAqIGZsYXQgZGF0YXNldCBvdmVyIGEgdm9sdW1lIGhhcyBub3RoaW5nIHRvIGZpbHRlciBvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9ic2VydmF0aW9uc0luU2xpY2UoXG4gIG9iczogU3BhdGlhbE9ic2VydmF0aW9ucywgdm9sdW1lOiBTcGF0aWFsVm9sdW1lTWV0YSwgc2xpY2U6IG51bWJlcixcbik6IFVpbnQzMkFycmF5IHtcbiAgY29uc3QgeiA9IG9icy56O1xuICBpZiAoIXopIHJldHVybiBVaW50MzJBcnJheS5mcm9tKHsgbGVuZ3RoOiBvYnMuY291bnQgfSwgKF8sIGkpID0+IGkpO1xuICBjb25zdCBvdXQgPSBuZXcgVWludDMyQXJyYXkob2JzLmNvdW50KTtcbiAgbGV0IG4gPSAwO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG9icy5jb3VudDsgaSsrKSB7XG4gICAgaWYgKHNsaWNlSW5kZXhPZih6W2ldLCB2b2x1bWUpID09PSBzbGljZSkgb3V0W24rK10gPSBpO1xuICB9XG4gIHJldHVybiBvdXQuc3ViYXJyYXkoMCwgbik7XG59XG4iXX0=
|
|
161
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhdGlhbC12b2x1bWUtaW1hZ2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3NwYXRpYWwvc3BhdGlhbC12b2x1bWUtaW1hZ2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBcUJBLHVGQUF1RjtBQUN2RixLQUFLLFVBQVUsU0FBUyxDQUFDLE1BQTJDO0lBQ2xFLElBQUksZUFBZSxJQUFJLE1BQU07UUFBRSxPQUFPLE1BQU0sQ0FBQyxhQUFhLENBQUMsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQztJQUNsRixPQUFPLElBQUksT0FBTyxDQUFPLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1FBQzNDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FBQztJQUM5RyxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQkc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLHFCQUFxQixDQUN6QyxPQUF1QixFQUN2QixNQUFrQjtJQUVsQixNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDO0lBQzVCLElBQUksQ0FBQyxJQUFJO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDdkIsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLEdBQUcsSUFBSSxDQUFDO0lBQ3RDLE1BQU0sS0FBSyxHQUFHLEtBQUssR0FBRyxNQUFNLENBQUM7SUFDN0IsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLEtBQUssR0FBRyxLQUFLLEVBQUUsQ0FBQztRQUNwQyxPQUFPLENBQUMsSUFBSSxD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QztRQUNuQyxJQUFJLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLEtBQUssS0FBSztZQUFFLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN6RCxDQUFDO0lBQ0QsT0FBTyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUM1QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSUltYWdlSW5mbyB9IGZyb20gJy4uL2NvbnRyYWN0cy9pbWFnZS5jb250cmFjdCc7XG5pbXBvcnQge1xuICBTcGF0aWFsRGF0YXNldCxcbiAgU3BhdGlhbEltYWdlUmVmLFxuICBTcGF0aWFsT2JzZXJ2YXRpb25zLFxuICBTcGF0aWFsVm9sdW1lTWV0YSxcbn0gZnJvbSAnLi4vY29udHJhY3RzL3NwYXRpYWwtZGF0YXNldC5jb250cmFjdCc7XG5cbi8qKlxuICogQSBkYXRhc2V0J3MgcmVmZXJlbmNlIHZvbHVtZSwgZW5jb2RlZCBhcyB0aGUgei1zdGFjayBpbWFnZSB0aGUgMkQgcGF0aCByZW5kZXJzLFxuICogcGx1cyB0aGUgYmxvYiBVUkxzIGJhY2tpbmcgaXQuXG4gKlxuICogVGhlIFVSTHMgYmVsb25nIHRvIHRoZSBDQUxMRVI6IG5vdGhpbmcgZWxzZSBjYW4ga25vdyB3aGVuIHRoZSBpbWFnZSBzdG9wcyBiZWluZ1xuICogZGlzcGxheWVkLCBhbmQgYSBkYXRhc2V0IHN3aXRjaCB0aGF0IGZvcmdldHMgdG8gcmV2b2tlIHRoZW0gbGVha3MgYSB2b2x1bWUnc1xuICogd29ydGggb2YgUE5HcyBwZXIgc3dpdGNoLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFZvbHVtZVN0YWNrSW1hZ2Uge1xuICBpbmZvOiBJSW1hZ2VJbmZvO1xuICB1cmxzOiBzdHJpbmdbXTtcbn1cblxuLyoqIEVuY29kZSBvbmUgY2FudmFzIGFzIGEgUE5HIGJsb2IsIG92ZXIgd2hpY2hldmVyIGNhbnZhcyBmbGF2b3VyIHRoaXMgcnVudGltZSBoYXMuICovXG5hc3luYyBmdW5jdGlvbiB0b1BuZ0Jsb2IoY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCB8IE9mZnNjcmVlbkNhbnZhcyk6IFByb21pc2U8QmxvYj4ge1xuICBpZiAoJ2NvbnZlcnRUb0Jsb2InIGluIGNhbnZhcykgcmV0dXJuIGNhbnZhcy5jb252ZXJ0VG9CbG9iKHsgdHlwZTogJ2ltYWdlL3BuZycgfSk7XG4gIHJldHVybiBuZXcgUHJvbWlzZTxCbG9iPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY2FudmFzLnRvQmxvYigoYmxvYikgPT4gKGJsb2IgPyByZXNvbHZlKGJsb2IpIDogcmVqZWN0KG5ldyBFcnJvcigndG9CbG9iIHByb2R1Y2VkIG5vdGhpbmcnKSkpLCAnaW1hZ2UvcG5nJyk7XG4gIH0pO1xufVxuXG4vKipcbiAqIFR1cm4gYSBzcGF0aWFsIGRhdGFzZXQncyByZWdpc3RlcmVkIHZvbHVtZSBpbnRvIGEgc2NydWJiYWJsZSB6LXN0YWNrIGltYWdlLlxuICpcbiAqIEEgM0Qgb21pY3MgZGF0YXNldCBhcnJpdmVzIGFzIG9uZSB2b2x1bWUgYW5kIE5PIGBpbWFnZVJlZmAsIHNvIHRoZXJlIGlzIG5vIGltYWdlXG4gKiBiZWhpbmQgaXQg4oCUIHdoaWNoIGxlZnQgZXZlcnkgaW1hZ2Utc2hhcGVkIHN1cmZhY2UgKHRoZSBJbWFnZSB2aWV3LCB0aGUgc2xpY2VcbiAqIGJhciwgdGhlIGNvbnRyYXN0IHdpbmRvdywgcmVnaW9ucykgd2l0aCBub3RoaW5nIHRvIHdvcmsgb24sIGFuZCB0aGUgSW1hZ2Ugdmlld1xuICogc2hvd2luZyB3aGF0ZXZlciBzbGlkZSBoYXBwZW5lZCB0byBiZSBsb2FkZWQgYmVmb3JlLiBFbmNvZGluZyBlYWNoIHogcGxhbmUgYXMgYVxuICogYmxvYiBQTkcgbWFrZXMgdGhlIHZvbHVtZSBpdHNlbGYgdGhlIGltYWdlLCBzbyB0aGUgZXhpc3Rpbmcgc3RhY2sgbWFjaGluZXJ5XG4gKiBkcml2ZXMgaXQgdW5jaGFuZ2VkOiB0aGUgc2FtZSBgdXJsc1t6XWAgKyBgaXNTdGFja2Agc2hhcGUgYSBob3N0IGVtaXRzIGZvciBhXG4gKiBtdWx0aS1wYWdlIFRJRkYsIHdoaWNoIGlzIGV4YWN0bHkgd2hhdCB0aGlzIHZvbHVtZSBpcy5cbiAqXG4gKiBFdmVyeSBwbGFuZSBpcyBlbmNvZGVkIHVwIGZyb250IHJhdGhlciB0aGFuIG9uIGRlbWFuZCwgYmVjYXVzZSB0aGUgc2xpY2UgY291bnRcbiAqIGNvbWVzIGZyb20gYHVybHMubGVuZ3RoYCDigJQgdGhlIGNvbXBvbmVudCBoYXMgdG8ga25vdyB0aGUgZGVwdGggYmVmb3JlIHRoZSB1c2VyXG4gKiBzY3J1YnMuIFRoZSB2b3hlbHMgYXJlIGFscmVhZHkgcmVzaWRlbnQgKG1lZ2FieXRlcywgZmV0Y2hlZCBpbiBvbmUgY2FsbCksIGFuZCBhXG4gKiBwbGFuZSBpcyBhIGZldyBLQiBvZiBQTkcsIHNvIHRoZSBjb3N0IGlzIGJvdW5kZWQgYnkgdGhlIHZvbHVtZSB0aGUgaG9zdCBhbHJlYWR5XG4gKiBjaG9zZSB0byBmZXRjaC5cbiAqXG4gKiBSZXR1cm5zIG51bGwgd2hlbiB0aGUgZGF0YXNldCBkZWNsYXJlcyBubyB2b2x1bWUsIG9yIHRoZSBieXRlIGNvdW50IGNvbnRyYWRpY3RzXG4gKiB0aGUgZGVjbGFyZWQgZ2VvbWV0cnkg4oCUIGEgc2hvcnQgYnVmZmVyIHdvdWxkIHNpbGVudGx5IHByb2R1Y2Ugc2xpY2VzIG9mIHNoaWZ0ZWRcbiAqIGFuYXRvbXksIHdoaWNoIGlzIHdvcnNlIHRoYW4gbm8gaW1hZ2UgYXQgYWxsLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYnVpbGRWb2x1bWVTdGFja0ltYWdlKFxuICBkYXRhc2V0OiBTcGF0aWFsRGF0YXNldCxcbiAgdm94ZWxzOiBVaW50OEFycmF5LFxuKTogUHJvbWlzZTxWb2x1bWVTdGFja0ltYWdlIHwgbnVsbD4ge1xuICBjb25zdCBtZXRhID0gZGF0YXNldC52b2x1bWU7XG4gIGlmICghbWV0YSkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IHsgd2lkdGgsIGhlaWdodCwgZGVwdGggfSA9IG1ldGE7XG4gIGNvbnN0IHBsYW5lID0gd2lkdGggKiBoZWlnaHQ7XG4gIGlmICh2b3hlbHMubGVuZ3RoICE9PSBwbGFuZSAqIGRlcHRoKSB7XG4gICAgY29uc29sZS53YXJuKFxuICAgICAgYFtzcGF0aWFsXSB2b2x1bWUgaXMgJHt2b3hlbHMubGVuZ3RofSBieXRlcyBidXQgaXRzIGdlb21ldHJ5IGRlY2xhcmVzIGAgK1xuICAgICAgICBgJHtwbGFuZSAqIGRlcHRofSAoJHt3aWR0aH14JHtoZWlnaHR9eCR7ZGVwdGh9KSDigJQgbm90IHJlbmRlcmluZyBpdCBhcyBhbiBpbWFnZWAsXG4gICAgKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGxldCBjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50IHwgT2Zmc2NyZWVuQ2FudmFzO1xuICBpZiAodHlwZW9mIE9mZnNjcmVlbkNhbnZhcyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBjYW52YXMgPSBuZXcgT2Zmc2NyZWVuQ2FudmFzKHdpZHRoLCBoZWlnaHQpO1xuICB9IGVsc2Uge1xuICAgIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgIGNhbnZhcy53aWR0aCA9IHdpZHRoO1xuICAgIGNhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7XG4gIH1cbiAgY29uc3QgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJykgYXMgQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEIHwgT2Zmc2NyZWVuQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEIHwgbnVsbDtcbiAgaWYgKCFjdHgpIHRocm93IG5ldyBFcnJvcignW3NwYXRpYWxdIHZvbHVtZSBzbGljZSBlbmNvZGU6IDJEIGNvbnRleHQgdW5hdmFpbGFibGUnKTtcblxuICAvLyBPbmUgY2FudmFzIGFuZCBvbmUgUkdCQSBidWZmZXIgZm9yIHRoZSB3aG9sZSBzdGFjayDigJQgYSBjYW52YXMgcGVyIHBsYW5lIHdvdWxkXG4gIC8vIGJlIGBkZXB0aGAgR1BVLWJhY2tlZCBzdXJmYWNlcyBhbGl2ZSBhdCBvbmNlIGZvciBubyBnYWluLlxuICBjb25zdCByZ2JhID0gbmV3IFVpbnQ4Q2xhbXBlZEFycmF5KHBsYW5lICogNCk7XG4gIGNvbnN0IHVybHM6IHN0cmluZ1tdID0gW107XG4gIGZvciAobGV0IHogPSAwOyB6IDwgZGVwdGg7IHorKykge1xuICAgIGNvbnN0IGJhc2UgPSB6ICogcGxhbmU7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwbGFuZTsgaSsrKSB7XG4gICAgICBjb25zdCB2ID0gdm94ZWxzW2Jhc2UgKyBpXTtcbiAgICAgIGNvbnN0IG8gPSBpICogNDtcbiAgICAgIHJnYmFbb10gPSB2O1xuICAgICAgcmdiYVtvICsgMV0gPSB2O1xuICAgICAgcmdiYVtvICsgMl0gPSB2O1xuICAgICAgcmdiYVtvICsgM10gPSAyNTU7XG4gICAgfVxuICAgIGN0eC5wdXRJbWFnZURhdGEobmV3IEltYWdlRGF0YShyZ2JhLCB3aWR0aCwgaGVpZ2h0KSwgMCwgMCk7XG4gICAgdXJscy5wdXNoKFVSTC5jcmVhdGVPYmplY3RVUkwoYXdhaXQgdG9QbmdCbG9iKGNhbnZhcykpKTtcbiAgfVxuXG4gIC8vIHZveGVsU2l6ZSBpcyBpbiB0aGUgT0JTRVJWQVRJT05TJyB1bml0cywgc28gaXQgb25seSBtZWFucyBtaWNyb25zIG9uY2VcbiAgLy8gYG1pY3JvbnNQZXJVbml0YCBzYXlzIHNvLiBBYnNlbnQsIHRoZSB1bml0IGlzIHVua25vd24gYW5kIG1wcCBzdGF5cyBudWxsIOKAlFxuICAvLyB0aGUgY29udHJhY3QncyBydWxlIGZvciB0aGUgc2NhbGUgYmFyOiBubyBiYXIgYmVhdHMgYSBiYXIgdGhhdCBsb29rcyBsaWtlIGFcbiAgLy8gbWVhc3VyZW1lbnQgYW5kIGlzIG5vdCBvbmUuXG4gIGNvbnN0IHBlclVuaXQgPSBkYXRhc2V0Lm1pY3JvbnNQZXJVbml0O1xuICBjb25zdCBtcHBYID0gcGVyVW5pdCAhPSBudWxsID8gbWV0YS52b3hlbFNpemVbMF0gKiBwZXJVbml0IDogbnVsbDtcbiAgY29uc3QgbXBwWSA9IHBlclVuaXQgIT0gbnVsbCA/IG1ldGEudm94ZWxTaXplWzFdICogcGVyVW5pdCA6IG51bGw7XG4gIC8vIFRoZSB6IGNvdW50ZXJwYXJ0LCB3aGljaCBpcyB3aGF0IGNhcnJpZXMgdGhlIHZvbHVtZSdzIGFuaXNvdHJvcHkgaW50byB0aGVcbiAgLy8gVm9sdW1lIC8gSXNvc3VyZmFjZSB2aWV3czogdGhleSByYXltYXJjaCB0aGUgaW1hZ2Ugc3RhY2ssIGFuZCBhIHN0YWNrIHdpdGggbm9cbiAgLy8gZGVjbGFyZWQgc2xpY2Ugc3BhY2luZyBjYW4gb25seSBiZSBnaXZlbiBhIHNoYXBlLW9ubHkgd29ybGQgYm94LlxuICBjb25zdCBtcHBaID0gcGVyVW5pdCAhPSBudWxsID8gbWV0YS52b3hlbFNpemVbMl0gKiBwZXJVbml0IDogbnVsbDtcblxuICByZXR1cm4ge1xuICAgIHVybHMsXG4gICAgaW5mbzoge1xuICAgICAgLy8gQSBzY2FsYXIgZmllbGQ6IG9uZSBiYW5kLCBubyBjb2xvdXIgb2YgaXRzIG93biDigJQgd2hpY2ggaXMgYWxzbyB3aGF0IHB1dHNcbiAgICAgIC8vIHRoZSBzY2FsYXIgbW9kZXMgKEhlYXRtYXAgLyBDb250b3VyIC8gU3VyZmFjZSAvIFZvbHVtZSkgbGVnaXRpbWF0ZWx5IG9uXG4gICAgICAvLyBvZmZlciBmb3IgYSBkYXRhc2V0IHRoYXQgaGFzIG5vIGNhbWVyYSBpbWFnZSBhbnl3aGVyZSBpbiBpdC5cbiAgICAgIGlzR3JheXNjYWxlOiB0cnVlLFxuICAgICAgdHJ1ZUltYWdlU2l6ZTogW3dpZHRoLCBoZWlnaHRdLFxuICAgICAgdXJscyxcbiAgICAgIGlzU3RhY2s6IGRlcHRoID4gMSxcbiAgICAgIHNob3dTdGFjazogZmFsc2UsXG4gICAgICBzY2FsZVJhdGlvOiB0cnVlLFxuICAgICAgLy8gU3RhYmxlIEFORCB1bmlxdWUgcGVyIGRhdGFzZXQ6IHRoZSBzbGljZS1ibG9iIGNhY2hlIGtleXMgb2ZmIHRoZSBmaWxlIG5hbWUsXG4gICAgICAvLyBzbyBhIG5hbWUgdGhhdCBjaGFuZ2VkIHBlciBsb2FkIHdvdWxkIHJlLWZldGNoIGEgdm9sdW1lIHRoYXQgbmV2ZXIgbW92ZWQg4oCUXG4gICAgICAvLyBhbmQgYSBuYW1lIFNIQVJFRCBieSB0d28gZGF0YXNldHMgKG9ubHkgYGlkYCBpcyByZXF1aXJlZCB0byBiZSB1bmlxdWUpXG4gICAgICAvLyB3b3VsZCBzZXJ2ZSBvbmUgZGF0YXNldCdzIHNsaWNlcyBmb3IgdGhlIG90aGVyLlxuICAgICAgZmlsZU5hbWU6IGAke2RhdGFzZXQubmFtZX0gwrcgcmVmZXJlbmNlIHZvbHVtZSBbJHtkYXRhc2V0LmlkfV1gLFxuICAgICAgaW1hZ2VNZXRhOiBbeyBjaGFubmVsQ291bnQ6IDEsIHJnYkNoYW5uZWxzOiAxLCB4OiB3aWR0aCwgeTogaGVpZ2h0LCB6OiBkZXB0aCwgbXBwWCwgbXBwWSwgbXBwWiB9XSxcbiAgICAgIC8vIEJsb2IgVVJMcyBhcmUgY29tcGxldGUgaW1hZ2VzOiBPU0QgbXVzdCBvcGVuIHRoZW0gZGlyZWN0bHksIG5vdCBhc2sgYSB0aWxlXG4gICAgICAvLyBzZXJ2ZXIgZm9yIGEgcHlyYW1pZCB0aGF0IGRvZXMgbm90IGV4aXN0LlxuICAgICAgdGlsZWQ6IGZhbHNlLFxuICAgICAgLy8gT3BlbiBtaWQtdm9sdW1lLiBUaGUgZmlyc3QgYW5kIGxhc3QgcGxhbmVzIG9mIGFuIGFuYXRvbWljYWwgdm9sdW1lIGFyZVxuICAgICAgLy8gb3V0c2lkZSB0aGUgc3BlY2ltZW4g4oCUIG9wZW5pbmcgb24gc2xpY2UgMCBzaG93cyBhbiBlbXB0eSBmcmFtZSBhbmQgcmVhZHNcbiAgICAgIC8vIGFzIGEgZmFpbGVkIGxvYWQuXG4gICAgICBpbml0aWFsWkluZGV4OiBkZXB0aCA+IDEgPyBkZXB0aCA+PiAxIDogdW5kZWZpbmVkLFxuICAgIH0sXG4gIH07XG59XG5cbi8qKlxuICogVGhlIGRhdGHihpJpbWFnZSBhZmZpbmUgYSByZWdpc3RlcmVkIHZvbHVtZSBpbXBsaWVzLlxuICpcbiAqIE9uY2UgdGhlIHZvbHVtZSBJUyB0aGUgaW1hZ2UgKHtAbGluayBidWlsZFZvbHVtZVN0YWNrSW1hZ2V9KSwgb25lIHNsaWNlIGlzIGFcbiAqIGB3aWR0aCB4IGhlaWdodGAgcGl4ZWwgZ3JpZCB3aG9zZSB2b3hlbCBgKGksIGopYCBjb3ZlcnNcbiAqIGBbaSAqIHZveGVsU2l6ZVswXSwgKGkgKyAxKSAqIHZveGVsU2l6ZVswXSlgIG9mIHRoZSBvYnNlcnZhdGlvbnMnIGNvb3JkaW5hdGVcbiAqIHNwYWNlIOKAlCB0aGUgY29udHJhY3QncyBydWxlIHRoYXQgdGhlIHZvbHVtZSdzIG5lYXIgY29ybmVyIHNpdHMgYXQgdGhlXG4gKiBjb29yZGluYXRlIG9yaWdpbi4gU28gb2JzZXJ2YXRpb25zIHJlYWNoIHBpeGVsIHNwYWNlIGJ5IGRpdmlkaW5nIG91dCB0aGUgdm94ZWxcbiAqIHNpemUsIGFuZCBub3RoaW5nIGhhcyB0byBtb3ZlLlxuICpcbiAqIFNoYXBlZCBhcyBhIGBTcGF0aWFsSW1hZ2VSZWZgIG9uIHB1cnBvc2U6IHRoZSBtYXJrZXIgbGF5ZXIgYW5kIHRoZSBST0lcbiAqIHNlbGVjdGlvbiB0aGVuIHRha2UgdGhlIFNBTUUgdHJhbnNmb3JtIHRoZXkgdGFrZSBmb3IgYSBkYXRhc2V0IHRoYXQgc2hpcHMgYVxuICogcmVhbCBgaW1hZ2VSZWZgLCBpbnN0ZWFkIG9mIGVhY2ggZ3Jvd2luZyBhIHZvbHVtZSBzcGVjaWFsIGNhc2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2b2x1bWVJbWFnZVJlZih2b2x1bWU6IFNwYXRpYWxWb2x1bWVNZXRhLCBtaWNyb25zUGVyVW5pdD86IG51bWJlcik6IFNwYXRpYWxJbWFnZVJlZiB7XG4gIGNvbnN0IFt2eCwgdnldID0gdm9sdW1lLnZveGVsU2l6ZTtcbiAgcmV0dXJuIHtcbiAgICBzY2FsZTogWzEgLyB2eCwgMSAvIHZ5XSxcbiAgICB0cmFuc2xhdGU6IFswLCAwXSxcbiAgICAuLi4obWljcm9uc1BlclVuaXQgIT0gbnVsbCA/IHsgbXBwWDogdnggKiBtaWNyb25zUGVyVW5pdCwgbXBwWTogdnkgKiBtaWNyb25zUGVyVW5pdCB9IDoge30pLFxuICB9O1xufVxuXG4vKiogVGhlIHZveGVsIHBsYW5lIGEgY29vcmRpbmF0ZSBmYWxscyBpbiwgY2xhbXBlZCBpbnRvIHRoZSB2b2x1bWUuICovXG5leHBvcnQgZnVuY3Rpb24gc2xpY2VJbmRleE9mKHo6IG51bWJlciwgdm9sdW1lOiBTcGF0aWFsVm9sdW1lTWV0YSk6IG51bWJlciB7XG4gIGNvbnN0IGsgPSBNYXRoLmZsb29yKHogLyB2b2x1bWUudm94ZWxTaXplWzJdKTtcbiAgcmV0dXJuIE1hdGgubWF4KDAsIE1hdGgubWluKHZvbHVtZS5kZXB0aCAtIDEsIGspKTtcbn1cblxuLyoqXG4gKiBJbmRpY2VzIG9mIHRoZSBvYnNlcnZhdGlvbnMgdGhhdCBmYWxsIGluIG9uZSB2b3hlbCBwbGFuZSBvZiB0aGUgdm9sdW1lLlxuICpcbiAqIEEgMkQgdmlldyBvZiBhIDNEIGRhdGFzZXQgc2hvd3MgT05FIHBsYW5lLCBzbyBpdCBtdXN0IGRyYXcgb25lIHBsYW5lJ3NcbiAqIG9ic2VydmF0aW9uczogd2l0aG91dCB0aGlzIHRoZSB3aG9sZSBkZXB0aCBvZiB0aGUgc3BlY2ltZW4gcGlsZXMgb250byBhIHNpbmdsZVxuICogc2VjdGlvbiBhbmQgcmVhZHMgYXMgYSBzb2xpZCBzbWVhciByYXRoZXIgdGhhbiBhIHNlY3Rpb24ncyBjZWxscy4gVGhlIHBsYW5lIGlzXG4gKiBhIHNsYWIgYHZveGVsU2l6ZVsyXWAgdGhpY2ssIHdoaWNoIGlzIGV4YWN0bHkgdGhlIHNhbXBsaW5nIHRoZSB2b2x1bWUgaXRzZWxmXG4gKiBoYXMg4oCUIGZvciBzZXJpYWwgc2VjdGlvbnMgcmVnaXN0ZXJlZCBpbnRvIGEgY29tbW9uIGZyYW1lLCBvbmUgc2xhYiBpcyBvbmVcbiAqIHNlY3Rpb24uXG4gKlxuICogRXZlcnkgb2JzZXJ2YXRpb24gaXMgaW4gdGhlIHBsYW5lIHdoZW4gdGhlIGRhdGFzZXQgY2FycmllcyBubyB6OiBhIGdlbnVpbmVseVxuICogZmxhdCBkYXRhc2V0IG92ZXIgYSB2b2x1bWUgaGFzIG5vdGhpbmcgdG8gZmlsdGVyIG9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gb2JzZXJ2YXRpb25zSW5TbGljZShcbiAgb2JzOiBTcGF0aWFsT2JzZXJ2YXRpb25zLFxuICB2b2x1bWU6IFNwYXRpYWxWb2x1bWVNZXRhLFxuICBzbGljZTogbnVtYmVyLFxuKTogVWludDMyQXJyYXkge1xuICBjb25zdCB6ID0gb2JzLno7XG4gIGlmICgheikgcmV0dXJuIFVpbnQzMkFycmF5LmZyb20oeyBsZW5ndGg6IG9icy5jb3VudCB9LCAoXywgaSkgPT4gaSk7XG4gIGNvbnN0IG91dCA9IG5ldyBVaW50MzJBcnJheShvYnMuY291bnQpO1xuICBsZXQgbiA9IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgb2JzLmNvdW50OyBpKyspIHtcbiAgICBpZiAoc2xpY2VJbmRleE9mKHpbaV0sIHZvbHVtZSkgPT09IHNsaWNlKSBvdXRbbisrXSA9IGk7XG4gIH1cbiAgcmV0dXJuIG91dC5zdWJhcnJheSgwLCBuKTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Percentiles for the spatial code: one "collect, sort, index" routine instead of one per
|
|
3
|
+
* caller.
|
|
4
|
+
*
|
|
5
|
+
* The callers used to differ in rounding (`round(p·(n-1))` against `floor(p·n)`), in
|
|
6
|
+
* sampling and in filtering, so windows computed for the same data in different views
|
|
7
|
+
* could disagree. Here there is one rule for each:
|
|
8
|
+
*
|
|
9
|
+
* - **Rank**: `round(p·(n-1))` — the nearest rank. `floor(p·n)` is biased upward and
|
|
10
|
+
* hands back the maximum for `p = 0.99` on a hundred values, outlier included.
|
|
11
|
+
* - **Sort**: a typed-array sort, which is native and numeric — several times faster
|
|
12
|
+
* than a comparator sort of a boxed `number[]`, and far lighter on the heap.
|
|
13
|
+
* - **Sample**: past `2·sampleSize` qualifying values, every `floor(count/sampleSize)`-th
|
|
14
|
+
* one, which is plenty for a display window and keeps a 3.7M-cell recolour from
|
|
15
|
+
* sorting 3.7M values.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* The `ps` quantiles (each 0..1, clamped) of the values that qualify, or null when none do.
|
|
19
|
+
*/
|
|
20
|
+
export function quantiles(values, ps, opts = {}) {
|
|
21
|
+
const positive = opts.filter === 'positive';
|
|
22
|
+
const where = opts.where;
|
|
23
|
+
const n = values.length;
|
|
24
|
+
const keep = (i) => {
|
|
25
|
+
const v = values[i];
|
|
26
|
+
if (positive ? !(v > 0) : !Number.isFinite(v))
|
|
27
|
+
return false;
|
|
28
|
+
return !where || where[i] > 0;
|
|
29
|
+
};
|
|
30
|
+
let count = 0;
|
|
31
|
+
for (let i = 0; i < n; i++)
|
|
32
|
+
if (keep(i))
|
|
33
|
+
count++;
|
|
34
|
+
if (count === 0)
|
|
35
|
+
return null;
|
|
36
|
+
const step = opts.sampleSize && count >= 2 * opts.sampleSize ? Math.floor(count / opts.sampleSize) : 1;
|
|
37
|
+
const sample = new Float64Array(Math.ceil(count / step));
|
|
38
|
+
let seen = 0;
|
|
39
|
+
let k = 0;
|
|
40
|
+
for (let i = 0; i < n && k < sample.length; i++) {
|
|
41
|
+
if (!keep(i))
|
|
42
|
+
continue;
|
|
43
|
+
if (seen++ % step === 0)
|
|
44
|
+
sample[k++] = values[i];
|
|
45
|
+
}
|
|
46
|
+
const sorted = sample.subarray(0, k).sort();
|
|
47
|
+
const last = sorted.length - 1;
|
|
48
|
+
return ps.map((p) => {
|
|
49
|
+
const f = Math.max(0, Math.min(1, Number.isFinite(p) ? p : 0));
|
|
50
|
+
return sorted[Math.round(f * last)];
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
/** One quantile; see {@link quantiles}. */
|
|
54
|
+
export function quantile(values, p, opts = {}) {
|
|
55
|
+
return quantiles(values, [p], opts)?.[0] ?? null;
|
|
56
|
+
}
|
|
57
|
+
/** Sample size for a contrast window: a display window does not need every value. */
|
|
58
|
+
export const WINDOW_SAMPLE_SIZE = 65_536;
|
|
59
|
+
/**
|
|
60
|
+
* A `[lo, hi]` percentile window over the qualifying values, never flat or inverted
|
|
61
|
+
* (a flat window would divide by zero downstream, so it is widened by one), and `[0, 1]`
|
|
62
|
+
* when nothing qualifies, so callers always get a usable window.
|
|
63
|
+
*/
|
|
64
|
+
export function percentileWindow(values, lo, hi, opts = {}) {
|
|
65
|
+
const q = quantiles(values, [lo, hi], { sampleSize: WINDOW_SAMPLE_SIZE, ...opts });
|
|
66
|
+
if (!q)
|
|
67
|
+
return [0, 1];
|
|
68
|
+
const [min, max] = q;
|
|
69
|
+
return max > min ? [min, max] : [min, min + 1];
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3NwYXRpYWwvc3RhdHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBV0g7O0dBRUc7QUFDSCxNQUFNLFVBQVUsU0FBUyxDQUN2QixNQUF5QixFQUN6QixFQUFxQixFQUNyQixPQUF3QixFQUFFO0lBRTFCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxNQUFNLEtBQUssVUFBVSxDQUFDO0lBQzVDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7SUFDekIsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUN4QixNQUFNLElBQUksR0FBRyxDQUFDLENBQVMsRUFBVyxFQUFFO1FBQ2xDLE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNwQixJQUFJLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztZQUFFLE9BQU8sS0FBSyxDQUFDO1FBQzVELE9BQU8sQ0FBQyxLQUFLLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNoQyxDQUFDLENBQUM7SUFFRixJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7SUFDZCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRTtRQUFFLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQztZQUFFLEtBQUssRUFBRSxDQUFDO0lBQ2pELElBQUksS0FBSyxLQUFLLENBQUM7UUFBRSxPQUFPLElBQUksQ0FBQztJQUU3QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsVUFBVSxJQUFJLEtBQUssSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDdkcsTUFBTSxNQUFNLEdBQUcsSUFBSSxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUN6RCxJQUFJLElBQUksR0FBRyxDQUFDLENBQUM7SUFDYixJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDVixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDaEQsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7WUFBRSxTQUFTO1FBQ3ZCLElBQUksSUFBSSxFQUFFLEdBQUcsSUFBSSxLQUFLLENBQUM7WUFBRSxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbkQsQ0FBQztJQUNELE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzVDLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQy9CLE9BQU8sRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO1FBQ2xCLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMvRCxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ3RDLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELDJDQUEyQztBQUMzQyxNQUFNLFVBQVUsUUFBUSxDQUFDLE1BQXlCLEVBQUUsQ0FBUyxFQUFFLE9BQXdCLEVBQUU7SUFDdkYsT0FBTyxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUM7QUFDbkQsQ0FBQztBQUVELHFGQUFxRjtBQUNyRixNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLENBQUM7QUFFekM7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxnQkFBZ0IsQ0FDOUIsTUFBeUIsRUFDekIsRUFBVSxFQUNWLEVBQVUsRUFDVixPQUF3QixFQUFFO0lBRTFCLE1BQU0sQ0FBQyxHQUFHLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxVQUFVLEVBQUUsa0JBQWtCLEVBQUUsR0FBRyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ25GLElBQUksQ0FBQyxDQUFDO1FBQUUsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUN0QixNQUFNLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNyQixPQUFPLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDakQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUGVyY2VudGlsZXMgZm9yIHRoZSBzcGF0aWFsIGNvZGU6IG9uZSBcImNvbGxlY3QsIHNvcnQsIGluZGV4XCIgcm91dGluZSBpbnN0ZWFkIG9mIG9uZSBwZXJcbiAqIGNhbGxlci5cbiAqXG4gKiBUaGUgY2FsbGVycyB1c2VkIHRvIGRpZmZlciBpbiByb3VuZGluZyAoYHJvdW5kKHDCtyhuLTEpKWAgYWdhaW5zdCBgZmxvb3IocMK3bilgKSwgaW5cbiAqIHNhbXBsaW5nIGFuZCBpbiBmaWx0ZXJpbmcsIHNvIHdpbmRvd3MgY29tcHV0ZWQgZm9yIHRoZSBzYW1lIGRhdGEgaW4gZGlmZmVyZW50IHZpZXdzXG4gKiBjb3VsZCBkaXNhZ3JlZS4gSGVyZSB0aGVyZSBpcyBvbmUgcnVsZSBmb3IgZWFjaDpcbiAqXG4gKiAgLSAqKlJhbmsqKjogYHJvdW5kKHDCtyhuLTEpKWAg4oCUIHRoZSBuZWFyZXN0IHJhbmsuIGBmbG9vcihwwrduKWAgaXMgYmlhc2VkIHVwd2FyZCBhbmRcbiAqICAgIGhhbmRzIGJhY2sgdGhlIG1heGltdW0gZm9yIGBwID0gMC45OWAgb24gYSBodW5kcmVkIHZhbHVlcywgb3V0bGllciBpbmNsdWRlZC5cbiAqICAtICoqU29ydCoqOiBhIHR5cGVkLWFycmF5IHNvcnQsIHdoaWNoIGlzIG5hdGl2ZSBhbmQgbnVtZXJpYyDigJQgc2V2ZXJhbCB0aW1lcyBmYXN0ZXJcbiAqICAgIHRoYW4gYSBjb21wYXJhdG9yIHNvcnQgb2YgYSBib3hlZCBgbnVtYmVyW11gLCBhbmQgZmFyIGxpZ2h0ZXIgb24gdGhlIGhlYXAuXG4gKiAgLSAqKlNhbXBsZSoqOiBwYXN0IGAywrdzYW1wbGVTaXplYCBxdWFsaWZ5aW5nIHZhbHVlcywgZXZlcnkgYGZsb29yKGNvdW50L3NhbXBsZVNpemUpYC10aFxuICogICAgb25lLCB3aGljaCBpcyBwbGVudHkgZm9yIGEgZGlzcGxheSB3aW5kb3cgYW5kIGtlZXBzIGEgMy43TS1jZWxsIHJlY29sb3VyIGZyb21cbiAqICAgIHNvcnRpbmcgMy43TSB2YWx1ZXMuXG4gKi9cblxuZXhwb3J0IGludGVyZmFjZSBRdWFudGlsZU9wdGlvbnMge1xuICAvKiogV2hpY2ggdmFsdWVzIGNvdW50OiBldmVyeSBmaW5pdGUgb25lICh0aGUgZGVmYXVsdCksIG9yIG9ubHkgdGhvc2UgYWJvdmUgemVyby4gKi9cbiAgZmlsdGVyPzogJ2Zpbml0ZScgfCAncG9zaXRpdmUnO1xuICAvKiogQ291bnQgaW5kZXggYGlgIG9ubHkgd2hlcmUgYHdoZXJlW2ldID4gMGAg4oCUIGUuZy4gYSBmaWVsZCdzIHN1cHBvcnQuICovXG4gIHdoZXJlPzogQXJyYXlMaWtlPG51bWJlcj47XG4gIC8qKiBTYW1wbGUgZG93biB0byBhYm91dCB0aGlzIG1hbnkgdmFsdWVzIChzZWUgdGhlIG1vZHVsZSBkb2MpOyB1bnNhbXBsZWQgd2hlbiBhYnNlbnQuICovXG4gIHNhbXBsZVNpemU/OiBudW1iZXI7XG59XG5cbi8qKlxuICogVGhlIGBwc2AgcXVhbnRpbGVzIChlYWNoIDAuLjEsIGNsYW1wZWQpIG9mIHRoZSB2YWx1ZXMgdGhhdCBxdWFsaWZ5LCBvciBudWxsIHdoZW4gbm9uZSBkby5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHF1YW50aWxlcyhcbiAgdmFsdWVzOiBBcnJheUxpa2U8bnVtYmVyPixcbiAgcHM6IHJlYWRvbmx5IG51bWJlcltdLFxuICBvcHRzOiBRdWFudGlsZU9wdGlvbnMgPSB7fSxcbik6IG51bWJlcltdIHwgbnVsbCB7XG4gIGNvbnN0IHBvc2l0aXZlID0gb3B0cy5maWx0ZXIgPT09ICdwb3NpdGl2ZSc7XG4gIGNvbnN0IHdoZXJlID0gb3B0cy53aGVyZTtcbiAgY29uc3QgbiA9IHZhbHVlcy5sZW5ndGg7XG4gIGNvbnN0IGtlZXAgPSAoaTogbnVtYmVyKTogYm9vbGVhbiA9PiB7XG4gICAgY29uc3QgdiA9IHZhbHVlc1tpXTtcbiAgICBpZiAocG9zaXRpdmUgPyAhKHYgPiAwKSA6ICFOdW1iZXIuaXNGaW5pdGUodikpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gIXdoZXJlIHx8IHdoZXJlW2ldID4gMDtcbiAgfTtcblxuICBsZXQgY291bnQgPSAwO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgaWYgKGtlZXAoaSkpIGNvdW50Kys7XG4gIGlmIChjb3VudCA9PT0gMCkgcmV0dXJuIG51bGw7XG5cbiAgY29uc3Qgc3RlcCA9IG9wdHMuc2FtcGxlU2l6ZSAmJiBjb3VudCA+PSAyICogb3B0cy5zYW1wbGVTaXplID8gTWF0aC5mbG9vcihjb3VudCAvIG9wdHMuc2FtcGxlU2l6ZSkgOiAxO1xuICBjb25zdCBzYW1wbGUgPSBuZXcgRmxvYXQ2NEFycmF5KE1hdGguY2VpbChjb3VudCAvIHN0ZXApKTtcbiAgbGV0IHNlZW4gPSAwO1xuICBsZXQgayA9IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbiAmJiBrIDwgc2FtcGxlLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKCFrZWVwKGkpKSBjb250aW51ZTtcbiAgICBpZiAoc2VlbisrICUgc3RlcCA9PT0gMCkgc2FtcGxlW2srK10gPSB2YWx1ZXNbaV07XG4gIH1cbiAgY29uc3Qgc29ydGVkID0gc2FtcGxlLnN1YmFycmF5KDAsIGspLnNvcnQoKTtcbiAgY29uc3QgbGFzdCA9IHNvcnRlZC5sZW5ndGggLSAxO1xuICByZXR1cm4gcHMubWFwKChwKSA9PiB7XG4gICAgY29uc3QgZiA9IE1hdGgubWF4KDAsIE1hdGgubWluKDEsIE51bWJlci5pc0Zpbml0ZShwKSA/IHAgOiAwKSk7XG4gICAgcmV0dXJuIHNvcnRlZFtNYXRoLnJvdW5kKGYgKiBsYXN0KV07XG4gIH0pO1xufVxuXG4vKiogT25lIHF1YW50aWxlOyBzZWUge0BsaW5rIHF1YW50aWxlc30uICovXG5leHBvcnQgZnVuY3Rpb24gcXVhbnRpbGUodmFsdWVzOiBBcnJheUxpa2U8bnVtYmVyPiwgcDogbnVtYmVyLCBvcHRzOiBRdWFudGlsZU9wdGlvbnMgPSB7fSk6IG51bWJlciB8IG51bGwge1xuICByZXR1cm4gcXVhbnRpbGVzKHZhbHVlcywgW3BdLCBvcHRzKT8uWzBdID8/IG51bGw7XG59XG5cbi8qKiBTYW1wbGUgc2l6ZSBmb3IgYSBjb250cmFzdCB3aW5kb3c6IGEgZGlzcGxheSB3aW5kb3cgZG9lcyBub3QgbmVlZCBldmVyeSB2YWx1ZS4gKi9cbmV4cG9ydCBjb25zdCBXSU5ET1dfU0FNUExFX1NJWkUgPSA2NV81MzY7XG5cbi8qKlxuICogQSBgW2xvLCBoaV1gIHBlcmNlbnRpbGUgd2luZG93IG92ZXIgdGhlIHF1YWxpZnlpbmcgdmFsdWVzLCBuZXZlciBmbGF0IG9yIGludmVydGVkXG4gKiAoYSBmbGF0IHdpbmRvdyB3b3VsZCBkaXZpZGUgYnkgemVybyBkb3duc3RyZWFtLCBzbyBpdCBpcyB3aWRlbmVkIGJ5IG9uZSksIGFuZCBgWzAsIDFdYFxuICogd2hlbiBub3RoaW5nIHF1YWxpZmllcywgc28gY2FsbGVycyBhbHdheXMgZ2V0IGEgdXNhYmxlIHdpbmRvdy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBlcmNlbnRpbGVXaW5kb3coXG4gIHZhbHVlczogQXJyYXlMaWtlPG51bWJlcj4sXG4gIGxvOiBudW1iZXIsXG4gIGhpOiBudW1iZXIsXG4gIG9wdHM6IFF1YW50aWxlT3B0aW9ucyA9IHt9LFxuKTogW251bWJlciwgbnVtYmVyXSB7XG4gIGNvbnN0IHEgPSBxdWFudGlsZXModmFsdWVzLCBbbG8sIGhpXSwgeyBzYW1wbGVTaXplOiBXSU5ET1dfU0FNUExFX1NJWkUsIC4uLm9wdHMgfSk7XG4gIGlmICghcSkgcmV0dXJuIFswLCAxXTtcbiAgY29uc3QgW21pbiwgbWF4XSA9IHE7XG4gIHJldHVybiBtYXggPiBtaW4gPyBbbWluLCBtYXhdIDogW21pbiwgbWluICsgMV07XG59XG4iXX0=
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transcript grouping and marker sizing: how many transcripts one marker stands for at the
|
|
3
|
+
* current zoom, how big it is drawn, and which colour each gene-tree cluster takes. Pure, so
|
|
4
|
+
* the budget policy is testable without a viewer.
|
|
5
|
+
*/
|
|
6
|
+
import { visibleArea } from './lod';
|
|
7
|
+
import { quantile } from './stats';
|
|
8
|
+
/** Smallest on-screen spacing between groups, in px — below it groups read as noise. */
|
|
9
|
+
export const GROUP_MIN_SPACING_PX = 14;
|
|
10
|
+
/**
|
|
11
|
+
* The bin a selection of genes is grouped into at this zoom, in observation units, or null
|
|
12
|
+
* to draw every transcript. Bins follow the all-gene pyramid's ladder (`baseBin` × 2^m) so a
|
|
13
|
+
* gene selection and "all genes" group alike: the finest bin whose markers land at least
|
|
14
|
+
* `spacingPx` apart on screen. Once the finest bin is that wide, transcripts are drawn as
|
|
15
|
+
* themselves.
|
|
16
|
+
*/
|
|
17
|
+
export function geneBinSize(pxPerUnit, baseBin, levels = 7, spacingPx = GROUP_MIN_SPACING_PX) {
|
|
18
|
+
if (!(pxPerUnit > 0) || !(baseBin > 0))
|
|
19
|
+
return null;
|
|
20
|
+
if (baseBin * pxPerUnit >= spacingPx)
|
|
21
|
+
return null;
|
|
22
|
+
for (let m = 1; m < levels; m++) {
|
|
23
|
+
const bin = baseBin * 2 ** m;
|
|
24
|
+
if (bin * pxPerUnit >= spacingPx)
|
|
25
|
+
return bin;
|
|
26
|
+
}
|
|
27
|
+
return baseBin * 2 ** (levels - 1);
|
|
28
|
+
}
|
|
29
|
+
/** The entries of `t` inside `rect` (observation units). */
|
|
30
|
+
export function clipTranscripts(t, rect) {
|
|
31
|
+
const keep = [];
|
|
32
|
+
for (let i = 0; i < t.count; i++) {
|
|
33
|
+
if (t.x[i] >= rect.x0 && t.x[i] <= rect.x1 && t.y[i] >= rect.y0 && t.y[i] <= rect.y1)
|
|
34
|
+
keep.push(i);
|
|
35
|
+
}
|
|
36
|
+
if (keep.length === t.count)
|
|
37
|
+
return t;
|
|
38
|
+
const pick = (a) => {
|
|
39
|
+
const out = new a.constructor(keep.length);
|
|
40
|
+
keep.forEach((src, i) => {
|
|
41
|
+
out[i] = a[src];
|
|
42
|
+
});
|
|
43
|
+
return out;
|
|
44
|
+
};
|
|
45
|
+
return {
|
|
46
|
+
count: keep.length,
|
|
47
|
+
aggregated: t.aggregated,
|
|
48
|
+
x: pick(t.x),
|
|
49
|
+
y: pick(t.y),
|
|
50
|
+
z: pick(t.z),
|
|
51
|
+
weight: pick(t.weight),
|
|
52
|
+
observation: pick(t.observation),
|
|
53
|
+
gene: pick(t.gene),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
// ── Grouping ──────────────────────────────────────────────────────────────────────────
|
|
57
|
+
/**
|
|
58
|
+
* Group transcripts into `bin`-wide squares of a grid anchored at the origin (so a pan does
|
|
59
|
+
* not move them), one entry per (group, square): `groupOf(gene slot)` says which group a gene
|
|
60
|
+
* is in — its cluster in the gene tree, or itself. Each entry sits at its transcripts'
|
|
61
|
+
* centroid, weighted by how many each stands for; it takes the gene and the cell holding most
|
|
62
|
+
* of them, each summed over all its transcripts in the entry. `group[i]` is entry i's group.
|
|
63
|
+
*/
|
|
64
|
+
export function groupTranscripts(t, bin, groupOf = (g) => g) {
|
|
65
|
+
// Hot on every pan and zoom, so nothing is allocated per transcript: the (group, square)
|
|
66
|
+
// key is a number over the tile's own bounded extent rather than a template string, and
|
|
67
|
+
// the per-entry gene and cell tallies share two flat maps instead of two Maps per entry.
|
|
68
|
+
const count = t.count;
|
|
69
|
+
const gks = new Int32Array(count);
|
|
70
|
+
let minBx = Infinity;
|
|
71
|
+
let maxBx = -Infinity;
|
|
72
|
+
let minBy = Infinity;
|
|
73
|
+
let maxBy = -Infinity;
|
|
74
|
+
for (let i = 0; i < count; i++) {
|
|
75
|
+
gks[i] = groupOf(t.gene[i]);
|
|
76
|
+
const bx = Math.floor(t.x[i] / bin);
|
|
77
|
+
const by = Math.floor(t.y[i] / bin);
|
|
78
|
+
if (bx < minBx)
|
|
79
|
+
minBx = bx;
|
|
80
|
+
if (bx > maxBx)
|
|
81
|
+
maxBx = bx;
|
|
82
|
+
if (by < minBy)
|
|
83
|
+
minBy = by;
|
|
84
|
+
if (by > maxBy)
|
|
85
|
+
maxBy = by;
|
|
86
|
+
}
|
|
87
|
+
// One spare column and row for a square that is not finite (a NaN coordinate), so such
|
|
88
|
+
// transcripts still group together rather than colliding with a real square.
|
|
89
|
+
const cols = Number.isFinite(maxBx - minBx) ? maxBx - minBx + 2 : 1;
|
|
90
|
+
const rows = Number.isFinite(maxBy - minBy) ? maxBy - minBy + 2 : 1;
|
|
91
|
+
const col = (v) => {
|
|
92
|
+
const b = Math.floor(v / bin);
|
|
93
|
+
return Number.isFinite(b) ? b - minBx : cols - 1;
|
|
94
|
+
};
|
|
95
|
+
const row = (v) => {
|
|
96
|
+
const b = Math.floor(v / bin);
|
|
97
|
+
return Number.isFinite(b) ? b - minBy : rows - 1;
|
|
98
|
+
};
|
|
99
|
+
const index = new Map();
|
|
100
|
+
const sx = [];
|
|
101
|
+
const sy = [];
|
|
102
|
+
const sz = [];
|
|
103
|
+
const w = [];
|
|
104
|
+
const grp = [];
|
|
105
|
+
// Per entry, how many transcripts of each gene (the dominant one gives the icon and colour)
|
|
106
|
+
// and in each cell (the dominant one is the entry's cell).
|
|
107
|
+
const genes = new DominantTally();
|
|
108
|
+
const cells = new DominantTally();
|
|
109
|
+
for (let i = 0; i < count; i++) {
|
|
110
|
+
const gk = gks[i];
|
|
111
|
+
const key = (gk * rows + row(t.y[i])) * cols + col(t.x[i]);
|
|
112
|
+
let k = index.get(key);
|
|
113
|
+
const wi = t.weight[i] || 1;
|
|
114
|
+
if (k === undefined) {
|
|
115
|
+
k = w.length;
|
|
116
|
+
index.set(key, k);
|
|
117
|
+
sx.push(0);
|
|
118
|
+
sy.push(0);
|
|
119
|
+
sz.push(0);
|
|
120
|
+
w.push(0);
|
|
121
|
+
grp.push(gk);
|
|
122
|
+
}
|
|
123
|
+
sx[k] += t.x[i] * wi;
|
|
124
|
+
sy[k] += t.y[i] * wi;
|
|
125
|
+
sz[k] += t.z[i] * wi;
|
|
126
|
+
w[k] += wi;
|
|
127
|
+
genes.add(k, t.gene[i], wi);
|
|
128
|
+
cells.add(k, t.observation[i], wi);
|
|
129
|
+
}
|
|
130
|
+
const n = w.length;
|
|
131
|
+
const tile = {
|
|
132
|
+
count: n,
|
|
133
|
+
aggregated: true,
|
|
134
|
+
x: new Float32Array(n),
|
|
135
|
+
y: new Float32Array(n),
|
|
136
|
+
z: new Float32Array(n),
|
|
137
|
+
weight: new Uint32Array(n),
|
|
138
|
+
observation: new Uint32Array(n),
|
|
139
|
+
gene: new Uint16Array(n),
|
|
140
|
+
};
|
|
141
|
+
const group = new Int32Array(n);
|
|
142
|
+
for (let k = 0; k < n; k++) {
|
|
143
|
+
tile.x[k] = sx[k] / w[k];
|
|
144
|
+
tile.y[k] = sy[k] / w[k];
|
|
145
|
+
tile.z[k] = sz[k] / w[k];
|
|
146
|
+
tile.weight[k] = w[k];
|
|
147
|
+
tile.observation[k] = cells.dominant(k);
|
|
148
|
+
tile.gene[k] = genes.dominant(k);
|
|
149
|
+
group[k] = grp[k];
|
|
150
|
+
}
|
|
151
|
+
return { tile, group };
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Weighted tallies of u32 keys per entry, tracking each entry's dominant key as it goes:
|
|
155
|
+
* the key with the largest total, the first seen on a tie.
|
|
156
|
+
*
|
|
157
|
+
* One map for every entry, keyed `entry · 2^32 + key` — exact while entries stay below
|
|
158
|
+
* 2^21, far above any marker budget.
|
|
159
|
+
*/
|
|
160
|
+
class DominantTally {
|
|
161
|
+
constructor() {
|
|
162
|
+
this.total = new Map();
|
|
163
|
+
this.firstSeen = new Map();
|
|
164
|
+
this.seq = 0;
|
|
165
|
+
this.bestKey = [];
|
|
166
|
+
this.bestTotal = [];
|
|
167
|
+
this.bestSeen = [];
|
|
168
|
+
}
|
|
169
|
+
static { this.KEY_SPAN = 2 ** 32; }
|
|
170
|
+
add(entry, key, weight) {
|
|
171
|
+
const id = entry * DominantTally.KEY_SPAN + key;
|
|
172
|
+
const v = (this.total.get(id) ?? 0) + weight;
|
|
173
|
+
this.total.set(id, v);
|
|
174
|
+
let first = this.firstSeen.get(id);
|
|
175
|
+
if (first === undefined) {
|
|
176
|
+
first = this.seq++;
|
|
177
|
+
this.firstSeen.set(id, first);
|
|
178
|
+
}
|
|
179
|
+
const top = this.bestTotal[entry];
|
|
180
|
+
if (top === undefined || v > top || (v === top && first < this.bestSeen[entry])) {
|
|
181
|
+
this.bestKey[entry] = key;
|
|
182
|
+
this.bestTotal[entry] = v;
|
|
183
|
+
this.bestSeen[entry] = first;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
dominant(entry) {
|
|
187
|
+
return this.bestKey[entry] ?? 0;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
// ── Cluster colours ───────────────────────────────────────────────────────────────────
|
|
191
|
+
/**
|
|
192
|
+
* The colour of each gene-tree cluster of a selection, for colouring transcripts by cluster: a
|
|
193
|
+
* cluster named like a group of the cells' grouping takes that group's colour (its cells and its
|
|
194
|
+
* transcripts agree); the others take palette colours in tree order. Clusters are the tree's
|
|
195
|
+
* groups holding a selected gene, then each ungrouped selected gene on its own. Every gene of a
|
|
196
|
+
* cluster gets the same colour — the tree's swatches and the markers use this one map.
|
|
197
|
+
*/
|
|
198
|
+
export function clusterColorMap(genes, groups, cellColors, palette) {
|
|
199
|
+
const chosen = new Set(genes);
|
|
200
|
+
const names = [];
|
|
201
|
+
const grouped = new Set();
|
|
202
|
+
for (const g of groups) {
|
|
203
|
+
const mine = g.genes.filter((x) => chosen.has(x) && !grouped.has(x));
|
|
204
|
+
if (!mine.length)
|
|
205
|
+
continue;
|
|
206
|
+
mine.forEach((x) => grouped.add(x));
|
|
207
|
+
names.push(g.name);
|
|
208
|
+
}
|
|
209
|
+
for (const gene of genes)
|
|
210
|
+
if (!grouped.has(gene))
|
|
211
|
+
names.push(gene);
|
|
212
|
+
const out = new Map();
|
|
213
|
+
let k = 0;
|
|
214
|
+
for (const name of names) {
|
|
215
|
+
if (out.has(name))
|
|
216
|
+
continue;
|
|
217
|
+
out.set(name, cellColors.get(name) ?? palette[k++ % palette.length]);
|
|
218
|
+
}
|
|
219
|
+
return out;
|
|
220
|
+
}
|
|
221
|
+
/** The cluster a selected gene is in: its first gene-tree group holding it, else itself. */
|
|
222
|
+
export function clusterOfGene(gene, groups) {
|
|
223
|
+
return groups.find((g) => g.genes.includes(gene))?.name ?? gene;
|
|
224
|
+
}
|
|
225
|
+
// ── Marker sizing ─────────────────────────────────────────────────────────────────────
|
|
226
|
+
/** Smallest transcript marker, in canvas pixels. */
|
|
227
|
+
export const TRANSCRIPT_MIN_PX = 4;
|
|
228
|
+
/** Largest transcript marker, in canvas pixels. */
|
|
229
|
+
export const TRANSCRIPT_MAX_PX = 32;
|
|
230
|
+
/**
|
|
231
|
+
* Physical diameter a single transcript is drawn at, in µm — clearly larger than the
|
|
232
|
+
* imaged spot (~0.3 µm) so it stays legible, and small enough that neighbouring
|
|
233
|
+
* molecules inside one cell stay apart.
|
|
234
|
+
*/
|
|
235
|
+
export const TRANSCRIPT_PHYSICAL_UM = 1.2;
|
|
236
|
+
/**
|
|
237
|
+
* Marker diameter in canvas pixels for an entry standing for `weight` transcripts.
|
|
238
|
+
*
|
|
239
|
+
* The convention spatial viewers share (deck.gl's `radiusMinPixels`/`radiusMaxPixels`,
|
|
240
|
+
* Xenium Explorer's transcript size): a PHYSICAL size, clamped to a screen-pixel range.
|
|
241
|
+
* Zoomed out, markers sit at the minimum and never vanish; zoomed in, they grow with the
|
|
242
|
+
* tissue instead of shrinking to specks next to cells hundreds of pixels wide. A fixed
|
|
243
|
+
* screen size does the opposite at high zoom, which is what made transcripts disappear
|
|
244
|
+
* at pixel-level zoom.
|
|
245
|
+
*
|
|
246
|
+
* Aggregates grow with the cube root of their count: area ∝ count would let one dense
|
|
247
|
+
* aggregate swallow its neighbours, the cube root keeps a 1000-transcript cluster clearly
|
|
248
|
+
* larger than a 10-transcript one without covering the tile.
|
|
249
|
+
*
|
|
250
|
+
* `pxPerMicron` is omitted for data with no known physical unit; the marker is then
|
|
251
|
+
* screen-sized only.
|
|
252
|
+
*/
|
|
253
|
+
export function transcriptMarkerPx(weight, scale = 1, pxPerMicron) {
|
|
254
|
+
const counted = TRANSCRIPT_MIN_PX * Math.cbrt(Math.max(1, weight));
|
|
255
|
+
const physical = pxPerMicron ? TRANSCRIPT_PHYSICAL_UM * pxPerMicron : 0;
|
|
256
|
+
const px = Math.max(counted, physical) * scale;
|
|
257
|
+
return Math.min(TRANSCRIPT_MAX_PX * Math.max(scale, 1), Math.max(TRANSCRIPT_MIN_PX * scale, px));
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* How to draw every transcript in view without exceeding `budget` markers.
|
|
261
|
+
*
|
|
262
|
+
* - The transcripts themselves, once the estimated count in view fits the budget.
|
|
263
|
+
* - Otherwise the finest pyramid level whose bins are at least `minSpacingPx` apart on
|
|
264
|
+
* screen and number no more than the budget — groups big enough to read, few enough
|
|
265
|
+
* to draw.
|
|
266
|
+
*
|
|
267
|
+
* The count in view is estimated from the average density, which over- or under-shoots
|
|
268
|
+
* locally; the renderer still caps what it draws, so an estimate is enough to choose.
|
|
269
|
+
*/
|
|
270
|
+
export function allGenesPlan(o) {
|
|
271
|
+
const area = visibleArea(o.rect, o.bounds);
|
|
272
|
+
if (!(area > 0))
|
|
273
|
+
return { kind: 'none' };
|
|
274
|
+
const b = o.bounds;
|
|
275
|
+
const density = o.total / Math.max(1, (b[2] - b[0]) * (b[3] - b[1]));
|
|
276
|
+
if (o.canIndividual && density * area <= o.budget)
|
|
277
|
+
return { kind: 'individual' };
|
|
278
|
+
if (!o.levels.length)
|
|
279
|
+
return { kind: 'none' };
|
|
280
|
+
const spacing = o.minSpacingPx ?? GROUP_MIN_SPACING_PX;
|
|
281
|
+
for (let l = 0; l < o.levels.length; l++) {
|
|
282
|
+
const bin = o.levels[l].binSize;
|
|
283
|
+
// Tissue rarely fills the view; 0.7 of the bins occupied is a fair guess.
|
|
284
|
+
if (bin * o.pxPerUnit >= spacing && (area / (bin * bin)) * 0.7 <= o.budget) {
|
|
285
|
+
return { kind: 'bins', level: l };
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return { kind: 'bins', level: o.levels.length - 1 };
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Diameter in px of a group of `count` transcripts in a bin `binPx` wide, where
|
|
292
|
+
* `refCount` is a typical busy bin in view (its 95th percentile).
|
|
293
|
+
*
|
|
294
|
+
* Area grows with the count — a bin with a quarter of the transcripts gets half the
|
|
295
|
+
* diameter — between a third of the bin (so a sparse bin is still visible) and a little
|
|
296
|
+
* over the full bin (so dense neighbours just touch rather than pile up).
|
|
297
|
+
*/
|
|
298
|
+
export function groupedMarkerPx(count, refCount, binPx, scale = 1) {
|
|
299
|
+
const f = Math.sqrt(Math.min(1, count / Math.max(1, refCount)));
|
|
300
|
+
const d = binPx * (0.35 + 0.75 * f) * scale;
|
|
301
|
+
return Math.max(TRANSCRIPT_MIN_PX * scale, Math.min(d, binPx * 1.2 * Math.max(scale, 1)));
|
|
302
|
+
}
|
|
303
|
+
/** The `p` quantile (0..1) of a count vector — a sample of it for large vectors. */
|
|
304
|
+
export function quantileOf(values, p) {
|
|
305
|
+
return quantile(values, p, { sampleSize: 4096 }) ?? 0;
|
|
306
|
+
}
|
|
307
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNjcmlwdC1ncm91cGluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvc3BhdGlhbC90cmFuc2NyaXB0LWdyb3VwaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7O0dBSUc7QUFHSCxPQUFPLEVBQVksV0FBVyxFQUFFLE1BQU0sT0FBTyxDQUFDO0FBQzlDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFbkMsd0ZBQXdGO0FBQ3hGLE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHLEVBQUUsQ0FBQztBQUV2Qzs7Ozs7O0dBTUc7QUFDSCxNQUFNLFVBQVUsV0FBVyxDQUN6QixTQUFpQixFQUNqQixPQUFlLEVBQ2YsTUFBTSxHQUFHLENBQUMsRUFDVixTQUFTLEdBQUcsb0JBQW9CO0lBRWhDLElBQUksQ0FBQyxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQztRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQ3BELElBQUksT0FBTyxHQUFHLFNBQVMsSUFBSSxTQUFTO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDbEQsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ2hDLE1BQU0sR0FBRyxHQUFHLE9BQU8sR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzdCLElBQUksR0FBRyxHQUFHLFNBQVMsSUFBSSxTQUFTO1lBQUUsT0FBTyxHQUFHLENBQUM7SUFDL0MsQ0FBQztJQUNELE9BQU8sT0FBTyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNyQyxDQUFDO0FBRUQsNERBQTREO0FBQzVELE1BQU0sVUFBVSxlQUFlLENBQUMsQ0FBd0IsRUFBRSxJQUFjO0lBQ3RFLE1BQU0sSUFBSSxHQUFhLEVBQUUsQ0FB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LElBQUksRUFBRSxHQUFHLEtBQUs7WUFBRSxLQUFLLEdBQUcsRUFBRSxDQUFDO1FBQzNCLElBQUksRUFBRSxHQUFHLEtBQUs7WUFBRSxLQUFLLEdBQUcsRUFBRSxDQUFDO1FBQzNCLElBQUksRUFBRSxHQUFHLEtBQUs7WUFBRSxLQUFLLEdBQUcsRUFBRSxDQUFDO1FBQzNCLElBQUksRUFBRSxHQUFHLEtBQUs7WUFBRSxLQUFLLEdBQUcsRUFBRSxDQUFDO0lBQzdCLENBQUM7SUFDRCx1RkFBdUY7SUFDdkYsNkVBQTZFO0lBQzdFLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3BFLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3BFLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBUyxFQUFVLEVBQUU7UUFDaEMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFDOUIsT0FBTyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDO0lBQ25ELENBQUMsQ0FBQztJQUNGLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBUyxFQUFVLEVBQUU7UUFDaEMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFDOUIsT0FBTyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENB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SSxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUM7SUFDNUMsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLGlCQUFpQixHQUFHLEtBQUssRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxLQUFLLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM1RixDQUFDO0FBRUQsb0ZBQW9GO0FBQ3BGLE1BQU0sVUFBVSxVQUFVLENBQUMsTUFBeUIsRUFBRSxDQUFTO0lBQzdELE9BQU8sUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDeEQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVHJhbnNjcmlwdCBncm91cGluZyBhbmQgbWFya2VyIHNpemluZzogaG93IG1hbnkgdHJhbnNjcmlwdHMgb25lIG1hcmtlciBzdGFuZHMgZm9yIGF0IHRoZVxuICogY3VycmVudCB6b29tLCBob3cgYmlnIGl0IGlzIGRyYXduLCBhbmQgd2hpY2ggY29sb3VyIGVhY2ggZ2VuZS10cmVlIGNsdXN0ZXIgdGFrZXMuIFB1cmUsIHNvXG4gKiB0aGUgYnVkZ2V0IHBvbGljeSBpcyB0ZXN0YWJsZSB3aXRob3V0IGEgdmlld2VyLlxuICovXG5cbmltcG9ydCB0eXBlIHsgU3BhdGlhbEJvdW5kcywgU3BhdGlhbFRyYW5zY3JpcHRUaWxlIH0gZnJvbSAnLi4vY29udHJhY3RzL3NwYXRpYWwtZGF0YXNldC5jb250cmFjdCc7XG5pbXBvcnQgeyBEYXRhUmVjdCwgdmlzaWJsZUFyZWEgfSBmcm9tICcuL2xvZCc7XG5pbXBvcnQgeyBxdWFudGlsZSB9IGZyb20gJy4vc3RhdHMnO1xuXG4vKiogU21hbGxlc3Qgb24tc2NyZWVuIHNwYWNpbmcgYmV0d2VlbiBncm91cHMsIGluIHB4IOKAlCBiZWxvdyBpdCBncm91cHMgcmVhZCBhcyBub2lzZS4gKi9cbmV4cG9ydCBjb25zdCBHUk9VUF9NSU5fU1BBQ0lOR19QWCA9IDE0O1xuXG4vKipcbiAqIFRoZSBiaW4gYSBzZWxlY3Rpb24gb2YgZ2VuZXMgaXMgZ3JvdXBlZCBpbnRvIGF0IHRoaXMgem9vbSwgaW4gb2JzZXJ2YXRpb24gdW5pdHMsIG9yIG51bGxcbiAqIHRvIGRyYXcgZXZlcnkgdHJhbnNjcmlwdC4gQmlucyBmb2xsb3cgdGhlIGFsbC1nZW5lIHB5cmFtaWQncyBsYWRkZXIgKGBiYXNlQmluYCDDlyAyXm0pIHNvIGFcbiAqIGdlbmUgc2VsZWN0aW9uIGFuZCBcImFsbCBnZW5lc1wiIGdyb3VwIGFsaWtlOiB0aGUgZmluZXN0IGJpbiB3aG9zZSBtYXJrZXJzIGxhbmQgYXQgbGVhc3RcbiAqIGBzcGFjaW5nUHhgIGFwYXJ0IG9uIHNjcmVlbi4gT25jZSB0aGUgZmluZXN0IGJpbiBpcyB0aGF0IHdpZGUsIHRyYW5zY3JpcHRzIGFyZSBkcmF3biBhc1xuICogdGhlbXNlbHZlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVCaW5TaXplKFxuICBweFBlclVuaXQ6IG51bWJlcixcbiAgYmFzZUJpbjogbnVtYmVyLFxuICBsZXZlbHMgPSA3LFxuICBzcGFjaW5nUHggPSBHUk9VUF9NSU5fU1BBQ0lOR19QWCxcbik6IG51bWJlciB8IG51bGwge1xuICBpZiAoIShweFBlclVuaXQgPiAwKSB8fCAhKGJhc2VCaW4gPiAwKSkgcmV0dXJuIG51bGw7XG4gIGlmIChiYXNlQmluICogcHhQZXJVbml0ID49IHNwYWNpbmdQeCkgcmV0dXJuIG51bGw7XG4gIGZvciAobGV0IG0gPSAxOyBtIDwgbGV2ZWxzOyBtKyspIHtcbiAgICBjb25zdCBiaW4gPSBiYXNlQmluICogMiAqKiBtO1xuICAgIGlmIChiaW4gKiBweFBlclVuaXQgPj0gc3BhY2luZ1B4KSByZXR1cm4gYmluO1xuICB9XG4gIHJldHVybiBiYXNlQmluICogMiAqKiAobGV2ZWxzIC0gMSk7XG59XG5cbi8qKiBUaGUgZW50cmllcyBvZiBgdGAgaW5zaWRlIGByZWN0YCAob2JzZXJ2YXRpb24gdW5pdHMpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsaXBUcmFuc2NyaXB0cyh0OiBTcGF0aWFsVHJhbnNjcmlwdFRpbGUsIHJlY3Q6IERhdGFSZWN0KTogU3BhdGlhbFRyYW5zY3JpcHRUaWxlIHtcbiAgY29uc3Qga2VlcDogbnVtYmVyW10gPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB0LmNvdW50OyBpKyspIHtcbiAgICBpZiAodC54W2ldID49IHJlY3QueDAgJiYgdC54W2ldIDw9IHJlY3QueDEgJiYgdC55W2ldID49IHJlY3QueTAgJiYgdC55W2ldIDw9IHJlY3QueTEpIGtlZXAucHVzaChpKTtcbiAgfVxuICBpZiAoa2VlcC5sZW5ndGggPT09IHQuY291bnQpIHJldHVybiB0O1xuICBjb25zdCBwaWNrID0gPEEgZXh0ZW5kcyBGbG9hdDMyQXJyYXkgfCBVaW50MzJBcnJheSB8IFVpbnQxNkFycmF5PihhOiBBKTogQSA9PiB7XG4gICAgY29uc3Qgb3V0ID0gbmV3IChhLmNvbnN0cnVjdG9yIGFzIG5ldyAobjogbnVtYmVyKSA9PiBBKShrZWVwLmxlbmd0aCk7XG4gICAga2VlcC5mb3JFYWNoKChzcmMsIGkpID0+IHtcbiAgICAgIG91dFtpXSA9IGFbc3JjXTtcbiAgICB9KTtcbiAgICByZXR1cm4gb3V0O1xuICB9O1xuICByZXR1cm4ge1xuICAgIGNvdW50OiBrZWVwLmxlbmd0aCxcbiAgICBhZ2dyZWdhdGVkOiB0LmFnZ3JlZ2F0ZWQsXG4gICAgeDogcGljayh0LngpLFxuICAgIHk6IHBpY2sodC55KSxcbiAgICB6OiBwaWNrKHQueiksXG4gICAgd2VpZ2h0OiBwaWNrKHQud2VpZ2h0KSxcbiAgICBvYnNlcnZhdGlvbjogcGljayh0Lm9ic2VydmF0aW9uKSxcbiAgICBnZW5lOiBwaWNrKHQuZ2VuZSksXG4gIH07XG59XG5cbi8vIOKUgOKUgCBHcm91cGluZyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuLyoqXG4gKiBHcm91cCB0cmFuc2NyaXB0cyBpbnRvIGBiaW5gLXdpZGUgc3F1YXJlcyBvZiBhIGdyaWQgYW5jaG9yZWQgYXQgdGhlIG9yaWdpbiAoc28gYSBwYW4gZG9lc1xuICogbm90IG1vdmUgdGhlbSksIG9uZSBlbnRyeSBwZXIgKGdyb3VwLCBzcXVhcmUpOiBgZ3JvdXBPZihnZW5lIHNsb3QpYCBzYXlzIHdoaWNoIGdyb3VwIGEgZ2VuZVxuICogaXMgaW4g4oCUIGl0cyBjbHVzdGVyIGluIHRoZSBnZW5lIHRyZWUsIG9yIGl0c2VsZi4gRWFjaCBlbnRyeSBzaXRzIGF0IGl0cyB0cmFuc2NyaXB0cydcbiAqIGNlbnRyb2lkLCB3ZWlnaHRlZCBieSBob3cgbWFueSBlYWNoIHN0YW5kcyBmb3I7IGl0IHRha2VzIHRoZSBnZW5lIGFuZCB0aGUgY2VsbCBob2xkaW5nIG1vc3RcbiAqIG9mIHRoZW0sIGVhY2ggc3VtbWVkIG92ZXIgYWxsIGl0cyB0cmFuc2NyaXB0cyBpbiB0aGUgZW50cnkuIGBncm91cFtpXWAgaXMgZW50cnkgaSdzIGdyb3VwLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ3JvdXBUcmFuc2NyaXB0cyhcbiAgdDogU3BhdGlhbFRyYW5zY3JpcHRUaWxlLFxuICBiaW46IG51bWJlcixcbiAgZ3JvdXBPZjogKGdlbmVTbG90OiBudW1iZXIpID0+IG51bWJlciA9IChnKSA9PiBnLFxuKTogeyB0aWxlOiBTcGF0aWFsVHJhbnNjcmlwdFRpbGU7IGdyb3VwOiBJbnQzMkFycmF5IH0ge1xuICAvLyBIb3Qgb24gZXZlcnkgcGFuIGFuZCB6b29tLCBzbyBub3RoaW5nIGlzIGFsbG9jYXRlZCBwZXIgdHJhbnNjcmlwdDogdGhlIChncm91cCwgc3F1YXJlKVxuICAvLyBrZXkgaXMgYSBudW1iZXIgb3ZlciB0aGUgdGlsZSdzIG93biBib3VuZGVkIGV4dGVudCByYXRoZXIgdGhhbiBhIHRlbXBsYXRlIHN0cmluZywgYW5kXG4gIC8vIHRoZSBwZXItZW50cnkgZ2VuZSBhbmQgY2VsbCB0YWxsaWVzIHNoYXJlIHR3byBmbGF0IG1hcHMgaW5zdGVhZCBvZiB0d28gTWFwcyBwZXIgZW50cnkuXG4gIGNvbnN0IGNvdW50ID0gdC5jb3VudDtcbiAgY29uc3QgZ2tzID0gbmV3IEludDMyQXJyYXkoY291bnQpO1xuICBsZXQgbWluQnggPSBJbmZpbml0eTtcbiAgbGV0IG1heEJ4ID0gLUluZmluaXR5O1xuICBsZXQgbWluQnkgPSBJbmZpbml0eTtcbiAgbGV0IG1heEJ5ID0gLUluZmluaXR5O1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcbiAgICBna3NbaV0gPSBncm91cE9mKHQuZ2VuZVtpXSk7XG4gICAgY29uc3QgYnggPSBNYXRoLmZsb29yKHQueFtpXSAvIGJpbik7XG4gICAgY29uc3QgYnkgPSBNYXRoLmZsb29yKHQueVtpXSAvIGJpbik7XG4gICAgaWYgKGJ4IDwgbWluQngpIG1pbkJ4ID0gYng7XG4gICAgaWYgKGJ4ID4gbWF4QngpIG1heEJ4ID0gYng7XG4gICAgaWYgKGJ5IDwgbWluQnkpIG1pbkJ5ID0gYnk7XG4gICAgaWYgKGJ5ID4gbWF4QnkpIG1heEJ5ID0gYnk7XG4gIH1cbiAgLy8gT25lIHNwYXJlIGNvbHVtbiBhbmQgcm93IGZvciBhIHNxdWFyZSB0aGF0IGlzIG5vdCBmaW5pdGUgKGEgTmFOIGNvb3JkaW5hdGUpLCBzbyBzdWNoXG4gIC8vIHRyYW5zY3JpcHRzIHN0aWxsIGdyb3VwIHRvZ2V0aGVyIHJhdGhlciB0aGFuIGNvbGxpZGluZyB3aXRoIGEgcmVhbCBzcXVhcmUuXG4gIGNvbnN0IGNvbHMgPSBOdW1iZXIuaXNGaW5pdGUobWF4QnggLSBtaW5CeCkgPyBtYXhCeCAtIG1pbkJ4ICsgMiA6IDE7XG4gIGNvbnN0IHJvd3MgPSBOdW1iZXIuaXNGaW5pdGUobWF4QnkgLSBtaW5CeSkgPyBtYXhCeSAtIG1pbkJ5ICsgMiA6IDE7XG4gIGNvbnN0IGNvbCA9ICh2OiBudW1iZXIpOiBudW1iZXIgPT4ge1xuICAgIGNvbnN0IGIgPSBNYXRoLmZsb29yKHYgLyBiaW4pO1xuICAgIHJldHVybiBOdW1iZXIuaXNGaW5pdGUoYikgPyBiIC0gbWluQnggOiBjb2xzIC0gMTtcbiAgfTtcbiAgY29uc3Qgcm93ID0gKHY6IG51bWJlcik6IG51bWJlciA9PiB7XG4gICAgY29uc3QgYiA9IE1hdGguZmxvb3IodiAvIGJpbik7XG4gICAgcmV0dXJuIE51bWJlci5pc0Zpbml0ZShiKSA/IGIgLSBtaW5CeSA6IHJvd3MgLSAxO1xuICB9O1xuXG4gIGNvbnN0IGluZGV4ID0gbmV3IE1hcDxudW1iZXIsIG51bWJlcj4oKTtcbiAgY29uc3Qgc3g6IG51bWJlcltdID0gW107XG4gIGNvbnN0IHN5OiBudW1iZXJbXSA9IFtdO1xuICBjb25zdCBzejogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgdzogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgZ3JwOiBudW1iZXJbXSA9IFtdO1xuICAvLyBQZXIgZW50cnksIGhvdyBtYW55IHRyYW5zY3JpcHRzIG9mIGVhY2ggZ2VuZSAodGhlIGRvbWluYW50IG9uZSBnaXZlcyB0aGUgaWNvbiBhbmQgY29sb3VyKVxuICAvLyBhbmQgaW4gZWFjaCBjZWxsICh0aGUgZG9taW5hbnQgb25lIGlzIHRoZSBlbnRyeSdzIGNlbGwpLlxuICBjb25zdCBnZW5lcyA9IG5ldyBEb21pbmFudFRhbGx5KCk7XG4gIGNvbnN0IGNlbGxzID0gbmV3IERvbWluYW50VGFsbHkoKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgY29uc3QgZ2sgPSBna3NbaV07XG4gICAgY29uc3Qga2V5ID0gKGdrICogcm93cyArIHJvdyh0LnlbaV0pKSAqIGNvbHMgKyBjb2wodC54W2ldKTtcbiAgICBsZXQgayA9IGluZGV4LmdldChrZXkpO1xuICAgIGNvbnN0IHdpID0gdC53ZWlnaHRbaV0gfHwgMTtcbiAgICBpZiAoayA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBrID0gdy5sZW5ndGg7XG4gICAgICBpbmRleC5zZXQoa2V5LCBrKTtcbiAgICAgIHN4LnB1c2goMCk7XG4gICAgICBzeS5wdXNoKDApO1xuICAgICAgc3oucHVzaCgwKTtcbiAgICAgIHcucHVzaCgwKTtcbiAgICAgIGdycC5wdXNoKGdrKTtcbiAgICB9XG4gICAgc3hba10gKz0gdC54W2ldICogd2k7XG4gICAgc3lba10gKz0gdC55W2ldICogd2k7XG4gICAgc3pba10gKz0gdC56W2ldICogd2k7XG4gICAgd1trXSArPSB3aTtcbiAgICBnZW5lcy5hZGQoaywgdC5nZW5lW2ldLCB3aSk7XG4gICAgY2VsbHMuYWRkKGssIHQub2JzZXJ2YXRpb25baV0sIHdpKTtcbiAgfVxuICBjb25zdCBuID0gdy5sZW5ndGg7XG4gIGNvbnN0IHRpbGU6IFNwYXRpYWxUcmFuc2NyaXB0VGlsZSA9IHtcbiAgICBjb3VudDogbixcbiAgICBhZ2dyZWdhdGVkOiB0cnVlLFxuICAgIHg6IG5ldyBGbG9hdDMyQXJyYXkobiksXG4gICAgeTogbmV3IEZsb2F0MzJBcnJheShuKSxcbiAgICB6OiBuZXcgRmxvYXQzMkFycmF5KG4pLFxuICAgIHdlaWdodDogbmV3IFVpbnQzMkFycmF5KG4pLFxuICAgIG9ic2VydmF0aW9uOiBuZXcgVWludDMyQXJyYXkobiksXG4gICAgZ2VuZTogbmV3IFVpbnQxNkFycmF5KG4pLFxuICB9O1xuICBjb25zdCBncm91cCA9IG5ldyBJbnQzMkFycmF5KG4pO1xuICBmb3IgKGxldCBrID0gMDsgayA8IG47IGsrKykge1xuICAgIHRpbGUueFtrXSA9IHN4W2tdIC8gd1trXTtcbiAgICB0aWxlLnlba10gPSBzeVtrXSAvIHdba107XG4gICAgdGlsZS56W2tdID0gc3pba10gLyB3W2tdO1xuICAgIHRpbGUud2VpZ2h0W2tdID0gd1trXTtcbiAgICB0aWxlLm9ic2VydmF0aW9uW2tdID0gY2VsbHMuZG9taW5hbnQoayk7XG4gICAgdGlsZS5nZW5lW2tdID0gZ2VuZXMuZG9taW5hbnQoayk7XG4gICAgZ3JvdXBba10gPSBncnBba107XG4gIH1cbiAgcmV0dXJuIHsgdGlsZSwgZ3JvdXAgfTtcbn1cblxuLyoqXG4gKiBXZWlnaHRlZCB0YWxsaWVzIG9mIHUzMiBrZXlzIHBlciBlbnRyeSwgdHJhY2tpbmcgZWFjaCBlbnRyeSdzIGRvbWluYW50IGtleSBhcyBpdCBnb2VzOlxuICogdGhlIGtleSB3aXRoIHRoZSBsYXJnZXN0IHRvdGFsLCB0aGUgZmlyc3Qgc2VlbiBvbiBhIHRpZS5cbiAqXG4gKiBPbmUgbWFwIGZvciBldmVyeSBlbnRyeSwga2V5ZWQgYGVudHJ5IMK3IDJeMzIgKyBrZXlgIOKAlCBleGFjdCB3aGlsZSBlbnRyaWVzIHN0YXkgYmVsb3dcbiAqIDJeMjEsIGZhciBhYm92ZSBhbnkgbWFya2VyIGJ1ZGdldC5cbiAqL1xuY2xhc3MgRG9taW5hbnRUYWxseSB7XG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IEtFWV9TUEFOID0gMiAqKiAzMjtcbiAgcHJpdmF0ZSByZWFkb25seSB0b3RhbCA9IG5ldyBNYXA8bnVtYmVyLCBudW1iZXI+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgZmlyc3RTZWVuID0gbmV3IE1hcDxudW1iZXIsIG51bWJlcj4oKTtcbiAgcHJpdmF0ZSBzZXEgPSAwO1xuICBwcml2YXRlIHJlYWRvbmx5IGJlc3RLZXk6IG51bWJlcltdID0gW107XG4gIHByaXZhdGUgcmVhZG9ubHkgYmVzdFRvdGFsOiBudW1iZXJbXSA9IFtdO1xuICBwcml2YXRlIHJlYWRvbmx5IGJlc3RTZWVuOiBudW1iZXJbXSA9IFtdO1xuXG4gIGFkZChlbnRyeTogbnVtYmVyLCBrZXk6IG51bWJlciwgd2VpZ2h0OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBpZCA9IGVudHJ5ICogRG9taW5hbnRUYWxseS5LRVlfU1BBTiArIGtleTtcbiAgICBjb25zdCB2ID0gKHRoaXMudG90YWwuZ2V0KGlkKSA/PyAwKSArIHdlaWdodDtcbiAgICB0aGlzLnRvdGFsLnNldChpZCwgdik7XG4gICAgbGV0IGZpcnN0ID0gdGhpcy5maXJzdFNlZW4uZ2V0KGlkKTtcbiAgICBpZiAoZmlyc3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgZmlyc3QgPSB0aGlzLnNlcSsrO1xuICAgICAgdGhpcy5maXJzdFNlZW4uc2V0KGlkLCBmaXJzdCk7XG4gICAgfVxuICAgIGNvbnN0IHRvcCA9IHRoaXMuYmVzdFRvdGFsW2VudHJ5XTtcbiAgICBpZiAodG9wID09PSB1bmRlZmluZWQgfHwgdiA+IHRvcCB8fCAodiA9PT0gdG9wICYmIGZpcnN0IDwgdGhpcy5iZXN0U2VlbltlbnRyeV0pKSB7XG4gICAgICB0aGlzLmJlc3RLZXlbZW50cnldID0ga2V5O1xuICAgICAgdGhpcy5iZXN0VG90YWxbZW50cnldID0gdjtcbiAgICAgIHRoaXMuYmVzdFNlZW5bZW50cnldID0gZmlyc3Q7XG4gICAgfVxuICB9XG5cbiAgZG9taW5hbnQoZW50cnk6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuYmVzdEtleVtlbnRyeV0gPz8gMDtcbiAgfVxufVxuXG4vLyDilIDilIAgQ2x1c3RlciBjb2xvdXJzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4vKipcbiAqIFRoZSBjb2xvdXIgb2YgZWFjaCBnZW5lLXRyZWUgY2x1c3RlciBvZiBhIHNlbGVjdGlvbiwgZm9yIGNvbG91cmluZyB0cmFuc2NyaXB0cyBieSBjbHVzdGVyOiBhXG4gKiBjbHVzdGVyIG5hbWVkIGxpa2UgYSBncm91cCBvZiB0aGUgY2VsbHMnIGdyb3VwaW5nIHRha2VzIHRoYXQgZ3JvdXAncyBjb2xvdXIgKGl0cyBjZWxscyBhbmQgaXRzXG4gKiB0cmFuc2NyaXB0cyBhZ3JlZSk7IHRoZSBvdGhlcnMgdGFrZSBwYWxldHRlIGNvbG91cnMgaW4gdHJlZSBvcmRlci4gQ2x1c3RlcnMgYXJlIHRoZSB0cmVlJ3NcbiAqIGdyb3VwcyBob2xkaW5nIGEgc2VsZWN0ZWQgZ2VuZSwgdGhlbiBlYWNoIHVuZ3JvdXBlZCBzZWxlY3RlZCBnZW5lIG9uIGl0cyBvd24uIEV2ZXJ5IGdlbmUgb2YgYVxuICogY2x1c3RlciBnZXRzIHRoZSBzYW1lIGNvbG91ciDigJQgdGhlIHRyZWUncyBzd2F0Y2hlcyBhbmQgdGhlIG1hcmtlcnMgdXNlIHRoaXMgb25lIG1hcC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsdXN0ZXJDb2xvck1hcChcbiAgZ2VuZXM6IHJlYWRvbmx5IHN0cmluZ1tdLFxuICBncm91cHM6IHJlYWRvbmx5IHsgbmFtZTogc3RyaW5nOyBnZW5lczogcmVhZG9ubHkgc3RyaW5nW10gfVtdLFxuICBjZWxsQ29sb3JzOiBSZWFkb25seU1hcDxzdHJpbmcsIHN0cmluZz4sXG4gIHBhbGV0dGU6IHJlYWRvbmx5IHN0cmluZ1tdLFxuKTogTWFwPHN0cmluZywgc3RyaW5nPiB7XG4gIGNvbnN0IGNob3NlbiA9IG5ldyBTZXQoZ2VuZXMpO1xuICBjb25zdCBuYW1lczogc3RyaW5nW10gPSBbXTtcbiAgY29uc3QgZ3JvdXBlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBmb3IgKGNvbnN0IGcgb2YgZ3JvdXBzKSB7XG4gICAgY29uc3QgbWluZSA9IGcuZ2VuZXMuZmlsdGVyKCh4KSA9PiBjaG9zZW4uaGFzKHgpICYmICFncm91cGVkLmhhcyh4KSk7XG4gICAgaWYgKCFtaW5lLmxlbmd0aCkgY29udGludWU7XG4gICAgbWluZS5mb3JFYWNoKCh4KSA9PiBncm91cGVkLmFkZCh4KSk7XG4gICAgbmFtZXMucHVzaChnLm5hbWUpO1xuICB9XG4gIGZvciAoY29uc3QgZ2VuZSBvZiBnZW5lcykgaWYgKCFncm91cGVkLmhhcyhnZW5lKSkgbmFtZXMucHVzaChnZW5lKTtcbiAgY29uc3Qgb3V0ID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcbiAgbGV0IGsgPSAwO1xuICBmb3IgKGNvbnN0IG5hbWUgb2YgbmFtZXMpIHtcbiAgICBpZiAob3V0LmhhcyhuYW1lKSkgY29udGludWU7XG4gICAgb3V0LnNldChuYW1lLCBjZWxsQ29sb3JzLmdldChuYW1lKSA/PyBwYWxldHRlW2srKyAlIHBhbGV0dGUubGVuZ3RoXSk7XG4gIH1cbiAgcmV0dXJuIG91dDtcbn1cblxuLyoqIFRoZSBjbHVzdGVyIGEgc2VsZWN0ZWQgZ2VuZSBpcyBpbjogaXRzIGZpcnN0IGdlbmUtdHJlZSBncm91cCBob2xkaW5nIGl0LCBlbHNlIGl0c2VsZi4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjbHVzdGVyT2ZHZW5lKFxuICBnZW5lOiBzdHJpbmcsXG4gIGdyb3VwczogcmVhZG9ubHkgeyBuYW1lOiBzdHJpbmc7IGdlbmVzOiByZWFkb25seSBzdHJpbmdbXSB9W10sXG4pOiBzdHJpbmcge1xuICByZXR1cm4gZ3JvdXBzLmZpbmQoKGcpID0+IGcuZ2VuZXMuaW5jbHVkZXMoZ2VuZSkpPy5uYW1lID8/IGdlbmU7XG59XG5cbi8vIOKUgOKUgCBNYXJrZXIgc2l6aW5nIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4vKiogU21hbGxlc3QgdHJhbnNjcmlwdCBtYXJrZXIsIGluIGNhbnZhcyBwaXhlbHMuICovXG5leHBvcnQgY29uc3QgVFJBTlNDUklQVF9NSU5fUFggPSA0O1xuLyoqIExhcmdlc3QgdHJhbnNjcmlwdCBtYXJrZXIsIGluIGNhbnZhcyBwaXhlbHMuICovXG5leHBvcnQgY29uc3QgVFJBTlNDUklQVF9NQVhfUFggPSAzMjtcbi8qKlxuICogUGh5c2ljYWwgZGlhbWV0ZXIgYSBzaW5nbGUgdHJhbnNjcmlwdCBpcyBkcmF3biBhdCwgaW4gwrVtIOKAlCBjbGVhcmx5IGxhcmdlciB0aGFuIHRoZVxuICogaW1hZ2VkIHNwb3QgKH4wLjMgwrVtKSBzbyBpdCBzdGF5cyBsZWdpYmxlLCBhbmQgc21hbGwgZW5vdWdoIHRoYXQgbmVpZ2hib3VyaW5nXG4gKiBtb2xlY3VsZXMgaW5zaWRlIG9uZSBjZWxsIHN0YXkgYXBhcnQuXG4gKi9cbmV4cG9ydCBjb25zdCBUUkFOU0NSSVBUX1BIWVNJQ0FMX1VNID0gMS4yO1xuXG4vKipcbiAqIE1hcmtlciBkaWFtZXRlciBpbiBjYW52YXMgcGl4ZWxzIGZvciBhbiBlbnRyeSBzdGFuZGluZyBmb3IgYHdlaWdodGAgdHJhbnNjcmlwdHMuXG4gKlxuICogVGhlIGNvbnZlbnRpb24gc3BhdGlhbCB2aWV3ZXJzIHNoYXJlIChkZWNrLmdsJ3MgYHJhZGl1c01pblBpeGVsc2AvYHJhZGl1c01heFBpeGVsc2AsXG4gKiBYZW5pdW0gRXhwbG9yZXIncyB0cmFuc2NyaXB0IHNpemUpOiBhIFBIWVNJQ0FMIHNpemUsIGNsYW1wZWQgdG8gYSBzY3JlZW4tcGl4ZWwgcmFuZ2UuXG4gKiBab29tZWQgb3V0LCBtYXJrZXJzIHNpdCBhdCB0aGUgbWluaW11bSBhbmQgbmV2ZXIgdmFuaXNoOyB6b29tZWQgaW4sIHRoZXkgZ3JvdyB3aXRoIHRoZVxuICogdGlzc3VlIGluc3RlYWQgb2Ygc2hyaW5raW5nIHRvIHNwZWNrcyBuZXh0IHRvIGNlbGxzIGh1bmRyZWRzIG9mIHBpeGVscyB3aWRlLiBBIGZpeGVkXG4gKiBzY3JlZW4gc2l6ZSBkb2VzIHRoZSBvcHBvc2l0ZSBhdCBoaWdoIHpvb20sIHdoaWNoIGlzIHdoYXQgbWFkZSB0cmFuc2NyaXB0cyBkaXNhcHBlYXJcbiAqIGF0IHBpeGVsLWxldmVsIHpvb20uXG4gKlxuICogQWdncmVnYXRlcyBncm93IHdpdGggdGhlIGN1YmUgcm9vdCBvZiB0aGVpciBjb3VudDogYXJlYSDiiJ0gY291bnQgd291bGQgbGV0IG9uZSBkZW5zZVxuICogYWdncmVnYXRlIHN3YWxsb3cgaXRzIG5laWdoYm91cnMsIHRoZSBjdWJlIHJvb3Qga2VlcHMgYSAxMDAwLXRyYW5zY3JpcHQgY2x1c3RlciBjbGVhcmx5XG4gKiBsYXJnZXIgdGhhbiBhIDEwLXRyYW5zY3JpcHQgb25lIHdpdGhvdXQgY292ZXJpbmcgdGhlIHRpbGUuXG4gKlxuICogYHB4UGVyTWljcm9uYCBpcyBvbWl0dGVkIGZvciBkYXRhIHdpdGggbm8ga25vd24gcGh5c2ljYWwgdW5pdDsgdGhlIG1hcmtlciBpcyB0aGVuXG4gKiBzY3JlZW4tc2l6ZWQgb25seS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zY3JpcHRNYXJrZXJQeCh3ZWlnaHQ6IG51bWJlciwgc2NhbGUgPSAxLCBweFBlck1pY3Jvbj86IG51bWJlcik6IG51bWJlciB7XG4gIGNvbnN0IGNvdW50ZWQgPSBUUkFOU0NSSVBUX01JTl9QWCAqIE1hdGguY2JydChNYXRoLm1heCgxLCB3ZWlnaHQpKTtcbiAgY29uc3QgcGh5c2ljYWwgPSBweFBlck1pY3JvbiA/IFRSQU5TQ1JJUFRfUEhZU0lDQUxfVU0gKiBweFBlck1pY3JvbiA6IDA7XG4gIGNvbnN0IHB4ID0gTWF0aC5tYXgoY291bnRlZCwgcGh5c2ljYWwpICogc2NhbGU7XG4gIHJldHVybiBNYXRoLm1pbihUUkFOU0NSSVBUX01BWF9QWCAqIE1hdGgubWF4KHNjYWxlLCAxKSwgTWF0aC5tYXgoVFJBTlNDUklQVF9NSU5fUFggKiBzY2FsZSwgcHgpKTtcbn1cblxuLy8g4pSA4pSAIEFsbC1nZW5lIHRyYW5zY3JpcHRzOiBncm91cGluZyB1bmRlciBhIG1hcmtlciBidWRnZXQg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbi8qKlxuICogSG93IFwiYWxsIGdlbmVzXCIgaXMgZHJhd24gYXQgdGhlIGN1cnJlbnQgem9vbTogaW5kaXZpZHVhbCB0cmFuc2NyaXB0cywgYSBiaW4gbGV2ZWwsIG9yIG5vdGhpbmcuXG4gKi9cbmV4cG9ydCB0eXBlIEFsbEdlbmVzUGxhbiA9IHsga2luZDogJ2luZGl2aWR1YWwnIH0gfCB7IGtpbmQ6ICdiaW5zJzsgbGV2ZWw6IG51bWJlciB9IHwgeyBraW5kOiAnbm9uZScgfTtcblxuLyoqXG4gKiBIb3cgdG8gZHJhdyBldmVyeSB0cmFuc2NyaXB0IGluIHZpZXcgd2l0aG91dCBleGNlZWRpbmcgYGJ1ZGdldGAgbWFya2Vycy5cbiAqXG4gKiAtIFRoZSB0cmFuc2NyaXB0cyB0aGVtc2VsdmVzLCBvbmNlIHRoZSBlc3RpbWF0ZWQgY291bnQgaW4gdmlldyBmaXRzIHRoZSBidWRnZXQuXG4gKiAtIE90aGVyd2lzZSB0aGUgZmluZXN0IHB5cmFtaWQgbGV2ZWwgd2hvc2UgYmlucyBhcmUgYXQgbGVhc3QgYG1pblNwYWNpbmdQeGAgYXBhcnQgb25cbiAqICAgc2NyZWVuIGFuZCBudW1iZXIgbm8gbW9yZSB0aGFuIHRoZSBidWRnZXQg4oCUIGdyb3VwcyBiaWcgZW5vdWdoIHRvIHJlYWQsIGZldyBlbm91Z2hcbiAqICAgdG8gZHJhdy5cbiAqXG4gKiBUaGUgY291bnQgaW4gdmlldyBpcyBlc3RpbWF0ZWQgZnJvbSB0aGUgYXZlcmFnZSBkZW5zaXR5LCB3aGljaCBvdmVyLSBvciB1bmRlci1zaG9vdHNcbiAqIGxvY2FsbHk7IHRoZSByZW5kZXJlciBzdGlsbCBjYXBzIHdoYXQgaXQgZHJhd3MsIHNvIGFuIGVzdGltYXRlIGlzIGVub3VnaCB0byBjaG9vc2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhbGxHZW5lc1BsYW4obzoge1xuICByZWN0OiBEYXRhUmVjdDtcbiAgYm91bmRzOiBTcGF0aWFsQm91bmRzO1xuICB0b3RhbDogbnVtYmVyO1xuICBweFBlclVuaXQ6IG51bWJlcjtcbiAgbGV2ZWxzOiByZWFkb25seSB7IGJpblNpemU6IG51bWJlciB9W107XG4gIGJ1ZGdldDogbnVtYmVyO1xuICBjYW5JbmRpdmlkdWFsOiBib29sZWFuO1xuICBtaW5TcGFjaW5nUHg/OiBudW1iZXI7XG59KTogQWxsR2VuZXNQbGFuIHtcbiAgY29uc3QgYXJlYSA9IHZpc2libGVBcmVhKG8ucmVjdCwgby5ib3VuZHMpO1xuICBpZiAoIShhcmVhID4gMCkpIHJldHVybiB7IGtpbmQ6ICdub25lJyB9O1xuICBjb25zdCBiID0gby5ib3VuZHM7XG4gIGNvbnN0IGRlbnNpdHkgPSBvLnRvdGFsIC8gTWF0aC5tYXgoMSwgKGJbMl0gLSBiWzBdKSAqIChiWzNdIC0gYlsxXSkpO1xuICBpZiAoby5jYW5JbmRpdmlkdWFsICYmIGRlbnNpdHkgKiBhcmVhIDw9IG8uYnVkZ2V0KSByZXR1cm4geyBraW5kOiAnaW5kaXZpZHVhbCcgfTtcbiAgaWYgKCFvLmxldmVscy5sZW5ndGgpIHJldHVybiB7IGtpbmQ6ICdub25lJyB9O1xuICBjb25zdCBzcGFjaW5nID0gby5taW5TcGFjaW5nUHggPz8gR1JPVVBfTUlOX1NQQUNJTkdfUFg7XG4gIGZvciAobGV0IGwgPSAwOyBsIDwgby5sZXZlbHMubGVuZ3RoOyBsKyspIHtcbiAgICBjb25zdCBiaW4gPSBvLmxldmVsc1tsXS5iaW5TaXplO1xuICAgIC8vIFRpc3N1ZSByYXJlbHkgZmlsbHMgdGhlIHZpZXc7IDAuNyBvZiB0aGUgYmlucyBvY2N1cGllZCBpcyBhIGZhaXIgZ3Vlc3MuXG4gICAgaWYgKGJpbiAqIG8ucHhQZXJVbml0ID49IHNwYWNpbmcgJiYgKGFyZWEgLyAoYmluICogYmluKSkgKiAwLjcgPD0gby5idWRnZXQpIHtcbiAgICAgIHJldHVybiB7IGtpbmQ6ICdiaW5zJywgbGV2ZWw6IGwgfTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHsga2luZDogJ2JpbnMnLCBsZXZlbDogby5sZXZlbHMubGVuZ3RoIC0gMSB9O1xufVxuXG4vKipcbiAqIERpYW1ldGVyIGluIHB4IG9mIGEgZ3JvdXAgb2YgYGNvdW50YCB0cmFuc2NyaXB0cyBpbiBhIGJpbiBgYmluUHhgIHdpZGUsIHdoZXJlXG4gKiBgcmVmQ291bnRgIGlzIGEgdHlwaWNhbCBidXN5IGJpbiBpbiB2aWV3IChpdHMgOTV0aCBwZXJjZW50aWxlKS5cbiAqXG4gKiBBcmVhIGdyb3dzIHdpdGggdGhlIGNvdW50IOKAlCBhIGJpbiB3aXRoIGEgcXVhcnRlciBvZiB0aGUgdHJhbnNjcmlwdHMgZ2V0cyBoYWxmIHRoZVxuICogZGlhbWV0ZXIg4oCUIGJldHdlZW4gYSB0aGlyZCBvZiB0aGUgYmluIChzbyBhIHNwYXJzZSBiaW4gaXMgc3RpbGwgdmlzaWJsZSkgYW5kIGEgbGl0dGxlXG4gKiBvdmVyIHRoZSBmdWxsIGJpbiAoc28gZGVuc2UgbmVpZ2hib3VycyBqdXN0IHRvdWNoIHJhdGhlciB0aGFuIHBpbGUgdXApLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ3JvdXBlZE1hcmtlclB4KGNvdW50OiBudW1iZXIsIHJlZkNvdW50OiBudW1iZXIsIGJpblB4OiBudW1iZXIsIHNjYWxlID0gMSk6IG51bWJlciB7XG4gIGNvbnN0IGYgPSBNYXRoLnNxcnQoTWF0aC5taW4oMSwgY291bnQgLyBNYXRoLm1heCgxLCByZWZDb3VudCkpKTtcbiAgY29uc3QgZCA9IGJpblB4ICogKDAuMzUgKyAwLjc1ICogZikgKiBzY2FsZTtcbiAgcmV0dXJuIE1hdGgubWF4KFRSQU5TQ1JJUFRfTUlOX1BYICogc2NhbGUsIE1hdGgubWluKGQsIGJpblB4ICogMS4yICogTWF0aC5tYXgoc2NhbGUsIDEpKSk7XG59XG5cbi8qKiBUaGUgYHBgIHF1YW50aWxlICgwLi4xKSBvZiBhIGNvdW50IHZlY3RvciDigJQgYSBzYW1wbGUgb2YgaXQgZm9yIGxhcmdlIHZlY3RvcnMuICovXG5leHBvcnQgZnVuY3Rpb24gcXVhbnRpbGVPZih2YWx1ZXM6IEFycmF5TGlrZTxudW1iZXI+LCBwOiBudW1iZXIpOiBudW1iZXIge1xuICByZXR1cm4gcXVhbnRpbGUodmFsdWVzLCBwLCB7IHNhbXBsZVNpemU6IDQwOTYgfSkgPz8gMDtcbn1cbiJdfQ==
|