@envive-ai/react-hooks 0.1.6 → 0.1.7
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.
- package/dist/NewOrgConfig-C5YL4Y62.cjs +20 -0
- package/dist/NewOrgConfig-CRyIfb_l.js +15 -0
- package/dist/SystemSettingsContext-Cb9YHln8.cjs +20 -0
- package/dist/SystemSettingsContext-D3mmGGcv.js +13 -0
- package/dist/TrackComponentVisibleEvent-C7c_rHFW.cjs +59 -0
- package/dist/TrackComponentVisibleEvent-DXTEBjGM.js +52 -0
- package/dist/amplitudeContext-CB_F-nJY.d.cts +52 -0
- package/dist/amplitudeContext-Cak6ijMq.js +287 -0
- package/dist/amplitudeContext-DFYBDc0h.d.ts +52 -0
- package/dist/amplitudeContext-sTEsPaVG.cjs +309 -0
- package/dist/api-DSFlctlc.cjs +269 -0
- package/dist/api-JTNjuOfc.js +190 -0
- package/dist/{app-CjsQ2_n-.js → app-D_upYeqF.js} +6 -6
- package/dist/{app-CnKRZ9RW.cjs → app-KXTMPa4s.cjs} +8 -8
- package/dist/application/models/graphql/index.cjs +2 -1
- package/dist/application/models/graphql/index.d.ts +1 -1
- package/dist/application/models/graphql/index.js +2 -1
- package/dist/application/models/guards/api/index.cjs +2 -1
- package/dist/application/models/guards/api/index.d.ts +2 -2
- package/dist/application/models/guards/api/index.js +2 -1
- package/dist/application/models/index.cjs +11 -9
- package/dist/application/models/index.d.cts +8 -4
- package/dist/application/models/index.d.ts +11 -7
- package/dist/application/models/index.js +10 -7
- package/dist/application/models/utilityTypes/index.cjs +1 -1
- package/dist/application/models/utilityTypes/index.d.ts +1 -1
- package/dist/application/models/utilityTypes/index.js +1 -1
- package/dist/application/models/variantInfo/index.cjs +1 -1
- package/dist/application/models/variantInfo/index.d.cts +1 -1
- package/dist/application/models/variantInfo/index.d.ts +1 -1
- package/dist/application/models/variantInfo/index.js +1 -1
- package/dist/application/utils/index.cjs +28 -22
- package/dist/application/utils/index.d.cts +12 -8
- package/dist/application/utils/index.d.ts +16 -12
- package/dist/application/utils/index.js +19 -13
- package/dist/{atomStore-B4jIaDPd.cjs → atomStore-DEZyFCNz.cjs} +1 -1
- package/dist/{atomStore-D8pjE1vL.js → atomStore-DnPEioF4.js} +1 -1
- package/dist/atoms/app/index.cjs +13 -9
- package/dist/atoms/app/index.d.cts +15 -11
- package/dist/atoms/app/index.d.ts +18 -14
- package/dist/atoms/app/index.js +13 -9
- package/dist/atoms/atomStore/index.cjs +2 -2
- package/dist/atoms/atomStore/index.d.cts +1 -1
- package/dist/atoms/atomStore/index.js +2 -2
- package/dist/atoms/chat/index.cjs +34 -28
- package/dist/atoms/chat/index.d.cts +35 -31
- package/dist/atoms/chat/index.d.ts +38 -34
- package/dist/atoms/chat/index.js +20 -14
- package/dist/atoms/globalSearch/index.cjs +1 -1
- package/dist/atoms/globalSearch/index.d.cts +5 -5
- package/dist/atoms/globalSearch/index.d.ts +5 -5
- package/dist/atoms/globalSearch/index.js +1 -1
- package/dist/atoms/org/index.cjs +6 -14
- package/dist/atoms/org/index.d.cts +27 -32
- package/dist/atoms/org/index.d.ts +30 -35
- package/dist/atoms/org/index.js +5 -11
- package/dist/atoms/search/index.cjs +44 -34
- package/dist/atoms/search/index.d.cts +9 -4
- package/dist/atoms/search/index.d.ts +12 -7
- package/dist/atoms/search/index.js +26 -16
- package/dist/atoms/search/types.cjs +5 -0
- package/dist/atoms/search/types.d.cts +2 -0
- package/dist/atoms/search/types.d.ts +2 -0
- package/dist/atoms/search/types.js +3 -0
- package/dist/cdnContext-BMjVfBft.cjs +53 -0
- package/dist/cdnContext-DgsJ00Tb.js +38 -0
- package/dist/{chat-CV6MXeID.js → chat-B4lkFIxz.js} +1 -1
- package/dist/chat-D1Eat8Ih.cjs +394 -0
- package/dist/chat-DPJGdUkz.js +258 -0
- package/dist/{chat-BubCW1as.cjs → chat-zA-K4tR_.cjs} +1 -1
- package/dist/chatElementDisplayLocation-9SW40Dd3.d.cts +25 -0
- package/dist/chatElementDisplayLocation-C1tRM5OD.d.ts +25 -0
- package/dist/chatSearch-B5jMnCYX.js +315 -0
- package/dist/chatSearch-DWMiyWN0.cjs +444 -0
- package/dist/chatState-BisPJd5g.cjs +120 -0
- package/dist/chatState-BrmBYY8l.js +34 -0
- package/dist/commerce-api-CxDIfeME.cjs +318 -0
- package/dist/commerce-api-DagLj3D_.js +311 -0
- package/dist/{components-B4T3Uzth.js → components-B1edduHz.js} +1 -1
- package/dist/{components-Cw9WjA6g.cjs → components-g0G58Kat.cjs} +1 -1
- package/dist/config/locators/components/chat/index.cjs +1 -1
- package/dist/config/locators/components/chat/index.d.cts +1 -1
- package/dist/config/locators/components/chat/index.d.ts +1 -1
- package/dist/config/locators/components/chat/index.js +1 -1
- package/dist/config/locators/components/chat/variants/index.d.cts +1 -1
- package/dist/config/locators/components/chat/variants/index.d.ts +1 -1
- package/dist/config/locators/components/index.cjs +1 -1
- package/dist/config/locators/components/index.d.cts +1 -1
- package/dist/config/locators/components/index.d.ts +1 -1
- package/dist/config/locators/components/index.js +1 -1
- package/dist/config/locators/components/search/index.d.cts +1 -1
- package/dist/config/locators/components/search/index.d.ts +1 -1
- package/dist/config/locators/index.cjs +42 -22
- package/dist/config/locators/index.d.cts +2 -2
- package/dist/config/locators/index.d.ts +3 -3
- package/dist/config/locators/index.js +25 -5
- package/dist/contexts/amplitudeContext/index.cjs +21 -0
- package/dist/contexts/amplitudeContext/index.d.cts +2 -0
- package/dist/contexts/amplitudeContext/index.d.ts +2 -0
- package/dist/contexts/amplitudeContext/index.js +19 -0
- package/dist/contexts/cdnContext/index.cjs +7 -0
- package/dist/contexts/cdnContext/index.d.cts +15 -0
- package/dist/contexts/cdnContext/index.d.ts +15 -0
- package/dist/contexts/cdnContext/index.js +6 -0
- package/dist/contexts/chatContext/index.cjs +329 -0
- package/dist/contexts/chatContext/index.d.cts +15 -0
- package/dist/contexts/chatContext/index.d.ts +15 -0
- package/dist/contexts/chatContext/index.js +322 -0
- package/dist/contexts/enviveConfigContext/index.cjs +7 -0
- package/dist/contexts/enviveConfigContext/index.d.cts +30 -0
- package/dist/contexts/enviveConfigContext/index.d.ts +30 -0
- package/dist/contexts/enviveConfigContext/index.js +6 -0
- package/dist/contexts/enviveCssContext/index.cjs +65 -0
- package/dist/contexts/enviveCssContext/index.d.cts +10 -0
- package/dist/contexts/enviveCssContext/index.d.ts +10 -0
- package/dist/contexts/enviveCssContext/index.js +62 -0
- package/dist/contexts/featureFlagContext/index.cjs +107 -0
- package/dist/contexts/featureFlagContext/index.d.cts +20 -0
- package/dist/contexts/featureFlagContext/index.d.ts +20 -0
- package/dist/contexts/featureFlagContext/index.js +103 -0
- package/dist/contexts/featureFlagServiceContext/index.cjs +6 -0
- package/dist/contexts/featureFlagServiceContext/index.d.cts +5 -0
- package/dist/contexts/featureFlagServiceContext/index.d.ts +5 -0
- package/dist/contexts/featureFlagServiceContext/index.js +5 -0
- package/dist/contexts/graphqlContext/index.cjs +15 -0
- package/dist/contexts/graphqlContext/index.d.cts +12 -0
- package/dist/contexts/graphqlContext/index.d.ts +12 -0
- package/dist/contexts/graphqlContext/index.js +14 -0
- package/dist/contexts/localStorageContext/index.cjs +6 -0
- package/dist/contexts/localStorageContext/index.d.cts +30 -0
- package/dist/contexts/localStorageContext/index.d.ts +30 -0
- package/dist/contexts/localStorageContext/index.js +4 -0
- package/dist/contexts/newOrgConfigContext/index.cjs +19 -0
- package/dist/contexts/newOrgConfigContext/index.d.cts +30 -0
- package/dist/contexts/newOrgConfigContext/index.d.ts +30 -0
- package/dist/contexts/newOrgConfigContext/index.js +18 -0
- package/dist/contexts/searchContext/index.cjs +23 -0
- package/dist/contexts/searchContext/index.d.cts +16 -0
- package/dist/contexts/searchContext/index.d.ts +16 -0
- package/dist/contexts/searchContext/index.js +22 -0
- package/dist/contexts/sessionStorageContext/index.cjs +5 -0
- package/dist/contexts/sessionStorageContext/index.d.cts +15 -0
- package/dist/contexts/sessionStorageContext/index.d.ts +15 -0
- package/dist/contexts/sessionStorageContext/index.js +4 -0
- package/dist/contexts/shopifyUrlContext/index.cjs +5 -0
- package/dist/contexts/shopifyUrlContext/index.d.cts +20 -0
- package/dist/contexts/shopifyUrlContext/index.d.ts +20 -0
- package/dist/contexts/shopifyUrlContext/index.js +4 -0
- package/dist/contexts/systemSettingsContext/index.cjs +8 -0
- package/dist/contexts/systemSettingsContext/index.d.cts +36 -0
- package/dist/contexts/systemSettingsContext/index.d.ts +36 -0
- package/dist/contexts/systemSettingsContext/index.js +6 -0
- package/dist/contexts/types.cjs +7 -0
- package/dist/contexts/types.d.cts +4 -0
- package/dist/contexts/types.d.ts +4 -0
- package/dist/contexts/types.js +3 -0
- package/dist/contexts/userIdentityContext/index.cjs +26 -0
- package/dist/contexts/userIdentityContext/index.d.cts +2 -0
- package/dist/contexts/userIdentityContext/index.d.ts +2 -0
- package/dist/contexts/userIdentityContext/index.js +25 -0
- package/dist/domObserver-B6cRGTny.js +285 -0
- package/dist/domObserver-DQZwhPrc.cjs +304 -0
- package/dist/enviveConfig-BJZ4zTJo.js +62 -0
- package/dist/enviveConfig-DdBrcGSQ.cjs +130 -0
- package/dist/enviveConfigContext-78orE_uH.cjs +60 -0
- package/dist/enviveConfigContext-jBCCWQH9.js +45 -0
- package/dist/events/index.cjs +1 -1
- package/dist/events/index.d.ts +1 -1
- package/dist/events/index.js +1 -1
- package/dist/{events-BrLpaNxh.js → events-BHJJjPDN.js} +1 -1
- package/dist/{events-DwT6cEwI.cjs → events-B_fJZf9E.cjs} +1 -1
- package/dist/featureFlagServiceContext-ChL7DJ53.cjs +56 -0
- package/dist/featureFlagServiceContext-D1PzHsEs.d.ts +23 -0
- package/dist/featureFlagServiceContext-DQwlCTde.d.cts +23 -0
- package/dist/featureFlagServiceContext-DzFfmb1Z.js +42 -0
- package/dist/featureGates-Blx10fwB.js +27 -0
- package/dist/featureGates-DcZNrUma.cjs +33 -0
- package/dist/frontendConfig-DrvrQSm8.d.ts +857 -0
- package/dist/frontendConfig-wg41mBok.d.cts +857 -0
- package/dist/{globalSearch-BFvEg53C.cjs → globalSearch-Bnjlxtr5.cjs} +1 -1
- package/dist/{globalSearch-B6THR7Jx.js → globalSearch-CRWUqnjq.js} +1 -1
- package/dist/graphql-B9HhDXYt.cjs +53 -0
- package/dist/graphql-W7GMIHUu.js +36 -0
- package/dist/graphqlConfig-Bn-HLHsh.cjs +39 -0
- package/dist/graphqlConfig-DtZm_YaH.js +14 -0
- package/dist/graphqlContext-BJg7B--J.js +96 -0
- package/dist/graphqlContext-DI-_VRmb.cjs +111 -0
- package/dist/hooks/AmplitudeOperations/index.cjs +21 -0
- package/dist/hooks/AmplitudeOperations/index.d.cts +12 -0
- package/dist/hooks/AmplitudeOperations/index.d.ts +12 -0
- package/dist/hooks/AmplitudeOperations/index.js +21 -0
- package/dist/hooks/AppDetails/index.cjs +18 -0
- package/dist/hooks/AppDetails/index.d.cts +26 -0
- package/dist/hooks/AppDetails/index.d.ts +26 -0
- package/dist/hooks/AppDetails/index.js +18 -0
- package/dist/hooks/BlockBackButton/index.cjs +29 -0
- package/dist/hooks/BlockBackButton/index.d.cts +5 -0
- package/dist/hooks/BlockBackButton/index.d.ts +5 -0
- package/dist/hooks/BlockBackButton/index.js +27 -0
- package/dist/hooks/CdnOperations/index.cjs +24 -0
- package/dist/hooks/CdnOperations/index.d.cts +7 -0
- package/dist/hooks/CdnOperations/index.d.ts +7 -0
- package/dist/hooks/CdnOperations/index.js +22 -0
- package/dist/hooks/ChatToggle/index.cjs +63 -0
- package/dist/hooks/ChatToggle/index.d.cts +12 -0
- package/dist/hooks/ChatToggle/index.d.ts +12 -0
- package/dist/hooks/ChatToggle/index.js +61 -0
- package/dist/hooks/ChatToggleAnalytics/index.cjs +37 -0
- package/dist/hooks/ChatToggleAnalytics/index.d.cts +9 -0
- package/dist/hooks/ChatToggleAnalytics/index.d.ts +9 -0
- package/dist/hooks/ChatToggleAnalytics/index.js +35 -0
- package/dist/hooks/CustomerSupportHandoff/index.cjs +36 -0
- package/dist/hooks/CustomerSupportHandoff/index.d.cts +16 -0
- package/dist/hooks/CustomerSupportHandoff/index.d.ts +16 -0
- package/dist/hooks/CustomerSupportHandoff/index.js +34 -0
- package/dist/hooks/Debounce/index.cjs +3 -0
- package/dist/hooks/Debounce/index.d.cts +5 -0
- package/dist/hooks/Debounce/index.d.ts +5 -0
- package/dist/hooks/Debounce/index.js +3 -0
- package/dist/hooks/ElementObserver/index.cjs +179 -0
- package/dist/hooks/ElementObserver/index.d.cts +29 -0
- package/dist/hooks/ElementObserver/index.d.ts +29 -0
- package/dist/hooks/ElementObserver/index.js +177 -0
- package/dist/hooks/GrabAndScroll/index.cjs +99 -0
- package/dist/hooks/GrabAndScroll/index.d.cts +14 -0
- package/dist/hooks/GrabAndScroll/index.d.ts +14 -0
- package/dist/hooks/GrabAndScroll/index.js +97 -0
- package/dist/hooks/GraphQLConfig/index.cjs +16 -0
- package/dist/hooks/GraphQLConfig/index.d.cts +15 -0
- package/dist/hooks/GraphQLConfig/index.d.ts +15 -0
- package/dist/hooks/GraphQLConfig/index.js +15 -0
- package/dist/hooks/IdentifyUser/index.cjs +59 -0
- package/dist/hooks/IdentifyUser/index.d.cts +10 -0
- package/dist/hooks/IdentifyUser/index.d.ts +10 -0
- package/dist/hooks/IdentifyUser/index.js +57 -0
- package/dist/hooks/ImageResolver/index.cjs +54 -0
- package/dist/hooks/ImageResolver/index.d.cts +7 -0
- package/dist/hooks/ImageResolver/index.d.ts +7 -0
- package/dist/hooks/ImageResolver/index.js +52 -0
- package/dist/hooks/Intersection/index.cjs +3 -0
- package/dist/hooks/Intersection/index.d.cts +7 -0
- package/dist/hooks/Intersection/index.d.ts +7 -0
- package/dist/hooks/Intersection/index.js +3 -0
- package/dist/hooks/IsSmallScreen/index.cjs +22 -0
- package/dist/hooks/IsSmallScreen/index.d.cts +5 -0
- package/dist/hooks/IsSmallScreen/index.d.ts +5 -0
- package/dist/hooks/IsSmallScreen/index.js +20 -0
- package/dist/hooks/LocalStorageOperations/index.cjs +79 -0
- package/dist/hooks/LocalStorageOperations/index.d.cts +17 -0
- package/dist/hooks/LocalStorageOperations/index.d.ts +17 -0
- package/dist/hooks/LocalStorageOperations/index.js +74 -0
- package/dist/hooks/MessageFilter/index.cjs +53 -0
- package/dist/hooks/MessageFilter/index.d.cts +29 -0
- package/dist/hooks/MessageFilter/index.d.ts +29 -0
- package/dist/hooks/MessageFilter/index.js +53 -0
- package/dist/hooks/MessageScrollObserver/index.cjs +36 -0
- package/dist/hooks/MessageScrollObserver/index.d.cts +5 -0
- package/dist/hooks/MessageScrollObserver/index.d.ts +5 -0
- package/dist/hooks/MessageScrollObserver/index.js +34 -0
- package/dist/hooks/NewOrgConfig/index.cjs +19 -0
- package/dist/hooks/NewOrgConfig/index.d.cts +22 -0
- package/dist/hooks/NewOrgConfig/index.d.ts +22 -0
- package/dist/hooks/NewOrgConfig/index.js +19 -0
- package/dist/hooks/Search/index.cjs +324 -0
- package/dist/hooks/Search/index.d.cts +66 -0
- package/dist/hooks/Search/index.d.ts +66 -0
- package/dist/hooks/Search/index.js +321 -0
- package/dist/hooks/SearchOperations/index.cjs +101 -0
- package/dist/hooks/SearchOperations/index.d.cts +22 -0
- package/dist/hooks/SearchOperations/index.d.ts +22 -0
- package/dist/hooks/SearchOperations/index.js +98 -0
- package/dist/hooks/SessionStorageOperations/index.cjs +30 -0
- package/dist/hooks/SessionStorageOperations/index.d.cts +8 -0
- package/dist/hooks/SessionStorageOperations/index.d.ts +8 -0
- package/dist/hooks/SessionStorageOperations/index.js +28 -0
- package/dist/hooks/ShopifyUrlOperations/index.cjs +53 -0
- package/dist/hooks/ShopifyUrlOperations/index.d.cts +23 -0
- package/dist/hooks/ShopifyUrlOperations/index.d.ts +23 -0
- package/dist/hooks/ShopifyUrlOperations/index.js +49 -0
- package/dist/hooks/SnapCalculator/index.cjs +29 -0
- package/dist/hooks/SnapCalculator/index.d.cts +12 -0
- package/dist/hooks/SnapCalculator/index.d.ts +12 -0
- package/dist/hooks/SnapCalculator/index.js +27 -0
- package/dist/hooks/SystemSettingsContext/index.cjs +7 -0
- package/dist/hooks/SystemSettingsContext/index.d.cts +22 -0
- package/dist/hooks/SystemSettingsContext/index.d.ts +22 -0
- package/dist/hooks/SystemSettingsContext/index.js +7 -0
- package/dist/hooks/TrackComponentVisibleEvent/index.cjs +21 -0
- package/dist/hooks/TrackComponentVisibleEvent/index.d.cts +18 -0
- package/dist/hooks/TrackComponentVisibleEvent/index.d.ts +18 -0
- package/dist/hooks/TrackComponentVisibleEvent/index.js +21 -0
- package/dist/hooks/UpdateAnalyticsProps/index.cjs +61 -0
- package/dist/hooks/UpdateAnalyticsProps/index.d.cts +9 -0
- package/dist/hooks/UpdateAnalyticsProps/index.d.ts +9 -0
- package/dist/hooks/UpdateAnalyticsProps/index.js +58 -0
- package/dist/index-BCLaqnc2.d.cts +689 -0
- package/dist/{index-ylUiJvnr.d.ts → index-BS7-_CW4.d.ts} +1 -1
- package/dist/index-Bmub8e38.d.cts +1 -1
- package/dist/index-Bs0QtkSu.d.ts +689 -0
- package/dist/index-CESxqFso.d.cts +1 -1
- package/dist/index-CKeS9dud.d.ts +28 -0
- package/dist/index-CiWEYzXl.d.cts +1 -1
- package/dist/index-CyXULMyI.d.cts +186 -0
- package/dist/index-Cz10TYQA.d.cts +28 -0
- package/dist/{index-B0NW9KTj.d.cts → index-D46Rd0io.d.cts} +1 -1
- package/dist/{index-C6KdON7d.d.ts → index-D8ThXrqI.d.ts} +1 -1
- package/dist/{index-PGF8BvxQ.d.ts → index-D9VegTU-.d.ts} +1 -1
- package/dist/{index-DOii3C6b.d.ts → index-DBqgBV9N.d.ts} +1 -1
- package/dist/{index-Cqg6ltII.d.ts → index-DNUKSg6R.d.ts} +1 -1
- package/dist/{index-BDPWBU3h.d.cts → index-DO0s5KNA.d.cts} +1 -1
- package/dist/{index-CcIG01PJ.d.ts → index-DuyZQOE1.d.ts} +2 -2
- package/dist/{index-Byb45OPg.d.cts → index-REhT-Pls.d.cts} +1 -1
- package/dist/index-fKJB9EFb.d.ts +186 -0
- package/dist/interceptors/index.cjs +2 -1
- package/dist/interceptors/index.d.cts +9 -10
- package/dist/interceptors/index.d.ts +12 -13
- package/dist/interceptors/index.js +2 -1
- package/dist/interceptors/types.cjs +1 -0
- package/dist/interceptors/types.d.cts +12 -0
- package/dist/interceptors/types.d.ts +12 -0
- package/dist/interceptors/types.js +3 -0
- package/dist/localStorageContext-6OrGDFid.js +95 -0
- package/dist/localStorageContext-Bld0OWmG.cjs +115 -0
- package/dist/logger-CSL2jqI9.cjs +26 -0
- package/dist/logger-D5MFf3nW.js +20 -0
- package/dist/{models-BkXg5eIP.cjs → models-Dn8Emdzc.js} +219 -458
- package/dist/models-ZpQcRZQK.cjs +1536 -0
- package/dist/newOrgConfigAtom--tewb_G0.js +8 -0
- package/dist/newOrgConfigAtom-DkSi45_Q.cjs +15 -0
- package/dist/newOrgConfigContext-B3aeblfE.cjs +68 -0
- package/dist/newOrgConfigContext-B5mzHKTG.js +53 -0
- package/dist/{nodeSelector-BxrS2S_k.d.ts → nodeSelector-DybpVr-i.d.ts} +1 -1
- package/dist/{nodeSelector-Dm4S-10n.d.cts → nodeSelector-XsUa5vNH.d.cts} +1 -1
- package/dist/org-B2uRkPt3.js +12 -0
- package/dist/org-ClUxpHPZ.cjs +43 -0
- package/dist/{orgAnalyticsConfig-BJ2A1RZ-.cjs → orgAnalyticsConfig-CuWXijsr.cjs} +1 -1
- package/dist/{orgAnalyticsConfig-ClrFy2qH.js → orgAnalyticsConfig-DOceTdNp.js} +1 -1
- package/dist/search-BIomqYy6.d.ts +20 -0
- package/dist/search-B_Hg-Es2.d.cts +20 -0
- package/dist/search-Bn4x-3TG.js +126 -0
- package/dist/search-DsQm_pAi.cjs +205 -0
- package/dist/{search-filter-types-fZf91Pdw.d.ts → search-filter-types-B5xcaEit.d.ts} +1 -1
- package/dist/{search-filter-types-DosbseF3.d.cts → search-filter-types-Byd0lEUa.d.cts} +1 -1
- package/dist/searchContext-Cn-pCoDy.cjs +145 -0
- package/dist/searchContext-fQDGSvUF.js +129 -0
- package/dist/searchServiceAdapter-BSPZOg1r.js +16 -0
- package/dist/searchServiceAdapter-DrjFCiw8.cjs +34 -0
- package/dist/sessionStorageContext-C5MUl2zf.js +52 -0
- package/dist/sessionStorageContext-CXE7iHtP.cjs +66 -0
- package/dist/shopifyUrlContext-7ppKx1jJ.cjs +75 -0
- package/dist/shopifyUrlContext-BSYWsoX9.js +61 -0
- package/dist/spiffyWidgets-CdxRcXhW.d.ts +20 -0
- package/dist/spiffyWidgets-DxGuuuCG.d.cts +20 -0
- package/dist/systemSettingsContext-BdAe_3Ll.cjs +60 -0
- package/dist/systemSettingsContext-Cjyo2o3N.js +39 -0
- package/dist/{test-types-CgVJtwUr.d.cts → test-types-DQB1JqOf.d.cts} +1 -1
- package/dist/{test-types-C9b_OdfO.d.ts → test-types-ZuRAYwox.d.ts} +1 -1
- package/dist/types/index.cjs +33 -5
- package/dist/types/index.d.cts +2 -2
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.js +30 -3
- package/dist/types-BCz-hOvv.d.ts +51 -0
- package/dist/types-BwNrLPSZ.cjs +106 -0
- package/dist/types-D3uOF0Oy.js +76 -0
- package/dist/types-DIk0FLwd.js +30 -0
- package/dist/types-DNLkuGWZ.cjs +48 -0
- package/dist/types-DzwBmZHy.d.cts +10 -0
- package/dist/types-Eip78dWv.d.cts +51 -0
- package/dist/types-YvACLe2e.d.ts +10 -0
- package/dist/types.d.cts +15 -0
- package/dist/types.d.ts +15 -0
- package/dist/unsupportedProductExceptions--t7AQFou.js +20 -0
- package/dist/unsupportedProductExceptions-Dak4AD-t.cjs +32 -0
- package/dist/urlsParser-BV5yF8sa.cjs +78 -0
- package/dist/urlsParser-DUgV_Qy9.js +42 -0
- package/dist/useAmplitudeOperations-C6Osqkso.js +34 -0
- package/dist/useAmplitudeOperations-Cco_B3A5.cjs +41 -0
- package/dist/useAppDetails-CGqtN6sJ.cjs +38 -0
- package/dist/useAppDetails-DwX2Rhed.js +30 -0
- package/dist/useDebounce-BJqnCBcl.cjs +26 -0
- package/dist/useDebounce-Ce31ph7m.js +19 -0
- package/dist/useGraphQLConfig-ByOZb3oZ.js +63 -0
- package/dist/useGraphQLConfig-DItL4BgM.cjs +76 -0
- package/dist/useIntersection-Czeo04jt.js +21 -0
- package/dist/useIntersection-DnZNLcnu.cjs +28 -0
- package/dist/{useMessageInterceptor-B87e3yu3.cjs → useMessageInterceptor-C9p9No1n.cjs} +3 -3
- package/dist/{useMessageInterceptor-Bb7YRaWk.js → useMessageInterceptor-tntd2rvB.js} +2 -2
- package/dist/userIdentityContext-C1HzZFb2.cjs +125 -0
- package/dist/userIdentityContext-CDfosvOO.js +109 -0
- package/dist/userIdentityContext-DBXoLrFu.d.cts +20 -0
- package/dist/userIdentityContext-W1OWF3cG.d.ts +20 -0
- package/dist/utilityTypes-CWJZb9BZ.js +1 -0
- package/dist/utilityTypes-YGiMSyV7.cjs +0 -0
- package/dist/utils-BA5HXmkL.cjs +74 -0
- package/dist/utils-BTDw2aMx.cjs +715 -0
- package/dist/utils-C7S9YiFp.js +54 -0
- package/dist/utils-CF13DfA1.js +606 -0
- package/dist/variantInfo-58JLeDJb.js +1 -0
- package/dist/variantInfo-DRFLcGc7.cjs +0 -0
- package/package.json +179 -7
- package/src/application/models/index.ts +0 -1
- package/src/application/utils/analyticsUtils.ts +1 -1
- package/src/atoms/amplitude/amplitudeTrackEventAtom.ts +1 -1
- package/src/atoms/app/index.ts +1 -1
- package/src/atoms/chat/chatState.ts +1 -1
- package/src/atoms/chat/replies.ts +1 -1
- package/src/atoms/org/graphqlConfig.ts +1 -39
- package/src/atoms/org/index.ts +0 -1
- package/src/atoms/org/newOrgConfigAtom.ts +2 -6
- package/src/contexts/{amplitudeContext.tsx → amplitudeContext/amplitudeContext.tsx} +1 -2
- package/src/contexts/amplitudeContext/index.ts +1 -0
- package/src/contexts/{cdnContext.tsx → cdnContext/cdnContext.tsx} +1 -1
- package/src/contexts/cdnContext/index.ts +1 -0
- package/src/contexts/{chatContext.tsx → chatContext/chatContext.tsx} +3 -3
- package/src/contexts/chatContext/index.ts +1 -0
- package/src/contexts/{enviveConfigContext.tsx → enviveConfigContext/enviveConfigContext.tsx} +1 -1
- package/src/contexts/enviveConfigContext/index.ts +1 -0
- package/src/contexts/{enviveCssContext.tsx → enviveCssContext/enviveCssContext.tsx} +1 -1
- package/src/contexts/enviveCssContext/index.ts +1 -0
- package/src/contexts/{featureFlagContext.tsx → featureFlagContext/featureFlagContext.tsx} +1 -1
- package/src/contexts/featureFlagContext/index.ts +1 -0
- package/src/contexts/featureFlagServiceContext/index.ts +1 -0
- package/src/contexts/graphqlContext/index.ts +1 -0
- package/src/contexts/localStorageContext/index.ts +1 -0
- package/src/contexts/{localStorageContext.tsx → localStorageContext/localStorageContext.tsx} +2 -2
- package/src/contexts/newOrgConfigContext/index.ts +1 -0
- package/src/contexts/newOrgConfigContext/newOrgConfigContext.tsx +70 -0
- package/src/contexts/searchContext/index.ts +1 -0
- package/src/contexts/{searchContext.tsx → searchContext/searchContext.tsx} +5 -5
- package/src/contexts/sessionStorageContext/index.ts +1 -0
- package/src/contexts/{sessionStorageContext.tsx → sessionStorageContext/sessionStorageContext.tsx} +1 -1
- package/src/contexts/shopifyUrlContext/index.ts +1 -0
- package/src/contexts/systemSettingsContext/index.ts +1 -0
- package/src/contexts/userIdentityContext/index.ts +1 -0
- package/src/events/registerAnalyticsListeners.ts +2 -2
- package/src/favicon.ico +0 -0
- package/src/hooks/AmplitudeOperations/index.ts +1 -0
- package/src/hooks/{useAmplitudeOperations.ts → AmplitudeOperations/useAmplitudeOperations.ts} +1 -1
- package/src/hooks/AppDetails/index.ts +1 -0
- package/src/hooks/{useAppDetails.ts → AppDetails/useAppDetails.ts} +1 -3
- package/src/hooks/BlockBackButton/index.ts +1 -0
- package/src/hooks/CdnOperations/index.ts +1 -0
- package/src/hooks/{useCdnOperations.ts → CdnOperations/useCdnOperations.ts} +1 -1
- package/src/hooks/ChatToggle/index.ts +1 -0
- package/src/hooks/{useChatToggle.ts → ChatToggle/useChatToggle.ts} +1 -1
- package/src/hooks/ChatToggleAnalytics/index.ts +1 -0
- package/src/hooks/{useChatToggleAnalytics.ts → ChatToggleAnalytics/useChatToggleAnalytics.ts} +1 -1
- package/src/hooks/CustomerSupportHandoff/index.ts +1 -0
- package/src/hooks/Debounce/index.ts +1 -0
- package/src/hooks/ElementObserver/index.ts +1 -0
- package/src/hooks/GrabAndScroll/index.ts +1 -0
- package/src/hooks/GraphQLConfig/index.ts +1 -0
- package/src/hooks/{useGraphQLConfig.ts → GraphQLConfig/useGraphQLConfig.ts} +1 -1
- package/src/hooks/IdentifyUser/index.ts +1 -0
- package/src/hooks/{useIdentifyUser.ts → IdentifyUser/useIdentifyUser.ts} +1 -1
- package/src/hooks/ImageResolver/index.ts +1 -0
- package/src/hooks/Intersection/index.ts +1 -0
- package/src/hooks/IsSmallScreen/index.ts +1 -0
- package/src/hooks/LocalStorageOperations/index.ts +1 -0
- package/src/hooks/{useLocalStorageOperations.ts → LocalStorageOperations/useLocalStorageOperations.ts} +2 -2
- package/src/hooks/MessageFilter/index.ts +1 -0
- package/src/hooks/MessageScrollObserver/index.ts +1 -0
- package/src/hooks/NewOrgConfig/index.ts +1 -0
- package/src/hooks/{useNewOrgConfig.ts → NewOrgConfig/useNewOrgConfig.ts} +1 -1
- package/src/hooks/Search/index.ts +1 -0
- package/src/hooks/{useSearch.tsx → Search/useSearch.tsx} +5 -4
- package/src/hooks/SearchOperations/index.ts +1 -0
- package/src/hooks/SessionStorageOperations/index.ts +1 -0
- package/src/hooks/{useSessionStorageOperations.ts → SessionStorageOperations/useSessionStorageOperations.ts} +1 -1
- package/src/hooks/ShopifyUrlOperations/index.ts +1 -0
- package/src/hooks/{useShopifyUrlOperations.ts → ShopifyUrlOperations/useShopifyUrlOperations.ts} +1 -1
- package/src/hooks/SnapCalculator/index.ts +1 -0
- package/src/hooks/SystemSettingsContext/index.ts +1 -0
- package/src/hooks/SystemSettingsContext/useSystemSettingsContext.ts +14 -0
- package/src/hooks/TrackComponentVisibleEvent/index.ts +1 -0
- package/src/hooks/{useTrackComponentVisibleEvent.ts → TrackComponentVisibleEvent/useTrackComponentVisibleEvent.ts} +2 -2
- package/src/hooks/UpdateAnalyticsProps/index.ts +1 -0
- package/src/hooks/{useUpdateAnalyticsProps.ts → UpdateAnalyticsProps/useUpdateAnalyticsProps.ts} +1 -1
- package/dist/amplitudeContext-CHzas7Cf.d.cts +0 -52
- package/dist/amplitudeContext-D-7fmVh1.cjs +0 -356
- package/dist/amplitudeContext-hY3caPC6.js +0 -322
- package/dist/amplitudeContext-tJ4y-SzX.d.ts +0 -52
- package/dist/api-DjeZXxl_.js +0 -207
- package/dist/api-_JaUnIUj.cjs +0 -292
- package/dist/bandolier-DYEz4-8C.js +0 -1229
- package/dist/bandolier-o_-xrbOV.cjs +0 -1229
- package/dist/carpe-CsG5jCcl.cjs +0 -607
- package/dist/carpe-DONk00bZ.js +0 -605
- package/dist/cdnUtils-32v8bDX9.cjs +0 -16
- package/dist/cdnUtils-E4tLBt2g.js +0 -11
- package/dist/chat-CO7cRkaq.cjs +0 -506
- package/dist/chat-hcRc4RRd.js +0 -285
- package/dist/contexts/index.cjs +0 -57
- package/dist/contexts/index.d.cts +0 -10
- package/dist/contexts/index.d.ts +0 -10
- package/dist/contexts/index.js +0 -23
- package/dist/contexts-B4ihTBsV.cjs +0 -2980
- package/dist/contexts-DGlr7M1o.js +0 -2596
- package/dist/coterie-CKB93qfz.cjs +0 -239
- package/dist/coterie-DHcj2fRE.js +0 -239
- package/dist/custservice-types-Dy0kc9TW.cjs +0 -35
- package/dist/custservice-types-mnIunabv.js +0 -23
- package/dist/default-BnB4p0Se.cjs +0 -234
- package/dist/default-D6f5Dyt7.js +0 -199
- package/dist/default-ZKkE5zT4.cjs +0 -4
- package/dist/default-legGZJwI.js +0 -4
- package/dist/divIds-2dJlU3z8.cjs +0 -117
- package/dist/divIds-BUrN2vY-.js +0 -21
- package/dist/dreamlandBaby-BiRYYFav.js +0 -346
- package/dist/dreamlandBaby-zuvmfzfD.cjs +0 -346
- package/dist/embedded-BJLWIriJ.js +0 -23
- package/dist/embedded-Dl79TJLC.cjs +0 -131
- package/dist/entrypoints-Bs3pn6EV.js +0 -7
- package/dist/entrypoints-Dqi5pzWH.cjs +0 -19
- package/dist/enviveConfig-BccuzS2a.cjs +0 -240
- package/dist/enviveConfig-CzhTz8Aa.js +0 -152
- package/dist/fiveCbd-DwTTwC2j.cjs +0 -613
- package/dist/fiveCbd-Dz2NouOF.js +0 -613
- package/dist/forLoveAndLemons-DqSdyD6S.js +0 -665
- package/dist/forLoveAndLemons-Ud6mPrV3.cjs +0 -667
- package/dist/graphql-BNW60InJ.cjs +0 -128
- package/dist/graphql-CjB8wHzm.js +0 -74
- package/dist/graphqlConfig-CYt6tWII.js +0 -30
- package/dist/graphqlConfig-DicykC-o.cjs +0 -61
- package/dist/greenpan-B_EbPkSP.js +0 -397
- package/dist/greenpan-kPE4fJgd.cjs +0 -397
- package/dist/grooveLife-Ckuir319.js +0 -342
- package/dist/grooveLife-DKSEQp1F.cjs +0 -342
- package/dist/homegrownCannabis-BVPa2pqe.js +0 -410
- package/dist/homegrownCannabis-BwIAkxuA.cjs +0 -410
- package/dist/hooks/index.cjs +0 -63
- package/dist/hooks/index.d.cts +0 -314
- package/dist/hooks/index.d.ts +0 -314
- package/dist/hooks/index.js +0 -23
- package/dist/index-BMPtlgac.d.ts +0 -191
- package/dist/index-C7pGDl1A.d.ts +0 -1609
- package/dist/index-C9lgsCWp.d.cts +0 -203
- package/dist/index-Cc-wBCn6.d.ts +0 -203
- package/dist/index-DTu2X-YS.d.cts +0 -1609
- package/dist/index-OEifcBsm.d.cts +0 -191
- package/dist/jackArcher-B39OEIj6.cjs +0 -727
- package/dist/jackArcher-BwkWGybC.js +0 -727
- package/dist/jordanCraig-CxRH_jLi.js +0 -1786
- package/dist/jordanCraig-RwmWw-jM.cjs +0 -1786
- package/dist/kindredBravely-D78VwL20.cjs +0 -490
- package/dist/kindredBravely-DQDpAzdl.js +0 -490
- package/dist/kutFromTheKloth-TcXQkIti.js +0 -369
- package/dist/kutFromTheKloth-dXRrNti0.cjs +0 -369
- package/dist/larryAndSerges-Bh5XEXsZ.js +0 -262
- package/dist/larryAndSerges-COdBzOzu.cjs +0 -262
- package/dist/leapsAndRebounds-BbXnqkl5.cjs +0 -360
- package/dist/leapsAndRebounds-mjCaH1k-.js +0 -360
- package/dist/longevityrx-DdV3v26F.cjs +0 -320
- package/dist/longevityrx-DfPDfvAt.js +0 -320
- package/dist/lookOptic-DgXFGBPP.cjs +0 -282
- package/dist/lookOptic-FgVW1afF.js +0 -282
- package/dist/mantraBrand-C5gVm3rk.cjs +0 -750
- package/dist/mantraBrand-uV8HCDR8.js +0 -750
- package/dist/medterra-BtDpr1Hw.cjs +0 -583
- package/dist/medterra-DgzE7-mj.js +0 -583
- package/dist/modells-CJjsxOIR.js +0 -484
- package/dist/modells-Ck5KbRFj.cjs +0 -484
- package/dist/models-UZ6HszfZ.js +0 -1281
- package/dist/org-C2RrBVQR.cjs +0 -81
- package/dist/org-xMytX--e.js +0 -38
- package/dist/pressedFloral-Bteoboms.js +0 -661
- package/dist/pressedFloral-CexgV-xy.cjs +0 -661
- package/dist/search-BMOAmrmY.js +0 -459
- package/dist/search-Df0Ifneg.cjs +0 -672
- package/dist/skinPerfection-BGzq9lq-.cjs +0 -334
- package/dist/skinPerfection-BlvcEcUE.js +0 -334
- package/dist/snapSupplements-CbbGzAgO.cjs +0 -285
- package/dist/snapSupplements-kcsPAOm9.js +0 -285
- package/dist/socialProofClasses-Db8gzsfi.cjs +0 -40
- package/dist/socialProofClasses-kwDvwLOZ.js +0 -10
- package/dist/spanx-B4WFA_rI.js +0 -661
- package/dist/spanx-BWoE4F8b.cjs +0 -663
- package/dist/spanxStaging-BOrOjhXn.js +0 -845
- package/dist/spanxStaging-BfdfIug4.cjs +0 -848
- package/dist/suggestionBarV2-types-IMMOmCir.js +0 -10
- package/dist/suggestionBarV2-types-nnGNgFvR.cjs +0 -16
- package/dist/supergoop-22dd5_BS.js +0 -323
- package/dist/supergoop-B-a4cku2.cjs +0 -323
- package/dist/types--pr1GQQx.js +0 -154
- package/dist/types-BVSyY3Hk.cjs +0 -196
- package/dist/uniqueVintage-CJXiNNe7.js +0 -1211
- package/dist/uniqueVintage-D0jzJWlo.cjs +0 -1213
- package/dist/userIdentityContext-BPqvVIg0.d.cts +0 -20
- package/dist/userIdentityContext-wbCRmlzp.d.ts +0 -20
- package/dist/utils-C9ZSCx12.js +0 -888
- package/dist/utils-D5HO61hG.cjs +0 -1016
- package/dist/venaCbd-Bhhu_qUf.cjs +0 -365
- package/dist/venaCbd-CanovPS_.js +0 -365
- package/dist/westonJonBoucher-BC0x1ktI.cjs +0 -422
- package/dist/westonJonBoucher-BUu1_wP1.js +0 -422
- package/dist/wineEnthusiast-BlCryfil.cjs +0 -940
- package/dist/wineEnthusiast-Ck1x5iJq.js +0 -940
- package/dist/wolfMattress-D9Mjq-HP.js +0 -372
- package/dist/wolfMattress-JssghhC-.cjs +0 -372
- package/dist/wolfTactical-C6exYhL7.cjs +0 -349
- package/dist/wolfTactical-CnV3KQdI.js +0 -349
- package/src/application/models/supportedOrgs.ts +0 -161
- package/src/atoms/org/orgPageConfig.ts +0 -42
- package/src/contexts/index.ts +0 -16
- package/src/contexts/newOrgConfigContext.tsx +0 -104
- package/src/contexts/orgConfigContext.tsx +0 -106
- package/src/hooks/index.ts +0 -27
- package/src/hooks/useSystemSettingsContext.ts +0 -12
- package/src/merchants/bandolier/bandolier.ts +0 -1371
- package/src/merchants/carpe/carpe.ts +0 -653
- package/src/merchants/coterie/coterie.ts +0 -277
- package/src/merchants/default.ts +0 -196
- package/src/merchants/dreamlandBaby/dreamlandBaby.ts +0 -381
- package/src/merchants/fiveCbd/fiveCbd.ts +0 -691
- package/src/merchants/forLoveAndLemons/forLoveAndLemons.ts +0 -751
- package/src/merchants/greenpan/greenpan.ts +0 -434
- package/src/merchants/grooveLife/grooveLife.ts +0 -392
- package/src/merchants/homegrownCannabis/homegrownCannabis.ts +0 -474
- package/src/merchants/init-merchant.sh +0 -53
- package/src/merchants/jackArcher/jackArcher.ts +0 -989
- package/src/merchants/jordanCraig/jordanCraig.ts +0 -1927
- package/src/merchants/kindredBravely/kindredBravely.ts +0 -538
- package/src/merchants/kutFromTheKloth/kutFromTheKloth.ts +0 -421
- package/src/merchants/larryAndSerges/larryAndSerges.ts +0 -318
- package/src/merchants/leapsAndRebounds/leapsAndRebounds.ts +0 -424
- package/src/merchants/longevityrx/longevityrx.ts +0 -374
- package/src/merchants/lookOptic/lookOptic.ts +0 -323
- package/src/merchants/mantraBrand/mantraBrand.ts +0 -844
- package/src/merchants/medterra/medterra.ts +0 -673
- package/src/merchants/modells/modells.ts +0 -543
- package/src/merchants/pressedFloral/pressedFloral.ts +0 -728
- package/src/merchants/skinPerfection/skinPerfection.ts +0 -385
- package/src/merchants/snapSupplements/snapSupplements.ts +0 -328
- package/src/merchants/spanx/spanx.ts +0 -810
- package/src/merchants/spanx/spanxStaging.ts +0 -936
- package/src/merchants/supergoop/supergoop.ts +0 -375
- package/src/merchants/uniqueVintage/uniqueVintage.ts +0 -1314
- package/src/merchants/venaCbd/venaCbd.ts +0 -407
- package/src/merchants/westonJonBoucher/westonJonBoucher.ts +0 -473
- package/src/merchants/wineEnthusiast/wineEnthusiast.ts +0 -990
- package/src/merchants/wolfMattress/wolfMattress.ts +0 -411
- package/src/merchants/wolfTactical/wolfTactical.ts +0 -383
- /package/dist/{atomStore-KSoFS3Jj.cjs → AmplitudeOperations-CgIVPUlr.cjs} +0 -0
- /package/dist/{atomStore-CZnUUsrr.js → AmplitudeOperations-YpyaR7Mp.js} +0 -0
- /package/dist/{locators-fBXS_pxP.js → atomStore-C2OI76yN.js} +0 -0
- /package/dist/{locators-0YYZu9n4.cjs → atomStore-DWmT1six.cjs} +0 -0
- /package/dist/{utilityTypes-8sETsYPk.js → types-DQoXDiso.js} +0 -0
- /package/dist/{utilityTypes-COShxVir.cjs → types-o3zWarRp.cjs} +0 -0
- /package/dist/{variantInfo-orXoPBCU.cjs → types.cjs} +0 -0
- /package/dist/{variantInfo-DbVxA1yE.js → types.js} +0 -0
- /package/src/contexts/{featureFlagServiceContext.tsx → featureFlagServiceContext/featureFlagServiceContext.tsx} +0 -0
- /package/src/contexts/{graphqlContext.tsx → graphqlContext/graphqlContext.tsx} +0 -0
- /package/src/contexts/{shopifyUrlContext.tsx → shopifyUrlContext/shopifyUrlContext.tsx} +0 -0
- /package/src/contexts/{systemSettingsContext.tsx → systemSettingsContext/systemSettingsContext.tsx} +0 -0
- /package/src/contexts/{userIdentityContext.tsx → userIdentityContext/userIdentityContext.tsx} +0 -0
- /package/src/hooks/{useBlockBackButton.ts → BlockBackButton/useBlockBackButton.ts} +0 -0
- /package/src/hooks/{useCustomerSupportHandoff.ts → CustomerSupportHandoff/useCustomerSupportHandoff.ts} +0 -0
- /package/src/hooks/{useDebounce.ts → Debounce/useDebounce.ts} +0 -0
- /package/src/hooks/{useElementObserver.ts → ElementObserver/useElementObserver.ts} +0 -0
- /package/src/hooks/{useGrabAndScroll.ts → GrabAndScroll/useGrabAndScroll.ts} +0 -0
- /package/src/hooks/{useImageResolver.ts → ImageResolver/useImageResolver.ts} +0 -0
- /package/src/hooks/{useIntersection.ts → Intersection/useIntersection.ts} +0 -0
- /package/src/hooks/{useIsSmallScreen.ts → IsSmallScreen/useIsSmallScreen.ts} +0 -0
- /package/src/hooks/{useMessageFilter.ts → MessageFilter/useMessageFilter.ts} +0 -0
- /package/src/hooks/{useMessageScrollObserver.ts → MessageScrollObserver/useMessageScrollObserver.ts} +0 -0
- /package/src/hooks/{useSearchOperations.ts → SearchOperations/useSearchOperations.ts} +0 -0
- /package/src/hooks/{useSnapCalculator.ts → SnapCalculator/useSnapCalculator.ts} +0 -0
|
@@ -1,2980 +0,0 @@
|
|
|
1
|
-
const require_chunk = require('./chunk-CUT6urMc.cjs');
|
|
2
|
-
const require_models = require('./models-BkXg5eIP.cjs');
|
|
3
|
-
const require_types = require('./types-BVSyY3Hk.cjs');
|
|
4
|
-
const require_graphql = require('./graphql-BNW60InJ.cjs');
|
|
5
|
-
const require_api = require('./api-_JaUnIUj.cjs');
|
|
6
|
-
const require_enviveConfig = require('./enviveConfig-BccuzS2a.cjs');
|
|
7
|
-
const require_atomStore = require('./atomStore-B4jIaDPd.cjs');
|
|
8
|
-
const require_app = require('./app-CnKRZ9RW.cjs');
|
|
9
|
-
const require_amplitudeContext = require('./amplitudeContext-D-7fmVh1.cjs');
|
|
10
|
-
const require_utils = require('./utils-D5HO61hG.cjs');
|
|
11
|
-
const require_graphqlConfig = require('./graphqlConfig-DicykC-o.cjs');
|
|
12
|
-
const require_chat = require('./chat-CO7cRkaq.cjs');
|
|
13
|
-
const require_org = require('./org-C2RrBVQR.cjs');
|
|
14
|
-
const require_search = require('./search-Df0Ifneg.cjs');
|
|
15
|
-
const require_globalSearch = require('./globalSearch-BFvEg53C.cjs');
|
|
16
|
-
const require_useMessageInterceptor = require('./useMessageInterceptor-B87e3yu3.cjs');
|
|
17
|
-
let react = require("react");
|
|
18
|
-
react = require_chunk.__toESM(react);
|
|
19
|
-
let jotai = require("jotai");
|
|
20
|
-
jotai = require_chunk.__toESM(jotai);
|
|
21
|
-
let __spiffy_ai_commerce_api_client = require("@spiffy-ai/commerce-api-client");
|
|
22
|
-
__spiffy_ai_commerce_api_client = require_chunk.__toESM(__spiffy_ai_commerce_api_client);
|
|
23
|
-
let react_jsx_runtime = require("react/jsx-runtime");
|
|
24
|
-
react_jsx_runtime = require_chunk.__toESM(react_jsx_runtime);
|
|
25
|
-
let uuid = require("uuid");
|
|
26
|
-
uuid = require_chunk.__toESM(uuid);
|
|
27
|
-
let ua_parser_js = require("ua-parser-js");
|
|
28
|
-
ua_parser_js = require_chunk.__toESM(ua_parser_js);
|
|
29
|
-
|
|
30
|
-
//#region src/contexts/cdnContext.tsx
|
|
31
|
-
const CdnContext = (0, react.createContext)(null);
|
|
32
|
-
const CdnProvider = ({ children }) => {
|
|
33
|
-
const cdnUrl = (0, jotai.useAtomValue)(require_enviveConfig.cdnUrlAtom) || "https://cdn.spiffy.ai/other";
|
|
34
|
-
const getCdnBasePath = (0, react.useCallback)(() => {
|
|
35
|
-
return cdnUrl;
|
|
36
|
-
}, [cdnUrl]);
|
|
37
|
-
const getAssetURL = (0, react.useCallback)((assetName, orgShortName) => {
|
|
38
|
-
return `${getCdnBasePath()}/assets/${orgShortName}/${assetName}`;
|
|
39
|
-
}, [getCdnBasePath]);
|
|
40
|
-
const value = (0, react.useMemo)(() => ({
|
|
41
|
-
cdnUrl,
|
|
42
|
-
getCdnBasePath,
|
|
43
|
-
getAssetURL
|
|
44
|
-
}), [
|
|
45
|
-
cdnUrl,
|
|
46
|
-
getCdnBasePath,
|
|
47
|
-
getAssetURL
|
|
48
|
-
]);
|
|
49
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CdnContext.Provider, {
|
|
50
|
-
value,
|
|
51
|
-
children
|
|
52
|
-
});
|
|
53
|
-
};
|
|
54
|
-
const useCdn = () => {
|
|
55
|
-
const context = (0, react.useContext)(CdnContext);
|
|
56
|
-
if (!context) throw new Error("useCdn must be used within a CdnProvider");
|
|
57
|
-
return context;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
//#endregion
|
|
61
|
-
//#region src/types/exceptions/sessionExceptions.ts
|
|
62
|
-
var SessionRestartRequired = class extends Error {
|
|
63
|
-
constructor() {
|
|
64
|
-
super("Session restart required");
|
|
65
|
-
this.name = "SessionRestartRequired";
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
//#endregion
|
|
70
|
-
//#region src/types/exceptions/unsupportedProductExceptions.ts
|
|
71
|
-
var UnsupportedProductException = class extends Error {
|
|
72
|
-
constructor() {
|
|
73
|
-
super("Unsupported product");
|
|
74
|
-
this.name = "UnsupportedProduct";
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
//#endregion
|
|
79
|
-
//#region src/application/commerce-api.ts
|
|
80
|
-
async function errorResponseBody$1(error) {
|
|
81
|
-
try {
|
|
82
|
-
return await error.response.json();
|
|
83
|
-
} catch {
|
|
84
|
-
return {};
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
async function throwSessionRestartRequiredIf$1(errorMsg, error) {
|
|
88
|
-
if (!(error instanceof __spiffy_ai_commerce_api_client.ResponseError)) {
|
|
89
|
-
require_api.logger_default.logInfo(errorMsg, error);
|
|
90
|
-
throw error;
|
|
91
|
-
}
|
|
92
|
-
const errorResponse = await errorResponseBody$1(error);
|
|
93
|
-
if (errorResponse?.message?.toLowerCase() === "unsupported product" || errorResponse?.app_code?.toUpperCase() === "PRODUCT_NOT_FOUND") throw new UnsupportedProductException();
|
|
94
|
-
else if (errorResponse?.app_code?.toUpperCase() === "RESTART_SESSION" || errorResponse?.sub_code?.toUpperCase() === "NOT_FOUND") {
|
|
95
|
-
require_api.logger_default.logInfo("Session does not exist. Re-start session", error, error.response, errorResponse);
|
|
96
|
-
throw new SessionRestartRequired();
|
|
97
|
-
}
|
|
98
|
-
require_api.logger_default.logInfo(errorMsg, error);
|
|
99
|
-
throw error;
|
|
100
|
-
}
|
|
101
|
-
var CommerceApiClient = class CommerceApiClient {
|
|
102
|
-
static {
|
|
103
|
-
this.getInstance = () => {
|
|
104
|
-
if (!CommerceApiClient.instance) CommerceApiClient.instance = new CommerceApiClient();
|
|
105
|
-
return CommerceApiClient.instance;
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
constructor(basePath) {
|
|
109
|
-
this.suggestionsAbortController = new AbortController();
|
|
110
|
-
this.responsesAbortController = new AbortController();
|
|
111
|
-
const baseUrl = require_atomStore.getAtomStore().get(require_enviveConfig.baseUrlAtom);
|
|
112
|
-
const config = new __spiffy_ai_commerce_api_client.Configuration({
|
|
113
|
-
basePath: basePath || baseUrl,
|
|
114
|
-
headers: {
|
|
115
|
-
"Content-Type": "application/json",
|
|
116
|
-
Accept: "application/json"
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
this.defaultApi = new __spiffy_ai_commerce_api_client.DefaultApi(config);
|
|
120
|
-
this.inferenceApi = new __spiffy_ai_commerce_api_client.InferenceApi(config);
|
|
121
|
-
this.customerServiceApi = new __spiffy_ai_commerce_api_client.CustomerServiceApi(config);
|
|
122
|
-
}
|
|
123
|
-
static {
|
|
124
|
-
this.resolveUrl = async (url) => {
|
|
125
|
-
const atomStore = require_atomStore.getAtomStore();
|
|
126
|
-
const orgShortName = atomStore.get(require_enviveConfig.orgShortNameAtom);
|
|
127
|
-
const orgId = atomStore.get(require_graphqlConfig.orgIdAtom);
|
|
128
|
-
const userId = atomStore.get(require_app.userIdAtom);
|
|
129
|
-
const chatId = atomStore.get(require_app.chatIdAtom);
|
|
130
|
-
const source = atomStore.get(require_enviveConfig.contextSourceAtom);
|
|
131
|
-
const env = atomStore.get(require_enviveConfig.envAtom);
|
|
132
|
-
const featureFlagService = atomStore.get(require_graphqlConfig.featureFlagServiceAtom);
|
|
133
|
-
const context = {
|
|
134
|
-
user_id: userId ?? "",
|
|
135
|
-
org_id: orgId ?? "",
|
|
136
|
-
org_short_name: orgShortName ?? "",
|
|
137
|
-
chat_id: chatId ?? "",
|
|
138
|
-
source: source ?? __spiffy_ai_commerce_api_client.ContextSourceEnum.App,
|
|
139
|
-
env: env ?? __spiffy_ai_commerce_api_client.ContextEnvEnum.Dev
|
|
140
|
-
};
|
|
141
|
-
const featureGates = featureFlagService?.featureFlagService?.getFeatureFlags() || {};
|
|
142
|
-
const urlResolvingRequest = {
|
|
143
|
-
url,
|
|
144
|
-
context,
|
|
145
|
-
feature_gates: featureGates
|
|
146
|
-
};
|
|
147
|
-
return await (await CommerceApiClient.getInstance().inferenceApi.v1UrlResolvingPostRaw({ UrlResolvingRequest: urlResolvingRequest })).raw.json();
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
static {
|
|
151
|
-
this.reportSession = async (reportRequest) => {
|
|
152
|
-
await CommerceApiClient.getInstance().defaultApi.v1ChatsReportSessionIdPost({ ReportSessionRequest: reportRequest });
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
static {
|
|
156
|
-
this.getNextResponses = async (payload) => {
|
|
157
|
-
try {
|
|
158
|
-
return (await CommerceApiClient.getInstance().inferenceApi.v1NextResponsesPost({ NextMessageRequest: require_utils.messageRequestToCommerceMessageRequest(payload) })).map((resp) => require_models.validateResponse(resp)).map((resp) => require_utils.messageFromResponse(resp)).filter((m) => m != null);
|
|
159
|
-
} catch (err) {
|
|
160
|
-
require_api.logger_default.logInfo("Failed to get next responses", err, {
|
|
161
|
-
payloadContext: payload?.context,
|
|
162
|
-
userEvents: payload?.userEvents
|
|
163
|
-
});
|
|
164
|
-
await throwSessionRestartRequiredIf$1("Failed to get next responses", err);
|
|
165
|
-
return [];
|
|
166
|
-
}
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
static {
|
|
170
|
-
this.getNextResponseStreaming = (payload) => {
|
|
171
|
-
async function* generate(inferenceApi, abortController) {
|
|
172
|
-
try {
|
|
173
|
-
const response = await inferenceApi.v1NextResponsesPostRaw({ NextMessageRequest: require_utils.messageRequestToCommerceMessageRequest(payload) }, { signal: abortController.signal });
|
|
174
|
-
if (!response.raw.body) {
|
|
175
|
-
require_api.logger_default.logError("[spiffy-ai] No body in the streamed response", void 0, { response: response.raw });
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
const reader = response.raw.body.getReader();
|
|
179
|
-
const decoder = new TextDecoder("utf-8");
|
|
180
|
-
let partial = "";
|
|
181
|
-
const safeParse = (line) => {
|
|
182
|
-
try {
|
|
183
|
-
return JSON.parse(line);
|
|
184
|
-
} catch (err) {
|
|
185
|
-
require_api.logger_default.logError("[spiffy-ai] Error parsing streamed line", err, {
|
|
186
|
-
line,
|
|
187
|
-
partial
|
|
188
|
-
});
|
|
189
|
-
partial = line;
|
|
190
|
-
return partial;
|
|
191
|
-
}
|
|
192
|
-
};
|
|
193
|
-
const processChunk = (chunk) => {
|
|
194
|
-
return `${partial}${chunk}`.split("\n").map((line) => line.replace(/^data: /, "").trim()).filter((line) => line !== "" && line !== "[DONE]").map(safeParse).filter((v) => v);
|
|
195
|
-
};
|
|
196
|
-
while (true) {
|
|
197
|
-
const { done, value } = await reader.read();
|
|
198
|
-
if (done) break;
|
|
199
|
-
const chunk = decoder.decode(value);
|
|
200
|
-
const parsedLines = processChunk(chunk);
|
|
201
|
-
for (const parsedLine of parsedLines) {
|
|
202
|
-
const validatedResponse = require_models.validateResponse(parsedLine);
|
|
203
|
-
if (validatedResponse) yield validatedResponse;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
} catch (error) {
|
|
207
|
-
require_api.logger_default.logError("[spiffy-ai] Failed to get next streaming responses", error, {
|
|
208
|
-
payloadContext: payload?.context,
|
|
209
|
-
userEvents: payload?.userEvents
|
|
210
|
-
});
|
|
211
|
-
await throwSessionRestartRequiredIf$1("Failed to get next streaming responses", error);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
CommerceApiClient.getInstance().responsesAbortController.abort();
|
|
215
|
-
CommerceApiClient.getInstance().responsesAbortController = new AbortController();
|
|
216
|
-
return generate(CommerceApiClient.getInstance().inferenceApi, CommerceApiClient.getInstance().responsesAbortController);
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
static {
|
|
220
|
-
this.getNextSuggestions = async (payload) => {
|
|
221
|
-
try {
|
|
222
|
-
CommerceApiClient.getInstance().suggestionsAbortController.abort();
|
|
223
|
-
CommerceApiClient.getInstance().suggestionsAbortController = new AbortController();
|
|
224
|
-
return (await CommerceApiClient.getInstance().inferenceApi.v1NextSuggestionsPost({ NextMessageRequest: require_utils.messageRequestToCommerceMessageRequest(payload) }, { signal: CommerceApiClient.getInstance().suggestionsAbortController.signal })).map((resp) => require_models.validateSuggestion(resp)).filter((suggestion) => suggestion != null);
|
|
225
|
-
} catch (error) {
|
|
226
|
-
require_api.logger_default.logInfo("Failed to get suggestions", error, {
|
|
227
|
-
payloadContext: payload?.context,
|
|
228
|
-
userEvents: payload?.userEvents
|
|
229
|
-
});
|
|
230
|
-
await throwSessionRestartRequiredIf$1("Failed to get suggestions", error);
|
|
231
|
-
return [];
|
|
232
|
-
}
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
static {
|
|
236
|
-
this.getResponses = async (orgId, chatId, userId) => {
|
|
237
|
-
let data = {
|
|
238
|
-
responses: [],
|
|
239
|
-
suggestions: [],
|
|
240
|
-
user_events: []
|
|
241
|
-
};
|
|
242
|
-
const request = {
|
|
243
|
-
org_id: orgId,
|
|
244
|
-
chat_id: chatId,
|
|
245
|
-
user_id: userId
|
|
246
|
-
};
|
|
247
|
-
try {
|
|
248
|
-
data = await CommerceApiClient.getInstance().defaultApi.v1GetSessionMessages(request);
|
|
249
|
-
} catch (error) {
|
|
250
|
-
await throwSessionRestartRequiredIf$1("Failed to get chat responses", error);
|
|
251
|
-
}
|
|
252
|
-
const responses = data?.responses?.map((turn) => turn.map((response) => require_models.validateResponse(response)).filter((response) => response != null));
|
|
253
|
-
const suggestions = data?.suggestions.map((suggestion) => require_models.validateSuggestion(suggestion)).filter((suggestion) => suggestion != null);
|
|
254
|
-
const userEvents = data?.user_events.map((event) => require_models.validateUserEvent(event)).filter((event) => event != null);
|
|
255
|
-
const formSubmittedUserEventsFormIds = userEvents.filter((event) => event.category === __spiffy_ai_commerce_api_client.UserEventCategory.FormSubmitted).map((event) => event.attributes.formResponseId);
|
|
256
|
-
const assistantMessages = responses.map((turn) => turn.filter((response) => !(response.category === __spiffy_ai_commerce_api_client.ResponseCategory.Form && formSubmittedUserEventsFormIds.includes(response.id))).map((response) => require_utils.messageFromResponse(response)).filter((message) => message != null)).filter((turn) => turn.length > 0);
|
|
257
|
-
const userMessages = userEvents.map((event) => {
|
|
258
|
-
if ([__spiffy_ai_commerce_api_client.UserEventCategory.QueryTyped, __spiffy_ai_commerce_api_client.UserEventCategory.Search].includes(event.category)) return [require_utils.messageFromQueryEvent(event)];
|
|
259
|
-
if (event.category === __spiffy_ai_commerce_api_client.UserEventCategory.SuggestionClicked) return [require_utils.messageFromSuggestionEvent(event, suggestions)];
|
|
260
|
-
if (event.category === __spiffy_ai_commerce_api_client.UserEventCategory.FormSubmitted) {
|
|
261
|
-
const formResponse = responses.flat().find((response) => response.id === event.attributes.formResponseId && event.attributes.formType !== __spiffy_ai_commerce_api_client.FormType.Escalation);
|
|
262
|
-
if (formResponse && formResponse.category === __spiffy_ai_commerce_api_client.ResponseCategory.Form) return [require_utils.messageFromFormSubmittedEvent(event, formResponse.attributes)];
|
|
263
|
-
}
|
|
264
|
-
return [];
|
|
265
|
-
}).filter((message) => message.length > 0);
|
|
266
|
-
const sortedMessages = [...assistantMessages, ...userMessages].sort((a, b) => new Date(a[0].createdAt).getTime() - new Date(b[0].createdAt).getTime());
|
|
267
|
-
return {
|
|
268
|
-
responses,
|
|
269
|
-
userEvents,
|
|
270
|
-
suggestions,
|
|
271
|
-
messages: sortedMessages
|
|
272
|
-
};
|
|
273
|
-
};
|
|
274
|
-
}
|
|
275
|
-
static {
|
|
276
|
-
this.isSupportedEvent = async (payload) => {
|
|
277
|
-
try {
|
|
278
|
-
const httpResponseText = await (await CommerceApiClient.getInstance().inferenceApi.v1SupportedEventPostRaw({ SupportedEventRequest: require_utils.coreSupportedEventRequestToApiRequest(payload) })).raw.text();
|
|
279
|
-
const httpResponseJson = JSON.parse(httpResponseText);
|
|
280
|
-
return {
|
|
281
|
-
...httpResponseJson,
|
|
282
|
-
numberOfReviews: httpResponseJson.num_of_reviews,
|
|
283
|
-
merchant_tags: httpResponseJson.merchant_tags || []
|
|
284
|
-
};
|
|
285
|
-
} catch (err) {
|
|
286
|
-
require_api.logger_default.logError("Failed to get response for v1SupportedEventPost", { err });
|
|
287
|
-
return {
|
|
288
|
-
supported: false,
|
|
289
|
-
ready: false,
|
|
290
|
-
category: void 0,
|
|
291
|
-
collections: [],
|
|
292
|
-
numberOfReviews: void 0,
|
|
293
|
-
top_category: void 0,
|
|
294
|
-
merchant_tags: []
|
|
295
|
-
};
|
|
296
|
-
}
|
|
297
|
-
};
|
|
298
|
-
}
|
|
299
|
-
static {
|
|
300
|
-
this.identifyUser = async (spiffyUserId, merchantUserId, uaDetails) => {
|
|
301
|
-
try {
|
|
302
|
-
await CommerceApiClient.getInstance().defaultApi.v1AnalyticsIdentifyPost({ AnalyticsIdentifyRequest: {
|
|
303
|
-
user_id: spiffyUserId,
|
|
304
|
-
os_name: uaDetails.os,
|
|
305
|
-
os_version: uaDetails.osVersion,
|
|
306
|
-
platform: uaDetails.os,
|
|
307
|
-
device_id: uaDetails.deviceModel,
|
|
308
|
-
device_brand: uaDetails.deviceBrand,
|
|
309
|
-
device_manufacturer: uaDetails.deviceManufacturer,
|
|
310
|
-
device_model: uaDetails.deviceModel,
|
|
311
|
-
user_properties: {
|
|
312
|
-
cdp_user_id: merchantUserId,
|
|
313
|
-
browser: uaDetails.browser,
|
|
314
|
-
browser_version: uaDetails.browserVersion,
|
|
315
|
-
user_agent: uaDetails.userAgent
|
|
316
|
-
}
|
|
317
|
-
} });
|
|
318
|
-
} catch (err) {
|
|
319
|
-
require_api.logger_default.logError("Failed to identify user", err);
|
|
320
|
-
}
|
|
321
|
-
};
|
|
322
|
-
}
|
|
323
|
-
static {
|
|
324
|
-
this.mapContextSourceToV1OrgConfigGetSource = (source) => {
|
|
325
|
-
if (source === void 0) return void 0;
|
|
326
|
-
switch (source) {
|
|
327
|
-
case __spiffy_ai_commerce_api_client.ContextSourceEnum.Fork: return __spiffy_ai_commerce_api_client.V1OrgConfigGetSourceEnum.Fork;
|
|
328
|
-
case __spiffy_ai_commerce_api_client.ContextSourceEnum.Playground: return __spiffy_ai_commerce_api_client.V1OrgConfigGetSourceEnum.Playground;
|
|
329
|
-
case __spiffy_ai_commerce_api_client.ContextSourceEnum.App: return __spiffy_ai_commerce_api_client.V1OrgConfigGetSourceEnum.App;
|
|
330
|
-
case __spiffy_ai_commerce_api_client.ContextSourceEnum.Test: return __spiffy_ai_commerce_api_client.V1OrgConfigGetSourceEnum.Test;
|
|
331
|
-
default: return source;
|
|
332
|
-
}
|
|
333
|
-
};
|
|
334
|
-
}
|
|
335
|
-
static {
|
|
336
|
-
this.getOrgConfig = async (user_id) => {
|
|
337
|
-
try {
|
|
338
|
-
const atomStore = require_atomStore.getAtomStore();
|
|
339
|
-
const reactAppName = atomStore.get(require_enviveConfig.reactAppNameAtom);
|
|
340
|
-
const contextSource = atomStore.get(require_enviveConfig.contextSourceAtom);
|
|
341
|
-
const featureFlagService = atomStore.get(require_graphqlConfig.featureFlagServiceAtom);
|
|
342
|
-
const request = {
|
|
343
|
-
namespace: reactAppName,
|
|
344
|
-
user_id,
|
|
345
|
-
source: this.mapContextSourceToV1OrgConfigGetSource(contextSource),
|
|
346
|
-
include_experiments: Object.values(require_models.ProductExperiment),
|
|
347
|
-
include_feature_gates: Object.entries(featureFlagService?.featureFlagService?.getFeatureFlags() || {}).filter(([, isEnabled]) => isEnabled).map(([featureGateName]) => featureGateName)
|
|
348
|
-
};
|
|
349
|
-
const response = await CommerceApiClient.getInstance().defaultApi.v1OrgConfigGet(request);
|
|
350
|
-
return require_models.validateOrgConfigResults(response);
|
|
351
|
-
} catch (err) {
|
|
352
|
-
require_api.logger_default.logError(`Failed to get org config`, err, { err });
|
|
353
|
-
return;
|
|
354
|
-
}
|
|
355
|
-
};
|
|
356
|
-
}
|
|
357
|
-
static {
|
|
358
|
-
this.addNoteToLatestConversation = async (spiffyUserId, email, customerServiceProvider) => {
|
|
359
|
-
require_api.logger_default.logInfo(`addNoteToLatestConversation - user_id=${spiffyUserId} email=${email} customer_service_provider=${customerServiceProvider}`);
|
|
360
|
-
try {
|
|
361
|
-
await CommerceApiClient.getInstance().customerServiceApi.v1CustserviceAddNoteToLatestConversationPost({ AddNoteToLatestConversationRequest: {
|
|
362
|
-
spiffy_user_id: spiffyUserId,
|
|
363
|
-
email,
|
|
364
|
-
customer_service_provider: customerServiceProvider
|
|
365
|
-
} });
|
|
366
|
-
} catch (err) {
|
|
367
|
-
require_api.logger_default.logError("Failed to add note to latest conversation", { err });
|
|
368
|
-
}
|
|
369
|
-
};
|
|
370
|
-
}
|
|
371
|
-
static {
|
|
372
|
-
this.getCustomerServiceApi = () => CommerceApiClient.getInstance().customerServiceApi;
|
|
373
|
-
}
|
|
374
|
-
};
|
|
375
|
-
var commerce_api_default = CommerceApiClient;
|
|
376
|
-
|
|
377
|
-
//#endregion
|
|
378
|
-
//#region src/hooks/useAmplitudeOperations.ts
|
|
379
|
-
const useAmplitudeTracking = () => {
|
|
380
|
-
const { trackEvent, isReady } = require_amplitudeContext.useAmplitude();
|
|
381
|
-
const [loading, setLoading] = (0, react.useState)(false);
|
|
382
|
-
const [error, setError] = (0, react.useState)(null);
|
|
383
|
-
return {
|
|
384
|
-
track: (0, react.useCallback)(async (eventName, eventProps) => {
|
|
385
|
-
if (!isReady) return;
|
|
386
|
-
setLoading(true);
|
|
387
|
-
setError(null);
|
|
388
|
-
try {
|
|
389
|
-
await trackEvent({
|
|
390
|
-
eventName,
|
|
391
|
-
eventProps
|
|
392
|
-
});
|
|
393
|
-
} catch (err) {
|
|
394
|
-
setError(err instanceof Error ? err : /* @__PURE__ */ new Error("Tracking failed"));
|
|
395
|
-
throw err;
|
|
396
|
-
} finally {
|
|
397
|
-
setLoading(false);
|
|
398
|
-
}
|
|
399
|
-
}, [trackEvent, isReady]),
|
|
400
|
-
loading,
|
|
401
|
-
error,
|
|
402
|
-
isReady
|
|
403
|
-
};
|
|
404
|
-
};
|
|
405
|
-
|
|
406
|
-
//#endregion
|
|
407
|
-
//#region src/hooks/useBlockBackButton.ts
|
|
408
|
-
const useBlockBackButton = (enabled, callback) => {
|
|
409
|
-
(0, react.useEffect)(() => {
|
|
410
|
-
if (enabled && window) {
|
|
411
|
-
if (window.history.scrollRestoration) window.history.scrollRestoration = "manual";
|
|
412
|
-
window.history.pushState(null, document.title, window.location.href);
|
|
413
|
-
window.onpopstate = (e) => {
|
|
414
|
-
e.preventDefault();
|
|
415
|
-
window.history.pushState(null, document.title, window.location.href);
|
|
416
|
-
callback?.();
|
|
417
|
-
};
|
|
418
|
-
}
|
|
419
|
-
return () => {
|
|
420
|
-
if (enabled && window) {
|
|
421
|
-
window.history.back();
|
|
422
|
-
window.onpopstate = null;
|
|
423
|
-
window.history.scrollRestoration = "auto";
|
|
424
|
-
}
|
|
425
|
-
};
|
|
426
|
-
}, [enabled]);
|
|
427
|
-
};
|
|
428
|
-
|
|
429
|
-
//#endregion
|
|
430
|
-
//#region src/hooks/useCdnOperations.ts
|
|
431
|
-
const useCdnUrl = () => {
|
|
432
|
-
const { cdnUrl } = useCdn();
|
|
433
|
-
return cdnUrl;
|
|
434
|
-
};
|
|
435
|
-
const useCdnBasePath = () => {
|
|
436
|
-
const { getCdnBasePath } = useCdn();
|
|
437
|
-
return getCdnBasePath();
|
|
438
|
-
};
|
|
439
|
-
const useAssetUrl = (assetName, orgShortName) => {
|
|
440
|
-
const { getAssetURL } = useCdn();
|
|
441
|
-
return getAssetURL(assetName, orgShortName);
|
|
442
|
-
};
|
|
443
|
-
|
|
444
|
-
//#endregion
|
|
445
|
-
//#region src/hooks/useChatToggle.ts
|
|
446
|
-
const useChatToggle = () => {
|
|
447
|
-
const onToggle = (0, jotai.useSetAtom)(require_chat.chatOnToggleAtom);
|
|
448
|
-
const { isOpen } = (0, jotai.useAtomValue)(require_chat.chatAtom);
|
|
449
|
-
const { trackEvent } = require_amplitudeContext.useAmplitude();
|
|
450
|
-
const toggle = (triggerLocation, triggerId) => {
|
|
451
|
-
if (!isOpen) trackEvent({
|
|
452
|
-
eventName: require_amplitudeContext.SpiffyMetricsEventName.ChatComponentExpanded,
|
|
453
|
-
eventProps: { message_metadata: {
|
|
454
|
-
trigger_location: triggerLocation,
|
|
455
|
-
trigger_id: triggerId
|
|
456
|
-
} }
|
|
457
|
-
});
|
|
458
|
-
else trackEvent({
|
|
459
|
-
eventName: require_amplitudeContext.SpiffyMetricsEventName.ChatComponentCollapsed,
|
|
460
|
-
eventProps: { message_metadata: {
|
|
461
|
-
trigger_location: triggerLocation,
|
|
462
|
-
trigger_id: triggerId
|
|
463
|
-
} }
|
|
464
|
-
});
|
|
465
|
-
onToggle();
|
|
466
|
-
};
|
|
467
|
-
const openChat = (triggerLocation, triggerId) => {
|
|
468
|
-
if (!isOpen) toggle(triggerLocation, triggerId);
|
|
469
|
-
};
|
|
470
|
-
const closeChat = (triggerLocation, triggerId) => {
|
|
471
|
-
if (isOpen) toggle(triggerLocation, triggerId);
|
|
472
|
-
};
|
|
473
|
-
return {
|
|
474
|
-
toggle,
|
|
475
|
-
isOpen,
|
|
476
|
-
openChat,
|
|
477
|
-
closeChat
|
|
478
|
-
};
|
|
479
|
-
};
|
|
480
|
-
|
|
481
|
-
//#endregion
|
|
482
|
-
//#region src/hooks/useChatToggleAnalytics.ts
|
|
483
|
-
const useChatToggleAnalytics = () => {
|
|
484
|
-
const setChatOnToggle = (0, jotai.useSetAtom)(require_chat.chatOnToggleAtom);
|
|
485
|
-
const { track } = useAmplitudeTracking();
|
|
486
|
-
const toggleChat = (triggerLocation) => {
|
|
487
|
-
setChatOnToggle(triggerLocation, track);
|
|
488
|
-
};
|
|
489
|
-
return { toggleChat };
|
|
490
|
-
};
|
|
491
|
-
|
|
492
|
-
//#endregion
|
|
493
|
-
//#region src/hooks/useCustomerSupportHandoff.ts
|
|
494
|
-
/**
|
|
495
|
-
* Hook to call the `click` method of the merchant's customer support chat widget.
|
|
496
|
-
*
|
|
497
|
-
* @param onSwitchToAgent a function to override the function returned by the hook. This is mainly to
|
|
498
|
-
* preserve backward compatibility for merchants not using Kustomer and will be removed when all
|
|
499
|
-
* CS integrations are handled.
|
|
500
|
-
*
|
|
501
|
-
* @returns a function that searches for the customer support chat widget and calls the `click` method.
|
|
502
|
-
*/
|
|
503
|
-
const useCustomerSupportHandoff = (onSwitchToAgent) => {
|
|
504
|
-
const onKustomerSwitch = (0, react.useCallback)(() => {
|
|
505
|
-
const kustomerElement = document.getElementById("kustomer-ui-sdk-iframe");
|
|
506
|
-
if (kustomerElement == null || !(kustomerElement instanceof HTMLIFrameElement)) {
|
|
507
|
-
require_api.logger_default.logError("[spiffy-ai] Kustomer iFrame element not found", void 0);
|
|
508
|
-
return;
|
|
509
|
-
}
|
|
510
|
-
const kustomerButton = kustomerElement.contentWindow?.document?.getElementById("rootChatIcon");
|
|
511
|
-
if (kustomerButton == null) {
|
|
512
|
-
require_api.logger_default.logError("[spiffy-ai] Kustomer button not found", void 0);
|
|
513
|
-
return;
|
|
514
|
-
}
|
|
515
|
-
kustomerButton.click();
|
|
516
|
-
}, []);
|
|
517
|
-
if (onSwitchToAgent != null) return { onSwitch: onSwitchToAgent };
|
|
518
|
-
return { onSwitch: onKustomerSwitch };
|
|
519
|
-
};
|
|
520
|
-
|
|
521
|
-
//#endregion
|
|
522
|
-
//#region src/hooks/useDebounce.ts
|
|
523
|
-
function useDebounce(value, delay) {
|
|
524
|
-
const [debouncedValue, setDebouncedValue] = (0, react.useState)(value);
|
|
525
|
-
(0, react.useEffect)(() => {
|
|
526
|
-
const handler = setTimeout(() => {
|
|
527
|
-
setDebouncedValue(value);
|
|
528
|
-
}, delay);
|
|
529
|
-
return () => {
|
|
530
|
-
clearTimeout(handler);
|
|
531
|
-
};
|
|
532
|
-
}, [value, delay]);
|
|
533
|
-
return debouncedValue;
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
//#endregion
|
|
537
|
-
//#region src/hooks/useElementObserver.ts
|
|
538
|
-
const useElementObserver = (selector) => {
|
|
539
|
-
const INITIAL_RENDER_STATE = true;
|
|
540
|
-
const eoRef = (0, react.useRef)(require_utils.DOMObserver.add(selector));
|
|
541
|
-
const [renderBlocked, setRenderBlocked] = (0, react.useState)(INITIAL_RENDER_STATE);
|
|
542
|
-
/**
|
|
543
|
-
* Fired every time the HTML element changes.
|
|
544
|
-
*
|
|
545
|
-
* @param fn
|
|
546
|
-
*/
|
|
547
|
-
const onChange = (fn) => {
|
|
548
|
-
eoRef.current?.registerOnChange(fn);
|
|
549
|
-
};
|
|
550
|
-
/**
|
|
551
|
-
* Fired when the HTML element is added to the DOM.
|
|
552
|
-
*
|
|
553
|
-
* @param fn
|
|
554
|
-
*/
|
|
555
|
-
const onAdd = (fn) => {
|
|
556
|
-
eoRef.current?.registerOnAdd(fn);
|
|
557
|
-
};
|
|
558
|
-
/**
|
|
559
|
-
* Fired when the HTML element is removed from the DOM.
|
|
560
|
-
*
|
|
561
|
-
* @param fn
|
|
562
|
-
*/
|
|
563
|
-
const onRemove = (fn) => {
|
|
564
|
-
eoRef.current?.registerOnRemove(fn);
|
|
565
|
-
};
|
|
566
|
-
/**
|
|
567
|
-
* Fired when the class of the HTML element changes.
|
|
568
|
-
*
|
|
569
|
-
* @param fn
|
|
570
|
-
*/
|
|
571
|
-
const onClassChange = (fn) => {
|
|
572
|
-
eoRef.current?.registerOnclassChange(fn);
|
|
573
|
-
};
|
|
574
|
-
/**
|
|
575
|
-
* Fired when a class is added to the HTML element.
|
|
576
|
-
*
|
|
577
|
-
* @param className
|
|
578
|
-
* @param fn
|
|
579
|
-
*/
|
|
580
|
-
const onClassAdded = (className, fn) => {
|
|
581
|
-
eoRef.current?.registerOnClassAdded(className, fn);
|
|
582
|
-
};
|
|
583
|
-
/**
|
|
584
|
-
* Fired when a class is removed from the HTML element.
|
|
585
|
-
*
|
|
586
|
-
* @param className
|
|
587
|
-
* @param fn
|
|
588
|
-
*/
|
|
589
|
-
const onClassRemoved = (className, fn) => {
|
|
590
|
-
eoRef.current?.registerOnClassRemoved(className, fn);
|
|
591
|
-
};
|
|
592
|
-
/**
|
|
593
|
-
* Fired when a child element is added to the HTML element.
|
|
594
|
-
*
|
|
595
|
-
* @param fn
|
|
596
|
-
*/
|
|
597
|
-
const onAddChild = (fn) => {
|
|
598
|
-
eoRef.current?.registerOnAddChild(fn);
|
|
599
|
-
};
|
|
600
|
-
/**
|
|
601
|
-
* Fired when a child element is removed from the HTML element.
|
|
602
|
-
*
|
|
603
|
-
* @param fn
|
|
604
|
-
*/
|
|
605
|
-
const onRemoveChild = (fn) => {
|
|
606
|
-
eoRef.current?.registerOnRemoveChild(fn);
|
|
607
|
-
};
|
|
608
|
-
/**
|
|
609
|
-
* Allows hooking event listeners to the HTML element, such as `focus`, `blur`, etc.
|
|
610
|
-
*
|
|
611
|
-
* @param event
|
|
612
|
-
* @param fn
|
|
613
|
-
*/
|
|
614
|
-
const onEvent = (event, fn) => {
|
|
615
|
-
eoRef.current.registerEvent(event, fn);
|
|
616
|
-
};
|
|
617
|
-
/**
|
|
618
|
-
* Useful when rendering a React.js component inside the HTML element.
|
|
619
|
-
*
|
|
620
|
-
* @param fn
|
|
621
|
-
* @returns
|
|
622
|
-
*/
|
|
623
|
-
const render = (fn) => {
|
|
624
|
-
if (!renderBlocked) return eoRef.current.render(fn);
|
|
625
|
-
};
|
|
626
|
-
/**
|
|
627
|
-
* Checks if the element exists in the DOM.
|
|
628
|
-
*
|
|
629
|
-
* @returns
|
|
630
|
-
*/
|
|
631
|
-
const exists = () => !!eoRef.current.getNode();
|
|
632
|
-
/**
|
|
633
|
-
* Checks if rendering is unblocked.
|
|
634
|
-
*
|
|
635
|
-
* @returns
|
|
636
|
-
*/
|
|
637
|
-
const isRendered = () => !renderBlocked;
|
|
638
|
-
/**
|
|
639
|
-
* Triggers an event for the HTML element.
|
|
640
|
-
*
|
|
641
|
-
* @param event
|
|
642
|
-
*/
|
|
643
|
-
const fire = (event) => {
|
|
644
|
-
eoRef.current.fire(event);
|
|
645
|
-
};
|
|
646
|
-
/**
|
|
647
|
-
* Shows the HTML element.
|
|
648
|
-
*
|
|
649
|
-
* @returns
|
|
650
|
-
*/
|
|
651
|
-
const show = () => eoRef.current.show();
|
|
652
|
-
/**
|
|
653
|
-
* Hides the HTML element.
|
|
654
|
-
*
|
|
655
|
-
* @returns
|
|
656
|
-
*/
|
|
657
|
-
const hide = () => eoRef.current.hide();
|
|
658
|
-
/**
|
|
659
|
-
* Blocks the rendering of elements.
|
|
660
|
-
*
|
|
661
|
-
* @returns
|
|
662
|
-
*/
|
|
663
|
-
const blockRendering = () => setRenderBlocked(true);
|
|
664
|
-
/**
|
|
665
|
-
* Unblocks the rendering of elements.
|
|
666
|
-
*
|
|
667
|
-
* @returns
|
|
668
|
-
*/
|
|
669
|
-
const unblockRendering = () => setRenderBlocked(false);
|
|
670
|
-
/**
|
|
671
|
-
* Applies CSS styles to the HTML element.
|
|
672
|
-
*
|
|
673
|
-
* @param styles
|
|
674
|
-
*/
|
|
675
|
-
const applyStyle = (styles) => {
|
|
676
|
-
const node = eoRef?.current?.getNode();
|
|
677
|
-
node && Object.assign(node.style, styles);
|
|
678
|
-
};
|
|
679
|
-
(0, react.useEffect)(() => {
|
|
680
|
-
eoRef.current.init();
|
|
681
|
-
eoRef.current.registerOnReset(() => setRenderBlocked(INITIAL_RENDER_STATE));
|
|
682
|
-
require_utils.DOMObserver.observe();
|
|
683
|
-
return () => require_utils.DOMObserver.remove(selector);
|
|
684
|
-
}, [selector.getPattern()]);
|
|
685
|
-
return {
|
|
686
|
-
targetNode: eoRef.current.getNode(),
|
|
687
|
-
onChange,
|
|
688
|
-
onAdd,
|
|
689
|
-
onRemove,
|
|
690
|
-
onClassChange,
|
|
691
|
-
onClassAdded,
|
|
692
|
-
onClassRemoved,
|
|
693
|
-
onAddChild,
|
|
694
|
-
onRemoveChild,
|
|
695
|
-
onEvent,
|
|
696
|
-
blockRendering,
|
|
697
|
-
unblockRendering,
|
|
698
|
-
exists,
|
|
699
|
-
isRendered,
|
|
700
|
-
render,
|
|
701
|
-
fire,
|
|
702
|
-
show,
|
|
703
|
-
hide,
|
|
704
|
-
applyStyle
|
|
705
|
-
};
|
|
706
|
-
};
|
|
707
|
-
|
|
708
|
-
//#endregion
|
|
709
|
-
//#region src/hooks/useGrabAndScroll.ts
|
|
710
|
-
const animateHorizontalScroll = ({ element, duration, targetScroll, multiply = 1, direction, callback, offset = 0 }) => {
|
|
711
|
-
const start = element.scrollLeft;
|
|
712
|
-
const distance = (targetScroll - start) * multiply;
|
|
713
|
-
const startTime = performance.now();
|
|
714
|
-
function easeOutSine(x) {
|
|
715
|
-
return Math.sin(x * Math.PI / 2);
|
|
716
|
-
}
|
|
717
|
-
function scrollStep(currentTime) {
|
|
718
|
-
const timeElapsed = currentTime - startTime;
|
|
719
|
-
const progress = Math.min(timeElapsed / duration, 1);
|
|
720
|
-
const easing = easeOutSine(progress);
|
|
721
|
-
const step = start + distance * easing;
|
|
722
|
-
const canScroll = (direction === "rt" ? element.scrollLeft < step : element.scrollLeft > step) || !direction;
|
|
723
|
-
if (step > 0 && canScroll) element.scrollTo(step, 0);
|
|
724
|
-
if (timeElapsed < duration) requestAnimationFrame(scrollStep);
|
|
725
|
-
else if (element.scrollLeft + offset === element.scrollWidth) callback?.("rt");
|
|
726
|
-
else if (element.scrollLeft <= 1) callback?.("lt");
|
|
727
|
-
else callback?.("ct");
|
|
728
|
-
}
|
|
729
|
-
requestAnimationFrame(scrollStep);
|
|
730
|
-
};
|
|
731
|
-
const useGrabAndScroll = (enabled, chunkWidth, speed = 400, offset = 0) => {
|
|
732
|
-
const containerRef = (0, react.useRef)(null);
|
|
733
|
-
const [leftArrow, setLeftArrow] = (0, react.useState)(false);
|
|
734
|
-
const [rightArrow, setRightArrow] = (0, react.useState)(true);
|
|
735
|
-
const handleArrows = (position) => {
|
|
736
|
-
switch (position) {
|
|
737
|
-
case "lt":
|
|
738
|
-
setLeftArrow(false);
|
|
739
|
-
setRightArrow(true);
|
|
740
|
-
break;
|
|
741
|
-
case "rt":
|
|
742
|
-
setLeftArrow(true);
|
|
743
|
-
setRightArrow(false);
|
|
744
|
-
break;
|
|
745
|
-
default:
|
|
746
|
-
setLeftArrow(true);
|
|
747
|
-
setRightArrow(true);
|
|
748
|
-
}
|
|
749
|
-
};
|
|
750
|
-
const animationTrigger = () => {
|
|
751
|
-
if (enabled && containerRef.current) {
|
|
752
|
-
const dist = (containerRef?.current?.scrollLeft || 0) / chunkWidth;
|
|
753
|
-
const targetScroll = chunkWidth * (Math.floor(dist) + (dist % 1 > .5 ? 1 : 0));
|
|
754
|
-
animateHorizontalScroll({
|
|
755
|
-
element: containerRef.current,
|
|
756
|
-
targetScroll,
|
|
757
|
-
duration: speed,
|
|
758
|
-
offset,
|
|
759
|
-
callback: handleArrows
|
|
760
|
-
});
|
|
761
|
-
}
|
|
762
|
-
};
|
|
763
|
-
const onNext = (cardsToSlide) => {
|
|
764
|
-
if (containerRef.current) {
|
|
765
|
-
const targetScroll = containerRef.current.scrollLeft + chunkWidth;
|
|
766
|
-
animateHorizontalScroll({
|
|
767
|
-
element: containerRef.current,
|
|
768
|
-
targetScroll,
|
|
769
|
-
duration: speed,
|
|
770
|
-
direction: "rt",
|
|
771
|
-
multiply: cardsToSlide,
|
|
772
|
-
offset,
|
|
773
|
-
callback: handleArrows
|
|
774
|
-
});
|
|
775
|
-
}
|
|
776
|
-
};
|
|
777
|
-
const onPrevious = (cardsToSlide) => {
|
|
778
|
-
if (containerRef.current) {
|
|
779
|
-
const targetScroll = containerRef.current.scrollLeft - chunkWidth;
|
|
780
|
-
animateHorizontalScroll({
|
|
781
|
-
element: containerRef.current,
|
|
782
|
-
targetScroll,
|
|
783
|
-
duration: speed,
|
|
784
|
-
direction: "lt",
|
|
785
|
-
multiply: cardsToSlide,
|
|
786
|
-
offset,
|
|
787
|
-
callback: handleArrows
|
|
788
|
-
});
|
|
789
|
-
}
|
|
790
|
-
};
|
|
791
|
-
return {
|
|
792
|
-
containerRef,
|
|
793
|
-
leftArrow,
|
|
794
|
-
rightArrow,
|
|
795
|
-
animationTrigger,
|
|
796
|
-
onNext,
|
|
797
|
-
onPrevious
|
|
798
|
-
};
|
|
799
|
-
};
|
|
800
|
-
|
|
801
|
-
//#endregion
|
|
802
|
-
//#region src/contexts/graphqlContext.tsx
|
|
803
|
-
const GraphQLContext = (0, react.createContext)(null);
|
|
804
|
-
const colorsAndFrontendConfigQuery = () => `
|
|
805
|
-
query ($version: String = "${require_graphql.configVersion()}") {
|
|
806
|
-
me {
|
|
807
|
-
getProductsConfigByVersion(version: $version) {
|
|
808
|
-
frontend { values }
|
|
809
|
-
colors { values }
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
}
|
|
813
|
-
`;
|
|
814
|
-
const GraphQLProvider = ({ children }) => {
|
|
815
|
-
const apiKey = (0, jotai.useAtomValue)(require_enviveConfig.orgLevelApiKeyAtom);
|
|
816
|
-
const baseUrl = (0, jotai.useAtomValue)(require_enviveConfig.baseUrlAtom);
|
|
817
|
-
const isReady = Boolean(apiKey && baseUrl);
|
|
818
|
-
const executeQuery = (0, react.useCallback)(async (query, variables) => {
|
|
819
|
-
if (!isReady) throw new Error("GraphQL client not ready - missing apiKey or baseUrl");
|
|
820
|
-
const response = await fetch(`${baseUrl}/v1/graphql`, {
|
|
821
|
-
method: "POST",
|
|
822
|
-
headers: {
|
|
823
|
-
"Content-Type": "application/json",
|
|
824
|
-
Authorization: `Bearer ${apiKey}`
|
|
825
|
-
},
|
|
826
|
-
body: JSON.stringify({
|
|
827
|
-
query,
|
|
828
|
-
variables
|
|
829
|
-
})
|
|
830
|
-
});
|
|
831
|
-
if (!response.ok) throw new Error(`GraphQL request failed: ${response.statusText}`);
|
|
832
|
-
const result = await response.json();
|
|
833
|
-
if (result.errors) throw new Error(`GraphQL errors: ${JSON.stringify(result.errors)}`);
|
|
834
|
-
return result.data;
|
|
835
|
-
}, [
|
|
836
|
-
apiKey,
|
|
837
|
-
baseUrl,
|
|
838
|
-
isReady
|
|
839
|
-
]);
|
|
840
|
-
const getOrgId = (0, react.useCallback)(async () => {
|
|
841
|
-
const response = await executeQuery(require_models.getMerchantOrgIdQuery);
|
|
842
|
-
return require_models.validateGraphQLOrgId(response.me.org?.id);
|
|
843
|
-
}, [executeQuery]);
|
|
844
|
-
const getColorsAndFrontendConfig = (0, react.useCallback)(async () => {
|
|
845
|
-
try {
|
|
846
|
-
const query = await colorsAndFrontendConfigQuery();
|
|
847
|
-
if (!query) throw new Error("Colors and frontend config query is not defined");
|
|
848
|
-
const response = await executeQuery(query);
|
|
849
|
-
const colorsConfig = response.me.getProductsConfigByVersion?.colors?.values;
|
|
850
|
-
const frontendConfig = response.me.getProductsConfigByVersion?.frontend?.values;
|
|
851
|
-
const transformedColorConfig = require_models.transformSnakeToCamel(colorsConfig);
|
|
852
|
-
const transformedFrontendConfig = require_models.transformSnakeToCamel(frontendConfig);
|
|
853
|
-
return {
|
|
854
|
-
colorsConfig: transformedColorConfig,
|
|
855
|
-
frontendConfig: transformedFrontendConfig
|
|
856
|
-
};
|
|
857
|
-
} catch (err) {
|
|
858
|
-
require_api.logger_default.logError("Error fetching graphql colors and frontend config", err);
|
|
859
|
-
return {
|
|
860
|
-
colorsConfig: void 0,
|
|
861
|
-
frontendConfig: void 0
|
|
862
|
-
};
|
|
863
|
-
}
|
|
864
|
-
}, [executeQuery]);
|
|
865
|
-
const value = (0, react.useMemo)(() => ({
|
|
866
|
-
executeQuery,
|
|
867
|
-
getOrgId,
|
|
868
|
-
getColorsAndFrontendConfig,
|
|
869
|
-
isReady
|
|
870
|
-
}), [
|
|
871
|
-
executeQuery,
|
|
872
|
-
getOrgId,
|
|
873
|
-
getColorsAndFrontendConfig,
|
|
874
|
-
isReady
|
|
875
|
-
]);
|
|
876
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GraphQLContext.Provider, {
|
|
877
|
-
value,
|
|
878
|
-
children
|
|
879
|
-
});
|
|
880
|
-
};
|
|
881
|
-
const useGraphQLClient = () => {
|
|
882
|
-
const context = (0, react.useContext)(GraphQLContext);
|
|
883
|
-
if (!context) throw new Error("useGraphQLClient must be used within a GraphQLProvider");
|
|
884
|
-
return context;
|
|
885
|
-
};
|
|
886
|
-
|
|
887
|
-
//#endregion
|
|
888
|
-
//#region src/hooks/useGraphQLConfig.ts
|
|
889
|
-
const useColorsAndFrontendConfig = () => {
|
|
890
|
-
const { getColorsAndFrontendConfig, isReady } = useGraphQLClient();
|
|
891
|
-
const [data, setData] = (0, react.useState)({});
|
|
892
|
-
const [loading, setLoading] = (0, react.useState)(false);
|
|
893
|
-
const [error, setError] = (0, react.useState)(null);
|
|
894
|
-
const fetchConfig = (0, react.useCallback)(async () => {
|
|
895
|
-
if (!isReady) return;
|
|
896
|
-
setLoading(true);
|
|
897
|
-
setError(null);
|
|
898
|
-
try {
|
|
899
|
-
const result = await getColorsAndFrontendConfig();
|
|
900
|
-
setData(result);
|
|
901
|
-
} catch (err) {
|
|
902
|
-
setError(err instanceof Error ? err : /* @__PURE__ */ new Error("Unknown error"));
|
|
903
|
-
} finally {
|
|
904
|
-
setLoading(false);
|
|
905
|
-
}
|
|
906
|
-
}, [getColorsAndFrontendConfig, isReady]);
|
|
907
|
-
(0, react.useEffect)(() => {
|
|
908
|
-
fetchConfig();
|
|
909
|
-
}, [fetchConfig]);
|
|
910
|
-
return {
|
|
911
|
-
data,
|
|
912
|
-
loading,
|
|
913
|
-
error,
|
|
914
|
-
refetch: fetchConfig
|
|
915
|
-
};
|
|
916
|
-
};
|
|
917
|
-
const useOrgId = () => {
|
|
918
|
-
const { getOrgId, isReady } = useGraphQLClient();
|
|
919
|
-
const [orgId, setOrgId] = (0, react.useState)();
|
|
920
|
-
const [loading, setLoading] = (0, react.useState)(false);
|
|
921
|
-
const [error, setError] = (0, react.useState)(null);
|
|
922
|
-
(0, react.useEffect)(() => {
|
|
923
|
-
if (!isReady) return;
|
|
924
|
-
const fetchOrgId = async () => {
|
|
925
|
-
setLoading(true);
|
|
926
|
-
setError(null);
|
|
927
|
-
try {
|
|
928
|
-
const id = await getOrgId();
|
|
929
|
-
setOrgId(id);
|
|
930
|
-
} catch (err) {
|
|
931
|
-
setError(err instanceof Error ? err : /* @__PURE__ */ new Error("Unknown error"));
|
|
932
|
-
} finally {
|
|
933
|
-
setLoading(false);
|
|
934
|
-
}
|
|
935
|
-
};
|
|
936
|
-
fetchOrgId();
|
|
937
|
-
}, [getOrgId, isReady]);
|
|
938
|
-
return {
|
|
939
|
-
orgId,
|
|
940
|
-
loading,
|
|
941
|
-
error
|
|
942
|
-
};
|
|
943
|
-
};
|
|
944
|
-
|
|
945
|
-
//#endregion
|
|
946
|
-
//#region src/contexts/userIdentityContext.tsx
|
|
947
|
-
const getUserAgentDetails = () => {
|
|
948
|
-
const result = new ua_parser_js.default().getResult();
|
|
949
|
-
return {
|
|
950
|
-
os: result?.os?.name,
|
|
951
|
-
osVersion: result?.os?.version,
|
|
952
|
-
deviceBrand: result?.device?.vendor,
|
|
953
|
-
deviceManufacturer: result?.device?.vendor,
|
|
954
|
-
deviceModel: result?.device?.model,
|
|
955
|
-
browser: result?.browser?.name,
|
|
956
|
-
browserVersion: result?.browser?.version,
|
|
957
|
-
userAgent: result?.ua
|
|
958
|
-
};
|
|
959
|
-
};
|
|
960
|
-
const UserIdentityContext = (0, react.createContext)(void 0);
|
|
961
|
-
const UserIdentityProvider = ({ children }) => {
|
|
962
|
-
const { getItem, setItem, isAvailable: localStorageIsReady } = require_enviveConfig.useLocalStorage();
|
|
963
|
-
const [isReady, setIsReady] = (0, react.useState)(false);
|
|
964
|
-
(0, react.useEffect)(() => {
|
|
965
|
-
setIsReady(localStorageIsReady);
|
|
966
|
-
}, [localStorageIsReady]);
|
|
967
|
-
const USER_ID_OVERRIDE_KEY = "v1-spiffy-user-id-override";
|
|
968
|
-
const USER_ID_DEFAULT_KEY = "v1-spiffy-user-id-default";
|
|
969
|
-
const getUserIdOverrideFromLocalStorage = (0, react.useCallback)(() => {
|
|
970
|
-
return getItem(USER_ID_OVERRIDE_KEY) ?? void 0;
|
|
971
|
-
}, [getItem]);
|
|
972
|
-
const getUserIdDefaultFromLocalStorage = (0, react.useCallback)(() => {
|
|
973
|
-
return getItem(USER_ID_DEFAULT_KEY) ?? void 0;
|
|
974
|
-
}, [getItem]);
|
|
975
|
-
const setUserIdDefaultInLocalStorage = (0, react.useCallback)((userId) => {
|
|
976
|
-
require_api.logger_default.logInfo(`setUserIdDefaultInLocalStorage - Setting user_id=${userId}`);
|
|
977
|
-
setItem(USER_ID_DEFAULT_KEY, userId);
|
|
978
|
-
return userId;
|
|
979
|
-
}, [setItem, USER_ID_DEFAULT_KEY]);
|
|
980
|
-
const setUserIdOverrideInLocalStorage = (0, react.useCallback)((userId) => {
|
|
981
|
-
require_api.logger_default.logInfo(`setUserIdOverrideInLocalStorage - Setting user_id=${userId}`);
|
|
982
|
-
setItem(USER_ID_OVERRIDE_KEY, userId);
|
|
983
|
-
return userId;
|
|
984
|
-
}, [setItem, USER_ID_OVERRIDE_KEY]);
|
|
985
|
-
const clearUserIdOverrideInLocalStorage = (0, react.useCallback)(() => {
|
|
986
|
-
require_api.logger_default.logInfo(`clearUserIdOverrideInLocalStorage - Clearing user_id`);
|
|
987
|
-
setItem(USER_ID_OVERRIDE_KEY, "");
|
|
988
|
-
}, [setItem, USER_ID_OVERRIDE_KEY]);
|
|
989
|
-
const getUserIdOrDefault = (0, react.useCallback)(() => {
|
|
990
|
-
const userIdOverride = getUserIdOverrideFromLocalStorage();
|
|
991
|
-
if (userIdOverride) return userIdOverride;
|
|
992
|
-
const defaultUserId = getUserIdDefaultFromLocalStorage();
|
|
993
|
-
if (defaultUserId) return defaultUserId;
|
|
994
|
-
return setUserIdDefaultInLocalStorage(`spiffy-user-id-${(0, uuid.v4)()}`);
|
|
995
|
-
}, [
|
|
996
|
-
getUserIdOverrideFromLocalStorage,
|
|
997
|
-
getUserIdDefaultFromLocalStorage,
|
|
998
|
-
setUserIdDefaultInLocalStorage
|
|
999
|
-
]);
|
|
1000
|
-
const identifyUser = (0, react.useCallback)(async () => {
|
|
1001
|
-
if (!isReady) {
|
|
1002
|
-
require_api.logger_default.logWarn("[UserIdentityContext] Context not ready, skipping identifyUser", void 0);
|
|
1003
|
-
return;
|
|
1004
|
-
}
|
|
1005
|
-
try {
|
|
1006
|
-
const cdpUserId = "UNKNOWN_CDP_USER_ID";
|
|
1007
|
-
const userId = getUserIdOrDefault();
|
|
1008
|
-
const userAgentDetails = getUserAgentDetails();
|
|
1009
|
-
await commerce_api_default.identifyUser(userId, cdpUserId, userAgentDetails);
|
|
1010
|
-
} catch (error) {
|
|
1011
|
-
require_api.logger_default.logError("[spiffy-ai] Error identifying user", error);
|
|
1012
|
-
}
|
|
1013
|
-
}, [isReady, getUserIdOrDefault]);
|
|
1014
|
-
const value = (0, react.useMemo)(() => ({
|
|
1015
|
-
identifyUser,
|
|
1016
|
-
getUserIdOrDefault,
|
|
1017
|
-
getUserIdOverrideFromLocalStorage,
|
|
1018
|
-
getUserIdDefaultFromLocalStorage,
|
|
1019
|
-
setUserIdDefaultInLocalStorage,
|
|
1020
|
-
setUserIdOverrideInLocalStorage,
|
|
1021
|
-
clearUserIdOverrideInLocalStorage,
|
|
1022
|
-
isReady
|
|
1023
|
-
}), [
|
|
1024
|
-
identifyUser,
|
|
1025
|
-
getUserIdOrDefault,
|
|
1026
|
-
getUserIdOverrideFromLocalStorage,
|
|
1027
|
-
getUserIdDefaultFromLocalStorage,
|
|
1028
|
-
setUserIdDefaultInLocalStorage,
|
|
1029
|
-
setUserIdOverrideInLocalStorage,
|
|
1030
|
-
clearUserIdOverrideInLocalStorage,
|
|
1031
|
-
isReady
|
|
1032
|
-
]);
|
|
1033
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UserIdentityContext.Provider, {
|
|
1034
|
-
value,
|
|
1035
|
-
children
|
|
1036
|
-
});
|
|
1037
|
-
};
|
|
1038
|
-
const useUserIdentity = () => {
|
|
1039
|
-
const context = (0, react.useContext)(UserIdentityContext);
|
|
1040
|
-
if (!context) throw new Error("useUserIdentity must be used within a UserIdentityProvider");
|
|
1041
|
-
return context;
|
|
1042
|
-
};
|
|
1043
|
-
|
|
1044
|
-
//#endregion
|
|
1045
|
-
//#region src/hooks/useIdentifyUser.ts
|
|
1046
|
-
const useIdentifyUser = () => {
|
|
1047
|
-
const { identifyUser, isReady } = useUserIdentity();
|
|
1048
|
-
const [loading, setLoading] = (0, react.useState)(false);
|
|
1049
|
-
const [error, setError] = (0, react.useState)(null);
|
|
1050
|
-
const executeIdentifyUser = (0, react.useCallback)(async () => {
|
|
1051
|
-
if (!isReady) {
|
|
1052
|
-
setError(/* @__PURE__ */ new Error("UserIdentityContext not ready."));
|
|
1053
|
-
return;
|
|
1054
|
-
}
|
|
1055
|
-
setLoading(true);
|
|
1056
|
-
setError(null);
|
|
1057
|
-
try {
|
|
1058
|
-
await identifyUser();
|
|
1059
|
-
} catch (err) {
|
|
1060
|
-
setError(err instanceof Error ? err : /* @__PURE__ */ new Error("Unknown error during user identification."));
|
|
1061
|
-
throw err;
|
|
1062
|
-
} finally {
|
|
1063
|
-
setLoading(false);
|
|
1064
|
-
}
|
|
1065
|
-
}, [identifyUser, isReady]);
|
|
1066
|
-
return {
|
|
1067
|
-
loading,
|
|
1068
|
-
error,
|
|
1069
|
-
executeIdentifyUser,
|
|
1070
|
-
isReady
|
|
1071
|
-
};
|
|
1072
|
-
};
|
|
1073
|
-
|
|
1074
|
-
//#endregion
|
|
1075
|
-
//#region src/hooks/useImageResolver.ts
|
|
1076
|
-
var ImageResolver = class {};
|
|
1077
|
-
var MerchantImageResolver = class {
|
|
1078
|
-
static {
|
|
1079
|
-
this.imageResolverMap = /* @__PURE__ */ new Map();
|
|
1080
|
-
}
|
|
1081
|
-
static loadMapping() {
|
|
1082
|
-
if (this.imageResolverMap.size === 0) {
|
|
1083
|
-
this.imageResolverMap.set(require_types.OrgShortName.Spanx, new ShopifyImageResolver());
|
|
1084
|
-
this.imageResolverMap.set(require_types.OrgShortName.SpanxStaging, new ShopifyImageResolver());
|
|
1085
|
-
this.imageResolverMap.set(require_types.OrgShortName.UniqueVintage, new ShopifyImageResolver());
|
|
1086
|
-
}
|
|
1087
|
-
return this.imageResolverMap;
|
|
1088
|
-
}
|
|
1089
|
-
static get(name) {
|
|
1090
|
-
return this.loadMapping().get(name);
|
|
1091
|
-
}
|
|
1092
|
-
};
|
|
1093
|
-
var ShopifyImageResolver = class extends ImageResolver {
|
|
1094
|
-
resolve(url, size) {
|
|
1095
|
-
const pattern = /_\d+x\.jpg/;
|
|
1096
|
-
const urlHasPrefix = pattern.test(url);
|
|
1097
|
-
const newSizePrefix = `_${size}x.jpg`;
|
|
1098
|
-
if (urlHasPrefix) return url.replace(pattern, newSizePrefix);
|
|
1099
|
-
return url.replace(".jpg", newSizePrefix);
|
|
1100
|
-
}
|
|
1101
|
-
};
|
|
1102
|
-
const useImageResolver = () => {
|
|
1103
|
-
const orgShortName = (0, jotai.useAtomValue)(require_enviveConfig.orgShortNameAtom);
|
|
1104
|
-
const resolve = (image, size) => {
|
|
1105
|
-
if (image && size && orgShortName) return MerchantImageResolver.get(orgShortName)?.resolve(image, size) || image;
|
|
1106
|
-
return image;
|
|
1107
|
-
};
|
|
1108
|
-
return { resolve };
|
|
1109
|
-
};
|
|
1110
|
-
|
|
1111
|
-
//#endregion
|
|
1112
|
-
//#region src/hooks/useIntersection.ts
|
|
1113
|
-
const useIntersection = (element, rootMargin) => {
|
|
1114
|
-
const [isVisible, setIsVisible] = (0, react.useState)(false);
|
|
1115
|
-
(0, react.useEffect)(() => {
|
|
1116
|
-
const current = element?.current;
|
|
1117
|
-
const observer = new IntersectionObserver(([entry]) => {
|
|
1118
|
-
setIsVisible(entry.isIntersecting);
|
|
1119
|
-
}, { rootMargin });
|
|
1120
|
-
if (current) observer?.observe(current);
|
|
1121
|
-
return () => {
|
|
1122
|
-
if (current) observer.unobserve(current);
|
|
1123
|
-
};
|
|
1124
|
-
}, []);
|
|
1125
|
-
return isVisible;
|
|
1126
|
-
};
|
|
1127
|
-
|
|
1128
|
-
//#endregion
|
|
1129
|
-
//#region src/hooks/useIsSmallScreen.ts
|
|
1130
|
-
const useIsSmallScreen = () => {
|
|
1131
|
-
const [isSmall, setIsSmall] = (0, react.useState)(false);
|
|
1132
|
-
(0, react.useEffect)(() => {
|
|
1133
|
-
const mediaQuery = window.matchMedia("(max-width: 479px)");
|
|
1134
|
-
setIsSmall(mediaQuery.matches);
|
|
1135
|
-
const handleResize = (event) => {
|
|
1136
|
-
setIsSmall(event.matches);
|
|
1137
|
-
};
|
|
1138
|
-
mediaQuery.addEventListener("change", handleResize);
|
|
1139
|
-
return () => mediaQuery.removeEventListener("change", handleResize);
|
|
1140
|
-
}, []);
|
|
1141
|
-
return isSmall;
|
|
1142
|
-
};
|
|
1143
|
-
|
|
1144
|
-
//#endregion
|
|
1145
|
-
//#region src/hooks/useLocalStorageOperations.ts
|
|
1146
|
-
const useLocalStorageValue = (key) => {
|
|
1147
|
-
const { getItem, setItem, attachListener, detachListener } = require_enviveConfig.useLocalStorage();
|
|
1148
|
-
const [value, setValue] = (0, react.useState)(() => getItem(key));
|
|
1149
|
-
(0, react.useEffect)(() => {
|
|
1150
|
-
const listener = {
|
|
1151
|
-
storageKey: key,
|
|
1152
|
-
listener: (event) => {
|
|
1153
|
-
setValue(event.newValue);
|
|
1154
|
-
}
|
|
1155
|
-
};
|
|
1156
|
-
attachListener(listener);
|
|
1157
|
-
return () => detachListener(listener);
|
|
1158
|
-
}, [
|
|
1159
|
-
key,
|
|
1160
|
-
attachListener,
|
|
1161
|
-
detachListener
|
|
1162
|
-
]);
|
|
1163
|
-
const updateValue = (0, react.useCallback)((newValue) => {
|
|
1164
|
-
setItem(key, newValue);
|
|
1165
|
-
setValue(newValue);
|
|
1166
|
-
}, [key, setItem]);
|
|
1167
|
-
return {
|
|
1168
|
-
value,
|
|
1169
|
-
setValue: updateValue
|
|
1170
|
-
};
|
|
1171
|
-
};
|
|
1172
|
-
const useSpiffyFeatureFlag = () => {
|
|
1173
|
-
const { setSpiffyOnFeatureFlag } = require_enviveConfig.useLocalStorage();
|
|
1174
|
-
const { value } = useLocalStorageValue(require_enviveConfig.LocalStorageKeys.SpiffyOnOverride);
|
|
1175
|
-
const setFlag = (0, react.useCallback)((flag) => {
|
|
1176
|
-
setSpiffyOnFeatureFlag(flag);
|
|
1177
|
-
}, [setSpiffyOnFeatureFlag]);
|
|
1178
|
-
return {
|
|
1179
|
-
value: value === "true" ? true : value === "false" ? false : null,
|
|
1180
|
-
setFlag
|
|
1181
|
-
};
|
|
1182
|
-
};
|
|
1183
|
-
const useEnviveFeatureFlag = () => {
|
|
1184
|
-
const { setItem, getItem } = require_enviveConfig.useLocalStorage();
|
|
1185
|
-
const { value } = useLocalStorageValue(require_enviveConfig.LocalStorageKeys.EnviveOnOverride);
|
|
1186
|
-
const setFlag = (0, react.useCallback)((flag) => {
|
|
1187
|
-
if (flag === true) setItem(require_enviveConfig.LocalStorageKeys.EnviveOnOverride, "true");
|
|
1188
|
-
else if (flag === false) setItem(require_enviveConfig.LocalStorageKeys.EnviveOnOverride, "false");
|
|
1189
|
-
}, [setItem]);
|
|
1190
|
-
return {
|
|
1191
|
-
value: value === "true" ? true : value === "false" ? false : null,
|
|
1192
|
-
setFlag
|
|
1193
|
-
};
|
|
1194
|
-
};
|
|
1195
|
-
const useLocalStorageListener = (key, callback) => {
|
|
1196
|
-
const { attachListener, detachListener } = require_enviveConfig.useLocalStorage();
|
|
1197
|
-
(0, react.useEffect)(() => {
|
|
1198
|
-
const listener = {
|
|
1199
|
-
storageKey: key,
|
|
1200
|
-
listener: callback
|
|
1201
|
-
};
|
|
1202
|
-
attachListener(listener);
|
|
1203
|
-
return () => detachListener(listener);
|
|
1204
|
-
}, [
|
|
1205
|
-
key,
|
|
1206
|
-
callback,
|
|
1207
|
-
attachListener,
|
|
1208
|
-
detachListener
|
|
1209
|
-
]);
|
|
1210
|
-
};
|
|
1211
|
-
|
|
1212
|
-
//#endregion
|
|
1213
|
-
//#region src/hooks/useMessageFilter.ts
|
|
1214
|
-
const useMessageFilter = () => {
|
|
1215
|
-
const findMessageIndex = ({ msgs, type, role }) => {
|
|
1216
|
-
let lastIndex = -1;
|
|
1217
|
-
msgs.forEach((subArray, index) => {
|
|
1218
|
-
subArray.forEach((obj) => {
|
|
1219
|
-
if (obj.type === type || obj.role === role) lastIndex = index;
|
|
1220
|
-
});
|
|
1221
|
-
});
|
|
1222
|
-
return lastIndex;
|
|
1223
|
-
};
|
|
1224
|
-
const removePreviousDiscussions = (msgs, index) => {
|
|
1225
|
-
if (index > -1) {
|
|
1226
|
-
const lastMessages = msgs.slice(index);
|
|
1227
|
-
return lastMessages.length > 0 ? lastMessages : msgs;
|
|
1228
|
-
}
|
|
1229
|
-
return msgs;
|
|
1230
|
-
};
|
|
1231
|
-
const getFilteredMessages = (msgs, skipFilter) => {
|
|
1232
|
-
const messageMap = msgs.reduce((acc, msg) => {
|
|
1233
|
-
acc[msg[0].id] = msg;
|
|
1234
|
-
return acc;
|
|
1235
|
-
}, {});
|
|
1236
|
-
const deduplicatedMsgs = Object.values(messageMap);
|
|
1237
|
-
if (!skipFilter) {
|
|
1238
|
-
const idx = findMessageIndex({
|
|
1239
|
-
msgs: deduplicatedMsgs,
|
|
1240
|
-
type: require_models.MessageType.Separator
|
|
1241
|
-
});
|
|
1242
|
-
return removePreviousDiscussions(deduplicatedMsgs, idx);
|
|
1243
|
-
}
|
|
1244
|
-
return deduplicatedMsgs;
|
|
1245
|
-
};
|
|
1246
|
-
return {
|
|
1247
|
-
findMessageIndex,
|
|
1248
|
-
removePreviousDiscussions,
|
|
1249
|
-
getFilteredMessages
|
|
1250
|
-
};
|
|
1251
|
-
};
|
|
1252
|
-
|
|
1253
|
-
//#endregion
|
|
1254
|
-
//#region src/hooks/useMessageScrollObserver.ts
|
|
1255
|
-
const useMessageScrollObserver = (boxRef, scrollRef, onScrollChange) => {
|
|
1256
|
-
const calculateScrollHeight = () => {
|
|
1257
|
-
const boxHeight = boxRef?.current?.getBoundingClientRect().height || 0;
|
|
1258
|
-
const scrollHeight = scrollRef?.current?.getBoundingClientRect().height || 0;
|
|
1259
|
-
return boxHeight - scrollHeight;
|
|
1260
|
-
};
|
|
1261
|
-
const updateState = () => {
|
|
1262
|
-
const scrollHeight = calculateScrollHeight();
|
|
1263
|
-
if (scrollHeight > 0) onScrollChange(scrollHeight);
|
|
1264
|
-
};
|
|
1265
|
-
(0, react.useEffect)(() => {
|
|
1266
|
-
let boxRO = null;
|
|
1267
|
-
let scrollRO = null;
|
|
1268
|
-
if (scrollRef?.current) {
|
|
1269
|
-
boxRO = new ResizeObserver(updateState);
|
|
1270
|
-
boxRO.observe(scrollRef?.current);
|
|
1271
|
-
}
|
|
1272
|
-
if (boxRef?.current) {
|
|
1273
|
-
scrollRO = new ResizeObserver(updateState);
|
|
1274
|
-
scrollRO.observe(boxRef?.current);
|
|
1275
|
-
}
|
|
1276
|
-
return () => {
|
|
1277
|
-
if (scrollRef?.current && boxRO) boxRO.unobserve(scrollRef?.current);
|
|
1278
|
-
if (scrollRO && boxRef?.current) scrollRO?.unobserve(boxRef?.current);
|
|
1279
|
-
};
|
|
1280
|
-
}, []);
|
|
1281
|
-
};
|
|
1282
|
-
|
|
1283
|
-
//#endregion
|
|
1284
|
-
//#region src/contexts/featureFlagServiceContext.tsx
|
|
1285
|
-
var FeatureFlagService = class {
|
|
1286
|
-
constructor(featureGates) {
|
|
1287
|
-
this.isFeatureGateEnabled = (featureGate) => {
|
|
1288
|
-
const gateValue = this.featureGates.find((gate) => gate.name === featureGate);
|
|
1289
|
-
if (gateValue == null || gateValue.value == null) {
|
|
1290
|
-
require_api.logger_default.logDebug(`[spiffy-ai] isFeatureGateEnabled featureGate:${featureGate} value is undefined - returning false`);
|
|
1291
|
-
return false;
|
|
1292
|
-
}
|
|
1293
|
-
return gateValue.value;
|
|
1294
|
-
};
|
|
1295
|
-
this.isClientSessionEnabled = () => {
|
|
1296
|
-
return this.featureGates.filter((gate) => gate.name === require_models.FeatureGates.IsClientSessionEnabled && gate.value === true).length > 0;
|
|
1297
|
-
};
|
|
1298
|
-
this.getFeatureFlags = () => {
|
|
1299
|
-
return Object.fromEntries(Object.values(require_models.FeatureGates).map((featureGate) => [featureGate, this.isFeatureGateEnabled(featureGate)]));
|
|
1300
|
-
};
|
|
1301
|
-
this.featureGates = featureGates;
|
|
1302
|
-
}
|
|
1303
|
-
};
|
|
1304
|
-
const FeatureFlagServiceContext = (0, react.createContext)(void 0);
|
|
1305
|
-
const FeatureFlagServiceProvider = ({ featureGates, children }) => {
|
|
1306
|
-
const featureFlagService = (0, react.useMemo)(() => new FeatureFlagService(featureGates), [featureGates]);
|
|
1307
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FeatureFlagServiceContext.Provider, {
|
|
1308
|
-
value: { featureFlagService },
|
|
1309
|
-
children
|
|
1310
|
-
});
|
|
1311
|
-
};
|
|
1312
|
-
const useFeatureFlagService = () => {
|
|
1313
|
-
const context = (0, react.useContext)(FeatureFlagServiceContext);
|
|
1314
|
-
if (context === void 0) throw new Error("useFeatureFlagService must be used within a FeatureFlagServiceProvider");
|
|
1315
|
-
return context;
|
|
1316
|
-
};
|
|
1317
|
-
|
|
1318
|
-
//#endregion
|
|
1319
|
-
//#region src/contexts/newOrgConfigContext.tsx
|
|
1320
|
-
const NewOrgConfigContext = (0, react.createContext)(void 0);
|
|
1321
|
-
const NewOrgConfigProvider = ({ children }) => {
|
|
1322
|
-
const [oldConfig, setOldConfig] = (0, react.useState)();
|
|
1323
|
-
const orgShortName = (0, jotai.useAtomValue)(require_enviveConfig.orgShortNameAtom);
|
|
1324
|
-
const setNewOrgConfig = (0, jotai.useSetAtom)(require_org.newOrgConfigAtom);
|
|
1325
|
-
const { data: newConfig, loading, error } = useColorsAndFrontendConfig();
|
|
1326
|
-
(0, react.useEffect)(() => {
|
|
1327
|
-
if (orgShortName) require_types.getOrgInfo(orgShortName).then(setOldConfig);
|
|
1328
|
-
}, [orgShortName]);
|
|
1329
|
-
const combinedConfig = (0, react.useMemo)(() => {
|
|
1330
|
-
if (!oldConfig || !newConfig) return null;
|
|
1331
|
-
return {
|
|
1332
|
-
...oldConfig,
|
|
1333
|
-
...newConfig
|
|
1334
|
-
};
|
|
1335
|
-
}, [oldConfig, newConfig]);
|
|
1336
|
-
(0, react.useEffect)(() => {
|
|
1337
|
-
const atomStore = require_atomStore.getAtomStore();
|
|
1338
|
-
if (combinedConfig) {
|
|
1339
|
-
atomStore.set(require_graphqlConfig.orgIdAtom, "mock-org-id");
|
|
1340
|
-
setNewOrgConfig(combinedConfig);
|
|
1341
|
-
}
|
|
1342
|
-
}, [combinedConfig, setNewOrgConfig]);
|
|
1343
|
-
const contextValue = (0, react.useMemo)(() => {
|
|
1344
|
-
if (!orgShortName || loading && !oldConfig) return {
|
|
1345
|
-
combinedConfig: null,
|
|
1346
|
-
loading: true,
|
|
1347
|
-
error: null
|
|
1348
|
-
};
|
|
1349
|
-
if (error) return {
|
|
1350
|
-
combinedConfig: null,
|
|
1351
|
-
loading: false,
|
|
1352
|
-
error
|
|
1353
|
-
};
|
|
1354
|
-
return {
|
|
1355
|
-
combinedConfig,
|
|
1356
|
-
loading: false,
|
|
1357
|
-
error: null
|
|
1358
|
-
};
|
|
1359
|
-
}, [
|
|
1360
|
-
orgShortName,
|
|
1361
|
-
loading,
|
|
1362
|
-
error,
|
|
1363
|
-
oldConfig,
|
|
1364
|
-
combinedConfig
|
|
1365
|
-
]);
|
|
1366
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NewOrgConfigContext.Provider, {
|
|
1367
|
-
value: contextValue,
|
|
1368
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FeatureFlagServiceProvider, {
|
|
1369
|
-
featureGates: [],
|
|
1370
|
-
children
|
|
1371
|
-
})
|
|
1372
|
-
});
|
|
1373
|
-
};
|
|
1374
|
-
const useNewOrgConfigContext = () => {
|
|
1375
|
-
const context = (0, react.useContext)(NewOrgConfigContext);
|
|
1376
|
-
if (context === void 0) throw new Error("useNewOrgConfigContext must be used within a NewOrgConfigProvider");
|
|
1377
|
-
return context;
|
|
1378
|
-
};
|
|
1379
|
-
|
|
1380
|
-
//#endregion
|
|
1381
|
-
//#region src/hooks/useNewOrgConfig.ts
|
|
1382
|
-
const useNewOrgConfig = () => {
|
|
1383
|
-
const { combinedConfig, loading, error } = useNewOrgConfigContext();
|
|
1384
|
-
return {
|
|
1385
|
-
...combinedConfig,
|
|
1386
|
-
loading,
|
|
1387
|
-
error
|
|
1388
|
-
};
|
|
1389
|
-
};
|
|
1390
|
-
|
|
1391
|
-
//#endregion
|
|
1392
|
-
//#region src/hooks/utils.ts
|
|
1393
|
-
const isElementPartiallyVisible = (el) => {
|
|
1394
|
-
if (!el) return false;
|
|
1395
|
-
const rect = el.getBoundingClientRect();
|
|
1396
|
-
const windowHeight = window.innerHeight || document.documentElement.clientHeight;
|
|
1397
|
-
const windowWidth = window.innerWidth || document.documentElement.clientWidth;
|
|
1398
|
-
const verticallyVisible = Math.round(rect.top) < windowHeight && Math.round(rect.bottom) > 0;
|
|
1399
|
-
const horizontallyVisible = Math.round(rect.left) < windowWidth && Math.round(rect.right) > 0;
|
|
1400
|
-
return verticallyVisible && horizontallyVisible;
|
|
1401
|
-
};
|
|
1402
|
-
const createAppLoadedEvent = () => ({
|
|
1403
|
-
eventId: (0, uuid.v4)(),
|
|
1404
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1405
|
-
category: __spiffy_ai_commerce_api_client.UserEventCategory.AppLoaded
|
|
1406
|
-
});
|
|
1407
|
-
const createVisitUserEvent = ({ variantInfo }) => {
|
|
1408
|
-
if (variantInfo.variant === "pdp" && variantInfo.productId != null) return {
|
|
1409
|
-
eventId: (0, uuid.v4)(),
|
|
1410
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1411
|
-
category: __spiffy_ai_commerce_api_client.UserEventCategory.PdpVisit,
|
|
1412
|
-
attributes: {
|
|
1413
|
-
productId: variantInfo.productId,
|
|
1414
|
-
parentProductId: variantInfo.parentProductId ?? "",
|
|
1415
|
-
url: variantInfo.url ?? ""
|
|
1416
|
-
}
|
|
1417
|
-
};
|
|
1418
|
-
if (variantInfo.variant === "plp" && variantInfo.plpId != null) return {
|
|
1419
|
-
eventId: (0, uuid.v4)(),
|
|
1420
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1421
|
-
category: __spiffy_ai_commerce_api_client.UserEventCategory.PlpVisit,
|
|
1422
|
-
attributes: {
|
|
1423
|
-
category: __spiffy_ai_commerce_api_client.PLPAttributeCategory.Id,
|
|
1424
|
-
attributes: { id: variantInfo.plpId }
|
|
1425
|
-
}
|
|
1426
|
-
};
|
|
1427
|
-
if (variantInfo.variant === "page_visit") return {
|
|
1428
|
-
eventId: (0, uuid.v4)(),
|
|
1429
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1430
|
-
category: __spiffy_ai_commerce_api_client.UserEventCategory.PageVisit,
|
|
1431
|
-
attributes: {
|
|
1432
|
-
url: variantInfo.url,
|
|
1433
|
-
pageVisitCategory: variantInfo.pageVisitCategory
|
|
1434
|
-
}
|
|
1435
|
-
};
|
|
1436
|
-
};
|
|
1437
|
-
const parseTime = (time, timeZone) => {
|
|
1438
|
-
const times = time.match(/^([0-1]?\d):([0-5]\d)(AM|PM)$/i);
|
|
1439
|
-
const hours = times?.[1];
|
|
1440
|
-
const minutes = times?.[2];
|
|
1441
|
-
const period = times?.[3];
|
|
1442
|
-
if (hours && minutes && period) {
|
|
1443
|
-
const date = /* @__PURE__ */ new Date();
|
|
1444
|
-
let adjustedHours = 0;
|
|
1445
|
-
if (period.toUpperCase() === "PM" && hours !== "12") adjustedHours = parseInt(hours) + 12;
|
|
1446
|
-
if (period.toUpperCase() === "AM" && hours !== "12") adjustedHours = parseInt(hours);
|
|
1447
|
-
const formattedDate = `${date.toISOString().split("T")[0]}T${String(adjustedHours).padStart(2, "0")}:${minutes}:00`;
|
|
1448
|
-
return /* @__PURE__ */ new Date(`${formattedDate}${timeZone}`);
|
|
1449
|
-
}
|
|
1450
|
-
};
|
|
1451
|
-
const isWithinBusinessHours = (startTime, endTime, timeZone) => {
|
|
1452
|
-
const start = parseTime(startTime, timeZone);
|
|
1453
|
-
let end = parseTime(endTime, timeZone);
|
|
1454
|
-
if (!start || !end) return false;
|
|
1455
|
-
let now = /* @__PURE__ */ new Date();
|
|
1456
|
-
if (end < start) {
|
|
1457
|
-
end = new Date(end.getTime() + 1440 * 60 * 1e3);
|
|
1458
|
-
now = new Date(now.getTime() + 1440 * 60 * 1e3);
|
|
1459
|
-
}
|
|
1460
|
-
if (end.getUTCDate() > start.getUTCDate()) {
|
|
1461
|
-
const crossingMidnight = new Date(now.getTime() + 1440 * 60 * 1e3);
|
|
1462
|
-
return start <= now || crossingMidnight <= end;
|
|
1463
|
-
}
|
|
1464
|
-
return now >= start && now <= end;
|
|
1465
|
-
};
|
|
1466
|
-
let SearchResultsState = /* @__PURE__ */ function(SearchResultsState$1) {
|
|
1467
|
-
SearchResultsState$1[SearchResultsState$1["Loading"] = 0] = "Loading";
|
|
1468
|
-
SearchResultsState$1[SearchResultsState$1["Results"] = 1] = "Results";
|
|
1469
|
-
SearchResultsState$1[SearchResultsState$1["NoResults"] = 2] = "NoResults";
|
|
1470
|
-
return SearchResultsState$1;
|
|
1471
|
-
}({});
|
|
1472
|
-
const getSearchResultsState = (isLoadingSearch, searchData) => {
|
|
1473
|
-
if (isLoadingSearch) return SearchResultsState.Loading;
|
|
1474
|
-
if (searchData) return SearchResultsState.Results;
|
|
1475
|
-
return SearchResultsState.NoResults;
|
|
1476
|
-
};
|
|
1477
|
-
|
|
1478
|
-
//#endregion
|
|
1479
|
-
//#region src/hooks/useSearch.tsx
|
|
1480
|
-
const useSearch = () => {
|
|
1481
|
-
const config = useNewOrgConfig();
|
|
1482
|
-
const orgShortName = (0, jotai.useAtomValue)(require_enviveConfig.orgShortNameAtom);
|
|
1483
|
-
const { data: searchData, loading: isLoadingSearch } = (0, jotai.useAtomValue)(require_search.searchAtom);
|
|
1484
|
-
const productList = (0, jotai.useAtomValue)(require_search.filteredSearchProductsAtom);
|
|
1485
|
-
const performSearch = (0, jotai.useSetAtom)(require_search.performSearchAtom);
|
|
1486
|
-
const [{ results: autocompleteResults, isLoading: isLoadingAutocomplete }, setAutocompleteState] = (0, jotai.useAtom)(require_globalSearch.autocompleteStateAtom);
|
|
1487
|
-
const [{ query }] = (0, jotai.useAtom)(require_search.searchParamsAtom);
|
|
1488
|
-
const [isFilterOpen, setIsFilterOpen] = (0, jotai.useAtom)(require_globalSearch.isFilterOpenAtom);
|
|
1489
|
-
const [selectedFilterOptions] = (0, jotai.useAtom)(require_search.searchSelectedFiltersAtom);
|
|
1490
|
-
const addFilter = (0, jotai.useSetAtom)(require_search.addSearchFilterAtom);
|
|
1491
|
-
const removeFilter = (0, jotai.useSetAtom)(require_search.removeSearchFilterAtom);
|
|
1492
|
-
const [productSorting, setProductSorting] = (0, jotai.useAtom)(require_search.searchProductSortingAtom);
|
|
1493
|
-
const clearFilters = (0, jotai.useSetAtom)(require_search.clearSearchFiltersAtom);
|
|
1494
|
-
const searchFilters = (0, jotai.useAtomValue)(require_search.searchFiltersAtom);
|
|
1495
|
-
const [isDirty, setIsDirty] = (0, react.useState)(true);
|
|
1496
|
-
const [focusedIndex, setFocusedIndex] = (0, react.useState)(-1);
|
|
1497
|
-
const [focusedOptionId, setFocusedOptionId] = (0, react.useState)(void 0);
|
|
1498
|
-
const [searchText, setSearchText] = (0, react.useState)(query || "");
|
|
1499
|
-
const searchResultsRef = (0, react.useRef)(null);
|
|
1500
|
-
const debouncedSearchText = useDebounce(searchText, 200);
|
|
1501
|
-
const searchResultsState = getSearchResultsState(isLoadingSearch, searchData);
|
|
1502
|
-
const dynamicFilters = searchData?.filters || [];
|
|
1503
|
-
const safeProductCardConfig = config?.frontendConfig?.uiConfigs?.productCardConfig || {
|
|
1504
|
-
variant: "minimal",
|
|
1505
|
-
hoverVariant: "none",
|
|
1506
|
-
layoutVariant: "square"
|
|
1507
|
-
};
|
|
1508
|
-
const safeMerchantShortName = orgShortName || "";
|
|
1509
|
-
const availableDynamicFilters = (0, react.useMemo)(() => {
|
|
1510
|
-
return dynamicFilters.filter((dynamicFilterName) => !selectedFilterOptions.some((option) => option.id === `dynamic:${dynamicFilterName}`)).map((dynamicFilterName) => ({
|
|
1511
|
-
name: dynamicFilterName,
|
|
1512
|
-
displayName: require_search.formatFilterDisplayName(dynamicFilterName)
|
|
1513
|
-
}));
|
|
1514
|
-
}, [dynamicFilters, selectedFilterOptions]);
|
|
1515
|
-
const filters = (0, react.useMemo)(() => {
|
|
1516
|
-
return [{
|
|
1517
|
-
filterId: "sort",
|
|
1518
|
-
displayName: "SORT",
|
|
1519
|
-
items: [
|
|
1520
|
-
{
|
|
1521
|
-
filterItemId: String(require_search.ProductSorting.FEATURED),
|
|
1522
|
-
displayName: "Relevance",
|
|
1523
|
-
productCount: 0,
|
|
1524
|
-
isSelected: productSorting === require_search.ProductSorting.FEATURED
|
|
1525
|
-
},
|
|
1526
|
-
{
|
|
1527
|
-
filterItemId: String(require_search.ProductSorting.PRICE_ASC),
|
|
1528
|
-
displayName: "Price: Low to High",
|
|
1529
|
-
productCount: 0,
|
|
1530
|
-
isSelected: productSorting === require_search.ProductSorting.PRICE_ASC
|
|
1531
|
-
},
|
|
1532
|
-
{
|
|
1533
|
-
filterItemId: String(require_search.ProductSorting.PRICE_DESC),
|
|
1534
|
-
displayName: "Price: High to Low",
|
|
1535
|
-
productCount: 0,
|
|
1536
|
-
isSelected: productSorting === require_search.ProductSorting.PRICE_DESC
|
|
1537
|
-
}
|
|
1538
|
-
]
|
|
1539
|
-
}, ...searchFilters];
|
|
1540
|
-
}, [productSorting, searchFilters]);
|
|
1541
|
-
const filterButtonText = (0, react.useMemo)(() => {
|
|
1542
|
-
const selectedCount = filters.reduce((acc, filter) => {
|
|
1543
|
-
if (filter.filterId === "sort") return acc;
|
|
1544
|
-
return acc + filter.items.filter((item) => item.isSelected).length;
|
|
1545
|
-
}, 0);
|
|
1546
|
-
if (selectedCount === 0) return "Filter & Sort";
|
|
1547
|
-
return `Filter & Sort (${selectedCount})`;
|
|
1548
|
-
}, [filters]);
|
|
1549
|
-
const { trackEvent } = require_amplitudeContext.useAmplitude();
|
|
1550
|
-
const handleToggleDynamicFilter = (0, react.useCallback)(({ filter, dynamicFilterDisplayName }) => {
|
|
1551
|
-
trackEvent({
|
|
1552
|
-
eventName: require_amplitudeContext.SpiffyMetricsEventName.SearchFilterClicked,
|
|
1553
|
-
eventProps: {
|
|
1554
|
-
filterType: "Dynamic",
|
|
1555
|
-
filterValue: filter,
|
|
1556
|
-
queryText: searchText
|
|
1557
|
-
}
|
|
1558
|
-
});
|
|
1559
|
-
addFilter(require_search.createFilterOption("dynamic", filter, dynamicFilterDisplayName));
|
|
1560
|
-
}, [
|
|
1561
|
-
addFilter,
|
|
1562
|
-
searchText,
|
|
1563
|
-
trackEvent
|
|
1564
|
-
]);
|
|
1565
|
-
const handleRemoveFilter = (0, react.useCallback)((filter) => {
|
|
1566
|
-
removeFilter(filter.id);
|
|
1567
|
-
}, [removeFilter]);
|
|
1568
|
-
const handleSubmitSearch = (0, react.useCallback)(async () => {
|
|
1569
|
-
if (searchText.trim()) {
|
|
1570
|
-
trackEvent({
|
|
1571
|
-
eventName: require_amplitudeContext.SpiffyMetricsEventName.SearchQuerySubmitted,
|
|
1572
|
-
eventProps: {
|
|
1573
|
-
searchOrigin: require_models.SpiffyWidgets.SearchResults,
|
|
1574
|
-
queryText: searchText.trim()
|
|
1575
|
-
},
|
|
1576
|
-
alsoSendToGoogleAnalytics: true
|
|
1577
|
-
});
|
|
1578
|
-
const url = new URL(window.location.href);
|
|
1579
|
-
url.searchParams.set("esq", searchText.trim());
|
|
1580
|
-
window.history.pushState({}, "", url);
|
|
1581
|
-
performSearch({ query: searchText.trim() });
|
|
1582
|
-
}
|
|
1583
|
-
}, [
|
|
1584
|
-
performSearch,
|
|
1585
|
-
searchText,
|
|
1586
|
-
trackEvent
|
|
1587
|
-
]);
|
|
1588
|
-
const handleAutocompleteSelect = (0, react.useCallback)((suggestion) => {
|
|
1589
|
-
setSearchText(suggestion);
|
|
1590
|
-
handleSubmitSearch();
|
|
1591
|
-
}, [handleSubmitSearch, setSearchText]);
|
|
1592
|
-
const handleKeyDown = (0, react.useCallback)((event) => {
|
|
1593
|
-
if (event.key === "ArrowDown") {
|
|
1594
|
-
event.preventDefault();
|
|
1595
|
-
const newIndex = (focusedIndex + 1) % autocompleteResults.length;
|
|
1596
|
-
setFocusedIndex(newIndex);
|
|
1597
|
-
setFocusedOptionId(`option-${newIndex}`);
|
|
1598
|
-
} else if (event.key === "ArrowUp") {
|
|
1599
|
-
event.preventDefault();
|
|
1600
|
-
const newIndex = (focusedIndex - 1 + autocompleteResults.length) % autocompleteResults.length;
|
|
1601
|
-
setFocusedIndex(newIndex);
|
|
1602
|
-
setFocusedOptionId(`option-${newIndex}`);
|
|
1603
|
-
} else if (event.key === "Enter") if (focusedIndex === -1) {
|
|
1604
|
-
event.preventDefault();
|
|
1605
|
-
handleSubmitSearch();
|
|
1606
|
-
} else {
|
|
1607
|
-
event.preventDefault();
|
|
1608
|
-
const suggestionText = autocompleteResults[focusedIndex];
|
|
1609
|
-
handleAutocompleteSelect(suggestionText);
|
|
1610
|
-
}
|
|
1611
|
-
else if (event.key === "Escape") {
|
|
1612
|
-
event.preventDefault();
|
|
1613
|
-
setFocusedIndex(-1);
|
|
1614
|
-
setFocusedOptionId(void 0);
|
|
1615
|
-
}
|
|
1616
|
-
}, [
|
|
1617
|
-
autocompleteResults,
|
|
1618
|
-
focusedIndex,
|
|
1619
|
-
handleAutocompleteSelect,
|
|
1620
|
-
handleSubmitSearch
|
|
1621
|
-
]);
|
|
1622
|
-
const handleSearchInputChange = (newValue) => {
|
|
1623
|
-
if (newValue.length === 1) trackEvent({
|
|
1624
|
-
eventName: require_amplitudeContext.SpiffyMetricsEventName.SearchInputStarted,
|
|
1625
|
-
eventProps: { searchOrigin: require_models.SpiffyWidgets.SearchResults }
|
|
1626
|
-
});
|
|
1627
|
-
setSearchText(newValue);
|
|
1628
|
-
setIsDirty(true);
|
|
1629
|
-
};
|
|
1630
|
-
const handleSelectFilterItem = (0, react.useCallback)(({ filterId, filterItemId, isSelected, displayName }) => {
|
|
1631
|
-
if (filterId === "sort") {
|
|
1632
|
-
const newSort = filterItemId;
|
|
1633
|
-
trackEvent({
|
|
1634
|
-
eventName: require_amplitudeContext.SpiffyMetricsEventName.SearchSortClicked,
|
|
1635
|
-
eventProps: {
|
|
1636
|
-
sortType: newSort,
|
|
1637
|
-
queryText: searchText
|
|
1638
|
-
}
|
|
1639
|
-
});
|
|
1640
|
-
setProductSorting(newSort);
|
|
1641
|
-
} else if (!isSelected) removeFilter(`${filterId}:${filterItemId}`);
|
|
1642
|
-
else {
|
|
1643
|
-
trackEvent({
|
|
1644
|
-
eventName: require_amplitudeContext.SpiffyMetricsEventName.SearchFilterClicked,
|
|
1645
|
-
eventProps: {
|
|
1646
|
-
filterType: "Static",
|
|
1647
|
-
filterCategory: filterId,
|
|
1648
|
-
filterValue: filterItemId,
|
|
1649
|
-
queryText: searchText
|
|
1650
|
-
}
|
|
1651
|
-
});
|
|
1652
|
-
addFilter(require_search.createFilterOption(filterId, filterItemId, displayName));
|
|
1653
|
-
}
|
|
1654
|
-
}, [
|
|
1655
|
-
addFilter,
|
|
1656
|
-
removeFilter,
|
|
1657
|
-
setProductSorting,
|
|
1658
|
-
searchText,
|
|
1659
|
-
trackEvent
|
|
1660
|
-
]);
|
|
1661
|
-
const handleClearAllFilters = (0, react.useCallback)(() => {
|
|
1662
|
-
setProductSorting(require_search.ProductSorting.FEATURED);
|
|
1663
|
-
clearFilters();
|
|
1664
|
-
}, [setProductSorting, clearFilters]);
|
|
1665
|
-
useTrackComponentVisibleEvent(require_models.SpiffyWidgets.SearchResults, searchResultsRef, {}, require_amplitudeContext.SpiffyMetricsEventName.SearchComponentVisible);
|
|
1666
|
-
(0, react.useEffect)(() => {
|
|
1667
|
-
if (productList.length > 0) trackEvent({
|
|
1668
|
-
eventName: require_amplitudeContext.SpiffyMetricsEventName.SearchResultsViewed,
|
|
1669
|
-
eventProps: {
|
|
1670
|
-
queryText: searchText,
|
|
1671
|
-
resultsCount: productList.length
|
|
1672
|
-
}
|
|
1673
|
-
});
|
|
1674
|
-
}, [
|
|
1675
|
-
productList.length,
|
|
1676
|
-
searchText,
|
|
1677
|
-
trackEvent
|
|
1678
|
-
]);
|
|
1679
|
-
(0, react.useEffect)(() => {
|
|
1680
|
-
if (query && query !== searchText) setSearchText(query);
|
|
1681
|
-
}, [query]);
|
|
1682
|
-
(0, react.useEffect)(() => {
|
|
1683
|
-
const esq = new URLSearchParams(window.location.search).get("esq");
|
|
1684
|
-
if (esq) {
|
|
1685
|
-
setSearchText(esq);
|
|
1686
|
-
performSearch({ query: esq });
|
|
1687
|
-
}
|
|
1688
|
-
}, [performSearch]);
|
|
1689
|
-
const fetchAutocompleteSuggestions = (_query) => {
|
|
1690
|
-
return Promise.resolve([]);
|
|
1691
|
-
};
|
|
1692
|
-
(0, react.useEffect)(() => {
|
|
1693
|
-
if (fetchAutocompleteSuggestions === void 0) return;
|
|
1694
|
-
if (!isDirty || debouncedSearchText.length <= 2) {
|
|
1695
|
-
setAutocompleteState({
|
|
1696
|
-
results: [],
|
|
1697
|
-
isLoading: false
|
|
1698
|
-
});
|
|
1699
|
-
return;
|
|
1700
|
-
}
|
|
1701
|
-
setAutocompleteState((prev) => ({
|
|
1702
|
-
...prev,
|
|
1703
|
-
isLoading: true
|
|
1704
|
-
}));
|
|
1705
|
-
const fetchData = async () => {
|
|
1706
|
-
try {
|
|
1707
|
-
const results = await fetchAutocompleteSuggestions?.(debouncedSearchText);
|
|
1708
|
-
setAutocompleteState({
|
|
1709
|
-
results: results ?? [],
|
|
1710
|
-
isLoading: false
|
|
1711
|
-
});
|
|
1712
|
-
} catch (error) {
|
|
1713
|
-
require_api.logger_default.logError("Failed to fetch autocomplete suggestions:", error);
|
|
1714
|
-
setAutocompleteState({
|
|
1715
|
-
results: [],
|
|
1716
|
-
isLoading: false
|
|
1717
|
-
});
|
|
1718
|
-
}
|
|
1719
|
-
};
|
|
1720
|
-
fetchData();
|
|
1721
|
-
}, [
|
|
1722
|
-
debouncedSearchText,
|
|
1723
|
-
isDirty,
|
|
1724
|
-
setAutocompleteState
|
|
1725
|
-
]);
|
|
1726
|
-
return {
|
|
1727
|
-
searchData,
|
|
1728
|
-
searchResponseId: searchData?.searchResponseId ?? "",
|
|
1729
|
-
merchantShortName: safeMerchantShortName,
|
|
1730
|
-
productCardConfig: safeProductCardConfig,
|
|
1731
|
-
productList,
|
|
1732
|
-
autocompleteResults,
|
|
1733
|
-
searchFilters: filters,
|
|
1734
|
-
availableDynamicFilters,
|
|
1735
|
-
selectedFilterOptions,
|
|
1736
|
-
searchText,
|
|
1737
|
-
searchResultsState,
|
|
1738
|
-
isLoadingAutocomplete,
|
|
1739
|
-
isLoadingSearch,
|
|
1740
|
-
isFilterOpen,
|
|
1741
|
-
isDirty,
|
|
1742
|
-
focusedIndex,
|
|
1743
|
-
focusedOptionId,
|
|
1744
|
-
filterButtonText,
|
|
1745
|
-
onSearchInputChange: handleSearchInputChange,
|
|
1746
|
-
onSubmitSearch: handleSubmitSearch,
|
|
1747
|
-
onAutocompleteSelect: handleAutocompleteSelect,
|
|
1748
|
-
onKeyDown: handleKeyDown,
|
|
1749
|
-
onToggleDynamicFilter: handleToggleDynamicFilter,
|
|
1750
|
-
onSelectFilterItem: handleSelectFilterItem,
|
|
1751
|
-
onRemoveFilter: handleRemoveFilter,
|
|
1752
|
-
onClearAllFilters: handleClearAllFilters,
|
|
1753
|
-
setIsFilterOpen,
|
|
1754
|
-
searchResultsRef
|
|
1755
|
-
};
|
|
1756
|
-
};
|
|
1757
|
-
|
|
1758
|
-
//#endregion
|
|
1759
|
-
//#region src/hooks/useAppDetails.ts
|
|
1760
|
-
const useAppDetails = () => {
|
|
1761
|
-
const { orgId: fetchedOrgId } = useOrgId();
|
|
1762
|
-
const orgId = fetchedOrgId ?? "";
|
|
1763
|
-
const orgShortName = (0, jotai.useAtomValue)(require_enviveConfig.orgShortNameAtom) ?? "spiffy-ai";
|
|
1764
|
-
const chatId = (0, jotai.useAtomValue)(require_app.chatIdAtom);
|
|
1765
|
-
const userId = (0, jotai.useAtomValue)(require_app.userIdAtom);
|
|
1766
|
-
const source = (0, jotai.useAtomValue)(require_enviveConfig.contextSourceAtom) ?? __spiffy_ai_commerce_api_client.ContextSourceEnum.App;
|
|
1767
|
-
const env = (0, jotai.useAtomValue)(require_enviveConfig.envAtom) ?? __spiffy_ai_commerce_api_client.ContextEnvEnum.Dev;
|
|
1768
|
-
const variantInfo = (0, jotai.useAtomValue)(require_app.variantInfoAtom);
|
|
1769
|
-
return {
|
|
1770
|
-
orgId,
|
|
1771
|
-
orgShortName,
|
|
1772
|
-
chatId,
|
|
1773
|
-
userId,
|
|
1774
|
-
source,
|
|
1775
|
-
env,
|
|
1776
|
-
variantInfo
|
|
1777
|
-
};
|
|
1778
|
-
};
|
|
1779
|
-
|
|
1780
|
-
//#endregion
|
|
1781
|
-
//#region src/contexts/searchContext.tsx
|
|
1782
|
-
const transformProductResponses = (products) => products.map((data) => ({
|
|
1783
|
-
id: data.id,
|
|
1784
|
-
responseId: data.response_id,
|
|
1785
|
-
category: __spiffy_ai_commerce_api_client.ResponseCategory.Product,
|
|
1786
|
-
description: data.description,
|
|
1787
|
-
imageUrl: data.image_url,
|
|
1788
|
-
imageUrls: data.image_urls,
|
|
1789
|
-
title: data.title,
|
|
1790
|
-
url: data.url,
|
|
1791
|
-
originalPrice: data.original_price,
|
|
1792
|
-
salePrice: data.sale_price,
|
|
1793
|
-
averageRating: data.average_rating,
|
|
1794
|
-
numberReviews: data.number_reviews,
|
|
1795
|
-
metadata: data.metadata,
|
|
1796
|
-
isForGrid: data.is_for_grid,
|
|
1797
|
-
colors: data.colors,
|
|
1798
|
-
sizes: data.sizes,
|
|
1799
|
-
filters: data.filters
|
|
1800
|
-
}));
|
|
1801
|
-
async function errorResponseBody(error) {
|
|
1802
|
-
try {
|
|
1803
|
-
return await error.response.json();
|
|
1804
|
-
} catch {
|
|
1805
|
-
return {};
|
|
1806
|
-
}
|
|
1807
|
-
}
|
|
1808
|
-
async function throwSessionRestartRequiredIf(errorMsg, error) {
|
|
1809
|
-
if (!(error instanceof __spiffy_ai_commerce_api_client.ResponseError)) {
|
|
1810
|
-
require_api.logger_default.logInfo(errorMsg, error);
|
|
1811
|
-
throw error;
|
|
1812
|
-
}
|
|
1813
|
-
const errorResponse = await errorResponseBody(error);
|
|
1814
|
-
if (errorResponse?.message?.toLowerCase() === "unsupported product" || errorResponse?.app_code?.toUpperCase() === "PRODUCT_NOT_FOUND") throw new UnsupportedProductException();
|
|
1815
|
-
else if (errorResponse?.app_code?.toUpperCase() === "RESTART_SESSION" || errorResponse?.sub_code?.toUpperCase() === "NOT_FOUND") {
|
|
1816
|
-
require_api.logger_default.logInfo("Session does not exist. Re-start session", error, error.response, errorResponse);
|
|
1817
|
-
throw new SessionRestartRequired();
|
|
1818
|
-
}
|
|
1819
|
-
require_api.logger_default.logInfo(errorMsg, error);
|
|
1820
|
-
throw error;
|
|
1821
|
-
}
|
|
1822
|
-
const SearchContext = (0, react.createContext)(void 0);
|
|
1823
|
-
const SearchProvider = ({ children }) => {
|
|
1824
|
-
const { orgLevelApiKey, publicKey } = require_amplitudeContext.useEnviveConfig();
|
|
1825
|
-
const apiKey = orgLevelApiKey || publicKey;
|
|
1826
|
-
const appDetails = useAppDetails();
|
|
1827
|
-
const baseUrl = (0, jotai.useAtomValue)(require_enviveConfig.baseUrlAtom);
|
|
1828
|
-
const isReady = Boolean(apiKey && appDetails && baseUrl);
|
|
1829
|
-
const searchApi = (0, react.useMemo)(() => {
|
|
1830
|
-
if (!isReady) return null;
|
|
1831
|
-
const config = new __spiffy_ai_commerce_api_client.Configuration({
|
|
1832
|
-
accessToken: apiKey,
|
|
1833
|
-
basePath: baseUrl,
|
|
1834
|
-
headers: {
|
|
1835
|
-
"Content-Type": "application/json",
|
|
1836
|
-
Accept: "application/json"
|
|
1837
|
-
}
|
|
1838
|
-
});
|
|
1839
|
-
return new __spiffy_ai_commerce_api_client.SearchApi(config);
|
|
1840
|
-
}, [
|
|
1841
|
-
apiKey,
|
|
1842
|
-
baseUrl,
|
|
1843
|
-
isReady
|
|
1844
|
-
]);
|
|
1845
|
-
const searchProducts = (0, react.useCallback)(async (params) => {
|
|
1846
|
-
if (!isReady || !searchApi) throw new Error("SearchService not ready - missing dependencies");
|
|
1847
|
-
try {
|
|
1848
|
-
const { products, filters, search_response_id: searchResponseId } = await searchApi.v1SearchQueryGet({
|
|
1849
|
-
query: params.query,
|
|
1850
|
-
limit: params.limit,
|
|
1851
|
-
org_id: appDetails.orgId,
|
|
1852
|
-
user_id: appDetails.userId
|
|
1853
|
-
});
|
|
1854
|
-
return {
|
|
1855
|
-
products: transformProductResponses(products) || [],
|
|
1856
|
-
filters: filters || [],
|
|
1857
|
-
totalProductCount: products?.length || 0,
|
|
1858
|
-
searchResponseId: searchResponseId || ""
|
|
1859
|
-
};
|
|
1860
|
-
} catch (error) {
|
|
1861
|
-
await throwSessionRestartRequiredIf("Failed to search products", error);
|
|
1862
|
-
return {
|
|
1863
|
-
products: [],
|
|
1864
|
-
filters: [],
|
|
1865
|
-
totalProductCount: 0,
|
|
1866
|
-
searchResponseId: ""
|
|
1867
|
-
};
|
|
1868
|
-
}
|
|
1869
|
-
}, [
|
|
1870
|
-
searchApi,
|
|
1871
|
-
isReady,
|
|
1872
|
-
appDetails
|
|
1873
|
-
]);
|
|
1874
|
-
(0, react.useEffect)(() => {
|
|
1875
|
-
if (isReady) require_search.setSearchServiceFunction(searchProducts);
|
|
1876
|
-
else require_search.clearSearchServiceFunction();
|
|
1877
|
-
return () => {
|
|
1878
|
-
require_search.clearSearchServiceFunction();
|
|
1879
|
-
};
|
|
1880
|
-
}, [searchProducts, isReady]);
|
|
1881
|
-
const value = (0, react.useMemo)(() => ({
|
|
1882
|
-
searchProducts,
|
|
1883
|
-
isReady
|
|
1884
|
-
}), [searchProducts, isReady]);
|
|
1885
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SearchContext.Provider, {
|
|
1886
|
-
value,
|
|
1887
|
-
children
|
|
1888
|
-
});
|
|
1889
|
-
};
|
|
1890
|
-
const useSearchService = () => {
|
|
1891
|
-
const context = (0, react.useContext)(SearchContext);
|
|
1892
|
-
if (!context) throw new Error("useSearchService must be used within a SearchProvider");
|
|
1893
|
-
return context;
|
|
1894
|
-
};
|
|
1895
|
-
|
|
1896
|
-
//#endregion
|
|
1897
|
-
//#region src/hooks/useSearchOperations.ts
|
|
1898
|
-
const useProductSearch = () => {
|
|
1899
|
-
const { searchProducts, isReady } = useSearchService();
|
|
1900
|
-
const [data, setData] = (0, react.useState)();
|
|
1901
|
-
const [loading, setLoading] = (0, react.useState)(false);
|
|
1902
|
-
const [error, setError] = (0, react.useState)(null);
|
|
1903
|
-
const search = (0, react.useCallback)(async (params) => {
|
|
1904
|
-
if (!isReady) {
|
|
1905
|
-
setError(/* @__PURE__ */ new Error("Search service not ready - missing dependencies"));
|
|
1906
|
-
return;
|
|
1907
|
-
}
|
|
1908
|
-
setLoading(true);
|
|
1909
|
-
setError(null);
|
|
1910
|
-
try {
|
|
1911
|
-
const result = await searchProducts(params);
|
|
1912
|
-
setData(result);
|
|
1913
|
-
} catch (err) {
|
|
1914
|
-
setError(err instanceof Error ? err : /* @__PURE__ */ new Error("Unknown search error"));
|
|
1915
|
-
} finally {
|
|
1916
|
-
setLoading(false);
|
|
1917
|
-
}
|
|
1918
|
-
}, [searchProducts, isReady]);
|
|
1919
|
-
const reset = (0, react.useCallback)(() => {
|
|
1920
|
-
setData(void 0);
|
|
1921
|
-
setError(null);
|
|
1922
|
-
setLoading(false);
|
|
1923
|
-
}, []);
|
|
1924
|
-
return {
|
|
1925
|
-
data,
|
|
1926
|
-
loading,
|
|
1927
|
-
error,
|
|
1928
|
-
search,
|
|
1929
|
-
reset,
|
|
1930
|
-
isReady
|
|
1931
|
-
};
|
|
1932
|
-
};
|
|
1933
|
-
const useSearchWithQuery = (params) => {
|
|
1934
|
-
const { searchProducts, isReady } = useSearchService();
|
|
1935
|
-
const [data, setData] = (0, react.useState)();
|
|
1936
|
-
const [loading, setLoading] = (0, react.useState)(false);
|
|
1937
|
-
const [error, setError] = (0, react.useState)(null);
|
|
1938
|
-
const executeSearch = (0, react.useCallback)(async (searchParams) => {
|
|
1939
|
-
if (!isReady) return;
|
|
1940
|
-
setLoading(true);
|
|
1941
|
-
setError(null);
|
|
1942
|
-
try {
|
|
1943
|
-
const result = await searchProducts(searchParams);
|
|
1944
|
-
setData(result);
|
|
1945
|
-
} catch (err) {
|
|
1946
|
-
setError(err instanceof Error ? err : /* @__PURE__ */ new Error("Unknown search error"));
|
|
1947
|
-
} finally {
|
|
1948
|
-
setLoading(false);
|
|
1949
|
-
}
|
|
1950
|
-
}, [searchProducts, isReady]);
|
|
1951
|
-
(0, react.useEffect)(() => {
|
|
1952
|
-
if (params && isReady) executeSearch(params);
|
|
1953
|
-
}, [
|
|
1954
|
-
params,
|
|
1955
|
-
isReady,
|
|
1956
|
-
executeSearch
|
|
1957
|
-
]);
|
|
1958
|
-
const refetch = (0, react.useCallback)(() => {
|
|
1959
|
-
if (params) executeSearch(params);
|
|
1960
|
-
}, [params, executeSearch]);
|
|
1961
|
-
return {
|
|
1962
|
-
data,
|
|
1963
|
-
loading,
|
|
1964
|
-
error,
|
|
1965
|
-
refetch,
|
|
1966
|
-
isReady
|
|
1967
|
-
};
|
|
1968
|
-
};
|
|
1969
|
-
|
|
1970
|
-
//#endregion
|
|
1971
|
-
//#region src/contexts/sessionStorageContext.tsx
|
|
1972
|
-
const SessionStorageContext = (0, react.createContext)(null);
|
|
1973
|
-
const SessionStorageProvider = ({ children }) => {
|
|
1974
|
-
const isAvailable = (0, react.useMemo)(() => {
|
|
1975
|
-
try {
|
|
1976
|
-
return typeof window !== "undefined" && !!window.sessionStorage;
|
|
1977
|
-
} catch {
|
|
1978
|
-
return false;
|
|
1979
|
-
}
|
|
1980
|
-
}, []);
|
|
1981
|
-
(0, react.useEffect)(() => {
|
|
1982
|
-
if (!isAvailable) require_api.logger_default.logError("sessionStorage is not available", void 0);
|
|
1983
|
-
}, [isAvailable]);
|
|
1984
|
-
const setItem = (0, react.useCallback)((key, value$1) => {
|
|
1985
|
-
if (!isAvailable) return;
|
|
1986
|
-
sessionStorage.setItem(key, value$1);
|
|
1987
|
-
window.dispatchEvent(new StorageEvent("storage", {
|
|
1988
|
-
key,
|
|
1989
|
-
newValue: value$1
|
|
1990
|
-
}));
|
|
1991
|
-
}, [isAvailable]);
|
|
1992
|
-
const getItem = (0, react.useCallback)((key) => {
|
|
1993
|
-
if (!isAvailable) return null;
|
|
1994
|
-
return sessionStorage.getItem(key);
|
|
1995
|
-
}, [isAvailable]);
|
|
1996
|
-
const value = (0, react.useMemo)(() => ({
|
|
1997
|
-
setItem,
|
|
1998
|
-
getItem,
|
|
1999
|
-
isAvailable
|
|
2000
|
-
}), [
|
|
2001
|
-
setItem,
|
|
2002
|
-
getItem,
|
|
2003
|
-
isAvailable
|
|
2004
|
-
]);
|
|
2005
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SessionStorageContext.Provider, {
|
|
2006
|
-
value,
|
|
2007
|
-
children
|
|
2008
|
-
});
|
|
2009
|
-
};
|
|
2010
|
-
const useSessionStorage = () => {
|
|
2011
|
-
const context = (0, react.useContext)(SessionStorageContext);
|
|
2012
|
-
if (!context) throw new Error("useSessionStorage must be used within a SessionStorageProvider");
|
|
2013
|
-
return context;
|
|
2014
|
-
};
|
|
2015
|
-
|
|
2016
|
-
//#endregion
|
|
2017
|
-
//#region src/hooks/useSessionStorageOperations.ts
|
|
2018
|
-
const useSessionStorageValue = (key) => {
|
|
2019
|
-
const { getItem, setItem } = useSessionStorage();
|
|
2020
|
-
const [value, setValue] = (0, react.useState)(() => getItem(key));
|
|
2021
|
-
(0, react.useEffect)(() => {
|
|
2022
|
-
const handleStorageChange = (event) => {
|
|
2023
|
-
if (event.key === key) setValue(event.newValue);
|
|
2024
|
-
};
|
|
2025
|
-
window.addEventListener("storage", handleStorageChange);
|
|
2026
|
-
return () => window.removeEventListener("storage", handleStorageChange);
|
|
2027
|
-
}, [key, getItem]);
|
|
2028
|
-
const updateValue = (0, react.useCallback)((newValue) => {
|
|
2029
|
-
setItem(key, newValue);
|
|
2030
|
-
setValue(newValue);
|
|
2031
|
-
}, [key, setItem]);
|
|
2032
|
-
return {
|
|
2033
|
-
value,
|
|
2034
|
-
setValue: updateValue
|
|
2035
|
-
};
|
|
2036
|
-
};
|
|
2037
|
-
|
|
2038
|
-
//#endregion
|
|
2039
|
-
//#region src/contexts/shopifyUrlContext.tsx
|
|
2040
|
-
const ShopifyUrlContext = (0, react.createContext)(void 0);
|
|
2041
|
-
const ShopifyUrlProvider = ({ children }) => {
|
|
2042
|
-
const isReady = true;
|
|
2043
|
-
const getTrimmedPathName = (0, react.useCallback)(() => {
|
|
2044
|
-
let { pathname } = window.location;
|
|
2045
|
-
pathname = pathname.replace("/proxy", "");
|
|
2046
|
-
pathname = pathname.replace(/#.*$/, "");
|
|
2047
|
-
pathname = pathname.replace(/\/$/, "");
|
|
2048
|
-
if (pathname === void 0 || pathname === null || pathname.length === 0) return null;
|
|
2049
|
-
return pathname;
|
|
2050
|
-
}, []);
|
|
2051
|
-
const getPlpOrPdpId = (0, react.useCallback)((extractor) => {
|
|
2052
|
-
if (extractor === "shopify-product-variant-id") {
|
|
2053
|
-
const variantId = require_graphql.parseHref(window.location.href)?.urlSearchParams?.get("variant");
|
|
2054
|
-
if (!variantId) return getPlpOrPdpId("shopify-product-id");
|
|
2055
|
-
return variantId;
|
|
2056
|
-
}
|
|
2057
|
-
const pathSegment = extractor === "shopify-product-id" ? "products" : "collections";
|
|
2058
|
-
const tokens = getTrimmedPathName()?.split("/");
|
|
2059
|
-
const idIndex = tokens?.findIndex((token) => token === pathSegment);
|
|
2060
|
-
if (idIndex !== void 0 && idIndex >= 0 && tokens) return decodeURIComponent(tokens[idIndex + 1]);
|
|
2061
|
-
return null;
|
|
2062
|
-
}, [getTrimmedPathName]);
|
|
2063
|
-
const isOnPdpPage = (0, react.useCallback)(() => {
|
|
2064
|
-
return getTrimmedPathName()?.includes("/products") ?? false;
|
|
2065
|
-
}, [getTrimmedPathName]);
|
|
2066
|
-
const isOnPlpPage = (0, react.useCallback)(() => {
|
|
2067
|
-
return (getTrimmedPathName()?.includes("/collections") && !getTrimmedPathName()?.includes("/products")) ?? false;
|
|
2068
|
-
}, [getTrimmedPathName]);
|
|
2069
|
-
const value = (0, react.useMemo)(() => ({
|
|
2070
|
-
getTrimmedPathName,
|
|
2071
|
-
getPlpOrPdpId,
|
|
2072
|
-
isOnPdpPage,
|
|
2073
|
-
isOnPlpPage,
|
|
2074
|
-
isReady
|
|
2075
|
-
}), [
|
|
2076
|
-
getTrimmedPathName,
|
|
2077
|
-
getPlpOrPdpId,
|
|
2078
|
-
isOnPdpPage,
|
|
2079
|
-
isOnPlpPage,
|
|
2080
|
-
isReady
|
|
2081
|
-
]);
|
|
2082
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShopifyUrlContext.Provider, {
|
|
2083
|
-
value,
|
|
2084
|
-
children
|
|
2085
|
-
});
|
|
2086
|
-
};
|
|
2087
|
-
const useShopifyUrl = () => {
|
|
2088
|
-
const context = (0, react.useContext)(ShopifyUrlContext);
|
|
2089
|
-
if (!context) throw new Error("useShopifyUrl must be used within a ShopifyUrlProvider");
|
|
2090
|
-
return context;
|
|
2091
|
-
};
|
|
2092
|
-
|
|
2093
|
-
//#endregion
|
|
2094
|
-
//#region src/hooks/useShopifyUrlOperations.ts
|
|
2095
|
-
const useShopifyUrlOperations = () => {
|
|
2096
|
-
const { getTrimmedPathName, getPlpOrPdpId, isOnPdpPage, isOnPlpPage, isReady } = useShopifyUrl();
|
|
2097
|
-
return {
|
|
2098
|
-
getTrimmedPathName,
|
|
2099
|
-
getPlpOrPdpId,
|
|
2100
|
-
isOnPdpPage,
|
|
2101
|
-
isOnPlpPage,
|
|
2102
|
-
isReady
|
|
2103
|
-
};
|
|
2104
|
-
};
|
|
2105
|
-
const useCurrentPageType = () => {
|
|
2106
|
-
const { isOnPdpPage, isOnPlpPage, isReady } = useShopifyUrl();
|
|
2107
|
-
return {
|
|
2108
|
-
getPageType: (0, react.useCallback)(() => {
|
|
2109
|
-
if (!isReady) return "unknown";
|
|
2110
|
-
if (isOnPdpPage()) return "pdp";
|
|
2111
|
-
if (isOnPlpPage()) return "plp";
|
|
2112
|
-
return "other";
|
|
2113
|
-
}, [
|
|
2114
|
-
isReady,
|
|
2115
|
-
isOnPdpPage,
|
|
2116
|
-
isOnPlpPage
|
|
2117
|
-
]),
|
|
2118
|
-
isReady
|
|
2119
|
-
};
|
|
2120
|
-
};
|
|
2121
|
-
const useProductId = (extractor) => {
|
|
2122
|
-
const { getPlpOrPdpId, isReady } = useShopifyUrl();
|
|
2123
|
-
return {
|
|
2124
|
-
productId: (0, react.useCallback)(() => {
|
|
2125
|
-
if (!isReady) return null;
|
|
2126
|
-
return getPlpOrPdpId(extractor);
|
|
2127
|
-
}, [
|
|
2128
|
-
isReady,
|
|
2129
|
-
getPlpOrPdpId,
|
|
2130
|
-
extractor
|
|
2131
|
-
]),
|
|
2132
|
-
isReady
|
|
2133
|
-
};
|
|
2134
|
-
};
|
|
2135
|
-
|
|
2136
|
-
//#endregion
|
|
2137
|
-
//#region src/hooks/useSnapCalculator.ts
|
|
2138
|
-
const useSnapCalculator = (snaps, maxHeight, unit) => {
|
|
2139
|
-
const viewportHeightPx = document.documentElement.clientHeight;
|
|
2140
|
-
const swipeviewHeightPx = unit === "percent" ? Math.floor(viewportHeightPx * (maxHeight / 100)) : maxHeight;
|
|
2141
|
-
const snapsToPixels = (0, react.useMemo)(() => snaps?.map((snap) => Math.abs((unit === "percent" ? Math.floor(swipeviewHeightPx * (snap / 100)) : snap) - swipeviewHeightPx)), [viewportHeightPx]);
|
|
2142
|
-
const getPixelToSnap = (pixels) => {
|
|
2143
|
-
const snapIdx = snapsToPixels?.indexOf(pixels) || 0;
|
|
2144
|
-
return snaps?.[snapIdx] || 0;
|
|
2145
|
-
};
|
|
2146
|
-
const getSnapToPixel = (snap) => {
|
|
2147
|
-
const snapIdx = snaps?.indexOf(snap) || 0;
|
|
2148
|
-
return snapsToPixels?.[snapIdx] || 0;
|
|
2149
|
-
};
|
|
2150
|
-
return {
|
|
2151
|
-
viewportHeightPx,
|
|
2152
|
-
snapsToPixels,
|
|
2153
|
-
swipeviewHeightPx,
|
|
2154
|
-
getPixelToSnap,
|
|
2155
|
-
getSnapToPixel
|
|
2156
|
-
};
|
|
2157
|
-
};
|
|
2158
|
-
|
|
2159
|
-
//#endregion
|
|
2160
|
-
//#region src/hooks/useSystemSettingsContext.ts
|
|
2161
|
-
const useSystemSettingsContext = () => {
|
|
2162
|
-
const context = (0, react.useContext)(SystemSettingsContext);
|
|
2163
|
-
if (!context) throw new Error("useSystemSettingsContext must be used within a SystemSettingsContextProvider");
|
|
2164
|
-
return { ...context };
|
|
2165
|
-
};
|
|
2166
|
-
|
|
2167
|
-
//#endregion
|
|
2168
|
-
//#region src/hooks/useTrackComponentVisibleEvent.ts
|
|
2169
|
-
/**
|
|
2170
|
-
* Tracks a component and logs an event to Amplitude when the component is visible.
|
|
2171
|
-
*
|
|
2172
|
-
* @param component - The component to track.
|
|
2173
|
-
* @param element - The element to track visibility of.
|
|
2174
|
-
* @param eventProps - Additional properties to include with the event.
|
|
2175
|
-
* @param eventName - The Amplitude event name to track (defaults to ChatComponentVisible).
|
|
2176
|
-
*/
|
|
2177
|
-
const useTrackComponentVisibleEvent = (component, element, eventProps, eventName = require_amplitudeContext.SpiffyMetricsEventName.ChatComponentVisible) => {
|
|
2178
|
-
const isVisible = useIntersection(element, "0px");
|
|
2179
|
-
const hasTrackedEvent = (0, react.useRef)(false);
|
|
2180
|
-
const { trackEvent } = require_amplitudeContext.useAmplitude();
|
|
2181
|
-
const componentProps = (() => {
|
|
2182
|
-
if (eventName === require_amplitudeContext.SpiffyMetricsEventName.ChatComponentVisible) return {
|
|
2183
|
-
chat_component: component,
|
|
2184
|
-
...eventProps
|
|
2185
|
-
};
|
|
2186
|
-
if (eventName === require_amplitudeContext.SpiffyMetricsEventName.SearchComponentVisible) return {
|
|
2187
|
-
search_component: component,
|
|
2188
|
-
...eventProps
|
|
2189
|
-
};
|
|
2190
|
-
return {
|
|
2191
|
-
component,
|
|
2192
|
-
...eventProps
|
|
2193
|
-
};
|
|
2194
|
-
})();
|
|
2195
|
-
(0, react.useEffect)(() => {
|
|
2196
|
-
if (isVisible && !hasTrackedEvent.current) {
|
|
2197
|
-
trackEvent({
|
|
2198
|
-
eventName,
|
|
2199
|
-
eventProps: componentProps
|
|
2200
|
-
});
|
|
2201
|
-
hasTrackedEvent.current = true;
|
|
2202
|
-
}
|
|
2203
|
-
}, [
|
|
2204
|
-
isVisible,
|
|
2205
|
-
component,
|
|
2206
|
-
eventProps,
|
|
2207
|
-
eventName,
|
|
2208
|
-
componentProps,
|
|
2209
|
-
trackEvent
|
|
2210
|
-
]);
|
|
2211
|
-
};
|
|
2212
|
-
|
|
2213
|
-
//#endregion
|
|
2214
|
-
//#region src/hooks/useUpdateAnalyticsProps.ts
|
|
2215
|
-
/**
|
|
2216
|
-
* Updates the default analytics properties whenever the variant info changes. This hook also
|
|
2217
|
-
* triggers any events that should be sent once per page visit.
|
|
2218
|
-
*/
|
|
2219
|
-
const useUpdateAnalyticsProps = () => {
|
|
2220
|
-
const variantInfo = (0, jotai.useAtomValue)(require_app.variantInfoAtom);
|
|
2221
|
-
const hasInitialized = (0, react.useRef)(false);
|
|
2222
|
-
const hasParsedVariantInfo = (0, jotai.useAtomValue)(require_app.hasParsedVariantInfoAtom);
|
|
2223
|
-
const { trackEvent, setSupplementalDefaultProps } = require_amplitudeContext.useAmplitude();
|
|
2224
|
-
(0, react.useEffect)(() => {
|
|
2225
|
-
const variantInfoWithPrefix = Object.fromEntries(Object.entries(variantInfo).map(([key, value]) => [`variantInfo.${key}`, value]));
|
|
2226
|
-
const defaultEventProperties = {
|
|
2227
|
-
page_variant: variantInfo.variant,
|
|
2228
|
-
...variantInfoWithPrefix
|
|
2229
|
-
};
|
|
2230
|
-
if (variantInfo.variant === "pdp") defaultEventProperties.product_id = variantInfo.productId;
|
|
2231
|
-
if (variantInfo.variant === "plp") defaultEventProperties.plp_id = variantInfo.plpId;
|
|
2232
|
-
if (variantInfo.variant === "page_visit") {
|
|
2233
|
-
defaultEventProperties.page_visit_category = variantInfo.pageVisitCategory;
|
|
2234
|
-
defaultEventProperties.page_visit_url = variantInfo.url;
|
|
2235
|
-
}
|
|
2236
|
-
setSupplementalDefaultProps(defaultEventProperties);
|
|
2237
|
-
if (!hasInitialized.current && hasParsedVariantInfo) {
|
|
2238
|
-
trackEvent({ eventName: require_amplitudeContext.SpiffyMetricsEventName.BundleLoaded });
|
|
2239
|
-
hasInitialized.current = true;
|
|
2240
|
-
}
|
|
2241
|
-
}, [
|
|
2242
|
-
variantInfo,
|
|
2243
|
-
hasParsedVariantInfo,
|
|
2244
|
-
trackEvent,
|
|
2245
|
-
setSupplementalDefaultProps
|
|
2246
|
-
]);
|
|
2247
|
-
};
|
|
2248
|
-
|
|
2249
|
-
//#endregion
|
|
2250
|
-
//#region src/contexts/chatContext.tsx
|
|
2251
|
-
/**
|
|
2252
|
-
* Record the chat assistant response in Amplitude
|
|
2253
|
-
*
|
|
2254
|
-
* @param startTimeMs The start time of the assistant response
|
|
2255
|
-
* @param payload The payload used to generate the response
|
|
2256
|
-
*/
|
|
2257
|
-
const recordAssistantResponse = (startTimeMs, payload, track) => {
|
|
2258
|
-
const atomStore = require_atomStore.getAtomStore();
|
|
2259
|
-
const chatState = atomStore.get(require_chat.chatAtom);
|
|
2260
|
-
const chatSearchState = atomStore.get(require_search.chatSearchStateAtom);
|
|
2261
|
-
const searchProducts = atomStore.get(require_search.chatSearchProducts);
|
|
2262
|
-
const searchProductsSort = atomStore.get(require_search.chatSearchProductSortingAtom);
|
|
2263
|
-
const assistantResponseTimeMs = {
|
|
2264
|
-
start: startTimeMs,
|
|
2265
|
-
end: Date.now()
|
|
2266
|
-
};
|
|
2267
|
-
let userQueryProperty;
|
|
2268
|
-
if (chatState.replyEventCategory === __spiffy_ai_commerce_api_client.UserEventCategory.SuggestionClicked && chatState.suggestion) userQueryProperty = chatState.suggestion.content;
|
|
2269
|
-
else if (chatState.userQuery && chatState.userQuery.length > 0) userQueryProperty = chatState.userQuery;
|
|
2270
|
-
const eventProps = {
|
|
2271
|
-
response_time_ms: assistantResponseTimeMs.end - assistantResponseTimeMs.start,
|
|
2272
|
-
user_event_type: chatState.replyEventCategory,
|
|
2273
|
-
user_query: userQueryProperty
|
|
2274
|
-
};
|
|
2275
|
-
if (chatState.replyEventCategory === __spiffy_ai_commerce_api_client.UserEventCategory.FormSubmitted) {
|
|
2276
|
-
const lastAssistantTurn = chatState.messages.filter((turn) => turn.length > 0 && turn[0].role === require_models.MessageRole.Assistant).pop();
|
|
2277
|
-
const formType = payload.userEvents?.find((event) => event.category === __spiffy_ai_commerce_api_client.UserEventCategory.FormSubmitted)?.attributes.formType;
|
|
2278
|
-
const formStatus = lastAssistantTurn?.some((response) => response.type === require_models.MessageType.Order);
|
|
2279
|
-
eventProps.form_submitted_attributes = {
|
|
2280
|
-
form_type: formType,
|
|
2281
|
-
status: formStatus ? "success" : "failed"
|
|
2282
|
-
};
|
|
2283
|
-
}
|
|
2284
|
-
if (chatSearchState === "product-page") {
|
|
2285
|
-
eventProps.search_products_returned = searchProducts.length;
|
|
2286
|
-
eventProps.search_products_sort_type = searchProductsSort;
|
|
2287
|
-
}
|
|
2288
|
-
track(require_amplitudeContext.SpiffyMetricsEventName.ChatAssistantResponse, { eventProps });
|
|
2289
|
-
};
|
|
2290
|
-
const ChatContext = (0, react.createContext)(void 0);
|
|
2291
|
-
const updateMessageState = (message, lastMessage, setMessages) => {
|
|
2292
|
-
if (lastMessage == null) {
|
|
2293
|
-
setMessages((prev) => [...prev, [message]]);
|
|
2294
|
-
return message;
|
|
2295
|
-
}
|
|
2296
|
-
if (lastMessage.type === require_models.MessageType.Text && message.type === require_models.MessageType.Text) {
|
|
2297
|
-
const newMessage = {
|
|
2298
|
-
...lastMessage,
|
|
2299
|
-
metadata: {
|
|
2300
|
-
...lastMessage.metadata,
|
|
2301
|
-
content: lastMessage.metadata.content + message.metadata.content
|
|
2302
|
-
}
|
|
2303
|
-
};
|
|
2304
|
-
setMessages((prev) => {
|
|
2305
|
-
const lastTurn = prev[prev.length - 1];
|
|
2306
|
-
return [...prev.slice(0, prev.length - 1), [...lastTurn.slice(0, lastTurn.length - 1), newMessage]];
|
|
2307
|
-
});
|
|
2308
|
-
return newMessage;
|
|
2309
|
-
}
|
|
2310
|
-
setMessages((prev) => [...prev.slice(0, prev.length - 1), [...prev[prev.length - 1], message]]);
|
|
2311
|
-
return message;
|
|
2312
|
-
};
|
|
2313
|
-
const handleStreamingError = (_error, setRequestFailure, setMessages) => {
|
|
2314
|
-
setRequestFailure(true);
|
|
2315
|
-
setMessages((prev) => [...prev, [{
|
|
2316
|
-
id: (0, uuid.v4)(),
|
|
2317
|
-
role: require_models.MessageRole.Assistant,
|
|
2318
|
-
type: require_models.MessageType.Text,
|
|
2319
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2320
|
-
metadata: { content: "I'm sorry! I'm having trouble right now. Please refresh the page or try again in a moment." }
|
|
2321
|
-
}]]);
|
|
2322
|
-
};
|
|
2323
|
-
const processStreamingResponse = async (stream, messageInterceptor, handleSearchResults, setMessages, setSearchIsLoading, chatId) => {
|
|
2324
|
-
let lastMessage;
|
|
2325
|
-
let hasSearchResults = false;
|
|
2326
|
-
for await (const response of stream) try {
|
|
2327
|
-
if (messageInterceptor.intercept(response)) return { hasSearchResults };
|
|
2328
|
-
const message = require_utils.messageFromResponse(response);
|
|
2329
|
-
if (!message) throw new Error("Failed to transform API response to client message");
|
|
2330
|
-
if (message.type === require_models.MessageType.ProductSearch) {
|
|
2331
|
-
handleSearchResults(message);
|
|
2332
|
-
hasSearchResults = true;
|
|
2333
|
-
setSearchIsLoading(false);
|
|
2334
|
-
}
|
|
2335
|
-
lastMessage = updateMessageState(message, lastMessage, setMessages);
|
|
2336
|
-
} catch (error) {
|
|
2337
|
-
require_api.logger_default.logWarn(`[spiffy-ai] Failed to generate responses from stream chat_id=${chatId}`, error, {
|
|
2338
|
-
lastResponse: lastMessage,
|
|
2339
|
-
response
|
|
2340
|
-
});
|
|
2341
|
-
}
|
|
2342
|
-
return { hasSearchResults };
|
|
2343
|
-
};
|
|
2344
|
-
const ChatContextProvider = ({ children }) => {
|
|
2345
|
-
const logPerfMetric = (0, jotai.useSetAtom)(require_chat.logPerfMetricAtom);
|
|
2346
|
-
const [widgetInitialized, setWidgetInitialized] = (0, react.useState)(false);
|
|
2347
|
-
const setUserHasReplied = (0, jotai.useSetAtom)(require_chat.userHasRepliedAtom);
|
|
2348
|
-
const [messages, setMessages] = (0, jotai.useAtom)(require_chat.messagesAtom);
|
|
2349
|
-
const setUserEvents = (0, jotai.useSetAtom)(require_chat.userEventsAtom);
|
|
2350
|
-
const setSuggestions = (0, jotai.useSetAtom)(require_chat.suggestionsAtom);
|
|
2351
|
-
const [suggestionsLoading, setSuggestionsLoading] = (0, jotai.useAtom)(require_chat.suggestionsLoadingAtom);
|
|
2352
|
-
const [responseStreaming, setResponseStreaming] = (0, jotai.useAtom)(require_chat.responseStreamingAtom);
|
|
2353
|
-
const setRequestFailure = (0, jotai.useSetAtom)(require_chat.requestFailureAtom);
|
|
2354
|
-
const userEvents = (0, jotai.useAtomValue)(require_chat.userEventQueueAtom);
|
|
2355
|
-
const userQueueEventCount = (0, jotai.useAtomValue)(require_chat.userQueueEventCountAtom);
|
|
2356
|
-
const markUserEventsProcessed = (0, jotai.useSetAtom)(require_chat.processUserEventAtom);
|
|
2357
|
-
const clearUserEventQueue = (0, jotai.useSetAtom)(require_chat.clearUserEventAtom);
|
|
2358
|
-
const userId = (0, jotai.useAtomValue)(require_app.userIdAtom);
|
|
2359
|
-
const chatId = (0, jotai.useAtomValue)(require_app.chatIdAtom);
|
|
2360
|
-
const supportedEvent = (0, jotai.useAtomValue)(require_app.supportedEventAtom);
|
|
2361
|
-
const orgId = "mock-org-id";
|
|
2362
|
-
const variantInfo = (0, jotai.useAtomValue)(require_app.variantInfoAtom);
|
|
2363
|
-
const settingsContext = useSystemSettingsContext();
|
|
2364
|
-
const messageInterceptor = require_useMessageInterceptor.useMessageInterceptor();
|
|
2365
|
-
const handleSearchResults = (0, jotai.useSetAtom)(require_search.handleSearchResultsAtom);
|
|
2366
|
-
const setSearchIsLoading = (0, jotai.useSetAtom)(require_search.chatSearchIsLoadingAtom);
|
|
2367
|
-
const { track } = useAmplitudeTracking();
|
|
2368
|
-
const getStreamingResponses = (0, react.useCallback)(async (payload) => {
|
|
2369
|
-
logPerfMetric(require_chat.PerfMetricsEvents.FirstResponseStarted);
|
|
2370
|
-
const stream = commerce_api_default.getNextResponseStreaming(payload);
|
|
2371
|
-
try {
|
|
2372
|
-
setRequestFailure(false);
|
|
2373
|
-
const { hasSearchResults } = await processStreamingResponse(stream, messageInterceptor, handleSearchResults, setMessages, setSearchIsLoading, chatId);
|
|
2374
|
-
return { hasSearchResults };
|
|
2375
|
-
} catch (e) {
|
|
2376
|
-
handleStreamingError(e, setRequestFailure, setMessages);
|
|
2377
|
-
throw e;
|
|
2378
|
-
} finally {
|
|
2379
|
-
logPerfMetric(require_chat.PerfMetricsEvents.FirstResponseCompleted);
|
|
2380
|
-
}
|
|
2381
|
-
}, [
|
|
2382
|
-
logPerfMetric,
|
|
2383
|
-
setRequestFailure,
|
|
2384
|
-
messageInterceptor,
|
|
2385
|
-
handleSearchResults,
|
|
2386
|
-
setMessages,
|
|
2387
|
-
setSearchIsLoading,
|
|
2388
|
-
chatId
|
|
2389
|
-
]);
|
|
2390
|
-
const getSuggestions = (0, react.useCallback)(async () => {
|
|
2391
|
-
logPerfMetric(require_chat.PerfMetricsEvents.FirstSuggestionsStarted);
|
|
2392
|
-
setSuggestionsLoading(true);
|
|
2393
|
-
setSuggestions([]);
|
|
2394
|
-
const payloadWithoutAppLoaded = require_chat.createResponsePayload({
|
|
2395
|
-
userEvents: [],
|
|
2396
|
-
generationParams: settingsContext.generationParams
|
|
2397
|
-
});
|
|
2398
|
-
const response = await commerce_api_default.getNextSuggestions(payloadWithoutAppLoaded);
|
|
2399
|
-
setSuggestions(response.sort((a, b) => a.content.length - b.content.length));
|
|
2400
|
-
setSuggestionsLoading(false);
|
|
2401
|
-
logPerfMetric(require_chat.PerfMetricsEvents.FirstSuggestionsCompleted);
|
|
2402
|
-
}, [
|
|
2403
|
-
logPerfMetric,
|
|
2404
|
-
setSuggestionsLoading,
|
|
2405
|
-
setSuggestions,
|
|
2406
|
-
settingsContext.generationParams
|
|
2407
|
-
]);
|
|
2408
|
-
const getResponses = (0, react.useCallback)(async (payload) => {
|
|
2409
|
-
try {
|
|
2410
|
-
const requestPayload = payload ?? require_chat.createResponsePayload({
|
|
2411
|
-
userEvents,
|
|
2412
|
-
generationParams: settingsContext.generationParams
|
|
2413
|
-
});
|
|
2414
|
-
setResponseStreaming(true);
|
|
2415
|
-
setSuggestions([]);
|
|
2416
|
-
const startTimeMs = Date.now();
|
|
2417
|
-
await getStreamingResponses(requestPayload);
|
|
2418
|
-
recordAssistantResponse(startTimeMs, requestPayload, track);
|
|
2419
|
-
await getSuggestions();
|
|
2420
|
-
} catch (error) {
|
|
2421
|
-
require_api.logger_default.logError("[spiffy-ai] getResponses error", error);
|
|
2422
|
-
} finally {
|
|
2423
|
-
markUserEventsProcessed(userEvents.map(({ eventId }) => eventId));
|
|
2424
|
-
setUserHasReplied(false);
|
|
2425
|
-
setResponseStreaming(false);
|
|
2426
|
-
}
|
|
2427
|
-
}, [
|
|
2428
|
-
userEvents,
|
|
2429
|
-
settingsContext.generationParams,
|
|
2430
|
-
setResponseStreaming,
|
|
2431
|
-
setSuggestions,
|
|
2432
|
-
getStreamingResponses,
|
|
2433
|
-
markUserEventsProcessed,
|
|
2434
|
-
getSuggestions,
|
|
2435
|
-
setUserHasReplied,
|
|
2436
|
-
track
|
|
2437
|
-
]);
|
|
2438
|
-
(0, react.useEffect)(() => {
|
|
2439
|
-
const processUserEvents = async () => {
|
|
2440
|
-
if (responseStreaming || !widgetInitialized) return;
|
|
2441
|
-
if (variantInfo.variant === "pdp" && !variantInfo.productId || variantInfo.variant === "plp" && !variantInfo.plpId || variantInfo.variant === "page_visit" && !variantInfo.url) {
|
|
2442
|
-
require_api.logger_default.logDebug("[spiffy-ai] variantInfo has invalid values, skipping...", {
|
|
2443
|
-
variantInfo,
|
|
2444
|
-
supportedEvent
|
|
2445
|
-
});
|
|
2446
|
-
return;
|
|
2447
|
-
}
|
|
2448
|
-
require_api.logger_default.logDebug(`Assistants Turn is_currently_streaming=${responseStreaming} initialized=${widgetInitialized}`);
|
|
2449
|
-
try {
|
|
2450
|
-
await getResponses();
|
|
2451
|
-
require_api.logger_default.logInfo(`Assistants Turn [finished]`);
|
|
2452
|
-
} catch (error) {
|
|
2453
|
-
require_api.logger_default.logError("[spiffy-ai] Assistants Turn error", error);
|
|
2454
|
-
}
|
|
2455
|
-
};
|
|
2456
|
-
if (userQueueEventCount > 0) processUserEvents();
|
|
2457
|
-
}, [
|
|
2458
|
-
getResponses,
|
|
2459
|
-
responseStreaming,
|
|
2460
|
-
userQueueEventCount,
|
|
2461
|
-
widgetInitialized,
|
|
2462
|
-
variantInfo,
|
|
2463
|
-
supportedEvent
|
|
2464
|
-
]);
|
|
2465
|
-
(0, react.useEffect)(() => {
|
|
2466
|
-
if (widgetInitialized || responseStreaming) {
|
|
2467
|
-
require_api.logger_default.logDebug(`[spiffy-ai] initializeWidget [skipped] is_currently_streaming=${responseStreaming} is_initialized=${widgetInitialized}`);
|
|
2468
|
-
return;
|
|
2469
|
-
}
|
|
2470
|
-
const hydrateChat = async () => {
|
|
2471
|
-
try {
|
|
2472
|
-
require_api.logger_default.logDebug(`[spiffy-ai] initializeWidget is_currently_streaming=${responseStreaming} is_initialized=${widgetInitialized}`);
|
|
2473
|
-
const { messages: existingMessages, userEvents: userEvents$1 } = await commerce_api_default.getResponses(orgId, chatId, userId);
|
|
2474
|
-
setMessages([...existingMessages]);
|
|
2475
|
-
setUserEvents([...userEvents$1]);
|
|
2476
|
-
getResponses();
|
|
2477
|
-
} catch (error) {
|
|
2478
|
-
require_api.logger_default.logInfo(`Init chat [exception] chat_id=${chatId} error=${error}`, error);
|
|
2479
|
-
if (error instanceof SessionRestartRequired) {
|
|
2480
|
-
const appLoadedEvent = createAppLoadedEvent();
|
|
2481
|
-
const visitEvent = createVisitUserEvent({ variantInfo });
|
|
2482
|
-
setMessages([]);
|
|
2483
|
-
clearUserEventQueue();
|
|
2484
|
-
if (visitEvent) {
|
|
2485
|
-
const payload = require_chat.createResponsePayload({
|
|
2486
|
-
userEvents: [appLoadedEvent, visitEvent],
|
|
2487
|
-
generationParams: settingsContext.generationParams
|
|
2488
|
-
});
|
|
2489
|
-
getResponses(payload);
|
|
2490
|
-
}
|
|
2491
|
-
}
|
|
2492
|
-
} finally {
|
|
2493
|
-
setWidgetInitialized(true);
|
|
2494
|
-
}
|
|
2495
|
-
};
|
|
2496
|
-
hydrateChat();
|
|
2497
|
-
}, []);
|
|
2498
|
-
const onFocus = (0, react.useCallback)(async () => {
|
|
2499
|
-
try {
|
|
2500
|
-
if (!responseStreaming && !suggestionsLoading && orgId) {
|
|
2501
|
-
const { messages: existingMessages } = await commerce_api_default.getResponses(orgId, chatId, userId);
|
|
2502
|
-
if (existingMessages.length > messages.length) setMessages([...existingMessages]);
|
|
2503
|
-
}
|
|
2504
|
-
} catch (error) {
|
|
2505
|
-
require_api.logger_default.logError("[spiffy-ai] onFocus error", error);
|
|
2506
|
-
}
|
|
2507
|
-
}, [
|
|
2508
|
-
responseStreaming,
|
|
2509
|
-
suggestionsLoading,
|
|
2510
|
-
orgId,
|
|
2511
|
-
chatId,
|
|
2512
|
-
userId,
|
|
2513
|
-
messages.length,
|
|
2514
|
-
setMessages
|
|
2515
|
-
]);
|
|
2516
|
-
(0, react.useEffect)(() => {
|
|
2517
|
-
window.addEventListener("focus", onFocus);
|
|
2518
|
-
return () => {
|
|
2519
|
-
window.removeEventListener("focus", onFocus);
|
|
2520
|
-
};
|
|
2521
|
-
}, [onFocus]);
|
|
2522
|
-
const chatContext = (0, react.useMemo)(() => ({}), []);
|
|
2523
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChatContext.Provider, {
|
|
2524
|
-
value: chatContext,
|
|
2525
|
-
children
|
|
2526
|
-
});
|
|
2527
|
-
};
|
|
2528
|
-
|
|
2529
|
-
//#endregion
|
|
2530
|
-
//#region src/contexts/enviveCssContext.tsx
|
|
2531
|
-
const EnviveCssProvider = ({ children }) => {
|
|
2532
|
-
const { colorsConfig, frontendConfig, loading } = useNewOrgConfig();
|
|
2533
|
-
let merchantThemeCss = `* {}`;
|
|
2534
|
-
if (colorsConfig && !loading) merchantThemeCss = `
|
|
2535
|
-
* {
|
|
2536
|
-
--spiffy-colors-text-primary: ${colorsConfig.textPrimary};
|
|
2537
|
-
--spiffy-colors-text-secondary: ${colorsConfig.textSecondary};
|
|
2538
|
-
--spiffy-colors-text-accent: ${colorsConfig.textAccent};
|
|
2539
|
-
--spiffy-colors-text-link: ${colorsConfig.textLink};
|
|
2540
|
-
--spiffy-colors-text-light: ${colorsConfig.textLight};
|
|
2541
|
-
--spiffy-colors-background-primary: ${colorsConfig.backgroundPrimary};
|
|
2542
|
-
--spiffy-colors-background-secondary: ${colorsConfig.backgroundSecondary};
|
|
2543
|
-
--spiffy-colors-background-secondary-dark: ${colorsConfig.backgroundSecondaryDark};
|
|
2544
|
-
--spiffy-colors-background-tertiary: ${colorsConfig.backgroundTertiary};
|
|
2545
|
-
--spiffy-colors-background-dark: ${colorsConfig.backgroundDark};
|
|
2546
|
-
--spiffy-colors-background-light: ${colorsConfig.backgroundLight};
|
|
2547
|
-
--spiffy-colors-background-saturated: ${colorsConfig.backgroundSaturated};
|
|
2548
|
-
--spiffy-colors-border-light: ${colorsConfig.borderLight};
|
|
2549
|
-
--spiffy-colors-border-medium: ${colorsConfig.borderMedium};
|
|
2550
|
-
--spiffy-colors-border-dark: ${colorsConfig.borderDark};
|
|
2551
|
-
--spiffy-colors-border-outline: ${colorsConfig.borderOutline};
|
|
2552
|
-
--spiffy-colors-accent-primary: ${colorsConfig.accentPrimary};
|
|
2553
|
-
--spiffy-colors-accent-secondary: ${colorsConfig.accentSecondary};
|
|
2554
|
-
}`;
|
|
2555
|
-
console.log(frontendConfig);
|
|
2556
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
2557
|
-
frontendConfig ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", {
|
|
2558
|
-
id: "merchant-css-overrides",
|
|
2559
|
-
children: `${frontendConfig.merchantOverrideCss}`
|
|
2560
|
-
}) : null,
|
|
2561
|
-
colorsConfig ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", {
|
|
2562
|
-
id: "merchant-css-colors",
|
|
2563
|
-
children: `${merchantThemeCss}`
|
|
2564
|
-
}) : null,
|
|
2565
|
-
children
|
|
2566
|
-
] });
|
|
2567
|
-
};
|
|
2568
|
-
|
|
2569
|
-
//#endregion
|
|
2570
|
-
//#region src/contexts/systemSettingsContext.tsx
|
|
2571
|
-
const getChatModelName = () => {
|
|
2572
|
-
const urlObj = new URL(window.location.href);
|
|
2573
|
-
const params = new URLSearchParams(urlObj.search);
|
|
2574
|
-
return Object.fromEntries(params.entries()).llm_model_name;
|
|
2575
|
-
};
|
|
2576
|
-
const defaultGenerationParams = {
|
|
2577
|
-
stream: true,
|
|
2578
|
-
numSuggestions: 3,
|
|
2579
|
-
model: getChatModelName()
|
|
2580
|
-
};
|
|
2581
|
-
const SystemSettingsContext = (0, react.createContext)(void 0);
|
|
2582
|
-
const SystemSettingsContextProvider = ({ children, generationParams, showDebugBar }) => {
|
|
2583
|
-
const [params, setParams] = (0, react.useState)(() => generationParams ?? defaultGenerationParams);
|
|
2584
|
-
const endpointURL = (0, jotai.useAtomValue)(require_enviveConfig.baseUrlAtom);
|
|
2585
|
-
const settingsContextValues = (0, react.useMemo)(() => ({
|
|
2586
|
-
generationParams: params,
|
|
2587
|
-
showDebugBar,
|
|
2588
|
-
setGenerationParams: setParams,
|
|
2589
|
-
endpointURL
|
|
2590
|
-
}), [
|
|
2591
|
-
generationParams,
|
|
2592
|
-
endpointURL,
|
|
2593
|
-
showDebugBar
|
|
2594
|
-
]);
|
|
2595
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SystemSettingsContext.Provider, {
|
|
2596
|
-
value: settingsContextValues,
|
|
2597
|
-
children
|
|
2598
|
-
});
|
|
2599
|
-
};
|
|
2600
|
-
|
|
2601
|
-
//#endregion
|
|
2602
|
-
Object.defineProperty(exports, 'CdnProvider', {
|
|
2603
|
-
enumerable: true,
|
|
2604
|
-
get: function () {
|
|
2605
|
-
return CdnProvider;
|
|
2606
|
-
}
|
|
2607
|
-
});
|
|
2608
|
-
Object.defineProperty(exports, 'ChatContext', {
|
|
2609
|
-
enumerable: true,
|
|
2610
|
-
get: function () {
|
|
2611
|
-
return ChatContext;
|
|
2612
|
-
}
|
|
2613
|
-
});
|
|
2614
|
-
Object.defineProperty(exports, 'ChatContextProvider', {
|
|
2615
|
-
enumerable: true,
|
|
2616
|
-
get: function () {
|
|
2617
|
-
return ChatContextProvider;
|
|
2618
|
-
}
|
|
2619
|
-
});
|
|
2620
|
-
Object.defineProperty(exports, 'EnviveCssProvider', {
|
|
2621
|
-
enumerable: true,
|
|
2622
|
-
get: function () {
|
|
2623
|
-
return EnviveCssProvider;
|
|
2624
|
-
}
|
|
2625
|
-
});
|
|
2626
|
-
Object.defineProperty(exports, 'FeatureFlagServiceProvider', {
|
|
2627
|
-
enumerable: true,
|
|
2628
|
-
get: function () {
|
|
2629
|
-
return FeatureFlagServiceProvider;
|
|
2630
|
-
}
|
|
2631
|
-
});
|
|
2632
|
-
Object.defineProperty(exports, 'GraphQLProvider', {
|
|
2633
|
-
enumerable: true,
|
|
2634
|
-
get: function () {
|
|
2635
|
-
return GraphQLProvider;
|
|
2636
|
-
}
|
|
2637
|
-
});
|
|
2638
|
-
Object.defineProperty(exports, 'NewOrgConfigProvider', {
|
|
2639
|
-
enumerable: true,
|
|
2640
|
-
get: function () {
|
|
2641
|
-
return NewOrgConfigProvider;
|
|
2642
|
-
}
|
|
2643
|
-
});
|
|
2644
|
-
Object.defineProperty(exports, 'SearchProvider', {
|
|
2645
|
-
enumerable: true,
|
|
2646
|
-
get: function () {
|
|
2647
|
-
return SearchProvider;
|
|
2648
|
-
}
|
|
2649
|
-
});
|
|
2650
|
-
Object.defineProperty(exports, 'SearchResultsState', {
|
|
2651
|
-
enumerable: true,
|
|
2652
|
-
get: function () {
|
|
2653
|
-
return SearchResultsState;
|
|
2654
|
-
}
|
|
2655
|
-
});
|
|
2656
|
-
Object.defineProperty(exports, 'SessionStorageProvider', {
|
|
2657
|
-
enumerable: true,
|
|
2658
|
-
get: function () {
|
|
2659
|
-
return SessionStorageProvider;
|
|
2660
|
-
}
|
|
2661
|
-
});
|
|
2662
|
-
Object.defineProperty(exports, 'ShopifyUrlProvider', {
|
|
2663
|
-
enumerable: true,
|
|
2664
|
-
get: function () {
|
|
2665
|
-
return ShopifyUrlProvider;
|
|
2666
|
-
}
|
|
2667
|
-
});
|
|
2668
|
-
Object.defineProperty(exports, 'SystemSettingsContext', {
|
|
2669
|
-
enumerable: true,
|
|
2670
|
-
get: function () {
|
|
2671
|
-
return SystemSettingsContext;
|
|
2672
|
-
}
|
|
2673
|
-
});
|
|
2674
|
-
Object.defineProperty(exports, 'SystemSettingsContextProvider', {
|
|
2675
|
-
enumerable: true,
|
|
2676
|
-
get: function () {
|
|
2677
|
-
return SystemSettingsContextProvider;
|
|
2678
|
-
}
|
|
2679
|
-
});
|
|
2680
|
-
Object.defineProperty(exports, 'UserIdentityProvider', {
|
|
2681
|
-
enumerable: true,
|
|
2682
|
-
get: function () {
|
|
2683
|
-
return UserIdentityProvider;
|
|
2684
|
-
}
|
|
2685
|
-
});
|
|
2686
|
-
Object.defineProperty(exports, 'createAppLoadedEvent', {
|
|
2687
|
-
enumerable: true,
|
|
2688
|
-
get: function () {
|
|
2689
|
-
return createAppLoadedEvent;
|
|
2690
|
-
}
|
|
2691
|
-
});
|
|
2692
|
-
Object.defineProperty(exports, 'createVisitUserEvent', {
|
|
2693
|
-
enumerable: true,
|
|
2694
|
-
get: function () {
|
|
2695
|
-
return createVisitUserEvent;
|
|
2696
|
-
}
|
|
2697
|
-
});
|
|
2698
|
-
Object.defineProperty(exports, 'defaultGenerationParams', {
|
|
2699
|
-
enumerable: true,
|
|
2700
|
-
get: function () {
|
|
2701
|
-
return defaultGenerationParams;
|
|
2702
|
-
}
|
|
2703
|
-
});
|
|
2704
|
-
Object.defineProperty(exports, 'getSearchResultsState', {
|
|
2705
|
-
enumerable: true,
|
|
2706
|
-
get: function () {
|
|
2707
|
-
return getSearchResultsState;
|
|
2708
|
-
}
|
|
2709
|
-
});
|
|
2710
|
-
Object.defineProperty(exports, 'isElementPartiallyVisible', {
|
|
2711
|
-
enumerable: true,
|
|
2712
|
-
get: function () {
|
|
2713
|
-
return isElementPartiallyVisible;
|
|
2714
|
-
}
|
|
2715
|
-
});
|
|
2716
|
-
Object.defineProperty(exports, 'isWithinBusinessHours', {
|
|
2717
|
-
enumerable: true,
|
|
2718
|
-
get: function () {
|
|
2719
|
-
return isWithinBusinessHours;
|
|
2720
|
-
}
|
|
2721
|
-
});
|
|
2722
|
-
Object.defineProperty(exports, 'useAmplitudeTracking', {
|
|
2723
|
-
enumerable: true,
|
|
2724
|
-
get: function () {
|
|
2725
|
-
return useAmplitudeTracking;
|
|
2726
|
-
}
|
|
2727
|
-
});
|
|
2728
|
-
Object.defineProperty(exports, 'useAssetUrl', {
|
|
2729
|
-
enumerable: true,
|
|
2730
|
-
get: function () {
|
|
2731
|
-
return useAssetUrl;
|
|
2732
|
-
}
|
|
2733
|
-
});
|
|
2734
|
-
Object.defineProperty(exports, 'useBlockBackButton', {
|
|
2735
|
-
enumerable: true,
|
|
2736
|
-
get: function () {
|
|
2737
|
-
return useBlockBackButton;
|
|
2738
|
-
}
|
|
2739
|
-
});
|
|
2740
|
-
Object.defineProperty(exports, 'useCdn', {
|
|
2741
|
-
enumerable: true,
|
|
2742
|
-
get: function () {
|
|
2743
|
-
return useCdn;
|
|
2744
|
-
}
|
|
2745
|
-
});
|
|
2746
|
-
Object.defineProperty(exports, 'useCdnBasePath', {
|
|
2747
|
-
enumerable: true,
|
|
2748
|
-
get: function () {
|
|
2749
|
-
return useCdnBasePath;
|
|
2750
|
-
}
|
|
2751
|
-
});
|
|
2752
|
-
Object.defineProperty(exports, 'useCdnUrl', {
|
|
2753
|
-
enumerable: true,
|
|
2754
|
-
get: function () {
|
|
2755
|
-
return useCdnUrl;
|
|
2756
|
-
}
|
|
2757
|
-
});
|
|
2758
|
-
Object.defineProperty(exports, 'useChatToggle', {
|
|
2759
|
-
enumerable: true,
|
|
2760
|
-
get: function () {
|
|
2761
|
-
return useChatToggle;
|
|
2762
|
-
}
|
|
2763
|
-
});
|
|
2764
|
-
Object.defineProperty(exports, 'useChatToggleAnalytics', {
|
|
2765
|
-
enumerable: true,
|
|
2766
|
-
get: function () {
|
|
2767
|
-
return useChatToggleAnalytics;
|
|
2768
|
-
}
|
|
2769
|
-
});
|
|
2770
|
-
Object.defineProperty(exports, 'useColorsAndFrontendConfig', {
|
|
2771
|
-
enumerable: true,
|
|
2772
|
-
get: function () {
|
|
2773
|
-
return useColorsAndFrontendConfig;
|
|
2774
|
-
}
|
|
2775
|
-
});
|
|
2776
|
-
Object.defineProperty(exports, 'useCurrentPageType', {
|
|
2777
|
-
enumerable: true,
|
|
2778
|
-
get: function () {
|
|
2779
|
-
return useCurrentPageType;
|
|
2780
|
-
}
|
|
2781
|
-
});
|
|
2782
|
-
Object.defineProperty(exports, 'useCustomerSupportHandoff', {
|
|
2783
|
-
enumerable: true,
|
|
2784
|
-
get: function () {
|
|
2785
|
-
return useCustomerSupportHandoff;
|
|
2786
|
-
}
|
|
2787
|
-
});
|
|
2788
|
-
Object.defineProperty(exports, 'useDebounce', {
|
|
2789
|
-
enumerable: true,
|
|
2790
|
-
get: function () {
|
|
2791
|
-
return useDebounce;
|
|
2792
|
-
}
|
|
2793
|
-
});
|
|
2794
|
-
Object.defineProperty(exports, 'useElementObserver', {
|
|
2795
|
-
enumerable: true,
|
|
2796
|
-
get: function () {
|
|
2797
|
-
return useElementObserver;
|
|
2798
|
-
}
|
|
2799
|
-
});
|
|
2800
|
-
Object.defineProperty(exports, 'useEnviveFeatureFlag', {
|
|
2801
|
-
enumerable: true,
|
|
2802
|
-
get: function () {
|
|
2803
|
-
return useEnviveFeatureFlag;
|
|
2804
|
-
}
|
|
2805
|
-
});
|
|
2806
|
-
Object.defineProperty(exports, 'useFeatureFlagService', {
|
|
2807
|
-
enumerable: true,
|
|
2808
|
-
get: function () {
|
|
2809
|
-
return useFeatureFlagService;
|
|
2810
|
-
}
|
|
2811
|
-
});
|
|
2812
|
-
Object.defineProperty(exports, 'useGrabAndScroll', {
|
|
2813
|
-
enumerable: true,
|
|
2814
|
-
get: function () {
|
|
2815
|
-
return useGrabAndScroll;
|
|
2816
|
-
}
|
|
2817
|
-
});
|
|
2818
|
-
Object.defineProperty(exports, 'useGraphQLClient', {
|
|
2819
|
-
enumerable: true,
|
|
2820
|
-
get: function () {
|
|
2821
|
-
return useGraphQLClient;
|
|
2822
|
-
}
|
|
2823
|
-
});
|
|
2824
|
-
Object.defineProperty(exports, 'useIdentifyUser', {
|
|
2825
|
-
enumerable: true,
|
|
2826
|
-
get: function () {
|
|
2827
|
-
return useIdentifyUser;
|
|
2828
|
-
}
|
|
2829
|
-
});
|
|
2830
|
-
Object.defineProperty(exports, 'useImageResolver', {
|
|
2831
|
-
enumerable: true,
|
|
2832
|
-
get: function () {
|
|
2833
|
-
return useImageResolver;
|
|
2834
|
-
}
|
|
2835
|
-
});
|
|
2836
|
-
Object.defineProperty(exports, 'useIntersection', {
|
|
2837
|
-
enumerable: true,
|
|
2838
|
-
get: function () {
|
|
2839
|
-
return useIntersection;
|
|
2840
|
-
}
|
|
2841
|
-
});
|
|
2842
|
-
Object.defineProperty(exports, 'useIsSmallScreen', {
|
|
2843
|
-
enumerable: true,
|
|
2844
|
-
get: function () {
|
|
2845
|
-
return useIsSmallScreen;
|
|
2846
|
-
}
|
|
2847
|
-
});
|
|
2848
|
-
Object.defineProperty(exports, 'useLocalStorageListener', {
|
|
2849
|
-
enumerable: true,
|
|
2850
|
-
get: function () {
|
|
2851
|
-
return useLocalStorageListener;
|
|
2852
|
-
}
|
|
2853
|
-
});
|
|
2854
|
-
Object.defineProperty(exports, 'useLocalStorageValue', {
|
|
2855
|
-
enumerable: true,
|
|
2856
|
-
get: function () {
|
|
2857
|
-
return useLocalStorageValue;
|
|
2858
|
-
}
|
|
2859
|
-
});
|
|
2860
|
-
Object.defineProperty(exports, 'useMessageFilter', {
|
|
2861
|
-
enumerable: true,
|
|
2862
|
-
get: function () {
|
|
2863
|
-
return useMessageFilter;
|
|
2864
|
-
}
|
|
2865
|
-
});
|
|
2866
|
-
Object.defineProperty(exports, 'useMessageScrollObserver', {
|
|
2867
|
-
enumerable: true,
|
|
2868
|
-
get: function () {
|
|
2869
|
-
return useMessageScrollObserver;
|
|
2870
|
-
}
|
|
2871
|
-
});
|
|
2872
|
-
Object.defineProperty(exports, 'useNewOrgConfig', {
|
|
2873
|
-
enumerable: true,
|
|
2874
|
-
get: function () {
|
|
2875
|
-
return useNewOrgConfig;
|
|
2876
|
-
}
|
|
2877
|
-
});
|
|
2878
|
-
Object.defineProperty(exports, 'useNewOrgConfigContext', {
|
|
2879
|
-
enumerable: true,
|
|
2880
|
-
get: function () {
|
|
2881
|
-
return useNewOrgConfigContext;
|
|
2882
|
-
}
|
|
2883
|
-
});
|
|
2884
|
-
Object.defineProperty(exports, 'useOrgId', {
|
|
2885
|
-
enumerable: true,
|
|
2886
|
-
get: function () {
|
|
2887
|
-
return useOrgId;
|
|
2888
|
-
}
|
|
2889
|
-
});
|
|
2890
|
-
Object.defineProperty(exports, 'useProductId', {
|
|
2891
|
-
enumerable: true,
|
|
2892
|
-
get: function () {
|
|
2893
|
-
return useProductId;
|
|
2894
|
-
}
|
|
2895
|
-
});
|
|
2896
|
-
Object.defineProperty(exports, 'useProductSearch', {
|
|
2897
|
-
enumerable: true,
|
|
2898
|
-
get: function () {
|
|
2899
|
-
return useProductSearch;
|
|
2900
|
-
}
|
|
2901
|
-
});
|
|
2902
|
-
Object.defineProperty(exports, 'useSearch', {
|
|
2903
|
-
enumerable: true,
|
|
2904
|
-
get: function () {
|
|
2905
|
-
return useSearch;
|
|
2906
|
-
}
|
|
2907
|
-
});
|
|
2908
|
-
Object.defineProperty(exports, 'useSearchService', {
|
|
2909
|
-
enumerable: true,
|
|
2910
|
-
get: function () {
|
|
2911
|
-
return useSearchService;
|
|
2912
|
-
}
|
|
2913
|
-
});
|
|
2914
|
-
Object.defineProperty(exports, 'useSearchWithQuery', {
|
|
2915
|
-
enumerable: true,
|
|
2916
|
-
get: function () {
|
|
2917
|
-
return useSearchWithQuery;
|
|
2918
|
-
}
|
|
2919
|
-
});
|
|
2920
|
-
Object.defineProperty(exports, 'useSessionStorage', {
|
|
2921
|
-
enumerable: true,
|
|
2922
|
-
get: function () {
|
|
2923
|
-
return useSessionStorage;
|
|
2924
|
-
}
|
|
2925
|
-
});
|
|
2926
|
-
Object.defineProperty(exports, 'useSessionStorageValue', {
|
|
2927
|
-
enumerable: true,
|
|
2928
|
-
get: function () {
|
|
2929
|
-
return useSessionStorageValue;
|
|
2930
|
-
}
|
|
2931
|
-
});
|
|
2932
|
-
Object.defineProperty(exports, 'useShopifyUrl', {
|
|
2933
|
-
enumerable: true,
|
|
2934
|
-
get: function () {
|
|
2935
|
-
return useShopifyUrl;
|
|
2936
|
-
}
|
|
2937
|
-
});
|
|
2938
|
-
Object.defineProperty(exports, 'useShopifyUrlOperations', {
|
|
2939
|
-
enumerable: true,
|
|
2940
|
-
get: function () {
|
|
2941
|
-
return useShopifyUrlOperations;
|
|
2942
|
-
}
|
|
2943
|
-
});
|
|
2944
|
-
Object.defineProperty(exports, 'useSnapCalculator', {
|
|
2945
|
-
enumerable: true,
|
|
2946
|
-
get: function () {
|
|
2947
|
-
return useSnapCalculator;
|
|
2948
|
-
}
|
|
2949
|
-
});
|
|
2950
|
-
Object.defineProperty(exports, 'useSpiffyFeatureFlag', {
|
|
2951
|
-
enumerable: true,
|
|
2952
|
-
get: function () {
|
|
2953
|
-
return useSpiffyFeatureFlag;
|
|
2954
|
-
}
|
|
2955
|
-
});
|
|
2956
|
-
Object.defineProperty(exports, 'useSystemSettingsContext', {
|
|
2957
|
-
enumerable: true,
|
|
2958
|
-
get: function () {
|
|
2959
|
-
return useSystemSettingsContext;
|
|
2960
|
-
}
|
|
2961
|
-
});
|
|
2962
|
-
Object.defineProperty(exports, 'useTrackComponentVisibleEvent', {
|
|
2963
|
-
enumerable: true,
|
|
2964
|
-
get: function () {
|
|
2965
|
-
return useTrackComponentVisibleEvent;
|
|
2966
|
-
}
|
|
2967
|
-
});
|
|
2968
|
-
Object.defineProperty(exports, 'useUpdateAnalyticsProps', {
|
|
2969
|
-
enumerable: true,
|
|
2970
|
-
get: function () {
|
|
2971
|
-
return useUpdateAnalyticsProps;
|
|
2972
|
-
}
|
|
2973
|
-
});
|
|
2974
|
-
Object.defineProperty(exports, 'useUserIdentity', {
|
|
2975
|
-
enumerable: true,
|
|
2976
|
-
get: function () {
|
|
2977
|
-
return useUserIdentity;
|
|
2978
|
-
}
|
|
2979
|
-
});
|
|
2980
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGV4dHMtQjRpaFRCc1YuY2pzIiwibmFtZXMiOlsiQ2RuUHJvdmlkZXI6IFJlYWN0LkZDPHsgY2hpbGRyZW46IFJlYWN0LlJlYWN0Tm9kZSB9PiIsImNkblVybEF0b20iLCJlcnJvclJlc3BvbnNlQm9keSIsInRocm93U2Vzc2lvblJlc3RhcnRSZXF1aXJlZElmIiwiUmVzcG9uc2VFcnJvciIsImdldEF0b21TdG9yZSIsImJhc2VVcmxBdG9tIiwiY29uZmlnOiBDb25maWd1cmF0aW9uIiwiQ29uZmlndXJhdGlvbiIsIkRlZmF1bHRBcGkiLCJJbmZlcmVuY2VBcGkiLCJDdXN0b21lclNlcnZpY2VBcGkiLCJvcmdTaG9ydE5hbWVBdG9tIiwib3JnSWRBdG9tIiwidXNlcklkQXRvbSIsImNoYXRJZEF0b20iLCJjb250ZXh0U291cmNlQXRvbSIsImVudkF0b20iLCJmZWF0dXJlRmxhZ1NlcnZpY2VBdG9tIiwiY29udGV4dDogQ29udGV4dCIsIkNvbnRleHRTb3VyY2VFbnVtIiwiQ29udGV4dEVudkVudW0iLCJtZXNzYWdlUmVxdWVzdFRvQ29tbWVyY2VNZXNzYWdlUmVxdWVzdCIsInZhbGlkYXRlUmVzcG9uc2UiLCJtZXNzYWdlRnJvbVJlc3BvbnNlIiwiZXJyOiB1bmtub3duIiwiZXJyb3I6IHVua25vd24iLCJ2YWxpZGF0ZVN1Z2dlc3Rpb24iLCJkYXRhOiBWMUdldFNlc3Npb25NZXNzYWdlczIwMFJlc3BvbnNlIiwicmVzcG9uc2VzOiBSZXNwb25zZVtdW10iLCJzdWdnZXN0aW9uczogU3VnZ2VzdGlvbltdIiwidXNlckV2ZW50czogVXNlckV2ZW50W10iLCJ2YWxpZGF0ZVVzZXJFdmVudCIsIlVzZXJFdmVudENhdGVnb3J5IiwiYXNzaXN0YW50TWVzc2FnZXM6IE1lc3NhZ2VbXVtdIiwiUmVzcG9uc2VDYXRlZ29yeSIsInVzZXJNZXNzYWdlczogTWVzc2FnZVtdW10iLCJtZXNzYWdlRnJvbVF1ZXJ5RXZlbnQiLCJtZXNzYWdlRnJvbVN1Z2dlc3Rpb25FdmVudCIsIkZvcm1UeXBlIiwibWVzc2FnZUZyb21Gb3JtU3VibWl0dGVkRXZlbnQiLCJjb3JlU3VwcG9ydGVkRXZlbnRSZXF1ZXN0VG9BcGlSZXF1ZXN0IiwiVjFPcmdDb25maWdHZXRTb3VyY2VFbnVtIiwicmVhY3RBcHBOYW1lQXRvbSIsInJlcXVlc3Q6IFYxT3JnQ29uZmlnR2V0UmVxdWVzdCIsIlByb2R1Y3RFeHBlcmltZW50IiwidmFsaWRhdGVPcmdDb25maWdSZXN1bHRzIiwidXNlQW1wbGl0dWRlIiwiY2hhdE9uVG9nZ2xlQXRvbSIsImNoYXRBdG9tIiwidXNlQW1wbGl0dWRlIiwiU3BpZmZ5TWV0cmljc0V2ZW50TmFtZSIsImNoYXRPblRvZ2dsZUF0b20iLCJET01PYnNlcnZlciIsImNvbmZpZ1ZlcnNpb24iLCJvcmdMZXZlbEFwaUtleUF0b20iLCJiYXNlVXJsQXRvbSIsImdldE1lcmNoYW50T3JnSWRRdWVyeSIsInZhbGlkYXRlR3JhcGhRTE9yZ0lkIiwidHJhbnNmb3JtU25ha2VUb0NhbWVsIiwiVUFQYXJzZXIiLCJVc2VySWRlbnRpdHlQcm92aWRlcjogUmVhY3QuRkM8eyBjaGlsZHJlbjogUmVhY3QuUmVhY3ROb2RlIH0+IiwidXNlTG9jYWxTdG9yYWdlIiwiQ29tbWVyY2VBcGlDbGllbnQiLCJPcmdTaG9ydE5hbWUiLCJvcmdTaG9ydE5hbWVBdG9tIiwidXNlTG9jYWxTdG9yYWdlIiwibGlzdGVuZXI6IExvY2FsU3RvcmFnZUV2ZW50TGlzdGVuZXIiLCJMb2NhbFN0b3JhZ2VLZXlzIiwiTWVzc2FnZVR5cGUiLCJGZWF0dXJlR2F0ZXMiLCJGZWF0dXJlRmxhZ1NlcnZpY2VQcm92aWRlcjogUmVhY3QuRkM8XG4gIEZlYXR1cmVGbGFnU2VydmljZVByb3ZpZGVyUHJvcHNcbj4iLCJOZXdPcmdDb25maWdQcm92aWRlcjogUmVhY3QuRkM8TmV3T3JnQ29uZmlnUHJvdmlkZXJQcm9wcz4iLCJvcmdTaG9ydE5hbWVBdG9tIiwibmV3T3JnQ29uZmlnQXRvbSIsImdldEF0b21TdG9yZSIsIm9yZ0lkQXRvbSIsIlVzZXJFdmVudENhdGVnb3J5IiwiUExQQXR0cmlidXRlQ2F0ZWdvcnkiLCJvcmdTaG9ydE5hbWVBdG9tIiwic2VhcmNoQXRvbSIsImZpbHRlcmVkU2VhcmNoUHJvZHVjdHNBdG9tIiwicGVyZm9ybVNlYXJjaEF0b20iLCJhdXRvY29tcGxldGVTdGF0ZUF0b20iLCJzZWFyY2hQYXJhbXNBdG9tIiwiaXNGaWx0ZXJPcGVuQXRvbSIsInNlYXJjaFNlbGVjdGVkRmlsdGVyc0F0b20iLCJhZGRTZWFyY2hGaWx0ZXJBdG9tIiwicmVtb3ZlU2VhcmNoRmlsdGVyQXRvbSIsInNlYXJjaFByb2R1Y3RTb3J0aW5nQXRvbSIsImNsZWFyU2VhcmNoRmlsdGVyc0F0b20iLCJzZWFyY2hGaWx0ZXJzQXRvbSIsImZvcm1hdEZpbHRlckRpc3BsYXlOYW1lIiwiUHJvZHVjdFNvcnRpbmciLCJ1c2VBbXBsaXR1ZGUiLCJTcGlmZnlNZXRyaWNzRXZlbnROYW1lIiwiY3JlYXRlRmlsdGVyT3B0aW9uIiwiU3BpZmZ5V2lkZ2V0cyIsImhhbmRsZVNlbGVjdEZpbHRlckl0ZW06IFNlbGVjdEZpbHRlckl0ZW0iLCJlbnZpdmVPcmdTaG9ydE5hbWVBdG9tIiwiY2hhdElkQXRvbSIsInVzZXJJZEF0b20iLCJjb250ZXh0U291cmNlQXRvbSIsIkNvbnRleHRTb3VyY2VFbnVtIiwiZW52aXZlRW52QXRvbSIsIkNvbnRleHRFbnZFbnVtIiwidmFyaWFudEluZm9BdG9tIiwiUmVzcG9uc2VDYXRlZ29yeSIsIlJlc3BvbnNlRXJyb3IiLCJTZWFyY2hQcm92aWRlcjogUmVhY3QuRkM8eyBjaGlsZHJlbjogUmVhY3QuUmVhY3ROb2RlIH0+IiwidXNlRW52aXZlQ29uZmlnIiwiYmFzZVVybEF0b20iLCJjb25maWc6IENvbmZpZ3VyYXRpb24iLCJDb25maWd1cmF0aW9uIiwiU2VhcmNoQXBpIiwiU2Vzc2lvblN0b3JhZ2VQcm92aWRlcjogUmVhY3QuRkM8e1xuICBjaGlsZHJlbjogUmVhY3QuUmVhY3ROb2RlO1xufT4iLCJ2YWx1ZSIsIlNob3BpZnlVcmxQcm92aWRlcjogUmVhY3QuRkM8eyBjaGlsZHJlbjogUmVhY3QuUmVhY3ROb2RlIH0+IiwicGFyc2VIcmVmIiwiU3BpZmZ5TWV0cmljc0V2ZW50TmFtZSIsInVzZUFtcGxpdHVkZSIsInZhcmlhbnRJbmZvQXRvbSIsImhhc1BhcnNlZFZhcmlhbnRJbmZvQXRvbSIsInVzZUFtcGxpdHVkZSIsImRlZmF1bHRFdmVudFByb3BlcnRpZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IiwiU3BpZmZ5TWV0cmljc0V2ZW50TmFtZSIsImdldEF0b21TdG9yZSIsImNoYXRBdG9tIiwiY2hhdFNlYXJjaFN0YXRlQXRvbSIsImNoYXRTZWFyY2hQcm9kdWN0cyIsImNoYXRTZWFyY2hQcm9kdWN0U29ydGluZ0F0b20iLCJ1c2VyUXVlcnlQcm9wZXJ0eTogc3RyaW5nIHwgdW5kZWZpbmVkIiwiVXNlckV2ZW50Q2F0ZWdvcnkiLCJldmVudFByb3BzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiIsIk1lc3NhZ2VSb2xlIiwiTWVzc2FnZVR5cGUiLCJTcGlmZnlNZXRyaWNzRXZlbnROYW1lIiwibGFzdE1lc3NhZ2U6IE1lc3NhZ2UgfCB1bmRlZmluZWQiLCJtZXNzYWdlRnJvbVJlc3BvbnNlIiwiZXJyb3I6IHVua25vd24iLCJsb2dQZXJmTWV0cmljQXRvbSIsInVzZXJIYXNSZXBsaWVkQXRvbSIsIm1lc3NhZ2VzQXRvbSIsInVzZXJFdmVudHNBdG9tIiwic3VnZ2VzdGlvbnNBdG9tIiwic3VnZ2VzdGlvbnNMb2FkaW5nQXRvbSIsInJlc3BvbnNlU3RyZWFtaW5nQXRvbSIsInJlcXVlc3RGYWlsdXJlQXRvbSIsInVzZXJFdmVudFF1ZXVlQXRvbSIsInVzZXJRdWV1ZUV2ZW50Q291bnRBdG9tIiwicHJvY2Vzc1VzZXJFdmVudEF0b20iLCJjbGVhclVzZXJFdmVudEF0b20iLCJ1c2VySWRBdG9tIiwiY2hhdElkQXRvbSIsInN1cHBvcnRlZEV2ZW50QXRvbSIsInZhcmlhbnRJbmZvQXRvbSIsInVzZU1lc3NhZ2VJbnRlcmNlcHRvciIsImhhbmRsZVNlYXJjaFJlc3VsdHNBdG9tIiwiY2hhdFNlYXJjaElzTG9hZGluZ0F0b20iLCJQZXJmTWV0cmljc0V2ZW50cyIsIkNvbW1lcmNlQXBpQ2xpZW50IiwiY3JlYXRlUmVzcG9uc2VQYXlsb2FkIiwidXNlckV2ZW50cyIsIkVudml2ZUNzc1Byb3ZpZGVyOiBSZWFjdC5GQzxFbnZpdmVDc3NQcm92aWRlclByb3BzPiIsImRlZmF1bHRHZW5lcmF0aW9uUGFyYW1zOiBHZW5lcmF0aW9uUGFyYW1zIiwiYmFzZVVybEF0b20iXSwic291cmNlcyI6WyIuLi9zcmMvY29udGV4dHMvY2RuQ29udGV4dC50c3giLCIuLi9zcmMvdHlwZXMvZXhjZXB0aW9ucy9zZXNzaW9uRXhjZXB0aW9ucy50cyIsIi4uL3NyYy90eXBlcy9leGNlcHRpb25zL3Vuc3VwcG9ydGVkUHJvZHVjdEV4Y2VwdGlvbnMudHMiLCIuLi9zcmMvYXBwbGljYXRpb24vY29tbWVyY2UtYXBpLnRzIiwiLi4vc3JjL2hvb2tzL3VzZUFtcGxpdHVkZU9wZXJhdGlvbnMudHMiLCIuLi9zcmMvaG9va3MvdXNlQmxvY2tCYWNrQnV0dG9uLnRzIiwiLi4vc3JjL2hvb2tzL3VzZUNkbk9wZXJhdGlvbnMudHMiLCIuLi9zcmMvaG9va3MvdXNlQ2hhdFRvZ2dsZS50cyIsIi4uL3NyYy9ob29rcy91c2VDaGF0VG9nZ2xlQW5hbHl0aWNzLnRzIiwiLi4vc3JjL2hvb2tzL3VzZUN1c3RvbWVyU3VwcG9ydEhhbmRvZmYudHMiLCIuLi9zcmMvaG9va3MvdXNlRGVib3VuY2UudHMiLCIuLi9zcmMvaG9va3MvdXNlRWxlbWVudE9ic2VydmVyLnRzIiwiLi4vc3JjL2hvb2tzL3VzZUdyYWJBbmRTY3JvbGwudHMiLCIuLi9zcmMvY29udGV4dHMvZ3JhcGhxbENvbnRleHQudHN4IiwiLi4vc3JjL2hvb2tzL3VzZUdyYXBoUUxDb25maWcudHMiLCIuLi9zcmMvY29udGV4dHMvdXNlcklkZW50aXR5Q29udGV4dC50c3giLCIuLi9zcmMvaG9va3MvdXNlSWRlbnRpZnlVc2VyLnRzIiwiLi4vc3JjL2hvb2tzL3VzZUltYWdlUmVzb2x2ZXIudHMiLCIuLi9zcmMvaG9va3MvdXNlSW50ZXJzZWN0aW9uLnRzIiwiLi4vc3JjL2hvb2tzL3VzZUlzU21hbGxTY3JlZW4udHMiLCIuLi9zcmMvaG9va3MvdXNlTG9jYWxTdG9yYWdlT3BlcmF0aW9ucy50cyIsIi4uL3NyYy9ob29rcy91c2VNZXNzYWdlRmlsdGVyLnRzIiwiLi4vc3JjL2hvb2tzL3VzZU1lc3NhZ2VTY3JvbGxPYnNlcnZlci50cyIsIi4uL3NyYy9jb250ZXh0cy9mZWF0dXJlRmxhZ1NlcnZpY2VDb250ZXh0LnRzeCIsIi4uL3NyYy9jb250ZXh0cy9uZXdPcmdDb25maWdDb250ZXh0LnRzeCIsIi4uL3NyYy9ob29rcy91c2VOZXdPcmdDb25maWcudHMiLCIuLi9zcmMvaG9va3MvdXRpbHMudHMiLCIuLi9zcmMvaG9va3MvdXNlU2VhcmNoLnRzeCIsIi4uL3NyYy9ob29rcy91c2VBcHBEZXRhaWxzLnRzIiwiLi4vc3JjL2NvbnRleHRzL3NlYXJjaENvbnRleHQudHN4IiwiLi4vc3JjL2hvb2tzL3VzZVNlYXJjaE9wZXJhdGlvbnMudHMiLCIuLi9zcmMvY29udGV4dHMvc2Vzc2lvblN0b3JhZ2VDb250ZXh0LnRzeCIsIi4uL3NyYy9ob29rcy91c2VTZXNzaW9uU3RvcmFnZU9wZXJhdGlvbnMudHMiLCIuLi9zcmMvY29udGV4dHMvc2hvcGlmeVVybENvbnRleHQudHN4IiwiLi4vc3JjL2hvb2tzL3VzZVNob3BpZnlVcmxPcGVyYXRpb25zLnRzIiwiLi4vc3JjL2hvb2tzL3VzZVNuYXBDYWxjdWxhdG9yLnRzIiwiLi4vc3JjL2hvb2tzL3VzZVN5c3RlbVNldHRpbmdzQ29udGV4dC50cyIsIi4uL3NyYy9ob29rcy91c2VUcmFja0NvbXBvbmVudFZpc2libGVFdmVudC50cyIsIi4uL3NyYy9ob29rcy91c2VVcGRhdGVBbmFseXRpY3NQcm9wcy50cyIsIi4uL3NyYy9jb250ZXh0cy9jaGF0Q29udGV4dC50c3giLCIuLi9zcmMvY29udGV4dHMvZW52aXZlQ3NzQ29udGV4dC50c3giLCIuLi9zcmMvY29udGV4dHMvc3lzdGVtU2V0dGluZ3NDb250ZXh0LnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUmVhY3QsIHsgY3JlYXRlQ29udGV4dCwgdXNlQ29udGV4dCwgdXNlQ2FsbGJhY2ssIHVzZU1lbW8gfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IHVzZUF0b21WYWx1ZSB9IGZyb20gXCJqb3RhaVwiO1xuaW1wb3J0IHsgY2RuVXJsQXRvbSB9IGZyb20gXCIuLi9hdG9tcy9lbnZpdmUvZW52aXZlQ29uZmlnXCI7XG5cbmludGVyZmFjZSBDZG5Db250ZXh0VHlwZSB7XG4gIGNkblVybDogc3RyaW5nO1xuICBnZXRDZG5CYXNlUGF0aDogKCkgPT4gc3RyaW5nO1xuICBnZXRBc3NldFVSTDogKGFzc2V0TmFtZTogc3RyaW5nLCBvcmdTaG9ydE5hbWU6IHN0cmluZykgPT4gc3RyaW5nO1xufVxuXG5jb25zdCBDZG5Db250ZXh0ID0gY3JlYXRlQ29udGV4dDxDZG5Db250ZXh0VHlwZSB8IG51bGw+KG51bGwpO1xuXG5leHBvcnQgY29uc3QgQ2RuUHJvdmlkZXI6IFJlYWN0LkZDPHsgY2hpbGRyZW46IFJlYWN0LlJlYWN0Tm9kZSB9PiA9ICh7XG4gIGNoaWxkcmVuLFxufSkgPT4ge1xuICBjb25zdCBjZG5VcmxBdG9tVmFsdWUgPSB1c2VBdG9tVmFsdWUoY2RuVXJsQXRvbSk7XG4gIGNvbnN0IGNkblVybCA9IGNkblVybEF0b21WYWx1ZSB8fCBcImh0dHBzOi8vY2RuLnNwaWZmeS5haS9vdGhlclwiO1xuXG4gIGNvbnN0IGdldENkbkJhc2VQYXRoID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIHJldHVybiBjZG5Vcmw7XG4gIH0sIFtjZG5VcmxdKTtcblxuICBjb25zdCBnZXRBc3NldFVSTCA9IHVzZUNhbGxiYWNrKFxuICAgIChhc3NldE5hbWU6IHN0cmluZywgb3JnU2hvcnROYW1lOiBzdHJpbmcpID0+IHtcbiAgICAgIHJldHVybiBgJHtnZXRDZG5CYXNlUGF0aCgpfS9hc3NldHMvJHtvcmdTaG9ydE5hbWV9LyR7YXNzZXROYW1lfWA7XG4gICAgfSxcbiAgICBbZ2V0Q2RuQmFzZVBhdGhdXG4gICk7XG5cbiAgY29uc3QgdmFsdWUgPSB1c2VNZW1vKFxuICAgICgpID0+ICh7XG4gICAgICBjZG5VcmwsXG4gICAgICBnZXRDZG5CYXNlUGF0aCxcbiAgICAgIGdldEFzc2V0VVJMLFxuICAgIH0pLFxuICAgIFtjZG5VcmwsIGdldENkbkJhc2VQYXRoLCBnZXRBc3NldFVSTF1cbiAgKTtcblxuICByZXR1cm4gPENkbkNvbnRleHQuUHJvdmlkZXIgdmFsdWU9e3ZhbHVlfT57Y2hpbGRyZW59PC9DZG5Db250ZXh0LlByb3ZpZGVyPjtcbn07XG5cbmV4cG9ydCBjb25zdCB1c2VDZG4gPSAoKSA9PiB7XG4gIGNvbnN0IGNvbnRleHQgPSB1c2VDb250ZXh0KENkbkNvbnRleHQpO1xuICBpZiAoIWNvbnRleHQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1c2VDZG4gbXVzdCBiZSB1c2VkIHdpdGhpbiBhIENkblByb3ZpZGVyXCIpO1xuICB9XG4gIHJldHVybiBjb250ZXh0O1xufTtcbiIsImV4cG9ydCBjbGFzcyBTZXNzaW9uUmVzdGFydFJlcXVpcmVkIGV4dGVuZHMgRXJyb3Ige1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcignU2Vzc2lvbiByZXN0YXJ0IHJlcXVpcmVkJyk7XG4gICAgdGhpcy5uYW1lID0gJ1Nlc3Npb25SZXN0YXJ0UmVxdWlyZWQnO1xuICB9XG59XG4iLCJleHBvcnQgY2xhc3MgVW5zdXBwb3J0ZWRQcm9kdWN0RXhjZXB0aW9uIGV4dGVuZHMgRXJyb3Ige1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcignVW5zdXBwb3J0ZWQgcHJvZHVjdCcpO1xuICAgIHRoaXMubmFtZSA9ICdVbnN1cHBvcnRlZFByb2R1Y3QnO1xuICB9XG59IiwiaW1wb3J0IExvZ2dlciBmcm9tIFwic3JjL2FwcGxpY2F0aW9uL2xvZ2dpbmcvbG9nZ2VyXCI7XG5pbXBvcnQge1xuICBDb25maWd1cmF0aW9uLFxuICBDdXN0b21lclNlcnZpY2VBcGksXG4gIERlZmF1bHRBcGksXG4gIEluZmVyZW5jZUFwaSxcbiAgUmVwb3J0U2Vzc2lvblJlcXVlc3QsXG4gIFJlc3BvbnNlRXJyb3IsXG4gIFVzZXJFdmVudENhdGVnb3J5LFxuICBWMUdldFNlc3Npb25NZXNzYWdlczIwMFJlc3BvbnNlLFxuICBWMU9yZ0NvbmZpZ0dldFJlcXVlc3QsXG4gIENvbnRleHRTb3VyY2VFbnVtLFxuICBWMU9yZ0NvbmZpZ0dldFNvdXJjZUVudW0sXG4gIEN1c3RvbWVyU2VydmljZVByb3ZpZGVyLFxuICBSZXNwb25zZUNhdGVnb3J5LFxuICBGb3JtVHlwZSxcbn0gZnJvbSBcIkBzcGlmZnktYWkvY29tbWVyY2UtYXBpLWNsaWVudFwiO1xuaW1wb3J0IHsgdmFsaWRhdGVTdWdnZXN0aW9uIH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9tb2RlbHMvdmFsaWRhdG9ycy92YWxpZGF0ZVN1Z2dlc3Rpb25cIjtcbmltcG9ydCB7IHZhbGlkYXRlVXNlckV2ZW50IH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9tb2RlbHMvdmFsaWRhdG9ycy92YWxpZGF0ZVVzZXJFdmVudFwiO1xuaW1wb3J0IHtcbiAgbWVzc2FnZUZyb21RdWVyeUV2ZW50LFxuICBtZXNzYWdlRnJvbVJlc3BvbnNlLFxuICBtZXNzYWdlRnJvbVN1Z2dlc3Rpb25FdmVudCxcbn0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi91dGlsc1wiO1xuaW1wb3J0IHtcbiAgTWVzc2FnZSxcbiAgTmV4dE1lc3NhZ2VSZXF1ZXN0LFxuICBSZXNwb25zZSxcbiAgU3VnZ2VzdGlvbixcbiAgU3VwcG9ydGVkRXZlbnRSZXF1ZXN0LFxuICBVc2VyRXZlbnQsXG59IGZyb20gXCJzcmMvYXBwbGljYXRpb24vbW9kZWxzXCI7XG5pbXBvcnQgeyBtZXNzYWdlUmVxdWVzdFRvQ29tbWVyY2VNZXNzYWdlUmVxdWVzdCB9IGZyb20gXCJzcmMvYXBwbGljYXRpb24vdXRpbHMvbmV4dE1lc3NhZ2VSZXF1ZXN0VG9BcGlSZXF1ZXN0XCI7XG5pbXBvcnQgeyB2YWxpZGF0ZVJlc3BvbnNlIH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9tb2RlbHMvdmFsaWRhdG9ycy92YWxpZGF0ZVJlc3BvbnNlXCI7XG5pbXBvcnQgeyBjb3JlU3VwcG9ydGVkRXZlbnRSZXF1ZXN0VG9BcGlSZXF1ZXN0IH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi91dGlscy9zdXBwb3J0ZWRFdmVudFJlcXVlc3RUb0FwaVJlcXVlc3RcIjtcbmltcG9ydCB7IFNlc3Npb25SZXN0YXJ0UmVxdWlyZWQgfSBmcm9tIFwic3JjL3R5cGVzL2V4Y2VwdGlvbnMvc2Vzc2lvbkV4Y2VwdGlvbnNcIjtcbmltcG9ydCB7IFVuc3VwcG9ydGVkUHJvZHVjdEV4Y2VwdGlvbiB9IGZyb20gXCJzcmMvdHlwZXMvZXhjZXB0aW9ucy91bnN1cHBvcnRlZFByb2R1Y3RFeGNlcHRpb25zXCI7XG5pbXBvcnQgeyBDbGllbnREZXRhaWxzIH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9tb2RlbHMvY2xpZW50RGV0YWlsc1wiO1xuaW1wb3J0IHsgZ2V0QXRvbVN0b3JlIH0gZnJvbSBcInNyYy9hdG9tcy9hdG9tU3RvcmUvYXRvbVN0b3JlXCI7XG5pbXBvcnQgeyBQcm9kdWN0RXhwZXJpbWVudCB9IGZyb20gXCJzcmMvYXBwbGljYXRpb24vbW9kZWxzL3Byb2R1Y3RFeHBlcmltZW50XCI7XG5pbXBvcnQgeyBGZWF0dXJlR2F0ZXMgfSBmcm9tIFwic3JjL2FwcGxpY2F0aW9uL21vZGVscy9mZWF0dXJlR2F0ZXNcIjtcbmltcG9ydCB7IHZhbGlkYXRlT3JnQ29uZmlnUmVzdWx0cyB9IGZyb20gXCJzcmMvYXBwbGljYXRpb24vbW9kZWxzL3ZhbGlkYXRvcnMvdmFsaWRhdGVPcmdDb25maWdSZXN1bHRzXCI7XG5pbXBvcnQgeyBPcmdDb25maWcgfSBmcm9tIFwic3JjL2FwcGxpY2F0aW9uL21vZGVscy9hcGkvb3JnQ29uZmlnUmVzdWx0c1wiO1xuaW1wb3J0IHsgU3VwcG9ydGVkRXZlbnQgfSBmcm9tIFwic3JjL2F0b21zL2FwcC92YXJpYW50XCI7XG5pbXBvcnQgeyBtZXNzYWdlRnJvbUZvcm1TdWJtaXR0ZWRFdmVudCB9IGZyb20gXCJzcmMvYXBwbGljYXRpb24vdXRpbHMvbWVzc2FnZUZyb21Gb3JtU3VibWl0dGVkRXZlbnRcIjtcbmltcG9ydCB0eXBlIHsgQ29udGV4dCB9IGZyb20gXCJAc3BpZmZ5LWFpL2NvbW1lcmNlLWFwaS1jbGllbnQvZGlzdC9tb2RlbHMvQ29udGV4dFwiO1xuaW1wb3J0IHsgQ29udGV4dEVudkVudW0gfSBmcm9tIFwiQHNwaWZmeS1haS9jb21tZXJjZS1hcGktY2xpZW50XCI7IC8vIEltcG9ydCBDb250ZXh0RW52RW51bVxuaW1wb3J0IHtcbiAgYmFzZVVybEF0b20sXG4gIHJlYWN0QXBwTmFtZUF0b20sXG4gIGNvbnRleHRTb3VyY2VBdG9tLFxuICBvcmdTaG9ydE5hbWVBdG9tLFxuICBlbnZBdG9tLCAvLyBJbXBvcnQgZW52QXRvbVxufSBmcm9tIFwic3JjL2F0b21zL2Vudml2ZS9lbnZpdmVDb25maWdcIjtcbmltcG9ydCB7IHVzZXJJZEF0b20sIGNoYXRJZEF0b20gfSBmcm9tIFwic3JjL2F0b21zL2FwcFwiOyAvLyBJbXBvcnQgdXNlcklkQXRvbSBhbmQgY2hhdElkQXRvbVxuaW1wb3J0IHsgb3JnSWRBdG9tLCBmZWF0dXJlRmxhZ1NlcnZpY2VBdG9tIH0gZnJvbSBcInNyYy9hdG9tcy9vcmcvZ3JhcGhxbENvbmZpZ1wiOyAvLyBJbXBvcnQgbmV3IG9yZ0lkQXRvbSBhbmQgZmVhdHVyZUZsYWdTZXJ2aWNlQXRvbVxuXG5hc3luYyBmdW5jdGlvbiBlcnJvclJlc3BvbnNlQm9keShlcnJvcjogUmVzcG9uc2VFcnJvcikge1xuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCBlcnJvci5yZXNwb25zZS5qc29uKCk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiB7fTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiB0aHJvd1Nlc3Npb25SZXN0YXJ0UmVxdWlyZWRJZihlcnJvck1zZzogc3RyaW5nLCBlcnJvcjogdW5rbm93bikge1xuICBpZiAoIShlcnJvciBpbnN0YW5jZW9mIFJlc3BvbnNlRXJyb3IpKSB7XG4gICAgTG9nZ2VyLmxvZ0luZm8oZXJyb3JNc2csIGVycm9yKTtcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxuXG4gIGNvbnN0IGVycm9yUmVzcG9uc2UgPSBhd2FpdCBlcnJvclJlc3BvbnNlQm9keShlcnJvcik7XG4gIGlmIChcbiAgICBlcnJvclJlc3BvbnNlPy5tZXNzYWdlPy50b0xvd2VyQ2FzZSgpID09PSBcInVuc3VwcG9ydGVkIHByb2R1Y3RcIiB8fCAvLyBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eS4gbmV3ZXIgdmVyc2lvbnMgb2YgdGhlIEFQSSByZXR1cm4gc3ViX2NvZGUgaW5zdGVhZCBvZiBtZXNzYWdlXG4gICAgZXJyb3JSZXNwb25zZT8uYXBwX2NvZGU/LnRvVXBwZXJDYXNlKCkgPT09IFwiUFJPRFVDVF9OT1RfRk9VTkRcIlxuICApIHtcbiAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRQcm9kdWN0RXhjZXB0aW9uKCk7XG4gIH0gZWxzZSBpZiAoXG4gICAgZXJyb3JSZXNwb25zZT8uYXBwX2NvZGU/LnRvVXBwZXJDYXNlKCkgPT09IFwiUkVTVEFSVF9TRVNTSU9OXCIgfHxcbiAgICBlcnJvclJlc3BvbnNlPy5zdWJfY29kZT8udG9VcHBlckNhc2UoKSA9PT0gXCJOT1RfRk9VTkRcIiAvLyBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eS4gbmV3IEFQSSByZXNwb25zZXMgd2lsbCBjb250YWluIFwiYXBwX2NvZGVcIlxuICApIHtcbiAgICBMb2dnZXIubG9nSW5mbyhcbiAgICAgIFwiU2Vzc2lvbiBkb2VzIG5vdCBleGlzdC4gUmUtc3RhcnQgc2Vzc2lvblwiLFxuICAgICAgZXJyb3IsXG4gICAgICBlcnJvci5yZXNwb25zZSxcbiAgICAgIGVycm9yUmVzcG9uc2VcbiAgICApO1xuICAgIHRocm93IG5ldyBTZXNzaW9uUmVzdGFydFJlcXVpcmVkKCk7XG4gIH1cblxuICBMb2dnZXIubG9nSW5mbyhlcnJvck1zZywgZXJyb3IpO1xuICB0aHJvdyBlcnJvcjtcbn1cblxuY2xhc3MgQ29tbWVyY2VBcGlDbGllbnQge1xuICBwcml2YXRlIHJlYWRvbmx5IGRlZmF1bHRBcGk6IERlZmF1bHRBcGk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBjdXN0b21lclNlcnZpY2VBcGk6IEN1c3RvbWVyU2VydmljZUFwaTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGluZmVyZW5jZUFwaTogSW5mZXJlbmNlQXBpO1xuXG4gIHByaXZhdGUgc3RhdGljIGluc3RhbmNlOiBDb21tZXJjZUFwaUNsaWVudCB8IHVuZGVmaW5lZDtcblxuICBwcml2YXRlIHN1Z2dlc3Rpb25zQWJvcnRDb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuXG4gIHByaXZhdGUgcmVzcG9uc2VzQWJvcnRDb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuXG4gIHByaXZhdGUgc3RhdGljIGdldEluc3RhbmNlID0gKCk6IENvbW1lcmNlQXBpQ2xpZW50ID0+IHtcbiAgICBpZiAoIUNvbW1lcmNlQXBpQ2xpZW50Lmluc3RhbmNlKSB7XG4gICAgICBDb21tZXJjZUFwaUNsaWVudC5pbnN0YW5jZSA9IG5ldyBDb21tZXJjZUFwaUNsaWVudCgpO1xuICAgIH1cblxuICAgIHJldHVybiBDb21tZXJjZUFwaUNsaWVudC5pbnN0YW5jZTtcbiAgfTtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKGJhc2VQYXRoPzogc3RyaW5nKSB7XG4gICAgY29uc3QgYXRvbVN0b3JlID0gZ2V0QXRvbVN0b3JlKCk7XG4gICAgY29uc3QgYmFzZVVybCA9IGF0b21TdG9yZS5nZXQoYmFzZVVybEF0b20pO1xuICAgIGNvbnN0IHBhdGggPSBiYXNlUGF0aCB8fCBiYXNlVXJsO1xuICAgIC8vIEFQSSBLZXkgaXMgbm93IGhhbmRsZWQgYXQgdGhlIEVudml2ZUNvbmZpZ1Byb3ZpZGVyIGxldmVsXG4gICAgY29uc3QgY29uZmlnOiBDb25maWd1cmF0aW9uID0gbmV3IENvbmZpZ3VyYXRpb24oe1xuICAgICAgYmFzZVBhdGg6IHBhdGgsXG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgIFwiQ29udGVudC1UeXBlXCI6IFwiYXBwbGljYXRpb24vanNvblwiLFxuICAgICAgICBBY2NlcHQ6IFwiYXBwbGljYXRpb24vanNvblwiLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICB0aGlzLmRlZmF1bHRBcGkgPSBuZXcgRGVmYXVsdEFwaShjb25maWcpO1xuICAgIHRoaXMuaW5mZXJlbmNlQXBpID0gbmV3IEluZmVyZW5jZUFwaShjb25maWcpO1xuICAgIHRoaXMuY3VzdG9tZXJTZXJ2aWNlQXBpID0gbmV3IEN1c3RvbWVyU2VydmljZUFwaShjb25maWcpO1xuICB9XG5cbiAgc3RhdGljIHJlc29sdmVVcmwgPSBhc3luYyAodXJsOiBzdHJpbmcpID0+IHtcbiAgICBjb25zdCBhdG9tU3RvcmUgPSBnZXRBdG9tU3RvcmUoKTtcbiAgICBjb25zdCBvcmdTaG9ydE5hbWUgPSBhdG9tU3RvcmUuZ2V0KG9yZ1Nob3J0TmFtZUF0b20pO1xuICAgIGNvbnN0IG9yZ0lkID0gYXRvbVN0b3JlLmdldChvcmdJZEF0b20pO1xuICAgIGNvbnN0IHVzZXJJZCA9IGF0b21TdG9yZS5nZXQodXNlcklkQXRvbSk7XG4gICAgY29uc3QgY2hhdElkID0gYXRvbVN0b3JlLmdldChjaGF0SWRBdG9tKTtcbiAgICBjb25zdCBzb3VyY2UgPSBhdG9tU3RvcmUuZ2V0KGNvbnRleHRTb3VyY2VBdG9tKTtcbiAgICBjb25zdCBlbnYgPSBhdG9tU3RvcmUuZ2V0KGVudkF0b20pO1xuXG4gICAgY29uc3QgZmVhdHVyZUZsYWdTZXJ2aWNlID0gYXRvbVN0b3JlLmdldChmZWF0dXJlRmxhZ1NlcnZpY2VBdG9tKTtcblxuICAgIGNvbnN0IGNvbnRleHQ6IENvbnRleHQgPSB7XG4gICAgICB1c2VyX2lkOiB1c2VySWQgPz8gXCJcIixcbiAgICAgIG9yZ19pZDogb3JnSWQgPz8gXCJcIixcbiAgICAgIG9yZ19zaG9ydF9uYW1lOiBvcmdTaG9ydE5hbWUgPz8gXCJcIixcbiAgICAgIGNoYXRfaWQ6IGNoYXRJZCA/PyBcIlwiLFxuICAgICAgc291cmNlOiBzb3VyY2UgPz8gQ29udGV4dFNvdXJjZUVudW0uQXBwLFxuICAgICAgZW52OiAoZW52IGFzIENvbnRleHRFbnZFbnVtKSA/PyBDb250ZXh0RW52RW51bS5EZXYsIC8vIENhc3QgZW52IHRvIENvbnRleHRFbnZFbnVtXG4gICAgfTtcblxuICAgIGNvbnN0IGZlYXR1cmVHYXRlcyA9XG4gICAgICBmZWF0dXJlRmxhZ1NlcnZpY2U/LmZlYXR1cmVGbGFnU2VydmljZT8uZ2V0RmVhdHVyZUZsYWdzKCkgfHwge307XG4gICAgY29uc3QgdXJsUmVzb2x2aW5nUmVxdWVzdCA9IHtcbiAgICAgIHVybCxcbiAgICAgIGNvbnRleHQsXG4gICAgICBmZWF0dXJlX2dhdGVzOiBmZWF0dXJlR2F0ZXMsXG4gICAgfTtcblxuICAgIGNvbnN0IHJhd1Jlc3BvbnNlID1cbiAgICAgIGF3YWl0IENvbW1lcmNlQXBpQ2xpZW50LmdldEluc3RhbmNlKCkuaW5mZXJlbmNlQXBpLnYxVXJsUmVzb2x2aW5nUG9zdFJhdyh7XG4gICAgICAgIFVybFJlc29sdmluZ1JlcXVlc3Q6IHVybFJlc29sdmluZ1JlcXVlc3QsXG4gICAgICB9KTtcblxuICAgIGNvbnN0IHJlc3BvbnNlQm9keSA9IGF3YWl0IHJhd1Jlc3BvbnNlLnJhdy5qc29uKCk7XG5cbiAgICByZXR1cm4gcmVzcG9uc2VCb2R5O1xuICB9O1xuXG4gIHN0YXRpYyByZXBvcnRTZXNzaW9uID0gYXN5bmMgKFxuICAgIHJlcG9ydFJlcXVlc3Q6IFJlcG9ydFNlc3Npb25SZXF1ZXN0XG4gICk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGF3YWl0IENvbW1lcmNlQXBpQ2xpZW50LmdldEluc3RhbmNlKCkuZGVmYXVsdEFwaS52MUNoYXRzUmVwb3J0U2Vzc2lvbklkUG9zdChcbiAgICAgIHtcbiAgICAgICAgUmVwb3J0U2Vzc2lvblJlcXVlc3Q6IHJlcG9ydFJlcXVlc3QsXG4gICAgICB9XG4gICAgKTtcbiAgfTtcblxuICBzdGF0aWMgZ2V0TmV4dFJlc3BvbnNlcyA9IGFzeW5jIChcbiAgICBwYXlsb2FkOiBOZXh0TWVzc2FnZVJlcXVlc3RcbiAgKTogUHJvbWlzZTxNZXNzYWdlW10+ID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPVxuICAgICAgICBhd2FpdCBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLmluZmVyZW5jZUFwaS52MU5leHRSZXNwb25zZXNQb3N0KHtcbiAgICAgICAgICBOZXh0TWVzc2FnZVJlcXVlc3Q6IG1lc3NhZ2VSZXF1ZXN0VG9Db21tZXJjZU1lc3NhZ2VSZXF1ZXN0KHBheWxvYWQpLFxuICAgICAgICB9KTtcbiAgICAgIGNvbnN0IG1lc3NhZ2VzID0gcmVzcG9uc2VcbiAgICAgICAgLm1hcCgocmVzcCkgPT4gdmFsaWRhdGVSZXNwb25zZShyZXNwKSlcbiAgICAgICAgLm1hcCgocmVzcCkgPT4gbWVzc2FnZUZyb21SZXNwb25zZShyZXNwKSk7XG5cbiAgICAgIHJldHVybiBtZXNzYWdlcy5maWx0ZXIoKG0pOiBtIGlzIE1lc3NhZ2UgPT4gbSAhPSBudWxsKTtcbiAgICB9IGNhdGNoIChlcnI6IHVua25vd24pIHtcbiAgICAgIExvZ2dlci5sb2dJbmZvKFwiRmFpbGVkIHRvIGdldCBuZXh0IHJlc3BvbnNlc1wiLCBlcnIsIHtcbiAgICAgICAgcGF5bG9hZENvbnRleHQ6IHBheWxvYWQ/LmNvbnRleHQsXG4gICAgICAgIHVzZXJFdmVudHM6IHBheWxvYWQ/LnVzZXJFdmVudHMsXG4gICAgICB9KTtcbiAgICAgIGF3YWl0IHRocm93U2Vzc2lvblJlc3RhcnRSZXF1aXJlZElmKFwiRmFpbGVkIHRvIGdldCBuZXh0IHJlc3BvbnNlc1wiLCBlcnIpO1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgfTtcblxuICBzdGF0aWMgZ2V0TmV4dFJlc3BvbnNlU3RyZWFtaW5nID0gKFxuICAgIHBheWxvYWQ6IE5leHRNZXNzYWdlUmVxdWVzdFxuICApOiBBc3luY0dlbmVyYXRvcjxSZXNwb25zZSwgdm9pZCwgdW5rbm93bj4gPT4ge1xuICAgIGFzeW5jIGZ1bmN0aW9uKiBnZW5lcmF0ZShcbiAgICAgIGluZmVyZW5jZUFwaTogSW5mZXJlbmNlQXBpLFxuICAgICAgYWJvcnRDb250cm9sbGVyOiBBYm9ydENvbnRyb2xsZXJcbiAgICApIHtcbiAgICAgIC8vIG1ha2Ugc3VyZSBzdHJlYW1pbmcgaXMgZW5hYmxlZFxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBpbmZlcmVuY2VBcGkudjFOZXh0UmVzcG9uc2VzUG9zdFJhdyhcbiAgICAgICAgICB7XG4gICAgICAgICAgICBOZXh0TWVzc2FnZVJlcXVlc3Q6IG1lc3NhZ2VSZXF1ZXN0VG9Db21tZXJjZU1lc3NhZ2VSZXF1ZXN0KHBheWxvYWQpLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgeyBzaWduYWw6IGFib3J0Q29udHJvbGxlci5zaWduYWwgfVxuICAgICAgICApO1xuXG4gICAgICAgIC8vIFJlYWQgdGhlIHJlc3BvbnNlIGFzIGEgc3RyZWFtIG9mIGRhdGFcbiAgICAgICAgaWYgKCFyZXNwb25zZS5yYXcuYm9keSkge1xuICAgICAgICAgIExvZ2dlci5sb2dFcnJvcihcbiAgICAgICAgICAgIFwiW3NwaWZmeS1haV0gTm8gYm9keSBpbiB0aGUgc3RyZWFtZWQgcmVzcG9uc2VcIixcbiAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgcmVzcG9uc2U6IHJlc3BvbnNlLnJhdyxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlYWRlciA9IHJlc3BvbnNlLnJhdy5ib2R5LmdldFJlYWRlcigpO1xuICAgICAgICBjb25zdCBkZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKFwidXRmLThcIik7XG5cbiAgICAgICAgbGV0IHBhcnRpYWwgPSBcIlwiO1xuICAgICAgICAvLyBUT0RPIHRoaXMgZnVuY3Rpb24gaXMgcmVjcmVhdGVkIGV2ZXJ5IHRpbWUgbmV3IGRhdGEgY29tZXMgZnJvbSB0aGUgc3RyZWFtIC0gZGVmaW5lIGl0IG91dHNpZGUgb2YgdGhlIGdlbmVyYXRvclxuICAgICAgICBjb25zdCBzYWZlUGFyc2UgPSAobGluZTogc3RyaW5nKTogdW5rbm93biA9PiB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBKU09OLnBhcnNlKGxpbmUpOyAvLyBQYXJzZSB0aGUgSlNPTiBzdHJpbmdcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIExvZ2dlci5sb2dFcnJvcihcIltzcGlmZnktYWldIEVycm9yIHBhcnNpbmcgc3RyZWFtZWQgbGluZVwiLCBlcnIsIHtcbiAgICAgICAgICAgICAgbGluZSxcbiAgICAgICAgICAgICAgcGFydGlhbCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLy8gc3dhbGxvdyB0aGUgZXJyb3IgYW5kIHNldCB0aGUgcGFydGlhbCB0byBvdXIgY3VycmVudCBjaHVua1xuICAgICAgICAgICAgcGFydGlhbCA9IGxpbmU7XG4gICAgICAgICAgICByZXR1cm4gcGFydGlhbDtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gVE9ETyB0aGlzIGZ1bmN0aW9uIGlzIHJlY3JlYXRlZCBldmVyeSB0aW1lIG5ldyBkYXRhIGNvbWVzIGZyb20gdGhlIHN0cmVhbSAtIGRlZmluZSBpdCBvdXRzaWRlIG9mIHRoZSBnZW5lcmF0b3JcbiAgICAgICAgY29uc3QgcHJvY2Vzc0NodW5rID0gKGNodW5rOiBzdHJpbmcpOiB1bmtub3duW10gPT4ge1xuICAgICAgICAgIC8vIG1lcmdlIHRoZSBwYXJ0aWFsIHdpdGggdGhlIGluY29taW5nIGNodW5rXG4gICAgICAgICAgY29uc3QgbGluZXMgPSBgJHtwYXJ0aWFsfSR7Y2h1bmt9YC5zcGxpdChcIlxcblwiKTtcblxuICAgICAgICAgIGNvbnN0IHBhcnNlZExpbmVzID0gbGluZXNcbiAgICAgICAgICAgIC5tYXAoKGxpbmUpID0+IGxpbmUucmVwbGFjZSgvXmRhdGE6IC8sIFwiXCIpLnRyaW0oKSkgLy8gUmVtb3ZlIHRoZSBcImRhdGE6IFwiIHByZWZpeFxuICAgICAgICAgICAgLmZpbHRlcigobGluZSkgPT4gbGluZSAhPT0gXCJcIiAmJiBsaW5lICE9PSBcIltET05FXVwiKSAvLyBSZW1vdmUgZW1wdHkgbGluZXMgYW5kIFwiW0RPTkVdXCJcbiAgICAgICAgICAgIC5tYXAoc2FmZVBhcnNlKVxuICAgICAgICAgICAgLmZpbHRlcigodikgPT4gdik7IC8vIGFuZCBmaWx0ZXIgb3V0IHRoZSB1bmRlZmluZWQgdmFsdWVzXG4gICAgICAgICAgcmV0dXJuIHBhcnNlZExpbmVzO1xuICAgICAgICB9O1xuXG4gICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWF3YWl0LWluLWxvb3BcbiAgICAgICAgICBjb25zdCB7IGRvbmUsIHZhbHVlIH0gPSBhd2FpdCByZWFkZXIucmVhZCgpO1xuXG4gICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIE1hc3NhZ2UgYW5kIHBhcnNlIHRoZSBjaHVuayBvZiBkYXRhXG4gICAgICAgICAgY29uc3QgY2h1bmsgPSBkZWNvZGVyLmRlY29kZSh2YWx1ZSk7XG4gICAgICAgICAgY29uc3QgcGFyc2VkTGluZXMgPSBwcm9jZXNzQ2h1bmsoY2h1bmspO1xuXG4gICAgICAgICAgZm9yIChjb25zdCBwYXJzZWRMaW5lIG9mIHBhcnNlZExpbmVzKSB7XG4gICAgICAgICAgICBjb25zdCB2YWxpZGF0ZWRSZXNwb25zZSA9IHZhbGlkYXRlUmVzcG9uc2UocGFyc2VkTGluZSk7XG5cbiAgICAgICAgICAgIGlmICh2YWxpZGF0ZWRSZXNwb25zZSkge1xuICAgICAgICAgICAgICB5aWVsZCB2YWxpZGF0ZWRSZXNwb25zZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAgIExvZ2dlci5sb2dFcnJvcihcbiAgICAgICAgICBcIltzcGlmZnktYWldIEZhaWxlZCB0byBnZXQgbmV4dCBzdHJlYW1pbmcgcmVzcG9uc2VzXCIsXG4gICAgICAgICAgZXJyb3IsXG4gICAgICAgICAge1xuICAgICAgICAgICAgcGF5bG9hZENvbnRleHQ6IHBheWxvYWQ/LmNvbnRleHQsXG4gICAgICAgICAgICB1c2VyRXZlbnRzOiBwYXlsb2FkPy51c2VyRXZlbnRzLFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgICAgYXdhaXQgdGhyb3dTZXNzaW9uUmVzdGFydFJlcXVpcmVkSWYoXG4gICAgICAgICAgXCJGYWlsZWQgdG8gZ2V0IG5leHQgc3RyZWFtaW5nIHJlc3BvbnNlc1wiLFxuICAgICAgICAgIGVycm9yXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5yZXNwb25zZXNBYm9ydENvbnRyb2xsZXIuYWJvcnQoKTtcbiAgICBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLnJlc3BvbnNlc0Fib3J0Q29udHJvbGxlciA9XG4gICAgICBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG5cbiAgICByZXR1cm4gZ2VuZXJhdGUoXG4gICAgICBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLmluZmVyZW5jZUFwaSxcbiAgICAgIENvbW1lcmNlQXBpQ2xpZW50LmdldEluc3RhbmNlKCkucmVzcG9uc2VzQWJvcnRDb250cm9sbGVyXG4gICAgKTtcbiAgfTtcblxuICBzdGF0aWMgZ2V0TmV4dFN1Z2dlc3Rpb25zID0gYXN5bmMgKFxuICAgIHBheWxvYWQ6IE5leHRNZXNzYWdlUmVxdWVzdFxuICApOiBQcm9taXNlPFN1Z2dlc3Rpb25bXT4gPT4ge1xuICAgIHRyeSB7XG4gICAgICBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLnN1Z2dlc3Rpb25zQWJvcnRDb250cm9sbGVyLmFib3J0KCk7XG4gICAgICBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLnN1Z2dlc3Rpb25zQWJvcnRDb250cm9sbGVyID1cbiAgICAgICAgbmV3IEFib3J0Q29udHJvbGxlcigpO1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9XG4gICAgICAgIGF3YWl0IENvbW1lcmNlQXBpQ2xpZW50LmdldEluc3RhbmNlKCkuaW5mZXJlbmNlQXBpLnYxTmV4dFN1Z2dlc3Rpb25zUG9zdChcbiAgICAgICAgICB7XG4gICAgICAgICAgICBOZXh0TWVzc2FnZVJlcXVlc3Q6IG1lc3NhZ2VSZXF1ZXN0VG9Db21tZXJjZU1lc3NhZ2VSZXF1ZXN0KHBheWxvYWQpLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgc2lnbmFsOlxuICAgICAgICAgICAgICBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLnN1Z2dlc3Rpb25zQWJvcnRDb250cm9sbGVyLnNpZ25hbCxcbiAgICAgICAgICB9XG4gICAgICAgICk7XG5cbiAgICAgIGNvbnN0IHN1Z2dlc3Rpb25zID0gcmVzcG9uc2VcbiAgICAgICAgLm1hcCgocmVzcCkgPT4gdmFsaWRhdGVTdWdnZXN0aW9uKHJlc3ApKVxuICAgICAgICAuZmlsdGVyKChzdWdnZXN0aW9uKTogc3VnZ2VzdGlvbiBpcyBTdWdnZXN0aW9uID0+IHN1Z2dlc3Rpb24gIT0gbnVsbCk7XG5cbiAgICAgIHJldHVybiBzdWdnZXN0aW9ucztcbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgTG9nZ2VyLmxvZ0luZm8oXCJGYWlsZWQgdG8gZ2V0IHN1Z2dlc3Rpb25zXCIsIGVycm9yLCB7XG4gICAgICAgIHBheWxvYWRDb250ZXh0OiBwYXlsb2FkPy5jb250ZXh0LFxuICAgICAgICB1c2VyRXZlbnRzOiBwYXlsb2FkPy51c2VyRXZlbnRzLFxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IHRocm93U2Vzc2lvblJlc3RhcnRSZXF1aXJlZElmKFwiRmFpbGVkIHRvIGdldCBzdWdnZXN0aW9uc1wiLCBlcnJvcik7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBGZXRjaGVzIHRoZSBleGlzdGluZyBjaGF0IGRhdGEgZm9yIGEgZ2l2ZW4gc2Vzc2lvbiBhbmQgdHJhbnNmb3JtcyB0aGVtIHRvIHJlY29uc3RydWN0IHRoZSBjaGF0IGhpc3RvcnkuXG4gICAqXG4gICAqIEBwYXJhbSBvcmdJZCBUaGUgb3JnYW5pemF0aW9uIElkXG4gICAqIEBwYXJhbSBjaGF0SWQgVGhlIGV4aXN0aW5nIGNoYXQgSWRcbiAgICogQHBhcmFtIHVzZXJJZCBUaGUgdXNlciBJZFxuICAgKlxuICAgKiBAcmV0dXJucyBBIGxpc3Qgb2YgbWVzc2FnZXMgdGhhdCB3ZXJlIGV4Y2hhbmdlZCBpbiB0aGUgY2hhdCwgdGhyb3dzIGFuIGVycm9yIGlmIHRoZSBjaGF0IHNlc3Npb24gaGFzIGV4cGlyZWQuXG4gICAqL1xuICBzdGF0aWMgZ2V0UmVzcG9uc2VzID0gYXN5bmMgKFxuICAgIG9yZ0lkOiBzdHJpbmcsXG4gICAgY2hhdElkOiBzdHJpbmcsXG4gICAgdXNlcklkOiBzdHJpbmdcbiAgKTogUHJvbWlzZTx7XG4gICAgcmVzcG9uc2VzOiBSZXNwb25zZVtdW107XG4gICAgdXNlckV2ZW50czogVXNlckV2ZW50W107XG4gICAgc3VnZ2VzdGlvbnM6IFN1Z2dlc3Rpb25bXTtcbiAgICBtZXNzYWdlczogTWVzc2FnZVtdW107XG4gIH0+ID0+IHtcbiAgICBsZXQgZGF0YTogVjFHZXRTZXNzaW9uTWVzc2FnZXMyMDBSZXNwb25zZSA9IHtcbiAgICAgIHJlc3BvbnNlczogW10sXG4gICAgICBzdWdnZXN0aW9uczogW10sXG4gICAgICB1c2VyX2V2ZW50czogW10sXG4gICAgfTtcbiAgICBjb25zdCByZXF1ZXN0ID0ge1xuICAgICAgb3JnX2lkOiBvcmdJZCxcbiAgICAgIGNoYXRfaWQ6IGNoYXRJZCxcbiAgICAgIHVzZXJfaWQ6IHVzZXJJZCxcbiAgICB9O1xuICAgIHRyeSB7XG4gICAgICBkYXRhID1cbiAgICAgICAgYXdhaXQgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5kZWZhdWx0QXBpLnYxR2V0U2Vzc2lvbk1lc3NhZ2VzKFxuICAgICAgICAgIHJlcXVlc3RcbiAgICAgICAgKTtcbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgYXdhaXQgdGhyb3dTZXNzaW9uUmVzdGFydFJlcXVpcmVkSWYoXG4gICAgICAgIFwiRmFpbGVkIHRvIGdldCBjaGF0IHJlc3BvbnNlc1wiLFxuICAgICAgICBlcnJvclxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCByZXNwb25zZXM6IFJlc3BvbnNlW11bXSA9IGRhdGE/LnJlc3BvbnNlcz8ubWFwKCh0dXJuKSA9PlxuICAgICAgdHVyblxuICAgICAgICAubWFwKChyZXNwb25zZSkgPT4gdmFsaWRhdGVSZXNwb25zZShyZXNwb25zZSkpXG4gICAgICAgIC5maWx0ZXIoKHJlc3BvbnNlKTogcmVzcG9uc2UgaXMgUmVzcG9uc2UgPT4gcmVzcG9uc2UgIT0gbnVsbClcbiAgICApO1xuXG4gICAgY29uc3Qgc3VnZ2VzdGlvbnM6IFN1Z2dlc3Rpb25bXSA9IGRhdGE/LnN1Z2dlc3Rpb25zXG4gICAgICAubWFwKChzdWdnZXN0aW9uKSA9PiB2YWxpZGF0ZVN1Z2dlc3Rpb24oc3VnZ2VzdGlvbikpXG4gICAgICAuZmlsdGVyKChzdWdnZXN0aW9uKTogc3VnZ2VzdGlvbiBpcyBTdWdnZXN0aW9uID0+IHN1Z2dlc3Rpb24gIT0gbnVsbCk7XG5cbiAgICBjb25zdCB1c2VyRXZlbnRzOiBVc2VyRXZlbnRbXSA9IGRhdGE/LnVzZXJfZXZlbnRzXG4gICAgICAubWFwKChldmVudCkgPT4gdmFsaWRhdGVVc2VyRXZlbnQoZXZlbnQpKVxuICAgICAgLmZpbHRlcigoZXZlbnQpOiBldmVudCBpcyBVc2VyRXZlbnQgPT4gZXZlbnQgIT0gbnVsbCk7XG5cbiAgICAvLyBpZiBhIGZvcm0gaGFzIGFscmVhZHkgYmVlbiBzdWJtaXR0ZWQsIGRvbid0IHNob3cgaXQgaW4gdGhlIGNoYXQgaGlzdG9yeVxuICAgIGNvbnN0IGZvcm1TdWJtaXR0ZWRVc2VyRXZlbnRzRm9ybUlkcyA9IHVzZXJFdmVudHNcbiAgICAgIC5maWx0ZXIoKGV2ZW50KSA9PiBldmVudC5jYXRlZ29yeSA9PT0gVXNlckV2ZW50Q2F0ZWdvcnkuRm9ybVN1Ym1pdHRlZClcbiAgICAgIC5tYXAoKGV2ZW50KSA9PiBldmVudC5hdHRyaWJ1dGVzLmZvcm1SZXNwb25zZUlkKTtcblxuICAgIGNvbnN0IGFzc2lzdGFudE1lc3NhZ2VzOiBNZXNzYWdlW11bXSA9IHJlc3BvbnNlc1xuICAgICAgLm1hcCgodHVybikgPT5cbiAgICAgICAgdHVyblxuICAgICAgICAgIC5maWx0ZXIoXG4gICAgICAgICAgICAocmVzcG9uc2UpID0+XG4gICAgICAgICAgICAgICEoXG4gICAgICAgICAgICAgICAgcmVzcG9uc2UuY2F0ZWdvcnkgPT09IFJlc3BvbnNlQ2F0ZWdvcnkuRm9ybSAmJlxuICAgICAgICAgICAgICAgIGZvcm1TdWJtaXR0ZWRVc2VyRXZlbnRzRm9ybUlkcy5pbmNsdWRlcyhyZXNwb25zZS5pZClcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgIClcbiAgICAgICAgICAubWFwKChyZXNwb25zZSkgPT4gbWVzc2FnZUZyb21SZXNwb25zZShyZXNwb25zZSkpXG4gICAgICAgICAgLmZpbHRlcigobWVzc2FnZSk6IG1lc3NhZ2UgaXMgTWVzc2FnZSA9PiBtZXNzYWdlICE9IG51bGwpXG4gICAgICApXG4gICAgICAuZmlsdGVyKCh0dXJuKSA9PiB0dXJuLmxlbmd0aCA+IDApO1xuXG4gICAgY29uc3QgdXNlck1lc3NhZ2VzOiBNZXNzYWdlW11bXSA9IHVzZXJFdmVudHNcbiAgICAgIC5tYXAoKGV2ZW50KSA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBbVXNlckV2ZW50Q2F0ZWdvcnkuUXVlcnlUeXBlZCwgVXNlckV2ZW50Q2F0ZWdvcnkuU2VhcmNoXS5pbmNsdWRlcyhcbiAgICAgICAgICAgIGV2ZW50LmNhdGVnb3J5XG4gICAgICAgICAgKVxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm4gW21lc3NhZ2VGcm9tUXVlcnlFdmVudChldmVudCldO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGV2ZW50LmNhdGVnb3J5ID09PSBVc2VyRXZlbnRDYXRlZ29yeS5TdWdnZXN0aW9uQ2xpY2tlZCkge1xuICAgICAgICAgIHJldHVybiBbbWVzc2FnZUZyb21TdWdnZXN0aW9uRXZlbnQoZXZlbnQsIHN1Z2dlc3Rpb25zKV07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXZlbnQuY2F0ZWdvcnkgPT09IFVzZXJFdmVudENhdGVnb3J5LkZvcm1TdWJtaXR0ZWQpIHtcbiAgICAgICAgICBjb25zdCBmb3JtUmVzcG9uc2UgPSByZXNwb25zZXNcbiAgICAgICAgICAgIC5mbGF0KClcbiAgICAgICAgICAgIC5maW5kKFxuICAgICAgICAgICAgICAocmVzcG9uc2UpID0+XG4gICAgICAgICAgICAgICAgcmVzcG9uc2UuaWQgPT09IGV2ZW50LmF0dHJpYnV0ZXMuZm9ybVJlc3BvbnNlSWQgJiZcbiAgICAgICAgICAgICAgICBldmVudC5hdHRyaWJ1dGVzLmZvcm1UeXBlICE9PSBGb3JtVHlwZS5Fc2NhbGF0aW9uXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKGZvcm1SZXNwb25zZSAmJiBmb3JtUmVzcG9uc2UuY2F0ZWdvcnkgPT09IFJlc3BvbnNlQ2F0ZWdvcnkuRm9ybSkge1xuICAgICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgICAgbWVzc2FnZUZyb21Gb3JtU3VibWl0dGVkRXZlbnQoZXZlbnQsIGZvcm1SZXNwb25zZS5hdHRyaWJ1dGVzKSxcbiAgICAgICAgICAgIF07XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfSlcbiAgICAgIC5maWx0ZXIoKG1lc3NhZ2UpOiBtZXNzYWdlIGlzIE1lc3NhZ2VbXSA9PiBtZXNzYWdlLmxlbmd0aCA+IDApO1xuXG4gICAgLy8gU29ydCB0aGUgbWVzc2FnZXMgY2hyb25vbG9naWNhbGx5IHRvIHJlY29uc3RydWN0IHRoZSBjaGF0IGhpc3RvcnlcbiAgICBjb25zdCBzb3J0ZWRNZXNzYWdlcyA9IFsuLi5hc3Npc3RhbnRNZXNzYWdlcywgLi4udXNlck1lc3NhZ2VzXS5zb3J0KFxuICAgICAgKGEsIGIpID0+XG4gICAgICAgIG5ldyBEYXRlKGFbMF0uY3JlYXRlZEF0KS5nZXRUaW1lKCkgLSBuZXcgRGF0ZShiWzBdLmNyZWF0ZWRBdCkuZ2V0VGltZSgpXG4gICAgKTtcblxuICAgIHJldHVybiB7IHJlc3BvbnNlcywgdXNlckV2ZW50cywgc3VnZ2VzdGlvbnMsIG1lc3NhZ2VzOiBzb3J0ZWRNZXNzYWdlcyB9O1xuICB9O1xuXG4gIC8qKlxuICAgKlxuICAgKiBAcGFyYW0gcGF5bG9hZFxuICAgKiBAcmV0dXJuc1xuICAgKi9cbiAgc3RhdGljIGlzU3VwcG9ydGVkRXZlbnQgPSBhc3luYyAoXG4gICAgcGF5bG9hZDogU3VwcG9ydGVkRXZlbnRSZXF1ZXN0XG4gICk6IFByb21pc2U8U3VwcG9ydGVkRXZlbnQ+ID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmF3UmVzcG9uc2UgPVxuICAgICAgICBhd2FpdCBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLmluZmVyZW5jZUFwaS52MVN1cHBvcnRlZEV2ZW50UG9zdFJhdyhcbiAgICAgICAgICB7XG4gICAgICAgICAgICBTdXBwb3J0ZWRFdmVudFJlcXVlc3Q6XG4gICAgICAgICAgICAgIGNvcmVTdXBwb3J0ZWRFdmVudFJlcXVlc3RUb0FwaVJlcXVlc3QocGF5bG9hZCksXG4gICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAvLyBHZXQgdGhlIGFjdHVhbCBIVFRQIHJlc3BvbnNlIEpTT05cbiAgICAgIGNvbnN0IGh0dHBSZXNwb25zZVRleHQgPSBhd2FpdCByYXdSZXNwb25zZS5yYXcudGV4dCgpO1xuICAgICAgY29uc3QgaHR0cFJlc3BvbnNlSnNvbiA9IEpTT04ucGFyc2UoaHR0cFJlc3BvbnNlVGV4dCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLmh0dHBSZXNwb25zZUpzb24sXG4gICAgICAgIG51bWJlck9mUmV2aWV3czogaHR0cFJlc3BvbnNlSnNvbi5udW1fb2ZfcmV2aWV3cyxcbiAgICAgICAgbWVyY2hhbnRfdGFnczogaHR0cFJlc3BvbnNlSnNvbi5tZXJjaGFudF90YWdzIHx8IFtdLFxuICAgICAgfTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIExvZ2dlci5sb2dFcnJvcihcIkZhaWxlZCB0byBnZXQgcmVzcG9uc2UgZm9yIHYxU3VwcG9ydGVkRXZlbnRQb3N0XCIsIHtcbiAgICAgICAgZXJyLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdXBwb3J0ZWQ6IGZhbHNlLFxuICAgICAgICByZWFkeTogZmFsc2UsXG4gICAgICAgIGNhdGVnb3J5OiB1bmRlZmluZWQsXG4gICAgICAgIGNvbGxlY3Rpb25zOiBbXSxcbiAgICAgICAgbnVtYmVyT2ZSZXZpZXdzOiB1bmRlZmluZWQsXG4gICAgICAgIHRvcF9jYXRlZ29yeTogdW5kZWZpbmVkLFxuICAgICAgICBtZXJjaGFudF90YWdzOiBbXSxcbiAgICAgIH07XG4gICAgfVxuICB9O1xuXG4gIHN0YXRpYyBpZGVudGlmeVVzZXIgPSBhc3luYyAoXG4gICAgc3BpZmZ5VXNlcklkOiBzdHJpbmcsXG4gICAgbWVyY2hhbnRVc2VySWQ6IHN0cmluZyxcbiAgICB1YURldGFpbHM6IENsaWVudERldGFpbHNcbiAgKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IENvbW1lcmNlQXBpQ2xpZW50LmdldEluc3RhbmNlKCkuZGVmYXVsdEFwaS52MUFuYWx5dGljc0lkZW50aWZ5UG9zdCh7XG4gICAgICAgIEFuYWx5dGljc0lkZW50aWZ5UmVxdWVzdDoge1xuICAgICAgICAgIHVzZXJfaWQ6IHNwaWZmeVVzZXJJZCxcbiAgICAgICAgICBvc19uYW1lOiB1YURldGFpbHMub3MsXG4gICAgICAgICAgb3NfdmVyc2lvbjogdWFEZXRhaWxzLm9zVmVyc2lvbixcbiAgICAgICAgICBwbGF0Zm9ybTogdWFEZXRhaWxzLm9zLFxuICAgICAgICAgIGRldmljZV9pZDogdWFEZXRhaWxzLmRldmljZU1vZGVsLFxuICAgICAgICAgIGRldmljZV9icmFuZDogdWFEZXRhaWxzLmRldmljZUJyYW5kLFxuICAgICAgICAgIGRldmljZV9tYW51ZmFjdHVyZXI6IHVhRGV0YWlscy5kZXZpY2VNYW51ZmFjdHVyZXIsXG4gICAgICAgICAgZGV2aWNlX21vZGVsOiB1YURldGFpbHMuZGV2aWNlTW9kZWwsXG4gICAgICAgICAgdXNlcl9wcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICBjZHBfdXNlcl9pZDogbWVyY2hhbnRVc2VySWQsXG4gICAgICAgICAgICBicm93c2VyOiB1YURldGFpbHMuYnJvd3NlcixcbiAgICAgICAgICAgIGJyb3dzZXJfdmVyc2lvbjogdWFEZXRhaWxzLmJyb3dzZXJWZXJzaW9uLFxuICAgICAgICAgICAgdXNlcl9hZ2VudDogdWFEZXRhaWxzLnVzZXJBZ2VudCxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBMb2dnZXIubG9nRXJyb3IoXCJGYWlsZWQgdG8gaWRlbnRpZnkgdXNlclwiLCBlcnIpO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIHN0YXRpYyBtYXBDb250ZXh0U291cmNlVG9WMU9yZ0NvbmZpZ0dldFNvdXJjZSA9IChcbiAgICBzb3VyY2U6IENvbnRleHRTb3VyY2VFbnVtIHwgdW5kZWZpbmVkXG4gICk6IFYxT3JnQ29uZmlnR2V0U291cmNlRW51bSB8IHVuZGVmaW5lZCA9PiB7XG4gICAgaWYgKHNvdXJjZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIHN3aXRjaCAoc291cmNlKSB7XG4gICAgICBjYXNlIENvbnRleHRTb3VyY2VFbnVtLkZvcms6XG4gICAgICAgIHJldHVybiBWMU9yZ0NvbmZpZ0dldFNvdXJjZUVudW0uRm9yaztcbiAgICAgIGNhc2UgQ29udGV4dFNvdXJjZUVudW0uUGxheWdyb3VuZDpcbiAgICAgICAgcmV0dXJuIFYxT3JnQ29uZmlnR2V0U291cmNlRW51bS5QbGF5Z3JvdW5kO1xuICAgICAgY2FzZSBDb250ZXh0U291cmNlRW51bS5BcHA6XG4gICAgICAgIHJldHVybiBWMU9yZ0NvbmZpZ0dldFNvdXJjZUVudW0uQXBwO1xuICAgICAgY2FzZSBDb250ZXh0U291cmNlRW51bS5UZXN0OlxuICAgICAgICByZXR1cm4gVjFPcmdDb25maWdHZXRTb3VyY2VFbnVtLlRlc3Q7XG4gICAgICBkZWZhdWx0OiB7XG4gICAgICAgIC8vIFRoaXMgZW5zdXJlcyB0aGF0IGlmIG5ldyB2YWx1ZXMgYXJlIGFkZGVkIHRvIENvbnRleHRTb3VyY2VFbnVtLCB3ZSBjYXRjaCBpdFxuICAgICAgICBjb25zdCBleGhhdXN0aXZlQ2hlY2s6IG5ldmVyID0gc291cmNlO1xuICAgICAgICByZXR1cm4gZXhoYXVzdGl2ZUNoZWNrO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBzdGF0aWMgZ2V0T3JnQ29uZmlnID0gYXN5bmMgKFxuICAgIHVzZXJfaWQ6IHN0cmluZ1xuICApOiBQcm9taXNlPE9yZ0NvbmZpZyB8IHVuZGVmaW5lZD4gPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBhdG9tU3RvcmUgPSBnZXRBdG9tU3RvcmUoKTtcbiAgICAgIGNvbnN0IHJlYWN0QXBwTmFtZSA9IGF0b21TdG9yZS5nZXQocmVhY3RBcHBOYW1lQXRvbSk7XG4gICAgICBjb25zdCBjb250ZXh0U291cmNlID0gYXRvbVN0b3JlLmdldChjb250ZXh0U291cmNlQXRvbSk7XG4gICAgICBjb25zdCBmZWF0dXJlRmxhZ1NlcnZpY2UgPSBhdG9tU3RvcmUuZ2V0KGZlYXR1cmVGbGFnU2VydmljZUF0b20pOyAvLyBHZXQgZmVhdHVyZUZsYWdTZXJ2aWNlXG4gICAgICBjb25zdCByZXF1ZXN0OiBWMU9yZ0NvbmZpZ0dldFJlcXVlc3QgPSB7XG4gICAgICAgIG5hbWVzcGFjZTogcmVhY3RBcHBOYW1lLFxuICAgICAgICB1c2VyX2lkLFxuICAgICAgICBzb3VyY2U6IHRoaXMubWFwQ29udGV4dFNvdXJjZVRvVjFPcmdDb25maWdHZXRTb3VyY2UoY29udGV4dFNvdXJjZSksXG4gICAgICAgIGluY2x1ZGVfZXhwZXJpbWVudHM6IE9iamVjdC52YWx1ZXMoUHJvZHVjdEV4cGVyaW1lbnQpLFxuICAgICAgICBpbmNsdWRlX2ZlYXR1cmVfZ2F0ZXM6IE9iamVjdC5lbnRyaWVzKFxuICAgICAgICAgIGZlYXR1cmVGbGFnU2VydmljZT8uZmVhdHVyZUZsYWdTZXJ2aWNlPy5nZXRGZWF0dXJlRmxhZ3MoKSB8fCB7fVxuICAgICAgICApXG4gICAgICAgICAgLmZpbHRlcigoWywgaXNFbmFibGVkXSkgPT4gaXNFbmFibGVkKVxuICAgICAgICAgIC5tYXAoKFtmZWF0dXJlR2F0ZU5hbWVdKSA9PiBmZWF0dXJlR2F0ZU5hbWUpLCAvLyBVc2UgZmVhdHVyZUZsYWdTZXJ2aWNlXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVzcG9uc2UgPVxuICAgICAgICBhd2FpdCBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLmRlZmF1bHRBcGkudjFPcmdDb25maWdHZXQoXG4gICAgICAgICAgcmVxdWVzdFxuICAgICAgICApO1xuXG4gICAgICByZXR1cm4gdmFsaWRhdGVPcmdDb25maWdSZXN1bHRzKHJlc3BvbnNlKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIExvZ2dlci5sb2dFcnJvcihgRmFpbGVkIHRvIGdldCBvcmcgY29uZmlnYCwgZXJyLCB7IGVyciB9KTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9O1xuXG4gIHN0YXRpYyBhZGROb3RlVG9MYXRlc3RDb252ZXJzYXRpb24gPSBhc3luYyAoXG4gICAgc3BpZmZ5VXNlcklkOiBzdHJpbmcsXG4gICAgZW1haWw6IHN0cmluZyxcbiAgICBjdXN0b21lclNlcnZpY2VQcm92aWRlcjogQ3VzdG9tZXJTZXJ2aWNlUHJvdmlkZXJcbiAgKSA9PiB7XG4gICAgTG9nZ2VyLmxvZ0luZm8oXG4gICAgICBgYWRkTm90ZVRvTGF0ZXN0Q29udmVyc2F0aW9uIC0gdXNlcl9pZD0ke3NwaWZmeVVzZXJJZH0gZW1haWw9JHtlbWFpbH0gY3VzdG9tZXJfc2VydmljZV9wcm92aWRlcj0ke2N1c3RvbWVyU2VydmljZVByb3ZpZGVyfWBcbiAgICApO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLmN1c3RvbWVyU2VydmljZUFwaS52MUN1c3RzZXJ2aWNlQWRkTm90ZVRvTGF0ZXN0Q29udmVyc2F0aW9uUG9zdChcbiAgICAgICAge1xuICAgICAgICAgIEFkZE5vdGVUb0xhdGVzdENvbnZlcnNhdGlvblJlcXVlc3Q6IHtcbiAgICAgICAgICAgIHNwaWZmeV91c2VyX2lkOiBzcGlmZnlVc2VySWQsXG4gICAgICAgICAgICBlbWFpbCxcbiAgICAgICAgICAgIGN1c3RvbWVyX3NlcnZpY2VfcHJvdmlkZXI6IGN1c3RvbWVyU2VydmljZVByb3ZpZGVyLFxuICAgICAgICAgIH0sXG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBMb2dnZXIubG9nRXJyb3IoXCJGYWlsZWQgdG8gYWRkIG5vdGUgdG8gbGF0ZXN0IGNvbnZlcnNhdGlvblwiLCB7IGVyciB9KTtcbiAgICB9XG4gIH07XG5cbiAgc3RhdGljIGdldEN1c3RvbWVyU2VydmljZUFwaSA9ICgpID0+XG4gICAgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5jdXN0b21lclNlcnZpY2VBcGk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IENvbW1lcmNlQXBpQ2xpZW50O1xuIiwiaW1wb3J0IHsgdXNlU3RhdGUsIHVzZUNhbGxiYWNrIH0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQge1xuICBTcGlmZnlNZXRyaWNzRXZlbnROYW1lLFxuICB1c2VBbXBsaXR1ZGUsXG59IGZyb20gXCJzcmMvY29udGV4dHMvYW1wbGl0dWRlQ29udGV4dFwiO1xuXG5leHBvcnQgY29uc3QgdXNlQW1wbGl0dWRlVHJhY2tpbmcgPSAoKSA9PiB7XG4gIGNvbnN0IHsgdHJhY2tFdmVudCwgaXNSZWFkeSB9ID0gdXNlQW1wbGl0dWRlKCk7XG4gIGNvbnN0IFtsb2FkaW5nLCBzZXRMb2FkaW5nXSA9IHVzZVN0YXRlKGZhbHNlKTtcbiAgY29uc3QgW2Vycm9yLCBzZXRFcnJvcl0gPSB1c2VTdGF0ZTxFcnJvciB8IG51bGw+KG51bGwpO1xuXG4gIGNvbnN0IHRyYWNrID0gdXNlQ2FsbGJhY2soXG4gICAgYXN5bmMgKFxuICAgICAgZXZlbnROYW1lOiBTcGlmZnlNZXRyaWNzRXZlbnROYW1lLFxuICAgICAgZXZlbnRQcm9wcz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+XG4gICAgKSA9PiB7XG4gICAgICBpZiAoIWlzUmVhZHkpIHJldHVybjtcblxuICAgICAgc2V0TG9hZGluZyh0cnVlKTtcbiAgICAgIHNldEVycm9yKG51bGwpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB0cmFja0V2ZW50KHsgZXZlbnROYW1lLCBldmVudFByb3BzIH0pO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHNldEVycm9yKGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyIDogbmV3IEVycm9yKFwiVHJhY2tpbmcgZmFpbGVkXCIpKTtcbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgc2V0TG9hZGluZyhmYWxzZSk7XG4gICAgICB9XG4gICAgfSxcbiAgICBbdHJhY2tFdmVudCwgaXNSZWFkeV1cbiAgKTtcblxuICByZXR1cm4geyB0cmFjaywgbG9hZGluZywgZXJyb3IsIGlzUmVhZHkgfTtcbn07XG4iLCJpbXBvcnQgeyB1c2VFZmZlY3QgfSBmcm9tIFwicmVhY3RcIjtcblxuZXhwb3J0IGNvbnN0IHVzZUJsb2NrQmFja0J1dHRvbiA9IChlbmFibGVkOiBib29sZWFuLCBjYWxsYmFjazogKCkgPT4gdm9pZCkgPT4ge1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKGVuYWJsZWQgJiYgd2luZG93KSB7XG5cbiAgICAgIGlmICh3aW5kb3cuaGlzdG9yeS5zY3JvbGxSZXN0b3JhdGlvbikge1xuICAgICAgICB3aW5kb3cuaGlzdG9yeS5zY3JvbGxSZXN0b3JhdGlvbiA9IFwibWFudWFsXCJcbiAgICAgIH1cblxuICAgICAgd2luZG93Lmhpc3RvcnkucHVzaFN0YXRlKG51bGwsIGRvY3VtZW50LnRpdGxlLCB3aW5kb3cubG9jYXRpb24uaHJlZik7XG4gICAgICB3aW5kb3cub25wb3BzdGF0ZSA9IChlKSA9PiB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgd2luZG93Lmhpc3RvcnkucHVzaFN0YXRlKG51bGwsIGRvY3VtZW50LnRpdGxlLCB3aW5kb3cubG9jYXRpb24uaHJlZik7XG4gICAgICAgIGNhbGxiYWNrPy4oKVxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgaWYgKGVuYWJsZWQgJiYgd2luZG93KSB7XG4gICAgICAgIHdpbmRvdy5oaXN0b3J5LmJhY2soKVxuICAgICAgICB3aW5kb3cub25wb3BzdGF0ZSA9IG51bGxcbiAgICAgICAgd2luZG93Lmhpc3Rvcnkuc2Nyb2xsUmVzdG9yYXRpb24gPSBcImF1dG9cIjtcbiAgICAgIH1cbiAgICB9XG4gIH0sIFtlbmFibGVkXSlcblxufSIsImltcG9ydCB7IHVzZUNkbiB9IGZyb20gXCIuLi9jb250ZXh0cy9jZG5Db250ZXh0XCI7XG5cbmV4cG9ydCBjb25zdCB1c2VDZG5VcmwgPSAoKSA9PiB7XG4gIGNvbnN0IHsgY2RuVXJsIH0gPSB1c2VDZG4oKTtcbiAgcmV0dXJuIGNkblVybDtcbn07XG5cbmV4cG9ydCBjb25zdCB1c2VDZG5CYXNlUGF0aCA9ICgpID0+IHtcbiAgY29uc3QgeyBnZXRDZG5CYXNlUGF0aCB9ID0gdXNlQ2RuKCk7XG4gIHJldHVybiBnZXRDZG5CYXNlUGF0aCgpO1xufTtcblxuZXhwb3J0IGNvbnN0IHVzZUFzc2V0VXJsID0gKGFzc2V0TmFtZTogc3RyaW5nLCBvcmdTaG9ydE5hbWU6IHN0cmluZykgPT4ge1xuICBjb25zdCB7IGdldEFzc2V0VVJMIH0gPSB1c2VDZG4oKTtcbiAgcmV0dXJuIGdldEFzc2V0VVJMKGFzc2V0TmFtZSwgb3JnU2hvcnROYW1lKTtcbn07XG4iLCJpbXBvcnQgeyB1c2VBdG9tVmFsdWUsIHVzZVNldEF0b20gfSBmcm9tIFwiam90YWlcIjtcbmltcG9ydCB7IENoYXRFbGVtZW50RGlzcGxheUxvY2F0aW9uIH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9tb2RlbHMvY2hhdEVsZW1lbnREaXNwbGF5TG9jYXRpb25cIjtcbmltcG9ydCB7IGNoYXRBdG9tLCBjaGF0T25Ub2dnbGVBdG9tIH0gZnJvbSBcInNyYy9hdG9tcy9jaGF0XCI7XG5pbXBvcnQge1xuICBTcGlmZnlNZXRyaWNzRXZlbnROYW1lLFxuICB1c2VBbXBsaXR1ZGUsXG59IGZyb20gXCJzcmMvY29udGV4dHMvYW1wbGl0dWRlQ29udGV4dFwiO1xuXG5leHBvcnQgY29uc3QgdXNlQ2hhdFRvZ2dsZSA9ICgpID0+IHtcbiAgY29uc3Qgb25Ub2dnbGUgPSB1c2VTZXRBdG9tKGNoYXRPblRvZ2dsZUF0b20pO1xuICBjb25zdCB7IGlzT3BlbiB9ID0gdXNlQXRvbVZhbHVlKGNoYXRBdG9tKTtcbiAgY29uc3QgeyB0cmFja0V2ZW50IH0gPSB1c2VBbXBsaXR1ZGUoKTtcblxuICBjb25zdCB0b2dnbGUgPSAoXG4gICAgdHJpZ2dlckxvY2F0aW9uOiBDaGF0RWxlbWVudERpc3BsYXlMb2NhdGlvbixcbiAgICB0cmlnZ2VySWQ/OiBzdHJpbmdcbiAgKSA9PiB7XG4gICAgaWYgKCFpc09wZW4pIHtcbiAgICAgIHRyYWNrRXZlbnQoe1xuICAgICAgICBldmVudE5hbWU6IFNwaWZmeU1ldHJpY3NFdmVudE5hbWUuQ2hhdENvbXBvbmVudEV4cGFuZGVkLFxuICAgICAgICBldmVudFByb3BzOiB7XG4gICAgICAgICAgbWVzc2FnZV9tZXRhZGF0YToge1xuICAgICAgICAgICAgdHJpZ2dlcl9sb2NhdGlvbjogdHJpZ2dlckxvY2F0aW9uLFxuICAgICAgICAgICAgdHJpZ2dlcl9pZDogdHJpZ2dlcklkLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdHJhY2tFdmVudCh7XG4gICAgICAgIGV2ZW50TmFtZTogU3BpZmZ5TWV0cmljc0V2ZW50TmFtZS5DaGF0Q29tcG9uZW50Q29sbGFwc2VkLFxuICAgICAgICBldmVudFByb3BzOiB7XG4gICAgICAgICAgbWVzc2FnZV9tZXRhZGF0YToge1xuICAgICAgICAgICAgdHJpZ2dlcl9sb2NhdGlvbjogdHJpZ2dlckxvY2F0aW9uLFxuICAgICAgICAgICAgdHJpZ2dlcl9pZDogdHJpZ2dlcklkLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBvblRvZ2dsZSgpO1xuICB9O1xuXG4gIGNvbnN0IG9wZW5DaGF0ID0gKFxuICAgIHRyaWdnZXJMb2NhdGlvbjogQ2hhdEVsZW1lbnREaXNwbGF5TG9jYXRpb24sXG4gICAgdHJpZ2dlcklkPzogc3RyaW5nXG4gICkgPT4ge1xuICAgIGlmICghaXNPcGVuKSB7XG4gICAgICB0b2dnbGUodHJpZ2dlckxvY2F0aW9uLCB0cmlnZ2VySWQpO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBjbG9zZUNoYXQgPSAoXG4gICAgdHJpZ2dlckxvY2F0aW9uOiBDaGF0RWxlbWVudERpc3BsYXlMb2NhdGlvbixcbiAgICB0cmlnZ2VySWQ/OiBzdHJpbmdcbiAgKSA9PiB7XG4gICAgaWYgKGlzT3Blbikge1xuICAgICAgdG9nZ2xlKHRyaWdnZXJMb2NhdGlvbiwgdHJpZ2dlcklkKTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIHtcbiAgICB0b2dnbGUsXG4gICAgaXNPcGVuLFxuICAgIG9wZW5DaGF0LFxuICAgIGNsb3NlQ2hhdCxcbiAgfTtcbn07XG4iLCJpbXBvcnQgeyB1c2VTZXRBdG9tIH0gZnJvbSBcImpvdGFpXCI7XG5pbXBvcnQgeyBjaGF0T25Ub2dnbGVBdG9tIH0gZnJvbSBcInNyYy9hdG9tcy9jaGF0L2NoYXRTdGF0ZVwiO1xuaW1wb3J0IHsgQ2hhdEVsZW1lbnREaXNwbGF5TG9jYXRpb24gfSBmcm9tIFwic3JjL2FwcGxpY2F0aW9uL21vZGVscy9jaGF0RWxlbWVudERpc3BsYXlMb2NhdGlvblwiO1xuaW1wb3J0IHsgdXNlQW1wbGl0dWRlVHJhY2tpbmcgfSBmcm9tIFwiLi91c2VBbXBsaXR1ZGVPcGVyYXRpb25zXCI7XG5cbmV4cG9ydCBjb25zdCB1c2VDaGF0VG9nZ2xlQW5hbHl0aWNzID0gKCkgPT4ge1xuICBjb25zdCBzZXRDaGF0T25Ub2dnbGUgPSB1c2VTZXRBdG9tKGNoYXRPblRvZ2dsZUF0b20pO1xuICBjb25zdCB7IHRyYWNrIH0gPSB1c2VBbXBsaXR1ZGVUcmFja2luZygpO1xuXG4gIGNvbnN0IHRvZ2dsZUNoYXQgPSAodHJpZ2dlckxvY2F0aW9uPzogQ2hhdEVsZW1lbnREaXNwbGF5TG9jYXRpb24pID0+IHtcbiAgICBzZXRDaGF0T25Ub2dnbGUodHJpZ2dlckxvY2F0aW9uLCB0cmFjayk7XG4gIH07XG5cbiAgcmV0dXJuIHsgdG9nZ2xlQ2hhdCB9O1xufTtcbiIsImltcG9ydCBMb2dnZXIgZnJvbSAnc3JjL2FwcGxpY2F0aW9uL2xvZ2dpbmcvbG9nZ2VyJztcbmltcG9ydCB7IHVzZUNhbGxiYWNrIH0gZnJvbSAncmVhY3QnO1xuXG4vKipcbiAqIEhvb2sgdG8gY2FsbCB0aGUgYGNsaWNrYCBtZXRob2Qgb2YgdGhlIG1lcmNoYW50J3MgY3VzdG9tZXIgc3VwcG9ydCBjaGF0IHdpZGdldC5cbiAqXG4gKiBAcGFyYW0gb25Td2l0Y2hUb0FnZW50IGEgZnVuY3Rpb24gdG8gb3ZlcnJpZGUgdGhlIGZ1bmN0aW9uIHJldHVybmVkIGJ5IHRoZSBob29rLiBUaGlzIGlzIG1haW5seSB0b1xuICogcHJlc2VydmUgYmFja3dhcmQgY29tcGF0aWJpbGl0eSBmb3IgbWVyY2hhbnRzIG5vdCB1c2luZyBLdXN0b21lciBhbmQgd2lsbCBiZSByZW1vdmVkIHdoZW4gYWxsXG4gKiBDUyBpbnRlZ3JhdGlvbnMgYXJlIGhhbmRsZWQuXG4gKlxuICogQHJldHVybnMgYSBmdW5jdGlvbiB0aGF0IHNlYXJjaGVzIGZvciB0aGUgY3VzdG9tZXIgc3VwcG9ydCBjaGF0IHdpZGdldCBhbmQgY2FsbHMgdGhlIGBjbGlja2AgbWV0aG9kLlxuICovXG5leHBvcnQgY29uc3QgdXNlQ3VzdG9tZXJTdXBwb3J0SGFuZG9mZiA9IChvblN3aXRjaFRvQWdlbnQ/OiAoKSA9PiB2b2lkKSA9PiB7XG4gIC8vIFRPRE8gaGFuZGxlIEdvcmdpYXNcblxuICBjb25zdCBvbkt1c3RvbWVyU3dpdGNoID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIGNvbnN0IGt1c3RvbWVyRWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdrdXN0b21lci11aS1zZGstaWZyYW1lJyk7XG5cbiAgICBpZiAoa3VzdG9tZXJFbGVtZW50ID09IG51bGwgfHwgIShrdXN0b21lckVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MSUZyYW1lRWxlbWVudCkpIHtcbiAgICAgIExvZ2dlci5sb2dFcnJvcignW3NwaWZmeS1haV0gS3VzdG9tZXIgaUZyYW1lIGVsZW1lbnQgbm90IGZvdW5kJywgdW5kZWZpbmVkKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBrdXN0b21lckJ1dHRvbiA9IGt1c3RvbWVyRWxlbWVudC5jb250ZW50V2luZG93Py5kb2N1bWVudD8uZ2V0RWxlbWVudEJ5SWQoJ3Jvb3RDaGF0SWNvbicpO1xuXG4gICAgaWYgKGt1c3RvbWVyQnV0dG9uID09IG51bGwpIHtcbiAgICAgIExvZ2dlci5sb2dFcnJvcignW3NwaWZmeS1haV0gS3VzdG9tZXIgYnV0dG9uIG5vdCBmb3VuZCcsIHVuZGVmaW5lZCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAga3VzdG9tZXJCdXR0b24uY2xpY2soKTtcbiAgfSwgW10pO1xuXG4gIGlmIChvblN3aXRjaFRvQWdlbnQgIT0gbnVsbCkge1xuICAgIHJldHVybiB7IG9uU3dpdGNoOiBvblN3aXRjaFRvQWdlbnQgfTtcbiAgfVxuXG4gIHJldHVybiB7IG9uU3dpdGNoOiBvbkt1c3RvbWVyU3dpdGNoIH07XG59O1xuIiwiaW1wb3J0IHsgdXNlU3RhdGUsIHVzZUVmZmVjdCB9IGZyb20gJ3JlYWN0JztcblxuZXhwb3J0IGZ1bmN0aW9uIHVzZURlYm91bmNlPFQ+KHZhbHVlOiBULCBkZWxheTogbnVtYmVyKTogVCB7XG4gIGNvbnN0IFtkZWJvdW5jZWRWYWx1ZSwgc2V0RGVib3VuY2VkVmFsdWVdID0gdXNlU3RhdGU8VD4odmFsdWUpO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3QgaGFuZGxlciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgc2V0RGVib3VuY2VkVmFsdWUodmFsdWUpO1xuICAgIH0sIGRlbGF5KTtcblxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQoaGFuZGxlcik7XG4gICAgfTtcbiAgfSwgW3ZhbHVlLCBkZWxheV0pO1xuXG4gIHJldHVybiBkZWJvdW5jZWRWYWx1ZTtcbn1cbiIsImltcG9ydCB7IFJlYWN0RWxlbWVudCwgdXNlRWZmZWN0LCB1c2VSZWYsIHVzZVN0YXRlIH0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgRE9NT2JzZXJ2ZXIgfSBmcm9tICdzcmMvYXBwbGljYXRpb24vdXRpbHMvZG9tT2JzZXJ2ZXInO1xuaW1wb3J0IHsgRWxlbWVudE9ic2VydmVyIH0gZnJvbSAnc3JjL2FwcGxpY2F0aW9uL3V0aWxzL2VsZW1lbnRPYnNlcnZlcic7XG5pbXBvcnQgeyBNb3VzZUV2ZW50VHlwZXMgfSBmcm9tICdzcmMvYXBwbGljYXRpb24vdXRpbHMvbW91c2VFdmVudFR5cGVzJztcbmltcG9ydCB7IE5vZGVTZWxlY3RvciB9IGZyb20gJ3NyYy9hcHBsaWNhdGlvbi91dGlscy9ub2RlU2VsZWN0b3InO1xuXG5leHBvcnQgaW50ZXJmYWNlIEVsZW1lbnRPYnNlcnZlclV0aWxpdHkge1xuICBvbkNoYW5nZTogKGZuOiAoZWw6IEhUTUxFbGVtZW50IHwgbnVsbCkgPT4gdm9pZCkgPT4gdm9pZDtcbiAgb25BZGQ6IChmbjogKGVsOiBIVE1MRWxlbWVudCB8IG51bGwpID0+IHZvaWQpID0+IHZvaWQ7XG4gIG9uUmVtb3ZlOiAoZm46IChlbDogSFRNTEVsZW1lbnQgfCBudWxsKSA9PiB2b2lkKSA9PiB2b2lkO1xuICBvbkNsYXNzQ2hhbmdlOiAoZm46IChjbGFzc2VzPzogRE9NVG9rZW5MaXN0KSA9PiB2b2lkKSA9PiB2b2lkO1xuICBvbkNsYXNzQWRkZWQ6IChjbGFzc05hbWU6IHN0cmluZywgZm46ICgpID0+IHZvaWQpID0+IHZvaWQ7XG4gIG9uQ2xhc3NSZW1vdmVkOiAoY2xhc3NOYW1lOiBzdHJpbmcsIGZuOiAoKSA9PiB2b2lkKSA9PiB2b2lkO1xuICBvbkFkZENoaWxkOiAoZm46IChub2Rlcz86IERPTVRva2VuTGlzdCkgPT4gdm9pZCkgPT4gdm9pZDtcbiAgb25SZW1vdmVDaGlsZDogKGZuOiAobm9kZXM/OiBET01Ub2tlbkxpc3QpID0+IHZvaWQpID0+IHZvaWQ7XG4gIG9uRXZlbnQ6IDxLIGV4dGVuZHMga2V5b2YgSFRNTEVsZW1lbnRFdmVudE1hcD4oXG4gICAgZXZlbnQ6IEssXG4gICAgZm46IEV2ZW50TGlzdGVuZXJPckV2ZW50TGlzdGVuZXJPYmplY3QsXG4gICkgPT4gdm9pZDtcbiAgYmxvY2tSZW5kZXJpbmc6ICgpID0+IHZvaWQ7XG4gIHVuYmxvY2tSZW5kZXJpbmc6ICgpID0+IHZvaWQ7XG4gIGV4aXN0czogKCkgPT4gYm9vbGVhbjtcbiAgaXNSZW5kZXJlZDogKCkgPT4gYm9vbGVhbjtcbiAgcmVuZGVyOiAoZm46ICgpID0+IFJlYWN0RWxlbWVudCkgPT4gUmVhY3RFbGVtZW50IHwgdW5kZWZpbmVkO1xuICBmaXJlOiAoZXZlbnQ6IE1vdXNlRXZlbnRUeXBlcykgPT4gdm9pZDtcbiAgc2hvdzogKCkgPT4gdm9pZDtcbiAgaGlkZTogKCkgPT4gdm9pZDtcbiAgYXBwbHlTdHlsZTogKHN0eWxlczogUmVhY3QuQ1NTUHJvcGVydGllcykgPT4gdm9pZDtcbiAgdGFyZ2V0Tm9kZTogSFRNTEVsZW1lbnQgfCBudWxsO1xufVxuXG4vKlxuICogVGhpcyBob29rIGVuYWJsZXMgdGhlIGNvbm5lY3Rpb24gYmV0d2VlbiBhIGBNdXRhdGlvbk9ic2VydmVyYCBhbmQgYSBSZWFjdC5qcyBjb21wb25lbnQuXG4gKiBJdCBhYnN0cmFjdHMgYWxsIHRoZSBuZWNlc3NhcnkgdmFsaWRhdGlvbnMgYW5kIGltcGxlbWVudGF0aW9ucyB0byBtb2RpZnkgSFRNTCBlbGVtZW50cyxcbiAqIG1vbml0b3IgdGhlaXIgY2hhbmdlcywgYW5kIGludGVyYWN0IHdpdGggdGhlbS4gVGhlIG9ubHkgcmVxdWlyZWQgaW5wdXQgaXMgdGhlIGVsZW1lbnQncyBzZWxlY3Rvci5cbiAqXG4gKiBIb3cgdG8gdXNlIGl0OlxuICpcbiAqIExldCdzIGFzc3VtZSB3ZSB3YW50IHRvIGludGVyYWN0IHdpdGggdGhlIGZvbGxvd2luZyBlbGVtZW50OlxuICogYDxkaXYgaWQ9XCJhd2Vzb21lLWNvbnRlbnRcIj48Y29udGVudCAvPjwvZGl2PmBcbiAqXG4gKiBUbyBob29rIGludG8gdGhhdCBlbGVtZW50LCBzaW1wbHkgZG8gdGhlIGZvbGxvd2luZzpcbiAqIGBjb25zdCBlbGVtZW50ID0gdXNlRWxlbWVudE9ic2VydmVyKFNlbGVjdG9yRmFjdG9yeS5pZChcImF3ZXNvbWUtY29udGVudFwiKSlgXG4gKlxuICogV2l0aCB0aGUgYEVsZW1lbnRPYnNlcnZlcmAgaW5zdGFuY2UgaW4gaGFuZCwgd2UgY2FuIGludGVyYWN0IHdpdGggdGhlIEhUTUwgZWxlbWVudCB3aXRob3V0IGhhdmluZ1xuICogdG8gbWFuYWdlIGl0cyBwcmVzZW5jZSBpbiB0aGUgRE9NLiBUaGUgYG9uQWRkYCBhbmQgYG9uUmVtb3ZlYCBmdW5jdGlvbnMgY2FuIGJlIHVzZWQgdG8gZGV0ZXJtaW5lXG4gKiB3aGV0aGVyIHRoZSBlbGVtZW50IGlzIHByZXNlbnQgaW4gdGhlIERPTSBvciBub3QsIGFuZCB0byBlbnN1cmUgaW50ZXJhY3Rpb24gb2NjdXJzIG9ubHkgd2hlbiBuZWNlc3NhcnkuXG4gKlxuICogQHBhcmFtIHNlbGVjdG9yXG4gKiBAcmV0dXJuc1xuICovXG5leHBvcnQgY29uc3QgdXNlRWxlbWVudE9ic2VydmVyID0gKHNlbGVjdG9yOiBOb2RlU2VsZWN0b3IpOiBFbGVtZW50T2JzZXJ2ZXJVdGlsaXR5ID0+IHtcbiAgY29uc3QgSU5JVElBTF9SRU5ERVJfU1RBVEUgPSB0cnVlO1xuICBjb25zdCBlb1JlZiA9IHVzZVJlZjxFbGVtZW50T2JzZXJ2ZXI+KERPTU9ic2VydmVyLmFkZChzZWxlY3RvcikpO1xuICBjb25zdCBbcmVuZGVyQmxvY2tlZCwgc2V0UmVuZGVyQmxvY2tlZF0gPSB1c2VTdGF0ZShJTklUSUFMX1JFTkRFUl9TVEFURSk7XG5cbiAgLyoqXG4gICAqIEZpcmVkIGV2ZXJ5IHRpbWUgdGhlIEhUTUwgZWxlbWVudCBjaGFuZ2VzLlxuICAgKlxuICAgKiBAcGFyYW0gZm5cbiAgICovXG4gIGNvbnN0IG9uQ2hhbmdlID0gKGZuOiAoZWw6IEhUTUxFbGVtZW50IHwgbnVsbCkgPT4gdm9pZCkgPT4ge1xuICAgIGVvUmVmLmN1cnJlbnQ/LnJlZ2lzdGVyT25DaGFuZ2UoZm4pO1xuICB9O1xuXG4gIC8qKlxuICAgKiBGaXJlZCB3aGVuIHRoZSBIVE1MIGVsZW1lbnQgaXMgYWRkZWQgdG8gdGhlIERPTS5cbiAgICpcbiAgICogQHBhcmFtIGZuXG4gICAqL1xuICBjb25zdCBvbkFkZCA9IChmbjogKGVsOiBIVE1MRWxlbWVudCB8IG51bGwpID0+IHZvaWQpID0+IHtcbiAgICBlb1JlZi5jdXJyZW50Py5yZWdpc3Rlck9uQWRkKGZuKTtcbiAgfTtcblxuICAvKipcbiAgICogRmlyZWQgd2hlbiB0aGUgSFRNTCBlbGVtZW50IGlzIHJlbW92ZWQgZnJvbSB0aGUgRE9NLlxuICAgKlxuICAgKiBAcGFyYW0gZm5cbiAgICovXG4gIGNvbnN0IG9uUmVtb3ZlID0gKGZuOiAoZWw6IEhUTUxFbGVtZW50IHwgbnVsbCkgPT4gdm9pZCkgPT4ge1xuICAgIGVvUmVmLmN1cnJlbnQ/LnJlZ2lzdGVyT25SZW1vdmUoZm4pO1xuICB9O1xuXG4gIC8qKlxuICAgKiBGaXJlZCB3aGVuIHRoZSBjbGFzcyBvZiB0aGUgSFRNTCBlbGVtZW50IGNoYW5nZXMuXG4gICAqXG4gICAqIEBwYXJhbSBmblxuICAgKi9cbiAgY29uc3Qgb25DbGFzc0NoYW5nZSA9IChmbjogKGNsYXNzZXM/OiBET01Ub2tlbkxpc3QpID0+IHZvaWQpID0+IHtcbiAgICBlb1JlZi5jdXJyZW50Py5yZWdpc3Rlck9uY2xhc3NDaGFuZ2UoZm4pO1xuICB9O1xuXG4gIC8qKlxuICAgKiBGaXJlZCB3aGVuIGEgY2xhc3MgaXMgYWRkZWQgdG8gdGhlIEhUTUwgZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIGNsYXNzTmFtZVxuICAgKiBAcGFyYW0gZm5cbiAgICovXG4gIGNvbnN0IG9uQ2xhc3NBZGRlZCA9IChjbGFzc05hbWU6IHN0cmluZywgZm46ICgpID0+IHZvaWQpID0+IHtcbiAgICBlb1JlZi5jdXJyZW50Py5yZWdpc3Rlck9uQ2xhc3NBZGRlZChjbGFzc05hbWUsIGZuKTtcbiAgfTtcblxuICAvKipcbiAgICogRmlyZWQgd2hlbiBhIGNsYXNzIGlzIHJlbW92ZWQgZnJvbSB0aGUgSFRNTCBlbGVtZW50LlxuICAgKlxuICAgKiBAcGFyYW0gY2xhc3NOYW1lXG4gICAqIEBwYXJhbSBmblxuICAgKi9cbiAgY29uc3Qgb25DbGFzc1JlbW92ZWQgPSAoY2xhc3NOYW1lOiBzdHJpbmcsIGZuOiAoKSA9PiB2b2lkKSA9PiB7XG4gICAgZW9SZWYuY3VycmVudD8ucmVnaXN0ZXJPbkNsYXNzUmVtb3ZlZChjbGFzc05hbWUsIGZuKTtcbiAgfTtcblxuICAvKipcbiAgICogRmlyZWQgd2hlbiBhIGNoaWxkIGVsZW1lbnQgaXMgYWRkZWQgdG8gdGhlIEhUTUwgZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIGZuXG4gICAqL1xuICBjb25zdCBvbkFkZENoaWxkID0gKGZuOiAobm9kZXM/OiBET01Ub2tlbkxpc3QpID0+IHZvaWQpID0+IHtcbiAgICBlb1JlZi5jdXJyZW50Py5yZWdpc3Rlck9uQWRkQ2hpbGQoZm4pO1xuICB9O1xuXG4gIC8qKlxuICAgKiBGaXJlZCB3aGVuIGEgY2hpbGQgZWxlbWVudCBpcyByZW1vdmVkIGZyb20gdGhlIEhUTUwgZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIGZuXG4gICAqL1xuICBjb25zdCBvblJlbW92ZUNoaWxkID0gKGZuOiAobm9kZXM/OiBET01Ub2tlbkxpc3QpID0+IHZvaWQpID0+IHtcbiAgICBlb1JlZi5jdXJyZW50Py5yZWdpc3Rlck9uUmVtb3ZlQ2hpbGQoZm4pO1xuICB9O1xuXG4gIC8qKlxuICAgKiBBbGxvd3MgaG9va2luZyBldmVudCBsaXN0ZW5lcnMgdG8gdGhlIEhUTUwgZWxlbWVudCwgc3VjaCBhcyBgZm9jdXNgLCBgYmx1cmAsIGV0Yy5cbiAgICpcbiAgICogQHBhcmFtIGV2ZW50XG4gICAqIEBwYXJhbSBmblxuICAgKi9cbiAgY29uc3Qgb25FdmVudCA9IDxLIGV4dGVuZHMga2V5b2YgSFRNTEVsZW1lbnRFdmVudE1hcD4oXG4gICAgZXZlbnQ6IEssXG4gICAgZm46IEV2ZW50TGlzdGVuZXJPckV2ZW50TGlzdGVuZXJPYmplY3QsXG4gICkgPT4ge1xuICAgIGVvUmVmLmN1cnJlbnQucmVnaXN0ZXJFdmVudChldmVudCwgZm4pO1xuICB9O1xuXG4gIC8qKlxuICAgKiBVc2VmdWwgd2hlbiByZW5kZXJpbmcgYSBSZWFjdC5qcyBjb21wb25lbnQgaW5zaWRlIHRoZSBIVE1MIGVsZW1lbnQuXG4gICAqXG4gICAqIEBwYXJhbSBmblxuICAgKiBAcmV0dXJuc1xuICAgKi9cbiAgY29uc3QgcmVuZGVyID0gKGZuOiAoKSA9PiBSZWFjdEVsZW1lbnQpID0+IHtcbiAgICBpZiAoIXJlbmRlckJsb2NrZWQpIHtcbiAgICAgIHJldHVybiBlb1JlZi5jdXJyZW50LnJlbmRlcihmbik7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGVsZW1lbnQgZXhpc3RzIGluIHRoZSBET00uXG4gICAqXG4gICAqIEByZXR1cm5zXG4gICAqL1xuICBjb25zdCBleGlzdHMgPSAoKSA9PiAhIWVvUmVmLmN1cnJlbnQuZ2V0Tm9kZSgpO1xuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgcmVuZGVyaW5nIGlzIHVuYmxvY2tlZC5cbiAgICpcbiAgICogQHJldHVybnNcbiAgICovXG4gIGNvbnN0IGlzUmVuZGVyZWQgPSAoKSA9PiAhcmVuZGVyQmxvY2tlZDtcblxuICAvKipcbiAgICogVHJpZ2dlcnMgYW4gZXZlbnQgZm9yIHRoZSBIVE1MIGVsZW1lbnQuXG4gICAqXG4gICAqIEBwYXJhbSBldmVudFxuICAgKi9cbiAgY29uc3QgZmlyZSA9IChldmVudDogTW91c2VFdmVudFR5cGVzKSA9PiB7XG4gICAgZW9SZWYuY3VycmVudC5maXJlKGV2ZW50KTtcbiAgfTtcblxuICAvKipcbiAgICogU2hvd3MgdGhlIEhUTUwgZWxlbWVudC5cbiAgICpcbiAgICogQHJldHVybnNcbiAgICovXG4gIGNvbnN0IHNob3cgPSAoKSA9PiBlb1JlZi5jdXJyZW50LnNob3coKTtcblxuICAvKipcbiAgICogSGlkZXMgdGhlIEhUTUwgZWxlbWVudC5cbiAgICpcbiAgICogQHJldHVybnNcbiAgICovXG4gIGNvbnN0IGhpZGUgPSAoKSA9PiBlb1JlZi5jdXJyZW50LmhpZGUoKTtcblxuICAvKipcbiAgICogQmxvY2tzIHRoZSByZW5kZXJpbmcgb2YgZWxlbWVudHMuXG4gICAqXG4gICAqIEByZXR1cm5zXG4gICAqL1xuICBjb25zdCBibG9ja1JlbmRlcmluZyA9ICgpID0+IHNldFJlbmRlckJsb2NrZWQodHJ1ZSk7XG5cbiAgLyoqXG4gICAqIFVuYmxvY2tzIHRoZSByZW5kZXJpbmcgb2YgZWxlbWVudHMuXG4gICAqXG4gICAqIEByZXR1cm5zXG4gICAqL1xuICBjb25zdCB1bmJsb2NrUmVuZGVyaW5nID0gKCkgPT4gc2V0UmVuZGVyQmxvY2tlZChmYWxzZSk7XG5cbiAgLyoqXG4gICAqIEFwcGxpZXMgQ1NTIHN0eWxlcyB0byB0aGUgSFRNTCBlbGVtZW50LlxuICAgKlxuICAgKiBAcGFyYW0gc3R5bGVzXG4gICAqL1xuICBjb25zdCBhcHBseVN0eWxlID0gKHN0eWxlczogUmVhY3QuQ1NTUHJvcGVydGllcykgPT4ge1xuICAgIGNvbnN0IG5vZGUgPSBlb1JlZj8uY3VycmVudD8uZ2V0Tm9kZSgpO1xuICAgIG5vZGUgJiYgT2JqZWN0LmFzc2lnbihub2RlLnN0eWxlLCBzdHlsZXMpO1xuICB9O1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgZW9SZWYuY3VycmVudC5pbml0KCk7XG4gICAgZW9SZWYuY3VycmVudC5yZWdpc3Rlck9uUmVzZXQoKCkgPT4gc2V0UmVuZGVyQmxvY2tlZChJTklUSUFMX1JFTkRFUl9TVEFURSkpO1xuICAgIERPTU9ic2VydmVyLm9ic2VydmUoKTtcbiAgICByZXR1cm4gKCkgPT4gRE9NT2JzZXJ2ZXIucmVtb3ZlKHNlbGVjdG9yKTtcbiAgfSwgW3NlbGVjdG9yLmdldFBhdHRlcm4oKV0pO1xuXG4gIHJldHVybiB7XG4gICAgdGFyZ2V0Tm9kZTogZW9SZWYuY3VycmVudC5nZXROb2RlKCksXG4gICAgb25DaGFuZ2UsXG4gICAgb25BZGQsXG4gICAgb25SZW1vdmUsXG4gICAgb25DbGFzc0NoYW5nZSxcbiAgICBvbkNsYXNzQWRkZWQsXG4gICAgb25DbGFzc1JlbW92ZWQsXG4gICAgb25BZGRDaGlsZCxcbiAgICBvblJlbW92ZUNoaWxkLFxuICAgIG9uRXZlbnQsXG4gICAgYmxvY2tSZW5kZXJpbmcsXG4gICAgdW5ibG9ja1JlbmRlcmluZyxcbiAgICBleGlzdHMsXG4gICAgaXNSZW5kZXJlZCxcbiAgICByZW5kZXIsXG4gICAgZmlyZSxcbiAgICBzaG93LFxuICAgIGhpZGUsXG4gICAgYXBwbHlTdHlsZSxcbiAgfSBzYXRpc2ZpZXMgRWxlbWVudE9ic2VydmVyVXRpbGl0eTtcbn07XG4iLCJpbXBvcnQgeyB1c2VSZWYsIHVzZVN0YXRlIH0gZnJvbSBcInJlYWN0XCI7XG5cbnR5cGUgQXJyb3dQb3NpdGlvbiA9ICdsdCcgfCAnY3QnIHwgJ3J0J1xuXG5pbnRlcmZhY2UgQW5pbWF0aW9uUHJvcHMge1xuICAgIGVsZW1lbnQ6IEhUTUxFbGVtZW50XG4gICAgdGFyZ2V0U2Nyb2xsOiBudW1iZXIgXG4gICAgZHVyYXRpb246IG51bWJlciBcbiAgICBkaXJlY3Rpb24/OiAnbHQnIHwgJ3J0JyBcbiAgICBtdWx0aXBseT86IG51bWJlciBcbiAgICBvZmZzZXQ/OiBudW1iZXJcbiAgICBjYWxsYmFjaz86IChwb3NpdGlvbjogQXJyb3dQb3NpdGlvbikgPT4gdm9pZFxufVxuXG5jb25zdCBhbmltYXRlSG9yaXpvbnRhbFNjcm9sbCA9ICh7IGVsZW1lbnQsIGR1cmF0aW9uLCB0YXJnZXRTY3JvbGwsIG11bHRpcGx5ID0gMSwgZGlyZWN0aW9uLCBjYWxsYmFjaywgb2Zmc2V0ID0gMCB9OiBBbmltYXRpb25Qcm9wcykgPT4ge1xuICAgIGNvbnN0IHN0YXJ0ID0gZWxlbWVudC5zY3JvbGxMZWZ0XG4gICAgY29uc3QgZGlzdGFuY2UgPSAodGFyZ2V0U2Nyb2xsIC0gc3RhcnQpICogbXVsdGlwbHk7XG4gICAgY29uc3Qgc3RhcnRUaW1lID0gcGVyZm9ybWFuY2Uubm93KCk7XG5cbiAgICBmdW5jdGlvbiBlYXNlT3V0U2luZSh4OiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgcmV0dXJuIE1hdGguc2luKCh4ICogTWF0aC5QSSkgLyAyKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzY3JvbGxTdGVwKGN1cnJlbnRUaW1lOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgdGltZUVsYXBzZWQgPSBjdXJyZW50VGltZSAtIHN0YXJ0VGltZTtcbiAgICAgICAgY29uc3QgcHJvZ3Jlc3MgPSBNYXRoLm1pbih0aW1lRWxhcHNlZCAvIGR1cmF0aW9uLCAxKTtcbiAgICAgICAgY29uc3QgZWFzaW5nID0gZWFzZU91dFNpbmUocHJvZ3Jlc3MpO1xuICAgICAgICBjb25zdCBzdGVwID0gc3RhcnQgKyAoZGlzdGFuY2UgKiBlYXNpbmcpXG4gICAgICAgIGNvbnN0IGNhblNjcm9sbCA9IChkaXJlY3Rpb24gPT09ICdydCcgPyAoZWxlbWVudC5zY3JvbGxMZWZ0IDwgc3RlcCkgOiAoZWxlbWVudC5zY3JvbGxMZWZ0ID4gc3RlcCkpIHx8ICFkaXJlY3Rpb25cbiAgICAgICAgXG4gICAgICAgIGlmIChzdGVwID4gMCAmJiBjYW5TY3JvbGwpIHtcbiAgICAgICAgICBlbGVtZW50LnNjcm9sbFRvKHN0ZXAsIDApXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGltZUVsYXBzZWQgPCBkdXJhdGlvbikge1xuICAgICAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHNjcm9sbFN0ZXApO1xuICAgICAgICB9IFxuXG4gICAgICAgIC8vIEVuZCBvZiBzY3JvbGxpbmcgY29udGFpbmVyXG4gICAgICAgIGVsc2UgaWYgKChlbGVtZW50LnNjcm9sbExlZnQgKyBvZmZzZXQpID09PSBlbGVtZW50LnNjcm9sbFdpZHRoKSB7XG4gICAgICAgICAgICBjYWxsYmFjaz8uKCdydCcpXG4gICAgICAgIH0gXG4gICAgICAgIC8vIEJlZ2luIG9mIHNjcm9sbGluZyBjb250YWluZXJcbiAgICAgICAgZWxzZSBpZiAoZWxlbWVudC5zY3JvbGxMZWZ0IDw9IDEpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrPy4oJ2x0JylcbiAgICAgICAgfVxuICAgICAgICAvLyBTb21ld2hlcmUgaW4gdGhlIG1pZGRsZVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNhbGxiYWNrPy4oJ2N0JylcbiAgICAgICAgfVxuXG4gICAgfVxuXG4gICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHNjcm9sbFN0ZXApO1xufVxuXG5cbmV4cG9ydCBjb25zdCB1c2VHcmFiQW5kU2Nyb2xsID0gKGVuYWJsZWQ6IGJvb2xlYW4sIGNodW5rV2lkdGg6IG51bWJlciwgc3BlZWQ6IG51bWJlciA9IDQwMCwgb2Zmc2V0OiBudW1iZXIgPSAwKSA9PiB7XG4gICAgY29uc3QgY29udGFpbmVyUmVmID0gdXNlUmVmPEhUTUxEaXZFbGVtZW50PihudWxsKVxuICAgIGNvbnN0IFsgbGVmdEFycm93LCBzZXRMZWZ0QXJyb3cgXSA9IHVzZVN0YXRlKGZhbHNlKVxuICAgIGNvbnN0IFsgcmlnaHRBcnJvdywgc2V0UmlnaHRBcnJvdyBdID0gdXNlU3RhdGUodHJ1ZSlcblxuICAgIGNvbnN0IGhhbmRsZUFycm93cyA9IChwb3NpdGlvbjogQXJyb3dQb3NpdGlvbikgPT4ge1xuICAgICAgICBzd2l0Y2ggKHBvc2l0aW9uKSB7XG4gICAgICAgICAgICBjYXNlICdsdCc6XG4gICAgICAgICAgICAgICAgc2V0TGVmdEFycm93KGZhbHNlKVxuICAgICAgICAgICAgICAgIHNldFJpZ2h0QXJyb3codHJ1ZSlcbiAgICAgICAgICAgICAgICBicmVha1xuXG4gICAgICAgICAgICBjYXNlICdydCc6XG4gICAgICAgICAgICAgICAgc2V0TGVmdEFycm93KHRydWUpXG4gICAgICAgICAgICAgICAgc2V0UmlnaHRBcnJvdyhmYWxzZSlcbiAgICAgICAgICAgICAgICBicmVha1xuXG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHNldExlZnRBcnJvdyh0cnVlKVxuICAgICAgICAgICAgICAgIHNldFJpZ2h0QXJyb3codHJ1ZSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGFuaW1hdGlvblRyaWdnZXIgPSAoKSA9PiB7XG4gICAgICAgIGlmIChlbmFibGVkICYmIGNvbnRhaW5lclJlZi5jdXJyZW50KSB7XG4gICAgICAgICAgICBjb25zdCBkaXN0ID0gKGNvbnRhaW5lclJlZj8uY3VycmVudD8uc2Nyb2xsTGVmdCB8fCAwKSAvIGNodW5rV2lkdGhcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldFNjcm9sbCA9IGNodW5rV2lkdGggKiAoTWF0aC5mbG9vcihkaXN0KSArIChkaXN0ICUgMSA+IDAuNSA/IDEgOiAwKSlcbiAgICAgICAgICAgIGFuaW1hdGVIb3Jpem9udGFsU2Nyb2xsKHtcbiAgICAgICAgICAgICAgICBlbGVtZW50OiBjb250YWluZXJSZWYuY3VycmVudCwgXG4gICAgICAgICAgICAgICAgdGFyZ2V0U2Nyb2xsLCBcbiAgICAgICAgICAgICAgICBkdXJhdGlvbjogc3BlZWQsXG4gICAgICAgICAgICAgICAgb2Zmc2V0LFxuICAgICAgICAgICAgICAgIGNhbGxiYWNrOiBoYW5kbGVBcnJvd3NcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBvbk5leHQgPSAoY2FyZHNUb1NsaWRlOiBudW1iZXIpID0+IHtcbiAgICAgICAgaWYgKGNvbnRhaW5lclJlZi5jdXJyZW50KSB7XG4gICAgICAgICAgICBjb25zdCB0YXJnZXRTY3JvbGwgPSBjb250YWluZXJSZWYuY3VycmVudC5zY3JvbGxMZWZ0ICsgY2h1bmtXaWR0aFxuICAgICAgICAgICAgYW5pbWF0ZUhvcml6b250YWxTY3JvbGwoe1xuICAgICAgICAgICAgICAgIGVsZW1lbnQ6IGNvbnRhaW5lclJlZi5jdXJyZW50LCBcbiAgICAgICAgICAgICAgICB0YXJnZXRTY3JvbGwsIFxuICAgICAgICAgICAgICAgIGR1cmF0aW9uOiBzcGVlZCwgXG4gICAgICAgICAgICAgICAgZGlyZWN0aW9uOiAncnQnLCBcbiAgICAgICAgICAgICAgICBtdWx0aXBseTogY2FyZHNUb1NsaWRlLFxuICAgICAgICAgICAgICAgIG9mZnNldCxcbiAgICAgICAgICAgICAgICBjYWxsYmFjazogaGFuZGxlQXJyb3dzXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxuICAgIFxuICAgIGNvbnN0IG9uUHJldmlvdXMgPSAoY2FyZHNUb1NsaWRlOiBudW1iZXIpID0+IHtcbiAgICAgICAgaWYgKGNvbnRhaW5lclJlZi5jdXJyZW50KSB7XG4gICAgICAgICAgICBjb25zdCB0YXJnZXRTY3JvbGwgPSBjb250YWluZXJSZWYuY3VycmVudC5zY3JvbGxMZWZ0IC0gY2h1bmtXaWR0aFxuICAgICAgICAgICAgYW5pbWF0ZUhvcml6b250YWxTY3JvbGwoe1xuICAgICAgICAgICAgICAgIGVsZW1lbnQ6IGNvbnRhaW5lclJlZi5jdXJyZW50LCBcbiAgICAgICAgICAgICAgICB0YXJnZXRTY3JvbGwsIFxuICAgICAgICAgICAgICAgIGR1cmF0aW9uOiBzcGVlZCwgXG4gICAgICAgICAgICAgICAgZGlyZWN0aW9uOiAnbHQnLCBcbiAgICAgICAgICAgICAgICBtdWx0aXBseTogY2FyZHNUb1NsaWRlLFxuICAgICAgICAgICAgICAgIG9mZnNldCxcbiAgICAgICAgICAgICAgICBjYWxsYmFjazogaGFuZGxlQXJyb3dzXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgY29udGFpbmVyUmVmLFxuICAgICAgICBsZWZ0QXJyb3csXG4gICAgICAgIHJpZ2h0QXJyb3csXG4gICAgICAgIGFuaW1hdGlvblRyaWdnZXIsXG4gICAgICAgIG9uTmV4dCxcbiAgICAgICAgb25QcmV2aW91c1xuICAgIH1cbn0iLCJpbXBvcnQgUmVhY3QsIHtcbiAgY3JlYXRlQ29udGV4dCxcbiAgdXNlQ29udGV4dCxcbiAgdXNlQ2FsbGJhY2ssXG4gIHVzZU1lbW8sXG4gIFJlYWN0Tm9kZSxcbn0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyB1c2VBdG9tVmFsdWUgfSBmcm9tIFwiam90YWlcIjtcbmltcG9ydCB7IGJhc2VVcmxBdG9tLCBvcmdMZXZlbEFwaUtleUF0b20gfSBmcm9tIFwic3JjL2F0b21zL2Vudml2ZS9lbnZpdmVDb25maWdcIjtcbmltcG9ydCB7IGdldE1lcmNoYW50T3JnSWRRdWVyeSB9IGZyb20gXCJzcmMvYXBwbGljYXRpb24vbW9kZWxzL2dyYXBocWwvcXVlcmllcy9nZXRNZXJjaGFudE9yZ0lkUXVlcnlcIjtcbmltcG9ydCB7IHZhbGlkYXRlR3JhcGhRTE9yZ0lkIH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9tb2RlbHMvdmFsaWRhdG9ycy92YWxpZGF0ZUdyYXBoUUxPcmdJZFwiO1xuaW1wb3J0IHtcbiAgZ2V0TWVyY2hhbnRDb2xvcnNRdWVyeSxcbiAgR2V0TWVyY2hhbnRDb2xvcnNRdWVyeURhdGEsXG4gIGdldE1lcmNoYW50RnJvbnRlbmRDb25maWdRdWVyeSxcbiAgR2V0TWVyY2hhbnRGcm9udGVuZENvbmZpZ1F1ZXJ5RGF0YSxcbn0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9tb2RlbHMvZ3JhcGhxbFwiO1xuaW1wb3J0IHsgdmFsaWRhdGVHcmFwaFFMQ29sb3JzQ29uZmlnIH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9tb2RlbHMvdmFsaWRhdG9ycy92YWxpZGF0ZUdyYXBoUUxDb2xvcnNDb25maWdcIjtcbmltcG9ydCB7IHZhbGlkYXRlR3JhcGhRTEZyb250ZW5kQ29uZmlnIH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9tb2RlbHMvdmFsaWRhdG9ycy92YWxpZGF0ZUdyYXBoUUxGcm9udGVuZENvbmZpZ1wiO1xuaW1wb3J0IHsgQ29sb3JNYXBwaW5nIH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9tb2RlbHMvY29sb3JzQ29uZmlnXCI7XG5pbXBvcnQgeyBGcm9udGVuZENvbmZpZyB9IGZyb20gXCJzcmMvYXBwbGljYXRpb24vbW9kZWxzL2Zyb250ZW5kQ29uZmlnXCI7XG5pbXBvcnQgTG9nZ2VyIGZyb20gXCJzcmMvYXBwbGljYXRpb24vbG9nZ2luZy9sb2dnZXJcIjtcbmltcG9ydCB7IGNvbmZpZ1ZlcnNpb24gfSBmcm9tIFwic3JjL3R5cGVzL2NvbmZpZy12ZXJzaW9uc1wiO1xuaW1wb3J0IHtcbiAgQ2FtZWxDYXNlZFByb3BlcnRpZXNEZWVwLFxuICB0cmFuc2Zvcm1TbmFrZVRvQ2FtZWwsXG59IGZyb20gXCJzcmMvYXBwbGljYXRpb24vbW9kZWxzXCI7XG5cbmludGVyZmFjZSBCYXNlTWVDb25maWdRdWVyeVJlc3BvbnNlIHtcbiAgbWU6IHtcbiAgICBvcmc/OiB7XG4gICAgICBpZDogc3RyaW5nO1xuICAgIH07XG4gICAgZ2V0UHJvZHVjdHNDb25maWdCeVZlcnNpb24/OiB7XG4gICAgICBmcm9udGVuZD86IHtcbiAgICAgICAgdmFsdWVzOiBDYW1lbENhc2VkUHJvcGVydGllc0RlZXA8R2V0TWVyY2hhbnRGcm9udGVuZENvbmZpZ1F1ZXJ5RGF0YT47XG4gICAgICB9O1xuICAgICAgY29sb3JzPzogeyB2YWx1ZXM6IENhbWVsQ2FzZWRQcm9wZXJ0aWVzRGVlcDxHZXRNZXJjaGFudENvbG9yc1F1ZXJ5RGF0YT4gfTtcbiAgICB9O1xuICB9O1xufVxuZXhwb3J0IHR5cGUgQ29sb3JzQ29uZmlnUmVzcG9uc2UgPSBDYW1lbENhc2VkUHJvcGVydGllc0RlZXA8Q29sb3JNYXBwaW5nPjtcbmV4cG9ydCB0eXBlIEZyb250ZW5kQ29uZmlnUmVzcG9uc2UgPSBDYW1lbENhc2VkUHJvcGVydGllc0RlZXA8RnJvbnRlbmRDb25maWc+O1xuXG5leHBvcnQgdHlwZSBHcmFwaFFsQ29uZmlnVmFsdWVzID0ge1xuICBjb2xvcnNDb25maWc/OiBDb2xvcnNDb25maWdSZXNwb25zZTtcbiAgZnJvbnRlbmRDb25maWc/OiBDYW1lbENhc2VkUHJvcGVydGllc0RlZXA8RnJvbnRlbmRDb25maWc+O1xufTtcblxuaW50ZXJmYWNlIEdyYXBoUUxDb250ZXh0VmFsdWUge1xuICBleGVjdXRlUXVlcnk6IDxUPihcbiAgICBxdWVyeTogc3RyaW5nLFxuICAgIHZhcmlhYmxlcz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+XG4gICkgPT4gUHJvbWlzZTxUPjtcbiAgZ2V0T3JnSWQ6ICgpID0+IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPjtcbiAgZ2V0Q29sb3JzQW5kRnJvbnRlbmRDb25maWc6ICgpID0+IFByb21pc2U8R3JhcGhRbENvbmZpZ1ZhbHVlcz47XG4gIGlzUmVhZHk6IGJvb2xlYW47XG59XG5cbmNvbnN0IEdyYXBoUUxDb250ZXh0ID0gY3JlYXRlQ29udGV4dDxHcmFwaFFMQ29udGV4dFZhbHVlIHwgbnVsbD4obnVsbCk7XG5cbmNvbnN0IGNvbG9yc0FuZEZyb250ZW5kQ29uZmlnUXVlcnkgPSAoKSA9PiBgXG4gIHF1ZXJ5ICgkdmVyc2lvbjogU3RyaW5nID0gXCIke2NvbmZpZ1ZlcnNpb24oKX1cIikge1xuICAgIG1lIHtcbiAgICAgIGdldFByb2R1Y3RzQ29uZmlnQnlWZXJzaW9uKHZlcnNpb246ICR2ZXJzaW9uKSB7XG4gICAgICAgIGZyb250ZW5kIHsgdmFsdWVzIH1cbiAgICAgICAgY29sb3JzIHsgdmFsdWVzIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbmA7XG5cbnR5cGUgR3JhcGhRTFByb3ZpZGVyUHJvcHMgPSB7XG4gIGNoaWxkcmVuOiBSZWFjdE5vZGU7XG59O1xuXG5leHBvcnQgY29uc3QgR3JhcGhRTFByb3ZpZGVyID0gKHsgY2hpbGRyZW4gfTogR3JhcGhRTFByb3ZpZGVyUHJvcHMpID0+IHtcbiAgY29uc3QgYXBpS2V5ID0gdXNlQXRvbVZhbHVlKG9yZ0xldmVsQXBpS2V5QXRvbSk7XG4gIGNvbnN0IGJhc2VVcmwgPSB1c2VBdG9tVmFsdWUoYmFzZVVybEF0b20pO1xuXG4gIGNvbnN0IGlzUmVhZHkgPSBCb29sZWFuKGFwaUtleSAmJiBiYXNlVXJsKTtcblxuICBjb25zdCBleGVjdXRlUXVlcnkgPSB1c2VDYWxsYmFjayhcbiAgICBhc3luYyAocXVlcnk6IHN0cmluZywgdmFyaWFibGVzPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IHtcbiAgICAgIGlmICghaXNSZWFkeSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJHcmFwaFFMIGNsaWVudCBub3QgcmVhZHkgLSBtaXNzaW5nIGFwaUtleSBvciBiYXNlVXJsXCIpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGAke2Jhc2VVcmx9L3YxL2dyYXBocWxgLCB7XG4gICAgICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICBcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICAgICAgICBBdXRob3JpemF0aW9uOiBgQmVhcmVyICR7YXBpS2V5fWAsXG4gICAgICAgIH0sXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsgcXVlcnksIHZhcmlhYmxlcyB9KSxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgR3JhcGhRTCByZXF1ZXN0IGZhaWxlZDogJHtyZXNwb25zZS5zdGF0dXNUZXh0fWApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICBpZiAocmVzdWx0LmVycm9ycykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEdyYXBoUUwgZXJyb3JzOiAke0pTT04uc3RyaW5naWZ5KHJlc3VsdC5lcnJvcnMpfWApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0LmRhdGE7XG4gICAgfSxcbiAgICBbYXBpS2V5LCBiYXNlVXJsLCBpc1JlYWR5XVxuICApO1xuXG4gIGNvbnN0IGdldE9yZ0lkID0gdXNlQ2FsbGJhY2soYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZXhlY3V0ZVF1ZXJ5KGdldE1lcmNoYW50T3JnSWRRdWVyeSk7XG4gICAgcmV0dXJuIHZhbGlkYXRlR3JhcGhRTE9yZ0lkKHJlc3BvbnNlLm1lLm9yZz8uaWQpO1xuICB9LCBbZXhlY3V0ZVF1ZXJ5XSk7XG5cbiAgY29uc3QgZ2V0Q29sb3JzQW5kRnJvbnRlbmRDb25maWcgPVxuICAgIHVzZUNhbGxiYWNrKGFzeW5jICgpOiBQcm9taXNlPEdyYXBoUWxDb25maWdWYWx1ZXM+ID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHF1ZXJ5ID0gYXdhaXQgY29sb3JzQW5kRnJvbnRlbmRDb25maWdRdWVyeSgpO1xuICAgICAgICBpZiAoIXF1ZXJ5KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ29sb3JzIGFuZCBmcm9udGVuZCBjb25maWcgcXVlcnkgaXMgbm90IGRlZmluZWRcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBleGVjdXRlUXVlcnkocXVlcnkpO1xuICAgICAgICBjb25zdCBjb2xvcnNDb25maWcgPVxuICAgICAgICAgIHJlc3BvbnNlLm1lLmdldFByb2R1Y3RzQ29uZmlnQnlWZXJzaW9uPy5jb2xvcnM/LnZhbHVlcztcbiAgICAgICAgY29uc3QgZnJvbnRlbmRDb25maWcgPVxuICAgICAgICAgIHJlc3BvbnNlLm1lLmdldFByb2R1Y3RzQ29uZmlnQnlWZXJzaW9uPy5mcm9udGVuZD8udmFsdWVzO1xuICAgICAgICBjb25zdCB0cmFuc2Zvcm1lZENvbG9yQ29uZmlnID0gdHJhbnNmb3JtU25ha2VUb0NhbWVsKGNvbG9yc0NvbmZpZyk7XG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybWVkRnJvbnRlbmRDb25maWcgPSB0cmFuc2Zvcm1TbmFrZVRvQ2FtZWwoZnJvbnRlbmRDb25maWcpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNvbG9yc0NvbmZpZzogdHJhbnNmb3JtZWRDb2xvckNvbmZpZyBhcyBDb2xvcnNDb25maWdSZXNwb25zZSxcbiAgICAgICAgICBmcm9udGVuZENvbmZpZzogdHJhbnNmb3JtZWRGcm9udGVuZENvbmZpZyBhcyBGcm9udGVuZENvbmZpZ1Jlc3BvbnNlLFxuICAgICAgICB9O1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIExvZ2dlci5sb2dFcnJvcihcbiAgICAgICAgICBcIkVycm9yIGZldGNoaW5nIGdyYXBocWwgY29sb3JzIGFuZCBmcm9udGVuZCBjb25maWdcIixcbiAgICAgICAgICBlcnJcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHsgY29sb3JzQ29uZmlnOiB1bmRlZmluZWQsIGZyb250ZW5kQ29uZmlnOiB1bmRlZmluZWQgfTtcbiAgICAgIH1cbiAgICB9LCBbZXhlY3V0ZVF1ZXJ5XSk7XG5cbiAgY29uc3QgdmFsdWUgPSB1c2VNZW1vKFxuICAgICgpID0+ICh7XG4gICAgICBleGVjdXRlUXVlcnksXG4gICAgICBnZXRPcmdJZCxcbiAgICAgIGdldENvbG9yc0FuZEZyb250ZW5kQ29uZmlnLFxuICAgICAgaXNSZWFkeSxcbiAgICB9KSxcbiAgICBbZXhlY3V0ZVF1ZXJ5LCBnZXRPcmdJZCwgZ2V0Q29sb3JzQW5kRnJvbnRlbmRDb25maWcsIGlzUmVhZHldXG4gICk7XG5cbiAgcmV0dXJuIChcbiAgICA8R3JhcGhRTENvbnRleHQuUHJvdmlkZXIgdmFsdWU9e3ZhbHVlfT57Y2hpbGRyZW59PC9HcmFwaFFMQ29udGV4dC5Qcm92aWRlcj5cbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCB1c2VHcmFwaFFMQ2xpZW50ID0gKCkgPT4ge1xuICBjb25zdCBjb250ZXh0ID0gdXNlQ29udGV4dChHcmFwaFFMQ29udGV4dCk7XG4gIGlmICghY29udGV4dCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcInVzZUdyYXBoUUxDbGllbnQgbXVzdCBiZSB1c2VkIHdpdGhpbiBhIEdyYXBoUUxQcm92aWRlclwiKTtcbiAgfVxuICByZXR1cm4gY29udGV4dDtcbn07XG4iLCJpbXBvcnQgeyB1c2VDYWxsYmFjaywgdXNlRWZmZWN0LCB1c2VTdGF0ZSB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgdXNlR3JhcGhRTENsaWVudCB9IGZyb20gXCJzcmMvY29udGV4dHMvZ3JhcGhxbENvbnRleHRcIjtcbmltcG9ydCB7IENvbG9yTWFwcGluZyB9IGZyb20gXCJzcmMvYXBwbGljYXRpb24vbW9kZWxzL2NvbG9yc0NvbmZpZ1wiO1xuaW1wb3J0IHsgRnJvbnRlbmRDb25maWcgfSBmcm9tIFwic3JjL2FwcGxpY2F0aW9uL21vZGVscy9mcm9udGVuZENvbmZpZ1wiO1xuaW1wb3J0IHsgdHJhbnNmb3JtU25ha2VUb0NhbWVsIH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9tb2RlbHNcIjtcblxuZXhwb3J0IGNvbnN0IHVzZUNvbG9yc0FuZEZyb250ZW5kQ29uZmlnID0gKCkgPT4ge1xuICBjb25zdCB7IGdldENvbG9yc0FuZEZyb250ZW5kQ29uZmlnLCBpc1JlYWR5IH0gPSB1c2VHcmFwaFFMQ2xpZW50KCk7XG4gIGNvbnN0IFtkYXRhLCBzZXREYXRhXSA9IHVzZVN0YXRlKHt9KTtcbiAgY29uc3QgW2xvYWRpbmcsIHNldExvYWRpbmddID0gdXNlU3RhdGUoZmFsc2UpO1xuICBjb25zdCBbZXJyb3IsIHNldEVycm9yXSA9IHVzZVN0YXRlPEVycm9yIHwgbnVsbD4obnVsbCk7XG5cbiAgY29uc3QgZmV0Y2hDb25maWcgPSB1c2VDYWxsYmFjayhhc3luYyAoKSA9PiB7XG4gICAgaWYgKCFpc1JlYWR5KSByZXR1cm47XG5cbiAgICBzZXRMb2FkaW5nKHRydWUpO1xuICAgIHNldEVycm9yKG51bGwpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGdldENvbG9yc0FuZEZyb250ZW5kQ29uZmlnKCk7XG4gICAgICBzZXREYXRhKHJlc3VsdCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBzZXRFcnJvcihlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyciA6IG5ldyBFcnJvcihcIlVua25vd24gZXJyb3JcIikpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBzZXRMb2FkaW5nKGZhbHNlKTtcbiAgICB9XG4gIH0sIFtnZXRDb2xvcnNBbmRGcm9udGVuZENvbmZpZywgaXNSZWFkeV0pO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgZmV0Y2hDb25maWcoKTtcbiAgfSwgW2ZldGNoQ29uZmlnXSk7XG5cbiAgcmV0dXJuIHsgZGF0YSwgbG9hZGluZywgZXJyb3IsIHJlZmV0Y2g6IGZldGNoQ29uZmlnIH07XG59O1xuXG5leHBvcnQgY29uc3QgdXNlT3JnSWQgPSAoKSA9PiB7XG4gIGNvbnN0IHsgZ2V0T3JnSWQsIGlzUmVhZHkgfSA9IHVzZUdyYXBoUUxDbGllbnQoKTtcbiAgY29uc3QgW29yZ0lkLCBzZXRPcmdJZF0gPSB1c2VTdGF0ZTxzdHJpbmcgfCB1bmRlZmluZWQ+KCk7XG4gIGNvbnN0IFtsb2FkaW5nLCBzZXRMb2FkaW5nXSA9IHVzZVN0YXRlKGZhbHNlKTtcbiAgY29uc3QgW2Vycm9yLCBzZXRFcnJvcl0gPSB1c2VTdGF0ZTxFcnJvciB8IG51bGw+KG51bGwpO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFpc1JlYWR5KSByZXR1cm47XG5cbiAgICBjb25zdCBmZXRjaE9yZ0lkID0gYXN5bmMgKCkgPT4ge1xuICAgICAgc2V0TG9hZGluZyh0cnVlKTtcbiAgICAgIHNldEVycm9yKG51bGwpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBpZCA9IGF3YWl0IGdldE9yZ0lkKCk7XG4gICAgICAgIHNldE9yZ0lkKGlkKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBzZXRFcnJvcihlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyciA6IG5ldyBFcnJvcihcIlVua25vd24gZXJyb3JcIikpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgc2V0TG9hZGluZyhmYWxzZSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGZldGNoT3JnSWQoKTtcbiAgfSwgW2dldE9yZ0lkLCBpc1JlYWR5XSk7XG5cbiAgcmV0dXJuIHsgb3JnSWQsIGxvYWRpbmcsIGVycm9yIH07XG59O1xuIiwiaW1wb3J0IFJlYWN0LCB7XG4gIGNyZWF0ZUNvbnRleHQsXG4gIHVzZUNhbGxiYWNrLFxuICB1c2VDb250ZXh0LFxuICB1c2VNZW1vLFxuICB1c2VTdGF0ZSxcbiAgdXNlRWZmZWN0LFxufSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCBVQVBhcnNlciBmcm9tIFwidWEtcGFyc2VyLWpzXCI7XG5pbXBvcnQgTG9nZ2VyIGZyb20gXCJzcmMvYXBwbGljYXRpb24vbG9nZ2luZy9sb2dnZXJcIjtcbmltcG9ydCBDb21tZXJjZUFwaUNsaWVudCBmcm9tIFwic3JjL2FwcGxpY2F0aW9uL2NvbW1lcmNlLWFwaVwiO1xuaW1wb3J0IHsgdjQgYXMgdXVpZCB9IGZyb20gXCJ1dWlkXCI7XG5pbXBvcnQgeyBDbGllbnREZXRhaWxzIH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9tb2RlbHMvY2xpZW50RGV0YWlsc1wiO1xuaW1wb3J0IHsgdXNlTG9jYWxTdG9yYWdlIH0gZnJvbSBcInNyYy9jb250ZXh0cy9sb2NhbFN0b3JhZ2VDb250ZXh0XCI7XG5cbi8vIEhlbHBlciBmdW5jdGlvbiBmcm9tIHRoZSBvcmlnaW5hbCBzZXJ2aWNlXG5jb25zdCBnZXRVc2VyQWdlbnREZXRhaWxzID0gKCk6IENsaWVudERldGFpbHMgPT4ge1xuICBjb25zdCB1YVBhcnNlciA9IG5ldyBVQVBhcnNlcigpO1xuICBjb25zdCByZXN1bHQgPSB1YVBhcnNlci5nZXRSZXN1bHQoKTtcblxuICByZXR1cm4ge1xuICAgIG9zOiByZXN1bHQ/Lm9zPy5uYW1lLFxuICAgIG9zVmVyc2lvbjogcmVzdWx0Py5vcz8udmVyc2lvbixcbiAgICBkZXZpY2VCcmFuZDogcmVzdWx0Py5kZXZpY2U/LnZlbmRvcixcbiAgICBkZXZpY2VNYW51ZmFjdHVyZXI6IHJlc3VsdD8uZGV2aWNlPy52ZW5kb3IsXG4gICAgZGV2aWNlTW9kZWw6IHJlc3VsdD8uZGV2aWNlPy5tb2RlbCxcbiAgICBicm93c2VyOiByZXN1bHQ/LmJyb3dzZXI/Lm5hbWUsXG4gICAgYnJvd3NlclZlcnNpb246IHJlc3VsdD8uYnJvd3Nlcj8udmVyc2lvbixcbiAgICB1c2VyQWdlbnQ6IHJlc3VsdD8udWEsXG4gIH07XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIFVzZXJJZGVudGl0eUNvbnRleHRUeXBlIHtcbiAgaWRlbnRpZnlVc2VyOiAoKSA9PiBQcm9taXNlPHZvaWQ+O1xuICBnZXRVc2VySWRPckRlZmF1bHQ6ICgpID0+IHN0cmluZztcbiAgZ2V0VXNlcklkT3ZlcnJpZGVGcm9tTG9jYWxTdG9yYWdlOiAoKSA9PiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIGdldFVzZXJJZERlZmF1bHRGcm9tTG9jYWxTdG9yYWdlOiAoKSA9PiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIHNldFVzZXJJZERlZmF1bHRJbkxvY2FsU3RvcmFnZTogKHVzZXJJZDogc3RyaW5nKSA9PiBzdHJpbmc7XG4gIHNldFVzZXJJZE92ZXJyaWRlSW5Mb2NhbFN0b3JhZ2U6ICh1c2VySWQ6IHN0cmluZykgPT4gc3RyaW5nO1xuICBjbGVhclVzZXJJZE92ZXJyaWRlSW5Mb2NhbFN0b3JhZ2U6ICgpID0+IHZvaWQ7XG4gIGlzUmVhZHk6IGJvb2xlYW47XG59XG5cbmNvbnN0IFVzZXJJZGVudGl0eUNvbnRleHQgPSBjcmVhdGVDb250ZXh0PFVzZXJJZGVudGl0eUNvbnRleHRUeXBlIHwgdW5kZWZpbmVkPihcbiAgdW5kZWZpbmVkXG4pO1xuXG5leHBvcnQgY29uc3QgVXNlcklkZW50aXR5UHJvdmlkZXI6IFJlYWN0LkZDPHsgY2hpbGRyZW46IFJlYWN0LlJlYWN0Tm9kZSB9PiA9ICh7XG4gIGNoaWxkcmVuLFxufSkgPT4ge1xuICBjb25zdCB7XG4gICAgZ2V0SXRlbSxcbiAgICBzZXRJdGVtLFxuICAgIGlzQXZhaWxhYmxlOiBsb2NhbFN0b3JhZ2VJc1JlYWR5LFxuICB9ID0gdXNlTG9jYWxTdG9yYWdlKCk7XG5cbiAgY29uc3QgW2lzUmVhZHksIHNldElzUmVhZHldID0gdXNlU3RhdGUoZmFsc2UpO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgLy8gQXNzdW1pbmcgQ29tbWVyY2VBcGlDbGllbnQgYW5kIG90aGVyIGRlcGVuZGVuY2llcyBhcmUgcmVhZHkgaWYgbG9jYWxTdG9yYWdlIGlzLlxuICAgIC8vIEluIGEgbW9yZSBjb21wbGV4IHNjZW5hcmlvLCB5b3UgbWlnaHQgaGF2ZSBtb3JlIGNoZWNrcyBoZXJlLlxuICAgIHNldElzUmVhZHkobG9jYWxTdG9yYWdlSXNSZWFkeSk7XG4gIH0sIFtsb2NhbFN0b3JhZ2VJc1JlYWR5XSk7XG5cbiAgY29uc3QgVVNFUl9JRF9PVkVSUklERV9LRVkgPSBcInYxLXNwaWZmeS11c2VyLWlkLW92ZXJyaWRlXCI7XG4gIGNvbnN0IFVTRVJfSURfREVGQVVMVF9LRVkgPSBcInYxLXNwaWZmeS11c2VyLWlkLWRlZmF1bHRcIjtcblxuICBjb25zdCBnZXRVc2VySWRPdmVycmlkZUZyb21Mb2NhbFN0b3JhZ2UgPSB1c2VDYWxsYmFjaygoKTpcbiAgICB8IHN0cmluZ1xuICAgIHwgdW5kZWZpbmVkID0+IHtcbiAgICByZXR1cm4gZ2V0SXRlbShVU0VSX0lEX09WRVJSSURFX0tFWSkgPz8gdW5kZWZpbmVkO1xuICB9LCBbZ2V0SXRlbV0pO1xuXG4gIGNvbnN0IGdldFVzZXJJZERlZmF1bHRGcm9tTG9jYWxTdG9yYWdlID0gdXNlQ2FsbGJhY2soKCk6XG4gICAgfCBzdHJpbmdcbiAgICB8IHVuZGVmaW5lZCA9PiB7XG4gICAgcmV0dXJuIGdldEl0ZW0oVVNFUl9JRF9ERUZBVUxUX0tFWSkgPz8gdW5kZWZpbmVkO1xuICB9LCBbZ2V0SXRlbV0pO1xuXG4gIGNvbnN0IHNldFVzZXJJZERlZmF1bHRJbkxvY2FsU3RvcmFnZSA9IHVzZUNhbGxiYWNrKFxuICAgICh1c2VySWQ6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gICAgICBMb2dnZXIubG9nSW5mbyhcbiAgICAgICAgYHNldFVzZXJJZERlZmF1bHRJbkxvY2FsU3RvcmFnZSAtIFNldHRpbmcgdXNlcl9pZD0ke3VzZXJJZH1gXG4gICAgICApO1xuICAgICAgc2V0SXRlbShVU0VSX0lEX0RFRkFVTFRfS0VZLCB1c2VySWQpO1xuICAgICAgLy8gd2luZG93LmRpc3BhdGNoRXZlbnQgaXMgaGFuZGxlZCBieSB1c2VMb2NhbFN0b3JhZ2Ugbm93XG4gICAgICByZXR1cm4gdXNlcklkO1xuICAgIH0sXG4gICAgW3NldEl0ZW0sIFVTRVJfSURfREVGQVVMVF9LRVldXG4gICk7XG5cbiAgY29uc3Qgc2V0VXNlcklkT3ZlcnJpZGVJbkxvY2FsU3RvcmFnZSA9IHVzZUNhbGxiYWNrKFxuICAgICh1c2VySWQ6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gICAgICBMb2dnZXIubG9nSW5mbyhcbiAgICAgICAgYHNldFVzZXJJZE92ZXJyaWRlSW5Mb2NhbFN0b3JhZ2UgLSBTZXR0aW5nIHVzZXJfaWQ9JHt1c2VySWR9YFxuICAgICAgKTtcbiAgICAgIHNldEl0ZW0oVVNFUl9JRF9PVkVSUklERV9LRVksIHVzZXJJZCk7XG4gICAgICAvLyB3aW5kb3cuZGlzcGF0Y2hFdmVudCBpcyBoYW5kbGVkIGJ5IHVzZUxvY2FsU3RvcmFnZSBub3dcbiAgICAgIHJldHVybiB1c2VySWQ7XG4gICAgfSxcbiAgICBbc2V0SXRlbSwgVVNFUl9JRF9PVkVSUklERV9LRVldXG4gICk7XG5cbiAgY29uc3QgY2xlYXJVc2VySWRPdmVycmlkZUluTG9jYWxTdG9yYWdlID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIExvZ2dlci5sb2dJbmZvKGBjbGVhclVzZXJJZE92ZXJyaWRlSW5Mb2NhbFN0b3JhZ2UgLSBDbGVhcmluZyB1c2VyX2lkYCk7XG4gICAgLy8gTG9jYWxTdG9yYWdlU2VydmljZS5nZXRMb2NhbFN0b3JhZ2UoKT8ucmVtb3ZlSXRlbShVU0VSX0lEX09WRVJSSURFX0tFWSk7XG4gICAgLy8gd2luZG93LmRpc3BhdGNoRXZlbnQgaXMgaGFuZGxlZCBieSB1c2VMb2NhbFN0b3JhZ2Ugbm93XG4gICAgc2V0SXRlbShVU0VSX0lEX09WRVJSSURFX0tFWSwgXCJcIik7IC8vIFNldCB0byBlbXB0eSBzdHJpbmcgdG8gY2xlYXJcbiAgfSwgW3NldEl0ZW0sIFVTRVJfSURfT1ZFUlJJREVfS0VZXSk7XG5cbiAgY29uc3QgZ2V0VXNlcklkT3JEZWZhdWx0ID0gdXNlQ2FsbGJhY2soKCk6IHN0cmluZyA9PiB7XG4gICAgY29uc3QgdXNlcklkT3ZlcnJpZGUgPSBnZXRVc2VySWRPdmVycmlkZUZyb21Mb2NhbFN0b3JhZ2UoKTtcbiAgICBpZiAodXNlcklkT3ZlcnJpZGUpIHtcbiAgICAgIHJldHVybiB1c2VySWRPdmVycmlkZTtcbiAgICB9XG5cbiAgICBjb25zdCBkZWZhdWx0VXNlcklkID0gZ2V0VXNlcklkRGVmYXVsdEZyb21Mb2NhbFN0b3JhZ2UoKTtcbiAgICBpZiAoZGVmYXVsdFVzZXJJZCkge1xuICAgICAgcmV0dXJuIGRlZmF1bHRVc2VySWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNldFVzZXJJZERlZmF1bHRJbkxvY2FsU3RvcmFnZShgc3BpZmZ5LXVzZXItaWQtJHt1dWlkKCl9YCk7XG4gIH0sIFtcbiAgICBnZXRVc2VySWRPdmVycmlkZUZyb21Mb2NhbFN0b3JhZ2UsXG4gICAgZ2V0VXNlcklkRGVmYXVsdEZyb21Mb2NhbFN0b3JhZ2UsXG4gICAgc2V0VXNlcklkRGVmYXVsdEluTG9jYWxTdG9yYWdlLFxuICBdKTtcblxuICBjb25zdCBpZGVudGlmeVVzZXIgPSB1c2VDYWxsYmFjayhhc3luYyAoKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgaWYgKCFpc1JlYWR5KSB7XG4gICAgICBMb2dnZXIubG9nV2FybihcbiAgICAgICAgXCJbVXNlcklkZW50aXR5Q29udGV4dF0gQ29udGV4dCBub3QgcmVhZHksIHNraXBwaW5nIGlkZW50aWZ5VXNlclwiLFxuICAgICAgICB1bmRlZmluZWRcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIC8vIFRlbXBvcmFyaWx5IGNvbW1lbnRlZCBvdXQgdW50aWwgV2luZG93RGF0YUxheWVyU2VydmljZSBpcyByZXNvbHZlZFxuICAgICAgLy8gY29uc3QgY2RwVXNlcklkID0gV2luZG93RGF0YUxheWVyU2VydmljZS5nZXRHb29nbGVBbmFseXRpY3NDbGllbnRJZCgpO1xuICAgICAgY29uc3QgY2RwVXNlcklkID0gXCJVTktOT1dOX0NEUF9VU0VSX0lEXCI7IC8vIFBsYWNlaG9sZGVyXG4gICAgICBjb25zdCB1c2VySWQgPSBnZXRVc2VySWRPckRlZmF1bHQoKTtcbiAgICAgIGNvbnN0IHVzZXJBZ2VudERldGFpbHMgPSBnZXRVc2VyQWdlbnREZXRhaWxzKCk7XG5cbiAgICAgIGlmICghY2RwVXNlcklkKSB7XG4gICAgICAgIExvZ2dlci5sb2dXYXJuKFxuICAgICAgICAgIFwiW3NwaWZmeS1haV0gTm8gR0EgQ2xpZW50IElEIGZvdW5kLCBza2lwcGluZyBpZGVudGlmeVVzZXJcIixcbiAgICAgICAgICB1bmRlZmluZWRcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBDb21tZXJjZUFwaUNsaWVudC5pZGVudGlmeVVzZXIodXNlcklkLCBjZHBVc2VySWQsIHVzZXJBZ2VudERldGFpbHMpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBMb2dnZXIubG9nRXJyb3IoXCJbc3BpZmZ5LWFpXSBFcnJvciBpZGVudGlmeWluZyB1c2VyXCIsIGVycm9yKTtcbiAgICB9XG4gIH0sIFtpc1JlYWR5LCBnZXRVc2VySWRPckRlZmF1bHRdKTtcblxuICBjb25zdCB2YWx1ZSA9IHVzZU1lbW8oXG4gICAgKCkgPT4gKHtcbiAgICAgIGlkZW50aWZ5VXNlcixcbiAgICAgIGdldFVzZXJJZE9yRGVmYXVsdCxcbiAgICAgIGdldFVzZXJJZE92ZXJyaWRlRnJvbUxvY2FsU3RvcmFnZSxcbiAgICAgIGdldFVzZXJJZERlZmF1bHRGcm9tTG9jYWxTdG9yYWdlLFxuICAgICAgc2V0VXNlcklkRGVmYXVsdEluTG9jYWxTdG9yYWdlLFxuICAgICAgc2V0VXNlcklkT3ZlcnJpZGVJbkxvY2FsU3RvcmFnZSxcbiAgICAgIGNsZWFyVXNlcklkT3ZlcnJpZGVJbkxvY2FsU3RvcmFnZSxcbiAgICAgIGlzUmVhZHksXG4gICAgfSksXG4gICAgW1xuICAgICAgaWRlbnRpZnlVc2VyLFxuICAgICAgZ2V0VXNlcklkT3JEZWZhdWx0LFxuICAgICAgZ2V0VXNlcklkT3ZlcnJpZGVGcm9tTG9jYWxTdG9yYWdlLFxuICAgICAgZ2V0VXNlcklkRGVmYXVsdEZyb21Mb2NhbFN0b3JhZ2UsXG4gICAgICBzZXRVc2VySWREZWZhdWx0SW5Mb2NhbFN0b3JhZ2UsXG4gICAgICBzZXRVc2VySWRPdmVycmlkZUluTG9jYWxTdG9yYWdlLFxuICAgICAgY2xlYXJVc2VySWRPdmVycmlkZUluTG9jYWxTdG9yYWdlLFxuICAgICAgaXNSZWFkeSxcbiAgICBdXG4gICk7XG5cbiAgcmV0dXJuIChcbiAgICA8VXNlcklkZW50aXR5Q29udGV4dC5Qcm92aWRlciB2YWx1ZT17dmFsdWV9PlxuICAgICAge2NoaWxkcmVufVxuICAgIDwvVXNlcklkZW50aXR5Q29udGV4dC5Qcm92aWRlcj5cbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCB1c2VVc2VySWRlbnRpdHkgPSAoKSA9PiB7XG4gIGNvbnN0IGNvbnRleHQgPSB1c2VDb250ZXh0KFVzZXJJZGVudGl0eUNvbnRleHQpO1xuICBpZiAoIWNvbnRleHQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBcInVzZVVzZXJJZGVudGl0eSBtdXN0IGJlIHVzZWQgd2l0aGluIGEgVXNlcklkZW50aXR5UHJvdmlkZXJcIlxuICAgICk7XG4gIH1cbiAgcmV0dXJuIGNvbnRleHQ7XG59O1xuIiwiaW1wb3J0IHsgdXNlU3RhdGUsIHVzZUNhbGxiYWNrIH0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyB1c2VVc2VySWRlbnRpdHkgfSBmcm9tIFwic3JjL2NvbnRleHRzL3VzZXJJZGVudGl0eUNvbnRleHRcIjtcblxuZXhwb3J0IGNvbnN0IHVzZUlkZW50aWZ5VXNlciA9ICgpID0+IHtcbiAgY29uc3QgeyBpZGVudGlmeVVzZXIsIGlzUmVhZHkgfSA9IHVzZVVzZXJJZGVudGl0eSgpO1xuICBjb25zdCBbbG9hZGluZywgc2V0TG9hZGluZ10gPSB1c2VTdGF0ZShmYWxzZSk7XG4gIGNvbnN0IFtlcnJvciwgc2V0RXJyb3JdID0gdXNlU3RhdGU8RXJyb3IgfCBudWxsPihudWxsKTtcblxuICBjb25zdCBleGVjdXRlSWRlbnRpZnlVc2VyID0gdXNlQ2FsbGJhY2soYXN5bmMgKCkgPT4ge1xuICAgIGlmICghaXNSZWFkeSkge1xuICAgICAgc2V0RXJyb3IobmV3IEVycm9yKFwiVXNlcklkZW50aXR5Q29udGV4dCBub3QgcmVhZHkuXCIpKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzZXRMb2FkaW5nKHRydWUpO1xuICAgIHNldEVycm9yKG51bGwpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGlkZW50aWZ5VXNlcigpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgc2V0RXJyb3IoXG4gICAgICAgIGVyciBpbnN0YW5jZW9mIEVycm9yXG4gICAgICAgICAgPyBlcnJcbiAgICAgICAgICA6IG5ldyBFcnJvcihcIlVua25vd24gZXJyb3IgZHVyaW5nIHVzZXIgaWRlbnRpZmljYXRpb24uXCIpXG4gICAgICApO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBzZXRMb2FkaW5nKGZhbHNlKTtcbiAgICB9XG4gIH0sIFtpZGVudGlmeVVzZXIsIGlzUmVhZHldKTtcblxuICByZXR1cm4geyBsb2FkaW5nLCBlcnJvciwgZXhlY3V0ZUlkZW50aWZ5VXNlciwgaXNSZWFkeSB9O1xufTtcbiIsImltcG9ydCB7IHVzZUF0b21WYWx1ZSB9IGZyb20gXCJqb3RhaVwiO1xuaW1wb3J0IHsgT3JnU2hvcnROYW1lIH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9tb2RlbHNcIjtcbmltcG9ydCB7IG9yZ1Nob3J0TmFtZUF0b20gfSBmcm9tIFwic3JjL2F0b21zL2Vudml2ZS9lbnZpdmVDb25maWdcIjtcbmFic3RyYWN0IGNsYXNzIEltYWdlUmVzb2x2ZXIge1xuICBhYnN0cmFjdCByZXNvbHZlKHVybDogc3RyaW5nLCBzaXplOiBudW1iZXIpOiBzdHJpbmc7XG59XG5cbmNsYXNzIE1lcmNoYW50SW1hZ2VSZXNvbHZlciB7XG4gIHByaXZhdGUgc3RhdGljIGltYWdlUmVzb2x2ZXJNYXAgPSBuZXcgTWFwPHN0cmluZywgSW1hZ2VSZXNvbHZlcj4oKTtcblxuICBwcml2YXRlIHN0YXRpYyBsb2FkTWFwcGluZygpIHtcbiAgICBpZiAodGhpcy5pbWFnZVJlc29sdmVyTWFwLnNpemUgPT09IDApIHtcbiAgICAgIHRoaXMuaW1hZ2VSZXNvbHZlck1hcC5zZXQoT3JnU2hvcnROYW1lLlNwYW54LCBuZXcgU2hvcGlmeUltYWdlUmVzb2x2ZXIoKSk7XG4gICAgICB0aGlzLmltYWdlUmVzb2x2ZXJNYXAuc2V0KFxuICAgICAgICBPcmdTaG9ydE5hbWUuU3BhbnhTdGFnaW5nLFxuICAgICAgICBuZXcgU2hvcGlmeUltYWdlUmVzb2x2ZXIoKVxuICAgICAgKTtcbiAgICAgIHRoaXMuaW1hZ2VSZXNvbHZlck1hcC5zZXQoXG4gICAgICAgIE9yZ1Nob3J0TmFtZS5VbmlxdWVWaW50YWdlLFxuICAgICAgICBuZXcgU2hvcGlmeUltYWdlUmVzb2x2ZXIoKVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuaW1hZ2VSZXNvbHZlck1hcDtcbiAgfVxuXG4gIHN0YXRpYyBnZXQobmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMubG9hZE1hcHBpbmcoKS5nZXQobmFtZSk7XG4gIH1cbn1cblxuY2xhc3MgU2hvcGlmeUltYWdlUmVzb2x2ZXIgZXh0ZW5kcyBJbWFnZVJlc29sdmVyIHtcbiAgcmVzb2x2ZSh1cmw6IHN0cmluZywgc2l6ZTogbnVtYmVyKTogc3RyaW5nIHtcbiAgICBjb25zdCBwYXR0ZXJuID0gL19cXGQreFxcLmpwZy87XG4gICAgY29uc3QgdXJsSGFzUHJlZml4ID0gcGF0dGVybi50ZXN0KHVybCk7XG4gICAgY29uc3QgbmV3U2l6ZVByZWZpeCA9IGBfJHtzaXplfXguanBnYDtcbiAgICBpZiAodXJsSGFzUHJlZml4KSB7XG4gICAgICByZXR1cm4gdXJsLnJlcGxhY2UocGF0dGVybiwgbmV3U2l6ZVByZWZpeCk7XG4gICAgfVxuICAgIHJldHVybiB1cmwucmVwbGFjZShcIi5qcGdcIiwgbmV3U2l6ZVByZWZpeCk7XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHVzZUltYWdlUmVzb2x2ZXIgPSAoKSA9PiB7XG4gIGNvbnN0IG9yZ1Nob3J0TmFtZSA9IHVzZUF0b21WYWx1ZShvcmdTaG9ydE5hbWVBdG9tKTtcbiAgY29uc3QgcmVzb2x2ZSA9IChpbWFnZT86IHN0cmluZywgc2l6ZT86IG51bWJlcikgPT4ge1xuICAgIGlmIChpbWFnZSAmJiBzaXplICYmIG9yZ1Nob3J0TmFtZSkge1xuICAgICAgY29uc3QgbmV3SW1hZ2VQYXRoID0gTWVyY2hhbnRJbWFnZVJlc29sdmVyLmdldChvcmdTaG9ydE5hbWUpPy5yZXNvbHZlKFxuICAgICAgICBpbWFnZSxcbiAgICAgICAgc2l6ZVxuICAgICAgKTtcbiAgICAgIHJldHVybiBuZXdJbWFnZVBhdGggfHwgaW1hZ2U7XG4gICAgfVxuICAgIHJldHVybiBpbWFnZTtcbiAgfTtcblxuICByZXR1cm4ge1xuICAgIHJlc29sdmUsXG4gIH07XG59O1xuIiwiaW1wb3J0IHsgUmVmT2JqZWN0LCB1c2VFZmZlY3QsIHVzZVN0YXRlIH0gZnJvbSAncmVhY3QnO1xuXG4vLyBodHRwczovL3Jhc2lsYmFpZGFyLm1lZGl1bS5jb20vdHJpZ2dlci1ldmVudC13aGVuLWVsZW1lbnQtZW50ZXJzLXZpZXdwb3J0LXRoZS1yZWFjdC13YXktMTY4NTA5ZGEyZTIzXG5leHBvcnQgY29uc3QgdXNlSW50ZXJzZWN0aW9uID0gKGVsZW1lbnQ6IFJlZk9iamVjdDxIVE1MRWxlbWVudD4sIHJvb3RNYXJnaW46IHN0cmluZykgPT4ge1xuICBjb25zdCBbaXNWaXNpYmxlLCBzZXRJc1Zpc2libGVdID0gdXNlU3RhdGUoZmFsc2UpO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3QgY3VycmVudCA9IGVsZW1lbnQ/LmN1cnJlbnQ7XG4gICAgY29uc3Qgb2JzZXJ2ZXIgPSBuZXcgSW50ZXJzZWN0aW9uT2JzZXJ2ZXIoXG4gICAgICAoW2VudHJ5XSkgPT4ge1xuICAgICAgICBzZXRJc1Zpc2libGUoZW50cnkuaXNJbnRlcnNlY3RpbmcpO1xuICAgICAgfSxcbiAgICAgIHsgcm9vdE1hcmdpbiB9LFxuICAgICk7XG5cbiAgICBpZiAoY3VycmVudCkge1xuICAgICAgb2JzZXJ2ZXI/Lm9ic2VydmUoY3VycmVudCk7XG4gICAgfVxuXG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGlmIChjdXJyZW50KSB7XG4gICAgICAgIG9ic2VydmVyLnVub2JzZXJ2ZShjdXJyZW50KTtcbiAgICAgIH1cbiAgICB9O1xuICB9LCBbXSk7XG5cbiAgcmV0dXJuIGlzVmlzaWJsZTtcbn07XG4iLCJpbXBvcnQgeyB1c2VTdGF0ZSwgdXNlRWZmZWN0IH0gZnJvbSAncmVhY3QnO1xuXG5leHBvcnQgY29uc3QgdXNlSXNTbWFsbFNjcmVlbiA9ICgpID0+IHtcbiAgY29uc3QgW2lzU21hbGwsIHNldElzU21hbGxdID0gdXNlU3RhdGUoZmFsc2UpO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3QgbWVkaWFRdWVyeSA9IHdpbmRvdy5tYXRjaE1lZGlhKCcobWF4LXdpZHRoOiA0NzlweCknKTtcblxuICAgIC8vIFNldCBpbml0aWFsIHZhbHVlXG4gICAgc2V0SXNTbWFsbChtZWRpYVF1ZXJ5Lm1hdGNoZXMpO1xuXG4gICAgLy8gVXBkYXRlIHN0YXRlIHdoZW4gdmlld3BvcnQgY2hhbmdlc1xuICAgIGNvbnN0IGhhbmRsZVJlc2l6ZSA9IChldmVudDogTWVkaWFRdWVyeUxpc3RFdmVudCkgPT4ge1xuICAgICAgc2V0SXNTbWFsbChldmVudC5tYXRjaGVzKTtcbiAgICB9O1xuXG4gICAgbWVkaWFRdWVyeS5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCBoYW5kbGVSZXNpemUpO1xuXG4gICAgcmV0dXJuICgpID0+IG1lZGlhUXVlcnkucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgaGFuZGxlUmVzaXplKTtcbiAgfSwgW10pO1xuXG4gIHJldHVybiBpc1NtYWxsO1xufTtcbiIsImltcG9ydCB7IHVzZVN0YXRlLCB1c2VFZmZlY3QsIHVzZUNhbGxiYWNrIH0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQge1xuICB1c2VMb2NhbFN0b3JhZ2UsXG4gIExvY2FsU3RvcmFnZUtleXMsXG59IGZyb20gXCIuLi9jb250ZXh0cy9sb2NhbFN0b3JhZ2VDb250ZXh0XCI7XG5pbXBvcnQgeyBMb2NhbFN0b3JhZ2VFdmVudExpc3RlbmVyIH0gZnJvbSBcIi4uL2FwcGxpY2F0aW9uL21vZGVscy9sb2NhbFN0b3JhZ2VFdmVudExpc3RlbmVyXCI7XG5cbi8vIFJlYWN0aXZlIGxvY2FsU3RvcmFnZSB2YWx1ZSBob29rXG5leHBvcnQgY29uc3QgdXNlTG9jYWxTdG9yYWdlVmFsdWUgPSAoa2V5OiBzdHJpbmcpID0+IHtcbiAgY29uc3QgeyBnZXRJdGVtLCBzZXRJdGVtLCBhdHRhY2hMaXN0ZW5lciwgZGV0YWNoTGlzdGVuZXIgfSA9XG4gICAgdXNlTG9jYWxTdG9yYWdlKCk7XG4gIGNvbnN0IFt2YWx1ZSwgc2V0VmFsdWVdID0gdXNlU3RhdGU8c3RyaW5nIHwgbnVsbD4oKCkgPT4gZ2V0SXRlbShrZXkpKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IGxpc3RlbmVyOiBMb2NhbFN0b3JhZ2VFdmVudExpc3RlbmVyID0ge1xuICAgICAgc3RvcmFnZUtleToga2V5LFxuICAgICAgbGlzdGVuZXI6IChldmVudDogU3RvcmFnZUV2ZW50KSA9PiB7XG4gICAgICAgIHNldFZhbHVlKGV2ZW50Lm5ld1ZhbHVlKTtcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIGF0dGFjaExpc3RlbmVyKGxpc3RlbmVyKTtcbiAgICByZXR1cm4gKCkgPT4gZGV0YWNoTGlzdGVuZXIobGlzdGVuZXIpO1xuICB9LCBba2V5LCBhdHRhY2hMaXN0ZW5lciwgZGV0YWNoTGlzdGVuZXJdKTtcblxuICBjb25zdCB1cGRhdGVWYWx1ZSA9IHVzZUNhbGxiYWNrKFxuICAgIChuZXdWYWx1ZTogc3RyaW5nKSA9PiB7XG4gICAgICBzZXRJdGVtKGtleSwgbmV3VmFsdWUpO1xuICAgICAgc2V0VmFsdWUobmV3VmFsdWUpO1xuICAgIH0sXG4gICAgW2tleSwgc2V0SXRlbV1cbiAgKTtcblxuICByZXR1cm4geyB2YWx1ZSwgc2V0VmFsdWU6IHVwZGF0ZVZhbHVlIH07XG59O1xuXG4vLyBGZWF0dXJlIGZsYWcgaG9vayBmb3IgU3BpZmZ5XG5leHBvcnQgY29uc3QgdXNlU3BpZmZ5RmVhdHVyZUZsYWcgPSAoKSA9PiB7XG4gIGNvbnN0IHsgc2V0U3BpZmZ5T25GZWF0dXJlRmxhZyB9ID0gdXNlTG9jYWxTdG9yYWdlKCk7XG4gIGNvbnN0IHsgdmFsdWUgfSA9IHVzZUxvY2FsU3RvcmFnZVZhbHVlKExvY2FsU3RvcmFnZUtleXMuU3BpZmZ5T25PdmVycmlkZSk7XG5cbiAgY29uc3Qgc2V0RmxhZyA9IHVzZUNhbGxiYWNrKFxuICAgIChmbGFnOiBib29sZWFuIHwgbnVsbCkgPT4ge1xuICAgICAgc2V0U3BpZmZ5T25GZWF0dXJlRmxhZyhmbGFnKTtcbiAgICB9LFxuICAgIFtzZXRTcGlmZnlPbkZlYXR1cmVGbGFnXVxuICApO1xuXG4gIHJldHVybiB7XG4gICAgdmFsdWU6IHZhbHVlID09PSBcInRydWVcIiA/IHRydWUgOiB2YWx1ZSA9PT0gXCJmYWxzZVwiID8gZmFsc2UgOiBudWxsLFxuICAgIHNldEZsYWcsXG4gIH07XG59O1xuXG4vLyBGZWF0dXJlIGZsYWcgaG9vayBmb3IgRW52aXZlXG5leHBvcnQgY29uc3QgdXNlRW52aXZlRmVhdHVyZUZsYWcgPSAoKSA9PiB7XG4gIGNvbnN0IHsgc2V0SXRlbSwgZ2V0SXRlbSB9ID0gdXNlTG9jYWxTdG9yYWdlKCk7XG4gIGNvbnN0IHsgdmFsdWUgfSA9IHVzZUxvY2FsU3RvcmFnZVZhbHVlKExvY2FsU3RvcmFnZUtleXMuRW52aXZlT25PdmVycmlkZSk7XG5cbiAgY29uc3Qgc2V0RmxhZyA9IHVzZUNhbGxiYWNrKFxuICAgIChmbGFnOiBib29sZWFuIHwgbnVsbCkgPT4ge1xuICAgICAgaWYgKGZsYWcgPT09IHRydWUpIHtcbiAgICAgICAgc2V0SXRlbShMb2NhbFN0b3JhZ2VLZXlzLkVudml2ZU9uT3ZlcnJpZGUsIFwidHJ1ZVwiKTtcbiAgICAgIH0gZWxzZSBpZiAoZmxhZyA9PT0gZmFsc2UpIHtcbiAgICAgICAgc2V0SXRlbShMb2NhbFN0b3JhZ2VLZXlzLkVudml2ZU9uT3ZlcnJpZGUsIFwiZmFsc2VcIik7XG4gICAgICB9XG4gICAgfSxcbiAgICBbc2V0SXRlbV1cbiAgKTtcblxuICByZXR1cm4ge1xuICAgIHZhbHVlOiB2YWx1ZSA9PT0gXCJ0cnVlXCIgPyB0cnVlIDogdmFsdWUgPT09IFwiZmFsc2VcIiA/IGZhbHNlIDogbnVsbCxcbiAgICBzZXRGbGFnLFxuICB9O1xufTtcblxuLy8gU3RvcmFnZSBsaXN0ZW5lciBob29rXG5leHBvcnQgY29uc3QgdXNlTG9jYWxTdG9yYWdlTGlzdGVuZXIgPSAoXG4gIGtleTogc3RyaW5nLFxuICBjYWxsYmFjazogKGV2ZW50OiBTdG9yYWdlRXZlbnQpID0+IHZvaWRcbikgPT4ge1xuICBjb25zdCB7IGF0dGFjaExpc3RlbmVyLCBkZXRhY2hMaXN0ZW5lciB9ID0gdXNlTG9jYWxTdG9yYWdlKCk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBjb25zdCBsaXN0ZW5lcjogTG9jYWxTdG9yYWdlRXZlbnRMaXN0ZW5lciA9IHtcbiAgICAgIHN0b3JhZ2VLZXk6IGtleSxcbiAgICAgIGxpc3RlbmVyOiBjYWxsYmFjayxcbiAgICB9O1xuICAgIGF0dGFjaExpc3RlbmVyKGxpc3RlbmVyKTtcbiAgICByZXR1cm4gKCkgPT4gZGV0YWNoTGlzdGVuZXIobGlzdGVuZXIpO1xuICB9LCBba2V5LCBjYWxsYmFjaywgYXR0YWNoTGlzdGVuZXIsIGRldGFjaExpc3RlbmVyXSk7XG59O1xuIiwiaW1wb3J0IHsgTWVzc2FnZSwgTWVzc2FnZVJvbGUsIE1lc3NhZ2VUeXBlIH0gZnJvbSAnc3JjL2FwcGxpY2F0aW9uL21vZGVscyc7XG5cbnR5cGUgTWVzc2FnZUZpbmRlciA9IHtcbiAgbXNnczogTWVzc2FnZVtdW107XG4gIHR5cGU/OiBNZXNzYWdlVHlwZTtcbiAgcm9sZT86IE1lc3NhZ2VSb2xlO1xufTtcblxuZXhwb3J0IGNvbnN0IHVzZU1lc3NhZ2VGaWx0ZXIgPSAoKSA9PiB7XG4gIGNvbnN0IGZpbmRNZXNzYWdlSW5kZXggPSAoeyBtc2dzLCB0eXBlLCByb2xlIH06IE1lc3NhZ2VGaW5kZXIpID0+IHtcbiAgICBsZXQgbGFzdEluZGV4ID0gLTE7XG4gICAgbXNncy5mb3JFYWNoKChzdWJBcnJheSwgaW5kZXgpID0+IHtcbiAgICAgIHN1YkFycmF5LmZvckVhY2goKG9iaikgPT4ge1xuICAgICAgICBpZiAob2JqLnR5cGUgPT09IHR5cGUgfHwgb2JqLnJvbGUgPT09IHJvbGUpIGxhc3RJbmRleCA9IGluZGV4O1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGxhc3RJbmRleDtcbiAgfTtcblxuICBjb25zdCByZW1vdmVQcmV2aW91c0Rpc2N1c3Npb25zID0gKG1zZ3M6IE1lc3NhZ2VbXVtdLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgIGNvbnN0IGxhc3RNZXNzYWdlcyA9IG1zZ3Muc2xpY2UoaW5kZXgpO1xuICAgICAgcmV0dXJuIGxhc3RNZXNzYWdlcy5sZW5ndGggPiAwID8gbGFzdE1lc3NhZ2VzIDogbXNncztcbiAgICB9XG4gICAgcmV0dXJuIG1zZ3M7XG4gIH07XG5cbiAgY29uc3QgZ2V0RmlsdGVyZWRNZXNzYWdlcyA9IChtc2dzOiBNZXNzYWdlW11bXSwgc2tpcEZpbHRlcj86IGJvb2xlYW4pID0+IHtcbiAgICBjb25zdCBtZXNzYWdlTWFwID0gbXNncy5yZWR1Y2UoXG4gICAgICAoYWNjLCBtc2cpID0+IHtcbiAgICAgICAgYWNjW21zZ1swXS5pZF0gPSBtc2c7XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9LFxuICAgICAge30gYXMgUmVjb3JkPHN0cmluZywgTWVzc2FnZVtdPixcbiAgICApO1xuICAgIGNvbnN0IGRlZHVwbGljYXRlZE1zZ3MgPSBPYmplY3QudmFsdWVzKG1lc3NhZ2VNYXApO1xuICAgIGlmICghc2tpcEZpbHRlcikge1xuICAgICAgY29uc3QgaWR4ID0gZmluZE1lc3NhZ2VJbmRleCh7IG1zZ3M6IGRlZHVwbGljYXRlZE1zZ3MsIHR5cGU6IE1lc3NhZ2VUeXBlLlNlcGFyYXRvciB9KTtcbiAgICAgIHJldHVybiByZW1vdmVQcmV2aW91c0Rpc2N1c3Npb25zKGRlZHVwbGljYXRlZE1zZ3MsIGlkeCk7XG4gICAgfVxuICAgIHJldHVybiBkZWR1cGxpY2F0ZWRNc2dzO1xuICB9O1xuXG4gIHJldHVybiB7XG4gICAgZmluZE1lc3NhZ2VJbmRleCxcbiAgICByZW1vdmVQcmV2aW91c0Rpc2N1c3Npb25zLFxuICAgIGdldEZpbHRlcmVkTWVzc2FnZXMsXG4gIH07XG59O1xuIiwiaW1wb3J0IHsgdXNlRWZmZWN0IH0gZnJvbSBcInJlYWN0XCI7XG5cbmV4cG9ydCBjb25zdCB1c2VNZXNzYWdlU2Nyb2xsT2JzZXJ2ZXIgPSAoXG4gICAgYm94UmVmOiBSZWFjdC5SZWZPYmplY3Q8SFRNTERpdkVsZW1lbnQ+LCBcbiAgICBzY3JvbGxSZWY6IFJlYWN0LlJlZk9iamVjdDxIVE1MRGl2RWxlbWVudD4sIFxuICAgIG9uU2Nyb2xsQ2hhbmdlOiAocG9zaXRpb246IG51bWJlcikgPT4gdm9pZFxuKSA9PiB7XG5cbiAgICBjb25zdCBjYWxjdWxhdGVTY3JvbGxIZWlnaHQgPSAoKSA9PiB7XG4gICAgICBjb25zdCBib3hIZWlnaHQgPSBib3hSZWY/LmN1cnJlbnQ/LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmhlaWdodCB8fCAwXG4gICAgICBjb25zdCBzY3JvbGxIZWlnaHQgPSBzY3JvbGxSZWY/LmN1cnJlbnQ/LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmhlaWdodCB8fCAwXG4gICAgICByZXR1cm4gYm94SGVpZ2h0IC0gc2Nyb2xsSGVpZ2h0XG4gICAgfVxuXG4gICAgY29uc3QgdXBkYXRlU3RhdGUgPSAoKSA9PiB7XG4gICAgICBjb25zdCBzY3JvbGxIZWlnaHQgPSBjYWxjdWxhdGVTY3JvbGxIZWlnaHQoKVxuICAgICAgaWYgKHNjcm9sbEhlaWdodCA+IDApIHtcbiAgICAgICAgb25TY3JvbGxDaGFuZ2Uoc2Nyb2xsSGVpZ2h0KVxuICAgICAgfVxuICAgIH1cblxuICAgIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgICBsZXQgYm94Uk8gPSBudWxsO1xuICAgICAgbGV0IHNjcm9sbFJPID0gbnVsbDtcblxuICAgICAgaWYgKHNjcm9sbFJlZj8uY3VycmVudCkge1xuICAgICAgICBib3hSTyA9IG5ldyBSZXNpemVPYnNlcnZlcih1cGRhdGVTdGF0ZSk7XG4gICAgICAgIGJveFJPLm9ic2VydmUoc2Nyb2xsUmVmPy5jdXJyZW50KTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgaWYgKGJveFJlZj8uY3VycmVudCkge1xuICAgICAgICBzY3JvbGxSTyA9IG5ldyBSZXNpemVPYnNlcnZlcih1cGRhdGVTdGF0ZSk7XG4gICAgICAgIHNjcm9sbFJPLm9ic2VydmUoYm94UmVmPy5jdXJyZW50KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgaWYgKHNjcm9sbFJlZj8uY3VycmVudCAmJiBib3hSTykge1xuICAgICAgICAgIGJveFJPLnVub2JzZXJ2ZShzY3JvbGxSZWY/LmN1cnJlbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNjcm9sbFJPICYmIGJveFJlZj8uY3VycmVudCkge1xuICAgICAgICAgIHNjcm9sbFJPPy51bm9ic2VydmUoYm94UmVmPy5jdXJyZW50KVxuICAgICAgICB9XG4gICAgICB9O1xuICAgIH0sIFtdKTtcblxufSIsImltcG9ydCBSZWFjdCwgeyBjcmVhdGVDb250ZXh0LCB1c2VDb250ZXh0LCB1c2VNZW1vLCBSZWFjdE5vZGUgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IE9yZ0NvbmZpZ0ZlYXR1cmVHYXRlIH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9tb2RlbHMvYXBpL29yZ0NvbmZpZ1Jlc3VsdHNcIjtcbmltcG9ydCB7IEZlYXR1cmVHYXRlcyB9IGZyb20gXCJzcmMvYXBwbGljYXRpb24vbW9kZWxzL2ZlYXR1cmVHYXRlc1wiO1xuaW1wb3J0IExvZ2dlciBmcm9tIFwic3JjL2FwcGxpY2F0aW9uL2xvZ2dpbmcvbG9nZ2VyXCI7XG5cbi8vIFRoaXMgaXMgdGhlIGNsYXNzIHRoYXQgd2FzIHByZXZpb3VzbHkgaW1wbGljaXRseSB1c2VkIG9yIGRlZmluZWQgZWxzZXdoZXJlXG5jbGFzcyBGZWF0dXJlRmxhZ1NlcnZpY2Uge1xuICBwcml2YXRlIGZlYXR1cmVHYXRlczogT3JnQ29uZmlnRmVhdHVyZUdhdGVbXTtcblxuICBjb25zdHJ1Y3RvcihmZWF0dXJlR2F0ZXM6IE9yZ0NvbmZpZ0ZlYXR1cmVHYXRlW10pIHtcbiAgICB0aGlzLmZlYXR1cmVHYXRlcyA9IGZlYXR1cmVHYXRlcztcbiAgfVxuXG4gIGlzRmVhdHVyZUdhdGVFbmFibGVkID0gKGZlYXR1cmVHYXRlOiBGZWF0dXJlR2F0ZXMpOiBib29sZWFuID0+IHtcbiAgICBjb25zdCBnYXRlVmFsdWUgPSB0aGlzLmZlYXR1cmVHYXRlcy5maW5kKFxuICAgICAgKGdhdGUpID0+IGdhdGUubmFtZSA9PT0gZmVhdHVyZUdhdGVcbiAgICApO1xuXG4gICAgLy8gVE9ETzogQWRkIGxvZ2ljIGZvciBvdmVycmlkZXMgKHF1ZXJ5IHBhcmFtcywgd2luZG93LCBzdG9yZWQpIGlmIG5lZWRlZCwgc2ltaWxhciB0byB0aGUgb2xkIEZlYXR1cmVGbGFnQ29udGV4dC50c3hcbiAgICAvLyBGb3Igbm93LCBkaXJlY3QgdmFsdWUgZnJvbSBjb25maWcgaXMgdXNlZC5cblxuICAgIGlmIChnYXRlVmFsdWUgPT0gbnVsbCB8fCBnYXRlVmFsdWUudmFsdWUgPT0gbnVsbCkge1xuICAgICAgTG9nZ2VyLmxvZ0RlYnVnKFxuICAgICAgICBgW3NwaWZmeS1haV0gaXNGZWF0dXJlR2F0ZUVuYWJsZWQgZmVhdHVyZUdhdGU6JHtmZWF0dXJlR2F0ZX0gdmFsdWUgaXMgdW5kZWZpbmVkIC0gcmV0dXJuaW5nIGZhbHNlYFxuICAgICAgKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIGdhdGVWYWx1ZS52YWx1ZTtcbiAgfTtcblxuICBpc0NsaWVudFNlc3Npb25FbmFibGVkID0gKCk6IGJvb2xlYW4gPT4ge1xuICAgIGNvbnN0IGlzRW5hYmxlZCA9XG4gICAgICB0aGlzLmZlYXR1cmVHYXRlcy5maWx0ZXIoXG4gICAgICAgIChnYXRlKSA9PlxuICAgICAgICAgIGdhdGUubmFtZSA9PT0gRmVhdHVyZUdhdGVzLklzQ2xpZW50U2Vzc2lvbkVuYWJsZWQgJiZcbiAgICAgICAgICBnYXRlLnZhbHVlID09PSB0cnVlXG4gICAgICApLmxlbmd0aCA+IDA7XG4gICAgcmV0dXJuIGlzRW5hYmxlZDtcbiAgfTtcblxuICBnZXRGZWF0dXJlRmxhZ3MgPSAoKTogUmVjb3JkPHN0cmluZywgYm9vbGVhbj4gPT4ge1xuICAgIHJldHVybiBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICBPYmplY3QudmFsdWVzKEZlYXR1cmVHYXRlcykubWFwKChmZWF0dXJlR2F0ZTogRmVhdHVyZUdhdGVzKSA9PiBbXG4gICAgICAgIGZlYXR1cmVHYXRlLFxuICAgICAgICB0aGlzLmlzRmVhdHVyZUdhdGVFbmFibGVkKGZlYXR1cmVHYXRlKSxcbiAgICAgIF0pXG4gICAgKTtcbiAgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBGZWF0dXJlRmxhZ0NvbnRleHRUeXBlIHtcbiAgZmVhdHVyZUZsYWdTZXJ2aWNlOiBGZWF0dXJlRmxhZ1NlcnZpY2UgfCB1bmRlZmluZWQ7XG59XG5cbmNvbnN0IEZlYXR1cmVGbGFnU2VydmljZUNvbnRleHQgPSBjcmVhdGVDb250ZXh0PFxuICBGZWF0dXJlRmxhZ0NvbnRleHRUeXBlIHwgdW5kZWZpbmVkXG4+KHVuZGVmaW5lZCk7XG5cbmludGVyZmFjZSBGZWF0dXJlRmxhZ1NlcnZpY2VQcm92aWRlclByb3BzIHtcbiAgZmVhdHVyZUdhdGVzOiBPcmdDb25maWdGZWF0dXJlR2F0ZVtdO1xuICBjaGlsZHJlbjogUmVhY3ROb2RlO1xufVxuXG5leHBvcnQgY29uc3QgRmVhdHVyZUZsYWdTZXJ2aWNlUHJvdmlkZXI6IFJlYWN0LkZDPFxuICBGZWF0dXJlRmxhZ1NlcnZpY2VQcm92aWRlclByb3BzXG4+ID0gKHsgZmVhdHVyZUdhdGVzLCBjaGlsZHJlbiB9KSA9PiB7XG4gIGNvbnN0IGZlYXR1cmVGbGFnU2VydmljZSA9IHVzZU1lbW8oXG4gICAgKCkgPT4gbmV3IEZlYXR1cmVGbGFnU2VydmljZShmZWF0dXJlR2F0ZXMpLFxuICAgIFtmZWF0dXJlR2F0ZXNdXG4gICk7XG5cbiAgcmV0dXJuIChcbiAgICA8RmVhdHVyZUZsYWdTZXJ2aWNlQ29udGV4dC5Qcm92aWRlciB2YWx1ZT17eyBmZWF0dXJlRmxhZ1NlcnZpY2UgfX0+XG4gICAgICB7Y2hpbGRyZW59XG4gICAgPC9GZWF0dXJlRmxhZ1NlcnZpY2VDb250ZXh0LlByb3ZpZGVyPlxuICApO1xufTtcblxuZXhwb3J0IGNvbnN0IHVzZUZlYXR1cmVGbGFnU2VydmljZSA9ICgpID0+IHtcbiAgY29uc3QgY29udGV4dCA9IHVzZUNvbnRleHQoRmVhdHVyZUZsYWdTZXJ2aWNlQ29udGV4dCk7XG4gIGlmIChjb250ZXh0ID09PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBcInVzZUZlYXR1cmVGbGFnU2VydmljZSBtdXN0IGJlIHVzZWQgd2l0aGluIGEgRmVhdHVyZUZsYWdTZXJ2aWNlUHJvdmlkZXJcIlxuICAgICk7XG4gIH1cbiAgcmV0dXJuIGNvbnRleHQ7XG59O1xuIiwiaW1wb3J0IFJlYWN0LCB7XG4gIGNyZWF0ZUNvbnRleHQsXG4gIHVzZUNvbnRleHQsXG4gIFJlYWN0Tm9kZSxcbiAgdXNlU3RhdGUsXG4gIHVzZUVmZmVjdCxcbiAgdXNlTWVtbyxcbn0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyB1c2VBdG9tVmFsdWUsIHVzZVNldEF0b20gfSBmcm9tIFwiam90YWlcIjtcbmltcG9ydCB7XG4gIEJhc2ljT3JnSW5mb1R5cGUsXG4gIGdldE9yZ0luZm8sXG59IGZyb20gXCJzcmMvYXBwbGljYXRpb24vbW9kZWxzL3N1cHBvcnRlZE9yZ3NcIjtcbmltcG9ydCB7IHVzZUNvbG9yc0FuZEZyb250ZW5kQ29uZmlnIH0gZnJvbSBcInNyYy9ob29rcy91c2VHcmFwaFFMQ29uZmlnXCI7XG5pbXBvcnQgeyBvcmdTaG9ydE5hbWVBdG9tIH0gZnJvbSBcInNyYy9hdG9tcy9lbnZpdmUvZW52aXZlQ29uZmlnXCI7XG5pbXBvcnQgeyBnZXRBdG9tU3RvcmUgfSBmcm9tIFwic3JjL2F0b21zL2F0b21TdG9yZS9hdG9tU3RvcmVcIjsgLy8gSW1wb3J0IGdldEF0b21TdG9yZVxuaW1wb3J0IHsgb3JnSWRBdG9tIH0gZnJvbSBcInNyYy9hdG9tcy9vcmcvZ3JhcGhxbENvbmZpZ1wiOyAvLyBJbXBvcnQgbmV3IGF0b21zXG5pbXBvcnQgeyBuZXdPcmdDb25maWdBdG9tIH0gZnJvbSBcInNyYy9hdG9tcy9vcmcvbmV3T3JnQ29uZmlnQXRvbVwiOyAvLyBJbXBvcnQgbmV3T3JnQ29uZmlnQXRvbVxuaW1wb3J0IHsgT3JnQ29uZmlnRmVhdHVyZUdhdGUgfSBmcm9tIFwic3JjL2FwcGxpY2F0aW9uL21vZGVscy9hcGkvb3JnQ29uZmlnUmVzdWx0c1wiOyAvLyBJbXBvcnQgT3JnQ29uZmlnRmVhdHVyZUdhdGVcbmltcG9ydCB7IEZlYXR1cmVGbGFnU2VydmljZVByb3ZpZGVyIH0gZnJvbSBcInNyYy9jb250ZXh0cy9mZWF0dXJlRmxhZ1NlcnZpY2VDb250ZXh0XCI7IC8vIEltcG9ydCBGZWF0dXJlRmxhZ1NlcnZpY2VQcm92aWRlclxuaW1wb3J0IHsgQ29sb3JzQ29uZmlnUmVzcG9uc2UsIEZyb250ZW5kQ29uZmlnUmVzcG9uc2UgfSBmcm9tIFwiLi9ncmFwaHFsQ29udGV4dFwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIE5ld09yZ0NvbmZpZ0NvbnRleHRUeXBlIHtcbiAgY29tYmluZWRDb25maWc/OlxuICAgIHwgKEJhc2ljT3JnSW5mb1R5cGUgJiB7XG4gICAgICAgIGNvbG9yc0NvbmZpZz86IENvbG9yc0NvbmZpZ1Jlc3BvbnNlO1xuICAgICAgICBmcm9udGVuZENvbmZpZz86IEZyb250ZW5kQ29uZmlnUmVzcG9uc2U7XG4gICAgICB9KVxuICAgIHwgbnVsbDtcbiAgbG9hZGluZzogYm9vbGVhbjtcbiAgZXJyb3I6IEVycm9yIHwgbnVsbDtcbn1cblxuY29uc3QgTmV3T3JnQ29uZmlnQ29udGV4dCA9IGNyZWF0ZUNvbnRleHQ8TmV3T3JnQ29uZmlnQ29udGV4dFR5cGUgfCB1bmRlZmluZWQ+KFxuICB1bmRlZmluZWRcbik7XG5cbmludGVyZmFjZSBOZXdPcmdDb25maWdQcm92aWRlclByb3BzIHtcbiAgY2hpbGRyZW46IFJlYWN0Tm9kZTtcbn1cblxuZXhwb3J0IGNvbnN0IE5ld09yZ0NvbmZpZ1Byb3ZpZGVyOiBSZWFjdC5GQzxOZXdPcmdDb25maWdQcm92aWRlclByb3BzPiA9ICh7XG4gIGNoaWxkcmVuLFxufSkgPT4ge1xuICBjb25zdCBbb2xkQ29uZmlnLCBzZXRPbGRDb25maWddID0gdXNlU3RhdGU8QmFzaWNPcmdJbmZvVHlwZSB8IHVuZGVmaW5lZD4oKTtcbiAgY29uc3Qgb3JnU2hvcnROYW1lID0gdXNlQXRvbVZhbHVlKG9yZ1Nob3J0TmFtZUF0b20pO1xuICBjb25zdCBzZXROZXdPcmdDb25maWcgPSB1c2VTZXRBdG9tKG5ld09yZ0NvbmZpZ0F0b20pO1xuXG4gIGNvbnN0IHsgZGF0YTogbmV3Q29uZmlnLCBsb2FkaW5nLCBlcnJvciB9ID0gdXNlQ29sb3JzQW5kRnJvbnRlbmRDb25maWcoKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChvcmdTaG9ydE5hbWUpIHtcbiAgICAgIGdldE9yZ0luZm8ob3JnU2hvcnROYW1lKS50aGVuKHNldE9sZENvbmZpZyk7XG4gICAgfVxuICB9LCBbb3JnU2hvcnROYW1lXSk7XG5cbiAgY29uc3QgY29tYmluZWRDb25maWcgPSB1c2VNZW1vKCgpID0+IHtcbiAgICBpZiAoIW9sZENvbmZpZyB8fCAhbmV3Q29uZmlnKSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4geyAuLi5vbGRDb25maWcsIC4uLm5ld0NvbmZpZyB9O1xuICB9LCBbb2xkQ29uZmlnLCBuZXdDb25maWddKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IGF0b21TdG9yZSA9IGdldEF0b21TdG9yZSgpO1xuICAgIGlmIChjb21iaW5lZENvbmZpZykge1xuICAgICAgLy8gVE9ETzogUmVwbGFjZSB3aXRoIGFjdHVhbCBvcmdJZCB3aGVuIGF2YWlsYWJsZSBpbiBjb21iaW5lZENvbmZpZ1xuICAgICAgYXRvbVN0b3JlLnNldChvcmdJZEF0b20sIFwibW9jay1vcmctaWRcIik7XG5cbiAgICAgIHNldE5ld09yZ0NvbmZpZyhjb21iaW5lZENvbmZpZyk7XG4gICAgfVxuICB9LCBbY29tYmluZWRDb25maWcsIHNldE5ld09yZ0NvbmZpZ10pO1xuXG4gIGNvbnN0IGNvbnRleHRWYWx1ZSA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIGlmICghb3JnU2hvcnROYW1lIHx8IChsb2FkaW5nICYmICFvbGRDb25maWcpKSB7XG4gICAgICByZXR1cm4geyBjb21iaW5lZENvbmZpZzogbnVsbCwgbG9hZGluZzogdHJ1ZSwgZXJyb3I6IG51bGwgfTtcbiAgICB9XG5cbiAgICBpZiAoZXJyb3IpIHtcbiAgICAgIHJldHVybiB7IGNvbWJpbmVkQ29uZmlnOiBudWxsLCBsb2FkaW5nOiBmYWxzZSwgZXJyb3IgfTtcbiAgICB9XG5cbiAgICByZXR1cm4geyBjb21iaW5lZENvbmZpZywgbG9hZGluZzogZmFsc2UsIGVycm9yOiBudWxsIH07XG4gIH0sIFtvcmdTaG9ydE5hbWUsIGxvYWRpbmcsIGVycm9yLCBvbGRDb25maWcsIGNvbWJpbmVkQ29uZmlnXSk7XG5cbiAgLy8gVE9ETzogUHJvdmlkZSBhY3R1YWwgZmVhdHVyZUdhdGVzIHdoZW4gYXZhaWxhYmxlIGluIGNvbWJpbmVkQ29uZmlnXG4gIGNvbnN0IGZlYXR1cmVHYXRlczogT3JnQ29uZmlnRmVhdHVyZUdhdGVbXSA9IFtdO1xuXG4gIHJldHVybiAoXG4gICAgPE5ld09yZ0NvbmZpZ0NvbnRleHQuUHJvdmlkZXIgdmFsdWU9e2NvbnRleHRWYWx1ZX0+XG4gICAgICA8RmVhdHVyZUZsYWdTZXJ2aWNlUHJvdmlkZXIgZmVhdHVyZUdhdGVzPXtmZWF0dXJlR2F0ZXN9PlxuICAgICAgICB7Y2hpbGRyZW59XG4gICAgICA8L0ZlYXR1cmVGbGFnU2VydmljZVByb3ZpZGVyPlxuICAgIDwvTmV3T3JnQ29uZmlnQ29udGV4dC5Qcm92aWRlcj5cbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCB1c2VOZXdPcmdDb25maWdDb250ZXh0ID0gKCkgPT4ge1xuICBjb25zdCBjb250ZXh0ID0gdXNlQ29udGV4dChOZXdPcmdDb25maWdDb250ZXh0KTtcbiAgaWYgKGNvbnRleHQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIFwidXNlTmV3T3JnQ29uZmlnQ29udGV4dCBtdXN0IGJlIHVzZWQgd2l0aGluIGEgTmV3T3JnQ29uZmlnUHJvdmlkZXJcIlxuICAgICk7XG4gIH1cbiAgcmV0dXJuIGNvbnRleHQ7XG59O1xuIiwiaW1wb3J0IHsgdXNlTmV3T3JnQ29uZmlnQ29udGV4dCB9IGZyb20gXCJzcmMvY29udGV4dHMvbmV3T3JnQ29uZmlnQ29udGV4dFwiO1xuXG5leHBvcnQgY29uc3QgdXNlTmV3T3JnQ29uZmlnID0gKCkgPT4ge1xuICBjb25zdCB7IGNvbWJpbmVkQ29uZmlnLCBsb2FkaW5nLCBlcnJvciB9ID0gdXNlTmV3T3JnQ29uZmlnQ29udGV4dCgpO1xuXG4gIHJldHVybiB7IC4uLmNvbWJpbmVkQ29uZmlnLCBsb2FkaW5nLCBlcnJvciB9O1xufTtcbiIsImltcG9ydCB7XG4gIFBMUEF0dHJpYnV0ZUNhdGVnb3J5LFxuICBVc2VyRXZlbnRDYXRlZ29yeSxcbn0gZnJvbSBcIkBzcGlmZnktYWkvY29tbWVyY2UtYXBpLWNsaWVudFwiO1xuaW1wb3J0IHsgU2VhcmNoUmVzdWx0IH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9tb2RlbHMvYXBpL3NlYXJjaFwiO1xuaW1wb3J0IHsgVXNlckV2ZW50LCBWYXJpYW50SW5mbyB9IGZyb20gXCJzcmMvYXBwbGljYXRpb24vbW9kZWxzXCI7XG5pbXBvcnQgeyB2NCBhcyB1dWlkIH0gZnJvbSBcInV1aWRcIjtcblxuZXhwb3J0IGNvbnN0IGlzRWxlbWVudFBhcnRpYWxseVZpc2libGUgPSAoZWw/OiBIVE1MRGl2RWxlbWVudCB8IG51bGwpID0+IHtcbiAgaWYgKCFlbCkgcmV0dXJuIGZhbHNlO1xuXG4gIGNvbnN0IHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgY29uc3Qgd2luZG93SGVpZ2h0ID1cbiAgICB3aW5kb3cuaW5uZXJIZWlnaHQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodDtcbiAgY29uc3Qgd2luZG93V2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGg7XG4gIGNvbnN0IHZlcnRpY2FsbHlWaXNpYmxlID1cbiAgICBNYXRoLnJvdW5kKHJlY3QudG9wKSA8IHdpbmRvd0hlaWdodCAmJiBNYXRoLnJvdW5kKHJlY3QuYm90dG9tKSA+IDA7XG4gIGNvbnN0IGhvcml6b250YWxseVZpc2libGUgPVxuICAgIE1hdGgucm91bmQocmVjdC5sZWZ0KSA8IHdpbmRvd1dpZHRoICYmIE1hdGgucm91bmQocmVjdC5yaWdodCkgPiAwO1xuICByZXR1cm4gdmVydGljYWxseVZpc2libGUgJiYgaG9yaXpvbnRhbGx5VmlzaWJsZTtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVBcHBMb2FkZWRFdmVudCA9ICgpOiBVc2VyRXZlbnQgPT4gKHtcbiAgZXZlbnRJZDogdXVpZCgpLFxuICBjcmVhdGVkQXQ6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgY2F0ZWdvcnk6IFVzZXJFdmVudENhdGVnb3J5LkFwcExvYWRlZCxcbn0pO1xuXG5leHBvcnQgY29uc3QgY3JlYXRlVmlzaXRVc2VyRXZlbnQgPSAoe1xuICB2YXJpYW50SW5mbyxcbn06IHtcbiAgdmFyaWFudEluZm86IFZhcmlhbnRJbmZvO1xufSk6IFVzZXJFdmVudCB8IHVuZGVmaW5lZCA9PiB7XG4gIC8vIHRoaXMgaXMgYSBwZHAgdmlzaXQgZXZlbnRcbiAgaWYgKHZhcmlhbnRJbmZvLnZhcmlhbnQgPT09IFwicGRwXCIgJiYgdmFyaWFudEluZm8ucHJvZHVjdElkICE9IG51bGwpIHtcbiAgICByZXR1cm4ge1xuICAgICAgZXZlbnRJZDogdXVpZCgpLFxuICAgICAgY3JlYXRlZEF0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICBjYXRlZ29yeTogVXNlckV2ZW50Q2F0ZWdvcnkuUGRwVmlzaXQsXG4gICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgIHByb2R1Y3RJZDogdmFyaWFudEluZm8ucHJvZHVjdElkLFxuICAgICAgICBwYXJlbnRQcm9kdWN0SWQ6IHZhcmlhbnRJbmZvLnBhcmVudFByb2R1Y3RJZCA/PyBcIlwiLFxuICAgICAgICB1cmw6IHZhcmlhbnRJbmZvLnVybCA/PyBcIlwiLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgLy8gdGhpcyBpcyBhIHBscCB2aXNpdCBldmVudFxuICBpZiAodmFyaWFudEluZm8udmFyaWFudCA9PT0gXCJwbHBcIiAmJiB2YXJpYW50SW5mby5wbHBJZCAhPSBudWxsKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGV2ZW50SWQ6IHV1aWQoKSxcbiAgICAgIGNyZWF0ZWRBdDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgY2F0ZWdvcnk6IFVzZXJFdmVudENhdGVnb3J5LlBscFZpc2l0LFxuICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICBjYXRlZ29yeTogUExQQXR0cmlidXRlQ2F0ZWdvcnkuSWQsXG4gICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICBpZDogdmFyaWFudEluZm8ucGxwSWQsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBpZiAodmFyaWFudEluZm8udmFyaWFudCA9PT0gXCJwYWdlX3Zpc2l0XCIpIHtcbiAgICByZXR1cm4ge1xuICAgICAgZXZlbnRJZDogdXVpZCgpLFxuICAgICAgY3JlYXRlZEF0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICBjYXRlZ29yeTogVXNlckV2ZW50Q2F0ZWdvcnkuUGFnZVZpc2l0LFxuICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICB1cmw6IHZhcmlhbnRJbmZvLnVybCxcbiAgICAgICAgcGFnZVZpc2l0Q2F0ZWdvcnk6IHZhcmlhbnRJbmZvLnBhZ2VWaXNpdENhdGVnb3J5LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59O1xuXG5jb25zdCBwYXJzZVRpbWUgPSAodGltZTogc3RyaW5nLCB0aW1lWm9uZTogc3RyaW5nKSA9PiB7XG4gIGNvbnN0IHRpbWVzID0gdGltZS5tYXRjaCgvXihbMC0xXT9cXGQpOihbMC01XVxcZCkoQU18UE0pJC9pKTtcbiAgY29uc3QgaG91cnMgPSB0aW1lcz8uWzFdO1xuICBjb25zdCBtaW51dGVzID0gdGltZXM/LlsyXTtcbiAgY29uc3QgcGVyaW9kID0gdGltZXM/LlszXTtcblxuICBpZiAoaG91cnMgJiYgbWludXRlcyAmJiBwZXJpb2QpIHtcbiAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoKTtcblxuICAgIC8vIEFkanVzdCBob3VycyBmb3IgQU0vUE1cbiAgICBsZXQgYWRqdXN0ZWRIb3VycyA9IDA7XG4gICAgaWYgKHBlcmlvZC50b1VwcGVyQ2FzZSgpID09PSBcIlBNXCIgJiYgaG91cnMgIT09IFwiMTJcIikge1xuICAgICAgYWRqdXN0ZWRIb3VycyA9IHBhcnNlSW50KGhvdXJzKSArIDEyO1xuICAgIH1cblxuICAgIGlmIChwZXJpb2QudG9VcHBlckNhc2UoKSA9PT0gXCJBTVwiICYmIGhvdXJzICE9PSBcIjEyXCIpIHtcbiAgICAgIGFkanVzdGVkSG91cnMgPSBwYXJzZUludChob3Vycyk7XG4gICAgfVxuXG4gICAgLy8gQ3JlYXRlIHRoZSBkYXRlIHN0cmluZyB3aXRoIHRpbWUgem9uZVxuICAgIGNvbnN0IGZvcm1hdHRlZERhdGUgPSBgJHtkYXRlLnRvSVNPU3RyaW5nKCkuc3BsaXQoXCJUXCIpWzBdfVQke1N0cmluZyhcbiAgICAgIGFkanVzdGVkSG91cnNcbiAgICApLnBhZFN0YXJ0KDIsIFwiMFwiKX06JHttaW51dGVzfTowMGA7XG4gICAgcmV0dXJuIG5ldyBEYXRlKGAke2Zvcm1hdHRlZERhdGV9JHt0aW1lWm9uZX1gKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGlzV2l0aGluQnVzaW5lc3NIb3VycyA9IChcbiAgc3RhcnRUaW1lOiBzdHJpbmcsXG4gIGVuZFRpbWU6IHN0cmluZyxcbiAgdGltZVpvbmU6IHN0cmluZ1xuKSA9PiB7XG4gIC8vIFBhcnNlIHN0YXJ0IGFuZCBlbmQgdGltZXNcbiAgY29uc3Qgc3RhcnQgPSBwYXJzZVRpbWUoc3RhcnRUaW1lLCB0aW1lWm9uZSk7XG4gIGxldCBlbmQgPSBwYXJzZVRpbWUoZW5kVGltZSwgdGltZVpvbmUpO1xuXG4gIGlmICghc3RhcnQgfHwgIWVuZCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGxldCBub3cgPSBuZXcgRGF0ZSgpO1xuXG4gIC8vIElmIHRoZSBlbmQgZGF0ZSBpcyBncmVhdGVyIHRoYW4gdGhlIHN0YXJ0IGRhdGUsIGFkZCBhIGRheSB0byBib3RoIG9mIHRoZW1cbiAgLy8gVGhpcyBoYW5kbGVzIGNvbmZpZ3VyYXRpb25zIHN1Y2ggYXMgc3RhcnRUaW1lID0gMTA6MDBQTSBhbmQgZW5kVGltZSA9IDc6MDBBTVxuICBpZiAoZW5kIDwgc3RhcnQpIHtcbiAgICBlbmQgPSBuZXcgRGF0ZShlbmQuZ2V0VGltZSgpICsgMjQgKiA2MCAqIDYwICogMTAwMCk7XG4gICAgbm93ID0gbmV3IERhdGUobm93LmdldFRpbWUoKSArIDI0ICogNjAgKiA2MCAqIDEwMDApO1xuICB9XG5cbiAgLy8gSWYgdGhlIGRhdGUgY29udmVyc2lvbiBzaGlmdHMgdGhlIGVuZCBkYXRlIHRvIHRoZSBuZXh0IGRheSwgY29uc2lkZXIgY29tcGFyaW5nIGl0IGFjcm9zcyBtaWRuaWdodFxuICBpZiAoZW5kLmdldFVUQ0RhdGUoKSA+IHN0YXJ0LmdldFVUQ0RhdGUoKSkge1xuICAgIGNvbnN0IGNyb3NzaW5nTWlkbmlnaHQgPSBuZXcgRGF0ZShub3cuZ2V0VGltZSgpICsgMjQgKiA2MCAqIDYwICogMTAwMCk7XG4gICAgcmV0dXJuIHN0YXJ0IDw9IG5vdyB8fCBjcm9zc2luZ01pZG5pZ2h0IDw9IGVuZDtcbiAgfVxuXG4gIC8vIENoZWNrIGlmIHRoZSBjdXJyZW50IHRpbWUgZmFsbHMgYmV0d2VlbiBzdGFydCBhbmQgZW5kXG4gIHJldHVybiBub3cgPj0gc3RhcnQgJiYgbm93IDw9IGVuZDtcbn07XG5cbmV4cG9ydCBlbnVtIFNlYXJjaFJlc3VsdHNTdGF0ZSB7XG4gIExvYWRpbmcsXG4gIFJlc3VsdHMsXG4gIE5vUmVzdWx0cyxcbn1cblxuZXhwb3J0IGNvbnN0IGdldFNlYXJjaFJlc3VsdHNTdGF0ZSA9IChcbiAgaXNMb2FkaW5nU2VhcmNoOiBib29sZWFuLFxuICBzZWFyY2hEYXRhOiBTZWFyY2hSZXN1bHQgfCBudWxsXG4pOiBTZWFyY2hSZXN1bHRzU3RhdGUgPT4ge1xuICBpZiAoaXNMb2FkaW5nU2VhcmNoKSB7XG4gICAgcmV0dXJuIFNlYXJjaFJlc3VsdHNTdGF0ZS5Mb2FkaW5nO1xuICB9XG4gIGlmIChzZWFyY2hEYXRhKSB7XG4gICAgcmV0dXJuIFNlYXJjaFJlc3VsdHNTdGF0ZS5SZXN1bHRzO1xuICB9XG4gIHJldHVybiBTZWFyY2hSZXN1bHRzU3RhdGUuTm9SZXN1bHRzO1xufTtcbiIsImltcG9ydCB7IHVzZUF0b20sIHVzZUF0b21WYWx1ZSwgdXNlU2V0QXRvbSB9IGZyb20gXCJqb3RhaVwiO1xuaW1wb3J0IHsgdXNlQ2FsbGJhY2ssIHVzZUVmZmVjdCwgdXNlTWVtbywgdXNlUmVmLCB1c2VTdGF0ZSB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgdXNlRGVib3VuY2UgfSBmcm9tIFwic3JjL2hvb2tzL3VzZURlYm91bmNlXCI7XG5pbXBvcnQgeyB1c2VOZXdPcmdDb25maWcsIHVzZVRyYWNrQ29tcG9uZW50VmlzaWJsZUV2ZW50IH0gZnJvbSBcInNyYy9ob29rc1wiO1xuaW1wb3J0IHtcbiAgYWRkU2VhcmNoRmlsdGVyQXRvbSxcbiAgY2xlYXJTZWFyY2hGaWx0ZXJzQXRvbSxcbiAgY3JlYXRlRmlsdGVyT3B0aW9uLFxuICBmaWx0ZXJlZFNlYXJjaFByb2R1Y3RzQXRvbSxcbiAgcGVyZm9ybVNlYXJjaEF0b20sXG4gIHJlbW92ZVNlYXJjaEZpbHRlckF0b20sXG4gIHNlYXJjaEF0b20sXG4gIHNlYXJjaEZpbHRlcnNBdG9tLFxuICBzZWFyY2hQYXJhbXNBdG9tLFxuICBzZWFyY2hQcm9kdWN0U29ydGluZ0F0b20sXG4gIHNlYXJjaFNlbGVjdGVkRmlsdGVyc0F0b20sXG4gIFNlbGVjdGVkRmlsdGVyT3B0aW9uLFxufSBmcm9tIFwic3JjL2F0b21zL3NlYXJjaFwiO1xuaW1wb3J0IHtcbiAgYXV0b2NvbXBsZXRlU3RhdGVBdG9tLFxuICBpc0ZpbHRlck9wZW5BdG9tLFxufSBmcm9tIFwic3JjL2F0b21zL2dsb2JhbFNlYXJjaC9nbG9iYWxTZWFyY2hcIjtcbmltcG9ydCB7IGZvcm1hdEZpbHRlckRpc3BsYXlOYW1lIH0gZnJvbSBcInNyYy9hdG9tcy9zZWFyY2gvdXRpbHNcIjtcbmltcG9ydCB7IFByb2R1Y3RTb3J0aW5nIH0gZnJvbSBcInNyYy9hdG9tcy9zZWFyY2gvdHlwZXNcIjtcbmltcG9ydCB7XG4gIFNwaWZmeU1ldHJpY3NFdmVudE5hbWUsXG4gIHVzZUFtcGxpdHVkZSxcbn0gZnJvbSBcInNyYy9jb250ZXh0cy9hbXBsaXR1ZGVDb250ZXh0XCI7XG5pbXBvcnQgeyBTcGlmZnlXaWRnZXRzIH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9tb2RlbHMvc3BpZmZ5V2lkZ2V0c1wiO1xuaW1wb3J0IHsgUHJvZHVjdENhcmRDb25maWcgfSBmcm9tIFwic3JjL2NvbnRleHRzL3R5cGVzXCI7XG5pbXBvcnQgTG9nZ2VyIGZyb20gXCJzcmMvYXBwbGljYXRpb24vbG9nZ2luZy9sb2dnZXJcIjtcbmltcG9ydCB7IFNlYXJjaFJlc3VsdCB9IGZyb20gXCJzcmMvYXBwbGljYXRpb24vbW9kZWxzL2FwaS9zZWFyY2hcIjtcbmltcG9ydCB7IFNlYXJjaFJlc3BvbnNlUHJvZHVjdCB9IGZyb20gXCJAc3BpZmZ5LWFpL2NvbW1lcmNlLWFwaS1jbGllbnRcIjtcbmltcG9ydCB7XG4gIFNlYXJjaEZpbHRlckRhdHVtLFxuICBTZWxlY3RGaWx0ZXJJdGVtLFxufSBmcm9tIFwic3JjL3R5cGVzL3NlYXJjaC1maWx0ZXItdHlwZXNcIjtcbmltcG9ydCB7IGdldFNlYXJjaFJlc3VsdHNTdGF0ZSwgU2VhcmNoUmVzdWx0c1N0YXRlIH0gZnJvbSBcIi4vdXRpbHNcIjtcbmltcG9ydCB7IG9yZ1Nob3J0TmFtZUF0b20gfSBmcm9tIFwic3JjL2F0b21zL2Vudml2ZS9lbnZpdmVDb25maWdcIjtcblxuZXhwb3J0IGludGVyZmFjZSBTZWFyY2hSZXN1bHRzSG9jUHJvcHMge1xuICAvLyBEYXRhXG4gIHNlYXJjaERhdGE6IFNlYXJjaFJlc3VsdCB8IG51bGw7XG4gIHNlYXJjaFJlc3BvbnNlSWQ6IHN0cmluZztcbiAgbWVyY2hhbnRTaG9ydE5hbWU6IHN0cmluZztcbiAgcHJvZHVjdENhcmRDb25maWc6IFByb2R1Y3RDYXJkQ29uZmlnO1xuICBwcm9kdWN0TGlzdDogU2VhcmNoUmVzcG9uc2VQcm9kdWN0W107XG4gIGF1dG9jb21wbGV0ZVJlc3VsdHM6IHN0cmluZ1tdO1xuICBzZWFyY2hGaWx0ZXJzOiBTZWFyY2hGaWx0ZXJEYXR1bVtdO1xuICBhdmFpbGFibGVEeW5hbWljRmlsdGVyczogeyBuYW1lOiBzdHJpbmc7IGRpc3BsYXlOYW1lOiBzdHJpbmcgfVtdO1xuICBzZWxlY3RlZEZpbHRlck9wdGlvbnM6IFNlbGVjdGVkRmlsdGVyT3B0aW9uW107XG5cbiAgLy8gU3RhdGVcbiAgc2VhcmNoVGV4dDogc3RyaW5nO1xuICBzZWFyY2hSZXN1bHRzU3RhdGU6IFNlYXJjaFJlc3VsdHNTdGF0ZTtcbiAgaXNMb2FkaW5nQXV0b2NvbXBsZXRlOiBib29sZWFuO1xuICBpc0xvYWRpbmdTZWFyY2g6IGJvb2xlYW47XG4gIGlzRmlsdGVyT3BlbjogYm9vbGVhbjtcbiAgaXNEaXJ0eTogYm9vbGVhbjtcbiAgZm9jdXNlZEluZGV4OiBudW1iZXI7XG4gIGZvY3VzZWRPcHRpb25JZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gIC8vIFVJXG4gIGZpbHRlckJ1dHRvblRleHQ6IHN0cmluZztcblxuICAvLyBFdmVudCBIYW5kbGVyc1xuICBvblNlYXJjaElucHV0Q2hhbmdlOiAodmFsdWU6IHN0cmluZykgPT4gdm9pZDtcbiAgb25TdWJtaXRTZWFyY2g6ICgpID0+IHZvaWQ7XG4gIG9uQXV0b2NvbXBsZXRlU2VsZWN0OiAoc3VnZ2VzdGlvbjogc3RyaW5nKSA9PiB2b2lkO1xuICBvbktleURvd246IChldmVudDogUmVhY3QuS2V5Ym9hcmRFdmVudDxIVE1MSW5wdXRFbGVtZW50PikgPT4gdm9pZDtcbiAgb25Ub2dnbGVEeW5hbWljRmlsdGVyOiAoe1xuICAgIGZpbHRlcixcbiAgICBkeW5hbWljRmlsdGVyRGlzcGxheU5hbWUsXG4gIH06IHtcbiAgICBmaWx0ZXI6IHN0cmluZztcbiAgICBkeW5hbWljRmlsdGVyRGlzcGxheU5hbWU6IHN0cmluZztcbiAgfSkgPT4gdm9pZDtcbiAgb25TZWxlY3RGaWx0ZXJJdGVtOiBTZWxlY3RGaWx0ZXJJdGVtO1xuICBvblJlbW92ZUZpbHRlcjogKGZpbHRlcjogU2VsZWN0ZWRGaWx0ZXJPcHRpb24pID0+IHZvaWQ7XG4gIG9uQ2xlYXJBbGxGaWx0ZXJzOiAoKSA9PiB2b2lkO1xuICBzZXRJc0ZpbHRlck9wZW46IChpc0ZpbHRlck9wZW46IGJvb2xlYW4pID0+IHZvaWQ7XG5cbiAgLy8gUmVmc1xuICBzZWFyY2hSZXN1bHRzUmVmOiBSZWFjdC5SZWZPYmplY3Q8SFRNTERpdkVsZW1lbnQ+O1xufVxuXG5leHBvcnQgY29uc3QgdXNlU2VhcmNoID0gKCk6IFNlYXJjaFJlc3VsdHNIb2NQcm9wcyA9PiB7XG4gIC8vIEF0b21zXG4gIGNvbnN0IGNvbmZpZyA9IHVzZU5ld09yZ0NvbmZpZygpO1xuICBjb25zdCBvcmdTaG9ydE5hbWUgPSB1c2VBdG9tVmFsdWUob3JnU2hvcnROYW1lQXRvbSk7XG4gIGNvbnN0IHsgZGF0YTogc2VhcmNoRGF0YSwgbG9hZGluZzogaXNMb2FkaW5nU2VhcmNoIH0gPVxuICAgIHVzZUF0b21WYWx1ZShzZWFyY2hBdG9tKTtcbiAgY29uc3QgcHJvZHVjdExpc3QgPSB1c2VBdG9tVmFsdWUoZmlsdGVyZWRTZWFyY2hQcm9kdWN0c0F0b20pO1xuICBjb25zdCBwZXJmb3JtU2VhcmNoID0gdXNlU2V0QXRvbShwZXJmb3JtU2VhcmNoQXRvbSk7XG4gIGNvbnN0IFtcbiAgICB7IHJlc3VsdHM6IGF1dG9jb21wbGV0ZVJlc3VsdHMsIGlzTG9hZGluZzogaXNMb2FkaW5nQXV0b2NvbXBsZXRlIH0sXG4gICAgc2V0QXV0b2NvbXBsZXRlU3RhdGUsXG4gIF0gPSB1c2VBdG9tKGF1dG9jb21wbGV0ZVN0YXRlQXRvbSk7XG4gIGNvbnN0IFt7IHF1ZXJ5IH1dID0gdXNlQXRvbShzZWFyY2hQYXJhbXNBdG9tKTtcbiAgY29uc3QgW2lzRmlsdGVyT3Blbiwgc2V0SXNGaWx0ZXJPcGVuXSA9IHVzZUF0b20oaXNGaWx0ZXJPcGVuQXRvbSk7XG4gIGNvbnN0IFtzZWxlY3RlZEZpbHRlck9wdGlvbnNdID0gdXNlQXRvbShzZWFyY2hTZWxlY3RlZEZpbHRlcnNBdG9tKTtcbiAgY29uc3QgYWRkRmlsdGVyID0gdXNlU2V0QXRvbShhZGRTZWFyY2hGaWx0ZXJBdG9tKTtcbiAgY29uc3QgcmVtb3ZlRmlsdGVyID0gdXNlU2V0QXRvbShyZW1vdmVTZWFyY2hGaWx0ZXJBdG9tKTtcbiAgY29uc3QgW3Byb2R1Y3RTb3J0aW5nLCBzZXRQcm9kdWN0U29ydGluZ10gPSB1c2VBdG9tKHNlYXJjaFByb2R1Y3RTb3J0aW5nQXRvbSk7XG4gIGNvbnN0IGNsZWFyRmlsdGVycyA9IHVzZVNldEF0b20oY2xlYXJTZWFyY2hGaWx0ZXJzQXRvbSk7XG4gIGNvbnN0IHNlYXJjaEZpbHRlcnMgPSB1c2VBdG9tVmFsdWUoc2VhcmNoRmlsdGVyc0F0b20pO1xuXG4gIC8vIFN0YXRlXG4gIGNvbnN0IFtpc0RpcnR5LCBzZXRJc0RpcnR5XSA9IHVzZVN0YXRlKHRydWUpO1xuICBjb25zdCBbZm9jdXNlZEluZGV4LCBzZXRGb2N1c2VkSW5kZXhdID0gdXNlU3RhdGUoLTEpO1xuICBjb25zdCBbZm9jdXNlZE9wdGlvbklkLCBzZXRGb2N1c2VkT3B0aW9uSWRdID0gdXNlU3RhdGU8c3RyaW5nIHwgdW5kZWZpbmVkPihcbiAgICB1bmRlZmluZWRcbiAgKTtcbiAgY29uc3QgW3NlYXJjaFRleHQsIHNldFNlYXJjaFRleHRdID0gdXNlU3RhdGUocXVlcnkgfHwgXCJcIik7XG5cbiAgLy8gUmVmc1xuICBjb25zdCBzZWFyY2hSZXN1bHRzUmVmID0gdXNlUmVmPEhUTUxEaXZFbGVtZW50PihudWxsKTtcblxuICAvLyBEZXJpdmVkIFN0YXRlXG4gIGNvbnN0IGRlYm91bmNlZFNlYXJjaFRleHQgPSB1c2VEZWJvdW5jZShzZWFyY2hUZXh0LCAyMDApO1xuICBjb25zdCBzZWFyY2hSZXN1bHRzU3RhdGUgPSBnZXRTZWFyY2hSZXN1bHRzU3RhdGUoaXNMb2FkaW5nU2VhcmNoLCBzZWFyY2hEYXRhKTtcblxuICBjb25zdCBkeW5hbWljRmlsdGVycyA9IHNlYXJjaERhdGE/LmZpbHRlcnMgfHwgW107XG5cbiAgLy8gUHJvdmlkZSBmYWxsYmFjayB2YWx1ZXMgd2hlbiBvcmdVSUNvbmZpZyBpcyBub3QgeWV0IGF2YWlsYWJsZVxuICBjb25zdCBzYWZlUHJvZHVjdENhcmRDb25maWcgPSBjb25maWc/LmZyb250ZW5kQ29uZmlnPy51aUNvbmZpZ3NcbiAgICA/LnByb2R1Y3RDYXJkQ29uZmlnIHx8IHtcbiAgICB2YXJpYW50OiBcIm1pbmltYWxcIixcbiAgICBob3ZlclZhcmlhbnQ6IFwibm9uZVwiLFxuICAgIGxheW91dFZhcmlhbnQ6IFwic3F1YXJlXCIsXG4gIH07XG4gIGNvbnN0IHNhZmVNZXJjaGFudFNob3J0TmFtZSA9IG9yZ1Nob3J0TmFtZSB8fCBcIlwiO1xuXG4gIGNvbnN0IGF2YWlsYWJsZUR5bmFtaWNGaWx0ZXJzID0gdXNlTWVtbygoKSA9PiB7XG4gICAgcmV0dXJuIGR5bmFtaWNGaWx0ZXJzXG4gICAgICAuZmlsdGVyKFxuICAgICAgICAoZHluYW1pY0ZpbHRlck5hbWUpID0+XG4gICAgICAgICAgIXNlbGVjdGVkRmlsdGVyT3B0aW9ucy5zb21lKFxuICAgICAgICAgICAgKG9wdGlvbikgPT4gb3B0aW9uLmlkID09PSBgZHluYW1pYzoke2R5bmFtaWNGaWx0ZXJOYW1lfWBcbiAgICAgICAgICApXG4gICAgICApXG4gICAgICAubWFwKChkeW5hbWljRmlsdGVyTmFtZSkgPT4gKHtcbiAgICAgICAgbmFtZTogZHluYW1pY0ZpbHRlck5hbWUsXG4gICAgICAgIGRpc3BsYXlOYW1lOiBmb3JtYXRGaWx0ZXJEaXNwbGF5TmFtZShkeW5hbWljRmlsdGVyTmFtZSksXG4gICAgICB9KSk7XG4gIH0sIFtkeW5hbWljRmlsdGVycywgc2VsZWN0ZWRGaWx0ZXJPcHRpb25zXSk7XG5cbiAgY29uc3QgZmlsdGVycyA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIGNvbnN0IHNvcnRPcHRpb25zID0gW1xuICAgICAge1xuICAgICAgICBmaWx0ZXJJdGVtSWQ6IFN0cmluZyhQcm9kdWN0U29ydGluZy5GRUFUVVJFRCksXG4gICAgICAgIGRpc3BsYXlOYW1lOiBcIlJlbGV2YW5jZVwiLFxuICAgICAgICBwcm9kdWN0Q291bnQ6IDAsXG4gICAgICAgIGlzU2VsZWN0ZWQ6IHByb2R1Y3RTb3J0aW5nID09PSBQcm9kdWN0U29ydGluZy5GRUFUVVJFRCxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGZpbHRlckl0ZW1JZDogU3RyaW5nKFByb2R1Y3RTb3J0aW5nLlBSSUNFX0FTQyksXG4gICAgICAgIGRpc3BsYXlOYW1lOiBcIlByaWNlOiBMb3cgdG8gSGlnaFwiLFxuICAgICAgICBwcm9kdWN0Q291bnQ6IDAsXG4gICAgICAgIGlzU2VsZWN0ZWQ6IHByb2R1Y3RTb3J0aW5nID09PSBQcm9kdWN0U29ydGluZy5QUklDRV9BU0MsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBmaWx0ZXJJdGVtSWQ6IFN0cmluZyhQcm9kdWN0U29ydGluZy5QUklDRV9ERVNDKSxcbiAgICAgICAgZGlzcGxheU5hbWU6IFwiUHJpY2U6IEhpZ2ggdG8gTG93XCIsXG4gICAgICAgIHByb2R1Y3RDb3VudDogMCxcbiAgICAgICAgaXNTZWxlY3RlZDogcHJvZHVjdFNvcnRpbmcgPT09IFByb2R1Y3RTb3J0aW5nLlBSSUNFX0RFU0MsXG4gICAgICB9LFxuICAgIF07XG5cbiAgICByZXR1cm4gW1xuICAgICAgeyBmaWx0ZXJJZDogXCJzb3J0XCIsIGRpc3BsYXlOYW1lOiBcIlNPUlRcIiwgaXRlbXM6IHNvcnRPcHRpb25zIH0sXG4gICAgICAuLi5zZWFyY2hGaWx0ZXJzLFxuICAgIF0gYXMgU2VhcmNoRmlsdGVyRGF0dW1bXTtcbiAgfSwgW3Byb2R1Y3RTb3J0aW5nLCBzZWFyY2hGaWx0ZXJzXSk7XG5cbiAgY29uc3QgZmlsdGVyQnV0dG9uVGV4dCA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIGNvbnN0IHNlbGVjdGVkQ291bnQgPSBmaWx0ZXJzLnJlZHVjZSgoYWNjOiBudW1iZXIsIGZpbHRlcikgPT4ge1xuICAgICAgaWYgKGZpbHRlci5maWx0ZXJJZCA9PT0gXCJzb3J0XCIpIHtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH1cbiAgICAgIHJldHVybiBhY2MgKyBmaWx0ZXIuaXRlbXMuZmlsdGVyKChpdGVtKSA9PiBpdGVtLmlzU2VsZWN0ZWQpLmxlbmd0aDtcbiAgICB9LCAwKTtcbiAgICBpZiAoc2VsZWN0ZWRDb3VudCA9PT0gMCkge1xuICAgICAgcmV0dXJuIFwiRmlsdGVyICYgU29ydFwiO1xuICAgIH1cbiAgICByZXR1cm4gYEZpbHRlciAmIFNvcnQgKCR7c2VsZWN0ZWRDb3VudH0pYDtcbiAgfSwgW2ZpbHRlcnNdKTtcblxuICAvLyBDYWxsYmFja3NcbiAgY29uc3QgeyB0cmFja0V2ZW50IH0gPSB1c2VBbXBsaXR1ZGUoKTtcblxuICBjb25zdCBoYW5kbGVUb2dnbGVEeW5hbWljRmlsdGVyID0gdXNlQ2FsbGJhY2soXG4gICAgKHtcbiAgICAgIGZpbHRlcixcbiAgICAgIGR5bmFtaWNGaWx0ZXJEaXNwbGF5TmFtZSxcbiAgICB9OiB7XG4gICAgICBmaWx0ZXI6IHN0cmluZztcbiAgICAgIGR5bmFtaWNGaWx0ZXJEaXNwbGF5TmFtZTogc3RyaW5nO1xuICAgIH0pID0+IHtcbiAgICAgIHRyYWNrRXZlbnQoe1xuICAgICAgICBldmVudE5hbWU6IFNwaWZmeU1ldHJpY3NFdmVudE5hbWUuU2VhcmNoRmlsdGVyQ2xpY2tlZCxcbiAgICAgICAgZXZlbnRQcm9wczoge1xuICAgICAgICAgIGZpbHRlclR5cGU6IFwiRHluYW1pY1wiLFxuICAgICAgICAgIGZpbHRlclZhbHVlOiBmaWx0ZXIsXG4gICAgICAgICAgcXVlcnlUZXh0OiBzZWFyY2hUZXh0LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBhZGRGaWx0ZXIoXG4gICAgICAgIGNyZWF0ZUZpbHRlck9wdGlvbihcImR5bmFtaWNcIiwgZmlsdGVyLCBkeW5hbWljRmlsdGVyRGlzcGxheU5hbWUpXG4gICAgICApO1xuICAgIH0sXG4gICAgW2FkZEZpbHRlciwgc2VhcmNoVGV4dCwgdHJhY2tFdmVudF1cbiAgKTtcblxuICBjb25zdCBoYW5kbGVSZW1vdmVGaWx0ZXIgPSB1c2VDYWxsYmFjayhcbiAgICAoZmlsdGVyOiBTZWxlY3RlZEZpbHRlck9wdGlvbikgPT4ge1xuICAgICAgcmVtb3ZlRmlsdGVyKGZpbHRlci5pZCk7XG4gICAgfSxcbiAgICBbcmVtb3ZlRmlsdGVyXVxuICApO1xuXG4gIGNvbnN0IGhhbmRsZVN1Ym1pdFNlYXJjaCA9IHVzZUNhbGxiYWNrKGFzeW5jICgpID0+IHtcbiAgICBpZiAoc2VhcmNoVGV4dC50cmltKCkpIHtcbiAgICAgIHRyYWNrRXZlbnQoe1xuICAgICAgICBldmVudE5hbWU6IFNwaWZmeU1ldHJpY3NFdmVudE5hbWUuU2VhcmNoUXVlcnlTdWJtaXR0ZWQsXG4gICAgICAgIGV2ZW50UHJvcHM6IHtcbiAgICAgICAgICBzZWFyY2hPcmlnaW46IFNwaWZmeVdpZGdldHMuU2VhcmNoUmVzdWx0cyxcbiAgICAgICAgICBxdWVyeVRleHQ6IHNlYXJjaFRleHQudHJpbSgpLFxuICAgICAgICB9LFxuICAgICAgICBhbHNvU2VuZFRvR29vZ2xlQW5hbHl0aWNzOiB0cnVlLFxuICAgICAgfSk7XG4gICAgICBjb25zdCB1cmwgPSBuZXcgVVJMKHdpbmRvdy5sb2NhdGlvbi5ocmVmKTtcbiAgICAgIHVybC5zZWFyY2hQYXJhbXMuc2V0KFwiZXNxXCIsIHNlYXJjaFRleHQudHJpbSgpKTtcbiAgICAgIHdpbmRvdy5oaXN0b3J5LnB1c2hTdGF0ZSh7fSwgXCJcIiwgdXJsKTtcbiAgICAgIHBlcmZvcm1TZWFyY2goeyBxdWVyeTogc2VhcmNoVGV4dC50cmltKCkgfSk7XG4gICAgfVxuICB9LCBbcGVyZm9ybVNlYXJjaCwgc2VhcmNoVGV4dCwgdHJhY2tFdmVudF0pO1xuXG4gIGNvbnN0IGhhbmRsZUF1dG9jb21wbGV0ZVNlbGVjdCA9IHVzZUNhbGxiYWNrKFxuICAgIChzdWdnZXN0aW9uOiBzdHJpbmcpID0+IHtcbiAgICAgIHNldFNlYXJjaFRleHQoc3VnZ2VzdGlvbik7XG4gICAgICBoYW5kbGVTdWJtaXRTZWFyY2goKTtcbiAgICB9LFxuICAgIFtoYW5kbGVTdWJtaXRTZWFyY2gsIHNldFNlYXJjaFRleHRdXG4gICk7XG5cbiAgY29uc3QgaGFuZGxlS2V5RG93biA9IHVzZUNhbGxiYWNrKFxuICAgIChldmVudDogUmVhY3QuS2V5Ym9hcmRFdmVudDxIVE1MSW5wdXRFbGVtZW50PikgPT4ge1xuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gXCJBcnJvd0Rvd25cIikge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBjb25zdCBuZXdJbmRleCA9IChmb2N1c2VkSW5kZXggKyAxKSAlIGF1dG9jb21wbGV0ZVJlc3VsdHMubGVuZ3RoO1xuICAgICAgICBzZXRGb2N1c2VkSW5kZXgobmV3SW5kZXgpO1xuICAgICAgICBzZXRGb2N1c2VkT3B0aW9uSWQoYG9wdGlvbi0ke25ld0luZGV4fWApO1xuICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IFwiQXJyb3dVcFwiKSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGNvbnN0IG5ld0luZGV4ID1cbiAgICAgICAgICAoZm9jdXNlZEluZGV4IC0gMSArIGF1dG9jb21wbGV0ZVJlc3VsdHMubGVuZ3RoKSAlXG4gICAgICAgICAgYXV0b2NvbXBsZXRlUmVzdWx0cy5sZW5ndGg7XG4gICAgICAgIHNldEZvY3VzZWRJbmRleChuZXdJbmRleCk7XG4gICAgICAgIHNldEZvY3VzZWRPcHRpb25JZChgb3B0aW9uLSR7bmV3SW5kZXh9YCk7XG4gICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gXCJFbnRlclwiKSB7XG4gICAgICAgIGlmIChmb2N1c2VkSW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICBoYW5kbGVTdWJtaXRTZWFyY2goKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIGNvbnN0IHN1Z2dlc3Rpb25UZXh0ID0gYXV0b2NvbXBsZXRlUmVzdWx0c1tmb2N1c2VkSW5kZXhdO1xuICAgICAgICAgIGhhbmRsZUF1dG9jb21wbGV0ZVNlbGVjdChzdWdnZXN0aW9uVGV4dCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSBcIkVzY2FwZVwiKSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHNldEZvY3VzZWRJbmRleCgtMSk7XG4gICAgICAgIHNldEZvY3VzZWRPcHRpb25JZCh1bmRlZmluZWQpO1xuICAgICAgfVxuICAgIH0sXG4gICAgW1xuICAgICAgYXV0b2NvbXBsZXRlUmVzdWx0cyxcbiAgICAgIGZvY3VzZWRJbmRleCxcbiAgICAgIGhhbmRsZUF1dG9jb21wbGV0ZVNlbGVjdCxcbiAgICAgIGhhbmRsZVN1Ym1pdFNlYXJjaCxcbiAgICBdXG4gICk7XG5cbiAgY29uc3QgaGFuZGxlU2VhcmNoSW5wdXRDaGFuZ2UgPSAobmV3VmFsdWU6IHN0cmluZykgPT4ge1xuICAgIGlmIChuZXdWYWx1ZS5sZW5ndGggPT09IDEpIHtcbiAgICAgIHRyYWNrRXZlbnQoe1xuICAgICAgICBldmVudE5hbWU6IFNwaWZmeU1ldHJpY3NFdmVudE5hbWUuU2VhcmNoSW5wdXRTdGFydGVkLFxuICAgICAgICBldmVudFByb3BzOiB7XG4gICAgICAgICAgc2VhcmNoT3JpZ2luOiBTcGlmZnlXaWRnZXRzLlNlYXJjaFJlc3VsdHMsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9XG4gICAgc2V0U2VhcmNoVGV4dChuZXdWYWx1ZSk7XG4gICAgc2V0SXNEaXJ0eSh0cnVlKTtcbiAgfTtcblxuICBjb25zdCBoYW5kbGVTZWxlY3RGaWx0ZXJJdGVtOiBTZWxlY3RGaWx0ZXJJdGVtID0gdXNlQ2FsbGJhY2soXG4gICAgKHtcbiAgICAgIGZpbHRlcklkLFxuICAgICAgZmlsdGVySXRlbUlkLFxuICAgICAgaXNTZWxlY3RlZCxcbiAgICAgIGRpc3BsYXlOYW1lLFxuICAgIH06IHtcbiAgICAgIGZpbHRlcklkOiBzdHJpbmc7XG4gICAgICBmaWx0ZXJJdGVtSWQ6IHN0cmluZztcbiAgICAgIGlzU2VsZWN0ZWQ6IGJvb2xlYW47XG4gICAgICBkaXNwbGF5TmFtZTogc3RyaW5nO1xuICAgIH0pID0+IHtcbiAgICAgIGlmIChmaWx0ZXJJZCA9PT0gXCJzb3J0XCIpIHtcbiAgICAgICAgY29uc3QgbmV3U29ydCA9IGZpbHRlckl0ZW1JZCBhcyBQcm9kdWN0U29ydGluZztcbiAgICAgICAgdHJhY2tFdmVudCh7XG4gICAgICAgICAgZXZlbnROYW1lOiBTcGlmZnlNZXRyaWNzRXZlbnROYW1lLlNlYXJjaFNvcnRDbGlja2VkLFxuICAgICAgICAgIGV2ZW50UHJvcHM6IHtcbiAgICAgICAgICAgIHNvcnRUeXBlOiBuZXdTb3J0LFxuICAgICAgICAgICAgcXVlcnlUZXh0OiBzZWFyY2hUZXh0LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICBzZXRQcm9kdWN0U29ydGluZyhuZXdTb3J0KTtcbiAgICAgIH0gZWxzZSBpZiAoIWlzU2VsZWN0ZWQpIHtcbiAgICAgICAgcmVtb3ZlRmlsdGVyKGAke2ZpbHRlcklkfToke2ZpbHRlckl0ZW1JZH1gKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRyYWNrRXZlbnQoe1xuICAgICAgICAgIGV2ZW50TmFtZTogU3BpZmZ5TWV0cmljc0V2ZW50TmFtZS5TZWFyY2hGaWx0ZXJDbGlja2VkLFxuICAgICAgICAgIGV2ZW50UHJvcHM6IHtcbiAgICAgICAgICAgIGZpbHRlclR5cGU6IFwiU3RhdGljXCIsXG4gICAgICAgICAgICBmaWx0ZXJDYXRlZ29yeTogZmlsdGVySWQsXG4gICAgICAgICAgICBmaWx0ZXJWYWx1ZTogZmlsdGVySXRlbUlkLFxuICAgICAgICAgICAgcXVlcnlUZXh0OiBzZWFyY2hUZXh0LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICBhZGRGaWx0ZXIoY3JlYXRlRmlsdGVyT3B0aW9uKGZpbHRlcklkLCBmaWx0ZXJJdGVtSWQsIGRpc3BsYXlOYW1lKSk7XG4gICAgICB9XG4gICAgfSxcbiAgICBbYWRkRmlsdGVyLCByZW1vdmVGaWx0ZXIsIHNldFByb2R1Y3RTb3J0aW5nLCBzZWFyY2hUZXh0LCB0cmFja0V2ZW50XVxuICApO1xuXG4gIGNvbnN0IGhhbmRsZUNsZWFyQWxsRmlsdGVycyA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBzZXRQcm9kdWN0U29ydGluZyhQcm9kdWN0U29ydGluZy5GRUFUVVJFRCk7XG4gICAgY2xlYXJGaWx0ZXJzKCk7XG4gIH0sIFtzZXRQcm9kdWN0U29ydGluZywgY2xlYXJGaWx0ZXJzXSk7XG5cbiAgLy8gU2lkZSBFZmZlY3RzXG4gIHVzZVRyYWNrQ29tcG9uZW50VmlzaWJsZUV2ZW50KFxuICAgIFNwaWZmeVdpZGdldHMuU2VhcmNoUmVzdWx0cyxcbiAgICBzZWFyY2hSZXN1bHRzUmVmLFxuICAgIHt9LFxuICAgIFNwaWZmeU1ldHJpY3NFdmVudE5hbWUuU2VhcmNoQ29tcG9uZW50VmlzaWJsZVxuICApO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKHByb2R1Y3RMaXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgIHRyYWNrRXZlbnQoe1xuICAgICAgICBldmVudE5hbWU6IFNwaWZmeU1ldHJpY3NFdmVudE5hbWUuU2VhcmNoUmVzdWx0c1ZpZXdlZCxcbiAgICAgICAgZXZlbnRQcm9wczoge1xuICAgICAgICAgIHF1ZXJ5VGV4dDogc2VhcmNoVGV4dCxcbiAgICAgICAgICByZXN1bHRzQ291bnQ6IHByb2R1Y3RMaXN0Lmxlbmd0aCxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfSwgW3Byb2R1Y3RMaXN0Lmxlbmd0aCwgc2VhcmNoVGV4dCwgdHJhY2tFdmVudF0pO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKHF1ZXJ5ICYmIHF1ZXJ5ICE9PSBzZWFyY2hUZXh0KSB7XG4gICAgICBzZXRTZWFyY2hUZXh0KHF1ZXJ5KTtcbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL2V4aGF1c3RpdmUtZGVwc1xuICB9LCBbcXVlcnldKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IGVzcSA9IG5ldyBVUkxTZWFyY2hQYXJhbXMod2luZG93LmxvY2F0aW9uLnNlYXJjaCkuZ2V0KFwiZXNxXCIpO1xuICAgIGlmIChlc3EpIHtcbiAgICAgIHNldFNlYXJjaFRleHQoZXNxKTtcbiAgICAgIHBlcmZvcm1TZWFyY2goeyBxdWVyeTogZXNxIH0pO1xuICAgIH1cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaG9va3MvZXhoYXVzdGl2ZS1kZXBzXG4gIH0sIFtwZXJmb3JtU2VhcmNoXSk7XG5cbiAgY29uc3QgZmV0Y2hBdXRvY29tcGxldGVTdWdnZXN0aW9ucyA9IChfcXVlcnk6IHN0cmluZykgPT4ge1xuICAgIC8vIFRPRE86IGltcGxlbWVudCBhdXRvY29tcGxldGUgc3VnZ2VzdGlvbnNcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKFtdKTtcbiAgfTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChmZXRjaEF1dG9jb21wbGV0ZVN1Z2dlc3Rpb25zID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWlzRGlydHkgfHwgZGVib3VuY2VkU2VhcmNoVGV4dC5sZW5ndGggPD0gMikge1xuICAgICAgc2V0QXV0b2NvbXBsZXRlU3RhdGUoeyByZXN1bHRzOiBbXSwgaXNMb2FkaW5nOiBmYWxzZSB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzZXRBdXRvY29tcGxldGVTdGF0ZSgocHJldikgPT4gKHsgLi4ucHJldiwgaXNMb2FkaW5nOiB0cnVlIH0pKTtcblxuICAgIGNvbnN0IGZldGNoRGF0YSA9IGFzeW5jICgpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBmZXRjaEF1dG9jb21wbGV0ZVN1Z2dlc3Rpb25zPy4oXG4gICAgICAgICAgZGVib3VuY2VkU2VhcmNoVGV4dFxuICAgICAgICApO1xuICAgICAgICBzZXRBdXRvY29tcGxldGVTdGF0ZSh7IHJlc3VsdHM6IHJlc3VsdHMgPz8gW10sIGlzTG9hZGluZzogZmFsc2UgfSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBMb2dnZXIubG9nRXJyb3IoXCJGYWlsZWQgdG8gZmV0Y2ggYXV0b2NvbXBsZXRlIHN1Z2dlc3Rpb25zOlwiLCBlcnJvcik7XG4gICAgICAgIHNldEF1dG9jb21wbGV0ZVN0YXRlKHsgcmVzdWx0czogW10sIGlzTG9hZGluZzogZmFsc2UgfSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGZldGNoRGF0YSgpO1xuICB9LCBbZGVib3VuY2VkU2VhcmNoVGV4dCwgaXNEaXJ0eSwgc2V0QXV0b2NvbXBsZXRlU3RhdGVdKTtcblxuICByZXR1cm4ge1xuICAgIHNlYXJjaERhdGEsXG4gICAgc2VhcmNoUmVzcG9uc2VJZDogc2VhcmNoRGF0YT8uc2VhcmNoUmVzcG9uc2VJZCA/PyBcIlwiLFxuICAgIG1lcmNoYW50U2hvcnROYW1lOiBzYWZlTWVyY2hhbnRTaG9ydE5hbWUsXG4gICAgcHJvZHVjdENhcmRDb25maWc6IHNhZmVQcm9kdWN0Q2FyZENvbmZpZyxcbiAgICBwcm9kdWN0TGlzdCxcbiAgICBhdXRvY29tcGxldGVSZXN1bHRzLFxuICAgIHNlYXJjaEZpbHRlcnM6IGZpbHRlcnMsXG4gICAgYXZhaWxhYmxlRHluYW1pY0ZpbHRlcnMsXG4gICAgc2VsZWN0ZWRGaWx0ZXJPcHRpb25zLFxuICAgIHNlYXJjaFRleHQsXG4gICAgc2VhcmNoUmVzdWx0c1N0YXRlLFxuICAgIGlzTG9hZGluZ0F1dG9jb21wbGV0ZSxcbiAgICBpc0xvYWRpbmdTZWFyY2gsXG4gICAgaXNGaWx0ZXJPcGVuLFxuICAgIGlzRGlydHksXG4gICAgZm9jdXNlZEluZGV4LFxuICAgIGZvY3VzZWRPcHRpb25JZCxcbiAgICBmaWx0ZXJCdXR0b25UZXh0LFxuICAgIG9uU2VhcmNoSW5wdXRDaGFuZ2U6IGhhbmRsZVNlYXJjaElucHV0Q2hhbmdlLFxuICAgIG9uU3VibWl0U2VhcmNoOiBoYW5kbGVTdWJtaXRTZWFyY2gsXG4gICAgb25BdXRvY29tcGxldGVTZWxlY3Q6IGhhbmRsZUF1dG9jb21wbGV0ZVNlbGVjdCxcbiAgICBvbktleURvd246IGhhbmRsZUtleURvd24sXG4gICAgb25Ub2dnbGVEeW5hbWljRmlsdGVyOiBoYW5kbGVUb2dnbGVEeW5hbWljRmlsdGVyLFxuICAgIG9uU2VsZWN0RmlsdGVySXRlbTogaGFuZGxlU2VsZWN0RmlsdGVySXRlbSxcbiAgICBvblJlbW92ZUZpbHRlcjogaGFuZGxlUmVtb3ZlRmlsdGVyLFxuICAgIG9uQ2xlYXJBbGxGaWx0ZXJzOiBoYW5kbGVDbGVhckFsbEZpbHRlcnMsXG4gICAgc2V0SXNGaWx0ZXJPcGVuLFxuICAgIHNlYXJjaFJlc3VsdHNSZWYsXG4gIH07XG59O1xuIiwiaW1wb3J0IHsgdXNlQXRvbVZhbHVlIH0gZnJvbSBcImpvdGFpXCI7XG5pbXBvcnQge1xuICBDb250ZXh0RW52RW51bSxcbiAgQ29udGV4dFNvdXJjZUVudW0sXG59IGZyb20gXCJAc3BpZmZ5LWFpL2NvbW1lcmNlLWFwaS1jbGllbnRcIjtcbmltcG9ydCB7IFZhcmlhbnRJbmZvIH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9tb2RlbHNcIjtcbmltcG9ydCB7IFVzZXJJZGVudGl0eUNvbnRleHRUeXBlIH0gZnJvbSBcInNyYy9jb250ZXh0cy91c2VySWRlbnRpdHlDb250ZXh0XCI7XG5pbXBvcnQgeyB2YXJpYW50SW5mb0F0b20gfSBmcm9tIFwic3JjL2F0b21zL2FwcC92YXJpYW50XCI7XG5pbXBvcnQge1xuICBjb250ZXh0U291cmNlQXRvbSxcbiAgZW52QXRvbSBhcyBlbnZpdmVFbnZBdG9tLFxuICBvcmdTaG9ydE5hbWVBdG9tIGFzIGVudml2ZU9yZ1Nob3J0TmFtZUF0b20sXG59IGZyb20gXCJzcmMvYXRvbXMvZW52aXZlL2Vudml2ZUNvbmZpZ1wiO1xuaW1wb3J0IHsgY2hhdElkQXRvbSwgdXNlcklkQXRvbSB9IGZyb20gXCJzcmMvYXRvbXMvYXBwL2luZGV4XCI7XG5pbXBvcnQgeyB1c2VOZXdPcmdDb25maWdDb250ZXh0IH0gZnJvbSBcInNyYy9jb250ZXh0cy9uZXdPcmdDb25maWdDb250ZXh0XCI7XG5pbXBvcnQgeyB1c2VPcmdJZCB9IGZyb20gXCJzcmMvaG9va3MvdXNlR3JhcGhRTENvbmZpZ1wiOyAvLyBJbXBvcnQgdXNlT3JnSWRcblxuZXhwb3J0IGludGVyZmFjZSBBcHBEZXRhaWxzIHtcbiAgb3JnSWQ6IHN0cmluZztcbiAgb3JnU2hvcnROYW1lOiBzdHJpbmc7XG4gIGNoYXRJZDogc3RyaW5nO1xuICB1c2VySWQ6IHN0cmluZztcbiAgc291cmNlOiBDb250ZXh0U291cmNlRW51bTtcbiAgZW52OiBDb250ZXh0RW52RW51bTtcbiAgdmFyaWFudEluZm86IFZhcmlhbnRJbmZvO1xufVxuXG5leHBvcnQgY29uc3QgdXNlQXBwRGV0YWlscyA9ICgpOiBBcHBEZXRhaWxzID0+IHtcbiAgY29uc3QgeyBvcmdJZDogZmV0Y2hlZE9yZ0lkIH0gPSB1c2VPcmdJZCgpOyAvLyBHZXQgb3JnSWQgZnJvbSB1c2VPcmdJZCBob29rXG4gIGNvbnN0IG9yZ0lkID0gZmV0Y2hlZE9yZ0lkID8/IFwiXCI7IC8vIFByb3ZpZGUgYSBkZWZhdWx0IGVtcHR5IHN0cmluZyBpZiB1bmRlZmluZWRcblxuICBjb25zdCBvcmdTaG9ydE5hbWUgPSB1c2VBdG9tVmFsdWUoZW52aXZlT3JnU2hvcnROYW1lQXRvbSkgPz8gXCJzcGlmZnktYWlcIjtcbiAgY29uc3QgY2hhdElkID0gdXNlQXRvbVZhbHVlKGNoYXRJZEF0b20pO1xuICBjb25zdCB1c2VySWQgPSB1c2VBdG9tVmFsdWUodXNlcklkQXRvbSk7XG4gIGNvbnN0IHNvdXJjZSA9IHVzZUF0b21WYWx1ZShjb250ZXh0U291cmNlQXRvbSkgPz8gQ29udGV4dFNvdXJjZUVudW0uQXBwO1xuICBjb25zdCBlbnYgPVxuICAgICh1c2VBdG9tVmFsdWUoZW52aXZlRW52QXRvbSkgYXMgQ29udGV4dEVudkVudW0pID8/IENvbnRleHRFbnZFbnVtLkRldjsgLy8gQ2FzdCB0byBDb250ZXh0RW52RW51bVxuICBjb25zdCB2YXJpYW50SW5mbyA9IHVzZUF0b21WYWx1ZSh2YXJpYW50SW5mb0F0b20pO1xuXG4gIHJldHVybiB7XG4gICAgb3JnSWQsXG4gICAgb3JnU2hvcnROYW1lLFxuICAgIGNoYXRJZCxcbiAgICB1c2VySWQsXG4gICAgc291cmNlLFxuICAgIGVudixcbiAgICB2YXJpYW50SW5mbyxcbiAgfTtcbn07XG4iLCJpbXBvcnQgUmVhY3QsIHtcbiAgY3JlYXRlQ29udGV4dCxcbiAgdXNlQ29udGV4dCxcbiAgdXNlQ2FsbGJhY2ssXG4gIHVzZU1lbW8sXG4gIHVzZUVmZmVjdCxcbn0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyB1c2VBdG9tVmFsdWUgfSBmcm9tIFwiam90YWlcIjtcbmltcG9ydCB7XG4gIENvbmZpZ3VyYXRpb24sXG4gIFJlc3BvbnNlQ2F0ZWdvcnksXG4gIFJlc3BvbnNlRXJyb3IsXG4gIFNlYXJjaEFwaSxcbn0gZnJvbSBcIkBzcGlmZnktYWkvY29tbWVyY2UtYXBpLWNsaWVudFwiO1xuaW1wb3J0IHsgYmFzZVVybEF0b20gfSBmcm9tIFwic3JjL2F0b21zL2Vudml2ZS9lbnZpdmVDb25maWdcIjtcbmltcG9ydCBMb2dnZXIgZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9sb2dnaW5nL2xvZ2dlclwiO1xuaW1wb3J0IHsgdXNlQXBwRGV0YWlscyB9IGZyb20gXCJzcmMvaG9va3MvdXNlQXBwRGV0YWlsc1wiO1xuaW1wb3J0IHsgdXNlRW52aXZlQ29uZmlnIH0gZnJvbSBcInNyYy9jb250ZXh0cy9lbnZpdmVDb25maWdDb250ZXh0XCI7XG5pbXBvcnQgeyBTZXNzaW9uUmVzdGFydFJlcXVpcmVkIH0gZnJvbSBcInNyYy90eXBlcy9leGNlcHRpb25zL3Nlc3Npb25FeGNlcHRpb25zXCI7XG5pbXBvcnQgeyBVbnN1cHBvcnRlZFByb2R1Y3RFeGNlcHRpb24gfSBmcm9tIFwic3JjL3R5cGVzL2V4Y2VwdGlvbnMvdW5zdXBwb3J0ZWRQcm9kdWN0RXhjZXB0aW9uc1wiO1xuaW1wb3J0IHsgU2VhcmNoUmVzdWx0LCBTZWFyY2hQYXJhbXMgfSBmcm9tIFwiLi4vYXBwbGljYXRpb24vbW9kZWxzL2FwaS9zZWFyY2hcIjtcbmltcG9ydCB7XG4gIHNldFNlYXJjaFNlcnZpY2VGdW5jdGlvbixcbiAgY2xlYXJTZWFyY2hTZXJ2aWNlRnVuY3Rpb24sXG59IGZyb20gXCIuLi9hdG9tcy9zZWFyY2gvc2VhcmNoU2VydmljZUFkYXB0ZXJcIjtcblxuY29uc3QgdHJhbnNmb3JtUHJvZHVjdFJlc3BvbnNlcyA9IChwcm9kdWN0czogU2VhcmNoUmVzdWx0W1wicHJvZHVjdHNcIl0pID0+XG4gIHByb2R1Y3RzLm1hcCgoZGF0YSkgPT4gKHtcbiAgICBpZDogZGF0YS5pZCxcbiAgICByZXNwb25zZUlkOiBkYXRhLnJlc3BvbnNlX2lkLFxuICAgIGNhdGVnb3J5OiBSZXNwb25zZUNhdGVnb3J5LlByb2R1Y3QsXG4gICAgZGVzY3JpcHRpb246IGRhdGEuZGVzY3JpcHRpb24sXG4gICAgaW1hZ2VVcmw6IGRhdGEuaW1hZ2VfdXJsLFxuICAgIGltYWdlVXJsczogZGF0YS5pbWFnZV91cmxzLFxuICAgIHRpdGxlOiBkYXRhLnRpdGxlLFxuICAgIHVybDogZGF0YS51cmwsXG4gICAgb3JpZ2luYWxQcmljZTogZGF0YS5vcmlnaW5hbF9wcmljZSxcbiAgICBzYWxlUHJpY2U6IGRhdGEuc2FsZV9wcmljZSxcbiAgICBhdmVyYWdlUmF0aW5nOiBkYXRhLmF2ZXJhZ2VfcmF0aW5nLFxuICAgIG51bWJlclJldmlld3M6IGRhdGEubnVtYmVyX3Jldmlld3MsXG4gICAgbWV0YWRhdGE6IGRhdGEubWV0YWRhdGEsXG4gICAgaXNGb3JHcmlkOiBkYXRhLmlzX2Zvcl9ncmlkLFxuICAgIGNvbG9yczogZGF0YS5jb2xvcnMsXG4gICAgc2l6ZXM6IGRhdGEuc2l6ZXMsXG4gICAgZmlsdGVyczogZGF0YS5maWx0ZXJzLFxuICB9KSk7XG5cbmFzeW5jIGZ1bmN0aW9uIGVycm9yUmVzcG9uc2VCb2R5KGVycm9yOiBSZXNwb25zZUVycm9yKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGF3YWl0IGVycm9yLnJlc3BvbnNlLmpzb24oKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHRocm93U2Vzc2lvblJlc3RhcnRSZXF1aXJlZElmKGVycm9yTXNnOiBzdHJpbmcsIGVycm9yOiB1bmtub3duKSB7XG4gIGlmICghKGVycm9yIGluc3RhbmNlb2YgUmVzcG9uc2VFcnJvcikpIHtcbiAgICBMb2dnZXIubG9nSW5mbyhlcnJvck1zZywgZXJyb3IpO1xuICAgIHRocm93IGVycm9yO1xuICB9XG5cbiAgY29uc3QgZXJyb3JSZXNwb25zZSA9IGF3YWl0IGVycm9yUmVzcG9uc2VCb2R5KGVycm9yKTtcbiAgaWYgKFxuICAgIGVycm9yUmVzcG9uc2U/Lm1lc3NhZ2U/LnRvTG93ZXJDYXNlKCkgPT09IFwidW5zdXBwb3J0ZWQgcHJvZHVjdFwiIHx8XG4gICAgZXJyb3JSZXNwb25zZT8uYXBwX2NvZGU/LnRvVXBwZXJDYXNlKCkgPT09IFwiUFJPRFVDVF9OT1RfRk9VTkRcIlxuICApIHtcbiAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRQcm9kdWN0RXhjZXB0aW9uKCk7XG4gIH0gZWxzZSBpZiAoXG4gICAgZXJyb3JSZXNwb25zZT8uYXBwX2NvZGU/LnRvVXBwZXJDYXNlKCkgPT09IFwiUkVTVEFSVF9TRVNTSU9OXCIgfHxcbiAgICBlcnJvclJlc3BvbnNlPy5zdWJfY29kZT8udG9VcHBlckNhc2UoKSA9PT0gXCJOT1RfRk9VTkRcIlxuICApIHtcbiAgICBMb2dnZXIubG9nSW5mbyhcbiAgICAgIFwiU2Vzc2lvbiBkb2VzIG5vdCBleGlzdC4gUmUtc3RhcnQgc2Vzc2lvblwiLFxuICAgICAgZXJyb3IsXG4gICAgICBlcnJvci5yZXNwb25zZSxcbiAgICAgIGVycm9yUmVzcG9uc2VcbiAgICApO1xuICAgIHRocm93IG5ldyBTZXNzaW9uUmVzdGFydFJlcXVpcmVkKCk7XG4gIH1cblxuICBMb2dnZXIubG9nSW5mbyhlcnJvck1zZywgZXJyb3IpO1xuICB0aHJvdyBlcnJvcjtcbn1cblxuaW50ZXJmYWNlIFNlYXJjaENvbnRleHRWYWx1ZSB7XG4gIHNlYXJjaFByb2R1Y3RzOiAocGFyYW1zOiBTZWFyY2hQYXJhbXMpID0+IFByb21pc2U8U2VhcmNoUmVzdWx0PjtcbiAgaXNSZWFkeTogYm9vbGVhbjtcbn1cblxuY29uc3QgU2VhcmNoQ29udGV4dCA9IGNyZWF0ZUNvbnRleHQ8U2VhcmNoQ29udGV4dFZhbHVlIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuXG5leHBvcnQgY29uc3QgU2VhcmNoUHJvdmlkZXI6IFJlYWN0LkZDPHsgY2hpbGRyZW46IFJlYWN0LlJlYWN0Tm9kZSB9PiA9ICh7XG4gIGNoaWxkcmVuLFxufSkgPT4ge1xuICBjb25zdCB7IG9yZ0xldmVsQXBpS2V5LCBwdWJsaWNLZXkgfSA9IHVzZUVudml2ZUNvbmZpZygpO1xuICBjb25zdCBhcGlLZXkgPSBvcmdMZXZlbEFwaUtleSB8fCBwdWJsaWNLZXk7IC8vIFJlcGxpY2F0ZSBhcGlLZXlBdG9tIGxvZ2ljXG4gIGNvbnN0IGFwcERldGFpbHMgPSB1c2VBcHBEZXRhaWxzKCk7XG4gIGNvbnN0IGJhc2VVcmwgPSB1c2VBdG9tVmFsdWUoYmFzZVVybEF0b20pO1xuXG4gIGNvbnN0IGlzUmVhZHkgPSBCb29sZWFuKGFwaUtleSAmJiBhcHBEZXRhaWxzICYmIGJhc2VVcmwpO1xuXG4gIGNvbnN0IHNlYXJjaEFwaSA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIGlmICghaXNSZWFkeSkgcmV0dXJuIG51bGw7XG5cbiAgICBjb25zdCBjb25maWc6IENvbmZpZ3VyYXRpb24gPSBuZXcgQ29uZmlndXJhdGlvbih7XG4gICAgICBhY2Nlc3NUb2tlbjogYXBpS2V5LFxuICAgICAgYmFzZVBhdGg6IGJhc2VVcmwsXG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgIFwiQ29udGVudC1UeXBlXCI6IFwiYXBwbGljYXRpb24vanNvblwiLFxuICAgICAgICBBY2NlcHQ6IFwiYXBwbGljYXRpb24vanNvblwiLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICByZXR1cm4gbmV3IFNlYXJjaEFwaShjb25maWcpO1xuICB9LCBbYXBpS2V5LCBiYXNlVXJsLCBpc1JlYWR5XSk7XG5cbiAgY29uc3Qgc2VhcmNoUHJvZHVjdHMgPSB1c2VDYWxsYmFjayhcbiAgICBhc3luYyAocGFyYW1zOiBTZWFyY2hQYXJhbXMpOiBQcm9taXNlPFNlYXJjaFJlc3VsdD4gPT4ge1xuICAgICAgaWYgKCFpc1JlYWR5IHx8ICFzZWFyY2hBcGkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU2VhcmNoU2VydmljZSBub3QgcmVhZHkgLSBtaXNzaW5nIGRlcGVuZGVuY2llc1wiKTtcbiAgICAgIH1cblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBzZWFyY2hBcGkudjFTZWFyY2hRdWVyeUdldCh7XG4gICAgICAgICAgcXVlcnk6IHBhcmFtcy5xdWVyeSxcbiAgICAgICAgICBsaW1pdDogcGFyYW1zLmxpbWl0LFxuICAgICAgICAgIG9yZ19pZDogYXBwRGV0YWlscy5vcmdJZCxcbiAgICAgICAgICB1c2VyX2lkOiBhcHBEZXRhaWxzLnVzZXJJZCxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHtcbiAgICAgICAgICBwcm9kdWN0cyxcbiAgICAgICAgICBmaWx0ZXJzLFxuICAgICAgICAgIHNlYXJjaF9yZXNwb25zZV9pZDogc2VhcmNoUmVzcG9uc2VJZCxcbiAgICAgICAgfSA9IHJlc3BvbnNlO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcHJvZHVjdHM6IHRyYW5zZm9ybVByb2R1Y3RSZXNwb25zZXMocHJvZHVjdHMpIHx8IFtdLFxuICAgICAgICAgIGZpbHRlcnM6IGZpbHRlcnMgfHwgW10sXG4gICAgICAgICAgdG90YWxQcm9kdWN0Q291bnQ6IHByb2R1Y3RzPy5sZW5ndGggfHwgMCxcbiAgICAgICAgICBzZWFyY2hSZXNwb25zZUlkOiBzZWFyY2hSZXNwb25zZUlkIHx8IFwiXCIsXG4gICAgICAgIH07XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBhd2FpdCB0aHJvd1Nlc3Npb25SZXN0YXJ0UmVxdWlyZWRJZihcIkZhaWxlZCB0byBzZWFyY2ggcHJvZHVjdHNcIiwgZXJyb3IpO1xuICAgICAgICAvLyBUaGlzIHBhcnQgd2lsbCBub3QgYmUgcmVhY2hlZCBpZiBhbiBleGNlcHRpb24gaXMgdGhyb3duLCBidXQgaXQncyByZXF1aXJlZCBmb3IgdHlwZSBzYWZldHlcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBwcm9kdWN0czogW10sXG4gICAgICAgICAgZmlsdGVyczogW10sXG4gICAgICAgICAgdG90YWxQcm9kdWN0Q291bnQ6IDAsXG4gICAgICAgICAgc2VhcmNoUmVzcG9uc2VJZDogXCJcIixcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9LFxuICAgIFtzZWFyY2hBcGksIGlzUmVhZHksIGFwcERldGFpbHNdXG4gICk7XG5cbiAgLy8gUmVnaXN0ZXIgdGhlIHNlYXJjaCBmdW5jdGlvbiB3aXRoIHRoZSBhZGFwdGVyIGZvciB1c2UgaW4gYXRvbXNcbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoaXNSZWFkeSkge1xuICAgICAgc2V0U2VhcmNoU2VydmljZUZ1bmN0aW9uKHNlYXJjaFByb2R1Y3RzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY2xlYXJTZWFyY2hTZXJ2aWNlRnVuY3Rpb24oKTtcbiAgICB9XG5cbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgY2xlYXJTZWFyY2hTZXJ2aWNlRnVuY3Rpb24oKTtcbiAgICB9O1xuICB9LCBbc2VhcmNoUHJvZHVjdHMsIGlzUmVhZHldKTtcblxuICBjb25zdCB2YWx1ZSA9IHVzZU1lbW8oXG4gICAgKCkgPT4gKHtcbiAgICAgIHNlYXJjaFByb2R1Y3RzLFxuICAgICAgaXNSZWFkeSxcbiAgICB9KSxcbiAgICBbc2VhcmNoUHJvZHVjdHMsIGlzUmVhZHldXG4gICk7XG5cbiAgcmV0dXJuIChcbiAgICA8U2VhcmNoQ29udGV4dC5Qcm92aWRlciB2YWx1ZT17dmFsdWV9PntjaGlsZHJlbn08L1NlYXJjaENvbnRleHQuUHJvdmlkZXI+XG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgdXNlU2VhcmNoU2VydmljZSA9ICgpID0+IHtcbiAgY29uc3QgY29udGV4dCA9IHVzZUNvbnRleHQoU2VhcmNoQ29udGV4dCk7XG4gIGlmICghY29udGV4dCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcInVzZVNlYXJjaFNlcnZpY2UgbXVzdCBiZSB1c2VkIHdpdGhpbiBhIFNlYXJjaFByb3ZpZGVyXCIpO1xuICB9XG4gIHJldHVybiBjb250ZXh0O1xufTtcbiIsImltcG9ydCB7IHVzZVN0YXRlLCB1c2VDYWxsYmFjaywgdXNlRWZmZWN0IH0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyB1c2VTZWFyY2hTZXJ2aWNlIH0gZnJvbSBcInNyYy9jb250ZXh0cy9zZWFyY2hDb250ZXh0XCI7XG5pbXBvcnQgeyBTZWFyY2hSZXN1bHQsIFNlYXJjaFBhcmFtcyB9IGZyb20gXCJzcmMvYXBwbGljYXRpb24vbW9kZWxzL2FwaS9zZWFyY2hcIjtcblxuZXhwb3J0IGNvbnN0IHVzZVByb2R1Y3RTZWFyY2ggPSAoKSA9PiB7XG4gIGNvbnN0IHsgc2VhcmNoUHJvZHVjdHMsIGlzUmVhZHkgfSA9IHVzZVNlYXJjaFNlcnZpY2UoKTtcbiAgY29uc3QgW2RhdGEsIHNldERhdGFdID0gdXNlU3RhdGU8U2VhcmNoUmVzdWx0IHwgdW5kZWZpbmVkPigpO1xuICBjb25zdCBbbG9hZGluZywgc2V0TG9hZGluZ10gPSB1c2VTdGF0ZShmYWxzZSk7XG4gIGNvbnN0IFtlcnJvciwgc2V0RXJyb3JdID0gdXNlU3RhdGU8RXJyb3IgfCBudWxsPihudWxsKTtcblxuICBjb25zdCBzZWFyY2ggPSB1c2VDYWxsYmFjayhcbiAgICBhc3luYyAocGFyYW1zOiBTZWFyY2hQYXJhbXMpID0+IHtcbiAgICAgIGlmICghaXNSZWFkeSkge1xuICAgICAgICBzZXRFcnJvcihuZXcgRXJyb3IoXCJTZWFyY2ggc2VydmljZSBub3QgcmVhZHkgLSBtaXNzaW5nIGRlcGVuZGVuY2llc1wiKSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgc2V0TG9hZGluZyh0cnVlKTtcbiAgICAgIHNldEVycm9yKG51bGwpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzZWFyY2hQcm9kdWN0cyhwYXJhbXMpO1xuICAgICAgICBzZXREYXRhKHJlc3VsdCk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgc2V0RXJyb3IoXG4gICAgICAgICAgZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIgOiBuZXcgRXJyb3IoXCJVbmtub3duIHNlYXJjaCBlcnJvclwiKVxuICAgICAgICApO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgc2V0TG9hZGluZyhmYWxzZSk7XG4gICAgICB9XG4gICAgfSxcbiAgICBbc2VhcmNoUHJvZHVjdHMsIGlzUmVhZHldXG4gICk7XG5cbiAgY29uc3QgcmVzZXQgPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgc2V0RGF0YSh1bmRlZmluZWQpO1xuICAgIHNldEVycm9yKG51bGwpO1xuICAgIHNldExvYWRpbmcoZmFsc2UpO1xuICB9LCBbXSk7XG5cbiAgcmV0dXJuIHtcbiAgICBkYXRhLFxuICAgIGxvYWRpbmcsXG4gICAgZXJyb3IsXG4gICAgc2VhcmNoLFxuICAgIHJlc2V0LFxuICAgIGlzUmVhZHksXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgdXNlU2VhcmNoV2l0aFF1ZXJ5ID0gKHBhcmFtczogU2VhcmNoUGFyYW1zIHwgbnVsbCkgPT4ge1xuICBjb25zdCB7IHNlYXJjaFByb2R1Y3RzLCBpc1JlYWR5IH0gPSB1c2VTZWFyY2hTZXJ2aWNlKCk7XG4gIGNvbnN0IFtkYXRhLCBzZXREYXRhXSA9IHVzZVN0YXRlPFNlYXJjaFJlc3VsdCB8IHVuZGVmaW5lZD4oKTtcbiAgY29uc3QgW2xvYWRpbmcsIHNldExvYWRpbmddID0gdXNlU3RhdGUoZmFsc2UpO1xuICBjb25zdCBbZXJyb3IsIHNldEVycm9yXSA9IHVzZVN0YXRlPEVycm9yIHwgbnVsbD4obnVsbCk7XG5cbiAgY29uc3QgZXhlY3V0ZVNlYXJjaCA9IHVzZUNhbGxiYWNrKFxuICAgIGFzeW5jIChzZWFyY2hQYXJhbXM6IFNlYXJjaFBhcmFtcykgPT4ge1xuICAgICAgaWYgKCFpc1JlYWR5KSByZXR1cm47XG5cbiAgICAgIHNldExvYWRpbmcodHJ1ZSk7XG4gICAgICBzZXRFcnJvcihudWxsKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc2VhcmNoUHJvZHVjdHMoc2VhcmNoUGFyYW1zKTtcbiAgICAgICAgc2V0RGF0YShyZXN1bHQpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHNldEVycm9yKFxuICAgICAgICAgIGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyIDogbmV3IEVycm9yKFwiVW5rbm93biBzZWFyY2ggZXJyb3JcIilcbiAgICAgICAgKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHNldExvYWRpbmcoZmFsc2UpO1xuICAgICAgfVxuICAgIH0sXG4gICAgW3NlYXJjaFByb2R1Y3RzLCBpc1JlYWR5XVxuICApO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKHBhcmFtcyAmJiBpc1JlYWR5KSB7XG4gICAgICBleGVjdXRlU2VhcmNoKHBhcmFtcyk7XG4gICAgfVxuICB9LCBbcGFyYW1zLCBpc1JlYWR5LCBleGVjdXRlU2VhcmNoXSk7XG5cbiAgY29uc3QgcmVmZXRjaCA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBpZiAocGFyYW1zKSB7XG4gICAgICBleGVjdXRlU2VhcmNoKHBhcmFtcyk7XG4gICAgfVxuICB9LCBbcGFyYW1zLCBleGVjdXRlU2VhcmNoXSk7XG5cbiAgcmV0dXJuIHtcbiAgICBkYXRhLFxuICAgIGxvYWRpbmcsXG4gICAgZXJyb3IsXG4gICAgcmVmZXRjaCxcbiAgICBpc1JlYWR5LFxuICB9O1xufTtcbiIsImltcG9ydCBSZWFjdCwge1xuICBjcmVhdGVDb250ZXh0LFxuICB1c2VDb250ZXh0LFxuICB1c2VDYWxsYmFjayxcbiAgdXNlTWVtbyxcbiAgdXNlRWZmZWN0LFxufSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCBMb2dnZXIgZnJvbSBcIi4uL2FwcGxpY2F0aW9uL2xvZ2dpbmcvbG9nZ2VyXCI7XG5cbmludGVyZmFjZSBTZXNzaW9uU3RvcmFnZUNvbnRleHRUeXBlIHtcbiAgc2V0SXRlbTogKGtleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nKSA9PiB2b2lkO1xuICBnZXRJdGVtOiAoa2V5OiBzdHJpbmcpID0+IHN0cmluZyB8IG51bGw7XG4gIGlzQXZhaWxhYmxlOiBib29sZWFuO1xufVxuXG5jb25zdCBTZXNzaW9uU3RvcmFnZUNvbnRleHQgPSBjcmVhdGVDb250ZXh0PFNlc3Npb25TdG9yYWdlQ29udGV4dFR5cGUgfCBudWxsPihcbiAgbnVsbFxuKTtcblxuZXhwb3J0IGNvbnN0IFNlc3Npb25TdG9yYWdlUHJvdmlkZXI6IFJlYWN0LkZDPHtcbiAgY2hpbGRyZW46IFJlYWN0LlJlYWN0Tm9kZTtcbn0+ID0gKHsgY2hpbGRyZW4gfSkgPT4ge1xuICBjb25zdCBpc0F2YWlsYWJsZSA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJiAhIXdpbmRvdy5zZXNzaW9uU3RvcmFnZTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH0sIFtdKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghaXNBdmFpbGFibGUpIHtcbiAgICAgIExvZ2dlci5sb2dFcnJvcihcInNlc3Npb25TdG9yYWdlIGlzIG5vdCBhdmFpbGFibGVcIiwgdW5kZWZpbmVkKTtcbiAgICB9XG4gIH0sIFtpc0F2YWlsYWJsZV0pO1xuXG4gIGNvbnN0IHNldEl0ZW0gPSB1c2VDYWxsYmFjayhcbiAgICAoa2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpID0+IHtcbiAgICAgIGlmICghaXNBdmFpbGFibGUpIHJldHVybjtcbiAgICAgIHNlc3Npb25TdG9yYWdlLnNldEl0ZW0oa2V5LCB2YWx1ZSk7XG4gICAgICB3aW5kb3cuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgbmV3IFN0b3JhZ2VFdmVudChcInN0b3JhZ2VcIiwgeyBrZXksIG5ld1ZhbHVlOiB2YWx1ZSB9KVxuICAgICAgKTtcbiAgICB9LFxuICAgIFtpc0F2YWlsYWJsZV1cbiAgKTtcblxuICBjb25zdCBnZXRJdGVtID0gdXNlQ2FsbGJhY2soXG4gICAgKGtleTogc3RyaW5nKSA9PiB7XG4gICAgICBpZiAoIWlzQXZhaWxhYmxlKSByZXR1cm4gbnVsbDtcbiAgICAgIHJldHVybiBzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKGtleSk7XG4gICAgfSxcbiAgICBbaXNBdmFpbGFibGVdXG4gICk7XG5cbiAgY29uc3QgdmFsdWUgPSB1c2VNZW1vKFxuICAgICgpID0+ICh7XG4gICAgICBzZXRJdGVtLFxuICAgICAgZ2V0SXRlbSxcbiAgICAgIGlzQXZhaWxhYmxlLFxuICAgIH0pLFxuICAgIFtzZXRJdGVtLCBnZXRJdGVtLCBpc0F2YWlsYWJsZV1cbiAgKTtcblxuICByZXR1cm4gKFxuICAgIDxTZXNzaW9uU3RvcmFnZUNvbnRleHQuUHJvdmlkZXIgdmFsdWU9e3ZhbHVlfT5cbiAgICAgIHtjaGlsZHJlbn1cbiAgICA8L1Nlc3Npb25TdG9yYWdlQ29udGV4dC5Qcm92aWRlcj5cbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCB1c2VTZXNzaW9uU3RvcmFnZSA9ICgpID0+IHtcbiAgY29uc3QgY29udGV4dCA9IHVzZUNvbnRleHQoU2Vzc2lvblN0b3JhZ2VDb250ZXh0KTtcbiAgaWYgKCFjb250ZXh0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgXCJ1c2VTZXNzaW9uU3RvcmFnZSBtdXN0IGJlIHVzZWQgd2l0aGluIGEgU2Vzc2lvblN0b3JhZ2VQcm92aWRlclwiXG4gICAgKTtcbiAgfVxuICByZXR1cm4gY29udGV4dDtcbn07XG4iLCJpbXBvcnQgeyB1c2VTdGF0ZSwgdXNlRWZmZWN0LCB1c2VDYWxsYmFjayB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgdXNlU2Vzc2lvblN0b3JhZ2UgfSBmcm9tIFwiLi4vY29udGV4dHMvc2Vzc2lvblN0b3JhZ2VDb250ZXh0XCI7XG5cbmV4cG9ydCBjb25zdCB1c2VTZXNzaW9uU3RvcmFnZVZhbHVlID0gKGtleTogc3RyaW5nKSA9PiB7XG4gIGNvbnN0IHsgZ2V0SXRlbSwgc2V0SXRlbSB9ID0gdXNlU2Vzc2lvblN0b3JhZ2UoKTtcbiAgY29uc3QgW3ZhbHVlLCBzZXRWYWx1ZV0gPSB1c2VTdGF0ZTxzdHJpbmcgfCBudWxsPigoKSA9PiBnZXRJdGVtKGtleSkpO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3QgaGFuZGxlU3RvcmFnZUNoYW5nZSA9IChldmVudDogU3RvcmFnZUV2ZW50KSA9PiB7XG4gICAgICBpZiAoZXZlbnQua2V5ID09PSBrZXkpIHtcbiAgICAgICAgc2V0VmFsdWUoZXZlbnQubmV3VmFsdWUpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInN0b3JhZ2VcIiwgaGFuZGxlU3RvcmFnZUNoYW5nZSk7XG4gICAgcmV0dXJuICgpID0+IHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwic3RvcmFnZVwiLCBoYW5kbGVTdG9yYWdlQ2hhbmdlKTtcbiAgfSwgW2tleSwgZ2V0SXRlbV0pO1xuXG4gIGNvbnN0IHVwZGF0ZVZhbHVlID0gdXNlQ2FsbGJhY2soXG4gICAgKG5ld1ZhbHVlOiBzdHJpbmcpID0+IHtcbiAgICAgIHNldEl0ZW0oa2V5LCBuZXdWYWx1ZSk7XG4gICAgICBzZXRWYWx1ZShuZXdWYWx1ZSk7XG4gICAgfSxcbiAgICBba2V5LCBzZXRJdGVtXVxuICApO1xuXG4gIHJldHVybiB7IHZhbHVlLCBzZXRWYWx1ZTogdXBkYXRlVmFsdWUgfTtcbn07XG4iLCJpbXBvcnQgUmVhY3QsIHsgY3JlYXRlQ29udGV4dCwgdXNlQ2FsbGJhY2ssIHVzZUNvbnRleHQsIHVzZU1lbW8gfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IElkRXh0cmFjdG9yIH0gZnJvbSBcInNyYy9jb250ZXh0cy90eXBlc1wiO1xuaW1wb3J0IHsgcGFyc2VIcmVmIH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi91dGlscy91cmxzUGFyc2VyXCI7XG5cbmludGVyZmFjZSBTaG9waWZ5VXJsQ29udGV4dFR5cGUge1xuICBnZXRUcmltbWVkUGF0aE5hbWU6ICgpID0+IHN0cmluZyB8IG51bGw7XG4gIGdldFBscE9yUGRwSWQ6IChleHRyYWN0b3I6IElkRXh0cmFjdG9yKSA9PiBzdHJpbmcgfCBudWxsO1xuICBpc09uUGRwUGFnZTogKCkgPT4gYm9vbGVhbjtcbiAgaXNPblBscFBhZ2U6ICgpID0+IGJvb2xlYW47XG4gIGlzUmVhZHk6IGJvb2xlYW47XG59XG5cbmNvbnN0IFNob3BpZnlVcmxDb250ZXh0ID0gY3JlYXRlQ29udGV4dDxTaG9waWZ5VXJsQ29udGV4dFR5cGUgfCB1bmRlZmluZWQ+KFxuICB1bmRlZmluZWRcbik7XG5cbmV4cG9ydCBjb25zdCBTaG9waWZ5VXJsUHJvdmlkZXI6IFJlYWN0LkZDPHsgY2hpbGRyZW46IFJlYWN0LlJlYWN0Tm9kZSB9PiA9ICh7XG4gIGNoaWxkcmVuLFxufSkgPT4ge1xuICBjb25zdCBpc1JlYWR5ID0gdHJ1ZTsgLy8gTm8gZXh0ZXJuYWwgZGVwZW5kZW5jaWVzLCBzbyBhbHdheXMgcmVhZHlcblxuICBjb25zdCBnZXRUcmltbWVkUGF0aE5hbWUgPSB1c2VDYWxsYmFjaygoKTogc3RyaW5nIHwgbnVsbCA9PiB7XG4gICAgbGV0IHsgcGF0aG5hbWUgfSA9IHdpbmRvdy5sb2NhdGlvbjtcbiAgICAvLyBzdHJpcCBvdXQgdGhlIHByb3h5IHBhdGggc28gbG9jYWwgZGV2IHN0aWxsIHdvcmtzXG4gICAgcGF0aG5hbWUgPSBwYXRobmFtZS5yZXBsYWNlKFwiL3Byb3h5XCIsIFwiXCIpO1xuICAgIC8vIHJlbW92ZSB0cmFpbGluZyBoYXNoIGlmIGl0IGV4aXN0c1xuICAgIHBhdGhuYW1lID0gcGF0aG5hbWUucmVwbGFjZSgvIy4qJC8sIFwiXCIpO1xuICAgIC8vIHJlbW92ZSB0cmFpbGluZyAvLCBpZS4gc29tZSBVUkxzIGNhbiBlbmQgd2l0aCAnLycgbGlrZSAvY29sbGVjdGlvbnMvY2FzdC1pcm9uL1xuICAgIHBhdGhuYW1lID0gcGF0aG5hbWUucmVwbGFjZSgvXFwvJC8sIFwiXCIpO1xuXG4gICAgaWYgKHBhdGhuYW1lID09PSB1bmRlZmluZWQgfHwgcGF0aG5hbWUgPT09IG51bGwgfHwgcGF0aG5hbWUubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gcGF0aG5hbWU7XG4gIH0sIFtdKTtcblxuICBjb25zdCBnZXRQbHBPclBkcElkID0gdXNlQ2FsbGJhY2soXG4gICAgKGV4dHJhY3RvcjogSWRFeHRyYWN0b3IpOiBzdHJpbmcgfCBudWxsID0+IHtcbiAgICAgIGlmIChleHRyYWN0b3IgPT09IFwic2hvcGlmeS1wcm9kdWN0LXZhcmlhbnQtaWRcIikge1xuICAgICAgICBjb25zdCBwYXJzZWRIcmVmID0gcGFyc2VIcmVmKHdpbmRvdy5sb2NhdGlvbi5ocmVmKTtcbiAgICAgICAgY29uc3QgdmFyaWFudElkID0gcGFyc2VkSHJlZj8udXJsU2VhcmNoUGFyYW1zPy5nZXQoXCJ2YXJpYW50XCIpO1xuICAgICAgICBpZiAoIXZhcmlhbnRJZCkge1xuICAgICAgICAgIHJldHVybiBnZXRQbHBPclBkcElkKFwic2hvcGlmeS1wcm9kdWN0LWlkXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YXJpYW50SWQ7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBhdGhTZWdtZW50ID1cbiAgICAgICAgZXh0cmFjdG9yID09PSBcInNob3BpZnktcHJvZHVjdC1pZFwiID8gXCJwcm9kdWN0c1wiIDogXCJjb2xsZWN0aW9uc1wiO1xuICAgICAgY29uc3QgdG9rZW5zID0gZ2V0VHJpbW1lZFBhdGhOYW1lKCk/LnNwbGl0KFwiL1wiKTtcbiAgICAgIGNvbnN0IGlkSW5kZXggPSB0b2tlbnM/LmZpbmRJbmRleCgodG9rZW4pID0+IHRva2VuID09PSBwYXRoU2VnbWVudCk7XG4gICAgICBpZiAoaWRJbmRleCAhPT0gdW5kZWZpbmVkICYmIGlkSW5kZXggPj0gMCAmJiB0b2tlbnMpIHtcbiAgICAgICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudCh0b2tlbnNbaWRJbmRleCArIDFdKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0sXG4gICAgW2dldFRyaW1tZWRQYXRoTmFtZV1cbiAgKTtcblxuICBjb25zdCBpc09uUGRwUGFnZSA9IHVzZUNhbGxiYWNrKCgpOiBib29sZWFuID0+IHtcbiAgICByZXR1cm4gZ2V0VHJpbW1lZFBhdGhOYW1lKCk/LmluY2x1ZGVzKFwiL3Byb2R1Y3RzXCIpID8/IGZhbHNlO1xuICB9LCBbZ2V0VHJpbW1lZFBhdGhOYW1lXSk7XG5cbiAgY29uc3QgaXNPblBscFBhZ2UgPSB1c2VDYWxsYmFjaygoKTogYm9vbGVhbiA9PiB7XG4gICAgcmV0dXJuIChcbiAgICAgIChnZXRUcmltbWVkUGF0aE5hbWUoKT8uaW5jbHVkZXMoXCIvY29sbGVjdGlvbnNcIikgJiZcbiAgICAgICAgIWdldFRyaW1tZWRQYXRoTmFtZSgpPy5pbmNsdWRlcyhcIi9wcm9kdWN0c1wiKSkgPz9cbiAgICAgIGZhbHNlXG4gICAgKTtcbiAgfSwgW2dldFRyaW1tZWRQYXRoTmFtZV0pO1xuXG4gIGNvbnN0IHZhbHVlID0gdXNlTWVtbyhcbiAgICAoKSA9PiAoe1xuICAgICAgZ2V0VHJpbW1lZFBhdGhOYW1lLFxuICAgICAgZ2V0UGxwT3JQZHBJZCxcbiAgICAgIGlzT25QZHBQYWdlLFxuICAgICAgaXNPblBscFBhZ2UsXG4gICAgICBpc1JlYWR5LFxuICAgIH0pLFxuICAgIFtnZXRUcmltbWVkUGF0aE5hbWUsIGdldFBscE9yUGRwSWQsIGlzT25QZHBQYWdlLCBpc09uUGxwUGFnZSwgaXNSZWFkeV1cbiAgKTtcblxuICByZXR1cm4gKFxuICAgIDxTaG9waWZ5VXJsQ29udGV4dC5Qcm92aWRlciB2YWx1ZT17dmFsdWV9PlxuICAgICAge2NoaWxkcmVufVxuICAgIDwvU2hvcGlmeVVybENvbnRleHQuUHJvdmlkZXI+XG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgdXNlU2hvcGlmeVVybCA9ICgpID0+IHtcbiAgY29uc3QgY29udGV4dCA9IHVzZUNvbnRleHQoU2hvcGlmeVVybENvbnRleHQpO1xuICBpZiAoIWNvbnRleHQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1c2VTaG9waWZ5VXJsIG11c3QgYmUgdXNlZCB3aXRoaW4gYSBTaG9waWZ5VXJsUHJvdmlkZXJcIik7XG4gIH1cbiAgcmV0dXJuIGNvbnRleHQ7XG59O1xuIiwiaW1wb3J0IHsgdXNlQ2FsbGJhY2sgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IHVzZVNob3BpZnlVcmwgfSBmcm9tIFwic3JjL2NvbnRleHRzL3Nob3BpZnlVcmxDb250ZXh0XCI7XG5pbXBvcnQgeyBJZEV4dHJhY3RvciB9IGZyb20gXCJzcmMvY29udGV4dHMvdHlwZXNcIjtcblxuZXhwb3J0IGNvbnN0IHVzZVNob3BpZnlVcmxPcGVyYXRpb25zID0gKCkgPT4ge1xuICBjb25zdCB7XG4gICAgZ2V0VHJpbW1lZFBhdGhOYW1lLFxuICAgIGdldFBscE9yUGRwSWQsXG4gICAgaXNPblBkcFBhZ2UsXG4gICAgaXNPblBscFBhZ2UsXG4gICAgaXNSZWFkeSxcbiAgfSA9IHVzZVNob3BpZnlVcmwoKTtcblxuICByZXR1cm4ge1xuICAgIGdldFRyaW1tZWRQYXRoTmFtZSxcbiAgICBnZXRQbHBPclBkcElkLFxuICAgIGlzT25QZHBQYWdlLFxuICAgIGlzT25QbHBQYWdlLFxuICAgIGlzUmVhZHksXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgdXNlQ3VycmVudFBhZ2VUeXBlID0gKCkgPT4ge1xuICBjb25zdCB7IGlzT25QZHBQYWdlLCBpc09uUGxwUGFnZSwgaXNSZWFkeSB9ID0gdXNlU2hvcGlmeVVybCgpO1xuXG4gIGNvbnN0IGdldFBhZ2VUeXBlID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIGlmICghaXNSZWFkeSkgcmV0dXJuIFwidW5rbm93blwiO1xuICAgIGlmIChpc09uUGRwUGFnZSgpKSByZXR1cm4gXCJwZHBcIjtcbiAgICBpZiAoaXNPblBscFBhZ2UoKSkgcmV0dXJuIFwicGxwXCI7XG4gICAgcmV0dXJuIFwib3RoZXJcIjtcbiAgfSwgW2lzUmVhZHksIGlzT25QZHBQYWdlLCBpc09uUGxwUGFnZV0pO1xuXG4gIHJldHVybiB7IGdldFBhZ2VUeXBlLCBpc1JlYWR5IH07XG59O1xuXG5leHBvcnQgY29uc3QgdXNlUHJvZHVjdElkID0gKGV4dHJhY3RvcjogSWRFeHRyYWN0b3IpID0+IHtcbiAgY29uc3QgeyBnZXRQbHBPclBkcElkLCBpc1JlYWR5IH0gPSB1c2VTaG9waWZ5VXJsKCk7XG5cbiAgY29uc3QgcHJvZHVjdElkID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIGlmICghaXNSZWFkeSkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIGdldFBscE9yUGRwSWQoZXh0cmFjdG9yKTtcbiAgfSwgW2lzUmVhZHksIGdldFBscE9yUGRwSWQsIGV4dHJhY3Rvcl0pO1xuXG4gIHJldHVybiB7IHByb2R1Y3RJZCwgaXNSZWFkeSB9O1xufTtcbiIsImltcG9ydCB7IHVzZU1lbW8gfSBmcm9tICdyZWFjdCc7XG5cbmV4cG9ydCB0eXBlIFVuaXQgPSAncGVyY2VudCcgfCAncGl4ZWwnO1xuXG5leHBvcnQgY29uc3QgdXNlU25hcENhbGN1bGF0b3IgPSAoc25hcHM6IG51bWJlcltdLCBtYXhIZWlnaHQ6IG51bWJlciwgdW5pdDogVW5pdCkgPT4ge1xuICBjb25zdCB2aWV3cG9ydEhlaWdodFB4ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodDtcbiAgY29uc3Qgc3dpcGV2aWV3SGVpZ2h0UHggPVxuICAgIHVuaXQgPT09ICdwZXJjZW50JyA/IE1hdGguZmxvb3Iodmlld3BvcnRIZWlnaHRQeCAqIChtYXhIZWlnaHQgLyAxMDApKSA6IG1heEhlaWdodDtcblxuICBjb25zdCBzbmFwc1RvUGl4ZWxzID0gdXNlTWVtbyhcbiAgICAoKSA9PlxuICAgICAgc25hcHM/Lm1hcCgoc25hcCkgPT5cbiAgICAgICAgTWF0aC5hYnMoXG4gICAgICAgICAgKHVuaXQgPT09ICdwZXJjZW50JyA/IE1hdGguZmxvb3Ioc3dpcGV2aWV3SGVpZ2h0UHggKiAoc25hcCAvIDEwMCkpIDogc25hcCkgLVxuICAgICAgICAgICAgc3dpcGV2aWV3SGVpZ2h0UHgsXG4gICAgICAgICksXG4gICAgICApLFxuICAgIFt2aWV3cG9ydEhlaWdodFB4XSxcbiAgKTtcblxuICBjb25zdCBnZXRQaXhlbFRvU25hcCA9IChwaXhlbHM6IG51bWJlcikgPT4ge1xuICAgIGNvbnN0IHNuYXBJZHggPSBzbmFwc1RvUGl4ZWxzPy5pbmRleE9mKHBpeGVscykgfHwgMDtcbiAgICByZXR1cm4gc25hcHM/LltzbmFwSWR4XSB8fCAwO1xuICB9O1xuXG4gIGNvbnN0IGdldFNuYXBUb1BpeGVsID0gKHNuYXA6IG51bWJlcikgPT4ge1xuICAgIGNvbnN0IHNuYXBJZHggPSBzbmFwcz8uaW5kZXhPZihzbmFwKSB8fCAwO1xuICAgIHJldHVybiBzbmFwc1RvUGl4ZWxzPy5bc25hcElkeF0gfHwgMDtcbiAgfTtcblxuICByZXR1cm4ge1xuICAgIHZpZXdwb3J0SGVpZ2h0UHgsXG4gICAgc25hcHNUb1BpeGVscyxcbiAgICBzd2lwZXZpZXdIZWlnaHRQeCxcbiAgICBnZXRQaXhlbFRvU25hcCxcbiAgICBnZXRTbmFwVG9QaXhlbCxcbiAgfTtcbn07XG4iLCJpbXBvcnQgeyB1c2VDb250ZXh0IH0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgU3lzdGVtU2V0dGluZ3NDb250ZXh0IH0gZnJvbSAnc3JjL2NvbnRleHRzJztcblxuZXhwb3J0IGNvbnN0IHVzZVN5c3RlbVNldHRpbmdzQ29udGV4dCA9ICgpID0+IHtcbiAgY29uc3QgY29udGV4dCA9IHVzZUNvbnRleHQoU3lzdGVtU2V0dGluZ3NDb250ZXh0KTtcblxuICBpZiAoIWNvbnRleHQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3VzZVN5c3RlbVNldHRpbmdzQ29udGV4dCBtdXN0IGJlIHVzZWQgd2l0aGluIGEgU3lzdGVtU2V0dGluZ3NDb250ZXh0UHJvdmlkZXInKTtcbiAgfVxuXG4gIHJldHVybiB7IC4uLmNvbnRleHQgfTtcbn07XG4iLCJpbXBvcnQgeyBSZWZPYmplY3QsIHVzZUVmZmVjdCwgdXNlUmVmIH0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyBTcGlmZnlXaWRnZXRzIH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9tb2RlbHMvc3BpZmZ5V2lkZ2V0c1wiO1xuaW1wb3J0IHsgdXNlSW50ZXJzZWN0aW9uIH0gZnJvbSBcInNyYy9ob29rcy91c2VJbnRlcnNlY3Rpb25cIjtcbmltcG9ydCB7XG4gIFNwaWZmeU1ldHJpY3NFdmVudE5hbWUsXG4gIHVzZUFtcGxpdHVkZSxcbn0gZnJvbSBcInNyYy9jb250ZXh0cy9hbXBsaXR1ZGVDb250ZXh0XCI7XG5cbi8qKlxuICogVHJhY2tzIGEgY29tcG9uZW50IGFuZCBsb2dzIGFuIGV2ZW50IHRvIEFtcGxpdHVkZSB3aGVuIHRoZSBjb21wb25lbnQgaXMgdmlzaWJsZS5cbiAqXG4gKiBAcGFyYW0gY29tcG9uZW50IC0gVGhlIGNvbXBvbmVudCB0byB0cmFjay5cbiAqIEBwYXJhbSBlbGVtZW50IC0gVGhlIGVsZW1lbnQgdG8gdHJhY2sgdmlzaWJpbGl0eSBvZi5cbiAqIEBwYXJhbSBldmVudFByb3BzIC0gQWRkaXRpb25hbCBwcm9wZXJ0aWVzIHRvIGluY2x1ZGUgd2l0aCB0aGUgZXZlbnQuXG4gKiBAcGFyYW0gZXZlbnROYW1lIC0gVGhlIEFtcGxpdHVkZSBldmVudCBuYW1lIHRvIHRyYWNrIChkZWZhdWx0cyB0byBDaGF0Q29tcG9uZW50VmlzaWJsZSkuXG4gKi9cbmV4cG9ydCBjb25zdCB1c2VUcmFja0NvbXBvbmVudFZpc2libGVFdmVudCA9IChcbiAgY29tcG9uZW50OiBTcGlmZnlXaWRnZXRzLFxuICBlbGVtZW50OiBSZWZPYmplY3Q8SFRNTEVsZW1lbnQ+LFxuICBldmVudFByb3BzPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gIGV2ZW50TmFtZTogU3BpZmZ5TWV0cmljc0V2ZW50TmFtZSA9IFNwaWZmeU1ldHJpY3NFdmVudE5hbWUuQ2hhdENvbXBvbmVudFZpc2libGVcbikgPT4ge1xuICBjb25zdCBpc1Zpc2libGUgPSB1c2VJbnRlcnNlY3Rpb24oZWxlbWVudCwgXCIwcHhcIik7XG4gIGNvbnN0IGhhc1RyYWNrZWRFdmVudCA9IHVzZVJlZihmYWxzZSk7XG4gIGNvbnN0IHsgdHJhY2tFdmVudCB9ID0gdXNlQW1wbGl0dWRlKCk7XG5cbiAgY29uc3QgY29tcG9uZW50UHJvcHMgPSAoKCkgPT4ge1xuICAgIGlmIChldmVudE5hbWUgPT09IFNwaWZmeU1ldHJpY3NFdmVudE5hbWUuQ2hhdENvbXBvbmVudFZpc2libGUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNoYXRfY29tcG9uZW50OiBjb21wb25lbnQsXG4gICAgICAgIC4uLmV2ZW50UHJvcHMsXG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAoZXZlbnROYW1lID09PSBTcGlmZnlNZXRyaWNzRXZlbnROYW1lLlNlYXJjaENvbXBvbmVudFZpc2libGUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHNlYXJjaF9jb21wb25lbnQ6IGNvbXBvbmVudCxcbiAgICAgICAgLi4uZXZlbnRQcm9wcyxcbiAgICAgIH07XG4gICAgfVxuICAgIC8vIERlZmF1bHQgY2FzZSBmb3Igb3RoZXIgZXZlbnQgdHlwZXNcbiAgICByZXR1cm4ge1xuICAgICAgY29tcG9uZW50OiBjb21wb25lbnQsXG4gICAgICAuLi5ldmVudFByb3BzLFxuICAgIH07XG4gIH0pKCk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoaXNWaXNpYmxlICYmICFoYXNUcmFja2VkRXZlbnQuY3VycmVudCkge1xuICAgICAgdHJhY2tFdmVudCh7XG4gICAgICAgIGV2ZW50TmFtZTogZXZlbnROYW1lLFxuICAgICAgICBldmVudFByb3BzOiBjb21wb25lbnRQcm9wcyxcbiAgICAgIH0pO1xuICAgICAgaGFzVHJhY2tlZEV2ZW50LmN1cnJlbnQgPSB0cnVlO1xuICAgIH1cbiAgfSwgW2lzVmlzaWJsZSwgY29tcG9uZW50LCBldmVudFByb3BzLCBldmVudE5hbWUsIGNvbXBvbmVudFByb3BzLCB0cmFja0V2ZW50XSk7XG59O1xuIiwiaW1wb3J0IHsgdXNlQXRvbVZhbHVlIH0gZnJvbSBcImpvdGFpXCI7XG5pbXBvcnQgeyB1c2VFZmZlY3QsIHVzZVJlZiB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHtcbiAgU3BpZmZ5TWV0cmljc0V2ZW50TmFtZSxcbiAgdXNlQW1wbGl0dWRlLFxufSBmcm9tIFwic3JjL2NvbnRleHRzL2FtcGxpdHVkZUNvbnRleHRcIjtcbmltcG9ydCB7XG4gIGhhc1BhcnNlZFZhcmlhbnRJbmZvQXRvbSxcbiAgdmFyaWFudEluZm9BdG9tLFxufSBmcm9tIFwic3JjL2F0b21zL2FwcC92YXJpYW50XCI7XG5cbi8qKlxuICogVXBkYXRlcyB0aGUgZGVmYXVsdCBhbmFseXRpY3MgcHJvcGVydGllcyB3aGVuZXZlciB0aGUgdmFyaWFudCBpbmZvIGNoYW5nZXMuIFRoaXMgaG9vayBhbHNvXG4gKiB0cmlnZ2VycyBhbnkgZXZlbnRzIHRoYXQgc2hvdWxkIGJlIHNlbnQgb25jZSBwZXIgcGFnZSB2aXNpdC5cbiAqL1xuZXhwb3J0IGNvbnN0IHVzZVVwZGF0ZUFuYWx5dGljc1Byb3BzID0gKCkgPT4ge1xuICBjb25zdCB2YXJpYW50SW5mbyA9IHVzZUF0b21WYWx1ZSh2YXJpYW50SW5mb0F0b20pO1xuICBjb25zdCBoYXNJbml0aWFsaXplZCA9IHVzZVJlZihmYWxzZSk7XG4gIGNvbnN0IGhhc1BhcnNlZFZhcmlhbnRJbmZvID0gdXNlQXRvbVZhbHVlKGhhc1BhcnNlZFZhcmlhbnRJbmZvQXRvbSk7XG4gIGNvbnN0IHsgdHJhY2tFdmVudCwgc2V0U3VwcGxlbWVudGFsRGVmYXVsdFByb3BzIH0gPSB1c2VBbXBsaXR1ZGUoKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IHZhcmlhbnRJbmZvV2l0aFByZWZpeCA9IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgIE9iamVjdC5lbnRyaWVzKHZhcmlhbnRJbmZvKS5tYXAoKFtrZXksIHZhbHVlXSkgPT4gW1xuICAgICAgICBgdmFyaWFudEluZm8uJHtrZXl9YCxcbiAgICAgICAgdmFsdWUsXG4gICAgICBdKVxuICAgICk7XG5cbiAgICBjb25zdCBkZWZhdWx0RXZlbnRQcm9wZXJ0aWVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHtcbiAgICAgIHBhZ2VfdmFyaWFudDogdmFyaWFudEluZm8udmFyaWFudCwgLy8gVE9ETzogc2hvdWxkIGJlIHJlbW92ZWQgb3ZlciB0aW1lLCBhZnRlciBtaWdyYXRpb25cbiAgICAgIC4uLnZhcmlhbnRJbmZvV2l0aFByZWZpeCxcbiAgICB9O1xuXG4gICAgLy8gVE9ETzogc2hvdWxkIGJlIHJlbW92ZWQgb3ZlciB0aW1lLCBhZnRlciBtaWdyYXRpb25cbiAgICBpZiAodmFyaWFudEluZm8udmFyaWFudCA9PT0gXCJwZHBcIikge1xuICAgICAgZGVmYXVsdEV2ZW50UHJvcGVydGllcy5wcm9kdWN0X2lkID0gdmFyaWFudEluZm8ucHJvZHVjdElkO1xuICAgIH1cblxuICAgIC8vIFRPRE86IHNob3VsZCBiZSByZW1vdmVkIG92ZXIgdGltZSwgYWZ0ZXIgbWlncmF0aW9uXG4gICAgaWYgKHZhcmlhbnRJbmZvLnZhcmlhbnQgPT09IFwicGxwXCIpIHtcbiAgICAgIGRlZmF1bHRFdmVudFByb3BlcnRpZXMucGxwX2lkID0gdmFyaWFudEluZm8ucGxwSWQ7XG4gICAgfVxuXG4gICAgLy8gVE9ETzogc2hvdWxkIGJlIHJlbW92ZWQgb3ZlciB0aW1lLCBhZnRlciBtaWdyYXRpb25cbiAgICBpZiAodmFyaWFudEluZm8udmFyaWFudCA9PT0gXCJwYWdlX3Zpc2l0XCIpIHtcbiAgICAgIGRlZmF1bHRFdmVudFByb3BlcnRpZXMucGFnZV92aXNpdF9jYXRlZ29yeSA9XG4gICAgICAgIHZhcmlhbnRJbmZvLnBhZ2VWaXNpdENhdGVnb3J5O1xuICAgICAgZGVmYXVsdEV2ZW50UHJvcGVydGllcy5wYWdlX3Zpc2l0X3VybCA9IHZhcmlhbnRJbmZvLnVybDtcbiAgICB9XG5cbiAgICBzZXRTdXBwbGVtZW50YWxEZWZhdWx0UHJvcHMoZGVmYXVsdEV2ZW50UHJvcGVydGllcyk7XG5cbiAgICAvLyBwdXQgYW55IGV2ZW50cyB0aGF0IHNob3VsZCBiZSBzZW50IG9uY2UgcGVyIHBhZ2UgdmlzaXQgaGVyZVxuICAgIGlmICghaGFzSW5pdGlhbGl6ZWQuY3VycmVudCAmJiBoYXNQYXJzZWRWYXJpYW50SW5mbykge1xuICAgICAgdHJhY2tFdmVudCh7XG4gICAgICAgIGV2ZW50TmFtZTogU3BpZmZ5TWV0cmljc0V2ZW50TmFtZS5CdW5kbGVMb2FkZWQsXG4gICAgICB9KTtcbiAgICAgIGhhc0luaXRpYWxpemVkLmN1cnJlbnQgPSB0cnVlO1xuICAgIH1cbiAgfSwgW1xuICAgIHZhcmlhbnRJbmZvLFxuICAgIGhhc1BhcnNlZFZhcmlhbnRJbmZvLFxuICAgIHRyYWNrRXZlbnQsXG4gICAgc2V0U3VwcGxlbWVudGFsRGVmYXVsdFByb3BzLFxuICBdKTtcbn07XG4iLCJpbXBvcnQgeyBVc2VyRXZlbnRDYXRlZ29yeSB9IGZyb20gXCJAc3BpZmZ5LWFpL2NvbW1lcmNlLWFwaS1jbGllbnRcIjtcbmltcG9ydCB7IHVzZUF0b20sIHVzZUF0b21WYWx1ZSwgdXNlU2V0QXRvbSB9IGZyb20gXCJqb3RhaVwiO1xuaW1wb3J0IHtcbiAgY3JlYXRlQ29udGV4dCxcbiAgdXNlRWZmZWN0LFxuICB1c2VTdGF0ZSxcbiAgUmVhY3ROb2RlLFxuICB1c2VDYWxsYmFjayxcbiAgdXNlTWVtbyxcbn0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgQ29tbWVyY2VBcGlDbGllbnQgZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9jb21tZXJjZS1hcGlcIjtcbmltcG9ydCB7IHY0IGFzIHV1aWQgfSBmcm9tIFwidXVpZFwiO1xuaW1wb3J0IHsgU2Vzc2lvblJlc3RhcnRSZXF1aXJlZCB9IGZyb20gXCJzcmMvdHlwZXMvZXhjZXB0aW9ucy9zZXNzaW9uRXhjZXB0aW9uc1wiO1xuaW1wb3J0IExvZ2dlciBmcm9tIFwic3JjL2FwcGxpY2F0aW9uL2xvZ2dpbmcvbG9nZ2VyXCI7XG5pbXBvcnQge1xuICBNZXNzYWdlLFxuICBNZXNzYWdlUm9sZSxcbiAgTWVzc2FnZVR5cGUsXG4gIE5leHRNZXNzYWdlUmVxdWVzdCxcbiAgUmVzcG9uc2UsXG59IGZyb20gXCJzcmMvYXBwbGljYXRpb24vbW9kZWxzXCI7XG5pbXBvcnQgeyBTcGlmZnlNZXRyaWNzRXZlbnROYW1lIH0gZnJvbSBcInNyYy9jb250ZXh0cy9hbXBsaXR1ZGVDb250ZXh0XCI7XG5pbXBvcnQgeyBtZXNzYWdlRnJvbVJlc3BvbnNlIH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi91dGlsc1wiO1xuaW1wb3J0IHsgY2hhdElkQXRvbSwgdXNlcklkQXRvbSwgdmFyaWFudEluZm9BdG9tIH0gZnJvbSBcInNyYy9hdG9tcy9hcHBcIjtcbmltcG9ydCB7XG4gIG1lc3NhZ2VzQXRvbSxcbiAgcmVxdWVzdEZhaWx1cmVBdG9tLFxuICByZXNwb25zZVN0cmVhbWluZ0F0b20sXG4gIHVzZXJIYXNSZXBsaWVkQXRvbSxcbiAgUGVyZk1ldHJpY3NFdmVudHMsXG4gIGxvZ1BlcmZNZXRyaWNBdG9tLFxuICB1c2VyRXZlbnRzQXRvbSxcbiAgc3VnZ2VzdGlvbnNMb2FkaW5nQXRvbSxcbiAgc3VnZ2VzdGlvbnNBdG9tLFxufSBmcm9tIFwic3JjL2F0b21zL2NoYXRcIjtcbmltcG9ydCB7XG4gIGNoYXRTZWFyY2hQcm9kdWN0U29ydGluZ0F0b20sXG4gIGNoYXRTZWFyY2hQcm9kdWN0cyxcbiAgY2hhdFNlYXJjaFN0YXRlQXRvbSxcbiAgaGFuZGxlU2VhcmNoUmVzdWx0c0F0b20sXG4gIGNoYXRTZWFyY2hJc0xvYWRpbmdBdG9tLFxufSBmcm9tIFwic3JjL2F0b21zL3NlYXJjaC9jaGF0U2VhcmNoXCI7XG5pbXBvcnQgeyB1c2VTeXN0ZW1TZXR0aW5nc0NvbnRleHQgfSBmcm9tIFwic3JjL2hvb2tzXCI7XG5pbXBvcnQgeyBjcmVhdGVBcHBMb2FkZWRFdmVudCwgY3JlYXRlVmlzaXRVc2VyRXZlbnQgfSBmcm9tIFwic3JjL2hvb2tzL3V0aWxzXCI7XG5pbXBvcnQgeyB1c2VNZXNzYWdlSW50ZXJjZXB0b3IgfSBmcm9tIFwic3JjL2ludGVyY2VwdG9ycy91c2VNZXNzYWdlSW50ZXJjZXB0b3JcIjtcbmltcG9ydCB7IHN1cHBvcnRlZEV2ZW50QXRvbSB9IGZyb20gXCJzcmMvYXRvbXMvYXBwL3ZhcmlhbnRcIjtcbmltcG9ydCB7IGNoYXRBdG9tIH0gZnJvbSBcInNyYy9hdG9tcy9jaGF0XCI7XG5pbXBvcnQgeyBnZXRBdG9tU3RvcmUgfSBmcm9tIFwic3JjL2F0b21zL2F0b21TdG9yZVwiO1xuaW1wb3J0IHtcbiAgY2xlYXJVc2VyRXZlbnRBdG9tLFxuICBjcmVhdGVSZXNwb25zZVBheWxvYWQsXG4gIHByb2Nlc3NVc2VyRXZlbnRBdG9tLFxuICB1c2VyRXZlbnRRdWV1ZUF0b20sXG4gIHVzZXJRdWV1ZUV2ZW50Q291bnRBdG9tLFxufSBmcm9tIFwic3JjL2F0b21zL2NoYXQvbWVzc2FnZVF1ZXVlXCI7XG5pbXBvcnQgeyB1c2VBbXBsaXR1ZGVUcmFja2luZyB9IGZyb20gXCJzcmMvaG9va3MvdXNlQW1wbGl0dWRlT3BlcmF0aW9uc1wiO1xuXG4vKipcbiAqIFJlY29yZCB0aGUgY2hhdCBhc3Npc3RhbnQgcmVzcG9uc2UgaW4gQW1wbGl0dWRlXG4gKlxuICogQHBhcmFtIHN0YXJ0VGltZU1zIFRoZSBzdGFydCB0aW1lIG9mIHRoZSBhc3Npc3RhbnQgcmVzcG9uc2VcbiAqIEBwYXJhbSBwYXlsb2FkIFRoZSBwYXlsb2FkIHVzZWQgdG8gZ2VuZXJhdGUgdGhlIHJlc3BvbnNlXG4gKi9cbmNvbnN0IHJlY29yZEFzc2lzdGFudFJlc3BvbnNlID0gKFxuICBzdGFydFRpbWVNczogbnVtYmVyLFxuICBwYXlsb2FkOiBOZXh0TWVzc2FnZVJlcXVlc3QsXG4gIHRyYWNrOiAoXG4gICAgZXZlbnROYW1lOiBTcGlmZnlNZXRyaWNzRXZlbnROYW1lLFxuICAgIGV2ZW50UHJvcHM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPlxuICApID0+IHZvaWRcbikgPT4ge1xuICBjb25zdCBhdG9tU3RvcmUgPSBnZXRBdG9tU3RvcmUoKTtcbiAgY29uc3QgY2hhdFN0YXRlID0gYXRvbVN0b3JlLmdldChjaGF0QXRvbSk7XG4gIGNvbnN0IGNoYXRTZWFyY2hTdGF0ZSA9IGF0b21TdG9yZS5nZXQoY2hhdFNlYXJjaFN0YXRlQXRvbSk7XG4gIGNvbnN0IHNlYXJjaFByb2R1Y3RzID0gYXRvbVN0b3JlLmdldChjaGF0U2VhcmNoUHJvZHVjdHMpO1xuICBjb25zdCBzZWFyY2hQcm9kdWN0c1NvcnQgPSBhdG9tU3RvcmUuZ2V0KGNoYXRTZWFyY2hQcm9kdWN0U29ydGluZ0F0b20pO1xuICBjb25zdCBhc3Npc3RhbnRSZXNwb25zZVRpbWVNcyA9IHsgc3RhcnQ6IHN0YXJ0VGltZU1zLCBlbmQ6IERhdGUubm93KCkgfTtcbiAgbGV0IHVzZXJRdWVyeVByb3BlcnR5OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgaWYgKFxuICAgIGNoYXRTdGF0ZS5yZXBseUV2ZW50Q2F0ZWdvcnkgPT09IFVzZXJFdmVudENhdGVnb3J5LlN1Z2dlc3Rpb25DbGlja2VkICYmXG4gICAgY2hhdFN0YXRlLnN1Z2dlc3Rpb25cbiAgKSB7XG4gICAgdXNlclF1ZXJ5UHJvcGVydHkgPSBjaGF0U3RhdGUuc3VnZ2VzdGlvbi5jb250ZW50O1xuICB9IGVsc2UgaWYgKGNoYXRTdGF0ZS51c2VyUXVlcnkgJiYgY2hhdFN0YXRlLnVzZXJRdWVyeS5sZW5ndGggPiAwKSB7XG4gICAgdXNlclF1ZXJ5UHJvcGVydHkgPSBjaGF0U3RhdGUudXNlclF1ZXJ5O1xuICB9XG5cbiAgY29uc3QgZXZlbnRQcm9wczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7XG4gICAgcmVzcG9uc2VfdGltZV9tczpcbiAgICAgIGFzc2lzdGFudFJlc3BvbnNlVGltZU1zLmVuZCAtIGFzc2lzdGFudFJlc3BvbnNlVGltZU1zLnN0YXJ0LFxuICAgIHVzZXJfZXZlbnRfdHlwZTogY2hhdFN0YXRlLnJlcGx5RXZlbnRDYXRlZ29yeSxcbiAgICB1c2VyX3F1ZXJ5OiB1c2VyUXVlcnlQcm9wZXJ0eSxcbiAgfTtcblxuICBpZiAoY2hhdFN0YXRlLnJlcGx5RXZlbnRDYXRlZ29yeSA9PT0gVXNlckV2ZW50Q2F0ZWdvcnkuRm9ybVN1Ym1pdHRlZCkge1xuICAgIGNvbnN0IGxhc3RBc3Npc3RhbnRUdXJuID0gY2hhdFN0YXRlLm1lc3NhZ2VzXG4gICAgICAuZmlsdGVyKFxuICAgICAgICAodHVybikgPT4gdHVybi5sZW5ndGggPiAwICYmIHR1cm5bMF0ucm9sZSA9PT0gTWVzc2FnZVJvbGUuQXNzaXN0YW50XG4gICAgICApXG4gICAgICAucG9wKCk7XG4gICAgY29uc3QgZm9ybVR5cGUgPSBwYXlsb2FkLnVzZXJFdmVudHM/LmZpbmQoXG4gICAgICAoZXZlbnQpID0+IGV2ZW50LmNhdGVnb3J5ID09PSBVc2VyRXZlbnRDYXRlZ29yeS5Gb3JtU3VibWl0dGVkXG4gICAgKT8uYXR0cmlidXRlcy5mb3JtVHlwZTtcbiAgICBjb25zdCBmb3JtU3RhdHVzID0gbGFzdEFzc2lzdGFudFR1cm4/LnNvbWUoXG4gICAgICAocmVzcG9uc2UpID0+IHJlc3BvbnNlLnR5cGUgPT09IE1lc3NhZ2VUeXBlLk9yZGVyXG4gICAgKTtcbiAgICBldmVudFByb3BzLmZvcm1fc3VibWl0dGVkX2F0dHJpYnV0ZXMgPSB7XG4gICAgICBmb3JtX3R5cGU6IGZvcm1UeXBlLFxuICAgICAgc3RhdHVzOiBmb3JtU3RhdHVzID8gXCJzdWNjZXNzXCIgOiBcImZhaWxlZFwiLFxuICAgIH07XG4gIH1cblxuICBpZiAoY2hhdFNlYXJjaFN0YXRlID09PSBcInByb2R1Y3QtcGFnZVwiKSB7XG4gICAgZXZlbnRQcm9wcy5zZWFyY2hfcHJvZHVjdHNfcmV0dXJuZWQgPSBzZWFyY2hQcm9kdWN0cy5sZW5ndGg7XG4gICAgZXZlbnRQcm9wcy5zZWFyY2hfcHJvZHVjdHNfc29ydF90eXBlID0gc2VhcmNoUHJvZHVjdHNTb3J0O1xuICB9XG5cbiAgdHJhY2soU3BpZmZ5TWV0cmljc0V2ZW50TmFtZS5DaGF0QXNzaXN0YW50UmVzcG9uc2UsIHtcbiAgICBldmVudFByb3BzLFxuICB9KTtcbn07XG5cbmludGVyZmFjZSBDaGF0Q29udGV4dFBhcmFtcyB7fVxuXG5jb25zdCBDaGF0Q29udGV4dCA9IGNyZWF0ZUNvbnRleHQ8Q2hhdENvbnRleHRQYXJhbXMgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG5cbmNvbnN0IHVwZGF0ZU1lc3NhZ2VTdGF0ZSA9IChcbiAgbWVzc2FnZTogTWVzc2FnZSxcbiAgbGFzdE1lc3NhZ2U6IE1lc3NhZ2UsXG4gIHNldE1lc3NhZ2VzOiAodXBkYXRlcjogKHByZXY6IE1lc3NhZ2VbXVtdKSA9PiBNZXNzYWdlW11bXSkgPT4gdm9pZFxuKTogTWVzc2FnZSA9PiB7XG4gIGlmIChsYXN0TWVzc2FnZSA9PSBudWxsKSB7XG4gICAgc2V0TWVzc2FnZXMoKHByZXYpID0+IFsuLi5wcmV2LCBbbWVzc2FnZV1dKTtcbiAgICByZXR1cm4gbWVzc2FnZTtcbiAgfVxuICBpZiAoXG4gICAgbGFzdE1lc3NhZ2UudHlwZSA9PT0gTWVzc2FnZVR5cGUuVGV4dCAmJlxuICAgIG1lc3NhZ2UudHlwZSA9PT0gTWVzc2FnZVR5cGUuVGV4dFxuICApIHtcbiAgICBjb25zdCBuZXdNZXNzYWdlID0ge1xuICAgICAgLi4ubGFzdE1lc3NhZ2UsXG4gICAgICBtZXRhZGF0YToge1xuICAgICAgICAuLi5sYXN0TWVzc2FnZS5tZXRhZGF0YSxcbiAgICAgICAgY29udGVudDogbGFzdE1lc3NhZ2UubWV0YWRhdGEuY29udGVudCArIG1lc3NhZ2UubWV0YWRhdGEuY29udGVudCxcbiAgICAgIH0sXG4gICAgfTtcbiAgICBzZXRNZXNzYWdlcygocHJldikgPT4ge1xuICAgICAgY29uc3QgbGFzdFR1cm4gPSBwcmV2W3ByZXYubGVuZ3RoIC0gMV07XG4gICAgICByZXR1cm4gW1xuICAgICAgICAuLi5wcmV2LnNsaWNlKDAsIHByZXYubGVuZ3RoIC0gMSksXG4gICAgICAgIFsuLi5sYXN0VHVybi5zbGljZSgwLCBsYXN0VHVybi5sZW5ndGggLSAxKSwgbmV3TWVzc2FnZV0sXG4gICAgICBdO1xuICAgIH0pO1xuICAgIHJldHVybiBuZXdNZXNzYWdlO1xuICB9XG4gIHNldE1lc3NhZ2VzKChwcmV2KSA9PiBbXG4gICAgLi4ucHJldi5zbGljZSgwLCBwcmV2Lmxlbmd0aCAtIDEpLFxuICAgIFsuLi5wcmV2W3ByZXYubGVuZ3RoIC0gMV0sIG1lc3NhZ2VdLFxuICBdKTtcbiAgcmV0dXJuIG1lc3NhZ2U7XG59O1xuXG5jb25zdCBoYW5kbGVTdHJlYW1pbmdFcnJvciA9IChcbiAgX2Vycm9yOiB1bmtub3duLFxuICBzZXRSZXF1ZXN0RmFpbHVyZTogKGZhaWxlZDogYm9vbGVhbikgPT4gdm9pZCxcbiAgc2V0TWVzc2FnZXM6ICh1cGRhdGVyOiAocHJldjogTWVzc2FnZVtdW10pID0+IE1lc3NhZ2VbXVtdKSA9PiB2b2lkXG4pID0+IHtcbiAgc2V0UmVxdWVzdEZhaWx1cmUodHJ1ZSk7XG4gIHNldE1lc3NhZ2VzKChwcmV2KSA9PiBbXG4gICAgLi4ucHJldixcbiAgICBbXG4gICAgICB7XG4gICAgICAgIGlkOiB1dWlkKCksXG4gICAgICAgIHJvbGU6IE1lc3NhZ2VSb2xlLkFzc2lzdGFudCxcbiAgICAgICAgdHlwZTogTWVzc2FnZVR5cGUuVGV4dCxcbiAgICAgICAgY3JlYXRlZEF0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgICAgY29udGVudDpcbiAgICAgICAgICAgIFwiSSdtIHNvcnJ5ISBJJ20gaGF2aW5nIHRyb3VibGUgcmlnaHQgbm93LiBQbGVhc2UgcmVmcmVzaCB0aGUgcGFnZSBvciB0cnkgYWdhaW4gaW4gYSBtb21lbnQuXCIsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIF0sXG4gIF0pO1xufTtcblxuY29uc3QgcHJvY2Vzc1N0cmVhbWluZ1Jlc3BvbnNlID0gYXN5bmMgKFxuICBzdHJlYW06IEFzeW5jSXRlcmFibGU8UmVzcG9uc2U+LFxuICBtZXNzYWdlSW50ZXJjZXB0b3I6IHtcbiAgICBpbnRlcmNlcHQ6IChyZXNwb25zZT86IFJlc3BvbnNlKSA9PiBib29sZWFuIHwgdW5kZWZpbmVkO1xuICB9LFxuICBoYW5kbGVTZWFyY2hSZXN1bHRzOiAobWVzc2FnZTogTWVzc2FnZSkgPT4gdm9pZCxcbiAgc2V0TWVzc2FnZXM6ICh1cGRhdGVyOiAocHJldjogTWVzc2FnZVtdW10pID0+IE1lc3NhZ2VbXVtdKSA9PiB2b2lkLFxuICBzZXRTZWFyY2hJc0xvYWRpbmc6IChsb2FkaW5nOiBib29sZWFuKSA9PiB2b2lkLFxuICBjaGF0SWQ6IHN0cmluZ1xuKTogUHJvbWlzZTx7IGhhc1NlYXJjaFJlc3VsdHM6IGJvb2xlYW4gfT4gPT4ge1xuICBsZXQgbGFzdE1lc3NhZ2U6IE1lc3NhZ2UgfCB1bmRlZmluZWQ7XG4gIGxldCBoYXNTZWFyY2hSZXN1bHRzID0gZmFsc2U7XG5cbiAgZm9yIGF3YWl0IChjb25zdCByZXNwb25zZSBvZiBzdHJlYW0pIHtcbiAgICB0cnkge1xuICAgICAgaWYgKG1lc3NhZ2VJbnRlcmNlcHRvci5pbnRlcmNlcHQocmVzcG9uc2UpKSB7XG4gICAgICAgIHJldHVybiB7IGhhc1NlYXJjaFJlc3VsdHMgfTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgbWVzc2FnZSA9IG1lc3NhZ2VGcm9tUmVzcG9uc2UocmVzcG9uc2UpO1xuICAgICAgaWYgKCFtZXNzYWdlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkZhaWxlZCB0byB0cmFuc2Zvcm0gQVBJIHJlc3BvbnNlIHRvIGNsaWVudCBtZXNzYWdlXCIpO1xuICAgICAgfVxuXG4gICAgICBpZiAobWVzc2FnZS50eXBlID09PSBNZXNzYWdlVHlwZS5Qcm9kdWN0U2VhcmNoKSB7XG4gICAgICAgIGhhbmRsZVNlYXJjaFJlc3VsdHMobWVzc2FnZSk7XG4gICAgICAgIGhhc1NlYXJjaFJlc3VsdHMgPSB0cnVlO1xuICAgICAgICBzZXRTZWFyY2hJc0xvYWRpbmcoZmFsc2UpOyAvLyBVcGRhdGUgc2VhcmNoIGxvYWRpbmcgaW1tZWRpYXRlbHkgd2hlbiByZXN1bHRzIGFyZSBkZXRlY3RlZFxuICAgICAgfVxuXG4gICAgICBsYXN0TWVzc2FnZSA9IHVwZGF0ZU1lc3NhZ2VTdGF0ZShtZXNzYWdlLCBsYXN0TWVzc2FnZSEsIHNldE1lc3NhZ2VzKTtcbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgTG9nZ2VyLmxvZ1dhcm4oXG4gICAgICAgIGBbc3BpZmZ5LWFpXSBGYWlsZWQgdG8gZ2VuZXJhdGUgcmVzcG9uc2VzIGZyb20gc3RyZWFtIGNoYXRfaWQ9JHtjaGF0SWR9YCxcbiAgICAgICAgZXJyb3IsXG4gICAgICAgIHtcbiAgICAgICAgICBsYXN0UmVzcG9uc2U6IGxhc3RNZXNzYWdlLFxuICAgICAgICAgIHJlc3BvbnNlLFxuICAgICAgICB9XG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7IGhhc1NlYXJjaFJlc3VsdHMgfTtcbn07XG5cbmNvbnN0IENoYXRDb250ZXh0UHJvdmlkZXIgPSAoeyBjaGlsZHJlbiB9OiB7IGNoaWxkcmVuOiBSZWFjdE5vZGUgfSkgPT4ge1xuICBjb25zdCBsb2dQZXJmTWV0cmljID0gdXNlU2V0QXRvbShsb2dQZXJmTWV0cmljQXRvbSk7XG4gIGNvbnN0IFt3aWRnZXRJbml0aWFsaXplZCwgc2V0V2lkZ2V0SW5pdGlhbGl6ZWRdID0gdXNlU3RhdGUoZmFsc2UpO1xuICBjb25zdCBzZXRVc2VySGFzUmVwbGllZCA9IHVzZVNldEF0b20odXNlckhhc1JlcGxpZWRBdG9tKTtcbiAgLy8gVE9ETzogY3JlYXRlIGF0b21zIGZvciBzZXR0aW5nL2dldHRpbmcgdGhlIGxhc3QgbWVzc2FnZSB0dXJuXG4gIGNvbnN0IFttZXNzYWdlcywgc2V0TWVzc2FnZXNdID0gdXNlQXRvbTxNZXNzYWdlW11bXT4obWVzc2FnZXNBdG9tKTtcbiAgY29uc3Qgc2V0VXNlckV2ZW50cyA9IHVzZVNldEF0b20odXNlckV2ZW50c0F0b20pO1xuICBjb25zdCBzZXRTdWdnZXN0aW9ucyA9IHVzZVNldEF0b20oc3VnZ2VzdGlvbnNBdG9tKTtcbiAgY29uc3QgW3N1Z2dlc3Rpb25zTG9hZGluZywgc2V0U3VnZ2VzdGlvbnNMb2FkaW5nXSA9IHVzZUF0b208Ym9vbGVhbj4oXG4gICAgc3VnZ2VzdGlvbnNMb2FkaW5nQXRvbVxuICApO1xuICBjb25zdCBbcmVzcG9uc2VTdHJlYW1pbmcsIHNldFJlc3BvbnNlU3RyZWFtaW5nXSA9IHVzZUF0b208Ym9vbGVhbj4oXG4gICAgcmVzcG9uc2VTdHJlYW1pbmdBdG9tXG4gICk7XG4gIGNvbnN0IHNldFJlcXVlc3RGYWlsdXJlID0gdXNlU2V0QXRvbShyZXF1ZXN0RmFpbHVyZUF0b20pO1xuICBjb25zdCB1c2VyRXZlbnRzID0gdXNlQXRvbVZhbHVlKHVzZXJFdmVudFF1ZXVlQXRvbSk7XG4gIGNvbnN0IHVzZXJRdWV1ZUV2ZW50Q291bnQgPSB1c2VBdG9tVmFsdWUodXNlclF1ZXVlRXZlbnRDb3VudEF0b20pO1xuICBjb25zdCBtYXJrVXNlckV2ZW50c1Byb2Nlc3NlZCA9IHVzZVNldEF0b20ocHJvY2Vzc1VzZXJFdmVudEF0b20pO1xuICBjb25zdCBjbGVhclVzZXJFdmVudFF1ZXVlID0gdXNlU2V0QXRvbShjbGVhclVzZXJFdmVudEF0b20pO1xuICBjb25zdCB1c2VySWQgPSB1c2VBdG9tVmFsdWUodXNlcklkQXRvbSk7XG4gIGNvbnN0IGNoYXRJZCA9IHVzZUF0b21WYWx1ZShjaGF0SWRBdG9tKTtcbiAgY29uc3Qgc3VwcG9ydGVkRXZlbnQgPSB1c2VBdG9tVmFsdWUoc3VwcG9ydGVkRXZlbnRBdG9tKTtcbiAgLy8gVE9ETzogUmVwbGFjZSB3aXRoIGFjdHVhbCBvcmdJZCBmcm9tIHVzZUVudml2ZUNvbmZpZyBvciBOZXdPcmdDb25maWdDb250ZXh0IHdoZW4gYXZhaWxhYmxlXG4gIGNvbnN0IG9yZ0lkID0gXCJtb2NrLW9yZy1pZFwiO1xuXG4gIGNvbnN0IHZhcmlhbnRJbmZvID0gdXNlQXRvbVZhbHVlKHZhcmlhbnRJbmZvQXRvbSk7XG4gIGNvbnN0IHNldHRpbmdzQ29udGV4dCA9IHVzZVN5c3RlbVNldHRpbmdzQ29udGV4dCgpO1xuICBjb25zdCBtZXNzYWdlSW50ZXJjZXB0b3IgPSB1c2VNZXNzYWdlSW50ZXJjZXB0b3IoKTtcbiAgY29uc3QgaGFuZGxlU2VhcmNoUmVzdWx0cyA9IHVzZVNldEF0b20oaGFuZGxlU2VhcmNoUmVzdWx0c0F0b20pO1xuICBjb25zdCBzZXRTZWFyY2hJc0xvYWRpbmcgPSB1c2VTZXRBdG9tKGNoYXRTZWFyY2hJc0xvYWRpbmdBdG9tKTtcbiAgY29uc3QgeyB0cmFjayB9ID0gdXNlQW1wbGl0dWRlVHJhY2tpbmcoKTtcblxuICBjb25zdCBnZXRTdHJlYW1pbmdSZXNwb25zZXMgPSB1c2VDYWxsYmFjayhcbiAgICBhc3luYyAoXG4gICAgICBwYXlsb2FkOiBOZXh0TWVzc2FnZVJlcXVlc3RcbiAgICApOiBQcm9taXNlPHsgaGFzU2VhcmNoUmVzdWx0czogYm9vbGVhbiB9PiA9PiB7XG4gICAgICBsb2dQZXJmTWV0cmljKFBlcmZNZXRyaWNzRXZlbnRzLkZpcnN0UmVzcG9uc2VTdGFydGVkKTtcbiAgICAgIGNvbnN0IHN0cmVhbSA9IENvbW1lcmNlQXBpQ2xpZW50LmdldE5leHRSZXNwb25zZVN0cmVhbWluZyhwYXlsb2FkKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgc2V0UmVxdWVzdEZhaWx1cmUoZmFsc2UpO1xuXG4gICAgICAgIGNvbnN0IHsgaGFzU2VhcmNoUmVzdWx0cyB9ID0gYXdhaXQgcHJvY2Vzc1N0cmVhbWluZ1Jlc3BvbnNlKFxuICAgICAgICAgIHN0cmVhbSxcbiAgICAgICAgICBtZXNzYWdlSW50ZXJjZXB0b3IsXG4gICAgICAgICAgaGFuZGxlU2VhcmNoUmVzdWx0cyxcbiAgICAgICAgICBzZXRNZXNzYWdlcyxcbiAgICAgICAgICBzZXRTZWFyY2hJc0xvYWRpbmcsXG4gICAgICAgICAgY2hhdElkXG4gICAgICAgICk7XG5cbiAgICAgICAgcmV0dXJuIHsgaGFzU2VhcmNoUmVzdWx0cyB9O1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBoYW5kbGVTdHJlYW1pbmdFcnJvcihlLCBzZXRSZXF1ZXN0RmFpbHVyZSwgc2V0TWVzc2FnZXMpO1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgbG9nUGVyZk1ldHJpYyhQZXJmTWV0cmljc0V2ZW50cy5GaXJzdFJlc3BvbnNlQ29tcGxldGVkKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIFtcbiAgICAgIGxvZ1BlcmZNZXRyaWMsXG4gICAgICBzZXRSZXF1ZXN0RmFpbHVyZSxcbiAgICAgIG1lc3NhZ2VJbnRlcmNlcHRvcixcbiAgICAgIGhhbmRsZVNlYXJjaFJlc3VsdHMsXG4gICAgICBzZXRNZXNzYWdlcyxcbiAgICAgIHNldFNlYXJjaElzTG9hZGluZyxcbiAgICAgIGNoYXRJZCxcbiAgICBdXG4gICk7XG5cbiAgY29uc3QgZ2V0U3VnZ2VzdGlvbnMgPSB1c2VDYWxsYmFjayhhc3luYyAoKSA9PiB7XG4gICAgbG9nUGVyZk1ldHJpYyhQZXJmTWV0cmljc0V2ZW50cy5GaXJzdFN1Z2dlc3Rpb25zU3RhcnRlZCk7XG4gICAgc2V0U3VnZ2VzdGlvbnNMb2FkaW5nKHRydWUpO1xuICAgIHNldFN1Z2dlc3Rpb25zKFtdKTtcblxuICAgIGNvbnN0IHBheWxvYWRXaXRob3V0QXBwTG9hZGVkID0gY3JlYXRlUmVzcG9uc2VQYXlsb2FkKHtcbiAgICAgIHVzZXJFdmVudHM6IFtdLFxuICAgICAgZ2VuZXJhdGlvblBhcmFtczogc2V0dGluZ3NDb250ZXh0LmdlbmVyYXRpb25QYXJhbXMsXG4gICAgfSk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBDb21tZXJjZUFwaUNsaWVudC5nZXROZXh0U3VnZ2VzdGlvbnMoXG4gICAgICBwYXlsb2FkV2l0aG91dEFwcExvYWRlZFxuICAgICk7XG5cbiAgICAvLyBzb3J0IHRoZSBzdWdnZXN0aW9ucyBieSBzaG9ydGVzdCBsZW5ndGggc28gdGhlIHBpbGxzIGNhbiBiZSBzdGFja2VkIGhvcml6b250YWxseVxuICAgIHNldFN1Z2dlc3Rpb25zKFxuICAgICAgcmVzcG9uc2Uuc29ydCgoYSwgYikgPT4gYS5jb250ZW50Lmxlbmd0aCAtIGIuY29udGVudC5sZW5ndGgpXG4gICAgKTtcbiAgICBzZXRTdWdnZXN0aW9uc0xvYWRpbmcoZmFsc2UpO1xuICAgIGxvZ1BlcmZNZXRyaWMoUGVyZk1ldHJpY3NFdmVudHMuRmlyc3RTdWdnZXN0aW9uc0NvbXBsZXRlZCk7XG4gIH0sIFtcbiAgICBsb2dQZXJmTWV0cmljLFxuICAgIHNldFN1Z2dlc3Rpb25zTG9hZGluZyxcbiAgICBzZXRTdWdnZXN0aW9ucyxcbiAgICBzZXR0aW5nc0NvbnRleHQuZ2VuZXJhdGlvblBhcmFtcyxcbiAgXSk7XG5cbiAgY29uc3QgZ2V0UmVzcG9uc2VzID0gdXNlQ2FsbGJhY2soXG4gICAgYXN5bmMgKHBheWxvYWQ/OiBOZXh0TWVzc2FnZVJlcXVlc3QpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlcXVlc3RQYXlsb2FkID1cbiAgICAgICAgICBwYXlsb2FkID8/XG4gICAgICAgICAgY3JlYXRlUmVzcG9uc2VQYXlsb2FkKHtcbiAgICAgICAgICAgIHVzZXJFdmVudHMsXG4gICAgICAgICAgICBnZW5lcmF0aW9uUGFyYW1zOiBzZXR0aW5nc0NvbnRleHQuZ2VuZXJhdGlvblBhcmFtcyxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBzZXRSZXNwb25zZVN0cmVhbWluZyh0cnVlKTtcbiAgICAgICAgc2V0U3VnZ2VzdGlvbnMoW10pO1xuICAgICAgICBjb25zdCBzdGFydFRpbWVNcyA9IERhdGUubm93KCk7XG5cbiAgICAgICAgYXdhaXQgZ2V0U3RyZWFtaW5nUmVzcG9uc2VzKHJlcXVlc3RQYXlsb2FkKTtcblxuICAgICAgICByZWNvcmRBc3Npc3RhbnRSZXNwb25zZShzdGFydFRpbWVNcywgcmVxdWVzdFBheWxvYWQsIHRyYWNrKTtcbiAgICAgICAgYXdhaXQgZ2V0U3VnZ2VzdGlvbnMoKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIExvZ2dlci5sb2dFcnJvcihcIltzcGlmZnktYWldIGdldFJlc3BvbnNlcyBlcnJvclwiLCBlcnJvcik7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICAvLyBSZW1vdmUgc2VhcmNoIGxvYWRpbmcgbWFuYWdlbWVudCBmcm9tIGhlcmUgLSBpdCdzIG5vdyBoYW5kbGVkIGluZGVwZW5kZW50bHlcbiAgICAgICAgLy8gaW4gdGhlIHByb2Nlc3NTdHJlYW1pbmdSZXNwb25zZSBmdW5jdGlvbiB3aGVuIHNlYXJjaCByZXN1bHRzIGFyZSBkZXRlY3RlZFxuICAgICAgICBtYXJrVXNlckV2ZW50c1Byb2Nlc3NlZCh1c2VyRXZlbnRzLm1hcCgoeyBldmVudElkIH0pID0+IGV2ZW50SWQpKTtcbiAgICAgICAgc2V0VXNlckhhc1JlcGxpZWQoZmFsc2UpO1xuICAgICAgICBzZXRSZXNwb25zZVN0cmVhbWluZyhmYWxzZSk7XG4gICAgICB9XG4gICAgfSxcbiAgICBbXG4gICAgICB1c2VyRXZlbnRzLFxuICAgICAgc2V0dGluZ3NDb250ZXh0LmdlbmVyYXRpb25QYXJhbXMsXG4gICAgICBzZXRSZXNwb25zZVN0cmVhbWluZyxcbiAgICAgIHNldFN1Z2dlc3Rpb25zLFxuICAgICAgZ2V0U3RyZWFtaW5nUmVzcG9uc2VzLFxuICAgICAgbWFya1VzZXJFdmVudHNQcm9jZXNzZWQsXG4gICAgICBnZXRTdWdnZXN0aW9ucyxcbiAgICAgIHNldFVzZXJIYXNSZXBsaWVkLFxuICAgICAgdHJhY2ssXG4gICAgXVxuICApO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3QgcHJvY2Vzc1VzZXJFdmVudHMgPSBhc3luYyAoKSA9PiB7XG4gICAgICBpZiAocmVzcG9uc2VTdHJlYW1pbmcgfHwgIXdpZGdldEluaXRpYWxpemVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICAodmFyaWFudEluZm8udmFyaWFudCA9PT0gXCJwZHBcIiAmJiAhdmFyaWFudEluZm8ucHJvZHVjdElkKSB8fFxuICAgICAgICAodmFyaWFudEluZm8udmFyaWFudCA9PT0gXCJwbHBcIiAmJiAhdmFyaWFudEluZm8ucGxwSWQpIHx8XG4gICAgICAgICh2YXJpYW50SW5mby52YXJpYW50ID09PSBcInBhZ2VfdmlzaXRcIiAmJiAhdmFyaWFudEluZm8udXJsKVxuICAgICAgKSB7XG4gICAgICAgIExvZ2dlci5sb2dEZWJ1ZyhcbiAgICAgICAgICBcIltzcGlmZnktYWldIHZhcmlhbnRJbmZvIGhhcyBpbnZhbGlkIHZhbHVlcywgc2tpcHBpbmcuLi5cIixcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXJpYW50SW5mbyxcbiAgICAgICAgICAgIHN1cHBvcnRlZEV2ZW50LFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBMb2dnZXIubG9nRGVidWcoXG4gICAgICAgIGBBc3Npc3RhbnRzIFR1cm4gaXNfY3VycmVudGx5X3N0cmVhbWluZz0ke3Jlc3BvbnNlU3RyZWFtaW5nfSBpbml0aWFsaXplZD0ke3dpZGdldEluaXRpYWxpemVkfWBcbiAgICAgICk7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBnZXRSZXNwb25zZXMoKTtcbiAgICAgICAgTG9nZ2VyLmxvZ0luZm8oYEFzc2lzdGFudHMgVHVybiBbZmluaXNoZWRdYCk7XG4gICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICBMb2dnZXIubG9nRXJyb3IoXCJbc3BpZmZ5LWFpXSBBc3Npc3RhbnRzIFR1cm4gZXJyb3JcIiwgZXJyb3IpO1xuICAgICAgfVxuICAgIH07XG4gICAgaWYgKHVzZXJRdWV1ZUV2ZW50Q291bnQgPiAwKSB7XG4gICAgICBwcm9jZXNzVXNlckV2ZW50cygpO1xuICAgIH1cbiAgfSwgW1xuICAgIGdldFJlc3BvbnNlcyxcbiAgICByZXNwb25zZVN0cmVhbWluZyxcbiAgICB1c2VyUXVldWVFdmVudENvdW50LFxuICAgIHdpZGdldEluaXRpYWxpemVkLFxuICAgIHZhcmlhbnRJbmZvLFxuICAgIHN1cHBvcnRlZEV2ZW50LFxuICBdKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICh3aWRnZXRJbml0aWFsaXplZCB8fCByZXNwb25zZVN0cmVhbWluZykge1xuICAgICAgTG9nZ2VyLmxvZ0RlYnVnKFxuICAgICAgICBgW3NwaWZmeS1haV0gaW5pdGlhbGl6ZVdpZGdldCBbc2tpcHBlZF0gaXNfY3VycmVudGx5X3N0cmVhbWluZz0ke3Jlc3BvbnNlU3RyZWFtaW5nfSBpc19pbml0aWFsaXplZD0ke3dpZGdldEluaXRpYWxpemVkfWBcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgaHlkcmF0ZUNoYXQgPSBhc3luYyAoKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBMb2dnZXIubG9nRGVidWcoXG4gICAgICAgICAgYFtzcGlmZnktYWldIGluaXRpYWxpemVXaWRnZXQgaXNfY3VycmVudGx5X3N0cmVhbWluZz0ke3Jlc3BvbnNlU3RyZWFtaW5nfSBpc19pbml0aWFsaXplZD0ke3dpZGdldEluaXRpYWxpemVkfWBcbiAgICAgICAgKTtcbiAgICAgICAgLy8gb24gbW91bnQsIHRyeSB0byBnZXQgdGhlIHJlc3BvbnNlcyBmcm9tIGFuIGFjdGl2ZSBzZXNzaW9uIGlmIG9uZSBleGlzdHNcbiAgICAgICAgaWYgKCFvcmdJZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm9yZ0lkIGlzIG5vdCBhdmFpbGFibGVcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgeyBtZXNzYWdlczogZXhpc3RpbmdNZXNzYWdlcywgdXNlckV2ZW50cyB9ID1cbiAgICAgICAgICBhd2FpdCBDb21tZXJjZUFwaUNsaWVudC5nZXRSZXNwb25zZXMob3JnSWQsIGNoYXRJZCwgdXNlcklkKTtcbiAgICAgICAgc2V0TWVzc2FnZXMoWy4uLmV4aXN0aW5nTWVzc2FnZXNdKTtcbiAgICAgICAgc2V0VXNlckV2ZW50cyhbLi4udXNlckV2ZW50c10pO1xuICAgICAgICBnZXRSZXNwb25zZXMoKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIC8vIG5vIGFjdGl2ZSBjaGF0IHNlc3Npb24gd2FzIGZvdW5kLCBzdGFydCBhIG5ldyBvbmVcbiAgICAgICAgTG9nZ2VyLmxvZ0luZm8oXG4gICAgICAgICAgYEluaXQgY2hhdCBbZXhjZXB0aW9uXSBjaGF0X2lkPSR7Y2hhdElkfSBlcnJvcj0ke2Vycm9yfWAsXG4gICAgICAgICAgZXJyb3JcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgU2Vzc2lvblJlc3RhcnRSZXF1aXJlZCkge1xuICAgICAgICAgIGNvbnN0IGFwcExvYWRlZEV2ZW50ID0gY3JlYXRlQXBwTG9hZGVkRXZlbnQoKTtcbiAgICAgICAgICBjb25zdCB2aXNpdEV2ZW50ID0gY3JlYXRlVmlzaXRVc2VyRXZlbnQoeyB2YXJpYW50SW5mbyB9KTtcbiAgICAgICAgICBzZXRNZXNzYWdlcyhbXSk7XG4gICAgICAgICAgY2xlYXJVc2VyRXZlbnRRdWV1ZSgpO1xuICAgICAgICAgIGlmICh2aXNpdEV2ZW50KSB7XG4gICAgICAgICAgICBjb25zdCBwYXlsb2FkID0gY3JlYXRlUmVzcG9uc2VQYXlsb2FkKHtcbiAgICAgICAgICAgICAgdXNlckV2ZW50czogW2FwcExvYWRlZEV2ZW50LCB2aXNpdEV2ZW50XSxcbiAgICAgICAgICAgICAgZ2VuZXJhdGlvblBhcmFtczogc2V0dGluZ3NDb250ZXh0LmdlbmVyYXRpb25QYXJhbXMsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGdldFJlc3BvbnNlcyhwYXlsb2FkKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHNldFdpZGdldEluaXRpYWxpemVkKHRydWUpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBoeWRyYXRlQ2hhdCgpO1xuICB9LCBbXSk7XG5cbiAgY29uc3Qgb25Gb2N1cyA9IHVzZUNhbGxiYWNrKGFzeW5jICgpID0+IHtcbiAgICB0cnkge1xuICAgICAgaWYgKCFyZXNwb25zZVN0cmVhbWluZyAmJiAhc3VnZ2VzdGlvbnNMb2FkaW5nICYmIG9yZ0lkKSB7XG4gICAgICAgIGNvbnN0IHsgbWVzc2FnZXM6IGV4aXN0aW5nTWVzc2FnZXMgfSA9XG4gICAgICAgICAgYXdhaXQgQ29tbWVyY2VBcGlDbGllbnQuZ2V0UmVzcG9uc2VzKG9yZ0lkLCBjaGF0SWQsIHVzZXJJZCk7XG5cbiAgICAgICAgaWYgKGV4aXN0aW5nTWVzc2FnZXMubGVuZ3RoID4gbWVzc2FnZXMubGVuZ3RoKSB7XG4gICAgICAgICAgc2V0TWVzc2FnZXMoWy4uLmV4aXN0aW5nTWVzc2FnZXNdKTtcbiAgICAgICAgICAvLyBUT0RPOiBJcyB0aGlzIGJ1ZyBoYWNrIHN0aWxsIG5lY2Vzc2FyeT9cbiAgICAgICAgICAvLyBJZiBpdCBpcywgY29tZSB1cCB3aXRoIGEgYmV0dGVyIHNvbHV0aW9uIGZvciBpdFxuICAgICAgICAgIC8vIH0gZWxzZSBpZiAoZXhpc3RpbmdNZXNzYWdlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAvLyAgIC8vIGlmIHRoZXJlIHdhcyBhbiBlcnJvciBkdXJpbmcgdGhlIGluaXRpYWxpemF0aW9uIG9mIGEgbmV3IHNlc3Npb24sIHRoZSBzZXNzaW9uIHdvdWxkIGJlXG4gICAgICAgICAgLy8gICAvLyBjcmVhdGVkIGluIHRoZSBiYWNrZW5kIGJ1dCB3aXRob3V0IGFueSBtZXNzYWdlcy4gUmV0cnkgdGhlIG5leHRfcmVzcG9uc2VzIHJlcXVlc3Qgd2l0aFxuICAgICAgICAgIC8vICAgLy8gdGhlIGN1cnJlbnQgc2V0IG9mIHBhcmFtZXRlcnMgdG8gXCJqdW1wc3RhcnRcIiB0aGUgc2Vzc2lvblxuICAgICAgICAgIC8vICAgdHJpZ2dlckdldFJlc3BvbnNlQ2FsbCgnb25Gb2N1cycpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIExvZ2dlci5sb2dFcnJvcihcIltzcGlmZnktYWldIG9uRm9jdXMgZXJyb3JcIiwgZXJyb3IpO1xuICAgIH1cbiAgfSwgW1xuICAgIHJlc3BvbnNlU3RyZWFtaW5nLFxuICAgIHN1Z2dlc3Rpb25zTG9hZGluZyxcbiAgICBvcmdJZCxcbiAgICBjaGF0SWQsXG4gICAgdXNlcklkLFxuICAgIG1lc3NhZ2VzLmxlbmd0aCxcbiAgICBzZXRNZXNzYWdlcyxcbiAgXSk7XG5cbiAgLy8gbGlzdGVuIGZvciBwYWdlIGZvY3VzIHRvIGdldCBsYXRlc3QgbWVzc2FnZXMgZnJvbSB0aGUgc2VydmVyXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJmb2N1c1wiLCBvbkZvY3VzKTtcblxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImZvY3VzXCIsIG9uRm9jdXMpO1xuICAgIH07XG4gIH0sIFtvbkZvY3VzXSk7XG5cbiAgY29uc3QgY2hhdENvbnRleHQgPSB1c2VNZW1vKCgpID0+ICh7fSksIFtdKTtcblxuICByZXR1cm4gKFxuICAgIDxDaGF0Q29udGV4dC5Qcm92aWRlciB2YWx1ZT17Y2hhdENvbnRleHR9PntjaGlsZHJlbn08L0NoYXRDb250ZXh0LlByb3ZpZGVyPlxuICApO1xufTtcblxuZXhwb3J0IHsgQ2hhdENvbnRleHQsIENoYXRDb250ZXh0UHJvdmlkZXIgfTtcbmV4cG9ydCB0eXBlIHsgQ2hhdENvbnRleHRQYXJhbXMgfTtcbiIsImltcG9ydCBSZWFjdCwgeyBSZWFjdE5vZGUgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IHVzZU5ld09yZ0NvbmZpZyB9IGZyb20gXCJzcmMvaG9va3NcIjtcblxuaW50ZXJmYWNlIEVudml2ZUNzc1Byb3ZpZGVyUHJvcHMge1xuICBjaGlsZHJlbjogUmVhY3ROb2RlO1xufVxuXG5leHBvcnQgY29uc3QgRW52aXZlQ3NzUHJvdmlkZXI6IFJlYWN0LkZDPEVudml2ZUNzc1Byb3ZpZGVyUHJvcHM+ID0gKHtcbiAgY2hpbGRyZW4sXG59KSA9PiB7XG4gIGNvbnN0IHsgY29sb3JzQ29uZmlnLCBmcm9udGVuZENvbmZpZywgbG9hZGluZyB9ID0gdXNlTmV3T3JnQ29uZmlnKCk7XG4gIGxldCBtZXJjaGFudFRoZW1lQ3NzID0gYCoge31gO1xuICBpZiAoY29sb3JzQ29uZmlnICYmICFsb2FkaW5nKSB7XG4gICAgbWVyY2hhbnRUaGVtZUNzcyA9IGBcbioge1xuICAtLXNwaWZmeS1jb2xvcnMtdGV4dC1wcmltYXJ5OiAke2NvbG9yc0NvbmZpZy50ZXh0UHJpbWFyeX07XG4gIC0tc3BpZmZ5LWNvbG9ycy10ZXh0LXNlY29uZGFyeTogJHtjb2xvcnNDb25maWcudGV4dFNlY29uZGFyeX07XG4gIC0tc3BpZmZ5LWNvbG9ycy10ZXh0LWFjY2VudDogJHtjb2xvcnNDb25maWcudGV4dEFjY2VudH07XG4gIC0tc3BpZmZ5LWNvbG9ycy10ZXh0LWxpbms6ICR7Y29sb3JzQ29uZmlnLnRleHRMaW5rfTtcbiAgLS1zcGlmZnktY29sb3JzLXRleHQtbGlnaHQ6ICR7Y29sb3JzQ29uZmlnLnRleHRMaWdodH07XG4gIC0tc3BpZmZ5LWNvbG9ycy1iYWNrZ3JvdW5kLXByaW1hcnk6ICR7Y29sb3JzQ29uZmlnLmJhY2tncm91bmRQcmltYXJ5fTtcbiAgLS1zcGlmZnktY29sb3JzLWJhY2tncm91bmQtc2Vjb25kYXJ5OiAke2NvbG9yc0NvbmZpZy5iYWNrZ3JvdW5kU2Vjb25kYXJ5fTtcbiAgLS1zcGlmZnktY29sb3JzLWJhY2tncm91bmQtc2Vjb25kYXJ5LWRhcms6ICR7Y29sb3JzQ29uZmlnLmJhY2tncm91bmRTZWNvbmRhcnlEYXJrfTtcbiAgLS1zcGlmZnktY29sb3JzLWJhY2tncm91bmQtdGVydGlhcnk6ICR7Y29sb3JzQ29uZmlnLmJhY2tncm91bmRUZXJ0aWFyeX07XG4gIC0tc3BpZmZ5LWNvbG9ycy1iYWNrZ3JvdW5kLWRhcms6ICR7Y29sb3JzQ29uZmlnLmJhY2tncm91bmREYXJrfTtcbiAgLS1zcGlmZnktY29sb3JzLWJhY2tncm91bmQtbGlnaHQ6ICR7Y29sb3JzQ29uZmlnLmJhY2tncm91bmRMaWdodH07XG4gIC0tc3BpZmZ5LWNvbG9ycy1iYWNrZ3JvdW5kLXNhdHVyYXRlZDogJHtjb2xvcnNDb25maWcuYmFja2dyb3VuZFNhdHVyYXRlZH07XG4gIC0tc3BpZmZ5LWNvbG9ycy1ib3JkZXItbGlnaHQ6ICR7Y29sb3JzQ29uZmlnLmJvcmRlckxpZ2h0fTtcbiAgLS1zcGlmZnktY29sb3JzLWJvcmRlci1tZWRpdW06ICR7Y29sb3JzQ29uZmlnLmJvcmRlck1lZGl1bX07XG4gIC0tc3BpZmZ5LWNvbG9ycy1ib3JkZXItZGFyazogJHtjb2xvcnNDb25maWcuYm9yZGVyRGFya307XG4gIC0tc3BpZmZ5LWNvbG9ycy1ib3JkZXItb3V0bGluZTogJHtjb2xvcnNDb25maWcuYm9yZGVyT3V0bGluZX07XG4gIC0tc3BpZmZ5LWNvbG9ycy1hY2NlbnQtcHJpbWFyeTogJHtjb2xvcnNDb25maWcuYWNjZW50UHJpbWFyeX07XG4gIC0tc3BpZmZ5LWNvbG9ycy1hY2NlbnQtc2Vjb25kYXJ5OiAke2NvbG9yc0NvbmZpZy5hY2NlbnRTZWNvbmRhcnl9O1xufWA7XG4gIH1cbiAgY29uc29sZS5sb2coZnJvbnRlbmRDb25maWcpO1xuICByZXR1cm4gKFxuICAgIDw+XG4gICAgICB7ZnJvbnRlbmRDb25maWcgPyAoXG4gICAgICAgIDxzdHlsZSBpZD1cIm1lcmNoYW50LWNzcy1vdmVycmlkZXNcIj57YCR7ZnJvbnRlbmRDb25maWcubWVyY2hhbnRPdmVycmlkZUNzc31gfTwvc3R5bGU+XG4gICAgICApIDogbnVsbH1cbiAgICAgIHtjb2xvcnNDb25maWcgPyAoXG4gICAgICAgIDxzdHlsZSBpZD1cIm1lcmNoYW50LWNzcy1jb2xvcnNcIj57YCR7bWVyY2hhbnRUaGVtZUNzc31gfTwvc3R5bGU+XG4gICAgICApIDogbnVsbH1cblxuICAgICAge2NoaWxkcmVufVxuICAgIDwvPlxuICApO1xufTtcbiIsImltcG9ydCB7IHVzZUF0b21WYWx1ZSB9IGZyb20gXCJqb3RhaVwiO1xuaW1wb3J0IHtcbiAgRGlzcGF0Y2gsXG4gIFJlYWN0Tm9kZSxcbiAgU2V0U3RhdGVBY3Rpb24sXG4gIGNyZWF0ZUNvbnRleHQsXG4gIHVzZU1lbW8sXG4gIHVzZVN0YXRlLFxufSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IEdlbmVyYXRpb25QYXJhbXMgfSBmcm9tIFwic3JjL2FwcGxpY2F0aW9uL21vZGVsc1wiO1xuaW1wb3J0IHsgYmFzZVVybEF0b20gfSBmcm9tIFwic3JjL2F0b21zL2Vudml2ZS9lbnZpdmVDb25maWdcIjtcblxuLy8gVE9ETzogUmVmYWN0b3IgdGhpcyB0byBhIGNvbW1vbiBzZXJ2aWNlIHRoYXQgaGFuZGxlcyBxdWVyeSBwYXJhbXMgKGFuZCBzcGlmZnkgdmFyaWFibGVzIGFsbCB0b2dldGhlcilcbmNvbnN0IGdldENoYXRNb2RlbE5hbWUgPSAoKSA9PiB7XG4gIGNvbnN0IHVybE9iaiA9IG5ldyBVUkwod2luZG93LmxvY2F0aW9uLmhyZWYpO1xuICBjb25zdCBwYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHVybE9iai5zZWFyY2gpO1xuICBjb25zdCBwYXJhbXNPYmogPSBPYmplY3QuZnJvbUVudHJpZXMocGFyYW1zLmVudHJpZXMoKSk7XG4gIHJldHVybiBwYXJhbXNPYmoubGxtX21vZGVsX25hbWU7XG59O1xuXG5jb25zdCBkZWZhdWx0R2VuZXJhdGlvblBhcmFtczogR2VuZXJhdGlvblBhcmFtcyA9IHtcbiAgc3RyZWFtOiB0cnVlLFxuICBudW1TdWdnZXN0aW9uczogMyxcbiAgbW9kZWw6IGdldENoYXRNb2RlbE5hbWUoKSxcbn07XG5cbmludGVyZmFjZSBTeXN0ZW1TZXR0aW5nc0NvbnRleHRQYXJhbXMge1xuICBnZW5lcmF0aW9uUGFyYW1zPzogR2VuZXJhdGlvblBhcmFtcztcbiAgc2hvd0RlYnVnQmFyPzogYm9vbGVhbjtcbiAgZW5kcG9pbnRVUkw/OiBzdHJpbmc7XG4gIHNldEdlbmVyYXRpb25QYXJhbXM6IERpc3BhdGNoPFNldFN0YXRlQWN0aW9uPEdlbmVyYXRpb25QYXJhbXMgfCB1bmRlZmluZWQ+Pjtcbn1cblxuaW50ZXJmYWNlIFN5c3RlbVNldHRpbmdzQ29udGV4dFByb3ZpZGVyUHJvcHMge1xuICBjaGlsZHJlbjogUmVhY3ROb2RlO1xuICBnZW5lcmF0aW9uUGFyYW1zPzogR2VuZXJhdGlvblBhcmFtcztcbiAgc2hvd0RlYnVnQmFyPzogYm9vbGVhbjtcbn1cblxuY29uc3QgU3lzdGVtU2V0dGluZ3NDb250ZXh0ID0gY3JlYXRlQ29udGV4dDxcbiAgU3lzdGVtU2V0dGluZ3NDb250ZXh0UGFyYW1zIHwgdW5kZWZpbmVkXG4+KHVuZGVmaW5lZCk7XG5cbmNvbnN0IFN5c3RlbVNldHRpbmdzQ29udGV4dFByb3ZpZGVyID0gKHtcbiAgY2hpbGRyZW4sXG4gIGdlbmVyYXRpb25QYXJhbXMsXG4gIHNob3dEZWJ1Z0Jhcixcbn06IFN5c3RlbVNldHRpbmdzQ29udGV4dFByb3ZpZGVyUHJvcHMpID0+IHtcbiAgY29uc3QgW3BhcmFtcywgc2V0UGFyYW1zXSA9IHVzZVN0YXRlPEdlbmVyYXRpb25QYXJhbXMgfCB1bmRlZmluZWQ+KFxuICAgICgpID0+IGdlbmVyYXRpb25QYXJhbXMgPz8gZGVmYXVsdEdlbmVyYXRpb25QYXJhbXNcbiAgKTtcbiAgY29uc3QgZW5kcG9pbnRVUkwgPSB1c2VBdG9tVmFsdWUoYmFzZVVybEF0b20pO1xuICBjb25zdCBzZXR0aW5nc0NvbnRleHRWYWx1ZXMgPSB1c2VNZW1vKFxuICAgICgpID0+ICh7XG4gICAgICBnZW5lcmF0aW9uUGFyYW1zOiBwYXJhbXMsXG4gICAgICBzaG93RGVidWdCYXIsXG4gICAgICBzZXRHZW5lcmF0aW9uUGFyYW1zOiBzZXRQYXJhbXMsXG4gICAgICBlbmRwb2ludFVSTCxcbiAgICB9KSxcbiAgICBbZ2VuZXJhdGlvblBhcmFtcywgZW5kcG9pbnRVUkwsIHNob3dEZWJ1Z0Jhcl1cbiAgKTtcblxuICByZXR1cm4gKFxuICAgIDxTeXN0ZW1TZXR0aW5nc0NvbnRleHQuUHJvdmlkZXIgdmFsdWU9e3NldHRpbmdzQ29udGV4dFZhbHVlc30+XG4gICAgICB7Y2hpbGRyZW59XG4gICAgPC9TeXN0ZW1TZXR0aW5nc0NvbnRleHQuUHJvdmlkZXI+XG4gICk7XG59O1xuXG5leHBvcnQge1xuICBTeXN0ZW1TZXR0aW5nc0NvbnRleHRQcm92aWRlcixcbiAgU3lzdGVtU2V0dGluZ3NDb250ZXh0LFxuICBkZWZhdWx0R2VuZXJhdGlvblBhcmFtcyxcbn07XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQVVBLE1BQU0sc0NBQWtELEtBQUs7QUFFN0QsTUFBYUEsZUFBd0QsRUFDbkUsZUFDSTtDQUVKLE1BQU0saUNBRCtCQyxnQ0FBVyxJQUNkO0NBRWxDLE1BQU0sOENBQW1DO0FBQ3ZDLFNBQU87SUFDTixDQUFDLE9BQU8sQ0FBQztDQUVaLE1BQU0sc0NBQ0gsV0FBbUIsaUJBQXlCO0FBQzNDLFNBQU8sR0FBRyxnQkFBZ0IsQ0FBQyxVQUFVLGFBQWEsR0FBRztJQUV2RCxDQUFDLGVBQWUsQ0FDakI7Q0FFRCxNQUFNLGtDQUNHO0VBQ0w7RUFDQTtFQUNBO0VBQ0QsR0FDRDtFQUFDO0VBQVE7RUFBZ0I7RUFBWSxDQUN0QztBQUVELFFBQU8sMkNBQUMsV0FBVztFQUFnQjtFQUFRO0dBQStCOztBQUc1RSxNQUFhLGVBQWU7Q0FDMUIsTUFBTSxnQ0FBcUIsV0FBVztBQUN0QyxLQUFJLENBQUMsUUFDSCxPQUFNLElBQUksTUFBTSwyQ0FBMkM7QUFFN0QsUUFBTzs7Ozs7QUM5Q1QsSUFBYSx5QkFBYixjQUE0QyxNQUFNO0NBQ2hELGNB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
|