@envive-ai/react-hooks 0.2.6-alpha-4 → 0.2.6-alpha-6

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 (225) hide show
  1. package/dist/{AmplitudeOperations-Dpp91XWV.js → AmplitudeOperations-CaA5jTCq.js} +2 -2
  2. package/dist/{AmplitudeOperations-BEhMCOtx.cjs → AmplitudeOperations-CufFJLkn.cjs} +3 -3
  3. package/dist/{NewOrgConfig-Cx3R7FM6.js → NewOrgConfig-BnLPlU6Z.js} +2 -2
  4. package/dist/{NewOrgConfig-DRs9Sk4E.cjs → NewOrgConfig-CKHO6QW_.cjs} +2 -2
  5. package/dist/{TrackComponentVisibleEvent-OAFP4CZ6.cjs → TrackComponentVisibleEvent-BvrgpJuY.cjs} +4 -4
  6. package/dist/{TrackComponentVisibleEvent-CIfRZtFq.js → TrackComponentVisibleEvent-CKELFJhI.js} +3 -3
  7. package/dist/amplitudeContext-Bh4SVVse.js +227 -0
  8. package/dist/amplitudeContext-CjFkl5yr.cjs +243 -0
  9. package/dist/amplitudeTrackEventAtom-D66l5oFp.js +8 -0
  10. package/dist/amplitudeTrackEventAtom-f22P2U0u.cjs +15 -0
  11. package/dist/app-CrmrUsr6.js +514 -0
  12. package/dist/app-DudAJOe4.cjs +569 -0
  13. package/dist/application/models/graphql/index.d.ts +1 -1
  14. package/dist/application/models/guards/api/index.d.ts +2 -2
  15. package/dist/application/models/guards/utils.d.ts +1 -1
  16. package/dist/application/models/index.d.cts +1 -1
  17. package/dist/application/models/index.d.ts +4 -4
  18. package/dist/application/utils/index.cjs +3 -12
  19. package/dist/application/utils/index.d.cts +5 -6
  20. package/dist/application/utils/index.d.ts +8 -9
  21. package/dist/application/utils/index.js +3 -12
  22. package/dist/atoms/app/index.cjs +13 -15
  23. package/dist/atoms/app/index.d.cts +7 -7
  24. package/dist/atoms/app/index.d.ts +6 -6
  25. package/dist/atoms/app/index.js +8 -10
  26. package/dist/atoms/atomStore/index.d.cts +1 -1
  27. package/dist/atoms/chat/index.cjs +11 -13
  28. package/dist/atoms/chat/index.d.cts +33 -34
  29. package/dist/atoms/chat/index.d.ts +34 -35
  30. package/dist/atoms/chat/index.js +11 -13
  31. package/dist/atoms/globalSearch/index.cjs +1 -1
  32. package/dist/atoms/globalSearch/index.d.cts +6 -6
  33. package/dist/atoms/globalSearch/index.d.ts +1 -1
  34. package/dist/atoms/globalSearch/index.js +1 -1
  35. package/dist/atoms/org/index.cjs +2 -2
  36. package/dist/atoms/org/index.d.cts +16 -16
  37. package/dist/atoms/org/index.d.ts +1 -1
  38. package/dist/atoms/org/index.js +2 -2
  39. package/dist/atoms/search/index.cjs +5 -5
  40. package/dist/atoms/search/index.d.cts +14 -14
  41. package/dist/atoms/search/index.d.ts +14 -14
  42. package/dist/atoms/search/index.js +5 -5
  43. package/dist/atoms/search/utils.cjs +1 -1
  44. package/dist/atoms/search/utils.js +1 -1
  45. package/dist/{cdnContext-KMAzFHrZ.cjs → cdnContext-B9s1XSTE.cjs} +2 -2
  46. package/dist/{cdnContext-BJZSYlsP.js → cdnContext-BKQT9bPr.js} +2 -2
  47. package/dist/{chat-yICI8tzz.cjs → chat-B87y65R0.cjs} +4 -5
  48. package/dist/chat-DfVncvc2.js +226 -0
  49. package/dist/chatState-AYi1RPOJ.js +33 -0
  50. package/dist/{chatState-BRYkF2g2.cjs → chatState-COd-Dczh.cjs} +3 -4
  51. package/dist/config/index.d.cts +4 -4
  52. package/dist/config/index.d.ts +4 -4
  53. package/dist/config/locators/components/chat/index.d.cts +1 -1
  54. package/dist/config/locators/components/chat/index.d.ts +1 -1
  55. package/dist/config/locators/components/common/index.d.cts +1 -1
  56. package/dist/config/locators/components/common/index.d.ts +1 -1
  57. package/dist/config/locators/components/index.d.cts +1 -1
  58. package/dist/config/locators/components/index.d.ts +1 -1
  59. package/dist/config/locators/index.d.cts +4 -4
  60. package/dist/config/locators/index.d.ts +4 -4
  61. package/dist/contexts/amplitudeContext/index.cjs +13 -12
  62. package/dist/contexts/amplitudeContext/index.d.cts +11 -2
  63. package/dist/contexts/amplitudeContext/index.d.ts +11 -2
  64. package/dist/contexts/amplitudeContext/index.js +12 -10
  65. package/dist/contexts/cdnContext/index.cjs +2 -2
  66. package/dist/contexts/cdnContext/index.js +2 -2
  67. package/dist/contexts/enviveConfigContext/index.cjs +2 -2
  68. package/dist/contexts/enviveConfigContext/index.js +2 -2
  69. package/dist/contexts/enviveCssContext/index.cjs +8 -8
  70. package/dist/contexts/enviveCssContext/index.js +8 -8
  71. package/dist/contexts/featureFlagContext/index.cjs +3 -3
  72. package/dist/contexts/featureFlagContext/index.js +3 -3
  73. package/dist/contexts/featureFlagServiceContext/index.cjs +2 -2
  74. package/dist/contexts/featureFlagServiceContext/index.d.cts +1 -1
  75. package/dist/contexts/featureFlagServiceContext/index.d.ts +1 -1
  76. package/dist/contexts/featureFlagServiceContext/index.js +2 -2
  77. package/dist/contexts/graphqlContext/index.cjs +2 -2
  78. package/dist/contexts/graphqlContext/index.d.cts +1 -1
  79. package/dist/contexts/graphqlContext/index.js +2 -2
  80. package/dist/contexts/localStorageContext/index.cjs +1 -1
  81. package/dist/contexts/localStorageContext/index.js +1 -1
  82. package/dist/contexts/newOrgConfigContext/index.cjs +7 -7
  83. package/dist/contexts/newOrgConfigContext/index.d.cts +1 -1
  84. package/dist/contexts/newOrgConfigContext/index.js +7 -7
  85. package/dist/contexts/searchContext/index.cjs +14 -15
  86. package/dist/contexts/searchContext/index.js +14 -15
  87. package/dist/contexts/sessionStorageContext/index.cjs +1 -1
  88. package/dist/contexts/sessionStorageContext/index.js +1 -1
  89. package/dist/contexts/shopifyUrlContext/index.cjs +2 -2
  90. package/dist/contexts/shopifyUrlContext/index.js +2 -2
  91. package/dist/contexts/systemSettingsContext/index.cjs +2 -2
  92. package/dist/contexts/systemSettingsContext/index.d.cts +2 -2
  93. package/dist/contexts/systemSettingsContext/index.d.ts +2 -2
  94. package/dist/contexts/systemSettingsContext/index.js +2 -2
  95. package/dist/contexts/userIdentityContext/index.cjs +10 -12
  96. package/dist/contexts/userIdentityContext/index.js +8 -10
  97. package/dist/{domObserver-B19-69gW.js → domObserver-CVhsCSkS.js} +1 -1
  98. package/dist/{domObserver-CwieVNgj.cjs → domObserver-LCBj1xw4.cjs} +1 -1
  99. package/dist/{enviveConfig-u50Rpz-G.cjs → enviveConfig-D3hmiaPh.cjs} +1 -1
  100. package/dist/{enviveConfig-Be2kZE7j.js → enviveConfig-DyvNVrxm.js} +1 -1
  101. package/dist/{enviveConfigContext-kQfHEGdJ.cjs → enviveConfigContext-BADXcRZr.cjs} +2 -2
  102. package/dist/{enviveConfigContext-1oiQuocd.js → enviveConfigContext-D8ijWYZf.js} +2 -2
  103. package/dist/{featureFlagServiceContext-B7je7VZV.d.cts → featureFlagServiceContext-ClnlCJV5.d.cts} +1 -1
  104. package/dist/{featureFlagServiceContext-DiYIv0jI.d.ts → featureFlagServiceContext-CyPGEe2d.d.ts} +1 -1
  105. package/dist/{featureFlagServiceContext-pPneufeB.cjs → featureFlagServiceContext-DQYo0d6Q.cjs} +1 -1
  106. package/dist/{featureFlagServiceContext-CPsygiHO.js → featureFlagServiceContext-GIO9xKV0.js} +1 -1
  107. package/dist/{globalSearch-OiF96VLG.cjs → globalSearch-Cpc8egsM.cjs} +1 -1
  108. package/dist/{globalSearch-B_v9qfCT.js → globalSearch-nmrfGLOn.js} +1 -1
  109. package/dist/{graphqlContext-BVFRNIdi.cjs → graphqlContext-BXdtsubh.cjs} +2 -2
  110. package/dist/{graphqlContext-D_Wp0LEl.js → graphqlContext-i_3n2qoK.js} +2 -2
  111. package/dist/hooks/AmplitudeOperations/index.cjs +12 -10
  112. package/dist/hooks/AmplitudeOperations/index.js +12 -10
  113. package/dist/hooks/AppDetails/index.cjs +11 -13
  114. package/dist/hooks/AppDetails/index.js +11 -13
  115. package/dist/hooks/CdnOperations/index.cjs +2 -2
  116. package/dist/hooks/CdnOperations/index.d.ts +1 -1
  117. package/dist/hooks/CdnOperations/index.js +2 -2
  118. package/dist/hooks/ChatToggle/index.cjs +16 -14
  119. package/dist/hooks/ChatToggle/index.js +15 -13
  120. package/dist/hooks/ChatToggleAnalytics/index.cjs +14 -12
  121. package/dist/hooks/ChatToggleAnalytics/index.js +14 -12
  122. package/dist/hooks/ElementObserver/index.cjs +1 -1
  123. package/dist/hooks/ElementObserver/index.d.cts +1 -1
  124. package/dist/hooks/ElementObserver/index.d.ts +1 -1
  125. package/dist/hooks/ElementObserver/index.js +1 -1
  126. package/dist/hooks/GrabAndScroll/index.d.cts +2 -2
  127. package/dist/hooks/GrabAndScroll/index.d.ts +2 -2
  128. package/dist/hooks/GraphQLConfig/index.cjs +3 -3
  129. package/dist/hooks/GraphQLConfig/index.js +3 -3
  130. package/dist/hooks/IdentifyUser/index.cjs +10 -12
  131. package/dist/hooks/IdentifyUser/index.d.ts +1 -1
  132. package/dist/hooks/IdentifyUser/index.js +9 -11
  133. package/dist/hooks/ImageResolver/index.cjs +1 -1
  134. package/dist/hooks/ImageResolver/index.js +1 -1
  135. package/dist/hooks/Intersection/index.cjs +1 -1
  136. package/dist/hooks/Intersection/index.js +1 -1
  137. package/dist/hooks/LocalStorageOperations/index.cjs +1 -1
  138. package/dist/hooks/LocalStorageOperations/index.js +1 -1
  139. package/dist/hooks/NewOrgConfig/index.cjs +8 -8
  140. package/dist/hooks/NewOrgConfig/index.d.cts +2 -2
  141. package/dist/hooks/NewOrgConfig/index.d.ts +2 -2
  142. package/dist/hooks/NewOrgConfig/index.js +8 -8
  143. package/dist/hooks/Search/index.cjs +19 -17
  144. package/dist/hooks/Search/index.js +19 -17
  145. package/dist/hooks/SearchOperations/index.cjs +15 -16
  146. package/dist/hooks/SearchOperations/index.js +15 -16
  147. package/dist/hooks/SessionStorageOperations/index.cjs +1 -1
  148. package/dist/hooks/SessionStorageOperations/index.js +1 -1
  149. package/dist/hooks/ShopifyUrlOperations/index.cjs +2 -2
  150. package/dist/hooks/ShopifyUrlOperations/index.js +2 -2
  151. package/dist/hooks/SystemSettingsContext/index.cjs +2 -2
  152. package/dist/hooks/SystemSettingsContext/index.d.cts +2 -2
  153. package/dist/hooks/SystemSettingsContext/index.d.ts +4 -4
  154. package/dist/hooks/SystemSettingsContext/index.js +2 -2
  155. package/dist/hooks/TrackComponentVisibleEvent/index.cjs +13 -11
  156. package/dist/hooks/TrackComponentVisibleEvent/index.js +13 -11
  157. package/dist/hooks/UpdateAnalyticsProps/index.cjs +15 -13
  158. package/dist/hooks/UpdateAnalyticsProps/index.js +12 -10
  159. package/dist/{index-CAhGZxMI.d.ts → index-5li6ZMDu.d.ts} +1 -1
  160. package/dist/{index-ca7Qn8o0.d.cts → index-BbqT4BQv.d.cts} +1 -1
  161. package/dist/{index-w64il54a.d.cts → index-CAJq_8bO.d.cts} +1 -1
  162. package/dist/{index-BQpWG3Jm.d.cts → index-ChiZg0yw.d.cts} +1 -1
  163. package/dist/{index-DNccxbJi.d.ts → index-CsmO1rDH.d.ts} +1 -1
  164. package/dist/{index-Dgu085Lu.d.ts → index-CuihhoIF.d.ts} +2 -2
  165. package/dist/{index-BR1G8yyg.d.ts → index-DtzPIcQp.d.ts} +1 -1
  166. package/dist/{index-ZQMda2Iu.d.ts → index-bEjLKG_Q.d.ts} +1 -1
  167. package/dist/{index-DiIHuPq2.d.ts → index-jFQefHda.d.ts} +1 -1
  168. package/dist/{index-BO-ZLYtR.d.ts → index-mv7KvWDq.d.ts} +1 -1
  169. package/dist/{index-ClVBVK15.d.cts → index-npqPeJ1g.d.cts} +1 -1
  170. package/dist/interceptors/index.d.ts +1 -1
  171. package/dist/{localStorageContext-Bb2b_3ue.cjs → localStorageContext-CMQMTX56.cjs} +1 -1
  172. package/dist/{localStorageContext-D2uXKahw.js → localStorageContext-znToxGBM.js} +1 -1
  173. package/dist/{newOrgConfigAtom-Dsk0fJNR.js → newOrgConfigAtom-CKuuohFM.js} +1 -1
  174. package/dist/{newOrgConfigAtom-hs5A1pbZ.cjs → newOrgConfigAtom-Cy66eryV.cjs} +1 -1
  175. package/dist/{newOrgConfigContext-Dn9l1f9w.js → newOrgConfigContext-UdjemITl.js} +5 -5
  176. package/dist/{newOrgConfigContext-DkBvmY0p.cjs → newOrgConfigContext-kCipbRua.cjs} +5 -5
  177. package/dist/{nodeSelector-0gJ8Xayf.d.ts → nodeSelector-BAKg1h_y.d.ts} +1 -1
  178. package/dist/{nodeSelector-Cj-Xl1LP.d.cts → nodeSelector-BYEAyrsj.d.cts} +1 -1
  179. package/dist/org-D_QTp1ex.js +32 -0
  180. package/dist/org-DnpLYVzD.cjs +111 -0
  181. package/dist/{search-jNTQGSyl.js → search-CP6Tnjsb.js} +4 -4
  182. package/dist/{search-D-BGpGJt.cjs → search-JN-IYDIE.cjs} +4 -4
  183. package/dist/{searchContext-C75BHjlY.cjs → searchContext-BrymLMqU.cjs} +5 -5
  184. package/dist/{searchContext-DjcqQsxp.js → searchContext-CgXwm6aL.js} +5 -5
  185. package/dist/{searchServiceAdapter-BSPZOg1r.js → searchServiceAdapter-B0h7psvh.js} +1 -1
  186. package/dist/{searchServiceAdapter-DrjFCiw8.cjs → searchServiceAdapter-BclWy4fE.cjs} +1 -1
  187. package/dist/{sessionStorageContext-ByaTsDUC.cjs → sessionStorageContext-BuWrJQwc.cjs} +1 -1
  188. package/dist/{sessionStorageContext-DKE97oMv.js → sessionStorageContext-DvFHbk81.js} +1 -1
  189. package/dist/{shopifyUrlContext-Ba6MQdNV.cjs → shopifyUrlContext-COc1eDR_.cjs} +2 -2
  190. package/dist/{shopifyUrlContext-BI3fVtA5.js → shopifyUrlContext-CToAt_98.js} +2 -2
  191. package/dist/{systemSettingsContext-DTdzjE_O.js → systemSettingsContext-B8a7vEqE.js} +2 -2
  192. package/dist/{systemSettingsContext-CSXsgBiG.cjs → systemSettingsContext-D-4ma13L.cjs} +2 -2
  193. package/dist/types/index.d.ts +1 -1
  194. package/dist/{urlsParser-C-Vzs--G.cjs → urlsParser-Dax4iVNC.cjs} +1 -1
  195. package/dist/{urlsParser-G7Ocwg0M.js → urlsParser-NAp2LwWP.js} +1 -1
  196. package/dist/{useAppDetails-Cq8TbvkX.cjs → useAppDetails-BkTsIODv.cjs} +7 -7
  197. package/dist/{useAppDetails-DjdYWTqz.js → useAppDetails-HS5GtU5O.js} +4 -4
  198. package/dist/{useGraphQLConfig-Dy0ml9xw.cjs → useGraphQLConfig-DCd-kR81.cjs} +2 -2
  199. package/dist/{useGraphQLConfig-nY5CE8kj.js → useGraphQLConfig-arTbYTKS.js} +2 -2
  200. package/dist/{useIntersection-BQMfiS4x.cjs → useIntersection-BcBCa890.cjs} +1 -1
  201. package/dist/{useIntersection-D-ol9eH8.js → useIntersection-BkMkuJcZ.js} +1 -1
  202. package/dist/{utils-sosM0bEk.d.ts → utils-BitIIghf.d.ts} +1 -1
  203. package/dist/{utils-BBICrPjW.cjs → utils-CqVRbvfN.cjs} +1 -1
  204. package/dist/utils-CxDOv-yL.js +607 -0
  205. package/dist/{utils-w4-xONRA.js → utils-DQhbbAnt.js} +1 -1
  206. package/dist/utils-DucG4gQ7.cjs +716 -0
  207. package/package.json +2 -2
  208. package/src/application/commerce-api.ts +2 -0
  209. package/src/application/utils/analyticsUtils.ts +31 -16
  210. package/src/atoms/amplitude/amplitudeTrackEventAtom.ts +1 -1
  211. package/src/atoms/chat/chatState.ts +12 -7
  212. package/src/atoms/chat/replies.ts +42 -40
  213. package/src/contexts/amplitudeContext/amplitudeContext.tsx +116 -130
  214. package/dist/amplitudeContext-CMTvCsJC.d.ts +0 -52
  215. package/dist/amplitudeContext-ZkerrMUa.d.cts +0 -52
  216. package/dist/amplitudeTrackEventAtom-BBkB1LPQ.cjs +0 -15
  217. package/dist/amplitudeTrackEventAtom-yP38BuDB.js +0 -8
  218. package/dist/chat-DYD6B6em.js +0 -227
  219. package/dist/chatState-DRKB9bqM.js +0 -34
  220. package/dist/org-C2kLSSe9.cjs +0 -111
  221. package/dist/org-CIczyLRP.js +0 -32
  222. package/dist/utils-DqNhRm2b.cjs +0 -1546
  223. package/dist/utils-IogJwDB9.js +0 -1364
  224. /package/dist/{featureFlagServiceContext-DgoR6euC.js → featureFlagServiceContext-CISyb90N.js} +0 -0
  225. /package/dist/{featureFlagServiceContext-b-rYgf0u.cjs → featureFlagServiceContext-Csgo-MUv.cjs} +0 -0
