diff --git a/public/locales/en-US/translations.json b/public/locales/en-US/translations.json index eb3d83ec6..676cd2ade 100644 --- a/public/locales/en-US/translations.json +++ b/public/locales/en-US/translations.json @@ -52,24 +52,6 @@ "title": "Closing Position", "body": "Are you sure you want to close {{pair}} position?" }, - "helpUsImproveModal": { - "title": "Help us improve Bitfinex Honey", - "description": "We would like to gather usage data. Sounds scary, but this really helps us convince management to keep maintaining this for free😅. With the added benefit that we'll be able to better tailor our service to your needs, making your experience faster, more intuitive, and more enjoyable.", - "ppNotice": "This is consistent with the Bitfinex Privacy Policy and the Bitfinex API Terms of Service.", - "weWill": "We will:", - "willItem1": "Always allow you to opt-out from the settings", - "willItem2": "Send anonymised information to Bitfinex servers (such as errors or volume of trades) so we can know how the product is performing (check the code)", - "willNotItem1": "Never share any private information from your account (such as your IP address, balances, username, keys or order history) with 3rd parties", - "willNotItem2": "Never collect any proprietary information (such as your strategies or exact order details)", - "willNotItem3": "Never use the collected information to profile you in order to improve marketing communications", - "advancedConf": "Advanced Configuration", - "illHelp": "No problem, I'll help", - "3rdPartyNotice": "This is how we use trusted 3rd parties services and our own systems to enhance product usability and safety.", - "unexpectedErrors": "We store unexpected errors", - "unexpectedErrorsDesc": "Storing unexpected errors on our infrastructure allows us to proactively act on issues instead of relying on direct user reports, increasing our response time for fixes and making your overall experience safer (check the code).", - "anonymousData": "We store anonymous usage data", - "anonymousDataDesc": "Storing anonymous usage data on our infrastructure allows us to analyse usage trends of the application worldwide and better understand which actions should be prioritised due to their reach (check the code)." - }, "launchStrategyModal": { "title": "Launch Strategy", "body": "This action will launch this strategy in LIVE mode, acting automatically on your behalf trough the Bitfinex API and using real funds from your Exchange wallet. The current active strategy will stop and this one will take its place." @@ -438,7 +420,13 @@ "timestampFormatPreview": "Preview: {{date}}", "localTimestampFormat": "Local timestamp format", "timestampFormatHelpLink": "How to set a timestamp format", - "resetToDefaultBtn": "Reset to default" + "resetToDefaultBtn": "Reset to default", + "optinCrashReports": "Opt in to crash reports", + "optinCrashReportsDesc": "If checked we will send the automatic logs of ERROR and FATAL to the metrics server, otherwise this data will be stored locally.", + "optinBFXAnalytics": "Opt in to Bitfinex Analytics", + "optinBFXAnalyticsDesc": "If checked we will send the event data to the metrics server.", + "optinVendorPendo": "Opt in to Pendo Analytics", + "optinVendorPendoDesc": "If checked we will use Pendo to collect data about your usage of the application." }, "atomicOrdersTableModal": { "title": "Atomic Orders", @@ -912,8 +900,7 @@ "proceed": "Proceed", "saveAndLaunch": "Save & Launch", "launchNoSave": "Launch without saving", - "updateAndRestart": "Update and Restart", - "saveAndContinue": "Save and Continue" + "updateAndRestart": "Update and Restart" }, "crashHandler": { "text1": "An error occurred that caused the Bitfinex Honey UI to halt. Please, restart the application to proceed working with it", diff --git a/src/components/Navbar/Navbar.LanguageSettings.js b/src/components/Navbar/Navbar.LanguageSettings.js index aa48ecae8..a30459ce4 100644 --- a/src/components/Navbar/Navbar.LanguageSettings.js +++ b/src/components/Navbar/Navbar.LanguageSettings.js @@ -15,7 +15,15 @@ const LanguageSettings = () => { const i18nMappedKey = i18n.getMappedLanguageKey() const changeLanguageHandler = (lang) => { + const { pendo } = window + i18n.changeLanguage(LANGUAGES[lang]) + + if (pendo) { + pendo.updateOptions({ + language: LANGUAGES[lang], + }) + } } return ( diff --git a/src/components/SwitchMode/SwitchMode.js b/src/components/SwitchMode/SwitchMode.js index aca220be6..269973229 100644 --- a/src/components/SwitchMode/SwitchMode.js +++ b/src/components/SwitchMode/SwitchMode.js @@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next' import { Tooltip } from '@ufx-ui/core' import { THEMES } from '../../redux/selectors/ui' -export const SWITCH_THEME = { +const SWITCH_THEME = { [THEMES.LIGHT]: { onColor: '#07aa8c', offColor: '#818e9a', diff --git a/src/constants/variables.js b/src/constants/variables.js index e337d161f..63c0f1117 100644 --- a/src/constants/variables.js +++ b/src/constants/variables.js @@ -3,3 +3,6 @@ import { isElectronApp } from '../redux/config' export const MAX_STRATEGY_LABEL_LENGTH = 150 export const DONT_SHOW_DMS_MODAL_KEY = 'HF_UI_DONT_SHOW_DMS_MODAL' export const MIN_SAFE_WIDTH = isElectronApp ? 1200 : 100 + +// A random visitor ID which is generated on login and is used for Pendo tracking +export const LOCAL_STORAGE_UID = 'HF_VISITOR_ID' diff --git a/src/index.js b/src/index.js index e6e7fca79..f387fcb95 100644 --- a/src/index.js +++ b/src/index.js @@ -9,6 +9,7 @@ import HFUIWrapper from './components/HFUIWrapper' import i18n from './locales/i18n' import { isElectronApp } from './redux/config' +import './util/pendo' import './passive_listener_fix' import './index.css' diff --git a/src/modals/AppSettingsModal/AppSettingsModal.About.js b/src/modals/AppSettingsModal/AppSettingsModal.About.js index c3b102565..e7f46330d 100644 --- a/src/modals/AppSettingsModal/AppSettingsModal.About.js +++ b/src/modals/AppSettingsModal/AppSettingsModal.About.js @@ -1,7 +1,6 @@ /* eslint-disable jsx-a11y/anchor-has-content */ import React, { memo } from 'react' import { useTranslation, Trans } from 'react-i18next' -import { useDispatch } from 'react-redux' import { appVersion, @@ -17,16 +16,9 @@ import { PRIVACY_POLICY_URL, TERMS_CONDITIONS_URL, } from './AppSettingsModal.constants' -import UIActions from '../../redux/actions/ui' -import { UI_MODAL_KEYS } from '../../redux/constants/modals' const About = () => { const { t } = useTranslation() - const dispatch = useDispatch() - - const openHelpUsImproveModal = () => { - dispatch(UIActions.changeUIModalState(UI_MODAL_KEYS.HELP_US_IMPROVE_HONEY_MODAL, true)) - } return (
@@ -126,11 +118,6 @@ const About = () => { {t('appSettings.bfxPrivacy')}
-
- - Advanced privacy configuration - -
) } diff --git a/src/modals/AppSettingsModal/AppSettingsModal.Analytics.js b/src/modals/AppSettingsModal/AppSettingsModal.Analytics.js index e11ea7798..22422c001 100644 --- a/src/modals/AppSettingsModal/AppSettingsModal.Analytics.js +++ b/src/modals/AppSettingsModal/AppSettingsModal.Analytics.js @@ -1,20 +1,13 @@ -/* eslint-disable jsx-a11y/anchor-has-content */ import React, { memo } from 'react' import { useDispatch, useSelector } from 'react-redux' import { Checkbox } from '@ufx-ui/core' -import { Trans, useTranslation } from 'react-i18next' +import { useTranslation } from 'react-i18next' import WSActions from '../../redux/actions/ws' import GAActions from '../../redux/actions/google_analytics' import { - SETTINGS_KEYS, - getOptinCrashReports, - getOptinBFXAnalytics, + SETTINGS_KEYS, getOptinCrashReports, getOptinBFXAnalytics, getOptinVendorPendo, } from '../../redux/selectors/ui' -import { - METRICS_CODE_REF_URL, - UNIQUE_ID_CODE_REF_URL, -} from '../../redux/config' // import InnerModal from '../../ui/InnerModal/InnerModal' const Analytics = () => { @@ -23,18 +16,20 @@ const Analytics = () => { const optinCrashReports = useSelector(getOptinCrashReports) const optinBFXAnalytics = useSelector(getOptinBFXAnalytics) + const optinVendorPendo = useSelector(getOptinVendorPendo) const optinCrashReportsHandler = (isChecked) => { - dispatch( - WSActions.saveSetting(SETTINGS_KEYS.OPT_IN_CRASH_REPORTS, isChecked), - ) + dispatch(WSActions.saveSetting(SETTINGS_KEYS.OPT_IN_CRASH_REPORTS, isChecked)) dispatch(GAActions.updateSettings()) } const optinBFXAnalyticsHandler = (isChecked) => { - dispatch( - WSActions.saveSetting(SETTINGS_KEYS.OPT_IN_BFX_ANALYTICS, isChecked), - ) + dispatch(WSActions.saveSetting(SETTINGS_KEYS.OPT_IN_BFX_ANALYTICS, isChecked)) + dispatch(GAActions.updateSettings()) + } + + const optinVendorPendoHandler = (isChecked) => { + dispatch(WSActions.saveSetting(SETTINGS_KEYS.OPT_IN_VENDOR_PENDO, isChecked)) dispatch(GAActions.updateSettings()) } @@ -43,47 +38,34 @@ const Analytics = () => {
- - ), - }} - /> + {t('appSettings.optinCrashReportsDesc')}
- - ), - }} - /> + {t('appSettings.optinCrashReportsDesc')} +
+
+
+ +
+ {t('appSettings.optinVendorPendoDesc')}
diff --git a/src/modals/HelpUsImproveHoneyModal/HelpUsImproveHoneyModal.FirstStep.js b/src/modals/HelpUsImproveHoneyModal/HelpUsImproveHoneyModal.FirstStep.js deleted file mode 100644 index fa797aaf3..000000000 --- a/src/modals/HelpUsImproveHoneyModal/HelpUsImproveHoneyModal.FirstStep.js +++ /dev/null @@ -1,115 +0,0 @@ -/* eslint-disable jsx-a11y/anchor-has-content */ -import React, { memo } from 'react' -import PropTypes from 'prop-types' -import { useTranslation, Trans } from 'react-i18next' -import { Icon } from 'react-fa' -import { Intent } from '@ufx-ui/core' -import { - PRIVACY_POLICY_URL, - TERMS_CONDITIONS_URL, -} from '../AppSettingsModal/AppSettingsModal.constants' -import Modal from '../../ui/Modal' -import { UNIQUE_ID_CODE_REF_URL } from '../../redux/config' - -const HelpUsImproveHoneyModalFirstStep = ({ onSubmit, goToSecondStep }) => { - const { t } = useTranslation() - - return ( -
-

- -

-

- - ), - termsURL: ( - - ), - }} - /> -

-

{t('helpUsImproveModal.weWill')}

