botframework-webchat-component 4.13.0 → 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 (698) hide show
  1. package/.eslintrc.yml +4 -100
  2. package/.prettierrc.yml +1 -1
  3. package/lib/Activity/Avatar.d.ts +10 -0
  4. package/lib/Activity/Avatar.d.ts.map +1 -0
  5. package/lib/Activity/Avatar.js +2 -1
  6. package/lib/Activity/Bubble.d.ts +11 -0
  7. package/lib/Activity/Bubble.d.ts.map +1 -0
  8. package/lib/Activity/Bubble.js +2 -2
  9. package/lib/Activity/CarouselFilmStrip.js +21 -31
  10. package/lib/Activity/CarouselFilmStripAttachment.js +120 -0
  11. package/lib/Activity/CarouselLayout.js +5 -5
  12. package/lib/Activity/Speak.d.ts +10 -0
  13. package/lib/Activity/Speak.d.ts.map +1 -0
  14. package/lib/Activity/Speak.js +11 -13
  15. package/lib/Activity/StackedLayout.d.ts +18 -0
  16. package/lib/Activity/StackedLayout.d.ts.map +1 -0
  17. package/lib/Activity/StackedLayout.js +19 -15
  18. package/lib/Assets/TypingAnimation.js +2 -2
  19. package/lib/Attachment/Assets/DownloadIcon.js +3 -1
  20. package/lib/Attachment/AudioAttachment.js +2 -2
  21. package/lib/Attachment/AudioContent.d.ts +11 -0
  22. package/lib/Attachment/AudioContent.d.ts.map +1 -0
  23. package/lib/Attachment/AudioContent.js +4 -4
  24. package/lib/Attachment/FileAttachment.js +2 -2
  25. package/lib/Attachment/FileContent.d.ts +10 -0
  26. package/lib/Attachment/FileContent.d.ts.map +1 -0
  27. package/lib/Attachment/FileContent.js +14 -9
  28. package/lib/Attachment/HTMLVideoContent.d.ts +11 -0
  29. package/lib/Attachment/HTMLVideoContent.d.ts.map +1 -0
  30. package/lib/Attachment/HTMLVideoContent.js +2 -2
  31. package/lib/Attachment/ImageContent.d.ts +8 -0
  32. package/lib/Attachment/ImageContent.d.ts.map +1 -0
  33. package/lib/Attachment/ImageContent.js +2 -2
  34. package/lib/Attachment/TextContent.d.ts +8 -0
  35. package/lib/Attachment/TextContent.d.ts.map +1 -0
  36. package/lib/Attachment/TextContent.js +4 -4
  37. package/lib/Attachment/VideoAttachment.js +2 -2
  38. package/lib/Attachment/VideoContent.d.ts +11 -0
  39. package/lib/Attachment/VideoContent.d.ts.map +1 -0
  40. package/lib/Attachment/VideoContent.js +1 -1
  41. package/lib/Attachment/VimeoContent.d.ts +10 -0
  42. package/lib/Attachment/VimeoContent.d.ts.map +1 -0
  43. package/lib/Attachment/VimeoContent.js +8 -8
  44. package/lib/Attachment/YouTubeContent.d.ts +10 -0
  45. package/lib/Attachment/YouTubeContent.d.ts.map +1 -0
  46. package/lib/Attachment/YouTubeContent.js +5 -5
  47. package/lib/Avatar/ImageAvatar.js +2 -2
  48. package/lib/Avatar/InitialsAvatar.js +2 -2
  49. package/lib/BasicConnectivityStatus.js +2 -2
  50. package/lib/BasicSendBox.d.ts +9 -0
  51. package/lib/BasicSendBox.d.ts.map +1 -0
  52. package/lib/BasicSendBox.js +7 -6
  53. package/lib/BasicToast.js +4 -4
  54. package/lib/BasicToaster.js +8 -5
  55. package/lib/BasicTranscript.d.ts +7 -0
  56. package/lib/BasicTranscript.d.ts.map +1 -0
  57. package/lib/BasicTranscript.js +406 -743
  58. package/lib/BasicTypingIndicator.d.ts +6 -0
  59. package/lib/BasicTypingIndicator.d.ts.map +1 -0
  60. package/lib/BasicTypingIndicator.js +13 -5
  61. package/lib/BasicWebChat.d.ts +9 -0
  62. package/lib/BasicWebChat.d.ts.map +1 -0
  63. package/lib/BasicWebChat.js +6 -4
  64. package/lib/Composer.d.ts +23 -0
  65. package/lib/Composer.d.ts.map +1 -0
  66. package/lib/Composer.js +65 -82
  67. package/lib/ConnectivityStatus/Assets/ErrorNotificationIcon.js +2 -2
  68. package/lib/ConnectivityStatus/Assets/SpinnerAnimation.js +2 -2
  69. package/lib/ConnectivityStatus/Assets/WarningNotificationIcon.js +2 -2
  70. package/lib/ConnectivityStatus/Connected.js +1 -1
  71. package/lib/ConnectivityStatus/Connecting.js +4 -4
  72. package/lib/ConnectivityStatus/FailedToConnect.js +2 -2
  73. package/lib/ConnectivityStatus/JavaScriptError.js +2 -2
  74. package/lib/Dictation.js +13 -4
  75. package/lib/ErrorBox.d.ts +8 -0
  76. package/lib/ErrorBox.d.ts.map +1 -0
  77. package/lib/ErrorBox.js +2 -2
  78. package/lib/Middleware/Activity/createCoreMiddleware.d.ts +3 -0
  79. package/lib/Middleware/Activity/createCoreMiddleware.d.ts.map +1 -0
  80. package/lib/Middleware/Activity/createCoreMiddleware.js +1 -1
  81. package/lib/Middleware/ActivityStatus/AbsoluteTime.js +1 -1
  82. package/lib/Middleware/ActivityStatus/RelativeTime.js +1 -1
  83. package/lib/Middleware/ActivityStatus/SendStatus/SendFailedRetry.js +3 -3
  84. package/lib/Middleware/ActivityStatus/SendStatus/SendStatus.d.ts +11 -0
  85. package/lib/Middleware/ActivityStatus/SendStatus/SendStatus.d.ts.map +1 -0
  86. package/lib/Middleware/ActivityStatus/SendStatus/SendStatus.js +5 -5
  87. package/lib/Middleware/ActivityStatus/Timestamp.d.ts +9 -0
  88. package/lib/Middleware/ActivityStatus/Timestamp.d.ts.map +1 -0
  89. package/lib/Middleware/ActivityStatus/Timestamp.js +2 -2
  90. package/lib/Middleware/ActivityStatus/createCoreMiddleware.d.ts +3 -0
  91. package/lib/Middleware/ActivityStatus/createCoreMiddleware.d.ts.map +1 -0
  92. package/lib/Middleware/ActivityStatus/createCoreMiddleware.js +1 -1
  93. package/lib/Middleware/ActivityStatus/createSendStatusMiddleware.js +21 -16
  94. package/lib/Middleware/ActivityStatus/createTimestampMiddleware.js +1 -1
  95. package/lib/Middleware/Attachment/createCoreMiddleware.d.ts +3 -0
  96. package/lib/Middleware/Attachment/createCoreMiddleware.d.ts.map +1 -0
  97. package/lib/Middleware/Attachment/createCoreMiddleware.js +10 -13
  98. package/lib/Middleware/AttachmentForScreenReader/AudioAttachment.js +1 -1
  99. package/lib/Middleware/AttachmentForScreenReader/FileAttachment.js +1 -1
  100. package/lib/Middleware/AttachmentForScreenReader/ImageAttachment.js +1 -1
  101. package/lib/Middleware/AttachmentForScreenReader/TextAttachment.js +1 -1
  102. package/lib/Middleware/AttachmentForScreenReader/VideoAttachment.js +1 -1
  103. package/lib/Middleware/AttachmentForScreenReader/createCoreMiddleware.d.ts +3 -0
  104. package/lib/Middleware/AttachmentForScreenReader/createCoreMiddleware.d.ts.map +1 -0
  105. package/lib/Middleware/AttachmentForScreenReader/createCoreMiddleware.js +9 -5
  106. package/lib/Middleware/Avatar/createCoreMiddleware.d.ts +11 -0
  107. package/lib/Middleware/Avatar/createCoreMiddleware.d.ts.map +1 -0
  108. package/lib/Middleware/Avatar/createCoreMiddleware.js +3 -4
  109. package/lib/Middleware/CardAction/createCoreMiddleware.js +11 -4
  110. package/lib/Middleware/GroupActivities/createCoreMiddleware.js +1 -1
  111. package/lib/Middleware/ScrollToEndButton/ScrollToEndButton.js +71 -0
  112. package/lib/Middleware/ScrollToEndButton/createScrollToEndButtonMiddleware.d.ts +3 -0
  113. package/lib/Middleware/ScrollToEndButton/createScrollToEndButtonMiddleware.d.ts.map +1 -0
  114. package/lib/Middleware/ScrollToEndButton/createScrollToEndButtonMiddleware.js +27 -0
  115. package/lib/Middleware/Toast/createCoreMiddleware.d.ts +4 -0
  116. package/lib/Middleware/Toast/createCoreMiddleware.d.ts.map +1 -0
  117. package/lib/Middleware/Toast/createCoreMiddleware.js +1 -1
  118. package/lib/Middleware/TypingIndicator/createCoreMiddleware.d.ts +3 -0
  119. package/lib/Middleware/TypingIndicator/createCoreMiddleware.d.ts.map +1 -0
  120. package/lib/Middleware/TypingIndicator/createCoreMiddleware.js +9 -6
  121. package/lib/ReactWebChat.d.ts +10 -0
  122. package/lib/ReactWebChat.d.ts.map +1 -0
  123. package/lib/ReactWebChat.js +19 -7
  124. package/lib/ScreenReaderActivity.js +76 -48
  125. package/lib/ScreenReaderText.d.ts +9 -0
  126. package/lib/ScreenReaderText.d.ts.map +1 -0
  127. package/lib/ScreenReaderText.js +22 -8
  128. package/lib/SendBox/Assets/AttachmentIcon.js +3 -1
  129. package/lib/SendBox/Assets/MicrophoneIcon.js +3 -1
  130. package/lib/SendBox/Assets/SendIcon.js +2 -2
  131. package/lib/SendBox/AutoResizeTextArea.d.ts +23 -0
  132. package/lib/SendBox/AutoResizeTextArea.d.ts.map +1 -0
  133. package/lib/SendBox/AutoResizeTextArea.js +6 -6
  134. package/lib/SendBox/DictationInterims.d.ts +9 -0
  135. package/lib/SendBox/DictationInterims.d.ts.map +1 -0
  136. package/lib/SendBox/DictationInterims.js +3 -3
  137. package/lib/SendBox/IconButton.d.ts +11 -0
  138. package/lib/SendBox/IconButton.d.ts.map +1 -0
  139. package/lib/SendBox/IconButton.js +27 -7
  140. package/lib/SendBox/MicrophoneButton.d.ts +11 -0
  141. package/lib/SendBox/MicrophoneButton.d.ts.map +1 -0
  142. package/lib/SendBox/MicrophoneButton.js +25 -24
  143. package/lib/SendBox/SendButton.d.ts +9 -0
  144. package/lib/SendBox/SendButton.d.ts.map +1 -0
  145. package/lib/SendBox/SendButton.js +8 -6
  146. package/lib/SendBox/SuggestedAction.d.ts +17 -0
  147. package/lib/SendBox/SuggestedAction.d.ts.map +1 -0
  148. package/lib/SendBox/SuggestedAction.js +29 -24
  149. package/lib/SendBox/SuggestedActions.d.ts +5 -0
  150. package/lib/SendBox/SuggestedActions.d.ts.map +1 -0
  151. package/lib/SendBox/SuggestedActions.js +33 -13
  152. package/lib/SendBox/TextBox.d.ts +28 -0
  153. package/lib/SendBox/TextBox.d.ts.map +1 -0
  154. package/lib/SendBox/TextBox.js +13 -8
  155. package/lib/SendBox/UploadButton.d.ts +9 -0
  156. package/lib/SendBox/UploadButton.d.ts.map +1 -0
  157. package/lib/SendBox/UploadButton.js +6 -6
  158. package/lib/Styles/StyleSet/Activities.d.ts +5 -0
  159. package/lib/Styles/StyleSet/Activities.d.ts.map +1 -0
  160. package/lib/Styles/StyleSet/AudioAttachment.d.ts +6 -0
  161. package/lib/Styles/StyleSet/AudioAttachment.d.ts.map +1 -0
  162. package/lib/Styles/StyleSet/AudioContent.d.ts +4 -0
  163. package/lib/Styles/StyleSet/AudioContent.d.ts.map +1 -0
  164. package/lib/Styles/StyleSet/AutoResizeTextArea.d.ts +37 -0
  165. package/lib/Styles/StyleSet/AutoResizeTextArea.d.ts.map +1 -0
  166. package/lib/Styles/StyleSet/Avatar.d.ts +9 -0
  167. package/lib/Styles/StyleSet/Avatar.d.ts.map +1 -0
  168. package/lib/Styles/StyleSet/BasicTranscript.d.ts +85 -0
  169. package/lib/Styles/StyleSet/BasicTranscript.d.ts.map +1 -0
  170. package/lib/Styles/StyleSet/BasicTranscript.js +21 -9
  171. package/lib/Styles/StyleSet/Bubble.d.ts +5 -0
  172. package/lib/Styles/StyleSet/Bubble.d.ts.map +1 -0
  173. package/lib/Styles/StyleSet/Bubble.js +2 -2
  174. package/lib/Styles/StyleSet/CarouselFilmStrip.d.ts +5 -0
  175. package/lib/Styles/StyleSet/CarouselFilmStrip.d.ts.map +1 -0
  176. package/lib/Styles/StyleSet/CarouselFilmStrip.js +2 -18
  177. package/lib/Styles/StyleSet/CarouselFilmStripAttachment.d.ts +3 -0
  178. package/lib/Styles/StyleSet/CarouselFilmStripAttachment.d.ts.map +1 -0
  179. package/lib/Styles/StyleSet/CarouselFilmStripAttachment.js +63 -0
  180. package/lib/Styles/StyleSet/CarouselFlipper.d.ts +27 -0
  181. package/lib/Styles/StyleSet/CarouselFlipper.d.ts.map +1 -0
  182. package/lib/Styles/StyleSet/ConnectivityNotification.d.ts +13 -0
  183. package/lib/Styles/StyleSet/ConnectivityNotification.d.ts.map +1 -0
  184. package/lib/Styles/StyleSet/DictationInterims.d.ts +13 -0
  185. package/lib/Styles/StyleSet/DictationInterims.d.ts.map +1 -0
  186. package/lib/Styles/StyleSet/ErrorBox.d.ts +33 -0
  187. package/lib/Styles/StyleSet/ErrorBox.d.ts.map +1 -0
  188. package/lib/Styles/StyleSet/ErrorNotification.d.ts +23 -0
  189. package/lib/Styles/StyleSet/ErrorNotification.d.ts.map +1 -0
  190. package/lib/Styles/StyleSet/FileContent.d.ts +32 -0
  191. package/lib/Styles/StyleSet/FileContent.d.ts.map +1 -0
  192. package/lib/Styles/StyleSet/ImageAvatar.d.ts +7 -0
  193. package/lib/Styles/StyleSet/ImageAvatar.d.ts.map +1 -0
  194. package/lib/Styles/StyleSet/InitialsAvatar.d.ts +19 -0
  195. package/lib/Styles/StyleSet/InitialsAvatar.d.ts.map +1 -0
  196. package/lib/Styles/StyleSet/KeyboardHelp.d.ts +123 -0
  197. package/lib/Styles/StyleSet/KeyboardHelp.d.ts.map +1 -0
  198. package/lib/Styles/StyleSet/KeyboardHelp.js +145 -0
  199. package/lib/Styles/StyleSet/MicrophoneButton.d.ts +13 -0
  200. package/lib/Styles/StyleSet/MicrophoneButton.d.ts.map +1 -0
  201. package/lib/Styles/StyleSet/Root.d.ts +8 -0
  202. package/lib/Styles/StyleSet/Root.d.ts.map +1 -0
  203. package/lib/Styles/StyleSet/ScrollToEndButton.d.ts +36 -0
  204. package/lib/Styles/StyleSet/ScrollToEndButton.d.ts.map +1 -0
  205. package/lib/Styles/StyleSet/ScrollToEndButton.js +36 -34
  206. package/lib/Styles/StyleSet/SendBox.d.ts +24 -0
  207. package/lib/Styles/StyleSet/SendBox.d.ts.map +1 -0
  208. package/lib/Styles/StyleSet/SendBoxButton.d.ts +79 -0
  209. package/lib/Styles/StyleSet/SendBoxButton.d.ts.map +1 -0
  210. package/lib/Styles/StyleSet/SendBoxButton.js +76 -12
  211. package/lib/Styles/StyleSet/SendBoxTextBox.d.ts +41 -0
  212. package/lib/Styles/StyleSet/SendBoxTextBox.d.ts.map +1 -0
  213. package/lib/Styles/StyleSet/SendBoxTextBox.js +3 -3
  214. package/lib/Styles/StyleSet/SendStatus.d.ts +8 -0
  215. package/lib/Styles/StyleSet/SendStatus.d.ts.map +1 -0
  216. package/lib/Styles/StyleSet/SingleAttachmentActivity.d.ts +11 -0
  217. package/lib/Styles/StyleSet/SingleAttachmentActivity.d.ts.map +1 -0
  218. package/lib/Styles/StyleSet/SpinnerAnimation.d.ts +15 -0
  219. package/lib/Styles/StyleSet/SpinnerAnimation.d.ts.map +1 -0
  220. package/lib/Styles/StyleSet/StackedLayout.d.ts +63 -0
  221. package/lib/Styles/StyleSet/StackedLayout.d.ts.map +1 -0
  222. package/lib/Styles/StyleSet/StackedLayout.js +1 -1
  223. package/lib/Styles/StyleSet/SuggestedAction.d.ts +94 -0
  224. package/lib/Styles/StyleSet/SuggestedAction.d.ts.map +1 -0
  225. package/lib/Styles/StyleSet/SuggestedAction.js +116 -41
  226. package/lib/Styles/StyleSet/SuggestedActions.d.ts +125 -0
  227. package/lib/Styles/StyleSet/SuggestedActions.d.ts.map +1 -0
  228. package/lib/Styles/StyleSet/SuggestedActions.js +13 -6
  229. package/lib/Styles/StyleSet/TextContent.d.ts +28 -0
  230. package/lib/Styles/StyleSet/TextContent.d.ts.map +1 -0
  231. package/lib/Styles/StyleSet/Toast.d.ts +65 -0
  232. package/lib/Styles/StyleSet/Toast.d.ts.map +1 -0
  233. package/lib/Styles/StyleSet/Toaster.d.ts +111 -0
  234. package/lib/Styles/StyleSet/Toaster.d.ts.map +1 -0
  235. package/lib/Styles/StyleSet/TypingAnimation.d.ts +8 -0
  236. package/lib/Styles/StyleSet/TypingAnimation.d.ts.map +1 -0
  237. package/lib/Styles/StyleSet/TypingIndicator.d.ts +11 -0
  238. package/lib/Styles/StyleSet/TypingIndicator.d.ts.map +1 -0
  239. package/lib/Styles/StyleSet/UploadButton.d.ts +14 -0
  240. package/lib/Styles/StyleSet/UploadButton.d.ts.map +1 -0
  241. package/lib/Styles/StyleSet/VideoAttachment.d.ts +2 -0
  242. package/lib/Styles/StyleSet/VideoAttachment.d.ts.map +1 -0
  243. package/lib/Styles/StyleSet/VideoContent.d.ts +6 -0
  244. package/lib/Styles/StyleSet/VideoContent.d.ts.map +1 -0
  245. package/lib/Styles/StyleSet/VimeoContent.d.ts +7 -0
  246. package/lib/Styles/StyleSet/VimeoContent.d.ts.map +1 -0
  247. package/lib/Styles/StyleSet/WarningNotification.d.ts +22 -0
  248. package/lib/Styles/StyleSet/WarningNotification.d.ts.map +1 -0
  249. package/lib/Styles/StyleSet/YouTubeContent.d.ts +7 -0
  250. package/lib/Styles/StyleSet/YouTubeContent.d.ts.map +1 -0
  251. package/lib/Styles/createStyleSet.d.ts +1372 -0
  252. package/lib/Styles/createStyleSet.d.ts.map +1 -0
  253. package/lib/Styles/createStyleSet.js +47 -41
  254. package/lib/Styles/mirrorStyle.js +13 -4
  255. package/lib/Toast/CollapseIcon.js +3 -1
  256. package/lib/Toast/DismissIcon.js +3 -1
  257. package/lib/Toast/ExpandIcon.js +3 -1
  258. package/lib/Toast/NotificationIcon.js +7 -3
  259. package/lib/Toast/createToastMiddleware.d.ts +4 -0
  260. package/lib/Toast/createToastMiddleware.d.ts.map +1 -0
  261. package/lib/Toast/createToastMiddleware.js +2 -2
  262. package/lib/Transcript/ActivityRow.d.ts +9 -0
  263. package/lib/Transcript/ActivityRow.d.ts.map +1 -0
  264. package/lib/Transcript/ActivityRow.js +157 -0
  265. package/lib/Transcript/ActivityTextAlt.js +57 -0
  266. package/lib/Transcript/FocusTrap.d.ts +8 -0
  267. package/lib/Transcript/FocusTrap.d.ts.map +1 -0
  268. package/lib/Transcript/FocusTrap.js +74 -0
  269. package/lib/Transcript/KeyboardHelp.d.ts +4 -0
  270. package/lib/Transcript/KeyboardHelp.d.ts.map +1 -0
  271. package/lib/Transcript/KeyboardHelp.js +550 -0
  272. package/lib/Transcript/LiveRegionTranscript.d.ts +8 -0
  273. package/lib/Transcript/LiveRegionTranscript.d.ts.map +1 -0
  274. package/lib/Transcript/LiveRegionTranscript.js +214 -0
  275. package/lib/Transcript/types.d.ts +2 -0
  276. package/lib/Transcript/types.d.ts.map +1 -0
  277. package/lib/Transcript/types.js +2 -0
  278. package/lib/Transcript/useActivityAccessibleName.d.ts +4 -0
  279. package/lib/Transcript/useActivityAccessibleName.d.ts.map +1 -0
  280. package/lib/Transcript/useActivityAccessibleName.js +97 -0
  281. package/lib/Utils/AccessKeySink/Surface.js +7 -5
  282. package/lib/Utils/AccessibleButton.d.ts +11 -0
  283. package/lib/Utils/AccessibleButton.d.ts.map +1 -0
  284. package/lib/Utils/AccessibleButton.js +15 -8
  285. package/lib/Utils/AccessibleInputText.d.ts +21 -0
  286. package/lib/Utils/AccessibleInputText.d.ts.map +1 -0
  287. package/lib/Utils/AccessibleInputText.js +29 -25
  288. package/lib/Utils/AccessibleTextArea.d.ts +20 -0
  289. package/lib/Utils/AccessibleTextArea.d.ts.map +1 -0
  290. package/lib/Utils/AccessibleTextArea.js +35 -24
  291. package/lib/Utils/CroppedImage.js +2 -2
  292. package/lib/Utils/Fade.js +2 -2
  293. package/lib/Utils/FocusRedirector.d.ts +9 -0
  294. package/lib/Utils/FocusRedirector.d.ts.map +1 -0
  295. package/lib/Utils/FocusRedirector.js +18 -15
  296. package/lib/Utils/InlineMarkdown.js +17 -10
  297. package/lib/Utils/TypeFocusSink/FocusBox.js +6 -4
  298. package/lib/Utils/TypeFocusSink/getTabIndex.d.ts +2 -0
  299. package/lib/Utils/TypeFocusSink/getTabIndex.d.ts.map +1 -0
  300. package/lib/Utils/TypeFocusSink/getTabIndex.js +1 -1
  301. package/lib/Utils/TypeFocusSink/inputtableKey.d.ts +2 -0
  302. package/lib/Utils/TypeFocusSink/inputtableKey.d.ts.map +1 -0
  303. package/lib/Utils/TypeFocusSink/inputtableKey.js +5 -2
  304. package/lib/Utils/TypeFocusSink/navigableEvent.js +1 -1
  305. package/lib/Utils/activityAltText.d.ts +8 -0
  306. package/lib/Utils/activityAltText.d.ts.map +1 -0
  307. package/lib/Utils/activityAltText.js +100 -0
  308. package/lib/Utils/addTargetBlankToHyperlinksMarkdown.js +1 -1
  309. package/lib/Utils/createCustomEvent.js +9 -3
  310. package/lib/Utils/debounce.js +1 -1
  311. package/lib/Utils/detectBrowser.js +4 -2
  312. package/lib/Utils/downscaleImageToDataURL/downscaleImageToDataURLUsingWorker.js +3 -3
  313. package/lib/Utils/downscaleImageToDataURL/index.js +2 -2
  314. package/lib/Utils/filterMap.js +1 -1
  315. package/lib/Utils/findAncestor.js +17 -0
  316. package/lib/Utils/getActivityUniqueId.js +4 -2
  317. package/lib/Utils/intersectionOf.d.ts +5 -0
  318. package/lib/Utils/intersectionOf.d.ts.map +1 -0
  319. package/lib/Utils/intersectionOf.js +17 -2
  320. package/lib/Utils/isZeroOrPositive.d.ts +5 -0
  321. package/lib/Utils/isZeroOrPositive.d.ts.map +1 -0
  322. package/lib/Utils/isZeroOrPositive.js +4 -1
  323. package/lib/Utils/mapMap.js +10 -3
  324. package/lib/Utils/readDataURIToBlob.js +3 -3
  325. package/lib/Utils/scrollIntoViewWithBlockNearest.d.ts +7 -0
  326. package/lib/Utils/scrollIntoViewWithBlockNearest.d.ts.map +1 -0
  327. package/lib/Utils/scrollIntoViewWithBlockNearest.js +48 -0
  328. package/lib/Utils/shallowEquals.js +7 -3
  329. package/lib/Utils/singleToArray.js +1 -1
  330. package/lib/Utils/supportPseudoClass.d.ts +2 -0
  331. package/lib/Utils/supportPseudoClass.d.ts.map +1 -0
  332. package/lib/Utils/supportPseudoClass.js +23 -0
  333. package/lib/Utils/tabbableElements.d.ts +2 -0
  334. package/lib/Utils/tabbableElements.d.ts.map +1 -0
  335. package/lib/Utils/tabbableElements.js +2 -2
  336. package/lib/connectToWebChat.js +17 -7
  337. package/lib/hooks/index.d.ts +21 -0
  338. package/lib/hooks/index.d.ts.map +1 -0
  339. package/lib/hooks/index.js +25 -25
  340. package/lib/hooks/internal/BypassSpeechSynthesisPonyfill.js +100 -41
  341. package/lib/hooks/internal/UITracker.js +2 -2
  342. package/lib/hooks/internal/useChanged.js +8 -1
  343. package/lib/hooks/internal/useDispatchScrollPosition.js +3 -7
  344. package/lib/hooks/internal/useDispatchTranscriptFocusByActivityKey.d.ts +2 -0
  345. package/lib/hooks/internal/useDispatchTranscriptFocusByActivityKey.d.ts.map +1 -0
  346. package/lib/hooks/internal/useDispatchTranscriptFocusByActivityKey.js +15 -0
  347. package/lib/hooks/internal/useEnterKeyHint.js +1 -1
  348. package/lib/hooks/internal/useFocusVisible.d.ts +3 -0
  349. package/lib/hooks/internal/useFocusVisible.d.ts.map +1 -0
  350. package/lib/hooks/internal/useFocusVisible.js +48 -0
  351. package/lib/hooks/internal/useForceRender.js +2 -2
  352. package/lib/hooks/internal/useForceRenderAtInterval.js +2 -2
  353. package/lib/hooks/internal/useInternalRenderMarkdownInline.js +1 -1
  354. package/lib/hooks/internal/useLocalizeAccessKey.js +2 -2
  355. package/lib/hooks/internal/useMemoWithPrevious.d.ts +3 -0
  356. package/lib/hooks/internal/useMemoWithPrevious.d.ts.map +1 -0
  357. package/lib/hooks/internal/useMemoWithPrevious.js +22 -0
  358. package/lib/hooks/internal/useMemoize.d.ts +14 -0
  359. package/lib/hooks/internal/useMemoize.d.ts.map +1 -0
  360. package/lib/hooks/internal/useMemoize.js +12 -3
  361. package/lib/hooks/internal/useNavigatorPlatform.js +1 -1
  362. package/lib/hooks/internal/useNonce.js +1 -1
  363. package/lib/hooks/internal/useObserveFocusVisible.d.ts +3 -0
  364. package/lib/hooks/internal/useObserveFocusVisible.d.ts.map +1 -0
  365. package/lib/hooks/internal/useObserveFocusVisible.js +208 -0
  366. package/lib/hooks/internal/usePrevious.d.ts +2 -0
  367. package/lib/hooks/internal/usePrevious.d.ts.map +1 -0
  368. package/lib/hooks/internal/usePrevious.js +18 -0
  369. package/lib/hooks/internal/useRegisterFocusSendBox.js +1 -1
  370. package/lib/hooks/internal/useRegisterFocusTranscript.js +1 -1
  371. package/lib/hooks/internal/useRegisterScrollRelative.js +1 -1
  372. package/lib/hooks/internal/useRegisterScrollTo.js +1 -1
  373. package/lib/hooks/internal/useRegisterScrollToEnd.js +1 -1
  374. package/lib/hooks/internal/useReplaceEmoticon.js +2 -2
  375. package/lib/hooks/internal/useResumeAudioContext.js +33 -0
  376. package/lib/hooks/internal/useScrollRelative.js +1 -1
  377. package/lib/hooks/internal/useSettableDictateAbortable.js +1 -1
  378. package/lib/hooks/internal/useStateRef.d.ts +3 -0
  379. package/lib/hooks/internal/useStateRef.d.ts.map +1 -0
  380. package/lib/hooks/internal/useStateRef.js +40 -0
  381. package/lib/hooks/internal/useSuggestedActionsAccessKey.js +1 -1
  382. package/lib/hooks/internal/useUniqueId.d.ts +2 -0
  383. package/lib/hooks/internal/useUniqueId.d.ts.map +1 -0
  384. package/lib/hooks/internal/useUniqueId.js +1 -1
  385. package/lib/hooks/internal/useValueRef.d.ts +3 -0
  386. package/lib/hooks/internal/useValueRef.d.ts.map +1 -0
  387. package/lib/hooks/internal/useValueRef.js +25 -0
  388. package/lib/hooks/useDictateAbortable.d.ts +2 -0
  389. package/lib/hooks/useDictateAbortable.d.ts.map +1 -0
  390. package/lib/hooks/useDictateAbortable.js +2 -2
  391. package/lib/hooks/useFocus.d.ts +2 -0
  392. package/lib/hooks/useFocus.d.ts.map +1 -0
  393. package/lib/hooks/useFocus.js +1 -1
  394. package/lib/hooks/useFocusSendBox.d.ts +3 -0
  395. package/lib/hooks/useFocusSendBox.d.ts.map +1 -0
  396. package/lib/hooks/useFocusSendBox.js +2 -1
  397. package/lib/hooks/useObserveScrollPosition.d.ts +3 -0
  398. package/lib/hooks/useObserveScrollPosition.d.ts.map +1 -0
  399. package/lib/hooks/useObserveScrollPosition.js +2 -2
  400. package/lib/hooks/useObserveTranscriptFocus.d.ts +5 -0
  401. package/lib/hooks/useObserveTranscriptFocus.d.ts.map +1 -0
  402. package/lib/hooks/useObserveTranscriptFocus.js +2 -2
  403. package/lib/hooks/useRenderMarkdownAsHTML.d.ts +5 -0
  404. package/lib/hooks/useRenderMarkdownAsHTML.d.ts.map +1 -0
  405. package/lib/hooks/useRenderMarkdownAsHTML.js +2 -2
  406. package/lib/hooks/useScrollDown.d.ts +4 -0
  407. package/lib/hooks/useScrollDown.d.ts.map +1 -0
  408. package/lib/hooks/useScrollDown.js +1 -1
  409. package/lib/hooks/useScrollTo.d.ts +5 -0
  410. package/lib/hooks/useScrollTo.d.ts.map +1 -0
  411. package/lib/hooks/useScrollTo.js +1 -1
  412. package/lib/hooks/useScrollToEnd.d.ts +2 -0
  413. package/lib/hooks/useScrollToEnd.d.ts.map +1 -0
  414. package/lib/hooks/useScrollToEnd.js +1 -1
  415. package/lib/hooks/useScrollUp.d.ts +4 -0
  416. package/lib/hooks/useScrollUp.d.ts.map +1 -0
  417. package/lib/hooks/useScrollUp.js +1 -1
  418. package/lib/hooks/useSendFiles.d.ts +2 -0
  419. package/lib/hooks/useSendFiles.d.ts.map +1 -0
  420. package/lib/hooks/useSendFiles.js +3 -3
  421. package/lib/hooks/useStyleSet.d.ts +2 -0
  422. package/lib/hooks/useStyleSet.d.ts.map +1 -0
  423. package/lib/hooks/useStyleSet.js +1 -1
  424. package/lib/hooks/useWebSpeechPonyfill.d.ts +3 -0
  425. package/lib/hooks/useWebSpeechPonyfill.d.ts.map +1 -0
  426. package/lib/hooks/useWebSpeechPonyfill.js +1 -1
  427. package/lib/index.d.ts +219 -22
  428. package/lib/index.d.ts.map +1 -1
  429. package/lib/index.js +22 -20
  430. package/lib/providers/ActivityTree/ActivityTreeComposer.d.ts +5 -0
  431. package/lib/providers/ActivityTree/ActivityTreeComposer.d.ts.map +1 -0
  432. package/lib/providers/ActivityTree/ActivityTreeComposer.js +86 -0
  433. package/lib/providers/ActivityTree/private/Context.d.ts +9 -0
  434. package/lib/providers/ActivityTree/private/Context.d.ts.map +1 -0
  435. package/lib/providers/ActivityTree/private/Context.js +13 -0
  436. package/lib/providers/ActivityTree/private/types.d.ts +10 -0
  437. package/lib/providers/ActivityTree/private/types.d.ts.map +1 -0
  438. package/lib/providers/ActivityTree/private/types.js +2 -0
  439. package/lib/providers/ActivityTree/private/useActivitiesWithRenderer.d.ts +4 -0
  440. package/lib/providers/ActivityTree/private/useActivitiesWithRenderer.d.ts.map +1 -0
  441. package/lib/providers/ActivityTree/private/useActivitiesWithRenderer.js +58 -0
  442. package/lib/providers/ActivityTree/private/useActivityTreeWithRenderer.d.ts +5 -0
  443. package/lib/providers/ActivityTree/private/useActivityTreeWithRenderer.d.ts.map +1 -0
  444. package/lib/providers/ActivityTree/private/useActivityTreeWithRenderer.js +166 -0
  445. package/lib/providers/ActivityTree/private/useContext.d.ts +3 -0
  446. package/lib/providers/ActivityTree/private/useContext.d.ts.map +1 -0
  447. package/lib/providers/ActivityTree/private/useContext.js +24 -0
  448. package/lib/providers/ActivityTree/useActivityTreeWithRenderer.d.ts +8 -0
  449. package/lib/providers/ActivityTree/useActivityTreeWithRenderer.d.ts.map +1 -0
  450. package/lib/providers/ActivityTree/useActivityTreeWithRenderer.js +17 -0
  451. package/lib/providers/LiveRegionTwin/LiveRegionTwinComposer.d.ts +35 -0
  452. package/lib/providers/LiveRegionTwin/LiveRegionTwinComposer.d.ts.map +1 -0
  453. package/lib/providers/LiveRegionTwin/LiveRegionTwinComposer.js +156 -0
  454. package/lib/providers/LiveRegionTwin/private/Context.d.ts +10 -0
  455. package/lib/providers/LiveRegionTwin/private/Context.d.ts.map +1 -0
  456. package/lib/providers/LiveRegionTwin/private/Context.js +13 -0
  457. package/lib/providers/LiveRegionTwin/private/LiveRegionTwinContainer.d.ts +11 -0
  458. package/lib/providers/LiveRegionTwin/private/LiveRegionTwinContainer.d.ts.map +1 -0
  459. package/lib/providers/LiveRegionTwin/private/LiveRegionTwinContainer.js +86 -0
  460. package/lib/providers/LiveRegionTwin/private/types.d.ts +8 -0
  461. package/lib/providers/LiveRegionTwin/private/types.d.ts.map +1 -0
  462. package/lib/providers/LiveRegionTwin/private/types.js +2 -0
  463. package/lib/providers/LiveRegionTwin/private/useContext.d.ts +3 -0
  464. package/lib/providers/LiveRegionTwin/private/useContext.d.ts.map +1 -0
  465. package/lib/providers/LiveRegionTwin/private/useContext.js +24 -0
  466. package/lib/providers/LiveRegionTwin/private/useMarkAllAsRenderedEffect.d.ts +2 -0
  467. package/lib/providers/LiveRegionTwin/private/useMarkAllAsRenderedEffect.d.ts.map +1 -0
  468. package/lib/providers/LiveRegionTwin/private/useMarkAllAsRenderedEffect.js +24 -0
  469. package/lib/providers/LiveRegionTwin/private/useStaticElementEntries.d.ts +3 -0
  470. package/lib/providers/LiveRegionTwin/private/useStaticElementEntries.d.ts.map +1 -0
  471. package/lib/providers/LiveRegionTwin/private/useStaticElementEntries.js +15 -0
  472. package/lib/providers/LiveRegionTwin/useQueueStaticElement.d.ts +8 -0
  473. package/lib/providers/LiveRegionTwin/useQueueStaticElement.d.ts.map +1 -0
  474. package/lib/providers/LiveRegionTwin/useQueueStaticElement.js +20 -0
  475. package/lib/providers/TranscriptFocus/TranscriptFocusComposer.d.ts +7 -0
  476. package/lib/providers/TranscriptFocus/TranscriptFocusComposer.d.ts.map +1 -0
  477. package/lib/providers/TranscriptFocus/TranscriptFocusComposer.js +184 -0
  478. package/lib/providers/TranscriptFocus/private/Context.d.ts +12 -0
  479. package/lib/providers/TranscriptFocus/private/Context.d.ts.map +1 -0
  480. package/lib/providers/TranscriptFocus/private/Context.js +13 -0
  481. package/lib/providers/TranscriptFocus/private/useContext.d.ts +2 -0
  482. package/lib/providers/TranscriptFocus/private/useContext.d.ts.map +1 -0
  483. package/lib/providers/TranscriptFocus/private/useContext.js +24 -0
  484. package/lib/providers/TranscriptFocus/useActiveDescendantId.d.ts +2 -0
  485. package/lib/providers/TranscriptFocus/useActiveDescendantId.d.ts.map +1 -0
  486. package/lib/providers/TranscriptFocus/useActiveDescendantId.js +15 -0
  487. package/lib/providers/TranscriptFocus/useFocusByActivityKey.d.ts +8 -0
  488. package/lib/providers/TranscriptFocus/useFocusByActivityKey.d.ts.map +1 -0
  489. package/lib/providers/TranscriptFocus/useFocusByActivityKey.js +21 -0
  490. package/lib/providers/TranscriptFocus/useFocusRelativeActivity.d.ts +2 -0
  491. package/lib/providers/TranscriptFocus/useFocusRelativeActivity.d.ts.map +1 -0
  492. package/lib/providers/TranscriptFocus/useFocusRelativeActivity.js +15 -0
  493. package/lib/providers/TranscriptFocus/useFocusedActivityKey.d.ts +2 -0
  494. package/lib/providers/TranscriptFocus/useFocusedActivityKey.d.ts.map +1 -0
  495. package/lib/providers/TranscriptFocus/useFocusedActivityKey.js +15 -0
  496. package/lib/providers/TranscriptFocus/useFocusedExplicitly.d.ts +2 -0
  497. package/lib/providers/TranscriptFocus/useFocusedExplicitly.d.ts.map +1 -0
  498. package/lib/providers/TranscriptFocus/useFocusedExplicitly.js +15 -0
  499. package/lib/providers/TranscriptFocus/useGetDescendantIdByActivityKey.d.ts +2 -0
  500. package/lib/providers/TranscriptFocus/useGetDescendantIdByActivityKey.d.ts.map +1 -0
  501. package/lib/providers/TranscriptFocus/useGetDescendantIdByActivityKey.js +15 -0
  502. package/lib/tsconfig.json +1 -1
  503. package/lib/types/ScrollPosition.d.ts +6 -0
  504. package/lib/types/ScrollPosition.d.ts.map +1 -0
  505. package/lib/types/ScrollPosition.js +2 -0
  506. package/package.json +33 -40
  507. package/src/Activity/{Avatar.js → Avatar.tsx} +9 -2
  508. package/src/Activity/{Bubble.js → Bubble.tsx} +10 -2
  509. package/src/Activity/CarouselFilmStrip.js +20 -29
  510. package/src/Activity/CarouselFilmStripAttachment.js +91 -0
  511. package/src/Activity/{Speak.js → Speak.tsx} +12 -5
  512. package/src/Activity/{StackedLayout.js → StackedLayout.tsx} +46 -20
  513. package/src/Attachment/Assets/DownloadIcon.js +8 -1
  514. package/src/Attachment/{AudioContent.js → AudioContent.tsx} +12 -3
  515. package/src/Attachment/FileAttachment.js +1 -1
  516. package/src/Attachment/{FileContent.js → FileContent.tsx} +22 -7
  517. package/src/Attachment/{HTMLVideoContent.js → HTMLVideoContent.tsx} +10 -2
  518. package/src/Attachment/{ImageContent.js → ImageContent.tsx} +7 -2
  519. package/src/Attachment/{TextContent.js → TextContent.tsx} +14 -7
  520. package/src/Attachment/{VideoContent.js → VideoContent.tsx} +10 -2
  521. package/src/Attachment/{VimeoContent.js → VimeoContent.tsx} +15 -8
  522. package/src/Attachment/{YouTubeContent.js → YouTubeContent.tsx} +12 -5
  523. package/src/{BasicSendBox.js → BasicSendBox.tsx} +9 -5
  524. package/src/BasicToaster.js +9 -5
  525. package/src/BasicTranscript.tsx +878 -0
  526. package/src/{BasicTypingIndicator.js → BasicTypingIndicator.tsx} +4 -3
  527. package/src/{BasicWebChat.js → BasicWebChat.tsx} +13 -4
  528. package/src/{Composer.js → Composer.tsx} +82 -71
  529. package/src/Dictation.js +13 -4
  530. package/src/{ErrorBox.js → ErrorBox.tsx} +7 -2
  531. package/src/Middleware/Activity/createCoreMiddleware.tsx +78 -0
  532. package/src/Middleware/ActivityStatus/SendStatus/{SendStatus.js → SendStatus.tsx} +8 -3
  533. package/src/Middleware/ActivityStatus/{Timestamp.js → Timestamp.tsx} +8 -2
  534. package/src/Middleware/ActivityStatus/{createCoreMiddleware.js → createCoreMiddleware.tsx} +3 -1
  535. package/src/Middleware/ActivityStatus/createSendStatusMiddleware.js +10 -6
  536. package/src/Middleware/ActivityStatus/createTimestampMiddleware.js +10 -8
  537. package/src/Middleware/Attachment/createCoreMiddleware.tsx +44 -0
  538. package/src/Middleware/AttachmentForScreenReader/createCoreMiddleware.tsx +40 -0
  539. package/src/Middleware/Avatar/{createCoreMiddleware.js → createCoreMiddleware.tsx} +19 -11
  540. package/src/Middleware/CardAction/createCoreMiddleware.js +51 -42
  541. package/src/Middleware/GroupActivities/createCoreMiddleware.js +6 -4
  542. package/src/Middleware/ScrollToEndButton/ScrollToEndButton.js +45 -0
  543. package/src/Middleware/ScrollToEndButton/createScrollToEndButtonMiddleware.ts +19 -0
  544. package/src/Middleware/Toast/createCoreMiddleware.tsx +24 -0
  545. package/src/Middleware/TypingIndicator/{createCoreMiddleware.js → createCoreMiddleware.tsx} +10 -5
  546. package/src/{ReactWebChat.js → ReactWebChat.tsx} +25 -7
  547. package/src/ScreenReaderActivity.js +65 -40
  548. package/src/{ScreenReaderText.js → ScreenReaderText.tsx} +27 -9
  549. package/src/SendBox/Assets/AttachmentIcon.js +1 -1
  550. package/src/SendBox/Assets/MicrophoneIcon.js +1 -1
  551. package/src/SendBox/{AutoResizeTextArea.js → AutoResizeTextArea.tsx} +30 -4
  552. package/src/SendBox/{DictationInterims.js → DictationInterims.tsx} +6 -2
  553. package/src/SendBox/{IconButton.js → IconButton.tsx} +19 -3
  554. package/src/SendBox/{MicrophoneButton.js → MicrophoneButton.tsx} +35 -25
  555. package/src/SendBox/{SendButton.js → SendButton.tsx} +8 -3
  556. package/src/SendBox/{SuggestedAction.js → SuggestedAction.tsx} +62 -39
  557. package/src/SendBox/{SuggestedActions.js → SuggestedActions.tsx} +70 -22
  558. package/src/SendBox/{TextBox.js → TextBox.tsx} +21 -7
  559. package/src/SendBox/{UploadButton.js → UploadButton.tsx} +7 -3
  560. package/src/Styles/StyleSet/BasicTranscript.ts +34 -20
  561. package/src/Styles/StyleSet/Bubble.ts +0 -1
  562. package/src/Styles/StyleSet/CarouselFilmStrip.ts +12 -30
  563. package/src/Styles/StyleSet/CarouselFilmStripAttachment.ts +57 -0
  564. package/src/Styles/StyleSet/KeyboardHelp.ts +157 -0
  565. package/src/Styles/StyleSet/ScrollToEndButton.ts +33 -31
  566. package/src/Styles/StyleSet/SendBoxButton.ts +84 -13
  567. package/src/Styles/StyleSet/SendBoxTextBox.ts +1 -2
  568. package/src/Styles/StyleSet/StackedLayout.ts +13 -11
  569. package/src/Styles/StyleSet/SuggestedAction.ts +130 -43
  570. package/src/Styles/StyleSet/SuggestedActions.ts +13 -5
  571. package/src/Styles/createStyleSet.ts +43 -40
  572. package/src/Styles/mirrorStyle.js +10 -2
  573. package/src/Toast/CollapseIcon.js +9 -1
  574. package/src/Toast/DismissIcon.js +9 -1
  575. package/src/Toast/ExpandIcon.js +9 -1
  576. package/src/Toast/NotificationIcon.js +4 -1
  577. package/src/Toast/createToastMiddleware.tsx +15 -0
  578. package/src/Transcript/ActivityRow.tsx +124 -0
  579. package/src/Transcript/ActivityTextAlt.tsx +32 -0
  580. package/src/Transcript/FocusTrap.tsx +64 -0
  581. package/src/Transcript/KeyboardHelp.tsx +282 -0
  582. package/src/Transcript/LiveRegionTranscript.tsx +181 -0
  583. package/src/Transcript/types.ts +1 -0
  584. package/src/Transcript/useActivityAccessibleName.ts +85 -0
  585. package/src/Utils/{AccessibleButton.js → AccessibleButton.tsx} +19 -4
  586. package/src/Utils/{AccessibleInputText.js → AccessibleInputText.tsx} +48 -5
  587. package/src/Utils/{AccessibleTextArea.js → AccessibleTextArea.tsx} +67 -6
  588. package/src/Utils/{FocusRedirector.js → FocusRedirector.tsx} +21 -8
  589. package/src/Utils/InlineMarkdown.js +18 -2
  590. package/src/Utils/TypeFocusSink/FocusBox.js +4 -4
  591. package/src/Utils/TypeFocusSink/getTabIndex.ts +1 -1
  592. package/src/Utils/TypeFocusSink/inputtableKey.ts +5 -1
  593. package/src/Utils/activityAltText.ts +135 -0
  594. package/src/Utils/createCustomEvent.js +7 -1
  595. package/src/Utils/detectBrowser.js +2 -1
  596. package/src/Utils/findAncestor.ts +12 -0
  597. package/src/Utils/getActivityUniqueId.ts +5 -0
  598. package/src/Utils/intersectionOf.spec.js +2 -0
  599. package/src/Utils/intersectionOf.ts +14 -0
  600. package/src/Utils/isZeroOrPositive.ts +7 -0
  601. package/src/Utils/mapMap.js +7 -1
  602. package/src/Utils/mapMap.spec.js +2 -0
  603. package/src/Utils/removeInline.spec.js +2 -0
  604. package/src/Utils/scrollIntoViewWithBlockNearest.ts +20 -0
  605. package/src/Utils/shallowEquals.js +8 -1
  606. package/src/Utils/{singleToArray.js → singleToArray.ts} +1 -1
  607. package/src/Utils/supportPseudoClass.ts +17 -0
  608. package/src/Utils/{tabbableElements.js → tabbableElements.ts} +6 -5
  609. package/src/Utils/walkMarkdownTokens.spec.js +3 -3
  610. package/src/connectToWebChat.js +11 -4
  611. package/src/hooks/{index.js → index.ts} +1 -0
  612. package/src/hooks/internal/BypassSpeechSynthesisPonyfill.js +70 -17
  613. package/src/hooks/internal/useChanged.ts +17 -0
  614. package/src/hooks/internal/useDispatchScrollPosition.js +1 -3
  615. package/src/hooks/internal/useDispatchTranscriptFocusByActivityKey.ts +5 -0
  616. package/src/hooks/internal/useFocusVisible.ts +22 -0
  617. package/src/hooks/internal/useMemoWithPrevious.ts +16 -0
  618. package/src/hooks/internal/useMemoize.spec.js +3 -1
  619. package/src/hooks/internal/useMemoize.ts +53 -0
  620. package/src/hooks/internal/useObserveFocusVisible.ts +252 -0
  621. package/src/hooks/internal/usePrevious.ts +12 -0
  622. package/src/hooks/internal/useResumeAudioContext.ts +7 -0
  623. package/src/hooks/internal/useScrollRelative.js +4 -3
  624. package/src/hooks/internal/useStateRef.ts +31 -0
  625. package/src/hooks/internal/{useUniqueId.js → useUniqueId.ts} +1 -1
  626. package/src/hooks/internal/useValueRef.ts +22 -0
  627. package/src/hooks/{useDictateAbortable.js → useDictateAbortable.ts} +1 -1
  628. package/src/hooks/{useFocus.js → useFocus.ts} +1 -1
  629. package/src/hooks/{useFocusSendBox.js → useFocusSendBox.ts} +2 -1
  630. package/src/hooks/{useObserveScrollPosition.js → useObserveScrollPosition.ts} +6 -1
  631. package/src/hooks/{useObserveTranscriptFocus.js → useObserveTranscriptFocus.ts} +6 -1
  632. package/src/hooks/useRenderMarkdownAsHTML.ts +23 -0
  633. package/src/hooks/{useScrollDown.js → useScrollDown.ts} +1 -1
  634. package/src/hooks/useScrollTo.ts +16 -0
  635. package/src/hooks/useScrollToEnd.ts +12 -0
  636. package/src/hooks/{useScrollUp.js → useScrollUp.ts} +1 -1
  637. package/src/hooks/{useSendFiles.js → useSendFiles.ts} +3 -2
  638. package/src/hooks/{useStyleSet.js → useStyleSet.ts} +1 -1
  639. package/src/hooks/useWebSpeechPonyfill.ts +7 -0
  640. package/src/index.ts +7 -12
  641. package/src/providers/ActivityTree/ActivityTreeComposer.tsx +74 -0
  642. package/src/providers/ActivityTree/private/Context.ts +12 -0
  643. package/src/providers/ActivityTree/private/types.ts +12 -0
  644. package/src/providers/ActivityTree/private/useActivitiesWithRenderer.ts +66 -0
  645. package/src/providers/ActivityTree/private/useActivityTreeWithRenderer.ts +140 -0
  646. package/src/providers/ActivityTree/private/useContext.ts +15 -0
  647. package/src/providers/ActivityTree/useActivityTreeWithRenderer.ts +16 -0
  648. package/src/providers/LiveRegionTwin/LiveRegionTwinComposer.tsx +154 -0
  649. package/src/providers/LiveRegionTwin/private/Context.ts +15 -0
  650. package/src/providers/LiveRegionTwin/private/LiveRegionTwinContainer.tsx +64 -0
  651. package/src/providers/LiveRegionTwin/private/types.ts +10 -0
  652. package/src/providers/LiveRegionTwin/private/useContext.ts +15 -0
  653. package/src/providers/LiveRegionTwin/private/useMarkAllAsRenderedEffect.ts +13 -0
  654. package/src/providers/LiveRegionTwin/private/useStaticElementEntries.ts +7 -0
  655. package/src/providers/LiveRegionTwin/useQueueStaticElement.ts +12 -0
  656. package/src/providers/TranscriptFocus/TranscriptFocusComposer.tsx +180 -0
  657. package/src/providers/TranscriptFocus/private/Context.ts +16 -0
  658. package/src/providers/TranscriptFocus/private/useContext.ts +13 -0
  659. package/src/providers/TranscriptFocus/useActiveDescendantId.ts +5 -0
  660. package/src/providers/TranscriptFocus/useFocusByActivityKey.ts +14 -0
  661. package/src/providers/TranscriptFocus/useFocusRelativeActivity.ts +5 -0
  662. package/src/providers/TranscriptFocus/useFocusedActivityKey.ts +5 -0
  663. package/src/providers/TranscriptFocus/useFocusedExplicitly.ts +5 -0
  664. package/src/providers/TranscriptFocus/useGetDescendantIdByActivityKey.ts +5 -0
  665. package/src/tsconfig.json +1 -1
  666. package/src/types/ScrollPosition.ts +6 -0
  667. package/.eslintignore +0 -9
  668. package/lib/Activity/ScrollToEndButton.js +0 -81
  669. package/lib/Attachment/Assets/ErrorIcon.js +0 -22
  670. package/lib/Utils/findLastIndex.js +0 -32
  671. package/lib/Utils/remarkStripMarkdown.js +0 -26
  672. package/lib/hooks/internal/useAcknowledgedActivity.js +0 -90
  673. package/lib/hooks/internal/useDispatchTranscriptFocus.js +0 -19
  674. package/lib/hooks/internal/useStripMarkdown.js +0 -19
  675. package/src/Activity/ScrollToEndButton.js +0 -58
  676. package/src/Attachment/Assets/ErrorIcon.js +0 -9
  677. package/src/BasicTranscript.js +0 -1123
  678. package/src/Middleware/Activity/createCoreMiddleware.js +0 -71
  679. package/src/Middleware/Attachment/createCoreMiddleware.js +0 -43
  680. package/src/Middleware/AttachmentForScreenReader/createCoreMiddleware.js +0 -37
  681. package/src/Middleware/Toast/createCoreMiddleware.js +0 -20
  682. package/src/Toast/createToastMiddleware.js +0 -11
  683. package/src/Utils/findLastIndex.js +0 -11
  684. package/src/Utils/findLastIndex.spec.js +0 -29
  685. package/src/Utils/getActivityUniqueId.js +0 -3
  686. package/src/Utils/intersectionOf.js +0 -11
  687. package/src/Utils/isZeroOrPositive.js +0 -4
  688. package/src/Utils/remarkStripMarkdown.js +0 -13
  689. package/src/hooks/internal/useAcknowledgedActivity.js +0 -65
  690. package/src/hooks/internal/useChanged.js +0 -10
  691. package/src/hooks/internal/useDispatchTranscriptFocus.js +0 -7
  692. package/src/hooks/internal/useMemoize.js +0 -37
  693. package/src/hooks/internal/useStripMarkdown.js +0 -7
  694. package/src/hooks/useRenderMarkdownAsHTML.js +0 -20
  695. package/src/hooks/useScrollTo.js +0 -11
  696. package/src/hooks/useScrollToEnd.js +0 -11
  697. package/src/hooks/useWebSpeechPonyfill.js +0 -5
  698. package/src/index.tsx +0 -35
