@jax-data-science/sci-image-visualizer 0.8.2 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (525) hide show
  1. package/README.md +201 -460
  2. package/esm2022/index.mjs +28 -15
  3. package/esm2022/lib/channel-histogram/channel-histogram.component.mjs +163 -91
  4. package/esm2022/lib/contracts/capabilities.contract.mjs +4 -3
  5. package/esm2022/lib/contracts/cell-segmenter.contract.mjs +1 -1
  6. package/esm2022/lib/contracts/channel-histogram-api.contract.mjs +5 -1
  7. package/esm2022/lib/contracts/color.mjs +60 -0
  8. package/esm2022/lib/contracts/colormap-lut.mjs +213 -57
  9. package/esm2022/lib/contracts/coordinate-transform.contract.mjs +1 -1
  10. package/esm2022/lib/contracts/display-types.mjs +11 -1
  11. package/esm2022/lib/contracts/instance-segmenter.contract.mjs +1 -1
  12. package/esm2022/lib/contracts/intensity.mjs +48 -5
  13. package/esm2022/lib/contracts/plot-type-contribution.contract.mjs +1 -1
  14. package/esm2022/lib/contracts/plot-type.mjs +134 -17
  15. package/esm2022/lib/contracts/ports/image-state.port.mjs +4 -1
  16. package/esm2022/lib/contracts/ports/preferences.port.mjs +5 -1
  17. package/esm2022/lib/contracts/ports/region-io.port.mjs +2 -1
  18. package/esm2022/lib/contracts/ports/spatial-data.port.mjs +5 -1
  19. package/esm2022/lib/contracts/ports/tile-access.port.mjs +2 -1
  20. package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
  21. package/esm2022/lib/contracts/region-overlay.contract.mjs +1 -1
  22. package/esm2022/lib/contracts/sam.contract.mjs +1 -1
  23. package/esm2022/lib/contracts/semantic-segmenter.contract.mjs +1 -1
  24. package/esm2022/lib/contracts/spatial-dataset.contract.mjs +3 -1
  25. package/esm2022/lib/contracts/toolbar-tool.contract.mjs +6 -4
  26. package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
  27. package/esm2022/lib/contracts/viz-config.mjs +2 -1
  28. package/esm2022/lib/geometry/contour.mjs +63 -0
  29. package/esm2022/lib/geometry/raster.mjs +98 -0
  30. package/esm2022/lib/geometry/ring.mjs +201 -0
  31. package/esm2022/lib/hex-color-picker/hex-color-picker.component.mjs +202 -102
  32. package/esm2022/lib/implementations/base-store-visualizer.mjs +201 -48
  33. package/esm2022/lib/implementations/napari-js/napari-axes-gizmo.mjs +65 -0
  34. package/esm2022/lib/implementations/napari-js/napari-display-state.mjs +136 -0
  35. package/esm2022/lib/implementations/napari-js/napari-helpers.mjs +199 -0
  36. package/esm2022/lib/implementations/napari-js/napari-image-2d-scene.mjs +602 -0
  37. package/esm2022/lib/implementations/napari-js/napari-loading-badge.mjs +3 -4
  38. package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +66 -0
  39. package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +157 -591
  40. package/esm2022/lib/implementations/napari-js/napari-scene.mjs +2 -0
  41. package/esm2022/lib/implementations/napari-js/napari-spatial-2d-scene.mjs +614 -0
  42. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +769 -0
  43. package/esm2022/lib/implementations/napari-js/napari-spatial-encoding.mjs +199 -0
  44. package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +263 -0
  45. package/esm2022/lib/implementations/napari-js/napari-spatial-scene.mjs +159 -0
  46. package/esm2022/lib/implementations/napari-js/napari-spatial-tiles.mjs +106 -1408
  47. package/esm2022/lib/implementations/napari-js/napari-spatial-tooltip.mjs +2 -2
  48. package/esm2022/lib/implementations/napari-js/napari-surface-scene.mjs +271 -0
  49. package/esm2022/lib/implementations/napari-js/napari-tile-client.mjs +562 -0
  50. package/esm2022/lib/implementations/napari-js/napari-tool-bridge.mjs +344 -0
  51. package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +361 -4184
  52. package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +439 -0
  53. package/esm2022/lib/implementations/napari-js/napari-volume-z-handle.mjs +6 -6
  54. package/esm2022/lib/implementations/napari-js/region-overlay/overlay-projection.mjs +96 -0
  55. package/esm2022/lib/implementations/napari-js/region-overlay/region-edit.mjs +35 -0
  56. package/esm2022/lib/implementations/napari-js/region-overlay/region-svg-renderer.mjs +182 -0
  57. package/esm2022/lib/implementations/napari-js/spatial-tiles/categorical-lookup.mjs +30 -0
  58. package/esm2022/lib/implementations/napari-js/spatial-tiles/cell-layers.mjs +274 -0
  59. package/esm2022/lib/implementations/napari-js/spatial-tiles/density-layer.mjs +144 -0
  60. package/esm2022/lib/implementations/napari-js/spatial-tiles/layer-groups.mjs +165 -0
  61. package/esm2022/lib/implementations/napari-js/spatial-tiles/plan-context.mjs +78 -0
  62. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-hover.mjs +182 -0
  63. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-jobs.mjs +369 -0
  64. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-layers.mjs +306 -0
  65. package/esm2022/lib/implementations/osd/display-pipeline.mjs +102 -40
  66. package/esm2022/lib/implementations/osd/histogram-sampler.mjs +56 -31
  67. package/esm2022/lib/implementations/osd/openseadragon-viewer-options.mjs +128 -0
  68. package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +333 -1685
  69. package/esm2022/lib/implementations/osd/osd-coordinate-transform.mjs +1 -1
  70. package/esm2022/lib/implementations/osd/osd-coords.mjs +5 -6
  71. package/esm2022/lib/implementations/osd/osd-export.mjs +122 -0
  72. package/esm2022/lib/implementations/osd/osd-lib.mjs +15 -1
  73. package/esm2022/lib/implementations/osd/osd-navigator-chrome.mjs +205 -0
  74. package/esm2022/lib/implementations/osd/osd-pixel-readback.mjs +68 -0
  75. package/esm2022/lib/implementations/osd/osd-region-overlay-draw.mjs +153 -0
  76. package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +185 -718
  77. package/esm2022/lib/implementations/osd/osd-scale-bar.mjs +52 -60
  78. package/esm2022/lib/implementations/osd/osd-tile-source.mjs +105 -0
  79. package/esm2022/lib/implementations/osd/osd-viewer-like.mjs +2 -0
  80. package/esm2022/lib/implementations/osd/osd-viewer-mount.mjs +44 -0
  81. package/esm2022/lib/implementations/osd/osd-viewport.mjs +184 -0
  82. package/esm2022/lib/implementations/osd/osd-zoom.mjs +7 -1
  83. package/esm2022/lib/implementations/osd/simple-source.mjs +395 -0
  84. package/esm2022/lib/implementations/osd/slice-cache.mjs +53 -48
  85. package/esm2022/lib/implementations/osd/tile-client.mjs +32 -11
  86. package/esm2022/lib/implementations/osd/tile-recolor.mjs +330 -0
  87. package/esm2022/lib/implementations/plotly/omics-trace-builders.mjs +161 -73
  88. package/esm2022/lib/implementations/plotly/plotly-coordinate-transform.mjs +1 -1
  89. package/esm2022/lib/implementations/plotly/plotly-image-loader.mjs +112 -0
  90. package/esm2022/lib/implementations/plotly/plotly-image-recolor.mjs +178 -0
  91. package/esm2022/lib/implementations/plotly/plotly-intensity-inset.mjs +33 -0
  92. package/esm2022/lib/implementations/plotly/plotly-isosurface-controls.mjs +83 -0
  93. package/esm2022/lib/implementations/plotly/plotly-layouts.mjs +121 -0
  94. package/esm2022/lib/implementations/plotly/plotly-readback.mjs +117 -0
  95. package/esm2022/lib/implementations/plotly/plotly-region-overlay.mjs +19 -10
  96. package/esm2022/lib/implementations/plotly/plotly-shape-projection.mjs +223 -0
  97. package/esm2022/lib/implementations/plotly/plotly-trace-builders.mjs +79 -19
  98. package/esm2022/lib/implementations/plotly/plotly-zoom-controller.mjs +223 -0
  99. package/esm2022/lib/implementations/plotly/plotly.service.mjs +439 -1655
  100. package/esm2022/lib/implementations/region-centroids.mjs +47 -0
  101. package/esm2022/lib/implementations/simple-slice-access.service.mjs +22 -12
  102. package/esm2022/lib/implementations/spatial-data-http/spatial-data-http.service.mjs +172 -92
  103. package/esm2022/lib/implementations/spatial-data-http/spatial-wire.mjs +103 -22
  104. package/esm2022/lib/implementations/tile-server/index.mjs +6 -0
  105. package/esm2022/lib/implementations/tile-server/native-histogram.mjs +30 -0
  106. package/esm2022/lib/implementations/tile-server/poll-descriptor.mjs +65 -0
  107. package/esm2022/lib/implementations/tile-server/tile-protocol.mjs +42 -0
  108. package/esm2022/lib/implementations/tile-server/transport.mjs +135 -0
  109. package/esm2022/lib/intensity/intensity-profile.mjs +107 -0
  110. package/esm2022/lib/intensity/intensity-profile.service.mjs +223 -0
  111. package/esm2022/lib/intensity-inset/intensity-inset.component.mjs +133 -0
  112. package/esm2022/lib/models/bezier.mjs +1 -11
  113. package/esm2022/lib/models/class-preset.mjs +41 -3
  114. package/esm2022/lib/models/geometry.mjs +27 -164
  115. package/esm2022/lib/models/polygon-edit.mjs +254 -0
  116. package/esm2022/lib/models/polygon-factory.mjs +118 -0
  117. package/esm2022/lib/models/region-clone.mjs +68 -0
  118. package/esm2022/lib/models/region-geojson.mjs +373 -0
  119. package/esm2022/lib/models/region.mjs +34 -33
  120. package/esm2022/lib/models/shape.mjs +18 -16
  121. package/esm2022/lib/plot-mode/contribution-host.mjs +297 -0
  122. package/esm2022/lib/plot-mode/plot-mode-controller.mjs +9 -6
  123. package/esm2022/lib/plot-mode/plot-type-menu.mjs +85 -0
  124. package/esm2022/lib/plot-mode/tool-params-model.mjs +87 -0
  125. package/esm2022/lib/plot.utilities.mjs +296 -473
  126. package/esm2022/lib/processing/image-crop.mjs +1 -1
  127. package/esm2022/lib/processing/processing-image.mjs +28 -15
  128. package/esm2022/lib/provide-visualization.mjs +40 -14
  129. package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +99 -0
  130. package/esm2022/lib/region-editor/file-stem.mjs +13 -0
  131. package/esm2022/lib/region-editor/manage-classes-dialog/manage-classes-dialog.component.mjs +118 -0
  132. package/esm2022/lib/region-editor/mask-export.service.mjs +98 -0
  133. package/esm2022/lib/region-editor/mask-raster.mjs +11 -5
  134. package/esm2022/lib/region-editor/region-color-dialog/region-color-dialog.component.mjs +56 -0
  135. package/esm2022/lib/region-editor/region-editor-help/region-editor-help.component.mjs +28 -0
  136. package/esm2022/lib/region-editor/region-editor.component.mjs +402 -651
  137. package/esm2022/lib/region-editor/region-metrics.mjs +68 -0
  138. package/esm2022/lib/region-editor/region-persistence.service.mjs +134 -0
  139. package/esm2022/lib/region-editor/region-table/region-table.component.mjs +153 -0
  140. package/esm2022/lib/region-editor/save-mask-dialog/save-mask-dialog.component.mjs +91 -0
  141. package/esm2022/lib/region-editor/save-regions-dialog/save-regions-dialog.component.mjs +92 -0
  142. package/esm2022/lib/region-ops.service.mjs +28 -70
  143. package/esm2022/lib/region-overlay/region-geometry.mjs +360 -0
  144. package/esm2022/lib/region-overlay/region-hit-test.mjs +103 -0
  145. package/esm2022/lib/region-overlay/svg-region-renderer.mjs +228 -0
  146. package/esm2022/lib/render-orchestrator.mjs +14 -11
  147. package/esm2022/lib/render-session.mjs +207 -0
  148. package/esm2022/lib/routing-visualizer.service.mjs +459 -411
  149. package/esm2022/lib/spatial/density-raster.mjs +14 -0
  150. package/esm2022/lib/spatial/embedding-compute-coordinator.mjs +239 -0
  151. package/esm2022/lib/spatial/embedding-compute.mjs +43 -10
  152. package/esm2022/lib/spatial/gene-search.mjs +1 -1
  153. package/esm2022/lib/spatial/glyphs.mjs +97 -0
  154. package/esm2022/lib/spatial/lod.mjs +187 -0
  155. package/esm2022/lib/spatial/spatial-controls.facade.mjs +200 -0
  156. package/esm2022/lib/spatial/spatial-density.mjs +25 -16
  157. package/esm2022/lib/spatial/spatial-encoding.mjs +26 -82
  158. package/esm2022/lib/spatial/spatial-expression.mjs +43 -42
  159. package/esm2022/lib/spatial/spatial-framing.mjs +1 -1
  160. package/esm2022/lib/spatial/spatial-heatmap.mjs +6 -3
  161. package/esm2022/lib/spatial/spatial-hover.mjs +5 -33
  162. package/esm2022/lib/spatial/spatial-panel-model.mjs +282 -0
  163. package/esm2022/lib/spatial/spatial-sections.mjs +1 -1
  164. package/esm2022/lib/spatial/spatial-selection.mjs +33 -46
  165. package/esm2022/lib/spatial/spatial-tile-merge.mjs +219 -0
  166. package/esm2022/lib/spatial/spatial-tiles.mjs +12 -648
  167. package/esm2022/lib/spatial/spatial-volume-image.mjs +2 -4
  168. package/esm2022/lib/spatial/stats.mjs +71 -0
  169. package/esm2022/lib/spatial/transcript-grouping.mjs +307 -0
  170. package/esm2022/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.mjs +150 -0
  171. package/esm2022/lib/spatial-controls/spatial-charts/chart-data-model.mjs +309 -0
  172. package/esm2022/lib/spatial-controls/spatial-charts/chart-help.mjs +145 -0
  173. package/esm2022/lib/spatial-controls/spatial-charts/plotly-chart-host.mjs +158 -0
  174. package/esm2022/lib/spatial-controls/spatial-charts/spatial-chart-window/spatial-chart-window.component.mjs +47 -0
  175. package/esm2022/lib/spatial-controls/spatial-charts/spatial-charts.component.mjs +297 -802
  176. package/esm2022/lib/spatial-controls/spatial-charts/spatial-embedding-controls/spatial-embedding-controls.component.mjs +89 -0
  177. package/esm2022/lib/spatial-controls/spatial-charts/spatial-heatmap-controls/spatial-heatmap-controls.component.mjs +52 -0
  178. package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +143 -1238
  179. package/esm2022/lib/spatial-controls/spatial-gene-picker.mjs +153 -0
  180. package/esm2022/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.mjs +241 -0
  181. package/esm2022/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.mjs +193 -0
  182. package/esm2022/lib/spatial-controls/spatial-key/spatial-key.component.mjs +132 -0
  183. package/esm2022/lib/spatial-controls/spatial-key/spatial-key.model.mjs +67 -0
  184. package/esm2022/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.mjs +147 -0
  185. package/esm2022/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.mjs +300 -0
  186. package/esm2022/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.mjs +370 -0
  187. package/esm2022/lib/store/class-color.util.mjs +46 -3
  188. package/esm2022/lib/store/region-history.mjs +146 -0
  189. package/esm2022/lib/store/region-scope-cache.mjs +140 -0
  190. package/esm2022/lib/store/region-selection.mjs +82 -0
  191. package/esm2022/lib/store/region-store.service.mjs +279 -675
  192. package/esm2022/lib/store/spatial-selection.service.mjs +2 -2
  193. package/esm2022/lib/store/visualizer-store.service.mjs +49 -71
  194. package/esm2022/lib/toast-outlets.mjs +5 -4
  195. package/esm2022/lib/toolbar/brush/brush-tool.service.mjs +92 -434
  196. package/esm2022/lib/toolbar/canvas-tools.mjs +20 -0
  197. package/esm2022/lib/toolbar/crop/slide-crop.mjs +26 -42
  198. package/esm2022/lib/toolbar/plot-type-selector/plot-type-selector.component.mjs +85 -0
  199. package/esm2022/lib/toolbar/region-tools/region-tool-buttons.mjs +74 -0
  200. package/esm2022/lib/toolbar/region-tools/region-tools.component.mjs +114 -0
  201. package/esm2022/lib/toolbar/segmentation/cell-segment-tool.service.mjs +74 -78
  202. package/esm2022/lib/toolbar/segmentation/cellpose-segmenter.service.mjs +50 -8
  203. package/esm2022/lib/toolbar/segmentation/onnx-sam-session.mjs +61 -42
  204. package/esm2022/lib/toolbar/segmentation/pending-calls.mjs +47 -0
  205. package/esm2022/lib/toolbar/segmentation/sam-model-registry.mjs +12 -4
  206. package/esm2022/lib/toolbar/segmentation/sam-onnx-core.mjs +70 -14
  207. package/esm2022/lib/toolbar/segmentation/sam-point-tool.service.mjs +135 -172
  208. package/esm2022/lib/toolbar/segmentation/sam-prompt.mjs +9 -90
  209. package/esm2022/lib/toolbar/segmentation/sam-session.service.mjs +183 -0
  210. package/esm2022/lib/toolbar/segmentation/sam-tool.service.mjs +95 -150
  211. package/esm2022/lib/toolbar/segmentation/segmentation-commit.mjs +12 -0
  212. package/esm2022/lib/toolbar/segmentation/segmentation-runner.mjs +108 -0
  213. package/esm2022/lib/toolbar/segmentation-tools/segmentation-tools.component.mjs +155 -0
  214. package/esm2022/lib/toolbar/stack-controls/stack-controls.component.mjs +81 -0
  215. package/esm2022/lib/toolbar/tool-kit/async-tool-status.mjs +37 -0
  216. package/esm2022/lib/toolbar/tool-kit/canvas-tool-manager.mjs +63 -0
  217. package/esm2022/lib/toolbar/tool-kit/canvas-tool.mjs +2 -0
  218. package/esm2022/lib/toolbar/tool-kit/frame-pixels.mjs +108 -0
  219. package/esm2022/lib/toolbar/tool-kit/mask-stroke-editor.mjs +306 -0
  220. package/esm2022/lib/toolbar/tool-kit/matrix-frame.mjs +61 -0
  221. package/esm2022/lib/toolbar/tool-kit/tool-overlay.mjs +140 -0
  222. package/esm2022/lib/toolbar/tool-kit/undo-gesture.mjs +24 -0
  223. package/esm2022/lib/toolbar/tool-slider/tool-slider.component.mjs +63 -0
  224. package/esm2022/lib/toolbar/toolbar-help-dialog/toolbar-help-dialog.component.mjs +50 -0
  225. package/esm2022/lib/toolbar/toolbar.component.mjs +68 -117
  226. package/esm2022/lib/toolbar/vertex-eraser/vertex-eraser-tool.service.mjs +93 -115
  227. package/esm2022/lib/toolbar/view-controls/view-controls.component.mjs +107 -0
  228. package/esm2022/lib/toolbar/wand/wand-region-grow.mjs +321 -0
  229. package/esm2022/lib/toolbar/wand/wand-tool.service.mjs +121 -416
  230. package/esm2022/lib/toolbar/wand/wand.service.mjs +30 -894
  231. package/esm2022/lib/toolbar/zoom-to-box/zoom-to-box-tool.service.mjs +48 -90
  232. package/esm2022/lib/util/mark-for-check.mjs +17 -0
  233. package/esm2022/lib/util/supersede.mjs +56 -0
  234. package/esm2022/lib/visualization.module.mjs +39 -141
  235. package/esm2022/lib/visualizer/floating-drag.directive.mjs +58 -0
  236. package/esm2022/lib/visualizer/region-actions.mjs +149 -0
  237. package/esm2022/lib/visualizer/region-load.mjs +60 -0
  238. package/esm2022/lib/visualizer/spatial-dataset-binder.mjs +163 -0
  239. package/esm2022/lib/visualizer/tool-modes.mjs +113 -0
  240. package/esm2022/lib/visualizer/viewer-shortcuts.mjs +167 -0
  241. package/esm2022/lib/visualizer/visualizer-context-menu.mjs +119 -0
  242. package/esm2022/lib/visualizer.component.mjs +480 -1902
  243. package/esm2022/lib/workers/spatial-math-ops.mjs +43 -0
  244. package/esm2022/lib/workers/spatial-math-worker.mjs +10 -0
  245. package/esm2022/lib/workers/spatial-math.mjs +190 -0
  246. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs +41083 -0
  247. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs.map +1 -0
  248. package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs +238 -0
  249. package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs.map +1 -0
  250. package/fesm2022/jax-data-science-sci-image-visualizer-spatial-math-worker-BzVFFqGS.mjs +12 -0
  251. package/fesm2022/jax-data-science-sci-image-visualizer-spatial-math-worker-BzVFFqGS.mjs.map +1 -0
  252. package/fesm2022/jax-data-science-sci-image-visualizer.mjs +41 -34430
  253. package/fesm2022/jax-data-science-sci-image-visualizer.mjs.map +1 -1
  254. package/fesm2022/mask.worker.js +36 -917
  255. package/fesm2022/onnx-sam.worker.js +52 -16
  256. package/fesm2022/spatial-math.worker.js +471 -0
  257. package/fesm2022/tsne.worker.js +32 -15
  258. package/index.d.ts +13 -10
  259. package/lib/channel-histogram/channel-histogram.component.d.ts +53 -43
  260. package/lib/contracts/capabilities.contract.d.ts +4 -2
  261. package/lib/contracts/cell-segmenter.contract.d.ts +1 -0
  262. package/lib/contracts/channel-histogram-api.contract.d.ts +4 -0
  263. package/lib/contracts/color.d.ts +27 -0
  264. package/lib/contracts/colormap-lut.d.ts +19 -4
  265. package/lib/contracts/coordinate-transform.contract.d.ts +3 -3
  266. package/lib/contracts/display-types.d.ts +21 -0
  267. package/lib/contracts/instance-segmenter.contract.d.ts +5 -0
  268. package/lib/contracts/intensity.d.ts +13 -2
  269. package/lib/contracts/plot-type.d.ts +3 -1
  270. package/lib/contracts/ports/image-state.port.d.ts +6 -2
  271. package/lib/contracts/ports/preferences.port.d.ts +4 -0
  272. package/lib/contracts/ports/region-io.port.d.ts +1 -0
  273. package/lib/contracts/ports/spatial-data.port.d.ts +4 -10
  274. package/lib/contracts/ports/tile-access.port.d.ts +1 -0
  275. package/lib/contracts/region-editor-api.contract.d.ts +1 -1
  276. package/lib/contracts/region-overlay.contract.d.ts +5 -0
  277. package/lib/contracts/sam.contract.d.ts +7 -0
  278. package/lib/contracts/semantic-segmenter.contract.d.ts +6 -0
  279. package/lib/contracts/spatial-dataset.contract.d.ts +19 -6
  280. package/lib/contracts/toolbar-tool.contract.d.ts +1 -0
  281. package/lib/contracts/visualizer.contract.d.ts +221 -54
  282. package/lib/contracts/viz-config.d.ts +1 -0
  283. package/lib/geometry/contour.d.ts +24 -0
  284. package/lib/geometry/raster.d.ts +42 -0
  285. package/lib/geometry/ring.d.ts +67 -0
  286. package/lib/hex-color-picker/hex-color-picker.component.d.ts +61 -27
  287. package/lib/implementations/base-store-visualizer.d.ts +61 -15
  288. package/lib/implementations/napari-js/napari-axes-gizmo.d.ts +36 -0
  289. package/lib/implementations/napari-js/napari-display-state.d.ts +76 -0
  290. package/lib/implementations/napari-js/napari-helpers.d.ts +129 -0
  291. package/lib/implementations/napari-js/napari-image-2d-scene.d.ts +162 -0
  292. package/lib/implementations/napari-js/napari-loading-badge.d.ts +0 -1
  293. package/lib/implementations/napari-js/napari-loading-state.d.ts +30 -0
  294. package/lib/implementations/napari-js/napari-region-overlay.d.ts +62 -70
  295. package/lib/implementations/napari-js/napari-scene.d.ts +93 -0
  296. package/lib/implementations/napari-js/napari-spatial-2d-scene.d.ts +163 -0
  297. package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +212 -0
  298. package/lib/implementations/napari-js/napari-spatial-encoding.d.ts +114 -0
  299. package/lib/implementations/napari-js/napari-spatial-hover.d.ts +89 -0
  300. package/lib/implementations/napari-js/napari-spatial-scene.d.ts +118 -0
  301. package/lib/implementations/napari-js/napari-spatial-tiles.d.ts +56 -263
  302. package/lib/implementations/napari-js/napari-spatial-tooltip.d.ts +1 -1
  303. package/lib/implementations/napari-js/napari-surface-scene.d.ts +76 -0
  304. package/lib/implementations/napari-js/napari-tile-client.d.ts +214 -0
  305. package/lib/implementations/napari-js/napari-tool-bridge.d.ts +179 -0
  306. package/lib/implementations/napari-js/napari-visualizer.service.d.ts +121 -878
  307. package/lib/implementations/napari-js/napari-volume-scene.d.ts +104 -0
  308. package/lib/implementations/napari-js/napari-volume-z-handle.d.ts +8 -12
  309. package/lib/implementations/napari-js/region-overlay/overlay-projection.d.ts +59 -0
  310. package/lib/implementations/napari-js/region-overlay/region-edit.d.ts +15 -0
  311. package/lib/implementations/napari-js/region-overlay/region-svg-renderer.d.ts +54 -0
  312. package/lib/implementations/napari-js/spatial-tiles/categorical-lookup.d.ts +26 -0
  313. package/lib/implementations/napari-js/spatial-tiles/cell-layers.d.ts +70 -0
  314. package/lib/implementations/napari-js/spatial-tiles/density-layer.d.ts +61 -0
  315. package/lib/implementations/napari-js/spatial-tiles/layer-groups.d.ts +67 -0
  316. package/lib/implementations/napari-js/spatial-tiles/plan-context.d.ts +38 -0
  317. package/lib/implementations/napari-js/spatial-tiles/transcript-hover.d.ts +71 -0
  318. package/lib/implementations/napari-js/spatial-tiles/transcript-jobs.d.ts +105 -0
  319. package/lib/implementations/napari-js/spatial-tiles/transcript-layers.d.ts +56 -0
  320. package/lib/implementations/osd/display-pipeline.d.ts +38 -9
  321. package/lib/implementations/osd/histogram-sampler.d.ts +22 -12
  322. package/lib/implementations/osd/openseadragon-viewer-options.d.ts +35 -0
  323. package/lib/implementations/osd/openseadragon-visualizer.service.d.ts +78 -354
  324. package/lib/implementations/osd/osd-coordinate-transform.d.ts +2 -1
  325. package/lib/implementations/osd/osd-coords.d.ts +6 -4
  326. package/lib/implementations/osd/osd-export.d.ts +36 -0
  327. package/lib/implementations/osd/osd-lib.d.ts +7 -0
  328. package/lib/implementations/osd/osd-navigator-chrome.d.ts +69 -0
  329. package/lib/implementations/osd/osd-pixel-readback.d.ts +22 -0
  330. package/lib/implementations/osd/osd-region-overlay-draw.d.ts +37 -0
  331. package/lib/implementations/osd/osd-region-overlay.d.ts +36 -48
  332. package/lib/implementations/osd/osd-scale-bar.d.ts +8 -6
  333. package/lib/implementations/osd/osd-tile-source.d.ts +49 -0
  334. package/lib/implementations/osd/osd-viewer-like.d.ts +100 -0
  335. package/lib/implementations/osd/osd-viewer-mount.d.ts +14 -0
  336. package/lib/implementations/osd/osd-viewport.d.ts +77 -0
  337. package/lib/implementations/osd/osd-zoom.d.ts +6 -0
  338. package/lib/implementations/osd/simple-source.d.ts +161 -0
  339. package/lib/implementations/osd/slice-cache.d.ts +12 -3
  340. package/lib/implementations/osd/tile-client.d.ts +11 -14
  341. package/lib/implementations/osd/tile-recolor.d.ts +141 -0
  342. package/lib/implementations/plotly/omics-trace-builders.d.ts +32 -20
  343. package/lib/implementations/plotly/plotly-image-loader.d.ts +49 -0
  344. package/lib/implementations/plotly/plotly-image-recolor.d.ts +75 -0
  345. package/lib/implementations/plotly/plotly-intensity-inset.d.ts +8 -0
  346. package/lib/implementations/plotly/plotly-isosurface-controls.d.ts +38 -0
  347. package/lib/implementations/plotly/plotly-layouts.d.ts +188 -0
  348. package/lib/implementations/plotly/plotly-readback.d.ts +41 -0
  349. package/lib/implementations/plotly/plotly-region-overlay.d.ts +2 -2
  350. package/lib/implementations/plotly/plotly-shape-projection.d.ts +92 -0
  351. package/lib/implementations/plotly/plotly-trace-builders.d.ts +23 -12
  352. package/lib/implementations/plotly/plotly-zoom-controller.d.ts +86 -0
  353. package/lib/implementations/plotly/plotly.service.d.ts +136 -401
  354. package/lib/implementations/region-centroids.d.ts +14 -0
  355. package/lib/implementations/simple-slice-access.service.d.ts +7 -4
  356. package/lib/implementations/spatial-data-http/spatial-data-http.service.d.ts +42 -18
  357. package/lib/implementations/spatial-data-http/spatial-wire.d.ts +34 -9
  358. package/lib/implementations/tile-server/index.d.ts +5 -0
  359. package/lib/implementations/tile-server/native-histogram.d.ts +25 -0
  360. package/lib/implementations/tile-server/poll-descriptor.d.ts +39 -0
  361. package/lib/implementations/tile-server/tile-protocol.d.ts +80 -0
  362. package/lib/implementations/tile-server/transport.d.ts +62 -0
  363. package/lib/intensity/intensity-profile.d.ts +66 -0
  364. package/lib/intensity/intensity-profile.service.d.ts +108 -0
  365. package/lib/intensity-inset/intensity-inset.component.d.ts +58 -0
  366. package/lib/models/bezier.d.ts +0 -5
  367. package/lib/models/class-preset.d.ts +18 -0
  368. package/lib/models/geometry.d.ts +14 -48
  369. package/lib/models/polygon-edit.d.ts +72 -0
  370. package/lib/models/polygon-factory.d.ts +40 -0
  371. package/lib/models/region-clone.d.ts +20 -0
  372. package/lib/models/region-geojson.d.ts +17 -0
  373. package/lib/models/region.d.ts +40 -4
  374. package/lib/models/shape.d.ts +8 -0
  375. package/lib/plot-mode/contribution-host.d.ts +125 -0
  376. package/lib/plot-mode/plot-type-menu.d.ts +60 -0
  377. package/lib/plot-mode/tool-params-model.d.ts +49 -0
  378. package/lib/plot.utilities.d.ts +19 -30
  379. package/lib/processing/processing-image.d.ts +5 -2
  380. package/lib/provide-visualization.d.ts +19 -2
  381. package/lib/region-editor/classes-panel/classes-panel.component.d.ts +56 -0
  382. package/lib/region-editor/file-stem.d.ts +7 -0
  383. package/lib/region-editor/manage-classes-dialog/manage-classes-dialog.component.d.ts +45 -0
  384. package/lib/region-editor/mask-export.service.d.ts +54 -0
  385. package/lib/region-editor/mask-raster.d.ts +2 -8
  386. package/lib/region-editor/region-color-dialog/region-color-dialog.component.d.ts +29 -0
  387. package/lib/region-editor/region-editor-help/region-editor-help.component.d.ts +11 -0
  388. package/lib/region-editor/region-editor.component.d.ts +166 -199
  389. package/lib/region-editor/region-metrics.d.ts +26 -0
  390. package/lib/region-editor/region-persistence.service.d.ts +69 -0
  391. package/lib/region-editor/region-table/region-table.component.d.ts +83 -0
  392. package/lib/region-editor/save-mask-dialog/save-mask-dialog.component.d.ts +36 -0
  393. package/lib/region-editor/save-regions-dialog/save-regions-dialog.component.d.ts +37 -0
  394. package/lib/region-ops.service.d.ts +1 -7
  395. package/lib/region-overlay/region-geometry.d.ts +157 -0
  396. package/lib/region-overlay/region-hit-test.d.ts +38 -0
  397. package/lib/region-overlay/svg-region-renderer.d.ts +110 -0
  398. package/lib/render-orchestrator.d.ts +6 -2
  399. package/lib/render-session.d.ts +75 -0
  400. package/lib/routing-visualizer.service.d.ts +110 -58
  401. package/lib/spatial/density-raster.d.ts +6 -0
  402. package/lib/spatial/embedding-compute-coordinator.d.ts +123 -0
  403. package/lib/spatial/embedding-compute.d.ts +21 -2
  404. package/lib/spatial/glyphs.d.ts +16 -0
  405. package/lib/spatial/lod.d.ts +94 -0
  406. package/lib/spatial/spatial-controls.facade.d.ts +64 -0
  407. package/lib/spatial/spatial-density.d.ts +15 -5
  408. package/lib/spatial/spatial-encoding.d.ts +11 -44
  409. package/lib/spatial/spatial-expression.d.ts +40 -22
  410. package/lib/spatial/spatial-framing.d.ts +1 -0
  411. package/lib/spatial/spatial-heatmap.d.ts +2 -0
  412. package/lib/spatial/spatial-hover.d.ts +4 -16
  413. package/lib/spatial/spatial-panel-model.d.ts +135 -0
  414. package/lib/spatial/spatial-selection.d.ts +21 -26
  415. package/lib/spatial/spatial-tile-merge.d.ts +41 -0
  416. package/lib/spatial/spatial-tiles.d.ts +9 -256
  417. package/lib/spatial/stats.d.ts +38 -0
  418. package/lib/spatial/transcript-grouping.d.ts +119 -0
  419. package/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.d.ts +64 -0
  420. package/lib/spatial-controls/spatial-charts/chart-data-model.d.ts +153 -0
  421. package/lib/spatial-controls/spatial-charts/chart-help.d.ts +69 -0
  422. package/lib/spatial-controls/spatial-charts/plotly-chart-host.d.ts +98 -0
  423. package/lib/spatial-controls/spatial-charts/spatial-chart-window/spatial-chart-window.component.d.ts +26 -0
  424. package/lib/spatial-controls/spatial-charts/spatial-charts.component.d.ts +101 -260
  425. package/lib/spatial-controls/spatial-charts/spatial-embedding-controls/spatial-embedding-controls.component.d.ts +43 -0
  426. package/lib/spatial-controls/spatial-charts/spatial-heatmap-controls/spatial-heatmap-controls.component.d.ts +27 -0
  427. package/lib/spatial-controls/spatial-controls.component.d.ts +68 -448
  428. package/lib/spatial-controls/spatial-gene-picker.d.ts +86 -0
  429. package/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.d.ts +102 -0
  430. package/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.d.ts +72 -0
  431. package/lib/spatial-controls/spatial-key/spatial-key.component.d.ts +66 -0
  432. package/lib/spatial-controls/spatial-key/spatial-key.model.d.ts +33 -0
  433. package/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.d.ts +64 -0
  434. package/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.d.ts +117 -0
  435. package/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.d.ts +142 -0
  436. package/lib/store/class-color.util.d.ts +35 -1
  437. package/lib/store/region-history.d.ts +66 -0
  438. package/lib/store/region-scope-cache.d.ts +63 -0
  439. package/lib/store/region-selection.d.ts +36 -0
  440. package/lib/store/region-store.service.d.ts +104 -112
  441. package/lib/store/visualizer-store.service.d.ts +22 -33
  442. package/lib/toast-outlets.d.ts +4 -3
  443. package/lib/toolbar/brush/brush-tool.service.d.ts +31 -98
  444. package/lib/toolbar/canvas-tools.d.ts +20 -0
  445. package/lib/toolbar/crop/slide-crop.d.ts +10 -4
  446. package/lib/toolbar/plot-type-selector/plot-type-selector.component.d.ts +38 -0
  447. package/lib/toolbar/region-tools/region-tool-buttons.d.ts +21 -0
  448. package/lib/toolbar/region-tools/region-tools.component.d.ts +60 -0
  449. package/lib/toolbar/segmentation/cell-segment-tool.service.d.ts +10 -14
  450. package/lib/toolbar/segmentation/cellpose-segmenter.service.d.ts +12 -2
  451. package/lib/toolbar/segmentation/onnx-sam-session.d.ts +22 -3
  452. package/lib/toolbar/segmentation/pending-calls.d.ts +31 -0
  453. package/lib/toolbar/segmentation/sam-model-registry.d.ts +9 -3
  454. package/lib/toolbar/segmentation/sam-onnx-core.d.ts +18 -5
  455. package/lib/toolbar/segmentation/sam-point-tool.service.d.ts +46 -32
  456. package/lib/toolbar/segmentation/sam-prompt.d.ts +7 -31
  457. package/lib/toolbar/segmentation/sam-session.service.d.ts +74 -0
  458. package/lib/toolbar/segmentation/sam-tool.service.d.ts +23 -30
  459. package/lib/toolbar/segmentation/segmentation-commit.d.ts +8 -0
  460. package/lib/toolbar/segmentation/segmentation-runner.d.ts +52 -0
  461. package/lib/toolbar/segmentation-tools/segmentation-tools.component.d.ts +87 -0
  462. package/lib/toolbar/stack-controls/stack-controls.component.d.ts +40 -0
  463. package/lib/toolbar/tool-kit/async-tool-status.d.ts +21 -0
  464. package/lib/toolbar/tool-kit/canvas-tool-manager.d.ts +36 -0
  465. package/lib/toolbar/tool-kit/canvas-tool.d.ts +86 -0
  466. package/lib/toolbar/tool-kit/frame-pixels.d.ts +45 -0
  467. package/lib/toolbar/tool-kit/mask-stroke-editor.d.ts +125 -0
  468. package/lib/toolbar/tool-kit/matrix-frame.d.ts +40 -0
  469. package/lib/toolbar/tool-kit/tool-overlay.d.ts +60 -0
  470. package/lib/toolbar/tool-kit/undo-gesture.d.ts +17 -0
  471. package/lib/toolbar/tool-slider/tool-slider.component.d.ts +33 -0
  472. package/lib/toolbar/toolbar-help-dialog/toolbar-help-dialog.component.d.ts +24 -0
  473. package/lib/toolbar/toolbar.component.d.ts +47 -83
  474. package/lib/toolbar/vertex-eraser/vertex-eraser-tool.service.d.ts +33 -40
  475. package/lib/toolbar/view-controls/view-controls.component.d.ts +54 -0
  476. package/lib/toolbar/wand/wand-region-grow.d.ts +49 -0
  477. package/lib/toolbar/wand/wand-tool.service.d.ts +39 -124
  478. package/lib/toolbar/wand/wand.service.d.ts +22 -116
  479. package/lib/toolbar/zoom-to-box/zoom-to-box-tool.service.d.ts +17 -37
  480. package/lib/util/mark-for-check.d.ts +11 -0
  481. package/lib/util/supersede.d.ts +53 -0
  482. package/lib/visualization.module.d.ts +18 -39
  483. package/lib/visualizer/floating-drag.directive.d.ts +30 -0
  484. package/lib/visualizer/region-actions.d.ts +54 -0
  485. package/lib/visualizer/region-load.d.ts +27 -0
  486. package/lib/visualizer/spatial-dataset-binder.d.ts +74 -0
  487. package/lib/visualizer/tool-modes.d.ts +49 -0
  488. package/lib/visualizer/viewer-shortcuts.d.ts +71 -0
  489. package/lib/visualizer/visualizer-context-menu.d.ts +55 -0
  490. package/lib/visualizer.component.d.ts +201 -447
  491. package/lib/workers/spatial-math-ops.d.ts +65 -0
  492. package/lib/workers/spatial-math-worker.d.ts +7 -0
  493. package/lib/workers/spatial-math.d.ts +74 -0
  494. package/package.json +12 -3
  495. package/src/lib/styles/_viz-icons-rules.scss +73 -0
  496. package/src/lib/styles/viz-icons.scss +14 -0
  497. package/esm2022/lib/implementations/napari-js/napari-axes-labels.mjs +0 -97
  498. package/esm2022/lib/implementations/napari-js/napari-navigator.mjs +0 -195
  499. package/esm2022/lib/implementations/napari-js/napari-scale-bar.mjs +0 -92
  500. package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-BwP-A11m.mjs +0 -329
  501. package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-BwP-A11m.mjs.map +0 -1
  502. package/lib/implementations/napari-js/napari-axes-labels.d.ts +0 -49
  503. package/lib/implementations/napari-js/napari-navigator.d.ts +0 -72
  504. package/lib/implementations/napari-js/napari-scale-bar.d.ts +0 -35
  505. package/src/lib/assets/cell-detection.svg +0 -37
  506. package/src/lib/assets/click.svg +0 -1
  507. package/src/lib/assets/colormap-luts.json +0 -1
  508. package/src/lib/assets/edit-selection-white.svg +0 -47
  509. package/src/lib/assets/icons/colormap-earth.png +0 -0
  510. package/src/lib/assets/icons/colormap-placeholder.png +0 -0
  511. package/src/lib/assets/icons/colormap-pubu.png +0 -0
  512. package/src/lib/assets/interactive-segmentation-cursor.svg +0 -1
  513. package/src/lib/assets/picture-segmentation.svg +0 -43
  514. package/src/lib/assets/test/download-379.svg +0 -1
  515. package/src/lib/assets/test/download-98.svg +0 -1
  516. package/src/lib/assets/test/json-1.svg +0 -1
  517. package/src/lib/assets/test/load-53.svg +0 -1
  518. package/src/lib/assets/test/mask-44.svg +0 -1
  519. package/src/lib/assets/test/mask-download-44.svg +0 -15
  520. package/src/lib/assets/test/mask-save-44.svg +0 -11
  521. package/src/lib/assets/test/overlay-1.svg +0 -1
  522. package/src/lib/assets/test/overlay-4.svg +0 -1
  523. package/src/lib/assets/test/region-26.svg +0 -1
  524. package/src/lib/assets/test/save-56.svg +0 -1
  525. package/src/lib/assets/test/upload-43.svg +0 -1
