@envive-ai/react-hooks 0.2.6 → 0.2.7-arthur-2
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-BfrGpiGk.js → NewOrgConfig-BVByiYPp.js} +2 -2
- package/dist/{NewOrgConfig-BxSuoP9C.cjs → NewOrgConfig-CInGtTV6.cjs} +2 -2
- package/dist/{SystemSettingsContext-Bkoiobdv.cjs → SystemSettingsContext-150LTxIk.cjs} +2 -2
- package/dist/{SystemSettingsContext-B8X_Dvw2.js → SystemSettingsContext-ei5B0dxO.js} +2 -2
- package/dist/{TrackComponentVisibleEvent-DMuX-byo.cjs → TrackComponentVisibleEvent-C7-nnBks.cjs} +2 -2
- package/dist/{TrackComponentVisibleEvent-DwfGqNTx.js → TrackComponentVisibleEvent-CuwSLbug.js} +2 -2
- package/dist/amplitudeContext-BBQ1ATA3.js +265 -0
- package/dist/amplitudeContext-BItT9HmT.js +1 -0
- package/dist/amplitudeContext-C-0-DDk3.cjs +287 -0
- package/dist/{amplitudeContext-B73xamNe.d.cts → amplitudeContext-CCVyp5RU.d.cts} +1 -1
- package/dist/amplitudeContext-DPtyVv3Q.cjs +0 -0
- package/dist/{amplitudeContext-CiO9T9c-.d.ts → amplitudeContext-DcRur97Z.d.ts} +1 -1
- package/dist/{api-bHEYmSiT.js → api-BWSsazAG.js} +3 -3
- package/dist/{api-BvygKEiX.cjs → api-DeW6rHj3.cjs} +3 -3
- package/dist/{app-Aqkm_SlS.js → app-C_Y-57U5.js} +3 -4
- package/dist/{app-BQw_-JGl.cjs → app-XEFPotoH.cjs} +3 -4
- package/dist/application/models/graphql/index.cjs +4 -3
- package/dist/application/models/graphql/index.d.cts +2 -2
- package/dist/application/models/graphql/index.d.ts +2 -2
- package/dist/application/models/graphql/index.js +3 -3
- package/dist/application/models/guards/api/index.cjs +3 -3
- package/dist/application/models/guards/api/index.d.cts +2 -1
- package/dist/application/models/guards/api/index.d.ts +2 -1
- package/dist/application/models/guards/api/index.js +3 -3
- package/dist/application/models/guards/utils.cjs +1 -1
- package/dist/application/models/guards/utils.d.cts +1 -1
- package/dist/application/models/guards/utils.d.ts +1 -1
- package/dist/application/models/guards/utils.js +1 -1
- package/dist/application/models/index.cjs +9 -9
- package/dist/application/models/index.d.cts +11 -10
- package/dist/application/models/index.d.ts +11 -10
- package/dist/application/models/index.js +8 -8
- package/dist/application/models/variantInfo/index.d.cts +1 -1
- package/dist/application/models/variantInfo/index.d.ts +1 -1
- package/dist/application/utils/index.cjs +17 -17
- package/dist/application/utils/index.d.cts +16 -15
- package/dist/application/utils/index.d.ts +16 -15
- package/dist/application/utils/index.js +17 -17
- package/dist/{atomStore-CmZbgQHc.cjs → atomStore-8ppNkJ_n.cjs} +1 -1
- package/dist/{atomStore-DEcDhiLp.js → atomStore-BLYJ2ZoQ.js} +1 -1
- package/dist/atoms/app/index.cjs +12 -12
- package/dist/atoms/app/index.d.cts +19 -18
- package/dist/atoms/app/index.d.ts +14 -13
- package/dist/atoms/app/index.js +12 -12
- package/dist/atoms/atomStore/index.cjs +1 -1
- package/dist/atoms/atomStore/index.js +1 -1
- package/dist/atoms/chat/index.cjs +18 -18
- package/dist/atoms/chat/index.d.cts +39 -38
- package/dist/atoms/chat/index.d.ts +13 -12
- package/dist/atoms/chat/index.js +18 -18
- package/dist/atoms/globalSearch/index.d.cts +5 -5
- package/dist/atoms/org/index.cjs +1 -1
- package/dist/atoms/org/index.d.cts +30 -29
- package/dist/atoms/org/index.d.ts +30 -29
- package/dist/atoms/org/index.js +1 -1
- package/dist/atoms/search/index.cjs +20 -20
- package/dist/atoms/search/index.d.cts +13 -12
- package/dist/atoms/search/index.d.ts +13 -12
- package/dist/atoms/search/index.js +20 -20
- package/dist/atoms/search/types.d.cts +4 -2
- package/dist/atoms/search/types.d.ts +4 -2
- package/dist/{cdnContext-Cd0Kvt6g.cjs → cdnContext-Bzqk0s2M.cjs} +2 -2
- package/dist/{cdnContext-D8pHA9gh.js → cdnContext-CTC-zBtx.js} +2 -2
- package/dist/{chat-U1IgKNij.js → chat-Bzay7QnI.js} +9 -9
- package/dist/{chat-DwNALtox.cjs → chat-Ckd1b_z_.cjs} +14 -8
- package/dist/{chat-EJbfGWRr.js → chat-ClvJ9xEj.js} +1 -1
- package/dist/{chat-CJ9D8n7g.cjs → chat-DCGriB7h.cjs} +1 -1
- package/dist/{chatElementDisplayLocation-DWmfNX_u.d.cts → chatElementDisplayLocation-B7vr33eG.d.cts} +1 -1
- package/dist/{chatElementDisplayLocation-DbmdwAff.d.ts → chatElementDisplayLocation-D4XF0UfI.d.ts} +1 -1
- package/dist/{chatSearch-DtE2cUQw.cjs → chatSearch-Bev4ZI8Z.cjs} +4 -4
- package/dist/{chatSearch-Bb2SMr9X.js → chatSearch-DNaGtQyx.js} +4 -4
- package/dist/{chatState-BXBN-12W.js → chatState-CcCvgmSM.js} +3 -3
- package/dist/{chatState-B3Dyrd9M.cjs → chatState-OkYPVghN.cjs} +3 -3
- package/dist/{commerce-api-DXbnMNT8.js → commerce-api-ml5fkEuk.js} +9 -8
- package/dist/{commerce-api-Dx02FCQ7.cjs → commerce-api-sQtLuwTh.cjs} +9 -8
- package/dist/{common-CuwWqIJ1.cjs → common-DQPvV_S_.cjs} +1 -1
- package/dist/{common-Df2bwzd2.js → common-c_4eX0qn.js} +1 -1
- package/dist/{components-QGCWJ26c.js → components-CDpaMUjK.js} +1 -1
- package/dist/{components-BCfFLf9X.cjs → components-DKwVHIjq.cjs} +1 -1
- package/dist/config/index.cjs +4 -4
- package/dist/config/index.d.cts +4 -4
- package/dist/config/index.d.ts +4 -4
- package/dist/config/index.js +4 -4
- 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/common/index.cjs +1 -1
- package/dist/config/locators/components/common/index.d.cts +1 -1
- package/dist/config/locators/components/common/index.d.ts +1 -1
- package/dist/config/locators/components/common/index.js +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/index.cjs +4 -4
- package/dist/config/locators/index.d.cts +4 -4
- package/dist/config/locators/index.d.ts +4 -4
- package/dist/config/locators/index.js +4 -4
- package/dist/contexts/amplitudeContext/index.cjs +17 -16
- package/dist/contexts/amplitudeContext/index.d.cts +1 -1
- package/dist/contexts/amplitudeContext/index.d.ts +1 -1
- package/dist/contexts/amplitudeContext/index.js +17 -16
- package/dist/contexts/cdnContext/index.cjs +4 -4
- package/dist/contexts/cdnContext/index.js +4 -4
- package/dist/contexts/chatContext/index.cjs +25 -25
- package/dist/contexts/chatContext/index.d.cts +2 -2
- package/dist/contexts/chatContext/index.d.ts +2 -2
- package/dist/contexts/chatContext/index.js +25 -25
- package/dist/contexts/enviveConfigContext/index.cjs +4 -4
- package/dist/contexts/enviveConfigContext/index.d.cts +3 -3
- package/dist/contexts/enviveConfigContext/index.d.ts +3 -3
- package/dist/contexts/enviveConfigContext/index.js +4 -4
- package/dist/contexts/enviveCssContext/index.cjs +15 -15
- package/dist/contexts/enviveCssContext/index.js +15 -15
- package/dist/contexts/featureFlagContext/index.cjs +6 -6
- package/dist/contexts/featureFlagContext/index.d.cts +3 -3
- package/dist/contexts/featureFlagContext/index.d.ts +3 -3
- package/dist/contexts/featureFlagContext/index.js +6 -6
- package/dist/contexts/featureFlagServiceContext/index.cjs +3 -3
- package/dist/contexts/featureFlagServiceContext/index.d.cts +4 -4
- package/dist/contexts/featureFlagServiceContext/index.d.ts +4 -4
- package/dist/contexts/featureFlagServiceContext/index.js +3 -3
- package/dist/contexts/graphqlContext/index.cjs +11 -11
- package/dist/contexts/graphqlContext/index.d.cts +13 -12
- package/dist/contexts/graphqlContext/index.d.ts +13 -12
- package/dist/contexts/graphqlContext/index.js +11 -11
- package/dist/contexts/localStorageContext/index.cjs +2 -2
- package/dist/contexts/localStorageContext/index.js +2 -2
- package/dist/contexts/newOrgConfigContext/index.cjs +14 -14
- package/dist/contexts/newOrgConfigContext/index.d.cts +14 -13
- package/dist/contexts/newOrgConfigContext/index.d.ts +14 -13
- package/dist/contexts/newOrgConfigContext/index.js +14 -14
- package/dist/contexts/searchContext/index.cjs +18 -18
- package/dist/contexts/searchContext/index.d.cts +1 -1
- package/dist/contexts/searchContext/index.d.ts +1 -1
- package/dist/contexts/searchContext/index.js +18 -18
- package/dist/contexts/sessionStorageContext/index.cjs +2 -2
- package/dist/contexts/sessionStorageContext/index.js +2 -2
- package/dist/contexts/shopifyUrlContext/index.cjs +2 -2
- package/dist/contexts/shopifyUrlContext/index.d.cts +3 -3
- package/dist/contexts/shopifyUrlContext/index.d.ts +3 -3
- package/dist/contexts/shopifyUrlContext/index.js +2 -2
- package/dist/contexts/systemSettingsContext/index.cjs +4 -4
- package/dist/contexts/systemSettingsContext/index.d.cts +16 -15
- package/dist/contexts/systemSettingsContext/index.d.ts +16 -15
- package/dist/contexts/systemSettingsContext/index.js +4 -4
- package/dist/contexts/types.cjs +1 -1
- package/dist/contexts/types.d.cts +3 -3
- package/dist/contexts/types.d.ts +3 -3
- package/dist/contexts/types.js +1 -1
- package/dist/contexts/userIdentityContext/index.cjs +20 -20
- package/dist/contexts/userIdentityContext/index.d.cts +1 -1
- package/dist/contexts/userIdentityContext/index.d.ts +1 -1
- package/dist/contexts/userIdentityContext/index.js +20 -20
- package/dist/{enviveConfig-BlIkxiAF.js → enviveConfig-DV8F12B9.js} +3 -3
- package/dist/{enviveConfig-B42OJ8bK.cjs → enviveConfig-DZHdtLsQ.cjs} +3 -3
- package/dist/{enviveConfigContext-1_EivtCa.js → enviveConfigContext-BS7aNop5.js} +3 -3
- package/dist/{enviveConfigContext-Y1ahEAMe.cjs → enviveConfigContext-CTcHUIFP.cjs} +3 -3
- package/dist/{featureFlagServiceContext-D3Ge8GH5.cjs → featureFlagServiceContext-CJyYItqu.cjs} +3 -3
- package/dist/{featureFlagServiceContext-C5U0bshi.d.ts → featureFlagServiceContext-CpxlOkI9.d.ts} +2 -2
- package/dist/{featureFlagServiceContext-CAPrb4e_.js → featureFlagServiceContext-FBM6DdMJ.js} +3 -3
- package/dist/{featureFlagServiceContext-CiKWV306.d.cts → featureFlagServiceContext-p5UBwPM3.d.cts} +2 -2
- package/dist/{featureGates-D4Me_IZH.js → featureGates-KEwAL8p_.js} +1 -1
- package/dist/{featureGates-Bt_Y3kZ7.cjs → featureGates-qU_ulhpC.cjs} +1 -1
- package/dist/{frontendConfig-BiD1-j48.d.ts → frontendConfig-Cawh5iqv.d.ts} +6 -3
- package/dist/{frontendConfig-tVg0hsWZ.d.cts → frontendConfig-iZipB5FG.d.cts} +6 -3
- package/dist/graphql-CkxgqsXP.js +48 -0
- package/dist/graphql-i3dtpVTl.cjs +71 -0
- package/dist/{graphqlContext-Bf3E-V2T.d.cts → graphqlContext-BeyKU1Dr.d.cts} +2 -2
- package/dist/{graphqlContext-CpwAvnro.cjs → graphqlContext-CVbYIftg.cjs} +6 -6
- package/dist/{graphqlContext-CDeKzb46.d.ts → graphqlContext-DgkS-UX1.d.ts} +4 -4
- package/dist/{graphqlContext-dyWNSWNv.js → graphqlContext-DouNZbYo.js} +5 -5
- package/dist/hooks/AmplitudeOperations/index.cjs +18 -18
- package/dist/hooks/AmplitudeOperations/index.d.cts +1 -1
- package/dist/hooks/AmplitudeOperations/index.d.ts +1 -1
- package/dist/hooks/AmplitudeOperations/index.js +18 -18
- package/dist/hooks/AppDetails/index.cjs +15 -15
- package/dist/hooks/AppDetails/index.d.cts +12 -11
- package/dist/hooks/AppDetails/index.d.ts +12 -11
- package/dist/hooks/AppDetails/index.js +15 -15
- package/dist/hooks/CdnOperations/index.cjs +4 -4
- package/dist/hooks/CdnOperations/index.js +4 -4
- package/dist/hooks/ChatToggle/index.cjs +18 -18
- package/dist/hooks/ChatToggle/index.d.cts +1 -1
- package/dist/hooks/ChatToggle/index.d.ts +1 -1
- package/dist/hooks/ChatToggle/index.js +18 -18
- package/dist/hooks/ChatToggleAnalytics/index.cjs +19 -19
- package/dist/hooks/ChatToggleAnalytics/index.d.cts +1 -1
- package/dist/hooks/ChatToggleAnalytics/index.d.ts +1 -1
- package/dist/hooks/ChatToggleAnalytics/index.js +19 -19
- package/dist/hooks/CustomerSupportHandoff/index.cjs +1 -1
- package/dist/hooks/CustomerSupportHandoff/index.js +1 -1
- package/dist/hooks/Debounce/index.cjs +20 -2
- package/dist/hooks/Debounce/index.js +18 -2
- package/dist/hooks/ElementObserver/index.d.cts +1 -1
- package/dist/hooks/ElementObserver/index.d.ts +1 -1
- package/dist/hooks/GrabAndScroll/index.d.ts +2 -2
- package/dist/hooks/GraphQLConfig/index.cjs +12 -12
- package/dist/hooks/GraphQLConfig/index.d.cts +13 -12
- package/dist/hooks/GraphQLConfig/index.d.ts +13 -12
- package/dist/hooks/GraphQLConfig/index.js +12 -12
- package/dist/hooks/IdentifyUser/index.cjs +20 -20
- package/dist/hooks/IdentifyUser/index.js +20 -20
- package/dist/hooks/ImageResolver/index.cjs +10 -10
- package/dist/hooks/ImageResolver/index.js +10 -10
- package/dist/hooks/LocalStorageOperations/index.cjs +2 -2
- package/dist/hooks/LocalStorageOperations/index.js +2 -2
- package/dist/hooks/MessageFilter/index.cjs +8 -8
- package/dist/hooks/MessageFilter/index.d.cts +12 -11
- package/dist/hooks/MessageFilter/index.d.ts +12 -11
- package/dist/hooks/MessageFilter/index.js +8 -8
- package/dist/hooks/NewOrgConfig/index.cjs +15 -15
- package/dist/hooks/NewOrgConfig/index.d.cts +14 -13
- package/dist/hooks/NewOrgConfig/index.d.ts +14 -13
- package/dist/hooks/NewOrgConfig/index.js +15 -15
- package/dist/hooks/Search/index.cjs +323 -152
- package/dist/hooks/Search/index.d.cts +21 -17
- package/dist/hooks/Search/index.d.ts +21 -17
- package/dist/hooks/Search/index.js +323 -153
- package/dist/hooks/SearchOperations/index.cjs +18 -18
- package/dist/hooks/SearchOperations/index.d.cts +1 -1
- package/dist/hooks/SearchOperations/index.d.ts +1 -1
- package/dist/hooks/SearchOperations/index.js +18 -18
- package/dist/hooks/SessionStorageOperations/index.cjs +2 -2
- package/dist/hooks/SessionStorageOperations/index.js +2 -2
- package/dist/hooks/ShopifyUrlOperations/index.cjs +2 -2
- package/dist/hooks/ShopifyUrlOperations/index.d.cts +5 -5
- package/dist/hooks/ShopifyUrlOperations/index.d.ts +5 -5
- package/dist/hooks/ShopifyUrlOperations/index.js +2 -2
- package/dist/hooks/SystemSettingsContext/index.cjs +5 -5
- package/dist/hooks/SystemSettingsContext/index.d.cts +12 -11
- package/dist/hooks/SystemSettingsContext/index.d.ts +14 -13
- package/dist/hooks/SystemSettingsContext/index.js +5 -5
- package/dist/hooks/TrackComponentVisibleEvent/index.cjs +17 -17
- package/dist/hooks/TrackComponentVisibleEvent/index.d.cts +2 -2
- package/dist/hooks/TrackComponentVisibleEvent/index.d.ts +2 -2
- package/dist/hooks/TrackComponentVisibleEvent/index.js +17 -17
- package/dist/hooks/UpdateAnalyticsProps/index.cjs +16 -16
- package/dist/hooks/UpdateAnalyticsProps/index.js +16 -16
- package/dist/hooks/utils.d.cts +12 -11
- package/dist/hooks/utils.d.ts +12 -11
- package/dist/{index-B6xpW8RG.d.ts → index--9_c4tze.d.ts} +1 -1
- package/dist/index-BEpDGqnz.d.cts +41 -0
- package/dist/{index-D31m6bPU.d.ts → index-BKvFVPUX.d.ts} +1 -1
- package/dist/{index-VwfWqyR_.d.ts → index-BNHIIgYk.d.ts} +1 -1
- package/dist/index-BUDrAxnl.d.ts +673 -0
- package/dist/{index-DzbkQtaK.d.cts → index-CCboEuTO.d.cts} +1 -1
- package/dist/{index-wFHfdr6p.d.ts → index-CMJM-3zV.d.ts} +5 -5
- package/dist/{index-FQjyuD3D.d.cts → index-COXkY78t.d.cts} +1 -1
- package/dist/{index--uHjE7L8.d.ts → index-D7htGSQC.d.ts} +1 -1
- package/dist/index-DM_5fh8c.d.ts +101 -0
- package/dist/index-DU7uw0ba.d.cts +101 -0
- package/dist/{index-Da1s8h5C.d.cts → index-DZtnHhlr.d.cts} +1 -1
- package/dist/{index-Bq39XSmY.d.cts → index-DpJzjjpi.d.cts} +34 -34
- package/dist/{index-DSRs6N6J.d.ts → index-Dtw-hJdt.d.ts} +1 -1
- package/dist/index-Dy3TTIOm.d.cts +673 -0
- package/dist/index-ErVcwUnR.d.ts +41 -0
- package/dist/{index-Cyq5HiC0.d.cts → index-OkKEOL6H.d.cts} +1 -1
- package/dist/{index-9NE86em3.d.cts → index-hAqp0oYb.d.cts} +1 -1
- package/dist/interceptors/index.d.cts +13 -12
- package/dist/interceptors/index.d.ts +13 -12
- package/dist/interceptors/types.d.cts +12 -11
- package/dist/interceptors/types.d.ts +12 -11
- package/dist/{localStorageContext-DAOJ4be4.js → localStorageContext-CqcSvg2H.js} +2 -2
- package/dist/{localStorageContext-C5giszHn.cjs → localStorageContext-DiLfSsqL.cjs} +2 -2
- package/dist/{locators-C2fWd-74.js → locators-BMQGmGLq.js} +1 -1
- package/dist/{locators-Cx3q6Z_h.cjs → locators-DxYdak1F.cjs} +1 -1
- package/dist/{logger-0D_8Ip2L.cjs → logger-TBIl4uIH.cjs} +1 -1
- package/dist/{logger-Co0IA3k5.js → logger-W3lqg-4b.js} +1 -1
- package/dist/models-CWOgrLCm.js +1284 -0
- package/dist/models-DqdLOi2I.cjs +1519 -0
- package/dist/{newOrgConfigContext-BMvcqPzD.cjs → newOrgConfigContext-BIDz4ZuO.cjs} +4 -4
- package/dist/{newOrgConfigContext-DOdUxlOE.d.cts → newOrgConfigContext-CJI3tsVV.d.cts} +2 -2
- package/dist/{newOrgConfigContext-BVyJExeW.d.ts → newOrgConfigContext-CKn7B2rj.d.ts} +2 -2
- package/dist/{newOrgConfigContext-6mlrvr1w.js → newOrgConfigContext-u_9UPNcX.js} +4 -4
- package/dist/{nodeSelector-DYhDUi7v.d.ts → nodeSelector-B5NfnUHv.d.ts} +1 -1
- package/dist/{nodeSelector-B3bPtEjX.d.cts → nodeSelector-vKB44CDB.d.cts} +1 -1
- package/dist/{orgAnalyticsConfig-Bm23fw4s.cjs → orgAnalyticsConfig-CGEQtAFs.cjs} +1 -1
- package/dist/{orgAnalyticsConfig-CpBmga08.js → orgAnalyticsConfig-i4jozLBB.js} +1 -1
- package/dist/responseGenerics-D9bS-Dd6.d.ts +148 -0
- package/dist/{index-Cx9e-fRi.d.ts → responseGenerics-DWLV09cQ.d.cts} +4 -40
- package/dist/{search-y-ioX5Mz.d.cts → search-6RrxBXD6.d.cts} +1 -1
- package/dist/{search-D-UfTjB7.cjs → search-CTVX9gC6.cjs} +2 -2
- package/dist/{search-B1OtJe8Z.d.ts → search-DrJiCT7d.d.ts} +1 -1
- package/dist/{search-yawhMv22.js → search-NgNrXNS9.js} +2 -2
- package/dist/{search-filter-types-BxaNSLs_.d.cts → search-filter-types-BItKtezf.d.cts} +1 -1
- package/dist/{search-filter-types-OI9zH3E_.d.ts → search-filter-types-CGFhksO3.d.ts} +1 -1
- package/dist/{searchContext-CFuwIIW-.cjs → searchContext-CnDXkawZ.cjs} +6 -6
- package/dist/{searchContext-CiqOqTJL.js → searchContext-DtRmshTA.js} +6 -6
- package/dist/{sessionStorageContext-BmCW091C.cjs → sessionStorageContext-1Ks_d4Z0.cjs} +2 -2
- package/dist/{sessionStorageContext-CNxkqJi1.js → sessionStorageContext-CDcl7NVl.js} +2 -2
- package/dist/{shopifyUrlContext-aZMwCfbJ.cjs → shopifyUrlContext-CxjV3qvH.cjs} +2 -2
- package/dist/{shopifyUrlContext-BXbI0PIG.js → shopifyUrlContext-D2btP_lY.js} +2 -2
- package/dist/{spiffyWidgets-CvEJIuJx.d.ts → spiffyWidgets-CR6F7FRE.d.ts} +1 -1
- package/dist/{spiffyWidgets-BuS00VaQ.d.cts → spiffyWidgets-eNbU1gMc.d.cts} +1 -1
- package/dist/{systemSettingsContext-SozpUezn.cjs → systemSettingsContext-BejoGzzB.cjs} +2 -2
- package/dist/{systemSettingsContext-kz6yyiFF.js → systemSettingsContext-C4dtZ0uZ.js} +2 -2
- package/dist/{test-types-DRhqHXw-.d.ts → test-types-BEml_bm3.d.ts} +1 -1
- package/dist/{test-types-ThQiO_cc.d.cts → test-types-Dsu8RJZu.d.cts} +1 -1
- package/dist/types/index.d.cts +2 -2
- package/dist/types/index.d.ts +2 -2
- package/dist/{types-r0Z6CwyF.d.ts → types-4LQ7LUCk.d.ts} +2 -2
- package/dist/types-BegmH0S1.d.ts +60 -0
- package/dist/types-BuvXXGxE.cjs +1 -1
- package/dist/types-CtUb63bt.js +76 -0
- package/dist/{types-zQGBI-Yo.d.cts → types-DFsSqmWx.d.cts} +2 -2
- package/dist/types-DWorwfS-.d.cts +60 -0
- package/dist/types-DXnG1tV0.js +1 -1
- package/dist/types-UUvB6h05.cjs +106 -0
- package/dist/types.d.cts +3 -3
- package/dist/types.d.ts +3 -3
- package/dist/{unsupportedProductExceptions-B4f9aLjr.cjs → unsupportedProductExceptions-B0yx2bHK.cjs} +1 -1
- package/dist/{unsupportedProductExceptions-DlmraJm8.js → unsupportedProductExceptions-Cs66ngs3.js} +1 -1
- package/dist/{urlsParser-DhcEZLc_.cjs → urlsParser-COzMdJaX.cjs} +1 -1
- package/dist/{urlsParser-DLCzibqU.js → urlsParser-DxjoLj98.js} +1 -1
- package/dist/{useAmplitudeOperations-D0nvIYlt.cjs → useAmplitudeOperations-BJXD9v2u.cjs} +2 -2
- package/dist/{useAmplitudeOperations-Dhks3PgF.js → useAmplitudeOperations-Dym0Ker8.js} +2 -2
- package/dist/{useAppDetails-qyaQIbWE.js → useAppDetails-Dmh16bWE.js} +4 -4
- package/dist/{useAppDetails-B9sGmpJ3.cjs → useAppDetails-DsAZ1xQn.cjs} +4 -4
- package/dist/{useGraphQLConfig-CgKEfVYc.cjs → useGraphQLConfig-B3DlwmGg.cjs} +2 -2
- package/dist/{useGraphQLConfig-BccQUaeW.js → useGraphQLConfig-DSRaDTdT.js} +2 -2
- package/dist/{userIdentityContext-BKLedN4R.d.ts → userIdentityContext-C6kApbuk.d.ts} +1 -1
- package/dist/userIdentityContext-DF3atBFE.js +119 -0
- package/dist/userIdentityContext-DpQTduhF.cjs +136 -0
- package/dist/{userIdentityContext-D2oFVFzo.d.cts → userIdentityContext-kU1PIo8K.d.cts} +1 -1
- package/dist/{utils-DFPt3FSw.js → utils-B7KTAEmV.js} +4 -4
- package/dist/{utils-BhyZiDrE.d.ts → utils-BRkGP1eb.d.ts} +1 -1
- package/dist/{utils-B7PAzB_M.d.cts → utils-CBD4g2Nc.d.cts} +4 -4
- package/dist/{utils-C6imnLBo.cjs → utils-CDw74BCO.cjs} +1 -1
- package/dist/{utils-Cazq8Q3q.cjs → utils-CcC2jZRi.cjs} +4 -4
- package/dist/{utils-B3x_9JTY.d.cts → utils-DCrwX6FT.d.cts} +1 -1
- package/dist/{utils-C4ci_t0-.js → utils-DIvMgPe8.js} +1 -1
- package/dist/{utils-B1v0iXs3.d.ts → utils-QKFAbPT6.d.ts} +4 -4
- package/package.json +7 -2
- package/src/application/commerce-api.ts +2 -0
- package/src/application/models/graphql/index.ts +1 -0
- package/src/atoms/app/index.ts +1 -1
- package/src/atoms/search/productRetrievalAPI.ts +70 -0
- package/src/atoms/search/productRetrievalAdapter.ts +25 -0
- package/src/atoms/search/types.ts +13 -0
- package/src/contexts/amplitudeContext/__tests__/amplitudeContext.test.tsx +525 -0
- package/src/contexts/amplitudeContext/amplitudeContext.tsx +5 -2
- package/src/contexts/graphqlContext/__tests__/graphqlContext.test.tsx +790 -0
- package/src/contexts/localStorageContext/__tests__/localStorageContext.test.tsx +775 -0
- package/src/contexts/newOrgConfigContext/__tests__/newOrgConfigContext.test.tsx +495 -0
- package/src/contexts/searchContext/__tests__/searchContext.test.tsx +806 -0
- package/src/contexts/systemSettingsContext/__tests__/systemSettingsContext.test.tsx +506 -0
- package/src/contexts/types.ts +3 -0
- package/src/contexts/userIdentityContext/userIdentityContext.tsx +7 -5
- package/src/hooks/Search/useRecommendedProducts.ts +48 -0
- package/src/hooks/Search/useSearch.tsx +89 -182
- package/src/hooks/Search/useSearchInput.ts +263 -0
- package/src/types/FilterAttribute.ts +35 -0
- package/dist/amplitudeContext-DOqL2Vn8.js +0 -264
- package/dist/amplitudeContext-ZTQMvVTV.cjs +0 -286
- package/dist/graphql-OkhsP4ir.js +0 -36
- package/dist/graphql-l4dQrsA6.cjs +0 -53
- package/dist/index-Bmub8e38.d.cts +0 -98
- package/dist/index-CG3P8xE1.d.cts +0 -676
- package/dist/index-CiWEYzXl.d.cts +0 -184
- package/dist/index-D2VaMPA3.d.ts +0 -98
- package/dist/index-fUsw_Mea.d.ts +0 -676
- package/dist/models-CkJ-wg9Q.cjs +0 -1537
- package/dist/models-UHOY0ak5.js +0 -1296
- package/dist/types-BwNrLPSZ.cjs +0 -106
- package/dist/types-CKMMb_gX.d.cts +0 -51
- package/dist/types-D3uOF0Oy.js +0 -76
- package/dist/types-DZPuBnHe.d.ts +0 -51
- package/dist/useDebounce-BZDtUAQ8.cjs +0 -26
- package/dist/useDebounce-ueblXZI-.js +0 -19
- package/dist/userIdentityContext-Cb6lLv6t.cjs +0 -132
- package/dist/userIdentityContext-O_DHHPTN.js +0 -115
- /package/dist/{AmplitudeOperations-ChZWcSsc.js → AmplitudeOperations-C-ieCm9m.js} +0 -0
- /package/dist/{AmplitudeOperations-JggIc1zD.cjs → AmplitudeOperations-p7APchq9.cjs} +0 -0
- /package/dist/{index-RcVcRKH7.d.cts → index-A0HvA68Y.d.cts} +0 -0
- /package/dist/{index-mHc9_XC3.d.ts → index-DNVvRcKu.d.ts} +0 -0
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { useState, useCallback, useRef, useMemo } from "react";
|
|
2
|
+
import { useAtomValue } from "jotai";
|
|
3
|
+
import Fuse from "fuse.js";
|
|
4
|
+
|
|
5
|
+
import { autocompleteStateAtom } from "src/atoms/globalSearch";
|
|
6
|
+
import { amplitudeTrackEventAtom } from "src/atoms/amplitude/amplitudeTrackEventAtom";
|
|
7
|
+
import { SpiffyMetricsEventName } from "src/contexts/amplitudeContext";
|
|
8
|
+
import { SpiffyWidgets } from "src/application/models/spiffyWidgets";
|
|
9
|
+
|
|
10
|
+
export interface UseSearchInputProps {
|
|
11
|
+
initialSearchText?: string;
|
|
12
|
+
searchOrigin: SpiffyWidgets;
|
|
13
|
+
onSearchSubmit?: (query: string) => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface UseSearchInputReturn {
|
|
17
|
+
// State
|
|
18
|
+
searchText: string;
|
|
19
|
+
hasText: boolean;
|
|
20
|
+
isFocused: boolean;
|
|
21
|
+
focusedIndex: number;
|
|
22
|
+
focusedOptionId: string | undefined;
|
|
23
|
+
autocompleteResults: string[];
|
|
24
|
+
shouldShowAutocomplete: boolean;
|
|
25
|
+
|
|
26
|
+
// Handlers
|
|
27
|
+
handleSearchInputChange: (value: string) => void;
|
|
28
|
+
handleSearchInputFocus: () => void;
|
|
29
|
+
handleSearchInputBlur: () => void;
|
|
30
|
+
handleKeyDown: (event: React.KeyboardEvent<HTMLInputElement>) => void;
|
|
31
|
+
handleAutocompleteSelect: (suggestion: string, rankPosition?: number) => void;
|
|
32
|
+
handleSubmitSearch: () => void;
|
|
33
|
+
|
|
34
|
+
// Utilities
|
|
35
|
+
setSearchText: (text: string) => void;
|
|
36
|
+
resetSearch: () => void;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const useSearchInput = ({
|
|
40
|
+
initialSearchText = "",
|
|
41
|
+
searchOrigin,
|
|
42
|
+
onSearchSubmit,
|
|
43
|
+
}: UseSearchInputProps): UseSearchInputReturn => {
|
|
44
|
+
const track = useAtomValue(amplitudeTrackEventAtom);
|
|
45
|
+
|
|
46
|
+
// State
|
|
47
|
+
const [searchText, setSearchText] = useState(initialSearchText);
|
|
48
|
+
const [hasText, setHasText] = useState(initialSearchText.trim().length > 0);
|
|
49
|
+
const [isFocused, setIsFocused] = useState(false);
|
|
50
|
+
const [focusedIndex, setFocusedIndex] = useState(-1);
|
|
51
|
+
const [focusedOptionId, setFocusedOptionId] = useState<string | undefined>(
|
|
52
|
+
undefined
|
|
53
|
+
);
|
|
54
|
+
const autocompleteState = useAtomValue(autocompleteStateAtom);
|
|
55
|
+
const globalAutocompleteResults = autocompleteState.results;
|
|
56
|
+
const isAutocompleteEnabled = globalAutocompleteResults.length > 0;
|
|
57
|
+
|
|
58
|
+
// Refs
|
|
59
|
+
const isSelectingAutocomplete = useRef(false);
|
|
60
|
+
|
|
61
|
+
// Computed
|
|
62
|
+
const shouldShowAutocomplete = hasText && isFocused && isAutocompleteEnabled;
|
|
63
|
+
|
|
64
|
+
const autocompleteResultsLimit = 5;
|
|
65
|
+
|
|
66
|
+
// Configure Fuse.js for fuzzy search with custom scoring
|
|
67
|
+
const fuseOptions = useMemo(
|
|
68
|
+
() => ({
|
|
69
|
+
includeScore: true,
|
|
70
|
+
includeMatches: true,
|
|
71
|
+
// Fuzzy matching threshold (0.0 = perfect match, 1.0 = match anything)
|
|
72
|
+
threshold: 0.3,
|
|
73
|
+
// Location where match is expected (0 = beginning)
|
|
74
|
+
location: 0,
|
|
75
|
+
// Distance from location where match can be found - smaller for prefix preference
|
|
76
|
+
distance: 4,
|
|
77
|
+
// Minimum character length before fuzzy matching starts
|
|
78
|
+
minMatchCharLength: 1,
|
|
79
|
+
// Keys to search (we're searching strings directly, so no keys needed)
|
|
80
|
+
keys: [],
|
|
81
|
+
// Use extended search for exact matches and prefix matching
|
|
82
|
+
useExtendedSearch: false,
|
|
83
|
+
// Don't ignore location - this helps prioritize matches at the beginning
|
|
84
|
+
ignoreLocation: false,
|
|
85
|
+
}),
|
|
86
|
+
[]
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
const fuse = useMemo(() => {
|
|
90
|
+
if (!globalAutocompleteResults.length) return null;
|
|
91
|
+
return new Fuse(globalAutocompleteResults, fuseOptions);
|
|
92
|
+
}, [globalAutocompleteResults, fuseOptions]);
|
|
93
|
+
|
|
94
|
+
// Autocomplete fuzzy search using Fuse.js
|
|
95
|
+
const autocompleteResults = useMemo(() => {
|
|
96
|
+
if (!isAutocompleteEnabled || !fuse) {
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (!searchText.trim()) {
|
|
101
|
+
return [];
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const fuseResults = fuse.search(searchText);
|
|
105
|
+
|
|
106
|
+
// Use only Fuse.js scoring (results are already sorted by relevance)
|
|
107
|
+
return fuseResults
|
|
108
|
+
.slice(0, autocompleteResultsLimit)
|
|
109
|
+
.map((result) => result.item);
|
|
110
|
+
}, [isAutocompleteEnabled, fuse, searchText, autocompleteResultsLimit]);
|
|
111
|
+
|
|
112
|
+
// Handlers
|
|
113
|
+
const handleSearchInputChange = useCallback(
|
|
114
|
+
(newValue: string) => {
|
|
115
|
+
// If the user is changing text, they must be interacting with the input
|
|
116
|
+
// So we can safely assume they're focused
|
|
117
|
+
if (newValue !== searchText) {
|
|
118
|
+
setIsFocused(true);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (newValue.length === 1) {
|
|
122
|
+
track?.({
|
|
123
|
+
eventName: SpiffyMetricsEventName.SearchInputStarted,
|
|
124
|
+
eventProps: {
|
|
125
|
+
searchOrigin,
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
setSearchText(newValue);
|
|
130
|
+
setHasText(newValue.trim().length > 0);
|
|
131
|
+
setFocusedIndex(-1);
|
|
132
|
+
setFocusedOptionId(undefined);
|
|
133
|
+
},
|
|
134
|
+
[searchOrigin, searchText, track]
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
const handleSearchInputFocus = useCallback(() => {
|
|
138
|
+
setIsFocused(true);
|
|
139
|
+
}, []);
|
|
140
|
+
|
|
141
|
+
const handleSearchInputBlur = useCallback(() => {
|
|
142
|
+
setTimeout(() => {
|
|
143
|
+
if (!isSelectingAutocomplete.current) {
|
|
144
|
+
setIsFocused(false);
|
|
145
|
+
setFocusedIndex(-1);
|
|
146
|
+
setFocusedOptionId(undefined);
|
|
147
|
+
}
|
|
148
|
+
}, 150);
|
|
149
|
+
}, []);
|
|
150
|
+
|
|
151
|
+
const handleSubmitSearch = useCallback(() => {
|
|
152
|
+
setIsFocused(false);
|
|
153
|
+
if (searchText.trim() && onSearchSubmit) {
|
|
154
|
+
track?.({
|
|
155
|
+
eventName: SpiffyMetricsEventName.SearchQuerySubmitted,
|
|
156
|
+
eventProps: {
|
|
157
|
+
searchOrigin,
|
|
158
|
+
queryText: searchText.trim(),
|
|
159
|
+
},
|
|
160
|
+
alsoSendToGoogleAnalytics: true,
|
|
161
|
+
});
|
|
162
|
+
onSearchSubmit(searchText.trim());
|
|
163
|
+
}
|
|
164
|
+
}, [searchText, onSearchSubmit, searchOrigin, track]);
|
|
165
|
+
|
|
166
|
+
const handleAutocompleteSelect = useCallback(
|
|
167
|
+
(suggestion: string, rankPosition?: number) => {
|
|
168
|
+
isSelectingAutocomplete.current = true;
|
|
169
|
+
setSearchText(suggestion);
|
|
170
|
+
setHasText(suggestion.trim().length > 0);
|
|
171
|
+
setIsFocused(false);
|
|
172
|
+
|
|
173
|
+
track?.({
|
|
174
|
+
eventName: SpiffyMetricsEventName.SearchInputStarted,
|
|
175
|
+
eventProps: {
|
|
176
|
+
searchOrigin,
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
if (onSearchSubmit) {
|
|
181
|
+
onSearchSubmit(suggestion.trim());
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
setTimeout(() => {
|
|
185
|
+
isSelectingAutocomplete.current = false;
|
|
186
|
+
}, 100);
|
|
187
|
+
},
|
|
188
|
+
[onSearchSubmit, searchOrigin, track]
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
const handleKeyDown = useCallback(
|
|
192
|
+
(event: React.KeyboardEvent<HTMLInputElement>) => {
|
|
193
|
+
if (event.key === "ArrowDown") {
|
|
194
|
+
event.preventDefault();
|
|
195
|
+
const newIndex = (focusedIndex + 1) % autocompleteResults.length;
|
|
196
|
+
setFocusedIndex(newIndex);
|
|
197
|
+
setFocusedOptionId(`option-${newIndex}`);
|
|
198
|
+
} else if (event.key === "ArrowUp") {
|
|
199
|
+
event.preventDefault();
|
|
200
|
+
const newIndex =
|
|
201
|
+
(focusedIndex - 1 + autocompleteResults.length) %
|
|
202
|
+
autocompleteResults.length;
|
|
203
|
+
setFocusedIndex(newIndex);
|
|
204
|
+
setFocusedOptionId(`option-${newIndex}`);
|
|
205
|
+
} else if (event.key === "Enter") {
|
|
206
|
+
if (focusedIndex === -1) {
|
|
207
|
+
event.preventDefault();
|
|
208
|
+
handleSubmitSearch();
|
|
209
|
+
} else {
|
|
210
|
+
event.preventDefault();
|
|
211
|
+
const suggestionText = autocompleteResults[focusedIndex];
|
|
212
|
+
handleAutocompleteSelect(suggestionText, focusedIndex);
|
|
213
|
+
}
|
|
214
|
+
} else if (event.key === "Escape") {
|
|
215
|
+
event.preventDefault();
|
|
216
|
+
setFocusedIndex(-1);
|
|
217
|
+
setFocusedOptionId(undefined);
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
[
|
|
221
|
+
autocompleteResults,
|
|
222
|
+
focusedIndex,
|
|
223
|
+
handleAutocompleteSelect,
|
|
224
|
+
handleSubmitSearch,
|
|
225
|
+
]
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
const setSearchTextUtility = useCallback((text: string) => {
|
|
229
|
+
setSearchText(text);
|
|
230
|
+
setHasText(text.trim().length > 0);
|
|
231
|
+
}, []);
|
|
232
|
+
|
|
233
|
+
const resetSearch = useCallback(() => {
|
|
234
|
+
setSearchText("");
|
|
235
|
+
setHasText(false);
|
|
236
|
+
setIsFocused(false);
|
|
237
|
+
setFocusedIndex(-1);
|
|
238
|
+
setFocusedOptionId(undefined);
|
|
239
|
+
}, []);
|
|
240
|
+
|
|
241
|
+
return {
|
|
242
|
+
// State
|
|
243
|
+
searchText,
|
|
244
|
+
hasText,
|
|
245
|
+
isFocused,
|
|
246
|
+
focusedIndex,
|
|
247
|
+
focusedOptionId,
|
|
248
|
+
autocompleteResults,
|
|
249
|
+
shouldShowAutocomplete,
|
|
250
|
+
|
|
251
|
+
// Handlers
|
|
252
|
+
handleSearchInputChange,
|
|
253
|
+
handleSearchInputFocus,
|
|
254
|
+
handleSearchInputBlur,
|
|
255
|
+
handleKeyDown,
|
|
256
|
+
handleAutocompleteSelect,
|
|
257
|
+
handleSubmitSearch,
|
|
258
|
+
|
|
259
|
+
// Utilities
|
|
260
|
+
setSearchText: setSearchTextUtility,
|
|
261
|
+
resetSearch,
|
|
262
|
+
};
|
|
263
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// TODO: These are duplicated types. Right now, since this uses discriminated unions, they don't export from the types
|
|
2
|
+
// library properly. Can be fixed by refactoring the current approach use the right method is decided upon.
|
|
3
|
+
|
|
4
|
+
interface AlphabeticFilterSorting {
|
|
5
|
+
type: "alphabetic";
|
|
6
|
+
}
|
|
7
|
+
interface ProductCountFilterSorting {
|
|
8
|
+
type: "productCount";
|
|
9
|
+
}
|
|
10
|
+
interface CustomFilterSorting {
|
|
11
|
+
type: "custom";
|
|
12
|
+
map: Record<string, number>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type FilterSorting =
|
|
16
|
+
| AlphabeticFilterSorting
|
|
17
|
+
| ProductCountFilterSorting
|
|
18
|
+
| CustomFilterSorting;
|
|
19
|
+
|
|
20
|
+
interface BaseFilterConfig {
|
|
21
|
+
filterId: string;
|
|
22
|
+
displayName: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface PriceFilterConfig extends BaseFilterConfig {
|
|
26
|
+
type: "price";
|
|
27
|
+
bucketSize: number;
|
|
28
|
+
}
|
|
29
|
+
interface DynamicFilterConfig extends BaseFilterConfig {
|
|
30
|
+
type: "dynamic";
|
|
31
|
+
attribute: string;
|
|
32
|
+
sorting: FilterSorting;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type FilterAttribute = DynamicFilterConfig | PriceFilterConfig;
|
|
@@ -1,264 +0,0 @@
|
|
|
1
|
-
import { EventsDispatcher, SpiffyEvent } from "./events-DyUix-Bn.js";
|
|
2
|
-
import { logger_default } from "./logger-Co0IA3k5.js";
|
|
3
|
-
import { OrgShortName } from "./models-UHOY0ak5.js";
|
|
4
|
-
import { FeatureGates } from "./featureGates-D4Me_IZH.js";
|
|
5
|
-
import { LocalStorageKeys, useLocalStorage } from "./localStorageContext-DAOJ4be4.js";
|
|
6
|
-
import { amplitudeApiKeyAtom, contextSourceAtom, dataResidencyAtom, envAtom, identifyingPrefixAtom } from "./enviveConfig-BlIkxiAF.js";
|
|
7
|
-
import { orgAnalyticsGoogleAnalyticsConfigAtom } from "./orgAnalyticsConfig-CpBmga08.js";
|
|
8
|
-
import { userIdAtom } from "./app-Aqkm_SlS.js";
|
|
9
|
-
import { useEnviveConfig } from "./enviveConfigContext-1_EivtCa.js";
|
|
10
|
-
import { useFeatureFlagService } from "./featureFlagServiceContext-CAPrb4e_.js";
|
|
11
|
-
import React, { createContext, useCallback, useContext, useEffect, useMemo } from "react";
|
|
12
|
-
import { useAtomValue } from "jotai";
|
|
13
|
-
import { createInstance } from "@amplitude/analytics-browser";
|
|
14
|
-
import { jsx } from "react/jsx-runtime";
|
|
15
|
-
|
|
16
|
-
//#region src/contexts/amplitudeContext/amplitudeContext.tsx
|
|
17
|
-
let SpiffyMetricsEventName = /* @__PURE__ */ function(SpiffyMetricsEventName$1) {
|
|
18
|
-
SpiffyMetricsEventName$1["BundleLoaded"] = "Bundle Loaded";
|
|
19
|
-
SpiffyMetricsEventName$1["ChatLiveAgentBtnClick"] = "Chat Live Agent Btn Click";
|
|
20
|
-
SpiffyMetricsEventName$1["ChatFloatingButtonVisible"] = "Chat Floating Button Visible";
|
|
21
|
-
SpiffyMetricsEventName$1["ChatComponentVisible"] = "Chat Component Visible";
|
|
22
|
-
SpiffyMetricsEventName$1["ChatComponentExpanded"] = "Chat Component Expanded";
|
|
23
|
-
SpiffyMetricsEventName$1["ChatComponentCollapsed"] = "Chat Component Collapsed";
|
|
24
|
-
SpiffyMetricsEventName$1["ChatUserMessageInput"] = "Chat User Message Input";
|
|
25
|
-
SpiffyMetricsEventName$1["ChatSuggestionClicked"] = "Chat Suggestion Clicked";
|
|
26
|
-
SpiffyMetricsEventName$1["ChatAssistantResponse"] = "Chat Assistant Response";
|
|
27
|
-
SpiffyMetricsEventName$1["ProductCardClicked"] = "Product Card Clicked";
|
|
28
|
-
SpiffyMetricsEventName$1["ProductReviewCardClicked"] = "Product Review Card Clicked";
|
|
29
|
-
SpiffyMetricsEventName$1["AddToCartClicked"] = "Add to Cart Clicked";
|
|
30
|
-
SpiffyMetricsEventName$1["PromptCardClicked"] = "Prompt Card Clicked";
|
|
31
|
-
SpiffyMetricsEventName$1["SupportedEvent"] = "Supported Event";
|
|
32
|
-
SpiffyMetricsEventName$1["SearchBackToResponseClicked"] = "Search Back to Response Clicked";
|
|
33
|
-
SpiffyMetricsEventName$1["PerformanceMetrics"] = "Performance Metrics";
|
|
34
|
-
SpiffyMetricsEventName$1["SearchBarClicked"] = "Search Bar Clicked";
|
|
35
|
-
SpiffyMetricsEventName$1["OrderLookupStarted"] = "Order Lookup Started";
|
|
36
|
-
SpiffyMetricsEventName$1["OrderLookupFormSubmitted"] = "Order Lookup Form Submitted";
|
|
37
|
-
SpiffyMetricsEventName$1["SearchComponentVisible"] = "Search Component Visible";
|
|
38
|
-
SpiffyMetricsEventName$1["SearchZeroStateSuggestionClicked"] = "Search Zero State Suggestion Clicked";
|
|
39
|
-
SpiffyMetricsEventName$1["SearchInputStarted"] = "Search Input Started";
|
|
40
|
-
SpiffyMetricsEventName$1["SearchQuerySubmitted"] = "Search Query Submitted";
|
|
41
|
-
SpiffyMetricsEventName$1["SearchResultsViewed"] = "Search Results Viewed";
|
|
42
|
-
SpiffyMetricsEventName$1["SearchTimeToFirstClick"] = "Search Time to First Click";
|
|
43
|
-
SpiffyMetricsEventName$1["SearchZeroResultsRate"] = "Search Zero Results Rate";
|
|
44
|
-
SpiffyMetricsEventName$1["SearchFilterClicked"] = "Search Filter Clicked";
|
|
45
|
-
SpiffyMetricsEventName$1["SearchSortClicked"] = "Search Sort Clicked";
|
|
46
|
-
return SpiffyMetricsEventName$1;
|
|
47
|
-
}({});
|
|
48
|
-
const AmplitudeContext = createContext(null);
|
|
49
|
-
const AmplitudeProvider = ({ children }) => {
|
|
50
|
-
const userId = useAtomValue(userIdAtom);
|
|
51
|
-
const amplitudeApiKey = useAtomValue(amplitudeApiKeyAtom);
|
|
52
|
-
const dataResidency = useAtomValue(dataResidencyAtom);
|
|
53
|
-
const orgGaConfig = useAtomValue(orgAnalyticsGoogleAnalyticsConfigAtom);
|
|
54
|
-
const env = useAtomValue(envAtom);
|
|
55
|
-
const contextSource = useAtomValue(contextSourceAtom);
|
|
56
|
-
useAtomValue(identifyingPrefixAtom);
|
|
57
|
-
const { getItem } = useLocalStorage();
|
|
58
|
-
const { publicKey, featureOverrides, variantUrlOverride, variantInfoOverride, show, orgShortName, featureGates } = useEnviveConfig();
|
|
59
|
-
const { featureFlagService } = useFeatureFlagService();
|
|
60
|
-
const [amplitudeClient, setAmplitudeClient] = React.useState(void 0);
|
|
61
|
-
const [internalEventTrackingEnrichment, setInternalEventTrackingEnrichment] = React.useState(void 0);
|
|
62
|
-
const [supplementalDefaultProps, setSupplementalDefaultProps] = React.useState({});
|
|
63
|
-
const isReady = Boolean(userId && featureFlagService && amplitudeApiKey && userId);
|
|
64
|
-
const getDefaultTrackingProps = useCallback(() => {
|
|
65
|
-
const gatesProps = featureGates ? featureGates.reduce((acc, curr) => {
|
|
66
|
-
if (curr.name && curr.value != null) return {
|
|
67
|
-
...acc,
|
|
68
|
-
[`feature_gate.${curr.name}`]: curr.value
|
|
69
|
-
};
|
|
70
|
-
return acc;
|
|
71
|
-
}, {}) : {};
|
|
72
|
-
const experimentProps = {};
|
|
73
|
-
return {
|
|
74
|
-
...gatesProps,
|
|
75
|
-
...experimentProps,
|
|
76
|
-
...supplementalDefaultProps,
|
|
77
|
-
app_id: "commerce-chat-react-component",
|
|
78
|
-
chat_id: getItem(LocalStorageKeys.ChatId),
|
|
79
|
-
env: env || "unknown",
|
|
80
|
-
app_source: contextSource,
|
|
81
|
-
"org.short_name": orgShortName,
|
|
82
|
-
"user.id": userId,
|
|
83
|
-
"cdp.user_id": null,
|
|
84
|
-
"cdp.provider": null,
|
|
85
|
-
"event.source": "web-browser",
|
|
86
|
-
"event.type": "user-activity",
|
|
87
|
-
"event.id": null,
|
|
88
|
-
"event.channel": "web",
|
|
89
|
-
"event.timestamp": null
|
|
90
|
-
};
|
|
91
|
-
}, [
|
|
92
|
-
featureGates,
|
|
93
|
-
supplementalDefaultProps,
|
|
94
|
-
env,
|
|
95
|
-
contextSource,
|
|
96
|
-
orgShortName,
|
|
97
|
-
userId
|
|
98
|
-
]);
|
|
99
|
-
const eventPropsToPrefixedEventProps = useCallback((eventName, eventProps) => {
|
|
100
|
-
const prefix = eventName.toLowerCase().replace(/\s+/g, "_");
|
|
101
|
-
return Object.entries(eventProps).reduce((acc, [key, value$1]) => {
|
|
102
|
-
acc[`${prefix}.${key}`] = value$1;
|
|
103
|
-
return acc;
|
|
104
|
-
}, {});
|
|
105
|
-
}, []);
|
|
106
|
-
const amplitudeSessionReplayInit = useCallback(() => {
|
|
107
|
-
const isEnabled = Boolean(orgShortName === OrgShortName.UniqueVintage && featureFlagService?.isClientSessionEnabled() && featureFlagService?.isFeatureGateEnabled(FeatureGates.IsNewFeatureEnabled));
|
|
108
|
-
const sampleRate = 1;
|
|
109
|
-
try {
|
|
110
|
-
logger_default.logDebug(`[spiffy-ai] amplitude session-replay initializing isEnabled=${isEnabled} sampleRate=${sampleRate}`);
|
|
111
|
-
if (!isEnabled) return isEnabled;
|
|
112
|
-
return isEnabled;
|
|
113
|
-
} catch (e) {
|
|
114
|
-
logger_default.logError("[spiffy-ai] Error initializing amplitude session-replay", e);
|
|
115
|
-
return false;
|
|
116
|
-
}
|
|
117
|
-
}, [orgShortName, featureFlagService]);
|
|
118
|
-
const getEventTrackingEnrichment = useCallback(() => {
|
|
119
|
-
if (internalEventTrackingEnrichment !== void 0) return internalEventTrackingEnrichment;
|
|
120
|
-
const enrichment = {
|
|
121
|
-
name: "page-view-tracking-enrichment",
|
|
122
|
-
type: "enrichment",
|
|
123
|
-
setup: async () => void 0,
|
|
124
|
-
execute: async (event) => {
|
|
125
|
-
let enrichedEvent;
|
|
126
|
-
if (["[Amplitude] Page Viewed", `[Spiffy] ${SpiffyMetricsEventName.BundleLoaded}`].includes(event.event_type)) {
|
|
127
|
-
const globalProperties = {};
|
|
128
|
-
if (publicKey) globalProperties["globalProperties.publicKey"] = publicKey;
|
|
129
|
-
if (featureOverrides) Object.entries(featureOverrides).forEach(([key, value$1]) => {
|
|
130
|
-
globalProperties[`globalProperties.featureOverrides.${key}`] = String(value$1);
|
|
131
|
-
});
|
|
132
|
-
if (variantUrlOverride) globalProperties["globalProperties.variantUrlOverride"] = variantUrlOverride;
|
|
133
|
-
if (variantInfoOverride) globalProperties["globalProperties.variantInfoOverride"] = JSON.stringify(variantInfoOverride);
|
|
134
|
-
if (show != null) globalProperties["globalProperties.show"] = String(show);
|
|
135
|
-
const enabledFeatures = featureFlagService.getFeatureFlags();
|
|
136
|
-
const enabledFeaturesProperties = Object.entries(enabledFeatures).reduce((acc, [key, value$1]) => ({
|
|
137
|
-
...acc,
|
|
138
|
-
[`enabledFeatures.${key}`]: `${value$1}`
|
|
139
|
-
}), {});
|
|
140
|
-
const timingProperties = { "timing.enriched_at_ms": window.performance?.now() };
|
|
141
|
-
enrichedEvent = {
|
|
142
|
-
...event,
|
|
143
|
-
event_properties: {
|
|
144
|
-
...event.event_properties,
|
|
145
|
-
...getDefaultTrackingProps(),
|
|
146
|
-
...globalProperties,
|
|
147
|
-
...enabledFeaturesProperties,
|
|
148
|
-
...timingProperties
|
|
149
|
-
}
|
|
150
|
-
};
|
|
151
|
-
} else enrichedEvent = event;
|
|
152
|
-
EventsDispatcher.dispatch(SpiffyEvent.AMPLITUDE_EVENT, enrichedEvent);
|
|
153
|
-
return enrichedEvent;
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
setInternalEventTrackingEnrichment(enrichment);
|
|
157
|
-
return enrichment;
|
|
158
|
-
}, [
|
|
159
|
-
internalEventTrackingEnrichment,
|
|
160
|
-
getDefaultTrackingProps,
|
|
161
|
-
featureFlagService,
|
|
162
|
-
publicKey,
|
|
163
|
-
featureOverrides,
|
|
164
|
-
variantUrlOverride,
|
|
165
|
-
variantInfoOverride,
|
|
166
|
-
show
|
|
167
|
-
]);
|
|
168
|
-
useEffect(() => {
|
|
169
|
-
if (isReady && !amplitudeClient) {
|
|
170
|
-
const currentAmplitudeInstance = createInstance();
|
|
171
|
-
const isSessionsEnabled = amplitudeSessionReplayInit();
|
|
172
|
-
currentAmplitudeInstance.add(getEventTrackingEnrichment());
|
|
173
|
-
currentAmplitudeInstance.init(amplitudeApiKey, userId, {
|
|
174
|
-
serverZone: dataResidency,
|
|
175
|
-
trackingOptions: { ipAddress: true },
|
|
176
|
-
autocapture: {
|
|
177
|
-
attribution: true,
|
|
178
|
-
pageViews: { trackHistoryChanges: "pathOnly" },
|
|
179
|
-
sessions: isSessionsEnabled,
|
|
180
|
-
formInteractions: false,
|
|
181
|
-
fileDownloads: false
|
|
182
|
-
}
|
|
183
|
-
});
|
|
184
|
-
setAmplitudeClient(currentAmplitudeInstance);
|
|
185
|
-
}
|
|
186
|
-
}, [
|
|
187
|
-
isReady,
|
|
188
|
-
amplitudeClient,
|
|
189
|
-
amplitudeApiKey,
|
|
190
|
-
userId,
|
|
191
|
-
dataResidency,
|
|
192
|
-
amplitudeSessionReplayInit,
|
|
193
|
-
getEventTrackingEnrichment
|
|
194
|
-
]);
|
|
195
|
-
const trackEvent = useCallback(async ({ eventName, eventProps, eventGroups, alsoSendToGoogleAnalytics = false }) => {
|
|
196
|
-
logger_default.logDebug("Submitting event", eventName);
|
|
197
|
-
try {
|
|
198
|
-
const decoratedEventName = `[Spiffy] ${eventName}`;
|
|
199
|
-
if (!amplitudeClient) {
|
|
200
|
-
logger_default.logWarn("amplitude client undefined", void 0, { event_name: decoratedEventName });
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
const eventData = JSON.stringify({
|
|
204
|
-
eventName,
|
|
205
|
-
eventProps,
|
|
206
|
-
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
207
|
-
});
|
|
208
|
-
const data = new TextEncoder().encode(eventData);
|
|
209
|
-
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
210
|
-
const currentInsertId = Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
211
|
-
logger_default.logDebug(`amplitude tracking ${decoratedEventName}`, null, {
|
|
212
|
-
event_name: decoratedEventName,
|
|
213
|
-
props: eventProps
|
|
214
|
-
});
|
|
215
|
-
amplitudeClient.track(decoratedEventName, {
|
|
216
|
-
...getDefaultTrackingProps(),
|
|
217
|
-
...eventProps,
|
|
218
|
-
...eventProps ? eventPropsToPrefixedEventProps(eventName, eventProps) : {}
|
|
219
|
-
}, {
|
|
220
|
-
...eventGroups,
|
|
221
|
-
insert_id: currentInsertId
|
|
222
|
-
});
|
|
223
|
-
if (alsoSendToGoogleAnalytics && orgGaConfig) {
|
|
224
|
-
logger_default.logDebug("[spiffy-ai] GA tracking", decoratedEventName);
|
|
225
|
-
if (window.dataLayer) window.dataLayer.push({
|
|
226
|
-
event: decoratedEventName,
|
|
227
|
-
eventProps
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
} catch (err) {
|
|
231
|
-
logger_default.logError("[spiffy-ai] Error tracking event", err, {
|
|
232
|
-
eventName,
|
|
233
|
-
eventProps
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
}, [
|
|
237
|
-
amplitudeClient,
|
|
238
|
-
getDefaultTrackingProps,
|
|
239
|
-
eventPropsToPrefixedEventProps,
|
|
240
|
-
orgGaConfig
|
|
241
|
-
]);
|
|
242
|
-
const value = useMemo(() => ({
|
|
243
|
-
trackEvent,
|
|
244
|
-
isReady,
|
|
245
|
-
setSupplementalDefaultProps: (props) => setSupplementalDefaultProps(props)
|
|
246
|
-
}), [
|
|
247
|
-
trackEvent,
|
|
248
|
-
isReady,
|
|
249
|
-
setSupplementalDefaultProps
|
|
250
|
-
]);
|
|
251
|
-
return /* @__PURE__ */ jsx(AmplitudeContext.Provider, {
|
|
252
|
-
value,
|
|
253
|
-
children
|
|
254
|
-
});
|
|
255
|
-
};
|
|
256
|
-
const useAmplitude = () => {
|
|
257
|
-
const context = useContext(AmplitudeContext);
|
|
258
|
-
if (!context) throw new Error("useAmplitude must be used within AmplitudeProvider");
|
|
259
|
-
return context;
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
//#endregion
|
|
263
|
-
export { AmplitudeProvider, SpiffyMetricsEventName, useAmplitude };
|
|
264
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW1wbGl0dWRlQ29udGV4dC1ET3FMMlZuOC5qcyIsIm5hbWVzIjpbIkFtcGxpdHVkZVByb3ZpZGVyOiBSZWFjdC5GQzx7IGNoaWxkcmVuOiBSZWFjdC5SZWFjdE5vZGUgfT4iLCJ2YWx1ZSIsImVucmljaG1lbnQ6IEVucmljaG1lbnRQbHVnaW4iLCJlbnJpY2hlZEV2ZW50OiBFdmVudCIsImdsb2JhbFByb3BlcnRpZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4iLCJjdXJyZW50QW1wbGl0dWRlSW5zdGFuY2U6IEJyb3dzZXJDbGllbnQiXSwic291cmNlcyI6WyIuLi9zcmMvY29udGV4dHMvYW1wbGl0dWRlQ29udGV4dC9hbXBsaXR1ZGVDb250ZXh0LnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUmVhY3QsIHtcbiAgY3JlYXRlQ29udGV4dCxcbiAgdXNlQ29udGV4dCxcbiAgdXNlQ2FsbGJhY2ssXG4gIHVzZU1lbW8sXG4gIHVzZUVmZmVjdCxcbn0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyB1c2VBdG9tVmFsdWUgfSBmcm9tIFwiam90YWlcIjtcbmltcG9ydCB7IGNyZWF0ZUluc3RhbmNlIH0gZnJvbSBcIkBhbXBsaXR1ZGUvYW5hbHl0aWNzLWJyb3dzZXJcIjtcbmltcG9ydCB7IEZlYXR1cmVHYXRlcyB9IGZyb20gXCJzcmMvYXBwbGljYXRpb24vbW9kZWxzL2ZlYXR1cmVHYXRlc1wiO1xuaW1wb3J0IHsgT3JnU2hvcnROYW1lIH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9tb2RlbHNcIjtcbmltcG9ydCB7IEV2ZW50c0Rpc3BhdGNoZXIsIFNwaWZmeUV2ZW50IH0gZnJvbSBcInNyYy9ldmVudHNcIjtcbmltcG9ydCB7XG4gIGFtcGxpdHVkZUFwaUtleUF0b20sXG4gIGNvbnRleHRTb3VyY2VBdG9tLFxuICBkYXRhUmVzaWRlbmN5QXRvbSxcbiAgaWRlbnRpZnlpbmdQcmVmaXhBdG9tLFxufSBmcm9tIFwic3JjL2F0b21zL2Vudml2ZS9lbnZpdmVDb25maWdcIjtcbmltcG9ydCB7XG4gIExvY2FsU3RvcmFnZUtleXMsXG4gIHVzZUxvY2FsU3RvcmFnZSxcbn0gZnJvbSBcInNyYy9jb250ZXh0cy9sb2NhbFN0b3JhZ2VDb250ZXh0XCI7XG5pbXBvcnQgeyBvcmdBbmFseXRpY3NHb29nbGVBbmFseXRpY3NDb25maWdBdG9tIH0gZnJvbSBcInNyYy9hdG9tcy9vcmcvb3JnQW5hbHl0aWNzQ29uZmlnXCI7XG5pbXBvcnQgeyB1c2VySWRBdG9tIH0gZnJvbSBcInNyYy9hdG9tcy9hcHBcIjtcbmltcG9ydCB7IGVudkF0b20gfSBmcm9tIFwic3JjL2F0b21zL2Vudml2ZS9lbnZpdmVDb25maWdcIjtcbmltcG9ydCBMb2dnZXIgZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9sb2dnaW5nL2xvZ2dlclwiO1xuaW1wb3J0IHR5cGUge1xuICBCcm93c2VyQ2xpZW50LFxuICBFbnJpY2htZW50UGx1Z2luLFxuICBFdmVudCxcbiAgU2VydmVyWm9uZVR5cGUsXG59IGZyb20gXCJAYW1wbGl0dWRlL2FuYWx5dGljcy10eXBlc1wiO1xuaW1wb3J0IHsgdXNlRW52aXZlQ29uZmlnIH0gZnJvbSBcInNyYy9jb250ZXh0cy9lbnZpdmVDb25maWdDb250ZXh0L2Vudml2ZUNvbmZpZ0NvbnRleHRcIjtcbmltcG9ydCB7XG4gIHVzZUZlYXR1cmVGbGFnU2VydmljZSxcbn0gZnJvbSBcInNyYy9jb250ZXh0cy9mZWF0dXJlRmxhZ1NlcnZpY2VDb250ZXh0L2ZlYXR1cmVGbGFnU2VydmljZUNvbnRleHRcIjtcbmltcG9ydCB7IHVzZVVzZXJJZGVudGl0eSB9IGZyb20gXCJzcmMvY29udGV4dHMvdXNlcklkZW50aXR5Q29udGV4dC91c2VySWRlbnRpdHlDb250ZXh0XCI7XG5cbmV4cG9ydCBlbnVtIFNwaWZmeU1ldHJpY3NFdmVudE5hbWUge1xuICBCdW5kbGVMb2FkZWQgPSBcIkJ1bmRsZSBMb2FkZWRcIixcbiAgQ2hhdExpdmVBZ2VudEJ0bkNsaWNrID0gXCJDaGF0IExpdmUgQWdlbnQgQnRuIENsaWNrXCIsXG4gIENoYXRGbG9hdGluZ0J1dHRvblZpc2libGUgPSBcIkNoYXQgRmxvYXRpbmcgQnV0dG9uIFZpc2libGVcIixcbiAgQ2hhdENvbXBvbmVudFZpc2libGUgPSBcIkNoYXQgQ29tcG9uZW50IFZpc2libGVcIixcbiAgQ2hhdENvbXBvbmVudEV4cGFuZGVkID0gXCJDaGF0IENvbXBvbmVudCBFeHBhbmRlZFwiLFxuICBDaGF0Q29tcG9uZW50Q29sbGFwc2VkID0gXCJDaGF0IENvbXBvbmVudCBDb2xsYXBzZWRcIixcbiAgQ2hhdFVzZXJNZXNzYWdlSW5wdXQgPSBcIkNoYXQgVXNlciBNZXNzYWdlIElucHV0XCIsXG4gIENoYXRTdWdnZXN0aW9uQ2xpY2tlZCA9IFwiQ2hhdCBTdWdnZXN0aW9uIENsaWNrZWRcIixcbiAgQ2hhdEFzc2lzdGFudFJlc3BvbnNlID0gXCJDaGF0IEFzc2lzdGFudCBSZXNwb25zZVwiLFxuICBQcm9kdWN0Q2FyZENsaWNrZWQgPSBcIlByb2R1Y3QgQ2FyZCBDbGlja2VkXCIsXG4gIFByb2R1Y3RSZXZpZXdDYXJkQ2xpY2tlZCA9IFwiUHJvZHVjdCBSZXZpZXcgQ2FyZCBDbGlja2VkXCIsXG4gIEFkZFRvQ2FydENsaWNrZWQgPSBcIkFkZCB0byBDYXJ0IENsaWNrZWRcIixcbiAgUHJvbXB0Q2FyZENsaWNrZWQgPSBcIlByb21wdCBDYXJkIENsaWNrZWRcIixcbiAgU3VwcG9ydGVkRXZlbnQgPSBcIlN1cHBvcnRlZCBFdmVudFwiLFxuICBTZWFyY2hCYWNrVG9SZXNwb25zZUNsaWNrZWQgPSBcIlNlYXJjaCBCYWNrIHRvIFJlc3BvbnNlIENsaWNrZWRcIixcbiAgUGVyZm9ybWFuY2VNZXRyaWNzID0gXCJQZXJmb3JtYW5jZSBNZXRyaWNzXCIsXG4gIFNlYXJjaEJhckNsaWNrZWQgPSBcIlNlYXJjaCBCYXIgQ2xpY2tlZFwiLFxuICBPcmRlckxvb2t1cFN0YXJ0ZWQgPSBcIk9yZGVyIExvb2t1cCBTdGFydGVkXCIsXG4gIE9yZGVyTG9va3VwRm9ybVN1Ym1pdHRlZCA9IFwiT3JkZXIgTG9va3VwIEZvcm0gU3VibWl0dGVkXCIsXG4gIFNlYXJjaENvbXBvbmVudFZpc2libGUgPSBcIlNlYXJjaCBDb21wb25lbnQgVmlzaWJsZVwiLFxuICBTZWFyY2haZXJvU3RhdGVTdWdnZXN0aW9uQ2xpY2tlZCA9IFwiU2VhcmNoIFplcm8gU3RhdGUgU3VnZ2VzdGlvbiBDbGlja2VkXCIsIC8vIFRoaXMgaXMgdGhlIHNjcm9sbGluZyBsaXN0IG9mIHN1Z2dlc3Rpb24gYnV0dG9ucyBpbiBnbG9iYWwgc2VhcmNoXG4gIFNlYXJjaElucHV0U3RhcnRlZCA9IFwiU2VhcmNoIElucHV0IFN0YXJ0ZWRcIixcbiAgU2VhcmNoUXVlcnlTdWJtaXR0ZWQgPSBcIlNlYXJjaCBRdWVyeSBTdWJtaXR0ZWRcIixcbiAgLy8gU2VhcmNoQXV0b2NvbXBsZXRlVmlld2VkID0gJ1NlYXJjaCBBdXRvY29tcGxldGUgVmlld2VkJywgLy8gVE9ETzogYWRkIHRoaXMgd2hlbiBhdXRvY29tcGxldGUgaXMgYWRkZWRcbiAgLy8gU2VhcmNoQXV0b2NvbXBsZXRlQ2xpY2tlZCA9ICdTZWFyY2ggQXV0b2NvbXBsZXRlIENsaWNrZWQnLCAvLyBUT0RPOiBhZGQgdGhpcyB3aGVuIGF1dG9jb21wbGV0ZSBpcyBhZGRlZFxuICBTZWFyY2hSZXN1bHRzVmlld2VkID0gXCJTZWFyY2ggUmVzdWx0cyBWaWV3ZWRcIixcbiAgU2VhcmNoVGltZVRvRmlyc3RDbGljayA9IFwiU2VhcmNoIFRpbWUgdG8gRmlyc3QgQ2xpY2tcIixcbiAgU2VhcmNoWmVyb1Jlc3VsdHNSYXRlID0gXCJTZWFyY2ggWmVybyBSZXN1bHRzIFJhdGVcIixcbiAgU2VhcmNoRmlsdGVyQ2xpY2tlZCA9IFwiU2VhcmNoIEZpbHRlciBDbGlja2VkXCIsXG4gIFNlYXJjaFNvcnRDbGlja2VkID0gXCJTZWFyY2ggU29ydCBDbGlja2VkXCIsXG59XG5cbmludGVyZmFjZSBUcmFja0V2ZW50UGFyYW1zIHtcbiAgZXZlbnROYW1lOiBTcGlmZnlNZXRyaWNzRXZlbnROYW1lO1xuICBldmVudFByb3BzPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIGV2ZW50R3JvdXBzPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIGFsc29TZW5kVG9Hb29nbGVBbmFseXRpY3M/OiBib29sZWFuO1xufVxuXG5pbnRlcmZhY2UgQW1wbGl0dWRlQ29udGV4dFR5cGUge1xuICB0cmFja0V2ZW50OiAocGFyYW1zOiBUcmFja0V2ZW50UGFyYW1zKSA9PiBQcm9taXNlPHZvaWQ+O1xuICBpc1JlYWR5OiBib29sZWFuO1xuICBzZXRTdXBwbGVtZW50YWxEZWZhdWx0UHJvcHM6IChwcm9wczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IHZvaWQ7XG59XG5cbmNvbnN0IEFtcGxpdHVkZUNvbnRleHQgPSBjcmVhdGVDb250ZXh0PEFtcGxpdHVkZUNvbnRleHRUeXBlIHwgbnVsbD4obnVsbCk7XG5cbmV4cG9ydCBjb25zdCBBbXBsaXR1ZGVQcm92aWRlcjogUmVhY3QuRkM8eyBjaGlsZHJlbjogUmVhY3QuUmVhY3ROb2RlIH0+ID0gKHtcbiAgY2hpbGRyZW4sXG59KSA9PiB7XG4gIGNvbnN0IHVzZXJJZCA9IHVzZUF0b21WYWx1ZSh1c2VySWRBdG9tKTtcbiAgY29uc3QgYW1wbGl0dWRlQXBpS2V5ID0gdXNlQXRvbVZhbHVlKGFtcGxpdHVkZUFwaUtleUF0b20pO1xuICBjb25zdCBkYXRhUmVzaWRlbmN5ID0gdXNlQXRvbVZhbHVlKGRhdGFSZXNpZGVuY3lBdG9tKTtcbiAgY29uc3Qgb3JnR2FDb25maWcgPSB1c2VBdG9tVmFsdWUob3JnQW5hbHl0aWNzR29vZ2xlQW5hbHl0aWNzQ29uZmlnQXRvbSk7XG4gIGNvbnN0IGVudiA9IHVzZUF0b21WYWx1ZShlbnZBdG9tKTtcbiAgY29uc3QgY29udGV4dFNvdXJjZSA9IHVzZUF0b21WYWx1ZShjb250ZXh0U291cmNlQXRvbSk7XG4gIGNvbnN0IGlkZW50aWZ5aW5nUHJlZml4ID0gdXNlQXRvbVZhbHVlKGlkZW50aWZ5aW5nUHJlZml4QXRvbSk7XG4gIGNvbnN0IHsgZ2V0SXRlbSB9ID0gdXNlTG9jYWxTdG9yYWdlKCk7XG4gIGNvbnN0IHtcbiAgICBwdWJsaWNLZXksXG4gICAgZmVhdHVyZU92ZXJyaWRlcyxcbiAgICB2YXJpYW50VXJsT3ZlcnJpZGUsXG4gICAgdmFyaWFudEluZm9PdmVycmlkZSxcbiAgICBzaG93LFxuICAgIG9yZ1Nob3J0TmFtZSxcbiAgICBmZWF0dXJlR2F0ZXMsXG4gIH0gPSB1c2VFbnZpdmVDb25maWcoKTtcblxuICBjb25zdCB7IGZlYXR1cmVGbGFnU2VydmljZSB9ID0gdXNlRmVhdHVyZUZsYWdTZXJ2aWNlKCk7XG5cbiAgY29uc3QgW2FtcGxpdHVkZUNsaWVudCwgc2V0QW1wbGl0dWRlQ2xpZW50XSA9IFJlYWN0LnVzZVN0YXRlPFxuICAgIEJyb3dzZXJDbGllbnQgfCB1bmRlZmluZWRcbiAgPih1bmRlZmluZWQpO1xuICBjb25zdCBbaW50ZXJuYWxFdmVudFRyYWNraW5nRW5yaWNobWVudCwgc2V0SW50ZXJuYWxFdmVudFRyYWNraW5nRW5yaWNobWVudF0gPVxuICAgIFJlYWN0LnVzZVN0YXRlPEVucmljaG1lbnRQbHVnaW4gfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gIGNvbnN0IFtzdXBwbGVtZW50YWxEZWZhdWx0UHJvcHMsIHNldFN1cHBsZW1lbnRhbERlZmF1bHRQcm9wc10gPVxuICAgIFJlYWN0LnVzZVN0YXRlPFJlY29yZDxzdHJpbmcsIHVua25vd24+Pih7fSk7XG5cbiAgY29uc3QgaXNSZWFkeSA9IEJvb2xlYW4oXG4gICAgdXNlcklkICYmIGZlYXR1cmVGbGFnU2VydmljZSAmJiBhbXBsaXR1ZGVBcGlLZXkgJiYgdXNlcklkXG4gICk7XG5cbiAgY29uc3QgZ2V0RGVmYXVsdFRyYWNraW5nUHJvcHMgPSB1c2VDYWxsYmFjaygoKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPT4ge1xuICAgIGNvbnN0IGdhdGVzUHJvcHMgPSBmZWF0dXJlR2F0ZXNcbiAgICAgID8gZmVhdHVyZUdhdGVzLnJlZHVjZTxSZWNvcmQ8c3RyaW5nLCBib29sZWFuPj4oKGFjYywgY3VycikgPT4ge1xuICAgICAgICAgIGlmIChjdXJyLm5hbWUgJiYgY3Vyci52YWx1ZSAhPSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4geyAuLi5hY2MsIFtgZmVhdHVyZV9nYXRlLiR7Y3Vyci5uYW1lfWBdOiBjdXJyLnZhbHVlIH07XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgIH0sIHt9KVxuICAgICAgOiB7fTtcbiAgICBjb25zdCBleHBlcmltZW50UHJvcHMgPSB7fTsgLy8gTm8gZGlyZWN0IGVxdWl2YWxlbnQgZm9yIGV4cGVyaW1lbnRzIGluIEVudml2ZUNvbmZpZyB5ZXRcblxuICAgIGNvbnN0IG9yZ0xldmVsQW1wbGl0dWRlVHJhY2tpbmdQcm9wcyA9IHtcbiAgICAgIC4uLmdhdGVzUHJvcHMsXG4gICAgICAuLi5leHBlcmltZW50UHJvcHMsXG4gICAgfTtcblxuICAgIHJldHVybiB7XG4gICAgICAuLi5vcmdMZXZlbEFtcGxpdHVkZVRyYWNraW5nUHJvcHMsXG4gICAgICAuLi5zdXBwbGVtZW50YWxEZWZhdWx0UHJvcHMsXG4gICAgICAvLyBUT0RPOiBvcmdfaWQgaXMgbm90IGRpcmVjdGx5IGF2YWlsYWJsZSBpbiBFbnZpdmVDb25maWcuIE5lZWQgdG8gZmluZCBhIG5ldyBzb3VyY2Ugb3IgZGVyaXZlIGl0LlxuICAgICAgLy8gb3JnX2lkOiBvcmdDb25maWc/Lm9yZz8ub3JnPy5pZCxcbiAgICAgIGFwcF9pZDogXCJjb21tZXJjZS1jaGF0LXJlYWN0LWNvbXBvbmVudFwiLFxuICAgICAgY2hhdF9pZDogZ2V0SXRlbShMb2NhbFN0b3JhZ2VLZXlzLkNoYXRJZCksXG4gICAgICBlbnY6IGVudiB8fCBcInVua25vd25cIixcbiAgICAgIGFwcF9zb3VyY2U6IGNvbnRleHRTb3VyY2UsXG4gICAgICBcIm9yZy5zaG9ydF9uYW1lXCI6IG9yZ1Nob3J0TmFtZSxcbiAgICAgIFwidXNlci5pZFwiOiB1c2VySWQsXG4gICAgICBcImNkcC51c2VyX2lkXCI6IG51bGwsXG4gICAgICBcImNkcC5wcm92aWRlclwiOiBudWxsLFxuICAgICAgXCJldmVudC5zb3VyY2VcIjogXCJ3ZWItYnJvd3NlclwiLFxuICAgICAgXCJldmVudC50eXBlXCI6IFwidXNlci1hY3Rpdml0eVwiLFxuICAgICAgXCJldmVudC5pZFwiOiBudWxsLFxuICAgICAgXCJldmVudC5jaGFubmVsXCI6IFwid2ViXCIsXG4gICAgICBcImV2ZW50LnRpbWVzdGFtcFwiOiBudWxsLFxuICAgIH07XG4gIH0sIFtcbiAgICBmZWF0dXJlR2F0ZXMsXG4gICAgc3VwcGxlbWVudGFsRGVmYXVsdFByb3BzLFxuICAgIGVudixcbiAgICBjb250ZXh0U291cmNlLFxuICAgIG9yZ1Nob3J0TmFtZSxcbiAgICB1c2VySWQsXG4gIF0pO1xuXG4gIGNvbnN0IGV2ZW50UHJvcHNUb1ByZWZpeGVkRXZlbnRQcm9wcyA9IHVzZUNhbGxiYWNrKFxuICAgIChcbiAgICAgIGV2ZW50TmFtZTogU3BpZmZ5TWV0cmljc0V2ZW50TmFtZSxcbiAgICAgIGV2ZW50UHJvcHM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+XG4gICAgKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPT4ge1xuICAgICAgY29uc3QgcHJlZml4ID0gZXZlbnROYW1lLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvXFxzKy9nLCBcIl9cIik7XG4gICAgICByZXR1cm4gT2JqZWN0LmVudHJpZXMoZXZlbnRQcm9wcykucmVkdWNlKChhY2MsIFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgICBhY2NbYCR7cHJlZml4fS4ke2tleX1gXSA9IHZhbHVlO1xuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSwge30gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pO1xuICAgIH0sXG4gICAgW11cbiAgKTtcblxuICBjb25zdCBhbXBsaXR1ZGVTZXNzaW9uUmVwbGF5SW5pdCA9IHVzZUNhbGxiYWNrKCgpOiBib29sZWFuID0+IHtcbiAgICBjb25zdCBpc0VuYWJsZWQgPSBCb29sZWFuKFxuICAgICAgb3JnU2hvcnROYW1lID09PSBPcmdTaG9ydE5hbWUuVW5pcXVlVmludGFnZSAmJlxuICAgICAgICBmZWF0dXJlRmxhZ1NlcnZpY2U/LmlzQ2xpZW50U2Vzc2lvbkVuYWJsZWQoKSAmJlxuICAgICAgICBmZWF0dXJlRmxhZ1NlcnZpY2U/LmlzRmVhdHVyZUdhdGVFbmFibGVkKFxuICAgICAgICAgIEZlYXR1cmVHYXRlcy5Jc05ld0ZlYXR1cmVFbmFibGVkXG4gICAgICAgIClcbiAgICApO1xuICAgIGNvbnN0IHNhbXBsZVJhdGUgPSAxO1xuXG4gICAgdHJ5IHtcbiAgICAgIExvZ2dlci5sb2dEZWJ1ZyhcbiAgICAgICAgYFtzcGlmZnktYWldIGFtcGxpdHVkZSBzZXNzaW9uLXJlcGxheSBpbml0aWFsaXppbmcgaXNFbmFibGVkPSR7aXNFbmFibGVkfSBzYW1wbGVSYXRlPSR7c2FtcGxlUmF0ZX1gXG4gICAgICApO1xuXG4gICAgICBpZiAoIWlzRW5hYmxlZCkge1xuICAgICAgICByZXR1cm4gaXNFbmFibGVkO1xuICAgICAgfVxuXG4gICAgICAvLyBhbXBsaXR1ZGVJbnN0YW5jZS5hZGQoc2Vzc2lvblJlcGxheVBsdWdpbih7IHNhbXBsZVJhdGUgfSkpO1xuXG4gICAgICByZXR1cm4gaXNFbmFibGVkO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIExvZ2dlci5sb2dFcnJvcihcbiAgICAgICAgXCJbc3BpZmZ5LWFpXSBFcnJvciBpbml0aWFsaXppbmcgYW1wbGl0dWRlIHNlc3Npb24tcmVwbGF5XCIsXG4gICAgICAgIGVcbiAgICAgICk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9LCBbb3JnU2hvcnROYW1lLCBmZWF0dXJlRmxhZ1NlcnZpY2VdKTtcblxuICBjb25zdCBnZXRFdmVudFRyYWNraW5nRW5yaWNobWVudCA9IHVzZUNhbGxiYWNrKCgpOiBFbnJpY2htZW50UGx1Z2luID0+IHtcbiAgICBpZiAoaW50ZXJuYWxFdmVudFRyYWNraW5nRW5yaWNobWVudCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gaW50ZXJuYWxFdmVudFRyYWNraW5nRW5yaWNobWVudDtcbiAgICB9XG5cbiAgICBjb25zdCBlbnJpY2htZW50OiBFbnJpY2htZW50UGx1Z2luID0ge1xuICAgICAgbmFtZTogXCJwYWdlLXZpZXctdHJhY2tpbmctZW5yaWNobWVudFwiLFxuICAgICAgdHlwZTogXCJlbnJpY2htZW50XCIsXG4gICAgICBzZXR1cDogYXN5bmMgKCkgPT4gdW5kZWZpbmVkLFxuICAgICAgZXhlY3V0ZTogYXN5bmMgKGV2ZW50OiBFdmVudCk6IFByb21pc2U8RXZlbnQ+ID0+IHtcbiAgICAgICAgbGV0IGVucmljaGVkRXZlbnQ6IEV2ZW50O1xuXG4gICAgICAgIGNvbnN0IGV2ZW50c1RvRW5yaWNoID0gW1xuICAgICAgICAgIFwiW0FtcGxpdHVkZV0gUGFnZSBWaWV3ZWRcIixcbiAgICAgICAgICBgW1NwaWZmeV0gJHtTcGlmZnlNZXRyaWNzRXZlbnROYW1lLkJ1bmRsZUxvYWRlZH1gLFxuICAgICAgICBdO1xuXG4gICAgICAgIGlmIChldmVudHNUb0VucmljaC5pbmNsdWRlcyhldmVudC5ldmVudF90eXBlKSkge1xuICAgICAgICAgIGNvbnN0IGdsb2JhbFByb3BlcnRpZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblxuICAgICAgICAgIGlmIChwdWJsaWNLZXkpIHtcbiAgICAgICAgICAgIGdsb2JhbFByb3BlcnRpZXNbXCJnbG9iYWxQcm9wZXJ0aWVzLnB1YmxpY0tleVwiXSA9IHB1YmxpY0tleTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGZlYXR1cmVPdmVycmlkZXMpIHtcbiAgICAgICAgICAgIE9iamVjdC5lbnRyaWVzKGZlYXR1cmVPdmVycmlkZXMpLmZvckVhY2goKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgICAgICAgICBnbG9iYWxQcm9wZXJ0aWVzW2BnbG9iYWxQcm9wZXJ0aWVzLmZlYXR1cmVPdmVycmlkZXMuJHtrZXl9YF0gPVxuICAgICAgICAgICAgICAgIFN0cmluZyh2YWx1ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHZhcmlhbnRVcmxPdmVycmlkZSkge1xuICAgICAgICAgICAgZ2xvYmFsUHJvcGVydGllc1tcImdsb2JhbFByb3BlcnRpZXMudmFyaWFudFVybE92ZXJyaWRlXCJdID1cbiAgICAgICAgICAgICAgdmFyaWFudFVybE92ZXJyaWRlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodmFyaWFudEluZm9PdmVycmlkZSkge1xuICAgICAgICAgICAgZ2xvYmFsUHJvcGVydGllc1tcImdsb2JhbFByb3BlcnRpZXMudmFyaWFudEluZm9PdmVycmlkZVwiXSA9XG4gICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHZhcmlhbnRJbmZvT3ZlcnJpZGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoc2hvdyAhPSBudWxsKSB7XG4gICAgICAgICAgICBnbG9iYWxQcm9wZXJ0aWVzW1wiZ2xvYmFsUHJvcGVydGllcy5zaG93XCJdID0gU3RyaW5nKHNob3cpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGVuYWJsZWRGZWF0dXJlcyA9IGZlYXR1cmVGbGFnU2VydmljZSEuZ2V0RmVhdHVyZUZsYWdzKCk7XG4gICAgICAgICAgY29uc3QgZW5hYmxlZEZlYXR1cmVzUHJvcGVydGllcyA9IE9iamVjdC5lbnRyaWVzKFxuICAgICAgICAgICAgZW5hYmxlZEZlYXR1cmVzXG4gICAgICAgICAgKS5yZWR1Y2U8UmVjb3JkPHN0cmluZywgc3RyaW5nPj4oXG4gICAgICAgICAgICAoYWNjLCBba2V5LCB2YWx1ZV0pID0+ICh7XG4gICAgICAgICAgICAgIC4uLmFjYyxcbiAgICAgICAgICAgICAgW2BlbmFibGVkRmVhdHVyZXMuJHtrZXl9YF06IGAke3ZhbHVlfWAsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHt9XG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGNvbnN0IHRpbWluZ1Byb3BlcnRpZXMgPSB7XG4gICAgICAgICAgICBcInRpbWluZy5lbnJpY2hlZF9hdF9tc1wiOiB3aW5kb3cucGVyZm9ybWFuY2U/Lm5vdygpLFxuICAgICAgICAgIH07XG5cbiAgICAgICAgICBlbnJpY2hlZEV2ZW50ID0ge1xuICAgICAgICAgICAgLi4uZXZlbnQsXG4gICAgICAgICAgICBldmVudF9wcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgIC4uLmV2ZW50LmV2ZW50X3Byb3BlcnRpZXMsXG4gICAgICAgICAgICAgIC4uLmdldERlZmF1bHRUcmFja2luZ1Byb3BzKCksXG4gICAgICAgICAgICAgIC4uLmdsb2JhbFByb3BlcnRpZXMsXG4gICAgICAgICAgICAgIC4uLmVuYWJsZWRGZWF0dXJlc1Byb3BlcnRpZXMsXG4gICAgICAgICAgICAgIC4uLnRpbWluZ1Byb3BlcnRpZXMsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZW5yaWNoZWRFdmVudCA9IGV2ZW50O1xuICAgICAgICB9XG5cbiAgICAgICAgRXZlbnRzRGlzcGF0Y2hlci5kaXNwYXRjaChTcGlmZnlFdmVudC5BTVBMSVRVREVfRVZFTlQsIGVucmljaGVkRXZlbnQpO1xuXG4gICAgICAgIHJldHVybiBlbnJpY2hlZEV2ZW50O1xuICAgICAgfSxcbiAgICB9O1xuICAgIHNldEludGVybmFsRXZlbnRUcmFja2luZ0VucmljaG1lbnQoZW5yaWNobWVudCk7XG4gICAgcmV0dXJuIGVucmljaG1lbnQ7XG4gIH0sIFtcbiAgICBpbnRlcm5hbEV2ZW50VHJhY2tpbmdFbnJpY2htZW50LFxuICAgIGdldERlZmF1bHRUcmFja2luZ1Byb3BzLFxuICAgIGZlYXR1cmVGbGFnU2VydmljZSxcbiAgICBwdWJsaWNLZXksXG4gICAgZmVhdHVyZU92ZXJyaWRlcyxcbiAgICB2YXJpYW50VXJsT3ZlcnJpZGUsXG4gICAgdmFyaWFudEluZm9PdmVycmlkZSxcbiAgICBzaG93LFxuICBdKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChpc1JlYWR5ICYmICFhbXBsaXR1ZGVDbGllbnQpIHtcbiAgICAgIGNvbnN0IGN1cnJlbnRBbXBsaXR1ZGVJbnN0YW5jZTogQnJvd3NlckNsaWVudCA9IGNyZWF0ZUluc3RhbmNlKCk7XG4gICAgICBjb25zdCBpc1Nlc3Npb25zRW5hYmxlZCA9IGFtcGxpdHVkZVNlc3Npb25SZXBsYXlJbml0KCk7XG4gICAgICBjdXJyZW50QW1wbGl0dWRlSW5zdGFuY2UuYWRkKGdldEV2ZW50VHJhY2tpbmdFbnJpY2htZW50KCkpO1xuICAgICAgY3VycmVudEFtcGxpdHVkZUluc3RhbmNlLmluaXQoYW1wbGl0dWRlQXBpS2V5ISwgdXNlcklkISwge1xuICAgICAgICBzZXJ2ZXJab25lOiBkYXRhUmVzaWRlbmN5IGFzIFNlcnZlclpvbmVUeXBlLFxuICAgICAgICB0cmFja2luZ09wdGlvbnM6IHtcbiAgICAgICAgICBpcEFkZHJlc3M6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICAgIGF1dG9jYXB0dXJlOiB7XG4gICAgICAgICAgYXR0cmlidXRpb246IHRydWUsXG4gICAgICAgICAgcGFnZVZpZXdzOiB7XG4gICAgICAgICAgICB0cmFja0hpc3RvcnlDaGFuZ2VzOiBcInBhdGhPbmx5XCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzZXNzaW9uczogaXNTZXNzaW9uc0VuYWJsZWQsXG4gICAgICAgICAgZm9ybUludGVyYWN0aW9uczogZmFsc2UsXG4gICAgICAgICAgZmlsZURvd25sb2FkczogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIHNldEFtcGxpdHVkZUNsaWVudChjdXJyZW50QW1wbGl0dWRlSW5zdGFuY2UpO1xuICAgIH1cbiAgfSwgW1xuICAgIGlzUmVhZHksXG4gICAgYW1wbGl0dWRlQ2xpZW50LFxuICAgIGFtcGxpdHVkZUFwaUtleSxcbiAgICB1c2VySWQsXG4gICAgZGF0YVJlc2lkZW5jeSxcbiAgICBhbXBsaXR1ZGVTZXNzaW9uUmVwbGF5SW5pdCxcbiAgICBnZXRFdmVudFRyYWNraW5nRW5yaWNobWVudCxcbiAgXSk7XG5cbiAgY29uc3QgdHJhY2tFdmVudCA9IHVzZUNhbGxiYWNrKFxuICAgIGFzeW5jICh7XG4gICAgICBldmVudE5hbWUsXG4gICAgICBldmVudFByb3BzLFxuICAgICAgZXZlbnRHcm91cHMsXG4gICAgICBhbHNvU2VuZFRvR29vZ2xlQW5hbHl0aWNzID0gZmFsc2UsXG4gICAgfTogVHJhY2tFdmVudFBhcmFtcyk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgTG9nZ2VyLmxvZ0RlYnVnKFwiU3VibWl0dGluZyBldmVudFwiLCBldmVudE5hbWUpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZGVjb3JhdGVkRXZlbnROYW1lID0gYFtTcGlmZnldICR7ZXZlbnROYW1lfWA7XG5cbiAgICAgICAgaWYgKCFhbXBsaXR1ZGVDbGllbnQpIHtcbiAgICAgICAgICBMb2dnZXIubG9nV2FybihcImFtcGxpdHVkZSBjbGllbnQgdW5kZWZpbmVkXCIsIHVuZGVmaW5lZCwge1xuICAgICAgICAgICAgZXZlbnRfbmFtZTogZGVjb3JhdGVkRXZlbnROYW1lLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGV2ZW50RGF0YSA9IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICBldmVudE5hbWUsXG4gICAgICAgICAgZXZlbnRQcm9wcyxcbiAgICAgICAgICBjcmVhdGVkX2F0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBlbmNvZGVyID0gbmV3IFRleHRFbmNvZGVyKCk7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBlbmNvZGVyLmVuY29kZShldmVudERhdGEpO1xuICAgICAgICAgLy8gY2FsY3VsYXRlIGEgaGFzaCBvZiB0aGUgZXZlbnQgcHJvcGVydGllcyB0byB1c2UgYXMgdGhlIGluc2VydF9pZCBzbyB0aGF0IGR1cGxpY2F0ZSBldmVudHNcbiAgICAgICAgLy8gYXJlIGF1dG9tYXRpY2FsbHkgZHJvcHBlZCBieSBBbXBsaXR1ZGVcbiAgICAgICAgY29uc3QgaGFzaEJ1ZmZlciA9IGF3YWl0IGNyeXB0by5zdWJ0bGUuZGlnZXN0KFwiU0hBLTI1NlwiLCBkYXRhKTtcbiAgICAgICAgY29uc3QgaGFzaEFycmF5ID0gQXJyYXkuZnJvbShuZXcgVWludDhBcnJheShoYXNoQnVmZmVyKSk7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRJbnNlcnRJZCA9IGhhc2hBcnJheVxuICAgICAgICAgIC5tYXAoKGIpID0+IGIudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDIsIFwiMFwiKSlcbiAgICAgICAgICAuam9pbihcIlwiKTtcblxuICAgICAgICBMb2dnZXIubG9nRGVidWcoYGFtcGxpdHVkZSB0cmFja2luZyAke2RlY29yYXRlZEV2ZW50TmFtZX1gLCBudWxsLCB7XG4gICAgICAgICAgZXZlbnRfbmFtZTogZGVjb3JhdGVkRXZlbnROYW1lLFxuICAgICAgICAgIHByb3BzOiBldmVudFByb3BzLFxuICAgICAgICB9KTtcblxuICAgICAgICBhbXBsaXR1ZGVDbGllbnQudHJhY2soXG4gICAgICAgICAgZGVjb3JhdGVkRXZlbnROYW1lLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIC4uLmdldERlZmF1bHRUcmFja2luZ1Byb3BzKCksXG4gICAgICAgICAgICAuLi5ldmVudFByb3BzLFxuICAgICAgICAgICAgLi4uKGV2ZW50UHJvcHNcbiAgICAgICAgICAgICAgPyBldmVudFByb3BzVG9QcmVmaXhlZEV2ZW50UHJvcHMoZXZlbnROYW1lLCBldmVudFByb3BzKVxuICAgICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIC4uLmV2ZW50R3JvdXBzLFxuICAgICAgICAgICAgaW5zZXJ0X2lkOiBjdXJyZW50SW5zZXJ0SWQsXG4gICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChhbHNvU2VuZFRvR29vZ2xlQW5hbHl0aWNzICYmIG9yZ0dhQ29uZmlnKSB7XG4gICAgICAgICAgLy8gVE9ETzogQWRkIGluIHdpbmRvd0RhdGFMYXllclNlcnZpY2Ugb3IgY29udGV4dCBhbHRlcm5hdGl2ZSBhbmQgaG9vayBpdCB1cCBoZXJlXG4gICAgICAgICAgTG9nZ2VyLmxvZ0RlYnVnKFwiW3NwaWZmeS1haV0gR0EgdHJhY2tpbmdcIiwgZGVjb3JhdGVkRXZlbnROYW1lKTtcbiAgICAgICAgICBpZiAod2luZG93LmRhdGFMYXllcikge1xuICAgICAgICAgICAgKHdpbmRvdy5kYXRhTGF5ZXIgYXMgYW55W10pLnB1c2goe1xuICAgICAgICAgICAgICBldmVudDogZGVjb3JhdGVkRXZlbnROYW1lLFxuICAgICAgICAgICAgICBldmVudFByb3BzOiBldmVudFByb3BzLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgTG9nZ2VyLmxvZ0Vycm9yKFwiW3NwaWZmeS1haV0gRXJyb3IgdHJhY2tpbmcgZXZlbnRcIiwgZXJyLCB7XG4gICAgICAgICAgZXZlbnROYW1lLFxuICAgICAgICAgIGV2ZW50UHJvcHMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0sXG4gICAgW1xuICAgICAgYW1wbGl0dWRlQ2xpZW50LFxuICAgICAgZ2V0RGVmYXVsdFRyYWNraW5nUHJvcHMsXG4gICAgICBldmVudFByb3BzVG9QcmVmaXhlZEV2ZW50UHJvcHMsXG4gICAgICBvcmdHYUNvbmZpZyxcbiAgICBdXG4gICk7XG5cbiAgY29uc3QgdmFsdWUgPSB1c2VNZW1vKFxuICAgICgpID0+ICh7XG4gICAgICB0cmFja0V2ZW50LFxuICAgICAgaXNSZWFkeSxcbiAgICAgIHNldFN1cHBsZW1lbnRhbERlZmF1bHRQcm9wczogKHByb3BzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikgPT5cbiAgICAgICAgc2V0U3VwcGxlbWVudGFsRGVmYXVsdFByb3BzKHByb3BzKSxcbiAgICB9KSxcbiAgICBbdHJhY2tFdmVudCwgaXNSZWFkeSwgc2V0U3VwcGxlbWVudGFsRGVmYXVsdFByb3BzXVxuICApO1xuXG4gIHJldHVybiAoXG4gICAgPEFtcGxpdHVkZUNvbnRleHQuUHJvdmlkZXIgdmFsdWU9e3ZhbHVlfT5cbiAgICAgIHtjaGlsZHJlbn1cbiAgICA8L0FtcGxpdHVkZUNvbnRleHQuUHJvdmlkZXI+XG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgdXNlQW1wbGl0dWRlID0gKCkgPT4ge1xuICBjb25zdCBjb250ZXh0ID0gdXNlQ29udGV4dChBbXBsaXR1ZGVDb250ZXh0KTtcbiAgaWYgKCFjb250ZXh0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwidXNlQW1wbGl0dWRlIG11c3QgYmUgdXNlZCB3aXRoaW4gQW1wbGl0dWRlUHJvdmlkZXJcIik7XG4gIH1cbiAgcmV0dXJuIGNvbnRleHQ7XG59O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7O0FBc0NBLElBQVksNEVBQUw7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBZ0JGLE1BQU0sbUJBQW1CLGNBQTJDLEtBQUs7QUFFekUsTUFBYUEscUJBQThELEVBQ3pFLGVBQ0k7Q0FDSixNQUFNLFNBQVMsYUFBYSxXQUFXO0NBQ3ZDLE1BQU0sa0JBQWtCLGFBQWEsb0JBQW9CO0NBQ3pELE1BQU0sZ0JBQWdCLGFBQWEsa0JBQWtCO0NBQ3JELE1BQU0sY0FBYyxhQUFhLHNDQUFzQztDQUN2RSxNQUFNLE1BQU0sYUFBYSxR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
|