botframework-webchat-component 4.14.1 → 4.15.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 (371) hide show
  1. package/.eslintrc.yml +4 -106
  2. package/.prettierrc.yml +1 -1
  3. package/lib/Activity/CarouselFilmStrip.js +1 -1
  4. package/lib/Activity/CarouselFilmStripAttachment.js +1 -1
  5. package/lib/Activity/Speak.js +1 -1
  6. package/lib/Activity/StackedLayout.d.ts.map +1 -1
  7. package/lib/Activity/StackedLayout.js +2 -2
  8. package/lib/Attachment/FileAttachment.js +2 -2
  9. package/lib/Attachment/FileContent.d.ts.map +1 -1
  10. package/lib/Attachment/FileContent.js +11 -1
  11. package/lib/BasicSendBox.js +1 -1
  12. package/lib/BasicToaster.js +5 -2
  13. package/lib/BasicTranscript.d.ts +7 -0
  14. package/lib/BasicTranscript.d.ts.map +1 -0
  15. package/lib/BasicTranscript.js +368 -725
  16. package/lib/BasicTypingIndicator.d.ts +2 -1
  17. package/lib/BasicTypingIndicator.d.ts.map +1 -1
  18. package/lib/BasicTypingIndicator.js +12 -4
  19. package/lib/Composer.d.ts.map +1 -1
  20. package/lib/Composer.js +34 -29
  21. package/lib/Middleware/Activity/createCoreMiddleware.d.ts.map +1 -1
  22. package/lib/Middleware/Activity/createCoreMiddleware.js +1 -1
  23. package/lib/Middleware/ActivityStatus/SendStatus/SendStatus.js +1 -1
  24. package/lib/Middleware/ActivityStatus/createSendStatusMiddleware.js +18 -15
  25. package/lib/Middleware/Attachment/createCoreMiddleware.js +2 -5
  26. package/lib/Middleware/AttachmentForScreenReader/createCoreMiddleware.d.ts.map +1 -1
  27. package/lib/Middleware/AttachmentForScreenReader/createCoreMiddleware.js +1 -1
  28. package/lib/Middleware/Avatar/createCoreMiddleware.d.ts.map +1 -1
  29. package/lib/Middleware/Avatar/createCoreMiddleware.js +2 -3
  30. package/lib/Middleware/CardAction/createCoreMiddleware.js +10 -3
  31. package/lib/Middleware/ScrollToEndButton/createScrollToEndButtonMiddleware.d.ts.map +1 -1
  32. package/lib/Middleware/ScrollToEndButton/createScrollToEndButtonMiddleware.js +1 -1
  33. package/lib/Middleware/Toast/createCoreMiddleware.d.ts.map +1 -1
  34. package/lib/Middleware/Toast/createCoreMiddleware.js +1 -1
  35. package/lib/Middleware/TypingIndicator/createCoreMiddleware.d.ts.map +1 -1
  36. package/lib/Middleware/TypingIndicator/createCoreMiddleware.js +8 -6
  37. package/lib/ScreenReaderActivity.js +14 -5
  38. package/lib/ScreenReaderText.d.ts +9 -0
  39. package/lib/ScreenReaderText.d.ts.map +1 -0
  40. package/lib/ScreenReaderText.js +22 -8
  41. package/lib/SendBox/DictationInterims.js +1 -1
  42. package/lib/SendBox/IconButton.d.ts +11 -0
  43. package/lib/SendBox/IconButton.d.ts.map +1 -0
  44. package/lib/SendBox/IconButton.js +26 -6
  45. package/lib/SendBox/MicrophoneButton.js +1 -1
  46. package/lib/SendBox/SendButton.js +1 -1
  47. package/lib/SendBox/SuggestedAction.d.ts +17 -0
  48. package/lib/SendBox/SuggestedAction.d.ts.map +1 -0
  49. package/lib/SendBox/SuggestedAction.js +25 -16
  50. package/lib/SendBox/SuggestedActions.d.ts.map +1 -1
  51. package/lib/SendBox/SuggestedActions.js +25 -8
  52. package/lib/SendBox/TextBox.js +1 -1
  53. package/lib/SendBox/UploadButton.js +1 -1
  54. package/lib/Styles/StyleSet/BasicTranscript.d.ts +13 -5
  55. package/lib/Styles/StyleSet/BasicTranscript.d.ts.map +1 -1
  56. package/lib/Styles/StyleSet/BasicTranscript.js +21 -9
  57. package/lib/Styles/StyleSet/Bubble.d.ts.map +1 -1
  58. package/lib/Styles/StyleSet/Bubble.js +1 -1
  59. package/lib/Styles/StyleSet/CarouselFilmStrip.d.ts.map +1 -1
  60. package/lib/Styles/StyleSet/CarouselFilmStrip.js +1 -1
  61. package/lib/Styles/StyleSet/CarouselFilmStripAttachment.d.ts.map +1 -1
  62. package/lib/Styles/StyleSet/CarouselFilmStripAttachment.js +1 -1
  63. package/lib/Styles/StyleSet/KeyboardHelp.d.ts +123 -0
  64. package/lib/Styles/StyleSet/KeyboardHelp.d.ts.map +1 -0
  65. package/lib/Styles/StyleSet/KeyboardHelp.js +145 -0
  66. package/lib/Styles/StyleSet/ScrollToEndButton.d.ts +1 -1
  67. package/lib/Styles/StyleSet/ScrollToEndButton.js +2 -2
  68. package/lib/Styles/StyleSet/SendBoxButton.d.ts +56 -10
  69. package/lib/Styles/StyleSet/SendBoxButton.d.ts.map +1 -1
  70. package/lib/Styles/StyleSet/SendBoxButton.js +76 -12
  71. package/lib/Styles/StyleSet/SendBoxTextBox.d.ts +1 -1
  72. package/lib/Styles/StyleSet/SendBoxTextBox.d.ts.map +1 -1
  73. package/lib/Styles/StyleSet/SendBoxTextBox.js +3 -3
  74. package/lib/Styles/StyleSet/StackedLayout.d.ts.map +1 -1
  75. package/lib/Styles/StyleSet/StackedLayout.js +1 -1
  76. package/lib/Styles/StyleSet/SuggestedAction.d.ts +73 -28
  77. package/lib/Styles/StyleSet/SuggestedAction.d.ts.map +1 -1
  78. package/lib/Styles/StyleSet/SuggestedAction.js +116 -41
  79. package/lib/Styles/StyleSet/SuggestedActions.d.ts +13 -6
  80. package/lib/Styles/StyleSet/SuggestedActions.d.ts.map +1 -1
  81. package/lib/Styles/StyleSet/SuggestedActions.js +13 -6
  82. package/lib/Styles/createStyleSet.d.ts +323 -54
  83. package/lib/Styles/createStyleSet.d.ts.map +1 -1
  84. package/lib/Styles/createStyleSet.js +4 -1
  85. package/lib/Styles/mirrorStyle.js +12 -3
  86. package/lib/Toast/NotificationIcon.js +7 -3
  87. package/lib/Toast/createToastMiddleware.d.ts.map +1 -1
  88. package/lib/Toast/createToastMiddleware.js +1 -1
  89. package/lib/Transcript/ActivityRow.d.ts +9 -0
  90. package/lib/Transcript/ActivityRow.d.ts.map +1 -0
  91. package/lib/Transcript/ActivityRow.js +157 -0
  92. package/lib/Transcript/ActivityTextAlt.js +57 -0
  93. package/lib/Transcript/FocusTrap.d.ts +8 -0
  94. package/lib/Transcript/FocusTrap.d.ts.map +1 -0
  95. package/lib/Transcript/FocusTrap.js +74 -0
  96. package/lib/Transcript/KeyboardHelp.d.ts +4 -0
  97. package/lib/Transcript/KeyboardHelp.d.ts.map +1 -0
  98. package/lib/Transcript/KeyboardHelp.js +550 -0
  99. package/lib/Transcript/LiveRegionTranscript.d.ts +8 -0
  100. package/lib/Transcript/LiveRegionTranscript.d.ts.map +1 -0
  101. package/lib/Transcript/LiveRegionTranscript.js +214 -0
  102. package/lib/Transcript/types.d.ts +2 -0
  103. package/lib/Transcript/types.d.ts.map +1 -0
  104. package/lib/Transcript/types.js +2 -0
  105. package/lib/Transcript/useActivityAccessibleName.d.ts +4 -0
  106. package/lib/Transcript/useActivityAccessibleName.d.ts.map +1 -0
  107. package/lib/Transcript/useActivityAccessibleName.js +97 -0
  108. package/lib/Utils/AccessibleButton.d.ts +11 -0
  109. package/lib/Utils/AccessibleButton.d.ts.map +1 -0
  110. package/lib/Utils/AccessibleButton.js +11 -6
  111. package/lib/Utils/FocusRedirector.d.ts +9 -0
  112. package/lib/Utils/FocusRedirector.d.ts.map +1 -0
  113. package/lib/Utils/FocusRedirector.js +16 -13
  114. package/lib/Utils/InlineMarkdown.js +12 -5
  115. package/lib/Utils/TypeFocusSink/inputtableKey.d.ts +2 -0
  116. package/lib/Utils/TypeFocusSink/inputtableKey.d.ts.map +1 -0
  117. package/lib/Utils/TypeFocusSink/inputtableKey.js +5 -2
  118. package/lib/Utils/activityAltText.d.ts +8 -0
  119. package/lib/Utils/activityAltText.d.ts.map +1 -0
  120. package/lib/Utils/createCustomEvent.js +8 -2
  121. package/lib/Utils/detectBrowser.js +4 -2
  122. package/lib/Utils/downscaleImageToDataURL/downscaleImageToDataURLUsingWorker.js +1 -1
  123. package/lib/Utils/findAncestor.js +17 -0
  124. package/lib/Utils/getActivityUniqueId.js +4 -2
  125. package/lib/Utils/intersectionOf.d.ts +5 -0
  126. package/lib/Utils/intersectionOf.d.ts.map +1 -0
  127. package/lib/Utils/intersectionOf.js +17 -2
  128. package/lib/Utils/isZeroOrPositive.d.ts +5 -0
  129. package/lib/Utils/isZeroOrPositive.d.ts.map +1 -0
  130. package/lib/Utils/isZeroOrPositive.js +4 -1
  131. package/lib/Utils/mapMap.js +9 -2
  132. package/lib/Utils/readDataURIToBlob.js +1 -1
  133. package/lib/Utils/scrollIntoViewWithBlockNearest.d.ts +7 -0
  134. package/lib/Utils/scrollIntoViewWithBlockNearest.d.ts.map +1 -0
  135. package/lib/Utils/scrollIntoViewWithBlockNearest.js +48 -0
  136. package/lib/Utils/shallowEquals.js +7 -3
  137. package/lib/Utils/supportPseudoClass.d.ts +2 -0
  138. package/lib/Utils/supportPseudoClass.d.ts.map +1 -0
  139. package/lib/Utils/supportPseudoClass.js +23 -0
  140. package/lib/Utils/tabbableElements.d.ts +2 -0
  141. package/lib/Utils/tabbableElements.d.ts.map +1 -0
  142. package/lib/Utils/tabbableElements.js +2 -2
  143. package/lib/connectToWebChat.js +13 -5
  144. package/lib/hooks/index.js +24 -24
  145. package/lib/hooks/internal/BypassSpeechSynthesisPonyfill.js +5 -4
  146. package/lib/hooks/internal/useChanged.js +8 -1
  147. package/lib/hooks/internal/useDispatchScrollPosition.js +3 -7
  148. package/lib/hooks/internal/useDispatchTranscriptFocusByActivityKey.d.ts +2 -0
  149. package/lib/hooks/internal/useDispatchTranscriptFocusByActivityKey.d.ts.map +1 -0
  150. package/lib/hooks/internal/useDispatchTranscriptFocusByActivityKey.js +15 -0
  151. package/lib/hooks/internal/useFocusVisible.d.ts +3 -0
  152. package/lib/hooks/internal/useFocusVisible.d.ts.map +1 -0
  153. package/lib/hooks/internal/useFocusVisible.js +48 -0
  154. package/lib/hooks/internal/useMemoWithPrevious.d.ts +3 -0
  155. package/lib/hooks/internal/useMemoWithPrevious.d.ts.map +1 -0
  156. package/lib/hooks/internal/useMemoWithPrevious.js +22 -0
  157. package/lib/hooks/internal/useMemoize.d.ts +14 -0
  158. package/lib/hooks/internal/useMemoize.d.ts.map +1 -0
  159. package/lib/hooks/internal/useMemoize.js +11 -2
  160. package/lib/hooks/internal/useObserveFocusVisible.d.ts +3 -0
  161. package/lib/hooks/internal/useObserveFocusVisible.d.ts.map +1 -0
  162. package/lib/hooks/internal/useObserveFocusVisible.js +208 -0
  163. package/lib/hooks/internal/usePrevious.d.ts +2 -0
  164. package/lib/hooks/internal/usePrevious.d.ts.map +1 -0
  165. package/lib/hooks/internal/usePrevious.js +18 -0
  166. package/lib/hooks/internal/useStateRef.d.ts +3 -0
  167. package/lib/hooks/internal/useStateRef.d.ts.map +1 -0
  168. package/lib/hooks/internal/useStateRef.js +40 -0
  169. package/lib/hooks/internal/useValueRef.d.ts +3 -0
  170. package/lib/hooks/internal/useValueRef.d.ts.map +1 -0
  171. package/lib/hooks/internal/useValueRef.js +25 -0
  172. package/lib/hooks/useFocus.d.ts +1 -1
  173. package/lib/hooks/useFocus.d.ts.map +1 -1
  174. package/lib/hooks/useFocus.js +1 -1
  175. package/lib/hooks/useRenderMarkdownAsHTML.d.ts.map +1 -1
  176. package/lib/hooks/useRenderMarkdownAsHTML.js +1 -1
  177. package/lib/hooks/useScrollTo.d.ts.map +1 -1
  178. package/lib/hooks/useScrollTo.js +1 -1
  179. package/lib/hooks/useScrollToEnd.d.ts.map +1 -1
  180. package/lib/hooks/useScrollToEnd.js +1 -1
  181. package/lib/index.d.ts +10 -0
  182. package/lib/index.d.ts.map +1 -1
  183. package/lib/index.js +17 -15
  184. package/lib/providers/ActivityTree/ActivityTreeComposer.d.ts +5 -0
  185. package/lib/providers/ActivityTree/ActivityTreeComposer.d.ts.map +1 -0
  186. package/lib/providers/ActivityTree/ActivityTreeComposer.js +86 -0
  187. package/lib/providers/ActivityTree/private/Context.d.ts +9 -0
  188. package/lib/providers/ActivityTree/private/Context.d.ts.map +1 -0
  189. package/lib/providers/ActivityTree/private/Context.js +13 -0
  190. package/lib/providers/ActivityTree/private/types.d.ts +10 -0
  191. package/lib/providers/ActivityTree/private/types.d.ts.map +1 -0
  192. package/lib/providers/ActivityTree/private/types.js +2 -0
  193. package/lib/providers/ActivityTree/private/useActivitiesWithRenderer.d.ts +4 -0
  194. package/lib/providers/ActivityTree/private/useActivitiesWithRenderer.d.ts.map +1 -0
  195. package/lib/providers/ActivityTree/private/useActivitiesWithRenderer.js +58 -0
  196. package/lib/providers/ActivityTree/private/useActivityTreeWithRenderer.d.ts +5 -0
  197. package/lib/providers/ActivityTree/private/useActivityTreeWithRenderer.d.ts.map +1 -0
  198. package/lib/providers/ActivityTree/private/useActivityTreeWithRenderer.js +166 -0
  199. package/lib/providers/ActivityTree/private/useContext.d.ts +3 -0
  200. package/lib/providers/ActivityTree/private/useContext.d.ts.map +1 -0
  201. package/lib/providers/ActivityTree/private/useContext.js +24 -0
  202. package/lib/providers/ActivityTree/useActivityTreeWithRenderer.d.ts +8 -0
  203. package/lib/providers/ActivityTree/useActivityTreeWithRenderer.d.ts.map +1 -0
  204. package/lib/providers/ActivityTree/useActivityTreeWithRenderer.js +17 -0
  205. package/lib/providers/LiveRegionTwin/LiveRegionTwinComposer.d.ts +35 -0
  206. package/lib/providers/LiveRegionTwin/LiveRegionTwinComposer.d.ts.map +1 -0
  207. package/lib/providers/LiveRegionTwin/LiveRegionTwinComposer.js +156 -0
  208. package/lib/providers/LiveRegionTwin/private/Context.d.ts +10 -0
  209. package/lib/providers/LiveRegionTwin/private/Context.d.ts.map +1 -0
  210. package/lib/providers/LiveRegionTwin/private/Context.js +13 -0
  211. package/lib/providers/LiveRegionTwin/private/LiveRegionTwinContainer.d.ts +11 -0
  212. package/lib/providers/LiveRegionTwin/private/LiveRegionTwinContainer.d.ts.map +1 -0
  213. package/lib/providers/LiveRegionTwin/private/LiveRegionTwinContainer.js +86 -0
  214. package/lib/providers/LiveRegionTwin/private/types.d.ts +8 -0
  215. package/lib/providers/LiveRegionTwin/private/types.d.ts.map +1 -0
  216. package/lib/providers/LiveRegionTwin/private/types.js +2 -0
  217. package/lib/providers/LiveRegionTwin/private/useContext.d.ts +3 -0
  218. package/lib/providers/LiveRegionTwin/private/useContext.d.ts.map +1 -0
  219. package/lib/providers/LiveRegionTwin/private/useContext.js +24 -0
  220. package/lib/providers/LiveRegionTwin/private/useMarkAllAsRenderedEffect.d.ts +2 -0
  221. package/lib/providers/LiveRegionTwin/private/useMarkAllAsRenderedEffect.d.ts.map +1 -0
  222. package/lib/providers/LiveRegionTwin/private/useMarkAllAsRenderedEffect.js +24 -0
  223. package/lib/providers/LiveRegionTwin/private/useStaticElementEntries.d.ts +3 -0
  224. package/lib/providers/LiveRegionTwin/private/useStaticElementEntries.d.ts.map +1 -0
  225. package/lib/providers/LiveRegionTwin/private/useStaticElementEntries.js +15 -0
  226. package/lib/providers/LiveRegionTwin/useQueueStaticElement.d.ts +8 -0
  227. package/lib/providers/LiveRegionTwin/useQueueStaticElement.d.ts.map +1 -0
  228. package/lib/providers/LiveRegionTwin/useQueueStaticElement.js +20 -0
  229. package/lib/providers/TranscriptFocus/TranscriptFocusComposer.d.ts +7 -0
  230. package/lib/providers/TranscriptFocus/TranscriptFocusComposer.d.ts.map +1 -0
  231. package/lib/providers/TranscriptFocus/TranscriptFocusComposer.js +184 -0
  232. package/lib/providers/TranscriptFocus/private/Context.d.ts +12 -0
  233. package/lib/providers/TranscriptFocus/private/Context.d.ts.map +1 -0
  234. package/lib/providers/TranscriptFocus/private/Context.js +13 -0
  235. package/lib/providers/TranscriptFocus/private/useContext.d.ts +2 -0
  236. package/lib/providers/TranscriptFocus/private/useContext.d.ts.map +1 -0
  237. package/lib/providers/TranscriptFocus/private/useContext.js +24 -0
  238. package/lib/providers/TranscriptFocus/useActiveDescendantId.d.ts +2 -0
  239. package/lib/providers/TranscriptFocus/useActiveDescendantId.d.ts.map +1 -0
  240. package/lib/providers/TranscriptFocus/useActiveDescendantId.js +15 -0
  241. package/lib/providers/TranscriptFocus/useFocusByActivityKey.d.ts +8 -0
  242. package/lib/providers/TranscriptFocus/useFocusByActivityKey.d.ts.map +1 -0
  243. package/lib/providers/TranscriptFocus/useFocusByActivityKey.js +21 -0
  244. package/lib/providers/TranscriptFocus/useFocusRelativeActivity.d.ts +2 -0
  245. package/lib/providers/TranscriptFocus/useFocusRelativeActivity.d.ts.map +1 -0
  246. package/lib/providers/TranscriptFocus/useFocusRelativeActivity.js +15 -0
  247. package/lib/providers/TranscriptFocus/useFocusedActivityKey.d.ts +2 -0
  248. package/lib/providers/TranscriptFocus/useFocusedActivityKey.d.ts.map +1 -0
  249. package/lib/providers/TranscriptFocus/useFocusedActivityKey.js +15 -0
  250. package/lib/providers/TranscriptFocus/useFocusedExplicitly.d.ts +2 -0
  251. package/lib/providers/TranscriptFocus/useFocusedExplicitly.d.ts.map +1 -0
  252. package/lib/providers/TranscriptFocus/useFocusedExplicitly.js +15 -0
  253. package/lib/providers/TranscriptFocus/useGetDescendantIdByActivityKey.d.ts +2 -0
  254. package/lib/providers/TranscriptFocus/useGetDescendantIdByActivityKey.d.ts.map +1 -0
  255. package/lib/providers/TranscriptFocus/useGetDescendantIdByActivityKey.js +15 -0
  256. package/package.json +17 -24
  257. package/src/Activity/CarouselFilmStripAttachment.js +0 -1
  258. package/src/Activity/StackedLayout.tsx +10 -9
  259. package/src/Attachment/FileAttachment.js +1 -1
  260. package/src/Attachment/FileContent.tsx +12 -0
  261. package/src/BasicToaster.js +5 -1
  262. package/src/BasicTranscript.tsx +878 -0
  263. package/src/BasicTypingIndicator.tsx +3 -2
  264. package/src/Composer.tsx +41 -29
  265. package/src/Middleware/Activity/createCoreMiddleware.tsx +50 -44
  266. package/src/Middleware/ActivityStatus/createSendStatusMiddleware.js +2 -0
  267. package/src/Middleware/Attachment/createCoreMiddleware.tsx +28 -28
  268. package/src/Middleware/AttachmentForScreenReader/createCoreMiddleware.tsx +25 -23
  269. package/src/Middleware/Avatar/createCoreMiddleware.tsx +9 -8
  270. package/src/Middleware/CardAction/createCoreMiddleware.js +9 -2
  271. package/src/Middleware/ScrollToEndButton/createScrollToEndButtonMiddleware.ts +11 -9
  272. package/src/Middleware/Toast/createCoreMiddleware.tsx +12 -10
  273. package/src/Middleware/TypingIndicator/createCoreMiddleware.tsx +8 -2
  274. package/src/ScreenReaderActivity.js +18 -3
  275. package/src/{ScreenReaderText.js → ScreenReaderText.tsx} +27 -9
  276. package/src/SendBox/{IconButton.js → IconButton.tsx} +19 -3
  277. package/src/SendBox/{SuggestedAction.js → SuggestedAction.tsx} +72 -35
  278. package/src/SendBox/SuggestedActions.tsx +47 -20
  279. package/src/Styles/StyleSet/BasicTranscript.ts +34 -20
  280. package/src/Styles/StyleSet/Bubble.ts +0 -1
  281. package/src/Styles/StyleSet/CarouselFilmStrip.ts +12 -10
  282. package/src/Styles/StyleSet/CarouselFilmStripAttachment.ts +4 -3
  283. package/src/Styles/StyleSet/KeyboardHelp.ts +157 -0
  284. package/src/Styles/StyleSet/ScrollToEndButton.ts +1 -1
  285. package/src/Styles/StyleSet/SendBoxButton.ts +84 -13
  286. package/src/Styles/StyleSet/SendBoxTextBox.ts +1 -2
  287. package/src/Styles/StyleSet/StackedLayout.ts +13 -11
  288. package/src/Styles/StyleSet/SuggestedAction.ts +129 -42
  289. package/src/Styles/StyleSet/SuggestedActions.ts +13 -5
  290. package/src/Styles/createStyleSet.ts +2 -1
  291. package/src/Styles/mirrorStyle.js +10 -2
  292. package/src/Toast/NotificationIcon.js +4 -1
  293. package/src/Toast/createToastMiddleware.tsx +4 -1
  294. package/src/Transcript/ActivityRow.tsx +124 -0
  295. package/src/Transcript/ActivityTextAlt.tsx +32 -0
  296. package/src/Transcript/FocusTrap.tsx +64 -0
  297. package/src/Transcript/KeyboardHelp.tsx +282 -0
  298. package/src/Transcript/LiveRegionTranscript.tsx +181 -0
  299. package/src/Transcript/types.ts +1 -0
  300. package/src/Transcript/useActivityAccessibleName.ts +85 -0
  301. package/src/Utils/{AccessibleButton.js → AccessibleButton.tsx} +19 -4
  302. package/src/Utils/{FocusRedirector.js → FocusRedirector.tsx} +21 -8
  303. package/src/Utils/InlineMarkdown.js +18 -2
  304. package/src/Utils/TypeFocusSink/inputtableKey.ts +5 -1
  305. package/src/Utils/createCustomEvent.js +7 -1
  306. package/src/Utils/detectBrowser.js +2 -1
  307. package/src/Utils/findAncestor.ts +12 -0
  308. package/src/Utils/getActivityUniqueId.ts +5 -0
  309. package/src/Utils/intersectionOf.ts +14 -0
  310. package/src/Utils/isZeroOrPositive.ts +7 -0
  311. package/src/Utils/mapMap.js +7 -1
  312. package/src/Utils/scrollIntoViewWithBlockNearest.ts +20 -0
  313. package/src/Utils/shallowEquals.js +8 -1
  314. package/src/Utils/supportPseudoClass.ts +17 -0
  315. package/src/Utils/{tabbableElements.js → tabbableElements.ts} +6 -5
  316. package/src/connectToWebChat.js +11 -4
  317. package/src/hooks/internal/BypassSpeechSynthesisPonyfill.js +3 -1
  318. package/src/hooks/internal/useChanged.ts +17 -0
  319. package/src/hooks/internal/useDispatchScrollPosition.js +1 -3
  320. package/src/hooks/internal/useDispatchTranscriptFocusByActivityKey.ts +5 -0
  321. package/src/hooks/internal/useFocusVisible.ts +22 -0
  322. package/src/hooks/internal/useMemoWithPrevious.ts +16 -0
  323. package/src/hooks/internal/useMemoize.spec.js +1 -1
  324. package/src/hooks/internal/useMemoize.ts +53 -0
  325. package/src/hooks/internal/useObserveFocusVisible.ts +252 -0
  326. package/src/hooks/internal/usePrevious.ts +12 -0
  327. package/src/hooks/internal/useStateRef.ts +31 -0
  328. package/src/hooks/internal/useValueRef.ts +22 -0
  329. package/src/hooks/useFocus.ts +1 -1
  330. package/src/hooks/useRenderMarkdownAsHTML.ts +4 -5
  331. package/src/hooks/useScrollTo.ts +4 -3
  332. package/src/hooks/useScrollToEnd.ts +4 -3
  333. package/src/index.ts +0 -1
  334. package/src/providers/ActivityTree/ActivityTreeComposer.tsx +74 -0
  335. package/src/providers/ActivityTree/private/Context.ts +12 -0
  336. package/src/providers/ActivityTree/private/types.ts +12 -0
  337. package/src/providers/ActivityTree/private/useActivitiesWithRenderer.ts +66 -0
  338. package/src/providers/ActivityTree/private/useActivityTreeWithRenderer.ts +140 -0
  339. package/src/providers/ActivityTree/private/useContext.ts +15 -0
  340. package/src/providers/ActivityTree/useActivityTreeWithRenderer.ts +16 -0
  341. package/src/providers/LiveRegionTwin/LiveRegionTwinComposer.tsx +154 -0
  342. package/src/providers/LiveRegionTwin/private/Context.ts +15 -0
  343. package/src/providers/LiveRegionTwin/private/LiveRegionTwinContainer.tsx +64 -0
  344. package/src/providers/LiveRegionTwin/private/types.ts +10 -0
  345. package/src/providers/LiveRegionTwin/private/useContext.ts +15 -0
  346. package/src/providers/LiveRegionTwin/private/useMarkAllAsRenderedEffect.ts +13 -0
  347. package/src/providers/LiveRegionTwin/private/useStaticElementEntries.ts +7 -0
  348. package/src/providers/LiveRegionTwin/useQueueStaticElement.ts +12 -0
  349. package/src/providers/TranscriptFocus/TranscriptFocusComposer.tsx +180 -0
  350. package/src/providers/TranscriptFocus/private/Context.ts +16 -0
  351. package/src/providers/TranscriptFocus/private/useContext.ts +13 -0
  352. package/src/providers/TranscriptFocus/useActiveDescendantId.ts +5 -0
  353. package/src/providers/TranscriptFocus/useFocusByActivityKey.ts +14 -0
  354. package/src/providers/TranscriptFocus/useFocusRelativeActivity.ts +5 -0
  355. package/src/providers/TranscriptFocus/useFocusedActivityKey.ts +5 -0
  356. package/src/providers/TranscriptFocus/useFocusedExplicitly.ts +5 -0
  357. package/src/providers/TranscriptFocus/useGetDescendantIdByActivityKey.ts +5 -0
  358. package/.eslintignore +0 -1
  359. package/lib/Utils/findLastIndex.js +0 -32
  360. package/lib/hooks/internal/useAcknowledgedActivity.js +0 -90
  361. package/lib/hooks/internal/useDispatchTranscriptFocus.js +0 -19
  362. package/src/BasicTranscript.js +0 -1139
  363. package/src/Utils/findLastIndex.js +0 -11
  364. package/src/Utils/findLastIndex.spec.js +0 -31
  365. package/src/Utils/getActivityUniqueId.js +0 -3
  366. package/src/Utils/intersectionOf.js +0 -11
  367. package/src/Utils/isZeroOrPositive.js +0 -4
  368. package/src/hooks/internal/useAcknowledgedActivity.js +0 -65
  369. package/src/hooks/internal/useChanged.js +0 -10
  370. package/src/hooks/internal/useDispatchTranscriptFocus.js +0 -7
  371. package/src/hooks/internal/useMemoize.js +0 -37
@@ -15,45 +15,49 @@ var _classnames = _interopRequireDefault(require("classnames"));
15
15
 
16
16
  var _propTypes = _interopRequireDefault(require("prop-types"));
17
17
 
18
- var _mathRandom = _interopRequireDefault(require("math-random"));
19
-
20
18
  var _react = _interopRequireWildcard(require("react"));
21
19
 
22
- var _BasicTypingIndicator = _interopRequireDefault(require("./BasicTypingIndicator"));
23
-
24
- var _Fade = _interopRequireDefault(require("./Utils/Fade"));
20
+ var _detectBrowser = require("./Utils/detectBrowser");
25
21
 
26
- var _FocusRedirector = _interopRequireDefault(require("./Utils/FocusRedirector"));
22
+ var _ActivityRow = _interopRequireDefault(require("./Transcript/ActivityRow"));
27
23
 
28
- var _getActivityUniqueId = _interopRequireDefault(require("./Utils/getActivityUniqueId"));
24
+ var _BasicTypingIndicator = _interopRequireDefault(require("./BasicTypingIndicator"));
29
25
 
30
- var _getTabIndex = _interopRequireDefault(require("./Utils/TypeFocusSink/getTabIndex"));
26
+ var _FocusRedirector = _interopRequireDefault(require("./Utils/FocusRedirector"));
31
27
 
32
28
  var _inputtableKey = _interopRequireDefault(require("./Utils/TypeFocusSink/inputtableKey"));
33
29
 
34
- var _intersectionOf = _interopRequireDefault(require("./Utils/intersectionOf"));
35
-
36
30
  var _isZeroOrPositive = _interopRequireDefault(require("./Utils/isZeroOrPositive"));
37
31
 
38
- var _removeInline = _interopRequireDefault(require("./Utils/removeInline"));
32
+ var _KeyboardHelp = _interopRequireDefault(require("./Transcript/KeyboardHelp"));
39
33
 
40
- var _ScreenReaderActivity = _interopRequireDefault(require("./ScreenReaderActivity"));
34
+ var _LiveRegionTranscript = _interopRequireDefault(require("./Transcript/LiveRegionTranscript"));
41
35
 
42
- var _ScreenReaderText = _interopRequireDefault(require("./ScreenReaderText"));
36
+ var _tabbableElements = _interopRequireDefault(require("./Utils/tabbableElements"));
43
37
 
44
- var _Speak = _interopRequireDefault(require("./Activity/Speak"));
38
+ var _TranscriptFocusComposer = _interopRequireDefault(require("./providers/TranscriptFocus/TranscriptFocusComposer"));
45
39
 
46
- var _tabbableElements = _interopRequireDefault(require("./Utils/tabbableElements"));
40
+ var _useActiveDescendantId = _interopRequireDefault(require("./providers/TranscriptFocus/useActiveDescendantId"));
47
41
 
48
- var _useAcknowledgedActivity = _interopRequireDefault(require("./hooks/internal/useAcknowledgedActivity"));
42
+ var _useActivityTreeWithRenderer = _interopRequireDefault(require("./providers/ActivityTree/useActivityTreeWithRenderer"));
49
43
 
50
44
  var _useDispatchScrollPosition = _interopRequireDefault(require("./hooks/internal/useDispatchScrollPosition"));
51
45
 
52
- var _useDispatchTranscriptFocus = _interopRequireDefault(require("./hooks/internal/useDispatchTranscriptFocus"));
46
+ var _useDispatchTranscriptFocusByActivityKey = _interopRequireDefault(require("./hooks/internal/useDispatchTranscriptFocusByActivityKey"));
53
47
 
54
48
  var _useFocus = _interopRequireDefault(require("./hooks/useFocus"));
55
49
 
56
- var _useMemoize = _interopRequireDefault(require("./hooks/internal/useMemoize"));
50
+ var _useFocusByActivityKey = _interopRequireDefault(require("./providers/TranscriptFocus/useFocusByActivityKey"));
51
+
52
+ var _useFocusedActivityKey = _interopRequireDefault(require("./providers/TranscriptFocus/useFocusedActivityKey"));
53
+
54
+ var _useFocusedExplicitly3 = _interopRequireDefault(require("./providers/TranscriptFocus/useFocusedExplicitly"));
55
+
56
+ var _useFocusRelativeActivity = _interopRequireDefault(require("./providers/TranscriptFocus/useFocusRelativeActivity"));
57
+
58
+ var _useObserveFocusVisible = _interopRequireDefault(require("./hooks/internal/useObserveFocusVisible"));
59
+
60
+ var _usePrevious = _interopRequireDefault(require("./hooks/internal/usePrevious"));
57
61
 
58
62
  var _useRegisterFocusTranscript = _interopRequireDefault(require("./hooks/internal/useRegisterFocusTranscript"));
59
63
 
@@ -69,26 +73,22 @@ var _useStyleToEmotionObject = _interopRequireDefault(require("./hooks/internal/
69
73
 
70
74
  var _useUniqueId = _interopRequireDefault(require("./hooks/internal/useUniqueId"));
71
75
 
76
+ var _useValueRef = _interopRequireDefault(require("./hooks/internal/useValueRef"));
77
+
72
78
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
73
79
 
74
80
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
75
81
 
76
82
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
77
83
 
84
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
85
+
78
86
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
79
87
 
80
88
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
81
89
 
82
90
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
83
91
 
84
- function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
85
-
86
- function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
87
-
88
- function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
89
-
90
- function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
91
-
92
92
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
93
93
 
94
94
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@@ -101,14 +101,19 @@ function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Sy
101
101
 
102
102
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
103
103
 
104
- var useActivities = _botframeworkWebchatApi.hooks.useActivities,
105
- useCreateActivityRenderer = _botframeworkWebchatApi.hooks.useCreateActivityRenderer,
104
+ var useActivityKeys = _botframeworkWebchatApi.hooks.useActivityKeys,
105
+ useActivityKeysByRead = _botframeworkWebchatApi.hooks.useActivityKeysByRead,
106
106
  useCreateActivityStatusRenderer = _botframeworkWebchatApi.hooks.useCreateActivityStatusRenderer,
107
107
  useCreateAvatarRenderer = _botframeworkWebchatApi.hooks.useCreateAvatarRenderer,
108
108
  useCreateScrollToEndButtonRenderer = _botframeworkWebchatApi.hooks.useCreateScrollToEndButtonRenderer,
109
109
  useDirection = _botframeworkWebchatApi.hooks.useDirection,
110
- useGroupActivities = _botframeworkWebchatApi.hooks.useGroupActivities,
110
+ useGetActivityByKey = _botframeworkWebchatApi.hooks.useGetActivityByKey,
111
+ useGetKeyByActivity = _botframeworkWebchatApi.hooks.useGetKeyByActivity,
112
+ useGetKeyByActivityId = _botframeworkWebchatApi.hooks.useGetKeyByActivityId,
113
+ useLastAcknowledgedActivityKey = _botframeworkWebchatApi.hooks.useLastAcknowledgedActivityKey,
111
114
  useLocalizer = _botframeworkWebchatApi.hooks.useLocalizer,
115
+ useMarkActivityKeyAsRead = _botframeworkWebchatApi.hooks.useMarkActivityKeyAsRead,
116
+ useMarkAllAsAcknowledged = _botframeworkWebchatApi.hooks.useMarkAllAsAcknowledged,
112
117
  useStyleOptions = _botframeworkWebchatApi.hooks.useStyleOptions;
113
118
  var ROOT_STYLE = {
114
119
  '&.webchat__basic-transcript': {
@@ -133,17 +138,9 @@ var ROOT_STYLE = {
133
138
  }
134
139
  }
135
140
  };
136
-
137
- function validateAllActivitiesTagged(activities, bins) {
138
- return activities.every(function (activity) {
139
- return bins.some(function (bin) {
140
- return bin.includes(activity);
141
- });
142
- });
143
- }
144
-
145
- var InternalTranscript = function InternalTranscript(_ref) {
146
- var activityElementsRef = _ref.activityElementsRef,
141
+ // TODO: [P1] #4133 Add telemetry for computing how many re-render done so far.
142
+ var InternalTranscript = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, ref) {
143
+ var activityElementMapRef = _ref.activityElementMapRef,
147
144
  className = _ref.className;
148
145
 
149
146
  var _useStyleSet = (0, _useStyleSet5.default)(),
@@ -156,187 +153,84 @@ var InternalTranscript = function InternalTranscript(_ref) {
156
153
  bubbleFromUserNubOffset = _useStyleOptions2$.bubbleFromUserNubOffset,
157
154
  bubbleNubOffset = _useStyleOptions2$.bubbleNubOffset,
158
155
  groupTimestamp = _useStyleOptions2$.groupTimestamp,
159
- internalLiveRegionFadeAfter = _useStyleOptions2$.internalLiveRegionFadeAfter,
160
156
  showAvatarInGroup = _useStyleOptions2$.showAvatarInGroup;
161
157
 
162
- var _useState = (0, _react.useState)(),
163
- _useState2 = _slicedToArray(_useState, 2),
164
- focusedActivityKey = _useState2[0],
165
- setFocusedActivityKey = _useState2[1];
158
+ var _useActiveDescendantI = (0, _useActiveDescendantId.default)(),
159
+ _useActiveDescendantI2 = _slicedToArray(_useActiveDescendantI, 1),
160
+ activeDescendantId = _useActiveDescendantI2[0];
166
161
 
167
- var _useActivities = useActivities(),
168
- _useActivities2 = _slicedToArray(_useActivities, 1),
169
- activities = _useActivities2[0];
162
+ var _useActivityTreeWithR = (0, _useActivityTreeWithRenderer.default)(),
163
+ _useActivityTreeWithR2 = _slicedToArray(_useActivityTreeWithR, 1),
164
+ activityWithRendererTree = _useActivityTreeWithR2[0];
170
165
 
171
166
  var _useDirection = useDirection(),
172
167
  _useDirection2 = _slicedToArray(_useDirection, 1),
173
168
  direction = _useDirection2[0];
174
169
 
175
- var createActivityRenderer = useCreateActivityRenderer();
170
+ var _useFocusedActivityKe = (0, _useFocusedActivityKey.default)(),
171
+ _useFocusedActivityKe2 = _slicedToArray(_useFocusedActivityKe, 1),
172
+ focusedActivityKey = _useFocusedActivityKe2[0];
173
+
174
+ var _useFocusedExplicitly = (0, _useFocusedExplicitly3.default)(),
175
+ _useFocusedExplicitly2 = _slicedToArray(_useFocusedExplicitly, 1),
176
+ focusedExplicitly = _useFocusedExplicitly2[0];
177
+
176
178
  var createActivityStatusRenderer = useCreateActivityStatusRenderer();
177
179
  var createAvatarRenderer = useCreateAvatarRenderer();
178
180
  var focus = (0, _useFocus.default)();
179
- var groupActivities = useGroupActivities();
181
+ var focusByActivityKey = (0, _useFocusByActivityKey.default)();
182
+ var focusRelativeActivity = (0, _useFocusRelativeActivity.default)();
183
+ var getActivityByKey = useGetActivityByKey();
184
+ var getKeyByActivity = useGetKeyByActivity();
185
+ var getKeyByActivityId = useGetKeyByActivityId();
180
186
  var localize = useLocalizer();
181
187
  var rootClassName = (0, _useStyleToEmotionObject.default)()(ROOT_STYLE) + '';
182
188
  var rootElementRef = (0, _react.useRef)();
189
+ var terminatorLabelId = (0, _useUniqueId.default)('webchat__basic-transcript__terminator-label');
183
190
  var terminatorRef = (0, _react.useRef)();
184
- var activityInteractiveAlt = localize('ACTIVITY_INTERACTIVE_LABEL_ALT');
191
+ var focusedActivityKeyRef = (0, _useValueRef.default)(focusedActivityKey);
192
+ var hideAllTimestamps = groupTimestamp === false;
185
193
  var terminatorText = localize('TRANSCRIPT_TERMINATOR_TEXT');
186
194
  var transcriptAriaLabel = localize('TRANSCRIPT_ARIA_LABEL_ALT');
187
- var transcriptRoleDescription = localize('TRANSCRIPT_ARIA_ROLE_ALT');
188
- var hideAllTimestamps = groupTimestamp === false; // Gets renderer for every activity.
189
- // Activities that are not visible will return a falsy renderer.
190
- // Converted from createActivityRenderer({ activity, nextVisibleActivity }) to createActivityRenderer(activity, nextVisibleActivity).
191
- // This is for the memoization function to cache the arguments. Memoizer can only cache literal arguments.
192
-
193
- var createActivityRendererWithLiteralArgs = (0, _react.useCallback)(function (activity, nextVisibleActivity) {
194
- return createActivityRenderer({
195
- activity: activity,
196
- nextVisibleActivity: nextVisibleActivity
197
- });
198
- }, [createActivityRenderer]); // Create a memoized context of the createActivityRenderer function.
199
-
200
- var activitiesWithRenderer = (0, _useMemoize.default)(createActivityRendererWithLiteralArgs, function (createActivityRendererWithLiteralArgsMemoized) {
201
- // All calls to createActivityRendererWithLiteralArgsMemoized() in this function will be memoized (LRU = 1).
202
- // In the next render cycle, calls to createActivityRendererWithLiteralArgsMemoized() might return the memoized result instead.
203
- // This is an improvement to React useMemo(), because it only allows 1 memoization.
204
- // useMemoize() allows any number of memoization.
205
- var activitiesWithRenderer = [];
206
- var nextVisibleActivity;
207
-
208
- for (var index = activities.length - 1; index >= 0; index--) {
209
- var activity = activities[index];
210
- var renderActivity = createActivityRendererWithLiteralArgsMemoized(activity, nextVisibleActivity);
211
-
212
- if (renderActivity) {
213
- activitiesWithRenderer.splice(0, 0, {
214
- activity: activity,
215
- renderActivity: renderActivity
216
- });
217
- nextVisibleActivity = activity;
218
- }
219
- }
220
-
221
- return activitiesWithRenderer;
222
- }, [activities]);
223
- var visibleActivities = (0, _react.useMemo)(function () {
224
- return activitiesWithRenderer.map(function (_ref2) {
225
- var activity = _ref2.activity;
226
- return activity;
227
- });
228
- }, [activitiesWithRenderer]); // Tag activities based on types.
229
- // The default implementation tag into 2 types: sender and status.
230
-
231
- var _useMemo = (0, _react.useMemo)(function () {
232
- var _groupActivities = groupActivities({
233
- activities: visibleActivities
234
- }),
235
- activitiesGroupBySender = _groupActivities.sender,
236
- activitiesGroupByStatus = _groupActivities.status;
237
-
238
- if (!validateAllActivitiesTagged(visibleActivities, activitiesGroupBySender)) {
239
- console.warn('botframework-webchat: Not every activities are grouped in the "sender" property. Please fix "groupActivitiesMiddleware" and group every activities.');
240
- }
241
-
242
- if (!validateAllActivitiesTagged(visibleActivities, activitiesGroupByStatus)) {
243
- console.warn('botframework-webchat: Not every activities are grouped in the "status" property. Please fix "groupActivitiesMiddleware" and group every activities.');
244
- }
245
-
246
- return {
247
- activitiesGroupBySender: activitiesGroupBySender,
248
- activitiesGroupByStatus: activitiesGroupByStatus
249
- };
250
- }, [groupActivities, visibleActivities]),
251
- activitiesGroupBySender = _useMemo.activitiesGroupBySender,
252
- activitiesGroupByStatus = _useMemo.activitiesGroupByStatus; // Create a tree of activities with 2 dimensions: sender, followed by status.
253
-
254
-
255
- var activityTree = (0, _react.useMemo)(function () {
256
- var visibleActivitiesPendingGrouping = _toConsumableArray(visibleActivities);
257
-
258
- var activityTree = [];
259
-
260
- var _loop = function _loop() {
261
- var _visibleActivitiesPen = _slicedToArray(visibleActivitiesPendingGrouping, 1),
262
- activity = _visibleActivitiesPen[0];
263
-
264
- var senderTree = [];
265
- var activitiesWithSameSender = activitiesGroupBySender.find(function (activities) {
266
- return activities.includes(activity);
267
- });
268
- activityTree.push(senderTree);
269
- activitiesWithSameSender.forEach(function (activity) {
270
- var activitiesWithSameStatus = activitiesGroupByStatus.find(function (activities) {
271
- return activities.includes(activity);
272
- });
273
- var activitiesWithSameSenderAndStatus = (0, _intersectionOf.default)(visibleActivitiesPendingGrouping, activitiesWithSameSender, activitiesWithSameStatus);
274
-
275
- if (activitiesWithSameSenderAndStatus.length) {
276
- senderTree.push(activitiesWithSameSenderAndStatus);
277
-
278
- _removeInline.default.apply(void 0, [visibleActivitiesPendingGrouping].concat(_toConsumableArray(activitiesWithSameSenderAndStatus)));
279
- }
280
- });
281
- };
282
-
283
- while (visibleActivitiesPendingGrouping.length) {
284
- _loop();
285
- } // Assertion: All activities in visibleActivities, must be assigned to the activityTree
286
-
287
-
288
- if (!visibleActivities.every(function (activity) {
289
- return activityTree.some(function (activitiesWithSameSender) {
290
- return activitiesWithSameSender.some(function (activitiesWithSameSenderAndStatus) {
291
- return activitiesWithSameSenderAndStatus.includes(activity);
292
- });
293
- });
294
- })) {
295
- console.warn('botframework-webchat internal: Not all visible activities are grouped in the activityTree.', {
296
- visibleActivities: visibleActivities,
297
- activityTree: activityTree
298
- });
195
+ var callbackRef = (0, _react.useCallback)(function (element) {
196
+ if (typeof ref === 'function') {
197
+ ref(element);
198
+ } else {
199
+ ref.current = element;
299
200
  }
300
201
 
301
- return activityTree;
302
- }, [activitiesGroupBySender, activitiesGroupByStatus, visibleActivities]); // Flatten the tree back into an array with information related to rendering.
202
+ rootElementRef.current = element;
203
+ }, [ref, rootElementRef]); // Flatten the tree back into an array with information related to rendering.
303
204
 
304
205
  var renderingElements = (0, _react.useMemo)(function () {
305
206
  var renderingElements = [];
306
207
  var topSideBotNub = (0, _isZeroOrPositive.default)(bubbleNubOffset);
307
208
  var topSideUserNub = (0, _isZeroOrPositive.default)(bubbleFromUserNubOffset);
308
- activityTree.forEach(function (activitiesWithSameSender) {
309
- var _activitiesWithSameSe = _slicedToArray(activitiesWithSameSender, 1),
310
- _activitiesWithSameSe2 = _slicedToArray(_activitiesWithSameSe[0], 1),
311
- firstActivity = _activitiesWithSameSe2[0];
209
+ activityWithRendererTree.forEach(function (entriesWithSameSender) {
210
+ var _entriesWithSameSende = _slicedToArray(entriesWithSameSender, 1),
211
+ _entriesWithSameSende2 = _slicedToArray(_entriesWithSameSende[0], 1),
212
+ firstActivity = _entriesWithSameSende2[0].activity;
312
213
 
313
214
  var renderAvatar = createAvatarRenderer({
314
215
  activity: firstActivity
315
216
  });
316
- activitiesWithSameSender.forEach(function (activitiesWithSameSenderAndStatus, indexWithinSenderGroup) {
217
+ entriesWithSameSender.forEach(function (entriesWithSameSenderAndStatus, indexWithinSenderGroup) {
317
218
  var firstInSenderGroup = !indexWithinSenderGroup;
318
- var lastInSenderGroup = indexWithinSenderGroup === activitiesWithSameSender.length - 1;
319
- activitiesWithSameSenderAndStatus.forEach(function (activity, indexWithinSenderAndStatusGroup) {
320
- var _activity$channelData, _activity$channelData2, _activity$channelData3, _activity$channelData4, _activity$channelData5;
219
+ var lastInSenderGroup = indexWithinSenderGroup === entriesWithSameSender.length - 1;
220
+ entriesWithSameSenderAndStatus.forEach(function (_ref2, indexWithinSenderAndStatusGroup) {
221
+ var _activity$from;
321
222
 
223
+ var activity = _ref2.activity,
224
+ renderActivity = _ref2.renderActivity;
322
225
  // We only show the timestamp at the end of the sender group. But we always show the "Send failed, retry" prompt.
226
+ var firstInSenderAndStatusGroup = !indexWithinSenderAndStatusGroup;
227
+ var key = getKeyByActivity(activity);
228
+ var lastInSenderAndStatusGroup = indexWithinSenderAndStatusGroup === entriesWithSameSenderAndStatus.length - 1;
323
229
  var renderActivityStatus = createActivityStatusRenderer({
324
- activity: activity
230
+ activity: activity,
231
+ nextVisibleActivity: undefined
325
232
  });
326
- var firstInSenderAndStatusGroup = !indexWithinSenderAndStatusGroup;
327
- var lastInSenderAndStatusGroup = indexWithinSenderAndStatusGroup === activitiesWithSameSenderAndStatus.length - 1;
328
-
329
- var _activitiesWithRender = activitiesWithRenderer.find(function (entry) {
330
- return entry.activity === activity;
331
- }),
332
- renderActivity = _activitiesWithRender.renderActivity;
333
-
334
- var key = (0, _getActivityUniqueId.default)(activity) || renderingElements.length;
335
- var baseAltText = typeof (activity === null || activity === void 0 ? void 0 : (_activity$channelData = activity.channelData) === null || _activity$channelData === void 0 ? void 0 : _activity$channelData['webchat:fallback-text']) === 'string' ? activity === null || activity === void 0 ? void 0 : (_activity$channelData2 = activity.channelData) === null || _activity$channelData2 === void 0 ? void 0 : _activity$channelData2['webchat:fallback-text'] : (activity === null || activity === void 0 ? void 0 : (_activity$channelData3 = activity.channelData) === null || _activity$channelData3 === void 0 ? void 0 : (_activity$channelData4 = _activity$channelData3.messageBack) === null || _activity$channelData4 === void 0 ? void 0 : _activity$channelData4.displayText) || activity.text; // If "webchat:fallback-text" field is set to empty string, the activity must not be narrated.
336
-
337
- var supportScreenReader = (activity === null || activity === void 0 ? void 0 : (_activity$channelData5 = activity.channelData) === null || _activity$channelData5 === void 0 ? void 0 : _activity$channelData5['webchat:fallback-text']) !== '';
338
- var role = activity.from.role;
339
- var topSideNub = role === 'user' ? topSideUserNub : topSideBotNub;
233
+ var topSideNub = ((_activity$from = activity.from) === null || _activity$from === void 0 ? void 0 : _activity$from.role) === 'user' ? topSideUserNub : topSideBotNub;
340
234
  var showCallout; // Depending on the "showAvatarInGroup" setting, the avatar will render in different positions.
341
235
 
342
236
  if (showAvatarInGroup === 'sender') {
@@ -355,167 +249,78 @@ var InternalTranscript = function InternalTranscript(_ref) {
355
249
  showCallout = true;
356
250
  }
357
251
 
358
- var focusActivity = function focusActivity() {
359
- setFocusedActivityKey((0, _getActivityUniqueId.default)(activity)); // IE11 need to manually focus on the transcript.
360
-
361
- var rootElement = rootElementRef.current;
362
- rootElement && rootElement.focus();
363
- };
364
-
365
252
  renderingElements.push({
366
253
  activity: activity,
367
254
  // After the element is mounted, set it to activityElementsRef.
368
255
  callbackRef: function callbackRef(activityElement) {
369
- var entry = activityElementsRef.current.find(function (_ref3) {
370
- var activityID = _ref3.activityID;
371
- return activityID === activity.id;
372
- });
373
-
374
- if (entry) {
375
- entry.element = activityElement;
376
- }
377
- },
378
- // Calling this function will put the focus on the transcript and the activity.
379
- focusActivity: focusActivity,
380
- // When a child of the activity receives focus, notify the transcript to set the aria-activedescendant to this activity.
381
- handleFocus: function handleFocus() {
382
- setFocusedActivityKey((0, _getActivityUniqueId.default)(activity));
383
- },
384
- handleKeyDown: function handleKeyDown(event) {
385
- if (event.key === 'Escape') {
386
- event.preventDefault();
387
- event.stopPropagation();
388
- setFocusedActivityKey((0, _getActivityUniqueId.default)(activity));
389
- var current = rootElementRef.current;
390
- current && current.focus();
391
- }
392
- },
393
- // For accessibility: when the user press up/down arrow keys, we put a visual focus indicator around the focused activity.
394
- // We should do the same for mouse, that is why we have the click handler here.
395
- // We are doing it in event capture phase to prevent other components from stopping event propagation to us.
396
- handleMouseDownCapture: function handleMouseDownCapture(_ref4) {
397
- var target = _ref4.target;
398
- var tabIndex = (0, _getTabIndex.default)(target);
399
-
400
- if (typeof tabIndex !== 'number' || tabIndex < 0 || target.getAttribute('aria-disabled') === 'true') {
401
- focusActivity();
402
- }
256
+ activityElement ? activityElementMapRef.current.set(key, activityElement) : activityElementMapRef.current.delete(key);
403
257
  },
404
258
  // "hideTimestamp" is a render-time parameter for renderActivityStatus().
405
259
  // If true, it will hide the timestamp, but it will continue to show the
406
260
  // retry prompt. And show the screen reader version of the timestamp.
407
- hideTimestamp: hideAllTimestamps || indexWithinSenderAndStatusGroup !== activitiesWithSameSenderAndStatus.length - 1,
261
+ hideTimestamp: hideAllTimestamps || indexWithinSenderAndStatusGroup !== entriesWithSameSenderAndStatus.length - 1,
408
262
  key: key,
409
- // When "liveRegionKey" changes or contents that made up the alt text changed, it will show up in the live region momentarily.
410
- liveRegionKey: key + '|' + baseAltText,
411
263
  renderActivity: renderActivity,
412
264
  renderActivityStatus: renderActivityStatus,
413
265
  renderAvatar: renderAvatar,
414
- role: role,
415
- // TODO: [P2] #2858 We should use core/definitions/speakingActivity for this predicate instead
416
- shouldSpeak: activity.channelData && activity.channelData.speak,
417
- showCallout: showCallout,
418
- supportScreenReader: supportScreenReader
266
+ showCallout: showCallout
419
267
  });
420
268
  });
421
269
  });
422
270
  });
423
- var activityElements = activityElementsRef.current; // Update activityElementRef with new sets of activity, while retaining the existing referencing element if exists.
424
-
425
- activityElementsRef.current = renderingElements.map(function (_ref5) {
426
- var activity = _ref5.activity,
427
- id = _ref5.activity.id,
428
- elementId = _ref5.elementId,
429
- key = _ref5.key;
430
- var existingEntry = activityElements.find(function (entry) {
431
- return entry.key === key;
432
- });
433
- return {
434
- activity: activity,
435
- activityID: id,
436
- ariaLabelID: existingEntry ? existingEntry.ariaLabelID : "webchat__basic-transcript__activity-label-".concat((0, _mathRandom.default)().toString(36).substr(2, 5)),
437
- element: existingEntry && existingEntry.element,
438
- elementId: elementId,
439
- key: key
440
- };
441
- }); // There must be one focused (a.k.a. aria-activedescendant) designated. We default it to the last one.
442
-
443
- if (!renderingElements.find(function (_ref6) {
444
- var focused = _ref6.focused;
445
- return focused;
446
- })) {
447
- var lastElement = renderingElements[renderingElements.length - 1];
448
-
449
- if (lastElement) {
450
- lastElement.focused = true;
451
- }
452
- }
453
-
454
271
  return renderingElements;
455
- }, [activitiesWithRenderer, activityElementsRef, activityTree, bubbleFromUserNubOffset, bubbleNubOffset, createActivityStatusRenderer, createAvatarRenderer, hideAllTimestamps, rootElementRef, showAvatarInGroup]);
456
- var renderingActivities = (0, _react.useMemo)(function () {
457
- return renderingElements.map(function (_ref7) {
458
- var activity = _ref7.activity;
459
- return activity;
460
- });
461
- }, [renderingElements]);
272
+ }, [activityElementMapRef, activityWithRendererTree, bubbleFromUserNubOffset, bubbleNubOffset, createActivityStatusRenderer, createAvatarRenderer, getKeyByActivity, hideAllTimestamps, showAvatarInGroup]);
462
273
  var scrollToBottomScrollTo = (0, _reactScrollToBottom.useScrollTo)();
463
274
  var scrollToBottomScrollToEnd = (0, _reactScrollToBottom.useScrollToEnd)();
464
275
  var scrollTo = (0, _react.useCallback)(function (position) {
465
- var _ref8 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
466
- _ref8$behavior = _ref8.behavior,
467
- behavior = _ref8$behavior === void 0 ? 'auto' : _ref8$behavior;
276
+ var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
277
+ _ref3$behavior = _ref3.behavior,
278
+ behavior = _ref3$behavior === void 0 ? 'auto' : _ref3$behavior;
468
279
 
469
280
  if (!position) {
470
281
  throw new Error('botframework-webchat: First argument passed to "useScrollTo" must be a ScrollPosition object.');
471
282
  }
472
283
 
473
- var activityID = position.activityID,
284
+ var activityId = position.activityID,
474
285
  scrollTop = position.scrollTop;
475
286
 
476
287
  if (typeof scrollTop !== 'undefined') {
477
288
  scrollToBottomScrollTo(scrollTop, {
478
289
  behavior: behavior
479
290
  });
480
- } else if (typeof activityID !== 'undefined') {
481
- var rootElement = rootElementRef.current;
291
+ } else if (typeof activityId !== 'undefined') {
292
+ var _activityElementMapRe;
482
293
 
483
- var _ref9 = activityElementsRef.current.find(function (entry) {
484
- return entry.activityID === activityID;
485
- }) || {},
486
- activityElement = _ref9.element;
294
+ var activityBoundingBoxElement = (_activityElementMapRe = activityElementMapRef.current.get(getKeyByActivityId(activityId))) === null || _activityElementMapRe === void 0 ? void 0 : _activityElementMapRe.querySelector('.webchat__basic-transcript__activity-active-descendant');
295
+ var scrollableElement = rootElementRef.current.querySelector('.webchat__basic-transcript__scrollable');
487
296
 
488
- var scrollableElement = rootElement.querySelector('.webchat__basic-transcript__scrollable');
297
+ if (scrollableElement && activityBoundingBoxElement) {
298
+ // ESLint conflict with TypeScript. The result of getClientRects() is not an Array but DOMRectList, and cannot be destructured.
299
+ // eslint-disable-next-line prefer-destructuring
300
+ var _activityBoundingBoxE = activityBoundingBoxElement.getClientRects()[0],
301
+ activityHeight = _activityBoundingBoxE.height,
302
+ activityY = _activityBoundingBoxE.y; // ESLint conflict with TypeScript. The result of getClientRects() is not an Array but DOMRectList, and cannot be destructured.
303
+ // eslint-disable-next-line prefer-destructuring
489
304
 
490
- if (scrollableElement && activityElement) {
491
- var _activityElement$getC = activityElement.getClientRects(),
492
- _activityElement$getC2 = _slicedToArray(_activityElement$getC, 1),
493
- _activityElement$getC3 = _activityElement$getC2[0],
494
- activityElementHeight = _activityElement$getC3.height,
495
- activityElementY = _activityElement$getC3.y;
305
+ var scrollableHeight = scrollableElement.getClientRects()[0].height;
306
+ var activityOffsetTop = activityY + scrollableElement.scrollTop;
496
307
 
497
- var _scrollableElement$ge = scrollableElement.getClientRects(),
498
- _scrollableElement$ge2 = _slicedToArray(_scrollableElement$ge, 1),
499
- scrollableHeight = _scrollableElement$ge2[0].height;
500
-
501
- var activityElementOffsetTop = activityElementY + scrollableElement.scrollTop;
502
-
503
- var _scrollTop = Math.min(activityElementOffsetTop, activityElementOffsetTop - scrollableHeight + activityElementHeight);
308
+ var _scrollTop = Math.min(activityOffsetTop, activityOffsetTop - scrollableHeight + activityHeight);
504
309
 
505
310
  scrollToBottomScrollTo(_scrollTop, {
506
311
  behavior: behavior
507
312
  });
508
313
  }
509
314
  }
510
- }, [activityElementsRef, rootElementRef, scrollToBottomScrollTo]);
315
+ }, [activityElementMapRef, getKeyByActivityId, rootElementRef, scrollToBottomScrollTo]);
511
316
  var scrollToEnd = (0, _react.useCallback)(function () {
512
317
  return scrollToBottomScrollToEnd({
513
318
  behavior: 'smooth'
514
319
  });
515
320
  }, [scrollToBottomScrollToEnd]);
516
321
  var scrollRelative = (0, _react.useCallback)(function (direction) {
517
- var _ref10 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
518
- displacement = _ref10.displacement;
322
+ var _ref4 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
323
+ displacement = _ref4.displacement;
519
324
 
520
325
  var rootElement = rootElementRef.current;
521
326
 
@@ -527,8 +332,10 @@ var InternalTranscript = function InternalTranscript(_ref) {
527
332
  var nextScrollTop;
528
333
 
529
334
  if (typeof displacement === 'number') {
335
+ // eslint-disable-next-line no-magic-numbers
530
336
  nextScrollTop = scrollable.scrollTop + (direction === 'down' ? 1 : -1) * displacement;
531
337
  } else {
338
+ // eslint-disable-next-line no-magic-numbers
532
339
  nextScrollTop = scrollable.scrollTop + (direction === 'down' ? 1 : -1) * scrollable.offsetHeight;
533
340
  }
534
341
 
@@ -543,129 +350,47 @@ var InternalTranscript = function InternalTranscript(_ref) {
543
350
  (0, _useRegisterScrollTo.default)(scrollTo);
544
351
  (0, _useRegisterScrollToEnd.default)(scrollToEnd);
545
352
  (0, _useRegisterScrollRelative.default)(scrollRelative);
546
- var dispatchScrollPosition = (0, _useDispatchScrollPosition.default)();
547
- var patchedDispatchScrollPosition = (0, _react.useMemo)(function () {
548
- if (!dispatchScrollPosition) {
549
- return;
550
- }
353
+ var markActivityKeyAsRead = useMarkActivityKeyAsRead();
354
+ var dispatchScrollPositionWithActivityId = (0, _useDispatchScrollPosition.default)(); // TODO: [P2] We should use IntersectionObserver to track what activity is in the scrollable.
355
+ // However, IntersectionObserver is not available on IE11, we need to make a limited polyfill in React style.
551
356
 
552
- return function (_ref11) {
553
- var scrollTop = _ref11.scrollTop;
554
- var rootElement = rootElementRef.current;
357
+ var handleScrollPosition = (0, _react.useCallback)(function (_ref5) {
358
+ var _ref6;
555
359
 
556
- if (!rootElement) {
557
- return;
558
- }
559
-
560
- var scrollableElement = rootElement.querySelector('.webchat__basic-transcript__scrollable');
360
+ var scrollTop = _ref5.scrollTop;
361
+ var rootElement = rootElementRef.current;
561
362
 
562
- var _scrollableElement$ge3 = scrollableElement.getClientRects(),
563
- _scrollableElement$ge4 = _slicedToArray(_scrollableElement$ge3, 1),
564
- _scrollableElement$ge5 = _scrollableElement$ge4[0];
363
+ if (!rootElement) {
364
+ return;
365
+ }
565
366
 
566
- _scrollableElement$ge5 = _scrollableElement$ge5 === void 0 ? {} : _scrollableElement$ge5;
567
- var offsetHeight = _scrollableElement$ge5.height; // Find the activity just above scroll view bottom.
568
- // If the scroll view is already on top, get the first activity.
367
+ var scrollableElement = rootElement.querySelector('.webchat__basic-transcript__scrollable'); // "getClientRects()" is not returning an array, thus, it is not destructurable.
368
+ // eslint-disable-next-line prefer-destructuring
569
369
 
570
- var entry = scrollableElement.scrollTop ? _toConsumableArray(activityElementsRef.current).reverse().find(function (_ref12) {
571
- var element = _ref12.element;
370
+ var scrollableClientBottom = scrollableElement.getClientRects()[0].bottom; // Find the activity just above scroll view bottom.
371
+ // If the scroll view is already on top, get the first activity.
572
372
 
573
- if (!element) {
574
- return false;
575
- }
373
+ var activityElements = Array.from(activityElementMapRef.current.entries());
374
+ var activityKeyJustAboveScrollBottom = (_ref6 = scrollableElement.scrollTop ? activityElements.reverse() // Add subpixel tolerance
375
+ .find(function (_ref7) {
376
+ var _ref8 = _slicedToArray(_ref7, 2),
377
+ element = _ref8[1];
576
378
 
577
- var _element$getClientRec = element.getClientRects(),
578
- _element$getClientRec2 = _slicedToArray(_element$getClientRec, 1),
579
- _element$getClientRec3 = _element$getClientRec2[0];
379
+ return element.getClientRects()[0].bottom < scrollableClientBottom + 1;
380
+ }) : activityElements[0]) === null || _ref6 === void 0 ? void 0 : _ref6[0]; // When the end-user slowly scrolling the view down, we will mark activity as read when the message fully appear on the screen.
580
381
 
581
- _element$getClientRec3 = _element$getClientRec3 === void 0 ? {} : _element$getClientRec3;
582
- var y = _element$getClientRec3.y;
583
- return y < offsetHeight;
584
- }) : activityElementsRef.current[0];
382
+ activityKeyJustAboveScrollBottom && markActivityKeyAsRead(activityKeyJustAboveScrollBottom);
585
383
 
586
- var _ref13 = entry || {},
587
- activityID = _ref13.activityID;
588
-
589
- dispatchScrollPosition(_objectSpread(_objectSpread({}, activityID ? {
590
- activityID: activityID
384
+ if (dispatchScrollPositionWithActivityId) {
385
+ var activity = getActivityByKey(activityKeyJustAboveScrollBottom);
386
+ dispatchScrollPositionWithActivityId(_objectSpread(_objectSpread({}, activity ? {
387
+ activityID: activity.id
591
388
  } : {}), {}, {
592
389
  scrollTop: scrollTop
593
390
  }));
594
- };
595
- }, [activityElementsRef, dispatchScrollPosition, rootElementRef]);
596
- (0, _reactScrollToBottom.useObserveScrollPosition)(patchedDispatchScrollPosition);
597
-
598
- var _useAcknowledgedActiv = (0, _useAcknowledgedActivity.default)(),
599
- _useAcknowledgedActiv2 = _slicedToArray(_useAcknowledgedActiv, 1),
600
- lastInteractedActivity = _useAcknowledgedActiv2[0];
601
-
602
- var indexOfLastInteractedActivity = activities.indexOf(lastInteractedActivity); // Create a new ID for aria-activedescendant every time the active descendant change.
603
- // In our design, the transcript will only have 1 focused activity and it has an ID. Other blurred activities will not have ID assigned.
604
- // This help with performance.
605
- // But browser usually do noop if the value of aria-activedescendant doesn't change.
606
- // That means, if we assign the same ID to another element, browser will do noop.
607
- // We need to generate a new ID so the browser see there is a change in aria-activedescendant value and perform accordingly.
608
-
609
- var activeDescendantElementId = (0, _react.useMemo)(function () {
610
- return focusedActivityKey && "webchat__basic-transcript__active-descendant-".concat((0, _mathRandom.default)().toString(36).substr(2, 5));
611
- }, [focusedActivityKey]);
612
- var scrollActiveDescendantIntoView = (0, _react.useCallback)(function () {
613
- var activeDescendant = activeDescendantElementId && document.getElementById(activeDescendantElementId); // Don't scroll active descendant into view if the focus is already inside it.
614
- // Otherwise, given the focus is on the send box, clicking on any <input> inside the Adaptive Cards may cause the view to move.
615
- // This UX is not desirable because click should not cause scroll.
616
-
617
- if (activeDescendant && !activeDescendant.contains(document.activeElement)) {
618
- // Checks if scrollIntoView support options or not.
619
- // - https://github.com/Modernizr/Modernizr/issues/1568#issuecomment-419457972
620
- // - https://stackoverflow.com/questions/46919627/is-it-possible-to-test-for-scrollintoview-browser-compatibility
621
- if ('scrollBehavior' in document.documentElement.style) {
622
- activeDescendant.scrollIntoView({
623
- block: 'nearest'
624
- });
625
- } else {
626
- // This is for browser that does not support options passed to scrollIntoView(), possibly IE11.
627
- var scrollableElement = rootElementRef.current.querySelector('.webchat__basic-transcript__scrollable');
628
- var scrollTopAtTopSide = activeDescendant.offsetTop;
629
- var scrollTopAtBottomSide = activeDescendant.offsetTop + activeDescendant.offsetHeight;
630
-
631
- if (scrollTopAtTopSide < scrollableElement.scrollTop) {
632
- scrollableElement.scrollTop = scrollTopAtTopSide;
633
- } else if (scrollTopAtBottomSide > scrollableElement.scrollTop + scrollableElement.offsetHeight) {
634
- scrollableElement.scrollTop = scrollTopAtBottomSide - scrollableElement.offsetHeight;
635
- }
636
- }
637
- }
638
- }, [activeDescendantElementId, rootElementRef]);
639
- var handleTranscriptFocus = (0, _react.useCallback)(function (event) {
640
- var currentTarget = event.currentTarget,
641
- target = event.target; // When focus is placed on the transcript, scroll active descendant into the view.
642
-
643
- currentTarget === target && scrollActiveDescendantIntoView();
644
- }, [scrollActiveDescendantIntoView]); // After new aria-activedescendant is assigned, we will need to scroll it into view.
645
- // User agent will scroll automatically for focusing element, but not for aria-activedescendant.
646
- // We need to do the scrolling manually.
647
-
648
- (0, _react.useEffect)(function () {
649
- return scrollActiveDescendantIntoView();
650
- }, [scrollActiveDescendantIntoView]); // If any activities has changed, reset the active descendant.
651
-
652
- (0, _react.useEffect)(function () {
653
- return setFocusedActivityKey(undefined);
654
- }, [activities, setFocusedActivityKey]);
655
- var focusRelativeActivity = (0, _react.useCallback)(function (delta) {
656
- if (isNaN(delta) || !renderingElements.length) {
657
- return setFocusedActivityKey(undefined);
658
391
  }
659
-
660
- var index = renderingElements.findIndex(function (_ref14) {
661
- var key = _ref14.key;
662
- return key === focusedActivityKey;
663
- });
664
- var nextIndex = ~index ? Math.max(0, Math.min(renderingElements.length - 1, index + delta)) : renderingElements.length - 1;
665
- var nextFocusedActivity = renderingElements[nextIndex];
666
- setFocusedActivityKey(nextFocusedActivity.key);
667
- rootElementRef.current && rootElementRef.current.focus();
668
- }, [focusedActivityKey, renderingElements, rootElementRef, setFocusedActivityKey]);
392
+ }, [activityElementMapRef, dispatchScrollPositionWithActivityId, getActivityByKey, markActivityKeyAsRead, rootElementRef]);
393
+ (0, _reactScrollToBottom.useObserveScrollPosition)(handleScrollPosition);
669
394
  var handleTranscriptKeyDown = (0, _react.useCallback)(function (event) {
670
395
  var target = event.target;
671
396
  var fromEndOfTranscriptIndicator = target === terminatorRef.current;
@@ -683,6 +408,7 @@ var InternalTranscript = function InternalTranscript(_ref) {
683
408
  break;
684
409
 
685
410
  case 'ArrowUp':
411
+ // eslint-disable-next-line no-magic-numbers
686
412
  focusRelativeActivity(fromEndOfTranscriptIndicator ? 0 : -1);
687
413
  break;
688
414
 
@@ -691,30 +417,13 @@ var InternalTranscript = function InternalTranscript(_ref) {
691
417
  break;
692
418
 
693
419
  case 'Enter':
420
+ // This is capturing plain ENTER.
421
+ // When screen reader is not running, or screen reader is running outside of scan mode, the ENTER key will be captured here.
694
422
  if (!fromEndOfTranscriptIndicator) {
695
- var focusedActivityEntry = renderingElements.find(function (_ref15) {
696
- var key = _ref15.key;
697
- return key === focusedActivityKey;
698
- });
423
+ var _activityElementMapRe2, _tabbableElements$;
699
424
 
700
- if (focusedActivityEntry) {
701
- var _ref16 = activityElementsRef.current.find(function (_ref17) {
702
- var activity = _ref17.activity;
703
- return activity === focusedActivityEntry.activity;
704
- }) || {},
705
- focusedActivityElement = _ref16.element;
706
-
707
- if (focusedActivityElement) {
708
- var _tabbableElements$fil = (0, _tabbableElements.default)(focusedActivityElement).filter(function (_ref18) {
709
- var className = _ref18.className;
710
- return className !== 'webchat__basic-transcript__activity-sentinel';
711
- }),
712
- _tabbableElements$fil2 = _slicedToArray(_tabbableElements$fil, 1),
713
- firstTabbableElement = _tabbableElements$fil2[0];
714
-
715
- firstTabbableElement && firstTabbableElement.focus();
716
- }
717
- }
425
+ var body = (_activityElementMapRe2 = activityElementMapRef.current.get(focusedActivityKeyRef.current)) === null || _activityElementMapRe2 === void 0 ? void 0 : _activityElementMapRe2.querySelector('.webchat__basic-transcript__activity-body');
426
+ (_tabbableElements$ = (0, _tabbableElements.default)(body)[0]) === null || _tabbableElements$ === void 0 ? void 0 : _tabbableElements$.focus();
718
427
  }
719
428
 
720
429
  break;
@@ -737,20 +446,7 @@ var InternalTranscript = function InternalTranscript(_ref) {
737
446
 
738
447
  event.stopPropagation();
739
448
  }
740
- }, [focusedActivityKey, activityElementsRef, focusRelativeActivity, focus, terminatorRef, renderingElements]);
741
- var labelId = (0, _useUniqueId.default)('webchat__basic-transcript__label'); // If SHIFT-TAB from "End of transcript" indicator, if focusedActivityKey is not set (or no longer exists), set it the the bottommost activity.
742
-
743
- var setBottommostFocusedActivityKeyIfNeeded = (0, _react.useCallback)(function () {
744
- if (!~renderingElements.findIndex(function (_ref19) {
745
- var key = _ref19.key;
746
- return key === focusedActivityKey;
747
- })) {
748
- var _ref20 = renderingElements[renderingElements.length - 1] || {},
749
- lastActivityKey = _ref20.key;
750
-
751
- setFocusedActivityKey(lastActivityKey);
752
- }
753
- }, [focusedActivityKey, renderingElements, setFocusedActivityKey]);
449
+ }, [activityElementMapRef, focus, focusedActivityKeyRef, focusRelativeActivity, terminatorRef]);
754
450
  var handleTranscriptKeyDownCapture = (0, _react.useCallback)(function (event) {
755
451
  var altKey = event.altKey,
756
452
  ctrlKey = event.ctrlKey,
@@ -771,47 +467,46 @@ var InternalTranscript = function InternalTranscript(_ref) {
771
467
  focus('sendBox');
772
468
  }
773
469
  }, [focus]);
774
- var focusTranscriptCallback = (0, _react.useCallback)(function () {
775
- return rootElementRef.current && rootElementRef.current.focus();
776
- }, [rootElementRef]);
777
- (0, _useRegisterFocusTranscript.default)(focusTranscriptCallback);
778
- var handleFocusActivity = (0, _react.useCallback)(function (key) {
779
- setFocusedActivityKey(key);
780
- rootElementRef.current && rootElementRef.current.focus();
781
- }, [setFocusedActivityKey]); // When the focusing activity has changed, dispatch an event to observers of "useObserveTranscriptFocus".
782
-
783
- var dispatchTranscriptFocus = (0, _useDispatchTranscriptFocus.default)();
784
- var focusedActivity = (0, _react.useMemo)(function () {
785
- var _ref21 = renderingElements.find(function (_ref22) {
786
- var key = _ref22.key;
787
- return key === focusedActivityKey;
788
- }) || {},
789
- activity = _ref21.activity;
790
-
791
- return activity;
792
- }, [focusedActivityKey, renderingElements]);
470
+ (0, _useRegisterFocusTranscript.default)((0, _react.useCallback)(function () {
471
+ return focusByActivityKey(undefined);
472
+ }, [focusByActivityKey])); // When the focusing activity has changed, dispatch an event to observers of "useObserveTranscriptFocus".
473
+
474
+ var dispatchTranscriptFocusByActivityKey = (0, _useDispatchTranscriptFocusByActivityKey.default)(); // Dispatch a "transcript focus" event based on user selection.
475
+ // We should not dispatch "transcript focus" when a new activity come. Although the selection change, it is not initiated from the user.
476
+
793
477
  (0, _react.useMemo)(function () {
794
- return dispatchTranscriptFocus && dispatchTranscriptFocus({
795
- activity: focusedActivity
796
- });
797
- }, [dispatchTranscriptFocus, focusedActivity]); // This is required by IE11.
478
+ return dispatchTranscriptFocusByActivityKey(focusedExplicitly ? focusedActivityKey : undefined);
479
+ }, [dispatchTranscriptFocusByActivityKey, focusedActivityKey, focusedExplicitly]); // When the transcript is being focused on, we should dispatch a "transcriptfocus" event.
480
+
481
+ var handleFocus = (0, _react.useCallback)( // We call "focusByActivityKey" with activity key of "true".
482
+ // It means, tries to focus on anything.
483
+ function (_ref9) {
484
+ var currentTarget = _ref9.currentTarget,
485
+ target = _ref9.target;
486
+ return target === currentTarget && focusByActivityKey(true, false);
487
+ }, [focusByActivityKey]); // This is required by IE11.
798
488
  // When the user clicks on and empty space (a.k.a. filler) in an empty transcript, IE11 says the focus is on the <div className="filler">,
799
489
  // despite the fact there are no "tabIndex" attributes set on the filler.
800
490
  // We need to artificially send the focus back to the transcript.
801
491
 
802
492
  var handleFocusFiller = (0, _react.useCallback)(function () {
803
- var current = rootElementRef.current;
804
- current && current.focus();
805
- }, [rootElementRef]);
493
+ return focusByActivityKey(undefined);
494
+ }, [focusByActivityKey]); // When focus into the transcript using TAB/SHIFT-TAB, scroll the focused activity into view.
495
+
496
+ (0, _useObserveFocusVisible.default)(rootElementRef, (0, _react.useCallback)(function () {
497
+ return focusByActivityKey(undefined);
498
+ }, [focusByActivityKey]));
806
499
  return /*#__PURE__*/_react.default.createElement("div", {
807
- "aria-activedescendant": focusedActivityKey ? activeDescendantElementId : undefined,
808
- "aria-labelledby": labelId,
500
+ // Although Android TalkBack 12.1 does not support `aria-activedescendant`, when used, it become buggy and will narrate content twice.
501
+ // We are disabling `aria-activedescendant` for Android. See <ActivityRow> for details.
502
+ "aria-activedescendant": _detectBrowser.android ? undefined : activeDescendantId,
503
+ "aria-label": transcriptAriaLabel,
809
504
  className: (0, _classnames.default)('webchat__basic-transcript', basicTranscriptStyleSet + '', rootClassName, (className || '') + ''),
810
505
  dir: direction,
811
- onFocus: handleTranscriptFocus,
506
+ onFocus: handleFocus,
812
507
  onKeyDown: handleTranscriptKeyDown,
813
508
  onKeyDownCapture: handleTranscriptKeyDownCapture,
814
- ref: rootElementRef // "aria-activedescendant" will only works with a number of roles and it must be explicitly set.
509
+ ref: callbackRef // "aria-activedescendant" will only works with a number of roles and it must be explicitly set.
815
510
  // https://www.w3.org/TR/wai-aria/#aria-activedescendant
816
511
  ,
817
512
  role: "group" // For up/down arrow key navigation across activities, this component must be included in the tab sequence.
@@ -819,171 +514,65 @@ var InternalTranscript = function InternalTranscript(_ref) {
819
514
  // https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_focus_activedescendant
820
515
  ,
821
516
  tabIndex: 0
822
- }, /*#__PURE__*/_react.default.createElement(_ScreenReaderText.default, {
823
- id: labelId,
824
- text: transcriptAriaLabel
825
- }), /*#__PURE__*/_react.default.createElement("section", {
826
- "aria-atomic": false,
827
- "aria-live": "polite",
828
- "aria-relevant": "additions",
829
- "aria-roledescription": transcriptRoleDescription,
830
- role: "log"
831
- }, renderingElements.filter(function (_ref23) {
832
- var supportScreenReader = _ref23.supportScreenReader;
833
- return supportScreenReader;
834
- }).map(function (_ref24) {
835
- var activity = _ref24.activity,
836
- liveRegionKey = _ref24.liveRegionKey;
837
- return /*#__PURE__*/_react.default.createElement(_Fade.default, {
838
- fadeAfter: internalLiveRegionFadeAfter,
839
- key: liveRegionKey
840
- }, function () {
841
- return /*#__PURE__*/_react.default.createElement(_ScreenReaderActivity.default, {
842
- activity: activity
843
- });
844
- });
845
- })), /*#__PURE__*/_react.default.createElement(InternalTranscriptScrollable, {
846
- activities: renderingActivities,
847
- onFocusActivity: handleFocusActivity,
517
+ }, /*#__PURE__*/_react.default.createElement(_LiveRegionTranscript.default, {
518
+ activityElementMapRef: activityElementMapRef
519
+ }), /*#__PURE__*/_react.default.createElement(InternalTranscriptScrollable, {
848
520
  onFocusFiller: handleFocusFiller,
849
521
  terminatorRef: terminatorRef
850
- }, renderingElements.map(function (_ref25, index) {
851
- var activity = _ref25.activity,
852
- callbackRef = _ref25.callbackRef,
853
- focusActivity = _ref25.focusActivity,
854
- handleFocus = _ref25.handleFocus,
855
- handleKeyDown = _ref25.handleKeyDown,
856
- handleMouseDownCapture = _ref25.handleMouseDownCapture,
857
- hideTimestamp = _ref25.hideTimestamp,
858
- key = _ref25.key,
859
- renderActivity = _ref25.renderActivity,
860
- renderActivityStatus = _ref25.renderActivityStatus,
861
- renderAvatar = _ref25.renderAvatar,
862
- role = _ref25.role,
863
- shouldSpeak = _ref25.shouldSpeak,
864
- showCallout = _ref25.showCallout,
865
- supportScreenReader = _ref25.supportScreenReader;
866
-
867
- var _ref26 = activityElementsRef.current.find(function (entry) {
868
- return entry.activity === activity;
869
- }) || {},
870
- ariaLabelID = _ref26.ariaLabelID,
871
- element = _ref26.element;
872
-
873
- var activeDescendant = focusedActivityKey === key;
874
- var isContentInteractive = !!(element ? (0, _tabbableElements.default)(element.querySelector('.webchat__basic-transcript__activity-box')).length : 0);
875
- return /*#__PURE__*/_react.default.createElement("li", {
876
- "aria-labelledby": ariaLabelID,
877
- className: (0, _classnames.default)('webchat__basic-transcript__activity', {
878
- 'webchat__basic-transcript__activity--acknowledged': index <= indexOfLastInteractedActivity,
879
- 'webchat__basic-transcript__activity--from-bot': role !== 'user',
880
- 'webchat__basic-transcript__activity--from-user': role === 'user'
881
- }) // Set "id" for valid for accessibility.
882
-
883
- /* eslint-disable-next-line react/forbid-dom-props */
884
- ,
885
- id: activeDescendant ? activeDescendantElementId : undefined,
522
+ }, renderingElements.map(function (_ref10) {
523
+ var activity = _ref10.activity,
524
+ callbackRef = _ref10.callbackRef,
525
+ hideTimestamp = _ref10.hideTimestamp,
526
+ key = _ref10.key,
527
+ renderActivity = _ref10.renderActivity,
528
+ renderActivityStatus = _ref10.renderActivityStatus,
529
+ renderAvatar = _ref10.renderAvatar,
530
+ showCallout = _ref10.showCallout;
531
+ return /*#__PURE__*/_react.default.createElement(_ActivityRow.default, {
532
+ activity: activity,
886
533
  key: key,
887
- onFocus: handleFocus,
888
- onKeyDown: handleKeyDown,
889
- onMouseDownCapture: handleMouseDownCapture,
890
534
  ref: callbackRef
891
- }, supportScreenReader && /*#__PURE__*/_react.default.createElement(_ScreenReaderActivity.default, {
892
- activity: activity,
893
- id: ariaLabelID,
894
- renderAttachments: false
895
- }, !!isContentInteractive && /*#__PURE__*/_react.default.createElement("p", null, activityInteractiveAlt)), /*#__PURE__*/_react.default.createElement(_FocusRedirector.default, {
896
- className: "webchat__basic-transcript__activity-sentinel",
897
- onFocus: focusActivity,
898
- redirectRef: rootElementRef
899
- }), /*#__PURE__*/_react.default.createElement("div", {
900
- className: "webchat__basic-transcript__activity-box"
901
535
  }, renderActivity({
902
536
  hideTimestamp: hideTimestamp,
903
537
  renderActivityStatus: renderActivityStatus,
904
538
  renderAvatar: renderAvatar,
905
539
  showCallout: showCallout
906
- })), shouldSpeak && /*#__PURE__*/_react.default.createElement(_Speak.default, {
907
- activity: activity
908
- }), /*#__PURE__*/_react.default.createElement(_FocusRedirector.default, {
909
- className: "webchat__basic-transcript__activity-sentinel",
910
- onFocus: focusActivity,
911
- redirectRef: rootElementRef
912
- }), /*#__PURE__*/_react.default.createElement("div", {
913
- className: (0, _classnames.default)('webchat__basic-transcript__activity-indicator', {
914
- 'webchat__basic-transcript__activity-indicator--first': !index,
915
- 'webchat__basic-transcript__activity-indicator--focus': activeDescendant
916
- })
917
540
  }));
918
- })), !!renderingElements.length && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_FocusRedirector.default, {
919
- className: "webchat__basic-transcript__sentinel",
920
- onFocus: setBottommostFocusedActivityKeyIfNeeded,
541
+ })), !!renderingElements.length && /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement(_FocusRedirector.default, {
921
542
  redirectRef: rootElementRef
922
543
  }), /*#__PURE__*/_react.default.createElement("div", {
544
+ "aria-hidden": true,
545
+ "aria-labelledby": terminatorLabelId,
923
546
  className: "webchat__basic-transcript__terminator",
924
547
  ref: terminatorRef,
548
+ role: "note",
925
549
  tabIndex: 0
926
550
  }, /*#__PURE__*/_react.default.createElement("div", {
927
551
  className: "webchat__basic-transcript__terminator-body"
928
552
  }, /*#__PURE__*/_react.default.createElement("div", {
929
- className: "webchat__basic-transcript__terminator-text"
553
+ className: "webchat__basic-transcript__terminator-text",
554
+ id: terminatorLabelId
930
555
  }, terminatorText)))), /*#__PURE__*/_react.default.createElement("div", {
931
556
  className: "webchat__basic-transcript__focus-indicator"
932
557
  }));
933
- };
934
-
558
+ });
935
559
  InternalTranscript.defaultProps = {
936
560
  className: ''
937
561
  };
938
562
  InternalTranscript.propTypes = {
939
- activityElementsRef: _propTypes.default.shape({
940
- current: _propTypes.default.array.isRequired
563
+ // PropTypes cannot validate precisely with its TypeScript counterpart.
564
+ // @ts-ignore
565
+ activityElementMapRef: _propTypes.default.shape({
566
+ current: _propTypes.default.instanceOf(Map)
941
567
  }).isRequired,
942
568
  className: _propTypes.default.string
943
569
  };
944
570
 
945
- var InternalScreenReaderTranscript = function InternalScreenReaderTranscript(_ref27) {
946
- var renderingElements = _ref27.renderingElements;
947
- var localize = useLocalizer();
948
-
949
- var _useStyleOptions3 = useStyleOptions(),
950
- _useStyleOptions4 = _slicedToArray(_useStyleOptions3, 1),
951
- internalLiveRegionFadeAfter = _useStyleOptions4[0];
952
-
953
- var transcriptRoleDescription = localize('TRANSCRIPT_ARIA_ROLE_ALT');
954
- return /*#__PURE__*/_react.default.createElement("section", {
955
- "aria-atomic": false,
956
- "aria-live": "polite",
957
- "aria-relevant": "additions",
958
- "aria-roledescription": transcriptRoleDescription,
959
- role: "log"
960
- }, renderingElements.map(function (_ref28) {
961
- var activity = _ref28.activity,
962
- liveRegionKey = _ref28.liveRegionKey;
963
- return /*#__PURE__*/_react.default.createElement(_Fade.default, {
964
- fadeAfter: internalLiveRegionFadeAfter,
965
- key: liveRegionKey
966
- }, function () {
967
- return /*#__PURE__*/_react.default.createElement(_ScreenReaderActivity.default, {
968
- activity: activity
969
- });
970
- });
971
- }));
972
- };
973
-
974
- InternalScreenReaderTranscript.propTypes = {
975
- renderingElements: _propTypes.default.arrayOf(_propTypes.default.shape({
976
- activity: _propTypes.default.any,
977
- liveRegionKey: _propTypes.default.string
978
- })).isRequired
979
- }; // Separating high-frequency hooks to improve performance.
980
-
981
- var InternalTranscriptScrollable = function InternalTranscriptScrollable(_ref29) {
982
- var activities = _ref29.activities,
983
- children = _ref29.children,
984
- onFocusActivity = _ref29.onFocusActivity,
985
- onFocusFiller = _ref29.onFocusFiller,
986
- terminatorRef = _ref29.terminatorRef;
571
+ // Separating high-frequency hooks to improve performance.
572
+ var InternalTranscriptScrollable = function InternalTranscriptScrollable(_ref11) {
573
+ var children = _ref11.children,
574
+ onFocusFiller = _ref11.onFocusFiller,
575
+ terminatorRef = _ref11.terminatorRef;
987
576
 
988
577
  var _useStyleSet3 = (0, _useStyleSet5.default)(),
989
578
  _useStyleSet4 = _slicedToArray(_useStyleSet3, 1),
@@ -997,62 +586,116 @@ var InternalTranscriptScrollable = function InternalTranscriptScrollable(_ref29)
997
586
  _useAtEnd2 = _slicedToArray(_useAtEnd, 1),
998
587
  atEnd = _useAtEnd2[0];
999
588
 
589
+ var _useActivityKeysByRea = useActivityKeysByRead(),
590
+ _useActivityKeysByRea2 = _slicedToArray(_useActivityKeysByRea, 2),
591
+ unreadActivityKeys = _useActivityKeysByRea2[1];
592
+
1000
593
  var _useSticky = (0, _reactScrollToBottom.useSticky)(),
1001
594
  _useSticky2 = _slicedToArray(_useSticky, 1),
1002
595
  sticky = _useSticky2[0];
1003
596
 
1004
- var _useStyleOptions5 = useStyleOptions(),
1005
- _useStyleOptions6 = _slicedToArray(_useStyleOptions5, 1),
1006
- styleOptions = _useStyleOptions6[0];
1007
-
1008
- var lastVisibleActivityId = (0, _getActivityUniqueId.default)(activities[activities.length - 1] || {}); // Activity ID of the last visible activity in the list.
597
+ var _useStyleOptions3 = useStyleOptions(),
598
+ _useStyleOptions4 = _slicedToArray(_useStyleOptions3, 1),
599
+ styleOptions = _useStyleOptions4[0];
1009
600
 
601
+ var focusByActivityKey = (0, _useFocusByActivityKey.default)();
1010
602
  var localize = useLocalizer();
603
+ var markActivityKeyAsRead = useMarkActivityKeyAsRead();
604
+ var markAllAsAcknowledged = useMarkAllAsAcknowledged();
1011
605
  var scrollToEnd = (0, _reactScrollToBottom.useScrollToEnd)();
1012
- var lastReadActivityIdRef = (0, _react.useRef)(lastVisibleActivityId);
606
+ var prevSticky = (0, _usePrevious.default)(sticky);
1013
607
  var transcriptRoleDescription = localize('TRANSCRIPT_ARIA_ROLE_ALT');
608
+ var stickyChangedToTrue = prevSticky !== sticky && sticky; // Acknowledged means either:
609
+ // 1. The user sent a message
610
+ // - We don't need a condition here. When Web Chat sends the user's message, it will scroll to bottom, and it will trigger condition 2 below.
611
+ // 2. The user scroll to the bottom of the transcript, from a non-bottom scroll position
612
+ // - If the transcript is already at the bottom, the user needs to scroll up and then go back down
613
+ // - What happens if we are relaxing "scrolled from a non-bottom scroll position":
614
+ // 1. The condition will become solely "at the bottom of the transcript"
615
+ // 2. Auto-scroll will always scroll the transcript to the bottom
616
+ // 3. Web Chat will always acknowledge all activities as it is at the bottom
617
+ // 4. Acknowledge flag become useless
618
+ // 5. Therefore, even the developer set "pause after 3 activities", if activities are coming in at a slow pace (not batched in a single render)
619
+ // Web Chat will keep scrolling and not snapped/paused
620
+ // Note: When Web Chat is loaded, there are no activities acknowledged. We need to assume all arriving activities are acknowledged until end-user sends their first activity.
621
+ // Activities loaded initially could be from conversation history. Without assuming acknowledgement, Web Chat will not scroll initially (as everything is not acknowledged).
622
+ // It would be better if the chat adapter should let Web Chat know if the activity is loaded from history or not.
623
+ // TODO: [P2] #3670 Move the "conversation history acknowledgement" logic mentioned above to polyfill of chat adapters.
624
+ // 1. Chat adapter should send "acknowledged" as part of "channelData"
625
+ // 2. If "acknowledged" is "undefined", we set it to:
626
+ // a. true, if there are no egress activities yet
627
+ // b. Otherwise, false
628
+
629
+ (0, _react.useMemo)(function () {
630
+ return stickyChangedToTrue && // TODO: [P2] Both `markActivityKeyAsRead` and `markAllAsAcknowledged` hook are setters of useState.
631
+ // This means, in a render loop, we will be calling setter and will cause another re-render.
632
+ // This is not trivial but we should think if there is a way to avoid this.
633
+ markAllAsAcknowledged();
634
+ }, [markAllAsAcknowledged, stickyChangedToTrue]);
635
+
636
+ var _useActivityTreeWithR3 = (0, _useActivityTreeWithRenderer.default)({
637
+ flat: true
638
+ }),
639
+ _useActivityTreeWithR4 = _slicedToArray(_useActivityTreeWithR3, 1),
640
+ flattenedActivityTreeWithRenderer = _useActivityTreeWithR4[0];
641
+
642
+ var getKeyByActivity = useGetKeyByActivity();
643
+ var renderingActivityKeys = (0, _react.useMemo)(function () {
644
+ return flattenedActivityTreeWithRenderer.map(function (_ref12) {
645
+ var activity = _ref12.activity;
646
+ return getKeyByActivity(activity);
647
+ });
648
+ }, [flattenedActivityTreeWithRenderer, getKeyByActivity]);
649
+ var renderingActivityKeysRef = (0, _useValueRef.default)(renderingActivityKeys); // To prevent flashy button, we are not waiting for another render loop to update the `[readActivityKeys, unreadActivityKeys]` state.
650
+ // Instead, we are building the next one in this `useMemo` call.
651
+
652
+ var nextUnreadActivityKeys = (0, _react.useMemo)(function () {
653
+ // This code need to be careful reviewed as it will cause another render. The code should be converging.
654
+ // After we call `markActivityKeyAsRead`, everything will be read and nothing will be unread.
655
+ // That means, in next render, `unreadActivityKeys` will be emptied and the `markActivityKeyAsRead` will not get called again.
656
+ if (sticky && unreadActivityKeys.length) {
657
+ markActivityKeyAsRead(unreadActivityKeys[unreadActivityKeys.length - 1]);
658
+ return [];
659
+ }
660
+
661
+ return unreadActivityKeys;
662
+ }, [markActivityKeyAsRead, sticky, unreadActivityKeys]);
663
+ var nextUnreadActivityKeysRef = (0, _useValueRef.default)(nextUnreadActivityKeys); // If we are rendering anything that is unread, we should show the "New messages" button.
664
+ // Not everything in the `unreadActivityKeys` are rendered, say, bot typing indicator.
665
+ // We should not show the "New messages" button for bot typing indicator as it will confuse the user.
666
+
667
+ var unread = (0, _react.useMemo)(function () {
668
+ return nextUnreadActivityKeys.some(function (key) {
669
+ return renderingActivityKeys.includes(key);
670
+ });
671
+ }, [renderingActivityKeys, nextUnreadActivityKeys]);
1014
672
  var handleScrollToEndButtonClick = (0, _react.useCallback)(function () {
1015
673
  scrollToEnd({
1016
674
  behavior: 'smooth'
1017
- }); // After the "New message" button is clicked, focus on the first unread activity.
675
+ });
676
+ var renderingActivityKeys = renderingActivityKeysRef.current; // After the "New message" button is clicked, focus on the first unread activity which will be rendered.
1018
677
 
1019
- var index = activities.findIndex(function (_ref30) {
1020
- var id = _ref30.id;
1021
- return id === lastReadActivityIdRef.current;
678
+ var firstUnreadRenderingActivityKey = nextUnreadActivityKeysRef.current.find(function (key) {
679
+ return renderingActivityKeys.includes(key);
1022
680
  });
1023
681
 
1024
- if (~index) {
1025
- var firstUnreadActivity = activities[index + 1];
682
+ if (firstUnreadRenderingActivityKey) {
683
+ focusByActivityKey(firstUnreadRenderingActivityKey);
684
+ } else {
685
+ var _terminatorRef$curren;
1026
686
 
1027
- if (firstUnreadActivity) {
1028
- return onFocusActivity((0, _getActivityUniqueId.default)(firstUnreadActivity));
1029
- }
687
+ // If no unread activity, send the focus to the terminator block.
688
+ (_terminatorRef$curren = terminatorRef.current) === null || _terminatorRef$curren === void 0 ? void 0 : _terminatorRef$curren.focus();
1030
689
  }
1031
-
1032
- var current = terminatorRef.current;
1033
- current && current.focus();
1034
- }, [activities, lastReadActivityIdRef, onFocusActivity, scrollToEnd, terminatorRef]);
1035
-
1036
- if (atEnd || sticky) {
1037
- // If it is sticky or at the end, the user is at the bottom of the transcript, everything is read.
1038
- // So mark the activity ID as read.
1039
- lastReadActivityIdRef.current = lastVisibleActivityId;
1040
- }
1041
-
1042
- var ScrollToEndButton = useCreateScrollToEndButtonRenderer()({
690
+ }, [focusByActivityKey, nextUnreadActivityKeysRef, renderingActivityKeysRef, scrollToEnd, terminatorRef]);
691
+ var renderScrollToEndButton = useCreateScrollToEndButtonRenderer()({
1043
692
  atEnd: animatingToEnd || atEnd || sticky,
1044
693
  styleOptions: styleOptions,
1045
- // Unread means:
1046
- // 1. Last read is not the last one in the transcript, and;
1047
- // 2. Last read is still in the transcript.
1048
- unread: lastVisibleActivityId !== lastReadActivityIdRef.current && !!~activities.findIndex(function (activity) {
1049
- return (0, _getActivityUniqueId.default)(activity) === lastReadActivityIdRef.current;
1050
- })
694
+ unread: unread
1051
695
  });
1052
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, ScrollToEndButton && /*#__PURE__*/_react.default.createElement(ScrollToEndButton, {
696
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, renderScrollToEndButton && renderScrollToEndButton({
1053
697
  onClick: handleScrollToEndButtonClick
1054
698
  }), !!_react.default.Children.count(children) && /*#__PURE__*/_react.default.createElement(_FocusRedirector.default, {
1055
- className: "webchat__basic-transcript__sentinel",
1056
699
  redirectRef: terminatorRef
1057
700
  }), /*#__PURE__*/_react.default.createElement(_reactScrollToBottom.Panel, {
1058
701
  className: "webchat__basic-transcript__scrollable"
@@ -1060,129 +703,129 @@ var InternalTranscriptScrollable = function InternalTranscriptScrollable(_ref29)
1060
703
  "aria-hidden": true,
1061
704
  className: "webchat__basic-transcript__filler",
1062
705
  onFocus: onFocusFiller
1063
- }), /*#__PURE__*/_react.default.createElement("ul", {
706
+ }), /*#__PURE__*/_react.default.createElement("section", {
1064
707
  "aria-roledescription": transcriptRoleDescription,
1065
708
  className: (0, _classnames.default)(activitiesStyleSet + '', 'webchat__basic-transcript__transcript'),
1066
- role: "list"
709
+ role: "feed"
1067
710
  }, children), /*#__PURE__*/_react.default.createElement(_BasicTypingIndicator.default, null)));
1068
711
  };
1069
712
 
1070
713
  InternalTranscriptScrollable.propTypes = {
1071
- activities: _propTypes.default.array.isRequired,
1072
714
  children: _propTypes.default.any.isRequired,
1073
- onFocusActivity: _propTypes.default.func.isRequired,
1074
715
  onFocusFiller: _propTypes.default.func.isRequired,
1075
716
  terminatorRef: _propTypes.default.any.isRequired
1076
717
  };
1077
718
 
1078
- var SetScroller = function SetScroller(_ref31) {
1079
- var activityElementsRef = _ref31.activityElementsRef,
1080
- scrollerRef = _ref31.scrollerRef;
1081
-
1082
- var _useStyleOptions7 = useStyleOptions(),
1083
- _useStyleOptions8 = _slicedToArray(_useStyleOptions7, 1),
1084
- _useStyleOptions8$ = _useStyleOptions8[0],
1085
- autoScrollSnapOnActivity = _useStyleOptions8$.autoScrollSnapOnActivity,
1086
- autoScrollSnapOnActivityOffset = _useStyleOptions8$.autoScrollSnapOnActivityOffset,
1087
- autoScrollSnapOnPage = _useStyleOptions8$.autoScrollSnapOnPage,
1088
- autoScrollSnapOnPageOffset = _useStyleOptions8$.autoScrollSnapOnPageOffset;
1089
-
1090
- var _useActivities3 = useActivities(),
1091
- _useActivities4 = _slicedToArray(_useActivities3, 1),
1092
- activities = _useActivities4[0];
1093
-
1094
- var _useAcknowledgedActiv3 = (0, _useAcknowledgedActivity.default)(),
1095
- _useAcknowledgedActiv4 = _slicedToArray(_useAcknowledgedActiv3, 1),
1096
- lastAcknowledgedActivity = _useAcknowledgedActiv4[0];
1097
-
1098
- var activitiesRef = (0, _react.useRef)(activities);
1099
- var lastAcknowledgedActivityRef = (0, _react.useRef)(lastAcknowledgedActivity);
1100
- activitiesRef.current = activities;
1101
- lastAcknowledgedActivityRef.current = lastAcknowledgedActivity;
1102
- scrollerRef.current = (0, _react.useCallback)(function (_ref32) {
1103
- var offsetHeight = _ref32.offsetHeight,
1104
- scrollTop = _ref32.scrollTop;
719
+ // "scroller" is the auto-scroll limiter, a.k.a. auto scroll snap.
720
+ var useScroller = function useScroller(activityElementMapRef) {
721
+ var _useActivityKeys = useActivityKeys(),
722
+ _useActivityKeys2 = _slicedToArray(_useActivityKeys, 1),
723
+ activityKeys = _useActivityKeys2[0];
724
+
725
+ var _useLastAcknowledgedA = useLastAcknowledgedActivityKey(),
726
+ _useLastAcknowledgedA2 = _slicedToArray(_useLastAcknowledgedA, 1),
727
+ lastAcknowledgedActivityKey = _useLastAcknowledgedA2[0];
728
+
729
+ var _useStyleOptions5 = useStyleOptions(),
730
+ _useStyleOptions6 = _slicedToArray(_useStyleOptions5, 1),
731
+ styleOptions = _useStyleOptions6[0];
732
+
733
+ var activityKeysRef = (0, _useValueRef.default)(activityKeys);
734
+ var lastAcknowledgedActivityKeyRef = (0, _useValueRef.default)(lastAcknowledgedActivityKey);
735
+ var styleOptionsRef = (0, _useValueRef.default)(styleOptions);
736
+ return (0, _react.useCallback)(function (_ref13) {
737
+ var offsetHeight = _ref13.offsetHeight,
738
+ scrollTop = _ref13.scrollTop;
739
+ var _styleOptionsRef$curr = styleOptionsRef.current,
740
+ autoScrollSnapOnActivity = _styleOptionsRef$curr.autoScrollSnapOnActivity,
741
+ autoScrollSnapOnActivityOffset = _styleOptionsRef$curr.autoScrollSnapOnActivityOffset,
742
+ autoScrollSnapOnPage = _styleOptionsRef$curr.autoScrollSnapOnPage,
743
+ autoScrollSnapOnPageOffset = _styleOptionsRef$curr.autoScrollSnapOnPageOffset;
1105
744
  var patchedAutoScrollSnapOnActivity = typeof autoScrollSnapOnActivity === 'number' ? Math.max(0, autoScrollSnapOnActivity) : autoScrollSnapOnActivity ? 1 : 0;
1106
745
  var patchedAutoScrollSnapOnPage = typeof autoScrollSnapOnPage === 'number' ? Math.max(0, Math.min(1, autoScrollSnapOnPage)) : autoScrollSnapOnPage ? 1 : 0;
1107
746
  var patchedAutoScrollSnapOnActivityOffset = typeof autoScrollSnapOnActivityOffset === 'number' ? autoScrollSnapOnActivityOffset : 0;
1108
747
  var patchedAutoScrollSnapOnPageOffset = typeof autoScrollSnapOnPageOffset === 'number' ? autoScrollSnapOnPageOffset : 0;
1109
748
 
1110
749
  if (patchedAutoScrollSnapOnActivity || patchedAutoScrollSnapOnPage) {
1111
- var _activities = activitiesRef.current;
1112
- var activityElements = activityElementsRef.current;
1113
- var _lastAcknowledgedActivity = lastAcknowledgedActivityRef.current;
750
+ var activityElementMap = activityElementMapRef.current;
751
+ var _activityKeys = activityKeysRef.current;
752
+ var _lastAcknowledgedActivityKey = lastAcknowledgedActivityKeyRef.current;
1114
753
  var values = [];
1115
754
 
1116
- var lastAcknowledgedActivityIndex = _activities.indexOf(_lastAcknowledgedActivity);
755
+ var lastAcknowledgedActivityKeyIndex = _activityKeys.indexOf(_lastAcknowledgedActivityKey);
1117
756
 
1118
- if (~lastAcknowledgedActivityIndex) {
757
+ if (~lastAcknowledgedActivityKeyIndex) {
1119
758
  // The activity that we acknowledged could be not rendered, such as post back activity.
1120
759
  // When calculating scroll snap, we can only base on the first unacknowledged-and-rendering activity.
760
+ var renderingActivityKeys = Array.from(activityElementMap.keys());
1121
761
  var firstUnacknowledgedActivityElementIndex = -1;
1122
762
 
1123
- var _loop2 = function _loop2(index, length) {
1124
- var activity = _activities[index];
1125
- var activityElementIndex = activityElements.findIndex(function (entry) {
1126
- return entry.activity === activity;
1127
- });
763
+ var _iterator = _createForOfIteratorHelper(_activityKeys.slice(0, lastAcknowledgedActivityKeyIndex + 1).reverse()),
764
+ _step;
1128
765
 
1129
- if (~activityElementIndex) {
1130
- firstUnacknowledgedActivityElementIndex = activityElementIndex;
1131
- return "break";
1132
- }
1133
- };
766
+ try {
767
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
768
+ var acknowledgedActivityKey = _step.value;
769
+ var index = renderingActivityKeys.indexOf(acknowledgedActivityKey);
1134
770
 
1135
- for (var index = lastAcknowledgedActivityIndex + 1, length = _activities.length; index < length; index++) {
1136
- var _ret = _loop2(index, length);
771
+ if (~index) {
772
+ if (index !== renderingActivityKeys.length - 1) {
773
+ firstUnacknowledgedActivityElementIndex = index + 1;
774
+ }
1137
775
 
1138
- if (_ret === "break") break;
776
+ break;
777
+ }
778
+ }
779
+ } catch (err) {
780
+ _iterator.e(err);
781
+ } finally {
782
+ _iterator.f();
1139
783
  }
1140
784
 
1141
785
  if (~firstUnacknowledgedActivityElementIndex) {
786
+ var activityElements = Array.from(activityElementMap.values());
787
+
1142
788
  if (patchedAutoScrollSnapOnActivity) {
1143
789
  // Gets the activity element which we should snap to.
1144
- var nthUnacknowledgedActivityElement = activityElements[firstUnacknowledgedActivityElementIndex + patchedAutoScrollSnapOnActivity - 1].element;
790
+ var nthUnacknowledgedActivityElement = activityElements[firstUnacknowledgedActivityElementIndex + patchedAutoScrollSnapOnActivity - 1];
1145
791
 
1146
792
  if (nthUnacknowledgedActivityElement) {
1147
- values.push(nthUnacknowledgedActivityElement.offsetTop + nthUnacknowledgedActivityElement.offsetHeight - offsetHeight - scrollTop + patchedAutoScrollSnapOnActivityOffset);
793
+ var nthUnacknowledgedActivityBoundingBoxElement = nthUnacknowledgedActivityElement === null || nthUnacknowledgedActivityElement === void 0 ? void 0 : nthUnacknowledgedActivityElement.querySelector('.webchat__basic-transcript__activity-active-descendant');
794
+ var nthUnacknowledgedActivityOffsetTop = nthUnacknowledgedActivityElement.offsetTop + nthUnacknowledgedActivityBoundingBoxElement.offsetTop;
795
+ values.push(nthUnacknowledgedActivityOffsetTop + nthUnacknowledgedActivityBoundingBoxElement.offsetHeight - offsetHeight - scrollTop + patchedAutoScrollSnapOnActivityOffset);
1148
796
  }
1149
797
  }
1150
798
 
1151
799
  if (patchedAutoScrollSnapOnPage) {
1152
- var firstUnacknowledgedActivityElement = activityElements[firstUnacknowledgedActivityElementIndex].element;
1153
- values.push(firstUnacknowledgedActivityElement.offsetTop - scrollTop - offsetHeight * (1 - patchedAutoScrollSnapOnPage) + patchedAutoScrollSnapOnPageOffset);
800
+ var firstUnacknowledgedActivityElement = activityElements[+firstUnacknowledgedActivityElementIndex];
801
+ var firstUnacknowledgedActivityBoundingBoxElement = firstUnacknowledgedActivityElement.querySelector('.webchat__basic-transcript__activity-active-descendant');
802
+ var firstUnacknowledgedActivityOffsetTop = firstUnacknowledgedActivityElement.offsetTop + firstUnacknowledgedActivityBoundingBoxElement.offsetTop;
803
+ values.push(firstUnacknowledgedActivityOffsetTop - scrollTop - offsetHeight * (1 - patchedAutoScrollSnapOnPage) + patchedAutoScrollSnapOnPageOffset);
1154
804
  }
1155
805
  }
1156
806
  }
1157
807
 
1158
- return values.reduce(function (minValue, value) {
1159
- return Math.min(minValue, value);
1160
- }, Infinity);
808
+ return Math.min.apply(Math, values);
1161
809
  }
1162
810
 
1163
811
  return Infinity;
1164
- }, [activitiesRef, activityElementsRef, autoScrollSnapOnActivity, autoScrollSnapOnActivityOffset, autoScrollSnapOnPage, autoScrollSnapOnPageOffset, lastAcknowledgedActivityRef]);
1165
- return false;
812
+ }, [activityElementMapRef, activityKeysRef, lastAcknowledgedActivityKeyRef, styleOptionsRef]);
1166
813
  };
1167
814
 
1168
- var BasicTranscript = function BasicTranscript(_ref33) {
1169
- var className = _ref33.className;
1170
- var activityElementsRef = (0, _react.useRef)([]);
1171
- var scrollerRef = (0, _react.useRef)(function () {
1172
- return Infinity;
1173
- });
1174
- var scroller = (0, _react.useCallback)(function () {
1175
- return scrollerRef.current.apply(scrollerRef, arguments);
1176
- }, [scrollerRef]);
1177
- return /*#__PURE__*/_react.default.createElement(_reactScrollToBottom.Composer, {
815
+ var BasicTranscript = function BasicTranscript(_ref14) {
816
+ var className = _ref14.className;
817
+ var activityElementMapRef = (0, _react.useRef)(new Map());
818
+ var containerRef = (0, _react.useRef)();
819
+ var scroller = useScroller(activityElementMapRef);
820
+ return /*#__PURE__*/_react.default.createElement(_TranscriptFocusComposer.default, {
821
+ containerRef: containerRef
822
+ }, /*#__PURE__*/_react.default.createElement(_reactScrollToBottom.Composer, {
1178
823
  scroller: scroller
1179
- }, /*#__PURE__*/_react.default.createElement(SetScroller, {
1180
- activityElementsRef: activityElementsRef,
1181
- scrollerRef: scrollerRef
1182
- }), /*#__PURE__*/_react.default.createElement(InternalTranscript, {
1183
- activityElementsRef: activityElementsRef,
1184
- className: className
1185
- }));
824
+ }, /*#__PURE__*/_react.default.createElement(_KeyboardHelp.default, null), /*#__PURE__*/_react.default.createElement(InternalTranscript, {
825
+ activityElementMapRef: activityElementMapRef,
826
+ className: className,
827
+ ref: containerRef
828
+ })));
1186
829
  };
1187
830
 
1188
831
  BasicTranscript.defaultProps = {
@@ -1193,4 +836,4 @@ BasicTranscript.propTypes = {
1193
836
  };
1194
837
  var _default = BasicTranscript;
1195
838
  exports.default = _default;
1196
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9CYXNpY1RyYW5zY3JpcHQuanMiXSwibmFtZXMiOlsidXNlQWN0aXZpdGllcyIsImhvb2tzIiwidXNlQ3JlYXRlQWN0aXZpdHlSZW5kZXJlciIsInVzZUNyZWF0ZUFjdGl2aXR5U3RhdHVzUmVuZGVyZXIiLCJ1c2VDcmVhdGVBdmF0YXJSZW5kZXJlciIsInVzZUNyZWF0ZVNjcm9sbFRvRW5kQnV0dG9uUmVuZGVyZXIiLCJ1c2VEaXJlY3Rpb24iLCJ1c2VHcm91cEFjdGl2aXRpZXMiLCJ1c2VMb2NhbGl6ZXIiLCJ1c2VTdHlsZU9wdGlvbnMiLCJST09UX1NUWUxFIiwiZGlzcGxheSIsImZsZXhEaXJlY3Rpb24iLCJvdmVyZmxvdyIsInBvc2l0aW9uIiwiZmxleCIsIm92ZXJmbG93WCIsIldlYmtpdE92ZXJmbG93U2Nyb2xsaW5nIiwibGlzdFN0eWxlVHlwZSIsInZhbGlkYXRlQWxsQWN0aXZpdGllc1RhZ2dlZCIsImFjdGl2aXRpZXMiLCJiaW5zIiwiZXZlcnkiLCJhY3Rpdml0eSIsInNvbWUiLCJiaW4iLCJpbmNsdWRlcyIsIkludGVybmFsVHJhbnNjcmlwdCIsImFjdGl2aXR5RWxlbWVudHNSZWYiLCJjbGFzc05hbWUiLCJiYXNpY1RyYW5zY3JpcHRTdHlsZVNldCIsImJhc2ljVHJhbnNjcmlwdCIsImJ1YmJsZUZyb21Vc2VyTnViT2Zmc2V0IiwiYnViYmxlTnViT2Zmc2V0IiwiZ3JvdXBUaW1lc3RhbXAiLCJpbnRlcm5hbExpdmVSZWdpb25GYWRlQWZ0ZXIiLCJzaG93QXZhdGFySW5Hcm91cCIsImZvY3VzZWRBY3Rpdml0eUtleSIsInNldEZvY3VzZWRBY3Rpdml0eUtleSIsImRpcmVjdGlvbiIsImNyZWF0ZUFjdGl2aXR5UmVuZGVyZXIiLCJjcmVhdGVBY3Rpdml0eVN0YXR1c1JlbmRlcmVyIiwiY3JlYXRlQXZhdGFyUmVuZGVyZXIiLCJmb2N1cyIsImdyb3VwQWN0aXZpdGllcyIsImxvY2FsaXplIiwicm9vdENsYXNzTmFtZSIsInJvb3RFbGVtZW50UmVmIiwidGVybWluYXRvclJlZiIsImFjdGl2aXR5SW50ZXJhY3RpdmVBbHQiLCJ0ZXJtaW5hdG9yVGV4dCIsInRyYW5zY3JpcHRBcmlhTGFiZWwiLCJ0cmFuc2NyaXB0Um9sZURlc2NyaXB0aW9uIiwiaGlkZUFsbFRpbWVzdGFtcHMiLCJjcmVhdGVBY3Rpdml0eVJlbmRlcmVyV2l0aExpdGVyYWxBcmdzIiwibmV4dFZpc2libGVBY3Rpdml0eSIsImFjdGl2aXRpZXNXaXRoUmVuZGVyZXIiLCJjcmVhdGVBY3Rpdml0eVJlbmRlcmVyV2l0aExpdGVyYWxBcmdzTWVtb2l6ZWQiLCJpbmRleCIsImxlbmd0aCIsInJlbmRlckFjdGl2aXR5Iiwic3BsaWNlIiwidmlzaWJsZUFjdGl2aXRpZXMiLCJtYXAiLCJhY3Rpdml0aWVzR3JvdXBCeVNlbmRlciIsInNlbmRlciIsImFjdGl2aXRpZXNHcm91cEJ5U3RhdHVzIiwic3RhdHVzIiwiY29uc29sZSIsIndhcm4iLCJhY3Rpdml0eVRyZWUiLCJ2aXNpYmxlQWN0aXZpdGllc1BlbmRpbmdHcm91cGluZyIsInNlbmRlclRyZWUiLCJhY3Rpdml0aWVzV2l0aFNhbWVTZW5kZXIiLCJmaW5kIiwicHVzaCIsImZvckVhY2giLCJhY3Rpdml0aWVzV2l0aFNhbWVTdGF0dXMiLCJhY3Rpdml0aWVzV2l0aFNhbWVTZW5kZXJBbmRTdGF0dXMiLCJyZW1vdmVJbmxpbmUiLCJyZW5kZXJpbmdFbGVtZW50cyIsInRvcFNpZGVCb3ROdWIiLCJ0b3BTaWRlVXNlck51YiIsImZpcnN0QWN0aXZpdHkiLCJyZW5kZXJBdmF0YXIiLCJpbmRleFdpdGhpblNlbmRlckdyb3VwIiwiZmlyc3RJblNlbmRlckdyb3VwIiwibGFzdEluU2VuZGVyR3JvdXAiLCJpbmRleFdpdGhpblNlbmRlckFuZFN0YXR1c0dyb3VwIiwicmVuZGVyQWN0aXZpdHlTdGF0dXMiLCJmaXJzdEluU2VuZGVyQW5kU3RhdHVzR3JvdXAiLCJsYXN0SW5TZW5kZXJBbmRTdGF0dXNHcm91cCIsImVudHJ5Iiwia2V5IiwiYmFzZUFsdFRleHQiLCJjaGFubmVsRGF0YSIsIm1lc3NhZ2VCYWNrIiwiZGlzcGxheVRleHQiLCJ0ZXh0Iiwic3VwcG9ydFNjcmVlblJlYWRlciIsInJvbGUiLCJmcm9tIiwidG9wU2lkZU51YiIsInNob3dDYWxsb3V0IiwiZm9jdXNBY3Rpdml0eSIsInJvb3RFbGVtZW50IiwiY3VycmVudCIsImNhbGxiYWNrUmVmIiwiYWN0aXZpdHlFbGVtZW50IiwiYWN0aXZpdHlJRCIsImlkIiwiZWxlbWVudCIsImhhbmRsZUZvY3VzIiwiaGFuZGxlS2V5RG93biIsImV2ZW50IiwicHJldmVudERlZmF1bHQiLCJzdG9wUHJvcGFnYXRpb24iLCJoYW5kbGVNb3VzZURvd25DYXB0dXJlIiwidGFyZ2V0IiwidGFiSW5kZXgiLCJnZXRBdHRyaWJ1dGUiLCJoaWRlVGltZXN0YW1wIiwibGl2ZVJlZ2lvbktleSIsInNob3VsZFNwZWFrIiwic3BlYWsiLCJhY3Rpdml0eUVsZW1lbnRzIiwiZWxlbWVudElkIiwiZXhpc3RpbmdFbnRyeSIsImFyaWFMYWJlbElEIiwidG9TdHJpbmciLCJzdWJzdHIiLCJmb2N1c2VkIiwibGFzdEVsZW1lbnQiLCJyZW5kZXJpbmdBY3Rpdml0aWVzIiwic2Nyb2xsVG9Cb3R0b21TY3JvbGxUbyIsInNjcm9sbFRvQm90dG9tU2Nyb2xsVG9FbmQiLCJzY3JvbGxUbyIsImJlaGF2aW9yIiwiRXJyb3IiLCJzY3JvbGxUb3AiLCJzY3JvbGxhYmxlRWxlbWVudCIsInF1ZXJ5U2VsZWN0b3IiLCJnZXRDbGllbnRSZWN0cyIsImFjdGl2aXR5RWxlbWVudEhlaWdodCIsImhlaWdodCIsImFjdGl2aXR5RWxlbWVudFkiLCJ5Iiwic2Nyb2xsYWJsZUhlaWdodCIsImFjdGl2aXR5RWxlbWVudE9mZnNldFRvcCIsIk1hdGgiLCJtaW4iLCJzY3JvbGxUb0VuZCIsInNjcm9sbFJlbGF0aXZlIiwiZGlzcGxhY2VtZW50Iiwic2Nyb2xsYWJsZSIsIm5leHRTY3JvbGxUb3AiLCJvZmZzZXRIZWlnaHQiLCJtYXgiLCJzY3JvbGxIZWlnaHQiLCJkaXNwYXRjaFNjcm9sbFBvc2l0aW9uIiwicGF0Y2hlZERpc3BhdGNoU2Nyb2xsUG9zaXRpb24iLCJyZXZlcnNlIiwibGFzdEludGVyYWN0ZWRBY3Rpdml0eSIsImluZGV4T2ZMYXN0SW50ZXJhY3RlZEFjdGl2aXR5IiwiaW5kZXhPZiIsImFjdGl2ZURlc2NlbmRhbnRFbGVtZW50SWQiLCJzY3JvbGxBY3RpdmVEZXNjZW5kYW50SW50b1ZpZXciLCJhY3RpdmVEZXNjZW5kYW50IiwiZG9jdW1lbnQiLCJnZXRFbGVtZW50QnlJZCIsImNvbnRhaW5zIiwiYWN0aXZlRWxlbWVudCIsImRvY3VtZW50RWxlbWVudCIsInN0eWxlIiwic2Nyb2xsSW50b1ZpZXciLCJibG9jayIsInNjcm9sbFRvcEF0VG9wU2lkZSIsIm9mZnNldFRvcCIsInNjcm9sbFRvcEF0Qm90dG9tU2lkZSIsImhhbmRsZVRyYW5zY3JpcHRGb2N1cyIsImN1cnJlbnRUYXJnZXQiLCJ1bmRlZmluZWQiLCJmb2N1c1JlbGF0aXZlQWN0aXZpdHkiLCJkZWx0YSIsImlzTmFOIiwiZmluZEluZGV4IiwibmV4dEluZGV4IiwibmV4dEZvY3VzZWRBY3Rpdml0eSIsImhhbmRsZVRyYW5zY3JpcHRLZXlEb3duIiwiZnJvbUVuZE9mVHJhbnNjcmlwdEluZGljYXRvciIsImZyb21UcmFuc2NyaXB0IiwiaGFuZGxlZCIsIkluZmluaXR5IiwiZm9jdXNlZEFjdGl2aXR5RW50cnkiLCJmb2N1c2VkQWN0aXZpdHlFbGVtZW50IiwiZmlsdGVyIiwiZmlyc3RUYWJiYWJsZUVsZW1lbnQiLCJsYWJlbElkIiwic2V0Qm90dG9tbW9zdEZvY3VzZWRBY3Rpdml0eUtleUlmTmVlZGVkIiwibGFzdEFjdGl2aXR5S2V5IiwiaGFuZGxlVHJhbnNjcmlwdEtleURvd25DYXB0dXJlIiwiYWx0S2V5IiwiY3RybEtleSIsIm1ldGFLZXkiLCJmb2N1c1RyYW5zY3JpcHRDYWxsYmFjayIsImhhbmRsZUZvY3VzQWN0aXZpdHkiLCJkaXNwYXRjaFRyYW5zY3JpcHRGb2N1cyIsImZvY3VzZWRBY3Rpdml0eSIsImhhbmRsZUZvY3VzRmlsbGVyIiwiaXNDb250ZW50SW50ZXJhY3RpdmUiLCJkZWZhdWx0UHJvcHMiLCJwcm9wVHlwZXMiLCJQcm9wVHlwZXMiLCJzaGFwZSIsImFycmF5IiwiaXNSZXF1aXJlZCIsInN0cmluZyIsIkludGVybmFsU2NyZWVuUmVhZGVyVHJhbnNjcmlwdCIsImFycmF5T2YiLCJhbnkiLCJJbnRlcm5hbFRyYW5zY3JpcHRTY3JvbGxhYmxlIiwiY2hpbGRyZW4iLCJvbkZvY3VzQWN0aXZpdHkiLCJvbkZvY3VzRmlsbGVyIiwiYWN0aXZpdGllc1N0eWxlU2V0IiwiYW5pbWF0aW5nVG9FbmQiLCJhdEVuZCIsInN0aWNreSIsInN0eWxlT3B0aW9ucyIsImxhc3RWaXNpYmxlQWN0aXZpdHlJZCIsImxhc3RSZWFkQWN0aXZpdHlJZFJlZiIsImhhbmRsZVNjcm9sbFRvRW5kQnV0dG9uQ2xpY2siLCJmaXJzdFVucmVhZEFjdGl2aXR5IiwiU2Nyb2xsVG9FbmRCdXR0b24iLCJ1bnJlYWQiLCJSZWFjdCIsIkNoaWxkcmVuIiwiY291bnQiLCJmdW5jIiwiU2V0U2Nyb2xsZXIiLCJzY3JvbGxlclJlZiIsImF1dG9TY3JvbGxTbmFwT25BY3Rpdml0eSIsImF1dG9TY3JvbGxTbmFwT25BY3Rpdml0eU9mZnNldCIsImF1dG9TY3JvbGxTbmFwT25QYWdlIiwiYXV0b1Njcm9sbFNuYXBPblBhZ2VPZmZzZXQiLCJsYXN0QWNrbm93bGVkZ2VkQWN0aXZpdHkiLCJhY3Rpdml0aWVzUmVmIiwibGFzdEFja25vd2xlZGdlZEFjdGl2aXR5UmVmIiwicGF0Y2hlZEF1dG9TY3JvbGxTbmFwT25BY3Rpdml0eSIsInBhdGNoZWRBdXRvU2Nyb2xsU25hcE9uUGFnZSIsInBhdGNoZWRBdXRvU2Nyb2xsU25hcE9uQWN0aXZpdHlPZmZzZXQiLCJwYXRjaGVkQXV0b1Njcm9sbFNuYXBPblBhZ2VPZmZzZXQiLCJ2YWx1ZXMiLCJsYXN0QWNrbm93bGVkZ2VkQWN0aXZpdHlJbmRleCIsImZpcnN0VW5hY2tub3dsZWRnZWRBY3Rpdml0eUVsZW1lbnRJbmRleCIsImFjdGl2aXR5RWxlbWVudEluZGV4IiwibnRoVW5hY2tub3dsZWRnZWRBY3Rpdml0eUVsZW1lbnQiLCJmaXJzdFVuYWNrbm93bGVkZ2VkQWN0aXZpdHlFbGVtZW50IiwicmVkdWNlIiwibWluVmFsdWUiLCJ2YWx1ZSIsIkJhc2ljVHJhbnNjcmlwdCIsInNjcm9sbGVyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFFQTs7QUFDQTs7QUFVQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFFQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVBLElBQ0VBLGFBREYsR0FVSUMsNkJBVkosQ0FDRUQsYUFERjtBQUFBLElBRUVFLHlCQUZGLEdBVUlELDZCQVZKLENBRUVDLHlCQUZGO0FBQUEsSUFHRUMsK0JBSEYsR0FVSUYsNkJBVkosQ0FHRUUsK0JBSEY7QUFBQSxJQUlFQyx1QkFKRixHQVVJSCw2QkFWSixDQUlFRyx1QkFKRjtBQUFBLElBS0VDLGtDQUxGLEdBVUlKLDZCQVZKLENBS0VJLGtDQUxGO0FBQUEsSUFNRUMsWUFORixHQVVJTCw2QkFWSixDQU1FSyxZQU5GO0FBQUEsSUFPRUMsa0JBUEYsR0FVSU4sNkJBVkosQ0FPRU0sa0JBUEY7QUFBQSxJQVFFQyxZQVJGLEdBVUlQLDZCQVZKLENBUUVPLFlBUkY7QUFBQSxJQVNFQyxlQVRGLEdBVUlSLDZCQVZKLENBU0VRLGVBVEY7QUFZQSxJQUFNQyxVQUFVLEdBQUc7QUFDakIsaUNBQStCO0FBQzdCQyxJQUFBQSxPQUFPLEVBQUUsTUFEb0I7QUFFN0JDLElBQUFBLGFBQWEsRUFBRSxRQUZjO0FBRzdCQyxJQUFB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R0EsSUFBTWMsZUFBZSxHQUFHLFNBQWxCQSxlQUFrQixTQUFtQjtBQUFBLE1BQWhCeE8sU0FBZ0IsVUFBaEJBLFNBQWdCO0FBQ3pDLE1BQU1ELG1CQUFtQixHQUFHLG1CQUFPLEVBQVAsQ0FBNUI7QUFDQSxNQUFNb04sV0FBVyxHQUFHLG1CQUFPO0FBQUEsV0FBTWhELFFBQU47QUFBQSxHQUFQLENBQXBCO0FBRUEsTUFBTXNFLFFBQVEsR0FBRyx3QkFBWTtBQUFBLFdBQWF0QixXQUFXLENBQUN0SSxPQUFaLE9BQUFzSSxXQUFXLFlBQXhCO0FBQUEsR0FBWixFQUF1RCxDQUFDQSxXQUFELENBQXZELENBQWpCO0FBRUEsc0JBQ0UsNkJBQUMsNkJBQUQ7QUFBNkIsSUFBQSxRQUFRLEVBQUVzQjtBQUF2QyxrQkFDRSw2QkFBQyxXQUFEO0FBQWEsSUFBQSxtQkFBbUIsRUFBRTFPLG1CQUFsQztBQUF1RCxJQUFBLFdBQVcsRUFBRW9OO0FBQXBFLElBREYsZUFFRSw2QkFBQyxrQkFBRDtBQUFvQixJQUFBLG1CQUFtQixFQUFFcE4sbUJBQXpDO0FBQThELElBQUEsU0FBUyxFQUFFQztBQUF6RSxJQUZGLENBREY7QUFNRCxDQVpEOztBQWNBd08sZUFBZSxDQUFDbkQsWUFBaEIsR0FBK0I7QUFDN0JyTCxFQUFBQSxTQUFTLEVBQUU7QUFEa0IsQ0FBL0I7QUFJQXdPLGVBQWUsQ0FBQ2xELFNBQWhCLEdBQTRCO0FBQzFCdEwsRUFBQUEsU0FBUyxFQUFFdUwsbUJBQVVJO0FBREssQ0FBNUI7ZUFJZTZDLGUiLCJzb3VyY2VSb290IjoiY29tcG9uZW50Oi8vLyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludCBuby1tYWdpYy1udW1iZXJzOiBbXCJlcnJvclwiLCB7IFwiaWdub3JlXCI6IFstMSwgMCwgMSwgMiwgNSwgMzZdIH1dICovXG5cbmltcG9ydCB7IGhvb2tzIH0gZnJvbSAnYm90ZnJhbWV3b3JrLXdlYmNoYXQtYXBpJztcbmltcG9ydCB7XG4gIENvbXBvc2VyIGFzIFJlYWN0U2Nyb2xsVG9Cb3R0b21Db21wb3NlcixcbiAgUGFuZWwgYXMgUmVhY3RTY3JvbGxUb0JvdHRvbVBhbmVsLFxuICB1c2VBbmltYXRpbmdUb0VuZCxcbiAgdXNlQXRFbmQsXG4gIHVzZU9ic2VydmVTY3JvbGxQb3NpdGlvbixcbiAgdXNlU2Nyb2xsVG8sXG4gIHVzZVNjcm9sbFRvRW5kLFxuICB1c2VTdGlja3lcbn0gZnJvbSAncmVhY3Qtc2Nyb2xsLXRvLWJvdHRvbSc7XG5pbXBvcnQgY2xhc3NOYW1lcyBmcm9tICdjbGFzc25hbWVzJztcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5pbXBvcnQgcmFuZG9tIGZyb20gJ21hdGgtcmFuZG9tJztcbmltcG9ydCBSZWFjdCwgeyB1c2VDYWxsYmFjaywgdXNlRWZmZWN0LCB1c2VNZW1vLCB1c2VSZWYsIHVzZVN0YXRlIH0gZnJvbSAncmVhY3QnO1xuXG5pbXBvcnQgQmFzaWNUeXBpbmdJbmRpY2F0b3IgZnJvbSAnLi9CYXNpY1R5cGluZ0luZGljYXRvcic7XG5pbXBvcnQgRmFkZSBmcm9tICcuL1V0aWxzL0ZhZGUnO1xuaW1wb3J0IEZvY3VzUmVkaXJlY3RvciBmcm9tICcuL1V0aWxzL0ZvY3VzUmVkaXJlY3Rvcic7XG5pbXBvcnQgZ2V0QWN0aXZpdHlVbmlxdWVJZCBmcm9tICcuL1V0aWxzL2dldEFjdGl2aXR5VW5pcXVlSWQnO1xuaW1wb3J0IGdldFRhYkluZGV4IGZyb20gJy4vVXRpbHMvVHlwZUZvY3VzU2luay9nZXRUYWJJbmRleCc7XG5pbXBvcnQgaW5wdXR0YWJsZUtleSBmcm9tICcuL1V0aWxzL1R5cGVGb2N1c1NpbmsvaW5wdXR0YWJsZUtleSc7XG5pbXBvcnQgaW50ZXJzZWN0aW9uT2YgZnJvbSAnLi9VdGlscy9pbnRlcnNlY3Rpb25PZic7XG5pbXBvcnQgaXNaZXJvT3JQb3NpdGl2ZSBmcm9tICcuL1V0aWxzL2lzWmVyb09yUG9zaXRpdmUnO1xuaW1wb3J0IHJlbW92ZUlubGluZSBmcm9tICcuL1V0aWxzL3JlbW92ZUlubGluZSc7XG5pbXBvcnQgU2NyZWVuUmVhZGVyQWN0aXZpdHkgZnJvbSAnLi9TY3JlZW5SZWFkZXJBY3Rpdml0eSc7XG5pbXBvcnQgU2NyZWVuUmVhZGVyVGV4dCBmcm9tICcuL1NjcmVlblJlYWRlclRleHQnO1xuaW1wb3J0IFNwZWFrQWN0aXZpdHkgZnJvbSAnLi9BY3Rpdml0eS9TcGVhayc7XG5pbXBvcnQgdGFiYmFibGVFbGVtZW50cyBmcm9tICcuL1V0aWxzL3RhYmJhYmxlRWxlbWVudHMnO1xuaW1wb3J0IHVzZUFja25vd2xlZGdlZEFjdGl2aXR5IGZyb20gJy4vaG9va3MvaW50ZXJuYWwvdXNlQWNrbm93bGVkZ2VkQWN0aXZpdHknO1xuaW1wb3J0IHVzZURpc3BhdGNoU2Nyb2xsUG9zaXRpb24gZnJvbSAnLi9ob29rcy9pbnRlcm5hbC91c2VEaXNwYXRjaFNjcm9sbFBvc2l0aW9uJztcbmltcG9ydCB1c2VEaXNwYXRjaFRyYW5zY3JpcHRGb2N1cyBmcm9tICcuL2hvb2tzL2ludGVybmFsL3VzZURpc3BhdGNoVHJhbnNjcmlwdEZvY3VzJztcbmltcG9ydCB1c2VGb2N1cyBmcm9tICcuL2hvb2tzL3VzZUZvY3VzJztcbmltcG9ydCB1c2VNZW1vaXplIGZyb20gJy4vaG9va3MvaW50ZXJuYWwvdXNlTWVtb2l6ZSc7XG5pbXBvcnQgdXNlUmVnaXN0ZXJGb2N1c1RyYW5zY3JpcHQgZnJvbSAnLi9ob29rcy9pbnRlcm5hbC91c2VSZWdpc3RlckZvY3VzVHJhbnNjcmlwdCc7XG5pbXBvcnQgdXNlUmVnaXN0ZXJTY3JvbGxSZWxhdGl2ZSBmcm9tICcuL2hvb2tzL2ludGVybmFsL3VzZVJlZ2lzdGVyU2Nyb2xsUmVsYXRpdmUnO1xuaW1wb3J0IHVzZVJlZ2lzdGVyU2Nyb2xsVG8gZnJvbSAnLi9ob29rcy9pbnRlcm5hbC91c2VSZWdpc3RlclNjcm9sbFRvJztcbmltcG9ydCB1c2VSZWdpc3RlclNjcm9sbFRvRW5kIGZyb20gJy4vaG9va3MvaW50ZXJuYWwvdXNlUmVnaXN0ZXJTY3JvbGxUb0VuZCc7XG5pbXBvcnQgdXNlU3R5bGVTZXQgZnJvbSAnLi9ob29rcy91c2VTdHlsZVNldCc7XG5pbXBvcnQgdXNlU3R5bGVUb0Vtb3Rpb25PYmplY3QgZnJvbSAnLi9ob29rcy9pbnRlcm5hbC91c2VTdHlsZVRvRW1vdGlvbk9iamVjdCc7XG5pbXBvcnQgdXNlVW5pcXVlSWQgZnJvbSAnLi9ob29rcy9pbnRlcm5hbC91c2VVbmlxdWVJZCc7XG5cbmNvbnN0IHtcbiAgdXNlQWN0aXZpdGllcyxcbiAgdXNlQ3JlYXRlQWN0aXZpdHlSZW5kZXJlcixcbiAgdXNlQ3JlYXRlQWN0aXZpdHlTdGF0dXNSZW5kZXJlcixcbiAgdXNlQ3JlYXRlQXZhdGFyUmVuZGVyZXIsXG4gIHVzZUNyZWF0ZVNjcm9sbFRvRW5kQnV0dG9uUmVuZGVyZXIsXG4gIHVzZURpcmVjdGlvbixcbiAgdXNlR3JvdXBBY3Rpdml0aWVzLFxuICB1c2VMb2NhbGl6ZXIsXG4gIHVzZVN0eWxlT3B0aW9uc1xufSA9IGhvb2tzO1xuXG5jb25zdCBST09UX1NUWUxFID0ge1xuICAnJi53ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0Jzoge1xuICAgIGRpc3BsYXk6ICdmbGV4JyxcbiAgICBmbGV4RGlyZWN0aW9uOiAnY29sdW1uJyxcbiAgICBvdmVyZmxvdzogJ2hpZGRlbicsXG4gICAgLy8gTWFrZSBzdXJlIHRvIHNldCBcInBvc2l0aW9uOiByZWxhdGl2ZVwiIGhlcmUgdG8gZm9ybSBhbm90aGVyIHN0YWNraW5nIGNvbnRleHQgZm9yIHRoZSBzY3JvbGwtdG8tZW5kIGJ1dHRvbi5cbiAgICAvLyBTdGFja2luZyBjb250ZXh0IGhlbHAgaXNvbGF0aW5nIGVsZW1lbnRzIHRoYXQgdXNlIFwiei1pbmRleFwiIGZyb20gZ2xvYmFsIHBvbGx1dGlvbi5cbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9DU1MvQ1NTX1Bvc2l0aW9uaW5nL1VuZGVyc3RhbmRpbmdfel9pbmRleC9UaGVfc3RhY2tpbmdfY29udGV4dFxuICAgIHBvc2l0aW9uOiAncmVsYXRpdmUnLFxuXG4gICAgJyYgLndlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX2ZpbGxlcic6IHtcbiAgICAgIGZsZXg6IDFcbiAgICB9LFxuXG4gICAgJyYgLndlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX3Njcm9sbGFibGUnOiB7XG4gICAgICBkaXNwbGF5OiAnZmxleCcsXG4gICAgICBmbGV4RGlyZWN0aW9uOiAnY29sdW1uJyxcbiAgICAgIG92ZXJmbG93WDogJ2hpZGRlbicsXG4gICAgICBXZWJraXRPdmVyZmxvd1Njcm9sbGluZzogJ3RvdWNoJ1xuICAgIH0sXG5cbiAgICAnJiAud2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fdHJhbnNjcmlwdCc6IHtcbiAgICAgIGxpc3RTdHlsZVR5cGU6ICdub25lJ1xuICAgIH1cbiAgfVxufTtcblxuZnVuY3Rpb24gdmFsaWRhdGVBbGxBY3Rpdml0aWVzVGFnZ2VkKGFjdGl2aXRpZXMsIGJpbnMpIHtcbiAgcmV0dXJuIGFjdGl2aXRpZXMuZXZlcnkoYWN0aXZpdHkgPT4gYmlucy5zb21lKGJpbiA9PiBiaW4uaW5jbHVkZXMoYWN0aXZpdHkpKSk7XG59XG5cbmNvbnN0IEludGVybmFsVHJhbnNjcmlwdCA9ICh7IGFjdGl2aXR5RWxlbWVudHNSZWYsIGNsYXNzTmFtZSB9KSA9PiB7XG4gIGNvbnN0IFt7IGJhc2ljVHJhbnNjcmlwdDogYmFzaWNUcmFuc2NyaXB0U3R5bGVTZXQgfV0gPSB1c2VTdHlsZVNldCgpO1xuICBjb25zdCBbeyBidWJibGVGcm9tVXNlck51Yk9mZnNldCwgYnViYmxlTnViT2Zmc2V0LCBncm91cFRpbWVzdGFtcCwgaW50ZXJuYWxMaXZlUmVnaW9uRmFkZUFmdGVyLCBzaG93QXZhdGFySW5Hcm91cCB9XSA9XG4gICAgdXNlU3R5bGVPcHRpb25zKCk7XG4gIGNvbnN0IFtmb2N1c2VkQWN0aXZpdHlLZXksIHNldEZvY3VzZWRBY3Rpdml0eUtleV0gPSB1c2VTdGF0ZSgpO1xuICBjb25zdCBbYWN0aXZpdGllc10gPSB1c2VBY3Rpdml0aWVzKCk7XG4gIGNvbnN0IFtkaXJlY3Rpb25dID0gdXNlRGlyZWN0aW9uKCk7XG4gIGNvbnN0IGNyZWF0ZUFjdGl2aXR5UmVuZGVyZXIgPSB1c2VDcmVhdGVBY3Rpdml0eVJlbmRlcmVyKCk7XG4gIGNvbnN0IGNyZWF0ZUFjdGl2aXR5U3RhdHVzUmVuZGVyZXIgPSB1c2VDcmVhdGVBY3Rpdml0eVN0YXR1c1JlbmRlcmVyKCk7XG4gIGNvbnN0IGNyZWF0ZUF2YXRhclJlbmRlcmVyID0gdXNlQ3JlYXRlQXZhdGFyUmVuZGVyZXIoKTtcbiAgY29uc3QgZm9jdXMgPSB1c2VGb2N1cygpO1xuICBjb25zdCBncm91cEFjdGl2aXRpZXMgPSB1c2VHcm91cEFjdGl2aXRpZXMoKTtcbiAgY29uc3QgbG9jYWxpemUgPSB1c2VMb2NhbGl6ZXIoKTtcbiAgY29uc3Qgcm9vdENsYXNzTmFtZSA9IHVzZVN0eWxlVG9FbW90aW9uT2JqZWN0KCkoUk9PVF9TVFlMRSkgKyAnJztcbiAgY29uc3Qgcm9vdEVsZW1lbnRSZWYgPSB1c2VSZWYoKTtcbiAgY29uc3QgdGVybWluYXRvclJlZiA9IHVzZVJlZigpO1xuXG4gIGNvbnN0IGFjdGl2aXR5SW50ZXJhY3RpdmVBbHQgPSBsb2NhbGl6ZSgnQUNUSVZJVFlfSU5URVJBQ1RJVkVfTEFCRUxfQUxUJyk7XG4gIGNvbnN0IHRlcm1pbmF0b3JUZXh0ID0gbG9jYWxpemUoJ1RSQU5TQ1JJUFRfVEVSTUlOQVRPUl9URVhUJyk7XG4gIGNvbnN0IHRyYW5zY3JpcHRBcmlhTGFiZWwgPSBsb2NhbGl6ZSgnVFJBTlNDUklQVF9BUklBX0xBQkVMX0FMVCcpO1xuICBjb25zdCB0cmFuc2NyaXB0Um9sZURlc2NyaXB0aW9uID0gbG9jYWxpemUoJ1RSQU5TQ1JJUFRfQVJJQV9ST0xFX0FMVCcpO1xuXG4gIGNvbnN0IGhpZGVBbGxUaW1lc3RhbXBzID0gZ3JvdXBUaW1lc3RhbXAgPT09IGZhbHNlO1xuXG4gIC8vIEdldHMgcmVuZGVyZXIgZm9yIGV2ZXJ5IGFjdGl2aXR5LlxuICAvLyBBY3Rpdml0aWVzIHRoYXQgYXJlIG5vdCB2aXNpYmxlIHdpbGwgcmV0dXJuIGEgZmFsc3kgcmVuZGVyZXIuXG5cbiAgLy8gQ29udmVydGVkIGZyb20gY3JlYXRlQWN0aXZpdHlSZW5kZXJlcih7IGFjdGl2aXR5LCBuZXh0VmlzaWJsZUFjdGl2aXR5IH0pIHRvIGNyZWF0ZUFjdGl2aXR5UmVuZGVyZXIoYWN0aXZpdHksIG5leHRWaXNpYmxlQWN0aXZpdHkpLlxuICAvLyBUaGlzIGlzIGZvciB0aGUgbWVtb2l6YXRpb24gZnVuY3Rpb24gdG8gY2FjaGUgdGhlIGFyZ3VtZW50cy4gTWVtb2l6ZXIgY2FuIG9ubHkgY2FjaGUgbGl0ZXJhbCBhcmd1bWVudHMuXG4gIGNvbnN0IGNyZWF0ZUFjdGl2aXR5UmVuZGVyZXJXaXRoTGl0ZXJhbEFyZ3MgPSB1c2VDYWxsYmFjayhcbiAgICAoYWN0aXZpdHksIG5leHRWaXNpYmxlQWN0aXZpdHkpID0+IGNyZWF0ZUFjdGl2aXR5UmVuZGVyZXIoeyBhY3Rpdml0eSwgbmV4dFZpc2libGVBY3Rpdml0eSB9KSxcbiAgICBbY3JlYXRlQWN0aXZpdHlSZW5kZXJlcl1cbiAgKTtcblxuICAvLyBDcmVhdGUgYSBtZW1vaXplZCBjb250ZXh0IG9mIHRoZSBjcmVhdGVBY3Rpdml0eVJlbmRlcmVyIGZ1bmN0aW9uLlxuICBjb25zdCBhY3Rpdml0aWVzV2l0aFJlbmRlcmVyID0gdXNlTWVtb2l6ZShcbiAgICBjcmVhdGVBY3Rpdml0eVJlbmRlcmVyV2l0aExpdGVyYWxBcmdzLFxuICAgIGNyZWF0ZUFjdGl2aXR5UmVuZGVyZXJXaXRoTGl0ZXJhbEFyZ3NNZW1vaXplZCA9PiB7XG4gICAgICAvLyBBbGwgY2FsbHMgdG8gY3JlYXRlQWN0aXZpdHlSZW5kZXJlcldpdGhMaXRlcmFsQXJnc01lbW9pemVkKCkgaW4gdGhpcyBmdW5jdGlvbiB3aWxsIGJlIG1lbW9pemVkIChMUlUgPSAxKS5cbiAgICAgIC8vIEluIHRoZSBuZXh0IHJlbmRlciBjeWNsZSwgY2FsbHMgdG8gY3JlYXRlQWN0aXZpdHlSZW5kZXJlcldpdGhMaXRlcmFsQXJnc01lbW9pemVkKCkgbWlnaHQgcmV0dXJuIHRoZSBtZW1vaXplZCByZXN1bHQgaW5zdGVhZC5cbiAgICAgIC8vIFRoaXMgaXMgYW4gaW1wcm92ZW1lbnQgdG8gUmVhY3QgdXNlTWVtbygpLCBiZWNhdXNlIGl0IG9ubHkgYWxsb3dzIDEgbWVtb2l6YXRpb24uXG4gICAgICAvLyB1c2VNZW1vaXplKCkgYWxsb3dzIGFueSBudW1iZXIgb2YgbWVtb2l6YXRpb24uXG5cbiAgICAgIGNvbnN0IGFjdGl2aXRpZXNXaXRoUmVuZGVyZXIgPSBbXTtcbiAgICAgIGxldCBuZXh0VmlzaWJsZUFjdGl2aXR5O1xuXG4gICAgICBmb3IgKGxldCBpbmRleCA9IGFjdGl2aXRpZXMubGVuZ3RoIC0gMTsgaW5kZXggPj0gMDsgaW5kZXgtLSkge1xuICAgICAgICBjb25zdCBhY3Rpdml0eSA9IGFjdGl2aXRpZXNbaW5kZXhdO1xuICAgICAgICBjb25zdCByZW5kZXJBY3Rpdml0eSA9IGNyZWF0ZUFjdGl2aXR5UmVuZGVyZXJXaXRoTGl0ZXJhbEFyZ3NNZW1vaXplZChhY3Rpdml0eSwgbmV4dFZpc2libGVBY3Rpdml0eSk7XG5cbiAgICAgICAgaWYgKHJlbmRlckFjdGl2aXR5KSB7XG4gICAgICAgICAgYWN0aXZpdGllc1dpdGhSZW5kZXJlci5zcGxpY2UoMCwgMCwge1xuICAgICAgICAgICAgYWN0aXZpdHksXG4gICAgICAgICAgICByZW5kZXJBY3Rpdml0eVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgbmV4dFZpc2libGVBY3Rpdml0eSA9IGFjdGl2aXR5O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBhY3Rpdml0aWVzV2l0aFJlbmRlcmVyO1xuICAgIH0sXG4gICAgW2FjdGl2aXRpZXNdXG4gICk7XG5cbiAgY29uc3QgdmlzaWJsZUFjdGl2aXRpZXMgPSB1c2VNZW1vKFxuICAgICgpID0+IGFjdGl2aXRpZXNXaXRoUmVuZGVyZXIubWFwKCh7IGFjdGl2aXR5IH0pID0+IGFjdGl2aXR5KSxcbiAgICBbYWN0aXZpdGllc1dpdGhSZW5kZXJlcl1cbiAgKTtcblxuICAvLyBUYWcgYWN0aXZpdGllcyBiYXNlZCBvbiB0eXBlcy5cbiAgLy8gVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gdGFnIGludG8gMiB0eXBlczogc2VuZGVyIGFuZCBzdGF0dXMuXG5cbiAgY29uc3QgeyBhY3Rpdml0aWVzR3JvdXBCeVNlbmRlciwgYWN0aXZpdGllc0dyb3VwQnlTdGF0dXMgfSA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIGNvbnN0IHsgc2VuZGVyOiBhY3Rpdml0aWVzR3JvdXBCeVNlbmRlciwgc3RhdHVzOiBhY3Rpdml0aWVzR3JvdXBCeVN0YXR1cyB9ID0gZ3JvdXBBY3Rpdml0aWVzKHtcbiAgICAgIGFjdGl2aXRpZXM6IHZpc2libGVBY3Rpdml0aWVzXG4gICAgfSk7XG5cbiAgICBpZiAoIXZhbGlkYXRlQWxsQWN0aXZpdGllc1RhZ2dlZCh2aXNpYmxlQWN0aXZpdGllcywgYWN0aXZpdGllc0dyb3VwQnlTZW5kZXIpKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICdib3RmcmFtZXdvcmstd2ViY2hhdDogTm90IGV2ZXJ5IGFjdGl2aXRpZXMgYXJlIGdyb3VwZWQgaW4gdGhlIFwic2VuZGVyXCIgcHJvcGVydHkuIFBsZWFzZSBmaXggXCJncm91cEFjdGl2aXRpZXNNaWRkbGV3YXJlXCIgYW5kIGdyb3VwIGV2ZXJ5IGFjdGl2aXRpZXMuJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoIXZhbGlkYXRlQWxsQWN0aXZpdGllc1RhZ2dlZCh2aXNpYmxlQWN0aXZpdGllcywgYWN0aXZpdGllc0dyb3VwQnlTdGF0dXMpKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICdib3RmcmFtZXdvcmstd2ViY2hhdDogTm90IGV2ZXJ5IGFjdGl2aXRpZXMgYXJlIGdyb3VwZWQgaW4gdGhlIFwic3RhdHVzXCIgcHJvcGVydHkuIFBsZWFzZSBmaXggXCJncm91cEFjdGl2aXRpZXNNaWRkbGV3YXJlXCIgYW5kIGdyb3VwIGV2ZXJ5IGFjdGl2aXRpZXMuJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgYWN0aXZpdGllc0dyb3VwQnlTZW5kZXIsXG4gICAgICBhY3Rpdml0aWVzR3JvdXBCeVN0YXR1c1xuICAgIH07XG4gIH0sIFtncm91cEFjdGl2aXRpZXMsIHZpc2libGVBY3Rpdml0aWVzXSk7XG5cbiAgLy8gQ3JlYXRlIGEgdHJlZSBvZiBhY3Rpdml0aWVzIHdpdGggMiBkaW1lbnNpb25zOiBzZW5kZXIsIGZvbGxvd2VkIGJ5IHN0YXR1cy5cblxuICBjb25zdCBhY3Rpdml0eVRyZWUgPSB1c2VNZW1vKCgpID0+IHtcbiAgICBjb25zdCB2aXNpYmxlQWN0aXZpdGllc1BlbmRpbmdHcm91cGluZyA9IFsuLi52aXNpYmxlQWN0aXZpdGllc107XG4gICAgY29uc3QgYWN0aXZpdHlUcmVlID0gW107XG5cbiAgICB3aGlsZSAodmlzaWJsZUFjdGl2aXRpZXNQZW5kaW5nR3JvdXBpbmcubGVuZ3RoKSB7XG4gICAgICBjb25zdCBbYWN0aXZpdHldID0gdmlzaWJsZUFjdGl2aXRpZXNQZW5kaW5nR3JvdXBpbmc7XG4gICAgICBjb25zdCBzZW5kZXJUcmVlID0gW107XG4gICAgICBjb25zdCBhY3Rpdml0aWVzV2l0aFNhbWVTZW5kZXIgPSBhY3Rpdml0aWVzR3JvdXBCeVNlbmRlci5maW5kKGFjdGl2aXRpZXMgPT4gYWN0aXZpdGllcy5pbmNsdWRlcyhhY3Rpdml0eSkpO1xuXG4gICAgICBhY3Rpdml0eVRyZWUucHVzaChzZW5kZXJUcmVlKTtcblxuICAgICAgYWN0aXZpdGllc1dpdGhTYW1lU2VuZGVyLmZvckVhY2goYWN0aXZpdHkgPT4ge1xuICAgICAgICBjb25zdCBhY3Rpdml0aWVzV2l0aFNhbWVTdGF0dXMgPSBhY3Rpdml0aWVzR3JvdXBCeVN0YXR1cy5maW5kKGFjdGl2aXRpZXMgPT4gYWN0aXZpdGllcy5pbmNsdWRlcyhhY3Rpdml0eSkpO1xuXG4gICAgICAgIGNvbnN0IGFjdGl2aXRpZXNXaXRoU2FtZVNlbmRlckFuZFN0YXR1cyA9IGludGVyc2VjdGlvbk9mKFxuICAgICAgICAgIHZpc2libGVBY3Rpdml0aWVzUGVuZGluZ0dyb3VwaW5nLFxuICAgICAgICAgIGFjdGl2aXRpZXNXaXRoU2FtZVNlbmRlcixcbiAgICAgICAgICBhY3Rpdml0aWVzV2l0aFNhbWVTdGF0dXNcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoYWN0aXZpdGllc1dpdGhTYW1lU2VuZGVyQW5kU3RhdHVzLmxlbmd0aCkge1xuICAgICAgICAgIHNlbmRlclRyZWUucHVzaChhY3Rpdml0aWVzV2l0aFNhbWVTZW5kZXJBbmRTdGF0dXMpO1xuICAgICAgICAgIHJlbW92ZUlubGluZSh2aXNpYmxlQWN0aXZpdGllc1BlbmRpbmdHcm91cGluZywgLi4uYWN0aXZpdGllc1dpdGhTYW1lU2VuZGVyQW5kU3RhdHVzKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gQXNzZXJ0aW9uOiBBbGwgYWN0aXZpdGllcyBpbiB2aXNpYmxlQWN0aXZpdGllcywgbXVzdCBiZSBhc3NpZ25lZCB0byB0aGUgYWN0aXZpdHlUcmVlXG4gICAgaWYgKFxuICAgICAgIXZpc2libGVBY3Rpdml0aWVzLmV2ZXJ5KGFjdGl2aXR5ID0+XG4gICAgICAgIGFjdGl2aXR5VHJlZS5zb21lKGFjdGl2aXRpZXNXaXRoU2FtZVNlbmRlciA9PlxuICAgICAgICAgIGFjdGl2aXRpZXNXaXRoU2FtZVNlbmRlci5zb21lKGFjdGl2aXRpZXNXaXRoU2FtZVNlbmRlckFuZFN0YXR1cyA9PlxuICAgICAgICAgICAgYWN0aXZpdGllc1dpdGhTYW1lU2VuZGVyQW5kU3RhdHVzLmluY2x1ZGVzKGFjdGl2aXR5KVxuICAgICAgICAgIClcbiAgICAgICAgKVxuICAgICAgKVxuICAgICkge1xuICAgICAgY29uc29sZS53YXJuKCdib3RmcmFtZXdvcmstd2ViY2hhdCBpbnRlcm5hbDogTm90IGFsbCB2aXNpYmxlIGFjdGl2aXRpZXMgYXJlIGdyb3VwZWQgaW4gdGhlIGFjdGl2aXR5VHJlZS4nLCB7XG4gICAgICAgIHZpc2libGVBY3Rpdml0aWVzLFxuICAgICAgICBhY3Rpdml0eVRyZWVcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBhY3Rpdml0eVRyZWU7XG4gIH0sIFthY3Rpdml0aWVzR3JvdXBCeVNlbmRlciwgYWN0aXZpdGllc0dyb3VwQnlTdGF0dXMsIHZpc2libGVBY3Rpdml0aWVzXSk7XG5cbiAgLy8gRmxhdHRlbiB0aGUgdHJlZSBiYWNrIGludG8gYW4gYXJyYXkgd2l0aCBpbmZvcm1hdGlvbiByZWxhdGVkIHRvIHJlbmRlcmluZy5cblxuICBjb25zdCByZW5kZXJpbmdFbGVtZW50cyA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIGNvbnN0IHJlbmRlcmluZ0VsZW1lbnRzID0gW107XG4gICAgY29uc3QgdG9wU2lkZUJvdE51YiA9IGlzWmVyb09yUG9zaXRpdmUoYnViYmxlTnViT2Zmc2V0KTtcbiAgICBjb25zdCB0b3BTaWRlVXNlck51YiA9IGlzWmVyb09yUG9zaXRpdmUoYnViYmxlRnJvbVVzZXJOdWJPZmZzZXQpO1xuXG4gICAgYWN0aXZpdHlUcmVlLmZvckVhY2goYWN0aXZpdGllc1dpdGhTYW1lU2VuZGVyID0+IHtcbiAgICAgIGNvbnN0IFtbZmlyc3RBY3Rpdml0eV1dID0gYWN0aXZpdGllc1dpdGhTYW1lU2VuZGVyO1xuICAgICAgY29uc3QgcmVuZGVyQXZhdGFyID0gY3JlYXRlQXZhdGFyUmVuZGVyZXIoeyBhY3Rpdml0eTogZmlyc3RBY3Rpdml0eSB9KTtcblxuICAgICAgYWN0aXZpdGllc1dpdGhTYW1lU2VuZGVyLmZvckVhY2goKGFjdGl2aXRpZXNXaXRoU2FtZVNlbmRlckFuZFN0YXR1cywgaW5kZXhXaXRoaW5TZW5kZXJHcm91cCkgPT4ge1xuICAgICAgICBjb25zdCBmaXJzdEluU2VuZGVyR3JvdXAgPSAhaW5kZXhXaXRoaW5TZW5kZXJHcm91cDtcbiAgICAgICAgY29uc3QgbGFzdEluU2VuZGVyR3JvdXAgPSBpbmRleFdpdGhpblNlbmRlckdyb3VwID09PSBhY3Rpdml0aWVzV2l0aFNhbWVTZW5kZXIubGVuZ3RoIC0gMTtcblxuICAgICAgICBhY3Rpdml0aWVzV2l0aFNhbWVTZW5kZXJBbmRTdGF0dXMuZm9yRWFjaCgoYWN0aXZpdHksIGluZGV4V2l0aGluU2VuZGVyQW5kU3RhdHVzR3JvdXApID0+IHtcbiAgICAgICAgICAvLyBXZSBvbmx5IHNob3cgdGhlIHRpbWVzdGFtcCBhdCB0aGUgZW5kIG9mIHRoZSBzZW5kZXIgZ3JvdXAuIEJ1dCB3ZSBhbHdheXMgc2hvdyB0aGUgXCJTZW5kIGZhaWxlZCwgcmV0cnlcIiBwcm9tcHQuXG4gICAgICAgICAgY29uc3QgcmVuZGVyQWN0aXZpdHlTdGF0dXMgPSBjcmVhdGVBY3Rpdml0eVN0YXR1c1JlbmRlcmVyKHtcbiAgICAgICAgICAgIGFjdGl2aXR5XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCBmaXJzdEluU2VuZGVyQW5kU3RhdHVzR3JvdXAgPSAhaW5kZXhXaXRoaW5TZW5kZXJBbmRTdGF0dXNHcm91cDtcbiAgICAgICAgICBjb25zdCBsYXN0SW5TZW5kZXJBbmRTdGF0dXNHcm91cCA9XG4gICAgICAgICAgICBpbmRleFdpdGhpblNlbmRlckFuZFN0YXR1c0dyb3VwID09PSBhY3Rpdml0aWVzV2l0aFNhbWVTZW5kZXJBbmRTdGF0dXMubGVuZ3RoIC0gMTtcblxuICAgICAgICAgIGNvbnN0IHsgcmVuZGVyQWN0aXZpdHkgfSA9IGFjdGl2aXRpZXNXaXRoUmVuZGVyZXIuZmluZChlbnRyeSA9PiBlbnRyeS5hY3Rpdml0eSA9PT0gYWN0aXZpdHkpO1xuICAgICAgICAgIGNvbnN0IGtleSA9IGdldEFjdGl2aXR5VW5pcXVlSWQoYWN0aXZpdHkpIHx8IHJlbmRlcmluZ0VsZW1lbnRzLmxlbmd0aDtcbiAgICAgICAgICBjb25zdCBiYXNlQWx0VGV4dCA9XG4gICAgICAgICAgICB0eXBlb2YgYWN0aXZpdHk/LmNoYW5uZWxEYXRhPy5bJ3dlYmNoYXQ6ZmFsbGJhY2stdGV4dCddID09PSAnc3RyaW5nJ1xuICAgICAgICAgICAgICA/IGFjdGl2aXR5Py5jaGFubmVsRGF0YT8uWyd3ZWJjaGF0OmZhbGxiYWNrLXRleHQnXVxuICAgICAgICAgICAgICA6IGFjdGl2aXR5Py5jaGFubmVsRGF0YT8ubWVzc2FnZUJhY2s/LmRpc3BsYXlUZXh0IHx8IGFjdGl2aXR5LnRleHQ7XG5cbiAgICAgICAgICAvLyBJZiBcIndlYmNoYXQ6ZmFsbGJhY2stdGV4dFwiIGZpZWxkIGlzIHNldCB0byBlbXB0eSBzdHJpbmcsIHRoZSBhY3Rpdml0eSBtdXN0IG5vdCBiZSBuYXJyYXRlZC5cbiAgICAgICAgICBjb25zdCBzdXBwb3J0U2NyZWVuUmVhZGVyID0gYWN0aXZpdHk/LmNoYW5uZWxEYXRhPy5bJ3dlYmNoYXQ6ZmFsbGJhY2stdGV4dCddICE9PSAnJztcblxuICAgICAgICAgIGNvbnN0IHtcbiAgICAgICAgICAgIGZyb206IHsgcm9sZSB9XG4gICAgICAgICAgfSA9IGFjdGl2aXR5O1xuXG4gICAgICAgICAgY29uc3QgdG9wU2lkZU51YiA9IHJvbGUgPT09ICd1c2VyJyA/IHRvcFNpZGVVc2VyTnViIDogdG9wU2lkZUJvdE51YjtcblxuICAgICAgICAgIGxldCBzaG93Q2FsbG91dDtcblxuICAgICAgICAgIC8vIERlcGVuZGluZyBvbiB0aGUgXCJzaG93QXZhdGFySW5Hcm91cFwiIHNldHRpbmcsIHRoZSBhdmF0YXIgd2lsbCByZW5kZXIgaW4gZGlmZmVyZW50IHBvc2l0aW9ucy5cbiAgICAgICAgICBpZiAoc2hvd0F2YXRhckluR3JvdXAgPT09ICdzZW5kZXInKSB7XG4gICAgICAgICAgICBpZiAodG9wU2lkZU51Yikge1xuICAgICAgICAgICAgICBzaG93Q2FsbG91dCA9IGZpcnN0SW5TZW5kZXJHcm91cCAmJiBmaXJzdEluU2VuZGVyQW5kU3RhdHVzR3JvdXA7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBzaG93Q2FsbG91dCA9IGxhc3RJblNlbmRlckdyb3VwICYmIGxhc3RJblNlbmRlckFuZFN0YXR1c0dyb3VwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAoc2hvd0F2YXRhckluR3JvdXAgPT09ICdzdGF0dXMnKSB7XG4gICAgICAgICAgICBpZiAodG9wU2lkZU51Yikge1xuICAgICAgICAgICAgICBzaG93Q2FsbG91dCA9IGZpcnN0SW5TZW5kZXJBbmRTdGF0dXNHcm91cDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHNob3dDYWxsb3V0ID0gbGFzdEluU2VuZGVyQW5kU3RhdHVzR3JvdXA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNob3dDYWxsb3V0ID0gdHJ1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBmb2N1c0FjdGl2aXR5ID0gKCkgPT4ge1xuICAgICAgICAgICAgc2V0Rm9jdXNlZEFjdGl2aXR5S2V5KGdldEFjdGl2aXR5VW5pcXVlSWQoYWN0aXZpdHkpKTtcblxuICAgICAgICAgICAgLy8gSUUxMSBuZWVkIHRvIG1hbnVhbGx5IGZvY3VzIG9uIHRoZSB0cmFuc2NyaXB0LlxuICAgICAgICAgICAgY29uc3QgeyBjdXJyZW50OiByb290RWxlbWVudCB9ID0gcm9vdEVsZW1lbnRSZWY7XG5cbiAgICAgICAgICAgIHJvb3RFbGVtZW50ICYmIHJvb3RFbGVtZW50LmZvY3VzKCk7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIHJlbmRlcmluZ0VsZW1lbnRzLnB1c2goe1xuICAgICAgICAgICAgYWN0aXZpdHksXG5cbiAgICAgICAgICAgIC8vIEFmdGVyIHRoZSBlbGVtZW50IGlzIG1vdW50ZWQsIHNldCBpdCB0byBhY3Rpdml0eUVsZW1lbnRzUmVmLlxuICAgICAgICAgICAgY2FsbGJhY2tSZWY6IGFjdGl2aXR5RWxlbWVudCA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IGVudHJ5ID0gYWN0aXZpdHlFbGVtZW50c1JlZi5jdXJyZW50LmZpbmQoKHsgYWN0aXZpdHlJRCB9KSA9PiBhY3Rpdml0eUlEID09PSBhY3Rpdml0eS5pZCk7XG5cbiAgICAgICAgICAgICAgaWYgKGVudHJ5KSB7XG4gICAgICAgICAgICAgICAgZW50cnkuZWxlbWVudCA9IGFjdGl2aXR5RWxlbWVudDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgLy8gQ2FsbGluZyB0aGlzIGZ1bmN0aW9uIHdpbGwgcHV0IHRoZSBmb2N1cyBvbiB0aGUgdHJhbnNjcmlwdCBhbmQgdGhlIGFjdGl2aXR5LlxuICAgICAgICAgICAgZm9jdXNBY3Rpdml0eSxcblxuICAgICAgICAgICAgLy8gV2hlbiBhIGNoaWxkIG9mIHRoZSBhY3Rpdml0eSByZWNlaXZlcyBmb2N1cywgbm90aWZ5IHRoZSB0cmFuc2NyaXB0IHRvIHNldCB0aGUgYXJpYS1hY3RpdmVkZXNjZW5kYW50IHRvIHRoaXMgYWN0aXZpdHkuXG4gICAgICAgICAgICBoYW5kbGVGb2N1czogKCkgPT4ge1xuICAgICAgICAgICAgICBzZXRGb2N1c2VkQWN0aXZpdHlLZXkoZ2V0QWN0aXZpdHlVbmlxdWVJZChhY3Rpdml0eSkpO1xuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgaGFuZGxlS2V5RG93bjogZXZlbnQgPT4ge1xuICAgICAgICAgICAgICBpZiAoZXZlbnQua2V5ID09PSAnRXNjYXBlJykge1xuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAgICAgICAgICAgICBzZXRGb2N1c2VkQWN0aXZpdHlLZXkoZ2V0QWN0aXZpdHlVbmlxdWVJZChhY3Rpdml0eSkpO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgeyBjdXJyZW50IH0gPSByb290RWxlbWVudFJlZjtcblxuICAgICAgICAgICAgICAgIGN1cnJlbnQgJiYgY3VycmVudC5mb2N1cygpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAvLyBGb3IgYWNjZXNzaWJpbGl0eTogd2hlbiB0aGUgdXNlciBwcmVzcyB1cC9kb3duIGFycm93IGtleXMsIHdlIHB1dCBhIHZpc3VhbCBmb2N1cyBpbmRpY2F0b3IgYXJvdW5kIHRoZSBmb2N1c2VkIGFjdGl2aXR5LlxuICAgICAgICAgICAgLy8gV2Ugc2hvdWxkIGRvIHRoZSBzYW1lIGZvciBtb3VzZSwgdGhhdCBpcyB3aHkgd2UgaGF2ZSB0aGUgY2xpY2sgaGFuZGxlciBoZXJlLlxuICAgICAgICAgICAgLy8gV2UgYXJlIGRvaW5nIGl0IGluIGV2ZW50IGNhcHR1cmUgcGhhc2UgdG8gcHJldmVudCBvdGhlciBjb21wb25lbnRzIGZyb20gc3RvcHBpbmcgZXZlbnQgcHJvcGFnYXRpb24gdG8gdXMuXG4gICAgICAgICAgICBoYW5kbGVNb3VzZURvd25DYXB0dXJlOiAoeyB0YXJnZXQgfSkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCB0YWJJbmRleCA9IGdldFRhYkluZGV4KHRhcmdldCk7XG5cbiAgICAgICAgICAgICAgaWYgKHR5cGVvZiB0YWJJbmRleCAhPT0gJ251bWJlcicgfHwgdGFiSW5kZXggPCAwIHx8IHRhcmdldC5nZXRBdHRyaWJ1dGUoJ2FyaWEtZGlzYWJsZWQnKSA9PT0gJ3RydWUnKSB7XG4gICAgICAgICAgICAgICAgZm9jdXNBY3Rpdml0eSgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAvLyBcImhpZGVUaW1lc3RhbXBcIiBpcyBhIHJlbmRlci10aW1lIHBhcmFtZXRlciBmb3IgcmVuZGVyQWN0aXZpdHlTdGF0dXMoKS5cbiAgICAgICAgICAgIC8vIElmIHRydWUsIGl0IHdpbGwgaGlkZSB0aGUgdGltZXN0YW1wLCBidXQgaXQgd2lsbCBjb250aW51ZSB0byBzaG93IHRoZVxuICAgICAgICAgICAgLy8gcmV0cnkgcHJvbXB0LiBBbmQgc2hvdyB0aGUgc2NyZWVuIHJlYWRlciB2ZXJzaW9uIG9mIHRoZSB0aW1lc3RhbXAuXG4gICAgICAgICAgICBoaWRlVGltZXN0YW1wOlxuICAgICAgICAgICAgICBoaWRlQWxsVGltZXN0YW1wcyB8fCBpbmRleFdpdGhpblNlbmRlckFuZFN0YXR1c0dyb3VwICE9PSBhY3Rpdml0aWVzV2l0aFNhbWVTZW5kZXJBbmRTdGF0dXMubGVuZ3RoIC0gMSxcbiAgICAgICAgICAgIGtleSxcblxuICAgICAgICAgICAgLy8gV2hlbiBcImxpdmVSZWdpb25LZXlcIiBjaGFuZ2VzIG9yIGNvbnRlbnRzIHRoYXQgbWFkZSB1cCB0aGUgYWx0IHRleHQgY2hhbmdlZCwgaXQgd2lsbCBzaG93IHVwIGluIHRoZSBsaXZlIHJlZ2lvbiBtb21lbnRhcmlseS5cbiAgICAgICAgICAgIGxpdmVSZWdpb25LZXk6IGtleSArICd8JyArIGJhc2VBbHRUZXh0LFxuICAgICAgICAgICAgcmVuZGVyQWN0aXZpdHksXG4gICAgICAgICAgICByZW5kZXJBY3Rpdml0eVN0YXR1cyxcbiAgICAgICAgICAgIHJlbmRlckF2YXRhcixcbiAgICAgICAgICAgIHJvbGUsXG5cbiAgICAgICAgICAgIC8vIFRPRE86IFtQMl0gIzI4NTggV2Ugc2hvdWxkIHVzZSBjb3JlL2RlZmluaXRpb25zL3NwZWFraW5nQWN0aXZpdHkgZm9yIHRoaXMgcHJlZGljYXRlIGluc3RlYWRcbiAgICAgICAgICAgIHNob3VsZFNwZWFrOiBhY3Rpdml0eS5jaGFubmVsRGF0YSAmJiBhY3Rpdml0eS5jaGFubmVsRGF0YS5zcGVhayxcbiAgICAgICAgICAgIHNob3dDYWxsb3V0LFxuICAgICAgICAgICAgc3VwcG9ydFNjcmVlblJlYWRlclxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgY29uc3QgeyBjdXJyZW50OiBhY3Rpdml0eUVsZW1lbnRzIH0gPSBhY3Rpdml0eUVsZW1lbnRzUmVmO1xuXG4gICAgLy8gVXBkYXRlIGFjdGl2aXR5RWxlbWVudFJlZiB3aXRoIG5ldyBzZXRzIG9mIGFjdGl2aXR5LCB3aGlsZSByZXRhaW5pbmcgdGhlIGV4aXN0aW5nIHJlZmVyZW5jaW5nIGVsZW1lbnQgaWYgZXhpc3RzLlxuICAgIGFjdGl2aXR5RWxlbWVudHNSZWYuY3VycmVudCA9IHJlbmRlcmluZ0VsZW1lbnRzLm1hcCgoeyBhY3Rpdml0eSwgYWN0aXZpdHk6IHsgaWQgfSwgZWxlbWVudElkLCBrZXkgfSkgPT4ge1xuICAgICAgY29uc3QgZXhpc3RpbmdFbnRyeSA9IGFjdGl2aXR5RWxlbWVudHMuZmluZChlbnRyeSA9PiBlbnRyeS5rZXkgPT09IGtleSk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGFjdGl2aXR5LFxuICAgICAgICBhY3Rpdml0eUlEOiBpZCxcbiAgICAgICAgYXJpYUxhYmVsSUQ6IGV4aXN0aW5nRW50cnlcbiAgICAgICAgICA/IGV4aXN0aW5nRW50cnkuYXJpYUxhYmVsSURcbiAgICAgICAgICA6IGB3ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0X19hY3Rpdml0eS1sYWJlbC0ke3JhbmRvbSgpLnRvU3RyaW5nKDM2KS5zdWJzdHIoMiwgNSl9YCxcbiAgICAgICAgZWxlbWVudDogZXhpc3RpbmdFbnRyeSAmJiBleGlzdGluZ0VudHJ5LmVsZW1lbnQsXG4gICAgICAgIGVsZW1lbnRJZCxcbiAgICAgICAga2V5XG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgLy8gVGhlcmUgbXVzdCBiZSBvbmUgZm9jdXNlZCAoYS5rLmEuIGFyaWEtYWN0aXZlZGVzY2VuZGFudCkgZGVzaWduYXRlZC4gV2UgZGVmYXVsdCBpdCB0byB0aGUgbGFzdCBvbmUuXG4gICAgaWYgKCFyZW5kZXJpbmdFbGVtZW50cy5maW5kKCh7IGZvY3VzZWQgfSkgPT4gZm9jdXNlZCkpIHtcbiAgICAgIGNvbnN0IGxhc3RFbGVtZW50ID0gcmVuZGVyaW5nRWxlbWVudHNbcmVuZGVyaW5nRWxlbWVudHMubGVuZ3RoIC0gMV07XG5cbiAgICAgIGlmIChsYXN0RWxlbWVudCkge1xuICAgICAgICBsYXN0RWxlbWVudC5mb2N1c2VkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVuZGVyaW5nRWxlbWVudHM7XG4gIH0sIFtcbiAgICBhY3Rpdml0aWVzV2l0aFJlbmRlcmVyLFxuICAgIGFjdGl2aXR5RWxlbWVudHNSZWYsXG4gICAgYWN0aXZpdHlUcmVlLFxuICAgIGJ1YmJsZUZyb21Vc2VyTnViT2Zmc2V0LFxuICAgIGJ1YmJsZU51Yk9mZnNldCxcbiAgICBjcmVhdGVBY3Rpdml0eVN0YXR1c1JlbmRlcmVyLFxuICAgIGNyZWF0ZUF2YXRhclJlbmRlcmVyLFxuICAgIGhpZGVBbGxUaW1lc3RhbXBzLFxuICAgIHJvb3RFbGVtZW50UmVmLFxuICAgIHNob3dBdmF0YXJJbkdyb3VwXG4gIF0pO1xuXG4gIGNvbnN0IHJlbmRlcmluZ0FjdGl2aXRpZXMgPSB1c2VNZW1vKCgpID0+IHJlbmRlcmluZ0VsZW1lbnRzLm1hcCgoeyBhY3Rpdml0eSB9KSA9PiBhY3Rpdml0eSksIFtyZW5kZXJpbmdFbGVtZW50c10pO1xuXG4gIGNvbnN0IHNjcm9sbFRvQm90dG9tU2Nyb2xsVG8gPSB1c2VTY3JvbGxUbygpO1xuICBjb25zdCBzY3JvbGxUb0JvdHRvbVNjcm9sbFRvRW5kID0gdXNlU2Nyb2xsVG9FbmQoKTtcblxuICBjb25zdCBzY3JvbGxUbyA9IHVzZUNhbGxiYWNrKFxuICAgIChwb3NpdGlvbiwgeyBiZWhhdmlvciA9ICdhdXRvJyB9ID0ge30pID0+IHtcbiAgICAgIGlmICghcG9zaXRpb24pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICdib3RmcmFtZXdvcmstd2ViY2hhdDogRmlyc3QgYXJndW1lbnQgcGFzc2VkIHRvIFwidXNlU2Nyb2xsVG9cIiBtdXN0IGJlIGEgU2Nyb2xsUG9zaXRpb24gb2JqZWN0LidcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgeyBhY3Rpdml0eUlELCBzY3JvbGxUb3AgfSA9IHBvc2l0aW9uO1xuXG4gICAgICBpZiAodHlwZW9mIHNjcm9sbFRvcCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgc2Nyb2xsVG9Cb3R0b21TY3JvbGxUbyhzY3JvbGxUb3AsIHsgYmVoYXZpb3IgfSk7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBhY3Rpdml0eUlEICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBjb25zdCB7IGN1cnJlbnQ6IHJvb3RFbGVtZW50IH0gPSByb290RWxlbWVudFJlZjtcbiAgICAgICAgY29uc3QgeyBlbGVtZW50OiBhY3Rpdml0eUVsZW1lbnQgfSA9XG4gICAgICAgICAgYWN0aXZpdHlFbGVtZW50c1JlZi5jdXJyZW50LmZpbmQoZW50cnkgPT4gZW50cnkuYWN0aXZpdHlJRCA9PT0gYWN0aXZpdHlJRCkgfHwge307XG5cbiAgICAgICAgY29uc3Qgc2Nyb2xsYWJsZUVsZW1lbnQgPSByb290RWxlbWVudC5xdWVyeVNlbGVjdG9yKCcud2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fc2Nyb2xsYWJsZScpO1xuXG4gICAgICAgIGlmIChzY3JvbGxhYmxlRWxlbWVudCAmJiBhY3Rpdml0eUVsZW1lbnQpIHtcbiAgICAgICAgICBjb25zdCBbeyBoZWlnaHQ6IGFjdGl2aXR5RWxlbWVudEhlaWdodCwgeTogYWN0aXZpdHlFbGVtZW50WSB9XSA9IGFjdGl2aXR5RWxlbWVudC5nZXRDbGllbnRSZWN0cygpO1xuICAgICAgICAgIGNvbnN0IFt7IGhlaWdodDogc2Nyb2xsYWJsZUhlaWdodCB9XSA9IHNjcm9sbGFibGVFbGVtZW50LmdldENsaWVudFJlY3RzKCk7XG5cbiAgICAgICAgICBjb25zdCBhY3Rpdml0eUVsZW1lbnRPZmZzZXRUb3AgPSBhY3Rpdml0eUVsZW1lbnRZICsgc2Nyb2xsYWJsZUVsZW1lbnQuc2Nyb2xsVG9wO1xuXG4gICAgICAgICAgY29uc3Qgc2Nyb2xsVG9wID0gTWF0aC5taW4oXG4gICAgICAgICAgICBhY3Rpdml0eUVsZW1lbnRPZmZzZXRUb3AsXG4gICAgICAgICAgICBhY3Rpdml0eUVsZW1lbnRPZmZzZXRUb3AgLSBzY3JvbGxhYmxlSGVpZ2h0ICsgYWN0aXZpdHlFbGVtZW50SGVpZ2h0XG4gICAgICAgICAgKTtcblxuICAgICAgICAgIHNjcm9sbFRvQm90dG9tU2Nyb2xsVG8oc2Nyb2xsVG9wLCB7IGJlaGF2aW9yIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgICBbYWN0aXZpdHlFbGVtZW50c1JlZiwgcm9vdEVsZW1lbnRSZWYsIHNjcm9sbFRvQm90dG9tU2Nyb2xsVG9dXG4gICk7XG5cbiAgY29uc3Qgc2Nyb2xsVG9FbmQgPSB1c2VDYWxsYmFjaygoKSA9PiBzY3JvbGxUb0JvdHRvbVNjcm9sbFRvRW5kKHsgYmVoYXZpb3I6ICdzbW9vdGgnIH0pLCBbc2Nyb2xsVG9Cb3R0b21TY3JvbGxUb0VuZF0pO1xuXG4gIGNvbnN0IHNjcm9sbFJlbGF0aXZlID0gdXNlQ2FsbGJhY2soXG4gICAgKGRpcmVjdGlvbiwgeyBkaXNwbGFjZW1lbnQgfSA9IHt9KSA9PiB7XG4gICAgICBjb25zdCB7IGN1cnJlbnQ6IHJvb3RFbGVtZW50IH0gPSByb290RWxlbWVudFJlZjtcblxuICAgICAgaWYgKCFyb290RWxlbWVudCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHNjcm9sbGFibGUgPSByb290RWxlbWVudC5xdWVyeVNlbGVjdG9yKCcud2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fc2Nyb2xsYWJsZScpO1xuICAgICAgbGV0IG5leHRTY3JvbGxUb3A7XG5cbiAgICAgIGlmICh0eXBlb2YgZGlzcGxhY2VtZW50ID09PSAnbnVtYmVyJykge1xuICAgICAgICBuZXh0U2Nyb2xsVG9wID0gc2Nyb2xsYWJsZS5zY3JvbGxUb3AgKyAoZGlyZWN0aW9uID09PSAnZG93bicgPyAxIDogLTEpICogZGlzcGxhY2VtZW50O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmV4dFNjcm9sbFRvcCA9IHNjcm9sbGFibGUuc2Nyb2xsVG9wICsgKGRpcmVjdGlvbiA9PT0gJ2Rvd24nID8gMSA6IC0xKSAqIHNjcm9sbGFibGUub2Zmc2V0SGVpZ2h0O1xuICAgICAgfVxuXG4gICAgICBzY3JvbGxUbyhcbiAgICAgICAge1xuICAgICAgICAgIHNjcm9sbFRvcDogTWF0aC5tYXgoMCwgTWF0aC5taW4oc2Nyb2xsYWJsZS5zY3JvbGxIZWlnaHQgLSBzY3JvbGxhYmxlLm9mZnNldEhlaWdodCwgbmV4dFNjcm9sbFRvcCkpXG4gICAgICAgIH0sXG4gICAgICAgIHsgYmVoYXZpb3I6ICdzbW9vdGgnIH1cbiAgICAgICk7XG4gICAgfSxcbiAgICBbcm9vdEVsZW1lbnRSZWYsIHNjcm9sbFRvXVxuICApO1xuXG4gIC8vIFNpbmNlIHRoZXJlIGNvdWxkIGJlIG11bHRpcGxlIGluc3RhbmNlcyBvZiA8QmFzaWNUcmFuc2NyaXB0PiBpbnNpZGUgdGhlIDxDb21wb3Nlcj4sIHdoZW4gdGhlIGRldmVsb3BlciBjYWxscyBgc2Nyb2xsWFhYYCwgd2UgbmVlZCB0byBjYWxsIGl0IG9uIGFsbCBpbnN0YW5jZXMuXG4gIC8vIFdlIGNhbGwgYHVzZVJlZ2lzdGVyU2Nyb2xsWFhYYCB0byByZWdpc3RlciBhIGNhbGxiYWNrIGZ1bmN0aW9uLCB0aGUgYHVzZVNjcm9sbFhYWGAgd2lsbCBtdWx0aXBsZXggdGhlIGNhbGwgaW50byBlYWNoIGluc3RhbmNlIG9mIDxCYXNpY1RyYW5zY3JpcHQ+LlxuICB1c2VSZWdpc3RlclNjcm9sbFRvKHNjcm9sbFRvKTtcbiAgdXNlUmVnaXN0ZXJTY3JvbGxUb0VuZChzY3JvbGxUb0VuZCk7XG4gIHVzZVJlZ2lzdGVyU2Nyb2xsUmVsYXRpdmUoc2Nyb2xsUmVsYXRpdmUpO1xuXG4gIGNvbnN0IGRpc3BhdGNoU2Nyb2xsUG9zaXRpb24gPSB1c2VEaXNwYXRjaFNjcm9sbFBvc2l0aW9uKCk7XG4gIGNvbnN0IHBhdGNoZWREaXNwYXRjaFNjcm9sbFBvc2l0aW9uID0gdXNlTWVtbygoKSA9PiB7XG4gICAgaWYgKCFkaXNwYXRjaFNjcm9sbFBvc2l0aW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcmV0dXJuICh7IHNjcm9sbFRvcCB9KSA9PiB7XG4gICAgICBjb25zdCB7IGN1cnJlbnQ6IHJvb3RFbGVtZW50IH0gPSByb290RWxlbWVudFJlZjtcblxuICAgICAgaWYgKCFyb290RWxlbWVudCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHNjcm9sbGFibGVFbGVtZW50ID0gcm9vdEVsZW1lbnQucXVlcnlTZWxlY3RvcignLndlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX3Njcm9sbGFibGUnKTtcblxuICAgICAgY29uc3QgW3sgaGVpZ2h0OiBvZmZzZXRIZWlnaHQgfSA9IHt9XSA9IHNjcm9sbGFibGVFbGVtZW50LmdldENsaWVudFJlY3RzKCk7XG5cbiAgICAgIC8vIEZpbmQgdGhlIGFjdGl2aXR5IGp1c3QgYWJvdmUgc2Nyb2xsIHZpZXcgYm90dG9tLlxuICAgICAgLy8gSWYgdGhlIHNjcm9sbCB2aWV3IGlzIGFscmVhZHkgb24gdG9wLCBnZXQgdGhlIGZpcnN0IGFjdGl2aXR5LlxuICAgICAgY29uc3QgZW50cnkgPSBzY3JvbGxhYmxlRWxlbWVudC5zY3JvbGxUb3BcbiAgICAgICAgPyBbLi4uYWN0aXZpdHlFbGVtZW50c1JlZi5jdXJyZW50XS5yZXZlcnNlKCkuZmluZCgoeyBlbGVtZW50IH0pID0+IHtcbiAgICAgICAgICAgIGlmICghZWxlbWVudCkge1xuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IFt7IHkgfSA9IHt9XSA9IGVsZW1lbnQuZ2V0Q2xpZW50UmVjdHMoKTtcblxuICAgICAgICAgICAgcmV0dXJuIHkgPCBvZmZzZXRIZWlnaHQ7XG4gICAgICAgICAgfSlcbiAgICAgICAgOiBhY3Rpdml0eUVsZW1lbnRzUmVmLmN1cnJlbnRbMF07XG5cbiAgICAgIGNvbnN0IHsgYWN0aXZpdHlJRCB9ID0gZW50cnkgfHwge307XG5cbiAgICAgIGRpc3BhdGNoU2Nyb2xsUG9zaXRpb24oeyAuLi4oYWN0aXZpdHlJRCA/IHsgYWN0aXZpdHlJRCB9IDoge30pLCBzY3JvbGxUb3AgfSk7XG4gICAgfTtcbiAgfSwgW2FjdGl2aXR5RWxlbWVudHNSZWYsIGRpc3BhdGNoU2Nyb2xsUG9zaXRpb24sIHJvb3RFbGVtZW50UmVmXSk7XG5cbiAgdXNlT2JzZXJ2ZVNjcm9sbFBvc2l0aW9uKHBhdGNoZWREaXNwYXRjaFNjcm9sbFBvc2l0aW9uKTtcblxuICBjb25zdCBbbGFzdEludGVyYWN0ZWRBY3Rpdml0eV0gPSB1c2VBY2tub3dsZWRnZWRBY3Rpdml0eSgpO1xuXG4gIGNvbnN0IGluZGV4T2ZMYXN0SW50ZXJhY3RlZEFjdGl2aXR5ID0gYWN0aXZpdGllcy5pbmRleE9mKGxhc3RJbnRlcmFjdGVkQWN0aXZpdHkpO1xuXG4gIC8vIENyZWF0ZSBhIG5ldyBJRCBmb3IgYXJpYS1hY3RpdmVkZXNjZW5kYW50IGV2ZXJ5IHRpbWUgdGhlIGFjdGl2ZSBkZXNjZW5kYW50IGNoYW5nZS5cbiAgLy8gSW4gb3VyIGRlc2lnbiwgdGhlIHRyYW5zY3JpcHQgd2lsbCBvbmx5IGhhdmUgMSBmb2N1c2VkIGFjdGl2aXR5IGFuZCBpdCBoYXMgYW4gSUQuIE90aGVyIGJsdXJyZWQgYWN0aXZpdGllcyB3aWxsIG5vdCBoYXZlIElEIGFzc2lnbmVkLlxuICAvLyBUaGlzIGhlbHAgd2l0aCBwZXJmb3JtYW5jZS5cbiAgLy8gQnV0IGJyb3dzZXIgdXN1YWxseSBkbyBub29wIGlmIHRoZSB2YWx1ZSBvZiBhcmlhLWFjdGl2ZWRlc2NlbmRhbnQgZG9lc24ndCBjaGFuZ2UuXG4gIC8vIFRoYXQgbWVhbnMsIGlmIHdlIGFzc2lnbiB0aGUgc2FtZSBJRCB0byBhbm90aGVyIGVsZW1lbnQsIGJyb3dzZXIgd2lsbCBkbyBub29wLlxuICAvLyBXZSBuZWVkIHRvIGdlbmVyYXRlIGEgbmV3IElEIHNvIHRoZSBicm93c2VyIHNlZSB0aGVyZSBpcyBhIGNoYW5nZSBpbiBhcmlhLWFjdGl2ZWRlc2NlbmRhbnQgdmFsdWUgYW5kIHBlcmZvcm0gYWNjb3JkaW5nbHkuXG4gIGNvbnN0IGFjdGl2ZURlc2NlbmRhbnRFbGVtZW50SWQgPSB1c2VNZW1vKFxuICAgICgpID0+IGZvY3VzZWRBY3Rpdml0eUtleSAmJiBgd2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fYWN0aXZlLWRlc2NlbmRhbnQtJHtyYW5kb20oKS50b1N0cmluZygzNikuc3Vic3RyKDIsIDUpfWAsXG4gICAgW2ZvY3VzZWRBY3Rpdml0eUtleV1cbiAgKTtcblxuICBjb25zdCBzY3JvbGxBY3RpdmVEZXNjZW5kYW50SW50b1ZpZXcgPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgY29uc3QgYWN0aXZlRGVzY2VuZGFudCA9IGFjdGl2ZURlc2NlbmRhbnRFbGVtZW50SWQgJiYgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYWN0aXZlRGVzY2VuZGFudEVsZW1lbnRJZCk7XG5cbiAgICAvLyBEb24ndCBzY3JvbGwgYWN0aXZlIGRlc2NlbmRhbnQgaW50byB2aWV3IGlmIHRoZSBmb2N1cyBpcyBhbHJlYWR5IGluc2lkZSBpdC5cbiAgICAvLyBPdGhlcndpc2UsIGdpdmVuIHRoZSBmb2N1cyBpcyBvbiB0aGUgc2VuZCBib3gsIGNsaWNraW5nIG9uIGFueSA8aW5wdXQ+IGluc2lkZSB0aGUgQWRhcHRpdmUgQ2FyZHMgbWF5IGNhdXNlIHRoZSB2aWV3IHRvIG1vdmUuXG4gICAgLy8gVGhpcyBVWCBpcyBub3QgZGVzaXJhYmxlIGJlY2F1c2UgY2xpY2sgc2hvdWxkIG5vdCBjYXVzZSBzY3JvbGwuXG4gICAgaWYgKGFjdGl2ZURlc2NlbmRhbnQgJiYgIWFjdGl2ZURlc2NlbmRhbnQuY29udGFpbnMoZG9jdW1lbnQuYWN0aXZlRWxlbWVudCkpIHtcbiAgICAgIC8vIENoZWNrcyBpZiBzY3JvbGxJbnRvVmlldyBzdXBwb3J0IG9wdGlvbnMgb3Igbm90LlxuICAgICAgLy8gLSBodHRwczovL2dpdGh1Yi5jb20vTW9kZXJuaXpyL01vZGVybml6ci9pc3N1ZXMvMTU2OCNpc3N1ZWNvbW1lbnQtNDE5NDU3OTcyXG4gICAgICAvLyAtIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzQ2OTE5NjI3L2lzLWl0LXBvc3NpYmxlLXRvLXRlc3QtZm9yLXNjcm9sbGludG92aWV3LWJyb3dzZXItY29tcGF0aWJpbGl0eVxuICAgICAgaWYgKCdzY3JvbGxCZWhhdmlvcicgaW4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlKSB7XG4gICAgICAgIGFjdGl2ZURlc2NlbmRhbnQuc2Nyb2xsSW50b1ZpZXcoeyBibG9jazogJ25lYXJlc3QnIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gVGhpcyBpcyBmb3IgYnJvd3NlciB0aGF0IGRvZXMgbm90IHN1cHBvcnQgb3B0aW9ucyBwYXNzZWQgdG8gc2Nyb2xsSW50b1ZpZXcoKSwgcG9zc2libHkgSUUxMS5cbiAgICAgICAgY29uc3Qgc2Nyb2xsYWJsZUVsZW1lbnQgPSByb290RWxlbWVudFJlZi5jdXJyZW50LnF1ZXJ5U2VsZWN0b3IoJy53ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0X19zY3JvbGxhYmxlJyk7XG4gICAgICAgIGNvbnN0IHNjcm9sbFRvcEF0VG9wU2lkZSA9IGFjdGl2ZURlc2NlbmRhbnQub2Zmc2V0VG9wO1xuICAgICAgICBjb25zdCBzY3JvbGxUb3BBdEJvdHRvbVNpZGUgPSBhY3RpdmVEZXNjZW5kYW50Lm9mZnNldFRvcCArIGFjdGl2ZURlc2NlbmRhbnQub2Zmc2V0SGVpZ2h0O1xuXG4gICAgICAgIGlmIChzY3JvbGxUb3BBdFRvcFNpZGUgPCBzY3JvbGxhYmxlRWxlbWVudC5zY3JvbGxUb3ApIHtcbiAgICAgICAgICBzY3JvbGxhYmxlRWxlbWVudC5zY3JvbGxUb3AgPSBzY3JvbGxUb3BBdFRvcFNpZGU7XG4gICAgICAgIH0gZWxzZSBpZiAoc2Nyb2xsVG9wQXRCb3R0b21TaWRlID4gc2Nyb2xsYWJsZUVsZW1lbnQuc2Nyb2xsVG9wICsgc2Nyb2xsYWJsZUVsZW1lbnQub2Zmc2V0SGVpZ2h0KSB7XG4gICAgICAgICAgc2Nyb2xsYWJsZUVsZW1lbnQuc2Nyb2xsVG9wID0gc2Nyb2xsVG9wQXRCb3R0b21TaWRlIC0gc2Nyb2xsYWJsZUVsZW1lbnQub2Zmc2V0SGVpZ2h0O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9LCBbYWN0aXZlRGVzY2VuZGFudEVsZW1lbnRJZCwgcm9vdEVsZW1lbnRSZWZdKTtcblxuICBjb25zdCBoYW5kbGVUcmFuc2NyaXB0Rm9jdXMgPSB1c2VDYWxsYmFjayhcbiAgICBldmVudCA9PiB7XG4gICAgICBjb25zdCB7IGN1cnJlbnRUYXJnZXQsIHRhcmdldCB9ID0gZXZlbnQ7XG5cbiAgICAgIC8vIFdoZW4gZm9jdXMgaXMgcGxhY2VkIG9uIHRoZSB0cmFuc2NyaXB0LCBzY3JvbGwgYWN0aXZlIGRlc2NlbmRhbnQgaW50byB0aGUgdmlldy5cbiAgICAgIGN1cnJlbnRUYXJnZXQgPT09IHRhcmdldCAmJiBzY3JvbGxBY3RpdmVEZXNjZW5kYW50SW50b1ZpZXcoKTtcbiAgICB9LFxuICAgIFtzY3JvbGxBY3RpdmVEZXNjZW5kYW50SW50b1ZpZXddXG4gICk7XG5cbiAgLy8gQWZ0ZXIgbmV3IGFyaWEtYWN0aXZlZGVzY2VuZGFudCBpcyBhc3NpZ25lZCwgd2Ugd2lsbCBuZWVkIHRvIHNjcm9sbCBpdCBpbnRvIHZpZXcuXG4gIC8vIFVzZXIgYWdlbnQgd2lsbCBzY3JvbGwgYXV0b21hdGljYWxseSBmb3IgZm9jdXNpbmcgZWxlbWVudCwgYnV0IG5vdCBmb3IgYXJpYS1hY3RpdmVkZXNjZW5kYW50LlxuICAvLyBXZSBuZWVkIHRvIGRvIHRoZSBzY3JvbGxpbmcgbWFudWFsbHkuXG4gIHVzZUVmZmVjdCgoKSA9PiBzY3JvbGxBY3RpdmVEZXNjZW5kYW50SW50b1ZpZXcoKSwgW3Njcm9sbEFjdGl2ZURlc2NlbmRhbnRJbnRvVmlld10pO1xuXG4gIC8vIElmIGFueSBhY3Rpdml0aWVzIGhhcyBjaGFuZ2VkLCByZXNldCB0aGUgYWN0aXZlIGRlc2NlbmRhbnQuXG4gIHVzZUVmZmVjdCgoKSA9PiBzZXRGb2N1c2VkQWN0aXZpdHlLZXkodW5kZWZpbmVkKSwgW2FjdGl2aXRpZXMsIHNldEZvY3VzZWRBY3Rpdml0eUtleV0pO1xuXG4gIGNvbnN0IGZvY3VzUmVsYXRpdmVBY3Rpdml0eSA9IHVzZUNhbGxiYWNrKFxuICAgIGRlbHRhID0+IHtcbiAgICAgIGlmIChpc05hTihkZWx0YSkgfHwgIXJlbmRlcmluZ0VsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gc2V0Rm9jdXNlZEFjdGl2aXR5S2V5KHVuZGVmaW5lZCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGluZGV4ID0gcmVuZGVyaW5nRWxlbWVudHMuZmluZEluZGV4KCh7IGtleSB9KSA9PiBrZXkgPT09IGZvY3VzZWRBY3Rpdml0eUtleSk7XG4gICAgICBjb25zdCBuZXh0SW5kZXggPSB+aW5kZXhcbiAgICAgICAgPyBNYXRoLm1heCgwLCBNYXRoLm1pbihyZW5kZXJpbmdFbGVtZW50cy5sZW5ndGggLSAxLCBpbmRleCArIGRlbHRhKSlcbiAgICAgICAgOiByZW5kZXJpbmdFbGVtZW50cy5sZW5ndGggLSAxO1xuICAgICAgY29uc3QgbmV4dEZvY3VzZWRBY3Rpdml0eSA9IHJlbmRlcmluZ0VsZW1lbnRzW25leHRJbmRleF07XG5cbiAgICAgIHNldEZvY3VzZWRBY3Rpdml0eUtleShuZXh0Rm9jdXNlZEFjdGl2aXR5LmtleSk7XG4gICAgICByb290RWxlbWVudFJlZi5jdXJyZW50ICYmIHJvb3RFbGVtZW50UmVmLmN1cnJlbnQuZm9jdXMoKTtcbiAgICB9LFxuICAgIFtmb2N1c2VkQWN0aXZpdHlLZXksIHJlbmRlcmluZ0VsZW1lbnRzLCByb290RWxlbWVudFJlZiwgc2V0Rm9jdXNlZEFjdGl2aXR5S2V5XVxuICApO1xuXG4gIGNvbnN0IGhhbmRsZVRyYW5zY3JpcHRLZXlEb3duID0gdXNlQ2FsbGJhY2soXG4gICAgZXZlbnQgPT4ge1xuICAgICAgY29uc3QgeyB0YXJnZXQgfSA9IGV2ZW50O1xuXG4gICAgICBjb25zdCBmcm9tRW5kT2ZUcmFuc2NyaXB0SW5kaWNhdG9yID0gdGFyZ2V0ID09PSB0ZXJtaW5hdG9yUmVmLmN1cnJlbnQ7XG4gICAgICBjb25zdCBmcm9tVHJhbnNjcmlwdCA9IHRhcmdldCA9PT0gZXZlbnQuY3VycmVudFRhcmdldDtcblxuICAgICAgaWYgKCFmcm9tRW5kT2ZUcmFuc2NyaXB0SW5kaWNhdG9yICYmICFmcm9tVHJhbnNjcmlwdCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGxldCBoYW5kbGVkID0gdHJ1ZTtcblxuICAgICAgc3dpdGNoIChldmVudC5rZXkpIHtcbiAgICAgICAgY2FzZSAnQXJyb3dEb3duJzpcbiAgICAgICAgICBmb2N1c1JlbGF0aXZlQWN0aXZpdHkoZnJvbUVuZE9mVHJhbnNjcmlwdEluZGljYXRvciA/IDAgOiAxKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlICdBcnJvd1VwJzpcbiAgICAgICAgICBmb2N1c1JlbGF0aXZlQWN0aXZpdHkoZnJvbUVuZE9mVHJhbnNjcmlwdEluZGljYXRvciA/IDAgOiAtMSk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAnRW5kJzpcbiAgICAgICAgICBmb2N1c1JlbGF0aXZlQWN0aXZpdHkoSW5maW5pdHkpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgJ0VudGVyJzpcbiAgICAgICAgICBpZiAoIWZyb21FbmRPZlRyYW5zY3JpcHRJbmRpY2F0b3IpIHtcbiAgICAgICAgICAgIGNvbnN0IGZvY3VzZWRBY3Rpdml0eUVudHJ5ID0gcmVuZGVyaW5nRWxlbWVudHMuZmluZCgoeyBrZXkgfSkgPT4ga2V5ID09PSBmb2N1c2VkQWN0aXZpdHlLZXkpO1xuXG4gICAgICAgICAgICBpZiAoZm9jdXNlZEFjdGl2aXR5RW50cnkpIHtcbiAgICAgICAgICAgICAgY29uc3QgeyBlbGVtZW50OiBmb2N1c2VkQWN0aXZpdHlFbGVtZW50IH0gPVxuICAgICAgICAgICAgICAgIGFjdGl2aXR5RWxlbWVudHNSZWYuY3VycmVudC5maW5kKCh7IGFjdGl2aXR5IH0pID0+IGFjdGl2aXR5ID09PSBmb2N1c2VkQWN0aXZpdHlFbnRyeS5hY3Rpdml0eSkgfHwge307XG5cbiAgICAgICAgICAgICAgaWYgKGZvY3VzZWRBY3Rpdml0eUVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBbZmlyc3RUYWJiYWJsZUVsZW1lbnRdID0gdGFiYmFibGVFbGVtZW50cyhmb2N1c2VkQWN0aXZpdHlFbGVtZW50KS5maWx0ZXIoXG4gICAgICAgICAgICAgICAgICAoeyBjbGFzc05hbWUgfSkgPT4gY2xhc3NOYW1lICE9PSAnd2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fYWN0aXZpdHktc2VudGluZWwnXG4gICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIGZpcnN0VGFiYmFibGVFbGVtZW50ICYmIGZpcnN0VGFiYmFibGVFbGVtZW50LmZvY3VzKCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlICdFc2NhcGUnOlxuICAgICAgICAgIGZvY3VzKCdzZW5kQm94V2l0aG91dEtleWJvYXJkJyk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAnSG9tZSc6XG4gICAgICAgICAgZm9jdXNSZWxhdGl2ZUFjdGl2aXR5KC1JbmZpbml0eSk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBoYW5kbGVkID0gZmFsc2U7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGlmIChoYW5kbGVkKSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgLy8gSWYgYSBjdXN0b20gSFRNTCBjb250cm9sIHdhbnRzIHRvIGhhbmRsZSB1cC9kb3duIGFycm93LCB3ZSB3aWxsIHByZXZlbnQgdGhlbSBmcm9tIGxpc3RlbmluZyB0byB0aGlzIGV2ZW50IHRvIHByZXZlbnQgYnVncyBkdWUgdG8gaGFuZGxpbmcgYXJyb3cga2V5cyB0d2ljZS5cbiAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICB9XG4gICAgfSxcbiAgICBbZm9jdXNlZEFjdGl2aXR5S2V5LCBhY3Rpdml0eUVsZW1lbnRzUmVmLCBmb2N1c1JlbGF0aXZlQWN0aXZpdHksIGZvY3VzLCB0ZXJtaW5hdG9yUmVmLCByZW5kZXJpbmdFbGVtZW50c11cbiAgKTtcblxuICBjb25zdCBsYWJlbElkID0gdXNlVW5pcXVlSWQoJ3dlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX2xhYmVsJyk7XG5cbiAgLy8gSWYgU0hJRlQtVEFCIGZyb20gXCJFbmQgb2YgdHJhbnNjcmlwdFwiIGluZGljYXRvciwgaWYgZm9jdXNlZEFjdGl2aXR5S2V5IGlzIG5vdCBzZXQgKG9yIG5vIGxvbmdlciBleGlzdHMpLCBzZXQgaXQgdGhlIHRoZSBib3R0b21tb3N0IGFjdGl2aXR5LlxuICBjb25zdCBzZXRCb3R0b21tb3N0Rm9jdXNlZEFjdGl2aXR5S2V5SWZOZWVkZWQgPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgaWYgKCF+cmVuZGVyaW5nRWxlbWVudHMuZmluZEluZGV4KCh7IGtleSB9KSA9PiBrZXkgPT09IGZvY3VzZWRBY3Rpdml0eUtleSkpIHtcbiAgICAgIGNvbnN0IHsga2V5OiBsYXN0QWN0aXZpdHlLZXkgfSA9IHJlbmRlcmluZ0VsZW1lbnRzW3JlbmRlcmluZ0VsZW1lbnRzLmxlbmd0aCAtIDFdIHx8IHt9O1xuXG4gICAgICBzZXRGb2N1c2VkQWN0aXZpdHlLZXkobGFzdEFjdGl2aXR5S2V5KTtcbiAgICB9XG4gIH0sIFtmb2N1c2VkQWN0aXZpdHlLZXksIHJlbmRlcmluZ0VsZW1lbnRzLCBzZXRGb2N1c2VkQWN0aXZpdHlLZXldKTtcblxuICBjb25zdCBoYW5kbGVUcmFuc2NyaXB0S2V5RG93bkNhcHR1cmUgPSB1c2VDYWxsYmFjayhcbiAgICBldmVudCA9PiB7XG4gICAgICBjb25zdCB7IGFsdEtleSwgY3RybEtleSwga2V5LCBtZXRhS2V5LCB0YXJnZXQgfSA9IGV2ZW50O1xuXG4gICAgICBpZiAoYWx0S2V5IHx8IChjdHJsS2V5ICYmIGtleSAhPT0gJ3YnKSB8fCBtZXRhS2V5IHx8ICghaW5wdXR0YWJsZUtleShrZXkpICYmIGtleSAhPT0gJ0JhY2tzcGFjZScpKSB7XG4gICAgICAgIC8vIElnbm9yZSBpZiBvbmUgb2YgdGhlIHV0aWxpdHkga2V5IChleGNlcHQgU0hJRlQpIGlzIHByZXNzZWRcbiAgICAgICAgLy8gRS5nLiBDVFJMLUMgb24gYSBsaW5rIGluIG9uZSBvZiB0aGUgbWVzc2FnZSBzaG91bGQgbm90IGp1bXAgdG8gY2hhdCBib3hcbiAgICAgICAgLy8gRS5nLiBcIkFcIiBvciBcIkJhY2tzcGFjZVwiIHNob3VsZCBqdW1wIHRvIGNoYXQgYm94XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gU2VuZCBrZXlzdHJva2VzIHRvIHNlbmQgYm94IGlmIHdlIGFyZSBmb2N1c2luZyBvbiB0aGUgdHJhbnNjcmlwdCBvciB0ZXJtaW5hdG9yLlxuICAgICAgaWYgKHRhcmdldCA9PT0gZXZlbnQuY3VycmVudFRhcmdldCB8fCB0YXJnZXQgPT09IHRlcm1pbmF0b3JSZWYuY3VycmVudCkge1xuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgICBmb2N1cygnc2VuZEJveCcpO1xuICAgICAgfVxuICAgIH0sXG4gICAgW2ZvY3VzXVxuICApO1xuXG4gIGNvbnN0IGZvY3VzVHJhbnNjcmlwdENhbGxiYWNrID0gdXNlQ2FsbGJhY2soXG4gICAgKCkgPT4gcm9vdEVsZW1lbnRSZWYuY3VycmVudCAmJiByb290RWxlbWVudFJlZi5jdXJyZW50LmZvY3VzKCksXG4gICAgW3Jvb3RFbGVtZW50UmVmXVxuICApO1xuXG4gIHVzZVJlZ2lzdGVyRm9jdXNUcmFuc2NyaXB0KGZvY3VzVHJhbnNjcmlwdENhbGxiYWNrKTtcblxuICBjb25zdCBoYW5kbGVGb2N1c0FjdGl2aXR5ID0gdXNlQ2FsbGJhY2soXG4gICAga2V5ID0+IHtcbiAgICAgIHNldEZvY3VzZWRBY3Rpdml0eUtleShrZXkpO1xuICAgICAgcm9vdEVsZW1lbnRSZWYuY3VycmVudCAmJiByb290RWxlbWVudFJlZi5jdXJyZW50LmZvY3VzKCk7XG4gICAgfSxcbiAgICBbc2V0Rm9jdXNlZEFjdGl2aXR5S2V5XVxuICApO1xuXG4gIC8vIFdoZW4gdGhlIGZvY3VzaW5nIGFjdGl2aXR5IGhhcyBjaGFuZ2VkLCBkaXNwYXRjaCBhbiBldmVudCB0byBvYnNlcnZlcnMgb2YgXCJ1c2VPYnNlcnZlVHJhbnNjcmlwdEZvY3VzXCIuXG4gIGNvbnN0IGRpc3BhdGNoVHJhbnNjcmlwdEZvY3VzID0gdXNlRGlzcGF0Y2hUcmFuc2NyaXB0Rm9jdXMoKTtcbiAgY29uc3QgZm9jdXNlZEFjdGl2aXR5ID0gdXNlTWVtbygoKSA9PiB7XG4gICAgY29uc3QgeyBhY3Rpdml0eSB9ID0gcmVuZGVyaW5nRWxlbWVudHMuZmluZCgoeyBrZXkgfSkgPT4ga2V5ID09PSBmb2N1c2VkQWN0aXZpdHlLZXkpIHx8IHt9O1xuXG4gICAgcmV0dXJuIGFjdGl2aXR5O1xuICB9LCBbZm9jdXNlZEFjdGl2aXR5S2V5LCByZW5kZXJpbmdFbGVtZW50c10pO1xuXG4gIHVzZU1lbW8oXG4gICAgKCkgPT4gZGlzcGF0Y2hUcmFuc2NyaXB0Rm9jdXMgJiYgZGlzcGF0Y2hUcmFuc2NyaXB0Rm9jdXMoeyBhY3Rpdml0eTogZm9jdXNlZEFjdGl2aXR5IH0pLFxuICAgIFtkaXNwYXRjaFRyYW5zY3JpcHRGb2N1cywgZm9jdXNlZEFjdGl2aXR5XVxuICApO1xuXG4gIC8vIFRoaXMgaXMgcmVxdWlyZWQgYnkgSUUxMS5cbiAgLy8gV2hlbiB0aGUgdXNlciBjbGlja3Mgb24gYW5kIGVtcHR5IHNwYWNlIChhLmsuYS4gZmlsbGVyKSBpbiBhbiBlbXB0eSB0cmFuc2NyaXB0LCBJRTExIHNheXMgdGhlIGZvY3VzIGlzIG9uIHRoZSA8ZGl2IGNsYXNzTmFtZT1cImZpbGxlclwiPixcbiAgLy8gZGVzcGl0ZSB0aGUgZmFjdCB0aGVyZSBhcmUgbm8gXCJ0YWJJbmRleFwiIGF0dHJpYnV0ZXMgc2V0IG9uIHRoZSBmaWxsZXIuXG4gIC8vIFdlIG5lZWQgdG8gYXJ0aWZpY2lhbGx5IHNlbmQgdGhlIGZvY3VzIGJhY2sgdG8gdGhlIHRyYW5zY3JpcHQuXG4gIGNvbnN0IGhhbmRsZUZvY3VzRmlsbGVyID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIGNvbnN0IHsgY3VycmVudCB9ID0gcm9vdEVsZW1lbnRSZWY7XG5cbiAgICBjdXJyZW50ICYmIGN1cnJlbnQuZm9jdXMoKTtcbiAgfSwgW3Jvb3RFbGVtZW50UmVmXSk7XG5cbiAgcmV0dXJuIChcbiAgICA8ZGl2XG4gICAgICBhcmlhLWFjdGl2ZWRlc2NlbmRhbnQ9e2ZvY3VzZWRBY3Rpdml0eUtleSA/IGFjdGl2ZURlc2NlbmRhbnRFbGVtZW50SWQgOiB1bmRlZmluZWR9XG4gICAgICBhcmlhLWxhYmVsbGVkYnk9e2xhYmVsSWR9XG4gICAgICBjbGFzc05hbWU9e2NsYXNzTmFtZXMoXG4gICAgICAgICd3ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0JyxcbiAgICAgICAgYmFzaWNUcmFuc2NyaXB0U3R5bGVTZXQgKyAnJyxcbiAgICAgICAgcm9vdENsYXNzTmFtZSxcbiAgICAgICAgKGNsYXNzTmFtZSB8fCAnJykgKyAnJ1xuICAgICAgKX1cbiAgICAgIGRpcj17ZGlyZWN0aW9ufVxuICAgICAgb25Gb2N1cz17aGFuZGxlVHJhbnNjcmlwdEZvY3VzfVxuICAgICAgb25LZXlEb3duPXtoYW5kbGVUcmFuc2NyaXB0S2V5RG93bn1cbiAgICAgIG9uS2V5RG93bkNhcHR1cmU9e2hhbmRsZVRyYW5zY3JpcHRLZXlEb3duQ2FwdHVyZX1cbiAgICAgIHJlZj17cm9vdEVsZW1lbnRSZWZ9XG4gICAgICAvLyBcImFyaWEtYWN0aXZlZGVzY2VuZGFudFwiIHdpbGwgb25seSB3b3JrcyB3aXRoIGEgbnVtYmVyIG9mIHJvbGVzIGFuZCBpdCBtdXN0IGJlIGV4cGxpY2l0bHkgc2V0LlxuICAgICAgLy8gaHR0cHM6Ly93d3cudzMub3JnL1RSL3dhaS1hcmlhLyNhcmlhLWFjdGl2ZWRlc2NlbmRhbnRcbiAgICAgIHJvbGU9XCJncm91cFwiXG4gICAgICAvLyBGb3IgdXAvZG93biBhcnJvdyBrZXkgbmF2aWdhdGlvbiBhY3Jvc3MgYWN0aXZpdGllcywgdGhpcyBjb21wb25lbnQgbXVzdCBiZSBpbmNsdWRlZCBpbiB0aGUgdGFiIHNlcXVlbmNlLlxuICAgICAgLy8gT3RoZXJ3aXNlLCBcImFyaWEtYWN0aXZlZGVzY2VuZGFudFwiIHdpbGwgbm90IGJlIG5hcnJhdGVkIHdoZW4gdGhlIHVzZXIgcHJlc3MgdXAvZG93biBhcnJvdyBrZXlzLlxuICAgICAgLy8gaHR0cHM6Ly93d3cudzMub3JnL1RSL3dhaS1hcmlhLXByYWN0aWNlcy0xLjEvI2tiZF9mb2N1c19hY3RpdmVkZXNjZW5kYW50XG4gICAgICB0YWJJbmRleD17MH1cbiAgICA+XG4gICAgICA8U2NyZWVuUmVhZGVyVGV4dCBpZD17bGFiZWxJZH0gdGV4dD17dHJhbnNjcmlwdEFyaWFMYWJlbH0gLz5cbiAgICAgIHsvKiBUaGlzIDxzZWN0aW9uPiBpcyBmb3IgbGl2ZSByZWdpb24gb25seS4gQ29udGVudCBpcyBtYWRlIGludmlzaWJsZSB0aHJvdWdoIENTUy4gKi99XG4gICAgICA8c2VjdGlvblxuICAgICAgICBhcmlhLWF0b21pYz17ZmFsc2V9XG4gICAgICAgIGFyaWEtbGl2ZT1cInBvbGl0ZVwiXG4gICAgICAgIGFyaWEtcmVsZXZhbnQ9XCJhZGRpdGlvbnNcIlxuICAgICAgICBhcmlhLXJvbGVkZXNjcmlwdGlvbj17dHJhbnNjcmlwdFJvbGVEZXNjcmlwdGlvbn1cbiAgICAgICAgcm9sZT1cImxvZ1wiXG4gICAgICA+XG4gICAgICAgIHtyZW5kZXJpbmdFbGVtZW50c1xuICAgICAgICAgIC5maWx0ZXIoKHsgc3VwcG9ydFNjcmVlblJlYWRlciB9KSA9PiBzdXBwb3J0U2NyZWVuUmVhZGVyKVxuICAgICAgICAgIC5tYXAoKHsgYWN0aXZpdHksIGxpdmVSZWdpb25LZXkgfSkgPT4gKFxuICAgICAgICAgICAgPEZhZGUgZmFkZUFmdGVyPXtpbnRlcm5hbExpdmVSZWdpb25GYWRlQWZ0ZXJ9IGtleT17bGl2ZVJlZ2lvbktleX0+XG4gICAgICAgICAgICAgIHsoKSA9PiA8U2NyZWVuUmVhZGVyQWN0aXZpdHkgYWN0aXZpdHk9e2FjdGl2aXR5fSAvPn1cbiAgICAgICAgICAgIDwvRmFkZT5cbiAgICAgICAgICApKX1cbiAgICAgIDwvc2VjdGlvbj5cbiAgICAgIHsvKiBUT0RPOiBbUDJdIEZpeCBFU0xpbnQgZXJyb3IgYG5vLXVzZS1iZWZvcmUtZGVmaW5lYCAqL31cbiAgICAgIHsvKiBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVzZS1iZWZvcmUtZGVmaW5lICovfVxuICAgICAgPEludGVybmFsVHJhbnNjcmlwdFNjcm9sbGFibGVcbiAgICAgICAgYWN0aXZpdGllcz17cmVuZGVyaW5nQWN0aXZpdGllc31cbiAgICAgICAgb25Gb2N1c0FjdGl2aXR5PXtoYW5kbGVGb2N1c0FjdGl2aXR5fVxuICAgICAgICBvbkZvY3VzRmlsbGVyPXtoYW5kbGVGb2N1c0ZpbGxlcn1cbiAgICAgICAgdGVybWluYXRvclJlZj17dGVybWluYXRvclJlZn1cbiAgICAgID5cbiAgICAgICAge3JlbmRlcmluZ0VsZW1lbnRzLm1hcChcbiAgICAgICAgICAoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFjdGl2aXR5LFxuICAgICAgICAgICAgICBjYWxsYmFja1JlZixcbiAgICAgICAgICAgICAgZm9jdXNBY3Rpdml0eSxcbiAgICAgICAgICAgICAgaGFuZGxlRm9jdXMsXG4gICAgICAgICAgICAgIGhhbmRsZUtleURvd24sXG4gICAgICAgICAgICAgIGhhbmRsZU1vdXNlRG93bkNhcHR1cmUsXG4gICAgICAgICAgICAgIGhpZGVUaW1lc3RhbXAsXG4gICAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgICAgcmVuZGVyQWN0aXZpdHksXG4gICAgICAgICAgICAgIHJlbmRlckFjdGl2aXR5U3RhdHVzLFxuICAgICAgICAgICAgICByZW5kZXJBdmF0YXIsXG4gICAgICAgICAgICAgIHJvbGUsXG4gICAgICAgICAgICAgIHNob3VsZFNwZWFrLFxuICAgICAgICAgICAgICBzaG93Q2FsbG91dCxcbiAgICAgICAgICAgICAgc3VwcG9ydFNjcmVlblJlYWRlclxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IGFyaWFMYWJlbElELCBlbGVtZW50IH0gPVxuICAgICAgICAgICAgICBhY3Rpdml0eUVsZW1lbnRzUmVmLmN1cnJlbnQuZmluZChlbnRyeSA9PiBlbnRyeS5hY3Rpdml0eSA9PT0gYWN0aXZpdHkpIHx8IHt9O1xuICAgICAgICAgICAgY29uc3QgYWN0aXZlRGVzY2VuZGFudCA9IGZvY3VzZWRBY3Rpdml0eUtleSA9PT0ga2V5O1xuICAgICAgICAgICAgY29uc3QgaXNDb250ZW50SW50ZXJhY3RpdmUgPSAhIShlbGVtZW50XG4gICAgICAgICAgICAgID8gdGFiYmFibGVFbGVtZW50cyhlbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy53ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0X19hY3Rpdml0eS1ib3gnKSkubGVuZ3RoXG4gICAgICAgICAgICAgIDogMCk7XG5cbiAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgIDxsaVxuICAgICAgICAgICAgICAgIGFyaWEtbGFiZWxsZWRieT17YXJpYUxhYmVsSUR9XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lPXtjbGFzc05hbWVzKCd3ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0X19hY3Rpdml0eScsIHtcbiAgICAgICAgICAgICAgICAgICd3ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0X19hY3Rpdml0eS0tYWNrbm93bGVkZ2VkJzogaW5kZXggPD0gaW5kZXhPZkxhc3RJbnRlcmFjdGVkQWN0aXZpdHksXG4gICAgICAgICAgICAgICAgICAnd2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fYWN0aXZpdHktLWZyb20tYm90Jzogcm9sZSAhPT0gJ3VzZXInLFxuICAgICAgICAgICAgICAgICAgJ3dlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX2FjdGl2aXR5LS1mcm9tLXVzZXInOiByb2xlID09PSAndXNlcidcbiAgICAgICAgICAgICAgICB9KX1cbiAgICAgICAgICAgICAgICAvLyBTZXQgXCJpZFwiIGZvciB2YWxpZCBmb3IgYWNjZXNzaWJpbGl0eS5cbiAgICAgICAgICAgICAgICAvKiBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QvZm9yYmlkLWRvbS1wcm9wcyAqL1xuICAgICAgICAgICAgICAgIGlkPXthY3RpdmVEZXNjZW5kYW50ID8gYWN0aXZlRGVzY2VuZGFudEVsZW1lbnRJZCA6IHVuZGVmaW5lZH1cbiAgICAgICAgICAgICAgICBrZXk9e2tleX1cbiAgICAgICAgICAgICAgICBvbkZvY3VzPXtoYW5kbGVGb2N1c31cbiAgICAgICAgICAgICAgICBvbktleURvd249e2hhbmRsZUtleURvd259XG4gICAgICAgICAgICAgICAgb25Nb3VzZURvd25DYXB0dXJlPXtoYW5kbGVNb3VzZURvd25DYXB0dXJlfVxuICAgICAgICAgICAgICAgIHJlZj17Y2FsbGJhY2tSZWZ9XG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICB7c3VwcG9ydFNjcmVlblJlYWRlciAmJiAoXG4gICAgICAgICAgICAgICAgICA8U2NyZWVuUmVhZGVyQWN0aXZpdHkgYWN0aXZpdHk9e2FjdGl2aXR5fSBpZD17YXJpYUxhYmVsSUR9IHJlbmRlckF0dGFjaG1lbnRzPXtmYWxzZX0+XG4gICAgICAgICAgICAgICAgICAgIHshIWlzQ29udGVudEludGVyYWN0aXZlICYmIDxwPnthY3Rpdml0eUludGVyYWN0aXZlQWx0fTwvcD59XG4gICAgICAgICAgICAgICAgICA8L1NjcmVlblJlYWRlckFjdGl2aXR5PlxuICAgICAgICAgICAgICAgICl9XG4gICAgICAgICAgICAgICAgPEZvY3VzUmVkaXJlY3RvclxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwid2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fYWN0aXZpdHktc2VudGluZWxcIlxuICAgICAgICAgICAgICAgICAgb25Gb2N1cz17Zm9jdXNBY3Rpdml0eX1cbiAgICAgICAgICAgICAgICAgIHJlZGlyZWN0UmVmPXtyb290RWxlbWVudFJlZn1cbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwid2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fYWN0aXZpdHktYm94XCI+XG4gICAgICAgICAgICAgICAgICB7cmVuZGVyQWN0aXZpdHkoe1xuICAgICAgICAgICAgICAgICAgICBoaWRlVGltZXN0YW1wLFxuICAgICAgICAgICAgICAgICAgICByZW5kZXJBY3Rpdml0eVN0YXR1cyxcbiAgICAgICAgICAgICAgICAgICAgcmVuZGVyQXZhdGFyLFxuICAgICAgICAgICAgICAgICAgICBzaG93Q2FsbG91dFxuICAgICAgICAgICAgICAgICAgfSl9XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAge3Nob3VsZFNwZWFrICYmIDxTcGVha0FjdGl2aXR5IGFjdGl2aXR5PXthY3Rpdml0eX0gLz59XG4gICAgICAgICAgICAgICAgPEZvY3VzUmVkaXJlY3RvclxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwid2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fYWN0aXZpdHktc2VudGluZWxcIlxuICAgICAgICAgICAgICAgICAgb25Gb2N1cz17Zm9jdXNBY3Rpdml0eX1cbiAgICAgICAgICAgICAgICAgIHJlZGlyZWN0UmVmPXtyb290RWxlbWVudFJlZn1cbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT17Y2xhc3NOYW1lcygnd2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fYWN0aXZpdHktaW5kaWNhdG9yJywge1xuICAgICAgICAgICAgICAgICAgICAnd2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fYWN0aXZpdHktaW5kaWNhdG9yLS1maXJzdCc6ICFpbmRleCxcbiAgICAgICAgICAgICAgICAgICAgJ3dlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX2FjdGl2aXR5LWluZGljYXRvci0tZm9jdXMnOiBhY3RpdmVEZXNjZW5kYW50XG4gICAgICAgICAgICAgICAgICB9KX1cbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICl9XG4gICAgICA8L0ludGVybmFsVHJhbnNjcmlwdFNjcm9sbGFibGU+XG4gICAgICB7ISFyZW5kZXJpbmdFbGVtZW50cy5sZW5ndGggJiYgKFxuICAgICAgICA8UmVhY3QuRnJhZ21lbnQ+XG4gICAgICAgICAgPEZvY3VzUmVkaXJlY3RvclxuICAgICAgICAgICAgY2xhc3NOYW1lPVwid2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fc2VudGluZWxcIlxuICAgICAgICAgICAgb25Gb2N1cz17c2V0Qm90dG9tbW9zdEZvY3VzZWRBY3Rpdml0eUtleUlmTmVlZGVkfVxuICAgICAgICAgICAgcmVkaXJlY3RSZWY9e3Jvb3RFbGVtZW50UmVmfVxuICAgICAgICAgIC8+XG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJ3ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0X190ZXJtaW5hdG9yXCIgcmVmPXt0ZXJtaW5hdG9yUmVmfSB0YWJJbmRleD17MH0+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIndlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX3Rlcm1pbmF0b3ItYm9keVwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIndlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX3Rlcm1pbmF0b3ItdGV4dFwiPnt0ZXJtaW5hdG9yVGV4dH08L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L1JlYWN0LkZyYWdtZW50PlxuICAgICAgKX1cbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwid2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fZm9jdXMtaW5kaWNhdG9yXCIgLz5cbiAgICA8L2Rpdj5cbiAgKTtcbn07XG5cbkludGVybmFsVHJhbnNjcmlwdC5kZWZhdWx0UHJvcHMgPSB7XG4gIGNsYXNzTmFtZTogJydcbn07XG5cbkludGVybmFsVHJhbnNjcmlwdC5wcm9wVHlwZXMgPSB7XG4gIGFjdGl2aXR5RWxlbWVudHNSZWY6IFByb3BUeXBlcy5zaGFwZSh7XG4gICAgY3VycmVudDogUHJvcFR5cGVzLmFycmF5LmlzUmVxdWlyZWRcbiAgfSkuaXNSZXF1aXJlZCxcbiAgY2xhc3NOYW1lOiBQcm9wVHlwZXMuc3RyaW5nXG59O1xuXG5jb25zdCBJbnRlcm5hbFNjcmVlblJlYWRlclRyYW5zY3JpcHQgPSAoeyByZW5kZXJpbmdFbGVtZW50cyB9KSA9PiB7XG4gIGNvbnN0IGxvY2FsaXplID0gdXNlTG9jYWxpemVyKCk7XG4gIGNvbnN0IFtpbnRlcm5hbExpdmVSZWdpb25GYWRlQWZ0ZXJdID0gdXNlU3R5bGVPcHRpb25zKCk7XG5cbiAgY29uc3QgdHJhbnNjcmlwdFJvbGVEZXNjcmlwdGlvbiA9IGxvY2FsaXplKCdUUkFOU0NSSVBUX0FSSUFfUk9MRV9BTFQnKTtcblxuICByZXR1cm4gKFxuICAgIDxzZWN0aW9uXG4gICAgICBhcmlhLWF0b21pYz17ZmFsc2V9XG4gICAgICBhcmlhLWxpdmU9XCJwb2xpdGVcIlxuICAgICAgYXJpYS1yZWxldmFudD1cImFkZGl0aW9uc1wiXG4gICAgICBhcmlhLXJvbGVkZXNjcmlwdGlvbj17dHJhbnNjcmlwdFJvbGVEZXNjcmlwdGlvbn1cbiAgICAgIHJvbGU9XCJsb2dcIlxuICAgID5cbiAgICAgIHtyZW5kZXJpbmdFbGVtZW50cy5tYXAoKHsgYWN0aXZpdHksIGxpdmVSZWdpb25LZXkgfSkgPT4gKFxuICAgICAgICA8RmFkZSBmYWRlQWZ0ZXI9e2ludGVybmFsTGl2ZVJlZ2lvbkZhZGVBZnRlcn0ga2V5PXtsaXZlUmVnaW9uS2V5fT5cbiAgICAgICAgICB7KCkgPT4gPFNjcmVlblJlYWRlckFjdGl2aXR5IGFjdGl2aXR5PXthY3Rpdml0eX0gLz59XG4gICAgICAgIDwvRmFkZT5cbiAgICAgICkpfVxuICAgIDwvc2VjdGlvbj5cbiAgKTtcbn07XG5cbkludGVybmFsU2NyZWVuUmVhZGVyVHJhbnNjcmlwdC5wcm9wVHlwZXMgPSB7XG4gIHJlbmRlcmluZ0VsZW1lbnRzOiBQcm9wVHlwZXMuYXJyYXlPZihcbiAgICBQcm9wVHlwZXMuc2hhcGUoe1xuICAgICAgYWN0aXZpdHk6IFByb3BUeXBlcy5hbnksXG4gICAgICBsaXZlUmVnaW9uS2V5OiBQcm9wVHlwZXMuc3RyaW5nXG4gICAgfSlcbiAgKS5pc1JlcXVpcmVkXG59O1xuXG4vLyBTZXBhcmF0aW5nIGhpZ2gtZnJlcXVlbmN5IGhvb2tzIHRvIGltcHJvdmUgcGVyZm9ybWFuY2UuXG5jb25zdCBJbnRlcm5hbFRyYW5zY3JpcHRTY3JvbGxhYmxlID0gKHsgYWN0aXZpdGllcywgY2hpbGRyZW4sIG9uRm9jdXNBY3Rpdml0eSwgb25Gb2N1c0ZpbGxlciwgdGVybWluYXRvclJlZiB9KSA9PiB7XG4gIGNvbnN0IFt7IGFjdGl2aXRpZXM6IGFjdGl2aXRpZXNTdHlsZVNldCB9XSA9IHVzZVN0eWxlU2V0KCk7XG4gIGNvbnN0IFthbmltYXRpbmdUb0VuZF0gPSB1c2VBbmltYXRpbmdUb0VuZCgpO1xuICBjb25zdCBbYXRFbmRdID0gdXNlQXRFbmQoKTtcbiAgY29uc3QgW3N0aWNreV0gPSB1c2VTdGlja3koKTtcbiAgY29uc3QgW3N0eWxlT3B0aW9uc10gPSB1c2VTdHlsZU9wdGlvbnMoKTtcbiAgY29uc3QgbGFzdFZpc2libGVBY3Rpdml0eUlkID0gZ2V0QWN0aXZpdHlVbmlxdWVJZChhY3Rpdml0aWVzW2FjdGl2aXRpZXMubGVuZ3RoIC0gMV0gfHwge30pOyAvLyBBY3Rpdml0eSBJRCBvZiB0aGUgbGFzdCB2aXNpYmxlIGFjdGl2aXR5IGluIHRoZSBsaXN0LlxuICBjb25zdCBsb2NhbGl6ZSA9IHVzZUxvY2FsaXplcigpO1xuICBjb25zdCBzY3JvbGxUb0VuZCA9IHVzZVNjcm9sbFRvRW5kKCk7XG5cbiAgY29uc3QgbGFzdFJlYWRBY3Rpdml0eUlkUmVmID0gdXNlUmVmKGxhc3RWaXNpYmxlQWN0aXZpdHlJZCk7XG4gIGNvbnN0IHRyYW5zY3JpcHRSb2xlRGVzY3JpcHRpb24gPSBsb2NhbGl6ZSgnVFJBTlNDUklQVF9BUklBX1JPTEVfQUxUJyk7XG5cbiAgY29uc3QgaGFuZGxlU2Nyb2xsVG9FbmRCdXR0b25DbGljayA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBzY3JvbGxUb0VuZCh7IGJlaGF2aW9yOiAnc21vb3RoJyB9KTtcblxuICAgIC8vIEFmdGVyIHRoZSBcIk5ldyBtZXNzYWdlXCIgYnV0dG9uIGlzIGNsaWNrZWQsIGZvY3VzIG9uIHRoZSBmaXJzdCB1bnJlYWQgYWN0aXZpdHkuXG4gICAgY29uc3QgaW5kZXggPSBhY3Rpdml0aWVzLmZpbmRJbmRleCgoeyBpZCB9KSA9PiBpZCA9PT0gbGFzdFJlYWRBY3Rpdml0eUlkUmVmLmN1cnJlbnQpO1xuXG4gICAgaWYgKH5pbmRleCkge1xuICAgICAgY29uc3QgZmlyc3RVbnJlYWRBY3Rpdml0eSA9IGFjdGl2aXRpZXNbaW5kZXggKyAxXTtcblxuICAgICAgaWYgKGZpcnN0VW5yZWFkQWN0aXZpdHkpIHtcbiAgICAgICAgcmV0dXJuIG9uRm9jdXNBY3Rpdml0eShnZXRBY3Rpdml0eVVuaXF1ZUlkKGZpcnN0VW5yZWFkQWN0aXZpdHkpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB7IGN1cnJlbnQgfSA9IHRlcm1pbmF0b3JSZWY7XG5cbiAgICBjdXJyZW50ICYmIGN1cnJlbnQuZm9jdXMoKTtcbiAgfSwgW2FjdGl2aXRpZXMsIGxhc3RSZWFkQWN0aXZpdHlJZFJlZiwgb25Gb2N1c0FjdGl2aXR5LCBzY3JvbGxUb0VuZCwgdGVybWluYXRvclJlZl0pO1xuXG4gIGlmIChhdEVuZCB8fCBzdGlja3kpIHtcbiAgICAvLyBJZiBpdCBpcyBzdGlja3kgb3IgYXQgdGhlIGVuZCwgdGhlIHVzZXIgaXMgYXQgdGhlIGJvdHRvbSBvZiB0aGUgdHJhbnNjcmlwdCwgZXZlcnl0aGluZyBpcyByZWFkLlxuICAgIC8vIFNvIG1hcmsgdGhlIGFjdGl2aXR5IElEIGFzIHJlYWQuXG4gICAgbGFzdFJlYWRBY3Rpdml0eUlkUmVmLmN1cnJlbnQgPSBsYXN0VmlzaWJsZUFjdGl2aXR5SWQ7XG4gIH1cblxuICBjb25zdCBTY3JvbGxUb0VuZEJ1dHRvbiA9IHVzZUNyZWF0ZVNjcm9sbFRvRW5kQnV0dG9uUmVuZGVyZXIoKSh7XG4gICAgYXRFbmQ6IGFuaW1hdGluZ1RvRW5kIHx8IGF0RW5kIHx8IHN0aWNreSxcbiAgICBzdHlsZU9wdGlvbnMsXG5cbiAgICAvLyBVbnJlYWQgbWVhbnM6XG4gICAgLy8gMS4gTGFzdCByZWFkIGlzIG5vdCB0aGUgbGFzdCBvbmUgaW4gdGhlIHRyYW5zY3JpcHQsIGFuZDtcbiAgICAvLyAyLiBMYXN0IHJlYWQgaXMgc3RpbGwgaW4gdGhlIHRyYW5zY3JpcHQuXG4gICAgdW5yZWFkOlxuICAgICAgbGFzdFZpc2libGVBY3Rpdml0eUlkICE9PSBsYXN0UmVhZEFjdGl2aXR5SWRSZWYuY3VycmVudCAmJlxuICAgICAgISF+YWN0aXZpdGllcy5maW5kSW5kZXgoYWN0aXZpdHkgPT4gZ2V0QWN0aXZpdHlVbmlxdWVJZChhY3Rpdml0eSkgPT09IGxhc3RSZWFkQWN0aXZpdHlJZFJlZi5jdXJyZW50KVxuICB9KTtcblxuICByZXR1cm4gKFxuICAgIDxSZWFjdC5GcmFnbWVudD5cbiAgICAgIHtTY3JvbGxUb0VuZEJ1dHRvbiAmJiA8U2Nyb2xsVG9FbmRCdXR0b24gb25DbGljaz17aGFuZGxlU2Nyb2xsVG9FbmRCdXR0b25DbGlja30gLz59XG4gICAgICB7ISFSZWFjdC5DaGlsZHJlbi5jb3VudChjaGlsZHJlbikgJiYgKFxuICAgICAgICA8Rm9jdXNSZWRpcmVjdG9yIGNsYXNzTmFtZT1cIndlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX3NlbnRpbmVsXCIgcmVkaXJlY3RSZWY9e3Rlcm1pbmF0b3JSZWZ9IC8+XG4gICAgICApfVxuICAgICAgPFJlYWN0U2Nyb2xsVG9Cb3R0b21QYW5lbCBjbGFzc05hbWU9XCJ3ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0X19zY3JvbGxhYmxlXCI+XG4gICAgICAgIDxkaXYgYXJpYS1oaWRkZW49e3RydWV9IGNsYXNzTmFtZT1cIndlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX2ZpbGxlclwiIG9uRm9jdXM9e29uRm9jdXNGaWxsZXJ9IC8+XG4gICAgICAgIDx1bFxuICAgICAgICAgIGFyaWEtcm9sZWRlc2NyaXB0aW9uPXt0cmFuc2NyaXB0Um9sZURlc2NyaXB0aW9ufVxuICAgICAgICAgIGNsYXNzTmFtZT17Y2xhc3NOYW1lcyhhY3Rpdml0aWVzU3R5bGVTZXQgKyAnJywgJ3dlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX3RyYW5zY3JpcHQnKX1cbiAgICAgICAgICByb2xlPVwibGlzdFwiXG4gICAgICAgID5cbiAgICAgICAgICB7Y2hpbGRyZW59XG4gICAgICAgIDwvdWw+XG4gICAgICAgIDxCYXNpY1R5cGluZ0luZGljYXRvciAvPlxuICAgICAgPC9SZWFjdFNjcm9sbFRvQm90dG9tUGFuZWw+XG4gICAgPC9SZWFjdC5GcmFnbWVudD5cbiAgKTtcbn07XG5cbkludGVybmFsVHJhbnNjcmlwdFNjcm9sbGFibGUucHJvcFR5cGVzID0ge1xuICBhY3Rpdml0aWVzOiBQcm9wVHlwZXMuYXJyYXkuaXNSZXF1aXJlZCxcbiAgY2hpbGRyZW46IFByb3BUeXBlcy5hbnkuaXNSZXF1aXJlZCxcbiAgb25Gb2N1c0FjdGl2aXR5OiBQcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICBvbkZvY3VzRmlsbGVyOiBQcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICB0ZXJtaW5hdG9yUmVmOiBQcm9wVHlwZXMuYW55LmlzUmVxdWlyZWRcbn07XG5cbmNvbnN0IFNldFNjcm9sbGVyID0gKHsgYWN0aXZpdHlFbGVtZW50c1JlZiwgc2Nyb2xsZXJSZWYgfSkgPT4ge1xuICBjb25zdCBbXG4gICAgeyBhdXRvU2Nyb2xsU25hcE9uQWN0aXZpdHksIGF1dG9TY3JvbGxTbmFwT25BY3Rpdml0eU9mZnNldCwgYXV0b1Njcm9sbFNuYXBPblBhZ2UsIGF1dG9TY3JvbGxTbmFwT25QYWdlT2Zmc2V0IH1cbiAgXSA9IHVzZVN0eWxlT3B0aW9ucygpO1xuICBjb25zdCBbYWN0aXZpdGllc10gPSB1c2VBY3Rpdml0aWVzKCk7XG4gIGNvbnN0IFtsYXN0QWNrbm93bGVkZ2VkQWN0aXZpdHldID0gdXNlQWNrbm93bGVkZ2VkQWN0aXZpdHkoKTtcblxuICBjb25zdCBhY3Rpdml0aWVzUmVmID0gdXNlUmVmKGFjdGl2aXRpZXMpO1xuICBjb25zdCBsYXN0QWNrbm93bGVkZ2VkQWN0aXZpdHlSZWYgPSB1c2VSZWYobGFzdEFja25vd2xlZGdlZEFjdGl2aXR5KTtcblxuICBhY3Rpdml0aWVzUmVmLmN1cnJlbnQgPSBhY3Rpdml0aWVzO1xuICBsYXN0QWNrbm93bGVkZ2VkQWN0aXZpdHlSZWYuY3VycmVudCA9IGxhc3RBY2tub3dsZWRnZWRBY3Rpdml0eTtcblxuICBzY3JvbGxlclJlZi5jdXJyZW50ID0gdXNlQ2FsbGJhY2soXG4gICAgKHsgb2Zmc2V0SGVpZ2h0LCBzY3JvbGxUb3AgfSkgPT4ge1xuICAgICAgY29uc3QgcGF0Y2hlZEF1dG9TY3JvbGxTbmFwT25BY3Rpdml0eSA9XG4gICAgICAgIHR5cGVvZiBhdXRvU2Nyb2xsU25hcE9uQWN0aXZpdHkgPT09ICdudW1iZXInXG4gICAgICAgICAgPyBNYXRoLm1heCgwLCBhdXRvU2Nyb2xsU25hcE9uQWN0aXZpdHkpXG4gICAgICAgICAgOiBhdXRvU2Nyb2xsU25hcE9uQWN0aXZpdHlcbiAgICAgICAgICA/IDFcbiAgICAgICAgICA6IDA7XG4gICAgICBjb25zdCBwYXRjaGVkQXV0b1Njcm9sbFNuYXBPblBhZ2UgPVxuICAgICAgICB0eXBlb2YgYXV0b1Njcm9sbFNuYXBPblBhZ2UgPT09ICdudW1iZXInXG4gICAgICAgICAgPyBNYXRoLm1heCgwLCBNYXRoLm1pbigxLCBhdXRvU2Nyb2xsU25hcE9uUGFnZSkpXG4gICAgICAgICAgOiBhdXRvU2Nyb2xsU25hcE9uUGFnZVxuICAgICAgICAgID8gMVxuICAgICAgICAgIDogMDtcbiAgICAgIGNvbnN0IHBhdGNoZWRBdXRvU2Nyb2xsU25hcE9uQWN0aXZpdHlPZmZzZXQgPVxuICAgICAgICB0eXBlb2YgYXV0b1Njcm9sbFNuYXBPbkFjdGl2aXR5T2Zmc2V0ID09PSAnbnVtYmVyJyA/IGF1dG9TY3JvbGxTbmFwT25BY3Rpdml0eU9mZnNldCA6IDA7XG4gICAgICBjb25zdCBwYXRjaGVkQXV0b1Njcm9sbFNuYXBPblBhZ2VPZmZzZXQgPVxuICAgICAgICB0eXBlb2YgYXV0b1Njcm9sbFNuYXBPblBhZ2VPZmZzZXQgPT09ICdudW1iZXInID8gYXV0b1Njcm9sbFNuYXBPblBhZ2VPZmZzZXQgOiAwO1xuXG4gICAgICBpZiAocGF0Y2hlZEF1dG9TY3JvbGxTbmFwT25BY3Rpdml0eSB8fCBwYXRjaGVkQXV0b1Njcm9sbFNuYXBPblBhZ2UpIHtcbiAgICAgICAgY29uc3QgeyBjdXJyZW50OiBhY3Rpdml0aWVzIH0gPSBhY3Rpdml0aWVzUmVmO1xuICAgICAgICBjb25zdCB7IGN1cnJlbnQ6IGFjdGl2aXR5RWxlbWVudHMgfSA9IGFjdGl2aXR5RWxlbWVudHNSZWY7XG4gICAgICAgIGNvbnN0IHsgY3VycmVudDogbGFzdEFja25vd2xlZGdlZEFjdGl2aXR5IH0gPSBsYXN0QWNrbm93bGVkZ2VkQWN0aXZpdHlSZWY7XG4gICAgICAgIGNvbnN0IHZhbHVlcyA9IFtdO1xuXG4gICAgICAgIGNvbnN0IGxhc3RBY2tub3dsZWRnZWRBY3Rpdml0eUluZGV4ID0gYWN0aXZpdGllcy5pbmRleE9mKGxhc3RBY2tub3dsZWRnZWRBY3Rpdml0eSk7XG5cbiAgICAgICAgaWYgKH5sYXN0QWNrbm93bGVkZ2VkQWN0aXZpdHlJbmRleCkge1xuICAgICAgICAgIC8vIFRoZSBhY3Rpdml0eSB0aGF0IHdlIGFja25vd2xlZGdlZCBjb3VsZCBiZSBub3QgcmVuZGVyZWQsIHN1Y2ggYXMgcG9zdCBiYWNrIGFjdGl2aXR5LlxuICAgICAgICAgIC8vIFdoZW4gY2FsY3VsYXRpbmcgc2Nyb2xsIHNuYXAsIHdlIGNhbiBvbmx5IGJhc2Ugb24gdGhlIGZpcnN0IHVuYWNrbm93bGVkZ2VkLWFuZC1yZW5kZXJpbmcgYWN0aXZpdHkuXG4gICAgICAgICAgbGV0IGZpcnN0VW5hY2tub3dsZWRnZWRBY3Rpdml0eUVsZW1lbnRJbmRleCA9IC0xO1xuXG4gICAgICAgICAgZm9yIChsZXQgaW5kZXggPSBsYXN0QWNrbm93bGVkZ2VkQWN0aXZpdHlJbmRleCArIDEsIHsgbGVuZ3RoIH0gPSBhY3Rpdml0aWVzOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgY29uc3QgYWN0aXZpdHkgPSBhY3Rpdml0aWVzW2luZGV4XTtcbiAgICAgICAgICAgIGNvbnN0IGFjdGl2aXR5RWxlbWVudEluZGV4ID0gYWN0aXZpdHlFbGVtZW50cy5maW5kSW5kZXgoZW50cnkgPT4gZW50cnkuYWN0aXZpdHkgPT09IGFjdGl2aXR5KTtcblxuICAgICAgICAgICAgaWYgKH5hY3Rpdml0eUVsZW1lbnRJbmRleCkge1xuICAgICAgICAgICAgICBmaXJzdFVuYWNrbm93bGVkZ2VkQWN0aXZpdHlFbGVtZW50SW5kZXggPSBhY3Rpdml0eUVsZW1lbnRJbmRleDtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKH5maXJzdFVuYWNrbm93bGVkZ2VkQWN0aXZpdHlFbGVtZW50SW5kZXgpIHtcbiAgICAgICAgICAgIGlmIChwYXRjaGVkQXV0b1Njcm9sbFNuYXBPbkFjdGl2aXR5KSB7XG4gICAgICAgICAgICAgIC8vIEdldHMgdGhlIGFjdGl2aXR5IGVsZW1lbnQgd2hpY2ggd2Ugc2hvdWxkIHNuYXAgdG8uXG4gICAgICAgICAgICAgIGNvbnN0IHsgZWxlbWVudDogbnRoVW5hY2tub3dsZWRnZWRBY3Rpdml0eUVsZW1lbnQgfSA9XG4gICAgICAgICAgICAgICAgYWN0aXZpdHlFbGVtZW50c1tmaXJzdFVuYWNrbm93bGVkZ2VkQWN0aXZpdHlFbGVtZW50SW5kZXggKyBwYXRjaGVkQXV0b1Njcm9sbFNuYXBPbkFjdGl2aXR5IC0gMV07XG5cbiAgICAgICAgICAgICAgaWYgKG50aFVuYWNrbm93bGVkZ2VkQWN0aXZpdHlFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgdmFsdWVzLnB1c2goXG4gICAgICAgICAgICAgICAgICBudGhVbmFja25vd2xlZGdlZEFjdGl2aXR5RWxlbWVudC5vZmZzZXRUb3AgK1xuICAgICAgICAgICAgICAgICAgICBudGhVbmFja25vd2xlZGdlZEFjdGl2aXR5RWxlbWVudC5vZmZzZXRIZWlnaHQgLVxuICAgICAgICAgICAgICAgICAgICBvZmZzZXRIZWlnaHQgLVxuICAgICAgICAgICAgICAgICAgICBzY3JvbGxUb3AgK1xuICAgICAgICAgICAgICAgICAgICBwYXRjaGVkQXV0b1Njcm9sbFNuYXBPbkFjdGl2aXR5T2Zmc2V0XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocGF0Y2hlZEF1dG9TY3JvbGxTbmFwT25QYWdlKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHsgZWxlbWVudDogZmlyc3RVbmFja25vd2xlZGdlZEFjdGl2aXR5RWxlbWVudCB9ID1cbiAgICAgICAgICAgICAgICBhY3Rpdml0eUVsZW1lbnRzW2ZpcnN0VW5hY2tub3dsZWRnZWRBY3Rpdml0eUVsZW1lbnRJbmRleF07XG5cbiAgICAgICAgICAgICAgdmFsdWVzLnB1c2goXG4gICAgICAgICAgICAgICAgZmlyc3RVbmFja25vd2xlZGdlZEFjdGl2aXR5RWxlbWVudC5vZmZzZXRUb3AgLVxuICAgICAgICAgICAgICAgICAgc2Nyb2xsVG9wIC1cbiAgICAgICAgICAgICAgICAgIG9mZnNldEhlaWdodCAqICgxIC0gcGF0Y2hlZEF1dG9TY3JvbGxTbmFwT25QYWdlKSArXG4gICAgICAgICAgICAgICAgICBwYXRjaGVkQXV0b1Njcm9sbFNuYXBPblBhZ2VPZmZzZXRcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdmFsdWVzLnJlZHVjZSgobWluVmFsdWUsIHZhbHVlKSA9PiBNYXRoLm1pbihtaW5WYWx1ZSwgdmFsdWUpLCBJbmZpbml0eSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBJbmZpbml0eTtcbiAgICB9LFxuICAgIFtcbiAgICAgIGFjdGl2aXRpZXNSZWYsXG4gICAgICBhY3Rpdml0eUVsZW1lbnRzUmVmLFxuICAgICAgYXV0b1Njcm9sbFNuYXBPbkFjdGl2aXR5LFxuICAgICAgYXV0b1Njcm9sbFNuYXBPbkFjdGl2aXR5T2Zmc2V0LFxuICAgICAgYXV0b1Njcm9sbFNuYXBPblBhZ2UsXG4gICAgICBhdXRvU2Nyb2xsU25hcE9uUGFnZU9mZnNldCxcbiAgICAgIGxhc3RBY2tub3dsZWRnZWRBY3Rpdml0eVJlZlxuICAgIF1cbiAgKTtcblxuICByZXR1cm4gZmFsc2U7XG59O1xuXG5jb25zdCBCYXNpY1RyYW5zY3JpcHQgPSAoeyBjbGFzc05hbWUgfSkgPT4ge1xuICBjb25zdCBhY3Rpdml0eUVsZW1lbnRzUmVmID0gdXNlUmVmKFtdKTtcbiAgY29uc3Qgc2Nyb2xsZXJSZWYgPSB1c2VSZWYoKCkgPT4gSW5maW5pdHkpO1xuXG4gIGNvbnN0IHNjcm9sbGVyID0gdXNlQ2FsbGJhY2soKC4uLmFyZ3MpID0+IHNjcm9sbGVyUmVmLmN1cnJlbnQoLi4uYXJncyksIFtzY3JvbGxlclJlZl0pO1xuXG4gIHJldHVybiAoXG4gICAgPFJlYWN0U2Nyb2xsVG9Cb3R0b21Db21wb3NlciBzY3JvbGxlcj17c2Nyb2xsZXJ9PlxuICAgICAgPFNldFNjcm9sbGVyIGFjdGl2aXR5RWxlbWVudHNSZWY9e2FjdGl2aXR5RWxlbWVudHNSZWZ9IHNjcm9sbGVyUmVmPXtzY3JvbGxlclJlZn0gLz5cbiAgICAgIDxJbnRlcm5hbFRyYW5zY3JpcHQgYWN0aXZpdHlFbGVtZW50c1JlZj17YWN0aXZpdHlFbGVtZW50c1JlZn0gY2xhc3NOYW1lPXtjbGFzc05hbWV9IC8+XG4gICAgPC9SZWFjdFNjcm9sbFRvQm90dG9tQ29tcG9zZXI+XG4gICk7XG59O1xuXG5CYXNpY1RyYW5zY3JpcHQuZGVmYXVsdFByb3BzID0ge1xuICBjbGFzc05hbWU6ICcnXG59O1xuXG5CYXNpY1RyYW5zY3JpcHQucHJvcFR5cGVzID0ge1xuICBjbGFzc05hbWU6IFByb3BUeXBlcy5zdHJpbmdcbn07XG5cbmV4cG9ydCBkZWZhdWx0IEJhc2ljVHJhbnNjcmlwdDtcbiJdfQ==
839
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9CYXNpY1RyYW5zY3JpcHQudHN4Il0sIm5hbWVzIjpbInVzZUFjdGl2aXR5S2V5cyIsImhvb2tzIiwidXNlQWN0aXZpdHlLZXlzQnlSZWFkIiwidXNlQ3JlYXRlQWN0aXZpdHlTdGF0dXNSZW5kZXJlciIsInVzZUNyZWF0ZUF2YXRhclJlbmRlcmVyIiwidXNlQ3JlYXRlU2Nyb2xsVG9FbmRCdXR0b25SZW5kZXJlciIsInVzZURpcmVjdGlvbiIsInVzZUdldEFjdGl2aXR5QnlLZXkiLCJ1c2VHZXRLZXlCeUFjdGl2aXR5IiwidXNlR2V0S2V5QnlBY3Rpdml0eUlkIiwidXNlTGFzdEFja25vd2xlZGdlZEFjdGl2aXR5S2V5IiwidXNlTG9jYWxpemVyIiwidXNlTWFya0FjdGl2aXR5S2V5QXNSZWFkIiwidXNlTWFya0FsbEFzQWNrbm93bGVkZ2VkIiwidXNlU3R5bGVPcHRpb25zIiwiUk9PVF9TVFlMRSIsImRpc3BsYXkiLCJmbGV4RGlyZWN0aW9uIiwib3ZlcmZsb3ciLCJwb3NpdGlvbiIsImZsZXgiLCJvdmVyZmxvd1giLCJXZWJraXRPdmVyZmxvd1Njcm9sbGluZyIsImxpc3RTdHlsZVR5cGUiLCJJbnRlcm5hbFRyYW5zY3JpcHQiLCJyZWYiLCJhY3Rpdml0eUVsZW1lbnRNYXBSZWYiLCJjbGFzc05hbWUiLCJiYXNpY1RyYW5zY3JpcHRTdHlsZVNldCIsImJhc2ljVHJhbnNjcmlwdCIsImJ1YmJsZUZyb21Vc2VyTnViT2Zmc2V0IiwiYnViYmxlTnViT2Zmc2V0IiwiZ3JvdXBUaW1lc3RhbXAiLCJzaG93QXZhdGFySW5Hcm91cCIsImFjdGl2ZURlc2NlbmRhbnRJZCIsImFjdGl2aXR5V2l0aFJlbmRlcmVyVHJlZSIsImRpcmVjdGlvbiIsImZvY3VzZWRBY3Rpdml0eUtleSIsImZvY3VzZWRFeHBsaWNpdGx5IiwiY3JlYXRlQWN0aXZpdHlTdGF0dXNSZW5kZXJlciIsImNyZWF0ZUF2YXRhclJlbmRlcmVyIiwiZm9jdXMiLCJmb2N1c0J5QWN0aXZpdHlLZXkiLCJmb2N1c1JlbGF0aXZlQWN0aXZpdHkiLCJnZXRBY3Rpdml0eUJ5S2V5IiwiZ2V0S2V5QnlBY3Rpdml0eSIsImdldEtleUJ5QWN0aXZpdHlJZCIsImxvY2FsaXplIiwicm9vdENsYXNzTmFtZSIsInJvb3RFbGVtZW50UmVmIiwidGVybWluYXRvckxhYmVsSWQiLCJ0ZXJtaW5hdG9yUmVmIiwiZm9jdXNlZEFjdGl2aXR5S2V5UmVmIiwiaGlkZUFsbFRpbWVzdGFtcHMiLCJ0ZXJtaW5hdG9yVGV4dCIsInRyYW5zY3JpcHRBcmlhTGFiZWwiLCJjYWxsYmFja1JlZiIsImVsZW1lbnQiLCJjdXJyZW50IiwicmVuZGVyaW5nRWxlbWVudHMiLCJ0b3BTaWRlQm90TnViIiwidG9wU2lkZVVzZXJOdWIiLCJmb3JFYWNoIiwiZW50cmllc1dpdGhTYW1lU2VuZGVyIiwiZmlyc3RBY3Rpdml0eSIsImFjdGl2aXR5IiwicmVuZGVyQXZhdGFyIiwiZW50cmllc1dpdGhTYW1lU2VuZGVyQW5kU3RhdHVzIiwiaW5kZXhXaXRoaW5TZW5kZXJHcm91cCIsImZpcnN0SW5TZW5kZXJHcm91cCIsImxhc3RJblNlbmRlckdyb3VwIiwibGVuZ3RoIiwiaW5kZXhXaXRoaW5TZW5kZXJBbmRTdGF0dXNHcm91cCIsInJlbmRlckFjdGl2aXR5IiwiZmlyc3RJblNlbmRlckFuZFN0YXR1c0dyb3VwIiwia2V5IiwibGFzdEluU2VuZGVyQW5kU3RhdHVzR3JvdXAiLCJyZW5kZXJBY3Rpdml0eVN0YXR1cyIsIm5leHRWaXNpYmxlQWN0aXZpdHkiLCJ1bmRlZmluZWQiLCJ0b3BTaWRlTnViIiwiZnJvbSIsInJvbGUiLCJzaG93Q2FsbG91dCIsInB1c2giLCJhY3Rpdml0eUVsZW1lbnQiLCJzZXQiLCJkZWxldGUiLCJoaWRlVGltZXN0YW1wIiwic2Nyb2xsVG9Cb3R0b21TY3JvbGxUbyIsInNjcm9sbFRvQm90dG9tU2Nyb2xsVG9FbmQiLCJzY3JvbGxUbyIsImJlaGF2aW9yIiwiRXJyb3IiLCJhY3Rpdml0eUlkIiwiYWN0aXZpdHlJRCIsInNjcm9sbFRvcCIsImFjdGl2aXR5Qm91bmRpbmdCb3hFbGVtZW50IiwiZ2V0IiwicXVlcnlTZWxlY3RvciIsInNjcm9sbGFibGVFbGVtZW50IiwiZ2V0Q2xpZW50UmVjdHMiLCJhY3Rpdml0eUhlaWdodCIsImhlaWdodCIsImFjdGl2aXR5WSIsInkiLCJzY3JvbGxhYmxlSGVpZ2h0IiwiYWN0aXZpdHlPZmZzZXRUb3AiLCJNYXRoIiwibWluIiwic2Nyb2xsVG9FbmQiLCJzY3JvbGxSZWxhdGl2ZSIsImRpc3BsYWNlbWVudCIsInJvb3RFbGVtZW50Iiwic2Nyb2xsYWJsZSIsIm5leHRTY3JvbGxUb3AiLCJvZmZzZXRIZWlnaHQiLCJtYXgiLCJzY3JvbGxIZWlnaHQiLCJtYXJrQWN0aXZpdHlLZXlBc1JlYWQiLCJkaXNwYXRjaFNjcm9sbFBvc2l0aW9uV2l0aEFjdGl2aXR5SWQiLCJoYW5kbGVTY3JvbGxQb3NpdGlvbiIsInNjcm9sbGFibGVDbGllbnRCb3R0b20iLCJib3R0b20iLCJhY3Rpdml0eUVsZW1lbnRzIiwiQXJyYXkiLCJlbnRyaWVzIiwiYWN0aXZpdHlLZXlKdXN0QWJvdmVTY3JvbGxCb3R0b20iLCJyZXZlcnNlIiwiZmluZCIsImlkIiwiaGFuZGxlVHJhbnNjcmlwdEtleURvd24iLCJldmVudCIsInRhcmdldCIsImZyb21FbmRPZlRyYW5zY3JpcHRJbmRpY2F0b3IiLCJmcm9tVHJhbnNjcmlwdCIsImN1cnJlbnRUYXJnZXQiLCJoYW5kbGVkIiwiSW5maW5pdHkiLCJib2R5IiwicHJldmVudERlZmF1bHQiLCJzdG9wUHJvcGFnYXRpb24iLCJoYW5kbGVUcmFuc2NyaXB0S2V5RG93bkNhcHR1cmUiLCJhbHRLZXkiLCJjdHJsS2V5IiwibWV0YUtleSIsImRpc3BhdGNoVHJhbnNjcmlwdEZvY3VzQnlBY3Rpdml0eUtleSIsImhhbmRsZUZvY3VzIiwiaGFuZGxlRm9jdXNGaWxsZXIiLCJhbmRyb2lkIiwibWFwIiwiZGVmYXVsdFByb3BzIiwicHJvcFR5cGVzIiwiUHJvcFR5cGVzIiwic2hhcGUiLCJpbnN0YW5jZU9mIiwiTWFwIiwiaXNSZXF1aXJlZCIsInN0cmluZyIsIkludGVybmFsVHJhbnNjcmlwdFNjcm9sbGFibGUiLCJjaGlsZHJlbiIsIm9uRm9jdXNGaWxsZXIiLCJhY3Rpdml0aWVzU3R5bGVTZXQiLCJhY3Rpdml0aWVzIiwiYW5pbWF0aW5nVG9FbmQiLCJhdEVuZCIsInVucmVhZEFjdGl2aXR5S2V5cyIsInN0aWNreSIsInN0eWxlT3B0aW9ucyIsIm1hcmtBbGxBc0Fja25vd2xlZGdlZCIsInByZXZTdGlja3kiLCJ0cmFuc2NyaXB0Um9sZURlc2NyaXB0aW9uIiwic3RpY2t5Q2hhbmdlZFRvVHJ1ZSIsImZsYXQiLCJmbGF0dGVuZWRBY3Rpdml0eVRyZWVXaXRoUmVuZGVyZXIiLCJyZW5kZXJpbmdBY3Rpdml0eUtleXMiLCJyZW5kZXJpbmdBY3Rpdml0eUtleXNSZWYiLCJuZXh0VW5yZWFkQWN0aXZpdHlLZXlzIiwibmV4dFVucmVhZEFjdGl2aXR5S2V5c1JlZiIsInVucmVhZCIsInNvbWUiLCJpbmNsdWRlcyIsImhhbmRsZVNjcm9sbFRvRW5kQnV0dG9uQ2xpY2siLCJmaXJzdFVucmVhZFJlbmRlcmluZ0FjdGl2aXR5S2V5IiwicmVuZGVyU2Nyb2xsVG9FbmRCdXR0b24iLCJvbkNsaWNrIiwiUmVhY3QiLCJDaGlsZHJlbiIsImNvdW50IiwiYW55IiwiZnVuYyIsInVzZVNjcm9sbGVyIiwiYWN0aXZpdHlLZXlzIiwibGFzdEFja25vd2xlZGdlZEFjdGl2aXR5S2V5IiwiYWN0aXZpdHlLZXlzUmVmIiwibGFzdEFja25vd2xlZGdlZEFjdGl2aXR5S2V5UmVmIiwic3R5bGVPcHRpb25zUmVmIiwiYXV0b1Njcm9sbFNuYXBPbkFjdGl2aXR5IiwiYXV0b1Njcm9sbFNuYXBPbkFjdGl2aXR5T2Zmc2V0IiwiYXV0b1Njcm9sbFNuYXBPblBhZ2UiLCJhdXRvU2Nyb2xsU25hcE9uUGFnZU9mZnNldCIsInBhdGNoZWRBdXRvU2Nyb2xsU25hcE9uQWN0aXZpdHkiLCJwYXRjaGVkQXV0b1Njcm9sbFNuYXBPblBhZ2UiLCJwYXRjaGVkQXV0b1Njcm9sbFNuYXBPbkFjdGl2aXR5T2Zmc2V0IiwicGF0Y2hlZEF1dG9TY3JvbGxTbmFwT25QYWdlT2Zmc2V0IiwiYWN0aXZpdHlFbGVtZW50TWFwIiwidmFsdWVzIiwibGFzdEFja25vd2xlZGdlZEFjdGl2aXR5S2V5SW5kZXgiLCJpbmRleE9mIiwia2V5cyIsImZpcnN0VW5hY2tub3dsZWRnZWRBY3Rpdml0eUVsZW1lbnRJbmRleCIsInNsaWNlIiwiYWNrbm93bGVkZ2VkQWN0aXZpdHlLZXkiLCJpbmRleCIsIm50aFVuYWNrbm93bGVkZ2VkQWN0aXZpdHlFbGVtZW50IiwibnRoVW5hY2tub3dsZWRnZWRBY3Rpdml0eUJvdW5kaW5nQm94RWxlbWVudCIsIm50aFVuYWNrbm93bGVkZ2VkQWN0aXZpdHlPZmZzZXRUb3AiLCJvZmZzZXRUb3AiLCJmaXJzdFVuYWNrbm93bGVkZ2VkQWN0aXZpdHlFbGVtZW50IiwiZmlyc3RVbmFja25vd2xlZGdlZEFjdGl2aXR5Qm91bmRpbmdCb3hFbGVtZW50IiwiZmlyc3RVbmFja25vd2xlZGdlZEFjdGl2aXR5T2Zmc2V0VG9wIiwiQmFzaWNUcmFuc2NyaXB0IiwiY29udGFpbmVyUmVmIiwic2Nyb2xsZXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBOztBQUNBOztBQVVBOztBQUNBOztBQUNBOztBQU9BOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUVBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUEsSUFDRUEsZUFERixHQWVJQyw2QkFmSixDQUNFRCxlQURGO0FBQUEsSUFFRUUscUJBRkYsR0FlSUQsNkJBZkosQ0FFRUMscUJBRkY7QUFBQSxJQUdFQywrQkFI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RUFBRUMsU0FBN0U7QUFBd0YsSUFBQSxHQUFHLEVBQUVtTTtBQUE3RixJQUZGLENBREYsQ0FERjtBQVFELENBZEQ7O0FBZ0JBRCxlQUFlLENBQUN0RSxZQUFoQixHQUErQjtBQUM3QjVILEVBQUFBLFNBQVMsRUFBRTtBQURrQixDQUEvQjtBQUlBa00sZUFBZSxDQUFDckUsU0FBaEIsR0FBNEI7QUFDMUI3SCxFQUFBQSxTQUFTLEVBQUU4SCxtQkFBVUs7QUFESyxDQUE1QjtlQUllK0QsZSIsInNvdXJjZVJvb3QiOiJjb21wb25lbnQ6Ly8vIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaG9va3MgfSBmcm9tICdib3RmcmFtZXdvcmstd2ViY2hhdC1hcGknO1xuaW1wb3J0IHtcbiAgQ29tcG9zZXIgYXMgUmVhY3RTY3JvbGxUb0JvdHRvbUNvbXBvc2VyLFxuICBQYW5lbCBhcyBSZWFjdFNjcm9sbFRvQm90dG9tUGFuZWwsXG4gIHVzZUFuaW1hdGluZ1RvRW5kLFxuICB1c2VBdEVuZCxcbiAgdXNlT2JzZXJ2ZVNjcm9sbFBvc2l0aW9uLFxuICB1c2VTY3JvbGxUbyxcbiAgdXNlU2Nyb2xsVG9FbmQsXG4gIHVzZVN0aWNreVxufSBmcm9tICdyZWFjdC1zY3JvbGwtdG8tYm90dG9tJztcbmltcG9ydCBjbGFzc05hbWVzIGZyb20gJ2NsYXNzbmFtZXMnO1xuaW1wb3J0IFByb3BUeXBlcyBmcm9tICdwcm9wLXR5cGVzJztcbmltcG9ydCBSZWFjdCwgeyBmb3J3YXJkUmVmLCBGcmFnbWVudCwgdXNlQ2FsbGJhY2ssIHVzZU1lbW8sIHVzZVJlZiB9IGZyb20gJ3JlYWN0JztcblxuaW1wb3J0IHR5cGUgeyBBY3Rpdml0eUNvbXBvbmVudEZhY3RvcnksIEF2YXRhckNvbXBvbmVudEZhY3RvcnkgfSBmcm9tICdib3RmcmFtZXdvcmstd2ViY2hhdC1hcGknO1xuaW1wb3J0IHR5cGUgeyBBY3Rpdml0eUVsZW1lbnRNYXAgfSBmcm9tICcuL1RyYW5zY3JpcHQvdHlwZXMnO1xuaW1wb3J0IHR5cGUgeyBEaXJlY3RMaW5lQWN0aXZpdHkgfSBmcm9tICdib3RmcmFtZXdvcmstd2ViY2hhdC1jb3JlJztcbmltcG9ydCB0eXBlIHsgRkMsIEtleWJvYXJkRXZlbnRIYW5kbGVyLCBNdXRhYmxlUmVmT2JqZWN0LCBSZWFjdE5vZGUsIFZGQyB9IGZyb20gJ3JlYWN0JztcblxuaW1wb3J0IHsgYW5kcm9pZCB9IGZyb20gJy4vVXRpbHMvZGV0ZWN0QnJvd3Nlcic7XG5pbXBvcnQgQWN0aXZpdHlSb3cgZnJvbSAnLi9UcmFuc2NyaXB0L0FjdGl2aXR5Um93JztcbmltcG9ydCBCYXNpY1R5cGluZ0luZGljYXRvciBmcm9tICcuL0Jhc2ljVHlwaW5nSW5kaWNhdG9yJztcbmltcG9ydCBGb2N1c1JlZGlyZWN0b3IgZnJvbSAnLi9VdGlscy9Gb2N1c1JlZGlyZWN0b3InO1xuaW1wb3J0IGlucHV0dGFibGVLZXkgZnJvbSAnLi9VdGlscy9UeXBlRm9jdXNTaW5rL2lucHV0dGFibGVLZXknO1xuaW1wb3J0IGlzWmVyb09yUG9zaXRpdmUgZnJvbSAnLi9VdGlscy9pc1plcm9PclBvc2l0aXZlJztcbmltcG9ydCBLZXlib2FyZEhlbHAgZnJvbSAnLi9UcmFuc2NyaXB0L0tleWJvYXJkSGVscCc7XG5pbXBvcnQgTGl2ZVJlZ2lvblRyYW5zY3JpcHQgZnJvbSAnLi9UcmFuc2NyaXB0L0xpdmVSZWdpb25UcmFuc2NyaXB0Jztcbi8vIFRPRE86IFtQMl0gIzQxMzMgUmVuYW1lIHRvIFwiZ2V0VGFiYmFibGVFbGVtZW50c1wiLlxuaW1wb3J0IHRhYmJhYmxlRWxlbWVudHMgZnJvbSAnLi9VdGlscy90YWJiYWJsZUVsZW1lbnRzJztcbmltcG9ydCBUcmFuc2NyaXB0Rm9jdXNDb21wb3NlciBmcm9tICcuL3Byb3ZpZGVycy9UcmFuc2NyaXB0Rm9jdXMvVHJhbnNjcmlwdEZvY3VzQ29tcG9zZXInO1xuaW1wb3J0IHVzZUFjdGl2ZURlc2NlbmRhbnRJZCBmcm9tICcuL3Byb3ZpZGVycy9UcmFuc2NyaXB0Rm9jdXMvdXNlQWN0aXZlRGVzY2VuZGFudElkJztcbmltcG9ydCB1c2VBY3Rpdml0eVRyZWVXaXRoUmVuZGVyZXIgZnJvbSAnLi9wcm92aWRlcnMvQWN0aXZpdHlUcmVlL3VzZUFjdGl2aXR5VHJlZVdpdGhSZW5kZXJlcic7XG5pbXBvcnQgdXNlRGlzcGF0Y2hTY3JvbGxQb3NpdGlvbiBmcm9tICcuL2hvb2tzL2ludGVybmFsL3VzZURpc3BhdGNoU2Nyb2xsUG9zaXRpb24nO1xuaW1wb3J0IHVzZURpc3BhdGNoVHJhbnNjcmlwdEZvY3VzQnlBY3Rpdml0eUtleSBmcm9tICcuL2hvb2tzL2ludGVybmFsL3VzZURpc3BhdGNoVHJhbnNjcmlwdEZvY3VzQnlBY3Rpdml0eUtleSc7XG5pbXBvcnQgdXNlRm9jdXMgZnJvbSAnLi9ob29rcy91c2VGb2N1cyc7XG5pbXBvcnQgdXNlRm9jdXNCeUFjdGl2aXR5S2V5IGZyb20gJy4vcHJvdmlkZXJzL1RyYW5zY3JpcHRGb2N1cy91c2VGb2N1c0J5QWN0aXZpdHlLZXknO1xuaW1wb3J0IHVzZUZvY3VzZWRBY3Rpdml0eUtleSBmcm9tICcuL3Byb3ZpZGVycy9UcmFuc2NyaXB0Rm9jdXMvdXNlRm9jdXNlZEFjdGl2aXR5S2V5JztcbmltcG9ydCB1c2VGb2N1c2VkRXhwbGljaXRseSBmcm9tICcuL3Byb3ZpZGVycy9UcmFuc2NyaXB0Rm9jdXMvdXNlRm9jdXNlZEV4cGxpY2l0bHknO1xuaW1wb3J0IHVzZUZvY3VzUmVsYXRpdmVBY3Rpdml0eSBmcm9tICcuL3Byb3ZpZGVycy9UcmFuc2NyaXB0Rm9jdXMvdXNlRm9jdXNSZWxhdGl2ZUFjdGl2aXR5JztcbmltcG9ydCB1c2VPYnNlcnZlRm9jdXNWaXNpYmxlIGZyb20gJy4vaG9va3MvaW50ZXJuYWwvdXNlT2JzZXJ2ZUZvY3VzVmlzaWJsZSc7XG5pbXBvcnQgdXNlUHJldmlvdXMgZnJvbSAnLi9ob29rcy9pbnRlcm5hbC91c2VQcmV2aW91cyc7XG5pbXBvcnQgdXNlUmVnaXN0ZXJGb2N1c1RyYW5zY3JpcHQgZnJvbSAnLi9ob29rcy9pbnRlcm5hbC91c2VSZWdpc3RlckZvY3VzVHJhbnNjcmlwdCc7XG5pbXBvcnQgdXNlUmVnaXN0ZXJTY3JvbGxSZWxhdGl2ZSBmcm9tICcuL2hvb2tzL2ludGVybmFsL3VzZVJlZ2lzdGVyU2Nyb2xsUmVsYXRpdmUnO1xuaW1wb3J0IHVzZVJlZ2lzdGVyU2Nyb2xsVG8gZnJvbSAnLi9ob29rcy9pbnRlcm5hbC91c2VSZWdpc3RlclNjcm9sbFRvJztcbmltcG9ydCB1c2VSZWdpc3RlclNjcm9sbFRvRW5kIGZyb20gJy4vaG9va3MvaW50ZXJuYWwvdXNlUmVnaXN0ZXJTY3JvbGxUb0VuZCc7XG5pbXBvcnQgdXNlU3R5bGVTZXQgZnJvbSAnLi9ob29rcy91c2VTdHlsZVNldCc7XG5pbXBvcnQgdXNlU3R5bGVUb0Vtb3Rpb25PYmplY3QgZnJvbSAnLi9ob29rcy9pbnRlcm5hbC91c2VTdHlsZVRvRW1vdGlvbk9iamVjdCc7XG5pbXBvcnQgdXNlVW5pcXVlSWQgZnJvbSAnLi9ob29rcy9pbnRlcm5hbC91c2VVbmlxdWVJZCc7XG5pbXBvcnQgdXNlVmFsdWVSZWYgZnJvbSAnLi9ob29rcy9pbnRlcm5hbC91c2VWYWx1ZVJlZic7XG5cbmNvbnN0IHtcbiAgdXNlQWN0aXZpdHlLZXlzLFxuICB1c2VBY3Rpdml0eUtleXNCeVJlYWQsXG4gIHVzZUNyZWF0ZUFjdGl2aXR5U3RhdHVzUmVuZGVyZXIsXG4gIHVzZUNyZWF0ZUF2YXRhclJlbmRlcmVyLFxuICB1c2VDcmVhdGVTY3JvbGxUb0VuZEJ1dHRvblJlbmRlcmVyLFxuICB1c2VEaXJlY3Rpb24sXG4gIHVzZUdldEFjdGl2aXR5QnlLZXksXG4gIHVzZUdldEtleUJ5QWN0aXZpdHksXG4gIHVzZUdldEtleUJ5QWN0aXZpdHlJZCxcbiAgdXNlTGFzdEFja25vd2xlZGdlZEFjdGl2aXR5S2V5LFxuICB1c2VMb2NhbGl6ZXIsXG4gIHVzZU1hcmtBY3Rpdml0eUtleUFzUmVhZCxcbiAgdXNlTWFya0FsbEFzQWNrbm93bGVkZ2VkLFxuICB1c2VTdHlsZU9wdGlvbnNcbn0gPSBob29rcztcblxuY29uc3QgUk9PVF9TVFlMRSA9IHtcbiAgJyYud2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdCc6IHtcbiAgICBkaXNwbGF5OiAnZmxleCcsXG4gICAgZmxleERpcmVjdGlvbjogJ2NvbHVtbicsXG4gICAgb3ZlcmZsb3c6ICdoaWRkZW4nLFxuICAgIC8vIE1ha2Ugc3VyZSB0byBzZXQgXCJwb3NpdGlvbjogcmVsYXRpdmVcIiBoZXJlIHRvIGZvcm0gYW5vdGhlciBzdGFja2luZyBjb250ZXh0IGZvciB0aGUgc2Nyb2xsLXRvLWVuZCBidXR0b24uXG4gICAgLy8gU3RhY2tpbmcgY29udGV4dCBoZWxwIGlzb2xhdGluZyBlbGVtZW50cyB0aGF0IHVzZSBcInotaW5kZXhcIiBmcm9tIGdsb2JhbCBwb2xsdXRpb24uXG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL0NTU19Qb3NpdGlvbmluZy9VbmRlcnN0YW5kaW5nX3pfaW5kZXgvVGhlX3N0YWNraW5nX2NvbnRleHRcbiAgICBwb3NpdGlvbjogJ3JlbGF0aXZlJyxcblxuICAgICcmIC53ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0X19maWxsZXInOiB7XG4gICAgICBmbGV4OiAxXG4gICAgfSxcblxuICAgICcmIC53ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0X19zY3JvbGxhYmxlJzoge1xuICAgICAgZGlzcGxheTogJ2ZsZXgnLFxuICAgICAgZmxleERpcmVjdGlvbjogJ2NvbHVtbicsXG4gICAgICBvdmVyZmxvd1g6ICdoaWRkZW4nLFxuICAgICAgV2Via2l0T3ZlcmZsb3dTY3JvbGxpbmc6ICd0b3VjaCdcbiAgICB9LFxuXG4gICAgJyYgLndlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX3RyYW5zY3JpcHQnOiB7XG4gICAgICBsaXN0U3R5bGVUeXBlOiAnbm9uZSdcbiAgICB9XG4gIH1cbn07XG5cbnR5cGUgUmVuZGVyaW5nRWxlbWVudCA9IHtcbiAgYWN0aXZpdHk6IERpcmVjdExpbmVBY3Rpdml0eSAmIHtcbiAgICBjaGFubmVsRGF0YT86IHtcbiAgICAgIFsnd2ViY2hhdDpmYWxsYmFjay10ZXh0J106IHN0cmluZztcbiAgICB9O1xuICB9O1xuICBjYWxsYmFja1JlZjogKGVsZW1lbnQ6IEhUTUxFbGVtZW50KSA9PiB2b2lkO1xuICBoaWRlVGltZXN0YW1wOiBib29sZWFuO1xuICBrZXk6IHN0cmluZztcbiAgcmVuZGVyQWN0aXZpdHk6IEV4Y2x1ZGU8UmV0dXJuVHlwZTxBY3Rpdml0eUNvbXBvbmVudEZhY3Rvcnk+LCBmYWxzZT47XG4gIHJlbmRlckFjdGl2aXR5U3RhdHVzOiAocHJvcHM6IHsgaGlkZVRpbWVzdGFtcD86IGJvb2xlYW4gfSkgPT4gUmVhY3ROb2RlO1xuICByZW5kZXJBdmF0YXI6IEF2YXRhckNvbXBvbmVudEZhY3Rvcnk7XG4gIHNob3dDYWxsb3V0OiBib29sZWFuO1xufTtcblxudHlwZSBTY3JvbGxCZWhhdmlvciA9ICdhdXRvJyB8ICdzbW9vdGgnO1xudHlwZSBTY3JvbGxUb09wdGlvbnMgPSB7IGJlaGF2aW9yPzogU2Nyb2xsQmVoYXZpb3IgfTtcbnR5cGUgU2Nyb2xsVG9Qb3NpdGlvbiA9IHsgYWN0aXZpdHlJRD86IHN0cmluZzsgc2Nyb2xsVG9wPzogbnVtYmVyIH07XG5cbnR5cGUgSW50ZXJuYWxUcmFuc2NyaXB0UHJvcHMgPSB7XG4gIGFjdGl2aXR5RWxlbWVudE1hcFJlZjogTXV0YWJsZVJlZk9iamVjdDxBY3Rpdml0eUVsZW1lbnRNYXA+O1xuICBjbGFzc05hbWU/OiBzdHJpbmc7XG59O1xuXG4vLyBUT0RPOiBbUDFdICM0MTMzIEFkZCB0ZWxlbWV0cnkgZm9yIGNvbXB1dGluZyBob3cgbWFueSByZS1yZW5kZXIgZG9uZSBzbyBmYXIuXG5jb25zdCBJbnRlcm5hbFRyYW5zY3JpcHQgPSBmb3J3YXJkUmVmPEhUTUxEaXZFbGVtZW50LCBJbnRlcm5hbFRyYW5zY3JpcHRQcm9wcz4oXG4gICh7IGFjdGl2aXR5RWxlbWVudE1hcFJlZiwgY2xhc3NOYW1lIH0sIHJlZikgPT4ge1xuICAgIGNvbnN0IFt7IGJhc2ljVHJhbnNjcmlwdDogYmFzaWNUcmFuc2NyaXB0U3R5bGVTZXQgfV0gPSB1c2VTdHlsZVNldCgpO1xuICAgIGNvbnN0IFt7IGJ1YmJsZUZyb21Vc2VyTnViT2Zmc2V0LCBidWJibGVOdWJPZmZzZXQsIGdyb3VwVGltZXN0YW1wLCBzaG93QXZhdGFySW5Hcm91cCB9XSA9IHVzZVN0eWxlT3B0aW9ucygpO1xuICAgIGNvbnN0IFthY3RpdmVEZXNjZW5kYW50SWRdID0gdXNlQWN0aXZlRGVzY2VuZGFudElkKCk7XG4gICAgY29uc3QgW2FjdGl2aXR5V2l0aFJlbmRlcmVyVHJlZV0gPSB1c2VBY3Rpdml0eVRyZWVXaXRoUmVuZGVyZXIoKTtcbiAgICBjb25zdCBbZGlyZWN0aW9uXSA9IHVzZURpcmVjdGlvbigpO1xuICAgIGNvbnN0IFtmb2N1c2VkQWN0aXZpdHlLZXldID0gdXNlRm9jdXNlZEFjdGl2aXR5S2V5KCk7XG4gICAgY29uc3QgW2ZvY3VzZWRFeHBsaWNpdGx5XSA9IHVzZUZvY3VzZWRFeHBsaWNpdGx5KCk7XG4gICAgY29uc3QgY3JlYXRlQWN0aXZpdHlTdGF0dXNSZW5kZXJlciA9IHVzZUNyZWF0ZUFjdGl2aXR5U3RhdHVzUmVuZGVyZXIoKTtcbiAgICBjb25zdCBjcmVhdGVBdmF0YXJSZW5kZXJlciA9IHVzZUNyZWF0ZUF2YXRhclJlbmRlcmVyKCk7XG4gICAgY29uc3QgZm9jdXMgPSB1c2VGb2N1cygpO1xuICAgIGNvbnN0IGZvY3VzQnlBY3Rpdml0eUtleSA9IHVzZUZvY3VzQnlBY3Rpdml0eUtleSgpO1xuICAgIGNvbnN0IGZvY3VzUmVsYXRpdmVBY3Rpdml0eSA9IHVzZUZvY3VzUmVsYXRpdmVBY3Rpdml0eSgpO1xuICAgIGNvbnN0IGdldEFjdGl2aXR5QnlLZXkgPSB1c2VHZXRBY3Rpdml0eUJ5S2V5KCk7XG4gICAgY29uc3QgZ2V0S2V5QnlBY3Rpdml0eSA9IHVzZUdldEtleUJ5QWN0aXZpdHkoKTtcbiAgICBjb25zdCBnZXRLZXlCeUFjdGl2aXR5SWQgPSB1c2VHZXRLZXlCeUFjdGl2aXR5SWQoKTtcbiAgICBjb25zdCBsb2NhbGl6ZSA9IHVzZUxvY2FsaXplcigpO1xuICAgIGNvbnN0IHJvb3RDbGFzc05hbWUgPSB1c2VTdHlsZVRvRW1vdGlvbk9iamVjdCgpKFJPT1RfU1RZTEUpICsgJyc7XG4gICAgY29uc3Qgcm9vdEVsZW1lbnRSZWYgPSB1c2VSZWY8SFRNTERpdkVsZW1lbnQ+KCk7XG4gICAgY29uc3QgdGVybWluYXRvckxhYmVsSWQgPSB1c2VVbmlxdWVJZCgnd2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fdGVybWluYXRvci1sYWJlbCcpO1xuICAgIGNvbnN0IHRlcm1pbmF0b3JSZWYgPSB1c2VSZWY8SFRNTERpdkVsZW1lbnQ+KCk7XG5cbiAgICBjb25zdCBmb2N1c2VkQWN0aXZpdHlLZXlSZWYgPSB1c2VWYWx1ZVJlZihmb2N1c2VkQWN0aXZpdHlLZXkpO1xuICAgIGNvbnN0IGhpZGVBbGxUaW1lc3RhbXBzID0gZ3JvdXBUaW1lc3RhbXAgPT09IGZhbHNlO1xuICAgIGNvbnN0IHRlcm1pbmF0b3JUZXh0ID0gbG9jYWxpemUoJ1RSQU5TQ1JJUFRfVEVSTUlOQVRPUl9URVhUJyk7XG4gICAgY29uc3QgdHJhbnNjcmlwdEFyaWFMYWJlbCA9IGxvY2FsaXplKCdUUkFOU0NSSVBUX0FSSUFfTEFCRUxfQUxUJyk7XG5cbiAgICBjb25zdCBjYWxsYmFja1JlZiA9IHVzZUNhbGxiYWNrKFxuICAgICAgKGVsZW1lbnQ6IEhUTUxEaXZFbGVtZW50KSA9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgcmVmID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgcmVmKGVsZW1lbnQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlZi5jdXJyZW50ID0gZWxlbWVudDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJvb3RFbGVtZW50UmVmLmN1cnJlbnQgPSBlbGVtZW50O1xuICAgICAgfSxcbiAgICAgIFtyZWYsIHJvb3RFbGVtZW50UmVmXVxuICAgICk7XG5cbiAgICAvLyBGbGF0dGVuIHRoZSB0cmVlIGJhY2sgaW50byBhbiBhcnJheSB3aXRoIGluZm9ybWF0aW9uIHJlbGF0ZWQgdG8gcmVuZGVyaW5nLlxuICAgIGNvbnN0IHJlbmRlcmluZ0VsZW1lbnRzID0gdXNlTWVtbygoKSA9PiB7XG4gICAgICBjb25zdCByZW5kZXJpbmdFbGVtZW50czogUmVuZGVyaW5nRWxlbWVudFtdID0gW107XG4gICAgICBjb25zdCB0b3BTaWRlQm90TnViID0gaXNaZXJvT3JQb3NpdGl2ZShidWJibGVOdWJPZmZzZXQpO1xuICAgICAgY29uc3QgdG9wU2lkZVVzZXJOdWIgPSBpc1plcm9PclBvc2l0aXZlKGJ1YmJsZUZyb21Vc2VyTnViT2Zmc2V0KTtcblxuICAgICAgYWN0aXZpdHlXaXRoUmVuZGVyZXJUcmVlLmZvckVhY2goZW50cmllc1dpdGhTYW1lU2VuZGVyID0+IHtcbiAgICAgICAgY29uc3QgW1t7IGFjdGl2aXR5OiBmaXJzdEFjdGl2aXR5IH1dXSA9IGVudHJpZXNXaXRoU2FtZVNlbmRlcjtcbiAgICAgICAgY29uc3QgcmVuZGVyQXZhdGFyID0gY3JlYXRlQXZhdGFyUmVuZGVyZXIoeyBhY3Rpdml0eTogZmlyc3RBY3Rpdml0eSB9KTtcblxuICAgICAgICBlbnRyaWVzV2l0aFNhbWVTZW5kZXIuZm9yRWFjaCgoZW50cmllc1dpdGhTYW1lU2VuZGVyQW5kU3RhdHVzLCBpbmRleFdpdGhpblNlbmRlckdyb3VwKSA9PiB7XG4gICAgICAgICAgY29uc3QgZmlyc3RJblNlbmRlckdyb3VwID0gIWluZGV4V2l0aGluU2VuZGVyR3JvdXA7XG4gICAgICAgICAgY29uc3QgbGFzdEluU2VuZGVyR3JvdXAgPSBpbmRleFdpdGhpblNlbmRlckdyb3VwID09PSBlbnRyaWVzV2l0aFNhbWVTZW5kZXIubGVuZ3RoIC0gMTtcblxuICAgICAgICAgIGVudHJpZXNXaXRoU2FtZVNlbmRlckFuZFN0YXR1cy5mb3JFYWNoKCh7IGFjdGl2aXR5LCByZW5kZXJBY3Rpdml0eSB9LCBpbmRleFdpdGhpblNlbmRlckFuZFN0YXR1c0dyb3VwKSA9PiB7XG4gICAgICAgICAgICAvLyBXZSBvbmx5IHNob3cgdGhlIHRpbWVzdGFtcCBhdCB0aGUgZW5kIG9mIHRoZSBzZW5kZXIgZ3JvdXAuIEJ1dCB3ZSBhbHdheXMgc2hvdyB0aGUgXCJTZW5kIGZhaWxlZCwgcmV0cnlcIiBwcm9tcHQuXG4gICAgICAgICAgICBjb25zdCBmaXJzdEluU2VuZGVyQW5kU3RhdHVzR3JvdXAgPSAhaW5kZXhXaXRoaW5TZW5kZXJBbmRTdGF0dXNHcm91cDtcbiAgICAgICAgICAgIGNvbnN0IGtleTogc3RyaW5nID0gZ2V0S2V5QnlBY3Rpdml0eShhY3Rpdml0eSk7XG4gICAgICAgICAgICBjb25zdCBsYXN0SW5TZW5kZXJBbmRTdGF0dXNHcm91cCA9XG4gICAgICAgICAgICAgIGluZGV4V2l0aGluU2VuZGVyQW5kU3RhdHVzR3JvdXAgPT09IGVudHJpZXNXaXRoU2FtZVNlbmRlckFuZFN0YXR1cy5sZW5ndGggLSAxO1xuICAgICAgICAgICAgY29uc3QgcmVuZGVyQWN0aXZpdHlTdGF0dXMgPSBjcmVhdGVBY3Rpdml0eVN0YXR1c1JlbmRlcmVyKHtcbiAgICAgICAgICAgICAgYWN0aXZpdHksXG4gICAgICAgICAgICAgIG5leHRWaXNpYmxlQWN0aXZpdHk6IHVuZGVmaW5lZFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjb25zdCB0b3BTaWRlTnViID0gYWN0aXZpdHkuZnJvbT8ucm9sZSA9PT0gJ3VzZXInID8gdG9wU2lkZVVzZXJOdWIgOiB0b3BTaWRlQm90TnViO1xuXG4gICAgICAgICAgICBsZXQgc2hvd0NhbGxvdXQ6IGJvb2xlYW47XG5cbiAgICAgICAgICAgIC8vIERlcGVuZGluZyBvbiB0aGUgXCJzaG93QXZhdGFySW5Hcm91cFwiIHNldHRpbmcsIHRoZSBhdmF0YXIgd2lsbCByZW5kZXIgaW4gZGlmZmVyZW50IHBvc2l0aW9ucy5cbiAgICAgICAgICAgIGlmIChzaG93QXZhdGFySW5Hcm91cCA9PT0gJ3NlbmRlcicpIHtcbiAgICAgICAgICAgICAgaWYgKHRvcFNpZGVOdWIpIHtcbiAgICAgICAgICAgICAgICBzaG93Q2FsbG91dCA9IGZpcnN0SW5TZW5kZXJHcm91cCAmJiBmaXJzdEluU2VuZGVyQW5kU3RhdHVzR3JvdXA7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc2hvd0NhbGxvdXQgPSBsYXN0SW5TZW5kZXJHcm91cCAmJiBsYXN0SW5TZW5kZXJBbmRTdGF0dXNHcm91cDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChzaG93QXZhdGFySW5Hcm91cCA9PT0gJ3N0YXR1cycpIHtcbiAgICAgICAgICAgICAgaWYgKHRvcFNpZGVOdWIpIHtcbiAgICAgICAgICAgICAgICBzaG93Q2FsbG91dCA9IGZpcnN0SW5TZW5kZXJBbmRTdGF0dXNHcm91cDtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzaG93Q2FsbG91dCA9IGxhc3RJblNlbmRlckFuZFN0YXR1c0dyb3VwO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBzaG93Q2FsbG91dCA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJlbmRlcmluZ0VsZW1lbnRzLnB1c2goe1xuICAgICAgICAgICAgICBhY3Rpdml0eSxcblxuICAgICAgICAgICAgICAvLyBBZnRlciB0aGUgZWxlbWVudCBpcyBtb3VudGVkLCBzZXQgaXQgdG8gYWN0aXZpdHlFbGVtZW50c1JlZi5cbiAgICAgICAgICAgICAgY2FsbGJhY2tSZWY6IGFjdGl2aXR5RWxlbWVudCA9PiB7XG4gICAgICAgICAgICAgICAgYWN0aXZpdHlFbGVtZW50XG4gICAgICAgICAgICAgICAgICA/IGFjdGl2aXR5RWxlbWVudE1hcFJlZi5jdXJyZW50LnNldChrZXksIGFjdGl2aXR5RWxlbWVudClcbiAgICAgICAgICAgICAgICAgIDogYWN0aXZpdHlFbGVtZW50TWFwUmVmLmN1cnJlbnQuZGVsZXRlKGtleSk7XG4gICAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgICAgLy8gXCJoaWRlVGltZXN0YW1wXCIgaXMgYSByZW5kZXItdGltZSBwYXJhbWV0ZXIgZm9yIHJlbmRlckFjdGl2aXR5U3RhdHVzKCkuXG4gICAgICAgICAgICAgIC8vIElmIHRydWUsIGl0IHdpbGwgaGlkZSB0aGUgdGltZXN0YW1wLCBidXQgaXQgd2lsbCBjb250aW51ZSB0byBzaG93IHRoZVxuICAgICAgICAgICAgICAvLyByZXRyeSBwcm9tcHQuIEFuZCBzaG93IHRoZSBzY3JlZW4gcmVhZGVyIHZlcnNpb24gb2YgdGhlIHRpbWVzdGFtcC5cbiAgICAgICAgICAgICAgaGlkZVRpbWVzdGFtcDpcbiAgICAgICAgICAgICAgICBoaWRlQWxsVGltZXN0YW1wcyB8fCBpbmRleFdpdGhpblNlbmRlckFuZFN0YXR1c0dyb3VwICE9PSBlbnRyaWVzV2l0aFNhbWVTZW5kZXJBbmRTdGF0dXMubGVuZ3RoIC0gMSxcbiAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICByZW5kZXJBY3Rpdml0eSxcbiAgICAgICAgICAgICAgcmVuZGVyQWN0aXZpdHlTdGF0dXMsXG4gICAgICAgICAgICAgIHJlbmRlckF2YXRhcixcbiAgICAgICAgICAgICAgc2hvd0NhbGxvdXRcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gcmVuZGVyaW5nRWxlbWVudHM7XG4gICAgfSwgW1xuICAgICAgYWN0aXZpdHlFbGVtZW50TWFwUmVmLFxuICAgICAgYWN0aXZpdHlXaXRoUmVuZGVyZXJUcmVlLFxuICAgICAgYnViYmxlRnJvbVVzZXJOdWJPZmZzZXQsXG4gICAgICBidWJibGVOdWJPZmZzZXQsXG4gICAgICBjcmVhdGVBY3Rpdml0eVN0YXR1c1JlbmRlcmVyLFxuICAgICAgY3JlYXRlQXZhdGFyUmVuZGVyZXIsXG4gICAgICBnZXRLZXlCeUFjdGl2aXR5LFxuICAgICAgaGlkZUFsbFRpbWVzdGFtcHMsXG4gICAgICBzaG93QXZhdGFySW5Hcm91cFxuICAgIF0pO1xuXG4gICAgY29uc3Qgc2Nyb2xsVG9Cb3R0b21TY3JvbGxUbzogKHNjcm9sbFRvcDogbnVtYmVyLCBvcHRpb25zPzogU2Nyb2xsVG9PcHRpb25zKSA9PiB2b2lkID0gdXNlU2Nyb2xsVG8oKTtcbiAgICBjb25zdCBzY3JvbGxUb0JvdHRvbVNjcm9sbFRvRW5kOiAob3B0aW9ucz86IFNjcm9sbFRvT3B0aW9ucykgPT4gdm9pZCA9IHVzZVNjcm9sbFRvRW5kKCk7XG5cbiAgICBjb25zdCBzY3JvbGxUbyA9IHVzZUNhbGxiYWNrKFxuICAgICAgKHBvc2l0aW9uOiBTY3JvbGxUb1Bvc2l0aW9uLCB7IGJlaGF2aW9yID0gJ2F1dG8nIH06IFNjcm9sbFRvT3B0aW9ucyA9IHt9KSA9PiB7XG4gICAgICAgIGlmICghcG9zaXRpb24pIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAnYm90ZnJhbWV3b3JrLXdlYmNoYXQ6IEZpcnN0IGFyZ3VtZW50IHBhc3NlZCB0byBcInVzZVNjcm9sbFRvXCIgbXVzdCBiZSBhIFNjcm9sbFBvc2l0aW9uIG9iamVjdC4nXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHsgYWN0aXZpdHlJRDogYWN0aXZpdHlJZCwgc2Nyb2xsVG9wIH0gPSBwb3NpdGlvbjtcblxuICAgICAgICBpZiAodHlwZW9mIHNjcm9sbFRvcCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBzY3JvbGxUb0JvdHRvbVNjcm9sbFRvKHNjcm9sbFRvcCwgeyBiZWhhdmlvciB9KTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgYWN0aXZpdHlJZCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBjb25zdCBhY3Rpdml0eUJvdW5kaW5nQm94RWxlbWVudCA9IGFjdGl2aXR5RWxlbWVudE1hcFJlZi5jdXJyZW50XG4gICAgICAgICAgICAuZ2V0KGdldEtleUJ5QWN0aXZpdHlJZChhY3Rpdml0eUlkKSlcbiAgICAgICAgICAgID8ucXVlcnlTZWxlY3RvcignLndlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX2FjdGl2aXR5LWFjdGl2ZS1kZXNjZW5kYW50Jyk7XG5cbiAgICAgICAgICBjb25zdCBzY3JvbGxhYmxlRWxlbWVudCA9IHJvb3RFbGVtZW50UmVmLmN1cnJlbnQucXVlcnlTZWxlY3RvcignLndlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX3Njcm9sbGFibGUnKTtcblxuICAgICAgICAgIGlmIChzY3JvbGxhYmxlRWxlbWVudCAmJiBhY3Rpdml0eUJvdW5kaW5nQm94RWxlbWVudCkge1xuICAgICAgICAgICAgLy8gRVNMaW50IGNvbmZsaWN0IHdpdGggVHlwZVNjcmlwdC4gVGhlIHJlc3VsdCBvZiBnZXRDbGllbnRSZWN0cygpIGlzIG5vdCBhbiBBcnJheSBidXQgRE9NUmVjdExpc3QsIGFuZCBjYW5ub3QgYmUgZGVzdHJ1Y3R1cmVkLlxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1kZXN0cnVjdHVyaW5nXG4gICAgICAgICAgICBjb25zdCB7IGhlaWdodDogYWN0aXZpdHlIZWlnaHQsIHk6IGFjdGl2aXR5WSB9ID0gYWN0aXZpdHlCb3VuZGluZ0JveEVsZW1lbnQuZ2V0Q2xpZW50UmVjdHMoKVswXTtcblxuICAgICAgICAgICAgLy8gRVNMaW50IGNvbmZsaWN0IHdpdGggVHlwZVNjcmlwdC4gVGhlIHJlc3VsdCBvZiBnZXRDbGllbnRSZWN0cygpIGlzIG5vdCBhbiBBcnJheSBidXQgRE9NUmVjdExpc3QsIGFuZCBjYW5ub3QgYmUgZGVzdHJ1Y3R1cmVkLlxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1kZXN0cnVjdHVyaW5nXG4gICAgICAgICAgICBjb25zdCB7IGhlaWdodDogc2Nyb2xsYWJsZUhlaWdodCB9ID0gc2Nyb2xsYWJsZUVsZW1lbnQuZ2V0Q2xpZW50UmVjdHMoKVswXTtcbiAgICAgICAgICAgIGNvbnN0IGFjdGl2aXR5T2Zmc2V0VG9wID0gYWN0aXZpdHlZICsgc2Nyb2xsYWJsZUVsZW1lbnQuc2Nyb2xsVG9wO1xuXG4gICAgICAgICAgICBjb25zdCBzY3JvbGxUb3AgPSBNYXRoLm1pbihhY3Rpdml0eU9mZnNldFRvcCwgYWN0aXZpdHlPZmZzZXRUb3AgLSBzY3JvbGxhYmxlSGVpZ2h0ICsgYWN0aXZpdHlIZWlnaHQpO1xuXG4gICAgICAgICAgICBzY3JvbGxUb0JvdHRvbVNjcm9sbFRvKHNjcm9sbFRvcCwgeyBiZWhhdmlvciB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBbYWN0aXZpdHlFbGVtZW50TWFwUmVmLCBnZXRLZXlCeUFjdGl2aXR5SWQsIHJvb3RFbGVtZW50UmVmLCBzY3JvbGxUb0JvdHRvbVNjcm9sbFRvXVxuICAgICk7XG5cbiAgICBjb25zdCBzY3JvbGxUb0VuZCA9IHVzZUNhbGxiYWNrKFxuICAgICAgKCkgPT4gc2Nyb2xsVG9Cb3R0b21TY3JvbGxUb0VuZCh7IGJlaGF2aW9yOiAnc21vb3RoJyB9KSxcbiAgICAgIFtzY3JvbGxUb0JvdHRvbVNjcm9sbFRvRW5kXVxuICAgICk7XG5cbiAgICBjb25zdCBzY3JvbGxSZWxhdGl2ZSA9IHVzZUNhbGxiYWNrKFxuICAgICAgKGRpcmVjdGlvbjogJ2Rvd24nIHwgJ3VwJywgeyBkaXNwbGFjZW1lbnQgfTogeyBkaXNwbGFjZW1lbnQ/OiBudW1iZXIgfSA9IHt9KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgY3VycmVudDogcm9vdEVsZW1lbnQgfSA9IHJvb3RFbGVtZW50UmVmO1xuXG4gICAgICAgIGlmICghcm9vdEVsZW1lbnQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzY3JvbGxhYmxlOiBIVE1MRWxlbWVudCA9IHJvb3RFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy53ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0X19zY3JvbGxhYmxlJyk7XG4gICAgICAgIGxldCBuZXh0U2Nyb2xsVG9wOiBudW1iZXI7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBkaXNwbGFjZW1lbnQgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLW1hZ2ljLW51bWJlcnNcbiAgICAgICAgICBuZXh0U2Nyb2xsVG9wID0gc2Nyb2xsYWJsZS5zY3JvbGxUb3AgKyAoZGlyZWN0aW9uID09PSAnZG93bicgPyAxIDogLTEpICogZGlzcGxhY2VtZW50O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1tYWdpYy1udW1iZXJzXG4gICAgICAgICAgbmV4dFNjcm9sbFRvcCA9IHNjcm9sbGFibGUuc2Nyb2xsVG9wICsgKGRpcmVjdGlvbiA9PT0gJ2Rvd24nID8gMSA6IC0xKSAqIHNjcm9sbGFibGUub2Zmc2V0SGVpZ2h0O1xuICAgICAgICB9XG5cbiAgICAgICAgc2Nyb2xsVG8oXG4gICAgICAgICAge1xuICAgICAgICAgICAgc2Nyb2xsVG9wOiBNYXRoLm1heCgwLCBNYXRoLm1pbihzY3JvbGxhYmxlLnNjcm9sbEhlaWdodCAtIHNjcm9sbGFibGUub2Zmc2V0SGVpZ2h0LCBuZXh0U2Nyb2xsVG9wKSlcbiAgICAgICAgICB9LFxuICAgICAgICAgIHsgYmVoYXZpb3I6ICdzbW9vdGgnIH1cbiAgICAgICAgKTtcbiAgICAgIH0sXG4gICAgICBbcm9vdEVsZW1lbnRSZWYsIHNjcm9sbFRvXVxuICAgICk7XG5cbiAgICAvLyBTaW5jZSB0aGVyZSBjb3VsZCBiZSBtdWx0aXBsZSBpbnN0YW5jZXMgb2YgPEJhc2ljVHJhbnNjcmlwdD4gaW5zaWRlIHRoZSA8Q29tcG9zZXI+LCB3aGVuIHRoZSBkZXZlbG9wZXIgY2FsbHMgYHNjcm9sbFhYWGAsIHdlIG5lZWQgdG8gY2FsbCBpdCBvbiBhbGwgaW5zdGFuY2VzLlxuICAgIC8vIFdlIGNhbGwgYHVzZVJlZ2lzdGVyU2Nyb2xsWFhYYCB0byByZWdpc3RlciBhIGNhbGxiYWNrIGZ1bmN0aW9uLCB0aGUgYHVzZVNjcm9sbFhYWGAgd2lsbCBtdWx0aXBsZXggdGhlIGNhbGwgaW50byBlYWNoIGluc3RhbmNlIG9mIDxCYXNpY1RyYW5zY3JpcHQ+LlxuICAgIHVzZVJlZ2lzdGVyU2Nyb2xsVG8oc2Nyb2xsVG8pO1xuICAgIHVzZVJlZ2lzdGVyU2Nyb2xsVG9FbmQoc2Nyb2xsVG9FbmQpO1xuICAgIHVzZVJlZ2lzdGVyU2Nyb2xsUmVsYXRpdmUoc2Nyb2xsUmVsYXRpdmUpO1xuXG4gICAgY29uc3QgbWFya0FjdGl2aXR5S2V5QXNSZWFkID0gdXNlTWFya0FjdGl2aXR5S2V5QXNSZWFkKCk7XG5cbiAgICBjb25zdCBkaXNwYXRjaFNjcm9sbFBvc2l0aW9uV2l0aEFjdGl2aXR5SWQ6IChzY3JvbGxQb3NpdGlvbjogU2Nyb2xsVG9Qb3NpdGlvbikgPT4gdm9pZCA9XG4gICAgICB1c2VEaXNwYXRjaFNjcm9sbFBvc2l0aW9uKCk7XG5cbiAgICAvLyBUT0RPOiBbUDJdIFdlIHNob3VsZCB1c2UgSW50ZXJzZWN0aW9uT2JzZXJ2ZXIgdG8gdHJhY2sgd2hhdCBhY3Rpdml0eSBpcyBpbiB0aGUgc2Nyb2xsYWJsZS5cbiAgICAvLyAgICAgICAgICAgIEhvd2V2ZXIsIEludGVyc2VjdGlvbk9ic2VydmVyIGlzIG5vdCBhdmFpbGFibGUgb24gSUUxMSwgd2UgbmVlZCB0byBtYWtlIGEgbGltaXRlZCBwb2x5ZmlsbCBpbiBSZWFjdCBzdHlsZS5cbiAgICBjb25zdCBoYW5kbGVTY3JvbGxQb3NpdGlvbiA9IHVzZUNhbGxiYWNrKFxuICAgICAgKHsgc2Nyb2xsVG9wIH06IHsgc2Nyb2xsVG9wOiBudW1iZXIgfSkgPT4ge1xuICAgICAgICBjb25zdCB7IGN1cnJlbnQ6IHJvb3RFbGVtZW50IH0gPSByb290RWxlbWVudFJlZjtcblxuICAgICAgICBpZiAoIXJvb3RFbGVtZW50KSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc2Nyb2xsYWJsZUVsZW1lbnQgPSByb290RWxlbWVudC5xdWVyeVNlbGVjdG9yKCcud2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fc2Nyb2xsYWJsZScpO1xuXG4gICAgICAgIC8vIFwiZ2V0Q2xpZW50UmVjdHMoKVwiIGlzIG5vdCByZXR1cm5pbmcgYW4gYXJyYXksIHRodXMsIGl0IGlzIG5vdCBkZXN0cnVjdHVyYWJsZS5cbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1kZXN0cnVjdHVyaW5nXG4gICAgICAgIGNvbnN0IHsgYm90dG9tOiBzY3JvbGxhYmxlQ2xpZW50Qm90dG9tIH0gPSBzY3JvbGxhYmxlRWxlbWVudC5nZXRDbGllbnRSZWN0cygpWzBdO1xuXG4gICAgICAgIC8vIEZpbmQgdGhlIGFjdGl2aXR5IGp1c3QgYWJvdmUgc2Nyb2xsIHZpZXcgYm90dG9tLlxuICAgICAgICAvLyBJZiB0aGUgc2Nyb2xsIHZpZXcgaXMgYWxyZWFkeSBvbiB0b3AsIGdldCB0aGUgZmlyc3QgYWN0aXZpdHkuXG4gICAgICAgIGNvbnN0IGFjdGl2aXR5RWxlbWVudHMgPSBBcnJheS5mcm9tKGFjdGl2aXR5RWxlbWVudE1hcFJlZi5jdXJyZW50LmVudHJpZXMoKSk7XG4gICAgICAgIGNvbnN0IGFjdGl2aXR5S2V5SnVzdEFib3ZlU2Nyb2xsQm90dG9tOiBzdHJpbmcgfCB1bmRlZmluZWQgPSAoXG4gICAgICAgICAgc2Nyb2xsYWJsZUVsZW1lbnQuc2Nyb2xsVG9wXG4gICAgICAgICAgICA/IGFjdGl2aXR5RWxlbWVudHNcbiAgICAgICAgICAgICAgICAucmV2ZXJzZSgpXG4gICAgICAgICAgICAgICAgLy8gQWRkIHN1YnBpeGVsIHRvbGVyYW5jZVxuICAgICAgICAgICAgICAgIC5maW5kKChbLCBlbGVtZW50XSkgPT4gZWxlbWVudC5nZXRDbGllbnRSZWN0cygpWzBdLmJvdHRvbSA8IHNjcm9sbGFibGVDbGllbnRCb3R0b20gKyAxKVxuICAgICAgICAgICAgOiBhY3Rpdml0eUVsZW1lbnRzWzBdXG4gICAgICAgICk/LlswXTtcblxuICAgICAgICAvLyBXaGVuIHRoZSBlbmQtdXNlciBzbG93bHkgc2Nyb2xsaW5nIHRoZSB2aWV3IGRvd24sIHdlIHdpbGwgbWFyayBhY3Rpdml0eSBhcyByZWFkIHdoZW4gdGhlIG1lc3NhZ2UgZnVsbHkgYXBwZWFyIG9uIHRoZSBzY3JlZW4uXG4gICAgICAgIGFjdGl2aXR5S2V5SnVzdEFib3ZlU2Nyb2xsQm90dG9tICYmIG1hcmtBY3Rpdml0eUtleUFzUmVhZChhY3Rpdml0eUtleUp1c3RBYm92ZVNjcm9sbEJvdHRvbSk7XG5cbiAgICAgICAgaWYgKGRpc3BhdGNoU2Nyb2xsUG9zaXRpb25XaXRoQWN0aXZpdHlJZCkge1xuICAgICAgICAgIGNvbnN0IGFjdGl2aXR5ID0gZ2V0QWN0aXZpdHlCeUtleShhY3Rpdml0eUtleUp1c3RBYm92ZVNjcm9sbEJvdHRvbSk7XG5cbiAgICAgICAgICBkaXNwYXRjaFNjcm9sbFBvc2l0aW9uV2l0aEFjdGl2aXR5SWQoeyAuLi4oYWN0aXZpdHkgPyB7IGFjdGl2aXR5SUQ6IGFjdGl2aXR5LmlkIH0gOiB7fSksIHNjcm9sbFRvcCB9KTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIFtcbiAgICAgICAgYWN0aXZpdHlFbGVtZW50TWFwUmVmLFxuICAgICAgICBkaXNwYXRjaFNjcm9sbFBvc2l0aW9uV2l0aEFjdGl2aXR5SWQsXG4gICAgICAgIGdldEFjdGl2aXR5QnlLZXksXG4gICAgICAgIG1hcmtBY3Rpdml0eUtleUFzUmVhZCxcbiAgICAgICAgcm9vdEVsZW1lbnRSZWZcbiAgICAgIF1cbiAgICApO1xuXG4gICAgdXNlT2JzZXJ2ZVNjcm9sbFBvc2l0aW9uKGhhbmRsZVNjcm9sbFBvc2l0aW9uKTtcblxuICAgIGNvbnN0IGhhbmRsZVRyYW5zY3JpcHRLZXlEb3duID0gdXNlQ2FsbGJhY2s8S2V5Ym9hcmRFdmVudEhhbmRsZXI8SFRNTERpdkVsZW1lbnQ+PihcbiAgICAgIGV2ZW50ID0+IHtcbiAgICAgICAgY29uc3QgeyB0YXJnZXQgfSA9IGV2ZW50O1xuXG4gICAgICAgIGNvbnN0IGZyb21FbmRPZlRyYW5zY3JpcHRJbmRpY2F0b3IgPSB0YXJnZXQgPT09IHRlcm1pbmF0b3JSZWYuY3VycmVudDtcbiAgICAgICAgY29uc3QgZnJvbVRyYW5zY3JpcHQgPSB0YXJnZXQgPT09IGV2ZW50LmN1cnJlbnRUYXJnZXQ7XG5cbiAgICAgICAgaWYgKCFmcm9tRW5kT2ZUcmFuc2NyaXB0SW5kaWNhdG9yICYmICFmcm9tVHJhbnNjcmlwdCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBoYW5kbGVkID0gdHJ1ZTtcblxuICAgICAgICBzd2l0Y2ggKGV2ZW50LmtleSkge1xuICAgICAgICAgIGNhc2UgJ0Fycm93RG93bic6XG4gICAgICAgICAgICBmb2N1c1JlbGF0aXZlQWN0aXZpdHkoZnJvbUVuZE9mVHJhbnNjcmlwdEluZGljYXRvciA/IDAgOiAxKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSAnQXJyb3dVcCc6XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbWFnaWMtbnVtYmVyc1xuICAgICAgICAgICAgZm9jdXNSZWxhdGl2ZUFjdGl2aXR5KGZyb21FbmRPZlRyYW5zY3JpcHRJbmRpY2F0b3IgPyAwIDogLTEpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlICdFbmQnOlxuICAgICAgICAgICAgZm9jdXNSZWxhdGl2ZUFjdGl2aXR5KEluZmluaXR5KTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSAnRW50ZXInOlxuICAgICAgICAgICAgLy8gVGhpcyBpcyBjYXB0dXJpbmcgcGxhaW4gRU5URVIuXG4gICAgICAgICAgICAvLyBXaGVuIHNjcmVlbiByZWFkZXIgaXMgbm90IHJ1bm5pbmcsIG9yIHNjcmVlbiByZWFkZXIgaXMgcnVubmluZyBvdXRzaWRlIG9mIHNjYW4gbW9kZSwgdGhlIEVOVEVSIGtleSB3aWxsIGJlIGNhcHR1cmVkIGhlcmUuXG4gICAgICAgICAgICBpZiAoIWZyb21FbmRPZlRyYW5zY3JpcHRJbmRpY2F0b3IpIHtcbiAgICAgICAgICAgICAgY29uc3QgYm9keTogSFRNTEVsZW1lbnQgPSBhY3Rpdml0eUVsZW1lbnRNYXBSZWYuY3VycmVudFxuICAgICAgICAgICAgICAgIC5nZXQoZm9jdXNlZEFjdGl2aXR5S2V5UmVmLmN1cnJlbnQpXG4gICAgICAgICAgICAgICAgPy5xdWVyeVNlbGVjdG9yKCcud2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fYWN0aXZpdHktYm9keScpO1xuXG4gICAgICAgICAgICAgIHRhYmJhYmxlRWxlbWVudHMoYm9keSlbMF0/LmZvY3VzKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSAnRXNjYXBlJzpcbiAgICAgICAgICAgIGZvY3VzKCdzZW5kQm94V2l0aG91dEtleWJvYXJkJyk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgJ0hvbWUnOlxuICAgICAgICAgICAgZm9jdXNSZWxhdGl2ZUFjdGl2aXR5KC1JbmZpbml0eSk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBoYW5kbGVkID0gZmFsc2U7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChoYW5kbGVkKSB7XG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICAgIC8vIElmIGEgY3VzdG9tIEhUTUwgY29udHJvbCB3YW50cyB0byBoYW5kbGUgdXAvZG93biBhcnJvdywgd2Ugd2lsbCBwcmV2ZW50IHRoZW0gZnJvbSBsaXN0ZW5pbmcgdG8gdGhpcyBldmVudCB0byBwcmV2ZW50IGJ1Z3MgZHVlIHRvIGhhbmRsaW5nIGFycm93IGtleXMgdHdpY2UuXG4gICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBbYWN0aXZpdHlFbGVtZW50TWFwUmVmLCBmb2N1cywgZm9jdXNlZEFjdGl2aXR5S2V5UmVmLCBmb2N1c1JlbGF0aXZlQWN0aXZpdHksIHRlcm1pbmF0b3JSZWZdXG4gICAgKTtcblxuICAgIGNvbnN0IGhhbmRsZVRyYW5zY3JpcHRLZXlEb3duQ2FwdHVyZSA9IHVzZUNhbGxiYWNrPEtleWJvYXJkRXZlbnRIYW5kbGVyPEhUTUxEaXZFbGVtZW50Pj4oXG4gICAgICBldmVudCA9PiB7XG4gICAgICAgIGNvbnN0IHsgYWx0S2V5LCBjdHJsS2V5LCBrZXksIG1ldGFLZXksIHRhcmdldCB9ID0gZXZlbnQ7XG5cbiAgICAgICAgaWYgKGFsdEtleSB8fCAoY3RybEtleSAmJiBrZXkgIT09ICd2JykgfHwgbWV0YUtleSB8fCAoIWlucHV0dGFibGVLZXkoa2V5KSAmJiBrZXkgIT09ICdCYWNrc3BhY2UnKSkge1xuICAgICAgICAgIC8vIElnbm9yZSBpZiBvbmUgb2YgdGhlIHV0aWxpdHkga2V5IChleGNlcHQgU0hJRlQpIGlzIHByZXNzZWRcbiAgICAgICAgICAvLyBFLmcuIENUUkwtQyBvbiBhIGxpbmsgaW4gb25lIG9mIHRoZSBtZXNzYWdlIHNob3VsZCBub3QganVtcCB0byBjaGF0IGJveFxuICAgICAgICAgIC8vIEUuZy4gXCJBXCIgb3IgXCJCYWNrc3BhY2VcIiBzaG91bGQganVtcCB0byBjaGF0IGJveFxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNlbmQga2V5c3Ryb2tlcyB0byBzZW5kIGJveCBpZiB3ZSBhcmUgZm9jdXNpbmcgb24gdGhlIHRyYW5zY3JpcHQgb3IgdGVybWluYXRvci5cbiAgICAgICAgaWYgKHRhcmdldCA9PT0gZXZlbnQuY3VycmVudFRhcmdldCB8fCB0YXJnZXQgPT09IHRlcm1pbmF0b3JSZWYuY3VycmVudCkge1xuICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICAgICAgZm9jdXMoJ3NlbmRCb3gnKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIFtmb2N1c11cbiAgICApO1xuXG4gICAgdXNlUmVnaXN0ZXJGb2N1c1RyYW5zY3JpcHQodXNlQ2FsbGJhY2soKCkgPT4gZm9jdXNCeUFjdGl2aXR5S2V5KHVuZGVmaW5lZCksIFtmb2N1c0J5QWN0aXZpdHlLZXldKSk7XG5cbiAgICAvLyBXaGVuIHRoZSBmb2N1c2luZyBhY3Rpdml0eSBoYXMgY2hhbmdlZCwgZGlzcGF0Y2ggYW4gZXZlbnQgdG8gb2JzZXJ2ZXJzIG9mIFwidXNlT2JzZXJ2ZVRyYW5zY3JpcHRGb2N1c1wiLlxuICAgIGNvbnN0IGRpc3BhdGNoVHJhbnNjcmlwdEZvY3VzQnlBY3Rpdml0eUtleSA9IHVzZURpc3BhdGNoVHJhbnNjcmlwdEZvY3VzQnlBY3Rpdml0eUtleSgpO1xuXG4gICAgLy8gRGlzcGF0Y2ggYSBcInRyYW5zY3JpcHQgZm9jdXNcIiBldmVudCBiYXNlZCBvbiB1c2VyIHNlbGVjdGlvbi5cbiAgICAvLyBXZSBzaG91bGQgbm90IGRpc3BhdGNoIFwidHJhbnNjcmlwdCBmb2N1c1wiIHdoZW4gYSBuZXcgYWN0aXZpdHkgY29tZS4gQWx0aG91Z2ggdGhlIHNlbGVjdGlvbiBjaGFuZ2UsIGl0IGlzIG5vdCBpbml0aWF0ZWQgZnJvbSB0aGUgdXNlci5cbiAgICB1c2VNZW1vKFxuICAgICAgKCkgPT4gZGlzcGF0Y2hUcmFuc2NyaXB0Rm9jdXNCeUFjdGl2aXR5S2V5KGZvY3VzZWRFeHBsaWNpdGx5ID8gZm9jdXNlZEFjdGl2aXR5S2V5IDogdW5kZWZpbmVkKSxcbiAgICAgIFtkaXNwYXRjaFRyYW5zY3JpcHRGb2N1c0J5QWN0aXZpdHlLZXksIGZvY3VzZWRBY3Rpdml0eUtleSwgZm9jdXNlZEV4cGxpY2l0bHldXG4gICAgKTtcblxuICAgIC8vIFdoZW4gdGhlIHRyYW5zY3JpcHQgaXMgYmVpbmcgZm9jdXNlZCBvbiwgd2Ugc2hvdWxkIGRpc3BhdGNoIGEgXCJ0cmFuc2NyaXB0Zm9jdXNcIiBldmVudC5cbiAgICBjb25zdCBoYW5kbGVGb2N1cyA9IHVzZUNhbGxiYWNrKFxuICAgICAgLy8gV2UgY2FsbCBcImZvY3VzQnlBY3Rpdml0eUtleVwiIHdpdGggYWN0aXZpdHkga2V5IG9mIFwidHJ1ZVwiLlxuICAgICAgLy8gSXQgbWVhbnMsIHRyaWVzIHRvIGZvY3VzIG9uIGFueXRoaW5nLlxuICAgICAgKHsgY3VycmVudFRhcmdldCwgdGFyZ2V0IH0pID0+IHRhcmdldCA9PT0gY3VycmVudFRhcmdldCAmJiBmb2N1c0J5QWN0aXZpdHlLZXkodHJ1ZSwgZmFsc2UpLFxuICAgICAgW2ZvY3VzQnlBY3Rpdml0eUtleV1cbiAgICApO1xuXG4gICAgLy8gVGhpcyBpcyByZXF1aXJlZCBieSBJRTExLlxuICAgIC8vIFdoZW4gdGhlIHVzZXIgY2xpY2tzIG9uIGFuZCBlbXB0eSBzcGFjZSAoYS5rLmEuIGZpbGxlcikgaW4gYW4gZW1wdHkgdHJhbnNjcmlwdCwgSUUxMSBzYXlzIHRoZSBmb2N1cyBpcyBvbiB0aGUgPGRpdiBjbGFzc05hbWU9XCJmaWxsZXJcIj4sXG4gICAgLy8gZGVzcGl0ZSB0aGUgZmFjdCB0aGVyZSBhcmUgbm8gXCJ0YWJJbmRleFwiIGF0dHJpYnV0ZXMgc2V0IG9uIHRoZSBmaWxsZXIuXG4gICAgLy8gV2UgbmVlZCB0byBhcnRpZmljaWFsbHkgc2VuZCB0aGUgZm9jdXMgYmFjayB0byB0aGUgdHJhbnNjcmlwdC5cbiAgICBjb25zdCBoYW5kbGVGb2N1c0ZpbGxlciA9IHVzZUNhbGxiYWNrKCgpID0+IGZvY3VzQnlBY3Rpdml0eUtleSh1bmRlZmluZWQpLCBbZm9jdXNCeUFjdGl2aXR5S2V5XSk7XG5cbiAgICAvLyBXaGVuIGZvY3VzIGludG8gdGhlIHRyYW5zY3JpcHQgdXNpbmcgVEFCL1NISUZULVRBQiwgc2Nyb2xsIHRoZSBmb2N1c2VkIGFjdGl2aXR5IGludG8gdmlldy5cbiAgICB1c2VPYnNlcnZlRm9jdXNWaXNpYmxlKFxuICAgICAgcm9vdEVsZW1lbnRSZWYsXG4gICAgICB1c2VDYWxsYmFjaygoKSA9PiBmb2N1c0J5QWN0aXZpdHlLZXkodW5kZWZpbmVkKSwgW2ZvY3VzQnlBY3Rpdml0eUtleV0pXG4gICAgKTtcblxuICAgIHJldHVybiAoXG4gICAgICA8ZGl2XG4gICAgICAgIC8vIEFsdGhvdWdoIEFuZHJvaWQgVGFsa0JhY2sgMTIuMSBkb2VzIG5vdCBzdXBwb3J0IGBhcmlhLWFjdGl2ZWRlc2NlbmRhbnRgLCB3aGVuIHVzZWQsIGl0IGJlY29tZSBidWdneSBhbmQgd2lsbCBuYXJyYXRlIGNvbnRlbnQgdHdpY2UuXG4gICAgICAgIC8vIFdlIGFyZSBkaXNhYmxpbmcgYGFyaWEtYWN0aXZlZGVzY2VuZGFudGAgZm9yIEFuZHJvaWQuIFNlZSA8QWN0aXZpdHlSb3c+IGZvciBkZXRhaWxzLlxuICAgICAgICBhcmlhLWFjdGl2ZWRlc2NlbmRhbnQ9e2FuZHJvaWQgPyB1bmRlZmluZWQgOiBhY3RpdmVEZXNjZW5kYW50SWR9XG4gICAgICAgIGFyaWEtbGFiZWw9e3RyYW5zY3JpcHRBcmlhTGFiZWx9XG4gICAgICAgIGNsYXNzTmFtZT17Y2xhc3NOYW1lcyhcbiAgICAgICAgICAnd2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdCcsXG4gICAgICAgICAgYmFzaWNUcmFuc2NyaXB0U3R5bGVTZXQgKyAnJyxcbiAgICAgICAgICByb290Q2xhc3NOYW1lLFxuICAgICAgICAgIChjbGFzc05hbWUgfHwgJycpICsgJydcbiAgICAgICAgKX1cbiAgICAgICAgZGlyPXtkaXJlY3Rpb259XG4gICAgICAgIG9uRm9jdXM9e2hhbmRsZUZvY3VzfVxuICAgICAgICBvbktleURvd249e2hhbmRsZVRyYW5zY3JpcHRLZXlEb3dufVxuICAgICAgICBvbktleURvd25DYXB0dXJlPXtoYW5kbGVUcmFuc2NyaXB0S2V5RG93bkNhcHR1cmV9XG4gICAgICAgIHJlZj17Y2FsbGJhY2tSZWZ9XG4gICAgICAgIC8vIFwiYXJpYS1hY3RpdmVkZXNjZW5kYW50XCIgd2lsbCBvbmx5IHdvcmtzIHdpdGggYSBudW1iZXIgb2Ygcm9sZXMgYW5kIGl0IG11c3QgYmUgZXhwbGljaXRseSBzZXQuXG4gICAgICAgIC8vIGh0dHBzOi8vd3d3LnczLm9yZy9UUi93YWktYXJpYS8jYXJpYS1hY3RpdmVkZXNjZW5kYW50XG4gICAgICAgIHJvbGU9XCJncm91cFwiXG4gICAgICAgIC8vIEZvciB1cC9kb3duIGFycm93IGtleSBuYXZpZ2F0aW9uIGFjcm9zcyBhY3Rpdml0aWVzLCB0aGlzIGNvbXBvbmVudCBtdXN0IGJlIGluY2x1ZGVkIGluIHRoZSB0YWIgc2VxdWVuY2UuXG4gICAgICAgIC8vIE90aGVyd2lzZSwgXCJhcmlhLWFjdGl2ZWRlc2NlbmRhbnRcIiB3aWxsIG5vdCBiZSBuYXJyYXRlZCB3aGVuIHRoZSB1c2VyIHByZXNzIHVwL2Rvd24gYXJyb3cga2V5cy5cbiAgICAgICAgLy8gaHR0cHM6Ly93d3cudzMub3JnL1RSL3dhaS1hcmlhLXByYWN0aWNlcy0xLjEvI2tiZF9mb2N1c19hY3RpdmVkZXNjZW5kYW50XG4gICAgICAgIHRhYkluZGV4PXswfVxuICAgICAgPlxuICAgICAgICA8TGl2ZVJlZ2lvblRyYW5zY3JpcHQgYWN0aXZpdHlFbGVtZW50TWFwUmVmPXthY3Rpdml0eUVsZW1lbnRNYXBSZWZ9IC8+XG4gICAgICAgIHsvKiBUT0RPOiBbUDJdIEZpeCBFU0xpbnQgZXJyb3IgYG5vLXVzZS1iZWZvcmUtZGVmaW5lYCAqL31cbiAgICAgICAgey8qIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdXNlLWJlZm9yZS1kZWZpbmUgKi99XG4gICAgICAgIDxJbnRlcm5hbFRyYW5zY3JpcHRTY3JvbGxhYmxlIG9uRm9jdXNGaWxsZXI9e2hhbmRsZUZvY3VzRmlsbGVyfSB0ZXJtaW5hdG9yUmVmPXt0ZXJtaW5hdG9yUmVmfT5cbiAgICAgICAgICB7cmVuZGVyaW5nRWxlbWVudHMubWFwKFxuICAgICAgICAgICAgKHtcbiAgICAgICAgICAgICAgYWN0aXZpdHksXG4gICAgICAgICAgICAgIGNhbGxiYWNrUmVmLFxuICAgICAgICAgICAgICBoaWRlVGltZXN0YW1wLFxuICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgIHJlbmRlckFjdGl2aXR5LFxuICAgICAgICAgICAgICByZW5kZXJBY3Rpdml0eVN0YXR1cyxcbiAgICAgICAgICAgICAgcmVuZGVyQXZhdGFyLFxuICAgICAgICAgICAgICBzaG93Q2FsbG91dFxuICAgICAgICAgICAgfSkgPT4gKFxuICAgICAgICAgICAgICA8QWN0aXZpdHlSb3cgYWN0aXZpdHk9e2FjdGl2aXR5fSBrZXk9e2tleX0gcmVmPXtjYWxsYmFja1JlZn0+XG4gICAgICAgICAgICAgICAge3JlbmRlckFjdGl2aXR5KHtcbiAgICAgICAgICAgICAgICAgIGhpZGVUaW1lc3RhbXAsXG4gICAgICAgICAgICAgICAgICByZW5kZXJBY3Rpdml0eVN0YXR1cyxcbiAgICAgICAgICAgICAgICAgIHJlbmRlckF2YXRhcixcbiAgICAgICAgICAgICAgICAgIHNob3dDYWxsb3V0XG4gICAgICAgICAgICAgICAgfSl9XG4gICAgICAgICAgICAgIDwvQWN0aXZpdHlSb3c+XG4gICAgICAgICAgICApXG4gICAgICAgICAgKX1cbiAgICAgICAgPC9JbnRlcm5hbFRyYW5zY3JpcHRTY3JvbGxhYmxlPlxuICAgICAgICB7ISFyZW5kZXJpbmdFbGVtZW50cy5sZW5ndGggJiYgKFxuICAgICAgICAgIDxGcmFnbWVudD5cbiAgICAgICAgICAgIDxGb2N1c1JlZGlyZWN0b3IgcmVkaXJlY3RSZWY9e3Jvb3RFbGVtZW50UmVmfSAvPlxuICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICBhcmlhLWhpZGRlbj17dHJ1ZX1cbiAgICAgICAgICAgICAgYXJpYS1sYWJlbGxlZGJ5PXt0ZXJtaW5hdG9yTGFiZWxJZH1cbiAgICAgICAgICAgICAgY2xhc3NOYW1lPVwid2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fdGVybWluYXRvclwiXG4gICAgICAgICAgICAgIHJlZj17dGVybWluYXRvclJlZn1cbiAgICAgICAgICAgICAgcm9sZT1cIm5vdGVcIlxuICAgICAgICAgICAgICB0YWJJbmRleD17MH1cbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJ3ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0X190ZXJtaW5hdG9yLWJvZHlcIj5cbiAgICAgICAgICAgICAgICB7LyogYGlkYCBpcyByZXF1aXJlZCBmb3IgYGFyaWEtbGFiZWxsZWRieWAgKi99XG4gICAgICAgICAgICAgICAgey8qIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC9mb3JiaWQtZG9tLXByb3BzICovfVxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwid2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fdGVybWluYXRvci10ZXh0XCIgaWQ9e3Rlcm1pbmF0b3JMYWJlbElkfT5cbiAgICAgICAgICAgICAgICAgIHt0ZXJtaW5hdG9yVGV4dH1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L0ZyYWdtZW50PlxuICAgICAgICApfVxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIndlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX2ZvY3VzLWluZGljYXRvclwiIC8+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG4pO1xuXG5JbnRlcm5hbFRyYW5zY3JpcHQuZGVmYXVsdFByb3BzID0ge1xuICBjbGFzc05hbWU6ICcnXG59O1xuXG5JbnRlcm5hbFRyYW5zY3JpcHQucHJvcFR5cGVzID0ge1xuICAvLyBQcm9wVHlwZXMgY2Fubm90IHZhbGlkYXRlIHByZWNpc2VseSB3aXRoIGl0cyBUeXBlU2NyaXB0IGNvdW50ZXJwYXJ0LlxuICAvLyBAdHMtaWdub3JlXG4gIGFjdGl2aXR5RWxlbWVudE1hcFJlZjogUHJvcFR5cGVzLnNoYXBlKHtcbiAgICBjdXJyZW50OiBQcm9wVHlwZXMuaW5zdGFuY2VPZihNYXApXG4gIH0pLmlzUmVxdWlyZWQsXG4gIGNsYXNzTmFtZTogUHJvcFR5cGVzLnN0cmluZ1xufTtcblxudHlwZSBJbnRlcm5hbFRyYW5zY3JpcHRTY3JvbGxhYmxlUHJvcHMgPSB7XG4gIGNoaWxkcmVuPzogUmVhY3ROb2RlO1xuICBvbkZvY3VzRmlsbGVyOiAoKSA9PiB2b2lkO1xuICB0ZXJtaW5hdG9yUmVmOiBNdXRhYmxlUmVmT2JqZWN0PEhUTUxEaXZFbGVtZW50Pjtcbn07XG5cbi8vIFNlcGFyYXRpbmcgaGlnaC1mcmVxdWVuY3kgaG9va3MgdG8gaW1wcm92ZSBwZXJmb3JtYW5jZS5cbmNvbnN0IEludGVybmFsVHJhbnNjcmlwdFNjcm9sbGFibGU6IEZDPEludGVybmFsVHJhbnNjcmlwdFNjcm9sbGFibGVQcm9wcz4gPSAoe1xuICBjaGlsZHJlbixcbiAgb25Gb2N1c0ZpbGxlcixcbiAgdGVybWluYXRvclJlZlxufSkgPT4ge1xuICBjb25zdCBbeyBhY3Rpdml0aWVzOiBhY3Rpdml0aWVzU3R5bGVTZXQgfV0gPSB1c2VTdHlsZVNldCgpO1xuICBjb25zdCBbYW5pbWF0aW5nVG9FbmRdOiBbYm9vbGVhbl0gPSB1c2VBbmltYXRpbmdUb0VuZCgpO1xuICBjb25zdCBbYXRFbmRdOiBbYm9vbGVhbl0gPSB1c2VBdEVuZCgpO1xuICBjb25zdCBbLCB1bnJlYWRBY3Rpdml0eUtleXNdID0gdXNlQWN0aXZpdHlLZXlzQnlSZWFkKCk7XG4gIGNvbnN0IFtzdGlja3ldOiBbYm9vbGVhbl0gPSB1c2VTdGlja3koKTtcbiAgY29uc3QgW3N0eWxlT3B0aW9uc10gPSB1c2VTdHlsZU9wdGlvbnMoKTtcbiAgY29uc3QgZm9jdXNCeUFjdGl2aXR5S2V5ID0gdXNlRm9jdXNCeUFjdGl2aXR5S2V5KCk7XG4gIGNvbnN0IGxvY2FsaXplID0gdXNlTG9jYWxpemVyKCk7XG4gIGNvbnN0IG1hcmtBY3Rpdml0eUtleUFzUmVhZCA9IHVzZU1hcmtBY3Rpdml0eUtleUFzUmVhZCgpO1xuICBjb25zdCBtYXJrQWxsQXNBY2tub3dsZWRnZWQgPSB1c2VNYXJrQWxsQXNBY2tub3dsZWRnZWQoKTtcbiAgY29uc3Qgc2Nyb2xsVG9FbmQ6IChvcHRpb25zPzogU2Nyb2xsVG9PcHRpb25zKSA9PiB2b2lkID0gdXNlU2Nyb2xsVG9FbmQoKTtcblxuICBjb25zdCBwcmV2U3RpY2t5ID0gdXNlUHJldmlvdXMoc3RpY2t5KTtcbiAgY29uc3QgdHJhbnNjcmlwdFJvbGVEZXNjcmlwdGlvbiA9IGxvY2FsaXplKCdUUkFOU0NSSVBUX0FSSUFfUk9MRV9BTFQnKTtcblxuICBjb25zdCBzdGlja3lDaGFuZ2VkVG9UcnVlID0gcHJldlN0aWNreSAhPT0gc3RpY2t5ICYmIHN0aWNreTtcblxuICAvLyBBY2tub3dsZWRnZWQgbWVhbnMgZWl0aGVyOlxuICAvLyAxLiBUaGUgdXNlciBzZW50IGEgbWVzc2FnZVxuICAvLyAgICAtIFdlIGRvbid0IG5lZWQgYSBjb25kaXRpb24gaGVyZS4gV2hlbiBXZWIgQ2hhdCBzZW5kcyB0aGUgdXNlcidzIG1lc3NhZ2UsIGl0IHdpbGwgc2Nyb2xsIHRvIGJvdHRvbSwgYW5kIGl0IHdpbGwgdHJpZ2dlciBjb25kaXRpb24gMiBiZWxvdy5cbiAgLy8gMi4gVGhlIHVzZXIgc2Nyb2xsIHRvIHRoZSBib3R0b20gb2YgdGhlIHRyYW5zY3JpcHQsIGZyb20gYSBub24tYm90dG9tIHNjcm9sbCBwb3NpdGlvblxuICAvLyAgICAtIElmIHRoZSB0cmFuc2NyaXB0IGlzIGFscmVhZHkgYXQgdGhlIGJvdHRvbSwgdGhlIHVzZXIgbmVlZHMgdG8gc2Nyb2xsIHVwIGFuZCB0aGVuIGdvIGJhY2sgZG93blxuICAvLyAgICAtIFdoYXQgaGFwcGVucyBpZiB3ZSBhcmUgcmVsYXhpbmcgXCJzY3JvbGxlZCBmcm9tIGEgbm9uLWJvdHRvbSBzY3JvbGwgcG9zaXRpb25cIjpcbiAgLy8gICAgICAxLiBUaGUgY29uZGl0aW9uIHdpbGwgYmVjb21lIHNvbGVseSBcImF0IHRoZSBib3R0b20gb2YgdGhlIHRyYW5zY3JpcHRcIlxuICAvLyAgICAgIDIuIEF1dG8tc2Nyb2xsIHdpbGwgYWx3YXlzIHNjcm9sbCB0aGUgdHJhbnNjcmlwdCB0byB0aGUgYm90dG9tXG4gIC8vICAgICAgMy4gV2ViIENoYXQgd2lsbCBhbHdheXMgYWNrbm93bGVkZ2UgYWxsIGFjdGl2aXRpZXMgYXMgaXQgaXMgYXQgdGhlIGJvdHRvbVxuICAvLyAgICAgIDQuIEFja25vd2xlZGdlIGZsYWcgYmVjb21lIHVzZWxlc3NcbiAgLy8gICAgICA1LiBUaGVyZWZvcmUsIGV2ZW4gdGhlIGRldmVsb3BlciBzZXQgXCJwYXVzZSBhZnRlciAzIGFjdGl2aXRpZXNcIiwgaWYgYWN0aXZpdGllcyBhcmUgY29taW5nIGluIGF0IGEgc2xvdyBwYWNlIChub3QgYmF0Y2hlZCBpbiBhIHNpbmdsZSByZW5kZXIpXG4gIC8vICAgICAgICAgV2ViIENoYXQgd2lsbCBrZWVwIHNjcm9sbGluZyBhbmQgbm90IHNuYXBwZWQvcGF1c2VkXG5cbiAgLy8gTm90ZTogV2hlbiBXZWIgQ2hhdCBpcyBsb2FkZWQsIHRoZXJlIGFyZSBubyBhY3Rpdml0aWVzIGFja25vd2xlZGdlZC4gV2UgbmVlZCB0byBhc3N1bWUgYWxsIGFycml2aW5nIGFjdGl2aXRpZXMgYXJlIGFja25vd2xlZGdlZCB1bnRpbCBlbmQtdXNlciBzZW5kcyB0aGVpciBmaXJzdCBhY3Rpdml0eS5cbiAgLy8gICAgICAgQWN0aXZpdGllcyBsb2FkZWQgaW5pdGlhbGx5IGNvdWxkIGJlIGZyb20gY29udmVyc2F0aW9uIGhpc3RvcnkuIFdpdGhvdXQgYXNzdW1pbmcgYWNrbm93bGVkZ2VtZW50LCBXZWIgQ2hhdCB3aWxsIG5vdCBzY3JvbGwgaW5pdGlhbGx5IChhcyBldmVyeXRoaW5nIGlzIG5vdCBhY2tub3dsZWRnZWQpLlxuICAvLyAgICAgICBJdCB3b3VsZCBiZSBiZXR0ZXIgaWYgdGhlIGNoYXQgYWRhcHRlciBzaG91bGQgbGV0IFdlYiBDaGF0IGtub3cgaWYgdGhlIGFjdGl2aXR5IGlzIGxvYWRlZCBmcm9tIGhpc3Rvcnkgb3Igbm90LlxuXG4gIC8vIFRPRE86IFtQMl0gIzM2NzAgTW92ZSB0aGUgXCJjb252ZXJzYXRpb24gaGlzdG9yeSBhY2tub3dsZWRnZW1lbnRcIiBsb2dpYyBtZW50aW9uZWQgYWJvdmUgdG8gcG9seWZpbGwgb2YgY2hhdCBhZGFwdGVycy5cbiAgLy8gICAgICAgMS4gQ2hhdCBhZGFwdGVyIHNob3VsZCBzZW5kIFwiYWNrbm93bGVkZ2VkXCIgYXMgcGFydCBvZiBcImNoYW5uZWxEYXRhXCJcbiAgLy8gICAgICAgMi4gSWYgXCJhY2tub3dsZWRnZWRcIiBpcyBcInVuZGVmaW5lZFwiLCB3ZSBzZXQgaXQgdG86XG4gIC8vICAgICAgICAgIGEuIHRydWUsIGlmIHRoZXJlIGFyZSBubyBlZ3Jlc3MgYWN0aXZpdGllcyB5ZXRcbiAgLy8gICAgICAgICAgYi4gT3RoZXJ3aXNlLCBmYWxzZVxuXG4gIHVzZU1lbW8oXG4gICAgKCkgPT5cbiAgICAgIHN0aWNreUNoYW5nZWRUb1RydWUgJiZcbiAgICAgIC8vIFRPRE86IFtQMl0gQm90aCBgbWFya0FjdGl2aXR5S2V5QXNSZWFkYCBhbmQgYG1hcmtBbGxBc0Fja25vd2xlZGdlZGAgaG9vayBhcmUgc2V0dGVycyBvZiB1c2VTdGF0ZS5cbiAgICAgIC8vICAgICAgIFRoaXMgbWVhbnMsIGluIGEgcmVuZGVyIGxvb3AsIHdlIHdpbGwgYmUgY2FsbGluZyBzZXR0ZXIgYW5kIHdpbGwgY2F1c2UgYW5vdGhlciByZS1yZW5kZXIuXG4gICAgICAvLyAgICAgICBUaGlzIGlzIG5vdCB0cml2aWFsIGJ1dCB3ZSBzaG91bGQgdGhpbmsgaWYgdGhlcmUgaXMgYSB3YXkgdG8gYXZvaWQgdGhpcy5cbiAgICAgIG1hcmtBbGxBc0Fja25vd2xlZGdlZCgpLFxuICAgIFttYXJrQWxsQXNBY2tub3dsZWRnZWQsIHN0aWNreUNoYW5nZWRUb1RydWVdXG4gICk7XG5cbiAgY29uc3QgW2ZsYXR0ZW5lZEFjdGl2aXR5VHJlZVdpdGhSZW5kZXJlcl0gPSB1c2VBY3Rpdml0eVRyZWVXaXRoUmVuZGVyZXIoeyBmbGF0OiB0cnVlIH0pO1xuICBjb25zdCBnZXRLZXlCeUFjdGl2aXR5ID0gdXNlR2V0S2V5QnlBY3Rpdml0eSgpO1xuXG4gIGNvbnN0IHJlbmRlcmluZ0FjdGl2aXR5S2V5czogc3RyaW5nW10gPSB1c2VNZW1vPHN0cmluZ1tdPihcbiAgICAoKSA9PiBmbGF0dGVuZWRBY3Rpdml0eVRyZWVXaXRoUmVuZGVyZXIubWFwKCh7IGFjdGl2aXR5IH0pID0+IGdldEtleUJ5QWN0aXZpdHkoYWN0aXZpdHkpKSxcbiAgICBbZmxhdHRlbmVkQWN0aXZpdHlUcmVlV2l0aFJlbmRlcmVyLCBnZXRLZXlCeUFjdGl2aXR5XVxuICApO1xuXG4gIGNvbnN0IHJlbmRlcmluZ0FjdGl2aXR5S2V5c1JlZiA9IHVzZVZhbHVlUmVmKHJlbmRlcmluZ0FjdGl2aXR5S2V5cyk7XG5cbiAgLy8gVG8gcHJldmVudCBmbGFzaHkgYnV0dG9uLCB3ZSBhcmUgbm90IHdhaXRpbmcgZm9yIGFub3RoZXIgcmVuZGVyIGxvb3AgdG8gdXBkYXRlIHRoZSBgW3JlYWRBY3Rpdml0eUtleXMsIHVucmVhZEFjdGl2aXR5S2V5c11gIHN0YXRlLlxuICAvLyBJbnN0ZWFkLCB3ZSBhcmUgYnVpbGRpbmcgdGhlIG5leHQgb25lIGluIHRoaXMgYHVzZU1lbW9gIGNhbGwuXG4gIGNvbnN0IG5leHRVbnJlYWRBY3Rpdml0eUtleXMgPSB1c2VNZW1vKCgpID0+IHtcbiAgICAvLyBUaGlzIGNvZGUgbmVlZCB0byBiZSBjYXJlZnVsIHJldmlld2VkIGFzIGl0IHdpbGwgY2F1c2UgYW5vdGhlciByZW5kZXIuIFRoZSBjb2RlIHNob3VsZCBiZSBjb252ZXJnaW5nLlxuICAgIC8vIEFmdGVyIHdlIGNhbGwgYG1hcmtBY3Rpdml0eUtleUFzUmVhZGAsIGV2ZXJ5dGhpbmcgd2lsbCBiZSByZWFkIGFuZCBub3RoaW5nIHdpbGwgYmUgdW5yZWFkLlxuICAgIC8vIFRoYXQgbWVhbnMsIGluIG5leHQgcmVuZGVyLCBgdW5yZWFkQWN0aXZpdHlLZXlzYCB3aWxsIGJlIGVtcHRpZWQgYW5kIHRoZSBgbWFya0FjdGl2aXR5S2V5QXNSZWFkYCB3aWxsIG5vdCBnZXQgY2FsbGVkIGFnYWluLlxuICAgIGlmIChzdGlja3kgJiYgdW5yZWFkQWN0aXZpdHlLZXlzLmxlbmd0aCkge1xuICAgICAgbWFya0FjdGl2aXR5S2V5QXNSZWFkKHVucmVhZEFjdGl2aXR5S2V5c1t1bnJlYWRBY3Rpdml0eUtleXMubGVuZ3RoIC0gMV0pO1xuXG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgcmV0dXJuIHVucmVhZEFjdGl2aXR5S2V5cztcbiAgfSwgW21hcmtBY3Rpdml0eUtleUFzUmVhZCwgc3RpY2t5LCB1bnJlYWRBY3Rpdml0eUtleXNdKTtcblxuICBjb25zdCBuZXh0VW5yZWFkQWN0aXZpdHlLZXlzUmVmID0gdXNlVmFsdWVSZWYobmV4dFVucmVhZEFjdGl2aXR5S2V5cyk7XG5cbiAgLy8gSWYgd2UgYXJlIHJlbmRlcmluZyBhbnl0aGluZyB0aGF0IGlzIHVucmVhZCwgd2Ugc2hvdWxkIHNob3cgdGhlIFwiTmV3IG1lc3NhZ2VzXCIgYnV0dG9uLlxuICAvLyBOb3QgZXZlcnl0aGluZyBpbiB0aGUgYHVucmVhZEFjdGl2aXR5S2V5c2AgYXJlIHJlbmRlcmVkLCBzYXksIGJvdCB0eXBpbmcgaW5kaWNhdG9yLlxuICAvLyBXZSBzaG91bGQgbm90IHNob3cgdGhlIFwiTmV3IG1lc3NhZ2VzXCIgYnV0dG9uIGZvciBib3QgdHlwaW5nIGluZGljYXRvciBhcyBpdCB3aWxsIGNvbmZ1c2UgdGhlIHVzZXIuXG4gIGNvbnN0IHVucmVhZCA9IHVzZU1lbW8oXG4gICAgKCkgPT4gbmV4dFVucmVhZEFjdGl2aXR5S2V5cy5zb21lKGtleSA9PiByZW5kZXJpbmdBY3Rpdml0eUtleXMuaW5jbHVkZXMoa2V5KSksXG4gICAgW3JlbmRlcmluZ0FjdGl2aXR5S2V5cywgbmV4dFVucmVhZEFjdGl2aXR5S2V5c11cbiAgKTtcblxuICBjb25zdCBoYW5kbGVTY3JvbGxUb0VuZEJ1dHRvbkNsaWNrID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIHNjcm9sbFRvRW5kKHsgYmVoYXZpb3I6ICdzbW9vdGgnIH0pO1xuXG4gICAgY29uc3QgeyBjdXJyZW50OiByZW5kZXJpbmdBY3Rpdml0eUtleXMgfSA9IHJlbmRlcmluZ0FjdGl2aXR5S2V5c1JlZjtcblxuICAgIC8vIEFmdGVyIHRoZSBcIk5ldyBtZXNzYWdlXCIgYnV0dG9uIGlzIGNsaWNrZWQsIGZvY3VzIG9uIHRoZSBmaXJzdCB1bnJlYWQgYWN0aXZpdHkgd2hpY2ggd2lsbCBiZSByZW5kZXJlZC5cbiAgICBjb25zdCBmaXJzdFVucmVhZFJlbmRlcmluZ0FjdGl2aXR5S2V5ID0gbmV4dFVucmVhZEFjdGl2aXR5S2V5c1JlZi5jdXJyZW50LmZpbmQoa2V5ID0+XG4gICAgICByZW5kZXJpbmdBY3Rpdml0eUtleXMuaW5jbHVkZXMoa2V5KVxuICAgICk7XG5cbiAgICBpZiAoZmlyc3RVbnJlYWRSZW5kZXJpbmdBY3Rpdml0eUtleSkge1xuICAgICAgZm9jdXNCeUFjdGl2aXR5S2V5KGZpcnN0VW5yZWFkUmVuZGVyaW5nQWN0aXZpdHlLZXkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJZiBubyB1bnJlYWQgYWN0aXZpdHksIHNlbmQgdGhlIGZvY3VzIHRvIHRoZSB0ZXJtaW5hdG9yIGJsb2NrLlxuICAgICAgdGVybWluYXRvclJlZi5jdXJyZW50Py5mb2N1cygpO1xuICAgIH1cbiAgfSwgW2ZvY3VzQnlBY3Rpdml0eUtleSwgbmV4dFVucmVhZEFjdGl2aXR5S2V5c1JlZiwgcmVuZGVyaW5nQWN0aXZpdHlLZXlzUmVmLCBzY3JvbGxUb0VuZCwgdGVybWluYXRvclJlZl0pO1xuXG4gIGNvbnN0IHJlbmRlclNjcm9sbFRvRW5kQnV0dG9uID0gdXNlQ3JlYXRlU2Nyb2xsVG9FbmRCdXR0b25SZW5kZXJlcigpKHtcbiAgICBhdEVuZDogYW5pbWF0aW5nVG9FbmQgfHwgYXRFbmQgfHwgc3RpY2t5LFxuICAgIHN0eWxlT3B0aW9ucyxcbiAgICB1bnJlYWRcbiAgfSk7XG5cbiAgcmV0dXJuIChcbiAgICA8UmVhY3QuRnJhZ21lbnQ+XG4gICAgICB7cmVuZGVyU2Nyb2xsVG9FbmRCdXR0b24gJiYgcmVuZGVyU2Nyb2xsVG9FbmRCdXR0b24oeyBvbkNsaWNrOiBoYW5kbGVTY3JvbGxUb0VuZEJ1dHRvbkNsaWNrIH0pfVxuICAgICAgeyEhUmVhY3QuQ2hpbGRyZW4uY291bnQoY2hpbGRyZW4pICYmIDxGb2N1c1JlZGlyZWN0b3IgcmVkaXJlY3RSZWY9e3Rlcm1pbmF0b3JSZWZ9IC8+fVxuICAgICAgPFJlYWN0U2Nyb2xsVG9Cb3R0b21QYW5lbCBjbGFzc05hbWU9XCJ3ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0X19zY3JvbGxhYmxlXCI+XG4gICAgICAgIDxkaXYgYXJpYS1oaWRkZW49e3RydWV9IGNsYXNzTmFtZT1cIndlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX2ZpbGxlclwiIG9uRm9jdXM9e29uRm9jdXNGaWxsZXJ9IC8+XG4gICAgICAgIDxzZWN0aW9uXG4gICAgICAgICAgYXJpYS1yb2xlZGVzY3JpcHRpb249e3RyYW5zY3JpcHRSb2xlRGVzY3JpcHRpb259XG4gICAgICAgICAgY2xhc3NOYW1lPXtjbGFzc05hbWVzKGFjdGl2aXRpZXNTdHlsZVNldCArICcnLCAnd2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fdHJhbnNjcmlwdCcpfVxuICAgICAgICAgIHJvbGU9XCJmZWVkXCJcbiAgICAgICAgPlxuICAgICAgICAgIHtjaGlsZHJlbn1cbiAgICAgICAgPC9zZWN0aW9uPlxuICAgICAgICA8QmFzaWNUeXBpbmdJbmRpY2F0b3IgLz5cbiAgICAgIDwvUmVhY3RTY3JvbGxUb0JvdHRvbVBhbmVsPlxuICAgIDwvUmVhY3QuRnJhZ21lbnQ+XG4gICk7XG59O1xuXG5JbnRlcm5hbFRyYW5zY3JpcHRTY3JvbGxhYmxlLnByb3BUeXBlcyA9IHtcbiAgY2hpbGRyZW46IFByb3BUeXBlcy5hbnkuaXNSZXF1aXJlZCxcbiAgb25Gb2N1c0ZpbGxlcjogUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZCxcbiAgdGVybWluYXRvclJlZjogUHJvcFR5cGVzLmFueS5pc1JlcXVpcmVkXG59O1xuXG50eXBlIFNjcm9sbGVyID0gKHsgb2Zmc2V0SGVpZ2h0LCBzY3JvbGxUb3AgfTogeyBvZmZzZXRIZWlnaHQ6IG51bWJlcjsgc2Nyb2xsVG9wOiBudW1iZXIgfSkgPT4gbnVtYmVyO1xuXG4vLyBcInNjcm9sbGVyXCIgaXMgdGhlIGF1dG8tc2Nyb2xsIGxpbWl0ZXIsIGEuay5hLiBhdXRvIHNjcm9sbCBzbmFwLlxuY29uc3QgdXNlU2Nyb2xsZXIgPSAoYWN0aXZpdHlFbGVtZW50TWFwUmVmOiBNdXRhYmxlUmVmT2JqZWN0PEFjdGl2aXR5RWxlbWVudE1hcD4pOiBTY3JvbGxlciA9PiB7XG4gIGNvbnN0IFthY3Rpdml0eUtleXNdID0gdXNlQWN0aXZpdHlLZXlzKCk7XG4gIGNvbnN0IFtsYXN0QWNrbm93bGVkZ2VkQWN0aXZpdHlLZXldID0gdXNlTGFzdEFja25vd2xlZGdlZEFjdGl2aXR5S2V5KCk7XG4gIGNvbnN0IFtzdHlsZU9wdGlvbnNdID0gdXNlU3R5bGVPcHRpb25zKCk7XG5cbiAgY29uc3QgYWN0aXZpdHlLZXlzUmVmID0gdXNlVmFsdWVSZWYoYWN0aXZpdHlLZXlzKTtcbiAgY29uc3QgbGFzdEFja25vd2xlZGdlZEFjdGl2aXR5S2V5UmVmID0gdXNlVmFsdWVSZWYobGFzdEFja25vd2xlZGdlZEFjdGl2aXR5S2V5KTtcbiAgY29uc3Qgc3R5bGVPcHRpb25zUmVmID0gdXNlVmFsdWVSZWYoc3R5bGVPcHRpb25zKTtcblxuICByZXR1cm4gdXNlQ2FsbGJhY2soXG4gICAgKHsgb2Zmc2V0SGVpZ2h0LCBzY3JvbGxUb3AgfSkgPT4ge1xuICAgICAgY29uc3Qge1xuICAgICAgICBjdXJyZW50OiB7XG4gICAgICAgICAgYXV0b1Njcm9sbFNuYXBPbkFjdGl2aXR5LFxuICAgICAgICAgIGF1dG9TY3JvbGxTbmFwT25BY3Rpdml0eU9mZnNldCxcbiAgICAgICAgICBhdXRvU2Nyb2xsU25hcE9uUGFnZSxcbiAgICAgICAgICBhdXRvU2Nyb2xsU25hcE9uUGFnZU9mZnNldFxuICAgICAgICB9XG4gICAgICB9ID0gc3R5bGVPcHRpb25zUmVmO1xuXG4gICAgICBjb25zdCBwYXRjaGVkQXV0b1Njcm9sbFNuYXBPbkFjdGl2aXR5ID1cbiAgICAgICAgdHlwZW9mIGF1dG9TY3JvbGxTbmFwT25BY3Rpdml0eSA9PT0gJ251bWJlcidcbiAgICAgICAgICA/IE1hdGgubWF4KDAsIGF1dG9TY3JvbGxTbmFwT25BY3Rpdml0eSlcbiAgICAgICAgICA6IGF1dG9TY3JvbGxTbmFwT25BY3Rpdml0eVxuICAgICAgICAgID8gMVxuICAgICAgICAgIDogMDtcbiAgICAgIGNvbnN0IHBhdGNoZWRBdXRvU2Nyb2xsU25hcE9uUGFnZSA9XG4gICAgICAgIHR5cGVvZiBhdXRvU2Nyb2xsU25hcE9uUGFnZSA9PT0gJ251bWJlcidcbiAgICAgICAgICA/IE1hdGgubWF4KDAsIE1hdGgubWluKDEsIGF1dG9TY3JvbGxTbmFwT25QYWdlKSlcbiAgICAgICAgICA6IGF1dG9TY3JvbGxTbmFwT25QYWdlXG4gICAgICAgICAgPyAxXG4gICAgICAgICAgOiAwO1xuICAgICAgY29uc3QgcGF0Y2hlZEF1dG9TY3JvbGxTbmFwT25BY3Rpdml0eU9mZnNldCA9XG4gICAgICAgIHR5cGVvZiBhdXRvU2Nyb2xsU25hcE9uQWN0aXZpdHlPZmZzZXQgPT09ICdudW1iZXInID8gYXV0b1Njcm9sbFNuYXBPbkFjdGl2aXR5T2Zmc2V0IDogMDtcbiAgICAgIGNvbnN0IHBhdGNoZWRBdXRvU2Nyb2xsU25hcE9uUGFnZU9mZnNldCA9XG4gICAgICAgIHR5cGVvZiBhdXRvU2Nyb2xsU25hcE9uUGFnZU9mZnNldCA9PT0gJ251bWJlcicgPyBhdXRvU2Nyb2xsU25hcE9uUGFnZU9mZnNldCA6IDA7XG5cbiAgICAgIGlmIChwYXRjaGVkQXV0b1Njcm9sbFNuYXBPbkFjdGl2aXR5IHx8IHBhdGNoZWRBdXRvU2Nyb2xsU25hcE9uUGFnZSkge1xuICAgICAgICBjb25zdCB7IGN1cnJlbnQ6IGFjdGl2aXR5RWxlbWVudE1hcCB9ID0gYWN0aXZpdHlFbGVtZW50TWFwUmVmO1xuICAgICAgICBjb25zdCB7IGN1cnJlbnQ6IGFjdGl2aXR5S2V5cyB9ID0gYWN0aXZpdHlLZXlzUmVmO1xuICAgICAgICBjb25zdCB7IGN1cnJlbnQ6IGxhc3RBY2tub3dsZWRnZWRBY3Rpdml0eUtleSB9ID0gbGFzdEFja25vd2xlZGdlZEFjdGl2aXR5S2V5UmVmO1xuICAgICAgICBjb25zdCB2YWx1ZXM6IG51bWJlcltdID0gW107XG5cbiAgICAgICAgY29uc3QgbGFzdEFja25vd2xlZGdlZEFjdGl2aXR5S2V5SW5kZXggPSBhY3Rpdml0eUtleXMuaW5kZXhPZihsYXN0QWNrbm93bGVkZ2VkQWN0aXZpdHlLZXkpO1xuXG4gICAgICAgIGlmICh+bGFzdEFja25vd2xlZGdlZEFjdGl2aXR5S2V5SW5kZXgpIHtcbiAgICAgICAgICAvLyBUaGUgYWN0aXZpdHkgdGhhdCB3ZSBhY2tub3dsZWRnZWQgY291bGQgYmUgbm90IHJlbmRlcmVkLCBzdWNoIGFzIHBvc3QgYmFjayBhY3Rpdml0eS5cbiAgICAgICAgICAvLyBXaGVuIGNhbGN1bGF0aW5nIHNjcm9sbCBzbmFwLCB3ZSBjYW4gb25seSBiYXNlIG9uIHRoZSBmaXJzdCB1bmFja25vd2xlZGdlZC1hbmQtcmVuZGVyaW5nIGFjdGl2aXR5LlxuICAgICAgICAgIGNvbnN0IHJlbmRlcmluZ0FjdGl2aXR5S2V5cyA9IEFycmF5LmZyb20oYWN0aXZpdHlFbGVtZW50TWFwLmtleXMoKSk7XG4gICAgICAgICAgbGV0IGZpcnN0VW5hY2tub3dsZWRnZWRBY3Rpdml0eUVsZW1lbnRJbmRleCA9IC0xO1xuXG4gICAgICAgICAgZm9yIChjb25zdCBhY2tub3dsZWRnZWRBY3Rpdml0eUtleSBvZiBhY3Rpdml0eUtleXMuc2xpY2UoMCwgbGFzdEFja25vd2xlZGdlZEFjdGl2aXR5S2V5SW5kZXggKyAxKS5yZXZlcnNlKCkpIHtcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gcmVuZGVyaW5nQWN0aXZpdHlLZXlzLmluZGV4T2YoYWNrbm93bGVkZ2VkQWN0aXZpdHlLZXkpO1xuXG4gICAgICAgICAgICBpZiAofmluZGV4KSB7XG4gICAgICAgICAgICAgIGlmIChpbmRleCAhPT0gcmVuZGVyaW5nQWN0aXZpdHlLZXlzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgICAgICBmaXJzdFVuYWNrbm93bGVkZ2VkQWN0aXZpdHlFbGVtZW50SW5kZXggPSBpbmRleCArIDE7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAofmZpcnN0VW5hY2tub3dsZWRnZWRBY3Rpdml0eUVsZW1lbnRJbmRleCkge1xuICAgICAgICAgICAgY29uc3QgYWN0aXZpdHlFbGVtZW50cyA9IEFycmF5LmZyb20oYWN0aXZpdHlFbGVtZW50TWFwLnZhbHVlcygpKTtcblxuICAgICAgICAgICAgaWYgKHBhdGNoZWRBdXRvU2Nyb2xsU25hcE9uQWN0aXZpdHkpIHtcbiAgICAgICAgICAgICAgLy8gR2V0cyB0aGUgYWN0aXZpdHkgZWxlbWVudCB3aGljaCB3ZSBzaG91bGQgc25hcCB0by5cbiAgICAgICAgICAgICAgY29uc3QgbnRoVW5hY2tub3dsZWRnZWRBY3Rpdml0eUVsZW1lbnQgPVxuICAgICAgICAgICAgICAgIGFjdGl2aXR5RWxlbWVudHNbZmlyc3RVbmFja25vd2xlZGdlZEFjdGl2aXR5RWxlbWVudEluZGV4ICsgcGF0Y2hlZEF1dG9TY3JvbGxTbmFwT25BY3Rpdml0eSAtIDFdO1xuXG4gICAgICAgICAgICAgIGlmIChudGhVbmFja25vd2xlZGdlZEFjdGl2aXR5RWxlbWVudCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG50aFVuYWNrbm93bGVkZ2VkQWN0aXZpdHlCb3VuZGluZ0JveEVsZW1lbnQgPSBudGhVbmFja25vd2xlZGdlZEFjdGl2aXR5RWxlbWVudD8ucXVlcnlTZWxlY3RvcihcbiAgICAgICAgICAgICAgICAgICcud2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fYWN0aXZpdHktYWN0aXZlLWRlc2NlbmRhbnQnXG4gICAgICAgICAgICAgICAgKSBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgICAgICAgICBjb25zdCBudGhVbmFja25vd2xlZGdlZEFjdGl2aXR5T2Zmc2V0VG9wID1cbiAgICAgICAgICAgICAgICAgIG50aFVuYWNrbm93bGVkZ2VkQWN0aXZpdHlFbGVtZW50Lm9mZnNldFRvcCArIG50aFVuYWNrbm93bGVkZ2VkQWN0aXZpdHlCb3VuZGluZ0JveEVsZW1lbnQub2Zmc2V0VG9wO1xuXG4gICAgICAgICAgICAgICAgdmFsdWVzLnB1c2goXG4gICAgICAgICAgICAgICAgICBudGhVbmFja25vd2xlZGdlZEFjdGl2aXR5T2Zmc2V0VG9wICtcbiAgICAgICAgICAgICAgICAgICAgbnRoVW5hY2tub3dsZWRnZWRBY3Rpdml0eUJvdW5kaW5nQm94RWxlbWVudC5vZmZzZXRIZWlnaHQgLVxuICAgICAgICAgICAgICAgICAgICBvZmZzZXRIZWlnaHQgLVxuICAgICAgICAgICAgICAgICAgICBzY3JvbGxUb3AgK1xuICAgICAgICAgICAgICAgICAgICBwYXRjaGVkQXV0b1Njcm9sbFNuYXBPbkFjdGl2aXR5T2Zmc2V0XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocGF0Y2hlZEF1dG9TY3JvbGxTbmFwT25QYWdlKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGZpcnN0VW5hY2tub3dsZWRnZWRBY3Rpdml0eUVsZW1lbnQgPSBhY3Rpdml0eUVsZW1lbnRzWytmaXJzdFVuYWNrbm93bGVkZ2VkQWN0aXZpdHlFbGVtZW50SW5kZXhdO1xuICAgICAgICAgICAgICBjb25zdCBmaXJzdFVuYWNrbm93bGVkZ2VkQWN0aXZpdHlCb3VuZGluZ0JveEVsZW1lbnQgPSBmaXJzdFVuYWNrbm93bGVkZ2VkQWN0aXZpdHlFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgICAgICAgICAgICAgJy53ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0X19hY3Rpdml0eS1hY3RpdmUtZGVzY2VuZGFudCdcbiAgICAgICAgICAgICAgKSBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgICAgICAgY29uc3QgZmlyc3RVbmFja25vd2xlZGdlZEFjdGl2aXR5T2Zmc2V0VG9wID1cbiAgICAgICAgICAgICAgICBmaXJzdFVuYWNrbm93bGVkZ2VkQWN0aXZpdHlFbGVtZW50Lm9mZnNldFRvcCArIGZpcnN0VW5hY2tub3dsZWRnZWRBY3Rpdml0eUJvdW5kaW5nQm94RWxlbWVudC5vZmZzZXRUb3A7XG5cbiAgICAgICAgICAgICAgdmFsdWVzLnB1c2goXG4gICAgICAgICAgICAgICAgZmlyc3RVbmFja25vd2xlZGdlZEFjdGl2aXR5T2Zmc2V0VG9wIC1cbiAgICAgICAgICAgICAgICAgIHNjcm9sbFRvcCAtXG4gICAgICAgICAgICAgICAgICBvZmZzZXRIZWlnaHQgKiAoMSAtIHBhdGNoZWRBdXRvU2Nyb2xsU25hcE9uUGFnZSkgK1xuICAgICAgICAgICAgICAgICAgcGF0Y2hlZEF1dG9TY3JvbGxTbmFwT25QYWdlT2Zmc2V0XG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIE1hdGgubWluKC4uLnZhbHVlcyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBJbmZpbml0eTtcbiAgICB9LFxuICAgIFthY3Rpdml0eUVsZW1lbnRNYXBSZWYsIGFjdGl2aXR5S2V5c1JlZiwgbGFzdEFja25vd2xlZGdlZEFjdGl2aXR5S2V5UmVmLCBzdHlsZU9wdGlvbnNSZWZdXG4gICk7XG59O1xuXG50eXBlIEJhc2ljVHJhbnNjcmlwdFByb3BzID0ge1xuICBjbGFzc05hbWU/OiBzdHJpbmc7XG59O1xuXG5jb25zdCBCYXNpY1RyYW5zY3JpcHQ6IFZGQzxCYXNpY1RyYW5zY3JpcHRQcm9wcz4gPSAoeyBjbGFzc05hbWUgfSkgPT4ge1xuICBjb25zdCBhY3Rpdml0eUVsZW1lbnRNYXBSZWYgPSB1c2VSZWY8QWN0aXZpdHlFbGVtZW50TWFwPihuZXcgTWFwKCkpO1xuICBjb25zdCBjb250YWluZXJSZWYgPSB1c2VSZWY8SFRNTERpdkVsZW1lbnQ+KCk7XG5cbiAgY29uc3Qgc2Nyb2xsZXIgPSB1c2VTY3JvbGxlcihhY3Rpdml0eUVsZW1lbnRNYXBSZWYpO1xuXG4gIHJldHVybiAoXG4gICAgPFRyYW5zY3JpcHRGb2N1c0NvbXBvc2VyIGNvbnRhaW5lclJlZj17Y29udGFpbmVyUmVmfT5cbiAgICAgIDxSZWFjdFNjcm9sbFRvQm90dG9tQ29tcG9zZXIgc2Nyb2xsZXI9e3Njcm9sbGVyfT5cbiAgICAgICAgPEtleWJvYXJkSGVscCAvPlxuICAgICAgICA8SW50ZXJuYWxUcmFuc2NyaXB0IGFjdGl2aXR5RWxlbWVudE1hcFJlZj17YWN0aXZpdHlFbGVtZW50TWFwUmVmfSBjbGFzc05hbWU9e2NsYXNzTmFtZX0gcmVmPXtjb250YWluZXJSZWZ9IC8+XG4gICAgICA8L1JlYWN0U2Nyb2xsVG9Cb3R0b21Db21wb3Nlcj5cbiAgICA8L1RyYW5zY3JpcHRGb2N1c0NvbXBvc2VyPlxuICApO1xufTtcblxuQmFzaWNUcmFuc2NyaXB0LmRlZmF1bHRQcm9wcyA9IHtcbiAgY2xhc3NOYW1lOiAnJ1xufTtcblxuQmFzaWNUcmFuc2NyaXB0LnByb3BUeXBlcyA9IHtcbiAgY2xhc3NOYW1lOiBQcm9wVHlwZXMuc3RyaW5nXG59O1xuXG5leHBvcnQgZGVmYXVsdCBCYXNpY1RyYW5zY3JpcHQ7XG4iXX0=