@jax-data-science/sci-image-visualizer 0.8.3 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +201 -460
- package/esm2022/index.mjs +34 -15
- package/esm2022/lib/channel-histogram/channel-histogram.component.mjs +163 -91
- package/esm2022/lib/contracts/capabilities.contract.mjs +4 -3
- package/esm2022/lib/contracts/cell-segmenter.contract.mjs +1 -1
- package/esm2022/lib/contracts/channel-histogram-api.contract.mjs +5 -1
- package/esm2022/lib/contracts/color.mjs +60 -0
- package/esm2022/lib/contracts/colormap-lut.mjs +213 -57
- package/esm2022/lib/contracts/coordinate-transform.contract.mjs +1 -1
- package/esm2022/lib/contracts/display-types.mjs +11 -1
- package/esm2022/lib/contracts/image.contract.mjs +1 -1
- package/esm2022/lib/contracts/instance-segmenter.contract.mjs +1 -1
- package/esm2022/lib/contracts/intensity.mjs +48 -5
- package/esm2022/lib/contracts/plot-type-contribution.contract.mjs +1 -1
- package/esm2022/lib/contracts/plot-type.mjs +134 -17
- package/esm2022/lib/contracts/ports/image-state.port.mjs +4 -1
- package/esm2022/lib/contracts/ports/preferences.port.mjs +5 -1
- package/esm2022/lib/contracts/ports/region-io.port.mjs +2 -1
- package/esm2022/lib/contracts/ports/spatial-data.port.mjs +5 -1
- package/esm2022/lib/contracts/ports/tile-access.port.mjs +2 -1
- package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
- package/esm2022/lib/contracts/region-overlay.contract.mjs +1 -1
- package/esm2022/lib/contracts/region-store.contract.mjs +1 -1
- package/esm2022/lib/contracts/sam.contract.mjs +1 -1
- package/esm2022/lib/contracts/section-view.contract.mjs +2 -0
- package/esm2022/lib/contracts/semantic-segmenter.contract.mjs +1 -1
- package/esm2022/lib/contracts/spatial-dataset.contract.mjs +3 -1
- package/esm2022/lib/contracts/toolbar-tool.contract.mjs +6 -4
- package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
- package/esm2022/lib/contracts/viz-config.mjs +2 -1
- package/esm2022/lib/geometry/contour.mjs +63 -0
- package/esm2022/lib/geometry/loft.mjs +128 -0
- package/esm2022/lib/geometry/polylabel.mjs +156 -0
- package/esm2022/lib/geometry/raster.mjs +98 -0
- package/esm2022/lib/geometry/reconstruct.mjs +315 -0
- package/esm2022/lib/geometry/reslice-image.mjs +57 -0
- package/esm2022/lib/geometry/ring.mjs +201 -0
- package/esm2022/lib/geometry/section.mjs +215 -0
- package/esm2022/lib/hex-color-picker/hex-color-picker.component.mjs +202 -102
- package/esm2022/lib/implementations/base-store-visualizer.mjs +201 -48
- package/esm2022/lib/implementations/napari-js/napari-axes-gizmo.mjs +65 -0
- package/esm2022/lib/implementations/napari-js/napari-display-state.mjs +136 -0
- package/esm2022/lib/implementations/napari-js/napari-helpers.mjs +199 -0
- package/esm2022/lib/implementations/napari-js/napari-image-2d-scene.mjs +602 -0
- package/esm2022/lib/implementations/napari-js/napari-loading-badge.mjs +12 -9
- package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +83 -0
- package/esm2022/lib/implementations/napari-js/napari-region-mesh-pointer.mjs +100 -0
- package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +180 -591
- package/esm2022/lib/implementations/napari-js/napari-scene.mjs +2 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-2d-scene.mjs +614 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +769 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-encoding.mjs +199 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +270 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-scene.mjs +159 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-tiles.mjs +106 -1408
- package/esm2022/lib/implementations/napari-js/napari-spatial-tooltip.mjs +2 -2
- package/esm2022/lib/implementations/napari-js/napari-surface-scene.mjs +271 -0
- package/esm2022/lib/implementations/napari-js/napari-tile-client.mjs +562 -0
- package/esm2022/lib/implementations/napari-js/napari-tool-bridge.mjs +347 -0
- package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +427 -4207
- package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +129 -0
- package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +550 -0
- package/esm2022/lib/implementations/napari-js/napari-volume-slice-planes.mjs +103 -0
- package/esm2022/lib/implementations/napari-js/napari-volume-z-handle.mjs +6 -6
- package/esm2022/lib/implementations/napari-js/region-overlay/overlay-projection.mjs +96 -0
- package/esm2022/lib/implementations/napari-js/region-overlay/region-edit.mjs +35 -0
- package/esm2022/lib/implementations/napari-js/region-overlay/region-svg-renderer.mjs +194 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/categorical-lookup.mjs +30 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/cell-layers.mjs +274 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/density-layer.mjs +144 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/layer-groups.mjs +165 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/plan-context.mjs +78 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-hover.mjs +182 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-jobs.mjs +369 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-layers.mjs +306 -0
- package/esm2022/lib/implementations/osd/display-pipeline.mjs +102 -40
- package/esm2022/lib/implementations/osd/histogram-sampler.mjs +56 -31
- package/esm2022/lib/implementations/osd/openseadragon-viewer-options.mjs +128 -0
- package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +333 -1685
- package/esm2022/lib/implementations/osd/osd-coordinate-transform.mjs +1 -1
- package/esm2022/lib/implementations/osd/osd-coords.mjs +5 -6
- package/esm2022/lib/implementations/osd/osd-export.mjs +122 -0
- package/esm2022/lib/implementations/osd/osd-lib.mjs +15 -1
- package/esm2022/lib/implementations/osd/osd-navigator-chrome.mjs +205 -0
- package/esm2022/lib/implementations/osd/osd-pixel-readback.mjs +68 -0
- package/esm2022/lib/implementations/osd/osd-region-overlay-draw.mjs +164 -0
- package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +213 -716
- package/esm2022/lib/implementations/osd/osd-scale-bar.mjs +52 -60
- package/esm2022/lib/implementations/osd/osd-tile-source.mjs +105 -0
- package/esm2022/lib/implementations/osd/osd-viewer-like.mjs +2 -0
- package/esm2022/lib/implementations/osd/osd-viewer-mount.mjs +44 -0
- package/esm2022/lib/implementations/osd/osd-viewport.mjs +184 -0
- package/esm2022/lib/implementations/osd/osd-zoom.mjs +7 -1
- package/esm2022/lib/implementations/osd/simple-source.mjs +395 -0
- package/esm2022/lib/implementations/osd/slice-cache.mjs +53 -48
- package/esm2022/lib/implementations/osd/tile-client.mjs +32 -11
- package/esm2022/lib/implementations/osd/tile-recolor.mjs +330 -0
- package/esm2022/lib/implementations/plotly/omics-trace-builders.mjs +161 -73
- package/esm2022/lib/implementations/plotly/plotly-coordinate-transform.mjs +1 -1
- package/esm2022/lib/implementations/plotly/plotly-image-loader.mjs +112 -0
- package/esm2022/lib/implementations/plotly/plotly-image-recolor.mjs +178 -0
- package/esm2022/lib/implementations/plotly/plotly-intensity-inset.mjs +33 -0
- package/esm2022/lib/implementations/plotly/plotly-isosurface-controls.mjs +83 -0
- package/esm2022/lib/implementations/plotly/plotly-layouts.mjs +121 -0
- package/esm2022/lib/implementations/plotly/plotly-readback.mjs +117 -0
- package/esm2022/lib/implementations/plotly/plotly-region-overlay.mjs +19 -10
- package/esm2022/lib/implementations/plotly/plotly-shape-projection.mjs +223 -0
- package/esm2022/lib/implementations/plotly/plotly-trace-builders.mjs +79 -19
- package/esm2022/lib/implementations/plotly/plotly-zoom-controller.mjs +223 -0
- package/esm2022/lib/implementations/plotly/plotly.service.mjs +439 -1655
- package/esm2022/lib/implementations/region-centroids.mjs +47 -0
- package/esm2022/lib/implementations/simple-slice-access.service.mjs +22 -12
- package/esm2022/lib/implementations/spatial-data-http/spatial-data-http.service.mjs +172 -92
- package/esm2022/lib/implementations/spatial-data-http/spatial-wire.mjs +103 -22
- package/esm2022/lib/implementations/tile-server/index.mjs +6 -0
- package/esm2022/lib/implementations/tile-server/native-histogram.mjs +30 -0
- package/esm2022/lib/implementations/tile-server/poll-descriptor.mjs +65 -0
- package/esm2022/lib/implementations/tile-server/tile-protocol.mjs +42 -0
- package/esm2022/lib/implementations/tile-server/transport.mjs +135 -0
- package/esm2022/lib/intensity/intensity-profile.mjs +107 -0
- package/esm2022/lib/intensity/intensity-profile.service.mjs +223 -0
- package/esm2022/lib/intensity-inset/intensity-inset.component.mjs +133 -0
- package/esm2022/lib/models/bezier.mjs +1 -11
- package/esm2022/lib/models/class-preset.mjs +41 -3
- package/esm2022/lib/models/geometry.mjs +27 -164
- package/esm2022/lib/models/polygon-edit.mjs +254 -0
- package/esm2022/lib/models/polygon-factory.mjs +134 -0
- package/esm2022/lib/models/region-clone.mjs +68 -0
- package/esm2022/lib/models/region-geojson.mjs +411 -0
- package/esm2022/lib/models/region.mjs +34 -33
- package/esm2022/lib/models/shape.mjs +18 -16
- package/esm2022/lib/plot-mode/contribution-host.mjs +297 -0
- package/esm2022/lib/plot-mode/plot-mode-controller.mjs +9 -6
- package/esm2022/lib/plot-mode/plot-type-menu.mjs +85 -0
- package/esm2022/lib/plot-mode/tool-params-model.mjs +87 -0
- package/esm2022/lib/plot.utilities.mjs +296 -473
- package/esm2022/lib/processing/image-crop.mjs +1 -1
- package/esm2022/lib/processing/processing-image.mjs +28 -15
- package/esm2022/lib/provide-visualization.mjs +40 -14
- package/esm2022/lib/region-editor/class-tree/class-tree.component.mjs +156 -0
- package/esm2022/lib/region-editor/class-tree/class-tree.mjs +108 -0
- package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +163 -0
- package/esm2022/lib/region-editor/file-stem.mjs +13 -0
- package/esm2022/lib/region-editor/manage-classes-dialog/manage-classes-dialog.component.mjs +118 -0
- package/esm2022/lib/region-editor/mask-export.service.mjs +98 -0
- package/esm2022/lib/region-editor/mask-raster.mjs +11 -5
- package/esm2022/lib/region-editor/region-color-dialog/region-color-dialog.component.mjs +56 -0
- package/esm2022/lib/region-editor/region-editor-help/region-editor-help.component.mjs +28 -0
- package/esm2022/lib/region-editor/region-editor.component.mjs +896 -660
- package/esm2022/lib/region-editor/region-metrics.mjs +86 -0
- package/esm2022/lib/region-editor/region-persistence.service.mjs +160 -0
- package/esm2022/lib/region-editor/region-table/region-table.component.mjs +169 -0
- package/esm2022/lib/region-editor/save-mask-dialog/save-mask-dialog.component.mjs +91 -0
- package/esm2022/lib/region-editor/save-regions-dialog/save-regions-dialog.component.mjs +92 -0
- package/esm2022/lib/region-ops.service.mjs +28 -70
- package/esm2022/lib/region-overlay/region-geometry.mjs +360 -0
- package/esm2022/lib/region-overlay/region-hit-test.mjs +103 -0
- package/esm2022/lib/region-overlay/region-source-layer.mjs +378 -0
- package/esm2022/lib/region-overlay/region-style.mjs +97 -0
- package/esm2022/lib/region-overlay/svg-region-renderer.mjs +228 -0
- package/esm2022/lib/region-source/http-region-source.mjs +104 -0
- package/esm2022/lib/region-source/region-source-ops.mjs +53 -0
- package/esm2022/lib/region-source/region-source-worker.mjs +10 -0
- package/esm2022/lib/region-source/region-source.mjs +67 -0
- package/esm2022/lib/region-source/region-tiles.mjs +708 -0
- package/esm2022/lib/region-source/worker-region-source.mjs +229 -0
- package/esm2022/lib/render-orchestrator.mjs +14 -11
- package/esm2022/lib/render-session.mjs +207 -0
- package/esm2022/lib/routing-visualizer.service.mjs +858 -414
- package/esm2022/lib/section-pane/section-pane.component.mjs +299 -0
- package/esm2022/lib/spatial/density-raster.mjs +14 -0
- package/esm2022/lib/spatial/embedding-compute-coordinator.mjs +239 -0
- package/esm2022/lib/spatial/embedding-compute.mjs +43 -10
- package/esm2022/lib/spatial/gene-search.mjs +1 -1
- package/esm2022/lib/spatial/glyphs.mjs +97 -0
- package/esm2022/lib/spatial/lod.mjs +187 -0
- package/esm2022/lib/spatial/spatial-controls.facade.mjs +200 -0
- package/esm2022/lib/spatial/spatial-density.mjs +25 -16
- package/esm2022/lib/spatial/spatial-encoding.mjs +26 -82
- package/esm2022/lib/spatial/spatial-expression.mjs +43 -42
- package/esm2022/lib/spatial/spatial-framing.mjs +1 -1
- package/esm2022/lib/spatial/spatial-heatmap.mjs +6 -3
- package/esm2022/lib/spatial/spatial-hover.mjs +5 -33
- package/esm2022/lib/spatial/spatial-panel-model.mjs +282 -0
- package/esm2022/lib/spatial/spatial-sections.mjs +1 -1
- package/esm2022/lib/spatial/spatial-selection.mjs +33 -46
- package/esm2022/lib/spatial/spatial-tile-merge.mjs +219 -0
- package/esm2022/lib/spatial/spatial-tiles.mjs +12 -648
- package/esm2022/lib/spatial/spatial-volume-image.mjs +2 -4
- package/esm2022/lib/spatial/stats.mjs +71 -0
- package/esm2022/lib/spatial/transcript-grouping.mjs +307 -0
- package/esm2022/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.mjs +150 -0
- package/esm2022/lib/spatial-controls/spatial-charts/chart-data-model.mjs +309 -0
- package/esm2022/lib/spatial-controls/spatial-charts/chart-help.mjs +145 -0
- package/esm2022/lib/spatial-controls/spatial-charts/plotly-chart-host.mjs +158 -0
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-chart-window/spatial-chart-window.component.mjs +47 -0
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-charts.component.mjs +297 -802
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-embedding-controls/spatial-embedding-controls.component.mjs +89 -0
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-heatmap-controls/spatial-heatmap-controls.component.mjs +52 -0
- package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +143 -1238
- package/esm2022/lib/spatial-controls/spatial-gene-picker.mjs +153 -0
- package/esm2022/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.mjs +241 -0
- package/esm2022/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.mjs +193 -0
- package/esm2022/lib/spatial-controls/spatial-key/spatial-key.component.mjs +132 -0
- package/esm2022/lib/spatial-controls/spatial-key/spatial-key.model.mjs +67 -0
- package/esm2022/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.mjs +147 -0
- package/esm2022/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.mjs +300 -0
- package/esm2022/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.mjs +370 -0
- package/esm2022/lib/store/class-color.util.mjs +53 -5
- package/esm2022/lib/store/class-signatures.mjs +63 -0
- package/esm2022/lib/store/region-history.mjs +146 -0
- package/esm2022/lib/store/region-scope-cache.mjs +144 -0
- package/esm2022/lib/store/region-selection.mjs +82 -0
- package/esm2022/lib/store/region-source-scope.mjs +171 -0
- package/esm2022/lib/store/region-store.service.mjs +986 -670
- package/esm2022/lib/store/spatial-selection.service.mjs +2 -2
- package/esm2022/lib/store/visualizer-store.service.mjs +81 -76
- package/esm2022/lib/toast-outlets.mjs +5 -4
- package/esm2022/lib/toolbar/brush/brush-tool.service.mjs +92 -434
- package/esm2022/lib/toolbar/canvas-tools.mjs +20 -0
- package/esm2022/lib/toolbar/crop/slide-crop.mjs +26 -42
- package/esm2022/lib/toolbar/plot-type-selector/plot-type-selector.component.mjs +85 -0
- package/esm2022/lib/toolbar/region-tools/region-tool-buttons.mjs +74 -0
- package/esm2022/lib/toolbar/region-tools/region-tools.component.mjs +120 -0
- package/esm2022/lib/toolbar/segmentation/cell-segment-tool.service.mjs +74 -78
- package/esm2022/lib/toolbar/segmentation/cellpose-segmenter.service.mjs +50 -8
- package/esm2022/lib/toolbar/segmentation/onnx-sam-session.mjs +61 -42
- package/esm2022/lib/toolbar/segmentation/pending-calls.mjs +47 -0
- package/esm2022/lib/toolbar/segmentation/sam-model-registry.mjs +12 -4
- package/esm2022/lib/toolbar/segmentation/sam-onnx-core.mjs +70 -14
- package/esm2022/lib/toolbar/segmentation/sam-point-tool.service.mjs +135 -172
- package/esm2022/lib/toolbar/segmentation/sam-prompt.mjs +9 -90
- package/esm2022/lib/toolbar/segmentation/sam-session.service.mjs +183 -0
- package/esm2022/lib/toolbar/segmentation/sam-tool.service.mjs +95 -150
- package/esm2022/lib/toolbar/segmentation/segmentation-commit.mjs +12 -0
- package/esm2022/lib/toolbar/segmentation/segmentation-runner.mjs +108 -0
- package/esm2022/lib/toolbar/segmentation-tools/segmentation-tools.component.mjs +155 -0
- package/esm2022/lib/toolbar/stack-controls/stack-controls.component.mjs +121 -0
- package/esm2022/lib/toolbar/tool-kit/async-tool-status.mjs +37 -0
- package/esm2022/lib/toolbar/tool-kit/canvas-tool-manager.mjs +63 -0
- package/esm2022/lib/toolbar/tool-kit/canvas-tool.mjs +2 -0
- package/esm2022/lib/toolbar/tool-kit/frame-pixels.mjs +108 -0
- package/esm2022/lib/toolbar/tool-kit/mask-stroke-editor.mjs +306 -0
- package/esm2022/lib/toolbar/tool-kit/matrix-frame.mjs +61 -0
- package/esm2022/lib/toolbar/tool-kit/tool-overlay.mjs +140 -0
- package/esm2022/lib/toolbar/tool-kit/undo-gesture.mjs +24 -0
- package/esm2022/lib/toolbar/tool-slider/tool-slider.component.mjs +63 -0
- package/esm2022/lib/toolbar/toolbar-help-dialog/toolbar-help-dialog.component.mjs +50 -0
- package/esm2022/lib/toolbar/toolbar.component.mjs +84 -119
- package/esm2022/lib/toolbar/vertex-eraser/vertex-eraser-tool.service.mjs +93 -115
- package/esm2022/lib/toolbar/view-controls/view-controls.component.mjs +107 -0
- package/esm2022/lib/toolbar/wand/wand-region-grow.mjs +321 -0
- package/esm2022/lib/toolbar/wand/wand-tool.service.mjs +121 -416
- package/esm2022/lib/toolbar/wand/wand.service.mjs +30 -894
- package/esm2022/lib/toolbar/zoom-to-box/zoom-to-box-tool.service.mjs +48 -90
- package/esm2022/lib/util/mark-for-check.mjs +17 -0
- package/esm2022/lib/util/supersede.mjs +56 -0
- package/esm2022/lib/visualization.module.mjs +39 -141
- package/esm2022/lib/visualizer/floating-drag.directive.mjs +58 -0
- package/esm2022/lib/visualizer/region-actions.mjs +149 -0
- package/esm2022/lib/visualizer/region-load.mjs +123 -0
- package/esm2022/lib/visualizer/spatial-dataset-binder.mjs +163 -0
- package/esm2022/lib/visualizer/tool-modes.mjs +113 -0
- package/esm2022/lib/visualizer/viewer-shortcuts.mjs +167 -0
- package/esm2022/lib/visualizer/visualizer-context-menu.mjs +119 -0
- package/esm2022/lib/visualizer/volume-sections.mjs +175 -0
- package/esm2022/lib/visualizer.component.mjs +602 -1902
- package/esm2022/lib/workers/spatial-math-ops.mjs +43 -0
- package/esm2022/lib/workers/spatial-math-worker.mjs +10 -0
- package/esm2022/lib/workers/spatial-math.mjs +190 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BKQhpbHv.mjs +47169 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BKQhpbHv.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs +238 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs +12 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-spatial-math-worker-BzVFFqGS.mjs +12 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-spatial-math-worker-BzVFFqGS.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +41 -34467
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs.map +1 -1
- package/fesm2022/mask.worker.js +36 -917
- package/fesm2022/onnx-sam.worker.js +52 -16
- package/fesm2022/region-source.worker.js +1067 -0
- package/fesm2022/spatial-math.worker.js +471 -0
- package/fesm2022/tsne.worker.js +32 -15
- package/index.d.ts +19 -10
- package/lib/channel-histogram/channel-histogram.component.d.ts +53 -43
- package/lib/contracts/capabilities.contract.d.ts +4 -2
- package/lib/contracts/cell-segmenter.contract.d.ts +1 -0
- package/lib/contracts/channel-histogram-api.contract.d.ts +4 -0
- package/lib/contracts/color.d.ts +27 -0
- package/lib/contracts/colormap-lut.d.ts +19 -4
- package/lib/contracts/coordinate-transform.contract.d.ts +3 -3
- package/lib/contracts/display-types.d.ts +21 -0
- package/lib/contracts/image.contract.d.ts +4 -0
- package/lib/contracts/instance-segmenter.contract.d.ts +5 -0
- package/lib/contracts/intensity.d.ts +13 -2
- package/lib/contracts/plot-type.d.ts +3 -1
- package/lib/contracts/ports/image-state.port.d.ts +6 -2
- package/lib/contracts/ports/preferences.port.d.ts +4 -0
- package/lib/contracts/ports/region-io.port.d.ts +1 -0
- package/lib/contracts/ports/spatial-data.port.d.ts +4 -10
- package/lib/contracts/ports/tile-access.port.d.ts +1 -0
- package/lib/contracts/region-editor-api.contract.d.ts +85 -1
- package/lib/contracts/region-overlay.contract.d.ts +5 -0
- package/lib/contracts/region-store.contract.d.ts +22 -0
- package/lib/contracts/sam.contract.d.ts +7 -0
- package/lib/contracts/section-view.contract.d.ts +44 -0
- package/lib/contracts/semantic-segmenter.contract.d.ts +6 -0
- package/lib/contracts/spatial-dataset.contract.d.ts +19 -6
- package/lib/contracts/toolbar-tool.contract.d.ts +1 -0
- package/lib/contracts/visualizer.contract.d.ts +231 -54
- package/lib/contracts/viz-config.d.ts +9 -0
- package/lib/geometry/contour.d.ts +24 -0
- package/lib/geometry/loft.d.ts +22 -0
- package/lib/geometry/polylabel.d.ts +23 -0
- package/lib/geometry/raster.d.ts +42 -0
- package/lib/geometry/reconstruct.d.ts +54 -0
- package/lib/geometry/reslice-image.d.ts +33 -0
- package/lib/geometry/ring.d.ts +67 -0
- package/lib/geometry/section.d.ts +52 -0
- package/lib/hex-color-picker/hex-color-picker.component.d.ts +61 -27
- package/lib/implementations/base-store-visualizer.d.ts +61 -15
- package/lib/implementations/napari-js/napari-axes-gizmo.d.ts +36 -0
- package/lib/implementations/napari-js/napari-display-state.d.ts +76 -0
- package/lib/implementations/napari-js/napari-helpers.d.ts +129 -0
- package/lib/implementations/napari-js/napari-image-2d-scene.d.ts +162 -0
- package/lib/implementations/napari-js/napari-loading-badge.d.ts +4 -3
- package/lib/implementations/napari-js/napari-loading-state.d.ts +37 -0
- package/lib/implementations/napari-js/napari-region-mesh-pointer.d.ts +32 -0
- package/lib/implementations/napari-js/napari-region-overlay.d.ts +68 -71
- package/lib/implementations/napari-js/napari-scene.d.ts +126 -0
- package/lib/implementations/napari-js/napari-spatial-2d-scene.d.ts +163 -0
- package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +212 -0
- package/lib/implementations/napari-js/napari-spatial-encoding.d.ts +114 -0
- package/lib/implementations/napari-js/napari-spatial-hover.d.ts +91 -0
- package/lib/implementations/napari-js/napari-spatial-scene.d.ts +118 -0
- package/lib/implementations/napari-js/napari-spatial-tiles.d.ts +56 -263
- package/lib/implementations/napari-js/napari-spatial-tooltip.d.ts +1 -1
- package/lib/implementations/napari-js/napari-surface-scene.d.ts +76 -0
- package/lib/implementations/napari-js/napari-tile-client.d.ts +214 -0
- package/lib/implementations/napari-js/napari-tool-bridge.d.ts +179 -0
- package/lib/implementations/napari-js/napari-visualizer.service.d.ts +169 -883
- package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +66 -0
- package/lib/implementations/napari-js/napari-volume-scene.d.ts +148 -0
- package/lib/implementations/napari-js/napari-volume-slice-planes.d.ts +43 -0
- package/lib/implementations/napari-js/napari-volume-z-handle.d.ts +8 -12
- package/lib/implementations/napari-js/region-overlay/overlay-projection.d.ts +59 -0
- package/lib/implementations/napari-js/region-overlay/region-edit.d.ts +15 -0
- package/lib/implementations/napari-js/region-overlay/region-svg-renderer.d.ts +54 -0
- package/lib/implementations/napari-js/spatial-tiles/categorical-lookup.d.ts +26 -0
- package/lib/implementations/napari-js/spatial-tiles/cell-layers.d.ts +70 -0
- package/lib/implementations/napari-js/spatial-tiles/density-layer.d.ts +61 -0
- package/lib/implementations/napari-js/spatial-tiles/layer-groups.d.ts +67 -0
- package/lib/implementations/napari-js/spatial-tiles/plan-context.d.ts +38 -0
- package/lib/implementations/napari-js/spatial-tiles/transcript-hover.d.ts +71 -0
- package/lib/implementations/napari-js/spatial-tiles/transcript-jobs.d.ts +105 -0
- package/lib/implementations/napari-js/spatial-tiles/transcript-layers.d.ts +56 -0
- package/lib/implementations/osd/display-pipeline.d.ts +38 -9
- package/lib/implementations/osd/histogram-sampler.d.ts +22 -12
- package/lib/implementations/osd/openseadragon-viewer-options.d.ts +35 -0
- package/lib/implementations/osd/openseadragon-visualizer.service.d.ts +78 -354
- package/lib/implementations/osd/osd-coordinate-transform.d.ts +2 -1
- package/lib/implementations/osd/osd-coords.d.ts +6 -4
- package/lib/implementations/osd/osd-export.d.ts +36 -0
- package/lib/implementations/osd/osd-lib.d.ts +7 -0
- package/lib/implementations/osd/osd-navigator-chrome.d.ts +69 -0
- package/lib/implementations/osd/osd-pixel-readback.d.ts +22 -0
- package/lib/implementations/osd/osd-region-overlay-draw.d.ts +38 -0
- package/lib/implementations/osd/osd-region-overlay.d.ts +46 -51
- package/lib/implementations/osd/osd-scale-bar.d.ts +8 -6
- package/lib/implementations/osd/osd-tile-source.d.ts +49 -0
- package/lib/implementations/osd/osd-viewer-like.d.ts +100 -0
- package/lib/implementations/osd/osd-viewer-mount.d.ts +14 -0
- package/lib/implementations/osd/osd-viewport.d.ts +77 -0
- package/lib/implementations/osd/osd-zoom.d.ts +6 -0
- package/lib/implementations/osd/simple-source.d.ts +161 -0
- package/lib/implementations/osd/slice-cache.d.ts +12 -3
- package/lib/implementations/osd/tile-client.d.ts +11 -14
- package/lib/implementations/osd/tile-recolor.d.ts +141 -0
- package/lib/implementations/plotly/omics-trace-builders.d.ts +32 -20
- package/lib/implementations/plotly/plotly-image-loader.d.ts +49 -0
- package/lib/implementations/plotly/plotly-image-recolor.d.ts +75 -0
- package/lib/implementations/plotly/plotly-intensity-inset.d.ts +8 -0
- package/lib/implementations/plotly/plotly-isosurface-controls.d.ts +38 -0
- package/lib/implementations/plotly/plotly-layouts.d.ts +188 -0
- package/lib/implementations/plotly/plotly-readback.d.ts +41 -0
- package/lib/implementations/plotly/plotly-region-overlay.d.ts +2 -2
- package/lib/implementations/plotly/plotly-shape-projection.d.ts +92 -0
- package/lib/implementations/plotly/plotly-trace-builders.d.ts +23 -12
- package/lib/implementations/plotly/plotly-zoom-controller.d.ts +86 -0
- package/lib/implementations/plotly/plotly.service.d.ts +136 -401
- package/lib/implementations/region-centroids.d.ts +14 -0
- package/lib/implementations/simple-slice-access.service.d.ts +7 -4
- package/lib/implementations/spatial-data-http/spatial-data-http.service.d.ts +42 -18
- package/lib/implementations/spatial-data-http/spatial-wire.d.ts +34 -9
- package/lib/implementations/tile-server/index.d.ts +5 -0
- package/lib/implementations/tile-server/native-histogram.d.ts +25 -0
- package/lib/implementations/tile-server/poll-descriptor.d.ts +39 -0
- package/lib/implementations/tile-server/tile-protocol.d.ts +83 -0
- package/lib/implementations/tile-server/transport.d.ts +62 -0
- package/lib/intensity/intensity-profile.d.ts +66 -0
- package/lib/intensity/intensity-profile.service.d.ts +108 -0
- package/lib/intensity-inset/intensity-inset.component.d.ts +58 -0
- package/lib/models/bezier.d.ts +0 -5
- package/lib/models/class-preset.d.ts +25 -0
- package/lib/models/geometry.d.ts +14 -48
- package/lib/models/polygon-edit.d.ts +72 -0
- package/lib/models/polygon-factory.d.ts +45 -0
- package/lib/models/region-clone.d.ts +20 -0
- package/lib/models/region-geojson.d.ts +57 -0
- package/lib/models/region.d.ts +59 -4
- package/lib/models/shape.d.ts +8 -0
- package/lib/plot-mode/contribution-host.d.ts +125 -0
- package/lib/plot-mode/plot-type-menu.d.ts +60 -0
- package/lib/plot-mode/tool-params-model.d.ts +49 -0
- package/lib/plot.utilities.d.ts +19 -30
- package/lib/processing/processing-image.d.ts +5 -2
- package/lib/provide-visualization.d.ts +19 -2
- package/lib/region-editor/class-tree/class-tree.component.d.ts +78 -0
- package/lib/region-editor/class-tree/class-tree.d.ts +31 -0
- package/lib/region-editor/classes-panel/classes-panel.component.d.ts +86 -0
- package/lib/region-editor/file-stem.d.ts +7 -0
- package/lib/region-editor/manage-classes-dialog/manage-classes-dialog.component.d.ts +45 -0
- package/lib/region-editor/mask-export.service.d.ts +54 -0
- package/lib/region-editor/mask-raster.d.ts +2 -8
- package/lib/region-editor/region-color-dialog/region-color-dialog.component.d.ts +29 -0
- package/lib/region-editor/region-editor-help/region-editor-help.component.d.ts +11 -0
- package/lib/region-editor/region-editor.component.d.ts +283 -200
- package/lib/region-editor/region-metrics.d.ts +34 -0
- package/lib/region-editor/region-persistence.service.d.ts +77 -0
- package/lib/region-editor/region-table/region-table.component.d.ts +89 -0
- package/lib/region-editor/save-mask-dialog/save-mask-dialog.component.d.ts +36 -0
- package/lib/region-editor/save-regions-dialog/save-regions-dialog.component.d.ts +37 -0
- package/lib/region-ops.service.d.ts +1 -7
- package/lib/region-overlay/region-geometry.d.ts +158 -0
- package/lib/region-overlay/region-hit-test.d.ts +38 -0
- package/lib/region-overlay/region-source-layer.d.ts +96 -0
- package/lib/region-overlay/region-style.d.ts +52 -0
- package/lib/region-overlay/svg-region-renderer.d.ts +110 -0
- package/lib/region-source/http-region-source.d.ts +45 -0
- package/lib/region-source/region-source-ops.d.ts +89 -0
- package/lib/region-source/region-source-worker.d.ts +7 -0
- package/lib/region-source/region-source.d.ts +82 -0
- package/lib/region-source/region-tiles.d.ts +289 -0
- package/lib/region-source/worker-region-source.d.ts +65 -0
- package/lib/render-orchestrator.d.ts +6 -2
- package/lib/render-session.d.ts +75 -0
- package/lib/routing-visualizer.service.d.ts +248 -59
- package/lib/section-pane/section-pane.component.d.ts +47 -0
- package/lib/spatial/density-raster.d.ts +6 -0
- package/lib/spatial/embedding-compute-coordinator.d.ts +123 -0
- package/lib/spatial/embedding-compute.d.ts +21 -2
- package/lib/spatial/glyphs.d.ts +16 -0
- package/lib/spatial/lod.d.ts +94 -0
- package/lib/spatial/spatial-controls.facade.d.ts +64 -0
- package/lib/spatial/spatial-density.d.ts +15 -5
- package/lib/spatial/spatial-encoding.d.ts +11 -44
- package/lib/spatial/spatial-expression.d.ts +40 -22
- package/lib/spatial/spatial-framing.d.ts +1 -0
- package/lib/spatial/spatial-heatmap.d.ts +2 -0
- package/lib/spatial/spatial-hover.d.ts +4 -16
- package/lib/spatial/spatial-panel-model.d.ts +135 -0
- package/lib/spatial/spatial-selection.d.ts +21 -26
- package/lib/spatial/spatial-tile-merge.d.ts +41 -0
- package/lib/spatial/spatial-tiles.d.ts +9 -256
- package/lib/spatial/stats.d.ts +38 -0
- package/lib/spatial/transcript-grouping.d.ts +119 -0
- package/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.d.ts +64 -0
- package/lib/spatial-controls/spatial-charts/chart-data-model.d.ts +153 -0
- package/lib/spatial-controls/spatial-charts/chart-help.d.ts +69 -0
- package/lib/spatial-controls/spatial-charts/plotly-chart-host.d.ts +98 -0
- package/lib/spatial-controls/spatial-charts/spatial-chart-window/spatial-chart-window.component.d.ts +26 -0
- package/lib/spatial-controls/spatial-charts/spatial-charts.component.d.ts +101 -260
- package/lib/spatial-controls/spatial-charts/spatial-embedding-controls/spatial-embedding-controls.component.d.ts +43 -0
- package/lib/spatial-controls/spatial-charts/spatial-heatmap-controls/spatial-heatmap-controls.component.d.ts +27 -0
- package/lib/spatial-controls/spatial-controls.component.d.ts +68 -448
- package/lib/spatial-controls/spatial-gene-picker.d.ts +86 -0
- package/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.d.ts +102 -0
- package/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.d.ts +72 -0
- package/lib/spatial-controls/spatial-key/spatial-key.component.d.ts +66 -0
- package/lib/spatial-controls/spatial-key/spatial-key.model.d.ts +33 -0
- package/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.d.ts +64 -0
- package/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.d.ts +117 -0
- package/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.d.ts +142 -0
- package/lib/store/class-color.util.d.ts +39 -2
- package/lib/store/class-signatures.d.ts +11 -0
- package/lib/store/region-history.d.ts +66 -0
- package/lib/store/region-scope-cache.d.ts +65 -0
- package/lib/store/region-selection.d.ts +36 -0
- package/lib/store/region-source-scope.d.ts +68 -0
- package/lib/store/region-store.service.d.ts +312 -116
- package/lib/store/visualizer-store.service.d.ts +32 -33
- package/lib/toast-outlets.d.ts +4 -3
- package/lib/toolbar/brush/brush-tool.service.d.ts +31 -98
- package/lib/toolbar/canvas-tools.d.ts +20 -0
- package/lib/toolbar/crop/slide-crop.d.ts +10 -4
- package/lib/toolbar/plot-type-selector/plot-type-selector.component.d.ts +38 -0
- package/lib/toolbar/region-tools/region-tool-buttons.d.ts +21 -0
- package/lib/toolbar/region-tools/region-tools.component.d.ts +62 -0
- package/lib/toolbar/segmentation/cell-segment-tool.service.d.ts +10 -14
- package/lib/toolbar/segmentation/cellpose-segmenter.service.d.ts +12 -2
- package/lib/toolbar/segmentation/onnx-sam-session.d.ts +22 -3
- package/lib/toolbar/segmentation/pending-calls.d.ts +31 -0
- package/lib/toolbar/segmentation/sam-model-registry.d.ts +9 -3
- package/lib/toolbar/segmentation/sam-onnx-core.d.ts +18 -5
- package/lib/toolbar/segmentation/sam-point-tool.service.d.ts +46 -32
- package/lib/toolbar/segmentation/sam-prompt.d.ts +7 -31
- package/lib/toolbar/segmentation/sam-session.service.d.ts +74 -0
- package/lib/toolbar/segmentation/sam-tool.service.d.ts +23 -30
- package/lib/toolbar/segmentation/segmentation-commit.d.ts +8 -0
- package/lib/toolbar/segmentation/segmentation-runner.d.ts +52 -0
- package/lib/toolbar/segmentation-tools/segmentation-tools.component.d.ts +87 -0
- package/lib/toolbar/stack-controls/stack-controls.component.d.ts +51 -0
- package/lib/toolbar/tool-kit/async-tool-status.d.ts +21 -0
- package/lib/toolbar/tool-kit/canvas-tool-manager.d.ts +36 -0
- package/lib/toolbar/tool-kit/canvas-tool.d.ts +86 -0
- package/lib/toolbar/tool-kit/frame-pixels.d.ts +45 -0
- package/lib/toolbar/tool-kit/mask-stroke-editor.d.ts +125 -0
- package/lib/toolbar/tool-kit/matrix-frame.d.ts +40 -0
- package/lib/toolbar/tool-kit/tool-overlay.d.ts +60 -0
- package/lib/toolbar/tool-kit/undo-gesture.d.ts +17 -0
- package/lib/toolbar/tool-slider/tool-slider.component.d.ts +33 -0
- package/lib/toolbar/toolbar-help-dialog/toolbar-help-dialog.component.d.ts +24 -0
- package/lib/toolbar/toolbar.component.d.ts +55 -84
- package/lib/toolbar/vertex-eraser/vertex-eraser-tool.service.d.ts +33 -40
- package/lib/toolbar/view-controls/view-controls.component.d.ts +54 -0
- package/lib/toolbar/wand/wand-region-grow.d.ts +49 -0
- package/lib/toolbar/wand/wand-tool.service.d.ts +39 -124
- package/lib/toolbar/wand/wand.service.d.ts +22 -116
- package/lib/toolbar/zoom-to-box/zoom-to-box-tool.service.d.ts +17 -37
- package/lib/util/mark-for-check.d.ts +11 -0
- package/lib/util/supersede.d.ts +53 -0
- package/lib/visualization.module.d.ts +18 -39
- package/lib/visualizer/floating-drag.directive.d.ts +30 -0
- package/lib/visualizer/region-actions.d.ts +54 -0
- package/lib/visualizer/region-load.d.ts +46 -0
- package/lib/visualizer/spatial-dataset-binder.d.ts +74 -0
- package/lib/visualizer/tool-modes.d.ts +49 -0
- package/lib/visualizer/viewer-shortcuts.d.ts +71 -0
- package/lib/visualizer/visualizer-context-menu.d.ts +55 -0
- package/lib/visualizer/volume-sections.d.ts +64 -0
- package/lib/visualizer.component.d.ts +232 -447
- package/lib/workers/spatial-math-ops.d.ts +65 -0
- package/lib/workers/spatial-math-worker.d.ts +7 -0
- package/lib/workers/spatial-math.d.ts +74 -0
- package/package.json +12 -3
- package/src/lib/assets/slice.svg +23 -0
- package/src/lib/styles/_viz-icons-rules.scss +73 -0
- package/src/lib/styles/viz-icons.scss +14 -0
- package/esm2022/lib/implementations/napari-js/napari-axes-labels.mjs +0 -97
- package/esm2022/lib/implementations/napari-js/napari-navigator.mjs +0 -195
- package/esm2022/lib/implementations/napari-js/napari-scale-bar.mjs +0 -92
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-BwP-A11m.mjs +0 -329
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-BwP-A11m.mjs.map +0 -1
- package/lib/implementations/napari-js/napari-axes-labels.d.ts +0 -49
- package/lib/implementations/napari-js/napari-navigator.d.ts +0 -72
- package/lib/implementations/napari-js/napari-scale-bar.d.ts +0 -35
- package/src/lib/assets/cell-detection.svg +0 -37
- package/src/lib/assets/click.svg +0 -1
- package/src/lib/assets/colormap-luts.json +0 -1
- package/src/lib/assets/edit-selection-white.svg +0 -47
- package/src/lib/assets/icons/colormap-earth.png +0 -0
- package/src/lib/assets/icons/colormap-placeholder.png +0 -0
- package/src/lib/assets/icons/colormap-pubu.png +0 -0
- package/src/lib/assets/interactive-segmentation-cursor.svg +0 -1
- package/src/lib/assets/picture-segmentation.svg +0 -43
- package/src/lib/assets/test/download-379.svg +0 -1
- package/src/lib/assets/test/download-98.svg +0 -1
- package/src/lib/assets/test/json-1.svg +0 -1
- package/src/lib/assets/test/load-53.svg +0 -1
- package/src/lib/assets/test/mask-44.svg +0 -1
- package/src/lib/assets/test/mask-download-44.svg +0 -15
- package/src/lib/assets/test/mask-save-44.svg +0 -11
- package/src/lib/assets/test/overlay-1.svg +0 -1
- package/src/lib/assets/test/overlay-4.svg +0 -1
- package/src/lib/assets/test/region-26.svg +0 -1
- package/src/lib/assets/test/save-56.svg +0 -1
- package/src/lib/assets/test/upload-43.svg +0 -1
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { Region
|
|
5
|
-
import * as i0 from "@angular/core";
|
|
6
|
-
import * as i1 from "../wand/wand.service";
|
|
1
|
+
import { MaskStrokeEditor } from '../tool-kit/mask-stroke-editor';
|
|
2
|
+
import { UndoGesture } from '../tool-kit/undo-gesture';
|
|
3
|
+
import { ToolOverlayCanvas } from '../tool-kit/tool-overlay';
|
|
4
|
+
import { Region } from '../../models/region';
|
|
7
5
|
/** Default brush diameter (matrix pixels) if none is supplied. */
|
|
8
6
|
const DEFAULT_BRUSH_SIZE = 40;
|
|
9
7
|
/**
|
|
@@ -17,37 +15,27 @@ const DEFAULT_BRUSH_SIZE = 40;
|
|
|
17
15
|
* No pixel sampling and no cursor indicator: the painted stroke itself shows the
|
|
18
16
|
* brush size. The overlay canvas only captures the pointer.
|
|
19
17
|
*
|
|
20
|
-
* Lifecycle mirrors the wand: a
|
|
21
|
-
*
|
|
18
|
+
* Lifecycle mirrors the wand: a plain class, one instance per backend's
|
|
19
|
+
* `CanvasToolManager`, armed with `activate(host, options)` / `deactivate()`.
|
|
22
20
|
*
|
|
23
21
|
* Holes / donuts (jit-ui#85): brushing a ring that encloses an unpainted area
|
|
24
|
-
* keeps the enclosed hole —
|
|
22
|
+
* keeps the enclosed hole — the contour tracer (`geometry/contour`) traces interior
|
|
25
23
|
* rings into {@link Polygon.holes}, which adopt/merge preserve (the re-rasterize
|
|
26
24
|
* punches the holes back out). The OpenSeadragon overlay renders them with
|
|
27
25
|
* even-odd fill and GeoJSON round-trips them as extra Polygon rings. The Plotly
|
|
28
26
|
* (Heatmap) backend currently renders the filled exterior only.
|
|
29
27
|
*/
|
|
30
|
-
export class
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
this.
|
|
34
|
-
this.
|
|
28
|
+
export class BrushTool {
|
|
29
|
+
/** @param gestureTarget the region store, so each drag is one undo step. */
|
|
30
|
+
constructor(gestureTarget) {
|
|
31
|
+
this.id = 'brush';
|
|
32
|
+
this.overlay = new ToolOverlayCanvas();
|
|
35
33
|
/**
|
|
36
|
-
* Accumulated brush region (bbox-relative mask)
|
|
37
|
-
* subsequent stroke extends the *same* region
|
|
38
|
-
* matching QuPath, and the wand.
|
|
34
|
+
* Accumulated brush region (bbox-relative mask), shared logic with the wand.
|
|
35
|
+
* Persists across mouseup so a subsequent stroke extends the *same* region
|
|
36
|
+
* until the user switches tool — matching QuPath, and the wand.
|
|
39
37
|
*/
|
|
40
|
-
this.
|
|
41
|
-
/** Id of the region this stroke is editing (null = a fresh region). For an
|
|
42
|
-
* erase that splits the region, this tracks the largest resulting piece. */
|
|
43
|
-
this.strokeRegionId = null;
|
|
44
|
-
/** Readback ratio/origin signature the active stroke is tied to; a change (zoom/pan) invalidates
|
|
45
|
-
* it so it isn't re-committed at a different scale (jit-ui#102). */
|
|
46
|
-
this.strokeRatioSig = null;
|
|
47
|
-
/** Ids of the extra regions produced when an erase stroke splits a region
|
|
48
|
-
* into disconnected pieces — reused across drag ticks so the split pieces
|
|
49
|
-
* keep stable identities instead of being recreated each tick. */
|
|
50
|
-
this.strokeExtraIds = [];
|
|
38
|
+
this.editor = new MaskStrokeEditor();
|
|
51
39
|
/** Previous cursor position (matrix coords) within the current drag, so fast
|
|
52
40
|
* drags paint a continuous stroke rather than disconnected dabs. */
|
|
53
41
|
this.lastMatrix = null;
|
|
@@ -55,31 +43,25 @@ export class BrushToolService {
|
|
|
55
43
|
this.size = DEFAULT_BRUSH_SIZE;
|
|
56
44
|
/** The class being painted ({@link BrushOptions.label} / `color`); null = plain brush. */
|
|
57
45
|
this.paintClass = null;
|
|
58
|
-
this.
|
|
59
|
-
this.boundMouseMove = (e) => this.onMouseMove(e);
|
|
60
|
-
this.boundMouseUp = (e) => this.onMouseUp(e);
|
|
46
|
+
this.gesture = new UndoGesture(gestureTarget);
|
|
61
47
|
}
|
|
62
|
-
|
|
63
|
-
|
|
48
|
+
// ── ICanvasTool ─────────────────────────────────────────────────────
|
|
49
|
+
/** Arm the brush on `host`. Arming sets the class in full: no label/color
|
|
50
|
+
* means the plain brush; a missing size keeps the previous one. */
|
|
51
|
+
activate(host, options = {}) {
|
|
64
52
|
this.host = host;
|
|
53
|
+
this.setOptions({ label: undefined, color: undefined, ...options });
|
|
54
|
+
this.createOverlay();
|
|
65
55
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
this.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
// Arming sets the class in full: no label/color means the plain brush.
|
|
76
|
-
this.setOptions({ label: undefined, color: undefined, ...options });
|
|
77
|
-
this.createOverlay();
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
this.destroyOverlay();
|
|
81
|
-
this.paintClass = null;
|
|
82
|
-
}
|
|
56
|
+
/** Disarm: remove the overlay, drop the active region and the class. */
|
|
57
|
+
deactivate() {
|
|
58
|
+
this.overlay.detach();
|
|
59
|
+
this.resetStroke();
|
|
60
|
+
this.paintClass = null;
|
|
61
|
+
}
|
|
62
|
+
/** Drop the active brush region so the next stroke starts a new one. */
|
|
63
|
+
reset() {
|
|
64
|
+
this.resetStroke();
|
|
83
65
|
}
|
|
84
66
|
/**
|
|
85
67
|
* Update size and/or class while armed. The class changes only when `label`
|
|
@@ -92,9 +74,7 @@ export class BrushToolService {
|
|
|
92
74
|
this.setSize(options.size);
|
|
93
75
|
if (!('label' in options) && !('color' in options))
|
|
94
76
|
return;
|
|
95
|
-
const next = options.label != null || options.color != null
|
|
96
|
-
? { label: options.label, color: options.color }
|
|
97
|
-
: null;
|
|
77
|
+
const next = options.label != null || options.color != null ? { label: options.label, color: options.color } : null;
|
|
98
78
|
if (next?.label !== this.paintClass?.label || next?.color !== this.paintClass?.color) {
|
|
99
79
|
this.resetStroke();
|
|
100
80
|
}
|
|
@@ -106,71 +86,45 @@ export class BrushToolService {
|
|
|
106
86
|
return;
|
|
107
87
|
this.size = size;
|
|
108
88
|
}
|
|
109
|
-
/** Drop the active brush region so the next stroke starts a new one. */
|
|
110
|
-
clearActiveRegion() {
|
|
111
|
-
this.resetStroke();
|
|
112
|
-
}
|
|
113
89
|
// ── Overlay lifecycle ───────────────────────────────────────────────
|
|
114
90
|
createOverlay() {
|
|
115
|
-
const
|
|
116
|
-
if (!
|
|
91
|
+
const container = this.host.getOverlayContainer();
|
|
92
|
+
if (!container)
|
|
117
93
|
return;
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
canvas.style.height = '100%';
|
|
124
|
-
canvas.style.cursor = 'crosshair';
|
|
125
|
-
canvas.style.zIndex = '100';
|
|
126
|
-
canvas.width = plotEl.offsetWidth;
|
|
127
|
-
canvas.height = plotEl.offsetHeight;
|
|
128
|
-
plotEl.appendChild(canvas);
|
|
129
|
-
this.overlay = canvas;
|
|
130
|
-
canvas.addEventListener('mousedown', this.boundMouseDown);
|
|
131
|
-
canvas.addEventListener('mousemove', this.boundMouseMove);
|
|
132
|
-
canvas.addEventListener('mouseup', this.boundMouseUp);
|
|
133
|
-
canvas.addEventListener('mouseleave', this.boundMouseUp);
|
|
94
|
+
this.overlay.attach(container, {
|
|
95
|
+
down: (e) => this.onPointerDown(e),
|
|
96
|
+
move: (e) => this.onPointerMove(e),
|
|
97
|
+
up: () => this.onPointerUp(),
|
|
98
|
+
});
|
|
134
99
|
}
|
|
135
|
-
|
|
136
|
-
if (!this.overlay)
|
|
137
|
-
return;
|
|
138
|
-
this.overlay.removeEventListener('mousedown', this.boundMouseDown);
|
|
139
|
-
this.overlay.removeEventListener('mousemove', this.boundMouseMove);
|
|
140
|
-
this.overlay.removeEventListener('mouseup', this.boundMouseUp);
|
|
141
|
-
this.overlay.removeEventListener('mouseleave', this.boundMouseUp);
|
|
142
|
-
this.overlay.remove();
|
|
143
|
-
this.overlay = null;
|
|
144
|
-
this.resetStroke();
|
|
145
|
-
}
|
|
146
|
-
onMouseDown(e) {
|
|
147
|
-
if (e.button !== 0)
|
|
148
|
-
return;
|
|
100
|
+
onPointerDown(e) {
|
|
149
101
|
this.dragging = true;
|
|
102
|
+
this.gesture.begin();
|
|
150
103
|
this.lastMatrix = null; // first stamp of this drag is a single dab
|
|
151
104
|
this.applyAtClient(e, true);
|
|
152
105
|
}
|
|
153
|
-
|
|
106
|
+
onPointerMove(e) {
|
|
154
107
|
if (!this.dragging)
|
|
155
108
|
return;
|
|
156
109
|
if ((e.buttons & 1) === 0) {
|
|
157
110
|
this.dragging = false;
|
|
111
|
+
this.gesture.end();
|
|
158
112
|
return;
|
|
159
113
|
}
|
|
160
114
|
this.applyAtClient(e, false);
|
|
161
115
|
}
|
|
162
|
-
|
|
116
|
+
onPointerUp() {
|
|
163
117
|
// Stop accumulating from this drag, but keep the region alive so the next
|
|
164
118
|
// mousedown extends it. Clear lastMatrix so the next drag starts a dab.
|
|
165
119
|
this.dragging = false;
|
|
120
|
+
this.gesture.end();
|
|
166
121
|
this.lastMatrix = null;
|
|
167
122
|
}
|
|
168
123
|
resetStroke() {
|
|
169
|
-
this.
|
|
170
|
-
this.strokeRegionId = null;
|
|
171
|
-
this.strokeExtraIds = [];
|
|
124
|
+
this.editor.reset();
|
|
172
125
|
this.lastMatrix = null;
|
|
173
126
|
this.dragging = false;
|
|
127
|
+
this.gesture.end();
|
|
174
128
|
}
|
|
175
129
|
// ── Per-tick stroke logic ───────────────────────────────────────────
|
|
176
130
|
/**
|
|
@@ -179,52 +133,27 @@ export class BrushToolService {
|
|
|
179
133
|
* and commit the updated Region. Shift = erase.
|
|
180
134
|
*/
|
|
181
135
|
applyAtClient(e, isStart) {
|
|
182
|
-
if (!this.overlay)
|
|
183
|
-
return;
|
|
184
|
-
const cached = this.host.getCachedImageData();
|
|
185
|
-
if (!cached || cached.frames.length === 0)
|
|
186
|
-
return;
|
|
187
|
-
const regions = this.host.getRegions();
|
|
188
|
-
const transform = this.host.getCoordinateTransform();
|
|
189
|
-
if (!transform.isReady())
|
|
136
|
+
if (!this.overlay.attached)
|
|
190
137
|
return;
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
// Heatmap/image traces use ratios[0] for both dx and dy.
|
|
195
|
-
const rx = cached.ratios[0] || 1;
|
|
196
|
-
const ry = cached.ratios[0] || 1;
|
|
197
|
-
const ox = cached.originX ?? 0;
|
|
198
|
-
const oy = cached.originY ?? 0;
|
|
199
|
-
// Drop a stroke built at a different view (zoom/pan): its matrix coords are tied to the old
|
|
200
|
-
// ratio/origin, and re-committing would rescale the region by the zoom factor (jit-ui#102).
|
|
201
|
-
const sig = `${rx},${ry},${ox},${oy}`;
|
|
202
|
-
if (this.stroke && this.strokeRatioSig !== sig) {
|
|
203
|
-
this.stroke = null;
|
|
204
|
-
this.strokeRegionId = null;
|
|
205
|
-
}
|
|
206
|
-
this.strokeRatioSig = sig;
|
|
207
|
-
const matrixX = (dataX - ox) / rx;
|
|
208
|
-
const matrixY = (dataY - oy) / ry;
|
|
209
|
-
if (matrixX < 0 || matrixX >= cached.width)
|
|
210
|
-
return;
|
|
211
|
-
if (matrixY < 0 || matrixY >= cached.height)
|
|
138
|
+
const editor = this.editor;
|
|
139
|
+
const tick = editor.beginTick(this.host, e);
|
|
140
|
+
if (!tick)
|
|
212
141
|
return;
|
|
142
|
+
const { cached, regions, frame, mx: matrixX, my: matrixY } = tick;
|
|
213
143
|
const erase = e.shiftKey;
|
|
214
144
|
const radius = Math.max(0.5, this.size / 2);
|
|
215
145
|
// Start of a fresh drag that isn't inside the current accumulator: drop the
|
|
216
146
|
// old stroke so a brand-new region starts here (mirrors the wand).
|
|
217
|
-
if (isStart && !erase &&
|
|
218
|
-
|
|
219
|
-
this.strokeRegionId = null;
|
|
147
|
+
if (isStart && !erase && editor.stroke && !editor.contains(matrixX, matrixY)) {
|
|
148
|
+
editor.reset();
|
|
220
149
|
}
|
|
221
150
|
// If there's no active region, adopt an existing shape under the cursor so
|
|
222
151
|
// the stroke extends (or erases from) it instead of creating a new region.
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
152
|
+
const accept = (r) => this.paintsInto(r);
|
|
153
|
+
if (!editor.stroke)
|
|
154
|
+
editor.adoptAt(regions, matrixX, matrixY, frame, cached, accept);
|
|
226
155
|
// Erasing requires an existing region — shift on empty space is a no-op.
|
|
227
|
-
if (erase && !
|
|
156
|
+
if (erase && !editor.stroke) {
|
|
228
157
|
this.lastMatrix = { x: matrixX, y: matrixY };
|
|
229
158
|
return;
|
|
230
159
|
}
|
|
@@ -244,34 +173,38 @@ export class BrushToolService {
|
|
|
244
173
|
}
|
|
245
174
|
}
|
|
246
175
|
this.lastMatrix = { x: matrixX, y: matrixY };
|
|
247
|
-
if (!
|
|
248
|
-
return;
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
//
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
176
|
+
if (!editor.stroke)
|
|
177
|
+
return;
|
|
178
|
+
// Growing into another shape folds it into this stroke (merge-on-touch).
|
|
179
|
+
if (!erase)
|
|
180
|
+
editor.mergeTouching(regions, frame, cached, accept);
|
|
181
|
+
// Every connected piece is committed: an erase that cuts through the region
|
|
182
|
+
// splits it in two and both survive (the larger keeps the region identity),
|
|
183
|
+
// and enclosed unpainted areas stay holes (jit-ui#85).
|
|
184
|
+
const paint = this.paintClass;
|
|
185
|
+
editor.commit(regions, frame, this.host, {
|
|
186
|
+
erase,
|
|
187
|
+
defaultLabel: paint?.label ?? 'Region',
|
|
188
|
+
// An explicit class colour must survive a preset (re)apply, like a colour
|
|
189
|
+
// picked in the region editor (jit-ui#70).
|
|
190
|
+
editPatch: paint?.color != null ? { color: paint.color, colorOverridden: true } : undefined,
|
|
191
|
+
newRegion: (bounds) => {
|
|
192
|
+
const region = new Region();
|
|
193
|
+
region.bounds = bounds;
|
|
194
|
+
region.color = paint?.color ?? this.host.getShapeColor();
|
|
195
|
+
if (paint?.color != null)
|
|
196
|
+
region.colorOverridden = true;
|
|
197
|
+
// Default class/annotation name, matching the overlay-drawn regions and the
|
|
198
|
+
// wand so a brush region isn't left unlabeled.
|
|
199
|
+
region.label = paint?.label ?? 'Region';
|
|
200
|
+
return region;
|
|
201
|
+
},
|
|
202
|
+
});
|
|
271
203
|
}
|
|
272
204
|
/**
|
|
273
205
|
* OR (add) or AND-NOT (erase) a filled disc of `radius` matrix-pixels centred
|
|
274
|
-
* at (cx, cy) into the accumulator, growing its bbox to
|
|
206
|
+
* at (cx, cy) into the accumulator, growing its bbox (clipped to the
|
|
207
|
+
* readback) to fit when adding.
|
|
275
208
|
*/
|
|
276
209
|
stampDisc(cx, cy, radius, erase, cached) {
|
|
277
210
|
const px0 = Math.floor(cx - radius);
|
|
@@ -279,10 +212,11 @@ export class BrushToolService {
|
|
|
279
212
|
const px1 = Math.ceil(cx + radius) + 1;
|
|
280
213
|
const py1 = Math.ceil(cy + radius) + 1;
|
|
281
214
|
if (!erase) {
|
|
282
|
-
|
|
215
|
+
const ok = this.editor.ensureCovers(Math.max(0, px0), Math.max(0, py0), Math.min(cached.width, px1), Math.min(cached.height, py1));
|
|
216
|
+
if (!ok)
|
|
283
217
|
return;
|
|
284
218
|
}
|
|
285
|
-
const s = this.stroke;
|
|
219
|
+
const s = this.editor.stroke;
|
|
286
220
|
if (!s)
|
|
287
221
|
return; // erasing with no active region
|
|
288
222
|
const r2 = radius * radius;
|
|
@@ -301,287 +235,11 @@ export class BrushToolService {
|
|
|
301
235
|
}
|
|
302
236
|
}
|
|
303
237
|
}
|
|
304
|
-
/**
|
|
305
|
-
* Ensure the accumulator's bbox covers [px0,py0,px1,py1) (clamped to the
|
|
306
|
-
* image), allocating/copying a larger mask when it must grow. Returns false if
|
|
307
|
-
* the requested box is empty after clamping.
|
|
308
|
-
*/
|
|
309
|
-
ensureStrokeCovers(px0, py0, px1, py1, cached) {
|
|
310
|
-
const bx = Math.max(0, px0);
|
|
311
|
-
const by = Math.max(0, py0);
|
|
312
|
-
const bx1 = Math.min(cached.width, px1);
|
|
313
|
-
const by1 = Math.min(cached.height, py1);
|
|
314
|
-
const bw = bx1 - bx;
|
|
315
|
-
const bh = by1 - by;
|
|
316
|
-
if (bw <= 0 || bh <= 0)
|
|
317
|
-
return false;
|
|
318
|
-
if (!this.stroke) {
|
|
319
|
-
this.stroke = { bx, by, bw, bh, mask: new Uint8Array(bw * bh) };
|
|
320
|
-
return true;
|
|
321
|
-
}
|
|
322
|
-
const s = this.stroke;
|
|
323
|
-
const nbx = Math.min(s.bx, bx);
|
|
324
|
-
const nby = Math.min(s.by, by);
|
|
325
|
-
const nbx1 = Math.max(s.bx + s.bw, bx1);
|
|
326
|
-
const nby1 = Math.max(s.by + s.bh, by1);
|
|
327
|
-
const nbw = nbx1 - nbx;
|
|
328
|
-
const nbh = nby1 - nby;
|
|
329
|
-
if (nbw === s.bw && nbh === s.bh && nbx === s.bx && nby === s.by)
|
|
330
|
-
return true;
|
|
331
|
-
const next = new Uint8Array(nbw * nbh);
|
|
332
|
-
const dx = s.bx - nbx;
|
|
333
|
-
const dy = s.by - nby;
|
|
334
|
-
for (let row = 0; row < s.bh; row++) {
|
|
335
|
-
const srcOff = row * s.bw;
|
|
336
|
-
const dstOff = (row + dy) * nbw + dx;
|
|
337
|
-
next.set(s.mask.subarray(srcOff, srcOff + s.bw), dstOff);
|
|
338
|
-
}
|
|
339
|
-
this.stroke = { bx: nbx, by: nby, bw: nbw, bh: nbh, mask: next };
|
|
340
|
-
return true;
|
|
341
|
-
}
|
|
342
|
-
/** True if (matrixX, matrixY) lies inside the current stroke accumulator. */
|
|
343
|
-
pointInStroke(matrixX, matrixY) {
|
|
344
|
-
const s = this.stroke;
|
|
345
|
-
if (!s)
|
|
346
|
-
return false;
|
|
347
|
-
const mx = Math.floor(matrixX) - s.bx;
|
|
348
|
-
const my = Math.floor(matrixY) - s.by;
|
|
349
|
-
if (mx < 0 || my < 0 || mx >= s.bw || my >= s.bh)
|
|
350
|
-
return false;
|
|
351
|
-
return s.mask[my * s.bw + mx] === 1;
|
|
352
|
-
}
|
|
353
|
-
/**
|
|
354
|
-
* Remove the region(s) referenced by the stroke and reset it — used when an
|
|
355
|
-
* erase stroke deletes every pixel.
|
|
356
|
-
*/
|
|
357
|
-
dropActiveShape(regions) {
|
|
358
|
-
const ids = [this.strokeRegionId, ...this.strokeExtraIds].filter((id) => id != null);
|
|
359
|
-
let changed = false;
|
|
360
|
-
for (const id of ids) {
|
|
361
|
-
const idx = regions.findIndex((r) => r.id === id);
|
|
362
|
-
if (idx >= 0) {
|
|
363
|
-
regions.splice(idx, 1);
|
|
364
|
-
changed = true;
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
if (changed)
|
|
368
|
-
this.host.setRegions(regions);
|
|
369
|
-
this.stroke = null;
|
|
370
|
-
this.strokeRegionId = null;
|
|
371
|
-
this.strokeExtraIds = [];
|
|
372
|
-
}
|
|
373
238
|
/** Whether the stroke may adopt or merge `region`: always for the plain brush,
|
|
374
239
|
* otherwise only a region of the class being painted. */
|
|
375
240
|
paintsInto(region) {
|
|
376
241
|
const label = this.paintClass?.label;
|
|
377
242
|
return label == null || region?.label === label;
|
|
378
243
|
}
|
|
379
|
-
/** A region's closed-polygon vertices (image/data coords), or null when it
|
|
380
|
-
* isn't a fillable closed polygon (rectangles, open polylines). */
|
|
381
|
-
regionVerts(region) {
|
|
382
|
-
const b = region?.bounds;
|
|
383
|
-
if (b instanceof Polygon && b.closed !== false && b.xpoints.length >= 3) {
|
|
384
|
-
return { xpoints: b.xpoints, ypoints: b.ypoints, holes: b.holes };
|
|
385
|
-
}
|
|
386
|
-
return null;
|
|
387
|
-
}
|
|
388
|
-
/** Whether a region can be faithfully rasterized at this zoom (rx/ry = data units per matrix px).
|
|
389
|
-
* Editing rasterizes + re-traces the region, so one whose matrix-space bbox exceeds the
|
|
390
|
-
* rasterizer cap would come back rescaled/corrupted (e.g. a whole-slide annotation while zoomed
|
|
391
|
-
* out) — skip adopt/merge for those and only edit them near native zoom (jit-ui#102). */
|
|
392
|
-
fitsForEdit(verts, rx, ry) {
|
|
393
|
-
const xs = verts.xpoints;
|
|
394
|
-
const ys = verts.ypoints;
|
|
395
|
-
let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
|
|
396
|
-
for (let i = 0; i < xs.length; i++) {
|
|
397
|
-
if (xs[i] < minX)
|
|
398
|
-
minX = xs[i];
|
|
399
|
-
if (xs[i] > maxX)
|
|
400
|
-
maxX = xs[i];
|
|
401
|
-
if (ys[i] < minY)
|
|
402
|
-
minY = ys[i];
|
|
403
|
-
if (ys[i] > maxY)
|
|
404
|
-
maxY = ys[i];
|
|
405
|
-
}
|
|
406
|
-
const w = (maxX - minX) / (rx || 1);
|
|
407
|
-
const h = (maxY - minY) / (ry || 1);
|
|
408
|
-
return w > 0 && h > 0 && w * h <= 4096 * 4096;
|
|
409
|
-
}
|
|
410
|
-
/** Convert a region's hole rings from image/data coords into matrix coords so
|
|
411
|
-
* they line up with the stroke accumulator (jit-ui#85). */
|
|
412
|
-
holesToMatrix(holes, ox, oy, rx, ry) {
|
|
413
|
-
return holes?.map((ring) => ring.map(([x, y]) => [(x - ox) / rx, (y - oy) / ry]));
|
|
414
|
-
}
|
|
415
|
-
/**
|
|
416
|
-
* If (matrixX, matrixY) falls inside an existing region, rasterize it into the
|
|
417
|
-
* stroke accumulator so subsequent brush input extends it rather than starting
|
|
418
|
-
* a new region.
|
|
419
|
-
*/
|
|
420
|
-
tryAdoptShapeAt(regions, matrixX, matrixY, rx, ry, cached) {
|
|
421
|
-
if (!regions || regions.length === 0)
|
|
422
|
-
return false;
|
|
423
|
-
// Most-recently-added regions are on top — check them first.
|
|
424
|
-
for (let i = regions.length - 1; i >= 0; i--) {
|
|
425
|
-
if (!this.paintsInto(regions[i]))
|
|
426
|
-
continue; // another class's region
|
|
427
|
-
const verts = this.regionVerts(regions[i]);
|
|
428
|
-
if (!verts)
|
|
429
|
-
continue;
|
|
430
|
-
if (!this.fitsForEdit(verts, rx, ry))
|
|
431
|
-
continue; // too large at this zoom → don't adopt
|
|
432
|
-
const ox = cached.originX ?? 0;
|
|
433
|
-
const oy = cached.originY ?? 0;
|
|
434
|
-
const xs = verts.xpoints.map((x) => (x - ox) / rx);
|
|
435
|
-
const ys = verts.ypoints.map((y) => (y - oy) / ry);
|
|
436
|
-
const holes = this.holesToMatrix(verts.holes, ox, oy, rx, ry);
|
|
437
|
-
// Clicking inside a hole must NOT adopt the donut (it's empty there).
|
|
438
|
-
if (!this.wandService.pointInPolygonWithHoles(matrixX, matrixY, xs, ys, holes))
|
|
439
|
-
continue;
|
|
440
|
-
const raster = this.wandService.rasterizePolygon(xs, ys, cached.width, cached.height, holes);
|
|
441
|
-
if (!raster)
|
|
442
|
-
continue;
|
|
443
|
-
this.stroke = raster;
|
|
444
|
-
this.strokeRegionId = regions[i].id ?? null;
|
|
445
|
-
return true;
|
|
446
|
-
}
|
|
447
|
-
return false;
|
|
448
|
-
}
|
|
449
|
-
/**
|
|
450
|
-
* Fold every region whose rasterized mask overlaps the stroke mask into the
|
|
451
|
-
* stroke and remove it from the list, so brushing across regions merges them.
|
|
452
|
-
*/
|
|
453
|
-
mergeOverlappingShapes(regions, rx, ry, cached) {
|
|
454
|
-
if (!this.stroke)
|
|
455
|
-
return;
|
|
456
|
-
let didMerge = true;
|
|
457
|
-
while (didMerge) {
|
|
458
|
-
didMerge = false;
|
|
459
|
-
for (let i = regions.length - 1; i >= 0; i--) {
|
|
460
|
-
const region = regions[i];
|
|
461
|
-
if (region.id != null && region.id === this.strokeRegionId)
|
|
462
|
-
continue;
|
|
463
|
-
if (!this.paintsInto(region))
|
|
464
|
-
continue; // never fold another class in
|
|
465
|
-
const verts = this.regionVerts(region);
|
|
466
|
-
if (!verts)
|
|
467
|
-
continue;
|
|
468
|
-
if (!this.fitsForEdit(verts, rx, ry))
|
|
469
|
-
continue; // too large at this zoom → don't merge
|
|
470
|
-
const ox = cached.originX ?? 0;
|
|
471
|
-
const oy = cached.originY ?? 0;
|
|
472
|
-
const xs = verts.xpoints.map((x) => (x - ox) / rx);
|
|
473
|
-
const ys = verts.ypoints.map((y) => (y - oy) / ry);
|
|
474
|
-
// Quick bbox reject before rasterizing.
|
|
475
|
-
let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
|
|
476
|
-
for (let k = 0; k < xs.length; k++) {
|
|
477
|
-
if (xs[k] < minX)
|
|
478
|
-
minX = xs[k];
|
|
479
|
-
if (xs[k] > maxX)
|
|
480
|
-
maxX = xs[k];
|
|
481
|
-
if (ys[k] < minY)
|
|
482
|
-
minY = ys[k];
|
|
483
|
-
if (ys[k] > maxY)
|
|
484
|
-
maxY = ys[k];
|
|
485
|
-
}
|
|
486
|
-
const wx0 = this.stroke.bx, wy0 = this.stroke.by;
|
|
487
|
-
const wx1 = wx0 + this.stroke.bw, wy1 = wy0 + this.stroke.bh;
|
|
488
|
-
if (maxX < wx0 || minX > wx1 || maxY < wy0 || minY > wy1)
|
|
489
|
-
continue;
|
|
490
|
-
const holes = this.holesToMatrix(verts.holes, ox, oy, rx, ry);
|
|
491
|
-
const raster = this.wandService.rasterizePolygon(xs, ys, cached.width, cached.height, holes);
|
|
492
|
-
if (!raster)
|
|
493
|
-
continue;
|
|
494
|
-
if (!masksOverlap(this.stroke, raster))
|
|
495
|
-
continue;
|
|
496
|
-
this.stroke = unionMasks(this.stroke, raster);
|
|
497
|
-
if (this.strokeRegionId == null) {
|
|
498
|
-
this.strokeRegionId = region.id ?? null;
|
|
499
|
-
}
|
|
500
|
-
regions.splice(i, 1);
|
|
501
|
-
didMerge = true;
|
|
502
|
-
break;
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
/**
|
|
507
|
-
* Commit the stroke's connected pieces as regions — the largest keeps the
|
|
508
|
-
* stroke's region identity, additional pieces (from an erase that split the
|
|
509
|
-
* region) become their own regions tracked in `strokeExtraIds` so they keep
|
|
510
|
-
* stable identities across drag ticks. The store mints ids on commit, which
|
|
511
|
-
* we read back so subsequent ticks replace the same regions.
|
|
512
|
-
*/
|
|
513
|
-
commitComponents(regions, components) {
|
|
514
|
-
const valid = components.filter((c) => c.xPlot.length >= 3);
|
|
515
|
-
if (valid.length === 0)
|
|
516
|
-
return;
|
|
517
|
-
const prevExtraIds = this.strokeExtraIds;
|
|
518
|
-
// Drop previously-tracked extras that no longer have a matching piece (the
|
|
519
|
-
// component count shrank, e.g. an add stroke bridged a gap).
|
|
520
|
-
const reuseCount = Math.max(0, valid.length - 1);
|
|
521
|
-
for (let k = reuseCount; k < prevExtraIds.length; k++) {
|
|
522
|
-
const idx = regions.findIndex((r) => r.id === prevExtraIds[k]);
|
|
523
|
-
if (idx >= 0)
|
|
524
|
-
regions.splice(idx, 1);
|
|
525
|
-
}
|
|
526
|
-
const primary = this.upsertComponent(regions, this.strokeRegionId, valid[0]);
|
|
527
|
-
const extras = [];
|
|
528
|
-
for (let i = 1; i < valid.length; i++) {
|
|
529
|
-
extras.push(this.upsertComponent(regions, prevExtraIds[i - 1] ?? null, valid[i]));
|
|
530
|
-
}
|
|
531
|
-
this.host.setRegions(regions);
|
|
532
|
-
// Ids are minted during setRegions — read them back for the next tick.
|
|
533
|
-
this.strokeRegionId = primary.id ?? this.strokeRegionId;
|
|
534
|
-
this.strokeExtraIds = extras
|
|
535
|
-
.map((r) => r.id)
|
|
536
|
-
.filter((id) => id != null);
|
|
537
|
-
}
|
|
538
|
-
/**
|
|
539
|
-
* Build a Region for one component and insert it into `regions`: replace the
|
|
540
|
-
* region with `id` in place if it exists, otherwise append a new one. Returns
|
|
541
|
-
* the Region instance (its id is minted later by the store when new).
|
|
542
|
-
*/
|
|
543
|
-
upsertComponent(regions, id, c) {
|
|
544
|
-
const existing = id != null ? regions.find((r) => r.id === id) : null;
|
|
545
|
-
const poly = new Polygon();
|
|
546
|
-
poly.npoints = c.xPlot.length;
|
|
547
|
-
poly.xpoints = c.xPlot;
|
|
548
|
-
poly.ypoints = c.yPlot;
|
|
549
|
-
poly.coordinates = c.xPlot.map((x, i) => [x, c.yPlot[i]]);
|
|
550
|
-
poly.closed = true;
|
|
551
|
-
if (c.holes && c.holes.length)
|
|
552
|
-
poly.holes = c.holes;
|
|
553
|
-
const region = new Region();
|
|
554
|
-
region.bounds = poly;
|
|
555
|
-
const paint = this.paintClass;
|
|
556
|
-
region.color = paint?.color ?? this.host.getShapeColor();
|
|
557
|
-
// An explicit class colour must survive a preset (re)apply, like a colour
|
|
558
|
-
// picked in the region editor (jit-ui#70).
|
|
559
|
-
if (paint?.color != null)
|
|
560
|
-
region.colorOverridden = true;
|
|
561
|
-
if (existing) {
|
|
562
|
-
region.id = existing.id;
|
|
563
|
-
region.name = existing.name;
|
|
564
|
-
}
|
|
565
|
-
// Default class/annotation name, matching the overlay-drawn regions and the
|
|
566
|
-
// wand so a brush region isn't left unlabeled.
|
|
567
|
-
region.label = existing?.label ?? paint?.label ?? 'Region';
|
|
568
|
-
if (existing) {
|
|
569
|
-
const idx = regions.findIndex((r) => r.id === id);
|
|
570
|
-
if (idx >= 0)
|
|
571
|
-
regions[idx] = region;
|
|
572
|
-
else
|
|
573
|
-
regions.push(region);
|
|
574
|
-
}
|
|
575
|
-
else {
|
|
576
|
-
regions.push(region);
|
|
577
|
-
}
|
|
578
|
-
return region;
|
|
579
|
-
}
|
|
580
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: BrushToolService, deps: [{ token: i1.WandService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
581
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: BrushToolService, providedIn: 'root' }); }
|
|
582
244
|
}
|
|
583
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: BrushToolService, decorators: [{
|
|
584
|
-
type: Injectable,
|
|
585
|
-
args: [{ providedIn: 'root' }]
|
|
586
|
-
}], ctorParameters: () => [{ type: i1.WandService }] });
|
|
587
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJ1c2gtdG9vbC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi90b29sYmFyL2JydXNoL2JydXNoLXRvb2wuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTNDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUVuRCxPQUFPLEVBQVksWUFBWSxFQUFFLFVBQVUsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzNFLE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7OztBQWdCdEQsa0VBQWtFO0FBQ2xFLE1BQU0sa0JBQWtCLEdBQUcsRUFBRSxDQUFDO0FBVzlCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9CRztBQUVILE1BQU0sT0FBTyxnQkFBZ0I7SUFpQzNCLFlBQW9CLFdBQXdCO1FBQXhCLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBL0JwQyxZQUFPLEdBQTZCLElBQUksQ0FBQztRQUN6QyxXQUFNLEdBQUcsS0FBSyxDQUFDO1FBRXZCOzs7O1dBSUc7UUFDSyxXQUFNLEdBQW9CLElBQUksQ0FBQztRQUN2QztxRkFDNkU7UUFDckUsbUJBQWMsR0FBa0IsSUFBSSxDQUFDO1FBQzdDOzZFQUNxRTtRQUM3RCxtQkFBYyxHQUFrQixJQUFJLENBQUM7UUFDN0M7OzJFQUVtRTtRQUMzRCxtQkFBYyxHQUFhLEVBQUUsQ0FBQztRQUN0Qzs2RUFDcUU7UUFDN0QsZUFBVSxHQUFvQyxJQUFJLENBQUM7UUFDbkQsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUNqQixTQUFJLEdBQUcsa0JBQWtCLENBQUM7UUFDbEMsMEZBQTBGO1FBQ2xGLGVBQVUsR0FBOEMsSUFBSSxDQUFDO1FBT25FLElBQUksQ0FBQyxjQUFjLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUks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VSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztRQUN2QyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQztRQUN0QixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQztRQUN0QixLQUFLLElBQUksR0FBRyxHQUFHLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDO1lBQ3BDLE1BQU0sTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQzFCLE1BQU0sTUFBTSxHQUFHLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEdBQUcsR0FBRyxFQUFFLENBQUM7WUFDckMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsTUFBTSxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUMzRCxDQUFDO1FBQ0QsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDO1FBQ2pFLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELDZFQUE2RTtJQUNyRSxhQUFhLENBQUMsT0FBZSxFQUFFLE9BQWU7UUFDcEQsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUN0QixJQUFJLENBQUMsQ0FBQztZQUFFLE9BQU8sS0FBSyxDQUFDO1FBQ3JCLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUN0QyxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDdEMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFO1lBQUUsT0FBTyxLQUFLLENBQUM7UUFDL0QsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN0QyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssZUFBZSxDQUFDLE9BQWlCO1FBQ3ZDLE1BQU0sR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLEVBQWdCLEVBQUUsQ0FBQyxFQUFFLElBQUksSUFBSSxDQUFDLENBQUM7UUFDbkcsSUFBSSxPQUFPLEdBQUcsS0FBSyxDQUFDO1FBQ3BCLEtBQUssTUFBTSxFQUFFLElBQUksR0FBRyxFQUFFLENBQUM7WUFDckIsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUNsRCxJQUFJLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO1lBQUMsQ0FBQztRQUMzRCxDQUFDO1FBQ0QsSUFBSSxPQUFPO1lBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDM0MsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7UUFDbkIsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7UUFDM0IsSUFBSSxDQUFDLGNBQWMsR0FBRyxFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVE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RCw0RUFBNEU7UUFDNUUsK0NBQStDO1FBQy9DLE1BQU0sQ0FBQyxLQUFLLEdBQUcsUUFBUSxFQUFFLEtBQUssSUFBSSxLQUFLLEVBQUUsS0FBSyxJQUFJLFFBQVEsQ0FBQztRQUUzRCxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQ2IsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUNsRCxJQUFJLEdBQUcsSUFBSSxDQUFDO2dCQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUM7O2dCQUMvQixPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzVCLENBQUM7YUFBTSxDQUFDO1lBQ04sT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN2QixDQUFDO1FBQ0QsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQzs4R0Fua0JVLGdCQUFnQjtrSEFBaEIsZ0JBQWdCLGNBREgsTUFBTTs7MkZBQ25CLGdCQUFnQjtrQkFENUIsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IFdhbmRTZXJ2aWNlIH0gZnJvbSAnLi4vd2FuZC93YW5kLnNlcnZpY2UnO1xuaW1wb3J0IHsgQ2FjaGVkSW1hZ2VEYXRhLCBXYW5kVG9vbEhvc3QgfSBmcm9tICcuLi93YW5kL3dhbmQtdG9vbC5zZXJ2aWNlJztcbmltcG9ydCB7IEJCb3hNYXNrLCBtYXNrc092ZXJsYXAsIHVuaW9uTWFza3MgfSBmcm9tICcuLi8uLi9tb2RlbHMvZ2VvbWV0cnknO1xuaW1wb3J0IHsgUmVnaW9uLCBQb2x5Z29uIH0gZnJvbSAnLi4vLi4vbW9kZWxzL3JlZ2lvbic7XG5cbi8qKiBCcnVzaCBwYXJhbWV0ZXJzLiBgc2l6ZWAgaXMgdGhlIGJydXNoICpkaWFtZXRlciogaW4gbWF0cml4IChpbWFnZSkgcGl4ZWxzLiAqL1xuZXhwb3J0IGludGVyZmFjZSBCcnVzaE9wdGlvbnMge1xuICBzaXplPzogbnVtYmVyO1xuICAvKipcbiAgICogUGFpbnQgYXMgb25lIGNsYXNzLiBXaXRoIGBsYWJlbGAgc2V0LCBuZXcgcmVnaW9ucyB0YWtlIHRoaXMgbGFiZWwsIGFuZCB0aGVcbiAgICogc3Ryb2tlIG9ubHkgYWRvcHRzIG9yIG1lcmdlcyByZWdpb25zIHRoYXQgYWxyZWFkeSBoYXZlIGl0LCBzbyBwYWludGluZyBvbmVcbiAgICogY2xhc3MgbmV2ZXIgZ3Jvd3MgYW5vdGhlciBjbGFzcydzIHJlZ2lvbi4gYGNvbG9yYCBjb2xvdXJzIHRoZSBwYWludGVkXG4gICAqIHJlZ2lvbnMgaW5zdGVhZCBvZiB0aGUgdG9vbGJhcidzIHNoYXBlIGNvbG91ci4gTGVhdmUgYm90aCB1bnNldCBmb3IgdGhlXG4gICAqIHBsYWluIHRvb2xiYXIgYnJ1c2guXG4gICAqL1xuICBsYWJlbD86IHN0cmluZztcbiAgY29sb3I/OiBzdHJpbmc7XG59XG5cbi8qKiBEZWZhdWx0IGJydXNoIGRpYW1ldGVyIChtYXRyaXggcGl4ZWxzKSBpZiBub25lIGlzIHN1cHBsaWVkLiAqL1xuY29uc3QgREVGQVVMVF9CUlVTSF9TSVpFID0gNDA7XG5cbi8qKlxuICogVGhlIGJydXNoIGhvc3QgaXMgaWRlbnRpY2FsIHRvIHRoZSB3YW5kJ3Mg4oCUIGJvdGggbmVlZCB0aGUgY2FjaGVkLWltYWdlXG4gKiBjb29yZGluYXRlIGZyYW1lLCB0aGUgb3ZlcmxheSBjb250YWluZXIsIHRoZSBjb29yZGluYXRlIHRyYW5zZm9ybSwgYW5kXG4gKiByZWFkL3dyaXRlIGFjY2VzcyB0byB0aGUgc2hhcmVkIHJlZ2lvbiBsaXN0LiBUaGUgYnJ1c2ggaWdub3JlcyB0aGUgd2FuZCdzXG4gKiBwaXhlbCB2YWx1ZXMgKGl0IHBhaW50cyBhIGdlb21ldHJpYyBkaXNjIHJhdGhlciB0aGFuIGZsb29kLWZpbGxpbmcgYnkgY29sb3VyKSxcbiAqIHNvIHJldXNpbmcge0BsaW5rIFdhbmRUb29sSG9zdH0gbGV0cyBlYWNoIGJhY2tlbmQgYmluZCB0aGUgc2FtZSBob3N0IG9iamVjdC5cbiAqL1xuZXhwb3J0IHR5cGUgQnJ1c2hUb29sSG9zdCA9IFdhbmRUb29sSG9zdDtcblxuLyoqXG4gKiBRdVBhdGgtc3R5bGUgYnJ1c2ggdG9vbC4gUGFpbnRpbmcgYSBzdHJva2UgdW5pb25zIGEgZGlzYyBvZiB0aGUgY29uZmlndXJlZFxuICogc2l6ZSBpbnRvIHRoZSBhY3RpdmUgcmVnaW9uIGFzIHRoZSBjdXJzb3IgZHJhZ3M7IGhvbGRpbmcgPGtiZD5TaGlmdDwva2JkPlxuICogc3VidHJhY3RzIGluc3RlYWQgKGVyYXNlciBicnVzaCksIG1hdGNoaW5nIHRoZSB3YW5kJ3MgbW9kaWZpZXIuIFRoZSBzdHJva2UgaXNcbiAqIGFjY3VtdWxhdGVkIGFzIGEgYmJveC1yZWxhdGl2ZSBtYXNrIChleGFjdGx5IGxpa2Uge0BsaW5rIFdhbmRUb29sU2VydmljZX0pIHNvXG4gKiB0aGUgYnJ1c2ggaW5oZXJpdHMgdGhlIHdhbmQncyBhZG9wdC1leGlzdGluZy1yZWdpb24gYW5kIG1lcmdlLW9uLXRvdWNoXG4gKiBiZWhhdmlvdXIsIHRoZW4gdGhlIHVuaW9uIGJvdW5kYXJ5IGlzIHRyYWNlZCBiYWNrIGludG8gYSBwb2x5Z29uIFJlZ2lvbi5cbiAqXG4gKiBObyBwaXhlbCBzYW1wbGluZyBhbmQgbm8gY3Vyc29yIGluZGljYXRvcjogdGhlIHBhaW50ZWQgc3Ryb2tlIGl0c2VsZiBzaG93cyB0aGVcbiAqIGJydXNoIHNpemUuIFRoZSBvdmVybGF5IGNhbnZhcyBvbmx5IGNhcHR1cmVzIHRoZSBwb2ludGVyLlxuICpcbiAqIExpZmVjeWNsZSBtaXJyb3JzIHRoZSB3YW5kOiBhIGJhY2tlbmQgYmluZHMgaXRzIGhvc3Qgb25jZSwgdGhlbiB0b2dnbGVzIHRoZVxuICogdG9vbCB3aXRoIGBzZXRNb2RlKHRydWUgfCBmYWxzZSwgb3B0aW9ucylgLlxuICpcbiAqIEhvbGVzIC8gZG9udXRzIChqaXQtdWkjODUpOiBicnVzaGluZyBhIHJpbmcgdGhhdCBlbmNsb3NlcyBhbiB1bnBhaW50ZWQgYXJlYVxuICoga2VlcHMgdGhlIGVuY2xvc2VkIGhvbGUg4oCUIHtAbGluayBXYW5kU2VydmljZS5tYXNrVG9Qb2x5Z29uc30gdHJhY2VzIGludGVyaW9yXG4gKiByaW5ncyBpbnRvIHtAbGluayBQb2x5Z29uLmhvbGVzfSwgd2hpY2ggYWRvcHQvbWVyZ2UgcHJlc2VydmUgKHRoZSByZS1yYXN0ZXJpemVcbiAqIHB1bmNoZXMgdGhlIGhvbGVzIGJhY2sgb3V0KS4gVGhlIE9wZW5TZWFkcmFnb24gb3ZlcmxheSByZW5kZXJzIHRoZW0gd2l0aFxuICogZXZlbi1vZGQgZmlsbCBhbmQgR2VvSlNPTiByb3VuZC10cmlwcyB0aGVtIGFzIGV4dHJhIFBvbHlnb24gcmluZ3MuIFRoZSBQbG90bHlcbiAqIChIZWF0bWFwKSBiYWNrZW5kIGN1cnJlbnRseSByZW5kZXJzIHRoZSBmaWxsZWQgZXh0ZXJpb3Igb25seS5cbiAqL1xuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcbmV4cG9ydCBjbGFzcyBCcnVzaFRvb2xTZXJ2aWNlIHtcbiAgcHJpdmF0ZSBob3N0ITogQnJ1c2hUb29sSG9zdDtcbiAgcHJpdmF0ZSBvdmVybGF5OiBIVE1MQ2FudmFzRWxlbWVudCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGFjdGl2ZSA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBBY2N1bXVsYXRlZCBicnVzaCByZWdpb24gKGJib3gtcmVsYXRpdmUgbWFzaykuIFBlcnNpc3RzIGFjcm9zcyBtb3VzZXVwIHNvIGFcbiAgICogc3Vic2VxdWVudCBzdHJva2UgZXh0ZW5kcyB0aGUgKnNhbWUqIHJlZ2lvbiB1bnRpbCB0aGUgdXNlciBzd2l0Y2hlcyB0b29sIOKAlFxuICAgKiBtYXRjaGluZyBRdVBhdGgsIGFuZCB0aGUgd2FuZC5cbiAgICovXG4gIHByaXZhdGUgc3Ryb2tlOiBCQm94TWFzayB8IG51bGwgPSBudWxsO1xuICAvKiogSWQgb2YgdGhlIHJlZ2lvbiB0aGlzIHN0cm9rZSBpcyBlZGl0aW5nIChudWxsID0gYSBmcmVzaCByZWdpb24pLiBGb3IgYW5cbiAgICogIGVyYXNlIHRoYXQgc3BsaXRzIHRoZSByZWdpb24sIHRoaXMgdHJhY2tzIHRoZSBsYXJnZXN0IHJlc3VsdGluZyBwaWVjZS4gKi9cbiAgcHJpdmF0ZSBzdHJva2VSZWdpb25JZDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBSZWFkYmFjayByYXRpby9vcmlnaW4gc2lnbmF0dXJlIHRoZSBhY3RpdmUgc3Ryb2tlIGlzIHRpZWQgdG87IGEgY2hhbmdlICh6b29tL3BhbikgaW52YWxpZGF0ZXNcbiAgICogIGl0IHNvIGl0IGlzbid0IHJlLWNvbW1pdHRlZCBhdCBhIGRpZmZlcmVudCBzY2FsZSAoaml0LXVpIzEwMikuICovXG4gIHByaXZhdGUgc3Ryb2tlUmF0aW9TaWc6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICAvKiogSWRzIG9mIHRoZSBleHRyYSByZWdpb25zIHByb2R1Y2VkIHdoZW4gYW4gZXJhc2Ugc3Ryb2tlIHNwbGl0cyBhIHJlZ2lvblxuICAgKiAgaW50byBkaXNjb25uZWN0ZWQgcGllY2VzIOKAlCByZXVzZWQgYWNyb3NzIGRyYWcgdGlja3Mgc28gdGhlIHNwbGl0IHBpZWNlc1xuICAgKiAga2VlcCBzdGFibGUgaWRlbnRpdGllcyBpbnN0ZWFkIG9mIGJlaW5nIHJlY3JlYXRlZCBlYWNoIHRpY2suICovXG4gIHByaXZhdGUgc3Ryb2tlRXh0cmFJZHM6IG51bWJlcltdID0gW107XG4gIC8qKiBQcmV2aW91cyBjdXJzb3IgcG9zaXRpb24gKG1hdHJpeCBjb29yZHMpIHdpdGhpbiB0aGUgY3VycmVudCBkcmFnLCBzbyBmYXN0XG4gICAqICBkcmFncyBwYWludCBhIGNvbnRpbnVvdXMgc3Ryb2tlIHJhdGhlciB0aGFuIGRpc2Nvbm5lY3RlZCBkYWJzLiAqL1xuICBwcml2YXRlIGxhc3RNYXRyaXg6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGRyYWdnaW5nID0gZmFsc2U7XG4gIHByaXZhdGUgc2l6ZSA9IERFRkFVTFRfQlJVU0hfU0laRTtcbiAgLyoqIFRoZSBjbGFzcyBiZWluZyBwYWludGVkICh7QGxpbmsgQnJ1c2hPcHRpb25zLmxhYmVsfSAvIGBjb2xvcmApOyBudWxsID0gcGxhaW4gYnJ1c2guICovXG4gIHByaXZhdGUgcGFpbnRDbGFzczogeyBsYWJlbD86IHN0cmluZzsgY29sb3I/OiBzdHJpbmcgfSB8IG51bGwgPSBudWxsO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgYm91bmRNb3VzZURvd246IChlOiBNb3VzZUV2ZW50KSA9PiB2b2lkO1xuICBwcml2YXRlIHJlYWRvbmx5IGJvdW5kTW91c2VNb3ZlOiAoZTogTW91c2VFdmVudCkgPT4gdm9pZDtcbiAgcHJpdmF0ZSByZWFkb25seSBib3VuZE1vdXNlVXA6IChlOiBNb3VzZUV2ZW50KSA9PiB2b2lkO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgd2FuZFNlcnZpY2U6IFdhbmRTZXJ2aWNlKSB7XG4gICAgdGhpcy5ib3VuZE1vdXNlRG93biA9IChlKSA9PiB0aGlzLm9uTW91c2VEb3duKGUpO1xuICAgIHRoaXMuYm91bmRNb3VzZU1vdmUgPSAoZSkgPT4gdGhpcy5vbk1vdXNlTW92ZShlKTtcbiAgICB0aGlzLmJvdW5kTW91c2VVcCA9IChlKSA9PiB0aGlzLm9uTW91c2VVcChlKTtcbiAgfVxuXG4gIC8qKiBXaXJlIHRoZSB0b29sIHRvIGl0cyBob3N0LiBNdXN0IGJlIGNhbGxlZCBvbmNlIGJlZm9yZSBgc2V0TW9kZSh0cnVlKWAuICovXG4gIGJpbmRIb3N0KGhvc3Q6IEJydXNoVG9vbEhvc3QpIHtcbiAgICB0aGlzLmhvc3QgPSBob3N0O1xuICB9XG5cbiAgLy8g4pSA4pSAIFB1YmxpYyBBUEkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqIFRvZ2dsZSB0aGUgYnJ1c2ggb24vb2ZmLiAqL1xuICBzZXRNb2RlKGFjdGl2ZTogYm9vbGVhbiwgb3B0aW9uczogQnJ1c2hPcHRpb25zID0ge30pIHtcbiAgICB0aGlzLmFjdGl2ZSA9IGFjdGl2ZTtcbiAgICAvLyBTaXplIGFwcGxpZXMgd2hldGhlciBhcm1pbmcgb3Igbm90LCBhcyBiZWZvcmUgYnJ1c2ggY2xhc3NlczogYSBob3N0IG1heSBzZXQgaXRcbiAgICAvLyB3aGlsZSB0aGUgYnJ1c2ggaXMgb2ZmLCBhbmQgdGhlIG5leHQgYXJtIHdpdGhvdXQgb3B0aW9ucyBrZWVwcyBpdC5cbiAgICBpZiAob3B0aW9ucy5zaXplICE9IG51bGwpIHRoaXMuc2V0U2l6ZShvcHRpb25zLnNpemUpO1xuICAgIGlmIChhY3RpdmUpIHtcbiAgICAgIC8vIEFybWluZyBzZXRzIHRoZSBjbGFzcyBpbiBmdWxsOiBubyBsYWJlbC9jb2xvciBtZWFucyB0aGUgcGxhaW4gYnJ1c2guXG4gICAgICB0aGlzLnNldE9wdGlvbnMoeyBsYWJlbDogdW5kZWZpbmVkLCBjb2xvcjogdW5kZWZpbmVkLCAuLi5vcHRpb25zIH0pO1xuICAgICAgdGhpcy5jcmVhdGVPdmVybGF5KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZGVzdHJveU92ZXJsYXkoKTtcbiAgICAgIHRoaXMucGFpbnRDbGFzcyA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSBzaXplIGFuZC9vciBjbGFzcyB3aGlsZSBhcm1lZC4gVGhlIGNsYXNzIGNoYW5nZXMgb25seSB3aGVuIGBsYWJlbGBcbiAgICogb3IgYGNvbG9yYCBpcyBwYXNzZWQgKGFzIGEga2V5LCBldmVuIGB1bmRlZmluZWRgKSwgc28gYSBzaXplLW9ubHkgdXBkYXRlXG4gICAqIGtlZXBzIGl0LiBTd2l0Y2hpbmcgY2xhc3MgZHJvcHMgdGhlIGFjdGl2ZSByZWdpb24sIHNvIHRoZSBuZXh0IHN0cm9rZVxuICAgKiBzdGFydHMgYSByZWdpb24gb2YgdGhlIG5ldyBjbGFzcy5cbiAgICovXG4gIHNldE9wdGlvbnMob3B0aW9uczogQnJ1c2hPcHRpb25zID0ge30pIHtcbiAgICBpZiAob3B0aW9ucy5zaXplICE9IG51bGwpIHRoaXMuc2V0U2l6ZShvcHRpb25zLnNpemUpO1xuICAgIGlmICghKCdsYWJlbCcgaW4gb3B0aW9ucykgJiYgISgnY29sb3InIGluIG9wdGlvbnMpKSByZXR1cm47XG4gICAgY29uc3QgbmV4dCA9IG9wdGlvbnMubGFiZWwgIT0gbnVsbCB8fCBvcHRpb25zLmNvbG9yICE9IG51bGxcbiAgICAgID8geyBsYWJlbDogb3B0aW9ucy5sYWJlbCwgY29sb3I6IG9wdGlvbnMuY29sb3IgfVxuICAgICAgOiBudWxsO1xuICAgIGlmIChuZXh0Py5sYWJlbCAhPT0gdGhpcy5wYWludENsYXNzPy5sYWJlbCB8fCBuZXh0Py5jb2xvciAhPT0gdGhpcy5wYWludENsYXNzPy5jb2xvcikge1xuICAgICAgdGhpcy5yZXNldFN0cm9rZSgpO1xuICAgIH1cbiAgICB0aGlzLnBhaW50Q2xhc3MgPSBuZXh0O1xuICB9XG5cbiAgLyoqIExpdmUtdXBkYXRlIHRoZSBicnVzaCBzaXplIChtYXRyaXgtcGl4ZWwgZGlhbWV0ZXIpLiAqL1xuICBzZXRTaXplKHNpemU6IG51bWJlcikge1xuICAgIGlmICghTnVtYmVyLmlzRmluaXRlKHNpemUpIHx8IHNpemUgPD0gMCkgcmV0dXJuO1xuICAgIHRoaXMuc2l6ZSA9IHNpemU7XG4gIH1cblxuICAvKiogRHJvcCB0aGUgYWN0aXZlIGJydXNoIHJlZ2lvbiBzbyB0aGUgbmV4dCBzdHJva2Ugc3RhcnRzIGEgbmV3IG9uZS4gKi9cbiAgY2xlYXJBY3RpdmVSZWdpb24oKSB7XG4gICAgdGhpcy5yZXNldFN0cm9rZSgpO1xuICB9XG5cbiAgLy8g4pSA4pSAIE92ZXJsYXkgbGlmZWN5Y2xlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHByaXZhdGUgY3JlYXRlT3ZlcmxheSgpIHtcbiAgICBjb25zdCBwbG90RWwgPSB0aGlzLmhvc3QuZ2V0T3ZlcmxheUNvbnRhaW5lcigpO1xuICAgIGlmICghcGxvdEVsIHx8IHRoaXMub3ZlcmxheSkgcmV0dXJuO1xuXG4gICAgY29uc3QgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgY2FudmFzLnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICBjYW52YXMuc3R5bGUudG9wID0gJzAnO1xuICAgIGNhbnZhcy5zdHlsZS5sZWZ0ID0gJzAnO1xuICAgIGNhbnZhcy5zdHlsZS53aWR0aCA9ICcxMDAlJztcbiAgICBjYW52YXMuc3R5bGUuaGVpZ2h0ID0gJzEwMCUnO1xuICAgIGNhbnZhcy5zdHlsZS5jdXJzb3IgPSAnY3Jvc3NoYWlyJztcbiAgICBjYW52YXMuc3R5bGUuekluZGV4ID0gJzEwMCc7XG4gICAgY2FudmFzLndpZHRoID0gcGxvdEVsLm9mZnNldFdpZHRoO1xuICAgIGNhbnZhcy5oZWlnaHQgPSBwbG90RWwub2Zmc2V0SGVpZ2h0O1xuXG4gICAgcGxvdEVsLmFwcGVuZENoaWxkKGNhbnZhcyk7XG4gICAgdGhpcy5vdmVybGF5ID0gY2FudmFzO1xuXG4gICAgY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIHRoaXMuYm91bmRNb3VzZURvd24pO1xuICAgIGNhbnZhcy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB0aGlzLmJvdW5kTW91c2VNb3ZlKTtcbiAgICBjYW52YXMuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMuYm91bmRNb3VzZVVwKTtcbiAgICBjYW52YXMuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsIHRoaXMuYm91bmRNb3VzZVVwKTtcbiAgfVxuXG4gIHByaXZhdGUgZGVzdHJveU92ZXJsYXkoKSB7XG4gICAgaWYgKCF0aGlzLm92ZXJsYXkpIHJldHVybjtcbiAgICB0aGlzLm92ZXJsYXkucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5ib3VuZE1vdXNlRG93bik7XG4gICAgdGhpcy5vdmVybGF5LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHRoaXMuYm91bmRNb3VzZU1vdmUpO1xuICAgIHRoaXMub3ZlcmxheS5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgdGhpcy5ib3VuZE1vdXNlVXApO1xuICAgIHRoaXMub3ZlcmxheS5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgdGhpcy5ib3VuZE1vdXNlVXApO1xuICAgIHRoaXMub3ZlcmxheS5yZW1vdmUoKTtcbiAgICB0aGlzLm92ZXJsYXkgPSBudWxsO1xuICAgIHRoaXMucmVzZXRTdHJva2UoKTtcbiAgfVxuXG4gIHByaXZhdGUgb25Nb3VzZURvd24oZTogTW91c2VFdmVudCkge1xuICAgIGlmIChlLmJ1dHRvbiAhPT0gMCkgcmV0dXJuO1xuICAgIHRoaXMuZHJhZ2dpbmcgPSB0cnVlO1xuICAgIHRoaXMubGFzdE1hdHJpeCA9IG51bGw7IC8vIGZpcnN0IHN0YW1wIG9mIHRoaXMgZHJhZyBpcyBhIHNpbmdsZSBkYWJcbiAgICB0aGlzLmFwcGx5QXRDbGllbnQoZSwgdHJ1ZSk7XG4gIH1cblxuICBwcml2YXRlIG9uTW91c2VNb3ZlKGU6IE1vdXNlRXZlbnQpIHtcbiAgICBpZiAoIXRoaXMuZHJhZ2dpbmcpIHJldHVybjtcbiAgICBpZiAoKGUuYnV0dG9ucyAmIDEpID09PSAwKSB7XG4gICAgICB0aGlzLmRyYWdnaW5nID0gZmFsc2U7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuYXBwbHlBdENsaWVudChlLCBmYWxzZSk7XG4gIH1cblxuICBwcml2YXRlIG9uTW91c2VVcChfOiBNb3VzZUV2ZW50KSB7XG4gICAgLy8gU3RvcCBhY2N1bXVsYXRpbmcgZnJvbSB0aGlzIGRyYWcsIGJ1dCBrZWVwIHRoZSByZWdpb24gYWxpdmUgc28gdGhlIG5leHRcbiAgICAvLyBtb3VzZWRvd24gZXh0ZW5kcyBpdC4gQ2xlYXIgbGFzdE1hdHJpeCBzbyB0aGUgbmV4dCBkcmFnIHN0YXJ0cyBhIGRhYi5cbiAgICB0aGlzLmRyYWdnaW5nID0gZmFsc2U7XG4gICAgdGhpcy5sYXN0TWF0cml4ID0gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgcmVzZXRTdHJva2UoKSB7XG4gICAgdGhpcy5zdHJva2UgPSBudWxsO1xuICAgIHRoaXMuc3Ryb2tlUmVnaW9uSWQgPSBudWxsO1xuICAgIHRoaXMuc3Ryb2tlRXh0cmFJZHMgPSBbXTtcbiAgICB0aGlzLmxhc3RNYXRyaXggPSBudWxsO1xuICAgIHRoaXMuZHJhZ2dpbmcgPSBmYWxzZTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBQZXItdGljayBzdHJva2UgbG9naWMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqXG4gICAqIFBhaW50IChvciBlcmFzZSkgYSBkaXNjIOKAlCBvciBhIHN3ZXB0IGxpbmUgb2YgZGlzY3Mgc2luY2UgdGhlIHByZXZpb3VzXG4gICAqIHRpY2sg4oCUIGludG8gdGhlIGFjdGl2ZSByZWdpb24ncyBhY2N1bXVsYXRvciBtYXNrLCByZS10cmFjZSB0aGUgYm91bmRhcnksXG4gICAqIGFuZCBjb21taXQgdGhlIHVwZGF0ZWQgUmVnaW9uLiBTaGlmdCA9IGVyYXNlLlxuICAgKi9cbiAgcHJpdmF0ZSBhcHBseUF0Q2xpZW50KGU6IE1vdXNlRXZlbnQsIGlzU3RhcnQ6IGJvb2xlYW4pIHtcbiAgICBpZiAoIXRoaXMub3ZlcmxheSkgcmV0dXJuO1xuICAgIGNvbnN0IGNhY2hlZCA9IHRoaXMuaG9zdC5nZXRDYWNoZWRJbWFnZURhdGEoKTtcbiAgICBpZiAoIWNhY2hlZCB8fCBjYWNoZWQuZnJhbWVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuXG4gICAgY29uc3QgcmVnaW9ucyA9IHRoaXMuaG9zdC5nZXRSZWdpb25zKCk7XG5cbiAgICBjb25zdCB0cmFuc2Zvcm0gPSB0aGlzLmhvc3QuZ2V0Q29vcmRpbmF0ZVRyYW5zZm9ybSgpO1xuICAgIGlmICghdHJhbnNmb3JtLmlzUmVhZHkoKSkgcmV0dXJuO1xuICAgIGNvbnN0IHsgeDogZGF0YVgsIHk6IGRhdGFZIH0gPSB0cmFuc2Zvcm0uY2xpZW50VG9EYXRhKGUuY2xpZW50WCwgZS5jbGllbnRZKTtcbiAgICBpZiAoIU51bWJlci5pc0Zpbml0ZShkYXRhWCkgfHwgIU51bWJlci5pc0Zpbml0ZShkYXRhWSkpIHJldHVybjtcblxuICAgIC8vIEhlYXRtYXAvaW1hZ2UgdHJhY2VzIHVzZSByYXRpb3NbMF0gZm9yIGJvdGggZHggYW5kIGR5LlxuICAgIGNvbnN0IHJ4ID0gY2FjaGVkLnJhdGlvc1swXSB8fCAxO1xuICAgIGNvbnN0IHJ5ID0gY2FjaGVkLnJhdGlvc1swXSB8fCAxO1xuICAgIGNvbnN0IG94ID0gY2FjaGVkLm9yaWdpblggPz8gMDtcbiAgICBjb25zdCBveSA9IGNhY2hlZC5vcmlnaW5ZID8/IDA7XG4gICAgLy8gRHJvcCBhIHN0cm9rZSBidWlsdCBhdCBhIGRpZmZlcmVudCB2aWV3ICh6b29tL3Bhbik6IGl0cyBtYXRyaXggY29vcmRzIGFyZSB0aWVkIHRvIHRoZSBvbGRcbiAgICAvLyByYXRpby9vcmlnaW4sIGFuZCByZS1jb21taXR0aW5nIHdvdWxkIHJlc2NhbGUgdGhlIHJlZ2lvbiBieSB0aGUgem9vbSBmYWN0b3IgKGppdC11aSMxMDIpLlxuICAgIGNvbnN0IHNpZyA9IGAke3J4fSwke3J5fSwke294fSwke295fWA7XG4gICAgaWYgKHRoaXMuc3Ryb2tlICYmIHRoaXMuc3Ryb2tlUmF0aW9TaWcgIT09IHNpZykge1xuICAgICAgdGhpcy5zdHJva2UgPSBudWxsO1xuICAgICAgdGhpcy5zdHJva2VSZWdpb25JZCA9IG51bGw7XG4gICAgfVxuICAgIHRoaXMuc3Ryb2tlUmF0aW9TaWcgPSBzaWc7XG4gICAgY29uc3QgbWF0cml4WCA9IChkYXRhWCAtIG94KSAvIHJ4O1xuICAgIGNvbnN0IG1hdHJpeFkgPSAoZGF0YVkgLSBveSkgLyByeTtcbiAgICBpZiAobWF0cml4WCA8IDAgfHwgbWF0cml4WCA+PSBjYWNoZWQud2lkdGgpIHJldHVybjtcbiAgICBpZiAobWF0cml4WSA8IDAgfHwgbWF0cml4WSA+PSBjYWNoZWQuaGVpZ2h0KSByZXR1cm47XG5cbiAgICBjb25zdCBlcmFzZSA9IGUuc2hpZnRLZXk7XG4gICAgY29uc3QgcmFkaXVzID0gTWF0aC5tYXgoMC41LCB0aGlzLnNpemUgLyAyKTtcblxuICAgIC8vIFN0YXJ0IG9mIGEgZnJlc2ggZHJhZyB0aGF0IGlzbid0IGluc2lkZSB0aGUgY3VycmVudCBhY2N1bXVsYXRvcjogZHJvcCB0aGVcbiAgICAvLyBvbGQgc3Ryb2tlIHNvIGEgYnJhbmQtbmV3IHJlZ2lvbiBzdGFydHMgaGVyZSAobWlycm9ycyB0aGUgd2FuZCkuXG4gICAgaWYgKGlzU3RhcnQgJiYgIWVyYXNlICYmIHRoaXMuc3Ryb2tlICYmICF0aGlzLnBvaW50SW5TdHJva2UobWF0cml4WCwgbWF0cml4WSkpIHtcbiAgICAgIHRoaXMuc3Ryb2tlID0gbnVsbDtcbiAgICAgIHRoaXMuc3Ryb2tlUmVnaW9uSWQgPSBudWxsO1xuICAgIH1cblxuICAgIC8vIElmIHRoZXJlJ3Mgbm8gYWN0aXZlIHJlZ2lvbiwgYWRvcHQgYW4gZXhpc3Rpbmcgc2hhcGUgdW5kZXIgdGhlIGN1cnNvciBzb1xuICAgIC8vIHRoZSBzdHJva2UgZXh0ZW5kcyAob3IgZXJhc2VzIGZyb20pIGl0IGluc3RlYWQgb2YgY3JlYXRpbmcgYSBuZXcgcmVnaW9uLlxuICAgIGlmICghdGhpcy5zdHJva2UpIHtcbiAgICAgIHRoaXMudHJ5QWRvcHRTaGFwZUF0KHJlZ2lvbnMsIG1hdHJpeFgsIG1hdHJpeFksIHJ4LCByeSwgY2FjaGVkKTtcbiAgICB9XG5cbiAgICAvLyBFcmFzaW5nIHJlcXVpcmVzIGFuIGV4aXN0aW5nIHJlZ2lvbiDigJQgc2hpZnQgb24gZW1wdHkgc3BhY2UgaXMgYSBuby1vcC5cbiAgICBpZiAoZXJhc2UgJiYgIXRoaXMuc3Ryb2tlKSB7XG4gICAgICB0aGlzLmxhc3RNYXRyaXggPSB7IHg6IG1hdHJpeFgsIHk6IG1hdHJpeFkgfTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBTdGFtcCB0aGUgZGlzYywgc3dlZXBpbmcgZnJvbSB0aGUgcHJldmlvdXMgcG9pbnQgZm9yIGEgY29udGludW91cyBzdHJva2UuXG4gICAgaWYgKGlzU3RhcnQgfHwgIXRoaXMubGFzdE1hdHJpeCkge1xuICAgICAgdGhpcy5zdGFtcERpc2MobWF0cml4WCwgbWF0cml4WSwgcmFkaXVzLCBlcmFzZSwgY2FjaGVkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgZHggPSBtYXRyaXhYIC0gdGhpcy5sYXN0TWF0cml4Lng7XG4gICAgICBjb25zdCBkeSA9IG1hdHJpeFkgLSB0aGlzLmxhc3RNYXRyaXgueTtcbiAgICAgIGNvbnN0IGRpc3QgPSBNYXRoLmh5cG90KGR4LCBkeSk7XG4gICAgICBjb25zdCBzdGVwID0gTWF0aC5tYXgoMSwgcmFkaXVzIC8gMik7XG4gICAgICBjb25zdCBuID0gTWF0aC5tYXgoMSwgTWF0aC5jZWlsKGRpc3QgLyBzdGVwKSk7XG4gICAgICBmb3IgKGxldCBpID0gMTsgaSA8PSBuOyBpKyspIHtcbiAgICAgICAgY29uc3QgdCA9IGkgLyBuO1xuICAgICAgICB0aGlzLnN0YW1wRGlzYyh0aGlzLmxhc3RNYXRyaXgueCArIGR4ICogdCwgdGhpcy5sYXN0TWF0cml4LnkgKyBkeSAqIHQsIHJhZGl1cywgZXJhc2UsIGNhY2hlZCk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMubGFzdE1hdHJpeCA9IHsgeDogbWF0cml4WCwgeTogbWF0cml4WSB9O1xuXG4gICAgaWYgKCF0aGlzLnN0cm9rZSkgcmV0dXJuO1xuXG4gICAgaWYgKCFlcmFzZSkge1xuICAgICAgLy8gR3Jvd2luZyBpbnRvIGFub3RoZXIgc2hhcGUgZm9sZHMgaXQgaW50byB0aGlzIHN0cm9rZSAobWVyZ2Utb24tdG91Y2gpLlxuICAgICAgdGhpcy5tZXJnZU92ZXJsYXBwaW5nU2hhcGVzKHJlZ2lvbnMsIHJ4LCByeSwgY2FjaGVkKTtcbiAgICB9XG5cbiAgICBjb25zdCBzdHJva2UgPSB0aGlzLnN0cm9rZTtcbiAgICAvLyBUcmFjZSBldmVyeSBjb25uZWN0ZWQgcGllY2U6IGFuIGVyYXNlIHRoYXQgY3V0cyB0aHJvdWdoIHRoZSByZWdpb24gc3BsaXRzXG4gICAgLy8gaXQgaW50byB0d28sIGFuZCBib3RoIG11c3Qgc3Vydml2ZSAodGhlIGxhcmdlciBrZWVwcyB0aGUgcmVnaW9uIGlkZW50aXR5KS5cbiAgICBjb25zdCBwb2x5cyA9IHRoaXMud2FuZFNlcnZpY2UubWFza1RvUG9seWdvbnMoXG4gICAgICBzdHJva2UubWFzaywgc3Ryb2tlLmJ3LCBzdHJva2UuYmgsIGNhY2hlZC53aWR0aCwgY2FjaGVkLmhlaWdodCwgc3Ryb2tlLmJ4LCBzdHJva2UuYnksXG4gICAgKTtcbiAgICBpZiAocG9seXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAvLyBFcmFzZWQgdG8gbm90aGluZyDigJQgcmVtb3ZlIHRoZSBzaGFwZShzKSBlbnRpcmVseS5cbiAgICAgIGlmIChlcmFzZSkgdGhpcy5kcm9wQWN0aXZlU2hhcGUocmVnaW9ucyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY29tcG9uZW50cyA9IHBvbHlzLm1hcCgocG9seSkgPT4gKHtcbiAgICAgIHhQbG90OiBwb2x5Lnhwb2ludHMubWFwKCh4KSA9PiBveCArIHggKiByeCksXG4gICAgICB5UGxvdDogcG9seS55cG9pbnRzLm1hcCgoeSkgPT4gb3kgKyB5ICogcnkpLFxuICAgICAgLy8gQ2FycnkgdHJhY2VkIGludGVyaW9yIHJpbmdzIChob2xlcykgYmFjayB0byBwbG90IGNvb3JkcyBzbyB0aGUgZG9udXRcbiAgICAgIC8vIHN1cnZpdmVzIHRoZSBjb21taXQgKGppdC11aSM4NSkuXG4gICAgICBob2xlczogcG9seS5ob2xlcz8ubWFwKChyaW5nKSA9PiByaW5nLm1hcCgoW3gsIHldKSA9PiBbb3ggKyB4ICogcngsIG95ICsgeSAqIHJ5XSkpLFxuICAgIH0pKTtcbiAgICB0aGlzLmNvbW1pdENvbXBvbmVudHMocmVnaW9ucywgY29tcG9uZW50cyk7XG4gIH1cblxuICAvKipcbiAgICogT1IgKGFkZCkgb3IgQU5ELU5PVCAoZXJhc2UpIGEgZmlsbGVkIGRpc2Mgb2YgYHJhZGl1c2AgbWF0cml4LXBpeGVscyBjZW50cmVkXG4gICAqIGF0IChjeCwgY3kpIGludG8gdGhlIGFjY3VtdWxhdG9yLCBncm93aW5nIGl0cyBiYm94IHRvIGZpdCB3aGVuIGFkZGluZy5cbiAgICovXG4gIHByaXZhdGUgc3RhbXBEaXNjKGN4OiBudW1iZXIsIGN5OiBudW1iZXIsIHJhZGl1czogbnVtYmVyLCBlcmFzZTogYm9vbGVhbiwgY2FjaGVkOiBDYWNoZWRJbWFnZURhdGEpIHtcbiAgICBjb25zdCBweDAgPSBNYXRoLmZsb29yKGN4IC0gcmFkaXVzKTtcbiAgICBjb25zdCBweTAgPSBNYXRoLmZsb29yKGN5IC0gcmFkaXVzKTtcbiAgICBjb25zdCBweDEgPSBNYXRoLmNlaWwoY3ggKyByYWRpdXMpICsgMTtcbiAgICBjb25zdCBweTEgPSBNYXRoLmNlaWwoY3kgKyByYWRpdXMpICsgMTtcblxuICAgIGlmICghZXJhc2UpIHtcbiAgICAgIGlmICghdGhpcy5lbnN1cmVTdHJva2VDb3ZlcnMocHgwLCBweTAsIHB4MSwgcHkxLCBjYWNoZWQpKSByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHMgPSB0aGlzLnN0cm9rZTtcbiAgICBpZiAoIXMpIHJldHVybjsgLy8gZXJhc2luZyB3aXRoIG5vIGFjdGl2ZSByZWdpb25cblxuICAgIGNvbnN0IHIyID0gcmFkaXVzICogcmFkaXVzO1xuICAgIGNvbnN0IGl5MCA9IE1hdGgubWF4KHMuYnksIHB5MCk7XG4gICAgY29uc3QgaXkxID0gTWF0aC5taW4ocy5ieSArIHMuYmgsIHB5MSk7XG4gICAgY29uc3QgaXgwID0gTWF0aC5tYXgocy5ieCwgcHgwKTtcbiAgICBjb25zdCBpeDEgPSBNYXRoLm1pbihzLmJ4ICsgcy5idywgcHgxKTtcbiAgICBmb3IgKGxldCBpeSA9IGl5MDsgaXkgPCBpeTE7IGl5KyspIHtcbiAgICAgIGNvbnN0IGR5ID0gaXkgKyAwLjUgLSBjeTtcbiAgICAgIGNvbnN0IHJvdyA9IChpeSAtIHMuYnkpICogcy5idztcbiAgICAgIGZvciAobGV0IGl4ID0gaXgwOyBpeCA8IGl4MTsgaXgrKykge1xuICAgICAgICBjb25zdCBkeCA9IGl4ICsgMC41IC0gY3g7XG4gICAgICAgIGlmIChkeCAqIGR4ICsgZHkgKiBkeSA+IHIyKSBjb250aW51ZTtcbiAgICAgICAgcy5tYXNrW3JvdyArIChpeCAtIHMuYngpXSA9IGVyYXNlID8gMCA6IDE7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEVuc3VyZSB0aGUgYWNjdW11bGF0b3IncyBiYm94IGNvdmVycyBbcHgwLHB5MCxweDEscHkxKSAoY2xhbXBlZCB0byB0aGVcbiAgICogaW1hZ2UpLCBhbGxvY2F0aW5nL2NvcHlpbmcgYSBsYXJnZXIgbWFzayB3aGVuIGl0IG11c3QgZ3Jvdy4gUmV0dXJucyBmYWxzZSBpZlxuICAgKiB0aGUgcmVxdWVzdGVkIGJveCBpcyBlbXB0eSBhZnRlciBjbGFtcGluZy5cbiAgICovXG4gIHByaXZhdGUgZW5zdXJlU3Ryb2tlQ292ZXJzKFxuICAgIHB4MDogbnVtYmVyLCBweTA6IG51bWJlciwgcHgxOiBudW1iZXIsIHB5MTogbnVtYmVyLCBjYWNoZWQ6IENhY2hlZEltYWdlRGF0YSxcbiAgKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYnggPSBNYXRoLm1heCgwLCBweDApO1xuICAgIGNvbnN0IGJ5ID0gTWF0aC5tYXgoMCwgcHkwKTtcbiAgICBjb25zdCBieDEgPSBNYXRoLm1pbihjYWNoZWQud2lkdGgsIHB4MSk7XG4gICAgY29uc3QgYnkxID0gTWF0aC5taW4oY2FjaGVkLmhlaWdodCwgcHkxKTtcbiAgICBjb25zdCBidyA9IGJ4MSAtIGJ4O1xuICAgIGNvbnN0IGJoID0gYnkxIC0gYnk7XG4gICAgaWYgKGJ3IDw9IDAgfHwgYmggPD0gMCkgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKCF0aGlzLnN0cm9rZSkge1xuICAgICAgdGhpcy5zdHJva2UgPSB7IGJ4LCBieSwgYncsIGJoLCBtYXNrOiBuZXcgVWludDhBcnJheShidyAqIGJoKSB9O1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGNvbnN0IHMgPSB0aGlzLnN0cm9rZTtcbiAgICBjb25zdCBuYnggPSBNYXRoLm1pbihzLmJ4LCBieCk7XG4gICAgY29uc3QgbmJ5ID0gTWF0aC5taW4ocy5ieSwgYnkpO1xuICAgIGNvbnN0IG5ieDEgPSBNYXRoLm1heChzLmJ4ICsgcy5idywgYngxKTtcbiAgICBjb25zdCBuYnkxID0gTWF0aC5tYXgocy5ieSArIHMuYmgsIGJ5MSk7XG4gICAgY29uc3QgbmJ3ID0gbmJ4MSAtIG5ieDtcbiAgICBjb25zdCBuYmggPSBuYnkxIC0gbmJ5O1xuICAgIGlmIChuYncgPT09IHMuYncgJiYgbmJoID09PSBzLmJoICYmIG5ieCA9PT0gcy5ieCAmJiBuYnkgPT09IHMuYnkpIHJldHVybiB0cnVlO1xuXG4gICAgY29uc3QgbmV4dCA9IG5ldyBVaW50OEFycmF5KG5idyAqIG5iaCk7XG4gICAgY29uc3QgZHggPSBzLmJ4IC0gbmJ4O1xuICAgIGNvbnN0IGR5ID0gcy5ieSAtIG5ieTtcbiAgICBmb3IgKGxldCByb3cgPSAwOyByb3cgPCBzLmJoOyByb3crKykge1xuICAgICAgY29uc3Qgc3JjT2ZmID0gcm93ICogcy5idztcbiAgICAgIGNvbnN0IGRzdE9mZiA9IChyb3cgKyBkeSkgKiBuYncgKyBkeDtcbiAgICAgIG5leHQuc2V0KHMubWFzay5zdWJhcnJheShzcmNPZmYsIHNyY09mZiArIHMuYncpLCBkc3RPZmYpO1xuICAgIH1cbiAgICB0aGlzLnN0cm9rZSA9IHsgYng6IG5ieCwgYnk6IG5ieSwgYnc6IG5idywgYmg6IG5iaCwgbWFzazogbmV4dCB9O1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIFRydWUgaWYgKG1hdHJpeFgsIG1hdHJpeFkpIGxpZXMgaW5zaWRlIHRoZSBjdXJyZW50IHN0cm9rZSBhY2N1bXVsYXRvci4gKi9cbiAgcHJpdmF0ZSBwb2ludEluU3Ryb2tlKG1hdHJpeFg6IG51bWJlciwgbWF0cml4WTogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgY29uc3QgcyA9IHRoaXMuc3Ryb2tlO1xuICAgIGlmICghcykgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IG14ID0gTWF0aC5mbG9vcihtYXRyaXhYKSAtIHMuYng7XG4gICAgY29uc3QgbXkgPSBNYXRoLmZsb29yKG1hdHJpeFkpIC0gcy5ieTtcbiAgICBpZiAobXggPCAwIHx8IG15IDwgMCB8fCBteCA+PSBzLmJ3IHx8IG15ID49IHMuYmgpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gcy5tYXNrW215ICogcy5idyArIG14XSA9PT0gMTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgdGhlIHJlZ2lvbihzKSByZWZlcmVuY2VkIGJ5IHRoZSBzdHJva2UgYW5kIHJlc2V0IGl0IOKAlCB1c2VkIHdoZW4gYW5cbiAgICogZXJhc2Ugc3Ryb2tlIGRlbGV0ZXMgZXZlcnkgcGl4ZWwuXG4gICAqL1xuICBwcml2YXRlIGRyb3BBY3RpdmVTaGFwZShyZWdpb25zOiBSZWdpb25bXSkge1xuICAgIGNvbnN0IGlkcyA9IFt0aGlzLnN0cm9rZVJlZ2lvbklkLCAuLi50aGlzLnN0cm9rZUV4dHJhSWRzXS5maWx0ZXIoKGlkKTogaWQgaXMgbnVtYmVyID0+IGlkICE9IG51bGwpO1xuICAgIGxldCBjaGFuZ2VkID0gZmFsc2U7XG4gICAgZm9yIChjb25zdCBpZCBvZiBpZHMpIHtcbiAgICAgIGNvbnN0IGlkeCA9IHJlZ2lvbnMuZmluZEluZGV4KChyKSA9PiByLmlkID09PSBpZCk7XG4gICAgICBpZiAoaWR4ID49IDApIHsgcmVnaW9ucy5zcGxpY2UoaWR4LCAxKTsgY2hhbmdlZCA9IHRydWU7IH1cbiAgICB9XG4gICAgaWYgKGNoYW5nZWQpIHRoaXMuaG9zdC5zZXRSZWdpb25zKHJlZ2lvbnMpO1xuICAgIHRoaXMuc3Ryb2tlID0gbnVsbDtcbiAgICB0aGlzLnN0cm9rZVJlZ2lvbklkID0gbnVsbDtcbiAgICB0aGlzLnN0cm9rZUV4dHJhSWRzID0gW107XG4gIH1cblxuICAvKiogV2hldGhlciB0aGUgc3Ryb2tlIG1heSBhZG9wdCBvciBtZXJnZSBgcmVnaW9uYDogYWx3YXlzIGZvciB0aGUgcGxhaW4gYnJ1c2gsXG4gICAqICBvdGhlcndpc2Ugb25seSBhIHJlZ2lvbiBvZiB0aGUgY2xhc3MgYmVpbmcgcGFpbnRlZC4gKi9cbiAgcHJpdmF0ZSBwYWludHNJbnRvKHJlZ2lvbjogUmVnaW9uKTogYm9vbGVhbiB7XG4gICAgY29uc3QgbGFiZWwgPSB0aGlzLnBhaW50Q2xhc3M/LmxhYmVsO1xuICAgIHJldHVybiBsYWJlbCA9PSBudWxsIHx8IHJlZ2lvbj8ubGFiZWwgPT09IGxhYmVsO1xuICB9XG5cbiAgLyoqIEEgcmVnaW9uJ3MgY2xvc2VkLXBvbHlnb24gdmVydGljZXMgKGltYWdlL2RhdGEgY29vcmRzKSwgb3IgbnVsbCB3aGVuIGl0XG4gICAqICBpc24ndCBhIGZpbGxhYmxlIGNsb3NlZCBwb2x5Z29uIChyZWN0YW5nbGVzLCBvcGVuIHBvbHlsaW5lcykuICovXG4gIHByaXZhdGUgcmVnaW9uVmVydHMoXG4gICAgcmVnaW9uOiBSZWdpb24sXG4gICk6IHsgeHBvaW50czogbnVtYmVyW107IHlwb2ludHM6IG51bWJlcltdOyBob2xlcz86IG51bWJlcltdW11bXSB9IHwgbnVsbCB7XG4gICAgY29uc3QgYiA9IHJlZ2lvbj8uYm91bmRzO1xuICAgIGlmIChiIGluc3RhbmNlb2YgUG9seWdvbiAmJiBiLmNsb3NlZCAhPT0gZmFsc2UgJiYgYi54cG9pbnRzLmxlbmd0aCA+PSAzKSB7XG4gICAgICByZXR1cm4geyB4cG9pbnRzOiBiLnhwb2ludHMsIHlwb2ludHM6IGIueXBvaW50cywgaG9sZXM6IGIuaG9sZXMgfTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKiogV2hldGhlciBhIHJlZ2lvbiBjYW4gYmUgZmFpdGhmdWxseSByYXN0ZXJpemVkIGF0IHRoaXMgem9vbSAocngvcnkgPSBkYXRhIHVuaXRzIHBlciBtYXRyaXggcHgpLlxuICAgKiAgRWRpdGluZyByYXN0ZXJpemVzICsgcmUtdHJhY2VzIHRoZSByZWdpb24sIHNvIG9uZSB3aG9zZSBtYXRyaXgtc3BhY2UgYmJveCBleGNlZWRzIHRoZVxuICAgKiAgcmFzdGVyaXplciBjYXAgd291bGQgY29tZSBiYWNrIHJlc2NhbGVkL2NvcnJ1cHRlZCAoZS5nLiBhIHdob2xlLXNsaWRlIGFubm90YXRpb24gd2hpbGUgem9vbWVkXG4gICAqICBvdXQpIOKAlCBza2lwIGFkb3B0L21lcmdlIGZvciB0aG9zZSBhbmQgb25seSBlZGl0IHRoZW0gbmVhciBuYXRpdmUgem9vbSAoaml0LXVpIzEwMikuICovXG4gIHByaXZhdGUgZml0c0ZvckVkaXQodmVydHM6IHsgeHBvaW50czogbnVtYmVyW107IHlwb2ludHM6IG51bWJlcltdIH0sIHJ4OiBudW1iZXIsIHJ5OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICBjb25zdCB4cyA9IHZlcnRzLnhwb2ludHM7XG4gICAgY29uc3QgeXMgPSB2ZXJ0cy55cG9pbnRzO1xuICAgIGxldCBtaW5YID0gSW5maW5pdHksIG1heFggPSAtSW5maW5pdHksIG1pblkgPSBJbmZpbml0eSwgbWF4WSA9IC1JbmZpbml0eTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoeHNbaV0gPCBtaW5YKSBtaW5YID0geHNbaV07XG4gICAgICBpZiAoeHNbaV0gPiBtYXhYKSBtYXhYID0geHNbaV07XG4gICAgICBpZiAoeXNbaV0gPCBtaW5ZKSBtaW5ZID0geXNbaV07XG4gICAgICBpZiAoeXNbaV0gPiBtYXhZKSBtYXhZID0geXNbaV07XG4gICAgfVxuICAgIGNvbnN0IHcgPSAobWF4WCAtIG1pblgpIC8gKHJ4IHx8IDEpO1xuICAgIGNvbnN0IGggPSAobWF4WSAtIG1pblkpIC8gKHJ5IHx8IDEpO1xuICAgIHJldHVybiB3ID4gMCAmJiBoID4gMCAmJiB3ICogaCA8PSA0MDk2ICogNDA5NjtcbiAgfVxuXG4gIC8qKiBDb252ZXJ0IGEgcmVnaW9uJ3MgaG9sZSByaW5ncyBmcm9tIGltYWdlL2RhdGEgY29vcmRzIGludG8gbWF0cml4IGNvb3JkcyBzb1xuICAgKiAgdGhleSBsaW5lIHVwIHdpdGggdGhlIHN0cm9rZSBhY2N1bXVsYXRvciAoaml0LXVpIzg1KS4gKi9cbiAgcHJpdmF0ZSBob2xlc1RvTWF0cml4KFxuICAgIGhvbGVzOiBudW1iZXJbXVtdW10gfCB1bmRlZmluZWQsIG94OiBudW1iZXIsIG95OiBudW1iZXIsIHJ4OiBudW1iZXIsIHJ5OiBudW1iZXIsXG4gICk6IG51bWJlcltdW11bXSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIGhvbGVzPy5tYXAoKHJpbmcpID0+IHJpbmcubWFwKChbeCwgeV0pID0+IFsoeCAtIG94KSAvIHJ4LCAoeSAtIG95KSAvIHJ5XSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIElmIChtYXRyaXhYLCBtYXRyaXhZKSBmYWxscyBpbnNpZGUgYW4gZXhpc3RpbmcgcmVnaW9uLCByYXN0ZXJpemUgaXQgaW50byB0aGVcbiAgICogc3Ryb2tlIGFjY3VtdWxhdG9yIHNvIHN1YnNlcXVlbnQgYnJ1c2ggaW5wdXQgZXh0ZW5kcyBpdCByYXRoZXIgdGhhbiBzdGFydGluZ1xuICAgKiBhIG5ldyByZWdpb24uXG4gICAqL1xuICBwcml2YXRlIHRyeUFkb3B0U2hhcGVBdChcbiAgICByZWdpb25zOiBSZWdpb25bXSxcbiAgICBtYXRyaXhYOiBudW1iZXIsXG4gICAgbWF0cml4WTogbnVtYmVyLFxuICAgIHJ4OiBudW1iZXIsXG4gICAgcnk6IG51bWJlcixcbiAgICBjYWNoZWQ6IENhY2hlZEltYWdlRGF0YSxcbiAgKTogYm9vbGVhbiB7XG4gICAgaWYgKCFyZWdpb25zIHx8IHJlZ2lvbnMubGVuZ3RoID09PSAwKSByZXR1cm4gZmFsc2U7XG4gICAgLy8gTW9zdC1yZWNlbnRseS1hZGRlZCByZWdpb25zIGFyZSBvbiB0b3Ag4oCUIGNoZWNrIHRoZW0gZmlyc3QuXG4gICAgZm9yIChsZXQgaSA9IHJlZ2lvbnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGlmICghdGhpcy5wYWludHNJbnRvKHJlZ2lvbnNbaV0pKSBjb250aW51ZTsgLy8gYW5vdGhlciBjbGFzcydzIHJlZ2lvblxuICAgICAgY29uc3QgdmVydHMgPSB0aGlzLnJlZ2lvblZlcnRzKHJlZ2lvbnNbaV0pO1xuICAgICAgaWYgKCF2ZXJ0cykgY29udGludWU7XG4gICAgICBpZiAoIXRoaXMuZml0c0ZvckVkaXQodmVydHMsIHJ4LCByeSkpIGNvbnRpbnVlOyAvLyB0b28gbGFyZ2UgYXQgdGhpcyB6b29tIOKGkiBkb24ndCBhZG9wdFxuXG4gICAgICBjb25zdCBveCA9IGNhY2hlZC5vcmlnaW5YID8/IDA7XG4gICAgICBjb25zdCBveSA9IGNhY2hlZC5vcmlnaW5ZID8/IDA7XG4gICAgICBjb25zdCB4cyA9IHZlcnRzLnhwb2ludHMubWFwKCh4KSA9PiAoeCAtIG94KSAvIHJ4KTtcbiAgICAgIGNvbnN0IHlzID0gdmVydHMueXBvaW50cy5tYXAoKHkpID0+ICh5IC0gb3kpIC8gcnkpO1xuICAgICAgY29uc3QgaG9sZXMgPSB0aGlzLmhvbGVzVG9NYXRyaXgodmVydHMuaG9sZXMsIG94LCBveSwgcngsIHJ5KTtcblxuICAgICAgLy8gQ2xpY2tpbmcgaW5zaWRlIGEgaG9sZSBtdXN0IE5PVCBhZG9wdCB0aGUgZG9udXQgKGl0J3MgZW1wdHkgdGhlcmUpLlxuICAgICAgaWYgKCF0aGlzLndhbmRTZXJ2aWNlLnBvaW50SW5Qb2x5Z29uV2l0aEhvbGVzKG1hdHJpeFgsIG1hdHJpeFksIHhzLCB5cywgaG9sZXMpKSBjb250aW51ZTtcblxuICAgICAgY29uc3QgcmFzdGVyID0gdGhpcy53YW5kU2VydmljZS5yYXN0ZXJpemVQb2x5Z29uKHhzLCB5cywgY2FjaGVkLndpZHRoLCBjYWNoZWQuaGVpZ2h0LCBob2xlcyk7XG4gICAgICBpZiAoIXJhc3RlcikgY29udGludWU7XG5cbiAgICAgIHRoaXMuc3Ryb2tlID0gcmFzdGVyO1xuICAgICAgdGhpcy5zdHJva2VSZWdpb25JZCA9IHJlZ2lvbnNbaV0uaWQgPz8gbnVsbDtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogRm9sZCBldmVyeSByZWdpb24gd2hvc2UgcmFzdGVyaXplZCBtYXNrIG92ZXJsYXBzIHRoZSBzdHJva2UgbWFzayBpbnRvIHRoZVxuICAgKiBzdHJva2UgYW5kIHJlbW92ZSBpdCBmcm9tIHRoZSBsaXN0LCBzbyBicnVzaGluZyBhY3Jvc3MgcmVnaW9ucyBtZXJnZXMgdGhlbS5cbiAgICovXG4gIHByaXZhdGUgbWVyZ2VPdmVybGFwcGluZ1NoYXBlcyhyZWdpb25zOiBSZWdpb25bXSwgcng6IG51bWJlciwgcnk6IG51bWJlciwgY2FjaGVkOiBDYWNoZWRJbWFnZURhdGEpIHtcbiAgICBpZiAoIXRoaXMuc3Ryb2tlKSByZXR1cm47XG4gICAgbGV0IGRpZE1lcmdlID0gdHJ1ZTtcbiAgICB3aGlsZSAoZGlkTWVyZ2UpIHtcbiAgICAgIGRpZE1lcmdlID0gZmFsc2U7XG4gICAgICBmb3IgKGxldCBpID0gcmVnaW9ucy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBjb25zdCByZWdpb24gPSByZWdpb25zW2ldO1xuICAgICAgICBpZiAocmVnaW9uLmlkICE9IG51bGwgJiYgcmVnaW9uLmlkID09PSB0aGlzLnN0cm9rZVJlZ2lvbklkKSBjb250aW51ZTtcbiAgICAgICAgaWYgKCF0aGlzLnBhaW50c0ludG8ocmVnaW9uKSkgY29udGludWU7IC8vIG5ldmVyIGZvbGQgYW5vdGhlciBjbGFzcyBpblxuXG4gICAgICAgIGNvbnN0IHZlcnRzID0gdGhpcy5yZWdpb25WZXJ0cyhyZWdpb24pO1xuICAgICAgICBpZiAoIXZlcnRzKSBjb250aW51ZTtcbiAgICAgICAgaWYgKCF0aGlzLmZpdHNGb3JFZGl0KHZlcnRzLCByeCwgcnkpKSBjb250aW51ZTsgLy8gdG9vIGxhcmdlIGF0IHRoaXMgem9vbSDihpIgZG9uJ3QgbWVyZ2VcblxuICAgICAgICBjb25zdCBveCA9IGNhY2hlZC5vcmlnaW5YID8/IDA7XG4gICAgICAgIGNvbnN0IG95ID0gY2FjaGVkLm9yaWdpblkgPz8gMDtcbiAgICAgICAgY29uc3QgeHMgPSB2ZXJ0cy54cG9pbnRzLm1hcCgoeCkgPT4gKHggLSBveCkgLyByeCk7XG4gICAgICAgIGNvbnN0IHlzID0gdmVydHMueXBvaW50cy5tYXAoKHkpID0+ICh5IC0gb3kpIC8gcnkpO1xuXG4gICAgICAgIC8vIFF1aWNrIGJib3ggcmVqZWN0IGJlZm9yZSByYXN0ZXJpemluZy5cbiAgICAgICAgbGV0IG1pblggPSBJbmZpbml0eSwgbWF4WCA9IC1JbmZpbml0eSwgbWluWSA9IEluZmluaXR5LCBtYXhZID0gLUluZmluaXR5O1xuICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IHhzLmxlbmd0aDsgaysrKSB7XG4gICAgICAgICAgaWYgKHhzW2tdIDwgbWluWCkgbWluWCA9IHhzW2tdO1xuICAgICAgICAgIGlmICh4c1trXSA+IG1heFgpIG1heFggPSB4c1trXTtcbiAgICAgICAgICBpZiAoeXNba10gPCBtaW5ZKSBtaW5ZID0geXNba107XG4gICAgICAgICAgaWYgKHlzW2tdID4gbWF4WSkgbWF4WSA9IHlzW2tdO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHd4MCA9IHRoaXMuc3Ryb2tlLmJ4LCB3eTAgPSB0aGlzLnN0cm9rZS5ieTtcbiAgICAgICAgY29uc3Qgd3gxID0gd3gwICsgdGhpcy5zdHJva2UuYncsIHd5MSA9IHd5MCArIHRoaXMuc3Ryb2tlLmJoO1xuICAgICAgICBpZiAobWF4WCA8IHd4MCB8fCBtaW5YID4gd3gxIHx8IG1heFkgPCB3eTAgfHwgbWluWSA+IHd5MSkgY29udGludWU7XG5cbiAgICAgICAgY29uc3QgaG9sZXMgPSB0aGlzLmhvbGVzVG9NYXRyaXgodmVydHMuaG9sZXMsIG94LCBveSwgcngsIHJ5KTtcbiAgICAgICAgY29uc3QgcmFzdGVyID0gdGhpcy53YW5kU2VydmljZS5yYXN0ZXJpemVQb2x5Z29uKHhzLCB5cywgY2FjaGVkLndpZHRoLCBjYWNoZWQuaGVpZ2h0LCBob2xlcyk7XG4gICAgICAgIGlmICghcmFzdGVyKSBjb250aW51ZTtcbiAgICAgICAgaWYgKCFtYXNrc092ZXJsYXAodGhpcy5zdHJva2UsIHJhc3RlcikpIGNvbnRpbnVlO1xuXG4gICAgICAgIHRoaXMuc3Ryb2tlID0gdW5pb25NYXNrcyh0aGlzLnN0cm9rZSwgcmFzdGVyKTtcbiAgICAgICAgaWYgKHRoaXMuc3Ryb2tlUmVnaW9uSWQgPT0gbnVsbCkge1xuICAgICAgICAgIHRoaXMuc3Ryb2tlUmVnaW9uSWQgPSByZWdpb24uaWQgPz8gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICByZWdpb25zLnNwbGljZShpLCAxKTtcbiAgICAgICAgZGlkTWVyZ2UgPSB0cnVlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29tbWl0IHRoZSBzdHJva2UncyBjb25uZWN0ZWQgcGllY2VzIGFzIHJlZ2lvbnMg4oCUIHRoZSBsYXJnZXN0IGtlZXBzIHRoZVxuICAgKiBzdHJva2UncyByZWdpb24gaWRlbnRpdHksIGFkZGl0aW9uYWwgcGllY2VzIChmcm9tIGFuIGVyYXNlIHRoYXQgc3BsaXQgdGhlXG4gICAqIHJlZ2lvbikgYmVjb21lIHRoZWlyIG93biByZWdpb25zIHRyYWNrZWQgaW4gYHN0cm9rZUV4dHJhSWRzYCBzbyB0aGV5IGtlZXBcbiAgICogc3RhYmxlIGlkZW50aXRpZXMgYWNyb3NzIGRyYWcgdGlja3MuIFRoZSBzdG9yZSBtaW50cyBpZHMgb24gY29tbWl0LCB3aGljaFxuICAgKiB3ZSByZWFkIGJhY2sgc28gc3Vic2VxdWVudCB0aWNrcyByZXBsYWNlIHRoZSBzYW1lIHJlZ2lvbnMuXG4gICAqL1xuICBwcml2YXRlIGNvbW1pdENvbXBvbmVudHMoXG4gICAgcmVnaW9uczogUmVnaW9uW10sXG4gICAgY29tcG9uZW50czogeyB4UGxvdDogbnVtYmVyW107IHlQbG90OiBudW1iZXJbXTsgaG9sZXM/OiBudW1iZXJbXVtdW10gfVtdLFxuICApIHtcbiAgICBjb25zdCB2YWxpZCA9IGNvbXBvbmVudHMuZmlsdGVyKChjKSA9PiBjLnhQbG90Lmxlbmd0aCA+PSAzKTtcbiAgICBpZiAodmFsaWQubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICBjb25zdCBwcmV2RXh0cmFJZHMgPSB0aGlzLnN0cm9rZUV4dHJhSWRzO1xuICAgIC8vIERyb3AgcHJldmlvdXNseS10cmFja2VkIGV4dHJhcyB0aGF0IG5vIGxvbmdlciBoYXZlIGEgbWF0Y2hpbmcgcGllY2UgKHRoZVxuICAgIC8vIGNvbXBvbmVudCBjb3VudCBzaHJhbmssIGUuZy4gYW4gYWRkIHN0cm9rZSBicmlkZ2VkIGEgZ2FwKS5cbiAgICBjb25zdCByZXVzZUNvdW50ID0gTWF0aC5tYXgoMCwgdmFsaWQubGVuZ3RoIC0gMSk7XG4gICAgZm9yIChsZXQgayA9IHJldXNlQ291bnQ7IGsgPCBwcmV2RXh0cmFJZHMubGVuZ3RoOyBrKyspIHtcbiAgICAgIGNvbnN0IGlkeCA9IHJlZ2lvbnMuZmluZEluZGV4KChyKSA9PiByLmlkID09PSBwcmV2RXh0cmFJZHNba10pO1xuICAgICAgaWYgKGlkeCA+PSAwKSByZWdpb25zLnNwbGljZShpZHgsIDEpO1xuICAgIH1cblxuICAgIGNvbnN0IHByaW1hcnkgPSB0aGlzLnVwc2VydENvbXBvbmVudChyZWdpb25zLCB0aGlzLnN0cm9rZVJlZ2lvbklkLCB2YWxpZFswXSk7XG4gICAgY29uc3QgZXh0cmFzOiBSZWdpb25bXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgdmFsaWQubGVuZ3RoOyBpKyspIHtcbiAgICAgIGV4dHJhcy5wdXNoKHRoaXMudXBzZXJ0Q29tcG9uZW50KHJlZ2lvbnMsIHByZXZFeHRyYUlkc1tpIC0gMV0gPz8gbnVsbCwgdmFsaWRbaV0pKTtcbiAgICB9XG5cbiAgICB0aGlzLmhvc3Quc2V0UmVnaW9ucyhyZWdpb25zKTtcbiAgICAvLyBJZHMgYXJlIG1pbnRlZCBkdXJpbmcgc2V0UmVnaW9ucyDigJQgcmVhZCB0aGVtIGJhY2sgZm9yIHRoZSBuZXh0IHRpY2suXG4gICAgdGhpcy5zdHJva2VSZWdpb25JZCA9IHByaW1hcnkuaWQgPz8gdGhpcy5zdHJva2VSZWdpb25JZDtcbiAgICB0aGlzLnN0cm9rZUV4dHJhSWRzID0gZXh0cmFzXG4gICAgICAubWFwKChyKSA9PiByLmlkKVxuICAgICAgLmZpbHRlcigoaWQpOiBpZCBpcyBudW1iZXIgPT4gaWQgIT0gbnVsbCk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgYSBSZWdpb24gZm9yIG9uZSBjb21wb25lbnQgYW5kIGluc2VydCBpdCBpbnRvIGByZWdpb25zYDogcmVwbGFjZSB0aGVcbiAgICogcmVnaW9uIHdpdGggYGlkYCBpbiBwbGFjZSBpZiBpdCBleGlzdHMsIG90aGVyd2lzZSBhcHBlbmQgYSBuZXcgb25lLiBSZXR1cm5zXG4gICAqIHRoZSBSZWdpb24gaW5zdGFuY2UgKGl0cyBpZCBpcyBtaW50ZWQgbGF0ZXIgYnkgdGhlIHN0b3JlIHdoZW4gbmV3KS5cbiAgICovXG4gIHByaXZhdGUgdXBzZXJ0Q29tcG9uZW50KFxuICAgIHJlZ2lvbnM6IFJlZ2lvbltdLCBpZDogbnVtYmVyIHwgbnVsbCxcbiAgICBjOiB7IHhQbG90OiBudW1iZXJbXTsgeVBsb3Q6IG51bWJlcltdOyBob2xlcz86IG51bWJlcltdW11bXSB9LFxuICApOiBSZWdpb24ge1xuICAgIGNvbnN0IGV4aXN0aW5nID0gaWQgIT0gbnVsbCA/IHJlZ2lvbnMuZmluZCgocikgPT4gci5pZCA9PT0gaWQpIDogbnVsbDtcblxuICAgIGNvbnN0IHBvbHkgPSBuZXcgUG9seWdvbigpO1xuICAgIHBvbHkubnBvaW50cyA9IGMueFBsb3QubGVuZ3RoO1xuICAgIHBvbHkueHBvaW50cyA9IGMueFBsb3Q7XG4gICAgcG9seS55cG9pbnRzID0gYy55UGxvdDtcbiAgICBwb2x5LmNvb3JkaW5hdGVzID0gYy54UGxvdC5tYXAoKHgsIGkpID0+IFt4LCBjLnlQbG90W2ldXSk7XG4gICAgcG9seS5jbG9zZWQgPSB0cnVlO1xuICAgIGlmIChjLmhvbGVzICYmIGMuaG9sZXMubGVuZ3RoKSBwb2x5LmhvbGVzID0gYy5ob2xlcztcblxuICAgIGNvbnN0IHJlZ2lvbiA9IG5ldyBSZWdpb24oKTtcbiAgICByZWdpb24uYm91bmRzID0gcG9seTtcbiAgICBjb25zdCBwYWludCA9IHRoaXMucGFpbnRDbGFzcztcbiAgICByZWdpb24uY29sb3IgPSBwYWludD8uY29sb3IgPz8gdGhpcy5ob3N0LmdldFNoYXBlQ29sb3IoKTtcbiAgICAvLyBBbiBleHBsaWNpdCBjbGFzcyBjb2xvdXIgbXVzdCBzdXJ2aXZlIGEgcHJlc2V0IChyZSlhcHBseSwgbGlrZSBhIGNvbG91clxuICAgIC8vIHBpY2tlZCBpbiB0aGUgcmVnaW9uIGVkaXRvciAoaml0LXVpIzcwKS5cbiAgICBpZiAocGFpbnQ/LmNvbG9yICE9IG51bGwpIHJlZ2lvbi5jb2xvck92ZXJyaWRkZW4gPSB0cnVlO1xuICAgIGlmIChleGlzdGluZykge1xuICAgICAgcmVnaW9uLmlkID0gZXhpc3RpbmcuaWQ7XG4gICAgICByZWdpb24ubmFtZSA9IGV4aXN0aW5nLm5hbWU7XG4gICAgfVxuICAgIC8vIERlZmF1bHQgY2xhc3MvYW5ub3RhdGlvbiBuYW1lLCBtYXRjaGluZyB0aGUgb3ZlcmxheS1kcmF3biByZWdpb25zIGFuZCB0aGVcbiAgICAvLyB3YW5kIHNvIGEgYnJ1c2ggcmVnaW9uIGlzbid0IGxlZnQgdW5sYWJlbGVkLlxuICAgIHJlZ2lvbi5sYWJlbCA9IGV4aXN0aW5nPy5sYWJlbCA/PyBwYWludD8ubGFiZWwgPz8gJ1JlZ2lvbic7XG5cbiAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgIGNvbnN0IGlkeCA9IHJlZ2lvbnMuZmluZEluZGV4KChyKSA9PiByLmlkID09PSBpZCk7XG4gICAgICBpZiAoaWR4ID49IDApIHJlZ2lvbnNbaWR4XSA9IHJlZ2lvbjtcbiAgICAgIGVsc2UgcmVnaW9ucy5wdXNoKHJlZ2lvbik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlZ2lvbnMucHVzaChyZWdpb24pO1xuICAgIH1cbiAgICByZXR1cm4gcmVnaW9uO1xuICB9XG59XG4iXX0=
|
|
245
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJ1c2gtdG9vbC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi90b29sYmFyL2JydXNoL2JydXNoLXRvb2wuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNsRSxPQUFPLEVBQUUsV0FBVyxFQUFxQixNQUFNLDBCQUEwQixDQUFDO0FBQzFFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRTdELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQWdCN0Msa0VBQWtFO0FBQ2xFLE1BQU0sa0JBQWtCLEdBQUcsRUFBRSxDQUFDO0FBTTlCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9CRztBQUNILE1BQU0sT0FBTyxTQUFTO0lBc0JwQiw0RUFBNEU7SUFDNUUsWUFBWSxhQUF3QztRQXRCM0MsT0FBRSxHQUFHLE9BQU8sQ0FBQztRQUVMLFlBQU8sR0FBRyxJQUFJLGlCQUFpQixFQUFFLENBQUM7UUFFbkQ7Ozs7V0FJRztRQUNjLFdBQU0sR0FBRyxJQUFJLGdCQUFnQixFQUFFLENBQUM7UUFDakQ7NkVBQ3FFO1FBQzdELGVBQVUsR0FBb0MsSUFBSSxDQUFDO1FBQ25ELGFBQVEsR0FBRyxLQUFLLENBQUM7UUFDakIsU0FBSSxHQUFHLGtCQUFrQixDQUFDO1FBQ2xDLDBGQUEwRjtRQUNsRixlQUFVLEdBQThDLElBQUksQ0FBQztRQU9uRSxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksV0FBVyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFFRCx1RUFBdUU7SUFFdkU7d0VBQ29FO0lBQ3BFLFFBQVEsQ0FBQyxJQUFvQixFQUFFLFVBQXdCLEVBQUU7UUFDdkQsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLFVBQVUsQ0FB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QUFHLENBQUMsQ0FBQztRQUN2QyxLQUFLLElBQUksRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLEdBQUcsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUM7WUFDbEMsTUFBTSxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLENBQUM7WUFDekIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDL0IsS0FBSyxJQUFJLEVBQUUsR0FBRyxHQUFHLEVBQUUsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDO2dCQUNsQyxNQUFNLEVBQUUsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsQ0FBQztnQkFDekIsSUFBSSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRTtvQkFBRSxTQUFTO2dCQUNyQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzVDLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVEOzhEQUMwRDtJQUNsRCxVQUFVLENBQUMsTUFBYztRQUMvQixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQztRQUNyQyxPQUFPLEtBQUssSUFBSSxJQUFJLElBQUksTUFBTSxFQUFFLEtBQUssS0FBSyxLQUFLLENBQUM7SUFDbEQsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTWFza1N0cm9rZUVkaXRvciB9IGZyb20gJy4uL3Rvb2wta2l0L21hc2stc3Ryb2tlLWVkaXRvcic7XG5pbXBvcnQgeyBVbmRvR2VzdHVyZSwgVW5kb0dlc3R1cmVUYXJnZXQgfSBmcm9tICcuLi90b29sLWtpdC91bmRvLWdlc3R1cmUnO1xuaW1wb3J0IHsgVG9vbE92ZXJsYXlDYW52YXMgfSBmcm9tICcuLi90b29sLWtpdC90b29sLW92ZXJsYXknO1xuaW1wb3J0IHsgQ2FjaGVkSW1hZ2VEYXRhLCBDYW52YXNUb29sSG9zdCwgSUNhbnZhc1Rvb2wgfSBmcm9tICcuLi90b29sLWtpdC9jYW52YXMtdG9vbCc7XG5pbXBvcnQgeyBSZWdpb24gfSBmcm9tICcuLi8uLi9tb2RlbHMvcmVnaW9uJztcblxuLyoqIEJydXNoIHBhcmFtZXRlcnMuIGBzaXplYCBpcyB0aGUgYnJ1c2ggKmRpYW1ldGVyKiBpbiBtYXRyaXggKGltYWdlKSBwaXhlbHMuICovXG5leHBvcnQgaW50ZXJmYWNlIEJydXNoT3B0aW9ucyB7XG4gIHNpemU/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBQYWludCBhcyBvbmUgY2xhc3MuIFdpdGggYGxhYmVsYCBzZXQsIG5ldyByZWdpb25zIHRha2UgdGhpcyBsYWJlbCwgYW5kIHRoZVxuICAgKiBzdHJva2Ugb25seSBhZG9wdHMgb3IgbWVyZ2VzIHJlZ2lvbnMgdGhhdCBhbHJlYWR5IGhhdmUgaXQsIHNvIHBhaW50aW5nIG9uZVxuICAgKiBjbGFzcyBuZXZlciBncm93cyBhbm90aGVyIGNsYXNzJ3MgcmVnaW9uLiBgY29sb3JgIGNvbG91cnMgdGhlIHBhaW50ZWRcbiAgICogcmVnaW9ucyBpbnN0ZWFkIG9mIHRoZSB0b29sYmFyJ3Mgc2hhcGUgY29sb3VyLiBMZWF2ZSBib3RoIHVuc2V0IGZvciB0aGVcbiAgICogcGxhaW4gdG9vbGJhciBicnVzaC5cbiAgICovXG4gIGxhYmVsPzogc3RyaW5nO1xuICBjb2xvcj86IHN0cmluZztcbn1cblxuLyoqIERlZmF1bHQgYnJ1c2ggZGlhbWV0ZXIgKG1hdHJpeCBwaXhlbHMpIGlmIG5vbmUgaXMgc3VwcGxpZWQuICovXG5jb25zdCBERUZBVUxUX0JSVVNIX1NJWkUgPSA0MDtcblxuLyoqIEBkZXByZWNhdGVkIE9uZSBob3N0IHNlcnZlcyBldmVyeSBjYW52YXMgdG9vbDogdXNlIHtAbGluayBDYW52YXNUb29sSG9zdH0uIFRoZVxuICogIGJydXNoIHJlYWRzIG9ubHkgdGhlIHJlYWRiYWNrJ3MgY29vcmRpbmF0ZSBmcmFtZSwgbm90IGl0cyBwaXhlbCB2YWx1ZXMuICovXG5leHBvcnQgdHlwZSBCcnVzaFRvb2xIb3N0ID0gQ2FudmFzVG9vbEhvc3Q7XG5cbi8qKlxuICogUXVQYXRoLXN0eWxlIGJydXNoIHRvb2wuIFBhaW50aW5nIGEgc3Ryb2tlIHVuaW9ucyBhIGRpc2Mgb2YgdGhlIGNvbmZpZ3VyZWRcbiAqIHNpemUgaW50byB0aGUgYWN0aXZlIHJlZ2lvbiBhcyB0aGUgY3Vyc29yIGRyYWdzOyBob2xkaW5nIDxrYmQ+U2hpZnQ8L2tiZD5cbiAqIHN1YnRyYWN0cyBpbnN0ZWFkIChlcmFzZXIgYnJ1c2gpLCBtYXRjaGluZyB0aGUgd2FuZCdzIG1vZGlmaWVyLiBUaGUgc3Ryb2tlIGlzXG4gKiBhY2N1bXVsYXRlZCBhcyBhIGJib3gtcmVsYXRpdmUgbWFzayAoZXhhY3RseSBsaWtlIHtAbGluayBXYW5kVG9vbFNlcnZpY2V9KSBzb1xuICogdGhlIGJydXNoIGluaGVyaXRzIHRoZSB3YW5kJ3MgYWRvcHQtZXhpc3RpbmctcmVnaW9uIGFuZCBtZXJnZS1vbi10b3VjaFxuICogYmVoYXZpb3VyLCB0aGVuIHRoZSB1bmlvbiBib3VuZGFyeSBpcyB0cmFjZWQgYmFjayBpbnRvIGEgcG9seWdvbiBSZWdpb24uXG4gKlxuICogTm8gcGl4ZWwgc2FtcGxpbmcgYW5kIG5vIGN1cnNvciBpbmRpY2F0b3I6IHRoZSBwYWludGVkIHN0cm9rZSBpdHNlbGYgc2hvd3MgdGhlXG4gKiBicnVzaCBzaXplLiBUaGUgb3ZlcmxheSBjYW52YXMgb25seSBjYXB0dXJlcyB0aGUgcG9pbnRlci5cbiAqXG4gKiBMaWZlY3ljbGUgbWlycm9ycyB0aGUgd2FuZDogYSBwbGFpbiBjbGFzcywgb25lIGluc3RhbmNlIHBlciBiYWNrZW5kJ3NcbiAqIGBDYW52YXNUb29sTWFuYWdlcmAsIGFybWVkIHdpdGggYGFjdGl2YXRlKGhvc3QsIG9wdGlvbnMpYCAvIGBkZWFjdGl2YXRlKClgLlxuICpcbiAqIEhvbGVzIC8gZG9udXRzIChqaXQtdWkjODUpOiBicnVzaGluZyBhIHJpbmcgdGhhdCBlbmNsb3NlcyBhbiB1bnBhaW50ZWQgYXJlYVxuICoga2VlcHMgdGhlIGVuY2xvc2VkIGhvbGUg4oCUIHRoZSBjb250b3VyIHRyYWNlciAoYGdlb21ldHJ5L2NvbnRvdXJgKSB0cmFjZXMgaW50ZXJpb3JcbiAqIHJpbmdzIGludG8ge0BsaW5rIFBvbHlnb24uaG9sZXN9LCB3aGljaCBhZG9wdC9tZXJnZSBwcmVzZXJ2ZSAodGhlIHJlLXJhc3Rlcml6ZVxuICogcHVuY2hlcyB0aGUgaG9sZXMgYmFjayBvdXQpLiBUaGUgT3BlblNlYWRyYWdvbiBvdmVybGF5IHJlbmRlcnMgdGhlbSB3aXRoXG4gKiBldmVuLW9kZCBmaWxsIGFuZCBHZW9KU09OIHJvdW5kLXRyaXBzIHRoZW0gYXMgZXh0cmEgUG9seWdvbiByaW5ncy4gVGhlIFBsb3RseVxuICogKEhlYXRtYXApIGJhY2tlbmQgY3VycmVudGx5IHJlbmRlcnMgdGhlIGZpbGxlZCBleHRlcmlvciBvbmx5LlxuICovXG5leHBvcnQgY2xhc3MgQnJ1c2hUb29sIGltcGxlbWVudHMgSUNhbnZhc1Rvb2w8QnJ1c2hPcHRpb25zPiB7XG4gIHJlYWRvbmx5IGlkID0gJ2JydXNoJztcbiAgcHJpdmF0ZSBob3N0ITogQ2FudmFzVG9vbEhvc3Q7XG4gIHByaXZhdGUgcmVhZG9ubHkgb3ZlcmxheSA9IG5ldyBUb29sT3ZlcmxheUNhbnZhcygpO1xuXG4gIC8qKlxuICAgKiBBY2N1bXVsYXRlZCBicnVzaCByZWdpb24gKGJib3gtcmVsYXRpdmUgbWFzayksIHNoYXJlZCBsb2dpYyB3aXRoIHRoZSB3YW5kLlxuICAgKiBQZXJzaXN0cyBhY3Jvc3MgbW91c2V1cCBzbyBhIHN1YnNlcXVlbnQgc3Ryb2tlIGV4dGVuZHMgdGhlICpzYW1lKiByZWdpb25cbiAgICogdW50aWwgdGhlIHVzZXIgc3dpdGNoZXMgdG9vbCDigJQgbWF0Y2hpbmcgUXVQYXRoLCBhbmQgdGhlIHdhbmQuXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGVkaXRvciA9IG5ldyBNYXNrU3Ryb2tlRWRpdG9yKCk7XG4gIC8qKiBQcmV2aW91cyBjdXJzb3IgcG9zaXRpb24gKG1hdHJpeCBjb29yZHMpIHdpdGhpbiB0aGUgY3VycmVudCBkcmFnLCBzbyBmYXN0XG4gICAqICBkcmFncyBwYWludCBhIGNvbnRpbnVvdXMgc3Ryb2tlIHJhdGhlciB0aGFuIGRpc2Nvbm5lY3RlZCBkYWJzLiAqL1xuICBwcml2YXRlIGxhc3RNYXRyaXg6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGRyYWdnaW5nID0gZmFsc2U7XG4gIHByaXZhdGUgc2l6ZSA9IERFRkFVTFRfQlJVU0hfU0laRTtcbiAgLyoqIFRoZSBjbGFzcyBiZWluZyBwYWludGVkICh7QGxpbmsgQnJ1c2hPcHRpb25zLmxhYmVsfSAvIGBjb2xvcmApOyBudWxsID0gcGxhaW4gYnJ1c2guICovXG4gIHByaXZhdGUgcGFpbnRDbGFzczogeyBsYWJlbD86IHN0cmluZzsgY29sb3I/OiBzdHJpbmcgfSB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBNYWtlcyBlYWNoIGRyYWcgb25lIHVuZG8gc3RlcCwgaG93ZXZlciBsb25nIHRoZSB1c2VyIHBhdXNlcyAoUlQtMTIpLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGdlc3R1cmU6IFVuZG9HZXN0dXJlO1xuXG4gIC8qKiBAcGFyYW0gZ2VzdHVyZVRhcmdldCB0aGUgcmVnaW9uIHN0b3JlLCBzbyBlYWNoIGRyYWcgaXMgb25lIHVuZG8gc3RlcC4gKi9cbiAgY29uc3RydWN0b3IoZ2VzdHVyZVRhcmdldD86IFVuZG9HZXN0dXJlVGFyZ2V0IHwgbnVsbCkge1xuICAgIHRoaXMuZ2VzdHVyZSA9IG5ldyBVbmRvR2VzdHVyZShnZXN0dXJlVGFyZ2V0KTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBJQ2FudmFzVG9vbCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKiogQXJtIHRoZSBicnVzaCBvbiBgaG9zdGAuIEFybWluZyBzZXRzIHRoZSBjbGFzcyBpbiBmdWxsOiBubyBsYWJlbC9jb2xvclxuICAgKiAgbWVhbnMgdGhlIHBsYWluIGJydXNoOyBhIG1pc3Npbmcgc2l6ZSBrZWVwcyB0aGUgcHJldmlvdXMgb25lLiAqL1xuICBhY3RpdmF0ZShob3N0OiBDYW52YXNUb29sSG9zdCwgb3B0aW9uczogQnJ1c2hPcHRpb25zID0ge30pIHtcbiAgICB0aGlzLmhvc3QgPSBob3N0O1xuICAgIHRoaXMuc2V0T3B0aW9ucyh7IGxhYmVsOiB1bmRlZmluZWQsIGNvbG9yOiB1bmRlZmluZWQsIC4uLm9wdGlvbnMgfSk7XG4gICAgdGhpcy5jcmVhdGVPdmVybGF5KCk7XG4gIH1cblxuICAvKiogRGlzYXJtOiByZW1vdmUgdGhlIG92ZXJsYXksIGRyb3AgdGhlIGFjdGl2ZSByZWdpb24gYW5kIHRoZSBjbGFzcy4gKi9cbiAgZGVhY3RpdmF0ZSgpIHtcbiAgICB0aGlzLm92ZXJsYXkuZGV0YWNoKCk7XG4gICAgdGhpcy5yZXNldFN0cm9rZSgpO1xuICAgIHRoaXMucGFpbnRDbGFzcyA9IG51bGw7XG4gIH1cblxuICAvKiogRHJvcCB0aGUgYWN0aXZlIGJydXNoIHJlZ2lvbiBzbyB0aGUgbmV4dCBzdHJva2Ugc3RhcnRzIGEgbmV3IG9uZS4gKi9cbiAgcmVzZXQoKSB7XG4gICAgdGhpcy5yZXNldFN0cm9rZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSBzaXplIGFuZC9vciBjbGFzcyB3aGlsZSBhcm1lZC4gVGhlIGNsYXNzIGNoYW5nZXMgb25seSB3aGVuIGBsYWJlbGBcbiAgICogb3IgYGNvbG9yYCBpcyBwYXNzZWQgKGFzIGEga2V5LCBldmVuIGB1bmRlZmluZWRgKSwgc28gYSBzaXplLW9ubHkgdXBkYXRlXG4gICAqIGtlZXBzIGl0LiBTd2l0Y2hpbmcgY2xhc3MgZHJvcHMgdGhlIGFjdGl2ZSByZWdpb24sIHNvIHRoZSBuZXh0IHN0cm9rZVxuICAgKiBzdGFydHMgYSByZWdpb24gb2YgdGhlIG5ldyBjbGFzcy5cbiAgICovXG4gIHNldE9wdGlvbnMob3B0aW9uczogQnJ1c2hPcHRpb25zID0ge30pIHtcbiAgICBpZiAob3B0aW9ucy5zaXplICE9IG51bGwpIHRoaXMuc2V0U2l6ZShvcHRpb25zLnNpemUpO1xuICAgIGlmICghKCdsYWJlbCcgaW4gb3B0aW9ucykgJiYgISgnY29sb3InIGluIG9wdGlvbnMpKSByZXR1cm47XG4gICAgY29uc3QgbmV4dCA9XG4gICAgICBvcHRpb25zLmxhYmVsICE9IG51bGwgfHwgb3B0aW9ucy5jb2xvciAhPSBudWxsID8geyBsYWJlbDogb3B0aW9ucy5sYWJlbCwgY29sb3I6IG9wdGlvbnMuY29sb3IgfSA6IG51bGw7XG4gICAgaWYgKG5leHQ/LmxhYmVsICE9PSB0aGlzLnBhaW50Q2xhc3M/LmxhYmVsIHx8IG5leHQ/LmNvbG9yICE9PSB0aGlzLnBhaW50Q2xhc3M/LmNvbG9yKSB7XG4gICAgICB0aGlzLnJlc2V0U3Ryb2tlKCk7XG4gICAgfVxuICAgIHRoaXMucGFpbnRDbGFzcyA9IG5leHQ7XG4gIH1cblxuICAvKiogTGl2ZS11cGRhdGUgdGhlIGJydXNoIHNpemUgKG1hdHJpeC1waXhlbCBkaWFtZXRlcikuICovXG4gIHNldFNpemUoc2l6ZTogbnVtYmVyKSB7XG4gICAgaWYgKCFOdW1iZXIuaXNGaW5pdGUoc2l6ZSkgfHwgc2l6ZSA8PSAwKSByZXR1cm47XG4gICAgdGhpcy5zaXplID0gc2l6ZTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBPdmVybGF5IGxpZmVjeWNsZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBwcml2YXRlIGNyZWF0ZU92ZXJsYXkoKSB7XG4gICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5ob3N0LmdldE92ZXJsYXlDb250YWluZXIoKTtcbiAgICBpZiAoIWNvbnRhaW5lcikgcmV0dXJuO1xuICAgIHRoaXMub3ZlcmxheS5hdHRhY2goY29udGFpbmVyLCB7XG4gICAgICBkb3duOiAoZSkgPT4gdGhpcy5vblBvaW50ZXJEb3duKGUpLFxuICAgICAgbW92ZTogKGUpID0+IHRoaXMub25Qb2ludGVyTW92ZShlKSxcbiAgICAgIHVwOiAoKSA9PiB0aGlzLm9uUG9pbnRlclVwKCksXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIG9uUG9pbnRlckRvd24oZTogUG9pbnRlckV2ZW50KSB7XG4gICAgdGhpcy5kcmFnZ2luZyA9IHRydWU7XG4gICAgdGhpcy5nZXN0dXJlLmJlZ2luKCk7XG4gICAgdGhpcy5sYXN0TWF0cml4ID0gbnVsbDsgLy8gZmlyc3Qgc3RhbXAgb2YgdGhpcyBkcmFnIGlzIGEgc2luZ2xlIGRhYlxuICAgIHRoaXMuYXBwbHlBdENsaWVudChlLCB0cnVlKTtcbiAgfVxuXG4gIHByaXZhdGUgb25Qb2ludGVyTW92ZShlOiBQb2ludGVyRXZlbnQpIHtcbiAgICBpZiAoIXRoaXMuZHJhZ2dpbmcpIHJldHVybjtcbiAgICBpZiAoKGUuYnV0dG9ucyAmIDEpID09PSAwKSB7XG4gICAgICB0aGlzLmRyYWdnaW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmdlc3R1cmUuZW5kKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuYXBwbHlBdENsaWVudChlLCBmYWxzZSk7XG4gIH1cblxuICBwcml2YXRlIG9uUG9pbnRlclVwKCkge1xuICAgIC8vIFN0b3AgYWNjdW11bGF0aW5nIGZyb20gdGhpcyBkcmFnLCBidXQga2VlcCB0aGUgcmVnaW9uIGFsaXZlIHNvIHRoZSBuZXh0XG4gICAgLy8gbW91c2Vkb3duIGV4dGVuZHMgaXQuIENsZWFyIGxhc3RNYXRyaXggc28gdGhlIG5leHQgZHJhZyBzdGFydHMgYSBkYWIuXG4gICAgdGhpcy5kcmFnZ2luZyA9IGZhbHNlO1xuICAgIHRoaXMuZ2VzdHVyZS5lbmQoKTtcbiAgICB0aGlzLmxhc3RNYXRyaXggPSBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSByZXNldFN0cm9rZSgpIHtcbiAgICB0aGlzLmVkaXRvci5yZXNldCgpO1xuICAgIHRoaXMubGFzdE1hdHJpeCA9IG51bGw7XG4gICAgdGhpcy5kcmFnZ2luZyA9IGZhbHNlO1xuICAgIHRoaXMuZ2VzdHVyZS5lbmQoKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBQZXItdGljayBzdHJva2UgbG9naWMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqXG4gICAqIFBhaW50IChvciBlcmFzZSkgYSBkaXNjIOKAlCBvciBhIHN3ZXB0IGxpbmUgb2YgZGlzY3Mgc2luY2UgdGhlIHByZXZpb3VzXG4gICAqIHRpY2sg4oCUIGludG8gdGhlIGFjdGl2ZSByZWdpb24ncyBhY2N1bXVsYXRvciBtYXNrLCByZS10cmFjZSB0aGUgYm91bmRhcnksXG4gICAqIGFuZCBjb21taXQgdGhlIHVwZGF0ZWQgUmVnaW9uLiBTaGlmdCA9IGVyYXNlLlxuICAgKi9cbiAgcHJpdmF0ZSBhcHBseUF0Q2xpZW50KGU6IFBvaW50ZXJFdmVudCwgaXNTdGFydDogYm9vbGVhbikge1xuICAgIGlmICghdGhpcy5vdmVybGF5LmF0dGFjaGVkKSByZXR1cm47XG4gICAgY29uc3QgZWRpdG9yID0gdGhpcy5lZGl0b3I7XG4gICAgY29uc3QgdGljayA9IGVkaXRvci5iZWdpblRpY2sodGhpcy5ob3N0LCBlKTtcbiAgICBpZiAoIXRpY2spIHJldHVybjtcbiAgICBjb25zdCB7IGNhY2hlZCwgcmVnaW9ucywgZnJhbWUsIG14OiBtYXRyaXhYLCBteTogbWF0cml4WSB9ID0gdGljaztcblxuICAgIGNvbnN0IGVyYXNlID0gZS5zaGlmdEtleTtcbiAgICBjb25zdCByYWRpdXMgPSBNYXRoLm1heCgwLjUsIHRoaXMuc2l6ZSAvIDIpO1xuXG4gICAgLy8gU3RhcnQgb2YgYSBmcmVzaCBkcmFnIHRoYXQgaXNuJ3QgaW5zaWRlIHRoZSBjdXJyZW50IGFjY3VtdWxhdG9yOiBkcm9wIHRoZVxuICAgIC8vIG9sZCBzdHJva2Ugc28gYSBicmFuZC1uZXcgcmVnaW9uIHN0YXJ0cyBoZXJlIChtaXJyb3JzIHRoZSB3YW5kKS5cbiAgICBpZiAoaXNTdGFydCAmJiAhZXJhc2UgJiYgZWRpdG9yLnN0cm9rZSAmJiAhZWRpdG9yLmNvbnRhaW5zKG1hdHJpeFgsIG1hdHJpeFkpKSB7XG4gICAgICBlZGl0b3IucmVzZXQoKTtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGVyZSdzIG5vIGFjdGl2ZSByZWdpb24sIGFkb3B0IGFuIGV4aXN0aW5nIHNoYXBlIHVuZGVyIHRoZSBjdXJzb3Igc29cbiAgICAvLyB0aGUgc3Ryb2tlIGV4dGVuZHMgKG9yIGVyYXNlcyBmcm9tKSBpdCBpbnN0ZWFkIG9mIGNyZWF0aW5nIGEgbmV3IHJlZ2lvbi5cbiAgICBjb25zdCBhY2NlcHQgPSAocjogUmVnaW9uKSA9PiB0aGlzLnBhaW50c0ludG8ocik7XG4gICAgaWYgKCFlZGl0b3Iuc3Ryb2tlKSBlZGl0b3IuYWRvcHRBdChyZWdpb25zLCBtYXRyaXhYLCBtYXRyaXhZLCBmcmFtZSwgY2FjaGVkLCBhY2NlcHQpO1xuXG4gICAgLy8gRXJhc2luZyByZXF1aXJlcyBhbiBleGlzdGluZyByZWdpb24g4oCUIHNoaWZ0IG9uIGVtcHR5IHNwYWNlIGlzIGEgbm8tb3AuXG4gICAgaWYgKGVyYXNlICYmICFlZGl0b3Iuc3Ryb2tlKSB7XG4gICAgICB0aGlzLmxhc3RNYXRyaXggPSB7IHg6IG1hdHJpeFgsIHk6IG1hdHJpeFkgfTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBTdGFtcCB0aGUgZGlzYywgc3dlZXBpbmcgZnJvbSB0aGUgcHJldmlvdXMgcG9pbnQgZm9yIGEgY29udGludW91cyBzdHJva2UuXG4gICAgaWYgKGlzU3RhcnQgfHwgIXRoaXMubGFzdE1hdHJpeCkge1xuICAgICAgdGhpcy5zdGFtcERpc2MobWF0cml4WCwgbWF0cml4WSwgcmFkaXVzLCBlcmFzZSwgY2FjaGVkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgZHggPSBtYXRyaXhYIC0gdGhpcy5sYXN0TWF0cml4Lng7XG4gICAgICBjb25zdCBkeSA9IG1hdHJpeFkgLSB0aGlzLmxhc3RNYXRyaXgueTtcbiAgICAgIGNvbnN0IGRpc3QgPSBNYXRoLmh5cG90KGR4LCBkeSk7XG4gICAgICBjb25zdCBzdGVwID0gTWF0aC5tYXgoMSwgcmFkaXVzIC8gMik7XG4gICAgICBjb25zdCBuID0gTWF0aC5tYXgoMSwgTWF0aC5jZWlsKGRpc3QgLyBzdGVwKSk7XG4gICAgICBmb3IgKGxldCBpID0gMTsgaSA8PSBuOyBpKyspIHtcbiAgICAgICAgY29uc3QgdCA9IGkgLyBuO1xuICAgICAgICB0aGlzLnN0YW1wRGlzYyh0aGlzLmxhc3RNYXRyaXgueCArIGR4ICogdCwgdGhpcy5sYXN0TWF0cml4LnkgKyBkeSAqIHQsIHJhZGl1cywgZXJhc2UsIGNhY2hlZCk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMubGFzdE1hdHJpeCA9IHsgeDogbWF0cml4WCwgeTogbWF0cml4WSB9O1xuXG4gICAgaWYgKCFlZGl0b3Iuc3Ryb2tlKSByZXR1cm47XG5cbiAgICAvLyBHcm93aW5nIGludG8gYW5vdGhlciBzaGFwZSBmb2xkcyBpdCBpbnRvIHRoaXMgc3Ryb2tlIChtZXJnZS1vbi10b3VjaCkuXG4gICAgaWYgKCFlcmFzZSkgZWRpdG9yLm1lcmdlVG91Y2hpbmcocmVnaW9ucywgZnJhbWUsIGNhY2hlZCwgYWNjZXB0KTtcblxuICAgIC8vIEV2ZXJ5IGNvbm5lY3RlZCBwaWVjZSBpcyBjb21taXR0ZWQ6IGFuIGVyYXNlIHRoYXQgY3V0cyB0aHJvdWdoIHRoZSByZWdpb25cbiAgICAvLyBzcGxpdHMgaXQgaW4gdHdvIGFuZCBib3RoIHN1cnZpdmUgKHRoZSBsYXJnZXIga2VlcHMgdGhlIHJlZ2lvbiBpZGVudGl0eSksXG4gICAgLy8gYW5kIGVuY2xvc2VkIHVucGFpbnRlZCBhcmVhcyBzdGF5IGhvbGVzIChqaXQtdWkjODUpLlxuICAgIGNvbnN0IHBhaW50ID0gdGhpcy5wYWludENsYXNzO1xuICAgIGVkaXRvci5jb21taXQocmVnaW9ucywgZnJhbWUsIHRoaXMuaG9zdCwge1xuICAgICAgZXJhc2UsXG4gICAgICBkZWZhdWx0TGFiZWw6IHBhaW50Py5sYWJlbCA/PyAnUmVnaW9uJyxcbiAgICAgIC8vIEFuIGV4cGxpY2l0IGNsYXNzIGNvbG91ciBtdXN0IHN1cnZpdmUgYSBwcmVzZXQgKHJlKWFwcGx5LCBsaWtlIGEgY29sb3VyXG4gICAgICAvLyBwaWNrZWQgaW4gdGhlIHJlZ2lvbiBlZGl0b3IgKGppdC11aSM3MCkuXG4gICAgICBlZGl0UGF0Y2g6IHBhaW50Py5jb2xvciAhPSBudWxsID8geyBjb2xvcjogcGFpbnQuY29sb3IsIGNvbG9yT3ZlcnJpZGRlbjogdHJ1ZSB9IDogdW5kZWZpbmVkLFxuICAgICAgbmV3UmVnaW9uOiAoYm91bmRzKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlZ2lvbiA9IG5ldyBSZWdpb24oKTtcbiAgICAgICAgcmVnaW9uLmJvdW5kcyA9IGJvdW5kcztcbiAgICAgICAgcmVnaW9uLmNvbG9yID0gcGFpbnQ/LmNvbG9yID8/IHRoaXMuaG9zdC5nZXRTaGFwZUNvbG9yKCk7XG4gICAgICAgIGlmIChwYWludD8uY29sb3IgIT0gbnVsbCkgcmVnaW9uLmNvbG9yT3ZlcnJpZGRlbiA9IHRydWU7XG4gICAgICAgIC8vIERlZmF1bHQgY2xhc3MvYW5ub3RhdGlvbiBuYW1lLCBtYXRjaGluZyB0aGUgb3ZlcmxheS1kcmF3biByZWdpb25zIGFuZCB0aGVcbiAgICAgICAgLy8gd2FuZCBzbyBhIGJydXNoIHJlZ2lvbiBpc24ndCBsZWZ0IHVubGFiZWxlZC5cbiAgICAgICAgcmVnaW9uLmxhYmVsID0gcGFpbnQ/LmxhYmVsID8/ICdSZWdpb24nO1xuICAgICAgICByZXR1cm4gcmVnaW9uO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPUiAoYWRkKSBvciBBTkQtTk9UIChlcmFzZSkgYSBmaWxsZWQgZGlzYyBvZiBgcmFkaXVzYCBtYXRyaXgtcGl4ZWxzIGNlbnRyZWRcbiAgICogYXQgKGN4LCBjeSkgaW50byB0aGUgYWNjdW11bGF0b3IsIGdyb3dpbmcgaXRzIGJib3ggKGNsaXBwZWQgdG8gdGhlXG4gICAqIHJlYWRiYWNrKSB0byBmaXQgd2hlbiBhZGRpbmcuXG4gICAqL1xuICBwcml2YXRlIHN0YW1wRGlzYyhjeDogbnVtYmVyLCBjeTogbnVtYmVyLCByYWRpdXM6IG51bWJlciwgZXJhc2U6IGJvb2xlYW4sIGNhY2hlZDogQ2FjaGVkSW1hZ2VEYXRhKSB7XG4gICAgY29uc3QgcHgwID0gTWF0aC5mbG9vcihjeCAtIHJhZGl1cyk7XG4gICAgY29uc3QgcHkwID0gTWF0aC5mbG9vcihjeSAtIHJhZGl1cyk7XG4gICAgY29uc3QgcHgxID0gTWF0aC5jZWlsKGN4ICsgcmFkaXVzKSArIDE7XG4gICAgY29uc3QgcHkxID0gTWF0aC5jZWlsKGN5ICsgcmFkaXVzKSArIDE7XG5cbiAgICBpZiAoIWVyYXNlKSB7XG4gICAgICBjb25zdCBvayA9IHRoaXMuZWRpdG9yLmVuc3VyZUNvdmVycyhcbiAgICAgICAgTWF0aC5tYXgoMCwgcHgwKSxcbiAgICAgICAgTWF0aC5tYXgoMCwgcHkwKSxcbiAgICAgICAgTWF0aC5taW4oY2FjaGVkLndpZHRoLCBweDEpLFxuICAgICAgICBNYXRoLm1pbihjYWNoZWQuaGVpZ2h0LCBweTEpLFxuICAgICAgKTtcbiAgICAgIGlmICghb2spIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcyA9IHRoaXMuZWRpdG9yLnN0cm9rZTtcbiAgICBpZiAoIXMpIHJldHVybjsgLy8gZXJhc2luZyB3aXRoIG5vIGFjdGl2ZSByZWdpb25cblxuICAgIGNvbnN0IHIyID0gcmFkaXVzICogcmFkaXVzO1xuICAgIGNvbnN0IGl5MCA9IE1hdGgubWF4KHMuYnksIHB5MCk7XG4gICAgY29uc3QgaXkxID0gTWF0aC5taW4ocy5ieSArIHMuYmgsIHB5MSk7XG4gICAgY29uc3QgaXgwID0gTWF0aC5tYXgocy5ieCwgcHgwKTtcbiAgICBjb25zdCBpeDEgPSBNYXRoLm1pbihzLmJ4ICsgcy5idywgcHgxKTtcbiAgICBmb3IgKGxldCBpeSA9IGl5MDsgaXkgPCBpeTE7IGl5KyspIHtcbiAgICAgIGNvbnN0IGR5ID0gaXkgKyAwLjUgLSBjeTtcbiAgICAgIGNvbnN0IHJvdyA9IChpeSAtIHMuYnkpICogcy5idztcbiAgICAgIGZvciAobGV0IGl4ID0gaXgwOyBpeCA8IGl4MTsgaXgrKykge1xuICAgICAgICBjb25zdCBkeCA9IGl4ICsgMC41IC0gY3g7XG4gICAgICAgIGlmIChkeCAqIGR4ICsgZHkgKiBkeSA+IHIyKSBjb250aW51ZTtcbiAgICAgICAgcy5tYXNrW3JvdyArIChpeCAtIHMuYngpXSA9IGVyYXNlID8gMCA6IDE7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqIFdoZXRoZXIgdGhlIHN0cm9rZSBtYXkgYWRvcHQgb3IgbWVyZ2UgYHJlZ2lvbmA6IGFsd2F5cyBmb3IgdGhlIHBsYWluIGJydXNoLFxuICAgKiAgb3RoZXJ3aXNlIG9ubHkgYSByZWdpb24gb2YgdGhlIGNsYXNzIGJlaW5nIHBhaW50ZWQuICovXG4gIHByaXZhdGUgcGFpbnRzSW50byhyZWdpb246IFJlZ2lvbik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGxhYmVsID0gdGhpcy5wYWludENsYXNzPy5sYWJlbDtcbiAgICByZXR1cm4gbGFiZWwgPT0gbnVsbCB8fCByZWdpb24/LmxhYmVsID09PSBsYWJlbDtcbiAgfVxufVxuIl19
|