@@ -15,47 +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 _ScrollToEndButton = _interopRequireDefault(require("./Activity/ScrollToEndButton"));
38
+ var _TranscriptFocusComposer = _interopRequireDefault(require("./providers/TranscriptFocus/TranscriptFocusComposer"));
45
39
 
46
- var _Speak = _interopRequireDefault(require("./Activity/Speak"));
40
+ var _useActiveDescendantId = _interopRequireDefault(require("./providers/TranscriptFocus/useActiveDescendantId"));
47
41
 
48
- var _tabbableElements = _interopRequireDefault(require("./Utils/tabbableElements"));
49
-
50
- var _useAcknowledgedActivity = _interopRequireDefault(require("./hooks/internal/useAcknowledgedActivity"));
42
+ var _useActivityTreeWithRenderer = _interopRequireDefault(require("./providers/ActivityTree/useActivityTreeWithRenderer"));
51
43
 
52
44
  var _useDispatchScrollPosition = _interopRequireDefault(require("./hooks/internal/useDispatchScrollPosition"));
53
45
 
54
- var _useDispatchTranscriptFocus = _interopRequireDefault(require("./hooks/internal/useDispatchTranscriptFocus"));
46
+ var _useDispatchTranscriptFocusByActivityKey = _interopRequireDefault(require("./hooks/internal/useDispatchTranscriptFocusByActivityKey"));
55
47
 
56
48
  var _useFocus = _interopRequireDefault(require("./hooks/useFocus"));
57
49
 
58
- 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"));
59
61
 
60
62
  var _useRegisterFocusTranscript = _interopRequireDefault(require("./hooks/internal/useRegisterFocusTranscript"));
61
63
 
@@ -71,26 +73,22 @@ var _useStyleToEmotionObject = _interopRequireDefault(require("./hooks/internal/
71
73
 
72
74
  var _useUniqueId = _interopRequireDefault(require("./hooks/internal/useUniqueId"));
73
75
 
74
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
76
+ var _useValueRef = _interopRequireDefault(require("./hooks/internal/useValueRef"));
77
+
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); }
75
79
 
76
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (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; }
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; }
77
81
 
78
82
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
79
83
 
80
- 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; }
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
+
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; }
81
87
 
82
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; }
83
89
 
84
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; }
85
91
 
86
- function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
87
-
88
- 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."); }
89
-
90
- function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
91
-
92
- function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
93
-
94
92
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
95
93
 
96
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."); }
@@ -99,17 +97,23 @@ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o =
99
97
 
100
98
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
101
99
 
102
- function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
100
+ function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
103
101
 
104
102
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
105
103
 
106
- var useActivities = _botframeworkWebchatApi.hooks.useActivities,
107
- useCreateActivityRenderer = _botframeworkWebchatApi.hooks.useCreateActivityRenderer,
104
+ var useActivityKeys = _botframeworkWebchatApi.hooks.useActivityKeys,
105
+ useActivityKeysByRead = _botframeworkWebchatApi.hooks.useActivityKeysByRead,
108
106
  useCreateActivityStatusRenderer = _botframeworkWebchatApi.hooks.useCreateActivityStatusRenderer,
109
107
  useCreateAvatarRenderer = _botframeworkWebchatApi.hooks.useCreateAvatarRenderer,
108
+ useCreateScrollToEndButtonRenderer = _botframeworkWebchatApi.hooks.useCreateScrollToEndButtonRenderer,
110
109
  useDirection = _botframeworkWebchatApi.hooks.useDirection,
111
- useGroupActivities = _botframeworkWebchatApi.hooks.useGroupActivities,
110
+ useGetActivityByKey = _botframeworkWebchatApi.hooks.useGetActivityByKey,
111
+ useGetKeyByActivity = _botframeworkWebchatApi.hooks.useGetKeyByActivity,
112
+ useGetKeyByActivityId = _botframeworkWebchatApi.hooks.useGetKeyByActivityId,
113
+ useLastAcknowledgedActivityKey = _botframeworkWebchatApi.hooks.useLastAcknowledgedActivityKey,
112
114
  useLocalizer = _botframeworkWebchatApi.hooks.useLocalizer,
115
+ useMarkActivityKeyAsRead = _botframeworkWebchatApi.hooks.useMarkActivityKeyAsRead,
116
+ useMarkAllAsAcknowledged = _botframeworkWebchatApi.hooks.useMarkAllAsAcknowledged,
113
117
  useStyleOptions = _botframeworkWebchatApi.hooks.useStyleOptions;
114
118
  var ROOT_STYLE = {
115
119
  '&.webchat__basic-transcript': {
@@ -134,17 +138,9 @@ var ROOT_STYLE = {
134
138
  }
135
139
  }
136
140
  };