-
- - - {t('helpUsImproveModal.advancedConf')} - - - {t('helpUsImproveModal.illHelp')} - - -
- ) -} - -HelpUsImproveHoneyModalFirstStep.propTypes = { - onSubmit: PropTypes.func.isRequired, - goToSecondStep: PropTypes.func.isRequired, -} - -export default memo(HelpUsImproveHoneyModalFirstStep) diff --git a/src/modals/HelpUsImproveHoneyModal/HelpUsImproveHoneyModal.SecondStep.js b/src/modals/HelpUsImproveHoneyModal/HelpUsImproveHoneyModal.SecondStep.js deleted file mode 100644 index 5926daa00..000000000 --- a/src/modals/HelpUsImproveHoneyModal/HelpUsImproveHoneyModal.SecondStep.js +++ /dev/null @@ -1,105 +0,0 @@ -/* eslint-disable jsx-a11y/anchor-has-content */ -import React from 'react' -import PropTypes from 'prop-types' -import { Trans, useTranslation } from 'react-i18next' -import { Intent } from '@ufx-ui/core' -import { ToggleSwitch } from 'react-dragswitch' -import { THEMES } from '../../redux/selectors/ui' -import { SWITCH_THEME } from '../../components/SwitchMode/SwitchMode' -import Modal from '../../ui/Modal' -import { - METRICS_CODE_REF_URL, - UNIQUE_ID_CODE_REF_URL, -} from '../../redux/config' - -const HelpUsImproveHoneySecondStep = ({ - goToFirstStep, - onSubmit, - settingsTheme, - optinCrashReports, - setOptinCrashReports, - optinBFXAnalytics, - setOptinBFXAnalytics, -}) => { - const { t } = useTranslation() - - return ( -
-

{t('helpUsImproveModal.3rdPartyNotice')}

-
-
- {t('helpUsImproveModal.unexpectedErrors')} - -
-

- - ), - }} - /> -

-
-
-
- {t('helpUsImproveModal.anonymousData')} - -
-

- - ), - }} - /> -