@@ -0,0 +1,514 @@
1
+ import { SessionRestartRequired, UnsupportedProductException } from "./exceptions-CUGY31Ua.js";
2
+ import { ProductExperiment, VariantTypeEnum } from "./dist-CtkINi1R.js";
3
+ import { validateOrgConfigResults, validateResponse, validateSuggestion, validateUserEvent } from "./models-DmsMlaHT.js";
4
+ import { logger_default } from "./logger-BMVdhQOV.js";
5
+ import { coreSupportedEventRequestToApiRequest, messageFromFormSubmittedEvent, messageFromQueryEvent, messageFromResponse, messageFromSuggestionEvent, messageRequestToCommerceMessageRequest } from "./utils-CxDOv-yL.js";
6
+ import { getAtomStore, sessionStorageUtil } from "./atomStore-BuopbV9k.js";
7
+ import { baseUrlAtom, contextSourceAtom, envAtom, orgShortNameAtom, reactAppNameAtom } from "./enviveConfig-DyvNVrxm.js";
8
+ import { featureFlagServiceAtom, orgIdAtom } from "./org-D_QTp1ex.js";
9
+ import { useLocalStorage } from "./localStorageContext-znToxGBM.js";
10
+ import { Configuration, ContextEnvEnum, ContextSourceEnum, CustomerServiceApi, DefaultApi, FormType, InferenceApi, ResponseCategory, ResponseError, UserEventCategory, V1OrgConfigGetSourceEnum } from "@spiffy-ai/commerce-api-client";
11
+ import { v4 } from "uuid";
12
+ import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react";
13
+ import { atom } from "jotai";
14
+ import { atomWithStorage } from "jotai/utils";
15
+ import UAParser from "ua-parser-js";
16
+ import { jsx } from "react/jsx-runtime";
17
+
18
+ //#region src/application/commerce-api.ts
19
+ async function errorResponseBody(error) {
20
+ try {
21
+ return await error.response.json();
22
+ } catch {
23
+ return {};
24
+ }
25
+ }
26
+ async function throwSessionRestartRequiredIf(errorMsg, error) {
27
+ if (!(error instanceof ResponseError)) {
28
+ logger_default.logInfo(errorMsg, error);
29
+ throw error;
30
+ }
31
+ const errorResponse = await errorResponseBody(error);
32
+ if (errorResponse?.message?.toLowerCase() === "unsupported product" || errorResponse?.app_code?.toUpperCase() === "PRODUCT_NOT_FOUND") throw new UnsupportedProductException();
33
+ else if (errorResponse?.app_code?.toUpperCase() === "RESTART_SESSION" || errorResponse?.sub_code?.toUpperCase() === "NOT_FOUND") {
34
+ logger_default.logInfo("Session does not exist. Re-start session", error, error.response, errorResponse);
35
+ throw new SessionRestartRequired();
36
+ }
37
+ logger_default.logInfo(errorMsg, error);
38
+ throw error;
39
+ }
40
+ var CommerceApiClient = class CommerceApiClient {
41
+ static {
42
+ this.getInstance = () => {
43
+ if (!CommerceApiClient.instance) CommerceApiClient.instance = new CommerceApiClient();
44
+ return CommerceApiClient.instance;
45
+ };
46
+ }
47
+ constructor(basePath) {
48
+ this.suggestionsAbortController = new AbortController();
49
+ this.responsesAbortController = new AbortController();
50
+ const baseUrl = getAtomStore().get(baseUrlAtom);
51
+ const config = new Configuration({
52
+ basePath: basePath || baseUrl,
53
+ headers: {
54
+ "Content-Type": "application/json",
55
+ Accept: "application/json"
56
+ }
57
+ });
58
+ this.defaultApi = new DefaultApi(config);
59
+ this.inferenceApi = new InferenceApi(config);
60
+ this.customerServiceApi = new CustomerServiceApi(config);
61
+ }
62
+ static {
63
+ this.resolveUrl = async (url) => {
64
+ const atomStore = getAtomStore();
65
+ const orgShortName = atomStore.get(orgShortNameAtom);
66
+ const orgId = atomStore.get(orgIdAtom);
67
+ const userId = atomStore.get(userIdAtom);
68
+ const chatId = atomStore.get(chatIdAtom);
69
+ const source = atomStore.get(contextSourceAtom);
70
+ const env = atomStore.get(envAtom);
71
+ const featureFlagService = atomStore.get(featureFlagServiceAtom);
72
+ const context = {
73
+ user_id: userId ?? "",
74
+ org_id: orgId ?? "",
75
+ org_short_name: orgShortName ?? "",
76
+ chat_id: chatId ?? "",
77
+ source: source ?? ContextSourceEnum.App,
78
+ env: env ?? ContextEnvEnum.Dev
79
+ };
80
+ const featureGates = featureFlagService?.featureFlagService?.getFeatureFlags() || {};
81
+ const urlResolvingRequest = {
82
+ url,
83
+ context,
84
+ feature_gates: featureGates
85
+ };
86
+ return await (await CommerceApiClient.getInstance().inferenceApi.v1UrlResolvingPostRaw({ UrlResolvingRequest: urlResolvingRequest })).raw.json();
87
+ };
88
+ }
89
+ static {
90
+ this.reportSession = async (reportRequest) => {
91
+ await CommerceApiClient.getInstance().defaultApi.v1ChatsReportSessionIdPost({ ReportSessionRequest: reportRequest });
92
+ };
93
+ }
94
+ static {
95
+ this.getNextResponses = async (payload) => {
96
+ try {
97
+ return (await CommerceApiClient.getInstance().inferenceApi.v1NextResponsesPost({ NextMessageRequest: messageRequestToCommerceMessageRequest(payload) })).map((resp) => validateResponse(resp)).map((resp) => messageFromResponse(resp)).filter((m) => m != null);
98
+ } catch (err) {
99
+ logger_default.logInfo("Failed to get next responses", err, {
100
+ payloadContext: payload?.context,
101
+ userEvents: payload?.userEvents
102
+ });
103
+ await throwSessionRestartRequiredIf("Failed to get next responses", err);
104
+ return [];
105
+ }
106
+ };
107
+ }
108
+ static {
109
+ this.getNextResponseStreaming = (payload) => {
110
+ async function* generate(inferenceApi, abortController) {
111
+ try {
112
+ const response = await inferenceApi.v1NextResponsesPostRaw({ NextMessageRequest: messageRequestToCommerceMessageRequest(payload) }, { signal: abortController.signal });
113
+ if (!response.raw.body) {
114
+ logger_default.logError("[spiffy-ai] No body in the streamed response", void 0, { response: response.raw });
115
+ return;
116
+ }
117
+ const reader = response.raw.body.getReader();
118
+ const decoder = new TextDecoder("utf-8");
119
+ let partial = "";
120
+ const safeParse = (line) => {
121
+ try {
122
+ return JSON.parse(line);
123
+ } catch (err) {
124
+ logger_default.logError("[spiffy-ai] Error parsing streamed line", err, {
125
+ line,
126
+ partial
127
+ });
128
+ partial = line;
129
+ return partial;
130
+ }
131
+ };
132
+ const processChunk = (chunk) => {
133
+ return `${partial}${chunk}`.split("\n").map((line) => line.replace(/^data: /, "").trim()).filter((line) => line !== "" && line !== "[DONE]").map(safeParse).filter((v) => v);
134
+ };
135
+ while (true) {
136
+ const { done, value } = await reader.read();
137
+ if (done) break;
138
+ const chunk = decoder.decode(value);
139
+ const parsedLines = processChunk(chunk);
140
+ for (const parsedLine of parsedLines) {
141
+ const validatedResponse = validateResponse(parsedLine);
142
+ if (validatedResponse) yield validatedResponse;
143
+ }
144
+ }
145
+ } catch (error) {
146
+ logger_default.logError("[spiffy-ai] Failed to get next streaming responses", error, {
147
+ payloadContext: payload?.context,
148
+ userEvents: payload?.userEvents
149
+ });
150
+ await throwSessionRestartRequiredIf("Failed to get next streaming responses", error);
151
+ }
152
+ }
153
+ CommerceApiClient.getInstance().responsesAbortController.abort();
154
+ CommerceApiClient.getInstance().responsesAbortController = new AbortController();
155
+ return generate(CommerceApiClient.getInstance().inferenceApi, CommerceApiClient.getInstance().responsesAbortController);
156
+ };
157
+ }
158
+ static {
159
+ this.getNextSuggestions = async (payload) => {
160
+ try {
161
+ CommerceApiClient.getInstance().suggestionsAbortController.abort();
162
+ CommerceApiClient.getInstance().suggestionsAbortController = new AbortController();
163
+ return (await CommerceApiClient.getInstance().inferenceApi.v1NextSuggestionsPost({ NextMessageRequest: messageRequestToCommerceMessageRequest(payload) }, { signal: CommerceApiClient.getInstance().suggestionsAbortController.signal })).map((resp) => validateSuggestion(resp)).filter((suggestion) => suggestion != null);
164
+ } catch (error) {
165
+ logger_default.logInfo("Failed to get suggestions", error, {
166
+ payloadContext: payload?.context,
167
+ userEvents: payload?.userEvents
168
+ });
169
+ await throwSessionRestartRequiredIf("Failed to get suggestions", error);
170
+ return [];
171
+ }
172
+ };
173
+ }
174
+ static {
175
+ this.getResponses = async (orgId, chatId, userId) => {
176
+ let data = {
177
+ responses: [],
178
+ suggestions: [],
179
+ user_events: []
180
+ };
181
+ const request = {
182
+ org_id: orgId,
183
+ chat_id: chatId,
184
+ user_id: userId
185
+ };
186
+ try {
187
+ data = await CommerceApiClient.getInstance().defaultApi.v1GetSessionMessages(request);
188
+ } catch (error) {
189
+ await throwSessionRestartRequiredIf("Failed to get chat responses", error);
190
+ }
191
+ const responses = data?.responses?.map((turn) => turn.map((response) => validateResponse(response)).filter((response) => response != null));
192
+ const suggestions = data?.suggestions.map((suggestion) => validateSuggestion(suggestion)).filter((suggestion) => suggestion != null);
193
+ const userEvents = data?.user_events.map((event) => validateUserEvent(event)).filter((event) => event != null);
194
+ const formSubmittedUserEventsFormIds = userEvents.filter((event) => event.category === UserEventCategory.FormSubmitted).map((event) => event.attributes.formResponseId);
195
+ const assistantMessages = responses.map((turn) => turn.filter((response) => !(response.category === ResponseCategory.Form && formSubmittedUserEventsFormIds.includes(response.id))).map((response) => messageFromResponse(response)).filter((message) => message != null)).filter((turn) => turn.length > 0);
196
+ const userMessages = userEvents.map((event) => {
197
+ if ([UserEventCategory.QueryTyped, UserEventCategory.Search].includes(event.category)) return [messageFromQueryEvent(event)];
198
+ if (event.category === UserEventCategory.SuggestionClicked) return [messageFromSuggestionEvent(event, suggestions)];
199
+ if (event.category === UserEventCategory.FormSubmitted) {
200
+ const formResponse = responses.flat().find((response) => response.id === event.attributes.formResponseId && event.attributes.formType !== FormType.Escalation);
201
+ if (formResponse && formResponse.category === ResponseCategory.Form) return [messageFromFormSubmittedEvent(event, formResponse.attributes)];
202
+ }
203
+ return [];
204
+ }).filter((message) => message.length > 0);
205
+ const sortedMessages = [...assistantMessages, ...userMessages].sort((a, b) => new Date(a[0].createdAt).getTime() - new Date(b[0].createdAt).getTime());
206
+ return {
207
+ responses,
208
+ userEvents,
209
+ suggestions,
210
+ messages: sortedMessages
211
+ };
212
+ };
213
+ }
214
+ static {
215
+ this.isSupportedEvent = async (payload) => {
216
+ try {
217
+ const httpResponseText = await (await CommerceApiClient.getInstance().inferenceApi.v1SupportedEventPostRaw({ SupportedEventRequest: coreSupportedEventRequestToApiRequest(payload) })).raw.text();
218
+ const httpResponseJson = JSON.parse(httpResponseText);
219
+ return {
220
+ ...httpResponseJson,
221
+ numberOfReviews: httpResponseJson.num_of_reviews,
222
+ merchant_tags: httpResponseJson.merchant_tags || []
223
+ };
224
+ } catch (err) {
225
+ logger_default.logError("Failed to get response for v1SupportedEventPost", { err });
226
+ return {
227
+ supported: false,
228
+ ready: false,
229
+ category: void 0,
230
+ collections: [],
231
+ numberOfReviews: void 0,
232
+ top_category: void 0,
233
+ merchant_tags: []
234
+ };
235
+ }
236
+ };
237
+ }
238
+ static {
239
+ this.identifyUser = async (spiffyUserId, merchantUserId, uaDetails) => {
240
+ try {
241
+ await CommerceApiClient.getInstance().defaultApi.v1AnalyticsIdentifyPost({ AnalyticsIdentifyRequest: {
242
+ user_id: spiffyUserId,
243
+ os_name: uaDetails.os,
244
+ os_version: uaDetails.osVersion,
245
+ platform: uaDetails.os,
246
+ device_id: uaDetails.deviceModel,
247
+ device_brand: uaDetails.deviceBrand,
248
+ device_manufacturer: uaDetails.deviceManufacturer,
249
+ device_model: uaDetails.deviceModel,
250
+ user_properties: {
251
+ cdp_user_id: merchantUserId,
252
+ browser: uaDetails.browser,
253
+ browser_version: uaDetails.browserVersion,
254
+ user_agent: uaDetails.userAgent
255
+ }
256
+ } });
257
+ } catch (err) {
258
+ logger_default.logError("Failed to identify user", err);
259
+ }
260
+ };
261
+ }
262
+ static {
263
+ this.mapContextSourceToV1OrgConfigGetSource = (source) => {
264
+ if (source === void 0) return void 0;
265
+ switch (source) {
266
+ case ContextSourceEnum.Fork: return V1OrgConfigGetSourceEnum.Fork;
267
+ case ContextSourceEnum.Playground: return V1OrgConfigGetSourceEnum.Playground;
268
+ case ContextSourceEnum.App: return V1OrgConfigGetSourceEnum.App;
269
+ case ContextSourceEnum.Test: return V1OrgConfigGetSourceEnum.Test;
270
+ default: return source;
271
+ }
272
+ };
273
+ }
274
+ static {
275
+ this.getOrgConfig = async (user_id) => {
276
+ try {
277
+ const atomStore = getAtomStore();
278
+ const reactAppName = atomStore.get(reactAppNameAtom);
279
+ const contextSource = atomStore.get(contextSourceAtom);
280
+ const featureFlagService = atomStore.get(featureFlagServiceAtom);
281
+ const request = {
282
+ namespace: reactAppName,
283
+ user_id,
284
+ source: this.mapContextSourceToV1OrgConfigGetSource(contextSource),
285
+ include_experiments: Object.values(ProductExperiment),
286
+ include_feature_gates: Object.entries(featureFlagService?.featureFlagService?.getFeatureFlags() || {}).filter(([, isEnabled]) => isEnabled).map(([featureGateName]) => featureGateName)
287
+ };
288
+ const response = await CommerceApiClient.getInstance().defaultApi.v1OrgConfigGet(request);
289
+ return validateOrgConfigResults(response);
290
+ } catch (err) {
291
+ logger_default.logError(`Failed to get org config`, err, { err });
292
+ return;
293
+ }
294
+ };
295
+ }
296
+ static {
297
+ this.addNoteToLatestConversation = async (spiffyUserId, email, customerServiceProvider) => {
298
+ logger_default.logInfo(`addNoteToLatestConversation - user_id=${spiffyUserId} email=${email} customer_service_provider=${customerServiceProvider}`);
299
+ try {
300
+ await CommerceApiClient.getInstance().customerServiceApi.v1CustserviceAddNoteToLatestConversationPost({ AddNoteToLatestConversationRequest: {
301
+ spiffy_user_id: spiffyUserId,
302
+ email,
303
+ customer_service_provider: customerServiceProvider
304
+ } });
305
+ } catch (err) {
306
+ logger_default.logError("Failed to add note to latest conversation", { err });
307
+ }
308
+ };
309
+ }
310
+ static {
311
+ this.getCustomerServiceApi = () => CommerceApiClient.getInstance().customerServiceApi;
312
+ }
313
+ };
314
+ var commerce_api_default = CommerceApiClient;
315
+
316
+ //#endregion
317
+ //#region src/contexts/userIdentityContext/userIdentityContext.tsx
318
+ const getUserAgentDetails = () => {
319
+ const result = new UAParser().getResult();
320
+ return {
321
+ os: result?.os?.name,
322
+ osVersion: result?.os?.version,
323
+ deviceBrand: result?.device?.vendor,
324
+ deviceManufacturer: result?.device?.vendor,
325
+ deviceModel: result?.device?.model,
326
+ browser: result?.browser?.name,
327
+ browserVersion: result?.browser?.version,
328
+ userAgent: result?.ua
329
+ };
330
+ };
331
+ const UserIdentityContext = createContext(void 0);
332
+ const UserIdentityProvider = ({ children }) => {
333
+ const { getItem, setItem, isAvailable: localStorageIsReady } = useLocalStorage();
334
+ const [isReady, setIsReady] = useState(false);
335
+ useEffect(() => {
336
+ setIsReady(localStorageIsReady);
337
+ }, [localStorageIsReady]);
338
+ const USER_ID_OVERRIDE_KEY = "v1-spiffy-user-id-override";
339
+ const USER_ID_DEFAULT_KEY = "v1-spiffy-user-id-default";
340
+ const getUserIdOverrideFromLocalStorage = useCallback(() => getItem(USER_ID_OVERRIDE_KEY) ?? void 0, [getItem]);
341
+ const getUserIdDefaultFromLocalStorage = useCallback(() => getItem(USER_ID_DEFAULT_KEY) ?? void 0, [getItem]);
342
+ const setUserIdDefaultInLocalStorage = useCallback((userId) => {
343
+ logger_default.logInfo(`setUserIdDefaultInLocalStorage - Setting user_id=${userId}`);
344
+ setItem(USER_ID_DEFAULT_KEY, userId);
345
+ return userId;
346
+ }, [setItem, USER_ID_DEFAULT_KEY]);
347
+ const setUserIdOverrideInLocalStorage = useCallback((userId) => {
348
+ logger_default.logInfo(`setUserIdOverrideInLocalStorage - Setting user_id=${userId}`);
349
+ setItem(USER_ID_OVERRIDE_KEY, userId);
350
+ return userId;
351
+ }, [setItem, USER_ID_OVERRIDE_KEY]);
352
+ const clearUserIdOverrideInLocalStorage = useCallback(() => {
353
+ logger_default.logInfo(`clearUserIdOverrideInLocalStorage - Clearing user_id`);
354
+ setItem(USER_ID_OVERRIDE_KEY, "");
355
+ }, [setItem, USER_ID_OVERRIDE_KEY]);
356
+ const getUserIdOrDefault = useCallback(() => {
357
+ const userIdOverride = getUserIdOverrideFromLocalStorage();
358
+ if (userIdOverride) return userIdOverride;
359
+ const defaultUserId = getUserIdDefaultFromLocalStorage();
360
+ if (defaultUserId) return defaultUserId;
361
+ return setUserIdDefaultInLocalStorage(`spiffy-user-id-${v4()}`);
362
+ }, [
363
+ getUserIdOverrideFromLocalStorage,
364
+ getUserIdDefaultFromLocalStorage,
365
+ setUserIdDefaultInLocalStorage
366
+ ]);
367
+ const identifyUser = useCallback(async () => {
368
+ if (!isReady) {
369
+ logger_default.logWarn("[UserIdentityContext] Context not ready, skipping identifyUser", void 0);
370
+ return;
371
+ }
372
+ try {
373
+ const cdpUserId = "UNKNOWN_CDP_USER_ID";
374
+ const userId = getUserIdOrDefault();
375
+ const userAgentDetails = getUserAgentDetails();
376
+ await commerce_api_default.identifyUser(userId, cdpUserId, userAgentDetails);
377
+ } catch (error) {
378
+ logger_default.logError("[spiffy-ai] Error identifying user", error);
379
+ }
380
+ }, [isReady, getUserIdOrDefault]);
381
+ const value = useMemo(() => ({
382
+ identifyUser,
383
+ getUserIdOrDefault,
384
+ getUserIdOverrideFromLocalStorage,
385
+ getUserIdDefaultFromLocalStorage,
386
+ setUserIdDefaultInLocalStorage,
387
+ setUserIdOverrideInLocalStorage,
388
+ clearUserIdOverrideInLocalStorage,
389
+ isReady
390
+ }), [
391
+ identifyUser,
392
+ getUserIdOrDefault,
393
+ getUserIdOverrideFromLocalStorage,
394
+ getUserIdDefaultFromLocalStorage,
395
+ setUserIdDefaultInLocalStorage,
396
+ setUserIdOverrideInLocalStorage,
397
+ clearUserIdOverrideInLocalStorage,
398
+ isReady
399
+ ]);
400
+ return /* @__PURE__ */ jsx(UserIdentityContext.Provider, {
401
+ value,
402
+ children
403
+ });
404
+ };
405
+ const useUserIdentity = () => {
406
+ const context = useContext(UserIdentityContext);
407
+ if (!context) throw new Error("useUserIdentity must be used within a UserIdentityProvider");
408
+ return context;
409
+ };
410
+
411
+ //#endregion
412
+ //#region src/atoms/app/variant.ts
413
+ const internalStorageUrlResolverAtom = atomWithStorage("spiffy-url-resolver", void 0, sessionStorageUtil, { getOnInit: true });
414
+ const urlResolverAtom = atom((get) => {
415
+ const maybeUrlResolver = get(internalStorageUrlResolverAtom);
416
+ if (maybeUrlResolver == null) return {};
417
+ return JSON.parse(maybeUrlResolver);
418
+ }, (get, set, value) => {
419
+ const newCache = {
420
+ ...get(urlResolverAtom),
421
+ [value.url]: value.response
422
+ };
423
+ set(internalStorageUrlResolverAtom, JSON.stringify(newCache));
424
+ });
425
+ const internalStorageSupportedEventAtom = atomWithStorage("spiffy-supported-event", void 0, sessionStorageUtil, { getOnInit: true });
426
+ const internalSupportedEventAtom = atom(void 0);
427
+ const supportedEventAtom = atom((get) => {
428
+ const maybeSupportedEvent = get(internalStorageSupportedEventAtom);
429
+ if (maybeSupportedEvent == null) return;
430
+ return JSON.parse(maybeSupportedEvent);
431
+ }, (_, set, value) => {
432
+ if (value == null) {
433
+ set(internalStorageSupportedEventAtom, void 0);
434
+ set(internalSupportedEventAtom, void 0);
435
+ return;
436
+ }
437
+ set(internalSupportedEventAtom, value);
438
+ set(internalStorageSupportedEventAtom, JSON.stringify(value));
439
+ });
440
+ const internalVariantIdAtom = atom();
441
+ const internalProductIdAtom = atom();
442
+ const internalParentProductIdAtom = atom();
443
+ const internalProductUrlAtom = atom();
444
+ const internalPlpIdAtom = atom();
445
+ const internalUrlAtom = atom();
446
+ const internalPageVisitCategoryAtom = atom();
447
+ const internalVariantAtom = atom("pdp");
448
+ const variantIdAtom = atom((get) => get(internalVariantIdAtom));
449
+ const productIdAtom = atom((get) => get(internalProductIdAtom));
450
+ const parentProductIdAtom = atom((get) => get(internalParentProductIdAtom));
451
+ const productUrlAtom = atom((get) => get(internalProductUrlAtom));
452
+ const plpIdAtom = atom((get) => get(internalPlpIdAtom));
453
+ const urlAtom = atom((get) => get(internalUrlAtom));
454
+ const pageVisitCategoryAtom = atom((get) => get(internalPageVisitCategoryAtom));
455
+ const variantAtom = atom((get) => get(internalVariantAtom));
456
+ const hasParsedVariantInfoAtom = atom(false);
457
+ const variantInfoAtom = atom((get) => {
458
+ const variant = get(variantAtom);
459
+ if (variant === VariantTypeEnum.Pdp) return {
460
+ variantId: get(variantIdAtom),
461
+ variant,
462
+ productId: get(productIdAtom),
463
+ parentProductId: get(parentProductIdAtom),
464
+ url: get(urlAtom)
465
+ };
466
+ if (variant === VariantTypeEnum.Plp) return {
467
+ variantId: get(variantIdAtom),
468
+ variant,
469
+ plpId: get(plpIdAtom),
470
+ url: get(urlAtom)
471
+ };
472
+ if (variant === VariantTypeEnum.PageVisit) return {
473
+ variantId: get(variantIdAtom),
474
+ variant,
475
+ url: get(urlAtom),
476
+ pageVisitCategory: get(pageVisitCategoryAtom)
477
+ };
478
+ throw new Error("Invalid variantInfo details");
479
+ }, (_, set, newVariant) => {
480
+ set(internalVariantAtom, newVariant.variant);
481
+ set(internalVariantIdAtom, newVariant.variantId);
482
+ if (newVariant.variant === VariantTypeEnum.Pdp) {
483
+ set(internalProductIdAtom, newVariant.productId);
484
+ set(internalParentProductIdAtom, newVariant.parentProductId);
485
+ set(internalUrlAtom, newVariant.url);
486
+ }
487
+ if (newVariant.variant === VariantTypeEnum.Plp) {
488
+ set(internalPlpIdAtom, newVariant.plpId);
489
+ set(internalUrlAtom, newVariant.url);
490
+ }
491
+ if (newVariant.variant === VariantTypeEnum.PageVisit) {
492
+ set(internalUrlAtom, newVariant.url);
493
+ set(internalPageVisitCategoryAtom, newVariant.pageVisitCategory);
494
+ }
495
+ });
496
+
497
+ //#endregion
498
+ //#region src/atoms/app/index.ts
499
+ const internalUserIdAtom = atom(void 0);
500
+ const userIdAtom = atom((get) => {
501
+ const maybeUserId = get(internalUserIdAtom);
502
+ if (maybeUserId) return maybeUserId;
503
+ const { getUserIdOrDefault } = useUserIdentity();
504
+ return getUserIdOrDefault();
505
+ }, (_, set, value) => {
506
+ set(internalUserIdAtom, value);
507
+ });
508
+ const userIdentityAtom = atom(void 0);
509
+ const appSourceAtom = atom((get) => get(contextSourceAtom) ?? ContextSourceEnum.App);
510
+ const chatIdAtom = atomWithStorage("v1-spiffy-chat-session-id", v4(), void 0, { getOnInit: true });
511
+
512
+ //#endregion
513
+ export { UserIdentityProvider, appSourceAtom, chatIdAtom, hasParsedVariantInfoAtom, useUserIdentity, userIdAtom, userIdentityAtom, variantInfoAtom };
514
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLUNybXJVc3I2LmpzIiwibmFtZXMiOlsiY29uZmlnOiBDb25maWd1cmF0aW9uIiwiY29udGV4dDogQ29udGV4dCIsImVycjogdW5rbm93biIsImVycm9yOiB1bmtub3duIiwiZGF0YTogVjFHZXRTZXNzaW9uTWVzc2FnZXMyMDBSZXNwb25zZSIsInJlc3BvbnNlczogQXBpUmVzcG9uc2VbXVtdIiwic3VnZ2VzdGlvbnM6IFN1Z2dlc3Rpb25bXSIsInVzZXJFdmVudHM6IFVzZXJFdmVudFtdIiwiYXNzaXN0YW50TWVzc2FnZXM6IE1lc3NhZ2VbXVtdIiwidXNlck1lc3NhZ2VzOiBNZXNzYWdlW11bXSIsInJlcXVlc3Q6IFYxT3JnQ29uZmlnR2V0UmVxdWVzdCIsIlVzZXJJZGVudGl0eVByb3ZpZGVyOiBSZWFjdC5GQzx7IGNoaWxkcmVuOiBSZWFjdC5SZWFjdE5vZGUgfT4iLCJ1dWlkIiwiQ29tbWVyY2VBcGlDbGllbnQiLCJ1dWlkIl0sInNvdXJjZXMiOlsiLi4vc3JjL2FwcGxpY2F0aW9uL2NvbW1lcmNlLWFwaS50cyIsIi4uL3NyYy9jb250ZXh0cy91c2VySWRlbnRpdHlDb250ZXh0L3VzZXJJZGVudGl0eUNvbnRleHQudHN4IiwiLi4vc3JjL2F0b21zL2FwcC92YXJpYW50LnRzIiwiLi4vc3JjL2F0b21zL2FwcC9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb250ZXh0LFxuICBDb250ZXh0RW52RW51bSxcbiAgQ29uZmlndXJhdGlvbixcbiAgQ3VzdG9tZXJTZXJ2aWNlQXBpLFxuICBEZWZhdWx0QXBpLFxuICBJbmZlcmVuY2VBcGksXG4gIFJlcG9ydFNlc3Npb25SZXF1ZXN0LFxuICBSZXNwb25zZUVycm9yLFxuICBVc2VyRXZlbnRDYXRlZ29yeSxcbiAgVjFHZXRTZXNzaW9uTWVzc2FnZXMyMDBSZXNwb25zZSxcbiAgVjFPcmdDb25maWdHZXRSZXF1ZXN0LFxuICBDb250ZXh0U291cmNlRW51bSxcbiAgVjFPcmdDb25maWdHZXRTb3VyY2VFbnVtLFxuICBDdXN0b21lclNlcnZpY2VQcm92aWRlcixcbiAgUmVzcG9uc2VDYXRlZ29yeSxcbiAgRm9ybVR5cGUsXG59IGZyb20gXCJAc3BpZmZ5LWFpL2NvbW1lcmNlLWFwaS1jbGllbnRcIjtcbmltcG9ydCB7XG4gIFN1cHBvcnRlZEV2ZW50LFxuICBQcm9kdWN0RXhwZXJpbWVudCxcbiAgQ2xpZW50RGV0YWlscyxcbiAgVXNlckV2ZW50LFxuICBOZXh0TWVzc2FnZVJlcXVlc3QsXG4gIFN1cHBvcnRlZEV2ZW50UmVxdWVzdCxcbiAgT3JnQ29uZmlnLFxufSBmcm9tIFwiQGVudml2ZS1haS90eXBlc1wiO1xuaW1wb3J0IHsgQXBpUmVzcG9uc2UsIE1lc3NhZ2UsIFN1Z2dlc3Rpb24gfSBmcm9tIFwic3JjL3R5cGVzXCI7XG5pbXBvcnQgeyB1c2VySWRBdG9tLCBjaGF0SWRBdG9tIH0gZnJvbSBcInNyYy9hdG9tcy9hcHBcIjtcbmltcG9ydCB7IGdldEF0b21TdG9yZSB9IGZyb20gXCJzcmMvYXRvbXMvYXRvbVN0b3JlXCI7XG5pbXBvcnQge1xuICBiYXNlVXJsQXRvbSxcbiAgb3JnU2hvcnROYW1lQXRvbSxcbiAgY29udGV4dFNvdXJjZUF0b20sXG4gIGVudkF0b20sXG4gIHJlYWN0QXBwTmFtZUF0b20sXG59IGZyb20gXCJzcmMvYXRvbXMvZW52aXZlL2Vudml2ZUNvbmZpZ1wiO1xuaW1wb3J0IHsgb3JnSWRBdG9tLCBmZWF0dXJlRmxhZ1NlcnZpY2VBdG9tIH0gZnJvbSBcInNyYy9hdG9tcy9vcmdcIjtcbmltcG9ydCB7XG4gIFVuc3VwcG9ydGVkUHJvZHVjdEV4Y2VwdGlvbixcbiAgU2Vzc2lvblJlc3RhcnRSZXF1aXJlZCxcbn0gZnJvbSBcInNyYy9leGNlcHRpb25zXCI7XG5pbXBvcnQgTG9nZ2VyIGZyb20gXCIuL2xvZ2dpbmcvbG9nZ2VyXCI7XG5pbXBvcnQge1xuICB2YWxpZGF0ZVJlc3BvbnNlLFxuICB2YWxpZGF0ZVN1Z2dlc3Rpb24sXG4gIHZhbGlkYXRlVXNlckV2ZW50LFxuICB2YWxpZGF0ZU9yZ0NvbmZpZ1Jlc3VsdHMsXG59IGZyb20gXCIuL21vZGVsc1wiO1xuaW1wb3J0IHtcbiAgbWVzc2FnZVJlcXVlc3RUb0NvbW1lcmNlTWVzc2FnZVJlcXVlc3QsXG4gIG1lc3NhZ2VGcm9tUmVzcG9uc2UsXG4gIG1lc3NhZ2VGcm9tUXVlcnlFdmVudCxcbiAgbWVzc2FnZUZyb21TdWdnZXN0aW9uRXZlbnQsXG4gIG1lc3NhZ2VGcm9tRm9ybVN1Ym1pdHRlZEV2ZW50LFxuICBjb3JlU3VwcG9ydGVkRXZlbnRSZXF1ZXN0VG9BcGlSZXF1ZXN0LFxufSBmcm9tIFwiLi91dGlsc1wiO1xuXG5hc3luYyBmdW5jdGlvbiBlcnJvclJlc3BvbnNlQm9keShlcnJvcjogUmVzcG9uc2VFcnJvcikge1xuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCBlcnJvci5yZXNwb25zZS5qc29uKCk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiB7fTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiB0aHJvd1Nlc3Npb25SZXN0YXJ0UmVxdWlyZWRJZihlcnJvck1zZzogc3RyaW5nLCBlcnJvcjogdW5rbm93bikge1xuICBpZiAoIShlcnJvciBpbnN0YW5jZW9mIFJlc3BvbnNlRXJyb3IpKSB7XG4gICAgTG9nZ2VyLmxvZ0luZm8oZXJyb3JNc2csIGVycm9yKTtcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxuXG4gIGNvbnN0IGVycm9yUmVzcG9uc2UgPSBhd2FpdCBlcnJvclJlc3BvbnNlQm9keShlcnJvcik7XG4gIGlmIChcbiAgICBlcnJvclJlc3BvbnNlPy5tZXNzYWdlPy50b0xvd2VyQ2FzZSgpID09PSBcInVuc3VwcG9ydGVkIHByb2R1Y3RcIiB8fCAvLyBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eS4gbmV3ZXIgdmVyc2lvbnMgb2YgdGhlIEFQSSByZXR1cm4gc3ViX2NvZGUgaW5zdGVhZCBvZiBtZXNzYWdlXG4gICAgZXJyb3JSZXNwb25zZT8uYXBwX2NvZGU/LnRvVXBwZXJDYXNlKCkgPT09IFwiUFJPRFVDVF9OT1RfRk9VTkRcIlxuICApIHtcbiAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRQcm9kdWN0RXhjZXB0aW9uKCk7XG4gIH0gZWxzZSBpZiAoXG4gICAgZXJyb3JSZXNwb25zZT8uYXBwX2NvZGU/LnRvVXBwZXJDYXNlKCkgPT09IFwiUkVTVEFSVF9TRVNTSU9OXCIgfHxcbiAgICBlcnJvclJlc3BvbnNlPy5zdWJfY29kZT8udG9VcHBlckNhc2UoKSA9PT0gXCJOT1RfRk9VTkRcIiAvLyBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eS4gbmV3IEFQSSByZXNwb25zZXMgd2lsbCBjb250YWluIFwiYXBwX2NvZGVcIlxuICApIHtcbiAgICBMb2dnZXIubG9nSW5mbyhcbiAgICAgIFwiU2Vzc2lvbiBkb2VzIG5vdCBleGlzdC4gUmUtc3RhcnQgc2Vzc2lvblwiLFxuICAgICAgZXJyb3IsXG4gICAgICBlcnJvci5yZXNwb25zZSxcbiAgICAgIGVycm9yUmVzcG9uc2VcbiAgICApO1xuICAgIHRocm93IG5ldyBTZXNzaW9uUmVzdGFydFJlcXVpcmVkKCk7XG4gIH1cblxuICBMb2dnZXIubG9nSW5mbyhlcnJvck1zZywgZXJyb3IpO1xuICB0aHJvdyBlcnJvcjtcbn1cblxuY2xhc3MgQ29tbWVyY2VBcGlDbGllbnQge1xuICBwcml2YXRlIHJlYWRvbmx5IGRlZmF1bHRBcGk6IERlZmF1bHRBcGk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBjdXN0b21lclNlcnZpY2VBcGk6IEN1c3RvbWVyU2VydmljZUFwaTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGluZmVyZW5jZUFwaTogSW5mZXJlbmNlQXBpO1xuXG4gIHByaXZhdGUgc3RhdGljIGluc3RhbmNlOiBDb21tZXJjZUFwaUNsaWVudCB8IHVuZGVmaW5lZDtcblxuICBwcml2YXRlIHN1Z2dlc3Rpb25zQWJvcnRDb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuXG4gIHByaXZhdGUgcmVzcG9uc2VzQWJvcnRDb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuXG4gIHByaXZhdGUgc3RhdGljIGdldEluc3RhbmNlID0gKCk6IENvbW1lcmNlQXBpQ2xpZW50ID0+IHtcbiAgICBpZiAoIUNvbW1lcmNlQXBpQ2xpZW50Lmluc3RhbmNlKSB7XG4gICAgICBDb21tZXJjZUFwaUNsaWVudC5pbnN0YW5jZSA9IG5ldyBDb21tZXJjZUFwaUNsaWVudCgpO1xuICAgIH1cblxuICAgIHJldHVybiBDb21tZXJjZUFwaUNsaWVudC5pbnN0YW5jZTtcbiAgfTtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKGJhc2VQYXRoPzogc3RyaW5nKSB7XG4gICAgY29uc3QgYXRvbVN0b3JlID0gZ2V0QXRvbVN0b3JlKCk7XG4gICAgY29uc3QgYmFzZVVybCA9IGF0b21TdG9yZS5nZXQoYmFzZVVybEF0b20pO1xuICAgIGNvbnN0IHBhdGggPSBiYXNlUGF0aCB8fCBiYXNlVXJsO1xuICAgIC8vIEFQSSBLZXkgaXMgbm93IGhhbmRsZWQgYXQgdGhlIEVudml2ZUNvbmZpZ1Byb3ZpZGVyIGxldmVsXG4gICAgY29uc3QgY29uZmlnOiBDb25maWd1cmF0aW9uID0gbmV3IENvbmZpZ3VyYXRpb24oe1xuICAgICAgYmFzZVBhdGg6IHBhdGgsXG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgIFwiQ29udGVudC1UeXBlXCI6IFwiYXBwbGljYXRpb24vanNvblwiLFxuICAgICAgICBBY2NlcHQ6IFwiYXBwbGljYXRpb24vanNvblwiLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICB0aGlzLmRlZmF1bHRBcGkgPSBuZXcgRGVmYXVsdEFwaShjb25maWcpO1xuICAgIHRoaXMuaW5mZXJlbmNlQXBpID0gbmV3IEluZmVyZW5jZUFwaShjb25maWcpO1xuICAgIHRoaXMuY3VzdG9tZXJTZXJ2aWNlQXBpID0gbmV3IEN1c3RvbWVyU2VydmljZUFwaShjb25maWcpO1xuICB9XG5cbiAgc3RhdGljIHJlc29sdmVVcmwgPSBhc3luYyAodXJsOiBzdHJpbmcpID0+IHtcbiAgICBjb25zdCBhdG9tU3RvcmUgPSBnZXRBdG9tU3RvcmUoKTtcbiAgICBjb25zdCBvcmdTaG9ydE5hbWUgPSBhdG9tU3RvcmUuZ2V0KG9yZ1Nob3J0TmFtZUF0b20pO1xuICAgIGNvbnN0IG9yZ0lkID0gYXRvbVN0b3JlLmdldChvcmdJZEF0b20pO1xuICAgIGNvbnN0IHVzZXJJZCA9IGF0b21TdG9yZS5nZXQodXNlcklkQXRvbSk7XG4gICAgY29uc3QgY2hhdElkID0gYXRvbVN0b3JlLmdldChjaGF0SWRBdG9tKTtcbiAgICBjb25zdCBzb3VyY2UgPSBhdG9tU3RvcmUuZ2V0KGNvbnRleHRTb3VyY2VBdG9tKTtcbiAgICBjb25zdCBlbnYgPSBhdG9tU3RvcmUuZ2V0KGVudkF0b20pO1xuXG4gICAgY29uc3QgZmVhdHVyZUZsYWdTZXJ2aWNlID0gYXRvbVN0b3JlLmdldChmZWF0dXJlRmxhZ1NlcnZpY2VBdG9tKTtcblxuICAgIGNvbnN0IGNvbnRleHQ6IENvbnRleHQgPSB7XG4gICAgICB1c2VyX2lkOiB1c2VySWQgPz8gXCJcIixcbiAgICAgIG9yZ19pZDogb3JnSWQgPz8gXCJcIixcbiAgICAgIG9yZ19zaG9ydF9uYW1lOiBvcmdTaG9ydE5hbWUgPz8gXCJcIixcbiAgICAgIGNoYXRfaWQ6IGNoYXRJZCA/PyBcIlwiLFxuICAgICAgc291cmNlOiBzb3VyY2UgPz8gQ29udGV4dFNvdXJjZUVudW0uQXBwLFxuICAgICAgZW52OiAoZW52IGFzIENvbnRleHRFbnZFbnVtKSA/PyBDb250ZXh0RW52RW51bS5EZXYsIC8vIENhc3QgZW52IHRvIENvbnRleHRFbnZFbnVtXG4gICAgfTtcblxuICAgIGNvbnN0IGZlYXR1cmVHYXRlcyA9XG4gICAgICBmZWF0dXJlRmxhZ1NlcnZpY2U/LmZlYXR1cmVGbGFnU2VydmljZT8uZ2V0RmVhdHVyZUZsYWdzKCkgfHwge307XG4gICAgY29uc3QgdXJsUmVzb2x2aW5nUmVxdWVzdCA9IHtcbiAgICAgIHVybCxcbiAgICAgIGNvbnRleHQsXG4gICAgICBmZWF0dXJlX2dhdGVzOiBmZWF0dXJlR2F0ZXMsXG4gICAgfTtcblxuICAgIGNvbnN0IHJhd1Jlc3BvbnNlID1cbiAgICAgIGF3YWl0IENvbW1lcmNlQXBpQ2xpZW50LmdldEluc3RhbmNlKCkuaW5mZXJlbmNlQXBpLnYxVXJsUmVzb2x2aW5nUG9zdFJhdyh7XG4gICAgICAgIFVybFJlc29sdmluZ1JlcXVlc3Q6IHVybFJlc29sdmluZ1JlcXVlc3QsXG4gICAgICB9KTtcblxuICAgIGNvbnN0IHJlc3BvbnNlQm9keSA9IGF3YWl0IHJhd1Jlc3BvbnNlLnJhdy5qc29uKCk7XG5cbiAgICByZXR1cm4gcmVzcG9uc2VCb2R5O1xuICB9O1xuXG4gIHN0YXRpYyByZXBvcnRTZXNzaW9uID0gYXN5bmMgKFxuICAgIHJlcG9ydFJlcXVlc3Q6IFJlcG9ydFNlc3Npb25SZXF1ZXN0XG4gICk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGF3YWl0IENvbW1lcmNlQXBpQ2xpZW50LmdldEluc3RhbmNlKCkuZGVmYXVsdEFwaS52MUNoYXRzUmVwb3J0U2Vzc2lvbklkUG9zdChcbiAgICAgIHtcbiAgICAgICAgUmVwb3J0U2Vzc2lvblJlcXVlc3Q6IHJlcG9ydFJlcXVlc3QsXG4gICAgICB9XG4gICAgKTtcbiAgfTtcblxuICBzdGF0aWMgZ2V0TmV4dFJlc3BvbnNlcyA9IGFzeW5jIChcbiAgICBwYXlsb2FkOiBOZXh0TWVzc2FnZVJlcXVlc3RcbiAgKTogUHJvbWlzZTxNZXNzYWdlW10+ID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPVxuICAgICAgICBhd2FpdCBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLmluZmVyZW5jZUFwaS52MU5leHRSZXNwb25zZXNQb3N0KHtcbiAgICAgICAgICBOZXh0TWVzc2FnZVJlcXVlc3Q6IG1lc3NhZ2VSZXF1ZXN0VG9Db21tZXJjZU1lc3NhZ2VSZXF1ZXN0KHBheWxvYWQpLFxuICAgICAgICB9KTtcbiAgICAgIGNvbnN0IG1lc3NhZ2VzID0gcmVzcG9uc2VcbiAgICAgICAgLm1hcCgocmVzcCkgPT4gdmFsaWRhdGVSZXNwb25zZShyZXNwKSlcbiAgICAgICAgLm1hcCgocmVzcCkgPT4gbWVzc2FnZUZyb21SZXNwb25zZShyZXNwKSk7XG5cbiAgICAgIHJldHVybiBtZXNzYWdlcy5maWx0ZXIoKG0pOiBtIGlzIE1lc3NhZ2UgPT4gbSAhPSBudWxsKTtcbiAgICB9IGNhdGNoIChlcnI6IHVua25vd24pIHtcbiAgICAgIExvZ2dlci5sb2dJbmZvKFwiRmFpbGVkIHRvIGdldCBuZXh0IHJlc3BvbnNlc1wiLCBlcnIsIHtcbiAgICAgICAgcGF5bG9hZENvbnRleHQ6IHBheWxvYWQ/LmNvbnRleHQsXG4gICAgICAgIHVzZXJFdmVudHM6IHBheWxvYWQ/LnVzZXJFdmVudHMsXG4gICAgICB9KTtcbiAgICAgIGF3YWl0IHRocm93U2Vzc2lvblJlc3RhcnRSZXF1aXJlZElmKFwiRmFpbGVkIHRvIGdldCBuZXh0IHJlc3BvbnNlc1wiLCBlcnIpO1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgfTtcblxuICBzdGF0aWMgZ2V0TmV4dFJlc3BvbnNlU3RyZWFtaW5nID0gKFxuICAgIHBheWxvYWQ6IE5leHRNZXNzYWdlUmVxdWVzdFxuICApOiBBc3luY0dlbmVyYXRvcjxBcGlSZXNwb25zZSwgdm9pZCwgdW5rbm93bj4gPT4ge1xuICAgIGFzeW5jIGZ1bmN0aW9uKiBnZW5lcmF0ZShcbiAgICAgIGluZmVyZW5jZUFwaTogSW5mZXJlbmNlQXBpLFxuICAgICAgYWJvcnRDb250cm9sbGVyOiBBYm9ydENvbnRyb2xsZXJcbiAgICApIHtcbiAgICAgIC8vIG1ha2Ugc3VyZSBzdHJlYW1pbmcgaXMgZW5hYmxlZFxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBpbmZlcmVuY2VBcGkudjFOZXh0UmVzcG9uc2VzUG9zdFJhdyhcbiAgICAgICAgICB7XG4gICAgICAgICAgICBOZXh0TWVzc2FnZVJlcXVlc3Q6IG1lc3NhZ2VSZXF1ZXN0VG9Db21tZXJjZU1lc3NhZ2VSZXF1ZXN0KHBheWxvYWQpLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgeyBzaWduYWw6IGFib3J0Q29udHJvbGxlci5zaWduYWwgfVxuICAgICAgICApO1xuXG4gICAgICAgIC8vIFJlYWQgdGhlIHJlc3BvbnNlIGFzIGEgc3RyZWFtIG9mIGRhdGFcbiAgICAgICAgaWYgKCFyZXNwb25zZS5yYXcuYm9keSkge1xuICAgICAgICAgIExvZ2dlci5sb2dFcnJvcihcbiAgICAgICAgICAgIFwiW3NwaWZmeS1haV0gTm8gYm9keSBpbiB0aGUgc3RyZWFtZWQgcmVzcG9uc2VcIixcbiAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgcmVzcG9uc2U6IHJlc3BvbnNlLnJhdyxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlYWRlciA9IHJlc3BvbnNlLnJhdy5ib2R5LmdldFJlYWRlcigpO1xuICAgICAgICBjb25zdCBkZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKFwidXRmLThcIik7XG5cbiAgICAgICAgbGV0IHBhcnRpYWwgPSBcIlwiO1xuICAgICAgICAvLyBUT0RPIHRoaXMgZnVuY3Rpb24gaXMgcmVjcmVhdGVkIGV2ZXJ5IHRpbWUgbmV3IGRhdGEgY29tZXMgZnJvbSB0aGUgc3RyZWFtIC0gZGVmaW5lIGl0IG91dHNpZGUgb2YgdGhlIGdlbmVyYXRvclxuICAgICAgICBjb25zdCBzYWZlUGFyc2UgPSAobGluZTogc3RyaW5nKTogdW5rbm93biA9PiB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBKU09OLnBhcnNlKGxpbmUpOyAvLyBQYXJzZSB0aGUgSlNPTiBzdHJpbmdcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIExvZ2dlci5sb2dFcnJvcihcIltzcGlmZnktYWldIEVycm9yIHBhcnNpbmcgc3RyZWFtZWQgbGluZVwiLCBlcnIsIHtcbiAgICAgICAgICAgICAgbGluZSxcbiAgICAgICAgICAgICAgcGFydGlhbCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLy8gc3dhbGxvdyB0aGUgZXJyb3IgYW5kIHNldCB0aGUgcGFydGlhbCB0byBvdXIgY3VycmVudCBjaHVua1xuICAgICAgICAgICAgcGFydGlhbCA9IGxpbmU7XG4gICAgICAgICAgICByZXR1cm4gcGFydGlhbDtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gVE9ETyB0aGlzIGZ1bmN0aW9uIGlzIHJlY3JlYXRlZCBldmVyeSB0aW1lIG5ldyBkYXRhIGNvbWVzIGZyb20gdGhlIHN0cmVhbSAtIGRlZmluZSBpdCBvdXRzaWRlIG9mIHRoZSBnZW5lcmF0b3JcbiAgICAgICAgY29uc3QgcHJvY2Vzc0NodW5rID0gKGNodW5rOiBzdHJpbmcpOiB1bmtub3duW10gPT4ge1xuICAgICAgICAgIC8vIG1lcmdlIHRoZSBwYXJ0aWFsIHdpdGggdGhlIGluY29taW5nIGNodW5rXG4gICAgICAgICAgY29uc3QgbGluZXMgPSBgJHtwYXJ0aWFsfSR7Y2h1bmt9YC5zcGxpdChcIlxcblwiKTtcblxuICAgICAgICAgIGNvbnN0IHBhcnNlZExpbmVzID0gbGluZXNcbiAgICAgICAgICAgIC5tYXAoKGxpbmUpID0+IGxpbmUucmVwbGFjZSgvXmRhdGE6IC8sIFwiXCIpLnRyaW0oKSkgLy8gUmVtb3ZlIHRoZSBcImRhdGE6IFwiIHByZWZpeFxuICAgICAgICAgICAgLmZpbHRlcigobGluZSkgPT4gbGluZSAhPT0gXCJcIiAmJiBsaW5lICE9PSBcIltET05FXVwiKSAvLyBSZW1vdmUgZW1wdHkgbGluZXMgYW5kIFwiW0RPTkVdXCJcbiAgICAgICAgICAgIC5tYXAoc2FmZVBhcnNlKVxuICAgICAgICAgICAgLmZpbHRlcigodikgPT4gdik7IC8vIGFuZCBmaWx0ZXIgb3V0IHRoZSB1bmRlZmluZWQgdmFsdWVzXG4gICAgICAgICAgcmV0dXJuIHBhcnNlZExpbmVzO1xuICAgICAgICB9O1xuXG4gICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWF3YWl0LWluLWxvb3BcbiAgICAgICAgICBjb25zdCB7IGRvbmUsIHZhbHVlIH0gPSBhd2FpdCByZWFkZXIucmVhZCgpO1xuXG4gICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIE1hc3NhZ2UgYW5kIHBhcnNlIHRoZSBjaHVuayBvZiBkYXRhXG4gICAgICAgICAgY29uc3QgY2h1bmsgPSBkZWNvZGVyLmRlY29kZSh2YWx1ZSk7XG4gICAgICAgICAgY29uc3QgcGFyc2VkTGluZXMgPSBwcm9jZXNzQ2h1bmsoY2h1bmspO1xuXG4gICAgICAgICAgZm9yIChjb25zdCBwYXJzZWRMaW5lIG9mIHBhcnNlZExpbmVzKSB7XG4gICAgICAgICAgICBjb25zdCB2YWxpZGF0ZWRSZXNwb25zZSA9IHZhbGlkYXRlUmVzcG9uc2UocGFyc2VkTGluZSk7XG5cbiAgICAgICAgICAgIGlmICh2YWxpZGF0ZWRSZXNwb25zZSkge1xuICAgICAgICAgICAgICB5aWVsZCB2YWxpZGF0ZWRSZXNwb25zZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAgIExvZ2dlci5sb2dFcnJvcihcbiAgICAgICAgICBcIltzcGlmZnktYWldIEZhaWxlZCB0byBnZXQgbmV4dCBzdHJlYW1pbmcgcmVzcG9uc2VzXCIsXG4gICAgICAgICAgZXJyb3IsXG4gICAgICAgICAge1xuICAgICAgICAgICAgcGF5bG9hZENvbnRleHQ6IHBheWxvYWQ/LmNvbnRleHQsXG4gICAgICAgICAgICB1c2VyRXZlbnRzOiBwYXlsb2FkPy51c2VyRXZlbnRzLFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgICAgYXdhaXQgdGhyb3dTZXNzaW9uUmVzdGFydFJlcXVpcmVkSWYoXG4gICAgICAgICAgXCJGYWlsZWQgdG8gZ2V0IG5leHQgc3RyZWFtaW5nIHJlc3BvbnNlc1wiLFxuICAgICAgICAgIGVycm9yXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5yZXNwb25zZXNBYm9ydENvbnRyb2xsZXIuYWJvcnQoKTtcbiAgICBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLnJlc3BvbnNlc0Fib3J0Q29udHJvbGxlciA9XG4gICAgICBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG5cbiAgICByZXR1cm4gZ2VuZXJhdGUoXG4gICAgICBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLmluZmVyZW5jZUFwaSxcbiAgICAgIENvbW1lcmNlQXBpQ2xpZW50LmdldEluc3RhbmNlKCkucmVzcG9uc2VzQWJvcnRDb250cm9sbGVyXG4gICAgKTtcbiAgfTtcblxuICBzdGF0aWMgZ2V0TmV4dFN1Z2dlc3Rpb25zID0gYXN5bmMgKFxuICAgIHBheWxvYWQ6IE5leHRNZXNzYWdlUmVxdWVzdFxuICApOiBQcm9taXNlPFN1Z2dlc3Rpb25bXT4gPT4ge1xuICAgIHRyeSB7XG4gICAgICBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLnN1Z2dlc3Rpb25zQWJvcnRDb250cm9sbGVyLmFib3J0KCk7XG4gICAgICBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLnN1Z2dlc3Rpb25zQWJvcnRDb250cm9sbGVyID1cbiAgICAgICAgbmV3IEFib3J0Q29udHJvbGxlcigpO1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9XG4gICAgICAgIGF3YWl0IENvbW1lcmNlQXBpQ2xpZW50LmdldEluc3RhbmNlKCkuaW5mZXJlbmNlQXBpLnYxTmV4dFN1Z2dlc3Rpb25zUG9zdChcbiAgICAgICAgICB7XG4gICAgICAgICAgICBOZXh0TWVzc2FnZVJlcXVlc3Q6IG1lc3NhZ2VSZXF1ZXN0VG9Db21tZXJjZU1lc3NhZ2VSZXF1ZXN0KHBheWxvYWQpLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgc2lnbmFsOlxuICAgICAgICAgICAgICBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLnN1Z2dlc3Rpb25zQWJvcnRDb250cm9sbGVyLnNpZ25hbCxcbiAgICAgICAgICB9XG4gICAgICAgICk7XG5cbiAgICAgIGNvbnN0IHN1Z2dlc3Rpb25zID0gcmVzcG9uc2VcbiAgICAgICAgLm1hcCgocmVzcCkgPT4gdmFsaWRhdGVTdWdnZXN0aW9uKHJlc3ApKVxuICAgICAgICAuZmlsdGVyKChzdWdnZXN0aW9uKTogc3VnZ2VzdGlvbiBpcyBTdWdnZXN0aW9uID0+IHN1Z2dlc3Rpb24gIT0gbnVsbCk7XG5cbiAgICAgIHJldHVybiBzdWdnZXN0aW9ucztcbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgTG9nZ2VyLmxvZ0luZm8oXCJGYWlsZWQgdG8gZ2V0IHN1Z2dlc3Rpb25zXCIsIGVycm9yLCB7XG4gICAgICAgIHBheWxvYWRDb250ZXh0OiBwYXlsb2FkPy5jb250ZXh0LFxuICAgICAgICB1c2VyRXZlbnRzOiBwYXlsb2FkPy51c2VyRXZlbnRzLFxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IHRocm93U2Vzc2lvblJlc3RhcnRSZXF1aXJlZElmKFwiRmFpbGVkIHRvIGdldCBzdWdnZXN0aW9uc1wiLCBlcnJvcik7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBGZXRjaGVzIHRoZSBleGlzdGluZyBjaGF0IGRhdGEgZm9yIGEgZ2l2ZW4gc2Vzc2lvbiBhbmQgdHJhbnNmb3JtcyB0aGVtIHRvIHJlY29uc3RydWN0IHRoZSBjaGF0IGhpc3RvcnkuXG4gICAqXG4gICAqIEBwYXJhbSBvcmdJZCBUaGUgb3JnYW5pemF0aW9uIElkXG4gICAqIEBwYXJhbSBjaGF0SWQgVGhlIGV4aXN0aW5nIGNoYXQgSWRcbiAgICogQHBhcmFtIHVzZXJJZCBUaGUgdXNlciBJZFxuICAgKlxuICAgKiBAcmV0dXJucyBBIGxpc3Qgb2YgbWVzc2FnZXMgdGhhdCB3ZXJlIGV4Y2hhbmdlZCBpbiB0aGUgY2hhdCwgdGhyb3dzIGFuIGVycm9yIGlmIHRoZSBjaGF0IHNlc3Npb24gaGFzIGV4cGlyZWQuXG4gICAqL1xuICBzdGF0aWMgZ2V0UmVzcG9uc2VzID0gYXN5bmMgKFxuICAgIG9yZ0lkOiBzdHJpbmcsXG4gICAgY2hhdElkOiBzdHJpbmcsXG4gICAgdXNlcklkOiBzdHJpbmdcbiAgKTogUHJvbWlzZTx7XG4gICAgcmVzcG9uc2VzOiBBcGlSZXNwb25zZVtdW107XG4gICAgdXNlckV2ZW50czogVXNlckV2ZW50W107XG4gICAgc3VnZ2VzdGlvbnM6IFN1Z2dlc3Rpb25bXTtcbiAgICBtZXNzYWdlczogTWVzc2FnZVtdW107XG4gIH0+ID0+IHtcbiAgICBsZXQgZGF0YTogVjFHZXRTZXNzaW9uTWVzc2FnZXMyMDBSZXNwb25zZSA9IHtcbiAgICAgIHJlc3BvbnNlczogW10sXG4gICAgICBzdWdnZXN0aW9uczogW10sXG4gICAgICB1c2VyX2V2ZW50czogW10sXG4gICAgfTtcbiAgICBjb25zdCByZXF1ZXN0ID0ge1xuICAgICAgb3JnX2lkOiBvcmdJZCxcbiAgICAgIGNoYXRfaWQ6IGNoYXRJZCxcbiAgICAgIHVzZXJfaWQ6IHVzZXJJZCxcbiAgICB9O1xuICAgIHRyeSB7XG4gICAgICBkYXRhID1cbiAgICAgICAgYXdhaXQgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5kZWZhdWx0QXBpLnYxR2V0U2Vzc2lvbk1lc3NhZ2VzKFxuICAgICAgICAgIHJlcXVlc3RcbiAgICAgICAgKTtcbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgYXdhaXQgdGhyb3dTZXNzaW9uUmVzdGFydFJlcXVpcmVkSWYoXG4gICAgICAgIFwiRmFpbGVkIHRvIGdldCBjaGF0IHJlc3BvbnNlc1wiLFxuICAgICAgICBlcnJvclxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCByZXNwb25zZXM6IEFwaVJlc3BvbnNlW11bXSA9IGRhdGE/LnJlc3BvbnNlcz8ubWFwKCh0dXJuKSA9PlxuICAgICAgdHVyblxuICAgICAgICAubWFwKChyZXNwb25zZSkgPT4gdmFsaWRhdGVSZXNwb25zZShyZXNwb25zZSkpXG4gICAgICAgIC5maWx0ZXIoKHJlc3BvbnNlKTogcmVzcG9uc2UgaXMgQXBpUmVzcG9uc2UgPT4gcmVzcG9uc2UgIT0gbnVsbClcbiAgICApO1xuXG4gICAgY29uc3Qgc3VnZ2VzdGlvbnM6IFN1Z2dlc3Rpb25bXSA9IGRhdGE/LnN1Z2dlc3Rpb25zXG4gICAgICAubWFwKChzdWdnZXN0aW9uKSA9PiB2YWxpZGF0ZVN1Z2dlc3Rpb24oc3VnZ2VzdGlvbikpXG4gICAgICAuZmlsdGVyKChzdWdnZXN0aW9uKTogc3VnZ2VzdGlvbiBpcyBTdWdnZXN0aW9uID0+IHN1Z2dlc3Rpb24gIT0gbnVsbCk7XG5cbiAgICBjb25zdCB1c2VyRXZlbnRzOiBVc2VyRXZlbnRbXSA9IGRhdGE/LnVzZXJfZXZlbnRzXG4gICAgICAubWFwKChldmVudCkgPT4gdmFsaWRhdGVVc2VyRXZlbnQoZXZlbnQpKVxuICAgICAgLmZpbHRlcigoZXZlbnQpOiBldmVudCBpcyBVc2VyRXZlbnQgPT4gZXZlbnQgIT0gbnVsbCk7XG5cbiAgICAvLyBpZiBhIGZvcm0gaGFzIGFscmVhZHkgYmVlbiBzdWJtaXR0ZWQsIGRvbid0IHNob3cgaXQgaW4gdGhlIGNoYXQgaGlzdG9yeVxuICAgIGNvbnN0IGZvcm1TdWJtaXR0ZWRVc2VyRXZlbnRzRm9ybUlkcyA9IHVzZXJFdmVudHNcbiAgICAgIC5maWx0ZXIoKGV2ZW50KSA9PiBldmVudC5jYXRlZ29yeSA9PT0gVXNlckV2ZW50Q2F0ZWdvcnkuRm9ybVN1Ym1pdHRlZClcbiAgICAgIC5tYXAoKGV2ZW50KSA9PiBldmVudC5hdHRyaWJ1dGVzLmZvcm1SZXNwb25zZUlkKTtcblxuICAgIGNvbnN0IGFzc2lzdGFudE1lc3NhZ2VzOiBNZXNzYWdlW11bXSA9IHJlc3BvbnNlc1xuICAgICAgLm1hcCgodHVybikgPT5cbiAgICAgICAgdHVyblxuICAgICAgICAgIC5maWx0ZXIoXG4gICAgICAgICAgICAocmVzcG9uc2UpID0+XG4gICAgICAgICAgICAgICEoXG4gICAgICAgICAgICAgICAgcmVzcG9uc2UuY2F0ZWdvcnkgPT09IFJlc3BvbnNlQ2F0ZWdvcnkuRm9ybSAmJlxuICAgICAgICAgICAgICAgIGZvcm1TdWJtaXR0ZWRVc2VyRXZlbnRzRm9ybUlkcy5pbmNsdWRlcyhyZXNwb25zZS5pZClcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgIClcbiAgICAgICAgICAubWFwKChyZXNwb25zZSkgPT4gbWVzc2FnZUZyb21SZXNwb25zZShyZXNwb25zZSkpXG4gICAgICAgICAgLmZpbHRlcigobWVzc2FnZSk6IG1lc3NhZ2UgaXMgTWVzc2FnZSA9PiBtZXNzYWdlICE9IG51bGwpXG4gICAgICApXG4gICAgICAuZmlsdGVyKCh0dXJuKSA9PiB0dXJuLmxlbmd0aCA+IDApO1xuXG4gICAgY29uc3QgdXNlck1lc3NhZ2VzOiBNZXNzYWdlW11bXSA9IHVzZXJFdmVudHNcbiAgICAgIC5tYXAoKGV2ZW50KSA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBbVXNlckV2ZW50Q2F0ZWdvcnkuUXVlcnlUeXBlZCwgVXNlckV2ZW50Q2F0ZWdvcnkuU2VhcmNoXS5pbmNsdWRlcyhcbiAgICAgICAgICAgIGV2ZW50LmNhdGVnb3J5XG4gICAgICAgICAgKVxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm4gW21lc3NhZ2VGcm9tUXVlcnlFdmVudChldmVudCldO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGV2ZW50LmNhdGVnb3J5ID09PSBVc2VyRXZlbnRDYXRlZ29yeS5TdWdnZXN0aW9uQ2xpY2tlZCkge1xuICAgICAgICAgIHJldHVybiBbbWVzc2FnZUZyb21TdWdnZXN0aW9uRXZlbnQoZXZlbnQsIHN1Z2dlc3Rpb25zKV07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXZlbnQuY2F0ZWdvcnkgPT09IFVzZXJFdmVudENhdGVnb3J5LkZvcm1TdWJtaXR0ZWQpIHtcbiAgICAgICAgICBjb25zdCBmb3JtUmVzcG9uc2UgPSByZXNwb25zZXNcbiAgICAgICAgICAgIC5mbGF0KClcbiAgICAgICAgICAgIC5maW5kKFxuICAgICAgICAgICAgICAocmVzcG9uc2UpID0+XG4gICAgICAgICAgICAgICAgcmVzcG9uc2UuaWQgPT09IGV2ZW50LmF0dHJpYnV0ZXMuZm9ybVJlc3BvbnNlSWQgJiZcbiAgICAgICAgICAgICAgICBldmVudC5hdHRyaWJ1dGVzLmZvcm1UeXBlICE9PSBGb3JtVHlwZS5Fc2NhbGF0aW9uXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKGZvcm1SZXNwb25zZSAmJiBmb3JtUmVzcG9uc2UuY2F0ZWdvcnkgPT09IFJlc3BvbnNlQ2F0ZWdvcnkuRm9ybSkge1xuICAgICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgICAgbWVzc2FnZUZyb21Gb3JtU3VibWl0dGVkRXZlbnQoZXZlbnQsIGZvcm1SZXNwb25zZS5hdHRyaWJ1dGVzKSxcbiAgICAgICAgICAgIF07XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfSlcbiAgICAgIC5maWx0ZXIoKG1lc3NhZ2UpOiBtZXNzYWdlIGlzIE1lc3NhZ2VbXSA9PiBtZXNzYWdlLmxlbmd0aCA+IDApO1xuXG4gICAgLy8gU29ydCB0aGUgbWVzc2FnZXMgY2hyb25vbG9naWNhbGx5IHRvIHJlY29uc3RydWN0IHRoZSBjaGF0IGhpc3RvcnlcbiAgICBjb25zdCBzb3J0ZWRNZXNzYWdlcyA9IFsuLi5hc3Npc3RhbnRNZXNzYWdlcywgLi4udXNlck1lc3NhZ2VzXS5zb3J0KFxuICAgICAgKGEsIGIpID0+XG4gICAgICAgIG5ldyBEYXRlKGFbMF0uY3JlYXRlZEF0KS5nZXRUaW1lKCkgLSBuZXcgRGF0ZShiWzBdLmNyZWF0ZWRBdCkuZ2V0VGltZSgpXG4gICAgKTtcblxuICAgIHJldHVybiB7IHJlc3BvbnNlcywgdXNlckV2ZW50cywgc3VnZ2VzdGlvbnMsIG1lc3NhZ2VzOiBzb3J0ZWRNZXNzYWdlcyB9O1xuICB9O1xuXG4gIC8qKlxuICAgKlxuICAgKiBAcGFyYW0gcGF5bG9hZFxuICAgKiBAcmV0dXJuc1xuICAgKi9cbiAgc3RhdGljIGlzU3VwcG9ydGVkRXZlbnQgPSBhc3luYyAoXG4gICAgcGF5bG9hZDogU3VwcG9ydGVkRXZlbnRSZXF1ZXN0XG4gICk6IFByb21pc2U8U3VwcG9ydGVkRXZlbnQ+ID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmF3UmVzcG9uc2UgPVxuICAgICAgICBhd2FpdCBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLmluZmVyZW5jZUFwaS52MVN1cHBvcnRlZEV2ZW50UG9zdFJhdyhcbiAgICAgICAgICB7XG4gICAgICAgICAgICBTdXBwb3J0ZWRFdmVudFJlcXVlc3Q6XG4gICAgICAgICAgICAgIGNvcmVTdXBwb3J0ZWRFdmVudFJlcXVlc3RUb0FwaVJlcXVlc3QocGF5bG9hZCksXG4gICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAvLyBHZXQgdGhlIGFjdHVhbCBIVFRQIHJlc3BvbnNlIEpTT05cbiAgICAgIGNvbnN0IGh0dHBSZXNwb25zZVRleHQgPSBhd2FpdCByYXdSZXNwb25zZS5yYXcudGV4dCgpO1xuICAgICAgY29uc3QgaHR0cFJlc3BvbnNlSnNvbiA9IEpTT04ucGFyc2UoaHR0cFJlc3BvbnNlVGV4dCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLmh0dHBSZXNwb25zZUpzb24sXG4gICAgICAgIG51bWJlck9mUmV2aWV3czogaHR0cFJlc3BvbnNlSnNvbi5udW1fb2ZfcmV2aWV3cyxcbiAgICAgICAgbWVyY2hhbnRfdGFnczogaHR0cFJlc3BvbnNlSnNvbi5tZXJjaGFudF90YWdzIHx8IFtdLFxuICAgICAgfTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIExvZ2dlci5sb2dFcnJvcihcIkZhaWxlZCB0byBnZXQgcmVzcG9uc2UgZm9yIHYxU3VwcG9ydGVkRXZlbnRQb3N0XCIsIHtcbiAgICAgICAgZXJyLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdXBwb3J0ZWQ6IGZhbHNlLFxuICAgICAgICByZWFkeTogZmFsc2UsXG4gICAgICAgIGNhdGVnb3J5OiB1bmRlZmluZWQsXG4gICAgICAgIGNvbGxlY3Rpb25zOiBbXSxcbiAgICAgICAgbnVtYmVyT2ZSZXZpZXdzOiB1bmRlZmluZWQsXG4gICAgICAgIHRvcF9jYXRlZ29yeTogdW5kZWZpbmVkLFxuICAgICAgICBtZXJjaGFudF90YWdzOiBbXSxcbiAgICAgIH07XG4gICAgfVxuICB9O1xuXG4gIHN0YXRpYyBpZGVudGlmeVVzZXIgPSBhc3luYyAoXG4gICAgc3BpZmZ5VXNlcklkOiBzdHJpbmcsXG4gICAgbWVyY2hhbnRVc2VySWQ6IHN0cmluZyxcbiAgICB1YURldGFpbHM6IENsaWVudERldGFpbHNcbiAgKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IENvbW1lcmNlQXBpQ2xpZW50LmdldEluc3RhbmNlKCkuZGVmYXVsdEFwaS52MUFuYWx5dGljc0lkZW50aWZ5UG9zdCh7XG4gICAgICAgIEFuYWx5dGljc0lkZW50aWZ5UmVxdWVzdDoge1xuICAgICAgICAgIHVzZXJfaWQ6IHNwaWZmeVVzZXJJZCxcbiAgICAgICAgICBvc19uYW1lOiB1YURldGFpbHMub3MsXG4gICAgICAgICAgb3NfdmVyc2lvbjogdWFEZXRhaWxzLm9zVmVyc2lvbixcbiAgICAgICAgICBwbGF0Zm9ybTogdWFEZXRhaWxzLm9zLFxuICAgICAgICAgIGRldmljZV9pZDogdWFEZXRhaWxzLmRldmljZU1vZGVsLFxuICAgICAgICAgIGRldmljZV9icmFuZDogdWFEZXRhaWxzLmRldmljZUJyYW5kLFxuICAgICAgICAgIGRldmljZV9tYW51ZmFjdHVyZXI6IHVhRGV0YWlscy5kZXZpY2VNYW51ZmFjdHVyZXIsXG4gICAgICAgICAgZGV2aWNlX21vZGVsOiB1YURldGFpbHMuZGV2aWNlTW9kZWwsXG4gICAgICAgICAgdXNlcl9wcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICBjZHBfdXNlcl9pZDogbWVyY2hhbnRVc2VySWQsXG4gICAgICAgICAgICBicm93c2VyOiB1YURldGFpbHMuYnJvd3NlcixcbiAgICAgICAgICAgIGJyb3dzZXJfdmVyc2lvbjogdWFEZXRhaWxzLmJyb3dzZXJWZXJzaW9uLFxuICAgICAgICAgICAgdXNlcl9hZ2VudDogdWFEZXRhaWxzLnVzZXJBZ2VudCxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBMb2dnZXIubG9nRXJyb3IoXCJGYWlsZWQgdG8gaWRlbnRpZnkgdXNlclwiLCBlcnIpO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIHN0YXRpYyBtYXBDb250ZXh0U291cmNlVG9WMU9yZ0NvbmZpZ0dldFNvdXJjZSA9IChcbiAgICBzb3VyY2U6IENvbnRleHRTb3VyY2VFbnVtIHwgdW5kZWZpbmVkXG4gICk6IFYxT3JnQ29uZmlnR2V0U291cmNlRW51bSB8IHVuZGVmaW5lZCA9PiB7XG4gICAgaWYgKHNvdXJjZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIHN3aXRjaCAoc291cmNlKSB7XG4gICAgICBjYXNlIENvbnRleHRTb3VyY2VFbnVtLkZvcms6XG4gICAgICAgIHJldHVybiBWMU9yZ0NvbmZpZ0dldFNvdXJjZUVudW0uRm9yaztcbiAgICAgIGNhc2UgQ29udGV4dFNvdXJjZUVudW0uUGxheWdyb3VuZDpcbiAgICAgICAgcmV0dXJuIFYxT3JnQ29uZmlnR2V0U291cmNlRW51bS5QbGF5Z3JvdW5kO1xuICAgICAgY2FzZSBDb250ZXh0U291cmNlRW51bS5BcHA6XG4gICAgICAgIHJldHVybiBWMU9yZ0NvbmZpZ0dldFNvdXJjZUVudW0uQXBwO1xuICAgICAgY2FzZSBDb250ZXh0U291cmNlRW51bS5UZXN0OlxuICAgICAgICByZXR1cm4gVjFPcmdDb25maWdHZXRTb3VyY2VFbnVtLlRlc3Q7XG4gICAgICBkZWZhdWx0OiB7XG4gICAgICAgIC8vIFRoaXMgZW5zdXJlcyB0aGF0IGlmIG5ldyB2YWx1ZXMgYXJlIGFkZGVkIHRvIENvbnRleHRTb3VyY2VFbnVtLCB3ZSBjYXRjaCBpdFxuICAgICAgICBjb25zdCBleGhhdXN0aXZlQ2hlY2s6IG5ldmVyID0gc291cmNlO1xuICAgICAgICByZXR1cm4gZXhoYXVzdGl2ZUNoZWNrO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBzdGF0aWMgZ2V0T3JnQ29uZmlnID0gYXN5bmMgKFxuICAgIHVzZXJfaWQ6IHN0cmluZ1xuICApOiBQcm9taXNlPE9yZ0NvbmZpZyB8IHVuZGVmaW5lZD4gPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBhdG9tU3RvcmUgPSBnZXRBdG9tU3RvcmUoKTtcbiAgICAgIGNvbnN0IHJlYWN0QXBwTmFtZSA9IGF0b21TdG9yZS5nZXQocmVhY3RBcHBOYW1lQXRvbSk7XG4gICAgICBjb25zdCBjb250ZXh0U291cmNlID0gYXRvbVN0b3JlLmdldChjb250ZXh0U291cmNlQXRvbSk7XG4gICAgICBjb25zdCBmZWF0dXJlRmxhZ1NlcnZpY2UgPSBhdG9tU3RvcmUuZ2V0KGZlYXR1cmVGbGFnU2VydmljZUF0b20pOyAvLyBHZXQgZmVhdHVyZUZsYWdTZXJ2aWNlXG4gICAgICBjb25zdCByZXF1ZXN0OiBWMU9yZ0NvbmZpZ0dldFJlcXVlc3QgPSB7XG4gICAgICAgIG5hbWVzcGFjZTogcmVhY3RBcHBOYW1lLFxuICAgICAgICB1c2VyX2lkLFxuICAgICAgICBzb3VyY2U6IHRoaXMubWFwQ29udGV4dFNvdXJjZVRvVjFPcmdDb25maWdHZXRTb3VyY2UoY29udGV4dFNvdXJjZSksXG4gICAgICAgIGluY2x1ZGVfZXhwZXJpbWVudHM6IE9iamVjdC52YWx1ZXMoUHJvZHVjdEV4cGVyaW1lbnQpLFxuICAgICAgICBpbmNsdWRlX2ZlYXR1cmVfZ2F0ZXM6IE9iamVjdC5lbnRyaWVzKFxuICAgICAgICAgIGZlYXR1cmVGbGFnU2VydmljZT8uZmVhdHVyZUZsYWdTZXJ2aWNlPy5nZXRGZWF0dXJlRmxhZ3MoKSB8fCB7fVxuICAgICAgICApXG4gICAgICAgICAgLmZpbHRlcigoWywgaXNFbmFibGVkXSkgPT4gaXNFbmFibGVkKVxuICAgICAgICAgIC5tYXAoKFtmZWF0dXJlR2F0ZU5hbWVdKSA9PiBmZWF0dXJlR2F0ZU5hbWUpLCAvLyBVc2UgZmVhdHVyZUZsYWdTZXJ2aWNlXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVzcG9uc2UgPVxuICAgICAgICBhd2FpdCBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLmRlZmF1bHRBcGkudjFPcmdDb25maWdHZXQoXG4gICAgICAgICAgcmVxdWVzdFxuICAgICAgICApO1xuXG4gICAgICByZXR1cm4gdmFsaWRhdGVPcmdDb25maWdSZXN1bHRzKHJlc3BvbnNlKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIExvZ2dlci5sb2dFcnJvcihgRmFpbGVkIHRvIGdldCBvcmcgY29uZmlnYCwgZXJyLCB7IGVyciB9KTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9O1xuXG4gIHN0YXRpYyBhZGROb3RlVG9MYXRlc3RDb252ZXJzYXRpb24gPSBhc3luYyAoXG4gICAgc3BpZmZ5VXNlcklkOiBzdHJpbmcsXG4gICAgZW1haWw6IHN0cmluZyxcbiAgICBjdXN0b21lclNlcnZpY2VQcm92aWRlcjogQ3VzdG9tZXJTZXJ2aWNlUHJvdmlkZXJcbiAgKSA9PiB7XG4gICAgTG9nZ2VyLmxvZ0luZm8oXG4gICAgICBgYWRkTm90ZVRvTGF0ZXN0Q29udmVyc2F0aW9uIC0gdXNlcl9pZD0ke3NwaWZmeVVzZXJJZH0gZW1haWw9JHtlbWFpbH0gY3VzdG9tZXJfc2VydmljZV9wcm92aWRlcj0ke2N1c3RvbWVyU2VydmljZVByb3ZpZGVyfWBcbiAgICApO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLmN1c3RvbWVyU2VydmljZUFwaS52MUN1c3RzZXJ2aWNlQWRkTm90ZVRvTGF0ZXN0Q29udmVyc2F0aW9uUG9zdChcbiAgICAgICAge1xuICAgICAgICAgIEFkZE5vdGVUb0xhdGVzdENvbnZlcnNhdGlvblJlcXVlc3Q6IHtcbiAgICAgICAgICAgIHNwaWZmeV91c2VyX2lkOiBzcGlmZnlVc2VySWQsXG4gICAgICAgICAgICBlbWFpbCxcbiAgICAgICAgICAgIGN1c3RvbWVyX3NlcnZpY2VfcHJvdmlkZXI6IGN1c3RvbWVyU2VydmljZVByb3ZpZGVyLFxuICAgICAgICAgIH0sXG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBMb2dnZXIubG9nRXJyb3IoXCJGYWlsZWQgdG8gYWRkIG5vdGUgdG8gbGF0ZXN0IGNvbnZlcnNhdGlvblwiLCB7IGVyciB9KTtcbiAgICB9XG4gIH07XG5cbiAgc3RhdGljIGdldEN1c3RvbWVyU2VydmljZUFwaSA9ICgpID0+XG4gICAgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5jdXN0b21lclNlcnZpY2VBcGk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IENvbW1lcmNlQXBpQ2xpZW50O1xuIiwiaW1wb3J0IFJlYWN0LCB7IGNyZWF0ZUNvbnRleHQsIHVzZUNhbGxiYWNrLCB1c2VDb250ZXh0LCB1c2VNZW1vLCB1c2VTdGF0ZSwgdXNlRWZmZWN0IH0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IFVBUGFyc2VyIGZyb20gJ3VhLXBhcnNlci1qcyc7XG5pbXBvcnQgeyBDbGllbnREZXRhaWxzLCBVc2VySWRlbnRpdHlDb250ZXh0VHlwZSB9IGZyb20gJ0BlbnZpdmUtYWkvdHlwZXMnO1xuaW1wb3J0IExvZ2dlciBmcm9tICcuLi8uLi9hcHBsaWNhdGlvbi9sb2dnaW5nL2xvZ2dlcic7XG5pbXBvcnQgQ29tbWVyY2VBcGlDbGllbnQgZnJvbSAnLi4vLi4vYXBwbGljYXRpb24vY29tbWVyY2UtYXBpJztcbmltcG9ydCB7IHVzZUxvY2FsU3RvcmFnZSB9IGZyb20gJy4uL2xvY2FsU3RvcmFnZUNvbnRleHQnO1xuaW1wb3J0IHsgdjQgYXMgdXVpZCB9IGZyb20gJ3V1aWQnO1xuXG4vLyBIZWxwZXIgZnVuY3Rpb24gZnJvbSB0aGUgb3JpZ2luYWwgc2VydmljZVxuY29uc3QgZ2V0VXNlckFnZW50RGV0YWlscyA9ICgpOiBDbGllbnREZXRhaWxzID0+IHtcbiAgY29uc3QgdWFQYXJzZXIgPSBuZXcgVUFQYXJzZXIoKTtcbiAgY29uc3QgcmVzdWx0ID0gdWFQYXJzZXIuZ2V0UmVzdWx0KCk7XG5cbiAgcmV0dXJuIHtcbiAgICBvczogcmVzdWx0Py5vcz8ubmFtZSxcbiAgICBvc1ZlcnNpb246IHJlc3VsdD8ub3M/LnZlcnNpb24sXG4gICAgZGV2aWNlQnJhbmQ6IHJlc3VsdD8uZGV2aWNlPy52ZW5kb3IsXG4gICAgZGV2aWNlTWFudWZhY3R1cmVyOiByZXN1bHQ/LmRldmljZT8udmVuZG9yLFxuICAgIGRldmljZU1vZGVsOiByZXN1bHQ/LmRldmljZT8ubW9kZWwsXG4gICAgYnJvd3NlcjogcmVzdWx0Py5icm93c2VyPy5uYW1lLFxuICAgIGJyb3dzZXJWZXJzaW9uOiByZXN1bHQ/LmJyb3dzZXI/LnZlcnNpb24sXG4gICAgdXNlckFnZW50OiByZXN1bHQ/LnVhLFxuICB9O1xufTtcblxuY29uc3QgVXNlcklkZW50aXR5Q29udGV4dCA9IGNyZWF0ZUNvbnRleHQ8VXNlcklkZW50aXR5Q29udGV4dFR5cGUgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG5cbmV4cG9ydCBjb25zdCBVc2VySWRlbnRpdHlQcm92aWRlcjogUmVhY3QuRkM8eyBjaGlsZHJlbjogUmVhY3QuUmVhY3ROb2RlIH0+ID0gKHsgY2hpbGRyZW4gfSkgPT4ge1xuICBjb25zdCB7IGdldEl0ZW0sIHNldEl0ZW0sIGlzQXZhaWxhYmxlOiBsb2NhbFN0b3JhZ2VJc1JlYWR5IH0gPSB1c2VMb2NhbFN0b3JhZ2UoKTtcblxuICBjb25zdCBbaXNSZWFkeSwgc2V0SXNSZWFkeV0gPSB1c2VTdGF0ZShmYWxzZSk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICAvLyBBc3N1bWluZyBDb21tZXJjZUFwaUNsaWVudCBhbmQgb3RoZXIgZGVwZW5kZW5jaWVzIGFyZSByZWFkeSBpZiBsb2NhbFN0b3JhZ2UgaXMuXG4gICAgLy8gSW4gYSBtb3JlIGNvbXBsZXggc2NlbmFyaW8sIHlvdSBtaWdodCBoYXZlIG1vcmUgY2hlY2tzIGhlcmUuXG4gICAgc2V0SXNSZWFkeShsb2NhbFN0b3JhZ2VJc1JlYWR5KTtcbiAgfSwgW2xvY2FsU3RvcmFnZUlzUmVhZHldKTtcblxuICBjb25zdCBVU0VSX0lEX09WRVJSSURFX0tFWSA9ICd2MS1zcGlmZnktdXNlci1pZC1vdmVycmlkZSc7XG4gIGNvbnN0IFVTRVJfSURfREVGQVVMVF9LRVkgPSAndjEtc3BpZmZ5LXVzZXItaWQtZGVmYXVsdCc7XG5cbiAgY29uc3QgZ2V0VXNlcklkT3ZlcnJpZGVGcm9tTG9jYWxTdG9yYWdlID0gdXNlQ2FsbGJhY2soXG4gICAgKCk6IHN0cmluZyB8IHVuZGVmaW5lZCA9PiBnZXRJdGVtKFVTRVJfSURfT1ZFUlJJREVfS0VZKSA/PyB1bmRlZmluZWQsXG4gICAgW2dldEl0ZW1dLFxuICApO1xuXG4gIGNvbnN0IGdldFVzZXJJZERlZmF1bHRGcm9tTG9jYWxTdG9yYWdlID0gdXNlQ2FsbGJhY2soXG4gICAgKCk6IHN0cmluZyB8IHVuZGVmaW5lZCA9PiBnZXRJdGVtKFVTRVJfSURfREVGQVVMVF9LRVkpID8/IHVuZGVmaW5lZCxcbiAgICBbZ2V0SXRlbV0sXG4gICk7XG5cbiAgY29uc3Qgc2V0VXNlcklkRGVmYXVsdEluTG9jYWxTdG9yYWdlID0gdXNlQ2FsbGJhY2soXG4gICAgKHVzZXJJZDogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgICAgIExvZ2dlci5sb2dJbmZvKGBzZXRVc2VySWREZWZhdWx0SW5Mb2NhbFN0b3JhZ2UgLSBTZXR0aW5nIHVzZXJfaWQ9JHt1c2VySWR9YCk7XG4gICAgICBzZXRJdGVtKFVTRVJfSURfREVGQVVMVF9LRVksIHVzZXJJZCk7XG4gICAgICAvLyB3aW5kb3cuZGlzcGF0Y2hFdmVudCBpcyBoYW5kbGVkIGJ5IHVzZUxvY2FsU3RvcmFnZSBub3dcbiAgICAgIHJldHVybiB1c2VySWQ7XG4gICAgfSxcbiAgICBbc2V0SXRlbSwgVVNFUl9JRF9ERUZBVUxUX0tFWV0sXG4gICk7XG5cbiAgY29uc3Qgc2V0VXNlcklkT3ZlcnJpZGVJbkxvY2FsU3RvcmFnZSA9IHVzZUNhbGxiYWNrKFxuICAgICh1c2VySWQ6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gICAgICBMb2dnZXIubG9nSW5mbyhgc2V0VXNlcklkT3ZlcnJpZGVJbkxvY2FsU3RvcmFnZSAtIFNldHRpbmcgdXNlcl9pZD0ke3VzZXJJZH1gKTtcbiAgICAgIHNldEl0ZW0oVVNFUl9JRF9PVkVSUklERV9LRVksIHVzZXJJZCk7XG4gICAgICAvLyB3aW5kb3cuZGlzcGF0Y2hFdmVudCBpcyBoYW5kbGVkIGJ5IHVzZUxvY2FsU3RvcmFnZSBub3dcbiAgICAgIHJldHVybiB1c2VySWQ7XG4gICAgfSxcbiAgICBbc2V0SXRlbSwgVVNFUl9JRF9PVkVSUklERV9LRVldLFxuICApO1xuXG4gIGNvbnN0IGNsZWFyVXNlcklkT3ZlcnJpZGVJbkxvY2FsU3RvcmFnZSA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBMb2dnZXIubG9nSW5mbyhgY2xlYXJVc2VySWRPdmVycmlkZUluTG9jYWxTdG9yYWdlIC0gQ2xlYXJpbmcgdXNlcl9pZGApO1xuICAgIC8vIExvY2FsU3RvcmFnZVNlcnZpY2UuZ2V0TG9jYWxTdG9yYWdlKCk/LnJlbW92ZUl0ZW0oVVNFUl9JRF9PVkVSUklERV9LRVkpO1xuICAgIC8vIHdpbmRvdy5kaXNwYXRjaEV2ZW50IGlzIGhhbmRsZWQgYnkgdXNlTG9jYWxTdG9yYWdlIG5vd1xuICAgIHNldEl0ZW0oVVNFUl9JRF9PVkVSUklERV9LRVksICcnKTsgLy8gU2V0IHRvIGVtcHR5IHN0cmluZyB0byBjbGVhclxuICB9LCBbc2V0SXRlbSwgVVNFUl9JRF9PVkVSUklERV9LRVldKTtcblxuICBjb25zdCBnZXRVc2VySWRPckRlZmF1bHQgPSB1c2VDYWxsYmFjaygoKTogc3RyaW5nID0+IHtcbiAgICBjb25zdCB1c2VySWRPdmVycmlkZSA9IGdldFVzZXJJZE92ZXJyaWRlRnJvbUxvY2FsU3RvcmFnZSgpO1xuICAgIGlmICh1c2VySWRPdmVycmlkZSkge1xuICAgICAgcmV0dXJuIHVzZXJJZE92ZXJyaWRlO1xuICAgIH1cblxuICAgIGNvbnN0IGRlZmF1bHRVc2VySWQgPSBnZXRVc2VySWREZWZhdWx0RnJvbUxvY2FsU3RvcmFnZSgpO1xuICAgIGlmIChkZWZhdWx0VXNlcklkKSB7XG4gICAgICByZXR1cm4gZGVmYXVsdFVzZXJJZDtcbiAgICB9XG5cbiAgICByZXR1cm4gc2V0VXNlcklkRGVmYXVsdEluTG9jYWxTdG9yYWdlKGBzcGlmZnktdXNlci1pZC0ke3V1aWQoKX1gKTtcbiAgfSwgW1xuICAgIGdldFVzZXJJZE92ZXJyaWRlRnJvbUxvY2FsU3RvcmFnZSxcbiAgICBnZXRVc2VySWREZWZhdWx0RnJvbUxvY2FsU3RvcmFnZSxcbiAgICBzZXRVc2VySWREZWZhdWx0SW5Mb2NhbFN0b3JhZ2UsXG4gIF0pO1xuXG4gIGNvbnN0IGlkZW50aWZ5VXNlciA9IHVzZUNhbGxiYWNrKGFzeW5jICgpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICBpZiAoIWlzUmVhZHkpIHtcbiAgICAgIExvZ2dlci5sb2dXYXJuKCdbVXNlcklkZW50aXR5Q29udGV4dF0gQ29udGV4dCBub3QgcmVhZHksIHNraXBwaW5nIGlkZW50aWZ5VXNlcicsIHVuZGVmaW5lZCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIC8vIFRlbXBvcmFyaWx5IGNvbW1lbnRlZCBvdXQgdW50aWwgV2luZG93RGF0YUxheWVyU2VydmljZSBpcyByZXNvbHZlZFxuICAgICAgLy8gY29uc3QgY2RwVXNlcklkID0gV2luZG93RGF0YUxheWVyU2VydmljZS5nZXRHb29nbGVBbmFseXRpY3NDbGllbnRJZCgpO1xuICAgICAgY29uc3QgY2RwVXNlcklkID0gJ1VOS05PV05fQ0RQX1VTRVJfSUQnOyAvLyBQbGFjZWhvbGRlclxuICAgICAgY29uc3QgdXNlcklkID0gZ2V0VXNlcklkT3JEZWZhdWx0KCk7XG4gICAgICBjb25zdCB1c2VyQWdlbnREZXRhaWxzID0gZ2V0VXNlckFnZW50RGV0YWlscygpO1xuXG4gICAgICBpZiAoIWNkcFVzZXJJZCkge1xuICAgICAgICBMb2dnZXIubG9nV2FybignW3NwaWZmeS1haV0gTm8gR0EgQ2xpZW50IElEIGZvdW5kLCBza2lwcGluZyBpZGVudGlmeVVzZXInLCB1bmRlZmluZWQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IENvbW1lcmNlQXBpQ2xpZW50LmlkZW50aWZ5VXNlcih1c2VySWQsIGNkcFVzZXJJZCwgdXNlckFnZW50RGV0YWlscyk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIExvZ2dlci5sb2dFcnJvcignW3NwaWZmeS1haV0gRXJyb3IgaWRlbnRpZnlpbmcgdXNlcicsIGVycm9yKTtcbiAgICB9XG4gIH0sIFtpc1JlYWR5LCBnZXRVc2VySWRPckRlZmF1bHRdKTtcblxuICBjb25zdCB2YWx1ZSA9IHVzZU1lbW8oXG4gICAgKCkgPT4gKHtcbiAgICAgIGlkZW50aWZ5VXNlcixcbiAgICAgIGdldFVzZXJJZE9yRGVmYXVsdCxcbiAgICAgIGdldFVzZXJJZE92ZXJyaWRlRnJvbUxvY2FsU3RvcmFnZSxcbiAgICAgIGdldFVzZXJJZERlZmF1bHRGcm9tTG9jYWxTdG9yYWdlLFxuICAgICAgc2V0VXNlcklkRGVmYXVsdEluTG9jYWxTdG9yYWdlLFxuICAgICAgc2V0VXNlcklkT3ZlcnJpZGVJbkxvY2FsU3RvcmFnZSxcbiAgICAgIGNsZWFyVXNlcklkT3ZlcnJpZGVJbkxvY2FsU3RvcmFnZSxcbiAgICAgIGlzUmVhZHksXG4gICAgfSksXG4gICAgW1xuICAgICAgaWRlbnRpZnlVc2VyLFxuICAgICAgZ2V0VXNlcklkT3JEZWZhdWx0LFxuICAgICAgZ2V0VXNlcklkT3ZlcnJpZGVGcm9tTG9jYWxTdG9yYWdlLFxuICAgICAgZ2V0VXNlcklkRGVmYXVsdEZyb21Mb2NhbFN0b3JhZ2UsXG4gICAgICBzZXRVc2VySWREZWZhdWx0SW5Mb2NhbFN0b3JhZ2UsXG4gICAgICBzZXRVc2VySWRPdmVycmlkZUluTG9jYWxTdG9yYWdlLFxuICAgICAgY2xlYXJVc2VySWRPdmVycmlkZUluTG9jYWxTdG9yYWdlLFxuICAgICAgaXNSZWFkeSxcbiAgICBdLFxuICApO1xuXG4gIHJldHVybiA8VXNlcklkZW50aXR5Q29udGV4dC5Qcm92aWRlciB2YWx1ZT17dmFsdWV9PntjaGlsZHJlbn08L1VzZXJJZGVudGl0eUNvbnRleHQuUHJvdmlkZXI+O1xufTtcblxuZXhwb3J0IGNvbnN0IHVzZVVzZXJJZGVudGl0eSA9ICgpID0+IHtcbiAgY29uc3QgY29udGV4dCA9IHVzZUNvbnRleHQoVXNlcklkZW50aXR5Q29udGV4dCk7XG4gIGlmICghY29udGV4dCkge1xuICAgIHRocm93IG5ldyBFcnJvcigndXNlVXNlcklkZW50aXR5IG11c3QgYmUgdXNlZCB3aXRoaW4gYSBVc2VySWRlbnRpdHlQcm92aWRlcicpO1xuICB9XG4gIHJldHVybiBjb250ZXh0O1xufTtcbiIsImltcG9ydCB7IGF0b21XaXRoU3RvcmFnZSB9IGZyb20gJ2pvdGFpL3V0aWxzJztcbmltcG9ydCB7IGF0b20gfSBmcm9tICdqb3RhaSc7XG5pbXBvcnQgeyBTdXBwb3J0ZWRFdmVudFJlc3BvbnNlLCBQYWdlVmlzaXRDYXRlZ29yeSB9IGZyb20gJ0BzcGlmZnktYWkvY29tbWVyY2UtYXBpLWNsaWVudCc7XG5pbXBvcnQge1xuICBQYWdlVmlzaXRWYXJpYW50SW5mbyxcbiAgUERQVmFyaWFudEluZm8sXG4gIFBMUFZhcmlhbnRJbmZvLFxuICBWYXJpYW50SW5mbyxcbiAgVmFyaWFudFR5cGVFbnVtLFxufSBmcm9tICdAZW52aXZlLWFpL3R5cGVzJztcbmltcG9ydCB7IHNlc3Npb25TdG9yYWdlVXRpbCB9IGZyb20gJ3NyYy9hdG9tcy9hdG9tU3RvcmUnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFN1cHBvcnRlZEV2ZW50XG4gIGV4dGVuZHMgUGljazxcbiAgICBTdXBwb3J0ZWRFdmVudFJlc3BvbnNlLFxuICAgICdzdXBwb3J0ZWQnIHwgJ3JlYWR5JyB8ICdjYXRlZ29yeScgfCAnY29sbGVjdGlvbnMnIHwgJ3RvcF9jYXRlZ29yeSdcbiAgPiB7XG4gIG51bWJlck9mUmV2aWV3czogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICBtZXJjaGFudF90YWdzPzogc3RyaW5nW107XG59XG5cbmludGVyZmFjZSBQRFBBdHRyaWJ1dGVzIHtcbiAgcHJvZHVjdF9pZD86IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIFBMUEF0dHJpYnV0ZXMge1xuICBhdHRyaWJ1dGVzPzoge1xuICAgIGlkPzogc3RyaW5nO1xuICB9O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVybFJlc29sdmluZ1BEUENvbmZpZyB7XG4gIHBkcF9hdHRyaWJ1dGVzOiBQRFBBdHRyaWJ1dGVzO1xuICBudW1iZXJfb2ZfcmV2aWV3cz86IG51bWJlcjtcbiAgY29sbGVjdGlvbnM/OiBzdHJpbmdbXTtcbiAgbWVyY2hhbnRfdGFncz86IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVybFJlc29sdmluZ1BMUENvbmZpZyB7XG4gIHBscF9hdHRyaWJ1dGVzOiBQTFBBdHRyaWJ1dGVzO1xuICB0b3BfY2F0ZWdvcnk/OiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBVcmxSZXNvbHZpbmdHZW5lcmljQ29uZmlnIHtcbiAgZGV0YWlscz86IHN0cmluZztcbn1cblxuZXhwb3J0IHR5cGUgUGFnZVZhcmlhbnRDaGVja0NvbmZpZyA9IHtcbiAgY2hlY2tfdHlwZTogc3RyaW5nO1xuICBmZWF0dXJlX2dhdGU/OiBzdHJpbmc7XG4gIGV4dHJhY3Rvcj86IHtcbiAgICB0eXBlOiBzdHJpbmc7XG4gICAgbWFwPzogUmVjb3JkPHN0cmluZywgc3RyaW5nW10+O1xuICAgIHZhbHVlPzogc3RyaW5nO1xuICB9O1xuICBwcm9kdWN0X2lkX2V4dHJhY3Rvcj86IHN0cmluZztcbiAgcHJvZHVjdF9pZHM/OiBzdHJpbmdbXTtcbiAgcGxwX2lkX2V4dHJhY3Rvcj86IHN0cmluZztcbiAgcGxwX2lkcz86IHN0cmluZ1tdO1xuICBjb2xsZWN0aW9ucz86IHN0cmluZ1tdO1xuICBxdWVyeV9wYXJhbT86IHN0cmluZztcbiAgY2F0ZWdvcnk/OiBzdHJpbmc7XG4gIHRvcF9jYXRlZ29yeT86IHN0cmluZ1tdO1xuICByZXZpZXdfbWluaW11bT86IG51bWJlcjtcbiAgbWVyY2hhbnRfdGFncz86IHN0cmluZ1tdO1xufTtcblxuZXhwb3J0IHR5cGUgQmFja2VuZFdpZGdldE1vdW50aW5nQ29uZmlnID0ge1xuICBtb3VudGluZ19jb25maWdfaWQ6IHN0cmluZztcbiAgd2lkZ2V0X2NvbmZpZ19pZD86IHN0cmluZztcbiAgbW91bnRpbmdfcG9pbnRfd2lkZ2V0cz86IEFycmF5PHtcbiAgICBjaGVja3M6IFBhZ2VWYXJpYW50Q2hlY2tDb25maWdbXTtcbiAgICB3aWRnZXRfY29uZmlnX2lkOiBzdHJpbmc7XG4gIH0+O1xufTtcblxuZXhwb3J0IHR5cGUgQmFja2VuZFBhZ2VWYXJpYW50Q29uZmlnID0ge1xuICB2YXJpYW50X2lkOiBzdHJpbmc7XG4gIHZhcmlhbnRfdHlwZTogc3RyaW5nO1xuICB2YXJpYW50X2NoZWNrczogUGFnZVZhcmlhbnRDaGVja0NvbmZpZ1tdO1xuICB3aWRnZXRfbW91bnRpbmc6IEJhY2tlbmRXaWRnZXRNb3VudGluZ0NvbmZpZ1tdO1xuICBwbHBfaWRfZXh0cmFjdG9yPzogc3RyaW5nO1xuICBwcm9kdWN0X2lkX2V4dHJhY3Rvcj86IHN0cmluZztcbiAgcGFyZW50X3Byb2R1Y3RfaWRfZXh0cmFjdG9yPzogc3RyaW5nO1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBVcmxSZXNvbHZlclJlc3BvbnNlIHtcbiAgdmFyaWFudF90eXBlOiBzdHJpbmc7XG4gIHNwZWNpZmljX2RldGFpbHM6IFVybFJlc29sdmluZ1BEUENvbmZpZyB8IFVybFJlc29sdmluZ1BMUENvbmZpZyB8IFVybFJlc29sdmluZ0dlbmVyaWNDb25maWc7XG4gIHJlYWR5OiBib29sZWFuO1xuICB1c2VyX2V2ZW50Pzoge1xuICAgIGV2ZW50X2lkPzogc3RyaW5nO1xuICAgIGF0dHJpYnV0ZXM/OiBQRFBBdHRyaWJ1dGVzIHwgUExQQXR0cmlidXRlcztcbiAgICBjYXRlZ29yeT86IHN0cmluZztcbiAgICBjcmVhdGVkX2F0Pzogc3RyaW5nO1xuICB9O1xuICBwYWdlX3ZhcmlhbnQ/OiBCYWNrZW5kUGFnZVZhcmlhbnRDb25maWc7XG59XG5cbi8vIFVzZSBhIG1hcCBmb3IgcGVyLVVSTCBjYWNoZVxuZXhwb3J0IHR5cGUgVXJsUmVzb2x2ZXJDYWNoZSA9IFJlY29yZDxzdHJpbmcsIFVybFJlc29sdmVyUmVzcG9uc2UgfCB1bmRlZmluZWQ+O1xuXG5jb25zdCBpbnRlcm5hbFN0b3JhZ2VVcmxSZXNvbHZlckF0b20gPSBhdG9tV2l0aFN0b3JhZ2U8c3RyaW5nIHwgdW5kZWZpbmVkPihcbiAgJ3NwaWZmeS11cmwtcmVzb2x2ZXInLFxuICB1bmRlZmluZWQsXG4gIHNlc3Npb25TdG9yYWdlVXRpbCxcbiAge1xuICAgIGdldE9uSW5pdDogdHJ1ZSxcbiAgfSxcbik7XG5cbmV4cG9ydCBjb25zdCB1cmxSZXNvbHZlckF0b20gPSBhdG9tKFxuICAoZ2V0KTogVXJsUmVzb2x2ZXJDYWNoZSA9PiB7XG4gICAgY29uc3QgbWF5YmVVcmxSZXNvbHZlciA9IGdldChpbnRlcm5hbFN0b3JhZ2VVcmxSZXNvbHZlckF0b20pO1xuICAgIGlmIChtYXliZVVybFJlc29sdmVyID09IG51bGwpIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgcmV0dXJuIEpTT04ucGFyc2UobWF5YmVVcmxSZXNvbHZlcik7XG4gIH0sXG4gIChnZXQsIHNldCwgdmFsdWU6IHsgdXJsOiBzdHJpbmc7IHJlc3BvbnNlOiBVcmxSZXNvbHZlclJlc3BvbnNlIHwgdW5kZWZpbmVkIH0pID0+IHtcbiAgICAvLyBHZXQgY3VycmVudCBjYWNoZSBmcm9tIHN0b3JhZ2VcbiAgICBjb25zdCBjdXJyZW50Q2FjaGUgPSBnZXQodXJsUmVzb2x2ZXJBdG9tKTtcbiAgICBjb25zdCBuZXdDYWNoZSA9IHsgLi4uY3VycmVudENhY2hlLCBbdmFsdWUudXJsXTogdmFsdWUucmVzcG9uc2UgfTtcblxuICAgIHNldChpbnRlcm5hbFN0b3JhZ2VVcmxSZXNvbHZlckF0b20sIEpTT04uc3RyaW5naWZ5KG5ld0NhY2hlKSk7XG4gIH0sXG4pO1xuXG5jb25zdCBpbnRlcm5hbFN0b3JhZ2VTdXBwb3J0ZWRFdmVudEF0b20gPSBhdG9tV2l0aFN0b3JhZ2U8c3RyaW5nIHwgdW5kZWZpbmVkPihcbiAgJ3NwaWZmeS1zdXBwb3J0ZWQtZXZlbnQnLFxuICB1bmRlZmluZWQsXG4gIHNlc3Npb25TdG9yYWdlVXRpbCxcbiAge1xuICAgIGdldE9uSW5pdDogdHJ1ZSxcbiAgfSxcbik7XG5jb25zdCBpbnRlcm5hbFN1cHBvcnRlZEV2ZW50QXRvbSA9IGF0b208U3VwcG9ydGVkRXZlbnQgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG5cbmV4cG9ydCBjb25zdCBzdXBwb3J0ZWRFdmVudEF0b20gPSBhdG9tKFxuICAoZ2V0KTogU3VwcG9ydGVkRXZlbnQgfCB1bmRlZmluZWQgPT4ge1xuICAgIGNvbnN0IG1heWJlU3VwcG9ydGVkRXZlbnQgPSBnZXQoaW50ZXJuYWxTdG9yYWdlU3VwcG9ydGVkRXZlbnRBdG9tKTtcbiAgICBpZiAobWF5YmVTdXBwb3J0ZWRFdmVudCA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8vIFRPRE8gdGhpcyBpcyBhbiB1bnZhbGlkYXRlZCBwYXJzZS4gSXQgbWF5IGJlIGJldHRlciB0byBpbXBsZW1lbnQgYSBjdXN0b20gc3RvcmFnZSB1dGlsXG4gICAgLy8gYW5kIHBlcmZvcm0gdGhlIG9iamVjdCB2YWxpZGF0aW9uIG9uIFwiZ2V0XCIgdGhlcmUuXG4gICAgcmV0dXJuIEpTT04ucGFyc2UobWF5YmVTdXBwb3J0ZWRFdmVudCk7XG4gIH0sXG4gIChfLCBzZXQsIHZhbHVlOiBTdXBwb3J0ZWRFdmVudCB8IHVuZGVmaW5lZCkgPT4ge1xuICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgICBzZXQoaW50ZXJuYWxTdG9yYWdlU3VwcG9ydGVkRXZlbnRBdG9tLCB1bmRlZmluZWQpO1xuICAgICAgc2V0KGludGVybmFsU3VwcG9ydGVkRXZlbnRBdG9tLCB1bmRlZmluZWQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHNldChpbnRlcm5hbFN1cHBvcnRlZEV2ZW50QXRvbSwgdmFsdWUpO1xuICAgIHNldChpbnRlcm5hbFN0b3JhZ2VTdXBwb3J0ZWRFdmVudEF0b20sIEpTT04uc3RyaW5naWZ5KHZhbHVlKSk7XG4gIH0sXG4pO1xuXG5jb25zdCBpbnRlcm5hbFZhcmlhbnRJZEF0b20gPSBhdG9tPHN0cmluZz4oKTtcbmNvbnN0IGludGVybmFsUHJvZHVjdElkQXRvbSA9IGF0b208c3RyaW5nPigpO1xuY29uc3QgaW50ZXJuYWxQYXJlbnRQcm9kdWN0SWRBdG9tID0gYXRvbTxzdHJpbmc+KCk7XG5jb25zdCBpbnRlcm5hbFByb2R1Y3RVcmxBdG9tID0gYXRvbTxzdHJpbmc+KCk7XG5jb25zdCBpbnRlcm5hbFBscElkQXRvbSA9IGF0b208c3RyaW5nPigpO1xuY29uc3QgaW50ZXJuYWxVcmxBdG9tID0gYXRvbTxzdHJpbmc+KCk7XG5jb25zdCBpbnRlcm5hbFBhZ2VWaXNpdENhdGVnb3J5QXRvbSA9IGF0b208UGFnZVZpc2l0Q2F0ZWdvcnk+KCk7XG5jb25zdCBpbnRlcm5hbFZhcmlhbnRBdG9tID0gYXRvbTwncGRwJyB8ICdwbHAnIHwgJ3NlYXJjaCcgfCAncGFnZV92aXNpdCc+KCdwZHAnKTtcblxuZXhwb3J0IGNvbnN0IHZhcmlhbnRJZEF0b20gPSBhdG9tKChnZXQpID0+IGdldChpbnRlcm5hbFZhcmlhbnRJZEF0b20pKTtcbmV4cG9ydCBjb25zdCBwcm9kdWN0SWRBdG9tID0gYXRvbSgoZ2V0KSA9PiBnZXQoaW50ZXJuYWxQcm9kdWN0SWRBdG9tKSk7XG5leHBvcnQgY29uc3QgcGFyZW50UHJvZHVjdElkQXRvbSA9IGF0b20oKGdldCkgPT4gZ2V0KGludGVybmFsUGFyZW50UHJvZHVjdElkQXRvbSkpO1xuZXhwb3J0IGNvbnN0IHByb2R1Y3RVcmxBdG9tID0gYXRvbSgoZ2V0KSA9PiBnZXQoaW50ZXJuYWxQcm9kdWN0VXJsQXRvbSkpO1xuZXhwb3J0IGNvbnN0IHBscElkQXRvbSA9IGF0b20oKGdldCkgPT4gZ2V0KGludGVybmFsUGxwSWRBdG9tKSk7XG5leHBvcnQgY29uc3QgdXJsQXRvbSA9IGF0b20oKGdldCkgPT4gZ2V0KGludGVybmFsVXJsQXRvbSkpO1xuZXhwb3J0IGNvbnN0IHBhZ2VWaXNpdENhdGVnb3J5QXRvbSA9IGF0b20oKGdldCkgPT4gZ2V0KGludGVybmFsUGFnZVZpc2l0Q2F0ZWdvcnlBdG9tKSk7XG5leHBvcnQgY29uc3QgdmFyaWFudEF0b20gPSBhdG9tKChnZXQpID0+IGdldChpbnRlcm5hbFZhcmlhbnRBdG9tKSk7XG5leHBvcnQgY29uc3QgaGFzUGFyc2VkVmFyaWFudEluZm9BdG9tID0gYXRvbShmYWxzZSk7XG5cbmV4cG9ydCBjb25zdCB2YXJpYW50SW5mb0F0b20gPSBhdG9tKFxuICAoZ2V0KTogVmFyaWFudEluZm8gPT4ge1xuICAgIGNvbnN0IHZhcmlhbnQgPSBnZXQodmFyaWFudEF0b20pO1xuICAgIGlmICh2YXJpYW50ID09PSBWYXJpYW50VHlwZUVudW0uUGRwKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YXJpYW50SWQ6IGdldCh2YXJpYW50SWRBdG9tKSxcbiAgICAgICAgdmFyaWFudCxcbiAgICAgICAgcHJvZHVjdElkOiBnZXQocHJvZHVjdElkQXRvbSksXG4gICAgICAgIHBhcmVudFByb2R1Y3RJZDogZ2V0KHBhcmVudFByb2R1Y3RJZEF0b20pLFxuICAgICAgICB1cmw6IGdldCh1cmxBdG9tKSxcbiAgICAgIH0gYXMgUERQVmFyaWFudEluZm87XG4gICAgfVxuICAgIGlmICh2YXJpYW50ID09PSBWYXJpYW50VHlwZUVudW0uUGxwKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YXJpYW50SWQ6IGdldCh2YXJpYW50SWRBdG9tKSxcbiAgICAgICAgdmFyaWFudCxcbiAgICAgICAgcGxwSWQ6IGdldChwbHBJZEF0b20pLFxuICAgICAgICB1cmw6IGdldCh1cmxBdG9tKSxcbiAgICAgIH0gYXMgUExQVmFyaWFudEluZm87XG4gICAgfVxuICAgIGlmICh2YXJpYW50ID09PSBWYXJpYW50VHlwZUVudW0uUGFnZVZpc2l0KSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YXJpYW50SWQ6IGdldCh2YXJpYW50SWRBdG9tKSxcbiAgICAgICAgdmFyaWFudCxcbiAgICAgICAgdXJsOiBnZXQodXJsQXRvbSksXG4gICAgICAgIHBhZ2VWaXNpdENhdGVnb3J5OiBnZXQocGFnZVZpc2l0Q2F0ZWdvcnlBdG9tKSxcbiAgICAgIH0gYXMgUGFnZVZpc2l0VmFyaWFudEluZm87XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCB2YXJpYW50SW5mbyBkZXRhaWxzJyk7XG4gIH0sXG4gIChfLCBzZXQsIG5ld1ZhcmlhbnQ6IFZhcmlhbnRJbmZvKSA9PiB7XG4gICAgc2V0KGludGVybmFsVmFyaWFudEF0b20sIG5ld1ZhcmlhbnQudmFyaWFudCk7XG4gICAgc2V0KGludGVybmFsVmFyaWFudElkQXRvbSwgbmV3VmFyaWFudC52YXJpYW50SWQpO1xuICAgIGlmIChuZXdWYXJpYW50LnZhcmlhbnQgPT09IFZhcmlhbnRUeXBlRW51bS5QZHApIHtcbiAgICAgIHNldChpbnRlcm5hbFByb2R1Y3RJZEF0b20sIG5ld1ZhcmlhbnQucHJvZHVjdElkKTtcbiAgICAgIHNldChpbnRlcm5hbFBhcmVudFByb2R1Y3RJZEF0b20sIG5ld1ZhcmlhbnQucGFyZW50UHJvZHVjdElkKTtcbiAgICAgIHNldChpbnRlcm5hbFVybEF0b20sIG5ld1ZhcmlhbnQudXJsKTtcbiAgICB9XG4gICAgaWYgKG5ld1ZhcmlhbnQudmFyaWFudCA9PT0gVmFyaWFudFR5cGVFbnVtLlBscCkge1xuICAgICAgc2V0KGludGVybmFsUGxwSWRBdG9tLCBuZXdWYXJpYW50LnBscElkKTtcbiAgICAgIHNldChpbnRlcm5hbFVybEF0b20sIG5ld1ZhcmlhbnQudXJsKTtcbiAgICB9XG4gICAgaWYgKG5ld1ZhcmlhbnQudmFyaWFudCA9PT0gVmFyaWFudFR5cGVFbnVtLlBhZ2VWaXNpdCkge1xuICAgICAgc2V0KGludGVybmFsVXJsQXRvbSwgbmV3VmFyaWFudC51cmwpO1xuICAgICAgc2V0KGludGVybmFsUGFnZVZpc2l0Q2F0ZWdvcnlBdG9tLCBuZXdWYXJpYW50LnBhZ2VWaXNpdENhdGVnb3J5KTtcbiAgICB9XG4gIH0sXG4pO1xuIiwiaW1wb3J0IHsgQ29udGV4dEVudkVudW0sIENvbnRleHRTb3VyY2VFbnVtIH0gZnJvbSAnQHNwaWZmeS1haS9jb21tZXJjZS1hcGktY2xpZW50JztcbmltcG9ydCB7IGF0b20gfSBmcm9tICdqb3RhaSc7XG5pbXBvcnQgeyBhdG9tV2l0aFN0b3JhZ2UgfSBmcm9tICdqb3RhaS91dGlscyc7XG5pbXBvcnQgeyBWYXJpYW50SW5mbywgVXNlcklkZW50aXR5Q29udGV4dFR5cGUgfSBmcm9tICdAZW52aXZlLWFpL3R5cGVzJztcbmltcG9ydCB7IHVzZVVzZXJJZGVudGl0eSB9IGZyb20gJ3NyYy9jb250ZXh0cy91c2VySWRlbnRpdHlDb250ZXh0L3VzZXJJZGVudGl0eUNvbnRleHQnO1xuaW1wb3J0IHsgdmFyaWFudEluZm9BdG9tIH0gZnJvbSAnc3JjL2F0b21zL2FwcC92YXJpYW50JztcbmltcG9ydCB7IHY0IGFzIHV1aWQgfSBmcm9tICd1dWlkJztcbmltcG9ydCB7IGNvbnRleHRTb3VyY2VBdG9tIH0gZnJvbSAnLi4vZW52aXZlL2Vudml2ZUNvbmZpZyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXBwRGV0YWlscyB7XG4gIG9yZ0lkOiBzdHJpbmc7XG4gIG9yZ1Nob3J0TmFtZTogc3RyaW5nO1xuICBjaGF0SWQ6IHN0cmluZztcbiAgdXNlcklkOiBzdHJpbmc7XG4gIHNvdXJjZTogQ29udGV4dFNvdXJjZUVudW07XG4gIGVudjogQ29udGV4dEVudkVudW07XG4gIHZhcmlhbnRJbmZvOiBWYXJpYW50SW5mbztcbn1cblxuZXhwb3J0IHsgdmFyaWFudEluZm9BdG9tIH0gZnJvbSAnLi92YXJpYW50JztcblxuY29uc3QgaW50ZXJuYWxVc2VySWRBdG9tID0gYXRvbTxzdHJpbmcgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG5cbmV4cG9ydCBjb25zdCB1c2VySWRBdG9tID0gYXRvbShcbiAgKGdldCkgPT4ge1xuICAgIGNvbnN0IG1heWJlVXNlcklkID0gZ2V0KGludGVybmFsVXNlcklkQXRvbSk7XG5cbiAgICBpZiAobWF5YmVVc2VySWQpIHtcbiAgICAgIHJldHVybiBtYXliZVVzZXJJZDtcbiAgICB9XG5cbiAgICBjb25zdCB7IGdldFVzZXJJZE9yRGVmYXVsdCB9ID0gdXNlVXNlcklkZW50aXR5KCk7XG4gICAgcmV0dXJuIGdldFVzZXJJZE9yRGVmYXVsdCgpO1xuICB9LFxuICAoXywgc2V0LCB2YWx1ZTogc3RyaW5nIHwgdW5kZWZpbmVkKSA9PiB7XG4gICAgc2V0KGludGVybmFsVXNlcklkQXRvbSwgdmFsdWUpO1xuICB9LFxuKTtcblxuZXhwb3J0IGNvbnN0IHVzZXJJZGVudGl0eUF0b20gPSBhdG9tPFVzZXJJZGVudGl0eUNvbnRleHRUeXBlIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuXG5leHBvcnQgY29uc3QgYXBwU291cmNlQXRvbSA9IGF0b208Q29udGV4dFNvdXJjZUVudW0+KFxuICAoZ2V0KTogQ29udGV4dFNvdXJjZUVudW0gPT4gZ2V0KGNvbnRleHRTb3VyY2VBdG9tKSA/PyBDb250ZXh0U291cmNlRW51bS5BcHAsXG4pO1xuZXhwb3J0IGNvbnN0IGNoYXRJZEF0b20gPSBhdG9tV2l0aFN0b3JhZ2U8c3RyaW5nPigndjEtc3BpZmZ5LWNoYXQtc2Vzc2lvbi1pZCcsIHV1aWQoKSwgdW5kZWZpbmVkLCB7XG4gIGdldE9uSW5pdDogdHJ1ZSxcbn0pO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUEwREEsZUFBZSxrQkFBa0IsT0FBc0I7QUFDckQsS0FBSTtBQUNGLFNBQU8sTUFBTSxNQUFNLFNBQVMsTUFBTTtTQUM1QjtBQUNOLFNBQU8sRUFBRTs7O0FBSWIsZUFBZSw4QkFBOEIsVUFBa0IsT0FBZ0I7QUFDN0UsS0FBSSxFQUFFLGlCQUFpQixnQkFBZ0I7QUFDckMsaUJBQU8sUUFBUSxVQUFVLE1BQU07QUFDL0IsUUFBTTs7Q0FHUixNQUFNLGdCQUFnQixNQUFNLGtCQUFrQixNQUFNO0FBQ3BELEtBQ0UsZUFBZSxTQUFTLGFBQWEsS0FBSyx5QkFDMUMsZUFBZSxVQUFVLGFBQWEsS0FBSyxvQkFFM0MsT0FBTSxJQUFJLDZCQUE2QjtVQUV2QyxlQUFlLFVBQVUsYUFBYSxLQUFLLHFCQUMzQyxlQUFlLFVBQVUsYUFBYSxLQUFLLGFBQzNDO0FBQ0EsaUJBQU8sUUFDTCw0Q0FDQSxPQUNBLE1BQU0sVUFDTixjQUNEO0FBQ0QsUUFBTSxJQUFJLHdCQUF3Qjs7QUFHcEMsZ0JBQU8sUUFBUSxVQUFVLE1BQU07QUFDL0IsT0FBTTs7QUFHUixJQUFNLG9CQUFOLE1BQU0sa0JBQWtCOzsyQkFhZ0M7QUFDcEQsT0FBSSxDQUFDLGtCQUFrQixTQUNyQixtQkFBa0IsV0FBVyxJQUFJLG1CQUFtQjtBQUd0RCxVQUFPLGtCQUFrQjs7O0NBRzNCLEFBQVEsWUFBWSxVQUFtQjtvQ0Fa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