137
-
138
- function validateAllActivitiesTagged(activities, bins) {
139
- return activities.every(function (activity) {
140
- return bins.some(function (bin) {
141
- return bin.includes(activity);
142
- });
143
- });
144
- }
145
-
146
- var InternalTranscript = function InternalTranscript(_ref) {
147
- 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,
148
144
  className = _ref.className;
149
145
 
150
146
  var _useStyleSet = (0, _useStyleSet5.default)(),
@@ -157,188 +153,84 @@ var InternalTranscript = function InternalTranscript(_ref) {
157
153
  bubbleFromUserNubOffset = _useStyleOptions2$.bubbleFromUserNubOffset,
158
154
  bubbleNubOffset = _useStyleOptions2$.bubbleNubOffset,
159
155
  groupTimestamp = _useStyleOptions2$.groupTimestamp,
160
- internalLiveRegionFadeAfter = _useStyleOptions2$.internalLiveRegionFadeAfter,
161
156
  showAvatarInGroup = _useStyleOptions2$.showAvatarInGroup;
162
157
 
163
- var _useState = (0, _react.useState)(),
164
- _useState2 = _slicedToArray(_useState, 2),
165
- focusedActivityKey = _useState2[0],
166
- setFocusedActivityKey = _useState2[1];
158
+ var _useActiveDescendantI = (0, _useActiveDescendantId.default)(),
159
+ _useActiveDescendantI2 = _slicedToArray(_useActiveDescendantI, 1),
160
+ activeDescendantId = _useActiveDescendantI2[0];
167
161
 
168
- var _useActivities = useActivities(),
169
- _useActivities2 = _slicedToArray(_useActivities, 1),
170
- activities = _useActivities2[0];
162
+ var _useActivityTreeWithR = (0, _useActivityTreeWithRenderer.default)(),
163
+ _useActivityTreeWithR2 = _slicedToArray(_useActivityTreeWithR, 1),
164
+ activityWithRendererTree = _useActivityTreeWithR2[0];
171
165
 
172
166
  var _useDirection = useDirection(),
173
167
  _useDirection2 = _slicedToArray(_useDirection, 1),
174
168
  direction = _useDirection2[0];
175
169
 
176
- 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
+
177
178
  var createActivityStatusRenderer = useCreateActivityStatusRenderer();
178
179
  var createAvatarRenderer = useCreateAvatarRenderer();
179
180
  var focus = (0, _useFocus.default)();
180
- 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();
181
186
  var localize = useLocalizer();
182
187
  var rootClassName = (0, _useStyleToEmotionObject.default)()(ROOT_STYLE) + '';
183
188
  var rootElementRef = (0, _react.useRef)();
189
+ var terminatorLabelId = (0, _useUniqueId.default)('webchat__basic-transcript__terminator-label');
184
190
  var terminatorRef = (0, _react.useRef)();
185
- var activityInteractiveAlt = localize('ACTIVITY_INTERACTIVE_LABEL_ALT');
191
+ var focusedActivityKeyRef = (0, _useValueRef.default)(focusedActivityKey);
192
+ var hideAllTimestamps = groupTimestamp === false;
186
193
  var terminatorText = localize('TRANSCRIPT_TERMINATOR_TEXT');
187
194
  var transcriptAriaLabel = localize('TRANSCRIPT_ARIA_LABEL_ALT');
188
- var transcriptRoleDescription = localize('TRANSCRIPT_ARIA_ROLE_ALT');
189
- var hideAllTimestamps = groupTimestamp === false; // Gets renderer for every activity.
190
- // Activities that are not visible will return a falsy renderer.
191
- // Converted from createActivityRenderer({ activity, nextVisibleActivity }) to createActivityRenderer(activity, nextVisibleActivity).
192
- // This is for the memoization function to cache the arguments. Memoizer can only cache literal arguments.
193
-
194
- var createActivityRendererWithLiteralArgs = (0, _react.useCallback)(function (activity, nextVisibleActivity) {
195
- return createActivityRenderer({
196
- activity: activity,
197
- nextVisibleActivity: nextVisibleActivity
198
- });
199
- }, [createActivityRenderer]); // Create a memoized context of the createActivityRenderer function.
200
-
201
- var activitiesWithRenderer = (0, _useMemoize.default)(createActivityRendererWithLiteralArgs, function (createActivityRendererWithLiteralArgsMemoized) {
202
- // All calls to createActivityRendererWithLiteralArgsMemoized() in this function will be memoized (LRU = 1).
203
- // In the next render cycle, calls to createActivityRendererWithLiteralArgsMemoized() might return the memoized result instead.
204
- // This is an improvement to React useMemo(), because it only allows 1 memoization.
205
- // useMemoize() allows any number of memoization.
206
- var activitiesWithRenderer = [];
207
- var nextVisibleActivity;
208
-
209
- for (var index = activities.length - 1; index >= 0; index--) {
210
- var activity = activities[index];
211
- var renderActivity = createActivityRendererWithLiteralArgsMemoized(activity, nextVisibleActivity);
212
-
213
- if (renderActivity) {
214
- activitiesWithRenderer.splice(0, 0, {
215
- activity: activity,
216
- renderActivity: renderActivity
217
- });
218
- nextVisibleActivity = activity;
219
- }
220
- }
221
-
222
- return activitiesWithRenderer;
223
- }, [activities]);
224
- var visibleActivities = (0, _react.useMemo)(function () {
225
- return activitiesWithRenderer.map(function (_ref2) {
226
- var activity = _ref2.activity;
227
- return activity;
228
- });
229
- }, [activitiesWithRenderer]); // Tag activities based on types.
230
- // The default implementation tag into 2 types: sender and status.
231
-
232
- var _useMemo = (0, _react.useMemo)(function () {
233
- var _groupActivities = groupActivities({
234
- activities: visibleActivities
235
- }),
236
- activitiesGroupBySender = _groupActivities.sender,
237
- activitiesGroupByStatus = _groupActivities.status;
238
-
239
- if (!validateAllActivitiesTagged(visibleActivities, activitiesGroupBySender)) {
240
- console.warn('botframework-webchat: Not every activities are grouped in the "sender" property. Please fix "groupActivitiesMiddleware" and group every activities.');
241
- }
242
-
243
- if (!validateAllActivitiesTagged(visibleActivities, activitiesGroupByStatus)) {
244
- console.warn('botframework-webchat: Not every activities are grouped in the "status" property. Please fix "groupActivitiesMiddleware" and group every activities.');
245
- }
246
-
247
- return {
248
- activitiesGroupBySender: activitiesGroupBySender,
249
- activitiesGroupByStatus: activitiesGroupByStatus
250
- };
251
- }, [groupActivities, visibleActivities]),
252
- activitiesGroupBySender = _useMemo.activitiesGroupBySender,
253
- activitiesGroupByStatus = _useMemo.activitiesGroupByStatus; // Create a tree of activities with 2 dimensions: sender, followed by status.
254
-
255
-
256
- var activityTree = (0, _react.useMemo)(function () {
257
- var visibleActivitiesPendingGrouping = _toConsumableArray(visibleActivities);
258
-
259
- var activityTree = [];
260
-
261
- var _loop = function _loop() {
262
- var _visibleActivitiesPen = _slicedToArray(visibleActivitiesPendingGrouping, 1),
263
- activity = _visibleActivitiesPen[0];
264
-
265
- var senderTree = [];
266
- var activitiesWithSameSender = activitiesGroupBySender.find(function (activities) {
267
- return activities.includes(activity);
268
- });
269
- activityTree.push(senderTree);
270
- activitiesWithSameSender.forEach(function (activity) {
271
- var activitiesWithSameStatus = activitiesGroupByStatus.find(function (activities) {
272
- return activities.includes(activity);
273
- });
274
- var activitiesWithSameSenderAndStatus = (0, _intersectionOf.default)(visibleActivitiesPendingGrouping, activitiesWithSameSender, activitiesWithSameStatus);
275
-
276
- if (activitiesWithSameSenderAndStatus.length) {
277
- senderTree.push(activitiesWithSameSenderAndStatus);
278
-
279
- _removeInline.default.apply(void 0, [visibleActivitiesPendingGrouping].concat(_toConsumableArray(activitiesWithSameSenderAndStatus)));
280
- }
281
- });
282
- };
283
-
284
- while (visibleActivitiesPendingGrouping.length) {
285
- _loop();
286
- } // Assertion: All activities in visibleActivities, must be assigned to the activityTree
287
-
288
-
289
- if (!visibleActivities.every(function (activity) {
290
- return activityTree.some(function (activitiesWithSameSender) {
291
- return activitiesWithSameSender.some(function (activitiesWithSameSenderAndStatus) {
292
- return activitiesWithSameSenderAndStatus.includes(activity);
293
- });
294
- });
295
- })) {
296
- console.warn('botframework-webchat internal: Not all visible activities are grouped in the activityTree.', {
297
- visibleActivities: visibleActivities,
298
- activityTree: activityTree
299
- });
195
+ var callbackRef = (0, _react.useCallback)(function (element) {
196
+ if (typeof ref === 'function') {
197
+ ref(element);
198
+ } else {
199
+ ref.current = element;
300
200
  }
301
201
 
302
- return activityTree;
303
- }, [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.
304
204
 
305
205
  var renderingElements = (0, _react.useMemo)(function () {
306
206
  var renderingElements = [];
307
207
  var topSideBotNub = (0, _isZeroOrPositive.default)(bubbleNubOffset);
308
208
  var topSideUserNub = (0, _isZeroOrPositive.default)(bubbleFromUserNubOffset);
309
- activityTree.forEach(function (activitiesWithSameSender) {
310
- var _activitiesWithSameSe = _slicedToArray(activitiesWithSameSender, 1),
311
- _activitiesWithSameSe2 = _slicedToArray(_activitiesWithSameSe[0], 1),
312
- 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;
313
213
 
314
214
  var renderAvatar = createAvatarRenderer({
315
215
  activity: firstActivity
316
216
  });
317
- activitiesWithSameSender.forEach(function (activitiesWithSameSenderAndStatus, indexWithinSenderGroup) {
217
+ entriesWithSameSender.forEach(function (entriesWithSameSenderAndStatus, indexWithinSenderGroup) {
318
218
  var firstInSenderGroup = !indexWithinSenderGroup;
319
- var lastInSenderGroup = indexWithinSenderGroup === activitiesWithSameSender.length - 1;
320
- activitiesWithSameSenderAndStatus.forEach(function (activity, indexWithinSenderAndStatusGroup) {
219
+ var lastInSenderGroup = indexWithinSenderGroup === entriesWithSameSender.length - 1;
220
+ entriesWithSameSenderAndStatus.forEach(function (_ref2, indexWithinSenderAndStatusGroup) {
221
+ var _activity$from;
222
+
223
+ var activity = _ref2.activity,
224
+ renderActivity = _ref2.renderActivity;
321
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;
322
229
  var renderActivityStatus = createActivityStatusRenderer({
323
- activity: activity
230
+ activity: activity,
231
+ nextVisibleActivity: undefined
324
232
  });
325
- var firstInSenderAndStatusGroup = !indexWithinSenderAndStatusGroup;
326
- var lastInSenderAndStatusGroup = indexWithinSenderAndStatusGroup === activitiesWithSameSenderAndStatus.length - 1;
327
-
328
- var _activitiesWithRender = activitiesWithRenderer.find(function (entry) {
329
- return entry.activity === activity;
330
- }),
331
- renderActivity = _activitiesWithRender.renderActivity;
332
-
333
- var key = (0, _getActivityUniqueId.default)(activity) || renderingElements.length;
334
- var _activity$channelData = activity.channelData;
335
- _activity$channelData = _activity$channelData === void 0 ? {} : _activity$channelData;
336
- var _activity$channelData2 = _activity$channelData.messageBack;
337
- _activity$channelData2 = _activity$channelData2 === void 0 ? {} : _activity$channelData2;
338
- var messageBackDisplayText = _activity$channelData2.displayText,
339
- role = activity.from.role,
340
- text = activity.text;
341
- 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;
342
234
  var showCallout; // Depending on the "showAvatarInGroup" setting, the avatar will render in different positions.
343
235
 
344
236
  if (showAvatarInGroup === 'sender') {
@@ -357,161 +249,78 @@ var InternalTranscript = function InternalTranscript(_ref) {
357
249
  showCallout = true;
358
250
  }
359
251
 
360
- var focusActivity = function focusActivity() {
361
- setFocusedActivityKey((0, _getActivityUniqueId.default)(activity)); // IE11 need to manually focus on the transcript.
362
-
363
- var rootElement = rootElementRef.current;
364
- rootElement && rootElement.focus();
365
- };
366
-
367
252
  renderingElements.push({
368
253
  activity: activity,
369
254
  // After the element is mounted, set it to activityElementsRef.
370
255
  callbackRef: function callbackRef(activityElement) {
371
- var entry = activityElementsRef.current.find(function (_ref3) {
372
- var activityID = _ref3.activityID;
373
- return activityID === activity.id;
374
- });
375
-
376
- if (entry) {
377
- entry.element = activityElement;
378
- }
379
- },
380
- // Calling this function will put the focus on the transcript and the activity.
381
- focusActivity: focusActivity,
382
- // When a child of the activity receives focus, notify the transcript to set the aria-activedescendant to this activity.
383
- handleFocus: function handleFocus() {
384
- setFocusedActivityKey((0, _getActivityUniqueId.default)(activity));
385
- },
386
- handleKeyDown: function handleKeyDown(event) {
387
- if (event.key === 'Escape') {
388
- event.preventDefault();
389
- event.stopPropagation();
390
- setFocusedActivityKey((0, _getActivityUniqueId.default)(activity));
391
- var current = rootElementRef.current;
392
- current && current.focus();
393
- }
394
- },
395
- // For accessibility: when the user press up/down arrow keys, we put a visual focus indicator around the focused activity.
396
- // We should do the same for mouse, that is why we have the click handler here.
397
- // We are doing it in event capture phase to prevent other components from stopping event propagation to us.
398
- handleMouseDownCapture: function handleMouseDownCapture(_ref4) {
399
- var target = _ref4.target;
400
- var tabIndex = (0, _getTabIndex.default)(target);
401
-
402
- if (typeof tabIndex !== 'number' || tabIndex < 0 || target.getAttribute('aria-disabled') === 'true') {
403
- focusActivity();
404
- }
256
+ activityElement ? activityElementMapRef.current.set(key, activityElement) : activityElementMapRef.current.delete(key);
405
257
  },
406
258
  // "hideTimestamp" is a render-time parameter for renderActivityStatus().
407
259
  // If true, it will hide the timestamp, but it will continue to show the
408
260
  // retry prompt. And show the screen reader version of the timestamp.
409
- hideTimestamp: hideAllTimestamps || indexWithinSenderAndStatusGroup !== activitiesWithSameSenderAndStatus.length - 1,
261
+ hideTimestamp: hideAllTimestamps || indexWithinSenderAndStatusGroup !== entriesWithSameSenderAndStatus.length - 1,
410
262
  key: key,
411
- // When "liveRegionKey" changes, it will show up in the live region momentarily.
412
- liveRegionKey: key + '|' + (messageBackDisplayText || text),
413
263
  renderActivity: renderActivity,
414
264
  renderActivityStatus: renderActivityStatus,
415
265
  renderAvatar: renderAvatar,
416
- role: role,
417
- // TODO: [P2] #2858 We should use core/definitions/speakingActivity for this predicate instead
418
- shouldSpeak: activity.channelData && activity.channelData.speak,
419
266
  showCallout: showCallout
420
267
  });
421
268
  });
422
269
  });
423
270
  });
424
- var activityElements = activityElementsRef.current; // Update activityElementRef with new sets of activity, while retaining the existing referencing element if exists.
425
-
426
- activityElementsRef.current = renderingElements.map(function (_ref5) {
427
- var activity = _ref5.activity,
428
- id = _ref5.activity.id,
429
- elementId = _ref5.elementId,
430
- key = _ref5.key;
431
- var existingEntry = activityElements.find(function (entry) {
432
- return entry.key === key;
433
- });
434
- return {
435
- activity: activity,
436
- activityID: id,
437
- ariaLabelID: existingEntry ? existingEntry.ariaLabelID : "webchat__basic-transcript__activity-label-".concat((0, _mathRandom.default)().toString(36).substr(2, 5)),
438
- element: existingEntry && existingEntry.element,
439
- elementId: elementId,
440
- key: key
441
- };
442
- }); // There must be one focused (a.k.a. aria-activedescendant) designated. We default it to the last one.
443
-
444
- if (!renderingElements.find(function (_ref6) {
445
- var focused = _ref6.focused;
446
- return focused;
447
- })) {
448
- var lastElement = renderingElements[renderingElements.length - 1];
449
-
450
- if (lastElement) {
451
- lastElement.focused = true;
452
- }
453
- }
454
-
455
271
  return renderingElements;
456
- }, [activitiesWithRenderer, activityElementsRef, activityTree, bubbleFromUserNubOffset, bubbleNubOffset, createActivityStatusRenderer, createAvatarRenderer, hideAllTimestamps, rootElementRef, showAvatarInGroup]);
457
- var renderingActivities = (0, _react.useMemo)(function () {
458
- return renderingElements.map(function (_ref7) {
459
- var activity = _ref7.activity;
460
- return activity;
461
- });
462
- }, [renderingElements]);
272
+ }, [activityElementMapRef, activityWithRendererTree, bubbleFromUserNubOffset, bubbleNubOffset, createActivityStatusRenderer, createAvatarRenderer, getKeyByActivity, hideAllTimestamps, showAvatarInGroup]);
463
273
  var scrollToBottomScrollTo = (0, _reactScrollToBottom.useScrollTo)();
464
274
  var scrollToBottomScrollToEnd = (0, _reactScrollToBottom.useScrollToEnd)();
465
275
  var scrollTo = (0, _react.useCallback)(function (position) {
466
- var _ref8 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
467
- _ref8$behavior = _ref8.behavior,
468
- 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;
469
279
 
470
280
  if (!position) {
471
281
  throw new Error('botframework-webchat: First argument passed to "useScrollTo" must be a ScrollPosition object.');
472
282
  }
473
283
 
474
- var activityID = position.activityID,
284
+ var activityId = position.activityID,
475
285
  scrollTop = position.scrollTop;
476
286
 
477
287
  if (typeof scrollTop !== 'undefined') {
478
288
  scrollToBottomScrollTo(scrollTop, {
479
289
  behavior: behavior
480
290
  });
481
- } else if (typeof activityID !== 'undefined') {
482
- var rootElement = rootElementRef.current;
483
-
484
- var _ref9 = activityElementsRef.current.find(function (entry) {
485
- return entry.activityID === activityID;
486
- }) || {},
487
- activityElement = _ref9.element;
488
-
489
- var scrollableElement = rootElement.querySelector('.webchat__basic-transcript__scrollable');
291
+ } else if (typeof activityId !== 'undefined') {
292
+ var _activityElementMapRe;
490
293
 
491
- if (scrollableElement && activityElement) {
492
- var _activityElement$getC = activityElement.getClientRects(),
493
- _activityElement$getC2 = _slicedToArray(_activityElement$getC, 1),
494
- _activityElement$getC3 = _activityElement$getC2[0],
495
- activityElementHeight = _activityElement$getC3.height,
496
- activityElementY = _activityElement$getC3.y;
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');
497
296
 
498
- var _scrollableElement$ge = scrollableElement.getClientRects(),
499
- _scrollableElement$ge2 = _slicedToArray(_scrollableElement$ge, 1),
500
- scrollableHeight = _scrollableElement$ge2[0].height;
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
501
304
 
502
- var activityElementOffsetTop = activityElementY + scrollableElement.scrollTop;
305
+ var scrollableHeight = scrollableElement.getClientRects()[0].height;
306
+ var activityOffsetTop = activityY + scrollableElement.scrollTop;
503
307
 
504
- var _scrollTop = Math.min(activityElementOffsetTop, activityElementOffsetTop - scrollableHeight + activityElementHeight);
308
+ var _scrollTop = Math.min(activityOffsetTop, activityOffsetTop - scrollableHeight + activityHeight);
505
309
 
506
310
  scrollToBottomScrollTo(_scrollTop, {
507
311
  behavior: behavior
508
312
  });
509
313
  }
510
314
  }
511
- }, [activityElementsRef, rootElementRef, scrollToBottomScrollTo]);
315
+ }, [activityElementMapRef, getKeyByActivityId, rootElementRef, scrollToBottomScrollTo]);
316
+ var scrollToEnd = (0, _react.useCallback)(function () {
317
+ return scrollToBottomScrollToEnd({
318
+ behavior: 'smooth'
319
+ });
320
+ }, [scrollToBottomScrollToEnd]);
512
321
  var scrollRelative = (0, _react.useCallback)(function (direction) {
513
- var _ref10 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
514
- displacement = _ref10.displacement;
322
+ var _ref4 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
323
+ displacement = _ref4.displacement;
515
324
 
516
325
  var rootElement = rootElementRef.current;
517
326
 
@@ -523,8 +332,10 @@ var InternalTranscript = function InternalTranscript(_ref) {
523
332
  var nextScrollTop;
524
333
 
525
334
  if (typeof displacement === 'number') {
335
+ // eslint-disable-next-line no-magic-numbers
526
336
  nextScrollTop = scrollable.scrollTop + (direction === 'down' ? 1 : -1) * displacement;
527
337
  } else {
338
+ // eslint-disable-next-line no-magic-numbers
528
339
  nextScrollTop = scrollable.scrollTop + (direction === 'down' ? 1 : -1) * scrollable.offsetHeight;
529
340
  }
530
341
 
@@ -537,131 +348,49 @@ var InternalTranscript = function InternalTranscript(_ref) {
537
348
  // We call `useRegisterScrollXXX` to register a callback function, the `useScrollXXX` will multiplex the call into each instance of <BasicTranscript>.
538
349
 
539
350
  (0, _useRegisterScrollTo.default)(scrollTo);
540
- (0, _useRegisterScrollToEnd.default)(scrollToBottomScrollToEnd);
351
+ (0, _useRegisterScrollToEnd.default)(scrollToEnd);
541
352
  (0, _useRegisterScrollRelative.default)(scrollRelative);
542
- var dispatchScrollPosition = (0, _useDispatchScrollPosition.default)();
543
- var patchedDispatchScrollPosition = (0, _react.useMemo)(function () {
544
- if (!dispatchScrollPosition) {
545
- return;
546
- }
547
-
548
- return function (_ref11) {
549
- var scrollTop = _ref11.scrollTop;
550
- var rootElement = rootElementRef.current;
551
-
552
- if (!rootElement) {
553
- return;
554
- }
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.
555
356
 
556
- var scrollableElement = rootElement.querySelector('.webchat__basic-transcript__scrollable');
357
+ var handleScrollPosition = (0, _react.useCallback)(function (_ref5) {
358
+ var _ref6;
557
359
 
558
- var _scrollableElement$ge3 = scrollableElement.getClientRects(),
559
- _scrollableElement$ge4 = _slicedToArray(_scrollableElement$ge3, 1),
560
- _scrollableElement$ge5 = _scrollableElement$ge4[0];
360
+ var scrollTop = _ref5.scrollTop;
361
+ var rootElement = rootElementRef.current;
561
362
 
562
- _scrollableElement$ge5 = _scrollableElement$ge5 === void 0 ? {} : _scrollableElement$ge5;
563
- var offsetHeight = _scrollableElement$ge5.height; // Find the activity just above scroll view bottom.
564
- // If the scroll view is already on top, get the first activity.
363
+ if (!rootElement) {
364
+ return;
365
+ }
565
366
 
566
- var entry = scrollableElement.scrollTop ? _toConsumableArray(activityElementsRef.current).reverse().find(function (_ref12) {
567
- var element = _ref12.element;
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
568
369
 
569
- if (!element) {
570
- return false;
571
- }
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
- var _element$getClientRec = element.getClientRects(),
574
- _element$getClientRec2 = _slicedToArray(_element$getClientRec, 1),
575
- _element$getClientRec3 = _element$getClientRec2[0];
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
- _element$getClientRec3 = _element$getClientRec3 === void 0 ? {} : _element$getClientRec3;
578
- var y = _element$getClientRec3.y;
579
- return y < offsetHeight;
580
- }) : activityElementsRef.current[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.
581
381
 
582
- var _ref13 = entry || {},
583
- activityID = _ref13.activityID;
382
+ activityKeyJustAboveScrollBottom && markActivityKeyAsRead(activityKeyJustAboveScrollBottom);
584
383
 
585
- dispatchScrollPosition(_objectSpread(_objectSpread({}, activityID ? {
586
- activityID: activityID
384
+ if (dispatchScrollPositionWithActivityId) {
385
+ var activity = getActivityByKey(activityKeyJustAboveScrollBottom);
386
+ dispatchScrollPositionWithActivityId(_objectSpread(_objectSpread({}, activity ? {
387
+ activityID: activity.id
587
388
  } : {}), {}, {
588
389
  scrollTop: scrollTop
589
390
  }));
590
- };
591
- }, [activityElementsRef, dispatchScrollPosition, rootElementRef]);
592
- (0, _reactScrollToBottom.useObserveScrollPosition)(patchedDispatchScrollPosition);
593
-
594
- var _useAcknowledgedActiv = (0, _useAcknowledgedActivity.default)(),
595
- _useAcknowledgedActiv2 = _slicedToArray(_useAcknowledgedActiv, 1),
596
- lastInteractedActivity = _useAcknowledgedActiv2[0];
597
-
598
- var indexOfLastInteractedActivity = activities.indexOf(lastInteractedActivity); // Create a new ID for aria-activedescendant every time the active descendant change.
599
- // In our design, the transcript will only have 1 focused activity and it has an ID. Other blurred activities will not have ID assigned.
600
- // This help with performance.
601
- // But browser usually do noop if the value of aria-activedescendant doesn't change.
602
- // That means, if we assign the same ID to another element, browser will do noop.
603
- // We need to generate a new ID so the browser see there is a change in aria-activedescendant value and perform accordingly.
604
-
605
- var activeDescendantElementId = (0, _react.useMemo)(function () {
606
- return focusedActivityKey && "webchat__basic-transcript__active-descendant-".concat((0, _mathRandom.default)().toString(36).substr(2, 5));
607
- }, [focusedActivityKey]);
608
- var scrollActiveDescendantIntoView = (0, _react.useCallback)(function () {
609
- var activeDescendant = activeDescendantElementId && document.getElementById(activeDescendantElementId); // Don't scroll active descendant into view if the focus is already inside it.
610
- // Otherwise, given the focus is on the send box, clicking on any <input> inside the Adaptive Cards may cause the view to move.
611
- // This UX is not desirable because click should not cause scroll.
612
-
613
- if (activeDescendant && !activeDescendant.contains(document.activeElement)) {
614
- // Checks if scrollIntoView support options or not.
615
- // - https://github.com/Modernizr/Modernizr/issues/1568#issuecomment-419457972
616
- // - https://stackoverflow.com/questions/46919627/is-it-possible-to-test-for-scrollintoview-browser-compatibility
617
- if ('scrollBehavior' in document.documentElement.style) {
618
- activeDescendant.scrollIntoView({
619
- block: 'nearest'
620
- });
621
- } else {
622
- // This is for browser that does not support options passed to scrollIntoView(), possibly IE11.
623
- var scrollableElement = rootElementRef.current.querySelector('.webchat__basic-transcript__scrollable');
624
- var scrollTopAtTopSide = activeDescendant.offsetTop;
625
- var scrollTopAtBottomSide = activeDescendant.offsetTop + activeDescendant.offsetHeight;
626
-
627
- if (scrollTopAtTopSide < scrollableElement.scrollTop) {
628
- scrollableElement.scrollTop = scrollTopAtTopSide;
629
- } else if (scrollTopAtBottomSide > scrollableElement.scrollTop + scrollableElement.offsetHeight) {
630
- scrollableElement.scrollTop = scrollTopAtBottomSide - scrollableElement.offsetHeight;
631
- }
632
- }
633
- }
634
- }, [activeDescendantElementId, rootElementRef]);
635
- var handleTranscriptFocus = (0, _react.useCallback)(function (event) {
636
- var currentTarget = event.currentTarget,
637
- target = event.target; // When focus is placed on the transcript, scroll active descendant into the view.
638
-
639
- currentTarget === target && scrollActiveDescendantIntoView();
640
- }, [scrollActiveDescendantIntoView]); // After new aria-activedescendant is assigned, we will need to scroll it into view.
641
- // User agent will scroll automatically for focusing element, but not for aria-activedescendant.
642
- // We need to do the scrolling manually.
643
-
644
- (0, _react.useEffect)(function () {
645
- return scrollActiveDescendantIntoView();
646
- }, [scrollActiveDescendantIntoView]); // If any activities has changed, reset the active descendant.
647
-
648
- (0, _react.useEffect)(function () {
649
- return setFocusedActivityKey(undefined);
650
- }, [activities, setFocusedActivityKey]);
651
- var focusRelativeActivity = (0, _react.useCallback)(function (delta) {
652
- if (isNaN(delta) || !renderingElements.length) {
653
- return setFocusedActivityKey(undefined);
654
391
  }
655
-
656
- var index = renderingElements.findIndex(function (_ref14) {
657
- var key = _ref14.key;
658
- return key === focusedActivityKey;
659
- });
660
- var nextIndex = ~index ? Math.max(0, Math.min(renderingElements.length - 1, index + delta)) : renderingElements.length - 1;
661
- var nextFocusedActivity = renderingElements[nextIndex];
662
- setFocusedActivityKey(nextFocusedActivity.key);
663
- rootElementRef.current && rootElementRef.current.focus();
664
- }, [focusedActivityKey, renderingElements, rootElementRef, setFocusedActivityKey]);
392
+ }, [activityElementMapRef, dispatchScrollPositionWithActivityId, getActivityByKey, markActivityKeyAsRead, rootElementRef]);
393
+ (0, _reactScrollToBottom.useObserveScrollPosition)(handleScrollPosition);
665
394
  var handleTranscriptKeyDown = (0, _react.useCallback)(function (event) {
666
395
  var target = event.target;
667
396
  var fromEndOfTranscriptIndicator = target === terminatorRef.current;
@@ -679,6 +408,7 @@ var InternalTranscript = function InternalTranscript(_ref) {
679
408
  break;
680
409
 
681
410
  case 'ArrowUp':
411
+ // eslint-disable-next-line no-magic-numbers
682
412
  focusRelativeActivity(fromEndOfTranscriptIndicator ? 0 : -1);
683
413
  break;
684
414
 
@@ -687,30 +417,13 @@ var InternalTranscript = function InternalTranscript(_ref) {
687
417
  break;
688
418
 
689
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.
690
422
  if (!fromEndOfTranscriptIndicator) {
691
- var focusedActivityEntry = renderingElements.find(function (_ref15) {
692
- var key = _ref15.key;
693
- return key === focusedActivityKey;
694
- });
423
+ var _activityElementMapRe2, _tabbableElements$;
695
424
 
696
- if (focusedActivityEntry) {
697
- var _ref16 = activityElementsRef.current.find(function (_ref17) {
698
- var activity = _ref17.activity;
699
- return activity === focusedActivityEntry.activity;
700
- }) || {},
701
- focusedActivityElement = _ref16.element;
702
-
703
- if (focusedActivityElement) {
704
- var _tabbableElements$fil = (0, _tabbableElements.default)(focusedActivityElement).filter(function (_ref18) {
705
- var className = _ref18.className;
706
- return className !== 'webchat__basic-transcript__activity-sentinel';
707
- }),
708
- _tabbableElements$fil2 = _slicedToArray(_tabbableElements$fil, 1),
709
- firstTabbableElement = _tabbableElements$fil2[0];
710
-
711
- firstTabbableElement && firstTabbableElement.focus();
712
- }
713
- }
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();
714
427
  }
715
428
 
716
429
  break;
@@ -733,20 +446,7 @@ var InternalTranscript = function InternalTranscript(_ref) {
733
446
 
734
447
  event.stopPropagation();
735
448
  }
736
- }, [focusedActivityKey, activityElementsRef, focusRelativeActivity, focus, terminatorRef, renderingElements]);
737
- 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.
738
-
739
- var setBottommostFocusedActivityKeyIfNeeded = (0, _react.useCallback)(function () {
740
- if (!~renderingElements.findIndex(function (_ref19) {
741
- var key = _ref19.key;
742
- return key === focusedActivityKey;
743
- })) {
744
- var _ref20 = renderingElements[renderingElements.length - 1] || {},
745
- lastActivityKey = _ref20.key;
746
-
747
- setFocusedActivityKey(lastActivityKey);
748
- }
749
- }, [focusedActivityKey, renderingElements, setFocusedActivityKey]);
449
+ }, [activityElementMapRef, focus, focusedActivityKeyRef, focusRelativeActivity, terminatorRef]);
750
450
  var handleTranscriptKeyDownCapture = (0, _react.useCallback)(function (event) {
751
451
  var altKey = event.altKey,
752
452
  ctrlKey = event.ctrlKey,
@@ -767,47 +467,46 @@ var InternalTranscript = function InternalTranscript(_ref) {
767
467
  focus('sendBox');
768
468
  }
769
469
  }, [focus]);
770
- var focusTranscriptCallback = (0, _react.useCallback)(function () {
771
- return rootElementRef.current && rootElementRef.current.focus();
772
- }, [rootElementRef]);
773
- (0, _useRegisterFocusTranscript.default)(focusTranscriptCallback);
774
- var handleFocusActivity = (0, _react.useCallback)(function (key) {
775
- setFocusedActivityKey(key);
776
- rootElementRef.current && rootElementRef.current.focus();
777
- }, [setFocusedActivityKey]); // When the focusing activity has changed, dispatch an event to observers of "useObserveTranscriptFocus".
778
-
779
- var dispatchTranscriptFocus = (0, _useDispatchTranscriptFocus.default)();
780
- var focusedActivity = (0, _react.useMemo)(function () {
781
- var _ref21 = renderingElements.find(function (_ref22) {
782
- var key = _ref22.key;
783
- return key === focusedActivityKey;
784
- }) || {},
785
- activity = _ref21.activity;
786
-
787
- return activity;
788
- }, [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
+
789
477
  (0, _react.useMemo)(function () {
790
- return dispatchTranscriptFocus && dispatchTranscriptFocus({
791
- activity: focusedActivity
792
- });
793
- }, [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.
794
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">,
795
489
  // despite the fact there are no "tabIndex" attributes set on the filler.
796
490
  // We need to artificially send the focus back to the transcript.
797
491
 
798
492
  var handleFocusFiller = (0, _react.useCallback)(function () {
799
- var current = rootElementRef.current;
800
- current && current.focus();
801
- }, [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]));
802
499
  return /*#__PURE__*/_react.default.createElement("div", {
803
- "aria-activedescendant": focusedActivityKey ? activeDescendantElementId : undefined,
804
- "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,
805
504
  className: (0, _classnames.default)('webchat__basic-transcript', basicTranscriptStyleSet + '', rootClassName, (className || '') + ''),
806
505
  dir: direction,
807
- onFocus: handleTranscriptFocus,
506
+ onFocus: handleFocus,
808
507
  onKeyDown: handleTranscriptKeyDown,
809
508
  onKeyDownCapture: handleTranscriptKeyDownCapture,
810
- 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.
811
510
  // https://www.w3.org/TR/wai-aria/#aria-activedescendant
812
511
  ,
813
512
  role: "group" // For up/down arrow key navigation across activities, this component must be included in the tab sequence.
@@ -815,250 +514,188 @@ var InternalTranscript = function InternalTranscript(_ref) {
815
514
  // https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_focus_activedescendant
816
515
  ,
817
516
  tabIndex: 0
818
- }, /*#__PURE__*/_react.default.createElement(_ScreenReaderText.default, {
819
- id: labelId,
820
- text: transcriptAriaLabel
821
- }), /*#__PURE__*/_react.default.createElement("section", {
822
- "aria-atomic": false,
823
- "aria-live": "polite",
824
- "aria-relevant": "additions",
825
- "aria-roledescription": transcriptRoleDescription,
826
- role: "log"
827
- }, renderingElements.map(function (_ref23) {
828
- var activity = _ref23.activity,
829
- liveRegionKey = _ref23.liveRegionKey;
830
- return /*#__PURE__*/_react.default.createElement(_Fade.default, {
831
- fadeAfter: internalLiveRegionFadeAfter,
832
- key: liveRegionKey
833
- }, function () {
834
- return /*#__PURE__*/_react.default.createElement(_ScreenReaderActivity.default, {
835
- activity: activity
836
- });
837
- });
838
- })), /*#__PURE__*/_react.default.createElement(InternalTranscriptScrollable, {
839
- activities: renderingActivities,
840
- onFocusActivity: handleFocusActivity,
517
+ }, /*#__PURE__*/_react.default.createElement(_LiveRegionTranscript.default, {
518
+ activityElementMapRef: activityElementMapRef
519
+ }), /*#__PURE__*/_react.default.createElement(InternalTranscriptScrollable, {
841
520
  onFocusFiller: handleFocusFiller,
842
521
  terminatorRef: terminatorRef
843
- }, renderingElements.map(function (_ref24, index) {
844
- var activity = _ref24.activity,
845
- callbackRef = _ref24.callbackRef,
846
- focusActivity = _ref24.focusActivity,
847
- handleFocus = _ref24.handleFocus,
848
- handleKeyDown = _ref24.handleKeyDown,
849
- handleMouseDownCapture = _ref24.handleMouseDownCapture,
850
- hideTimestamp = _ref24.hideTimestamp,
851
- key = _ref24.key,
852
- renderActivity = _ref24.renderActivity,
853
- renderActivityStatus = _ref24.renderActivityStatus,
854
- renderAvatar = _ref24.renderAvatar,
855
- role = _ref24.role,
856
- shouldSpeak = _ref24.shouldSpeak,
857
- showCallout = _ref24.showCallout;
858
-
859
- var _ref25 = activityElementsRef.current.find(function (entry) {
860
- return entry.activity === activity;
861
- }) || {},
862
- ariaLabelID = _ref25.ariaLabelID,
863
- element = _ref25.element;
864
-
865
- var activeDescendant = focusedActivityKey === key;
866
- var isContentInteractive = !!(element ? (0, _tabbableElements.default)(element.querySelector('.webchat__basic-transcript__activity-box')).length : 0);
867
- return /*#__PURE__*/_react.default.createElement("li", {
868
- "aria-labelledby": ariaLabelID,
869
- className: (0, _classnames.default)('webchat__basic-transcript__activity', {
870
- 'webchat__basic-transcript__activity--acknowledged': index <= indexOfLastInteractedActivity,
871
- 'webchat__basic-transcript__activity--from-bot': role !== 'user',
872
- 'webchat__basic-transcript__activity--from-user': role === 'user'
873
- }) // Set "id" for valid for accessibility.
874
-
875
- /* eslint-disable-next-line react/forbid-dom-props */
876
- ,
877
- 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,
878
533
  key: key,
879
- onFocus: handleFocus,
880
- onKeyDown: handleKeyDown,
881
- onMouseDownCapture: handleMouseDownCapture,
882
534
  ref: callbackRef
883
- }, /*#__PURE__*/_react.default.createElement(_ScreenReaderActivity.default, {
884
- activity: activity,
885
- id: ariaLabelID,
886
- renderAttachments: false
887
- }, !!isContentInteractive && /*#__PURE__*/_react.default.createElement("p", null, activityInteractiveAlt)), /*#__PURE__*/_react.default.createElement(_FocusRedirector.default, {
888
- className: "webchat__basic-transcript__activity-sentinel",
889
- onFocus: focusActivity,
890
- redirectRef: rootElementRef
891
- }), /*#__PURE__*/_react.default.createElement("div", {
892
- className: "webchat__basic-transcript__activity-box"
893
535
  }, renderActivity({
894
536
  hideTimestamp: hideTimestamp,
895
537
  renderActivityStatus: renderActivityStatus,
896
538
  renderAvatar: renderAvatar,
897
539
  showCallout: showCallout
898
- })), shouldSpeak && /*#__PURE__*/_react.default.createElement(_Speak.default, {
899
- activity: activity
900
- }), /*#__PURE__*/_react.default.createElement(_FocusRedirector.default, {
901
- className: "webchat__basic-transcript__activity-sentinel",
902
- onFocus: focusActivity,
903
- redirectRef: rootElementRef
904
- }), /*#__PURE__*/_react.default.createElement("div", {
905
- className: (0, _classnames.default)('webchat__basic-transcript__activity-indicator', {
906
- 'webchat__basic-transcript__activity-indicator--first': !index,
907
- 'webchat__basic-transcript__activity-indicator--focus': activeDescendant
908
- })
909
540
  }));
910
- })), !!renderingElements.length && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_FocusRedirector.default, {
911
- className: "webchat__basic-transcript__sentinel",
912
- onFocus: setBottommostFocusedActivityKeyIfNeeded,
541
+ })), !!renderingElements.length && /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement(_FocusRedirector.default, {
913
542
  redirectRef: rootElementRef
914
543
  }), /*#__PURE__*/_react.default.createElement("div", {
544
+ "aria-hidden": true,
545
+ "aria-labelledby": terminatorLabelId,
915
546
  className: "webchat__basic-transcript__terminator",
916
547
  ref: terminatorRef,
548
+ role: "note",
917
549
  tabIndex: 0
918
550
  }, /*#__PURE__*/_react.default.createElement("div", {
919
551
  className: "webchat__basic-transcript__terminator-body"
920
552
  }, /*#__PURE__*/_react.default.createElement("div", {
921
- className: "webchat__basic-transcript__terminator-text"
553
+ className: "webchat__basic-transcript__terminator-text",
554
+ id: terminatorLabelId
922
555
  }, terminatorText)))), /*#__PURE__*/_react.default.createElement("div", {
923
556
  className: "webchat__basic-transcript__focus-indicator"
924
557
  }));
925
- };
926
-
558
+ });
927
559
  InternalTranscript.defaultProps = {
928
560
  className: ''
929
561
  };
930
562
  InternalTranscript.propTypes = {
931
- activityElementsRef: _propTypes.default.shape({
932
- 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)
933
567
  }).isRequired,
934
568
  className: _propTypes.default.string
935
569
  };
936
570
 
937
- var InternalScreenReaderTranscript = function InternalScreenReaderTranscript(_ref26) {
938
- var renderingElements = _ref26.renderingElements;
939
- var localize = useLocalizer();
940
-
941
- var _useStyleOptions3 = useStyleOptions(),
942
- _useStyleOptions4 = _slicedToArray(_useStyleOptions3, 1),
943
- internalLiveRegionFadeAfter = _useStyleOptions4[0];
944
-
945
- var transcriptRoleDescription = localize('TRANSCRIPT_ARIA_ROLE_ALT');
946
- return /*#__PURE__*/_react.default.createElement("section", {
947
- "aria-atomic": false,
948
- "aria-live": "polite",
949
- "aria-relevant": "additions",
950
- "aria-roledescription": transcriptRoleDescription,
951
- role: "log"
952
- }, renderingElements.map(function (_ref27) {
953
- var activity = _ref27.activity,
954
- liveRegionKey = _ref27.liveRegionKey;
955
- return /*#__PURE__*/_react.default.createElement(_Fade.default, {
956
- fadeAfter: internalLiveRegionFadeAfter,
957
- key: liveRegionKey
958
- }, function () {
959
- return /*#__PURE__*/_react.default.createElement(_ScreenReaderActivity.default, {
960
- activity: activity
961
- });
962
- });
963
- }));
964
- };
965
-
966
- InternalScreenReaderTranscript.propTypes = {
967
- renderingElements: _propTypes.default.arrayOf(_propTypes.default.shape({
968
- activity: _propTypes.default.any,
969
- liveRegionKey: _propTypes.default.string
970
- })).isRequired
971
- }; // Separating high-frequency hooks to improve performance.
972
-
973
- var InternalTranscriptScrollable = function InternalTranscriptScrollable(_ref28) {
974
- var activities = _ref28.activities,
975
- children = _ref28.children,
976
- onFocusActivity = _ref28.onFocusActivity,
977
- onFocusFiller = _ref28.onFocusFiller,
978
- terminatorRef = _ref28.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;
979
576
 
980
577
  var _useStyleSet3 = (0, _useStyleSet5.default)(),
981
578
  _useStyleSet4 = _slicedToArray(_useStyleSet3, 1),
982
579
  activitiesStyleSet = _useStyleSet4[0].activities;
983
580
 
984
- var _useStyleOptions5 = useStyleOptions(),
985
- _useStyleOptions6 = _slicedToArray(_useStyleOptions5, 1),
986
- hideScrollToEndButton = _useStyleOptions6[0].hideScrollToEndButton;
987
-
988
581
  var _useAnimatingToEnd = (0, _reactScrollToBottom.useAnimatingToEnd)(),
989
582
  _useAnimatingToEnd2 = _slicedToArray(_useAnimatingToEnd, 1),
990
583
  animatingToEnd = _useAnimatingToEnd2[0];
991
584
 
585
+ var _useAtEnd = (0, _reactScrollToBottom.useAtEnd)(),
586
+ _useAtEnd2 = _slicedToArray(_useAtEnd, 1),
587
+ atEnd = _useAtEnd2[0];
588
+
589
+ var _useActivityKeysByRea = useActivityKeysByRead(),
590
+ _useActivityKeysByRea2 = _slicedToArray(_useActivityKeysByRea, 2),
591
+ unreadActivityKeys = _useActivityKeysByRea2[1];
592
+
992
593
  var _useSticky = (0, _reactScrollToBottom.useSticky)(),
993
594
  _useSticky2 = _slicedToArray(_useSticky, 1),
994
595
  sticky = _useSticky2[0];
995
596
 
996
- 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];
997
600
 
601
+ var focusByActivityKey = (0, _useFocusByActivityKey.default)();
998
602
  var localize = useLocalizer();
999
- var scrollToEndButtonRef = (0, _react.useRef)();
1000
- var lastReadActivityIdRef = (0, _react.useRef)(lastVisibleActivityId);
603
+ var markActivityKeyAsRead = useMarkActivityKeyAsRead();
604
+ var markAllAsAcknowledged = useMarkAllAsAcknowledged();
605
+ var scrollToEnd = (0, _reactScrollToBottom.useScrollToEnd)();
606
+ var prevSticky = (0, _usePrevious.default)(sticky);
1001
607
  var transcriptRoleDescription = localize('TRANSCRIPT_ARIA_ROLE_ALT');
1002
- var allActivitiesRead = lastVisibleActivityId === lastReadActivityIdRef.current;
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]);
1003
672
  var handleScrollToEndButtonClick = (0, _react.useCallback)(function () {
1004
- // After the "New message" button is clicked, focus on the first unread activity.
1005
- var index = activities.findIndex(function (_ref29) {
1006
- var id = _ref29.id;
1007
- return id === lastReadActivityIdRef.current;
673
+ scrollToEnd({
674
+ behavior: 'smooth'
1008
675
  });
676
+ var renderingActivityKeys = renderingActivityKeysRef.current; // After the "New message" button is clicked, focus on the first unread activity which will be rendered.
1009
677
 
1010
- if (~index) {
1011
- var firstUnreadActivity = activities[index + 1];
678
+ var firstUnreadRenderingActivityKey = nextUnreadActivityKeysRef.current.find(function (key) {
679
+ return renderingActivityKeys.includes(key);
680
+ });
1012
681
 
1013
- if (firstUnreadActivity) {
1014
- return onFocusActivity((0, _getActivityUniqueId.default)(firstUnreadActivity));
1015
- }
1016
- }
682
+ if (firstUnreadRenderingActivityKey) {
683
+ focusByActivityKey(firstUnreadRenderingActivityKey);
684
+ } else {
685
+ var _terminatorRef$curren;
1017
686
 
1018
- var current = terminatorRef.current;
1019
- current && current.focus();
1020
- }, [activities, lastReadActivityIdRef, onFocusActivity, terminatorRef]);
1021
-
1022
- if (sticky) {
1023
- // If it is sticky, the user is at the bottom of the transcript, everything is read.
1024
- // So mark the activity ID as read.
1025
- lastReadActivityIdRef.current = lastVisibleActivityId;
1026
- } // Finds where we should render the "New messages" button, in index. Returns -1 to hide the button.
1027
-
1028
-
1029
- var renderSeparatorAfterIndex = (0, _react.useMemo)(function () {
1030
- // Don't show the button if:
1031
- // - All activities have been read
1032
- // - Currently animating towards bottom
1033
- // - "New messages" button must not flash when: 1. Type "help", 2. Scroll to top, 3. Type "help" again, 4. Expect the "New messages" button not flashy
1034
- // - Hidden by style options
1035
- // - It is already at the bottom (sticky)
1036
- // Any changes to this logic, verify:
1037
- // - "New messages" button should persist while programmatically scrolling to mid-point of the transcript:
1038
- // 1. Type "help"
1039
- // 2. Type "proactive", then immediately scroll to top
1040
- // Expect: the "New messages" button should appear
1041
- // 3. Run hook "useScrollTo({ scrollTop: 500 })"
1042
- // Expect: when the scroll is animating to 500px, the "New messages" button should kept on the screen
1043
- // - "New messages" button must not flashy:
1044
- // 1. Type "help"
1045
- // 2. Scroll to top
1046
- // Expect: no "New messages" button is shown
1047
- // 3. Type "help" again
1048
- // Expect: "New messages" button must not flash-appear
1049
- if (allActivitiesRead || animatingToEnd || hideScrollToEndButton || sticky) {
1050
- return -1;
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();
1051
689
  }
1052
-
1053
- return activities.findIndex(function (activity) {
1054
- return (0, _getActivityUniqueId.default)(activity) === lastReadActivityIdRef.current;
1055
- });
1056
- }, [activities, allActivitiesRead, animatingToEnd, hideScrollToEndButton, lastReadActivityIdRef, sticky]);
1057
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, renderSeparatorAfterIndex !== -1 && /*#__PURE__*/_react.default.createElement(_ScrollToEndButton.default, {
1058
- onClick: handleScrollToEndButtonClick,
1059
- ref: scrollToEndButtonRef
690
+ }, [focusByActivityKey, nextUnreadActivityKeysRef, renderingActivityKeysRef, scrollToEnd, terminatorRef]);
691
+ var renderScrollToEndButton = useCreateScrollToEndButtonRenderer()({
692
+ atEnd: animatingToEnd || atEnd || sticky,
693
+ styleOptions: styleOptions,
694
+ unread: unread
695
+ });
696
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, renderScrollToEndButton && renderScrollToEndButton({
697
+ onClick: handleScrollToEndButtonClick
1060
698
  }), !!_react.default.Children.count(children) && /*#__PURE__*/_react.default.createElement(_FocusRedirector.default, {
1061
- className: "webchat__basic-transcript__sentinel",
1062
699
  redirectRef: terminatorRef
1063
700
  }), /*#__PURE__*/_react.default.createElement(_reactScrollToBottom.Panel, {
1064
701
  className: "webchat__basic-transcript__scrollable"
@@ -1066,103 +703,129 @@ var InternalTranscriptScrollable = function InternalTranscriptScrollable(_ref28)
1066
703
  "aria-hidden": true,
1067
704
  className: "webchat__basic-transcript__filler",
1068
705
  onFocus: onFocusFiller
1069
- }), /*#__PURE__*/_react.default.createElement("ul", {
706
+ }), /*#__PURE__*/_react.default.createElement("section", {
1070
707
  "aria-roledescription": transcriptRoleDescription,
1071
708
  className: (0, _classnames.default)(activitiesStyleSet + '', 'webchat__basic-transcript__transcript'),
1072
- role: "list"
709
+ role: "feed"
1073
710
  }, children), /*#__PURE__*/_react.default.createElement(_BasicTypingIndicator.default, null)));
1074
711
  };
1075
712
 
1076
713
  InternalTranscriptScrollable.propTypes = {
1077
- activities: _propTypes.default.array.isRequired,
1078
714
  children: _propTypes.default.any.isRequired,
1079
- onFocusActivity: _propTypes.default.func.isRequired,
1080
715
  onFocusFiller: _propTypes.default.func.isRequired,
1081
716
  terminatorRef: _propTypes.default.any.isRequired
1082
717
  };
1083
718
 
1084
- var SetScroller = function SetScroller(_ref30) {
1085
- var activityElementsRef = _ref30.activityElementsRef,
1086
- scrollerRef = _ref30.scrollerRef;
1087
-
1088
- var _useStyleOptions7 = useStyleOptions(),
1089
- _useStyleOptions8 = _slicedToArray(_useStyleOptions7, 1),
1090
- _useStyleOptions8$ = _useStyleOptions8[0],
1091
- autoScrollSnapOnActivity = _useStyleOptions8$.autoScrollSnapOnActivity,
1092
- autoScrollSnapOnActivityOffset = _useStyleOptions8$.autoScrollSnapOnActivityOffset,
1093
- autoScrollSnapOnPage = _useStyleOptions8$.autoScrollSnapOnPage,
1094
- autoScrollSnapOnPageOffset = _useStyleOptions8$.autoScrollSnapOnPageOffset;
1095
-
1096
- var _useAcknowledgedActiv3 = (0, _useAcknowledgedActivity.default)(),
1097
- _useAcknowledgedActiv4 = _slicedToArray(_useAcknowledgedActiv3, 1),
1098
- lastAcknowledgedActivity = _useAcknowledgedActiv4[0];
1099
-
1100
- var lastAcknowledgedActivityRef = (0, _react.useRef)(lastAcknowledgedActivity);
1101
- lastAcknowledgedActivityRef.current = lastAcknowledgedActivity;
1102
- scrollerRef.current = (0, _react.useCallback)(function (_ref31) {
1103
- var offsetHeight = _ref31.offsetHeight,
1104
- scrollTop = _ref31.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 _lastAcknowledgedActivity = lastAcknowledgedActivityRef.current;
750
+ var activityElementMap = activityElementMapRef.current;
751
+ var _activityKeys = activityKeysRef.current;
752
+ var _lastAcknowledgedActivityKey = lastAcknowledgedActivityKeyRef.current;
1112
753
  var values = [];
1113
754
 
1114
- if (patchedAutoScrollSnapOnActivity) {
1115
- var _ref32 = activityElementsRef.current[activityElementsRef.current.findIndex(function (_ref33) {
1116
- var activity = _ref33.activity;
1117
- return activity === _lastAcknowledgedActivity;
1118
- }) + patchedAutoScrollSnapOnActivity] || {},
1119
- nthUnacknowledgedActivityElement = _ref32.element;
755
+ var lastAcknowledgedActivityKeyIndex = _activityKeys.indexOf(_lastAcknowledgedActivityKey);
756
+
757
+ if (~lastAcknowledgedActivityKeyIndex) {
758
+ // The activity that we acknowledged could be not rendered, such as post back activity.
759
+ // When calculating scroll snap, we can only base on the first unacknowledged-and-rendering activity.
760
+ var renderingActivityKeys = Array.from(activityElementMap.keys());
761
+ var firstUnacknowledgedActivityElementIndex = -1;
1120
762
 
1121
- if (nthUnacknowledgedActivityElement) {
1122
- values.push(nthUnacknowledgedActivityElement.offsetTop + nthUnacknowledgedActivityElement.offsetHeight - offsetHeight - scrollTop + patchedAutoScrollSnapOnActivityOffset);
763
+ var _iterator = _createForOfIteratorHelper(_activityKeys.slice(0, lastAcknowledgedActivityKeyIndex + 1).reverse()),
764
+ _step;
765
+
766
+ try {
767
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
768
+ var acknowledgedActivityKey = _step.value;
769
+ var index = renderingActivityKeys.indexOf(acknowledgedActivityKey);
770
+
771
+ if (~index) {
772
+ if (index !== renderingActivityKeys.length - 1) {
773
+ firstUnacknowledgedActivityElementIndex = index + 1;
774
+ }
775
+
776
+ break;
777
+ }
778
+ }
779
+ } catch (err) {
780
+ _iterator.e(err);
781
+ } finally {
782
+ _iterator.f();
1123
783
  }
1124
- }
1125
784
 
1126
- if (patchedAutoScrollSnapOnPage) {
1127
- var _ref34 = activityElementsRef.current[activityElementsRef.current.findIndex(function (_ref35) {
1128
- var activity = _ref35.activity;
1129
- return activity === _lastAcknowledgedActivity;
1130
- }) + 1] || {},
1131
- firstUnacknowledgedActivityElement = _ref34.element;
785
+ if (~firstUnacknowledgedActivityElementIndex) {
786
+ var activityElements = Array.from(activityElementMap.values());
787
+
788
+ if (patchedAutoScrollSnapOnActivity) {
789
+ // Gets the activity element which we should snap to.
790
+ var nthUnacknowledgedActivityElement = activityElements[firstUnacknowledgedActivityElementIndex + patchedAutoScrollSnapOnActivity - 1];
791
+
792
+ if (nthUnacknowledgedActivityElement) {
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);
796
+ }
797
+ }
1132
798
 
1133
- if (firstUnacknowledgedActivityElement) {
1134
- values.push(firstUnacknowledgedActivityElement.offsetTop - scrollTop - offsetHeight * (1 - patchedAutoScrollSnapOnPage) + patchedAutoScrollSnapOnPageOffset);
799
+ if (patchedAutoScrollSnapOnPage) {
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);
804
+ }
1135
805
  }
1136
806
  }
1137
807
 
1138
- return values.reduce(function (minValue, value) {
1139
- return Math.min(minValue, value);
1140
- }, Infinity);
808
+ return Math.min.apply(Math, values);
1141
809
  }
1142
810
 
1143
811
  return Infinity;
1144
- }, [activityElementsRef, autoScrollSnapOnActivity, autoScrollSnapOnActivityOffset, autoScrollSnapOnPage, autoScrollSnapOnPageOffset, lastAcknowledgedActivityRef]);
1145
- return false;
812
+ }, [activityElementMapRef, activityKeysRef, lastAcknowledgedActivityKeyRef, styleOptionsRef]);
1146
813
  };
1147
814
 
1148
- var BasicTranscript = function BasicTranscript(_ref36) {
1149
- var className = _ref36.className;
1150
- var activityElementsRef = (0, _react.useRef)([]);
1151
- var scrollerRef = (0, _react.useRef)(function () {
1152
- return Infinity;
1153
- });
1154
- var scroller = (0, _react.useCallback)(function () {
1155
- return scrollerRef.current.apply(scrollerRef, arguments);
1156
- }, [scrollerRef]);
1157
- 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, {
1158
823
  scroller: scroller
1159
- }, /*#__PURE__*/_react.default.createElement(SetScroller, {
1160
- activityElementsRef: activityElementsRef,
1161
- scrollerRef: scrollerRef
1162
- }), /*#__PURE__*/_react.default.createElement(InternalTranscript, {
1163
- activityElementsRef: activityElementsRef,
1164
- className: className
1165
- }));
824
+ }, /*#__PURE__*/_react.default.createElement(_KeyboardHelp.default, null), /*#__PURE__*/_react.default.createElement(InternalTranscript, {
825
+ activityElementMapRef: activityElementMapRef,
826
+ className: className,
827
+ ref: containerRef
828
+ })));
1166
829
  };
1167
830
 
1168
831
  BasicTranscript.defaultProps = {
@@ -1173,4 +836,4 @@ BasicTranscript.propTypes = {
1173
836
  };
1174
837
  var _default = BasicTranscript;
1175
838
  exports.default = _default;
1176
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9CYXNpY1RyYW5zY3JpcHQuanMiXSwibmFtZXMiOlsidXNlQWN0aXZpdGllcyIsImhvb2tzIiwidXNlQ3JlYXRlQWN0aXZpdHlSZW5kZXJlciIsInVzZUNyZWF0ZUFjdGl2aXR5U3RhdHVzUmVuZGVyZXIiLCJ1c2VDcmVhdGVBdmF0YXJSZW5kZXJlciIsInVzZURpcmVjdGlvbiIsInVzZUdyb3VwQWN0aXZpdGllcyIsInVzZUxvY2FsaXplciIsInVzZVN0eWxlT3B0aW9ucyIsIlJPT1RfU1RZTEUiLCJkaXNwbGF5IiwiZmxleERpcmVjdGlvbiIsIm92ZXJmbG93IiwicG9zaXRpb24iLCJmbGV4Iiwib3ZlcmZsb3dYIiwiV2Via2l0T3ZlcmZsb3dTY3JvbGxpbmciLCJsaXN0U3R5bGVUeXBlIiwidmFsaWRhdGVBbGxBY3Rpdml0aWVzVGFnZ2VkIiwiYWN0aXZpdGllcyIsImJpbnMiLCJldmVyeSIsImFjdGl2aXR5Iiwic29tZSIsImJpbiIsImluY2x1ZGVzIiwiSW50ZXJuYWxUcmFuc2NyaXB0IiwiYWN0aXZpdHlFbGVtZW50c1JlZiIsImNsYXNzTmFtZSIsImJhc2ljVHJhbnNjcmlwdFN0eWxlU2V0IiwiYmFzaWNUcmFuc2NyaXB0IiwiYnViYmxlRnJvbVVzZXJOdWJPZmZzZXQiLCJidWJibGVOdWJPZmZzZXQiLCJncm91cFRpbWVzdGFtcCIsImludGVybmFsTGl2ZVJlZ2lvbkZhZGVBZnRlciIsInNob3dBdmF0YXJJbkdyb3VwIiwiZm9jdXNlZEFjdGl2aXR5S2V5Iiwic2V0Rm9jdXNlZEFjdGl2aXR5S2V5IiwiZGlyZWN0aW9uIiwiY3JlYXRlQWN0aXZpdHlSZW5kZXJlciIsImNyZWF0ZUFjdGl2aXR5U3RhdHVzUmVuZGVyZXIiLCJjcmVhdGVBdmF0YXJSZW5kZXJlciIsImZvY3VzIiwiZ3JvdXBBY3Rpdml0aWVzIiwibG9jYWxpemUiLCJyb290Q2xhc3NOYW1lIiwicm9vdEVsZW1lbnRSZWYiLCJ0ZXJtaW5hdG9yUmVmIiwiYWN0aXZpdHlJbnRlcmFjdGl2ZUFsdCIsInRlcm1pbmF0b3JUZXh0IiwidHJhbnNjcmlwdEFyaWFMYWJlbCIsInRyYW5zY3JpcHRSb2xlRGVzY3JpcHRpb24iLCJoaWRlQWxsVGltZXN0YW1wcyIsImNyZWF0ZUFjdGl2aXR5UmVuZGVyZXJXaXRoTGl0ZXJhbEFyZ3MiLCJuZXh0VmlzaWJsZUFjdGl2aXR5IiwiYWN0aXZpdGllc1dpdGhSZW5kZXJlciIsImNyZWF0ZUFjdGl2aXR5UmVuZGVyZXJXaXRoTGl0ZXJhbEFyZ3NNZW1vaXplZCIsImluZGV4IiwibGVuZ3RoIiwicmVuZGVyQWN0aXZpdHkiLCJzcGxpY2UiLCJ2aXNpYmxlQWN0aXZpdGllcyIsIm1hcCIsImFjdGl2aXRpZXNHcm91cEJ5U2VuZGVyIiwic2VuZGVyIiwiYWN0aXZpdGllc0dyb3VwQnlTdGF0dXMiLCJzdGF0dXMiLCJjb25zb2xlIiwid2FybiIsImFjdGl2aXR5VHJlZSIsInZpc2libGVBY3Rpdml0aWVzUGVuZGluZ0dyb3VwaW5nIiwic2VuZGVyVHJlZSIsImFjdGl2aXRpZXNXaXRoU2FtZVNlbmRlciIsImZpbmQiLCJwdXNoIiwiZm9yRWFjaCIsImFjdGl2aXRpZXNXaXRoU2FtZVN0YXR1cyIsImFjdGl2aXRpZXNXaXRoU2FtZVNlbmRlckFuZFN0YXR1cyIsInJlbW92ZUlubGluZSIsInJlbmRlcmluZ0VsZW1lbnRzIiwidG9wU2lkZUJvdE51YiIsInRvcFNpZGVVc2VyTnViIiwiZmlyc3RBY3Rpdml0eSIsInJlbmRlckF2YXRhciIsImluZGV4V2l0aGluU2VuZGVyR3JvdXAiLCJmaXJzdEluU2VuZGVyR3JvdXAiLCJsYXN0SW5TZW5kZXJHcm91cCIsImluZGV4V2l0aGluU2VuZGVyQW5kU3RhdHVzR3JvdXAiLCJyZW5kZXJBY3Rpdml0eVN0YXR1cyIsImZpcnN0SW5TZW5kZXJBbmRTdGF0dXNHcm91cCIsImxhc3RJblNlbmRlckFuZFN0YXR1c0dyb3VwIiwiZW50cnkiLCJrZXkiLCJjaGFubmVsRGF0YSIsIm1lc3NhZ2VCYWNrIiwibWVzc2FnZUJhY2tEaXNwbGF5VGV4dCIsImRpc3BsYXlUZXh0Iiwicm9sZSIsImZyb20iLCJ0ZXh0IiwidG9wU2lkZU51YiIsInNob3dDYWxsb3V0IiwiZm9jdXNBY3Rpdml0eSIsInJvb3RFbGVtZW50IiwiY3VycmVudCIsImNhbGxiYWNrUmVmIiwiYWN0aXZpdHlFbGVtZW50IiwiYWN0aXZpdHlJRCIsImlkIiwiZWxlbWVudCIsImhhbmRsZUZvY3VzIiwiaGFuZGxlS2V5RG93biIsImV2ZW50IiwicHJldmVudERlZmF1bHQiLCJzdG9wUHJvcGFnYXRpb24iLCJoYW5kbGVNb3VzZURvd25DYXB0dXJlIiwidGFyZ2V0IiwidGFiSW5kZXgiLCJnZXRBdHRyaWJ1dGUiLCJoaWRlVGltZXN0YW1wIiwibGl2ZVJlZ2lvbktleSIsInNob3VsZFNwZWFrIiwic3BlYWsiLCJhY3Rpdml0eUVsZW1lbnRzIiwiZWxlbWVudElkIiwiZXhpc3RpbmdFbnRyeSIsImFyaWFMYWJlbElEIiwidG9TdHJpbmciLCJzdWJzdHIiLCJmb2N1c2VkIiwibGFzdEVsZW1lbnQiLCJyZW5kZXJpbmdBY3Rpdml0aWVzIiwic2Nyb2xsVG9Cb3R0b21TY3JvbGxUbyIsInNjcm9sbFRvQm90dG9tU2Nyb2xsVG9FbmQiLCJzY3JvbGxUbyIsImJlaGF2aW9yIiwiRXJyb3IiLCJzY3JvbGxUb3AiLCJzY3JvbGxhYmxlRWxlbWVudCIsInF1ZXJ5U2VsZWN0b3IiLCJnZXRDbGllbnRSZWN0cyIsImFjdGl2aXR5RWxlbWVudEhlaWdodCIsImhlaWdodCIsImFjdGl2aXR5RWxlbWVudFkiLCJ5Iiwic2Nyb2xsYWJsZUhlaWdodCIsImFjdGl2aXR5RWxlbWVudE9mZnNldFRvcCIsIk1hdGgiLCJtaW4iLCJzY3JvbGxSZWxhdGl2ZSIsImRpc3BsYWNlbWVudCIsInNjcm9sbGFibGUiLCJuZXh0U2Nyb2xsVG9wIiwib2Zmc2V0SGVpZ2h0IiwibWF4Iiwic2Nyb2xsSGVpZ2h0IiwiZGlzcGF0Y2hTY3JvbGxQb3NpdGlvbiIsInBhdGNoZWREaXNwYXRjaFNjcm9sbFBvc2l0aW9uIiwicmV2ZXJzZSIsImxhc3RJbnRlcmFjdGVkQWN0aXZpdHkiLCJpbmRleE9mTGFzdEludGVyYWN0ZWRBY3Rpdml0eSIsImluZGV4T2YiLCJhY3RpdmVEZXNjZW5kYW50RWxlbWVudElkIiwic2Nyb2xsQWN0aXZlRGVzY2VuZGFudEludG9WaWV3IiwiYWN0aXZlRGVzY2VuZGFudCIsImRvY3VtZW50IiwiZ2V0RWxlbWVudEJ5SWQiLCJjb250YWlucyIsImFjdGl2ZUVsZW1lbnQiLCJkb2N1bWVudEVsZW1lbnQiLCJzdHlsZSIsInNjcm9sbEludG9WaWV3IiwiYmxvY2siLCJzY3JvbGxUb3BBdFRvcFNpZGUiLCJvZmZzZXRUb3AiLCJzY3JvbGxUb3BBdEJvdHRvbVNpZGUiLCJoYW5kbGVUcmFuc2NyaXB0Rm9jdXMiLCJjdXJyZW50VGFyZ2V0IiwidW5kZWZpbmVkIiwiZm9jdXNSZWxhdGl2ZUFjdGl2aXR5IiwiZGVsdGEiLCJpc05hTiIsImZpbmRJbmRleCIsIm5leHRJbmRleCIsIm5leHRGb2N1c2VkQWN0aXZpdHkiLCJoYW5kbGVUcmFuc2NyaXB0S2V5RG93biIsImZyb21FbmRPZlRyYW5zY3JpcHRJbmRpY2F0b3IiLCJmcm9tVHJhbnNjcmlwdCIsImhhbmRsZWQiLCJJbmZpbml0eSIsImZvY3VzZWRBY3Rpdml0eUVudHJ5IiwiZm9jdXNlZEFjdGl2aXR5RWxlbWVudCIsImZpbHRlciIsImZpcnN0VGFiYmFibGVFbGVtZW50IiwibGFiZWxJZCIsInNldEJvdHRvbW1vc3RGb2N1c2VkQWN0aXZpdHlLZXlJZk5lZWRlZCIsImxhc3RBY3Rpdml0eUtleSIsImhhbmRsZVRyYW5zY3JpcHRLZXlEb3duQ2FwdHVyZSIsImFsdEtleSIsImN0cmxLZXkiLCJtZXRhS2V5IiwiZm9jdXNUcmFuc2NyaXB0Q2FsbGJhY2siLCJoYW5kbGVGb2N1c0FjdGl2aXR5IiwiZGlzcGF0Y2hUcmFuc2NyaXB0Rm9jdXMiLCJmb2N1c2VkQWN0aXZpdHkiLCJoYW5kbGVGb2N1c0ZpbGxlciIsImlzQ29udGVudEludGVyYWN0aXZlIiwiZGVmYXVsdFByb3BzIiwicHJvcFR5cGVzIiwiUHJvcFR5cGVzIiwic2hhcGUiLCJhcnJheSIsImlzUmVxdWlyZWQiLCJzdHJpbmciLCJJbnRlcm5hbFNjcmVlblJlYWRlclRyYW5zY3JpcHQiLCJhcnJheU9mIiwiYW55IiwiSW50ZXJuYWxUcmFuc2NyaXB0U2Nyb2xsYWJsZSIsImNoaWxkcmVuIiwib25Gb2N1c0FjdGl2aXR5Iiwib25Gb2N1c0ZpbGxlciIsImFjdGl2aXRpZXNTdHlsZVNldCIsImhpZGVTY3JvbGxUb0VuZEJ1dHRvbiIsImFuaW1hdGluZ1RvRW5kIiwic3RpY2t5IiwibGFzdFZpc2libGVBY3Rpdml0eUlkIiwic2Nyb2xsVG9FbmRCdXR0b25SZWYiLCJsYXN0UmVhZEFjdGl2aXR5SWRSZWYiLCJhbGxBY3Rpdml0aWVzUmVhZCIsImhhbmRsZVNjcm9sbFRvRW5kQnV0dG9uQ2xpY2siLCJmaXJzdFVucmVhZEFjdGl2aXR5IiwicmVuZGVyU2VwYXJhdG9yQWZ0ZXJJbmRleCIsIlJlYWN0IiwiQ2hpbGRyZW4iLCJjb3VudCIsImZ1bmMiLCJTZXRTY3JvbGxlciIsInNjcm9sbGVyUmVmIiwiYXV0b1Njcm9sbFNuYXBPbkFjdGl2aXR5IiwiYXV0b1Njcm9sbFNuYXBPbkFjdGl2aXR5T2Zmc2V0IiwiYXV0b1Njcm9sbFNuYXBPblBhZ2UiLCJhdXRvU2Nyb2xsU25hcE9uUGFnZU9mZnNldCIsImxhc3RBY2tub3dsZWRnZWRBY3Rpdml0eSIsImxhc3RBY2tub3dsZWRnZWRBY3Rpdml0eVJlZiIsInBhdGNoZWRBdXRvU2Nyb2xsU25hcE9uQWN0aXZpdHkiLCJwYXRjaGVkQXV0b1Njcm9sbFNuYXBPblBhZ2UiLCJwYXRjaGVkQXV0b1Njcm9sbFNuYXBPbkFjdGl2aXR5T2Zmc2V0IiwicGF0Y2hlZEF1dG9TY3JvbGxTbmFwT25QYWdlT2Zmc2V0IiwidmFsdWVzIiwibnRoVW5hY2tub3dsZWRnZWRBY3Rpdml0eUVsZW1lbnQiLCJmaXJzdFVuYWNrbm93bGVkZ2VkQWN0aXZpdHlFbGVtZW50IiwicmVkdWNlIiwibWluVmFsdWUiLCJ2YWx1ZSIsIkJhc2ljVHJhbnNjcmlwdCIsInNjcm9sbGVyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFFQTs7QUFDQTs7QUFTQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFFQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQUdFQSxhLEdBUUVDLDZCLENBUkZELGE7SUFDQUUseUIsR0FPRUQsNkIsQ0FQRkMseUI7SUFDQUMsK0IsR0FNRUYsNkIsQ0FORkUsK0I7SUFDQUMsdUIsR0FLRUgsNkIsQ0FMRkcsdUI7SUFDQUMsWSxHQUlFSiw2QixDQUpGSSxZO0lBQ0FDLGtCLEdBR0VMLDZCLENBSEZLLGtCO0lBQ0FDLFksR0FFRU4sNkIsQ0FGRk0sWTtJQUNBQyxlLEdBQ0VQLDZCLENBREZPLGU7QUFHRixJQUFNQyxVQUFVLEdBQUc7QUFDakIsaUNBQStCO0FBQzdCQyxJQUFBQSxPQUFPLEVBQUUsTUFEb0I7QUFFN0JDLElBQUFBLGFBQWEsRUFBRSxRQUZjO0FBRzdCQyxJQUFBQSxRQUFRLEVBQUUsUUFIbUI7QUFJN0I7QUFDQTtBQUNBO0FBQ0FDLElBQUFBLFFBQVEsRUFBRSxVQVBtQjtBQVM3Qiw0Q0FBd0M7QUFDdENDLE1BQUFBLElBQUksRUFBRTtBQURnQyxLQVRYO0FBYTdCLGdEQUE0QztBQUMxQ0osTUFBQUEsT0FBTyxFQUFFLE1BRGlDO0FBRTFDQyxNQUFBQSxhQUFhLEVBQUUsUUFGMkI7QUFHMUNJLE1BQUFBLFNBQVMsRUFBRSxRQUgrQjtBQUkxQ0MsTUFBQUEsdUJBQXVCLEVBQUU7QUFKaUIsS0FiZjtBQW9CN0IsZ0RBQTRDO0FBQzFDQyxNQUFBQSxhQUFhLEVB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QUEsUUFBUSxFQUFFa0I7QUFBdkMsa0JBQ0UsNkJBQUMsV0FBRDtBQUFhLElBQUEsbUJBQW1CLEVBQUVwTyxtQkFBbEM7QUFBdUQsSUFBQSxXQUFXLEVBQUVrTjtBQUFwRSxJQURGLGVBRUUsNkJBQUMsa0JBQUQ7QUFBb0IsSUFBQSxtQkFBbUIsRUFBRWxOLG1CQUF6QztBQUE4RCxJQUFBLFNBQVMsRUFBRUM7QUFBekUsSUFGRixDQURGO0FBTUQsQ0FaRDs7QUFjQWtPLGVBQWUsQ0FBQy9DLFlBQWhCLEdBQStCO0FBQzdCbkwsRUFBQUEsU0FBUyxFQUFFO0FBRGtCLENBQS9CO0FBSUFrTyxlQUFlLENBQUM5QyxTQUFoQixHQUE0QjtBQUMxQnBMLEVBQUFBLFNBQVMsRUFBRXFMLG1CQUFVSTtBQURLLENBQTVCO2VBSWV5QyxlIiwic291cmNlUm9vdCI6ImNvbXBvbmVudDovLy8iLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQgbm8tbWFnaWMtbnVtYmVyczogW1wiZXJyb3JcIiwgeyBcImlnbm9yZVwiOiBbLTEsIDAsIDEsIDIsIDUsIDM2XSB9XSAqL1xuXG5pbXBvcnQgeyBob29rcyB9IGZyb20gJ2JvdGZyYW1ld29yay13ZWJjaGF0LWFwaSc7XG5pbXBvcnQge1xuICBDb21wb3NlciBhcyBSZWFjdFNjcm9sbFRvQm90dG9tQ29tcG9zZXIsXG4gIFBhbmVsIGFzIFJlYWN0U2Nyb2xsVG9Cb3R0b21QYW5lbCxcbiAgdXNlQW5pbWF0aW5nVG9FbmQsXG4gIHVzZU9ic2VydmVTY3JvbGxQb3NpdGlvbixcbiAgdXNlU2Nyb2xsVG8sXG4gIHVzZVNjcm9sbFRvRW5kLFxuICB1c2VTdGlja3lcbn0gZnJvbSAncmVhY3Qtc2Nyb2xsLXRvLWJvdHRvbSc7XG5pbXBvcnQgY2xhc3NOYW1lcyBmcm9tICdjbGFzc25hbWVzJztcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5pbXBvcnQgcmFuZG9tIGZyb20gJ21hdGgtcmFuZG9tJztcbmltcG9ydCBSZWFjdCwgeyB1c2VDYWxsYmFjaywgdXNlRWZmZWN0LCB1c2VNZW1vLCB1c2VSZWYsIHVzZVN0YXRlIH0gZnJvbSAncmVhY3QnO1xuXG5pbXBvcnQgQmFzaWNUeXBpbmdJbmRpY2F0b3IgZnJvbSAnLi9CYXNpY1R5cGluZ0luZGljYXRvcic7XG5pbXBvcnQgRmFkZSBmcm9tICcuL1V0aWxzL0ZhZGUnO1xuaW1wb3J0IEZvY3VzUmVkaXJlY3RvciBmcm9tICcuL1V0aWxzL0ZvY3VzUmVkaXJlY3Rvcic7XG5pbXBvcnQgZ2V0QWN0aXZpdHlVbmlxdWVJZCBmcm9tICcuL1V0aWxzL2dldEFjdGl2aXR5VW5pcXVlSWQnO1xuaW1wb3J0IGdldFRhYkluZGV4IGZyb20gJy4vVXRpbHMvVHlwZUZvY3VzU2luay9nZXRUYWJJbmRleCc7XG5pbXBvcnQgaW5wdXR0YWJsZUtleSBmcm9tICcuL1V0aWxzL1R5cGVGb2N1c1NpbmsvaW5wdXR0YWJsZUtleSc7XG5pbXBvcnQgaW50ZXJzZWN0aW9uT2YgZnJvbSAnLi9VdGlscy9pbnRlcnNlY3Rpb25PZic7XG5pbXBvcnQgaXNaZXJvT3JQb3NpdGl2ZSBmcm9tICcuL1V0aWxzL2lzWmVyb09yUG9zaXRpdmUnO1xuaW1wb3J0IHJlbW92ZUlubGluZSBmcm9tICcuL1V0aWxzL3JlbW92ZUlubGluZSc7XG5pbXBvcnQgU2NyZWVuUmVhZGVyQWN0aXZpdHkgZnJvbSAnLi9TY3JlZW5SZWFkZXJBY3Rpdml0eSc7XG5pbXBvcnQgU2NyZWVuUmVhZGVyVGV4dCBmcm9tICcuL1NjcmVlblJlYWRlclRleHQnO1xuaW1wb3J0IFNjcm9sbFRvRW5kQnV0dG9uIGZyb20gJy4vQWN0aXZpdHkvU2Nyb2xsVG9FbmRCdXR0b24nO1xuaW1wb3J0IFNwZWFrQWN0aXZpdHkgZnJvbSAnLi9BY3Rpdml0eS9TcGVhayc7XG5pbXBvcnQgdGFiYmFibGVFbGVtZW50cyBmcm9tICcuL1V0aWxzL3RhYmJhYmxlRWxlbWVudHMnO1xuaW1wb3J0IHVzZUFja25vd2xlZGdlZEFjdGl2aXR5IGZyb20gJy4vaG9va3MvaW50ZXJuYWwvdXNlQWNrbm93bGVkZ2VkQWN0aXZpdHknO1xuaW1wb3J0IHVzZURpc3BhdGNoU2Nyb2xsUG9zaXRpb24gZnJvbSAnLi9ob29rcy9pbnRlcm5hbC91c2VEaXNwYXRjaFNjcm9sbFBvc2l0aW9uJztcbmltcG9ydCB1c2VEaXNwYXRjaFRyYW5zY3JpcHRGb2N1cyBmcm9tICcuL2hvb2tzL2ludGVybmFsL3VzZURpc3BhdGNoVHJhbnNjcmlwdEZvY3VzJztcbmltcG9ydCB1c2VGb2N1cyBmcm9tICcuL2hvb2tzL3VzZUZvY3VzJztcbmltcG9ydCB1c2VNZW1vaXplIGZyb20gJy4vaG9va3MvaW50ZXJuYWwvdXNlTWVtb2l6ZSc7XG5pbXBvcnQgdXNlUmVnaXN0ZXJGb2N1c1RyYW5zY3JpcHQgZnJvbSAnLi9ob29rcy9pbnRlcm5hbC91c2VSZWdpc3RlckZvY3VzVHJhbnNjcmlwdCc7XG5pbXBvcnQgdXNlUmVnaXN0ZXJTY3JvbGxSZWxhdGl2ZSBmcm9tICcuL2hvb2tzL2ludGVybmFsL3VzZVJlZ2lzdGVyU2Nyb2xsUmVsYXRpdmUnO1xuaW1wb3J0IHVzZVJlZ2lzdGVyU2Nyb2xsVG8gZnJvbSAnLi9ob29rcy9pbnRlcm5hbC91c2VSZWdpc3RlclNjcm9sbFRvJztcbmltcG9ydCB1c2VSZWdpc3RlclNjcm9sbFRvRW5kIGZyb20gJy4vaG9va3MvaW50ZXJuYWwvdXNlUmVnaXN0ZXJTY3JvbGxUb0VuZCc7XG5pbXBvcnQgdXNlU3R5bGVTZXQgZnJvbSAnLi9ob29rcy91c2VTdHlsZVNldCc7XG5pbXBvcnQgdXNlU3R5bGVUb0Vtb3Rpb25PYmplY3QgZnJvbSAnLi9ob29rcy9pbnRlcm5hbC91c2VTdHlsZVRvRW1vdGlvbk9iamVjdCc7XG5pbXBvcnQgdXNlVW5pcXVlSWQgZnJvbSAnLi9ob29rcy9pbnRlcm5hbC91c2VVbmlxdWVJZCc7XG5cbmNvbnN0IHtcbiAgdXNlQWN0aXZpdGllcyxcbiAgdXNlQ3JlYXRlQWN0aXZpdHlSZW5kZXJlcixcbiAgdXNlQ3JlYXRlQWN0aXZpdHlTdGF0dXNSZW5kZXJlcixcbiAgdXNlQ3JlYXRlQXZhdGFyUmVuZGVyZXIsXG4gIHVzZURpcmVjdGlvbixcbiAgdXNlR3JvdXBBY3Rpdml0aWVzLFxuICB1c2VMb2NhbGl6ZXIsXG4gIHVzZVN0eWxlT3B0aW9uc1xufSA9IGhvb2tzO1xuXG5jb25zdCBST09UX1NUWUxFID0ge1xuICAnJi53ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0Jzoge1xuICAgIGRpc3BsYXk6ICdmbGV4JyxcbiAgICBmbGV4RGlyZWN0aW9uOiAnY29sdW1uJyxcbiAgICBvdmVyZmxvdzogJ2hpZGRlbicsXG4gICAgLy8gTWFrZSBzdXJlIHRvIHNldCBcInBvc2l0aW9uOiByZWxhdGl2ZVwiIGhlcmUgdG8gZm9ybSBhbm90aGVyIHN0YWNraW5nIGNvbnRleHQgZm9yIHRoZSBzY3JvbGwtdG8tZW5kIGJ1dHRvbi5cbiAgICAvLyBTdGFja2luZyBjb250ZXh0IGhlbHAgaXNvbGF0aW5nIGVsZW1lbnRzIHRoYXQgdXNlIFwiei1pbmRleFwiIGZyb20gZ2xvYmFsIHBvbGx1dGlvbi5cbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9DU1MvQ1NTX1Bvc2l0aW9uaW5nL1VuZGVyc3RhbmRpbmdfel9pbmRleC9UaGVfc3RhY2tpbmdfY29udGV4dFxuICAgIHBvc2l0aW9uOiAncmVsYXRpdmUnLFxuXG4gICAgJyYgLndlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX2ZpbGxlcic6IHtcbiAgICAgIGZsZXg6IDFcbiAgICB9LFxuXG4gICAgJyYgLndlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX3Njcm9sbGFibGUnOiB7XG4gICAgICBkaXNwbGF5OiAnZmxleCcsXG4gICAgICBmbGV4RGlyZWN0aW9uOiAnY29sdW1uJyxcbiAgICAgIG92ZXJmbG93WDogJ2hpZGRlbicsXG4gICAgICBXZWJraXRPdmVyZmxvd1Njcm9sbGluZzogJ3RvdWNoJ1xuICAgIH0sXG5cbiAgICAnJiAud2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fdHJhbnNjcmlwdCc6IHtcbiAgICAgIGxpc3RTdHlsZVR5cGU6ICdub25lJ1xuICAgIH1cbiAgfVxufTtcblxuZnVuY3Rpb24gdmFsaWRhdGVBbGxBY3Rpdml0aWVzVGFnZ2VkKGFjdGl2aXRpZXMsIGJpbnMpIHtcbiAgcmV0dXJuIGFjdGl2aXRpZXMuZXZlcnkoYWN0aXZpdHkgPT4gYmlucy5zb21lKGJpbiA9PiBiaW4uaW5jbHVkZXMoYWN0aXZpdHkpKSk7XG59XG5cbmNvbnN0IEludGVybmFsVHJhbnNjcmlwdCA9ICh7IGFjdGl2aXR5RWxlbWVudHNSZWYsIGNsYXNzTmFtZSB9KSA9PiB7XG4gIGNvbnN0IFt7IGJhc2ljVHJhbnNjcmlwdDogYmFzaWNUcmFuc2NyaXB0U3R5bGVTZXQgfV0gPSB1c2VTdHlsZVNldCgpO1xuICBjb25zdCBbXG4gICAgeyBidWJibGVGcm9tVXNlck51Yk9mZnNldCwgYnViYmxlTnViT2Zmc2V0LCBncm91cFRpbWVzdGFtcCwgaW50ZXJuYWxMaXZlUmVnaW9uRmFkZUFmdGVyLCBzaG93QXZhdGFySW5Hcm91cCB9XG4gIF0gPSB1c2VTdHlsZU9wdGlvbnMoKTtcbiAgY29uc3QgW2ZvY3VzZWRBY3Rpdml0eUtleSwgc2V0Rm9jdXNlZEFjdGl2aXR5S2V5XSA9IHVzZVN0YXRlKCk7XG4gIGNvbnN0IFthY3Rpdml0aWVzXSA9IHVzZUFjdGl2aXRpZXMoKTtcbiAgY29uc3QgW2RpcmVjdGlvbl0gPSB1c2VEaXJlY3Rpb24oKTtcbiAgY29uc3QgY3JlYXRlQWN0aXZpdHlSZW5kZXJlciA9IHVzZUNyZWF0ZUFjdGl2aXR5UmVuZGVyZXIoKTtcbiAgY29uc3QgY3JlYXRlQWN0aXZpdHlTdGF0dXNSZW5kZXJlciA9IHVzZUNyZWF0ZUFjdGl2aXR5U3RhdHVzUmVuZGVyZXIoKTtcbiAgY29uc3QgY3JlYXRlQXZhdGFyUmVuZGVyZXIgPSB1c2VDcmVhdGVBdmF0YXJSZW5kZXJlcigpO1xuICBjb25zdCBmb2N1cyA9IHVzZUZvY3VzKCk7XG4gIGNvbnN0IGdyb3VwQWN0aXZpdGllcyA9IHVzZUdyb3VwQWN0aXZpdGllcygpO1xuICBjb25zdCBsb2NhbGl6ZSA9IHVzZUxvY2FsaXplcigpO1xuICBjb25zdCByb290Q2xhc3NOYW1lID0gdXNlU3R5bGVUb0Vtb3Rpb25PYmplY3QoKShST09UX1NUWUxFKSArICcnO1xuICBjb25zdCByb290RWxlbWVudFJlZiA9IHVzZVJlZigpO1xuICBjb25zdCB0ZXJtaW5hdG9yUmVmID0gdXNlUmVmKCk7XG5cbiAgY29uc3QgYWN0aXZpdHlJbnRlcmFjdGl2ZUFsdCA9IGxvY2FsaXplKCdBQ1RJVklUWV9JTlRFUkFDVElWRV9MQUJFTF9BTFQnKTtcbiAgY29uc3QgdGVybWluYXRvclRleHQgPSBsb2NhbGl6ZSgnVFJBTlNDUklQVF9URVJNSU5BVE9SX1RFWFQnKTtcbiAgY29uc3QgdHJhbnNjcmlwdEFyaWFMYWJlbCA9IGxvY2FsaXplKCdUUkFOU0NSSVBUX0FSSUFfTEFCRUxfQUxUJyk7XG4gIGNvbnN0IHRyYW5zY3JpcHRSb2xlRGVzY3JpcHRpb24gPSBsb2NhbGl6ZSgnVFJBTlNDUklQVF9BUklBX1JPTEVfQUxUJyk7XG5cbiAgY29uc3QgaGlkZUFsbFRpbWVzdGFtcHMgPSBncm91cFRpbWVzdGFtcCA9PT0gZmFsc2U7XG5cbiAgLy8gR2V0cyByZW5kZXJlciBmb3IgZXZlcnkgYWN0aXZpdHkuXG4gIC8vIEFjdGl2aXRpZXMgdGhhdCBhcmUgbm90IHZpc2libGUgd2lsbCByZXR1cm4gYSBmYWxzeSByZW5kZXJlci5cblxuICAvLyBDb252ZXJ0ZWQgZnJvbSBjcmVhdGVBY3Rpdml0eVJlbmRlcmVyKHsgYWN0aXZpdHksIG5leHRWaXNpYmxlQWN0aXZpdHkgfSkgdG8gY3JlYXRlQWN0aXZpdHlSZW5kZXJlcihhY3Rpdml0eSwgbmV4dFZpc2libGVBY3Rpdml0eSkuXG4gIC8vIFRoaXMgaXMgZm9yIHRoZSBtZW1vaXphdGlvbiBmdW5jdGlvbiB0byBjYWNoZSB0aGUgYXJndW1lbnRzLiBNZW1vaXplciBjYW4gb25seSBjYWNoZSBsaXRlcmFsIGFyZ3VtZW50cy5cbiAgY29uc3QgY3JlYXRlQWN0aXZpdHlSZW5kZXJlcldpdGhMaXRlcmFsQXJncyA9IHVzZUNhbGxiYWNrKFxuICAgIChhY3Rpdml0eSwgbmV4dFZpc2libGVBY3Rpdml0eSkgPT4gY3JlYXRlQWN0aXZpdHlSZW5kZXJlcih7IGFjdGl2aXR5LCBuZXh0VmlzaWJsZUFjdGl2aXR5IH0pLFxuICAgIFtjcmVhdGVBY3Rpdml0eVJlbmRlcmVyXVxuICApO1xuXG4gIC8vIENyZWF0ZSBhIG1lbW9pemVkIGNvbnRleHQgb2YgdGhlIGNyZWF0ZUFjdGl2aXR5UmVuZGVyZXIgZnVuY3Rpb24uXG4gIGNvbnN0IGFjdGl2aXRpZXNXaXRoUmVuZGVyZXIgPSB1c2VNZW1vaXplKFxuICAgIGNyZWF0ZUFjdGl2aXR5UmVuZGVyZXJXaXRoTGl0ZXJhbEFyZ3MsXG4gICAgY3JlYXRlQWN0aXZpdHlSZW5kZXJlcldpdGhMaXRlcmFsQXJnc01lbW9pemVkID0+IHtcbiAgICAgIC8vIEFsbCBjYWxscyB0byBjcmVhdGVBY3Rpdml0eVJlbmRlcmVyV2l0aExpdGVyYWxBcmdzTWVtb2l6ZWQoKSBpbiB0aGlzIGZ1bmN0aW9uIHdpbGwgYmUgbWVtb2l6ZWQgKExSVSA9IDEpLlxuICAgICAgLy8gSW4gdGhlIG5leHQgcmVuZGVyIGN5Y2xlLCBjYWxscyB0byBjcmVhdGVBY3Rpdml0eVJlbmRlcmVyV2l0aExpdGVyYWxBcmdzTWVtb2l6ZWQoKSBtaWdodCByZXR1cm4gdGhlIG1lbW9pemVkIHJlc3VsdCBpbnN0ZWFkLlxuICAgICAgLy8gVGhpcyBpcyBhbiBpbXByb3ZlbWVudCB0byBSZWFjdCB1c2VNZW1vKCksIGJlY2F1c2UgaXQgb25seSBhbGxvd3MgMSBtZW1vaXphdGlvbi5cbiAgICAgIC8vIHVzZU1lbW9pemUoKSBhbGxvd3MgYW55IG51bWJlciBvZiBtZW1vaXphdGlvbi5cblxuICAgICAgY29uc3QgYWN0aXZpdGllc1dpdGhSZW5kZXJlciA9IFtdO1xuICAgICAgbGV0IG5leHRWaXNpYmxlQWN0aXZpdHk7XG5cbiAgICAgIGZvciAobGV0IGluZGV4ID0gYWN0aXZpdGllcy5sZW5ndGggLSAxOyBpbmRleCA+PSAwOyBpbmRleC0tKSB7XG4gICAgICAgIGNvbnN0IGFjdGl2aXR5ID0gYWN0aXZpdGllc1tpbmRleF07XG4gICAgICAgIGNvbnN0IHJlbmRlckFjdGl2aXR5ID0gY3JlYXRlQWN0aXZpdHlSZW5kZXJlcldpdGhMaXRlcmFsQXJnc01lbW9pemVkKGFjdGl2aXR5LCBuZXh0VmlzaWJsZUFjdGl2aXR5KTtcblxuICAgICAgICBpZiAocmVuZGVyQWN0aXZpdHkpIHtcbiAgICAgICAgICBhY3Rpdml0aWVzV2l0aFJlbmRlcmVyLnNwbGljZSgwLCAwLCB7XG4gICAgICAgICAgICBhY3Rpdml0eSxcbiAgICAgICAgICAgIHJlbmRlckFjdGl2aXR5XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBuZXh0VmlzaWJsZUFjdGl2aXR5ID0gYWN0aXZpdHk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGFjdGl2aXRpZXNXaXRoUmVuZGVyZXI7XG4gICAgfSxcbiAgICBbYWN0aXZpdGllc11cbiAgKTtcblxuICBjb25zdCB2aXNpYmxlQWN0aXZpdGllcyA9IHVzZU1lbW8oKCkgPT4gYWN0aXZpdGllc1dpdGhSZW5kZXJlci5tYXAoKHsgYWN0aXZpdHkgfSkgPT4gYWN0aXZpdHkpLCBbXG4gICAgYWN0aXZpdGllc1dpdGhSZW5kZXJlclxuICBdKTtcblxuICAvLyBUYWcgYWN0aXZpdGllcyBiYXNlZCBvbiB0eXBlcy5cbiAgLy8gVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gdGFnIGludG8gMiB0eXBlczogc2VuZGVyIGFuZCBzdGF0dXMuXG5cbiAgY29uc3QgeyBhY3Rpdml0aWVzR3JvdXBCeVNlbmRlciwgYWN0aXZpdGllc0dyb3VwQnlTdGF0dXMgfSA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIGNvbnN0IHsgc2VuZGVyOiBhY3Rpdml0aWVzR3JvdXBCeVNlbmRlciwgc3RhdHVzOiBhY3Rpdml0aWVzR3JvdXBCeVN0YXR1cyB9ID0gZ3JvdXBBY3Rpdml0aWVzKHtcbiAgICAgIGFjdGl2aXRpZXM6IHZpc2libGVBY3Rpdml0aWVzXG4gICAgfSk7XG5cbiAgICBpZiAoIXZhbGlkYXRlQWxsQWN0aXZpdGllc1RhZ2dlZCh2aXNpYmxlQWN0aXZpdGllcywgYWN0aXZpdGllc0dyb3VwQnlTZW5kZXIpKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICdib3RmcmFtZXdvcmstd2ViY2hhdDogTm90IGV2ZXJ5IGFjdGl2aXRpZXMgYXJlIGdyb3VwZWQgaW4gdGhlIFwic2VuZGVyXCIgcHJvcGVydHkuIFBsZWFzZSBmaXggXCJncm91cEFjdGl2aXRpZXNNaWRkbGV3YXJlXCIgYW5kIGdyb3VwIGV2ZXJ5IGFjdGl2aXRpZXMuJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoIXZhbGlkYXRlQWxsQWN0aXZpdGllc1RhZ2dlZCh2aXNpYmxlQWN0aXZpdGllcywgYWN0aXZpdGllc0dyb3VwQnlTdGF0dXMpKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICdib3RmcmFtZXdvcmstd2ViY2hhdDogTm90IGV2ZXJ5IGFjdGl2aXRpZXMgYXJlIGdyb3VwZWQgaW4gdGhlIFwic3RhdHVzXCIgcHJvcGVydHkuIFBsZWFzZSBmaXggXCJncm91cEFjdGl2aXRpZXNNaWRkbGV3YXJlXCIgYW5kIGdyb3VwIGV2ZXJ5IGFjdGl2aXRpZXMuJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgYWN0aXZpdGllc0dyb3VwQnlTZW5kZXIsXG4gICAgICBhY3Rpdml0aWVzR3JvdXBCeVN0YXR1c1xuICAgIH07XG4gIH0sIFtncm91cEFjdGl2aXRpZXMsIHZpc2libGVBY3Rpdml0aWVzXSk7XG5cbiAgLy8gQ3JlYXRlIGEgdHJlZSBvZiBhY3Rpdml0aWVzIHdpdGggMiBkaW1lbnNpb25zOiBzZW5kZXIsIGZvbGxvd2VkIGJ5IHN0YXR1cy5cblxuICBjb25zdCBhY3Rpdml0eVRyZWUgPSB1c2VNZW1vKCgpID0+IHtcbiAgICBjb25zdCB2aXNpYmxlQWN0aXZpdGllc1BlbmRpbmdHcm91cGluZyA9IFsuLi52aXNpYmxlQWN0aXZpdGllc107XG4gICAgY29uc3QgYWN0aXZpdHlUcmVlID0gW107XG5cbiAgICB3aGlsZSAodmlzaWJsZUFjdGl2aXRpZXNQZW5kaW5nR3JvdXBpbmcubGVuZ3RoKSB7XG4gICAgICBjb25zdCBbYWN0aXZpdHldID0gdmlzaWJsZUFjdGl2aXRpZXNQZW5kaW5nR3JvdXBpbmc7XG4gICAgICBjb25zdCBzZW5kZXJUcmVlID0gW107XG4gICAgICBjb25zdCBhY3Rpdml0aWVzV2l0aFNhbWVTZW5kZXIgPSBhY3Rpdml0aWVzR3JvdXBCeVNlbmRlci5maW5kKGFjdGl2aXRpZXMgPT4gYWN0aXZpdGllcy5pbmNsdWRlcyhhY3Rpdml0eSkpO1xuXG4gICAgICBhY3Rpdml0eVRyZWUucHVzaChzZW5kZXJUcmVlKTtcblxuICAgICAgYWN0aXZpdGllc1dpdGhTYW1lU2VuZGVyLmZvckVhY2goYWN0aXZpdHkgPT4ge1xuICAgICAgICBjb25zdCBhY3Rpdml0aWVzV2l0aFNhbWVTdGF0dXMgPSBhY3Rpdml0aWVzR3JvdXBCeVN0YXR1cy5maW5kKGFjdGl2aXRpZXMgPT4gYWN0aXZpdGllcy5pbmNsdWRlcyhhY3Rpdml0eSkpO1xuXG4gICAgICAgIGNvbnN0IGFjdGl2aXRpZXNXaXRoU2FtZVNlbmRlckFuZFN0YXR1cyA9IGludGVyc2VjdGlvbk9mKFxuICAgICAgICAgIHZpc2libGVBY3Rpdml0aWVzUGVuZGluZ0dyb3VwaW5nLFxuICAgICAgICAgIGFjdGl2aXRpZXNXaXRoU2FtZVNlbmRlcixcbiAgICAgICAgICBhY3Rpdml0aWVzV2l0aFNhbWVTdGF0dXNcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoYWN0aXZpdGllc1dpdGhTYW1lU2VuZGVyQW5kU3RhdHVzLmxlbmd0aCkge1xuICAgICAgICAgIHNlbmRlclRyZWUucHVzaChhY3Rpdml0aWVzV2l0aFNhbWVTZW5kZXJBbmRTdGF0dXMpO1xuICAgICAgICAgIHJlbW92ZUlubGluZSh2aXNpYmxlQWN0aXZpdGllc1BlbmRpbmdHcm91cGluZywgLi4uYWN0aXZpdGllc1dpdGhTYW1lU2VuZGVyQW5kU3RhdHVzKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gQXNzZXJ0aW9uOiBBbGwgYWN0aXZpdGllcyBpbiB2aXNpYmxlQWN0aXZpdGllcywgbXVzdCBiZSBhc3NpZ25lZCB0byB0aGUgYWN0aXZpdHlUcmVlXG4gICAgaWYgKFxuICAgICAgIXZpc2libGVBY3Rpdml0aWVzLmV2ZXJ5KGFjdGl2aXR5ID0+XG4gICAgICAgIGFjdGl2aXR5VHJlZS5zb21lKGFjdGl2aXRpZXNXaXRoU2FtZVNlbmRlciA9PlxuICAgICAgICAgIGFjdGl2aXRpZXNXaXRoU2FtZVNlbmRlci5zb21lKGFjdGl2aXRpZXNXaXRoU2FtZVNlbmRlckFuZFN0YXR1cyA9PlxuICAgICAgICAgICAgYWN0aXZpdGllc1dpdGhTYW1lU2VuZGVyQW5kU3RhdHVzLmluY2x1ZGVzKGFjdGl2aXR5KVxuICAgICAgICAgIClcbiAgICAgICAgKVxuICAgICAgKVxuICAgICkge1xuICAgICAgY29uc29sZS53YXJuKCdib3RmcmFtZXdvcmstd2ViY2hhdCBpbnRlcm5hbDogTm90IGFsbCB2aXNpYmxlIGFjdGl2aXRpZXMgYXJlIGdyb3VwZWQgaW4gdGhlIGFjdGl2aXR5VHJlZS4nLCB7XG4gICAgICAgIHZpc2libGVBY3Rpdml0aWVzLFxuICAgICAgICBhY3Rpdml0eVRyZWVcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBhY3Rpdml0eVRyZWU7XG4gIH0sIFthY3Rpdml0aWVzR3JvdXBCeVNlbmRlciwgYWN0aXZpdGllc0dyb3VwQnlTdGF0dXMsIHZpc2libGVBY3Rpdml0aWVzXSk7XG5cbiAgLy8gRmxhdHRlbiB0aGUgdHJlZSBiYWNrIGludG8gYW4gYXJyYXkgd2l0aCBpbmZvcm1hdGlvbiByZWxhdGVkIHRvIHJlbmRlcmluZy5cblxuICBjb25zdCByZW5kZXJpbmdFbGVtZW50cyA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIGNvbnN0IHJlbmRlcmluZ0VsZW1lbnRzID0gW107XG4gICAgY29uc3QgdG9wU2lkZUJvdE51YiA9IGlzWmVyb09yUG9zaXRpdmUoYnViYmxlTnViT2Zmc2V0KTtcbiAgICBjb25zdCB0b3BTaWRlVXNlck51YiA9IGlzWmVyb09yUG9zaXRpdmUoYnViYmxlRnJvbVVzZXJOdWJPZmZzZXQpO1xuXG4gICAgYWN0aXZpdHlUcmVlLmZvckVhY2goYWN0aXZpdGllc1dpdGhTYW1lU2VuZGVyID0+IHtcbiAgICAgIGNvbnN0IFtbZmlyc3RBY3Rpdml0eV1dID0gYWN0aXZpdGllc1dpdGhTYW1lU2VuZGVyO1xuICAgICAgY29uc3QgcmVuZGVyQXZhdGFyID0gY3JlYXRlQXZhdGFyUmVuZGVyZXIoeyBhY3Rpdml0eTogZmlyc3RBY3Rpdml0eSB9KTtcblxuICAgICAgYWN0aXZpdGllc1dpdGhTYW1lU2VuZGVyLmZvckVhY2goKGFjdGl2aXRpZXNXaXRoU2FtZVNlbmRlckFuZFN0YXR1cywgaW5kZXhXaXRoaW5TZW5kZXJHcm91cCkgPT4ge1xuICAgICAgICBjb25zdCBmaXJzdEluU2VuZGVyR3JvdXAgPSAhaW5kZXhXaXRoaW5TZW5kZXJHcm91cDtcbiAgICAgICAgY29uc3QgbGFzdEluU2VuZGVyR3JvdXAgPSBpbmRleFdpdGhpblNlbmRlckdyb3VwID09PSBhY3Rpdml0aWVzV2l0aFNhbWVTZW5kZXIubGVuZ3RoIC0gMTtcblxuICAgICAgICBhY3Rpdml0aWVzV2l0aFNhbWVTZW5kZXJBbmRTdGF0dXMuZm9yRWFjaCgoYWN0aXZpdHksIGluZGV4V2l0aGluU2VuZGVyQW5kU3RhdHVzR3JvdXApID0+IHtcbiAgICAgICAgICAvLyBXZSBvbmx5IHNob3cgdGhlIHRpbWVzdGFtcCBhdCB0aGUgZW5kIG9mIHRoZSBzZW5kZXIgZ3JvdXAuIEJ1dCB3ZSBhbHdheXMgc2hvdyB0aGUgXCJTZW5kIGZhaWxlZCwgcmV0cnlcIiBwcm9tcHQuXG4gICAgICAgICAgY29uc3QgcmVuZGVyQWN0aXZpdHlTdGF0dXMgPSBjcmVhdGVBY3Rpdml0eVN0YXR1c1JlbmRlcmVyKHtcbiAgICAgICAgICAgIGFjdGl2aXR5XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCBmaXJzdEluU2VuZGVyQW5kU3RhdHVzR3JvdXAgPSAhaW5kZXhXaXRoaW5TZW5kZXJBbmRTdGF0dXNHcm91cDtcbiAgICAgICAgICBjb25zdCBsYXN0SW5TZW5kZXJBbmRTdGF0dXNHcm91cCA9XG4gICAgICAgICAgICBpbmRleFdpdGhpblNlbmRlckFuZFN0YXR1c0dyb3VwID09PSBhY3Rpdml0aWVzV2l0aFNhbWVTZW5kZXJBbmRTdGF0dXMubGVuZ3RoIC0gMTtcblxuICAgICAgICAgIGNvbnN0IHsgcmVuZGVyQWN0aXZpdHkgfSA9IGFjdGl2aXRpZXNXaXRoUmVuZGVyZXIuZmluZChlbnRyeSA9PiBlbnRyeS5hY3Rpdml0eSA9PT0gYWN0aXZpdHkpO1xuICAgICAgICAgIGNvbnN0IGtleSA9IGdldEFjdGl2aXR5VW5pcXVlSWQoYWN0aXZpdHkpIHx8IHJlbmRlcmluZ0VsZW1lbnRzLmxlbmd0aDtcbiAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICBjaGFubmVsRGF0YTogeyBtZXNzYWdlQmFjazogeyBkaXNwbGF5VGV4dDogbWVzc2FnZUJhY2tEaXNwbGF5VGV4dCB9ID0ge30gfSA9IHt9LFxuICAgICAgICAgICAgZnJvbTogeyByb2xlIH0sXG4gICAgICAgICAgICB0ZXh0XG4gICAgICAgICAgfSA9IGFjdGl2aXR5O1xuXG4gICAgICAgICAgY29uc3QgdG9wU2lkZU51YiA9IHJvbGUgPT09ICd1c2VyJyA/IHRvcFNpZGVVc2VyTnViIDogdG9wU2lkZUJvdE51YjtcblxuICAgICAgICAgIGxldCBzaG93Q2FsbG91dDtcblxuICAgICAgICAgIC8vIERlcGVuZGluZyBvbiB0aGUgXCJzaG93QXZhdGFySW5Hcm91cFwiIHNldHRpbmcsIHRoZSBhdmF0YXIgd2lsbCByZW5kZXIgaW4gZGlmZmVyZW50IHBvc2l0aW9ucy5cbiAgICAgICAgICBpZiAoc2hvd0F2YXRhckluR3JvdXAgPT09ICdzZW5kZXInKSB7XG4gICAgICAgICAgICBpZiAodG9wU2lkZU51Yikge1xuICAgICAgICAgICAgICBzaG93Q2FsbG91dCA9IGZpcnN0SW5TZW5kZXJHcm91cCAmJiBmaXJzdEluU2VuZGVyQW5kU3RhdHVzR3JvdXA7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBzaG93Q2FsbG91dCA9IGxhc3RJblNlbmRlckdyb3VwICYmIGxhc3RJblNlbmRlckFuZFN0YXR1c0dyb3VwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAoc2hvd0F2YXRhckluR3JvdXAgPT09ICdzdGF0dXMnKSB7XG4gICAgICAgICAgICBpZiAodG9wU2lkZU51Yikge1xuICAgICAgICAgICAgICBzaG93Q2FsbG91dCA9IGZpcnN0SW5TZW5kZXJBbmRTdGF0dXNHcm91cDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHNob3dDYWxsb3V0ID0gbGFzdEluU2VuZGVyQW5kU3RhdHVzR3JvdXA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNob3dDYWxsb3V0ID0gdHJ1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBmb2N1c0FjdGl2aXR5ID0gKCkgPT4ge1xuICAgICAgICAgICAgc2V0Rm9jdXNlZEFjdGl2aXR5S2V5KGdldEFjdGl2aXR5VW5pcXVlSWQoYWN0aXZpdHkpKTtcblxuICAgICAgICAgICAgLy8gSUUxMSBuZWVkIHRvIG1hbnVhbGx5IGZvY3VzIG9uIHRoZSB0cmFuc2NyaXB0LlxuICAgICAgICAgICAgY29uc3QgeyBjdXJyZW50OiByb290RWxlbWVudCB9ID0gcm9vdEVsZW1lbnRSZWY7XG5cbiAgICAgICAgICAgIHJvb3RFbGVtZW50ICYmIHJvb3RFbGVtZW50LmZvY3VzKCk7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIHJlbmRlcmluZ0VsZW1lbnRzLnB1c2goe1xuICAgICAgICAgICAgYWN0aXZpdHksXG5cbiAgICAgICAgICAgIC8vIEFmdGVyIHRoZSBlbGVtZW50IGlzIG1vdW50ZWQsIHNldCBpdCB0byBhY3Rpdml0eUVsZW1lbnRzUmVmLlxuICAgICAgICAgICAgY2FsbGJhY2tSZWY6IGFjdGl2aXR5RWxlbWVudCA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IGVudHJ5ID0gYWN0aXZpdHlFbGVtZW50c1JlZi5jdXJyZW50LmZpbmQoKHsgYWN0aXZpdHlJRCB9KSA9PiBhY3Rpdml0eUlEID09PSBhY3Rpdml0eS5pZCk7XG5cbiAgICAgICAgICAgICAgaWYgKGVudHJ5KSB7XG4gICAgICAgICAgICAgICAgZW50cnkuZWxlbWVudCA9IGFjdGl2aXR5RWxlbWVudDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgLy8gQ2FsbGluZyB0aGlzIGZ1bmN0aW9uIHdpbGwgcHV0IHRoZSBmb2N1cyBvbiB0aGUgdHJhbnNjcmlwdCBhbmQgdGhlIGFjdGl2aXR5LlxuICAgICAgICAgICAgZm9jdXNBY3Rpdml0eSxcblxuICAgICAgICAgICAgLy8gV2hlbiBhIGNoaWxkIG9mIHRoZSBhY3Rpdml0eSByZWNlaXZlcyBmb2N1cywgbm90aWZ5IHRoZSB0cmFuc2NyaXB0IHRvIHNldCB0aGUgYXJpYS1hY3RpdmVkZXNjZW5kYW50IHRvIHRoaXMgYWN0aXZpdHkuXG4gICAgICAgICAgICBoYW5kbGVGb2N1czogKCkgPT4ge1xuICAgICAgICAgICAgICBzZXRGb2N1c2VkQWN0aXZpdHlLZXkoZ2V0QWN0aXZpdHlVbmlxdWVJZChhY3Rpdml0eSkpO1xuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgaGFuZGxlS2V5RG93bjogZXZlbnQgPT4ge1xuICAgICAgICAgICAgICBpZiAoZXZlbnQua2V5ID09PSAnRXNjYXBlJykge1xuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAgICAgICAgICAgICBzZXRGb2N1c2VkQWN0aXZpdHlLZXkoZ2V0QWN0aXZpdHlVbmlxdWVJZChhY3Rpdml0eSkpO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgeyBjdXJyZW50IH0gPSByb290RWxlbWVudFJlZjtcblxuICAgICAgICAgICAgICAgIGN1cnJlbnQgJiYgY3VycmVudC5mb2N1cygpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAvLyBGb3IgYWNjZXNzaWJpbGl0eTogd2hlbiB0aGUgdXNlciBwcmVzcyB1cC9kb3duIGFycm93IGtleXMsIHdlIHB1dCBhIHZpc3VhbCBmb2N1cyBpbmRpY2F0b3IgYXJvdW5kIHRoZSBmb2N1c2VkIGFjdGl2aXR5LlxuICAgICAgICAgICAgLy8gV2Ugc2hvdWxkIGRvIHRoZSBzYW1lIGZvciBtb3VzZSwgdGhhdCBpcyB3aHkgd2UgaGF2ZSB0aGUgY2xpY2sgaGFuZGxlciBoZXJlLlxuICAgICAgICAgICAgLy8gV2UgYXJlIGRvaW5nIGl0IGluIGV2ZW50IGNhcHR1cmUgcGhhc2UgdG8gcHJldmVudCBvdGhlciBjb21wb25lbnRzIGZyb20gc3RvcHBpbmcgZXZlbnQgcHJvcGFnYXRpb24gdG8gdXMuXG4gICAgICAgICAgICBoYW5kbGVNb3VzZURvd25DYXB0dXJlOiAoeyB0YXJnZXQgfSkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCB0YWJJbmRleCA9IGdldFRhYkluZGV4KHRhcmdldCk7XG5cbiAgICAgICAgICAgICAgaWYgKHR5cGVvZiB0YWJJbmRleCAhPT0gJ251bWJlcicgfHwgdGFiSW5kZXggPCAwIHx8IHRhcmdldC5nZXRBdHRyaWJ1dGUoJ2FyaWEtZGlzYWJsZWQnKSA9PT0gJ3RydWUnKSB7XG4gICAgICAgICAgICAgICAgZm9jdXNBY3Rpdml0eSgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAvLyBcImhpZGVUaW1lc3RhbXBcIiBpcyBhIHJlbmRlci10aW1lIHBhcmFtZXRlciBmb3IgcmVuZGVyQWN0aXZpdHlTdGF0dXMoKS5cbiAgICAgICAgICAgIC8vIElmIHRydWUsIGl0IHdpbGwgaGlkZSB0aGUgdGltZXN0YW1wLCBidXQgaXQgd2lsbCBjb250aW51ZSB0byBzaG93IHRoZVxuICAgICAgICAgICAgLy8gcmV0cnkgcHJvbXB0LiBBbmQgc2hvdyB0aGUgc2NyZWVuIHJlYWRlciB2ZXJzaW9uIG9mIHRoZSB0aW1lc3RhbXAuXG4gICAgICAgICAgICBoaWRlVGltZXN0YW1wOlxuICAgICAgICAgICAgICBoaWRlQWxsVGltZXN0YW1wcyB8fCBpbmRleFdpdGhpblNlbmRlckFuZFN0YXR1c0dyb3VwICE9PSBhY3Rpdml0aWVzV2l0aFNhbWVTZW5kZXJBbmRTdGF0dXMubGVuZ3RoIC0gMSxcbiAgICAgICAgICAgIGtleSxcblxuICAgICAgICAgICAgLy8gV2hlbiBcImxpdmVSZWdpb25LZXlcIiBjaGFuZ2VzLCBpdCB3aWxsIHNob3cgdXAgaW4gdGhlIGxpdmUgcmVnaW9uIG1vbWVudGFyaWx5LlxuICAgICAgICAgICAgbGl2ZVJlZ2lvbktleToga2V5ICsgJ3wnICsgKG1lc3NhZ2VCYWNrRGlzcGxheVRleHQgfHwgdGV4dCksXG4gICAgICAgICAgICByZW5kZXJBY3Rpdml0eSxcbiAgICAgICAgICAgIHJlbmRlckFjdGl2aXR5U3RhdHVzLFxuICAgICAgICAgICAgcmVuZGVyQXZhdGFyLFxuICAgICAgICAgICAgcm9sZSxcblxuICAgICAgICAgICAgLy8gVE9ETzogW1AyXSAjMjg1OCBXZSBzaG91bGQgdXNlIGNvcmUvZGVmaW5pdGlvbnMvc3BlYWtpbmdBY3Rpdml0eSBmb3IgdGhpcyBwcmVkaWNhdGUgaW5zdGVhZFxuICAgICAgICAgICAgc2hvdWxkU3BlYWs6IGFjdGl2aXR5LmNoYW5uZWxEYXRhICYmIGFjdGl2aXR5LmNoYW5uZWxEYXRhLnNwZWFrLFxuICAgICAgICAgICAgc2hvd0NhbGxvdXRcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHsgY3VycmVudDogYWN0aXZpdHlFbGVtZW50cyB9ID0gYWN0aXZpdHlFbGVtZW50c1JlZjtcblxuICAgIC8vIFVwZGF0ZSBhY3Rpdml0eUVsZW1lbnRSZWYgd2l0aCBuZXcgc2V0cyBvZiBhY3Rpdml0eSwgd2hpbGUgcmV0YWluaW5nIHRoZSBleGlzdGluZyByZWZlcmVuY2luZyBlbGVtZW50IGlmIGV4aXN0cy5cbiAgICBhY3Rpdml0eUVsZW1lbnRzUmVmLmN1cnJlbnQgPSByZW5kZXJpbmdFbGVtZW50cy5tYXAoKHsgYWN0aXZpdHksIGFjdGl2aXR5OiB7IGlkIH0sIGVsZW1lbnRJZCwga2V5IH0pID0+IHtcbiAgICAgIGNvbnN0IGV4aXN0aW5nRW50cnkgPSBhY3Rpdml0eUVsZW1lbnRzLmZpbmQoZW50cnkgPT4gZW50cnkua2V5ID09PSBrZXkpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBhY3Rpdml0eSxcbiAgICAgICAgYWN0aXZpdHlJRDogaWQsXG4gICAgICAgIGFyaWFMYWJlbElEOiBleGlzdGluZ0VudHJ5XG4gICAgICAgICAgPyBleGlzdGluZ0VudHJ5LmFyaWFMYWJlbElEXG4gICAgICAgICAgOiBgd2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fYWN0aXZpdHktbGFiZWwtJHtyYW5kb20oKS50b1N0cmluZygzNikuc3Vic3RyKDIsIDUpfWAsXG4gICAgICAgIGVsZW1lbnQ6IGV4aXN0aW5nRW50cnkgJiYgZXhpc3RpbmdFbnRyeS5lbGVtZW50LFxuICAgICAgICBlbGVtZW50SWQsXG4gICAgICAgIGtleVxuICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8vIFRoZXJlIG11c3QgYmUgb25lIGZvY3VzZWQgKGEuay5hLiBhcmlhLWFjdGl2ZWRlc2NlbmRhbnQpIGRlc2lnbmF0ZWQuIFdlIGRlZmF1bHQgaXQgdG8gdGhlIGxhc3Qgb25lLlxuICAgIGlmICghcmVuZGVyaW5nRWxlbWVudHMuZmluZCgoeyBmb2N1c2VkIH0pID0+IGZvY3VzZWQpKSB7XG4gICAgICBjb25zdCBsYXN0RWxlbWVudCA9IHJlbmRlcmluZ0VsZW1lbnRzW3JlbmRlcmluZ0VsZW1lbnRzLmxlbmd0aCAtIDFdO1xuXG4gICAgICBpZiAobGFzdEVsZW1lbnQpIHtcbiAgICAgICAgbGFzdEVsZW1lbnQuZm9jdXNlZCA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlbmRlcmluZ0VsZW1lbnRzO1xuICB9LCBbXG4gICAgYWN0aXZpdGllc1dpdGhSZW5kZXJlcixcbiAgICBhY3Rpdml0eUVsZW1lbnRzUmVmLFxuICAgIGFjdGl2aXR5VHJlZSxcbiAgICBidWJibGVGcm9tVXNlck51Yk9mZnNldCxcbiAgICBidWJibGVOdWJPZmZzZXQsXG4gICAgY3JlYXRlQWN0aXZpdHlTdGF0dXNSZW5kZXJlcixcbiAgICBjcmVhdGVBdmF0YXJSZW5kZXJlcixcbiAgICBoaWRlQWxsVGltZXN0YW1wcyxcbiAgICByb290RWxlbWVudFJlZixcbiAgICBzaG93QXZhdGFySW5Hcm91cFxuICBdKTtcblxuICBjb25zdCByZW5kZXJpbmdBY3Rpdml0aWVzID0gdXNlTWVtbygoKSA9PiByZW5kZXJpbmdFbGVtZW50cy5tYXAoKHsgYWN0aXZpdHkgfSkgPT4gYWN0aXZpdHkpLCBbcmVuZGVyaW5nRWxlbWVudHNdKTtcblxuICBjb25zdCBzY3JvbGxUb0JvdHRvbVNjcm9sbFRvID0gdXNlU2Nyb2xsVG8oKTtcbiAgY29uc3Qgc2Nyb2xsVG9Cb3R0b21TY3JvbGxUb0VuZCA9IHVzZVNjcm9sbFRvRW5kKCk7XG5cbiAgY29uc3Qgc2Nyb2xsVG8gPSB1c2VDYWxsYmFjayhcbiAgICAocG9zaXRpb24sIHsgYmVoYXZpb3IgPSAnYXV0bycgfSA9IHt9KSA9PiB7XG4gICAgICBpZiAoIXBvc2l0aW9uKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAnYm90ZnJhbWV3b3JrLXdlYmNoYXQ6IEZpcnN0IGFyZ3VtZW50IHBhc3NlZCB0byBcInVzZVNjcm9sbFRvXCIgbXVzdCBiZSBhIFNjcm9sbFBvc2l0aW9uIG9iamVjdC4nXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsgYWN0aXZpdHlJRCwgc2Nyb2xsVG9wIH0gPSBwb3NpdGlvbjtcblxuICAgICAgaWYgKHR5cGVvZiBzY3JvbGxUb3AgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHNjcm9sbFRvQm90dG9tU2Nyb2xsVG8oc2Nyb2xsVG9wLCB7IGJlaGF2aW9yIH0pO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgYWN0aXZpdHlJRCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgY29uc3QgeyBjdXJyZW50OiByb290RWxlbWVudCB9ID0gcm9vdEVsZW1lbnRSZWY7XG4gICAgICAgIGNvbnN0IHsgZWxlbWVudDogYWN0aXZpdHlFbGVtZW50IH0gPVxuICAgICAgICAgIGFjdGl2aXR5RWxlbWVudHNSZWYuY3VycmVudC5maW5kKGVudHJ5ID0+IGVudHJ5LmFjdGl2aXR5SUQgPT09IGFjdGl2aXR5SUQpIHx8IHt9O1xuXG4gICAgICAgIGNvbnN0IHNjcm9sbGFibGVFbGVtZW50ID0gcm9vdEVsZW1lbnQucXVlcnlTZWxlY3RvcignLndlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX3Njcm9sbGFibGUnKTtcblxuICAgICAgICBpZiAoc2Nyb2xsYWJsZUVsZW1lbnQgJiYgYWN0aXZpdHlFbGVtZW50KSB7XG4gICAgICAgICAgY29uc3QgW3sgaGVpZ2h0OiBhY3Rpdml0eUVsZW1lbnRIZWlnaHQsIHk6IGFjdGl2aXR5RWxlbWVudFkgfV0gPSBhY3Rpdml0eUVsZW1lbnQuZ2V0Q2xpZW50UmVjdHMoKTtcbiAgICAgICAgICBjb25zdCBbeyBoZWlnaHQ6IHNjcm9sbGFibGVIZWlnaHQgfV0gPSBzY3JvbGxhYmxlRWxlbWVudC5nZXRDbGllbnRSZWN0cygpO1xuXG4gICAgICAgICAgY29uc3QgYWN0aXZpdHlFbGVtZW50T2Zmc2V0VG9wID0gYWN0aXZpdHlFbGVtZW50WSArIHNjcm9sbGFibGVFbGVtZW50LnNjcm9sbFRvcDtcblxuICAgICAgICAgIGNvbnN0IHNjcm9sbFRvcCA9IE1hdGgubWluKFxuICAgICAgICAgICAgYWN0aXZpdHlFbGVtZW50T2Zmc2V0VG9wLFxuICAgICAgICAgICAgYWN0aXZpdHlFbGVtZW50T2Zmc2V0VG9wIC0gc2Nyb2xsYWJsZUhlaWdodCArIGFjdGl2aXR5RWxlbWVudEhlaWdodFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBzY3JvbGxUb0JvdHRvbVNjcm9sbFRvKHNjcm9sbFRvcCwgeyBiZWhhdmlvciB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICAgW2FjdGl2aXR5RWxlbWVudHNSZWYsIHJvb3RFbGVtZW50UmVmLCBzY3JvbGxUb0JvdHRvbVNjcm9sbFRvXVxuICApO1xuXG4gIGNvbnN0IHNjcm9sbFJlbGF0aXZlID0gdXNlQ2FsbGJhY2soXG4gICAgKGRpcmVjdGlvbiwgeyBkaXNwbGFjZW1lbnQgfSA9IHt9KSA9PiB7XG4gICAgICBjb25zdCB7IGN1cnJlbnQ6IHJvb3RFbGVtZW50IH0gPSByb290RWxlbWVudFJlZjtcblxuICAgICAgaWYgKCFyb290RWxlbWVudCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHNjcm9sbGFibGUgPSByb290RWxlbWVudC5xdWVyeVNlbGVjdG9yKCcud2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fc2Nyb2xsYWJsZScpO1xuICAgICAgbGV0IG5leHRTY3JvbGxUb3A7XG5cbiAgICAgIGlmICh0eXBlb2YgZGlzcGxhY2VtZW50ID09PSAnbnVtYmVyJykge1xuICAgICAgICBuZXh0U2Nyb2xsVG9wID0gc2Nyb2xsYWJsZS5zY3JvbGxUb3AgKyAoZGlyZWN0aW9uID09PSAnZG93bicgPyAxIDogLTEpICogZGlzcGxhY2VtZW50O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmV4dFNjcm9sbFRvcCA9IHNjcm9sbGFibGUuc2Nyb2xsVG9wICsgKGRpcmVjdGlvbiA9PT0gJ2Rvd24nID8gMSA6IC0xKSAqIHNjcm9sbGFibGUub2Zmc2V0SGVpZ2h0O1xuICAgICAgfVxuXG4gICAgICBzY3JvbGxUbyhcbiAgICAgICAge1xuICAgICAgICAgIHNjcm9sbFRvcDogTWF0aC5tYXgoMCwgTWF0aC5taW4oc2Nyb2xsYWJsZS5zY3JvbGxIZWlnaHQgLSBzY3JvbGxhYmxlLm9mZnNldEhlaWdodCwgbmV4dFNjcm9sbFRvcCkpXG4gICAgICAgIH0sXG4gICAgICAgIHsgYmVoYXZpb3I6ICdzbW9vdGgnIH1cbiAgICAgICk7XG4gICAgfSxcbiAgICBbcm9vdEVsZW1lbnRSZWYsIHNjcm9sbFRvXVxuICApO1xuXG4gIC8vIFNpbmNlIHRoZXJlIGNvdWxkIGJlIG11bHRpcGxlIGluc3RhbmNlcyBvZiA8QmFzaWNUcmFuc2NyaXB0PiBpbnNpZGUgdGhlIDxDb21wb3Nlcj4sIHdoZW4gdGhlIGRldmVsb3BlciBjYWxscyBgc2Nyb2xsWFhYYCwgd2UgbmVlZCB0byBjYWxsIGl0IG9uIGFsbCBpbnN0YW5jZXMuXG4gIC8vIFdlIGNhbGwgYHVzZVJlZ2lzdGVyU2Nyb2xsWFhYYCB0byByZWdpc3RlciBhIGNhbGxiYWNrIGZ1bmN0aW9uLCB0aGUgYHVzZVNjcm9sbFhYWGAgd2lsbCBtdWx0aXBsZXggdGhlIGNhbGwgaW50byBlYWNoIGluc3RhbmNlIG9mIDxCYXNpY1RyYW5zY3JpcHQ+LlxuICB1c2VSZWdpc3RlclNjcm9sbFRvKHNjcm9sbFRvKTtcbiAgdXNlUmVnaXN0ZXJTY3JvbGxUb0VuZChzY3JvbGxUb0JvdHRvbVNjcm9sbFRvRW5kKTtcbiAgdXNlUmVnaXN0ZXJTY3JvbGxSZWxhdGl2ZShzY3JvbGxSZWxhdGl2ZSk7XG5cbiAgY29uc3QgZGlzcGF0Y2hTY3JvbGxQb3NpdGlvbiA9IHVzZURpc3BhdGNoU2Nyb2xsUG9zaXRpb24oKTtcbiAgY29uc3QgcGF0Y2hlZERpc3BhdGNoU2Nyb2xsUG9zaXRpb24gPSB1c2VNZW1vKCgpID0+IHtcbiAgICBpZiAoIWRpc3BhdGNoU2Nyb2xsUG9zaXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICByZXR1cm4gKHsgc2Nyb2xsVG9wIH0pID0+IHtcbiAgICAgIGNvbnN0IHsgY3VycmVudDogcm9vdEVsZW1lbnQgfSA9IHJvb3RFbGVtZW50UmVmO1xuXG4gICAgICBpZiAoIXJvb3RFbGVtZW50KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc2Nyb2xsYWJsZUVsZW1lbnQgPSByb290RWxlbWVudC5xdWVyeVNlbGVjdG9yKCcud2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fc2Nyb2xsYWJsZScpO1xuXG4gICAgICBjb25zdCBbeyBoZWlnaHQ6IG9mZnNldEhlaWdodCB9ID0ge31dID0gc2Nyb2xsYWJsZUVsZW1lbnQuZ2V0Q2xpZW50UmVjdHMoKTtcblxuICAgICAgLy8gRmluZCB0aGUgYWN0aXZpdHkganVzdCBhYm92ZSBzY3JvbGwgdmlldyBib3R0b20uXG4gICAgICAvLyBJZiB0aGUgc2Nyb2xsIHZpZXcgaXMgYWxyZWFkeSBvbiB0b3AsIGdldCB0aGUgZmlyc3QgYWN0aXZpdHkuXG4gICAgICBjb25zdCBlbnRyeSA9IHNjcm9sbGFibGVFbGVtZW50LnNjcm9sbFRvcFxuICAgICAgICA/IFsuLi5hY3Rpdml0eUVsZW1lbnRzUmVmLmN1cnJlbnRdLnJldmVyc2UoKS5maW5kKCh7IGVsZW1lbnQgfSkgPT4ge1xuICAgICAgICAgICAgaWYgKCFlbGVtZW50KSB7XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgW3sgeSB9ID0ge31dID0gZWxlbWVudC5nZXRDbGllbnRSZWN0cygpO1xuXG4gICAgICAgICAgICByZXR1cm4geSA8IG9mZnNldEhlaWdodDtcbiAgICAgICAgICB9KVxuICAgICAgICA6IGFjdGl2aXR5RWxlbWVudHNSZWYuY3VycmVudFswXTtcblxuICAgICAgY29uc3QgeyBhY3Rpdml0eUlEIH0gPSBlbnRyeSB8fCB7fTtcblxuICAgICAgZGlzcGF0Y2hTY3JvbGxQb3NpdGlvbih7IC4uLihhY3Rpdml0eUlEID8geyBhY3Rpdml0eUlEIH0gOiB7fSksIHNjcm9sbFRvcCB9KTtcbiAgICB9O1xuICB9LCBbYWN0aXZpdHlFbGVtZW50c1JlZiwgZGlzcGF0Y2hTY3JvbGxQb3NpdGlvbiwgcm9vdEVsZW1lbnRSZWZdKTtcblxuICB1c2VPYnNlcnZlU2Nyb2xsUG9zaXRpb24ocGF0Y2hlZERpc3BhdGNoU2Nyb2xsUG9zaXRpb24pO1xuXG4gIGNvbnN0IFtsYXN0SW50ZXJhY3RlZEFjdGl2aXR5XSA9IHVzZUFja25vd2xlZGdlZEFjdGl2aXR5KCk7XG5cbiAgY29uc3QgaW5kZXhPZkxhc3RJbnRlcmFjdGVkQWN0aXZpdHkgPSBhY3Rpdml0aWVzLmluZGV4T2YobGFzdEludGVyYWN0ZWRBY3Rpdml0eSk7XG5cbiAgLy8gQ3JlYXRlIGEgbmV3IElEIGZvciBhcmlhLWFjdGl2ZWRlc2NlbmRhbnQgZXZlcnkgdGltZSB0aGUgYWN0aXZlIGRlc2NlbmRhbnQgY2hhbmdlLlxuICAvLyBJbiBvdXIgZGVzaWduLCB0aGUgdHJhbnNjcmlwdCB3aWxsIG9ubHkgaGF2ZSAxIGZvY3VzZWQgYWN0aXZpdHkgYW5kIGl0IGhhcyBhbiBJRC4gT3RoZXIgYmx1cnJlZCBhY3Rpdml0aWVzIHdpbGwgbm90IGhhdmUgSUQgYXNzaWduZWQuXG4gIC8vIFRoaXMgaGVscCB3aXRoIHBlcmZvcm1hbmNlLlxuICAvLyBCdXQgYnJvd3NlciB1c3VhbGx5IGRvIG5vb3AgaWYgdGhlIHZhbHVlIG9mIGFyaWEtYWN0aXZlZGVzY2VuZGFudCBkb2Vzbid0IGNoYW5nZS5cbiAgLy8gVGhhdCBtZWFucywgaWYgd2UgYXNzaWduIHRoZSBzYW1lIElEIHRvIGFub3RoZXIgZWxlbWVudCwgYnJvd3NlciB3aWxsIGRvIG5vb3AuXG4gIC8vIFdlIG5lZWQgdG8gZ2VuZXJhdGUgYSBuZXcgSUQgc28gdGhlIGJyb3dzZXIgc2VlIHRoZXJlIGlzIGEgY2hhbmdlIGluIGFyaWEtYWN0aXZlZGVzY2VuZGFudCB2YWx1ZSBhbmQgcGVyZm9ybSBhY2NvcmRpbmdseS5cbiAgY29uc3QgYWN0aXZlRGVzY2VuZGFudEVsZW1lbnRJZCA9IHVzZU1lbW8oXG4gICAgKCkgPT4gZm9jdXNlZEFjdGl2aXR5S2V5ICYmIGB3ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0X19hY3RpdmUtZGVzY2VuZGFudC0ke3JhbmRvbSgpLnRvU3RyaW5nKDM2KS5zdWJzdHIoMiwgNSl9YCxcbiAgICBbZm9jdXNlZEFjdGl2aXR5S2V5XVxuICApO1xuXG4gIGNvbnN0IHNjcm9sbEFjdGl2ZURlc2NlbmRhbnRJbnRvVmlldyA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBjb25zdCBhY3RpdmVEZXNjZW5kYW50ID0gYWN0aXZlRGVzY2VuZGFudEVsZW1lbnRJZCAmJiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChhY3RpdmVEZXNjZW5kYW50RWxlbWVudElkKTtcblxuICAgIC8vIERvbid0IHNjcm9sbCBhY3RpdmUgZGVzY2VuZGFudCBpbnRvIHZpZXcgaWYgdGhlIGZvY3VzIGlzIGFscmVhZHkgaW5zaWRlIGl0LlxuICAgIC8vIE90aGVyd2lzZSwgZ2l2ZW4gdGhlIGZvY3VzIGlzIG9uIHRoZSBzZW5kIGJveCwgY2xpY2tpbmcgb24gYW55IDxpbnB1dD4gaW5zaWRlIHRoZSBBZGFwdGl2ZSBDYXJkcyBtYXkgY2F1c2UgdGhlIHZpZXcgdG8gbW92ZS5cbiAgICAvLyBUaGlzIFVYIGlzIG5vdCBkZXNpcmFibGUgYmVjYXVzZSBjbGljayBzaG91bGQgbm90IGNhdXNlIHNjcm9sbC5cbiAgICBpZiAoYWN0aXZlRGVzY2VuZGFudCAmJiAhYWN0aXZlRGVzY2VuZGFudC5jb250YWlucyhkb2N1bWVudC5hY3RpdmVFbGVtZW50KSkge1xuICAgICAgLy8gQ2hlY2tzIGlmIHNjcm9sbEludG9WaWV3IHN1cHBvcnQgb3B0aW9ucyBvciBub3QuXG4gICAgICAvLyAtIGh0dHBzOi8vZ2l0aHViLmNvbS9Nb2Rlcm5penIvTW9kZXJuaXpyL2lzc3Vlcy8xNTY4I2lzc3VlY29tbWVudC00MTk0NTc5NzJcbiAgICAgIC8vIC0gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNDY5MTk2MjcvaXMtaXQtcG9zc2libGUtdG8tdGVzdC1mb3Itc2Nyb2xsaW50b3ZpZXctYnJvd3Nlci1jb21wYXRpYmlsaXR5XG4gICAgICBpZiAoJ3Njcm9sbEJlaGF2aW9yJyBpbiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUpIHtcbiAgICAgICAgYWN0aXZlRGVzY2VuZGFudC5zY3JvbGxJbnRvVmlldyh7IGJsb2NrOiAnbmVhcmVzdCcgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBUaGlzIGlzIGZvciBicm93c2VyIHRoYXQgZG9lcyBub3Qgc3VwcG9ydCBvcHRpb25zIHBhc3NlZCB0byBzY3JvbGxJbnRvVmlldygpLCBwb3NzaWJseSBJRTExLlxuICAgICAgICBjb25zdCBzY3JvbGxhYmxlRWxlbWVudCA9IHJvb3RFbGVtZW50UmVmLmN1cnJlbnQucXVlcnlTZWxlY3RvcignLndlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX3Njcm9sbGFibGUnKTtcbiAgICAgICAgY29uc3Qgc2Nyb2xsVG9wQXRUb3BTaWRlID0gYWN0aXZlRGVzY2VuZGFudC5vZmZzZXRUb3A7XG4gICAgICAgIGNvbnN0IHNjcm9sbFRvcEF0Qm90dG9tU2lkZSA9IGFjdGl2ZURlc2NlbmRhbnQub2Zmc2V0VG9wICsgYWN0aXZlRGVzY2VuZGFudC5vZmZzZXRIZWlnaHQ7XG5cbiAgICAgICAgaWYgKHNjcm9sbFRvcEF0VG9wU2lkZSA8IHNjcm9sbGFibGVFbGVtZW50LnNjcm9sbFRvcCkge1xuICAgICAgICAgIHNjcm9sbGFibGVFbGVtZW50LnNjcm9sbFRvcCA9IHNjcm9sbFRvcEF0VG9wU2lkZTtcbiAgICAgICAgfSBlbHNlIGlmIChzY3JvbGxUb3BBdEJvdHRvbVNpZGUgPiBzY3JvbGxhYmxlRWxlbWVudC5zY3JvbGxUb3AgKyBzY3JvbGxhYmxlRWxlbWVudC5vZmZzZXRIZWlnaHQpIHtcbiAgICAgICAgICBzY3JvbGxhYmxlRWxlbWVudC5zY3JvbGxUb3AgPSBzY3JvbGxUb3BBdEJvdHRvbVNpZGUgLSBzY3JvbGxhYmxlRWxlbWVudC5vZmZzZXRIZWlnaHQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0sIFthY3RpdmVEZXNjZW5kYW50RWxlbWVudElkLCByb290RWxlbWVudFJlZl0pO1xuXG4gIGNvbnN0IGhhbmRsZVRyYW5zY3JpcHRGb2N1cyA9IHVzZUNhbGxiYWNrKFxuICAgIGV2ZW50ID0+IHtcbiAgICAgIGNvbnN0IHsgY3VycmVudFRhcmdldCwgdGFyZ2V0IH0gPSBldmVudDtcblxuICAgICAgLy8gV2hlbiBmb2N1cyBpcyBwbGFjZWQgb24gdGhlIHRyYW5zY3JpcHQsIHNjcm9sbCBhY3RpdmUgZGVzY2VuZGFudCBpbnRvIHRoZSB2aWV3LlxuICAgICAgY3VycmVudFRhcmdldCA9PT0gdGFyZ2V0ICYmIHNjcm9sbEFjdGl2ZURlc2NlbmRhbnRJbnRvVmlldygpO1xuICAgIH0sXG4gICAgW3Njcm9sbEFjdGl2ZURlc2NlbmRhbnRJbnRvVmlld11cbiAgKTtcblxuICAvLyBBZnRlciBuZXcgYXJpYS1hY3RpdmVkZXNjZW5kYW50IGlzIGFzc2lnbmVkLCB3ZSB3aWxsIG5lZWQgdG8gc2Nyb2xsIGl0IGludG8gdmlldy5cbiAgLy8gVXNlciBhZ2VudCB3aWxsIHNjcm9sbCBhdXRvbWF0aWNhbGx5IGZvciBmb2N1c2luZyBlbGVtZW50LCBidXQgbm90IGZvciBhcmlhLWFjdGl2ZWRlc2NlbmRhbnQuXG4gIC8vIFdlIG5lZWQgdG8gZG8gdGhlIHNjcm9sbGluZyBtYW51YWxseS5cbiAgdXNlRWZmZWN0KCgpID0+IHNjcm9sbEFjdGl2ZURlc2NlbmRhbnRJbnRvVmlldygpLCBbc2Nyb2xsQWN0aXZlRGVzY2VuZGFudEludG9WaWV3XSk7XG5cbiAgLy8gSWYgYW55IGFjdGl2aXRpZXMgaGFzIGNoYW5nZWQsIHJlc2V0IHRoZSBhY3RpdmUgZGVzY2VuZGFudC5cbiAgdXNlRWZmZWN0KCgpID0+IHNldEZvY3VzZWRBY3Rpdml0eUtleSh1bmRlZmluZWQpLCBbYWN0aXZpdGllcywgc2V0Rm9jdXNlZEFjdGl2aXR5S2V5XSk7XG5cbiAgY29uc3QgZm9jdXNSZWxhdGl2ZUFjdGl2aXR5ID0gdXNlQ2FsbGJhY2soXG4gICAgZGVsdGEgPT4ge1xuICAgICAgaWYgKGlzTmFOKGRlbHRhKSB8fCAhcmVuZGVyaW5nRWxlbWVudHMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBzZXRGb2N1c2VkQWN0aXZpdHlLZXkodW5kZWZpbmVkKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgaW5kZXggPSByZW5kZXJpbmdFbGVtZW50cy5maW5kSW5kZXgoKHsga2V5IH0pID0+IGtleSA9PT0gZm9jdXNlZEFjdGl2aXR5S2V5KTtcbiAgICAgIGNvbnN0IG5leHRJbmRleCA9IH5pbmRleFxuICAgICAgICA/IE1hdGgubWF4KDAsIE1hdGgubWluKHJlbmRlcmluZ0VsZW1lbnRzLmxlbmd0aCAtIDEsIGluZGV4ICsgZGVsdGEpKVxuICAgICAgICA6IHJlbmRlcmluZ0VsZW1lbnRzLmxlbmd0aCAtIDE7XG4gICAgICBjb25zdCBuZXh0Rm9jdXNlZEFjdGl2aXR5ID0gcmVuZGVyaW5nRWxlbWVudHNbbmV4dEluZGV4XTtcblxuICAgICAgc2V0Rm9jdXNlZEFjdGl2aXR5S2V5KG5leHRGb2N1c2VkQWN0aXZpdHkua2V5KTtcbiAgICAgIHJvb3RFbGVtZW50UmVmLmN1cnJlbnQgJiYgcm9vdEVsZW1lbnRSZWYuY3VycmVudC5mb2N1cygpO1xuICAgIH0sXG4gICAgW2ZvY3VzZWRBY3Rpdml0eUtleSwgcmVuZGVyaW5nRWxlbWVudHMsIHJvb3RFbGVtZW50UmVmLCBzZXRGb2N1c2VkQWN0aXZpdHlLZXldXG4gICk7XG5cbiAgY29uc3QgaGFuZGxlVHJhbnNjcmlwdEtleURvd24gPSB1c2VDYWxsYmFjayhcbiAgICBldmVudCA9PiB7XG4gICAgICBjb25zdCB7IHRhcmdldCB9ID0gZXZlbnQ7XG5cbiAgICAgIGNvbnN0IGZyb21FbmRPZlRyYW5zY3JpcHRJbmRpY2F0b3IgPSB0YXJnZXQgPT09IHRlcm1pbmF0b3JSZWYuY3VycmVudDtcbiAgICAgIGNvbnN0IGZyb21UcmFuc2NyaXB0ID0gdGFyZ2V0ID09PSBldmVudC5jdXJyZW50VGFyZ2V0O1xuXG4gICAgICBpZiAoIWZyb21FbmRPZlRyYW5zY3JpcHRJbmRpY2F0b3IgJiYgIWZyb21UcmFuc2NyaXB0KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgbGV0IGhhbmRsZWQgPSB0cnVlO1xuXG4gICAgICBzd2l0Y2ggKGV2ZW50LmtleSkge1xuICAgICAgICBjYXNlICdBcnJvd0Rvd24nOlxuICAgICAgICAgIGZvY3VzUmVsYXRpdmVBY3Rpdml0eShmcm9tRW5kT2ZUcmFuc2NyaXB0SW5kaWNhdG9yID8gMCA6IDEpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgJ0Fycm93VXAnOlxuICAgICAgICAgIGZvY3VzUmVsYXRpdmVBY3Rpdml0eShmcm9tRW5kT2ZUcmFuc2NyaXB0SW5kaWNhdG9yID8gMCA6IC0xKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlICdFbmQnOlxuICAgICAgICAgIGZvY3VzUmVsYXRpdmVBY3Rpdml0eShJbmZpbml0eSk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAnRW50ZXInOlxuICAgICAgICAgIGlmICghZnJvbUVuZE9mVHJhbnNjcmlwdEluZGljYXRvcikge1xuICAgICAgICAgICAgY29uc3QgZm9jdXNlZEFjdGl2aXR5RW50cnkgPSByZW5kZXJpbmdFbGVtZW50cy5maW5kKCh7IGtleSB9KSA9PiBrZXkgPT09IGZvY3VzZWRBY3Rpdml0eUtleSk7XG5cbiAgICAgICAgICAgIGlmIChmb2N1c2VkQWN0aXZpdHlFbnRyeSkge1xuICAgICAgICAgICAgICBjb25zdCB7IGVsZW1lbnQ6IGZvY3VzZWRBY3Rpdml0eUVsZW1lbnQgfSA9XG4gICAgICAgICAgICAgICAgYWN0aXZpdHlFbGVtZW50c1JlZi5jdXJyZW50LmZpbmQoKHsgYWN0aXZpdHkgfSkgPT4gYWN0aXZpdHkgPT09IGZvY3VzZWRBY3Rpdml0eUVudHJ5LmFjdGl2aXR5KSB8fCB7fTtcblxuICAgICAgICAgICAgICBpZiAoZm9jdXNlZEFjdGl2aXR5RWxlbWVudCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IFtmaXJzdFRhYmJhYmxlRWxlbWVudF0gPSB0YWJiYWJsZUVsZW1lbnRzKGZvY3VzZWRBY3Rpdml0eUVsZW1lbnQpLmZpbHRlcihcbiAgICAgICAgICAgICAgICAgICh7IGNsYXNzTmFtZSB9KSA9PiBjbGFzc05hbWUgIT09ICd3ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0X19hY3Rpdml0eS1zZW50aW5lbCdcbiAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgZmlyc3RUYWJiYWJsZUVsZW1lbnQgJiYgZmlyc3RUYWJiYWJsZUVsZW1lbnQuZm9jdXMoKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgJ0VzY2FwZSc6XG4gICAgICAgICAgZm9jdXMoJ3NlbmRCb3hXaXRob3V0S2V5Ym9hcmQnKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlICdIb21lJzpcbiAgICAgICAgICBmb2N1c1JlbGF0aXZlQWN0aXZpdHkoLUluZmluaXR5KTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIGhhbmRsZWQgPSBmYWxzZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgaWYgKGhhbmRsZWQpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICAvLyBJZiBhIGN1c3RvbSBIVE1MIGNvbnRyb2wgd2FudHMgdG8gaGFuZGxlIHVwL2Rvd24gYXJyb3csIHdlIHdpbGwgcHJldmVudCB0aGVtIGZyb20gbGlzdGVuaW5nIHRvIHRoaXMgZXZlbnQgdG8gcHJldmVudCBidWdzIGR1ZSB0byBoYW5kbGluZyBhcnJvdyBrZXlzIHR3aWNlLlxuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIFtmb2N1c2VkQWN0aXZpdHlLZXksIGFjdGl2aXR5RWxlbWVudHNSZWYsIGZvY3VzUmVsYXRpdmVBY3Rpdml0eSwgZm9jdXMsIHRlcm1pbmF0b3JSZWYsIHJlbmRlcmluZ0VsZW1lbnRzXVxuICApO1xuXG4gIGNvbnN0IGxhYmVsSWQgPSB1c2VVbmlxdWVJZCgnd2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fbGFiZWwnKTtcblxuICAvLyBJZiBTSElGVC1UQUIgZnJvbSBcIkVuZCBvZiB0cmFuc2NyaXB0XCIgaW5kaWNhdG9yLCBpZiBmb2N1c2VkQWN0aXZpdHlLZXkgaXMgbm90IHNldCAob3Igbm8gbG9uZ2VyIGV4aXN0cyksIHNldCBpdCB0aGUgdGhlIGJvdHRvbW1vc3QgYWN0aXZpdHkuXG4gIGNvbnN0IHNldEJvdHRvbW1vc3RGb2N1c2VkQWN0aXZpdHlLZXlJZk5lZWRlZCA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBpZiAoIX5yZW5kZXJpbmdFbGVtZW50cy5maW5kSW5kZXgoKHsga2V5IH0pID0+IGtleSA9PT0gZm9jdXNlZEFjdGl2aXR5S2V5KSkge1xuICAgICAgY29uc3QgeyBrZXk6IGxhc3RBY3Rpdml0eUtleSB9ID0gcmVuZGVyaW5nRWxlbWVudHNbcmVuZGVyaW5nRWxlbWVudHMubGVuZ3RoIC0gMV0gfHwge307XG5cbiAgICAgIHNldEZvY3VzZWRBY3Rpdml0eUtleShsYXN0QWN0aXZpdHlLZXkpO1xuICAgIH1cbiAgfSwgW2ZvY3VzZWRBY3Rpdml0eUtleSwgcmVuZGVyaW5nRWxlbWVudHMsIHNldEZvY3VzZWRBY3Rpdml0eUtleV0pO1xuXG4gIGNvbnN0IGhhbmRsZVRyYW5zY3JpcHRLZXlEb3duQ2FwdHVyZSA9IHVzZUNhbGxiYWNrKFxuICAgIGV2ZW50ID0+IHtcbiAgICAgIGNvbnN0IHsgYWx0S2V5LCBjdHJsS2V5LCBrZXksIG1ldGFLZXksIHRhcmdldCB9ID0gZXZlbnQ7XG5cbiAgICAgIGlmIChhbHRLZXkgfHwgKGN0cmxLZXkgJiYga2V5ICE9PSAndicpIHx8IG1ldGFLZXkgfHwgKCFpbnB1dHRhYmxlS2V5KGtleSkgJiYga2V5ICE9PSAnQmFja3NwYWNlJykpIHtcbiAgICAgICAgLy8gSWdub3JlIGlmIG9uZSBvZiB0aGUgdXRpbGl0eSBrZXkgKGV4Y2VwdCBTSElGVCkgaXMgcHJlc3NlZFxuICAgICAgICAvLyBFLmcuIENUUkwtQyBvbiBhIGxpbmsgaW4gb25lIG9mIHRoZSBtZXNzYWdlIHNob3VsZCBub3QganVtcCB0byBjaGF0IGJveFxuICAgICAgICAvLyBFLmcuIFwiQVwiIG9yIFwiQmFja3NwYWNlXCIgc2hvdWxkIGp1bXAgdG8gY2hhdCBib3hcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBTZW5kIGtleXN0cm9rZXMgdG8gc2VuZCBib3ggaWYgd2UgYXJlIGZvY3VzaW5nIG9uIHRoZSB0cmFuc2NyaXB0IG9yIHRlcm1pbmF0b3IuXG4gICAgICBpZiAodGFyZ2V0ID09PSBldmVudC5jdXJyZW50VGFyZ2V0IHx8IHRhcmdldCA9PT0gdGVybWluYXRvclJlZi5jdXJyZW50KSB7XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICAgIGZvY3VzKCdzZW5kQm94Jyk7XG4gICAgICB9XG4gICAgfSxcbiAgICBbZm9jdXNdXG4gICk7XG5cbiAgY29uc3QgZm9jdXNUcmFuc2NyaXB0Q2FsbGJhY2sgPSB1c2VDYWxsYmFjaygoKSA9PiByb290RWxlbWVudFJlZi5jdXJyZW50ICYmIHJvb3RFbGVtZW50UmVmLmN1cnJlbnQuZm9jdXMoKSwgW1xuICAgIHJvb3RFbGVtZW50UmVmXG4gIF0pO1xuXG4gIHVzZVJlZ2lzdGVyRm9jdXNUcmFuc2NyaXB0KGZvY3VzVHJhbnNjcmlwdENhbGxiYWNrKTtcblxuICBjb25zdCBoYW5kbGVGb2N1c0FjdGl2aXR5ID0gdXNlQ2FsbGJhY2soXG4gICAga2V5ID0+IHtcbiAgICAgIHNldEZvY3VzZWRBY3Rpdml0eUtleShrZXkpO1xuICAgICAgcm9vdEVsZW1lbnRSZWYuY3VycmVudCAmJiByb290RWxlbWVudFJlZi5jdXJyZW50LmZvY3VzKCk7XG4gICAgfSxcbiAgICBbc2V0Rm9jdXNlZEFjdGl2aXR5S2V5XVxuICApO1xuXG4gIC8vIFdoZW4gdGhlIGZvY3VzaW5nIGFjdGl2aXR5IGhhcyBjaGFuZ2VkLCBkaXNwYXRjaCBhbiBldmVudCB0byBvYnNlcnZlcnMgb2YgXCJ1c2VPYnNlcnZlVHJhbnNjcmlwdEZvY3VzXCIuXG4gIGNvbnN0IGRpc3BhdGNoVHJhbnNjcmlwdEZvY3VzID0gdXNlRGlzcGF0Y2hUcmFuc2NyaXB0Rm9jdXMoKTtcbiAgY29uc3QgZm9jdXNlZEFjdGl2aXR5ID0gdXNlTWVtbygoKSA9PiB7XG4gICAgY29uc3QgeyBhY3Rpdml0eSB9ID0gcmVuZGVyaW5nRWxlbWVudHMuZmluZCgoeyBrZXkgfSkgPT4ga2V5ID09PSBmb2N1c2VkQWN0aXZpdHlLZXkpIHx8IHt9O1xuXG4gICAgcmV0dXJuIGFjdGl2aXR5O1xuICB9LCBbZm9jdXNlZEFjdGl2aXR5S2V5LCByZW5kZXJpbmdFbGVtZW50c10pO1xuXG4gIHVzZU1lbW8oKCkgPT4gZGlzcGF0Y2hUcmFuc2NyaXB0Rm9jdXMgJiYgZGlzcGF0Y2hUcmFuc2NyaXB0Rm9jdXMoeyBhY3Rpdml0eTogZm9jdXNlZEFjdGl2aXR5IH0pLCBbXG4gICAgZGlzcGF0Y2hUcmFuc2NyaXB0Rm9jdXMsXG4gICAgZm9jdXNlZEFjdGl2aXR5XG4gIF0pO1xuXG4gIC8vIFRoaXMgaXMgcmVxdWlyZWQgYnkgSUUxMS5cbiAgLy8gV2hlbiB0aGUgdXNlciBjbGlja3Mgb24gYW5kIGVtcHR5IHNwYWNlIChhLmsuYS4gZmlsbGVyKSBpbiBhbiBlbXB0eSB0cmFuc2NyaXB0LCBJRTExIHNheXMgdGhlIGZvY3VzIGlzIG9uIHRoZSA8ZGl2IGNsYXNzTmFtZT1cImZpbGxlclwiPixcbiAgLy8gZGVzcGl0ZSB0aGUgZmFjdCB0aGVyZSBhcmUgbm8gXCJ0YWJJbmRleFwiIGF0dHJpYnV0ZXMgc2V0IG9uIHRoZSBmaWxsZXIuXG4gIC8vIFdlIG5lZWQgdG8gYXJ0aWZpY2lhbGx5IHNlbmQgdGhlIGZvY3VzIGJhY2sgdG8gdGhlIHRyYW5zY3JpcHQuXG4gIGNvbnN0IGhhbmRsZUZvY3VzRmlsbGVyID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIGNvbnN0IHsgY3VycmVudCB9ID0gcm9vdEVsZW1lbnRSZWY7XG5cbiAgICBjdXJyZW50ICYmIGN1cnJlbnQuZm9jdXMoKTtcbiAgfSwgW3Jvb3RFbGVtZW50UmVmXSk7XG5cbiAgcmV0dXJuIChcbiAgICA8ZGl2XG4gICAgICBhcmlhLWFjdGl2ZWRlc2NlbmRhbnQ9e2ZvY3VzZWRBY3Rpdml0eUtleSA/IGFjdGl2ZURlc2NlbmRhbnRFbGVtZW50SWQgOiB1bmRlZmluZWR9XG4gICAgICBhcmlhLWxhYmVsbGVkYnk9e2xhYmVsSWR9XG4gICAgICBjbGFzc05hbWU9e2NsYXNzTmFtZXMoXG4gICAgICAgICd3ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0JyxcbiAgICAgICAgYmFzaWNUcmFuc2NyaXB0U3R5bGVTZXQgKyAnJyxcbiAgICAgICAgcm9vdENsYXNzTmFtZSxcbiAgICAgICAgKGNsYXNzTmFtZSB8fCAnJykgKyAnJ1xuICAgICAgKX1cbiAgICAgIGRpcj17ZGlyZWN0aW9ufVxuICAgICAgb25Gb2N1cz17aGFuZGxlVHJhbnNjcmlwdEZvY3VzfVxuICAgICAgb25LZXlEb3duPXtoYW5kbGVUcmFuc2NyaXB0S2V5RG93bn1cbiAgICAgIG9uS2V5RG93bkNhcHR1cmU9e2hhbmRsZVRyYW5zY3JpcHRLZXlEb3duQ2FwdHVyZX1cbiAgICAgIHJlZj17cm9vdEVsZW1lbnRSZWZ9XG4gICAgICAvLyBcImFyaWEtYWN0aXZlZGVzY2VuZGFudFwiIHdpbGwgb25seSB3b3JrcyB3aXRoIGEgbnVtYmVyIG9mIHJvbGVzIGFuZCBpdCBtdXN0IGJlIGV4cGxpY2l0bHkgc2V0LlxuICAgICAgLy8gaHR0cHM6Ly93d3cudzMub3JnL1RSL3dhaS1hcmlhLyNhcmlhLWFjdGl2ZWRlc2NlbmRhbnRcbiAgICAgIHJvbGU9XCJncm91cFwiXG4gICAgICAvLyBGb3IgdXAvZG93biBhcnJvdyBrZXkgbmF2aWdhdGlvbiBhY3Jvc3MgYWN0aXZpdGllcywgdGhpcyBjb21wb25lbnQgbXVzdCBiZSBpbmNsdWRlZCBpbiB0aGUgdGFiIHNlcXVlbmNlLlxuICAgICAgLy8gT3RoZXJ3aXNlLCBcImFyaWEtYWN0aXZlZGVzY2VuZGFudFwiIHdpbGwgbm90IGJlIG5hcnJhdGVkIHdoZW4gdGhlIHVzZXIgcHJlc3MgdXAvZG93biBhcnJvdyBrZXlzLlxuICAgICAgLy8gaHR0cHM6Ly93d3cudzMub3JnL1RSL3dhaS1hcmlhLXByYWN0aWNlcy0xLjEvI2tiZF9mb2N1c19hY3RpdmVkZXNjZW5kYW50XG4gICAgICB0YWJJbmRleD17MH1cbiAgICA+XG4gICAgICA8U2NyZWVuUmVhZGVyVGV4dCBpZD17bGFiZWxJZH0gdGV4dD17dHJhbnNjcmlwdEFyaWFMYWJlbH0gLz5cbiAgICAgIHsvKiBUaGlzIDxzZWN0aW9uPiBpcyBmb3IgbGl2ZSByZWdpb24gb25seS4gQ29udGVudCBpcyBtYWRlIGludmlzaWJsZSB0aHJvdWdoIENTUy4gKi99XG4gICAgICA8c2VjdGlvblxuICAgICAgICBhcmlhLWF0b21pYz17ZmFsc2V9XG4gICAgICAgIGFyaWEtbGl2ZT1cInBvbGl0ZVwiXG4gICAgICAgIGFyaWEtcmVsZXZhbnQ9XCJhZGRpdGlvbnNcIlxuICAgICAgICBhcmlhLXJvbGVkZXNjcmlwdGlvbj17dHJhbnNjcmlwdFJvbGVEZXNjcmlwdGlvbn1cbiAgICAgICAgcm9sZT1cImxvZ1wiXG4gICAgICA+XG4gICAgICAgIHtyZW5kZXJpbmdFbGVtZW50cy5tYXAoKHsgYWN0aXZpdHksIGxpdmVSZWdpb25LZXkgfSkgPT4gKFxuICAgICAgICAgIDxGYWRlIGZhZGVBZnRlcj17aW50ZXJuYWxMaXZlUmVnaW9uRmFkZUFmdGVyfSBrZXk9e2xpdmVSZWdpb25LZXl9PlxuICAgICAgICAgICAgeygpID0+IDxTY3JlZW5SZWFkZXJBY3Rpdml0eSBhY3Rpdml0eT17YWN0aXZpdHl9IC8+fVxuICAgICAgICAgIDwvRmFkZT5cbiAgICAgICAgKSl9XG4gICAgICA8L3NlY3Rpb24+XG4gICAgICB7LyogVE9ETzogW1AyXSBGaXggRVNMaW50IGVycm9yIGBuby11c2UtYmVmb3JlLWRlZmluZWAgKi99XG4gICAgICB7LyogZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11c2UtYmVmb3JlLWRlZmluZSAqL31cbiAgICAgIDxJbnRlcm5hbFRyYW5zY3JpcHRTY3JvbGxhYmxlXG4gICAgICAgIGFjdGl2aXRpZXM9e3JlbmRlcmluZ0FjdGl2aXRpZXN9XG4gICAgICAgIG9uRm9jdXNBY3Rpdml0eT17aGFuZGxlRm9jdXNBY3Rpdml0eX1cbiAgICAgICAgb25Gb2N1c0ZpbGxlcj17aGFuZGxlRm9jdXNGaWxsZXJ9XG4gICAgICAgIHRlcm1pbmF0b3JSZWY9e3Rlcm1pbmF0b3JSZWZ9XG4gICAgICA+XG4gICAgICAgIHtyZW5kZXJpbmdFbGVtZW50cy5tYXAoXG4gICAgICAgICAgKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBhY3Rpdml0eSxcbiAgICAgICAgICAgICAgY2FsbGJhY2tSZWYsXG4gICAgICAgICAgICAgIGZvY3VzQWN0aXZpdHksXG4gICAgICAgICAgICAgIGhhbmRsZUZvY3VzLFxuICAgICAgICAgICAgICBoYW5kbGVLZXlEb3duLFxuICAgICAgICAgICAgICBoYW5kbGVNb3VzZURvd25DYXB0dXJlLFxuICAgICAgICAgICAgICBoaWRlVGltZXN0YW1wLFxuICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgIHJlbmRlckFjdGl2aXR5LFxuICAgICAgICAgICAgICByZW5kZXJBY3Rpdml0eVN0YXR1cyxcbiAgICAgICAgICAgICAgcmVuZGVyQXZhdGFyLFxuICAgICAgICAgICAgICByb2xlLFxuICAgICAgICAgICAgICBzaG91bGRTcGVhayxcbiAgICAgICAgICAgICAgc2hvd0NhbGxvdXRcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBpbmRleFxuICAgICAgICAgICkgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBhcmlhTGFiZWxJRCwgZWxlbWVudCB9ID1cbiAgICAgICAgICAgICAgYWN0aXZpdHlFbGVtZW50c1JlZi5jdXJyZW50LmZpbmQoZW50cnkgPT4gZW50cnkuYWN0aXZpdHkgPT09IGFjdGl2aXR5KSB8fCB7fTtcbiAgICAgICAgICAgIGNvbnN0IGFjdGl2ZURlc2NlbmRhbnQgPSBmb2N1c2VkQWN0aXZpdHlLZXkgPT09IGtleTtcbiAgICAgICAgICAgIGNvbnN0IGlzQ29udGVudEludGVyYWN0aXZlID0gISEoZWxlbWVudFxuICAgICAgICAgICAgICA/IHRhYmJhYmxlRWxlbWVudHMoZWxlbWVudC5xdWVyeVNlbGVjdG9yKCcud2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fYWN0aXZpdHktYm94JykpLmxlbmd0aFxuICAgICAgICAgICAgICA6IDApO1xuXG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICA8bGlcbiAgICAgICAgICAgICAgICBhcmlhLWxhYmVsbGVkYnk9e2FyaWFMYWJlbElEfVxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZT17Y2xhc3NOYW1lcygnd2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fYWN0aXZpdHknLCB7XG4gICAgICAgICAgICAgICAgICAnd2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fYWN0aXZpdHktLWFja25vd2xlZGdlZCc6IGluZGV4IDw9IGluZGV4T2ZMYXN0SW50ZXJhY3RlZEFjdGl2aXR5LFxuICAgICAgICAgICAgICAgICAgJ3dlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX2FjdGl2aXR5LS1mcm9tLWJvdCc6IHJvbGUgIT09ICd1c2VyJyxcbiAgICAgICAgICAgICAgICAgICd3ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0X19hY3Rpdml0eS0tZnJvbS11c2VyJzogcm9sZSA9PT0gJ3VzZXInXG4gICAgICAgICAgICAgICAgfSl9XG4gICAgICAgICAgICAgICAgLy8gU2V0IFwiaWRcIiBmb3IgdmFsaWQgZm9yIGFjY2Vzc2liaWxpdHkuXG4gICAgICAgICAgICAgICAgLyogZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0L2ZvcmJpZC1kb20tcHJvcHMgKi9cbiAgICAgICAgICAgICAgICBpZD17YWN0aXZlRGVzY2VuZGFudCA/IGFjdGl2ZURlc2NlbmRhbnRFbGVtZW50SWQgOiB1bmRlZmluZWR9XG4gICAgICAgICAgICAgICAga2V5PXtrZXl9XG4gICAgICAgICAgICAgICAgb25Gb2N1cz17aGFuZGxlRm9jdXN9XG4gICAgICAgICAgICAgICAgb25LZXlEb3duPXtoYW5kbGVLZXlEb3dufVxuICAgICAgICAgICAgICAgIG9uTW91c2VEb3duQ2FwdHVyZT17aGFuZGxlTW91c2VEb3duQ2FwdHVyZX1cbiAgICAgICAgICAgICAgICByZWY9e2NhbGxiYWNrUmVmfVxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPFNjcmVlblJlYWRlckFjdGl2aXR5IGFjdGl2aXR5PXthY3Rpdml0eX0gaWQ9e2FyaWFMYWJlbElEfSByZW5kZXJBdHRhY2htZW50cz17ZmFsc2V9PlxuICAgICAgICAgICAgICAgICAgeyEhaXNDb250ZW50SW50ZXJhY3RpdmUgJiYgPHA+e2FjdGl2aXR5SW50ZXJhY3RpdmVBbHR9PC9wPn1cbiAgICAgICAgICAgICAgICA8L1NjcmVlblJlYWRlckFjdGl2aXR5PlxuICAgICAgICAgICAgICAgIDxGb2N1c1JlZGlyZWN0b3JcbiAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cIndlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX2FjdGl2aXR5LXNlbnRpbmVsXCJcbiAgICAgICAgICAgICAgICAgIG9uRm9jdXM9e2ZvY3VzQWN0aXZpdHl9XG4gICAgICAgICAgICAgICAgICByZWRpcmVjdFJlZj17cm9vdEVsZW1lbnRSZWZ9XG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIndlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX2FjdGl2aXR5LWJveFwiPlxuICAgICAgICAgICAgICAgICAge3JlbmRlckFjdGl2aXR5KHtcbiAgICAgICAgICAgICAgICAgICAgaGlkZVRpbWVzdGFtcCxcbiAgICAgICAgICAgICAgICAgICAgcmVuZGVyQWN0aXZpdHlTdGF0dXMsXG4gICAgICAgICAgICAgICAgICAgIHJlbmRlckF2YXRhcixcbiAgICAgICAgICAgICAgICAgICAgc2hvd0NhbGxvdXRcbiAgICAgICAgICAgICAgICAgIH0pfVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIHtzaG91bGRTcGVhayAmJiA8U3BlYWtBY3Rpdml0eSBhY3Rpdml0eT17YWN0aXZpdHl9IC8+fVxuICAgICAgICAgICAgICAgIDxGb2N1c1JlZGlyZWN0b3JcbiAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cIndlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX2FjdGl2aXR5LXNlbnRpbmVsXCJcbiAgICAgICAgICAgICAgICAgIG9uRm9jdXM9e2ZvY3VzQWN0aXZpdHl9XG4gICAgICAgICAgICAgICAgICByZWRpcmVjdFJlZj17cm9vdEVsZW1lbnRSZWZ9XG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICBjbGFzc05hbWU9e2NsYXNzTmFtZXMoJ3dlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX2FjdGl2aXR5LWluZGljYXRvcicsIHtcbiAgICAgICAgICAgICAgICAgICAgJ3dlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX2FjdGl2aXR5LWluZGljYXRvci0tZmlyc3QnOiAhaW5kZXgsXG4gICAgICAgICAgICAgICAgICAgICd3ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0X19hY3Rpdml0eS1pbmRpY2F0b3ItLWZvY3VzJzogYWN0aXZlRGVzY2VuZGFudFxuICAgICAgICAgICAgICAgICAgfSl9XG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICApfVxuICAgICAgPC9JbnRlcm5hbFRyYW5zY3JpcHRTY3JvbGxhYmxlPlxuICAgICAgeyEhcmVuZGVyaW5nRWxlbWVudHMubGVuZ3RoICYmIChcbiAgICAgICAgPFJlYWN0LkZyYWdtZW50PlxuICAgICAgICAgIDxGb2N1c1JlZGlyZWN0b3JcbiAgICAgICAgICAgIGNsYXNzTmFtZT1cIndlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX3NlbnRpbmVsXCJcbiAgICAgICAgICAgIG9uRm9jdXM9e3NldEJvdHRvbW1vc3RGb2N1c2VkQWN0aXZpdHlLZXlJZk5lZWRlZH1cbiAgICAgICAgICAgIHJlZGlyZWN0UmVmPXtyb290RWxlbWVudFJlZn1cbiAgICAgICAgICAvPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwid2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fdGVybWluYXRvclwiIHJlZj17dGVybWluYXRvclJlZn0gdGFiSW5kZXg9ezB9PlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJ3ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0X190ZXJtaW5hdG9yLWJvZHlcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJ3ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0X190ZXJtaW5hdG9yLXRleHRcIj57dGVybWluYXRvclRleHR9PC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9SZWFjdC5GcmFnbWVudD5cbiAgICAgICl9XG4gICAgICA8ZGl2IGNsYXNzTmFtZT1cIndlYmNoYXRfX2Jhc2ljLXRyYW5zY3JpcHRfX2ZvY3VzLWluZGljYXRvclwiIC8+XG4gICAgPC9kaXY+XG4gICk7XG59O1xuXG5JbnRlcm5hbFRyYW5zY3JpcHQuZGVmYXVsdFByb3BzID0ge1xuICBjbGFzc05hbWU6ICcnXG59O1xuXG5JbnRlcm5hbFRyYW5zY3JpcHQucHJvcFR5cGVzID0ge1xuICBhY3Rpdml0eUVsZW1lbnRzUmVmOiBQcm9wVHlwZXMuc2hhcGUoe1xuICAgIGN1cnJlbnQ6IFByb3BUeXBlcy5hcnJheS5pc1JlcXVpcmVkXG4gIH0pLmlzUmVxdWlyZWQsXG4gIGNsYXNzTmFtZTogUHJvcFR5cGVzLnN0cmluZ1xufTtcblxuY29uc3QgSW50ZXJuYWxTY3JlZW5SZWFkZXJUcmFuc2NyaXB0ID0gKHsgcmVuZGVyaW5nRWxlbWVudHMgfSkgPT4ge1xuICBjb25zdCBsb2NhbGl6ZSA9IHVzZUxvY2FsaXplcigpO1xuICBjb25zdCBbaW50ZXJuYWxMaXZlUmVnaW9uRmFkZUFmdGVyXSA9IHVzZVN0eWxlT3B0aW9ucygpO1xuXG4gIGNvbnN0IHRyYW5zY3JpcHRSb2xlRGVzY3JpcHRpb24gPSBsb2NhbGl6ZSgnVFJBTlNDUklQVF9BUklBX1JPTEVfQUxUJyk7XG5cbiAgcmV0dXJuIChcbiAgICA8c2VjdGlvblxuICAgICAgYXJpYS1hdG9taWM9e2ZhbHNlfVxuICAgICAgYXJpYS1saXZlPVwicG9saXRlXCJcbiAgICAgIGFyaWEtcmVsZXZhbnQ9XCJhZGRpdGlvbnNcIlxuICAgICAgYXJpYS1yb2xlZGVzY3JpcHRpb249e3RyYW5zY3JpcHRSb2xlRGVzY3JpcHRpb259XG4gICAgICByb2xlPVwibG9nXCJcbiAgICA+XG4gICAgICB7cmVuZGVyaW5nRWxlbWVudHMubWFwKCh7IGFjdGl2aXR5LCBsaXZlUmVnaW9uS2V5IH0pID0+IChcbiAgICAgICAgPEZhZGUgZmFkZUFmdGVyPXtpbnRlcm5hbExpdmVSZWdpb25GYWRlQWZ0ZXJ9IGtleT17bGl2ZVJlZ2lvbktleX0+XG4gICAgICAgICAgeygpID0+IDxTY3JlZW5SZWFkZXJBY3Rpdml0eSBhY3Rpdml0eT17YWN0aXZpdHl9IC8+fVxuICAgICAgICA8L0ZhZGU+XG4gICAgICApKX1cbiAgICA8L3NlY3Rpb24+XG4gICk7XG59O1xuXG5JbnRlcm5hbFNjcmVlblJlYWRlclRyYW5zY3JpcHQucHJvcFR5cGVzID0ge1xuICByZW5kZXJpbmdFbGVtZW50czogUHJvcFR5cGVzLmFycmF5T2YoXG4gICAgUHJvcFR5cGVzLnNoYXBlKHtcbiAgICAgIGFjdGl2aXR5OiBQcm9wVHlwZXMuYW55LFxuICAgICAgbGl2ZVJlZ2lvbktleTogUHJvcFR5cGVzLnN0cmluZ1xuICAgIH0pXG4gICkuaXNSZXF1aXJlZFxufTtcblxuLy8gU2VwYXJhdGluZyBoaWdoLWZyZXF1ZW5jeSBob29rcyB0byBpbXByb3ZlIHBlcmZvcm1hbmNlLlxuY29uc3QgSW50ZXJuYWxUcmFuc2NyaXB0U2Nyb2xsYWJsZSA9ICh7IGFjdGl2aXRpZXMsIGNoaWxkcmVuLCBvbkZvY3VzQWN0aXZpdHksIG9uRm9jdXNGaWxsZXIsIHRlcm1pbmF0b3JSZWYgfSkgPT4ge1xuICBjb25zdCBbeyBhY3Rpdml0aWVzOiBhY3Rpdml0aWVzU3R5bGVTZXQgfV0gPSB1c2VTdHlsZVNldCgpO1xuICBjb25zdCBbeyBoaWRlU2Nyb2xsVG9FbmRCdXR0b24gfV0gPSB1c2VTdHlsZU9wdGlvbnMoKTtcbiAgY29uc3QgW2FuaW1hdGluZ1RvRW5kXSA9IHVzZUFuaW1hdGluZ1RvRW5kKCk7XG4gIGNvbnN0IFtzdGlja3ldID0gdXNlU3RpY2t5KCk7XG4gIGNvbnN0IGxhc3RWaXNpYmxlQWN0aXZpdHlJZCA9IGdldEFjdGl2aXR5VW5pcXVlSWQoYWN0aXZpdGllc1thY3Rpdml0aWVzLmxlbmd0aCAtIDFdIHx8IHt9KTsgLy8gQWN0aXZpdHkgSUQgb2YgdGhlIGxhc3QgdmlzaWJsZSBhY3Rpdml0eSBpbiB0aGUgbGlzdC5cbiAgY29uc3QgbG9jYWxpemUgPSB1c2VMb2NhbGl6ZXIoKTtcbiAgY29uc3Qgc2Nyb2xsVG9FbmRCdXR0b25SZWYgPSB1c2VSZWYoKTtcblxuICBjb25zdCBsYXN0UmVhZEFjdGl2aXR5SWRSZWYgPSB1c2VSZWYobGFzdFZpc2libGVBY3Rpdml0eUlkKTtcbiAgY29uc3QgdHJhbnNjcmlwdFJvbGVEZXNjcmlwdGlvbiA9IGxvY2FsaXplKCdUUkFOU0NSSVBUX0FSSUFfUk9MRV9BTFQnKTtcblxuICBjb25zdCBhbGxBY3Rpdml0aWVzUmVhZCA9IGxhc3RWaXNpYmxlQWN0aXZpdHlJZCA9PT0gbGFzdFJlYWRBY3Rpdml0eUlkUmVmLmN1cnJlbnQ7XG5cbiAgY29uc3QgaGFuZGxlU2Nyb2xsVG9FbmRCdXR0b25DbGljayA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICAvLyBBZnRlciB0aGUgXCJOZXcgbWVzc2FnZVwiIGJ1dHRvbiBpcyBjbGlja2VkLCBmb2N1cyBvbiB0aGUgZmlyc3QgdW5yZWFkIGFjdGl2aXR5LlxuICAgIGNvbnN0IGluZGV4ID0gYWN0aXZpdGllcy5maW5kSW5kZXgoKHsgaWQgfSkgPT4gaWQgPT09IGxhc3RSZWFkQWN0aXZpdHlJZFJlZi5jdXJyZW50KTtcblxuICAgIGlmICh+aW5kZXgpIHtcbiAgICAgIGNvbnN0IGZpcnN0VW5yZWFkQWN0aXZpdHkgPSBhY3Rpdml0aWVzW2luZGV4ICsgMV07XG5cbiAgICAgIGlmIChmaXJzdFVucmVhZEFjdGl2aXR5KSB7XG4gICAgICAgIHJldHVybiBvbkZvY3VzQWN0aXZpdHkoZ2V0QWN0aXZpdHlVbmlxdWVJZChmaXJzdFVucmVhZEFjdGl2aXR5KSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgeyBjdXJyZW50IH0gPSB0ZXJtaW5hdG9yUmVmO1xuXG4gICAgY3VycmVudCAmJiBjdXJyZW50LmZvY3VzKCk7XG4gIH0sIFthY3Rpdml0aWVzLCBsYXN0UmVhZEFjdGl2aXR5SWRSZWYsIG9uRm9jdXNBY3Rpdml0eSwgdGVybWluYXRvclJlZl0pO1xuXG4gIGlmIChzdGlja3kpIHtcbiAgICAvLyBJZiBpdCBpcyBzdGlja3ksIHRoZSB1c2VyIGlzIGF0IHRoZSBib3R0b20gb2YgdGhlIHRyYW5zY3JpcHQsIGV2ZXJ5dGhpbmcgaXMgcmVhZC5cbiAgICAvLyBTbyBtYXJrIHRoZSBhY3Rpdml0eSBJRCBhcyByZWFkLlxuICAgIGxhc3RSZWFkQWN0aXZpdHlJZFJlZi5jdXJyZW50ID0gbGFzdFZpc2libGVBY3Rpdml0eUlkO1xuICB9XG5cbiAgLy8gRmluZHMgd2hlcmUgd2Ugc2hvdWxkIHJlbmRlciB0aGUgXCJOZXcgbWVzc2FnZXNcIiBidXR0b24sIGluIGluZGV4LiBSZXR1cm5zIC0xIHRvIGhpZGUgdGhlIGJ1dHRvbi5cbiAgY29uc3QgcmVuZGVyU2VwYXJhdG9yQWZ0ZXJJbmRleCA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIC8vIERvbid0IHNob3cgdGhlIGJ1dHRvbiBpZjpcbiAgICAvLyAtIEFsbCBhY3Rpdml0aWVzIGhhdmUgYmVlbiByZWFkXG4gICAgLy8gLSBDdXJyZW50bHkgYW5pbWF0aW5nIHRvd2FyZHMgYm90dG9tXG4gICAgLy8gICAtIFwiTmV3IG1lc3NhZ2VzXCIgYnV0dG9uIG11c3Qgbm90IGZsYXNoIHdoZW46IDEuIFR5cGUgXCJoZWxwXCIsIDIuIFNjcm9sbCB0byB0b3AsIDMuIFR5cGUgXCJoZWxwXCIgYWdhaW4sIDQuIEV4cGVjdCB0aGUgXCJOZXcgbWVzc2FnZXNcIiBidXR0b24gbm90IGZsYXNoeVxuICAgIC8vIC0gSGlkZGVuIGJ5IHN0eWxlIG9wdGlvbnNcbiAgICAvLyAtIEl0IGlzIGFscmVhZHkgYXQgdGhlIGJvdHRvbSAoc3RpY2t5KVxuXG4gICAgLy8gQW55IGNoYW5nZXMgdG8gdGhpcyBsb2dpYywgdmVyaWZ5OlxuICAgIC8vIC0gXCJOZXcgbWVzc2FnZXNcIiBidXR0b24gc2hvdWxkIHBlcnNpc3Qgd2hpbGUgcHJvZ3JhbW1hdGljYWxseSBzY3JvbGxpbmcgdG8gbWlkLXBvaW50IG9mIHRoZSB0cmFuc2NyaXB0OlxuICAgIC8vICAgMS4gVHlwZSBcImhlbHBcIlxuICAgIC8vICAgMi4gVHlwZSBcInByb2FjdGl2ZVwiLCB0aGVuIGltbWVkaWF0ZWx5IHNjcm9sbCB0byB0b3BcbiAgICAvLyAgICAgIEV4cGVjdDogdGhlIFwiTmV3IG1lc3NhZ2VzXCIgYnV0dG9uIHNob3VsZCBhcHBlYXJcbiAgICAvLyAgIDMuIFJ1biBob29rIFwidXNlU2Nyb2xsVG8oeyBzY3JvbGxUb3A6IDUwMCB9KVwiXG4gICAgLy8gICAgICBFeHBlY3Q6IHdoZW4gdGhlIHNjcm9sbCBpcyBhbmltYXRpbmcgdG8gNTAwcHgsIHRoZSBcIk5ldyBtZXNzYWdlc1wiIGJ1dHRvbiBzaG91bGQga2VwdCBvbiB0aGUgc2NyZWVuXG4gICAgLy8gLSBcIk5ldyBtZXNzYWdlc1wiIGJ1dHRvbiBtdXN0IG5vdCBmbGFzaHk6XG4gICAgLy8gICAxLiBUeXBlIFwiaGVscFwiXG4gICAgLy8gICAyLiBTY3JvbGwgdG8gdG9wXG4gICAgLy8gICAgICBFeHBlY3Q6IG5vIFwiTmV3IG1lc3NhZ2VzXCIgYnV0dG9uIGlzIHNob3duXG4gICAgLy8gICAzLiBUeXBlIFwiaGVscFwiIGFnYWluXG4gICAgLy8gICAgICBFeHBlY3Q6IFwiTmV3IG1lc3NhZ2VzXCIgYnV0dG9uIG11c3Qgbm90IGZsYXNoLWFwcGVhclxuXG4gICAgaWYgKGFsbEFjdGl2aXRpZXNSZWFkIHx8IGFuaW1hdGluZ1RvRW5kIHx8IGhpZGVTY3JvbGxUb0VuZEJ1dHRvbiB8fCBzdGlja3kpIHtcbiAgICAgIHJldHVybiAtMTtcbiAgICB9XG5cbiAgICByZXR1cm4gYWN0aXZpdGllcy5maW5kSW5kZXgoYWN0aXZpdHkgPT4gZ2V0QWN0aXZpdHlVbmlxdWVJZChhY3Rpdml0eSkgPT09IGxhc3RSZWFkQWN0aXZpdHlJZFJlZi5jdXJyZW50KTtcbiAgfSwgW2FjdGl2aXRpZXMsIGFsbEFjdGl2aXRpZXNSZWFkLCBhbmltYXRpbmdUb0VuZCwgaGlkZVNjcm9sbFRvRW5kQnV0dG9uLCBsYXN0UmVhZEFjdGl2aXR5SWRSZWYsIHN0aWNreV0pO1xuXG4gIHJldHVybiAoXG4gICAgPFJlYWN0LkZyYWdtZW50PlxuICAgICAge3JlbmRlclNlcGFyYXRvckFmdGVySW5kZXggIT09IC0xICYmIChcbiAgICAgICAgPFNjcm9sbFRvRW5kQnV0dG9uIG9uQ2xpY2s9e2hhbmRsZVNjcm9sbFRvRW5kQnV0dG9uQ2xpY2t9IHJlZj17c2Nyb2xsVG9FbmRCdXR0b25SZWZ9IC8+XG4gICAgICApfVxuICAgICAgeyEhUmVhY3QuQ2hpbGRyZW4uY291bnQoY2hpbGRyZW4pICYmIChcbiAgICAgICAgPEZvY3VzUmVkaXJlY3RvciBjbGFzc05hbWU9XCJ3ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0X19zZW50aW5lbFwiIHJlZGlyZWN0UmVmPXt0ZXJtaW5hdG9yUmVmfSAvPlxuICAgICAgKX1cbiAgICAgIDxSZWFjdFNjcm9sbFRvQm90dG9tUGFuZWwgY2xhc3NOYW1lPVwid2ViY2hhdF9fYmFzaWMtdHJhbnNjcmlwdF9fc2Nyb2xsYWJsZVwiPlxuICAgICAgICA8ZGl2IGFyaWEtaGlkZGVuPXt0cnVlfSBjbGFzc05hbWU9XCJ3ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0X19maWxsZXJcIiBvbkZvY3VzPXtvbkZvY3VzRmlsbGVyfSAvPlxuICAgICAgICA8dWxcbiAgICAgICAgICBhcmlhLXJvbGVkZXNjcmlwdGlvbj17dHJhbnNjcmlwdFJvbGVEZXNjcmlwdGlvbn1cbiAgICAgICAgICBjbGFzc05hbWU9e2NsYXNzTmFtZXMoYWN0aXZpdGllc1N0eWxlU2V0ICsgJycsICd3ZWJjaGF0X19iYXNpYy10cmFuc2NyaXB0X190cmFuc2NyaXB0Jyl9XG4gICAgICAgICAgcm9sZT1cImxpc3RcIlxuICAgICAgICA+XG4gICAgICAgICAge2NoaWxkcmVufVxuICAgICAgICA8L3VsPlxuICAgICAgICA8QmFzaWNUeXBpbmdJbmRpY2F0b3IgLz5cbiAgICAgIDwvUmVhY3RTY3JvbGxUb0JvdHRvbVBhbmVsPlxuICAgIDwvUmVhY3QuRnJhZ21lbnQ+XG4gICk7XG59O1xuXG5JbnRlcm5hbFRyYW5zY3JpcHRTY3JvbGxhYmxlLnByb3BUeXBlcyA9IHtcbiAgYWN0aXZpdGllczogUHJvcFR5cGVzLmFycmF5LmlzUmVxdWlyZWQsXG4gIGNoaWxkcmVuOiBQcm9wVHlwZXMuYW55LmlzUmVxdWlyZWQsXG4gIG9uRm9jdXNBY3Rpdml0eTogUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZCxcbiAgb25Gb2N1c0ZpbGxlcjogUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZCxcbiAgdGVybWluYXRvclJlZjogUHJvcFR5cGVzLmFueS5pc1JlcXVpcmVkXG59O1xuXG5jb25zdCBTZXRTY3JvbGxlciA9ICh7IGFjdGl2aXR5RWxlbWVudHNSZWYsIHNjcm9sbGVyUmVmIH0pID0+IHtcbiAgY29uc3QgW1xuICAgIHsgYXV0b1Njcm9sbFNuYXBPbkFjdGl2aXR5LCBhdXRvU2Nyb2xsU25hcE9uQWN0aXZpdHlPZmZzZXQsIGF1dG9TY3JvbGxTbmFwT25QYWdlLCBhdXRvU2Nyb2xsU25hcE9uUGFnZU9mZnNldCB9XG4gIF0gPSB1c2VTdHlsZU9wdGlvbnMoKTtcbiAgY29uc3QgW2xhc3RBY2tub3dsZWRnZWRBY3Rpdml0eV0gPSB1c2VBY2tub3dsZWRnZWRBY3Rpdml0eSgpO1xuXG4gIGNvbnN0IGxhc3RBY2tub3dsZWRnZWRBY3Rpdml0eVJlZiA9IHVzZVJlZihsYXN0QWNrbm93bGVkZ2VkQWN0aXZpdHkpO1xuXG4gIGxhc3RBY2tub3dsZWRnZWRBY3Rpdml0eVJlZi5jdXJyZW50ID0gbGFzdEFja25vd2xlZGdlZEFjdGl2aXR5O1xuXG4gIHNjcm9sbGVyUmVmLmN1cnJlbnQgPSB1c2VDYWxsYmFjayhcbiAgICAoeyBvZmZzZXRIZWlnaHQsIHNjcm9sbFRvcCB9KSA9PiB7XG4gICAgICBjb25zdCBwYXRjaGVkQXV0b1Njcm9sbFNuYXBPbkFjdGl2aXR5ID1cbiAgICAgICAgdHlwZW9mIGF1dG9TY3JvbGxTbmFwT25BY3Rpdml0eSA9PT0gJ251bWJlcidcbiAgICAgICAgICA/IE1hdGgubWF4KDAsIGF1dG9TY3JvbGxTbmFwT25BY3Rpdml0eSlcbiAgICAgICAgICA6IGF1dG9TY3JvbGxTbmFwT25BY3Rpdml0eVxuICAgICAgICAgID8gMVxuICAgICAgICAgIDogMDtcbiAgICAgIGNvbnN0IHBhdGNoZWRBdXRvU2Nyb2xsU25hcE9uUGFnZSA9XG4gICAgICAgIHR5cGVvZiBhdXRvU2Nyb2xsU25hcE9uUGFnZSA9PT0gJ251bWJlcidcbiAgICAgICAgICA/IE1hdGgubWF4KDAsIE1hdGgubWluKDEsIGF1dG9TY3JvbGxTbmFwT25QYWdlKSlcbiAgICAgICAgICA6IGF1dG9TY3JvbGxTbmFwT25QYWdlXG4gICAgICAgICAgPyAxXG4gICAgICAgICAgOiAwO1xuICAgICAgY29uc3QgcGF0Y2hlZEF1dG9TY3JvbGxTbmFwT25BY3Rpdml0eU9mZnNldCA9XG4gICAgICAgIHR5cGVvZiBhdXRvU2Nyb2xsU25hcE9uQWN0aXZpdHlPZmZzZXQgPT09ICdudW1iZXInID8gYXV0b1Njcm9sbFNuYXBPbkFjdGl2aXR5T2Zmc2V0IDogMDtcbiAgICAgIGNvbnN0IHBhdGNoZWRBdXRvU2Nyb2xsU25hcE9uUGFnZU9mZnNldCA9XG4gICAgICAgIHR5cGVvZiBhdXRvU2Nyb2xsU25hcE9uUGFnZU9mZnNldCA9PT0gJ251bWJlcicgPyBhdXRvU2Nyb2xsU25hcE9uUGFnZU9mZnNldCA6IDA7XG5cbiAgICAgIGlmIChwYXRjaGVkQXV0b1Njcm9sbFNuYXBPbkFjdGl2aXR5IHx8IHBhdGNoZWRBdXRvU2Nyb2xsU25hcE9uUGFnZSkge1xuICAgICAgICBjb25zdCB7IGN1cnJlbnQ6IGxhc3RBY2tub3dsZWRnZWRBY3Rpdml0eSB9ID0gbGFzdEFja25vd2xlZGdlZEFjdGl2aXR5UmVmO1xuXG4gICAgICAgIGNvbnN0IHZhbHVlcyA9IFtdO1xuXG4gICAgICAgIGlmIChwYXRjaGVkQXV0b1Njcm9sbFNuYXBPbkFjdGl2aXR5KSB7XG4gICAgICAgICAgY29uc3QgeyBlbGVtZW50OiBudGhVbmFja25vd2xlZGdlZEFjdGl2aXR5RWxlbWVudCB9ID1cbiAgICAgICAgICAgIGFjdGl2aXR5RWxlbWVudHNSZWYuY3VycmVudFtcbiAgICAgICAgICAgICAgYWN0aXZpdHlFbGVtZW50c1JlZi5jdXJyZW50LmZpbmRJbmRleCgoeyBhY3Rpdml0eSB9KSA9PiBhY3Rpdml0eSA9PT0gbGFzdEFja25vd2xlZGdlZEFjdGl2aXR5KSArXG4gICAgICAgICAgICAgICAgcGF0Y2hlZEF1dG9TY3JvbGxTbmFwT25BY3Rpdml0eVxuICAgICAgICAgICAgXSB8fCB7fTtcblxuICAgICAgICAgIGlmIChudGhVbmFja25vd2xlZGdlZEFjdGl2aXR5RWxlbWVudCkge1xuICAgICAgICAgICAgdmFsdWVzLnB1c2goXG4gICAgICAgICAgICAgIG50aFVuYWNrbm93bGVkZ2VkQWN0aXZpdHlFbGVtZW50Lm9mZnNldFRvcCArXG4gICAgICAgICAgICAgICAgbnRoVW5hY2tub3dsZWRnZWRBY3Rpdml0eUVsZW1lbnQub2Zmc2V0SGVpZ2h0IC1cbiAgICAgICAgICAgICAgICBvZmZzZXRIZWlnaHQgLVxuICAgICAgICAgICAgICAgIHNjcm9sbFRvcCArXG4gICAgICAgICAgICAgICAgcGF0Y2hlZEF1dG9TY3JvbGxTbmFwT25BY3Rpdml0eU9mZnNldFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGF0Y2hlZEF1dG9TY3JvbGxTbmFwT25QYWdlKSB7XG4gICAgICAgICAgY29uc3QgeyBlbGVtZW50OiBmaXJzdFVuYWNrbm93bGVkZ2VkQWN0aXZpdHlFbGVtZW50IH0gPVxuICAgICAgICAgICAgYWN0aXZpdHlFbGVtZW50c1JlZi5jdXJyZW50W1xuICAgICAgICAgICAgICBhY3Rpdml0eUVsZW1lbnRzUmVmLmN1cnJlbnQuZmluZEluZGV4KCh7IGFjdGl2aXR5IH0pID0+IGFjdGl2aXR5ID09PSBsYXN0QWNrbm93bGVkZ2VkQWN0aXZpdHkpICsgMVxuICAgICAgICAgICAgXSB8fCB7fTtcblxuICAgICAgICAgIGlmIChmaXJzdFVuYWNrbm93bGVkZ2VkQWN0aXZpdHlFbGVtZW50KSB7XG4gICAgICAgICAgICB2YWx1ZXMucHVzaChcbiAgICAgICAgICAgICAgZmlyc3RVbmFja25vd2xlZGdlZEFjdGl2aXR5RWxlbWVudC5vZmZzZXRUb3AgLVxuICAgICAgICAgICAgICAgIHNjcm9sbFRvcCAtXG4gICAgICAgICAgICAgICAgb2Zmc2V0SGVpZ2h0ICogKDEgLSBwYXRjaGVkQXV0b1Njcm9sbFNuYXBPblBhZ2UpICtcbiAgICAgICAgICAgICAgICBwYXRjaGVkQXV0b1Njcm9sbFNuYXBPblBhZ2VPZmZzZXRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHZhbHVlcy5yZWR1Y2UoKG1pblZhbHVlLCB2YWx1ZSkgPT4gTWF0aC5taW4obWluVmFsdWUsIHZhbHVlKSwgSW5maW5pdHkpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gSW5maW5pdHk7XG4gICAgfSxcbiAgICBbXG4gICAgICBhY3Rpdml0eUVsZW1lbnRzUmVmLFxuICAgICAgYXV0b1Njcm9sbFNuYXBPbkFjdGl2aXR5LFxuICAgICAgYXV0b1Njcm9sbFNuYXBPbkFjdGl2aXR5T2Zmc2V0LFxuICAgICAgYXV0b1Njcm9sbFNuYXBPblBhZ2UsXG4gICAgICBhdXRvU2Nyb2xsU25hcE9uUGFnZU9mZnNldCxcbiAgICAgIGxhc3RBY2tub3dsZWRnZWRBY3Rpdml0eVJlZlxuICAgIF1cbiAgKTtcblxuICByZXR1cm4gZmFsc2U7XG59O1xuXG5jb25zdCBCYXNpY1RyYW5zY3JpcHQgPSAoeyBjbGFzc05hbWUgfSkgPT4ge1xuICBjb25zdCBhY3Rpdml0eUVsZW1lbnRzUmVmID0gdXNlUmVmKFtdKTtcbiAgY29uc3Qgc2Nyb2xsZXJSZWYgPSB1c2VSZWYoKCkgPT4gSW5maW5pdHkpO1xuXG4gIGNvbnN0IHNjcm9sbGVyID0gdXNlQ2FsbGJhY2soKC4uLmFyZ3MpID0+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=