-
- - - {t('ui.goBack')} - - - {t('ui.saveAndContinue')} - - -
- ) -} - -HelpUsImproveHoneySecondStep.propTypes = { - goToFirstStep: PropTypes.func.isRequired, - onSubmit: PropTypes.func.isRequired, - optinCrashReports: PropTypes.bool.isRequired, - setOptinCrashReports: PropTypes.func.isRequired, - optinBFXAnalytics: PropTypes.bool.isRequired, - setOptinBFXAnalytics: PropTypes.func.isRequired, - settingsTheme: PropTypes.oneOf([THEMES.LIGHT, THEMES.DARK]).isRequired, -} - -export default HelpUsImproveHoneySecondStep diff --git a/src/modals/HelpUsImproveHoneyModal/HelpUsImproveHoneyModal.container.js b/src/modals/HelpUsImproveHoneyModal/HelpUsImproveHoneyModal.container.js deleted file mode 100644 index ef38d8c00..000000000 --- a/src/modals/HelpUsImproveHoneyModal/HelpUsImproveHoneyModal.container.js +++ /dev/null @@ -1,27 +0,0 @@ -import { connect } from 'react-redux' - -import UIActions from '../../redux/actions/ui' -import WSActions from '../../redux/actions/ws' -import GAActions from '../../redux/actions/google_analytics' -import { getUIModalStateForKey, getThemeSetting } from '../../redux/selectors/ui' -// import { getAuthToken } from '../../redux/selectors/ws' -import HelpUsImproveHoneyModal from './HelpUsImproveHoneyModal' -import { UI_MODAL_KEYS } from '../../redux/constants/modals' - -const mapStateToProps = (state = {}) => ({ - visible: getUIModalStateForKey(state, UI_MODAL_KEYS.HELP_US_IMPROVE_HONEY_MODAL), - // authToken: getAuthToken(state), - settingsTheme: getThemeSetting(state), -}) - -const mapDispatchToProps = dispatch => ({ - updateSettings: (payload) => { - dispatch(WSActions.saveSettings(payload)) - dispatch(GAActions.updateSettings()) - }, - closeHelpUsImproveHoneyModal: () => { - dispatch(UIActions.changeUIModalState(UI_MODAL_KEYS.HELP_US_IMPROVE_HONEY_MODAL, false)) - }, -}) - -export default connect(mapStateToProps, mapDispatchToProps)(HelpUsImproveHoneyModal) diff --git a/src/modals/HelpUsImproveHoneyModal/HelpUsImproveHoneyModal.js b/src/modals/HelpUsImproveHoneyModal/HelpUsImproveHoneyModal.js deleted file mode 100644 index 8474fb003..000000000 --- a/src/modals/HelpUsImproveHoneyModal/HelpUsImproveHoneyModal.js +++ /dev/null @@ -1,86 +0,0 @@ -/* eslint-disable jsx-a11y/anchor-has-content */ -import React, { memo, useState } from 'react' -import PropTypes from 'prop-types' -import { useTranslation } from 'react-i18next' - -import Modal from '../../ui/Modal' -import { SETTINGS_KEYS, THEMES } from '../../redux/selectors/ui' -import HelpUsImproveHoneyModalFirstStep from './HelpUsImproveHoneyModal.FirstStep' -import HelpUsImproveHoneySecondStep from './HelpUsImproveHoneyModal.SecondStep' -import useToggle from '../../hooks/useToggle' - -import './style.css' - -const HelpUsImproveHoney = ({ - closeHelpUsImproveHoneyModal, - visible, - settingsTheme, - updateSettings, -}) => { - const [isFirstStep, , goToFirstStep, goToSecondStep] = useToggle(true) - const [optinCrashReports, setOptinCrashReports] = useState(true) - const [optinBFXAnalytics, setOptinBFXAnalytics] = useState(true) - - const { t } = useTranslation() - - const onSubmit = () => { - if (isFirstStep) { - updateSettings({ - [SETTINGS_KEYS.OPT_IN_CRASH_REPORTS]: true, - [SETTINGS_KEYS.OPT_IN_BFX_ANALYTICS]: true, - [SETTINGS_KEYS.SHOW_OPT_IN_MODAL]: false, - }) - } else { - updateSettings({ - [SETTINGS_KEYS.OPT_IN_CRASH_REPORTS]: optinCrashReports, - [SETTINGS_KEYS.OPT_IN_BFX_ANALYTICS]: optinBFXAnalytics, - [SETTINGS_KEYS.SHOW_OPT_IN_MODAL]: false, - }) - } - - closeHelpUsImproveHoneyModal() - } - - return ( - {}} - onSubmit={onSubmit} - isCloseButtonShown={false} - canOutsideClickClose={false} - className='help-us-improve-honey-modal' - > - {isFirstStep ? ( - - ) : ( - - )} - - ) -} - -HelpUsImproveHoney.propTypes = { - closeHelpUsImproveHoneyModal: PropTypes.func.isRequired, - visible: PropTypes.bool.isRequired, - // authToken: PropTypes.string.isRequired, - settingsTheme: PropTypes.oneOf([THEMES.LIGHT, THEMES.DARK]).isRequired, - updateSettings: PropTypes.func.isRequired, -} - -export default memo(HelpUsImproveHoney) diff --git a/src/modals/HelpUsImproveHoneyModal/index.js b/src/modals/HelpUsImproveHoneyModal/index.js deleted file mode 100644 index 2089e5554..000000000 --- a/src/modals/HelpUsImproveHoneyModal/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import HelpUsImproveHoneyModal from './HelpUsImproveHoneyModal.container' - -export default HelpUsImproveHoneyModal diff --git a/src/modals/HelpUsImproveHoneyModal/style.scss b/src/modals/HelpUsImproveHoneyModal/style.scss deleted file mode 100644 index 83d5c2950..000000000 --- a/src/modals/HelpUsImproveHoneyModal/style.scss +++ /dev/null @@ -1,60 +0,0 @@ -@import "../../variables.scss"; - -.help-us-improve-honey-modal { - .modal__body { - > p { - font-size: 14px; - white-space: pre-line; - margin-bottom: 10px !important; - } - - .modal__footer { - display: flex; - justify-content: flex-end; - align-items: baseline; - margin-left: 0; - } - } - - .advanced-configuration { - margin-top: 20px; - - &:first-child { - margin-top: 0; - } - - > .adv-setting-toggle { - display: flex; - justify-content: space-between; - - > span { - font-weight: bold; - } - } - - > p { - white-space: pre-line; - text-align: justify; - // 100% - 60px of the toggle width - width: calc(100% - 60px); - } - } - - .will-list-item { - &:not(:last-child) { - margin-bottom: 10px; - } - } - - .check-icon { - color: var(--primary-9); - margin-right: 5px; - font-size: 20px; - } - - .times-icon { - color: var(--red); - margin-right: 5px; - font-size: 20px; - } -} diff --git a/src/modals/ModalsWrapper/ModalsWrapper.js b/src/modals/ModalsWrapper/ModalsWrapper.js index f6810ee19..b5f03b255 100644 --- a/src/modals/ModalsWrapper/ModalsWrapper.js +++ b/src/modals/ModalsWrapper/ModalsWrapper.js @@ -12,7 +12,6 @@ const ClosePositionModal = lazy(() => import('../ClosePositionModal')) const ConfirmDMSModal = lazy(() => import('../ConfirmDMSModal')) const EditOrderModal = lazy(() => import('../EditOrderModal')) const ResetAPIKeysModal = lazy(() => import('../ResetAPIKeysModal')) -const HelpUsImproveHoneyModal = lazy(() => import('../HelpUsImproveHoneyModal')) const ModalsWrapper = ({ isElectronApp }) => { return ( @@ -25,7 +24,6 @@ const ModalsWrapper = ({ isElectronApp }) => { - )} diff --git a/src/redux/actions/ui.js b/src/redux/actions/ui.js index 272490cd7..2e59e734f 100644 --- a/src/redux/actions/ui.js +++ b/src/redux/actions/ui.js @@ -163,6 +163,11 @@ export const removeStrategy = (authToken, id) => ({ payload: { authToken, id }, }) +export const setPendoState = (isInitialized, auid) => ({ + type: types.SET_PENDO_STATE, + payload: { isInitialized, auid }, +}) + export const logInformation = (message, level, action, trace) => ({ type: types.LOG, payload: { @@ -194,5 +199,6 @@ export default { removeStrategy, setCurrentStrategy, setIsStrategyDirty, + setPendoState, logInformation, } diff --git a/src/redux/actions/ws.js b/src/redux/actions/ws.js index a11a2f888..9ab5fe60b 100644 --- a/src/redux/actions/ws.js +++ b/src/redux/actions/ws.js @@ -23,6 +23,11 @@ export default { disconnected: (alias) => ({ type: t.DISCONNECTED, payload: { alias } }), disconnect: (alias) => ({ type: t.DISCONNECT, payload: { alias } }), + recvUserAuid: (auid, mode) => ({ + type: t.SET_AUID, + payload: { auid, mode }, + }), + setBacktestLoading: () => ({ type: t.SET_BACKTEST_LOADING, payload: {}, diff --git a/src/redux/config.js b/src/redux/config.js index cf29cb940..a0a6de5d8 100644 --- a/src/redux/config.js +++ b/src/redux/config.js @@ -53,9 +53,6 @@ const STOP_ORDER_ARTICLE_URL = 'https://support.bitfinex.com/hc/en-us/articles/1 const SETUP_TIMESTAMP_FORMAT_ARTICLE = 'https://bitfinex-honey.readme.io/docs/timestamp-format?utm-source=standalone' -const METRICS_CODE_REF_URL = 'https://github.com/bitfinexcom/bfx-hf-ui-core/blob/main/src/redux/sagas/ui/on_log.js#L63-L65' -const UNIQUE_ID_CODE_REF_URL = 'https://github.com/bitfinexcom/bfx-hf-server/blob/10d9db0a660661e8794d5c0a336ad04bbe52a467/lib/ws_servers/api/metrics_client.js#L154-L157' - // product description link const HF_DESC_URL = 'https://support.bitfinex.com/hc/en-us/articles/900000096823-Honey-Framework' @@ -63,7 +60,6 @@ const DISCUSSION_BOARD_URL = 'https://bit.ly/42p9YiV' const DISCORD_URL = 'https://bit.ly/400Xj49' const CHART_URL = isElectronApp ? 'https://bitfinexcom.github.io/bfx-hf-tradingview/' : process.env.REACT_APP_CHART_URL -// const CHART_URL = 'http://localhost:3001/bfx-hf-tradingview/' const HONEY_AUTH_URL = `${process.env.REACT_APP_UFX_API_URL}/honey` @@ -99,6 +95,4 @@ export { SETUP_TIMESTAMP_FORMAT_ARTICLE, DISCUSSION_BOARD_URL, DISCORD_URL, - METRICS_CODE_REF_URL, - UNIQUE_ID_CODE_REF_URL, } diff --git a/src/redux/constants/modals.js b/src/redux/constants/modals.js index 1c394afa3..756026c14 100644 --- a/src/redux/constants/modals.js +++ b/src/redux/constants/modals.js @@ -13,5 +13,4 @@ export const UI_MODAL_KEYS = { CLOSE_SESSION_MODAL: 'CloseSessionModal', RESET_LIVE_API_KEY_MODAL: 'ResetLiveApiKeyModal', RESET_PAPER_API_KEY_MODAL: 'ResetPaperApiKeyModal', - HELP_US_IMPROVE_HONEY_MODAL: 'HelpUsImproveHoneyModal', } diff --git a/src/redux/constants/ui.js b/src/redux/constants/ui.js index f2c23e6fb..e1319ddc6 100644 --- a/src/redux/constants/ui.js +++ b/src/redux/constants/ui.js @@ -41,5 +41,6 @@ module.exports = { TOGGLE_UI_MODAL_STATE: 'UI_TOGGLE_UI_MODAL_STATE', REMOVE_STRATEGY: 'UI_REMOVE_STRATEGY', + SET_PENDO_STATE: 'UI_SET_PENDO_STATE', LOG: 'UI_LOG', } diff --git a/src/redux/constants/ws.js b/src/redux/constants/ws.js index 959d8a443..4d07af2ad 100644 --- a/src/redux/constants/ws.js +++ b/src/redux/constants/ws.js @@ -20,6 +20,7 @@ export default { DISCONNECTED: 'WS_DISCONNECTED', FLUSH_QUEUE: 'WS_FLUSH_QUEUE', + SET_AUID: 'WS_SET_AUID', DATA_AUTH_CONFIGURED: 'WS_DATA_AUTH_CONFIGURED', DATA_AUTH_TOKEN: 'WS_DATA_AUTH_TOKEN', DATA_WEB_AUTH_SUCCESS: 'WS_DATA_WEB_AUTH_SUCCESS', diff --git a/src/redux/middleware/ws/on_message.js b/src/redux/middleware/ws/on_message.js index d392617fb..fe2127dec 100644 --- a/src/redux/middleware/ws/on_message.js +++ b/src/redux/middleware/ws/on_message.js @@ -18,7 +18,7 @@ import { isElectronApp, HONEY_AUTH_URL } from '../../config' import { UI_MODAL_KEYS } from '../../constants/modals' import { UI_KEYS } from '../../constants/ui_keys' import { WS_CONNECTION } from '../../constants/ws' -import { SETTINGS_KEYS, getCurrentStrategy } from '../../selectors/ui' +import { getCurrentStrategy } from '../../selectors/ui' import { LOG_LEVELS } from '../../../constants/logging' const debug = Debug('hfui:rx:m:ws-hfui-server:msg') @@ -83,6 +83,13 @@ export default (alias, store) => (e = {}) => { break } + case 'info.auid': { + const [, auid, { mode }] = payload + + store.dispatch(WSActions.recvUserAuid(auid, mode)) + break + } + case 'auth.user_id': { const [, userId, { mode } = {}] = payload store.dispatch(WSActions.recvUserId(userId)) @@ -276,9 +283,6 @@ export default (alias, store) => (e = {}) => { const [, settings] = payload store.dispatch(UIActions.setUIValue(UI_KEYS.settings, settings)) store.dispatch(UIActions.logInformation('App setting was updated', LOG_LEVELS.INFO, 'setting_update_success')) - if (settings[SETTINGS_KEYS.SHOW_OPT_IN_MODAL]) { - store.dispatch(UIActions.changeUIModalState(UI_MODAL_KEYS.HELP_US_IMPROVE_HONEY_MODAL, true)) - } break } diff --git a/src/redux/reducers/ui/index.js b/src/redux/reducers/ui/index.js index b0f78cb91..b1f9694bc 100644 --- a/src/redux/reducers/ui/index.js +++ b/src/redux/reducers/ui/index.js @@ -88,6 +88,9 @@ function getInitialState() { isApplicationHidden: false, isFullscreenBarShown: false, isRCDisclaimerShown: false, + pendo: { + isInitialized: false, + }, } _map(_values(UI_MODAL_KEYS), (modalKey) => { @@ -548,6 +551,13 @@ function reducer(state = getInitialState(), action = {}) { } } + case types.SET_PENDO_STATE: { + return { + ...state, + pendo: { ...payload }, + } + } + default: { return state } diff --git a/src/redux/sagas/ui/index.js b/src/redux/sagas/ui/index.js index a0c17fe96..b2fbc4c5d 100644 --- a/src/redux/sagas/ui/index.js +++ b/src/redux/sagas/ui/index.js @@ -9,6 +9,7 @@ import workerFetchRemoteVersion from './worker_fetch_remote_version' import onChangeMode from './on_change_mode' import onRemoveStrategy from './on_remove_strategy' import onShowNotification from './on_show_notification' +import pendoIdentify from './pendo_identify' import addComponent from './on_add_component' import removeComponent from './on_remove_component' import createLayout from './on_create_layout' @@ -22,6 +23,7 @@ export default function* () { yield takeEvery(UITypes.SAVE_SETTINGS, onSaveSettings) yield takeEvery(UITypes.CHANGE_MODE, onChangeMode) yield takeEvery(UITypes.REMOVE_STRATEGY, onRemoveStrategy) + yield takeEvery(WSTypes.SET_AUID, pendoIdentify) yield takeEvery(UITypes.LOG, onLog) yield takeEvery(UITypes.ADD_COMPONENT, addComponent) yield takeEvery(UITypes.REMOVE_COMPONENT, removeComponent) diff --git a/src/redux/sagas/ui/on_change_mode.js b/src/redux/sagas/ui/on_change_mode.js index 8caf23312..6dc6ea024 100644 --- a/src/redux/sagas/ui/on_change_mode.js +++ b/src/redux/sagas/ui/on_change_mode.js @@ -13,6 +13,7 @@ export default function* onChangeMode(action) { yield put(UIActions.logInformation(msg, LOG_LEVELS.INFO, 'change_env')) yield put(UIActions.setTradingMode(isPaperTrading)) + yield put(UIActions.setPendoState(false)) yield put(WSActions.setUsername(null)) yield put(UIActions.setMarketFromStore(isPaperTrading)) yield put(WSActions.recvBalances({ balances: [] })) diff --git a/src/redux/sagas/ui/pendo_identify.js b/src/redux/sagas/ui/pendo_identify.js new file mode 100644 index 000000000..0f6525bfe --- /dev/null +++ b/src/redux/sagas/ui/pendo_identify.js @@ -0,0 +1,88 @@ +import { put, select } from 'redux-saga/effects' +import { v4 as uuidv4 } from 'uuid' +import Debug from 'debug' + +import UIActions from '../../actions/ui' +import { getOptinVendorPendo } from '../../selectors/ui' +import { LOCAL_STORAGE_UID } from '../../../constants/variables' +import { LOCAL_STORAGE_I18N_KEY } from '../../../locales/i18n' + +const getPendoVisitorId = () => { + const visitorId = localStorage.getItem(LOCAL_STORAGE_UID) + + if (visitorId) { + return visitorId + } + + const newVisitorId = uuidv4() + localStorage.setItem(LOCAL_STORAGE_UID, newVisitorId) + + return newVisitorId +} + +const PENDO_API_KEY = process.env.REACT_APP_PENDO_API_KEY +const PENDO_VISITOR_ID = getPendoVisitorId() + +const debug = Debug('hfui:pendo') + +export default function* ({ payload = {} }) { + const { auid, mode } = payload + const language = localStorage.getItem(LOCAL_STORAGE_I18N_KEY) || 'en-US' + + const { pendo } = window + + if (!PENDO_API_KEY) { + debug('pendo api key is absent') + return + } + + if (!pendo || !auid) { + debug('pendo is empty') + return + } + + const optinVendorPendo = yield select(getOptinVendorPendo) + + if (!optinVendorPendo) { + debug('Pendo tracking is disabled (optinVendorPendo flag is false)') + return + } + + try { + const isPendoInitialized = pendo.isReady() + + if (isPendoInitialized) { + pendo.identify({ + visitor: { + id: PENDO_VISITOR_ID, + language, + }, + account: { + id: auid, + mode, + }, + }) + debug('pendo identified', auid) + yield put(UIActions.setPendoState(true, auid)) + return + } + + pendo.initialize({ + apiKey: PENDO_API_KEY, + visitor: { + id: PENDO_VISITOR_ID, + language, + }, + account: { + id: auid, + mode, + }, + }) + + debug('pendo initialized', auid) + yield put(UIActions.setPendoState(true, auid)) + } catch (e) { + debug('caught an error', e) + yield put(UIActions.setPendoState(false)) + } +} diff --git a/src/redux/selectors/ui/get_settings.js b/src/redux/selectors/ui/get_settings.js index 7f32f3c52..bee1fd1b9 100644 --- a/src/redux/selectors/ui/get_settings.js +++ b/src/redux/selectors/ui/get_settings.js @@ -23,7 +23,7 @@ export const SETTINGS_KEYS = { TIMESTAMP_FORMAT: 'timestampFormat', OPT_IN_CRASH_REPORTS: 'optinCrashReports', OPT_IN_BFX_ANALYTICS: 'optinBFXAnalytics', - SHOW_OPT_IN_MODAL: 'showOptInModal', + OPT_IN_VENDOR_PENDO: 'optinVendorPendo', } export const THEMES = { @@ -78,6 +78,11 @@ export const getOptinBFXAnalytics = createSelector( (settings) => _get(settings, SETTINGS_KEYS.OPT_IN_BFX_ANALYTICS, false), ) +export const getOptinVendorPendo = createSelector( + getSettings, + (settings) => _get(settings, SETTINGS_KEYS.OPT_IN_VENDOR_PENDO, false), +) + export const getShouldHideOnClose = createSelector( getSettings, (settings) => _get(settings, SETTINGS_KEYS.HIDE_ON_CLOSE, false), diff --git a/src/util/pendo.js b/src/util/pendo.js new file mode 100644 index 000000000..a28aaa6cf --- /dev/null +++ b/src/util/pendo.js @@ -0,0 +1,100 @@ +/* eslint-disable */ +const PENDO_API_KEY = process.env.REACT_APP_PENDO_API_KEY; + +/* eslint-disable */ +// Pendo Agent Wrapper +// Copyright 2023 Pendo.io, Inc. +// Environment: production +// Agent Version: 2.176.1 +// Installed: 2023-04-11T09:46:06Z +(function (PendoConfig) { +!function(L0,k0,M0){!function(){function e(i){var R=function(){var a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".split("");return{uint8ToBase64:function(e){var t,n,i,r=e.length%3,o="";for(t=0,i=e.length-r;t>18&63]+a[e>>12&63]+a[e>>6&63]+a[63&e]}(n);switch(r){case 1:n=e[e.length-1],o=(o+=a[n>>2])+a[n<<4&63];break;case 2:n=(e[e.length-2]<<8)+e[e.length-1],o=(o=(o+=a[n>>10])+a[n>>4&63])+a[n<<2&63]}return o}}}(),N="undefined"!=typeof globalThis?globalThis:void 0!==L0?L0:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},e={exports:{}},O=(!function(p){ +/* + * [js-sha1]{@link https://github.com/emn178/js-sha1} + * + * @version 0.6.0 + * @author Chen, Yi-Cyuan [emn178@gmail.com] + * @copyright Chen, Yi-Cyuan 2014-2017 + * @license MIT + */ +!function(){var s="object"==typeof L0?L0:{},i=!s.JS_SHA1_NO_NODE_JS&&"object"==typeof process&&process.versions&&process.versions.node,e=(i&&(s=N),!s.JS_SHA1_NO_COMMON_JS&&p.exports),o="0123456789abcdef".split(""),n=[-2147483648,8388608,32768,128],u=[24,16,8,0],r=["hex","array","digest","arrayBuffer"],t=[],a=function(t){return function(e){return new l(!0).update(e)[t]()}},d=function(){var t=a("hex");(t=i?c(t):t).create=function(){return new l},t.update=function(e){return t.create().update(e)};for(var e=0;e>2]|=e[r]<>2]|=t<>2]|=(192|t>>6)<>2]|=(224|t>>12)<>2]|=(240|t>>18)<>2]|=(128|t>>12&63)<>2]|=(128|t>>6&63)<>2]|=(128|63&t)<>2]|=n[3&t],this.block=e[16],56<=t&&(this.hashed||this.hash(),e[0]=this.block,e[16]=e[1]=e[2]=e[3]=e[4]=e[5]=e[6]=e[7]=e[8]=e[9]=e[10]=e[11]=e[12]=e[13]=e[14]=e[15]=0),e[14]=this.hBytes<<3|this.bytes>>>29,e[15]=this.bytes<<3,this.hash())},l.prototype.hash=function(){for(var e,t=this.h0,n=this.h1,i=this.h2,r=this.h3,o=this.h4,a=this.blocks,s=16;s<80;++s)e=a[s-3]^a[s-8]^a[s-14]^a[s-16],a[s]=e<<1|e>>>31;for(s=0;s<20;s+=5)t=(e=(n=(e=(i=(e=(r=(e=(o=(e=t<<5|t>>>27)+(n&i|~n&r)+o+1518500249+a[s]<<0)<<5|o>>>27)+(t&(n=n<<30|n>>>2)|~t&i)+r+1518500249+a[s+1]<<0)<<5|r>>>27)+(o&(t=t<<30|t>>>2)|~o&n)+i+1518500249+a[s+2]<<0)<<5|i>>>27)+(r&(o=o<<30|o>>>2)|~r&t)+n+1518500249+a[s+3]<<0)<<5|n>>>27)+(i&(r=r<<30|r>>>2)|~i&o)+t+1518500249+a[s+4]<<0,i=i<<30|i>>>2;for(;s<40;s+=5)t=(e=(n=(e=(i=(e=(r=(e=(o=(e=t<<5|t>>>27)+(n^i^r)+o+1859775393+a[s]<<0)<<5|o>>>27)+(t^(n=n<<30|n>>>2)^i)+r+1859775393+a[s+1]<<0)<<5|r>>>27)+(o^(t=t<<30|t>>>2)^n)+i+1859775393+a[s+2]<<0)<<5|i>>>27)+(r^(o=o<<30|o>>>2)^t)+n+1859775393+a[s+3]<<0)<<5|n>>>27)+(i^(r=r<<30|r>>>2)^o)+t+1859775393+a[s+4]<<0,i=i<<30|i>>>2;for(;s<60;s+=5)t=(e=(n=(e=(i=(e=(r=(e=(o=(e=t<<5|t>>>27)+(n&i|n&r|i&r)+o-1894007588+a[s]<<0)<<5|o>>>27)+(t&(n=n<<30|n>>>2)|t&i|n&i)+r-1894007588+a[s+1]<<0)<<5|r>>>27)+(o&(t=t<<30|t>>>2)|o&n|t&n)+i-1894007588+a[s+2]<<0)<<5|i>>>27)+(r&(o=o<<30|o>>>2)|r&t|o&t)+n-1894007588+a[s+3]<<0)<<5|n>>>27)+(i&(r=r<<30|r>>>2)|i&o|r&o)+t-1894007588+a[s+4]<<0,i=i<<30|i>>>2;for(;s<80;s+=5)t=(e=(n=(e=(i=(e=(r=(e=(o=(e=t<<5|t>>>27)+(n^i^r)+o-899497514+a[s]<<0)<<5|o>>>27)+(t^(n=n<<30|n>>>2)^i)+r-899497514+a[s+1]<<0)<<5|r>>>27)+(o^(t=t<<30|t>>>2)^n)+i-899497514+a[s+2]<<0)<<5|i>>>27)+(r^(o=o<<30|o>>>2)^t)+n-899497514+a[s+3]<<0)<<5|n>>>27)+(i^(r=r<<30|r>>>2)^o)+t-899497514+a[s+4]<<0,i=i<<30|i>>>2;this.h0=this.h0+t<<0,this.h1=this.h1+n<<0,this.h2=this.h2+i<<0,this.h3=this.h3+r<<0,this.h4=this.h4+o<<0},l.prototype.hex=function(){this.finalize();var e=this.h0,t=this.h1,n=this.h2,i=this.h3,r=this.h4;return o[e>>28&15]+o[e>>24&15]+o[e>>20&15]+o[e>>16&15]+o[e>>12&15]+o[e>>8&15]+o[e>>4&15]+o[15&e]+o[t>>28&15]+o[t>>24&15]+o[t>>20&15]+o[t>>16&15]+o[t>>12&15]+o[t>>8&15]+o[t>>4&15]+o[15&t]+o[n>>28&15]+o[n>>24&15]+o[n>>20&15]+o[n>>16&15]+o[n>>12&15]+o[n>>8&15]+o[n>>4&15]+o[15&n]+o[i>>28&15]+o[i>>24&15]+o[i>>20&15]+o[i>>16&15]+o[i>>12&15]+o[i>>8&15]+o[i>>4&15]+o[15&i]+o[r>>28&15]+o[r>>24&15]+o[r>>20&15]+o[r>>16&15]+o[r>>12&15]+o[r>>8&15]+o[r>>4&15]+o[15&r]},l.prototype.toString=l.prototype.hex,l.prototype.digest=function(){this.finalize();var e=this.h0,t=this.h1,n=this.h2,i=this.h3,r=this.h4;return[e>>24&255,e>>16&255,e>>8&255,255&e,t>>24&255,t>>16&255,t>>8&255,255&t,n>>24&255,n>>16&255,n>>8&255,255&n,i>>24&255,i>>16&255,i>>8&255,255&i,r>>24&255,r>>16&255,r>>8&255,255&r]},l.prototype.array=l.prototype.digest,l.prototype.arrayBuffer=function(){this.finalize();var e=new ArrayBuffer(20),t=new DataView(e);return t.setUint32(0,this.h0),t.setUint32(4,this.h1),t.setUint32(8,this.h2),t.setUint32(12,this.h3),t.setUint32(16,this.h4),e};var f=d();e?p.exports=f:s.sha1=f}()}(e),e.exports),L="stagingServerHashes",G,n={};function r(e){return e.loadAsModule}function a(e){e=r(e)?{}:L0;return G=e.pendo=e.pendo||{}}function k(e){return"staging"===e.environmentName}function s(e){return!e.unminified}function M(e){return"extension"===e.installType}function P(e){return!M(e)&&!k(e)&&B(e)}function F(e,t){return!M(e)&&s(e)&&t}function U(e,t,n){e=e.stagingAgentUrl;return n&&(n="unminified.js",t&&(n="staging-"+n),e=e&&e.replace(/staging\.js$/,n)),e}function B(e,t){if(k(e=e||ce()))return!0;if(t=t||L0.location,Q(e))for(var n=Y(t.host),i=0,r=e[L].length;i>>1;n(e[s])":">",'"':""","'":"'","`":"`"}),n=p.invert(r),b=function(t){var n=function(e){return t[e]},e="(?:"+p.keys(t).join("|")+")",i=RegExp(e),r=RegExp(e,"g");return function(e){return i.test(e=null==e?"":""+e)?e.replace(r,n):e}},y=(p.escape=b(r),p.unescape=b(n),p.result=function(e,t){var n;if(null!=e)return n=e[t],p.isFunction(n)?e[t]():n},0),w=(p.uniqueId=function(e){var t=++y+"";return e?e+t:t},p.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g},/(.)^/),S={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},I=/\\|'|\r|\n|\u2028|\u2029/g,x=function(e){return"\\"+S[e]},E=(p.template=function(o,e,t){e=p.defaults({},e=!e&&t?t:e,p.templateSettings);var t=RegExp([(e.escape||w).source,(e.interpolate||w).source,(e.evaluate||w).source].join("|")+"|$","g"),a=0,s="__p+='";o.replace(t,function(e,t,n,i,r){return s+=o.slice(a,r).replace(I,x),a=r+e.length,t?s+="'+\n((__t=("+t+"))==null?'':_.escape(__t))+\n'":n?s+="'+\n((__t=("+n+"))==null?'':__t)+\n'":i&&(s+="';\n"+i+"\n__p+='"),e}),s+="';\n",s="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+(s=e.variable?s:"with(obj||{}){\n"+s+"}\n")+"return __p;\n";try{throw new Error("Function constructor not supported")}catch(n){throw n.source=s,n}t=function(e){return render.call(this,e,p)},e=e.variable||"obj";return t.source="function("+e+"){\n"+s+"}",t},p.chain=function(e){e=p(e);return e._chain=!0,e},function(e){return this._chain?p(e).chain():e});p.mixin=function(n){p.each(p.functions(n),function(e){var t=p[e]=n[e];p.prototype[e]=function(){var e=[this._wrapped];return s.apply(e,arguments),E.call(this,t.apply(p,e))}})},p.mixin(p),p.each(["pop","push","reverse","shift","sort","splice","unshift"],function(t){var n=i[t];p.prototype[t]=function(){var e=this._wrapped;return n.apply(e,arguments),"shift"!==t&&"splice"!==t||0!==e.length||delete e[0],E.call(this,e)}}),p.each(["concat","join","slice"],function(e){var t=i[e];p.prototype[e]=function(){return E.call(this,t.apply(this._wrapped,arguments))}}),p.prototype.value=function(){return this._wrapped}}.call(N)}(pe,pe.exports),pe.exports),he;function I(e){return!(null==e)}function H(e,t,n){if(D.isString(t)){if(I(e)&&I(e[t]))return e[t];for(var i=t.split("."),r=0,o=i.length;r=e}function Te(){return(L0.navigator||{}).userAgent}var Ae=function(e){var t=Ee((/msie (\d+)/.exec(Ce(e))||[])[1]);return t=isNaN(t)?Ee((/trident\/.*; rv:(\d+)/.exec(Ce(e))||[])[1]):t},u=Ae(Te()),Re=function(e,t){e=Ee((/trident\/(\d+)/.exec(Ce(e))||[])[1]);return e=isNaN(e)&&7==t?3:e};function Ne(e){return/native/.test(e)}var xe=Re(Te(),u),Oe={},Le=Ee((/android (\d+)/.exec(Ce(Te()))||[])[1]),ke=/Boxee/i.test(Te()),Me=L0.document||{},Pe=Me.documentMode,Fe,Ue=/^(Moz|webkit|O|ms)(?=[A-Z])/,Be=Me.body&&Me.body.style,Ge=!1,De=!1,He;if(Be){for(var ze in Be)if(He=Ue.exec(ze),He){Fe=He[0],Fe=Fe.substr(0,1).toUpperCase()+Fe.substr(1);break}Fe=Fe||"WebkitOpacity"in Be&&"webkit",Ge=!!("transition"in Be||Fe+"Transition"in Be),De=!!("animation"in Be||Fe+"Animation"in Be),!Le||Ge&&De||(Ge=D.isString(Me.body.style.webkitTransition),De=D.isString(Me.body.style.webkitAnimation))}var je=D.memoize(function je(){var e=L0.history&&L0.history.pushState&&L0.history.replaceState,t=!(Le<4),n=ye()===ve;return!(!e||!t||ke||n)});function We(){var e="onhashchange"in L0,t=!Pe||7>>8&255]<<16|d[e>>>16&255]<<8|d[e>>>24&255])>>32-t:d[e]>>8-t),t+a<8)s=s<>t-i-1&1,8==++a&&(a=0,r[o++]=d[s],s=0,o===r.length)&&(r=u(this));r[o]=s,this.buffer=r,this.e=a,this.index=o},te.prototype.finish=function(){var e=this.buffer,t=this.index;return 0>>1;a;a>>>=1)i=i<<1|1&a,--r;t[n]=(i<>>0}var d=t;function c(e){this.buffer=new(ee?Uint16Array:Array)(2*e),this.length=0}function s(e,t){this.d=ne,this.i=0,this.input=ee&&e instanceof Array?new Uint8Array(e):e,this.c=0,t&&(t.lazy&&(this.i=t.lazy),"number"==typeof t.compressionType&&(this.d=t.compressionType),t.outputBuffer&&(this.a=ee&&t.outputBuffer instanceof Array?new Uint8Array(t.outputBuffer):t.outputBuffer),"number"==typeof t.outputIndex)&&(this.c=t.outputIndex),this.a||(this.a=new(ee?Uint8Array:Array)(32768))}c.prototype.getParent=function(e){return 2*((e-2)/4|0)},c.prototype.push=function(e,t){var n,i,r=this.buffer,o=this.length;for(r[this.length++]=t,r[this.length++]=e;0r[n]);)i=r[o],r[o]=r[n],r[n]=i,i=r[o+1],r[o+1]=r[n+1],r[n+1]=i,o=n;return this.length},c.prototype.pop=function(){var e,t,n,i=this.buffer,r=i[0],o=i[1];for(this.length-=2,i[0]=i[this.length],i[1]=i[this.length+1],n=0;!((t=2*n+2)>=this.length)&&(t+2i[t]&&(t+=2),i[t]>i[n]);)e=i[n],i[n]=i[t],i[t]=e,e=i[n+1],i[n+1]=i[t+1],i[t+1]=e,n=t;return{index:o,value:r,length:this.length}};for(var ne=2,l={NONE:0,h:1,g:ne,n:3},ie=[],f=0;f<288;f++)switch(Q){case f<=143:ie.push([f+48,8]);break;case f<=255:ie.push([f-144+400,9]);break;case f<=279:ie.push([f-256,7]);break;case f<=287:ie.push([f-280+192,8]);break;default:throw"invalid literal: "+f}function y(e,t){this.length=e,this.k=t}s.prototype.f=function(){var e,t,F,n=this.input;switch(this.d){case 0:for(t=0,F=n.length;t>>8&255,a[s++]=255&U,a[s++]=U>>>8&255,ee)a.set(i,s),s+=i.length,a=a.subarray(0,s);else{for(o=0,B=i.length;o>16&255,a[s++]=u>>24,Q){case 1===o:n=[0,o-1,0];break;case 2===o:n=[1,o-2,0];break;case 3===o:n=[2,o-3,0];break;case 4===o:n=[3,o-4,0];break;case o<=6:n=[4,o-5,1];break;case o<=8:n=[5,o-7,1];break;case o<=12:n=[6,o-9,2];break;case o<=16:n=[7,o-13,2];break;case o<=24:n=[8,o-17,3];break;case o<=32:n=[9,o-25,3];break;case o<=48:n=[10,o-33,4];break;case o<=64:n=[11,o-49,4];break;case o<=96:n=[12,o-65,5];break;case o<=128:n=[13,o-97,5];break;case o<=192:n=[14,o-129,6];break;case o<=256:n=[15,o-193,6];break;case o<=384:n=[16,o-257,7];break;case o<=512:n=[17,o-385,7];break;case o<=768:n=[18,o-513,8];break;case o<=1024:n=[19,o-769,8];break;case o<=1536:n=[20,o-1025,9];break;case o<=2048:n=[21,o-1537,9];break;case o<=3072:n=[22,o-2049,10];break;case o<=4096:n=[23,o-3073,10];break;case o<=6144:n=[24,o-4097,11];break;case o<=8192:n=[25,o-6145,11];break;case o<=12288:n=[26,o-8193,12];break;case o<=16384:n=[27,o-12289,12];break;case o<=24576:n=[28,o-16385,13];break;case o<=32768:n=[29,o-24577,13];break;default:throw"invalid distance"}for(u=n,a[s++]=u[0],a[+s]=u[1],a[5]=u[2],i=0,r=a.length;i2*u[r-1]+d[r]&&(u[r]=2*u[r-1]+d[r]),l[r]=Array(u[r]),f[r]=Array(u[r]);for(i=0;ie[i]?(l[r][o]=a,f[r][o]=n,s+=2):(l[r][o]=e[i],f[r][o]=i,++i);p[r]=0,1===d[r]&&function m(e){var t=f[e][p[e]];t===n?(m(e+1),m(e+1)):--c[t],++p[e]}(r)}return c}(i,i.length,t),o=0,a=n.length;o>>=1;return i}function h(e,t){this.input=e,this.a=new(ee?Uint8Array:Array)(32768),this.d=S.g;var n,i={};for(n in(t?"number"==typeof t.compressionType:(t={},0))&&(this.d=t.compressionType),t)i[n]=t[n];i.outputBuffer=this.a,this.j=new s(this.input,i)}var g,m,v,b,S=l,I=(h.prototype.f=function(){var e,t,n=0,i=this.a,r=Math.LOG2E*Math.log(32768)-8<<4|8;switch(i[n++]=r,8,this.d){case S.NONE:t=0;break;case S.h:t=1;break;case S.g:t=2;break;default:throw Error("unsupported compression type")}i[+n]=(e=t<<6|0)|31-(256*r+e)%31;var o=this.input;if("string"==typeof o){for(var a=o.split(""),s=0,u=a.length;s>>0;o=a}for(var d,c=1,l=0,f=o.length,p=0;0>>0,this.j.c=2,n=(i=this.j.f()).length,ee&&((i=new Uint8Array(i.buffer)).length<=n+4&&(this.a=new Uint8Array(i.length+4),this.a.set(i),i=this.a),i=i.subarray(0,n+4)),i[n++]=r>>24&255,i[n++]=r>>16&255,i[n++]=r>>8&255,i[+n]=255&r,i},e("Zlib.Deflate",h),e("Zlib.Deflate.compress",function(e,t){return new h(e,t).f()}),e("Zlib.Deflate.prototype.compress",h.prototype.f),{NONE:S.NONE,FIXED:S.h,DYNAMIC:S.g});if(Object.keys)g=Object.keys(I);else for(m in g=[],v=0,I)g[v++]=m;for(v=0,b=g.length;v>>8^r[255&(t^e[n])];for(o=i>>3;o--;n+=8)t=(t=(t=(t=(t=(t=(t=(t=t>>>8^r[255&(t^e[n])])>>>8^r[255&(t^e[n+1])])>>>8^r[255&(t^e[n+2])])>>>8^r[255&(t^e[n+3])])>>>8^r[255&(t^e[n+4])])>>>8^r[255&(t^e[n+5])])>>>8^r[255&(t^e[n+6])])>>>8^r[255&(t^e[n+7])];return(4294967295^t)>>>0},d:function(e,t){return(a.a[255&(e^t)]^e>>>8)>>>0},b:[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117]};a.a="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array?new Uint32Array(a.b):a.b,e("Zlib.CRC32",a),e("Zlib.CRC32.calc",a.c),e("Zlib.CRC32.update",a.update)}.call(dt.exports),dt.exports),lt={Deflate:ut.Zlib.Deflate,CRC32:ct.Zlib.CRC32},ft={base64Url:"base64url",binary:"binary"},pt=function(e,n){var i;return 200<=(n=n||0)?e:D.isArray(e)?D.map(e,function(e){return pt(e,n+1)}):!D.isObject(e)||D.isDate(e)||D.isRegExp(e)||D.isElement(e)?D.isString(e)?D.escape(e):e:(i={},D.each(e,function(e,t){i[t]=pt(e,n+1)}),i)};function ht(e,t){t=t||ft.base64Url;e=yt(JSON.stringify(e)),e=new lt.Deflate(e).compress();return t===ft.base64Url?R.uint8ToBase64(e):e}var gt=function(e){e=yt(e);return R.uint8ToBase64(e)},mt=function(e){if(void 0!==e)return D.isString(e)||(e=JSON.stringify(e)),e=yt(e),lt.CRC32.calc(e,0,e.length)};function vt(e){return e[Math.floor(Math.random()*e.length)]}function bt(e){for(var t="abcdefghijklmnopqrstuvwxyz",n="",i=(t+t.toUpperCase()+"1234567890").split(""),r=0;r>6,128|63&i):i<55296||57344<=i?t.push(224|i>>12,128|i>>6&63,128|63&i):(n++,i=65536+((1023&i)<<10|1023&e.charCodeAt(n)),t.push(240|i>>18,128|i>>12&63,128|i>>6&63,128|63&i))}return t},wt=function(e,t,n){return!(!I(e)||!I(t))&&(n&&(e=e.toLowerCase(),t=t.toLowerCase()),-1=r})}),e}function Et(e){var t="__symbol__";if("undefined"!=typeof Zone&&D.isFunction(Zone[t])){t=L0[Zone[t](e)];if(D.isFunction(t))return t}return L0[e]}function Ct(e){return D.isFunction(e.isFinite)?e.isFinite:e.Number&&D.isFunction(e.Number.isFinite)?e.Number.isFinite:function(e){return e!=Infinity&&e!=-Infinity&&!isNaN(e)}}var _t=Ct(L0);function Tt(e){return"number"==typeof e&&_t(e)&&Math.floor(e)===e}function At(e,t,n,i){(t=t||{}).maxRetries=Tt(t.maxRetries)?t.maxRetries:10,t.delay=Tt(t.delay)?t.delay:50,t.exponentialBackoff=t.exponentialBackoff||!1;var r=function(e){return e&&"[object Function]"==={}.toString.call(e)},o=r(n)?n:function(){},a=r(i)?i:function(){},n=e();n?o(n):0+~]|"+s+")"+s+"*"),te=new RegExp(s+"|>"),ne=new RegExp(X),ie=new RegExp("^"+l+"$"),f={ID:new RegExp("^#("+l+")"),CLASS:new RegExp("^\\.("+l+")"),TAG:new RegExp("^("+l+"|[*])"),ATTR:new RegExp("^"+$),PSEUDO:new RegExp("^"+X),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+s+"*(even|odd|(([+-]|)(\\d*)n|)"+s+"*(?:([+-]|)"+s+"*(\\d+)|))"+s+"*\\)|)","i"),bool:new RegExp("^(?:"+Z+")$","i"),needsContext:new RegExp("^"+s+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+s+"*((?:-\\d)?\\d*)"+s+"*\\)|)(?=[^-]|$)","i")},re=/HTML$/i,oe=/^(?:input|select|textarea|button)$/i,ae=/^h\d$/i,se=/^[^{]+\{\s*\[native \w/,ue=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,de=/[+~]/,b=new RegExp("\\\\[\\da-fA-F]{1,6}"+s+"?|\\\\([^\\r\\n\\f])","g"),y=function(e,t){e="0x"+e.slice(1)-65536;return t||(e<0?String.fromCharCode(65536+e):String.fromCharCode(e>>10|55296,1023&e|56320))},ce=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,le=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},fe=function(){I()},pe=we(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{T.apply(t=V.call(c.childNodes),c.childNodes),t[c.childNodes.length].nodeType}catch(P){T={apply:t.length?function(e,t){q.apply(e,V.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}function N(e,t,n,i){var r,o,a,s,u,d,c=t&&t.ownerDocument,l=t?t.nodeType:9;if(n=n||[],"string"!=typeof e||!e||1!==l&&9!==l&&11!==l)return n;if(!i&&(I(t),t=t||x,E)){if(11!==l&&(s=ue.exec(e)))if(r=s[1]){if(9===l){if(!(d=t.getElementById(r)))return n;if(d.id===r)return n.push(d),n}else if(c&&(d=c.getElementById(r))&&m(t,d)&&d.id===r)return n.push(d),n}else{if(s[2])return T.apply(n,t.getElementsByTagName(e)),n;if((r=s[3])&&p.getElementsByClassName&&t.getElementsByClassName)return T.apply(n,t.getElementsByClassName(r)),n}if(p.qsa&&!v[e+" "]&&(!g||!g.test(e))&&(1!==l||"object"!==t.nodeName.toLowerCase())){if(d=e,c=t,1===l&&(te.test(e)||ee.test(e))){for((c=de.test(e)&&ve(t.parentNode)||t)===t&&p.scope||((a=t.getAttribute("id"))?a=a.replace(ce,le):t.setAttribute("id",a=C)),o=(u=h(e)).length;o--;)u[o]=(a?"#"+a:":scope")+" "+ye(u[o]);d=u.join(",")}try{return T.apply(n,c.querySelectorAll(d)),n}catch(f){v(e,!0)}finally{a===C&&t.removeAttribute("id")}}}return G(e.replace(R,"$1"),t,n,i)}function O(){var n=[];function i(e,t){return n.push(e+" ")>w.cacheLength&&delete i[n.shift()],i[e+" "]=t}return i}function L(e){return e[C]=!0,e}function k(e){var t=x.createElement("fieldset");try{return!!e(t)}catch(P){return!1}finally{t.parentNode&&t.parentNode.removeChild(t)}}function he(e,t){for(var n=e.split("|"),i=n.length;i--;)w.attrHandle[n[i]]=t}function ge(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function me(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&pe(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function M(a){return L(function(o){return o=+o,L(function(e,t){for(var n,i=a([],e.length,o),r=i.length;r--;)e[n=i[r]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in p=N.support={},U=N.isXML=function(e){var t=e.namespaceURI,e=(e.ownerDocument||e).documentElement;return!re.test(t||e&&e.nodeName||"HTML")},I=N.setDocument=function(e){var e=e?e.ownerDocument||e:c;return e!=x&&9===e.nodeType&&e.documentElement&&(n=(x=e).documentElement,E=!U(x),c!=x&&(e=x.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",fe,!1):e.attachEvent&&e.attachEvent("onunload",fe)),p.scope=k(function(e){return n.appendChild(e).appendChild(x.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),p.attributes=k(function(e){return e.className="i",!e.getAttribute("className")}),p.getElementsByTagName=k(function(e){return e.appendChild(x.createComment("")),!e.getElementsByTagName("*").length}),p.getElementsByClassName=!!x.getElementsByClassName,p.getById=k(function(e){return n.appendChild(e).id=C,!x.getElementsByName||!x.getElementsByName(C).length}),p.getById?(w.filter.ID=function(e){var t=e.replace(b,y);return function(e){return e.getAttribute("id")===t}},w.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E)return(e=t.getElementById(e))?[e]:[]}):(w.filter.ID=function(e){var t=e.replace(b,y);return function(e){e="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return e&&e.value===t}},w.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,i,r,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];for(r=t.getElementsByName(e),i=0;o=r[i++];)if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),w.find.TAG=p.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):p.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,i=[],r=0,o=t.getElementsByTagName(e);if("*"!==e)return o;for(;n=o[r++];)1===n.nodeType&&i.push(n);return i},w.find.CLASS=p.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},i=[],g=[],(p.qsa=!!x.querySelectorAll)&&(k(function(e){var t;n.appendChild(e).innerHTML="
",e.querySelectorAll("[msallowcapture^='']").length&&g.push("[*^$]="+s+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||g.push("\\["+s+"*(?:value|"+Z+")"),e.querySelectorAll("[id~="+C+"-]").length||g.push("~="),(t=x.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||g.push("\\["+s+"*name"+s+"*="+s+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||g.push(":checked"),e.querySelectorAll("a#"+C+"+*").length||g.push(".#.+[+~]"),e.querySelectorAll("\\\f"),g.push("[\\r\\n\\f]")}),k(function(e){e.innerHTML="";var t=x.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&g.push("name"+s+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&g.push(":enabled",":disabled"),n.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(p.matchesSelector=se.test(r=n.matches||n.webkitMatchesSelector||n.mozMatchesSelector||n.oMatchesSelector||n.msMatchesSelector))&&k(function(e){p.disconnectedMatch=r.call(e,"*"),r.call(e,"[s!='']:x"),i.push("!=",X)}),g=g.length&&new RegExp(g.join("|")),i=i.length&&new RegExp(i.join("|")),e=!!n.compareDocumentPosition,m=e||n.contains?function(e,t){var n=9===e.nodeType?e.documentElement:e,t=t&&t.parentNode;return e===t||!(!t||1!==t.nodeType||!(n.contains?n.contains(t):e.compareDocumentPosition&&16&e.compareDocumentPosition(t)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},W=e?function(e,t){var n;return e===t?(d=!0,0):(n=!e.compareDocumentPosition-!t.compareDocumentPosition)||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!p.sortDetached&&t.compareDocumentPosition(e)===n?e==x||e.ownerDocument==c&&m(c,e)?-1:t==x||t.ownerDocument==c&&m(c,t)?1:u?A(u,e)-A(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return d=!0,0;var n,i=0,r=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!r||!o)return e==x?-1:t==x?1:r?-1:o?1:u?A(u,e)-A(u,t):0;if(r===o)return ge(e,t);for(n=e;n=n.parentNode;)a.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;a[i]===s[i];)i++;return i?ge(a[i],s[i]):a[i]==c?-1:s[i]==c?1:0}),x},N.matches=function(e,t){return N(e,null,null,t)},N.matchesSelector=function(e,t){if(I(e),p.matchesSelector&&E&&!v[t+" "]&&(!i||!i.test(t))&&(!g||!g.test(t)))try{var n=r.call(e,t);if(n||p.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(P){v(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(b,y),e[3]=(e[3]||e[4]||e[5]||"").replace(b,y),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||N.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&N.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return f.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&ne.test(n)&&(t=(t=h(n,!0))&&n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(b,y).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=H[e+" "];return t||(t=new RegExp("(^|"+s+")"+e+"("+s+"|$)"))&&H(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(t,n,i){return function(e){e=N.attr(e,t);return null==e?"!="===n:!n||(e+="","="===n?e===i:"!="===n?e!==i:"^="===n?i&&0===e.indexOf(i):"*="===n?i&&-1$/.exec(e))n=[k0.createElement(r[1])];else if(/^<[\w\W]+>$/.test(e)){var r=k0.createElement("div");r.innerHTML=e,n=D.toArray(r.childNodes)}else if(D.isString(e)){t instanceof K&&(t=0=n&&e.left>=i&&e.top+e.height<=n+t.height&&e.left+e.width<=i+t.width};function io(t){return D.each(["left","top","width","height"],function(e){t[e]=Math.round(t[e])}),t}function ro(e){var t;return go(e)?((t=Or(e)).fixed=!0,io(t)):io(Nr(e,lo()))}var oo=function(e,t){var n;"string"==typeof e?(n=K(e),D.map(n,function(e){qr(e,t)})):qr(e,t)},ao=function(e,t){var n;"string"==typeof e?(n=K(e),D.map(n,function(e){Kr(e,t)})):Kr(e,t)},so=function(e){e&&e.parentNode&&e.parentNode.removeChild(e)},uo=D.compose(function(e){return Array.prototype.slice.call(e)},function(e,t){try{return S(e,t)}catch(n){return Fr("error using sizzle: "+n),t.getElementsByTagName(e)}}),co=function(e,t){try{return t.children.length+t.offsetHeight+t.offsetWidth-(e.children.length+e.offsetHeight+e.offsetWidth)}catch(n){return z("error interrogating body elements: "+n),Fr("error picking best body:"+n),0}},lo=function(e){e=e||k0;try{var t=uo("body",e);return t&&1=t.bottom||e.bottom<=t.top||e.left>=t.right||e.right<=t.left)};function ho(e){for(var t=e&&e.parentNode;t;){if(xr(V(t),Fe))return 1;t=t.parentNode}}function go(e){for(var t,n=e;n;){if(!(t=V(n)))return;if("fixed"===t.position)return!isNaN(u)||!ho(n);n=n.parentNode}}var mo=function(e,t,n){t=t||/(auto|scroll|hidden)/;var i,r=(n=n||L0).document.documentElement;if(fo(e))for(i=e;i;)if(i.assignedSlot&&(i=i.assignedSlot),c.isElementShadowRoot(i))i=i.host;else{if(i===r)return null;if(!(o=V(i)))return null;var o,a=o.position;if(i!==e&&t.test(o.overflow+o.overflowY+o.overflowX))return i.parentNode!==r||(o=V(r))&&!D.contains([o.overflow,o.overflowY,o.overflowX],"visible")?i:null;if("absolute"===a||"fixed"===a&&ho(i))i=Tr(i);else{if("fixed"===a)return null;i=i.parentNode}}return null};function vo(e,t){e=V(e);return t=t||/(auto|scroll|hidden)/,!e||"inline"===e.display?h.NONE:t.test(e.overflowY)&&t.test(e.overflowX)?h.BOTH:t.test(e.overflowY)?h.Y:t.test(e.overflowX)?h.X:t.test(e.overflow)?h.BOTH:h.NONE}var h={X:"x",Y:"y",BOTH:"both",NONE:"none"};function bo(e){return e&&e.nodeName&&"body"===e.nodeName.toLowerCase()&&fo(e)}function yo(e){var t=k0.createElement("script"),n=k0.head||k0.getElementsByTagName("head")[0]||k0.body;t.type="text/javascript",e.src?t.src=e.src:t.text=e.text||e.textContent||e.innerHTML||"",n.appendChild(t),n.removeChild(t)}function wo(e){var e=Or(e),t=to();return D.extend(t,{top:0,left:0,bottom:t.height,right:t.width}),po(t,e)}function So(e){var t=D.contains(["A","INPUT","LABEL","SELECT","TEXTAREA","BUTTON","FIELDSET","LEGEND","DATALIST","OUTPUT","OPTION","OPTGROUP"],e.nodeName),n=!!e.tabIndex,i=!e.hidden,e=!e.disabled;return(t||n)&&i&&e}function Io(e){if(e){if(D.isFunction(e.getRootNode))return e.getRootNode();if(null!=e.ownerDocument)return e.ownerDocument}return k0}function xo(e,t,n){var i=Z(t),t=vo(t,n);if(t!==h.BOTH||po(e,i)){if(t===h.Y){if(e.top>=i.bottom)return;if(e.bottom<=i.top)return}if(t===h.X){if(e.left>=i.right)return;if(e.right<=i.left)return}return 1}}function Eo(e){if(e){if(bo(e))return 1;var t=Z(e);if(0!==t.width&&0!==t.height){var n=V(e);if(!n||"hidden"!==n.visibility){for(var i=e;i&&n;){if("none"===n.display)return;if(parseFloat(n.opacity)<=0)return;n=V(i=i.parentNode)}return 1}}}}function Co(e,t){if(!Eo(e))return!1;if(!bo(e)){for(var n=Z(e),i=mo(e,t=t||/hidden/),r=null;i&&i!==k0&&i!==r;){if(!xo(n,i,t))return!1;i=mo(r=i,t)}if(e.getBoundingClientRect){var e=e.getBoundingClientRect(),o=e.right,e=e.bottom;if(n.fixed||(o+=Cr(),e+=Er()),o<=0||e<=0)return!1}}return!0}function _o(e){var t,n,i,r,o,a=/(auto|scroll)/,s=/(auto|scroll|hidden)/,u=Z(e),d=mo(e,s);if(!Eo(e))return!1;for(;d;){if(t=Z(d),(o=vo(d,a))!==h.NONE&&(i=n=0,o!==h.Y&&o!==h.BOTH||(u.bottom>t.bottom&&(n+=u.bottom-t.bottom,u.top-=n,u.bottom-=n),u.topt.right&&(i+=u.right-t.right,u.left-=i,u.right-=i),u.leftn.bottom&&(i+=t.bottom-n.bottom,t.top-=i,t.bottom-=i),t.topn.right&&(r+=t.right-n.right,t.left-=r,t.right-=r),t.leftt.upper)return o;i+=n}if(!(0t.lower)return o;i+=n}return-1}function Ha(){var e=wa.get();return D.isEmpty(e)?0:e.jwt.length+e.signingKeyName.length}function za(i){return function(e,t){for(var n=Da(e,i);0<=n;)t(e.splice(0,Math.max(n,1))),n=Da(e,i)}}function ja(e,t){var n;e.length>Yi&&(n=e.slice(),e.length=0,t(n))}var Wa=2e3;function Ja(t){return t=D.defaults(t||{},{fields:[],siloMaxLength:er}),function(n,e){var i;1===n.length&&n.JZB.length>t.siloMaxLength&&(i=n[0],o("Max length exceeded for an event"),D.each(t.fields,function(e){var t=i[e];t&&t.length>Wa&&(o("shortening "+t+" and retrying"),i[e]=t.substring(0,Wa),delete n.JZB)})),e(n)}}function Ka(e,t){var n;if(0!==e.length)return e.JZB||(e.JZB=G.squeezeAndCompress(e.slice()),e.JZB.length<=er)||1===e.length?t(e):(n=e.length/2,Ka(e.slice(0,n),t),void Ka(e.slice(n),t))}function qa(e,t){Wr()&&t(e)}function Va(n){return function(e,t){1===e.length&&e.JZB.length>Qi?(o("Couldn't write event"),Fr("Single item is: "+e.JZB.length+". Dropping."),Ur(e.JZB)):W.commit("monitoring/incrementCounter",n.beacon+"GifFailures")}}function Za(e){return D.isFunction(e.apiKey)?[].concat(e.apiKey()):[].concat(e.apiKey)}function $a(t){return D.map(t.apiKeys,function(e){return Mr(t.beacon+".gif",e,D.extend({v:Ye,ct:v(),jzb:t.JZB},t.params,t.auth))})}function Xa(t){return D.map(t.apiKeys,function(e){return Mr(t.beacon+".gif",e,D.extend({v:Ye,ct:v(),s:t.JZB.length},t.params))})}function Ya(i){return function(e,t){e.apiKeys=Za(i),e.params=D.extend({},e.params,i.params),e.beacon=i.beacon,e.eventLength=e.JZB.length;var n=wa.get();D.isEmpty(n)||(e.auth=n,e.eventLength+=n.jwt.length,e.eventLength+=n.signingKeyName.length),t(e)}}function Qa(e,t){var n=m.get("trainingPartner"),i=H(D.first(e),"account_id");n&&i&&(e.params=D.extend({},e.params,{acc:gt(i)})),t(e)}function es(e,t){var n=H(D.first(e),"props.source");n&&(e.params=D.extend({},e.params,{source:n})),t(e)}function ts(e){return JSON.stringify(D.extend({events:e.JZB},e.auth))}function ns(t,n){return t.failed||t.eventLength>Qi?n(t):void(t.auth?n(t):D.each($a(t),function(e){Br(e)["catch"](us(t,n))}))}function is(t,n){return t.failed||t.eventLength>Qi?n(t):void(!t.auth&&Gr.supported()?D.each($a(t),function(e){Gr(e)["catch"](us(t,n))}):n(t))}function rs(t,n){return t.failed||t.eventLength>er?n(t):void(Gr.supported()?D.each(Xa(t),function(e){fetch(e,{method:"POST",keepalive:!0,body:ts(t),headers:{"Content-Type":"application/json"}})["catch"](us(t,n))}):n(t))}function os(t,n){return t.failed||t.eventLength>er?n(t):void(Dr.supported()?D.each(Xa(t),function(e){Dr(e,ts(t))||us(t,n)()}):n(t))}function as(t,n){return t.failed||t.eventLength>Qi?n(t):void D.each($a(t),function(e){f({method:"GET",url:e})["catch"](us(t,n))})}function ss(t,n){return t.failed||t.eventLength>er?n(t):void D.each(Xa(t),function(e){f({method:"POST",url:e,data:ts(t),headers:{"Content-Type":"application/json"}})["catch"](us(t,n))})}function us(e,t){return function(){e.failed=!0,t(e)}}function ds(t,n){return t.failed||t.eventLength>Qi?n(t):void(y.msie<=11?D.each($a(t),function(e){f({method:"GET",url:e,sync:!0})["catch"](us(t,n))}):n(t))}function cs(t,n){return t.failed||t.eventLength>er?n(t):void(y.msie<=11?D.each(Xa(t),function(e){f({method:"POST",url:e,data:ts(t),sync:!0,headers:{"Content-Type":"application/json"}})["catch"](us(t,n))}):n(t))}function ls(i){return function(e,t){var n;return!e.JZB||e.failed?t(e):(n=[Ya(i),Qa,es],i.preferFetch&&n.push(is),n.push(ns,as),i.allowPost&&(i.preferFetch&&n.push(rs),n.push(os,ss)),void ka.apply(null,n)(e,function(e){t(e)}))}}function fs(i){return function(e,t){var n;return!e.JZB||e.failed?t(e):(n=[Ya(i),Qa,es,is,ds],i.allowPost&&n.push(rs,os,cs),void ka.apply(null,n)(e,function(e){t(e)}))}}function ps(e,t){return ka(qa,Fa,Ka,Ja(e.shorten),Ka,t(e),Va(e))}function hs(i){return function(e,t){var n=m.get("excludeNonGuideAnalytics");"ptm"===i&&n||t(e)}}function gs(e){var i=e.cache,r=e.silos,o=ps(e,ls),a=ps(e,fs),t=ka(hs(e.beacon),Pa(i),za({overhead:Ha,lower:Qi,upper:er,compressionRatio:[.5*Ia,.75*Ia,Ia]}),function(e){r.push(e)});return{push:function(e){t(e,D.noop)},clear:function(){i.length=0,r.length=0},flush:function(e){var t,n;0===i.length&&0===r.length||(r.push(i.slice()),i.length=0,t=r.slice(),r.length=0,n=(e||{}).guaranteed?a:o,D.each(t,function(e){n(e,D.noop)}))}}}var ms=Yn(function(e){var t,n;if((e=e||p.get())&&e!==ms.lastUrl)return ms.lastUrl=e,t=-1,ua()||aa(),o("sending load event for url "+e),n={load_time:t="undefined"!=typeof performance&&D.isFunction(performance.getEntriesByType)&&!D.isEmpty(performance.getEntriesByType("navigation"))?(n=performance.getEntriesByType("navigation")[0]).loadEventStart-n.fetchStart:t},ra()&&(n.is_frame=!0),Ra("load",n,e),ga(),b.urlChanged.trigger(),!0}),vs=[],bs=ws({cache:vs,apiKey:function(){return G.apiKey},beacon:"xhr",shorten:{fields:["request_url","browser_url"],siloMaxLength:Qi}});function ys(e,t){var n=ar.replace(/\./g,"\\.").replace(/\//g,"\\/"),n=new RegExp("^"+n+"\\/data\\/"),i=H(e,"request_url","");n.test(i)||t(e)}function ws(e){var n=e.cache,i=ps(e,ls),r=ps(e,fs),t=ka(ys,Pa(n),ja,i);return{push:function(e){t(e,D.noop)},clear:function(){n.length=0},flush:function(e){var t;0!==n.length&&(t=n.slice(),n.length=0,((e||{}).guaranteed?r:i)(t,D.noop))}}}fa(bs);var Ss=function(){var a;b.appUnloaded.on(function(){Es({guaranteed:!0})}),a=XMLHttpRequest.prototype.open,XMLHttpRequest.prototype.open=function(t,n,e,i,r){var o={};this.addEventListener("readystatechange",function(){var e=arguments[0].target||arguments[0].srcElement||arguments[0].currentTarget;Is(o,this.readyState,n,t,e)},!1),a.apply(this,arguments)}},Is=function(e,t,n,i,r){var o;1===t?(o=J(),e.visitor_id=o,o=Jn(),e.account_id=o,e.browser_url=xs(Ti()),e.browser_time=(new Date).getTime(),e.request_method=i,e.type="xhr"):4===t&&(e.request_url=xs(r.responseURL),e.response_status=r.status,e.duration=(new Date).getTime()-e.browser_time,bs.push(e))},xs=function(e){var t=e?e.indexOf("?"):-1,t=-1===t?"":e.slice(t+1,e.length);return Ji(e,t,m.get("xhrWhitelist"))},Es=function(e){try{bs.flush(e)}catch(t){w(t,"error while flushing xhr cache")}},Cs=function(){var n,i;return{flush:r,run:function(e){m.get("enableDebugEvents")&&!function(e,t){n=[],e.on(function(e){e=JSON.stringify(e),n.push(e)}),i=setInterval(r,t||5e3)}(b.debug,e)},stop:function(){clearInterval(i)}};function r(){var e;n&&0!==n.length&&(e=n,n=[],Ur("["+e.join(",")+"]"))}}(),_s="visibilitychange",Ts="unload";function As(e,t){t?q(k0,_s,function(){"hidden"===k0.visibilityState&&e()}):q(L0,Ts,e)}function Rs(e,i){return"undefined"!=typeof Proxy&&D.isFunction(i)?new Proxy(e,{get:function(e,t){if("textContent"===t)return i(e);if("parentNode"===t){var n=e[t];if(e.ownerDocument!==n)return Rs(e[t],i)}return e[t]}}):e}var Ns=!1,Os=D.identity;function Ls(e,n){return e?function(e,t){return 0Vs?"large":"small"}),D.pluck([].concat(D.sortBy(t.defaults,"nodeName")).concat(D.sortBy(t.small,"nodeName")).concat(D.sortBy(t.large,"nodeName")).slice(0,Zs),"nodeName"))}function nu(t,n){var e=eu(m.get("htmlAttributes")),i=eu(m.get("htmlAttributeBlacklist")),r=(i("title")||(t.title=Qs(n,"title","string")),(t.tag||"").toLowerCase()),r=("input"===r&&(r+='[type="'+n.type+'"]'),t.attrs={},tu(n.attributes,$s[r]&&$s[r].attr,e,i));return D.each(r,function(e){t.attrs[e.toLowerCase()]=Qs(n,e)}),t}function iu(e,t){var n;return t.parentNode&&t.parentNode.childNodes&&(n=D.chain(t.parentNode.childNodes),e.myIndex=n.indexOf(t).value(),e.childIndex=n.filter(function(e){return e.nodeType==br}).indexOf(t).value()),e}function ru(i,e){var r;return m.get("siblingSelectors")&&e.previousElementSibling&&(r="_pendo_sibling_",this.remove(ru),e=this.serialize(e.previousElementSibling),this.add(ru),i.attrs=i.attrs||{},D.each(e,function(e,t){var n={cls:"class",txt:"pendo_text"}[t]||t;D.isEmpty(e)||(D.isObject(e)?D.each(e,function(e,t){e&&!D.isEmpty(e)&&(i.attrs[r+n+"_"+t]=e)}):i.attrs[r+n]=e)})),i}function ou(){return new js(Ws,Ks,qs,nu,iu,ru)}var au=ou(),su=function(e){return"BODY"===e.nodeName||null===e.parentNode&&!c.isElementShadowRoot(e)},uu="pendo-ignore",du=function(e){var t={},n=t,i=e,r=!1;if(!e)return t;do{var o=i,a=au.serialize(o,e)}while(!r&&wt(a.cls,uu)&&(r=!0),n.parentElem=a,n=a,(i=c.getParent(o))&&!su(o));return r&&(t.parentElem.ignore=!0),t.parentElem},cu=["","left","right","middle"],lu=function(e,t){return cu[t]},fu=function(){return!0},pu=function(e){return e.which||e.button},hu=function(e){return e},gu=function(e,t){return e[t]},mu=[["button",pu,fu,lu],["altKey",gu,hu,hu],["ctrlKey",gu,hu,hu],["metaKey",gu,hu,hu],["shiftKey",gu,hu,hu]],vu=function(e,t){for(var n=[],i=0;i>>i-5&31],i-=5;return 0/.test(o)?D.template(n):D.constant(n)),o=d[e+t])&&o.deferred.content&&(o.content=n,o.template=i,o.script=r,o.deferred.content.resolve())},receiveDomStructureJson:function(e,t,n){(e=d[e+t])&&e.deferred.domJson&&(e.domJson=od(n),e.deferred.domJson.resolve())}}}(),cd=function(){function u(n){var i=this,t=1;return(i.contentUrl||i.domJsonpUrl)&&(D.extend(i,{fetchContent:function(){return u.fetchContent(i)}}),i.after("render",function(e){!function(e){var t=D.indexOf(n.steps,i);D.chain(n.steps).rest(t+1).first(e).each(function(e){e.fetchContent()}).value()}(t)})),i}return u.state={},u.reset=function(){dd.reset(),u.state={}},u.fetchContent=function(t){a=(a=(e=t).getGuide())&&a.language?a.language:"default";var e=e.id+"."+a;if(!(o=u.state[e])){var n,i,r,o={},a=t.getGuide();if(a.control)return j.resolve();a&&a.language&&(n=a.language)!==a.authoredLanguage&&(i=H(a,"translationStates."+n+".stepTranslations."+t.id+".domHash"),r=H(a,"translationStates."+n+".stepTranslations."+t.id+".domJsonpHash"));var a=t.guideId+t.id,s=D.extend({id:a,language:n,domHash:i,domJsonpHash:r},D.pick(t,"contentUrl","contentUrlCss","contentUrlJs","domJsonpUrl","domUrl"));o.promise=Yu.verify(s).then(function(){return o.verified=!0,dd.load(s)}).then(function(e){return o.loaded=!0,e}),u.state[e]=o}return o.promise.then(function(e){D.extend(t,e)})},u.hasContent=function(e){return I(e.content)||I(e.domJson)},u}(),ld=function(){var e=b.runtime,a=[];function s(e,n,i){return D.filter(e,function(e){if(D.isFunction(e.script)){if(D.isFunction(e.test))try{return e.test(n,i)}catch(t){return w(t,"Error in global script test code block"),!1}return D.isRegExp(e.regex)?e.regex.test(i.name)||e.regex.test(n.name):!0}})}var i=Tn.call({}),r={beforeUnmount:{type:"trigger",fromUnmount:!1},beforeUpdate:{type:"trigger",fromUnmount:!1},updated:{type:"trigger",fromUnmount:!1},unmounted:{type:"trigger",fromUnmount:!0},advanced:{type:"trigger",fromUnmount:!0},dismissed:{type:"trigger",fromUnmount:!0},snoozed:{type:"trigger",fromUnmount:!0},hidden:{type:"trigger",fromUnmount:!0},beforeAdvance:{type:"triggerCancelable",fromUnmount:!1},beforePrevious:{type:"triggerCancelable",fromUnmount:!1},beforeDismiss:{type:"triggerCancelable",fromUnmount:!1},beforeSnooze:{type:"triggerCancelable",fromUnmount:!1}};function o(e){return r[e]}function t(n){this.step=n,D.each(["read","write","clear"],function(t){this[t]=d[t],this[t+"ByGuide"]=function(){var e=D.first(arguments)+":"+H(n,"guide.id");return d[t].apply(this,[e].concat(D.rest(arguments)))}},this);var e=D.bind(function(){this.purge()},this);this.purge=D.partial(i.off,"afterUnmounted",e),i.on("afterUnmounted",e)}return e.on(function(e){var t=e.data[0];if(e.step=t,delete e.data,o(e.type))return-1<["beforeUnmount","unmounted"].indexOf(e.type)&&(t="active"===(t=t).seenState?"hidden":t.seenState,e.reason=t,"unmounted"===e.type)&&i.trigger(t,e),t=r[e.type].type,i[t](e.type,e),"unmounted"===e.type&&i.trigger("afterUnmounted"),"triggerCancelable"!==t&&e.cancel&&delete e.cancel,e}),t.prototype.on=function(e,t){var n;o(e)?(t=Yn(t),n="on",r[e].fromUnmount&&(n="one"),i[n](e,t),this.purge=D.compose(this.purge,D.partial(i.off,e,t))):z("GUIDE-RUNTIME: Warning! Unregisterable event type "+e)},{addGlobalScript:function(e){var t;t=e,!D.isFunction(t.script)||t.test&&!D.isFunction(t.test)||t.regex&&!D.isRegExp(t.regex)?w("Error adding invalid GlobalScript via API"):a.push(e)},getContext:function(e){return new t(e)},runCustomScripts:function(i,r){var t,n,o,e;D.each((t=i,n=r,o=[],D.isFunction(t.script)&&o.push(t.script),e=m.get("guides.globalScripts"),D.forEach([e,a],function(e){D.size(e)&&(e=s(e,t,n),D.each(e,function(e){o.push(e.script)}))}),o),function(e){try{var t=ld.getContext(i);e.call(t,i,r)}catch(n){w(n,"Exception thrown running code block for: "+JSON.stringify({guideId:r.id,stepId:i.id}))}})}}}();function fd(e){return e.props&&e.props.id&&0===e.props.id.indexOf("pendo-g-")?e:e.children?D.find(e.children,function(e){return fd(e)}):void 0}function pd(e,t){if(t(e))return e;if(e.children)for(var n=0;n/gi,function(e,t){return D.isNull(n[t])||D.isUndefined(n[t])?e:n[t]})}function g(e,t,n){if(e.content&&(e.content=c(e.content,t)),e.props&&e.props.id&&0<=e.props.id.indexOf("pendo-right-caret")&&(e.props["aria-labelledby"]=n),e.children)for(var i=0;i