@1agh/maude 0.28.1 → 0.29.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 (339) hide show
  1. package/README.md +2 -2
  2. package/{plugins/design/dev-server → apps/studio}/ai-banner.tsx +1 -1
  3. package/{plugins/design/dev-server → apps/studio}/annotations-context-toolbar.tsx +285 -5
  4. package/{plugins/design/dev-server → apps/studio}/annotations-layer.tsx +1206 -119
  5. package/{plugins/design/dev-server → apps/studio}/api.ts +486 -32
  6. package/{plugins/design/dev-server → apps/studio}/artboard-activity-overlay.tsx +1 -1
  7. package/{plugins/design/dev-server → apps/studio}/artboard-marquee.tsx +1 -1
  8. package/apps/studio/bin/_motion-sample-playwright.mjs +129 -0
  9. package/{plugins/design/dev-server → apps/studio}/bin/canvas-edit.sh +1 -1
  10. package/{plugins/design/dev-server → apps/studio}/bin/draw-proof.sh +37 -2
  11. package/{plugins/design/dev-server → apps/studio}/bin/preflight.sh +1 -1
  12. package/apps/studio/bin/read-annotations.mjs +438 -0
  13. package/apps/studio/bin/read-annotations.sh +11 -0
  14. package/{plugins/design/dev-server → apps/studio}/bin/runtime-health.sh +1 -1
  15. package/{plugins/design/dev-server → apps/studio}/bin/screenshot.sh +62 -2
  16. package/{plugins/design/dev-server → apps/studio}/bin/server-up.sh +9 -3
  17. package/apps/studio/bin/to-lottie-verify.html +68 -0
  18. package/apps/studio/bin/to-lottie.sh +128 -0
  19. package/{plugins/design/dev-server → apps/studio}/build.ts +5 -3
  20. package/{plugins/design/dev-server → apps/studio}/canvas-arrowheads.ts +1 -1
  21. package/{plugins/design/dev-server → apps/studio}/canvas-comment-mount.tsx +1 -1
  22. package/apps/studio/canvas-create.ts +104 -0
  23. package/{plugins/design/dev-server → apps/studio}/canvas-cursors.ts +46 -12
  24. package/{plugins/design/dev-server → apps/studio}/canvas-icons.tsx +60 -1
  25. package/{plugins/design/dev-server → apps/studio}/canvas-lib-inline.ts +1 -1
  26. package/{plugins/design/dev-server → apps/studio}/canvas-lib-resolver.ts +1 -1
  27. package/{plugins/design/dev-server → apps/studio}/canvas-lib.tsx +31 -12
  28. package/{plugins/design/dev-server → apps/studio}/canvas-shell.tsx +56 -41
  29. package/{plugins/design/dev-server → apps/studio}/client/app.jsx +1713 -530
  30. package/apps/studio/client/canvas-url.js +81 -0
  31. package/{plugins/design/dev-server → apps/studio}/client/comments-overlay.css +41 -27
  32. package/{plugins/design/dev-server → apps/studio}/client/index.html +2 -1
  33. package/apps/studio/client/styles/1-tokens-maude.css +296 -0
  34. package/apps/studio/client/styles/3-shell-maude.css +459 -0
  35. package/{plugins/design/dev-server → apps/studio}/client/styles/3-shell.css +129 -0
  36. package/apps/studio/client/styles/4-components-maude.css +74 -0
  37. package/{plugins/design/dev-server → apps/studio}/client/styles/4-components.css +357 -34
  38. package/apps/studio/client/styles/5-maude-overrides.css +123 -0
  39. package/{plugins/design/dev-server → apps/studio}/client/styles/_index.css +9 -0
  40. package/{plugins/design/dev-server → apps/studio}/client/styles.css +1 -1
  41. package/apps/studio/client/tour/overlay.jsx +191 -0
  42. package/apps/studio/client/tour/usage-tour.js +35 -0
  43. package/apps/studio/client/whats-new-seen.js +52 -0
  44. package/apps/studio/client/whats-new.jsx +250 -0
  45. package/{plugins/design/dev-server → apps/studio}/commands/annotation-strokes-command.ts +1 -1
  46. package/{plugins/design/dev-server → apps/studio}/commands/equal-spacing-command.ts +1 -1
  47. package/{plugins/design/dev-server → apps/studio}/commands/move-artboards-command.ts +1 -1
  48. package/{plugins/design/dev-server → apps/studio}/comments-overlay.tsx +25 -6
  49. package/{plugins/design/dev-server → apps/studio}/context-menu.tsx +1 -1
  50. package/{plugins/design/dev-server → apps/studio}/contextual-toolbar.tsx +4 -7
  51. package/{plugins/design/dev-server → apps/studio}/cursors-overlay.tsx +1 -1
  52. package/apps/studio/dist/client.bundle.js +22825 -0
  53. package/apps/studio/dist/comment-mount.js +1960 -0
  54. package/apps/studio/dist/styles.css +5695 -0
  55. package/{plugins/design/dev-server → apps/studio}/dom-selection.ts +75 -4
  56. package/apps/studio/draw/animate.ts +333 -0
  57. package/{plugins/design/dev-server → apps/studio}/draw/brush.ts +1 -1
  58. package/{plugins/design/dev-server → apps/studio}/draw/composition.ts +1 -1
  59. package/{plugins/design/dev-server → apps/studio}/draw/geometry.ts +1 -1
  60. package/{plugins/design/dev-server → apps/studio}/draw/index.ts +4 -1
  61. package/{plugins/design/dev-server → apps/studio}/draw/layout.ts +1 -1
  62. package/apps/studio/draw/morph.ts +204 -0
  63. package/{plugins/design/dev-server → apps/studio}/draw/optimize.ts +1 -1
  64. package/{plugins/design/dev-server → apps/studio}/draw/palette.ts +1 -1
  65. package/{plugins/design/dev-server → apps/studio}/draw/primitives.ts +1 -1
  66. package/apps/studio/draw/serialize-animate.ts +324 -0
  67. package/{plugins/design/dev-server → apps/studio}/draw/serialize.ts +9 -3
  68. package/apps/studio/draw/test/animate.test.ts +172 -0
  69. package/apps/studio/draw/test/morph.test.ts +107 -0
  70. package/apps/studio/draw/test/serialize-animate.test.ts +142 -0
  71. package/{plugins/design/dev-server → apps/studio}/equal-spacing-detector.ts +1 -1
  72. package/{plugins/design/dev-server → apps/studio}/equal-spacing-handles.tsx +7 -29
  73. package/{plugins/design/dev-server → apps/studio}/export-dialog.tsx +13 -1
  74. package/{plugins/design/dev-server → apps/studio}/http.ts +102 -1
  75. package/{plugins/design/dev-server → apps/studio}/input-router.tsx +8 -1
  76. package/{plugins/design/dev-server → apps/studio}/inspect.ts +20 -3
  77. package/{plugins/design/dev-server → apps/studio}/marquee-overlay.tsx +5 -2
  78. package/{plugins/design/dev-server → apps/studio}/participants-chrome.tsx +1 -1
  79. package/{plugins/design/dev-server → apps/studio}/paths.ts +15 -11
  80. package/{plugins/design/dev-server → apps/studio}/server.ts +18 -0
  81. package/{plugins/design/dev-server → apps/studio}/sync/index.ts +1 -1
  82. package/{plugins/design/dev-server → apps/studio}/test/annotations-layer.test.ts +63 -0
  83. package/{plugins/design/dev-server → apps/studio}/test/annotations-roundtrip.test.ts +97 -0
  84. package/apps/studio/test/annotations-text-format.test.ts +396 -0
  85. package/apps/studio/test/asset-api.test.ts +149 -0
  86. package/apps/studio/test/canvas-create-api.test.ts +361 -0
  87. package/{plugins/design/dev-server → apps/studio}/test/canvas-cursors.test.ts +2 -0
  88. package/{plugins/design/dev-server → apps/studio}/test/canvas-lib-resolver.test.ts +1 -1
  89. package/apps/studio/test/canvas-media-drop.test.ts +158 -0
  90. package/{plugins/design/dev-server → apps/studio}/test/canvas-origin-gate.test.ts +17 -1
  91. package/apps/studio/test/canvas-url.test.ts +99 -0
  92. package/apps/studio/test/index-data-canvas-ds.test.ts +97 -0
  93. package/apps/studio/test/motion-sample.test.ts +35 -0
  94. package/{plugins/design/dev-server → apps/studio}/test/perf-harness.ts +1 -1
  95. package/{plugins/design/dev-server → apps/studio}/test/phase-3.6-smoke.test.ts +3 -1
  96. package/apps/studio/test/read-annotations.test.ts +409 -0
  97. package/{plugins/design/dev-server → apps/studio}/test/sanitize-annotation-svg.test.ts +108 -2
  98. package/{plugins/design/dev-server → apps/studio}/test/shared-doc-convergence.test.ts +1 -1
  99. package/apps/studio/test/tour-overlay.test.tsx +56 -0
  100. package/{plugins/design/dev-server → apps/studio}/test/use-annotation-resize.test.ts +43 -0
  101. package/{plugins/design/dev-server → apps/studio}/test/use-tool-mode.test.tsx +4 -1
  102. package/apps/studio/test/whats-new.test.ts +101 -0
  103. package/apps/studio/text-imports.d.ts +9 -0
  104. package/{plugins/design/dev-server → apps/studio}/tool-palette.tsx +4 -69
  105. package/{plugins/design/dev-server → apps/studio}/undo-hud.tsx +1 -1
  106. package/{plugins/design/dev-server → apps/studio}/undo-stack.ts +1 -1
  107. package/{plugins/design/dev-server → apps/studio}/use-agent-presence.tsx +1 -1
  108. package/{plugins/design/dev-server → apps/studio}/use-annotation-resize.tsx +40 -7
  109. package/{plugins/design/dev-server → apps/studio}/use-annotation-selection.tsx +1 -1
  110. package/{plugins/design/dev-server → apps/studio}/use-annotations-visibility.tsx +1 -1
  111. package/{plugins/design/dev-server → apps/studio}/use-artboard-drag.tsx +1 -1
  112. package/{plugins/design/dev-server → apps/studio}/use-canvas-activity.tsx +1 -1
  113. package/apps/studio/use-canvas-media-drop.tsx +343 -0
  114. package/{plugins/design/dev-server → apps/studio}/use-collab.tsx +1 -1
  115. package/{plugins/design/dev-server → apps/studio}/use-cursor-modifiers.tsx +1 -1
  116. package/{plugins/design/dev-server → apps/studio}/use-keyboard-discipline.tsx +5 -2
  117. package/{plugins/design/dev-server → apps/studio}/use-selection-set.tsx +9 -1
  118. package/{plugins/design/dev-server → apps/studio}/use-snap-guides.tsx +1 -1
  119. package/{plugins/design/dev-server → apps/studio}/use-tool-mode.tsx +3 -1
  120. package/{plugins/design/dev-server → apps/studio}/use-undo-stack.tsx +1 -1
  121. package/apps/studio/whats-new.json +139 -0
  122. package/apps/studio/whats-new.schema.json +70 -0
  123. package/apps/studio/whats-new.ts +87 -0
  124. package/cli/bin/maude.mjs +10 -0
  125. package/cli/commands/design.mjs +15 -7
  126. package/cli/commands/design.test.mjs +36 -0
  127. package/cli/commands/help.mjs +8 -2
  128. package/cli/commands/hub.mjs +3 -3
  129. package/cli/commands/hub.test.mjs +1 -1
  130. package/cli/commands/scenario-report.mjs +2 -9
  131. package/cli/lib/flow-design-integration.test.mjs +1 -1
  132. package/cli/lib/gitignore-block.mjs +1 -0
  133. package/cli/lib/plugin-cli-reachability.test.mjs +8 -7
  134. package/cli/lib/preflight.mjs +1 -1
  135. package/package.json +15 -15
  136. package/plugins/design/templates/brief-board.tsx.template +61 -0
  137. package/plugins/design/templates/canvas.tsx.template +1 -1
  138. package/plugins/design/templates/design-system-inspiration/core/config.json.tpl +1 -1
  139. package/plugins/design/templates/design-system-inspiration/core/preview/_motion-readme.md.tpl +1 -1
  140. package/plugins/flow/.claude-plugin/config.schema.json +16 -0
  141. package/plugins/design/dev-server/dist/client.bundle.js +0 -20692
  142. package/plugins/design/dev-server/dist/comment-mount.js +0 -1924
  143. package/plugins/design/dev-server/dist/styles.css +0 -2710
  144. /package/{plugins/design/dev-server → apps/studio}/activity.ts +0 -0
  145. /package/{plugins/design/dev-server → apps/studio}/bin/_enumerate-artboards-playwright.mjs +0 -0
  146. /package/{plugins/design/dev-server → apps/studio}/bin/_html-playwright.mjs +0 -0
  147. /package/{plugins/design/dev-server → apps/studio}/bin/_pdf-playwright.mjs +0 -0
  148. /package/{plugins/design/dev-server → apps/studio}/bin/_png-playwright.mjs +0 -0
  149. /package/{plugins/design/dev-server → apps/studio}/bin/_pptx-playwright.mjs +0 -0
  150. /package/{plugins/design/dev-server → apps/studio}/bin/_pw-launch.mjs +0 -0
  151. /package/{plugins/design/dev-server → apps/studio}/bin/_screenshot-playwright.mjs +0 -0
  152. /package/{plugins/design/dev-server → apps/studio}/bin/_svg-optimize.mjs +0 -0
  153. /package/{plugins/design/dev-server → apps/studio}/bin/_svg-playwright.mjs +0 -0
  154. /package/{plugins/design/dev-server → apps/studio}/bin/asset-sweep.sh +0 -0
  155. /package/{plugins/design/dev-server → apps/studio}/bin/bootstrap-check.sh +0 -0
  156. /package/{plugins/design/dev-server → apps/studio}/bin/check-runtime-bundles.sh +0 -0
  157. /package/{plugins/design/dev-server → apps/studio}/bin/draw-build.sh +0 -0
  158. /package/{plugins/design/dev-server → apps/studio}/bin/handoff.sh +0 -0
  159. /package/{plugins/design/dev-server → apps/studio}/bin/prep.sh +0 -0
  160. /package/{plugins/design/dev-server → apps/studio}/bin/scenario-report.mjs +0 -0
  161. /package/{plugins/design/dev-server → apps/studio}/bin/slug.sh +0 -0
  162. /package/{plugins/design/dev-server → apps/studio}/bin/smoke.sh +0 -0
  163. /package/{plugins/design/dev-server → apps/studio}/bin/svg-optimize.sh +0 -0
  164. /package/{plugins/design/dev-server → apps/studio}/bin/visual-sanity.sh +0 -0
  165. /package/{plugins/design/dev-server → apps/studio}/boot-self-heal.ts +0 -0
  166. /package/{plugins/design/dev-server → apps/studio}/canvas-build.ts +0 -0
  167. /package/{plugins/design/dev-server → apps/studio}/canvas-edit.ts +0 -0
  168. /package/{plugins/design/dev-server → apps/studio}/canvas-header.ts +0 -0
  169. /package/{plugins/design/dev-server → apps/studio}/canvas-meta.schema.json +0 -0
  170. /package/{plugins/design/dev-server → apps/studio}/canvas-pipeline.ts +0 -0
  171. /package/{plugins/design/dev-server → apps/studio}/client/hmr.mjs +0 -0
  172. /package/{plugins/design/dev-server → apps/studio}/client/iframe-lazy.mjs +0 -0
  173. /package/{plugins/design/dev-server → apps/studio}/client/styles/0-reset.css +0 -0
  174. /package/{plugins/design/dev-server → apps/studio}/client/styles/1-tokens.css +0 -0
  175. /package/{plugins/design/dev-server → apps/studio}/client/styles/2-layout.css +0 -0
  176. /package/{plugins/design/dev-server → apps/studio}/client/styles/5-utilities.css +0 -0
  177. /package/{plugins/design/dev-server → apps/studio}/collab/ai-activity.ts +0 -0
  178. /package/{plugins/design/dev-server → apps/studio}/collab/awareness-bridge.ts +0 -0
  179. /package/{plugins/design/dev-server → apps/studio}/collab/git-lifecycle.ts +0 -0
  180. /package/{plugins/design/dev-server → apps/studio}/collab/index.ts +0 -0
  181. /package/{plugins/design/dev-server → apps/studio}/collab/persistence.ts +0 -0
  182. /package/{plugins/design/dev-server → apps/studio}/collab/protocol.ts +0 -0
  183. /package/{plugins/design/dev-server → apps/studio}/collab/registry.ts +0 -0
  184. /package/{plugins/design/dev-server → apps/studio}/collab/room.ts +0 -0
  185. /package/{plugins/design/dev-server → apps/studio}/config.schema.json +0 -0
  186. /package/{plugins/design/dev-server → apps/studio}/context.ts +0 -0
  187. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/.min-sizes.json +0 -0
  188. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/lib0_decoding.js +0 -0
  189. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/lib0_encoding.js +0 -0
  190. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/motion.js +0 -0
  191. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/motion_react.js +0 -0
  192. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/pixi-js.js +0 -0
  193. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/react-dom.js +0 -0
  194. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/react-dom_client.js +0 -0
  195. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/react.js +0 -0
  196. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/react_jsx-dev-runtime.js +0 -0
  197. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/react_jsx-runtime.js +0 -0
  198. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/y-protocols_awareness.js +0 -0
  199. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/y-protocols_sync.js +0 -0
  200. /package/{plugins/design/dev-server → apps/studio}/dist/runtime/yjs.js +0 -0
  201. /package/{plugins/design/dev-server → apps/studio}/draw/test/brush.test.ts +0 -0
  202. /package/{plugins/design/dev-server → apps/studio}/draw/test/composition.test.ts +0 -0
  203. /package/{plugins/design/dev-server → apps/studio}/draw/test/geometry.test.ts +0 -0
  204. /package/{plugins/design/dev-server → apps/studio}/draw/test/gradient.test.ts +0 -0
  205. /package/{plugins/design/dev-server → apps/studio}/draw/test/layout.test.ts +0 -0
  206. /package/{plugins/design/dev-server → apps/studio}/draw/test/optimize.test.ts +0 -0
  207. /package/{plugins/design/dev-server → apps/studio}/draw/test/palette.test.ts +0 -0
  208. /package/{plugins/design/dev-server → apps/studio}/draw/test/primitives.test.ts +0 -0
  209. /package/{plugins/design/dev-server → apps/studio}/draw/test/serialize.test.ts +0 -0
  210. /package/{plugins/design/dev-server → apps/studio}/examples/README.md +0 -0
  211. /package/{plugins/design/dev-server → apps/studio}/examples/perf-100-artboards.tsx +0 -0
  212. /package/{plugins/design/dev-server → apps/studio}/exporters/_browser-bundles.ts +0 -0
  213. /package/{plugins/design/dev-server → apps/studio}/exporters/canva-handoff-prompt.ts +0 -0
  214. /package/{plugins/design/dev-server → apps/studio}/exporters/canva.ts +0 -0
  215. /package/{plugins/design/dev-server → apps/studio}/exporters/html.ts +0 -0
  216. /package/{plugins/design/dev-server → apps/studio}/exporters/index.ts +0 -0
  217. /package/{plugins/design/dev-server → apps/studio}/exporters/pdf.ts +0 -0
  218. /package/{plugins/design/dev-server → apps/studio}/exporters/png.ts +0 -0
  219. /package/{plugins/design/dev-server → apps/studio}/exporters/pptx.ts +0 -0
  220. /package/{plugins/design/dev-server → apps/studio}/exporters/scope.ts +0 -0
  221. /package/{plugins/design/dev-server → apps/studio}/exporters/svg.ts +0 -0
  222. /package/{plugins/design/dev-server → apps/studio}/exporters/zip.ts +0 -0
  223. /package/{plugins/design/dev-server → apps/studio}/fs-watch.ts +0 -0
  224. /package/{plugins/design/dev-server → apps/studio}/handoff.ts +0 -0
  225. /package/{plugins/design/dev-server → apps/studio}/history.ts +0 -0
  226. /package/{plugins/design/dev-server → apps/studio}/hmr-broadcast.ts +0 -0
  227. /package/{plugins/design/dev-server → apps/studio}/locator.ts +0 -0
  228. /package/{plugins/design/dev-server → apps/studio}/mem.ts +0 -0
  229. /package/{plugins/design/dev-server → apps/studio}/runtime-bundle.ts +0 -0
  230. /package/{plugins/design/dev-server → apps/studio}/server.mjs +0 -0
  231. /package/{plugins/design/dev-server → apps/studio}/sync/agent.ts +0 -0
  232. /package/{plugins/design/dev-server → apps/studio}/sync/atomic-write.ts +0 -0
  233. /package/{plugins/design/dev-server → apps/studio}/sync/codec.ts +0 -0
  234. /package/{plugins/design/dev-server → apps/studio}/sync/connection-state.ts +0 -0
  235. /package/{plugins/design/dev-server → apps/studio}/sync/echo-guard.ts +0 -0
  236. /package/{plugins/design/dev-server → apps/studio}/sync/fs-mirror.ts +0 -0
  237. /package/{plugins/design/dev-server → apps/studio}/sync/hubs-config.ts +0 -0
  238. /package/{plugins/design/dev-server → apps/studio}/sync/materialize.ts +0 -0
  239. /package/{plugins/design/dev-server → apps/studio}/sync/migrate-seed.ts +0 -0
  240. /package/{plugins/design/dev-server → apps/studio}/sync/origins.ts +0 -0
  241. /package/{plugins/design/dev-server → apps/studio}/sync/projection.ts +0 -0
  242. /package/{plugins/design/dev-server → apps/studio}/sync/status.ts +0 -0
  243. /package/{plugins/design/dev-server → apps/studio}/sync/untrusted.ts +0 -0
  244. /package/{plugins/design/dev-server → apps/studio}/test/_helpers.ts +0 -0
  245. /package/{plugins/design/dev-server → apps/studio}/test/active-state.test.ts +0 -0
  246. /package/{plugins/design/dev-server → apps/studio}/test/activity.test.ts +0 -0
  247. /package/{plugins/design/dev-server → apps/studio}/test/ai-activity.test.ts +0 -0
  248. /package/{plugins/design/dev-server → apps/studio}/test/annotation-strokes-command.test.ts +0 -0
  249. /package/{plugins/design/dev-server → apps/studio}/test/annotations-api.test.ts +0 -0
  250. /package/{plugins/design/dev-server → apps/studio}/test/annotations-draw-modifiers.test.ts +0 -0
  251. /package/{plugins/design/dev-server → apps/studio}/test/artboard-activity-overlay.test.tsx +0 -0
  252. /package/{plugins/design/dev-server → apps/studio}/test/binary-smoke.test.ts +0 -0
  253. /package/{plugins/design/dev-server → apps/studio}/test/boot-self-heal.test.ts +0 -0
  254. /package/{plugins/design/dev-server → apps/studio}/test/bundle-smoke.test.ts +0 -0
  255. /package/{plugins/design/dev-server → apps/studio}/test/canvas-build.test.ts +0 -0
  256. /package/{plugins/design/dev-server → apps/studio}/test/canvas-edit.test.ts +0 -0
  257. /package/{plugins/design/dev-server → apps/studio}/test/canvas-header.test.ts +0 -0
  258. /package/{plugins/design/dev-server → apps/studio}/test/canvas-hmr-runtime.test.tsx +0 -0
  259. /package/{plugins/design/dev-server → apps/studio}/test/canvas-lib-inline.test.ts +0 -0
  260. /package/{plugins/design/dev-server → apps/studio}/test/canvas-lib-motion.test.ts +0 -0
  261. /package/{plugins/design/dev-server → apps/studio}/test/canvas-meta-api.test.ts +0 -0
  262. /package/{plugins/design/dev-server → apps/studio}/test/canvas-pipeline.test.ts +0 -0
  263. /package/{plugins/design/dev-server → apps/studio}/test/canvas-route.test.ts +0 -0
  264. /package/{plugins/design/dev-server → apps/studio}/test/collab-annotations-bridge.test.ts +0 -0
  265. /package/{plugins/design/dev-server → apps/studio}/test/collab-awareness-bridge.test.ts +0 -0
  266. /package/{plugins/design/dev-server → apps/studio}/test/collab-bridge.test.ts +0 -0
  267. /package/{plugins/design/dev-server → apps/studio}/test/collab-loopback.test.ts +0 -0
  268. /package/{plugins/design/dev-server → apps/studio}/test/collab-protocol.test.ts +0 -0
  269. /package/{plugins/design/dev-server → apps/studio}/test/collab-reseed-guard.test.ts +0 -0
  270. /package/{plugins/design/dev-server → apps/studio}/test/collab-room.test.ts +0 -0
  271. /package/{plugins/design/dev-server → apps/studio}/test/collab-stress.test.ts +0 -0
  272. /package/{plugins/design/dev-server → apps/studio}/test/comment-mount.test.ts +0 -0
  273. /package/{plugins/design/dev-server → apps/studio}/test/comments-api.test.ts +0 -0
  274. /package/{plugins/design/dev-server → apps/studio}/test/compile-entry.test.ts +0 -0
  275. /package/{plugins/design/dev-server → apps/studio}/test/context-resolve-tokens.test.ts +0 -0
  276. /package/{plugins/design/dev-server → apps/studio}/test/csp-canvas-shell.test.ts +0 -0
  277. /package/{plugins/design/dev-server → apps/studio}/test/equal-spacing-detector.test.ts +0 -0
  278. /package/{plugins/design/dev-server → apps/studio}/test/exporters/canva.test.ts +0 -0
  279. /package/{plugins/design/dev-server → apps/studio}/test/exporters/endpoint.test.ts +0 -0
  280. /package/{plugins/design/dev-server → apps/studio}/test/exporters/history.test.ts +0 -0
  281. /package/{plugins/design/dev-server → apps/studio}/test/exporters/html.test.ts +0 -0
  282. /package/{plugins/design/dev-server → apps/studio}/test/exporters/pdf.test.ts +0 -0
  283. /package/{plugins/design/dev-server → apps/studio}/test/exporters/png.test.ts +0 -0
  284. /package/{plugins/design/dev-server → apps/studio}/test/exporters/pptx-deck.test.ts +0 -0
  285. /package/{plugins/design/dev-server → apps/studio}/test/exporters/pptx.test.ts +0 -0
  286. /package/{plugins/design/dev-server → apps/studio}/test/exporters/pw-launch.test.ts +0 -0
  287. /package/{plugins/design/dev-server → apps/studio}/test/exporters/scope.test.ts +0 -0
  288. /package/{plugins/design/dev-server → apps/studio}/test/exporters/svg.test.ts +0 -0
  289. /package/{plugins/design/dev-server → apps/studio}/test/exporters/zip.test.ts +0 -0
  290. /package/{plugins/design/dev-server → apps/studio}/test/fixtures/phase-20-annotations.svg +0 -0
  291. /package/{plugins/design/dev-server → apps/studio}/test/fixtures/phase-21-annotations.svg +0 -0
  292. /package/{plugins/design/dev-server → apps/studio}/test/fs-watch.test.ts +0 -0
  293. /package/{plugins/design/dev-server → apps/studio}/test/git-lifecycle.test.ts +0 -0
  294. /package/{plugins/design/dev-server → apps/studio}/test/handoff-static-frames.test.ts +0 -0
  295. /package/{plugins/design/dev-server → apps/studio}/test/handoff.test.ts +0 -0
  296. /package/{plugins/design/dev-server → apps/studio}/test/history-rollback.test.ts +0 -0
  297. /package/{plugins/design/dev-server → apps/studio}/test/hmr-broadcast.test.ts +0 -0
  298. /package/{plugins/design/dev-server → apps/studio}/test/hmr-classify.test.ts +0 -0
  299. /package/{plugins/design/dev-server → apps/studio}/test/input-router.test.ts +0 -0
  300. /package/{plugins/design/dev-server → apps/studio}/test/locator.test.ts +0 -0
  301. /package/{plugins/design/dev-server → apps/studio}/test/marquee-overlay.test.ts +0 -0
  302. /package/{plugins/design/dev-server → apps/studio}/test/move-artboards-command.test.ts +0 -0
  303. /package/{plugins/design/dev-server → apps/studio}/test/participants-chrome.test.ts +0 -0
  304. /package/{plugins/design/dev-server → apps/studio}/test/paths.test.ts +0 -0
  305. /package/{plugins/design/dev-server → apps/studio}/test/runtime-bundle-error-mapping.test.ts +0 -0
  306. /package/{plugins/design/dev-server → apps/studio}/test/runtime-bundle.test.ts +0 -0
  307. /package/{plugins/design/dev-server → apps/studio}/test/server-lifecycle.test.ts +0 -0
  308. /package/{plugins/design/dev-server → apps/studio}/test/shared-doc-foundation.test.ts +0 -0
  309. /package/{plugins/design/dev-server → apps/studio}/test/shared-doc-migrate.test.ts +0 -0
  310. /package/{plugins/design/dev-server → apps/studio}/test/shared-doc-projection.test.ts +0 -0
  311. /package/{plugins/design/dev-server → apps/studio}/test/snap-distance-pill.test.ts +0 -0
  312. /package/{plugins/design/dev-server → apps/studio}/test/sync-agent.test.ts +0 -0
  313. /package/{plugins/design/dev-server → apps/studio}/test/sync-atomic-write.test.ts +0 -0
  314. /package/{plugins/design/dev-server → apps/studio}/test/sync-codec.test.ts +0 -0
  315. /package/{plugins/design/dev-server → apps/studio}/test/sync-connection-state.test.ts +0 -0
  316. /package/{plugins/design/dev-server → apps/studio}/test/sync-echo-guard.test.ts +0 -0
  317. /package/{plugins/design/dev-server → apps/studio}/test/sync-fs-mirror.test.ts +0 -0
  318. /package/{plugins/design/dev-server → apps/studio}/test/sync-hardening.test.ts +0 -0
  319. /package/{plugins/design/dev-server → apps/studio}/test/sync-hubs-config.test.ts +0 -0
  320. /package/{plugins/design/dev-server → apps/studio}/test/sync-meta-codec.test.ts +0 -0
  321. /package/{plugins/design/dev-server → apps/studio}/test/sync-runtime.test.ts +0 -0
  322. /package/{plugins/design/dev-server → apps/studio}/test/sync-status.test.ts +0 -0
  323. /package/{plugins/design/dev-server → apps/studio}/test/sync-untrusted.test.ts +0 -0
  324. /package/{plugins/design/dev-server → apps/studio}/test/system-endpoint.test.ts +0 -0
  325. /package/{plugins/design/dev-server → apps/studio}/test/tool-palette.test.tsx +0 -0
  326. /package/{plugins/design/dev-server → apps/studio}/test/undo-stack.test.ts +0 -0
  327. /package/{plugins/design/dev-server → apps/studio}/test/use-agent-presence.test.tsx +0 -0
  328. /package/{plugins/design/dev-server → apps/studio}/test/use-annotation-selection.test.tsx +0 -0
  329. /package/{plugins/design/dev-server → apps/studio}/test/use-artboard-drag.test.ts +0 -0
  330. /package/{plugins/design/dev-server → apps/studio}/test/use-canvas-activity.test.tsx +0 -0
  331. /package/{plugins/design/dev-server → apps/studio}/test/use-collab.test.ts +0 -0
  332. /package/{plugins/design/dev-server → apps/studio}/test/use-cursor-modifiers.test.ts +0 -0
  333. /package/{plugins/design/dev-server → apps/studio}/test/use-keyboard-discipline.test.ts +0 -0
  334. /package/{plugins/design/dev-server → apps/studio}/test/use-selection-set.test.tsx +0 -0
  335. /package/{plugins/design/dev-server → apps/studio}/test/use-snap-guides.test.ts +0 -0
  336. /package/{plugins/design/dev-server → apps/studio}/test/use-undo-stack.test.tsx +0 -0
  337. /package/{plugins/design/dev-server → apps/studio}/test/ws-handshake.test.ts +0 -0
  338. /package/{plugins/design/dev-server → apps/studio}/tsconfig.json +0 -0
  339. /package/{plugins/design/dev-server → apps/studio}/ws.ts +0 -0
@@ -1,1924 +0,0 @@
1
- // canvas-comment-mount.tsx
2
- import {
3
- Component,
4
- createElement,
5
- Fragment as Fragment3,
6
- useCallback as useCallback5,
7
- useEffect as useEffect6,
8
- useMemo as useMemo5,
9
- useRef as useRef4,
10
- useState as useState5
11
- } from "react";
12
- import { createRoot } from "react-dom/client";
13
-
14
- // comments-overlay.tsx
15
- import { useCallback as useCallback3, useEffect as useEffect3, useMemo as useMemo3, useRef as useRef3, useState as useState3 } from "react";
16
-
17
- // use-collab.tsx
18
- import * as decoding from "lib0/decoding";
19
- import * as encoding from "lib0/encoding";
20
- import {
21
- createContext,
22
- useCallback,
23
- useContext,
24
- useEffect,
25
- useMemo,
26
- useRef,
27
- useState
28
- } from "react";
29
- import { Awareness, applyAwarenessUpdate, encodeAwarenessUpdate } from "y-protocols/awareness";
30
- import { readSyncMessage, writeSyncStep1, writeUpdate } from "y-protocols/sync";
31
- import * as Y from "yjs";
32
- import { jsx } from "react/jsx-runtime";
33
- var CollabContext = createContext(null);
34
- function useCollab() {
35
- return useContext(CollabContext);
36
- }
37
-
38
- // use-selection-set.tsx
39
- import {
40
- createContext as createContext2,
41
- useCallback as useCallback2,
42
- useContext as useContext2,
43
- useEffect as useEffect2,
44
- useMemo as useMemo2,
45
- useRef as useRef2,
46
- useState as useState2
47
- } from "react";
48
- import { jsx as jsx2, Fragment } from "react/jsx-runtime";
49
- var SelectionSetContext = createContext2(null);
50
- function selectionKey(s) {
51
- return s.id ? `id:${s.id}` : `sel:${s.selector}`;
52
- }
53
- function dedupe(list) {
54
- const out = [];
55
- const seen = new Set;
56
- for (const s of list) {
57
- const k = selectionKey(s);
58
- if (seen.has(k))
59
- continue;
60
- seen.add(k);
61
- out.push(s);
62
- }
63
- return out;
64
- }
65
- var POST_DEBOUNCE_MS = 50;
66
- function SelectionSetProvider({
67
- children,
68
- postTarget
69
- }) {
70
- const [selected, setSelected] = useState2([]);
71
- const timerRef = useRef2(null);
72
- const post = useCallback2((next) => {
73
- if (timerRef.current)
74
- clearTimeout(timerRef.current);
75
- timerRef.current = setTimeout(() => {
76
- timerRef.current = null;
77
- const target = postTarget ?? (typeof window !== "undefined" ? window.parent : null);
78
- if (!target)
79
- return;
80
- const payload = next.length === 0 ? null : next.length === 1 ? next[0] ?? null : next;
81
- try {
82
- target.postMessage({ dgn: "select-set", selection: payload }, "*");
83
- } catch {}
84
- }, POST_DEBOUNCE_MS);
85
- }, [postTarget]);
86
- useEffect2(() => () => {
87
- if (timerRef.current)
88
- clearTimeout(timerRef.current);
89
- }, []);
90
- const replace = useCallback2((s) => {
91
- const next = dedupe(Array.isArray(s) ? s : [s]);
92
- setSelected(next);
93
- post(next);
94
- }, [post]);
95
- const add = useCallback2((s) => {
96
- const incoming = Array.isArray(s) ? s : [s];
97
- setSelected((prev) => {
98
- const next = dedupe([...prev, ...incoming]);
99
- post(next);
100
- return next;
101
- });
102
- }, [post]);
103
- const remove = useCallback2((s) => {
104
- const k = selectionKey(s);
105
- setSelected((prev) => {
106
- const next = prev.filter((x) => selectionKey(x) !== k);
107
- post(next);
108
- return next;
109
- });
110
- }, [post]);
111
- const toggle = useCallback2((s) => {
112
- const k = selectionKey(s);
113
- setSelected((prev) => {
114
- const next = prev.some((x) => selectionKey(x) === k) ? prev.filter((x) => selectionKey(x) !== k) : [...prev, s];
115
- post(next);
116
- return next;
117
- });
118
- }, [post]);
119
- const clear = useCallback2(() => {
120
- setSelected([]);
121
- post([]);
122
- }, [post]);
123
- const value = useMemo2(() => ({ selected, replace, add, remove, toggle, clear }), [selected, replace, add, remove, toggle, clear]);
124
- return /* @__PURE__ */ jsx2(SelectionSetContext.Provider, {
125
- value,
126
- children
127
- });
128
- }
129
- function MaybeSelectionSetProvider({ children }) {
130
- const outer = useContext2(SelectionSetContext);
131
- if (outer)
132
- return /* @__PURE__ */ jsx2(Fragment, {
133
- children
134
- });
135
- return /* @__PURE__ */ jsx2(SelectionSetProvider, {
136
- children
137
- });
138
- }
139
- function useSelectionSet() {
140
- const ctx = useContext2(SelectionSetContext);
141
- if (!ctx) {
142
- throw new Error("useSelectionSet must be used inside <SelectionSetProvider>");
143
- }
144
- return ctx;
145
- }
146
- function useSelectionSetOptional() {
147
- return useContext2(SelectionSetContext);
148
- }
149
-
150
- // comments-overlay.tsx
151
- import { jsx as jsx3, jsxs } from "react/jsx-runtime";
152
- var CSS_HREF = "/_client/comments-overlay.css";
153
- function ensureOverlayStyles() {
154
- if (typeof document === "undefined")
155
- return;
156
- if (document.getElementById("cm-overlay-css"))
157
- return;
158
- const link = document.createElement("link");
159
- link.id = "cm-overlay-css";
160
- link.rel = "stylesheet";
161
- link.href = CSS_HREF;
162
- document.head.appendChild(link);
163
- }
164
- function deriveFile() {
165
- if (typeof window === "undefined")
166
- return null;
167
- try {
168
- const p = window.location.pathname;
169
- if (p === "/_canvas-shell.html" || p === "/_canvas-shell") {
170
- const qs = new URLSearchParams(window.location.search);
171
- const canvas = qs.get("canvas") ?? "";
172
- const designRel = (qs.get("designRel") ?? ".design").replace(/^\/+|\/+$/g, "");
173
- return canvas ? `${designRel}/${canvas}` : null;
174
- }
175
- return decodeURIComponent(p).replace(/^\//, "");
176
- } catch {
177
- return null;
178
- }
179
- }
180
- function screenRectFor(selector) {
181
- if (!selector)
182
- return null;
183
- let el = null;
184
- try {
185
- el = document.querySelector(selector);
186
- } catch {
187
- return null;
188
- }
189
- if (!el || !el.isConnected)
190
- return null;
191
- const r = el.getBoundingClientRect();
192
- if (r.width === 0 && r.height === 0)
193
- return null;
194
- return { x: r.left, y: r.top, w: r.width, h: r.height };
195
- }
196
- function CommentsOverlay() {
197
- ensureOverlayStyles();
198
- const selSet = useSelectionSetOptional();
199
- const [comments, setComments] = useState3([]);
200
- const [focusedId, setFocusedId] = useState3(null);
201
- const [composer, setComposer] = useState3(null);
202
- const file = useMemo3(() => deriveFile(), []);
203
- useEffect3(() => {
204
- if (typeof document === "undefined")
205
- return;
206
- const legacy = document.getElementById("dgn-pin-layer");
207
- if (!legacy)
208
- return;
209
- const prev = legacy.style.display;
210
- legacy.style.display = "none";
211
- return () => {
212
- legacy.style.display = prev;
213
- };
214
- }, []);
215
- const mirrorSelection = useCallback3((comment) => {
216
- if (!selSet)
217
- return;
218
- if (!comment || !comment.selector) {
219
- selSet.clear();
220
- return;
221
- }
222
- const cdMatch = comment.selector.match(/data-cd-id="([^"]+)"/);
223
- const cdId = cdMatch ? cdMatch[1] : undefined;
224
- let tag;
225
- let classes;
226
- try {
227
- const el = document.querySelector(comment.selector);
228
- if (el) {
229
- tag = el.tagName.toLowerCase();
230
- classes = (el.getAttribute("class") ?? "").split(/\s+/).filter((cls) => cls && !cls.startsWith("dgn-") && !cls.startsWith("dc-cv-")).join(" ");
231
- }
232
- } catch {}
233
- selSet.replace({
234
- file: file ?? undefined,
235
- id: cdId,
236
- selector: comment.selector,
237
- tag,
238
- classes,
239
- bounds: comment.bounds ?? undefined
240
- });
241
- }, [selSet, file]);
242
- const commentsRef = useRef3(comments);
243
- commentsRef.current = comments;
244
- const collab = useCollab();
245
- useEffect3(() => {
246
- if (!collab)
247
- return;
248
- const arr = collab.doc.getArray("comments");
249
- const sync = () => {
250
- setComments(arr.toArray());
251
- };
252
- if (arr.length > 0)
253
- sync();
254
- arr.observe(sync);
255
- return () => {
256
- try {
257
- arr.unobserve(sync);
258
- } catch {}
259
- };
260
- }, [collab]);
261
- useEffect3(() => {
262
- if (typeof window === "undefined")
263
- return;
264
- const onMessage = (e) => {
265
- const m = e.data;
266
- if (!m || typeof m !== "object" || !m.dgn)
267
- return;
268
- if (m.dgn === "comments-set" && Array.isArray(m.comments)) {
269
- setComments(m.comments);
270
- } else if (m.dgn === "comment-focus") {
271
- const id = typeof m.id === "string" ? m.id : null;
272
- setFocusedId(id);
273
- const target = id ? commentsRef.current.find((c) => c.id === id) : undefined;
274
- mirrorSelection(target);
275
- }
276
- };
277
- window.addEventListener("message", onMessage);
278
- return () => window.removeEventListener("message", onMessage);
279
- }, [mirrorSelection]);
280
- useEffect3(() => {
281
- if (typeof document === "undefined")
282
- return;
283
- const onOpen = (e) => {
284
- const detail = e.detail;
285
- if (!detail || !detail.selection)
286
- return;
287
- setComposer({
288
- selection: detail.selection,
289
- clientX: typeof detail.clientX === "number" ? detail.clientX : 0,
290
- clientY: typeof detail.clientY === "number" ? detail.clientY : 0
291
- });
292
- };
293
- document.addEventListener("cm:open-composer", onOpen);
294
- return () => document.removeEventListener("cm:open-composer", onOpen);
295
- }, []);
296
- const closeComposer = useCallback3(() => {
297
- setComposer(null);
298
- if (typeof window === "undefined")
299
- return;
300
- try {
301
- window.parent.postMessage({ dgn: "force-clear" }, "*");
302
- } catch {}
303
- }, []);
304
- const submitComposer = useCallback3((text) => {
305
- if (!composer)
306
- return;
307
- const sel = composer.selection;
308
- const payload = {
309
- file: sel.file,
310
- selector: sel.selector,
311
- dom_path: sel.dom_path,
312
- tag: sel.tag,
313
- classes: sel.classes,
314
- bounds: sel.bounds,
315
- html_excerpt: sel.html,
316
- text
317
- };
318
- if (typeof window === "undefined")
319
- return;
320
- try {
321
- window.parent.postMessage({ dgn: "comment-submit", payload }, "*");
322
- } catch {}
323
- closeComposer();
324
- }, [composer, closeComposer]);
325
- useEffect3(() => {
326
- if (!file)
327
- return;
328
- let cancelled = false;
329
- (async () => {
330
- try {
331
- const r = await fetch(`/_comments?file=${encodeURIComponent(file)}`);
332
- if (!r.ok)
333
- return;
334
- const data = await r.json();
335
- if (cancelled)
336
- return;
337
- if (Array.isArray(data.comments)) {
338
- setComments((prev) => prev.length === 0 ? data.comments ?? [] : prev);
339
- }
340
- } catch {}
341
- })();
342
- return () => {
343
- cancelled = true;
344
- };
345
- }, [file]);
346
- const visible = useMemo3(() => {
347
- const list = comments.slice().sort((a, b) => a.created.localeCompare(b.created));
348
- return list.filter((c) => c.status !== "resolved");
349
- }, [comments]);
350
- const indexById = useMemo3(() => {
351
- const m = new Map;
352
- const all = comments.slice().sort((a, b) => a.created.localeCompare(b.created));
353
- all.forEach((c, i) => m.set(c.id, i + 1));
354
- return m;
355
- }, [comments]);
356
- const handlePinClick = useCallback3((id) => {
357
- setFocusedId(id);
358
- mirrorSelection(comments.find((c) => c.id === id));
359
- if (typeof window === "undefined")
360
- return;
361
- try {
362
- window.parent.postMessage({ dgn: "comment-click", id }, "*");
363
- } catch {}
364
- }, [comments, mirrorSelection]);
365
- const handlePatch = useCallback3((id, patch) => {
366
- if (typeof window === "undefined")
367
- return;
368
- try {
369
- window.parent.postMessage({ dgn: "comment-patch", id, patch }, "*");
370
- } catch {}
371
- }, []);
372
- const handleDelete = useCallback3((id) => {
373
- if (typeof window === "undefined")
374
- return;
375
- try {
376
- window.parent.postMessage({ dgn: "comment-delete", id }, "*");
377
- } catch {}
378
- setFocusedId((prev) => prev === id ? null : prev);
379
- }, []);
380
- const handleReply = useCallback3(async (id, body) => {
381
- if (typeof fetch === "undefined")
382
- return false;
383
- try {
384
- const r = await fetch(`/_api/comments/${encodeURIComponent(id)}/reply`, {
385
- method: "POST",
386
- headers: { "Content-Type": "application/json" },
387
- body: JSON.stringify({ body })
388
- });
389
- if (!r.ok)
390
- return false;
391
- const updated = await r.json();
392
- setComments((prev) => prev.map((c) => c.id === updated.id ? updated : c));
393
- return true;
394
- } catch {
395
- return false;
396
- }
397
- }, []);
398
- return /* @__PURE__ */ jsxs("div", {
399
- className: "cm-layer",
400
- "aria-hidden": false,
401
- children: [
402
- visible.map((c) => {
403
- const n = indexById.get(c.id) ?? 0;
404
- return /* @__PURE__ */ jsx3(CommentPin, {
405
- comment: c,
406
- sequence: n,
407
- focused: focusedId === c.id,
408
- onClick: handlePinClick
409
- }, c.id);
410
- }),
411
- composer ? /* @__PURE__ */ jsx3(CommentComposer, {
412
- state: composer,
413
- onSubmit: submitComposer,
414
- onCancel: closeComposer
415
- }) : null,
416
- (() => {
417
- if (!focusedId)
418
- return null;
419
- const focused = visible.find((c) => c.id === focusedId);
420
- if (!focused)
421
- return null;
422
- return /* @__PURE__ */ jsx3(CommentThread, {
423
- comment: focused,
424
- onClose: () => {
425
- setFocusedId(null);
426
- selSet?.clear();
427
- },
428
- onPatch: (patch) => handlePatch(focused.id, patch),
429
- onDelete: () => handleDelete(focused.id),
430
- onReply: (body) => handleReply(focused.id, body)
431
- });
432
- })()
433
- ]
434
- });
435
- }
436
- var committerCache = null;
437
- async function loadCommitters() {
438
- if (!committerCache) {
439
- committerCache = (async () => {
440
- try {
441
- const r = await fetch("/_api/git-committers");
442
- if (!r.ok)
443
- return [];
444
- const data = await r.json();
445
- return Array.isArray(data.committers) ? data.committers : [];
446
- } catch {
447
- return [];
448
- }
449
- })();
450
- }
451
- return committerCache;
452
- }
453
- function firstNameSlug(name) {
454
- const first = name.trim().split(/\s+/)[0] ?? "";
455
- return first.replace(/[^\w.-]/g, "").toLowerCase();
456
- }
457
- function detectMentionToken(text, caret) {
458
- if (caret <= 0 || caret > text.length)
459
- return null;
460
- let i = caret - 1;
461
- while (i >= 0) {
462
- const ch = text[i] ?? "";
463
- if (ch === "@") {
464
- const prev = i > 0 ? text[i - 1] : "";
465
- if (i === 0 || /\s/.test(prev ?? "")) {
466
- const query = text.slice(i + 1, caret);
467
- return { start: i, end: caret, query };
468
- }
469
- return null;
470
- }
471
- if (!/[\w.-]/.test(ch))
472
- return null;
473
- i -= 1;
474
- }
475
- return null;
476
- }
477
- function MentionAwareTextarea({
478
- className,
479
- value,
480
- onChange,
481
- onKeyDown,
482
- placeholder,
483
- rows,
484
- disabled,
485
- textareaRef,
486
- ariaLabel
487
- }) {
488
- const internalRef = useRef3(null);
489
- const setRef = useCallback3((el) => {
490
- internalRef.current = el;
491
- if (textareaRef)
492
- textareaRef.current = el;
493
- }, [textareaRef]);
494
- const [committers, setCommitters] = useState3([]);
495
- const [token, setToken] = useState3(null);
496
- const [highlight, setHighlight] = useState3(0);
497
- const onFocus = useCallback3(() => {
498
- if (committers.length > 0)
499
- return;
500
- loadCommitters().then((list) => setCommitters(list));
501
- }, [committers.length]);
502
- const filtered = useMemo3(() => {
503
- if (!token)
504
- return [];
505
- const q = token.query.toLowerCase();
506
- const list = !q ? committers : committers.filter((c) => c.name.toLowerCase().includes(q) || c.email.toLowerCase().includes(q));
507
- return list.slice(0, 8);
508
- }, [token, committers]);
509
- const refreshToken = useCallback3((textarea) => {
510
- const caret = textarea.selectionStart ?? textarea.value.length;
511
- const t = detectMentionToken(textarea.value, caret);
512
- setToken(t);
513
- setHighlight(0);
514
- }, []);
515
- const handleChange = useCallback3((e) => {
516
- onChange(e.target.value);
517
- refreshToken(e.target);
518
- }, [onChange, refreshToken]);
519
- const insertMention = useCallback3((committer) => {
520
- if (!token)
521
- return;
522
- const ta = internalRef.current;
523
- if (!ta)
524
- return;
525
- const tag = `@${firstNameSlug(committer.name)}`;
526
- const next = `${value.slice(0, token.start)}${tag} ${value.slice(token.end)}`;
527
- onChange(next);
528
- setToken(null);
529
- const newCaret = token.start + tag.length + 1;
530
- requestAnimationFrame(() => {
531
- ta.focus();
532
- ta.setSelectionRange(newCaret, newCaret);
533
- });
534
- }, [token, value, onChange]);
535
- const handleKeyDown = useCallback3((e) => {
536
- if (token && filtered.length > 0) {
537
- if (e.key === "ArrowDown") {
538
- e.preventDefault();
539
- setHighlight((h) => (h + 1) % filtered.length);
540
- return;
541
- }
542
- if (e.key === "ArrowUp") {
543
- e.preventDefault();
544
- setHighlight((h) => (h - 1 + filtered.length) % filtered.length);
545
- return;
546
- }
547
- if (e.key === "Enter" || e.key === "Tab") {
548
- e.preventDefault();
549
- const pick = filtered[highlight] ?? filtered[0];
550
- if (pick)
551
- insertMention(pick);
552
- return;
553
- }
554
- if (e.key === "Escape") {
555
- e.preventDefault();
556
- setToken(null);
557
- return;
558
- }
559
- }
560
- onKeyDown?.(e);
561
- }, [token, filtered, highlight, insertMention, onKeyDown]);
562
- const handleSelect = useCallback3((e) => {
563
- refreshToken(e.currentTarget);
564
- }, [refreshToken]);
565
- return /* @__PURE__ */ jsxs("div", {
566
- style: { position: "relative" },
567
- children: [
568
- /* @__PURE__ */ jsx3("textarea", {
569
- ref: setRef,
570
- className,
571
- value,
572
- placeholder,
573
- rows,
574
- disabled,
575
- "aria-label": ariaLabel,
576
- onChange: handleChange,
577
- onKeyDown: handleKeyDown,
578
- onFocus,
579
- onSelect: handleSelect,
580
- onClick: handleSelect
581
- }),
582
- token && filtered.length > 0 ? /* @__PURE__ */ jsx3("ul", {
583
- className: "cm-mention-popup",
584
- role: "listbox",
585
- "aria-label": "Mention suggestions",
586
- style: { left: 0, top: "100%" },
587
- children: filtered.map((c, i) => {
588
- const selected = i === highlight;
589
- return /* @__PURE__ */ jsxs("li", {
590
- role: "option",
591
- "aria-selected": selected,
592
- className: "cm-mention-popup__item",
593
- onMouseEnter: () => setHighlight(i),
594
- onMouseDown: (ev) => {
595
- ev.preventDefault();
596
- insertMention(c);
597
- },
598
- children: [
599
- /* @__PURE__ */ jsxs("span", {
600
- className: "cm-mention-popup__name",
601
- children: [
602
- "@",
603
- firstNameSlug(c.name)
604
- ]
605
- }),
606
- /* @__PURE__ */ jsx3("span", {
607
- className: "cm-mention-popup__email",
608
- children: c.email
609
- })
610
- ]
611
- }, `${c.name}-${c.email}`);
612
- })
613
- }) : null
614
- ]
615
- });
616
- }
617
- function CommentPin({
618
- comment,
619
- sequence,
620
- focused,
621
- onClick
622
- }) {
623
- const ref = useRef3(null);
624
- const rafRef = useRef3(null);
625
- useEffect3(() => {
626
- const tick = () => {
627
- rafRef.current = null;
628
- const pin = ref.current;
629
- if (!pin)
630
- return;
631
- let pos = screenRectFor(comment.selector);
632
- if (!pos && comment.bounds) {
633
- pos = {
634
- x: comment.bounds.x,
635
- y: comment.bounds.y,
636
- w: comment.bounds.w,
637
- h: comment.bounds.h
638
- };
639
- }
640
- if (!pos) {
641
- pin.style.display = "none";
642
- rafRef.current = requestAnimationFrame(tick);
643
- return;
644
- }
645
- pin.style.display = "grid";
646
- const left = Math.round(pos.x + pos.w - 12);
647
- const top = Math.round(pos.y - 12);
648
- pin.style.left = `${left}px`;
649
- pin.style.top = `${top}px`;
650
- rafRef.current = requestAnimationFrame(tick);
651
- };
652
- rafRef.current = requestAnimationFrame(tick);
653
- return () => {
654
- if (rafRef.current != null)
655
- cancelAnimationFrame(rafRef.current);
656
- };
657
- }, [comment.selector, comment.bounds]);
658
- const author = comment.author?.trim() || "unknown";
659
- const label = `Comment ${sequence} by ${author}`;
660
- return /* @__PURE__ */ jsx3("button", {
661
- ref,
662
- type: "button",
663
- className: "cm-pin",
664
- "data-resolved": comment.status === "resolved" ? "true" : "false",
665
- "data-focused": focused ? "true" : "false",
666
- "data-comment-pin": comment.id,
667
- "aria-label": label,
668
- "aria-expanded": focused,
669
- title: comment.text.slice(0, 200),
670
- onClick: (e) => {
671
- e.preventDefault();
672
- e.stopPropagation();
673
- onClick(comment.id);
674
- },
675
- children: sequence
676
- });
677
- }
678
- function CommentComposer({
679
- state,
680
- onSubmit,
681
- onCancel
682
- }) {
683
- const [text, setText] = useState3("");
684
- const textareaRef = useRef3(null);
685
- const cardRef = useRef3(null);
686
- const rafRef = useRef3(null);
687
- useEffect3(() => {
688
- const tick = () => {
689
- rafRef.current = null;
690
- const node = cardRef.current;
691
- if (!node)
692
- return;
693
- const anchor = computeAnchor(state);
694
- node.style.left = `${Math.round(anchor.x)}px`;
695
- node.style.top = `${Math.round(anchor.y)}px`;
696
- rafRef.current = requestAnimationFrame(tick);
697
- };
698
- rafRef.current = requestAnimationFrame(tick);
699
- return () => {
700
- if (rafRef.current != null)
701
- cancelAnimationFrame(rafRef.current);
702
- };
703
- }, [state]);
704
- useEffect3(() => {
705
- textareaRef.current?.focus();
706
- }, []);
707
- const trySubmit = useCallback3(() => {
708
- const v = text.trim();
709
- if (!v)
710
- return;
711
- onSubmit(v);
712
- }, [text, onSubmit]);
713
- const onKeyDown = useCallback3((e) => {
714
- if (e.key === "Escape") {
715
- e.preventDefault();
716
- onCancel();
717
- return;
718
- }
719
- if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
720
- e.preventDefault();
721
- trySubmit();
722
- }
723
- }, [onCancel, trySubmit]);
724
- const selectorChip = useMemo3(() => {
725
- const s = state.selection.selector || "";
726
- if (!s)
727
- return state.selection.tag || "canvas";
728
- const cd = s.match(/data-cd-id="([^"]+)"/);
729
- if (cd)
730
- return `cd:${cd[1]}`;
731
- return s.length > 36 ? `${s.slice(0, 33)}…` : s;
732
- }, [state.selection]);
733
- return /* @__PURE__ */ jsxs("div", {
734
- ref: cardRef,
735
- className: "cm-composer",
736
- role: "dialog",
737
- "aria-label": "New comment",
738
- onClick: (e) => e.stopPropagation(),
739
- onPointerDown: (e) => e.stopPropagation(),
740
- children: [
741
- /* @__PURE__ */ jsxs("div", {
742
- className: "cm-composer__head",
743
- children: [
744
- /* @__PURE__ */ jsx3("span", {
745
- children: "New comment"
746
- }),
747
- /* @__PURE__ */ jsx3("span", {
748
- className: "cm-composer__selector",
749
- children: selectorChip
750
- })
751
- ]
752
- }),
753
- /* @__PURE__ */ jsx3(MentionAwareTextarea, {
754
- textareaRef,
755
- className: "cm-composer__textarea",
756
- value: text,
757
- placeholder: "Type a comment. ⌘↵ to save · Esc to cancel · @name to tag",
758
- onChange: setText,
759
- onKeyDown,
760
- rows: 3,
761
- ariaLabel: "Comment body"
762
- }),
763
- /* @__PURE__ */ jsxs("div", {
764
- className: "cm-composer__actions",
765
- children: [
766
- /* @__PURE__ */ jsx3("button", {
767
- type: "button",
768
- className: "cm-btn",
769
- onClick: onCancel,
770
- children: "Cancel"
771
- }),
772
- /* @__PURE__ */ jsx3("button", {
773
- type: "button",
774
- className: "cm-btn cm-btn--primary",
775
- disabled: !text.trim(),
776
- onClick: trySubmit,
777
- children: "Save"
778
- })
779
- ]
780
- })
781
- ]
782
- });
783
- }
784
- function CommentThread({
785
- comment,
786
- onClose,
787
- onPatch,
788
- onDelete,
789
- onReply
790
- }) {
791
- const dialogRef = useRef3(null);
792
- const replyRef = useRef3(null);
793
- const rafRef = useRef3(null);
794
- const [reply, setReply] = useState3("");
795
- const [sending, setSending] = useState3(false);
796
- useEffect3(() => {
797
- const tick = () => {
798
- rafRef.current = null;
799
- const node = dialogRef.current;
800
- if (!node)
801
- return;
802
- const anchor = computeThreadAnchor(comment);
803
- node.style.left = `${Math.round(anchor.x)}px`;
804
- node.style.top = `${Math.round(anchor.y)}px`;
805
- rafRef.current = requestAnimationFrame(tick);
806
- };
807
- rafRef.current = requestAnimationFrame(tick);
808
- return () => {
809
- if (rafRef.current != null)
810
- cancelAnimationFrame(rafRef.current);
811
- };
812
- }, [comment]);
813
- useEffect3(() => {
814
- dialogRef.current?.focus();
815
- const pinId = comment.id;
816
- return () => {
817
- const pin = document.querySelector(`[data-comment-pin="${pinId}"]`);
818
- pin?.focus();
819
- };
820
- }, [comment.id]);
821
- useEffect3(() => {
822
- if (typeof document === "undefined")
823
- return;
824
- const onKey = (e) => {
825
- if (e.key !== "Escape")
826
- return;
827
- const root = dialogRef.current;
828
- if (!root)
829
- return;
830
- if (root.contains(e.target) || document.activeElement === root) {
831
- e.preventDefault();
832
- onClose();
833
- }
834
- };
835
- document.addEventListener("keydown", onKey);
836
- return () => document.removeEventListener("keydown", onKey);
837
- }, [onClose]);
838
- const trySendReply = useCallback3(async () => {
839
- const v = reply.trim();
840
- if (!v || sending)
841
- return;
842
- setSending(true);
843
- const ok = await onReply(v);
844
- setSending(false);
845
- if (ok) {
846
- setReply("");
847
- replyRef.current?.focus();
848
- }
849
- }, [reply, sending, onReply]);
850
- const onReplyKeyDown = useCallback3((e) => {
851
- if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
852
- e.preventDefault();
853
- trySendReply();
854
- }
855
- }, [trySendReply]);
856
- const headId = `cm-thread-head-${comment.id}`;
857
- const selectorChip = formatSelectorChip(comment.selector, "");
858
- return /* @__PURE__ */ jsxs("div", {
859
- ref: dialogRef,
860
- className: "cm-thread",
861
- role: "dialog",
862
- "aria-labelledby": headId,
863
- tabIndex: -1,
864
- onClick: (e) => e.stopPropagation(),
865
- onPointerDown: (e) => e.stopPropagation(),
866
- children: [
867
- /* @__PURE__ */ jsxs("div", {
868
- className: "cm-thread__head",
869
- id: headId,
870
- children: [
871
- /* @__PURE__ */ jsxs("div", {
872
- className: "cm-thread__head-row",
873
- children: [
874
- /* @__PURE__ */ jsx3("span", {
875
- className: "cm-thread__author",
876
- children: comment.author?.trim() || "unknown"
877
- }),
878
- /* @__PURE__ */ jsx3("span", {
879
- className: "cm-thread__time",
880
- children: formatRelativeTime(comment.created)
881
- }),
882
- /* @__PURE__ */ jsx3("button", {
883
- type: "button",
884
- className: "cm-thread__close",
885
- "aria-label": "Close thread",
886
- title: "Close · Esc",
887
- onClick: onClose,
888
- children: "×"
889
- })
890
- ]
891
- }),
892
- selectorChip ? /* @__PURE__ */ jsx3("code", {
893
- className: "cm-thread__selector",
894
- children: selectorChip
895
- }) : null
896
- ]
897
- }),
898
- /* @__PURE__ */ jsx3("div", {
899
- className: "cm-thread__body",
900
- children: renderBodyWithMentions(comment.text)
901
- }),
902
- (comment.thread ?? []).map((r) => /* @__PURE__ */ jsxs("div", {
903
- className: "cm-thread__reply",
904
- children: [
905
- /* @__PURE__ */ jsxs("div", {
906
- className: "cm-thread__reply-head",
907
- children: [
908
- /* @__PURE__ */ jsx3("span", {
909
- className: "cm-thread__reply-author",
910
- children: r.author?.trim() || "unknown"
911
- }),
912
- /* @__PURE__ */ jsx3("span", {
913
- className: "cm-thread__reply-time",
914
- children: formatRelativeTime(r.created)
915
- })
916
- ]
917
- }),
918
- /* @__PURE__ */ jsx3("div", {
919
- className: "cm-thread__reply-body",
920
- children: renderBodyWithMentions(r.body)
921
- })
922
- ]
923
- }, r.id)),
924
- /* @__PURE__ */ jsxs("div", {
925
- className: "cm-thread__reply-form",
926
- children: [
927
- /* @__PURE__ */ jsx3(MentionAwareTextarea, {
928
- textareaRef: replyRef,
929
- className: "cm-thread__reply-textarea",
930
- value: reply,
931
- placeholder: "Reply… ⌘↵ to send · @name to tag",
932
- onChange: setReply,
933
- onKeyDown: onReplyKeyDown,
934
- rows: 2,
935
- ariaLabel: "Reply",
936
- disabled: sending
937
- }),
938
- /* @__PURE__ */ jsx3("div", {
939
- className: "cm-thread__reply-actions",
940
- children: /* @__PURE__ */ jsx3("button", {
941
- type: "button",
942
- className: "cm-btn cm-btn--primary",
943
- disabled: !reply.trim() || sending,
944
- onClick: () => void trySendReply(),
945
- children: "Send"
946
- })
947
- })
948
- ]
949
- }),
950
- /* @__PURE__ */ jsxs("div", {
951
- className: "cm-thread__actions",
952
- children: [
953
- comment.status === "resolved" ? /* @__PURE__ */ jsx3("button", {
954
- type: "button",
955
- className: "cm-btn",
956
- onClick: () => onPatch({ status: "open" }),
957
- children: "↺ Reopen"
958
- }) : /* @__PURE__ */ jsx3("button", {
959
- type: "button",
960
- className: "cm-btn cm-btn--primary",
961
- onClick: () => {
962
- onPatch({ status: "resolved" });
963
- onClose();
964
- },
965
- children: "✓ Resolve"
966
- }),
967
- /* @__PURE__ */ jsx3("button", {
968
- type: "button",
969
- className: "cm-btn cm-btn--danger",
970
- onClick: () => {
971
- onDelete();
972
- onClose();
973
- },
974
- children: "Delete"
975
- })
976
- ]
977
- })
978
- ]
979
- });
980
- }
981
- function renderBodyWithMentions(text) {
982
- if (!text)
983
- return null;
984
- const re = /(@[\w][\w.-]*)/g;
985
- const parts = text.split(re);
986
- return parts.map((part, i) => {
987
- const key = `${i}:${part}`;
988
- if (i % 2 === 1) {
989
- return /* @__PURE__ */ jsx3("strong", {
990
- "data-mention": "true",
991
- children: part
992
- }, key);
993
- }
994
- return /* @__PURE__ */ jsx3("span", {
995
- children: part
996
- }, key);
997
- });
998
- }
999
- function formatRelativeTime(iso) {
1000
- if (!iso)
1001
- return "";
1002
- const t = Date.parse(iso);
1003
- if (!Number.isFinite(t))
1004
- return "";
1005
- const diffSec = Math.round((Date.now() - t) / 1000);
1006
- if (diffSec < 60)
1007
- return `${Math.max(diffSec, 0)}s ago`;
1008
- if (diffSec < 3600)
1009
- return `${Math.round(diffSec / 60)}m ago`;
1010
- if (diffSec < 86400)
1011
- return `${Math.round(diffSec / 3600)}h ago`;
1012
- return `${Math.round(diffSec / 86400)}d ago`;
1013
- }
1014
- function formatSelectorChip(selector, fallback) {
1015
- if (!selector)
1016
- return fallback;
1017
- const cd = selector.match(/data-cd-id="([^"]+)"/);
1018
- if (cd)
1019
- return `cd:${cd[1]}`;
1020
- return selector.length > 36 ? `${selector.slice(0, 33)}…` : selector;
1021
- }
1022
- function computeThreadAnchor(comment) {
1023
- const rect = comment.selector ? screenRectFor(comment.selector) : null;
1024
- if (rect) {
1025
- return { x: rect.x + rect.w - 12, y: rect.y + 16 };
1026
- }
1027
- if (comment.bounds) {
1028
- return { x: comment.bounds.x + comment.bounds.w - 12, y: comment.bounds.y + 16 };
1029
- }
1030
- return { x: 16, y: 16 };
1031
- }
1032
- function computeAnchor(state) {
1033
- if (state.clientX || state.clientY) {
1034
- return { x: state.clientX, y: state.clientY + 8 };
1035
- }
1036
- if (state.selection.selector) {
1037
- const rect = screenRectFor(state.selection.selector);
1038
- if (rect) {
1039
- return { x: rect.x, y: rect.y + rect.h + 8 };
1040
- }
1041
- }
1042
- return { x: 16, y: 16 };
1043
- }
1044
-
1045
- // dom-selection.ts
1046
- function deriveFile2() {
1047
- if (typeof window === "undefined")
1048
- return;
1049
- try {
1050
- const p = window.location.pathname;
1051
- if (p === "/_canvas-shell.html" || p === "/_canvas-shell") {
1052
- const qs = new URLSearchParams(window.location.search);
1053
- const canvas = qs.get("canvas") ?? "";
1054
- const designRel = (qs.get("designRel") ?? ".design").replace(/^\/+|\/+$/g, "");
1055
- return canvas ? `${designRel}/${canvas}` : undefined;
1056
- }
1057
- return decodeURIComponent(p).replace(/^\//, "");
1058
- } catch {
1059
- return;
1060
- }
1061
- }
1062
- function realClasses(el) {
1063
- if (!el)
1064
- return "";
1065
- return (el.getAttribute("class") ?? "").trim().split(/\s+/).filter((c) => c && !c.startsWith("dgn-") && !c.startsWith("dc-cv-")).join(" ");
1066
- }
1067
- function shortText(el, max) {
1068
- if (!el)
1069
- return "";
1070
- const t = (el.innerText || el.textContent || "").replace(/\s+/g, " ").trim();
1071
- return t.length > max ? `${t.slice(0, max - 1)}…` : t;
1072
- }
1073
- function cssPath(el) {
1074
- if (!el)
1075
- return "";
1076
- const path = [];
1077
- let cur = el;
1078
- while (cur && cur.nodeType === 1 && path.length < 8) {
1079
- const dscEl = cur.getAttribute?.("data-dc-element");
1080
- if (dscEl) {
1081
- path.unshift(`[data-dc-element="${dscEl}"]`);
1082
- break;
1083
- }
1084
- const dscSc = cur.getAttribute?.("data-dc-screen");
1085
- if (dscSc) {
1086
- path.unshift(`[data-dc-screen="${dscSc}"]`);
1087
- break;
1088
- }
1089
- let sel = cur.nodeName.toLowerCase();
1090
- if (cur.id) {
1091
- sel = `#${cur.id}`;
1092
- path.unshift(sel);
1093
- break;
1094
- }
1095
- const cls = realClasses(cur).split(/\s+/).filter(Boolean).slice(0, 2);
1096
- if (cls.length)
1097
- sel += `.${cls.join(".")}`;
1098
- let sib = 1;
1099
- let n = cur.previousElementSibling;
1100
- while (n) {
1101
- sib++;
1102
- n = n.previousElementSibling;
1103
- }
1104
- sel += `:nth-child(${sib})`;
1105
- path.unshift(sel);
1106
- cur = cur.parentElement;
1107
- }
1108
- return path.join(" > ");
1109
- }
1110
- function domPath(el) {
1111
- const hops = [];
1112
- let cur = el;
1113
- while (cur && cur.nodeType === 1 && hops.length < 8) {
1114
- let label = cur.nodeName.toLowerCase();
1115
- const dEl = cur.getAttribute?.("data-dc-element");
1116
- const dSc = cur.getAttribute?.("data-dc-screen");
1117
- if (dEl)
1118
- label += `[data-dc-element="${dEl}"]`;
1119
- else if (dSc)
1120
- label += `[data-dc-screen="${dSc}"]`;
1121
- else if (cur.id)
1122
- label += `#${cur.id}`;
1123
- const cls = realClasses(cur).split(/\s+/).filter(Boolean).slice(0, 2);
1124
- if (cls.length && !dEl && !dSc)
1125
- label += `.${cls.join(".")}`;
1126
- hops.unshift(label);
1127
- cur = cur.parentElement;
1128
- }
1129
- return hops;
1130
- }
1131
- function hoverTargetToSelection(target, file) {
1132
- const el = target.el;
1133
- const rect = el && el.getBoundingClientRect ? el.getBoundingClientRect() : null;
1134
- const cdId = target.cdId;
1135
- const selector = cdId ? `[data-cd-id="${cdId}"]` : !cdId && target.artboardId ? `[data-dc-screen="${target.artboardId}"]` : cssPath(el);
1136
- return {
1137
- file: file ?? deriveFile2(),
1138
- id: cdId ?? undefined,
1139
- selector,
1140
- artboardId: target.artboardId,
1141
- tag: el?.tagName.toLowerCase() ?? "",
1142
- classes: realClasses(el),
1143
- text: shortText(el, 240),
1144
- dom_path: domPath(el),
1145
- bounds: rect ? {
1146
- x: Math.round(rect.left),
1147
- y: Math.round(rect.top),
1148
- w: Math.round(rect.width),
1149
- h: Math.round(rect.height)
1150
- } : null,
1151
- html: el ? (el.outerHTML ?? "").slice(0, 4000) : ""
1152
- };
1153
- }
1154
-
1155
- // input-router.tsx
1156
- import { useEffect as useEffect4 } from "react";
1157
- var ANNOTATION_TOOLS = new Set([
1158
- "pen",
1159
- "shape",
1160
- "rect",
1161
- "ellipse",
1162
- "arrow",
1163
- "sticky",
1164
- "text",
1165
- "eraser"
1166
- ]);
1167
- function isAnnotationTool(t) {
1168
- return ANNOTATION_TOOLS.has(t);
1169
- }
1170
- var metaOrCtrl = (i) => !!(i.metaKey || i.ctrlKey);
1171
- function classify(input) {
1172
- if (input.type === "keydown") {
1173
- if (input.isEditable)
1174
- return { kind: "no-op" };
1175
- if (input.metaKey || input.ctrlKey || input.altKey) {
1176
- if (input.key === "Escape")
1177
- return { kind: "escape" };
1178
- const k2 = (input.key || "").toLowerCase();
1179
- if (!input.altKey && (input.metaKey || input.ctrlKey)) {
1180
- if (k2 === "z" && input.shiftKey)
1181
- return { kind: "redo" };
1182
- if (k2 === "z")
1183
- return { kind: "undo" };
1184
- if (k2 === "y" && !input.shiftKey)
1185
- return { kind: "redo" };
1186
- }
1187
- return { kind: "no-op" };
1188
- }
1189
- const k = (input.key || "").toLowerCase();
1190
- if (k === "v")
1191
- return { kind: "tool", tool: "move" };
1192
- if (k === "h")
1193
- return { kind: "tool", tool: "hand" };
1194
- if (k === "c")
1195
- return { kind: "tool", tool: "comment" };
1196
- if (k === "b")
1197
- return { kind: "tool", tool: "pen" };
1198
- if (k === "r" || k === "o")
1199
- return { kind: "tool", tool: "shape" };
1200
- if (k === "a")
1201
- return { kind: "tool", tool: "arrow" };
1202
- if (k === "n")
1203
- return { kind: "tool", tool: "sticky" };
1204
- if (k === "t")
1205
- return { kind: "tool", tool: "text" };
1206
- if (k === "e")
1207
- return { kind: "tool", tool: "eraser" };
1208
- if (input.key === "Escape")
1209
- return { kind: "escape" };
1210
- return { kind: "no-op" };
1211
- }
1212
- if (input.type === "contextmenu") {
1213
- return {
1214
- kind: "context-menu",
1215
- clientX: input.clientX ?? 0,
1216
- clientY: input.clientY ?? 0
1217
- };
1218
- }
1219
- if (input.type === "pointermove") {
1220
- if (isAnnotationTool(input.activeTool))
1221
- return { kind: "no-op" };
1222
- if (input.activeTool === "hand")
1223
- return { kind: "no-op" };
1224
- if (input.activeTool === "comment") {
1225
- return {
1226
- kind: "hover",
1227
- deep: true,
1228
- clientX: input.clientX ?? 0,
1229
- clientY: input.clientY ?? 0
1230
- };
1231
- }
1232
- if (!metaOrCtrl(input))
1233
- return { kind: "no-op" };
1234
- return {
1235
- kind: "hover",
1236
- deep: true,
1237
- clientX: input.clientX ?? 0,
1238
- clientY: input.clientY ?? 0
1239
- };
1240
- }
1241
- if (input.type === "pointerdown") {
1242
- if (input.button === 2) {
1243
- return {
1244
- kind: "context-menu",
1245
- clientX: input.clientX ?? 0,
1246
- clientY: input.clientY ?? 0
1247
- };
1248
- }
1249
- if (input.button === 1 || input.spaceHeld)
1250
- return { kind: "no-op" };
1251
- if (input.button !== 0)
1252
- return { kind: "no-op" };
1253
- if (isAnnotationTool(input.activeTool) && !metaOrCtrl(input)) {
1254
- return { kind: "no-op" };
1255
- }
1256
- if (input.activeTool === "comment") {
1257
- return {
1258
- kind: "drop-comment",
1259
- clientX: input.clientX ?? 0,
1260
- clientY: input.clientY ?? 0
1261
- };
1262
- }
1263
- if (input.activeTool === "hand")
1264
- return { kind: "no-op" };
1265
- const cmd = metaOrCtrl(input);
1266
- if (!cmd)
1267
- return { kind: "no-op" };
1268
- const shift = !!input.shiftKey;
1269
- return {
1270
- kind: "select",
1271
- mode: shift ? "add" : "replace",
1272
- deep: true,
1273
- clientX: input.clientX ?? 0,
1274
- clientY: input.clientY ?? 0
1275
- };
1276
- }
1277
- return { kind: "no-op" };
1278
- }
1279
- function isEditableTarget(t) {
1280
- if (!t || !t.tagName)
1281
- return false;
1282
- const el = t;
1283
- const tag = el.tagName;
1284
- if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT")
1285
- return true;
1286
- if (el.isContentEditable)
1287
- return true;
1288
- return false;
1289
- }
1290
- function isOverlayTarget(t) {
1291
- if (!t || !t.closest)
1292
- return false;
1293
- return !!t.closest(".cm-composer, .cm-thread, .cm-mention-popup, .cm-pin");
1294
- }
1295
- function useInputRouter(opts) {
1296
- const { hostRef, getActiveTool, isSpaceHeld, callbacks, enabled = true, claimableActions } = opts;
1297
- useEffect4(() => {
1298
- if (!enabled)
1299
- return;
1300
- const host = hostRef.current;
1301
- if (!host)
1302
- return;
1303
- const claim = (action) => claimableActions && action.kind !== "no-op" && !claimableActions.has(action.kind) ? { kind: "no-op" } : action;
1304
- const dispatch = (action) => {
1305
- switch (action.kind) {
1306
- case "hover":
1307
- callbacks.onHover?.(action);
1308
- break;
1309
- case "select":
1310
- callbacks.onSelect?.(action);
1311
- break;
1312
- case "drop-comment":
1313
- callbacks.onDropComment?.(action);
1314
- break;
1315
- case "context-menu":
1316
- callbacks.onContextMenu?.(action);
1317
- break;
1318
- case "tool":
1319
- callbacks.onTool?.(action);
1320
- break;
1321
- case "escape":
1322
- callbacks.onEscape?.();
1323
- break;
1324
- case "undo":
1325
- callbacks.onUndo?.();
1326
- break;
1327
- case "redo":
1328
- callbacks.onRedo?.();
1329
- break;
1330
- case "no-op":
1331
- break;
1332
- }
1333
- };
1334
- const onPointerMove = (e) => {
1335
- const action = claim(classify({
1336
- type: "pointermove",
1337
- button: e.button,
1338
- metaKey: e.metaKey,
1339
- ctrlKey: e.ctrlKey,
1340
- shiftKey: e.shiftKey,
1341
- altKey: e.altKey,
1342
- clientX: e.clientX,
1343
- clientY: e.clientY,
1344
- spaceHeld: isSpaceHeld?.() ?? false,
1345
- activeTool: getActiveTool()
1346
- }));
1347
- dispatch(action);
1348
- };
1349
- const onPointerDown = (e) => {
1350
- if (isOverlayTarget(e.target))
1351
- return;
1352
- const action = claim(classify({
1353
- type: "pointerdown",
1354
- button: e.button,
1355
- metaKey: e.metaKey,
1356
- ctrlKey: e.ctrlKey,
1357
- shiftKey: e.shiftKey,
1358
- altKey: e.altKey,
1359
- clientX: e.clientX,
1360
- clientY: e.clientY,
1361
- spaceHeld: isSpaceHeld?.() ?? false,
1362
- activeTool: getActiveTool()
1363
- }));
1364
- if (action.kind !== "no-op") {
1365
- e.preventDefault();
1366
- e.stopImmediatePropagation();
1367
- }
1368
- dispatch(action);
1369
- };
1370
- const onMouseDown = (e) => {
1371
- if (isOverlayTarget(e.target))
1372
- return;
1373
- const action = claim(classify({
1374
- type: "pointerdown",
1375
- button: e.button,
1376
- metaKey: e.metaKey,
1377
- ctrlKey: e.ctrlKey,
1378
- shiftKey: e.shiftKey,
1379
- altKey: e.altKey,
1380
- clientX: e.clientX,
1381
- clientY: e.clientY,
1382
- spaceHeld: isSpaceHeld?.() ?? false,
1383
- activeTool: getActiveTool()
1384
- }));
1385
- if (action.kind !== "no-op") {
1386
- e.preventDefault();
1387
- e.stopImmediatePropagation();
1388
- }
1389
- };
1390
- const onClick = (e) => {
1391
- if (isOverlayTarget(e.target))
1392
- return;
1393
- const tool = getActiveTool();
1394
- const mod = e.metaKey || e.ctrlKey;
1395
- const wouldRouteKind = tool === "comment" ? "drop-comment" : tool === "move" && mod && e.button === 0 ? "select" : e.button === 2 ? "context-menu" : null;
1396
- if (wouldRouteKind && (!claimableActions || claimableActions.has(wouldRouteKind))) {
1397
- e.preventDefault();
1398
- e.stopImmediatePropagation();
1399
- }
1400
- };
1401
- const onContextMenu = (e) => {
1402
- const action = claim(classify({
1403
- type: "contextmenu",
1404
- clientX: e.clientX,
1405
- clientY: e.clientY,
1406
- metaKey: e.metaKey,
1407
- ctrlKey: e.ctrlKey,
1408
- shiftKey: e.shiftKey,
1409
- altKey: e.altKey,
1410
- activeTool: getActiveTool()
1411
- }));
1412
- if (action.kind === "no-op")
1413
- return;
1414
- e.preventDefault();
1415
- e.stopImmediatePropagation();
1416
- dispatch(action);
1417
- };
1418
- const onKeyDown = (e) => {
1419
- const action = claim(classify({
1420
- type: "keydown",
1421
- key: e.key,
1422
- metaKey: e.metaKey,
1423
- ctrlKey: e.ctrlKey,
1424
- shiftKey: e.shiftKey,
1425
- altKey: e.altKey,
1426
- isEditable: isEditableTarget(e.target),
1427
- activeTool: getActiveTool()
1428
- }));
1429
- if (action.kind === "tool" || action.kind === "escape" || action.kind === "undo" || action.kind === "redo") {
1430
- e.preventDefault();
1431
- }
1432
- dispatch(action);
1433
- };
1434
- host.addEventListener("pointermove", onPointerMove, { passive: true });
1435
- host.addEventListener("pointerdown", onPointerDown, { capture: true });
1436
- host.addEventListener("mousedown", onMouseDown, { capture: true });
1437
- host.addEventListener("click", onClick, { capture: true });
1438
- host.addEventListener("contextmenu", onContextMenu, { capture: true });
1439
- const doc = host.ownerDocument ?? document;
1440
- doc.addEventListener("keydown", onKeyDown, true);
1441
- return () => {
1442
- host.removeEventListener("pointermove", onPointerMove);
1443
- host.removeEventListener("pointerdown", onPointerDown, {
1444
- capture: true
1445
- });
1446
- host.removeEventListener("mousedown", onMouseDown, { capture: true });
1447
- host.removeEventListener("click", onClick, { capture: true });
1448
- host.removeEventListener("contextmenu", onContextMenu, {
1449
- capture: true
1450
- });
1451
- doc.removeEventListener("keydown", onKeyDown, true);
1452
- };
1453
- }, [enabled, hostRef, getActiveTool, isSpaceHeld, callbacks, claimableActions]);
1454
- }
1455
- function resolveHoverTarget(doc, clientX, clientY, opts) {
1456
- const hit = doc.elementFromPoint(clientX, clientY);
1457
- if (!hit)
1458
- return null;
1459
- if (hit.closest?.(".dc-mm, .dc-zoom-tb, .dc-tool-palette, .dc-context-menu, .dc-cv-group-bbox")) {
1460
- return null;
1461
- }
1462
- const artboardEl = hit.closest?.("[data-dc-screen]") ?? null;
1463
- const artboardId = artboardEl?.getAttribute("data-dc-screen") ?? null;
1464
- const bodyEl = hit.closest?.(".dc-artboard-body") ?? null;
1465
- if (!bodyEl) {
1466
- if (artboardEl && artboardId) {
1467
- return { el: artboardEl, cdId: null, artboardId };
1468
- }
1469
- return null;
1470
- }
1471
- if (hit === bodyEl) {
1472
- if (artboardEl && artboardId) {
1473
- return { el: artboardEl, cdId: null, artboardId };
1474
- }
1475
- return null;
1476
- }
1477
- if (opts.deep) {
1478
- const cdId2 = hit.getAttribute?.("data-cd-id") ?? null;
1479
- return { el: hit, cdId: cdId2, artboardId };
1480
- }
1481
- let cur = hit;
1482
- let topCdEl = null;
1483
- while (cur && cur !== bodyEl) {
1484
- if (cur.hasAttribute?.("data-cd-id"))
1485
- topCdEl = cur;
1486
- cur = cur.parentElement;
1487
- }
1488
- const el = topCdEl ?? hit;
1489
- const cdId = el.getAttribute?.("data-cd-id") ?? null;
1490
- return { el, cdId, artboardId };
1491
- }
1492
-
1493
- // use-tool-mode.tsx
1494
- import {
1495
- createContext as createContext3,
1496
- useCallback as useCallback4,
1497
- useContext as useContext3,
1498
- useEffect as useEffect5,
1499
- useMemo as useMemo4,
1500
- useState as useState4
1501
- } from "react";
1502
-
1503
- // canvas-cursors.ts
1504
- function svgCursor(svg, hx, hy, fallback) {
1505
- return `url("data:image/svg+xml,${encodeURIComponent(svg.trim())}") ${hx} ${hy}, ${fallback}`;
1506
- }
1507
- var W = `width='24' height='24' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'`;
1508
- var INK = "#1f1f1f";
1509
- var HALO = "stroke='#ffffff' stroke-linejoin='round' stroke-linecap='round'";
1510
- function kenney(b, w) {
1511
- return `<svg ${W}><path fill='#ffffff' d='${b}'/><path fill='${INK}' d='${w}'/></svg>`;
1512
- }
1513
- var MOVE = svgCursor(kenney("M16.75 23.9 L20 22.55 20.5 22.15 20.35 21.55 18.4 17.75 21.25 17.25 21.75 17 22 16.45 Q22 16.1 21.6 15.9 L11.45 8.2 11.4 8.2 10.85 8 10.2 8.25 10 8.8 10 20.75 Q10 21.55 10.85 21.55 L11.4 21.35 13.6 19.8 15.6 23.5 16.05 23.95 16.75 23.9 M8 8.8 Q7.95 8.05 8.55 7.15 L8.95 6.75 Q9.8 6 10.85 6 11.55 6 12.2 6.35 L12.65 6.6 22.65 14.15 Q24.15 15 24 16.45 24.05 17.55 23.2 18.45 L23.05 18.55 Q22.1 19.3 21.45 19.3 L22.1 20.55 Q22.5 21.2 22.5 22.15 L22.05 23.4 20.9 24.35 20.8 24.4 17.55 25.75 15.25 25.8 Q14.15 25.4 13.75 24.25 L12.95 22.75 12.65 22.9 12.55 23 Q11.75 23.55 10.85 23.55 7.95 23.55 8 20.75 L8 8.8", "M16.75 23.9 L16.05 23.95 15.6 23.5 13.6 19.8 11.4 21.35 10.85 21.55 Q10 21.55 10 20.75 L10 8.8 10.2 8.25 10.85 8 11.4 8.2 11.45 8.2 21.6 15.9 Q22 16.1 22 16.45 L21.75 17 21.25 17.25 18.4 17.75 20.35 21.55 20.5 22.15 20 22.55 16.75 23.9"), 6, 5, "default");
1514
- var HAND = svgCursor(kenney("M28.55 17.8 Q29.4 20.3 28.75 22.8 L28.7 23 28.15 24.55 28.05 24.75 Q26.4 28.2 22.75 29.4 L22.45 29.5 18 29.9 17.75 29.85 Q15.8 29.25 13.8 28.1 L13.45 27.95 Q12 27.05 10.35 26.8 L10.25 26.75 7.9 26.7 7.8 26.7 Q6.1 26.9 4.8 25.8 L4.75 25.8 4.65 25.7 4.6 25.65 Q3.25 24.5 3.05 22.85 L3 22.75 Q2.8 20.95 4 19.5 5.05 18.15 6.75 17.95 L8.4 17.9 7.5 15.55 7.3 15.2 7.2 15 5 10.95 Q3.9 9.15 4.3 7.75 L4.4 7.5 Q4.75 6.15 6.45 5.2 9 3.65 11 5 11.05 4.1 11.5 3.45 12.15 2.1 14.2 1.6 L14.35 1.6 Q18.05 0.6 19.6 4.4 L19.65 4.55 Q20.75 3.65 22.7 3.75 L22.75 3.75 Q26.75 4 27 8.15 L27 8.25 27 8.35 27 8.45 Q26.9 10.75 27.1 12.6 27.15 14.65 28.2 16.75 L28.55 17.8 M26.65 18.4 L26.1 16.8 26.1 16.85 Q24.8 13.7 25 8.35 L25 8.25 Q24.85 5.9 22.6 5.75 20.7 5.65 20.4 7.35 L20.1 7.95 19.5 8.2 18.85 8.05 18.45 7.5 17.75 5.15 Q16.85 2.95 14.7 3.55 L14.65 3.55 Q12.55 4.05 13.15 6.15 L13.85 8.75 13.75 9.45 13.25 9.95 12.55 9.95 12 9.55 10.9 7.7 Q9.5 5.7 7.45 6.9 6.5 7.45 6.25 8.15 6.1 8.9 6.7 9.85 9.2 13.9 10.8 18.65 L10.8 19.3 10.4 19.8 9.75 19.95 Q8.35 19.8 6.95 19.95 6.1 20.05 5.55 20.75 4.9 21.55 5 22.55 5.15 23.55 6 24.2 L6.05 24.25 Q6.75 24.85 7.65 24.7 L7.7 24.7 10.65 24.8 Q12.7 25.15 14.45 26.2 L14.5 26.2 Q16.4 27.35 18.3 27.9 L22.05 27.5 22.1 27.5 Q24.95 26.55 26.25 23.85 L26.8 22.3 Q27.3 20.35 26.65 18.4", "M26.65 18.4 Q27.3 20.35 26.8 22.3 L26.25 23.85 Q24.95 26.55 22.1 27.5 L22.05 27.5 18.3 27.9 Q16.4 27.35 14.5 26.2 L14.45 26.2 Q12.7 25.15 10.65 24.8 L7.7 24.7 7.65 24.7 Q6.75 24.85 6.05 24.25 L6 24.2 Q5.15 23.55 5 22.55 4.9 21.55 5.55 20.75 6.1 20.05 6.95 19.95 8.35 19.8 9.75 19.95 L10.4 19.8 10.8 19.3 10.8 18.65 Q9.2 13.9 6.7 9.85 6.1 8.9 6.25 8.15 6.5 7.45 7.45 6.9 9.5 5.7 10.9 7.7 L12 9.55 12.55 9.95 13.25 9.95 13.75 9.45 13.85 8.75 13.15 6.15 Q12.55 4.05 14.65 3.55 L14.7 3.55 Q16.85 2.95 17.75 5.15 L18.45 7.5 18.85 8.05 19.5 8.2 20.1 7.95 20.4 7.35 Q20.7 5.65 22.6 5.75 24.85 5.9 25 8.25 L25 8.35 Q24.8 13.7 26.1 16.85 L26.1 16.8 26.65 18.4"), 12, 12, "grab");
1515
- var COMMENT = svgCursor(kenney("M8 4 Q4 4 4 8 L4 20 Q4 24 8 24 L12 24 15.3 27.3 16 27.6 16.7 27.3 20 24 24 24 Q28 24 28 20 L28 8 Q28 4 24 4 L8 4 M24 2 Q30 2 30 8 L30 20 Q30 26 24 26 L20.85 26 18.15 28.75 Q17.2 29.6 16 29.6 14.8 29.6 13.9 28.75 L11.15 26 8 26 Q2 26 2 20 L2 8 Q2 2 8 2 L24 2 M24 14 Q24 14.85 23.4 15.4 22.85 16 22 16 21.15 16 20.55 15.4 20 14.85 20 14 20 13.15 20.55 12.55 21.15 12 22 12 22.85 12 23.4 12.55 24 13.15 24 14 M12 14 Q12 14.85 11.4 15.4 10.85 16 10 16 9.15 16 8.55 15.4 8 14.85 8 14 8 13.15 8.55 12.55 9.15 12 10 12 10.85 12 11.4 12.55 12 13.15 12 14 M18 14 Q18 14.85 17.4 15.4 16.85 16 16 16 15.15 16 14.55 15.4 14 14.85 14 14 14 13.15 14.55 12.55 15.15 12 16 12 16.85 12 17.4 12.55 18 13.15 18 14", "M18 14 Q18 13.15 17.4 12.55 16.85 12 16 12 15.15 12 14.55 12.55 14 13.15 14 14 14 14.85 14.55 15.4 15.15 16 16 16 16.85 16 17.4 15.4 18 14.85 18 14 M8 4 L24 4 Q28 4 28 8 L28 20 Q28 24 24 24 L20 24 16.7 27.3 16 27.6 15.3 27.3 12 24 8 24 Q4 24 4 20 L4 8 Q4 4 8 4 M12 14 Q12 13.15 11.4 12.55 10.85 12 10 12 9.15 12 8.55 12.55 8 13.15 8 14 8 14.85 8.55 15.4 9.15 16 10 16 10.85 16 11.4 15.4 12 14.85 12 14 M24 14 Q24 13.15 23.4 12.55 22.85 12 22 12 21.15 12 20.55 12.55 20 13.15 20 14 20 14.85 20.55 15.4 21.15 16 22 16 22.85 16 23.4 15.4 24 14.85 24 14"), 12, 22, "crosshair");
1516
- var PEN = svgCursor(kenney("M5.15 10.85 Q4 9.65 4 8.1 L4 7.95 4 7.85 Q3.95 6.2 5.1 5.15 6.25 4 7.85 4 L7.95 4 8.1 4 Q9.65 4 10.85 5.15 L11 5.3 14.3 5.25 Q15.15 5.25 15.75 5.85 L29.9 20 Q31 21.15 31 22.75 L31 22.85 31 23 Q31.05 24.5 29.9 25.7 L29.55 25.95 25.65 29.9 25.65 29.95 Q24.45 31.1 22.75 31.1 21.2 31.15 20 29.95 L5.85 15.8 Q5.25 15.2 5.25 14.35 L5.25 10.95 5.15 10.85 M19.95 24.2 L18.55 22.8 22.8 18.55 24.2 19.95 19.95 24.2 M28.45 21.4 L14.3 7.25 10.15 7.3 9.4 6.55 Q8.8 5.95 7.95 6 7.1 5.95 6.5 6.55 5.95 7.1 6 7.95 5.95 8.8 6.55 9.4 L7.25 10.1 7.25 14.35 21.4 28.5 Q22 29.1 22.75 29.1 23.6 29.1 24.2 28.5 L28.45 24.25 Q29.05 23.65 29 22.85 29.05 22 28.45 21.4 M9.25 13.5 L9.25 9.3 13.5 9.25 14.3 10.05 10.05 14.3 9.25 13.5 M17.15 21.4 L11.5 15.75 15.75 11.5 21.4 17.15 17.15 21.4", "M17.15 21.4 L21.4 17.15 15.75 11.5 11.5 15.75 17.15 21.4 M28.45 21.4 Q29.05 22 29 22.85 29.05 23.65 28.45 24.25 L24.2 28.5 Q23.6 29.1 22.75 29.1 22 29.1 21.4 28.5 L7.25 14.35 7.25 10.1 6.55 9.4 Q5.95 8.8 6 7.95 5.95 7.1 6.5 6.55 7.1 5.95 7.95 6 8.8 5.95 9.4 6.55 L10.15 7.3 14.3 7.25 28.45 21.4 M19.95 24.2 L24.2 19.95 22.8 18.55 18.55 22.8 19.95 24.2 M9.25 13.5 L10.05 14.3 14.3 10.05 13.5 9.25 9.25 9.3 9.25 13.5"), 20, 20, "crosshair");
1517
- var CROSSHAIR = svgCursor(kenney("M17 2 Q18.2 2 19.15 2.9 20 3.8 20 5 L20 12 27 12 Q28.2 12 29.15 12.9 30 13.8 30 15 L30 17 Q30 18.2 29.15 19.15 28.2 20 27 20 L20 20 20 27 Q20 28.2 19.15 29.15 18.2 30 17 30 L15 30 Q13.8 30 12.9 29.15 12 28.2 12 27 L12 20 5 20 Q3.8 20 2.9 19.15 2 18.2 2 17 L2 15 Q2 13.8 2.9 12.9 3.8 12 5 12 L12 12 12 5 Q12 3.8 12.9 2.9 13.8 2 15 2 L17 2 M14 27 L14.3 27.7 Q14.6 28 15 28 L17 28 17.7 27.7 18 27 18 18.05 18.05 18 27 18 Q27.4 18 27.7 17.7 L28 17 28 15 27.7 14.3 Q27.4 14 27 14 L18 14 18 5 17.7 4.3 17 4 15 4 Q14.6 4 14.3 4.3 14 4.6 14 5 L14 14 5 14 Q4.6 14 4.3 14.3 4 14.6 4 15 L4 17 Q4 17.4 4.3 17.7 4.6 18 5 18 L14 18 14 27", "M14 27 L14 18 5 18 Q4.6 18 4.3 17.7 4 17.4 4 17 L4 15 Q4 14.6 4.3 14.3 4.6 14 5 14 L14 14 14 5 Q14 4.6 14.3 4.3 14.6 4 15 4 L17 4 17.7 4.3 18 5 18 14 27 14 Q27.4 14 27.7 14.3 L28 15 28 17 27.7 17.7 Q27.4 18 27 18 L18.05 18 18 18.05 18 27 17.7 27.7 17 28 15 28 Q14.6 28 14.3 27.7 L14 27"), 12, 12, "crosshair");
1518
- var ERASER = svgCursor(kenney("M3.9 11.35 Q2.3 12.5 3.7 13.9 L16.4 26.65 Q17.85 28.05 19.45 26.9 L27.65 21.15 Q29.3 20 27.85 18.6 L15.15 5.85 Q13.75 4.45 12.1 5.6 L3.9 11.35 M1.05 12.4 Q1 10.95 2.75 9.75 L10.95 4 10.95 3.95 Q14 1.85 16.6 4.45 L29.3 17.2 Q30.8 18.65 30.55 20.1 30.55 21.55 28.8 22.8 L20.6 28.55 20.65 28.55 Q17.7 30.65 15 28.1 L15 28.05 2.3 15.3 2.3 15.35 Q0.8 13.85 1.05 12.4 M13.5 7 L19.85 13.35 11.65 19.15 5.3 12.75 13.5 7", "M13.5 7 L5.3 12.75 11.65 19.15 19.85 13.35 13.5 7 M3.9 11.35 L12.1 5.6 Q13.75 4.45 15.15 5.85 L27.85 18.6 Q29.3 20 27.65 21.15 L19.45 26.9 Q17.85 28.05 16.4 26.65 L3.7 13.9 Q2.3 12.5 3.9 11.35"), 6, 14, "cell");
1519
- var TEXT = svgCursor(`<svg ${W}><path d='M16 4V28M11 4H21M11 28H21' fill='none' ${HALO} stroke-width='5'/><path d='M16 4V28M11 4H21M11 28H21' fill='none' stroke='${INK}' stroke-width='2.25' stroke-linecap='round'/></svg>`, 12, 12, "text");
1520
- var STICKY = svgCursor(`<svg ${W}><path d='M6 5H21L26 10V27H6Z' fill='${INK}' ${HALO} stroke-width='2.5'/><path d='M21 5V11H26' fill='none' ${HALO} stroke-width='2.25'/></svg>`, 5, 5, "crosshair");
1521
- var TOOL_CURSORS = Object.freeze({
1522
- move: MOVE,
1523
- hand: HAND,
1524
- comment: COMMENT,
1525
- pen: PEN,
1526
- shape: CROSSHAIR,
1527
- rect: CROSSHAIR,
1528
- ellipse: CROSSHAIR,
1529
- sticky: STICKY,
1530
- arrow: CROSSHAIR,
1531
- text: TEXT,
1532
- eraser: ERASER
1533
- });
1534
-
1535
- // use-tool-mode.tsx
1536
- import { jsx as jsx4, Fragment as Fragment2 } from "react/jsx-runtime";
1537
- var DEFAULT_TOOLS = Object.freeze([
1538
- { id: "move", label: "Move", shortcut: "V", cursor: TOOL_CURSORS.move },
1539
- { id: "hand", label: "Hand", shortcut: "H", cursor: TOOL_CURSORS.hand },
1540
- { id: "comment", label: "Comment", shortcut: "C", cursor: TOOL_CURSORS.comment },
1541
- { id: "pen", label: "Pen", shortcut: "B", cursor: TOOL_CURSORS.pen },
1542
- { id: "shape", label: "Shape", shortcut: "R", cursor: TOOL_CURSORS.shape },
1543
- { id: "sticky", label: "Sticky", shortcut: "N", cursor: TOOL_CURSORS.sticky },
1544
- { id: "arrow", label: "Arrow", shortcut: "A", cursor: TOOL_CURSORS.arrow },
1545
- { id: "text", label: "Text", shortcut: "T", cursor: TOOL_CURSORS.text },
1546
- { id: "eraser", label: "Eraser", shortcut: "E", cursor: TOOL_CURSORS.eraser }
1547
- ]);
1548
- var ToolContext = createContext3(null);
1549
- function ToolProvider({
1550
- children,
1551
- tools = DEFAULT_TOOLS,
1552
- initial = "move"
1553
- }) {
1554
- const [tool, setToolState] = useState4(initial);
1555
- const [sticky, setSticky] = useState4(() => ({
1556
- tool: null,
1557
- locked: false
1558
- }));
1559
- const setTool = useCallback4((t) => {
1560
- setToolState(t);
1561
- setSticky((prev) => prev.locked && prev.tool === t ? prev : { tool: null, locked: false });
1562
- }, []);
1563
- const toggleSticky = useCallback4((t) => {
1564
- setSticky((prev) => {
1565
- if (prev.locked && prev.tool === t)
1566
- return { tool: null, locked: false };
1567
- return { tool: t, locked: true };
1568
- });
1569
- setToolState(t);
1570
- }, []);
1571
- const clearSticky = useCallback4(() => {
1572
- setSticky({ tool: null, locked: false });
1573
- }, []);
1574
- const [shapeKind, setShapeKind] = useState4("square");
1575
- useEffect5(() => {
1576
- if (typeof document === "undefined")
1577
- return;
1578
- const desc = tools.find((t) => t.id === tool);
1579
- if (!desc)
1580
- return;
1581
- const prev = document.body.style.cursor;
1582
- document.body.style.cursor = desc.cursor;
1583
- let styleEl = document.getElementById("dc-tool-cursor");
1584
- if (!styleEl) {
1585
- styleEl = document.createElement("style");
1586
- styleEl.id = "dc-tool-cursor";
1587
- document.head.appendChild(styleEl);
1588
- }
1589
- styleEl.textContent = `* { cursor: ${desc.cursor} !important; }`;
1590
- if (typeof window !== "undefined" && window.parent && window.parent !== window) {
1591
- try {
1592
- window.parent.postMessage({ dgn: "tool-cursor", tool }, "*");
1593
- } catch {}
1594
- }
1595
- return () => {
1596
- document.body.style.cursor = prev;
1597
- const el = document.getElementById("dc-tool-cursor");
1598
- if (el)
1599
- el.textContent = "";
1600
- };
1601
- }, [tool, tools]);
1602
- const value = useMemo4(() => ({ tool, setTool, tools, sticky, toggleSticky, clearSticky, shapeKind, setShapeKind }), [tool, setTool, tools, sticky, toggleSticky, clearSticky, shapeKind]);
1603
- return /* @__PURE__ */ jsx4(ToolContext.Provider, {
1604
- value,
1605
- children
1606
- });
1607
- }
1608
- function MaybeToolProvider({ children }) {
1609
- const outer = useContext3(ToolContext);
1610
- if (outer)
1611
- return /* @__PURE__ */ jsx4(Fragment2, {
1612
- children
1613
- });
1614
- return /* @__PURE__ */ jsx4(ToolProvider, {
1615
- children
1616
- });
1617
- }
1618
- function useToolMode() {
1619
- const ctx = useContext3(ToolContext);
1620
- if (!ctx) {
1621
- throw new Error("useToolMode must be used inside <ToolProvider>");
1622
- }
1623
- return ctx;
1624
- }
1625
-
1626
- // canvas-comment-mount.tsx
1627
- import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
1628
- var COMMENT_CLAIMS = new Set([
1629
- "drop-comment",
1630
- "tool",
1631
- "escape",
1632
- "hover"
1633
- ]);
1634
- function isBareSpecimen() {
1635
- return typeof document !== "undefined" && !document.querySelector(".dc-canvas");
1636
- }
1637
- function pickSpecimenEl(clientX, clientY) {
1638
- if (typeof document === "undefined")
1639
- return null;
1640
- const hit = document.elementFromPoint(clientX, clientY);
1641
- if (!hit)
1642
- return null;
1643
- if (hit.closest(".cm-composer, .cm-thread, .cm-mention-popup, .cm-pin, [data-mc-hover-halo]")) {
1644
- return null;
1645
- }
1646
- const tag = hit.tagName;
1647
- if (tag === "HTML" || tag === "BODY")
1648
- return null;
1649
- return hit;
1650
- }
1651
- function CommentHost({ children, file }) {
1652
- const { tool, setTool } = useToolMode();
1653
- const selSet = useSelectionSet();
1654
- const hostRef = useRef4(null);
1655
- const [hoverEl, setHoverEl] = useState5(null);
1656
- const toolRef = useRef4(tool);
1657
- toolRef.current = tool;
1658
- const getActiveTool = useMemo5(() => () => toolRef.current, []);
1659
- useEffect6(() => {
1660
- if (tool !== "comment")
1661
- setHoverEl(null);
1662
- }, [tool]);
1663
- useEffect6(() => {
1664
- const host = hostRef.current;
1665
- if (host)
1666
- host.setAttribute("data-active-tool", tool);
1667
- if (typeof document !== "undefined" && document.body) {
1668
- document.body.setAttribute("data-active-tool", tool);
1669
- }
1670
- return () => {
1671
- host?.removeAttribute("data-active-tool");
1672
- };
1673
- }, [tool]);
1674
- useEffect6(() => {
1675
- if (typeof window === "undefined")
1676
- return;
1677
- const onMessage = (e) => {
1678
- const m = e.data;
1679
- if (!m || typeof m !== "object" || m.dgn !== "tool-set")
1680
- return;
1681
- if (typeof m.tool === "string")
1682
- setTool(m.tool);
1683
- };
1684
- window.addEventListener("message", onMessage);
1685
- return () => window.removeEventListener("message", onMessage);
1686
- }, [setTool]);
1687
- useInputRouter({
1688
- hostRef,
1689
- getActiveTool,
1690
- claimableActions: COMMENT_CLAIMS,
1691
- callbacks: {
1692
- onHover: ({ clientX, clientY }) => {
1693
- if (toolRef.current !== "comment" || !isBareSpecimen()) {
1694
- setHoverEl(null);
1695
- return;
1696
- }
1697
- const el = pickSpecimenEl(clientX, clientY);
1698
- setHoverEl((prev) => prev === el ? prev : el);
1699
- },
1700
- onTool: ({ tool: t }) => setTool(t),
1701
- onEscape: () => {
1702
- if (toolRef.current !== "move")
1703
- setTool("move");
1704
- setHoverEl(null);
1705
- selSet.clear();
1706
- if (typeof window !== "undefined") {
1707
- try {
1708
- window.parent.postMessage({ dgn: "force-clear" }, "*");
1709
- } catch {}
1710
- }
1711
- },
1712
- onDropComment: ({ clientX, clientY }) => dropComment(clientX, clientY, selSet, file)
1713
- }
1714
- });
1715
- return /* @__PURE__ */ jsxs2("div", {
1716
- "data-mc-host": true,
1717
- ref: hostRef,
1718
- style: { display: "contents" },
1719
- children: [
1720
- children,
1721
- hoverEl ? /* @__PURE__ */ jsx5(MountHoverHalo, {
1722
- el: hoverEl
1723
- }) : null,
1724
- /* @__PURE__ */ jsx5(CommentsOverlay, {})
1725
- ]
1726
- });
1727
- }
1728
- function MountHoverHalo({ el }) {
1729
- const ref = useRef4(null);
1730
- const targetRef = useRef4(el);
1731
- targetRef.current = el;
1732
- const rafRef = useRef4(null);
1733
- useEffect6(() => {
1734
- const tick = () => {
1735
- rafRef.current = null;
1736
- const div = ref.current;
1737
- const t = targetRef.current;
1738
- if (div && t?.isConnected) {
1739
- const r = t.getBoundingClientRect();
1740
- if (r.width === 0 && r.height === 0) {
1741
- div.style.display = "none";
1742
- } else {
1743
- div.style.display = "block";
1744
- div.style.left = `${Math.round(r.left)}px`;
1745
- div.style.top = `${Math.round(r.top)}px`;
1746
- div.style.width = `${Math.round(r.width)}px`;
1747
- div.style.height = `${Math.round(r.height)}px`;
1748
- }
1749
- } else if (div) {
1750
- div.style.display = "none";
1751
- }
1752
- rafRef.current = requestAnimationFrame(tick);
1753
- };
1754
- rafRef.current = requestAnimationFrame(tick);
1755
- return () => {
1756
- if (rafRef.current != null)
1757
- cancelAnimationFrame(rafRef.current);
1758
- };
1759
- }, []);
1760
- return /* @__PURE__ */ jsx5("div", {
1761
- ref,
1762
- "aria-hidden": "true",
1763
- "data-mc-hover-halo": "",
1764
- style: {
1765
- position: "fixed",
1766
- display: "none",
1767
- pointerEvents: "none",
1768
- zIndex: 2147483646,
1769
- border: "2px solid var(--maude-hud-accent, #d63b1f)",
1770
- borderRadius: "3px",
1771
- boxSizing: "border-box"
1772
- }
1773
- });
1774
- }
1775
- function dropComment(clientX, clientY, selSet, file) {
1776
- if (typeof document === "undefined")
1777
- return;
1778
- let target = resolveHoverTarget(document, clientX, clientY, { deep: true });
1779
- if (!target)
1780
- target = resolveHoverTarget(document, clientX, clientY, { deep: false });
1781
- if (!target && !isBareSpecimen() && typeof document.elementsFromPoint === "function") {
1782
- const stack = document.elementsFromPoint(clientX, clientY);
1783
- for (const candidate of stack) {
1784
- const stamped = candidate.closest?.("[data-cd-id]");
1785
- if (!stamped)
1786
- continue;
1787
- if (!stamped.closest(".dc-artboard-body"))
1788
- continue;
1789
- const artboardEl = stamped.closest("[data-dc-screen]");
1790
- target = {
1791
- el: stamped,
1792
- cdId: stamped.getAttribute("data-cd-id"),
1793
- artboardId: artboardEl?.getAttribute("data-dc-screen") ?? null
1794
- };
1795
- break;
1796
- }
1797
- }
1798
- if (!target && isBareSpecimen()) {
1799
- const el = pickSpecimenEl(clientX, clientY);
1800
- if (el)
1801
- target = { el, cdId: el.getAttribute("data-cd-id"), artboardId: null };
1802
- }
1803
- if (!target) {
1804
- const floatingSel = {
1805
- file,
1806
- id: undefined,
1807
- selector: "",
1808
- artboardId: null,
1809
- tag: "",
1810
- classes: "",
1811
- text: "",
1812
- dom_path: [],
1813
- bounds: { x: clientX - 12, y: clientY - 12, w: 24, h: 24 },
1814
- html: ""
1815
- };
1816
- openComposer(floatingSel, clientX, clientY);
1817
- return;
1818
- }
1819
- const sel = hoverTargetToSelection(target, file);
1820
- selSet.replace(sel);
1821
- openComposer(sel, clientX, clientY);
1822
- }
1823
- function openComposer(selection, clientX, clientY) {
1824
- if (typeof document !== "undefined") {
1825
- try {
1826
- document.dispatchEvent(new CustomEvent("cm:open-composer", { detail: { selection, clientX, clientY } }));
1827
- } catch {}
1828
- }
1829
- if (typeof window !== "undefined") {
1830
- try {
1831
- window.parent.postMessage({ dgn: "comment-compose", selection }, "*");
1832
- } catch {}
1833
- }
1834
- }
1835
- function buildCanvasTree(Canvas, file) {
1836
- return createElement(MaybeToolProvider, null, createElement(MaybeSelectionSetProvider, null, createElement(CommentHost, { file }, createElement(Canvas))));
1837
- }
1838
- function mountCanvas(Canvas, opts) {
1839
- const root = createRoot(opts.rootEl);
1840
- if (!opts.commentsEnabled) {
1841
- root.render(createElement(Canvas));
1842
- return;
1843
- }
1844
- const file = opts.file ?? deriveFile2();
1845
- root.render(createElement(CanvasHmrRuntime, { initialCanvas: Canvas, file }));
1846
- }
1847
- var RUNTIME_KEY = "__maudeCanvasRuntime";
1848
- function OkSignal({
1849
- Canvas,
1850
- file,
1851
- onOk
1852
- }) {
1853
- useEffect6(() => {
1854
- onOk();
1855
- }, []);
1856
- return buildCanvasTree(Canvas, file);
1857
- }
1858
-
1859
- class CanvasErrorBoundary extends Component {
1860
- state = { hasError: false };
1861
- static getDerivedStateFromError() {
1862
- return { hasError: true };
1863
- }
1864
- componentDidCatch() {
1865
- this.props.onError();
1866
- }
1867
- componentDidUpdate(prev) {
1868
- if (prev.attempt !== this.props.attempt && this.state.hasError) {
1869
- this.setState({ hasError: false });
1870
- }
1871
- }
1872
- render() {
1873
- if (this.state.hasError)
1874
- return this.props.fallback();
1875
- return this.props.children;
1876
- }
1877
- }
1878
- function HmrHoldingToast({ message }) {
1879
- return createElement("div", {
1880
- className: "dc-hmr-holding",
1881
- role: "status",
1882
- "aria-live": "polite",
1883
- title: message ? `Holding last working render — ${message}` : "Holding last working render"
1884
- }, "⏸ build error — držím poslední funkční verzi");
1885
- }
1886
- function CanvasHmrRuntime({
1887
- initialCanvas,
1888
- file
1889
- }) {
1890
- const [{ canvas, attempt }, setCanvasState] = useState5({ canvas: initialCanvas, attempt: 0 });
1891
- const [holding, setHoldingState] = useState5({ on: false });
1892
- const lastGood = useRef4(null);
1893
- const canvasRef = useRef4(canvas);
1894
- canvasRef.current = canvas;
1895
- useEffect6(() => {
1896
- const api = {
1897
- remount: (next) => setCanvasState((s) => ({ canvas: next, attempt: s.attempt + 1 })),
1898
- setHolding: (on, message) => setHoldingState(on ? { on: true, message } : { on: false })
1899
- };
1900
- window[RUNTIME_KEY] = api;
1901
- return () => {
1902
- window[RUNTIME_KEY] = undefined;
1903
- };
1904
- }, []);
1905
- const handleOk = useCallback5(() => {
1906
- lastGood.current = canvasRef.current;
1907
- setHoldingState((h) => h.on ? { on: false } : h);
1908
- }, []);
1909
- const handleError = useCallback5(() => {
1910
- setHoldingState({ on: true, message: "render error" });
1911
- }, []);
1912
- const fallback = useCallback5(() => {
1913
- const LG = lastGood.current;
1914
- return LG ? buildCanvasTree(LG, file) : null;
1915
- }, [file]);
1916
- return createElement(Fragment3, null, createElement(CanvasErrorBoundary, { attempt, onError: handleError, fallback }, createElement(OkSignal, { key: attempt, Canvas: canvas, file, onOk: handleOk })), holding.on ? createElement(HmrHoldingToast, { message: holding.message }) : null);
1917
- }
1918
- export {
1919
- mountCanvas,
1920
- CanvasErrorBoundary
1921
- };
1922
-
1923
- //# debugId=620C311D8382D62064756E2164756E21
1924
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vY2FudmFzLWNvbW1lbnQtbW91bnQudHN4IiwgIi4uL2NvbW1lbnRzLW92ZXJsYXkudHN4IiwgIi4uL3VzZS1jb2xsYWIudHN4IiwgIi4uL3VzZS1zZWxlY3Rpb24tc2V0LnRzeCIsICIuLi9kb20tc2VsZWN0aW9uLnRzIiwgIi4uL2lucHV0LXJvdXRlci50c3giLCAiLi4vdXNlLXRvb2wtbW9kZS50c3giLCAiLi4vY2FudmFzLWN1cnNvcnMudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbCiAgICAiLyoqXG4gKiBAZmlsZSAgICAgICBjYW52YXMtY29tbWVudC1tb3VudC50c3gg4oCUIHNoZWxsLW93bmVkIGNvbW1lbnQgbGF5ZXIgKyBtb3VudENhbnZhc1xuICogQHNjb3BlICAgICAgcGx1Z2lucy9kZXNpZ24vZGV2LXNlcnZlci9jYW52YXMtY29tbWVudC1tb3VudC50c3hcbiAqIEBwdXJwb3NlICAgIFRoZSBjYW52YXMgbW91bnQgaGFybmVzcyAoYF9zaGVsbC5odG1sYCkgY2FsbHMgYG1vdW50Q2FudmFzYFxuICogICAgICAgICAgICAgaW5zdGVhZCBvZiByZW5kZXJpbmcgdGhlIGNhbnZhcyBkZWZhdWx0LWV4cG9ydCByYXcuIG1vdW50Q2FudmFzXG4gKiAgICAgICAgICAgICB3cmFwcyBBTlkgZGVmYXVsdCBleHBvcnQg4oCUIGEgYERlc2lnbkNhbnZhc2AgVUkgY2FudmFzIE9SIGEgYmFyZVxuICogICAgICAgICAgICAgRFMgc3BlY2ltZW4g4oCUIGluIGEgTElURSBjb21tZW50IHByb3ZpZGVyIHRyZWUgc28gdGhlIGluLXBsYWNlXG4gKiAgICAgICAgICAgICBjb21tZW50IHRvb2wgd29ya3Mgb24gZXZlcnkgbW91bnRlZCBzdXJmYWNlLlxuICpcbiAqIFdoeSBhIHNpbmdsZSBzaGVsbC1vd25lZCBsYXllciAoRERSIOKAlCBzZWUgcGxhbiDCp1wiS2V5IGRlY2lzaW9uXCIpOlxuICogICAtIENvbW1lbnRzIHVzZWQgdG8gYmUgbW91bnRlZCBvbmx5IGJ5IGBEZXNpZ25DYW52YXNgIChUb29sUHJvdmlkZXIgK1xuICogICAgIFNlbGVjdGlvblNldFByb3ZpZGVyICsgQ29tbWVudHNPdmVybGF5ICsgdGhlIG9uRHJvcENvbW1lbnQgcm91dGVyXG4gKiAgICAgYnJhbmNoKS4gQmFyZSBzcGVjaW1lbnMgKGBzeXN0ZW0vPGRzPi9wcmV2aWV3LyoudHN4YCkgbmV2ZXIgcmVuZGVyXG4gKiAgICAgRGVzaWduQ2FudmFzLCBzbyB0aGV5IGhhZCBubyBjb21tZW50IHRvb2wgYXQgYWxsLlxuICogICAtIEhvaXN0aW5nIHRoZSBjb21tZW50IHN1YnN5c3RlbSBoZXJlIG1ha2VzIGl0IHVuaXZlcnNhbC4gYERlc2lnbkNhbnZhc2BcbiAqICAgICBiZWNvbWVzIGEgQ09OU1VNRVIgb2YgdGhlIHNoZWxsLXByb3ZpZGVkIFRvb2xQcm92aWRlciAvIFNlbGVjdGlvblNldCAvXG4gKiAgICAgQ29tbWVudHNPdmVybGF5ICh2aWEgTWF5YmVUb29sUHJvdmlkZXIgLyBNYXliZVNlbGVjdGlvblNldFByb3ZpZGVyIGFuZFxuICogICAgIGJ5IGRyb3BwaW5nIGl0cyBvd24gPENvbW1lbnRzT3ZlcmxheS8+KS5cbiAqXG4gKiBDb2V4aXN0ZW5jZSB3aXRoIHRoZSBVSS1jYW52YXMgcm91dGVyOiB0aGlzIGxheWVyJ3MgaW5wdXQgcm91dGVyIGlzIGFuXG4gKiBBTkNFU1RPUiBjYXB0dXJlLWxpc3RlbmVyIG92ZXIgdGhlIGNhbnZhcy4gT24gYSBVSSBjYW52YXMsIGBDYW52YXNTaGVsbGBcbiAqIHN0aWxsIHJ1bnMgaXRzIE9XTiByb3V0ZXIgKGhvdmVyIC8gc2VsZWN0IC8gY29udGV4dC1tZW51IC8gdW5kbykuIFRvIGF2b2lkXG4gKiBzd2FsbG93aW5nIHRob3NlIGdlc3R1cmVzLCB0aGlzIHJvdXRlciBwYXNzZXMgYSBuYXJyb3cgYGNsYWltYWJsZUFjdGlvbnNgXG4gKiBhbGxvd2xpc3Qg4oCUIGBkcm9wLWNvbW1lbnRgIC8gYHRvb2xgIC8gYGVzY2FwZWAgLyBgaG92ZXJgLiBgaG92ZXJgIG5ldmVyXG4gKiBwcmV2ZW50RGVmYXVsdHMgc28gdGhlIGlubmVyIHJvdXRlcidzIGhhbG8gaXMgdW5hZmZlY3RlZDsgZXZlcnl0aGluZyBlbHNlXG4gKiAoc2VsZWN0IC8gY29udGV4dC1tZW51IC8gdW5kbykgcHJvcGFnYXRlcyB1bnRvdWNoZWQgdG8gdGhlIGlubmVyIHJvdXRlci5cbiAqL1xuXG5pbXBvcnQge1xuICBDb21wb25lbnQsXG4gIHR5cGUgQ29tcG9uZW50VHlwZSxcbiAgY3JlYXRlRWxlbWVudCxcbiAgRnJhZ21lbnQsXG4gIHR5cGUgUmVhY3ROb2RlLFxuICB1c2VDYWxsYmFjayxcbiAgdXNlRWZmZWN0LFxuICB1c2VNZW1vLFxuICB1c2VSZWYsXG4gIHVzZVN0YXRlLFxufSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBjcmVhdGVSb290IH0gZnJvbSAncmVhY3QtZG9tL2NsaWVudCc7XG5cbmltcG9ydCB7IENvbW1lbnRzT3ZlcmxheSB9IGZyb20gJy4vY29tbWVudHMtb3ZlcmxheS50c3gnO1xuaW1wb3J0IHsgZGVyaXZlRmlsZSwgaG92ZXJUYXJnZXRUb1NlbGVjdGlvbiB9IGZyb20gJy4vZG9tLXNlbGVjdGlvbi50cyc7XG5pbXBvcnQgeyB0eXBlIFJvdXRlckFjdGlvbiwgcmVzb2x2ZUhvdmVyVGFyZ2V0LCB1c2VJbnB1dFJvdXRlciB9IGZyb20gJy4vaW5wdXQtcm91dGVyLnRzeCc7XG5pbXBvcnQge1xuICBNYXliZVNlbGVjdGlvblNldFByb3ZpZGVyLFxuICB0eXBlIFNlbGVjdGlvbixcbiAgdXNlU2VsZWN0aW9uU2V0LFxufSBmcm9tICcuL3VzZS1zZWxlY3Rpb24tc2V0LnRzeCc7XG5pbXBvcnQgeyBNYXliZVRvb2xQcm92aWRlciwgdXNlVG9vbE1vZGUgfSBmcm9tICcuL3VzZS10b29sLW1vZGUudHN4JztcblxuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4vLyBQaGFzZSAyNCDigJQgdGhlIGNvbW1lbnQtbW9kZSBjdXJzb3IgKGFuZCBldmVyeSBvdGhlciB0b29sIGN1cnNvcikgaXMgb3duZWRcbi8vIFNPTEVMWSBieSB1c2UtdG9vbC1tb2RlLnRzeCwgd2hvc2UgYCogeyBjdXJzb3I6IDxLZW5uZXkgZ2x5cGg+ICFpbXBvcnRhbnQgfWBcbi8vIHJ1bGUgaXMgaW5qZWN0ZWQgYnkgdGhlIFRvb2xQcm92aWRlciB0aGlzIGxheWVyIG1vdW50cyAoTWF5YmVUb29sUHJvdmlkZXIpIOKAlFxuLy8gc28gaXQgY292ZXJzIGJhcmUgRFMgc3BlY2ltZW5zIHRvby4gVGhlIG9sZCBgW2RhdGEtbWMtaG9zdF3igKZgL2Bib2R5W+KApl1gXG4vLyBjb21tZW50LWN1cnNvciBydWxlIHVzZWQgdG8gbGl2ZSBoZXJlLCBidXQgaXRzIGhpZ2hlciBzcGVjaWZpY2l0eSBzaGFkb3dlZFxuLy8gdGhlIHVuaWZpZWQgS2VubmV5IGN1cnNvciBvbiBVSSBjYW52YXNlcyAoY29tbWVudC1tb3VudCBzdGFtcHNcbi8vIGBkYXRhLWFjdGl2ZS10b29sYCBvbiA8Ym9keT4sIHNvIGBib2R5W2RhdGEtYWN0aXZlLXRvb2w9XCJjb21tZW50XCJdICpgIG1hdGNoZWRcbi8vIHRoZXJlIGFzIHdlbGwpLiBSZW1vdmVkIHNvIHRoZSBzaW5nbGUgc291cmNlIG9mIHRydXRoIHdpbnMuIFNlZSBERFItMDY3LlxuXG4vLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbi8vIENvbW1lbnRIb3N0IOKAlCBvd25zIHRoZSBsaXRlIGNvbW1lbnQgc3Vic3lzdGVtOiB0aGUgaW5wdXQgcm91dGVyIChjb21tZW50LVxuLy8gc2NvcGVkKSwgdGhlIHNpbmdsZSBDb21tZW50c092ZXJsYXksIHRoZSBjb21tZW50LW1vZGUgY3Vyc29yIGF0dHJpYnV0ZSwgYW5kXG4vLyB0aGUgcGFyZW50IGBkZ246J3Rvb2wtc2V0J2AgbGlzdGVuZXIgKHNvIHRoZSBvdXRlciBtZW51YmFyIGNvbW1lbnQgdG9nZ2xlXG4vLyByZWFjaGVzIHRoZSBpZnJhbWUpLlxuXG4vLyBPbmx5IHRoZXNlIGFjdGlvbiBraW5kcyBhcmUgY2xhaW1lZCBieSB0aGUgbW91bnQtbGF5ZXIgcm91dGVyOyB0aGUgcmVzdFxuLy8gcHJvcGFnYXRlIHRvIGEgVUkgY2FudmFzJ3Mgb3duIHJvdXRlci4gYHRvb2xgICsgYGVzY2FwZWAgYXJlIGFsc28gaGFuZGxlZCBieVxuLy8gdGhlIGlubmVyIHJvdXRlciBvbiBVSSBjYW52YXNlcyDigJQgaWRlbXBvdGVudCAoc2FtZSBzaGFyZWQgcHJvdmlkZXIpLiBgaG92ZXJgXG4vLyBpcyBkaXNwYXRjaGVkIHRvbyAoaXQgbmV2ZXIgcHJldmVudERlZmF1bHRzLCBzbyB0aGUgaW5uZXIgcm91dGVyJ3Mgb3duIGhvdmVyXG4vLyBoYWxvIG9uIGEgVUkgY2FudmFzIGlzIHVuYWZmZWN0ZWQpIOKAlCB3ZSBvbmx5IFBBSU5UIHRoZSBtb3VudC1sYXllciBwcmV2aWV3XG4vLyBoYWxvIG9uIGEgYmFyZSBzcGVjaW1lbiwgd2hlcmUgdGhlcmUgaXMgbm8gaW5uZXIgQ2FudmFzU2hlbGwgaGFsby5cbmNvbnN0IENPTU1FTlRfQ0xBSU1TOiBSZWFkb25seVNldDxSb3V0ZXJBY3Rpb25bJ2tpbmQnXT4gPSBuZXcgU2V0PFJvdXRlckFjdGlvblsna2luZCddPihbXG4gICdkcm9wLWNvbW1lbnQnLFxuICAndG9vbCcsXG4gICdlc2NhcGUnLFxuICAnaG92ZXInLFxuXSk7XG5cbi8vIFRydWUgd2hlbiBubyBEZXNpZ25DYW52YXMvQ2FudmFzU2hlbGwgaXMgbW91bnRlZCBvbiB0aGlzIHN1cmZhY2Ug4oCUIGkuZS4gYVxuLy8gYmFyZSBEUyBzcGVjaW1lbi4gT24gYSBVSSBjYW52YXMgKGAuZGMtY2FudmFzYCBwcmVzZW50KSB0aGUgaW5uZXIgc2hlbGwgb3duc1xuLy8gaG92ZXItaGFsbyBwYWludGluZyArIGByZXNvbHZlSG92ZXJUYXJnZXRgIGVsZW1lbnQgYW5jaG9yaW5nLCBzbyB0aGUgbGl0ZVxuLy8gbGF5ZXIgZGVmZXJzIHRvIGl0LlxuZnVuY3Rpb24gaXNCYXJlU3BlY2ltZW4oKTogYm9vbGVhbiB7XG4gIHJldHVybiB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnICYmICFkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuZGMtY2FudmFzJyk7XG59XG5cbi8vIERlZXBlc3Qgbm9uLWNocm9tZSBlbGVtZW50IHVuZGVyIGEgcG9pbnQg4oCUIHRoZSBjb21tZW50IGFuY2hvciBmb3IgYSBiYXJlXG4vLyBzcGVjaW1lbiAoc3BlY2ltZW5zIGFyZW4ndCBzdGFtcGVkIHdpdGggYGRhdGEtY2QtaWRgIGFuZCBoYXZlIG5vXG4vLyBgLmRjLWFydGJvYXJkLWJvZHlgLCBzbyBgcmVzb2x2ZUhvdmVyVGFyZ2V0YCByZXR1cm5zIG51bGwgZm9yIHRoZW0pLlxuZnVuY3Rpb24gcGlja1NwZWNpbWVuRWwoY2xpZW50WDogbnVtYmVyLCBjbGllbnRZOiBudW1iZXIpOiBIVE1MRWxlbWVudCB8IG51bGwge1xuICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykgcmV0dXJuIG51bGw7XG4gIGNvbnN0IGhpdCA9IGRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQoY2xpZW50WCwgY2xpZW50WSkgYXMgSFRNTEVsZW1lbnQgfCBudWxsO1xuICBpZiAoIWhpdCkgcmV0dXJuIG51bGw7XG4gIC8vIE5ldmVyIGFuY2hvciB0byBjb21tZW50IGNocm9tZSBvciB0aGUgZG9jdW1lbnQgcm9vdC5cbiAgaWYgKGhpdC5jbG9zZXN0KCcuY20tY29tcG9zZXIsIC5jbS10aHJlYWQsIC5jbS1tZW50aW9uLXBvcHVwLCAuY20tcGluLCBbZGF0YS1tYy1ob3Zlci1oYWxvXScpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgY29uc3QgdGFnID0gaGl0LnRhZ05hbWU7XG4gIGlmICh0YWcgPT09ICdIVE1MJyB8fCB0YWcgPT09ICdCT0RZJykgcmV0dXJuIG51bGw7XG4gIHJldHVybiBoaXQ7XG59XG5cbmZ1bmN0aW9uIENvbW1lbnRIb3N0KHsgY2hpbGRyZW4sIGZpbGUgfTogeyBjaGlsZHJlbjogUmVhY3ROb2RlOyBmaWxlOiBzdHJpbmcgfCB1bmRlZmluZWQgfSkge1xuICBjb25zdCB7IHRvb2wsIHNldFRvb2wgfSA9IHVzZVRvb2xNb2RlKCk7XG4gIGNvbnN0IHNlbFNldCA9IHVzZVNlbGVjdGlvblNldCgpO1xuICBjb25zdCBob3N0UmVmID0gdXNlUmVmPEhUTUxEaXZFbGVtZW50IHwgbnVsbD4obnVsbCk7XG4gIC8vIEhvdmVyLXByZXZpZXcgaGFsbyB0YXJnZXQgKGJhcmUgc3BlY2ltZW5zIG9ubHkg4oCUIHNlZSBpc0JhcmVTcGVjaW1lbikuXG4gIGNvbnN0IFtob3ZlckVsLCBzZXRIb3ZlckVsXSA9IHVzZVN0YXRlPEhUTUxFbGVtZW50IHwgbnVsbD4obnVsbCk7XG5cbiAgLy8gTGF0ZXN0IHRvb2wgZm9yIHRoZSByb3V0ZXIgKHJlYWQgYXQgZXZlbnQgdGltZSwgbm90IGNhcHR1cmVkKS5cbiAgY29uc3QgdG9vbFJlZiA9IHVzZVJlZih0b29sKTtcbiAgdG9vbFJlZi5jdXJyZW50ID0gdG9vbDtcbiAgY29uc3QgZ2V0QWN0aXZlVG9vbCA9IHVzZU1lbW8oKCkgPT4gKCkgPT4gdG9vbFJlZi5jdXJyZW50LCBbXSk7XG5cbiAgLy8gRHJvcCB0aGUgcHJldmlldyBoYWxvIHdoZW5ldmVyIHdlIGxlYXZlIGNvbW1lbnQgbW9kZS5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAodG9vbCAhPT0gJ2NvbW1lbnQnKSBzZXRIb3ZlckVsKG51bGwpO1xuICB9LCBbdG9vbF0pO1xuXG4gIC8vIFJlZmxlY3QgdGhlIGFjdGl2ZSB0b29sIG9udG8gdGhlIGhvc3QgKGFuZCBib2R5LCBzaW5jZSB0aGUgaG9zdCBpc1xuICAvLyBkaXNwbGF5OmNvbnRlbnRzIGFuZCBjYW4ndCBjYXJyeSBhIHBhaW50YWJsZSBjdXJzb3IpLiBDb21tZW50LW1vZGUgQ1NTXG4gIC8vIGtleXMgb2ZmIGBbZGF0YS1hY3RpdmUtdG9vbD1cImNvbW1lbnRcIl1gLlxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IGhvc3QgPSBob3N0UmVmLmN1cnJlbnQ7XG4gICAgaWYgKGhvc3QpIGhvc3Quc2V0QXR0cmlidXRlKCdkYXRhLWFjdGl2ZS10b29sJywgdG9vbCk7XG4gICAgaWYgKHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcgJiYgZG9jdW1lbnQuYm9keSkge1xuICAgICAgZG9jdW1lbnQuYm9keS5zZXRBdHRyaWJ1dGUoJ2RhdGEtYWN0aXZlLXRvb2wnLCB0b29sKTtcbiAgICB9XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGhvc3Q/LnJlbW92ZUF0dHJpYnV0ZSgnZGF0YS1hY3RpdmUtdG9vbCcpO1xuICAgIH07XG4gIH0sIFt0b29sXSk7XG5cbiAgLy8gUGFyZW50IGBkZ246J3Rvb2wtc2V0J2Ag4oCUIHRoZSBvdXRlciBkZXYtc2VydmVyIG1lbnViYXIgcG9zdHMgdGhpcyB3aGVuIHRoZVxuICAvLyB1c2VyIHRvZ2dsZXMgdGhlIGNvbW1lbnQgdG9vbC4gTWlycm9ycyBjYW52YXMtc2hlbGwncyBsaXN0ZW5lciBzbyB0aGVcbiAgLy8gdG9nZ2xlIHJlYWNoZXMgYmFyZSBzcGVjaW1lbnMgdG9vICh3aGljaCBoYXZlIG5vIGlubmVyIHNoZWxsIGxpc3RlbmVyKS5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybjtcbiAgICBjb25zdCBvbk1lc3NhZ2UgPSAoZTogTWVzc2FnZUV2ZW50KSA9PiB7XG4gICAgICBjb25zdCBtID0gZS5kYXRhIGFzIHsgZGduPzogc3RyaW5nOyB0b29sPzogc3RyaW5nIH0gfCBudWxsO1xuICAgICAgaWYgKCFtIHx8IHR5cGVvZiBtICE9PSAnb2JqZWN0JyB8fCBtLmRnbiAhPT0gJ3Rvb2wtc2V0JykgcmV0dXJuO1xuICAgICAgaWYgKHR5cGVvZiBtLnRvb2wgPT09ICdzdHJpbmcnKSBzZXRUb29sKG0udG9vbCBhcyBuZXZlcik7XG4gICAgfTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9uTWVzc2FnZSk7XG4gICAgcmV0dXJuICgpID0+IHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25NZXNzYWdlKTtcbiAgfSwgW3NldFRvb2xdKTtcblxuICB1c2VJbnB1dFJvdXRlcih7XG4gICAgaG9zdFJlZixcbiAgICBnZXRBY3RpdmVUb29sLFxuICAgIGNsYWltYWJsZUFjdGlvbnM6IENPTU1FTlRfQ0xBSU1TLFxuICAgIGNhbGxiYWNrczoge1xuICAgICAgb25Ib3ZlcjogKHsgY2xpZW50WCwgY2xpZW50WSB9KSA9PiB7XG4gICAgICAgIC8vIFBhaW50IGEgcHJldmlldyBoYWxvIG9ubHkgb24gYmFyZSBzcGVjaW1lbnM7IGEgVUkgY2FudmFzJ3Mgb3duXG4gICAgICAgIC8vIENhbnZhc1NoZWxsIEhvdmVySGFsbyBvd25zIHRoZSBjb21tZW50LW1vZGUgcHJldmlldyB0aGVyZS5cbiAgICAgICAgaWYgKHRvb2xSZWYuY3VycmVudCAhPT0gJ2NvbW1lbnQnIHx8ICFpc0JhcmVTcGVjaW1lbigpKSB7XG4gICAgICAgICAgc2V0SG92ZXJFbChudWxsKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZWwgPSBwaWNrU3BlY2ltZW5FbChjbGllbnRYLCBjbGllbnRZKTtcbiAgICAgICAgc2V0SG92ZXJFbCgocHJldikgPT4gKHByZXYgPT09IGVsID8gcHJldiA6IGVsKSk7XG4gICAgICB9LFxuICAgICAgb25Ub29sOiAoeyB0b29sOiB0IH0pID0+IHNldFRvb2wodCksXG4gICAgICBvbkVzY2FwZTogKCkgPT4ge1xuICAgICAgICBpZiAodG9vbFJlZi5jdXJyZW50ICE9PSAnbW92ZScpIHNldFRvb2woJ21vdmUnKTtcbiAgICAgICAgc2V0SG92ZXJFbChudWxsKTtcbiAgICAgICAgc2VsU2V0LmNsZWFyKCk7XG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICB3aW5kb3cucGFyZW50LnBvc3RNZXNzYWdlKHsgZGduOiAnZm9yY2UtY2xlYXInIH0sICcqJyk7XG4gICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAvKiBwYXJlbnQgZGV0YWNoZWQgKi9cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBvbkRyb3BDb21tZW50OiAoeyBjbGllbnRYLCBjbGllbnRZIH0pID0+IGRyb3BDb21tZW50KGNsaWVudFgsIGNsaWVudFksIHNlbFNldCwgZmlsZSksXG4gICAgfSxcbiAgfSk7XG5cbiAgLy8gYGRpc3BsYXk6IGNvbnRlbnRzYCBrZWVwcyB0aGUgc3BlY2ltZW4ncyBvd24gZmxleC9ncmlkIGxheW91dCBieXRlLVxuICAvLyBpZGVudGljYWwg4oCUIHRoZSBob3N0IGJveCBjb250cmlidXRlcyBub3RoaW5nIHRvIGxheW91dC4gVGhlIGZpeGVkLXBvc2l0aW9uXG4gIC8vIENvbW1lbnRzT3ZlcmxheSByZW5kZXJzIGZpbmUgYXMgYSBjaGlsZCByZWdhcmRsZXNzLlxuICByZXR1cm4gKFxuICAgIDxkaXYgZGF0YS1tYy1ob3N0IHJlZj17aG9zdFJlZn0gc3R5bGU9e3sgZGlzcGxheTogJ2NvbnRlbnRzJyB9fT5cbiAgICAgIHtjaGlsZHJlbn1cbiAgICAgIHtob3ZlckVsID8gPE1vdW50SG92ZXJIYWxvIGVsPXtob3ZlckVsfSAvPiA6IG51bGx9XG4gICAgICA8Q29tbWVudHNPdmVybGF5IC8+XG4gICAgPC9kaXY+XG4gICk7XG59XG5cbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuLy8gTW91bnRIb3ZlckhhbG8g4oCUIGZpeGVkLXBvc2l0aW9uIG91dGxpbmUgdHJhY2tpbmcgdGhlIGhvdmVyZWQgZWxlbWVudCdzIHNjcmVlblxuLy8gYm91bmRzIHZpYSByQUYuIElubGluZS1zdHlsZWQgKG5vIGRlcGVuZGVuY3kgb24gY2FudmFzLWxpYidzIEhBTE9fQ1NTLCB3aGljaFxuLy8gYSBiYXJlIHNwZWNpbWVuIGRvZXNuJ3QgbG9hZCkuIE1pcnJvcnMgY2FudmFzLXNoZWxsJ3MgSG92ZXJIYWxvIHZpc3VhbGx5LlxuXG5mdW5jdGlvbiBNb3VudEhvdmVySGFsbyh7IGVsIH06IHsgZWw6IEhUTUxFbGVtZW50IH0pIHtcbiAgY29uc3QgcmVmID0gdXNlUmVmPEhUTUxEaXZFbGVtZW50IHwgbnVsbD4obnVsbCk7XG4gIGNvbnN0IHRhcmdldFJlZiA9IHVzZVJlZjxIVE1MRWxlbWVudD4oZWwpO1xuICB0YXJnZXRSZWYuY3VycmVudCA9IGVsO1xuICBjb25zdCByYWZSZWYgPSB1c2VSZWY8bnVtYmVyIHwgbnVsbD4obnVsbCk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBjb25zdCB0aWNrID0gKCkgPT4ge1xuICAgICAgcmFmUmVmLmN1cnJlbnQgPSBudWxsO1xuICAgICAgY29uc3QgZGl2ID0gcmVmLmN1cnJlbnQ7XG4gICAgICBjb25zdCB0ID0gdGFyZ2V0UmVmLmN1cnJlbnQ7XG4gICAgICBpZiAoZGl2ICYmIHQ/LmlzQ29ubmVjdGVkKSB7XG4gICAgICAgIGNvbnN0IHIgPSB0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICBpZiAoci53aWR0aCA9PT0gMCAmJiByLmhlaWdodCA9PT0gMCkge1xuICAgICAgICAgIGRpdi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRpdi5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgICAgICBkaXYuc3R5bGUubGVmdCA9IGAke01hdGgucm91bmQoci5sZWZ0KX1weGA7XG4gICAgICAgICAgZGl2LnN0eWxlLnRvcCA9IGAke01hdGgucm91bmQoci50b3ApfXB4YDtcbiAgICAgICAgICBkaXYuc3R5bGUud2lkdGggPSBgJHtNYXRoLnJvdW5kKHIud2lkdGgpfXB4YDtcbiAgICAgICAgICBkaXYuc3R5bGUuaGVpZ2h0ID0gYCR7TWF0aC5yb3VuZChyLmhlaWdodCl9cHhgO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGRpdikge1xuICAgICAgICBkaXYuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgIH1cbiAgICAgIHJhZlJlZi5jdXJyZW50ID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRpY2spO1xuICAgIH07XG4gICAgcmFmUmVmLmN1cnJlbnQgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUodGljayk7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGlmIChyYWZSZWYuY3VycmVudCAhPSBudWxsKSBjYW5jZWxBbmltYXRpb25GcmFtZShyYWZSZWYuY3VycmVudCk7XG4gICAgfTtcbiAgfSwgW10pO1xuXG4gIHJldHVybiAoXG4gICAgPGRpdlxuICAgICAgcmVmPXtyZWZ9XG4gICAgICBhcmlhLWhpZGRlbj1cInRydWVcIlxuICAgICAgZGF0YS1tYy1ob3Zlci1oYWxvPVwiXCJcbiAgICAgIHN0eWxlPXt7XG4gICAgICAgIHBvc2l0aW9uOiAnZml4ZWQnLFxuICAgICAgICBkaXNwbGF5OiAnbm9uZScsXG4gICAgICAgIHBvaW50ZXJFdmVudHM6ICdub25lJyxcbiAgICAgICAgekluZGV4OiAyMTQ3NDgzNjQ2LFxuICAgICAgICBib3JkZXI6ICcycHggc29saWQgdmFyKC0tbWF1ZGUtaHVkLWFjY2VudCwgI2Q2M2IxZiknLFxuICAgICAgICBib3JkZXJSYWRpdXM6ICczcHgnLFxuICAgICAgICBib3hTaXppbmc6ICdib3JkZXItYm94JyxcbiAgICAgIH19XG4gICAgLz5cbiAgKTtcbn1cblxuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4vLyBDb21tZW50IGRyb3Ag4oCUIGdlbmVyaWMgcGF0aCBsaWZ0ZWQgZnJvbSBjYW52YXMtc2hlbGwncyBvbkRyb3BDb21tZW50LiBXb3Jrc1xuLy8gd2l0aCBvciB3aXRob3V0IGFydGJvYXJkczogZGVlcC9zaGFsbG93IHJlc29sdmVIb3ZlclRhcmdldCDihpIgZWxlbWVudHNGcm9tUG9pbnRcbi8vIGRhdGEtY2QtaWQgY2xpbWIg4oaSIGZsb2F0aW5nIGZhbGxiYWNrLiBEaXNwYXRjaGVzIGBjbTpvcGVuLWNvbXBvc2VyYCBmb3IgdGhlXG4vLyBpbi1pZnJhbWUgb3ZlcmxheSArIHBvc3RzIGBjb21tZW50LWNvbXBvc2VgIHRvIHRoZSBwYXJlbnQgZm9yIGxlZ2FjeSBtb2Nrcy5cblxuZnVuY3Rpb24gZHJvcENvbW1lbnQoXG4gIGNsaWVudFg6IG51bWJlcixcbiAgY2xpZW50WTogbnVtYmVyLFxuICBzZWxTZXQ6IHsgcmVwbGFjZTogKHM6IFNlbGVjdGlvbikgPT4gdm9pZCB9LFxuICBmaWxlOiBzdHJpbmcgfCB1bmRlZmluZWRcbik6IHZvaWQge1xuICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykgcmV0dXJuO1xuICBsZXQgdGFyZ2V0ID0gcmVzb2x2ZUhvdmVyVGFyZ2V0KGRvY3VtZW50LCBjbGllbnRYLCBjbGllbnRZLCB7IGRlZXA6IHRydWUgfSk7XG4gIGlmICghdGFyZ2V0KSB0YXJnZXQgPSByZXNvbHZlSG92ZXJUYXJnZXQoZG9jdW1lbnQsIGNsaWVudFgsIGNsaWVudFksIHsgZGVlcDogZmFsc2UgfSk7XG4gIC8vIFVJLWNhbnZhcyByZWNvdmVyeSDigJQgd2hlbiBib3RoIHBhc3NlcyBiYWlsIG9uIGEgYHBvaW50ZXItZXZlbnRzOiBub25lYFxuICAvLyBkZWNvcmF0aW9uLCBlbnVtZXJhdGUgdGhlIHN0YWNrIGFuZCBjbGltYiB0aGUgZmlyc3QgYGRhdGEtY2QtaWRgIGFuY2VzdG9yXG4gIC8vIGluc2lkZSBhbiBhcnRib2FyZCBib2R5LiBTa2lwcGVkIG9uIGJhcmUgc3BlY2ltZW5zLCB3aGljaCBpbnN0ZWFkIGFuY2hvciB0b1xuICAvLyB0aGUgZXhhY3QgaG92ZXJlZCBlbGVtZW50IGJlbG93IChzbyB0aGUgcGluIG1hdGNoZXMgdGhlIGhvdmVyIHByZXZpZXcgaGFsbykuXG4gIGlmICghdGFyZ2V0ICYmICFpc0JhcmVTcGVjaW1lbigpICYmIHR5cGVvZiBkb2N1bWVudC5lbGVtZW50c0Zyb21Qb2ludCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNvbnN0IHN0YWNrID0gZG9jdW1lbnQuZWxlbWVudHNGcm9tUG9pbnQoY2xpZW50WCwgY2xpZW50WSk7XG4gICAgZm9yIChjb25zdCBjYW5kaWRhdGUgb2Ygc3RhY2spIHtcbiAgICAgIGNvbnN0IHN0YW1wZWQgPSAoY2FuZGlkYXRlIGFzIEVsZW1lbnQpLmNsb3Nlc3Q/LignW2RhdGEtY2QtaWRdJykgYXMgSFRNTEVsZW1lbnQgfCBudWxsO1xuICAgICAgaWYgKCFzdGFtcGVkKSBjb250aW51ZTtcbiAgICAgIGlmICghc3RhbXBlZC5jbG9zZXN0KCcuZGMtYXJ0Ym9hcmQtYm9keScpKSBjb250aW51ZTtcbiAgICAgIGNvbnN0IGFydGJvYXJkRWwgPSBzdGFtcGVkLmNsb3Nlc3QoJ1tkYXRhLWRjLXNjcmVlbl0nKTtcbiAgICAgIHRhcmdldCA9IHtcbiAgICAgICAgZWw6IHN0YW1wZWQsXG4gICAgICAgIGNkSWQ6IHN0YW1wZWQuZ2V0QXR0cmlidXRlKCdkYXRhLWNkLWlkJyksXG4gICAgICAgIGFydGJvYXJkSWQ6IGFydGJvYXJkRWw/LmdldEF0dHJpYnV0ZSgnZGF0YS1kYy1zY3JlZW4nKSA/PyBudWxsLFxuICAgICAgfTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIC8vIEJhcmUtc3BlY2ltZW4gYW5jaG9yIOKAlCBzcGVjaW1lbnMgaGF2ZSBubyBgLmRjLWFydGJvYXJkLWJvZHlgLCBzb1xuICAvLyByZXNvbHZlSG92ZXJUYXJnZXQgYmFpbHMuIEFuY2hvciB0byB0aGUgRVhBQ1QgZWxlbWVudCB1bmRlciB0aGUgY3Vyc29yICh0aGVcbiAgLy8gc2FtZSBvbmUgcGlja1NwZWNpbWVuRWwgaGlnaGxpZ2h0cyBmb3IgdGhlIGhvdmVyIHByZXZpZXcpLCB2aWEgaXRzIG93blxuICAvLyBkYXRhLWNkLWlkIHdoZW4gc3RhbXBlZCwgZWxzZSBhIGNzc1BhdGggc2VsZWN0b3Ig4oCUIHNvIHRoZSBkcm9wcGVkIHBpbiBsYW5kc1xuICAvLyBvbiB0aGUgcHJldmlld2VkIGVsZW1lbnQgaW5zdGVhZCBvZiBmbG9hdGluZy5cbiAgaWYgKCF0YXJnZXQgJiYgaXNCYXJlU3BlY2ltZW4oKSkge1xuICAgIGNvbnN0IGVsID0gcGlja1NwZWNpbWVuRWwoY2xpZW50WCwgY2xpZW50WSk7XG4gICAgaWYgKGVsKSB0YXJnZXQgPSB7IGVsLCBjZElkOiBlbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtY2QtaWQnKSwgYXJ0Ym9hcmRJZDogbnVsbCB9O1xuICB9XG5cbiAgaWYgKCF0YXJnZXQpIHtcbiAgICAvLyBGbG9hdGluZyBjb21tZW50IOKAlCBubyBlbGVtZW50IGFuY2hvciwganVzdCB0aGUgY2xpY2sgcG9pbnQgKGUuZy4gYSBjbGlja1xuICAgIC8vIG9uIGVtcHR5IGNhbnZhcy9zcGVjaW1lbiBkZWFkIHNwYWNlKS4gVGhlIG92ZXJsYXkgcmVuZGVycyBhIHBpbiBhdCB0aGVcbiAgICAvLyBzdG9yZWQgYm91bmRzLlxuICAgIGNvbnN0IGZsb2F0aW5nU2VsOiBTZWxlY3Rpb24gPSB7XG4gICAgICBmaWxlLFxuICAgICAgaWQ6IHVuZGVmaW5lZCxcbiAgICAgIHNlbGVjdG9yOiAnJyxcbiAgICAgIGFydGJvYXJkSWQ6IG51bGwsXG4gICAgICB0YWc6ICcnLFxuICAgICAgY2xhc3NlczogJycsXG4gICAgICB0ZXh0OiAnJyxcbiAgICAgIGRvbV9wYXRoOiBbXSxcbiAgICAgIGJvdW5kczogeyB4OiBjbGllbnRYIC0gMTIsIHk6IGNsaWVudFkgLSAxMiwgdzogMjQsIGg6IDI0IH0sXG4gICAgICBodG1sOiAnJyxcbiAgICB9O1xuICAgIG9wZW5Db21wb3NlcihmbG9hdGluZ1NlbCwgY2xpZW50WCwgY2xpZW50WSk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3Qgc2VsID0gaG92ZXJUYXJnZXRUb1NlbGVjdGlvbih0YXJnZXQsIGZpbGUpO1xuICBzZWxTZXQucmVwbGFjZShzZWwpO1xuICBvcGVuQ29tcG9zZXIoc2VsLCBjbGllbnRYLCBjbGllbnRZKTtcbn1cblxuZnVuY3Rpb24gb3BlbkNvbXBvc2VyKHNlbGVjdGlvbjogU2VsZWN0aW9uLCBjbGllbnRYOiBudW1iZXIsIGNsaWVudFk6IG51bWJlcik6IHZvaWQge1xuICBpZiAodHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJykge1xuICAgIHRyeSB7XG4gICAgICBkb2N1bWVudC5kaXNwYXRjaEV2ZW50KFxuICAgICAgICBuZXcgQ3VzdG9tRXZlbnQoJ2NtOm9wZW4tY29tcG9zZXInLCB7IGRldGFpbDogeyBzZWxlY3Rpb24sIGNsaWVudFgsIGNsaWVudFkgfSB9KVxuICAgICAgKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8qIEN1c3RvbUV2ZW50IGFic2VudCDigJQgZmFsbCB0aHJvdWdoIHRvIHBhcmVudCBwYXRoICovXG4gICAgfVxuICB9XG4gIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICAgIHRyeSB7XG4gICAgICB3aW5kb3cucGFyZW50LnBvc3RNZXNzYWdlKHsgZGduOiAnY29tbWVudC1jb21wb3NlJywgc2VsZWN0aW9uIH0sICcqJyk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvKiBwYXJlbnQgZGV0YWNoZWQgKi9cbiAgICB9XG4gIH1cbn1cblxuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4vLyBtb3VudENhbnZhcyDigJQgdGhlIHNoZWxsIGhhcm5lc3MgZW50cnkuIFJlbmRlcnMgdGhlIGNhbnZhcyB3cmFwcGVkIGluIHRoZSBsaXRlXG4vLyBjb21tZW50IHRyZWUsIG9yIGJhcmUgd2hlbiBjb21tZW50cyBhcmUgZGlzYWJsZWQgKGdhbGxlcnkgdGh1bWJuYWlscyBwYXNzXG4vLyBgY29tbWVudHNFbmFibGVkOiBmYWxzZWAgdmlhIGA/Y29tbWVudHM9MGApLlxuXG5leHBvcnQgaW50ZXJmYWNlIE1vdW50Q2FudmFzT3B0aW9ucyB7XG4gIHJvb3RFbDogSFRNTEVsZW1lbnQ7XG4gIC8qKiBDYW52YXMgZmlsZSBrZXkgKGRlc2lnblJlbC1wcmVmaXhlZCkuIERlZmF1bHRzIHRvIGBkZXJpdmVGaWxlKClgLiAqL1xuICBmaWxlPzogc3RyaW5nO1xuICAvKiogV2hlbiBmYWxzZSwgdGhlIGNvbW1lbnQgbGF5ZXIgaXMgc2tpcHBlZCDigJQgdGhlIGNhbnZhcyByZW5kZXJzIHJhdy4gKi9cbiAgY29tbWVudHNFbmFibGVkOiBib29sZWFuO1xufVxuXG4vLyBUaGUgbGl0ZSBwcm92aWRlciB0cmVlIHdyYXBwaW5nIGEgY2FudmFzIGNvbXBvbmVudCAodG9vbCArIHNlbGVjdGlvbiArXG4vLyBjb21tZW50IGxheWVyKS4gUHVsbGVkIG91dCBzbyBib3RoIHRoZSBsaXZlIHJlbmRlciBhbmQgdGhlIGVycm9yLWZhbGxiYWNrXG4vLyByZW5kZXIgYnVpbGQgdGhlIGlkZW50aWNhbCBlbnZlbG9wZS5cbi8vXG4vLyBOQjogdGhlIENhbnZhc0FjdGl2aXR5UHJvdmlkZXIgKFBoYXNlIDEzIC8gRERSLTAyOSkgaXMgTk9UIG1vdW50ZWQgaGVyZSDigJQgaXRcbi8vIGxpdmVzIGluc2lkZSBgRGVzaWduQ2FudmFzYCAoY2FudmFzLWxpYikuIGNvbW1lbnQtbW91bnQuanMgYW5kIGNhbnZhcy1saWIgYXJlXG4vLyBTRVBBUkFURSBidW5kbGVzLCBzbyBhIGNvbnRleHQgcHJvdmlkZWQgaGVyZSB3b3VsZCBiZSBhIGRpZmZlcmVudCBpbnN0YW5jZVxuLy8gZnJvbSB0aGUgb25lIERDQXJ0Ym9hcmQgKGNhbnZhcy1saWIpIGNvbnN1bWVzLiBTYW1lIHJlYXNvbmluZyB0aGUgcmVhbFxuLy8gVG9vbFByb3ZpZGVyIGxpdmVzIGluIERlc2lnbkNhbnZhcywgbm90IGluIHRoaXMgbGF5ZXIncyBNYXliZVRvb2xQcm92aWRlci5cbmZ1bmN0aW9uIGJ1aWxkQ2FudmFzVHJlZShDYW52YXM6IENvbXBvbmVudFR5cGUsIGZpbGU6IHN0cmluZyB8IHVuZGVmaW5lZCk6IFJlYWN0Tm9kZSB7XG4gIHJldHVybiBjcmVhdGVFbGVtZW50KFxuICAgIE1heWJlVG9vbFByb3ZpZGVyLFxuICAgIG51bGwsXG4gICAgY3JlYXRlRWxlbWVudChcbiAgICAgIE1heWJlU2VsZWN0aW9uU2V0UHJvdmlkZXIsXG4gICAgICBudWxsLFxuICAgICAgY3JlYXRlRWxlbWVudChDb21tZW50SG9zdCwgeyBmaWxlIH0sIGNyZWF0ZUVsZW1lbnQoQ2FudmFzKSlcbiAgICApXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtb3VudENhbnZhcyhDYW52YXM6IENvbXBvbmVudFR5cGUsIG9wdHM6IE1vdW50Q2FudmFzT3B0aW9ucyk6IHZvaWQge1xuICBjb25zdCByb290ID0gY3JlYXRlUm9vdChvcHRzLnJvb3RFbCk7XG4gIGlmICghb3B0cy5jb21tZW50c0VuYWJsZWQpIHtcbiAgICByb290LnJlbmRlcihjcmVhdGVFbGVtZW50KENhbnZhcykpO1xuICAgIHJldHVybjtcbiAgfVxuICBjb25zdCBmaWxlID0gb3B0cy5maWxlID8/IGRlcml2ZUZpbGUoKTtcbiAgcm9vdC5yZW5kZXIoY3JlYXRlRWxlbWVudChDYW52YXNIbXJSdW50aW1lLCB7IGluaXRpYWxDYW52YXM6IENhbnZhcywgZmlsZSB9KSk7XG59XG5cbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuLy8gUGhhc2UgMTMuMSAvIEREUi0wNzcg4oCUIEhNUiBlcnJvciByZXNpbGllbmNlIGR1cmluZyBhZ2VudCBlZGl0aW5nLlxuLy9cbi8vIFdoZW4gYW4gYWdlbnQgKGAvZGVzaWduOmVkaXRgIC8gYC9kZXNpZ246bmV3YCkgbGl2ZS1lZGl0cyBhIGNhbnZhcywgYVxuLy8gaGFsZi1zYXZlZCBmaWxlIChtaXNzaW5nIGltcG9ydCwgdW5kZWZpbmVkIHN5bWJvbCwgdHJhbnNwaWxlIGVycm9yKSB1c2VkIHRvXG4vLyBibGFuayB0aGUgY2FudmFzIHRvIHdoaXRlOiB0aGUgc2hlbGwgZGlkIGBsb2NhdGlvbi5yZWxvYWQoKWAgc3RyYWlnaHQgaW50byB0aGVcbi8vIGJyb2tlbiBtb2R1bGUuIFRoZSBzaGVsbCBub3cgc29mdC1yZWxvYWRzIChpbXBvcnQtYmVmb3JlLXN3YXAsIHNlZVxuLy8gYHRlbXBsYXRlcy9fc2hlbGwuaHRtbGApIHNvIGEgYnVpbGQvaW1wb3J0IGVycm9yIG5ldmVyIHRlYXJzIGRvd24gdGhlIGdvb2Rcbi8vIHJlbmRlci4gVGhpcyBydW50aW1lIGNsb3NlcyB0aGUgcmVtYWluaW5nIGdhcCDigJQgYSAqcmVuZGVyLXRpbWUqIHRocm93IOKAlCBieVxuLy8ga2VlcGluZyB0aGUgbGFzdCBnb29kIGNhbnZhcyBtb3VudGVkIHZpYSBhbiBlcnJvciBib3VuZGFyeSBhbmQgc3VyZmFjaW5nIGFcbi8vIFwiaG9sZGluZyBsYXN0IGdvb2RcIiB0b2FzdCBpbnN0ZWFkIG9mIGEgd2hpdGUgc2NyZWVuLiBTdHJpY3RseSBnYXRlZCBieSB0aGVcbi8vIHNoZWxsIG9uIGFnZW50LWFjdGl2ZTsgbWFudWFsIGVkaXRzIGtlZXAgdGhlIHBsYWluIHJlbG9hZCAoc28gdGhpcyBpcyBpbmVydFxuLy8gZm9yIHNvbG8gaGFuZC1lZGl0aW5nKS4gVGhlIHJ1bnRpbWUgZXhwb3NlcyBpdHMgc3dhcC9ob2xkIEFQSSBvblxuLy8gYHdpbmRvdy5fX21hdWRlQ2FudmFzUnVudGltZWAgKHRoZSBzYW1lIHdpbmRvdy1oYW5kc2hha2Ugc3R5bGUgdGhlIHNoZWxsXG4vLyBhbHJlYWR5IHVzZXMgZm9yIGBfX2NhbnZhc19yZWxfX2AgZXRjLikuXG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FudmFzUnVudGltZUFwaSB7XG4gIC8qKiBTd2FwIGluIGEgZnJlc2hseS1pbXBvcnRlZCBjYW52YXMgbW9kdWxlJ3MgZGVmYXVsdCBleHBvcnQgKHN1Y2Nlc3MgcGF0aCkuICovXG4gIHJlbW91bnQ6IChuZXh0OiBDb21wb25lbnRUeXBlKSA9PiB2b2lkO1xuICAvKiogU2hvdy9oaWRlIHRoZSBcImhvbGRpbmcgbGFzdCBnb29kXCIgdG9hc3QgKGJ1aWxkLWVycm9yIHBhdGggZnJvbSB0aGUgc2hlbGwpLiAqL1xuICBzZXRIb2xkaW5nOiAob246IGJvb2xlYW4sIG1lc3NhZ2U/OiBzdHJpbmcpID0+IHZvaWQ7XG59XG5cbmNvbnN0IFJVTlRJTUVfS0VZID0gJ19fbWF1ZGVDYW52YXNSdW50aW1lJztcblxuLyoqXG4gKiBGaXJlcyBgb25Pa2Agb25seSB3aGVuIGl0cyBzdWJ0cmVlIENPTU1JVFMg4oCUIGkuZS4gcmVuZGVycyB3aXRob3V0IHRocm93aW5nLiBBXG4gKiByZW5kZXItdGltZSB0aHJvdyBpbiB0aGUgY2FudmFzIHVud2luZHMgdG8gdGhlIGJvdW5kYXJ5IGJlZm9yZSB0aGlzIGNvbW1pdHMsXG4gKiBzbyBgb25Pa2AgbmV2ZXIgcnVucyBhbmQgYGxhc3RHb29kYCBpcyBub3QgYWR2YW5jZWQgdG8gYSBicm9rZW4gbW9kdWxlLlxuICovXG5mdW5jdGlvbiBPa1NpZ25hbCh7XG4gIENhbnZhcyxcbiAgZmlsZSxcbiAgb25Payxcbn06IHtcbiAgQ2FudmFzOiBDb21wb25lbnRUeXBlO1xuICBmaWxlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIG9uT2s6ICgpID0+IHZvaWQ7XG59KSB7XG4gIC8vIGJpb21lLWlnbm9yZSBsaW50L2NvcnJlY3RuZXNzL3VzZUV4aGF1c3RpdmVEZXBlbmRlbmNpZXM6IGZpcmUgb25jZSBwZXIgbW91bnQgKGtleT1hdHRlbXB0IHJlbW91bnRzIHRoaXMpLlxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIG9uT2soKTtcbiAgfSwgW10pO1xuICByZXR1cm4gYnVpbGRDYW52YXNUcmVlKENhbnZhcywgZmlsZSk7XG59XG5cbmV4cG9ydCBjbGFzcyBDYW52YXNFcnJvckJvdW5kYXJ5IGV4dGVuZHMgQ29tcG9uZW50PFxuICB7XG4gICAgYXR0ZW1wdDogbnVtYmVyO1xuICAgIG9uRXJyb3I6ICgpID0+IHZvaWQ7XG4gICAgZmFsbGJhY2s6ICgpID0+IFJlYWN0Tm9kZTtcbiAgICBjaGlsZHJlbjogUmVhY3ROb2RlO1xuICB9LFxuICB7IGhhc0Vycm9yOiBib29sZWFuIH1cbj4ge1xuICBzdGF0ZSA9IHsgaGFzRXJyb3I6IGZhbHNlIH07XG4gIHN0YXRpYyBnZXREZXJpdmVkU3RhdGVGcm9tRXJyb3IoKTogeyBoYXNFcnJvcjogYm9vbGVhbiB9IHtcbiAgICByZXR1cm4geyBoYXNFcnJvcjogdHJ1ZSB9O1xuICB9XG4gIGNvbXBvbmVudERpZENhdGNoKCk6IHZvaWQge1xuICAgIHRoaXMucHJvcHMub25FcnJvcigpO1xuICB9XG4gIGNvbXBvbmVudERpZFVwZGF0ZShwcmV2OiB7IGF0dGVtcHQ6IG51bWJlciB9KTogdm9pZCB7XG4gICAgLy8gQSBuZXcgY2FudmFzIChuZXcgYXR0ZW1wdCkgYXJyaXZlZCDihpIgY2xlYXIgdGhlIGVycm9yIGFuZCB0cnkgcmVuZGVyaW5nIGl0LlxuICAgIGlmIChwcmV2LmF0dGVtcHQgIT09IHRoaXMucHJvcHMuYXR0ZW1wdCAmJiB0aGlzLnN0YXRlLmhhc0Vycm9yKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgaGFzRXJyb3I6IGZhbHNlIH0pO1xuICAgIH1cbiAgfVxuICByZW5kZXIoKTogUmVhY3ROb2RlIHtcbiAgICBpZiAodGhpcy5zdGF0ZS5oYXNFcnJvcikgcmV0dXJuIHRoaXMucHJvcHMuZmFsbGJhY2soKTtcbiAgICByZXR1cm4gdGhpcy5wcm9wcy5jaGlsZHJlbjtcbiAgfVxufVxuXG5mdW5jdGlvbiBIbXJIb2xkaW5nVG9hc3QoeyBtZXNzYWdlIH06IHsgbWVzc2FnZT86IHN0cmluZyB9KTogUmVhY3ROb2RlIHtcbiAgcmV0dXJuIGNyZWF0ZUVsZW1lbnQoXG4gICAgJ2RpdicsXG4gICAge1xuICAgICAgY2xhc3NOYW1lOiAnZGMtaG1yLWhvbGRpbmcnLFxuICAgICAgcm9sZTogJ3N0YXR1cycsXG4gICAgICAnYXJpYS1saXZlJzogJ3BvbGl0ZScsXG4gICAgICB0aXRsZTogbWVzc2FnZSA/IGBIb2xkaW5nIGxhc3Qgd29ya2luZyByZW5kZXIg4oCUICR7bWVzc2FnZX1gIDogJ0hvbGRpbmcgbGFzdCB3b3JraW5nIHJlbmRlcicsXG4gICAgfSxcbiAgICAn4o+4IGJ1aWxkIGVycm9yIOKAlCBkcsW+w61tIHBvc2xlZG7DrSBmdW5rxI1uw60gdmVyemknXG4gICk7XG59XG5cbmZ1bmN0aW9uIENhbnZhc0htclJ1bnRpbWUoe1xuICBpbml0aWFsQ2FudmFzLFxuICBmaWxlLFxufToge1xuICBpbml0aWFsQ2FudmFzOiBDb21wb25lbnRUeXBlO1xuICBmaWxlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG59KTogUmVhY3ROb2RlIHtcbiAgY29uc3QgW3sgY2FudmFzLCBhdHRlbXB0IH0sIHNldENhbnZhc1N0YXRlXSA9IHVzZVN0YXRlKHsgY2FudmFzOiBpbml0aWFsQ2FudmFzLCBhdHRlbXB0OiAwIH0pO1xuICBjb25zdCBbaG9sZGluZywgc2V0SG9sZGluZ1N0YXRlXSA9IHVzZVN0YXRlPHsgb246IGJvb2xlYW47IG1lc3NhZ2U/OiBzdHJpbmcgfT4oeyBvbjogZmFsc2UgfSk7XG4gIGNvbnN0IGxhc3RHb29kID0gdXNlUmVmPENvbXBvbmVudFR5cGUgfCBudWxsPihudWxsKTtcbiAgY29uc3QgY2FudmFzUmVmID0gdXNlUmVmKGNhbnZhcyk7XG4gIGNhbnZhc1JlZi5jdXJyZW50ID0gY2FudmFzO1xuXG4gIC8vIFB1Ymxpc2ggdGhlIHJ1bnRpbWUgQVBJIGZvciB0aGUgc2hlbGwgSE1SIGNsaWVudC5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBjb25zdCBhcGk6IENhbnZhc1J1bnRpbWVBcGkgPSB7XG4gICAgICByZW1vdW50OiAobmV4dCkgPT4gc2V0Q2FudmFzU3RhdGUoKHMpID0+ICh7IGNhbnZhczogbmV4dCwgYXR0ZW1wdDogcy5hdHRlbXB0ICsgMSB9KSksXG4gICAgICBzZXRIb2xkaW5nOiAob24sIG1lc3NhZ2UpID0+IHNldEhvbGRpbmdTdGF0ZShvbiA/IHsgb246IHRydWUsIG1lc3NhZ2UgfSA6IHsgb246IGZhbHNlIH0pLFxuICAgIH07XG4gICAgKHdpbmRvdyBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KVtSVU5USU1FX0tFWV0gPSBhcGk7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICh3aW5kb3cgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilbUlVOVElNRV9LRVldID0gdW5kZWZpbmVkO1xuICAgIH07XG4gIH0sIFtdKTtcblxuICBjb25zdCBoYW5kbGVPayA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBsYXN0R29vZC5jdXJyZW50ID0gY2FudmFzUmVmLmN1cnJlbnQ7XG4gICAgLy8gVGhlIG5ldyBjYW52YXMgcmVuZGVyZWQgY2xlYW4g4oaSIGRyb3AgYW55IGhvbGRpbmcgc3RhdGUuXG4gICAgc2V0SG9sZGluZ1N0YXRlKChoKSA9PiAoaC5vbiA/IHsgb246IGZhbHNlIH0gOiBoKSk7XG4gIH0sIFtdKTtcblxuICBjb25zdCBoYW5kbGVFcnJvciA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBzZXRIb2xkaW5nU3RhdGUoeyBvbjogdHJ1ZSwgbWVzc2FnZTogJ3JlbmRlciBlcnJvcicgfSk7XG4gIH0sIFtdKTtcblxuICBjb25zdCBmYWxsYmFjayA9IHVzZUNhbGxiYWNrKCgpOiBSZWFjdE5vZGUgPT4ge1xuICAgIGNvbnN0IExHID0gbGFzdEdvb2QuY3VycmVudDtcbiAgICByZXR1cm4gTEcgPyBidWlsZENhbnZhc1RyZWUoTEcsIGZpbGUpIDogbnVsbDtcbiAgfSwgW2ZpbGVdKTtcblxuICByZXR1cm4gY3JlYXRlRWxlbWVudChcbiAgICBGcmFnbWVudCxcbiAgICBudWxsLFxuICAgIGNyZWF0ZUVsZW1lbnQoXG4gICAgICBDYW52YXNFcnJvckJvdW5kYXJ5LFxuICAgICAgeyBhdHRlbXB0LCBvbkVycm9yOiBoYW5kbGVFcnJvciwgZmFsbGJhY2sgfSxcbiAgICAgIC8vIGtleT1hdHRlbXB0IOKGkiBlYWNoIHNvZnQtcmVsb2FkIHJlbW91bnRzIGEgZnJlc2ggc3VidHJlZSAoYW5kIHJlc2V0cyB0aGVcbiAgICAgIC8vIGJvdW5kYXJ5J3MgY2hpbGQpLCBtYXRjaGluZyB0aGUgY2xlYW4tc2xhdGUgc2VtYW50aWNzIG9mIGEgZnVsbCByZWxvYWQuXG4gICAgICBjcmVhdGVFbGVtZW50KE9rU2lnbmFsLCB7IGtleTogYXR0ZW1wdCwgQ2FudmFzOiBjYW52YXMsIGZpbGUsIG9uT2s6IGhhbmRsZU9rIH0pXG4gICAgKSxcbiAgICBob2xkaW5nLm9uID8gY3JlYXRlRWxlbWVudChIbXJIb2xkaW5nVG9hc3QsIHsgbWVzc2FnZTogaG9sZGluZy5tZXNzYWdlIH0pIDogbnVsbFxuICApO1xufVxuIiwKICAgICIvKipcbiAqIEBmaWxlICAgICAgIGNvbW1lbnRzLW92ZXJsYXkudHN4IOKAlCBGaWdKYW0tc3R5bGUgaW4tcGxhY2UgY29tbWVudHMgb3ZlcmxheVxuICogQHNjb3BlICAgICAgcGx1Z2lucy9kZXNpZ24vZGV2LXNlcnZlci9jb21tZW50cy1vdmVybGF5LnRzeFxuICogQHB1cnBvc2UgICAgUmVuZGVycyBEUy1zdHlsZWQgY29tbWVudCBwaW5zIChQaGFzZSA2IFRhc2sgMiksIHRoZSBpbi1wbGFjZVxuICogICAgICAgICAgICAgY29tcG9zZXIgYnViYmxlIChUYXNrIDMpLCBhbmQgdGhlIHRocmVhZCBwb3BvdmVyIChUYXNrIDQpXG4gKiAgICAgICAgICAgICBpbnNpZGUgdGhlIGNhbnZhcyBpZnJhbWUuIFNpYmxpbmcgdG8gYGFubm90YXRpb25zLWxheWVyYCDigJRcbiAqICAgICAgICAgICAgIHBvcnRhbHMgaW50byBgLmRjLXdvcmxkYCBzbyBDU1Mgem9vbSArIHRyYW5zbGF0ZSBvbiB0aGUgd29ybGRcbiAqICAgICAgICAgICAgIHBsYW5lIHNjYWxlIGV2ZXJ5IHBpbi9wb3BvdmVyIHVuaWZvcm1seSB3aXRoIHRoZSBhcnRib2FyZHMuXG4gKlxuICogRGF0YSBmbG93IChQaGFzZSA2IFRhc2sgMiDigJQgcGlucyBvbmx5OyBjb21wb3NlciArIHRocmVhZCBsYW5kIGluIFRhc2sgMy80KTpcbiAqICAgMS4gU2hlbGwgKGBjbGllbnQvYXBwLmpzeGApIHB1c2hlcyBgeyBkZ246ICdjb21tZW50cy1zZXQnLCBjb21tZW50cyB9YFxuICogICAgICBpbnRvIHRoZSBpZnJhbWUgd2hlbmV2ZXIgaXRzIGBjb21tZW50c0J5RmlsZVthY3RpdmVQYXRoXWAgY2hhbmdlcy5cbiAqICAgMi4gT3ZlcmxheSBhbHNvIGZldGNoZXMgYC9fY29tbWVudHM/ZmlsZT0uLi5gIG9uIG1vdW50IGFzIGEgc2VsZi1oZWFsIOKAlFxuICogICAgICBsZXRzIHRoZSBvdmVybGF5IHJlbmRlciBldmVuIGlmIHRoZSBzaGVsbCBoYXNuJ3QgYnJvYWRjYXN0IHlldFxuICogICAgICAocmFjZSBvbiBmaXJzdCBpZnJhbWUgbG9hZCkuXG4gKiAgIDMuIFNoZWxsIHB1c2hlcyBgeyBkZ246ICdjb21tZW50LWZvY3VzJywgaWQgfWAgd2hlbiB0aGUgdXNlciBjbGlja3MgYSByb3dcbiAqICAgICAgaW4gdGhlIGNvbW1lbnRzIHBhbmVsIOKAlCBvdmVybGF5IGhpZ2hsaWdodHMgdGhlIG1hdGNoaW5nIHBpbi5cbiAqICAgNC4gT3ZlcmxheSBwb3N0cyBgeyBkZ246ICdjb21tZW50LWNsaWNrJywgaWQgfWAgYmFjayB0byB0aGUgc2hlbGwgd2hlblxuICogICAgICB0aGUgdXNlciBjbGlja3MgYSBwaW4g4oCUIHNhbWUgY2hhbm5lbCB0aGUgbGVnYWN5IGBkZ24tcGluYCBvdmVybGF5XG4gKiAgICAgIHVzZWQ7IHRoZSBzaGVsbCBhbHJlYWR5IHJvdXRlcyBpdCB0byBgc2V0Rm9jdXNlZENvbW1lbnRJZGAuXG4gKlxuICogRmlsdGVyIHJlc3BlY3Qg4oCUIFBoYXNlIDYgVGFzayAyIGRlZmF1bHQgaXMgXCJoaWRlIHJlc29sdmVkXCIuIFRoZSBzaGVsbCB3aWxsXG4gKiBnYWluIGEgYGNvbW1lbnRzLWZpbHRlcmAgY2hhbm5lbCBpbiBUYXNrIDY7IHVudGlsIHRoZW4gdGhlIG92ZXJsYXkgYWx3YXlzXG4gKiBoaWRlcyByZXNvbHZlZCBwaW5zLiBQbGFuLWFsaWduZWQuXG4gKlxuICogUGluIHBvc2l0aW9uIG1hdGgg4oCUIHNlZSBgb2Zmc2V0V2l0aGluV29ybGRgIGJlbG93LiBXZSB3YWxrIG9mZnNldFBhcmVudCB1cFxuICogdG8gYC5kYy13b3JsZGAgdG8gZ2V0IHByZS16b29tIHdvcmxkIGNvb3JkcyBkaXJlY3RseTsgQ1NTIHpvb20gb24gdGhlIHdvcmxkXG4gKiBwbGFuZSB0aGVuIHJlbmRlcnMgdGhlIHBpbiBhdCB0aGUgcmlnaHQgc2NhbGUgd2l0aG91dCB1cyBkb2luZyB6b29tIG1hdGguXG4gKlxuICogVGhlIGxlZ2FjeSB2YW5pbGxhLUpTIGAjZGduLXBpbi1sYXllcmAgaW5qZWN0ZWQgYnkgYGluc3BlY3QudHNgIGlzIGhpZGRlblxuICogb24gbW91bnQgdG8gYXZvaWQgZG91YmxlLXBpbnMgaW5zaWRlIFRTWCBjYW52YXNlcy4gVGhlIGxlZ2FjeSBsYXllciBzdGlsbFxuICogcmVuZGVycyBmb3IgYC5odG1sYCBtb2NrcyB3aGVyZSB0aGlzIFJlYWN0IG92ZXJsYXkgbmV2ZXIgbW91bnRzLlxuICovXG5cbmltcG9ydCB7IHVzZUNhbGxiYWNrLCB1c2VFZmZlY3QsIHVzZU1lbW8sIHVzZVJlZiwgdXNlU3RhdGUgfSBmcm9tICdyZWFjdCc7XG5cbmltcG9ydCB7IHVzZUNvbGxhYiB9IGZyb20gJy4vdXNlLWNvbGxhYi50c3gnO1xuaW1wb3J0IHsgdXNlU2VsZWN0aW9uU2V0T3B0aW9uYWwgfSBmcm9tICcuL3VzZS1zZWxlY3Rpb24tc2V0LnRzeCc7XG5cbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuLy8gVHlwZXMg4oCUIGtlcHQgaW4gc3luYyB3aXRoIGBDb21tZW50YCBpbiBgYXBpLnRzYC4gV2UgbWlycm9yIHRoZSBzaGFwZSByYXRoZXJcbi8vIHRoYW4gaW1wb3J0IHRvIGF2b2lkIHB1bGxpbmcgc2VydmVyIHR5cGVzIGludG8gdGhlIGNhbnZhcyBydW50aW1lIGJ1bmRsZS5cblxuaW50ZXJmYWNlIE92ZXJsYXlCb3VuZHMge1xuICB4OiBudW1iZXI7XG4gIHk6IG51bWJlcjtcbiAgdzogbnVtYmVyO1xuICBoOiBudW1iZXI7XG59XG5cbi8vIFNlbGVjdGlvbiBwYXlsb2FkIHBvc3RlZCBieSBjYW52YXMtc2hlbGwncyBgb25Ecm9wQ29tbWVudGAuIE1pcnJvcnMgdGhlXG4vLyBzaGFwZSBgaG92ZXJUYXJnZXRUb1NlbGVjdGlvbmAgcmV0dXJuczsgd2Uga2VlcCBpdCBsb29zZSBzbyB0aGUgb3ZlcmxheVxuLy8gZG9lc24ndCBkZXBlbmQgb24gY2FudmFzLXNoZWxsIHR5cGVzLlxuaW50ZXJmYWNlIENvbXBvc2VTZWxlY3Rpb24ge1xuICBmaWxlPzogc3RyaW5nO1xuICBpZD86IHN0cmluZztcbiAgc2VsZWN0b3I6IHN0cmluZztcbiAgYXJ0Ym9hcmRJZD86IHN0cmluZyB8IG51bGw7XG4gIHRhZzogc3RyaW5nO1xuICBjbGFzc2VzOiBzdHJpbmc7XG4gIHRleHQ6IHN0cmluZztcbiAgZG9tX3BhdGg6IHN0cmluZ1tdO1xuICBib3VuZHM6IE92ZXJsYXlCb3VuZHMgfCBudWxsO1xuICBodG1sOiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBDb21wb3NlclN0YXRlIHtcbiAgc2VsZWN0aW9uOiBDb21wb3NlU2VsZWN0aW9uO1xuICBjbGllbnRYOiBudW1iZXI7XG4gIGNsaWVudFk6IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIE92ZXJsYXlSZXBseSB7XG4gIGlkOiBzdHJpbmc7XG4gIGF1dGhvcjogc3RyaW5nO1xuICBib2R5OiBzdHJpbmc7XG4gIGNyZWF0ZWQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPdmVybGF5Q29tbWVudCB7XG4gIGlkOiBzdHJpbmc7XG4gIGZpbGU6IHN0cmluZztcbiAgc2VsZWN0b3I6IHN0cmluZztcbiAgYm91bmRzOiBPdmVybGF5Qm91bmRzIHwgbnVsbDtcbiAgdGV4dDogc3RyaW5nO1xuICBzdGF0dXM6ICdvcGVuJyB8ICdyZXNvbHZlZCc7XG4gIGNyZWF0ZWQ6IHN0cmluZztcbiAgcmVzb2x2ZWRfYXQ6IHN0cmluZyB8IG51bGw7XG4gIGF1dGhvcj86IHN0cmluZztcbiAgdGhyZWFkPzogT3ZlcmxheVJlcGx5W107XG4gIG1lbnRpb25zPzogc3RyaW5nW107XG4gIC8vIGRvbV9wYXRoIC8gdGFnIC8gY2xhc3NlcyAvIGh0bWxfZXhjZXJwdCB1bnVzZWQgYXQgb3ZlcmxheSBsYXllcjsga2VwdCBvZmZcbiAgLy8gdGhlIHR5cGUgdG8ga2VlcCB0aGUgc3VyZmFjZSB0aWdodC5cbn1cblxuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4vLyBDU1MgbG9hZCDigJQgc2libGluZyBzdHlsZXNoZWV0LCBmZXRjaGVkIG9uY2UgcGVyIHNlc3Npb24gdmlhIGEgPGxpbms+IHRhZy5cbi8vIElubGluaW5nIHRoZSBmaWxlIGF0IGJ1aWxkIHRpbWUgd291bGQgY29zdCBhbiBleHRyYSBidW5kbGVyIGNvbmZpZzsgdGhlXG4vLyBvdmVybGF5IGlzIGludGVybmFsLW9ubHkgc28gYSBydW50aW1lIDxsaW5rPiBpcyBmaW5lLlxuXG5jb25zdCBDU1NfSFJFRiA9ICcvX2NsaWVudC9jb21tZW50cy1vdmVybGF5LmNzcyc7XG5cbmZ1bmN0aW9uIGVuc3VyZU92ZXJsYXlTdHlsZXMoKTogdm9pZCB7XG4gIGlmICh0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnKSByZXR1cm47XG4gIGlmIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY20tb3ZlcmxheS1jc3MnKSkgcmV0dXJuO1xuICBjb25zdCBsaW5rID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGluaycpO1xuICBsaW5rLmlkID0gJ2NtLW92ZXJsYXktY3NzJztcbiAgbGluay5yZWwgPSAnc3R5bGVzaGVldCc7XG4gIGxpbmsuaHJlZiA9IENTU19IUkVGO1xuICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKGxpbmspO1xufVxuXG4vLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbi8vIEZpbGUgZGVyaXZhdGlvbiDigJQgc2FtZSBsb2dpYyBhcyBjYW52YXMtc2hlbGwudHN4OjpkZXJpdmVGaWxlKCkuIER1cGxpY2F0ZWRcbi8vIGhlcmUgc28gdGhlIG92ZXJsYXkgY2FuIGZldGNoIGl0cyBvd24gY29tbWVudHMgb24gbW91bnQgd2l0aG91dCBpbXBvcnRpbmdcbi8vIGZyb20gY2FudmFzLXNoZWxsICh3aGljaCB3b3VsZCBjcmVhdGUgYSBjeWNsZSkuXG5cbmZ1bmN0aW9uIGRlcml2ZUZpbGUoKTogc3RyaW5nIHwgbnVsbCB7XG4gIGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykgcmV0dXJuIG51bGw7XG4gIHRyeSB7XG4gICAgY29uc3QgcCA9IHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZTtcbiAgICBpZiAocCA9PT0gJy9fY2FudmFzLXNoZWxsLmh0bWwnIHx8IHAgPT09ICcvX2NhbnZhcy1zaGVsbCcpIHtcbiAgICAgIGNvbnN0IHFzID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh3aW5kb3cubG9jYXRpb24uc2VhcmNoKTtcbiAgICAgIGNvbnN0IGNhbnZhcyA9IHFzLmdldCgnY2FudmFzJykgPz8gJyc7XG4gICAgICBjb25zdCBkZXNpZ25SZWwgPSAocXMuZ2V0KCdkZXNpZ25SZWwnKSA/PyAnLmRlc2lnbicpLnJlcGxhY2UoL15cXC8rfFxcLyskL2csICcnKTtcbiAgICAgIHJldHVybiBjYW52YXMgPyBgJHtkZXNpZ25SZWx9LyR7Y2FudmFzfWAgOiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KHApLnJlcGxhY2UoL15cXC8vLCAnJyk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuLy8gUG9zaXRpb24gcmVzb2x2ZXJzIOKAlCBzY3JlZW4gY29vcmRzIHZpYSBnZXRCb3VuZGluZ0NsaWVudFJlY3QuIE1pcnJvcnMgdGhlXG4vLyBgU2VsZWN0aW9uSGFsb3NgIC8gYEhvdmVySGFsb2AgcGF0dGVybiBpbiBjYW52YXMtc2hlbGwudHN4IHNvIHRoZSBjb21tZW50c1xuLy8gbGF5ZXIgY2FuIHJlbmRlciBhcyBhIGZpeGVkLXBvc2l0aW9uIHNpYmxpbmcgb2YgYC5kYy1jYW52YXNgIChhYm92ZSB0aGVcbi8vIGhhbG8gY2hyb21lIGF0IHotaW5kZXggNSkgaW5zdGVhZCBvZiBiZWluZyBwb3J0YWxlZCBpbnRvIGAuZGMtd29ybGRgIHdoZXJlXG4vLyBpdCB3b3VsZCBsb3NlIHRoZSBzdGFja2luZyBiYXR0bGUuXG5cbmZ1bmN0aW9uIHNjcmVlblJlY3RGb3Ioc2VsZWN0b3I6IHN0cmluZyk6IHtcbiAgeDogbnVtYmVyO1xuICB5OiBudW1iZXI7XG4gIHc6IG51bWJlcjtcbiAgaDogbnVtYmVyO1xufSB8IG51bGwge1xuICBpZiAoIXNlbGVjdG9yKSByZXR1cm4gbnVsbDtcbiAgbGV0IGVsOiBIVE1MRWxlbWVudCB8IG51bGwgPSBudWxsO1xuICB0cnkge1xuICAgIGVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3RvcikgYXMgSFRNTEVsZW1lbnQgfCBudWxsO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBpZiAoIWVsIHx8ICFlbC5pc0Nvbm5lY3RlZCkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IHIgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgaWYgKHIud2lkdGggPT09IDAgJiYgci5oZWlnaHQgPT09IDApIHJldHVybiBudWxsO1xuICByZXR1cm4geyB4OiByLmxlZnQsIHk6IHIudG9wLCB3OiByLndpZHRoLCBoOiByLmhlaWdodCB9O1xufVxuXG4vLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbi8vIFB1YmxpYyBjb21wb25lbnQg4oCUIG1vdW50ZWQgZnJvbSBjYW52YXMtc2hlbGwudHN4IGFsb25nc2lkZSBUb29sUGFsZXR0ZSAvXG4vLyBBbm5vdGF0aW9uc0xheWVyIC8gU25hcEd1aWRlT3ZlcmxheS5cblxuZXhwb3J0IGZ1bmN0aW9uIENvbW1lbnRzT3ZlcmxheSgpOiBSZWFjdC5SZWFjdE5vZGUge1xuICBlbnN1cmVPdmVybGF5U3R5bGVzKCk7XG5cbiAgLy8gT3B0aW9uYWwg4oCUIENvbW1lbnRzT3ZlcmxheSBpcyBtb3VudGVkIGluc2lkZSBTZWxlY3Rpb25TZXRQcm92aWRlciBpbiB0aGVcbiAgLy8gc3RhbmRhcmQgQ2FudmFzU2hlbGwgdHJlZSwgYnV0IHN0YXlzIHVzYWJsZSBpZiBhIGhvc3QgZXZlciBlbWJlZHMgaXRcbiAgLy8gb3V0c2lkZSB0aGF0IHByb3ZpZGVyIChyZXR1cm5zIG51bGwgaW5zdGVhZCBvZiB0aHJvd2luZykuXG4gIGNvbnN0IHNlbFNldCA9IHVzZVNlbGVjdGlvblNldE9wdGlvbmFsKCk7XG4gIGNvbnN0IFtjb21tZW50cywgc2V0Q29tbWVudHNdID0gdXNlU3RhdGU8T3ZlcmxheUNvbW1lbnRbXT4oW10pO1xuICBjb25zdCBbZm9jdXNlZElkLCBzZXRGb2N1c2VkSWRdID0gdXNlU3RhdGU8c3RyaW5nIHwgbnVsbD4obnVsbCk7XG4gIGNvbnN0IFtjb21wb3Nlciwgc2V0Q29tcG9zZXJdID0gdXNlU3RhdGU8Q29tcG9zZXJTdGF0ZSB8IG51bGw+KG51bGwpO1xuICBjb25zdCBmaWxlID0gdXNlTWVtbygoKSA9PiBkZXJpdmVGaWxlKCksIFtdKTtcblxuICAvLyBEcm9wIHRoZSBsZWdhY3kgYCNkZ24tcGluLWxheWVyYCBzbyB3ZSBkb24ndCByZW5kZXIgZHVwbGljYXRlIHBpbnMgaW5zaWRlXG4gIC8vIFRTWCBjYW52YXNlcy4gVGhlIGxheWVyIHNoaXBzIGluIGV2ZXJ5IHNlcnZlZCBIVE1MIHBhZ2UgdmlhIGluc3BlY3QudHM7XG4gIC8vIGZvciBgLmh0bWxgIG1vY2tzIChubyBjYW52YXMtc2hlbGwgbW91bnQpIGl0IHN0aWxsIGRvZXMgaXRzIGpvYi5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykgcmV0dXJuO1xuICAgIGNvbnN0IGxlZ2FjeSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkZ24tcGluLWxheWVyJykgYXMgSFRNTEVsZW1lbnQgfCBudWxsO1xuICAgIGlmICghbGVnYWN5KSByZXR1cm47XG4gICAgY29uc3QgcHJldiA9IGxlZ2FjeS5zdHlsZS5kaXNwbGF5O1xuICAgIGxlZ2FjeS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBsZWdhY3kuc3R5bGUuZGlzcGxheSA9IHByZXY7XG4gICAgfTtcbiAgfSwgW10pO1xuXG4gIC8vIE1pcnJvciBhIGNvbW1lbnQgaW50byB0aGUgY2FudmFzIHNlbGVjdGlvbiBzZXQgc28gU2VsZWN0aW9uSGFsb3MgcGFpbnRzXG4gIC8vIHRoZSBzYW1lIGhhbG8gQ21kLWNsaWNrIHdvdWxkLiBDYWxsZWQgZnJvbSBib3RoIHRoZSBpbi1pZnJhbWUgcGluIGNsaWNrXG4gIC8vIEFORCB0aGUgaW5ib3VuZCBgY29tbWVudC1mb2N1c2AgcG9zdE1lc3NhZ2Ugc28ganVtcGluZyBmcm9tIHRoZSBzaGVsbCdzXG4gIC8vIENvbW1lbnRzIHBhbmVsIHByb2R1Y2VzIHRoZSBzYW1lIHZpc3VhbCBmZWVkYmFjayBhcyBjbGlja2luZyB0aGUgcGluLlxuICBjb25zdCBtaXJyb3JTZWxlY3Rpb24gPSB1c2VDYWxsYmFjayhcbiAgICAoY29tbWVudDogT3ZlcmxheUNvbW1lbnQgfCB1bmRlZmluZWQpID0+IHtcbiAgICAgIGlmICghc2VsU2V0KSByZXR1cm47XG4gICAgICBpZiAoIWNvbW1lbnQgfHwgIWNvbW1lbnQuc2VsZWN0b3IpIHtcbiAgICAgICAgc2VsU2V0LmNsZWFyKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGNkTWF0Y2ggPSBjb21tZW50LnNlbGVjdG9yLm1hdGNoKC9kYXRhLWNkLWlkPVwiKFteXCJdKylcIi8pO1xuICAgICAgY29uc3QgY2RJZCA9IGNkTWF0Y2ggPyBjZE1hdGNoWzFdIDogdW5kZWZpbmVkO1xuICAgICAgbGV0IHRhZzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgbGV0IGNsYXNzZXM6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihjb21tZW50LnNlbGVjdG9yKSBhcyBIVE1MRWxlbWVudCB8IG51bGw7XG4gICAgICAgIGlmIChlbCkge1xuICAgICAgICAgIHRhZyA9IGVsLnRhZ05hbWUudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICBjbGFzc2VzID0gKGVsLmdldEF0dHJpYnV0ZSgnY2xhc3MnKSA/PyAnJylcbiAgICAgICAgICAgIC5zcGxpdCgvXFxzKy8pXG4gICAgICAgICAgICAuZmlsdGVyKChjbHMpID0+IGNscyAmJiAhY2xzLnN0YXJ0c1dpdGgoJ2Rnbi0nKSAmJiAhY2xzLnN0YXJ0c1dpdGgoJ2RjLWN2LScpKVxuICAgICAgICAgICAgLmpvaW4oJyAnKTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8qIHVucmVzb2x2YWJsZSBzZWxlY3RvciDigJQgZmFsbCB0aHJvdWdoIHdpdGggbm8gZnJlc2ggbWV0YWRhdGEgKi9cbiAgICAgIH1cbiAgICAgIHNlbFNldC5yZXBsYWNlKHtcbiAgICAgICAgZmlsZTogZmlsZSA/PyB1bmRlZmluZWQsXG4gICAgICAgIGlkOiBjZElkLFxuICAgICAgICBzZWxlY3RvcjogY29tbWVudC5zZWxlY3RvcixcbiAgICAgICAgdGFnLFxuICAgICAgICBjbGFzc2VzLFxuICAgICAgICBib3VuZHM6IGNvbW1lbnQuYm91bmRzID8/IHVuZGVmaW5lZCxcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgW3NlbFNldCwgZmlsZV1cbiAgKTtcblxuICAvLyBLZWVwIHRoZSBsYXRlc3QgY29tbWVudHMgbGlzdCByZWFjaGFibGUgZnJvbSB0aGUgbWVzc2FnZSBoYW5kbGVyIHdpdGhvdXRcbiAgLy8gcmUtYXR0YWNoaW5nIHRoZSBsaXN0ZW5lciBvbiBldmVyeSBjb21tZW50cyBtdXRhdGlvbi5cbiAgY29uc3QgY29tbWVudHNSZWYgPSB1c2VSZWY8T3ZlcmxheUNvbW1lbnRbXT4oY29tbWVudHMpO1xuICBjb21tZW50c1JlZi5jdXJyZW50ID0gY29tbWVudHM7XG5cbiAgLy8gUGhhc2UgOCBUYXNrIDMg4oCUIHdoZW4gYSBjb2xsYWIgcm9vbSBpcyBjb25uZWN0ZWQsIHRoZSBZLkFycmF5IG9mIGNvbW1lbnRzXG4gIC8vIGlzIHRoZSBsaXZlIHNvdXJjZSBvZiB0cnV0aC4gb2JzZXJ2ZSgpIGZpcmVzIG9uIGV2ZXJ5IHJlbW90ZSBtdXRhdGlvblxuICAvLyAoYWRkZWQgcGlucyBmcm9tIGFub3RoZXIgdGFiLCByZXNvbHZlZC1mcm9tLWluc3BlY3RvciB2aWEgdGhlIHJlZ2lzdHJ5XG4gIC8vIGJyaWRnZSwgZXRjLikgYW5kIG9uIHRoZSBsb2NhbCBzZWVkLiBCb3RoIHBhdGhzIGNvbnZlcmdlIG9uIHRoZSBzYW1lXG4gIC8vIEpTT04gcHJvamVjdGlvbiDigJQgbGFzdC13cml0ZS13aW5zIGJldHdlZW4gWS5BcnJheSBhbmQgcG9zdE1lc3NhZ2UgaXNcbiAgLy8gc2FmZSBiZWNhdXNlIHRoZXkgY2FycnkgaWRlbnRpY2FsIGNvbnRlbnQ7IHRoZSBZLkFycmF5IHBhdGgganVzdFxuICAvLyByZWFjaGVzIHVzIGZpcnN0IChubyA4MDAgbXMgZGVib3VuY2UgZGVsYXkpLlxuICBjb25zdCBjb2xsYWIgPSB1c2VDb2xsYWIoKTtcbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIWNvbGxhYikgcmV0dXJuO1xuICAgIGNvbnN0IGFyciA9IGNvbGxhYi5kb2MuZ2V0QXJyYXk8T3ZlcmxheUNvbW1lbnQ+KCdjb21tZW50cycpO1xuICAgIGNvbnN0IHN5bmMgPSAoKSA9PiB7XG4gICAgICAvLyB0b0FycmF5KCkgc25hcHNob3QgdGhlIGN1cnJlbnQgWS5BcnJheSBpbnRvIGEgcGxhaW4gSlMgbGlzdC5cbiAgICAgIHNldENvbW1lbnRzKGFyci50b0FycmF5KCkgYXMgT3ZlcmxheUNvbW1lbnRbXSk7XG4gICAgfTtcbiAgICAvLyBJbml0aWFsIGZpbGwg4oCUIGNvdmVycyB0aGUgY2FzZSB3aGVyZSBZLkRvYyB3YXMgYWxyZWFkeSBzZWVkZWQgYnkgdGhlXG4gICAgLy8gdGltZSB0aGlzIG92ZXJsYXkgbW91bnRlZC5cbiAgICBpZiAoYXJyLmxlbmd0aCA+IDApIHN5bmMoKTtcbiAgICBhcnIub2JzZXJ2ZShzeW5jKTtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXJyLnVub2JzZXJ2ZShzeW5jKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvKiBkb2MgZGVzdHJveWVkIGJlZm9yZSB1bm1vdW50IOKAlCBvYnNlcnZlciBhbHJlYWR5IGdvbmUgKi9cbiAgICAgIH1cbiAgICB9O1xuICB9LCBbY29sbGFiXSk7XG5cbiAgLy8gTGlzdGVuIGZvciB0aGUgc2hlbGwncyBicm9hZGNhc3QgY2hhbm5lbHMuIFNjaGVtYSBtYXRjaGVzIHRoZSBsZWdhY3lcbiAgLy8gb3ZlcmxheSBzbyB0aGUgc2hlbGwtc2lkZSBnbHVlIGluIGNsaWVudC9hcHAuanN4ICh+bGluZSAxNjcyKSBrZWVwc1xuICAvLyB3b3JraW5nIHdpdGhvdXQgbW9kaWZpY2F0aW9uLlxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykgcmV0dXJuO1xuICAgIGNvbnN0IG9uTWVzc2FnZSA9IChlOiBNZXNzYWdlRXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IG0gPSBlLmRhdGEgYXMgeyBkZ24/OiBzdHJpbmc7IGNvbW1lbnRzPzogdW5rbm93bjsgaWQ/OiBzdHJpbmcgfSB8IG51bGw7XG4gICAgICBpZiAoIW0gfHwgdHlwZW9mIG0gIT09ICdvYmplY3QnIHx8ICFtLmRnbikgcmV0dXJuO1xuICAgICAgaWYgKG0uZGduID09PSAnY29tbWVudHMtc2V0JyAmJiBBcnJheS5pc0FycmF5KG0uY29tbWVudHMpKSB7XG4gICAgICAgIHNldENvbW1lbnRzKG0uY29tbWVudHMgYXMgT3ZlcmxheUNvbW1lbnRbXSk7XG4gICAgICB9IGVsc2UgaWYgKG0uZGduID09PSAnY29tbWVudC1mb2N1cycpIHtcbiAgICAgICAgY29uc3QgaWQgPSB0eXBlb2YgbS5pZCA9PT0gJ3N0cmluZycgPyBtLmlkIDogbnVsbDtcbiAgICAgICAgc2V0Rm9jdXNlZElkKGlkKTtcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gaWQgPyBjb21tZW50c1JlZi5jdXJyZW50LmZpbmQoKGMpID0+IGMuaWQgPT09IGlkKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgbWlycm9yU2VsZWN0aW9uKHRhcmdldCk7XG4gICAgICB9XG4gICAgfTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9uTWVzc2FnZSk7XG4gICAgcmV0dXJuICgpID0+IHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25NZXNzYWdlKTtcbiAgfSwgW21pcnJvclNlbGVjdGlvbl0pO1xuXG4gIC8vIGNhbnZhcy1zaGVsbCdzIGBvbkRyb3BDb21tZW50YCBkaXNwYXRjaGVzIGBjbTpvcGVuLWNvbXBvc2VyYCBvbiB0aGUgaWZyYW1lXG4gIC8vIGRvY3VtZW50LiBPcGVuIHRoZSBjb21wb3NlciBwaW5uZWQgdG8gdGhhdCBjbGljayBwb2ludC5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykgcmV0dXJuO1xuICAgIGNvbnN0IG9uT3BlbiA9IChlOiBFdmVudCkgPT4ge1xuICAgICAgY29uc3QgZGV0YWlsID0gKFxuICAgICAgICBlIGFzIEN1c3RvbUV2ZW50PHsgc2VsZWN0aW9uPzogQ29tcG9zZVNlbGVjdGlvbjsgY2xpZW50WD86IG51bWJlcjsgY2xpZW50WT86IG51bWJlciB9PlxuICAgICAgKS5kZXRhaWw7XG4gICAgICBpZiAoIWRldGFpbCB8fCAhZGV0YWlsLnNlbGVjdGlvbikgcmV0dXJuO1xuICAgICAgc2V0Q29tcG9zZXIoe1xuICAgICAgICBzZWxlY3Rpb246IGRldGFpbC5zZWxlY3Rpb24sXG4gICAgICAgIGNsaWVudFg6IHR5cGVvZiBkZXRhaWwuY2xpZW50WCA9PT0gJ251bWJlcicgPyBkZXRhaWwuY2xpZW50WCA6IDAsXG4gICAgICAgIGNsaWVudFk6IHR5cGVvZiBkZXRhaWwuY2xpZW50WSA9PT0gJ251bWJlcicgPyBkZXRhaWwuY2xpZW50WSA6IDAsXG4gICAgICB9KTtcbiAgICB9O1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NtOm9wZW4tY29tcG9zZXInLCBvbk9wZW4pO1xuICAgIHJldHVybiAoKSA9PiBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdjbTpvcGVuLWNvbXBvc2VyJywgb25PcGVuKTtcbiAgfSwgW10pO1xuXG4gIGNvbnN0IGNsb3NlQ29tcG9zZXIgPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgc2V0Q29tcG9zZXIobnVsbCk7XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSByZXR1cm47XG4gICAgdHJ5IHtcbiAgICAgIHdpbmRvdy5wYXJlbnQucG9zdE1lc3NhZ2UoeyBkZ246ICdmb3JjZS1jbGVhcicgfSwgJyonKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8qIHBhcmVudCBkZXRhY2hlZCAqL1xuICAgIH1cbiAgfSwgW10pO1xuXG4gIGNvbnN0IHN1Ym1pdENvbXBvc2VyID0gdXNlQ2FsbGJhY2soXG4gICAgKHRleHQ6IHN0cmluZykgPT4ge1xuICAgICAgaWYgKCFjb21wb3NlcikgcmV0dXJuO1xuICAgICAgY29uc3Qgc2VsID0gY29tcG9zZXIuc2VsZWN0aW9uO1xuICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgZmlsZTogc2VsLmZpbGUsXG4gICAgICAgIHNlbGVjdG9yOiBzZWwuc2VsZWN0b3IsXG4gICAgICAgIGRvbV9wYXRoOiBzZWwuZG9tX3BhdGgsXG4gICAgICAgIHRhZzogc2VsLnRhZyxcbiAgICAgICAgY2xhc3Nlczogc2VsLmNsYXNzZXMsXG4gICAgICAgIGJvdW5kczogc2VsLmJvdW5kcyxcbiAgICAgICAgaHRtbF9leGNlcnB0OiBzZWwuaHRtbCxcbiAgICAgICAgdGV4dCxcbiAgICAgIH07XG4gICAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybjtcbiAgICAgIC8vIFNoZWxsIHJlbGF5cyBpbnRvIHRoZSBXUyBgY29tbWVudHMtYWRkYCBjaGFubmVsIGFuZCBwZXJzaXN0cy5cbiAgICAgIHRyeSB7XG4gICAgICAgIHdpbmRvdy5wYXJlbnQucG9zdE1lc3NhZ2UoeyBkZ246ICdjb21tZW50LXN1Ym1pdCcsIHBheWxvYWQgfSwgJyonKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvKiBwYXJlbnQgZGV0YWNoZWQgKi9cbiAgICAgIH1cbiAgICAgIGNsb3NlQ29tcG9zZXIoKTtcbiAgICB9LFxuICAgIFtjb21wb3NlciwgY2xvc2VDb21wb3Nlcl1cbiAgKTtcblxuICAvLyBTZWxmLWhlYWwgZmV0Y2gg4oCUIGNvdmVycyB0aGUgcmFjZSB3aGVyZSB0aGUgaWZyYW1lIGxvYWRzIGJlZm9yZSB0aGUgc2hlbGxcbiAgLy8gcHVzaGVzIGBjb21tZW50cy1zZXRgIChlLmcuIGZpcnN0IGh5ZHJhdGlvbiBvbiBjb2xkIG9wZW4pLlxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghZmlsZSkgcmV0dXJuO1xuICAgIGxldCBjYW5jZWxsZWQgPSBmYWxzZTtcbiAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgciA9IGF3YWl0IGZldGNoKGAvX2NvbW1lbnRzP2ZpbGU9JHtlbmNvZGVVUklDb21wb25lbnQoZmlsZSl9YCk7XG4gICAgICAgIGlmICghci5vaykgcmV0dXJuO1xuICAgICAgICBjb25zdCBkYXRhID0gKGF3YWl0IHIuanNvbigpKSBhcyB7IGNvbW1lbnRzPzogT3ZlcmxheUNvbW1lbnRbXSB9O1xuICAgICAgICBpZiAoY2FuY2VsbGVkKSByZXR1cm47XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEuY29tbWVudHMpKSB7XG4gICAgICAgICAgLy8gT25seSBzZXQgd2hlbiB3ZSBoYXZlbid0IHJlY2VpdmVkIGEgc2hlbGwgYnJvYWRjYXN0IHlldDsgdGhlXG4gICAgICAgICAgLy8gc2hlbGwgaXMgYXV0aG9yaXRhdGl2ZSBvbmNlIGl0IGtpY2tzIGluLlxuICAgICAgICAgIHNldENvbW1lbnRzKChwcmV2KSA9PiAocHJldi5sZW5ndGggPT09IDAgPyAoZGF0YS5jb21tZW50cyA/PyBbXSkgOiBwcmV2KSk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvKiBvZmZsaW5lIC8gZGV2LXNlcnZlciByZXN0YXJ0IOKAlCBzaWxlbnRseSBuby1vcCAqL1xuICAgICAgfVxuICAgIH0pKCk7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGNhbmNlbGxlZCA9IHRydWU7XG4gICAgfTtcbiAgfSwgW2ZpbGVdKTtcblxuICAvLyBTb3J0ZWQgYnkgYGNyZWF0ZWRgIGFzYyBzbyBzZXF1ZW5jZSBudW1iZXJzIGFyZSBzdGFibGUgcGVyIGNhbnZhcyBhY3Jvc3NcbiAgLy8gcmVsb2Fkcy4gUmVzb2x2ZWQgY29tbWVudHMgYXJlIGhpZGRlbiBieSBkZWZhdWx0IChUYXNrIDIgc3BlYykuXG4gIGNvbnN0IHZpc2libGUgPSB1c2VNZW1vKCgpID0+IHtcbiAgICBjb25zdCBsaXN0ID0gY29tbWVudHMuc2xpY2UoKS5zb3J0KChhLCBiKSA9PiBhLmNyZWF0ZWQubG9jYWxlQ29tcGFyZShiLmNyZWF0ZWQpKTtcbiAgICByZXR1cm4gbGlzdC5maWx0ZXIoKGMpID0+IGMuc3RhdHVzICE9PSAncmVzb2x2ZWQnKTtcbiAgfSwgW2NvbW1lbnRzXSk7XG5cbiAgLy8gU2VxdWVuY2UgaW5kZXggbG9va3VwIOKAlCBidWlsdCBvZmYgdGhlIEZVTEwgc29ydGVkIGxpc3Qgc28gYSByZXNvbHZlZC10aGVuLVxuICAvLyByZW9wZW5lZCBwaW4ga2VlcHMgaXRzIG9yaWdpbmFsIG51bWJlci5cbiAgY29uc3QgaW5kZXhCeUlkID0gdXNlTWVtbygoKSA9PiB7XG4gICAgY29uc3QgbSA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gICAgY29uc3QgYWxsID0gY29tbWVudHMuc2xpY2UoKS5zb3J0KChhLCBiKSA9PiBhLmNyZWF0ZWQubG9jYWxlQ29tcGFyZShiLmNyZWF0ZWQpKTtcbiAgICBhbGwuZm9yRWFjaCgoYywgaSkgPT4gbS5zZXQoYy5pZCwgaSArIDEpKTtcbiAgICByZXR1cm4gbTtcbiAgfSwgW2NvbW1lbnRzXSk7XG5cbiAgY29uc3QgaGFuZGxlUGluQ2xpY2sgPSB1c2VDYWxsYmFjayhcbiAgICAoaWQ6IHN0cmluZykgPT4ge1xuICAgICAgc2V0Rm9jdXNlZElkKGlkKTtcbiAgICAgIG1pcnJvclNlbGVjdGlvbihjb21tZW50cy5maW5kKChjKSA9PiBjLmlkID09PSBpZCkpO1xuICAgICAgaWYgKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSByZXR1cm47XG4gICAgICB0cnkge1xuICAgICAgICB3aW5kb3cucGFyZW50LnBvc3RNZXNzYWdlKHsgZGduOiAnY29tbWVudC1jbGljaycsIGlkIH0sICcqJyk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLyogcGFyZW50IGRldGFjaGVkICovXG4gICAgICB9XG4gICAgfSxcbiAgICBbY29tbWVudHMsIG1pcnJvclNlbGVjdGlvbl1cbiAgKTtcblxuICBjb25zdCBoYW5kbGVQYXRjaCA9IHVzZUNhbGxiYWNrKChpZDogc3RyaW5nLCBwYXRjaDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IHtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybjtcbiAgICB0cnkge1xuICAgICAgd2luZG93LnBhcmVudC5wb3N0TWVzc2FnZSh7IGRnbjogJ2NvbW1lbnQtcGF0Y2gnLCBpZCwgcGF0Y2ggfSwgJyonKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8qIHBhcmVudCBkZXRhY2hlZCAqL1xuICAgIH1cbiAgfSwgW10pO1xuXG4gIGNvbnN0IGhhbmRsZURlbGV0ZSA9IHVzZUNhbGxiYWNrKChpZDogc3RyaW5nKSA9PiB7XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSByZXR1cm47XG4gICAgdHJ5IHtcbiAgICAgIHdpbmRvdy5wYXJlbnQucG9zdE1lc3NhZ2UoeyBkZ246ICdjb21tZW50LWRlbGV0ZScsIGlkIH0sICcqJyk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvKiBwYXJlbnQgZGV0YWNoZWQgKi9cbiAgICB9XG4gICAgc2V0Rm9jdXNlZElkKChwcmV2KSA9PiAocHJldiA9PT0gaWQgPyBudWxsIDogcHJldikpO1xuICB9LCBbXSk7XG5cbiAgY29uc3QgaGFuZGxlUmVwbHkgPSB1c2VDYWxsYmFjayhhc3luYyAoaWQ6IHN0cmluZywgYm9keTogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiA9PiB7XG4gICAgaWYgKHR5cGVvZiBmZXRjaCA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybiBmYWxzZTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgciA9IGF3YWl0IGZldGNoKGAvX2FwaS9jb21tZW50cy8ke2VuY29kZVVSSUNvbXBvbmVudChpZCl9L3JlcGx5YCwge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsgYm9keSB9KSxcbiAgICAgIH0pO1xuICAgICAgaWYgKCFyLm9rKSByZXR1cm4gZmFsc2U7XG4gICAgICBjb25zdCB1cGRhdGVkID0gKGF3YWl0IHIuanNvbigpKSBhcyBPdmVybGF5Q29tbWVudDtcbiAgICAgIC8vIE9wdGltaXN0aWMgbG9jYWwgbWVyZ2Ug4oCUIHRoZSBzaGVsbCB3aWxsIGJyb2FkY2FzdCBgY29tbWVudHMtc2V0YFxuICAgICAgLy8gc2hvcnRseSBhZnRlciBhcyB0aGUgV1MgZmFucyBvdXQgdGhlIGNoYW5nZSwgYnV0IGFwcGx5aW5nIGl0IG5vd1xuICAgICAgLy8gYXZvaWRzIHRoZSBwb3BvdmVyIGZsaWNrZXJpbmcgZW1wdHkgYmV0d2VlbiBzdWJtaXQgKyBicm9hZGNhc3QuXG4gICAgICBzZXRDb21tZW50cygocHJldikgPT4gcHJldi5tYXAoKGMpID0+IChjLmlkID09PSB1cGRhdGVkLmlkID8gdXBkYXRlZCA6IGMpKSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH0sIFtdKTtcblxuICByZXR1cm4gKFxuICAgIDxkaXYgY2xhc3NOYW1lPVwiY20tbGF5ZXJcIiBhcmlhLWhpZGRlbj17ZmFsc2V9PlxuICAgICAge3Zpc2libGUubWFwKChjKSA9PiB7XG4gICAgICAgIGNvbnN0IG4gPSBpbmRleEJ5SWQuZ2V0KGMuaWQpID8/IDA7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgPENvbW1lbnRQaW5cbiAgICAgICAgICAgIGtleT17Yy5pZH1cbiAgICAgICAgICAgIGNvbW1lbnQ9e2N9XG4gICAgICAgICAgICBzZXF1ZW5jZT17bn1cbiAgICAgICAgICAgIGZvY3VzZWQ9e2ZvY3VzZWRJZCA9PT0gYy5pZH1cbiAgICAgICAgICAgIG9uQ2xpY2s9e2hhbmRsZVBpbkNsaWNrfVxuICAgICAgICAgIC8+XG4gICAgICAgICk7XG4gICAgICB9KX1cbiAgICAgIHtjb21wb3NlciA/IChcbiAgICAgICAgPENvbW1lbnRDb21wb3NlciBzdGF0ZT17Y29tcG9zZXJ9IG9uU3VibWl0PXtzdWJtaXRDb21wb3Nlcn0gb25DYW5jZWw9e2Nsb3NlQ29tcG9zZXJ9IC8+XG4gICAgICApIDogbnVsbH1cbiAgICAgIHsoKCkgPT4ge1xuICAgICAgICBpZiAoIWZvY3VzZWRJZCkgcmV0dXJuIG51bGw7XG4gICAgICAgIGNvbnN0IGZvY3VzZWQgPSB2aXNpYmxlLmZpbmQoKGMpID0+IGMuaWQgPT09IGZvY3VzZWRJZCk7XG4gICAgICAgIGlmICghZm9jdXNlZCkgcmV0dXJuIG51bGw7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgPENvbW1lbnRUaHJlYWRcbiAgICAgICAgICAgIGNvbW1lbnQ9e2ZvY3VzZWR9XG4gICAgICAgICAgICBvbkNsb3NlPXsoKSA9PiB7XG4gICAgICAgICAgICAgIHNldEZvY3VzZWRJZChudWxsKTtcbiAgICAgICAgICAgICAgLy8gRHJvcCB0aGUgY2FudmFzIGhhbG8gd2hlbiB0aGUgdGhyZWFkIGNsb3NlcyDigJQgc3ltbWV0cmljIHdpdGhcbiAgICAgICAgICAgICAgLy8gYGhhbmRsZVBpbkNsaWNrYCB3aGljaCBwYWludHMgaXQgb24gb3Blbi5cbiAgICAgICAgICAgICAgc2VsU2V0Py5jbGVhcigpO1xuICAgICAgICAgICAgfX1cbiAgICAgICAgICAgIG9uUGF0Y2g9eyhwYXRjaCkgPT4gaGFuZGxlUGF0Y2goZm9jdXNlZC5pZCwgcGF0Y2gpfVxuICAgICAgICAgICAgb25EZWxldGU9eygpID0+IGhhbmRsZURlbGV0ZShmb2N1c2VkLmlkKX1cbiAgICAgICAgICAgIG9uUmVwbHk9eyhib2R5KSA9PiBoYW5kbGVSZXBseShmb2N1c2VkLmlkLCBib2R5KX1cbiAgICAgICAgICAvPlxuICAgICAgICApO1xuICAgICAgfSkoKX1cbiAgICA8L2Rpdj5cbiAgKTtcbn1cblxuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4vLyBNZW50aW9uQXdhcmVUZXh0YXJlYSArIHBvcHVwIOKAlCBUYXNrIDVcbi8vXG4vLyBXcmFwcyBhIHRleHRhcmVhIGFuZCBzdXJmYWNlcyBhbiBhdXRvY29tcGxldGUgcG9wdXAgd2hlbiB0aGUgY2FyZXQgc2l0c1xuLy8gaW5zaWRlIGFuIGBAPHF1ZXJ5PmAgdG9rZW4gKG5vIHdoaXRlc3BhY2UgYmV0d2VlbiBgQGAgYW5kIGN1cnNvcikuIFRoZVxuLy8gY29tbWl0dGVyIGxpc3QgaXMgZmV0Y2hlZCBvbmNlIG9uIGZpcnN0IGZvY3VzIGFuZCBjYWNoZWQgZm9yIHRoZSBzZXNzaW9uLlxuLy8gS2V5Ym9hcmQ6IOKGkeKGkyBtb3ZlLCDihrUvVGFiIGluc2VydCAoYEBmaXJzdG5hbWUgYCksIEVzYyBkaXNtaXNzLlxuXG5pbnRlcmZhY2UgQ29tbWl0dGVyUm93IHtcbiAgbmFtZTogc3RyaW5nO1xuICBlbWFpbDogc3RyaW5nO1xuICBjb21taXRzOiBudW1iZXI7XG59XG5cbmxldCBjb21taXR0ZXJDYWNoZTogUHJvbWlzZTxDb21taXR0ZXJSb3dbXT4gfCBudWxsID0gbnVsbDtcbmFzeW5jIGZ1bmN0aW9uIGxvYWRDb21taXR0ZXJzKCk6IFByb21pc2U8Q29tbWl0dGVyUm93W10+IHtcbiAgaWYgKCFjb21taXR0ZXJDYWNoZSkge1xuICAgIGNvbW1pdHRlckNhY2hlID0gKGFzeW5jICgpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHIgPSBhd2FpdCBmZXRjaCgnL19hcGkvZ2l0LWNvbW1pdHRlcnMnKTtcbiAgICAgICAgaWYgKCFyLm9rKSByZXR1cm4gW107XG4gICAgICAgIGNvbnN0IGRhdGEgPSAoYXdhaXQgci5qc29uKCkpIGFzIHsgY29tbWl0dGVycz86IENvbW1pdHRlclJvd1tdIH07XG4gICAgICAgIHJldHVybiBBcnJheS5pc0FycmF5KGRhdGEuY29tbWl0dGVycykgPyBkYXRhLmNvbW1pdHRlcnMgOiBbXTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgfSkoKTtcbiAgfVxuICByZXR1cm4gY29tbWl0dGVyQ2FjaGU7XG59XG5cbmZ1bmN0aW9uIGZpcnN0TmFtZVNsdWcobmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgLy8gYEBmaXJzdG5hbWVgIGlzIHdoYXQgd2UgaW5zZXJ0IG9uIGFjY2VwdC4gU3RyaXAgc3VybmFtZXMgKyBwdW5jdHVhdGlvbi5cbiAgY29uc3QgZmlyc3QgPSBuYW1lLnRyaW0oKS5zcGxpdCgvXFxzKy8pWzBdID8/ICcnO1xuICAvLyBLZWVwIGFscGhhbnVtICsgYC5gIGAtYCBgX2AgKG1hdGNoZXMgdGhlIHBhcnNlTWVudGlvbnMgcmVnZXggb24gdGhlIHNlcnZlcikuXG4gIHJldHVybiBmaXJzdC5yZXBsYWNlKC9bXlxcdy4tXS9nLCAnJykudG9Mb3dlckNhc2UoKTtcbn1cblxuaW50ZXJmYWNlIE1lbnRpb25Ub2tlbiB7XG4gIHN0YXJ0OiBudW1iZXI7IC8vIGluZGV4IG9mIGBAYFxuICBlbmQ6IG51bWJlcjsgLy8gZXhjbHVzaXZlIOKAlCBjdXJyZW50IGNhcmV0XG4gIHF1ZXJ5OiBzdHJpbmc7IC8vIGNoYXJzIGJldHdlZW4gYEBgIGFuZCBjYXJldCAoZXhjbHVkaW5nIGBAYClcbn1cblxuZnVuY3Rpb24gZGV0ZWN0TWVudGlvblRva2VuKHRleHQ6IHN0cmluZywgY2FyZXQ6IG51bWJlcik6IE1lbnRpb25Ub2tlbiB8IG51bGwge1xuICBpZiAoY2FyZXQgPD0gMCB8fCBjYXJldCA+IHRleHQubGVuZ3RoKSByZXR1cm4gbnVsbDtcbiAgLy8gV2FsayBiYWNrd2FyZHMgZnJvbSBjYXJldDsgdGhlIHRva2VuIHN0YXJ0cyBhdCBgQGAgYW5kIGVuZHMgYXQgdGhlIGNhcmV0LlxuICAvLyBBYm9ydHMgb24gd2hpdGVzcGFjZSwgbmV3bGluZSwgb3IgYW55IG5vbi1tZW50aW9uIGNoYXIgc28gYSBzdHJheSBgQGAgaW5cbiAgLy8gYW4gZW1haWwgaXMgaWdub3JlZC5cbiAgbGV0IGkgPSBjYXJldCAtIDE7XG4gIHdoaWxlIChpID49IDApIHtcbiAgICBjb25zdCBjaCA9IHRleHRbaV0gPz8gJyc7XG4gICAgaWYgKGNoID09PSAnQCcpIHtcbiAgICAgIC8vIFRva2VuIG11c3QgYmUgd29yZC1sZWFkaW5nOiBwcmV2aW91cyBjaGFyIGlzIHN0YXJ0LW9mLXN0cmluZyBvciB3aGl0ZXNwYWNlLlxuICAgICAgY29uc3QgcHJldiA9IGkgPiAwID8gdGV4dFtpIC0gMV0gOiAnJztcbiAgICAgIGlmIChpID09PSAwIHx8IC9cXHMvLnRlc3QocHJldiA/PyAnJykpIHtcbiAgICAgICAgY29uc3QgcXVlcnkgPSB0ZXh0LnNsaWNlKGkgKyAxLCBjYXJldCk7XG4gICAgICAgIHJldHVybiB7IHN0YXJ0OiBpLCBlbmQ6IGNhcmV0LCBxdWVyeSB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGlmICghL1tcXHcuLV0vLnRlc3QoY2gpKSByZXR1cm4gbnVsbDtcbiAgICBpIC09IDE7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIE1lbnRpb25Bd2FyZVRleHRhcmVhKHtcbiAgY2xhc3NOYW1lLFxuICB2YWx1ZSxcbiAgb25DaGFuZ2UsXG4gIG9uS2V5RG93bixcbiAgcGxhY2Vob2xkZXIsXG4gIHJvd3MsXG4gIGRpc2FibGVkLFxuICB0ZXh0YXJlYVJlZixcbiAgYXJpYUxhYmVsLFxufToge1xuICBjbGFzc05hbWU6IHN0cmluZztcbiAgdmFsdWU6IHN0cmluZztcbiAgb25DaGFuZ2U6IChuZXh0OiBzdHJpbmcpID0+IHZvaWQ7XG4gIG9uS2V5RG93bj86IChlOiBSZWFjdC5LZXlib2FyZEV2ZW50PEhUTUxUZXh0QXJlYUVsZW1lbnQ+KSA9PiB2b2lkO1xuICBwbGFjZWhvbGRlcj86IHN0cmluZztcbiAgcm93cz86IG51bWJlcjtcbiAgZGlzYWJsZWQ/OiBib29sZWFuO1xuICB0ZXh0YXJlYVJlZj86IFJlYWN0Lk11dGFibGVSZWZPYmplY3Q8SFRNTFRleHRBcmVhRWxlbWVudCB8IG51bGw+O1xuICBhcmlhTGFiZWw/OiBzdHJpbmc7XG59KTogUmVhY3QuUmVhY3RFbGVtZW50IHtcbiAgY29uc3QgaW50ZXJuYWxSZWYgPSB1c2VSZWY8SFRNTFRleHRBcmVhRWxlbWVudCB8IG51bGw+KG51bGwpO1xuICBjb25zdCBzZXRSZWYgPSB1c2VDYWxsYmFjayhcbiAgICAoZWw6IEhUTUxUZXh0QXJlYUVsZW1lbnQgfCBudWxsKSA9PiB7XG4gICAgICBpbnRlcm5hbFJlZi5jdXJyZW50ID0gZWw7XG4gICAgICBpZiAodGV4dGFyZWFSZWYpIHRleHRhcmVhUmVmLmN1cnJlbnQgPSBlbDtcbiAgICB9LFxuICAgIFt0ZXh0YXJlYVJlZl1cbiAgKTtcblxuICBjb25zdCBbY29tbWl0dGVycywgc2V0Q29tbWl0dGVyc10gPSB1c2VTdGF0ZTxDb21taXR0ZXJSb3dbXT4oW10pO1xuICBjb25zdCBbdG9rZW4sIHNldFRva2VuXSA9IHVzZVN0YXRlPE1lbnRpb25Ub2tlbiB8IG51bGw+KG51bGwpO1xuICBjb25zdCBbaGlnaGxpZ2h0LCBzZXRIaWdobGlnaHRdID0gdXNlU3RhdGUoMCk7XG5cbiAgLy8gTGF6eS1sb2FkIGNvbW1pdHRlcnMgb24gZmlyc3QgZm9jdXMuXG4gIGNvbnN0IG9uRm9jdXMgPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgaWYgKGNvbW1pdHRlcnMubGVuZ3RoID4gMCkgcmV0dXJuO1xuICAgIHZvaWQgbG9hZENvbW1pdHRlcnMoKS50aGVuKChsaXN0KSA9PiBzZXRDb21taXR0ZXJzKGxpc3QpKTtcbiAgfSwgW2NvbW1pdHRlcnMubGVuZ3RoXSk7XG5cbiAgY29uc3QgZmlsdGVyZWQgPSB1c2VNZW1vKCgpID0+IHtcbiAgICBpZiAoIXRva2VuKSByZXR1cm4gW10gYXMgQ29tbWl0dGVyUm93W107XG4gICAgY29uc3QgcSA9IHRva2VuLnF1ZXJ5LnRvTG93ZXJDYXNlKCk7XG4gICAgY29uc3QgbGlzdCA9ICFxXG4gICAgICA/IGNvbW1pdHRlcnNcbiAgICAgIDogY29tbWl0dGVycy5maWx0ZXIoXG4gICAgICAgICAgKGMpID0+IGMubmFtZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHEpIHx8IGMuZW1haWwudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhxKVxuICAgICAgICApO1xuICAgIHJldHVybiBsaXN0LnNsaWNlKDAsIDgpO1xuICB9LCBbdG9rZW4sIGNvbW1pdHRlcnNdKTtcblxuICBjb25zdCByZWZyZXNoVG9rZW4gPSB1c2VDYWxsYmFjaygodGV4dGFyZWE6IEhUTUxUZXh0QXJlYUVsZW1lbnQpID0+IHtcbiAgICBjb25zdCBjYXJldCA9IHRleHRhcmVhLnNlbGVjdGlvblN0YXJ0ID8/IHRleHRhcmVhLnZhbHVlLmxlbmd0aDtcbiAgICBjb25zdCB0ID0gZGV0ZWN0TWVudGlvblRva2VuKHRleHRhcmVhLnZhbHVlLCBjYXJldCk7XG4gICAgc2V0VG9rZW4odCk7XG4gICAgc2V0SGlnaGxpZ2h0KDApO1xuICB9LCBbXSk7XG5cbiAgY29uc3QgaGFuZGxlQ2hhbmdlID0gdXNlQ2FsbGJhY2soXG4gICAgKGU6IFJlYWN0LkNoYW5nZUV2ZW50PEhUTUxUZXh0QXJlYUVsZW1lbnQ+KSA9PiB7XG4gICAgICBvbkNoYW5nZShlLnRhcmdldC52YWx1ZSk7XG4gICAgICByZWZyZXNoVG9rZW4oZS50YXJnZXQpO1xuICAgIH0sXG4gICAgW29uQ2hhbmdlLCByZWZyZXNoVG9rZW5dXG4gICk7XG5cbiAgY29uc3QgaW5zZXJ0TWVudGlvbiA9IHVzZUNhbGxiYWNrKFxuICAgIChjb21taXR0ZXI6IENvbW1pdHRlclJvdykgPT4ge1xuICAgICAgaWYgKCF0b2tlbikgcmV0dXJuO1xuICAgICAgY29uc3QgdGEgPSBpbnRlcm5hbFJlZi5jdXJyZW50O1xuICAgICAgaWYgKCF0YSkgcmV0dXJuO1xuICAgICAgY29uc3QgdGFnID0gYEAke2ZpcnN0TmFtZVNsdWcoY29tbWl0dGVyLm5hbWUpfWA7XG4gICAgICBjb25zdCBuZXh0ID0gYCR7dmFsdWUuc2xpY2UoMCwgdG9rZW4uc3RhcnQpfSR7dGFnfSAke3ZhbHVlLnNsaWNlKHRva2VuLmVuZCl9YDtcbiAgICAgIG9uQ2hhbmdlKG5leHQpO1xuICAgICAgc2V0VG9rZW4obnVsbCk7XG4gICAgICAvLyBSZXN0b3JlIGNhcmV0IGp1c3QgcGFzdCB0aGUgaW5zZXJ0ZWQgdG9rZW4gKyB0cmFpbGluZyBzcGFjZS5cbiAgICAgIGNvbnN0IG5ld0NhcmV0ID0gdG9rZW4uc3RhcnQgKyB0YWcubGVuZ3RoICsgMTtcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgIHRhLmZvY3VzKCk7XG4gICAgICAgIHRhLnNldFNlbGVjdGlvblJhbmdlKG5ld0NhcmV0LCBuZXdDYXJldCk7XG4gICAgICB9KTtcbiAgICB9LFxuICAgIFt0b2tlbiwgdmFsdWUsIG9uQ2hhbmdlXVxuICApO1xuXG4gIGNvbnN0IGhhbmRsZUtleURvd24gPSB1c2VDYWxsYmFjayhcbiAgICAoZTogUmVhY3QuS2V5Ym9hcmRFdmVudDxIVE1MVGV4dEFyZWFFbGVtZW50PikgPT4ge1xuICAgICAgaWYgKHRva2VuICYmIGZpbHRlcmVkLmxlbmd0aCA+IDApIHtcbiAgICAgICAgaWYgKGUua2V5ID09PSAnQXJyb3dEb3duJykge1xuICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICBzZXRIaWdobGlnaHQoKGgpID0+IChoICsgMSkgJSBmaWx0ZXJlZC5sZW5ndGgpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZS5rZXkgPT09ICdBcnJvd1VwJykge1xuICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICBzZXRIaWdobGlnaHQoKGgpID0+IChoIC0gMSArIGZpbHRlcmVkLmxlbmd0aCkgJSBmaWx0ZXJlZC5sZW5ndGgpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZS5rZXkgPT09ICdFbnRlcicgfHwgZS5rZXkgPT09ICdUYWInKSB7XG4gICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIGNvbnN0IHBpY2sgPSBmaWx0ZXJlZFtoaWdobGlnaHRdID8/IGZpbHRlcmVkWzBdO1xuICAgICAgICAgIGlmIChwaWNrKSBpbnNlcnRNZW50aW9uKHBpY2spO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZS5rZXkgPT09ICdFc2NhcGUnKSB7XG4gICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIHNldFRva2VuKG51bGwpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgb25LZXlEb3duPy4oZSk7XG4gICAgfSxcbiAgICBbdG9rZW4sIGZpbHRlcmVkLCBoaWdobGlnaHQsIGluc2VydE1lbnRpb24sIG9uS2V5RG93bl1cbiAgKTtcblxuICBjb25zdCBoYW5kbGVTZWxlY3QgPSB1c2VDYWxsYmFjayhcbiAgICAoZTogUmVhY3QuU3ludGhldGljRXZlbnQ8SFRNTFRleHRBcmVhRWxlbWVudD4pID0+IHtcbiAgICAgIHJlZnJlc2hUb2tlbihlLmN1cnJlbnRUYXJnZXQpO1xuICAgIH0sXG4gICAgW3JlZnJlc2hUb2tlbl1cbiAgKTtcblxuICByZXR1cm4gKFxuICAgIDxkaXYgc3R5bGU9e3sgcG9zaXRpb246ICdyZWxhdGl2ZScgfX0+XG4gICAgICA8dGV4dGFyZWFcbiAgICAgICAgcmVmPXtzZXRSZWZ9XG4gICAgICAgIGNsYXNzTmFtZT17Y2xhc3NOYW1lfVxuICAgICAgICB2YWx1ZT17dmFsdWV9XG4gICAgICAgIHBsYWNlaG9sZGVyPXtwbGFjZWhvbGRlcn1cbiAgICAgICAgcm93cz17cm93c31cbiAgICAgICAgZGlzYWJsZWQ9e2Rpc2FibGVkfVxuICAgICAgICBhcmlhLWxhYmVsPXthcmlhTGFiZWx9XG4gICAgICAgIG9uQ2hhbmdlPXtoYW5kbGVDaGFuZ2V9XG4gICAgICAgIG9uS2V5RG93bj17aGFuZGxlS2V5RG93bn1cbiAgICAgICAgb25Gb2N1cz17b25Gb2N1c31cbiAgICAgICAgb25TZWxlY3Q9e2hhbmRsZVNlbGVjdH1cbiAgICAgICAgb25DbGljaz17aGFuZGxlU2VsZWN0fVxuICAgICAgLz5cbiAgICAgIHsvKiBDb21ib2JveCBwYXR0ZXJuIOKAlCBgcm9sZT1cImxpc3Rib3hcImAgKyBgcm9sZT1cIm9wdGlvblwiYCBpcyB0aGUgY2Fub25pY2FsXG4gICAgICAgKiBBUklBIHNoYXBlIGZvciBhIHNpbmdsZS1zZWxlY3QgYXV0b2NvbXBsZXRlLiBLZXlib2FyZCBuYXZpZ2F0aW9uXG4gICAgICAgKiAo4oaRIOKGkyBFbnRlciBFc2MpIGxpdmVzIG9uIHRoZSBwYXJlbnQgdGV4dGFyZWEgcGVyIHRoZSBjb21ib2JveCBzcGVjLFxuICAgICAgICogc28gdGhlIHBvcHVwIGl0c2VsZiBzdGF5cyBpbmVydC4gU2FtZSBwYXR0ZXJuIGFwcGxpZXMgdG8gdGhlIGNvbXBvc2VyXG4gICAgICAgKiArIHRocmVhZCBwb3BvdmVycyBiZWxvdyAoYHJvbGU9XCJkaWFsb2dcImAgb24gYSBwb3NpdGlvbmVkIDxkaXY+KS5cbiAgICAgICAqIEJpb21lJ3MgYTExeSBydWxlcyB3YW50IHNlbWFudGljIEhUTUwgcHJpbWl0aXZlcywgYnV0IG5vbmUgbWF0Y2hcbiAgICAgICAqIFwibm9uLWZvY3VzYWJsZSBsaXN0Ym94IHVuZGVyIGEgdGV4dGFyZWFcIiBvciBcImFuY2hvcmVkIG5vbi1tb2RhbCBwb3BvdmVyXCIuXG4gICAgICAgKiBUaGUgZm91ciBhZmZlY3RlZCBydWxlcyBhcmUgc2NvcGVkIG9mZiBmb3IgdGhpcyBmaWxlIGluIGJpb21lLmpzb24uICovfVxuICAgICAge3Rva2VuICYmIGZpbHRlcmVkLmxlbmd0aCA+IDAgPyAoXG4gICAgICAgIDx1bFxuICAgICAgICAgIGNsYXNzTmFtZT1cImNtLW1lbnRpb24tcG9wdXBcIlxuICAgICAgICAgIHJvbGU9XCJsaXN0Ym94XCJcbiAgICAgICAgICBhcmlhLWxhYmVsPVwiTWVudGlvbiBzdWdnZXN0aW9uc1wiXG4gICAgICAgICAgc3R5bGU9e3sgbGVmdDogMCwgdG9wOiAnMTAwJScgfX1cbiAgICAgICAgPlxuICAgICAgICAgIHtmaWx0ZXJlZC5tYXAoKGMsIGkpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdGVkID0gaSA9PT0gaGlnaGxpZ2h0O1xuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgPGxpXG4gICAgICAgICAgICAgICAga2V5PXtgJHtjLm5hbWV9LSR7Yy5lbWFpbH1gfVxuICAgICAgICAgICAgICAgIHJvbGU9XCJvcHRpb25cIlxuICAgICAgICAgICAgICAgIGFyaWEtc2VsZWN0ZWQ9e3NlbGVjdGVkfVxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cImNtLW1lbnRpb24tcG9wdXBfX2l0ZW1cIlxuICAgICAgICAgICAgICAgIG9uTW91c2VFbnRlcj17KCkgPT4gc2V0SGlnaGxpZ2h0KGkpfVxuICAgICAgICAgICAgICAgIC8vIFVzZSBtb3VzZWRvd24gc28gdGhlIHRleHRhcmVhIGRvZXNuJ3QgYmx1ciBiZWZvcmUgdGhlXG4gICAgICAgICAgICAgICAgLy8gc2VsZWN0aW9uIHJlZ2lzdGVycy5cbiAgICAgICAgICAgICAgICBvbk1vdXNlRG93bj17KGV2KSA9PiB7XG4gICAgICAgICAgICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgaW5zZXJ0TWVudGlvbihjKTtcbiAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPVwiY20tbWVudGlvbi1wb3B1cF9fbmFtZVwiPkB7Zmlyc3ROYW1lU2x1ZyhjLm5hbWUpfTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzc05hbWU9XCJjbS1tZW50aW9uLXBvcHVwX19lbWFpbFwiPntjLmVtYWlsfTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSl9XG4gICAgICAgIDwvdWw+XG4gICAgICApIDogbnVsbH1cbiAgICA8L2Rpdj5cbiAgKTtcbn1cblxuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4vLyBDb21tZW50UGluIOKAlCBzaW5nbGUgMjTDlzI0IGJhZGdlIGFuY2hvcmVkIHRvIHRvcC1yaWdodCBvZiBpdHMgdGFyZ2V0IGVsZW1lbnQuXG4vLyBSZXNvbHZlcyB0YXJnZXQgb24gZXZlcnkgYW5pbWF0aW9uIGZyYW1lIHRvIHRyYWNrIGxheW91dCBzaGlmdHMgKGRyYWcsXG4vLyByZWZsb3csIGZvbnQgbG9hZCkuIEZhbGxzIGJhY2sgdG8gdGhlIHN0b3JlZCBgYm91bmRzYCB3aGVuIHRoZSB0YXJnZXQgaXNcbi8vIGdvbmUgZnJvbSB0aGUgRE9NLlxuXG5mdW5jdGlvbiBDb21tZW50UGluKHtcbiAgY29tbWVudCxcbiAgc2VxdWVuY2UsXG4gIGZvY3VzZWQsXG4gIG9uQ2xpY2ssXG59OiB7XG4gIGNvbW1lbnQ6IE92ZXJsYXlDb21tZW50O1xuICBzZXF1ZW5jZTogbnVtYmVyO1xuICBmb2N1c2VkOiBib29sZWFuO1xuICBvbkNsaWNrOiAoaWQ6IHN0cmluZykgPT4gdm9pZDtcbn0pIHtcbiAgY29uc3QgcmVmID0gdXNlUmVmPEhUTUxCdXR0b25FbGVtZW50IHwgbnVsbD4obnVsbCk7XG4gIGNvbnN0IHJhZlJlZiA9IHVzZVJlZjxudW1iZXIgfCBudWxsPihudWxsKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IHRpY2sgPSAoKSA9PiB7XG4gICAgICByYWZSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICBjb25zdCBwaW4gPSByZWYuY3VycmVudDtcbiAgICAgIGlmICghcGluKSByZXR1cm47XG5cbiAgICAgIC8vIExpdmUgc2NyZWVuLWNvb3JkIGxvb2t1cCBtaXJyb3JzIFNlbGVjdGlvbkhhbG9zIGluIGNhbnZhcy1zaGVsbC50c3guXG4gICAgICAvLyBGYWxscyBiYWNrIHRvIHN0b3JlZCBib3VuZHMgKGEgc2NyZWVuLWNvb3JkIGNhcHR1cmUgYXQgY3JlYXRlIHRpbWUpXG4gICAgICAvLyB3aGVuIHRoZSB0YXJnZXQgZWxlbWVudCBpcyBnb25lIOKAlCBiZXR0ZXIgdGhhbiB2YW5pc2hpbmcgZW50aXJlbHkuXG4gICAgICBsZXQgcG9zID0gc2NyZWVuUmVjdEZvcihjb21tZW50LnNlbGVjdG9yKTtcbiAgICAgIGlmICghcG9zICYmIGNvbW1lbnQuYm91bmRzKSB7XG4gICAgICAgIHBvcyA9IHtcbiAgICAgICAgICB4OiBjb21tZW50LmJvdW5kcy54LFxuICAgICAgICAgIHk6IGNvbW1lbnQuYm91bmRzLnksXG4gICAgICAgICAgdzogY29tbWVudC5ib3VuZHMudyxcbiAgICAgICAgICBoOiBjb21tZW50LmJvdW5kcy5oLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgaWYgKCFwb3MpIHtcbiAgICAgICAgcGluLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgIHJhZlJlZi5jdXJyZW50ID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRpY2spO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBwaW4uc3R5bGUuZGlzcGxheSA9ICdncmlkJztcbiAgICAgIC8vIFBvc2l0aW9uIHRoZSBwaW4ncyBjZW50ZXIgYXQgKHJpZ2h0IC0gMTIsIHRvcCAtIDEyKSDigJQgdGhlIEZpZ0phbVxuICAgICAgLy8gY29udmVudGlvbi4gMTIgPSBoYWxmIG9mIDI0ICh0aGUgcGluJ3Mgb3duIHNpemUpLlxuICAgICAgY29uc3QgbGVmdCA9IE1hdGgucm91bmQocG9zLnggKyBwb3MudyAtIDEyKTtcbiAgICAgIGNvbnN0IHRvcCA9IE1hdGgucm91bmQocG9zLnkgLSAxMik7XG4gICAgICBwaW4uc3R5bGUubGVmdCA9IGAke2xlZnR9cHhgO1xuICAgICAgcGluLnN0eWxlLnRvcCA9IGAke3RvcH1weGA7XG4gICAgICByYWZSZWYuY3VycmVudCA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aWNrKTtcbiAgICB9O1xuICAgIHJhZlJlZi5jdXJyZW50ID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRpY2spO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBpZiAocmFmUmVmLmN1cnJlbnQgIT0gbnVsbCkgY2FuY2VsQW5pbWF0aW9uRnJhbWUocmFmUmVmLmN1cnJlbnQpO1xuICAgIH07XG4gIH0sIFtjb21tZW50LnNlbGVjdG9yLCBjb21tZW50LmJvdW5kc10pO1xuXG4gIGNvbnN0IGF1dGhvciA9IGNvbW1lbnQuYXV0aG9yPy50cmltKCkgfHwgJ3Vua25vd24nO1xuICBjb25zdCBsYWJlbCA9IGBDb21tZW50ICR7c2VxdWVuY2V9IGJ5ICR7YXV0aG9yfWA7XG5cbiAgcmV0dXJuIChcbiAgICA8YnV0dG9uXG4gICAgICByZWY9e3JlZn1cbiAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgY2xhc3NOYW1lPVwiY20tcGluXCJcbiAgICAgIGRhdGEtcmVzb2x2ZWQ9e2NvbW1lbnQuc3RhdHVzID09PSAncmVzb2x2ZWQnID8gJ3RydWUnIDogJ2ZhbHNlJ31cbiAgICAgIGRhdGEtZm9jdXNlZD17Zm9jdXNlZCA/ICd0cnVlJyA6ICdmYWxzZSd9XG4gICAgICBkYXRhLWNvbW1lbnQtcGluPXtjb21tZW50LmlkfVxuICAgICAgYXJpYS1sYWJlbD17bGFiZWx9XG4gICAgICBhcmlhLWV4cGFuZGVkPXtmb2N1c2VkfVxuICAgICAgdGl0bGU9e2NvbW1lbnQudGV4dC5zbGljZSgwLCAyMDApfVxuICAgICAgb25DbGljaz17KGUpID0+IHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICBvbkNsaWNrKGNvbW1lbnQuaWQpO1xuICAgICAgfX1cbiAgICA+XG4gICAgICB7c2VxdWVuY2V9XG4gICAgPC9idXR0b24+XG4gICk7XG59XG5cbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuLy8gQ29tbWVudENvbXBvc2VyIOKAlCBEUy1zdHlsZWQgY2FyZCBhbmNob3JlZCBqdXN0IHVuZGVyIHRoZSBjbGlja2VkIGVsZW1lbnRcbi8vIChvciBhdCB0aGUgY2xpY2sgcG9pbnQgaWYgdGhlIGNsaWNrIGhpdCBlbXB0eSBjYW52YXMpLiBFZGdlLWNsYW1wIGlzIHRoZVxuLy8gcHJhZ21hdGljIGtpbmQ6IHBvc2l0aW9uIGlzIGNvbXB1dGVkIG9uY2Ugb24gb3BlbiBhZ2FpbnN0IHRoZSB3b3JsZCBsYXlvdXQsXG4vLyBub3QgY2hhc2VkIG9uIHBhbi96b29tIOKAlCB0aGUgdXNlciBpcyBhY3RpdmVseSB0eXBpbmcuXG5cbmZ1bmN0aW9uIENvbW1lbnRDb21wb3Nlcih7XG4gIHN0YXRlLFxuICBvblN1Ym1pdCxcbiAgb25DYW5jZWwsXG59OiB7XG4gIHN0YXRlOiBDb21wb3NlclN0YXRlO1xuICBvblN1Ym1pdDogKHRleHQ6IHN0cmluZykgPT4gdm9pZDtcbiAgb25DYW5jZWw6ICgpID0+IHZvaWQ7XG59KSB7XG4gIGNvbnN0IFt0ZXh0LCBzZXRUZXh0XSA9IHVzZVN0YXRlKCcnKTtcbiAgY29uc3QgdGV4dGFyZWFSZWYgPSB1c2VSZWY8SFRNTFRleHRBcmVhRWxlbWVudCB8IG51bGw+KG51bGwpO1xuICBjb25zdCBjYXJkUmVmID0gdXNlUmVmPEhUTUxEaXZFbGVtZW50IHwgbnVsbD4obnVsbCk7XG4gIGNvbnN0IHJhZlJlZiA9IHVzZVJlZjxudW1iZXIgfCBudWxsPihudWxsKTtcblxuICAvLyBMaXZlIGFuY2hvciDigJQgY29tcG9zZXIgdHJhY2tzIHRoZSB0YXJnZXQgZWxlbWVudCB2aWEgckFGIHNvIHBhbi96b29tXG4gIC8vIHdoaWxlIHR5cGluZyBrZWVwcyB0aGUgY2FyZCBnbHVlZCB0byBpdHMgYW5jaG9yLiBXcml0ZXMgZGlyZWN0bHkgdG8gdGhlXG4gIC8vIERPTSBzbyB3ZSBkb24ndCByZS1yZW5kZXIgZXZlcnkgZnJhbWUuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3QgdGljayA9ICgpID0+IHtcbiAgICAgIHJhZlJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICAgIGNvbnN0IG5vZGUgPSBjYXJkUmVmLmN1cnJlbnQ7XG4gICAgICBpZiAoIW5vZGUpIHJldHVybjtcbiAgICAgIGNvbnN0IGFuY2hvciA9IGNvbXB1dGVBbmNob3Ioc3RhdGUpO1xuICAgICAgbm9kZS5zdHlsZS5sZWZ0ID0gYCR7TWF0aC5yb3VuZChhbmNob3IueCl9cHhgO1xuICAgICAgbm9kZS5zdHlsZS50b3AgPSBgJHtNYXRoLnJvdW5kKGFuY2hvci55KX1weGA7XG4gICAgICByYWZSZWYuY3VycmVudCA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aWNrKTtcbiAgICB9O1xuICAgIHJhZlJlZi5jdXJyZW50ID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRpY2spO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBpZiAocmFmUmVmLmN1cnJlbnQgIT0gbnVsbCkgY2FuY2VsQW5pbWF0aW9uRnJhbWUocmFmUmVmLmN1cnJlbnQpO1xuICAgIH07XG4gIH0sIFtzdGF0ZV0pO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgdGV4dGFyZWFSZWYuY3VycmVudD8uZm9jdXMoKTtcbiAgfSwgW10pO1xuXG4gIGNvbnN0IHRyeVN1Ym1pdCA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBjb25zdCB2ID0gdGV4dC50cmltKCk7XG4gICAgaWYgKCF2KSByZXR1cm47XG4gICAgb25TdWJtaXQodik7XG4gIH0sIFt0ZXh0LCBvblN1Ym1pdF0pO1xuXG4gIGNvbnN0IG9uS2V5RG93biA9IHVzZUNhbGxiYWNrKFxuICAgIChlOiBSZWFjdC5LZXlib2FyZEV2ZW50PEhUTUxUZXh0QXJlYUVsZW1lbnQ+KSA9PiB7XG4gICAgICBpZiAoZS5rZXkgPT09ICdFc2NhcGUnKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgb25DYW5jZWwoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKChlLm1ldGFLZXkgfHwgZS5jdHJsS2V5KSAmJiBlLmtleSA9PT0gJ0VudGVyJykge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRyeVN1Ym1pdCgpO1xuICAgICAgfVxuICAgIH0sXG4gICAgW29uQ2FuY2VsLCB0cnlTdWJtaXRdXG4gICk7XG5cbiAgLy8gQ29tcGFjdCBzZWxlY3RvciBoaW50IOKAlCBzdHJpcCBub2lzeSBzdHJ1Y3R1cmFsIGJpdHMgc28gdGhlIGhlYWQgc3RheXNcbiAgLy8gdGlnaHQgaW5zaWRlIHRoZSAzMDBweCBjYXJkLlxuICBjb25zdCBzZWxlY3RvckNoaXAgPSB1c2VNZW1vKCgpID0+IHtcbiAgICBjb25zdCBzID0gc3RhdGUuc2VsZWN0aW9uLnNlbGVjdG9yIHx8ICcnO1xuICAgIGlmICghcykgcmV0dXJuIHN0YXRlLnNlbGVjdGlvbi50YWcgfHwgJ2NhbnZhcyc7XG4gICAgLy8gW2RhdGEtY2QtaWQ9XCLigKZcIl0g4oaSIGNkOjxpZD4gwrcga2VlcHMgdGhlIGNoaXAgcmVhZGFibGUgd2hlbiBzdGFibGUgaWRzXG4gICAgLy8gYXJlIHByZXNlbnQuXG4gICAgY29uc3QgY2QgPSBzLm1hdGNoKC9kYXRhLWNkLWlkPVwiKFteXCJdKylcIi8pO1xuICAgIGlmIChjZCkgcmV0dXJuIGBjZDoke2NkWzFdfWA7XG4gICAgcmV0dXJuIHMubGVuZ3RoID4gMzYgPyBgJHtzLnNsaWNlKDAsIDMzKX3igKZgIDogcztcbiAgfSwgW3N0YXRlLnNlbGVjdGlvbl0pO1xuXG4gIHJldHVybiAoXG4gICAgPGRpdlxuICAgICAgcmVmPXtjYXJkUmVmfVxuICAgICAgY2xhc3NOYW1lPVwiY20tY29tcG9zZXJcIlxuICAgICAgcm9sZT1cImRpYWxvZ1wiXG4gICAgICBhcmlhLWxhYmVsPVwiTmV3IGNvbW1lbnRcIlxuICAgICAgb25DbGljaz17KGUpID0+IGUuc3RvcFByb3BhZ2F0aW9uKCl9XG4gICAgICBvblBvaW50ZXJEb3duPXsoZSkgPT4gZS5zdG9wUHJvcGFnYXRpb24oKX1cbiAgICA+XG4gICAgICA8ZGl2IGNsYXNzTmFtZT1cImNtLWNvbXBvc2VyX19oZWFkXCI+XG4gICAgICAgIDxzcGFuPk5ldyBjb21tZW50PC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzc05hbWU9XCJjbS1jb21wb3Nlcl9fc2VsZWN0b3JcIj57c2VsZWN0b3JDaGlwfTwvc3Bhbj5cbiAgICAgIDwvZGl2PlxuICAgICAgPE1lbnRpb25Bd2FyZVRleHRhcmVhXG4gICAgICAgIHRleHRhcmVhUmVmPXt0ZXh0YXJlYVJlZn1cbiAgICAgICAgY2xhc3NOYW1lPVwiY20tY29tcG9zZXJfX3RleHRhcmVhXCJcbiAgICAgICAgdmFsdWU9e3RleHR9XG4gICAgICAgIHBsYWNlaG9sZGVyPVwiVHlwZSBhIGNvbW1lbnQuIOKMmOKGtSB0byBzYXZlIMK3IEVzYyB0byBjYW5jZWwgwrcgQG5hbWUgdG8gdGFnXCJcbiAgICAgICAgb25DaGFuZ2U9e3NldFRleHR9XG4gICAgICAgIG9uS2V5RG93bj17b25LZXlEb3dufVxuICAgICAgICByb3dzPXszfVxuICAgICAgICBhcmlhTGFiZWw9XCJDb21tZW50IGJvZHlcIlxuICAgICAgLz5cbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwiY20tY29tcG9zZXJfX2FjdGlvbnNcIj5cbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3NOYW1lPVwiY20tYnRuXCIgb25DbGljaz17b25DYW5jZWx9PlxuICAgICAgICAgIENhbmNlbFxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIGNsYXNzTmFtZT1cImNtLWJ0biBjbS1idG4tLXByaW1hcnlcIlxuICAgICAgICAgIGRpc2FibGVkPXshdGV4dC50cmltKCl9XG4gICAgICAgICAgb25DbGljaz17dHJ5U3VibWl0fVxuICAgICAgICA+XG4gICAgICAgICAgU2F2ZVxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICApO1xufVxuXG4vLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbi8vIENvbW1lbnRUaHJlYWQg4oCUIHBvcG92ZXIgYW5jaG9yZWQgdG8gdGhlIGZvY3VzZWQgcGluLiBTaG93cyBhdXRob3IgKyByZWxhdGl2ZVxuLy8gdGltZSArIHNlbGVjdG9yIGNoaXAsIHRoZSBvcmlnaW5hbCBib2R5IHdpdGggQG1lbnRpb25zIGJvbGRlZCwgcmVwbGllcywgYVxuLy8gcmVwbHkgdGV4dGFyZWEsIGFuZCByZXNvbHZlL3Jlb3Blbi9kZWxldGUgYWN0aW9ucy4gUGF0Y2hlcyArIGRlbGV0ZXMgcm91dGVcbi8vIHRocm91Z2ggdGhlIHNoZWxsJ3MgZXhpc3RpbmcgV1MgY2hhbm5lbCB2aWEgcG9zdE1lc3NhZ2U7IHJlcGxpZXMgUE9TVFxuLy8gZGlyZWN0bHkgdG8gYC9fYXBpL2NvbW1lbnRzLzxpZD4vcmVwbHlgIGJlY2F1c2UgdGhhdCBlbmRwb2ludCBleGlzdHMgb25seSBvblxuLy8gQnVuIHJ1bnRpbWUgYW5kIGxpdmVzIGluIGBodHRwLnRzYC5cblxuZnVuY3Rpb24gQ29tbWVudFRocmVhZCh7XG4gIGNvbW1lbnQsXG4gIG9uQ2xvc2UsXG4gIG9uUGF0Y2gsXG4gIG9uRGVsZXRlLFxuICBvblJlcGx5LFxufToge1xuICBjb21tZW50OiBPdmVybGF5Q29tbWVudDtcbiAgb25DbG9zZTogKCkgPT4gdm9pZDtcbiAgb25QYXRjaDogKHBhdGNoOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikgPT4gdm9pZDtcbiAgb25EZWxldGU6ICgpID0+IHZvaWQ7XG4gIG9uUmVwbHk6IChib2R5OiBzdHJpbmcpID0+IFByb21pc2U8Ym9vbGVhbj47XG59KSB7XG4gIGNvbnN0IGRpYWxvZ1JlZiA9IHVzZVJlZjxIVE1MRGl2RWxlbWVudCB8IG51bGw+KG51bGwpO1xuICBjb25zdCByZXBseVJlZiA9IHVzZVJlZjxIVE1MVGV4dEFyZWFFbGVtZW50IHwgbnVsbD4obnVsbCk7XG4gIGNvbnN0IHJhZlJlZiA9IHVzZVJlZjxudW1iZXIgfCBudWxsPihudWxsKTtcbiAgY29uc3QgW3JlcGx5LCBzZXRSZXBseV0gPSB1c2VTdGF0ZSgnJyk7XG4gIGNvbnN0IFtzZW5kaW5nLCBzZXRTZW5kaW5nXSA9IHVzZVN0YXRlKGZhbHNlKTtcblxuICAvLyBMaXZlIGFuY2hvciDigJQgcG9wb3ZlciB0cmFja3MgdGhlIHBpbiB2aWEgckFGIHNvIGl0IHN0YXlzIGdsdWVkIHRvIGl0c1xuICAvLyB0YXJnZXQgdGhyb3VnaCBwYW4gLyB6b29tIChGaWdKYW0gcGFyaXR5KS4gV3JpdGluZyB0byB0aGUgZGlhbG9nIHN0eWxlXG4gIC8vIGRpcmVjdGx5IGF2b2lkcyByZS1yZW5kZXJpbmcgZXZlcnkgZnJhbWUuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3QgdGljayA9ICgpID0+IHtcbiAgICAgIHJhZlJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICAgIGNvbnN0IG5vZGUgPSBkaWFsb2dSZWYuY3VycmVudDtcbiAgICAgIGlmICghbm9kZSkgcmV0dXJuO1xuICAgICAgY29uc3QgYW5jaG9yID0gY29tcHV0ZVRocmVhZEFuY2hvcihjb21tZW50KTtcbiAgICAgIG5vZGUuc3R5bGUubGVmdCA9IGAke01hdGgucm91bmQoYW5jaG9yLngpfXB4YDtcbiAgICAgIG5vZGUuc3R5bGUudG9wID0gYCR7TWF0aC5yb3VuZChhbmNob3IueSl9cHhgO1xuICAgICAgcmFmUmVmLmN1cnJlbnQgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUodGljayk7XG4gICAgfTtcbiAgICByYWZSZWYuY3VycmVudCA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aWNrKTtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgaWYgKHJhZlJlZi5jdXJyZW50ICE9IG51bGwpIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHJhZlJlZi5jdXJyZW50KTtcbiAgICB9O1xuICB9LCBbY29tbWVudF0pO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgLy8gTW92ZSBmb2N1cyBpbnRvIHRoZSBkaWFsb2cgb24gb3Blbi4gUGVyIFdDQUcgMi4xIHRoZSBkaWFsb2cgc2hvdWxkIG93blxuICAgIC8vIGluaXRpYWwgZm9jdXM7IHdlIHB1dCBpdCBvbiB0aGUgZGlhbG9nIHJvb3QgKGZvY3VzYWJsZSB2aWEgdGFiaW5kZXgpXG4gICAgLy8gc28gc2NyZWVuIHJlYWRlcnMgYW5ub3VuY2UgdGhlIGhlYWRlciBiZWZvcmUgdGhlIGJvZHkuIE9uIGNsb3NlLFxuICAgIC8vIHJldHVybiBmb2N1cyB0byB0aGUgcGluIHNvIGtleWJvYXJkIHVzZXJzIGxhbmQgd2hlcmUgdGhleSBzdGFydGVkLlxuICAgIGRpYWxvZ1JlZi5jdXJyZW50Py5mb2N1cygpO1xuICAgIGNvbnN0IHBpbklkID0gY29tbWVudC5pZDtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgY29uc3QgcGluID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcjxIVE1MQnV0dG9uRWxlbWVudD4oYFtkYXRhLWNvbW1lbnQtcGluPVwiJHtwaW5JZH1cIl1gKTtcbiAgICAgIHBpbj8uZm9jdXMoKTtcbiAgICB9O1xuICB9LCBbY29tbWVudC5pZF0pO1xuXG4gIC8vIEVzYy10by1jbG9zZSB3aGlsZSBmb2N1cyBpcyBhbnl3aGVyZSBpbnNpZGUgdGhlIHBvcG92ZXIuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKHR5cGVvZiBkb2N1bWVudCA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybjtcbiAgICBjb25zdCBvbktleSA9IChlOiBLZXlib2FyZEV2ZW50KSA9PiB7XG4gICAgICBpZiAoZS5rZXkgIT09ICdFc2NhcGUnKSByZXR1cm47XG4gICAgICBjb25zdCByb290ID0gZGlhbG9nUmVmLmN1cnJlbnQ7XG4gICAgICBpZiAoIXJvb3QpIHJldHVybjtcbiAgICAgIGlmIChyb290LmNvbnRhaW5zKGUudGFyZ2V0IGFzIE5vZGUpIHx8IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgPT09IHJvb3QpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBvbkNsb3NlKCk7XG4gICAgICB9XG4gICAgfTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgb25LZXkpO1xuICAgIHJldHVybiAoKSA9PiBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgb25LZXkpO1xuICB9LCBbb25DbG9zZV0pO1xuXG4gIGNvbnN0IHRyeVNlbmRSZXBseSA9IHVzZUNhbGxiYWNrKGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB2ID0gcmVwbHkudHJpbSgpO1xuICAgIGlmICghdiB8fCBzZW5kaW5nKSByZXR1cm47XG4gICAgc2V0U2VuZGluZyh0cnVlKTtcbiAgICBjb25zdCBvayA9IGF3YWl0IG9uUmVwbHkodik7XG4gICAgc2V0U2VuZGluZyhmYWxzZSk7XG4gICAgaWYgKG9rKSB7XG4gICAgICBzZXRSZXBseSgnJyk7XG4gICAgICByZXBseVJlZi5jdXJyZW50Py5mb2N1cygpO1xuICAgIH1cbiAgfSwgW3JlcGx5LCBzZW5kaW5nLCBvblJlcGx5XSk7XG5cbiAgY29uc3Qgb25SZXBseUtleURvd24gPSB1c2VDYWxsYmFjayhcbiAgICAoZTogUmVhY3QuS2V5Ym9hcmRFdmVudDxIVE1MVGV4dEFyZWFFbGVtZW50PikgPT4ge1xuICAgICAgaWYgKChlLm1ldGFLZXkgfHwgZS5jdHJsS2V5KSAmJiBlLmtleSA9PT0gJ0VudGVyJykge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHZvaWQgdHJ5U2VuZFJlcGx5KCk7XG4gICAgICB9XG4gICAgfSxcbiAgICBbdHJ5U2VuZFJlcGx5XVxuICApO1xuXG4gIGNvbnN0IGhlYWRJZCA9IGBjbS10aHJlYWQtaGVhZC0ke2NvbW1lbnQuaWR9YDtcbiAgY29uc3Qgc2VsZWN0b3JDaGlwID0gZm9ybWF0U2VsZWN0b3JDaGlwKGNvbW1lbnQuc2VsZWN0b3IsICcnKTtcblxuICByZXR1cm4gKFxuICAgIDxkaXZcbiAgICAgIHJlZj17ZGlhbG9nUmVmfVxuICAgICAgY2xhc3NOYW1lPVwiY20tdGhyZWFkXCJcbiAgICAgIHJvbGU9XCJkaWFsb2dcIlxuICAgICAgYXJpYS1sYWJlbGxlZGJ5PXtoZWFkSWR9XG4gICAgICB0YWJJbmRleD17LTF9XG4gICAgICBvbkNsaWNrPXsoZSkgPT4gZS5zdG9wUHJvcGFnYXRpb24oKX1cbiAgICAgIG9uUG9pbnRlckRvd249eyhlKSA9PiBlLnN0b3BQcm9wYWdhdGlvbigpfVxuICAgID5cbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwiY20tdGhyZWFkX19oZWFkXCIgaWQ9e2hlYWRJZH0+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiY20tdGhyZWFkX19oZWFkLXJvd1wiPlxuICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cImNtLXRocmVhZF9fYXV0aG9yXCI+e2NvbW1lbnQuYXV0aG9yPy50cmltKCkgfHwgJ3Vua25vd24nfTwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzc05hbWU9XCJjbS10aHJlYWRfX3RpbWVcIj57Zm9ybWF0UmVsYXRpdmVUaW1lKGNvbW1lbnQuY3JlYXRlZCl9PC9zcGFuPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgY2xhc3NOYW1lPVwiY20tdGhyZWFkX19jbG9zZVwiXG4gICAgICAgICAgICBhcmlhLWxhYmVsPVwiQ2xvc2UgdGhyZWFkXCJcbiAgICAgICAgICAgIHRpdGxlPVwiQ2xvc2UgwrcgRXNjXCJcbiAgICAgICAgICAgIG9uQ2xpY2s9e29uQ2xvc2V9XG4gICAgICAgICAgPlxuICAgICAgICAgICAgw5dcbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIHtzZWxlY3RvckNoaXAgPyA8Y29kZSBjbGFzc05hbWU9XCJjbS10aHJlYWRfX3NlbGVjdG9yXCI+e3NlbGVjdG9yQ2hpcH08L2NvZGU+IDogbnVsbH1cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGNsYXNzTmFtZT1cImNtLXRocmVhZF9fYm9keVwiPntyZW5kZXJCb2R5V2l0aE1lbnRpb25zKGNvbW1lbnQudGV4dCl9PC9kaXY+XG5cbiAgICAgIHsoY29tbWVudC50aHJlYWQgPz8gW10pLm1hcCgocikgPT4gKFxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImNtLXRocmVhZF9fcmVwbHlcIiBrZXk9e3IuaWR9PlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiY20tdGhyZWFkX19yZXBseS1oZWFkXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzc05hbWU9XCJjbS10aHJlYWRfX3JlcGx5LWF1dGhvclwiPntyLmF1dGhvcj8udHJpbSgpIHx8ICd1bmtub3duJ308L3NwYW4+XG4gICAgICAgICAgICA8c3BhbiBjbGFzc05hbWU9XCJjbS10aHJlYWRfX3JlcGx5LXRpbWVcIj57Zm9ybWF0UmVsYXRpdmVUaW1lKHIuY3JlYXRlZCl9PC9zcGFuPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiY20tdGhyZWFkX19yZXBseS1ib2R5XCI+e3JlbmRlckJvZHlXaXRoTWVudGlvbnMoci5ib2R5KX08L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICApKX1cblxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJjbS10aHJlYWRfX3JlcGx5LWZvcm1cIj5cbiAgICAgICAgPE1lbnRpb25Bd2FyZVRleHRhcmVhXG4gICAgICAgICAgdGV4dGFyZWFSZWY9e3JlcGx5UmVmfVxuICAgICAgICAgIGNsYXNzTmFtZT1cImNtLXRocmVhZF9fcmVwbHktdGV4dGFyZWFcIlxuICAgICAgICAgIHZhbHVlPXtyZXBseX1cbiAgICAgICAgICBwbGFjZWhvbGRlcj1cIlJlcGx54oCmIOKMmOKGtSB0byBzZW5kIMK3IEBuYW1lIHRvIHRhZ1wiXG4gICAgICAgICAgb25DaGFuZ2U9e3NldFJlcGx5fVxuICAgICAgICAgIG9uS2V5RG93bj17b25SZXBseUtleURvd259XG4gICAgICAgICAgcm93cz17Mn1cbiAgICAgICAgICBhcmlhTGFiZWw9XCJSZXBseVwiXG4gICAgICAgICAgZGlzYWJsZWQ9e3NlbmRpbmd9XG4gICAgICAgIC8+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiY20tdGhyZWFkX19yZXBseS1hY3Rpb25zXCI+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBjbGFzc05hbWU9XCJjbS1idG4gY20tYnRuLS1wcmltYXJ5XCJcbiAgICAgICAgICAgIGRpc2FibGVkPXshcmVwbHkudHJpbSgpIHx8IHNlbmRpbmd9XG4gICAgICAgICAgICBvbkNsaWNrPXsoKSA9PiB2b2lkIHRyeVNlbmRSZXBseSgpfVxuICAgICAgICAgID5cbiAgICAgICAgICAgIFNlbmRcbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJjbS10aHJlYWRfX2FjdGlvbnNcIj5cbiAgICAgICAge2NvbW1lbnQuc3RhdHVzID09PSAncmVzb2x2ZWQnID8gKFxuICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzTmFtZT1cImNtLWJ0blwiIG9uQ2xpY2s9eygpID0+IG9uUGF0Y2goeyBzdGF0dXM6ICdvcGVuJyB9KX0+XG4gICAgICAgICAgICDihrogUmVvcGVuXG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICkgOiAoXG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBjbGFzc05hbWU9XCJjbS1idG4gY20tYnRuLS1wcmltYXJ5XCJcbiAgICAgICAgICAgIG9uQ2xpY2s9eygpID0+IHtcbiAgICAgICAgICAgICAgb25QYXRjaCh7IHN0YXR1czogJ3Jlc29sdmVkJyB9KTtcbiAgICAgICAgICAgICAgb25DbG9zZSgpO1xuICAgICAgICAgICAgfX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICDinJMgUmVzb2x2ZVxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICApfVxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgY2xhc3NOYW1lPVwiY20tYnRuIGNtLWJ0bi0tZGFuZ2VyXCJcbiAgICAgICAgICBvbkNsaWNrPXsoKSA9PiB7XG4gICAgICAgICAgICBvbkRlbGV0ZSgpO1xuICAgICAgICAgICAgb25DbG9zZSgpO1xuICAgICAgICAgIH19XG4gICAgICAgID5cbiAgICAgICAgICBEZWxldGVcbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgKTtcbn1cblxuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4vLyBCb2R5IHJlbmRlcmVyIOKAlCBzcGxpdHMgdGV4dCBvbiBALWhhbmRsZXMsIHdyYXBzIGVhY2ggaW4gPHN0cm9uZz4uIEFueXRoaW5nXG4vLyBub3QgbWF0Y2hpbmcgdGhlIG1lbnRpb24gcmVnZXggc3RheXMgcGxhaW4gdGV4dCAobmV3bGluZXMgcHJlc2VydmVkIGJ5IENTU1xuLy8gYHdoaXRlLXNwYWNlOiBwcmUtd3JhcGApLlxuXG5mdW5jdGlvbiByZW5kZXJCb2R5V2l0aE1lbnRpb25zKHRleHQ6IHN0cmluZyk6IFJlYWN0LlJlYWN0Tm9kZSB7XG4gIGlmICghdGV4dCkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IHJlID0gLyhAW1xcd11bXFx3Li1dKikvZztcbiAgY29uc3QgcGFydHMgPSB0ZXh0LnNwbGl0KHJlKTtcbiAgcmV0dXJuIHBhcnRzLm1hcCgocGFydCwgaSkgPT4ge1xuICAgIC8vIFRoZSBzcGxpdCBwb3NpdGlvbnMgQVJFIHRoZSBpZGVudGl0eSBoZXJlIOKAlCBmb3IgdGhlIHNhbWUgYHRleHRgIGlucHV0LFxuICAgIC8vIGluZGV4IGBpYCBhbHdheXMgbWFwcyB0byB0aGUgc2FtZSBmcmFnbWVudC4gQ29tcG9zZSBrZXkgZnJvbSBpbmRleCArXG4gICAgLy8gY29udGVudCBzbyBiaW9tZSdzIGFycmF5LWluZGV4LWtleSBoZXVyaXN0aWMgaXMgc2F0aXNmaWVkIEFORCByZW9yZGVyXG4gICAgLy8gcmVzaXN0YW5jZSBpcyBpbnRhY3QgaWYgYHRleHRgIG11dGF0ZXMgbWlkLXJlbmRlci5cbiAgICBjb25zdCBrZXkgPSBgJHtpfToke3BhcnR9YDtcbiAgICBpZiAoaSAlIDIgPT09IDEpIHtcbiAgICAgIC8vIE9kZCBwYXJ0cyBhcmUgdGhlIGNhcHR1cmVkIEBoYW5kbGVzIHRoYW5rcyB0byB0aGUgcGFyZW50aGVzaXplZCBzcGxpdC5cbiAgICAgIHJldHVybiAoXG4gICAgICAgIDxzdHJvbmcga2V5PXtrZXl9IGRhdGEtbWVudGlvbj1cInRydWVcIj5cbiAgICAgICAgICB7cGFydH1cbiAgICAgICAgPC9zdHJvbmc+XG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gPHNwYW4ga2V5PXtrZXl9PntwYXJ0fTwvc3Bhbj47XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRSZWxhdGl2ZVRpbWUoaXNvOiBzdHJpbmcpOiBzdHJpbmcge1xuICBpZiAoIWlzbykgcmV0dXJuICcnO1xuICBjb25zdCB0ID0gRGF0ZS5wYXJzZShpc28pO1xuICBpZiAoIU51bWJlci5pc0Zpbml0ZSh0KSkgcmV0dXJuICcnO1xuICBjb25zdCBkaWZmU2VjID0gTWF0aC5yb3VuZCgoRGF0ZS5ub3coKSAtIHQpIC8gMTAwMCk7XG4gIGlmIChkaWZmU2VjIDwgNjApIHJldHVybiBgJHtNYXRoLm1heChkaWZmU2VjLCAwKX1zIGFnb2A7XG4gIGlmIChkaWZmU2VjIDwgMzYwMCkgcmV0dXJuIGAke01hdGgucm91bmQoZGlmZlNlYyAvIDYwKX1tIGFnb2A7XG4gIGlmIChkaWZmU2VjIDwgODZfNDAwKSByZXR1cm4gYCR7TWF0aC5yb3VuZChkaWZmU2VjIC8gMzYwMCl9aCBhZ29gO1xuICByZXR1cm4gYCR7TWF0aC5yb3VuZChkaWZmU2VjIC8gODZfNDAwKX1kIGFnb2A7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFNlbGVjdG9yQ2hpcChzZWxlY3Rvcjogc3RyaW5nLCBmYWxsYmFjazogc3RyaW5nKTogc3RyaW5nIHtcbiAgaWYgKCFzZWxlY3RvcikgcmV0dXJuIGZhbGxiYWNrO1xuICBjb25zdCBjZCA9IHNlbGVjdG9yLm1hdGNoKC9kYXRhLWNkLWlkPVwiKFteXCJdKylcIi8pO1xuICBpZiAoY2QpIHJldHVybiBgY2Q6JHtjZFsxXX1gO1xuICByZXR1cm4gc2VsZWN0b3IubGVuZ3RoID4gMzYgPyBgJHtzZWxlY3Rvci5zbGljZSgwLCAzMyl94oCmYCA6IHNlbGVjdG9yO1xufVxuXG5mdW5jdGlvbiBjb21wdXRlVGhyZWFkQW5jaG9yKGNvbW1lbnQ6IE92ZXJsYXlDb21tZW50KTogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9IHtcbiAgLy8gUmVzb2x2ZSB0YXJnZXQncyBsaXZlIHNjcmVlbiByZWN0OyBwb3BvdmVyIGRyb3BzIGJlbG93IHRoZSBwaW4gd2l0aCBzbWFsbFxuICAvLyBicmVhdGhpbmcgcm9vbS4gU3RvcmVkIGJvdW5kcyAoY2FwdHVyZS10aW1lIHNjcmVlbiBjb29yZHMpIGFyZSB0aGVcbiAgLy8gbGFzdC1yZXNvcnQgZmFsbGJhY2sgZm9yIG9ycGhhbmVkIHBpbnMuXG4gIGNvbnN0IHJlY3QgPSBjb21tZW50LnNlbGVjdG9yID8gc2NyZWVuUmVjdEZvcihjb21tZW50LnNlbGVjdG9yKSA6IG51bGw7XG4gIGlmIChyZWN0KSB7XG4gICAgLy8gUGluIHNpdHMgYXQgKHJlY3QucmlnaHQgLSAxMiwgcmVjdC50b3AgLSAxMikuIFBsYWNlIHBvcG92ZXIgYXQgdGhlIHNhbWVcbiAgICAvLyB4IGZvciB2aXN1YWwgY29udGludWl0eSwgMTZweCBiZWxvdyB0aGUgdG9wIHNvIGl0IGNsZWFycyB0aGUgcGluLlxuICAgIHJldHVybiB7IHg6IHJlY3QueCArIHJlY3QudyAtIDEyLCB5OiByZWN0LnkgKyAxNiB9O1xuICB9XG4gIGlmIChjb21tZW50LmJvdW5kcykge1xuICAgIHJldHVybiB7IHg6IGNvbW1lbnQuYm91bmRzLnggKyBjb21tZW50LmJvdW5kcy53IC0gMTIsIHk6IGNvbW1lbnQuYm91bmRzLnkgKyAxNiB9O1xuICB9XG4gIHJldHVybiB7IHg6IDE2LCB5OiAxNiB9O1xufVxuXG5mdW5jdGlvbiBjb21wdXRlQW5jaG9yKHN0YXRlOiBDb21wb3NlclN0YXRlKTogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9IHtcbiAgLy8gRzQg4oCUIGFuY2hvciB0byB0aGUgY3Vyc29yIGNsaWNrIHBvaW50IGZpcnN0LiBFYXJsaWVyIHZlcnNpb25zIGFuY2hvcmVkIHRvXG4gIC8vIHRoZSBzZWxlY3RlZCBlbGVtZW50J3MgYm90dG9tLWxlZnQsIHdoaWNoIGxhbmRlZCB0aGUgY29tcG9zZXIgZmx1c2ggaW5cbiAgLy8gdGhlIGNvcm5lciByZWdhcmRsZXNzIG9mIHdoZXJlIHRoZSB1c2VyIGNsaWNrZWQg4oCUIHN1cnByaXNpbmcgZm9yIHRoZVxuICAvLyBjb21tb24gY2FzZSBvZiBcIkkgY2xpY2tlZCB0aGUgbWlkZGxlIG9mIGFuIGVsZW1lbnQsIGV4cGVjdGluZyB0aGVcbiAgLy8gY29tcG9zZXIgdG8gYXBwZWFyIG5lYXIgbXkgY3Vyc29yXCIuIFRoZSBlbGVtZW50LXJlY3QgcGF0aCByZW1haW5zIGFzIGFcbiAgLy8gZmFsbGJhY2sgZm9yIGVudHJ5IHBvaW50cyB0aGF0IGRvbid0IGNhcnJ5IGEgY3Vyc29yIChlLmcuIG9wZW5pbmcgdGhlXG4gIC8vIGNvbXBvc2VyIGZyb20gYSBjb250ZXh0dWFsIHRvb2xiYXIgYnV0dG9uIOKAlCB0aG9zZSBzaG91bGQgc2V0IGNsaWVudFgvWVxuICAvLyB0byBhIHNlbnNpYmxlIGFuY2hvciBiZWZvcmUgZGlzcGF0Y2hpbmcpLlxuICBpZiAoc3RhdGUuY2xpZW50WCB8fCBzdGF0ZS5jbGllbnRZKSB7XG4gICAgcmV0dXJuIHsgeDogc3RhdGUuY2xpZW50WCwgeTogc3RhdGUuY2xpZW50WSArIDggfTtcbiAgfVxuICBpZiAoc3RhdGUuc2VsZWN0aW9uLnNlbGVjdG9yKSB7XG4gICAgY29uc3QgcmVjdCA9IHNjcmVlblJlY3RGb3Ioc3RhdGUuc2VsZWN0aW9uLnNlbGVjdG9yKTtcbiAgICBpZiAocmVjdCkge1xuICAgICAgcmV0dXJuIHsgeDogcmVjdC54LCB5OiByZWN0LnkgKyByZWN0LmggKyA4IH07XG4gICAgfVxuICB9XG4gIHJldHVybiB7IHg6IDE2LCB5OiAxNiB9O1xufVxuIiwKICAgICIvKipcbiAqIEBmaWxlICAgICAgIHVzZS1jb2xsYWIudHN4IOKAlCBjbGllbnQtc2lkZSBZanMgY29sbGFiIHByb3ZpZGVyIGZvciBjYW52YXMgaWZyYW1lc1xuICogQHNjb3BlICAgICAgcGx1Z2lucy9kZXNpZ24vZGV2LXNlcnZlci91c2UtY29sbGFiLnRzeFxuICogQHB1cnBvc2UgICAgTW91bnRzIGEgc2luZ2xlIFkuRG9jICsgQXdhcmVuZXNzIHBlciBjYW52YXMgaWZyYW1lLiBPcGVucyBhXG4gKiAgICAgICAgICAgICBXZWJTb2NrZXQgdG8gYC9fd3MvY29sbGFiLzpzbHVnYCwgc3BlYWtzIHRoZSB5LXdlYnNvY2tldCBiaW5hcnlcbiAqICAgICAgICAgICAgIHByb3RvY29sLCBleHBvc2VzIGhvb2tzIGZvciB0aGUgY3Vyc29yIG92ZXJsYXkgKyBUYXNrIDMgY29tbWVudHNcbiAqICAgICAgICAgICAgIGJpbmRpbmcuXG4gKlxuICogQm91bmRhcnk6XG4gKiAgIC0gU2VydmVyLXNpZGUgZXF1aXZhbGVudCBpcyBgY29sbGFiL3Byb3RvY29sLnRzYCArIGBjb2xsYWIvcm9vbS50c2AuXG4gKiAgIC0gVGhpcyBmaWxlIG1pcnJvcnMgdGhlIG1lc3NhZ2UgZnJhbWluZyAodmFyaW50LXByZWZpeGVkIHN5bmMgKyBhd2FyZW5lc3NcbiAqICAgICBmcmFtZXMpIHNvIHRoZSB0d28gc2lkZXMgY29udmVyZ2Ugb3ZlciBhIGJpbmFyeSBXUyB3aXRob3V0IGludGVybWVkaWF0ZVxuICogICAgIEpTT04uXG4gKiAgIC0gSW1wb3J0cyBgeWpzYCArIGB5LXByb3RvY29scy97c3luYyxhd2FyZW5lc3N9YCB2aWEgdGhlIGNhbnZhcy1zaGVsbFxuICogICAgIGltcG9ydG1hcCAoUlVOVElNRV9QQUNLQUdFUyBhZGRpdGlvbnMpLiBDYW52YXMgYnVuZGxlcyB0aGF0IGRvbid0IG1vdW50XG4gKiAgICAgPENvbGxhYlByb3ZpZGVyPiBuZXZlciByZXNvbHZlIHRoZXNlIHNwZWNpZmllcnMgYW5kIHBheSB6ZXJvIGJ1bmRsZSBjb3N0LlxuICovXG5cbmltcG9ydCAqIGFzIGRlY29kaW5nIGZyb20gJ2xpYjAvZGVjb2RpbmcnO1xuaW1wb3J0ICogYXMgZW5jb2RpbmcgZnJvbSAnbGliMC9lbmNvZGluZyc7XG5pbXBvcnQge1xuICBjcmVhdGVDb250ZXh0LFxuICB0eXBlIFJlYWN0Tm9kZSxcbiAgdXNlQ2FsbGJhY2ssXG4gIHVzZUNvbnRleHQsXG4gIHVzZUVmZmVjdCxcbiAgdXNlTWVtbyxcbiAgdXNlUmVmLFxuICB1c2VTdGF0ZSxcbn0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgQXdhcmVuZXNzLCBhcHBseUF3YXJlbmVzc1VwZGF0ZSwgZW5jb2RlQXdhcmVuZXNzVXBkYXRlIH0gZnJvbSAneS1wcm90b2NvbHMvYXdhcmVuZXNzJztcbmltcG9ydCB7IHJlYWRTeW5jTWVzc2FnZSwgd3JpdGVTeW5jU3RlcDEsIHdyaXRlVXBkYXRlIH0gZnJvbSAneS1wcm90b2NvbHMvc3luYyc7XG5pbXBvcnQgKiBhcyBZIGZyb20gJ3lqcyc7XG5cbmNvbnN0IE1FU1NBR0VfU1lOQyA9IDA7XG5jb25zdCBNRVNTQUdFX0FXQVJFTkVTUyA9IDE7XG5cbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuLy8gQ29sb3IgaGFzaCDigJQgc3RhYmxlIHBlciBwZWVyIGlkZW50aXR5LlxuXG4vKipcbiAqIGRqYjIgc3RyaW5nIGhhc2gg4oaSIDB4UlJHR0JCIGNvbG9yIGluIGEgY3VyYXRlZCBwYWxldHRlLiBEZXRlcm1pbmlzbSBwZXJcbiAqIGlucHV0IG5hbWUgaXMgdGhlIGxvYWQtYmVhcmluZyBwcm9wZXJ0eTogZXZlcnkgcGVlciBoYXNoaW5nIFwiQWxpY2VcIiBtdXN0XG4gKiBsYW5kIG9uIHRoZSBTQU1FIGNvbG9yLiAxMiBodWVzIHNwcmVhZCBldmVubHkgYXJvdW5kIHRoZSB3aGVlbDsgc2F0dXJhdGlvblxuICogKyBsaWdodG5lc3MgZml4ZWQgc28gYWxsIGNvbG9ycyBzdGF5IHJlYWRhYmxlIG9uIGxpZ2h0ICsgZGFyayBzdXJmYWNlcy5cbiAqL1xuY29uc3QgQ09MT1JfUEFMRVRURSA9IFtcbiAgJyNlOTFlNjMnLCAvLyBwaW5rXG4gICcjZjQ0MzM2JywgLy8gcmVkXG4gICcjZmY5ODAwJywgLy8gb3JhbmdlXG4gICcjZmZjMTA3JywgLy8gYW1iZXJcbiAgJyNjZGRjMzknLCAvLyBsaW1lXG4gICcjNGNhZjUwJywgLy8gZ3JlZW5cbiAgJyMwMDk2ODgnLCAvLyB0ZWFsXG4gICcjMDBiY2Q0JywgLy8gY3lhblxuICAnIzAzYTlmNCcsIC8vIGxpZ2h0IGJsdWVcbiAgJyMzZjUxYjUnLCAvLyBpbmRpZ29cbiAgJyM2NzNhYjcnLCAvLyBkZWVwIHB1cnBsZVxuICAnIzljMjdiMCcsIC8vIHB1cnBsZVxuXSBhcyBjb25zdDtcblxuZXhwb3J0IGZ1bmN0aW9uIGNvbG9yRm9yTmFtZShuYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAvLyBDT0xPUl9QQUxFVFRFIGlzIGEgbm9uLWVtcHR5IGNvbnN0IHR1cGxlOyB0aGUgZXhwbGljaXQgYD8/ICcjMDAwJ2BcbiAgLy8gZmFsbGJhY2sgaXMgdW5yZWFjaGFibGUgYnV0IHNhdGlzZmllcyBgbm9VbmNoZWNrZWRJbmRleGVkQWNjZXNzYC5cbiAgY29uc3QgRkFMTEJBQ0sgPSAnIzAwMDAwMCc7XG4gIGlmICghbmFtZSkgcmV0dXJuIENPTE9SX1BBTEVUVEVbMF0gPz8gRkFMTEJBQ0s7XG4gIGxldCBoYXNoID0gNTM4MTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuYW1lLmxlbmd0aDsgaSsrKSB7XG4gICAgaGFzaCA9ICgoaGFzaCA8PCA1KSArIGhhc2ggKyBuYW1lLmNoYXJDb2RlQXQoaSkpIHwgMDtcbiAgfVxuICBjb25zdCBpZHggPSAoKGhhc2ggJSBDT0xPUl9QQUxFVFRFLmxlbmd0aCkgKyBDT0xPUl9QQUxFVFRFLmxlbmd0aCkgJSBDT0xPUl9QQUxFVFRFLmxlbmd0aDtcbiAgcmV0dXJuIENPTE9SX1BBTEVUVEVbaWR4XSA/PyBGQUxMQkFDSztcbn1cblxuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4vLyBBd2FyZW5lc3Mgc3RhdGUgc2hhcGUuXG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29sbGFiQXdhcmVuZXNzU3RhdGUge1xuICBuYW1lOiBzdHJpbmc7XG4gIGNvbG9yOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBDdXJzb3IgcG9zaXRpb24gaW4gKip3b3JsZCBjb29yZHMqKiAoY2FudmFzLWxpYiB2aWV3cG9ydCBzcGFjZSkgc28gZm9yZWlnblxuICAgKiBwZWVycyBzZWUgdGhlIHNhbWUgY29uY2VwdHVhbCBwb2ludCBldmVuIHdoZW4gdGhlaXIgbG9jYWwgdmlld3BvcnQgaXNcbiAgICogcGFubmVkL3pvb21lZCBkaWZmZXJlbnRseS4gTnVsbCA9IHBlZXIgaXMgbm90IG92ZXIgdGhlIGNhbnZhcyBzdXJmYWNlLlxuICAgKi9cbiAgY3Vyc29yOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0gfCBudWxsO1xuICAvKipcbiAgICogTW9zdC1yZWNlbnRseSBzZWxlY3RlZCBlbGVtZW50LiBgY3NzUGF0aGAgaXMgdGhlIGxvY2F0b3IgaWQgY2hhaW4gdGhlXG4gICAqIGNhbnZhcy1zaGVsbCBhbHJlYWR5IHVzZXM7IGBib3VuZHNgIGFyZSBzY3JlZW4tcHggcmVjdCBhdCB0aGUgbW9tZW50IG9mXG4gICAqIHB1Ymxpc2ggKHNvIGl0J3MgYSBoaW50LCBub3QgYSBsaXZlIHJlZikuIE51bGwgd2hlbiBub3RoaW5nIHNlbGVjdGVkLlxuICAgKi9cbiAgc2VsZWN0aW9uOiB7IGNzc1BhdGg6IHN0cmluZzsgYm91bmRzOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyOyB3OiBudW1iZXI7IGg6IG51bWJlciB9IH0gfCBudWxsO1xuICAvKipcbiAgICogQ3VycmVudGx5LXNlbGVjdGVkIGFubm90YXRpb24gc3Ryb2tlIElEcyAoUGhhc2UgNSkuIFN0cm9rZXMgYXJlIGFkZHJlc3NlZFxuICAgKiBieSB0aGVpciBzdGFibGUgYGRhdGEtaWRgIGF0dHJpYnV0ZSwgc28gcGVlcnMgY2FuIHJlc29sdmUgaGFsb3MgdmlhXG4gICAqIGBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdbZGF0YS1pZD1cIjxpZD5cIl0nKWAuIEVtcHR5IHdoZW4gbm90aGluZ1xuICAgKiBhbm5vdGF0aW9uLXNoYXBlZCBpcyBzZWxlY3RlZC5cbiAgICovXG4gIGFubm90YXRpb25TZWxlY3Rpb246IHN0cmluZ1tdO1xuICB2aWV3cG9ydDogeyB4OiBudW1iZXI7IHk6IG51bWJlcjsgem9vbTogbnVtYmVyIH07XG4gIC8qKlxuICAgKiBTZXJ2ZXItc2lkZSBgZGlzY29ubmVjdGAgbWF0Y2hlcyBhd2FyZW5lc3Mgc3RhdGVzIHRvIG91dGdvaW5nIHBlZXJzIGJ5XG4gICAqIHRoaXMgdG9rZW4gKG11c3QgZXF1YWwgdGhlIHdzLmRhdGEuaWQgdGhlIHNlcnZlciBhc3NpZ25zIGF0IHVwZ3JhZGUpLlxuICAgKiBVbnRpbCB0aGUgc2VydmVyIHB1c2hlcyB0aGUgYXNzaWduZWQgaWQgYmFjayB0byB0aGUgY2xpZW50LCB3ZSB1c2UgYVxuICAgKiBjbGllbnQtZ2VuZXJhdGVkIFVVSUQg4oCUIGNvbGxpc2lvbnMgYXJlIG5lZ2xpZ2libGUgYW5kIGRpc2Nvbm5lY3QgY2xlYW51cFxuICAgKiB0b2xlcmF0ZXMgYSBzdGFsZSBzdGF0ZSAodGhlIG5leHQgYXdhcmVuZXNzIEdDIHBhc3MgZHJvcHMgaXQpLlxuICAgKi9cbiAgX19jb25uSWQ6IHN0cmluZztcbn1cblxuZXhwb3J0IHR5cGUgRm9yZWlnbkF3YXJlbmVzcyA9IE9taXQ8Q29sbGFiQXdhcmVuZXNzU3RhdGUsICdfX2Nvbm5JZCc+ICYgeyBjbGllbnRJRDogbnVtYmVyIH07XG5cbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuLy8gVW50cnVzdGVkLWlucHV0IHNhbml0aXphdGlvbiBhdCB0aGUgYXdhcmVuZXNzIHRydXN0IGJvdW5kYXJ5LlxuLy9cbi8vIFBoYXNlIDggYXdhcmVuZXNzIHdhcyBsb29wYmFjay1vbmx5IOKAlCBldmVyeSBzdGF0ZSBjYW1lIGZyb20gYSB0cnVzdGVkIGxvY2FsXG4vLyB0YWIuIFBoYXNlIDkgKFRhc2sgNSkgYnJpZGdlcyBhd2FyZW5lc3MgdGhyb3VnaCBhIFNFTUktVFJVU1RFRCBodWIgKEREUi0wNTQpLFxuLy8gc28gZm9yZWlnbiBzdGF0ZXMgYXJlIG5vdyBhdHRhY2tlci1pbmZsdWVuY2VhYmxlLiBgdXNlRm9yZWlnbkF3YXJlbmVzc2AgaXNcbi8vIHRoZSBzaW5nbGUgY2hva2Vwb2ludCB3aGVyZSByZW1vdGUgc3RhdGUgaXMgcmVhZCBiZWZvcmUgaXQgcmVhY2hlcyB0aGVcbi8vIGN1cnNvciAvIHBhcnRpY2lwYW50IHJlbmRlciBzaW5rcywgc28gYWxsIHZhbGlkYXRpb24gbGl2ZXMgaGVyZS4gRmllbGRzIGFyZVxuLy8gdmFsaWRhdGVkIGZvciBWQUxVRSwgbm90IGp1c3QgdHlwZTpcbi8vICAgLSBjb2xvcjogcmUtZGVyaXZlZCBsb2NhbGx5IGZyb20gdGhlIChzYW5pdGl6ZWQpIG5hbWUgYW5kIHRoZSB3aXJlIHZhbHVlXG4vLyAgICAgaXMgRElTQ0FSREVEIOKAlCBhIGh1Yi1jaG9zZW4gYGNvbG9yYCBzdHJpbmcgd291bGQgb3RoZXJ3aXNlIGZsb3cgaW50byBhblxuLy8gICAgIGlubGluZSBgc3R5bGVgIGFuZCBhIGB1cmwoLi4uKWAgdmFsdWUgYmVhY29ucyBldmVyeSB2aWV3ZXIncyBicm93c2VyLlxuLy8gICAgIFRoZSBwYWxldHRlIGlzIGRldGVybWluaXN0aWMsIHNvIHJlLWRlcml2YXRpb24gaXMgdmlzdWFsbHkgaWRlbnRpY2FsLlxuLy8gICAtIG5hbWU6IGNvbnRyb2wgLyBiaWRpIC8gemVyby13aWR0aCBjaGFycyBzdHJpcHBlZCwgbGVuZ3RoLWNhcHBlZCDigJQgYmxvY2tzXG4vLyAgICAgaWRlbnRpdHkgc3Bvb2ZpbmcgKyByZW5kZXIgYmxvYXQuXG4vLyAgIC0gY3Vyc29yIC8gdmlld3BvcnQ6IGZpbml0ZS1udW1iZXIgZ2F0ZWQg4oCUIGEgTmFOL0luZmluaXR5IHdvdWxkIHBvaXNvbiB0aGVcbi8vICAgICBDU1MgdHJhbnNmb3JtIC8gdGhlIGxvY2FsIHZpZXdwb3J0IGNvbnRyb2xsZXIgZHVyaW5nIEZvbGxvdyBtb2RlLlxuLy8gICAtIHNlbGVjdGlvbi5jc3NQYXRoOiBjaGFyc2V0ICsgbGVuZ3RoIGFsbG93bGlzdCBiZWZvcmUgaXQgcmVhY2hlc1xuLy8gICAgIGBxdWVyeVNlbGVjdG9yYCDigJQgYmxvY2tzIHNlbGVjdG9yLWNvbXBsZXhpdHkgRG9TICsgYXJiaXRyYXJ5IERPTSBwcm9iaW5nLlxuLy8gICAtIGFubm90YXRpb25TZWxlY3Rpb246IHBlci1pZCB0b2tlbiArIGFycmF5LWxlbmd0aCBjYXBwZWQg4oCUIGJsb2NrcyBhXG4vLyAgICAgcXVlcnlTZWxlY3RvciByZW5kZXItc3Rvcm0uXG4vLyAgIC0gcGVlciBjb3VudCBjYXBwZWQg4oCUIGJsb2NrcyBhbiB1bmJvdW5kZWQtY2xpZW50cyBtZW1vcnkvcmVuZGVyIERvUy5cblxuY29uc3QgTUFYX0ZPUkVJR05fUEVFUlMgPSA2NDtcbmNvbnN0IE1BWF9OQU1FX0xFTiA9IDY0O1xuY29uc3QgTUFYX0NTU1BBVEhfTEVOID0gNTEyO1xuY29uc3QgTUFYX0FOTk9UQVRJT05fSURTID0gMjU2O1xuY29uc3QgTUFYX0FOTk9UQVRJT05fSURfTEVOID0gMTI4O1xuXG4vLyBDaGFyc2V0IG9mIGV2ZXJ5IHNlbGVjdG9yIHRoZSBjYW52YXMtc2hlbGwgYGNzc1BhdGgoKWAgZW1pdHNcbi8vIChgW2RhdGEtKj1cIi4uLlwiXWAsIGAjaWRgLCBgdGFnLmNsczpudGgtY2hpbGQoTilgLCBgID4gYCBjb21iaW5hdG9ycykuXG5jb25zdCBDU1NQQVRIX0FMTE9XRUQgPSAvXltBLVphLXowLTkgLl8jPjpbXFxdPVwiJygpLV0rJC87XG4vLyBgY3NzUGF0aCgpYCBvbmx5IGV2ZXIgZW1pdHMgYDpudGgtY2hpbGQoTilgIGFzIGEgcGFyZW50aGVzaXNlZCBjb25zdHJ1Y3QuXG4vLyBGdW5jdGlvbmFsIHBzZXVkby1jbGFzc2VzIChgOmhhcygpYCwgYDppcygpYCwgYDp3aGVyZSgpYCwgYDpub3QoKWApIHRyaWdnZXJcbi8vIHBlci1yZW5kZXIgc3VidHJlZSB3YWxrcyDihpIgYSBtYWxpY2lvdXMgaHViIHBlZXIgY291bGQgcHVibGlzaCBhIGRlZXBseVxuLy8gbmVzdGVkIGA6aGFzKClgIHNlbGVjdG9yIGFuZCBwaW4gZXZlcnkgdmlld2VyJ3MgbWFpbiB0aHJlYWQgKHF1ZXJ5U2VsZWN0b3Jcbi8vIHJlLXJ1bnMgZWFjaCByZW5kZXIpLiBTbyBhZnRlciBzdHJpcHBpbmcgdGhlIGxlZ2l0IGA6bnRoLWNoaWxkL29mLXR5cGUoTilgXG4vLyBmb3JtcywgYW55IHJlc2lkdWFsIHBhcmVuIG1lYW5zIGEgZnVuY3Rpb25hbCBwc2V1ZG8g4oCUIHJlamVjdC4gVGhlIGNoYXJzZXRcbi8vIGFsbG93bGlzdCBhbG9uZSB3YXMgd2lkZXIgdGhhbiB0aGUgZ2VuZXJhdG9yICh0aGUgb3JpZ2luYWwgRG9TIGhvbGUpLlxuY29uc3QgQ1NTUEFUSF9OVEggPSAvOm50aC0oY2hpbGR8b2YtdHlwZSlcXChcXGR7MSw0fVxcKS9nO1xuY29uc3QgQU5OT1RBVElPTl9JRF9BTExPV0VEID0gL15bQS1aYS16MC05Ll86LV0rJC87XG5cbmZ1bmN0aW9uIGlzU2FmZUNzc1BhdGgocDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGlmIChwLmxlbmd0aCA+IE1BWF9DU1NQQVRIX0xFTiB8fCAhQ1NTUEFUSF9BTExPV0VELnRlc3QocCkpIHJldHVybiBmYWxzZTtcbiAgY29uc3Qgc3RyaXBwZWQgPSBwLnJlcGxhY2UoQ1NTUEFUSF9OVEgsICcnKTtcbiAgcmV0dXJuICFzdHJpcHBlZC5pbmNsdWRlcygnKCcpICYmICFzdHJpcHBlZC5pbmNsdWRlcygnKScpO1xufVxuXG5mdW5jdGlvbiBpc0Zpbml0ZU51bSh2OiB1bmtub3duKTogdiBpcyBudW1iZXIge1xuICByZXR1cm4gdHlwZW9mIHYgPT09ICdudW1iZXInICYmIE51bWJlci5pc0Zpbml0ZSh2KTtcbn1cblxuLy8gQ29udHJvbCAoQzAvQzEpLCB6ZXJvLXdpZHRoLCBhbmQgYmlkaS1vdmVycmlkZSBjb2RlIHBvaW50cyBnZXQgc3RyaXBwZWQgZnJvbVxuLy8gZGlzcGxheWVkIHN0cmluZ3Mgc28gYSByZW1vdGUgcGVlciBjYW4ndCBzcG9vZiBhbm90aGVyJ3MgaWRlbnRpdHkgb3IgaGlkZVxuLy8gcGF5bG9hZHMgaW4gbGFiZWxzLiBBIGNoYXJDb2RlIHNjYW4gKG5vdCBhIHJlZ2V4IGxpdGVyYWwgd2l0aCByYXcgY29udHJvbFxuLy8gY2hhcnMpIHNpZGVzdGVwcyBiaW9tZSdzIG5vQ29udHJvbENoYXJhY3RlcnNJblJlZ2V4IHdoaWxlIGtlZXBpbmcgdGhlIHNhbWVcbi8vIHNlbWFudGljcyDigJQgc2FtZSBhcHByb2FjaCBhcyB0aGUgaHViJ3Mgc2FuaXRpemVGb3JMb2cgKEREUi0wNTMpLlxuZnVuY3Rpb24gaXNVbnNhZmVDb2RlUG9pbnQoY3A6IG51bWJlcik6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIGNwIDw9IDB4MWYgfHxcbiAgICAoY3AgPj0gMHg3ZiAmJiBjcCA8PSAweDlmKSB8fFxuICAgIChjcCA+PSAweDIwMGIgJiYgY3AgPD0gMHgyMDBmKSB8fFxuICAgIChjcCA+PSAweDIwMmEgJiYgY3AgPD0gMHgyMDJlKSB8fFxuICAgIChjcCA+PSAweDIwNjYgJiYgY3AgPD0gMHgyMDY5KSB8fFxuICAgIGNwID09PSAweGZlZmZcbiAgKTtcbn1cblxuZnVuY3Rpb24gc2FuaXRpemVOYW1lKHJhdzogdW5rbm93bik6IHN0cmluZyB7XG4gIGlmICh0eXBlb2YgcmF3ICE9PSAnc3RyaW5nJykgcmV0dXJuICdhbm9ueW1vdXMnO1xuICBsZXQgY2xlYW5lZCA9ICcnO1xuICBmb3IgKGNvbnN0IGNoIG9mIHJhdykge1xuICAgIGlmICghaXNVbnNhZmVDb2RlUG9pbnQoY2guY29kZVBvaW50QXQoMCkgPz8gMCkpIGNsZWFuZWQgKz0gY2g7XG4gIH1cbiAgY2xlYW5lZCA9IGNsZWFuZWQudHJpbSgpLnNsaWNlKDAsIE1BWF9OQU1FX0xFTik7XG4gIHJldHVybiBjbGVhbmVkIHx8ICdhbm9ueW1vdXMnO1xufVxuXG5mdW5jdGlvbiBzYW5pdGl6ZUN1cnNvcihyYXc6IHVua25vd24pOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0gfCBudWxsIHtcbiAgaWYgKCFyYXcgfHwgdHlwZW9mIHJhdyAhPT0gJ29iamVjdCcpIHJldHVybiBudWxsO1xuICBjb25zdCBjID0gcmF3IGFzIHsgeD86IHVua25vd247IHk/OiB1bmtub3duIH07XG4gIHJldHVybiBpc0Zpbml0ZU51bShjLngpICYmIGlzRmluaXRlTnVtKGMueSkgPyB7IHg6IGMueCwgeTogYy55IH0gOiBudWxsO1xufVxuXG5mdW5jdGlvbiBzYW5pdGl6ZVZpZXdwb3J0KHJhdzogdW5rbm93bik6IHsgeDogbnVtYmVyOyB5OiBudW1iZXI7IHpvb206IG51bWJlciB9IHtcbiAgY29uc3QgZmFsbGJhY2sgPSB7IHg6IDAsIHk6IDAsIHpvb206IDEgfTtcbiAgaWYgKCFyYXcgfHwgdHlwZW9mIHJhdyAhPT0gJ29iamVjdCcpIHJldHVybiBmYWxsYmFjaztcbiAgY29uc3QgdiA9IHJhdyBhcyB7IHg/OiB1bmtub3duOyB5PzogdW5rbm93bjsgem9vbT86IHVua25vd24gfTtcbiAgaWYgKCFpc0Zpbml0ZU51bSh2LngpIHx8ICFpc0Zpbml0ZU51bSh2LnkpIHx8ICFpc0Zpbml0ZU51bSh2Lnpvb20pIHx8IHYuem9vbSA8PSAwKVxuICAgIHJldHVybiBmYWxsYmFjaztcbiAgcmV0dXJuIHsgeDogdi54LCB5OiB2LnksIHpvb206IHYuem9vbSB9O1xufVxuXG5mdW5jdGlvbiBzYW5pdGl6ZVNlbGVjdGlvbihyYXc6IHVua25vd24pOiBDb2xsYWJBd2FyZW5lc3NTdGF0ZVsnc2VsZWN0aW9uJ10ge1xuICBpZiAoIXJhdyB8fCB0eXBlb2YgcmF3ICE9PSAnb2JqZWN0JykgcmV0dXJuIG51bGw7XG4gIGNvbnN0IHMgPSByYXcgYXMgeyBjc3NQYXRoPzogdW5rbm93bjsgYm91bmRzPzogdW5rbm93biB9O1xuICBjb25zdCBiID0gcy5ib3VuZHMgYXMgeyB4PzogdW5rbm93bjsgeT86IHVua25vd247IHc/OiB1bmtub3duOyBoPzogdW5rbm93biB9IHwgdW5kZWZpbmVkO1xuICBjb25zdCBib3VuZHMgPVxuICAgIGIgJiYgaXNGaW5pdGVOdW0oYi54KSAmJiBpc0Zpbml0ZU51bShiLnkpICYmIGlzRmluaXRlTnVtKGIudykgJiYgaXNGaW5pdGVOdW0oYi5oKVxuICAgICAgPyB7IHg6IGIueCwgeTogYi55LCB3OiBiLncsIGg6IGIuaCB9XG4gICAgICA6IG51bGw7XG4gIC8vIE9ubHkga2VlcCBjc3NQYXRoIGlmIGl0IG1hdGNoZXMgdGhlIGxvY2F0b3IgZ3JhbW1hciDigJQgb3RoZXJ3aXNlIGRyb3AgaXQgYW5kXG4gIC8vIGxldCB0aGUgcmVuZGVyZXIgZmFsbCBiYWNrIHRvIHRoZSAodmFsaWRhdGVkKSBib3VuZHMuXG4gIGNvbnN0IGNzc1BhdGggPSB0eXBlb2Ygcy5jc3NQYXRoID09PSAnc3RyaW5nJyAmJiBpc1NhZmVDc3NQYXRoKHMuY3NzUGF0aCkgPyBzLmNzc1BhdGggOiAnJztcbiAgaWYgKCFjc3NQYXRoICYmICFib3VuZHMpIHJldHVybiBudWxsO1xuICByZXR1cm4geyBjc3NQYXRoLCBib3VuZHM6IGJvdW5kcyA/PyB7IHg6IDAsIHk6IDAsIHc6IDAsIGg6IDAgfSB9O1xufVxuXG5mdW5jdGlvbiBzYW5pdGl6ZUFubm90YXRpb25TZWxlY3Rpb24ocmF3OiB1bmtub3duKTogc3RyaW5nW10ge1xuICBpZiAoIUFycmF5LmlzQXJyYXkocmF3KSkgcmV0dXJuIFtdO1xuICBjb25zdCBvdXQ6IHN0cmluZ1tdID0gW107XG4gIGZvciAoY29uc3QgaWQgb2YgcmF3KSB7XG4gICAgaWYgKG91dC5sZW5ndGggPj0gTUFYX0FOTk9UQVRJT05fSURTKSBicmVhaztcbiAgICBpZiAoXG4gICAgICB0eXBlb2YgaWQgPT09ICdzdHJpbmcnICYmXG4gICAgICBpZC5sZW5ndGggPD0gTUFYX0FOTk9UQVRJT05fSURfTEVOICYmXG4gICAgICBBTk5PVEFUSU9OX0lEX0FMTE9XRUQudGVzdChpZClcbiAgICApXG4gICAgICBvdXQucHVzaChpZCk7XG4gIH1cbiAgcmV0dXJuIG91dDtcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZSArIG5vcm1hbGl6ZSBvbmUgZm9yZWlnbiBhd2FyZW5lc3Mgc3RhdGUgYXQgdGhlIHRydXN0IGJvdW5kYXJ5LlxuICogUmV0dXJucyBudWxsIGZvciBzdGF0ZXMgdGhhdCBjYW4ndCBiZSBhIHBlZXIgKG5vIHVzYWJsZSBuYW1lKS4gYGNvbG9yYCBpc1xuICogYWx3YXlzIHJlLWRlcml2ZWQgbG9jYWxseSBmcm9tIHRoZSBzYW5pdGl6ZWQgbmFtZSDigJQgdGhlIHdpcmUgdmFsdWUgaXMgbmV2ZXJcbiAqIHRydXN0ZWQsIHdoaWNoIGlzIHdoYXQgY2xvc2VzIHRoZSBodWIgQ1NTLWB1cmwoKWAgZXhmaWwgY2hhbm5lbC4gRXhwb3J0ZWQgc29cbiAqIHRoZSBob3N0aWxlLWlucHV0IG1hdHJpeCBjYW4gZXhlcmNpc2UgaXQgd2l0aG91dCBhIFJlYWN0IGhhcm5lc3MuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzYW5pdGl6ZUZvcmVpZ25TdGF0ZShjbGllbnRJRDogbnVtYmVyLCBzdGF0ZTogdW5rbm93bik6IEZvcmVpZ25Bd2FyZW5lc3MgfCBudWxsIHtcbiAgaWYgKCFzdGF0ZSB8fCB0eXBlb2Ygc3RhdGUgIT09ICdvYmplY3QnKSByZXR1cm4gbnVsbDtcbiAgY29uc3QgcyA9IHN0YXRlIGFzIFBhcnRpYWw8Q29sbGFiQXdhcmVuZXNzU3RhdGU+O1xuICBpZiAodHlwZW9mIHMubmFtZSAhPT0gJ3N0cmluZycpIHJldHVybiBudWxsO1xuICBjb25zdCBuYW1lID0gc2FuaXRpemVOYW1lKHMubmFtZSk7XG4gIHJldHVybiB7XG4gICAgY2xpZW50SUQsXG4gICAgbmFtZSxcbiAgICBjb2xvcjogY29sb3JGb3JOYW1lKG5hbWUpLFxuICAgIGN1cnNvcjogc2FuaXRpemVDdXJzb3Iocy5jdXJzb3IpLFxuICAgIHNlbGVjdGlvbjogc2FuaXRpemVTZWxlY3Rpb24ocy5zZWxlY3Rpb24pLFxuICAgIGFubm90YXRpb25TZWxlY3Rpb246IHNhbml0aXplQW5ub3RhdGlvblNlbGVjdGlvbihzLmFubm90YXRpb25TZWxlY3Rpb24pLFxuICAgIHZpZXdwb3J0OiBzYW5pdGl6ZVZpZXdwb3J0KHMudmlld3BvcnQpLFxuICB9O1xufVxuXG4vLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbi8vIENvbnRleHQuXG5cbmludGVyZmFjZSBDb2xsYWJWYWx1ZSB7XG4gIGRvYzogWS5Eb2M7XG4gIC8qKlxuICAgKiBTRUNVUklUWSBJTlZBUklBTlQ6IGluIGxpbmtlZCBtb2RlIHRoaXMgQXdhcmVuZXNzIGNhcnJpZXMgc3RhdGVzIHJlbGF5ZWRcbiAgICogZnJvbSBhIFNFTUktVFJVU1RFRCBodWIgKEREUi0wNTQpLiBGb3JlaWduIHN0YXRlcyBhcmUgdW50cnVzdGVkIGlucHV0IOKAlFxuICAgKiByZWFkIHRoZW0gT05MWSB0aHJvdWdoIGB1c2VGb3JlaWduQXdhcmVuZXNzYCwgd2hpY2ggc2FuaXRpemVzIGV2ZXJ5IGZpZWxkXG4gICAqIGF0IHRoZSB0cnVzdCBib3VuZGFyeSAoYHNhbml0aXplRm9yZWlnblN0YXRlYCkuIERvIE5PVCBjYWxsXG4gICAqIGBhd2FyZW5lc3MuZ2V0U3RhdGVzKClgIGRpcmVjdGx5IGluIHJlbmRlciBjb2RlOyB0aGF0IGJ5cGFzc2VzIHRoZSBnYXRlLlxuICAgKi9cbiAgYXdhcmVuZXNzOiBBd2FyZW5lc3M7XG4gIC8qKiBMb2NhbCBwZWVyJ3Mgc2Vzc2lvbi1zdGFibGUgY29sb3IgKGRlcml2ZWQgZnJvbSBnaXQgdXNlci5uYW1lKS4gKi9cbiAgbXlDb2xvcjogc3RyaW5nO1xuICAvKiogTG9jYWwgcGVlcidzIGRpc3BsYXkgbmFtZSAoZ2l0IHVzZXIubmFtZSBvciBhbm9ueW1vdXMgZmFsbGJhY2spLiAqL1xuICBteU5hbWU6IHN0cmluZztcbiAgLyoqIExvY2FsIHBlZXIncyBjb25uZWN0aW9uIGlkIChtYXRjaGVzIHNlcnZlci1zaWRlIHdzLmRhdGEuaWQgcGF0dGVybikuICovXG4gIG15Q29ubklkOiBzdHJpbmc7XG4gIC8qKiBUcnVlIHdoZW4gdGhlIFdTIGlzIE9QRU4uIEN1cnNvciBvdmVybGF5IGNhbiB1c2UgdGhpcyB0byBnYXRlIHJlbmRlcmluZy4gKi9cbiAgY29ubmVjdGVkOiBib29sZWFuO1xuICAvKiogUHVibGlzaCAoZGVib3VuY2UtY29hbGVzY2VkKSBhbiB1cGRhdGVkIGxvY2FsIGF3YXJlbmVzcyBzdGF0ZS4gKi9cbiAgcHVibGlzaEF3YXJlbmVzczogKHBhdGNoOiBQYXJ0aWFsPE9taXQ8Q29sbGFiQXdhcmVuZXNzU3RhdGUsICdfX2Nvbm5JZCc+PikgPT4gdm9pZDtcbn1cblxuY29uc3QgQ29sbGFiQ29udGV4dCA9IGNyZWF0ZUNvbnRleHQ8Q29sbGFiVmFsdWUgfCBudWxsPihudWxsKTtcblxuZXhwb3J0IGZ1bmN0aW9uIHVzZUNvbGxhYigpOiBDb2xsYWJWYWx1ZSB8IG51bGwge1xuICByZXR1cm4gdXNlQ29udGV4dChDb2xsYWJDb250ZXh0KTtcbn1cblxuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4vLyBIb29rOiBmb3JlaWduIGF3YXJlbmVzcyBwZWVycyAodGhlIGN1cnNvciBvdmVybGF5IHN1YnNjcmliZXMgdG8gdGhpcykuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgY3VycmVudCBzZXQgb2YgZm9yZWlnbiBwZWVycyAoZXhjbHVkZXMgdGhlIGxvY2FsIGNsaWVudCkuIFRoZVxuICogcmV0dXJuZWQgYXJyYXkgaXMgc3RhYmxlLXJlZmVyZW5jZSBiZXR3ZWVuIGF3YXJlbmVzcyB1cGRhdGVzIOKAlCB1c2VmdWwgZm9yXG4gKiBkb3duc3RyZWFtIFJlYWN0Lm1lbW8gY3Vyc29yIGNvbXBvbmVudHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1c2VGb3JlaWduQXdhcmVuZXNzKCk6IEZvcmVpZ25Bd2FyZW5lc3NbXSB7XG4gIGNvbnN0IGNvbGxhYiA9IHVzZUNvbGxhYigpO1xuICBjb25zdCBbcGVlcnMsIHNldFBlZXJzXSA9IHVzZVN0YXRlPEZvcmVpZ25Bd2FyZW5lc3NbXT4oW10pO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFjb2xsYWIpIHtcbiAgICAgIHNldFBlZXJzKFtdKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgeyBhd2FyZW5lc3MgfSA9IGNvbGxhYjtcbiAgICBmdW5jdGlvbiBjb21wdXRlKCk6IEZvcmVpZ25Bd2FyZW5lc3NbXSB7XG4gICAgICBjb25zdCBvdXQ6IEZvcmVpZ25Bd2FyZW5lc3NbXSA9IFtdO1xuICAgICAgY29uc3QgbXlJZCA9IGF3YXJlbmVzcy5jbGllbnRJRDtcbiAgICAgIGZvciAoY29uc3QgW2NsaWVudElELCBzdGF0ZV0gb2YgYXdhcmVuZXNzLmdldFN0YXRlcygpIGFzIE1hcDxudW1iZXIsIHVua25vd24+KSB7XG4gICAgICAgIGlmIChjbGllbnRJRCA9PT0gbXlJZCkgY29udGludWU7XG4gICAgICAgIGlmIChvdXQubGVuZ3RoID49IE1BWF9GT1JFSUdOX1BFRVJTKSBicmVhazsgLy8gYm91bmQgRG9TIHZpYSB1bmJvdW5kZWQgcGVlcnNcbiAgICAgICAgLy8gU2FuaXRpemUgZXZlcnkgbm93LXJlbW90ZSBmaWVsZCBhdCB0aGlzIHRydXN0IGJvdW5kYXJ5IChUYXNrIDUpLlxuICAgICAgICBjb25zdCBwZWVyID0gc2FuaXRpemVGb3JlaWduU3RhdGUoY2xpZW50SUQsIHN0YXRlKTtcbiAgICAgICAgaWYgKHBlZXIpIG91dC5wdXNoKHBlZXIpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG91dDtcbiAgICB9XG4gICAgc2V0UGVlcnMoY29tcHV0ZSgpKTtcbiAgICBjb25zdCBvbkNoYW5nZSA9ICgpID0+IHNldFBlZXJzKGNvbXB1dGUoKSk7XG4gICAgYXdhcmVuZXNzLm9uKCdjaGFuZ2UnLCBvbkNoYW5nZSk7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGF3YXJlbmVzcy5vZmYoJ2NoYW5nZScsIG9uQ2hhbmdlKTtcbiAgICB9O1xuICB9LCBbY29sbGFiXSk7XG5cbiAgcmV0dXJuIHBlZXJzO1xufVxuXG4vLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbi8vIFNsdWcgZGVyaXZhdGlvbiDigJQgbXVzdCBtYXRjaCBgYXBpLmZpbGVTbHVnYCBzZXJ2ZXItc2lkZS5cblxuLyoqXG4gKiBNaXJyb3Igb2Ygc2VydmVyLXNpZGUgYGFwaS5maWxlU2x1Z2AuIFRoZSBpbnB1dCBpcyB0aGUgY2FudmFzIHBhdGggYXMgdGhlXG4gKiBzaGVsbCBzdG9yZWQgaXQgb24gYHdpbmRvdy5fX2NhbnZhc19tZXRhX2ZpbGVfX2AgKGUuZy4gYC5kZXNpZ24vdWkvRm9vLnRzeGApLlxuICogU3RyaXAgdGhlIGRlc2lnblJlbCBwcmVmaXggKHJlYWQgZnJvbSBgd2luZG93Ll9fY2FudmFzX2Rlc2lnbl9yZWxfX2AsIHNldFxuICogYnkgX3NoZWxsLmh0bWwpIHNvIGJvdGggc2lkZXMgbGFuZCBvbiB0aGUgc2FtZSBzbHVnIOKAlCB3aXRob3V0IHRoaXMgYm90aFxuICogdGFicyBvcGVuIGEgYGRlc2lnbi11aS1mb29gIHJvb20gd2hpbGUgdGhlIHNlcnZlcidzIGluc3BlY3RvciBicmlkZ2VcbiAqIHB1c2hlcyBpbnRvIGB1aS1mb29gLCBhbmQgdGhlIHJvb21zIG5ldmVyIGNvbnZlcmdlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FudmFzU2x1Z0Zyb21QYXRoKGNhbnZhc1JlbDogc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZCk6IHN0cmluZyB8IG51bGwge1xuICBpZiAoIWNhbnZhc1JlbCkgcmV0dXJuIG51bGw7XG4gIGxldCBwID0gY2FudmFzUmVsLnJlcGxhY2UoL15cXC8rfFxcLyskL2csICcnKTtcbiAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgY29uc3QgdyA9IHdpbmRvdyBhcyB1bmtub3duIGFzIHsgX19jYW52YXNfZGVzaWduX3JlbF9fPzogc3RyaW5nIH07XG4gICAgY29uc3QgZGVzaWduUmVsID0gKHcuX19jYW52YXNfZGVzaWduX3JlbF9fID8/ICcnKS5yZXBsYWNlKC9eXFwvK3xcXC8rJC9nLCAnJyk7XG4gICAgaWYgKGRlc2lnblJlbCAmJiBwLnN0YXJ0c1dpdGgoYCR7ZGVzaWduUmVsfS9gKSkgcCA9IHAuc2xpY2UoZGVzaWduUmVsLmxlbmd0aCArIDEpO1xuICB9XG4gIGNvbnN0IHNsdWcgPSBwXG4gICAgLnJlcGxhY2UoL1xcLy9nLCAnLScpXG4gICAgLnJlcGxhY2UoL1xccysvZywgJ18nKVxuICAgIC5yZXBsYWNlKC9cXC4odHN4fGh0bWwpJC9pLCAnJylcbiAgICAucmVwbGFjZSgvXlxcLisvLCAnJylcbiAgICAudG9Mb3dlckNhc2UoKTtcbiAgcmV0dXJuIC9eW2EtejAtOV8tXSskLy50ZXN0KHNsdWcpID8gc2x1ZyA6IG51bGw7XG59XG5cbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuLy8gUHJvdmlkZXIg4oCUIG9wZW5zIFdTLCBvd25zIFkuRG9jICsgQXdhcmVuZXNzIGxpZmVjeWNsZS5cblxuaW50ZXJmYWNlIENvbGxhYlByb3ZpZGVyUHJvcHMge1xuICAvKiogQ2FudmFzIHNsdWcg4oCUIG11c3QgbWF0Y2ggc2VydmVyLXNpZGUgYHBhcnNlQ29sbGFiU2x1Z2AuICovXG4gIHNsdWc6IHN0cmluZztcbiAgY2hpbGRyZW46IFJlYWN0Tm9kZTtcbn1cblxuY29uc3QgQVdBUkVORVNTX1RIUk9UVExFX01TID0gMzM7IC8vIH4zMCBIelxuXG5leHBvcnQgZnVuY3Rpb24gQ29sbGFiUHJvdmlkZXIoeyBzbHVnLCBjaGlsZHJlbiB9OiBDb2xsYWJQcm92aWRlclByb3BzKTogSlNYLkVsZW1lbnQge1xuICAvLyBZLkRvYyArIEF3YXJlbmVzcyBhcmUgcmVjcmVhdGVkIHdoZW5ldmVyIHRoZSBzbHVnIGNoYW5nZXMgKHN3aXRjaGluZ1xuICAvLyBjYW52YXNlcyB0ZWFycyBkb3duIHRoZSBwcmlvciBzZXNzaW9uIGNsZWFubHkpLiBUaGUgdXNlTWVtbyBmYWN0b3J5XG4gIC8vIGJvZGllcyBkb24ndCByZWFkIGBzbHVnYCDigJQgc2x1ZyBJUyB0aGUgY2FjaGUga2V5LCBpbnRlbnRpb25hbGx5LlxuICAvLyBiaW9tZS1pZ25vcmUgbGludC9jb3JyZWN0bmVzcy91c2VFeGhhdXN0aXZlRGVwZW5kZW5jaWVzOiBzbHVnIGlzIHRoZSBjYWNoZSBrZXlcbiAgY29uc3QgZG9jID0gdXNlTWVtbygoKSA9PiBuZXcgWS5Eb2MoKSwgW3NsdWddKTtcbiAgY29uc3QgYXdhcmVuZXNzID0gdXNlTWVtbygoKSA9PiBuZXcgQXdhcmVuZXNzKGRvYyksIFtkb2NdKTtcbiAgLy8gYmlvbWUtaWdub3JlIGxpbnQvY29ycmVjdG5lc3MvdXNlRXhoYXVzdGl2ZURlcGVuZGVuY2llczogc2x1ZyBpcyB0aGUgY2FjaGUga2V5XG4gIGNvbnN0IG15Q29ubklkID0gdXNlTWVtbygoKSA9PiBjcnlwdG8ucmFuZG9tVVVJRCgpLCBbc2x1Z10pO1xuXG4gIGNvbnN0IFtteU5hbWUsIHNldE15TmFtZV0gPSB1c2VTdGF0ZSgnYW5vbnltb3VzJyk7XG4gIGNvbnN0IFtteUNvbG9yLCBzZXRNeUNvbG9yXSA9IHVzZVN0YXRlKGNvbG9yRm9yTmFtZSgnYW5vbnltb3VzJykpO1xuICBjb25zdCBbY29ubmVjdGVkLCBzZXRDb25uZWN0ZWRdID0gdXNlU3RhdGUoZmFsc2UpO1xuXG4gIC8vIEZldGNoIGdpdCB1c2VyLm5hbWUgb25jZSBwZXIgc2x1ZzsgZmFsbHMgYmFjayB0byBhbm9ueW1vdXMtPHNob3J0IGlkPi5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBsZXQgY2FuY2VsbGVkID0gZmFsc2U7XG4gICAgZmV0Y2goJy9fYXBpL2dpdC11c2VyJylcbiAgICAgIC50aGVuKChyKSA9PiByLmpzb24oKSlcbiAgICAgIC50aGVuKChqKSA9PiB7XG4gICAgICAgIGlmIChjYW5jZWxsZWQpIHJldHVybjtcbiAgICAgICAgY29uc3QgbiA9IHR5cGVvZiBqPy5uYW1lID09PSAnc3RyaW5nJyAmJiBqLm5hbWUudHJpbSgpID8gai5uYW1lLnRyaW0oKSA6IG51bGw7XG4gICAgICAgIGNvbnN0IGZpbmFsTmFtZSA9IG4gPz8gYGFub255bW91cy0ke215Q29ubklkLnNsaWNlKDAsIDYpfWA7XG4gICAgICAgIHNldE15TmFtZShmaW5hbE5hbWUpO1xuICAgICAgICBzZXRNeUNvbG9yKGNvbG9yRm9yTmFtZShmaW5hbE5hbWUpKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKCkgPT4ge1xuICAgICAgICBpZiAoY2FuY2VsbGVkKSByZXR1cm47XG4gICAgICAgIGNvbnN0IGZhbGxiYWNrID0gYGFub255bW91cy0ke215Q29ubklkLnNsaWNlKDAsIDYpfWA7XG4gICAgICAgIHNldE15TmFtZShmYWxsYmFjayk7XG4gICAgICAgIHNldE15Q29sb3IoY29sb3JGb3JOYW1lKGZhbGxiYWNrKSk7XG4gICAgICB9KTtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgY2FuY2VsbGVkID0gdHJ1ZTtcbiAgICB9O1xuICB9LCBbbXlDb25uSWRdKTtcblxuICAvLyBTZWVkIGxvY2FsIGF3YXJlbmVzcyBzdGF0ZSBpbW1lZGlhdGVseSBzbyBmb3JlaWduIHBlZXJzIHNlZSBvdXIgbmFtZSBldmVuXG4gIC8vIGJlZm9yZSB0aGUgY3Vyc29yIG1vdmVzLiBVcGRhdGUgd2hlbiBteU5hbWUvbXlDb2xvciBzZXR0bGVzIGZyb20gdGhlIGZldGNoLlxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGF3YXJlbmVzcy5zZXRMb2NhbFN0YXRlKHtcbiAgICAgIG5hbWU6IG15TmFtZSxcbiAgICAgIGNvbG9yOiBteUNvbG9yLFxuICAgICAgY3Vyc29yOiBudWxsLFxuICAgICAgc2VsZWN0aW9uOiBudWxsLFxuICAgICAgYW5ub3RhdGlvblNlbGVjdGlvbjogW10sXG4gICAgICB2aWV3cG9ydDogeyB4OiAwLCB5OiAwLCB6b29tOiAxIH0sXG4gICAgICBfX2Nvbm5JZDogbXlDb25uSWQsXG4gICAgfSBzYXRpc2ZpZXMgQ29sbGFiQXdhcmVuZXNzU3RhdGUpO1xuICB9LCBbYXdhcmVuZXNzLCBteU5hbWUsIG15Q29sb3IsIG15Q29ubklkXSk7XG5cbiAgLy8g4pSA4pSAIFdlYlNvY2tldCBsaWZlY3ljbGUg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gIGNvbnN0IHdzUmVmID0gdXNlUmVmPFdlYlNvY2tldCB8IG51bGw+KG51bGwpO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgbGV0IGNhbmNlbGxlZCA9IGZhbHNlO1xuICAgIGxldCByZWNvbm5lY3RUaW1lcjogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD4gfCBudWxsID0gbnVsbDtcblxuICAgIGZ1bmN0aW9uIHNlbmRGcmFtZSh3czogV2ViU29ja2V0LCBwYXlsb2FkOiBVaW50OEFycmF5KSB7XG4gICAgICB0cnkge1xuICAgICAgICB3cy5zZW5kKHBheWxvYWQpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8qIGRlYWQgc29ja2V0IOKAlCBjbG9zZSBoYW5kbGVyIHdpbGwgcmVjb25uZWN0ICovXG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYnJvYWRjYXN0QXdhcmVuZXNzKHdzOiBXZWJTb2NrZXQsIGNoYW5nZWQ6IG51bWJlcltdKSB7XG4gICAgICBpZiAoY2hhbmdlZC5sZW5ndGggPT09IDApIHJldHVybjtcbiAgICAgIGNvbnN0IGVuY29kZXIgPSBlbmNvZGluZy5jcmVhdGVFbmNvZGVyKCk7XG4gICAgICBlbmNvZGluZy53cml0ZVZhclVpbnQoZW5jb2RlciwgTUVTU0FHRV9BV0FSRU5FU1MpO1xuICAgICAgZW5jb2Rpbmcud3JpdGVWYXJVaW50OEFycmF5KGVuY29kZXIsIGVuY29kZUF3YXJlbmVzc1VwZGF0ZShhd2FyZW5lc3MsIGNoYW5nZWQpKTtcbiAgICAgIHNlbmRGcmFtZSh3cywgZW5jb2RpbmcudG9VaW50OEFycmF5KGVuY29kZXIpKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBicm9hZGNhc3RTeW5jVXBkYXRlKHdzOiBXZWJTb2NrZXQsIHVwZGF0ZTogVWludDhBcnJheSkge1xuICAgICAgY29uc3QgZW5jb2RlciA9IGVuY29kaW5nLmNyZWF0ZUVuY29kZXIoKTtcbiAgICAgIGVuY29kaW5nLndyaXRlVmFyVWludChlbmNvZGVyLCBNRVNTQUdFX1NZTkMpO1xuICAgICAgd3JpdGVVcGRhdGUoZW5jb2RlciwgdXBkYXRlKTtcbiAgICAgIHNlbmRGcmFtZSh3cywgZW5jb2RpbmcudG9VaW50OEFycmF5KGVuY29kZXIpKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjb25uZWN0KCkge1xuICAgICAgaWYgKGNhbmNlbGxlZCkgcmV0dXJuO1xuICAgICAgY29uc3QgcHJvdG8gPSBsb2NhdGlvbi5wcm90b2NvbCA9PT0gJ2h0dHBzOicgPyAnd3NzOicgOiAnd3M6JztcbiAgICAgIGNvbnN0IHdzID0gbmV3IFdlYlNvY2tldChgJHtwcm90b30vLyR7bG9jYXRpb24uaG9zdH0vX3dzL2NvbGxhYi8ke3NsdWd9YCk7XG4gICAgICB3cy5iaW5hcnlUeXBlID0gJ2FycmF5YnVmZmVyJztcbiAgICAgIHdzUmVmLmN1cnJlbnQgPSB3cztcblxuICAgICAgd3MuYWRkRXZlbnRMaXN0ZW5lcignb3BlbicsICgpID0+IHtcbiAgICAgICAgc2V0Q29ubmVjdGVkKHRydWUpO1xuICAgICAgICAvLyBTeW5jIHN0ZXAgMSDigJQgYW5ub3VuY2Ugb3VyIHN0YXRlIHZlY3RvciBzbyB0aGUgc2VydmVyIGNhbiBzZW5kIHRoZVxuICAgICAgICAvLyBtaXNzaW5nIHBpZWNlcyAobWF0Y2hlcyB0aGUgZW5jb2RlSGFuZHNoYWtlIHNlcnZlciBwYXRoKS5cbiAgICAgICAgY29uc3QgZW5jb2RlciA9IGVuY29kaW5nLmNyZWF0ZUVuY29kZXIoKTtcbiAgICAgICAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KGVuY29kZXIsIE1FU1NBR0VfU1lOQyk7XG4gICAgICAgIHdyaXRlU3luY1N0ZXAxKGVuY29kZXIsIGRvYyk7XG4gICAgICAgIHNlbmRGcmFtZSh3cywgZW5jb2RpbmcudG9VaW50OEFycmF5KGVuY29kZXIpKTtcbiAgICAgICAgLy8gQXdhcmVuZXNzIGluaXRpYWwgc3RhdGUg4oCUIGZpcmUgb3VyIGxvY2FsIHN0YXRlIHRvIHRoZSByb29tLlxuICAgICAgICBicm9hZGNhc3RBd2FyZW5lc3Mod3MsIFthd2FyZW5lc3MuY2xpZW50SURdKTtcbiAgICAgIH0pO1xuXG4gICAgICB3cy5hZGRFdmVudExpc3RlbmVyKCdjbG9zZScsICgpID0+IHtcbiAgICAgICAgc2V0Q29ubmVjdGVkKGZhbHNlKTtcbiAgICAgICAgd3NSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICAgIGlmIChjYW5jZWxsZWQpIHJldHVybjtcbiAgICAgICAgcmVjb25uZWN0VGltZXIgPSBzZXRUaW1lb3V0KGNvbm5lY3QsIDEwMDApO1xuICAgICAgfSk7XG5cbiAgICAgIHdzLmFkZEV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgKCkgPT4ge1xuICAgICAgICAvLyBMZXQgY2xvc2UgaGFuZGxlciBkbyB0aGUgcmVjb25uZWN0OyBlcnJvciBldmVudHMgd2l0aG91dCBhIGNsb3NlXG4gICAgICAgIC8vIHdvdWxkIGp1c3QgcmV0cnktc3BhbS5cbiAgICAgIH0pO1xuXG4gICAgICB3cy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgKGV2dCkgPT4ge1xuICAgICAgICBjb25zdCBwYXlsb2FkID1cbiAgICAgICAgICBldnQuZGF0YSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyXG4gICAgICAgICAgICA/IG5ldyBVaW50OEFycmF5KGV2dC5kYXRhKVxuICAgICAgICAgICAgOiBldnQuZGF0YSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXlcbiAgICAgICAgICAgICAgPyBldnQuZGF0YVxuICAgICAgICAgICAgICA6IG51bGw7XG4gICAgICAgIGlmICghcGF5bG9hZCkgcmV0dXJuO1xuICAgICAgICBjb25zdCBkZWNvZGVyID0gZGVjb2RpbmcuY3JlYXRlRGVjb2RlcihwYXlsb2FkKTtcbiAgICAgICAgY29uc3QgbWVzc2FnZVR5cGUgPSBkZWNvZGluZy5yZWFkVmFyVWludChkZWNvZGVyKTtcbiAgICAgICAgc3dpdGNoIChtZXNzYWdlVHlwZSkge1xuICAgICAgICAgIGNhc2UgTUVTU0FHRV9TWU5DOiB7XG4gICAgICAgICAgICBjb25zdCBlbmNvZGVyID0gZW5jb2RpbmcuY3JlYXRlRW5jb2RlcigpO1xuICAgICAgICAgICAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KGVuY29kZXIsIE1FU1NBR0VfU1lOQyk7XG4gICAgICAgICAgICByZWFkU3luY01lc3NhZ2UoZGVjb2RlciwgZW5jb2RlciwgZG9jLCB3cyk7XG4gICAgICAgICAgICBpZiAoZW5jb2RpbmcubGVuZ3RoKGVuY29kZXIpID4gMSkgc2VuZEZyYW1lKHdzLCBlbmNvZGluZy50b1VpbnQ4QXJyYXkoZW5jb2RlcikpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgTUVTU0FHRV9BV0FSRU5FU1M6IHtcbiAgICAgICAgICAgIGFwcGx5QXdhcmVuZXNzVXBkYXRlKGF3YXJlbmVzcywgZGVjb2RpbmcucmVhZFZhclVpbnQ4QXJyYXkoZGVjb2RlciksIHdzKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIFdpcmUgZG9jIHVwZGF0ZXMg4oaSIGJyb2FkY2FzdCB0byBzZXJ2ZXIuIE9yaWdpbiB0YWdnZWQgd2l0aCB0aGUgd3MgcmVmIHNvXG4gICAgLy8gc2VydmVyLXNpZGUgdXBkYXRlcyB3ZSByZWNlaXZlIGRvbid0IGVjaG8gYmFjay5cbiAgICBjb25zdCBvbkRvY1VwZGF0ZSA9ICh1cGRhdGU6IFVpbnQ4QXJyYXksIG9yaWdpbjogdW5rbm93bikgPT4ge1xuICAgICAgY29uc3Qgd3MgPSB3c1JlZi5jdXJyZW50O1xuICAgICAgaWYgKCF3cyB8fCB3cy5yZWFkeVN0YXRlICE9PSBXZWJTb2NrZXQuT1BFTikgcmV0dXJuO1xuICAgICAgaWYgKG9yaWdpbiA9PT0gd3MpIHJldHVybjsgLy8gY2FtZSBmcm9tIHNlcnZlciwgZG9uJ3QgZWNob1xuICAgICAgYnJvYWRjYXN0U3luY1VwZGF0ZSh3cywgdXBkYXRlKTtcbiAgICB9O1xuICAgIGRvYy5vbigndXBkYXRlJywgb25Eb2NVcGRhdGUpO1xuXG4gICAgLy8gV2lyZSBhd2FyZW5lc3MgY2hhbmdlcyDihpIgYnJvYWRjYXN0LiBTYW1lIG9yaWdpbiBndWFyZC5cbiAgICBjb25zdCBvbkF3YXJlbmVzc1VwZGF0ZSA9IChcbiAgICAgIHsgYWRkZWQsIHVwZGF0ZWQsIHJlbW92ZWQgfTogeyBhZGRlZDogbnVtYmVyW107IHVwZGF0ZWQ6IG51bWJlcltdOyByZW1vdmVkOiBudW1iZXJbXSB9LFxuICAgICAgb3JpZ2luOiB1bmtub3duXG4gICAgKSA9PiB7XG4gICAgICBjb25zdCB3cyA9IHdzUmVmLmN1cnJlbnQ7XG4gICAgICBpZiAoIXdzIHx8IHdzLnJlYWR5U3RhdGUgIT09IFdlYlNvY2tldC5PUEVOKSByZXR1cm47XG4gICAgICBpZiAob3JpZ2luID09PSB3cykgcmV0dXJuO1xuICAgICAgY29uc3QgY2hhbmdlZCA9IGFkZGVkLmNvbmNhdCh1cGRhdGVkLCByZW1vdmVkKTtcbiAgICAgIGJyb2FkY2FzdEF3YXJlbmVzcyh3cywgY2hhbmdlZCk7XG4gICAgfTtcbiAgICBhd2FyZW5lc3Mub24oJ3VwZGF0ZScsIG9uQXdhcmVuZXNzVXBkYXRlKTtcblxuICAgIGNvbm5lY3QoKTtcblxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBjYW5jZWxsZWQgPSB0cnVlO1xuICAgICAgaWYgKHJlY29ubmVjdFRpbWVyKSBjbGVhclRpbWVvdXQocmVjb25uZWN0VGltZXIpO1xuICAgICAgZG9jLm9mZigndXBkYXRlJywgb25Eb2NVcGRhdGUpO1xuICAgICAgYXdhcmVuZXNzLm9mZigndXBkYXRlJywgb25Bd2FyZW5lc3NVcGRhdGUpO1xuICAgICAgY29uc3Qgd3MgPSB3c1JlZi5jdXJyZW50O1xuICAgICAgaWYgKHdzICYmIHdzLnJlYWR5U3RhdGUgPT09IFdlYlNvY2tldC5PUEVOKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgd3MuY2xvc2UoKTtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgLyogaWdub3JlICovXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIERvbid0IGRlc3Ryb3kgZG9jL2F3YXJlbmVzcyBoZXJlIOKAlCB0aGUgdXNlTWVtby10aWVkIGxpZmV0aW1lIGhhbmRsZXNcbiAgICAgIC8vIHRoYXQgd2hlbiB0aGUgc2x1ZyBjaGFuZ2VzLlxuICAgIH07XG4gIH0sIFtzbHVnLCBkb2MsIGF3YXJlbmVzc10pO1xuXG4gIC8vIFBlci1zbHVnIGNsZWFudXAgb2YgZG9jL2F3YXJlbmVzcyB3aGVuIHNsdWcgY2hhbmdlcyAob3IgcHJvdmlkZXIgdW5tb3VudHMpLlxuICB1c2VFZmZlY3QoXG4gICAgKCkgPT4gKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhcmVuZXNzLmRlc3Ryb3koKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvKiBpZ25vcmUgKi9cbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIGRvYy5kZXN0cm95KCk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLyogaWdub3JlICovXG4gICAgICB9XG4gICAgfSxcbiAgICBbZG9jLCBhd2FyZW5lc3NdXG4gICk7XG5cbiAgLy8g4pSA4pSAIFRocm90dGxlZCBhd2FyZW5lc3MgcHVibGlzaCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgY29uc3QgcGVuZGluZ1JlZiA9IHVzZVJlZjxQYXJ0aWFsPE9taXQ8Q29sbGFiQXdhcmVuZXNzU3RhdGUsICdfX2Nvbm5JZCc+PiB8IG51bGw+KG51bGwpO1xuICBjb25zdCB0aHJvdHRsZVRpbWVyUmVmID0gdXNlUmVmPFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgbnVsbD4obnVsbCk7XG5cbiAgY29uc3QgcHVibGlzaEF3YXJlbmVzcyA9IHVzZUNhbGxiYWNrKFxuICAgIChwYXRjaDogUGFydGlhbDxPbWl0PENvbGxhYkF3YXJlbmVzc1N0YXRlLCAnX19jb25uSWQnPj4pID0+IHtcbiAgICAgIHBlbmRpbmdSZWYuY3VycmVudCA9IHsgLi4uKHBlbmRpbmdSZWYuY3VycmVudCA/PyB7fSksIC4uLnBhdGNoIH07XG4gICAgICBpZiAodGhyb3R0bGVUaW1lclJlZi5jdXJyZW50KSByZXR1cm47XG4gICAgICB0aHJvdHRsZVRpbWVyUmVmLmN1cnJlbnQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhyb3R0bGVUaW1lclJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICAgICAgY29uc3QgbmV4dCA9IHBlbmRpbmdSZWYuY3VycmVudDtcbiAgICAgICAgcGVuZGluZ1JlZi5jdXJyZW50ID0gbnVsbDtcbiAgICAgICAgaWYgKCFuZXh0KSByZXR1cm47XG4gICAgICAgIGNvbnN0IGN1cnJlbnQgPSAoYXdhcmVuZXNzLmdldExvY2FsU3RhdGUoKSA/PyB7fSkgYXMgUGFydGlhbDxDb2xsYWJBd2FyZW5lc3NTdGF0ZT47XG4gICAgICAgIGF3YXJlbmVzcy5zZXRMb2NhbFN0YXRlKHtcbiAgICAgICAgICBuYW1lOiBjdXJyZW50Lm5hbWUgPz8gbXlOYW1lLFxuICAgICAgICAgIGNvbG9yOiBjdXJyZW50LmNvbG9yID8/IG15Q29sb3IsXG4gICAgICAgICAgY3Vyc29yOiBjdXJyZW50LmN1cnNvciA/PyBudWxsLFxuICAgICAgICAgIHNlbGVjdGlvbjogY3VycmVudC5zZWxlY3Rpb24gPz8gbnVsbCxcbiAgICAgICAgICBhbm5vdGF0aW9uU2VsZWN0aW9uOiBjdXJyZW50LmFubm90YXRpb25TZWxlY3Rpb24gPz8gW10sXG4gICAgICAgICAgdmlld3BvcnQ6IGN1cnJlbnQudmlld3BvcnQgPz8geyB4OiAwLCB5OiAwLCB6b29tOiAxIH0sXG4gICAgICAgICAgX19jb25uSWQ6IG15Q29ubklkLFxuICAgICAgICAgIC4uLm5leHQsXG4gICAgICAgIH0gc2F0aXNmaWVzIENvbGxhYkF3YXJlbmVzc1N0YXRlKTtcbiAgICAgIH0sIEFXQVJFTkVTU19USFJPVFRMRV9NUyk7XG4gICAgfSxcbiAgICBbYXdhcmVuZXNzLCBteU5hbWUsIG15Q29sb3IsIG15Q29ubklkXVxuICApO1xuXG4gIC8vIOKUgOKUgCBDbGVhbnVwIHRocm90dGxlIHRpbWVyIG9uIHVubW91bnQg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gIHVzZUVmZmVjdChcbiAgICAoKSA9PiAoKSA9PiB7XG4gICAgICBpZiAodGhyb3R0bGVUaW1lclJlZi5jdXJyZW50KSBjbGVhclRpbWVvdXQodGhyb3R0bGVUaW1lclJlZi5jdXJyZW50KTtcbiAgICB9LFxuICAgIFtdXG4gICk7XG5cbiAgY29uc3QgdmFsdWUgPSB1c2VNZW1vPENvbGxhYlZhbHVlPihcbiAgICAoKSA9PiAoe1xuICAgICAgZG9jLFxuICAgICAgYXdhcmVuZXNzLFxuICAgICAgbXlDb2xvcixcbiAgICAgIG15TmFtZSxcbiAgICAgIG15Q29ubklkLFxuICAgICAgY29ubmVjdGVkLFxuICAgICAgcHVibGlzaEF3YXJlbmVzcyxcbiAgICB9KSxcbiAgICBbZG9jLCBhd2FyZW5lc3MsIG15Q29sb3IsIG15TmFtZSwgbXlDb25uSWQsIGNvbm5lY3RlZCwgcHVibGlzaEF3YXJlbmVzc11cbiAgKTtcblxuICByZXR1cm4gPENvbGxhYkNvbnRleHQuUHJvdmlkZXIgdmFsdWU9e3ZhbHVlfT57Y2hpbGRyZW59PC9Db2xsYWJDb250ZXh0LlByb3ZpZGVyPjtcbn1cbiIsCiAgICAiLyoqXG4gKiBAZmlsZSAgICAgICB1c2Utc2VsZWN0aW9uLXNldC50c3gg4oCUIFBoYXNlIDQuMSBtdWx0aS1zZWxlY3Rpb24gc3RvcmVcbiAqIEBzY29wZSAgICAgIHBsdWdpbnMvZGVzaWduL2Rldi1zZXJ2ZXIvdXNlLXNlbGVjdGlvbi1zZXQudHN4XG4gKiBAcHVycG9zZSAgICBNdWx0aS1lbGVtZW50IHNlbGVjdGlvbiBzdGF0ZSBmb3IgY2FudmFzLXNoZWxsLiBUaGUgY2FudmFzXG4gKiAgICAgICAgICAgICBpbnB1dCByb3V0ZXIgY2FsbHMgYHJlcGxhY2UoKWAgLyBgYWRkKClgIC8gYGNsZWFyKClgO1xuICogICAgICAgICAgICAgdGhlIHByb3ZpZGVyIGRlYm91bmNlcyBhbmQgcG9zdHMgdXAgdG8gdGhlIGRldi1zZXJ2ZXIgc2hlbGxcbiAqICAgICAgICAgICAgIHRocm91Z2ggdGhlIGV4aXN0aW5nIGBfX2Rlc2lnbl9zZWxlY3RlZGAgd2luZG93LnBhcmVudCBjaGFubmVsXG4gKiAgICAgICAgICAgICBzbyBgX2FjdGl2ZS5qc29uYCByZWZsZWN0cyB0aGUgY3VycmVudCBzZWxlY3Rpb24gc2V0LlxuICpcbiAqIFNjaGVtYSBtaWdyYXRpb24uIGBfYWN0aXZlLmpzb24jc2VsZWN0ZWRgIGhpc3RvcmljYWxseSBob2xkc1xuICogICAgIHNlbGVjdGVkOiBTZWxlY3RlZEVsZW1lbnQgfCBudWxsXG4gKiBQaGFzZSA0LjEgd2lkZW5zIHRvXG4gKiAgICAgc2VsZWN0ZWQ6IFNlbGVjdGVkRWxlbWVudCB8IFNlbGVjdGVkRWxlbWVudFtdIHwgbnVsbFxuICogV3JpdGVyOiBlbWl0cyBhIHNpbmdsZSBvYmplY3Qgd2hlbiBOID09PSAxIChiYWNrLWNvbXBhdCB3aXRoIGRvd25zdHJlYW1cbiAqIHRvb2xzIHRoYXQgc3RpbGwgcmVhZCB0aGUgbGVnYWN5IHNoYXBlIOKAlCBgL2Rlc2lnbjplZGl0YCwgaGFuZG9mZikuIEVtaXRzIGFuXG4gKiBhcnJheSB3aGVuIE4gPiAxLiBSZWFkZXIgKHRoaXMgaG9vayBvbiByZWh5ZHJhdGUpIGFjY2VwdHMgYWxsIHRocmVlLlxuICovXG5cbmltcG9ydCB7XG4gIGNyZWF0ZUNvbnRleHQsXG4gIHR5cGUgUmVhY3ROb2RlLFxuICB1c2VDYWxsYmFjayxcbiAgdXNlQ29udGV4dCxcbiAgdXNlRWZmZWN0LFxuICB1c2VNZW1vLFxuICB1c2VSZWYsXG4gIHVzZVN0YXRlLFxufSBmcm9tICdyZWFjdCc7XG5cbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuLy8gVHlwZXNcblxuLyoqXG4gKiBNaW5pbWFsIFNlbGVjdGlvbiBzaGFwZSB0aGF0IHRyYXZlbHMgdGhyb3VnaCB0aGUgcGFyZW50IHBvc3RNZXNzYWdlIGNoYW5uZWwuXG4gKiBNaXJyb3JzIGBTZWxlY3RlZEVsZW1lbnRgIGZyb20gaW5zcGVjdC50cyBidXQgdGhlIGNhbnZhcyByb3V0ZXIgY29tcHV0ZXMgaXRcbiAqIGNsaWVudC1zaWRlIGFuZCB0aGUgaW5zcGVjdG9yIG92ZXJsYXkncyBlbnJpY2htZW50IGZpZWxkcyAoaHRtbCBleGNlcnB0LFxuICogZG9tX3BhdGgsIGNsYXNzZXMuLi4pIGFyZSBmaWxsZWQgaW4gYnkgdGhlIHJvdXRlciByaWdodCBiZWZvcmUgdGhlIG1lc3NhZ2VcbiAqIGlzIHBvc3RlZC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTZWxlY3Rpb24ge1xuICAvKiogQ2FudmFzIGZpbGUgcGF0aCDigJQgZGVzaWduUmVsLXByZWZpeGVkIChlLmcuIGAuZGVzaWduL3VpL0Zvby50c3hgKS4gKi9cbiAgZmlsZT86IHN0cmluZztcbiAgLyoqIFN0YWJsZSBgZGF0YS1jZC1pZGAgYW5jaG9yIHdoZW4gcHJlc2VudC4gdjItZ3JhZGUgb25seS4gKi9cbiAgaWQ/OiBzdHJpbmc7XG4gIC8qKiBDU1Mtc2VsZWN0b3IgZmFsbGJhY2sgcGF0aCAoYWx3YXlzIHByZXNlbnQpLiAqL1xuICBzZWxlY3Rvcjogc3RyaW5nO1xuICAvKiogQXJ0Ym9hcmQgaG9zdCAoYGRhdGEtZGMtc2NyZWVuYCkg4oCUIGZvciBzY29waW5nIG11bHRpLWVkaXRzIGluIGZ1dHVyZS4gKi9cbiAgYXJ0Ym9hcmRJZD86IHN0cmluZyB8IG51bGw7XG4gIC8qKiBTbmFwc2hvdCBmaWVsZHMgZmlsbGVkIGJ5IHRoZSByb3V0ZXIgZnJvbSBgcmVzb2x2ZUhvdmVyVGFyZ2V0YC4gKi9cbiAgdGFnPzogc3RyaW5nO1xuICBjbGFzc2VzPzogc3RyaW5nO1xuICB0ZXh0Pzogc3RyaW5nO1xuICBkb21fcGF0aD86IHN0cmluZ1tdO1xuICBib3VuZHM/OiB7IHg6IG51bWJlcjsgeTogbnVtYmVyOyB3OiBudW1iZXI7IGg6IG51bWJlciB9IHwgbnVsbDtcbiAgaHRtbD86IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIFNlbGVjdGlvblNldFZhbHVlIHtcbiAgc2VsZWN0ZWQ6IFNlbGVjdGlvbltdO1xuICByZXBsYWNlOiAoczogU2VsZWN0aW9uIHwgU2VsZWN0aW9uW10pID0+IHZvaWQ7XG4gIGFkZDogKHM6IFNlbGVjdGlvbiB8IFNlbGVjdGlvbltdKSA9PiB2b2lkO1xuICByZW1vdmU6IChzOiBTZWxlY3Rpb24pID0+IHZvaWQ7XG4gIHRvZ2dsZTogKHM6IFNlbGVjdGlvbikgPT4gdm9pZDtcbiAgY2xlYXI6ICgpID0+IHZvaWQ7XG59XG5cbmNvbnN0IFNlbGVjdGlvblNldENvbnRleHQgPSBjcmVhdGVDb250ZXh0PFNlbGVjdGlvblNldFZhbHVlIHwgbnVsbD4obnVsbCk7XG5cbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuLy8gSWRlbnRpdHkuIFByZWZlciBgaWRgIChkYXRhLWNkLWlkIHN0YWJsZSBhbmNob3IpOyBmYWxsIGJhY2sgdG8gc2VsZWN0b3IuXG5cbmZ1bmN0aW9uIHNlbGVjdGlvbktleShzOiBTZWxlY3Rpb24pOiBzdHJpbmcge1xuICByZXR1cm4gcy5pZCA/IGBpZDoke3MuaWR9YCA6IGBzZWw6JHtzLnNlbGVjdG9yfWA7XG59XG5cbmZ1bmN0aW9uIGRlZHVwZShsaXN0OiBTZWxlY3Rpb25bXSk6IFNlbGVjdGlvbltdIHtcbiAgY29uc3Qgb3V0OiBTZWxlY3Rpb25bXSA9IFtdO1xuICBjb25zdCBzZWVuID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIGZvciAoY29uc3QgcyBvZiBsaXN0KSB7XG4gICAgY29uc3QgayA9IHNlbGVjdGlvbktleShzKTtcbiAgICBpZiAoc2Vlbi5oYXMoaykpIGNvbnRpbnVlO1xuICAgIHNlZW4uYWRkKGspO1xuICAgIG91dC5wdXNoKHMpO1xuICB9XG4gIHJldHVybiBvdXQ7XG59XG5cbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuLy8gUHJvdmlkZXJcblxuY29uc3QgUE9TVF9ERUJPVU5DRV9NUyA9IDUwOyAvLyBtaXJyb3JzIGNhbnZhcy1saWIncyBTRVRUTEUvUFVCTElTSCBjYWRlbmNlXG5cbmV4cG9ydCBmdW5jdGlvbiBTZWxlY3Rpb25TZXRQcm92aWRlcih7XG4gIGNoaWxkcmVuLFxuICAvKiogT3ZlcnJpZGUgdGhlIHBvc3RNZXNzYWdlIGRlc3RpbmF0aW9uICh1c2VkIGluIHRlc3RzKS4gKi9cbiAgcG9zdFRhcmdldCxcbn06IHtcbiAgY2hpbGRyZW46IFJlYWN0Tm9kZTtcbiAgcG9zdFRhcmdldD86IHsgcG9zdE1lc3NhZ2U6IChtc2c6IHVua25vd24sIHRhcmdldE9yaWdpbjogc3RyaW5nKSA9PiB2b2lkIH0gfCBudWxsO1xufSkge1xuICBjb25zdCBbc2VsZWN0ZWQsIHNldFNlbGVjdGVkXSA9IHVzZVN0YXRlPFNlbGVjdGlvbltdPihbXSk7XG4gIGNvbnN0IHRpbWVyUmVmID0gdXNlUmVmPFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgbnVsbD4obnVsbCk7XG5cbiAgY29uc3QgcG9zdCA9IHVzZUNhbGxiYWNrKFxuICAgIChuZXh0OiBTZWxlY3Rpb25bXSkgPT4ge1xuICAgICAgaWYgKHRpbWVyUmVmLmN1cnJlbnQpIGNsZWFyVGltZW91dCh0aW1lclJlZi5jdXJyZW50KTtcbiAgICAgIHRpbWVyUmVmLmN1cnJlbnQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGltZXJSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICAgIGNvbnN0IHRhcmdldCA9IHBvc3RUYXJnZXQgPz8gKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93LnBhcmVudCA6IG51bGwpO1xuICAgICAgICBpZiAoIXRhcmdldCkgcmV0dXJuO1xuICAgICAgICAvLyBXaXJlIHNoYXBlOiBzaW5nbGUgb2JqZWN0IGZvciBOPTEgKGJhY2stY29tcGF0KSwgYXJyYXkgZm9yIE4+MSwgbnVsbCBmb3IgZW1wdHkuXG4gICAgICAgIGNvbnN0IHBheWxvYWQ6IFNlbGVjdGlvbiB8IFNlbGVjdGlvbltdIHwgbnVsbCA9XG4gICAgICAgICAgbmV4dC5sZW5ndGggPT09IDAgPyBudWxsIDogbmV4dC5sZW5ndGggPT09IDEgPyAobmV4dFswXSA/PyBudWxsKSA6IG5leHQ7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdGFyZ2V0LnBvc3RNZXNzYWdlKHsgZGduOiAnc2VsZWN0LXNldCcsIHNlbGVjdGlvbjogcGF5bG9hZCB9LCAnKicpO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAvKiBpZnJhbWUgbGlrZWx5IGNyb3NzLW9yaWdpbiBvciBkZXRhY2hlZCAqL1xuICAgICAgICB9XG4gICAgICB9LCBQT1NUX0RFQk9VTkNFX01TKTtcbiAgICB9LFxuICAgIFtwb3N0VGFyZ2V0XVxuICApO1xuXG4gIC8vIENsZWFudXAgdGhlIGRlYm91bmNlIHRpbWVyIG9uIHVubW91bnQuXG4gIHVzZUVmZmVjdChcbiAgICAoKSA9PiAoKSA9PiB7XG4gICAgICBpZiAodGltZXJSZWYuY3VycmVudCkgY2xlYXJUaW1lb3V0KHRpbWVyUmVmLmN1cnJlbnQpO1xuICAgIH0sXG4gICAgW11cbiAgKTtcblxuICBjb25zdCByZXBsYWNlID0gdXNlQ2FsbGJhY2soXG4gICAgKHM6IFNlbGVjdGlvbiB8IFNlbGVjdGlvbltdKSA9PiB7XG4gICAgICBjb25zdCBuZXh0ID0gZGVkdXBlKEFycmF5LmlzQXJyYXkocykgPyBzIDogW3NdKTtcbiAgICAgIHNldFNlbGVjdGVkKG5leHQpO1xuICAgICAgcG9zdChuZXh0KTtcbiAgICB9LFxuICAgIFtwb3N0XVxuICApO1xuXG4gIGNvbnN0IGFkZCA9IHVzZUNhbGxiYWNrKFxuICAgIChzOiBTZWxlY3Rpb24gfCBTZWxlY3Rpb25bXSkgPT4ge1xuICAgICAgY29uc3QgaW5jb21pbmcgPSBBcnJheS5pc0FycmF5KHMpID8gcyA6IFtzXTtcbiAgICAgIHNldFNlbGVjdGVkKChwcmV2KSA9PiB7XG4gICAgICAgIGNvbnN0IG5leHQgPSBkZWR1cGUoWy4uLnByZXYsIC4uLmluY29taW5nXSk7XG4gICAgICAgIHBvc3QobmV4dCk7XG4gICAgICAgIHJldHVybiBuZXh0O1xuICAgICAgfSk7XG4gICAgfSxcbiAgICBbcG9zdF1cbiAgKTtcblxuICBjb25zdCByZW1vdmUgPSB1c2VDYWxsYmFjayhcbiAgICAoczogU2VsZWN0aW9uKSA9PiB7XG4gICAgICBjb25zdCBrID0gc2VsZWN0aW9uS2V5KHMpO1xuICAgICAgc2V0U2VsZWN0ZWQoKHByZXYpID0+IHtcbiAgICAgICAgY29uc3QgbmV4dCA9IHByZXYuZmlsdGVyKCh4KSA9PiBzZWxlY3Rpb25LZXkoeCkgIT09IGspO1xuICAgICAgICBwb3N0KG5leHQpO1xuICAgICAgICByZXR1cm4gbmV4dDtcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgW3Bvc3RdXG4gICk7XG5cbiAgY29uc3QgdG9nZ2xlID0gdXNlQ2FsbGJhY2soXG4gICAgKHM6IFNlbGVjdGlvbikgPT4ge1xuICAgICAgY29uc3QgayA9IHNlbGVjdGlvbktleShzKTtcbiAgICAgIHNldFNlbGVjdGVkKChwcmV2KSA9PiB7XG4gICAgICAgIGNvbnN0IG5leHQgPSBwcmV2LnNvbWUoKHgpID0+IHNlbGVjdGlvbktleSh4KSA9PT0gaylcbiAgICAgICAgICA/IHByZXYuZmlsdGVyKCh4KSA9PiBzZWxlY3Rpb25LZXkoeCkgIT09IGspXG4gICAgICAgICAgOiBbLi4ucHJldiwgc107XG4gICAgICAgIHBvc3QobmV4dCk7XG4gICAgICAgIHJldHVybiBuZXh0O1xuICAgICAgfSk7XG4gICAgfSxcbiAgICBbcG9zdF1cbiAgKTtcblxuICBjb25zdCBjbGVhciA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBzZXRTZWxlY3RlZChbXSk7XG4gICAgcG9zdChbXSk7XG4gIH0sIFtwb3N0XSk7XG5cbiAgY29uc3QgdmFsdWUgPSB1c2VNZW1vPFNlbGVjdGlvblNldFZhbHVlPihcbiAgICAoKSA9PiAoeyBzZWxlY3RlZCwgcmVwbGFjZSwgYWRkLCByZW1vdmUsIHRvZ2dsZSwgY2xlYXIgfSksXG4gICAgW3NlbGVjdGVkLCByZXBsYWNlLCBhZGQsIHJlbW92ZSwgdG9nZ2xlLCBjbGVhcl1cbiAgKTtcblxuICByZXR1cm4gPFNlbGVjdGlvblNldENvbnRleHQuUHJvdmlkZXIgdmFsdWU9e3ZhbHVlfT57Y2hpbGRyZW59PC9TZWxlY3Rpb25TZXRDb250ZXh0LlByb3ZpZGVyPjtcbn1cblxuLyoqXG4gKiBNb3VudCBhIGBTZWxlY3Rpb25TZXRQcm92aWRlcmAgb25seSB3aGVuIG5vbmUgZXhpc3RzIGFib3ZlIHVzLiBUaGUgc2hlbGwtXG4gKiBvd25lZCBjb21tZW50IG1vdW50IGxheWVyIHByb3ZpZGVzIG9uZSBzbyBib3RoIHRoZSBsaXRlIGNvbW1lbnQgcm91dGVyIGFuZFxuICogYENhbnZhc1NoZWxsYCBzaGFyZSBhIHNpbmdsZSBzZWxlY3Rpb24gc2V0LiBIb29rIGNhbGxlZCB1bmNvbmRpdGlvbmFsbHk7XG4gKiBvbmx5IHRoZSByZXR1cm5lZCB0cmVlIGJyYW5jaGVzIChob29rIHJ1bGVzKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIE1heWJlU2VsZWN0aW9uU2V0UHJvdmlkZXIoeyBjaGlsZHJlbiB9OiB7IGNoaWxkcmVuOiBSZWFjdE5vZGUgfSkge1xuICBjb25zdCBvdXRlciA9IHVzZUNvbnRleHQoU2VsZWN0aW9uU2V0Q29udGV4dCk7XG4gIGlmIChvdXRlcikgcmV0dXJuIDw+e2NoaWxkcmVufTwvPjtcbiAgcmV0dXJuIDxTZWxlY3Rpb25TZXRQcm92aWRlcj57Y2hpbGRyZW59PC9TZWxlY3Rpb25TZXRQcm92aWRlcj47XG59XG5cbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuLy8gSG9va3NcblxuZXhwb3J0IGZ1bmN0aW9uIHVzZVNlbGVjdGlvblNldCgpOiBTZWxlY3Rpb25TZXRWYWx1ZSB7XG4gIGNvbnN0IGN0eCA9IHVzZUNvbnRleHQoU2VsZWN0aW9uU2V0Q29udGV4dCk7XG4gIGlmICghY3R4KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1c2VTZWxlY3Rpb25TZXQgbXVzdCBiZSB1c2VkIGluc2lkZSA8U2VsZWN0aW9uU2V0UHJvdmlkZXI+Jyk7XG4gIH1cbiAgcmV0dXJuIGN0eDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVzZVNlbGVjdGlvblNldE9wdGlvbmFsKCk6IFNlbGVjdGlvblNldFZhbHVlIHwgbnVsbCB7XG4gIHJldHVybiB1c2VDb250ZXh0KFNlbGVjdGlvblNldENvbnRleHQpO1xufVxuXG4vLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbi8vIFdpcmUtc2hhcGUgaGVscGVycyDigJQgZXhwb3J0ZWQgZm9yIHRlc3RzIGFuZCBpbnNwZWN0LnRzIGJhY2stY29tcGF0IHJlYWRlci5cblxuLyoqIENvbnZlcnQgYW55IGluYm91bmQgc2hhcGUgdG8gYW4gYXJyYXkuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplU2VsZWN0ZWRSZWFkKFxuICByYXc6IFNlbGVjdGlvbiB8IFNlbGVjdGlvbltdIHwgbnVsbCB8IHVuZGVmaW5lZFxuKTogU2VsZWN0aW9uW10ge1xuICBpZiAocmF3ID09IG51bGwpIHJldHVybiBbXTtcbiAgaWYgKEFycmF5LmlzQXJyYXkocmF3KSkgcmV0dXJuIGRlZHVwZShyYXcpO1xuICByZXR1cm4gW3Jhd107XG59XG5cbi8qKiBDb252ZXJ0IGludGVybmFsIGFycmF5IGJhY2sgdG8gdGhlIHdpcmUgc2hhcGUgKHdyaXRlcikuICovXG5leHBvcnQgZnVuY3Rpb24gZGVub3JtYWxpemVTZWxlY3RlZFdyaXRlKGxpc3Q6IFNlbGVjdGlvbltdKTogU2VsZWN0aW9uIHwgU2VsZWN0aW9uW10gfCBudWxsIHtcbiAgaWYgKGxpc3QubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcbiAgaWYgKGxpc3QubGVuZ3RoID09PSAxKSByZXR1cm4gbGlzdFswXSA/PyBudWxsO1xuICByZXR1cm4gbGlzdDtcbn1cbiIsCiAgICAiLyoqXG4gKiBAZmlsZSAgICAgICBkb20tc2VsZWN0aW9uLnRzIOKAlCBzZWxlY3Rpb24tZnJvbS1ET00gaGVscGVycyAobGVhZiBtb2R1bGUpXG4gKiBAc2NvcGUgICAgICBwbHVnaW5zL2Rlc2lnbi9kZXYtc2VydmVyL2RvbS1zZWxlY3Rpb24udHNcbiAqIEBwdXJwb3NlICAgIFB1cmUgRE9NIOKGkiBTZWxlY3Rpb24gYnVpbGRlcnMgc2hhcmVkIGJ5IHRoZSBjYW52YXMgY2hyb21lXG4gKiAgICAgICAgICAgICAoY2FudmFzLXNoZWxsLnRzeCkgYW5kIHRoZSBzaGVsbC1vd25lZCBjb21tZW50IG1vdW50IGxheWVyXG4gKiAgICAgICAgICAgICAoY2FudmFzLWNvbW1lbnQtbW91bnQudHN4KS4gTGl2ZXMgaW4gaXRzIG93biBsZWFmIG1vZHVsZSDigJQgbm9cbiAqICAgICAgICAgICAgIFJlYWN0LCBubyBjYW52YXMtbGliIGltcG9ydCDigJQgc28gYm90aCBjb25zdW1lcnMgY2FuIGxpZnQgdGhlXG4gKiAgICAgICAgICAgICBzYW1lIGBob3ZlclRhcmdldFRvU2VsZWN0aW9uYCAvIGBkZXJpdmVGaWxlYCBsb2dpYyB3aXRob3V0IGFcbiAqICAgICAgICAgICAgIGN5Y2xlIGFuZCB3aXRob3V0IGJ1bmRsaW5nIHRoZSBoZWF2eSBEZXNpZ25DYW52YXMgdHJlZSBpbnRvIHRoZVxuICogICAgICAgICAgICAgbGl0ZSBjb21tZW50IG1vdW50LlxuICovXG5cbmltcG9ydCB0eXBlIHsgSG92ZXJUYXJnZXQgfSBmcm9tICcuL2lucHV0LXJvdXRlci50c3gnO1xuaW1wb3J0IHR5cGUgeyBTZWxlY3Rpb24gfSBmcm9tICcuL3VzZS1zZWxlY3Rpb24tc2V0LnRzeCc7XG5cbi8qKlxuICogQ2FudmFzIGZpbGUgcGF0aCBmb3IgdGhlIGN1cnJlbnQgcGFnZS4gVW5kZXIgdGhlIG1vdW50IGhhcm5lc3MgdGhlIHBhZ2UgaXNcbiAqIGAvX2NhbnZhcy1zaGVsbC5odG1sP2NhbnZhcz08cmVsPiZkZXNpZ25SZWw9PHJvb3Q+YDsgZm9yIGxlZ2FjeSBgLmh0bWxgXG4gKiBtb2NrcyBpdCdzIHRoZSBzZXJ2ZWQgZmlsZSBwYXRoIGl0c2VsZi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlcml2ZUZpbGUoKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgaWYgKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSByZXR1cm4gdW5kZWZpbmVkO1xuICB0cnkge1xuICAgIGNvbnN0IHAgPSB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWU7XG4gICAgaWYgKHAgPT09ICcvX2NhbnZhcy1zaGVsbC5odG1sJyB8fCBwID09PSAnL19jYW52YXMtc2hlbGwnKSB7XG4gICAgICBjb25zdCBxcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMod2luZG93LmxvY2F0aW9uLnNlYXJjaCk7XG4gICAgICBjb25zdCBjYW52YXMgPSBxcy5nZXQoJ2NhbnZhcycpID8/ICcnO1xuICAgICAgY29uc3QgZGVzaWduUmVsID0gKHFzLmdldCgnZGVzaWduUmVsJykgPz8gJy5kZXNpZ24nKS5yZXBsYWNlKC9eXFwvK3xcXC8rJC9nLCAnJyk7XG4gICAgICByZXR1cm4gY2FudmFzID8gYCR7ZGVzaWduUmVsfS8ke2NhbnZhc31gIDogdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KHApLnJlcGxhY2UoL15cXC8vLCAnJyk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlYWxDbGFzc2VzKGVsOiBFbGVtZW50IHwgbnVsbCk6IHN0cmluZyB7XG4gIGlmICghZWwpIHJldHVybiAnJztcbiAgcmV0dXJuIChlbC5nZXRBdHRyaWJ1dGUoJ2NsYXNzJykgPz8gJycpXG4gICAgLnRyaW0oKVxuICAgIC5zcGxpdCgvXFxzKy8pXG4gICAgLmZpbHRlcigoYykgPT4gYyAmJiAhYy5zdGFydHNXaXRoKCdkZ24tJykgJiYgIWMuc3RhcnRzV2l0aCgnZGMtY3YtJykpXG4gICAgLmpvaW4oJyAnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNob3J0VGV4dChlbDogRWxlbWVudCB8IG51bGwsIG1heDogbnVtYmVyKTogc3RyaW5nIHtcbiAgaWYgKCFlbCkgcmV0dXJuICcnO1xuICBjb25zdCB0ID0gKChlbCBhcyBIVE1MRWxlbWVudCkuaW5uZXJUZXh0IHx8IGVsLnRleHRDb250ZW50IHx8ICcnKS5yZXBsYWNlKC9cXHMrL2csICcgJykudHJpbSgpO1xuICByZXR1cm4gdC5sZW5ndGggPiBtYXggPyBgJHt0LnNsaWNlKDAsIG1heCAtIDEpfeKApmAgOiB0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3NzUGF0aChlbDogRWxlbWVudCB8IG51bGwpOiBzdHJpbmcge1xuICBpZiAoIWVsKSByZXR1cm4gJyc7XG4gIGNvbnN0IHBhdGg6IHN0cmluZ1tdID0gW107XG4gIGxldCBjdXI6IEVsZW1lbnQgfCBudWxsID0gZWw7XG4gIHdoaWxlIChjdXIgJiYgY3VyLm5vZGVUeXBlID09PSAxICYmIHBhdGgubGVuZ3RoIDwgOCkge1xuICAgIGNvbnN0IGRzY0VsID0gY3VyLmdldEF0dHJpYnV0ZT8uKCdkYXRhLWRjLWVsZW1lbnQnKTtcbiAgICBpZiAoZHNjRWwpIHtcbiAgICAgIHBhdGgudW5zaGlmdChgW2RhdGEtZGMtZWxlbWVudD1cIiR7ZHNjRWx9XCJdYCk7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgY29uc3QgZHNjU2MgPSBjdXIuZ2V0QXR0cmlidXRlPy4oJ2RhdGEtZGMtc2NyZWVuJyk7XG4gICAgaWYgKGRzY1NjKSB7XG4gICAgICBwYXRoLnVuc2hpZnQoYFtkYXRhLWRjLXNjcmVlbj1cIiR7ZHNjU2N9XCJdYCk7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgbGV0IHNlbCA9IGN1ci5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgIGlmIChjdXIuaWQpIHtcbiAgICAgIHNlbCA9IGAjJHtjdXIuaWR9YDtcbiAgICAgIHBhdGgudW5zaGlmdChzZWwpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGNvbnN0IGNscyA9IHJlYWxDbGFzc2VzKGN1cikuc3BsaXQoL1xccysvKS5maWx0ZXIoQm9vbGVhbikuc2xpY2UoMCwgMik7XG4gICAgaWYgKGNscy5sZW5ndGgpIHNlbCArPSBgLiR7Y2xzLmpvaW4oJy4nKX1gO1xuICAgIGxldCBzaWIgPSAxO1xuICAgIGxldCBuOiBFbGVtZW50IHwgbnVsbCA9IGN1ci5wcmV2aW91c0VsZW1lbnRTaWJsaW5nO1xuICAgIHdoaWxlIChuKSB7XG4gICAgICBzaWIrKztcbiAgICAgIG4gPSBuLnByZXZpb3VzRWxlbWVudFNpYmxpbmc7XG4gICAgfVxuICAgIHNlbCArPSBgOm50aC1jaGlsZCgke3NpYn0pYDtcbiAgICBwYXRoLnVuc2hpZnQoc2VsKTtcbiAgICBjdXIgPSBjdXIucGFyZW50RWxlbWVudDtcbiAgfVxuICByZXR1cm4gcGF0aC5qb2luKCcgPiAnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRvbVBhdGgoZWw6IEVsZW1lbnQgfCBudWxsKTogc3RyaW5nW10ge1xuICBjb25zdCBob3BzOiBzdHJpbmdbXSA9IFtdO1xuICBsZXQgY3VyID0gZWw7XG4gIHdoaWxlIChjdXIgJiYgY3VyLm5vZGVUeXBlID09PSAxICYmIGhvcHMubGVuZ3RoIDwgOCkge1xuICAgIGxldCBsYWJlbCA9IGN1ci5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgIGNvbnN0IGRFbCA9IGN1ci5nZXRBdHRyaWJ1dGU/LignZGF0YS1kYy1lbGVtZW50Jyk7XG4gICAgY29uc3QgZFNjID0gY3VyLmdldEF0dHJpYnV0ZT8uKCdkYXRhLWRjLXNjcmVlbicpO1xuICAgIGlmIChkRWwpIGxhYmVsICs9IGBbZGF0YS1kYy1lbGVtZW50PVwiJHtkRWx9XCJdYDtcbiAgICBlbHNlIGlmIChkU2MpIGxhYmVsICs9IGBbZGF0YS1kYy1zY3JlZW49XCIke2RTY31cIl1gO1xuICAgIGVsc2UgaWYgKGN1ci5pZCkgbGFiZWwgKz0gYCMke2N1ci5pZH1gO1xuICAgIGNvbnN0IGNscyA9IHJlYWxDbGFzc2VzKGN1cikuc3BsaXQoL1xccysvKS5maWx0ZXIoQm9vbGVhbikuc2xpY2UoMCwgMik7XG4gICAgaWYgKGNscy5sZW5ndGggJiYgIWRFbCAmJiAhZFNjKSBsYWJlbCArPSBgLiR7Y2xzLmpvaW4oJy4nKX1gO1xuICAgIGhvcHMudW5zaGlmdChsYWJlbCk7XG4gICAgY3VyID0gY3VyLnBhcmVudEVsZW1lbnQ7XG4gIH1cbiAgcmV0dXJuIGhvcHM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjc3NFc2NhcGUoczogc3RyaW5nKTogc3RyaW5nIHtcbiAgLy8gTWluaW1hbCBDU1MuZXNjYXBlIHBvbHlmaWxsIOKAlCBvbmx5IGhhbmRsZXMgY2hhcnMgYWN0dWFsbHkgcHJlc2VudCBpblxuICAvLyBwaXBlbGluZS1zdGFtcGVkIElEcyAoYWxwaGFudW1lcmljcyArIGAtYCArIGBfYCkuXG4gIHJldHVybiBzLnJlcGxhY2UoL1teYS16QS1aMC05Xy1dL2csIChjKSA9PiBgXFxcXCR7Y31gKTtcbn1cblxuLyoqXG4gKiBCdWlsZCB0aGUgd2lyZS1zaGFwZSBgU2VsZWN0aW9uYCBmb3IgYSByZXNvbHZlZCBob3ZlciB0YXJnZXQuIGBmaWxlYFxuICogZGVmYXVsdHMgdG8gYGRlcml2ZUZpbGUoKWA7IHRoZSBjb21tZW50IG1vdW50IGxheWVyIHBhc3NlcyBpdCBleHBsaWNpdGx5XG4gKiBzbyBhbGwgdGhyZWUgY29uc3VtZXJzIChyb3V0ZXIsIG92ZXJsYXksIG1vdW50KSBhZ3JlZSBvbiB0aGUgc2FtZSBrZXkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBob3ZlclRhcmdldFRvU2VsZWN0aW9uKHRhcmdldDogSG92ZXJUYXJnZXQsIGZpbGU/OiBzdHJpbmcpOiBTZWxlY3Rpb24ge1xuICBjb25zdCBlbCA9IHRhcmdldC5lbDtcbiAgY29uc3QgcmVjdCA9XG4gICAgZWwgJiYgKGVsIGFzIEhUTUxFbGVtZW50KS5nZXRCb3VuZGluZ0NsaWVudFJlY3RcbiAgICAgID8gKGVsIGFzIEhUTUxFbGVtZW50KS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgICAgOiBudWxsO1xuICAvLyBgY2RJZGAgaXMgdGhlIGhpdCBlbGVtZW50J3MgT1dOIGRhdGEtY2QtaWQgKGRlZXAgbW9kZSk7IHJlc29sdmVyIG5ldmVyXG4gIC8vIGNsaW1icyB0byBhbiBhbmNlc3Rvci4gRmFsbHMgYmFjayB0byBjc3NQYXRoIG9mIHRoZSBoaXQgd2hlbiBubyBzdGFibGVcbiAgLy8gYW5jaG9yIGV4aXN0cy5cbiAgY29uc3QgY2RJZCA9IHRhcmdldC5jZElkO1xuICAvLyBTZWxlY3RvciByZXNvbHV0aW9uIG9yZGVyOlxuICAvLyAgIDEuIGRhdGEtY2QtaWQgYW5jaG9yIOKAlCBzdGFibGUgcGlwZWxpbmUtc3RhbXBlZCBpZCAocHJlZmVycmVkKS5cbiAgLy8gICAyLiBkYXRhLWRjLXNjcmVlbiDigJQgY2hyb21lIGNsaWNrIHByb21vdGVkIHRvIHdob2xlLWFydGJvYXJkIHNlbGVjdFxuICAvLyAgICAgIChUMjQuNSBHOCBtdWx0aS1hcnRib2FyZCBnZXN0dXJlKS5cbiAgLy8gICAzLiBjc3NQYXRoIG9mIHRoZSBoaXQg4oCUIGxhc3QtcmVzb3J0IHBhdGggc3RyaW5nLlxuICBjb25zdCBzZWxlY3RvciA9IGNkSWRcbiAgICA/IGBbZGF0YS1jZC1pZD1cIiR7Y2RJZH1cIl1gXG4gICAgOiAhY2RJZCAmJiB0YXJnZXQuYXJ0Ym9hcmRJZFxuICAgICAgPyBgW2RhdGEtZGMtc2NyZWVuPVwiJHt0YXJnZXQuYXJ0Ym9hcmRJZH1cIl1gXG4gICAgICA6IGNzc1BhdGgoZWwpO1xuICByZXR1cm4ge1xuICAgIGZpbGU6IGZpbGUgPz8gZGVyaXZlRmlsZSgpLFxuICAgIGlkOiBjZElkID8/IHVuZGVmaW5lZCxcbiAgICBzZWxlY3RvcixcbiAgICBhcnRib2FyZElkOiB0YXJnZXQuYXJ0Ym9hcmRJZCxcbiAgICB0YWc6IGVsPy50YWdOYW1lLnRvTG93ZXJDYXNlKCkgPz8gJycsXG4gICAgY2xhc3NlczogcmVhbENsYXNzZXMoZWwpLFxuICAgIHRleHQ6IHNob3J0VGV4dChlbCwgMjQwKSxcbiAgICBkb21fcGF0aDogZG9tUGF0aChlbCksXG4gICAgYm91bmRzOiByZWN0XG4gICAgICA/IHtcbiAgICAgICAgICB4OiBNYXRoLnJvdW5kKHJlY3QubGVmdCksXG4gICAgICAgICAgeTogTWF0aC5yb3VuZChyZWN0LnRvcCksXG4gICAgICAgICAgdzogTWF0aC5yb3VuZChyZWN0LndpZHRoKSxcbiAgICAgICAgICBoOiBNYXRoLnJvdW5kKHJlY3QuaGVpZ2h0KSxcbiAgICAgICAgfVxuICAgICAgOiBudWxsLFxuICAgIGh0bWw6IGVsID8gKGVsLm91dGVySFRNTCA/PyAnJykuc2xpY2UoMCwgNDAwMCkgOiAnJyxcbiAgfTtcbn1cbiIsCiAgICAiLyoqXG4gKiBAZmlsZSAgICAgICBpbnB1dC1yb3V0ZXIudHN4IOKAlCBjYW52YXMgcG9pbnRlci9rZXlib2FyZCBjbGFzc2lmaWVyICsgaG9va1xuICogQHNjb3BlICAgICAgcGx1Z2lucy9kZXNpZ24vZGV2LXNlcnZlci9pbnB1dC1yb3V0ZXIudHN4XG4gKiBAcHVycG9zZSAgICBPd25lZCBieSBjYW52YXMtbGliJ3MgRGVzaWduQ2FudmFzLiBDbGFzc2lmaWVzIHRoZSBOT04tV0hFRUxcbiAqICAgICAgICAgICAgIHN1YnNldCBvZiBwb2ludGVyICsga2V5IGV2ZW50cyBpbnRvIGRpc2NyZXRlIHJvdXRlciBhY3Rpb25zLlxuICogICAgICAgICAgICAgYHVzZVZpZXdwb3J0Q29udHJvbGxlcmAga2VlcHMgb3duaW5nIHdoZWVsICsgbWlkZGxlLW1vdXNlICtcbiAqICAgICAgICAgICAgIHNwYWNlLXBhbiArIENtZCswLzEvKy8tIOKAlCB0aGUgdHdvIHN0YWNrcyBjb2V4aXN0IHdpdGhvdXQgYVxuICogICAgICAgICAgICAgbGlzdGVuZXIgcmFjZSAoRERSLTAyNikuXG4gKlxuICogRXZlbnQgb3duZXJzaGlwIChyZWFkIHRoaXMgYmVmb3JlIGFkZGluZyBoYW5kbGVycyk6XG4gKlxuICogICDilIzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilKzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJBcbiAqICAg4pSCIEV2ZW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUgiBPd25lciAgICAgICAgICAgICAgICAgICAg4pSCXG4gKiAgIOKUnOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUvOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUpFxuICogICDilIIgd2hlZWwgLyBzaGlmdC13aGVlbCAvIGNtZC13aGVlbCAg4pSCIHVzZVZpZXdwb3J0Q29udHJvbGxlciAgICDilIJcbiAqICAg4pSCIHBvaW50ZXJkb3duIGJ0bj0xIC8gc3BhY2UtaGVsZCAgIOKUgiB1c2VWaWV3cG9ydENvbnRyb2xsZXIgICAg4pSCXG4gKiAgIOKUgiBrZXlkb3duIFNwYWNlIC8gQ21kKzAvMS8rLy0gICAgICDilIIgdXNlVmlld3BvcnRDb250cm9sbGVyICAgIOKUglxuICogICDilIIgcG9pbnRlcm1vdmUgKGhvdmVyKSAgICAgICAgICAgICAg4pSCIGlucHV0LXJvdXRlciAgICAgICAgICAgICDilIJcbiAqICAg4pSCIHBvaW50ZXJkb3duIGJ0bj0wIChzZWxlY3QpICAgICAgIOKUgiBpbnB1dC1yb3V0ZXIgICAgICAgICAgICAg4pSCXG4gKiAgIOKUgiBwb2ludGVyZG93biBidG49MiAocmlnaHQtY2xpY2spICDilIIgaW5wdXQtcm91dGVyICAgICAgICAgICAgIOKUglxuICogICDilIIga2V5ZG93biBWIC8gSCAvIEMgLyBFc2MgICAgICAgICAg4pSCIGlucHV0LXJvdXRlciAgICAgICAgICAgICDilIJcbiAqICAg4pSU4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pS04pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSYXG4gKlxuICogVGhlIHJvdXRlciBkb2VzIG5vIERPTSB3b3JrIGl0c2VsZiDigJQgYGNsYXNzaWZ5KClgIGlzIHB1cmUgKHRlc3RhYmxlIHdpdGhvdXRcbiAqIGEgRE9NKSBhbmQgYHVzZUlucHV0Um91dGVyKClgIGF0dGFjaGVzIGxpc3RlbmVycyB0aGF0IGRpc3BhdGNoIHRocm91Z2ggdGhlXG4gKiBjYWxsZXItc3VwcGxpZWQgY2FsbGJhY2tzLiBIb3Zlci10YXJnZXQgcmVzb2x1dGlvbiArIHNlbGVjdGlvbiBwZXJzaXN0ZW5jZVxuICogbGl2ZSBpbiB0aGUgY29uc3VtZXIgKERlc2lnbkNhbnZhcykuXG4gKi9cblxuaW1wb3J0IHsgdHlwZSBSZWZPYmplY3QsIHVzZUVmZmVjdCB9IGZyb20gJ3JlYWN0JztcblxuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4vLyBEcmFnLXZzLWNsaWNrIHRocmVzaG9sZCAoVDI1KVxuLy9cbi8vIDQgcHggc2NyZWVuLXBpeGVsIGh5cG90IHNlcGFyYXRlcyBcImNsaWNrXCIgZnJvbSBcImRyYWdcIiDigJQgTWljcm9zb2Z0IFdpbjMyXG4vLyBjYW5vbmljYWwgKGBTTV9DWERSQUdgL2BTTV9DWURSQUdgIGRlZmF1bHQpLCBhbHNvIGQzLWRyYWcgYW5kIHRsZHJhdyBkZWZhdWx0LlxuLy8gT3duZWQgaGVyZSBzbyBhcnRib2FyZC1kcmFnLCBhcnRib2FyZC1tYXJxdWVlLCBlbGVtZW50LW1hcnF1ZWUsIGFubm90YXRpb24tXG4vLyBkcmFnLXZzLXRhcCwgYW5kIGFueSBmdXR1cmUgZHJhZy1jbGFzcyBnZXN0dXJlIGFsbCByZWFkIHRoZSBzYW1lIGNvbnN0YW50LlxuLy8gV2hlZWwgKyBwaW5jaC16b29tIGFyZSBFWEVNUFQg4oCUIHRocmVzaG9sZCBpcyBmb3IgYHBvaW50ZXJkb3duIOKGkiBwb2ludGVybW92ZWBcbi8vIGRyYWcgY2xhc3NpZmljYXRpb24gb25seS5cblxuZXhwb3J0IGNvbnN0IERSQUdfVEhSRVNIT0xEX1BYID0gNDtcblxuLyoqIFRydWUgb25jZSB0aGUgcG9pbnRlciBoYXMgbW92ZWQg4omlIERSQUdfVEhSRVNIT0xEX1BYIGZyb20gaXRzIHN0YXJ0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyb3NzZWREcmFnVGhyZXNob2xkKFxuICBzdGFydFg6IG51bWJlcixcbiAgc3RhcnRZOiBudW1iZXIsXG4gIGN1clg6IG51bWJlcixcbiAgY3VyWTogbnVtYmVyXG4pOiBib29sZWFuIHtcbiAgY29uc3QgZHggPSBjdXJYIC0gc3RhcnRYO1xuICBjb25zdCBkeSA9IGN1clkgLSBzdGFydFk7XG4gIHJldHVybiBNYXRoLmh5cG90KGR4LCBkeSkgPj0gRFJBR19USFJFU0hPTERfUFg7XG59XG5cbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuLy8gVHlwZXNcblxuLyoqXG4gKiBUb29sIHVuaW9uLiBQaGFzZSA0LjEgc2hpcHBlZCBWL0gvQzsgUGhhc2UgNSBhZGRzIHRoZSBkcmF3IHNldFxuICogKHBlbiAvIHJlY3QgLyBhcnJvdyAvIGVyYXNlcikuIERyYXctdG9vbCBwb2ludGVyIGV2ZW50cyBhcmUgb3duZWQgYnlcbiAqIGBBbm5vdGF0aW9uc0xheWVyYCDigJQgdGhlIHJvdXRlciBjbGFzc2lmaWVzIHRoZWlyIGxldHRlciBzaG9ydGN1dHMgYnV0XG4gKiByZXR1cm5zIGBuby1vcGAgZm9yIHRoZSBjb3JyZXNwb25kaW5nIHBvaW50ZXIgZXZlbnRzIHNvIHRoZSBTVkcgb3ZlcmxheVxuICogY2FuIGdyYWIgdGhlbSBuYXRpdmVseS5cbiAqL1xuZXhwb3J0IHR5cGUgVG9vbCA9XG4gIHwgJ21vdmUnXG4gIHwgJ2hhbmQnXG4gIHwgJ2NvbW1lbnQnXG4gIHwgJ3BlbidcbiAgLy8gUGhhc2UgMjQg4oCUIGBzaGFwZWAgaXMgdGhlIHNpbmdsZSBhY3RpdmUgZHJhdyB0b29sIHRoYXQgcHJvZHVjZXMgcmVjdCAvXG4gIC8vIGVsbGlwc2UgLyBwb2x5Z29uIHN0cm9rZXMgKHRoZSBraW5kIGlzIGNob3NlbiB2aWEgdGhlIHBhbGV0dGUgcG9wb3ZlcikuXG4gIC8vIGByZWN0YCAvIGBlbGxpcHNlYCBzdGF5IGluIHRoZSB1bmlvbiBhcyB0aGUgc3Ryb2tlIGRpc2NyaW1pbmFudHMgdGhleVxuICAvLyBhbHdheXMgd2VyZSwgYnV0IGFyZSBubyBsb25nZXIgZGlyZWN0bHkgc2VsZWN0YWJsZSBhY3RpdmUgdG9vbHMuXG4gIHwgJ3NoYXBlJ1xuICB8ICdyZWN0J1xuICB8ICdlbGxpcHNlJ1xuICB8ICdhcnJvdydcbiAgfCAnc3RpY2t5J1xuICB8ICd0ZXh0J1xuICB8ICdlcmFzZXInO1xuXG5jb25zdCBBTk5PVEFUSU9OX1RPT0xTID0gbmV3IFNldDxUb29sPihbXG4gICdwZW4nLFxuICAnc2hhcGUnLFxuICAncmVjdCcsXG4gICdlbGxpcHNlJyxcbiAgJ2Fycm93JyxcbiAgJ3N0aWNreScsXG4gICd0ZXh0JyxcbiAgJ2VyYXNlcicsXG5dKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGlzQW5ub3RhdGlvblRvb2wodDogVG9vbCk6IGJvb2xlYW4ge1xuICByZXR1cm4gQU5OT1RBVElPTl9UT09MUy5oYXModCk7XG59XG5cbmV4cG9ydCB0eXBlIFJvdXRlckFjdGlvbiA9XG4gIHwgeyBraW5kOiAnbm8tb3AnIH1cbiAgfCB7IGtpbmQ6ICdob3Zlcic7IGRlZXA6IGJvb2xlYW47IGNsaWVudFg6IG51bWJlcjsgY2xpZW50WTogbnVtYmVyIH1cbiAgfCB7XG4gICAgICBraW5kOiAnc2VsZWN0JztcbiAgICAgIC8qKiBgcmVwbGFjZWAgc3dhcHMgdGhlIHNlbGVjdGlvbiBzZXQsIGBhZGRgIG1lcmdlcyBpbnRvIGl0LiAqL1xuICAgICAgbW9kZTogJ3JlcGxhY2UnIHwgJ2FkZCc7XG4gICAgICAvKipcbiAgICAgICAqIGB0cnVlYCByZXNvbHZlcyB0byB0aGUgZGVlcGVzdCBkZXNjZW5kYW50IHVuZGVyIHRoZSBjdXJzb3IgKENtZC1oZWxkXG4gICAgICAgKiBtb2RlKS4gYGZhbHNlYCByZXNvbHZlcyB0byB0aGUgdG9wbW9zdCBpbnRlcmVzdGluZyBhbmNlc3RvciAodG9wIG1vZGUpLlxuICAgICAgICogUGhhc2UgNC4xIE1vdmUtdG9vbCBzZWxlY3Rpb24gYWx3YXlzIHVzZXMgZGVlcD10cnVlIOKAlCBiYXJlIGNsaWNrc1xuICAgICAgICogYXJlIHBhc3N0aHJvdWdoIChubyBzZWxlY3QpLCBhbmQgdGhlIG9ubHkgZW50cnkgcG9pbnRzIGFyZSBDbWRcbiAgICAgICAqIChyZXBsYWNlIGRlZXApIGFuZCBDbWQrU2hpZnQgKGFkZCBkZWVwKS5cbiAgICAgICAqL1xuICAgICAgZGVlcDogYm9vbGVhbjtcbiAgICAgIGNsaWVudFg6IG51bWJlcjtcbiAgICAgIGNsaWVudFk6IG51bWJlcjtcbiAgICB9XG4gIHwgeyBraW5kOiAnZHJvcC1jb21tZW50JzsgY2xpZW50WDogbnVtYmVyOyBjbGllbnRZOiBudW1iZXIgfVxuICB8IHsga2luZDogJ2NvbnRleHQtbWVudSc7IGNsaWVudFg6IG51bWJlcjsgY2xpZW50WTogbnVtYmVyIH1cbiAgfCB7IGtpbmQ6ICd0b29sJzsgdG9vbDogVG9vbCB9XG4gIHwgeyBraW5kOiAnZXNjYXBlJyB9XG4gIHwgeyBraW5kOiAndW5kbycgfVxuICB8IHsga2luZDogJ3JlZG8nIH07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2xhc3NpZnlJbnB1dCB7XG4gIHR5cGU6ICdwb2ludGVybW92ZScgfCAncG9pbnRlcmRvd24nIHwgJ2NvbnRleHRtZW51JyB8ICdrZXlkb3duJztcbiAgLyoqIFBvaW50ZXJFdmVudC5idXR0b246IDAgPSBsZWZ0LCAxID0gbWlkZGxlLCAyID0gcmlnaHQuICovXG4gIGJ1dHRvbj86IG51bWJlcjtcbiAgbWV0YUtleT86IGJvb2xlYW47XG4gIGN0cmxLZXk/OiBib29sZWFuO1xuICBzaGlmdEtleT86IGJvb2xlYW47XG4gIGFsdEtleT86IGJvb2xlYW47XG4gIGtleT86IHN0cmluZztcbiAgY2xpZW50WD86IG51bWJlcjtcbiAgY2xpZW50WT86IG51bWJlcjtcbiAgLyoqIFNwYWNlYmFyIGhlbGQg4oCUIHNoYXJlZCBzaWduYWwgd2l0aCBgdXNlVmlld3BvcnRDb250cm9sbGVyYCdzIHBhbi1kcmFnLiAqL1xuICBzcGFjZUhlbGQ/OiBib29sZWFuO1xuICAvKiogRXZlbnQgdGFyZ2V0IGlzIGVkaXRhYmxlIChpbnB1dC90ZXh0YXJlYS9jb250ZW50RWRpdGFibGUpIOKAlCBjYWxsZXIgY29tcHV0ZXMuICovXG4gIGlzRWRpdGFibGU/OiBib29sZWFuO1xuICBhY3RpdmVUb29sOiBUb29sO1xufVxuXG4vLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbi8vIGNsYXNzaWZ5IOKAlCBwdXJlIGZ1bmN0aW9uLiBBbGwgYnJhbmNoaW5nIGxpdmVzIGhlcmUgc28gdW5pdCB0ZXN0cyBjb3ZlciBldmVyeVxuLy8gcm93IG9mIHRoZSBkaXNwYXRjaCB0YWJsZSB3aXRob3V0IHNwaW5uaW5nIHVwIGEgRE9NLlxuXG5jb25zdCBtZXRhT3JDdHJsID0gKGk6IENsYXNzaWZ5SW5wdXQpOiBib29sZWFuID0+ICEhKGkubWV0YUtleSB8fCBpLmN0cmxLZXkpO1xuXG5leHBvcnQgZnVuY3Rpb24gY2xhc3NpZnkoaW5wdXQ6IENsYXNzaWZ5SW5wdXQpOiBSb3V0ZXJBY3Rpb24ge1xuICBpZiAoaW5wdXQudHlwZSA9PT0gJ2tleWRvd24nKSB7XG4gICAgaWYgKGlucHV0LmlzRWRpdGFibGUpIHJldHVybiB7IGtpbmQ6ICduby1vcCcgfTtcbiAgICAvLyBUb29sIGxldHRlcnMgYXJlIGJhcmUga2V5cyDigJQgQ21kL0N0cmwvQWx0K2xldHRlciBiZWxvbmdzIHRvIHNoZWxsIC8gYnJvd3Nlci5cbiAgICBpZiAoaW5wdXQubWV0YUtleSB8fCBpbnB1dC5jdHJsS2V5IHx8IGlucHV0LmFsdEtleSkge1xuICAgICAgLy8gRXNjIHdpdGggbW9kaWZpZXJzIHN0aWxsIGRpc21pc3Nlcy5cbiAgICAgIGlmIChpbnB1dC5rZXkgPT09ICdFc2NhcGUnKSByZXR1cm4geyBraW5kOiAnZXNjYXBlJyB9O1xuICAgICAgLy8gVW5kbyAvIHJlZG8gKFBoYXNlIDIwKS4gQWx0IGlzIHJlc2VydmVkIOKAlCBDbWQrT3B0K1ogaXMgYSBicm93c2VyXG4gICAgICAvLyB0ZXh0LWlucHV0IGdlc3R1cmUgd2UgZG9uJ3QgY2xhaW0uIGBtZXRhS2V5IHx8IGN0cmxLZXlgIGNvdmVycyBib3RoXG4gICAgICAvLyBtYWMgYW5kIFdpbmRvd3MgLyBMaW51eCB3aXRob3V0IGEgcGxhdGZvcm0gc25pZmYuXG4gICAgICBjb25zdCBrID0gKGlucHV0LmtleSB8fCAnJykudG9Mb3dlckNhc2UoKTtcbiAgICAgIGlmICghaW5wdXQuYWx0S2V5ICYmIChpbnB1dC5tZXRhS2V5IHx8IGlucHV0LmN0cmxLZXkpKSB7XG4gICAgICAgIGlmIChrID09PSAneicgJiYgaW5wdXQuc2hpZnRLZXkpIHJldHVybiB7IGtpbmQ6ICdyZWRvJyB9O1xuICAgICAgICBpZiAoayA9PT0gJ3onKSByZXR1cm4geyBraW5kOiAndW5kbycgfTtcbiAgICAgICAgaWYgKGsgPT09ICd5JyAmJiAhaW5wdXQuc2hpZnRLZXkpIHJldHVybiB7IGtpbmQ6ICdyZWRvJyB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsga2luZDogJ25vLW9wJyB9O1xuICAgIH1cbiAgICBjb25zdCBrID0gKGlucHV0LmtleSB8fCAnJykudG9Mb3dlckNhc2UoKTtcbiAgICBpZiAoayA9PT0gJ3YnKSByZXR1cm4geyBraW5kOiAndG9vbCcsIHRvb2w6ICdtb3ZlJyB9O1xuICAgIGlmIChrID09PSAnaCcpIHJldHVybiB7IGtpbmQ6ICd0b29sJywgdG9vbDogJ2hhbmQnIH07XG4gICAgaWYgKGsgPT09ICdjJykgcmV0dXJuIHsga2luZDogJ3Rvb2wnLCB0b29sOiAnY29tbWVudCcgfTtcbiAgICBpZiAoayA9PT0gJ2InKSByZXR1cm4geyBraW5kOiAndG9vbCcsIHRvb2w6ICdwZW4nIH07XG4gICAgLy8gUGhhc2UgMjQg4oCUIFIgKGFuZCBsZWdhY3kgTykgYm90aCBhcm0gdGhlIHNpbmdsZSBTaGFwZSB0b29sOyB0aGUgc3BlY2lmaWNcbiAgICAvLyBwcmltaXRpdmUgaXMgcGlja2VkIGZyb20gdGhlIHBhbGV0dGUncyBzaGFwZS1raW5kIHBvcG92ZXIuXG4gICAgaWYgKGsgPT09ICdyJyB8fCBrID09PSAnbycpIHJldHVybiB7IGtpbmQ6ICd0b29sJywgdG9vbDogJ3NoYXBlJyB9O1xuICAgIGlmIChrID09PSAnYScpIHJldHVybiB7IGtpbmQ6ICd0b29sJywgdG9vbDogJ2Fycm93JyB9O1xuICAgIC8vIFBoYXNlIDIxIOKAlCBOID0gc3RpY2t5IE5vdGUgKCdTJyBpcyB0YWtlbiBieSB0aGUgc2hlbGwgRGVzaWduLXN5c3RlbSB2aWV3XG4gICAgLy8gKyBTaGlmdC1tYXJxdWVlKTsgVCA9IHN0YW5kYWxvbmUgVGV4dC4gQm90aCBhcmUgYmFyZSBsZXR0ZXJzIHRoZSBzaGVsbFxuICAgIC8vIHlpZWxkcyB3aGVuIGZvY3VzIGlzIGluc2lkZSB0aGUgY2FudmFzIGlmcmFtZSAoYXBwLmpzeCBvbktleSBiYWlsKS5cbiAgICBpZiAoayA9PT0gJ24nKSByZXR1cm4geyBraW5kOiAndG9vbCcsIHRvb2w6ICdzdGlja3knIH07XG4gICAgaWYgKGsgPT09ICd0JykgcmV0dXJuIHsga2luZDogJ3Rvb2wnLCB0b29sOiAndGV4dCcgfTtcbiAgICBpZiAoayA9PT0gJ2UnKSByZXR1cm4geyBraW5kOiAndG9vbCcsIHRvb2w6ICdlcmFzZXInIH07XG4gICAgaWYgKGlucHV0LmtleSA9PT0gJ0VzY2FwZScpIHJldHVybiB7IGtpbmQ6ICdlc2NhcGUnIH07XG4gICAgcmV0dXJuIHsga2luZDogJ25vLW9wJyB9O1xuICB9XG5cbiAgaWYgKGlucHV0LnR5cGUgPT09ICdjb250ZXh0bWVudScpIHtcbiAgICByZXR1cm4ge1xuICAgICAga2luZDogJ2NvbnRleHQtbWVudScsXG4gICAgICBjbGllbnRYOiBpbnB1dC5jbGllbnRYID8/IDAsXG4gICAgICBjbGllbnRZOiBpbnB1dC5jbGllbnRZID8/IDAsXG4gICAgfTtcbiAgfVxuXG4gIGlmIChpbnB1dC50eXBlID09PSAncG9pbnRlcm1vdmUnKSB7XG4gICAgLy8gUGhhc2UgNSBkcmF3IHRvb2xzOiBwZW4gLyByZWN0IC8gYXJyb3cgLyBlcmFzZXIgb3duIGFsbCB0aGVpciBwb2ludGVyXG4gICAgLy8gZXZlbnRzIHRocm91Z2ggYEFubm90YXRpb25zTGF5ZXJgLiBUaGUgcm91dGVyIG5ldmVyIHBhaW50cyBhIGhvdmVyIGhhbG9cbiAgICAvLyB3aGlsZSBkcmF3aW5nIOKAlCB0aGF0IGFmZm9yZGFuY2UgaXMgcmVzZXJ2ZWQgZm9yIHNlbGVjdCAvIGNvbW1lbnQuXG4gICAgaWYgKGlzQW5ub3RhdGlvblRvb2woaW5wdXQuYWN0aXZlVG9vbCkpIHJldHVybiB7IGtpbmQ6ICduby1vcCcgfTtcbiAgICAvLyBIYW5kIHRvb2w6IGRyYWcgcGFuIGlzIG93bmVkIGJ5IHVzZVZpZXdwb3J0Q29udHJvbGxlcjsgbm8gaG92ZXIgcGFpbnQuXG4gICAgaWYgKGlucHV0LmFjdGl2ZVRvb2wgPT09ICdoYW5kJykgcmV0dXJuIHsga2luZDogJ25vLW9wJyB9O1xuICAgIC8vIENvbW1lbnQgdG9vbDogYWx3YXlzIHBhaW50IGEgcHJldmlldyBoYWxvIG9uIHRoZSBkZWVwZXN0IGVsZW1lbnQgdW5kZXJcbiAgICAvLyBjdXJzb3Ig4oCUIHRoYXQncyB0aGUgZWxlbWVudCB0aGUgdXNlciBpcyBhYm91dCB0byBjb21tZW50IG9uLiBDb21tZW50XG4gICAgLy8gcGluIGF0dGFjaG1lbnQgaXMgdG8gdGhlIHNhbWUgZWxlbWVudCB0aGV5IHdlcmUgaG92ZXJpbmcuXG4gICAgaWYgKGlucHV0LmFjdGl2ZVRvb2wgPT09ICdjb21tZW50Jykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAga2luZDogJ2hvdmVyJyxcbiAgICAgICAgZGVlcDogdHJ1ZSxcbiAgICAgICAgY2xpZW50WDogaW5wdXQuY2xpZW50WCA/PyAwLFxuICAgICAgICBjbGllbnRZOiBpbnB1dC5jbGllbnRZID8/IDAsXG4gICAgICB9O1xuICAgIH1cbiAgICAvLyBNb3ZlIHRvb2w6IGJhcmUgaG92ZXIgZG9lcyBub3RoaW5nIChuYXRpdmUgaW50ZXJhY3Rpb25zIHBhc3MgdGhyb3VnaCk7XG4gICAgLy8gQ21kLWhlbGQgaG92ZXIgcGFpbnRzIGEgaGFsbyBvbiB0aGUgZGVlcGVzdCBlbGVtZW50IChwcmV2aWV3KS5cbiAgICBpZiAoIW1ldGFPckN0cmwoaW5wdXQpKSByZXR1cm4geyBraW5kOiAnbm8tb3AnIH07XG4gICAgcmV0dXJuIHtcbiAgICAgIGtpbmQ6ICdob3ZlcicsXG4gICAgICBkZWVwOiB0cnVlLFxuICAgICAgY2xpZW50WDogaW5wdXQuY2xpZW50WCA/PyAwLFxuICAgICAgY2xpZW50WTogaW5wdXQuY2xpZW50WSA/PyAwLFxuICAgIH07XG4gIH1cblxuICBpZiAoaW5wdXQudHlwZSA9PT0gJ3BvaW50ZXJkb3duJykge1xuICAgIGlmIChpbnB1dC5idXR0b24gPT09IDIpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGtpbmQ6ICdjb250ZXh0LW1lbnUnLFxuICAgICAgICBjbGllbnRYOiBpbnB1dC5jbGllbnRYID8/IDAsXG4gICAgICAgIGNsaWVudFk6IGlucHV0LmNsaWVudFkgPz8gMCxcbiAgICAgIH07XG4gICAgfVxuICAgIGlmIChpbnB1dC5idXR0b24gPT09IDEgfHwgaW5wdXQuc3BhY2VIZWxkKSByZXR1cm4geyBraW5kOiAnbm8tb3AnIH07XG4gICAgaWYgKGlucHV0LmJ1dHRvbiAhPT0gMCkgcmV0dXJuIHsga2luZDogJ25vLW9wJyB9O1xuXG4gICAgLy8gUGhhc2UgNSBkcmF3IHRvb2xzIG93biBiYXJlIGxlZnQtY2xpY2tzOyB0aGUgcm91dGVyIHJldHVybnMgbm8tb3Agc29cbiAgICAvLyB0aGUgU1ZHIGxheWVyJ3Mgb3duIGxpc3RlbmVycyAobm8gcHJldmVudERlZmF1bHQpIGZpcmUgbm9ybWFsbHkuIENtZC1cbiAgICAvLyBtb2RpZmllZCBjbGlja3Mgc3RpbGwgZmxvdyBpbnRvIHRoZSBtb3ZlLXRvb2wgc2VsZWN0IHBhdGggYmVsb3cg4oCUIHRoYXRcbiAgICAvLyBzdGF5cyBhdmFpbGFibGUgYXMgYW4gZXNjYXBlIGhhdGNoIGV2ZW4gd2hpbGUgYSBkcmF3IHRvb2wgaXMgYWN0aXZlLlxuICAgIGlmIChpc0Fubm90YXRpb25Ub29sKGlucHV0LmFjdGl2ZVRvb2wpICYmICFtZXRhT3JDdHJsKGlucHV0KSkge1xuICAgICAgcmV0dXJuIHsga2luZDogJ25vLW9wJyB9O1xuICAgIH1cblxuICAgIGlmIChpbnB1dC5hY3RpdmVUb29sID09PSAnY29tbWVudCcpIHtcbiAgICAgIC8vIENvbW1lbnQgdG9vbDogYmFyZSBjbGljayBkcm9wcyBhIHBpbi4gQ21kIC8gU2hpZnQgbW9kaWZpZXJzIHJlc2VydmVkXG4gICAgICAvLyBmb3IgZnV0dXJlIFwic2NvcGUgY29tbWVudCB0byBkZWVwZXN0XCIgdmFyaWFudHMg4oCUIGZvciBub3cgdGhleSBmYWxsXG4gICAgICAvLyB0aHJvdWdoIHRvIHRoZSBzYW1lIGRyb3AuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBraW5kOiAnZHJvcC1jb21tZW50JyxcbiAgICAgICAgY2xpZW50WDogaW5wdXQuY2xpZW50WCA/PyAwLFxuICAgICAgICBjbGllbnRZOiBpbnB1dC5jbGllbnRZID8/IDAsXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIEhhbmQgdG9vbDogcGFuIGlzIG93bmVkIGJ5IHVzZVZpZXdwb3J0Q29udHJvbGxlciB2aWEgYGlzUGFuRHJhZ0FjdGl2ZWAuXG4gICAgLy8gUm91dGVyIHJldHVybnMgbm8tb3Agc28gaXQgZG9lc24ndCBwcmV2ZW50RGVmYXVsdCBvciBzdG9wUHJvcGFnYXRpb24g4oCUXG4gICAgLy8gdGhlIGNvbnRyb2xsZXIncyBwb2ludGVyZG93biBsaXN0ZW5lciBvbiB0aGUgc2FtZSBob3N0IGNsYWltcyB0aGUgZHJhZy5cbiAgICBpZiAoaW5wdXQuYWN0aXZlVG9vbCA9PT0gJ2hhbmQnKSByZXR1cm4geyBraW5kOiAnbm8tb3AnIH07XG5cbiAgICAvLyBNb3ZlIHRvb2wuIFNlbGVjdGlvbiBPTkxZIGZpcmVzIHdpdGggQ21kIC8gQ21kK1NoaWZ0LiBCYXJlIGNsaWNrcyBhbmRcbiAgICAvLyBTaGlmdC13aXRob3V0LUNtZCBwYXNzIHRocm91Z2ggc28gbmF0aXZlIGNhbnZhcyBpbnRlcmFjdGlvbnMgKGJ1dHRvblxuICAgIC8vIHByZXNzZXMsIGxpbmsgY2xpY2tzLCBpbnB1dCBmb2N1cykgc3RpbGwgd29yayDigJQgZXhhY3RseSB0aGUgc2FtZSBhc1xuICAgIC8vIHByZS1QaGFzZS00LjEgYmVoYXZpb3IgZm9yIGV2ZXJ5dGhpbmcgZXhjZXB0IENtZC1tb2RpZmllZCBnZXN0dXJlcy5cbiAgICBjb25zdCBjbWQgPSBtZXRhT3JDdHJsKGlucHV0KTtcbiAgICBpZiAoIWNtZCkgcmV0dXJuIHsga2luZDogJ25vLW9wJyB9O1xuICAgIGNvbnN0IHNoaWZ0ID0gISFpbnB1dC5zaGlmdEtleTtcbiAgICByZXR1cm4ge1xuICAgICAga2luZDogJ3NlbGVjdCcsXG4gICAgICBtb2RlOiBzaGlmdCA/ICdhZGQnIDogJ3JlcGxhY2UnLFxuICAgICAgZGVlcDogdHJ1ZSxcbiAgICAgIGNsaWVudFg6IGlucHV0LmNsaWVudFggPz8gMCxcbiAgICAgIGNsaWVudFk6IGlucHV0LmNsaWVudFkgPz8gMCxcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHsga2luZDogJ25vLW9wJyB9O1xufVxuXG4vLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbi8vIHVzZUlucHV0Um91dGVyIOKAlCBhdHRhY2ggbGlzdGVuZXJzIHNjb3BlZCB0byBgaG9zdFJlZi5jdXJyZW50YC4gRGlzcGF0Y2hlc1xuLy8gdGhyb3VnaCBgY2FsbGJhY2tzYC4gUmV0dXJucyBub3RoaW5nOyBjbGVhbnMgdXAgb24gdW5tb3VudC5cblxuZXhwb3J0IGludGVyZmFjZSBSb3V0ZXJDYWxsYmFja3Mge1xuICBvbkhvdmVyPzogKGE6IEV4dHJhY3Q8Um91dGVyQWN0aW9uLCB7IGtpbmQ6ICdob3ZlcicgfT4pID0+IHZvaWQ7XG4gIG9uU2VsZWN0PzogKGE6IEV4dHJhY3Q8Um91dGVyQWN0aW9uLCB7IGtpbmQ6ICdzZWxlY3QnIH0+KSA9PiB2b2lkO1xuICBvbkRyb3BDb21tZW50PzogKGE6IEV4dHJhY3Q8Um91dGVyQWN0aW9uLCB7IGtpbmQ6ICdkcm9wLWNvbW1lbnQnIH0+KSA9PiB2b2lkO1xuICBvbkNvbnRleHRNZW51PzogKGE6IEV4dHJhY3Q8Um91dGVyQWN0aW9uLCB7IGtpbmQ6ICdjb250ZXh0LW1lbnUnIH0+KSA9PiB2b2lkO1xuICBvblRvb2w/OiAoYTogRXh0cmFjdDxSb3V0ZXJBY3Rpb24sIHsga2luZDogJ3Rvb2wnIH0+KSA9PiB2b2lkO1xuICBvbkVzY2FwZT86ICgpID0+IHZvaWQ7XG4gIC8qKiBQaGFzZSAyMCDigJQgQ21kK1ogLyBDdHJsK1ouICovXG4gIG9uVW5kbz86ICgpID0+IHZvaWQ7XG4gIC8qKiBQaGFzZSAyMCDigJQgQ21kK1NoaWZ0K1ogLyBDdHJsK1kgLyBDbWQrWS4gKi9cbiAgb25SZWRvPzogKCkgPT4gdm9pZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBVc2VJbnB1dFJvdXRlck9wdGlvbnMge1xuICBob3N0UmVmOiBSZWZPYmplY3Q8SFRNTEVsZW1lbnQgfCBudWxsPjtcbiAgLyoqIExhdGVzdCBhY3RpdmUgdG9vbCDigJQgcmVhZCBhdCBldmVudCB0aW1lLCBub3QgY2FwdHVyZWQuICovXG4gIGdldEFjdGl2ZVRvb2w6ICgpID0+IFRvb2w7XG4gIC8qKiBPcHRpb25hbCBzcGFjZWJhci1oZWxkIHNpZ25hbCBzaGFyZWQgd2l0aCB1c2VWaWV3cG9ydENvbnRyb2xsZXIuICovXG4gIGlzU3BhY2VIZWxkPzogKCkgPT4gYm9vbGVhbjtcbiAgY2FsbGJhY2tzOiBSb3V0ZXJDYWxsYmFja3M7XG4gIC8qKiBXaGVuIGZhbHNlLCBsaXN0ZW5lcnMgYXJlIG5vdCBhdHRhY2hlZC4gRGVmYXVsdHMgdG8gdHJ1ZS4gKi9cbiAgZW5hYmxlZD86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBBbGxvd2xpc3Qgb2YgYWN0aW9uIGtpbmRzIHRoaXMgcm91dGVyIGlzIHBlcm1pdHRlZCB0byBDTEFJTSAocHJldmVudERlZmF1bHRcbiAgICogKyBzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24gKyBkaXNwYXRjaCkuIEFueSBjbGFzc2lmaWVkIGFjdGlvbiBvdXRzaWRlIHRoZVxuICAgKiBzZXQgaXMgZG93bmdyYWRlZCB0byBgbm8tb3BgIHNvIGl0IHByb3BhZ2F0ZXMgdW50b3VjaGVkIHRvIG90aGVyIGxpc3RlbmVycy5cbiAgICogT21pdCB0byBjbGFpbSBldmVyeXRoaW5nICh0aGUgZGVmYXVsdCDigJQgdXNlZCBieSB0aGUgZnVsbCBEZXNpZ25DYW52YXNcbiAgICogcm91dGVyKS4gVGhlIHNoZWxsLW93bmVkIGNvbW1lbnQgbW91bnQgbGF5ZXIgcGFzc2VzIGEgbmFycm93IHNldCBzbyBpdCBjYW5cbiAgICogY29leGlzdCBhcyBhbiBBTkNFU1RPUiBjYXB0dXJlLWxpc3RlbmVyIG92ZXIgYSBVSSBjYW52YXMncyBvd24gcm91dGVyXG4gICAqIHdpdGhvdXQgc3dhbGxvd2luZyBzZWxlY3QgLyBjb250ZXh0LW1lbnUgLyB1bmRvIGdlc3R1cmVzIGl0IGRvZXNuJ3Qgb3duLlxuICAgKi9cbiAgY2xhaW1hYmxlQWN0aW9ucz86IFJlYWRvbmx5U2V0PFJvdXRlckFjdGlvblsna2luZCddPjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzRWRpdGFibGVUYXJnZXQodDogRXZlbnRUYXJnZXQgfCBudWxsKTogYm9vbGVhbiB7XG4gIGlmICghdCB8fCAhKHQgYXMgSFRNTEVsZW1lbnQpLnRhZ05hbWUpIHJldHVybiBmYWxzZTtcbiAgY29uc3QgZWwgPSB0IGFzIEhUTUxFbGVtZW50O1xuICBjb25zdCB0YWcgPSBlbC50YWdOYW1lO1xuICBpZiAodGFnID09PSAnSU5QVVQnIHx8IHRhZyA9PT0gJ1RFWFRBUkVBJyB8fCB0YWcgPT09ICdTRUxFQ1QnKSByZXR1cm4gdHJ1ZTtcbiAgaWYgKGVsLmlzQ29udGVudEVkaXRhYmxlKSByZXR1cm4gdHJ1ZTtcbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIFBoYXNlIDYg4oCUIHRoZSBjb21tZW50cyBvdmVybGF5IChwaW5zIC8gY29tcG9zZXIgLyB0aHJlYWQgcG9wb3ZlciAvIG1lbnRpb25cbiAqIHBvcHVwKSBsaXZlcyBJTlNJREUgdGhlIGNhbnZhcyB3b3JsZCwgd2hpY2ggbWVhbnMgaXRzIERPTSBub2RlcyBhcmUgaW5zaWRlXG4gKiB0aGUgaW5wdXQtcm91dGVyJ3MgY2FwdHVyZSBob3N0LiBXaXRob3V0IGFuIGV4cGxpY2l0IGJhaWwtb3V0IHRoZSByb3V0ZXJcbiAqIHdvdWxkIGBwcmV2ZW50RGVmYXVsdCArIHN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbmAgZXZlcnkgY2xpY2sgb24gYVxuICogY29tcG9zZXIgYnV0dG9uIHdoaWxlIGNvbW1lbnQgbW9kZSBpcyBhY3RpdmUsIGJsb2NraW5nIFNhdmUgLyBDYW5jZWwuXG4gKlxuICogV2UgdHJlYXQgdGhlIG92ZXJsYXkgbm9kZXMgbGlrZSBlZGl0YWJsZSBmb3JtIHdpZGdldHMg4oCUIHRoZSByb3V0ZXIgeWllbGRzLFxuICogdGhlIFJlYWN0IGV2ZW50IGhhbmRsZXIgcnVucy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzT3ZlcmxheVRhcmdldCh0OiBFdmVudFRhcmdldCB8IG51bGwpOiBib29sZWFuIHtcbiAgaWYgKCF0IHx8ICEodCBhcyBFbGVtZW50KS5jbG9zZXN0KSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiAhISh0IGFzIEVsZW1lbnQpLmNsb3Nlc3QoJy5jbS1jb21wb3NlciwgLmNtLXRocmVhZCwgLmNtLW1lbnRpb24tcG9wdXAsIC5jbS1waW4nKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVzZUlucHV0Um91dGVyKG9wdHM6IFVzZUlucHV0Um91dGVyT3B0aW9ucyk6IHZvaWQge1xuICBjb25zdCB7IGhvc3RSZWYsIGdldEFjdGl2ZVRvb2wsIGlzU3BhY2VIZWxkLCBjYWxsYmFja3MsIGVuYWJsZWQgPSB0cnVlLCBjbGFpbWFibGVBY3Rpb25zIH0gPSBvcHRzO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFlbmFibGVkKSByZXR1cm47XG4gICAgY29uc3QgaG9zdCA9IGhvc3RSZWYuY3VycmVudDtcbiAgICBpZiAoIWhvc3QpIHJldHVybjtcblxuICAgIC8vIERvd25ncmFkZSBhbnkgYWN0aW9uIHRoaXMgcm91dGVyIGlzbid0IHBlcm1pdHRlZCB0byBjbGFpbSB0byBuby1vcCBzbyBpdFxuICAgIC8vIHByb3BhZ2F0ZXMgdW50b3VjaGVkIChubyBwcmV2ZW50RGVmYXVsdCAvIG5vIGRpc3BhdGNoKS4gSWRlbnRpdHkgcGFzcy1cbiAgICAvLyB0aHJvdWdoIHdoZW4gbm8gYWxsb3dsaXN0IGlzIGNvbmZpZ3VyZWQuXG4gICAgY29uc3QgY2xhaW0gPSAoYWN0aW9uOiBSb3V0ZXJBY3Rpb24pOiBSb3V0ZXJBY3Rpb24gPT5cbiAgICAgIGNsYWltYWJsZUFjdGlvbnMgJiYgYWN0aW9uLmtpbmQgIT09ICduby1vcCcgJiYgIWNsYWltYWJsZUFjdGlvbnMuaGFzKGFjdGlvbi5raW5kKVxuICAgICAgICA/IHsga2luZDogJ25vLW9wJyB9XG4gICAgICAgIDogYWN0aW9uO1xuXG4gICAgY29uc3QgZGlzcGF0Y2ggPSAoYWN0aW9uOiBSb3V0ZXJBY3Rpb24pOiB2b2lkID0+IHtcbiAgICAgIHN3aXRjaCAoYWN0aW9uLmtpbmQpIHtcbiAgICAgICAgY2FzZSAnaG92ZXInOlxuICAgICAgICAgIGNhbGxiYWNrcy5vbkhvdmVyPy4oYWN0aW9uKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnc2VsZWN0JzpcbiAgICAgICAgICBjYWxsYmFja3Mub25TZWxlY3Q/LihhY3Rpb24pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdkcm9wLWNvbW1lbnQnOlxuICAgICAgICAgIGNhbGxiYWNrcy5vbkRyb3BDb21tZW50Py4oYWN0aW9uKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnY29udGV4dC1tZW51JzpcbiAgICAgICAgICBjYWxsYmFja3Mub25Db250ZXh0TWVudT8uKGFjdGlvbik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3Rvb2wnOlxuICAgICAgICAgIGNhbGxiYWNrcy5vblRvb2w/LihhY3Rpb24pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdlc2NhcGUnOlxuICAgICAgICAgIGNhbGxiYWNrcy5vbkVzY2FwZT8uKCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3VuZG8nOlxuICAgICAgICAgIGNhbGxiYWNrcy5vblVuZG8/LigpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdyZWRvJzpcbiAgICAgICAgICBjYWxsYmFja3Mub25SZWRvPy4oKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnbm8tb3AnOlxuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBjb25zdCBvblBvaW50ZXJNb3ZlID0gKGU6IFBvaW50ZXJFdmVudCk6IHZvaWQgPT4ge1xuICAgICAgY29uc3QgYWN0aW9uID0gY2xhaW0oXG4gICAgICAgIGNsYXNzaWZ5KHtcbiAgICAgICAgICB0eXBlOiAncG9pbnRlcm1vdmUnLFxuICAgICAgICAgIGJ1dHRvbjogZS5idXR0b24sXG4gICAgICAgICAgbWV0YUtleTogZS5tZXRhS2V5LFxuICAgICAgICAgIGN0cmxLZXk6IGUuY3RybEtleSxcbiAgICAgICAgICBzaGlmdEtleTogZS5zaGlmdEtleSxcbiAgICAgICAgICBhbHRLZXk6IGUuYWx0S2V5LFxuICAgICAgICAgIGNsaWVudFg6IGUuY2xpZW50WCxcbiAgICAgICAgICBjbGllbnRZOiBlLmNsaWVudFksXG4gICAgICAgICAgc3BhY2VIZWxkOiBpc1NwYWNlSGVsZD8uKCkgPz8gZmFsc2UsXG4gICAgICAgICAgYWN0aXZlVG9vbDogZ2V0QWN0aXZlVG9vbCgpLFxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICAgIGRpc3BhdGNoKGFjdGlvbik7XG4gICAgfTtcblxuICAgIGNvbnN0IG9uUG9pbnRlckRvd24gPSAoZTogUG9pbnRlckV2ZW50KTogdm9pZCA9PiB7XG4gICAgICAvLyBQaGFzZSA2IOKAlCBvdmVybGF5IHN1cmZhY2VzIChjb21wb3NlciAvIHRocmVhZCAvIG1lbnRpb24gcG9wdXApIG93blxuICAgICAgLy8gdGhlaXIgb3duIGNsaWNrcy4gVGhlIHJvdXRlciBpcyBpbiBjYXB0dXJlIHBoYXNlLCBzbyB3ZSBoYXZlIHRvXG4gICAgICAvLyBiYWlsIEhFUkUgYmVmb3JlIGNsYXNzaWZ5IGNhbiBjbGFpbSB0aGUgZXZlbnQuXG4gICAgICBpZiAoaXNPdmVybGF5VGFyZ2V0KGUudGFyZ2V0KSkgcmV0dXJuO1xuICAgICAgY29uc3QgYWN0aW9uID0gY2xhaW0oXG4gICAgICAgIGNsYXNzaWZ5KHtcbiAgICAgICAgICB0eXBlOiAncG9pbnRlcmRvd24nLFxuICAgICAgICAgIGJ1dHRvbjogZS5idXR0b24sXG4gICAgICAgICAgbWV0YUtleTogZS5tZXRhS2V5LFxuICAgICAgICAgIGN0cmxLZXk6IGUuY3RybEtleSxcbiAgICAgICAgICBzaGlmdEtleTogZS5zaGlmdEtleSxcbiAgICAgICAgICBhbHRLZXk6IGUuYWx0S2V5LFxuICAgICAgICAgIGNsaWVudFg6IGUuY2xpZW50WCxcbiAgICAgICAgICBjbGllbnRZOiBlLmNsaWVudFksXG4gICAgICAgICAgc3BhY2VIZWxkOiBpc1NwYWNlSGVsZD8uKCkgPz8gZmFsc2UsXG4gICAgICAgICAgYWN0aXZlVG9vbDogZ2V0QWN0aXZlVG9vbCgpLFxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICAgIGlmIChhY3Rpb24ua2luZCAhPT0gJ25vLW9wJykge1xuICAgICAgICAvLyBTdXBwcmVzcyBuYXRpdmUgYmVoYXZpb3Igb24gZXZlcnkgZXZlbnQgdGhlIHJvdXRlciBjbGFpbXMg4oCUXG4gICAgICAgIC8vIGJ1dHRvbiBwcmVzc2VzIGRvbid0IGZpcmUsIGlucHV0cyBkb24ndCBmb2N1cywgdGhlIGNhbnZhc1xuICAgICAgICAvLyBjb250ZW50J3Mgb3duIGNsaWNrIGhhbmRsZXJzIGRvbid0IHJ1bi4gVGhlIHJvdXRlciBsaXZlcyBpblxuICAgICAgICAvLyBjYXB0dXJlIHBoYXNlIHNvIHRoaXMgZmlyZXMgYmVmb3JlIGRlc2NlbmRhbnRzLlxuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICAgICB9XG4gICAgICBkaXNwYXRjaChhY3Rpb24pO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBQYWlyZWQgbW91c2Vkb3duIGxpc3RlbmVyIOKAlCBwcmV2ZW50RGVmYXVsdCBvbiBwb2ludGVyZG93biBkb2VzIE5PVFxuICAgICAqIHN1cHByZXNzIHRoZSBtb3VzZWRvd24gZXZlbnQgdGhhdCBicm93c2VycyBmaXJlIGFsb25nc2lkZSwgYW5kXG4gICAgICogYDxpbnB1dD5gIC8gYDxidXR0b24+YCBmb2N1cyBpcyBkcml2ZW4gYnkgbW91c2Vkb3duJ3MgZGVmYXVsdCBiZWhhdmlvci5cbiAgICAgKiBXZSBtaXJyb3IgdGhlIHNhbWUgZ2F0ZSBhcyBwb2ludGVyZG93biBzbyBzdXBwcmVzc2VkIHBvaW50ZXJkb3ducyBhbHNvXG4gICAgICogc3RvcCB0aGVpciB0d2luIG1vdXNlZG93bi5cbiAgICAgKi9cbiAgICBjb25zdCBvbk1vdXNlRG93biA9IChlOiBNb3VzZUV2ZW50KTogdm9pZCA9PiB7XG4gICAgICBpZiAoaXNPdmVybGF5VGFyZ2V0KGUudGFyZ2V0KSkgcmV0dXJuO1xuICAgICAgY29uc3QgYWN0aW9uID0gY2xhaW0oXG4gICAgICAgIGNsYXNzaWZ5KHtcbiAgICAgICAgICB0eXBlOiAncG9pbnRlcmRvd24nLFxuICAgICAgICAgIGJ1dHRvbjogZS5idXR0b24sXG4gICAgICAgICAgbWV0YUtleTogZS5tZXRhS2V5LFxuICAgICAgICAgIGN0cmxLZXk6IGUuY3RybEtleSxcbiAgICAgICAgICBzaGlmdEtleTogZS5zaGlmdEtleSxcbiAgICAgICAgICBhbHRLZXk6IGUuYWx0S2V5LFxuICAgICAgICAgIGNsaWVudFg6IGUuY2xpZW50WCxcbiAgICAgICAgICBjbGllbnRZOiBlLmNsaWVudFksXG4gICAgICAgICAgc3BhY2VIZWxkOiBpc1NwYWNlSGVsZD8uKCkgPz8gZmFsc2UsXG4gICAgICAgICAgYWN0aXZlVG9vbDogZ2V0QWN0aXZlVG9vbCgpLFxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICAgIGlmIChhY3Rpb24ua2luZCAhPT0gJ25vLW9wJykge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENsaWNrIGxpc3RlbmVyIOKAlCBmaXJlcyBBRlRFUiBwb2ludGVyZG93bitwb2ludGVydXAuIEV2ZW4gd2l0aFxuICAgICAqIHByZXZlbnREZWZhdWx0IG9uIG1vdXNlZG93biwgdGhlIGNsaWNrIGV2ZW50IHN0aWxsIHN5bnRoZXNpemVzIGZvclxuICAgICAqIG5vbi1mb3JtIGVsZW1lbnRzLiBXZSBzdXBwcmVzcyBpdCB3aGVuZXZlciB0aGUgcm91dGVyIGNsYWltZWQgdGhlXG4gICAgICogbWF0Y2hpbmcgcG9pbnRlcmRvd24gKHJlLWNsYXNzaWZ5IHdpdGggdGhlIHNhbWUgbW9kaWZpZXJzKS5cbiAgICAgKi9cbiAgICBjb25zdCBvbkNsaWNrID0gKGU6IE1vdXNlRXZlbnQpOiB2b2lkID0+IHtcbiAgICAgIGlmIChpc092ZXJsYXlUYXJnZXQoZS50YXJnZXQpKSByZXR1cm47XG4gICAgICBjb25zdCB0b29sID0gZ2V0QWN0aXZlVG9vbCgpO1xuICAgICAgY29uc3QgbW9kID0gZS5tZXRhS2V5IHx8IGUuY3RybEtleTtcbiAgICAgIC8vIE1hcCB0aGUgY2xpY2sgdG8gdGhlIGFjdGlvbiBraW5kIHRoZSBtYXRjaGluZyBwb2ludGVyZG93biB3b3VsZCBoYXZlXG4gICAgICAvLyBwcm9kdWNlZCwgdGhlbiBob25vciB0aGUgY2xhaW0gYWxsb3dsaXN0IHNvIGEgc2NvcGVkIHJvdXRlciAodGhlXG4gICAgICAvLyBjb21tZW50IG1vdW50IGxheWVyKSBkb2Vzbid0IHN1cHByZXNzIGNsaWNrcyBpdCBuZXZlciBjbGFpbWVkLlxuICAgICAgY29uc3Qgd291bGRSb3V0ZUtpbmQ6IFJvdXRlckFjdGlvblsna2luZCddIHwgbnVsbCA9XG4gICAgICAgIHRvb2wgPT09ICdjb21tZW50J1xuICAgICAgICAgID8gJ2Ryb3AtY29tbWVudCdcbiAgICAgICAgICA6IHRvb2wgPT09ICdtb3ZlJyAmJiBtb2QgJiYgZS5idXR0b24gPT09IDBcbiAgICAgICAgICAgID8gJ3NlbGVjdCdcbiAgICAgICAgICAgIDogZS5idXR0b24gPT09IDJcbiAgICAgICAgICAgICAgPyAnY29udGV4dC1tZW51J1xuICAgICAgICAgICAgICA6IG51bGw7XG4gICAgICBpZiAod291bGRSb3V0ZUtpbmQgJiYgKCFjbGFpbWFibGVBY3Rpb25zIHx8IGNsYWltYWJsZUFjdGlvbnMuaGFzKHdvdWxkUm91dGVLaW5kKSkpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBjb25zdCBvbkNvbnRleHRNZW51ID0gKGU6IE1vdXNlRXZlbnQpOiB2b2lkID0+IHtcbiAgICAgIGNvbnN0IGFjdGlvbiA9IGNsYWltKFxuICAgICAgICBjbGFzc2lmeSh7XG4gICAgICAgICAgdHlwZTogJ2NvbnRleHRtZW51JyxcbiAgICAgICAgICBjbGllbnRYOiBlLmNsaWVudFgsXG4gICAgICAgICAgY2xpZW50WTogZS5jbGllbnRZLFxuICAgICAgICAgIG1ldGFLZXk6IGUubWV0YUtleSxcbiAgICAgICAgICBjdHJsS2V5OiBlLmN0cmxLZXksXG4gICAgICAgICAgc2hpZnRLZXk6IGUuc2hpZnRLZXksXG4gICAgICAgICAgYWx0S2V5OiBlLmFsdEtleSxcbiAgICAgICAgICBhY3RpdmVUb29sOiBnZXRBY3RpdmVUb29sKCksXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgICAgaWYgKGFjdGlvbi5raW5kID09PSAnbm8tb3AnKSByZXR1cm47IC8vIG5vdCBvdXJzIHRvIGNsYWltIOKAlCBsZXQgaXQgYnViYmxlXG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuICAgICAgZGlzcGF0Y2goYWN0aW9uKTtcbiAgICB9O1xuXG4gICAgY29uc3Qgb25LZXlEb3duID0gKGU6IEtleWJvYXJkRXZlbnQpOiB2b2lkID0+IHtcbiAgICAgIGNvbnN0IGFjdGlvbiA9IGNsYWltKFxuICAgICAgICBjbGFzc2lmeSh7XG4gICAgICAgICAgdHlwZTogJ2tleWRvd24nLFxuICAgICAgICAgIGtleTogZS5rZXksXG4gICAgICAgICAgbWV0YUtleTogZS5tZXRhS2V5LFxuICAgICAgICAgIGN0cmxLZXk6IGUuY3RybEtleSxcbiAgICAgICAgICBzaGlmdEtleTogZS5zaGlmdEtleSxcbiAgICAgICAgICBhbHRLZXk6IGUuYWx0S2V5LFxuICAgICAgICAgIGlzRWRpdGFibGU6IGlzRWRpdGFibGVUYXJnZXQoZS50YXJnZXQpLFxuICAgICAgICAgIGFjdGl2ZVRvb2w6IGdldEFjdGl2ZVRvb2woKSxcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgICBpZiAoXG4gICAgICAgIGFjdGlvbi5raW5kID09PSAndG9vbCcgfHxcbiAgICAgICAgYWN0aW9uLmtpbmQgPT09ICdlc2NhcGUnIHx8XG4gICAgICAgIGFjdGlvbi5raW5kID09PSAndW5kbycgfHxcbiAgICAgICAgYWN0aW9uLmtpbmQgPT09ICdyZWRvJ1xuICAgICAgKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIH1cbiAgICAgIGRpc3BhdGNoKGFjdGlvbik7XG4gICAgfTtcblxuICAgIC8vIENhcHR1cmUgcGhhc2UgZm9yIHBvaW50ZXIvbW91c2UvY2xpY2sgZXZlbnRzIOKAlCByb3V0ZXIgcnVucyBCRUZPUkVcbiAgICAvLyBkZXNjZW5kYW50cyAoYnV0dG9ucywgaW5wdXRzLCBjYW52YXMgY29udGVudCBsaXN0ZW5lcnMpLiBGb3IgZXZlbnRzIHRoZVxuICAgIC8vIGNsYXNzaWZpZXIgY2xhaW1zLCB3ZSBwcmV2ZW50RGVmYXVsdCArIHN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiBzbyB0aGVcbiAgICAvLyBkZXNjZW5kYW50cyBuZXZlciBzZWUgdGhlbS5cbiAgICBob3N0LmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJtb3ZlJywgb25Qb2ludGVyTW92ZSwgeyBwYXNzaXZlOiB0cnVlIH0pO1xuICAgIGhvc3QuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCBvblBvaW50ZXJEb3duLCB7IGNhcHR1cmU6IHRydWUgfSk7XG4gICAgaG9zdC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCBvbk1vdXNlRG93biwgeyBjYXB0dXJlOiB0cnVlIH0pO1xuICAgIGhvc3QuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBvbkNsaWNrLCB7IGNhcHR1cmU6IHRydWUgfSk7XG4gICAgaG9zdC5hZGRFdmVudExpc3RlbmVyKCdjb250ZXh0bWVudScsIG9uQ29udGV4dE1lbnUsIHsgY2FwdHVyZTogdHJ1ZSB9KTtcbiAgICAvLyBLZXkgZXZlbnRzOiBhdHRhY2ggb24gZG9jdW1lbnQgc28gZm9jdXMgaW5zaWRlIGFueSBkZXNjZW5kYW50IGlzIE9LO1xuICAgIC8vIHRoZSBlZGl0YWJsZS10YXJnZXQgZ2F0ZSBoYW5kbGVzIHRoZSBcInVzZXIgaXMgdHlwaW5nXCIgY2FzZS5cbiAgICBjb25zdCBkb2MgPSBob3N0Lm93bmVyRG9jdW1lbnQgPz8gZG9jdW1lbnQ7XG4gICAgZG9jLmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBvbktleURvd24sIHRydWUpO1xuXG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGhvc3QucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcm1vdmUnLCBvblBvaW50ZXJNb3ZlKTtcbiAgICAgIGhvc3QucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCBvblBvaW50ZXJEb3duLCB7XG4gICAgICAgIGNhcHR1cmU6IHRydWUsXG4gICAgICB9IGFzIEV2ZW50TGlzdGVuZXJPcHRpb25zKTtcbiAgICAgIGhvc3QucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgb25Nb3VzZURvd24sIHsgY2FwdHVyZTogdHJ1ZSB9IGFzIEV2ZW50TGlzdGVuZXJPcHRpb25zKTtcbiAgICAgIGhvc3QucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCBvbkNsaWNrLCB7IGNhcHR1cmU6IHRydWUgfSBhcyBFdmVudExpc3RlbmVyT3B0aW9ucyk7XG4gICAgICBob3N0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NvbnRleHRtZW51Jywgb25Db250ZXh0TWVudSwge1xuICAgICAgICBjYXB0dXJlOiB0cnVlLFxuICAgICAgfSBhcyBFdmVudExpc3RlbmVyT3B0aW9ucyk7XG4gICAgICBkb2MucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIG9uS2V5RG93biwgdHJ1ZSk7XG4gICAgfTtcbiAgfSwgW2VuYWJsZWQsIGhvc3RSZWYsIGdldEFjdGl2ZVRvb2wsIGlzU3BhY2VIZWxkLCBjYWxsYmFja3MsIGNsYWltYWJsZUFjdGlvbnNdKTtcbn1cblxuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4vLyByZXNvbHZlSG92ZXJUYXJnZXQg4oCUIHdhbGtzIGZyb20gYSBjbGllbnRYL2NsaWVudFkgcGFpciB0byB0aGUgY2FudmFzIGVsZW1lbnRcbi8vIG9mIGludGVyZXN0LiBEZWZhdWx0ID0gdG9wbW9zdCBgW2RhdGEtY2QtaWRdYCBhbmNlc3RvciAodGhlIHN0YWJsZVxuLy8gcGlwZWxpbmUtc3RhbXBlZCBhbmNob3IpLiBgZGVlcCA9IHRydWVgIHJldHVybnMgdGhlIGRlZXBlc3QgZGVzY2VuZGFudFxuLy8gKENtZC1ob3ZlciBiZWhhdmlvcikuXG5cbmV4cG9ydCBpbnRlcmZhY2UgSG92ZXJUYXJnZXQge1xuICBlbDogRWxlbWVudDtcbiAgY2RJZDogc3RyaW5nIHwgbnVsbDtcbiAgYXJ0Ym9hcmRJZDogc3RyaW5nIHwgbnVsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVIb3ZlclRhcmdldChcbiAgZG9jOiBEb2N1bWVudCxcbiAgY2xpZW50WDogbnVtYmVyLFxuICBjbGllbnRZOiBudW1iZXIsXG4gIG9wdHM6IHsgZGVlcDogYm9vbGVhbiB9XG4pOiBIb3ZlclRhcmdldCB8IG51bGwge1xuICBjb25zdCBoaXQgPSBkb2MuZWxlbWVudEZyb21Qb2ludChjbGllbnRYLCBjbGllbnRZKTtcbiAgaWYgKCFoaXQpIHJldHVybiBudWxsO1xuICAvLyBTa2lwIHRoZSBmbG9hdGluZyBjaHJvbWUgKE1pbmlNYXAgLyBab29tVG9vbGJhciAvIFRvb2xQYWxldHRlIC8gQ29udGV4dE1lbnUpXG4gIC8vIEFORCB0aGUgY2FudmFzL3dvcmxkIGZyYW1lIGl0c2VsZiDigJQgdGhlIHVzZXIgaXMgbmV2ZXIgYXNraW5nIHRvIFwic2VsZWN0XG4gIC8vIHRoZSBlbnRpcmUgY2FudmFzIHZpZXdwb3J0LFwiIHRoYXQncyBhIFVJIGFjY2lkZW50IGZyb20gY2xpbWJpbmcgdG9vIGhpZ2guXG4gIGlmIChoaXQuY2xvc2VzdD8uKCcuZGMtbW0sIC5kYy16b29tLXRiLCAuZGMtdG9vbC1wYWxldHRlLCAuZGMtY29udGV4dC1tZW51LCAuZGMtY3YtZ3JvdXAtYmJveCcpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBhcnRib2FyZEVsID0gaGl0LmNsb3Nlc3Q/LignW2RhdGEtZGMtc2NyZWVuXScpID8/IG51bGw7XG4gIGNvbnN0IGFydGJvYXJkSWQgPSBhcnRib2FyZEVsPy5nZXRBdHRyaWJ1dGUoJ2RhdGEtZGMtc2NyZWVuJykgPz8gbnVsbDtcblxuICAvLyBIb3Zlci10YXJnZXQgaGFyZCBjZWlsaW5nID0gYC5kYy1hcnRib2FyZC1ib2R5YC4gSW5uZXIgRE9NIGNvbnRlbnQgbGl2ZXNcbiAgLy8gdGhlcmU7IGNocm9tZSBsaXZlcyBvdXRzaWRlIChsYWJlbCwgaGVhZGVyLCBhcnRpY2xlIHJvb3QpLiBUaGUgdHdvIHBhdGhzXG4gIC8vIGRpdmVyZ2UgZnJvbSBoZXJlOlxuICAvLyAgICogaGl0IOKIiCBib2R5IOKGkiByZXNvbHZlIHRvIHRoZSBkZWVwZXN0IHN0YW1wZWQgZWxlbWVudCAoZXhpc3RpbmdcbiAgLy8gICAgIGRlZXAvdG9wIGxvZ2ljIGJlbG93KS5cbiAgLy8gICAqIGhpdCDiiIggY2hyb21lIChsYWJlbC9oZWFkZXIvYXJ0aWNsZS1yb290KSDihpIgdGhlIHVzZXIgd2FudHMgdG8gc2VsZWN0XG4gIC8vICAgICB0aGUgV0hPTEUgYXJ0Ym9hcmQuIFJldHVybiB0aGUgYXJ0aWNsZSBlbGVtZW50IGl0c2VsZiB3aXRoIG5vIGNkSWQ7XG4gIC8vICAgICBjb25zdW1lcnMgKGhvdmVyVGFyZ2V0VG9TZWxlY3Rpb24pIGZhbGwgYmFjayB0byBhXG4gIC8vICAgICBgW2RhdGEtZGMtc2NyZWVuPVwi4oCmXCJdYCBzZWxlY3RvciB0aGF0IHdyYXBzIHRoZSB3aG9sZSBmcmFtZS4gVGhpcyBpc1xuICAvLyAgICAgd2hhdCBlbmFibGVzIENtZCtTaGlmdCtDbGljayBtdWx0aS1zZWxlY3Qgb2YgYXJ0Ym9hcmRzIChUMjQgLyBHOCkuXG4gIGNvbnN0IGJvZHlFbCA9IGhpdC5jbG9zZXN0Py4oJy5kYy1hcnRib2FyZC1ib2R5JykgPz8gbnVsbDtcbiAgaWYgKCFib2R5RWwpIHtcbiAgICBpZiAoYXJ0Ym9hcmRFbCAmJiBhcnRib2FyZElkKSB7XG4gICAgICByZXR1cm4geyBlbDogYXJ0Ym9hcmRFbCwgY2RJZDogbnVsbCwgYXJ0Ym9hcmRJZCB9O1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBpZiAoaGl0ID09PSBib2R5RWwpIHtcbiAgICAvLyBDbGlja2VkIHRoZSBib2R5IHdyYXBwZXIgaXRzZWxmIChlbXB0eSBwYWRkaW5nIGluc2lkZSBhbiBhcnRib2FyZCwgbm9cbiAgICAvLyB1c2VyIGNvbnRlbnQgdW5kZXIgdGhlIGN1cnNvcikuIFByb21vdGUgdG8gXCJzZWxlY3Qgd2hvbGUgYXJ0Ym9hcmRcIiBzb1xuICAgIC8vIHRoZSBnZXN0dXJlIHN0YXlzIGNvbnNpc3RlbnQgd2l0aCBjaHJvbWUgY2xpY2tzIGFib3ZlLlxuICAgIGlmIChhcnRib2FyZEVsICYmIGFydGJvYXJkSWQpIHtcbiAgICAgIHJldHVybiB7IGVsOiBhcnRib2FyZEVsLCBjZElkOiBudWxsLCBhcnRib2FyZElkIH07XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKG9wdHMuZGVlcCkge1xuICAgIC8vIERlZXBlc3QgbW9kZSDigJQgdGhlIGhpdCBlbGVtZW50IElTIHRoZSB0YXJnZXQuIFVzZSBpdHMgT1dOIGRhdGEtY2QtaWRcbiAgICAvLyB3aGVuIHByZXNlbnQ7IG5ldmVyIGNsaW1iIHRvIGFuIGFuY2VzdG9yJ3MgaWQgKGNsaW1iaW5nIHdhcyB0aGUgY2F1c2VcbiAgICAvLyBvZiBcIkNtZC1jbGljayBvbiBhIGRlZXAgc3BhbiBzZWxlY3RzIHRoZSB3aG9sZSBhcnRib2FyZCByb290XCIpLiBXaGVuXG4gICAgLy8gdGhlIGhpdCBsYWNrcyBhIHN0YW1wZWQgaWQsIGNvbnN1bWVycyBmYWxsIGJhY2sgdG8gYSBDU1MtcGF0aCBzZWxlY3Rvci5cbiAgICBjb25zdCBjZElkID0gaGl0LmdldEF0dHJpYnV0ZT8uKCdkYXRhLWNkLWlkJykgPz8gbnVsbDtcbiAgICByZXR1cm4geyBlbDogaGl0LCBjZElkLCBhcnRib2FyZElkIH07XG4gIH1cblxuICAvLyBUb3AgbW9kZSDigJQgY2xpbWIgdG8gdGhlIHRvcG1vc3QgZGVzY2VuZGFudCBvZiB0aGUgYXJ0Ym9hcmQgYm9keSB0aGF0XG4gIC8vIHN0aWxsIGNhcnJpZXMgYSBkYXRhLWNkLWlkLiBIYXJkIGNlaWxpbmcgaXMgYm9keUVsIGl0c2VsZiAobmV2ZXIgc2VsZWN0XG4gIC8vIHRoZSBib2R5IHdyYXBwZXIgb3IgaGlnaGVyKS5cbiAgbGV0IGN1cjogRWxlbWVudCB8IG51bGwgPSBoaXQ7XG4gIGxldCB0b3BDZEVsOiBFbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIHdoaWxlIChjdXIgJiYgY3VyICE9PSBib2R5RWwpIHtcbiAgICBpZiAoY3VyLmhhc0F0dHJpYnV0ZT8uKCdkYXRhLWNkLWlkJykpIHRvcENkRWwgPSBjdXI7XG4gICAgY3VyID0gY3VyLnBhcmVudEVsZW1lbnQ7XG4gIH1cbiAgY29uc3QgZWwgPSB0b3BDZEVsID8/IGhpdDtcbiAgY29uc3QgY2RJZCA9IGVsLmdldEF0dHJpYnV0ZT8uKCdkYXRhLWNkLWlkJykgPz8gbnVsbDtcbiAgcmV0dXJuIHsgZWwsIGNkSWQsIGFydGJvYXJkSWQgfTtcbn1cbiIsCiAgICAiLyoqXG4gKiBAZmlsZSAgICAgICB1c2UtdG9vbC1tb2RlLnRzeCDigJQgUGhhc2UgNC4xIHRvb2wtbW9kZSBzdG9yZVxuICogQHNjb3BlICAgICAgcGx1Z2lucy9kZXNpZ24vZGV2LXNlcnZlci91c2UtdG9vbC1tb2RlLnRzeFxuICogQHB1cnBvc2UgICAgQ29udGV4dCArIGhvb2sgZm9yIHRoZSBhY3RpdmUgY2FudmFzIHRvb2wuIFdpcmVkIGludG9cbiAqICAgICAgICAgICAgIERlc2lnbkNhbnZhcy4gUGhhc2UgNSB3aWxsXG4gKiAgICAgICAgICAgICByZWdpc3RlciBhZGRpdGlvbmFsIHRvb2xzIChwZW4sIGNpcmNsZSwgYXJyb3csIGVyYXNlcikgdmlhXG4gKiAgICAgICAgICAgICB0aGUgc2FtZSBwcm92aWRlciDigJQgdGhlIEFQSSBpcyBpbnRlbnRpb25hbGx5IG9wZW4uXG4gKlxuICogVGhlIHJvdXRlcidzIGBvblRvb2xgIGNhbGxiYWNrIChpbnB1dC1yb3V0ZXIudHN4KSB3cml0ZXMgaW50byB0aGlzIHN0b3JlLlxuICogVGhlIFRvb2xQYWxldHRlICsgY3Vyc29yIHN5bmMgcmVhZCBmcm9tIGl0LiBTZWxlY3RpbmcgYSB0b29sIGFsc28gbXV0YXRlc1xuICogYGRvY3VtZW50LmJvZHkuc3R5bGUuY3Vyc29yYCBzbyB0aGUgYWZmb3JkYW5jZSBtYXRjaGVzIGFjcm9zcyB0aGUgaWZyYW1lLlxuICovXG5cbmltcG9ydCB7XG4gIGNyZWF0ZUNvbnRleHQsXG4gIHR5cGUgUmVhY3ROb2RlLFxuICB1c2VDYWxsYmFjayxcbiAgdXNlQ29udGV4dCxcbiAgdXNlRWZmZWN0LFxuICB1c2VNZW1vLFxuICB1c2VTdGF0ZSxcbn0gZnJvbSAncmVhY3QnO1xuXG5pbXBvcnQgeyBUT09MX0NVUlNPUlMgfSBmcm9tICcuL2NhbnZhcy1jdXJzb3JzLnRzJztcbmltcG9ydCB0eXBlIHsgVG9vbCB9IGZyb20gJy4vaW5wdXQtcm91dGVyLnRzeCc7XG5cbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuLy8gVHlwZXNcblxuZXhwb3J0IGludGVyZmFjZSBUb29sRGVzY3JpcHRvciB7XG4gIGlkOiBUb29sO1xuICBsYWJlbDogc3RyaW5nO1xuICAvKiogTGV0dGVyLWtleSBzaG9ydGN1dCBzaG93biBpbiB0aGUgcGFsZXR0ZSB0b29sdGlwLiAqL1xuICBzaG9ydGN1dDogc3RyaW5nO1xuICAvKiogQ1NTIGN1cnNvciB2YWx1ZSBhcHBsaWVkIHRvIDxib2R5PiB3aGVuIHRoaXMgdG9vbCBpcyBhY3RpdmUuICovXG4gIGN1cnNvcjogc3RyaW5nO1xufVxuXG4vKipcbiAqIFBoYXNlIDI0IOKAlCB0aGUgc2l4IHByaW1pdGl2ZXMgdGhlIHNpbmdsZSBTaGFwZSB0b29sIGNhbiBkcmF3LiBNYXBzIG9udG8gdGhlXG4gKiBzdHJva2UgbW9kZWw6IHNxdWFyZS9yb3VuZGVkIOKGkiBgcmVjdGAgKGNvcm5lclJhZGl1cyAwIC8gOCk7IGNpcmNsZSDihpJcbiAqIGBlbGxpcHNlYDsgZGlhbW9uZC90cmlhbmdsZS90cmlhbmdsZS1kb3duIOKGkiBgcG9seWdvbmAuXG4gKi9cbmV4cG9ydCB0eXBlIFNoYXBlS2luZCA9ICdzcXVhcmUnIHwgJ3JvdW5kZWQnIHwgJ2NpcmNsZScgfCAnZGlhbW9uZCcgfCAndHJpYW5nbGUnIHwgJ3RyaWFuZ2xlLWRvd24nO1xuXG4vLyBQaGFzZSAyMSDigJQgZXZlcnkgdG9vbCBzaGlwcyBhIGN1c3RvbSAzMsOXMzIgU1ZHIGN1cnNvciAoY2FudmFzLWN1cnNvcnMudHMpXG4vLyB3aXRoIGEgd2hpdGUgb3V0bGluZSBoYWxvIHNvIHRoZSBnbHlwaCByZWFkcyBvbiBhbnkgYmFja2dyb3VuZC4gVGhlIG5hdGl2ZVxuLy8gY3Jvc3NoYWlyL3RleHQvY2VsbCB3ZXJlIHRoaW4gKyB0aW55IChcInBlbiBhbG1vc3QgaW52aXNpYmxlXCIpOyB0aGVzZSBtaXJyb3Jcbi8vIHRoZSB0b29sLXBhbGV0dGUgaWNvbnMuIGBtb3ZlYCBrZWVwcyB0aGUgc3lzdGVtIGFycm93IG9uIHB1cnBvc2UuXG5leHBvcnQgY29uc3QgREVGQVVMVF9UT09MUzogcmVhZG9ubHkgVG9vbERlc2NyaXB0b3JbXSA9IE9iamVjdC5mcmVlemUoW1xuICB7IGlkOiAnbW92ZScsIGxhYmVsOiAnTW92ZScsIHNob3J0Y3V0OiAnVicsIGN1cnNvcjogVE9PTF9DVVJTT1JTLm1vdmUgfSxcbiAgeyBpZDogJ2hhbmQnLCBsYWJlbDogJ0hhbmQnLCBzaG9ydGN1dDogJ0gnLCBjdXJzb3I6IFRPT0xfQ1VSU09SUy5oYW5kIH0sXG4gIHsgaWQ6ICdjb21tZW50JywgbGFiZWw6ICdDb21tZW50Jywgc2hvcnRjdXQ6ICdDJywgY3Vyc29yOiBUT09MX0NVUlNPUlMuY29tbWVudCB9LFxuICB7IGlkOiAncGVuJywgbGFiZWw6ICdQZW4nLCBzaG9ydGN1dDogJ0InLCBjdXJzb3I6IFRPT0xfQ1VSU09SUy5wZW4gfSxcbiAgLy8gUGhhc2UgMjQg4oCUIG9uZSBTaGFwZSB0b29sIHJlcGxhY2VzIHRoZSBzZXBhcmF0ZSBSZWN0IChSKSArIEVsbGlwc2UgKE8pXG4gIC8vIGJ1dHRvbnM7IHRoZSBwcmltaXRpdmUgaXMgY2hvc2VuIGZyb20gdGhlIHBhbGV0dGUgcG9wb3Zlci5cbiAgeyBpZDogJ3NoYXBlJywgbGFiZWw6ICdTaGFwZScsIHNob3J0Y3V0OiAnUicsIGN1cnNvcjogVE9PTF9DVVJTT1JTLnNoYXBlIH0sXG4gIHsgaWQ6ICdzdGlja3knLCBsYWJlbDogJ1N0aWNreScsIHNob3J0Y3V0OiAnTicsIGN1cnNvcjogVE9PTF9DVVJTT1JTLnN0aWNreSB9LFxuICB7IGlkOiAnYXJyb3cnLCBsYWJlbDogJ0Fycm93Jywgc2hvcnRjdXQ6ICdBJywgY3Vyc29yOiBUT09MX0NVUlNPUlMuYXJyb3cgfSxcbiAgeyBpZDogJ3RleHQnLCBsYWJlbDogJ1RleHQnLCBzaG9ydGN1dDogJ1QnLCBjdXJzb3I6IFRPT0xfQ1VSU09SUy50ZXh0IH0sXG4gIHsgaWQ6ICdlcmFzZXInLCBsYWJlbDogJ0VyYXNlcicsIHNob3J0Y3V0OiAnRScsIGN1cnNvcjogVE9PTF9DVVJTT1JTLmVyYXNlciB9LFxuXSk7XG5cbmludGVyZmFjZSBUb29sQ29udGV4dFZhbHVlIHtcbiAgdG9vbDogVG9vbDtcbiAgc2V0VG9vbDogKHQ6IFRvb2wpID0+IHZvaWQ7XG4gIHRvb2xzOiByZWFkb25seSBUb29sRGVzY3JpcHRvcltdO1xuICAvKiogVDE5IOKAlCBzdGlja3ktdG9vbCBkb3VibGUtY2xpY2sgbG9jay4gV2hlbiBgc3RpY2t5LmxvY2tlZCA9PT0gdHJ1ZWAgQU5EXG4gICAqICBgc3RpY2t5LnRvb2wgPT09IHRvb2xgLCBkcmF3IHRvb2xzIHN0YXkgYXJtZWQgYWZ0ZXIgZWFjaCBzaGFwZSBjb21taXRcbiAgICogIChUMTggYXV0by1mbGlwIGlzIHN1cHByZXNzZWQpLiBTaW5nbGUtY2xpY2sgb24gYW55IG90aGVyIHRvb2wgY2xlYXJzXG4gICAqICBzdGlja3k7IEVzYyBjbGVhcnMgKyBmbGlwcyB0byBNb3ZlLiAqL1xuICBzdGlja3k6IHsgdG9vbDogVG9vbCB8IG51bGw7IGxvY2tlZDogYm9vbGVhbiB9O1xuICB0b2dnbGVTdGlja3k6ICh0OiBUb29sKSA9PiB2b2lkO1xuICBjbGVhclN0aWNreTogKCkgPT4gdm9pZDtcbiAgLyoqIFBoYXNlIDI0IOKAlCB0aGUgcHJpbWl0aXZlIHRoZSBTaGFwZSB0b29sIHdpbGwgZHJhdyBuZXh0LiAqL1xuICBzaGFwZUtpbmQ6IFNoYXBlS2luZDtcbiAgc2V0U2hhcGVLaW5kOiAoazogU2hhcGVLaW5kKSA9PiB2b2lkO1xufVxuXG5jb25zdCBUb29sQ29udGV4dCA9IGNyZWF0ZUNvbnRleHQ8VG9vbENvbnRleHRWYWx1ZSB8IG51bGw+KG51bGwpO1xuXG4vLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbi8vIFByb3ZpZGVyXG5cbmV4cG9ydCBmdW5jdGlvbiBUb29sUHJvdmlkZXIoe1xuICBjaGlsZHJlbixcbiAgdG9vbHMgPSBERUZBVUxUX1RPT0xTLFxuICBpbml0aWFsID0gJ21vdmUnLFxufToge1xuICBjaGlsZHJlbjogUmVhY3ROb2RlO1xuICB0b29scz86IHJlYWRvbmx5IFRvb2xEZXNjcmlwdG9yW107XG4gIGluaXRpYWw/OiBUb29sO1xufSkge1xuICBjb25zdCBbdG9vbCwgc2V0VG9vbFN0YXRlXSA9IHVzZVN0YXRlPFRvb2w+KGluaXRpYWwpO1xuICBjb25zdCBbc3RpY2t5LCBzZXRTdGlja3ldID0gdXNlU3RhdGU8eyB0b29sOiBUb29sIHwgbnVsbDsgbG9ja2VkOiBib29sZWFuIH0+KCgpID0+ICh7XG4gICAgdG9vbDogbnVsbCxcbiAgICBsb2NrZWQ6IGZhbHNlLFxuICB9KSk7XG4gIGNvbnN0IHNldFRvb2wgPSB1c2VDYWxsYmFjaygodDogVG9vbCkgPT4ge1xuICAgIHNldFRvb2xTdGF0ZSh0KTtcbiAgICAvLyBTaW5nbGUtY2xpY2sgb24gYSBkaWZmZXJlbnQgdG9vbCBjbGVhcnMgYW55IHN0aWNreSBsb2NrIOKAlCBzdGlja3kgaXNcbiAgICAvLyBhIHBlci10b29sIGZsYWcsIG5vdCBnbG9iYWwuXG4gICAgc2V0U3RpY2t5KChwcmV2KSA9PiAocHJldi5sb2NrZWQgJiYgcHJldi50b29sID09PSB0ID8gcHJldiA6IHsgdG9vbDogbnVsbCwgbG9ja2VkOiBmYWxzZSB9KSk7XG4gIH0sIFtdKTtcbiAgY29uc3QgdG9nZ2xlU3RpY2t5ID0gdXNlQ2FsbGJhY2soKHQ6IFRvb2wpID0+IHtcbiAgICBzZXRTdGlja3koKHByZXYpID0+IHtcbiAgICAgIGlmIChwcmV2LmxvY2tlZCAmJiBwcmV2LnRvb2wgPT09IHQpIHJldHVybiB7IHRvb2w6IG51bGwsIGxvY2tlZDogZmFsc2UgfTtcbiAgICAgIHJldHVybiB7IHRvb2w6IHQsIGxvY2tlZDogdHJ1ZSB9O1xuICAgIH0pO1xuICAgIHNldFRvb2xTdGF0ZSh0KTtcbiAgfSwgW10pO1xuICBjb25zdCBjbGVhclN0aWNreSA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBzZXRTdGlja3koeyB0b29sOiBudWxsLCBsb2NrZWQ6IGZhbHNlIH0pO1xuICB9LCBbXSk7XG4gIGNvbnN0IFtzaGFwZUtpbmQsIHNldFNoYXBlS2luZF0gPSB1c2VTdGF0ZTxTaGFwZUtpbmQ+KCdzcXVhcmUnKTtcblxuICAvLyBDdXJzb3Igc3luYyDigJQgYXBwbGllZCBpbnNpZGUgdGhlIGNhbnZhcyAodGhpcyBob29rIHJ1bnMgaW4gdGhlIGNhbnZhc1xuICAvLyBjb250ZXh0KS4gVGhlIGFjdGl2ZSB0b29sJ3MgY3Vyc29yIGlzIHNldCBvbiA8Ym9keT4gQU5EIGZvcmNlZCBhY3Jvc3MgdGhlXG4gIC8vIHdob2xlIGNhbnZhcyB3b3JraW5nIGFyZWEgdmlhIGFuIGAhaW1wb3J0YW50YCBydWxlLCBzbyB0aGUgY3VzdG9tIGN1cnNvclxuICAvLyBzaG93cyBFVkVSWVdIRVJFIOKAlCBpbmNsdWRpbmcgb3ZlciBhcnRib2FyZCBDT05URU5ULCB3aG9zZSBvd24gYGN1cnNvcjpcbiAgLy8gcG9pbnRlcmAvYHRleHRgL+KApiB3b3VsZCBvdGhlcndpc2Ugd2luIChQaGFzZSAyNCwgdGhlIFwiY3VzdG9tIGN1cnNvcnMgaW4gdGhlXG4gIC8vIHdob2xlIGFwcFwiIHJlcXVpcmVtZW50OyBGaWdKYW0gYmVoYXZpb3VyKS4gQ2hyb21lIHRoYXQgbGl2ZXMgT1VUU0lERVxuICAvLyBgLmRjLXdvcmxkYCAodG9vbCBwYWxldHRlLCBjb250ZXh0IHRvb2xiYXIsIHJlc2l6ZSBoYW5kbGVzKSBpcyBpbnRlbnRpb25hbGx5XG4gIC8vIE5PVCBtYXRjaGVkLCBzbyBpdHMgYnV0dG9ucy9oYW5kbGVzIGtlZXAgdGhlaXIgYWZmb3JkYW5jZSBjdXJzb3JzLiBUaGVcbiAgLy8gdmlld3BvcnQtY29udHJvbGxlciBzdGlsbCBvd25zIHRoZSBncmFiL2dyYWJiaW5nIHN3YXAgZHVyaW5nIHNwYWNlLXBhbi5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykgcmV0dXJuO1xuICAgIGNvbnN0IGRlc2MgPSB0b29scy5maW5kKCh0KSA9PiB0LmlkID09PSB0b29sKTtcbiAgICBpZiAoIWRlc2MpIHJldHVybjtcbiAgICBjb25zdCBwcmV2ID0gZG9jdW1lbnQuYm9keS5zdHlsZS5jdXJzb3I7XG4gICAgZG9jdW1lbnQuYm9keS5zdHlsZS5jdXJzb3IgPSBkZXNjLmN1cnNvcjtcbiAgICBsZXQgc3R5bGVFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkYy10b29sLWN1cnNvcicpIGFzIEhUTUxTdHlsZUVsZW1lbnQgfCBudWxsO1xuICAgIGlmICghc3R5bGVFbCkge1xuICAgICAgc3R5bGVFbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJyk7XG4gICAgICBzdHlsZUVsLmlkID0gJ2RjLXRvb2wtY3Vyc29yJztcbiAgICAgIGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoc3R5bGVFbCk7XG4gICAgfVxuICAgIC8vIFRydWx5IEdMT0JBTCBpbnNpZGUgdGhlIGNhbnZhcyBkb2N1bWVudCDigJQgYCpgIHNvIGl0IGNvdmVycyB0aGUgZW1wdHkgZ3JpZFxuICAgIC8vIGhvc3QsIGAuZGMtd29ybGRgLCBldmVyeSBhcnRib2FyZCArIGl0cyBjb250ZW50LCBBTkQgdGhlIGZsb2F0aW5nIGNocm9tZVxuICAgIC8vIChtaW5pbWFwLCB0b29sYmFyKS4gVGhlIGVhcmxpZXIgYC5kYy13b3JsZGAtc2NvcGVkIHJ1bGUgbGVmdCB0aGUgZW1wdHlcbiAgICAvLyBjYW52YXMgLyBtaW5pbWFwIG9uIHRoZWlyIG93biBjdXJzb3JzOyB0aGUgYnJpZWYgaXMgXCJwcm9zdMSbIHbFoXVkZVwiLiAoTWlycm9yc1xuICAgIC8vIHRoZSBvdXRlci1zaGVsbCBgKmAgcnVsZSBzbyBib3RoIGRvY3VtZW50cyBhcmUgdW5pZm9ybWx5IGNvdmVyZWQuKVxuICAgIHN0eWxlRWwudGV4dENvbnRlbnQgPSBgKiB7IGN1cnNvcjogJHtkZXNjLmN1cnNvcn0gIWltcG9ydGFudDsgfWA7XG4gICAgLy8gUGhhc2UgMjQg4oCUIGJyb2FkY2FzdCB0aGUgYWN0aXZlIHRvb2wgVE9LRU4gdG8gdGhlIE9VVEVSIGFwcCBzaGVsbCAodGhpc1xuICAgIC8vIGhvb2sgcnVucyBpbiB0aGUgY2FudmFzIGlmcmFtZSkgc28gdGhlIHNoZWxsIHNob3dzIHRoZSBzYW1lIGN1c3RvbSBjdXJzb3JcbiAgICAvLyBhY3Jvc3MgdGhlIHdob2xlIG1hdWRlIFVJIChzaWRlYmFyIC8gdG9wIGJhcikuIFdlIHNlbmQgdGhlIHRvb2wgKmlkKiwgTk9UXG4gICAgLy8gdGhlIGN1cnNvciBzdHJpbmc6IHRoZSBzaGVsbCByZXNvbHZlcyBpdCBhZ2FpbnN0IGl0cyBvd24gdHJ1c3RlZFxuICAgIC8vIFRPT0xfQ1VSU09SUyBjb3B5IChyZXNvbHZlVG9vbEN1cnNvciksIHNvIGFuIHVudHJ1c3RlZCBzeW5jZWQgY2FudmFzXG4gICAgLy8gKEREUi0wNTQpIGNhbiBvbmx5IHBpY2sgYSBrbm93biwgYWx3YXlzLXZpc2libGUgZ2x5cGgg4oCUIGl0IGNhbid0IGluamVjdCBhblxuICAgIC8vIGludmlzaWJsZS9kaXNwbGFjZWQgY3Vyc29yIGFzIGEgY2xpY2tqYWNraW5nIGFpZCAocGhhc2UtMjQgZXRoaWNhbC1oYWNrZXJcbiAgICAvLyBGaW5kaW5nIDI7IEREUi0wNjcpLlxuICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cucGFyZW50ICYmIHdpbmRvdy5wYXJlbnQgIT09IHdpbmRvdykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgd2luZG93LnBhcmVudC5wb3N0TWVzc2FnZSh7IGRnbjogJ3Rvb2wtY3Vyc29yJywgdG9vbCB9LCAnKicpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8qIGNyb3NzLW9yaWdpbiBwYXJlbnQgcmVqZWN0ZWQg4oCUIHNoZWxsIGtlZXBzIGl0cyBkZWZhdWx0IGN1cnNvciAqL1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgZG9jdW1lbnQuYm9keS5zdHlsZS5jdXJzb3IgPSBwcmV2O1xuICAgICAgY29uc3QgZWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGMtdG9vbC1jdXJzb3InKTtcbiAgICAgIGlmIChlbCkgZWwudGV4dENvbnRlbnQgPSAnJztcbiAgICB9O1xuICB9LCBbdG9vbCwgdG9vbHNdKTtcblxuICBjb25zdCB2YWx1ZSA9IHVzZU1lbW88VG9vbENvbnRleHRWYWx1ZT4oXG4gICAgKCkgPT4gKHsgdG9vbCwgc2V0VG9vbCwgdG9vbHMsIHN0aWNreSwgdG9nZ2xlU3RpY2t5LCBjbGVhclN0aWNreSwgc2hhcGVLaW5kLCBzZXRTaGFwZUtpbmQgfSksXG4gICAgW3Rvb2wsIHNldFRvb2wsIHRvb2xzLCBzdGlja3ksIHRvZ2dsZVN0aWNreSwgY2xlYXJTdGlja3ksIHNoYXBlS2luZF1cbiAgKTtcblxuICByZXR1cm4gPFRvb2xDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXt2YWx1ZX0+e2NoaWxkcmVufTwvVG9vbENvbnRleHQuUHJvdmlkZXI+O1xufVxuXG4vKipcbiAqIE1vdW50IGEgYFRvb2xQcm92aWRlcmAgb25seSB3aGVuIG5vbmUgZXhpc3RzIGFib3ZlIHVzLiBXaGVuIHRoZSBzaGVsbC1vd25lZFxuICogY29tbWVudCBtb3VudCBsYXllciAoY2FudmFzLWNvbW1lbnQtbW91bnQudHN4KSBhbHJlYWR5IHByb3ZpZGVzIG9uZSxcbiAqIGBEZXNpZ25DYW52YXNgIGNvbnN1bWVzIHRoYXQgaW5zdGFuY2UgaW5zdGVhZCBvZiBkb3VibGUtbW91bnRpbmcuIFRoZSBob29rXG4gKiBpcyBjYWxsZWQgdW5jb25kaXRpb25hbGx5OyBvbmx5IHRoZSByZXR1cm5lZCB0cmVlIGJyYW5jaGVzIChob29rIHJ1bGVzKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIE1heWJlVG9vbFByb3ZpZGVyKHsgY2hpbGRyZW4gfTogeyBjaGlsZHJlbjogUmVhY3ROb2RlIH0pIHtcbiAgY29uc3Qgb3V0ZXIgPSB1c2VDb250ZXh0KFRvb2xDb250ZXh0KTtcbiAgaWYgKG91dGVyKSByZXR1cm4gPD57Y2hpbGRyZW59PC8+O1xuICByZXR1cm4gPFRvb2xQcm92aWRlcj57Y2hpbGRyZW59PC9Ub29sUHJvdmlkZXI+O1xufVxuXG4vLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbi8vIEhvb2tcblxuZXhwb3J0IGZ1bmN0aW9uIHVzZVRvb2xNb2RlKCk6IFRvb2xDb250ZXh0VmFsdWUge1xuICBjb25zdCBjdHggPSB1c2VDb250ZXh0KFRvb2xDb250ZXh0KTtcbiAgaWYgKCFjdHgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3VzZVRvb2xNb2RlIG11c3QgYmUgdXNlZCBpbnNpZGUgPFRvb2xQcm92aWRlcj4nKTtcbiAgfVxuICByZXR1cm4gY3R4O1xufVxuXG4vKipcbiAqIFJlYWQtb25seSB2YXJpYW50IOKAlCByZXR1cm5zIGBudWxsYCB3aGVuIG5vIHByb3ZpZGVyIG1vdW50ZWQuIFVzZWQgYnlcbiAqIGNvbXBvbmVudHMgdGhhdCBjYW4gcmVuZGVyIG91dHNpZGUgYSBUb29sUHJvdmlkZXIgdHJlZSAodGhlIGlucHV0XG4gKiByb3V0ZXIncyBvcHRpb25hbCBwYXRoKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVzZVRvb2xNb2RlT3B0aW9uYWwoKTogVG9vbENvbnRleHRWYWx1ZSB8IG51bGwge1xuICByZXR1cm4gdXNlQ29udGV4dChUb29sQ29udGV4dCk7XG59XG4iLAogICAgIi8qKlxuICogQGZpbGUgICAgICAgY2FudmFzLWN1cnNvcnMudHMg4oCUIFBoYXNlIDI0IGN1c3RvbSB0b29sIGN1cnNvcnMgKEtlbm5leSBDQzApXG4gKiBAc2NvcGUgICAgICBwbHVnaW5zL2Rlc2lnbi9kZXYtc2VydmVyL2NhbnZhcy1jdXJzb3JzLnRzXG4gKiBAcHVycG9zZSAgICBGaWdKYW0vRmlnbWEtc3R5bGUgY3VzdG9tIGN1cnNvcnMgZm9yIEVWRVJZIGNhbnZhcyB0b29sLiBUaGVcbiAqICAgICAgICAgICAgIG5hdGl2ZSBjcm9zc2hhaXIgLyB0ZXh0IC8gYXJyb3cgY3Vyc29ycyBhcmUgdGlueSArIHRoaW4gYW5kXG4gKiAgICAgICAgICAgICB2YW5pc2ggb24gYnVzeSBjYW52YXNlczsgdGhlc2UgYXJlIDMyw5czMiBTVkcgY3Vyc29ycyB0aGF0IHJlYWQgb25cbiAqICAgICAgICAgICAgIGFueSBiYWNrZ3JvdW5kLlxuICpcbiAqICAgICAgICAgICAgIFBoYXNlIDI0IOKAlCBBTEwgdG9vbHMgZHJhdyBmcm9tIE9ORSBsaWJyYXJ5LCB0aGUgKipLZW5uZXkgQ3Vyc29yXG4gKiAgICAgICAgICAgICBQYWNrICgxLjEpKiogXCJPdXRsaW5lXCIgc2V0LCB3aGljaCBpcyAqKkNDMCAvIHB1YmxpYyBkb21haW4qKlxuICogICAgICAgICAgICAgKGh0dHBzOi8va2VubmV5Lm5sL2Fzc2V0cy9jdXJzb3ItcGFjayDigJQgbm8gYXR0cmlidXRpb24gcmVxdWlyZWQsXG4gKiAgICAgICAgICAgICByZWRpc3RyaWJ1dGFibGUgaW5zaWRlIHRoaXMgTUlUIHBhY2thZ2UgKyBtYXJrZXRwbGFjZSBjbG9uZSkuIFNlZVxuICogICAgICAgICAgICAgRERSLTA2NyBmb3IgdGhlIGxpY2VuY2UgZ2F0ZSAoQmliYXRhIEdQTC0zLjAgd2FzIHJlamVjdGVkIGFzXG4gKiAgICAgICAgICAgICBjb3B5bGVmdCkuIE9uZSBsaWJyYXJ5ID0gb25lIHZpc3VhbCBpZGVudGl0eSBhY3Jvc3MgbW92ZSAvIGhhbmQgL1xuICogICAgICAgICAgICAgY29tbWVudCAvIHBlbiAvIHNoYXBlIC8gc3RpY2t5IC8gdGV4dCAvIGVyYXNlci4gVGhlIGdseXBoIHBhdGhzXG4gKiAgICAgICAgICAgICBhcmUgS2VubmV5J3M7IHdlIFJFQ09MT1VSIHRoZW0gKHNlZSBga2VubmV5KClgKSB0byBhIGRhcmstZ2x5cGggK1xuICogICAgICAgICAgICAgd2hpdGUtaGFsbyB0cmVhdG1lbnQgc28gdGhleSByZWFkIGNyaXNwbHkgb24gbGlnaHQgQU5EIGRhcmtcbiAqICAgICAgICAgICAgIGNhbnZhc2VzLiBQZXItdG9vbCBnbHlwaCBtYXA6XG4gKiAgICAgICAgICAgICAgIG1vdmXihpJwb2ludGVyX2EgwrcgaGFuZOKGkmhhbmRfb3BlbiDCtyBjb21tZW504oaSbWVzc2FnZV9kb3RzX3NxdWFyZSDCt1xuICogICAgICAgICAgICAgICBwZW7ihpJkcmF3aW5nX3BlbmNpbCDCtyBzaGFwZeKGkmxpbmVfY3Jvc3MgwrcgZXJhc2Vy4oaSZHJhd2luZ19lcmFzZXIuXG4gKiAgICAgICAgICAgICB0ZXh0IChJLWJlYW0pICsgc3RpY2t5IChmb2xkZWQtY29ybmVyIG5vdGUpIGhhdmUgbm8gY2xlYW4gS2VubmV5XG4gKiAgICAgICAgICAgICBlcXVpdmFsZW50LCBzbyB0aGV5IGFyZSBBVVRIT1JFRCBpbiB0aGUgaWRlbnRpY2FsIGRhcmstZ2x5cGggK1xuICogICAgICAgICAgICAgd2hpdGUtaGFsbyB0cmVhdG1lbnQgdG8ga2VlcCBvbmUgdmlzdWFsIGlkZW50aXR5LlxuICpcbiAqICAgICAgICAgICAgIERlbGl2ZXJlZCBhcyBDU1MgYGN1cnNvcjogdXJsKFwiZGF0YTppbWFnZS9zdmcreG1sLOKAplwiKSBoeCBoeSwgZmJgXG4gKiAgICAgICAgICAgICDigJQgbm8gcnVudGltZSBkZXBlbmRlbmN5LCBubyBhc3NldCBmaWxlcy4gMzLDlzMyIGlzIHRoZVxuICogICAgICAgICAgICAgY3Jvc3MtYnJvd3Nlci1zYWZlIGNlaWxpbmc7IChoeCwgaHkpIGlzIHRoZSBjbGljayBob3RzcG90LlxuICovXG5cbmltcG9ydCB0eXBlIHsgVG9vbCB9IGZyb20gJy4vaW5wdXQtcm91dGVyLnRzeCc7XG5cbi8qKiBCdWlsZCBhIENTUyBjdXJzb3IgdmFsdWUgZnJvbSBhbiBpbmxpbmUgU1ZHICsgaG90c3BvdCArIG5hdGl2ZSBmYWxsYmFjay4gKi9cbmZ1bmN0aW9uIHN2Z0N1cnNvcihzdmc6IHN0cmluZywgaHg6IG51bWJlciwgaHk6IG51bWJlciwgZmFsbGJhY2s6IHN0cmluZyk6IHN0cmluZyB7XG4gIC8vIGVuY29kZVVSSUNvbXBvbmVudCBpcyB0aGUgc2FmZXN0IGVzY2FwaW5nIGZvciBhIGRhdGE6IFVSSSBpbnNpZGUgdXJsKFwi4oCmXCIpLlxuICByZXR1cm4gYHVybChcImRhdGE6aW1hZ2Uvc3ZnK3htbCwke2VuY29kZVVSSUNvbXBvbmVudChzdmcudHJpbSgpKX1cIikgJHtoeH0gJHtoeX0sICR7ZmFsbGJhY2t9YDtcbn1cblxuLy8gUGhhc2UgMjQg4oCUIDI0cHggcmVuZGVyZWQgYm94IChkb3duIGZyb20gMzIpIHNvIGN1cnNvcnMgYXJlbid0IG92ZXJzaXplZDsgdGhlXG4vLyBnbHlwaCBjb29yZHMgc3RheSBpbiB0aGUgMzItdW5pdCB2aWV3Qm94IGFuZCBzY2FsZSBpbnRvIDI0cHguIEhvdHNwb3RzIGFyZVxuLy8gc2NhbGVkIHRvIG1hdGNoIChzZWUgdGhlIGdlbmVyYXRvcikuXG5jb25zdCBXID0gYHdpZHRoPScyNCcgaGVpZ2h0PScyNCcgdmlld0JveD0nMCAwIDMyIDMyJyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnYDtcbmNvbnN0IElOSyA9ICcjMWYxZjFmJztcbmNvbnN0IEhBTE8gPSBcInN0cm9rZT0nI2ZmZmZmZicgc3Ryb2tlLWxpbmVqb2luPSdyb3VuZCcgc3Ryb2tlLWxpbmVjYXA9J3JvdW5kJ1wiO1xuXG4vLyBLZW5uZXkgQ0MwIGdseXBoLCByZWNvbG91cmVkIHRvIGEgRmlnSmFtLXN0eWxlICoqZGFyayBnbHlwaCArIHdoaXRlIGhhbG8qKjpcbi8vIEtlbm5leSdzIG91dGxpbmUgYmFuZCAoYGJgKSBpcyBwYWludGVkIFdISVRFICh0aGUgaGFsbykgYW5kIGl0cyBpbm5lciBmaWxsXG4vLyAoYHdgKSBpcyBwYWludGVkIGRhcmsgSU5LLiBSZWFkcyBjcmlzcGx5IG9uIGEgTElHSFQgY2FudmFzIChzb2xpZCBkYXJrIGdseXBoKVxuLy8gQU5EIGEgZGFyayBvbmUgKHdoaXRlIGhhbG8gZWRnZSkuXG5mdW5jdGlvbiBrZW5uZXkoYjogc3RyaW5nLCB3OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYDxzdmcgJHtXfT48cGF0aCBmaWxsPScjZmZmZmZmJyBkPScke2J9Jy8+PHBhdGggZmlsbD0nJHtJTkt9JyBkPScke3d9Jy8+PC9zdmc+YDtcbn1cblxuY29uc3QgTU9WRSA9IHN2Z0N1cnNvcihcbiAga2VubmV5KFxuICAgICdNMTYuNzUgMjMuOSBMMjAgMjIuNTUgMjAuNSAyMi4xNSAyMC4zNSAyMS41NSAxOC40IDE3Ljc1IDIxLjI1IDE3LjI1IDIxLjc1IDE3IDIyIDE2LjQ1IFEyMiAxNi4xIDIxLjYgMTUuOSBMMTEuNDUgOC4yIDExLjQgOC4yIDEwLjg1IDggMTAuMiA4LjI1IDEwIDguOCAxMCAyMC43NSBRMTAgMjEuNTUgMTAuODUgMjEuNTUgTDExLjQgMjEuMzUgMTMuNiAxOS44IDE1LjYgMjMuNSAxNi4wNSAyMy45NSAxNi43NSAyMy45IE04IDguOCBRNy45NSA4LjA1IDguNTUgNy4xNSBMOC45NSA2Ljc1IFE5LjggNiAxMC44NSA2IDExLjU1IDYgMTIuMiA2LjM1IEwxMi42NSA2LjYgMjIuNjUgMTQuMTUgUTI0LjE1IDE1IDI0IDE2LjQ1IDI0LjA1IDE3LjU1IDIzLjIgMTguNDUgTDIzLjA1IDE4LjU1IFEyMi4xIDE5LjMgMjEuNDUgMTkuMyBMMjIuMSAyMC41NSBRMjIuNSAyMS4yIDIyLjUgMjIuMTUgTDIyLjA1IDIzLjQgMjAuOSAyNC4zNSAyMC44IDI0LjQgMTcuNTUgMjUuNzUgMTUuMjUgMjUuOCBRMTQuMTUgMjUuNCAxMy43NSAyNC4yNSBMMTIuOTUgMjIuNzUgMTIuNjUgMjIuOSAxMi41NSAyMyBRMTEuNzUgMjMuNTUgMTAuODUgMjMuNTUgNy45NSAyMy41NSA4IDIwLjc1IEw4IDguOCcsXG4gICAgJ00xNi43NSAyMy45IEwxNi4wNSAyMy45NSAxNS42IDIzLjUgMTMuNiAxOS44IDExLjQgMjEuMzUgMTAuODUgMjEuNTUgUTEwIDIxLjU1IDEwIDIwLjc1IEwxMCA4LjggMTAuMiA4LjI1IDEwLjg1IDggMTEuNCA4LjIgMTEuNDUgOC4yIDIxLjYgMTUuOSBRMjIgMTYuMSAyMiAxNi40NSBMMjEuNzUgMTcgMjEuMjUgMTcuMjUgMTguNCAxNy43NSAyMC4zNSAyMS41NSAyMC41IDIyLjE1IDIwIDIyLjU1IDE2Ljc1IDIzLjknXG4gICksXG4gIDYsXG4gIDUsXG4gICdkZWZhdWx0J1xuKTtcbmNvbnN0IEhBTkQgPSBzdmdDdXJzb3IoXG4gIGtlbm5leShcbiAgICAnTTI4LjU1IDE3LjggUTI5LjQgMjAuMyAyOC43NSAyMi44IEwyOC43IDIzIDI4LjE1IDI0LjU1IDI4LjA1IDI0Ljc1IFEyNi40IDI4LjIgMjIuNzUgMjkuNCBMMjIuNDUgMjkuNSAxOCAyOS45IDE3Ljc1IDI5Ljg1IFExNS44IDI5LjI1IDEzLjggMjguMSBMMTMuNDUgMjcuOTUgUTEyIDI3LjA1IDEwLjM1IDI2LjggTDEwLjI1IDI2Ljc1IDcuOSAyNi43IDcuOCAyNi43IFE2LjEgMjYuOSA0LjggMjUuOCBMNC43NSAyNS44IDQuNjUgMjUuNyA0LjYgMjUuNjUgUTMuMjUgMjQuNSAzLjA1IDIyLjg1IEwzIDIyLjc1IFEyLjggMjAuOTUgNCAxOS41IDUuMDUgMTguMTUgNi43NSAxNy45NSBMOC40IDE3LjkgNy41IDE1LjU1IDcuMyAxNS4yIDcuMiAxNSA1IDEwLjk1IFEzLjkgOS4xNSA0LjMgNy43NSBMNC40IDcuNSBRNC43NSA2LjE1IDYuNDUgNS4yIDkgMy42NSAxMSA1IDExLjA1IDQuMSAxMS41IDMuNDUgMTIuMTUgMi4xIDE0LjIgMS42IEwxNC4zNSAxLjYgUTE4LjA1IDAuNiAxOS42IDQuNCBMMTkuNjUgNC41NSBRMjAuNzUgMy42NSAyMi43IDMuNzUgTDIyLjc1IDMuNzUgUTI2Ljc1IDQgMjcgOC4xNSBMMjcgOC4yNSAyNyA4LjM1IDI3IDguNDUgUTI2LjkgMTAuNzUgMjcuMSAxMi42IDI3LjE1IDE0LjY1IDI4LjIgMTYuNzUgTDI4LjU1IDE3LjggTTI2LjY1IDE4LjQgTDI2LjEgMTYuOCAyNi4xIDE2Ljg1IFEyNC44IDEzLjcgMjUgOC4zNSBMMjUgOC4yNSBRMjQuODUgNS45IDIyLjYgNS43NSAyMC43IDUuNjUgMjAuNCA3LjM1IEwyMC4xIDcuOTUgMTkuNSA4LjIgMTguODUgOC4wNSAxOC40NSA3LjUgMTcuNzUgNS4xNSBRMTYuODUgMi45NSAxNC43IDMuNTUgTDE0LjY1IDMuNTUgUTEyLjU1IDQuMDUgMTMuMTUgNi4xNSBMMTMuODUgOC43NSAxMy43NSA5LjQ1IDEzLjI1IDkuOTUgMTIuNTUgOS45NSAxMiA5LjU1IDEwLjkgNy43IFE5LjUgNS43IDcuNDUgNi45IDYuNSA3LjQ1IDYuMjUgOC4xNSA2LjEgOC45IDYuNyA5Ljg1IDkuMiAxMy45IDEwLjggMTguNjUgTDEwLjggMTkuMyAxMC40IDE5LjggOS43NSAxOS45NSBROC4zNSAxOS44IDYuOTUgMTkuOTUgNi4xIDIwLjA1IDUuNTUgMjAuNzUgNC45IDIxLjU1IDUgMjIuNTUgNS4xNSAyMy41NSA2IDI0LjIgTDYuMDUgMjQuMjUgUTYuNzUgMjQuODUgNy42NSAyNC43IEw3LjcgMjQuNyAxMC42NSAyNC44IFExMi43IDI1LjE1IDE0LjQ1IDI2LjIgTDE0LjUgMjYuMiBRMTYuNCAyNy4zNSAxOC4zIDI3LjkgTDIyLjA1IDI3LjUgMjIuMSAyNy41IFEyNC45NSAyNi41NSAyNi4yNSAyMy44NSBMMjYuOCAyMi4zIFEyNy4zIDIwLjM1IDI2LjY1IDE4LjQnLFxuICAgICdNMjYuNjUgMTguNCBRMjcuMyAyMC4zNSAyNi44IDIyLjMgTDI2LjI1IDIzLjg1IFEyNC45NSAyNi41NSAyMi4xIDI3LjUgTDIyLjA1IDI3LjUgMTguMyAyNy45IFExNi40IDI3LjM1IDE0LjUgMjYuMiBMMTQuNDUgMjYuMiBRMTIuNyAyNS4xNSAxMC42NSAyNC44IEw3LjcgMjQuNyA3LjY1IDI0LjcgUTYuNzUgMjQuODUgNi4wNSAyNC4yNSBMNiAyNC4yIFE1LjE1IDIzLjU1IDUgMjIuNTUgNC45IDIxLjU1IDUuNTUgMjAuNzUgNi4xIDIwLjA1IDYuOTUgMTkuOTUgOC4zNSAxOS44IDkuNzUgMTkuOTUgTDEwLjQgMTkuOCAxMC44IDE5LjMgMTAuOCAxOC42NSBROS4yIDEzLjkgNi43IDkuODUgNi4xIDguOSA2LjI1IDguMTUgNi41IDcuNDUgNy40NSA2LjkgOS41IDUuNyAxMC45IDcuNyBMMTIgOS41NSAxMi41NSA5Ljk1IDEzLjI1IDkuOTUgMTMuNzUgOS40NSAxMy44NSA4Ljc1IDEzLjE1IDYuMTUgUTEyLjU1IDQuMDUgMTQuNjUgMy41NSBMMTQuNyAzLjU1IFExNi44NSAyLjk1IDE3Ljc1IDUuMTUgTDE4LjQ1IDcuNSAxOC44NSA4LjA1IDE5LjUgOC4yIDIwLjEgNy45NSAyMC40IDcuMzUgUTIwLjcgNS42NSAyMi42IDUuNzUgMjQuODUgNS45IDI1IDguMjUgTDI1IDguMzUgUTI0LjggMTMuNyAyNi4xIDE2Ljg1IEwyNi4xIDE2LjggMjYuNjUgMTguNCdcbiAgKSxcbiAgMTIsXG4gIDEyLFxuICAnZ3JhYidcbik7XG5jb25zdCBDT01NRU5UID0gc3ZnQ3Vyc29yKFxuICBrZW5uZXkoXG4gICAgJ004IDQgUTQgNCA0IDggTDQgMjAgUTQgMjQgOCAyNCBMMTIgMjQgMTUuMyAyNy4zIDE2IDI3LjYgMTYuNyAyNy4zIDIwIDI0IDI0IDI0IFEyOCAyNCAyOCAyMCBMMjggOCBRMjggNCAyNCA0IEw4IDQgTTI0IDIgUTMwIDIgMzAgOCBMMzAgMjAgUTMwIDI2IDI0IDI2IEwyMC44NSAyNiAxOC4xNSAyOC43NSBRMTcuMiAyOS42IDE2IDI5LjYgMTQuOCAyOS42IDEzLjkgMjguNzUgTDExLjE1IDI2IDggMjYgUTIgMjYgMiAyMCBMMiA4IFEyIDIgOCAyIEwyNCAyIE0yNCAxNCBRMjQgMTQuODUgMjMuNCAxNS40IDIyLjg1IDE2IDIyIDE2IDIxLjE1IDE2IDIwLjU1IDE1LjQgMjAgMTQuODUgMjAgMTQgMjAgMTMuMTUgMjAuNTUgMTIuNTUgMjEuMTUgMTIgMjIgMTIgMjIuODUgMTIgMjMuNCAxMi41NSAyNCAxMy4xNSAyNCAxNCBNMTIgMTQgUTEyIDE0Ljg1IDExLjQgMTUuNCAxMC44NSAxNiAxMCAxNiA5LjE1IDE2IDguNTUgMTUuNCA4IDE0Ljg1IDggMTQgOCAxMy4xNSA4LjU1IDEyLjU1IDkuMTUgMTIgMTAgMTIgMTAuODUgMTIgMTEuNCAxMi41NSAxMiAxMy4xNSAxMiAxNCBNMTggMTQgUTE4IDE0Ljg1IDE3LjQgMTUuNCAxNi44NSAxNiAxNiAxNiAxNS4xNSAxNiAxNC41NSAxNS40IDE0IDE0Ljg1IDE0IDE0IDE0IDEzLjE1IDE0LjU1IDEyLjU1IDE1LjE1IDEyIDE2IDEyIDE2Ljg1IDEyIDE3LjQgMTIuNTUgMTggMTMuMTUgMTggMTQnLFxuICAgICdNMTggMTQgUTE4IDEzLjE1IDE3LjQgMTIuNTUgMTYuODUgMTIgMTYgMTIgMTUuMTUgMTIgMTQuNTUgMTIuNTUgMTQgMTMuMTUgMTQgMTQgMTQgMTQuODUgMTQuNTUgMTUuNCAxNS4xNSAxNiAxNiAxNiAxNi44NSAxNiAxNy40IDE1LjQgMTggMTQuODUgMTggMTQgTTggNCBMMjQgNCBRMjggNCAyOCA4IEwyOCAyMCBRMjggMjQgMjQgMjQgTDIwIDI0IDE2LjcgMjcuMyAxNiAyNy42IDE1LjMgMjcuMyAxMiAyNCA4IDI0IFE0IDI0IDQgMjAgTDQgOCBRNCA0IDggNCBNMTIgMTQgUTEyIDEzLjE1IDExLjQgMTIuNTUgMTAuODUgMTIgMTAgMTIgOS4xNSAxMiA4LjU1IDEyLjU1IDggMTMuMTUgOCAxNCA4IDE0Ljg1IDguNTUgMTUuNCA5LjE1IDE2IDEwIDE2IDEwLjg1IDE2IDExLjQgMTUuNCAxMiAxNC44NSAxMiAxNCBNMjQgMTQgUTI0IDEzLjE1IDIzLjQgMTIuNTUgMjIuODUgMTIgMjIgMTIgMjEuMTUgMTIgMjAuNTUgMTIuNTUgMjAgMTMuMTUgMjAgMTQgMjAgMTQuODUgMjAuNTUgMTUuNCAyMS4xNSAxNiAyMiAxNiAyMi44NSAxNiAyMy40IDE1LjQgMjQgMTQuODUgMjQgMTQnXG4gICksXG4gIDEyLFxuICAyMixcbiAgJ2Nyb3NzaGFpcidcbik7XG5jb25zdCBQRU4gPSBzdmdDdXJzb3IoXG4gIGtlbm5leShcbiAgICAnTTUuMTUgMTAuODUgUTQgOS42NSA0IDguMSBMNCA3Ljk1IDQgNy44NSBRMy45NSA2LjIgNS4xIDUuMTUgNi4yNSA0IDcuODUgNCBMNy45NSA0IDguMSA0IFE5LjY1IDQgMTAuODUgNS4xNSBMMTEgNS4zIDE0LjMgNS4yNSBRMTUuMTUgNS4yNSAxNS43NSA1Ljg1IEwyOS45IDIwIFEzMSAyMS4xNSAzMSAyMi43NSBMMzEgMjIuODUgMzEgMjMgUTMxLjA1IDI0LjUgMjkuOSAyNS43IEwyOS41NSAyNS45NSAyNS42NSAyOS45IDI1LjY1IDI5Ljk1IFEyNC40NSAzMS4xIDIyLjc1IDMxLjEgMjEuMiAzMS4xNSAyMCAyOS45NSBMNS44NSAxNS44IFE1LjI1IDE1LjIgNS4yNSAxNC4zNSBMNS4yNSAxMC45NSA1LjE1IDEwLjg1IE0xOS45NSAyNC4yIEwxOC41NSAyMi44IDIyLjggMTguNTUgMjQuMiAxOS45NSAxOS45NSAyNC4yIE0yOC40NSAyMS40IEwxNC4zIDcuMjUgMTAuMTUgNy4zIDkuNCA2LjU1IFE4LjggNS45NSA3Ljk1IDYgNy4xIDUuOTUgNi41IDYuNTUgNS45NSA3LjEgNiA3Ljk1IDUuOTUgOC44IDYuNTUgOS40IEw3LjI1IDEwLjEgNy4yNSAxNC4zNSAyMS40IDI4LjUgUTIyIDI5LjEgMjIuNzUgMjkuMSAyMy42IDI5LjEgMjQuMiAyOC41IEwyOC40NSAyNC4yNSBRMjkuMDUgMjMuNjUgMjkgMjIuODUgMjkuMDUgMjIgMjguNDUgMjEuNCBNOS4yNSAxMy41IEw5LjI1IDkuMyAxMy41IDkuMjUgMTQuMyAxMC4wNSAxMC4wNSAxNC4zIDkuMjUgMTMuNSBNMTcuMTUgMjEuNCBMMTEuNSAxNS43NSAxNS43NSAxMS41IDIxLjQgMTcuMTUgMTcuMTUgMjEuNCcsXG4gICAgJ00xNy4xNSAyMS40IEwyMS40IDE3LjE1IDE1Ljc1IDExLjUgMTEuNSAxNS43NSAxNy4xNSAyMS40IE0yOC40NSAyMS40IFEyOS4wNSAyMiAyOSAyMi44NSAyOS4wNSAyMy42NSAyOC40NSAyNC4yNSBMMjQuMiAyOC41IFEyMy42IDI5LjEgMjIuNzUgMjkuMSAyMiAyOS4xIDIxLjQgMjguNSBMNy4yNSAxNC4zNSA3LjI1IDEwLjEgNi41NSA5LjQgUTUuOTUgOC44IDYgNy45NSA1Ljk1IDcuMSA2LjUgNi41NSA3LjEgNS45NSA3Ljk1IDYgOC44IDUuOTUgOS40IDYuNTUgTDEwLjE1IDcuMyAxNC4zIDcuMjUgMjguNDUgMjEuNCBNMTkuOTUgMjQuMiBMMjQuMiAxOS45NSAyMi44IDE4LjU1IDE4LjU1IDIyLjggMTkuOTUgMjQuMiBNOS4yNSAxMy41IEwxMC4wNSAxNC4zIDE0LjMgMTAuMDUgMTMuNSA5LjI1IDkuMjUgOS4zIDkuMjUgMTMuNSdcbiAgKSxcbiAgMjAsXG4gIDIwLFxuICAnY3Jvc3NoYWlyJ1xuKTtcbmNvbnN0IENST1NTSEFJUiA9IHN2Z0N1cnNvcihcbiAga2VubmV5KFxuICAgICdNMTcgMiBRMTguMiAyIDE5LjE1IDIuOSAyMCAzLjggMjAgNSBMMjAgMTIgMjcgMTIgUTI4LjIgMTIgMjkuMTUgMTIuOSAzMCAxMy44IDMwIDE1IEwzMCAxNyBRMzAgMTguMiAyOS4xNSAxOS4xNSAyOC4yIDIwIDI3IDIwIEwyMCAyMCAyMCAyNyBRMjAgMjguMiAxOS4xNSAyOS4xNSAxOC4yIDMwIDE3IDMwIEwxNSAzMCBRMTMuOCAzMCAxMi45IDI5LjE1IDEyIDI4LjIgMTIgMjcgTDEyIDIwIDUgMjAgUTMuOCAyMCAyLjkgMTkuMTUgMiAxOC4yIDIgMTcgTDIgMTUgUTIgMTMuOCAyLjkgMTIuOSAzLjggMTIgNSAxMiBMMTIgMTIgMTIgNSBRMTIgMy44IDEyLjkgMi45IDEzLjggMiAxNSAyIEwxNyAyIE0xNCAyNyBMMTQuMyAyNy43IFExNC42IDI4IDE1IDI4IEwxNyAyOCAxNy43IDI3LjcgMTggMjcgMTggMTguMDUgMTguMDUgMTggMjcgMTggUTI3LjQgMTggMjcuNyAxNy43IEwyOCAxNyAyOCAxNSAyNy43IDE0LjMgUTI3LjQgMTQgMjcgMTQgTDE4IDE0IDE4IDUgMTcuNyA0LjMgMTcgNCAxNSA0IFExNC42IDQgMTQuMyA0LjMgMTQgNC42IDE0IDUgTDE0IDE0IDUgMTQgUTQuNiAxNCA0LjMgMTQuMyA0IDE0LjYgNCAxNSBMNCAxNyBRNCAxNy40IDQuMyAxNy43IDQuNiAxOCA1IDE4IEwxNCAxOCAxNCAyNycsXG4gICAgJ00xNCAyNyBMMTQgMTggNSAxOCBRNC42IDE4IDQuMyAxNy43IDQgMTcuNCA0IDE3IEw0IDE1IFE0IDE0LjYgNC4zIDE0LjMgNC42IDE0IDUgMTQgTDE0IDE0IDE0IDUgUTE0IDQuNiAxNC4zIDQuMyAxNC42IDQgMTUgNCBMMTcgNCAxNy43IDQuMyAxOCA1IDE4IDE0IDI3IDE0IFEyNy40IDE0IDI3LjcgMTQuMyBMMjggMTUgMjggMTcgMjcuNyAxNy43IFEyNy40IDE4IDI3IDE4IEwxOC4wNSAxOCAxOCAxOC4wNSAxOCAyNyAxNy43IDI3LjcgMTcgMjggMTUgMjggUTE0LjYgMjggMTQuMyAyNy43IEwxNCAyNydcbiAgKSxcbiAgMTIsXG4gIDEyLFxuICAnY3Jvc3NoYWlyJ1xuKTtcbmNvbnN0IEVSQVNFUiA9IHN2Z0N1cnNvcihcbiAga2VubmV5KFxuICAgICdNMy45IDExLjM1IFEyLjMgMTIuNSAzLjcgMTMuOSBMMTYuNCAyNi42NSBRMTcuODUgMjguMDUgMTkuNDUgMjYuOSBMMjcuNjUgMjEuMTUgUTI5LjMgMjAgMjcuODUgMTguNiBMMTUuMTUgNS44NSBRMTMuNzUgNC40NSAxMi4xIDUuNiBMMy45IDExLjM1IE0xLjA1IDEyLjQgUTEgMTAuOTUgMi43NSA5Ljc1IEwxMC45NSA0IDEwLjk1IDMuOTUgUTE0IDEuODUgMTYuNiA0LjQ1IEwyOS4zIDE3LjIgUTMwLjggMTguNjUgMzAuNTUgMjAuMSAzMC41NSAyMS41NSAyOC44IDIyLjggTDIwLjYgMjguNTUgMjAuNjUgMjguNTUgUTE3LjcgMzAuNjUgMTUgMjguMSBMMTUgMjguMDUgMi4zIDE1LjMgMi4zIDE1LjM1IFEwLjggMTMuODUgMS4wNSAxMi40IE0xMy41IDcgTDE5Ljg1IDEzLjM1IDExLjY1IDE5LjE1IDUuMyAxMi43NSAxMy41IDcnLFxuICAgICdNMTMuNSA3IEw1LjMgMTIuNzUgMTEuNjUgMTkuMTUgMTkuODUgMTMuMzUgMTMuNSA3IE0zLjkgMTEuMzUgTDEyLjEgNS42IFExMy43NSA0LjQ1IDE1LjE1IDUuODUgTDI3Ljg1IDE4LjYgUTI5LjMgMjAgMjcuNjUgMjEuMTUgTDE5LjQ1IDI2LjkgUTE3Ljg1IDI4LjA1IDE2LjQgMjYuNjUgTDMuNyAxMy45IFEyLjMgMTIuNSAzLjkgMTEuMzUnXG4gICksXG4gIDYsXG4gIDE0LFxuICAnY2VsbCdcbik7XG5cbi8vIFRleHQg4oCUIGEgY2xhc3NpYyBJLWJlYW0gKHZlcnRpY2FsIHN0ZW0gKyB0b3AvYm90dG9tIHNlcmlmcykuIEF1dGhvcmVkIGluIHRoZVxuLy8gc2FtZSBkYXJrLUlOSyBnbHlwaCArIHdoaXRlLUhBTE8gdHJlYXRtZW50IGFzIHRoZSBLZW5uZXkgZ2x5cGhzIChLZW5uZXknc1xuLy8gcG9pbnRlcl9pIHJlYWRzIGFzIGEgc21hbGwgYnJhY2tldCwgbm90IGFuIEktYmVhbSkuIEhvdHNwb3QgZGVhZC1jZW50cmUuXG5jb25zdCBURVhUID0gc3ZnQ3Vyc29yKFxuICBgPHN2ZyAke1d9PjxwYXRoIGQ9J00xNiA0VjI4TTExIDRIMjFNMTEgMjhIMjEnIGZpbGw9J25vbmUnICR7SEFMT30gc3Ryb2tlLXdpZHRoPSc1Jy8+PHBhdGggZD0nTTE2IDRWMjhNMTEgNEgyMU0xMSAyOEgyMScgZmlsbD0nbm9uZScgc3Ryb2tlPScke0lOS30nIHN0cm9rZS13aWR0aD0nMi4yNScgc3Ryb2tlLWxpbmVjYXA9J3JvdW5kJy8+PC9zdmc+YCxcbiAgMTIsXG4gIDEyLFxuICAndGV4dCdcbik7XG5cbi8vIFN0aWNreSDigJQgYSBub3RlIHdpdGggYSBwZWVsZWQvZm9sZGVkIHRvcC1yaWdodCBjb3JuZXIgKHRoZSB1bml2ZXJzYWwgc3RpY2t5XG4vLyBnbHlwaCkuIEF1dGhvcmVkIGluIHRoZSBzYW1lIHRyZWF0bWVudCAoS2VubmV5IGhhcyBubyBzdGlja3ktbm90ZSkuIEhvdHNwb3Rcbi8vIGF0IHRoZSBub3RlJ3MgdG9wLWxlZnQsIHdoZXJlIHRoZSBub3RlIGlzIGRyb3BwZWQuXG5jb25zdCBTVElDS1kgPSBzdmdDdXJzb3IoXG4gIGA8c3ZnICR7V30+PHBhdGggZD0nTTYgNUgyMUwyNiAxMFYyN0g2WicgZmlsbD0nJHtJTkt9JyAke0hBTE99IHN0cm9rZS13aWR0aD0nMi41Jy8+PHBhdGggZD0nTTIxIDVWMTFIMjYnIGZpbGw9J25vbmUnICR7SEFMT30gc3Ryb2tlLXdpZHRoPScyLjI1Jy8+PC9zdmc+YCxcbiAgNSxcbiAgNSxcbiAgJ2Nyb3NzaGFpcidcbik7XG5cbi8qKlxuICogVG9vbCDihpIgQ1NTIGN1cnNvciB2YWx1ZS4gUGhhc2UgMjQg4oCUIGV2ZXJ5IHRvb2wgc2hpcHMgYSBLZW5uZXkgZ2x5cGggKG5vXG4gKiBzeXN0ZW0gZmFsbGJhY2sgZm9yIGBtb3ZlYCBhbnltb3JlOyB0aGUgYnJpZWYgaXMgT05FIHVuaWZpZWQgbGlicmFyeSkuIFRoZVxuICogc2luZ2xlIFNoYXBlIHRvb2wgdXNlcyB0aGUgY3Jvc3NoYWlyOyBgcmVjdGAvYGVsbGlwc2VgIHN0YXkga2V5ZWQgKHN0aWxsIGluXG4gKiB0aGUgVG9vbCB1bmlvbikgYnV0IGFyZSBubyBsb25nZXIgZGlyZWN0bHkgc2VsZWN0YWJsZS5cbiAqL1xuLy8gRnJvemVuIHNvIHRoZSBkb2NzdHJpbmcncyBcImZyb3plbiBtYXBcIiBndWFyYW50ZWUgaXMgcmVhbDogYHJlc29sdmVUb29sQ3Vyc29yYFxuLy8gaXMgYSBwdXJlIGxvb2t1cCBpbnRvIHRoaXMgb2JqZWN0LCBhbmQgZnJlZXppbmcgZm9yZWNsb3NlcyBhbnkgc2FtZS1yZWFsbVxuLy8gc2hlbGwtc2lkZSBjb2RlIGV2ZXIgbXV0YXRpbmcgYW4gZW50cnkgb3V0IGZyb20gdW5kZXIgdGhlIGxvb2t1cCAodGhlIGNhbnZhc1xuLy8gcnVucyBjcm9zcy1vcmlnaW4gYW5kIGNhbid0IHJlYWNoIGl0IHJlZ2FyZGxlc3Mg4oCUIHRoaXMgaXMgYmVsdC1hbmQtYnJhY2VzKS5cbmV4cG9ydCBjb25zdCBUT09MX0NVUlNPUlM6IFJlY29yZDxUb29sLCBzdHJpbmc+ID0gT2JqZWN0LmZyZWV6ZSh7XG4gIG1vdmU6IE1PVkUsXG4gIGhhbmQ6IEhBTkQsXG4gIGNvbW1lbnQ6IENPTU1FTlQsXG4gIHBlbjogUEVOLFxuICBzaGFwZTogQ1JPU1NIQUlSLFxuICByZWN0OiBDUk9TU0hBSVIsXG4gIGVsbGlwc2U6IENST1NTSEFJUixcbiAgc3RpY2t5OiBTVElDS1ksXG4gIGFycm93OiBDUk9TU0hBSVIsXG4gIHRleHQ6IFRFWFQsXG4gIGVyYXNlcjogRVJBU0VSLFxufSk7XG5cbi8qKlxuICogUmVzb2x2ZSBhIHRvb2wgdG9rZW4g4oCUIHJlY2VpdmVkIG92ZXIgdGhlICoqdW50cnVzdGVkKiogY2FudmFz4oaSc2hlbGxcbiAqIGB0b29sLWN1cnNvcmAgcG9zdE1lc3NhZ2UgYnJpZGdlIOKAlCB0byBhIFRSVVNURUQgY3Vyc29yIHN0cmluZyBmcm9tXG4gKiB7QGxpbmsgVE9PTF9DVVJTT1JTfSwgb3IgYG51bGxgIHdoZW4gdGhlIHRva2VuIGlzIG5vdCBhIGtub3duIHRvb2wuXG4gKlxuICogVGhlIGFwcCBzaGVsbCBhcHBsaWVzIHRoZSB2YWx1ZSB0aGlzIFJFVFVSTlMsIG5ldmVyIHRoZSByYXcgbWVzc2FnZS4gVGhhdCBpc1xuICogdGhlIHNlY3VyaXR5IGJvdW5kYXJ5OiBhIG1hbGljaW91cyAqc3luY2VkKiBjYW52YXMgKEREUi0wNTQg4oCUIGNhbnZhcyBjb250ZW50XG4gKiBpcyB1bnRydXN0ZWQgYW5kIG1heSBiZSBodWItcHVzaGVkKSBjYW4gY2FsbFxuICogYHdpbmRvdy5wYXJlbnQucG9zdE1lc3NhZ2UoeyBkZ246ICd0b29sLWN1cnNvcicsIHRvb2w6IOKApiB9LCAnKicpYCBkaXJlY3RseSxcbiAqIGJ5cGFzc2luZyB0aGUgaG9uZXN0IGBUb29sUHJvdmlkZXJgIHNlbmRlci4gQnkgZWNob2luZyBvbmx5IGEgdG9rZW4gYW5kXG4gKiBsb29raW5nIHRoZSBjdXJzb3IgdXAgaGVyZSwgdGhlIHdvcnN0IHRoYXQgY2FudmFzIGNhbiBkbyBpcyBwaWNrICp3aGljaCpcbiAqIGtub3duLCBhbHdheXMtdmlzaWJsZSBnbHlwaCB0aGUgc2hlbGwgc2hvd3Mg4oCUIGl0IGNhbiBubyBsb25nZXIgc211Z2dsZSBhblxuICogaW52aXNpYmxlIC8gZGlzcGxhY2VkIC8gemVyby1jb250ZW50IFNWRyBjdXJzb3IgdGhhdCB3b3VsZCBhY3QgYXMgYVxuICogY2xpY2tqYWNraW5nIGFpZCBvdmVyIHRoZSB1bi1DU1AnZCBzaGVsbCAocGhhc2UtMjQgZXRoaWNhbC1oYWNrZXIgRmluZGluZyAyO1xuICogc2VlIEREUi0wNjcpLiBgaGFzT3duUHJvcGVydHlgIChub3QgYGluYCkga2VlcHMgYGNvbnN0cnVjdG9yYC9gX19wcm90b19fYFxuICogb2ZmIHRoZSBhbGxvd2xpc3QsIGFuZCB0aGUgYFthLXotXWAgc2hhcGUgZ2F0ZSBiYXJzIGFueXRoaW5nIGJ1dCBhIHRvb2wgaWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlVG9vbEN1cnNvcih0b2tlbjogdW5rbm93bik6IHN0cmluZyB8IG51bGwge1xuICBpZiAodHlwZW9mIHRva2VuICE9PSAnc3RyaW5nJyB8fCAhL15bYS16LV0rJC8udGVzdCh0b2tlbikpIHJldHVybiBudWxsO1xuICBpZiAoIU9iamVjdC5oYXNPd24oVE9PTF9DVVJTT1JTLCB0b2tlbikpIHJldHVybiBudWxsO1xuICByZXR1cm4gVE9PTF9DVVJTT1JTW3Rva2VuIGFzIFRvb2xdO1xufVxuIgogIF0sCiAgIm1hcHBpbmdzIjogIjtBQTRCQTtBQUFBO0FBQUE7QUFBQSxjQUlFO0FBQUEsaUJBRUE7QUFBQSxlQUNBO0FBQUEsYUFDQTtBQUFBLFlBQ0E7QUFBQSxjQUNBO0FBQUE7QUFFRjs7O0FDTkEsd0JBQVMsMkJBQWEsdUJBQVcsb0JBQVMscUJBQVE7OztBQ2hCbEQ7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQVVBO0FBQ0E7QUFDQTtBQUFBO0FBMlBBLElBQU0sZ0JBQWdCLGNBQWtDLElBQUk7QUFFckQsU0FBUyxTQUFTLEdBQXVCO0FBQUEsRUFDOUMsT0FBTyxXQUFXLGFBQWE7QUFBQTs7O0FDNVFqQztBQUFBLG1CQUNFO0FBQUEsaUJBRUE7QUFBQSxnQkFDQTtBQUFBLGVBQ0E7QUFBQSxhQUNBO0FBQUEsWUFDQTtBQUFBLGNBQ0E7QUFBQTtBQUFBO0FBd0NGLElBQU0sc0JBQXNCLGVBQXdDLElBQUk7QUFLeEUsU0FBUyxZQUFZLENBQUMsR0FBc0I7QUFBQSxFQUMxQyxPQUFPLEVBQUUsS0FBSyxNQUFNLEVBQUUsT0FBTyxPQUFPLEVBQUU7QUFBQTtBQUd4QyxTQUFTLE1BQU0sQ0FBQyxNQUFnQztBQUFBLEVBQzlDLE1BQU0sTUFBbUIsQ0FBQztBQUFBLEVBQzFCLE1BQU0sT0FBTyxJQUFJO0FBQUEsRUFDakIsV0FBVyxLQUFLLE1BQU07QUFBQSxJQUNwQixNQUFNLElBQUksYUFBYSxDQUFDO0FBQUEsSUFDeEIsSUFBSSxLQUFLLElBQUksQ0FBQztBQUFBLE1BQUc7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QUFDO0FBQUEsRUFFTCxNQUFNLFdBQVcsYUFBWSxNQUFNO0FBQUEsSUFDakMsU0FBUyxVQUFVLFVBQVU7QUFBQSxJQUU3QixnQkFBZ0IsQ0FBQyxNQUFPLEVBQUUsS0FBSyxFQUFFLElBQUksTUFBTSxJQUFJLENBQUU7QUFBQSxLQUNoRCxDQUFDLENBQUM7QUFBQSxFQUVMLE1BQU0sY0FBYyxhQUFZLE1BQU07QUFBQSxJQUNwQyxnQkFBZ0IsRUFBRSxJQUFJLE1BQU0sU0FBUyxlQUFlLENBQUM7QUFBQSxLQUNwRCxDQUFDLENBQUM7QUFBQSxFQUVMLE1BQU0sV0FBVyxhQUFZLE1BQWlCO0FBQUEsSUFDNUMsTUFBTSxLQUFLLFNBQVM7QUFBQSxJQUNwQixPQUFPLEtBQUssZ0JBQWdCLElBQUksSUFBSSxJQUFJO0FBQUEsS0FDdkMsQ0FBQyxJQUFJLENBQUM7QUFBQSxFQUVULE9BQU8sY0FDTCxXQUNBLE1BQ0EsY0FDRSxxQkFDQSxFQUFFLFNBQVMsU0FBUyxhQUFhLFNBQVMsR0FHMUMsY0FBYyxVQUFVLEVBQUUsS0FBSyxTQUFTLFFBQVEsUUFBUSxNQUFNLE1BQU0sU0FBUyxDQUFDLENBQ2hGLEdBQ0EsUUFBUSxLQUFLLGNBQWMsaUJBQWlCLEVBQUUsU0FBUyxRQUFRLFFBQVEsQ0FBQyxJQUFJLElBQzlFO0FBQUE7IiwKICAiZGVidWdJZCI6ICI2MjBDMzExRDgzODJENjIwNjQ3NTZFMjE2NDc1NkUyMSIsCiAgIm5hbWVzIjogW10KfQ==