@jax-data-science/sci-image-visualizer 0.8.3 → 0.10.0

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