@envive-ai/react-hooks 0.2.4 → 0.2.6-alpha

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 (878) hide show
  1. package/dist/AmplitudeOperations-CDe6oRn4.cjs +41 -0
  2. package/dist/AmplitudeOperations-zFjk1Mkm.js +34 -0
  3. package/dist/{NewOrgConfig-xNlcpcF_.js → NewOrgConfig-ChNJ3ZtC.js} +2 -2
  4. package/dist/{NewOrgConfig-B_1A1d9q.cjs → NewOrgConfig-KHz61ikr.cjs} +2 -2
  5. package/dist/TrackComponentVisibleEvent-f8ahqV1g.js +53 -0
  6. package/dist/TrackComponentVisibleEvent-uEzgBXb9.cjs +60 -0
  7. package/dist/amplitudeContext-CRFxGj_x.d.ts +52 -0
  8. package/dist/amplitudeContext-ZkerrMUa.d.cts +52 -0
  9. package/dist/api-1-73JxnF.js +166 -0
  10. package/dist/api-ZNG6wObS.cjs +239 -0
  11. package/dist/application/models/graphql/index.cjs +3 -3
  12. package/dist/application/models/graphql/index.d.cts +2 -2
  13. package/dist/application/models/graphql/index.d.ts +2 -2
  14. package/dist/application/models/graphql/index.js +2 -3
  15. package/dist/application/models/guards/api/index.cjs +3 -3
  16. package/dist/application/models/guards/api/index.d.cts +2 -2
  17. package/dist/application/models/guards/api/index.d.ts +2 -2
  18. package/dist/application/models/guards/api/index.js +3 -3
  19. package/dist/application/models/guards/utils.cjs +1 -1
  20. package/dist/application/models/guards/utils.d.ts +1 -1
  21. package/dist/application/models/guards/utils.js +1 -1
  22. package/dist/application/models/index.cjs +7 -23
  23. package/dist/application/models/index.d.cts +167 -11
  24. package/dist/application/models/index.d.ts +168 -12
  25. package/dist/application/models/index.js +7 -11
  26. package/dist/application/utils/index.cjs +18 -18
  27. package/dist/application/utils/index.d.cts +16 -65
  28. package/dist/application/utils/index.d.ts +14 -63
  29. package/dist/application/utils/index.js +18 -18
  30. package/dist/{atomStore-BLYJ2ZoQ.js → atomStore-DAQvNPkh.js} +1 -1
  31. package/dist/{atomStore-8ppNkJ_n.cjs → atomStore-DD9g7Zw2.cjs} +1 -1
  32. package/dist/atoms/app/index.cjs +18 -18
  33. package/dist/atoms/app/index.d.cts +9 -20
  34. package/dist/atoms/app/index.d.ts +8 -19
  35. package/dist/atoms/app/index.js +18 -18
  36. package/dist/atoms/atomStore/index.cjs +1 -1
  37. package/dist/atoms/atomStore/index.js +1 -1
  38. package/dist/atoms/chat/index.cjs +20 -20
  39. package/dist/atoms/chat/index.d.cts +37 -45
  40. package/dist/atoms/chat/index.d.ts +35 -43
  41. package/dist/atoms/chat/index.js +20 -20
  42. package/dist/atoms/globalSearch/index.cjs +1 -1
  43. package/dist/atoms/globalSearch/index.d.cts +6 -6
  44. package/dist/atoms/globalSearch/index.d.ts +6 -6
  45. package/dist/atoms/globalSearch/index.js +1 -1
  46. package/dist/atoms/org/index.cjs +10 -11
  47. package/dist/atoms/org/index.d.cts +19 -31
  48. package/dist/atoms/org/index.d.ts +19 -31
  49. package/dist/atoms/org/index.js +2 -3
  50. package/dist/atoms/search/index.cjs +6 -46
  51. package/dist/atoms/search/index.d.cts +76 -14
  52. package/dist/atoms/search/index.d.ts +76 -14
  53. package/dist/atoms/search/index.js +6 -28
  54. package/dist/atoms/search/utils.d.cts +1 -1
  55. package/dist/atoms/search/utils.d.ts +1 -1
  56. package/dist/cdnContext-BLNiW2HT.cjs +53 -0
  57. package/dist/cdnContext-DT6J5nCw.js +38 -0
  58. package/dist/chat-C0cgfkL8.js +230 -0
  59. package/dist/{chat-pXCsesuS.js → chat-ClvJ9xEj.js} +1 -1
  60. package/dist/{chat-sCX7aTrz.cjs → chat-DCGriB7h.cjs} +1 -1
  61. package/dist/chat-DULmjtx1.cjs +330 -0
  62. package/dist/chatState-BrSfXIV4.cjs +120 -0
  63. package/dist/chatState-Cn8JGAlH.js +34 -0
  64. package/dist/{common-4xhjcUbt.cjs → common-DQPvV_S_.cjs} +1 -1
  65. package/dist/{common-DhKoZ6jN.js → common-c_4eX0qn.js} +1 -1
  66. package/dist/{components-BUisjl4v.js → components-CDpaMUjK.js} +1 -1
  67. package/dist/{components-DVaYBroL.cjs → components-DKwVHIjq.cjs} +1 -1
  68. package/dist/config/index.cjs +71 -0
  69. package/dist/config/index.d.cts +5 -0
  70. package/dist/config/index.d.ts +5 -0
  71. package/dist/config/index.js +6 -0
  72. package/dist/config/locators/components/chat/index.cjs +1 -1
  73. package/dist/config/locators/components/chat/index.d.cts +1 -1
  74. package/dist/config/locators/components/chat/index.d.ts +1 -1
  75. package/dist/config/locators/components/chat/index.js +1 -1
  76. package/dist/config/locators/components/chat/variants/index.d.cts +1 -1
  77. package/dist/config/locators/components/chat/variants/index.d.ts +1 -1
  78. package/dist/config/locators/components/common/index.cjs +1 -1
  79. package/dist/config/locators/components/common/index.d.cts +1 -1
  80. package/dist/config/locators/components/common/index.d.ts +1 -1
  81. package/dist/config/locators/components/common/index.js +1 -1
  82. package/dist/config/locators/components/index.cjs +1 -1
  83. package/dist/config/locators/components/index.d.cts +1 -1
  84. package/dist/config/locators/components/index.d.ts +1 -1
  85. package/dist/config/locators/components/index.js +1 -1
  86. package/dist/config/locators/components/search/index.d.cts +1 -1
  87. package/dist/config/locators/components/search/index.d.ts +1 -1
  88. package/dist/config/locators/index.cjs +23 -44
  89. package/dist/config/locators/index.d.cts +5 -26
  90. package/dist/config/locators/index.d.ts +5 -26
  91. package/dist/config/locators/index.js +5 -26
  92. package/dist/contexts/amplitudeContext/index.cjs +18 -18
  93. package/dist/contexts/amplitudeContext/index.d.cts +1 -1
  94. package/dist/contexts/amplitudeContext/index.d.ts +1 -1
  95. package/dist/contexts/amplitudeContext/index.js +18 -18
  96. package/dist/contexts/cdnContext/index.cjs +4 -4
  97. package/dist/contexts/cdnContext/index.d.cts +2 -6
  98. package/dist/contexts/cdnContext/index.d.ts +2 -6
  99. package/dist/contexts/cdnContext/index.js +4 -4
  100. package/dist/contexts/enviveConfigContext/index.cjs +4 -4
  101. package/dist/contexts/enviveConfigContext/index.d.cts +3 -24
  102. package/dist/contexts/enviveConfigContext/index.d.ts +3 -24
  103. package/dist/contexts/enviveConfigContext/index.js +4 -4
  104. package/dist/contexts/enviveCssContext/index.cjs +15 -19
  105. package/dist/contexts/enviveCssContext/index.d.cts +3 -5
  106. package/dist/contexts/enviveCssContext/index.d.ts +3 -5
  107. package/dist/contexts/enviveCssContext/index.js +15 -19
  108. package/dist/contexts/featureFlagContext/index.cjs +9 -10
  109. package/dist/contexts/featureFlagContext/index.d.cts +3 -11
  110. package/dist/contexts/featureFlagContext/index.d.ts +3 -11
  111. package/dist/contexts/featureFlagContext/index.js +6 -7
  112. package/dist/contexts/featureFlagServiceContext/index.cjs +4 -3
  113. package/dist/contexts/featureFlagServiceContext/index.d.cts +1 -4
  114. package/dist/contexts/featureFlagServiceContext/index.d.ts +1 -4
  115. package/dist/contexts/featureFlagServiceContext/index.js +4 -3
  116. package/dist/contexts/graphqlContext/index.cjs +8 -13
  117. package/dist/contexts/graphqlContext/index.d.cts +11 -14
  118. package/dist/contexts/graphqlContext/index.d.ts +11 -14
  119. package/dist/contexts/graphqlContext/index.js +8 -13
  120. package/dist/contexts/localStorageContext/index.cjs +3 -3
  121. package/dist/contexts/localStorageContext/index.d.cts +3 -22
  122. package/dist/contexts/localStorageContext/index.d.ts +3 -22
  123. package/dist/contexts/localStorageContext/index.js +4 -3
  124. package/dist/contexts/newOrgConfigContext/index.cjs +13 -17
  125. package/dist/contexts/newOrgConfigContext/index.d.cts +12 -15
  126. package/dist/contexts/newOrgConfigContext/index.d.ts +12 -15
  127. package/dist/contexts/newOrgConfigContext/index.js +13 -17
  128. package/dist/contexts/searchContext/index.cjs +23 -23
  129. package/dist/contexts/searchContext/index.d.cts +2 -7
  130. package/dist/contexts/searchContext/index.d.ts +2 -7
  131. package/dist/contexts/searchContext/index.js +23 -23
  132. package/dist/contexts/sessionStorageContext/index.cjs +2 -2
  133. package/dist/contexts/sessionStorageContext/index.d.cts +2 -6
  134. package/dist/contexts/sessionStorageContext/index.d.ts +2 -6
  135. package/dist/contexts/sessionStorageContext/index.js +2 -2
  136. package/dist/contexts/shopifyUrlContext/index.cjs +2 -2
  137. package/dist/contexts/shopifyUrlContext/index.d.cts +2 -11
  138. package/dist/contexts/shopifyUrlContext/index.d.ts +2 -11
  139. package/dist/contexts/shopifyUrlContext/index.js +2 -2
  140. package/dist/contexts/systemSettingsContext/index.cjs +4 -4
  141. package/dist/contexts/systemSettingsContext/index.d.cts +4 -14
  142. package/dist/contexts/systemSettingsContext/index.d.ts +4 -14
  143. package/dist/contexts/systemSettingsContext/index.js +4 -4
  144. package/dist/contexts/userIdentityContext/index.cjs +18 -18
  145. package/dist/contexts/userIdentityContext/index.d.cts +11 -2
  146. package/dist/contexts/userIdentityContext/index.d.ts +11 -2
  147. package/dist/contexts/userIdentityContext/index.js +18 -18
  148. package/dist/dist-BZX_Mgfn.cjs +6019 -0
  149. package/dist/dist-CIM4YRqp.js +5923 -0
  150. package/dist/domObserver-DKcas6tl.js +1 -1
  151. package/dist/domObserver-Do6RAJdf.cjs +1 -1
  152. package/dist/enviveConfig-DaotBKMS.cjs +130 -0
  153. package/dist/enviveConfig-DrvYlCYG.js +62 -0
  154. package/dist/enviveConfigContext--89ejDs5.cjs +60 -0
  155. package/dist/enviveConfigContext-BCnzgk4M.js +45 -0
  156. package/dist/events/index.cjs +2 -3
  157. package/dist/events/index.d.cts +2 -15
  158. package/dist/events/index.d.ts +2 -15
  159. package/dist/events/index.js +2 -2
  160. package/dist/events-CgFGtanE.cjs +69 -0
  161. package/dist/events-WOOrnUAx.js +63 -0
  162. package/dist/exceptions/index.cjs +4 -0
  163. package/dist/exceptions/index.d.cts +12 -0
  164. package/dist/exceptions/index.d.ts +12 -0
  165. package/dist/exceptions/index.js +3 -0
  166. package/dist/exceptions-BiSWJEl2.cjs +32 -0
  167. package/dist/exceptions-DSv0ZaH0.js +20 -0
  168. package/dist/featureFlagServiceContext-B7je7VZV.d.cts +24 -0
  169. package/dist/featureFlagServiceContext-BztKnBPk.cjs +66 -0
  170. package/dist/featureFlagServiceContext-DpdlcjNb.js +46 -0
  171. package/dist/featureFlagServiceContext-ahy3jou0.d.ts +24 -0
  172. package/dist/{globalSearch-OiF96VLG.cjs → globalSearch-Cpc8egsM.cjs} +1 -1
  173. package/dist/{globalSearch-B_v9qfCT.js → globalSearch-nmrfGLOn.js} +1 -1
  174. package/dist/graphql-CWNkUHFV.js +46 -0
  175. package/dist/graphql-DT-H-lta.cjs +70 -0
  176. package/dist/graphqlContext-B181y-sa.cjs +111 -0
  177. package/dist/graphqlContext-CWulFxxC.js +96 -0
  178. package/dist/hooks/AmplitudeOperations/index.cjs +20 -21
  179. package/dist/hooks/AmplitudeOperations/index.d.cts +2 -2
  180. package/dist/hooks/AmplitudeOperations/index.d.ts +2 -2
  181. package/dist/hooks/AmplitudeOperations/index.js +19 -20
  182. package/dist/hooks/AppDetails/index.cjs +21 -21
  183. package/dist/hooks/AppDetails/index.d.cts +3 -23
  184. package/dist/hooks/AppDetails/index.d.ts +3 -23
  185. package/dist/hooks/AppDetails/index.js +21 -21
  186. package/dist/hooks/CdnOperations/index.cjs +4 -4
  187. package/dist/hooks/CdnOperations/index.js +4 -4
  188. package/dist/hooks/ChatToggle/index.cjs +23 -23
  189. package/dist/hooks/ChatToggle/index.d.cts +2 -2
  190. package/dist/hooks/ChatToggle/index.d.ts +2 -2
  191. package/dist/hooks/ChatToggle/index.js +21 -21
  192. package/dist/hooks/ChatToggleAnalytics/index.cjs +22 -23
  193. package/dist/hooks/ChatToggleAnalytics/index.d.cts +2 -2
  194. package/dist/hooks/ChatToggleAnalytics/index.d.ts +2 -2
  195. package/dist/hooks/ChatToggleAnalytics/index.js +21 -22
  196. package/dist/hooks/CustomerSupportHandoff/index.cjs +2 -2
  197. package/dist/hooks/CustomerSupportHandoff/index.js +2 -2
  198. package/dist/hooks/Debounce/index.cjs +20 -2
  199. package/dist/hooks/Debounce/index.js +18 -2
  200. package/dist/hooks/ElementObserver/index.cjs +3 -5
  201. package/dist/hooks/ElementObserver/index.d.cts +4 -25
  202. package/dist/hooks/ElementObserver/index.d.ts +4 -25
  203. package/dist/hooks/ElementObserver/index.js +3 -5
  204. package/dist/hooks/GrabAndScroll/index.cjs +1 -1
  205. package/dist/hooks/GrabAndScroll/index.js +1 -1
  206. package/dist/hooks/GraphQLConfig/index.cjs +9 -14
  207. package/dist/hooks/GraphQLConfig/index.d.cts +2 -13
  208. package/dist/hooks/GraphQLConfig/index.d.ts +2 -13
  209. package/dist/hooks/GraphQLConfig/index.js +9 -14
  210. package/dist/hooks/IdentifyUser/index.cjs +18 -18
  211. package/dist/hooks/IdentifyUser/index.js +18 -18
  212. package/dist/hooks/ImageResolver/index.cjs +20 -29
  213. package/dist/hooks/ImageResolver/index.js +20 -29
  214. package/dist/hooks/Intersection/index.cjs +1 -1
  215. package/dist/hooks/Intersection/index.js +1 -1
  216. package/dist/hooks/LocalStorageOperations/index.cjs +8 -7
  217. package/dist/hooks/LocalStorageOperations/index.js +4 -3
  218. package/dist/hooks/MessageFilter/index.cjs +3 -12
  219. package/dist/hooks/MessageFilter/index.d.cts +2 -17
  220. package/dist/hooks/MessageFilter/index.d.ts +2 -17
  221. package/dist/hooks/MessageFilter/index.js +2 -11
  222. package/dist/hooks/NewOrgConfig/index.cjs +14 -18
  223. package/dist/hooks/NewOrgConfig/index.d.cts +3 -16
  224. package/dist/hooks/NewOrgConfig/index.d.ts +3 -16
  225. package/dist/hooks/NewOrgConfig/index.js +14 -18
  226. package/dist/hooks/Search/index.cjs +331 -166
  227. package/dist/hooks/Search/index.d.cts +3 -57
  228. package/dist/hooks/Search/index.d.ts +3 -57
  229. package/dist/hooks/Search/index.js +319 -155
  230. package/dist/hooks/SearchOperations/index.cjs +24 -24
  231. package/dist/hooks/SearchOperations/index.d.cts +2 -3
  232. package/dist/hooks/SearchOperations/index.d.ts +2 -3
  233. package/dist/hooks/SearchOperations/index.js +24 -24
  234. package/dist/hooks/SessionStorageOperations/index.cjs +2 -2
  235. package/dist/hooks/SessionStorageOperations/index.js +2 -2
  236. package/dist/hooks/ShopifyUrlOperations/index.cjs +3 -3
  237. package/dist/hooks/ShopifyUrlOperations/index.d.cts +3 -5
  238. package/dist/hooks/ShopifyUrlOperations/index.d.ts +3 -5
  239. package/dist/hooks/ShopifyUrlOperations/index.js +3 -3
  240. package/dist/hooks/SnapCalculator/index.cjs +1 -1
  241. package/dist/hooks/SnapCalculator/index.d.cts +4 -3
  242. package/dist/hooks/SnapCalculator/index.d.ts +4 -3
  243. package/dist/hooks/SnapCalculator/index.js +1 -1
  244. package/dist/hooks/SystemSettingsContext/index.cjs +17 -6
  245. package/dist/hooks/SystemSettingsContext/index.d.cts +5 -15
  246. package/dist/hooks/SystemSettingsContext/index.d.ts +5 -15
  247. package/dist/hooks/SystemSettingsContext/index.js +15 -6
  248. package/dist/hooks/TrackComponentVisibleEvent/index.cjs +20 -20
  249. package/dist/hooks/TrackComponentVisibleEvent/index.d.cts +2 -3
  250. package/dist/hooks/TrackComponentVisibleEvent/index.d.ts +2 -3
  251. package/dist/hooks/TrackComponentVisibleEvent/index.js +20 -20
  252. package/dist/hooks/UpdateAnalyticsProps/index.cjs +20 -20
  253. package/dist/hooks/UpdateAnalyticsProps/index.js +19 -19
  254. package/dist/hooks/utils.cjs +1 -1
  255. package/dist/hooks/utils.d.cts +20 -13
  256. package/dist/hooks/utils.d.ts +20 -13
  257. package/dist/hooks/utils.js +1 -1
  258. package/dist/index-B4cSHxVN.d.ts +22 -0
  259. package/dist/{index-DzbkQtaK.d.cts → index-BQpWG3Jm.d.cts} +1 -1
  260. package/dist/index-BVZbvpx_.d.cts +11 -0
  261. package/dist/index-CEmUfoZa.d.ts +42 -0
  262. package/dist/index-CMZcE7pk.d.cts +224 -0
  263. package/dist/{index-DzzKdrcZ.d.ts → index-CYGpI6hE.d.ts} +1 -1
  264. package/dist/{index-9NE86em3.d.cts → index-ClVBVK15.d.cts} +1 -1
  265. package/dist/{index-Dy22w7kg.d.ts → index-Clf4wYaJ.d.ts} +1 -1
  266. package/dist/index-DeQte6mb.d.ts +11 -0
  267. package/dist/index-Dzv6WwSZ.d.ts +224 -0
  268. package/dist/index-ca7Qn8o0.d.cts +22 -0
  269. package/dist/{index-C1nwLU6Q.d.ts → index-dngXrfnT.d.ts} +1 -1
  270. package/dist/index-qOBU4GEh.d.cts +42 -0
  271. package/dist/{index-Da1s8h5C.d.cts → index-w64il54a.d.cts} +1 -1
  272. package/dist/interceptors/index.cjs +28 -3
  273. package/dist/interceptors/index.d.cts +4 -15
  274. package/dist/interceptors/index.d.ts +4 -15
  275. package/dist/interceptors/index.js +25 -3
  276. package/dist/localStorageContext-DSpmlfyr.js +90 -0
  277. package/dist/localStorageContext-DbWl7Row.cjs +104 -0
  278. package/dist/locators-BMQGmGLq.js +23 -0
  279. package/dist/locators-DxYdak1F.cjs +131 -0
  280. package/dist/{logger-Cp7J4YJT.cjs → logger-BF6iGSVd.cjs} +1 -1
  281. package/dist/{logger-oAgZx2-m.js → logger-DCs3_11o.js} +1 -1
  282. package/dist/models-158fyHt9.cjs +1305 -0
  283. package/dist/models-DEJUuKYQ.js +1118 -0
  284. package/dist/newOrgConfigAtom-BuQE_zPK.js +8 -0
  285. package/dist/{newOrgConfigAtom-B9FW3fDc.cjs → newOrgConfigAtom-rrYHmp1b.cjs} +1 -1
  286. package/dist/newOrgConfigContext-BVrzYatq.cjs +68 -0
  287. package/dist/newOrgConfigContext-C0LzIRJ7.js +53 -0
  288. package/dist/nodeSelector-CbWcUbuc.d.ts +28 -0
  289. package/dist/nodeSelector-Cj-Xl1LP.d.cts +28 -0
  290. package/dist/org-CVjyv-gv.cjs +111 -0
  291. package/dist/org-Ct9Vjv1J.js +32 -0
  292. package/dist/search-C0TAcTeY.cjs +312 -0
  293. package/dist/search-DLHzcbfP.js +233 -0
  294. package/dist/searchContext-Dmtue5QO.js +129 -0
  295. package/dist/searchContext-l_23fiuP.cjs +145 -0
  296. package/dist/searchServiceAdapter-B0h7psvh.js +16 -0
  297. package/dist/searchServiceAdapter-BclWy4fE.cjs +34 -0
  298. package/dist/sessionStorageContext-BOyr7mIM.cjs +66 -0
  299. package/dist/sessionStorageContext-ClXN9eX4.js +52 -0
  300. package/dist/shopifyUrlContext-G9eqIcsL.cjs +75 -0
  301. package/dist/shopifyUrlContext-WAm0pnPh.js +61 -0
  302. package/dist/src/application/commerce-api.js +406 -0
  303. package/dist/src/application/logging/logger.js +16 -0
  304. package/dist/src/application/models/graphql/index.js +3 -0
  305. package/dist/src/application/models/graphql/queries/getMerchantColorsQuery.js +13 -0
  306. package/dist/src/application/models/graphql/queries/getMerchantFrontendConfigQuery.js +13 -0
  307. package/dist/src/application/models/graphql/queries/getMerchantOrgIdQuery.js +10 -0
  308. package/dist/src/application/models/guards/api/index.js +12 -0
  309. package/dist/src/application/models/guards/api/isApiFormResponse.js +59 -0
  310. package/dist/src/application/models/guards/api/isApiFormSubmittedResponseAttributes.js +22 -0
  311. package/dist/src/application/models/guards/api/isApiOrderResponseAttributes.js +91 -0
  312. package/dist/src/application/models/guards/api/isApiOrgConfigResults.js +188 -0
  313. package/dist/src/application/models/guards/api/isApiOrganizationConfig.js +115 -0
  314. package/dist/src/application/models/guards/api/isApiPDPEventAttributes.js +16 -0
  315. package/dist/src/application/models/guards/api/isApiPLPEventAttributes.js +26 -0
  316. package/dist/src/application/models/guards/api/isApiPageResponseAttributes.js +15 -0
  317. package/dist/src/application/models/guards/api/isApiProductResponseAttributes.js +65 -0
  318. package/dist/src/application/models/guards/api/isApiProductSearchAttributes.js +15 -0
  319. package/dist/src/application/models/guards/api/isApiProductSearchFilterAttributes.js +10 -0
  320. package/dist/src/application/models/guards/api/isApiQueryTypedEventAttributes.js +4 -0
  321. package/dist/src/application/models/guards/api/isApiResponse.js +33 -0
  322. package/dist/src/application/models/guards/api/isApiReviewResponseAttributes.js +22 -0
  323. package/dist/src/application/models/guards/api/isApiReviewRichInformation.js +23 -0
  324. package/dist/src/application/models/guards/api/isApiSearchEventAttributes.js +20 -0
  325. package/dist/src/application/models/guards/api/isApiSuggestion.js +24 -0
  326. package/dist/src/application/models/guards/api/isApiSuggestionClickedEventAttributes.js +4 -0
  327. package/dist/src/application/models/guards/api/isApiTextResponseAttributes.js +4 -0
  328. package/dist/src/application/models/guards/api/isApiUserEvent.js +18 -0
  329. package/dist/src/application/models/guards/graphQL/isGraphQLColorsConfig.js +41 -0
  330. package/dist/src/application/models/guards/isBaseEcommerceEvent.js +14 -0
  331. package/dist/src/application/models/guards/isGA4EcommerceEvent.js +14 -0
  332. package/dist/src/application/models/guards/isLegacyUAEcommerceEvent.js +14 -0
  333. package/dist/src/application/models/guards/isMobilePLPChatPlacementParameter.js +4 -0
  334. package/dist/src/application/models/guards/isSpanxTakeAQuizCtaParameter.js +1 -0
  335. package/dist/src/application/models/guards/isVariantInfo.js +28 -0
  336. package/dist/src/application/models/guards/utils.js +34 -0
  337. package/dist/src/application/models/index.js +34 -0
  338. package/dist/src/application/models/utils/snakeToCamelTransformer.js +71 -0
  339. package/dist/src/application/models/utils/stringToFulfillmentDisplayStatusEnumValue.js +65 -0
  340. package/dist/src/application/models/validators/validateGraphQLColorsConfig.js +9 -0
  341. package/dist/src/application/models/validators/validateGraphQLFrontendConfig.js +420 -0
  342. package/dist/src/application/models/validators/validateGraphQLOrgId.js +6 -0
  343. package/dist/src/application/models/validators/validateMobilePLPChatPlacementParameter.js +9 -0
  344. package/dist/src/application/models/validators/validateOrgConfigResults.js +44 -0
  345. package/dist/src/application/models/validators/validateOrganizationConfig.js +34 -0
  346. package/dist/src/application/models/validators/validateResponse.js +173 -0
  347. package/dist/src/application/models/validators/validateSuggestion.js +13 -0
  348. package/dist/src/application/models/validators/validateUserEvent.js +91 -0
  349. package/dist/src/application/utils/analyticsUtils.js +94 -0
  350. package/dist/src/application/utils/coreContextToApiContext.js +8 -0
  351. package/dist/src/application/utils/coreUserEventToApiUserEvent.js +90 -0
  352. package/dist/src/application/utils/divideArray.js +7 -0
  353. package/dist/src/application/utils/domObserver.js +85 -0
  354. package/dist/src/application/utils/elementObserver.js +186 -0
  355. package/dist/src/application/utils/imageFilter.js +11 -0
  356. package/dist/src/application/utils/index.js +21 -0
  357. package/dist/src/application/utils/merchantUtils.js +15 -0
  358. package/dist/src/application/utils/messageFromFormSubmittedEvent.js +19 -0
  359. package/dist/src/application/utils/messageFromQueryEvent.js +35 -0
  360. package/dist/src/application/utils/messageFromResponse.js +123 -0
  361. package/dist/src/application/utils/messageFromSuggestionEvent.js +27 -0
  362. package/dist/src/application/utils/mouseEventTypes.js +1 -0
  363. package/dist/src/application/utils/mutationHelper.js +33 -0
  364. package/dist/src/application/utils/nextMessageRequestToApiRequest.js +29 -0
  365. package/dist/src/application/utils/nodeSelector.js +101 -0
  366. package/dist/src/application/utils/overrides.js +144 -0
  367. package/dist/src/application/utils/stringUtils.js +47 -0
  368. package/dist/src/application/utils/supportedEventRequestToApiRequest.js +7 -0
  369. package/dist/src/application/utils/urlsParser.js +33 -0
  370. package/dist/src/application/utils/validation.js +5 -0
  371. package/dist/src/atoms/amplitude/amplitudeTrackEventAtom.js +4 -0
  372. package/dist/src/atoms/app/index.js +23 -0
  373. package/dist/src/atoms/app/variant.js +102 -0
  374. package/dist/src/atoms/atomStore/atomStore.js +28 -0
  375. package/dist/src/atoms/atomStore/index.js +1 -0
  376. package/dist/src/atoms/chat/chatState.js +33 -0
  377. package/dist/src/atoms/chat/form.js +16 -0
  378. package/dist/src/atoms/chat/index.js +23 -0
  379. package/dist/src/atoms/chat/lastMessage.js +10 -0
  380. package/dist/src/atoms/chat/messageQueue.js +68 -0
  381. package/dist/src/atoms/chat/performanceMetrics.js +70 -0
  382. package/dist/src/atoms/chat/renderedWidgetRefs.js +24 -0
  383. package/dist/src/atoms/chat/replies.js +43 -0
  384. package/dist/src/atoms/chat/suggestions.js +29 -0
  385. package/dist/src/atoms/envive/enviveConfig.js +67 -0
  386. package/dist/src/atoms/globalSearch/globalSearch.js +8 -0
  387. package/dist/src/atoms/globalSearch/index.js +1 -0
  388. package/dist/src/atoms/org/customerService.js +6 -0
  389. package/dist/src/atoms/org/graphqlConfig.js +8 -0
  390. package/dist/src/atoms/org/index.js +4 -0
  391. package/dist/src/atoms/org/newOrgConfigAtom.js +2 -0
  392. package/dist/src/atoms/org/orgAnalyticsConfig.js +8 -0
  393. package/dist/src/atoms/search/index.js +1 -0
  394. package/dist/src/atoms/search/productFilters.js +163 -0
  395. package/dist/src/atoms/search/productRetrievalAPI.js +50 -0
  396. package/dist/src/atoms/search/productRetrievalAdapter.js +14 -0
  397. package/dist/src/atoms/search/productSorter.js +13 -0
  398. package/dist/src/atoms/search/searchAPI.js +140 -0
  399. package/dist/src/atoms/search/searchServiceAdapter.js +14 -0
  400. package/dist/src/atoms/search/utils.js +15 -0
  401. package/dist/src/config/index.js +1 -0
  402. package/dist/src/config/locators/components/chat/entrypoints.js +10 -0
  403. package/dist/src/config/locators/components/chat/index.js +21 -0
  404. package/dist/src/config/locators/components/chat/preview.js +11 -0
  405. package/dist/src/config/locators/components/chat/variants/index.js +12 -0
  406. package/dist/src/config/locators/components/common/buttons.js +6 -0
  407. package/dist/src/config/locators/components/common/cards.js +17 -0
  408. package/dist/src/config/locators/components/common/index.js +4 -0
  409. package/dist/src/config/locators/components/common/links.js +1 -0
  410. package/dist/src/config/locators/components/common/tables.js +1 -0
  411. package/dist/src/config/locators/components/floating-button.js +2 -0
  412. package/dist/src/config/locators/components/index.js +3 -0
  413. package/dist/src/config/locators/components/report-issue.js +13 -0
  414. package/dist/src/config/locators/components/search/index.js +5 -0
  415. package/dist/src/config/locators/components/shadow-dom.js +1 -0
  416. package/dist/src/config/locators/embedded.js +20 -0
  417. package/dist/src/config/locators/index.js +4 -0
  418. package/dist/src/contexts/amplitudeContext/amplitudeContext.js +292 -0
  419. package/dist/src/contexts/amplitudeContext/index.js +1 -0
  420. package/dist/src/contexts/cdnContext/cdnContext.js +28 -0
  421. package/dist/src/contexts/cdnContext/index.js +1 -0
  422. package/dist/src/contexts/enviveConfigContext/enviveConfigContext.js +37 -0
  423. package/dist/src/contexts/enviveConfigContext/index.js +1 -0
  424. package/dist/src/contexts/enviveCssContext/enviveCssContext.js +31 -0
  425. package/dist/src/contexts/enviveCssContext/index.js +1 -0
  426. package/dist/src/contexts/featureFlagContext/featureFlagContext.js +109 -0
  427. package/dist/src/contexts/featureFlagContext/index.js +1 -0
  428. package/dist/src/contexts/featureFlagServiceContext/featureFlagServiceContext.js +47 -0
  429. package/dist/src/contexts/featureFlagServiceContext/index.js +1 -0
  430. package/dist/src/contexts/graphqlContext/graphqlContext.js +87 -0
  431. package/dist/src/contexts/graphqlContext/index.js +1 -0
  432. package/dist/src/contexts/localStorageContext/index.js +1 -0
  433. package/dist/src/contexts/localStorageContext/localStorageContext.js +95 -0
  434. package/dist/src/contexts/newOrgConfigContext/index.js +1 -0
  435. package/dist/src/contexts/newOrgConfigContext/newOrgConfigContext.js +33 -0
  436. package/dist/src/contexts/searchContext/index.js +1 -0
  437. package/dist/src/contexts/searchContext/searchContext.js +131 -0
  438. package/dist/src/contexts/sessionStorageContext/index.js +1 -0
  439. package/dist/src/contexts/sessionStorageContext/sessionStorageContext.js +43 -0
  440. package/dist/src/contexts/shopifyUrlContext/index.js +1 -0
  441. package/dist/src/contexts/shopifyUrlContext/shopifyUrlContext.js +62 -0
  442. package/dist/src/contexts/systemSettingsContext/index.js +1 -0
  443. package/dist/src/contexts/systemSettingsContext/systemSettingsContext.js +29 -0
  444. package/dist/src/contexts/userIdentityContext/index.js +1 -0
  445. package/dist/src/contexts/userIdentityContext/userIdentityContext.js +118 -0
  446. package/dist/src/events/index.js +51 -0
  447. package/dist/src/events/registerAnalyticsListeners.js +32 -0
  448. package/dist/src/exceptions/index.js +2 -0
  449. package/dist/src/exceptions/sessionExceptions.js +6 -0
  450. package/dist/src/exceptions/unsupportedProductExceptions.js +6 -0
  451. package/dist/src/hooks/AmplitudeOperations/index.js +1 -0
  452. package/dist/src/hooks/AmplitudeOperations/useAmplitudeOperations.js +24 -0
  453. package/dist/src/hooks/AppDetails/index.js +1 -0
  454. package/dist/src/hooks/AppDetails/useAppDetails.js +26 -0
  455. package/dist/src/hooks/BlockBackButton/index.js +1 -0
  456. package/dist/src/hooks/BlockBackButton/useBlockBackButton.js +23 -0
  457. package/dist/src/hooks/CdnOperations/index.js +1 -0
  458. package/dist/src/hooks/CdnOperations/useCdnOperations.js +13 -0
  459. package/dist/src/hooks/ChatToggle/index.js +1 -0
  460. package/dist/src/hooks/ChatToggle/useChatToggle.js +50 -0
  461. package/dist/src/hooks/ChatToggleAnalytics/index.js +1 -0
  462. package/dist/src/hooks/ChatToggleAnalytics/useChatToggleAnalytics.js +11 -0
  463. package/dist/src/hooks/CustomerSupportHandoff/index.js +1 -0
  464. package/dist/src/hooks/CustomerSupportHandoff/useCustomerSupportHandoff.js +32 -0
  465. package/dist/src/hooks/Debounce/index.js +1 -0
  466. package/dist/src/hooks/Debounce/useDebounce.js +13 -0
  467. package/dist/src/hooks/ElementObserver/index.js +1 -0
  468. package/dist/src/hooks/ElementObserver/useElementObserver.js +208 -0
  469. package/dist/src/hooks/GrabAndScroll/index.js +1 -0
  470. package/dist/src/hooks/GrabAndScroll/useGrabAndScroll.js +105 -0
  471. package/dist/src/hooks/GraphQLConfig/index.js +1 -0
  472. package/dist/src/hooks/GraphQLConfig/useGraphQLConfig.js +54 -0
  473. package/dist/src/hooks/IdentifyUser/index.js +1 -0
  474. package/dist/src/hooks/IdentifyUser/useIdentifyUser.js +28 -0
  475. package/dist/src/hooks/ImageResolver/index.js +1 -0
  476. package/dist/src/hooks/ImageResolver/useImageResolver.js +45 -0
  477. package/dist/src/hooks/Intersection/index.js +1 -0
  478. package/dist/src/hooks/Intersection/useIntersection.js +20 -0
  479. package/dist/src/hooks/IsSmallScreen/index.js +1 -0
  480. package/dist/src/hooks/IsSmallScreen/useIsSmallScreen.js +16 -0
  481. package/dist/src/hooks/LocalStorageOperations/index.js +1 -0
  482. package/dist/src/hooks/LocalStorageOperations/useLocalStorageOperations.js +64 -0
  483. package/dist/src/hooks/MessageFilter/index.js +1 -0
  484. package/dist/src/hooks/MessageFilter/useMessageFilter.js +37 -0
  485. package/dist/src/hooks/MessageScrollObserver/index.js +1 -0
  486. package/dist/src/hooks/MessageScrollObserver/useMessageScrollObserver.js +35 -0
  487. package/dist/src/hooks/NewOrgConfig/index.js +1 -0
  488. package/dist/src/hooks/NewOrgConfig/useNewOrgConfig.js +5 -0
  489. package/dist/src/hooks/Search/index.js +1 -0
  490. package/dist/src/hooks/Search/useRecommendedProducts.js +35 -0
  491. package/dist/src/hooks/Search/useSearch.js +224 -0
  492. package/dist/src/hooks/Search/useSearchInput.js +183 -0
  493. package/dist/src/hooks/SearchOperations/index.js +1 -0
  494. package/dist/src/hooks/SearchOperations/useSearchOperations.js +78 -0
  495. package/dist/src/hooks/SessionStorageOperations/index.js +1 -0
  496. package/dist/src/hooks/SessionStorageOperations/useSessionStorageOperations.js +20 -0
  497. package/dist/src/hooks/ShopifyUrlOperations/index.js +1 -0
  498. package/dist/src/hooks/ShopifyUrlOperations/useShopifyUrlOperations.js +34 -0
  499. package/dist/src/hooks/SnapCalculator/index.js +1 -0
  500. package/dist/src/hooks/SnapCalculator/useSnapCalculator.js +22 -0
  501. package/dist/src/hooks/SystemSettingsContext/index.js +1 -0
  502. package/dist/src/hooks/SystemSettingsContext/useSystemSettingsContext.js +9 -0
  503. package/dist/src/hooks/TrackComponentVisibleEvent/index.js +1 -0
  504. package/dist/src/hooks/TrackComponentVisibleEvent/useTrackComponentVisibleEvent.js +45 -0
  505. package/dist/src/hooks/UpdateAnalyticsProps/index.js +1 -0
  506. package/dist/src/hooks/UpdateAnalyticsProps/useUpdateAnalyticsProps.js +43 -0
  507. package/dist/src/hooks/utils.js +116 -0
  508. package/dist/src/interceptors/index.js +1 -0
  509. package/dist/src/interceptors/useMessageInterceptor.js +24 -0
  510. package/dist/src/types/ApiResponse.js +1 -0
  511. package/dist/src/types/FilterAttribute.js +3 -0
  512. package/dist/src/types/Message.js +24 -0
  513. package/dist/src/types/Suggestion.js +3 -0
  514. package/dist/src/types/index.js +4 -0
  515. package/dist/src/util/colorVar.js +3 -0
  516. package/dist/src/util/configVersion.js +4 -0
  517. package/dist/src/util/domInsertion.js +16 -0
  518. package/dist/systemSettingsContext-Cb5kczBD.cjs +60 -0
  519. package/dist/systemSettingsContext-CksCdpiU.js +39 -0
  520. package/dist/types/index.cjs +3 -33
  521. package/dist/types/index.d.cts +2 -3
  522. package/dist/types/index.d.ts +2 -3
  523. package/dist/types/index.js +2 -30
  524. package/dist/types-18QXD2rd.cjs +39 -0
  525. package/dist/types-DQC1pHqD.js +27 -0
  526. package/dist/urlsParser-C-Vzs--G.cjs +78 -0
  527. package/dist/urlsParser-G7Ocwg0M.js +42 -0
  528. package/dist/useAppDetails-BJFRSYbI.js +30 -0
  529. package/dist/useAppDetails-Czn-5FzP.cjs +38 -0
  530. package/dist/useGraphQLConfig-BEtX5pDM.cjs +76 -0
  531. package/dist/useGraphQLConfig-Dkcrz1YL.js +63 -0
  532. package/dist/{useIntersection-UEO0Cezc.js → useIntersection-BWiHkpKL.js} +1 -1
  533. package/dist/{useIntersection-rV0Q8mBH.cjs → useIntersection-DZHz44BY.cjs} +1 -1
  534. package/dist/{utils-ARmpTh1O.js → utils-CEKzBcN2.js} +1 -1
  535. package/dist/utils-CPvqOk0g.cjs +1546 -0
  536. package/dist/{utils-Cavu4XiM.cjs → utils-CsMbZmRw.cjs} +1 -1
  537. package/dist/utils-D_kATUj6.js +92 -0
  538. package/dist/utils-N47VsL9W.js +1364 -0
  539. package/dist/utils-hYTjy7hJ.cjs +130 -0
  540. package/dist/{utils-BLe5oreh.d.ts → utils-wWki3L1d.d.ts} +1 -1
  541. package/package.json +15 -25
  542. package/src/application/commerce-api.ts +38 -37
  543. package/src/application/models/graphql/index.ts +1 -0
  544. package/src/application/models/graphql/queries/getMerchantColorsQuery.ts +1 -23
  545. package/src/application/models/graphql/queries/getMerchantFrontendConfigQuery.ts +1 -89
  546. package/src/application/models/guards/api/isApiFormResponse.ts +4 -4
  547. package/src/application/models/guards/api/isApiFormSubmittedResponseAttributes.ts +2 -2
  548. package/src/application/models/guards/api/isApiOrderResponseAttributes.ts +2 -20
  549. package/src/application/models/guards/api/isApiOrgConfigResults.ts +3 -9
  550. package/src/application/models/guards/api/isApiOrganizationConfig.ts +8 -32
  551. package/src/application/models/guards/api/isApiPDPEventAttributes.ts +8 -5
  552. package/src/application/models/guards/api/isApiPLPEventAttributes.ts +14 -10
  553. package/src/application/models/guards/api/isApiPageResponseAttributes.ts +1 -1
  554. package/src/application/models/guards/api/isApiProductResponseAttributes.ts +2 -4
  555. package/src/application/models/guards/api/isApiProductSearchAttributes.ts +9 -6
  556. package/src/application/models/guards/api/isApiProductSearchFilterAttributes.ts +7 -4
  557. package/src/application/models/guards/api/isApiQueryTypedEventAttributes.ts +8 -3
  558. package/src/application/models/guards/api/isApiResponse.ts +22 -15
  559. package/src/application/models/guards/api/isApiReviewResponseAttributes.ts +1 -1
  560. package/src/application/models/guards/api/isApiReviewRichInformation.ts +1 -1
  561. package/src/application/models/guards/api/isApiTextResponseAttributes.ts +1 -1
  562. package/src/application/models/guards/graphQL/isGraphQLColorsConfig.ts +1 -1
  563. package/src/application/models/guards/isBaseEcommerceEvent.ts +1 -2
  564. package/src/application/models/guards/isGA4EcommerceEvent.ts +1 -1
  565. package/src/application/models/guards/isLegacyUAEcommerceEvent.ts +1 -1
  566. package/src/application/models/guards/isMobilePLPChatPlacementParameter.ts +1 -3
  567. package/src/application/models/guards/isSpanxTakeAQuizCtaParameter.ts +5 -3
  568. package/src/application/models/guards/isVariantInfo.ts +6 -1
  569. package/src/application/models/index.ts +30 -95
  570. package/src/application/models/utils/snakeToCamelTransformer.ts +8 -8
  571. package/src/application/models/validators/validateGraphQLColorsConfig.ts +6 -2
  572. package/src/application/models/validators/validateGraphQLFrontendConfig.ts +6 -6
  573. package/src/application/models/validators/validateMobilePLPChatPlacementParameter.ts +5 -3
  574. package/src/application/models/validators/validateOrgConfigResults.ts +6 -5
  575. package/src/application/models/validators/validateOrganizationConfig.ts +11 -8
  576. package/src/application/models/validators/validateResponse.ts +66 -44
  577. package/src/application/models/validators/validateSuggestion.ts +1 -1
  578. package/src/application/models/validators/validateUserEvent.ts +23 -12
  579. package/src/application/utils/analyticsUtils.ts +16 -38
  580. package/src/application/utils/coreContextToApiContext.ts +3 -1
  581. package/src/application/utils/coreUserEventToApiUserEvent.ts +2 -2
  582. package/src/application/utils/elementObserver.ts +1 -1
  583. package/src/application/utils/imageFilter.ts +5 -2
  584. package/src/application/utils/index.ts +20 -21
  585. package/src/application/utils/messageFromFormSubmittedEvent.ts +1 -1
  586. package/src/application/utils/messageFromQueryEvent.ts +1 -1
  587. package/src/application/utils/messageFromResponse.ts +14 -10
  588. package/src/application/utils/messageFromSuggestionEvent.ts +6 -4
  589. package/src/application/utils/mouseEventTypes.ts +1 -1
  590. package/src/application/utils/nextMessageRequestToApiRequest.ts +1 -1
  591. package/src/application/utils/overrides.ts +1 -49
  592. package/src/application/utils/supportedEventRequestToApiRequest.ts +3 -1
  593. package/src/application/utils/urlsParser.ts +1 -7
  594. package/src/atoms/app/index.ts +15 -25
  595. package/src/atoms/app/variant.ts +1 -1
  596. package/src/atoms/chat/chatState.ts +9 -14
  597. package/src/atoms/chat/form.ts +1 -1
  598. package/src/atoms/chat/messageQueue.ts +25 -50
  599. package/src/atoms/chat/replies.ts +40 -43
  600. package/src/atoms/chat/suggestions.ts +34 -29
  601. package/src/atoms/envive/enviveConfig.ts +14 -20
  602. package/src/atoms/org/customerService.ts +4 -8
  603. package/src/atoms/org/graphqlConfig.ts +7 -15
  604. package/src/atoms/org/index.ts +4 -6
  605. package/src/atoms/org/newOrgConfigAtom.ts +2 -2
  606. package/src/atoms/org/orgAnalyticsConfig.ts +1 -1
  607. package/src/atoms/search/index.ts +0 -1
  608. package/src/atoms/search/productFilters.ts +72 -52
  609. package/src/atoms/search/productRetrievalAPI.ts +72 -0
  610. package/src/atoms/search/productRetrievalAdapter.ts +28 -0
  611. package/src/atoms/search/productSorter.ts +2 -2
  612. package/src/atoms/search/searchAPI.ts +42 -60
  613. package/src/atoms/search/searchServiceAdapter.ts +1 -1
  614. package/src/config/index.ts +1 -0
  615. package/src/contexts/amplitudeContext/amplitudeContext.tsx +104 -143
  616. package/src/contexts/cdnContext/cdnContext.tsx +9 -16
  617. package/src/contexts/enviveConfigContext/enviveConfigContext.tsx +6 -27
  618. package/src/contexts/enviveCssContext/enviveCssContext.tsx +5 -12
  619. package/src/contexts/featureFlagContext/featureFlagContext.tsx +27 -48
  620. package/src/contexts/featureFlagServiceContext/featureFlagServiceContext.tsx +11 -3
  621. package/src/contexts/graphqlContext/graphqlContext.tsx +40 -95
  622. package/src/contexts/localStorageContext/localStorageContext.tsx +26 -60
  623. package/src/contexts/newOrgConfigContext/newOrgConfigContext.tsx +10 -22
  624. package/src/contexts/searchContext/searchContext.tsx +29 -49
  625. package/src/contexts/sessionStorageContext/sessionStorageContext.tsx +12 -33
  626. package/src/contexts/shopifyUrlContext/shopifyUrlContext.tsx +20 -37
  627. package/src/contexts/systemSettingsContext/systemSettingsContext.tsx +8 -21
  628. package/src/contexts/userIdentityContext/userIdentityContext.tsx +33 -77
  629. package/src/events/index.ts +8 -5
  630. package/src/events/registerAnalyticsListeners.ts +10 -13
  631. package/src/exceptions/index.ts +2 -0
  632. package/src/{types/exceptions → exceptions}/unsupportedProductExceptions.ts +2 -2
  633. package/src/global.d.ts +8 -0
  634. package/src/hooks/AmplitudeOperations/useAmplitudeOperations.ts +6 -11
  635. package/src/hooks/AppDetails/useAppDetails.ts +10 -24
  636. package/src/hooks/ChatToggle/useChatToggle.ts +7 -19
  637. package/src/hooks/ChatToggleAnalytics/useChatToggleAnalytics.ts +4 -4
  638. package/src/hooks/CustomerSupportHandoff/useCustomerSupportHandoff.ts +1 -1
  639. package/src/hooks/ElementObserver/useElementObserver.ts +14 -32
  640. package/src/hooks/GrabAndScroll/useGrabAndScroll.ts +125 -124
  641. package/src/hooks/GraphQLConfig/useGraphQLConfig.ts +5 -7
  642. package/src/hooks/ImageResolver/useImageResolver.ts +24 -31
  643. package/src/hooks/LocalStorageOperations/useLocalStorageOperations.ts +12 -19
  644. package/src/hooks/MessageFilter/useMessageFilter.ts +1 -7
  645. package/src/hooks/Search/useRecommendedProducts.ts +50 -0
  646. package/src/hooks/Search/useSearch.tsx +80 -210
  647. package/src/hooks/Search/useSearchInput.ts +227 -0
  648. package/src/hooks/SearchOperations/useSearchOperations.ts +8 -12
  649. package/src/hooks/ShopifyUrlOperations/useShopifyUrlOperations.ts +8 -14
  650. package/src/hooks/SnapCalculator/useSnapCalculator.ts +1 -2
  651. package/src/hooks/TrackComponentVisibleEvent/useTrackComponentVisibleEvent.ts +8 -11
  652. package/src/hooks/UpdateAnalyticsProps/useUpdateAnalyticsProps.ts +11 -25
  653. package/src/hooks/utils.ts +19 -29
  654. package/src/interceptors/index.ts +1 -2
  655. package/src/interceptors/useMessageInterceptor.ts +10 -6
  656. package/src/{application/models/api/response.ts → types/ApiResponse.ts} +35 -29
  657. package/src/types/FilterAttribute.ts +35 -0
  658. package/src/{application/models/message.ts → types/Message.ts} +38 -34
  659. package/src/types/Suggestion.ts +6 -0
  660. package/src/types/index.ts +4 -4
  661. package/src/util/colorVar.ts +4 -0
  662. package/src/util/configVersion.ts +4 -0
  663. package/src/util/domInsertion.ts +17 -0
  664. package/dist/SystemSettingsContext-CCuS3kWH.js +0 -13
  665. package/dist/SystemSettingsContext-Dh_35fES.cjs +0 -20
  666. package/dist/TrackComponentVisibleEvent-B828giM-.js +0 -52
  667. package/dist/TrackComponentVisibleEvent-DsTIH7Yt.cjs +0 -59
  668. package/dist/amplitudeContext-B73xamNe.d.cts +0 -52
  669. package/dist/amplitudeContext-BfRDG5CX.d.ts +0 -52
  670. package/dist/api-Bc3_julZ.cjs +0 -239
  671. package/dist/api-D9gmGNAV.js +0 -166
  672. package/dist/application/models/utilityTypes/index.cjs +0 -1
  673. package/dist/application/models/utilityTypes/index.d.cts +0 -2
  674. package/dist/application/models/utilityTypes/index.d.ts +0 -2
  675. package/dist/application/models/utilityTypes/index.js +0 -3
  676. package/dist/application/models/variantInfo/index.cjs +0 -3
  677. package/dist/application/models/variantInfo/index.d.cts +0 -2
  678. package/dist/application/models/variantInfo/index.d.ts +0 -2
  679. package/dist/application/models/variantInfo/index.js +0 -3
  680. package/dist/atoms/search/types.cjs +0 -5
  681. package/dist/atoms/search/types.d.cts +0 -2
  682. package/dist/atoms/search/types.d.ts +0 -2
  683. package/dist/atoms/search/types.js +0 -3
  684. package/dist/cdnContext-BlRI74F-.cjs +0 -53
  685. package/dist/cdnContext-D26C8Y4H.js +0 -38
  686. package/dist/chat-2NGrmU_Z.cjs +0 -393
  687. package/dist/chat-Bg3wEfNd.js +0 -257
  688. package/dist/chatElementDisplayLocation-D6oLuQS4.d.ts +0 -25
  689. package/dist/chatElementDisplayLocation-DWmfNX_u.d.cts +0 -25
  690. package/dist/chatSearch-B4dsxGth.cjs +0 -418
  691. package/dist/chatSearch-Cvc_eBFV.js +0 -295
  692. package/dist/chatState-2bMtvPgG.js +0 -34
  693. package/dist/chatState-fP1r34CN.cjs +0 -120
  694. package/dist/contexts/chatContext/index.cjs +0 -326
  695. package/dist/contexts/chatContext/index.d.cts +0 -15
  696. package/dist/contexts/chatContext/index.d.ts +0 -15
  697. package/dist/contexts/chatContext/index.js +0 -319
  698. package/dist/contexts/types.cjs +0 -7
  699. package/dist/contexts/types.d.cts +0 -4
  700. package/dist/contexts/types.d.ts +0 -4
  701. package/dist/contexts/types.js +0 -3
  702. package/dist/enviveConfig-BSfyz_pm.js +0 -62
  703. package/dist/enviveConfig-D8vcVPWD.cjs +0 -130
  704. package/dist/enviveConfigContext-C8cCcdKU.cjs +0 -60
  705. package/dist/enviveConfigContext-CJqpRSKu.js +0 -45
  706. package/dist/events-BHJJjPDN.js +0 -78
  707. package/dist/events-B_fJZf9E.cjs +0 -90
  708. package/dist/featureFlagServiceContext-C2Yj-Uyh.d.ts +0 -23
  709. package/dist/featureFlagServiceContext-CiKWV306.d.cts +0 -23
  710. package/dist/featureFlagServiceContext-DFb-uLHN.cjs +0 -62
  711. package/dist/featureFlagServiceContext-Dd_Hbq6e.js +0 -42
  712. package/dist/featureGates-BdvOVv8N.cjs +0 -32
  713. package/dist/featureGates-DhoJq4io.js +0 -26
  714. package/dist/frontendConfig-CbyjUXZW.d.ts +0 -856
  715. package/dist/frontendConfig-tVg0hsWZ.d.cts +0 -856
  716. package/dist/graphql-B9HhDXYt.cjs +0 -53
  717. package/dist/graphql-W7GMIHUu.js +0 -36
  718. package/dist/graphqlConfig-DZHeFKDY.cjs +0 -73
  719. package/dist/graphqlConfig-Xk--JbPl.js +0 -24
  720. package/dist/graphqlContext-BotK7KCg.d.ts +0 -28
  721. package/dist/graphqlContext-CMav2igl.d.cts +0 -28
  722. package/dist/graphqlContext-CSVwhCnP.js +0 -96
  723. package/dist/graphqlContext-aaOOb79d.cjs +0 -111
  724. package/dist/index-7VOYQNo5.d.ts +0 -184
  725. package/dist/index-Bmub8e38.d.cts +0 -98
  726. package/dist/index-CESxqFso.d.cts +0 -228
  727. package/dist/index-CG3P8xE1.d.cts +0 -676
  728. package/dist/index-CalyvQj_.d.ts +0 -1
  729. package/dist/index-CiWEYzXl.d.cts +0 -184
  730. package/dist/index-Cyq5HiC0.d.cts +0 -44
  731. package/dist/index-D9SzePCE.d.cts +0 -186
  732. package/dist/index-DDZmV951.d.ts +0 -186
  733. package/dist/index-L7SEpDLz.d.ts +0 -228
  734. package/dist/index-RcVcRKH7.d.cts +0 -1
  735. package/dist/index-YrhxAGtH.d.ts +0 -676
  736. package/dist/index-exSzn3SP.d.ts +0 -44
  737. package/dist/index-hebsV7fc.d.ts +0 -98
  738. package/dist/interceptors/types.cjs +0 -1
  739. package/dist/interceptors/types.d.cts +0 -13
  740. package/dist/interceptors/types.d.ts +0 -13
  741. package/dist/interceptors/types.js +0 -3
  742. package/dist/localStorageContext-Dwgto93_.js +0 -95
  743. package/dist/localStorageContext-cnMYDllE.cjs +0 -115
  744. package/dist/models-B1P-dSCW.cjs +0 -1537
  745. package/dist/models-CgvSM2fW.js +0 -1296
  746. package/dist/newOrgConfigAtom-CMeY5c6t.js +0 -8
  747. package/dist/newOrgConfigContext-1uwWWCPa.js +0 -53
  748. package/dist/newOrgConfigContext-B0v1q3dk.cjs +0 -68
  749. package/dist/newOrgConfigContext-C8wBmK3q.d.cts +0 -16
  750. package/dist/newOrgConfigContext-D180PO0t.d.ts +0 -16
  751. package/dist/nodeSelector-B3bPtEjX.d.cts +0 -31
  752. package/dist/nodeSelector-DQicm08Y.d.ts +0 -31
  753. package/dist/org-DU3Wck0R.cjs +0 -43
  754. package/dist/org-DptftvB6.js +0 -12
  755. package/dist/search-BtYKpiNB.js +0 -126
  756. package/dist/search-DYVQuYti.d.ts +0 -20
  757. package/dist/search-Du6HZpO6.cjs +0 -205
  758. package/dist/search-filter-types-B5xcaEit.d.ts +0 -102
  759. package/dist/search-filter-types-DZPTzUK9.d.cts +0 -102
  760. package/dist/search-y-ioX5Mz.d.cts +0 -20
  761. package/dist/searchContext-BK43ArCs.cjs +0 -145
  762. package/dist/searchContext-JjZZhDCe.js +0 -129
  763. package/dist/searchServiceAdapter-BSPZOg1r.js +0 -16
  764. package/dist/searchServiceAdapter-DrjFCiw8.cjs +0 -34
  765. package/dist/sessionStorageContext-BQY9r8zz.js +0 -52
  766. package/dist/sessionStorageContext-R2yUAkd9.cjs +0 -66
  767. package/dist/shopifyUrlContext-Bon8_SUJ.js +0 -61
  768. package/dist/shopifyUrlContext-DUdw1xUH.cjs +0 -75
  769. package/dist/spiffyWidgets-BuS00VaQ.d.cts +0 -20
  770. package/dist/spiffyWidgets-DZqG5plz.d.ts +0 -20
  771. package/dist/systemSettingsContext-BjbhIz6y.js +0 -39
  772. package/dist/systemSettingsContext-Dv9EmjmZ.cjs +0 -60
  773. package/dist/test-types-Dl5puRHC.d.ts +0 -40
  774. package/dist/test-types-ThQiO_cc.d.cts +0 -40
  775. package/dist/types-BwNrLPSZ.cjs +0 -106
  776. package/dist/types-CKMMb_gX.d.cts +0 -51
  777. package/dist/types-Csgpt7EV.d.ts +0 -51
  778. package/dist/types-D3uOF0Oy.js +0 -76
  779. package/dist/types-DIk0FLwd.js +0 -30
  780. package/dist/types-DNLkuGWZ.cjs +0 -48
  781. package/dist/types-DSW9XODe.d.cts +0 -10
  782. package/dist/types-DtTnp0o0.js +0 -1
  783. package/dist/types-a8gm_IaQ.cjs +0 -0
  784. package/dist/types-oSg-AkO5.d.ts +0 -10
  785. package/dist/types.cjs +0 -0
  786. package/dist/types.d.cts +0 -15
  787. package/dist/types.d.ts +0 -15
  788. package/dist/types.js +0 -1
  789. package/dist/urlsParser-BV5yF8sa.cjs +0 -78
  790. package/dist/urlsParser-DUgV_Qy9.js +0 -42
  791. package/dist/useAmplitudeOperations-C9o_wDU6.cjs +0 -41
  792. package/dist/useAmplitudeOperations-COq3L1no.js +0 -34
  793. package/dist/useAppDetails-C4GTLEIR.cjs +0 -38
  794. package/dist/useAppDetails-CEksA88Q.js +0 -30
  795. package/dist/useDebounce--rPGMuE7.js +0 -19
  796. package/dist/useDebounce-DECHWSTn.cjs +0 -26
  797. package/dist/useGraphQLConfig-DQoMmpNM.js +0 -63
  798. package/dist/useGraphQLConfig-DzH1nVBh.cjs +0 -76
  799. package/dist/useMessageInterceptor-CstX10ih.cjs +0 -33
  800. package/dist/useMessageInterceptor-D5oAekXn.js +0 -25
  801. package/dist/userIdentityContext-8kfKQRFx.d.ts +0 -20
  802. package/dist/userIdentityContext-D2oFVFzo.d.cts +0 -20
  803. package/dist/utilityTypes-DynzxjK3.js +0 -1
  804. package/dist/utilityTypes-xb8SjKSV.cjs +0 -0
  805. package/dist/utils-B8rATLoc.d.ts +0 -22
  806. package/dist/utils-Bcz5kAgP.js +0 -92
  807. package/dist/utils-CMqFfqZx.cjs +0 -130
  808. package/dist/utils-EDgzCG3Q.d.cts +0 -22
  809. package/dist/utils-V1YTUQng.js +0 -1385
  810. package/dist/utils-VI19AC8S.cjs +0 -1591
  811. package/dist/variantInfo-BRmDpamJ.cjs +0 -17
  812. package/dist/variantInfo-BwBBEWSA.js +0 -11
  813. package/src/application/models/api/context.ts +0 -4
  814. package/src/application/models/api/generationParams.ts +0 -4
  815. package/src/application/models/api/nextMessageRequest.ts +0 -11
  816. package/src/application/models/api/orgAnalyticsConfig.ts +0 -19
  817. package/src/application/models/api/orgConfigResults.ts +0 -44
  818. package/src/application/models/api/organizationConfig.ts +0 -12
  819. package/src/application/models/api/responseGenerics.ts +0 -67
  820. package/src/application/models/api/search.ts +0 -26
  821. package/src/application/models/api/suggestion.ts +0 -4
  822. package/src/application/models/api/supportedEventRequest.ts +0 -8
  823. package/src/application/models/api/userEvent.ts +0 -101
  824. package/src/application/models/cachedValue.ts +0 -8
  825. package/src/application/models/chatElementDisplayLocation.ts +0 -22
  826. package/src/application/models/clientDetails.ts +0 -18
  827. package/src/application/models/colorsConfig.ts +0 -28
  828. package/src/application/models/conversationalSearchIds.ts +0 -5
  829. package/src/application/models/dataLayer.ts +0 -45
  830. package/src/application/models/events.ts +0 -5
  831. package/src/application/models/featureGates.ts +0 -21
  832. package/src/application/models/frontendConfig.ts +0 -14
  833. package/src/application/models/googleAnalyticsEvents.ts +0 -8
  834. package/src/application/models/localStorageEventListener.ts +0 -4
  835. package/src/application/models/mobilePLPChatPlacementParameter.ts +0 -3
  836. package/src/application/models/orgsEnum.ts +0 -36
  837. package/src/application/models/productExperiment.ts +0 -5
  838. package/src/application/models/spanxTakeAQuizCtaParameter.ts +0 -4
  839. package/src/application/models/spiffyWidgets.ts +0 -16
  840. package/src/application/models/utilityTypes/camelCase.ts +0 -87
  841. package/src/application/models/utilityTypes/camelCasedPropertiesDeep.ts +0 -80
  842. package/src/application/models/utilityTypes/delimiterCase.ts +0 -121
  843. package/src/application/models/utilityTypes/delimiterCasedPropertiesDeep.ts +0 -98
  844. package/src/application/models/utilityTypes/index.ts +0 -1
  845. package/src/application/models/utilityTypes/internal.ts +0 -93
  846. package/src/application/models/utilityTypes/primitive.ts +0 -8
  847. package/src/application/models/utilityTypes/snakeCasedPropertiesDeep.ts +0 -49
  848. package/src/application/models/utilityTypes/splitWords.ts +0 -76
  849. package/src/application/models/utilityTypes/trim.ts +0 -28
  850. package/src/application/models/utilityTypes/unknownArray.ts +0 -25
  851. package/src/application/models/variantInfo/index.ts +0 -1
  852. package/src/application/models/variantInfo/pageVisitInfo.ts +0 -6
  853. package/src/application/models/variantInfo/plpInfo.ts +0 -3
  854. package/src/application/models/variantInfo/productInfo.ts +0 -5
  855. package/src/application/models/variantInfo/variantInfo.ts +0 -29
  856. package/src/application/utils/__tests__/divideArrays.test.ts +0 -14
  857. package/src/application/utils/cdnUtils.ts +0 -11
  858. package/src/atoms/search/chatSearch.ts +0 -317
  859. package/src/atoms/search/types.ts +0 -55
  860. package/src/config/divIds.ts +0 -27
  861. package/src/config/socialProofClasses.ts +0 -17
  862. package/src/contexts/chatContext/chatContext.tsx +0 -509
  863. package/src/contexts/chatContext/index.ts +0 -1
  864. package/src/contexts/types.ts +0 -1066
  865. package/src/events/event-types.ts +0 -11
  866. package/src/interceptors/types.ts +0 -6
  867. package/src/merchants/domInsertion.ts +0 -30
  868. package/src/merchants/gridInsertion.ts +0 -19
  869. package/src/types/config-versions.ts +0 -6
  870. package/src/types/customerService.ts +0 -31
  871. package/src/types/custservice-types.ts +0 -28
  872. package/src/types/search-filter-types.ts +0 -111
  873. package/src/types/suggestionBarV2-types.ts +0 -4
  874. package/src/types/test-types.ts +0 -3
  875. package/src/types.ts +0 -11
  876. /package/dist/{AmplitudeOperations-CEwp7tPJ.cjs → featureFlagServiceContext-B4ash4vz.cjs} +0 -0
  877. /package/dist/{AmplitudeOperations-uF2zIi_1.js → featureFlagServiceContext-bI7ZLz4r.js} +0 -0
  878. /package/src/{types/exceptions → exceptions}/sessionExceptions.ts +0 -0
@@ -0,0 +1,1546 @@
1
+ const require_chunk = require('./chunk-CUT6urMc.cjs');
2
+ const require_events = require('./events-CgFGtanE.cjs');
3
+ const require_dist = require('./dist-BZX_Mgfn.cjs');
4
+ const require_exceptions = require('./exceptions-BiSWJEl2.cjs');
5
+ const require_models = require('./models-158fyHt9.cjs');
6
+ const require_logger = require('./logger-BF6iGSVd.cjs');
7
+ const require_enviveConfig = require('./enviveConfig-DaotBKMS.cjs');
8
+ const require_localStorageContext = require('./localStorageContext-DbWl7Row.cjs');
9
+ const require_org = require('./org-CVjyv-gv.cjs');
10
+ const require_atomStore = require('./atomStore-DD9g7Zw2.cjs');
11
+ const require_enviveConfigContext = require('./enviveConfigContext--89ejDs5.cjs');
12
+ const require_featureFlagServiceContext = require('./featureFlagServiceContext-BztKnBPk.cjs');
13
+ const require_types = require('./types-18QXD2rd.cjs');
14
+ let __spiffy_ai_commerce_api_client = require("@spiffy-ai/commerce-api-client");
15
+ __spiffy_ai_commerce_api_client = require_chunk.__toESM(__spiffy_ai_commerce_api_client);
16
+ let react = require("react");
17
+ react = require_chunk.__toESM(react);
18
+ let uuid = require("uuid");
19
+ uuid = require_chunk.__toESM(uuid);
20
+ let jotai = require("jotai");
21
+ jotai = require_chunk.__toESM(jotai);
22
+ let __amplitude_analytics_browser = require("@amplitude/analytics-browser");
23
+ __amplitude_analytics_browser = require_chunk.__toESM(__amplitude_analytics_browser);
24
+ let react_jsx_runtime = require("react/jsx-runtime");
25
+ react_jsx_runtime = require_chunk.__toESM(react_jsx_runtime);
26
+ let jotai_utils = require("jotai/utils");
27
+ jotai_utils = require_chunk.__toESM(jotai_utils);
28
+ let ua_parser_js = require("ua-parser-js");
29
+ ua_parser_js = require_chunk.__toESM(ua_parser_js);
30
+
31
+ //#region src/application/commerce-api.ts
32
+ async function errorResponseBody(error) {
33
+ try {
34
+ return await error.response.json();
35
+ } catch {
36
+ return {};
37
+ }
38
+ }
39
+ async function throwSessionRestartRequiredIf(errorMsg, error) {
40
+ if (!(error instanceof __spiffy_ai_commerce_api_client.ResponseError)) {
41
+ require_logger.logger_default.logInfo(errorMsg, error);
42
+ throw error;
43
+ }
44
+ const errorResponse = await errorResponseBody(error);
45
+ if (errorResponse?.message?.toLowerCase() === "unsupported product" || errorResponse?.app_code?.toUpperCase() === "PRODUCT_NOT_FOUND") throw new require_exceptions.UnsupportedProductException();
46
+ else if (errorResponse?.app_code?.toUpperCase() === "RESTART_SESSION" || errorResponse?.sub_code?.toUpperCase() === "NOT_FOUND") {
47
+ require_logger.logger_default.logInfo("Session does not exist. Re-start session", error, error.response, errorResponse);
48
+ throw new require_exceptions.SessionRestartRequired();
49
+ }
50
+ require_logger.logger_default.logInfo(errorMsg, error);
51
+ throw error;
52
+ }
53
+ var CommerceApiClient = class CommerceApiClient {
54
+ static {
55
+ this.getInstance = () => {
56
+ if (!CommerceApiClient.instance) CommerceApiClient.instance = new CommerceApiClient();
57
+ return CommerceApiClient.instance;
58
+ };
59
+ }
60
+ constructor(basePath) {
61
+ this.suggestionsAbortController = new AbortController();
62
+ this.responsesAbortController = new AbortController();
63
+ const baseUrl = require_atomStore.getAtomStore().get(require_enviveConfig.baseUrlAtom);
64
+ const config = new __spiffy_ai_commerce_api_client.Configuration({
65
+ basePath: basePath || baseUrl,
66
+ headers: {
67
+ "Content-Type": "application/json",
68
+ Accept: "application/json"
69
+ }
70
+ });
71
+ this.defaultApi = new __spiffy_ai_commerce_api_client.DefaultApi(config);
72
+ this.inferenceApi = new __spiffy_ai_commerce_api_client.InferenceApi(config);
73
+ this.customerServiceApi = new __spiffy_ai_commerce_api_client.CustomerServiceApi(config);
74
+ }
75
+ static {
76
+ this.resolveUrl = async (url) => {
77
+ const atomStore = require_atomStore.getAtomStore();
78
+ const orgShortName = atomStore.get(require_enviveConfig.orgShortNameAtom);
79
+ const orgId = atomStore.get(require_org.orgIdAtom);
80
+ const userId = atomStore.get(userIdAtom);
81
+ const chatId = atomStore.get(chatIdAtom);
82
+ const source = atomStore.get(require_enviveConfig.contextSourceAtom);
83
+ const env = atomStore.get(require_enviveConfig.envAtom);
84
+ const featureFlagService = atomStore.get(require_org.featureFlagServiceAtom);
85
+ const context = {
86
+ user_id: userId ?? "",
87
+ org_id: orgId ?? "",
88
+ org_short_name: orgShortName ?? "",
89
+ chat_id: chatId ?? "",
90
+ source: source ?? __spiffy_ai_commerce_api_client.ContextSourceEnum.App,
91
+ env: env ?? __spiffy_ai_commerce_api_client.ContextEnvEnum.Dev
92
+ };
93
+ const featureGates = featureFlagService?.featureFlagService?.getFeatureFlags() || {};
94
+ const urlResolvingRequest = {
95
+ url,
96
+ context,
97
+ feature_gates: featureGates
98
+ };
99
+ return await (await CommerceApiClient.getInstance().inferenceApi.v1UrlResolvingPostRaw({ UrlResolvingRequest: urlResolvingRequest })).raw.json();
100
+ };
101
+ }
102
+ static {
103
+ this.reportSession = async (reportRequest) => {
104
+ await CommerceApiClient.getInstance().defaultApi.v1ChatsReportSessionIdPost({ ReportSessionRequest: reportRequest });
105
+ };
106
+ }
107
+ static {
108
+ this.getNextResponses = async (payload) => {
109
+ try {
110
+ return (await CommerceApiClient.getInstance().inferenceApi.v1NextResponsesPost({ NextMessageRequest: messageRequestToCommerceMessageRequest(payload) })).map((resp) => require_models.validateResponse(resp)).map((resp) => messageFromResponse(resp)).filter((m) => m != null);
111
+ } catch (err) {
112
+ require_logger.logger_default.logInfo("Failed to get next responses", err, {
113
+ payloadContext: payload?.context,
114
+ userEvents: payload?.userEvents
115
+ });
116
+ await throwSessionRestartRequiredIf("Failed to get next responses", err);
117
+ return [];
118
+ }
119
+ };
120
+ }
121
+ static {
122
+ this.getNextResponseStreaming = (payload) => {
123
+ async function* generate(inferenceApi, abortController) {
124
+ try {
125
+ const response = await inferenceApi.v1NextResponsesPostRaw({ NextMessageRequest: messageRequestToCommerceMessageRequest(payload) }, { signal: abortController.signal });
126
+ if (!response.raw.body) {
127
+ require_logger.logger_default.logError("[spiffy-ai] No body in the streamed response", void 0, { response: response.raw });
128
+ return;
129
+ }
130
+ const reader = response.raw.body.getReader();
131
+ const decoder = new TextDecoder("utf-8");
132
+ let partial = "";
133
+ const safeParse = (line) => {
134
+ try {
135
+ return JSON.parse(line);
136
+ } catch (err) {
137
+ require_logger.logger_default.logError("[spiffy-ai] Error parsing streamed line", err, {
138
+ line,
139
+ partial
140
+ });
141
+ partial = line;
142
+ return partial;
143
+ }
144
+ };
145
+ const processChunk = (chunk) => {
146
+ return `${partial}${chunk}`.split("\n").map((line) => line.replace(/^data: /, "").trim()).filter((line) => line !== "" && line !== "[DONE]").map(safeParse).filter((v) => v);
147
+ };
148
+ while (true) {
149
+ const { done, value } = await reader.read();
150
+ if (done) break;
151
+ const chunk = decoder.decode(value);
152
+ const parsedLines = processChunk(chunk);
153
+ for (const parsedLine of parsedLines) {
154
+ const validatedResponse = require_models.validateResponse(parsedLine);
155
+ if (validatedResponse) yield validatedResponse;
156
+ }
157
+ }
158
+ } catch (error) {
159
+ require_logger.logger_default.logError("[spiffy-ai] Failed to get next streaming responses", error, {
160
+ payloadContext: payload?.context,
161
+ userEvents: payload?.userEvents
162
+ });
163
+ await throwSessionRestartRequiredIf("Failed to get next streaming responses", error);
164
+ }
165
+ }
166
+ CommerceApiClient.getInstance().responsesAbortController.abort();
167
+ CommerceApiClient.getInstance().responsesAbortController = new AbortController();
168
+ return generate(CommerceApiClient.getInstance().inferenceApi, CommerceApiClient.getInstance().responsesAbortController);
169
+ };
170
+ }
171
+ static {
172
+ this.getNextSuggestions = async (payload) => {
173
+ try {
174
+ CommerceApiClient.getInstance().suggestionsAbortController.abort();
175
+ CommerceApiClient.getInstance().suggestionsAbortController = new AbortController();
176
+ return (await CommerceApiClient.getInstance().inferenceApi.v1NextSuggestionsPost({ NextMessageRequest: messageRequestToCommerceMessageRequest(payload) }, { signal: CommerceApiClient.getInstance().suggestionsAbortController.signal })).map((resp) => require_models.validateSuggestion(resp)).filter((suggestion) => suggestion != null);
177
+ } catch (error) {
178
+ require_logger.logger_default.logInfo("Failed to get suggestions", error, {
179
+ payloadContext: payload?.context,
180
+ userEvents: payload?.userEvents
181
+ });
182
+ await throwSessionRestartRequiredIf("Failed to get suggestions", error);
183
+ return [];
184
+ }
185
+ };
186
+ }
187
+ static {
188
+ this.getResponses = async (orgId, chatId, userId) => {
189
+ let data = {
190
+ responses: [],
191
+ suggestions: [],
192
+ user_events: []
193
+ };
194
+ const request = {
195
+ org_id: orgId,
196
+ chat_id: chatId,
197
+ user_id: userId
198
+ };
199
+ try {
200
+ data = await CommerceApiClient.getInstance().defaultApi.v1GetSessionMessages(request);
201
+ } catch (error) {
202
+ await throwSessionRestartRequiredIf("Failed to get chat responses", error);
203
+ }
204
+ const responses = data?.responses?.map((turn) => turn.map((response) => require_models.validateResponse(response)).filter((response) => response != null));
205
+ const suggestions = data?.suggestions.map((suggestion) => require_models.validateSuggestion(suggestion)).filter((suggestion) => suggestion != null);
206
+ const userEvents = data?.user_events.map((event) => require_models.validateUserEvent(event)).filter((event) => event != null);
207
+ const formSubmittedUserEventsFormIds = userEvents.filter((event) => event.category === __spiffy_ai_commerce_api_client.UserEventCategory.FormSubmitted).map((event) => event.attributes.formResponseId);
208
+ const assistantMessages = responses.map((turn) => turn.filter((response) => !(response.category === __spiffy_ai_commerce_api_client.ResponseCategory.Form && formSubmittedUserEventsFormIds.includes(response.id))).map((response) => messageFromResponse(response)).filter((message) => message != null)).filter((turn) => turn.length > 0);
209
+ const userMessages = userEvents.map((event) => {
210
+ if ([__spiffy_ai_commerce_api_client.UserEventCategory.QueryTyped, __spiffy_ai_commerce_api_client.UserEventCategory.Search].includes(event.category)) return [messageFromQueryEvent(event)];
211
+ if (event.category === __spiffy_ai_commerce_api_client.UserEventCategory.SuggestionClicked) return [messageFromSuggestionEvent(event, suggestions)];
212
+ if (event.category === __spiffy_ai_commerce_api_client.UserEventCategory.FormSubmitted) {
213
+ const formResponse = responses.flat().find((response) => response.id === event.attributes.formResponseId && event.attributes.formType !== __spiffy_ai_commerce_api_client.FormType.Escalation);
214
+ if (formResponse && formResponse.category === __spiffy_ai_commerce_api_client.ResponseCategory.Form) return [messageFromFormSubmittedEvent(event, formResponse.attributes)];
215
+ }
216
+ return [];
217
+ }).filter((message) => message.length > 0);
218
+ const sortedMessages = [...assistantMessages, ...userMessages].sort((a, b) => new Date(a[0].createdAt).getTime() - new Date(b[0].createdAt).getTime());
219
+ return {
220
+ responses,
221
+ userEvents,
222
+ suggestions,
223
+ messages: sortedMessages
224
+ };
225
+ };
226
+ }
227
+ static {
228
+ this.isSupportedEvent = async (payload) => {
229
+ try {
230
+ const httpResponseText = await (await CommerceApiClient.getInstance().inferenceApi.v1SupportedEventPostRaw({ SupportedEventRequest: coreSupportedEventRequestToApiRequest(payload) })).raw.text();
231
+ const httpResponseJson = JSON.parse(httpResponseText);
232
+ return {
233
+ ...httpResponseJson,
234
+ numberOfReviews: httpResponseJson.num_of_reviews,
235
+ merchant_tags: httpResponseJson.merchant_tags || []
236
+ };
237
+ } catch (err) {
238
+ require_logger.logger_default.logError("Failed to get response for v1SupportedEventPost", { err });
239
+ return {
240
+ supported: false,
241
+ ready: false,
242
+ category: void 0,
243
+ collections: [],
244
+ numberOfReviews: void 0,
245
+ top_category: void 0,
246
+ merchant_tags: []
247
+ };
248
+ }
249
+ };
250
+ }
251
+ static {
252
+ this.identifyUser = async (spiffyUserId, merchantUserId, uaDetails) => {
253
+ try {
254
+ await CommerceApiClient.getInstance().defaultApi.v1AnalyticsIdentifyPost({ AnalyticsIdentifyRequest: {
255
+ user_id: spiffyUserId,
256
+ os_name: uaDetails.os,
257
+ os_version: uaDetails.osVersion,
258
+ platform: uaDetails.os,
259
+ device_id: uaDetails.deviceModel,
260
+ device_brand: uaDetails.deviceBrand,
261
+ device_manufacturer: uaDetails.deviceManufacturer,
262
+ device_model: uaDetails.deviceModel,
263
+ user_properties: {
264
+ cdp_user_id: merchantUserId,
265
+ browser: uaDetails.browser,
266
+ browser_version: uaDetails.browserVersion,
267
+ user_agent: uaDetails.userAgent
268
+ }
269
+ } });
270
+ } catch (err) {
271
+ require_logger.logger_default.logError("Failed to identify user", err);
272
+ }
273
+ };
274
+ }
275
+ static {
276
+ this.mapContextSourceToV1OrgConfigGetSource = (source) => {
277
+ if (source === void 0) return void 0;
278
+ switch (source) {
279
+ case __spiffy_ai_commerce_api_client.ContextSourceEnum.Fork: return __spiffy_ai_commerce_api_client.V1OrgConfigGetSourceEnum.Fork;
280
+ case __spiffy_ai_commerce_api_client.ContextSourceEnum.Playground: return __spiffy_ai_commerce_api_client.V1OrgConfigGetSourceEnum.Playground;
281
+ case __spiffy_ai_commerce_api_client.ContextSourceEnum.App: return __spiffy_ai_commerce_api_client.V1OrgConfigGetSourceEnum.App;
282
+ case __spiffy_ai_commerce_api_client.ContextSourceEnum.Test: return __spiffy_ai_commerce_api_client.V1OrgConfigGetSourceEnum.Test;
283
+ default: return source;
284
+ }
285
+ };
286
+ }
287
+ static {
288
+ this.getOrgConfig = async (user_id) => {
289
+ try {
290
+ const atomStore = require_atomStore.getAtomStore();
291
+ const reactAppName = atomStore.get(require_enviveConfig.reactAppNameAtom);
292
+ const contextSource = atomStore.get(require_enviveConfig.contextSourceAtom);
293
+ const featureFlagService = atomStore.get(require_org.featureFlagServiceAtom);
294
+ const request = {
295
+ namespace: reactAppName,
296
+ user_id,
297
+ source: this.mapContextSourceToV1OrgConfigGetSource(contextSource),
298
+ include_experiments: Object.values(require_dist.ProductExperiment),
299
+ include_feature_gates: Object.entries(featureFlagService?.featureFlagService?.getFeatureFlags() || {}).filter(([, isEnabled]) => isEnabled).map(([featureGateName]) => featureGateName)
300
+ };
301
+ const response = await CommerceApiClient.getInstance().defaultApi.v1OrgConfigGet(request);
302
+ return require_models.validateOrgConfigResults(response);
303
+ } catch (err) {
304
+ require_logger.logger_default.logError(`Failed to get org config`, err, { err });
305
+ return;
306
+ }
307
+ };
308
+ }
309
+ static {
310
+ this.addNoteToLatestConversation = async (spiffyUserId, email, customerServiceProvider) => {
311
+ require_logger.logger_default.logInfo(`addNoteToLatestConversation - user_id=${spiffyUserId} email=${email} customer_service_provider=${customerServiceProvider}`);
312
+ try {
313
+ await CommerceApiClient.getInstance().customerServiceApi.v1CustserviceAddNoteToLatestConversationPost({ AddNoteToLatestConversationRequest: {
314
+ spiffy_user_id: spiffyUserId,
315
+ email,
316
+ customer_service_provider: customerServiceProvider
317
+ } });
318
+ } catch (err) {
319
+ require_logger.logger_default.logError("Failed to add note to latest conversation", { err });
320
+ }
321
+ };
322
+ }
323
+ static {
324
+ this.getCustomerServiceApi = () => CommerceApiClient.getInstance().customerServiceApi;
325
+ }
326
+ };
327
+ var commerce_api_default = CommerceApiClient;
328
+
329
+ //#endregion
330
+ //#region src/contexts/userIdentityContext/userIdentityContext.tsx
331
+ const getUserAgentDetails = () => {
332
+ const result = new ua_parser_js.default().getResult();
333
+ return {
334
+ os: result?.os?.name,
335
+ osVersion: result?.os?.version,
336
+ deviceBrand: result?.device?.vendor,
337
+ deviceManufacturer: result?.device?.vendor,
338
+ deviceModel: result?.device?.model,
339
+ browser: result?.browser?.name,
340
+ browserVersion: result?.browser?.version,
341
+ userAgent: result?.ua
342
+ };
343
+ };
344
+ const UserIdentityContext = (0, react.createContext)(void 0);
345
+ const UserIdentityProvider = ({ children }) => {
346
+ const { getItem, setItem, isAvailable: localStorageIsReady } = require_localStorageContext.useLocalStorage();
347
+ const [isReady, setIsReady] = (0, react.useState)(false);
348
+ (0, react.useEffect)(() => {
349
+ setIsReady(localStorageIsReady);
350
+ }, [localStorageIsReady]);
351
+ const USER_ID_OVERRIDE_KEY = "v1-spiffy-user-id-override";
352
+ const USER_ID_DEFAULT_KEY = "v1-spiffy-user-id-default";
353
+ const getUserIdOverrideFromLocalStorage = (0, react.useCallback)(() => getItem(USER_ID_OVERRIDE_KEY) ?? void 0, [getItem]);
354
+ const getUserIdDefaultFromLocalStorage = (0, react.useCallback)(() => getItem(USER_ID_DEFAULT_KEY) ?? void 0, [getItem]);
355
+ const setUserIdDefaultInLocalStorage = (0, react.useCallback)((userId) => {
356
+ require_logger.logger_default.logInfo(`setUserIdDefaultInLocalStorage - Setting user_id=${userId}`);
357
+ setItem(USER_ID_DEFAULT_KEY, userId);
358
+ return userId;
359
+ }, [setItem, USER_ID_DEFAULT_KEY]);
360
+ const setUserIdOverrideInLocalStorage = (0, react.useCallback)((userId) => {
361
+ require_logger.logger_default.logInfo(`setUserIdOverrideInLocalStorage - Setting user_id=${userId}`);
362
+ setItem(USER_ID_OVERRIDE_KEY, userId);
363
+ return userId;
364
+ }, [setItem, USER_ID_OVERRIDE_KEY]);
365
+ const clearUserIdOverrideInLocalStorage = (0, react.useCallback)(() => {
366
+ require_logger.logger_default.logInfo(`clearUserIdOverrideInLocalStorage - Clearing user_id`);
367
+ setItem(USER_ID_OVERRIDE_KEY, "");
368
+ }, [setItem, USER_ID_OVERRIDE_KEY]);
369
+ const getUserIdOrDefault = (0, react.useCallback)(() => {
370
+ const userIdOverride = getUserIdOverrideFromLocalStorage();
371
+ if (userIdOverride) return userIdOverride;
372
+ const defaultUserId = getUserIdDefaultFromLocalStorage();
373
+ if (defaultUserId) return defaultUserId;
374
+ return setUserIdDefaultInLocalStorage(`spiffy-user-id-${(0, uuid.v4)()}`);
375
+ }, [
376
+ getUserIdOverrideFromLocalStorage,
377
+ getUserIdDefaultFromLocalStorage,
378
+ setUserIdDefaultInLocalStorage
379
+ ]);
380
+ const identifyUser = (0, react.useCallback)(async () => {
381
+ if (!isReady) {
382
+ require_logger.logger_default.logWarn("[UserIdentityContext] Context not ready, skipping identifyUser", void 0);
383
+ return;
384
+ }
385
+ try {
386
+ const cdpUserId = "UNKNOWN_CDP_USER_ID";
387
+ const userId = getUserIdOrDefault();
388
+ const userAgentDetails = getUserAgentDetails();
389
+ await commerce_api_default.identifyUser(userId, cdpUserId, userAgentDetails);
390
+ } catch (error) {
391
+ require_logger.logger_default.logError("[spiffy-ai] Error identifying user", error);
392
+ }
393
+ }, [isReady, getUserIdOrDefault]);
394
+ const value = (0, react.useMemo)(() => ({
395
+ identifyUser,
396
+ getUserIdOrDefault,
397
+ getUserIdOverrideFromLocalStorage,
398
+ getUserIdDefaultFromLocalStorage,
399
+ setUserIdDefaultInLocalStorage,
400
+ setUserIdOverrideInLocalStorage,
401
+ clearUserIdOverrideInLocalStorage,
402
+ isReady
403
+ }), [
404
+ identifyUser,
405
+ getUserIdOrDefault,
406
+ getUserIdOverrideFromLocalStorage,
407
+ getUserIdDefaultFromLocalStorage,
408
+ setUserIdDefaultInLocalStorage,
409
+ setUserIdOverrideInLocalStorage,
410
+ clearUserIdOverrideInLocalStorage,
411
+ isReady
412
+ ]);
413
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UserIdentityContext.Provider, {
414
+ value,
415
+ children
416
+ });
417
+ };
418
+ const useUserIdentity = () => {
419
+ const context = (0, react.useContext)(UserIdentityContext);
420
+ if (!context) throw new Error("useUserIdentity must be used within a UserIdentityProvider");
421
+ return context;
422
+ };
423
+
424
+ //#endregion
425
+ //#region src/atoms/app/variant.ts
426
+ const internalStorageUrlResolverAtom = (0, jotai_utils.atomWithStorage)("spiffy-url-resolver", void 0, require_atomStore.sessionStorageUtil, { getOnInit: true });
427
+ const urlResolverAtom = (0, jotai.atom)((get) => {
428
+ const maybeUrlResolver = get(internalStorageUrlResolverAtom);
429
+ if (maybeUrlResolver == null) return {};
430
+ return JSON.parse(maybeUrlResolver);
431
+ }, (get, set, value) => {
432
+ const newCache = {
433
+ ...get(urlResolverAtom),
434
+ [value.url]: value.response
435
+ };
436
+ set(internalStorageUrlResolverAtom, JSON.stringify(newCache));
437
+ });
438
+ const internalStorageSupportedEventAtom = (0, jotai_utils.atomWithStorage)("spiffy-supported-event", void 0, require_atomStore.sessionStorageUtil, { getOnInit: true });
439
+ const internalSupportedEventAtom = (0, jotai.atom)(void 0);
440
+ const supportedEventAtom = (0, jotai.atom)((get) => {
441
+ const maybeSupportedEvent = get(internalStorageSupportedEventAtom);
442
+ if (maybeSupportedEvent == null) return;
443
+ return JSON.parse(maybeSupportedEvent);
444
+ }, (_, set, value) => {
445
+ if (value == null) {
446
+ set(internalStorageSupportedEventAtom, void 0);
447
+ set(internalSupportedEventAtom, void 0);
448
+ return;
449
+ }
450
+ set(internalSupportedEventAtom, value);
451
+ set(internalStorageSupportedEventAtom, JSON.stringify(value));
452
+ });
453
+ const internalVariantIdAtom = (0, jotai.atom)();
454
+ const internalProductIdAtom = (0, jotai.atom)();
455
+ const internalParentProductIdAtom = (0, jotai.atom)();
456
+ const internalProductUrlAtom = (0, jotai.atom)();
457
+ const internalPlpIdAtom = (0, jotai.atom)();
458
+ const internalUrlAtom = (0, jotai.atom)();
459
+ const internalPageVisitCategoryAtom = (0, jotai.atom)();
460
+ const internalVariantAtom = (0, jotai.atom)("pdp");
461
+ const variantIdAtom = (0, jotai.atom)((get) => get(internalVariantIdAtom));
462
+ const productIdAtom = (0, jotai.atom)((get) => get(internalProductIdAtom));
463
+ const parentProductIdAtom = (0, jotai.atom)((get) => get(internalParentProductIdAtom));
464
+ const productUrlAtom = (0, jotai.atom)((get) => get(internalProductUrlAtom));
465
+ const plpIdAtom = (0, jotai.atom)((get) => get(internalPlpIdAtom));
466
+ const urlAtom = (0, jotai.atom)((get) => get(internalUrlAtom));
467
+ const pageVisitCategoryAtom = (0, jotai.atom)((get) => get(internalPageVisitCategoryAtom));
468
+ const variantAtom = (0, jotai.atom)((get) => get(internalVariantAtom));
469
+ const hasParsedVariantInfoAtom = (0, jotai.atom)(false);
470
+ const variantInfoAtom = (0, jotai.atom)((get) => {
471
+ const variant = get(variantAtom);
472
+ if (variant === require_dist.VariantTypeEnum.Pdp) return {
473
+ variantId: get(variantIdAtom),
474
+ variant,
475
+ productId: get(productIdAtom),
476
+ parentProductId: get(parentProductIdAtom),
477
+ url: get(urlAtom)
478
+ };
479
+ if (variant === require_dist.VariantTypeEnum.Plp) return {
480
+ variantId: get(variantIdAtom),
481
+ variant,
482
+ plpId: get(plpIdAtom),
483
+ url: get(urlAtom)
484
+ };
485
+ if (variant === require_dist.VariantTypeEnum.PageVisit) return {
486
+ variantId: get(variantIdAtom),
487
+ variant,
488
+ url: get(urlAtom),
489
+ pageVisitCategory: get(pageVisitCategoryAtom)
490
+ };
491
+ throw new Error("Invalid variantInfo details");
492
+ }, (_, set, newVariant) => {
493
+ set(internalVariantAtom, newVariant.variant);
494
+ set(internalVariantIdAtom, newVariant.variantId);
495
+ if (newVariant.variant === require_dist.VariantTypeEnum.Pdp) {
496
+ set(internalProductIdAtom, newVariant.productId);
497
+ set(internalParentProductIdAtom, newVariant.parentProductId);
498
+ set(internalUrlAtom, newVariant.url);
499
+ }
500
+ if (newVariant.variant === require_dist.VariantTypeEnum.Plp) {
501
+ set(internalPlpIdAtom, newVariant.plpId);
502
+ set(internalUrlAtom, newVariant.url);
503
+ }
504
+ if (newVariant.variant === require_dist.VariantTypeEnum.PageVisit) {
505
+ set(internalUrlAtom, newVariant.url);
506
+ set(internalPageVisitCategoryAtom, newVariant.pageVisitCategory);
507
+ }
508
+ });
509
+
510
+ //#endregion
511
+ //#region src/atoms/app/index.ts
512
+ const internalUserIdAtom = (0, jotai.atom)(void 0);
513
+ const userIdAtom = (0, jotai.atom)((get) => {
514
+ const maybeUserId = get(internalUserIdAtom);
515
+ if (maybeUserId) return maybeUserId;
516
+ const { getUserIdOrDefault } = useUserIdentity();
517
+ return getUserIdOrDefault();
518
+ }, (_, set, value) => {
519
+ set(internalUserIdAtom, value);
520
+ });
521
+ const userIdentityAtom = (0, jotai.atom)(void 0);
522
+ const appSourceAtom = (0, jotai.atom)((get) => get(require_enviveConfig.contextSourceAtom) ?? __spiffy_ai_commerce_api_client.ContextSourceEnum.App);
523
+ const chatIdAtom = (0, jotai_utils.atomWithStorage)("v1-spiffy-chat-session-id", (0, uuid.v4)(), void 0, { getOnInit: true });
524
+
525
+ //#endregion
526
+ //#region src/contexts/amplitudeContext/amplitudeContext.tsx
527
+ let SpiffyMetricsEventName = /* @__PURE__ */ function(SpiffyMetricsEventName$1) {
528
+ SpiffyMetricsEventName$1["BundleLoaded"] = "Bundle Loaded";
529
+ SpiffyMetricsEventName$1["ChatLiveAgentBtnClick"] = "Chat Live Agent Btn Click";
530
+ SpiffyMetricsEventName$1["ChatFloatingButtonVisible"] = "Chat Floating Button Visible";
531
+ SpiffyMetricsEventName$1["ChatComponentVisible"] = "Chat Component Visible";
532
+ SpiffyMetricsEventName$1["ChatComponentExpanded"] = "Chat Component Expanded";
533
+ SpiffyMetricsEventName$1["ChatComponentCollapsed"] = "Chat Component Collapsed";
534
+ SpiffyMetricsEventName$1["ChatUserMessageInput"] = "Chat User Message Input";
535
+ SpiffyMetricsEventName$1["ChatSuggestionClicked"] = "Chat Suggestion Clicked";
536
+ SpiffyMetricsEventName$1["ChatAssistantResponse"] = "Chat Assistant Response";
537
+ SpiffyMetricsEventName$1["ProductCardClicked"] = "Product Card Clicked";
538
+ SpiffyMetricsEventName$1["ProductReviewCardClicked"] = "Product Review Card Clicked";
539
+ SpiffyMetricsEventName$1["AddToCartClicked"] = "Add to Cart Clicked";
540
+ SpiffyMetricsEventName$1["PromptCardClicked"] = "Prompt Card Clicked";
541
+ SpiffyMetricsEventName$1["SupportedEvent"] = "Supported Event";
542
+ SpiffyMetricsEventName$1["SearchBackToResponseClicked"] = "Search Back to Response Clicked";
543
+ SpiffyMetricsEventName$1["PerformanceMetrics"] = "Performance Metrics";
544
+ SpiffyMetricsEventName$1["SearchBarClicked"] = "Search Bar Clicked";
545
+ SpiffyMetricsEventName$1["OrderLookupStarted"] = "Order Lookup Started";
546
+ SpiffyMetricsEventName$1["OrderLookupFormSubmitted"] = "Order Lookup Form Submitted";
547
+ SpiffyMetricsEventName$1["SearchComponentVisible"] = "Search Component Visible";
548
+ SpiffyMetricsEventName$1["SearchZeroStateSuggestionClicked"] = "Search Zero State Suggestion Clicked";
549
+ SpiffyMetricsEventName$1["SearchInputStarted"] = "Search Input Started";
550
+ SpiffyMetricsEventName$1["SearchQuerySubmitted"] = "Search Query Submitted";
551
+ SpiffyMetricsEventName$1["SearchResultsViewed"] = "Search Results Viewed";
552
+ SpiffyMetricsEventName$1["SearchTimeToFirstClick"] = "Search Time to First Click";
553
+ SpiffyMetricsEventName$1["SearchZeroResultsRate"] = "Search Zero Results Rate";
554
+ SpiffyMetricsEventName$1["SearchFilterClicked"] = "Search Filter Clicked";
555
+ SpiffyMetricsEventName$1["SearchSortClicked"] = "Search Sort Clicked";
556
+ return SpiffyMetricsEventName$1;
557
+ }({});
558
+ const AmplitudeContext = (0, react.createContext)(null);
559
+ const AmplitudeProvider = ({ children }) => {
560
+ const userId = (0, jotai.useAtomValue)(userIdAtom);
561
+ const amplitudeApiKey = (0, jotai.useAtomValue)(require_enviveConfig.amplitudeApiKeyAtom);
562
+ const dataResidency = (0, jotai.useAtomValue)(require_enviveConfig.dataResidencyAtom);
563
+ const orgGaConfig = (0, jotai.useAtomValue)(require_org.orgAnalyticsGoogleAnalyticsConfigAtom);
564
+ const env = (0, jotai.useAtomValue)(require_enviveConfig.envAtom);
565
+ const contextSource = (0, jotai.useAtomValue)(require_enviveConfig.contextSourceAtom);
566
+ (0, jotai.useAtomValue)(require_enviveConfig.identifyingPrefixAtom);
567
+ const { getItem } = require_localStorageContext.useLocalStorage();
568
+ const { publicKey, featureOverrides, variantUrlOverride, variantInfoOverride, show, orgShortName, featureGates } = require_enviveConfigContext.useEnviveConfig();
569
+ const { featureFlagService } = require_featureFlagServiceContext.useFeatureFlagService();
570
+ const [amplitudeClient, setAmplitudeClient] = react.default.useState(void 0);
571
+ const [internalEventTrackingEnrichment, setInternalEventTrackingEnrichment] = react.default.useState(void 0);
572
+ const [supplementalDefaultProps, setSupplementalDefaultProps] = react.default.useState({});
573
+ const isReady = Boolean(userId && featureFlagService && amplitudeApiKey && userId);
574
+ const getDefaultTrackingProps = (0, react.useCallback)(() => {
575
+ const gatesProps = featureGates ? featureGates.reduce((acc, curr) => {
576
+ if (curr.name && curr.value != null) return {
577
+ ...acc,
578
+ [`feature_gate.${curr.name}`]: curr.value
579
+ };
580
+ return acc;
581
+ }, {}) : {};
582
+ const experimentProps = {};
583
+ return {
584
+ ...gatesProps,
585
+ ...experimentProps,
586
+ ...supplementalDefaultProps,
587
+ app_id: "commerce-chat-react-component",
588
+ chat_id: getItem(require_dist.LocalStorageKeys.ChatId),
589
+ env: env || "unknown",
590
+ app_source: contextSource,
591
+ "org.short_name": orgShortName,
592
+ "user.id": userId,
593
+ "cdp.user_id": null,
594
+ "cdp.provider": null,
595
+ "event.source": "web-browser",
596
+ "event.type": "user-activity",
597
+ "event.id": null,
598
+ "event.channel": "web",
599
+ "event.timestamp": null
600
+ };
601
+ }, [
602
+ featureGates,
603
+ supplementalDefaultProps,
604
+ env,
605
+ contextSource,
606
+ orgShortName,
607
+ userId
608
+ ]);
609
+ const eventPropsToPrefixedEventProps = (0, react.useCallback)((eventName, eventProps) => {
610
+ const prefix = eventName.toLowerCase().replace(/\s+/g, "_");
611
+ return Object.entries(eventProps).reduce((acc, [key, value$1]) => {
612
+ acc[`${prefix}.${key}`] = value$1;
613
+ return acc;
614
+ }, {});
615
+ }, []);
616
+ const amplitudeSessionReplayInit = (0, react.useCallback)(() => {
617
+ const isEnabled = Boolean(orgShortName === require_dist.OrgShortName.UniqueVintage && featureFlagService?.isClientSessionEnabled() && featureFlagService?.isFeatureGateEnabled(require_dist.FeatureGates.IsNewFeatureEnabled));
618
+ const sampleRate = 1;
619
+ try {
620
+ require_logger.logger_default.logDebug(`[spiffy-ai] amplitude session-replay initializing isEnabled=${isEnabled} sampleRate=${sampleRate}`);
621
+ if (!isEnabled) return isEnabled;
622
+ return isEnabled;
623
+ } catch (e) {
624
+ require_logger.logger_default.logError("[spiffy-ai] Error initializing amplitude session-replay", e);
625
+ return false;
626
+ }
627
+ }, [orgShortName, featureFlagService]);
628
+ const getEventTrackingEnrichment = (0, react.useCallback)(() => {
629
+ if (internalEventTrackingEnrichment !== void 0) return internalEventTrackingEnrichment;
630
+ const enrichment = {
631
+ name: "page-view-tracking-enrichment",
632
+ type: "enrichment",
633
+ setup: async () => void 0,
634
+ execute: async (event) => {
635
+ let enrichedEvent;
636
+ if (["[Amplitude] Page Viewed", `[Spiffy] ${SpiffyMetricsEventName.BundleLoaded}`].includes(event.event_type)) {
637
+ const globalProperties = {};
638
+ if (publicKey) globalProperties["globalProperties.publicKey"] = publicKey;
639
+ if (featureOverrides) Object.entries(featureOverrides).forEach(([key, value$1]) => {
640
+ globalProperties[`globalProperties.featureOverrides.${key}`] = String(value$1);
641
+ });
642
+ if (variantUrlOverride) globalProperties["globalProperties.variantUrlOverride"] = variantUrlOverride;
643
+ if (variantInfoOverride) globalProperties["globalProperties.variantInfoOverride"] = JSON.stringify(variantInfoOverride);
644
+ if (show != null) globalProperties["globalProperties.show"] = String(show);
645
+ const enabledFeatures = featureFlagService.getFeatureFlags();
646
+ const enabledFeaturesProperties = Object.entries(enabledFeatures).reduce((acc, [key, value$1]) => ({
647
+ ...acc,
648
+ [`enabledFeatures.${key}`]: `${value$1}`
649
+ }), {});
650
+ const timingProperties = { "timing.enriched_at_ms": window.performance?.now() };
651
+ enrichedEvent = {
652
+ ...event,
653
+ event_properties: {
654
+ ...event.event_properties,
655
+ ...getDefaultTrackingProps(),
656
+ ...globalProperties,
657
+ ...enabledFeaturesProperties,
658
+ ...timingProperties
659
+ }
660
+ };
661
+ } else enrichedEvent = event;
662
+ require_events.EventsDispatcher.dispatch(require_dist.SpiffyEvent.AMPLITUDE_EVENT, enrichedEvent);
663
+ return enrichedEvent;
664
+ }
665
+ };
666
+ setInternalEventTrackingEnrichment(enrichment);
667
+ return enrichment;
668
+ }, [
669
+ internalEventTrackingEnrichment,
670
+ getDefaultTrackingProps,
671
+ featureFlagService,
672
+ publicKey,
673
+ featureOverrides,
674
+ variantUrlOverride,
675
+ variantInfoOverride,
676
+ show
677
+ ]);
678
+ (0, react.useEffect)(() => {
679
+ if (isReady && !amplitudeClient) {
680
+ const currentAmplitudeInstance = (0, __amplitude_analytics_browser.createInstance)();
681
+ const isSessionsEnabled = amplitudeSessionReplayInit();
682
+ currentAmplitudeInstance.add(getEventTrackingEnrichment());
683
+ currentAmplitudeInstance.init(amplitudeApiKey, userId, {
684
+ serverZone: dataResidency,
685
+ trackingOptions: { ipAddress: true },
686
+ autocapture: {
687
+ attribution: true,
688
+ pageViews: { trackHistoryChanges: "pathOnly" },
689
+ sessions: isSessionsEnabled,
690
+ formInteractions: false,
691
+ fileDownloads: false
692
+ }
693
+ });
694
+ setAmplitudeClient(currentAmplitudeInstance);
695
+ }
696
+ }, [
697
+ isReady,
698
+ amplitudeClient,
699
+ amplitudeApiKey,
700
+ userId,
701
+ dataResidency,
702
+ amplitudeSessionReplayInit,
703
+ getEventTrackingEnrichment
704
+ ]);
705
+ const trackEvent = (0, react.useCallback)(async ({ eventName, eventProps, eventGroups, alsoSendToGoogleAnalytics = false }) => {
706
+ require_logger.logger_default.logDebug("Submitting event", eventName);
707
+ try {
708
+ const decoratedEventName = `[Spiffy] ${eventName}`;
709
+ if (!amplitudeClient) {
710
+ require_logger.logger_default.logWarn("amplitude client undefined", void 0, { event_name: decoratedEventName });
711
+ return;
712
+ }
713
+ const eventData = JSON.stringify({
714
+ eventName,
715
+ eventProps,
716
+ created_at: (/* @__PURE__ */ new Date()).toISOString()
717
+ });
718
+ const data = new TextEncoder().encode(eventData);
719
+ const hashBuffer = await crypto.subtle.digest("SHA-256", data);
720
+ const currentInsertId = Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
721
+ require_logger.logger_default.logDebug(`amplitude tracking ${decoratedEventName}`, null, {
722
+ event_name: decoratedEventName,
723
+ props: eventProps
724
+ });
725
+ amplitudeClient.track(decoratedEventName, {
726
+ ...getDefaultTrackingProps(),
727
+ ...eventProps,
728
+ ...eventProps ? eventPropsToPrefixedEventProps(eventName, eventProps) : {}
729
+ }, {
730
+ ...eventGroups,
731
+ insert_id: currentInsertId
732
+ });
733
+ if (alsoSendToGoogleAnalytics && orgGaConfig) {
734
+ require_logger.logger_default.logDebug("[spiffy-ai] GA tracking", decoratedEventName);
735
+ if (window.dataLayer) window.dataLayer.push({
736
+ event: decoratedEventName,
737
+ eventProps
738
+ });
739
+ }
740
+ } catch (err) {
741
+ require_logger.logger_default.logError("[spiffy-ai] Error tracking event", err, {
742
+ eventName,
743
+ eventProps
744
+ });
745
+ }
746
+ }, [
747
+ amplitudeClient,
748
+ getDefaultTrackingProps,
749
+ eventPropsToPrefixedEventProps,
750
+ orgGaConfig
751
+ ]);
752
+ const value = (0, react.useMemo)(() => ({
753
+ trackEvent,
754
+ isReady,
755
+ setSupplementalDefaultProps: (props) => setSupplementalDefaultProps(props)
756
+ }), [
757
+ trackEvent,
758
+ isReady,
759
+ setSupplementalDefaultProps
760
+ ]);
761
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AmplitudeContext.Provider, {
762
+ value,
763
+ children
764
+ });
765
+ };
766
+ const useAmplitude = () => {
767
+ const context = (0, react.useContext)(AmplitudeContext);
768
+ if (!context) throw new Error("useAmplitude must be used within AmplitudeProvider");
769
+ return context;
770
+ };
771
+
772
+ //#endregion
773
+ //#region src/application/utils/analyticsUtils.ts
774
+ const NORMALIZED_ADD_TO_CART_EVENT_NAMES = ["addtocart", "addedtocart"];
775
+ const CHECK_DATA_LAYER_INTERVAL_MS = 500;
776
+ const CHECK_DATA_LAYER_MAX_ATTEMPTS = 10;
777
+ /**
778
+ * Checks if a Google Analytics event is an add_to_cart event.
779
+ *
780
+ * @param event The event name to check.
781
+ *
782
+ * @returns True if the event is an add_to_cart event, false otherwise.
783
+ */
784
+ const isAddToCartEvent = (event) => {
785
+ const normalizedEvent = event.replace(/[-_]/g, "").toLowerCase();
786
+ return NORMALIZED_ADD_TO_CART_EVENT_NAMES.some((name) => normalizedEvent.includes(name));
787
+ };
788
+ /**
789
+ * Tracks an add_to_cart event in Amplitude.
790
+ *
791
+ * @param event The event to track.
792
+ */
793
+ const handleAddToCartEvent = (event, track) => {
794
+ let eventProps;
795
+ if (require_models.isLegacyUAEcommerceEvent(event)) eventProps = {
796
+ items: event.ecommerce.add.products.map((product) => ({
797
+ item_name: product.name,
798
+ item_category: product.category,
799
+ price: product.price,
800
+ quantity: product.quantity
801
+ })),
802
+ currency: event.ecommerce.add.currencyCode,
803
+ event_format_version: "legacy_universal_analytics"
804
+ };
805
+ else if (require_models.isGA4EcommerceEvent(event)) eventProps = {
806
+ items: event.ecommerce.items.map((item) => ({
807
+ item_name: item.item_name,
808
+ item_category: item.item_category,
809
+ price: item.price,
810
+ quantity: item.quantity
811
+ })),
812
+ currency: event.ecommerce.currency,
813
+ event_format_version: "google_analytics_4"
814
+ };
815
+ else eventProps = {
816
+ event_properties: { ...event },
817
+ event_format_version: "unknown"
818
+ };
819
+ track(SpiffyMetricsEventName.AddToCartClicked, { eventProps });
820
+ };
821
+ /**
822
+ * Wraps the window.dataLayer.push method to intercept add_to_cart events and send them to Amplitude.
823
+ * This function runs on an interval until the dataLayer is available.
824
+ */
825
+ const initDataLayerWrapper = (track) => {
826
+ let attempts = 0;
827
+ const checkAndInitialize = () => {
828
+ if (!window.dataLayer || !window.dataLayer.push) {
829
+ attempts += 1;
830
+ if (attempts >= CHECK_DATA_LAYER_MAX_ATTEMPTS) {
831
+ require_logger.logger_default.logDebug(`[spiffy-ai] dataLayer not available after ${CHECK_DATA_LAYER_MAX_ATTEMPTS} attempts`);
832
+ return;
833
+ }
834
+ setTimeout(checkAndInitialize, CHECK_DATA_LAYER_INTERVAL_MS);
835
+ return;
836
+ }
837
+ require_logger.logger_default.logDebug("[spiffy-ai] dataLayer is available, wrapping push function...");
838
+ const originalPush = window.dataLayer.push;
839
+ window.dataLayer.push = (...args) => {
840
+ if (require_models.isBaseEcommerceEvent(args[0]) && isAddToCartEvent(args[0].event)) handleAddToCartEvent(args[0], track);
841
+ return originalPush.apply(window.dataLayer, args);
842
+ };
843
+ };
844
+ checkAndInitialize();
845
+ };
846
+ const initAmplitude = (track) => {
847
+ track(SpiffyMetricsEventName.BundleLoaded);
848
+ };
849
+
850
+ //#endregion
851
+ //#region src/application/utils/coreContextToApiContext.ts
852
+ const coreContextToApiContext = (context) => ({
853
+ chat_id: context.chatId,
854
+ org_id: context.orgId,
855
+ user_id: context.userId,
856
+ org_short_name: context.orgShortName,
857
+ source: context.source,
858
+ env: context.env
859
+ });
860
+
861
+ //#endregion
862
+ //#region src/application/utils/coreUserEventToApiUserEvent.ts
863
+ const coreUserEventToApiUserEvent = (data) => {
864
+ if (data.category === __spiffy_ai_commerce_api_client.UserEventCategory.PdpVisit || data.category === __spiffy_ai_commerce_api_client.UserEventCategory.AddToCart) return {
865
+ event_id: data.eventId,
866
+ created_at: data.createdAt,
867
+ category: data.category,
868
+ attributes: {
869
+ product_id: data.attributes.productId,
870
+ parent_product_id: data.attributes.parentProductId,
871
+ url: data.attributes.url
872
+ }
873
+ };
874
+ if (data.category === __spiffy_ai_commerce_api_client.UserEventCategory.PlpVisit) return {
875
+ event_id: data.eventId,
876
+ created_at: data.createdAt,
877
+ category: data.category,
878
+ attributes: {
879
+ category: __spiffy_ai_commerce_api_client.PLPAttributeCategory.Id,
880
+ attributes: { id: data.attributes.attributes.id }
881
+ }
882
+ };
883
+ if (data.category === __spiffy_ai_commerce_api_client.UserEventCategory.QueryTyped) return {
884
+ event_id: data.eventId,
885
+ created_at: data.createdAt,
886
+ category: data.category,
887
+ attributes: { query: data.attributes.query }
888
+ };
889
+ if (data.category === __spiffy_ai_commerce_api_client.UserEventCategory.Search) return {
890
+ event_id: data.eventId,
891
+ created_at: data.createdAt,
892
+ category: data.category,
893
+ attributes: {
894
+ search_term: data.attributes.searchTerm,
895
+ selected_filters: data.attributes.selectedFilters
896
+ }
897
+ };
898
+ if (data.category === __spiffy_ai_commerce_api_client.UserEventCategory.SuggestionClicked) return {
899
+ event_id: data.eventId,
900
+ created_at: data.createdAt,
901
+ category: data.category,
902
+ attributes: { suggestion_id: data.attributes.suggestionId }
903
+ };
904
+ if (data.category === __spiffy_ai_commerce_api_client.UserEventCategory.PageVisit) return {
905
+ event_id: data.eventId,
906
+ created_at: data.createdAt,
907
+ category: data.category,
908
+ attributes: {
909
+ url: data.attributes.url,
910
+ page_visit_category: data.attributes.pageVisitCategory
911
+ }
912
+ };
913
+ if (data.category === __spiffy_ai_commerce_api_client.UserEventCategory.FormSubmitted) return {
914
+ event_id: data.eventId,
915
+ created_at: data.createdAt,
916
+ category: data.category,
917
+ attributes: {
918
+ filled_schema: { ...data.attributes.filledSchema },
919
+ form_response_id: data.attributes.formResponseId,
920
+ form_type: data.attributes.formType
921
+ }
922
+ };
923
+ return {
924
+ event_id: data.eventId,
925
+ created_at: data.createdAt,
926
+ category: data.category
927
+ };
928
+ };
929
+
930
+ //#endregion
931
+ //#region src/application/utils/divideArray.ts
932
+ const divideArray = (array, size) => {
933
+ const rows = [];
934
+ for (let i = 0; i < size; i += 1) rows.push(array.filter((_, index) => index % size === i));
935
+ return rows;
936
+ };
937
+
938
+ //#endregion
939
+ //#region src/application/utils/imageFilter.ts
940
+ const getRecentProductImageUrls = (lastMessages, currentProductId) => {
941
+ const productMessages = lastMessages.filter((message) => message.type === require_dist.MessageType.Product && message.metadata?.imageUrl).map((m) => m);
942
+ return [...productMessages.filter((m) => m.metadata?.id === currentProductId), ...productMessages.filter((m) => m.metadata?.id !== currentProductId)].map((m) => m.metadata.imageUrl);
943
+ };
944
+
945
+ //#endregion
946
+ //#region src/application/utils/merchantUtils.ts
947
+ const prepareMerchantPage = () => {
948
+ let metaViewport = document.querySelector("meta[name='viewport']");
949
+ if (metaViewport) {
950
+ const content = metaViewport.getAttribute("content");
951
+ if (!content?.includes("maximum-scale=1")) metaViewport.setAttribute("content", `${content}, maximum-scale=1`);
952
+ return;
953
+ }
954
+ metaViewport = document.createElement("meta");
955
+ metaViewport.setAttribute("name", "viewport");
956
+ metaViewport.setAttribute("content", "width=device-width, initial-scale=1, maximum-scale=1");
957
+ document.head.appendChild(metaViewport);
958
+ };
959
+
960
+ //#endregion
961
+ //#region src/application/utils/messageFromFormSubmittedEvent.ts
962
+ const messageFromFormSubmittedEvent = (event, formResponseAttributes) => {
963
+ if (event.category !== __spiffy_ai_commerce_api_client.UserEventCategory.FormSubmitted) return;
964
+ const formStringContents = Object.entries(formResponseAttributes.schema.properties).map(([key, value]) => `${value.title}: ${event.attributes.filledSchema[key]}`).join("\n");
965
+ return {
966
+ id: event.eventId,
967
+ role: require_dist.MessageRole.User,
968
+ type: require_dist.MessageType.QueryTyped,
969
+ createdAt: event.createdAt,
970
+ metadata: { content: formStringContents }
971
+ };
972
+ };
973
+
974
+ //#endregion
975
+ //#region src/application/utils/messageFromQueryEvent.ts
976
+ /**
977
+ * Transforms a query UserEvent object into a Message object for presentation.
978
+ *
979
+ * @param event The user event object received from the server
980
+ *
981
+ * @returns A Message if the event is a query event, otherwise undefined
982
+ */
983
+ const messageFromQueryEvent = (event) => {
984
+ if (event.category === __spiffy_ai_commerce_api_client.UserEventCategory.QueryTyped) return {
985
+ id: event.eventId,
986
+ role: require_dist.MessageRole.User,
987
+ type: require_dist.MessageType.QueryTyped,
988
+ createdAt: event.createdAt,
989
+ metadata: { content: event.attributes.query }
990
+ };
991
+ if (event.category === __spiffy_ai_commerce_api_client.UserEventCategory.Search) return {
992
+ id: event.eventId,
993
+ role: require_dist.MessageRole.User,
994
+ type: require_dist.MessageType.Search,
995
+ createdAt: event.createdAt,
996
+ metadata: {
997
+ searchTerm: event.attributes.searchTerm || "",
998
+ selectedFilters: event.attributes.selectedFilters || []
999
+ }
1000
+ };
1001
+ };
1002
+
1003
+ //#endregion
1004
+ //#region src/application/utils/messageFromResponse.ts
1005
+ /**
1006
+ * Transforms a server Response object into a Message object for presentation.
1007
+ *
1008
+ * @param response The response object received from the server containing model generated content
1009
+ *
1010
+ * @returns A Message if the response contains known attributes, undefined otherwise
1011
+ */
1012
+ const messageFromResponse = (response) => {
1013
+ if (response == null) return;
1014
+ if (response.category === __spiffy_ai_commerce_api_client.ResponseCategory.Text) return {
1015
+ id: response.id,
1016
+ createdAt: response.createdAt,
1017
+ type: require_types.MessageType.Text,
1018
+ role: require_types.MessageRole.Assistant,
1019
+ metadata: { content: response.attributes.content }
1020
+ };
1021
+ if (response.category === __spiffy_ai_commerce_api_client.ResponseCategory.Product) return {
1022
+ id: response.id,
1023
+ createdAt: response.createdAt,
1024
+ role: require_types.MessageRole.Assistant,
1025
+ type: require_types.MessageType.Product,
1026
+ metadata: { ...response.attributes }
1027
+ };
1028
+ if (response.category === __spiffy_ai_commerce_api_client.ResponseCategory.Review) return {
1029
+ id: response.id,
1030
+ createdAt: response.createdAt,
1031
+ type: require_types.MessageType.Review,
1032
+ role: require_types.MessageRole.Assistant,
1033
+ metadata: {
1034
+ review: response.attributes.review,
1035
+ reviewer: response.attributes.reviewer,
1036
+ stars: response.attributes.stars,
1037
+ title: response.attributes.title,
1038
+ richInformation: response.attributes.richInformation
1039
+ }
1040
+ };
1041
+ if (response.category === __spiffy_ai_commerce_api_client.ResponseCategory.Separator) return {
1042
+ id: response.id,
1043
+ createdAt: response.createdAt,
1044
+ type: require_types.MessageType.Separator,
1045
+ role: require_types.MessageRole.Assistant
1046
+ };
1047
+ if (response.category === __spiffy_ai_commerce_api_client.ResponseCategory.Page) return {
1048
+ id: response.id,
1049
+ createdAt: response.createdAt,
1050
+ role: require_types.MessageRole.Assistant,
1051
+ type: require_types.MessageType.Page,
1052
+ metadata: { ...response.attributes }
1053
+ };
1054
+ if (response.category === __spiffy_ai_commerce_api_client.ResponseCategory.ProductSearch) return {
1055
+ id: response.id,
1056
+ createdAt: response.createdAt,
1057
+ role: require_types.MessageRole.Assistant,
1058
+ type: require_types.MessageType.ProductSearch,
1059
+ metadata: { ...response.attributes }
1060
+ };
1061
+ if (response.category === __spiffy_ai_commerce_api_client.ResponseCategory.ProductSearchFilter) return {
1062
+ id: response.id,
1063
+ createdAt: response.createdAt,
1064
+ role: require_types.MessageRole.Assistant,
1065
+ type: require_types.MessageType.ProductSearchFilter,
1066
+ metadata: { ...response.attributes }
1067
+ };
1068
+ if (response.category === __spiffy_ai_commerce_api_client.ResponseCategory.Form) return {
1069
+ id: response.id,
1070
+ createdAt: response.createdAt,
1071
+ role: require_types.MessageRole.Assistant,
1072
+ type: require_types.MessageType.Form,
1073
+ metadata: {
1074
+ formType: response.attributes.formCategory?.formType,
1075
+ fields: Object.entries(response.attributes.schema.properties).map(([key, value]) => ({
1076
+ key,
1077
+ title: value.title,
1078
+ type: value.type,
1079
+ format: value.format,
1080
+ required: response.attributes.schema.required.includes(key)
1081
+ }))
1082
+ }
1083
+ };
1084
+ if (response.category === __spiffy_ai_commerce_api_client.ResponseCategory.Order) return {
1085
+ id: response.id,
1086
+ createdAt: response.createdAt,
1087
+ role: require_types.MessageRole.Assistant,
1088
+ type: require_types.MessageType.Order,
1089
+ metadata: { ...response.attributes }
1090
+ };
1091
+ };
1092
+
1093
+ //#endregion
1094
+ //#region src/application/utils/messageFromSuggestionEvent.ts
1095
+ /**
1096
+ * Transforms a UserEvent object into a Message object for presentation.
1097
+ *
1098
+ * @param event The UserEvent object received from the server
1099
+ * @param suggestions A list of generated suggestions to match the event to
1100
+ *
1101
+ * @returns A Message if the event is a suggestion click event, undefined otherwise
1102
+ */
1103
+ const messageFromSuggestionEvent = (event, suggestions) => {
1104
+ if (event.category === __spiffy_ai_commerce_api_client.UserEventCategory.SuggestionClicked) {
1105
+ const { suggestionId } = event.attributes;
1106
+ return {
1107
+ id: event.eventId,
1108
+ role: require_types.MessageRole.User,
1109
+ type: require_types.MessageType.SuggestionClicked,
1110
+ createdAt: event.createdAt,
1111
+ metadata: {
1112
+ suggestionId,
1113
+ suggestionContent: suggestions.find((s) => s.id === suggestionId)?.content ?? ""
1114
+ }
1115
+ };
1116
+ }
1117
+ };
1118
+
1119
+ //#endregion
1120
+ //#region src/application/utils/nextMessageRequestToApiRequest.ts
1121
+ const messageRequestToCommerceMessageRequest = (data) => ({
1122
+ context: {
1123
+ chat_id: data.context.chatId,
1124
+ org_id: data.context.orgId,
1125
+ org_short_name: data.context.orgShortName,
1126
+ user_id: data.context.userId,
1127
+ source: data.context.source,
1128
+ env: data.context.env
1129
+ },
1130
+ id: data.id,
1131
+ feature_flags: data.featureFlags,
1132
+ user_events: data.userEvents?.map((userEvent) => coreUserEventToApiUserEvent(userEvent)),
1133
+ generation_params: {
1134
+ model: data.generationParams?.model,
1135
+ max_tokens: data.generationParams?.maxTokens,
1136
+ stop: data.generationParams?.stop,
1137
+ stream: data.generationParams?.stream,
1138
+ temperature: data.generationParams?.temperature,
1139
+ top_p: data.generationParams?.topP,
1140
+ num_suggestions: data.generationParams?.numSuggestions,
1141
+ response_system_prompt: data.generationParams?.responseSystemPrompt,
1142
+ suggestion_system_prompt: data.generationParams?.suggestionSystemPrompt,
1143
+ response_caching: data.generationParams?.responseCaching
1144
+ }
1145
+ });
1146
+
1147
+ //#endregion
1148
+ //#region src/application/utils/nodeSelector.ts
1149
+ var NodeSelector = class {
1150
+ constructor(pattern) {
1151
+ this.pattern = pattern;
1152
+ this.root = document;
1153
+ }
1154
+ getPattern() {
1155
+ return this.pattern;
1156
+ }
1157
+ setRoot(root) {
1158
+ this.root = root;
1159
+ }
1160
+ getRoot() {
1161
+ return this.root;
1162
+ }
1163
+ };
1164
+ var QuerySelector = class extends NodeSelector {
1165
+ parse() {
1166
+ return this.getRoot().querySelector(this.getPattern());
1167
+ }
1168
+ };
1169
+ var IDSelector = class extends NodeSelector {
1170
+ parse() {
1171
+ return this.getRoot().getElementById(this.getPattern());
1172
+ }
1173
+ };
1174
+ var XpathSelector = class extends NodeSelector {
1175
+ parse() {
1176
+ return this.getRoot()?.evaluate(this.getPattern(), this.getRoot(), null, XPathResult.FIRST_ORDERED_NODE_TYPE, null)?.singleNodeValue;
1177
+ }
1178
+ };
1179
+ var ChainSelector = class extends NodeSelector {
1180
+ parse() {
1181
+ let selectorIndex = 0;
1182
+ const selectors = this.getPattern().split("@");
1183
+ const lastIndex = selectors.length - 1;
1184
+ const parseChain = (pattern, prevNode) => {
1185
+ const selector = SelectorFactory.parse(pattern);
1186
+ if (prevNode) selector.setRoot(prevNode);
1187
+ const currentNode = selector.parse();
1188
+ if (selectorIndex === lastIndex) return currentNode;
1189
+ let node = currentNode || document;
1190
+ if (currentNode?.shadowRoot) node = currentNode.shadowRoot;
1191
+ if (currentNode?.contentWindow) node = currentNode.contentWindow?.document;
1192
+ return parseChain(selectors[++selectorIndex].trim(), node);
1193
+ };
1194
+ return parseChain(selectors[selectorIndex].trim());
1195
+ }
1196
+ };
1197
+ var Empty = class extends NodeSelector {
1198
+ constructor() {
1199
+ super("");
1200
+ }
1201
+ parse() {
1202
+ return null;
1203
+ }
1204
+ };
1205
+ var SelectorFactory = class {
1206
+ static parse(composedSelector) {
1207
+ if (!composedSelector) return new Empty();
1208
+ const split = composedSelector.split("|");
1209
+ const type = split[0];
1210
+ const selector = split[1];
1211
+ switch (type) {
1212
+ case "id": return this.id(selector);
1213
+ case "query": return this.query(selector);
1214
+ case "xpath": return this.xpath(selector);
1215
+ default: return new Empty();
1216
+ }
1217
+ }
1218
+ static check(selector) {
1219
+ return selector ?? new Empty();
1220
+ }
1221
+ static chain(pattern) {
1222
+ return pattern ? new ChainSelector(pattern) : new Empty();
1223
+ }
1224
+ static id(pattern) {
1225
+ return pattern ? new IDSelector(pattern) : new Empty();
1226
+ }
1227
+ static query(pattern) {
1228
+ return pattern ? new QuerySelector(pattern) : new Empty();
1229
+ }
1230
+ static xpath(pattern) {
1231
+ return pattern ? new XpathSelector(pattern) : new Empty();
1232
+ }
1233
+ };
1234
+
1235
+ //#endregion
1236
+ //#region src/application/utils/overrides.ts
1237
+ function isPlainObject(x) {
1238
+ return !!x && typeof x === "object" && !Array.isArray(x) && !(x instanceof Date) && !(x instanceof RegExp);
1239
+ }
1240
+ function isReplace(x) {
1241
+ return !!x && typeof x === "object" && "$replace" in x;
1242
+ }
1243
+ function isDelete(x) {
1244
+ return !!x && typeof x === "object" && x.$delete === true;
1245
+ }
1246
+ function isPrimitiveValue(x) {
1247
+ const t = typeof x;
1248
+ return x === null || t === "string" || t === "number" || t === "boolean" || t === "bigint" || t === "symbol" || t === "undefined";
1249
+ }
1250
+ function isArrayOfPrimitives(arr) {
1251
+ if (arr.length === 0) return false;
1252
+ for (let i = 0; i < arr.length; i += 1) {
1253
+ const v = arr[i];
1254
+ if (v !== void 0 && !isPrimitiveValue(v)) return false;
1255
+ }
1256
+ return true;
1257
+ }
1258
+ function mergeAny(baseAny, patchAny, opts) {
1259
+ if (isReplace(patchAny)) return patchAny.$replace;
1260
+ if (isDelete(patchAny)) return void 0;
1261
+ if (Array.isArray(baseAny)) {
1262
+ if (Array.isArray(patchAny)) {
1263
+ const baseArr = baseAny;
1264
+ const patchArr = patchAny;
1265
+ if (opts.arrayStrategy === "replace" || isArrayOfPrimitives(baseArr) || isArrayOfPrimitives(patchArr)) return patchAny;
1266
+ const out = baseArr.slice();
1267
+ const max = Math.max(out.length, patchArr.length);
1268
+ for (let i = 0; i < max; i += 1) {
1269
+ const pVal = patchArr[i];
1270
+ if (pVal !== void 0) out[i] = mergeAny(out[i], pVal, opts);
1271
+ }
1272
+ return out;
1273
+ }
1274
+ return baseAny;
1275
+ }
1276
+ if (isPlainObject(baseAny) && isPlainObject(patchAny)) {
1277
+ const baseObj = baseAny;
1278
+ const patchObj = patchAny;
1279
+ const out = { ...baseObj };
1280
+ for (const key of Object.keys(patchObj)) {
1281
+ const pVal = patchObj[key];
1282
+ if (pVal === void 0) {} else if (opts.nullDeletes && pVal === null) delete out[key];
1283
+ else if (isReplace(pVal)) out[key] = pVal.$replace;
1284
+ else if (isDelete(pVal)) delete out[key];
1285
+ else out[key] = mergeAny(baseObj?.[key], pVal, opts);
1286
+ }
1287
+ return out;
1288
+ }
1289
+ return patchAny ?? baseAny;
1290
+ }
1291
+ function applyOverrides(base, patch, opts = {}) {
1292
+ const { arrayStrategy = "mergeByIndex", nullDeletes = false } = opts;
1293
+ if (isReplace(patch)) return patch.$replace;
1294
+ if (isDelete(patch)) return void 0;
1295
+ if (Array.isArray(base)) {
1296
+ if (isReplace(patch)) return patch.$replace;
1297
+ if (Array.isArray(patch)) {
1298
+ if (arrayStrategy === "replace") return patch;
1299
+ const out = base.slice();
1300
+ const max = Math.max(out.length, patch.length);
1301
+ for (let i = 0; i < max; i += 1) {
1302
+ const pVal = patch[i];
1303
+ if (pVal !== void 0) out[i] = mergeAny(out[i], pVal, opts);
1304
+ }
1305
+ return out;
1306
+ }
1307
+ return base;
1308
+ }
1309
+ if (isPlainObject(base) && isPlainObject(patch)) {
1310
+ const out = { ...base };
1311
+ const patchObj = patch;
1312
+ for (const key of Object.keys(patchObj)) {
1313
+ const pVal = patchObj[key];
1314
+ if (pVal === void 0) {} else if (nullDeletes && pVal === null) delete out[key];
1315
+ else if (isReplace(pVal)) out[key] = pVal.$replace;
1316
+ else if (isDelete(pVal)) delete out[key];
1317
+ else {
1318
+ const bVal = base[key];
1319
+ out[key] = mergeAny(bVal, pVal, opts);
1320
+ }
1321
+ }
1322
+ return out;
1323
+ }
1324
+ return patch ?? base;
1325
+ }
1326
+
1327
+ //#endregion
1328
+ //#region src/application/utils/stringUtils.ts
1329
+ var StringUtils = class StringUtils {
1330
+ static isNullOrEmpty(value) {
1331
+ const valueTrimmed = value?.trim();
1332
+ return value === void 0 || valueTrimmed === "";
1333
+ }
1334
+ static trimToNull(value) {
1335
+ const valueTrimmed = value?.trim();
1336
+ return StringUtils.isNullOrEmpty(valueTrimmed) ? void 0 : valueTrimmed;
1337
+ }
1338
+ static capitalize(type) {
1339
+ if (type === void 0) return "";
1340
+ return type.charAt(0).toUpperCase() + type.substring(1);
1341
+ }
1342
+ /**
1343
+ * Finds the first pattern in an array that matches a given URL.
1344
+ * Patterns can include a single wildcard '*' which matches any sequence of characters.
1345
+ *
1346
+ * @param patterns
1347
+ * @param urlToTest
1348
+ * @returns
1349
+ */
1350
+ static findMatchingPattern(patterns, urlToTest) {
1351
+ if (!urlToTest) return;
1352
+ for (const pattern of patterns) if (urlToTest.pathname !== "/") {
1353
+ const regexPattern = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
1354
+ if ((/* @__PURE__ */ new RegExp(`^${regexPattern}$`)).test(urlToTest.pathname)) return pattern;
1355
+ } else if (pattern.startsWith(urlToTest.hostname)) return pattern;
1356
+ }
1357
+ };
1358
+
1359
+ //#endregion
1360
+ //#region src/application/utils/supportedEventRequestToApiRequest.ts
1361
+ const coreSupportedEventRequestToApiRequest = (coreSupportedEventRequest) => ({
1362
+ id: coreSupportedEventRequest.id,
1363
+ user_event: coreUserEventToApiUserEvent(coreSupportedEventRequest.userEvent),
1364
+ context: coreContextToApiContext(coreSupportedEventRequest.context)
1365
+ });
1366
+
1367
+ //#endregion
1368
+ //#region src/application/utils/validation.ts
1369
+ const validateEmail = (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
1370
+
1371
+ //#endregion
1372
+ Object.defineProperty(exports, 'AmplitudeProvider', {
1373
+ enumerable: true,
1374
+ get: function () {
1375
+ return AmplitudeProvider;
1376
+ }
1377
+ });
1378
+ Object.defineProperty(exports, 'NodeSelector', {
1379
+ enumerable: true,
1380
+ get: function () {
1381
+ return NodeSelector;
1382
+ }
1383
+ });
1384
+ Object.defineProperty(exports, 'SelectorFactory', {
1385
+ enumerable: true,
1386
+ get: function () {
1387
+ return SelectorFactory;
1388
+ }
1389
+ });
1390
+ Object.defineProperty(exports, 'SpiffyMetricsEventName', {
1391
+ enumerable: true,
1392
+ get: function () {
1393
+ return SpiffyMetricsEventName;
1394
+ }
1395
+ });
1396
+ Object.defineProperty(exports, 'StringUtils', {
1397
+ enumerable: true,
1398
+ get: function () {
1399
+ return StringUtils;
1400
+ }
1401
+ });
1402
+ Object.defineProperty(exports, 'UserIdentityProvider', {
1403
+ enumerable: true,
1404
+ get: function () {
1405
+ return UserIdentityProvider;
1406
+ }
1407
+ });
1408
+ Object.defineProperty(exports, 'appSourceAtom', {
1409
+ enumerable: true,
1410
+ get: function () {
1411
+ return appSourceAtom;
1412
+ }
1413
+ });
1414
+ Object.defineProperty(exports, 'applyOverrides', {
1415
+ enumerable: true,
1416
+ get: function () {
1417
+ return applyOverrides;
1418
+ }
1419
+ });
1420
+ Object.defineProperty(exports, 'chatIdAtom', {
1421
+ enumerable: true,
1422
+ get: function () {
1423
+ return chatIdAtom;
1424
+ }
1425
+ });
1426
+ Object.defineProperty(exports, 'coreContextToApiContext', {
1427
+ enumerable: true,
1428
+ get: function () {
1429
+ return coreContextToApiContext;
1430
+ }
1431
+ });
1432
+ Object.defineProperty(exports, 'coreSupportedEventRequestToApiRequest', {
1433
+ enumerable: true,
1434
+ get: function () {
1435
+ return coreSupportedEventRequestToApiRequest;
1436
+ }
1437
+ });
1438
+ Object.defineProperty(exports, 'coreUserEventToApiUserEvent', {
1439
+ enumerable: true,
1440
+ get: function () {
1441
+ return coreUserEventToApiUserEvent;
1442
+ }
1443
+ });
1444
+ Object.defineProperty(exports, 'divideArray', {
1445
+ enumerable: true,
1446
+ get: function () {
1447
+ return divideArray;
1448
+ }
1449
+ });
1450
+ Object.defineProperty(exports, 'getRecentProductImageUrls', {
1451
+ enumerable: true,
1452
+ get: function () {
1453
+ return getRecentProductImageUrls;
1454
+ }
1455
+ });
1456
+ Object.defineProperty(exports, 'hasParsedVariantInfoAtom', {
1457
+ enumerable: true,
1458
+ get: function () {
1459
+ return hasParsedVariantInfoAtom;
1460
+ }
1461
+ });
1462
+ Object.defineProperty(exports, 'initAmplitude', {
1463
+ enumerable: true,
1464
+ get: function () {
1465
+ return initAmplitude;
1466
+ }
1467
+ });
1468
+ Object.defineProperty(exports, 'initDataLayerWrapper', {
1469
+ enumerable: true,
1470
+ get: function () {
1471
+ return initDataLayerWrapper;
1472
+ }
1473
+ });
1474
+ Object.defineProperty(exports, 'messageFromFormSubmittedEvent', {
1475
+ enumerable: true,
1476
+ get: function () {
1477
+ return messageFromFormSubmittedEvent;
1478
+ }
1479
+ });
1480
+ Object.defineProperty(exports, 'messageFromQueryEvent', {
1481
+ enumerable: true,
1482
+ get: function () {
1483
+ return messageFromQueryEvent;
1484
+ }
1485
+ });
1486
+ Object.defineProperty(exports, 'messageFromResponse', {
1487
+ enumerable: true,
1488
+ get: function () {
1489
+ return messageFromResponse;
1490
+ }
1491
+ });
1492
+ Object.defineProperty(exports, 'messageFromSuggestionEvent', {
1493
+ enumerable: true,
1494
+ get: function () {
1495
+ return messageFromSuggestionEvent;
1496
+ }
1497
+ });
1498
+ Object.defineProperty(exports, 'messageRequestToCommerceMessageRequest', {
1499
+ enumerable: true,
1500
+ get: function () {
1501
+ return messageRequestToCommerceMessageRequest;
1502
+ }
1503
+ });
1504
+ Object.defineProperty(exports, 'prepareMerchantPage', {
1505
+ enumerable: true,
1506
+ get: function () {
1507
+ return prepareMerchantPage;
1508
+ }
1509
+ });
1510
+ Object.defineProperty(exports, 'useAmplitude', {
1511
+ enumerable: true,
1512
+ get: function () {
1513
+ return useAmplitude;
1514
+ }
1515
+ });
1516
+ Object.defineProperty(exports, 'useUserIdentity', {
1517
+ enumerable: true,
1518
+ get: function () {
1519
+ return useUserIdentity;
1520
+ }
1521
+ });
1522
+ Object.defineProperty(exports, 'userIdAtom', {
1523
+ enumerable: true,
1524
+ get: function () {
1525
+ return userIdAtom;
1526
+ }
1527
+ });
1528
+ Object.defineProperty(exports, 'userIdentityAtom', {
1529
+ enumerable: true,
1530
+ get: function () {
1531
+ return userIdentityAtom;
1532
+ }
1533
+ });
1534
+ Object.defineProperty(exports, 'validateEmail', {
1535
+ enumerable: true,
1536
+ get: function () {
1537
+ return validateEmail;
1538
+ }
1539
+ });
1540
+ Object.defineProperty(exports, 'variantInfoAtom', {
1541
+ enumerable: true,
1542
+ get: function () {
1543
+ return variantInfoAtom;
1544
+ }
1545
+ });
1546
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMtQ1B2cU9rMGcuY2pzIiwibmFtZXMiOlsiUmVzcG9uc2VFcnJvciIsIlVuc3VwcG9ydGVkUHJvZHVjdEV4Y2VwdGlvbiIsIlNlc3Npb25SZXN0YXJ0UmVxdWlyZWQiLCJnZXRBdG9tU3RvcmUiLCJiYXNlVXJsQXRvbSIsImNvbmZpZzogQ29uZmlndXJhdGlvbiIsIkNvbmZpZ3VyYXRpb24iLCJEZWZhdWx0QXBpIiwiSW5mZXJlbmNlQXBpIiwiQ3VzdG9tZXJTZXJ2aWNlQXBpIiwib3JnU2hvcnROYW1lQXRvbSIsIm9yZ0lkQXRvbSIsImNvbnRleHRTb3VyY2VBdG9tIiwiZW52QXRvbSIsImZlYXR1cmVGbGFnU2VydmljZUF0b20iLCJjb250ZXh0OiBDb250ZXh0IiwiQ29udGV4dFNvdXJjZUVudW0iLCJDb250ZXh0RW52RW51bSIsInZhbGlkYXRlUmVzcG9uc2UiLCJlcnI6IHVua25vd24iLCJlcnJvcjogdW5rbm93biIsInZhbGlkYXRlU3VnZ2VzdGlvbiIsImRhdGE6IFYxR2V0U2Vzc2lvbk1lc3NhZ2VzMjAwUmVzcG9uc2UiLCJyZXNwb25zZXM6IEFwaVJlc3BvbnNlW11bXSIsInN1Z2dlc3Rpb25zOiBTdWdnZXN0aW9uW10iLCJ1c2VyRXZlbnRzOiBVc2VyRXZlbnRbXSIsInZhbGlkYXRlVXNlckV2ZW50IiwiVXNlckV2ZW50Q2F0ZWdvcnkiLCJhc3Npc3RhbnRNZXNzYWdlczogTWVzc2FnZVtdW10iLCJSZXNwb25zZUNhdGVnb3J5IiwidXNlck1lc3NhZ2VzOiBNZXNzYWdlW11bXSIsIkZvcm1UeXBlIiwiVjFPcmdDb25maWdHZXRTb3VyY2VFbnVtIiwicmVhY3RBcHBOYW1lQXRvbSIsInJlcXVlc3Q6IFYxT3JnQ29uZmlnR2V0UmVxdWVzdCIsIlByb2R1Y3RFeHBlcmltZW50IiwidmFsaWRhdGVPcmdDb25maWdSZXN1bHRzIiwiVUFQYXJzZXIiLCJVc2VySWRlbnRpdHlQcm92aWRlcjogUmVhY3QuRkM8eyBjaGlsZHJlbjogUmVhY3QuUmVhY3ROb2RlIH0+IiwidXNlTG9jYWxTdG9yYWdlIiwiQ29tbWVyY2VBcGlDbGllbnQiLCJzZXNzaW9uU3RvcmFnZVV0aWwiLCJWYXJpYW50VHlwZUVudW0iLCJjb250ZXh0U291cmNlQXRvbSIsIkNvbnRleHRTb3VyY2VFbnVtIiwiQW1wbGl0dWRlUHJvdmlkZXI6IFJlYWN0LkZDPHsgY2hpbGRyZW46IFJlYWN0LlJlYWN0Tm9kZSB9PiIsImFtcGxpdHVkZUFwaUtleUF0b20iLCJkYXRhUmVzaWRlbmN5QXRvbSIsIm9yZ0FuYWx5dGljc0dvb2dsZUFuYWx5dGljc0NvbmZpZ0F0b20iLCJlbnZBdG9tIiwiY29udGV4dFNvdXJjZUF0b20iLCJpZGVudGlmeWluZ1ByZWZpeEF0b20iLCJ1c2VMb2NhbFN0b3JhZ2UiLCJ1c2VFbnZpdmVDb25maWciLCJ1c2VGZWF0dXJlRmxhZ1NlcnZpY2UiLCJSZWFjdCIsIkxvY2FsU3RvcmFnZUtleXMiLCJ2YWx1ZSIsIk9yZ1Nob3J0TmFtZSIsIkZlYXR1cmVHYXRlcyIsImVucmljaG1lbnQ6IEVucmljaG1lbnRQbHVnaW4iLCJlbnJpY2hlZEV2ZW50OiBFdmVudCIsImdsb2JhbFByb3BlcnRpZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4iLCJTcGlmZnlFdmVudCIsImN1cnJlbnRBbXBsaXR1ZGVJbnN0YW5jZTogQnJvd3NlckNsaWVudCIsImV2ZW50UHJvcHM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IiwiaXNMZWdhY3lVQUVjb21tZXJjZUV2ZW50IiwiaXNHQTRFY29tbWVyY2VFdmVudCIsImlzQmFzZUVjb21tZXJjZUV2ZW50IiwiVXNlckV2ZW50Q2F0ZWdvcnkiLCJQTFBBdHRyaWJ1dGVDYXRlZ29yeSIsIk1lc3NhZ2VUeXBlIiwiVXNlckV2ZW50Q2F0ZWdvcnkiLCJNZXNzYWdlUm9sZSIsIk1lc3NhZ2VUeXBlIiwiVXNlckV2ZW50Q2F0ZWdvcnkiLCJNZXNzYWdlUm9sZSIsIk1lc3NhZ2VUeXBlIiwiUmVzcG9uc2VDYXRlZ29yeSIsIk1lc3NhZ2VUeXBlIiwiTWVzc2FnZVJvbGUiLCJVc2VyRXZlbnRDYXRlZ29yeSIsIk1lc3NhZ2VSb2xlIiwiTWVzc2FnZVR5cGUiLCJub2RlOiBOb2RlIHwgbnVsbCB8IHVuZGVmaW5lZCIsIm91dDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4iXSwic291cmNlcyI6WyIuLi9zcmMvYXBwbGljYXRpb24vY29tbWVyY2UtYXBpLnRzIiwiLi4vc3JjL2NvbnRleHRzL3VzZXJJZGVudGl0eUNvbnRleHQvdXNlcklkZW50aXR5Q29udGV4dC50c3giLCIuLi9zcmMvYXRvbXMvYXBwL3ZhcmlhbnQudHMiLCIuLi9zcmMvYXRvbXMvYXBwL2luZGV4LnRzIiwiLi4vc3JjL2NvbnRleHRzL2FtcGxpdHVkZUNvbnRleHQvYW1wbGl0dWRlQ29udGV4dC50c3giLCIuLi9zcmMvYXBwbGljYXRpb24vdXRpbHMvYW5hbHl0aWNzVXRpbHMudHMiLCIuLi9zcmMvYXBwbGljYXRpb24vdXRpbHMvY29yZUNvbnRleHRUb0FwaUNvbnRleHQudHMiLCIuLi9zcmMvYXBwbGljYXRpb24vdXRpbHMvY29yZVVzZXJFdmVudFRvQXBpVXNlckV2ZW50LnRzIiwiLi4vc3JjL2FwcGxpY2F0aW9uL3V0aWxzL2RpdmlkZUFycmF5LnRzIiwiLi4vc3JjL2FwcGxpY2F0aW9uL3V0aWxzL2ltYWdlRmlsdGVyLnRzIiwiLi4vc3JjL2FwcGxpY2F0aW9uL3V0aWxzL21lcmNoYW50VXRpbHMudHMiLCIuLi9zcmMvYXBwbGljYXRpb24vdXRpbHMvbWVzc2FnZUZyb21Gb3JtU3VibWl0dGVkRXZlbnQudHMiLCIuLi9zcmMvYXBwbGljYXRpb24vdXRpbHMvbWVzc2FnZUZyb21RdWVyeUV2ZW50LnRzIiwiLi4vc3JjL2FwcGxpY2F0aW9uL3V0aWxzL21lc3NhZ2VGcm9tUmVzcG9uc2UudHMiLCIuLi9zcmMvYXBwbGljYXRpb24vdXRpbHMvbWVzc2FnZUZyb21TdWdnZXN0aW9uRXZlbnQudHMiLCIuLi9zcmMvYXBwbGljYXRpb24vdXRpbHMvbmV4dE1lc3NhZ2VSZXF1ZXN0VG9BcGlSZXF1ZXN0LnRzIiwiLi4vc3JjL2FwcGxpY2F0aW9uL3V0aWxzL25vZGVTZWxlY3Rvci50cyIsIi4uL3NyYy9hcHBsaWNhdGlvbi91dGlscy9vdmVycmlkZXMudHMiLCIuLi9zcmMvYXBwbGljYXRpb24vdXRpbHMvc3RyaW5nVXRpbHMudHMiLCIuLi9zcmMvYXBwbGljYXRpb24vdXRpbHMvc3VwcG9ydGVkRXZlbnRSZXF1ZXN0VG9BcGlSZXF1ZXN0LnRzIiwiLi4vc3JjL2FwcGxpY2F0aW9uL3V0aWxzL3ZhbGlkYXRpb24udHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29udGV4dCxcbiAgQ29udGV4dEVudkVudW0sXG4gIENvbmZpZ3VyYXRpb24sXG4gIEN1c3RvbWVyU2VydmljZUFwaSxcbiAgRGVmYXVsdEFwaSxcbiAgSW5mZXJlbmNlQXBpLFxuICBSZXBvcnRTZXNzaW9uUmVxdWVzdCxcbiAgUmVzcG9uc2VFcnJvcixcbiAgVXNlckV2ZW50Q2F0ZWdvcnksXG4gIFYxR2V0U2Vzc2lvbk1lc3NhZ2VzMjAwUmVzcG9uc2UsXG4gIFYxT3JnQ29uZmlnR2V0UmVxdWVzdCxcbiAgQ29udGV4dFNvdXJjZUVudW0sXG4gIFYxT3JnQ29uZmlnR2V0U291cmNlRW51bSxcbiAgQ3VzdG9tZXJTZXJ2aWNlUHJvdmlkZXIsXG4gIFJlc3BvbnNlQ2F0ZWdvcnksXG4gIEZvcm1UeXBlLFxufSBmcm9tIFwiQHNwaWZmeS1haS9jb21tZXJjZS1hcGktY2xpZW50XCI7XG5pbXBvcnQge1xuICBTdXBwb3J0ZWRFdmVudCxcbiAgUHJvZHVjdEV4cGVyaW1lbnQsXG4gIENsaWVudERldGFpbHMsXG4gIFVzZXJFdmVudCxcbiAgTmV4dE1lc3NhZ2VSZXF1ZXN0LFxuICBTdXBwb3J0ZWRFdmVudFJlcXVlc3QsXG4gIE9yZ0NvbmZpZyxcbn0gZnJvbSBcIkBlbnZpdmUtYWkvdHlwZXNcIjtcbmltcG9ydCB7IEFwaVJlc3BvbnNlLCBNZXNzYWdlLCBTdWdnZXN0aW9uIH0gZnJvbSBcInNyYy90eXBlc1wiO1xuaW1wb3J0IHsgdXNlcklkQXRvbSwgY2hhdElkQXRvbSB9IGZyb20gXCJzcmMvYXRvbXMvYXBwXCI7XG5pbXBvcnQgeyBnZXRBdG9tU3RvcmUgfSBmcm9tIFwic3JjL2F0b21zL2F0b21TdG9yZVwiO1xuaW1wb3J0IHtcbiAgYmFzZVVybEF0b20sXG4gIG9yZ1Nob3J0TmFtZUF0b20sXG4gIGNvbnRleHRTb3VyY2VBdG9tLFxuICBlbnZBdG9tLFxuICByZWFjdEFwcE5hbWVBdG9tLFxufSBmcm9tIFwic3JjL2F0b21zL2Vudml2ZS9lbnZpdmVDb25maWdcIjtcbmltcG9ydCB7IG9yZ0lkQXRvbSwgZmVhdHVyZUZsYWdTZXJ2aWNlQXRvbSB9IGZyb20gXCJzcmMvYXRvbXMvb3JnXCI7XG5pbXBvcnQge1xuICBVbnN1cHBvcnRlZFByb2R1Y3RFeGNlcHRpb24sXG4gIFNlc3Npb25SZXN0YXJ0UmVxdWlyZWQsXG59IGZyb20gXCJzcmMvZXhjZXB0aW9uc1wiO1xuaW1wb3J0IExvZ2dlciBmcm9tIFwiLi9sb2dnaW5nL2xvZ2dlclwiO1xuaW1wb3J0IHtcbiAgdmFsaWRhdGVSZXNwb25zZSxcbiAgdmFsaWRhdGVTdWdnZXN0aW9uLFxuICB2YWxpZGF0ZVVzZXJFdmVudCxcbiAgdmFsaWRhdGVPcmdDb25maWdSZXN1bHRzLFxufSBmcm9tIFwiLi9tb2RlbHNcIjtcbmltcG9ydCB7XG4gIG1lc3NhZ2VSZXF1ZXN0VG9Db21tZXJjZU1lc3NhZ2VSZXF1ZXN0LFxuICBtZXNzYWdlRnJvbVJlc3BvbnNlLFxuICBtZXNzYWdlRnJvbVF1ZXJ5RXZlbnQsXG4gIG1lc3NhZ2VGcm9tU3VnZ2VzdGlvbkV2ZW50LFxuICBtZXNzYWdlRnJvbUZvcm1TdWJtaXR0ZWRFdmVudCxcbiAgY29yZVN1cHBvcnRlZEV2ZW50UmVxdWVzdFRvQXBpUmVxdWVzdCxcbn0gZnJvbSBcIi4vdXRpbHNcIjtcblxuYXN5bmMgZnVuY3Rpb24gZXJyb3JSZXNwb25zZUJvZHkoZXJyb3I6IFJlc3BvbnNlRXJyb3IpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgZXJyb3IucmVzcG9uc2UuanNvbigpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4ge307XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gdGhyb3dTZXNzaW9uUmVzdGFydFJlcXVpcmVkSWYoZXJyb3JNc2c6IHN0cmluZywgZXJyb3I6IHVua25vd24pIHtcbiAgaWYgKCEoZXJyb3IgaW5zdGFuY2VvZiBSZXNwb25zZUVycm9yKSkge1xuICAgIExvZ2dlci5sb2dJbmZvKGVycm9yTXNnLCBlcnJvcik7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cblxuICBjb25zdCBlcnJvclJlc3BvbnNlID0gYXdhaXQgZXJyb3JSZXNwb25zZUJvZHkoZXJyb3IpO1xuICBpZiAoXG4gICAgZXJyb3JSZXNwb25zZT8ubWVzc2FnZT8udG9Mb3dlckNhc2UoKSA9PT0gXCJ1bnN1cHBvcnRlZCBwcm9kdWN0XCIgfHwgLy8gZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkuIG5ld2VyIHZlcnNpb25zIG9mIHRoZSBBUEkgcmV0dXJuIHN1Yl9jb2RlIGluc3RlYWQgb2YgbWVzc2FnZVxuICAgIGVycm9yUmVzcG9uc2U/LmFwcF9jb2RlPy50b1VwcGVyQ2FzZSgpID09PSBcIlBST0RVQ1RfTk9UX0ZPVU5EXCJcbiAgKSB7XG4gICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkUHJvZHVjdEV4Y2VwdGlvbigpO1xuICB9IGVsc2UgaWYgKFxuICAgIGVycm9yUmVzcG9uc2U/LmFwcF9jb2RlPy50b1VwcGVyQ2FzZSgpID09PSBcIlJFU1RBUlRfU0VTU0lPTlwiIHx8XG4gICAgZXJyb3JSZXNwb25zZT8uc3ViX2NvZGU/LnRvVXBwZXJDYXNlKCkgPT09IFwiTk9UX0ZPVU5EXCIgLy8gZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkuIG5ldyBBUEkgcmVzcG9uc2VzIHdpbGwgY29udGFpbiBcImFwcF9jb2RlXCJcbiAgKSB7XG4gICAgTG9nZ2VyLmxvZ0luZm8oXG4gICAgICBcIlNlc3Npb24gZG9lcyBub3QgZXhpc3QuIFJlLXN0YXJ0IHNlc3Npb25cIixcbiAgICAgIGVycm9yLFxuICAgICAgZXJyb3IucmVzcG9uc2UsXG4gICAgICBlcnJvclJlc3BvbnNlXG4gICAgKTtcbiAgICB0aHJvdyBuZXcgU2Vzc2lvblJlc3RhcnRSZXF1aXJlZCgpO1xuICB9XG5cbiAgTG9nZ2VyLmxvZ0luZm8oZXJyb3JNc2csIGVycm9yKTtcbiAgdGhyb3cgZXJyb3I7XG59XG5cbmNsYXNzIENvbW1lcmNlQXBpQ2xpZW50IHtcbiAgcHJpdmF0ZSByZWFkb25seSBkZWZhdWx0QXBpOiBEZWZhdWx0QXBpO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgY3VzdG9tZXJTZXJ2aWNlQXBpOiBDdXN0b21lclNlcnZpY2VBcGk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBpbmZlcmVuY2VBcGk6IEluZmVyZW5jZUFwaTtcblxuICBwcml2YXRlIHN0YXRpYyBpbnN0YW5jZTogQ29tbWVyY2VBcGlDbGllbnQgfCB1bmRlZmluZWQ7XG5cbiAgcHJpdmF0ZSBzdWdnZXN0aW9uc0Fib3J0Q29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcblxuICBwcml2YXRlIHJlc3BvbnNlc0Fib3J0Q29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcblxuICBwcml2YXRlIHN0YXRpYyBnZXRJbnN0YW5jZSA9ICgpOiBDb21tZXJjZUFwaUNsaWVudCA9PiB7XG4gICAgaWYgKCFDb21tZXJjZUFwaUNsaWVudC5pbnN0YW5jZSkge1xuICAgICAgQ29tbWVyY2VBcGlDbGllbnQuaW5zdGFuY2UgPSBuZXcgQ29tbWVyY2VBcGlDbGllbnQoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gQ29tbWVyY2VBcGlDbGllbnQuaW5zdGFuY2U7XG4gIH07XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihiYXNlUGF0aD86IHN0cmluZykge1xuICAgIGNvbnN0IGF0b21TdG9yZSA9IGdldEF0b21TdG9yZSgpO1xuICAgIGNvbnN0IGJhc2VVcmwgPSBhdG9tU3RvcmUuZ2V0KGJhc2VVcmxBdG9tKTtcbiAgICBjb25zdCBwYXRoID0gYmFzZVBhdGggfHwgYmFzZVVybDtcbiAgICAvLyBBUEkgS2V5IGlzIG5vdyBoYW5kbGVkIGF0IHRoZSBFbnZpdmVDb25maWdQcm92aWRlciBsZXZlbFxuICAgIGNvbnN0IGNvbmZpZzogQ29uZmlndXJhdGlvbiA9IG5ldyBDb25maWd1cmF0aW9uKHtcbiAgICAgIGJhc2VQYXRoOiBwYXRoLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICBcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICAgICAgQWNjZXB0OiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgdGhpcy5kZWZhdWx0QXBpID0gbmV3IERlZmF1bHRBcGkoY29uZmlnKTtcbiAgICB0aGlzLmluZmVyZW5jZUFwaSA9IG5ldyBJbmZlcmVuY2VBcGkoY29uZmlnKTtcbiAgICB0aGlzLmN1c3RvbWVyU2VydmljZUFwaSA9IG5ldyBDdXN0b21lclNlcnZpY2VBcGkoY29uZmlnKTtcbiAgfVxuXG4gIHN0YXRpYyByZXNvbHZlVXJsID0gYXN5bmMgKHVybDogc3RyaW5nKSA9PiB7XG4gICAgY29uc3QgYXRvbVN0b3JlID0gZ2V0QXRvbVN0b3JlKCk7XG4gICAgY29uc3Qgb3JnU2hvcnROYW1lID0gYXRvbVN0b3JlLmdldChvcmdTaG9ydE5hbWVBdG9tKTtcbiAgICBjb25zdCBvcmdJZCA9IGF0b21TdG9yZS5nZXQob3JnSWRBdG9tKTtcbiAgICBjb25zdCB1c2VySWQgPSBhdG9tU3RvcmUuZ2V0KHVzZXJJZEF0b20pO1xuICAgIGNvbnN0IGNoYXRJZCA9IGF0b21TdG9yZS5nZXQoY2hhdElkQXRvbSk7XG4gICAgY29uc3Qgc291cmNlID0gYXRvbVN0b3JlLmdldChjb250ZXh0U291cmNlQXRvbSk7XG4gICAgY29uc3QgZW52ID0gYXRvbVN0b3JlLmdldChlbnZBdG9tKTtcblxuICAgIGNvbnN0IGZlYXR1cmVGbGFnU2VydmljZSA9IGF0b21TdG9yZS5nZXQoZmVhdHVyZUZsYWdTZXJ2aWNlQXRvbSk7XG5cbiAgICBjb25zdCBjb250ZXh0OiBDb250ZXh0ID0ge1xuICAgICAgdXNlcl9pZDogdXNlcklkID8/IFwiXCIsXG4gICAgICBvcmdfaWQ6IG9yZ0lkID8/IFwiXCIsXG4gICAgICBvcmdfc2hvcnRfbmFtZTogb3JnU2hvcnROYW1lID8/IFwiXCIsXG4gICAgICBjaGF0X2lkOiBjaGF0SWQgPz8gXCJcIixcbiAgICAgIHNvdXJjZTogc291cmNlID8/IENvbnRleHRTb3VyY2VFbnVtLkFwcCxcbiAgICAgIGVudjogKGVudiBhcyBDb250ZXh0RW52RW51bSkgPz8gQ29udGV4dEVudkVudW0uRGV2LCAvLyBDYXN0IGVudiB0byBDb250ZXh0RW52RW51bVxuICAgIH07XG5cbiAgICBjb25zdCBmZWF0dXJlR2F0ZXMgPVxuICAgICAgZmVhdHVyZUZsYWdTZXJ2aWNlPy5mZWF0dXJlRmxhZ1NlcnZpY2U/LmdldEZlYXR1cmVGbGFncygpIHx8IHt9O1xuICAgIGNvbnN0IHVybFJlc29sdmluZ1JlcXVlc3QgPSB7XG4gICAgICB1cmwsXG4gICAgICBjb250ZXh0LFxuICAgICAgZmVhdHVyZV9nYXRlczogZmVhdHVyZUdhdGVzLFxuICAgIH07XG5cbiAgICBjb25zdCByYXdSZXNwb25zZSA9XG4gICAgICBhd2FpdCBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLmluZmVyZW5jZUFwaS52MVVybFJlc29sdmluZ1Bvc3RSYXcoe1xuICAgICAgICBVcmxSZXNvbHZpbmdSZXF1ZXN0OiB1cmxSZXNvbHZpbmdSZXF1ZXN0LFxuICAgICAgfSk7XG5cbiAgICBjb25zdCByZXNwb25zZUJvZHkgPSBhd2FpdCByYXdSZXNwb25zZS5yYXcuanNvbigpO1xuXG4gICAgcmV0dXJuIHJlc3BvbnNlQm9keTtcbiAgfTtcblxuICBzdGF0aWMgcmVwb3J0U2Vzc2lvbiA9IGFzeW5jIChcbiAgICByZXBvcnRSZXF1ZXN0OiBSZXBvcnRTZXNzaW9uUmVxdWVzdFxuICApOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICBhd2FpdCBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLmRlZmF1bHRBcGkudjFDaGF0c1JlcG9ydFNlc3Npb25JZFBvc3QoXG4gICAgICB7XG4gICAgICAgIFJlcG9ydFNlc3Npb25SZXF1ZXN0OiByZXBvcnRSZXF1ZXN0LFxuICAgICAgfVxuICAgICk7XG4gIH07XG5cbiAgc3RhdGljIGdldE5leHRSZXNwb25zZXMgPSBhc3luYyAoXG4gICAgcGF5bG9hZDogTmV4dE1lc3NhZ2VSZXF1ZXN0XG4gICk6IFByb21pc2U8TWVzc2FnZVtdPiA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID1cbiAgICAgICAgYXdhaXQgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5pbmZlcmVuY2VBcGkudjFOZXh0UmVzcG9uc2VzUG9zdCh7XG4gICAgICAgICAgTmV4dE1lc3NhZ2VSZXF1ZXN0OiBtZXNzYWdlUmVxdWVzdFRvQ29tbWVyY2VNZXNzYWdlUmVxdWVzdChwYXlsb2FkKSxcbiAgICAgICAgfSk7XG4gICAgICBjb25zdCBtZXNzYWdlcyA9IHJlc3BvbnNlXG4gICAgICAgIC5tYXAoKHJlc3ApID0+IHZhbGlkYXRlUmVzcG9uc2UocmVzcCkpXG4gICAgICAgIC5tYXAoKHJlc3ApID0+IG1lc3NhZ2VGcm9tUmVzcG9uc2UocmVzcCkpO1xuXG4gICAgICByZXR1cm4gbWVzc2FnZXMuZmlsdGVyKChtKTogbSBpcyBNZXNzYWdlID0+IG0gIT0gbnVsbCk7XG4gICAgfSBjYXRjaCAoZXJyOiB1bmtub3duKSB7XG4gICAgICBMb2dnZXIubG9nSW5mbyhcIkZhaWxlZCB0byBnZXQgbmV4dCByZXNwb25zZXNcIiwgZXJyLCB7XG4gICAgICAgIHBheWxvYWRDb250ZXh0OiBwYXlsb2FkPy5jb250ZXh0LFxuICAgICAgICB1c2VyRXZlbnRzOiBwYXlsb2FkPy51c2VyRXZlbnRzLFxuICAgICAgfSk7XG4gICAgICBhd2FpdCB0aHJvd1Nlc3Npb25SZXN0YXJ0UmVxdWlyZWRJZihcIkZhaWxlZCB0byBnZXQgbmV4dCByZXNwb25zZXNcIiwgZXJyKTtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gIH07XG5cbiAgc3RhdGljIGdldE5leHRSZXNwb25zZVN0cmVhbWluZyA9IChcbiAgICBwYXlsb2FkOiBOZXh0TWVzc2FnZVJlcXVlc3RcbiAgKTogQXN5bmNHZW5lcmF0b3I8QXBpUmVzcG9uc2UsIHZvaWQsIHVua25vd24+ID0+IHtcbiAgICBhc3luYyBmdW5jdGlvbiogZ2VuZXJhdGUoXG4gICAgICBpbmZlcmVuY2VBcGk6IEluZmVyZW5jZUFwaSxcbiAgICAgIGFib3J0Q29udHJvbGxlcjogQWJvcnRDb250cm9sbGVyXG4gICAgKSB7XG4gICAgICAvLyBtYWtlIHN1cmUgc3RyZWFtaW5nIGlzIGVuYWJsZWRcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgaW5mZXJlbmNlQXBpLnYxTmV4dFJlc3BvbnNlc1Bvc3RSYXcoXG4gICAgICAgICAge1xuICAgICAgICAgICAgTmV4dE1lc3NhZ2VSZXF1ZXN0OiBtZXNzYWdlUmVxdWVzdFRvQ29tbWVyY2VNZXNzYWdlUmVxdWVzdChwYXlsb2FkKSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHsgc2lnbmFsOiBhYm9ydENvbnRyb2xsZXIuc2lnbmFsIH1cbiAgICAgICAgKTtcblxuICAgICAgICAvLyBSZWFkIHRoZSByZXNwb25zZSBhcyBhIHN0cmVhbSBvZiBkYXRhXG4gICAgICAgIGlmICghcmVzcG9uc2UucmF3LmJvZHkpIHtcbiAgICAgICAgICBMb2dnZXIubG9nRXJyb3IoXG4gICAgICAgICAgICBcIltzcGlmZnktYWldIE5vIGJvZHkgaW4gdGhlIHN0cmVhbWVkIHJlc3BvbnNlXCIsXG4gICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHJlc3BvbnNlOiByZXNwb25zZS5yYXcsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZWFkZXIgPSByZXNwb25zZS5yYXcuYm9keS5nZXRSZWFkZXIoKTtcbiAgICAgICAgY29uc3QgZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcihcInV0Zi04XCIpO1xuXG4gICAgICAgIGxldCBwYXJ0aWFsID0gXCJcIjtcbiAgICAgICAgLy8gVE9ETyB0aGlzIGZ1bmN0aW9uIGlzIHJlY3JlYXRlZCBldmVyeSB0aW1lIG5ldyBkYXRhIGNvbWVzIGZyb20gdGhlIHN0cmVhbSAtIGRlZmluZSBpdCBvdXRzaWRlIG9mIHRoZSBnZW5lcmF0b3JcbiAgICAgICAgY29uc3Qgc2FmZVBhcnNlID0gKGxpbmU6IHN0cmluZyk6IHVua25vd24gPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShsaW5lKTsgLy8gUGFyc2UgdGhlIEpTT04gc3RyaW5nXG4gICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBMb2dnZXIubG9nRXJyb3IoXCJbc3BpZmZ5LWFpXSBFcnJvciBwYXJzaW5nIHN0cmVhbWVkIGxpbmVcIiwgZXJyLCB7XG4gICAgICAgICAgICAgIGxpbmUsXG4gICAgICAgICAgICAgIHBhcnRpYWwsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIHN3YWxsb3cgdGhlIGVycm9yIGFuZCBzZXQgdGhlIHBhcnRpYWwgdG8gb3VyIGN1cnJlbnQgY2h1bmtcbiAgICAgICAgICAgIHBhcnRpYWwgPSBsaW5lO1xuICAgICAgICAgICAgcmV0dXJuIHBhcnRpYWw7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFRPRE8gdGhpcyBmdW5jdGlvbiBpcyByZWNyZWF0ZWQgZXZlcnkgdGltZSBuZXcgZGF0YSBjb21lcyBmcm9tIHRoZSBzdHJlYW0gLSBkZWZpbmUgaXQgb3V0c2lkZSBvZiB0aGUgZ2VuZXJhdG9yXG4gICAgICAgIGNvbnN0IHByb2Nlc3NDaHVuayA9IChjaHVuazogc3RyaW5nKTogdW5rbm93bltdID0+IHtcbiAgICAgICAgICAvLyBtZXJnZSB0aGUgcGFydGlhbCB3aXRoIHRoZSBpbmNvbWluZyBjaHVua1xuICAgICAgICAgIGNvbnN0IGxpbmVzID0gYCR7cGFydGlhbH0ke2NodW5rfWAuc3BsaXQoXCJcXG5cIik7XG5cbiAgICAgICAgICBjb25zdCBwYXJzZWRMaW5lcyA9IGxpbmVzXG4gICAgICAgICAgICAubWFwKChsaW5lKSA9PiBsaW5lLnJlcGxhY2UoL15kYXRhOiAvLCBcIlwiKS50cmltKCkpIC8vIFJlbW92ZSB0aGUgXCJkYXRhOiBcIiBwcmVmaXhcbiAgICAgICAgICAgIC5maWx0ZXIoKGxpbmUpID0+IGxpbmUgIT09IFwiXCIgJiYgbGluZSAhPT0gXCJbRE9ORV1cIikgLy8gUmVtb3ZlIGVtcHR5IGxpbmVzIGFuZCBcIltET05FXVwiXG4gICAgICAgICAgICAubWFwKHNhZmVQYXJzZSlcbiAgICAgICAgICAgIC5maWx0ZXIoKHYpID0+IHYpOyAvLyBhbmQgZmlsdGVyIG91dCB0aGUgdW5kZWZpbmVkIHZhbHVlc1xuICAgICAgICAgIHJldHVybiBwYXJzZWRMaW5lcztcbiAgICAgICAgfTtcblxuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hd2FpdC1pbi1sb29wXG4gICAgICAgICAgY29uc3QgeyBkb25lLCB2YWx1ZSB9ID0gYXdhaXQgcmVhZGVyLnJlYWQoKTtcblxuICAgICAgICAgIGlmIChkb25lKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBNYXNzYWdlIGFuZCBwYXJzZSB0aGUgY2h1bmsgb2YgZGF0YVxuICAgICAgICAgIGNvbnN0IGNodW5rID0gZGVjb2Rlci5kZWNvZGUodmFsdWUpO1xuICAgICAgICAgIGNvbnN0IHBhcnNlZExpbmVzID0gcHJvY2Vzc0NodW5rKGNodW5rKTtcblxuICAgICAgICAgIGZvciAoY29uc3QgcGFyc2VkTGluZSBvZiBwYXJzZWRMaW5lcykge1xuICAgICAgICAgICAgY29uc3QgdmFsaWRhdGVkUmVzcG9uc2UgPSB2YWxpZGF0ZVJlc3BvbnNlKHBhcnNlZExpbmUpO1xuXG4gICAgICAgICAgICBpZiAodmFsaWRhdGVkUmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgeWllbGQgdmFsaWRhdGVkUmVzcG9uc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICBMb2dnZXIubG9nRXJyb3IoXG4gICAgICAgICAgXCJbc3BpZmZ5LWFpXSBGYWlsZWQgdG8gZ2V0IG5leHQgc3RyZWFtaW5nIHJlc3BvbnNlc1wiLFxuICAgICAgICAgIGVycm9yLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHBheWxvYWRDb250ZXh0OiBwYXlsb2FkPy5jb250ZXh0LFxuICAgICAgICAgICAgdXNlckV2ZW50czogcGF5bG9hZD8udXNlckV2ZW50cyxcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIGF3YWl0IHRocm93U2Vzc2lvblJlc3RhcnRSZXF1aXJlZElmKFxuICAgICAgICAgIFwiRmFpbGVkIHRvIGdldCBuZXh0IHN0cmVhbWluZyByZXNwb25zZXNcIixcbiAgICAgICAgICBlcnJvclxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIENvbW1lcmNlQXBpQ2xpZW50LmdldEluc3RhbmNlKCkucmVzcG9uc2VzQWJvcnRDb250cm9sbGVyLmFib3J0KCk7XG4gICAgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5yZXNwb25zZXNBYm9ydENvbnRyb2xsZXIgPVxuICAgICAgbmV3IEFib3J0Q29udHJvbGxlcigpO1xuXG4gICAgcmV0dXJuIGdlbmVyYXRlKFxuICAgICAgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5pbmZlcmVuY2VBcGksXG4gICAgICBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLnJlc3BvbnNlc0Fib3J0Q29udHJvbGxlclxuICAgICk7XG4gIH07XG5cbiAgc3RhdGljIGdldE5leHRTdWdnZXN0aW9ucyA9IGFzeW5jIChcbiAgICBwYXlsb2FkOiBOZXh0TWVzc2FnZVJlcXVlc3RcbiAgKTogUHJvbWlzZTxTdWdnZXN0aW9uW10+ID0+IHtcbiAgICB0cnkge1xuICAgICAgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5zdWdnZXN0aW9uc0Fib3J0Q29udHJvbGxlci5hYm9ydCgpO1xuICAgICAgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5zdWdnZXN0aW9uc0Fib3J0Q29udHJvbGxlciA9XG4gICAgICAgIG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPVxuICAgICAgICBhd2FpdCBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLmluZmVyZW5jZUFwaS52MU5leHRTdWdnZXN0aW9uc1Bvc3QoXG4gICAgICAgICAge1xuICAgICAgICAgICAgTmV4dE1lc3NhZ2VSZXF1ZXN0OiBtZXNzYWdlUmVxdWVzdFRvQ29tbWVyY2VNZXNzYWdlUmVxdWVzdChwYXlsb2FkKSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHNpZ25hbDpcbiAgICAgICAgICAgICAgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5zdWdnZXN0aW9uc0Fib3J0Q29udHJvbGxlci5zaWduYWwsXG4gICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICBjb25zdCBzdWdnZXN0aW9ucyA9IHJlc3BvbnNlXG4gICAgICAgIC5tYXAoKHJlc3ApID0+IHZhbGlkYXRlU3VnZ2VzdGlvbihyZXNwKSlcbiAgICAgICAgLmZpbHRlcigoc3VnZ2VzdGlvbik6IHN1Z2dlc3Rpb24gaXMgU3VnZ2VzdGlvbiA9PiBzdWdnZXN0aW9uICE9IG51bGwpO1xuXG4gICAgICByZXR1cm4gc3VnZ2VzdGlvbnM7XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIExvZ2dlci5sb2dJbmZvKFwiRmFpbGVkIHRvIGdldCBzdWdnZXN0aW9uc1wiLCBlcnJvciwge1xuICAgICAgICBwYXlsb2FkQ29udGV4dDogcGF5bG9hZD8uY29udGV4dCxcbiAgICAgICAgdXNlckV2ZW50czogcGF5bG9hZD8udXNlckV2ZW50cyxcbiAgICAgIH0pO1xuXG4gICAgICBhd2FpdCB0aHJvd1Nlc3Npb25SZXN0YXJ0UmVxdWlyZWRJZihcIkZhaWxlZCB0byBnZXQgc3VnZ2VzdGlvbnNcIiwgZXJyb3IpO1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogRmV0Y2hlcyB0aGUgZXhpc3RpbmcgY2hhdCBkYXRhIGZvciBhIGdpdmVuIHNlc3Npb24gYW5kIHRyYW5zZm9ybXMgdGhlbSB0byByZWNvbnN0cnVjdCB0aGUgY2hhdCBoaXN0b3J5LlxuICAgKlxuICAgKiBAcGFyYW0gb3JnSWQgVGhlIG9yZ2FuaXphdGlvbiBJZFxuICAgKiBAcGFyYW0gY2hhdElkIFRoZSBleGlzdGluZyBjaGF0IElkXG4gICAqIEBwYXJhbSB1c2VySWQgVGhlIHVzZXIgSWRcbiAgICpcbiAgICogQHJldHVybnMgQSBsaXN0IG9mIG1lc3NhZ2VzIHRoYXQgd2VyZSBleGNoYW5nZWQgaW4gdGhlIGNoYXQsIHRocm93cyBhbiBlcnJvciBpZiB0aGUgY2hhdCBzZXNzaW9uIGhhcyBleHBpcmVkLlxuICAgKi9cbiAgc3RhdGljIGdldFJlc3BvbnNlcyA9IGFzeW5jIChcbiAgICBvcmdJZDogc3RyaW5nLFxuICAgIGNoYXRJZDogc3RyaW5nLFxuICAgIHVzZXJJZDogc3RyaW5nXG4gICk6IFByb21pc2U8e1xuICAgIHJlc3BvbnNlczogQXBpUmVzcG9uc2VbXVtdO1xuICAgIHVzZXJFdmVudHM6IFVzZXJFdmVudFtdO1xuICAgIHN1Z2dlc3Rpb25zOiBTdWdnZXN0aW9uW107XG4gICAgbWVzc2FnZXM6IE1lc3NhZ2VbXVtdO1xuICB9PiA9PiB7XG4gICAgbGV0IGRhdGE6IFYxR2V0U2Vzc2lvbk1lc3NhZ2VzMjAwUmVzcG9uc2UgPSB7XG4gICAgICByZXNwb25zZXM6IFtdLFxuICAgICAgc3VnZ2VzdGlvbnM6IFtdLFxuICAgICAgdXNlcl9ldmVudHM6IFtdLFxuICAgIH07XG4gICAgY29uc3QgcmVxdWVzdCA9IHtcbiAgICAgIG9yZ19pZDogb3JnSWQsXG4gICAgICBjaGF0X2lkOiBjaGF0SWQsXG4gICAgICB1c2VyX2lkOiB1c2VySWQsXG4gICAgfTtcbiAgICB0cnkge1xuICAgICAgZGF0YSA9XG4gICAgICAgIGF3YWl0IENvbW1lcmNlQXBpQ2xpZW50LmdldEluc3RhbmNlKCkuZGVmYXVsdEFwaS52MUdldFNlc3Npb25NZXNzYWdlcyhcbiAgICAgICAgICByZXF1ZXN0XG4gICAgICAgICk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIGF3YWl0IHRocm93U2Vzc2lvblJlc3RhcnRSZXF1aXJlZElmKFxuICAgICAgICBcIkZhaWxlZCB0byBnZXQgY2hhdCByZXNwb25zZXNcIixcbiAgICAgICAgZXJyb3JcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzcG9uc2VzOiBBcGlSZXNwb25zZVtdW10gPSBkYXRhPy5yZXNwb25zZXM/Lm1hcCgodHVybikgPT5cbiAgICAgIHR1cm5cbiAgICAgICAgLm1hcCgocmVzcG9uc2UpID0+IHZhbGlkYXRlUmVzcG9uc2UocmVzcG9uc2UpKVxuICAgICAgICAuZmlsdGVyKChyZXNwb25zZSk6IHJlc3BvbnNlIGlzIEFwaVJlc3BvbnNlID0+IHJlc3BvbnNlICE9IG51bGwpXG4gICAgKTtcblxuICAgIGNvbnN0IHN1Z2dlc3Rpb25zOiBTdWdnZXN0aW9uW10gPSBkYXRhPy5zdWdnZXN0aW9uc1xuICAgICAgLm1hcCgoc3VnZ2VzdGlvbikgPT4gdmFsaWRhdGVTdWdnZXN0aW9uKHN1Z2dlc3Rpb24pKVxuICAgICAgLmZpbHRlcigoc3VnZ2VzdGlvbik6IHN1Z2dlc3Rpb24gaXMgU3VnZ2VzdGlvbiA9PiBzdWdnZXN0aW9uICE9IG51bGwpO1xuXG4gICAgY29uc3QgdXNlckV2ZW50czogVXNlckV2ZW50W10gPSBkYXRhPy51c2VyX2V2ZW50c1xuICAgICAgLm1hcCgoZXZlbnQpID0+IHZhbGlkYXRlVXNlckV2ZW50KGV2ZW50KSlcbiAgICAgIC5maWx0ZXIoKGV2ZW50KTogZXZlbnQgaXMgVXNlckV2ZW50ID0+IGV2ZW50ICE9IG51bGwpO1xuXG4gICAgLy8gaWYgYSBmb3JtIGhhcyBhbHJlYWR5IGJlZW4gc3VibWl0dGVkLCBkb24ndCBzaG93IGl0IGluIHRoZSBjaGF0IGhpc3RvcnlcbiAgICBjb25zdCBmb3JtU3VibWl0dGVkVXNlckV2ZW50c0Zvcm1JZHMgPSB1c2VyRXZlbnRzXG4gICAgICAuZmlsdGVyKChldmVudCkgPT4gZXZlbnQuY2F0ZWdvcnkgPT09IFVzZXJFdmVudENhdGVnb3J5LkZvcm1TdWJtaXR0ZWQpXG4gICAgICAubWFwKChldmVudCkgPT4gZXZlbnQuYXR0cmlidXRlcy5mb3JtUmVzcG9uc2VJZCk7XG5cbiAgICBjb25zdCBhc3Npc3RhbnRNZXNzYWdlczogTWVzc2FnZVtdW10gPSByZXNwb25zZXNcbiAgICAgIC5tYXAoKHR1cm4pID0+XG4gICAgICAgIHR1cm5cbiAgICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgICAgKHJlc3BvbnNlKSA9PlxuICAgICAgICAgICAgICAhKFxuICAgICAgICAgICAgICAgIHJlc3BvbnNlLmNhdGVnb3J5ID09PSBSZXNwb25zZUNhdGVnb3J5LkZvcm0gJiZcbiAgICAgICAgICAgICAgICBmb3JtU3VibWl0dGVkVXNlckV2ZW50c0Zvcm1JZHMuaW5jbHVkZXMocmVzcG9uc2UuaWQpXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICAgICAgLm1hcCgocmVzcG9uc2UpID0+IG1lc3NhZ2VGcm9tUmVzcG9uc2UocmVzcG9uc2UpKVxuICAgICAgICAgIC5maWx0ZXIoKG1lc3NhZ2UpOiBtZXNzYWdlIGlzIE1lc3NhZ2UgPT4gbWVzc2FnZSAhPSBudWxsKVxuICAgICAgKVxuICAgICAgLmZpbHRlcigodHVybikgPT4gdHVybi5sZW5ndGggPiAwKTtcblxuICAgIGNvbnN0IHVzZXJNZXNzYWdlczogTWVzc2FnZVtdW10gPSB1c2VyRXZlbnRzXG4gICAgICAubWFwKChldmVudCkgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgW1VzZXJFdmVudENhdGVnb3J5LlF1ZXJ5VHlwZWQsIFVzZXJFdmVudENhdGVnb3J5LlNlYXJjaF0uaW5jbHVkZXMoXG4gICAgICAgICAgICBldmVudC5jYXRlZ29yeVxuICAgICAgICAgIClcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuIFttZXNzYWdlRnJvbVF1ZXJ5RXZlbnQoZXZlbnQpXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChldmVudC5jYXRlZ29yeSA9PT0gVXNlckV2ZW50Q2F0ZWdvcnkuU3VnZ2VzdGlvbkNsaWNrZWQpIHtcbiAgICAgICAgICByZXR1cm4gW21lc3NhZ2VGcm9tU3VnZ2VzdGlvbkV2ZW50KGV2ZW50LCBzdWdnZXN0aW9ucyldO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGV2ZW50LmNhdGVnb3J5ID09PSBVc2VyRXZlbnRDYXRlZ29yeS5Gb3JtU3VibWl0dGVkKSB7XG4gICAgICAgICAgY29uc3QgZm9ybVJlc3BvbnNlID0gcmVzcG9uc2VzXG4gICAgICAgICAgICAuZmxhdCgpXG4gICAgICAgICAgICAuZmluZChcbiAgICAgICAgICAgICAgKHJlc3BvbnNlKSA9PlxuICAgICAgICAgICAgICAgIHJlc3BvbnNlLmlkID09PSBldmVudC5hdHRyaWJ1dGVzLmZvcm1SZXNwb25zZUlkICYmXG4gICAgICAgICAgICAgICAgZXZlbnQuYXR0cmlidXRlcy5mb3JtVHlwZSAhPT0gRm9ybVR5cGUuRXNjYWxhdGlvblxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgIGlmIChmb3JtUmVzcG9uc2UgJiYgZm9ybVJlc3BvbnNlLmNhdGVnb3J5ID09PSBSZXNwb25zZUNhdGVnb3J5LkZvcm0pIHtcbiAgICAgICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICAgIG1lc3NhZ2VGcm9tRm9ybVN1Ym1pdHRlZEV2ZW50KGV2ZW50LCBmb3JtUmVzcG9uc2UuYXR0cmlidXRlcyksXG4gICAgICAgICAgICBdO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH0pXG4gICAgICAuZmlsdGVyKChtZXNzYWdlKTogbWVzc2FnZSBpcyBNZXNzYWdlW10gPT4gbWVzc2FnZS5sZW5ndGggPiAwKTtcblxuICAgIC8vIFNvcnQgdGhlIG1lc3NhZ2VzIGNocm9ub2xvZ2ljYWxseSB0byByZWNvbnN0cnVjdCB0aGUgY2hhdCBoaXN0b3J5XG4gICAgY29uc3Qgc29ydGVkTWVzc2FnZXMgPSBbLi4uYXNzaXN0YW50TWVzc2FnZXMsIC4uLnVzZXJNZXNzYWdlc10uc29ydChcbiAgICAgIChhLCBiKSA9PlxuICAgICAgICBuZXcgRGF0ZShhWzBdLmNyZWF0ZWRBdCkuZ2V0VGltZSgpIC0gbmV3IERhdGUoYlswXS5jcmVhdGVkQXQpLmdldFRpbWUoKVxuICAgICk7XG5cbiAgICByZXR1cm4geyByZXNwb25zZXMsIHVzZXJFdmVudHMsIHN1Z2dlc3Rpb25zLCBtZXNzYWdlczogc29ydGVkTWVzc2FnZXMgfTtcbiAgfTtcblxuICAvKipcbiAgICpcbiAgICogQHBhcmFtIHBheWxvYWRcbiAgICogQHJldHVybnNcbiAgICovXG4gIHN0YXRpYyBpc1N1cHBvcnRlZEV2ZW50ID0gYXN5bmMgKFxuICAgIHBheWxvYWQ6IFN1cHBvcnRlZEV2ZW50UmVxdWVzdFxuICApOiBQcm9taXNlPFN1cHBvcnRlZEV2ZW50PiA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJhd1Jlc3BvbnNlID1cbiAgICAgICAgYXdhaXQgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5pbmZlcmVuY2VBcGkudjFTdXBwb3J0ZWRFdmVudFBvc3RSYXcoXG4gICAgICAgICAge1xuICAgICAgICAgICAgU3VwcG9ydGVkRXZlbnRSZXF1ZXN0OlxuICAgICAgICAgICAgICBjb3JlU3VwcG9ydGVkRXZlbnRSZXF1ZXN0VG9BcGlSZXF1ZXN0KHBheWxvYWQpLFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgLy8gR2V0IHRoZSBhY3R1YWwgSFRUUCByZXNwb25zZSBKU09OXG4gICAgICBjb25zdCBodHRwUmVzcG9uc2VUZXh0ID0gYXdhaXQgcmF3UmVzcG9uc2UucmF3LnRleHQoKTtcbiAgICAgIGNvbnN0IGh0dHBSZXNwb25zZUpzb24gPSBKU09OLnBhcnNlKGh0dHBSZXNwb25zZVRleHQpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5odHRwUmVzcG9uc2VKc29uLFxuICAgICAgICBudW1iZXJPZlJldmlld3M6IGh0dHBSZXNwb25zZUpzb24ubnVtX29mX3Jldmlld3MsXG4gICAgICAgIG1lcmNoYW50X3RhZ3M6IGh0dHBSZXNwb25zZUpzb24ubWVyY2hhbnRfdGFncyB8fCBbXSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBMb2dnZXIubG9nRXJyb3IoXCJGYWlsZWQgdG8gZ2V0IHJlc3BvbnNlIGZvciB2MVN1cHBvcnRlZEV2ZW50UG9zdFwiLCB7XG4gICAgICAgIGVycixcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc3VwcG9ydGVkOiBmYWxzZSxcbiAgICAgICAgcmVhZHk6IGZhbHNlLFxuICAgICAgICBjYXRlZ29yeTogdW5kZWZpbmVkLFxuICAgICAgICBjb2xsZWN0aW9uczogW10sXG4gICAgICAgIG51bWJlck9mUmV2aWV3czogdW5kZWZpbmVkLFxuICAgICAgICB0b3BfY2F0ZWdvcnk6IHVuZGVmaW5lZCxcbiAgICAgICAgbWVyY2hhbnRfdGFnczogW10sXG4gICAgICB9O1xuICAgIH1cbiAgfTtcblxuICBzdGF0aWMgaWRlbnRpZnlVc2VyID0gYXN5bmMgKFxuICAgIHNwaWZmeVVzZXJJZDogc3RyaW5nLFxuICAgIG1lcmNoYW50VXNlcklkOiBzdHJpbmcsXG4gICAgdWFEZXRhaWxzOiBDbGllbnREZXRhaWxzXG4gICk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLmRlZmF1bHRBcGkudjFBbmFseXRpY3NJZGVudGlmeVBvc3Qoe1xuICAgICAgICBBbmFseXRpY3NJZGVudGlmeVJlcXVlc3Q6IHtcbiAgICAgICAgICB1c2VyX2lkOiBzcGlmZnlVc2VySWQsXG4gICAgICAgICAgb3NfbmFtZTogdWFEZXRhaWxzLm9zLFxuICAgICAgICAgIG9zX3ZlcnNpb246IHVhRGV0YWlscy5vc1ZlcnNpb24sXG4gICAgICAgICAgcGxhdGZvcm06IHVhRGV0YWlscy5vcyxcbiAgICAgICAgICBkZXZpY2VfaWQ6IHVhRGV0YWlscy5kZXZpY2VNb2RlbCxcbiAgICAgICAgICBkZXZpY2VfYnJhbmQ6IHVhRGV0YWlscy5kZXZpY2VCcmFuZCxcbiAgICAgICAgICBkZXZpY2VfbWFudWZhY3R1cmVyOiB1YURldGFpbHMuZGV2aWNlTWFudWZhY3R1cmVyLFxuICAgICAgICAgIGRldmljZV9tb2RlbDogdWFEZXRhaWxzLmRldmljZU1vZGVsLFxuICAgICAgICAgIHVzZXJfcHJvcGVydGllczoge1xuICAgICAgICAgICAgY2RwX3VzZXJfaWQ6IG1lcmNoYW50VXNlcklkLFxuICAgICAgICAgICAgYnJvd3NlcjogdWFEZXRhaWxzLmJyb3dzZXIsXG4gICAgICAgICAgICBicm93c2VyX3ZlcnNpb246IHVhRGV0YWlscy5icm93c2VyVmVyc2lvbixcbiAgICAgICAgICAgIHVzZXJfYWdlbnQ6IHVhRGV0YWlscy51c2VyQWdlbnQsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgTG9nZ2VyLmxvZ0Vycm9yKFwiRmFpbGVkIHRvIGlkZW50aWZ5IHVzZXJcIiwgZXJyKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBzdGF0aWMgbWFwQ29udGV4dFNvdXJjZVRvVjFPcmdDb25maWdHZXRTb3VyY2UgPSAoXG4gICAgc291cmNlOiBDb250ZXh0U291cmNlRW51bSB8IHVuZGVmaW5lZFxuICApOiBWMU9yZ0NvbmZpZ0dldFNvdXJjZUVudW0gfCB1bmRlZmluZWQgPT4ge1xuICAgIGlmIChzb3VyY2UgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBzd2l0Y2ggKHNvdXJjZSkge1xuICAgICAgY2FzZSBDb250ZXh0U291cmNlRW51bS5Gb3JrOlxuICAgICAgICByZXR1cm4gVjFPcmdDb25maWdHZXRTb3VyY2VFbnVtLkZvcms7XG4gICAgICBjYXNlIENvbnRleHRTb3VyY2VFbnVtLlBsYXlncm91bmQ6XG4gICAgICAgIHJldHVybiBWMU9yZ0NvbmZpZ0dldFNvdXJjZUVudW0uUGxheWdyb3VuZDtcbiAgICAgIGNhc2UgQ29udGV4dFNvdXJjZUVudW0uQXBwOlxuICAgICAgICByZXR1cm4gVjFPcmdDb25maWdHZXRTb3VyY2VFbnVtLkFwcDtcbiAgICAgIGNhc2UgQ29udGV4dFNvdXJjZUVudW0uVGVzdDpcbiAgICAgICAgcmV0dXJuIFYxT3JnQ29uZmlnR2V0U291cmNlRW51bS5UZXN0O1xuICAgICAgZGVmYXVsdDoge1xuICAgICAgICAvLyBUaGlzIGVuc3VyZXMgdGhhdCBpZiBuZXcgdmFsdWVzIGFyZSBhZGRlZCB0byBDb250ZXh0U291cmNlRW51bSwgd2UgY2F0Y2ggaXRcbiAgICAgICAgY29uc3QgZXhoYXVzdGl2ZUNoZWNrOiBuZXZlciA9IHNvdXJjZTtcbiAgICAgICAgcmV0dXJuIGV4aGF1c3RpdmVDaGVjaztcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgc3RhdGljIGdldE9yZ0NvbmZpZyA9IGFzeW5jIChcbiAgICB1c2VyX2lkOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxPcmdDb25maWcgfCB1bmRlZmluZWQ+ID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgYXRvbVN0b3JlID0gZ2V0QXRvbVN0b3JlKCk7XG4gICAgICBjb25zdCByZWFjdEFwcE5hbWUgPSBhdG9tU3RvcmUuZ2V0KHJlYWN0QXBwTmFtZUF0b20pO1xuICAgICAgY29uc3QgY29udGV4dFNvdXJjZSA9IGF0b21TdG9yZS5nZXQoY29udGV4dFNvdXJjZUF0b20pO1xuICAgICAgY29uc3QgZmVhdHVyZUZsYWdTZXJ2aWNlID0gYXRvbVN0b3JlLmdldChmZWF0dXJlRmxhZ1NlcnZpY2VBdG9tKTsgLy8gR2V0IGZlYXR1cmVGbGFnU2VydmljZVxuICAgICAgY29uc3QgcmVxdWVzdDogVjFPcmdDb25maWdHZXRSZXF1ZXN0ID0ge1xuICAgICAgICBuYW1lc3BhY2U6IHJlYWN0QXBwTmFtZSxcbiAgICAgICAgdXNlcl9pZCxcbiAgICAgICAgc291cmNlOiB0aGlzLm1hcENvbnRleHRTb3VyY2VUb1YxT3JnQ29uZmlnR2V0U291cmNlKGNvbnRleHRTb3VyY2UpLFxuICAgICAgICBpbmNsdWRlX2V4cGVyaW1lbnRzOiBPYmplY3QudmFsdWVzKFByb2R1Y3RFeHBlcmltZW50KSxcbiAgICAgICAgaW5jbHVkZV9mZWF0dXJlX2dhdGVzOiBPYmplY3QuZW50cmllcyhcbiAgICAgICAgICBmZWF0dXJlRmxhZ1NlcnZpY2U/LmZlYXR1cmVGbGFnU2VydmljZT8uZ2V0RmVhdHVyZUZsYWdzKCkgfHwge31cbiAgICAgICAgKVxuICAgICAgICAgIC5maWx0ZXIoKFssIGlzRW5hYmxlZF0pID0+IGlzRW5hYmxlZClcbiAgICAgICAgICAubWFwKChbZmVhdHVyZUdhdGVOYW1lXSkgPT4gZmVhdHVyZUdhdGVOYW1lKSwgLy8gVXNlIGZlYXR1cmVGbGFnU2VydmljZVxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID1cbiAgICAgICAgYXdhaXQgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5kZWZhdWx0QXBpLnYxT3JnQ29uZmlnR2V0KFxuICAgICAgICAgIHJlcXVlc3RcbiAgICAgICAgKTtcblxuICAgICAgcmV0dXJuIHZhbGlkYXRlT3JnQ29uZmlnUmVzdWx0cyhyZXNwb25zZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBMb2dnZXIubG9nRXJyb3IoYEZhaWxlZCB0byBnZXQgb3JnIGNvbmZpZ2AsIGVyciwgeyBlcnIgfSk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfTtcblxuICBzdGF0aWMgYWRkTm90ZVRvTGF0ZXN0Q29udmVyc2F0aW9uID0gYXN5bmMgKFxuICAgIHNwaWZmeVVzZXJJZDogc3RyaW5nLFxuICAgIGVtYWlsOiBzdHJpbmcsXG4gICAgY3VzdG9tZXJTZXJ2aWNlUHJvdmlkZXI6IEN1c3RvbWVyU2VydmljZVByb3ZpZGVyXG4gICkgPT4ge1xuICAgIExvZ2dlci5sb2dJbmZvKFxuICAgICAgYGFkZE5vdGVUb0xhdGVzdENvbnZlcnNhdGlvbiAtIHVzZXJfaWQ9JHtzcGlmZnlVc2VySWR9IGVtYWlsPSR7ZW1haWx9IGN1c3RvbWVyX3NlcnZpY2VfcHJvdmlkZXI9JHtjdXN0b21lclNlcnZpY2VQcm92aWRlcn1gXG4gICAgKTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5jdXN0b21lclNlcnZpY2VBcGkudjFDdXN0c2VydmljZUFkZE5vdGVUb0xhdGVzdENvbnZlcnNhdGlvblBvc3QoXG4gICAgICAgIHtcbiAgICAgICAgICBBZGROb3RlVG9MYXRlc3RDb252ZXJzYXRpb25SZXF1ZXN0OiB7XG4gICAgICAgICAgICBzcGlmZnlfdXNlcl9pZDogc3BpZmZ5VXNlcklkLFxuICAgICAgICAgICAgZW1haWwsXG4gICAgICAgICAgICBjdXN0b21lcl9zZXJ2aWNlX3Byb3ZpZGVyOiBjdXN0b21lclNlcnZpY2VQcm92aWRlcixcbiAgICAgICAgICB9LFxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgTG9nZ2VyLmxvZ0Vycm9yKFwiRmFpbGVkIHRvIGFkZCBub3RlIHRvIGxhdGVzdCBjb252ZXJzYXRpb25cIiwgeyBlcnIgfSk7XG4gICAgfVxuICB9O1xuXG4gIHN0YXRpYyBnZXRDdXN0b21lclNlcnZpY2VBcGkgPSAoKSA9PlxuICAgIENvbW1lcmNlQXBpQ2xpZW50LmdldEluc3RhbmNlKCkuY3VzdG9tZXJTZXJ2aWNlQXBpO1xufVxuXG5leHBvcnQgZGVmYXVsdCBDb21tZXJjZUFwaUNsaWVudDtcbiIsImltcG9ydCBSZWFjdCwgeyBjcmVhdGVDb250ZXh0LCB1c2VDYWxsYmFjaywgdXNlQ29udGV4dCwgdXNlTWVtbywgdXNlU3RhdGUsIHVzZUVmZmVjdCB9IGZyb20gJ3JlYWN0JztcbmltcG9ydCBVQVBhcnNlciBmcm9tICd1YS1wYXJzZXItanMnO1xuaW1wb3J0IHsgQ2xpZW50RGV0YWlscywgVXNlcklkZW50aXR5Q29udGV4dFR5cGUgfSBmcm9tICdAZW52aXZlLWFpL3R5cGVzJztcbmltcG9ydCBMb2dnZXIgZnJvbSAnLi4vLi4vYXBwbGljYXRpb24vbG9nZ2luZy9sb2dnZXInO1xuaW1wb3J0IENvbW1lcmNlQXBpQ2xpZW50IGZyb20gJy4uLy4uL2FwcGxpY2F0aW9uL2NvbW1lcmNlLWFwaSc7XG5pbXBvcnQgeyB1c2VMb2NhbFN0b3JhZ2UgfSBmcm9tICcuLi9sb2NhbFN0b3JhZ2VDb250ZXh0JztcbmltcG9ydCB7IHY0IGFzIHV1aWQgfSBmcm9tICd1dWlkJztcblxuLy8gSGVscGVyIGZ1bmN0aW9uIGZyb20gdGhlIG9yaWdpbmFsIHNlcnZpY2VcbmNvbnN0IGdldFVzZXJBZ2VudERldGFpbHMgPSAoKTogQ2xpZW50RGV0YWlscyA9PiB7XG4gIGNvbnN0IHVhUGFyc2VyID0gbmV3IFVBUGFyc2VyKCk7XG4gIGNvbnN0IHJlc3VsdCA9IHVhUGFyc2VyLmdldFJlc3VsdCgpO1xuXG4gIHJldHVybiB7XG4gICAgb3M6IHJlc3VsdD8ub3M/Lm5hbWUsXG4gICAgb3NWZXJzaW9uOiByZXN1bHQ/Lm9zPy52ZXJzaW9uLFxuICAgIGRldmljZUJyYW5kOiByZXN1bHQ/LmRldmljZT8udmVuZG9yLFxuICAgIGRldmljZU1hbnVmYWN0dXJlcjogcmVzdWx0Py5kZXZpY2U/LnZlbmRvcixcbiAgICBkZXZpY2VNb2RlbDogcmVzdWx0Py5kZXZpY2U/Lm1vZGVsLFxuICAgIGJyb3dzZXI6IHJlc3VsdD8uYnJvd3Nlcj8ubmFtZSxcbiAgICBicm93c2VyVmVyc2lvbjogcmVzdWx0Py5icm93c2VyPy52ZXJzaW9uLFxuICAgIHVzZXJBZ2VudDogcmVzdWx0Py51YSxcbiAgfTtcbn07XG5cbmNvbnN0IFVzZXJJZGVudGl0eUNvbnRleHQgPSBjcmVhdGVDb250ZXh0PFVzZXJJZGVudGl0eUNvbnRleHRUeXBlIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuXG5leHBvcnQgY29uc3QgVXNlcklkZW50aXR5UHJvdmlkZXI6IFJlYWN0LkZDPHsgY2hpbGRyZW46IFJlYWN0LlJlYWN0Tm9kZSB9PiA9ICh7IGNoaWxkcmVuIH0pID0+IHtcbiAgY29uc3QgeyBnZXRJdGVtLCBzZXRJdGVtLCBpc0F2YWlsYWJsZTogbG9jYWxTdG9yYWdlSXNSZWFkeSB9ID0gdXNlTG9jYWxTdG9yYWdlKCk7XG5cbiAgY29uc3QgW2lzUmVhZHksIHNldElzUmVhZHldID0gdXNlU3RhdGUoZmFsc2UpO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgLy8gQXNzdW1pbmcgQ29tbWVyY2VBcGlDbGllbnQgYW5kIG90aGVyIGRlcGVuZGVuY2llcyBhcmUgcmVhZHkgaWYgbG9jYWxTdG9yYWdlIGlzLlxuICAgIC8vIEluIGEgbW9yZSBjb21wbGV4IHNjZW5hcmlvLCB5b3UgbWlnaHQgaGF2ZSBtb3JlIGNoZWNrcyBoZXJlLlxuICAgIHNldElzUmVhZHkobG9jYWxTdG9yYWdlSXNSZWFkeSk7XG4gIH0sIFtsb2NhbFN0b3JhZ2VJc1JlYWR5XSk7XG5cbiAgY29uc3QgVVNFUl9JRF9PVkVSUklERV9LRVkgPSAndjEtc3BpZmZ5LXVzZXItaWQtb3ZlcnJpZGUnO1xuICBjb25zdCBVU0VSX0lEX0RFRkFVTFRfS0VZID0gJ3YxLXNwaWZmeS11c2VyLWlkLWRlZmF1bHQnO1xuXG4gIGNvbnN0IGdldFVzZXJJZE92ZXJyaWRlRnJvbUxvY2FsU3RvcmFnZSA9IHVzZUNhbGxiYWNrKFxuICAgICgpOiBzdHJpbmcgfCB1bmRlZmluZWQgPT4gZ2V0SXRlbShVU0VSX0lEX09WRVJSSURFX0tFWSkgPz8gdW5kZWZpbmVkLFxuICAgIFtnZXRJdGVtXSxcbiAgKTtcblxuICBjb25zdCBnZXRVc2VySWREZWZhdWx0RnJvbUxvY2FsU3RvcmFnZSA9IHVzZUNhbGxiYWNrKFxuICAgICgpOiBzdHJpbmcgfCB1bmRlZmluZWQgPT4gZ2V0SXRlbShVU0VSX0lEX0RFRkFVTFRfS0VZKSA/PyB1bmRlZmluZWQsXG4gICAgW2dldEl0ZW1dLFxuICApO1xuXG4gIGNvbnN0IHNldFVzZXJJZERlZmF1bHRJbkxvY2FsU3RvcmFnZSA9IHVzZUNhbGxiYWNrKFxuICAgICh1c2VySWQ6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gICAgICBMb2dnZXIubG9nSW5mbyhgc2V0VXNlcklkRGVmYXVsdEluTG9jYWxTdG9yYWdlIC0gU2V0dGluZyB1c2VyX2lkPSR7dXNlcklkfWApO1xuICAgICAgc2V0SXRlbShVU0VSX0lEX0RFRkFVTFRfS0VZLCB1c2VySWQpO1xuICAgICAgLy8gd2luZG93LmRpc3BhdGNoRXZlbnQgaXMgaGFuZGxlZCBieSB1c2VMb2NhbFN0b3JhZ2Ugbm93XG4gICAgICByZXR1cm4gdXNlcklkO1xuICAgIH0sXG4gICAgW3NldEl0ZW0sIFVTRVJfSURfREVGQVVMVF9LRVldLFxuICApO1xuXG4gIGNvbnN0IHNldFVzZXJJZE92ZXJyaWRlSW5Mb2NhbFN0b3JhZ2UgPSB1c2VDYWxsYmFjayhcbiAgICAodXNlcklkOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICAgICAgTG9nZ2VyLmxvZ0luZm8oYHNldFVzZXJJZE92ZXJyaWRlSW5Mb2NhbFN0b3JhZ2UgLSBTZXR0aW5nIHVzZXJfaWQ9JHt1c2VySWR9YCk7XG4gICAgICBzZXRJdGVtKFVTRVJfSURfT1ZFUlJJREVfS0VZLCB1c2VySWQpO1xuICAgICAgLy8gd2luZG93LmRpc3BhdGNoRXZlbnQgaXMgaGFuZGxlZCBieSB1c2VMb2NhbFN0b3JhZ2Ugbm93XG4gICAgICByZXR1cm4gdXNlcklkO1xuICAgIH0sXG4gICAgW3NldEl0ZW0sIFVTRVJfSURfT1ZFUlJJREVfS0VZXSxcbiAgKTtcblxuICBjb25zdCBjbGVhclVzZXJJZE92ZXJyaWRlSW5Mb2NhbFN0b3JhZ2UgPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgTG9nZ2VyLmxvZ0luZm8oYGNsZWFyVXNlcklkT3ZlcnJpZGVJbkxvY2FsU3RvcmFnZSAtIENsZWFyaW5nIHVzZXJfaWRgKTtcbiAgICAvLyBMb2NhbFN0b3JhZ2VTZXJ2aWNlLmdldExvY2FsU3RvcmFnZSgpPy5yZW1vdmVJdGVtKFVTRVJfSURfT1ZFUlJJREVfS0VZKTtcbiAgICAvLyB3aW5kb3cuZGlzcGF0Y2hFdmVudCBpcyBoYW5kbGVkIGJ5IHVzZUxvY2FsU3RvcmFnZSBub3dcbiAgICBzZXRJdGVtKFVTRVJfSURfT1ZFUlJJREVfS0VZLCAnJyk7IC8vIFNldCB0byBlbXB0eSBzdHJpbmcgdG8gY2xlYXJcbiAgfSwgW3NldEl0ZW0sIFVTRVJfSURfT1ZFUlJJREVfS0VZXSk7XG5cbiAgY29uc3QgZ2V0VXNlcklkT3JEZWZhdWx0ID0gdXNlQ2FsbGJhY2soKCk6IHN0cmluZyA9PiB7XG4gICAgY29uc3QgdXNlcklkT3ZlcnJpZGUgPSBnZXRVc2VySWRPdmVycmlkZUZyb21Mb2NhbFN0b3JhZ2UoKTtcbiAgICBpZiAodXNlcklkT3ZlcnJpZGUpIHtcbiAgICAgIHJldHVybiB1c2VySWRPdmVycmlkZTtcbiAgICB9XG5cbiAgICBjb25zdCBkZWZhdWx0VXNlcklkID0gZ2V0VXNlcklkRGVmYXVsdEZyb21Mb2NhbFN0b3JhZ2UoKTtcbiAgICBpZiAoZGVmYXVsdFVzZXJJZCkge1xuICAgICAgcmV0dXJuIGRlZmF1bHRVc2VySWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNldFVzZXJJZERlZmF1bHRJbkxvY2FsU3RvcmFnZShgc3BpZmZ5LXVzZXItaWQtJHt1dWlkKCl9YCk7XG4gIH0sIFtcbiAgICBnZXRVc2VySWRPdmVycmlkZUZyb21Mb2NhbFN0b3JhZ2UsXG4gICAgZ2V0VXNlcklkRGVmYXVsdEZyb21Mb2NhbFN0b3JhZ2UsXG4gICAgc2V0VXNlcklkRGVmYXVsdEluTG9jYWxTdG9yYWdlLFxuICBdKTtcblxuICBjb25zdCBpZGVudGlmeVVzZXIgPSB1c2VDYWxsYmFjayhhc3luYyAoKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgaWYgKCFpc1JlYWR5KSB7XG4gICAgICBMb2dnZXIubG9nV2FybignW1VzZXJJZGVudGl0eUNvbnRleHRdIENvbnRleHQgbm90IHJlYWR5LCBza2lwcGluZyBpZGVudGlmeVVzZXInLCB1bmRlZmluZWQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICAvLyBUZW1wb3JhcmlseSBjb21tZW50ZWQgb3V0IHVudGlsIFdpbmRvd0RhdGFMYXllclNlcnZpY2UgaXMgcmVzb2x2ZWRcbiAgICAgIC8vIGNvbnN0IGNkcFVzZXJJZCA9IFdpbmRvd0RhdGFMYXllclNlcnZpY2UuZ2V0R29vZ2xlQW5hbHl0aWNzQ2xpZW50SWQoKTtcbiAgICAgIGNvbnN0IGNkcFVzZXJJZCA9ICdVTktOT1dOX0NEUF9VU0VSX0lEJzsgLy8gUGxhY2Vob2xkZXJcbiAgICAgIGNvbnN0IHVzZXJJZCA9IGdldFVzZXJJZE9yRGVmYXVsdCgpO1xuICAgICAgY29uc3QgdXNlckFnZW50RGV0YWlscyA9IGdldFVzZXJBZ2VudERldGFpbHMoKTtcblxuICAgICAgaWYgKCFjZHBVc2VySWQpIHtcbiAgICAgICAgTG9nZ2VyLmxvZ1dhcm4oJ1tzcGlmZnktYWldIE5vIEdBIENsaWVudCBJRCBmb3VuZCwgc2tpcHBpbmcgaWRlbnRpZnlVc2VyJywgdW5kZWZpbmVkKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBDb21tZXJjZUFwaUNsaWVudC5pZGVudGlmeVVzZXIodXNlcklkLCBjZHBVc2VySWQsIHVzZXJBZ2VudERldGFpbHMpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBMb2dnZXIubG9nRXJyb3IoJ1tzcGlmZnktYWldIEVycm9yIGlkZW50aWZ5aW5nIHVzZXInLCBlcnJvcik7XG4gICAgfVxuICB9LCBbaXNSZWFkeSwgZ2V0VXNlcklkT3JEZWZhdWx0XSk7XG5cbiAgY29uc3QgdmFsdWUgPSB1c2VNZW1vKFxuICAgICgpID0+ICh7XG4gICAgICBpZGVudGlmeVVzZXIsXG4gICAgICBnZXRVc2VySWRPckRlZmF1bHQsXG4gICAgICBnZXRVc2VySWRPdmVycmlkZUZyb21Mb2NhbFN0b3JhZ2UsXG4gICAgICBnZXRVc2VySWREZWZhdWx0RnJvbUxvY2FsU3RvcmFnZSxcbiAgICAgIHNldFVzZXJJZERlZmF1bHRJbkxvY2FsU3RvcmFnZSxcbiAgICAgIHNldFVzZXJJZE92ZXJyaWRlSW5Mb2NhbFN0b3JhZ2UsXG4gICAgICBjbGVhclVzZXJJZE92ZXJyaWRlSW5Mb2NhbFN0b3JhZ2UsXG4gICAgICBpc1JlYWR5LFxuICAgIH0pLFxuICAgIFtcbiAgICAgIGlkZW50aWZ5VXNlcixcbiAgICAgIGdldFVzZXJJZE9yRGVmYXVsdCxcbiAgICAgIGdldFVzZXJJZE92ZXJyaWRlRnJvbUxvY2FsU3RvcmFnZSxcbiAgICAgIGdldFVzZXJJZERlZmF1bHRGcm9tTG9jYWxTdG9yYWdlLFxuICAgICAgc2V0VXNlcklkRGVmYXVsdEluTG9jYWxTdG9yYWdlLFxuICAgICAgc2V0VXNlcklkT3ZlcnJpZGVJbkxvY2FsU3RvcmFnZSxcbiAgICAgIGNsZWFyVXNlcklkT3ZlcnJpZGVJbkxvY2FsU3RvcmFnZSxcbiAgICAgIGlzUmVhZHksXG4gICAgXSxcbiAgKTtcblxuICByZXR1cm4gPFVzZXJJZGVudGl0eUNvbnRleHQuUHJvdmlkZXIgdmFsdWU9e3ZhbHVlfT57Y2hpbGRyZW59PC9Vc2VySWRlbnRpdHlDb250ZXh0LlByb3ZpZGVyPjtcbn07XG5cbmV4cG9ydCBjb25zdCB1c2VVc2VySWRlbnRpdHkgPSAoKSA9PiB7XG4gIGNvbnN0IGNvbnRleHQgPSB1c2VDb250ZXh0KFVzZXJJZGVudGl0eUNvbnRleHQpO1xuICBpZiAoIWNvbnRleHQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3VzZVVzZXJJZGVudGl0eSBtdXN0IGJlIHVzZWQgd2l0aGluIGEgVXNlcklkZW50aXR5UHJvdmlkZXInKTtcbiAgfVxuICByZXR1cm4gY29udGV4dDtcbn07XG4iLCJpbXBvcnQgeyBhdG9tV2l0aFN0b3JhZ2UgfSBmcm9tICdqb3RhaS91dGlscyc7XG5pbXBvcnQgeyBhdG9tIH0gZnJvbSAnam90YWknO1xuaW1wb3J0IHsgU3VwcG9ydGVkRXZlbnRSZXNwb25zZSwgUGFnZVZpc2l0Q2F0ZWdvcnkgfSBmcm9tICdAc3BpZmZ5LWFpL2NvbW1lcmNlLWFwaS1jbGllbnQnO1xuaW1wb3J0IHtcbiAgUGFnZVZpc2l0VmFyaWFudEluZm8sXG4gIFBEUFZhcmlhbnRJbmZvLFxuICBQTFBWYXJpYW50SW5mbyxcbiAgVmFyaWFudEluZm8sXG4gIFZhcmlhbnRUeXBlRW51bSxcbn0gZnJvbSAnQGVudml2ZS1haS90eXBlcyc7XG5pbXBvcnQgeyBzZXNzaW9uU3RvcmFnZVV0aWwgfSBmcm9tICdzcmMvYXRvbXMvYXRvbVN0b3JlJztcblxuZXhwb3J0IGludGVyZmFjZSBTdXBwb3J0ZWRFdmVudFxuICBleHRlbmRzIFBpY2s8XG4gICAgU3VwcG9ydGVkRXZlbnRSZXNwb25zZSxcbiAgICAnc3VwcG9ydGVkJyB8ICdyZWFkeScgfCAnY2F0ZWdvcnknIHwgJ2NvbGxlY3Rpb25zJyB8ICd0b3BfY2F0ZWdvcnknXG4gID4ge1xuICBudW1iZXJPZlJldmlld3M6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgbWVyY2hhbnRfdGFncz86IHN0cmluZ1tdO1xufVxuXG5pbnRlcmZhY2UgUERQQXR0cmlidXRlcyB7XG4gIHByb2R1Y3RfaWQ/OiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBQTFBBdHRyaWJ1dGVzIHtcbiAgYXR0cmlidXRlcz86IHtcbiAgICBpZD86IHN0cmluZztcbiAgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBVcmxSZXNvbHZpbmdQRFBDb25maWcge1xuICBwZHBfYXR0cmlidXRlczogUERQQXR0cmlidXRlcztcbiAgbnVtYmVyX29mX3Jldmlld3M/OiBudW1iZXI7XG4gIGNvbGxlY3Rpb25zPzogc3RyaW5nW107XG4gIG1lcmNoYW50X3RhZ3M/OiBzdHJpbmdbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBVcmxSZXNvbHZpbmdQTFBDb25maWcge1xuICBwbHBfYXR0cmlidXRlczogUExQQXR0cmlidXRlcztcbiAgdG9wX2NhdGVnb3J5Pzogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgVXJsUmVzb2x2aW5nR2VuZXJpY0NvbmZpZyB7XG4gIGRldGFpbHM/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCB0eXBlIFBhZ2VWYXJpYW50Q2hlY2tDb25maWcgPSB7XG4gIGNoZWNrX3R5cGU6IHN0cmluZztcbiAgZmVhdHVyZV9nYXRlPzogc3RyaW5nO1xuICBleHRyYWN0b3I/OiB7XG4gICAgdHlwZTogc3RyaW5nO1xuICAgIG1hcD86IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdPjtcbiAgICB2YWx1ZT86IHN0cmluZztcbiAgfTtcbiAgcHJvZHVjdF9pZF9leHRyYWN0b3I/OiBzdHJpbmc7XG4gIHByb2R1Y3RfaWRzPzogc3RyaW5nW107XG4gIHBscF9pZF9leHRyYWN0b3I/OiBzdHJpbmc7XG4gIHBscF9pZHM/OiBzdHJpbmdbXTtcbiAgY29sbGVjdGlvbnM/OiBzdHJpbmdbXTtcbiAgcXVlcnlfcGFyYW0/OiBzdHJpbmc7XG4gIGNhdGVnb3J5Pzogc3RyaW5nO1xuICB0b3BfY2F0ZWdvcnk/OiBzdHJpbmdbXTtcbiAgcmV2aWV3X21pbmltdW0/OiBudW1iZXI7XG4gIG1lcmNoYW50X3RhZ3M/OiBzdHJpbmdbXTtcbn07XG5cbmV4cG9ydCB0eXBlIEJhY2tlbmRXaWRnZXRNb3VudGluZ0NvbmZpZyA9IHtcbiAgbW91bnRpbmdfY29uZmlnX2lkOiBzdHJpbmc7XG4gIHdpZGdldF9jb25maWdfaWQ/OiBzdHJpbmc7XG4gIG1vdW50aW5nX3BvaW50X3dpZGdldHM/OiBBcnJheTx7XG4gICAgY2hlY2tzOiBQYWdlVmFyaWFudENoZWNrQ29uZmlnW107XG4gICAgd2lkZ2V0X2NvbmZpZ19pZDogc3RyaW5nO1xuICB9Pjtcbn07XG5cbmV4cG9ydCB0eXBlIEJhY2tlbmRQYWdlVmFyaWFudENvbmZpZyA9IHtcbiAgdmFyaWFudF9pZDogc3RyaW5nO1xuICB2YXJpYW50X3R5cGU6IHN0cmluZztcbiAgdmFyaWFudF9jaGVja3M6IFBhZ2VWYXJpYW50Q2hlY2tDb25maWdbXTtcbiAgd2lkZ2V0X21vdW50aW5nOiBCYWNrZW5kV2lkZ2V0TW91bnRpbmdDb25maWdbXTtcbiAgcGxwX2lkX2V4dHJhY3Rvcj86IHN0cmluZztcbiAgcHJvZHVjdF9pZF9leHRyYWN0b3I/OiBzdHJpbmc7XG4gIHBhcmVudF9wcm9kdWN0X2lkX2V4dHJhY3Rvcj86IHN0cmluZztcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgVXJsUmVzb2x2ZXJSZXNwb25zZSB7XG4gIHZhcmlhbnRfdHlwZTogc3RyaW5nO1xuICBzcGVjaWZpY19kZXRhaWxzOiBVcmxSZXNvbHZpbmdQRFBDb25maWcgfCBVcmxSZXNvbHZpbmdQTFBDb25maWcgfCBVcmxSZXNvbHZpbmdHZW5lcmljQ29uZmlnO1xuICByZWFkeTogYm9vbGVhbjtcbiAgdXNlcl9ldmVudD86IHtcbiAgICBldmVudF9pZD86IHN0cmluZztcbiAgICBhdHRyaWJ1dGVzPzogUERQQXR0cmlidXRlcyB8IFBMUEF0dHJpYnV0ZXM7XG4gICAgY2F0ZWdvcnk/OiBzdHJpbmc7XG4gICAgY3JlYXRlZF9hdD86IHN0cmluZztcbiAgfTtcbiAgcGFnZV92YXJpYW50PzogQmFja2VuZFBhZ2VWYXJpYW50Q29uZmlnO1xufVxuXG4vLyBVc2UgYSBtYXAgZm9yIHBlci1VUkwgY2FjaGVcbmV4cG9ydCB0eXBlIFVybFJlc29sdmVyQ2FjaGUgPSBSZWNvcmQ8c3RyaW5nLCBVcmxSZXNvbHZlclJlc3BvbnNlIHwgdW5kZWZpbmVkPjtcblxuY29uc3QgaW50ZXJuYWxTdG9yYWdlVXJsUmVzb2x2ZXJBdG9tID0gYXRvbVdpdGhTdG9yYWdlPHN0cmluZyB8IHVuZGVmaW5lZD4oXG4gICdzcGlmZnktdXJsLXJlc29sdmVyJyxcbiAgdW5kZWZpbmVkLFxuICBzZXNzaW9uU3RvcmFnZVV0aWwsXG4gIHtcbiAgICBnZXRPbkluaXQ6IHRydWUsXG4gIH0sXG4pO1xuXG5leHBvcnQgY29uc3QgdXJsUmVzb2x2ZXJBdG9tID0gYXRvbShcbiAgKGdldCk6IFVybFJlc29sdmVyQ2FjaGUgPT4ge1xuICAgIGNvbnN0IG1heWJlVXJsUmVzb2x2ZXIgPSBnZXQoaW50ZXJuYWxTdG9yYWdlVXJsUmVzb2x2ZXJBdG9tKTtcbiAgICBpZiAobWF5YmVVcmxSZXNvbHZlciA9PSBudWxsKSB7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIHJldHVybiBKU09OLnBhcnNlKG1heWJlVXJsUmVzb2x2ZXIpO1xuICB9LFxuICAoZ2V0LCBzZXQsIHZhbHVlOiB7IHVybDogc3RyaW5nOyByZXNwb25zZTogVXJsUmVzb2x2ZXJSZXNwb25zZSB8IHVuZGVmaW5lZCB9KSA9PiB7XG4gICAgLy8gR2V0IGN1cnJlbnQgY2FjaGUgZnJvbSBzdG9yYWdlXG4gICAgY29uc3QgY3VycmVudENhY2hlID0gZ2V0KHVybFJlc29sdmVyQXRvbSk7XG4gICAgY29uc3QgbmV3Q2FjaGUgPSB7IC4uLmN1cnJlbnRDYWNoZSwgW3ZhbHVlLnVybF06IHZhbHVlLnJlc3BvbnNlIH07XG5cbiAgICBzZXQoaW50ZXJuYWxTdG9yYWdlVXJsUmVzb2x2ZXJBdG9tLCBKU09OLnN0cmluZ2lmeShuZXdDYWNoZSkpO1xuICB9LFxuKTtcblxuY29uc3QgaW50ZXJuYWxTdG9yYWdlU3VwcG9ydGVkRXZlbnRBdG9tID0gYXRvbVdpdGhTdG9yYWdlPHN0cmluZyB8IHVuZGVmaW5lZD4oXG4gICdzcGlmZnktc3VwcG9ydGVkLWV2ZW50JyxcbiAgdW5kZWZpbmVkLFxuICBzZXNzaW9uU3RvcmFnZVV0aWwsXG4gIHtcbiAgICBnZXRPbkluaXQ6IHRydWUsXG4gIH0sXG4pO1xuY29uc3QgaW50ZXJuYWxTdXBwb3J0ZWRFdmVudEF0b20gPSBhdG9tPFN1cHBvcnRlZEV2ZW50IHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuXG5leHBvcnQgY29uc3Qgc3VwcG9ydGVkRXZlbnRBdG9tID0gYXRvbShcbiAgKGdldCk6IFN1cHBvcnRlZEV2ZW50IHwgdW5kZWZpbmVkID0+IHtcbiAgICBjb25zdCBtYXliZVN1cHBvcnRlZEV2ZW50ID0gZ2V0KGludGVybmFsU3RvcmFnZVN1cHBvcnRlZEV2ZW50QXRvbSk7XG4gICAgaWYgKG1heWJlU3VwcG9ydGVkRXZlbnQgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvLyBUT0RPIHRoaXMgaXMgYW4gdW52YWxpZGF0ZWQgcGFyc2UuIEl0IG1heSBiZSBiZXR0ZXIgdG8gaW1wbGVtZW50IGEgY3VzdG9tIHN0b3JhZ2UgdXRpbFxuICAgIC8vIGFuZCBwZXJmb3JtIHRoZSBvYmplY3QgdmFsaWRhdGlvbiBvbiBcImdldFwiIHRoZXJlLlxuICAgIHJldHVybiBKU09OLnBhcnNlKG1heWJlU3VwcG9ydGVkRXZlbnQpO1xuICB9LFxuICAoXywgc2V0LCB2YWx1ZTogU3VwcG9ydGVkRXZlbnQgfCB1bmRlZmluZWQpID0+IHtcbiAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgc2V0KGludGVybmFsU3RvcmFnZVN1cHBvcnRlZEV2ZW50QXRvbSwgdW5kZWZpbmVkKTtcbiAgICAgIHNldChpbnRlcm5hbFN1cHBvcnRlZEV2ZW50QXRvbSwgdW5kZWZpbmVkKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzZXQoaW50ZXJuYWxTdXBwb3J0ZWRFdmVudEF0b20sIHZhbHVlKTtcbiAgICBzZXQoaW50ZXJuYWxTdG9yYWdlU3VwcG9ydGVkRXZlbnRBdG9tLCBKU09OLnN0cmluZ2lmeSh2YWx1ZSkpO1xuICB9LFxuKTtcblxuY29uc3QgaW50ZXJuYWxWYXJpYW50SWRBdG9tID0gYXRvbTxzdHJpbmc+KCk7XG5jb25zdCBpbnRlcm5hbFByb2R1Y3RJZEF0b20gPSBhdG9tPHN0cmluZz4oKTtcbmNvbnN0IGludGVybmFsUGFyZW50UHJvZHVjdElkQXRvbSA9IGF0b208c3RyaW5nPigpO1xuY29uc3QgaW50ZXJuYWxQcm9kdWN0VXJsQXRvbSA9IGF0b208c3RyaW5nPigpO1xuY29uc3QgaW50ZXJuYWxQbHBJZEF0b20gPSBhdG9tPHN0cmluZz4oKTtcbmNvbnN0IGludGVybmFsVXJsQXRvbSA9IGF0b208c3RyaW5nPigpO1xuY29uc3QgaW50ZXJuYWxQYWdlVmlzaXRDYXRlZ29yeUF0b20gPSBhdG9tPFBhZ2VWaXNpdENhdGVnb3J5PigpO1xuY29uc3QgaW50ZXJuYWxWYXJpYW50QXRvbSA9IGF0b208J3BkcCcgfCAncGxwJyB8ICdzZWFyY2gnIHwgJ3BhZ2VfdmlzaXQnPigncGRwJyk7XG5cbmV4cG9ydCBjb25zdCB2YXJpYW50SWRBdG9tID0gYXRvbSgoZ2V0KSA9PiBnZXQoaW50ZXJuYWxWYXJpYW50SWRBdG9tKSk7XG5leHBvcnQgY29uc3QgcHJvZHVjdElkQXRvbSA9IGF0b20oKGdldCkgPT4gZ2V0KGludGVybmFsUHJvZHVjdElkQXRvbSkpO1xuZXhwb3J0IGNvbnN0IHBhcmVudFByb2R1Y3RJZEF0b20gPSBhdG9tKChnZXQpID0+IGdldChpbnRlcm5hbFBhcmVudFByb2R1Y3RJZEF0b20pKTtcbmV4cG9ydCBjb25zdCBwcm9kdWN0VXJsQXRvbSA9IGF0b20oKGdldCkgPT4gZ2V0KGludGVybmFsUHJvZHVjdFVybEF0b20pKTtcbmV4cG9ydCBjb25zdCBwbHBJZEF0b20gPSBhdG9tKChnZXQpID0+IGdldChpbnRlcm5hbFBscElkQXRvbSkpO1xuZXhwb3J0IGNvbnN0IHVybEF0b20gPSBhdG9tKChnZXQpID0+IGdldChpbnRlcm5hbFVybEF0b20pKTtcbmV4cG9ydCBjb25zdCBwYWdlVmlzaXRDYXRlZ29yeUF0b20gPSBhdG9tKChnZXQpID0+IGdldChpbnRlcm5hbFBhZ2VWaXNpdENhdGVnb3J5QXRvbSkpO1xuZXhwb3J0IGNvbnN0IHZhcmlhbnRBdG9tID0gYXRvbSgoZ2V0KSA9PiBnZXQoaW50ZXJuYWxWYXJpYW50QXRvbSkpO1xuZXhwb3J0IGNvbnN0IGhhc1BhcnNlZFZhcmlhbnRJbmZvQXRvbSA9IGF0b20oZmFsc2UpO1xuXG5leHBvcnQgY29uc3QgdmFyaWFudEluZm9BdG9tID0gYXRvbShcbiAgKGdldCk6IFZhcmlhbnRJbmZvID0+IHtcbiAgICBjb25zdCB2YXJpYW50ID0gZ2V0KHZhcmlhbnRBdG9tKTtcbiAgICBpZiAodmFyaWFudCA9PT0gVmFyaWFudFR5cGVFbnVtLlBkcCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFyaWFudElkOiBnZXQodmFyaWFudElkQXRvbSksXG4gICAgICAgIHZhcmlhbnQsXG4gICAgICAgIHByb2R1Y3RJZDogZ2V0KHByb2R1Y3RJZEF0b20pLFxuICAgICAgICBwYXJlbnRQcm9kdWN0SWQ6IGdldChwYXJlbnRQcm9kdWN0SWRBdG9tKSxcbiAgICAgICAgdXJsOiBnZXQodXJsQXRvbSksXG4gICAgICB9IGFzIFBEUFZhcmlhbnRJbmZvO1xuICAgIH1cbiAgICBpZiAodmFyaWFudCA9PT0gVmFyaWFudFR5cGVFbnVtLlBscCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFyaWFudElkOiBnZXQodmFyaWFudElkQXRvbSksXG4gICAgICAgIHZhcmlhbnQsXG4gICAgICAgIHBscElkOiBnZXQocGxwSWRBdG9tKSxcbiAgICAgICAgdXJsOiBnZXQodXJsQXRvbSksXG4gICAgICB9IGFzIFBMUFZhcmlhbnRJbmZvO1xuICAgIH1cbiAgICBpZiAodmFyaWFudCA9PT0gVmFyaWFudFR5cGVFbnVtLlBhZ2VWaXNpdCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFyaWFudElkOiBnZXQodmFyaWFudElkQXRvbSksXG4gICAgICAgIHZhcmlhbnQsXG4gICAgICAgIHVybDogZ2V0KHVybEF0b20pLFxuICAgICAgICBwYWdlVmlzaXRDYXRlZ29yeTogZ2V0KHBhZ2VWaXNpdENhdGVnb3J5QXRvbSksXG4gICAgICB9IGFzIFBhZ2VWaXNpdFZhcmlhbnRJbmZvO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgdmFyaWFudEluZm8gZGV0YWlscycpO1xuICB9LFxuICAoXywgc2V0LCBuZXdWYXJpYW50OiBWYXJpYW50SW5mbykgPT4ge1xuICAgIHNldChpbnRlcm5hbFZhcmlhbnRBdG9tLCBuZXdWYXJpYW50LnZhcmlhbnQpO1xuICAgIHNldChpbnRlcm5hbFZhcmlhbnRJZEF0b20sIG5ld1ZhcmlhbnQudmFyaWFudElkKTtcbiAgICBpZiAobmV3VmFyaWFudC52YXJpYW50ID09PSBWYXJpYW50VHlwZUVudW0uUGRwKSB7XG4gICAgICBzZXQoaW50ZXJuYWxQcm9kdWN0SWRBdG9tLCBuZXdWYXJpYW50LnByb2R1Y3RJZCk7XG4gICAgICBzZXQoaW50ZXJuYWxQYXJlbnRQcm9kdWN0SWRBdG9tLCBuZXdWYXJpYW50LnBhcmVudFByb2R1Y3RJZCk7XG4gICAgICBzZXQoaW50ZXJuYWxVcmxBdG9tLCBuZXdWYXJpYW50LnVybCk7XG4gICAgfVxuICAgIGlmIChuZXdWYXJpYW50LnZhcmlhbnQgPT09IFZhcmlhbnRUeXBlRW51bS5QbHApIHtcbiAgICAgIHNldChpbnRlcm5hbFBscElkQXRvbSwgbmV3VmFyaWFudC5wbHBJZCk7XG4gICAgICBzZXQoaW50ZXJuYWxVcmxBdG9tLCBuZXdWYXJpYW50LnVybCk7XG4gICAgfVxuICAgIGlmIChuZXdWYXJpYW50LnZhcmlhbnQgPT09IFZhcmlhbnRUeXBlRW51bS5QYWdlVmlzaXQpIHtcbiAgICAgIHNldChpbnRlcm5hbFVybEF0b20sIG5ld1ZhcmlhbnQudXJsKTtcbiAgICAgIHNldChpbnRlcm5hbFBhZ2VWaXNpdENhdGVnb3J5QXRvbSwgbmV3VmFyaWFudC5wYWdlVmlzaXRDYXRlZ29yeSk7XG4gICAgfVxuICB9LFxuKTtcbiIsImltcG9ydCB7IENvbnRleHRFbnZFbnVtLCBDb250ZXh0U291cmNlRW51bSB9IGZyb20gJ0BzcGlmZnktYWkvY29tbWVyY2UtYXBpLWNsaWVudCc7XG5pbXBvcnQgeyBhdG9tIH0gZnJvbSAnam90YWknO1xuaW1wb3J0IHsgYXRvbVdpdGhTdG9yYWdlIH0gZnJvbSAnam90YWkvdXRpbHMnO1xuaW1wb3J0IHsgVmFyaWFudEluZm8sIFVzZXJJZGVudGl0eUNvbnRleHRUeXBlIH0gZnJvbSAnQGVudml2ZS1haS90eXBlcyc7XG5pbXBvcnQgeyB1c2VVc2VySWRlbnRpdHkgfSBmcm9tICdzcmMvY29udGV4dHMvdXNlcklkZW50aXR5Q29udGV4dC91c2VySWRlbnRpdHlDb250ZXh0JztcbmltcG9ydCB7IHZhcmlhbnRJbmZvQXRvbSB9IGZyb20gJ3NyYy9hdG9tcy9hcHAvdmFyaWFudCc7XG5pbXBvcnQgeyB2NCBhcyB1dWlkIH0gZnJvbSAndXVpZCc7XG5pbXBvcnQgeyBjb250ZXh0U291cmNlQXRvbSB9IGZyb20gJy4uL2Vudml2ZS9lbnZpdmVDb25maWcnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEFwcERldGFpbHMge1xuICBvcmdJZDogc3RyaW5nO1xuICBvcmdTaG9ydE5hbWU6IHN0cmluZztcbiAgY2hhdElkOiBzdHJpbmc7XG4gIHVzZXJJZDogc3RyaW5nO1xuICBzb3VyY2U6IENvbnRleHRTb3VyY2VFbnVtO1xuICBlbnY6IENvbnRleHRFbnZFbnVtO1xuICB2YXJpYW50SW5mbzogVmFyaWFudEluZm87XG59XG5cbmV4cG9ydCB7IHZhcmlhbnRJbmZvQXRvbSB9IGZyb20gJy4vdmFyaWFudCc7XG5cbmNvbnN0IGludGVybmFsVXNlcklkQXRvbSA9IGF0b208c3RyaW5nIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuXG5leHBvcnQgY29uc3QgdXNlcklkQXRvbSA9IGF0b20oXG4gIChnZXQpID0+IHtcbiAgICBjb25zdCBtYXliZVVzZXJJZCA9IGdldChpbnRlcm5hbFVzZXJJZEF0b20pO1xuXG4gICAgaWYgKG1heWJlVXNlcklkKSB7XG4gICAgICByZXR1cm4gbWF5YmVVc2VySWQ7XG4gICAgfVxuXG4gICAgY29uc3QgeyBnZXRVc2VySWRPckRlZmF1bHQgfSA9IHVzZVVzZXJJZGVudGl0eSgpO1xuICAgIHJldHVybiBnZXRVc2VySWRPckRlZmF1bHQoKTtcbiAgfSxcbiAgKF8sIHNldCwgdmFsdWU6IHN0cmluZyB8IHVuZGVmaW5lZCkgPT4ge1xuICAgIHNldChpbnRlcm5hbFVzZXJJZEF0b20sIHZhbHVlKTtcbiAgfSxcbik7XG5cbmV4cG9ydCBjb25zdCB1c2VySWRlbnRpdHlBdG9tID0gYXRvbTxVc2VySWRlbnRpdHlDb250ZXh0VHlwZSB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcblxuZXhwb3J0IGNvbnN0IGFwcFNvdXJjZUF0b20gPSBhdG9tPENvbnRleHRTb3VyY2VFbnVtPihcbiAgKGdldCk6IENvbnRleHRTb3VyY2VFbnVtID0+IGdldChjb250ZXh0U291cmNlQXRvbSkgPz8gQ29udGV4dFNvdXJjZUVudW0uQXBwLFxuKTtcbmV4cG9ydCBjb25zdCBjaGF0SWRBdG9tID0gYXRvbVdpdGhTdG9yYWdlPHN0cmluZz4oJ3YxLXNwaWZmeS1jaGF0LXNlc3Npb24taWQnLCB1dWlkKCksIHVuZGVmaW5lZCwge1xuICBnZXRPbkluaXQ6IHRydWUsXG59KTtcbiIsImltcG9ydCBSZWFjdCwgeyBjcmVhdGVDb250ZXh0LCB1c2VDb250ZXh0LCB1c2VDYWxsYmFjaywgdXNlTWVtbywgdXNlRWZmZWN0IH0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgdXNlQXRvbVZhbHVlIH0gZnJvbSAnam90YWknO1xuaW1wb3J0IHsgY3JlYXRlSW5zdGFuY2UgfSBmcm9tICdAYW1wbGl0dWRlL2FuYWx5dGljcy1icm93c2VyJztcbmltcG9ydCB7IEZlYXR1cmVHYXRlcywgT3JnU2hvcnROYW1lLCBMb2NhbFN0b3JhZ2VLZXlzLCBTcGlmZnlFdmVudCB9IGZyb20gJ0BlbnZpdmUtYWkvdHlwZXMnO1xuaW1wb3J0IHtcbiAgYW1wbGl0dWRlQXBpS2V5QXRvbSxcbiAgY29udGV4dFNvdXJjZUF0b20sXG4gIGRhdGFSZXNpZGVuY3lBdG9tLFxuICBpZGVudGlmeWluZ1ByZWZpeEF0b20sXG59IGZyb20gJ3NyYy9hdG9tcy9lbnZpdmUvZW52aXZlQ29uZmlnJztcbmltcG9ydCB7IHVzZUxvY2FsU3RvcmFnZSB9IGZyb20gJ3NyYy9jb250ZXh0cy9sb2NhbFN0b3JhZ2VDb250ZXh0JztcbmltcG9ydCB7IG9yZ0FuYWx5dGljc0dvb2dsZUFuYWx5dGljc0NvbmZpZ0F0b20gfSBmcm9tICdzcmMvYXRvbXMvb3JnL29yZ0FuYWx5dGljc0NvbmZpZyc7XG5pbXBvcnQgeyB1c2VySWRBdG9tIH0gZnJvbSAnc3JjL2F0b21zL2FwcCc7XG5pbXBvcnQgeyBlbnZBdG9tIH0gZnJvbSAnc3JjL2F0b21zL2Vudml2ZS9lbnZpdmVDb25maWcnO1xuaW1wb3J0IExvZ2dlciBmcm9tICdzcmMvYXBwbGljYXRpb24vbG9nZ2luZy9sb2dnZXInO1xuaW1wb3J0IHR5cGUge1xuICBCcm93c2VyQ2xpZW50LFxuICBFbnJpY2htZW50UGx1Z2luLFxuICBFdmVudCxcbiAgU2VydmVyWm9uZVR5cGUsXG59IGZyb20gJ0BhbXBsaXR1ZGUvYW5hbHl0aWNzLXR5cGVzJztcbmltcG9ydCB7IHVzZUVudml2ZUNvbmZpZyB9IGZyb20gJ3NyYy9jb250ZXh0cy9lbnZpdmVDb25maWdDb250ZXh0L2Vudml2ZUNvbmZpZ0NvbnRleHQnO1xuaW1wb3J0IHsgdXNlRmVhdHVyZUZsYWdTZXJ2aWNlIH0gZnJvbSAnc3JjL2NvbnRleHRzL2ZlYXR1cmVGbGFnU2VydmljZUNvbnRleHQvZmVhdHVyZUZsYWdTZXJ2aWNlQ29udGV4dCc7XG5pbXBvcnQgeyBFdmVudHNEaXNwYXRjaGVyIH0gZnJvbSAnc3JjL2V2ZW50cyc7XG5cbmV4cG9ydCBlbnVtIFNwaWZmeU1ldHJpY3NFdmVudE5hbWUge1xuICBCdW5kbGVMb2FkZWQgPSAnQnVuZGxlIExvYWRlZCcsXG4gIENoYXRMaXZlQWdlbnRCdG5DbGljayA9ICdDaGF0IExpdmUgQWdlbnQgQnRuIENsaWNrJyxcbiAgQ2hhdEZsb2F0aW5nQnV0dG9uVmlzaWJsZSA9ICdDaGF0IEZsb2F0aW5nIEJ1dHRvbiBWaXNpYmxlJyxcbiAgQ2hhdENvbXBvbmVudFZpc2libGUgPSAnQ2hhdCBDb21wb25lbnQgVmlzaWJsZScsXG4gIENoYXRDb21wb25lbnRFeHBhbmRlZCA9ICdDaGF0IENvbXBvbmVudCBFeHBhbmRlZCcsXG4gIENoYXRDb21wb25lbnRDb2xsYXBzZWQgPSAnQ2hhdCBDb21wb25lbnQgQ29sbGFwc2VkJyxcbiAgQ2hhdFVzZXJNZXNzYWdlSW5wdXQgPSAnQ2hhdCBVc2VyIE1lc3NhZ2UgSW5wdXQnLFxuICBDaGF0U3VnZ2VzdGlvbkNsaWNrZWQgPSAnQ2hhdCBTdWdnZXN0aW9uIENsaWNrZWQnLFxuICBDaGF0QXNzaXN0YW50UmVzcG9uc2UgPSAnQ2hhdCBBc3Npc3RhbnQgUmVzcG9uc2UnLFxuICBQcm9kdWN0Q2FyZENsaWNrZWQgPSAnUHJvZHVjdCBDYXJkIENsaWNrZWQnLFxuICBQcm9kdWN0UmV2aWV3Q2FyZENsaWNrZWQgPSAnUHJvZHVjdCBSZXZpZXcgQ2FyZCBDbGlja2VkJyxcbiAgQWRkVG9DYXJ0Q2xpY2tlZCA9ICdBZGQgdG8gQ2FydCBDbGlja2VkJyxcbiAgUHJvbXB0Q2FyZENsaWNrZWQgPSAnUHJvbXB0IENhcmQgQ2xpY2tlZCcsXG4gIFN1cHBvcnRlZEV2ZW50ID0gJ1N1cHBvcnRlZCBFdmVudCcsXG4gIFNlYXJjaEJhY2tUb1Jlc3BvbnNlQ2xpY2tlZCA9ICdTZWFyY2ggQmFjayB0byBSZXNwb25zZSBDbGlja2VkJyxcbiAgUGVyZm9ybWFuY2VNZXRyaWNzID0gJ1BlcmZvcm1hbmNlIE1ldHJpY3MnLFxuICBTZWFyY2hCYXJDbGlja2VkID0gJ1NlYXJjaCBCYXIgQ2xpY2tlZCcsXG4gIE9yZGVyTG9va3VwU3RhcnRlZCA9ICdPcmRlciBMb29rdXAgU3RhcnRlZCcsXG4gIE9yZGVyTG9va3VwRm9ybVN1Ym1pdHRlZCA9ICdPcmRlciBMb29rdXAgRm9ybSBTdWJtaXR0ZWQnLFxuICBTZWFyY2hDb21wb25lbnRWaXNpYmxlID0gJ1NlYXJjaCBDb21wb25lbnQgVmlzaWJsZScsXG4gIFNlYXJjaFplcm9TdGF0ZVN1Z2dlc3Rpb25DbGlja2VkID0gJ1NlYXJjaCBaZXJvIFN0YXRlIFN1Z2dlc3Rpb24gQ2xpY2tlZCcsIC8vIFRoaXMgaXMgdGhlIHNjcm9sbGluZyBsaXN0IG9mIHN1Z2dlc3Rpb24gYnV0dG9ucyBpbiBnbG9iYWwgc2VhcmNoXG4gIFNlYXJjaElucHV0U3RhcnRlZCA9ICdTZWFyY2ggSW5wdXQgU3RhcnRlZCcsXG4gIFNlYXJjaFF1ZXJ5U3VibWl0dGVkID0gJ1NlYXJjaCBRdWVyeSBTdWJtaXR0ZWQnLFxuICAvLyBTZWFyY2hBdXRvY29tcGxldGVWaWV3ZWQgPSAnU2VhcmNoIEF1dG9jb21wbGV0ZSBWaWV3ZWQnLCAvLyBUT0RPOiBhZGQgdGhpcyB3aGVuIGF1dG9jb21wbGV0ZSBpcyBhZGRlZFxuICAvLyBTZWFyY2hBdXRvY29tcGxldGVDbGlja2VkID0gJ1NlYXJjaCBBdXRvY29tcGxldGUgQ2xpY2tlZCcsIC8vIFRPRE86IGFkZCB0aGlzIHdoZW4gYXV0b2NvbXBsZXRlIGlzIGFkZGVkXG4gIFNlYXJjaFJlc3VsdHNWaWV3ZWQgPSAnU2VhcmNoIFJlc3VsdHMgVmlld2VkJyxcbiAgU2VhcmNoVGltZVRvRmlyc3RDbGljayA9ICdTZWFyY2ggVGltZSB0byBGaXJzdCBDbGljaycsXG4gIFNlYXJjaFplcm9SZXN1bHRzUmF0ZSA9ICdTZWFyY2ggWmVybyBSZXN1bHRzIFJhdGUnLFxuICBTZWFyY2hGaWx0ZXJDbGlja2VkID0gJ1NlYXJjaCBGaWx0ZXIgQ2xpY2tlZCcsXG4gIFNlYXJjaFNvcnRDbGlja2VkID0gJ1NlYXJjaCBTb3J0IENsaWNrZWQnLFxufVxuXG5pbnRlcmZhY2UgVHJhY2tFdmVudFBhcmFtcyB7XG4gIGV2ZW50TmFtZTogU3BpZmZ5TWV0cmljc0V2ZW50TmFtZTtcbiAgZXZlbnRQcm9wcz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICBldmVudEdyb3Vwcz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICBhbHNvU2VuZFRvR29vZ2xlQW5hbHl0aWNzPzogYm9vbGVhbjtcbn1cblxuaW50ZXJmYWNlIEFtcGxpdHVkZUNvbnRleHRUeXBlIHtcbiAgdHJhY2tFdmVudDogKHBhcmFtczogVHJhY2tFdmVudFBhcmFtcykgPT4gUHJvbWlzZTx2b2lkPjtcbiAgaXNSZWFkeTogYm9vbGVhbjtcbiAgc2V0U3VwcGxlbWVudGFsRGVmYXVsdFByb3BzOiAocHJvcHM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PiB2b2lkO1xufVxuXG5jb25zdCBBbXBsaXR1ZGVDb250ZXh0ID0gY3JlYXRlQ29udGV4dDxBbXBsaXR1ZGVDb250ZXh0VHlwZSB8IG51bGw+KG51bGwpO1xuXG5leHBvcnQgY29uc3QgQW1wbGl0dWRlUHJvdmlkZXI6IFJlYWN0LkZDPHsgY2hpbGRyZW46IFJlYWN0LlJlYWN0Tm9kZSB9PiA9ICh7IGNoaWxkcmVuIH0pID0+IHtcbiAgY29uc3QgdXNlcklkID0gdXNlQXRvbVZhbHVlKHVzZXJJZEF0b20pO1xuICBjb25zdCBhbXBsaXR1ZGVBcGlLZXkgPSB1c2VBdG9tVmFsdWUoYW1wbGl0dWRlQXBpS2V5QXRvbSk7XG4gIGNvbnN0IGRhdGFSZXNpZGVuY3kgPSB1c2VBdG9tVmFsdWUoZGF0YVJlc2lkZW5jeUF0b20pO1xuICBjb25zdCBvcmdHYUNvbmZpZyA9IHVzZUF0b21WYWx1ZShvcmdBbmFseXRpY3NHb29nbGVBbmFseXRpY3NDb25maWdBdG9tKTtcbiAgY29uc3QgZW52ID0gdXNlQXRvbVZhbHVlKGVudkF0b20pO1xuICBjb25zdCBjb250ZXh0U291cmNlID0gdXNlQXRvbVZhbHVlKGNvbnRleHRTb3VyY2VBdG9tKTtcbiAgY29uc3QgaWRlbnRpZnlpbmdQcmVmaXggPSB1c2VBdG9tVmFsdWUoaWRlbnRpZnlpbmdQcmVmaXhBdG9tKTtcbiAgY29uc3QgeyBnZXRJdGVtIH0gPSB1c2VMb2NhbFN0b3JhZ2UoKTtcbiAgY29uc3Qge1xuICAgIHB1YmxpY0tleSxcbiAgICBmZWF0dXJlT3ZlcnJpZGVzLFxuICAgIHZhcmlhbnRVcmxPdmVycmlkZSxcbiAgICB2YXJpYW50SW5mb092ZXJyaWRlLFxuICAgIHNob3csXG4gICAgb3JnU2hvcnROYW1lLFxuICAgIGZlYXR1cmVHYXRlcyxcbiAgfSA9IHVzZUVudml2ZUNvbmZpZygpO1xuXG4gIGNvbnN0IHsgZmVhdHVyZUZsYWdTZXJ2aWNlIH0gPSB1c2VGZWF0dXJlRmxhZ1NlcnZpY2UoKTtcblxuICBjb25zdCBbYW1wbGl0dWRlQ2xpZW50LCBzZXRBbXBsaXR1ZGVDbGllbnRdID0gUmVhY3QudXNlU3RhdGU8QnJvd3NlckNsaWVudCB8IHVuZGVmaW5lZD4oXG4gICAgdW5kZWZpbmVkLFxuICApO1xuICBjb25zdCBbaW50ZXJuYWxFdmVudFRyYWNraW5nRW5yaWNobWVudCwgc2V0SW50ZXJuYWxFdmVudFRyYWNraW5nRW5yaWNobWVudF0gPSBSZWFjdC51c2VTdGF0ZTxcbiAgICBFbnJpY2htZW50UGx1Z2luIHwgdW5kZWZpbmVkXG4gID4odW5kZWZpbmVkKTtcbiAgY29uc3QgW3N1cHBsZW1lbnRhbERlZmF1bHRQcm9wcywgc2V0U3VwcGxlbWVudGFsRGVmYXVsdFByb3BzXSA9IFJlYWN0LnVzZVN0YXRlPFxuICAgIFJlY29yZDxzdHJpbmcsIHVua25vd24+XG4gID4oe30pO1xuXG4gIGNvbnN0IGlzUmVhZHkgPSBCb29sZWFuKHVzZXJJZCAmJiBmZWF0dXJlRmxhZ1NlcnZpY2UgJiYgYW1wbGl0dWRlQXBpS2V5ICYmIHVzZXJJZCk7XG5cbiAgY29uc3QgZ2V0RGVmYXVsdFRyYWNraW5nUHJvcHMgPSB1c2VDYWxsYmFjaygoKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPT4ge1xuICAgIGNvbnN0IGdhdGVzUHJvcHMgPSBmZWF0dXJlR2F0ZXNcbiAgICAgID8gZmVhdHVyZUdhdGVzLnJlZHVjZTxSZWNvcmQ8c3RyaW5nLCBib29sZWFuPj4oKGFjYywgY3VycikgPT4ge1xuICAgICAgICAgIGlmIChjdXJyLm5hbWUgJiYgY3Vyci52YWx1ZSAhPSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4geyAuLi5hY2MsIFtgZmVhdHVyZV9nYXRlLiR7Y3Vyci5uYW1lfWBdOiBjdXJyLnZhbHVlIH07XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgIH0sIHt9KVxuICAgICAgOiB7fTtcbiAgICBjb25zdCBleHBlcmltZW50UHJvcHMgPSB7fTsgLy8gTm8gZGlyZWN0IGVxdWl2YWxlbnQgZm9yIGV4cGVyaW1lbnRzIGluIEVudml2ZUNvbmZpZyB5ZXRcblxuICAgIGNvbnN0IG9yZ0xldmVsQW1wbGl0dWRlVHJhY2tpbmdQcm9wcyA9IHtcbiAgICAgIC4uLmdhdGVzUHJvcHMsXG4gICAgICAuLi5leHBlcmltZW50UHJvcHMsXG4gICAgfTtcblxuICAgIHJldHVybiB7XG4gICAgICAuLi5vcmdMZXZlbEFtcGxpdHVkZVRyYWNraW5nUHJvcHMsXG4gICAgICAuLi5zdXBwbGVtZW50YWxEZWZhdWx0UHJvcHMsXG4gICAgICAvLyBUT0RPOiBvcmdfaWQgaXMgbm90IGRpcmVjdGx5IGF2YWlsYWJsZSBpbiBFbnZpdmVDb25maWcuIE5lZWQgdG8gZmluZCBhIG5ldyBzb3VyY2Ugb3IgZGVyaXZlIGl0LlxuICAgICAgLy8gb3JnX2lkOiBvcmdDb25maWc/Lm9yZz8ub3JnPy5pZCxcbiAgICAgIGFwcF9pZDogJ2NvbW1lcmNlLWNoYXQtcmVhY3QtY29tcG9uZW50JyxcbiAgICAgIGNoYXRfaWQ6IGdldEl0ZW0oTG9jYWxTdG9yYWdlS2V5cy5DaGF0SWQpLFxuICAgICAgZW52OiBlbnYgfHwgJ3Vua25vd24nLFxuICAgICAgYXBwX3NvdXJjZTogY29udGV4dFNvdXJjZSxcbiAgICAgICdvcmcuc2hvcnRfbmFtZSc6IG9yZ1Nob3J0TmFtZSxcbiAgICAgICd1c2VyLmlkJzogdXNlcklkLFxuICAgICAgJ2NkcC51c2VyX2lkJzogbnVsbCxcbiAgICAgICdjZHAucHJvdmlkZXInOiBudWxsLFxuICAgICAgJ2V2ZW50LnNvdXJjZSc6ICd3ZWItYnJvd3NlcicsXG4gICAgICAnZXZlbnQudHlwZSc6ICd1c2VyLWFjdGl2aXR5JyxcbiAgICAgICdldmVudC5pZCc6IG51bGwsXG4gICAgICAnZXZlbnQuY2hhbm5lbCc6ICd3ZWInLFxuICAgICAgJ2V2ZW50LnRpbWVzdGFtcCc6IG51bGwsXG4gICAgfTtcbiAgfSwgW2ZlYXR1cmVHYXRlcywgc3VwcGxlbWVudGFsRGVmYXVsdFByb3BzLCBlbnYsIGNvbnRleHRTb3VyY2UsIG9yZ1Nob3J0TmFtZSwgdXNlcklkXSk7XG5cbiAgY29uc3QgZXZlbnRQcm9wc1RvUHJlZml4ZWRFdmVudFByb3BzID0gdXNlQ2FsbGJhY2soXG4gICAgKFxuICAgICAgZXZlbnROYW1lOiBTcGlmZnlNZXRyaWNzRXZlbnROYW1lLFxuICAgICAgZXZlbnRQcm9wczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gICAgKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPT4ge1xuICAgICAgY29uc3QgcHJlZml4ID0gZXZlbnROYW1lLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvXFxzKy9nLCAnXycpO1xuICAgICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKGV2ZW50UHJvcHMpLnJlZHVjZShcbiAgICAgICAgKGFjYywgW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICAgICAgYWNjW2Ake3ByZWZpeH0uJHtrZXl9YF0gPSB2YWx1ZTtcbiAgICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgICB9LFxuICAgICAgICB7fSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbiAgICAgICk7XG4gICAgfSxcbiAgICBbXSxcbiAgKTtcblxuICBjb25zdCBhbXBsaXR1ZGVTZXNzaW9uUmVwbGF5SW5pdCA9IHVzZUNhbGxiYWNrKCgpOiBib29sZWFuID0+IHtcbiAgICBjb25zdCBpc0VuYWJsZWQgPSBCb29sZWFuKFxuICAgICAgb3JnU2hvcnROYW1lID09PSBPcmdTaG9ydE5hbWUuVW5pcXVlVmludGFnZSAmJlxuICAgICAgICBmZWF0dXJlRmxhZ1NlcnZpY2U/LmlzQ2xpZW50U2Vzc2lvbkVuYWJsZWQoKSAmJlxuICAgICAgICBmZWF0dXJlRmxhZ1NlcnZpY2U/LmlzRmVhdHVyZUdhdGVFbmFibGVkKEZlYXR1cmVHYXRlcy5Jc05ld0ZlYXR1cmVFbmFibGVkKSxcbiAgICApO1xuICAgIGNvbnN0IHNhbXBsZVJhdGUgPSAxO1xuXG4gICAgdHJ5IHtcbiAgICAgIExvZ2dlci5sb2dEZWJ1ZyhcbiAgICAgICAgYFtzcGlmZnktYWldIGFtcGxpdHVkZSBzZXNzaW9uLXJlcGxheSBpbml0aWFsaXppbmcgaXNFbmFibGVkPSR7aXNFbmFibGVkfSBzYW1wbGVSYXRlPSR7c2FtcGxlUmF0ZX1gLFxuICAgICAgKTtcblxuICAgICAgaWYgKCFpc0VuYWJsZWQpIHtcbiAgICAgICAgcmV0dXJuIGlzRW5hYmxlZDtcbiAgICAgIH1cblxuICAgICAgLy8gYW1wbGl0dWRlSW5zdGFuY2UuYWRkKHNlc3Npb25SZXBsYXlQbHVnaW4oeyBzYW1wbGVSYXRlIH0pKTtcblxuICAgICAgcmV0dXJuIGlzRW5hYmxlZDtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBMb2dnZXIubG9nRXJyb3IoJ1tzcGlmZnktYWldIEVycm9yIGluaXRpYWxpemluZyBhbXBsaXR1ZGUgc2Vzc2lvbi1yZXBsYXknLCBlKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH0sIFtvcmdTaG9ydE5hbWUsIGZlYXR1cmVGbGFnU2VydmljZV0pO1xuXG4gIGNvbnN0IGdldEV2ZW50VHJhY2tpbmdFbnJpY2htZW50ID0gdXNlQ2FsbGJhY2soKCk6IEVucmljaG1lbnRQbHVnaW4gPT4ge1xuICAgIGlmIChpbnRlcm5hbEV2ZW50VHJhY2tpbmdFbnJpY2htZW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBpbnRlcm5hbEV2ZW50VHJhY2tpbmdFbnJpY2htZW50O1xuICAgIH1cblxuICAgIGNvbnN0IGVucmljaG1lbnQ6IEVucmljaG1lbnRQbHVnaW4gPSB7XG4gICAgICBuYW1lOiAncGFnZS12aWV3LXRyYWNraW5nLWVucmljaG1lbnQnLFxuICAgICAgdHlwZTogJ2VucmljaG1lbnQnLFxuICAgICAgc2V0dXA6IGFzeW5jICgpID0+IHVuZGVmaW5lZCxcbiAgICAgIGV4ZWN1dGU6IGFzeW5jIChldmVudDogRXZlbnQpOiBQcm9taXNlPEV2ZW50PiA9PiB7XG4gICAgICAgIGxldCBlbnJpY2hlZEV2ZW50OiBFdmVudDtcblxuICAgICAgICBjb25zdCBldmVudHNUb0VucmljaCA9IFtcbiAgICAgICAgICAnW0FtcGxpdHVkZV0gUGFnZSBWaWV3ZWQnLFxuICAgICAgICAgIGBbU3BpZmZ5XSAke1NwaWZmeU1ldHJpY3NFdmVudE5hbWUuQnVuZGxlTG9hZGVkfWAsXG4gICAgICAgIF07XG5cbiAgICAgICAgaWYgKGV2ZW50c1RvRW5yaWNoLmluY2x1ZGVzKGV2ZW50LmV2ZW50X3R5cGUpKSB7XG4gICAgICAgICAgY29uc3QgZ2xvYmFsUHJvcGVydGllczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuXG4gICAgICAgICAgaWYgKHB1YmxpY0tleSkge1xuICAgICAgICAgICAgZ2xvYmFsUHJvcGVydGllc1snZ2xvYmFsUHJvcGVydGllcy5wdWJsaWNLZXknXSA9IHB1YmxpY0tleTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGZlYXR1cmVPdmVycmlkZXMpIHtcbiAgICAgICAgICAgIE9iamVjdC5lbnRyaWVzKGZlYXR1cmVPdmVycmlkZXMpLmZvckVhY2goKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgICAgICAgICBnbG9iYWxQcm9wZXJ0aWVzW2BnbG9iYWxQcm9wZXJ0aWVzLmZlYXR1cmVPdmVycmlkZXMuJHtrZXl9YF0gPSBTdHJpbmcodmFsdWUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh2YXJpYW50VXJsT3ZlcnJpZGUpIHtcbiAgICAgICAgICAgIGdsb2JhbFByb3BlcnRpZXNbJ2dsb2JhbFByb3BlcnRpZXMudmFyaWFudFVybE92ZXJyaWRlJ10gPSB2YXJpYW50VXJsT3ZlcnJpZGU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh2YXJpYW50SW5mb092ZXJyaWRlKSB7XG4gICAgICAgICAgICBnbG9iYWxQcm9wZXJ0aWVzWydnbG9iYWxQcm9wZXJ0aWVzLnZhcmlhbnRJbmZvT3ZlcnJpZGUnXSA9XG4gICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHZhcmlhbnRJbmZvT3ZlcnJpZGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoc2hvdyAhPSBudWxsKSB7XG4gICAgICAgICAgICBnbG9iYWxQcm9wZXJ0aWVzWydnbG9iYWxQcm9wZXJ0aWVzLnNob3cnXSA9IFN0cmluZyhzaG93KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBlbmFibGVkRmVhdHVyZXMgPSBmZWF0dXJlRmxhZ1NlcnZpY2UhLmdldEZlYXR1cmVGbGFncygpO1xuICAgICAgICAgIGNvbnN0IGVuYWJsZWRGZWF0dXJlc1Byb3BlcnRpZXMgPSBPYmplY3QuZW50cmllcyhlbmFibGVkRmVhdHVyZXMpLnJlZHVjZTxcbiAgICAgICAgICAgIFJlY29yZDxzdHJpbmcsIHN0cmluZz5cbiAgICAgICAgICA+KFxuICAgICAgICAgICAgKGFjYywgW2tleSwgdmFsdWVdKSA9PiAoe1xuICAgICAgICAgICAgICAuLi5hY2MsXG4gICAgICAgICAgICAgIFtgZW5hYmxlZEZlYXR1cmVzLiR7a2V5fWBdOiBgJHt2YWx1ZX1gLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB7fSxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgY29uc3QgdGltaW5nUHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgICd0aW1pbmcuZW5yaWNoZWRfYXRfbXMnOiB3aW5kb3cucGVyZm9ybWFuY2U/Lm5vdygpLFxuICAgICAgICAgIH07XG5cbiAgICAgICAgICBlbnJpY2hlZEV2ZW50ID0ge1xuICAgICAgICAgICAgLi4uZXZlbnQsXG4gICAgICAgICAgICBldmVudF9wcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgIC4uLmV2ZW50LmV2ZW50X3Byb3BlcnRpZXMsXG4gICAgICAgICAgICAgIC4uLmdldERlZmF1bHRUcmFja2luZ1Byb3BzKCksXG4gICAgICAgICAgICAgIC4uLmdsb2JhbFByb3BlcnRpZXMsXG4gICAgICAgICAgICAgIC4uLmVuYWJsZWRGZWF0dXJlc1Byb3BlcnRpZXMsXG4gICAgICAgICAgICAgIC4uLnRpbWluZ1Byb3BlcnRpZXMsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZW5yaWNoZWRFdmVudCA9IGV2ZW50O1xuICAgICAgICB9XG5cbiAgICAgICAgRXZlbnRzRGlzcGF0Y2hlci5kaXNwYXRjaChTcGlmZnlFdmVudC5BTVBMSVRVREVfRVZFTlQsIGVucmljaGVkRXZlbnQpO1xuXG4gICAgICAgIHJldHVybiBlbnJpY2hlZEV2ZW50O1xuICAgICAgfSxcbiAgICB9O1xuICAgIHNldEludGVybmFsRXZlbnRUcmFja2luZ0VucmljaG1lbnQoZW5yaWNobWVudCk7XG4gICAgcmV0dXJuIGVucmljaG1lbnQ7XG4gIH0sIFtcbiAgICBpbnRlcm5hbEV2ZW50VHJhY2tpbmdFbnJpY2htZW50LFxuICAgIGdldERlZmF1bHRUcmFja2luZ1Byb3BzLFxuICAgIGZlYXR1cmVGbGFnU2VydmljZSxcbiAgICBwdWJsaWNLZXksXG4gICAgZmVhdHVyZU92ZXJyaWRlcyxcbiAgICB2YXJpYW50VXJsT3ZlcnJpZGUsXG4gICAgdmFyaWFudEluZm9PdmVycmlkZSxcbiAgICBzaG93LFxuICBdKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChpc1JlYWR5ICYmICFhbXBsaXR1ZGVDbGllbnQpIHtcbiAgICAgIGNvbnN0IGN1cnJlbnRBbXBsaXR1ZGVJbnN0YW5jZTogQnJvd3NlckNsaWVudCA9IGNyZWF0ZUluc3RhbmNlKCk7XG4gICAgICBjb25zdCBpc1Nlc3Npb25zRW5hYmxlZCA9IGFtcGxpdHVkZVNlc3Npb25SZXBsYXlJbml0KCk7XG4gICAgICBjdXJyZW50QW1wbGl0dWRlSW5zdGFuY2UuYWRkKGdldEV2ZW50VHJhY2tpbmdFbnJpY2htZW50KCkpO1xuICAgICAgY3VycmVudEFtcGxpdHVkZUluc3RhbmNlLmluaXQoYW1wbGl0dWRlQXBpS2V5ISwgdXNlcklkISwge1xuICAgICAgICBzZXJ2ZXJab25lOiBkYXRhUmVzaWRlbmN5IGFzIFNlcnZlclpvbmVUeXBlLFxuICAgICAgICB0cmFja2luZ09wdGlvbnM6IHtcbiAgICAgICAgICBpcEFkZHJlc3M6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICAgIGF1dG9jYXB0dXJlOiB7XG4gICAgICAgICAgYXR0cmlidXRpb246IHRydWUsXG4gICAgICAgICAgcGFnZVZpZXdzOiB7XG4gICAgICAgICAgICB0cmFja0hpc3RvcnlDaGFuZ2VzOiAncGF0aE9ubHknLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc2Vzc2lvbnM6IGlzU2Vzc2lvbnNFbmFibGVkLFxuICAgICAgICAgIGZvcm1JbnRlcmFjdGlvbnM6IGZhbHNlLFxuICAgICAgICAgIGZpbGVEb3dubG9hZHM6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBzZXRBbXBsaXR1ZGVDbGllbnQoY3VycmVudEFtcGxpdHVkZUluc3RhbmNlKTtcbiAgICB9XG4gIH0sIFtcbiAgICBpc1JlYWR5LFxuICAgIGFtcGxpdHVkZUNsaWVudCxcbiAgICBhbXBsaXR1ZGVBcGlLZXksXG4gICAgdXNlcklkLFxuICAgIGRhdGFSZXNpZGVuY3ksXG4gICAgYW1wbGl0dWRlU2Vzc2lvblJlcGxheUluaXQsXG4gICAgZ2V0RXZlbnRUcmFja2luZ0VucmljaG1lbnQsXG4gIF0pO1xuXG4gIGNvbnN0IHRyYWNrRXZlbnQgPSB1c2VDYWxsYmFjayhcbiAgICBhc3luYyAoe1xuICAgICAgZXZlbnROYW1lLFxuICAgICAgZXZlbnRQcm9wcyxcbiAgICAgIGV2ZW50R3JvdXBzLFxuICAgICAgYWxzb1NlbmRUb0dvb2dsZUFuYWx5dGljcyA9IGZhbHNlLFxuICAgIH06IFRyYWNrRXZlbnRQYXJhbXMpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICAgIExvZ2dlci5sb2dEZWJ1ZygnU3VibWl0dGluZyBldmVudCcsIGV2ZW50TmFtZSk7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBkZWNvcmF0ZWRFdmVudE5hbWUgPSBgW1NwaWZmeV0gJHtldmVudE5hbWV9YDtcblxuICAgICAgICBpZiAoIWFtcGxpdHVkZUNsaWVudCkge1xuICAgICAgICAgIExvZ2dlci5sb2dXYXJuKCdhbXBsaXR1ZGUgY2xpZW50IHVuZGVmaW5lZCcsIHVuZGVmaW5lZCwge1xuICAgICAgICAgICAgZXZlbnRfbmFtZTogZGVjb3JhdGVkRXZlbnROYW1lLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGV2ZW50RGF0YSA9IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICBldmVudE5hbWUsXG4gICAgICAgICAgZXZlbnRQcm9wcyxcbiAgICAgICAgICBjcmVhdGVkX2F0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBlbmNvZGVyID0gbmV3IFRleHRFbmNvZGVyKCk7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBlbmNvZGVyLmVuY29kZShldmVudERhdGEpO1xuICAgICAgICAvLyBjYWxjdWxhdGUgYSBoYXNoIG9mIHRoZSBldmVudCBwcm9wZXJ0aWVzIHRvIHVzZSBhcyB0aGUgaW5zZXJ0X2lkIHNvIHRoYXQgZHVwbGljYXRlIGV2ZW50c1xuICAgICAgICAvLyBhcmUgYXV0b21hdGljYWxseSBkcm9wcGVkIGJ5IEFtcGxpdHVkZVxuICAgICAgICBjb25zdCBoYXNoQnVmZmVyID0gYXdhaXQgY3J5cHRvLnN1YnRsZS5kaWdlc3QoJ1NIQS0yNTYnLCBkYXRhKTtcbiAgICAgICAgY29uc3QgaGFzaEFycmF5ID0gQXJyYXkuZnJvbShuZXcgVWludDhBcnJheShoYXNoQnVmZmVyKSk7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRJbnNlcnRJZCA9IGhhc2hBcnJheS5tYXAoKGIpID0+IGIudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDIsICcwJykpLmpvaW4oJycpO1xuXG4gICAgICAgIExvZ2dlci5sb2dEZWJ1ZyhgYW1wbGl0dWRlIHRyYWNraW5nICR7ZGVjb3JhdGVkRXZlbnROYW1lfWAsIG51bGwsIHtcbiAgICAgICAgICBldmVudF9uYW1lOiBkZWNvcmF0ZWRFdmVudE5hbWUsXG4gICAgICAgICAgcHJvcHM6IGV2ZW50UHJvcHMsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGFtcGxpdHVkZUNsaWVudC50cmFjayhcbiAgICAgICAgICBkZWNvcmF0ZWRFdmVudE5hbWUsXG4gICAgICAgICAge1xuICAgICAgICAgICAgLi4uZ2V0RGVmYXVsdFRyYWNraW5nUHJvcHMoKSxcbiAgICAgICAgICAgIC4uLmV2ZW50UHJvcHMsXG4gICAgICAgICAgICAuLi4oZXZlbnRQcm9wcyA/IGV2ZW50UHJvcHNUb1ByZWZpeGVkRXZlbnRQcm9wcyhldmVudE5hbWUsIGV2ZW50UHJvcHMpIDoge30pLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgLi4uZXZlbnRHcm91cHMsXG4gICAgICAgICAgICBpbnNlcnRfaWQ6IGN1cnJlbnRJbnNlcnRJZCxcbiAgICAgICAgICB9LFxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChhbHNvU2VuZFRvR29vZ2xlQW5hbHl0aWNzICYmIG9yZ0dhQ29uZmlnKSB7XG4gICAgICAgICAgLy8gVE9ETzogQWRkIGluIHdpbmRvd0RhdGFMYXllclNlcnZpY2Ugb3IgY29udGV4dCBhbHRlcm5hdGl2ZSBhbmQgaG9vayBpdCB1cCBoZXJlXG4gICAgICAgICAgTG9nZ2VyLmxvZ0RlYnVnKCdbc3BpZmZ5LWFpXSBHQSB0cmFja2luZycsIGRlY29yYXRlZEV2ZW50TmFtZSk7XG4gICAgICAgICAgaWYgKHdpbmRvdy5kYXRhTGF5ZXIpIHtcbiAgICAgICAgICAgICh3aW5kb3cuZGF0YUxheWVyIGFzIGFueVtdKS5wdXNoKHtcbiAgICAgICAgICAgICAgZXZlbnQ6IGRlY29yYXRlZEV2ZW50TmFtZSxcbiAgICAgICAgICAgICAgZXZlbnRQcm9wczogZXZlbnRQcm9wcyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIExvZ2dlci5sb2dFcnJvcignW3NwaWZmeS1haV0gRXJyb3IgdHJhY2tpbmcgZXZlbnQnLCBlcnIsIHtcbiAgICAgICAgICBldmVudE5hbWUsXG4gICAgICAgICAgZXZlbnRQcm9wcyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSxcbiAgICBbYW1wbGl0dWRlQ2xpZW50LCBnZXREZWZhdWx0VHJhY2tpbmdQcm9wcywgZXZlbnRQcm9wc1RvUHJlZml4ZWRFdmVudFByb3BzLCBvcmdHYUNvbmZpZ10sXG4gICk7XG5cbiAgY29uc3QgdmFsdWUgPSB1c2VNZW1vKFxuICAgICgpID0+ICh7XG4gICAgICB0cmFja0V2ZW50LFxuICAgICAgaXNSZWFkeSxcbiAgICAgIHNldFN1cHBsZW1lbnRhbERlZmF1bHRQcm9wczogKHByb3BzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikgPT5cbiAgICAgICAgc2V0U3VwcGxlbWVudGFsRGVmYXVsdFByb3BzKHByb3BzKSxcbiAgICB9KSxcbiAgICBbdHJhY2tFdmVudCwgaXNSZWFkeSwgc2V0U3VwcGxlbWVudGFsRGVmYXVsdFByb3BzXSxcbiAgKTtcblxuICByZXR1cm4gPEFtcGxpdHVkZUNvbnRleHQuUHJvdmlkZXIgdmFsdWU9e3ZhbHVlfT57Y2hpbGRyZW59PC9BbXBsaXR1ZGVDb250ZXh0LlByb3ZpZGVyPjtcbn07XG5cbmV4cG9ydCBjb25zdCB1c2VBbXBsaXR1ZGUgPSAoKSA9PiB7XG4gIGNvbnN0IGNvbnRleHQgPSB1c2VDb250ZXh0KEFtcGxpdHVkZUNvbnRleHQpO1xuICBpZiAoIWNvbnRleHQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3VzZUFtcGxpdHVkZSBtdXN0IGJlIHVzZWQgd2l0aGluIEFtcGxpdHVkZVByb3ZpZGVyJyk7XG4gIH1cbiAgcmV0dXJuIGNvbnRleHQ7XG59O1xuIiwiaW1wb3J0IExvZ2dlciBmcm9tICdzcmMvYXBwbGljYXRpb24vbG9nZ2luZy9sb2dnZXInO1xuaW1wb3J0IHtcbiAgaXNMZWdhY3lVQUVjb21tZXJjZUV2ZW50LFxuICBpc0dBNEVjb21tZXJjZUV2ZW50LFxuICBpc0Jhc2VFY29tbWVyY2VFdmVudCxcbn0gZnJvbSAnc3JjL2FwcGxpY2F0aW9uL21vZGVscyc7XG5pbXBvcnQgeyBCYXNlRWNvbW1lcmNlRXZlbnQgfSBmcm9tICdAZW52aXZlLWFpL3R5cGVzJztcbmltcG9ydCB7IFNwaWZmeU1ldHJpY3NFdmVudE5hbWUgfSBmcm9tICdzcmMvY29udGV4dHMvYW1wbGl0dWRlQ29udGV4dC9hbXBsaXR1ZGVDb250ZXh0JztcblxuY29uc3QgTk9STUFMSVpFRF9BRERfVE9fQ0FSVF9FVkVOVF9OQU1FUyA9IFsnYWRkdG9jYXJ0JywgJ2FkZGVkdG9jYXJ0J107XG5jb25zdCBDSEVDS19EQVRBX0xBWUVSX0lOVEVSVkFMX01TID0gNTAwO1xuY29uc3QgQ0hFQ0tfREFUQV9MQVlFUl9NQVhfQVRURU1QVFMgPSAxMDtcblxuLyoqXG4gKiBDaGVja3MgaWYgYSBHb29nbGUgQW5hbHl0aWNzIGV2ZW50IGlzIGFuIGFkZF90b19jYXJ0IGV2ZW50LlxuICpcbiAqIEBwYXJhbSBldmVudCBUaGUgZXZlbnQgbmFtZSB0byBjaGVjay5cbiAqXG4gKiBAcmV0dXJucyBUcnVlIGlmIHRoZSBldmVudCBpcyBhbiBhZGRfdG9fY2FydCBldmVudCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICovXG5jb25zdCBpc0FkZFRvQ2FydEV2ZW50ID0gKGV2ZW50OiBzdHJpbmcpOiBib29sZWFuID0+IHtcbiAgY29uc3Qgbm9ybWFsaXplZEV2ZW50ID0gZXZlbnQucmVwbGFjZSgvWy1fXS9nLCAnJykudG9Mb3dlckNhc2UoKTtcbiAgcmV0dXJuIE5PUk1BTElaRURfQUREX1RPX0NBUlRfRVZFTlRfTkFNRVMuc29tZSgobmFtZSkgPT4gbm9ybWFsaXplZEV2ZW50LmluY2x1ZGVzKG5hbWUpKTtcbn07XG5cbi8qKlxuICogVHJhY2tzIGFuIGFkZF90b19jYXJ0IGV2ZW50IGluIEFtcGxpdHVkZS5cbiAqXG4gKiBAcGFyYW0gZXZlbnQgVGhlIGV2ZW50IHRvIHRyYWNrLlxuICovXG5jb25zdCBoYW5kbGVBZGRUb0NhcnRFdmVudCA9IChcbiAgZXZlbnQ6IEJhc2VFY29tbWVyY2VFdmVudCxcbiAgdHJhY2s6IChldmVudE5hbWU6IFNwaWZmeU1ldHJpY3NFdmVudE5hbWUsIGV2ZW50UHJvcHM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikgPT4gdm9pZCxcbikgPT4ge1xuICBsZXQgZXZlbnRQcm9wczogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG5cbiAgaWYgKGlzTGVnYWN5VUFFY29tbWVyY2VFdmVudChldmVudCkpIHtcbiAgICBldmVudFByb3BzID0ge1xuICAgICAgaXRlbXM6IGV2ZW50LmVjb21tZXJjZS5hZGQucHJvZHVjdHMubWFwKChwcm9kdWN0KSA9PiAoe1xuICAgICAgICBpdGVtX25hbWU6IHByb2R1Y3QubmFtZSxcbiAgICAgICAgaXRlbV9jYXRlZ29yeTogcHJvZHVjdC5jYXRlZ29yeSxcbiAgICAgICAgcHJpY2U6IHByb2R1Y3QucHJpY2UsXG4gICAgICAgIHF1YW50aXR5OiBwcm9kdWN0LnF1YW50aXR5LFxuICAgICAgfSkpLFxuICAgICAgY3VycmVuY3k6IGV2ZW50LmVjb21tZXJjZS5hZGQuY3VycmVuY3lDb2RlLFxuICAgICAgZXZlbnRfZm9ybWF0X3ZlcnNpb246ICdsZWdhY3lfdW5pdmVyc2FsX2FuYWx5dGljcycsXG4gICAgfTtcbiAgfSBlbHNlIGlmIChpc0dBNEVjb21tZXJjZUV2ZW50KGV2ZW50KSkge1xuICAgIGV2ZW50UHJvcHMgPSB7XG4gICAgICBpdGVtczogZXZlbnQuZWNvbW1lcmNlLml0ZW1zLm1hcCgoaXRlbSkgPT4gKHtcbiAgICAgICAgaXRlbV9uYW1lOiBpdGVtLml0ZW1fbmFtZSxcbiAgICAgICAgaXRlbV9jYXRlZ29yeTogaXRlbS5pdGVtX2NhdGVnb3J5LFxuICAgICAgICBwcmljZTogaXRlbS5wcmljZSxcbiAgICAgICAgcXVhbnRpdHk6IGl0ZW0ucXVhbnRpdHksXG4gICAgICB9KSksXG4gICAgICBjdXJyZW5jeTogZXZlbnQuZWNvbW1lcmNlLmN1cnJlbmN5LFxuICAgICAgZXZlbnRfZm9ybWF0X3ZlcnNpb246ICdnb29nbGVfYW5hbHl0aWNzXzQnLFxuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgZXZlbnRQcm9wcyA9IHtcbiAgICAgIGV2ZW50X3Byb3BlcnRpZXM6IHsgLi4uZXZlbnQgfSxcbiAgICAgIGV2ZW50X2Zvcm1hdF92ZXJzaW9uOiAndW5rbm93bicsXG4gICAgfTtcbiAgfVxuXG4gIHRyYWNrKFNwaWZmeU1ldHJpY3NFdmVudE5hbWUuQWRkVG9DYXJ0Q2xpY2tlZCwge1xuICAgIGV2ZW50UHJvcHMsXG4gIH0pO1xufTtcblxuLyoqXG4gKiBXcmFwcyB0aGUgd2luZG93LmRhdGFMYXllci5wdXNoIG1ldGhvZCB0byBpbnRlcmNlcHQgYWRkX3RvX2NhcnQgZXZlbnRzIGFuZCBzZW5kIHRoZW0gdG8gQW1wbGl0dWRlLlxuICogVGhpcyBmdW5jdGlvbiBydW5zIG9uIGFuIGludGVydmFsIHVudGlsIHRoZSBkYXRhTGF5ZXIgaXMgYXZhaWxhYmxlLlxuICovXG5leHBvcnQgY29uc3QgaW5pdERhdGFMYXllcldyYXBwZXIgPSAoXG4gIHRyYWNrOiAoZXZlbnROYW1lOiBTcGlmZnlNZXRyaWNzRXZlbnROYW1lLCBldmVudFByb3BzPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IHZvaWQsXG4pID0+IHtcbiAgbGV0IGF0dGVtcHRzID0gMDtcblxuICAvLyBjdXJyZW50bHksIG91ciBidW5kbGUgaXMgYWx3YXlzIGxvYWRlZCBhZnRlciBHVE0gaGFzIGluaXRpYWxpemVkIEdBL2RhdGFMYXllclxuICAvLyB3ZSdsbCBuZWVkIHRoaXMgY2hlY2sgaGVyZSBpZi93aGVuIHdlIGxvYWQgc3BpZmZ5IGJlZm9yZS9vdXRzaWRlIG9mIEdUTVxuICBjb25zdCBjaGVja0FuZEluaXRpYWxpemUgPSAoKSA9PiB7XG4gICAgaWYgKCF3aW5kb3cuZGF0YUxheWVyIHx8ICEod2luZG93LmRhdGFMYXllciBhcyBhbnkpLnB1c2gpIHtcbiAgICAgIGF0dGVtcHRzICs9IDE7XG5cbiAgICAgIGlmIChhdHRlbXB0cyA+PSBDSEVDS19EQVRBX0xBWUVSX01BWF9BVFRFTVBUUykge1xuICAgICAgICBMb2dnZXIubG9nRGVidWcoXG4gICAgICAgICAgYFtzcGlmZnktYWldIGRhdGFMYXllciBub3QgYXZhaWxhYmxlIGFmdGVyICR7Q0hFQ0tfREFUQV9MQVlFUl9NQVhfQVRURU1QVFN9IGF0dGVtcHRzYCxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBzZXRUaW1lb3V0KGNoZWNrQW5kSW5pdGlhbGl6ZSwgQ0hFQ0tfREFUQV9MQVlFUl9JTlRFUlZBTF9NUyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgTG9nZ2VyLmxvZ0RlYnVnKCdbc3BpZmZ5LWFpXSBkYXRhTGF5ZXIgaXMgYXZhaWxhYmxlLCB3cmFwcGluZyBwdXNoIGZ1bmN0aW9uLi4uJyk7XG4gICAgY29uc3Qgb3JpZ2luYWxQdXNoID0gd2luZG93LmRhdGFMYXllci5wdXNoO1xuICAgIHdpbmRvdy5kYXRhTGF5ZXIucHVzaCA9ICguLi5hcmdzOiB1bmtub3duW10pID0+IHtcbiAgICAgIGlmIChpc0Jhc2VFY29tbWVyY2VFdmVudChhcmdzWzBdKSAmJiBpc0FkZFRvQ2FydEV2ZW50KChhcmdzWzBdIGFzIGFueSkuZXZlbnQpKSB7XG4gICAgICAgIGhhbmRsZUFkZFRvQ2FydEV2ZW50KGFyZ3NbMF0gYXMgQmFzZUVjb21tZXJjZUV2ZW50LCB0cmFjayk7XG4gICAgICB9XG5cbiAgICAgIC8vIElNUE9SVEFOVDogY2FsbCB0aGUgb3JpZ2luYWwgcHVzaCBtZXRob2Qgc28gdGhhdCB0aGUgZXZlbnQgaXMgc3RpbGwgbG9nZ2VkIHRvIEdBXG4gICAgICByZXR1cm4gb3JpZ2luYWxQdXNoLmFwcGx5KHdpbmRvdy5kYXRhTGF5ZXIsIGFyZ3MpO1xuICAgIH07XG4gIH07XG5cbiAgY2hlY2tBbmRJbml0aWFsaXplKCk7XG59O1xuXG5leHBvcnQgY29uc3QgaW5pdEFtcGxpdHVkZSA9IChcbiAgdHJhY2s6IChldmVudE5hbWU6IFNwaWZmeU1ldHJpY3NFdmVudE5hbWUsIGV2ZW50UHJvcHM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikgPT4gdm9pZCxcbikgPT4ge1xuICAvLyBUaGlzIGZ1bmN0aW9uIG1pZ2h0IG5vdCBiZSBuZWVkZWQgYW55bW9yZSBpZiBBbXBsaXR1ZGUgaXMgaW5pdGlhbGl6ZWQgdmlhIGNvbnRleHQuXG4gIC8vIEZvciBub3csIHdlJ2xsIGtlZXAgaXQgYW5kIHBhc3MgdGhlIHRyYWNrIGZ1bmN0aW9uLlxuICAvLyBJZiBpdCdzIHRydWx5IHJlZHVuZGFudCwgaXQgY2FuIGJlIHJlbW92ZWQgbGF0ZXIuXG4gIHRyYWNrKFNwaWZmeU1ldHJpY3NFdmVudE5hbWUuQnVuZGxlTG9hZGVkKTsgLy8gRXhhbXBsZSB1c2FnZSwgYWRqdXN0IGFzIG5lZWRlZFxufTtcbiIsImltcG9ydCB7IENhbWVsQ2FzZWRQcm9wZXJ0aWVzRGVlcCB9IGZyb20gJ0BlbnZpdmUtYWkvdHlwZXMnO1xuaW1wb3J0IHsgQ29udGV4dCBhcyBBcGlDb250ZXh0IH0gZnJvbSAnQHNwaWZmeS1haS9jb21tZXJjZS1hcGktY2xpZW50JztcblxuaW50ZXJmYWNlIENvcmVDb250ZXh0IGV4dGVuZHMgQ2FtZWxDYXNlZFByb3BlcnRpZXNEZWVwPEFwaUNvbnRleHQ+IHt9XG5cbmV4cG9ydCBjb25zdCBjb3JlQ29udGV4dFRvQXBpQ29udGV4dCA9IChjb250ZXh0OiBDb3JlQ29udGV4dCk6IEFwaUNvbnRleHQgPT4gKHtcbiAgY2hhdF9pZDogY29udGV4dC5jaGF0SWQsXG4gIG9yZ19pZDogY29udGV4dC5vcmdJZCxcbiAgdXNlcl9pZDogY29udGV4dC51c2VySWQsXG4gIG9yZ19zaG9ydF9uYW1lOiBjb250ZXh0Lm9yZ1Nob3J0TmFtZSxcbiAgc291cmNlOiBjb250ZXh0LnNvdXJjZSxcbiAgZW52OiBjb250ZXh0LmVudixcbn0pO1xuIiwiaW1wb3J0IHsgVXNlckV2ZW50IH0gZnJvbSAnQGVudml2ZS1haS90eXBlcyc7XG5pbXBvcnQge1xuICBVc2VyRXZlbnQgYXMgQXBpVXNlckV2ZW50LFxuICBQTFBBdHRyaWJ1dGVDYXRlZ29yeSxcbiAgUExQSWRBdHRyaWJ1dGVzLFxuICBVc2VyRXZlbnRDYXRlZ29yeSxcbn0gZnJvbSAnQHNwaWZmeS1haS9jb21tZXJjZS1hcGktY2xpZW50JztcblxuZXhwb3J0IGNvbnN0IGNvcmVVc2VyRXZlbnRUb0FwaVVzZXJFdmVudCA9IChkYXRhOiBVc2VyRXZlbnQpOiBBcGlVc2VyRXZlbnQgPT4ge1xuICBpZiAoXG4gICAgZGF0YS5jYXRlZ29yeSA9PT0gVXNlckV2ZW50Q2F0ZWdvcnkuUGRwVmlzaXQgfHxcbiAgICBkYXRhLmNhdGVnb3J5ID09PSBVc2VyRXZlbnRDYXRlZ29yeS5BZGRUb0NhcnRcbiAgKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGV2ZW50X2lkOiBkYXRhLmV2ZW50SWQsXG4gICAgICBjcmVhdGVkX2F0OiBkYXRhLmNyZWF0ZWRBdCxcbiAgICAgIGNhdGVnb3J5OiBkYXRhLmNhdGVnb3J5LFxuICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICBwcm9kdWN0X2lkOiBkYXRhLmF0dHJpYnV0ZXMucHJvZHVjdElkLFxuICAgICAgICBwYXJlbnRfcHJvZHVjdF9pZDogZGF0YS5hdHRyaWJ1dGVzLnBhcmVudFByb2R1Y3RJZCxcbiAgICAgICAgdXJsOiBkYXRhLmF0dHJpYnV0ZXMudXJsLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgaWYgKGRhdGEuY2F0ZWdvcnkgPT09IFVzZXJFdmVudENhdGVnb3J5LlBscFZpc2l0KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGV2ZW50X2lkOiBkYXRhLmV2ZW50SWQsXG4gICAgICBjcmVhdGVkX2F0OiBkYXRhLmNyZWF0ZWRBdCxcbiAgICAgIGNhdGVnb3J5OiBkYXRhLmNhdGVnb3J5LFxuICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICBjYXRlZ29yeTogUExQQXR0cmlidXRlQ2F0ZWdvcnkuSWQsXG4gICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICAvLyB3ZSdyZSBvbmx5IGhhbmRsaW5nIGlkIGF0dHJpYnV0ZXMgZm9yIG5vd1xuICAgICAgICAgIGlkOiAoZGF0YS5hdHRyaWJ1dGVzLmF0dHJpYnV0ZXMgYXMgUExQSWRBdHRyaWJ1dGVzKS5pZCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIGlmIChkYXRhLmNhdGVnb3J5ID09PSBVc2VyRXZlbnRDYXRlZ29yeS5RdWVyeVR5cGVkKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGV2ZW50X2lkOiBkYXRhLmV2ZW50SWQsXG4gICAgICBjcmVhdGVkX2F0OiBkYXRhLmNyZWF0ZWRBdCxcbiAgICAgIGNhdGVnb3J5OiBkYXRhLmNhdGVnb3J5LFxuICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICBxdWVyeTogZGF0YS5hdHRyaWJ1dGVzLnF1ZXJ5LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgaWYgKGRhdGEuY2F0ZWdvcnkgPT09IFVzZXJFdmVudENhdGVnb3J5LlNlYXJjaCkge1xuICAgIHJldHVybiB7XG4gICAgICBldmVudF9pZDogZGF0YS5ldmVudElkLFxuICAgICAgY3JlYXRlZF9hdDogZGF0YS5jcmVhdGVkQXQsXG4gICAgICBjYXRlZ29yeTogZGF0YS5jYXRlZ29yeSxcbiAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgc2VhcmNoX3Rlcm06IGRhdGEuYXR0cmlidXRlcy5zZWFyY2hUZXJtLFxuICAgICAgICBzZWxlY3RlZF9maWx0ZXJzOiBkYXRhLmF0dHJpYnV0ZXMuc2VsZWN0ZWRGaWx0ZXJzLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgaWYgKGRhdGEuY2F0ZWdvcnkgPT09IFVzZXJFdmVudENhdGVnb3J5LlN1Z2dlc3Rpb25DbGlja2VkKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGV2ZW50X2lkOiBkYXRhLmV2ZW50SWQsXG4gICAgICBjcmVhdGVkX2F0OiBkYXRhLmNyZWF0ZWRBdCxcbiAgICAgIGNhdGVnb3J5OiBkYXRhLmNhdGVnb3J5LFxuICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICBzdWdnZXN0aW9uX2lkOiBkYXRhLmF0dHJpYnV0ZXMuc3VnZ2VzdGlvbklkLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgaWYgKGRhdGEuY2F0ZWdvcnkgPT09IFVzZXJFdmVudENhdGVnb3J5LlBhZ2VWaXNpdCkge1xuICAgIHJldHVybiB7XG4gICAgICBldmVudF9pZDogZGF0YS5ldmVudElkLFxuICAgICAgY3JlYXRlZF9hdDogZGF0YS5jcmVhdGVkQXQsXG4gICAgICBjYXRlZ29yeTogZGF0YS5jYXRlZ29yeSxcbiAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgdXJsOiBkYXRhLmF0dHJpYnV0ZXMudXJsLFxuICAgICAgICBwYWdlX3Zpc2l0X2NhdGVnb3J5OiBkYXRhLmF0dHJpYnV0ZXMucGFnZVZpc2l0Q2F0ZWdvcnksXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBpZiAoZGF0YS5jYXRlZ29yeSA9PT0gVXNlckV2ZW50Q2F0ZWdvcnkuRm9ybVN1Ym1pdHRlZCkge1xuICAgIHJldHVybiB7XG4gICAgICBldmVudF9pZDogZGF0YS5ldmVudElkLFxuICAgICAgY3JlYXRlZF9hdDogZGF0YS5jcmVhdGVkQXQsXG4gICAgICBjYXRlZ29yeTogZGF0YS5jYXRlZ29yeSxcbiAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgZmlsbGVkX3NjaGVtYTogeyAuLi5kYXRhLmF0dHJpYnV0ZXMuZmlsbGVkU2NoZW1hIH0sXG4gICAgICAgIGZvcm1fcmVzcG9uc2VfaWQ6IGRhdGEuYXR0cmlidXRlcy5mb3JtUmVzcG9uc2VJZCxcbiAgICAgICAgZm9ybV90eXBlOiBkYXRhLmF0dHJpYnV0ZXMuZm9ybVR5cGUsXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICAvLyBUaGlzIGlzIHRoZSBkZWZhdWx0IGFwcF9sb2FkZWQgZXZlbnQsIHdoZW4gd2Ugc3RhcnQgdG8gdXNlIGFwcF91bmxvYWRlZCB3ZSBuZWVkIHRvIGhhbmRsZSBpdCBoZXJlXG4gIHJldHVybiB7XG4gICAgZXZlbnRfaWQ6IGRhdGEuZXZlbnRJZCxcbiAgICBjcmVhdGVkX2F0OiBkYXRhLmNyZWF0ZWRBdCxcbiAgICBjYXRlZ29yeTogZGF0YS5jYXRlZ29yeSxcbiAgfTtcbn07XG4iLCJleHBvcnQgY29uc3QgZGl2aWRlQXJyYXkgPSA8VD4oYXJyYXk6IFRbXSwgc2l6ZTogbnVtYmVyKSA9PiB7XG4gIGNvbnN0IHJvd3MgPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaXplOyBpICs9IDEpIHtcbiAgICByb3dzLnB1c2goYXJyYXkuZmlsdGVyKChfOiBULCBpbmRleDogbnVtYmVyKSA9PiBpbmRleCAlIHNpemUgPT09IGkpKTtcbiAgfVxuICByZXR1cm4gcm93cztcbn07XG4iLCJpbXBvcnQgeyBNZXNzYWdlLCBNZXNzYWdlVHlwZSwgUHJvZHVjdE1lc3NhZ2VNZXRhZGF0YSB9IGZyb20gJ0BlbnZpdmUtYWkvdHlwZXMnO1xuXG5leHBvcnQgY29uc3QgZ2V0UmVjZW50UHJvZHVjdEltYWdlVXJscyA9IChcbiAgbGFzdE1lc3NhZ2VzOiBNZXNzYWdlW10sXG4gIGN1cnJlbnRQcm9kdWN0SWQ6IHN0cmluZyB8IHVuZGVmaW5lZCxcbikgPT4ge1xuICBjb25zdCBwcm9kdWN0TWVzc2FnZXMgPSBsYXN0TWVzc2FnZXNcbiAgICAuZmlsdGVyKChtZXNzYWdlKSA9PiBtZXNzYWdlLnR5cGUgPT09IE1lc3NhZ2VUeXBlLlByb2R1Y3QgJiYgbWVzc2FnZS5tZXRhZGF0YT8uaW1hZ2VVcmwpXG4gICAgLm1hcCgobSkgPT4gbSBhcyBQcm9kdWN0TWVzc2FnZU1ldGFkYXRhKTtcbiAgLy8gcHV0IGFkZGVkIHByb2R1Y3QgaW1hZ2UgYXQgdGhlIHRvcCBvZiB0aGUgbGlzdFxuICByZXR1cm4gW1xuICAgIC4uLnByb2R1Y3RNZXNzYWdlcy5maWx0ZXIoKG0pID0+IG0ubWV0YWRhdGE/LmlkID09PSBjdXJyZW50UHJvZHVjdElkKSxcbiAgICAuLi5wcm9kdWN0TWVzc2FnZXMuZmlsdGVyKChtKSA9PiBtLm1ldGFkYXRhPy5pZCAhPT0gY3VycmVudFByb2R1Y3RJZCksXG4gIF0ubWFwKChtKSA9PiBtLm1ldGFkYXRhIS5pbWFnZVVybCEpO1xufTtcbiIsImV4cG9ydCBjb25zdCBwcmVwYXJlTWVyY2hhbnRQYWdlID0gKCkgPT4ge1xuICBsZXQgbWV0YVZpZXdwb3J0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIm1ldGFbbmFtZT0ndmlld3BvcnQnXVwiKTtcbiAgaWYgKG1ldGFWaWV3cG9ydCkge1xuICAgIGNvbnN0IGNvbnRlbnQgPSBtZXRhVmlld3BvcnQuZ2V0QXR0cmlidXRlKFwiY29udGVudFwiKVxuICAgIGNvbnN0IGhhc01heGltdW1TY2FsZSA9IGNvbnRlbnQ/LmluY2x1ZGVzKFwibWF4aW11bS1zY2FsZT0xXCIpXG4gICAgaWYgKCFoYXNNYXhpbXVtU2NhbGUpIHtcbiAgICAgIG1ldGFWaWV3cG9ydC5zZXRBdHRyaWJ1dGUoXCJjb250ZW50XCIsIGAke2NvbnRlbnR9LCBtYXhpbXVtLXNjYWxlPTFgKVxuICAgIH1cbiAgICByZXR1cm5cbiAgfVxuXG4gIG1ldGFWaWV3cG9ydCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJtZXRhXCIpO1xuICBtZXRhVmlld3BvcnQuc2V0QXR0cmlidXRlKFwibmFtZVwiLCBcInZpZXdwb3J0XCIpXG4gIG1ldGFWaWV3cG9ydC5zZXRBdHRyaWJ1dGUoXCJjb250ZW50XCIsIFwid2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEsIG1heGltdW0tc2NhbGU9MVwiKVxuICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKG1ldGFWaWV3cG9ydCk7XG59XG4iLCJpbXBvcnQgeyBVc2VyRXZlbnRDYXRlZ29yeSB9IGZyb20gJ0BzcGlmZnktYWkvY29tbWVyY2UtYXBpLWNsaWVudCc7XG5pbXBvcnQge1xuICBGb3JtUmVzcG9uc2VBdHRyaWJ1dGVzLFxuICBNZXNzYWdlLFxuICBNZXNzYWdlUm9sZSxcbiAgTWVzc2FnZVR5cGUsXG4gIFVzZXJFdmVudCxcbn0gZnJvbSAnQGVudml2ZS1haS90eXBlcyc7XG5cbmV4cG9ydCBjb25zdCBtZXNzYWdlRnJvbUZvcm1TdWJtaXR0ZWRFdmVudCA9IChcbiAgZXZlbnQ6IFVzZXJFdmVudCxcbiAgZm9ybVJlc3BvbnNlQXR0cmlidXRlczogRm9ybVJlc3BvbnNlQXR0cmlidXRlc1snYXR0cmlidXRlcyddLFxuKTogTWVzc2FnZSB8IHVuZGVmaW5lZCA9PiB7XG4gIGlmIChldmVudC5jYXRlZ29yeSAhPT0gVXNlckV2ZW50Q2F0ZWdvcnkuRm9ybVN1Ym1pdHRlZCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCBmb3JtU3RyaW5nQ29udGVudHMgPSBPYmplY3QuZW50cmllcyhmb3JtUmVzcG9uc2VBdHRyaWJ1dGVzLnNjaGVtYS5wcm9wZXJ0aWVzKVxuICAgIC5tYXAoKFtrZXksIHZhbHVlXSkgPT4gYCR7dmFsdWUudGl0bGV9OiAke2V2ZW50LmF0dHJpYnV0ZXMuZmlsbGVkU2NoZW1hW2tleV19YClcbiAgICAuam9pbignXFxuJyk7XG5cbiAgcmV0dXJuIHtcbiAgICBpZDogZXZlbnQuZXZlbnRJZCxcbiAgICByb2xlOiBNZXNzYWdlUm9sZS5Vc2VyLFxuICAgIHR5cGU6IE1lc3NhZ2VUeXBlLlF1ZXJ5VHlwZWQsXG4gICAgY3JlYXRlZEF0OiBldmVudC5jcmVhdGVkQXQsXG4gICAgbWV0YWRhdGE6IHtcbiAgICAgIGNvbnRlbnQ6IGZvcm1TdHJpbmdDb250ZW50cyxcbiAgICB9LFxuICB9O1xufTtcbiIsImltcG9ydCB7IE1lc3NhZ2UsIE1lc3NhZ2VSb2xlLCBNZXNzYWdlVHlwZSwgVXNlckV2ZW50IH0gZnJvbSAnQGVudml2ZS1haS90eXBlcyc7XG5pbXBvcnQgeyBVc2VyRXZlbnRDYXRlZ29yeSB9IGZyb20gJ0BzcGlmZnktYWkvY29tbWVyY2UtYXBpLWNsaWVudCc7XG5cbi8qKlxuICogVHJhbnNmb3JtcyBhIHF1ZXJ5IFVzZXJFdmVudCBvYmplY3QgaW50byBhIE1lc3NhZ2Ugb2JqZWN0IGZvciBwcmVzZW50YXRpb24uXG4gKlxuICogQHBhcmFtIGV2ZW50IFRoZSB1c2VyIGV2ZW50IG9iamVjdCByZWNlaXZlZCBmcm9tIHRoZSBzZXJ2ZXJcbiAqXG4gKiBAcmV0dXJucyBBIE1lc3NhZ2UgaWYgdGhlIGV2ZW50IGlzIGEgcXVlcnkgZXZlbnQsIG90aGVyd2lzZSB1bmRlZmluZWRcbiAqL1xuZXhwb3J0IGNvbnN0IG1lc3NhZ2VGcm9tUXVlcnlFdmVudCA9IChldmVudDogVXNlckV2ZW50KTogTWVzc2FnZSB8IHVuZGVmaW5lZCA9PiB7XG4gIGlmIChldmVudC5jYXRlZ29yeSA9PT0gVXNlckV2ZW50Q2F0ZWdvcnkuUXVlcnlUeXBlZCkge1xuICAgIHJldHVybiB7XG4gICAgICBpZDogZXZlbnQuZXZlbnRJZCxcbiAgICAgIHJvbGU6IE1lc3NhZ2VSb2xlLlVzZXIsXG4gICAgICB0eXBlOiBNZXNzYWdlVHlwZS5RdWVyeVR5cGVkLFxuICAgICAgY3JlYXRlZEF0OiBldmVudC5jcmVhdGVkQXQsXG4gICAgICBtZXRhZGF0YToge1xuICAgICAgICBjb250ZW50OiBldmVudC5hdHRyaWJ1dGVzLnF1ZXJ5LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgaWYgKGV2ZW50LmNhdGVnb3J5ID09PSBVc2VyRXZlbnRDYXRlZ29yeS5TZWFyY2gpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IGV2ZW50LmV2ZW50SWQsXG4gICAgICByb2xlOiBNZXNzYWdlUm9sZS5Vc2VyLFxuICAgICAgdHlwZTogTWVzc2FnZVR5cGUuU2VhcmNoLFxuICAgICAgY3JlYXRlZEF0OiBldmVudC5jcmVhdGVkQXQsXG4gICAgICBtZXRhZGF0YToge1xuICAgICAgICBzZWFyY2hUZXJtOiBldmVudC5hdHRyaWJ1dGVzLnNlYXJjaFRlcm0gfHwgJycsXG4gICAgICAgIHNlbGVjdGVkRmlsdGVyczogZXZlbnQuYXR0cmlidXRlcy5zZWxlY3RlZEZpbHRlcnMgfHwgW10sXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICByZXR1cm4gdW5kZWZpbmVkO1xufTtcbiIsImltcG9ydCB7IE1lc3NhZ2UsIE1lc3NhZ2VUeXBlLCBNZXNzYWdlUm9sZSwgQXBpUmVzcG9uc2UgfSBmcm9tIFwic3JjL3R5cGVzXCI7XG5pbXBvcnQgeyBSZXNwb25zZUNhdGVnb3J5IH0gZnJvbSBcIkBzcGlmZnktYWkvY29tbWVyY2UtYXBpLWNsaWVudFwiO1xuXG4vKipcbiAqIFRyYW5zZm9ybXMgYSBzZXJ2ZXIgUmVzcG9uc2Ugb2JqZWN0IGludG8gYSBNZXNzYWdlIG9iamVjdCBmb3IgcHJlc2VudGF0aW9uLlxuICpcbiAqIEBwYXJhbSByZXNwb25zZSBUaGUgcmVzcG9uc2Ugb2JqZWN0IHJlY2VpdmVkIGZyb20gdGhlIHNlcnZlciBjb250YWluaW5nIG1vZGVsIGdlbmVyYXRlZCBjb250ZW50XG4gKlxuICogQHJldHVybnMgQSBNZXNzYWdlIGlmIHRoZSByZXNwb25zZSBjb250YWlucyBrbm93biBhdHRyaWJ1dGVzLCB1bmRlZmluZWQgb3RoZXJ3aXNlXG4gKi9cbmV4cG9ydCBjb25zdCBtZXNzYWdlRnJvbVJlc3BvbnNlID0gKFxuICByZXNwb25zZT86IEFwaVJlc3BvbnNlXG4pOiBNZXNzYWdlIHwgdW5kZWZpbmVkID0+IHtcbiAgaWYgKHJlc3BvbnNlID09IG51bGwpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgaWYgKHJlc3BvbnNlLmNhdGVnb3J5ID09PSBSZXNwb25zZUNhdGVnb3J5LlRleHQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHJlc3BvbnNlLmlkLFxuICAgICAgY3JlYXRlZEF0OiByZXNwb25zZS5jcmVhdGVkQXQsXG4gICAgICB0eXBlOiBNZXNzYWdlVHlwZS5UZXh0LFxuICAgICAgcm9sZTogTWVzc2FnZVJvbGUuQXNzaXN0YW50LFxuICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgY29udGVudDogcmVzcG9uc2UuYXR0cmlidXRlcy5jb250ZW50LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgaWYgKHJlc3BvbnNlLmNhdGVnb3J5ID09PSBSZXNwb25zZUNhdGVnb3J5LlByb2R1Y3QpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHJlc3BvbnNlLmlkLFxuICAgICAgY3JlYXRlZEF0OiByZXNwb25zZS5jcmVhdGVkQXQsXG4gICAgICByb2xlOiBNZXNzYWdlUm9sZS5Bc3Npc3RhbnQsXG4gICAgICB0eXBlOiBNZXNzYWdlVHlwZS5Qcm9kdWN0LFxuICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgLi4ucmVzcG9uc2UuYXR0cmlidXRlcyxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIGlmIChyZXNwb25zZS5jYXRlZ29yeSA9PT0gUmVzcG9uc2VDYXRlZ29yeS5SZXZpZXcpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHJlc3BvbnNlLmlkLFxuICAgICAgY3JlYXRlZEF0OiByZXNwb25zZS5jcmVhdGVkQXQsXG4gICAgICB0eXBlOiBNZXNzYWdlVHlwZS5SZXZpZXcsXG4gICAgICByb2xlOiBNZXNzYWdlUm9sZS5Bc3Npc3RhbnQsXG4gICAgICBtZXRhZGF0YToge1xuICAgICAgICByZXZpZXc6IHJlc3BvbnNlLmF0dHJpYnV0ZXMucmV2aWV3LFxuICAgICAgICByZXZpZXdlcjogcmVzcG9uc2UuYXR0cmlidXRlcy5yZXZpZXdlcixcbiAgICAgICAgc3RhcnM6IHJlc3BvbnNlLmF0dHJpYnV0ZXMuc3RhcnMsXG4gICAgICAgIHRpdGxlOiByZXNwb25zZS5hdHRyaWJ1dGVzLnRpdGxlLFxuICAgICAgICByaWNoSW5mb3JtYXRpb246IHJlc3BvbnNlLmF0dHJpYnV0ZXMucmljaEluZm9ybWF0aW9uLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgaWYgKHJlc3BvbnNlLmNhdGVnb3J5ID09PSBSZXNwb25zZUNhdGVnb3J5LlNlcGFyYXRvcikge1xuICAgIHJldHVybiB7XG4gICAgICBpZDogcmVzcG9uc2UuaWQsXG4gICAgICBjcmVhdGVkQXQ6IHJlc3BvbnNlLmNyZWF0ZWRBdCxcbiAgICAgIHR5cGU6IE1lc3NhZ2VUeXBlLlNlcGFyYXRvcixcbiAgICAgIHJvbGU6IE1lc3NhZ2VSb2xlLkFzc2lzdGFudCxcbiAgICB9O1xuICB9XG5cbiAgaWYgKHJlc3BvbnNlLmNhdGVnb3J5ID09PSBSZXNwb25zZUNhdGVnb3J5LlBhZ2UpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHJlc3BvbnNlLmlkLFxuICAgICAgY3JlYXRlZEF0OiByZXNwb25zZS5jcmVhdGVkQXQsXG4gICAgICByb2xlOiBNZXNzYWdlUm9sZS5Bc3Npc3RhbnQsXG4gICAgICB0eXBlOiBNZXNzYWdlVHlwZS5QYWdlLFxuICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgLi4ucmVzcG9uc2UuYXR0cmlidXRlcyxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIGlmIChyZXNwb25zZS5jYXRlZ29yeSA9PT0gUmVzcG9uc2VDYXRlZ29yeS5Qcm9kdWN0U2VhcmNoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiByZXNwb25zZS5pZCxcbiAgICAgIGNyZWF0ZWRBdDogcmVzcG9uc2UuY3JlYXRlZEF0LFxuICAgICAgcm9sZTogTWVzc2FnZVJvbGUuQXNzaXN0YW50LFxuICAgICAgdHlwZTogTWVzc2FnZVR5cGUuUHJvZHVjdFNlYXJjaCxcbiAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgIC4uLnJlc3BvbnNlLmF0dHJpYnV0ZXMsXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBpZiAocmVzcG9uc2UuY2F0ZWdvcnkgPT09IFJlc3BvbnNlQ2F0ZWdvcnkuUHJvZHVjdFNlYXJjaEZpbHRlcikge1xuICAgIHJldHVybiB7XG4gICAgICBpZDogcmVzcG9uc2UuaWQsXG4gICAgICBjcmVhdGVkQXQ6IHJlc3BvbnNlLmNyZWF0ZWRBdCxcbiAgICAgIHJvbGU6IE1lc3NhZ2VSb2xlLkFzc2lzdGFudCxcbiAgICAgIHR5cGU6IE1lc3NhZ2VUeXBlLlByb2R1Y3RTZWFyY2hGaWx0ZXIsXG4gICAgICBtZXRhZGF0YToge1xuICAgICAgICAuLi5yZXNwb25zZS5hdHRyaWJ1dGVzLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgaWYgKHJlc3BvbnNlLmNhdGVnb3J5ID09PSBSZXNwb25zZUNhdGVnb3J5LkZvcm0pIHtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHJlc3BvbnNlLmlkLFxuICAgICAgY3JlYXRlZEF0OiByZXNwb25zZS5jcmVhdGVkQXQsXG4gICAgICByb2xlOiBNZXNzYWdlUm9sZS5Bc3Npc3RhbnQsXG4gICAgICB0eXBlOiBNZXNzYWdlVHlwZS5Gb3JtLFxuICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgZm9ybVR5cGU6IHJlc3BvbnNlLmF0dHJpYnV0ZXMuZm9ybUNhdGVnb3J5Py5mb3JtVHlwZSxcbiAgICAgICAgZmllbGRzOiBPYmplY3QuZW50cmllcyhyZXNwb25zZS5hdHRyaWJ1dGVzLnNjaGVtYS5wcm9wZXJ0aWVzKS5tYXAoXG4gICAgICAgICAgKFtrZXksIHZhbHVlXSkgPT4gKHtcbiAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgIHRpdGxlOiB2YWx1ZS50aXRsZSxcbiAgICAgICAgICAgIHR5cGU6IHZhbHVlLnR5cGUsXG4gICAgICAgICAgICBmb3JtYXQ6IHZhbHVlLmZvcm1hdCxcbiAgICAgICAgICAgIHJlcXVpcmVkOiByZXNwb25zZS5hdHRyaWJ1dGVzLnNjaGVtYS5yZXF1aXJlZC5pbmNsdWRlcyhrZXkpLFxuICAgICAgICAgIH0pXG4gICAgICAgICksXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBpZiAocmVzcG9uc2UuY2F0ZWdvcnkgPT09IFJlc3BvbnNlQ2F0ZWdvcnkuT3JkZXIpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHJlc3BvbnNlLmlkLFxuICAgICAgY3JlYXRlZEF0OiByZXNwb25zZS5jcmVhdGVkQXQsXG4gICAgICByb2xlOiBNZXNzYWdlUm9sZS5Bc3Npc3RhbnQsXG4gICAgICB0eXBlOiBNZXNzYWdlVHlwZS5PcmRlcixcbiAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgIC4uLnJlc3BvbnNlLmF0dHJpYnV0ZXMsXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICByZXR1cm4gdW5kZWZpbmVkO1xufTtcbiIsImltcG9ydCB7IE1lc3NhZ2UsIE1lc3NhZ2VSb2xlLCBNZXNzYWdlVHlwZSwgU3VnZ2VzdGlvbiB9IGZyb20gXCJzcmMvdHlwZXNcIjtcbmltcG9ydCB7IFVzZXJFdmVudCB9IGZyb20gXCJAZW52aXZlLWFpL3R5cGVzXCI7XG5pbXBvcnQgeyBVc2VyRXZlbnRDYXRlZ29yeSB9IGZyb20gXCJAc3BpZmZ5LWFpL2NvbW1lcmNlLWFwaS1jbGllbnRcIjtcblxuLyoqXG4gKiBUcmFuc2Zvcm1zIGEgVXNlckV2ZW50IG9iamVjdCBpbnRvIGEgTWVzc2FnZSBvYmplY3QgZm9yIHByZXNlbnRhdGlvbi5cbiAqXG4gKiBAcGFyYW0gZXZlbnQgVGhlIFVzZXJFdmVudCBvYmplY3QgcmVjZWl2ZWQgZnJvbSB0aGUgc2VydmVyXG4gKiBAcGFyYW0gc3VnZ2VzdGlvbnMgQSBsaXN0IG9mIGdlbmVyYXRlZCBzdWdnZXN0aW9ucyB0byBtYXRjaCB0aGUgZXZlbnQgdG9cbiAqXG4gKiBAcmV0dXJucyBBIE1lc3NhZ2UgaWYgdGhlIGV2ZW50IGlzIGEgc3VnZ2VzdGlvbiBjbGljayBldmVudCwgdW5kZWZpbmVkIG90aGVyd2lzZVxuICovXG5leHBvcnQgY29uc3QgbWVzc2FnZUZyb21TdWdnZXN0aW9uRXZlbnQgPSAoXG4gIGV2ZW50OiBVc2VyRXZlbnQsXG4gIHN1Z2dlc3Rpb25zOiBTdWdnZXN0aW9uW11cbik6IE1lc3NhZ2UgfCB1bmRlZmluZWQgPT4ge1xuICBpZiAoZXZlbnQuY2F0ZWdvcnkgPT09IFVzZXJFdmVudENhdGVnb3J5LlN1Z2dlc3Rpb25DbGlja2VkKSB7XG4gICAgY29uc3QgeyBzdWdnZXN0aW9uSWQgfSA9IGV2ZW50LmF0dHJpYnV0ZXM7XG5cbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IGV2ZW50LmV2ZW50SWQsXG4gICAgICByb2xlOiBNZXNzYWdlUm9sZS5Vc2VyLFxuICAgICAgdHlwZTogTWVzc2FnZVR5cGUuU3VnZ2VzdGlvbkNsaWNrZWQsXG4gICAgICBjcmVhdGVkQXQ6IGV2ZW50LmNyZWF0ZWRBdCxcbiAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgIHN1Z2dlc3Rpb25JZCxcbiAgICAgICAgc3VnZ2VzdGlvbkNvbnRlbnQ6XG4gICAgICAgICAgc3VnZ2VzdGlvbnMuZmluZCgocykgPT4gcy5pZCA9PT0gc3VnZ2VzdGlvbklkKT8uY29udGVudCA/PyBcIlwiLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn07XG4iLCJpbXBvcnQgeyBOZXh0TWVzc2FnZVJlcXVlc3QgYXMgQXBpTmV4dE1lc3NhZ2VSZXF1ZXN0IH0gZnJvbSAnQHNwaWZmeS1haS9jb21tZXJjZS1hcGktY2xpZW50JztcbmltcG9ydCB7IGNvcmVVc2VyRXZlbnRUb0FwaVVzZXJFdmVudCB9IGZyb20gJy4vY29yZVVzZXJFdmVudFRvQXBpVXNlckV2ZW50JztcbmltcG9ydCB7IE5leHRNZXNzYWdlUmVxdWVzdCB9IGZyb20gJ0BlbnZpdmUtYWkvdHlwZXMnO1xuXG5leHBvcnQgY29uc3QgbWVzc2FnZVJlcXVlc3RUb0NvbW1lcmNlTWVzc2FnZVJlcXVlc3QgPSAoXG4gIGRhdGE6IE5leHRNZXNzYWdlUmVxdWVzdCxcbik6IEFwaU5leHRNZXNzYWdlUmVxdWVzdCA9PiAoe1xuICBjb250ZXh0OiB7XG4gICAgY2hhdF9pZDogZGF0YS5jb250ZXh0LmNoYXRJZCxcbiAgICBvcmdfaWQ6IGRhdGEuY29udGV4dC5vcmdJZCxcbiAgICBvcmdfc2hvcnRfbmFtZTogZGF0YS5jb250ZXh0Lm9yZ1Nob3J0TmFtZSxcbiAgICB1c2VyX2lkOiBkYXRhLmNvbnRleHQudXNlcklkLFxuICAgIHNvdXJjZTogZGF0YS5jb250ZXh0LnNvdXJjZSxcbiAgICBlbnY6IGRhdGEuY29udGV4dC5lbnYsXG4gIH0sXG4gIGlkOiBkYXRhLmlkLFxuICBmZWF0dXJlX2ZsYWdzOiBkYXRhLmZlYXR1cmVGbGFncyxcbiAgdXNlcl9ldmVudHM6IGRhdGEudXNlckV2ZW50cz8ubWFwKCh1c2VyRXZlbnQpID0+IGNvcmVVc2VyRXZlbnRUb0FwaVVzZXJFdmVudCh1c2VyRXZlbnQpKSxcbiAgZ2VuZXJhdGlvbl9wYXJhbXM6IHtcbiAgICBtb2RlbDogZGF0YS5nZW5lcmF0aW9uUGFyYW1zPy5tb2RlbCxcbiAgICBtYXhfdG9rZW5zOiBkYXRhLmdlbmVyYXRpb25QYXJhbXM/Lm1heFRva2VucyxcbiAgICBzdG9wOiBkYXRhLmdlbmVyYXRpb25QYXJhbXM/LnN0b3AsXG4gICAgc3RyZWFtOiBkYXRhLmdlbmVyYXRpb25QYXJhbXM/LnN0cmVhbSxcbiAgICB0ZW1wZXJhdHVyZTogZGF0YS5nZW5lcmF0aW9uUGFyYW1zPy50ZW1wZXJhdHVyZSxcbiAgICB0b3BfcDogZGF0YS5nZW5lcmF0aW9uUGFyYW1zPy50b3BQLFxuICAgIG51bV9zdWdnZXN0aW9uczogZGF0YS5nZW5lcmF0aW9uUGFyYW1zPy5udW1TdWdnZXN0aW9ucyxcbiAgICByZXNwb25zZV9zeXN0ZW1fcHJvbXB0OiBkYXRhLmdlbmVyYXRpb25QYXJhbXM/LnJlc3BvbnNlU3lzdGVtUHJvbXB0LFxuICAgIHN1Z2dlc3Rpb25fc3lzdGVtX3Byb21wdDogZGF0YS5nZW5lcmF0aW9uUGFyYW1zPy5zdWdnZXN0aW9uU3lzdGVtUHJvbXB0LFxuICAgIHJlc3BvbnNlX2NhY2hpbmc6IGRhdGEuZ2VuZXJhdGlvblBhcmFtcz8ucmVzcG9uc2VDYWNoaW5nLFxuICB9LFxufSk7XG4iLCJleHBvcnQgYWJzdHJhY3QgY2xhc3MgTm9kZVNlbGVjdG9yIHtcbiAgcHJpdmF0ZSBwYXR0ZXJuOiBzdHJpbmc7XG4gIHByaXZhdGUgcm9vdDogRG9jdW1lbnQ7XG5cbiAgY29uc3RydWN0b3IocGF0dGVybjogc3RyaW5nKSB7XG4gICAgdGhpcy5wYXR0ZXJuID0gcGF0dGVybjtcbiAgICB0aGlzLnJvb3QgPSBkb2N1bWVudDtcbiAgfVxuXG4gIGdldFBhdHRlcm4oKSB7XG4gICAgcmV0dXJuIHRoaXMucGF0dGVybjtcbiAgfVxuXG4gIHNldFJvb3Qocm9vdDogRG9jdW1lbnQpIHtcbiAgICB0aGlzLnJvb3QgPSByb290O1xuICB9XG5cbiAgZ2V0Um9vdCgpIHtcbiAgICByZXR1cm4gdGhpcy5yb290O1xuICB9XG5cbiAgYWJzdHJhY3QgcGFyc2UoKTogTm9kZSB8IG51bGw7XG59XG5cbmNsYXNzIFF1ZXJ5U2VsZWN0b3IgZXh0ZW5kcyBOb2RlU2VsZWN0b3Ige1xuICBwYXJzZSgpOiBOb2RlIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0Um9vdCgpLnF1ZXJ5U2VsZWN0b3IodGhpcy5nZXRQYXR0ZXJuKCkpO1xuICB9XG59XG5cbmNsYXNzIElEU2VsZWN0b3IgZXh0ZW5kcyBOb2RlU2VsZWN0b3Ige1xuICBwYXJzZSgpOiBOb2RlIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0Um9vdCgpLmdldEVsZW1lbnRCeUlkKHRoaXMuZ2V0UGF0dGVybigpKSBhcyBOb2RlO1xuICB9XG59XG5cbmNsYXNzIFhwYXRoU2VsZWN0b3IgZXh0ZW5kcyBOb2RlU2VsZWN0b3Ige1xuICBwYXJzZSgpOiBOb2RlIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0Um9vdCgpPy5ldmFsdWF0ZShcbiAgICAgIHRoaXMuZ2V0UGF0dGVybigpLFxuICAgICAgdGhpcy5nZXRSb290KCksXG4gICAgICBudWxsLFxuICAgICAgWFBhdGhSZXN1bHQuRklSU1RfT1JERVJFRF9OT0RFX1RZUEUsXG4gICAgICBudWxsLFxuICAgICk/LnNpbmdsZU5vZGVWYWx1ZSBhcyBOb2RlO1xuICB9XG59XG5cbmNsYXNzIENoYWluU2VsZWN0b3IgZXh0ZW5kcyBOb2RlU2VsZWN0b3Ige1xuICBwYXJzZSgpOiBOb2RlIHwgbnVsbCB7XG4gICAgbGV0IHNlbGVjdG9ySW5kZXggPSAwO1xuICAgIGNvbnN0IHNlbGVjdG9ycyA9IHRoaXMuZ2V0UGF0dGVybigpLnNwbGl0KCdAJyk7XG4gICAgY29uc3QgbGFzdEluZGV4ID0gc2VsZWN0b3JzLmxlbmd0aCAtIDE7XG5cbiAgICBjb25zdCBwYXJzZUNoYWluID0gKHBhdHRlcm46IHN0cmluZywgcHJldk5vZGU/OiBOb2RlIHwgbnVsbCk6IE5vZGUgfCBudWxsID0+IHtcbiAgICAgIGNvbnN0IHNlbGVjdG9yID0gU2VsZWN0b3JGYWN0b3J5LnBhcnNlKHBhdHRlcm4pO1xuXG4gICAgICBpZiAocHJldk5vZGUpIHtcbiAgICAgICAgc2VsZWN0b3Iuc2V0Um9vdChwcmV2Tm9kZSBhcyBEb2N1bWVudCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGN1cnJlbnROb2RlID0gc2VsZWN0b3IucGFyc2UoKTtcbiAgICAgIGlmIChzZWxlY3RvckluZGV4ID09PSBsYXN0SW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIGN1cnJlbnROb2RlO1xuICAgICAgfVxuXG4gICAgICBsZXQgbm9kZTogTm9kZSB8IG51bGwgfCB1bmRlZmluZWQgPSBjdXJyZW50Tm9kZSB8fCBkb2N1bWVudDtcbiAgICAgIGlmICgoY3VycmVudE5vZGUgYXMgSFRNTEVsZW1lbnQpPy5zaGFkb3dSb290KSB7XG4gICAgICAgIG5vZGUgPSAoY3VycmVudE5vZGUgYXMgSFRNTEVsZW1lbnQpLnNoYWRvd1Jvb3Q7XG4gICAgICB9XG5cbiAgICAgIGlmICgoY3VycmVudE5vZGUgYXMgSFRNTElGcmFtZUVsZW1lbnQpPy5jb250ZW50V2luZG93KSB7XG4gICAgICAgIG5vZGUgPSAoY3VycmVudE5vZGUgYXMgSFRNTElGcmFtZUVsZW1lbnQpLmNvbnRlbnRXaW5kb3c/LmRvY3VtZW50O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcGFyc2VDaGFpbihzZWxlY3RvcnNbKytzZWxlY3RvckluZGV4XS50cmltKCksIG5vZGUpO1xuICAgIH07XG5cbiAgICByZXR1cm4gcGFyc2VDaGFpbihzZWxlY3RvcnNbc2VsZWN0b3JJbmRleF0udHJpbSgpKTtcbiAgfVxufVxuXG5jbGFzcyBFbXB0eSBleHRlbmRzIE5vZGVTZWxlY3RvciB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCcnKTtcbiAgfVxuICBwYXJzZSgpOiBOb2RlIHwgbnVsbCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFNlbGVjdG9yRmFjdG9yeSB7XG4gIHN0YXRpYyBwYXJzZShjb21wb3NlZFNlbGVjdG9yPzogc3RyaW5nKSB7XG4gICAgaWYgKCFjb21wb3NlZFNlbGVjdG9yKSB7XG4gICAgICByZXR1cm4gbmV3IEVtcHR5KCk7XG4gICAgfVxuXG4gICAgY29uc3Qgc3BsaXQgPSBjb21wb3NlZFNlbGVjdG9yLnNwbGl0KCd8Jyk7XG4gICAgY29uc3QgdHlwZSA9IHNwbGl0WzBdO1xuICAgIGNvbnN0IHNlbGVjdG9yID0gc3BsaXRbMV07XG5cbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2UgJ2lkJzpcbiAgICAgICAgcmV0dXJuIHRoaXMuaWQoc2VsZWN0b3IpO1xuICAgICAgY2FzZSAncXVlcnknOlxuICAgICAgICByZXR1cm4gdGhpcy5xdWVyeShzZWxlY3Rvcik7XG4gICAgICBjYXNlICd4cGF0aCc6XG4gICAgICAgIHJldHVybiB0aGlzLnhwYXRoKHNlbGVjdG9yKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBuZXcgRW1wdHkoKTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgY2hlY2soc2VsZWN0b3I/OiBOb2RlU2VsZWN0b3IpIHtcbiAgICByZXR1cm4gc2VsZWN0b3IgPz8gbmV3IEVtcHR5KCk7XG4gIH1cblxuICBzdGF0aWMgY2hhaW4ocGF0dGVybj86IHN0cmluZykge1xuICAgIHJldHVybiBwYXR0ZXJuID8gbmV3IENoYWluU2VsZWN0b3IocGF0dGVybikgOiBuZXcgRW1wdHkoKTtcbiAgfVxuXG4gIHN0YXRpYyBpZChwYXR0ZXJuPzogc3RyaW5nKTogTm9kZVNlbGVjdG9yIHtcbiAgICByZXR1cm4gcGF0dGVybiA/IG5ldyBJRFNlbGVjdG9yKHBhdHRlcm4pIDogbmV3IEVtcHR5KCk7XG4gIH1cblxuICBzdGF0aWMgcXVlcnkocGF0dGVybj86IHN0cmluZyk6IE5vZGVTZWxlY3RvciB7XG4gICAgcmV0dXJuIHBhdHRlcm4gPyBuZXcgUXVlcnlTZWxlY3RvcihwYXR0ZXJuKSA6IG5ldyBFbXB0eSgpO1xuICB9XG5cbiAgc3RhdGljIHhwYXRoKHBhdHRlcm4/OiBzdHJpbmcpOiBOb2RlU2VsZWN0b3Ige1xuICAgIHJldHVybiBwYXR0ZXJuID8gbmV3IFhwYXRoU2VsZWN0b3IocGF0dGVybikgOiBuZXcgRW1wdHkoKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgRGVsZXRlT3AsIE1lcmdlT3B0aW9ucywgTm9JbmZlciwgT3ZlcnJpZGUsIFJlcGxhY2VPcCB9IGZyb20gJ0BlbnZpdmUtYWkvdHlwZXMnO1xuXG5mdW5jdGlvbiBpc1BsYWluT2JqZWN0KHg6IHVua25vd24pOiB4IGlzIFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgcmV0dXJuIChcbiAgICAhIXggJiZcbiAgICB0eXBlb2YgeCA9PT0gJ29iamVjdCcgJiZcbiAgICAhQXJyYXkuaXNBcnJheSh4KSAmJlxuICAgICEoeCBpbnN0YW5jZW9mIERhdGUpICYmXG4gICAgISh4IGluc3RhbmNlb2YgUmVnRXhwKVxuICApO1xufVxuXG5mdW5jdGlvbiBpc1JlcGxhY2UoeDogdW5rbm93bik6IHggaXMgUmVwbGFjZU9wPHVua25vd24+IHtcbiAgcmV0dXJuICEheCAmJiB0eXBlb2YgeCA9PT0gJ29iamVjdCcgJiYgJyRyZXBsYWNlJyBpbiAoeCBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik7XG59XG5mdW5jdGlvbiBpc0RlbGV0ZSh4OiB1bmtub3duKTogeCBpcyBEZWxldGVPcCB7XG4gIHJldHVybiAhIXggJiYgdHlwZW9mIHggPT09ICdvYmplY3QnICYmICh4IGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS4kZGVsZXRlID09PSB0cnVlO1xufVxuXG5mdW5jdGlvbiBpc1ByaW1pdGl2ZVZhbHVlKHg6IHVua25vd24pOiBib29sZWFuIHtcbiAgY29uc3QgdCA9IHR5cGVvZiB4O1xuICByZXR1cm4gKFxuICAgIHggPT09IG51bGwgfHxcbiAgICB0ID09PSAnc3RyaW5nJyB8fFxuICAgIHQgPT09ICdudW1iZXInIHx8XG4gICAgdCA9PT0gJ2Jvb2xlYW4nIHx8XG4gICAgdCA9PT0gJ2JpZ2ludCcgfHxcbiAgICB0ID09PSAnc3ltYm9sJyB8fFxuICAgIHQgPT09ICd1bmRlZmluZWQnXG4gICk7XG59XG5cbmZ1bmN0aW9uIGlzQXJyYXlPZlByaW1pdGl2ZXMoYXJyOiB1bmtub3duW10pOiBib29sZWFuIHtcbiAgaWYgKGFyci5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTsgLy8gYW1iaWd1b3VzLCBkZWZhdWx0IHRvIG1lcmdlLWJ5LWluZGV4IG9uIGVtcHR5XG4gIC8vIElmIGV2ZXJ5IGRlZmluZWQgZWxlbWVudCBpcyBwcmltaXRpdmUsIHRyZWF0IGFzIHByaW1pdGl2ZXNcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpICs9IDEpIHtcbiAgICBjb25zdCB2ID0gYXJyW2ldO1xuICAgIGlmICh2ICE9PSB1bmRlZmluZWQgJiYgIWlzUHJpbWl0aXZlVmFsdWUodikpIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gbWVyZ2VBbnkoYmFzZUFueTogdW5rbm93biwgcGF0Y2hBbnk6IHVua25vd24sIG9wdHM6IE1lcmdlT3B0aW9ucyk6IHVua25vd24ge1xuICBpZiAoaXNSZXBsYWNlKHBhdGNoQW55KSkgcmV0dXJuIHBhdGNoQW55LiRyZXBsYWNlIGFzIHVua25vd247XG4gIGlmIChpc0RlbGV0ZShwYXRjaEFueSkpIHJldHVybiB1bmRlZmluZWQ7IC8vIGNhbGxlciBkZWxldGVzIHRoZSBrZXlcblxuICBpZiAoQXJyYXkuaXNBcnJheShiYXNlQW55KSkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KHBhdGNoQW55KSkge1xuICAgICAgY29uc3QgYmFzZUFyciA9IGJhc2VBbnkgYXMgdW5rbm93bltdO1xuICAgICAgY29uc3QgcGF0Y2hBcnIgPSBwYXRjaEFueSBhcyB1bmtub3duW107XG4gICAgICBjb25zdCBzaG91bGRSZXBsYWNlID1cbiAgICAgICAgb3B0cy5hcnJheVN0cmF0ZWd5ID09PSAncmVwbGFjZScgfHxcbiAgICAgICAgaXNBcnJheU9mUHJpbWl0aXZlcyhiYXNlQXJyKSB8fFxuICAgICAgICBpc0FycmF5T2ZQcmltaXRpdmVzKHBhdGNoQXJyKTtcbiAgICAgIGlmIChzaG91bGRSZXBsYWNlKSByZXR1cm4gcGF0Y2hBbnkgYXMgdW5rbm93bjtcbiAgICAgIGNvbnN0IG91dCA9IGJhc2VBcnIuc2xpY2UoKTtcbiAgICAgIGNvbnN0IG1heCA9IE1hdGgubWF4KG91dC5sZW5ndGgsIHBhdGNoQXJyLmxlbmd0aCk7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1heDsgaSArPSAxKSB7XG4gICAgICAgIGNvbnN0IHBWYWwgPSBwYXRjaEFycltpXTtcbiAgICAgICAgaWYgKHBWYWwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIG91dFtpXSA9IG1lcmdlQW55KG91dFtpXSwgcFZhbCwgb3B0cyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBvdXQgYXMgdW5rbm93bjtcbiAgICB9XG4gICAgcmV0dXJuIGJhc2VBbnkgYXMgdW5rbm93bjtcbiAgfVxuXG4gIGlmIChpc1BsYWluT2JqZWN0KGJhc2VBbnkpICYmIGlzUGxhaW5PYmplY3QocGF0Y2hBbnkpKSB7XG4gICAgY29uc3QgYmFzZU9iaiA9IGJhc2VBbnkgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgY29uc3QgcGF0Y2hPYmogPSBwYXRjaEFueSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICBjb25zdCBvdXQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0geyAuLi5iYXNlT2JqIH07XG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMocGF0Y2hPYmopKSB7XG4gICAgICBjb25zdCBwVmFsID0gcGF0Y2hPYmpba2V5XTtcbiAgICAgIGlmIChwVmFsID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgLy8gbGVhdmUgYXMtaXNcbiAgICAgIH0gZWxzZSBpZiAob3B0cy5udWxsRGVsZXRlcyAmJiBwVmFsID09PSBudWxsKSB7XG4gICAgICAgIGRlbGV0ZSBvdXRba2V5XTtcbiAgICAgIH0gZWxzZSBpZiAoaXNSZXBsYWNlKHBWYWwpKSB7XG4gICAgICAgIG91dFtrZXldID0gcFZhbC4kcmVwbGFjZTtcbiAgICAgIH0gZWxzZSBpZiAoaXNEZWxldGUocFZhbCkpIHtcbiAgICAgICAgZGVsZXRlIG91dFtrZXldO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3V0W2tleV0gPSBtZXJnZUFueShiYXNlT2JqPy5ba2V5XSwgcFZhbCwgb3B0cyk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvdXQgYXMgdW5rbm93bjtcbiAgfVxuXG4gIHJldHVybiAocGF0Y2hBbnkgYXMgdW5rbm93bikgPz8gYmFzZUFueTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5T3ZlcnJpZGVzPFQ+KFxuICBiYXNlOiBULFxuICBwYXRjaDogT3ZlcnJpZGU8Tm9JbmZlcjxUPj4sXG4gIG9wdHM6IE1lcmdlT3B0aW9ucyA9IHt9LFxuKTogVCB7XG4gIGNvbnN0IHsgYXJyYXlTdHJhdGVneSA9ICdtZXJnZUJ5SW5kZXgnLCBudWxsRGVsZXRlcyA9IGZhbHNlIH0gPSBvcHRzO1xuXG4gIC8vIEhhbmRsZSB3aG9sZS1ub2RlIGNvbnRyb2wgb3BlcmF0b3JzIG9uIHBhdGNoIGl0c2VsZlxuICBpZiAoaXNSZXBsYWNlKHBhdGNoKSkgcmV0dXJuIHBhdGNoLiRyZXBsYWNlIGFzIFQ7XG4gIGlmIChpc0RlbGV0ZShwYXRjaCkpIHJldHVybiB1bmRlZmluZWQgYXMgdW5rbm93biBhcyBUO1xuXG4gIC8vIEFycmF5c1xuICBpZiAoQXJyYXkuaXNBcnJheShiYXNlKSkge1xuICAgIGlmIChpc1JlcGxhY2UocGF0Y2gpKSByZXR1cm4gcGF0Y2guJHJlcGxhY2UgYXMgVDtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShwYXRjaCkpIHtcbiAgICAgIGlmIChhcnJheVN0cmF0ZWd5ID09PSAncmVwbGFjZScpIHJldHVybiBwYXRjaCBhcyB1bmtub3duIGFzIFQ7XG4gICAgICAvLyBtZXJnZSBieSBpbmRleFxuICAgICAgY29uc3Qgb3V0ID0gKGJhc2UgYXMgdW5rbm93bltdKS5zbGljZSgpO1xuICAgICAgY29uc3QgbWF4ID0gTWF0aC5tYXgob3V0Lmxlbmd0aCwgcGF0Y2gubGVuZ3RoKTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWF4OyBpICs9IDEpIHtcbiAgICAgICAgY29uc3QgcFZhbCA9IChwYXRjaCBhcyB1bmtub3duW10pW2ldO1xuICAgICAgICBpZiAocFZhbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgb3V0W2ldID0gbWVyZ2VBbnkob3V0W2ldLCBwVmFsLCBvcHRzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG91dCBhcyB1bmtub3duIGFzIFQ7XG4gICAgfVxuICAgIC8vIGludmFsaWQgcGF0Y2ggdHlwZSBmb3IgYW4gYXJyYXkg4oaSIGlnbm9yZSBhbmQgcmV0dXJuIGJhc2VcbiAgICByZXR1cm4gYmFzZSBhcyBUO1xuICB9XG5cbiAgLy8gUGxhaW4gb2JqZWN0c1xuICBpZiAoaXNQbGFpbk9iamVjdChiYXNlKSAmJiBpc1BsYWluT2JqZWN0KHBhdGNoKSkge1xuICAgIGNvbnN0IG91dDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7IC4uLihiYXNlIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KSB9O1xuICAgIGNvbnN0IHBhdGNoT2JqID0gcGF0Y2ggYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMocGF0Y2hPYmopKSB7XG4gICAgICBjb25zdCBwVmFsID0gcGF0Y2hPYmpba2V5XTtcbiAgICAgIGlmIChwVmFsID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgLy8gbGVhdmUgZXhpc3RpbmcgdmFsdWVcbiAgICAgIH0gZWxzZSBpZiAobnVsbERlbGV0ZXMgJiYgcFZhbCA9PT0gbnVsbCkge1xuICAgICAgICBkZWxldGUgb3V0W2tleV07XG4gICAgICB9IGVsc2UgaWYgKGlzUmVwbGFjZShwVmFsKSkge1xuICAgICAgICBvdXRba2V5XSA9IHBWYWwuJHJlcGxhY2U7XG4gICAgICB9IGVsc2UgaWYgKGlzRGVsZXRlKHBWYWwpKSB7XG4gICAgICAgIGRlbGV0ZSBvdXRba2V5XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGJWYWwgPSAoYmFzZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilba2V5XTtcbiAgICAgICAgb3V0W2tleV0gPSBtZXJnZUFueShiVmFsLCBwVmFsLCBvcHRzKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG91dCBhcyB1bmtub3duIGFzIFQ7XG4gIH1cblxuICAvLyBGb3IgcHJpbWl0aXZlcyBvciB3aGVuIHBhdGNoIGlzIHByaW1pdGl2ZSwgcGF0Y2ggd2lucyBpZiBkZWZpbmVkXG4gIHJldHVybiAoKHBhdGNoIGFzIHVua25vd24pID8/IGJhc2UpIGFzIFQ7XG59XG4iLCJcbmNsYXNzIFN0cmluZ1V0aWxzIHtcbiAgc3RhdGljIGlzTnVsbE9yRW1wdHkodmFsdWU6IHN0cmluZyB8IHVuZGVmaW5lZCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHZhbHVlVHJpbW1lZCA9IHZhbHVlPy50cmltKCk7XG4gICAgcmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWVUcmltbWVkID09PSAnJztcbiAgfVxuXG4gIHN0YXRpYyB0cmltVG9OdWxsKHZhbHVlOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHZhbHVlVHJpbW1lZCA9IHZhbHVlPy50cmltKCk7XG4gICAgcmV0dXJuIFN0cmluZ1V0aWxzLmlzTnVsbE9yRW1wdHkodmFsdWVUcmltbWVkKSA/IHVuZGVmaW5lZCA6IHZhbHVlVHJpbW1lZDtcbiAgfVxuXG4gIHN0YXRpYyBjYXBpdGFsaXplKHR5cGU6IHN0cmluZyB8IHVuZGVmaW5lZCkge1xuICAgIGlmICh0eXBlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gICAgcmV0dXJuIHR5cGUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyB0eXBlLnN1YnN0cmluZygxKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kcyB0aGUgZmlyc3QgcGF0dGVybiBpbiBhbiBhcnJheSB0aGF0IG1hdGNoZXMgYSBnaXZlbiBVUkwuXG4gICAqIFBhdHRlcm5zIGNhbiBpbmNsdWRlIGEgc2luZ2xlIHdpbGRjYXJkICcqJyB3aGljaCBtYXRjaGVzIGFueSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzLlxuICAgKlxuICAgKiBAcGFyYW0gcGF0dGVybnNcbiAgICogQHBhcmFtIHVybFRvVGVzdFxuICAgKiBAcmV0dXJuc1xuICAgKi9cbiAgc3RhdGljIGZpbmRNYXRjaGluZ1BhdHRlcm4ocGF0dGVybnM6IHN0cmluZ1tdLCB1cmxUb1Rlc3Q6IExvY2F0aW9uKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIXVybFRvVGVzdCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHBhdHRlcm4gb2YgcGF0dGVybnMpIHtcbiAgICAgIC8vIFRlc3Qgb25seSBpZiBhIHBhdGhuYW1lIGlzIHByZXNlbnQuXG4gICAgICBpZiAodXJsVG9UZXN0LnBhdGhuYW1lICE9PSAnLycpIHtcbiAgICAgICAgLy8gRXNjYXBlIHNwZWNpYWwgcmVnZXggY2hhcmFjdGVycyBpbiB0aGUgcGF0dGVyblxuICAgICAgICAvLyBUaGlzIGVuc3VyZXMgdGhhdCBjaGFyYWN0ZXJzIGxpa2UgJy4nLCAnKycsICc/JywgJygnLCBldGMuLCBpbiB0aGUgcGF0dGVybiBhcmUgdHJlYXRlZCBsaXRlcmFsbHkuXG4gICAgICAgIGNvbnN0IGVzY2FwZWRQYXR0ZXJuID0gcGF0dGVybi5yZXBsYWNlKC9bLis/XiR7fSgpfFtcXF1cXFxcXS9nLCAnXFxcXCQmJyk7XG5cbiAgICAgICAgLy8gUmVwbGFjZSB0aGUgd2lsZGNhcmQgJyonIHdpdGggaXRzIHJlZ2V4IGVxdWl2YWxlbnQgJy4qJyAobWF0Y2hlcyBhbnkgY2hhcmFjdGVyIHplcm8gb3IgbW9yZSB0aW1lcylcbiAgICAgICAgY29uc3QgcmVnZXhQYXR0ZXJuID0gZXNjYXBlZFBhdHRlcm4ucmVwbGFjZSgvXFwqL2csICcuKicpO1xuXG4gICAgICAgIGNvbnN0IHJlZ2V4ID0gbmV3IFJlZ0V4cChgXiR7cmVnZXhQYXR0ZXJufSRgKTtcbiAgICAgICAgaWYgKHJlZ2V4LnRlc3QodXJsVG9UZXN0LnBhdGhuYW1lKSkge1xuICAgICAgICAgIHJldHVybiBwYXR0ZXJuO1xuICAgICAgICB9XG5cbiAgICAgIH0gZWxzZSBpZiAocGF0dGVybi5zdGFydHNXaXRoKHVybFRvVGVzdC5ob3N0bmFtZSkpIHtcbiAgICAgICAgcmV0dXJuIHBhdHRlcm47XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCB7IFN0cmluZ1V0aWxzIH07XG4iLCJpbXBvcnQgeyBTdXBwb3J0ZWRFdmVudFJlcXVlc3QgYXMgQXBpU3VwcG9ydGVkRXZlbnRSZXF1ZXN0IH0gZnJvbSAnQHNwaWZmeS1haS9jb21tZXJjZS1hcGktY2xpZW50JztcbmltcG9ydCB7IFN1cHBvcnRlZEV2ZW50UmVxdWVzdCB9IGZyb20gJ0BlbnZpdmUtYWkvdHlwZXMnO1xuaW1wb3J0IHsgY29yZVVzZXJFdmVudFRvQXBpVXNlckV2ZW50IH0gZnJvbSAnLi9jb3JlVXNlckV2ZW50VG9BcGlVc2VyRXZlbnQnO1xuaW1wb3J0IHsgY29yZUNvbnRleHRUb0FwaUNvbnRleHQgfSBmcm9tICcuL2NvcmVDb250ZXh0VG9BcGlDb250ZXh0JztcblxudHlwZSBDb3JlU3VwcG9ydGVkRXZlbnRSZXF1ZXN0ID0gU3VwcG9ydGVkRXZlbnRSZXF1ZXN0O1xuXG5leHBvcnQgY29uc3QgY29yZVN1cHBvcnRlZEV2ZW50UmVxdWVzdFRvQXBpUmVxdWVzdCA9IChcbiAgY29yZVN1cHBvcnRlZEV2ZW50UmVxdWVzdDogQ29yZVN1cHBvcnRlZEV2ZW50UmVxdWVzdCxcbik6IEFwaVN1cHBvcnRlZEV2ZW50UmVxdWVzdCA9PiAoe1xuICBpZDogY29yZVN1cHBvcnRlZEV2ZW50UmVxdWVzdC5pZCxcbiAgdXNlcl9ldmVudDogY29yZVVzZXJFdmVudFRvQXBpVXNlckV2ZW50KGNvcmVTdXBwb3J0ZWRFdmVudFJlcXVlc3QudXNlckV2ZW50KSxcbiAgY29udGV4dDogY29yZUNvbnRleHRUb0FwaUNvbnRleHQoY29yZVN1cHBvcnRlZEV2ZW50UmVxdWVzdC5jb250ZXh0KSxcbn0pO1xuIiwiLy8gVGhpcyBlbWFpbCB2YWxpZGF0ZXMgdGhhdCB0aGVyZSBhcmUgb25lIG9yIG1vcmUgY2hhcmFjdGVycyBiZWZvcmUgdGhlIGBAYCBzeW1ib2wsXG4vLyBvbmUgb3IgbW9yZSBjaGFyYWN0ZXJzIGJldHdlZW4gdGhlIGBAYCBzeW1ib2wgYW5kIHRoZSBgLmAgc3ltYm9sLFxuLy8gYW5kIG9uZSBvciBtb3JlIGNoYXJhY3RlcnMgYWZ0ZXIgdGhlIGAuYCBzeW1ib2xcbi8vIEl0IGRvZXMgTk9UIHZhbGlkYXRlIGFsbCBwb3NzaWJsZSBlbWFpbCBmb3JtYXRzLCBidXQgaXQgaXMgYSBkZWNlbnQgcGxhY2UgdG8gc3RhcnQuXG5leHBvcnQgY29uc3QgdmFsaWRhdGVFbWFpbCA9ICh2YWx1ZTogc3RyaW5nKTogYm9vbGVhbiA9PiAvXlteXFxzQF0rQFteXFxzQF0rXFwuW15cXHNAXSskLy50ZXN0KHZhbHVlKTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTBEQSxlQUFlLGtCQUFrQixPQUFzQjtBQUNyRCxLQUFJO0FBQ0YsU0FBTyxNQUFNLE1BQU0sU0FBUyxNQUFNO1NBQzVCO0FBQ04sU0FBTyxFQUFFOzs7QUFJYixlQUFlLDhCQUE4QixVQUFrQixPQUFnQjtBQUM3RSxLQUFJLEVBQUUsaUJBQWlCQSxnREFBZ0I7QUFDckMsZ0NBQU8sUUFBUSxVQUFVLE1BQU07QUFDL0IsUUFBTTs7Q0FHUixNQUFNLGdCQUFnQixNQUFNLGtCQUFrQixNQUFNO0FBQ3BELEtBQ0UsZUFBZSxTQUFTLGFBQWEsS0FBSyx5QkFDMUMsZUFBZSxVQUFVLGFBQWEsS0FBSyxvQkFFM0MsT0FBTSxJQUFJQyxnREFBNkI7VUFFdkMsZUFBZSxV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