@@ -1,124 +1,90 @@
1
- import { Injectable } from '@angular/core';
2
- import { WandService } from './wand.service';
3
- import { masksOverlap, unionMasks } from '../../models/geometry';
4
- import { Region, Polygon } from '../../models/region';
5
- import * as i0 from "@angular/core";
6
- import * as i1 from "./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
  /**
8
- * The wand drawing tool. Owns its own canvas overlay, mouse handlers, and
9
- * stroke accumulator. Reads/writes the shape list via the WandToolHost
10
- * interface so it stays decoupled from PlotlyService internals.
6
+ * The wand drawing tool. Owns its pointer overlay and stroke accumulator
7
+ * (shared with the brush, see {@link MaskStrokeEditor}). Reads/writes regions
8
+ * via its {@link CanvasToolHost} so it stays decoupled from the backends.
11
9
  *
12
- * Lifecycle: PlotlyService injects this service, calls `bindHost(this)` once
13
- * during its own construction, then calls `setMode(true | false, options)` to
14
- * activate/deactivate the tool.
10
+ * A plain class: each backend's `CanvasToolManager` owns one instance and arms
11
+ * it with `activate(host, options)` / `deactivate()`.
15
12
  */
16
- export class WandToolService {
17
- constructor(wandService) {
13
+ export class WandTool {
14
+ /** @param gestureTarget the region store, so each drag is one undo step. */
15
+ constructor(wandService, gestureTarget) {
18
16
  this.wandService = wandService;
19
- this.overlay = null;
20
- this.active = false;
17
+ this.id = 'wand';
18
+ this.overlay = new ToolOverlayCanvas();
21
19
  /**
22
- * Accumulated wand region. Every per-tick patch mask is OR'd into `mask`
23
- * over a bbox that grows with the stroke, so the region keeps expanding
24
- * as the user drags. The accumulator persists across mouseup/mousedown so
25
- * that subsequent strokes extend the *same* region — matching QuPath's
26
- * brush behaviour where the active annotation stays editable until the
27
- * user switches tool.
20
+ * Accumulated wand region. Every per-tick patch mask is OR'd into the stroke
21
+ * over a bbox that grows with the stroke, so the region keeps expanding as
22
+ * the user drags. The accumulator persists across mouseup/mousedown so that
23
+ * subsequent strokes extend the *same* region — matching QuPath's brush
24
+ * behaviour where the active annotation stays editable until the user
25
+ * switches tool.
28
26
  */
29
- this.stroke = null;
30
- /** Id of the region this wand stroke is editing (null = a fresh region). */
31
- this.strokeRegionId = null;
32
- /** Readback ratio/origin signature the active stroke's matrix coords are tied to; a change
33
- * (zoom/pan) invalidates the stroke so it isn't re-committed at a different scale (jit-ui#102). */
34
- this.strokeRatioSig = null;
27
+ this.editor = new MaskStrokeEditor();
35
28
  this.dragging = false;
36
29
  this.options = {};
37
- this.boundMouseDown = (e) => this.onMouseDown(e);
38
- this.boundMouseMove = (e) => this.onMouseMove(e);
39
- this.boundMouseUp = (e) => this.onMouseUp(e);
30
+ this.gesture = new UndoGesture(gestureTarget);
40
31
  }
41
- /** Wire the tool to its host. Must be called once before `setMode(true)`. */
42
- bindHost(host) {
32
+ // ── ICanvasTool ─────────────────────────────────────────────────────
33
+ /** Arm the wand on `host` with `options` (replacing the previous options). */
34
+ activate(host, options = {}) {
43
35
  this.host = host;
44
- }
45
- // ── Public API ──────────────────────────────────────────────────────
46
- /** Toggle the wand on/off. */
47
- setMode(active, options = {}) {
48
- this.active = active;
49
36
  this.options = options;
50
- if (active) {
51
- this.createOverlay();
52
- }
53
- else {
54
- this.destroyOverlay();
55
- }
37
+ this.createOverlay();
38
+ }
39
+ /** Disarm: remove the overlay and drop the active region. */
40
+ deactivate() {
41
+ this.overlay.detach();
42
+ this.resetStroke();
56
43
  }
57
44
  /** Merge new options (e.g. live sensitivity slider updates). */
58
45
  setOptions(options) {
59
46
  this.options = { ...this.options, ...options };
60
47
  }
61
48
  /** Drop the active wand region so the next click starts a new one. */
62
- clearActiveRegion() {
49
+ reset() {
63
50
  this.resetStroke();
64
51
  }
65
52
  // ── Overlay lifecycle ───────────────────────────────────────────────
66
53
  createOverlay() {
67
- const plotEl = this.host.getOverlayContainer();
68
- if (!plotEl || this.overlay)
54
+ const container = this.host.getOverlayContainer();
55
+ if (!container)
69
56
  return;
70
- const canvas = document.createElement('canvas');
71
- canvas.style.position = 'absolute';
72
- canvas.style.top = '0';
73
- canvas.style.left = '0';
74
- canvas.style.width = '100%';
75
- canvas.style.height = '100%';
76
- canvas.style.cursor = 'crosshair';
77
- canvas.style.zIndex = '100';
78
- canvas.width = plotEl.offsetWidth;
79
- canvas.height = plotEl.offsetHeight;
80
- plotEl.appendChild(canvas);
81
- this.overlay = canvas;
82
- canvas.addEventListener('mousedown', this.boundMouseDown);
83
- canvas.addEventListener('mousemove', this.boundMouseMove);
84
- canvas.addEventListener('mouseup', this.boundMouseUp);
85
- canvas.addEventListener('mouseleave', this.boundMouseUp);
57
+ this.overlay.attach(container, {
58
+ down: (e) => this.onPointerDown(e),
59
+ move: (e) => this.onPointerMove(e),
60
+ up: () => this.onPointerUp(),
61
+ });
86
62
  }
87
- destroyOverlay() {
88
- if (!this.overlay)
89
- return;
90
- this.overlay.removeEventListener('mousedown', this.boundMouseDown);
91
- this.overlay.removeEventListener('mousemove', this.boundMouseMove);
92
- this.overlay.removeEventListener('mouseup', this.boundMouseUp);
93
- this.overlay.removeEventListener('mouseleave', this.boundMouseUp);
94
- this.overlay.remove();
95
- this.overlay = null;
96
- this.resetStroke();
97
- }
98
- onMouseDown(e) {
99
- if (e.button !== 0)
100
- return;
63
+ onPointerDown(e) {
101
64
  this.dragging = true;
65
+ this.gesture.begin();
102
66
  this.applyAtClient(e, true);
103
67
  }
104
- onMouseMove(e) {
68
+ onPointerMove(e) {
105
69
  if (!this.dragging)
106
70
  return;
107
71
  if ((e.buttons & 1) === 0) {
108
72
  this.dragging = false;
73
+ this.gesture.end();
109
74
  return;
110
75
  }
111
76
  this.applyAtClient(e, false);
112
77
  }
113
- onMouseUp(_) {
78
+ onPointerUp() {
114
79
  // Stop accumulating from this drag, but keep the region alive so the
115
80
  // next mousedown extends it instead of starting fresh.
116
81
  this.dragging = false;
82
+ this.gesture.end();
117
83
  }
118
84
  resetStroke() {
119
- this.stroke = null;
120
- this.strokeRegionId = null;
85
+ this.editor.reset();
121
86
  this.dragging = false;
87
+ this.gesture.end();
122
88
  }
123
89
  // ── Per-tick stroke logic ───────────────────────────────────────────
124
90
  /**
@@ -129,53 +95,15 @@ export class WandToolService {
129
95
  * exact-match flood fill.
130
96
  */
131
97
  applyAtClient(e, isStart = false) {
132
- if (!this.overlay)
133
- return;
134
- const cached = this.host.getCachedImageData();
135
- if (!cached || cached.frames.length === 0)
98
+ if (!this.overlay.attached)
136
99
  return;
137
- // The current regions (neutral model). Mutated locally across this tick and
100
+ // The current regions (neutral model) are mutated locally across this tick and
138
101
  // committed once via host.setRegions().
139
- const regions = this.host.getRegions();
140
- const transform = this.host.getCoordinateTransform();
141
- if (!transform.isReady())
102
+ const editor = this.editor;
103
+ const tick = editor.beginTick(this.host, e);
104
+ if (!tick)
142
105
  return;
143
- const { x: dataX, y: dataY } = transform.clientToData(e.clientX, e.clientY);
144
- if (!Number.isFinite(dataX) || !Number.isFinite(dataY))
145
- return;
146
- // ratios = [xRatio, yRatio] from both backends. Use the X ratio for the
147
- // column and the Y ratio for the row: they differ when the pixel aspect
148
- // isn't 1:1 (e.g. a non-square OSD viewport), and reusing ratios[0] for
149
- // both would distort the sampled region vertically. Fall back to the X
150
- // ratio if only one was supplied.
151
- const rx = cached.ratios[0] || 1;
152
- const ry = cached.ratios[1] || cached.ratios[0] || 1;
153
- const ox = cached.originX ?? 0;
154
- const oy = cached.originY ?? 0;
155
- // The stroke accumulator is in matrix (viewport-pixel) coordinates tied to the readback's
156
- // ratio/origin. If the view changed (zoom/pan) since the stroke was built, those coords no
157
- // longer mean the same thing — re-committing would rescale the region by the zoom factor
158
- // (jit-ui#102). Drop the stale stroke so a fresh one is built at the current view.
159
- const sig = `${rx},${ry},${ox},${oy}`;
160
- if (this.stroke && this.strokeRatioSig !== sig) {
161
- this.stroke = null;
162
- this.strokeRegionId = null;
163
- }
164
- this.strokeRatioSig = sig;
165
- const matrixX = (dataX - ox) / rx;
166
- const matrixY = (dataY - oy) / ry;
167
- if (matrixX < 0 || matrixX >= cached.width)
168
- return;
169
- if (matrixY < 0 || matrixY >= cached.height)
170
- return;
171
- const frameIdx = this.host.getActiveFrameIndex();
172
- const frame = cached.frames[frameIdx] ?? cached.frames[0];
173
- const wandImage = {
174
- data: frame,
175
- width: cached.width,
176
- height: cached.height,
177
- isGrayscale: cached.isGrayscale,
178
- };
106
+ const { cached, regions, frame, mx: matrixX, my: matrixY } = tick;
179
107
  // Shift = erase (subtract pixels from an existing region).
180
108
  // Cmd/Ctrl alone = simple flood fill (no smoothing/threshold).
181
109
  const erase = e.shiftKey;
@@ -183,76 +111,80 @@ export class WandToolService {
183
111
  ...this.options,
184
112
  simpleMode: this.options.simpleMode || ((e.metaKey || e.ctrlKey) && !erase),
185
113
  };
186
- // If this is the first tick of a new drag and the click is NOT inside the
187
- // current accumulator and NOT inside any existing path-shape, drop the old
188
- // stroke so a brand-new region starts here. Without this, the accumulator
189
- // bbox grows to span both areas and `maskToPolygon` keeps only the largest
190
- // connected blob — making the new click appear to do nothing.
191
- if (isStart && !erase && this.stroke && !this.pointInStroke(matrixX, matrixY)) {
192
- // Will fall through to tryAdoptShapeAt below; if that also misses, a
193
- // fresh stroke is created from the patch.
194
- this.stroke = null;
195
- this.strokeRegionId = null;
114
+ // A new drag that starts outside the current accumulator starts a new region
115
+ // (or adopts the one under the cursor) instead of growing the old stroke's
116
+ // bbox to span both areas.
117
+ if (isStart && !erase && editor.stroke && !editor.contains(matrixX, matrixY)) {
118
+ editor.reset();
196
119
  }
197
- const patch = this.wandService.computePatchMask(wandImage, matrixX, matrixY, opts);
120
+ const patch = this.wandService.computePatchMask(this.wandImage(cached), matrixX, matrixY, opts);
198
121
  if (!patch)
199
122
  return;
200
- const W = patch.size;
201
- const half = (W - 1) / 2;
202
- const px0 = Math.round(matrixX) - half;
203
- const py0 = Math.round(matrixY) - half;
204
- const px1 = px0 + W;
205
- const py1 = py0 + W;
206
- // If there's no active wand region, see if the click landed on an
207
- // existing path-shape — adopt it so this stroke extends (or erases
208
- // from) it instead of creating a new region.
209
- if (!this.stroke) {
210
- this.tryAdoptShapeAt(regions, matrixX, matrixY, rx, ry, cached);
211
- }
123
+ // With no active region, a click on an existing region adopts it so this
124
+ // stroke extends (or erases from) it.
125
+ if (!editor.stroke)
126
+ editor.adoptAt(regions, matrixX, matrixY, frame, cached);
212
127
  // Erasing requires an existing region. Shift-clicking empty space is a
213
128
  // no-op — we don't create a region only to immediately delete from it.
214
- if (erase && !this.stroke)
215
- return;
216
- // Grow the region's accumulated mask only when adding. Erasing never
217
- // expands the region beyond its current bbox.
218
- if (!this.stroke) {
219
- const bx = Math.max(0, px0);
220
- const by = Math.max(0, py0);
221
- const bx1 = Math.min(cached.width, px1);
222
- const by1 = Math.min(cached.height, py1);
223
- const bw = Math.max(0, bx1 - bx);
224
- const bh = Math.max(0, by1 - by);
225
- if (bw === 0 || bh === 0)
226
- return;
227
- this.stroke = { bx, by, bw, bh, mask: new Uint8Array(bw * bh) };
129
+ if (erase && !editor.stroke)
130
+ return;
131
+ if (!this.stampPatch(patch, matrixX, matrixY, erase, cached))
132
+ return;
133
+ // Growing into other regions folds them in (QuPath's merge-on-touch).
134
+ if (!erase)
135
+ editor.mergeTouching(regions, frame, cached);
136
+ editor.commit(regions, frame, this.host, {
137
+ erase,
138
+ defaultLabel: 'Region',
139
+ newRegion: (bounds) => {
140
+ const region = new Region();
141
+ region.bounds = bounds;
142
+ region.color = this.host.getShapeColor();
143
+ // Default class/annotation name, matching the overlay-drawn regions and the
144
+ // Region Editor's "Add" actions so a wand region isn't left unlabeled.
145
+ region.label = 'Region';
146
+ return region;
147
+ },
148
+ });
149
+ }
150
+ /** The visible frame of the readback, as the region grow reads it. */
151
+ wandImage(cached) {
152
+ const frameIdx = this.host.getActiveFrameIndex();
153
+ return {
154
+ data: cached.frames[frameIdx] ?? cached.frames[0],
155
+ width: cached.width,
156
+ height: cached.height,
157
+ isGrayscale: cached.isGrayscale,
158
+ };
159
+ }
160
+ /**
161
+ * OR (add) or AND-NOT (erase) the patch mask, centred on matrix point
162
+ * (cx, cy), into the stroke, growing the stroke to cover it first when
163
+ * adding. False when a fresh stroke has nothing inside the readback.
164
+ */
165
+ stampPatch(patch, cx, cy, erase, cached) {
166
+ const editor = this.editor;
167
+ const W = patch.size;
168
+ const half = (W - 1) / 2;
169
+ // The patch is centred on the clicked pixel (`computePatchMask` floors the same way).
170
+ const px0 = Math.floor(cx) - half;
171
+ const py0 = Math.floor(cy) - half;
172
+ if (!editor.stroke) {
173
+ // A fresh stroke starts at the patch, clipped to the readback.
174
+ const ok = editor.ensureCovers(Math.max(0, px0), Math.max(0, py0), Math.min(cached.width, px0 + W), Math.min(cached.height, py0 + W));
175
+ if (!ok)
176
+ return false;
228
177
  }
229
178
  else if (!erase) {
230
- // Don't clamp the accumulator to the viewport: an adopted region may extend off-screen, and
231
- // clamping here would discard its off-screen part when the stroke grows (jit-ui#102).
232
- const bx = Math.min(this.stroke.bx, px0);
233
- const by = Math.min(this.stroke.by, py0);
234
- const bx1 = Math.max(this.stroke.bx + this.stroke.bw, px1);
235
- const by1 = Math.max(this.stroke.by + this.stroke.bh, py1);
236
- const bw = bx1 - bx;
237
- const bh = by1 - by;
238
- if (bw !== this.stroke.bw || bh !== this.stroke.bh || bx !== this.stroke.bx || by !== this.stroke.by) {
239
- // Reallocate the larger mask and copy the previous mask into it.
240
- const next = new Uint8Array(bw * bh);
241
- const dx = this.stroke.bx - bx;
242
- const dy = this.stroke.by - by;
243
- for (let row = 0; row < this.stroke.bh; row++) {
244
- const srcOff = row * this.stroke.bw;
245
- const dstOff = (row + dy) * bw + dx;
246
- next.set(this.stroke.mask.subarray(srcOff, srcOff + this.stroke.bw), dstOff);
247
- }
248
- this.stroke = { bx, by, bw, bh, mask: next };
249
- }
179
+ // Don't clamp a growing stroke to the viewport: an adopted region may extend
180
+ // off-screen, and clamping would discard that part (jit-ui#102). Erasing never
181
+ // grows the stroke.
182
+ editor.ensureCovers(px0, py0, px0 + W, py0 + W);
250
183
  }
251
184
  // Apply the patch: OR (add) or AND-NOT (erase).
252
- const stroke = this.stroke;
185
+ const stroke = editor.stroke;
253
186
  for (let py = 0; py < W; py++) {
254
- const iy = py0 + py;
255
- const my = iy - stroke.by;
187
+ const my = py0 + py - stroke.by;
256
188
  if (my < 0 || my >= stroke.bh)
257
189
  continue;
258
190
  const srcRow = py * W;
@@ -260,240 +192,13 @@ export class WandToolService {
260
192
  for (let px = 0; px < W; px++) {
261
193
  if (!patch.mask[srcRow + px])
262
194
  continue;
263
- const ix = px0 + px;
264
- const mx = ix - stroke.bx;
195
+ const mx = px0 + px - stroke.bx;
265
196
  if (mx < 0 || mx >= stroke.bw)
266
197
  continue;
267
- if (erase)
268
- stroke.mask[dstRow + mx] = 0;
269
- else
270
- stroke.mask[dstRow + mx] = 1;
198
+ stroke.mask[dstRow + mx] = erase ? 0 : 1;
271
199
  }
272
200
  }
273
- if (!erase) {
274
- // If the grown stroke now overlaps another path-shape, fold those
275
- // shapes into this one and drop them — matching QuPath's
276
- // merge-on-touch behaviour.
277
- this.mergeOverlappingShapes(regions, rx, ry, cached);
278
- }
279
- // Trace the union boundary in image-pixel coords.
280
- const stroke2 = this.stroke;
281
- const poly = this.wandService.maskToPolygon(stroke2.mask, stroke2.bw, stroke2.bh, cached.width, cached.height, stroke2.bx, stroke2.by);
282
- if (!poly) {
283
- // Erased to nothing — remove the shape entirely.
284
- if (erase)
285
- this.dropActiveShape(regions);
286
- return;
287
- }
288
- // Convert from matrix coords back to plot data coords.
289
- const xPlot = poly.xpoints.map((x) => ox + x * rx);
290
- const yPlot = poly.ypoints.map((y) => oy + y * ry);
291
- this.commitStroke(regions, xPlot, yPlot);
292
- }
293
- /** True if (matrixX, matrixY) lies inside the current stroke accumulator. */
294
- pointInStroke(matrixX, matrixY) {
295
- const s = this.stroke;
296
- if (!s)
297
- return false;
298
- const mx = Math.floor(matrixX) - s.bx;
299
- const my = Math.floor(matrixY) - s.by;
300
- if (mx < 0 || my < 0 || mx >= s.bw || my >= s.bh)
301
- return false;
302
- return s.mask[my * s.bw + mx] === 1;
303
- }
304
- /**
305
- * Remove the region referenced by `strokeRegionId` from the region list and
306
- * reset the active stroke — used when an erase stroke deletes every pixel.
307
- */
308
- dropActiveShape(regions) {
309
- if (this.strokeRegionId != null) {
310
- const idx = regions.findIndex((r) => r.id === this.strokeRegionId);
311
- if (idx >= 0) {
312
- regions.splice(idx, 1);
313
- this.host.setRegions(regions);
314
- }
315
- }
316
- this.stroke = null;
317
- this.strokeRegionId = null;
318
- }
319
- /**
320
- * Whether a region can be faithfully rasterized into the wand stroke at the current view
321
- * resolution (rx/ry = data units per matrix pixel). Editing rasterizes the region to the
322
- * viewport grid and re-traces it, so a region whose matrix-space bbox exceeds the rasterizer's
323
- * cap would be clipped/down-quantized and come back rescaled/corrupted (jit-ui#102) — e.g. a
324
- * whole-slide annotation while zoomed out. Skip adopt/merge for those: leave them untouched and
325
- * only edit them near native zoom.
326
- */
327
- fitsForEdit(verts, rx, ry) {
328
- const xs = verts.xpoints;
329
- const ys = verts.ypoints;
330
- let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
331
- for (let i = 0; i < xs.length; i++) {
332
- if (xs[i] < minX)
333
- minX = xs[i];
334
- if (xs[i] > maxX)
335
- maxX = xs[i];
336
- if (ys[i] < minY)
337
- minY = ys[i];
338
- if (ys[i] > maxY)
339
- maxY = ys[i];
340
- }
341
- const w = (maxX - minX) / (rx || 1);
342
- const h = (maxY - minY) / (ry || 1);
343
- return w > 0 && h > 0 && w * h <= 4096 * 4096;
344
- }
345
- /** A region's closed-polygon vertices (image/data coords), or null when it
346
- * isn't a fillable closed polygon (rectangles, open polylines). */
347
- regionVerts(region) {
348
- const b = region?.bounds;
349
- if (b instanceof Polygon && b.closed !== false && b.xpoints.length >= 3) {
350
- return { xpoints: b.xpoints, ypoints: b.ypoints, holes: b.holes };
351
- }
352
- return null;
353
- }
354
- /** Convert a region's hole rings from image/data coords into matrix coords so
355
- * they line up with the stroke accumulator (jit-ui#85). */
356
- holesToMatrix(holes, ox, oy, rx, ry) {
357
- return holes?.map((ring) => ring.map(([x, y]) => [(x - ox) / rx, (y - oy) / ry]));
358
- }
359
- /**
360
- * If (matrixX, matrixY) falls inside an existing region, rasterize it into
361
- * the wand stroke accumulator so subsequent wand input extends it rather than
362
- * starting a new region.
363
- */
364
- tryAdoptShapeAt(regions, matrixX, matrixY, rx, ry, cached) {
365
- if (!regions || regions.length === 0)
366
- return false;
367
- // Most-recently-added regions are on top — check them first.
368
- for (let i = regions.length - 1; i >= 0; i--) {
369
- const verts = this.regionVerts(regions[i]);
370
- if (!verts)
371
- continue;
372
- // Too large to rasterize at this zoom → don't adopt it (editing would rescale/corrupt it).
373
- if (!this.fitsForEdit(verts, rx, ry))
374
- continue;
375
- const ox = cached.originX ?? 0;
376
- const oy = cached.originY ?? 0;
377
- const xs = verts.xpoints.map((x) => (x - ox) / rx);
378
- const ys = verts.ypoints.map((y) => (y - oy) / ry);
379
- const holes = this.holesToMatrix(verts.holes, ox, oy, rx, ry);
380
- // Clicking inside a hole must NOT adopt the donut (it's empty there).
381
- if (!this.wandService.pointInPolygonWithHoles(matrixX, matrixY, xs, ys, holes))
382
- continue;
383
- const raster = this.wandService.rasterizePolygon(xs, ys, cached.width, cached.height, holes);
384
- if (!raster)
385
- continue;
386
- this.stroke = raster;
387
- this.strokeRegionId = regions[i].id ?? null;
388
- return true;
389
- }
390
- return false;
391
- }
392
- /**
393
- * Iterate every region; if its rasterized mask overlaps the wand stroke mask
394
- * by at least one pixel, OR it into the stroke and remove it from the list.
395
- * Called every tick so chained merges resolve. If the wand has no region id
396
- * yet, the merged region's id is adopted so the merged region replaces it.
397
- */
398
- mergeOverlappingShapes(regions, rx, ry, cached) {
399
- if (!this.stroke)
400
- return;
401
- let didMerge = true;
402
- while (didMerge) {
403
- didMerge = false;
404
- for (let i = regions.length - 1; i >= 0; i--) {
405
- const region = regions[i];
406
- if (region.id != null && region.id === this.strokeRegionId)
407
- continue;
408
- const verts = this.regionVerts(region);
409
- if (!verts)
410
- continue;
411
- // Too large to rasterize at this zoom → don't merge it (would rescale/corrupt it).
412
- if (!this.fitsForEdit(verts, rx, ry))
413
- continue;
414
- const ox = cached.originX ?? 0;
415
- const oy = cached.originY ?? 0;
416
- const xs = verts.xpoints.map((x) => (x - ox) / rx);
417
- const ys = verts.ypoints.map((y) => (y - oy) / ry);
418
- // Quick bbox reject before rasterizing.
419
- let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
420
- for (let k = 0; k < xs.length; k++) {
421
- if (xs[k] < minX)
422
- minX = xs[k];
423
- if (xs[k] > maxX)
424
- maxX = xs[k];
425
- if (ys[k] < minY)
426
- minY = ys[k];
427
- if (ys[k] > maxY)
428
- maxY = ys[k];
429
- }
430
- const wx0 = this.stroke.bx, wy0 = this.stroke.by;
431
- const wx1 = wx0 + this.stroke.bw, wy1 = wy0 + this.stroke.bh;
432
- if (maxX < wx0 || minX > wx1 || maxY < wy0 || minY > wy1)
433
- continue;
434
- const holes = this.holesToMatrix(verts.holes, ox, oy, rx, ry);
435
- const raster = this.wandService.rasterizePolygon(xs, ys, cached.width, cached.height, holes);
436
- if (!raster)
437
- continue;
438
- if (!masksOverlap(this.stroke, raster))
439
- continue;
440
- this.stroke = unionMasks(this.stroke, raster);
441
- if (this.strokeRegionId == null) {
442
- this.strokeRegionId = region.id ?? null;
443
- }
444
- regions.splice(i, 1);
445
- didMerge = true;
446
- break;
447
- }
448
- }
449
- }
450
- /**
451
- * Commit the in-progress polygon as a region — a new region on the first tick
452
- * of a stroke, or an in-place replacement of the active region on later ticks
453
- * — then ask the host to render. The store mints an id on the first commit,
454
- * which we adopt so subsequent ticks replace the same region.
455
- */
456
- commitStroke(regions, xPlot, yPlot) {
457
- if (xPlot.length < 3)
458
- return;
459
- const existing = this.strokeRegionId != null
460
- ? regions.find((r) => r.id === this.strokeRegionId) : null;
461
- const poly = new Polygon();
462
- poly.npoints = xPlot.length;
463
- poly.xpoints = xPlot;
464
- poly.ypoints = yPlot;
465
- poly.coordinates = xPlot.map((x, i) => [x, yPlot[i]]);
466
- poly.closed = true;
467
- const region = new Region();
468
- region.bounds = poly;
469
- region.color = this.host.getShapeColor();
470
- if (existing) {
471
- // Preserve identity + class label across the stroke's drag ticks.
472
- region.id = existing.id;
473
- region.name = existing.name;
474
- }
475
- // Default class/annotation name, matching the overlay-drawn regions and the
476
- // Region Editor's "Add" actions so a wand region isn't left unlabeled.
477
- region.label = existing?.label ?? 'Region';
478
- if (this.strokeRegionId == null) {
479
- regions.push(region);
480
- }
481
- else {
482
- const idx = regions.findIndex((r) => r.id === this.strokeRegionId);
483
- if (idx >= 0)
484
- regions[idx] = region;
485
- else
486
- regions.push(region);
487
- }
488
- this.host.setRegions(regions);
489
- // The store assigns an id on the first commit — adopt it.
490
- this.strokeRegionId = region.id ?? this.strokeRegionId;
201
+ return true;
491
202
  }
492
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: WandToolService, deps: [{ token: i1.WandService }], target: i0.ɵɵFactoryTarget.Injectable }); }
493
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: WandToolService, providedIn: 'root' }); }
494
203
  }
495
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: WandToolService, decorators: [{
496
- type: Injectable,
497
- args: [{ providedIn: 'root' }]
498
- }], ctorParameters: () => [{ type: i1.WandService }] });
499
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FuZC10b29sLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL3Rvb2xiYXIvd2FuZC93YW5kLXRvb2wuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTNDLE9BQU8sRUFBMEIsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDckUsT0FBTyxFQUFZLFlBQVksRUFBRSxVQUFVLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUUzRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLHFCQUFxQixDQUFDOzs7QUFrRHREOzs7Ozs7OztHQVFHO0FBRUgsTUFBTSxPQUFPLGVBQWU7SUEyQjFCLFlBQW9CLFdBQXdCO1FBQXhCLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBdkJwQyxZQUFPLEdBQTZCLElBQUksQ0FBQztRQUN6QyxXQUFNLEdBQUcsS0FBSyxDQUFDO1FBQ3ZCOzs7Ozs7O1dBT0c7UUFDSyxXQUFNLEdBQW9CLElBQUksQ0FBQztRQUN2Qyw0RUFBNEU7UUFDcEUsbUJBQWMsR0FBa0IsSUFBSSxDQUFDO1FBQzdDOzRHQUNvRztRQUM1RixtQkFBYyxHQUFrQixJQUFJLENBQUM7UUFDckMsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUNqQixZQUFPLEdBQWdCLEVBQUUsQ0FBQztRQU9oQyxJQUFJLENBQUMsY0FBYyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pELElBQUksQ0FBQyxjQUFjLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDakQsSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMs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QUM5QiwwREFBMEQ7UUFDMUQsSUFBSSxDQUFDLGNBQWMsR0FBRyxNQUFNLENBQUMsRUFBRSxJQUFJLElBQUksQ0FBQyxjQUFjLENBQUM7SUFDekQsQ0FBQzs4R0FyZ0JVLGVBQWU7a0hBQWYsZUFBZSxjQURGLE1BQU07OzJGQUNuQixlQUFlO2tCQUQzQixVQUFVO21CQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgV2FuZEltYWdlLCBXYW5kT3B0aW9ucywgV2FuZFNlcnZpY2UgfSBmcm9tICcuL3dhbmQuc2VydmljZSc7XG5pbXBvcnQgeyBCQm94TWFzaywgbWFza3NPdmVybGFwLCB1bmlvbk1hc2tzIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2dlb21ldHJ5JztcbmltcG9ydCB7IElWaWV3cG9ydEhvc3QsIElSZWdpb25EYXRhSG9zdCB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy9jb29yZGluYXRlLXRyYW5zZm9ybS5jb250cmFjdCc7XG5pbXBvcnQgeyBSZWdpb24sIFBvbHlnb24gfSBmcm9tICcuLi8uLi9tb2RlbHMvcmVnaW9uJztcblxuLyoqXG4gKiBUaGUgcGl4ZWwgZGF0YSBhbmQgZnJhbWUgc3RhdGUgUGxvdGx5U2VydmljZSBjYWNoZXMgZm9yIHNhbXBsaW5nLiBSZXR1cm5lZFxuICogYnkgYFdhbmRUb29sSG9zdC5nZXRDYWNoZWRJbWFnZURhdGEoKWAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2FjaGVkSW1hZ2VEYXRhIHtcbiAgLyoqIDItRCBtYXRyaWNlcywgb25lIHBlciBzdGFjayBmcmFtZSAobGVuZ3RoIDEgZm9yIG5vbi1zdGFjayBpbWFnZXMpLiAqL1xuICBmcmFtZXM6IGFueVtdO1xuICAvKiogSW1hZ2UtcGl4ZWwgd2lkdGggb2YgZWFjaCBmcmFtZSBtYXRyaXguICovXG4gIHdpZHRoOiBudW1iZXI7XG4gIC8qKiBJbWFnZS1waXhlbCBoZWlnaHQgb2YgZWFjaCBmcmFtZSBtYXRyaXguICovXG4gIGhlaWdodDogbnVtYmVyO1xuICAvKipcbiAgICogUGxvdC1kYXRhLWNvb3Jkcy1wZXItaW1hZ2UtcGl4ZWwgYWxvbmcgeCAoYW5kIHkg4oCUIHRoZXkncmUgdGhlIHNhbWVcbiAgICogZm9yIGhlYXRtYXAgYW5kIGltYWdlIHRyYWNlcykuXG4gICAqL1xuICByYXRpb3M6IG51bWJlcltdO1xuICAvKiogV2hldGhlciBlYWNoIGZyYW1lIGlzIGEgMi1EIHNjYWxhciBtYXRyaXggKHRydWUpIG9yIDMtY2hhbm5lbCBSR0IgKGZhbHNlKS4gKi9cbiAgaXNHcmF5c2NhbGU6IGJvb2xlYW47XG4gIC8qKlxuICAgKiBEYXRhLWNvb3JkcyBvZiBtYXRyaXggcGl4ZWwgKDAsMCkuIExldHMgdGhlIG1hdHJpeCBiZSBhICpjcm9wKiBvZiB0aGUgZGF0YVxuICAgKiBzcGFjZSByYXRoZXIgdGhhbiBzdGFydGluZyBhdCB0aGUgb3JpZ2luIOKAlCBlLmcuIHRoZSBPU0QgYmFja2VuZCBzYW1wbGVzIHRoZVxuICAgKiBjdXJyZW50bHkgcmVuZGVyZWQgdmlld3BvcnQsIHNvIHdoZW4gem9vbWVkIGluIHRoZSBtYXRyaXggY292ZXJzIG9ubHkgdGhlXG4gICAqIHZpc2libGUgc3ViLXJlZ2lvbiBhdCBzY3JlZW4gcmVzb2x1dGlvbi4gRGVmYXVsdHMgdG8gMCAoZnVsbC1mcmFtZSBtYXRyaXgsXG4gICAqIGFzIFBsb3RseSBwcm92aWRlcykuIG1hdHJpeEluZGV4ID0gKGRhdGEgLSBvcmlnaW4pIC8gcmF0aW8uXG4gICAqL1xuICBvcmlnaW5YPzogbnVtYmVyO1xuICBvcmlnaW5ZPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIFRoZSBjb2xsYWJvcmF0aW9uIGludGVyZmFjZSB0aGUgd2FuZCB0b29sIG5lZWRzIGZyb20gUGxvdGx5U2VydmljZS5cbiAqXG4gKiBLZWVwaW5nIGl0IGV4cGxpY2l0IG1ha2VzIHRoZSBkZXBlbmRlbmN5IG9uZS13YXk6IFdhbmRUb29sU2VydmljZSBuZXZlclxuICogaW1wb3J0cyBQbG90bHlTZXJ2aWNlIGRpcmVjdGx5LiBQbG90bHlTZXJ2aWNlIHNhdGlzZmllcyB0aGlzIGludGVyZmFjZVxuICogc3RydWN0dXJhbGx5IGFuZCBiaW5kcyBpdHNlbGYgdmlhIGBiaW5kSG9zdCh0aGlzKWAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgV2FuZFRvb2xIb3N0IGV4dGVuZHMgSVZpZXdwb3J0SG9zdCwgSVJlZ2lvbkRhdGFIb3N0IHtcbiAgLyoqIFBpeGVsIGRhdGEgZm9yIHNhbXBsaW5nLiBudWxsIHdoZW4gbm8gaW1hZ2UgaXMgbG9hZGVkIHlldC4gKi9cbiAgZ2V0Q2FjaGVkSW1hZ2VEYXRhKCk6IENhY2hlZEltYWdlRGF0YSB8IG51bGw7XG4gIC8qKiBJbmRleCBvZiB0aGUgY3VycmVudGx5IHZpc2libGUgZnJhbWUgaW4gYSBzdGFjayAoMCBmb3Igbm9uLXN0YWNrKS4gKi9cbiAgZ2V0QWN0aXZlRnJhbWVJbmRleCgpOiBudW1iZXI7XG5cbiAgLyoqIEN1cnJlbnQgaW1hZ2UncyBmaWxlbmFtZSDigJQgc3RhbXBlZCBvbnRvIG5ldyBzaGFwZXMgZm9yIGZpbHRlcmluZy4gKi9cbiAgZ2V0RmlsZU5hbWUoKTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAvKiogRGVmYXVsdCBzdHJva2UgY29sb3VyIGZvciBuZXcgc2hhcGVzLiAqL1xuICBnZXRTaGFwZUNvbG9yKCk6IHN0cmluZztcbn1cblxuLyoqXG4gKiBUaGUgd2FuZCBkcmF3aW5nIHRvb2wuIE93bnMgaXRzIG93biBjYW52YXMgb3ZlcmxheSwgbW91c2UgaGFuZGxlcnMsIGFuZFxuICogc3Ryb2tlIGFjY3VtdWxhdG9yLiBSZWFkcy93cml0ZXMgdGhlIHNoYXBlIGxpc3QgdmlhIHRoZSBXYW5kVG9vbEhvc3RcbiAqIGludGVyZmFjZSBzbyBpdCBzdGF5cyBkZWNvdXBsZWQgZnJvbSBQbG90bHlTZXJ2aWNlIGludGVybmFscy5cbiAqXG4gKiBMaWZlY3ljbGU6IFBsb3RseVNlcnZpY2UgaW5qZWN0cyB0aGlzIHNlcnZpY2UsIGNhbGxzIGBiaW5kSG9zdCh0aGlzKWAgb25jZVxuICogZHVyaW5nIGl0cyBvd24gY29uc3RydWN0aW9uLCB0aGVuIGNhbGxzIGBzZXRNb2RlKHRydWUgfCBmYWxzZSwgb3B0aW9ucylgIHRvXG4gKiBhY3RpdmF0ZS9kZWFjdGl2YXRlIHRoZSB0b29sLlxuICovXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46ICdyb290JyB9KVxuZXhwb3J0IGNsYXNzIFdhbmRUb29sU2VydmljZSB7XG4gIC8vIOKUgOKUgCBUb29sIHN0YXRlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHByaXZhdGUgaG9zdCE6IFdhbmRUb29sSG9zdDtcbiAgcHJpdmF0ZSBvdmVybGF5OiBIVE1MQ2FudmFzRWxlbWVudCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGFjdGl2ZSA9IGZhbHNlO1xuICAvKipcbiAgICogQWNjdW11bGF0ZWQgd2FuZCByZWdpb24uIEV2ZXJ5IHBlci10aWNrIHBhdGNoIG1hc2sgaXMgT1InZCBpbnRvIGBtYXNrYFxuICAgKiBvdmVyIGEgYmJveCB0aGF0IGdyb3dzIHdpdGggdGhlIHN0cm9rZSwgc28gdGhlIHJlZ2lvbiBrZWVwcyBleHBhbmRpbmdcbiAgICogYXMgdGhlIHVzZXIgZHJhZ3MuIFRoZSBhY2N1bXVsYXRvciBwZXJzaXN0cyBhY3Jvc3MgbW91c2V1cC9tb3VzZWRvd24gc29cbiAgICogdGhhdCBzdWJzZXF1ZW50IHN0cm9rZXMgZXh0ZW5kIHRoZSAqc2FtZSogcmVnaW9uIOKAlCBtYXRjaGluZyBRdVBhdGgnc1xuICAgKiBicnVzaCBiZWhhdmlvdXIgd2hlcmUgdGhlIGFjdGl2ZSBhbm5vdGF0aW9uIHN0YXlzIGVkaXRhYmxlIHVudGlsIHRoZVxuICAgKiB1c2VyIHN3aXRjaGVzIHRvb2wuXG4gICAqL1xuICBwcml2YXRlIHN0cm9rZTogQkJveE1hc2sgfCBudWxsID0gbnVsbDtcbiAgLyoqIElkIG9mIHRoZSByZWdpb24gdGhpcyB3YW5kIHN0cm9rZSBpcyBlZGl0aW5nIChudWxsID0gYSBmcmVzaCByZWdpb24pLiAqL1xuICBwcml2YXRlIHN0cm9rZVJlZ2lvbklkOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqIFJlYWRiYWNrIHJhdGlvL29yaWdpbiBzaWduYXR1cmUgdGhlIGFjdGl2ZSBzdHJva2UncyBtYXRyaXggY29vcmRzIGFyZSB0aWVkIHRvOyBhIGNoYW5nZVxuICAgKiAgKHpvb20vcGFuKSBpbnZhbGlkYXRlcyB0aGUgc3Ryb2tlIHNvIGl0IGlzbid0IHJlLWNvbW1pdHRlZCBhdCBhIGRpZmZlcmVudCBzY2FsZSAoaml0LXVpIzEwMikuICovXG4gIHByaXZhdGUgc3Ryb2tlUmF0aW9TaWc6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGRyYWdnaW5nID0gZmFsc2U7XG4gIHByaXZhdGUgb3B0aW9uczogV2FuZE9wdGlvbnMgPSB7fTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGJvdW5kTW91c2VEb3duOiAoZTogTW91c2VFdmVudCkgPT4gdm9pZDtcbiAgcHJpdmF0ZSByZWFkb25seSBib3VuZE1vdXNlTW92ZTogKGU6IE1vdXNlRXZlbnQpID0+IHZvaWQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgYm91bmRNb3VzZVVwOiAoZTogTW91c2VFdmVudCkgPT4gdm9pZDtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHdhbmRTZXJ2aWNlOiBXYW5kU2VydmljZSkge1xuICAgIHRoaXMuYm91bmRNb3VzZURvd24gPSAoZSkgPT4gdGhpcy5vbk1vdXNlRG93bihlKTtcbiAgICB0aGlzLmJvdW5kTW91c2VNb3ZlID0gKGUpID0+IHRoaXMub25Nb3VzZU1vdmUoZSk7XG4gICAgdGhpcy5ib3VuZE1vdXNlVXAgPSAoZSkgPT4gdGhpcy5vbk1vdXNlVXAoZSk7XG4gIH1cblxuICAvKiogV2lyZSB0aGUgdG9vbCB0byBpdHMgaG9zdC4gTXVzdCBiZSBjYWxsZWQgb25jZSBiZWZvcmUgYHNldE1vZGUodHJ1ZSlgLiAqL1xuICBiaW5kSG9zdChob3N0OiBXYW5kVG9vbEhvc3QpIHtcbiAgICB0aGlzLmhvc3QgPSBob3N0O1xuICB9XG5cbiAgLy8g4pSA4pSAIFB1YmxpYyBBUEkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqIFRvZ2dsZSB0aGUgd2FuZCBvbi9vZmYuICovXG4gIHNldE1vZGUoYWN0aXZlOiBib29sZWFuLCBvcHRpb25zOiBXYW5kT3B0aW9ucyA9IHt9KSB7XG4gICAgdGhpcy5hY3RpdmUgPSBhY3RpdmU7XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICBpZiAoYWN0aXZlKSB7XG4gICAgICB0aGlzLmNyZWF0ZU92ZXJsYXkoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5kZXN0cm95T3ZlcmxheSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBNZXJnZSBuZXcgb3B0aW9ucyAoZS5nLiBsaXZlIHNlbnNpdGl2aXR5IHNsaWRlciB1cGRhdGVzKS4gKi9cbiAgc2V0T3B0aW9ucyhvcHRpb25zOiBXYW5kT3B0aW9ucykge1xuICAgIHRoaXMub3B0aW9ucyA9IHsgLi4udGhpcy5vcHRpb25zLCAuLi5vcHRpb25zIH07XG4gIH1cblxuICAvKiogRHJvcCB0aGUgYWN0aXZlIHdhbmQgcmVnaW9uIHNvIHRoZSBuZXh0IGNsaWNrIHN0YXJ0cyBhIG5ldyBvbmUuICovXG4gIGNsZWFyQWN0aXZlUmVnaW9uKCkge1xuICAgIHRoaXMucmVzZXRTdHJva2UoKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBPdmVybGF5IGxpZmVjeWNsZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBwcml2YXRlIGNyZWF0ZU92ZXJsYXkoKSB7XG4gICAgY29uc3QgcGxvdEVsID0gdGhpcy5ob3N0LmdldE92ZXJsYXlDb250YWluZXIoKTtcbiAgICBpZiAoIXBsb3RFbCB8fCB0aGlzLm92ZXJsYXkpIHJldHVybjtcblxuICAgIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgIGNhbnZhcy5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgY2FudmFzLnN0eWxlLnRvcCA9ICcwJztcbiAgICBjYW52YXMuc3R5bGUubGVmdCA9ICcwJztcbiAgICBjYW52YXMuc3R5bGUud2lkdGggPSAnMTAwJSc7XG4gICAgY2FudmFzLnN0eWxlLmhlaWdodCA9ICcxMDAlJztcbiAgICBjYW52YXMuc3R5bGUuY3Vyc29yID0gJ2Nyb3NzaGFpcic7XG4gICAgY2FudmFzLnN0eWxlLnpJbmRleCA9ICcxMDAnO1xuICAgIGNhbnZhcy53aWR0aCA9IHBsb3RFbC5vZmZzZXRXaWR0aDtcbiAgICBjYW52YXMuaGVpZ2h0ID0gcGxvdEVsLm9mZnNldEhlaWdodDtcblxuICAgIHBsb3RFbC5hcHBlbmRDaGlsZChjYW52YXMpO1xuICAgIHRoaXMub3ZlcmxheSA9IGNhbnZhcztcblxuICAgIGNhbnZhcy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCB0aGlzLmJvdW5kTW91c2VEb3duKTtcbiAgICBjYW52YXMuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5ib3VuZE1vdXNlTW92ZSk7XG4gICAgY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLmJvdW5kTW91c2VVcCk7XG4gICAgY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbGVhdmUnLCB0aGlzLmJvdW5kTW91c2VVcCk7XG4gIH1cblxuICBwcml2YXRlIGRlc3Ryb3lPdmVybGF5KCkge1xuICAgIGlmICghdGhpcy5vdmVybGF5KSByZXR1cm47XG4gICAgdGhpcy5vdmVybGF5LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIHRoaXMuYm91bmRNb3VzZURvd24pO1xuICAgIHRoaXMub3ZlcmxheS5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB0aGlzLmJvdW5kTW91c2VNb3ZlKTtcbiAgICB0aGlzLm92ZXJsYXkucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMuYm91bmRNb3VzZVVwKTtcbiAgICB0aGlzLm92ZXJsYXkucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsIHRoaXMuYm91bmRNb3VzZVVwKTtcbiAgICB0aGlzLm92ZXJsYXkucmVtb3ZlKCk7XG4gICAgdGhpcy5vdmVybGF5ID0gbnVsbDtcbiAgICB0aGlzLnJlc2V0U3Ryb2tlKCk7XG4gIH1cblxuICBwcml2YXRlIG9uTW91c2VEb3duKGU6IE1vdXNlRXZlbnQpIHtcbiAgICBpZiAoZS5idXR0b24gIT09IDApIHJldHVybjtcbiAgICB0aGlzLmRyYWdnaW5nID0gdHJ1ZTtcbiAgICB0aGlzLmFwcGx5QXRDbGllbnQoZSwgdHJ1ZSk7XG4gIH1cblxuICBwcml2YXRlIG9uTW91c2VNb3ZlKGU6IE1vdXNlRXZlbnQpIHtcbiAgICBpZiAoIXRoaXMuZHJhZ2dpbmcpIHJldHVybjtcbiAgICBpZiAoKGUuYnV0dG9ucyAmIDEpID09PSAwKSB7XG4gICAgICB0aGlzLmRyYWdnaW5nID0gZmFsc2U7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuYXBwbHlBdENsaWVudChlLCBmYWxzZSk7XG4gIH1cblxuICBwcml2YXRlIG9uTW91c2VVcChfOiBNb3VzZUV2ZW50KSB7XG4gICAgLy8gU3RvcCBhY2N1bXVsYXRpbmcgZnJvbSB0aGlzIGRyYWcsIGJ1dCBrZWVwIHRoZSByZWdpb24gYWxpdmUgc28gdGhlXG4gICAgLy8gbmV4dCBtb3VzZWRvd24gZXh0ZW5kcyBpdCBpbnN0ZWFkIG9mIHN0YXJ0aW5nIGZyZXNoLlxuICAgIHRoaXMuZHJhZ2dpbmcgPSBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzZXRTdHJva2UoKSB7XG4gICAgdGhpcy5zdHJva2UgPSBudWxsO1xuICAgIHRoaXMuc3Ryb2tlUmVnaW9uSWQgPSBudWxsO1xuICAgIHRoaXMuZHJhZ2dpbmcgPSBmYWxzZTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBQZXItdGljayBzdHJva2UgbG9naWMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqXG4gICAqIFNhbXBsZSB0aGUgY2FjaGVkIGltYWdlIGF0IHRoZSBjbGljayBsb2NhdGlvbiwgT1IgKG9yIEFORC1OT1QpIHRoZVxuICAgKiB3YW5kJ3MgcGVyLXRpY2sgcGF0Y2ggbWFzayBpbnRvIHRoZSBhY3RpdmUgcmVnaW9uJ3MgYmJveC1yZWxhdGl2ZSBtYXNrLFxuICAgKiByZS10cmFjZSB0aGUgYm91bmRhcnksIGFuZCB1cGRhdGUgdGhlIGluLXByb2dyZXNzIHNoYXBlIOKAlCBtYXRjaGluZ1xuICAgKiBRdVBhdGgncyBhZGRpdGl2ZSBicnVzaC93YW5kIGJlaGF2aW91ci4gU2hpZnQgPSBlcmFzZS4gQ21kL0N0cmwgPVxuICAgKiBleGFjdC1tYXRjaCBmbG9vZCBmaWxsLlxuICAgKi9cbiAgcHJpdmF0ZSBhcHBseUF0Q2xpZW50KGU6IE1vdXNlRXZlbnQsIGlzU3RhcnQgPSBmYWxzZSkge1xuICAgIGlmICghdGhpcy5vdmVybGF5KSByZXR1cm47XG4gICAgY29uc3QgY2FjaGVkID0gdGhpcy5ob3N0LmdldENhY2hlZEltYWdlRGF0YSgpO1xuICAgIGlmICghY2FjaGVkIHx8IGNhY2hlZC5mcmFtZXMubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICAvLyBUaGUgY3VycmVudCByZWdpb25zIChuZXV0cmFsIG1vZGVsKS4gTXV0YXRlZCBsb2NhbGx5IGFjcm9zcyB0aGlzIHRpY2sgYW5kXG4gICAgLy8gY29tbWl0dGVkIG9uY2UgdmlhIGhvc3Quc2V0UmVnaW9ucygpLlxuICAgIGNvbnN0IHJlZ2lvbnMgPSB0aGlzLmhvc3QuZ2V0UmVnaW9ucygpO1xuXG4gICAgY29uc3QgdHJhbnNmb3JtID0gdGhpcy5ob3N0LmdldENvb3JkaW5hdGVUcmFuc2Zvcm0oKTtcbiAgICBpZiAoIXRyYW5zZm9ybS5pc1JlYWR5KCkpIHJldHVybjtcbiAgICBjb25zdCB7IHg6IGRhdGFYLCB5OiBkYXRhWSB9ID0gdHJhbnNmb3JtLmNsaWVudFRvRGF0YShlLmNsaWVudFgsIGUuY2xpZW50WSk7XG4gICAgaWYgKCFOdW1iZXIuaXNGaW5pdGUoZGF0YVgpIHx8ICFOdW1iZXIuaXNGaW5pdGUoZGF0YVkpKSByZXR1cm47XG5cbiAgICAvLyByYXRpb3MgPSBbeFJhdGlvLCB5UmF0aW9dIGZyb20gYm90aCBiYWNrZW5kcy4gVXNlIHRoZSBYIHJhdGlvIGZvciB0aGVcbiAgICAvLyBjb2x1bW4gYW5kIHRoZSBZIHJhdGlvIGZvciB0aGUgcm93OiB0aGV5IGRpZmZlciB3aGVuIHRoZSBwaXhlbCBhc3BlY3RcbiAgICAvLyBpc24ndCAxOjEgKGUuZy4gYSBub24tc3F1YXJlIE9TRCB2aWV3cG9ydCksIGFuZCByZXVzaW5nIHJhdGlvc1swXSBmb3JcbiAgICAvLyBib3RoIHdvdWxkIGRpc3RvcnQgdGhlIHNhbXBsZWQgcmVnaW9uIHZlcnRpY2FsbHkuIEZhbGwgYmFjayB0byB0aGUgWFxuICAgIC8vIHJhdGlvIGlmIG9ubHkgb25lIHdhcyBzdXBwbGllZC5cbiAgICBjb25zdCByeCA9IGNhY2hlZC5yYXRpb3NbMF0gfHwgMTtcbiAgICBjb25zdCByeSA9IGNhY2hlZC5yYXRpb3NbMV0gfHwgY2FjaGVkLnJhdGlvc1swXSB8fCAxO1xuICAgIGNvbnN0IG94ID0gY2FjaGVkLm9yaWdpblggPz8gMDtcbiAgICBjb25zdCBveSA9IGNhY2hlZC5vcmlnaW5ZID8/IDA7XG4gICAgLy8gVGhlIHN0cm9rZSBhY2N1bXVsYXRvciBpcyBpbiBtYXRyaXggKHZpZXdwb3J0LXBpeGVsKSBjb29yZGluYXRlcyB0aWVkIHRvIHRoZSByZWFkYmFjaydzXG4gICAgLy8gcmF0aW8vb3JpZ2luLiBJZiB0aGUgdmlldyBjaGFuZ2VkICh6b29tL3Bhbikgc2luY2UgdGhlIHN0cm9rZSB3YXMgYnVpbHQsIHRob3NlIGNvb3JkcyBub1xuICAgIC8vIGxvbmdlciBtZWFuIHRoZSBzYW1lIHRoaW5nIOKAlCByZS1jb21taXR0aW5nIHdvdWxkIHJlc2NhbGUgdGhlIHJlZ2lvbiBieSB0aGUgem9vbSBmYWN0b3JcbiAgICAvLyAoaml0LXVpIzEwMikuIERyb3AgdGhlIHN0YWxlIHN0cm9rZSBzbyBhIGZyZXNoIG9uZSBpcyBidWlsdCBhdCB0aGUgY3VycmVudCB2aWV3LlxuICAgIGNvbnN0IHNpZyA9IGAke3J4fSwke3J5fSwke294fSwke295fWA7XG4gICAgaWYgKHRoaXMuc3Ryb2tlICYmIHRoaXMuc3Ryb2tlUmF0aW9TaWcgIT09IHNpZykge1xuICAgICAgdGhpcy5zdHJva2UgPSBudWxsO1xuICAgICAgdGhpcy5zdHJva2VSZWdpb25JZCA9IG51bGw7XG4gICAgfVxuICAgIHRoaXMuc3Ryb2tlUmF0aW9TaWcgPSBzaWc7XG4gICAgY29uc3QgbWF0cml4WCA9IChkYXRhWCAtIG94KSAvIHJ4O1xuICAgIGNvbnN0IG1hdHJpeFkgPSAoZGF0YVkgLSBveSkgLyByeTtcbiAgICBpZiAobWF0cml4WCA8IDAgfHwgbWF0cml4WCA+PSBjYWNoZWQud2lkdGgpIHJldHVybjtcbiAgICBpZiAobWF0cml4WSA8IDAgfHwgbWF0cml4WSA+PSBjYWNoZWQuaGVpZ2h0KSByZXR1cm47XG5cbiAgICBjb25zdCBmcmFtZUlkeCA9IHRoaXMuaG9zdC5nZXRBY3RpdmVGcmFtZUluZGV4KCk7XG4gICAgY29uc3QgZnJhbWUgPSBjYWNoZWQuZnJhbWVzW2ZyYW1lSWR4XSA/PyBjYWNoZWQuZnJhbWVzWzBdO1xuXG4gICAgY29uc3Qgd2FuZEltYWdlOiBXYW5kSW1hZ2UgPSB7XG4gICAgICBkYXRhOiBmcmFtZSxcbiAgICAgIHdpZHRoOiBjYWNoZWQud2lkdGgsXG4gICAgICBoZWlnaHQ6IGNhY2hlZC5oZWlnaHQsXG4gICAgICBpc0dyYXlzY2FsZTogY2FjaGVkLmlzR3JheXNjYWxlLFxuICAgIH07XG4gICAgLy8gU2hpZnQgPSBlcmFzZSAoc3VidHJhY3QgcGl4ZWxzIGZyb20gYW4gZXhpc3RpbmcgcmVnaW9uKS5cbiAgICAvLyBDbWQvQ3RybCBhbG9uZSA9IHNpbXBsZSBmbG9vZCBmaWxsIChubyBzbW9vdGhpbmcvdGhyZXNob2xkKS5cbiAgICBjb25zdCBlcmFzZSA9IGUuc2hpZnRLZXk7XG4gICAgY29uc3Qgb3B0czogV2FuZE9wdGlvbnMgPSB7XG4gICAgICAuLi50aGlzLm9wdGlvbnMsXG4gICAgICBzaW1wbGVNb2RlOiB0aGlzLm9wdGlvbnMuc2ltcGxlTW9kZSB8fCAoKGUubWV0YUtleSB8fCBlLmN0cmxLZXkpICYmICFlcmFzZSksXG4gICAgfTtcblxuICAgIC8vIElmIHRoaXMgaXMgdGhlIGZpcnN0IHRpY2sgb2YgYSBuZXcgZHJhZyBhbmQgdGhlIGNsaWNrIGlzIE5PVCBpbnNpZGUgdGhlXG4gICAgLy8gY3VycmVudCBhY2N1bXVsYXRvciBhbmQgTk9UIGluc2lkZSBhbnkgZXhpc3RpbmcgcGF0aC1zaGFwZSwgZHJvcCB0aGUgb2xkXG4gICAgLy8gc3Ryb2tlIHNvIGEgYnJhbmQtbmV3IHJlZ2lvbiBzdGFydHMgaGVyZS4gV2l0aG91dCB0aGlzLCB0aGUgYWNjdW11bGF0b3JcbiAgICAvLyBiYm94IGdyb3dzIHRvIHNwYW4gYm90aCBhcmVhcyBhbmQgYG1hc2tUb1BvbHlnb25gIGtlZXBzIG9ubHkgdGhlIGxhcmdlc3RcbiAgICAvLyBjb25uZWN0ZWQgYmxvYiDigJQgbWFraW5nIHRoZSBuZXcgY2xpY2sgYXBwZWFyIHRvIGRvIG5vdGhpbmcuXG4gICAgaWYgKGlzU3RhcnQgJiYgIWVyYXNlICYmIHRoaXMuc3Ryb2tlICYmICF0aGlzLnBvaW50SW5TdHJva2UobWF0cml4WCwgbWF0cml4WSkpIHtcbiAgICAgIC8vIFdpbGwgZmFsbCB0aHJvdWdoIHRvIHRyeUFkb3B0U2hhcGVBdCBiZWxvdzsgaWYgdGhhdCBhbHNvIG1pc3NlcywgYVxuICAgICAgLy8gZnJlc2ggc3Ryb2tlIGlzIGNyZWF0ZWQgZnJvbSB0aGUgcGF0Y2guXG4gICAgICB0aGlzLnN0cm9rZSA9IG51bGw7XG4gICAgICB0aGlzLnN0cm9rZVJlZ2lvbklkID0gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBwYXRjaCA9IHRoaXMud2FuZFNlcnZpY2UuY29tcHV0ZVBhdGNoTWFzayh3YW5kSW1hZ2UsIG1hdHJpeFgsIG1hdHJpeFksIG9wdHMpO1xuICAgIGlmICghcGF0Y2gpIHJldHVybjtcblxuICAgIGNvbnN0IFcgPSBwYXRjaC5zaXplO1xuICAgIGNvbnN0IGhhbGYgPSAoVyAtIDEpIC8gMjtcbiAgICBjb25zdCBweDAgPSBNYXRoLnJvdW5kKG1hdHJpeFgpIC0gaGFsZjtcbiAgICBjb25zdCBweTAgPSBNYXRoLnJvdW5kKG1hdHJpeFkpIC0gaGFsZjtcbiAgICBjb25zdCBweDEgPSBweDAgKyBXO1xuICAgIGNvbnN0IHB5MSA9IHB5MCArIFc7XG5cbiAgICAvLyBJZiB0aGVyZSdzIG5vIGFjdGl2ZSB3YW5kIHJlZ2lvbiwgc2VlIGlmIHRoZSBjbGljayBsYW5kZWQgb24gYW5cbiAgICAvLyBleGlzdGluZyBwYXRoLXNoYXBlIOKAlCBhZG9wdCBpdCBzbyB0aGlzIHN0cm9rZSBleHRlbmRzIChvciBlcmFzZXNcbiAgICAvLyBmcm9tKSBpdCBpbnN0ZWFkIG9mIGNyZWF0aW5nIGEgbmV3IHJlZ2lvbi5cbiAgICBpZiAoIXRoaXMuc3Ryb2tlKSB7XG4gICAgICB0aGlzLnRyeUFkb3B0U2hhcGVBdChyZWdpb25zLCBtYXRyaXhYLCBtYXRyaXhZLCByeCwgcnksIGNhY2hlZCk7XG4gICAgfVxuXG4gICAgLy8gRXJhc2luZyByZXF1aXJlcyBhbiBleGlzdGluZyByZWdpb24uIFNoaWZ0LWNsaWNraW5nIGVtcHR5IHNwYWNlIGlzIGFcbiAgICAvLyBuby1vcCDigJQgd2UgZG9uJ3QgY3JlYXRlIGEgcmVnaW9uIG9ubHkgdG8gaW1tZWRpYXRlbHkgZGVsZXRlIGZyb20gaXQuXG4gICAgaWYgKGVyYXNlICYmICF0aGlzLnN0cm9rZSkgcmV0dXJuO1xuXG4gICAgLy8gR3JvdyB0aGUgcmVnaW9uJ3MgYWNjdW11bGF0ZWQgbWFzayBvbmx5IHdoZW4gYWRkaW5nLiBFcmFzaW5nIG5ldmVyXG4gICAgLy8gZXhwYW5kcyB0aGUgcmVnaW9uIGJleW9uZCBpdHMgY3VycmVudCBiYm94LlxuICAgIGlmICghdGhpcy5zdHJva2UpIHtcbiAgICAgIGNvbnN0IGJ4ID0gTWF0aC5tYXgoMCwgcHgwKTtcbiAgICAgIGNvbnN0IGJ5ID0gTWF0aC5tYXgoMCwgcHkwKTtcbiAgICAgIGNvbnN0IGJ4MSA9IE1hdGgubWluKGNhY2hlZC53aWR0aCwgcHgxKTtcbiAgICAgIGNvbnN0IGJ5MSA9IE1hdGgubWluKGNhY2hlZC5oZWlnaHQsIHB5MSk7XG4gICAgICBjb25zdCBidyA9IE1hdGgubWF4KDAsIGJ4MSAtIGJ4KTtcbiAgICAgIGNvbnN0IGJoID0gTWF0aC5tYXgoMCwgYnkxIC0gYnkpO1xuICAgICAgaWYgKGJ3ID09PSAwIHx8IGJoID09PSAwKSByZXR1cm47XG4gICAgICB0aGlzLnN0cm9rZSA9IHsgYngsIGJ5LCBidywgYmgsIG1hc2s6IG5ldyBVaW50OEFycmF5KGJ3ICogYmgpIH07XG4gICAgfSBlbHNlIGlmICghZXJhc2UpIHtcbiAgICAgIC8vIERvbid0IGNsYW1wIHRoZSBhY2N1bXVsYXRvciB0byB0aGUgdmlld3BvcnQ6IGFuIGFkb3B0ZWQgcmVnaW9uIG1heSBleHRlbmQgb2ZmLXNjcmVlbiwgYW5kXG4gICAgICAvLyBjbGFtcGluZyBoZXJlIHdvdWxkIGRpc2NhcmQgaXRzIG9mZi1zY3JlZW4gcGFydCB3aGVuIHRoZSBzdHJva2UgZ3Jvd3MgKGppdC11aSMxMDIpLlxuICAgICAgY29uc3QgYnggPSBNYXRoLm1pbih0aGlzLnN0cm9rZS5ieCwgcHgwKTtcbiAgICAgIGNvbnN0IGJ5ID0gTWF0aC5taW4odGhpcy5zdHJva2UuYnksIHB5MCk7XG4gICAgICBjb25zdCBieDEgPSBNYXRoLm1heCh0aGlzLnN0cm9rZS5ieCArIHRoaXMuc3Ryb2tlLmJ3LCBweDEpO1xuICAgICAgY29uc3QgYnkxID0gTWF0aC5tYXgodGhpcy5zdHJva2UuYnkgKyB0aGlzLnN0cm9rZS5iaCwgcHkxKTtcbiAgICAgIGNvbnN0IGJ3ID0gYngxIC0gYng7XG4gICAgICBjb25zdCBiaCA9IGJ5MSAtIGJ5O1xuICAgICAgaWYgKGJ3ICE9PSB0aGlzLnN0cm9rZS5idyB8fCBiaCAhPT0gdGhpcy5zdHJva2UuYmggfHwgYnggIT09IHRoaXMuc3Ryb2tlLmJ4IHx8IGJ5ICE9PSB0aGlzLnN0cm9rZS5ieSkge1xuICAgICAgICAvLyBSZWFsbG9jYXRlIHRoZSBsYXJnZXIgbWFzayBhbmQgY29weSB0aGUgcHJldmlvdXMgbWFzayBpbnRvIGl0LlxuICAgICAgICBjb25zdCBuZXh0ID0gbmV3IFVpbnQ4QXJyYXkoYncgKiBiaCk7XG4gICAgICAgIGNvbnN0IGR4ID0gdGhpcy5zdHJva2UuYnggLSBieDtcbiAgICAgICAgY29uc3QgZHkgPSB0aGlzLnN0cm9rZS5ieSAtIGJ5O1xuICAgICAgICBmb3IgKGxldCByb3cgPSAwOyByb3cgPCB0aGlzLnN0cm9rZS5iaDsgcm93KyspIHtcbiAgICAgICAgICBjb25zdCBzcmNPZmYgPSByb3cgKiB0aGlzLnN0cm9rZS5idztcbiAgICAgICAgICBjb25zdCBkc3RPZmYgPSAocm93ICsgZHkpICogYncgKyBkeDtcbiAgICAgICAgICBuZXh0LnNldCh0aGlzLnN0cm9rZS5tYXNrLnN1YmFycmF5KHNyY09mZiwgc3JjT2ZmICsgdGhpcy5zdHJva2UuYncpLCBkc3RPZmYpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3Ryb2tlID0geyBieCwgYnksIGJ3LCBiaCwgbWFzazogbmV4dCB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEFwcGx5IHRoZSBwYXRjaDogT1IgKGFkZCkgb3IgQU5ELU5PVCAoZXJhc2UpLlxuICAgIGNvbnN0IHN0cm9rZSA9IHRoaXMuc3Ryb2tlO1xuICAgIGZvciAobGV0IHB5ID0gMDsgcHkgPCBXOyBweSsrKSB7XG4gICAgICBjb25zdCBpeSA9IHB5MCArIHB5O1xuICAgICAgY29uc3QgbXkgPSBpeSAtIHN0cm9rZS5ieTtcbiAgICAgIGlmIChteSA8IDAgfHwgbXkgPj0gc3Ryb2tlLmJoKSBjb250aW51ZTtcbiAgICAgIGNvbnN0IHNyY1JvdyA9IHB5ICogVztcbiAgICAgIGNvbnN0IGRzdFJvdyA9IG15ICogc3Ryb2tlLmJ3O1xuICAgICAgZm9yIChsZXQgcHggPSAwOyBweCA8IFc7IHB4KyspIHtcbiAgICAgICAgaWYgKCFwYXRjaC5tYXNrW3NyY1JvdyArIHB4XSkgY29udGludWU7XG4gICAgICAgIGNvbnN0IGl4ID0gcHgwICsgcHg7XG4gICAgICAgIGNvbnN0IG14ID0gaXggLSBzdHJva2UuYng7XG4gICAgICAgIGlmIChteCA8IDAgfHwgbXggPj0gc3Ryb2tlLmJ3KSBjb250aW51ZTtcbiAgICAgICAgaWYgKGVyYXNlKSBzdHJva2UubWFza1tkc3RSb3cgKyBteF0gPSAwO1xuICAgICAgICBlbHNlIHN0cm9rZS5tYXNrW2RzdFJvdyArIG14XSA9IDE7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFlcmFzZSkge1xuICAgICAgLy8gSWYgdGhlIGdyb3duIHN0cm9rZSBub3cgb3ZlcmxhcHMgYW5vdGhlciBwYXRoLXNoYXBlLCBmb2xkIHRob3NlXG4gICAgICAvLyBzaGFwZXMgaW50byB0aGlzIG9uZSBhbmQgZHJvcCB0aGVtIOKAlCBtYXRjaGluZyBRdVBhdGgnc1xuICAgICAgLy8gbWVyZ2Utb24tdG91Y2ggYmVoYXZpb3VyLlxuICAgICAgdGhpcy5tZXJnZU92ZXJsYXBwaW5nU2hhcGVzKHJlZ2lvbnMsIHJ4LCByeSwgY2FjaGVkKTtcbiAgICB9XG5cbiAgICAvLyBUcmFjZSB0aGUgdW5pb24gYm91bmRhcnkgaW4gaW1hZ2UtcGl4ZWwgY29vcmRzLlxuICAgIGNvbnN0IHN0cm9rZTIgPSB0aGlzLnN0cm9rZSE7XG4gICAgY29uc3QgcG9seSA9IHRoaXMud2FuZFNlcnZpY2UubWFza1RvUG9seWdvbihcbiAgICAgIHN0cm9rZTIubWFzayxcbiAgICAgIHN0cm9rZTIuYncsXG4gICAgICBzdHJva2UyLmJoLFxuICAgICAgY2FjaGVkLndpZHRoLFxuICAgICAgY2FjaGVkLmhlaWdodCxcbiAgICAgIHN0cm9rZTIuYngsXG4gICAgICBzdHJva2UyLmJ5LFxuICAgICk7XG5cbiAgICBpZiAoIXBvbHkpIHtcbiAgICAgIC8vIEVyYXNlZCB0byBub3RoaW5nIOKAlCByZW1vdmUgdGhlIHNoYXBlIGVudGlyZWx5LlxuICAgICAgaWYgKGVyYXNlKSB0aGlzLmRyb3BBY3RpdmVTaGFwZShyZWdpb25zKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBDb252ZXJ0IGZyb20gbWF0cml4IGNvb3JkcyBiYWNrIHRvIHBsb3QgZGF0YSBjb29yZHMuXG4gICAgY29uc3QgeFBsb3QgPSBwb2x5Lnhwb2ludHMubWFwKCh4KSA9PiBveCArIHggKiByeCk7XG4gICAgY29uc3QgeVBsb3QgPSBwb2x5Lnlwb2ludHMubWFwKCh5KSA9PiBveSArIHkgKiByeSk7XG5cbiAgICB0aGlzLmNvbW1pdFN0cm9rZShyZWdpb25zLCB4UGxvdCwgeVBsb3QpO1xuICB9XG5cbiAgLyoqIFRydWUgaWYgKG1hdHJpeFgsIG1hdHJpeFkpIGxpZXMgaW5zaWRlIHRoZSBjdXJyZW50IHN0cm9rZSBhY2N1bXVsYXRvci4gKi9cbiAgcHJpdmF0ZSBwb2ludEluU3Ryb2tlKG1hdHJpeFg6IG51bWJlciwgbWF0cml4WTogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgY29uc3QgcyA9IHRoaXMuc3Ryb2tlO1xuICAgIGlmICghcykgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IG14ID0gTWF0aC5mbG9vcihtYXRyaXhYKSAtIHMuYng7XG4gICAgY29uc3QgbXkgPSBNYXRoLmZsb29yKG1hdHJpeFkpIC0gcy5ieTtcbiAgICBpZiAobXggPCAwIHx8IG15IDwgMCB8fCBteCA+PSBzLmJ3IHx8IG15ID49IHMuYmgpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gcy5tYXNrW215ICogcy5idyArIG14XSA9PT0gMTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgdGhlIHJlZ2lvbiByZWZlcmVuY2VkIGJ5IGBzdHJva2VSZWdpb25JZGAgZnJvbSB0aGUgcmVnaW9uIGxpc3QgYW5kXG4gICAqIHJlc2V0IHRoZSBhY3RpdmUgc3Ryb2tlIOKAlCB1c2VkIHdoZW4gYW4gZXJhc2Ugc3Ryb2tlIGRlbGV0ZXMgZXZlcnkgcGl4ZWwuXG4gICAqL1xuICBwcml2YXRlIGRyb3BBY3RpdmVTaGFwZShyZWdpb25zOiBSZWdpb25bXSkge1xuICAgIGlmICh0aGlzLnN0cm9rZVJlZ2lvbklkICE9IG51bGwpIHtcbiAgICAgIGNvbnN0IGlkeCA9IHJlZ2lvbnMuZmluZEluZGV4KChyKSA9PiByLmlkID09PSB0aGlzLnN0cm9rZVJlZ2lvbklkKTtcbiAgICAgIGlmIChpZHggPj0gMCkge1xuICAgICAgICByZWdpb25zLnNwbGljZShpZHgsIDEpO1xuICAgICAgICB0aGlzLmhvc3Quc2V0UmVnaW9ucyhyZWdpb25zKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5zdHJva2UgPSBudWxsO1xuICAgIHRoaXMuc3Ryb2tlUmVnaW9uSWQgPSBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgYSByZWdpb24gY2FuIGJlIGZhaXRoZnVsbHkgcmFzdGVyaXplZCBpbnRvIHRoZSB3YW5kIHN0cm9rZSBhdCB0aGUgY3VycmVudCB2aWV3XG4gICAqIHJlc29sdXRpb24gKHJ4L3J5ID0gZGF0YSB1bml0cyBwZXIgbWF0cml4IHBpeGVsKS4gRWRpdGluZyByYXN0ZXJpemVzIHRoZSByZWdpb24gdG8gdGhlXG4gICAqIHZpZXdwb3J0IGdyaWQgYW5kIHJlLXRyYWNlcyBpdCwgc28gYSByZWdpb24gd2hvc2UgbWF0cml4LXNwYWNlIGJib3ggZXhjZWVkcyB0aGUgcmFzdGVyaXplcidzXG4gICAqIGNhcCB3b3VsZCBiZSBjbGlwcGVkL2Rvd24tcXVhbnRpemVkIGFuZCBjb21lIGJhY2sgcmVzY2FsZWQvY29ycnVwdGVkIChqaXQtdWkjMTAyKSDigJQgZS5nLiBhXG4gICAqIHdob2xlLXNsaWRlIGFubm90YXRpb24gd2hpbGUgem9vbWVkIG91dC4gU2tpcCBhZG9wdC9tZXJnZSBmb3IgdGhvc2U6IGxlYXZlIHRoZW0gdW50b3VjaGVkIGFuZFxuICAgKiBvbmx5IGVkaXQgdGhlbSBuZWFyIG5hdGl2ZSB6b29tLlxuICAgKi9cbiAgcHJpdmF0ZSBmaXRzRm9yRWRpdChcbiAgICB2ZXJ0czogeyB4cG9pbnRzOiBudW1iZXJbXTsgeXBvaW50czogbnVtYmVyW10gfSxcbiAgICByeDogbnVtYmVyLFxuICAgIHJ5OiBudW1iZXIsXG4gICk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHhzID0gdmVydHMueHBvaW50cztcbiAgICBjb25zdCB5cyA9IHZlcnRzLnlwb2ludHM7XG4gICAgbGV0IG1pblggPSBJbmZpbml0eSwgbWF4WCA9IC1JbmZpbml0eSwgbWluWSA9IEluZmluaXR5LCBtYXhZID0gLUluZmluaXR5O1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICh4c1tpXSA8IG1pblgpIG1pblggPSB4c1tpXTtcbiAgICAgIGlmICh4c1tpXSA+IG1heFgpIG1heFggPSB4c1tpXTtcbiAgICAgIGlmICh5c1tpXSA8IG1pblkpIG1pblkgPSB5c1tpXTtcbiAgICAgIGlmICh5c1tpXSA+IG1heFkpIG1heFkgPSB5c1tpXTtcbiAgICB9XG4gICAgY29uc3QgdyA9IChtYXhYIC0gbWluWCkgLyAocnggfHwgMSk7XG4gICAgY29uc3QgaCA9IChtYXhZIC0gbWluWSkgLyAocnkgfHwgMSk7XG4gICAgcmV0dXJuIHcgPiAwICYmIGggPiAwICYmIHcgKiBoIDw9IDQwOTYgKiA0MDk2O1xuICB9XG5cbiAgLyoqIEEgcmVnaW9uJ3MgY2xvc2VkLXBvbHlnb24gdmVydGljZXMgKGltYWdlL2RhdGEgY29vcmRzKSwgb3IgbnVsbCB3aGVuIGl0XG4gICAqICBpc24ndCBhIGZpbGxhYmxlIGNsb3NlZCBwb2x5Z29uIChyZWN0YW5nbGVzLCBvcGVuIHBvbHlsaW5lcykuICovXG4gIHByaXZhdGUgcmVnaW9uVmVydHMoXG4gICAgcmVnaW9uOiBSZWdpb24sXG4gICk6IHsgeHBvaW50czogbnVtYmVyW107IHlwb2ludHM6IG51bWJlcltdOyBob2xlcz86IG51bWJlcltdW11bXSB9IHwgbnVsbCB7XG4gICAgY29uc3QgYiA9IHJlZ2lvbj8uYm91bmRzO1xuICAgIGlmIChiIGluc3RhbmNlb2YgUG9seWdvbiAmJiBiLmNsb3NlZCAhPT0gZmFsc2UgJiYgYi54cG9pbnRzLmxlbmd0aCA+PSAzKSB7XG4gICAgICByZXR1cm4geyB4cG9pbnRzOiBiLnhwb2ludHMsIHlwb2ludHM6IGIueXBvaW50cywgaG9sZXM6IGIuaG9sZXMgfTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKiogQ29udmVydCBhIHJlZ2lvbidzIGhvbGUgcmluZ3MgZnJvbSBpbWFnZS9kYXRhIGNvb3JkcyBpbnRvIG1hdHJpeCBjb29yZHMgc29cbiAgICogIHRoZXkgbGluZSB1cCB3aXRoIHRoZSBzdHJva2UgYWNjdW11bGF0b3IgKGppdC11aSM4NSkuICovXG4gIHByaXZhdGUgaG9sZXNUb01hdHJpeChcbiAgICBob2xlczogbnVtYmVyW11bXVtdIHwgdW5kZWZpbmVkLCBveDogbnVtYmVyLCBveTogbnVtYmVyLCByeDogbnVtYmVyLCByeTogbnVtYmVyLFxuICApOiBudW1iZXJbXVtdW10gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBob2xlcz8ubWFwKChyaW5nKSA9PiByaW5nLm1hcCgoW3gsIHldKSA9PiBbKHggLSBveCkgLyByeCwgKHkgLSBveSkgLyByeV0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJZiAobWF0cml4WCwgbWF0cml4WSkgZmFsbHMgaW5zaWRlIGFuIGV4aXN0aW5nIHJlZ2lvbiwgcmFzdGVyaXplIGl0IGludG9cbiAgICogdGhlIHdhbmQgc3Ryb2tlIGFjY3VtdWxhdG9yIHNvIHN1YnNlcXVlbnQgd2FuZCBpbnB1dCBleHRlbmRzIGl0IHJhdGhlciB0aGFuXG4gICAqIHN0YXJ0aW5nIGEgbmV3IHJlZ2lvbi5cbiAgICovXG4gIHByaXZhdGUgdHJ5QWRvcHRTaGFwZUF0KFxuICAgIHJlZ2lvbnM6IFJlZ2lvbltdLFxuICAgIG1hdHJpeFg6IG51bWJlcixcbiAgICBtYXRyaXhZOiBudW1iZXIsXG4gICAgcng6IG51bWJlcixcbiAgICByeTogbnVtYmVyLFxuICAgIGNhY2hlZDogQ2FjaGVkSW1hZ2VEYXRhLFxuICApOiBib29sZWFuIHtcbiAgICBpZiAoIXJlZ2lvbnMgfHwgcmVnaW9ucy5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcblxuICAgIC8vIE1vc3QtcmVjZW50bHktYWRkZWQgcmVnaW9ucyBhcmUgb24gdG9wIOKAlCBjaGVjayB0aGVtIGZpcnN0LlxuICAgIGZvciAobGV0IGkgPSByZWdpb25zLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBjb25zdCB2ZXJ0cyA9IHRoaXMucmVnaW9uVmVydHMocmVnaW9uc1tpXSk7XG4gICAgICBpZiAoIXZlcnRzKSBjb250aW51ZTtcbiAgICAgIC8vIFRvbyBsYXJnZSB0byByYXN0ZXJpemUgYXQgdGhpcyB6b29tIOKGkiBkb24ndCBhZG9wdCBpdCAoZWRpdGluZyB3b3VsZCByZXNjYWxlL2NvcnJ1cHQgaXQpLlxuICAgICAgaWYgKCF0aGlzLmZpdHNGb3JFZGl0KHZlcnRzLCByeCwgcnkpKSBjb250aW51ZTtcblxuICAgICAgY29uc3Qgb3ggPSBjYWNoZWQub3JpZ2luWCA/PyAwO1xuICAgICAgY29uc3Qgb3kgPSBjYWNoZWQub3JpZ2luWSA/PyAwO1xuICAgICAgY29uc3QgeHMgPSB2ZXJ0cy54cG9pbnRzLm1hcCgoeCkgPT4gKHggLSBveCkgLyByeCk7XG4gICAgICBjb25zdCB5cyA9IHZlcnRzLnlwb2ludHMubWFwKCh5KSA9PiAoeSAtIG95KSAvIHJ5KTtcbiAgICAgIGNvbnN0IGhvbGVzID0gdGhpcy5ob2xlc1RvTWF0cml4KHZlcnRzLmhvbGVzLCBveCwgb3ksIHJ4LCByeSk7XG5cbiAgICAgIC8vIENsaWNraW5nIGluc2lkZSBhIGhvbGUgbXVzdCBOT1QgYWRvcHQgdGhlIGRvbnV0IChpdCdzIGVtcHR5IHRoZXJlKS5cbiAgICAgIGlmICghdGhpcy53YW5kU2VydmljZS5wb2ludEluUG9seWdvbldpdGhIb2xlcyhtYXRyaXhYLCBtYXRyaXhZLCB4cywgeXMsIGhvbGVzKSkgY29udGludWU7XG5cbiAgICAgIGNvbnN0IHJhc3RlciA9IHRoaXMud2FuZFNlcnZpY2UucmFzdGVyaXplUG9seWdvbih4cywgeXMsIGNhY2hlZC53aWR0aCwgY2FjaGVkLmhlaWdodCwgaG9sZXMpO1xuICAgICAgaWYgKCFyYXN0ZXIpIGNvbnRpbnVlO1xuXG4gICAgICB0aGlzLnN0cm9rZSA9IHJhc3RlcjtcbiAgICAgIHRoaXMuc3Ryb2tlUmVnaW9uSWQgPSByZWdpb25zW2ldLmlkID8/IG51bGw7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEl0ZXJhdGUgZXZlcnkgcmVnaW9uOyBpZiBpdHMgcmFzdGVyaXplZCBtYXNrIG92ZXJsYXBzIHRoZSB3YW5kIHN0cm9rZSBtYXNrXG4gICAqIGJ5IGF0IGxlYXN0IG9uZSBwaXhlbCwgT1IgaXQgaW50byB0aGUgc3Ryb2tlIGFuZCByZW1vdmUgaXQgZnJvbSB0aGUgbGlzdC5cbiAgICogQ2FsbGVkIGV2ZXJ5IHRpY2sgc28gY2hhaW5lZCBtZXJnZXMgcmVzb2x2ZS4gSWYgdGhlIHdhbmQgaGFzIG5vIHJlZ2lvbiBpZFxuICAgKiB5ZXQsIHRoZSBtZXJnZWQgcmVnaW9uJ3MgaWQgaXMgYWRvcHRlZCBzbyB0aGUgbWVyZ2VkIHJlZ2lvbiByZXBsYWNlcyBpdC5cbiAgICovXG4gIHByaXZhdGUgbWVyZ2VPdmVybGFwcGluZ1NoYXBlcyhyZWdpb25zOiBSZWdpb25bXSwgcng6IG51bWJlciwgcnk6IG51bWJlciwgY2FjaGVkOiBDYWNoZWRJbWFnZURhdGEpIHtcbiAgICBpZiAoIXRoaXMuc3Ryb2tlKSByZXR1cm47XG4gICAgbGV0IGRpZE1lcmdlID0gdHJ1ZTtcbiAgICB3aGlsZSAoZGlkTWVyZ2UpIHtcbiAgICAgIGRpZE1lcmdlID0gZmFsc2U7XG4gICAgICBmb3IgKGxldCBpID0gcmVnaW9ucy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBjb25zdCByZWdpb24gPSByZWdpb25zW2ldO1xuICAgICAgICBpZiAocmVnaW9uLmlkICE9IG51bGwgJiYgcmVnaW9uLmlkID09PSB0aGlzLnN0cm9rZVJlZ2lvbklkKSBjb250aW51ZTtcblxuICAgICAgICBjb25zdCB2ZXJ0cyA9IHRoaXMucmVnaW9uVmVydHMocmVnaW9uKTtcbiAgICAgICAgaWYgKCF2ZXJ0cykgY29udGludWU7XG4gICAgICAgIC8vIFRvbyBsYXJnZSB0byByYXN0ZXJpemUgYXQgdGhpcyB6b29tIOKGkiBkb24ndCBtZXJnZSBpdCAod291bGQgcmVzY2FsZS9jb3JydXB0IGl0KS5cbiAgICAgICAgaWYgKCF0aGlzLmZpdHNGb3JFZGl0KHZlcnRzLCByeCwgcnkpKSBjb250aW51ZTtcblxuICAgICAgICBjb25zdCBveCA9IGNhY2hlZC5vcmlnaW5YID8/IDA7XG4gICAgICAgIGNvbnN0IG95ID0gY2FjaGVkLm9yaWdpblkgPz8gMDtcbiAgICAgICAgY29uc3QgeHMgPSB2ZXJ0cy54cG9pbnRzLm1hcCgoeCkgPT4gKHggLSBveCkgLyByeCk7XG4gICAgICAgIGNvbnN0IHlzID0gdmVydHMueXBvaW50cy5tYXAoKHkpID0+ICh5IC0gb3kpIC8gcnkpO1xuXG4gICAgICAgIC8vIFF1aWNrIGJib3ggcmVqZWN0IGJlZm9yZSByYXN0ZXJpemluZy5cbiAgICAgICAgbGV0IG1pblggPSBJbmZpbml0eSwgbWF4WCA9IC1JbmZpbml0eSwgbWluWSA9IEluZmluaXR5LCBtYXhZID0gLUluZmluaXR5O1xuICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IHhzLmxlbmd0aDsgaysrKSB7XG4gICAgICAgICAgaWYgKHhzW2tdIDwgbWluWCkgbWluWCA9IHhzW2tdO1xuICAgICAgICAgIGlmICh4c1trXSA+IG1heFgpIG1heFggPSB4c1trXTtcbiAgICAgICAgICBpZiAoeXNba10gPCBtaW5ZKSBtaW5ZID0geXNba107XG4gICAgICAgICAgaWYgKHlzW2tdID4gbWF4WSkgbWF4WSA9IHlzW2tdO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHd4MCA9IHRoaXMuc3Ryb2tlLmJ4LCB3eTAgPSB0aGlzLnN0cm9rZS5ieTtcbiAgICAgICAgY29uc3Qgd3gxID0gd3gwICsgdGhpcy5zdHJva2UuYncsIHd5MSA9IHd5MCArIHRoaXMuc3Ryb2tlLmJoO1xuICAgICAgICBpZiAobWF4WCA8IHd4MCB8fCBtaW5YID4gd3gxIHx8IG1heFkgPCB3eTAgfHwgbWluWSA+IHd5MSkgY29udGludWU7XG5cbiAgICAgICAgY29uc3QgaG9sZXMgPSB0aGlzLmhvbGVzVG9NYXRyaXgodmVydHMuaG9sZXMsIG94LCBveSwgcngsIHJ5KTtcbiAgICAgICAgY29uc3QgcmFzdGVyID0gdGhpcy53YW5kU2VydmljZS5yYXN0ZXJpemVQb2x5Z29uKHhzLCB5cywgY2FjaGVkLndpZHRoLCBjYWNoZWQuaGVpZ2h0LCBob2xlcyk7XG4gICAgICAgIGlmICghcmFzdGVyKSBjb250aW51ZTtcblxuICAgICAgICBpZiAoIW1hc2tzT3ZlcmxhcCh0aGlzLnN0cm9rZSwgcmFzdGVyKSkgY29udGludWU7XG5cbiAgICAgICAgdGhpcy5zdHJva2UgPSB1bmlvbk1hc2tzKHRoaXMuc3Ryb2tlLCByYXN0ZXIpO1xuXG4gICAgICAgIGlmICh0aGlzLnN0cm9rZVJlZ2lvbklkID09IG51bGwpIHtcbiAgICAgICAgICB0aGlzLnN0cm9rZVJlZ2lvbklkID0gcmVnaW9uLmlkID8/IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgcmVnaW9ucy5zcGxpY2UoaSwgMSk7XG4gICAgICAgIGRpZE1lcmdlID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENvbW1pdCB0aGUgaW4tcHJvZ3Jlc3MgcG9seWdvbiBhcyBhIHJlZ2lvbiDigJQgYSBuZXcgcmVnaW9uIG9uIHRoZSBmaXJzdCB0aWNrXG4gICAqIG9mIGEgc3Ryb2tlLCBvciBhbiBpbi1wbGFjZSByZXBsYWNlbWVudCBvZiB0aGUgYWN0aXZlIHJlZ2lvbiBvbiBsYXRlciB0aWNrc1xuICAgKiDigJQgdGhlbiBhc2sgdGhlIGhvc3QgdG8gcmVuZGVyLiBUaGUgc3RvcmUgbWludHMgYW4gaWQgb24gdGhlIGZpcnN0IGNvbW1pdCxcbiAgICogd2hpY2ggd2UgYWRvcHQgc28gc3Vic2VxdWVudCB0aWNrcyByZXBsYWNlIHRoZSBzYW1lIHJlZ2lvbi5cbiAgICovXG4gIHByaXZhdGUgY29tbWl0U3Ryb2tlKHJlZ2lvbnM6IFJlZ2lvbltdLCB4UGxvdDogbnVtYmVyW10sIHlQbG90OiBudW1iZXJbXSkge1xuICAgIGlmICh4UGxvdC5sZW5ndGggPCAzKSByZXR1cm47XG5cbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuc3Ryb2tlUmVnaW9uSWQgIT0gbnVsbFxuICAgICAgPyByZWdpb25zLmZpbmQoKHIpID0+IHIuaWQgPT09IHRoaXMuc3Ryb2tlUmVnaW9uSWQpIDogbnVsbDtcblxuICAgIGNvbnN0IHBvbHkgPSBuZXcgUG9seWdvbigpO1xuICAgIHBvbHkubnBvaW50cyA9IHhQbG90Lmxlbmd0aDtcbiAgICBwb2x5Lnhwb2ludHMgPSB4UGxvdDtcbiAgICBwb2x5Lnlwb2ludHMgPSB5UGxvdDtcbiAgICBwb2x5LmNvb3JkaW5hdGVzID0geFBsb3QubWFwKCh4LCBpKSA9PiBbeCwgeVBsb3RbaV1dKTtcbiAgICBwb2x5LmNsb3NlZCA9IHRydWU7XG5cbiAgICBjb25zdCByZWdpb24gPSBuZXcgUmVnaW9uKCk7XG4gICAgcmVnaW9uLmJvdW5kcyA9IHBvbHk7XG4gICAgcmVnaW9uLmNvbG9yID0gdGhpcy5ob3N0LmdldFNoYXBlQ29sb3IoKTtcbiAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgIC8vIFByZXNlcnZlIGlkZW50aXR5ICsgY2xhc3MgbGFiZWwgYWNyb3NzIHRoZSBzdHJva2UncyBkcmFnIHRpY2tzLlxuICAgICAgcmVnaW9uLmlkID0gZXhpc3RpbmcuaWQ7XG4gICAgICByZWdpb24ubmFtZSA9IGV4aXN0aW5nLm5hbWU7XG4gICAgfVxuICAgIC8vIERlZmF1bHQgY2xhc3MvYW5ub3RhdGlvbiBuYW1lLCBtYXRjaGluZyB0aGUgb3ZlcmxheS1kcmF3biByZWdpb25zIGFuZCB0aGVcbiAgICAvLyBSZWdpb24gRWRpdG9yJ3MgXCJBZGRcIiBhY3Rpb25zIHNvIGEgd2FuZCByZWdpb24gaXNuJ3QgbGVmdCB1bmxhYmVsZWQuXG4gICAgcmVnaW9uLmxhYmVsID0gZXhpc3Rpbmc/LmxhYmVsID8/ICdSZWdpb24nO1xuXG4gICAgaWYgKHRoaXMuc3Ryb2tlUmVnaW9uSWQgPT0gbnVsbCkge1xuICAgICAgcmVnaW9ucy5wdXNoKHJlZ2lvbik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGlkeCA9IHJlZ2lvbnMuZmluZEluZGV4KChyKSA9PiByLmlkID09PSB0aGlzLnN0cm9rZVJlZ2lvbklkKTtcbiAgICAgIGlmIChpZHggPj0gMCkgcmVnaW9uc1tpZHhdID0gcmVnaW9uO1xuICAgICAgZWxzZSByZWdpb25zLnB1c2gocmVnaW9uKTtcbiAgICB9XG5cbiAgICB0aGlzLmhvc3Quc2V0UmVnaW9ucyhyZWdpb25zKTtcbiAgICAvLyBUaGUgc3RvcmUgYXNzaWducyBhbiBpZCBvbiB0aGUgZmlyc3QgY29tbWl0IOKAlCBhZG9wdCBpdC5cbiAgICB0aGlzLnN0cm9rZVJlZ2lvbklkID0gcmVnaW9uLmlkID8/IHRoaXMuc3Ryb2tlUmVnaW9uSWQ7XG4gIH1cbn1cbiJdfQ==
204
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FuZC10b29sLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL3Rvb2xiYXIvd2FuZC93YW5kLXRvb2wuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNsRSxPQUFPLEVBQUUsV0FBVyxFQUFxQixNQUFNLDBCQUEwQixDQUFDO0FBQzFFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRTdELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQVM3Qzs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxPQUFPLFFBQVE7SUFzQm5CLDRFQUE0RTtJQUM1RSxZQUNtQixXQUF3QixFQUN6QyxhQUF3QztRQUR2QixnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQXZCbEMsT0FBRSxHQUFHLE1BQU0sQ0FBQztRQUtKLFlBQU8sR0FBRyxJQUFJLGlCQUFpQixFQUFFLENBQUM7UUFDbkQ7Ozs7Ozs7V0FPRztRQUNjLFdBQU0sR0FBRyxJQUFJLGdCQUFnQixFQUFFLENBQUM7UUFDekMsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUNqQixZQUFPLEdBQWdCLEVBQUUsQ0FBQztRQVVoQyxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksV0FBVyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFFRCx1RUFBdUU7SUFFdkUsOEVBQThFO0lBQzlFLFFBQVEsQ0FBQyxJQUFvQixFQUFFLFVBQXVCLEVBQUU7UUFDdEQsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFDdkIsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3ZCLENBQUM7SUFFRCw2REFBNkQ7SUFDN0QsVUFBVTtRQUNSLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDdEIsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ3JCLENBQUM7SUFFRCxnRUFBZ0U7SUFDaEUsVUFBVSxDQUFDLE9BQW9CO1FBQzdCLElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsR0FBRyxPQUFPLEVBQUUsQ0FBQztJQUNqRCxDQUFDO0lBRUQsc0VBQXNFO0lBQ3RFLEtBQUs7UUFDSCxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDckIsQ0FBQztJQUVELHVFQUF1RTtJQUUvRCxhQUFhO1FBQ25CLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztRQUNsRCxJQUFJLENBQUMsU0FBUztZQUFFLE9BQU87UUFDdkIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFO1lBQzdCLElBQUksRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7WUFDbEMsSUFBSSxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQztZQUNsQyxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRTtTQUM3QixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sYUFBYSxDQUFDLENBQWU7UUFDbkMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7UUFDckIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNyQixJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBRU8sYUFBYSxDQUFDLENBQWU7UUFDbkMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRO1lBQUUsT0FBTztRQUMzQixJQUFJLENBQUMsQ0FBQyxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMxQixJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQztZQUN0QixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ25CLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVPLFdBQVc7UUFDakIscUVBQXFFO1FBQ3JFLHVEQUF1RDtRQUN2RCxJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQztRQUN0QixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQ3JCLENBQUM7SUFFTyxXQUFXO1FBQ2pCLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7UUFDdEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBRUQsdUVBQXVFO0lBRXZFOzs7Ozs7T0FNRztJQUNLLGFBQWEsQ0FBQyxDQUFlLEVBQUUsT0FBTyxHQUFHLEtBQUs7UUFDcEQsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUTtZQUFFLE9BQU87UUFDbkMsK0VBQStFO1FBQy9FLHdDQUF3QztRQUN4QyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQzNCLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU87UUFDbEIsTUFBTSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLE9BQU8sRUFBRSxHQUFHLElBQUksQ0FBQztRQUVsRSwyREFBMkQ7UUFDM0QsK0RBQStEO1FBQy9ELE1BQU0sS0FBSyxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUM7UUFDekIsTUFBTSxJQUFJLEdBQWdCO1lBQ3hCLEdBQUcsSUFBSSxDQUFDLE9BQU87WUFDZixVQUFVLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO1NBQzVFLENBQUM7UUFFRiw2RUFBNkU7UUFDN0UsMkVBQTJFO1FBQzNFLDJCQUEyQjtRQUMzQixJQUFJLE9BQU8sSUFBSSxDQUFDLEtBQUssSUFBSSxNQUFNLENBQUMsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUM3RSxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDakIsQ0FBQztRQUVELE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2hHLElBQUksQ0FBQyxLQUFLO1lBQUUsT0FBTztRQUVuQix5RUFBeUU7UUFDekUsc0NBQXNDO1FBQ3RDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTTtZQUFFLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBRTdFLHVFQUF1RTtRQUN2RSx1RUFBdUU7UUFDdkUsSUFBSSxLQUFLLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTTtZQUFFLE9BQU87UUFFcEMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQztZQUFFLE9BQU87UUFFckUsc0VBQXNFO1FBQ3RFLElBQUksQ0FBQyxLQUFLO1lBQUUsTUFBTSxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBRXpELE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFO1lBQ3ZDLEtBQUs7WUFDTCxZQUFZLEVBQUUsUUFBUTtZQUN0QixTQUFTLEVBQUUsQ0FBQyxNQUFNLEVBQUUsRUFBRTtnQkFDcEIsTUFBTSxNQUFNLEdBQUcsSUFBSSxNQUFNLEVBQUUsQ0FBQztnQkFDNUIsTUFBTSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7Z0JBQ3ZCLE1BQU0sQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztnQkFDekMsNEVBQTRFO2dCQUM1RSx1RUFBdUU7Z0JBQ3ZFLE1BQU0sQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFDO2dCQUN4QixPQUFPLE1BQU0sQ0FBQztZQUNoQixDQUFDO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELHNFQUFzRTtJQUM5RCxTQUFTLENBQUMsTUFBdUI7UUFDdkMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBQ2pELE9BQU87WUFDTCxJQUFJLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUNqRCxLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUs7WUFDbkIsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNO1lBQ3JCLFdBQVcsRUFBRSxNQUFNLENBQUMsV0FBVztTQUNoQyxDQUFDO0lBQ0osQ0FBQztJQUVEOzs7O09BSUc7SUFDSyxVQUFVLENBQ2hCLEtBQW9CLEVBQ3BCLEVBQVUsRUFDVixFQUFVLEVBQ1YsS0FBYyxFQUNkLE1BQXVCO1FBRXZCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDM0IsTUFBTSxDQUFDLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQztRQUNyQixNQUFNLElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDekIsc0ZBQXNGO1FBQ3RGLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQ2xDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBRWxDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDbkIsK0RBQStEO1lBQy9ELE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQzVCLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUNoQixJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsRUFDaEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFDL0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FDakMsQ0FBQztZQUNGLElBQUksQ0FBQyxFQUFFO2dCQUFFLE9BQU8sS0FBSyxDQUFDO1FBQ3hCLENBQUM7YUFBTSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDbEIsNkVBQTZFO1lBQzdFLCtFQUErRTtZQUMvRSxvQkFBb0I7WUFDcEIsTUFBTSxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ2xELENBQUM7UUFFRCxnREFBZ0Q7UUFDaEQsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQWtCLENBQUM7UUFDekMsS0FBSyxJQUFJLEVBQUUsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDO1lBQzlCLE1BQU0sRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUNoQyxJQUFJLEVBQUUsR0FBRyxDQUFDLElBQUksRUFBRSxJQUFJLE1BQU0sQ0FBQyxFQUFFO2dCQUFFLFNBQVM7WUFDeEMsTUFBTSxNQUFNLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUN0QixNQUFNLE1BQU0sR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUM5QixLQUFLLElBQUksRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUM7Z0JBQzlCLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUM7b0JBQUUsU0FBUztnQkFDdkMsTUFBTSxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDO2dCQUNoQyxJQUFJLEVBQUUsR0FBRyxDQUFDLElBQUksRUFBRSxJQUFJLE1BQU0sQ0FBQyxFQUFFO29CQUFFLFNBQVM7Z0JBQ3hDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDM0MsQ0FBQztRQUNILENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFdhbmRJbWFnZSwgV2FuZE9wdGlvbnMsIFdhbmRQYXRjaE1hc2ssIFdhbmRTZXJ2aWNlIH0gZnJvbSAnLi93YW5kLnNlcnZpY2UnO1xuaW1wb3J0IHsgQkJveE1hc2sgfSBmcm9tICcuLi8uLi9nZW9tZXRyeS9yYXN0ZXInO1xuaW1wb3J0IHsgTWFza1N0cm9rZUVkaXRvciB9IGZyb20gJy4uL3Rvb2wta2l0L21hc2stc3Ryb2tlLWVkaXRvcic7XG5pbXBvcnQgeyBVbmRvR2VzdHVyZSwgVW5kb0dlc3R1cmVUYXJnZXQgfSBmcm9tICcuLi90b29sLWtpdC91bmRvLWdlc3R1cmUnO1xuaW1wb3J0IHsgVG9vbE92ZXJsYXlDYW52YXMgfSBmcm9tICcuLi90b29sLWtpdC90b29sLW92ZXJsYXknO1xuaW1wb3J0IHsgQ2FjaGVkSW1hZ2VEYXRhLCBDYW52YXNUb29sSG9zdCwgSUNhbnZhc1Rvb2wgfSBmcm9tICcuLi90b29sLWtpdC9jYW52YXMtdG9vbCc7XG5pbXBvcnQgeyBSZWdpb24gfSBmcm9tICcuLi8uLi9tb2RlbHMvcmVnaW9uJztcblxuLy8gVGhlIHJlYWRiYWNrIHR5cGUgbGl2ZXMgd2l0aCB0aGUgdG9vbCBjb250cmFjdCBub3c7IHJlLWV4cG9ydGVkIGZvciB0aGVcbi8vIG1vZHVsZXMgdGhhdCBpbXBvcnQgaXQgZnJvbSBoZXJlLlxuZXhwb3J0IHR5cGUgeyBDYWNoZWRJbWFnZURhdGEgfSBmcm9tICcuLi90b29sLWtpdC9jYW52YXMtdG9vbCc7XG5cbi8qKiBAZGVwcmVjYXRlZCBPbmUgaG9zdCBzZXJ2ZXMgZXZlcnkgY2FudmFzIHRvb2w6IHVzZSB7QGxpbmsgQ2FudmFzVG9vbEhvc3R9LiAqL1xuZXhwb3J0IHR5cGUgV2FuZFRvb2xIb3N0ID0gQ2FudmFzVG9vbEhvc3Q7XG5cbi8qKlxuICogVGhlIHdhbmQgZHJhd2luZyB0b29sLiBPd25zIGl0cyBwb2ludGVyIG92ZXJsYXkgYW5kIHN0cm9rZSBhY2N1bXVsYXRvclxuICogKHNoYXJlZCB3aXRoIHRoZSBicnVzaCwgc2VlIHtAbGluayBNYXNrU3Ryb2tlRWRpdG9yfSkuIFJlYWRzL3dyaXRlcyByZWdpb25zXG4gKiB2aWEgaXRzIHtAbGluayBDYW52YXNUb29sSG9zdH0gc28gaXQgc3RheXMgZGVjb3VwbGVkIGZyb20gdGhlIGJhY2tlbmRzLlxuICpcbiAqIEEgcGxhaW4gY2xhc3M6IGVhY2ggYmFja2VuZCdzIGBDYW52YXNUb29sTWFuYWdlcmAgb3ducyBvbmUgaW5zdGFuY2UgYW5kIGFybXNcbiAqIGl0IHdpdGggYGFjdGl2YXRlKGhvc3QsIG9wdGlvbnMpYCAvIGBkZWFjdGl2YXRlKClgLlxuICovXG5leHBvcnQgY2xhc3MgV2FuZFRvb2wgaW1wbGVtZW50cyBJQ2FudmFzVG9vbDxXYW5kT3B0aW9ucz4ge1xuICByZWFkb25seSBpZCA9ICd3YW5kJztcblxuICAvLyDilIDilIAgVG9vbCBzdGF0ZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBwcml2YXRlIGhvc3QhOiBDYW52YXNUb29sSG9zdDtcbiAgcHJpdmF0ZSByZWFkb25seSBvdmVybGF5ID0gbmV3IFRvb2xPdmVybGF5Q2FudmFzKCk7XG4gIC8qKlxuICAgKiBBY2N1bXVsYXRlZCB3YW5kIHJlZ2lvbi4gRXZlcnkgcGVyLXRpY2sgcGF0Y2ggbWFzayBpcyBPUidkIGludG8gdGhlIHN0cm9rZVxuICAgKiBvdmVyIGEgYmJveCB0aGF0IGdyb3dzIHdpdGggdGhlIHN0cm9rZSwgc28gdGhlIHJlZ2lvbiBrZWVwcyBleHBhbmRpbmcgYXNcbiAgICogdGhlIHVzZXIgZHJhZ3MuIFRoZSBhY2N1bXVsYXRvciBwZXJzaXN0cyBhY3Jvc3MgbW91c2V1cC9tb3VzZWRvd24gc28gdGhhdFxuICAgKiBzdWJzZXF1ZW50IHN0cm9rZXMgZXh0ZW5kIHRoZSAqc2FtZSogcmVnaW9uIOKAlCBtYXRjaGluZyBRdVBhdGgncyBicnVzaFxuICAgKiBiZWhhdmlvdXIgd2hlcmUgdGhlIGFjdGl2ZSBhbm5vdGF0aW9uIHN0YXlzIGVkaXRhYmxlIHVudGlsIHRoZSB1c2VyXG4gICAqIHN3aXRjaGVzIHRvb2wuXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGVkaXRvciA9IG5ldyBNYXNrU3Ryb2tlRWRpdG9yKCk7XG4gIHByaXZhdGUgZHJhZ2dpbmcgPSBmYWxzZTtcbiAgcHJpdmF0ZSBvcHRpb25zOiBXYW5kT3B0aW9ucyA9IHt9O1xuXG4gIC8qKiBNYWtlcyBlYWNoIGRyYWcgb25lIHVuZG8gc3RlcCwgaG93ZXZlciBsb25nIHRoZSB1c2VyIHBhdXNlcyAoUlQtMTIpLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGdlc3R1cmU6IFVuZG9HZXN0dXJlO1xuXG4gIC8qKiBAcGFyYW0gZ2VzdHVyZVRhcmdldCB0aGUgcmVnaW9uIHN0b3JlLCBzbyBlYWNoIGRyYWcgaXMgb25lIHVuZG8gc3RlcC4gKi9cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSB3YW5kU2VydmljZTogV2FuZFNlcnZpY2UsXG4gICAgZ2VzdHVyZVRhcmdldD86IFVuZG9HZXN0dXJlVGFyZ2V0IHwgbnVsbCxcbiAgKSB7XG4gICAgdGhpcy5nZXN0dXJlID0gbmV3IFVuZG9HZXN0dXJlKGdlc3R1cmVUYXJnZXQpO1xuICB9XG5cbiAgLy8g4pSA4pSAIElDYW52YXNUb29sIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKiBBcm0gdGhlIHdhbmQgb24gYGhvc3RgIHdpdGggYG9wdGlvbnNgIChyZXBsYWNpbmcgdGhlIHByZXZpb3VzIG9wdGlvbnMpLiAqL1xuICBhY3RpdmF0ZShob3N0OiBDYW52YXNUb29sSG9zdCwgb3B0aW9uczogV2FuZE9wdGlvbnMgPSB7fSkge1xuICAgIHRoaXMuaG9zdCA9IGhvc3Q7XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICB0aGlzLmNyZWF0ZU92ZXJsYXkoKTtcbiAgfVxuXG4gIC8qKiBEaXNhcm06IHJlbW92ZSB0aGUgb3ZlcmxheSBhbmQgZHJvcCB0aGUgYWN0aXZlIHJlZ2lvbi4gKi9cbiAgZGVhY3RpdmF0ZSgpIHtcbiAgICB0aGlzLm92ZXJsYXkuZGV0YWNoKCk7XG4gICAgdGhpcy5yZXNldFN0cm9rZSgpO1xuICB9XG5cbiAgLyoqIE1lcmdlIG5ldyBvcHRpb25zIChlLmcuIGxpdmUgc2Vuc2l0aXZpdHkgc2xpZGVyIHVwZGF0ZXMpLiAqL1xuICBzZXRPcHRpb25zKG9wdGlvbnM6IFdhbmRPcHRpb25zKSB7XG4gICAgdGhpcy5vcHRpb25zID0geyAuLi50aGlzLm9wdGlvbnMsIC4uLm9wdGlvbnMgfTtcbiAgfVxuXG4gIC8qKiBEcm9wIHRoZSBhY3RpdmUgd2FuZCByZWdpb24gc28gdGhlIG5leHQgY2xpY2sgc3RhcnRzIGEgbmV3IG9uZS4gKi9cbiAgcmVzZXQoKSB7XG4gICAgdGhpcy5yZXNldFN0cm9rZSgpO1xuICB9XG5cbiAgLy8g4pSA4pSAIE92ZXJsYXkgbGlmZWN5Y2xlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHByaXZhdGUgY3JlYXRlT3ZlcmxheSgpIHtcbiAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLmhvc3QuZ2V0T3ZlcmxheUNvbnRhaW5lcigpO1xuICAgIGlmICghY29udGFpbmVyKSByZXR1cm47XG4gICAgdGhpcy5vdmVybGF5LmF0dGFjaChjb250YWluZXIsIHtcbiAgICAgIGRvd246IChlKSA9PiB0aGlzLm9uUG9pbnRlckRvd24oZSksXG4gICAgICBtb3ZlOiAoZSkgPT4gdGhpcy5vblBvaW50ZXJNb3ZlKGUpLFxuICAgICAgdXA6ICgpID0+IHRoaXMub25Qb2ludGVyVXAoKSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgb25Qb2ludGVyRG93bihlOiBQb2ludGVyRXZlbnQpIHtcbiAgICB0aGlzLmRyYWdnaW5nID0gdHJ1ZTtcbiAgICB0aGlzLmdlc3R1cmUuYmVnaW4oKTtcbiAgICB0aGlzLmFwcGx5QXRDbGllbnQoZSwgdHJ1ZSk7XG4gIH1cblxuICBwcml2YXRlIG9uUG9pbnRlck1vdmUoZTogUG9pbnRlckV2ZW50KSB7XG4gICAgaWYgKCF0aGlzLmRyYWdnaW5nKSByZXR1cm47XG4gICAgaWYgKChlLmJ1dHRvbnMgJiAxKSA9PT0gMCkge1xuICAgICAgdGhpcy5kcmFnZ2luZyA9IGZhbHNlO1xuICAgICAgdGhpcy5nZXN0dXJlLmVuZCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmFwcGx5QXRDbGllbnQoZSwgZmFsc2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBvblBvaW50ZXJVcCgpIHtcbiAgICAvLyBTdG9wIGFjY3VtdWxhdGluZyBmcm9tIHRoaXMgZHJhZywgYnV0IGtlZXAgdGhlIHJlZ2lvbiBhbGl2ZSBzbyB0aGVcbiAgICAvLyBuZXh0IG1vdXNlZG93biBleHRlbmRzIGl0IGluc3RlYWQgb2Ygc3RhcnRpbmcgZnJlc2guXG4gICAgdGhpcy5kcmFnZ2luZyA9IGZhbHNlO1xuICAgIHRoaXMuZ2VzdHVyZS5lbmQoKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzZXRTdHJva2UoKSB7XG4gICAgdGhpcy5lZGl0b3IucmVzZXQoKTtcbiAgICB0aGlzLmRyYWdnaW5nID0gZmFsc2U7XG4gICAgdGhpcy5nZXN0dXJlLmVuZCgpO1xuICB9XG5cbiAgLy8g4pSA4pSAIFBlci10aWNrIHN0cm9rZSBsb2dpYyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKipcbiAgICogU2FtcGxlIHRoZSBjYWNoZWQgaW1hZ2UgYXQgdGhlIGNsaWNrIGxvY2F0aW9uLCBPUiAob3IgQU5ELU5PVCkgdGhlXG4gICAqIHdhbmQncyBwZXItdGljayBwYXRjaCBtYXNrIGludG8gdGhlIGFjdGl2ZSByZWdpb24ncyBiYm94LXJlbGF0aXZlIG1hc2ssXG4gICAqIHJlLXRyYWNlIHRoZSBib3VuZGFyeSwgYW5kIHVwZGF0ZSB0aGUgaW4tcHJvZ3Jlc3Mgc2hhcGUg4oCUIG1hdGNoaW5nXG4gICAqIFF1UGF0aCdzIGFkZGl0aXZlIGJydXNoL3dhbmQgYmVoYXZpb3VyLiBTaGlmdCA9IGVyYXNlLiBDbWQvQ3RybCA9XG4gICAqIGV4YWN0LW1hdGNoIGZsb29kIGZpbGwuXG4gICAqL1xuICBwcml2YXRlIGFwcGx5QXRDbGllbnQoZTogUG9pbnRlckV2ZW50LCBpc1N0YXJ0ID0gZmFsc2UpIHtcbiAgICBpZiAoIXRoaXMub3ZlcmxheS5hdHRhY2hlZCkgcmV0dXJuO1xuICAgIC8vIFRoZSBjdXJyZW50IHJlZ2lvbnMgKG5ldXRyYWwgbW9kZWwpIGFyZSBtdXRhdGVkIGxvY2FsbHkgYWNyb3NzIHRoaXMgdGljayBhbmRcbiAgICAvLyBjb21taXR0ZWQgb25jZSB2aWEgaG9zdC5zZXRSZWdpb25zKCkuXG4gICAgY29uc3QgZWRpdG9yID0gdGhpcy5lZGl0b3I7XG4gICAgY29uc3QgdGljayA9IGVkaXRvci5iZWdpblRpY2sodGhpcy5ob3N0LCBlKTtcbiAgICBpZiAoIXRpY2spIHJldHVybjtcbiAgICBjb25zdCB7IGNhY2hlZCwgcmVnaW9ucywgZnJhbWUsIG14OiBtYXRyaXhYLCBteTogbWF0cml4WSB9ID0gdGljaztcblxuICAgIC8vIFNoaWZ0ID0gZXJhc2UgKHN1YnRyYWN0IHBpeGVscyBmcm9tIGFuIGV4aXN0aW5nIHJlZ2lvbikuXG4gICAgLy8gQ21kL0N0cmwgYWxvbmUgPSBzaW1wbGUgZmxvb2QgZmlsbCAobm8gc21vb3RoaW5nL3RocmVzaG9sZCkuXG4gICAgY29uc3QgZXJhc2UgPSBlLnNoaWZ0S2V5O1xuICAgIGNvbnN0IG9wdHM6IFdhbmRPcHRpb25zID0ge1xuICAgICAgLi4udGhpcy5vcHRpb25zLFxuICAgICAgc2ltcGxlTW9kZTogdGhpcy5vcHRpb25zLnNpbXBsZU1vZGUgfHwgKChlLm1ldGFLZXkgfHwgZS5jdHJsS2V5KSAmJiAhZXJhc2UpLFxuICAgIH07XG5cbiAgICAvLyBBIG5ldyBkcmFnIHRoYXQgc3RhcnRzIG91dHNpZGUgdGhlIGN1cnJlbnQgYWNjdW11bGF0b3Igc3RhcnRzIGEgbmV3IHJlZ2lvblxuICAgIC8vIChvciBhZG9wdHMgdGhlIG9uZSB1bmRlciB0aGUgY3Vyc29yKSBpbnN0ZWFkIG9mIGdyb3dpbmcgdGhlIG9sZCBzdHJva2Unc1xuICAgIC8vIGJib3ggdG8gc3BhbiBib3RoIGFyZWFzLlxuICAgIGlmIChpc1N0YXJ0ICYmICFlcmFzZSAmJiBlZGl0b3Iuc3Ryb2tlICYmICFlZGl0b3IuY29udGFpbnMobWF0cml4WCwgbWF0cml4WSkpIHtcbiAgICAgIGVkaXRvci5yZXNldCgpO1xuICAgIH1cblxuICAgIGNvbnN0IHBhdGNoID0gdGhpcy53YW5kU2VydmljZS5jb21wdXRlUGF0Y2hNYXNrKHRoaXMud2FuZEltYWdlKGNhY2hlZCksIG1hdHJpeFgsIG1hdHJpeFksIG9wdHMpO1xuICAgIGlmICghcGF0Y2gpIHJldHVybjtcblxuICAgIC8vIFdpdGggbm8gYWN0aXZlIHJlZ2lvbiwgYSBjbGljayBvbiBhbiBleGlzdGluZyByZWdpb24gYWRvcHRzIGl0IHNvIHRoaXNcbiAgICAvLyBzdHJva2UgZXh0ZW5kcyAob3IgZXJhc2VzIGZyb20pIGl0LlxuICAgIGlmICghZWRpdG9yLnN0cm9rZSkgZWRpdG9yLmFkb3B0QXQocmVnaW9ucywgbWF0cml4WCwgbWF0cml4WSwgZnJhbWUsIGNhY2hlZCk7XG5cbiAgICAvLyBFcmFzaW5nIHJlcXVpcmVzIGFuIGV4aXN0aW5nIHJlZ2lvbi4gU2hpZnQtY2xpY2tpbmcgZW1wdHkgc3BhY2UgaXMgYVxuICAgIC8vIG5vLW9wIOKAlCB3ZSBkb24ndCBjcmVhdGUgYSByZWdpb24gb25seSB0byBpbW1lZGlhdGVseSBkZWxldGUgZnJvbSBpdC5cbiAgICBpZiAoZXJhc2UgJiYgIWVkaXRvci5zdHJva2UpIHJldHVybjtcblxuICAgIGlmICghdGhpcy5zdGFtcFBhdGNoKHBhdGNoLCBtYXRyaXhYLCBtYXRyaXhZLCBlcmFzZSwgY2FjaGVkKSkgcmV0dXJuO1xuXG4gICAgLy8gR3Jvd2luZyBpbnRvIG90aGVyIHJlZ2lvbnMgZm9sZHMgdGhlbSBpbiAoUXVQYXRoJ3MgbWVyZ2Utb24tdG91Y2gpLlxuICAgIGlmICghZXJhc2UpIGVkaXRvci5tZXJnZVRvdWNoaW5nKHJlZ2lvbnMsIGZyYW1lLCBjYWNoZWQpO1xuXG4gICAgZWRpdG9yLmNvbW1pdChyZWdpb25zLCBmcmFtZSwgdGhpcy5ob3N0LCB7XG4gICAgICBlcmFzZSxcbiAgICAgIGRlZmF1bHRMYWJlbDogJ1JlZ2lvbicsXG4gICAgICBuZXdSZWdpb246IChib3VuZHMpID0+IHtcbiAgICAgICAgY29uc3QgcmVnaW9uID0gbmV3IFJlZ2lvbigpO1xuICAgICAgICByZWdpb24uYm91bmRzID0gYm91bmRzO1xuICAgICAgICByZWdpb24uY29sb3IgPSB0aGlzLmhvc3QuZ2V0U2hhcGVDb2xvcigpO1xuICAgICAgICAvLyBEZWZhdWx0IGNsYXNzL2Fubm90YXRpb24gbmFtZSwgbWF0Y2hpbmcgdGhlIG92ZXJsYXktZHJhd24gcmVnaW9ucyBhbmQgdGhlXG4gICAgICAgIC8vIFJlZ2lvbiBFZGl0b3IncyBcIkFkZFwiIGFjdGlvbnMgc28gYSB3YW5kIHJlZ2lvbiBpc24ndCBsZWZ0IHVubGFiZWxlZC5cbiAgICAgICAgcmVnaW9uLmxhYmVsID0gJ1JlZ2lvbic7XG4gICAgICAgIHJldHVybiByZWdpb247XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqIFRoZSB2aXNpYmxlIGZyYW1lIG9mIHRoZSByZWFkYmFjaywgYXMgdGhlIHJlZ2lvbiBncm93IHJlYWRzIGl0LiAqL1xuICBwcml2YXRlIHdhbmRJbWFnZShjYWNoZWQ6IENhY2hlZEltYWdlRGF0YSk6IFdhbmRJbWFnZSB7XG4gICAgY29uc3QgZnJhbWVJZHggPSB0aGlzLmhvc3QuZ2V0QWN0aXZlRnJhbWVJbmRleCgpO1xuICAgIHJldHVybiB7XG4gICAgICBkYXRhOiBjYWNoZWQuZnJhbWVzW2ZyYW1lSWR4XSA/PyBjYWNoZWQuZnJhbWVzWzBdLFxuICAgICAgd2lkdGg6IGNhY2hlZC53aWR0aCxcbiAgICAgIGhlaWdodDogY2FjaGVkLmhlaWdodCxcbiAgICAgIGlzR3JheXNjYWxlOiBjYWNoZWQuaXNHcmF5c2NhbGUsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPUiAoYWRkKSBvciBBTkQtTk9UIChlcmFzZSkgdGhlIHBhdGNoIG1hc2ssIGNlbnRyZWQgb24gbWF0cml4IHBvaW50XG4gICAqIChjeCwgY3kpLCBpbnRvIHRoZSBzdHJva2UsIGdyb3dpbmcgdGhlIHN0cm9rZSB0byBjb3ZlciBpdCBmaXJzdCB3aGVuXG4gICAqIGFkZGluZy4gRmFsc2Ugd2hlbiBhIGZyZXNoIHN0cm9rZSBoYXMgbm90aGluZyBpbnNpZGUgdGhlIHJlYWRiYWNrLlxuICAgKi9cbiAgcHJpdmF0ZSBzdGFtcFBhdGNoKFxuICAgIHBhdGNoOiBXYW5kUGF0Y2hNYXNrLFxuICAgIGN4OiBudW1iZXIsXG4gICAgY3k6IG51bWJlcixcbiAgICBlcmFzZTogYm9vbGVhbixcbiAgICBjYWNoZWQ6IENhY2hlZEltYWdlRGF0YSxcbiAgKTogYm9vbGVhbiB7XG4gICAgY29uc3QgZWRpdG9yID0gdGhpcy5lZGl0b3I7XG4gICAgY29uc3QgVyA9IHBhdGNoLnNpemU7XG4gICAgY29uc3QgaGFsZiA9IChXIC0gMSkgLyAyO1xuICAgIC8vIFRoZSBwYXRjaCBpcyBjZW50cmVkIG9uIHRoZSBjbGlja2VkIHBpeGVsIChgY29tcHV0ZVBhdGNoTWFza2AgZmxvb3JzIHRoZSBzYW1lIHdheSkuXG4gICAgY29uc3QgcHgwID0gTWF0aC5mbG9vcihjeCkgLSBoYWxmO1xuICAgIGNvbnN0IHB5MCA9IE1hdGguZmxvb3IoY3kpIC0gaGFsZjtcblxuICAgIGlmICghZWRpdG9yLnN0cm9rZSkge1xuICAgICAgLy8gQSBmcmVzaCBzdHJva2Ugc3RhcnRzIGF0IHRoZSBwYXRjaCwgY2xpcHBlZCB0byB0aGUgcmVhZGJhY2suXG4gICAgICBjb25zdCBvayA9IGVkaXRvci5lbnN1cmVDb3ZlcnMoXG4gICAgICAgIE1hdGgubWF4KDAsIHB4MCksXG4gICAgICAgIE1hdGgubWF4KDAsIHB5MCksXG4gICAgICAgIE1hdGgubWluKGNhY2hlZC53aWR0aCwgcHgwICsgVyksXG4gICAgICAgIE1hdGgubWluKGNhY2hlZC5oZWlnaHQsIHB5MCArIFcpLFxuICAgICAgKTtcbiAgICAgIGlmICghb2spIHJldHVybiBmYWxzZTtcbiAgICB9IGVsc2UgaWYgKCFlcmFzZSkge1xuICAgICAgLy8gRG9uJ3QgY2xhbXAgYSBncm93aW5nIHN0cm9rZSB0byB0aGUgdmlld3BvcnQ6IGFuIGFkb3B0ZWQgcmVnaW9uIG1heSBleHRlbmRcbiAgICAgIC8vIG9mZi1zY3JlZW4sIGFuZCBjbGFtcGluZyB3b3VsZCBkaXNjYXJkIHRoYXQgcGFydCAoaml0LXVpIzEwMikuIEVyYXNpbmcgbmV2ZXJcbiAgICAgIC8vIGdyb3dzIHRoZSBzdHJva2UuXG4gICAgICBlZGl0b3IuZW5zdXJlQ292ZXJzKHB4MCwgcHkwLCBweDAgKyBXLCBweTAgKyBXKTtcbiAgICB9XG5cbiAgICAvLyBBcHBseSB0aGUgcGF0Y2g6IE9SIChhZGQpIG9yIEFORC1OT1QgKGVyYXNlKS5cbiAgICBjb25zdCBzdHJva2UgPSBlZGl0b3Iuc3Ryb2tlIGFzIEJCb3hNYXNrO1xuICAgIGZvciAobGV0IHB5ID0gMDsgcHkgPCBXOyBweSsrKSB7XG4gICAgICBjb25zdCBteSA9IHB5MCArIHB5IC0gc3Ryb2tlLmJ5O1xuICAgICAgaWYgKG15IDwgMCB8fCBteSA+PSBzdHJva2UuYmgpIGNvbnRpbnVlO1xuICAgICAgY29uc3Qgc3JjUm93ID0gcHkgKiBXO1xuICAgICAgY29uc3QgZHN0Um93ID0gbXkgKiBzdHJva2UuYnc7XG4gICAgICBmb3IgKGxldCBweCA9IDA7IHB4IDwgVzsgcHgrKykge1xuICAgICAgICBpZiAoIXBhdGNoLm1hc2tbc3JjUm93ICsgcHhdKSBjb250aW51ZTtcbiAgICAgICAgY29uc3QgbXggPSBweDAgKyBweCAtIHN0cm9rZS5ieDtcbiAgICAgICAgaWYgKG14IDwgMCB8fCBteCA+PSBzdHJva2UuYncpIGNvbnRpbnVlO1xuICAgICAgICBzdHJva2UubWFza1tkc3RSb3cgKyBteF0gPSBlcmFzZSA/IDAgOiAxO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuIl19