\n );\n};\n\ntype PageHash = { requestId?: string };\ntype PageCode = { errorCode?: number };\ntype HocProps = Omit & PageCode;\n\nexport const withHttpErrorPage =\n (\n Component: React.ComponentType,\n { errorCode, ...defaultComponentProps }: HocProps\n ) =>\n ({ requestId, ...props }: T & PageHash) => {\n const componentProps = {\n ...defaultComponentProps,\n ...props,\n } as T;\n return (\n \n \n \n );\n };\n\nexport default withWebAssetsTheme(HttpErrorPage);\n","import { createUseStyles } from 'react-jss';\n\nconst useStyles = createUseStyles({\n container: {\n '& a:hover, & a:focus': {\n textDecoration: 'none',\n },\n },\n});\n\nexport default useStyles;\n","import React from 'react';\nimport { t, defineMessages } from '@sm/intl';\nimport { Typography } from '@wds/typography';\nimport { Box, BoxProps } from '@wds/box';\nimport { Button } from '@wds/button';\nimport useStyles from './useStyles';\n\nconst DEFAULT_COPY = defineMessages({\n SIGN_UP_TEXT: {\n id: 'SignupButton.signUpText',\n defaultMessage: 'Want to create your own survey?',\n description:\n '[Type: Label][Vis.: med] - Sign up free button description text',\n },\n SIGN_UP_FREE: {\n id: 'SignupButton.signUpFree',\n defaultMessage: 'Sign Up FREE',\n description: '[Type: Label][Vis.: med] - Sign up free button',\n },\n});\n\nconst DEFAULT_HREF = '/user/sign-up/?ut_source=404_page';\n\ntype ButtonProps = {\n label?: string;\n href?: string;\n};\n\nexport type SignupButtonProps = {\n buttonProps?: ButtonProps;\n signUpText?: string;\n} & BoxProps;\n\nconst SignupButton = ({\n buttonProps,\n signUpText,\n ...containerBoxProps\n}: SignupButtonProps): React.ReactElement => {\n const { container } = useStyles();\n const buttonLabel = buttonProps?.label ?? t(DEFAULT_COPY.SIGN_UP_FREE);\n const buttonHref = buttonProps?.href ?? DEFAULT_HREF;\n const description = signUpText ?? t(DEFAULT_COPY.SIGN_UP_TEXT);\n return (\n \n \n \n {description}\n \n \n \n \n );\n};\n\nexport default SignupButton;\n","import { createUseStyles } from 'react-jss';\nimport type { Theme } from '@wds/styles';\n\nconst useStyles = createUseStyles(({ border, palette }: Theme) => ({\n linkList: {\n display: 'flex',\n flexWrap: 'wrap',\n justifyContent: 'center',\n padding: 0,\n margin: 0,\n listStyleType: 'none',\n },\n linkItem: {\n '&:not(:last-child)': {\n '&::after': {\n content: '\"|\"',\n margin: '0 3px',\n },\n },\n },\n linkAnchor: {\n color: palette.link.main,\n textDecoration: 'none',\n fontWeight: 'inherit',\n fontSize: 'inherit',\n '&:hover': {\n textDecoration: 'underline',\n },\n '&:focus': {\n textDecoration: 'none',\n outlineStyle: 'auto',\n outlineWidth: '1px',\n outlineColor: border.hover,\n outlineOffset: '1px',\n },\n },\n}));\n\nexport default useStyles;\n","import { Typography } from '@wds/typography';\nimport { Box, BoxProps } from '@wds/box';\nimport React from 'react';\nimport { t, defineMessages } from '@sm/intl';\nimport useStyles from './useStyles';\n\nconst COPY = defineMessages({\n HOME: {\n id: 'Links.home',\n defaultMessage: 'Home',\n description: '[Type: Label][Vis.: med] - Home link in Error Message',\n },\n SITEMAP: {\n id: 'Links.sitemap',\n defaultMessage: 'Sitemap',\n description: '[Type: Label][Vis.: med] - Sitemap link in Error Message',\n },\n HELP_CENTER: {\n id: 'Links.helpCenter',\n defaultMessage: 'Help Center',\n description: '[Type: Label][Vis.: med] - Help Center link in Error Message',\n },\n TEMPLATES: {\n id: 'Links.templates',\n defaultMessage: 'Templates',\n description: '[Type: Label][Vis.: med] - Templates link in Error Message',\n },\n LEARN_MORE: {\n id: 'Links.learnMore',\n defaultMessage: 'Learn More',\n description:\n '[Type: Label][Vis.: med] - Learn More link in 404 Error Message',\n },\n});\n\nconst defaultLinks = [\n {\n href: '/',\n label: t(COPY.HOME),\n },\n {\n href: '/mp/sitemap/',\n label: t(COPY.SITEMAP),\n },\n {\n href: 'https://help.surveymonkey.com/',\n label: t(COPY.HELP_CENTER),\n },\n {\n href: '/mp/survey-templates/',\n label: t(COPY.TEMPLATES),\n },\n {\n href: '/mp/take-a-tour/',\n label: t(COPY.LEARN_MORE),\n },\n];\n\nexport type Link = {\n href: string;\n label: string;\n};\n\nexport type LinksProps = {\n links?: Link[];\n} & BoxProps;\n\nconst Links = ({\n links = defaultLinks,\n ...containerBoxProps\n}: LinksProps): React.ReactElement => {\n const { linkList, linkItem: linkStyles, linkAnchor } = useStyles();\n return (\n \n \n \n \n \n );\n};\nexport default Links;\n","import React from 'react';\nimport { Box } from '@wds/box';\nimport { t, defineMessages } from '@sm/intl';\nimport { ClientError, ClientErrorProps } from '../ClientError';\nimport Links, { LinksProps } from '../ClientError/Links';\nimport { withWebAssetsTheme } from '../../theme';\n\nconst DEFAULT_COPY = defineMessages({\n SORRY_MESSAGE: {\n id: 'FiveHundredError.SorryMessage',\n defaultMessage: \"We're sorry\",\n description: '[Type: Label][Vis.: med] - We are sorry message',\n },\n SOMETHING_WRONG: {\n id: 'FiveHundredError.SomethingWentWrong',\n defaultMessage: 'Something went wrong.',\n description: '[Type: Label][Vis.: med] - something went wrong subtitle',\n },\n FIVE_HUNDRED_MESSAGE: {\n id: 'FiveHundredError.Message',\n defaultMessage:\n \"Sorry if you lost your place - we're working hard to get things up and running again. Thanks for your patience!\",\n description: '[Type: Label][Vis.: med] - Five Hundred Error Message',\n },\n});\n\nexport type FiveHundredErrorProps = Partial & {\n /** Error content message */\n errorMessage?: React.ReactNode;\n /** ClientError Links component props */\n linksProps?: LinksProps;\n};\n\nconst FiveHundredError = ({\n openingMessage = t(DEFAULT_COPY.SORRY_MESSAGE),\n errorTitle = t(DEFAULT_COPY.SOMETHING_WRONG),\n titularElementTag = 'p',\n errorMessage = t(DEFAULT_COPY.FIVE_HUNDRED_MESSAGE),\n linksProps,\n 'data-testid': dataTestId = 'FiveHundredError',\n ...props\n}: FiveHundredErrorProps): React.ReactElement => {\n return (\n \n \n {React.Children.map(errorMessage, (message: React.ReactNode) => {\n return
{message}
;\n })}\n \n \n \n );\n};\nexport default withWebAssetsTheme(FiveHundredError);\n","import { withWebAssetsTheme } from '../../theme';\nimport { withClientErrorPage } from '../ClientError';\nimport FiveHundredError, { FiveHundredErrorProps } from './FiveHundredError';\n\nexport default withWebAssetsTheme(\n withClientErrorPage(FiveHundredError, {\n titularElementTag: 'h1', // set default to H1\n errorCode: 500,\n })\n);\n","import React from 'react';\nimport { Box } from '@wds/box';\nimport { t, defineMessages } from '@sm/intl';\nimport { withWebAssetsTheme } from '../../theme';\nimport { ClientError, ClientErrorProps } from '../ClientError';\nimport SignupButton, { SignupButtonProps } from '../ClientError/SignupButton';\nimport Links, { LinksProps } from '../ClientError/Links';\n\nexport type FourHundredErrorProps = Partial & {\n errorMessage?: React.ReactNode;\n signupButtonProps?: SignupButtonProps;\n linksProps?: LinksProps;\n showLinks?: boolean;\n};\n\nconst COPY = defineMessages({\n SORRY_MESSAGE: {\n id: 'FourHundredError.sorryMessage',\n defaultMessage: \"We're sorry\",\n description: '[Type: Label][Vis.: med] - We are sorry message',\n },\n CANT_FIND_PAGE: {\n id: 'FourHundredError.cantFindPage',\n defaultMessage: \"We can't find the page you're looking for.\",\n description: '[Type: Label][Vis.: med] - Cant find page message',\n },\n CHECK_URL: {\n id: 'FourHundredError.checkURL',\n defaultMessage:\n \"Please check the URL you entered to make sure it's spelled correctly.\",\n description: '[Type: Label][Vis.: med] - check URL subtitle',\n },\n HELP_FIND_WAY: {\n id: 'FourHundredError.helpFindWay',\n defaultMessage:\n 'Still not sure how to get to the page you want? Maybe we can help you find your way:',\n description: '[Type: Label][Vis.: med] - Help find your way subtitle',\n },\n});\n\nconst FourHundredError = ({\n openingMessage = t(COPY.SORRY_MESSAGE),\n errorTitle = t(COPY.CANT_FIND_PAGE),\n titularElementTag = 'p',\n errorMessage = [t(COPY.CHECK_URL), t(COPY.HELP_FIND_WAY)],\n signupButtonProps,\n linksProps,\n showLinks = false,\n 'data-testid': dataTestId = 'FourHundredError',\n ...props\n}: FourHundredErrorProps): React.ReactElement => {\n return (\n \n \n {React.Children.map(errorMessage, (message: React.ReactNode) => (\n
{message}
\n ))}\n \n \n {showLinks && }\n \n );\n};\n\nexport default withWebAssetsTheme(FourHundredError);\n","import { withWebAssetsTheme } from '../../theme';\nimport { withClientErrorPage } from '../ClientError';\nimport FourHundredError, { FourHundredErrorProps } from './FourHundredError';\n\nexport default withWebAssetsTheme(\n withClientErrorPage(FourHundredError, {\n titularElementTag: 'h1', // set default to H1\n errorCode: 400,\n })\n);\n","import React from 'react';\nimport { Box } from '@wds/box';\nimport { t, defineMessages } from '@sm/intl';\nimport { withWebAssetsTheme } from '../../theme';\nimport { ClientError, ClientErrorProps } from '../ClientError';\nimport SignupButton, { SignupButtonProps } from '../ClientError/SignupButton';\nimport Links, { LinksProps } from '../ClientError/Links';\n\nexport type FourOhFourErrorProps = Partial & {\n errorMessage?: React.ReactNode;\n signupButtonProps?: SignupButtonProps;\n linksProps?: LinksProps;\n showLinks?: boolean;\n};\n\nconst COPY = defineMessages({\n SORRY_MESSAGE: {\n id: 'FourOhFourError.sorryMessage',\n defaultMessage: \"We're sorry\",\n description: '[Type: Label][Vis.: med] - We are sorry message',\n },\n CANT_FIND_PAGE: {\n id: 'FourOhFourError.cantFindPage',\n defaultMessage: \"We can't find the page you're looking for.\",\n description: '[Type: Label][Vis.: med] - Cant find page message',\n },\n CHECK_URL: {\n id: 'FourOhFourError.checkURL',\n defaultMessage:\n \"Please check the URL you entered to make sure it's spelled correctly.\",\n description: '[Type: Label][Vis.: med] - check URL subtitle',\n },\n HELP_FIND_WAY: {\n id: 'FourOhFourError.helpFindWay',\n defaultMessage:\n 'Still not sure how to get to the page you want? Maybe we can help you find your way:',\n description: '[Type: Label][Vis.: med] - Help find your way subtitle',\n },\n});\n\nconst FourOhFourError = ({\n openingMessage = t(COPY.SORRY_MESSAGE),\n errorTitle = t(COPY.CANT_FIND_PAGE),\n titularElementTag = 'p',\n errorMessage = [t(COPY.CHECK_URL), t(COPY.HELP_FIND_WAY)],\n signupButtonProps,\n linksProps,\n showLinks = false,\n 'data-testid': dataTestId = 'FourOhFourError',\n ...props\n}: FourOhFourErrorProps): React.ReactElement => {\n return (\n \n \n {React.Children.map(errorMessage, (message: React.ReactNode) => {\n return
{message}
;\n })}\n \n \n {showLinks && }\n \n );\n};\n\nexport default withWebAssetsTheme(FourOhFourError);\n","import { withWebAssetsTheme } from '../../theme';\nimport { withClientErrorPage } from '../ClientError';\nimport FourOhFourError, { FourOhFourErrorProps } from './FourOhFourError';\n\n/* A variant when showing 404 error as a page */\nexport default withWebAssetsTheme(\n withClientErrorPage(FourOhFourError, {\n titularElementTag: 'h1', // set default to H1\n showLinks: true,\n errorCode: 404,\n })\n);\n","import React, { ReactElement } from 'react';\nimport { Box } from '@wds/box';\nimport { t, defineMessages } from '@sm/intl';\nimport { withWebAssetsTheme } from '../../theme';\nimport { ClientError, ClientErrorProps } from '../ClientError';\nimport Links, { LinksProps } from '../ClientError/Links';\n\n// put this into common error component strings file\nconst DEFAULT_COPY = defineMessages({\n SORRY_MESSAGE: {\n id: 'ForbiddenError.sorryMessage',\n defaultMessage: \"We're sorry\",\n description: '[Type: Label][Vis.: med] - We are sorry message',\n },\n PERMISSIONS: {\n id: 'ForbiddenError.permissions',\n defaultMessage: 'You do not have permission to see this page.',\n description: '[Type: Label][Vis.: med] - We are sorry message',\n },\n CHECK_URL: {\n id: 'ForbiddenError.checkURL',\n defaultMessage:\n \"Please check the URL you entered to make sure it's spelled correctly.\",\n description: '[Type: Label][Vis.: med] - check URL subtitle',\n },\n HELP_FIND_WAY: {\n id: 'ForbiddenError.helpFindWay',\n defaultMessage:\n 'Still not sure how to get to the page you want? Maybe we can help you find your way:',\n description: '[Type: Label][Vis.: med] - Help find your way subtitle',\n },\n});\n\nexport type ForbiddenErrorProps = Partial & {\n /** Error content message */\n errorMessage?: React.ReactNode;\n /** ClientError Links component props */\n linksProps?: LinksProps;\n showLinks?: boolean;\n};\n\nconst ForbiddenError = ({\n openingMessage = t(DEFAULT_COPY.SORRY_MESSAGE),\n errorTitle = t(DEFAULT_COPY.PERMISSIONS),\n titularElementTag = 'p',\n errorMessage = [t(DEFAULT_COPY.CHECK_URL), t(DEFAULT_COPY.HELP_FIND_WAY)],\n linksProps,\n showLinks = true,\n 'data-testid': dataTestId = 'ForbiddenError',\n ...props\n}: ForbiddenErrorProps): ReactElement => {\n return (\n \n \n {React.Children.map(errorMessage, (message: React.ReactNode) => {\n return
{message}
;\n })}\n \n {showLinks && }\n \n );\n};\n\nexport default withWebAssetsTheme(ForbiddenError);\n","import { withWebAssetsTheme } from '../../theme';\nimport { withClientErrorPage } from '../ClientError';\n\nimport ForbiddenError, { ForbiddenErrorProps } from '.';\n\nexport default withWebAssetsTheme(\n withClientErrorPage(ForbiddenError, {\n titularElementTag: 'h1', // set default to H1\n errorCode: 403,\n })\n);\n","import React from 'react';\nimport { t, defineMessages } from '@sm/intl';\nimport { withWebAssetsTheme } from '../../theme';\nimport { ClientError, ClientErrorProps } from '../ClientError';\nimport Links, { LinksProps } from '../ClientError/Links';\nimport SignupButton, { SignupButtonProps } from '../ClientError/SignupButton';\n\nconst DEFAULT_COPY = defineMessages({\n // Client Error\n OH_BANANAS: {\n id: 'FourTenError.ohBananas',\n defaultMessage: 'Oh bananas!',\n description: '[Type: Label][Vis.: med] - Oh bananas message',\n },\n TERMS_VIOLATION: {\n id: 'FourTenError.somethingWentWrong',\n defaultMessage:\n \"This survey is currently closed due to a violation of SurveyMonkey's terms of use.\",\n description: '[Type: Label][Vis.: med] - terms of use violation title',\n },\n // Primary Links\n HOME: {\n id: 'FourTenError.home',\n defaultMessage: 'SurveyMonkey Home',\n description: '[Type: Label][Vis.: med] - Home link in 410 Error Message',\n },\n SITEMAP: {\n id: 'FourTenError.sitemap',\n defaultMessage: 'Sitemap',\n description: '[Type: Label][Vis.: med] - Sitemap link in 410 Error Message',\n },\n LEARN_MORE: {\n id: 'FourTenError.howItWorks',\n defaultMessage: 'How It Works',\n description:\n '[Type: Label][Vis.: med] - How It Works link in 410 Error Message',\n },\n // Secondary Links\n TYPES: {\n id: 'FourTenError.types',\n defaultMessage: 'Survey Types',\n description:\n '[Type: Label][Vis.: med] - Survey Types link in 410 Error Message',\n },\n SATISFACTION_SURVEYS: {\n id: 'FourTenError.satisfactionSurveys',\n defaultMessage: 'Customer Satisfaction Surveys',\n description:\n '[Type: Label][Vis.: med] - Customer Satisfaction Surveys link in 410 Error Message',\n },\n EMPLOYEE_SURVEYS: {\n id: 'FourTenError.employeeSurveys',\n defaultMessage: 'Employee Surveys',\n description:\n '[Type: Label][Vis.: med] - Employee Surveys link in 410 Error Message',\n },\n});\n\nconst defaultPrimaryLinks = {\n links: [\n {\n label: t(DEFAULT_COPY.HOME),\n href: '/',\n },\n {\n label: t(DEFAULT_COPY.SITEMAP),\n href: '/mp/sitemap/',\n },\n {\n label: t(DEFAULT_COPY.LEARN_MORE),\n href: '/mp/take-a-tour/',\n },\n ],\n};\n\nconst defaultSecondaryLinks = {\n links: [\n {\n label: t(DEFAULT_COPY.TYPES),\n href: '/mp/survey-types/',\n },\n {\n label: t(DEFAULT_COPY.SATISFACTION_SURVEYS),\n href: '/mp/customer-satisfaction-surveys/',\n },\n {\n label: t(DEFAULT_COPY.EMPLOYEE_SURVEYS),\n href: '/mp/employee-surveys/',\n },\n ],\n};\n\nexport type FourTenErrorProps = Partial & {\n /** ClientError SignupButton component props */\n signupButtonProps?: SignupButtonProps;\n /** ClientError Links component props */\n primaryLinksProps?: LinksProps;\n secondaryLinksProps?: LinksProps;\n};\n\nconst FourTenError = ({\n openingMessage = t(DEFAULT_COPY.OH_BANANAS),\n errorTitle = t(DEFAULT_COPY.TERMS_VIOLATION),\n titularElementTag = 'p',\n signupButtonProps,\n primaryLinksProps = defaultPrimaryLinks,\n secondaryLinksProps = defaultSecondaryLinks,\n 'data-testid': dataTestId = 'FourTenError',\n ...props\n}: FourTenErrorProps): React.ReactElement => {\n return (\n \n \n \n \n \n );\n};\n\nexport default withWebAssetsTheme(FourTenError);\n","import { withWebAssetsTheme } from '../../theme';\nimport { withClientErrorPage } from '../ClientError';\nimport FourTenError, { FourTenErrorProps } from './FourTenError';\n\nexport default withWebAssetsTheme(\n withClientErrorPage(FourTenError, {\n titularElementTag: 'h1', // set default to H1\n errorCode: 410,\n })\n);\n","/**\n * @file A controlled component that triggers loading for infinite scroll\n * behaviour.\n *\n * Should be instantiated positionally at the bottom of a list whose next load\n * should be triggered as the user scrolls to the bottom of the list.\n *\n * Implemented using the IntersectionObserver web API for optimal performance.\n */\n\nimport React, {\n useState,\n useEffect,\n useRef,\n ReactElement,\n Dispatch,\n SetStateAction,\n} from 'react';\nimport PropTypes from 'prop-types';\n\nimport { Button } from '@wds/button';\nimport { Box } from '@wds/box';\nimport { ProgressCircle } from '@wds/progress-circle';\n\nimport { T, t } from '@sm/intl';\n\ntype InfiniteScrollTriggerProps = {\n /**\n * Set to `true` when there are more items that can possibly be loaded\n * (otherwise, should be set to `false`).\n */\n hasMoreToLoad: boolean;\n\n /**\n * Set to `true` when the items that will initially populate the list are\n * being loaded (otherwise, `false`).\n */\n loadingFirstData: boolean;\n\n /**\n * Set to `true` when more results are being loaded. Will show a loading\n * spinner underneath the list.\n */\n loadingMore: boolean;\n\n /**\n * Callback called when more list items are requested.\n */\n onLoadMore: (() => void) | (() => Promise);\n};\n\nconst COPY = {\n // todo: add in definemessages when translating\n LOAD_MORE: {\n id: 'InfiniteScrollTrigger.LoadMore',\n defaultMessage: 'Load more',\n description: '[Type: button][Vis: med] - Button to load more data',\n },\n LOADING: {\n id: 'InfiniteScrollTrigger.Loading',\n defaultMessage: 'Loading...',\n description: '[Type: button][Vis: low] - loading data',\n },\n};\n\ntype IntersectionObserverOptions = {\n root?: HTMLElement | null;\n rootMargin?: string;\n threshold?: number;\n};\n\nconst useIntersectionObserverCallback = (\n callback: (entry: IntersectionObserverEntry) => void,\n options: IntersectionObserverOptions = {}\n): [boolean, Dispatch>] => {\n const { root = null, rootMargin, threshold = 0 } = options;\n const [node, setNode] = useState(null);\n\n const observer = useRef(null);\n\n useEffect(() => {\n if (observer.current) {\n observer.current.disconnect();\n }\n\n if (window.IntersectionObserver) {\n observer.current = new window.IntersectionObserver(\n ([newEntry]) => callback(newEntry),\n {\n root,\n rootMargin,\n threshold,\n }\n );\n }\n\n if (node) {\n observer.current?.observe(node);\n }\n\n return () => observer.current?.disconnect();\n }, [callback, node, root, rootMargin, threshold]);\n\n return [!!window.IntersectionObserver, setNode];\n};\n\nfunction InfiniteScrollTrigger({\n hasMoreToLoad,\n loadingFirstData,\n loadingMore,\n onLoadMore,\n}: InfiniteScrollTriggerProps): ReactElement {\n const [isSupported, ref] = useIntersectionObserverCallback(\n (entry: IntersectionObserverEntry) => {\n if (entry.isIntersecting) {\n onLoadMore();\n }\n },\n {}\n );\n\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n );\n}\n\nInfiniteScrollTrigger.propTypes = {\n hasMoreToLoad: PropTypes.bool.isRequired,\n onLoadMore: PropTypes.func.isRequired,\n loadingFirstData: PropTypes.bool.isRequired,\n loadingMore: PropTypes.bool.isRequired,\n};\n\nexport default InfiniteScrollTrigger;\n","import fetch from 'isomorphic-fetch';\nimport { getClientEnvironmentDetails } from '@sm/utils';\nimport { clientErrorHandler } from '../..';\n\nconst { isBrowser } = getClientEnvironmentDetails();\n\n// Small in-memory only localstorage\nfunction inMemoryLocalStorage() {\n return {\n _data: {},\n setItem(id, val) {\n let dataId = this._data[id];\n dataId = String(val);\n return dataId;\n },\n getItem(id) {\n const dataID = Object.prototype.hasOwnProperty.call(this._data, id)\n ? this._data[id]\n : undefined;\n return dataID;\n },\n removeItem(id) {\n const deleteDataId = delete this._data[id];\n return deleteDataId;\n },\n clear() {\n let data = this._data;\n data = {};\n return data;\n },\n };\n}\nif (isBrowser && !('localStorage' in window)) {\n window.localStorage = inMemoryLocalStorage();\n}\n\nlet Storage;\n\nconst LAST_BACKEND_ACTIVITY_KEY = 'SessionCtrl.lba';\nconst LAST_FRONTEND_ACTIVITY_KEY = 'SessionCtrl.lfa';\n\nconst RUN_EVERY = 1000 * 30; // Every 30 seconds\n\nconst state = {\n initialized: false,\n timeoutInterval: 0, // seconds\n intervalInstanceId: null, // setInterval instance ID\n reminderCb: null, // function passed during init\n\n // settings\n minimumDeltaForFlight: 5, // seconds\n minimumDeltaForBackendExtension: 5 * 60, // 5 minutes\n minimumDeltaToShowReminder: 5 * 60, // 5 minutes\n};\n\nfunction now() {\n return parseInt(new Date().getTime() / 1000, 10);\n}\n\nfunction getTimeToBackendTimeout() {\n const lastBackendActivity = Storage.getItem(LAST_BACKEND_ACTIVITY_KEY);\n const n = now();\n return state.timeoutInterval - (n - lastBackendActivity);\n}\n\nfunction getTimeToFrontendTimeout() {\n const lastFrontendActivity = Storage.getItem(LAST_FRONTEND_ACTIVITY_KEY);\n const n = now();\n return state.timeoutInterval - (n - lastFrontendActivity);\n}\n\nfunction logout() {\n if (state.timeoutInterval === 0) {\n window.location.assign(`/user/sign-out/?timeout=true`);\n } else {\n window.location.assign(\n `/user/sign-out/?timeout=${Math.ceil(state.timeoutInterval / 60)}`\n );\n }\n}\n\nfunction updateBackendActivity() {\n return Storage.setItem(LAST_BACKEND_ACTIVITY_KEY, now());\n}\n\nasync function extendBackend(callback) {\n try {\n const resp = await fetch('/user/session/', {\n method: 'GET',\n credentials: 'include',\n });\n if (/sign-in/.test(resp.url)) {\n logout();\n } else {\n updateBackendActivity();\n return callback && callback();\n }\n } catch (e) {\n clientErrorHandler.logError(e);\n }\n return null;\n}\n\nfunction updateFrontendActivity() {\n return Storage.setItem(LAST_FRONTEND_ACTIVITY_KEY, now());\n}\n\nfunction verifyLocalStorage() {\n const testKey = 'value_that_is_not_expected_to_be_there';\n Storage = localStorage;\n try {\n Storage.setItem(testKey, 'foo');\n if (Storage.getItem(testKey) !== 'foo') {\n throw new Error('Unable to find match in localStorage');\n }\n Storage.removeItem(testKey);\n } catch {\n Storage = inMemoryLocalStorage();\n }\n}\n\nfunction bindActivityEvents() {\n document.addEventListener('mousedown', updateFrontendActivity, false);\n document.addEventListener('touchstart', updateFrontendActivity, false);\n document.addEventListener('keydown', updateFrontendActivity, false);\n}\n\nfunction timer() {\n const timeToFrontendTimeout = getTimeToFrontendTimeout();\n const timeToBackendTimeout = getTimeToBackendTimeout();\n if (timeToFrontendTimeout < state.minimumDeltaForFlight) {\n return logout();\n }\n\n // If we have been active in the frontend only but not done any AJAX request\n // then we want to extend the backend\n if (\n timeToBackendTimeout < state.minimumDeltaForBackendExtension &&\n timeToFrontendTimeout > state.minimumDeltaToShowReminder\n ) {\n extendBackend();\n } else if (timeToFrontendTimeout < state.minimumDeltaToShowReminder) {\n state.reminderCb(timeToFrontendTimeout);\n }\n return null;\n}\n\nfunction startTimer() {\n state.intervalInstanceId = window.setInterval(timer, RUN_EVERY);\n}\n\n// Make it a singleton\nconst instance = {\n init({ timeout, reminderCb }) {\n if (!isBrowser) {\n // eslint-disable-next-line\n console.warn('SessionCtrl init() method was called without a window!');\n return;\n }\n state.timeoutInterval = timeout; // timeout in seconds\n state.reminderCb = reminderCb;\n if (timeout && !state.initialized) {\n verifyLocalStorage();\n bindActivityEvents();\n updateBackendActivity();\n updateFrontendActivity();\n startTimer();\n state.initialized = true;\n }\n },\n\n removeCallback() {\n delete state.reminderCb;\n },\n\n continueSession(callback) {\n updateFrontendActivity();\n extendBackend(callback);\n },\n};\n\nObject.freeze(instance);\n\nexport default instance;\n","import { createUseStyles } from 'react-jss';\n\nconst useStyles = createUseStyles(theme => {\n const { palette, radius } = theme;\n return {\n iconBackground: () => ({\n background: palette.warning.main,\n 'border-radius': radius.large,\n height: '70px',\n width: '70px',\n display: 'flex',\n 'justify-content': 'center',\n 'align-items': 'center',\n }),\n };\n});\n\nexport default useStyles;\n","import React, { useEffect, useState } from 'react';\nimport { defineMessages, T, t } from '@sm/intl';\nimport PropTypes from 'prop-types';\nimport { IconLock } from '@wds/icons';\nimport { Modal } from '@wds/modal';\nimport { Button } from '@wds/button';\nimport { Grid } from '@wds/grid';\nimport { useTheme } from 'react-jss';\n\nimport SessionCtrl from './SessionCtrl';\nimport useStyles from './useStyles';\nimport { WebAssetsThemeWrapper } from '../../theme';\n\nconst COPY = defineMessages({\n CONTINUE_SESSION: {\n id: 'SessionTimeoutModal.ContinueSession',\n defaultMessage: 'CONTINUE SESSION',\n description:\n '[Type: Button][Vis.: med] - CTA for the user to continue their browsing session and not be logged out automatically.',\n },\n TIME_LEFT_MSG: {\n id: 'SessionTimeoutModal.TimeLeftMessage',\n defaultMessage:\n 'After {minutesLeft, plural, one { 1 minute } other {{ minutesLeft } minutes}} of inactivity, we sign you out to keep your data safe. Your session will expire soon, unless you click Continue Session',\n description:\n '[Type: Paragraph][Vis.: med] - Message given to the user informing them of the time left before automatic expiration.',\n },\n SESSION_HEADER: {\n id: 'SessionTimeoutModal.TimeLeftHeader',\n defaultMessage: 'Do you want to continue your session?',\n description:\n '[Type: Header][Vis.: med] - Modal header for the prompt asking the user if they want to continue their browsing session.',\n },\n});\n\nconst SessionTimeoutModal = props => (\n \n \n \n);\n\nconst SessionTimeoutModalContent = ({ user }) => {\n const [show, setShow] = useState(false);\n const timeLeft = 30; // see WEBPLAT-4491; we're not doing a time countdown anymore\n const theme = useTheme();\n const { iconBackground } = useStyles({ theme });\n\n const onReminder = () => {\n setShow(true);\n };\n const onClose = () => {\n SessionCtrl.continueSession(() => {\n setShow(false);\n });\n };\n\n useEffect(() => {\n const timeout =\n (user?.hipaa?.isHipaaEnabled && 30 * 60) ||\n (user?.group?.sessionTimeout &&\n parseInt(user.group.sessionTimeout, 10) * 60);\n if (timeout !== undefined) {\n // it could be 0\n SessionCtrl.init({ timeout, reminderCb: onReminder });\n }\n return function cleanup() {\n SessionCtrl.removeCallback();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return (\n \n \n \n \n \n
\n \n
\n \n \n \n \n \n \n \n \n \n \n );\n};\n\nSessionTimeoutModalContent.propTypes = {\n user: PropTypes.shape({\n hipaa: PropTypes.shape({\n isHipaaEnabled: PropTypes.bool,\n }),\n group: PropTypes.shape({\n sessionTimeout: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n }),\n }).isRequired,\n};\n\nexport default SessionTimeoutModal;\n","import SessionTimeoutModal from './SessionTimeoutModal';\n\nexport default SessionTimeoutModal;\n","import { FC, ReactNode } from 'react';\n\nimport { clientErrorHandler } from '../..';\n\ninterface urlObject {\n smReleaseToggles?: string;\n}\n\ninterface cookieObject {\n sm_release_toggles?: string;\n}\n\ntype url = string | urlObject;\ntype cookies = string | cookieObject;\n\nexport interface ReleaseToggleProps {\n toggleId: string;\n url?: url;\n cookies?: cookies;\n children: ReactNode;\n}\n\n/**\n * Takes the cookie string from the document and returns an Array of\n * configured release toggle IDs using the key 'sm_release_toggles'.\n *\n * @param {string} cookie: Cookie string from document\n * @return {Array}\n */\nexport const getOverridesFromCookie = (cookie?: string) => {\n if (!cookie) return [];\n const found = cookie\n .split(';')\n .filter(elem => elem)\n .map(elem => elem.split('='))\n .filter(([key, val]) => key && val)\n .map(([key, val]) => ({ key: key.trim(), val: val.trim() }))\n .find(elem => elem.key === 'sm_release_toggles');\n\n const toggles: Array = [];\n if (found) {\n found.val.split(',').forEach(elem => {\n toggles.push(elem.trim());\n });\n }\n return toggles;\n};\n\n/**\n * Takes a URL string from the window.location object (must include query\n * params) and returns an Array of the configured release toggle IDs under the\n * key 'smReleaseToggles'.\n *\n * @param {string} url: HREF string from the window.location object\n * @return {*}\n */\nexport const getOverridesFromQueryParameters = (url?: string) => {\n if (!url) return [];\n const queryStrIndex = url.indexOf('?');\n if (queryStrIndex > -1) {\n const queryStr = url.slice(queryStrIndex + 1);\n const releaseToggles = queryStr\n .split('&')\n .map(elem => elem.split('='))\n .find(elem => {\n const [key] = elem;\n return key === 'smReleaseToggles';\n });\n if (releaseToggles && releaseToggles.length > 1) {\n return releaseToggles[1].split(',').filter(elem => elem);\n }\n }\n return [];\n};\n\n/**\n * Looks for a 'sm_release_toggles' cookie. If it exists, parses out the\n * comma-separated list of toggle IDs and returns a Set of the IDs.\n *\n * @return {Set}: IDs of enabled toggles\n */\nexport const getOverrides = (url?: url, cookies?: cookies) => {\n // We know that this is from the Express req.\n if (typeof url === 'object' && typeof cookies === 'object') {\n const paramValues = (url.smReleaseToggles || '')\n .split(',')\n .map(elem => elem.trim());\n const cookieValues = (cookies.sm_release_toggles || '')\n .split(',')\n .map(elem => elem.trim());\n return new Set(paramValues.concat(cookieValues));\n }\n return new Set(\n getOverridesFromCookie(document.cookie).concat(\n getOverridesFromQueryParameters(window.location.href)\n )\n );\n};\n\n/**\n * Component wraps code that isn't ready to be seen. Children are only\n * rendered if the 'releaseToggles' cookie or query parameter is set\n * where the value is a comma-separated list of toggle IDs\n * (IE. document.cookie=\"releaseToggles=ID1,ID2,ID3\", whitespace is trimmed;\n * or https://localmonkey.com/my_page/?smReleaseToggles=ID1,ID2,ID3, no\n * whitespace trim) and the ID is in the list. If this component is rendered\n * on the client, these values are manually parsed from the window. If not,\n * they must be passed in through the queryParams and cookies props.\n *\n * Component may also have a child that is a function with the signature:\n * (isToggledOn: boolean) => Node which can be used to render a default\n * component in place of the feature component.\n *\n * If there is an error parsing the override cookies or params, it is caught,\n * logged and then the child function is called with false or null is returned.\n */\nconst ReleaseToggle: FC = ({\n toggleId,\n url,\n cookies,\n children,\n}) => {\n let showToggle;\n try {\n showToggle = getOverrides(url, cookies).has(toggleId);\n } catch (err) {\n showToggle = false;\n // TODO: Remove this cast when clientErrorHandler has been typed\n (clientErrorHandler as any).logError(\n err,\n 'There was a problem reading the override cookies and params in a ReleaseToggle'\n );\n }\n if (typeof children === 'function') return children(showToggle);\n return showToggle ? children : null;\n};\n\nexport default ReleaseToggle;\n","/**\n * TODO:\n * Is CookieBanner still being used anywhere? If not, remove it?\n */\nimport React, { useState, useEffect } from 'react';\nimport Cookie from 'js-cookie';\nimport PropTypes from 'prop-types';\nimport { T, t, defineMessages } from '@sm/intl';\nimport { MetricsTracker, USER_EVENTS } from '@sm/metrics';\n\nimport { Box } from '@wds/box';\nimport { Typography } from '@wds/typography';\nimport { Sheet } from '@wds/sheet';\nimport { Button } from '@wds/button';\n\nimport { WebAssetsThemeWrapper } from '../../theme';\n\nconst CONSENT_KEY = 'gdpr_consent';\nconst CONSENT_DENIED_KEY = 'gdpr_consent_denied';\n\nconst COPY = defineMessages({\n COOKIE_BANNER: {\n id: 'CookieBanner.cookiePolicy',\n defaultMessage:\n // eslint-disable-next-line no-multi-str\n 'In order to give you the best experience, SurveyMonkey and our third party partners may use cookies\\\n and similar technologies, for example, to analyze usage and optimize our sites and services, personalize content,\\\n tailor and measure our marketing and to keep the site secure. Please visit our\\\n privacy policy for more information and our\\\n cookies policy for a list of all cookies used.',\n description: '[Type: Label][Vis.: med] - Cookie Banner Message',\n },\n COOKIE_PREFERENCES: {\n id: 'CookieBanner.preferences',\n defaultMessage:\n 'Clear or manage cookie preferences.',\n description: '[Type: Label][Vis.: med] - Cookie Banner Preferences',\n },\n NO: {\n id: 'CookieBanner.decline',\n defaultMessage: 'DISAGREE',\n description: '[Type: Label][Vis.: med] - Cookie Banner Decline button',\n },\n AGREE: {\n id: 'CookieBanner.agree',\n defaultMessage: 'AGREE',\n description: '[Type: Label][Vis.: med] - Cookie Banner Agree button',\n },\n});\n\nconst CookieBanner = ({ GDPR }) => {\n const { hasGDPRConsent, hasExplictlyDenied } = GDPR;\n const [show, setShow] = useState(true);\n const [consent, setConsent] = useState('gdpr_consent_denied');\n\n useEffect(() => {\n if (!show) {\n MetricsTracker.track({\n name: USER_EVENTS.GDPR_ACTION,\n data: {\n actionType: USER_EVENTS.GDPR_ACTION,\n actionFlow: consent !== CONSENT_KEY ? 'denyConsent' : 'giveConsent',\n },\n });\n }\n }, [show, consent]);\n\n if (hasGDPRConsent || hasExplictlyDenied || !show) {\n return null;\n }\n\n /**\n * Agree to tracking cookie\n * @param {Object} e\n */\n const onAgree = e => {\n e.stopPropagation();\n Cookie.set(CONSENT_KEY, 'true', { expires: 365, secure: true });\n setConsent(CONSENT_KEY);\n setShow(!show);\n };\n\n /**\n * Deny tracking cookie\n */\n const onDeny = () => {\n Cookie.set(CONSENT_DENIED_KEY, 'true', { expires: 7, secure: true });\n setConsent(CONSENT_DENIED_KEY);\n setShow(!show);\n };\n\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n );\n};\n\nCookieBanner.propTypes = {\n GDPR: PropTypes.shape({\n hasGDPRConsent: PropTypes.bool,\n hasExplictlyDenied: PropTypes.bool,\n }).isRequired,\n};\n\nexport default CookieBanner;\n","/**\n * errorHandler is a singleton which allows users to log errors and get a list of subscribers.\n * It initializes the subscribers if they haven't already been initialized and does so only\n * once per instance.\n */\nexport const errorHandler = (function handlerFactory() {\n return {\n getSubscribers() {\n return errorHandler.errorSubscribers || {};\n },\n };\n})();\n\nexport function initializeErrorHandler() {\n if (typeof errorHandler.errorSubscribers !== 'undefined') {\n return;\n }\n errorHandler.errorSubscribers = {};\n if (typeof window === 'undefined') {\n return;\n }\n if (\n typeof errorHandler.errorSubscribers.splunkRum === 'undefined' &&\n typeof window.SplunkRum !== 'undefined'\n ) {\n errorHandler.errorSubscribers.splunkRum = window.SplunkRum;\n }\n errorHandler.errorSubscribers.user = (err, msg, metaData) => {\n // eslint-disable-next-line no-console\n console.error(err.toString(), msg, metaData);\n };\n}\n\nfunction tellSplunkRum(err, msg, metaData = {}) {\n try {\n const client = errorHandler.getSubscribers().splunkRum;\n if (client) {\n // This function works like console.error, so we don't really pass in\n // objects to it. If we want to capture that info, we need to pass it in\n // as a string; thus the JSON.stringify so we don't lose granularity.\n client.error(err, msg, JSON.stringify(metaData));\n }\n } catch (doNothingWithError) {\n // eslint-disable-next-line no-console\n console.log(doNothingWithError);\n }\n}\n\nfunction tellUser(err, msg, metaData) {\n const client = errorHandler.getSubscribers().user;\n if (client) {\n client(err, msg, metaData);\n }\n}\n\n/**\n *\n * @param {Error} err - Error object\n * @param {string} msg - {optional extra message}\n * @param {Object} metaData - [optional metadata object]\n */\nerrorHandler.logError = function logError(err, ...rest) {\n if (!err) return;\n let [message, metaData] = rest;\n if (typeof rest[0] === 'object' && rest.length === 1) {\n message = null;\n [metaData] = rest;\n }\n\n tellSplunkRum(err, message, metaData);\n tellUser(err, message, metaData);\n};\n","import React, { ReactElement } from 'react';\nimport { useMutation } from '@apollo/client';\n\nimport { getClientEnvironmentDetails } from '@sm/utils';\n\nimport { errorHandler as clientErrorHandler } from '../../../helpers/errorHandler';\nimport SaveTreatmentMutation from './SaveTreatment.graphql';\nimport {\n ExperimentAssignmentType,\n SaveExperimentTreatmentPayload,\n} from '../../../types';\nimport { TreatmentItem } from '..';\n\n/**\n * If the user is LO and we have values from the Svc,\n * we can set a cookie for experimentsvc to injest\n * @param {Object} saveTreatmentPayload\n * @return {null}\n */\nconst createCookie = (\n saveTreatmentPayload: SaveExperimentTreatmentPayload\n): null => {\n const { isBrowser } = getClientEnvironmentDetails();\n // no need to create a cookie if there isn't a cookie to create\n if (saveTreatmentPayload.success === false || !saveTreatmentPayload.name) {\n return null;\n }\n const { name, maxAge, assignments } = saveTreatmentPayload;\n if (isBrowser) {\n const { host } = window.location;\n const domain = host.replace(/^[^.]+\\./g, '');\n document.cookie = `${name}=${assignments}; max-age=${maxAge}; path=/; domain=${domain}`;\n }\n return null;\n};\n\nconst EXPERIMENT_ASSIGNMENT_TYPE_TO_SCHEMA = Object.freeze({\n NEW: ExperimentAssignmentType.New,\n EXISTING: ExperimentAssignmentType.Existing,\n WINNER: ExperimentAssignmentType.Winner,\n} as const) as Record;\n\ntype TreatmentProps = {\n when: string;\n treatments: Record;\n control?: boolean;\n children: React.ReactNode;\n};\n\n/**\n * Component to display a treatment\n * @param {String} when\n * @param {Object} treatments\n * @param {Boolean} control\n * @param {Function|Object} children\n * @returns {*}\n */\nconst Treatment = ({\n when,\n treatments,\n control = false,\n children,\n}: TreatmentProps): ReactElement => {\n const [saveTreatment] = useMutation(SaveTreatmentMutation);\n const childElement = typeof children === 'function' ? children() : children;\n const allTreatments = Object.keys(treatments);\n\n // If experiments fails, or the user hasn't been assigned and experiment show the control.\n if (allTreatments.length === 0 && control) {\n return childElement;\n }\n\n // if our treatment exists in the object\n if (allTreatments.length) {\n if (treatments[when] && treatments[when].treatmentName) {\n // send the data back to experiments that we are showing this treatment\n const {\n treatmentId,\n experimentId,\n treatmentName,\n experimentName,\n assignmentType: assignmentTypeString,\n } = treatments[when];\n const assignmentType =\n EXPERIMENT_ASSIGNMENT_TYPE_TO_SCHEMA[assignmentTypeString];\n saveTreatment({\n variables: {\n input: {\n treatmentId,\n treatmentName,\n experimentId,\n experimentName,\n assignmentType,\n },\n },\n })\n .then(({ data }) => {\n if (data && data.saveExperimentTreatment)\n createCookie(data.saveExperimentTreatment);\n })\n .catch(e =>\n // TODO: Remove this cast when clientErrorHandler has been typed\n (clientErrorHandler as any).logError(\n e,\n 'Unable to save experiment treatment'\n )\n );\n // Let's return the child element without waiting for the mutation as the\n // mutation doesn't really impact the children.\n return childElement;\n }\n }\n // eslint-disable-next-line react/jsx-no-useless-fragment\n return <>>;\n};\n\nexport default Treatment;\n","import React, { useState, useEffect } from 'react';\nimport { isBrowserSupported, SupportedBrowsers } from '@sm/utils';\nimport { Modal } from '@wds/modal';\nimport { defineMessages, T, t } from '@sm/intl';\nimport { WebAssetsThemeWrapper } from '../../theme';\n\nexport interface BrowserGuardProps {\n children: JSX.Element;\n supportedBrowsers: SupportedBrowsers[];\n}\n\nconst COPY = defineMessages({\n DIALOG_HEADER: {\n id: 'BrowserGuard.DialogHeader',\n defaultMessage: \"Your browser isn't supported\",\n description:\n 'Header of a dialog displaying a message to the users that their browser is not supported.',\n },\n DIALOG_BODY: {\n id: 'BrowserGuard.DialogBody',\n defaultMessage: 'For more information please visit:',\n description:\n 'Text describing that more information on the issue will be available on the following link',\n },\n LINK_TEXT: {\n id: 'BrowserGuard.LinkText',\n defaultMessage: 'Supported Browsers',\n description:\n 'Text for a link directing the user to the Supported Browsers help page',\n },\n});\n\nconst BrowserGuardDialog = (): JSX.Element => {\n return (\n \n
\n \n );\n};\n\n/**\n * Component for checking if the user browser is supported\n *\n * Basic usage example:\n * ``\n *\n * The basic usage will check against the default supported browsers\n * as documented here: https://help.surveymonkey.com/articles/en_US/kb/What-browser-versions-do-you-support\n *\n * If the user's browser is not supported a modal window will be displayed to the user.\n *\n * Optionally one can provide a list of supported browsers via the supportedBrowsers prop.\n * Also, a different UI may be rendered if a children is passed to the component.\n */\nconst BrowserGuard = ({\n // defaultProps will eventually be deprecated, so using object default values\n children = ,\n supportedBrowsers,\n}: BrowserGuardProps): JSX.Element => {\n const [hasVerified, setHasVerified] = useState(false);\n const [isSupported, setIsSupported] = useState(false);\n\n useEffect(() => {\n if (window && !hasVerified) {\n setIsSupported(\n isBrowserSupported(window.navigator.userAgent, supportedBrowsers)\n );\n setHasVerified(true);\n }\n }, [hasVerified, supportedBrowsers]);\n\n return (\n <>\n {hasVerified && !isSupported ? (\n
{children}
\n ) : null}\n >\n );\n};\n\nexport default BrowserGuard;\n","import React from 'react';\nimport { createTheming, createUseStyles, Styles, Theming } from 'react-jss';\nimport type { Classes } from 'jss';\nimport type { SurveyTheme } from './types';\n\n/** Create a React context which JSS would need to wrap on */\nconst SurveyThemeContext = React.createContext({} as SurveyTheme);\nSurveyThemeContext.displayName = 'SurveyTheme';\n\n/** Use JSS custom hook to create the wrapper */\nconst theming = createTheming(SurveyThemeContext);\n\n/** Expose the associated hooks with aliases */\nexport const {\n useTheme: useSurveyTheme,\n ThemeProvider: SurveyThemeProvider,\n} = theming;\n\n/** Recreation of `react-jss`'s `CreateUseStylesOptions`, which is dynamic and does not get exported */\ntype CreateUseStylesOptions = Omit<\n Parameters[1],\n 'theme'\n> & {\n theming?: Theming; // set theme manually as we can't access it from `react-jss` and via inference\n};\n\n/**\n * For convenience, expose a custom hook which would carry the theming context wrapper along,\n * as well as injecting style sheet name-space / class name prefix as \"sm\" by default.\n *\n * Note: One may still utilize the stock `createUseStyles()` hook to construct styles regardless\n * relying on a survey theme or not; however if they do, please keep in mind that the recommended\n * way per JSS documentation is to pass in `theming` context wrapper every time.\n * ( https://cssinjs.org/react-jss/?v=v10.8.1#using-custom-theming-context )\n *\n */\nexport const createSurveyStyles = (\n styles:\n | Styles\n | ((theme: SurveyTheme) => Styles),\n opts: CreateUseStylesOptions = {}\n): ((data?: Props & { theme?: SurveyTheme }) => Classes) =>\n createUseStyles(styles, {\n theming,\n name: 'sm',\n ...opts,\n });\n\n/**\n * The context wrapper constructed by JSS `createTheming()` hook.\n * Note: `theming.context` points to the same SurveyThemeContext we just instantiated\n */\nexport default theming;\n","import { WrenchTheme } from '@wds/styles';\nimport {\n ColorPalette,\n CommonStyle,\n FontStyleType,\n FontWeightType,\n QuestionBodyStyle,\n SurveyLogo,\n SurveyPageStyle,\n SurveyProgressBar,\n TextDecorationType,\n GetSurveyDesignResponse,\n} from './graphQlApiResponse.types';\nimport isDark from './isDark';\nimport getFontWeights, { defaultFontWeightOptions as fontWeightOption } from './getFontWeights';\nimport { SurveyTheme as SurveyThemeType, FontWeightOptionsType } from './types';\nimport { FontStyle } from '../../types';\n\nconst fontStyleOption = {\n INHERIT: 'inherit',\n INITIAL: 'initial',\n ITALIC: 'italic',\n NORMAL: 'normal',\n OBLIQUE: 'oblique',\n} as const;\n\nconst textDecorationOption = {\n NONE: 'none',\n UNDERLINE: 'underline',\n} as const;\n\nexport const breakpoints = {\n 'xxs': { 'max': '480px' },\n 'xs': { 'min': '481px', 'max': '640px' },\n 'sm': { 'min': '641px', 'max': '768px' },\n 'md': { 'min': '769px', 'max': '1024px' },\n 'lg': { 'min': '1025px', 'max': '1200px' },\n 'xl': { 'min': '1201px' },\n} as const;\n\n/** Possible Styles to format */\ntype Styles =\n | CommonStyle\n | SurveyPageStyle\n | QuestionBodyStyle\n | SurveyProgressBar\n | SurveyLogo\n | ColorPalette;\n\n\n/**\n * Generic helper to map an Object to a discriminated union of key-value tuples\n *\n * `{a: number, b?: string | null}` -> `[\"a\", number] | [\"b\", string | null | undefined]`\n*/\ntype MapKVToTupleUnion> = NonNullable<\n {\n [K in keyof T]: [K, T[K]];\n } extends Record\n ? B\n : never\n >;\n\n/**\n * Generic helper to map an Object to a discriminated union of key-value tuples and make the keys non-nullable\n *\n * `{a: number, b?: string | null}` -> `[\"a\", number] | [\"b\", string]`\n */\ntype MapKVToNonNullableTupleUnion> = NonNullable<{\n [K in keyof T]: [K, NonNullable];\n} extends Record\n ? B\n : never>;\n\ntype StyleTuples = MapKVToNonNullableTupleUnion;\n\n\n\nconst formatStyle = (kvPair: StyleTuples, styles: T) => {\n switch (kvPair[0]) {\n case 'fontWeight':\n if (styles.fontFamily) {\n const fontWeights = getFontWeights(styles.fontFamily);\n return {\n [kvPair[0]]: fontWeights[kvPair[1].toLowerCase() as keyof FontWeightOptionsType],\n };\n }\n return {\n [kvPair[0]]: fontWeightOption[kvPair[1].toLowerCase() as keyof FontWeightOptionsType],\n };\n case 'fontStyle':\n return {\n [kvPair[0]]: fontStyleOption[kvPair[1]],\n };\n case 'fontFamily':\n if (kvPair[1] === 'National2') {\n // add fallback-fonts and also use Wrench spelling of font: `'National 2'` vs `National2`\n return {\n [kvPair[0]]: WrenchTheme.type.fontFamily.base,\n };\n }\n return {\n [kvPair[0]]: kvPair[1],\n };\n case 'textDecoration':\n return {\n [kvPair[0]]: textDecorationOption[kvPair[1]],\n };\n case 'backgroundImage':\n return kvPair[1].url\n ? {\n [kvPair[0]]: `url(${kvPair[1].url})`,\n }\n : null;\n default:\n if (typeof kvPair[1] === 'object') {\n // format nested data recursively\n return { [kvPair[0]]: formatCommonStyle(kvPair[1]) };\n }\n return { [kvPair[0]]: kvPair[1] };\n }\n};\n\nexport type FontWeightOptions = typeof fontWeightOption[Lowercase]\nexport type FontStyleOptions = typeof fontStyleOption[FontStyleType]\nexport type TextDecorationOptions = typeof textDecorationOption[TextDecorationType]\n\n\ntype MappedFields = 'fontWeight' | 'fontStyle' | 'textDecoration' | 'backgroundImage';\ntype PickResult = {\n [Key in keyof T as Exclude]: NonNullable\n} & (T extends Pick ? { fontWeight?: FontWeightOptions } : {})\n & (T extends Pick ? { fontStyle?: FontStyleOptions } : {})\n & (T extends Pick ?{ textDecoration?: TextDecorationOptions } : {})\n & (T extends Pick ? {backgroundImage?: string} : {});\n\n\n/** Formats data recursively */\nconst formatCommonStyle = ({\n __typename,\n ...styles\n}: T & { __typename?: string }): PickResult => {\n const entries = Object.entries(styles) as MapKVToTupleUnion[];\n\n return entries.reduce((acc, args) => {\n const [key, val] = args as StyleTuples;\n return val === null || val === undefined\n ? acc\n : {\n ...acc,\n ...formatStyle([key, val], styles),\n };\n }, {} as PickResult );\n};\n\n/** Standardizes the formatting to be CSS/JSS compatible */\nexport const formatEntity = (data?: T | null) =>\n data && formatCommonStyle(data) || undefined;\n\n\n/** Collapses `Maybe` (`T | null | undefined`) to `T | undefined` */\nexport const defaultNullToUndefined = (arg: T) => arg === null ? undefined : arg as T extends null ? never: T;\n\n/** Format GraphQL to Theme representation */\nexport const formatTheme = (response: GetSurveyDesignResponse = {}): SurveyThemeType => {\n\n const { theme, ...settings } = response?.survey?.design || {};\n\n const {\n name = \"Default\",\n selectedColorPalette,\n layout,\n surveyPage,\n surveyTitle,\n pageTitle,\n questionTitle,\n questionBody,\n button,\n error,\n exitLink,\n artifacts,\n isAccessible,\n isCustomTheme,\n } = theme || {};\n\n const { logo, progressBar } = settings;\n\n const surveyPageBackgroundImage = artifacts?.background?.url;\n const smFont =\n \"'National 2', 'Helvetica Neue', Helvetica, Arial, 'Hiragino Sans', 'Hiragino Kaku Gothic Pro', '游ゴシック', '游ゴシック体', YuGothic, 'Yu Gothic', 'ï¼ï¼³ ゴシック', 'MS Gothic', sans-serif\";\n\n const surveyTheme: SurveyThemeType = {\n name,\n fontFamily: smFont,\n fontSize: {\n body: 16,\n },\n fontWeight: fontWeightOption,\n layout: defaultNullToUndefined(layout),\n isAccessible: isAccessible && !isCustomTheme,\n isCustomTheme,\n isDark: isDark(selectedColorPalette?.primaryBackgroundColor || '#fff'),\n surveyPage: {\n ...formatEntity(surveyPage),\n ...(surveyPageBackgroundImage && {\n backgroundImage: `url(${surveyPageBackgroundImage})`,\n }),\n },\n surveyTitle: formatEntity(surveyTitle),\n pageTitle: formatEntity(pageTitle),\n questionTitle: formatEntity(questionTitle),\n questionBody: {\n color: selectedColorPalette?.answerColor,\n ...formatEntity(questionBody),\n },\n button: formatEntity(button),\n error: formatEntity(error),\n exitLink: formatEntity(exitLink),\n ...(logo && {\n logo: formatEntity(logo),\n }),\n ...(progressBar && {\n progressBar: formatEntity(progressBar),\n }),\n ...formatEntity(selectedColorPalette),\n breakpoints,\n };\n\n return surveyTheme;\n};\n","import React from 'react';\nimport { useQuery } from '@apollo/client';\nimport { SurveyThemeProvider } from './context';\nimport { formatTheme } from './helpers';\nimport { SurveyTheme as SurveyThemeType } from './types';\nimport getSurveyDesign from './SurveyTheme.graphql';\n\ntype Props = {\n surveyId: string;\n targetEndPoint?: string;\n headers?: Record;\n children: React.ReactNode;\n};\n\n/** A simple wrapper composes inner children with the fetched theming info. */\nconst SurveyTheme = ({\n children,\n surveyId,\n targetEndPoint,\n headers,\n}: Props): JSX.Element | null => {\n const {\n data,\n loading,\n error: fetchError,\n refetch,\n } = useQuery(getSurveyDesign, {\n variables: {\n id: surveyId,\n errorPolicy: 'all',\n partialRefetch: true,\n ...(targetEndPoint && {\n context: {\n targetPath: `/lo-graphql/${targetEndPoint}`,\n ...(headers && headers),\n },\n }),\n },\n });\n\n /* No-op on the loading state.\n * The wrapping component should know better how to compose with a representable skeleton.\n */\n if (loading) {\n return null;\n }\n\n const surveyTheme: SurveyThemeType = formatTheme(data);\n\n return (\n \n {children}\n \n );\n};\n\nexport default SurveyTheme;\n","import React, { useEffect } from 'react';\nimport {\n DefaultTheme,\n ThemeProvider as ReactJSSThemeProvider,\n} from 'react-jss';\nimport { getClientEnvironmentDetails } from '@sm/utils';\n\ntype GlobalThemeProviderProps = {\n theme: Theme;\n children: React.ReactNode;\n};\n\nconst GlobalThemeProvider = ({ theme, children }: GlobalThemeProviderProps) => {\n const { isBrowser } = getClientEnvironmentDetails();\n useEffect(() => {\n /**\n * remove the JSS styles from the DOM after the client has loaded\n * https://cssinjs.org/react-jss?v=v10.4.0#server-side-rendering\n */\n if (isBrowser) {\n const jss = document.getElementById('jss');\n if (jss) {\n jss.remove();\n }\n }\n }, [isBrowser]);\n\n return (\n {children}\n );\n};\n\nexport default GlobalThemeProvider;\n","import GlobalThemeProvider from './GlobalThemeProvider';\n\nexport default GlobalThemeProvider;\n","import React, { createContext } from 'react';\nimport { createTheming, ThemeProvider } from 'react-jss';\nimport { WrenchTheme as WebAssetsTheme } from '@wds/styles';\n\nconst ThemeContext = createContext({});\n\nconst theming = createTheming(ThemeContext);\n\nconst {\n ThemeProvider: WebAssetsThemeProvider,\n useTheme: useWebAssetsTheme,\n} = theming;\n\nconst WebAssetsThemeWrapper = ({ children }: any) => {\n const theme = useWebAssetsTheme();\n return (\n \n {children}\n \n );\n};\n\nconst withWebAssetsTheme = (\n Component: React.ComponentType\n) => (props: T) => {\n return (\n \n \n \n );\n};\n\nexport {\n WebAssetsThemeProvider,\n useWebAssetsTheme,\n WebAssetsTheme,\n WebAssetsThemeWrapper,\n withWebAssetsTheme,\n};\nexport type ThemeShape = typeof WebAssetsTheme;\n","export type Maybe = T | null;\nexport type InputMaybe = Maybe;\nexport type Exact = {\n [K in keyof T]: T[K];\n};\nexport type MakeOptional = Omit & {\n [SubKey in K]?: Maybe;\n};\nexport type MakeMaybe = Omit & {\n [SubKey in K]: Maybe;\n};\n/** All built-in and custom scalars, mapped to their actual values */\nexport type Scalars = {\n ID: string;\n String: string;\n Boolean: boolean;\n Int: number;\n Float: number;\n AdvancedFilter: any;\n DateTime: any;\n RGBA: any;\n SolutionsStudyMethodologyConfigValueDiscriminated: any;\n};\n\n/** Supports Image and Text A/B question type answers */\nexport type AbQuestionVariableAnswerData = QuestionVariableAnswerData & {\n __typename?: 'ABQuestionVariableAnswerData';\n headers: Array;\n stimuliPerRespondent?: Maybe;\n type: SurveyQuestionType;\n};\n\nexport type AiPredictedQuestionArray = {\n __typename?: 'AIPredictedQuestionArray';\n answerChoices?: Maybe>>;\n title?: Maybe;\n type?: Maybe;\n};\n\nexport type AiPredictedSurveyQuestions = {\n __typename?: 'AIPredictedSurveyQuestions';\n languageCode?: Maybe;\n questions?: Maybe>>;\n surveyEntity?: Maybe;\n surveyTitle?: Maybe;\n};\n\nexport type Awss3PostPolicy = {\n __typename?: 'AWSS3PostPolicy';\n fields: Awss3PostPolicyFields;\n url: Scalars['String'];\n};\n\nexport type Awss3PostPolicyFields = {\n __typename?: 'AWSS3PostPolicyFields';\n acl: Scalars['String'];\n bucket: Scalars['String'];\n key: Scalars['String'];\n policy: Scalars['String'];\n xAmzAlgorithm: Scalars['String'];\n xAmzCredential: Scalars['String'];\n xAmzDate: Scalars['String'];\n xAmzServerSideEncryption?: Maybe;\n xAmzSignature: Scalars['String'];\n};\n\nexport type AccountOwnerPublicInfo = {\n __typename?: 'AccountOwnerPublicInfo';\n email: Scalars['String'];\n firstName?: Maybe;\n id: Scalars['ID'];\n lastName?: Maybe;\n username: Scalars['String'];\n};\n\n/** The types of activities associated with an individual activity log */\nexport enum ActivityActionType {\n AuthenticationFailed = 'AUTHENTICATION_FAILED',\n AuthenticationSignout = 'AUTHENTICATION_SIGNOUT',\n AuthenticationSucceeded = 'AUTHENTICATION_SUCCEEDED',\n CollectorInfoCreated = 'COLLECTOR_INFO_CREATED',\n CollectorInfoDeleted = 'COLLECTOR_INFO_DELETED',\n CollectorInfoUpdated = 'COLLECTOR_INFO_UPDATED',\n CustomRolesCreate = 'CUSTOM_ROLES_CREATE',\n CustomRolesDelete = 'CUSTOM_ROLES_DELETE',\n CustomRolesUpdate = 'CUSTOM_ROLES_UPDATE',\n ExportDownloaded = 'EXPORT_DOWNLOADED',\n ExportExportCreate = 'EXPORT_EXPORT_CREATE',\n GrantInfoCreated = 'GRANT_INFO_CREATED',\n GrantInfoDeleted = 'GRANT_INFO_DELETED',\n GroupInfoUpdatedGroupName = 'GROUP_INFO_UPDATED_GROUP_NAME',\n InviteCreated = 'INVITE_CREATED',\n InviteResent = 'INVITE_RESENT',\n MemberDeleted = 'MEMBER_DELETED',\n MemberJoined = 'MEMBER_JOINED',\n MemberScimCreateConflict = 'MEMBER_SCIM_CREATE_CONFLICT',\n MemberScimCreateFailed = 'MEMBER_SCIM_CREATE_FAILED',\n MemberScimCreateSuccess = 'MEMBER_SCIM_CREATE_SUCCESS',\n MemberScimDeleteFailed = 'MEMBER_SCIM_DELETE_FAILED',\n MemberScimDeleteSuccess = 'MEMBER_SCIM_DELETE_SUCCESS',\n MemberScimUpdateConflict = 'MEMBER_SCIM_UPDATE_CONFLICT',\n MemberScimUpdateFailed = 'MEMBER_SCIM_UPDATE_FAILED',\n MemberScimUpdateSuccess = 'MEMBER_SCIM_UPDATE_SUCCESS',\n MemberUpdatedGroupMemberType = 'MEMBER_UPDATED_GROUP_MEMBER_TYPE',\n PermissionCreated = 'PERMISSION_CREATED',\n PermissionUpdated = 'PERMISSION_UPDATED',\n RespondentDeleted = 'RESPONDENT_DELETED',\n RespondentUpdated = 'RESPONDENT_UPDATED',\n ScimTokenCreated = 'SCIM_TOKEN_CREATED',\n ScimTokenRevoked = 'SCIM_TOKEN_REVOKED',\n ScimTokenUpdated = 'SCIM_TOKEN_UPDATED',\n ScimUserCreated = 'SCIM_USER_CREATED',\n ScimUserDeleted = 'SCIM_USER_DELETED',\n ScimUserLinkedToSso = 'SCIM_USER_LINKED_TO_SSO',\n ScimUserUpdated = 'SCIM_USER_UPDATED',\n SharedViewCreated = 'SHARED_VIEW_CREATED',\n SharedViewUpdated = 'SHARED_VIEW_UPDATED',\n SurveyInfoCopy = 'SURVEY_INFO_COPY',\n SurveyInfoCreate = 'SURVEY_INFO_CREATE',\n SurveyInfoDelete = 'SURVEY_INFO_DELETE',\n SurveyInfoTransfer = 'SURVEY_INFO_TRANSFER',\n SurveyInfoUpdate = 'SURVEY_INFO_UPDATE',\n}\n\nexport enum ActivityCategories {\n AppInstall = 'APP_INSTALL',\n Collaboration = 'COLLABORATION',\n Collect = 'COLLECT',\n Logins = 'LOGINS',\n Scim = 'SCIM',\n Survey = 'SURVEY',\n}\n\n/** The activity category related to app installs */\nexport type ActivityCategoryAppInstall = ActivityLog & {\n __typename?: 'ActivityCategoryAppInstall';\n actionType: ActivityActionType;\n appName: Scalars['String'];\n city?: Maybe;\n country?: Maybe;\n createdAt: Scalars['DateTime'];\n division?: Maybe;\n email?: Maybe;\n groupId: Scalars['ID'];\n id: Scalars['ID'];\n ipAddress?: Maybe;\n memberType: ActivityMemberType;\n userId: Scalars['ID'];\n username: Scalars['String'];\n};\n\n/** The activity category related to collaboration of surveys */\nexport type ActivityCategoryCollaboration = ActivityLog & {\n __typename?: 'ActivityCategoryCollaboration';\n actionType: ActivityActionType;\n activityEmail?: Maybe;\n activityUsername?: Maybe;\n city?: Maybe;\n country?: Maybe;\n createdAt: Scalars['DateTime'];\n division?: Maybe;\n email?: Maybe;\n groupId: Scalars['ID'];\n id: Scalars['ID'];\n ipAddress?: Maybe;\n memberType: ActivityMemberType;\n newVal?: Maybe;\n nickname?: Maybe;\n prevVal?: Maybe;\n shareType?: Maybe;\n title?: Maybe;\n userId: Scalars['ID'];\n username: Scalars['String'];\n};\n\n/** The activity category related to survey collectors */\nexport type ActivityCategoryCollect = ActivityLog & {\n __typename?: 'ActivityCategoryCollect';\n action?: Maybe;\n actionType: ActivityActionType;\n city?: Maybe;\n country?: Maybe;\n createdAt: Scalars['DateTime'];\n division?: Maybe;\n email?: Maybe;\n groupId: Scalars['ID'];\n id: Scalars['ID'];\n ipAddress?: Maybe;\n memberType: ActivityMemberType;\n name?: Maybe;\n type?: Maybe;\n userId: Scalars['ID'];\n username: Scalars['String'];\n};\n\n/** The activity category related to custom roles */\nexport type ActivityCategoryCustomRole = ActivityLog & {\n __typename?: 'ActivityCategoryCustomRole';\n actionType: ActivityActionType;\n city?: Maybe;\n country?: Maybe;\n createdAt: Scalars['DateTime'];\n division?: Maybe;\n email?: Maybe;\n groupId: Scalars['ID'];\n id: Scalars['ID'];\n ipAddress?: Maybe;\n memberType: ActivityMemberType;\n roleName?: Maybe;\n userId: Scalars['ID'];\n username: Scalars['String'];\n};\n\n/** The default activity category for when an activity has no raw activity data */\nexport type ActivityCategoryDefault = ActivityLog & {\n __typename?: 'ActivityCategoryDefault';\n actionType: ActivityActionType;\n city?: Maybe;\n country?: Maybe;\n createdAt: Scalars['DateTime'];\n division?: Maybe;\n email?: Maybe;\n groupId: Scalars['ID'];\n id: Scalars['ID'];\n ipAddress?: Maybe;\n memberType: ActivityMemberType;\n userId: Scalars['ID'];\n username: Scalars['String'];\n};\n\n/** The activity category related to exporting data across the service */\nexport type ActivityCategoryExport = ActivityLog & {\n __typename?: 'ActivityCategoryExport';\n actionType: ActivityActionType;\n city?: Maybe;\n country?: Maybe;\n createdAt: Scalars['DateTime'];\n division?: Maybe;\n email?: Maybe;\n exportJobFormat?: Maybe;\n exportJobType?: Maybe;\n groupId: Scalars['ID'];\n id: Scalars['ID'];\n ipAddress?: Maybe;\n memberType: ActivityMemberType;\n title?: Maybe;\n userId: Scalars['ID'];\n username: Scalars['String'];\n};\n\n/** The activity category related to user login and authentication */\nexport type ActivityCategoryLogin = ActivityLog & {\n __typename?: 'ActivityCategoryLogin';\n actionType: ActivityActionType;\n activityEmail?: Maybe;\n city?: Maybe;\n country?: Maybe;\n createdAt: Scalars['DateTime'];\n division?: Maybe;\n email?: Maybe;\n groupId: Scalars['ID'];\n id: Scalars['ID'];\n ipAddress?: Maybe;\n memberType: ActivityMemberType;\n thirdParty?: Maybe;\n userId: Scalars['ID'];\n username: Scalars['String'];\n};\n\n/** The activity category related to the changes in permissions for surveys */\nexport type ActivityCategoryPermissionUpdate = ActivityLog & {\n __typename?: 'ActivityCategoryPermissionUpdate';\n actionType: ActivityActionType;\n activityEmail?: Maybe;\n activityUsername?: Maybe;\n city?: Maybe;\n country?: Maybe;\n createdAt: Scalars['DateTime'];\n division?: Maybe;\n email?: Maybe;\n groupId: Scalars['ID'];\n id: Scalars['ID'];\n ipAddress?: Maybe;\n memberType: ActivityMemberType;\n nickname?: Maybe;\n permission0?: Maybe;\n permission1?: Maybe;\n permission2?: Maybe;\n title?: Maybe;\n userId: Scalars['ID'];\n username: Scalars['String'];\n};\n\n/** The activity category related to survey updates */\nexport type ActivityCategorySurvey = ActivityLog & {\n __typename?: 'ActivityCategorySurvey';\n actionType: ActivityActionType;\n activityUsername?: Maybe;\n city?: Maybe;\n country?: Maybe;\n createdAt: Scalars['DateTime'];\n division?: Maybe;\n email?: Maybe;\n groupId: Scalars['ID'];\n id: Scalars['ID'];\n ipAddress?: Maybe;\n memberType: ActivityMemberType;\n nickname?: Maybe;\n title?: Maybe;\n userId: Scalars['ID'];\n username: Scalars['String'];\n};\n\n/** The types of methods to collect survey results */\nexport enum ActivityCollectorType {\n Audience = 'AUDIENCE',\n Email = 'EMAIL',\n Facebook = 'FACEBOOK',\n FacebookMessenger = 'FACEBOOK_MESSENGER',\n MobileSdk = 'MOBILE_SDK',\n OfflineKiosk = 'OFFLINE_KIOSK',\n Popup = 'POPUP',\n Sms = 'SMS',\n Weblink = 'WEBLINK',\n}\n\n/** The actions a user could take on a collector object */\nexport enum ActivityCollectorUpdateAction {\n Close = 'CLOSE',\n Open = 'OPEN',\n Rename = 'RENAME',\n Update = 'UPDATE',\n}\n\n/** The format of exported jobs */\nexport enum ActivityExportJobFormat {\n Csv = 'CSV',\n Excel = 'EXCEL',\n ExcelPlus = 'EXCEL_PLUS',\n Gss = 'GSS',\n Html = 'HTML',\n Pdf = 'PDF',\n Png = 'PNG',\n Ppt = 'PPT',\n Spss = 'SPSS',\n}\n\nexport type ActivityLog = {\n actionType: ActivityActionType;\n city?: Maybe;\n country?: Maybe;\n createdAt: Scalars['DateTime'];\n division?: Maybe;\n email?: Maybe;\n groupId: Scalars['ID'];\n id: Scalars['ID'];\n ipAddress?: Maybe;\n memberType: ActivityMemberType;\n userId: Scalars['ID'];\n username: Scalars['String'];\n};\n\nexport type ActivityLogsInput = {\n categories?: InputMaybe>>;\n divisionId?: InputMaybe;\n endDate?: InputMaybe;\n memberId?: InputMaybe;\n page?: InputMaybe;\n pageSize?: InputMaybe;\n startDate?: InputMaybe;\n};\n\nexport type ActivityLogsList = PaginatedList & {\n __typename?: 'ActivityLogsList';\n items: Array;\n pageInfo: PageInfo;\n totalCount: Scalars['Int'];\n};\n\n/** The types of members associated with an individual activity log */\nexport enum ActivityMemberType {\n AccountOwner = 'ACCOUNT_OWNER',\n Admin = 'ADMIN',\n Analyst = 'ANALYST',\n Casual = 'CASUAL',\n DivisionAdmin = 'DIVISION_ADMIN',\n NonEnterprise = 'NON_ENTERPRISE',\n Regular = 'REGULAR',\n}\n\n/** The permission types on a survey */\nexport enum ActivityPermissionType {\n Analyze = 'ANALYZE',\n Collect = 'COLLECT',\n Design = 'DESIGN',\n}\n\n/** The restrictions on shared surveys */\nexport enum ActivityShareType {\n Private = 'PRIVATE',\n Public = 'PUBLIC',\n Restricted = 'RESTRICTED',\n}\n\n/** The third party services a user could use as a log in method */\nexport enum ActivityThirdPartyLoginType {\n Facebook = 'FACEBOOK',\n Google = 'GOOGLE',\n Microsoft = 'MICROSOFT',\n SamlEnterprise = 'SAML_ENTERPRISE',\n}\n\nexport type AddOnProductItem = {\n __typename?: 'AddOnProductItem';\n isActive: Scalars['Boolean'];\n name: Scalars['String'];\n price: PriceItem;\n productId: Scalars['ID'];\n productMetadata: ProductMetaData;\n quantity: ProductQuantity;\n skuId: Scalars['ID'];\n unitLabel: Scalars['String'];\n};\n\nexport type AddSuggestedLogoToSurveyPayload = {\n __typename?: 'AddSuggestedLogoToSurveyPayload';\n /**\n * Whether or not the logo was added successfully\n * @deprecated Clearbit deprecation CREATE-18066\n */\n logoAdded: Scalars['Boolean'];\n /** @deprecated Clearbit deprecation CREATE-18066 */\n success: Scalars['Boolean'];\n /** @deprecated Clearbit deprecation CREATE-18066 */\n survey?: Maybe;\n /**\n * Whether or not a theme was applied successfully\n * @deprecated Clearbit deprecation CREATE-18066\n */\n themeApplied: Scalars['Boolean'];\n};\n\nexport type AddUsersToAudienceCreditPoolInput = {\n /** The id of the credit pool */\n poolId: Scalars['ID'];\n /** List of user IDs to be added to pool */\n userIds: Array;\n};\n\n/** Indicates how new surveys created by team members should be automatically shared. */\nexport enum AdminShareSetting {\n MaxPermissions = 'MAX_PERMISSIONS',\n MaxPermissionsAllowShareOff = 'MAX_PERMISSIONS_ALLOW_SHARE_OFF',\n MaxPermissionsCanDecrease = 'MAX_PERMISSIONS_CAN_DECREASE',\n ViewOnlyPermissionsCanIncrease = 'VIEW_ONLY_PERMISSIONS_CAN_INCREASE',\n}\n\nexport type AdvancedFeedbackValue = {\n id: Scalars['String'];\n options: Array;\n};\n\nexport type AdvancedFilterInput = {\n rules?: InputMaybe;\n};\n\nexport type AdvancedRecommendation = {\n __typename?: 'AdvancedRecommendation';\n id: Scalars['ID'];\n options: Array;\n};\n\nexport enum AlertChannel {\n Email = 'EMAIL',\n Mobile = 'MOBILE',\n}\n\nexport type AllStimuli = {\n __typename?: 'AllStimuli';\n description: Scalars['String'];\n family: Scalars['String'];\n heading: Scalars['String'];\n id: Scalars['ID'];\n image?: Maybe;\n nickname: Scalars['String'];\n randomAssignment: StimuliRandomAssignment;\n stimuliId: Scalars['ID'];\n type: Scalars['String'];\n};\n\nexport type AllStimuliImageStimulus = {\n __typename?: 'AllStimuliImageStimulus';\n id?: Maybe;\n s3Key?: Maybe;\n url?: Maybe;\n};\n\nexport type AnalysisAdvancedFilter = {\n __typename?: 'AnalysisAdvancedFilter';\n rules?: Maybe;\n};\n\nexport type AnalysisCollectorFilter = {\n __typename?: 'AnalysisCollectorFilter';\n collectorIds: Array;\n};\n\nexport type AnalysisCompletenessFilter = {\n __typename?: 'AnalysisCompletenessFilter';\n completely: Scalars['Boolean'];\n disqualified: Scalars['Boolean'];\n overquota: Scalars['Boolean'];\n partially: Scalars['Boolean'];\n};\n\n/** Cell type for XLS format exports */\nexport enum AnalysisExportCellDisplay {\n ActualText = 'ACTUAL_TEXT',\n NumericalValue = 'NUMERICAL_VALUE',\n}\n\n/** Column type for XLS format exports */\nexport enum AnalysisExportColumnCompression {\n Condensed = 'CONDENSED',\n CondensedMulti = 'CONDENSED_MULTI',\n Expanded = 'EXPANDED',\n}\n\nexport type AnalysisExportDisplayInfoTypeInput = {\n completeResponses: Scalars['Int'];\n /** Translations to display in export report */\n summaryTranslations?: InputMaybe;\n totalResponses: Scalars['Int'];\n /** Date export was created in a vanity string */\n vanityDateCreated: Scalars['String'];\n};\n\nexport type AnalysisExportFile = {\n __typename?: 'AnalysisExportFile';\n downloadLink?: Maybe;\n name: Scalars['String'];\n};\n\n/** Analyze Export Job type */\nexport type AnalysisExportJob = {\n __typename?: 'AnalysisExportJob';\n createdAt: Scalars['DateTime'];\n expiresAt?: Maybe;\n file: AnalysisExportFile;\n format: AnalysisExportJobFormat;\n id: Scalars['ID'];\n responseCount: Scalars['Int'];\n status: AnalysisExportJobStatus;\n survey: Survey;\n type: AnalysisJobType;\n};\n\n/** File format for exported data */\nexport enum AnalysisExportJobFormat {\n Csv = 'CSV',\n Pdf = 'PDF',\n Ppt = 'PPT',\n Spss = 'SPSS',\n Xls = 'XLS',\n}\n\n/** Required job info for all analysis export variations */\nexport type AnalysisExportJobInfoInput = {\n /** Pages to include in the export from show rule (default ALL) */\n pages?: InputMaybe>>;\n /** Questions to include in the export from show rule (default ALL) */\n questions?: InputMaybe>>;\n viewName: Scalars['String'];\n};\n\n/** Inputs required to construct the export job */\nexport type AnalysisExportJobInput = {\n /** Custom filename */\n analysisExportJobName: Scalars['String'];\n analysisViewId: Scalars['String'];\n /** File format for export job */\n jobFormat: AnalysisExportJobFormat;\n /** Job information for export job */\n jobInfo: AnalysisExportJobInfoInput;\n /** Export job type */\n jobType: AnalysisJobType;\n respondentCount: Scalars['Int'];\n surveyId: Scalars['ID'];\n};\n\nexport type AnalysisExportJobList = PaginatedList & {\n __typename?: 'AnalysisExportJobList';\n items: Array;\n pageInfo: PageInfo;\n totalCount: Scalars['Int'];\n};\n\n/** Analyze Export Job Status */\nexport enum AnalysisExportJobStatus {\n Enqueued = 'ENQUEUED',\n ServerError = 'SERVER_ERROR',\n Started = 'STARTED',\n Success = 'SUCCESS',\n}\n\n/** Orientation type for PDF format exports */\nexport enum AnalysisExportOrientation {\n Landscape = 'LANDSCAPE',\n Portait = 'PORTAIT',\n}\n\n/** Paper size for PDF format exports */\nexport enum AnalysisExportPaperSize {\n A4 = 'A4',\n Legal = 'LEGAL',\n Letter = 'LETTER',\n}\n\n/** All inputs required for question level exports */\nexport type AnalysisExportQuestionParamsInput = {\n /** Choice to include branding in export report */\n includeBranding?: InputMaybe;\n /** Choice to include charts in export report */\n includeCharts?: InputMaybe;\n /** Choice to include open ended question responses in export report */\n includeOpenEnded?: InputMaybe