@clickview/lite 0.103.0 → 0.103.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/.vite/manifest.json +392 -392
  2. package/dist/bundles.json +1 -1
  3. package/dist/en.json +1 -1
  4. package/dist/scripts/{BTXOoJko2.chunk.js → BFH_tnSb2.chunk.js} +3 -3
  5. package/dist/scripts/{BTXOoJko2.chunk.js.map → BFH_tnSb2.chunk.js.map} +1 -1
  6. package/dist/scripts/{Dvl1XgHV2.chunk.js → BeW5XQTb2.chunk.js} +2 -2
  7. package/dist/scripts/{Dvl1XgHV2.chunk.js.map → BeW5XQTb2.chunk.js.map} +1 -1
  8. package/dist/scripts/C8l37H7t2.chunk.js +2 -0
  9. package/dist/scripts/{Cj_F4Lv92.chunk.js.map → C8l37H7t2.chunk.js.map} +1 -1
  10. package/dist/scripts/{BoT5D3IL.chunk.js → CIzlhCeS.chunk.js} +2 -2
  11. package/dist/scripts/{BoT5D3IL.chunk.js.map → CIzlhCeS.chunk.js.map} +1 -1
  12. package/dist/scripts/{BTr5dJhb.chunk.js → CfrfHGSh.chunk.js} +2 -2
  13. package/dist/scripts/{BTr5dJhb.chunk.js.map → CfrfHGSh.chunk.js.map} +1 -1
  14. package/dist/scripts/{BTugVIIN2.chunk.js → CsCjBSq62.chunk.js} +2 -2
  15. package/dist/scripts/{BTugVIIN2.chunk.js.map → CsCjBSq62.chunk.js.map} +1 -1
  16. package/dist/scripts/{CvSpUZcJ2.chunk.js → Dd23z1_x2.chunk.js} +2 -2
  17. package/dist/scripts/{CvSpUZcJ2.chunk.js.map → Dd23z1_x2.chunk.js.map} +1 -1
  18. package/dist/scripts/{CWCtYUUU.chunk.js → Drh1bb9z.chunk.js} +2 -2
  19. package/dist/scripts/{CWCtYUUU.chunk.js.map → Drh1bb9z.chunk.js.map} +1 -1
  20. package/dist/scripts/{Cc9f2ux0.chunk.js → Drx3PvJj.chunk.js} +2 -2
  21. package/dist/scripts/{Cc9f2ux0.chunk.js.map → Drx3PvJj.chunk.js.map} +1 -1
  22. package/dist/scripts/QVwuOts3.chunk.js +12 -0
  23. package/dist/scripts/QVwuOts3.chunk.js.map +1 -0
  24. package/dist/scripts/{app-k0jrat-b.js → app-BHlllGhO.js} +4 -4
  25. package/dist/scripts/{app-k0jrat-b.js.map → app-BHlllGhO.js.map} +1 -1
  26. package/dist/scripts/{BQNOt7_Q2.chunk.js → kLCNzxrH2.chunk.js} +2 -2
  27. package/dist/scripts/{BQNOt7_Q2.chunk.js.map → kLCNzxrH2.chunk.js.map} +1 -1
  28. package/dist/scripts/{DXkvlC_92.chunk.js → wpRpI9h02.chunk.js} +2 -2
  29. package/dist/scripts/{DXkvlC_92.chunk.js.map → wpRpI9h02.chunk.js.map} +1 -1
  30. package/package.json +1 -1
  31. package/dist/scripts/Cj_F4Lv92.chunk.js +0 -2
  32. package/dist/scripts/DFleEz5_.chunk.js +0 -12
  33. package/dist/scripts/DFleEz5_.chunk.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QVwuOts3.chunk.js","names":["divWithClassName","Handlebars","Handlebars","Handlebars"],"sources":["../../../../../node_modules/@restart/hooks/esm/useMediaQuery.js","../../../../../node_modules/@restart/hooks/esm/useBreakpoint.js","../../../../../node_modules/react-bootstrap/esm/OffcanvasBody.js","../../../../../node_modules/react-bootstrap/esm/OffcanvasToggling.js","../../../../../node_modules/react-bootstrap/esm/OffcanvasHeader.js","../../../../../node_modules/react-bootstrap/esm/OffcanvasTitle.js","../../../../../node_modules/react-bootstrap/esm/Offcanvas.js","../../../../libs/shared/src/components/error-boundary/ErrorBoundary.tsx","../../../../libs/shared/src/hooks/useTabbingListener.tsx","../../src/shared/layouts/teacher-layout/teacher-layout.module.scss","../../src/shared/layouts/teacher-layout/TeacherLayoutHelper.tsx","../../../../libs/shared/src/components/skip-link/skip-link.module.scss","../../../../libs/shared/src/components/skip-link/SkipLink.tsx","../../../../libs/shared/src/context/product-tips-context/ProductTipsContext.tsx","../../src/shared/components/dev/cv-dev-tools/CVDevTools.tsx","../../src/shared/components/snowing/snowing.module.scss","../../src/shared/components/snowing/Snowing.tsx","../../src/shared/utils/LiteLayoutHelper.ts","../../../../libs/shared/src/constants/BrazeActions.ts","../../src/shared/views/braze-iam-region/helpers/braze-iam-helper/BamEventListenerMap.ts","../../src/shared/views/braze-iam-region/helpers/braze-iam-helper/BrazeIamMap.ts","../../src/shared/views/braze-iam-region/helpers/braze-iam-helper/BrazeIamHelper.ts","../../src/shared/views/braze-iam-region/BrazeIamRegion.tsx","../../src/shared/hooks/useCookieConsent.ts","../../src/shared/views/cookie-consent/data/cookies-data.ts","../../src/shared/views/cookie-consent/helpers/StringHelper.ts","../../src/shared/views/cookie-consent/components/category-info/category-info.module.scss","../../src/shared/views/cookie-consent/components/category-info/CategoryInfo.tsx","../../src/shared/views/cookie-consent/helpers/ConsentHelper.ts","../../src/shared/views/cookie-consent/components/cookie-consent-category-details/CookieConsentCategoryDetail.tsx","../../src/shared/views/cookie-consent/components/cookie-consent-manage-preferences/cookie-consent-manage-preferences.module.scss","../../src/shared/views/cookie-consent/components/cookie-consent-manage-preferences/CookieConsentManagePreferences.tsx","../../src/shared/views/cookie-consent/components/cookie-consent-manage-popup/cookie-consent-manage-popup.module.scss","../../src/shared/views/cookie-consent/components/cookie-consent-manage-popup/CookieConsentManagePopup.tsx","../../src/shared/views/cookie-consent/components/cookie-consent-banner/cookie-consent-banner.module.scss","../../src/shared/views/cookie-consent/components/cookie-consent-banner/CookieConsentBanner.tsx","../../src/shared/views/cookie-consent/CookieConsentView.tsx","../../src/shared/views/footer/FooterView.tsx","../../src/shared/views/global-player/global-player.module.scss","../../src/shared/views/global-player/GlobalPlayerView.tsx","../../../../libs/shared/src/apps/notifications/components/notification-status/NotificationStatus.hbs","../../../../libs/shared/src/apps/notifications/components/notification-status/notification-status.module.scss","../../../../libs/shared/src/apps/notifications/components/notification-status/NotificationStatusComponent.ts","../../../../libs/shared/src/apps/notifications/views/popover/NotificationsPopover.hbs","../../../../libs/shared/src/apps/notifications/views/popover/NotificationsPopoverView.ts","../../../../libs/shared/src/legacy/behaviors/tooltip/TooltipBehavior.ts","../../../../libs/shared/src/apps/notifications/views/header/NotificationHeader.hbs","../../../../libs/shared/src/apps/notifications/views/header/notification-header.module.scss","../../../../libs/shared/src/apps/notifications/views/header/NotificationHeaderView.ts","../../../../libs/shared/src/images/svg/objects/SpeechSvg.tsx","../../../../libs/shared/src/views/user-options/components/customer-selector-item.module.scss","../../../../libs/shared/src/views/user-options/components/CustomerSelectorItem.tsx","../../../../libs/shared/src/views/user-options/UserOptionsViewUtils.ts","../../../../libs/shared/src/views/user-options/user-options.module.scss","../../../../libs/shared/src/views/user-options/UserOptionsView.tsx","../../src/shared/hooks/useBrazeContentCards.ts","../../src/shared/hooks/use-lite-banner/useLiteBanner.ts","../../src/shared/views/braze-banner/braze-banner.module.scss","../../src/shared/views/braze-banner/BrazeBannerView.tsx","../../src/shared/views/plugin-banner/plugin-banner.module.scss","../../src/shared/views/plugin-banner/PluginBannerView.tsx","../../src/shared/views/banner/BannerView.tsx","../../src/apps/search/components/search-bar-v2/components/search-in-tag/SearchInTag.tsx","../../src/apps/search/components/search-bar-v2/components/text-highlight/TextHighlight.tsx","../../src/apps/search/components/search-bar-v2/components/search-suggestion/search-suggestion.module.scss","../../src/apps/search/components/search-bar-v2/components/search-suggestion/SearchSuggestion.tsx","../../src/apps/search/components/search-bar-v2/components/section-title/section-title.module.scss","../../src/apps/search/components/search-bar-v2/components/section-title/SectionTitle.tsx","../../../../libs/shared/src/apps/search/utils/RecentSearchHelper.ts","../../../../libs/shared/src/hooks/useKeyboardShortcut.ts","../../../../libs/shared/src/hooks/useScrollbar.ts","../../src/shared/views/banner/constants/LiteBanner.ts","../../src/apps/search/hooks/useLiteSearchBar.tsx","../../src/apps/search/hooks/useSearchIn.tsx","../../src/apps/search/utils/getLiteSearchEventLogger.ts","../../src/apps/search/components/search-bar-v2/constants/LiteSearchSettings.ts","../../src/apps/search/components/search-bar-v2/utils/SearchBarUtils.ts","../../src/apps/search/components/search-bar-v2/lite-search-bar.module.scss","../../src/apps/search/components/search-bar-v2/LiteSearchBarV2.tsx","../../src/apps/search/views/lite-search-bar-view/lite-search-bar-view.module.scss","../../src/apps/search/views/lite-search-bar-view/LiteSearchBarView.tsx","../../src/shared/views/header/HeaderViewUtils.ts","../../src/shared/views/header/header.module.scss","../../src/shared/views/header/HeaderView.tsx","../../src/shared/components/upsell-header/components/upsell-advert/upsell-advert.module.scss","../../src/shared/components/upsell-header/components/upsell-advert/components/UpsellAdvertControls.tsx","../../src/shared/components/upsell-header/components/upsell-advert/components/UpsellAdvertTextBlock.tsx","../../src/shared/components/upsell-header/components/upsell-advert/components/UpsellAdvertVideo.tsx","../../src/shared/components/upsell-header/components/upsell-advert/UpsellAdvert.tsx","../../../../libs/shared/src/enums/UpsellType.ts","../../src/shared/components/sticky-banner/sticky-banner.module.scss","../../src/shared/components/sticky-banner/components/LeftDecorator.tsx","../../src/shared/components/sticky-banner/StickyBanner.tsx","../../src/shared/components/upsell-badge/UpsellBadge.tsx","../../src/shared/components/upsell-header/components/upsell-banner/upsell-banner.module.scss","../../src/shared/components/upsell-header/components/upsell-banner/UpsellBanner.tsx","../../src/shared/components/upsell-header/upsell-header.module.scss","../../src/shared/components/upsell-header/UpsellHeader.tsx","../../src/shared/views/header-banner/BannerWhiteListHelper.ts","../../src/shared/views/header-banner/BannerWhiteList.ts","../../src/shared/views/header-banner/components/freemium/FreemiumBanner.tsx","../../src/shared/views/header-banner/components/trial/TrialBanner.tsx","../../src/shared/views/header-banner/HeaderBannerView.tsx","../../src/shared/utils/HubHelper.ts","../../src/shared/hooks/hubs/useHubDashboards.ts","../../src/shared/views/left-nav-v2/enums/LeftNavTheme.ts","../../../../libs/shared/src/images/svg/objects/CalendarOutlineSvg.tsx","../../src/shared/views/left-nav-v2/utils/create-left-nav-builder/handlers/getCalendarItemHandler.ts","../../../../libs/shared/src/images/svg/objects/ClassroomsFilledSvg.tsx","../../src/shared/views/left-nav-v2/utils/create-left-nav-builder/handlers/getClassroomsItemHandler.ts","../../../../libs/shared/src/images/svg/objects/FernBoldSvg.tsx","../../../../libs/shared/src/images/svg/objects/FernSvg.tsx","../../../../libs/shared/src/images/svg/objects/LocationFilledSvg.tsx","../../../../libs/shared/src/images/svg/objects/LocationSvg.tsx","../../src/shared/views/left-nav-v2/utils/create-left-nav-builder/handlers/getHubsItemHandler.ts","../../src/shared/views/left-nav-v2/utils/create-left-nav-builder/handlers/getLibrariesItemHandler.ts","../../src/shared/views/left-nav-v2/utils/create-left-nav-builder/handlers/getPresentationItemHandler.ts","../../src/shared/views/left-nav-v2/hooks/use-left-nav-builder/useLeftNavBuilder.ts","../../src/shared/views/left-nav-v2/components/left-nav-complication/left-nav-complication.module.scss","../../src/shared/views/left-nav-v2/components/left-nav-complication/LeftNavComplication.tsx","../../src/shared/views/left-nav-v2/left-nav-v2.module.scss","../../src/shared/views/left-nav-v2/components/left-nav-applink/left-nav-applink.module.scss","../../src/shared/views/left-nav-v2/components/left-nav-applink/LeftNavAppLink.tsx","../../src/shared/views/left-nav-v2/components/left-nav-dropdown/left-nav-dropdown.module.scss","../../src/shared/views/left-nav-v2/components/left-nav-dropdown/LeftNavDropdownButton.tsx","../../src/shared/views/left-nav-v2/components/left-nav-dropdown/LeftNavDropdown.tsx","../../src/shared/views/left-nav-v2/components/left-nav-item-component/LeftNavItemComponent.tsx","../../src/shared/views/left-nav-v2/components/scroll-track/ScrollTrack.tsx","../../src/shared/views/left-nav-v2/LeftNavV2View.tsx","../../src/shared/views/open-in-app-prompt/open-in-app-prompt.module.scss","../../src/shared/views/open-in-app-prompt/OpenInAppPromptView.tsx","../../../../libs/shared/src/components/product-tip/product-tip.module.scss","../../../../libs/shared/src/components/product-tip/ProductTip.tsx","../../src/shared/views/product-tips/tips/nz-hub/nz-hub-product-tip.module.scss","../../src/shared/views/product-tips/tips/nz-hub/NzHubProductTipView.tsx","../../src/shared/views/product-tips/tips/streamable-migrated/streamable-migrated-product-tip.module.scss","../../src/shared/views/product-tips/tips/streamable-migrated/StreamableMigratedProductTipView.tsx","../../src/shared/views/product-tips/tips/tutorial-playlist/tutorial-videos-product-tip.module.scss","../../src/shared/views/product-tips/tips/tutorial-playlist/TutorialPlaylistProductTipView.tsx","../../src/shared/constants/product-tips/product-tip-styles.module.scss","../../src/shared/constants/product-tips/LiteProductTipsConfig.ts","../../src/shared/hooks/product-tips/useStreamableMigration.ts","../../src/shared/hooks/product-tips/useFetchProductTipsData.ts","../../src/shared/hooks/product-tips/useLiteProductTips.ts","../../src/shared/utils/ProductTipsHelper.ts","../../src/shared/views/product-tips/product-tips.module.scss","../../src/shared/views/product-tips/ProductTipsContainerView.tsx","../../src/shared/layouts/teacher-layout/drag-mask/drag-mask.module.scss","../../src/shared/layouts/teacher-layout/drag-mask/DragMask.tsx","../../src/shared/layouts/teacher-layout/TeacherLayoutComponent.tsx"],"sourcesContent":["import useEffect from './useIsomorphicEffect';\nimport { useState } from 'react';\nconst matchersByWindow = new WeakMap();\nconst getMatcher = (query, targetWindow) => {\n if (!query || !targetWindow) return undefined;\n const matchers = matchersByWindow.get(targetWindow) || new Map();\n matchersByWindow.set(targetWindow, matchers);\n let mql = matchers.get(query);\n if (!mql) {\n mql = targetWindow.matchMedia(query);\n mql.refCount = 0;\n matchers.set(mql.media, mql);\n }\n return mql;\n};\n/**\n * Match a media query and get updates as the match changes. The media string is\n * passed directly to `window.matchMedia` and run as a Layout Effect, so initial\n * matches are returned before the browser has a chance to paint.\n *\n * ```tsx\n * function Page() {\n * const isWide = useMediaQuery('min-width: 1000px')\n *\n * return isWide ? \"very wide\" : 'not so wide'\n * }\n * ```\n *\n * Media query lists are also reused globally, hook calls for the same query\n * will only create a matcher once under the hood.\n *\n * @param query A media query\n * @param targetWindow The window to match against, uses the globally available one as a default.\n */\nexport default function useMediaQuery(query, targetWindow = typeof window === 'undefined' ? undefined : window) {\n const mql = getMatcher(query, targetWindow);\n const [matches, setMatches] = useState(() => mql ? mql.matches : false);\n useEffect(() => {\n let mql = getMatcher(query, targetWindow);\n if (!mql) {\n return setMatches(false);\n }\n let matchers = matchersByWindow.get(targetWindow);\n const handleChange = () => {\n setMatches(mql.matches);\n };\n mql.refCount++;\n mql.addListener(handleChange);\n handleChange();\n return () => {\n mql.removeListener(handleChange);\n mql.refCount--;\n if (mql.refCount <= 0) {\n matchers == null ? void 0 : matchers.delete(mql.media);\n }\n mql = undefined;\n };\n }, [query]);\n return matches;\n}","import useMediaQuery from './useMediaQuery';\nimport { useMemo } from 'react';\n/**\n * Create a responsive hook we a set of breakpoint names and widths.\n * You can use any valid css units as well as a numbers (for pixels).\n *\n * **NOTE:** The object key order is important! it's assumed to be in order from smallest to largest\n *\n * ```ts\n * const useBreakpoint = createBreakpointHook({\n * xs: 0,\n * sm: 576,\n * md: 768,\n * lg: 992,\n * xl: 1200,\n * })\n * ```\n *\n * **Watch out!** using string values will sometimes construct media queries using css `calc()` which\n * is NOT supported in media queries by all browsers at the moment. use numbers for\n * the widest range of browser support.\n *\n * @param breakpointValues A object hash of names to breakpoint dimensions\n */\nexport function createBreakpointHook(breakpointValues) {\n const names = Object.keys(breakpointValues);\n function and(query, next) {\n if (query === next) {\n return next;\n }\n return query ? `${query} and ${next}` : next;\n }\n function getNext(breakpoint) {\n return names[Math.min(names.indexOf(breakpoint) + 1, names.length - 1)];\n }\n function getMaxQuery(breakpoint) {\n const next = getNext(breakpoint);\n let value = breakpointValues[next];\n if (typeof value === 'number') value = `${value - 0.2}px`;else value = `calc(${value} - 0.2px)`;\n return `(max-width: ${value})`;\n }\n function getMinQuery(breakpoint) {\n let value = breakpointValues[breakpoint];\n if (typeof value === 'number') {\n value = `${value}px`;\n }\n return `(min-width: ${value})`;\n }\n\n /**\n * Match a set of breakpoints\n *\n * ```tsx\n * const MidSizeOnly = () => {\n * const isMid = useBreakpoint({ lg: 'down', sm: 'up' });\n *\n * if (isMid) return <div>On a Reasonable sized Screen!</div>\n * return null;\n * }\n * ```\n * @param breakpointMap An object map of breakpoints and directions, queries are constructed using \"and\" to join\n * breakpoints together\n * @param window Optionally specify the target window to match against (useful when rendering into iframes)\n */\n\n /**\n * Match a single breakpoint exactly, up, or down.\n *\n * ```tsx\n * const PhoneOnly = () => {\n * const isSmall = useBreakpoint('sm', 'down');\n *\n * if (isSmall) return <div>On a Small Screen!</div>\n * return null;\n * }\n * ```\n *\n * @param breakpoint The breakpoint key\n * @param direction A direction 'up' for a max, 'down' for min, true to match only the breakpoint\n * @param window Optionally specify the target window to match against (useful when rendering into iframes)\n */\n\n function useBreakpoint(breakpointOrMap, direction, window) {\n let breakpointMap;\n if (typeof breakpointOrMap === 'object') {\n breakpointMap = breakpointOrMap;\n window = direction;\n direction = true;\n } else {\n direction = direction || true;\n breakpointMap = {\n [breakpointOrMap]: direction\n };\n }\n let query = useMemo(() => Object.entries(breakpointMap).reduce((query, [key, direction]) => {\n if (direction === 'up' || direction === true) {\n query = and(query, getMinQuery(key));\n }\n if (direction === 'down' || direction === true) {\n query = and(query, getMaxQuery(key));\n }\n return query;\n }, ''), [JSON.stringify(breakpointMap)]);\n return useMediaQuery(query, window);\n }\n return useBreakpoint;\n}\nconst useBreakpoint = createBreakpointHook({\n xs: 0,\n sm: 576,\n md: 768,\n lg: 992,\n xl: 1200,\n xxl: 1400\n});\nexport default useBreakpoint;","\"use client\";\n\nimport * as React from 'react';\nimport classNames from 'classnames';\nimport { useBootstrapPrefix } from './ThemeProvider';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nconst OffcanvasBody = /*#__PURE__*/React.forwardRef(({\n className,\n bsPrefix,\n as: Component = 'div',\n ...props\n}, ref) => {\n bsPrefix = useBootstrapPrefix(bsPrefix, 'offcanvas-body');\n return /*#__PURE__*/_jsx(Component, {\n ref: ref,\n className: classNames(className, bsPrefix),\n ...props\n });\n});\nOffcanvasBody.displayName = 'OffcanvasBody';\nexport default OffcanvasBody;","\"use client\";\n\nimport classNames from 'classnames';\nimport * as React from 'react';\nimport { ENTERED, ENTERING, EXITING } from 'react-transition-group/Transition';\nimport { getChildRef } from '@restart/ui/utils';\nimport transitionEndListener from './transitionEndListener';\nimport TransitionWrapper from './TransitionWrapper';\nimport { useBootstrapPrefix } from './ThemeProvider';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nconst transitionStyles = {\n [ENTERING]: 'show',\n [ENTERED]: 'show'\n};\nconst OffcanvasToggling = /*#__PURE__*/React.forwardRef(({\n bsPrefix,\n className,\n children,\n in: inProp = false,\n mountOnEnter = false,\n unmountOnExit = false,\n appear = false,\n ...props\n}, ref) => {\n bsPrefix = useBootstrapPrefix(bsPrefix, 'offcanvas');\n return /*#__PURE__*/_jsx(TransitionWrapper, {\n ref: ref,\n addEndListener: transitionEndListener,\n in: inProp,\n mountOnEnter: mountOnEnter,\n unmountOnExit: unmountOnExit,\n appear: appear,\n ...props,\n childRef: getChildRef(children),\n children: (status, innerProps) => /*#__PURE__*/React.cloneElement(children, {\n ...innerProps,\n className: classNames(className, children.props.className, (status === ENTERING || status === EXITING) && `${bsPrefix}-toggling`, transitionStyles[status])\n })\n });\n});\nOffcanvasToggling.displayName = 'OffcanvasToggling';\nexport default OffcanvasToggling;","\"use client\";\n\nimport classNames from 'classnames';\nimport * as React from 'react';\nimport { useBootstrapPrefix } from './ThemeProvider';\nimport AbstractModalHeader from './AbstractModalHeader';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nconst OffcanvasHeader = /*#__PURE__*/React.forwardRef(({\n bsPrefix,\n className,\n closeLabel = 'Close',\n closeButton = false,\n ...props\n}, ref) => {\n bsPrefix = useBootstrapPrefix(bsPrefix, 'offcanvas-header');\n return /*#__PURE__*/_jsx(AbstractModalHeader, {\n ref: ref,\n ...props,\n className: classNames(className, bsPrefix),\n closeLabel: closeLabel,\n closeButton: closeButton\n });\n});\nOffcanvasHeader.displayName = 'OffcanvasHeader';\nexport default OffcanvasHeader;","\"use client\";\n\nimport * as React from 'react';\nimport classNames from 'classnames';\nimport divWithClassName from './divWithClassName';\nimport { useBootstrapPrefix } from './ThemeProvider';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nconst DivStyledAsH5 = divWithClassName('h5');\nconst OffcanvasTitle = /*#__PURE__*/React.forwardRef(({\n className,\n bsPrefix,\n as: Component = DivStyledAsH5,\n ...props\n}, ref) => {\n bsPrefix = useBootstrapPrefix(bsPrefix, 'offcanvas-title');\n return /*#__PURE__*/_jsx(Component, {\n ref: ref,\n className: classNames(className, bsPrefix),\n ...props\n });\n});\nOffcanvasTitle.displayName = 'OffcanvasTitle';\nexport default OffcanvasTitle;","\"use client\";\n\nimport classNames from 'classnames';\nimport useBreakpoint from '@restart/hooks/useBreakpoint';\nimport useEventCallback from '@restart/hooks/useEventCallback';\nimport * as React from 'react';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport BaseModal from '@restart/ui/Modal';\nimport Fade from './Fade';\nimport OffcanvasBody from './OffcanvasBody';\nimport OffcanvasToggling from './OffcanvasToggling';\nimport ModalContext from './ModalContext';\nimport OffcanvasHeader from './OffcanvasHeader';\nimport OffcanvasTitle from './OffcanvasTitle';\nimport { useBootstrapPrefix } from './ThemeProvider';\nimport BootstrapModalManager, { getSharedManager } from './BootstrapModalManager';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nimport { Fragment as _Fragment } from \"react/jsx-runtime\";\nimport { jsxs as _jsxs } from \"react/jsx-runtime\";\nfunction DialogTransition(props) {\n return /*#__PURE__*/_jsx(OffcanvasToggling, {\n ...props\n });\n}\nfunction BackdropTransition(props) {\n return /*#__PURE__*/_jsx(Fade, {\n ...props\n });\n}\nconst Offcanvas = /*#__PURE__*/React.forwardRef(({\n bsPrefix,\n className,\n children,\n 'aria-labelledby': ariaLabelledby,\n placement = 'start',\n responsive,\n /* BaseModal props */\n\n show = false,\n backdrop = true,\n keyboard = true,\n scroll = false,\n onEscapeKeyDown,\n onShow,\n onHide,\n container,\n autoFocus = true,\n enforceFocus = true,\n restoreFocus = true,\n restoreFocusOptions,\n onEntered,\n onExit,\n onExiting,\n onEnter,\n onEntering,\n onExited,\n backdropClassName,\n manager: propsManager,\n renderStaticNode = false,\n ...props\n}, ref) => {\n const modalManager = useRef();\n bsPrefix = useBootstrapPrefix(bsPrefix, 'offcanvas');\n const [showOffcanvas, setShowOffcanvas] = useState(false);\n const handleHide = useEventCallback(onHide);\n const hideResponsiveOffcanvas = useBreakpoint(responsive || 'xs', 'up');\n useEffect(() => {\n // Handles the case where screen is resized while the responsive\n // offcanvas is shown. If `responsive` not provided, just use `show`.\n setShowOffcanvas(responsive ? show && !hideResponsiveOffcanvas : show);\n }, [show, responsive, hideResponsiveOffcanvas]);\n const modalContext = useMemo(() => ({\n onHide: handleHide\n }), [handleHide]);\n function getModalManager() {\n if (propsManager) return propsManager;\n if (scroll) {\n // Have to use a different modal manager since the shared\n // one handles overflow.\n if (!modalManager.current) modalManager.current = new BootstrapModalManager({\n handleContainerOverflow: false\n });\n return modalManager.current;\n }\n return getSharedManager();\n }\n const handleEnter = (node, ...args) => {\n if (node) node.style.visibility = 'visible';\n onEnter == null || onEnter(node, ...args);\n };\n const handleExited = (node, ...args) => {\n if (node) node.style.visibility = '';\n onExited == null || onExited(...args);\n };\n const renderBackdrop = useCallback(backdropProps => /*#__PURE__*/_jsx(\"div\", {\n ...backdropProps,\n className: classNames(`${bsPrefix}-backdrop`, backdropClassName)\n }), [backdropClassName, bsPrefix]);\n const renderDialog = dialogProps => /*#__PURE__*/_jsx(\"div\", {\n ...dialogProps,\n ...props,\n className: classNames(className, responsive ? `${bsPrefix}-${responsive}` : bsPrefix, `${bsPrefix}-${placement}`),\n \"aria-labelledby\": ariaLabelledby,\n children: children\n });\n return /*#__PURE__*/_jsxs(_Fragment, {\n children: [!showOffcanvas && (responsive || renderStaticNode) && renderDialog({}), /*#__PURE__*/_jsx(ModalContext.Provider, {\n value: modalContext,\n children: /*#__PURE__*/_jsx(BaseModal, {\n show: showOffcanvas,\n ref: ref,\n backdrop: backdrop,\n container: container,\n keyboard: keyboard,\n autoFocus: autoFocus,\n enforceFocus: enforceFocus && !scroll,\n restoreFocus: restoreFocus,\n restoreFocusOptions: restoreFocusOptions,\n onEscapeKeyDown: onEscapeKeyDown,\n onShow: onShow,\n onHide: handleHide,\n onEnter: handleEnter,\n onEntering: onEntering,\n onEntered: onEntered,\n onExit: onExit,\n onExiting: onExiting,\n onExited: handleExited,\n manager: getModalManager(),\n transition: DialogTransition,\n backdropTransition: BackdropTransition,\n renderBackdrop: renderBackdrop,\n renderDialog: renderDialog\n })\n })]\n });\n});\nOffcanvas.displayName = 'Offcanvas';\nexport default Object.assign(Offcanvas, {\n Body: OffcanvasBody,\n Header: OffcanvasHeader,\n Title: OffcanvasTitle\n});","import React from 'react';\n\nimport { Core } from 'libs/common/core';\nimport { HashObject } from 'libs/common/react/interfaces';\n\ninterface ThrowErrorBoundaryProps extends React.PropsWithChildren<HashObject> {\n /**\n * Must be a ctor of a SilentError otherwise Core.ErrorHelper.throw\n * will rethrow the error and our app will crash out anyway\n */\n throwError: new (message: string) => Core.SilentError;\n renderError?: never;\n}\n\ninterface RenderErrorBoundaryProps extends React.PropsWithChildren<HashObject> {\n throwError?: never;\n /**\n * Will render this component instead of throwing an error\n */\n renderError: () => React.ReactElement;\n}\n\ntype ErrorBoundaryProps = ThrowErrorBoundaryProps | RenderErrorBoundaryProps;\n\ninterface ErrorBoundaryState {\n error: Error;\n}\n\nexport class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {\n private currentErrorHandled: boolean = false;\n declare public props: ErrorBoundaryProps;\n\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = { error: null };\n }\n\n static getDerivedStateFromError(error: Error) {\n return { error };\n }\n\n public componentDidCatch(error: Error, errorInfo: any): void {\n if (this.currentErrorHandled)\n return;\n\n this.currentErrorHandled = true;\n\n /**\n * Log language errors to track js without throwing an execution-breaking error\n */\n if ((window as any).trackJs)\n (window as any).trackJs.console.error(error.message, { errorInfo });\n\n if (!this.props.throwError)\n return;\n\n /**\n * Throw an error for our error handlers to handle\n */\n Core.ErrorHelper.throw(new this.props.throwError(error.message));\n\n /**\n * This is trash, but I can't find a nicer way to swallow multiple errors\n * throw within a single render lifetime - Sha\n */\n window.setTimeout(() => {\n this.currentErrorHandled = false;\n this.setState({ error: null });\n }, 500);\n }\n\n public render(): React.ReactNode {\n const { error } = this.state;\n\n if (error && this.props.renderError) {\n const Child = this.props.renderError;\n return <Child />;\n }\n\n if (error || !this.props.children) {\n return <></>;\n }\n\n return this.props.children;\n }\n}\n","import { useEffect } from 'react';\n\n// This means the a11y outline styles will only be applied to elements when focused by tabbing. Not by clicking.\n// This is so we can preserve a11y when it matters (when users are tabbing) but preserve aesthetics.\n\nexport function useTabbingListener(): void {\n function handleFirstTab(e: KeyboardEvent): void {\n if (e.key === 'Tab') {\n // This class is implemented in `_outline.scss`\n document.body.classList.add('user-is-tabbing');\n\n window.removeEventListener('keydown', handleFirstTab);\n window.addEventListener('mousedown', handleMouseDownOnce);\n }\n }\n\n function handleMouseDownOnce() {\n document.body.classList.remove('user-is-tabbing');\n\n window.removeEventListener('mousedown', handleMouseDownOnce);\n window.addEventListener('keydown', handleFirstTab);\n }\n\n useEffect(() => {\n window.addEventListener('keydown', handleFirstTab);\n return () => window.removeEventListener('keydown', handleFirstTab);\n }, []);\n}\n","@import '~styles/utils/include-media';\n:local {\n .content {\n padding-top: $spacer;\n min-height: 90vh;\n\n display: flex;\n flex-direction: column;\n }\n\n .collapsedNavContent {\n padding-left: $cv-left-nav-small-width;\n }\n\n .pluginCollapsedNavContent {\n padding-left: 4.5rem;\n }\n\n .hiddenNavContent {\n padding-left: 0;\n }\n\n .container {\n @include media('<=xl') {\n max-width: 100%;\n }\n }\n\n .mask {\n z-index: 1020;\n }\n\n .searchMask {\n background-color: $white;\n transition: all .2s ease-in-out;\n opacity: 0;\n z-index: -1;\n\n &.show {\n opacity: 1;\n z-index: 1000;\n }\n }\n\n .searchBackdrop {\n background-color: $black;\n min-height: 100vh;\n height: 100%;\n z-index: -1;\n opacity: 0;\n\n &.show {\n opacity: 0.4;\n z-index: 1034;\n }\n }\n\n .fixedBottomRightContainer {\n position: fixed;\n right: $spacer;\n bottom: 0;\n // Feel free to increase this as needed if the container ever falls below other UI elements with a higher z-index.\n z-index: $zindex-tooltip + 1;\n }\n\n .lockedWidth {\n min-width: map-get($grid-breakpoints, xl);\n }\n\n .tocPortal {\n position: fixed;\n right: 0;\n z-index: 1001; //below dropdown menu\n }\n\n .bannerPortalContainer {\n display: contents;\n }\n}\n","import { LeftNavState } from 'shared/views/left-nav-v2/enums/LeftNavState';\n\nimport styles from './teacher-layout.module.scss';\n\ninterface DerivedNavState {\n state: LeftNavState;\n showMask: boolean;\n contentClass: string;\n}\n\nexport const TeacherLayoutHelper = {\n getDerivedNavState(\n collapse: boolean,\n isMobile: boolean,\n isTablet: boolean,\n isHorizontalTablet: boolean,\n isDesktop: boolean,\n showNav: boolean,\n isPlugin: boolean\n ): DerivedNavState {\n const collapsedNavClass = isPlugin ? styles.pluginCollapsedNavContent : styles.collapsedNavContent;\n\n if (!showNav) {\n return {\n state: LeftNavState.Hidden,\n showMask: false,\n contentClass: styles.hiddenNavContent\n };\n }\n\n if (isMobile) {\n return {\n state: collapse ? LeftNavState.Hidden : LeftNavState.Open,\n showMask: !collapse,\n contentClass: styles.hiddenNavContent\n };\n }\n\n if (isTablet || isHorizontalTablet) {\n return {\n state: collapse ? LeftNavState.Collapsed : LeftNavState.Open,\n showMask: !collapse,\n contentClass: !collapse ? collapsedNavClass : ''\n };\n }\n\n if (isDesktop) {\n return {\n state: collapse ? LeftNavState.Collapsed : LeftNavState.Open,\n showMask: !collapse,\n contentClass: !collapse ? collapsedNavClass : ''\n };\n }\n\n return {\n state: collapse ? LeftNavState.Collapsed : LeftNavState.Open,\n showMask: false,\n contentClass: ''\n };\n },\n\n getContainerClassNames(isInFloatingPlayer: boolean) {\n // Right align content in the alert-player container.\n const alertPlayerContainerClassName = `\n d-flex flex-column align-items-end ${ isInFloatingPlayer ? styles.fixedBottomRightContainer : ''}\n `;\n \n /**\n * If the player is in the viewport we only apply the fixed position\n * styling to the alert container.\n *\n * Else we fix the entire alert-player container.\n */\n const alertContainerClassName = !isInFloatingPlayer ?\n styles.fixedBottomRightContainer :\n '';\n \n return {\n alertPlayerContainerClassName,\n alertContainerClassName\n };\n }\n};\n",":local {\n .skipLink {\n position: absolute;\n left: -9999px;\n z-index: 9999;\n opacity: 0;\n }\n\n .skipLink:focus {\n left: 0;\n opacity: 1;\n }\n}","import React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\n\nimport styles from './skip-link.module.scss';\n\nconst namespace = 'shared.skipLink';\n\ntype SkipTag = 'main';\n\ninterface SkipLinkProps {\n tag: SkipTag;\n}\n\nexport function SkipLink(props: SkipLinkProps) {\n function skipToTag() {\n const tag = document.querySelector(props.tag);\n \n (tag?.querySelector('a, button, div[role=button]') as HTMLElement)?.focus();\n }\n\n return (\n <button\n className={`${styles.skipLink} btn btn-outline-dark text-info fw-semibold`}\n onClick={skipToTag}\n >\n <Text namespace={namespace} phrase={props.tag} />\n </button>\n );\n}\n","import React from 'react';\n\nimport { ProductTipId } from 'libs/shared/interfaces';\n\ntype RefsHash = Partial<Record<ProductTipId, HTMLElement | null>>;\n\nexport interface ProductTipsContextValues {\n refs?: RefsHash;\n setProductTipRef?: (id: ProductTipId, ref: HTMLElement) => void;\n cleanUpProductTipRef?: (id: ProductTipId) => void;\n}\n\nconst ProductTipsContext = React.createContext<ProductTipsContextValues>({\n setProductTipRef: () => {},\n cleanUpProductTipRef: () => {},\n refs: {}\n});\n\nexport function useProductTipsContext(tipId?: ProductTipId) {\n const { setProductTipRef, cleanUpProductTipRef, refs } = React.useContext(ProductTipsContext);\n\n React.useEffect(() => {\n if (!tipId)\n return;\n\n return () => cleanUpProductTipRef(tipId);\n }, [tipId]);\n\n return {\n setProductTipRef: (ref: HTMLElement) => setProductTipRef(tipId, ref),\n refs\n };\n}\n\nexport function ProductTipsContextProvider(props: React.PropsWithChildren) {\n const [ refs, setRefs ] = React.useState<RefsHash>({});\n\n function setProductTipRef(id: ProductTipId, element: HTMLElement) {\n if (refs[id] || !element || !id)\n return;\n \n setRefs({\n ...refs,\n [id]: element\n });\n }\n\n function cleanUpProductTipRef(id: ProductTipId) {\n if (!id)\n return;\n\n setRefs({\n ...refs,\n [id]: null\n });\n }\n\n return (\n <ProductTipsContext.Provider value={{\n refs,\n setProductTipRef,\n cleanUpProductTipRef\n }}>\n {props.children}\n </ProductTipsContext.Provider>\n );\n}\n","import React from 'react';\nimport { TanStackDevtools } from '@tanstack/react-devtools';\n\nimport { IconButton } from 'libs/shared/components/icon-button/IconButton';\nimport { CodeSvg } from 'libs/shared/images/svg/objects/CodeSvg';\n\nimport { PermissionsDebugPanel } from '../permissions-debug-panel/PermissionsDebugPanel';\n\nexport function CVDevTools() {\n return (\n <>\n <TanStackDevtools\n config={{\n theme: 'dark',\n position: 'bottom-left',\n hideUntilHover: true,\n customTrigger: <IconButton svg={CodeSvg} className='btn btn-dark'>Dev Tools</IconButton>\n }}\n plugins={[{\n id: 'permissions',\n name: '🔑 Permissions',\n render: <PermissionsDebugPanel />\n }]}\n />\n </>\n );\n}\n","/* customizable snowflake styling */\n\n@keyframes snowflakes-fall {\n 0% { transform: translateY(0) }\n 100% { transform: translateY(110vh) }\n}\n\n@keyframes snowflakes-shake {\n 0%, 100% { transform: translateX(0) }\n 50% { transform: translateX(80px) }\n}\n\n// Snowflake positions and delays configuration\n$snowflakes: (\n 0: (left: 1%, delay: 0s, inner-delay: 0s),\n 1: (left: 10%, delay: 1s, inner-delay: 1s),\n 2: (left: 20%, delay: 0.5s, inner-delay: 6s),\n 3: (left: 30%, delay: 2s, inner-delay: 4s),\n 4: (left: 40%, delay: 2s, inner-delay: 2s),\n 5: (left: 50%, delay: 3s, inner-delay: 8s),\n 6: (left: 60%, delay: 2s, inner-delay: 6s),\n 7: (left: 70%, delay: 1s, inner-delay: 2.5s),\n 8: (left: 80%, delay: 0s, inner-delay: 1s),\n 9: (left: 90%, delay: 1.5s, inner-delay: 3s),\n 10: (left: 25%, delay: 0s, inner-delay: 2s),\n 11: (left: 65%, delay: 2.5s, inner-delay: 4s)\n);\n\n.snowflake {\n color: #b3d8f0;\n font-size: 1.5em;\n font-family: Arial, sans-serif;\n position: fixed;\n top: -10%;\n z-index: 9999;\n -webkit-user-select: none;\n user-select: none;\n cursor: default;\n pointer-events: none;\n animation: snowflakes-shake 3s ease-in-out infinite running;\n\n .inner {\n animation: snowflakes-fall 10s linear infinite running;\n }\n\n // Generate nth-of-type rules for each snowflake\n @each $index, $props in $snowflakes {\n @if $index == 1 {\n &:first-of-type {\n left: map-get($props, left);\n animation-delay: map-get($props, delay);\n \n .inner {\n animation-delay: map-get($props, inner-delay);\n }\n }\n } @else {\n &:nth-of-type(#{$index}) {\n left: map-get($props, left);\n animation-delay: map-get($props, delay);\n \n .inner {\n animation-delay: map-get($props, inner-delay);\n }\n }\n }\n }\n}","import React from 'react';\n\nimport styles from './snowing.module.scss';\n\nexport function Snowing() {\n return (\n <div className={styles.snowing} aria-hidden='true'>\n {Array.from({ length: 12 }).map((_, index) => (\n <div key={index} className={styles.snowflake}>\n <div className={styles.inner}>❅</div>\n </div>\n ))}\n </div>\n );\n}\n","import { ContextService } from 'libs/shared/services/ContextService';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nconst DropzoneAppLinkBlacklist = {\n [`${AppChannels.VIDEOS}:${Actions.Videos.EDIT_VIDEO}`]: true\n};\n\nexport const LiteLayoutHelper = {\n disableDropzone(disable: boolean): boolean {\n if (disable)\n return true;\n\n const appLink = ContextService.getCurrentRoute()?.appLink;\n\n if (!appLink)\n return false;\n\n const appLinkKey = `${appLink.application}:${appLink.action}`;\n\n return DropzoneAppLinkBlacklist[appLinkKey];\n }\n};\n","export const BrazeActions = {\n BAM: 'cv:iam:action'\n} as const;\n","import type { BamEventListenerCallback, BamEventListenerCallbackOptions, BrazeIAMCustomEventAction } from 'libs/shared/interfaces/braze/BrazeIam';\n\nexport const BamEventListenerMap: {[key in BrazeIAMCustomEventAction]: BamEventListenerCallback } = {\n 'close': closeBamListener,\n 'resize-height': resizeHeightBamListener,\n 'open-link': openLinkBamListener\n};\n\n/**\n * Closes the BAM\n */\nfunction closeBamListener({ event, options: { iamContainer } }: BamEventListenerCallbackOptions) {\n if (!event.detail.action) return;\n\n if (event.detail.action !== 'close') return;\n\n iamContainer.classList.add('d-none');\n iamContainer.innerHTML = '';\n}\n\n/**\n * Responds to height resize from BAM\n */\nfunction resizeHeightBamListener({ event, options: { iamContainer } }: BamEventListenerCallbackOptions) {\n if (!event.detail.action) return;\n\n if (event.detail.action !== 'resize-height') return;\n\n const height = event.detail.payload;\n if (!height || typeof height !== 'number') return;\n \n iamContainer.style.height = `${height}px`;\n}\n\ninterface OpenLinkBamEventPayload {\n link: string;\n newTab: boolean;\n}\n\n/**\n * Opens the link in new tab by responding to the event\n */\nfunction openLinkBamListener({\n event\n}: BamEventListenerCallbackOptions<OpenLinkBamEventPayload>) {\n if (!event.detail.action)\n return;\n\n if (event.detail.action !== 'open-link')\n return;\n\n if (!(typeof event.detail.payload?.link === 'string' && event.detail.payload?.link.length))\n return;\n \n if (!isUrlValid(event.detail.payload.link))\n return;\n\n const target = event.detail.payload.newTab ? '_blank' : '_self';\n\n window.open(event.detail.payload.link, target);\n}\n\nconst validHostNames = [\n 'clickvieweducation.com',\n 'clickview.net'\n];\n\nfunction isUrlValid(input: string): boolean {\n try {\n const url = new URL(input);\n if (url.protocol !== 'http:' && url.protocol !== 'https:')\n return false;\n \n if (\n !validHostNames.find(host => url.host.includes(host)) &&\n (process.env.NODE_ENV === 'production' || !url.host.includes('localhost'))\n )\n return false;\n \n return true;\n } catch {\n console.warn('[BAM] Invalid link provided in \"open-link\" event.');\n return false;\n }\n}\n","import type { InAppMessage } from '@clickview/braze-client';\n\nimport { BrazeActions } from 'libs/shared/constants/BrazeActions';\nimport type { BrazeIAMCustomEvent, BrazeIamDetail, BrazeIamRegionSize, BrazeIamRegionType } from 'libs/shared/interfaces/braze/BrazeIam';\n\nimport { BamEventListenerMap } from 'shared/views/braze-iam-region/helpers/braze-iam-helper/BamEventListenerMap';\n\nexport const BrazeIamMap: {[key in BrazeIamRegionType]: BrazeIamDetail } = {\n 'bottom-right': {\n id: 'braze-iam-region-bottom-right',\n callback: iamBottomRightCallback\n }\n};\n\nconst brazeIamSizeMap: {[key in BrazeIamRegionSize]: string } = {\n base: 'iam-base',\n sm: 'iam-sm'\n};\n\ninterface BindBamEventListenersOptions {\n iamContainer: HTMLElement;\n}\n\nfunction bindBamEventListeners({ iamContainer }: BindBamEventListenersOptions) {\n document.addEventListener(BrazeActions.BAM, (e: BrazeIAMCustomEvent) => {\n if (!e.detail.action) return;\n\n const handleCallback = BamEventListenerMap[e.detail.action];\n \n if (typeof handleCallback !== 'function') return;\n\n handleCallback({\n event: e,\n options: {\n iamContainer: iamContainer\n }\n });\n }, false);\n}\n\nfunction iamBottomRightCallback(inAppMessage: InAppMessage): void {\n const iam = BrazeIamMap['bottom-right'];\n const iamContainer = document.getElementById(iam.id);\n const iamSize = inAppMessage?.extras?.size || 'base';\n\n iamContainer.classList.remove('d-none');\n Object.values(brazeIamSizeMap).forEach(\n size => iamContainer.classList.remove(size)\n );\n \n // iamSize could be anything passed from braze so we default to base if it doesnot exist\n const sizeClass = brazeIamSizeMap[iamSize as BrazeIamRegionSize] || brazeIamSizeMap['base'];\n iamContainer.classList.add(sizeClass);\n\n bindBamEventListeners({\n iamContainer\n });\n}\n","import type { InAppMessage } from '@clickview/braze-client';\n\nimport { BrazeIamRegionType } from 'libs/shared/interfaces/braze/BrazeIam';\nimport { BrazeClientService } from 'libs/shared/services/BrazeClientService';\n\nimport { BrazeIamMap } from './BrazeIamMap';\n\nexport const BrazeIamHelper = {\n showInAppMessage(client: BrazeClientService, inAppMessage: InAppMessage) {\n if (!client || !inAppMessage) return;\n \n const iamRegion = inAppMessage?.extras?.region;\n if (!iamRegion) {\n /**\n * Ideally we should still show the in app message if this doesnot exsit but\n * we dont want anyone with access to braze to accidentaly trigger IAMs to our users\n * - nish\n */\n // client.showInAppMessage(inAppMessage);\n return;\n }\n const iam = BrazeIamMap[iamRegion as BrazeIamRegionType];\n \n if (!iam) {\n // client.showInAppMessage(inAppMessage);\n return;\n }\n \n const containerElement = document.getElementById(iam.id);\n \n if (!containerElement) return;\n \n client.showInAppMessage(inAppMessage, containerElement, () => iam.callback(inAppMessage));\n }\n};\n","import React from 'react';\nimport type { InAppMessage } from '@clickview/braze-client';\n\nimport { UserAgentHelper } from 'libs/common/backbone/utils/UserAgentHelper';\nimport { useInstanceSafe } from 'libs/common/react/hooks/UseInstance';\n\nimport { SharedServiceChannels } from 'libs/shared/constants/RadioChannels';\nimport { SharedServices } from 'libs/shared/constants/SharedServices';\nimport { useListenOn } from 'libs/shared/hooks/UseListenOn';\nimport { BrazeClientService, BrazeNewIamEvent } from 'libs/shared/services/BrazeClientService';\n\nimport { usePluginHelper } from 'shared/hooks/use-plugin-helper/usePluginHelper';\nimport { BrazeIamHelper } from 'shared/views/braze-iam-region/helpers/braze-iam-helper';\n\nexport function BrazeIamRegion() {\n const { isPlugin } = usePluginHelper();\n const brazeClient = useInstanceSafe<BrazeClientService>(SharedServices.BrazeClient);\n\n const isReady = !isPlugin && brazeClient.isReady;\n\n function handleInAppMessages(inAppMessage: InAppMessage) {\n /**\n * IOS has issues with displaying BAM so we will\n * not show BAMs on mobile device until we can\n * come up with a proper fix or rework this implementation\n * - Nish\n */\n if (UserAgentHelper.isTabletOrMobile()) return;\n\n return BrazeIamHelper.showInAppMessage(brazeClient, inAppMessage);\n }\n\n /**\n * Handle any IAMs we retrieved during start up.\n */\n React.useEffect(() => {\n if (!isReady)\n return;\n\n brazeClient.handleInAppMessages(handleInAppMessages);\n }, [isReady]);\n\n /**\n * Register listener for any subsequent IAMs we receive after start up.\n */\n useListenOn(SharedServiceChannels.BRAZE, BrazeNewIamEvent, () => {\n if (!isReady) return;\n\n brazeClient.handleInAppMessages(handleInAppMessages);\n }, [isReady]);\n\n return (\n <div id='braze-iam-region-bottom-right' className='bam-container d-none'>\n </div>\n );\n}\n","import { useState } from 'react';\n\nimport { CommonChannels } from 'libs/common/backbone/constants/CommonChannels';\nimport { useInstanceSafe } from 'libs/common/react/hooks/UseInstance';\n\nimport { useListenOn } from 'libs/shared/hooks/UseListenOn';\n\nimport { Services } from 'shared/constants/Services';\nimport { CookieConsentService } from 'shared/services/CookieConsentService';\nimport { CookieConsentSettings } from 'shared/views/cookie-consent/constants/CookieConsentSettings';\nimport type { CookieConsentCategoryValues, CookieConsentStoreResult } from 'shared/views/cookie-consent/interfaces/CookieConsentData';\n\nexport function useCookieConsent() {\n const cookieConsentService = useInstanceSafe<CookieConsentService>(Services.CookieConsent);\n const [ consent, setConsent ] = useState<CookieConsentStoreResult | undefined>(\n cookieConsentService.getConsentData()\n );\n\n // Using listener to update the state so anywhere this is used gets updated\n useListenOn(CommonChannels.SHELL, CookieConsentSettings.EventName, (consent: CookieConsentStoreResult) => {\n setConsent(consent);\n });\n\n function onAccept(acceptedCategories: CookieConsentCategoryValues[]) {\n const acceptedConsent: CookieConsentStoreResult = Object.values(CookieConsentSettings.Categories)\n .reduce((prev, curr) => {\n let accepted = false;\n if (acceptedCategories.includes(curr)) {\n accepted = true;\n }\n prev[curr] = accepted;\n return prev;\n }, {} as CookieConsentStoreResult);\n\n cookieConsentService.setConsent(acceptedConsent); // Emits the event that we listen to\n }\n\n function onAcceptAll() {\n onAccept(Object.values(CookieConsentSettings.Categories));\n }\n\n return {\n isEnabled: cookieConsentService.isEnabled(),\n currentConsent: consent,\n setConsent: onAccept,\n acceptAll: onAcceptAll\n };\n}\n","import type { CookieConsentData } from 'shared/views/cookie-consent/interfaces/CookieConsentData';\n\n/**\n * @ref https://support.google.com/analytics/answer/11397207?hl=en\n */\nconst googleCompanyDetails = {\n name: 'Alphabet',\n url: 'https://policies.google.com/privacy'\n};\n\nconst googleAnalyticsCookies: CookieConsentData[] = [\n {\n type: 'third-party',\n category: 'analytics',\n duration: '2 years',\n name: '_ga',\n purpose: 'Used to distinguish users',\n company: googleCompanyDetails\n },\n {\n type: 'third-party',\n category: 'analytics',\n duration: '2 years',\n name: '_ga_<container-id>',\n purpose: 'Used to persist session state',\n company: googleCompanyDetails\n }\n];\n\n/**\n * @ref https://www.braze.com/docs/developer_guide/platform_integration_guides/web/cookies_and_storage/#list-of-cookies\n */\nconst brazeCompanyDetails = {\n name: 'Braze',\n url: 'https://www.braze.com/company/legal/privacy/'\n};\nconst brazeCookies: CookieConsentData[] = [\n {\n type: 'third-party',\n category: 'analytics',\n duration: '1 year',\n name: 'ab.storage.userId.[key]',\n purpose: 'Used to determine whether the currently logged-in user has changed and to associate events with the current user',\n company: brazeCompanyDetails\n },\n {\n type: 'third-party',\n category: 'analytics',\n duration: '1 year',\n name: 'ab.storage.sessionId.[key]',\n purpose: 'Randomly-generated string used to determine whether the user is starting a new or existing session to sync messages and calculate session analytics',\n company: brazeCompanyDetails\n },\n {\n type: 'third-party',\n category: 'analytics',\n duration: '1 year',\n name: 'ab.storage.deviceId.[key]',\n purpose: 'Randomly-generated string used to identify anonymous users, and to differentiate users’ devices and enables device-based messaging',\n company: brazeCompanyDetails\n },\n {\n type: 'third-party',\n category: 'analytics',\n duration: '1 year',\n name: 'ab.optOut',\n purpose: 'Used to store a user’s opt-out preference when disableSDK is called',\n company: brazeCompanyDetails\n },\n {\n type: 'third-party',\n category: 'analytics',\n duration: '-',\n name: 'ab._gd',\n purpose: 'Temporarily created (and then deleted) to determine the root-level cookie domain, which allows the SDK to work properly across sub-domains',\n company: brazeCompanyDetails\n }\n];\n\nconst cvCookies: CookieConsentData[] = [\n {\n type: 'first-party',\n category: 'essential',\n duration: 'Session',\n name: 'app',\n purpose: 'Cookie to authenticate user to ClickView'\n },\n {\n type: 'first-party',\n category: 'essential',\n duration: '1 week',\n name: 'AWSALBCORS',\n purpose: 'Provides load balancing functionality'\n },\n {\n type: 'first-party',\n category: 'essential',\n duration: '8 hours',\n name: '_dismissOpenInAppPrompt',\n purpose: 'Stores mobile open in app prompt state so use can browse the site normally'\n }\n];\n\nexport const cookiesData: CookieConsentData[] = [\n ...cvCookies,\n ...googleAnalyticsCookies,\n ...brazeCookies\n];\n","type ValidParams = string | boolean | undefined | null;\n\nexport const StringHelper = {\n cn(...classNames: Array<ValidParams>): string {\n if (!classNames.length) return '';\n\n const filteredClassNames = classNames.filter(className => !!className);\n \n if (!filteredClassNames.length) return '';\n \n return filteredClassNames.join(' ');\n }\n};\n",":local {\n .cookie {\n width: 16px;\n height: 16px;\n }\n\n .tableBody {\n font-size: 0.75rem;\n }\n}","import React from 'react';\n\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { MediaQueryStrings } from 'libs/shared/enums/MediaQueries';\nimport { useMediaQuery } from 'libs/shared/hooks/UseMediaQuery';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { CookieConsentSettings } from 'shared/views/cookie-consent/constants/CookieConsentSettings';\nimport { cookiesData } from 'shared/views/cookie-consent/data/cookies-data';\nimport { StringHelper } from 'shared/views/cookie-consent/helpers/StringHelper';\nimport type { CookieConsentCategoryValues, CookieConsentData, CookieConsentDataType } from 'shared/views/cookie-consent/interfaces/CookieConsentData';\n\nimport styles from './category-info.module.scss';\n\ntype ValidDisplayKeys = keyof Pick<CookieConsentData, 'name' | 'duration' | 'purpose' | 'type'>;\n\nconst categoryTitlePhraseMap: {[key in CookieConsentCategoryValues]: string } = {\n [CookieConsentSettings.Categories.Essential]: 'essentialTitle',\n [CookieConsentSettings.Categories.Analytics]: 'analyticsTitle',\n [CookieConsentSettings.Categories.Functional]: 'functionalTitle',\n [CookieConsentSettings.Categories.Other]: 'otherTitle'\n};\n\nconst categoryDescriptionPhraseMap: {[key in CookieConsentCategoryValues]: string } = {\n [CookieConsentSettings.Categories.Essential]: 'essentialDescription',\n [CookieConsentSettings.Categories.Analytics]: 'analyticsDescription',\n [CookieConsentSettings.Categories.Functional]: 'functionalDescription',\n [CookieConsentSettings.Categories.Other]: 'otherDescription'\n};\n\nconst cookieDetailTitlePhraseMap: {[key in ValidDisplayKeys]: string } = {\n name: 'thName',\n duration: 'thDuration',\n purpose: 'thPurpose',\n type: 'thType'\n};\n\nconst cookieTypePhraseMap: {[key in CookieConsentDataType]: string } = {\n 'first-party': 'firstParty',\n 'third-party': 'thirdParty'\n};\n\ninterface CategoryInfoProps {\n category: CookieConsentCategoryValues;\n}\n\nconst namespace = 'cookieConsent.categoryInfo';\n\nfunction CategoryTitle({ category }: CategoryInfoProps): JSX.Element {\n return <Text namespace={namespace} phrase={categoryTitlePhraseMap[category]} />;\n}\n\nfunction CategoryDescription({ category }: CategoryInfoProps): JSX.Element {\n return <Text namespace={namespace} phrase={categoryDescriptionPhraseMap[category]} />;\n}\n\nfunction CategoryCookiesList({ category }: CategoryInfoProps): JSX.Element {\n const smallScreen = useMediaQuery(MediaQueryStrings.SMDown);\n \n const tableData = cookiesData.filter(cookie => cookie.category === category);\n \n if (!tableData.length) return <></>;\n\n return (\n <div className='rounded overflow-hidden border border-dark my-3'>\n <table className='table table-responsive table-borderless m-0'>\n <CookieListTableHead isSmallScreen={smallScreen} />\n <CookieListTableData data={tableData} isSmallScreen={smallScreen} />\n </table>\n </div>\n );\n}\n\ninterface HasSmallerScreen {\n isSmallScreen: boolean;\n}\n\nfunction CookieListTableHead({ isSmallScreen }: HasSmallerScreen) {\n if (isSmallScreen) {\n return (\n <thead className='table-dark'>\n <tr className='d-table-row d-md-none'>\n <th className='fw-semibold d-flex flex-row justify-content-start align-items-center' colSpan={2}>\n <img src={ImageUrls.CookieConsent.CookieIcon} className={styles.cookie}/>\n <span className='ps-1'>\n <Text namespace={namespace} phrase='thCookie' />\n </span>\n </th>\n </tr>\n </thead>\n );\n }\n \n return (\n <thead className='table-dark'>\n <tr>\n <th className='fw-semibold d-flex flex-row align-items-center'>\n <img src={ImageUrls.CookieConsent.CookieIcon} className={styles.cookie}/>\n <span className='ps-1'>\n <Text namespace={namespace} phrase='thCookie' />\n </span>\n </th>\n <th className='fw-semibold'>\n <Text namespace={namespace} phrase='thType' />\n </th>\n <th className='fw-semibold'>\n <Text namespace={namespace} phrase='thDuration' />\n </th>\n <th className='fw-semibold'>\n <Text namespace={namespace} phrase='thPurpose' />\n </th>\n </tr>\n </thead>\n );\n}\n\ninterface CookieListTableData extends HasSmallerScreen {\n data: CookieConsentData[];\n}\n\nfunction CookieListTableData({ data, isSmallScreen }: CookieListTableData) {\n if (isSmallScreen) {\n return (\n <tbody className={StringHelper.cn('d-block d-md-none', styles.tableBody)}>\n {data.map((cookie, index) => {\n return (\n <CookieListTableDataRow data={cookie} key={cookie.name + index} />\n );\n })}\n </tbody>\n );\n }\n \n return (\n <tbody className={styles.tableBody}>\n {data.map((cookie, index) => {\n return (\n <tr key={cookie.name} className={StringHelper.cn(\n index !== data.length - 1 && 'border-bottom border-dark'\n )}>\n <td>{cookie.name}</td>\n <td><Text namespace={namespace} phrase={cookieTypePhraseMap[cookie.type]} /></td>\n <td>{cookie.duration}</td>\n <td>{cookie.purpose}</td>\n </tr>\n );\n })}\n </tbody>\n );\n}\n\nconst orderedDisplayKeys: ValidDisplayKeys[] = [ 'name', 'type', 'duration', 'purpose' ];\n\nfunction CookieListTableDataRow({ data }: { data: CookieConsentData }): JSX.Element {\n const filteredData = ObjectHelper.pick(data, orderedDisplayKeys);\n const mapableData = Object.keys(filteredData);\n return (\n <>\n {mapableData.map((item, index) => {\n const value = filteredData[item as ValidDisplayKeys];\n const isLastItem = index === mapableData.length - 1;\n\n if (!value) return;\n\n return (\n <tr\n key={`${index}-${item}`}\n className={StringHelper.cn(\n isLastItem && 'border-bottom border-dark'\n )}>\n <td><Text namespace={namespace} phrase={cookieDetailTitlePhraseMap[item as ValidDisplayKeys]} /></td>\n <td>{value}</td>\n </tr>\n );\n })}\n </>\n );\n}\n\nexport const CategoryInfo = {\n Title: CategoryTitle,\n Description: CategoryDescription,\n CookiesList: CategoryCookiesList\n};\n","import { cookiesData } from 'shared/views/cookie-consent/data/cookies-data';\nimport type { CookieConsentCategoryValues } from 'shared/views/cookie-consent/interfaces/CookieConsentData';\n\nexport const ConsentHelper = {\n canBeToggled(category: CookieConsentCategoryValues): boolean {\n return category !== 'essential';\n },\n\n hasCookies(category: CookieConsentCategoryValues): boolean {\n return !!cookiesData.filter(cookie => cookie.category === category).length;\n }\n};\n","import React from 'react';\n\nimport { IconButton } from 'libs/shared/components/icon-button/IconButton';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { ToggleSwitch } from 'libs/shared/components/toggle-switch/ToggleSwitch';\nimport { ChevronLeftSvg } from 'libs/shared/images/svg/arrows/ChevronLeftSvg';\n\nimport { CategoryInfo } from 'shared/views/cookie-consent/components/category-info/CategoryInfo';\nimport { ConsentHelper } from 'shared/views/cookie-consent/helpers/ConsentHelper';\nimport { StringHelper } from 'shared/views/cookie-consent/helpers/StringHelper';\nimport type { CookieConsentCategoryValues } from 'shared/views/cookie-consent/interfaces/CookieConsentData';\n\ninterface CookieConsentCategoryDetailProps {\n category: CookieConsentCategoryValues;\n toggled: boolean;\n toggle: () => void;\n back: () => void;\n\n className?: string;\n}\n\nconst namespace = 'cookieConsent.categoryDetail';\n\nconst { cn } = StringHelper;\n\nexport function CookieConsentCategoryDetail({\n category,\n back,\n toggle,\n toggled,\n className\n}: CookieConsentCategoryDetailProps): JSX.Element {\n const enabled = ConsentHelper.canBeToggled(category);\n \n return (\n <div className={cn(className)}>\n <div className='d-flex flex-row justify-content-between align-items-center'>\n <div className='d-flex flex-row justify-content-between align-items-center'>\n <IconButton svg={ChevronLeftSvg} className='btn btn-sm' onClick={back} />\n <span className='fw-semibold ps-2'>\n <CategoryInfo.Title category={category} />\n </span>\n </div>\n {enabled ?\n <ToggleSwitch on={toggled} onClick={toggle} /> :\n <span className='fw-semibold'>\n <Text namespace={namespace} phrase='alwaysActive' />\n </span>\n }\n </div>\n <div>\n <CategoryInfo.Description category={category} />\n <CategoryInfo.CookiesList category={category} />\n </div>\n </div>\n );\n}\n",":local {\n .accordion {\n >* {\n border: 1px solid $gray-900;\n border-bottom: 0;\n }\n\n >*:last-child {\n border-bottom: 1px solid $gray-900;\n border-radius: 0 0 3px 3px;\n }\n\n >*:first-child {\n border-radius: 3px 3px 0 0;\n }\n }\n}","import React, { useContext } from 'react';\nimport { Accordion } from 'react-bootstrap';\nimport { useAccordionButton } from 'react-bootstrap/AccordionButton';\nimport AccordionContext from 'react-bootstrap/AccordionContext';\n\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { ToggleSwitch } from 'libs/shared/components/toggle-switch/ToggleSwitch';\nimport { MinusSvg } from 'libs/shared/images/svg/actions/MinusSvg';\nimport { PlusSvg } from 'libs/shared/images/svg/actions/PlusSvg';\n\nimport { CategoryInfo } from 'shared/views/cookie-consent/components/category-info/CategoryInfo';\nimport { CookieConsentSettings } from 'shared/views/cookie-consent/constants/CookieConsentSettings';\nimport { ConsentHelper } from 'shared/views/cookie-consent/helpers/ConsentHelper';\nimport { StringHelper } from 'shared/views/cookie-consent/helpers/StringHelper';\nimport type { CookieConsentCategoryValues } from 'shared/views/cookie-consent/interfaces/CookieConsentData';\n\nimport styles from './cookie-consent-manage-preferences.module.scss';\n\nconst namespace = 'cookieConsent.managePreferences';\n\nconst { cn } = StringHelper;\n\ninterface CookieConsentManagePreferencesProps {\n selectedCategories: CookieConsentCategoryValues[];\n toggleSelectedCategory: (category: CookieConsentCategoryValues) => void;\n showCategory: (category: CookieConsentCategoryValues) => void;\n}\n\nexport function CookieConsentManagePreferences({\n selectedCategories,\n toggleSelectedCategory,\n showCategory\n}: CookieConsentManagePreferencesProps): JSX.Element {\n return (\n <div>\n <h6><Text namespace={namespace} phrase='title' /></h6>\n <Accordion className={styles.accordion}>\n {Object.values(CookieConsentSettings.Categories).map(item => {\n const toggled = selectedCategories?.includes(item) || false;\n \n return (\n <ManagePreferencesItem\n key={item}\n item={item}\n toggled={toggled}\n showCategory={showCategory}\n onToggle={() => toggleSelectedCategory(item)}\n />\n );\n })\n }\n </Accordion>\n </div>\n );\n}\n\ninterface ManagePreferencesItemProps {\n item: CookieConsentCategoryValues;\n toggled: boolean;\n onToggle: () => void;\n showCategory: (category: CookieConsentCategoryValues) => void;\n}\n\nfunction ManagePreferencesItem({\n item, toggled, onToggle, showCategory\n}: ManagePreferencesItemProps): JSX.Element {\n const hasCookies = ConsentHelper.hasCookies(item);\n return (\n <div>\n <ManagePreferenceAccordionButton item={item} toggled={toggled} onToggle={onToggle} />\n <Accordion.Collapse eventKey={item}>\n <div className='px-3 py-2 d-flex flex-column justify-content-between'>\n <CategoryInfo.Description category={item} />\n {hasCookies &&\n <div className='mt-2'>\n <DivButton onClick={() => showCategory(item)} className='text-decoration-underline'>\n <Text namespace={namespace} phrase='details' />\n </DivButton>\n </div>\n }\n </div>\n </Accordion.Collapse>\n </div>\n );\n}\n\ninterface ManagePreferenceAccordionButtonProps {\n item: CookieConsentCategoryValues;\n toggled: boolean;\n onToggle: () => void;\n}\n\nfunction ManagePreferenceAccordionButton({\n item,\n toggled,\n onToggle\n}: React.PropsWithChildren<ManagePreferenceAccordionButtonProps>): JSX.Element {\n const { activeEventKey } = useContext(AccordionContext);\n const onClick = useAccordionButton(item);\n\n function handleOnToggle(e: React.ChangeEvent) {\n e.stopPropagation();\n onToggle();\n }\n\n const isCurrentActive = activeEventKey && activeEventKey.includes(item);\n\n const enabled = ConsentHelper.canBeToggled(item);\n \n return (\n <DivButton\n onClick={onClick}\n className='d-flex flex-row p-2 justify-content-between w-100'\n >\n <div>\n {isCurrentActive ?\n <SvgContainer svg={MinusSvg} size={SvgContainerSize.Small} /> :\n <SvgContainer svg={PlusSvg} size={SvgContainerSize.Small} />\n }\n <span className={cn('ps-2', !enabled && 'fw-semibold')}>\n <CategoryInfo.Title category={item} />\n </span>\n </div>\n {enabled ?\n <ToggleSwitch on={!!toggled} onClick={handleOnToggle} /> :\n <span className='fw-semibold'><Text namespace={namespace} phrase='alwaysActive' /></span>\n }\n </DivButton>\n );\n}\n",":local {\n .logo {\n max-width: 36px;\n }\n\n .dialog {\n max-width: 600px;\n }\n\n .title {\n >* {\n margin: 0\n }\n }\n}","import React, { useState } from 'react';\nimport { Modal } from 'react-bootstrap';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\n\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { ExternalLink } from 'libs/shared/components/external-link/ExternalLink';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { MediaQueryStrings } from 'libs/shared/enums/MediaQueries';\nimport { useMediaQuery } from 'libs/shared/hooks/UseMediaQuery';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { CookieConsentCategoryDetail } from 'shared/views/cookie-consent/components/cookie-consent-category-details/CookieConsentCategoryDetail';\nimport { CookieConsentManagePreferences } from 'shared/views/cookie-consent/components/cookie-consent-manage-preferences/CookieConsentManagePreferences';\nimport { ConsentHelper } from 'shared/views/cookie-consent/helpers/ConsentHelper';\nimport { StringHelper } from 'shared/views/cookie-consent/helpers/StringHelper';\nimport type { CookieConsentCategoryValues } from 'shared/views/cookie-consent/interfaces/CookieConsentData';\n\nimport styles from './cookie-consent-manage-popup.module.scss';\n\nconst namespace = 'cookieConsent.managePopup';\nconst { cn } = StringHelper;\n\ninterface CookieConsentManagePopupProps {\n privacyPolicyUrl: string;\n show: boolean;\n onHide: () => void;\n acceptAll: () => void;\n setConsent: (category: CookieConsentCategoryValues[]) => void;\n}\n\nexport function CookieConsentManagePopup({\n show,\n privacyPolicyUrl,\n onHide,\n acceptAll,\n setConsent\n}: CookieConsentManagePopupProps): JSX.Element {\n const [ selectedCategories, setSelectedCategories ] = useState<CookieConsentCategoryValues[]>(['essential']);\n const [ showCategory, setShowCategory ] = useState<CookieConsentCategoryValues>();\n const scrollContainerRef = React.createRef<Scrollbars>();\n const isSmallScreen = useMediaQuery(MediaQueryStrings.SMDown);\n\n const bodyHeight = isSmallScreen ? '83.5%' : '430px';\n\n function toggleSelectedCategory(category: CookieConsentCategoryValues) {\n if (!ConsentHelper.canBeToggled(category)) return;\n\n if (!selectedCategories.includes(category)) {\n setSelectedCategories([ ...selectedCategories, category ]);\n return;\n }\n\n setSelectedCategories(selectedCategories.filter(item => item !== category));\n }\n\n function saveSelectedCategory() {\n setConsent(selectedCategories);\n }\n\n function back() {\n scrollContainerRef.current?.scrollToTop();\n setShowCategory(undefined);\n }\n\n function handleShowCategory(category: CookieConsentCategoryValues) {\n scrollContainerRef.current?.scrollToTop();\n setShowCategory(category);\n }\n\n if (!show) return <></>;\n \n return (\n <Modal\n show\n backdrop='static'\n onHide={onHide}\n fullscreen='sm-down'\n dialogClassName={styles.dialog}\n >\n <Modal.Header className='py-2' closeButton>\n <Modal.Title>\n <ManageTitle />\n </Modal.Title>\n </Modal.Header>\n <Scrollbars\n style={{\n height: bodyHeight\n }}\n ref={scrollContainerRef}\n >\n <Modal.Body>\n <ManageBodyContent\n showCategory={showCategory}\n privacyPolicyUrl={privacyPolicyUrl}\n selectedCategories={selectedCategories}\n back={back}\n handleShowCategory={handleShowCategory}\n toggleSelectedCategory={toggleSelectedCategory}\n />\n </Modal.Body>\n </Scrollbars>\n <Modal.Footer>\n <ManageFooter acceptAll={acceptAll} saveSelectedCategory={saveSelectedCategory} />\n </Modal.Footer>\n </Modal>\n );\n}\n\nfunction ManageTitle(): JSX.Element {\n return (\n <div className='d-flex flex-row align-items-center'>\n <img src={ImageUrls.CookieConsent.Logo} className={cn('me-2', styles.logo)} />\n <Text namespace={namespace} phrase='title'/>\n </div>\n );\n}\n\ninterface ManageBodyContentProps {\n selectedCategories: CookieConsentCategoryValues[];\n showCategory?: CookieConsentCategoryValues;\n privacyPolicyUrl: string;\n back: () => void;\n handleShowCategory: (category: CookieConsentCategoryValues) => void;\n toggleSelectedCategory: (category: CookieConsentCategoryValues) => void;\n}\n\nfunction ManageBodyContent({\n showCategory,\n selectedCategories,\n privacyPolicyUrl,\n back,\n handleShowCategory,\n toggleSelectedCategory\n}: ManageBodyContentProps): JSX.Element {\n if (!showCategory) {\n return (\n <>\n <ManageBodyDescription privacyPolicyUrl={privacyPolicyUrl} />\n <CookieConsentManagePreferences\n selectedCategories={selectedCategories}\n showCategory={handleShowCategory}\n toggleSelectedCategory={toggleSelectedCategory}\n />\n </>\n );\n }\n \n return (\n <CookieConsentCategoryDetail\n category={showCategory}\n back={back}\n toggled={selectedCategories.includes(showCategory)}\n toggle={() => toggleSelectedCategory(showCategory)}\n />\n );\n}\n\ninterface ManageBodyDescriptionProps {\n privacyPolicyUrl: string;\n}\n\nfunction ManageBodyDescription({ privacyPolicyUrl }: ManageBodyDescriptionProps): JSX.Element {\n return (\n <>\n <p><Text namespace={namespace} phrase='intro' /></p>\n <p>\n <Text namespace={namespace} phrase='reason' />\n <ExternalLink\n className='text-decoration-underline'\n href={privacyPolicyUrl}\n newTab\n >\n <Text namespace={namespace} phrase='privacyPolicy' />\n </ExternalLink>\n .\n </p>\n </>\n );\n}\n\ninterface ManageFooterProps {\n saveSelectedCategory: () => void;\n acceptAll: () => void;\n}\n\nfunction ManageFooter({ saveSelectedCategory, acceptAll }: ManageFooterProps): JSX.Element {\n return (\n <>\n <DivButton onClick={saveSelectedCategory} className='btn btn-outline-dark fw-semibold'>\n <Text namespace={namespace} phrase='btnConfirmChoices' />\n </DivButton>\n <DivButton onClick={acceptAll} className='btn btn-dark fw-semibold'>\n <Text namespace={namespace} phrase='btnAllowAll' />\n </DivButton>\n </>\n );\n}\n",":local {\n .dialog {\n min-height: 110px;\n\n transition: opacity .3s;\n }\n\n .cookieImg {\n max-width: 35px;\n\n @media screen and (min-width: #{map-get($grid-breakpoints, md)}) {\n max-width: 65px;\n }\n }\n\n .body {\n background: $gray-900;\n }\n\n .buttons {\n width: 100%;\n\n >div {\n width: 100%;\n }\n\n @media screen and (min-width: #{map-get($grid-breakpoints, md)}) {\n width: auto;\n\n >div {\n width: auto;\n }\n }\n }\n\n}","import React, { useState } from 'react';\nimport { Offcanvas } from 'react-bootstrap';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { UrlHelper } from 'libs/analytics/utils/UrlHelper';\n\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { ExternalLink } from 'libs/shared/components/external-link/ExternalLink';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Config } from 'libs/shared/interfaces';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { useCookieConsent } from 'shared/hooks/useCookieConsent';\nimport { CookieConsentManagePopup } from 'shared/views/cookie-consent/components/cookie-consent-manage-popup/CookieConsentManagePopup';\nimport { StringHelper } from 'shared/views/cookie-consent/helpers/StringHelper';\nimport type { CookieConsentCategoryValues } from 'shared/views/cookie-consent/interfaces/CookieConsentData';\n\nimport styles from './cookie-consent-banner.module.scss';\n\nconst namespace = 'cookieConsent.banner';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\nconst { cn } = StringHelper;\n\ninterface CookieConsentBannerProps {\n enabled: boolean;\n config: Config;\n description?: string;\n}\n\n/**\n * We set custom backdrop and we hide the default backdrop through css on `theme-overrides.css`\n * because there is a issue where even if we set the backdrop to false on Offcanvas still\n * renders the backdrop. So we hide all offcanvas backdrop unless it has the custom `cv-custom-backdrop` classname.\n * This behaviour is random as far as I have tested and shows up randomly while refreshing when the banner is displayed.\n * \n * - Nish\n */\nexport function CookieConsentBanner({\n description = getPhrase('description'),\n config,\n enabled\n}: CookieConsentBannerProps): JSX.Element {\n const {\n isEnabled,\n currentConsent,\n setConsent,\n acceptAll\n } = useCookieConsent();\n\n const [ show, setShow ] = useState(isEnabled);\n const [ showBackdrop, setShowBackdrop ] = useState(true);\n const [ showManagePopup, setShowManagePopup ] = useState(false);\n\n const privacyPolicyUrl = UrlHelper.safeUrlConcat(config.marketingSiteUrl, '/privacy-policy');\n\n /**\n * This is a quick fix to make sure we are able to scroll the body.\n * We will need to revisit this to find the root cause of the issue.\n * - Nish\n */\n function ensureBodyIsScrollable() {\n document.body.style.overflow = 'auto';\n document.body.style.overflowY = 'auto';\n }\n\n function removeBackdrop() {\n setShowBackdrop(false);\n ensureBodyIsScrollable();\n }\n\n function handleAcceptAll() {\n ensureBodyIsScrollable();\n acceptAll();\n setShowBackdrop(false);\n setShow(false);\n }\n\n function handleSetConsent(acceptedCategories: CookieConsentCategoryValues[]) {\n ensureBodyIsScrollable();\n setConsent(acceptedCategories);\n setShowBackdrop(false);\n setShow(false);\n }\n\n const showConsentBanner = enabled && !currentConsent && show;\n \n if (!showConsentBanner) return <></>;\n \n return (\n <>\n <div\n className={cn(\n 'fade offcanvas-backdrop cv-custom-backdrop', // really hacky way to resolve the random duplicate backdrop issue\n showBackdrop ? 'show' : 'hide d-none'\n )}\n onClick={removeBackdrop}\n />\n <Offcanvas\n className={cn(\n 'bg-transparent h-auto border-0',\n styles.dialog\n )}\n show\n placement='bottom'\n backdrop={false} // setting this to false has mixed result and renders backdrop sometimes\n scroll={true}\n keyboard={false}\n onHide={false}\n >\n <Offcanvas.Body className={cn(\n 'd-flex flex-column justify-content-center align-items-center rounded-top gap-2 text-white',\n 'flex-lg-row',\n styles.body\n )}>\n <div className={cn(\n 'd-flex flex-row justify-content-center align-items-start gap-2',\n 'align-items-md-center'\n )}>\n <img src={ImageUrls.CookieConsent.Cookie} className={styles.cookieImg} />\n <p className='mb-0 text-sm'>\n {description} &nbsp;\n <ExternalLink href={`${privacyPolicyUrl}#cookies`} className='text-decoration-underline text-white' newTab>\n <Text namespace={namespace} phrase='learnMore' />\n </ExternalLink>\n </p>\n </div>\n <div className={cn(\n 'd-flex flex-column justify-content-center align-items-center gap-2',\n 'flex-md-row',\n styles.buttons\n )}>\n <DivButton onClick={() => setShowManagePopup(true)} className={cn(\n 'btn btn-outline text-white border fw-semibold'\n )}>\n <Text namespace={namespace} phrase='btnManage' />\n </DivButton>\n <DivButton onClick={handleAcceptAll} className='btn btn-outline-dark fw-semibold'>\n <Text namespace={namespace} phrase='btnAccept' />\n </DivButton>\n </div>\n </Offcanvas.Body>\n </Offcanvas>\n <CookieConsentManagePopup\n show={showManagePopup}\n privacyPolicyUrl={privacyPolicyUrl}\n onHide={() => setShowManagePopup(false)}\n acceptAll={handleAcceptAll}\n setConsent={handleSetConsent}\n />\n </>\n );\n}\n","import React from 'react';\n\nimport { AppLink, AppLinkHelper } from 'libs/common/backbone/core';\nimport { useInstanceSafe } from 'libs/common/react/hooks/UseInstance';\nimport { Flight } from 'libs/common/react/index';\n\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { Config } from 'libs/shared/interfaces';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { Services } from 'shared/constants/Services';\nimport { CookieConsentService } from 'shared/services/CookieConsentService';\nimport { SeoHelper } from 'shared/utils/SeoHelper';\n\nimport { CookieConsentBanner } from './components/cookie-consent-banner/CookieConsentBanner';\n\nconst hideForAppLinks: AppLink[] = [\n // presentation popup\n {\n action: Actions.Default.SELECT_PUBLIC_PRESENTATION,\n application: AppChannels.DEFAULT\n },\n // link share view\n {\n action: Actions.Share.VIEW_SHARE_LINK,\n application: AppChannels.SHARE\n }\n];\n\nfunction disabledForAppLink(appLink: AppLink): boolean {\n return !!hideForAppLinks.find(item => (\n item.action === appLink.action && item.application === appLink.application\n ));\n}\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function CookieConsentView(): JSX.Element {\n const currentAppLink = AppLinkHelper.getCurrentAppLink();\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n\n const cookieConsent = useInstanceSafe<CookieConsentService>(Services.CookieConsent);\n const enableCookieConsent = !disabledForAppLink(currentAppLink) && !SeoHelper.isBot() && cookieConsent.isEnabled();\n\n if (!config.data) return <></>;\n\n return (\n <CookieConsentBanner enabled={enableCookieConsent} config={config.data} />\n );\n}\n","import React from 'react';\n\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\n\nimport { AnalyticsOptions, ClickDescriptor, EntityType, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { ExternalLink } from 'libs/shared/components/external-link/ExternalLink';\nimport { InstanceRegion } from 'libs/shared/enums/InstanceRegion';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { Config } from 'libs/shared/interfaces';\n\ninterface FooterUrls {\n privacyPolicyUrl: string;\n termsAndConditionsUrl: string;\n contactUsUrl: string;\n}\n\nconst newWebsiteUrls: FooterUrls = {\n privacyPolicyUrl: '/legal/privacy-policy',\n contactUsUrl: '/contact-us',\n termsAndConditionsUrl: '/legal/terms-and-conditions'\n};\n\nconst oldWebsiteUrls: FooterUrls = {\n contactUsUrl: '/contact-us',\n privacyPolicyUrl: '/privacy-policy',\n termsAndConditionsUrl: '/terms-and-conditions'\n};\n\nconst instanceUrlMap: {[key in string]: FooterUrls } = {\n [InstanceRegion.AU]: newWebsiteUrls,\n [InstanceRegion.US]: newWebsiteUrls,\n [InstanceRegion.UK]: newWebsiteUrls,\n // @todo need to update this if we ever migrate to new website\n [InstanceRegion.NZ]: oldWebsiteUrls\n};\n\nfunction buildUrls(baseUrl: string, instanceRegion: string) {\n const urls = instanceUrlMap[instanceRegion] || newWebsiteUrls;\n \n return {\n privacyPolicyUrl: UrlHelper.safeUrlConcat(baseUrl, urls.privacyPolicyUrl),\n termsAndConditionsUrl: UrlHelper.safeUrlConcat(baseUrl, urls.termsAndConditionsUrl),\n contactUsUrl: UrlHelper.safeUrlConcat(baseUrl, urls.contactUsUrl)\n };\n}\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function FooterView(): React.ReactElement {\n const version = Flight.useBasicFetch<string>(ConfigRequests.version());\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n\n if (!version.data || !config.hasCompleted)\n return <></>;\n\n const urls = buildUrls(config.data.marketingSiteUrl, config.data.instanceRegion);\n\n const analyticsOptions: AnalyticsOptions = {\n actionType: UserAction.Click,\n entity: EntityType.AppLink,\n descriptor: ClickDescriptor.ExternalLink,\n location: LocationContext.Footer\n };\n\n return (\n <footer className='text-secondary my-2 px-3 small'>\n <ul className='d-flex flex-wrap list-unstyled justify-content-center mb-0'>\n <li>2003 - {(new Date()).getFullYear()} © ClickView</li>\n &nbsp;|&nbsp;\n <li>\n <ExternalLink\n className='text-secondary'\n href={urls.privacyPolicyUrl}\n analyticsData={{ url: urls.privacyPolicyUrl }}\n analyticsOptions={analyticsOptions}\n newTab\n >\n Privacy Policy\n </ExternalLink>\n </li>\n &nbsp;|&nbsp;\n <li>\n <ExternalLink\n className='text-secondary'\n href={urls.termsAndConditionsUrl}\n analyticsData={{ url: urls.termsAndConditionsUrl }}\n analyticsOptions={analyticsOptions}\n newTab\n >\n Terms and Conditions\n </ExternalLink>\n </li>\n &nbsp;|&nbsp;\n <li>\n <ExternalLink\n className='text-secondary'\n href={urls.contactUsUrl}\n analyticsData={{ url: urls.contactUsUrl }}\n analyticsOptions={analyticsOptions}\n newTab\n >\n Contact Us\n </ExternalLink>\n </li>\n &nbsp;|&nbsp;\n <li>Version: {version.data}</li>\n </ul>\n </footer>\n );\n}\n","$animation-duration: 400ms;\n$buttons-width: 3.4rem;\n\n:local {\n .theatreBackground {\n // Duplicated in lite-player.scss\n padding: 0 !important;\n height: 100%;\n max-height: min(80vh, 56.25vw);\n }\n\n .globalPlayer {\n width: 25rem;\n\n :global {\n @keyframes fadeInTop {\n from {\n opacity: 0;\n transform: translateY(-30%);\n }\n \n to {\n opacity: 1;\n transform: none;\n }\n }\n\n .global-player-enter-active,\n .global-player-enter-done {\n display: block !important;\n animation-name: fadeInTop;\n animation-duration: $animation-duration;\n }\n }\n }\n\n .closeSvg {\n width: 2.1875rem;\n height: 2.1875rem;\n display: inline-block;\n }\n\n .buttons {\n /**\n * Prevents the child buttons cascading vertically because \n * of the flex-shrink-1 class\n */\n min-width: $buttons-width;\n }\n\n .title {\n max-width: calc(100% - #{$buttons-width});\n }\n\n .flippedIcon {\n transform: scaleX(-1);\n }\n}","import * as React from 'react';\nimport { InPortal, OutPortal } from 'react-reverse-portal';\nimport { CSSTransition } from 'react-transition-group';\n\nimport { Core } from 'libs/common/core';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { ClickDescriptor, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { VideoSubText } from 'libs/shared/components/video-sub-text/VideoSubText';\nimport { PlayerContextValues, usePlayerContext } from 'libs/shared/context/player-context/PlayerContext';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { useForceUpdate } from 'libs/shared/hooks/useForceUpdate';\nimport { HasProductFunc, useProducts } from 'libs/shared/hooks/UseProducts';\nimport { useSettings } from 'libs/shared/hooks/useSettings';\nimport { CloseSvg } from 'libs/shared/images/svg/actions/CloseSvg';\nimport { NewWindowSvg } from 'libs/shared/images/svg/actions/NewWindowSvg';\nimport { UnionShareObject, VideoTypes } from 'libs/shared/interfaces';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { VideoAppLinkHelper } from 'shared/utils/VideoAppLinkHelper';\nimport { LitePlayerView } from 'shared/views/lite-player/LitePlayerView';\nimport { useGetPlayerData } from 'shared/views/lite-player/LitePlayerViewHooks';\n\nimport { SeriesAppLinkHelper } from 'apps/series/SeriesAppLinkHelper';\n\nimport styles from './global-player.module.scss';\n\nfunction getVideoAppLink(\n video: VideoTypes,\n shareLink: UnionShareObject,\n context: PlayerContextValues,\n isAuthenticated: boolean,\n presentationSlug: string | null\n): Core.AppLink {\n if (shareLink && context.shareId === shareLink?.id) {\n return {\n application: AppChannels.SHARE,\n action: Actions.Share.VIEW_SHARE_LINK,\n args: [context.shareId]\n };\n }\n\n return VideoAppLinkHelper.getAppLink(video, {\n context: context.context,\n contextId: context.contextId,\n shareId: context.shareId,\n playNext: context.playNext,\n moviesAndTv: context.moviesAndTv,\n includeContext: isAuthenticated\n }, presentationSlug);\n}\n\ninterface GlobalPlayerViewProps {\n presentationSlug: string | null;\n}\n\ninterface GlobalPlayerTitleProps {\n video: VideoTypes;\n appLink: Core.AppLink;\n hasProduct: HasProductFunc;\n onClickTitle: () => void;\n presentationSlug: string | null;\n}\n\nfunction GlobalPlayerTitle(props: GlobalPlayerTitleProps): JSX.Element {\n const { video, hasProduct, appLink, onClickTitle, presentationSlug } = props;\n\n return (\n <h2 className={`mb-0 h6 w-100 ${styles.title}`}>\n {VideoHelper.isVideo(video) && (\n <VideoSubText\n type='series'\n className='d-block'\n video={video}\n appLink={\n hasProduct(ProductId.Primary) &&\n SeriesAppLinkHelper.getSeriesAppLink(video.series, {}, presentationSlug)\n }\n analyticsOptions={{ location: LocationContext.FloatingPlayer }}\n />\n )}\n <AppLink appLink={appLink} onClick={onClickTitle}>\n {video.name}\n </AppLink>\n </h2>\n );\n}\n\n/**\n * <LitePlayerView /> is rendered from <GlobalPlayerView /> and not <PlayPage />\n * as <GlobalPlayerView /> is always in the DOM (as it's rendered in the layout).\n * <PlayPage /> is removed whenever the content changes.\n * If we rendered <LitePlayerView /> from <PlayPage />, the player would\n * be re-initialized every time the user navigates to the play page.\n */\n// eslint-disable-next-line rulesdir/require-view-title\nexport function GlobalPlayerView(props: GlobalPlayerViewProps): React.ReactElement {\n const playerContext = usePlayerContext();\n\n const { hasProduct } = useProducts();\n\n const { hasPlayPageTranscript } = useSettings(null);\n\n const {\n config, currentUser, video, shareLink, pointsOfInterest, viewKey, relatedVideos, playerIntegrations, hasCompleted\n } = useGetPlayerData({\n objectId: playerContext.objectId,\n objectTypeId: playerContext.objectTypeId,\n shareId: playerContext.shareId,\n context: playerContext.context,\n contextId: playerContext.contextId,\n moviesAndTv: playerContext.moviesAndTv\n });\n\n function onClickClose(): void {\n AnalyticsHelper.logUserAction({\n id: video.id\n }, {\n location: LocationContext.FloatingPlayer,\n entity: VideoHelper.getAnalyticsEntity(video),\n actionType: UserAction.Click,\n descriptor: ClickDescriptor.Close\n });\n\n if (!playerContext.isOnPlayPage) {\n playerContext.dispose();\n return;\n }\n\n playerContext.setPlayerMode(playerContext.previousMode);\n playerContext.playerRef.current?.togglePictureInPicture(false);\n }\n\n function onClickOpenVideo(): void {\n if (playerContext.isOnPlayPage)\n return;\n\n playerContext.setPlayerMode?.('default');\n playerContext.playerRef.current?.togglePictureInPicture(false);\n\n AnalyticsHelper.logUserAction({\n id: video.id\n }, {\n location: LocationContext.FloatingPlayer,\n entity: VideoHelper.getAnalyticsEntity(video),\n actionType: UserAction.Click,\n descriptor: ClickDescriptor.Open\n });\n }\n\n function onClickHover(): void {\n playerContext.setPersist();\n // set to play mode before triggering redirect to prevent layout shift\n playerContext.playerRef.current?.setPlayerMode?.('play');\n Core.AppLinkHelper.trigger(playerContext.appLink ?? appLink);\n }\n\n const forceUpdate = useForceUpdate();\n function onReady(player: any): void {\n playerContext.setPlayerRef(player);\n forceUpdate();\n\n /**\n * 🗑️ Alert!! 📢\n * So browsers do this fun thing where sometimes they decide to\n * not respect the autoplay flag on the video element. - Sha\n */\n const timeoutId = window.setTimeout(() => {\n if (!player || player.isDisposed() || !player.isPaused())\n return;\n\n player.play();\n }, 300);\n\n const onPlaying = () => playerContext.setStarted(true);\n player.one('playing', onPlaying);\n player.one('dispose', () => {\n player.off('play', onPlaying);\n window.clearTimeout(timeoutId);\n playerContext.setPlayerRef(null);\n });\n }\n\n React.useEffect(() => {\n if (!playerContext.playerRef?.current || playerContext.disposed)\n return;\n \n if (playerContext.mode === 'hover') {\n playerContext.playerRef.current?.setPlayerMode?.('hover', onClickHover, playerContext.onRemoveVideo);\n return;\n }\n\n if (playerContext.mode === 'picture-in-picture') {\n playerContext.playerRef.current?.togglePictureInPicture?.(true);\n return;\n }\n\n playerContext.playerRef.current?.setPlayerMode?.('play');\n playerContext.playerRef.current?.togglePictureInPicture?.(false);\n }, [ playerContext.playerRef.current, playerContext.mode, playerContext.disposed ]);\n\n function onRequestPictureInPicture(isPip: boolean): void {\n playerContext.setPlayerMode?.(isPip ? 'picture-in-picture' : playerContext.previousMode);\n\n if (isPip) {\n playerContext.playerRef.current?.toggleTranscript(false);\n playerContext.setPersist();\n }\n }\n\n function onRequestTheatreMode(isTheatreMode: boolean): void {\n playerContext.setDefaultDisplayMode?.(isTheatreMode ? 'theatre' : 'normal');\n }\n\n const appLink = getVideoAppLink(\n video,\n shareLink,\n playerContext,\n currentUser?.isAuthenticated,\n props.presentationSlug\n );\n\n const isTheatreDisplayMode = playerContext.defaultDisplayMode === 'theatre' && playerContext.mode === 'default';\n\n return (\n <>\n <InPortal node={playerContext.portalNode}>\n {hasCompleted && (\n <LitePlayerView\n config={config}\n currentUser={currentUser}\n video={video}\n shareLink={shareLink}\n pointsOfInterest={pointsOfInterest}\n viewKey={viewKey}\n relatedVideos={relatedVideos}\n presentationSlug={props.presentationSlug}\n onReady={onReady}\n onRequestPictureInPicture={onRequestPictureInPicture}\n onRequestTheatreMode={onRequestTheatreMode}\n autoplay\n context={playerContext.context}\n contextId={playerContext.contextId}\n moviesAndTv={playerContext.moviesAndTv}\n playNext={playerContext.playNext}\n startTime={playerContext.startTime}\n endTime={playerContext.endTime}\n mode={playerContext.mode}\n defaultDisplayMode={playerContext.defaultDisplayMode}\n muted={playerContext.mode === 'hover' ? true : undefined}\n playerIntegrations={playerIntegrations}\n questionListPortalNode={playerContext.questionListPortalNode}\n token={playerContext.token}\n allowTranscript={hasPlayPageTranscript}\n // todo remove this when we ship theatre mode for everyone\n allowTheatreMode={hasPlayPageTranscript}\n />\n )}\n {!hasCompleted && playerContext.mode !== 'hover' && (\n <div className={`partial-loading-background responsive-img ${isTheatreDisplayMode ? styles.theatreBackground : ''}`} />\n )}\n </InPortal>\n {hasCompleted &&\n <div className={styles.globalPlayer}>\n <CSSTransition\n timeout={400}\n in={playerContext.mode === 'picture-in-picture'}\n classNames='global-player'\n >\n <div className='d-none shadow'>\n {playerContext.mode === 'picture-in-picture' && <OutPortal node={playerContext.portalNode} />}\n <div className='p-2 bg-white d-flex justify-content-between align-items-center'>\n <GlobalPlayerTitle\n hasProduct={hasProduct}\n video={video}\n appLink={appLink}\n onClickTitle={onClickOpenVideo}\n presentationSlug={props.presentationSlug}\n />\n <span className={`${styles.buttons}`}>\n <span className='cursor-pointer ms-1 float-end' role='button' tabIndex={0} onClick={onClickClose}>\n {playerContext.isOnPlayPage ?\n <SvgContainer svg={NewWindowSvg} className={`${styles.flippedIcon} d-inline-block svg-container`} /> :\n <SvgContainer svg={CloseSvg} />}\n </span>\n <AppLink\n appLink={appLink}\n onClick={onClickOpenVideo}\n >\n {!playerContext.isOnPlayPage && <SvgContainer\n svg={NewWindowSvg}\n className={`${styles.flippedIcon} d-inline-block svg-container float-end`} />}\n </AppLink>\n </span>\n </div>\n </div>\n </CSSTransition>\n </div>\n }\n </>\n );\n}\n","{{{options.svg}}}\n{{#if options.unreadCount}}\n<span class=\"badge bg-danger rounded-pill {{options.styles.unreadCount}}\">{{options.unreadCount}}</span>\n{{/if}}",":local {\n .notificationIcon {\n width: $cv-svg-size-lg;\n height: $cv-svg-size-lg;\n color: $white;\n position: relative;\n display: inline-block;\n vertical-align: middle;\n\n &:hover {\n cursor: pointer;\n }\n\n svg {\n fill: $white;\n }\n\n &.light {\n color: $white;\n }\n\n &.dark {\n color: $black;\n }\n }\n\n .unreadCount {\n position: absolute;\n left: 1rem;\n bottom: -2px;\n min-width: 0;\n font-size: 0.6rem;\n }\n}\n","import { ObjectHash } from 'backbone';\n\nimport { Core } from 'libs/common/core';\n\nimport { BellSvg } from 'libs/shared/images/svg/objects/BellSvg';\nimport { SvgHelper } from 'libs/shared/utils/SvgHelper';\n\nimport NotificationStatusTemplate from './NotificationStatus.hbs';\n\nimport styles from './notification-status.module.scss';\n\ninterface NotificationStatusComponentOptions extends Core.ComponentOptions {\n color: 'light' | 'dark';\n}\n\nexport class NotificationStatusComponent extends Core.Component {\n declare public options: NotificationStatusComponentOptions;\n\n public constructor(options: NotificationStatusComponentOptions) {\n super(options);\n }\n\n // @ts-ignore\n public get name(): string {\n return 'NotificationStatusComponent';\n }\n\n // @ts-ignore\n public get className(): string {\n return `notification-status ${styles.notificationIcon} ${styles[this.options.color]}`;\n }\n\n // @ts-ignore\n public get template(): any {\n return NotificationStatusTemplate;\n }\n\n public initialize(): void {\n this.listenTo(this.model, 'change:unreadCount', this.render);\n }\n\n private getUnreadCount(): string {\n const unreadCount = this.model.get('unreadCount');\n\n if (typeof unreadCount !== 'number' || unreadCount === 0)\n return '';\n\n if (unreadCount > 99)\n return '99+';\n\n return unreadCount.toString();\n }\n\n public viewOptions(): ObjectHash {\n return {\n styles,\n svg: SvgHelper.getSvg(BellSvg),\n unreadCount: this.getUnreadCount()\n };\n }\n}\n","<h2 class=\"header p-2 m-0 border-bottom h5\">{{lang \"notifications\"}}</h2>\n<div class=\"list-region\"></div>\n{{#if options.hasNotifications}}\n<div class=\"py-2 border-top text-end px-2\">\n <a class=\"see-all\">{{lang \"seeAll\"}}</a>\n</div>\n{{/if}}\n","import { ObjectHash } from 'backbone';\n\nimport { InstanceManager } from 'libs/common/backbone/services/InstanceManager';\nimport { Core } from 'libs/common/core';\n\nimport { NotificationCollection } from 'libs/shared/apps/notifications/collections/NotificationCollection';\nimport { NotificationChildType, NotificationListComponent } from 'libs/shared/apps/notifications/components/notification-list/NotificationListComponent';\nimport { NotificationService } from 'libs/shared/apps/notifications/services/NotificationService';\nimport { AppVariables } from 'libs/shared/constants/AppVariables';\nimport { SharedDataPrefixes } from 'libs/shared/constants/DataPrefixes';\nimport { SharedServices } from 'libs/shared/constants/SharedServices';\nimport { PartialLoadingComponentTypes } from 'libs/shared/enums/PartialLoading';\nimport { BaseNotificationsAppVariables, Config } from 'libs/shared/interfaces';\nimport { CollectionIdentifier } from 'libs/shared/legacy/interfaces';\nimport { ConfigDataServiceHelper } from 'libs/shared/services/ConfigDataService';\n\nimport PartialLoadingTemplate from '../../components/notification-items/partial-loading/NotificationsPartial.hbs';\n\nimport NotificationsPopoverTemplate from './NotificationsPopover.hbs';\n\nimport PartialLoadingStyles from '../../components/notification-items/partial-loading/notification-partial.module.scss';\n\nexport interface NotificationsPopoverViewOptions extends Core.ViewOptions {\n childType: NotificationChildType;\n hasLite: boolean;\n}\n\nexport class NotificationsPopoverView extends Core.View {\n declare public options: NotificationsPopoverViewOptions;\n declare public collection: NotificationCollection;\n public config: Config | Core.Model;\n private collectionIdentifier: CollectionIdentifier;\n private notificationService: NotificationService;\n private appVariables: BaseNotificationsAppVariables;\n\n public constructor(options: NotificationsPopoverViewOptions) {\n super(options);\n }\n\n // @ts-ignore\n public get name(): string {\n return 'NotificationPopoverView';\n }\n\n // @ts-ignore\n public get title(): boolean {\n return false;\n }\n\n // @ts-ignore\n public get lang(): string {\n return 'notifications.notificationsPopover';\n }\n\n // @ts-ignore\n public get className(): string {\n return 'notifications-container';\n }\n\n // @ts-ignore\n public get template(): any {\n return NotificationsPopoverTemplate;\n }\n\n public regions(): ObjectHash {\n return {\n notifications: {\n replaceElement: true,\n el: '.list-region',\n partialLoading: {\n component: PartialLoadingComponentTypes.ComponentCollection,\n options: {\n collectionLength: 5,\n childOptions: {\n template: PartialLoadingTemplate,\n className: `px-1 py-2`,\n viewOptions: {\n styles: PartialLoadingStyles\n }\n }\n }\n }\n }\n };\n }\n\n public get elements(): ObjectHash {\n return {\n anchor: '.see-all'\n };\n }\n\n // @ts-ignore\n public get appLinks(): Core.AppLinkHash {\n return {\n '@ui.anchor': this.appVariables.appLinks.notifications\n };\n }\n\n public initialize(): void {\n this.notificationService = InstanceManager.getInstance(SharedServices.Notification, this);\n this.appVariables = InstanceManager.getInstance(AppVariables.NOTIFICATIONS, this);\n }\n\n private onData(collection: NotificationCollection): void {\n this.collection = collection;\n this.render();\n }\n\n private getCollectionIdentifier(): CollectionIdentifier {\n if (this.collectionIdentifier)\n return this.collectionIdentifier;\n\n /**\n * Currently we only retrieve the first page\n */\n return this.collectionIdentifier = new CollectionIdentifier({\n collectionPrefix: SharedDataPrefixes.NOTIFICATIONS\n });\n }\n\n private renderNotificationList(): void {\n const view = new NotificationListComponent({\n collection: this.collection,\n childType: this.options.childType,\n isPopover: true,\n hasLite: this.options.hasLite,\n liteUrl: this.config instanceof Core.Model ? this.config.get('liteUrl') : this.config.liteUrl,\n libraryEditorUrl: this.config instanceof Core.Model ? this.config.get('libraryEditorUrl') : this.config.libraryEditorUrl\n });\n\n this.showChildView('notifications', view);\n }\n\n // @ts-ignore\n public get requiredResources(): Core.RequiredResourceHash {\n return {\n config: ConfigDataServiceHelper.config\n };\n }\n\n public onBeforeRender(): boolean {\n /**\n * Deliberately passing null to always fetch the first page for the popover.\n * In future, we may add infinite scroll, at which point this will need to change.\n */\n if (!this.collection) {\n this.notificationService.getNotifications(\n null,\n this.getCollectionIdentifier(),\n (collection: NotificationCollection) => this.onData(collection)\n );\n }\n\n return !!this.collection;\n }\n\n public viewOptions(): ObjectHash {\n return {\n hasNotifications: this.collection && this.collection.length\n };\n }\n\n public onRender(): void {\n this.renderNotificationList();\n }\n}\n","import { ObjectHash } from 'backbone';\nimport * as _ from 'underscore';\n\nimport { Core } from 'libs/common/core';\n\nexport type TooltipPlacement = 'auto' | 'top' | 'bottom' | 'left' | 'right';\n\n/**\n * If a selector is not passed in, the tooltip\n * will be added to the view's element.\n * \n * For multiple tooltips in a single component,\n * omit the title option and instead add the title\n * attribute to the elements in the template.\n */\nexport interface TooltipOptions {\n selector?: string;\n title?: string;\n placement?: TooltipPlacement;\n}\n\nexport class TooltipBehavior extends Core.Behavior {\n // @ts-ignore\n public get defaults(): TooltipOptions {\n return {\n placement: 'top'\n };\n }\n\n public set defaults(defaults: TooltipOptions) {}\n\n // @ts-ignore\n public get ui(): ObjectHash {\n if (!this.options.selector)\n return {};\n\n return {\n tooltip: this.options.selector\n };\n }\n\n public set ui(ui: ObjectHash) {\n let viewUi = {};\n if (this.view.ui)\n viewUi = _.result(this.view, 'ui');\n\n (this.view as any)._ui = _.extend({}, viewUi, ui);\n }\n\n private getElement(): JQuery<HTMLElement> {\n if (this.options.selector)\n return this.view.getUI('tooltip');\n\n return this.view.$el;\n }\n\n private getOptions(): ObjectHash {\n const options: ObjectHash = {\n placement: this.options.placement || this.defaults.placement\n };\n\n if (this.options.title)\n options.title = this.options.title;\n\n return options;\n }\n\n public onRender(): void {\n const el = this.getElement();\n\n if (!el.length) return;\n\n el.tooltip(this.getOptions());\n }\n\n public onBeforeDetach(): void {\n const element = this.getElement();\n\n if (element instanceof jQuery) {\n element.tooltip('dispose');\n }\n }\n}\n","<button id=\"notificationsDropdown\" class=\"notifications-status-region tool-tip\" data-bs-toggle=\"dropdown\" title=\"{{title}}\"></button>\n<div aria-labelledby=\"notificationsDropdown\" class=\"notifications-region dropdown-menu dropdown-menu-end dropdown-arrow p-0 {{options.notificationsContainer}}\"></div>","@import '~styles/utils/functions';\n\n:local {\n .notificationsContainer {\n width: popover-content-width($cv-popover-md, true);\n }\n\n // Hide popover arrow\n .noPopoverArrow {\n :global(.dropdown-menu) {\n &::before,\n &::after {\n content: none;\n }\n }\n }\n}\n","import { ObjectHash } from 'backbone';\n\nimport { InstanceManager } from 'libs/common/backbone/services/InstanceManager';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { ClickDescriptor, EntityType, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { NotificationChildType } from 'libs/shared/apps/notifications/components/notification-list/NotificationListComponent';\nimport { NotificationStatusComponent } from 'libs/shared/apps/notifications/components/notification-status/NotificationStatusComponent';\nimport { NotificationService } from 'libs/shared/apps/notifications/services/NotificationService';\nimport { NotificationsPopoverView } from 'libs/shared/apps/notifications/views/popover/NotificationsPopoverView';\nimport { AppVariables } from 'libs/shared/constants/AppVariables';\nimport { SharedDataPrefixes } from 'libs/shared/constants/DataPrefixes';\nimport { SharedDataChannels } from 'libs/shared/constants/RadioChannels';\nimport { SharedServices } from 'libs/shared/constants/SharedServices';\nimport { BaseNotificationsAppVariables } from 'libs/shared/interfaces';\nimport { TooltipBehavior } from 'libs/shared/legacy/behaviors/tooltip/TooltipBehavior';\n\nimport NotificationHeaderTemplate from './NotificationHeader.hbs';\n\nimport styles from './notification-header.module.scss';\n\nexport interface NotificationHeaderViewOptions extends Core.ComponentOptions {\n hasLite: boolean;\n _legacyTooltip?: boolean;\n}\n\nexport class NotificationHeaderView extends Core.View {\n declare protected options: NotificationHeaderViewOptions;\n private appVariables: BaseNotificationsAppVariables;\n private notificationService: NotificationService;\n\n /**\n * Ensures we only trigger notifications as seen once. And refresh\n * if we get any new notifications in.\n */\n private _markedSeen: boolean = false;\n\n constructor(options: NotificationHeaderViewOptions) {\n super(options);\n }\n\n public initialize(): void {\n this.appVariables = InstanceManager.getInstance(AppVariables.NOTIFICATIONS);\n this.notificationService = InstanceManager.getInstance(SharedServices.Notification, this);\n\n this.listenTo(SharedDataChannels.NOTIFICATIONS_SOCKET, `${SharedDataPrefixes.NOTIFICATIONS}:new:sync`, this.onNewNotification);\n }\n\n // @ts-ignore\n public get lang(): string {\n return 'header.notificationHeader';\n }\n\n // @ts-ignore\n public get name(): string {\n return 'NotificationHeaderView';\n }\n\n // @ts-ignore\n public get title(): boolean {\n return false;\n }\n\n // @ts-ignore\n public get behaviors(): any[] {\n if (!this.options._legacyTooltip)\n return [];\n\n return [{\n behaviorClass: TooltipBehavior,\n selector: '.tool-tip',\n placement: 'left',\n title: LanguageService.getPhrase(this.lang, 'notifications')\n }];\n }\n\n // @ts-ignore\n public get className(): string {\n return `d-flex align-items-center position-relative ${styles.noPopoverArrow} ${this.options.className}`;\n }\n\n // @ts-ignore\n public get template(): any {\n return NotificationHeaderTemplate;\n }\n\n public regions(): ObjectHash {\n return {\n status: {\n el: '.notifications-status-region',\n replaceElement: false\n },\n notifications: {\n el: '.notifications-region',\n replaceElement: false\n }\n };\n }\n\n public events(): ObjectHash {\n return {\n 'click .notifications-status-region': 'renderNotificationList'\n };\n }\n \n private onShowDropdown(): void {\n AnalyticsHelper.logUserAction({}, {\n actionType: UserAction.Click,\n entity: EntityType.AppLink,\n location: LocationContext.NotificationsDropdown,\n descriptor: ClickDescriptor.Open\n });\n\n this.triggerSeen();\n }\n\n private triggerSeen(): void {\n if (this._markedSeen) return;\n\n this._markedSeen = true;\n this.notificationService.markNotificationsSeen();\n }\n\n private onNewNotification(): void {\n this._markedSeen = false;\n }\n\n private renderNotificationList(): void {\n const view = new NotificationsPopoverView({\n childType: NotificationChildType.Popover,\n hasLite: this.options.hasLite\n });\n\n this.showChildView('notifications', view);\n\n this.onShowDropdown();\n }\n\n private renderNotificationStatus(): void {\n const notificationService = InstanceManager.getInstance<NotificationService>(SharedServices.Notification);\n const view = new NotificationStatusComponent({\n model: notificationService.getNotificationsMetadata(),\n color: this.appVariables.bellIconColor\n });\n\n this.showChildView('status', view);\n }\n\n public viewOptions(): ObjectHash {\n return styles;\n }\n\n public onRender(): void {\n this.renderNotificationStatus();\n }\n}\n","import React from 'react';\n\nexport function SpeechSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path\n fill='currentColor'\n d='M16.657 16.576a1 1 0 0 1 .143-1.024l.076-.094a6.292 6.292 0 1 0-2.12 1.688l.082-.04a1 1 0 0 1 .834-.022l1.473.631zm1.788 1.126c.355.83-.483 1.669-1.313 1.313l-1.848-.792a7.492 7.492 0 1 1 2.524-2.008z'\n />\n </svg>\n );\n}\n",":local {\n .toggle {\n &:before {\n display: none!important;\n }\n }\n}","import * as React from 'react';\nimport { Dropdown } from 'react-bootstrap';\n\nimport { LocationUtils } from 'libs/common/backbone/core';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { EntityType, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { HouseSvg } from 'libs/shared/images/svg/objects/HouseSvg';\nimport { Customer } from 'libs/shared/interfaces';\n\nimport styles from './customer-selector-item.module.scss';\n\nconst MAX_CUSTOMERS_SHOWN = 4;\n\nconst namespace = 'shared.customerSelectorItem';\n\ninterface CustomerSelectorItemProps {\n isParentOpen: boolean;\n customers: Customer[];\n currentCustomerId: string;\n}\n\nexport function CustomerSelectorItem(props: CustomerSelectorItemProps): React.ReactElement {\n function onClickItem(event: React.MouseEvent<any>, customerId: string = null): void {\n if (customerId === props.currentCustomerId)\n return;\n\n AnalyticsHelper.logUserAction({\n id: props.currentCustomerId,\n newCustomerId: customerId\n }, {\n actionType: UserAction.SwitchCustomer,\n entity: EntityType.Customer,\n location: LocationContext.UserOptions\n });\n\n LocationUtils.PageLoad(getHref(customerId));\n }\n\n function getHref(id?: string): string {\n if (!id)\n return '/change-customer';\n\n return `/change-customer?customerId=${id}`;\n }\n \n if (!props.customers?.length || !props.currentCustomerId)\n return <></>;\n\n if (props.customers.length <= 1)\n return <></>;\n\n /**\n * If the user has more than 4 customers, we'll send them to Auth which has nicer UI\n * to select which customer they want to log into\n */\n if (props.customers.length > MAX_CUSTOMERS_SHOWN) {\n return (\n <Dropdown.Item\n as='li'\n onClick={e => onClickItem(e)}\n className='cursor-pointer'\n >\n <div className='d-flex justify-content-between'>\n <Text namespace={namespace} phrase='title' />\n <SvgContainer svg={HouseSvg} className='svg-container text-secondary' />\n </div>\n </Dropdown.Item>\n );\n }\n\n return (\n <li className='dropdown-item dropstart cursor-pointer'>\n <div className={`dropdown-toggle d-flex justify-content-between ${styles.toggle}`} data-bs-toggle='dropdown' aria-expanded='false'>\n <Text namespace={namespace} phrase='title' />\n <SvgContainer svg={HouseSvg} className='svg-container text-secondary' />\n </div>\n <ul className='dropdown-menu'>\n {props.customers.map((c, i) => {\n const isCurrent = c.id === props.currentCustomerId;\n return (\n <Dropdown.Item\n key={i}\n as='li'\n onClick={e => onClickItem(e, c.id)}\n disabled={isCurrent}\n >\n {c.name}\n </Dropdown.Item>\n );\n })}\n </ul>\n </li>\n );\n}\n","import { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { ClickDescriptor, EntityType, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { ProductRequests } from 'libs/shared/flight-requests/ProductRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { Config, CurrentUser, Product } from 'libs/shared/interfaces';\nimport { ArticleHelper } from 'libs/shared/utils/ArticleHelper';\n\nimport { UserOptionsItem } from './UserOptionsView';\n\nconst namespace = 'shared.userOptions';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface UserOptionsItemSections {\n main: UserOptionsItem[]; // After user details, before products\n external: UserOptionsItem[]; // External links (Get started, Help centre, What's New?)\n logOut: UserOptionsItem[]; // With log out link\n}\n\nexport function useGetUserOptionsItems(\n config: Config,\n additionalItems?: UserOptionsItem[],\n hideWhatsNew?: boolean\n): UserOptionsItemSections {\n const { hasPermissions } = usePermissions();\n\n const items = ArrayHelper.sortBy(additionalItems, 'order');\n\n if (config) {\n if (!hasPermissions(PermissionName.StudentExperience)) {\n items.push({\n label: getPhrase('getStarted'),\n order: 0,\n section: 'external',\n url: ArticleHelper.getWelcomeSiteUrl(),\n analyticsData: {\n url: ArticleHelper.getWelcomeSiteUrl()\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n descriptor: ClickDescriptor.ExternalLink,\n location: LocationContext.UserOptions\n }\n });\n }\n\n items.push({\n label: getPhrase('helpCentre'),\n order: 0,\n section: 'external',\n url: ArticleHelper.getSupportSiteUrl(),\n analyticsData: {\n url: ArticleHelper.getSupportSiteUrl()\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n descriptor: ClickDescriptor.ExternalLink,\n location: LocationContext.UserOptions\n }\n });\n \n if (hasPermissions(PermissionName.ViewProductBoard) && !hideWhatsNew) {\n const whatsNewUrl = UrlHelper.safeUrlConcat(config.productBoardUrl, 'tabs/23-what-s-new');\n\n items.push({\n label: getPhrase('whatsNew'),\n order: 0,\n section: 'external',\n url: whatsNewUrl,\n analyticsData: {\n url: whatsNewUrl\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n descriptor: ClickDescriptor.ExternalLink,\n location: LocationContext.UserOptions\n }\n });\n }\n }\n\n const sections: UserOptionsItemSections = {\n main: [],\n external: [],\n logOut: []\n };\n\n items.forEach(item => {\n if (item.section === 'logOut')\n sections.logOut.push(item);\n else if (item.section === 'external')\n sections.external.push(item);\n else\n sections.main.push(item);\n });\n\n return sections;\n}\n\nexport function useGetProductsToDisplay(\n productId: ProductId | ProductId[],\n hideProductList: boolean,\n transform?: (products: Product[]) => Product[]\n): Product[] | null {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const products = Flight.useBasicFetch<Product[]>(\n currentUser.data?.isAuthenticated && ProductRequests.userProducts()\n );\n\n if (hideProductList || !products.data)\n return;\n\n const productsToDisplay = [...products.data];\n const productIdsToHide = Array.isArray(productId) ? productId : [productId];\n\n let visibleProducts = productsToDisplay.filter(p => !productIdsToHide.includes(p.id), 'order');\n\n if (typeof transform === 'function')\n visibleProducts = transform(visibleProducts);\n\n return ArrayHelper.sortBy(visibleProducts);\n}\n",":local {\n .avatarContainer {\n width: $cv-user-options-avatar-size;\n height: $cv-user-options-avatar-size;\n }\n\n .productLogo {\n width: 1.75rem;\n height: 1.75rem;\n }\n\n .counter {\n font-size: 90%;\n }\n}","import * as React from 'react';\nimport { Dropdown } from 'react-bootstrap';\n\nimport { LocationUtils } from 'libs/common/backbone/core';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\nimport { Flight } from 'libs/common/flight';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { AnalyticsOptions, ClickDescriptor, EntityType, LocationContext, SignUpDescriptors, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { Avatar } from 'libs/shared/components/avatar/Avatar';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { ImageSize } from 'libs/shared/enums/Images';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { NewWindowSvg } from 'libs/shared/images/svg/actions/NewWindowSvg';\nimport { Config, CurrentUser, CustomerCollection, Product, User } from 'libs/shared/interfaces';\nimport { ImageHelper } from 'libs/shared/utils/ImageHelper';\nimport { UserHelper } from 'libs/shared/utils/UserHelper';\n\nimport { CustomerSelectorItem } from './components/CustomerSelectorItem';\nimport { useGetProductsToDisplay, useGetUserOptionsItems } from './UserOptionsViewUtils';\n\nimport styles from './user-options.module.scss';\n\nconst namespace = 'shared.userOptions';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport interface UserOptionsAppLinks {\n signOut: Core.AppLink;\n signUp?: Core.AppLink;\n signIn?: Core.AppLink;\n}\n\n/**\n * If no appLink and no url is provided, nothing will be rendered.\n */\nexport interface UserOptionsItem {\n label: string;\n order: number;\n appLink?: Core.AppLink;\n onClick?: () => void;\n url?: string;\n openInNewTab?: boolean; // Urls will open in a new tab by default.\n section?: 'main' | 'external' | 'logOut'; // Will default to main\n analyticsData?: HashObject;\n analyticsOptions?: AnalyticsOptions;\n counter?: number;\n}\n\ninterface UserOptionsItemComponentProps {\n item: UserOptionsItem;\n}\n\nfunction UserOptionsItemComponent({ item }: UserOptionsItemComponentProps): JSX.Element {\n if (item.appLink) {\n return (\n <Dropdown.Item\n as={AppLink}\n appLink={item.appLink}\n openInNewTab={item.openInNewTab}\n onClick={item.onClick}\n className='d-flex align-items-center'\n analyticsData={item.analyticsData}\n analyticsOptions={item.analyticsOptions}\n >\n {item.counter > 0 && (\n <div className={`${styles.counter} badge bg-danger rounded-pill fw-semibold me-1`}>\n {item.counter}\n </div>\n )}\n <div className='d-flex justify-content-between align-items-center flex-grow-1'>\n {item.label}\n {!!item.openInNewTab &&\n <SvgContainer svg={NewWindowSvg} className='svg-container text-secondary' />\n }\n </div>\n </Dropdown.Item>\n );\n }\n\n if (item.url) {\n function onClick(e: React.MouseEvent<HTMLElement, MouseEvent>): void {\n e.preventDefault();\n \n item.onClick?.();\n\n /**\n * If `openInNewTab` is falsy, there's a risk that this request will get dropped.\n */\n if (item.analyticsData && item.analyticsOptions)\n AnalyticsHelper.logUserAction({ href: item.url, ...item.analyticsData }, item.analyticsOptions);\n \n LocationUtils.PageLoad(item.url, true);\n }\n\n return (\n <Dropdown.Item\n as='a'\n href={item.url}\n target={item.openInNewTab === false ? null : '_blank'}\n className='d-flex align-items-center'\n onClick={e => onClick(e)}\n >\n {item.counter > 0 && (\n <div className={`${styles.counter} badge bg-danger rounded-pill fw-semibold me-1`}>\n {item.counter}\n </div>\n )}\n <div className='d-flex justify-content-between align-items-center flex-grow-1'>\n {item.label}\n {item.openInNewTab !== false &&\n <SvgContainer svg={NewWindowSvg} className='svg-container text-secondary' />\n }\n </div>\n </Dropdown.Item>\n );\n }\n\n return <></>;\n}\n\ninterface UserOptionsViewProps {\n productId: ProductId | ProductId[];\n appLinks: UserOptionsAppLinks;\n additionalItems?: UserOptionsItem[];\n hideProductList?: boolean;\n hideWhatsNew?: boolean;\n transform?: (products: Product[]) => Product[];\n displaySignUp?: boolean;\n}\n\nconst SignUpButtonSet = ({ appLinks }: UserOptionsViewProps): JSX.Element => {\n const breakpoints = useBreakpoints();\n const isMobile = breakpoints.xs || breakpoints.sm;\n\n return (\n <>\n <AppLink\n appLink={appLinks.signIn}\n className='btn btn-link ps-0'\n analyticsOptions={{\n actionType: UserAction.Click,\n location: LocationContext.TopNav,\n entity: EntityType.Url,\n descriptor: SignUpDescriptors.SignIn\n }}\n analyticsData={{}}\n >\n {getPhrase('signIn')}\n </AppLink>\n <AppLink\n appLink={appLinks.signUp}\n className='btn btn-dark ms-2'\n analyticsOptions={{\n actionType: UserAction.Click,\n location: LocationContext.TopNav,\n entity: EntityType.AppLink,\n workflowPhase: WorkflowPhase.Start,\n descriptor: SignUpDescriptors.SignUp\n }}\n analyticsData={{}}\n tag='button'\n >\n {isMobile ? getPhrase('signUpForMobile') : getPhrase('signUp')}\n </AppLink>\n </>\n );\n};\n\nconst SignInButton = ({ appLinks }: UserOptionsViewProps): JSX.Element => (\n <AppLink\n appLink={appLinks.signIn}\n className='btn btn-dark d-inline-block'\n analyticsOptions={{\n actionType: UserAction.Click,\n location: LocationContext.TopNav,\n entity: EntityType.AppLink,\n workflowPhase: WorkflowPhase.Start,\n descriptor: SignUpDescriptors.SignIn\n }}\n analyticsData={{}}\n >\n {getPhrase('signIn')}\n </AppLink>\n);\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function UserOptionsView(props: UserOptionsViewProps): React.ReactElement {\n const [ isOpen, setIsOpen ] = React.useState(false);\n const { hasPermissions } = usePermissions();\n\n const user = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const userDetails = Flight.useBasicFetch<User>(user.data?.id && UserRequests.user(user.data.id));\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n const customers = Flight.useBasicFetch<CustomerCollection>(\n user.data?.isAuthenticated && UserRequests.customers(user.data.id)\n );\n\n const items = useGetUserOptionsItems(config.data, props.additionalItems, props.hideWhatsNew);\n \n const isGuest = hasPermissions(PermissionName.GuestExperience);\n const hideProductList = props.hideProductList || isGuest;\n const products = useGetProductsToDisplay(props.productId, hideProductList, props.transform);\n\n function onToggleDropdown(show: boolean): void {\n setIsOpen(show);\n\n AnalyticsHelper.logUserAction({}, {\n actionType: UserAction.Click,\n entity: EntityType.AppLink,\n location: LocationContext.UserOptions,\n descriptor: show ? ClickDescriptor.Open : ClickDescriptor.Close\n });\n }\n\n function onClickProduct(product: Product): void {\n AnalyticsHelper.logUserAction({\n id: product.id,\n name: product.name\n }, {\n actionType: UserAction.Click,\n entity: EntityType.Product,\n location: LocationContext.UserOptions,\n descriptor: ClickDescriptor.ExternalLink\n });\n }\n\n if (!user.hasCompleted || (user.data.isAuthenticated && !userDetails.hasCompleted) || !config.data)\n return <></>;\n\n if (!user.data.isAuthenticated)\n return props.displaySignUp ?\n <SignUpButtonSet { ...props } /> :\n <SignInButton { ...props } />;\n\n return (\n <Dropdown className='position-relative' onToggle={onToggleDropdown}>\n <Dropdown.Toggle id='userOptions' variant='' aria-label='Options menu' className={`${styles.avatarContainer} no-caret border-0 p-0`}>\n <Avatar\n imageUrl={ImageHelper.createUrl(user.data.avatar, { size: ImageSize.Small })}\n imageCdnUrl={config.data.imageCdnUrl}\n initials={UserHelper.getInitials(user.data.givenName, user.data.familyName)}\n showDot={items.main.some(item => item.counter > 0)}\n />\n </Dropdown.Toggle>\n <Dropdown.Menu\n as='ul'\n align='end'\n >\n <Dropdown.Item as='div'>\n <div className='m-0 d-flex flex-wrap'>\n <strong>{user.data.displayName}</strong>\n &nbsp;\n { !isGuest && <span className='text-secondary'>({user.data.username})</span> }\n </div>\n <div className='m-0 text-secondary'>{user.data.customerName}</div>\n { !isGuest && userDetails.data?.masterYearGroup && <p className='m-0 text-secondary'>{userDetails.data.masterYearGroup.name}</p> }\n </Dropdown.Item>\n <CustomerSelectorItem\n isParentOpen={isOpen}\n currentCustomerId={user.data?.customerId}\n customers={customers.data?.data}\n />\n <Dropdown.Divider />\n\n {items.main.map((item, idx) => <UserOptionsItemComponent key={idx} item={item} />)}\n\n {!!items.main.length && !!products?.length &&\n <Dropdown.Divider />\n }\n\n {products?.map((product, idx) => {\n return (\n <Dropdown.Item\n key={idx}\n as='a'\n href={product.url}\n target='_blank'\n className='d-flex align-items-center py-1'\n onClick={() => onClickProduct(product)}\n >\n <img\n src={product.imageUrl}\n className={`${styles.productLogo} me-2`}\n />\n {product.name}\n </Dropdown.Item>\n );\n })}\n \n {(!!products?.length || !!items.main.length) && !!items.external.length &&\n <Dropdown.Divider />\n }\n\n {items.external.map((item, idx) => <UserOptionsItemComponent key={idx} item={item} />)}\n\n <Dropdown.Divider />\n\n {items.logOut.map((item, idx) => <UserOptionsItemComponent key={idx} item={item} />)}\n \n <Dropdown.Item\n as={AppLink}\n appLink={props.appLinks.signOut}\n analyticsData={{\n id: user.data?.id\n }}\n analyticsOptions={{\n actionType: UserAction.Click,\n location: LocationContext.UserOptions,\n entity: EntityType.AppLink,\n descriptor: SignUpDescriptors.SignOut\n }}\n >\n {getPhrase('signOut')}\n </Dropdown.Item>\n </Dropdown.Menu>\n </Dropdown>\n );\n}\n\n","import React from 'react';\nimport { CaptionedImageCard, Card } from '@clickview/braze-client';\n\nimport { useInstanceSafe } from 'libs/common/react/hooks/UseInstance';\n\nimport { SharedServices } from 'libs/shared/constants/SharedServices';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { BrazeClientService } from 'libs/shared/services/BrazeClientService';\n\nenum ContentCardTypes {\n Banner = 'banner',\n ProductTips = 'product-tip'\n}\n\nexport interface ExtraContendCardMetadata {\n bannerId?: string;\n type?: ContentCardTypes;\n}\n\nexport interface BannerContentCard {\n // id from Braze\n id: string;\n\n // from extras of Braze Content Card object\n extras: ExtraContendCardMetadata;\n\n // directly from Braze Content Card object\n title: string;\n description: string;\n expiresAt: Date;\n url?: string;\n linkText?: string;\n}\n\n/**\n * I dont think we use Content Cards in Lite atm\n * but If we do want to use it in future this needs to\n * be reworked on its implementation.\n * \n * - Nish\n */\nexport function useBrazeContentCards() {\n const isMountedRef = React.useRef(null);\n\n const { hasPermissions, isLoaded } = usePermissions();\n\n const [ allContentCards, setAllContentCards ] = React.useState<CaptionedImageCard[]>([]);\n\n const brazeClient = useInstanceSafe<BrazeClientService>(SharedServices.BrazeClient);\n\n React.useEffect(() => {\n if (!brazeClient.isReady || !isLoaded || hasPermissions(PermissionName.StudentExperience))\n return;\n\n isMountedRef.current = true;\n\n brazeClient.getContentCards()\n .then(res => {\n if (!isMountedRef.current)\n return;\n\n setAllContentCards(res);\n });\n\n return () => {\n isMountedRef.current = false;\n };\n }, [ brazeClient?.name, isLoaded ]);\n\n function logCardDismissal(contentCard: Card): void {\n if (contentCard?.extras?.type === ContentCardTypes.Banner)\n dismissBannerCards(contentCard?.extras?.bannerId);\n }\n\n function logContentCardClick(contentCard: Card): void {\n return brazeClient.logContentCardClick(contentCard);\n }\n\n function logContentCardImpressions(contentCards: Card[]): void {\n return brazeClient.logContentCardImpressions(contentCards);\n }\n\n // Dismiss all cards that share the same bannerId\n function dismissBannerCards(bannerId: string): void {\n getBannerCards().forEach(c => {\n if (c?.extras?.bannerId === bannerId)\n brazeClient.logContentCardDismissal(c);\n\n return;\n });\n }\n\n function getBannerCards(): CaptionedImageCard[] {\n return allContentCards?.filter(c => {\n // Banners must have a type in Braze\n if (c?.extras?.type !== ContentCardTypes.Banner)\n return false;\n\n // Banners must have an idendifier in Braze\n // We don't use the braze id as it's versioned\n if (!c?.extras?.bannerId)\n return false;\n\n // Ignore any banner that's expired\n // @todo braze\n if (c?.expiresAt < new Date())\n return false;\n\n return true;\n });\n }\n\n function getActiveBannerCard(): CaptionedImageCard {\n const currentBanners = getBannerCards();\n\n if (!currentBanners?.length)\n return;\n\n const dismissedById = currentBanners.some(c => c?.dismissed);\n\n // Where any banner of the same variant has been dismissed, we consider\n // all to have been dismissed.\n if (dismissedById)\n return;\n\n const mostRecent = currentBanners.sort((a, b) => b.created.getUTCDate() - a.created.getUTCDate());\n\n return (mostRecent?.[0] as CaptionedImageCard);\n }\n\n return {\n contentCards: allContentCards,\n activeBanner: getActiveBannerCard(),\n logCardDismissal,\n logContentCardClick,\n logContentCardImpressions\n };\n}\n","import { Flight } from 'libs/common/flight';\n\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { type CurrentUser } from 'libs/shared/interfaces';\n\nimport { usePluginHelper } from '../use-plugin-helper/usePluginHelper';\nimport { useBrazeContentCards } from '../useBrazeContentCards';\n\nexport function useLiteBanner() {\n const { isPlugin, params: { popup } } = usePluginHelper();\n const { hasPermissions, isLoaded } = usePermissions();\n\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const isLoading = !isLoaded || !currentUser.hasCompleted;\n\n const {\n activeBanner\n } = useBrazeContentCards();\n\n function getBannerType(): 'none' | 'braze' | 'popup-plugin' {\n const noBanner = (\n isLoading ||\n hasPermissions(PermissionName.StudentExperience)\n );\n\n if (noBanner)\n return 'none';\n\n if (isPlugin)\n return popup ? 'popup-plugin' : 'none';\n\n if (activeBanner)\n return 'braze';\n\n return 'none';\n }\n\n const hasBanner = getBannerType() !== 'none';\n\n return {\n hasBanner,\n getBannerType\n };\n}\n",":local {\n .banner {\n // This z-index is to get ahead of the .searchMask & .searchBackdrop in the teacher-layout.\n z-index: 1035;\n position: relative;\n }\n\n .close {\n top: 1rem;\n right: 1.55rem;\n }\n}","import React from 'react';\nimport { CaptionedImageCard } from '@clickview/braze-client';\n\nimport { StorageType } from 'libs/common/backbone/utils/LocalStorageHelper';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { ClickDescriptor, EntityType, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { ExternalLink } from 'libs/shared/components/external-link/ExternalLink';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { SharedViewModelKeys } from 'libs/shared/constants/SharedViewModelKeys';\nimport { CloseSvg } from 'libs/shared/images/svg/actions/CloseSvg';\n\nimport { useBrazeContentCards } from 'shared/hooks/useBrazeContentCards';\n\nimport styles from './braze-banner.module.scss';\n\nfunction buildText(bannerCard: CaptionedImageCard) {\n const { title, description } = bannerCard || {};\n\n let text = title ?? '';\n\n if (description)\n text = `${text} ${description}`;\n \n return text;\n}\n\ninterface BrazeBannerImpression {\n hasDismissed: boolean;\n hasSeen: boolean;\n}\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function BrazeBannerView(): JSX.Element {\n const [ showBanner, setShowBanner ] = React.useState<boolean>(false);\n\n const {\n activeBanner,\n logCardDismissal,\n logContentCardClick,\n logContentCardImpressions\n } = useBrazeContentCards();\n\n const [ bannerImpression, setBannerImpression ] = useViewModel<BrazeBannerImpression>(\n `${SharedViewModelKeys.BRAZE_BANNER_PREFIX}:${activeBanner?.extras?.bannerId}`,\n {\n hasDismissed: false,\n hasSeen: false\n },\n { storage: StorageType.LocalStorage }\n );\n\n React.useEffect(() => {\n if (bannerImpression?.hasDismissed || !activeBanner) {\n setShowBanner(false);\n return;\n }\n\n if (!bannerImpression?.hasSeen) {\n logContentCardImpressions([activeBanner]);\n setBannerImpression({\n ...bannerImpression,\n hasSeen: true\n });\n }\n\n setShowBanner(true);\n }, [ bannerImpression?.hasDismissed, activeBanner?.extras?.bannerId ]);\n\n function onDismiss() {\n AnalyticsHelper.logUserAction(analyticsData, {\n actionType: UserAction.Dismiss,\n location: LocationContext.Banner,\n entity: EntityType.Banner\n });\n\n setBannerImpression({\n ...bannerImpression,\n hasDismissed: true\n });\n\n setShowBanner(false);\n logCardDismissal(activeBanner);\n }\n\n function onClick() {\n logContentCardClick(activeBanner);\n }\n\n if (!showBanner || !activeBanner)\n return <></>;\n\n const bannerText = buildText(activeBanner);\n const { url, linkText } = activeBanner;\n \n const analyticsData = {\n id: 'braze-content-card',\n name: activeBanner?.title,\n bannerId: activeBanner?.extras?.bannerId,\n type: 'banner',\n url\n };\n\n return (\n <div className={`bg-ultramarine d-none d-md-block ${styles.banner}`}>\n <div className='text-center'>\n {!!bannerText &&\n <span className='text-light d-inline-block py-3 h6 mb-0'>{bannerText}</span>\n }\n {!!url && !!linkText &&\n <ExternalLink\n className='ps-1 text-light h6 text-underline'\n href={url}\n newTab={true}\n analyticsData={analyticsData}\n onClick={onClick}\n analyticsOptions={{\n actionType: UserAction.Click,\n location: LocationContext.Banner,\n entity: EntityType.Url,\n descriptor: ClickDescriptor.ExternalLink\n }}>\n {linkText}\n </ExternalLink>\n }\n </div>\n <div className={`cursor-pointer position-absolute ${styles.close}`} onClick={onDismiss}>\n <SvgContainer className='d-inline-block svg-container text-white' svg={CloseSvg} />\n </div>\n </div>\n );\n}\n",":local {\n .banner {\n // This z-index is to get ahead of the .searchMask & .searchBackdrop in the teacher-layout.\n z-index: 1035;\n position: relative;\n }\n}","import React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\n\nimport { usePluginHelper } from 'shared/hooks/use-plugin-helper/usePluginHelper';\n\nimport styles from './plugin-banner.module.scss';\n\nconst namespace = 'shared.pluginBanner';\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function PluginBannerView(): JSX.Element {\n const { consumerName } = usePluginHelper();\n\n return (\n <div className={`bg-indigo ${styles.banner}`}>\n <div className='text-center'>\n <span className='text-light d-inline-block py-3 h6 mb-0'>\n <Text\n namespace={namespace}\n phrase={consumerName ? 'message' : 'noConsumer'}\n options={{ consumerName }}\n />\n </span>\n </div>\n </div>\n );\n}\n","import React from 'react';\n\nimport { useLiteBanner } from 'shared/hooks/use-lite-banner/useLiteBanner';\nimport { BrazeBannerView } from 'shared/views/braze-banner/BrazeBannerView';\nimport { PluginBannerView } from 'shared/views/plugin-banner/PluginBannerView';\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function BannerView(): JSX.Element {\n const { getBannerType } = useLiteBanner();\n\n const bannerType = getBannerType();\n \n if (bannerType === 'braze')\n return <BrazeBannerView />;\n\n if (bannerType === 'popup-plugin')\n return <PluginBannerView />;\n\n return <></>;\n}\n","import React from 'react';\n\ninterface SearchInTagProps {\n name: string;\n}\n\nexport function SearchInTag(props: SearchInTagProps): JSX.Element {\n return (\n <div className='rounded-pill px-2 bg-light-blue text-dark border text-nowrap font-size-small border-dark d-inline-block'>\n <span className='d-none d-md-inline'>Search in:&nbsp;</span>\n <span>{props.name}</span>\n </div>\n );\n}\n","import React from 'react';\n\nimport { useDebounce } from 'libs/shared/hooks/UseDebounce';\n\n/**\n * Escapes the regex special characters\n * so that it can be used as a matcher\n */\nfunction escapeRegex(value: string) {\n return value.replace(/[-[\\]{}()*+?.,\\\\^$|#]/g, '\\\\$&');\n}\n\nexport function highlighter(value: string, highlightText: string) {\n if (highlightText === null) {\n return [{ chunk: value, highlighted: false }];\n }\n\n const highlight = escapeRegex(highlightText);\n\n const shouldHighlight = Array.isArray(highlight) ?\n highlight.filter(part => part.trim().length > 0).length > 0 :\n highlight.trim() !== '';\n\n if (!shouldHighlight) {\n return [{ chunk: value, highlighted: false }];\n }\n\n const matcher = highlight.trim();\n const re = new RegExp(`(${matcher})`, 'gi');\n const chunks = value\n .split(re)\n .map(part => ({ chunk: part, highlighted: re.test(part) }))\n .filter(({ chunk }) => chunk);\n\n return chunks;\n}\n\ninterface TextHighlightProps {\n text: string;\n highlight: string;\n\n delay?: number; // in ms\n\n className?: {\n root?: string,\n text?: string,\n highlight?: string\n };\n}\n\nexport function TextHighlight(props: TextHighlightProps): JSX.Element {\n const highlightChunks = React.useMemo(\n () => highlighter(props.text, props.highlight),\n [ props.text, props.highlight ]\n );\n const debouncedHighlightChunks: typeof highlightChunks = useDebounce(highlightChunks, props.delay || 300);\n\n const chunks = props.delay ? debouncedHighlightChunks : highlightChunks;\n\n return (\n <span className={props.className?.root || ''}>\n {chunks.map(({ chunk, highlighted }, i) => {\n if (highlighted) {\n return <mark className={props.className?.highlight || 'fw-semibold'} key={i}>{chunk}</mark>;\n }\n\n return <span key={i} className={props.className?.text || ''}>{chunk}</span>;\n })}\n </span>\n );\n}\n",":local {\n .searchItemImage {\n width: 2.5rem;\n height: 2.5rem;\n }\n\n .trendingPresentationText {\n font-size: 0.625rem; // 10px\n }\n\n .recentSuggestion {\n // svg size + padding left & right size + gap size\n $leftIconWidth: (\n $cv-svg-size + (map-get($spacers, 2) * 2) + (map-get($spacers, 2))\n );\n\n max-width: calc(100% - $leftIconWidth);\n\n // right clearance for remove button\n padding-right: $spacer * 2;\n }\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { Badge, BadgeType } from 'libs/shared/components/badges/Badge';\nimport { IconButton } from 'libs/shared/components/icon-button/IconButton';\nimport { BaseImage } from 'libs/shared/components/image/BaseImage';\nimport { ContainerClassSize, ImageFallback, ImageFallbackType } from 'libs/shared/components/image/ImageFallback';\nimport { Suggestion } from 'libs/shared/components/search-bar/SearchBar';\nimport { SuggestionType } from 'libs/shared/components/search-bar/SearchUtils';\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { ImageSize, ImageType } from 'libs/shared/enums/Images';\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { useHover } from 'libs/shared/hooks/UseHover';\nimport { CloseSvg } from 'libs/shared/images/svg/actions/CloseSvg';\nimport { SearchSvg } from 'libs/shared/images/svg/actions/SearchSvg';\nimport { BaseObject, Classification, Presentation } from 'libs/shared/interfaces';\nimport { MasterTypeHelper } from 'libs/shared/utils/MasterTypeHelper';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { RecentQueryValue } from 'apps/search/hooks/useLiteSearchBar';\n\nimport { SearchInTag } from '../search-in-tag/SearchInTag';\nimport { TextHighlight } from '../text-highlight/TextHighlight';\n\nimport styles from './search-suggestion.module.scss';\n\nconst namespace = 'search.searchSuggestionV2';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface BaseSuggestionProps {\n suggestion: Suggestion<BaseObject & RecentQueryValue>;\n}\n\ninterface SearchSuggestionContainerProps {\n className?: string;\n}\n\nconst SearchSuggestionContainer = React.forwardRef(\n function SearchSuggestionContainer(\n props: React.PropsWithChildren<SearchSuggestionContainerProps>,\n ref: React.ForwardedRef<HTMLDivElement>\n ): JSX.Element {\n return (\n <div className={`p-2 ${props.className ? props.className : ''}`} ref={ref}>\n {props.children}\n </div>\n );\n }\n);\n\ninterface SearchQuerySuggestionProps extends BaseSuggestionProps {\n query: string;\n highlightQuery?: boolean;\n}\n\nexport const SearchQuerySuggestion = (props: SearchQuerySuggestionProps): JSX.Element => {\n return (\n <SearchSuggestionContainer className='d-flex justify-content-between align-items-center rounded-3'>\n <div className='d-flex gap-2 align-items-center'>\n <div className='p-2 bg-gray-100 rounded-1'>\n <SvgContainer svg={SearchSvg} size={SvgContainerSize.Standard} />\n </div>\n \n <div className='d-flex flex-column'>\n {props.highlightQuery ?\n <TextHighlight\n text={props.suggestion?.name}\n highlight={props.query}\n delay={300}\n className={{\n highlight: 'fw-normal bg-transparent p-0',\n text: 'fw-semibold'\n }}\n /> :\n <span className='fw-semibold'>{props.suggestion?.name}</span>\n }\n </div>\n </div>\n </SearchSuggestionContainer>\n );\n};\nSearchQuerySuggestion.Id = 'search-query-suggestion';\n\ninterface SearchRecentSuggestionProps extends BaseSuggestionProps {\n removeRecentSearch: (query: string) => void;\n isHighlighted: boolean;\n}\n\nfunction SearchRecentSuggestion(props: SearchRecentSuggestionProps) {\n const [ ref, hovered ] = useHover<HTMLDivElement>();\n \n function onClickClear(e: React.MouseEvent) {\n e.preventDefault();\n props.removeRecentSearch(props.suggestion?.name);\n }\n\n const active = props.isHighlighted || hovered;\n\n const scopeId = props.suggestion?.filters?.scopeId;\n const scopeName = props.suggestion?.filters?.scopeName;\n\n return (\n <SearchSuggestionContainer className={`d-flex justify-content-between align-items-center rounded-3 w-100 p-2 ${active ? 'bg-light-blue cursor-pointer' : ''}`} ref={ref}>\n <div className='d-flex gap-2 align-items-center w-100'>\n <div className='p-2 bg-gray-100 rounded-1'>\n <SvgContainer svg={SearchSvg} size={SvgContainerSize.Standard} />\n </div>\n \n <div className={classNames('d-flex align-items-center justify-content-between position-relative w-100', styles.recentSuggestion)}>\n <div>\n {scopeId && scopeName && <SearchInTag name={scopeName} />}\n <span className='ps-1 text-truncate fw-semibold'>{props.suggestion?.name}</span>\n </div>\n <IconButton\n svg={CloseSvg}\n svgSize={SvgContainerSize.Standard}\n onClick={onClickClear}\n className={`position-absolute end-0 ${active ? 'opacity-100' : 'opacity-0'}`}\n />\n </div>\n </div>\n </SearchSuggestionContainer>\n );\n}\n\ninterface SearchTopicSuggestionProps {\n classification: Classification;\n activePresentation: Presentation;\n totalPresentations: number;\n trending: boolean;\n}\n\nfunction SearchTopicSuggestion(props: SearchTopicSuggestionProps): JSX.Element {\n function getSubText(): JSX.Element {\n const showPresentation = props.totalPresentations > 1 && props.activePresentation;\n const showMtv = TopicsHelper.isMtv(props.classification);\n\n if (!showPresentation && !showMtv)\n return <></>;\n\n return (\n <span className={`${styles.trendingPresentationText}`}>\n {showPresentation && <>{props.activePresentation.name}</>}\n {showPresentation && showMtv && <> &bull; </>}\n {showMtv && <>{LanguageService.getPhrase(namespace, 'mtv')}</>}\n </span>\n );\n }\n\n return (\n <div className='d-flex justify-content-between align-items-center p-2'>\n <div className='d-flex gap-2 align-items-center'>\n <div className={styles.searchItemImage}>\n <BaseImage\n data={props.classification.cover?.url}\n imageClassName='rounded'\n imageOptions={{ size: ImageSize.Small }}\n imageType={ImageType.Logos}\n >\n <ImageFallback\n containerClassSize={ContainerClassSize.Small}\n extraClasses={`${styles.searchItemImage} rounded position-relative d-inline-block`}\n type={ImageFallbackType.Subject}\n svgContainerClassName='p-2'\n />\n </BaseImage>\n </div>\n <div className='d-flex flex-column'>\n {getSubText()}\n <span className='fw-semibold'>{props.classification.name}</span>\n </div>\n </div>\n {props.trending &&\n <Badge type={BadgeType.Trending} data={getPhrase('trending')} size='xs' />\n }\n </div>\n );\n}\n\ninterface SearchSuggestionProps extends BaseSuggestionProps {\n query: string;\n isHighlighted: boolean;\n activePresentation: Presentation;\n totalPresentations: number;\n removeRecentSearch: (recentSearchQuery: string) => void;\n}\n\nfunction getSuggestionComponent(props: SearchSuggestionProps): JSX.Element {\n if (props.suggestion?.suggestionType === SuggestionType.Recent) {\n return (\n <SearchRecentSuggestion\n suggestion={props.suggestion}\n removeRecentSearch={props.removeRecentSearch}\n isHighlighted={props.isHighlighted}\n />\n );\n }\n\n if (props.suggestion?.suggestionType === SuggestionType.Generic &&\n props.suggestion?.id === SearchQuerySuggestion.Id\n ) {\n return <SearchQuerySuggestion suggestion={props.suggestion} query={props.query} />;\n }\n\n if (MasterTypeHelper.isType<Classification>(props.suggestion, MasterType.Subject)) {\n return (\n <SearchTopicSuggestion\n activePresentation={props.activePresentation}\n totalPresentations={props.totalPresentations}\n classification={props.suggestion}\n trending={props.suggestion?.suggestionType === SuggestionType.Local}\n />\n );\n }\n\n return <SearchQuerySuggestion suggestion={props.suggestion} query={props.query} highlightQuery />;\n}\n\nexport function SearchSuggestion(props: SearchSuggestionProps): JSX.Element {\n const SuggestionComponent = getSuggestionComponent(props);\n\n return (\n <>\n {SuggestionComponent}\n </>\n );\n}\n",":local {\n .defaultSectionTitle {\n font-size: 0.75rem; // 12px\n }\n}","import React from 'react';\n\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { SuggestionSection } from 'libs/shared/components/search-bar/SearchUtils';\n\nimport styles from './section-title.module.scss';\n\ninterface SectionTitleProps {\n section: SuggestionSection<HashObject>;\n onClickClear: () => void;\n className?: string;\n}\n\nexport function SectionTitle(props: SectionTitleProps): JSX.Element {\n const { section, className } = props;\n \n if (!section.title?.length)\n return <></>;\n \n return (\n <div className={`p-2 pt-0 ${styles.defaultSectionTitle} ${className}`}>\n <strong>{section.title}</strong>\n </div>\n );\n}\n","import * as _ from 'underscore';\n\nimport { StorageHelper } from 'libs/common/backbone/utils/LocalStorageHelper';\n\nexport interface UpdateRecentSearchOptions<T> {\n query: T;\n add?: boolean;\n remove?: boolean;\n limit?: number;\n}\n\nexport const RecentSearchHelper = {\n getRecentSearches<T>(key: string, dataSource: StorageHelper): T[] {\n let recentSearches = dataSource.cacheGet(key);\n\n if (!_.isArray(recentSearches))\n recentSearches = [];\n\n return recentSearches;\n },\n\n setRecentSearches<T>(key: string, recentSearches: T[], dataSource: StorageHelper): void {\n if (!_.isArray(recentSearches))\n return;\n\n dataSource.cacheSet(key, recentSearches);\n },\n\n updateRecentSearches<T>(key: string, dataSource: StorageHelper, options: UpdateRecentSearchOptions<T>): T[] {\n const { add, remove, query, limit = 5 } = options;\n\n let recentSearches = RecentSearchHelper.getRecentSearches<T>(key, dataSource);\n\n const queryIndex = _.indexOf<T>(recentSearches, query);\n\n if (add && queryIndex === -1)\n recentSearches.unshift(query);\n\n if (remove && queryIndex > -1)\n recentSearches.splice(queryIndex, 1);\n\n if (recentSearches.length > limit)\n recentSearches = recentSearches.slice(0, limit);\n\n RecentSearchHelper.setRecentSearches<T>(key, recentSearches, dataSource);\n\n return recentSearches;\n },\n\n clearRecentSearches(dataSource: StorageHelper): void {\n dataSource.clear();\n }\n};\n\n","/**\n * Source: https://use-keyboard-shortcut.tyukayev.com/\n */\n\nimport { useCallback, useEffect, useMemo, useRef } from 'react';\n\nimport { HashObject } from 'libs/common/react/interfaces';\n\nconst BLACKLISTED_DOM_TARGETS = [ 'TEXTAREA', 'INPUT' ];\nconst BLACKLISTED_DOM_ATTRIBUTES = [\n { attribute: 'contenteditable', value: 'true' }\n];\n\nconst DEFAULT_OPTIONS = {\n overrideSystem: false,\n ignoreInputFields: true,\n repeatOnHold: true\n};\n\nconst overrideSystemHandling = (e: Event) => {\n if (e) {\n if (e.preventDefault) e.preventDefault();\n if (e.stopPropagation) {\n e.stopPropagation();\n } else if (window.event) {\n window.event.cancelBubble = true;\n }\n }\n};\n\nconst uniq_fast = (a: any[]) => {\n const seen: HashObject = {};\n const out = [];\n const len = a.length;\n let j = 0;\n for (let i = 0; i < len; i++) {\n const item = a[i];\n if (seen[item] !== 1) {\n seen[item] = 1;\n out[j++] = item;\n }\n }\n return out;\n};\n\nconst checkHeldKeysRecursive = (\n shortcutKey: string,\n // Tracks the call interation for the recursive function,\n // based on the previous index;\n shortcutKeyRecursionIndex = 0,\n shortcutArray: string[],\n heldKeysArray: string[]\n): boolean => {\n const shortcutIndexOfKey = shortcutArray.indexOf(shortcutKey);\n const keyPartOfShortCut = shortcutArray.indexOf(shortcutKey) >= 0;\n\n // Early exit if they key isn't even in the shortcut combination.\n if (!keyPartOfShortCut) return false;\n\n // While holding down one of the keys, if another is to be let go, the shortcut\n // should be void. Shortcut keys must be held down in a specifc order.\n // This function is always called before a key is added to held keys on keydown,\n // this will ensure that heldKeys only contains the prefixing keys\n const comparisonIndex = Math.max(heldKeysArray.length - 1, 0);\n if (\n heldKeysArray.length &&\n heldKeysArray[comparisonIndex] !== shortcutArray[comparisonIndex]\n ) {\n return false;\n }\n\n // Early exit for the first held down key in the shortcut,\n // except if this is a recursive call\n if (shortcutIndexOfKey === 0) {\n // If this isn't the first interation of this recursive function, and we're\n // recursively calling this function, we should always be checking the\n // currently held down keys instead of returning true\n if (shortcutKeyRecursionIndex > 0)\n return heldKeysArray.indexOf(shortcutKey) >= 0;\n return true;\n }\n\n const previousShortcutKeyIndex = shortcutIndexOfKey - 1;\n const previousShortcutKey = shortcutArray[previousShortcutKeyIndex];\n const previousShortcutKeyHeld =\n heldKeysArray[previousShortcutKeyIndex] === previousShortcutKey;\n\n // Early exit if the key just before the currently checked shortcut key\n // isn't being held down.\n if (!previousShortcutKeyHeld) return false;\n\n // Recursively call this function with the previous key as the new shortcut key\n // but the index of the current shortcut key.\n return checkHeldKeysRecursive(\n previousShortcutKey,\n shortcutIndexOfKey,\n shortcutArray,\n heldKeysArray\n );\n};\n\ninterface UseKeyboardShortcutOptions {\n shortcutKeys: string[];\n callback: (shortcutKeys: string[]) => void;\n options?: {\n overrideSystem?: boolean,\n ignoreInputFields?: boolean,\n repeatOnHold?: boolean,\n logKeyPress?: boolean\n };\n}\n\nconst useKeyboardShortcut = ({ shortcutKeys, callback, options: userOptions }: UseKeyboardShortcutOptions) => {\n const options = { ...DEFAULT_OPTIONS, ...userOptions };\n if (!Array.isArray(shortcutKeys))\n throw new Error(\n 'The first parameter to `useKeyboardShortcut` must be an ordered array of `KeyboardEvent.key` strings.'\n );\n\n if (!shortcutKeys.length)\n throw new Error(\n 'The first parameter to `useKeyboardShortcut` must contain at least one `KeyboardEvent.key` string.'\n );\n\n if (!callback || typeof callback !== 'function')\n throw new Error(\n 'The second parameter to `useKeyboardShortcut` must be a function that will be envoked when the keys are pressed.'\n );\n\n const shortcutKeysId = useMemo(() => shortcutKeys.join(), [shortcutKeys]);\n\n // Normalizes the shortcut keys a deduplicated array of lowercased keys.\n const shortcutArray = useMemo(\n () => uniq_fast(shortcutKeys).map(key => String(key).toLowerCase()),\n // While using .join() is bad for most larger objects, this shortcut\n // array is fine as it's small, according to the answer below.\n // https://github.com/facebook/react/issues/14476#issuecomment-471199055\n \n [shortcutKeysId]\n );\n // useRef to avoid a constant re-render on keydown and keyup.\n const heldKeys = useRef([]);\n\n const keydownListener = useCallback(\n (keydownEvent: KeyboardEvent) => {\n if (options?.logKeyPress) {\n console.log('[useKeyboardShortcut]', keydownEvent.key);\n }\n \n const loweredKey = String(keydownEvent.key).toLowerCase();\n if (!(shortcutArray.indexOf(loweredKey) >= 0)) return;\n\n const eventTarget = keydownEvent.target as HTMLElement;\n\n if (\n options.ignoreInputFields &&\n (\n BLACKLISTED_DOM_TARGETS.includes(eventTarget.tagName) ||\n BLACKLISTED_DOM_ATTRIBUTES.some(({ attribute, value }) => eventTarget.getAttribute(attribute) === value)\n )\n ) {\n return;\n }\n\n if (keydownEvent.repeat && !options.repeatOnHold) return;\n\n if (options.overrideSystem) {\n overrideSystemHandling(keydownEvent);\n }\n // This needs to be checked as soon as possible to avoid\n // all option checks that might prevent default behavior\n // of the key press.\n //\n // I.E If shortcut is \"Shift + A\", we shouldn't prevent the\n // default browser behavior of Select All Text just because\n // \"A\" is being observed for our custom behavior shortcut.\n const isHeldKeyCombinationValid = checkHeldKeysRecursive(\n loweredKey,\n null,\n shortcutArray,\n heldKeys.current\n );\n\n if (!isHeldKeyCombinationValid) {\n return;\n }\n\n const nextHeldKeys = [ ...heldKeys.current, loweredKey ];\n if (nextHeldKeys.join() === shortcutArray.join()) {\n callback(shortcutKeys);\n return false;\n }\n\n heldKeys.current = nextHeldKeys;\n\n return false;\n },\n \n [\n shortcutKeysId,\n callback,\n options.overrideSystem,\n options.ignoreInputFields\n ]\n );\n\n const keyupListener = useCallback(\n (keyupEvent: KeyboardEvent) => {\n const raisedKey = String(keyupEvent.key).toLowerCase();\n if (!(shortcutArray.indexOf(raisedKey) >= 0)) return;\n\n const raisedKeyHeldIndex = heldKeys.current.indexOf(raisedKey);\n if (!(raisedKeyHeldIndex >= 0)) return;\n\n const nextHeldKeys = [];\n let loopIndex;\n for (loopIndex = 0; loopIndex < heldKeys.current.length; ++loopIndex) {\n if (loopIndex !== raisedKeyHeldIndex) {\n nextHeldKeys.push(heldKeys.current[loopIndex]);\n }\n }\n heldKeys.current = nextHeldKeys;\n\n return false;\n },\n \n [shortcutKeysId]\n );\n\n const flushHeldKeys = useCallback(() => {\n heldKeys.current = [];\n }, []);\n\n useEffect(() => {\n window.addEventListener('keydown', keydownListener);\n window.addEventListener('keyup', keyupListener);\n return () => {\n window.removeEventListener('keydown', keydownListener);\n window.removeEventListener('keyup', keyupListener);\n };\n }, [ keydownListener, keyupListener, shortcutKeysId ]);\n\n // Resets the held keys array if the shortcut keys are changed.\n useEffect(() => {\n flushHeldKeys();\n }, [ shortcutKeysId, flushHeldKeys ]);\n\n return {\n flushHeldKeys\n };\n};\n\nexport default useKeyboardShortcut;\n","import { useEffect, useState } from 'react';\n\ninterface UseScrollbarOptions {\n /**\n * If set to true it will offset the\n * scrollbar width to prevent layout shift\n */\n offsetScrollWidth?: boolean;\n\n /**\n * Target element to offset the scroll width.\n */\n offsetScrollTarget?: HTMLElement;\n}\n\nexport function useScrollbar(options?: UseScrollbarOptions) {\n const [ scrollbarWidth, setScrollbarWidth ] = useState(0);\n\n useEffect(() => {\n function calculateScrollbarWidth() {\n requestAnimationFrame(() => {\n setScrollbarWidth(window.innerWidth - document.documentElement.clientWidth);\n });\n }\n\n calculateScrollbarWidth();\n\n window.addEventListener('resize', calculateScrollbarWidth);\n \n return () => {\n window.removeEventListener('resize', calculateScrollbarWidth);\n };\n }, []);\n\n function enableScrolling() {\n document.body.style.overflow = '';\n \n if (!options?.offsetScrollWidth)\n return;\n \n const target = options?.offsetScrollTarget || document.body;\n target.style.paddingRight = '';\n }\n\n function disableScrolling() {\n document.body.style.overflow = 'hidden';\n \n if (!options?.offsetScrollWidth)\n return;\n \n const target = options?.offsetScrollTarget || document.body;\n target.style.paddingRight = `${scrollbarWidth}px`;\n }\n\n return {\n width: scrollbarWidth,\n enable: enableScrolling,\n disable: disableScrolling\n };\n}\n","// All values are in px, just based on the size they are currently sized at\nexport const LiteBanner = {\n BannerHeight: 59,\n MultiplePresHeight: 69,\n PluginMultiplePresHeight: 49,\n BannerHideWidth: 768 // This is bootstrap md breakpoint\n} as const;\n","import React from 'react';\nimport Radio from 'backbone.radio';\n\nimport { CommonChannels } from 'libs/common/backbone/constants/CommonChannels';\nimport { AppLink } from 'libs/common/backbone/core';\nimport { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\nimport { LocalStorageHelper } from 'libs/common/backbone/utils/LocalStorageHelper';\nimport { UserAgentHelper } from 'libs/common/backbone/utils/UserAgentHelper';\nimport { Core } from 'libs/common/core';\nimport { Flight } from 'libs/common/flight';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { ClickDescriptor, EntityType, LocationContext, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { FilterHelper } from 'libs/shared/apps/search/utils/FilterHelper';\nimport { RecentSearchHelper } from 'libs/shared/apps/search/utils/RecentSearchHelper';\nimport { SearchBarControls } from 'libs/shared/components/search-bar/SearchUtils';\nimport { useDebounce } from 'libs/shared/hooks/UseDebounce';\nimport useKeyboardShortcut from 'libs/shared/hooks/useKeyboardShortcut';\nimport { useListenOn } from 'libs/shared/hooks/UseListenOn';\nimport { useResizeListener } from 'libs/shared/hooks/UseResizeListener';\nimport { useScrollbar } from 'libs/shared/hooks/useScrollbar';\nimport { useScrollListener } from 'libs/shared/hooks/UseScrollListener';\nimport { ContextService } from 'libs/shared/services/ContextService';\n\nimport { ViewModelKeys } from 'shared/constants/LiteViewModels';\nimport { useActivePresentation } from 'shared/hooks/presentations/useActivePresentation';\nimport { useAvailablePresentations } from 'shared/hooks/presentations/useAvailablePresentations';\nimport { useLiteBanner } from 'shared/hooks/use-lite-banner/useLiteBanner';\nimport { usePluginHelper } from 'shared/hooks/use-plugin-helper/usePluginHelper';\nimport { LiteBanner } from 'shared/views/banner/constants/LiteBanner';\n\nimport { SearchRequests } from 'apps/search/flight-requests/SearchRequests';\nimport { SearchHelper } from 'apps/search/utils';\n\nconst {\n BannerHeight: BANNER_HEIGHT,\n BannerHideWidth: BANNER_HIDE_WIDTH\n} = LiteBanner;\n\nconst HEADER_HEIGHT = 67;\nconst SUGGESTION_EXTRA_SPACING = 14; // Extra margins top and bottom\n\n// TODO: Maybe the flight middleware should handle this someday. Out of scope for now\nconst searchResultsCache = new Map();\n\nfunction getRecentQueryIndexKey(query: string, filters?: RecentQueryFilters): string {\n if (!filters || !Object.keys(filters).length) {\n return query;\n }\n\n if (!filters.scopeId && !filters.scopeName) {\n return query;\n }\n\n return JSON.stringify({\n name: query,\n filters\n });\n}\n\ninterface RecentQueryFilters {\n scopeId?: string;\n scopeName?: string;\n}\n\nexport interface RecentQueryValue {\n name: string;\n filters?: RecentQueryFilters;\n}\n\nfunction parseRecentQueryValue(value: string): RecentQueryValue {\n try {\n return JSON.parse(value) as RecentQueryValue;\n } catch {\n return { name: value };\n }\n}\n\ninterface UseLiteSearchBarOptions {\n recentSearchKey: string;\n queryDebounceTime: number;\n\n searchTransitionFadeDuration: number;\n\n mainRef?: React.MutableRefObject<HTMLElement>;\n\n navRef?: React.MutableRefObject<HTMLElement>;\n\n searchbarRef?: React.MutableRefObject<HTMLElement>;\n\n enableBackdrop?: boolean;\n\n hasGuestExperience: boolean;\n\n /**\n * Incremental changes flag - should be removed after we migrate to search v2\n */\n _hasNewSearch: boolean;\n}\n\nexport function useLiteSearchBar(options: UseLiteSearchBarOptions) {\n const getFetch = Flight.useGetFetch();\n const { hasBanner } = useLiteBanner();\n const { isPlugin } = usePluginHelper();\n\n const [ suggestionsContainerHeight, setSuggestionsContainerHeight ] = React.useState(0);\n const [ showMask, setShowMask ] = useViewModel(ViewModelKeys.SHOW_SEARCH_MASK, false);\n const [ , setShowBackdrop ] = useViewModel(ViewModelKeys.SHOW_SEARCH_BACKDROP, false);\n const { availablePresentations } = useAvailablePresentations();\n const { activePresentation } = useActivePresentation();\n\n const bodyScroll = useScrollbar({\n offsetScrollTarget: options?.mainRef?.current,\n offsetScrollWidth: true\n });\n\n const navScroll = useScrollbar({\n offsetScrollTarget: options?.navRef?.current,\n offsetScrollWidth: true\n });\n\n const searchScroll = useScrollbar({\n offsetScrollTarget: options?.searchbarRef?.current,\n offsetScrollWidth: true\n });\n\n const appLink = ContextService.getCurrentRoute().appLink;\n const params = (appLink?.params ?? {}) as HashObject;\n\n const [ isNavigatingAway, setIsNavigatingAway ] = React.useState(false);\n\n const searchBarControlsRef = React.useRef<SearchBarControls>(null);\n\n const initialQuery = React.useMemo(SearchHelper.getInitialQuery, []);\n const currentQuery = params?.query ?? '';\n const [ query, setQuery ] = React.useState(initialQuery);\n const debouncedQuery = useDebounce(query, options.queryDebounceTime);\n\n const [ recentSearches, setRecentSearches ] = React.useState<RecentQueryValue[]>(getMappedRecentSearches());\n const [ showSuggestions, setShowSuggestions ] = React.useState<boolean>(false);\n\n const routeContext = ContextService.getCurrentRoute();\n const currentAppLink = routeContext.appLink;\n const referrerAppLink = SearchHelper.useReferrerAppLink();\n const isOnSearchPage = SearchHelper.isSearchAppLink(currentAppLink);\n\n function getMappedRecentSearches(): RecentQueryValue[] {\n return RecentSearchHelper.getRecentSearches(options.recentSearchKey, LocalStorageHelper).\n map<RecentQueryValue>((value: string) => parseRecentQueryValue(value));\n }\n\n function leaveSearch(\n referrerAppLink: AppLink,\n fadeTime: number\n ) {\n setShowMask(true);\n\n window.setTimeout(() => {\n setShowMask(false);\n Core.AppLinkHelper.trigger(referrerAppLink, { replace: true });\n }, fadeTime);\n }\n\n function handleFetchSuggestions(query: string, onSuccess?: (data: any) => void, onError?: () => void) {\n if (searchResultsCache.has(query)) {\n const data = searchResultsCache.get(query);\n onSuccess?.(data);\n return;\n }\n\n const req = SearchRequests.suggestions(query, availablePresentations?.map(item => item?.id));\n\n getFetch({\n ...req,\n success: data => {\n searchResultsCache.set(query, data);\n typeof req.success === 'function' && req.success(data);\n typeof onSuccess === 'function' && onSuccess(data);\n },\n error: xhr => {\n typeof req.error === 'function' && req.error(xhr);\n typeof onError === 'function' && onError();\n }\n });\n }\n\n function findAvailablePresentation(id: string) {\n return availablePresentations?.find(pres => pres?.id.toString() === id);\n }\n\n function updateRecentSearches(query: string, filters?: RecentQueryFilters) {\n if (!query)\n return;\n\n if (options.hasGuestExperience)\n return;\n\n RecentSearchHelper.updateRecentSearches(options.recentSearchKey, LocalStorageHelper, {\n query: getRecentQueryIndexKey(query, filters),\n limit: options._hasNewSearch ? 3 : undefined,\n add: true\n });\n\n setRecentSearches(getMappedRecentSearches());\n }\n\n function removeRecentSearch(recentSearchQuery: string, filters?: RecentQueryFilters) {\n if (!recentSearchQuery || !recentSearchQuery.length)\n return;\n\n RecentSearchHelper.updateRecentSearches(options.recentSearchKey, LocalStorageHelper, {\n query: getRecentQueryIndexKey(recentSearchQuery, filters),\n limit: options._hasNewSearch ? 3 : undefined,\n remove: true\n });\n\n setRecentSearches(getMappedRecentSearches());\n }\n\n function onClearRecentSearchesCache() {\n const recentSearches = getMappedRecentSearches();\n\n AnalyticsHelper.logUserAction({\n recentSearches\n }, {\n actionType: UserAction.Click,\n entity: EntityType.SearchSuggestion,\n location: LocationContext.SearchBar,\n descriptor: ClickDescriptor.Clear\n });\n \n RecentSearchHelper.clearRecentSearches(LocalStorageHelper);\n setRecentSearches(recentSearches);\n }\n\n function onArrowKeyUpOrDown() {\n // Find suggestion element that is currently highlighted\n const suggestionElement = document.querySelector('nav [role=\"search\"] [data-suggestion-index][data-section-index][aria-selected=\"true\"]');\n if (!suggestionElement)\n return;\n\n suggestionElement.scrollIntoView({\n behavior: 'instant',\n block: 'nearest',\n inline: 'nearest'\n });\n }\n\n function enableScroll() {\n navScroll.enable();\n bodyScroll.enable();\n searchScroll.enable();\n }\n\n function disableScroll() {\n navScroll.disable();\n bodyScroll.disable();\n searchScroll.disable();\n }\n\n function onChangeFocus(type: 'blur' | 'focus') {\n if (type === 'blur') {\n setShowSuggestions(false);\n searchBarControlsRef.current.blurInput();\n return;\n }\n \n setShowSuggestions(true);\n searchBarControlsRef.current.focusInput();\n }\n\n const calculateSuggestionsContainerHeight = FunctionHelper.throttle(() => {\n if (!options._hasNewSearch)\n return;\n \n const isBannerVisible = hasBanner &&\n !isPlugin &&\n window.innerWidth > BANNER_HIDE_WIDTH &&\n window.scrollY < BANNER_HEIGHT;\n \n let availableHeight = window.innerHeight - HEADER_HEIGHT - SUGGESTION_EXTRA_SPACING;\n if (isBannerVisible) {\n availableHeight -= BANNER_HEIGHT;\n }\n setSuggestionsContainerHeight(availableHeight);\n }, 1000);\n\n /** \n * Side Effects below\n */\n\n React.useEffect(() => {\n if (!options._hasNewSearch || typeof options.enableBackdrop !== 'boolean')\n return;\n\n if (showSuggestions && options.enableBackdrop) {\n setShowBackdrop(true);\n disableScroll();\n return;\n }\n\n setShowBackdrop(false);\n enableScroll();\n }, [ showSuggestions, options.enableBackdrop, options._hasNewSearch ]) ;\n\n React.useEffect(() => {\n // calculate the initial container height when page loads\n calculateSuggestionsContainerHeight();\n }, [ hasBanner, options._hasNewSearch ]);\n\n useResizeListener(\n calculateSuggestionsContainerHeight,\n null,\n [ hasBanner, options._hasNewSearch ]\n );\n\n useScrollListener(\n calculateSuggestionsContainerHeight,\n [ hasBanner, options._hasNewSearch ]\n );\n\n useKeyboardShortcut({\n shortcutKeys: [ 'Control', 'k' ],\n options: {\n ignoreInputFields: true,\n overrideSystem: true,\n repeatOnHold: false\n },\n callback: () => {\n searchBarControlsRef.current?.focusInput();\n }\n });\n\n useKeyboardShortcut({\n shortcutKeys: [ 'Meta', 'k' ],\n options: {\n ignoreInputFields: true,\n overrideSystem: true,\n repeatOnHold: false\n },\n callback: () => {\n const osInfo = UserAgentHelper.getOperatingSystem();\n if (osInfo.os !== 'Macintosh')\n return;\n \n searchBarControlsRef.current?.focusInput();\n }\n });\n\n useKeyboardShortcut({\n shortcutKeys: ['Escape'],\n options: {\n ignoreInputFields: false,\n overrideSystem: false,\n repeatOnHold: false\n },\n callback: () => {\n searchBarControlsRef.current?.blurInput();\n }\n });\n\n /**\n * If all tag / classification filters are removed\n * and there's no query, leave search\n */\n React.useEffect(() => {\n const searchIsValid = SearchHelper.isValidSearch(query, currentAppLink);\n if (searchIsValid || !isOnSearchPage)\n return;\n\n leaveSearch(referrerAppLink, options.searchTransitionFadeDuration);\n }, [\n (currentAppLink.params as HashObject)?.tagOrClassification,\n (currentAppLink.params as HashObject)?.rating,\n (currentAppLink.params as HashObject)?.moviesAndTv,\n (currentAppLink.params as HashObject)?.source\n ]);\n\n // Search is triggered when the query hasn't been updated for 300ms\n React.useEffect(() => {\n if (options._hasNewSearch)\n return;\n \n const params = { ...currentAppLink.params as HashObject };\n\n // If the query changes and we have applied tag filters, unset them\n if (debouncedQuery.trim() && params?.tagOrClassification && !routeContext.pageLoad)\n delete params.tagOrClassification;\n \n const searchIsValid = SearchHelper.isValidSearch(query, currentAppLink);\n \n // If the search is no longer valid (e.g. the user has cleared their query), leave search\n if (!searchIsValid && isOnSearchPage)\n return leaveSearch(referrerAppLink, options.searchTransitionFadeDuration);\n \n if (!searchIsValid)\n return;\n \n AnalyticsHelper.logUserAction({\n query,\n indices: FilterHelper.getAppliedIndices(currentAppLink.params as HashObject, options._hasNewSearch)\n }, {\n actionType: UserAction.InstantSearch,\n entity: EntityType.SearchResults,\n location: LocationContext.SearchBar,\n workflowPhase: WorkflowPhase.Complete\n });\n \n SearchHelper.triggerAppLink(query, params as HashObject, isOnSearchPage);\n }, [debouncedQuery]);\n \n // Listen to all URL changes\n useListenOn(Radio.channel(CommonChannels.SHELL), Core.EventNames.URL_CHANGE, appLink => {\n // Applink is null when browsing via browser back/forth buttons\n if (!appLink)\n appLink = ContextService.getCurrentRoute().appLink;\n \n // Clears the query when the user manually navigates away from search\n if (query && !SearchHelper.isSearchAppLink(appLink)) {\n !options._hasNewSearch && setIsNavigatingAway(true);\n setQuery('');\n searchBarControlsRef.current?.resetQuery?.();\n }\n \n // Sets the query when the user navigates between search queries using their browser history\n if (SearchHelper.isSearchAppLink(appLink) && appLink.params?.query !== !query) {\n const queryParams = appLink.params.query ?? '';\n setQuery(queryParams);\n \n const prev = ContextService.getPreviousRoute();\n if (prev && (options._hasNewSearch || !SearchHelper.isSearchAppLink(prev.appLink)))\n searchBarControlsRef.current?.setQuery?.(queryParams);\n }\n }, [ query, setQuery ]);\n\n /**\n * TODO: The commented out code will allow for a feature where curriculum codes are displayed\n * in the search bar. Until we work out if we want this or not / how we want to implement it,\n * we will leave it commented out.\n */\n // const isCurriculumCodeSearch = !showSuggestions && params[SEARCH_CURRICULUM_CODE_PARAM]?.toString() === 'true';\n const isCurriculumCodeSearch = false;\n\n return {\n query,\n initialQuery,\n currentQuery,\n showMask,\n recentSearches,\n currentAppLink,\n isOnSearchPage,\n showSuggestions,\n isNavigatingAway,\n searchBarControlsRef,\n availablePresentations,\n suggestionsContainerHeight,\n activePresentation,\n isCurriculumCodeSearch,\n setQuery,\n setShowMask,\n leaveSearch,\n onChangeFocus,\n setShowBackdrop,\n setShowSuggestions,\n onArrowKeyUpOrDown,\n setIsNavigatingAway,\n updateRecentSearches,\n handleFetchSuggestions,\n findAvailablePresentation,\n removeRecentSearch,\n onClearRecentSearchesCache\n };\n}\n","import React from 'react';\nimport { useInView } from 'react-intersection-observer';\nimport { Radio } from 'backbone';\n\nimport { CommonChannels } from 'libs/common/backbone/constants/CommonChannels';\nimport { Core } from 'libs/common/backbone/index';\nimport { Flight } from 'libs/common/react/index';\nimport { HashObject } from 'libs/common/react/interfaces/HashObject';\n\nimport { SEARCH_IN_PARAM } from 'libs/shared/apps/search/utils/SharedSearchHelper';\nimport { SearchBarControls } from 'libs/shared/components/search-bar/SearchUtils';\nimport { useListenOn } from 'libs/shared/hooks/UseListenOn';\nimport { useResizeListener } from 'libs/shared/hooks/UseResizeListener';\nimport { PartnerProfile } from 'libs/shared/interfaces';\nimport { ContextService } from 'libs/shared/services/ContextService';\n\nimport { ContentPartnersRequests } from 'shared/flight-requests/ContentPartnersRequests';\n\nimport { SearchHelper } from '../utils';\n\n// In Pixels\nconst SearchInValues = {\n ContainerOffsetLeft: (24 + 24), // Size of svg + spacing\n InputPaddingLeft: 12\n};\n\ninterface UseSearchInOptions {\n controlsRef: React.RefObject<SearchBarControls>;\n}\n\nexport function useSearchIn(options: UseSearchInOptions) {\n const { controlsRef } = options;\n\n const appLink = ContextService.getCurrentRoute().appLink;\n const scopeId = (appLink?.params as HashObject)?.[SEARCH_IN_PARAM];\n const [ internalEntityId, setInternalEntityId ] = React.useState<string | undefined>(scopeId ?? undefined);\n\n const shouldFetch = SearchHelper.isSearchAppLink(appLink) && !!internalEntityId;\n \n const containerRef = React.useRef<HTMLDivElement>(null);\n\n const entity = Flight.useBasicFetch<PartnerProfile>(\n shouldFetch && ContentPartnersRequests.partnerProfile(internalEntityId)\n );\n\n /**\n * Given a search in tag container and search input ref, sets the container's\n * position and inputs position so that absolutely positioned 'Search in' tag\n * does not overlap with input or any other elements.\n */\n const calculateResizes = React.useCallback(() => {\n if (!containerRef.current || !controlsRef.current || !shouldFetch)\n return;\n\n containerRef.current.style.left = `${SearchInValues.ContainerOffsetLeft}px`;\n controlsRef.current.setInputProperty('padding-left', `${containerRef.current?.offsetWidth + SearchInValues.InputPaddingLeft}px`);\n }, [ containerRef.current, controlsRef.current, shouldFetch ]);\n\n /**\n * Since the search bar is hidden on smaller screens,\n * We need to calculate the sizes when it becomes visible\n */\n const [inViewRef] = useInView({\n onChange: inView => {\n if (!inView)\n return;\n\n calculateResizes();\n }\n });\n\n useResizeListener(calculateResizes);\n\n /**\n * Re-enable the filter on URL change if the user had previously cleared it.\n * This handles the case where the user clears the tag and then selects a recent\n * search with the same scopeId — entityId doesn't change so the useEffect above\n * won't fire, but the URL_CHANGE event still fires.\n */\n useListenOn(Radio.channel(CommonChannels.SHELL), Core.EventNames.URL_CHANGE, (appLink: Core.AppLink) => {\n const params = (appLink?.params ?? {}) as HashObject;\n const entityId = params[SEARCH_IN_PARAM];\n\n setInternalEntityId(entityId);\n }, [appLink]);\n\n const setRefs = React.useCallback((node: HTMLDivElement) => {\n containerRef.current = node;\n inViewRef(node);\n }, [inViewRef]);\n\n function disable() {\n setInternalEntityId(undefined);\n controlsRef.current?.setInputProperty('padding-left', '');\n }\n\n const isVisible = !!internalEntityId && entity.hasCompleted && !!entity.data?.name;\n\n return {\n data: {\n name: entity.data?.name\n },\n filter: isVisible ? {\n [SEARCH_IN_PARAM]: internalEntityId,\n scopeName: entity.data?.name\n } : undefined,\n isVisible,\n setContainerRefs: setRefs,\n disable\n };\n}\n","import { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { ActionDescriptor, AnalyticsOptions, SearchSuggestionDescriptor, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\ninterface LiteSearchEventLoggerOptions {\n analyticsOptions: AnalyticsOptions;\n shouldLog?: boolean;\n}\n\ninterface SearchData {\n /**\n * Suggestion that was selected or query that was searched for\n */\n query: string;\n /**\n * Query in the search input at the time of the event\n */\n inputQuery: string;\n}\n\ninterface QueryLogData extends SearchData {\n type: 'query';\n /**\n * The total number of searches that the user has done in a row.\n * As in, the user has not navigated away from the search results page between searches.\n */\n consecutiveSearchCount: number;\n}\n\ninterface RecentSearchLogData extends SearchData {\n type: 'recent-search';\n}\n\ninterface TopicLogData extends SearchData {\n type: 'topic';\n topic: {\n id: string\n };\n}\n\ninterface TrendingTopicLogData extends SearchData {\n type: 'trending-topic';\n topic: {\n id: string\n };\n}\n\ninterface SuggestionLogData extends SearchData {\n type: 'suggestion';\n}\n\ntype LogData =\n | QueryLogData |\n RecentSearchLogData |\n TopicLogData |\n TrendingTopicLogData |\n SuggestionLogData;\n\ntype LogDataType = LogData['type'];\n\ninterface LogDataConfigOptions {\n isValid: (data: LogData) => boolean;\n analyticsOptions: AnalyticsOptions;\n}\n\nconst defaultAnalyticsOptions: AnalyticsOptions = {\n actionType: UserAction.Search,\n workflowPhase: WorkflowPhase.Complete\n};\n\nconst LogDataConfig: {[key in LogDataType]: LogDataConfigOptions } = {\n 'query': {\n isValid: (data: QueryLogData) => {\n return !!data.query;\n },\n analyticsOptions: defaultAnalyticsOptions\n },\n 'recent-search': {\n isValid: (data: RecentSearchLogData) => {\n return !!data.query;\n },\n analyticsOptions: defaultAnalyticsOptions\n },\n 'topic': {\n isValid: (data: TopicLogData) => {\n return !!data.topic.id && !!data.query;\n },\n analyticsOptions: defaultAnalyticsOptions\n },\n 'trending-topic': {\n isValid: (data: TrendingTopicLogData) => {\n return !!data.topic.id && !!data.query;\n },\n analyticsOptions: defaultAnalyticsOptions\n },\n 'suggestion': {\n isValid: (data: SuggestionLogData) => {\n return !!data.query;\n },\n analyticsOptions: defaultAnalyticsOptions\n }\n};\n\nconst logTypeDescriptor: {[key in LogDataType]: ActionDescriptor } = {\n 'query': SearchSuggestionDescriptor.Query,\n 'topic': SearchSuggestionDescriptor.Topic,\n 'recent-search': SearchSuggestionDescriptor.RecentSearch,\n 'trending-topic': SearchSuggestionDescriptor.TrendingTopic,\n 'suggestion': SearchSuggestionDescriptor.Keyword\n};\n\nexport function getLiteSearchEventLogger(options: LiteSearchEventLoggerOptions) {\n const { shouldLog = true } = options;\n \n function log(data: LogData, logAnalyticsOptions?: AnalyticsOptions): void {\n if (!shouldLog)\n return;\n\n const logDataConfig = LogDataConfig[data.type];\n\n if (!logDataConfig.isValid(data))\n return;\n\n const analyticsOptions = AnalyticsHelper.mergeOptions(\n options.analyticsOptions,\n [\n logDataConfig.analyticsOptions,\n { descriptor: logTypeDescriptor[data.type] },\n logAnalyticsOptions\n ]\n );\n\n const sanitizeData = ObjectHelper.pick(data, [ 'query', 'inputQuery', 'topic', 'consecutiveSearchCount' ]);\n\n AnalyticsHelper.logUserAction(sanitizeData, analyticsOptions);\n }\n\n return {\n log\n };\n}\n","import { SuggestionType } from 'libs/shared/components/search-bar/SearchUtils';\n\nexport const LiteSearchSettings = {\n /**\n * (V2) Min Length if query for search request to active\n */\n SearchActivationLength: 3,\n\n /**\n * (V1 / V2)Transition time for the search mask in milliseconds\n */\n TransitionFadeTime: 200,\n \n /**\n * (V2) Limits the results on typehead for each Suggestion type\n */\n SuggestionLimits: {\n [SuggestionType.Local]: 3,\n [SuggestionType.Recent]: 3,\n [SuggestionType.Remote]: 10\n },\n\n /**\n * (V2) Sort order of suggestion sections in dropdown\n */\n SuggestionSortOrder: [\n SuggestionType.Generic,\n SuggestionType.Recent,\n SuggestionType.Remote,\n SuggestionType.Local\n ]\n} as const;\n","import { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { Suggestion } from 'libs/shared/components/search-bar/SearchBar';\nimport { SuggestionSection, SuggestionType } from 'libs/shared/components/search-bar/SearchUtils';\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { BaseObject, Classification, Presentation } from 'libs/shared/interfaces';\nimport { MasterTypeHelper } from 'libs/shared/utils/MasterTypeHelper';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { LiteSearchSettings } from '../constants/LiteSearchSettings';\n\nconst namespace = 'search.searchBarUtils';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport function transformSections(\n query: string,\n availablePresentations: Presentation[],\n sections: SuggestionSection<BaseObject & { suggestionType: SuggestionType }>[]\n): SuggestionSection<BaseObject & { suggestionType: SuggestionType }>[] {\n /**\n * Sort the sections in the order on LiteSearchSettings.SuggestionSortOrder\n */\n const sortedSections = sections.sort((a, b) =>\n LiteSearchSettings.SuggestionSortOrder.indexOf(a.suggestionType) -\n LiteSearchSettings.SuggestionSortOrder.indexOf(b.suggestionType));\n \n /**\n * Transform any sections data - in this case\n * we are transforming remote section into multiple\n * remote sections for topics and query suggestions\n * we also sort the topics section\n */\n const transformedSections = sortedSections.reduce((prev, curr) => {\n if (curr.suggestionType === SuggestionType.Remote) {\n const remoteData = curr.data.filter(item => item.suggestionType === SuggestionType.Remote);\n\n const remoteTopicsData = remoteData.filter(\n item => MasterTypeHelper.isType<Classification>(item, MasterType.Subject)\n ) as Suggestion<Classification>[];\n\n const remoteQueryData = remoteData.filter(\n item => typeof item?.id === 'undefined' && typeof item.name === 'string'\n ) as Suggestion<{ query: string }>[];\n\n if (remoteTopicsData.length) {\n /**\n * Group by exact matches and remaining\n * Each group is sorted by their presentation learning level\n */\n const exactMatch: Suggestion<Classification>[] = [];\n const remaining: Suggestion<Classification>[] = [];\n\n remoteTopicsData.forEach(topic => {\n if (topic?.name?.toLowerCase() === query.toLowerCase()) {\n exactMatch.push(topic);\n return;\n }\n\n remaining.push(topic);\n });\n\n exactMatch.sort((a, b) => TopicsHelper.sortByLearningLevel(a, b, availablePresentations));\n remaining.sort((a, b) => TopicsHelper.sortByLearningLevel(a, b, availablePresentations));\n \n prev.push({\n data: [\n ...exactMatch,\n ...remaining\n ],\n suggestionType: SuggestionType.Remote,\n title: getPhrase('remoteTopicsSearchHeading')\n });\n }\n\n if (remoteQueryData.length) {\n prev.push({\n data: remoteQueryData,\n suggestionType: SuggestionType.Remote\n });\n }\n } else {\n prev.push(curr);\n }\n\n return prev;\n }, [] as SuggestionSection<BaseObject & { suggestionType: SuggestionType }>[]);\n \n return transformedSections;\n}\n\ninterface SearchQueryResponse {\n suggestions: string[];\n topics: Classification[];\n}\n\nexport function formatRemoteSuggestions(response: SearchQueryResponse) {\n const transformSuggestions = response.suggestions.reduce((prev, curr) => {\n prev.push({ name: curr });\n return prev;\n }, [] as BaseObject[]);\n\n const suggestions = [\n ...response.topics.slice(0, 5),\n ...transformSuggestions.slice(0, 5)\n ];\n\n return suggestions;\n}\n",":local {\n .searchBar {\n // 40px for actual height and 1px up and bottom for border\n height: 2.625rem; // 42px\n border: 1px solid $gray-400;\n border-radius: $border-radius-pill;\n background-color: $gray-100;\n transition: all 0.25s;\n max-width: 748px;\n\n &.focus,\n &:focus-within {\n border: 1px solid $gray-900;\n background: $white;\n }\n }\n\n .suggestionsContainerOpen {\n position: absolute;\n top: 100%;\n left: calc(-1 * ($cv-svg-size + (#{map-get($spacers, 2)} * 2)));\n width: calc(100% + ($cv-svg-size + (#{map-get($spacers, 2)} * 3)));\n right: 0;\n z-index: 100;\n margin-top: 2rem;\n border-radius: $border-radius-lg;\n }\n\n .suggestionSections {\n >div:not(:last-child) {\n margin-bottom: 1rem;\n }\n }\n\n .suggestionsContainerOpenWithClearIcon {\n left: calc(-1 * ($cv-svg-size + (#{map-get($spacers, 3)} * 3.5)));\n width: calc(100% + ($cv-svg-size + (#{map-get($spacers, 3)} * 4)));\n }\n}","import React from 'react';\nimport Autosuggest from 'react-autosuggest';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { EntityType, LocationContext, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { SEARCH_CURRICULUM_CODE_PARAM, SEARCH_IN_PARAM } from 'libs/shared/apps/search/utils/SharedSearchHelper';\nimport { CurriculumCodeTag } from 'libs/shared/components/curriculum-links/CurriculumCodeTag';\nimport { IconButton } from 'libs/shared/components/icon-button/IconButton';\nimport { SearchBar, Suggestion } from 'libs/shared/components/search-bar/SearchBar';\nimport { SuggestionSection, SuggestionType } from 'libs/shared/components/search-bar/SearchUtils';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { SearchSvg } from 'libs/shared/images/svg/actions/SearchSvg';\nimport { ChevronLeftSvg } from 'libs/shared/images/svg/arrows/ChevronLeftSvg';\nimport { BaseObject, Classification } from 'libs/shared/interfaces';\nimport { BreadcrumbService } from 'libs/shared/services/BreadcrumbService';\nimport { ContextService } from 'libs/shared/services/ContextService';\nimport { MasterTypeHelper } from 'libs/shared/utils/MasterTypeHelper';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { ClassificationAppLinkHelper } from 'shared/utils/ClassificationAppLinkHelper';\n\nimport { SearchSuggestion } from 'apps/search/components/search-bar-v2/components/search-suggestion/SearchSuggestion';\nimport { SectionTitle } from 'apps/search/components/search-bar-v2/components/section-title/SectionTitle';\nimport { RecentQueryValue, useLiteSearchBar } from 'apps/search/hooks/useLiteSearchBar';\nimport { useSearchIn } from 'apps/search/hooks/useSearchIn';\nimport { getLiteSearchEventLogger } from 'apps/search/utils/getLiteSearchEventLogger';\n\nimport { SearchInTag } from './components/search-in-tag/SearchInTag';\nimport { LiteSearchSettings } from './constants/LiteSearchSettings';\nimport { formatRemoteSuggestions, transformSections } from './utils/SearchBarUtils';\n\nimport styles from './lite-search-bar.module.scss';\n\nconst ACTIVATION_LENGTH = LiteSearchSettings.SearchActivationLength;\n\nconst namespace = 'search.liteSearchBarV2';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface SearchBarProps {\n trendingTopics: Classification[];\n recentSearchKey: string;\n queryDebounceTime: number;\n mainRef: React.MutableRefObject<HTMLElement>;\n navRef: React.MutableRefObject<HTMLElement>;\n searchbarWrapperRef: React.MutableRefObject<HTMLElement>;\n showCloseButton?: boolean;\n onClickClose?: () => void;\n autoFocus?: boolean;\n hasGuestExperience: boolean;\n presentationSlug: string | null;\n}\n\nexport function LiteSearchBarV2(props: SearchBarProps): JSX.Element {\n const [ hasSuggestions, setHasSuggestions ] = React.useState(false);\n\n const consecutiveSearchCount = React.useRef(0);\n\n const {\n query,\n initialQuery,\n currentQuery,\n recentSearches,\n currentAppLink,\n showSuggestions,\n activePresentation,\n availablePresentations,\n searchBarControlsRef,\n suggestionsContainerHeight,\n isCurriculumCodeSearch,\n setQuery,\n onChangeFocus,\n removeRecentSearch,\n onArrowKeyUpOrDown,\n updateRecentSearches,\n handleFetchSuggestions,\n findAvailablePresentation,\n onClearRecentSearchesCache\n } = useLiteSearchBar({\n queryDebounceTime: props.queryDebounceTime,\n recentSearchKey: props.recentSearchKey,\n searchTransitionFadeDuration: LiteSearchSettings.TransitionFadeTime,\n mainRef: props.mainRef,\n navRef: props.navRef,\n searchbarRef: props.searchbarWrapperRef,\n enableBackdrop: hasSuggestions,\n hasGuestExperience: props.hasGuestExperience,\n _hasNewSearch: true\n });\n\n const searchIn = useSearchIn({\n controlsRef: searchBarControlsRef\n });\n\n const { log } = getLiteSearchEventLogger({\n analyticsOptions: {\n actionType: UserAction.Search,\n entity: EntityType.SearchSuggestion,\n location: LocationContext.SearchBar\n }\n });\n\n function getSearchAppLink(query: string, filters?: HashObject): Core.AppLink {\n let params: HashObject = {\n query\n };\n\n // Pass through query params if already on search page and searching\n if (currentAppLink.application === AppChannels.SEARCH &&\n currentAppLink.action === Actions.Search.HOME &&\n typeof currentAppLink?.params === 'object') {\n params = {\n ...ObjectHelper.omit(currentAppLink.params, [ SEARCH_CURRICULUM_CODE_PARAM, SEARCH_IN_PARAM ]),\n query\n };\n }\n\n return {\n application: AppChannels.SEARCH,\n action: Actions.Search.HOME,\n params: {\n ...params,\n ...ObjectHelper.pick(filters, [SEARCH_IN_PARAM])\n }\n };\n }\n\n async function onSuggestionSelected(\n suggestion: Suggestion<BaseObject & RecentQueryValue>,\n input: HTMLInputElement,\n event: (React.FormEvent | React.KeyboardEvent)\n ) {\n // Clicking a suggestion blur the focus from input\n onChangeFocus('blur');\n\n // Clicked the remove recent search button\n if (suggestion.suggestionType === SuggestionType.Recent &&\n event.isDefaultPrevented() &&\n !('key' in event && event.type === 'keydown' && event.key === 'Enter')\n ) {\n log({\n type: 'recent-search',\n query: suggestion.name,\n inputQuery: query\n }, {\n workflowPhase: WorkflowPhase.Discard\n });\n onChangeFocus('focus');\n return;\n }\n\n if (MasterTypeHelper.isType<Classification>(suggestion, MasterType.Subject)) {\n const isMtv = TopicsHelper.isMtv(suggestion);\n if (suggestion.suggestionType === SuggestionType.Local) {\n log({\n type: 'trending-topic',\n query: suggestion.name,\n inputQuery: query,\n topic: {\n id: suggestion.id\n }\n });\n }\n\n if (suggestion.suggestionType === SuggestionType.Remote) {\n log({\n type: 'topic',\n query: suggestion.name,\n inputQuery: query,\n topic: {\n id: suggestion.id\n }\n });\n }\n\n /**\n * We reset our breadcrumb history here because instant search allows us to build a history that goes\n * TOPIC A -> TOPIC B where TOPIC B is entirely unrelated to TOPIC A.\n * \n * If we do not reset, breadcrumbs will attempt to build a path for TOPIC A, which is unrelated\n * - Sha\n */\n BreadcrumbService.resetHistory();\n Core.AppLinkHelper.trigger(\n ClassificationAppLinkHelper.getAppLink(suggestion, { moviesAndTv: isMtv }, availablePresentations)\n );\n\n searchBarControlsRef.current?.resetQuery?.();\n input.blur();\n \n return;\n }\n\n let filters = suggestion.filters;\n if (!filters && searchIn.isVisible) {\n filters = searchIn.filter;\n }\n\n updateRecentSearches(suggestion.name, filters);\n\n if (suggestion.suggestionType === SuggestionType.Remote) {\n log({\n type: 'suggestion',\n query: suggestion.name,\n inputQuery: query\n }, {\n workflowPhase: WorkflowPhase.Start\n });\n }\n\n if (suggestion.suggestionType === SuggestionType.Recent) {\n log({\n type: 'recent-search',\n query: suggestion.name,\n inputQuery: query\n }, {\n workflowPhase: WorkflowPhase.Save\n });\n }\n \n Core.AppLinkHelper.trigger(getSearchAppLink(suggestion.name, filters));\n\n onChangeFocus('blur');\n \n return;\n }\n\n function getPresentation(suggestion: Suggestion<BaseObject>) {\n if (suggestion?.suggestionType === SuggestionType.Local)\n return activePresentation;\n\n if (!MasterTypeHelper.isType<Classification>(suggestion, MasterType.Subject)) {\n return activePresentation;\n }\n\n return findAvailablePresentation(suggestion?.presentationId?.toString());\n }\n\n function getSuggestionComponent(\n suggestion: Suggestion<BaseObject & RecentQueryValue>,\n params: Autosuggest.RenderSuggestionParams\n ): JSX.Element {\n return (\n <SearchSuggestion\n query={query}\n suggestion={suggestion}\n isHighlighted={params.isHighlighted}\n activePresentation={getPresentation(suggestion)}\n totalPresentations={availablePresentations.length}\n removeRecentSearch={query => removeRecentSearch(query, suggestion.filters)}\n />\n );\n }\n\n function onSearchSubmit(event: React.FormEvent) {\n event.preventDefault();\n\n if (!query || !query.length)\n return;\n\n searchBarControlsRef.current?.setQuery?.(query);\n\n const currentRoute = ContextService.getCurrentRoute().appLink;\n const isCurrentlyOnSearchRoute = (\n currentRoute.application === AppChannels.SEARCH &&\n currentRoute.action === Actions.Search.HOME\n );\n\n /**\n * If the user wasn't on the /search route when they submitted this search\n * query, then their consecutive search count is 1.\n */\n if (!isCurrentlyOnSearchRoute) {\n consecutiveSearchCount.current = 1;\n } else {\n consecutiveSearchCount.current++;\n }\n\n log({\n type: 'query',\n query,\n inputQuery: query,\n consecutiveSearchCount: consecutiveSearchCount.current\n }, {\n workflowPhase: WorkflowPhase.Start\n });\n Core.AppLinkHelper.trigger(getSearchAppLink(query, searchIn.filter));\n\n updateRecentSearches(query, searchIn.filter);\n searchBarControlsRef.current.blurInput();\n }\n\n function onSuggestionUpdated(suggestion: SuggestionSection<BaseObject & { suggestionType: SuggestionType }>[]) {\n if (!suggestion.length) {\n setHasSuggestions(false);\n return;\n }\n\n setHasSuggestions(true);\n }\n\n function onClickClearInput() {\n searchIn.disable();\n searchBarControlsRef.current.focusInput();\n }\n\n const isSuggestionsVisible = showSuggestions && hasSuggestions;\n\n const initialLocalSuggestions = props.trendingTopics || [];\n\n return (\n <>\n {props.showCloseButton && (\n <IconButton\n svg={ChevronLeftSvg}\n onClick={props.onClickClose}\n className='btn btn-link text-dark'\n />\n )}\n <form\n className={classNames(\n `${styles.searchBar} form-control ps-3 pe-2 d-flex align-items-center position-relative`,\n showSuggestions ? styles.focus : ''\n )}\n onSubmit={onSearchSubmit}\n role='search'\n >\n <SvgContainer\n svg={SearchSvg}\n className='svg-container flex-shrink-0'\n />\n {isCurriculumCodeSearch && (\n <div className='ms-2'>\n <CurriculumCodeTag\n code={currentQuery}\n id={null}\n description={null}\n locationContext={LocationContext.SearchBar}\n />\n </div>\n )}\n\n {searchIn.isVisible && (\n <div className='position-absolute z-1' ref={searchIn.setContainerRefs}>\n <SearchInTag name={searchIn.data.name} />\n </div>\n )}\n <div className='w-100 d-flex align-items-center ps-1'>\n <SearchBar\n // Limits / Flags\n renderAsForm={false}\n searchIconPlacement={false}\n focusInputOnSuggestionClick={true}\n suggestionLimit={LiteSearchSettings.SuggestionLimits}\n activationLength={ACTIVATION_LENGTH}\n debounceTime={props.queryDebounceTime}\n replacePreviousRemoteSuggestions={true}\n alwaysRenderSuggestions={showSuggestions}\n onArrowKeyUpOrDown={onArrowKeyUpOrDown}\n resetQueryOnEscape={false}\n // Show clear input icon if there is a query or search in filter is visible\n showClearInputIcon={query?.length > 0 || searchIn.isVisible}\n\n // Texts\n placeholder={getPhrase('placeholder')}\n suggestionsHeading={getPhrase('suggestionsHeading')}\n recentSearchHeading={getPhrase('recentSearchHeading')}\n \n initialQuery={initialQuery}\n recentSearches={recentSearches}\n initialLocalSuggestions={initialLocalSuggestions}\n onSuggestionDependencies={[recentSearches]}\n\n autoFocusInput={props.autoFocus}\n \n // Handlers / Transformers\n onQueryChange={setQuery}\n handleFetchSuggestions={handleFetchSuggestions}\n formatRemoteSuggestions={formatRemoteSuggestions}\n onSuggestionSelected={onSuggestionSelected}\n onSuggestionUpdated={onSuggestionUpdated}\n getSuggestionComponent={getSuggestionComponent}\n renderSuggestionsOnInputFocus={showSuggestions}\n transformSections={sections => transformSections(query, availablePresentations, sections)}\n onClickClearInput={onClickClearInput}\n shouldUpdateQueryOnSelection={(suggestion => {\n if (suggestion.suggestionType === SuggestionType.Recent)\n return false;\n\n if (suggestion.suggestionType === SuggestionType.Remote &&\n !MasterTypeHelper.isType(suggestion, MasterType.Subject))\n return true;\n\n return false;\n })}\n theme={{\n container: `w-100 h-100 position-relative`,\n suggestionsContainer: classNames('position-absolute', !isSuggestionsVisible && 'd-none'),\n suggestionsContainerOpen: classNames(\n 'bg-white border',\n styles.suggestionsContainerOpen,\n props.showCloseButton && styles.suggestionsContainerOpenWithClearIcon\n ),\n \n suggestionHighlighted: 'bg-light-blue cursor-pointer',\n sectionContainer: '',\n input: classNames('border-0 h-100 bg-transparent', isCurriculumCodeSearch && 'opacity-0', !searchIn.isVisible && 'ps-0'),\n suggestion: 'p-0 rounded-3'\n }}\n renderSectionTitle={(section, sectionTitleClassName) => (\n <SectionTitle\n section={section}\n className={sectionTitleClassName}\n onClickClear={onClearRecentSearchesCache}\n />\n )}\n onBlur={() => {\n onChangeFocus('blur');\n }}\n onFocus={() => onChangeFocus('focus')}\n\n controlsRef={searchBarControlsRef}\n customScrollbarProps={{\n renderView: props => <div {...props} className={`p-3 ${styles.suggestionSections}`}></div>,\n autoHeight: true,\n autoHeightMin: 0,\n autoHeightMax: suggestionsContainerHeight,\n style: {\n position: 'revert-layer',\n width: ''\n }\n }}\n />\n </div>\n </form>\n </>\n );\n}\n","@import '~styles/utils/include-media';\n:local {\n .searchBarContainer {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n left: 0px;\n width: 100%;\n padding-left: 14.75rem;\n }\n\n .searchBarPadding {\n padding-left: map-get($spacers, 3);\n padding-right: 20.75rem;\n\n @include media('<=lg') {\n padding-right: 12rem;\n }\n }\n\n // Hamburger + logo + right container\n // (40 + 280 + 270) / 16 = 36.875\n $nav-width-diff: 36.875rem;\n\n .searchBarWrapper {\n min-width: calc(#{map-get($container-max-widths, xl)} - #{$nav-width-diff});\n width: 100%;\n max-width: 50rem;\n padding: 0;\n border-radius: $border-radius-sm;\n\n @include media('<=xl') {\n min-width: calc(#{map-get($container-max-widths, lg)} - #{$nav-width-diff});\n margin-left: 0;\n }\n\n @include media('<=lg') {\n min-width: calc(#{map-get($container-max-widths, md)} - #{$nav-width-diff});\n margin-left: 0;\n max-width: 100%;\n }\n\n @include media('<=md') {\n min-width: calc(#{map-get($container-max-widths, sm)} - #{$nav-width-diff});\n }\n }\n}","import React from 'react';\n\nimport { Flight } from 'libs/common/flight';\n\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport type { Classification, CurrentUser } from 'libs/shared/interfaces';\n\nimport { LiteConstants } from 'shared/constants/LiteConstants';\nimport { useActivePresentation } from 'shared/hooks/presentations/useActivePresentation';\nimport { useAvailablePresentations } from 'shared/hooks/presentations/useAvailablePresentations';\n\nimport { LiteSearchBarV2 } from 'apps/search/components/search-bar-v2/LiteSearchBarV2';\nimport { SearchRequests } from 'apps/search/flight-requests/SearchRequests';\n\nimport styles from './lite-search-bar-view.module.scss';\n\ninterface LiteSearchBarViewProps {\n collapseSearchBar: boolean;\n expandResponsiveSearchBar: boolean;\n setExpandResponsiveSearchBar: (val: boolean) => void;\n mainRef: React.MutableRefObject<HTMLElement>;\n navRef: React.MutableRefObject<HTMLElement>;\n presentationSlug: string | null;\n}\n\ninterface TrendingTopicsResponse {\n trendingTopics: Classification[];\n}\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function LiteSearchBarView(props: LiteSearchBarViewProps): JSX.Element {\n const { collapseSearchBar, expandResponsiveSearchBar, setExpandResponsiveSearchBar } = props;\n \n const searchbarWrapperRef = React.useRef<HTMLDivElement>(null);\n\n const { activePresentation } = useActivePresentation();\n const { hasCompleted } = useAvailablePresentations();\n\n const { hasPermissions } = usePermissions();\n const isGuest = hasPermissions(PermissionName.GuestExperience);\n\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n\n const presentationId = activePresentation?.id;\n\n const trendingTopicsResponse = Flight.useBasicFetch<TrendingTopicsResponse>(\n presentationId && SearchRequests.trendingTopics(presentationId)\n );\n\n // Public users will experience a slightly longer debounce time to assist with rate limiting\n const queryDebounceTime = currentUser.data?.isAuthenticated ?\n LiteConstants.AUTHENTICATED_SEARCH_QUERY_DEBOUNCE :\n LiteConstants.PUBLIC_SEARCH_QUERY_DEBOUNCE;\n\n const hasLoaded = (\n currentUser.hasCompleted,\n hasCompleted\n );\n \n if (!hasLoaded)\n return <></>;\n\n return (\n <div className={`${styles.searchBarContainer} ${expandResponsiveSearchBar ? 'px-3' : ''} ${collapseSearchBar ? 'd-none' : 'd-block'}`}>\n <div className={`container ${styles.searchBarPadding} ${expandResponsiveSearchBar ? 'px-0 mw-100' : ''}`}>\n <div className={`${styles.searchBarWrapper} d-flex justify-content-center mx-auto`} ref={searchbarWrapperRef}>\n <LiteSearchBarV2\n trendingTopics={trendingTopicsResponse.data?.trendingTopics}\n recentSearchKey={`recent:search:v2:${currentUser.data?.id ?? 'public'}`}\n queryDebounceTime={queryDebounceTime}\n showCloseButton={expandResponsiveSearchBar}\n onClickClose={() => setExpandResponsiveSearchBar(false)}\n autoFocus={expandResponsiveSearchBar}\n mainRef={props.mainRef}\n navRef={props.navRef}\n searchbarWrapperRef={searchbarWrapperRef}\n hasGuestExperience={isGuest}\n presentationSlug={props.presentationSlug}\n />\n </div>\n </div>\n </div>\n );\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Core } from 'libs/common/core';\nimport { Flight } from 'libs/common/flight';\nimport { useInstanceSafe } from 'libs/common/react/hooks/UseInstance';\n\nimport { EntityType, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { NotificationService } from 'libs/shared/apps/notifications/services/NotificationService';\nimport { SharedServices } from 'libs/shared/constants/SharedServices';\nimport { MediaQueryStrings } from 'libs/shared/enums/MediaQueries';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useListenOn } from 'libs/shared/hooks/UseListenOn';\nimport { useMediaQuery } from 'libs/shared/hooks/UseMediaQuery';\nimport { useOrganisationRostering } from 'libs/shared/hooks/useOrganisationRostering';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useSettings } from 'libs/shared/hooks/useSettings';\nimport { Config, CurrentUser } from 'libs/shared/interfaces';\nimport { UserOptionsAppLinks, UserOptionsItem } from 'libs/shared/views/user-options/UserOptionsView';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { usePluginHelper } from 'shared/hooks/use-plugin-helper/usePluginHelper';\n\nconst namespace = 'liteShared.header';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport function useGetUserOptionsAppLinks(): UserOptionsAppLinks {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n\n const { isPlugin, params } = usePluginHelper();\n\n const signUp: Core.AppLink = {\n application: AppChannels.SIGN_UP,\n action: Actions.SignUp.SIGN_UP\n };\n\n const signIn: Core.AppLink = {\n application: AppChannels.DEFAULT,\n action: Actions.Default.CHALLENGE\n };\n\n const currentAppLink = Core.AppLinkHelper.getCurrentAppLink();\n\n /**\n * For unauthenticated users on dashboard home/discover, the post-login redirectUrl\n * should NOT lock the user into a specific presentation slug — after login, the\n * dashboard applink can pick a slug from the user's preferences instead. We strip\n * the slug from args[0] for these specific actions before generating the redirect href.\n *\n * For all other actions, the redirectUrl reflects the current URL exactly.\n */\n const isPublicDashboardHomeOrDiscover = !currentUser.data?.isAuthenticated\n && currentAppLink?.application === AppChannels.DASHBOARD\n && (currentAppLink?.action === Actions.Dashboard.HOME || currentAppLink?.action === Actions.Dashboard.DISCOVER);\n\n const redirectAppLink = isPublicDashboardHomeOrDiscover ?\n { ...currentAppLink, args: [ null, ...(currentAppLink.args ?? []).slice(1) ]} :\n currentAppLink;\n\n const redirectUrl = Core.AppLinkHelper.getHref(redirectAppLink);\n\n if (redirectUrl !== '/')\n signUp.params = { redirectUrl };\n\n /**\n * Important: Assigning params here will override the same behaviour in loginMiddleware.ts\n */\n if (isPublicDashboardHomeOrDiscover)\n signIn.params = { redirectUrl };\n\n return {\n signUp,\n signIn,\n signOut: {\n application: AppChannels.DEFAULT,\n action: Actions.Default.LOG_OUT,\n params: isPlugin ? { redirectUrl: UrlHelper.urlBuilder('/plugin/select', params) } : null\n }\n };\n}\n\nfunction useNotifications(notificationsEnabled: boolean) {\n const [ unreadNotificationCount, setUnreadNotificationCount ] = React.useState<number>();\n\n const notificationService = useInstanceSafe<NotificationService>(\n notificationsEnabled ? SharedServices.Notification : null\n );\n\n const notificationModel = notificationService?.getNotificationsMetadata();\n\n useListenOn(notificationModel, 'change:unreadCount', (model: Core.Model) => {\n setUnreadNotificationCount(model.get('unreadCount'));\n });\n\n return {\n unreadNotificationCount,\n markNotificationsSeen: () => notificationService?.markNotificationsSeen()\n };\n}\n\nexport function useGetUserOptionsItems({\n user,\n config\n}: {\n user: CurrentUser,\n config: Config\n}): UserOptionsItem[] {\n const { hasPermissions } = usePermissions();\n const hasOrgRostering = useOrganisationRostering(user?.customerId ?? '');\n const { inviteColleague, hasClassrooms } = useSettings(null);\n const isMobile = useMediaQuery(MediaQueryStrings.MDDown);\n\n const {\n unreadNotificationCount,\n markNotificationsSeen\n } = useNotifications(hasPermissions(PermissionName.ViewNotifications));\n\n const isGuest = hasPermissions(PermissionName.GuestExperience);\n\n if (!user || !config || isGuest)\n return [];\n\n const items: UserOptionsItem[] = [];\n\n items.push({\n label: getPhrase('settings'),\n order: 10,\n appLink: {\n application: AppChannels.SETTINGS,\n action: Actions.Settings.HOME\n },\n analyticsData: {\n url: Core.AppLinkHelper.getHref({\n application: AppChannels.SETTINGS,\n action: Actions.Settings.HOME\n })\n },\n analyticsOptions: {\n location: LocationContext.UserOptions,\n actionType: UserAction.Click,\n entity: EntityType.Url\n }\n });\n\n if (hasPermissions(PermissionName.ViewWatchHistory)) {\n items.push({\n label: getPhrase('watchHistory'),\n order: 6,\n appLink: {\n application: AppChannels.WATCH_HISTORY,\n action: Actions.WatchHistory.HOME\n },\n analyticsData: {\n url: Core.AppLinkHelper.getHref({\n application: AppChannels.WATCH_HISTORY,\n action: Actions.WatchHistory.HOME\n })\n },\n analyticsOptions: {\n location: LocationContext.UserOptions,\n actionType: UserAction.Click,\n entity: EntityType.Url\n }\n });\n }\n\n if (\n inviteColleague &&\n hasPermissions(PermissionName.ViewInviteColleague) &&\n // hide invite colleague if school has rostering switched on\n !hasOrgRostering\n ) {\n items.push({\n label: getPhrase('inviteColleague'),\n order: 0,\n appLink: {\n application: AppChannels.SIGN_UP,\n action: Actions.SignUp.INVITE_COLLEAGUE\n }\n });\n }\n\n if (!hasPermissions(PermissionName.StudentExperience) && hasPermissions(PermissionName.ViewMyShares)) {\n items.push(\n {\n label: getPhrase('sharedWithMe'),\n order: 5,\n appLink: {\n application: AppChannels.MY_SHARES,\n action: Actions.MyShares.SHARED_WITH_ME\n },\n analyticsData: {\n url: Core.AppLinkHelper.getHref({\n application: AppChannels.MY_SHARES,\n action: Actions.MyShares.SHARED_WITH_ME\n })\n },\n analyticsOptions: {\n location: LocationContext.UserOptions,\n actionType: UserAction.Click,\n entity: EntityType.Url\n }\n }\n );\n }\n\n if (isMobile && hasPermissions(PermissionName.ViewNotifications)) {\n items.push({\n label: getPhrase('notifications'),\n order: 15,\n counter: unreadNotificationCount,\n onClick: markNotificationsSeen,\n appLink: {\n application: AppChannels.NOTIFICATIONS,\n action: Actions.Notifications.HOME\n },\n analyticsData: {\n url: Core.AppLinkHelper.getHref({\n application: AppChannels.NOTIFICATIONS,\n action: Actions.Notifications.HOME\n })\n },\n analyticsOptions: {\n location: LocationContext.UserOptions,\n actionType: UserAction.Click,\n entity: EntityType.Url\n }\n });\n }\n\n if (hasPermissions(PermissionName.StudentExperience) && hasClassrooms) {\n items.push(...[\n {\n label: getPhrase('joinClassroom'),\n order: 1,\n appLink: {\n application: AppChannels.LAUNCHPAD,\n action: Actions.Launchpad.JOIN_CLASSROOM_PROMPT\n },\n analyticsData: {\n url: Core.AppLinkHelper.getHref({\n application: AppChannels.LAUNCHPAD,\n action: Actions.Launchpad.JOIN_CLASSROOM_PROMPT\n })\n },\n analyticsOptions: {\n location: LocationContext.UserOptions,\n actionType: UserAction.Click,\n entity: EntityType.Url\n }\n }\n ]);\n }\n\n return items;\n}\n","@import '~styles/utils/include-media';\n:local {\n .nav {\n position: fixed;\n position: sticky;\n background-color: $white;\n border-bottom: 1px solid $gray-300;\n z-index: 1035;\n padding-right: 0 !important; // This is necessary because bootstrap adds padding styles when a popup is visible\n top: 0;\n height: $cv-nav-height;\n }\n\n // Full wordmark viewBox is 2420×383; derive height from desired width ($cv-nav-logo-width-lg).\n .logo svg {\n display: block;\n height: calc(#{$cv-nav-logo-width-lg} * 383 / 2420);\n width: auto;\n }\n\n .headerLeft {\n z-index: 1;\n\n .hamburger {\n color: $gray-700;\n height: 2rem;\n width: 2rem;\n cursor: pointer;\n display: inline-block;\n\n svg {\n width: 100% !important;\n height: 100% !important;\n }\n }\n }\n\n .searchBarContainer {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n left: 0px;\n width: 100%;\n padding-left: 14.75rem;\n }\n\n .searchBarPadding {\n padding-left: map-get($spacers, 3);\n padding-right: 20.75rem;\n\n @include media('<=lg') {\n padding-right: 12rem;\n }\n }\n\n // Hamburger + logo + right container\n // (40 + 280 + 270) / 16 = 36.875\n $nav-width-diff: 36.875rem;\n\n .searchBarWrapper {\n min-width: calc(#{map-get($container-max-widths, xl)} - #{$nav-width-diff});\n width: 100%;\n max-width: 50rem;\n padding: 0;\n border-radius: $border-radius-sm;\n\n @include media('<=xl') {\n min-width: calc(#{map-get($container-max-widths, lg)} - #{$nav-width-diff});\n margin-left: 0;\n }\n\n @include media('<=lg') {\n min-width: calc(#{map-get($container-max-widths, md)} - #{$nav-width-diff});\n margin-left: 0;\n max-width: 100%;\n }\n\n @include media('<=md') {\n min-width: calc(#{map-get($container-max-widths, sm)} - #{$nav-width-diff});\n }\n }\n\n .deepLink {\n @include media(\"<=450px\") {\n display: none;\n }\n }\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\nimport { Flight } from 'libs/common/flight';\nimport { BackboneViewWrapper } from 'libs/common/react/components/BackboneViewWrapper';\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { ClickDescriptor, EntityType, LocationContext, SignUpDescriptors, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { NotificationHeaderView, NotificationHeaderViewOptions } from 'libs/shared/apps/notifications/views/header/NotificationHeaderView';\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { IconButton } from 'libs/shared/components/icon-button/IconButton';\nimport { useFocusSearchBar } from 'libs/shared/components/search-bar/SearchUtils';\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { ClickViewLogo, ClickViewLogoMark } from 'libs/shared/components/svgs/clickview-logo/ClickViewLogo';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { XmasConstants } from 'libs/shared/constants/XmasConstants';\nimport { useProductTipsContext } from 'libs/shared/context/product-tips-context/ProductTipsContext';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useSettings } from 'libs/shared/hooks/useSettings';\nimport { SearchSvg } from 'libs/shared/images/svg/actions/SearchSvg';\nimport { HamburgerSvg } from 'libs/shared/images/svg/objects/HamburgerSvg';\nimport { SpeechSvg } from 'libs/shared/images/svg/objects/SpeechSvg';\nimport { Config, CurrentUser, Product } from 'libs/shared/interfaces';\nimport { LayoutHelper } from 'libs/shared/utils/LayoutHelper';\nimport { UserOptionsView } from 'libs/shared/views/user-options/UserOptionsView';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { usePluginHelper } from 'shared/hooks/use-plugin-helper/usePluginHelper';\nimport { useDeepLinks } from 'shared/hooks/useDeepLinks';\nimport { LiteRouteHelper } from 'shared/utils/LiteRouteHelper';\nimport { BannerView } from 'shared/views/banner/BannerView';\n\nimport { useIsTertiary } from 'apps/onboarding/hooks/useIsTertiary';\nimport { LiteSearchBarView } from 'apps/search/views/lite-search-bar-view/LiteSearchBarView';\nimport { UploadFileSelect } from 'apps/upload/components/upload-file-select/UploadFileSelect';\n\nimport { useGetUserOptionsAppLinks, useGetUserOptionsItems } from './HeaderViewUtils';\n\nimport styles from './header.module.scss';\n\nconst namespace = 'liteShared.header';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction Logo(): JSX.Element {\n const breakpoints = useBreakpoints();\n\n if (!XmasConstants.IS_XMAS)\n return breakpoints.xs ? <ClickViewLogoMark /> : <ClickViewLogo />;\n\n return breakpoints.xs ?\n <img className='position-absolute start-0' height={41} src={ImageUrls.XMAS_LOGO_MOBILE} /> :\n <img className='h-100' src={ImageUrls.XMAS_LOGO} />;\n}\n\ninterface LogoProps {\n linkLocation: 'discover' | 'student-feed';\n linkType: 'soft' | 'hard';\n presentationSlug: string | null;\n}\n\nfunction LogoAppLink(props: LogoProps): JSX.Element {\n const appLink = props.linkLocation === 'student-feed' ?\n {\n application: AppChannels.STUDENT_FEED,\n action: Actions.StudentFeed.HOME\n } : {\n application: AppChannels.DASHBOARD,\n action: Actions.Dashboard.HOME,\n args: [props.presentationSlug]\n };\n\n return (\n <AppLink\n ariaLabel={getPhrase('logo')}\n appLink={LayoutHelper.shouldAllowLogoClick() ? appLink : undefined}\n forcePageLoad={props.linkType === 'hard'}\n className={`navbar-brand text-hide align-top ${styles.logo} position-relative`}\n analyticsData={{\n url: Core.AppLinkHelper.getHref(appLink)\n }}\n analyticsOptions={{\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.TopNav,\n descriptor: ClickDescriptor.ClickViewLogo\n }}\n >\n <Logo />\n </AppLink>\n );\n}\n\ninterface HeaderViewProps {\n presentationSlug: string | null;\n toggleLeftNav: () => void;\n collapse: boolean;\n showNav: boolean;\n showSearch: boolean;\n mainRef: React.MutableRefObject<HTMLElement>;\n}\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function HeaderView(props: HeaderViewProps): React.ReactElement {\n const [ expandResponsiveSearchBar, setExpandResponsiveSearchBar ] = React.useState(false);\n const { shouldFocus } = useFocusSearchBar();\n const navRef = React.useRef<HTMLDivElement>(null);\n\n const { hasPermissions } = usePermissions();\n\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const { hasShareFlowV2, clickViewLive } = useSettings(null);\n\n const breakpoints = useBreakpoints();\n\n const userOptionsAppLinks = useGetUserOptionsAppLinks();\n const userOptionsItems = useGetUserOptionsItems({\n user: currentUser?.data,\n config: config.data\n });\n\n const { isPlugin } = usePluginHelper();\n const { deepLink, showDeepLink, onClickDeepLink } = useDeepLinks(null, LocationContext.UseAppButton);\n\n const isTertiary = useIsTertiary();\n const isGuest = hasPermissions(PermissionName.GuestExperience);\n\n /*\n * We have temporarily removed the \"switch account\" button from the UI\n * as the sign-up process is tripping-up some of our IP Auth (guest)\n * users. We will revisit this once we have smoothed things over and have\n * gained momentum with out initial 1600 customers in British Columbia (Focused).\n * Talk to Boris before changing or removing this code.\n */\n const showSwitchAccountButton = false; // currentUser.data?.isAuthenticated && isGuest;\n\n const showGiveFeedback =\n currentUser.data?.isAuthenticated &&\n !hasPermissions(PermissionName.StudentExperience) &&\n !isGuest;\n \n const { setProductTipRef: setTutorialVideosTipRef } = useProductTipsContext('tutorial-videos');\n\n React.useEffect(() => {\n if (!breakpoints.sm && !breakpoints.xs && !breakpoints.md && !showDeepLink && expandResponsiveSearchBar)\n setExpandResponsiveSearchBar(false);\n }, [ breakpoints, expandResponsiveSearchBar ]);\n\n /**\n * Expand the search bar if `useFocusSearchBar` is used to focus the search bar.\n */\n React.useEffect(() => {\n if (!shouldFocus)\n return;\n\n setExpandResponsiveSearchBar(true);\n }, [shouldFocus]);\n\n // TODO: Delete this after analytics product is hidden from users with has_insights\n // domain option in permissions API\n function transformProductsList(products: Product[]): Product[] {\n let result = products;\n if (clickViewLive)\n result = result.filter(p => p.id !== ProductId.StreamableLearning);\n\n if (isTertiary && !hasPermissions(PermissionName.ViewSchoolAnalytics))\n result = result.filter(p => p.id !== ProductId.Analytics);\n\n /**\n * Teachers that have share flow v2\n */\n if (hasShareFlowV2 && !hasPermissions(PermissionName.ViewSchoolAnalytics))\n result = result.filter(p => p.id !== ProductId.Analytics);\n\n return result;\n }\n\n const isMobile = breakpoints.sm || breakpoints.xs;\n const showNotifications = hasPermissions(PermissionName.ViewNotifications) &&\n props.showNav && !isPlugin && !isMobile;\n\n const showUpload = hasPermissions(PermissionName.UploadVideo) && !isPlugin && props.showNav && !isMobile;\n const showSearch = props.showSearch && hasPermissions(PermissionName.ViewSearch);\n const logoLinkLocation = hasPermissions(PermissionName.StudentExperience) ?\n 'student-feed' :\n 'discover';\n \n const collapseSearchBar = (showDeepLink || isMobile || breakpoints.md) && !expandResponsiveSearchBar;\n\n /**\n * The logo route behaviour will differ depening on the page context. By default it will always be soft,\n * except where you're viewing a public share as an unauthenticated user.\n */\n const logoLinkType = !currentUser.data?.isAuthenticated && !LiteRouteHelper.hasRegionPrefix() && !props.showNav ?\n 'hard' :\n 'soft';\n\n return (\n <>\n <BannerView />\n <nav className={`navbar navbar-expanded ps-3 w-100 ${styles.nav}`}>\n <div className='container-fluid' ref={navRef}>\n {!expandResponsiveSearchBar && (\n <div className={`d-flex align-items-center justify-content-start ${styles.headerLeft}`}>\n {props.showNav &&\n <button\n onClick={props.toggleLeftNav}\n className='ms-1 me-3'\n aria-label={getPhrase(props.collapse ? 'expand' : 'collapse')}\n >\n <SvgContainer\n svg={HamburgerSvg}\n className={`${styles.hamburger}`}\n />\n </button>\n }\n <LogoAppLink\n linkType={logoLinkType}\n linkLocation={logoLinkLocation}\n presentationSlug={props.presentationSlug}\n />\n {showDeepLink && (\n <a\n className={classNames('btn', styles.deepLink, currentUser.data?.isAuthenticated ? 'btn-dark' : 'btn-outline-dark')}\n href={deepLink}\n onClick={onClickDeepLink}\n >\n <Text namespace={namespace} phrase='useApp' />\n </a>\n )}\n </div>\n )}\n\n {showSearch && (\n <LiteSearchBarView\n collapseSearchBar={collapseSearchBar}\n expandResponsiveSearchBar={expandResponsiveSearchBar}\n setExpandResponsiveSearchBar={(val: boolean) => setExpandResponsiveSearchBar(val)}\n mainRef={props.mainRef}\n navRef={navRef}\n presentationSlug={props.presentationSlug}\n />\n )}\n\n {!expandResponsiveSearchBar && (\n <div className='d-flex align-items-center justify-content-end z-1 me-4 gap-3'>\n {showSearch && collapseSearchBar &&\n <DivButton onClick={() => setExpandResponsiveSearchBar(true)}>\n <SvgContainer svg={SearchSvg} size={SvgContainerSize.Large} title={getPhrase('search')} tooltipPlacement='left' tooltipSpanHack />\n </DivButton>\n }\n\n {showUpload &&\n <UploadFileSelect\n hideButtonText={true}\n canUpload={hasPermissions(PermissionName.UploadVideo)}\n />\n }\n {showNotifications &&\n <Tooltip title={getPhrase('notifications')} spanHack placement='left'>\n <BackboneViewWrapper<NotificationHeaderViewOptions>\n view={NotificationHeaderView}\n options={{ hasLite: true }}\n />\n </Tooltip>\n }\n\n {showGiveFeedback && (\n <div className='position-relative'>\n <IconButton\n svg={SpeechSvg}\n svgSize={isMobile ? SvgContainerSize.Large : SvgContainerSize.Standard}\n className={`btn ${isMobile ? 'border-0' : 'btn-outline-dark'} `}\n appLink={{ application: AppChannels.DEFAULT, action: Actions.Default.GIVE_FEEDBACK }}\n >\n {!isMobile && <Text namespace={namespace} phrase='giveFeedback' />}\n </IconButton>\n </div>\n )}\n\n {showSwitchAccountButton && (\n <AppLink\n appLink={{ application: AppChannels.DEFAULT, action: Actions.Default.SWITCH_ACCOUNT }}\n className='btn btn-outline-dark'\n analyticsData={{\n id: currentUser.data?.id\n }}\n analyticsOptions={{\n actionType: UserAction.Click,\n location: LocationContext.TopNav,\n entity: EntityType.AppLink,\n workflowPhase: WorkflowPhase.Start,\n descriptor: SignUpDescriptors.SwitchAccount\n }}\n >\n {getPhrase('switchAccount')}\n </AppLink>\n )}\n\n {!!config.data &&\n <div className='position-relative' ref={el => setTutorialVideosTipRef(el)}>\n <UserOptionsView\n productId={ProductId.Primary}\n appLinks={userOptionsAppLinks}\n additionalItems={userOptionsItems}\n hideProductList={isPlugin}\n transform={transformProductsList}\n // TODO: Bring this back once we update productboard to show tertiary stuff\n hideWhatsNew={isTertiary}\n displaySignUp\n />\n </div>\n }\n </div>\n )}\n </div>\n \n </nav>\n </>\n );\n}\n","@import '~styles/utils/mixins';\n@import '~styles/utils/include-media';\n\n:local {\n .videoBannerRadius {\n border-radius: $border-radius-lg;\n\n @include media('<=sm') {\n border-radius: 0;\n }\n }\n\n .container {\n height: 500px;\n }\n\n .glassBackground {\n @include bg-blur(10px, true);\n }\n\n .textBox {\n @include media('<=md') {\n width: calc(100% - 2rem) !important;\n }\n }\n\n .videoControls {\n top: 1rem;\n right: 1rem;\n transition: opacity 0.5s ease-in-out;\n z-index: 1020;\n }\n}","import React from 'react';\n\nimport { LocationUtils } from 'libs/common/backbone/core';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { ContentPartnerEventLoggerFn } from 'libs/shared/apps/content-partners/utils/get-content-partner-event-logger/getContentPartnerEventLogger';\nimport { AllVideoBannerControlOptions, VideoBannerControlOption } from 'libs/shared/components/banner-header/enums/VideoBannerControlOption';\nimport { PartnerProfileBannerHeaderHelper } from 'libs/shared/components/banner-header/utils/PartnerProfileBannerHeaderHelper';\nimport { IconButton } from 'libs/shared/components/icon-button/IconButton';\nimport { SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { PauseSvg } from 'libs/shared/images/svg/actions/PauseSvg';\nimport { PlaySvg } from 'libs/shared/images/svg/actions/PlaySvg';\nimport { LinkSvg } from 'libs/shared/images/svg/objects/LinkSvg';\n\nimport styles from '../upsell-advert.module.scss';\n\nconst namespace = 'shared.upsellAdvert';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface UpsellAdvertControlsProps {\n isPlaying: boolean;\n togglePlayPause: () => void;\n className?: string;\n controls?: VideoBannerControlOption[];\n websiteUrl?: string;\n log?: ContentPartnerEventLoggerFn;\n}\n\nexport function UpsellAdvertControls(props: UpsellAdvertControlsProps): JSX.Element {\n const PlayPauseIcon = props.isPlaying ? PauseSvg : PlaySvg;\n\n function onClickWebsiteLink(): void {\n if (!props.websiteUrl) return;\n LocationUtils.PageLoad(props.websiteUrl, true);\n props.log?.({\n type: 'click-video-banner-controls',\n control: 'website-link'\n });\n }\n\n const controls = props.controls || AllVideoBannerControlOptions;\n const showWebsiteLinkControls = PartnerProfileBannerHeaderHelper.showWebsiteLinkControls(\n controls,\n props.websiteUrl,\n false\n );\n\n return (\n <div className={classNames(\n styles.videoControls,\n 'position-absolute d-flex gap-2 ',\n props.isPlaying && 'banner-header-video--controls',\n props.className\n )}>\n {showWebsiteLinkControls && (\n <IconButton\n svg={LinkSvg}\n svgSize={SvgContainerSize.Standard}\n className='bg-gray-200 rounded-circle cursor-pointer'\n onClick={onClickWebsiteLink}\n ariaLabel={getPhrase('viewWebsite')}\n role='button'\n tooltip={getPhrase('viewWebsite')}\n tooltipTrigger={[ 'hover', 'focus' ]}\n />\n )}\n {controls.includes(VideoBannerControlOption.PlayPause) && (\n <IconButton\n svg={PlayPauseIcon}\n svgSize={SvgContainerSize.Standard}\n className='bg-gray-200 rounded-circle cursor-pointer'\n onClick={props.togglePlayPause}\n ariaLabel={props.isPlaying ? getPhrase('pause') : getPhrase('play')}\n role='button'\n tooltip={props.isPlaying ? getPhrase('pause') : getPhrase('play')}\n tooltipTrigger={[ 'hover', 'focus' ]}\n />\n )}\n </div>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { Text } from 'libs/shared/components/text/Text';\n\nimport styles from '../upsell-advert.module.scss';\n\nconst namespace = 'shared.upsellAdvert';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface UpsellAdvertTextBlockProps {\n className?: string;\n appLink?: Core.AppLink;\n ctaAppLink?: Core.AppLink;\n isFreemium?: boolean;\n}\n\nexport function UpsellAdvertTextBlock(props: UpsellAdvertTextBlockProps) {\n return (\n <div className={classNames(\n 'position-absolute p-3 text-white rounded-3 w-50 bottom-0 left-0 m-3 text-shadow',\n styles.glassBackground,\n styles.textBox,\n props.className\n )}>\n <h4>{getPhrase('header')}</h4>\n <div className='text-wrap mb-3'>\n <Text\n namespace={namespace}\n phrase='content'\n />\n &nbsp;\n <AppLink appLink={props.isFreemium ? props.ctaAppLink : props.appLink} tag='a' className='d-inline'>\n <u>\n <Text\n namespace={namespace}\n phrase='infoApplink'\n options={{ product: 'ClickView' }}\n />\n </u>\n </AppLink>\n </div>\n <AppLink className='btn btn-dark' appLink={props.ctaAppLink}>\n {props.isFreemium ? getPhrase('startTrial') : getPhrase('requestAccess')}\n </AppLink>\n </div>\n );\n}\n","import React from 'react';\n\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { Video } from 'libs/shared/components/video/Video';\n\nimport styles from '../upsell-advert.module.scss';\n\ninterface UpsellAdvertVideoProps {\n videoUrl?: string;\n videoRef?: React.RefObject<HTMLVideoElement>;\n className?: string;\n}\n\nexport function UpsellAdvertVideo(props: UpsellAdvertVideoProps): JSX.Element {\n return (\n <div className={classNames('position-absolute top-0 start-0 w-100 h-100 overflow-hidden', styles.videoBannerRadius, props.className)}>\n <Video ref={props.videoRef} autoPlay muted controls={false} loop={true} className='w-100 h-100 object-fit-cover position-relative'>\n <source src={props.videoUrl} type='video/mp4' />\n </Video>\n </div>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\n\nimport { AllVideoBannerControlOptions, VideoBannerControlOption } from 'libs/shared/components/banner-header/enums/VideoBannerControlOption';\nimport { useVideoControls } from 'libs/shared/components/video/Video';\n\nimport { UpsellAdvertControls } from 'shared/components/upsell-header/components/upsell-advert/components/UpsellAdvertControls';\nimport { UpsellAdvertTextBlock } from 'shared/components/upsell-header/components/upsell-advert/components/UpsellAdvertTextBlock';\nimport { UpsellAdvertVideo } from 'shared/components/upsell-header/components/upsell-advert/components/UpsellAdvertVideo';\n\nimport styles from './upsell-advert.module.scss';\n\ninterface UpsellAdvertProps {\n className?: string;\n videoUrl?: string;\n imageUrl?: string;\n videoRef?: React.RefObject<HTMLVideoElement>;\n appLink?: Core.AppLink;\n ctaAppLink?: Core.AppLink;\n videoClassName?: string;\n isFreemium?: boolean;\n}\n\nexport function UpsellAdvert(props: UpsellAdvertProps) {\n const {\n videoRef,\n isPlaying,\n isFinished,\n loaded,\n togglePlayPause\n } = useVideoControls({\n addDelayOnLoad: 2000\n });\n\n const containerStyle: React.CSSProperties = {\n backgroundImage: `url('${props.imageUrl}')`,\n backgroundSize: 'cover',\n backgroundPosition: '70% center',\n height: '500px',\n width: 'auto'\n };\n\n const isVideoVisible = loaded && !isFinished;\n\n const controls = isVideoVisible ?\n AllVideoBannerControlOptions :\n [VideoBannerControlOption.PlayPause];\n\n return (\n <div className={props.className}>\n <div className={`position-relative ${styles.videoBannerRadius} ${styles.container}`}>\n <UpsellAdvertVideo videoRef={videoRef} videoUrl={props.videoUrl}/>\n {(!loaded || !isPlaying) && <div className={`${styles.videoBannerRadius} position-relative`} style={containerStyle}></div>}\n <UpsellAdvertTextBlock appLink={props.appLink} ctaAppLink={props.ctaAppLink} className='mb-3' isFreemium={props.isFreemium}/>\n {props.videoUrl && loaded &&\n <UpsellAdvertControls\n isPlaying={isPlaying}\n togglePlayPause={togglePlayPause}\n controls={controls}\n />}\n </div>\n </div>\n );\n}\n","export enum UpsellLevel {\n ClickView = 1,\n ClickViewLive = 2\n}\n\nexport enum UpsellVersion {\n Freemium = 1,\n Timed = 2\n}\n","@import '~styles/utils/include-media';\n\n:local {\n $padding-sm: map-get($spacers, 3);\n\n .progressBar {\n height: 1.5rem;\n width: 12rem;\n\n .background {\n background-color: rgba(234, 234, 234, 1);\n }\n }\n\n .stickyBanner {\n position: relative;\n z-index: 1021;\n width: 100%;\n max-width: map-get($grid-breakpoints, xl);\n margin: 0 auto;\n }\n\n .normalSizeSticky {\n &::before {\n content: '';\n position: absolute;\n left: 0;\n right: 0;\n bottom: 100%;\n height: calc(max($cv-nav-height, 5rem));\n }\n }\n\n @include media('<=sm') {\n .progressBar {\n top: ($padding-sm * 2) + $cv-svg-size;\n }\n }\n}","import React from 'react';\n\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { StickyBannerProps } from 'shared/components/sticky-banner/StickyBanner';\n\nimport styles from '../sticky-banner.module.scss';\n\nexport const MID_THRESHOLD = 60;\n\nexport function LeftDecorator(props: StickyBannerProps): JSX.Element {\n if (props.isSmScreen)\n return <></>;\n\n switch (props.type) {\n case 'icon':\n const { iconBgClass, roundIcon, Icon } = props;\n return (\n <div className={classNames(\n 'flex-shrink-0',\n iconBgClass,\n roundIcon ? 'rounded-circle' : 'rounded'\n )}>\n <Icon/>\n </div>\n );\n case 'progress-bar':\n const progressBarPercentage = Math.max(props.value / props.maxValue * 100, 0);\n const bgColor = progressBarPercentage > MID_THRESHOLD ? 'bg-green' : 'bg-yellow';\n\n return (\n <div className={classNames(styles.progressBar, 'rounded-pill bg-white d-flex align-items-center border border-black')}>\n <div className={classNames('flex-grow-1 h-50 rounded-pill px-0', styles.background)}>\n <div className={classNames('h-100 rounded-pill px-0', bgColor)} style={{ width: `${progressBarPercentage}%` }} />\n </div>\n </div>\n );\n case 'text-pill':\n return (\n <div className='rounded-pill px-2 text-nowrap bg-white border border-dark'>\n {props.pillText}\n </div>\n );\n }\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { AnalyticsOptions, HashObject } from 'libs/analytics/interfaces';\n\nimport { ActionButton } from 'libs/shared/components/actions/ActionButton';\nimport { SvgIcon } from 'libs/shared/utils/SvgHelper';\n\nimport { LeftDecorator } from 'shared/components/sticky-banner/components/LeftDecorator';\n\nimport styles from './sticky-banner.module.scss';\n\ntype StickyBannerType = 'progress-bar' | 'text-pill' | 'icon';\n\ninterface CtaProps {\n analyticsOptions?: AnalyticsOptions;\n analyticsData?: HashObject;\n appLink?: Core.AppLink;\n text: string;\n className?: string;\n onClick?: () => void;\n svg?: SvgIcon;\n disabled?: boolean;\n}\n\nfunction Cta(props: CtaProps) {\n return (\n <ActionButton\n className={props.className}\n analyticsOptions={props.analyticsOptions}\n analyticsData={props.analyticsData}\n appLink={props.appLink}\n onClick={props.onClick}\n svg={props.svg}\n disabled={props.disabled}\n >\n {props.text}\n </ActionButton>\n );\n}\n\ninterface WrapperProps {\n isSmScreen: boolean;\n}\n\nfunction StickyBannerWrapper(props: React.PropsWithChildren<WrapperProps>) {\n if (props.isSmScreen) {\n return (\n // some display may require the banner to ignore document flow\n <div className={`${styles.stickyBanner} px-3`}>\n {props.children}\n </div>\n );\n }\n\n return (\n <div className={`${styles.stickyBanner} ${styles.normalSizeSticky} px-4`}>\n <div className='rounded-bottom-lg'>\n {props.children}\n </div>\n </div>\n );\n}\n\ninterface BaseStickyBannerProps {\n type: StickyBannerType;\n className?: string;\n borderClass?: string;\n lightBgClass?: string;\n\n primaryAnalyticsOptions?: AnalyticsOptions;\n primaryAnalyticsData?: HashObject;\n primaryAppLink?: Core.AppLink;\n primaryText?: string;\n primaryClassName?: string;\n primaryOnClick?: () => void;\n primaryIcon?: SvgIcon;\n primaryDisabled?: boolean;\n \n secondaryAnalyticsData?: HashObject;\n secondaryAnalyticsOptions?: AnalyticsOptions;\n secondaryAppLink?: Core.AppLink;\n secondaryText?: string;\n secondaryClassName?: string;\n secondaryOnClick?: () => void;\n\n swapCtaOrder?: boolean;\n isSmScreen?: boolean;\n infoText?: string;\n}\n\nexport function StickyBanner(props: StickyBannerProps) {\n const {\n className,\n borderClass,\n lightBgClass,\n\n primaryAnalyticsOptions,\n primaryAnalyticsData,\n primaryAppLink,\n primaryText,\n primaryClassName,\n primaryOnClick,\n primaryIcon,\n primaryDisabled,\n\n secondaryAnalyticsData,\n secondaryAnalyticsOptions,\n secondaryAppLink,\n secondaryText,\n secondaryClassName,\n secondaryOnClick,\n\n swapCtaOrder,\n isSmScreen,\n infoText\n } = props;\n\n return (\n <StickyBannerWrapper isSmScreen={isSmScreen}>\n <div\n className={classNames(\n `border rounded-3 p-3 d-flex align-items-center justify-content-between gap-3`,\n borderClass,\n lightBgClass,\n className\n )}\n >\n <div className='d-flex align-items-center gap-3 overflow-hidden'>\n <LeftDecorator {...props} />\n <span className='d-inline-block text-wrap' dangerouslySetInnerHTML={{ __html: infoText }} />\n </div>\n \n <div className={classNames('d-flex align-items-center gap-3 flex-shrink-0', swapCtaOrder && 'flex-row-reverse')}>\n {\n secondaryText &&\n <Cta\n analyticsOptions={secondaryAnalyticsOptions}\n analyticsData={secondaryAnalyticsData}\n appLink={secondaryAppLink}\n text={secondaryText}\n className={secondaryClassName || 'btn btn-outline-dark'}\n onClick={secondaryOnClick}\n />\n }\n {\n primaryText &&\n <Cta\n analyticsOptions={primaryAnalyticsOptions}\n analyticsData={primaryAnalyticsData}\n appLink={primaryAppLink}\n text={primaryText}\n className={primaryClassName || 'btn btn-dark'}\n onClick={primaryOnClick}\n svg={primaryIcon}\n disabled={primaryDisabled}\n />\n }\n </div>\n </div>\n </StickyBannerWrapper>\n );\n}\n\ninterface IconStickyBannerProps extends BaseStickyBannerProps {\n type: 'icon';\n iconBgClass?: string;\n Icon: React.ComponentType;\n roundIcon?: boolean;\n}\n\ninterface ProgressBarStickyBannerProps extends BaseStickyBannerProps {\n type: 'progress-bar';\n value: number;\n maxValue: number;\n}\n\ninterface PillStickyBannerProps extends BaseStickyBannerProps {\n type: 'text-pill';\n pillText: string;\n}\n\nexport type StickyBannerProps =\n IconStickyBannerProps |\n ProgressBarStickyBannerProps |\n PillStickyBannerProps;\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { IconCircle } from 'libs/shared/components/icon-circle/IconCircle';\nimport { SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { CrownSvg } from 'libs/shared/images/svg/objects/CrownSvg';\n\ninterface UpsellBadgeProps {\n className?: string;\n svgSize?: SvgContainerSize;\n showTooltip?: boolean;\n}\n\nconst getPhrase = LanguageService.encloseNamespace('shared.upsellBadge');\n\nexport function UpsellBadge(props: UpsellBadgeProps) {\n return (\n <Tooltip title={props.showTooltip ? getPhrase('tooltipText') : null} spanHack>\n <div className={props.className}>\n <IconCircle\n svgSize={props.svgSize ?? SvgContainerSize.Standard}\n svg={CrownSvg}\n textVariant='primary'\n svgWrapperClassName='bg-white border border-gray d-flex items-center justify-content-center'\n />\n </div>\n </Tooltip>\n );\n}\n",":local {\n .successSvg {\n svg {\n color: $green-500;\n }\n }\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { EntityType, LocationContext, UpsellBannerDescriptor, UserAction } from 'libs/analytics/interfaces';\n\nimport { PresentationType } from 'libs/shared/enums/PresentationType';\nimport { UpsellLevel } from 'libs/shared/enums/UpsellType';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { CheckCircleSvg } from 'libs/shared/images/svg/status/CheckCircleSvg';\nimport { Presentation } from 'libs/shared/interfaces';\nimport { SvgIcon } from 'libs/shared/utils/SvgHelper';\n\nimport { StickyBanner } from 'shared/components/sticky-banner/StickyBanner';\nimport { UpsellBadge } from 'shared/components/upsell-badge/UpsellBadge';\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { OnClickRequestAccessButton } from 'shared/hooks/useRequestAccessApplink';\nimport { UpsellOutcome } from 'shared/utils/UpsellHelper';\n\nimport styles from './upsell-banner.module.scss';\n\nconst namespace = 'shared.upsellBanner';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface UpsellBannerProps {\n className?: string;\n activePresentation?: Presentation;\n preferredPresentation?: Presentation;\n upsellOutcome?: UpsellOutcome;\n isFreemium: boolean;\n borderClass?: string;\n requestAccessApplink: Core.AppLink | null;\n onClickRequestAccessButton: OnClickRequestAccessButton;\n}\n\nfunction getMappedLightBackgroundColourClass(previewLevel: UpsellLevel): string {\n switch (previewLevel) {\n case UpsellLevel.ClickView: return 'bg-light-yellow';\n case UpsellLevel.ClickViewLive: return 'bg-light-green';\n default: return 'bg-light-green';\n }\n}\n\nfunction getMappedBorderColourClass(previewLevel: UpsellLevel): string {\n switch (previewLevel) {\n case UpsellLevel.ClickView: return 'border-yellow';\n case UpsellLevel.ClickViewLive: return 'border-green';\n default: return 'border-green';\n }\n}\n\ninterface PrimaryButtonProps {\n primaryText: string;\n primaryAppLink?: Core.AppLink | null;\n primaryAnalyticsData?: Record<string, unknown>;\n primaryAnalyticsOptions?: Record<string, unknown>;\n primaryOnClick?: () => void;\n primaryIcon?: SvgIcon;\n primaryDisabled?: boolean;\n primaryClassName?: string;\n}\n\nexport function UpsellBanner(props: UpsellBannerProps) {\n const [ requestState, setRequestState ] = React.useState<'idle' | 'loading' | 'success' | 'error'>('idle');\n \n const alerts = useAlerts();\n\n const previewLevel =\n props.upsellOutcome?.upsellPresentationType === PresentationType.StreamableLearning ?\n UpsellLevel.ClickViewLive :\n UpsellLevel.ClickView;\n const borderClass = `${getMappedBorderColourClass(previewLevel)} ${props.borderClass}`;\n const lightBackgroundClass = getMappedLightBackgroundColourClass(previewLevel);\n\n const altProductName = previewLevel === UpsellLevel.ClickView ? getPhrase('primary') : getPhrase('live');\n\n const productInfoAppLink: Core.AppLink = {\n application: AppChannels.DEFAULT,\n action: Actions.Default.UPSELL_PRODUCT_INFO,\n args: [props.activePresentation?.type]\n };\n\n const breakpoints = useBreakpoints();\n\n const productInfoAnalyticsOptions = {\n actionType: UserAction.Click,\n entity: EntityType.AppLink,\n location: LocationContext.UpsellBanner,\n descriptor: UpsellBannerDescriptor.ProductInfo\n };\n\n const startTrialAnalyticsOptions = {\n actionType: UserAction.Click,\n entity: EntityType.AppLink,\n location: LocationContext.UpsellBanner,\n descriptor: UpsellBannerDescriptor.StartTrial\n };\n\n const analyticsData = {\n activePresentationId: props.activePresentation?.id,\n activePresentationLevel: props.activePresentation?.learningLevel,\n targetPresentationType: props.upsellOutcome?.upsellPresentationType\n };\n\n async function onClickRequestAccess() {\n await props.onClickRequestAccessButton({ setRequestState: state => {\n if (state === 'error')\n alerts.error(getPhrase('errorRequestingAccess'));\n \n setRequestState(state);\n } });\n }\n\n function getPrimaryButtonProps() {\n const primaryButtonProps: PrimaryButtonProps = {\n primaryText:\n props.isFreemium ?\n getPhrase('freemiumPrimary') :\n getPhrase('timedTrialPrimary'),\n primaryAnalyticsData: analyticsData,\n primaryAnalyticsOptions: startTrialAnalyticsOptions,\n primaryOnClick: onClickRequestAccess\n };\n\n if (requestState === 'loading') {\n primaryButtonProps.primaryDisabled = true;\n primaryButtonProps.primaryText = getPhrase('loading');\n }\n\n if (requestState === 'success') {\n primaryButtonProps.primaryDisabled = true;\n primaryButtonProps.primaryIcon = CheckCircleSvg;\n primaryButtonProps.primaryText = getPhrase('requestSent');\n primaryButtonProps.primaryClassName = classNames('btn btn-dark', styles.successSvg);\n }\n\n return primaryButtonProps;\n }\n\n const primaryButtonProps = getPrimaryButtonProps();\n\n const secondaryButtonProps = {\n secondaryText:\n breakpoints.xs || breakpoints.sm || props.isFreemium ?\n null :\n getPhrase('infoApplink', {\n product: altProductName\n }),\n secondaryAppLink: productInfoAppLink,\n secondaryAnalyticsData: analyticsData,\n secondaryAnalyticsOptions: productInfoAnalyticsOptions\n };\n\n function getInfoTextType() {\n if (props.isFreemium && previewLevel === UpsellLevel.ClickView)\n return 'infoClickViewFreemium';\n\n if (props.isFreemium)\n return 'infoLiveFreemium';\n\n if (previewLevel === UpsellLevel.ClickViewLive)\n return 'infoLive';\n\n return 'infoClickView';\n }\n\n return (\n <StickyBanner\n type='icon'\n className={props.className}\n borderClass={borderClass}\n lightBgClass={lightBackgroundClass}\n Icon={UpsellBadge}\n roundIcon\n swapCtaOrder\n \n isSmScreen={breakpoints.xs}\n\n infoText={getPhrase(getInfoTextType())}\n\n {...primaryButtonProps}\n {...secondaryButtonProps}\n />\n );\n}\n","@import '~styles/utils/include-media';\n\n:local {\n .stickyBanner {\n position: sticky;\n top: calc(max($cv-nav-height, 5rem));\n z-index: 1021;\n }\n\n .normalSizeSticky {\n &::before {\n content: '';\n position: absolute;\n left: 0;\n right: 0;\n bottom: 100%;\n height: calc(max($cv-nav-height, 5rem));\n background-color: $body-bg;\n }\n }\n\n .upsellBanner {\n width: 100%;\n max-width: map-get($grid-breakpoints, xl);\n margin: 0 auto;\n }\n\n .container {\n @include media('<=xl') {\n max-width: 100%;\n }\n }\n\n .smScreenVideo {\n z-index: 1018;\n }\n\n .smScreenContainer {\n height: 500px;\n margin-bottom: -1rem;\n margin-top: -7.5rem;\n }\n\n .advertContainer {\n transform: translateY(-1rem);\n }\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\n\nimport { HardCoded } from 'libs/shared/constants/HardCoded';\nimport { PresentationType } from 'libs/shared/enums/PresentationType';\nimport { Breakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { Presentation } from 'libs/shared/interfaces';\n\nimport { UpsellAdvert } from 'shared/components/upsell-header/components/upsell-advert/UpsellAdvert';\nimport { UpsellBanner } from 'shared/components/upsell-header/components/upsell-banner/UpsellBanner';\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { OnClickRequestAccessButton } from 'shared/hooks/useRequestAccessApplink';\nimport { UpsellKind, useUpsellContext } from 'shared/hooks/useUpsellContext';\n\nimport styles from './upsell-header.module.scss';\n\ninterface UpsellHeaderViewProps {\n breakpoints: Breakpoints;\n upsellContext: ReturnType<typeof useUpsellContext>;\n activePresentation?: Presentation;\n allPreferredPresentations: Presentation[];\n isAuthenticated?: boolean;\n showVideo: boolean;\n requestAccessApplink: Core.AppLink | null;\n onClickRequestAccessButton: OnClickRequestAccessButton;\n}\n\nexport function UpsellHeader(props: UpsellHeaderViewProps) {\n const {\n breakpoints,\n upsellContext,\n activePresentation,\n allPreferredPresentations,\n isAuthenticated,\n showVideo,\n requestAccessApplink,\n onClickRequestAccessButton\n } = props;\n \n const isFreemium = [ UpsellKind.StartLiveTrial, UpsellKind.StartCvTrial ].includes(upsellContext?.upsellKind);\n\n const productInfoAppLink: Core.AppLink = {\n application: AppChannels.DEFAULT,\n action: Actions.Default.UPSELL_PRODUCT_INFO,\n args: [activePresentation?.type]\n };\n\n const isSubjectUpsell = upsellContext.isLoaded &&\n upsellContext?.upsellPresentationType === PresentationType.Subject;\n\n const staticImageUrl = isSubjectUpsell ?\n ImageUrls.Upsell.CLICKVIEW_ADVERT :\n ImageUrls.Upsell.CLICKVIEW_LIVE_ADVERT;\n\n const videoUrl = isSubjectUpsell ?\n HardCoded.UpsellVideo.CLICKVIEW :\n undefined;\n\n if (!isAuthenticated)\n return null;\n\n if (breakpoints.xs) {\n return (\n <>\n <UpsellBanner\n className='d-inline-block'\n upsellOutcome={upsellContext}\n activePresentation={activePresentation}\n preferredPresentation={\n allPreferredPresentations.filter(p => p.type !== upsellContext.upsellPresentationType)[0]\n }\n isFreemium={isFreemium}\n requestAccessApplink={requestAccessApplink}\n onClickRequestAccessButton={onClickRequestAccessButton}\n />\n {\n showVideo &&\n <div className={`position-relative ${styles.smScreenContainer}`}>\n <div className={`position-sticky ${styles.advertContainer}`}>\n <UpsellAdvert\n className={`${styles.upsellBanner} ${styles.smScreenVideo}`}\n videoUrl={videoUrl}\n appLink={productInfoAppLink}\n ctaAppLink={requestAccessApplink}\n videoClassName='rounded-0'\n imageUrl={staticImageUrl}\n isFreemium={isFreemium}\n />\n </div>\n </div>\n }\n </>\n );\n }\n\n return (\n <>\n <UpsellBanner\n className='d-inline-block w-100'\n upsellOutcome={upsellContext}\n activePresentation={activePresentation}\n preferredPresentation={\n allPreferredPresentations.filter(p => p.type !== upsellContext.upsellPresentationType)[0]\n }\n isFreemium={isFreemium}\n requestAccessApplink={requestAccessApplink}\n onClickRequestAccessButton={onClickRequestAccessButton}\n />\n {\n showVideo &&\n <UpsellAdvert\n className={`container mt-4 px-4 pb-0 ${styles.container}`}\n videoUrl={videoUrl}\n appLink={productInfoAppLink}\n ctaAppLink={requestAccessApplink}\n imageUrl={staticImageUrl}\n isFreemium={isFreemium}\n />\n }\n </>\n );\n}\n","import { AppLink, AppLinkHelper } from 'libs/common/backbone/core';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { BannerWhiteList, WhiteListOptions } from 'shared/views/header-banner/BannerWhiteList';\n\nexport const BannerWhiteListHelper = {\n createBannerOptions(appLinkWithOptions: BannerWhiteList[]): HashObject<WhiteListOptions> {\n const lookupTable: HashObject =\n appLinkWithOptions.reduce((prev: HashObject, current: BannerWhiteList) => {\n prev[AppLinkHelper.getAppLinkString(current.appLink)] = current.options || {};\n return prev;\n }, {});\n\n return lookupTable;\n },\n\n getBannerOptions(appLink: AppLink, lookupTable: HashObject<WhiteListOptions>): WhiteListOptions {\n const key = AppLinkHelper.getAppLinkString(appLink);\n\n return lookupTable?.[key];\n }\n};\n","import { Core } from 'libs/common/core';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { BannerWhiteListHelper } from 'shared/views/header-banner/BannerWhiteListHelper';\n\nexport interface WhiteListOptions {\n showVideo?: boolean;\n}\n\nexport interface BannerWhiteList {\n appLink: Core.AppLink;\n options?: WhiteListOptions;\n}\n\nexport const TRIAL_BANNER_WHITELIST: HashObject<WhiteListOptions> = BannerWhiteListHelper.createBannerOptions([\n { appLink: { application: AppChannels.DASHBOARD, action: Actions.Dashboard.HOME } },\n { appLink: { application: AppChannels.DASHBOARD, action: Actions.Dashboard.DASHBOARD } },\n { appLink: { application: AppChannels.DASHBOARD, action: Actions.Dashboard.DISCOVER } },\n\n { appLink: { application: AppChannels.CALENDAR, action: Actions.Calendar.CALENDAR } },\n { appLink: { application: AppChannels.CALENDAR, action: Actions.Calendar.CALENDAR_MONTH } },\n\n { appLink: { application: AppChannels.MOVIES_AND_TV, action: Actions.MoviesAndTv.HOME } },\n\n { appLink: { application: AppChannels.VIDEOS, action: Actions.Videos.VIDEO_CLIPS } },\n { appLink: { application: AppChannels.VIDEOS, action: Actions.Videos.VIDEO_INTERACTIVES } },\n { appLink: { application: AppChannels.VIDEOS, action: Actions.Videos.PLAY_VIDEO } },\n\n { appLink: { application: AppChannels.CLIPS, action: Actions.Clips.PLAY_CLIP } },\n { appLink: { application: AppChannels.CLIPS, action: Actions.Clips.CLIP_CLIPS } },\n { appLink: { application: AppChannels.CLIPS, action: Actions.Clips.CLIP_INTERACTIVES } },\n\n { appLink: { application: AppChannels.INTERACTIVES, action: Actions.Interactives.VIEW_INTERACTIVE } },\n\n { appLink: { application: AppChannels.MY_VIDEOS, action: Actions.MyVideos.MY_VIDEOS } },\n { appLink: { application: AppChannels.MY_VIDEOS, action: Actions.MyVideos.MY_VIDEOS_FOLDER } },\n\n { appLink: { application: AppChannels.PLAYLISTS, action: Actions.Playlists.HOME } },\n\n { appLink: { application: AppChannels.MY_SHARES, action: Actions.MyShares.HOME } },\n \n { appLink: { application: AppChannels.CLASSROOMS, action: Actions.Classrooms.HOME } },\n { appLink: { application: AppChannels.CLASSROOMS, action: Actions.Classrooms.VIEW_ALL } },\n { appLink: { application: AppChannels.CLASSROOMS, action: Actions.Classrooms.OPEN_CLASSROOMS } }\n]);\n\nexport const UPSELL_BANNER_WHITELIST: HashObject<WhiteListOptions> = BannerWhiteListHelper.createBannerOptions([\n {\n appLink: { application: AppChannels.DASHBOARD, action: Actions.Dashboard.HOME },\n options: { showVideo: true }\n },\n {\n appLink: { application: AppChannels.DASHBOARD, action: Actions.Dashboard.DASHBOARD },\n options: { showVideo: true }\n },\n {\n appLink: { application: AppChannels.DASHBOARD, action: Actions.Dashboard.DISCOVER },\n options: { showVideo: true }\n },\n {\n appLink: { application: AppChannels.DASHBOARD, action: Actions.Dashboard.PARTNERS },\n options: { showVideo: true }\n },\n\n {\n appLink: { application: AppChannels.CALENDAR, action: Actions.Calendar.CALENDAR },\n options: { showVideo: false }\n },\n {\n appLink: { application: AppChannels.CALENDAR, action: Actions.Calendar.CALENDAR_MONTH },\n options: { showVideo: false }\n },\n {\n appLink: { application: AppChannels.CALENDAR, action: Actions.Calendar.SPECIAL_EVENT_LIST },\n options: { showVideo: false }\n },\n\n {\n appLink: { application: AppChannels.MOVIES_AND_TV, action: Actions.MoviesAndTv.HOME },\n options: { showVideo: false }\n },\n {\n appLink: { application: AppChannels.MOVIES_AND_TV, action: Actions.MoviesAndTv.COMPANY_DASHBOARD },\n options: { showVideo: false }\n }\n]);\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EntityType, FreemiumBannerDescriptor, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { Presentation } from 'libs/shared/interfaces';\n\nimport { MID_THRESHOLD } from 'shared/components/sticky-banner/components/LeftDecorator';\nimport { StickyBanner } from 'shared/components/sticky-banner/StickyBanner';\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nimport { RequestAccessApplinkHelper } from 'apps/sign-up/utils/RequestAccessApplinkHelper';\n\nconst getPhrase = LanguageService.encloseNamespace('shared.freemiumBanner');\n\nfunction getStreamText(percentage: number, hasReferral: boolean) {\n if (percentage === 100)\n return 'streamsFull';\n \n if (percentage > MID_THRESHOLD)\n return 'streamsHigh';\n\n if (percentage > 0 && hasReferral)\n return 'streamsMid';\n\n if (percentage > 0)\n return 'streamsMidNoReferrals';\n\n if (hasReferral)\n return 'streamsEmpty';\n\n return 'streamsEmptyNoReferrals';\n}\n\nfunction getBackgroundColorClass(percentage: number): string {\n if (percentage > MID_THRESHOLD)\n return 'bg-light-green';\n\n if (percentage > 0)\n return 'bg-light-yellow';\n\n return 'bg-light-red';\n}\n\nfunction getBorderColorClass(percentage: number): string {\n if (percentage > MID_THRESHOLD)\n return 'border-green';\n\n if (percentage > 0)\n return 'border-yellow';\n\n return 'border-red';\n}\n\ninterface FreemiumBannerProps {\n className: string;\n activePresentation: Presentation;\n streamQuota: number;\n hasReferral: boolean;\n maxStream: number;\n canManageUpsell: boolean;\n}\n\nexport function FreemiumBanner(props: FreemiumBannerProps) {\n const breakpoints = useBreakpoints();\n \n const inviteAnalyticsOptions = {\n actionType: UserAction.Click,\n entity: EntityType.AppLink,\n location: LocationContext.FreemiumBanner,\n descriptor: FreemiumBannerDescriptor.Invite\n };\n\n const requestAccessAnalyticsOptions = {\n actionType: UserAction.Click,\n entity: EntityType.AppLink,\n location: LocationContext.FreemiumBanner,\n descriptor: FreemiumBannerDescriptor.RequestFullAccess\n };\n \n const analyticsData = {\n activePresentationId: props.activePresentation?.id,\n activePresentationLevel: props.activePresentation?.learningLevel\n };\n\n const streamQuotaPercentage = (props.streamQuota / props.maxStream) * 100;\n\n const primaryButtonProps = {\n primaryText: getPhrase('requestAccess'),\n primaryAppLink: RequestAccessApplinkHelper.requestFullAccess(),\n primaryAnalyticsData: analyticsData,\n primaryAnalyticsOptions: requestAccessAnalyticsOptions,\n primaryClassName: streamQuotaPercentage > 0 ? 'btn btn-outline-dark' : 'btn btn-dark'\n };\n\n const secondaryButtonProps = {\n secondaryText:\n breakpoints.xs || breakpoints.sm ?\n null :\n getPhrase('invite'),\n secondaryAppLink: {\n application: AppChannels.SIGN_UP,\n action: Actions.SignUp.INVITE_COLLEAGUE\n },\n secondaryAnalyticsData: analyticsData,\n secondaryAnalyticsOptions: inviteAnalyticsOptions,\n secondaryClassName: streamQuotaPercentage > 0 ? 'btn btn-dark' : 'btn btn-outline-dark'\n };\n\n const infoTextProps = {\n infoText: getPhrase(getStreamText(\n streamQuotaPercentage, // calculate by percentage\n props.hasReferral\n ), {\n streamQuota: props.streamQuota\n }),\n isSmScreen: breakpoints.xs\n };\n\n return (\n <StickyBanner\n type='progress-bar'\n value={props.streamQuota}\n maxValue={props.maxStream}\n className={props.className}\n borderClass={getBorderColorClass(streamQuotaPercentage)}\n lightBgClass={getBackgroundColorClass(streamQuotaPercentage)}\n swapCtaOrder={streamQuotaPercentage <= 0}\n \n {...infoTextProps}\n\n {...primaryButtonProps}\n {...secondaryButtonProps}\n />\n );\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { EntityType, LocationContext, TrialBannerDescriptor, UserAction } from 'libs/analytics/interfaces';\n\nimport { useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { Presentation } from 'libs/shared/interfaces';\n\nimport { StickyBanner } from 'shared/components/sticky-banner/StickyBanner';\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nimport { RequestAccessApplinkHelper } from 'apps/sign-up/utils/RequestAccessApplinkHelper';\n\nconst getPhrase = LanguageService.encloseNamespace('shared.trialBanner');\nconst THRESHOLD_DAYS_LEFT = 10;\n\nfunction getText(daysLeft: number, hasReferral: boolean) {\n if (daysLeft > 30)\n return 'expiryDate';\n \n if (daysLeft > 0 && hasReferral)\n return 'daysLeftWithReference';\n\n return 'daysLeft';\n}\n\nfunction getBackgroundColorClass(timeLeft: number): string {\n if (timeLeft > THRESHOLD_DAYS_LEFT)\n return 'bg-light-green';\n\n if (timeLeft > 0)\n return 'bg-light-yellow';\n\n return 'bg-light-red';\n}\n\nfunction getBorderColorClass(timeLeft: number): string {\n if (timeLeft > THRESHOLD_DAYS_LEFT)\n return 'border-green';\n\n if (timeLeft > 0)\n return 'border-yellow';\n\n return 'border-red';\n}\n\ninterface TrialBannerProps {\n className: string;\n activePresentation: Presentation;\n daysLeft: number;\n monthsLeft: number;\n expiryDate: Date | string;\n hasReferral: boolean;\n isPilot: boolean;\n canManageUpsell: boolean;\n}\n\nexport function TrialBanner(props: TrialBannerProps) {\n const breakpoints = useBreakpoints();\n \n const inviteAnalyticsOptions = {\n actionType: UserAction.Click,\n entity: EntityType.AppLink,\n location: LocationContext.TrialBanner,\n descriptor: TrialBannerDescriptor.Invite\n };\n\n const requestAccessAnalyticsOptions = {\n actionType: UserAction.Click,\n entity: EntityType.AppLink,\n location: LocationContext.TrialBanner,\n descriptor: TrialBannerDescriptor.RequestFullAccess\n };\n \n const analyticsData = {\n activePresentationId: props.activePresentation?.id,\n activePresentationLevel: props.activePresentation?.learningLevel\n };\n\n const inviteAppLink = {\n application: AppChannels.SIGN_UP,\n action: Actions.SignUp.INVITE_COLLEAGUE\n };\n\n const requestAccessAppLink = RequestAccessApplinkHelper.requestFullAccess();\n\n const primaryButtonProps = {\n primaryText:\n props.isPilot ?\n (!props.hasReferral ? null : getPhrase('longInvite')) : // pilot users only have one button and it is the invite option, which they shouldn't have if they have no referral\n getPhrase('requestAccess'),\n primaryAppLink: props.isPilot ? inviteAppLink : requestAccessAppLink,\n primaryAnalyticsData: analyticsData,\n primaryAnalyticsOptions: props.isPilot ? inviteAnalyticsOptions : requestAccessAnalyticsOptions,\n primaryClassName: props.isPilot ? 'btn btn-outline-dark' : null\n };\n\n // this only shows up when there are more than 0 days left\n const secondaryButtonProps = {\n secondaryText:\n breakpoints.xs || breakpoints.sm || !props.hasReferral || props.isPilot ?\n null :\n getPhrase('invite'),\n secondaryAppLink: inviteAppLink,\n secondaryAnalyticsData: analyticsData,\n secondaryAnalyticsOptions: inviteAnalyticsOptions\n };\n\n const infoTextProps = {\n infoText: getPhrase(getText(props.daysLeft, props.hasReferral), {\n smartCount: props.daysLeft,\n date: DateHelper.format(props.expiryDate, 'Do MMMM YYYY')\n }),\n isSmScreen: breakpoints.xs\n };\n\n return (\n <StickyBanner\n type='text-pill'\n className={props.className}\n pillText={props.monthsLeft > 0 ?\n getPhrase('monthPillText', { smartCount: props.monthsLeft }) :\n getPhrase('dayPillText', { smartCount: props.daysLeft })\n }\n borderClass={getBorderColorClass(props.daysLeft)}\n lightBgClass={getBackgroundColorClass(props.daysLeft)}\n {...infoTextProps}\n\n {...primaryButtonProps}\n {...secondaryButtonProps}\n />\n );\n}\n","import React from 'react';\n\nimport { Flight } from 'libs/common/react/index';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useAccessPolicy } from 'libs/shared/hooks/useAccessPolicy';\nimport { useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useSettings } from 'libs/shared/hooks/useSettings';\nimport { CurrentUser } from 'libs/shared/interfaces';\nimport { ContextService } from 'libs/shared/services/ContextService';\n\nimport { UpsellHeader } from 'shared/components/upsell-header/UpsellHeader';\nimport { useActivePresentation } from 'shared/hooks/presentations/useActivePresentation';\nimport { usePreferredPresentation } from 'shared/hooks/presentations/usePreferredPresentation';\nimport { useRequestAccessApplink } from 'shared/hooks/useRequestAccessApplink';\nimport { useStreamQuota } from 'shared/hooks/useStreamQuota';\nimport { useTrialBanner } from 'shared/hooks/useTrialBanner';\nimport { useUpsellContext } from 'shared/hooks/useUpsellContext';\nimport { TRIAL_BANNER_WHITELIST, UPSELL_BANNER_WHITELIST, WhiteListOptions } from 'shared/views/header-banner/BannerWhiteList';\nimport { BannerWhiteListHelper } from 'shared/views/header-banner/BannerWhiteListHelper';\nimport { FreemiumBanner } from 'shared/views/header-banner/components/freemium/FreemiumBanner';\nimport { TrialBanner } from 'shared/views/header-banner/components/trial/TrialBanner';\n\ntype BannerTypes = 'upsell' | 'trial' | 'freemium';\n\nconst bannerWhitelistMapping: Record<BannerTypes, HashObject<WhiteListOptions>> = {\n trial: TRIAL_BANNER_WHITELIST,\n freemium: TRIAL_BANNER_WHITELIST,\n upsell: UPSELL_BANNER_WHITELIST\n};\n\n// These policies are stream-capped rather than time-limited, so they get the stream\n// banner instead of the trial banner (which would render a bogus duration)\nconst FREEMIUM_POLICY_IDS = [\n 'system_cv_live_trial_freemium_v1',\n 'system_cv_trial_freemium_v2'\n];\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function HeaderBannerView() {\n const currentAppLink = ContextService.getCurrentRoute().appLink;\n\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n \n const breakpoints = useBreakpoints();\n \n const { accessPolicy, isLoaded: accessPolicyLoaded } = useAccessPolicy();\n const { activePresentation } = useActivePresentation();\n const { allPreferredPresentations } = usePreferredPresentation();\n\n const { hasPermissions } = usePermissions();\n\n const { applink: requestAccessApplink, onClickRequestAccessButton } = useRequestAccessApplink();\n\n const {\n isLoaded: freemiumLoaded,\n streamsUsed,\n totalStreamsAvailable,\n canRedeemMoreReferrals\n } = useStreamQuota();\n\n const {\n policyEndTime,\n isLoadingSettings,\n inviteColleague\n } = useSettings(null);\n\n const daysLeft = React.useMemo(() => {\n if (isLoadingSettings)\n return 0;\n \n const endDate = new Date(policyEndTime);\n const today = new Date();\n \n return Math.max(DateHelper.diffBetween(endDate, today, 'day'), 0) + 1;\n }, [ isLoadingSettings, policyEndTime ]);\n\n const monthsLeft = Math.floor(daysLeft / 31);\n\n const { showBanner: showTrialBanner } = useTrialBanner();\n\n const upsellContext = useUpsellContext();\n\n const showUpsell = upsellContext.upsellPresentationType === activePresentation?.type;\n const isFreemium = FREEMIUM_POLICY_IDS.includes(accessPolicy?.id);\n\n function getCurrentBannerType(): BannerTypes {\n if (showUpsell)\n return 'upsell';\n\n if (isFreemium)\n return 'freemium';\n\n if (showTrialBanner)\n return 'trial';\n\n return null;\n }\n\n const whitelist = bannerWhitelistMapping[getCurrentBannerType()];\n\n // the banner only renders on whitelisted routes\n // if the path is whitelisted, we expect at a minimum, an empty object\n const whitelistOptions = BannerWhiteListHelper.getBannerOptions(currentAppLink, whitelist);\n\n if (\n isLoadingSettings ||\n !currentUser?.hasCompleted ||\n !upsellContext.isLoaded ||\n !accessPolicyLoaded ||\n !freemiumLoaded ||\n !whitelistOptions\n )\n return null;\n\n if (showUpsell) {\n return (\n <UpsellHeader\n breakpoints={breakpoints}\n upsellContext={upsellContext}\n activePresentation={activePresentation}\n allPreferredPresentations={allPreferredPresentations}\n isAuthenticated={currentUser.data?.isAuthenticated}\n showVideo={whitelistOptions.showVideo}\n requestAccessApplink={requestAccessApplink}\n onClickRequestAccessButton={onClickRequestAccessButton}\n />\n );\n }\n\n // block students from seeing the following banners\n if (hasPermissions(PermissionName.StudentExperience))\n return null;\n\n if (isFreemium) {\n return (\n <FreemiumBanner\n className='d-inline-block w-100 mb-4'\n activePresentation={activePresentation}\n streamQuota={totalStreamsAvailable - streamsUsed}\n hasReferral={canRedeemMoreReferrals}\n maxStream={totalStreamsAvailable}\n canManageUpsell={hasPermissions(PermissionName.ManageUpsell)}\n />\n );\n }\n\n if (showTrialBanner) {\n const isPilot = accessPolicy.metadata?.bannerType.includes('pilot');\n\n return (\n <TrialBanner\n className='d-inline-block w-100 mb-4'\n activePresentation={activePresentation}\n hasReferral={inviteColleague && hasPermissions(PermissionName.ViewInviteColleague)}\n isPilot={isPilot}\n expiryDate={policyEndTime}\n daysLeft={daysLeft}\n monthsLeft={monthsLeft}\n canManageUpsell={hasPermissions(PermissionName.ManageUpsell)}\n />\n );\n }\n\n return null;\n}\n","import { HardCoded } from 'libs/shared/constants/HardCoded';\nimport { Classification, ClassificationDashboardInfo, CuratedDashboard, CuratedWidgetData } from 'libs/shared/interfaces';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\n/**\n * Hubs that need dedicated nav treatment (custom icon/name, product tip anchor, etc) go here.\n * Add a new entry + a predicate in ValidHubPredicateMap to support another hub - other hub\n * topics/dashboards render as generic \"Hub\" nav items and shouldn't match any ValidHubs member.\n */\nexport enum ValidHubs {\n NZ_HUB = 'nz-hub'\n}\n\nconst NZ_HUB_PRESENTATION_IDS: string[] = [\n `${HardCoded.PresentationIds.NZ_PRIMARY}`,\n `${HardCoded.PresentationIds.NZ_SECONDARY}`\n];\n\nconst ValidHubPredicateMap: Record<ValidHubs, (topic: Classification | undefined) => boolean> = {\n [ValidHubs.NZ_HUB]: isNzHubTopic\n};\n\nfunction isNzHubTopic(topic: Classification | undefined): boolean {\n return !!topic && NZ_HUB_PRESENTATION_IDS.includes(`${topic.presentationId}`);\n}\n\nfunction getTopicForDashboard(\n dashboard: CuratedDashboard<CuratedWidgetData>,\n hubTopics: Classification[]\n): Classification | undefined {\n const targetInfo = CuratedDashboardHelper.getDashboardTargetInfo(dashboard) as ClassificationDashboardInfo;\n\n return hubTopics?.find(topic => topic.id === targetInfo.classificationId);\n}\n\nfunction hasHubTopic(type: ValidHubs, topic: Classification | undefined): boolean {\n return !!topic && ValidHubPredicateMap[type](topic);\n}\n\nfunction hasHubDashboard(\n type: ValidHubs,\n dashboards: CuratedDashboard<CuratedWidgetData>[],\n hubTopics: Classification[]\n): boolean {\n return (dashboards ?? []).some(dashboard => hasHubTopic(type, getTopicForDashboard(dashboard, hubTopics)));\n}\n\nexport const HubHelper = {\n getTopicForDashboard,\n hasHubTopic,\n hasHubDashboard\n};\n","import { Flight } from 'libs/common/react/index';\n\nimport { ClassificationRequests } from 'libs/shared/flight-requests/ClassificationRequests';\nimport { DashboardRequests } from 'libs/shared/flight-requests/DashboardRequests';\nimport { Classification, CuratedDashboard, DashboardStatus, DashboardUserType } from 'libs/shared/interfaces';\n\nimport { useActivePresentation } from 'shared/hooks/presentations/useActivePresentation';\nimport { HubHelper, ValidHubs } from 'shared/utils/HubHelper';\n\nexport function useHubDashboards() {\n const { activePresentation } = useActivePresentation();\n\n const hubTopics = Flight.useBasicFetch<Classification[]>(\n activePresentation?.id && ClassificationRequests.hubTopics(activePresentation.id)\n );\n\n const hubDashboardRequests = hubTopics.data?.length ? hubTopics.data.map(topic =>\n DashboardRequests.classificationDashboard(topic.id, DashboardUserType.Staff, [DashboardStatus.Published])) : [];\n const hubDashboardCollection = Flight.useBasicFetchAll<CuratedDashboard>(hubDashboardRequests);\n\n return {\n hubTopics,\n hubDashboardCollection,\n hasHubDashboard: (type: ValidHubs) => HubHelper.hasHubDashboard(type, hubDashboardCollection.data, hubTopics.data)\n };\n}\n","export enum LeftNavTheme {\n Default = 'default',\n Live = 'live'\n}\n","import React from 'react';\n\nexport function CalendarOutlineSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path d='M15.4004 4C15.7315 4.00021 15.9998 4.26855 16 4.59961V6H18C18.5523 6 19 6.44772 19 7V18C19 19.1046 18.1046 20 17 20H7C5.89543 20 5 19.1046 5 18V7C5 6.44772 5.44772 6 6 6H8V4.59961C8.00021 4.26855 8.26855 4.00021 8.59961 4C8.93085 4 9.19998 4.26842 9.2002 4.59961V6H14.7998V4.59961C14.8 4.26842 15.0691 4 15.4004 4ZM6 18C6 18.5523 6.44772 19 7 19H17C17.5523 19 18 18.5523 18 18V11H6V18ZM7 7C6.44772 7 6 7.44772 6 8V10H18V8C18 7.44772 17.5523 7 17 7H7Z' fill='#313543'/>\n </svg>\n\n );\n}\n","import { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { CalendarOutlineSvg } from 'libs/shared/images/svg/objects/CalendarOutlineSvg';\nimport { CalendarSvg } from 'libs/shared/images/svg/objects/CalendarSvg';\nimport { Presentation } from 'libs/shared/interfaces';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { LeftNavId } from 'shared/enums/LeftNavId';\nimport { LeftNavHelper } from 'shared/utils/LeftNavHelper';\nimport { LeftNavGroup } from 'shared/views/left-nav-v2/enums/LeftNavGroup';\nimport { LeftNavItem } from 'shared/views/left-nav-v2/interfaces/LeftNavItem';\n\nimport { getIsLeftNavActive, getNavIcon } from '../../LeftNavUtils';\nimport { GetItemHandlerOptions } from '../createLeftNavBuilder';\n\nconst getPhrase = LanguageService.encloseNamespace('leftNavV2.createLeftNavBuilder');\n\ninterface GetCalendarItemHandlerOptions extends GetItemHandlerOptions {\n activePresentation: Presentation | null;\n}\n\nexport function getCalendarItemHandler(options: GetCalendarItemHandlerOptions): LeftNavItem {\n const isActive = getIsLeftNavActive(\n options.currentAppLink,\n LeftNavHelper.getCalendarAppLinks()\n );\n\n const svg = getNavIcon({\n isActive: options.enableActiveIcons && isActive,\n defaultIcon: CalendarOutlineSvg,\n activeIcon: CalendarSvg\n });\n\n return {\n id: LeftNavId.Calendar,\n type: 'applink',\n show: true,\n appLink: {\n application: AppChannels.CALENDAR,\n action: Actions.Calendar.CALENDAR,\n args: [options.activePresentation?.vanitySlug]\n },\n name: getPhrase('calendar'),\n group: LeftNavGroup.First,\n svg,\n isActive\n };\n}\n","import React from 'react';\n\nexport function ClassroomsFilledSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path d='M16.2805 7.96377C17.1019 7.33344 17.7338 6.32247 17.7338 5.18487C17.7338 4.91215 17.5203 4.69103 17.257 4.69103H14.7746C13.5103 4.69103 12.408 5.22573 11.8417 6.30183C11.4713 5.5491 10.9686 5.05353 10.5126 4.73303C9.58287 4.07962 8.64929 4.00385 8.60999 4.00091C8.34676 3.98128 7.92082 4.28453 7.90208 4.5566C7.88331 4.82865 8.27724 5.16399 8.5399 5.18344C8.64596 5.19229 10.8902 5.41425 11.3533 8.10354C11.1947 8.06835 11.0517 8.01713 10.897 7.96174C10.5047 7.82126 10.0378 7.65403 9.0528 7.65403C6.9109 7.65403 5 9.36732 5 12.6912C5 16.1285 7.726 20 9.5297 20C10.5719 20 10.9498 19.8169 11.2503 19.6713C11.4488 19.5751 11.6136 19.4952 11.9138 19.4952C12.2152 19.4952 12.3798 19.5752 12.5779 19.6714C12.8777 19.8171 13.2543 20 14.2979 20C16.103 20 18.8276 16.1317 18.8276 12.6912C18.8276 10.1275 17.7135 8.58557 16.2805 7.96377ZM14.7746 5.77737L16.6339 5.6786C16.4124 6.8043 15.4424 7.3281 14.2982 7.4564L12.5372 7.65394C12.7587 6.52824 13.6249 5.83847 14.7746 5.77737Z' fill='#313543'/>\n </svg>\n\n );\n}\n","import { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { ClassroomsFilledSvg } from 'libs/shared/images/svg/objects/ClassroomsFilledSvg';\nimport { ClassroomsSvg } from 'libs/shared/images/svg/objects/ClassroomsSvg';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { LeftNavId } from 'shared/enums/LeftNavId';\nimport { LeftNavHelper } from 'shared/utils/LeftNavHelper';\nimport { LeftNavGroup } from 'shared/views/left-nav-v2/enums/LeftNavGroup';\nimport { LeftNavItem } from 'shared/views/left-nav-v2/interfaces/LeftNavItem';\n\nimport { getIsLeftNavActive, getNavIcon } from '../../LeftNavUtils';\nimport { GetItemHandlerOptions } from '../createLeftNavBuilder';\n\nconst getPhrase = LanguageService.encloseNamespace('leftNavV2.createLeftNavBuilder');\n\nexport function getClassroomsItemHandler(options: GetItemHandlerOptions): LeftNavItem {\n const { hasPermissions, settings } = options;\n const isActive = getIsLeftNavActive(options.currentAppLink, LeftNavHelper.getClassroomsAppLinks());\n const svg = getNavIcon({\n isActive: options.enableActiveIcons && isActive,\n defaultIcon: ClassroomsSvg,\n activeIcon: ClassroomsFilledSvg\n });\n \n const show = settings.hasClassrooms &&\n (hasPermissions(PermissionName.ViewClassrooms) || settings.hasShareFlowV2) &&\n !hasPermissions(PermissionName.StudentExperience) &&\n !hasPermissions(PermissionName.GuestExperience);\n \n return {\n id: LeftNavId.Classrooms,\n type: 'applink',\n name: getPhrase('classrooms'),\n show,\n group: LeftNavGroup.Second,\n appLink: {\n application: AppChannels.CLASSROOMS,\n action: Actions.Classrooms.HOME\n },\n svg,\n isActive\n };\n}\n","import React from 'react';\n\nexport function FernBoldSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg viewBox='0 0 24 24' fill='none' {...props}>\n <path\n d='M19.5164 3.65706C19.5164 3.65706 19.2783 3.86039 19.2867 4.14476C19.2409 4.39775 19.2129 4.58768 19.166 4.60025C19.1607 4.60166 19.1469 4.52279 19.1354 4.42497C19.0767 3.9304 19.0456 3.88757 18.9466 4.16426C18.8902 4.32147 18.8909 4.38948 18.9524 4.74386C18.9835 4.92382 18.9768 5.03199 18.93 5.10244C18.9006 5.14665 18.8966 5.14037 18.8796 5.02239C18.854 4.84506 18.7178 4.35253 18.691 4.34066C18.6501 4.32244 18.6113 4.39859 18.5788 4.56109C18.5372 4.7683 18.5404 4.81062 18.6237 5.15571C18.678 5.381 18.693 5.46423 18.6855 5.49895C18.6748 5.54894 18.6207 5.65301 18.6029 5.65776C18.5968 5.65939 18.5355 5.45042 18.4666 5.19338C18.3043 4.5878 18.281 4.56628 18.195 4.94397C18.1269 5.24371 18.1385 5.44197 18.2434 5.77279C18.3192 6.01153 18.3214 6.06168 18.2613 6.16285C18.2373 6.20302 18.2123 6.23737 18.2056 6.23915C18.1987 6.24101 18.132 6.005 18.0515 5.69399C17.8802 5.03207 17.859 4.98966 17.7881 5.16735C17.6503 5.51279 17.6502 5.94889 17.7879 6.46625C17.833 6.63576 17.8307 6.69278 17.7748 6.78275C17.7116 6.88454 17.6874 6.88836 17.6759 6.79837C17.6653 6.7148 17.3354 5.48197 17.3198 5.46764C17.2644 5.41671 17.0969 5.78649 17.0657 6.02847C17.0379 6.24454 17.0559 6.40184 17.1662 6.90624C17.2515 7.29662 17.2526 7.3266 17.1852 7.44398C17.117 7.5629 17.1005 7.56619 17.0855 7.46394C17.0732 7.38059 16.8287 6.36533 16.7469 6.05752C16.6795 5.80435 16.6353 5.82241 16.5184 6.15079C16.3607 6.59406 16.3585 6.85789 16.5064 7.61553C16.5888 8.03786 16.5861 8.08172 16.4701 8.20198C16.4143 8.25993 16.4121 8.2559 16.383 8.04142C16.3689 7.93661 16.3265 7.71311 16.289 7.54476C16.2515 7.37646 16.1774 7.02553 16.1244 6.76492C16.0173 6.23886 16.0106 6.22003 15.9488 6.27515C15.8733 6.34245 15.7359 6.69629 15.6867 6.95008C15.6094 7.34873 15.6255 7.55061 15.8158 8.57051C15.8416 8.70872 15.8327 8.77921 15.7804 8.85216C15.7302 8.92198 15.6792 8.96514 15.6715 8.94414C15.6494 8.88389 15.4142 7.80583 15.3058 7.2682C15.1811 6.64969 15.1717 6.64058 15.0146 6.98515C14.7961 7.46409 14.744 7.83483 14.8245 8.33964C14.8622 8.57623 14.9739 9.14767 15.0053 9.26509C15.0441 9.40979 15.0038 9.55179 14.8972 9.64578C14.8314 9.70382 14.8388 9.72271 14.7408 9.25048C14.6922 9.01628 14.62 8.66824 14.5804 8.47699C14.3298 7.26864 14.3348 7.29038 14.3015 7.26427C14.1944 7.18032 13.9769 7.81166 13.9273 8.3503C13.8884 8.77329 13.9133 9.01404 14.0729 9.7571C14.1592 10.1584 14.154 10.2256 14.0267 10.3601C13.9165 10.4765 13.9129 10.4727 13.8613 10.1808C13.8294 10.0002 13.6805 9.27113 13.5549 8.67982C13.508 8.45886 13.4438 8.15342 13.4121 8.00103C13.3326 7.61802 13.3006 7.58763 13.1887 7.78871C12.9838 8.15646 12.8421 8.79234 12.8706 9.21576C12.8797 9.35102 13.0074 10.0505 13.106 10.5055C13.1449 10.685 13.1767 10.8566 13.1767 10.8867C13.1767 10.9831 13.0662 11.1254 12.9459 11.1841L12.907 11.2032L12.8881 11.1019C12.8778 11.0462 12.8185 10.7617 12.7566 10.4696C12.6946 10.1775 12.6094 9.77292 12.5674 9.57047C12.5253 9.36803 12.4647 9.07986 12.4328 8.93013C12.4008 8.78035 12.3541 8.55575 12.3289 8.43097C12.2606 8.09299 12.2408 8.07868 12.1158 8.27693C11.8309 8.72866 11.6809 9.35341 11.722 9.91686C11.7383 10.1394 11.9452 11.3014 12.0168 11.572C12.0627 11.7456 11.941 11.9889 11.7869 12.0317C11.7654 12.0376 11.7788 12.0899 11.2502 9.94647C10.9581 8.7619 10.9566 8.75718 10.9026 8.77166C10.7963 8.80015 10.5278 9.40229 10.4399 9.8095C10.3042 10.438 10.3238 10.6766 10.637 12.2177C10.7448 12.7478 10.7454 12.7634 10.6618 12.8687C10.615 12.9277 10.5002 13.0285 10.4878 13.0216C10.4825 13.0186 10.2987 12.3049 10.0794 11.4354C9.52615 9.24311 9.5741 9.404 9.49107 9.45976C9.37741 9.53617 9.10488 10.2824 9.03974 10.6956C8.94378 11.3046 8.98303 11.6255 9.35627 13.2804C9.40169 13.4819 9.44719 13.6843 9.45732 13.7301C9.47097 13.7918 9.47038 13.8286 9.45502 13.8719C9.4319 13.9374 9.29729 14.114 9.27901 14.1029C9.26741 14.0959 9.07868 13.5143 8.86776 12.8356C8.80867 12.6456 8.74337 12.4397 8.7226 12.378C8.70182 12.3163 8.63747 12.1134 8.57956 11.927C8.11956 10.4463 8.05976 10.2692 8.01321 10.2492C7.94268 10.2189 7.91055 10.2656 7.7993 10.5602C7.5407 11.2451 7.47288 11.7551 7.5437 12.4828C7.56075 12.6581 7.57756 12.7285 7.87544 13.8714L8.18921 15.0754L8.1682 15.1482C8.13943 15.2476 7.99223 15.4489 7.96136 15.4309C7.95178 15.4253 7.79404 14.9364 7.16458 12.961C7.03206 12.5452 6.8176 11.8649 6.6387 11.2927C6.49712 10.8399 6.43312 10.8727 6.22942 11.5022C5.83287 12.7274 6.00846 14.0641 6.84342 16.1772C6.99912 16.5711 7.00205 16.5927 6.92111 16.7458C6.83271 16.9131 6.76495 16.9555 6.73879 16.86C6.72908 16.8244 6.55261 16.3719 6.26622 15.6483C6.1727 15.412 5.96613 14.8858 5.61448 13.988C5.50927 13.7193 5.38295 13.397 5.3337 13.2717C5.25059 13.06 5.17229 12.8595 4.97995 12.3662C4.80968 11.9296 4.67702 12.0725 4.53188 12.8487C4.37693 13.6776 4.38297 14.224 4.55653 15.063C4.67374 15.6296 5.06096 16.6581 5.56557 17.7429C5.67196 17.9716 5.76904 18.1829 5.78125 18.2125C5.81454 18.293 5.78288 18.3913 5.65963 18.5906C5.6022 18.6834 5.48106 18.8799 5.39047 19.0272C5.29988 19.1744 5.08737 19.5197 4.91832 19.7945C4.74921 20.0693 4.60587 20.2976 4.59978 20.3019C4.5889 20.3095 4.84252 21.2317 4.94111 21.5884C4.96184 21.6634 5.01291 21.6697 5.04383 21.5983C5.52165 20.496 6.48107 18.662 6.64954 18.5289C6.79924 18.4107 6.79783 18.4106 8.07489 18.5927C9.31206 18.7691 9.79271 18.8113 10.2242 18.7812C11.0177 18.7259 12.0898 18.4628 12.1019 18.3204C12.1085 18.2424 12.3233 18.3145 8.73349 17.1894C8.15222 17.0072 7.6688 16.8538 7.65924 16.8484C7.60987 16.8209 7.82132 16.6169 7.93157 16.5856C8.02773 16.5584 8.21945 16.5994 9.16109 16.8485C10.7133 17.2591 11.487 17.3338 12.5428 17.1748C13.0451 17.0992 13.0899 17.0351 12.7404 16.8922C12.5013 16.7944 12.0652 16.6029 10.9901 16.1234C9.84453 15.6127 9.23096 15.3427 9.05874 15.2738L8.93017 15.2223L8.95457 15.1884C8.99875 15.1273 9.11094 15.046 9.18781 15.0193C9.29084 14.9837 9.31439 14.99 9.78421 15.1809C11.0479 15.6945 11.2253 15.7503 11.8424 15.8294C12.6771 15.9364 13.8587 15.8522 13.8149 15.689C13.8046 15.6507 13.7312 15.6099 13.3672 15.4402C12.7442 15.1497 11.6552 14.6307 11.2229 14.418C10.7883 14.2043 10.4896 14.0671 10.2972 13.9925C10.1626 13.9404 10.1586 13.9299 10.2465 13.8586C10.4227 13.7153 10.4741 13.7187 10.9146 13.9026C11.9308 14.3268 12.2855 14.4352 12.8556 14.4961C13.7589 14.5925 14.8953 14.4663 14.7439 14.2864C14.7156 14.2528 12.7444 13.3866 12.1928 13.1654C12.0241 13.0979 11.603 12.9546 11.4326 12.9069C11.3864 12.8941 11.3472 12.878 11.3454 12.8714C11.3368 12.8394 11.5084 12.7341 11.6183 12.7038L11.7284 12.6736L12.0559 12.7895C13.2425 13.2097 13.7162 13.3161 14.4141 13.319C14.8444 13.3209 15.626 13.2047 15.7117 13.1261C15.7737 13.0692 15.7578 13.0602 15.2139 12.8441C13.6341 12.2164 13.0623 12.0055 12.7131 11.9217C12.5877 11.8916 12.5824 11.8835 12.6524 11.8282C12.8268 11.6906 12.8813 11.689 13.2956 11.8096C14.3262 12.1096 14.5548 12.156 15.0744 12.1707C15.6436 12.1867 16.3908 12.064 16.3627 11.959C16.3537 11.9255 16.3142 11.9083 16.0281 11.8135C15.8898 11.7676 15.5815 11.6594 15.343 11.5731C14.5469 11.2848 14.2187 11.1828 13.8455 11.1076C13.7413 11.0866 13.6548 11.0647 13.6532 11.059C13.6465 11.034 13.7473 10.9695 13.8425 10.9378L13.9443 10.904L14.3894 10.9931C15.5833 11.232 16.0753 11.2426 16.8943 11.0471C17.2388 10.9649 17.2813 10.9248 17.0865 10.8659C16.4845 10.6839 15.0408 10.3342 14.7377 10.297C14.5742 10.2769 14.5706 10.2589 14.7135 10.1737C14.822 10.109 14.8991 10.1038 15.1086 10.1469C16.1535 10.3619 16.9276 10.3582 17.6137 10.1348C17.9172 10.036 17.8979 10.0206 17.2977 9.8819C16.4881 9.69489 16.0589 9.60543 15.8119 9.57228C15.6728 9.55365 15.5357 9.53481 15.5073 9.53042L15.4557 9.52243L15.4816 9.48966C15.5841 9.35981 15.6841 9.33748 15.9659 9.38146C16.4525 9.45731 16.8388 9.49169 17.0679 9.47943C17.6588 9.44784 18.6263 9.13158 18.4338 9.033C18.4147 9.02325 18.2594 8.99832 18.0886 8.97762C17.9179 8.95698 17.4919 8.90189 17.1421 8.85526C16.7922 8.80863 16.4558 8.76507 16.3944 8.75839C16.2632 8.74416 16.257 8.73796 16.3186 8.68287C16.4101 8.60105 16.4743 8.5906 16.7731 8.60893C17.6116 8.6604 17.6682 8.65876 18.0227 8.57281C18.4233 8.47577 18.8046 8.32965 18.9299 8.2252C19.0239 8.14699 18.9827 8.13412 18.5599 8.10948C18.3786 8.09888 18.1219 8.08266 17.9894 8.0734C17.5574 8.04324 17.4127 8.03644 17.1891 8.03579C16.942 8.03502 16.9331 8.0293 17.0386 7.9393C17.1234 7.86699 17.174 7.85807 17.5735 7.84517C18.3043 7.82159 18.6107 7.75523 19.0409 7.52732C19.2937 7.39339 19.2925 7.3306 19.0371 7.33127C18.9613 7.33144 18.6847 7.32565 18.4226 7.3184C18.1605 7.31111 17.8718 7.30697 17.7809 7.30918C17.6043 7.31346 17.581 7.30243 17.6481 7.2465C17.7066 7.19775 17.7864 7.18034 18.0374 7.16154C18.5997 7.11938 18.8603 7.03901 19.2597 6.78457C19.5835 6.57827 19.5682 6.53827 19.182 6.5817C19.0421 6.59749 18.8754 6.61432 18.8117 6.61915C18.5247 6.64097 18.4392 6.6495 18.2804 6.67225C18.0799 6.7009 18.0858 6.70239 18.1382 6.63645L18.1797 6.58431L18.3821 6.53624C19.0652 6.37403 19.1722 6.33142 19.4644 6.10498C19.667 5.94803 19.7121 5.87012 19.5959 5.8782C19.539 5.88212 18.7674 6.04475 18.6342 6.08089C18.5406 6.10626 18.5298 6.1008 18.5658 6.04623C18.6152 5.97135 18.6413 5.95927 19.0031 5.84392C19.4846 5.69041 19.5361 5.66016 19.7311 5.41581C19.9233 5.17497 19.9139 5.17296 19.3651 5.33624C18.9124 5.47089 18.9358 5.46661 18.9678 5.40883C18.9984 5.35369 19.0444 5.32799 19.2699 5.24014C19.5716 5.1226 19.7539 4.98577 19.8765 4.7845C19.9753 4.62263 19.8592 4.64204 19.3932 4.86525C19.2103 4.95287 19.1938 4.95574 19.2279 4.8942C19.2561 4.84321 19.284 4.82286 19.4451 4.73583C19.6924 4.60235 19.8085 4.49711 19.9028 4.32129C19.9894 4.15959 19.9455 4.16714 19.6362 4.36722C19.5226 4.44069 19.4231 4.50256 19.415 4.50473C19.3686 4.51718 19.5045 4.34146 19.6208 4.23859C19.8153 3.99489 19.8472 3.85097 19.8486 3.64925C19.8492 3.5679 19.8393 3.39478 19.5164 3.65706Z'\n fill='#313543'\n stroke='#313543'\n strokeWidth='0.2'\n />\n </svg>\n );\n}\n","import React from 'react';\n\nexport function FernSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg viewBox='0 0 24 24' fill='none' {...props}>\n <path\n d='M19.5164 3.65706C19.5164 3.65706 19.4335 3.72785 19.3673 3.84431C19.2637 4.02632 19.2745 4.25007 19.2286 4.45438C19.2094 4.53987 19.1903 4.59376 19.166 4.60026C19.1607 4.60166 19.1469 4.52279 19.1354 4.42497C19.0767 3.9304 19.0456 3.88757 18.9466 4.16426C18.8902 4.32147 18.8909 4.38948 18.9524 4.74386C18.9835 4.92382 18.9768 5.03199 18.93 5.10244C18.9006 5.14665 18.8967 5.14037 18.8796 5.02239C18.854 4.84506 18.7178 4.35253 18.691 4.34066C18.6501 4.32244 18.6113 4.39859 18.5788 4.56109C18.5372 4.7683 18.5404 4.81062 18.6237 5.15571C18.678 5.381 18.693 5.46422 18.6855 5.49895C18.6748 5.54894 18.6207 5.65301 18.6029 5.65776C18.5968 5.65939 18.5355 5.45042 18.4666 5.19338C18.3043 4.5878 18.281 4.56628 18.195 4.94397C18.1269 5.24371 18.1385 5.44197 18.2434 5.77279C18.3192 6.01153 18.3214 6.06168 18.2613 6.16285C18.2373 6.20302 18.2123 6.23737 18.2056 6.23915C18.1987 6.24101 18.132 6.005 18.0515 5.69399C17.8802 5.03207 17.859 4.98966 17.7881 5.16735C17.6503 5.51279 17.6502 5.94889 17.7879 6.46625C17.833 6.63576 17.8307 6.69278 17.7748 6.78275C17.7116 6.88454 17.6874 6.88836 17.6759 6.79837C17.6653 6.7148 17.3354 5.48197 17.3198 5.46764C17.2644 5.41671 17.0969 5.78649 17.0657 6.02847C17.0379 6.24454 17.0559 6.40184 17.1662 6.90624C17.2515 7.29662 17.2526 7.3266 17.1852 7.44398C17.117 7.56291 17.1005 7.56619 17.0855 7.46394C17.0732 7.38059 16.8287 6.36533 16.7469 6.05752C16.6795 5.80435 16.6353 5.82241 16.5184 6.15079C16.3607 6.59406 16.3585 6.85789 16.5064 7.61553C16.5888 8.03786 16.5861 8.08172 16.4701 8.20198C16.4143 8.25993 16.4121 8.2559 16.383 8.04142C16.3689 7.93661 16.3265 7.71311 16.289 7.54476C16.2515 7.37646 16.1774 7.02553 16.1244 6.76492C16.0173 6.23886 16.0106 6.22003 15.9488 6.27515C15.8733 6.34245 15.7359 6.69629 15.6867 6.95008C15.6094 7.34873 15.6255 7.55061 15.8158 8.57051C15.8416 8.70873 15.8327 8.77921 15.7804 8.85216C15.7302 8.92198 15.6792 8.96514 15.6715 8.94414C15.6494 8.88389 15.4142 7.80583 15.3058 7.2682C15.1811 6.64969 15.1717 6.64058 15.0146 6.98515C14.7961 7.46409 14.744 7.83483 14.8245 8.33964C14.8622 8.57623 14.9739 9.14767 15.0053 9.26509C15.0441 9.40979 15.0038 9.55179 14.8972 9.64578C14.8314 9.70382 14.8388 9.72271 14.7408 9.25048C14.6922 9.01628 14.62 8.66824 14.5804 8.47699C14.3298 7.26864 14.3348 7.29038 14.3015 7.26427C14.1944 7.18032 13.9769 7.81166 13.9273 8.3503C13.8884 8.77329 13.9133 9.01404 14.0729 9.7571C14.1592 10.1584 14.154 10.2256 14.0267 10.3601C13.9165 10.4765 13.9129 10.4727 13.8613 10.1808C13.8294 10.0002 13.6805 9.27113 13.5549 8.67982C13.508 8.45886 13.4438 8.15342 13.4121 8.00103C13.3326 7.61802 13.3006 7.58764 13.1887 7.78871C12.9838 8.15646 12.8421 8.79234 12.8706 9.21576C12.8797 9.35102 13.0074 10.0505 13.106 10.5055C13.1449 10.685 13.1767 10.8566 13.1767 10.8867C13.1767 10.9831 13.0662 11.1255 12.9459 11.1841C12.9263 11.1937 12.903 11.182 12.899 11.1606L12.8881 11.1019C12.8778 11.0462 12.8185 10.7617 12.7566 10.4696C12.6946 10.1775 12.6094 9.77292 12.5674 9.57048C12.5253 9.36803 12.4647 9.07986 12.4328 8.93013C12.4008 8.78035 12.3541 8.55575 12.3289 8.43097C12.2606 8.09299 12.2408 8.07868 12.1158 8.27693C11.8309 8.72866 11.6809 9.35341 11.722 9.91686C11.7383 10.1394 11.9452 11.3014 12.0168 11.572C12.0627 11.7456 11.941 11.9889 11.7869 12.0317C11.7654 12.0376 11.7788 12.0899 11.2502 9.94647C10.9581 8.7619 10.9566 8.75718 10.9026 8.77166C10.7963 8.80015 10.5278 9.40229 10.4399 9.8095C10.3042 10.438 10.3238 10.6766 10.637 12.2177C10.7448 12.7478 10.7454 12.7634 10.6618 12.8687C10.615 12.9277 10.5002 13.0285 10.4878 13.0216C10.4825 13.0186 10.2987 12.3049 10.0794 11.4354C9.52615 9.24311 9.5741 9.404 9.49107 9.45976C9.37741 9.53617 9.10488 10.2824 9.03974 10.6956C8.94378 11.3046 8.98303 11.6255 9.35627 13.2804C9.40169 13.4819 9.44719 13.6843 9.45732 13.7301C9.47097 13.7918 9.47038 13.8286 9.45502 13.8719C9.4319 13.9374 9.29729 14.114 9.27901 14.1029C9.26741 14.0959 9.07868 13.5143 8.86776 12.8356C8.80867 12.6456 8.74337 12.4397 8.7226 12.378C8.70182 12.3163 8.63747 12.1134 8.57956 11.927C8.11956 10.4463 8.05976 10.2692 8.01321 10.2492C7.94268 10.2189 7.91055 10.2656 7.7993 10.5602C7.5407 11.2451 7.47288 11.7551 7.5437 12.4828C7.56075 12.6581 7.57756 12.7285 7.87544 13.8714L8.17012 15.0022C8.18262 15.0501 8.18196 15.1006 8.1682 15.1482C8.13943 15.2476 7.99223 15.4489 7.96136 15.4309C7.95178 15.4253 7.79404 14.9364 7.16458 12.961C7.03206 12.5452 6.8176 11.8649 6.6387 11.2927C6.49712 10.8399 6.43312 10.8727 6.22942 11.5022C5.83287 12.7274 6.00846 14.0641 6.84342 16.1772C6.99912 16.5712 7.00205 16.5927 6.92111 16.7458C6.83271 16.9131 6.76495 16.9555 6.7388 16.86C6.72908 16.8244 6.55261 16.3719 6.26622 15.6483C6.1727 15.412 5.96613 14.8858 5.61448 13.988C5.50927 13.7193 5.38295 13.397 5.3337 13.2717C5.25059 13.06 5.17229 12.8595 4.97995 12.3662C4.80968 11.9296 4.67702 12.0725 4.53188 12.8487C4.37693 13.6776 4.38297 14.2241 4.55654 15.063C4.67374 15.6296 5.06096 16.6581 5.56557 17.7429C5.67196 17.9716 5.76904 18.1829 5.78125 18.2125C5.81454 18.293 5.78288 18.3913 5.65963 18.5906C5.6022 18.6834 5.48106 18.8799 5.39047 19.0272C5.29988 19.1744 5.08737 19.5197 4.91832 19.7945C4.74921 20.0693 4.60587 20.2976 4.59978 20.3019C4.58891 20.3095 4.84252 21.2317 4.94112 21.5884C4.96184 21.6634 5.01291 21.6697 5.04383 21.5983C5.52165 20.496 6.48107 18.662 6.64954 18.5289C6.79924 18.4107 6.79783 18.4106 8.07489 18.5927C9.31206 18.7691 9.79272 18.8113 10.2242 18.7812C11.0177 18.7259 12.0898 18.4628 12.1019 18.3204C12.1085 18.2424 12.3233 18.3145 8.73349 17.1894C8.15222 17.0072 7.6688 16.8538 7.65924 16.8484C7.60987 16.8209 7.82132 16.6169 7.93157 16.5856C8.02773 16.5584 8.21945 16.5994 9.16109 16.8485C10.7133 17.2591 11.487 17.3338 12.5428 17.1748C13.0451 17.0992 13.0899 17.0351 12.7404 16.8922C12.5013 16.7944 12.0652 16.6029 10.9901 16.1234C9.84453 15.6127 9.23096 15.3427 9.05874 15.2738L8.9689 15.2378C8.94922 15.2299 8.94217 15.2056 8.95457 15.1884C8.99875 15.1273 9.11094 15.046 9.18781 15.0193C9.29084 14.9837 9.31439 14.99 9.78421 15.1809C11.0479 15.6945 11.2253 15.7503 11.8424 15.8294C12.6771 15.9364 13.8587 15.8522 13.8149 15.689C13.8046 15.6507 13.7312 15.6099 13.3672 15.4402C12.7442 15.1497 11.6552 14.6307 11.2229 14.418C10.7883 14.2043 10.4896 14.0671 10.2972 13.9925C10.1626 13.9404 10.1586 13.9299 10.2465 13.8586C10.4227 13.7153 10.4741 13.7187 10.9146 13.9026C11.9308 14.3268 12.2855 14.4352 12.8556 14.4961C13.7589 14.5925 14.8953 14.4663 14.7439 14.2864C14.7156 14.2528 12.7444 13.3866 12.1928 13.1654C12.0241 13.0979 11.603 12.9546 11.4326 12.9069C11.3864 12.8941 11.3472 12.878 11.3454 12.8714C11.3368 12.8394 11.5084 12.7341 11.6183 12.7038C11.69 12.6841 11.766 12.6869 11.8361 12.7117L12.0559 12.7895C13.2425 13.2097 13.7162 13.3161 14.4141 13.319C14.8444 13.3209 15.626 13.2047 15.7117 13.1261C15.7737 13.0692 15.7578 13.0602 15.2139 12.8441C13.6341 12.2164 13.0623 12.0055 12.7131 11.9217C12.5877 11.8916 12.5824 11.8835 12.6524 11.8282C12.8268 11.6906 12.8813 11.689 13.2956 11.8096C14.3262 12.1096 14.5548 12.156 15.0744 12.1707C15.6436 12.1867 16.3908 12.064 16.3627 11.959C16.3537 11.9255 16.3142 11.9083 16.0281 11.8135C15.8898 11.7676 15.5815 11.6594 15.343 11.5731C14.5469 11.2848 14.2187 11.1828 13.8455 11.1076C13.7413 11.0866 13.6548 11.0647 13.6532 11.059C13.6465 11.034 13.7473 10.9695 13.8425 10.9378C13.9092 10.9157 13.9805 10.9113 14.0494 10.925L14.3894 10.9931C15.5833 11.232 16.0753 11.2426 16.8943 11.0471C17.2388 10.9649 17.2813 10.9248 17.0865 10.8659C16.4845 10.6839 15.0408 10.3342 14.7377 10.297C14.5742 10.2769 14.5706 10.2589 14.7135 10.1737C14.822 10.109 14.8991 10.1038 15.1086 10.1469C16.1535 10.3619 16.9276 10.3582 17.6137 10.1349C17.9172 10.036 17.8979 10.0206 17.2977 9.8819C16.4881 9.69489 16.0589 9.60543 15.8119 9.57228C15.6728 9.55365 15.5357 9.53481 15.5073 9.53042L15.497 9.52883C15.4786 9.52597 15.4701 9.5043 15.4816 9.48966C15.5841 9.35981 15.6841 9.33748 15.9659 9.38146C16.4525 9.45731 16.8388 9.49169 17.0679 9.47943C17.6588 9.44785 18.6263 9.13158 18.4338 9.033C18.4147 9.02325 18.2594 8.99832 18.0886 8.97762C17.9179 8.95698 17.4919 8.90189 17.1421 8.85526C16.7922 8.80863 16.4558 8.76507 16.3944 8.75839C16.2632 8.74416 16.257 8.73796 16.3186 8.68287C16.4101 8.60105 16.4743 8.5906 16.7731 8.60893C17.6116 8.6604 17.6682 8.65876 18.0227 8.57281C18.4233 8.47577 18.8046 8.32965 18.9299 8.2252C19.0239 8.14699 18.9827 8.13413 18.5599 8.10948C18.3786 8.09888 18.1219 8.08266 17.9894 8.0734C17.5574 8.04324 17.4127 8.03644 17.1891 8.03579C16.942 8.03502 16.9331 8.0293 17.0386 7.9393C17.1234 7.86699 17.174 7.85808 17.5735 7.84517C18.3043 7.82159 18.6107 7.75523 19.0409 7.52732C19.2937 7.39339 19.2925 7.3306 19.0371 7.33127C18.9613 7.33144 18.6847 7.32565 18.4226 7.3184C18.1605 7.31111 17.8718 7.30697 17.7809 7.30918C17.6043 7.31346 17.581 7.30243 17.6481 7.2465C17.7066 7.19775 17.7864 7.18034 18.0374 7.16154C18.5997 7.11938 18.8603 7.03901 19.2597 6.78457C19.5835 6.57827 19.5682 6.53827 19.182 6.5817C19.0421 6.59749 18.8754 6.61432 18.8117 6.61915C18.5247 6.64097 18.4392 6.6495 18.2804 6.67225C18.0799 6.7009 18.0858 6.70239 18.1382 6.63645C18.1651 6.60267 18.2025 6.57889 18.2445 6.56892L18.3821 6.53624C19.0652 6.37403 19.1722 6.33142 19.4644 6.10498C19.667 5.94803 19.7121 5.87012 19.5959 5.8782C19.539 5.88212 18.7674 6.04475 18.6342 6.08089C18.5406 6.10627 18.5298 6.1008 18.5658 6.04623C18.6152 5.97135 18.6413 5.95927 19.0031 5.84392C19.4846 5.69041 19.5361 5.66016 19.7311 5.41581C19.9233 5.17497 19.9139 5.17296 19.3651 5.33624C18.9124 5.47089 18.9358 5.46661 18.9678 5.40883C18.9984 5.35369 19.0444 5.32799 19.2699 5.24014C19.5716 5.1226 19.7539 4.98577 19.8765 4.7845C19.9753 4.62263 19.8592 4.64204 19.3932 4.86525C19.2103 4.95287 19.1938 4.95574 19.2279 4.8942C19.2561 4.84321 19.284 4.82286 19.4451 4.73583C19.6924 4.60235 19.8085 4.49711 19.9028 4.32129C19.9894 4.15959 19.9455 4.16714 19.6362 4.36722C19.5226 4.44069 19.4231 4.50256 19.415 4.50473C19.394 4.51035 19.4103 4.4776 19.4451 4.43051C19.5481 4.29108 19.6861 4.17651 19.7659 4.02257C19.8332 3.89266 19.8477 3.78381 19.8486 3.64925C19.8492 3.5679 19.8393 3.39478 19.5164 3.65706Z'\n fill='#313543'\n stroke='white'\n strokeWidth='0.1'\n />\n </svg>\n );\n}\n","import React from 'react';\n\nexport function LocationFilledSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path d='M18 10.5882C18 6.94965 15.3137 4 12 4C8.68629 4 6 6.94965 6 10.5882C6 14.2268 11.5714 20 12 20C12.4286 20 18 14.2268 18 10.5882ZM14 10C14 11.1046 13.1046 12 12 12C10.8954 12 10 11.1046 10 10C10 8.89543 10.8954 8 12 8C13.1046 8 14 8.89543 14 10Z' fill='#313543'/>\n </svg>\n );\n}\n","import React from 'react';\n\nexport function LocationSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg viewBox='0 0 12 16' {...props}>\n <path xmlns='http://www.w3.org/2000/svg' d='M17 10.5882C17 11.2691 16.7307 12.1469 16.2292 13.1449C15.7368 14.1249 15.0652 15.134 14.3653 16.0525C13.6671 16.9687 12.957 17.7736 12.402 18.3433C12.253 18.4963 12.118 18.6293 12 18.7411C11.882 18.6293 11.747 18.4963 11.598 18.3433C11.043 17.7736 10.3329 16.9687 9.63467 16.0525C8.93475 15.134 8.26316 14.1249 7.77079 13.1449C7.26934 12.1469 7 11.2691 7 10.5882C7 7.41187 9.32454 5 12 5C14.6755 5 17 7.41187 17 10.5882ZM18 10.5882C18 6.94965 15.3137 4 12 4C8.68629 4 6 6.94965 6 10.5882C6 14.2268 11.5714 20 12 20C12.4286 20 18 14.2268 18 10.5882ZM14 10C14 11.1046 13.1046 12 12 12C10.8954 12 10 11.1046 10 10C10 8.89543 10.8954 8 12 8C13.1046 8 14 8.89543 14 10ZM15 10C15 8.34315 13.6568 7 12 7C10.3432 7 9 8.34315 9 10C9 11.6568 10.3432 13 12 13C13.6568 13 15 11.6568 15 10Z' fill='currentColor'/>\n </svg>\n );\n}\n","import { TextHelper } from 'libs/common/react/utils/TextHelper';\n\nimport { HardCoded } from 'libs/shared/constants/HardCoded';\nimport { FernBoldSvg } from 'libs/shared/images/svg/objects/FernBoldSvg';\nimport { FernSvg } from 'libs/shared/images/svg/objects/FernSvg';\nimport { LocationFilledSvg } from 'libs/shared/images/svg/objects/LocationFilledSvg';\nimport { LocationSvg } from 'libs/shared/images/svg/objects/LocationSvg';\nimport { Classification, CuratedDashboard, CuratedWidgetData } from 'libs/shared/interfaces';\nimport { SvgIcon } from 'libs/shared/utils/SvgHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { LeftNavId } from 'shared/enums/LeftNavId';\nimport { HubHelper, ValidHubs } from 'shared/utils/HubHelper';\nimport { LeftNavHelper } from 'shared/utils/LeftNavHelper';\nimport { LeftNavGroup } from 'shared/views/left-nav-v2/enums/LeftNavGroup';\nimport { LeftNavItem } from 'shared/views/left-nav-v2/interfaces/LeftNavItem';\n\nimport { getIsLeftNavActive, getNavIcon } from '../../LeftNavUtils';\nimport { GetItemHandlerOptions } from '../createLeftNavBuilder';\n\ninterface GetHubsItemsHandlerOptions extends GetItemHandlerOptions {\n dashboards: CuratedDashboard<CuratedWidgetData>[];\n hubTopics: Classification[];\n setNzHubProductTipRef?: (el: Element) => void;\n}\n\n// [defaultIcon, activeIcon]\nconst HubSvgPresentationMap: Record<string, [SvgIcon, SvgIcon]> = {\n [HardCoded.PresentationIds.NZ_PRIMARY]: [ FernSvg, FernBoldSvg ],\n [HardCoded.PresentationIds.NZ_SECONDARY]: [ FernSvg, FernBoldSvg ]\n};\n\nconst HubNameMap: Record<string, string> = {\n [HardCoded.PresentationIds.NZ_PRIMARY]: 'Māori Collection',\n [HardCoded.PresentationIds.NZ_SECONDARY]: 'Māori Collection'\n};\n\nexport function getHubsItemHandler(options: GetHubsItemsHandlerOptions): LeftNavItem[] {\n if (!options.dashboards.length || !options.hubTopics.length) return [];\n\n const items: LeftNavItem[] = options.dashboards.reduce<LeftNavItem[]>((acc, dashboard) => {\n const currentTopic = HubHelper.getTopicForDashboard(dashboard, options.hubTopics);\n\n if (!currentTopic) return acc;\n\n const { params } = options.currentAppLink;\n const hubTopicParam = typeof params === 'object' ? params?.hubTopic : undefined;\n const isActiveHubTopicParam = hubTopicParam !== undefined && String(hubTopicParam) === String(currentTopic.id);\n\n const isActive = isActiveHubTopicParam || getIsLeftNavActive(\n options.currentAppLink,\n LeftNavHelper.getHubsAppLinks(currentTopic.id),\n { matchArgs: true }\n );\n\n const [ defaultIcon, activeIcon ] =\n HubSvgPresentationMap[currentTopic.presentationId] || [ LocationSvg, LocationFilledSvg ];\n\n const svg = getNavIcon({\n isActive: options.enableActiveIcons && isActive,\n defaultIcon,\n activeIcon\n });\n\n const isNzHub = HubHelper.hasHubTopic(ValidHubs.NZ_HUB, currentTopic);\n\n acc.push({\n id: LeftNavId.Hubs,\n type: 'applink',\n show: true,\n group: LeftNavGroup.First,\n appLink: {\n application: AppChannels.SUBJECT,\n action: Actions.Subjects.CLASSIFICATION,\n args: [ null, currentTopic.id, TextHelper.slugify(currentTopic.name) ]\n },\n name: HubNameMap[currentTopic.presentationId] || dashboard.name,\n svg,\n isActive,\n // Anchor the \"nz-hub\" product tip to this item once it's rendered as the Māori Collection hub\n ref: isNzHub ? el => options.setNzHubProductTipRef?.(el) : undefined\n });\n\n return acc;\n }, []) ?? [];\n\n return items;\n}\n","import { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { LibraryFilledSvg } from 'libs/shared/images/svg/objects/LibraryFilledSvg';\nimport { LibrarySvg } from 'libs/shared/images/svg/objects/LibrarySvg';\nimport { Library } from 'libs/shared/interfaces';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { LeftNavId } from 'shared/enums/LeftNavId';\nimport { LeftNavHelper } from 'shared/utils/LeftNavHelper';\nimport { LeftNavGroup } from 'shared/views/left-nav-v2/enums/LeftNavGroup';\nimport { LeftNavState } from 'shared/views/left-nav-v2/enums/LeftNavState';\nimport { LeftNavItem } from 'shared/views/left-nav-v2/interfaces/LeftNavItem';\n\nimport { getIsLeftNavActive, getNavIcon } from '../../LeftNavUtils';\nimport { GetItemHandlerOptions } from '../createLeftNavBuilder';\n\nconst getPhrase = LanguageService.encloseNamespace('leftNavV2.createLeftNavBuilder');\n\ninterface GetLibrariesItemHandlerOptions extends GetItemHandlerOptions {\n libraries: Library[];\n}\n\nexport function getLibrariesItemHandler(options: GetLibrariesItemHandlerOptions): LeftNavItem {\n const show =\n options.navState === LeftNavState.Collapsed &&\n options.hasPermissions(PermissionName.ViewLibraries) &&\n options.libraries.length > 0 ;\n\n function getLibraryIsActive(): boolean {\n const appLinks = LeftNavHelper.getLibrariesAppLinks();\n \n if (options.navState === LeftNavState.Collapsed) {\n appLinks.push(...LeftNavHelper.getLibraryAppLinks());\n }\n\n return getIsLeftNavActive(options.currentAppLink, appLinks);\n }\n\n const isActive = getLibraryIsActive();\n const svg = getNavIcon({\n isActive: options.enableActiveIcons && isActive,\n defaultIcon: LibrarySvg,\n activeIcon: LibraryFilledSvg\n });\n \n return {\n id: LeftNavId.Libraries,\n type: 'applink',\n name: getPhrase('libraries'),\n show,\n group: LeftNavGroup.Third,\n appLink: {\n application: AppChannels.LIBRARIES,\n action: Actions.Libraries.LIBRARIES\n },\n svg,\n isActive\n };\n}\n","import { TopicsConstants } from 'libs/shared/constants/TopicsConstants';\nimport { PresentationType } from 'libs/shared/enums/PresentationType';\nimport { GlobeSvg } from 'libs/shared/images/svg/objects/GlobeSvg';\nimport { SchoolSvg } from 'libs/shared/images/svg/objects/SchoolSvg';\nimport { Presentation } from 'libs/shared/interfaces';\nimport { SvgIcon } from 'libs/shared/utils/SvgHelper';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { LeftNavId } from 'shared/enums/LeftNavId';\nimport { LeftNavComplications } from 'shared/views/left-nav-v2/enums/LeftNavComplications';\nimport { LeftNavGroup } from 'shared/views/left-nav-v2/enums/LeftNavGroup';\nimport { LeftNavState } from 'shared/views/left-nav-v2/enums/LeftNavState';\nimport { DropdownGroupedItems, LeftNavItem } from 'shared/views/left-nav-v2/interfaces/LeftNavItem';\n\nimport { GetItemHandlerOptions } from '../createLeftNavBuilder';\n\ninterface GetPresentationItemHandlerOptions extends GetItemHandlerOptions {\n onSwitchPresentation: (presentation: Presentation) => void;\n browsablePresentations: Presentation[];\n selectedPresentation: Presentation | null;\n isPreviewingPresentation: (presentation: Presentation) => boolean;\n setProductTipRef: (el: Element) => void;\n isShowingTeachingLevelReminder: boolean;\n}\n\ninterface PresentationTypeDetails {\n icon: SvgIcon;\n iconClassName: string;\n group: LeftNavGroup;\n}\n\nfunction getPresentationTypeDetails(presentation: Presentation | null): PresentationTypeDetails {\n const iconClassName = TopicsHelper.getMappedPresentationBackgroundColourClass(\n presentation?.learningLevel,\n presentation?.type\n );\n\n switch (presentation?.type) {\n case PresentationType.StreamableLearning:\n return {\n icon: GlobeSvg,\n iconClassName,\n group: LeftNavGroup.Second\n };\n default:\n return {\n icon: SchoolSvg,\n iconClassName,\n group: LeftNavGroup.First\n };\n }\n}\n\nfunction getGroupedItems(options: GetPresentationItemHandlerOptions): DropdownGroupedItems {\n const { browsablePresentations, selectedPresentation, isPreviewingPresentation } = options;\n\n if (!browsablePresentations?.length || !selectedPresentation)\n return {};\n\n return browsablePresentations.reduce((acc, presentation) => {\n const itemDetail = getPresentationTypeDetails(presentation);\n\n const group = itemDetail.group;\n \n acc[group] = acc[group] || [];\n acc[group].push({\n icon: itemDetail.icon,\n iconClassName: itemDetail.iconClassName,\n group,\n name: presentation.name,\n selected: selectedPresentation?.id === presentation.id,\n onClick: () => {\n options.onSwitchPresentation(presentation);\n },\n complications: [\n isPreviewingPresentation(presentation) ? LeftNavComplications.Premium : null\n ]\n });\n\n return acc;\n }, {} as DropdownGroupedItems);\n}\n\nfunction getSortedGroupedItems(groupedItems: DropdownGroupedItems): DropdownGroupedItems {\n const sortedGroups = Object.values(LeftNavGroup).sort(\n (a, b) => Number(a) - Number(b)\n );\n\n return sortedGroups.reduce((result, group) => {\n if (groupedItems[group])\n result[group] = groupedItems[group];\n return result;\n }, {} as DropdownGroupedItems);\n}\n\nexport function getPresentationItemHandler(options: GetPresentationItemHandlerOptions): LeftNavItem {\n const {\n selectedPresentation,\n browsablePresentations,\n isPreviewingPresentation,\n isShowingTeachingLevelReminder\n } = options;\n\n const details = getPresentationTypeDetails(selectedPresentation);\n\n const showDropdownItems = browsablePresentations?.length >= TopicsConstants.MULTI_PRESENTATION_THRESHOLD;\n\n // Hide the presentation switcher all together if there are no dropdown items\n const show = showDropdownItems && !!selectedPresentation;\n \n const groupedItems = getGroupedItems(options);\n const sortedGroupedItems = getSortedGroupedItems(groupedItems);\n\n const complications: LeftNavComplications[] = [];\n \n if (isShowingTeachingLevelReminder)\n complications.push(LeftNavComplications.Header);\n \n if (isPreviewingPresentation(selectedPresentation))\n complications.push(LeftNavComplications.Premium);\n\n return {\n type: 'dropdown',\n id: LeftNavId.Presentation,\n group: LeftNavGroup.First,\n name: selectedPresentation?.name ?? '',\n svg: details.icon,\n classNames: {\n icon: details.iconClassName,\n dropdownMenu: options.navState === LeftNavState.Open ? 'ms-0' : 'ms-2'\n },\n show,\n items: sortedGroupedItems,\n isNavCollapsed: options.navState === LeftNavState.Collapsed,\n isActive: false,\n ref: el => options.setProductTipRef(el),\n complications\n };\n}\n","import { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/react/index';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { EntityType, EventVersion, LocationContext, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { useProductTipsContext } from 'libs/shared/context/product-tips-context/ProductTipsContext';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { PresentationType } from 'libs/shared/enums/PresentationType';\nimport { LibraryRequests } from 'libs/shared/flight-requests/LibraryRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useSettings } from 'libs/shared/hooks/useSettings';\nimport { CurrentUser, DashboardTargetType, Library, Presentation } from 'libs/shared/interfaces';\nimport { ContextService } from 'libs/shared/services/ContextService';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { LeftNavId } from 'shared/enums/LeftNavId';\nimport { isRegionScopedRoute, isSlugAwareRoute } from 'shared/filters/PresentationSlugFilter';\nimport { useHubDashboards } from 'shared/hooks/hubs/useHubDashboards';\nimport { useActivePresentation } from 'shared/hooks/presentations/useActivePresentation';\nimport { useAvailablePresentations } from 'shared/hooks/presentations/useAvailablePresentations';\nimport { usePreferredPresentation } from 'shared/hooks/presentations/usePreferredPresentation';\nimport { useShowCalendar } from 'shared/hooks/useShowCalendar';\nimport { useTeachingLevelBanner } from 'shared/hooks/useTeachingLevelBanner';\nimport { useUpsellContext } from 'shared/hooks/useUpsellContext';\nimport { useFetchCuratedDashboard } from 'shared/utils/DashboardHelper';\nimport { UnmappedAppLinks, UnmappedAppLinksBetweenCVandSL } from 'shared/views/school-level-popup/constants/UnmappedAppLinks';\n\nimport { useCountUploadingAndProcessingItems } from 'apps/upload/hooks/useCountUploadingAndProcessingItems';\n\nimport { LeftNavState } from '../../enums/LeftNavState';\nimport { LeftNavTheme } from '../../enums/LeftNavTheme';\nimport { useCreateLeftNavBuilder } from '../../utils/create-left-nav-builder/createLeftNavBuilder';\nimport { getCalendarItemHandler } from '../../utils/create-left-nav-builder/handlers/getCalendarItemHandler';\nimport { getClassroomsItemHandler } from '../../utils/create-left-nav-builder/handlers/getClassroomsItemHandler';\nimport { getDiscoverItemHandler } from '../../utils/create-left-nav-builder/handlers/getDiscoverItemHandler';\nimport { getHubsItemHandler } from '../../utils/create-left-nav-builder/handlers/getHubsItemHandler';\nimport { getLibrariesItemHandler } from '../../utils/create-left-nav-builder/handlers/getLibrariesItemHandler';\nimport { getLibraryItemsHandler } from '../../utils/create-left-nav-builder/handlers/getLibraryItemsHandler';\nimport { getMoviesAndTvItemHandler } from '../../utils/create-left-nav-builder/handlers/getMoviesAndTvItemHandler';\nimport { getMySharesItemHandler } from '../../utils/create-left-nav-builder/handlers/getMySharesItemHandler';\nimport { getMyVideosItemHandler } from '../../utils/create-left-nav-builder/handlers/getMyVideosItemHandler';\nimport { getPlaylistsItemHandler } from '../../utils/create-left-nav-builder/handlers/getPlaylistItemHandler';\nimport { getPresentationItemHandler } from '../../utils/create-left-nav-builder/handlers/getPresentationItemHandler';\nimport { getStudentFeedItemHandler } from '../../utils/create-left-nav-builder/handlers/getStudentFeedItemHandler';\n\nconst namespace = 'leftNavV2.useLeftNavBuilder';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface GetLeftNavThemeOptions {\n activePresentation: Presentation;\n}\n\nfunction getLeftNavTheme(options: GetLeftNavThemeOptions): LeftNavTheme {\n if (options.activePresentation?.type === PresentationType.StreamableLearning) {\n return LeftNavTheme.Live;\n }\n\n return LeftNavTheme.Default;\n}\n\ninterface UseLeftNavBuilderOptions {\n navState: LeftNavState;\n activeAppLink: Core.AppLink;\n}\n\nexport function useLeftNavBuilder(options: UseLeftNavBuilderOptions) {\n const builder = useCreateLeftNavBuilder();\n const { hasPermissions, hasLocalPermissions } = usePermissions();\n const settings = useSettings(null);\n const alerts = useAlerts();\n\n const { showCalendar } = useShowCalendar();\n const { activePresentation, setActivePresentation } = useActivePresentation();\n const { preferredPresentation, setPreferredPresentation } = usePreferredPresentation();\n const { browsablePresentations, isOwnedPresentation } = useAvailablePresentations();\n const isUploading = !!useCountUploadingAndProcessingItems(hasPermissions(PermissionName.UploadVideo));\n const { isLoaded, upsellPresentationType } = useUpsellContext();\n\n const teachLevelBannerContext = useTeachingLevelBanner();\n\n // don't display the teaching level reminder if the user is only previewing ClickView\n const showTeachingLevelReminder =\n teachLevelBannerContext.showSetLevelReminder &&\n upsellPresentationType !== PresentationType.Subject;\n\n const isUpselling =\n (presentation: Presentation) => isLoaded && presentation?.type === upsellPresentationType;\n\n const { setProductTipRef: setSlMigratedProductTipRef } = useProductTipsContext('sl-migrated');\n const { setProductTipRef: setNzHubProductTipRef } = useProductTipsContext('nz-hub');\n\n const {\n dashboard: moviesAndTvDashboard\n } = useFetchCuratedDashboard({\n targetType: DashboardTargetType.MoviesAndTv,\n queryParams: {}\n });\n\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n\n const { hubTopics, hubDashboardCollection } = useHubDashboards();\n\n const libraries = Flight.useBasicFetch<Library[]>(\n hasPermissions(PermissionName.ViewLibraries) &&\n LibraryRequests.domainLibraries([ 'customLibrary', 'sharedLibrary' ])\n );\n\n Flight.useBasicFetch(!!libraries.data?.length &&\n LibraryRequests.librariesWithOwnerLogos(libraries.data.map(s => s.id)));\n\n function onPresentationSwitchSuccess(selectedPresentation: Presentation) {\n AnalyticsHelper.logUserAction(\n {\n id: preferredPresentation?.id,\n targetId: selectedPresentation.id\n },\n {\n actionType: UserAction.EditAssoc,\n entity: EntityType.Presentation,\n location: LocationContext.LeftNav,\n workflowPhase: WorkflowPhase.Complete,\n eventVersion: EventVersion.V3\n }\n );\n\n const currentAppLink = ContextService.getCurrentRoute().appLink;\n\n const noMatchingTargetAppLink = () => {\n if (UnmappedAppLinks.has(Core.AppLinkHelper.getAppLinkString(currentAppLink))) return true;\n\n // if switching from CV to SL and vice verse\n if (activePresentation?.type !== selectedPresentation.type &&\n UnmappedAppLinksBetweenCVandSL.has(Core.AppLinkHelper.getAppLinkString(currentAppLink))) return true;\n\n return false;\n };\n\n // Switching to a presentation the user doesn't own would 404 on a non-region-scoped route\n // (the slug filter only allows unowned presentations on region-scoped routes), so in that\n // case fall back to the dashboard instead of staying on the current route.\n const isInaccessibleOnCurrentRoute =\n !isRegionScopedRoute(currentAppLink) && !isOwnedPresentation(selectedPresentation.id);\n\n if (noMatchingTargetAppLink() || isInaccessibleOnCurrentRoute) {\n Core.AppLinkHelper.trigger({\n application: AppChannels.DASHBOARD,\n action: Actions.Dashboard.HOME,\n args: [selectedPresentation.vanitySlug]\n });\n } else if (isSlugAwareRoute(currentAppLink)) {\n Core.AppLinkHelper.trigger({\n ...currentAppLink,\n args: [ selectedPresentation.vanitySlug, ...currentAppLink.args.slice(1) ?? [] ]\n });\n } else {\n Core.AppLinkHelper.trigger(currentAppLink);\n }\n }\n\n function onSwitchPresentation(presentation: Presentation) {\n setActivePresentation(presentation);\n \n // if the user is selecting a presentation of a type that they are previewing, don't set preferred\n if (isUpselling(presentation)) {\n onPresentationSwitchSuccess(presentation);\n return;\n }\n\n setPreferredPresentation(presentation)\n .then(() => onPresentationSwitchSuccess(presentation))\n .catch(() => alerts.error(getPhrase('error')));\n }\n\n builder\n .setOptions({\n currentUser: currentUser.data,\n settings,\n navState: options.navState,\n currentAppLink: options.activeAppLink,\n hasPermissions,\n hasLocalPermissions,\n enableActiveIcons: true\n })\n // Group 1\n .addHandler(LeftNavId.Presentation, getPresentationItemHandler, {\n onSwitchPresentation,\n browsablePresentations,\n selectedPresentation: activePresentation,\n isPreviewingPresentation: isUpselling,\n setProductTipRef: setSlMigratedProductTipRef,\n isShowingTeachingLevelReminder: showTeachingLevelReminder\n })\n .addHandler(LeftNavId.StudentFeed, getStudentFeedItemHandler)\n .addHandler(LeftNavId.Discover, getDiscoverItemHandler, {\n excludeTopicIds: hubTopics.data?.map(t => t.id.toString()),\n activePresentation,\n hasMoviesAndTvDashboardData: !!moviesAndTvDashboard.data\n })\n .addHandler(LeftNavId.MoviesAndTv, getMoviesAndTvItemHandler, {\n hasMoviesAndTvDashboardData: !!moviesAndTvDashboard.data,\n activePresentation\n });\n\n if (showCalendar)\n builder.addHandler(\n LeftNavId.Calendar,\n getCalendarItemHandler,\n { activePresentation }\n );\n \n builder\n .addHandler(\n LeftNavId.Hubs,\n getHubsItemHandler,\n {\n dashboards: hubDashboardCollection.data ?? [],\n hubTopics: hubTopics.data ?? [],\n setNzHubProductTipRef\n }\n )\n // Group 2\n .addHandler(LeftNavId.Playlists, getPlaylistsItemHandler)\n .addHandler(LeftNavId.MyVideos, getMyVideosItemHandler, { isUploading })\n .addHandler(LeftNavId.MyShares, getMySharesItemHandler)\n .addHandler(LeftNavId.Classrooms, getClassroomsItemHandler)\n // Group 3\n .addHandler(LeftNavId.Library, getLibraryItemsHandler, { libraries: libraries.data ?? []})\n .addHandler(LeftNavId.Libraries, getLibrariesItemHandler, { libraries: libraries.data ?? []});\n\n const hasItems = builder.getItems().length > 1;\n\n return {\n items: builder.getGroupedItems(),\n showNav: hasItems,\n theme: getLeftNavTheme({ activePresentation })\n };\n}\n",":local {\n .redDotComplication {\n width: 0.5rem;\n height: 0.5rem;\n }\n}","import React from 'react';\n\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\n\nimport { SchoolLevelReminder } from 'shared/components/school-level-reminder/SchoolLevelReminder';\nimport { UpsellBadge } from 'shared/components/upsell-badge/UpsellBadge';\n\nimport { LeftNavComplications } from '../../enums/LeftNavComplications';\n\nimport styles from './left-nav-complication.module.scss';\n\ninterface LeftNavComplicationProps {\n type: LeftNavComplications;\n className?: string;\n svgSize?: SvgContainerSize;\n}\n\nexport function LeftNavComplication(props: LeftNavComplicationProps) {\n if (props.type === LeftNavComplications.Header) {\n return <SchoolLevelReminder type='set-level' className='mx-2' asDropdown={true} />;\n }\n\n if (props.type === LeftNavComplications.Uploading) {\n return <span className={classNames('bg-danger rounded-circle', styles.redDotComplication, props.className)} />;\n }\n\n if (props.type === LeftNavComplications.Premium) {\n return (\n <UpsellBadge className={props.className} svgSize={props.svgSize} showTooltip/>\n );\n }\n}\n","@import '~styles/utils/include-media';\n\n:local {\n $top-nav-height: 4.1875rem;\n $clamp-padding-bottom: 0.14rem;\n $nav-item-padding: map-get($spacers, 2);\n\n $icon-bg-size: 2rem; // 32px\n\n .leftNav {\n top: $top-nav-height;\n width: $cv-left-nav-width;\n z-index: $cv-left-nav-z-index;\n height: calc(100vh - #{$top-nav-height});\n }\n\n .leftNavItem {\n --nav-item-active-bg: #{$gray-200};\n --nav-item-hover-bg: #{$light-blue};\n\n [data-nav-theme='live'] & {\n --nav-item-active-bg: #{$light-green};\n }\n\n display: flex;\n min-height: $icon-bg-size;\n flex-direction: row;\n padding: $nav-item-padding;\n padding-bottom: $nav-item-padding - $clamp-padding-bottom; // clamp-2 classname adds padding-bottom: 0.14rem\n\n &:hover {\n background-color: var(--nav-item-hover-bg);\n }\n\n &.active {\n background-color: var(--nav-item-active-bg);\n }\n\n &.static {\n &:hover, &.active {\n background-color: unset;\n cursor: default !important;\n }\n }\n }\n\n .leftNavIconContainer {\n color: $black;\n\n width: $icon-bg-size;\n height: $icon-bg-size;\n \n display: flex;\n justify-content: center;\n align-items: center;\n\n flex-shrink: 0;\n }\n\n .leftNavExpanded {\n z-index: 1031;\n\n @include media('<=xl') {\n margin-right: -$cv-left-nav-width;\n }\n\n & ul {\n gap: map-get($spacers, 3);\n }\n\n .leftNavItemContainer {\n padding-left: map-get($spacers, 3);\n padding-right: map-get($spacers, 3);\n }\n \n .leftNavItem {\n gap: map-get($spacers, 3);\n\n align-items: center;\n border-radius: $border-radius-md;\n }\n }\n\n .leftNavCollapsed {\n z-index: 1031;\n width: $cv-left-nav-small-width;\n\n & ul {\n gap: map-get($spacers, 2);\n }\n\n .leftNavItemContainer, .leftNavDividerContainer {\n padding-left: map-get($spacers, 1);\n padding-right: map-get($spacers, 1);\n }\n\n .leftNavItem {\n flex-direction: column;\n align-items: center;\n align-self: stretch;\n text-align: center;\n \n gap: map-get($spacers, 1);\n\n border-radius: $border-radius-sm;\n }\n\n .leftNavItemText {\n font-size: $font-size-sm;\n }\n }\n}",":local {\n .myVideosRedDot {\n top: 0.35rem; // to position dot in the icon corner\n right: 0.2rem; // to position dot in the icon corner\n }\n}","import React from 'react';\n\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { EntityType, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { IconCircle } from 'libs/shared/components/icon-circle/IconCircle';\nimport { SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { ImageSize } from 'libs/shared/enums/Images';\nimport { ImageHelper } from 'libs/shared/utils/ImageHelper';\n\nimport { LeftNavId } from 'shared/enums/LeftNavId';\nimport { LeftNavHelper } from 'shared/utils/LeftNavHelper';\n\nimport { LeftNavComplications } from '../../enums/LeftNavComplications';\nimport { LeftNavAppLinkItem } from '../../interfaces/LeftNavItem';\nimport { LeftNavComplication } from '../left-nav-complication/LeftNavComplication';\n\nimport baseStyles from '../../left-nav-v2.module.scss';\nimport styles from './left-nav-applink.module.scss';\n\nconst leftNavDotPositionMap: {[key in LeftNavId]?: string } = {\n [LeftNavId.MyVideos]: styles.myVideosRedDot\n};\n\nexport interface LeftNavAppLinkProps extends LeftNavAppLinkItem {}\n\nexport const LeftNavAppLink = React.forwardRef(\n (props: LeftNavAppLinkProps, ref: React.Ref<HTMLElement>) => {\n const itemContainerClassName = classNames(\n baseStyles.leftNavItem,\n 'w-100 text-decoration-none',\n props.isActive && baseStyles.active\n );\n\n const leftNavIconContainerClassName = classNames(\n 'position-relative',\n baseStyles.leftNavIconContainer,\n props.classNames?.icon\n );\n\n const dotPositionClassName = classNames(\n 'position-absolute',\n leftNavDotPositionMap[props.id] ?? 'top-0 end-0'\n );\n \n const isUploading = props.complications?.includes(LeftNavComplications.Uploading);\n \n return (\n <AppLink\n ref={ref}\n className={itemContainerClassName}\n appLink={props.appLink}\n analyticsData={{\n id: LeftNavHelper.mapIdToAnalyticsId(props.id),\n label: props.name,\n icon: props.svg\n }}\n analyticsOptions={{\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.LeftNav\n }}\n onClick={props.onClick}\n >\n <div className={leftNavIconContainerClassName}>\n <IconCircle\n svg={props.svg}\n textVariant='dark'\n svgSize={SvgContainerSize.Standard}\n imageUrl={ImageHelper.createUrl(props.imageUrl, { size: ImageSize.Small })}\n />\n {isUploading && (\n <LeftNavComplication type={LeftNavComplications.Uploading} className={dotPositionClassName} />\n )}\n </div>\n <span className={classNames('clamp-2 text-wrap', baseStyles.leftNavItemText)}>{props.name}</span>\n </AppLink>\n );\n }\n);\n",":local {\n .leftNavDropdown {\n --container-width: 14.875rem;\n\n width: var(--container-width);\n padding: map-get($spacers, 2) 0;\n\n // This should be higher than the left navbar z-index (1031) and lower than top nav z-index (1035)\n z-index: 1032;\n }\n\n .leftNavDropdownItem {\n padding: map-get($spacers, 2) map-get($spacers, 3);\n gap: map-get($spacers, 2);\n }\n\n .parentPremiumIconContainer {\n position: absolute;\n right: 0.7rem;\n top: -0.3rem;\n }\n}","import React from 'react';\n\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { ChevronDownSvg } from 'libs/shared/images/svg/arrows/ChevronDownSvg';\nimport { ChevronUpSvg } from 'libs/shared/images/svg/arrows/ChevronUpSvg';\nimport { CheckSvg } from 'libs/shared/images/svg/status/CheckSvg';\nimport { SvgIcon } from 'libs/shared/utils/SvgHelper';\n\nimport { LeftNavComplications } from '../../enums/LeftNavComplications';\nimport { LeftNavComplication } from '../left-nav-complication/LeftNavComplication';\n\nimport baseStyles from '../../left-nav-v2.module.scss';\nimport styles from './left-nav-dropdown.module.scss';\n\ninterface LeftNavDropdownButtonProps extends React.HTMLAttributes<HTMLDivElement> {\n isActive: boolean;\n isStatic?: boolean;\n svg: SvgIcon;\n classNames?: {\n container?: string,\n icon?: string\n };\n isOpen: boolean;\n showActiveIcon?: boolean;\n showDropIndicator?: boolean;\n isNavCollapsed?: boolean;\n isPremiumFeature?: boolean;\n isParent?: boolean;\n}\n\nexport const LeftNavDropdownButton = React.forwardRef(\n (props: LeftNavDropdownButtonProps, ref: React.RefObject<HTMLDivElement>) => {\n const { children, onClick } = props;\n\n const itemContainerClassName = classNames(\n baseStyles.leftNavItem,\n props.classNames?.container,\n props.isStatic && baseStyles.static,\n 'dropdown-item w-100 text-decoration-none'\n );\n\n const leftNavIconContainerClassName = classNames(\n baseStyles.leftNavIconContainer,\n props.classNames?.icon,\n 'rounded-2'\n );\n\n const premiumFeatureContainerClassName = classNames(\n props.isNavCollapsed && props.isParent ?\n styles.parentPremiumIconContainer : 'position-relative ms-auto'\n );\n\n const isOpenIcon = props.isOpen ? ChevronUpSvg : ChevronDownSvg;\n \n return (\n <DivButton ref={ref} onClick={onClick} className={itemContainerClassName}>\n {props.showActiveIcon && (\n <div className={classNames(!props.isActive && 'invisible')}>\n <SvgContainer\n svg={CheckSvg}\n size={SvgContainerSize.Small}\n />\n </div>\n )}\n <div className={leftNavIconContainerClassName}>\n <div className='w-100 h-100 d-flex justify-content-center align-items-center text-white'>\n <SvgContainer\n svg={props.svg}\n size={SvgContainerSize.Standard}\n />\n </div>\n </div>\n <div className='d-flex align-items-center gap-1'>\n <span className={classNames('clamp-2 text-wrap', baseStyles.leftNavItemText)}>{children}</span>\n {props.showDropIndicator && <SvgContainer svg={isOpenIcon} size={SvgContainerSize.Small} />}\n </div>\n\n {props.isPremiumFeature && (\n <LeftNavComplication\n type={LeftNavComplications.Premium}\n className={premiumFeatureContainerClassName}\n svgSize={props.isNavCollapsed ? SvgContainerSize.Small : SvgContainerSize.Standard}\n />\n )}\n </DivButton>\n );\n }\n);\n","import React from 'react';\nimport { Dropdown, DropdownMenuProps } from 'react-bootstrap';\nimport { createPortal } from 'react-dom';\n\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { LeftNavComplication } from 'shared/views/left-nav-v2/components/left-nav-complication/LeftNavComplication';\n\nimport { LeftNavComplications } from '../../enums/LeftNavComplications';\nimport { LeftNavTheme } from '../../enums/LeftNavTheme';\nimport { LeftNavDropdownItem } from '../../interfaces/LeftNavItem';\n\nimport { LeftNavDropdownButton } from './LeftNavDropdownButton';\n\nimport styles from './left-nav-dropdown.module.scss';\n\ntype PortalMenuProps = React.PropsWithChildren<\n React.HTMLAttributes<HTMLDivElement> & DropdownMenuProps & { 'data-nav-theme'?: LeftNavTheme }\n>;\n\nexport interface LeftNavDropdownProps extends LeftNavDropdownItem {\n navTheme?: LeftNavTheme;\n}\n\n/**\n * Since the dropdown menu is portalled, we need to pass the nav theme to the menu\n * so that the theme variables are applied to the menu.\n */\nconst PortalMenu = React.forwardRef(\n (props: PortalMenuProps, ref: React.RefObject<HTMLDivElement>) => {\n const {\n className, children, style, tabIndex,\n ['aria-labelledby']: ariaLabelledby,\n ['data-nav-theme']: dataNavTheme\n } = props;\n\n const portalMenuClassName = classNames(styles.leftNavDropdown, className);\n\n return createPortal(\n <div\n ref={ref}\n className={portalMenuClassName}\n style={style}\n aria-labelledby={ariaLabelledby}\n tabIndex={tabIndex}\n data-nav-theme={dataNavTheme}\n >\n {children}\n </div>,\n document.getElementById('dialog-region')\n );\n }\n);\n\nexport const LeftNavDropdown = React.forwardRef(\n (props: LeftNavDropdownProps, ref: React.Ref<HTMLDivElement>) => {\n const [ isOpen, setIsOpen ] = React.useState(false);\n\n const itemEntries = Object.entries(props.items);\n\n const hasDropdownItems = itemEntries.length > 0;\n const showDropdown = hasDropdownItems && isOpen;\n function handleToggle(nextShown: boolean) {\n if (!hasDropdownItems)\n return;\n\n setIsOpen(nextShown);\n }\n\n return (\n <Dropdown show={showDropdown} onToggle={handleToggle}>\n <div className='d-flex flex-row justify-content-between align-items-center'>\n <Dropdown.Toggle\n as={LeftNavDropdownButton}\n ref={ref}\n isActive={props.isActive}\n isStatic={!hasDropdownItems}\n isOpen={showDropdown}\n svg={props.svg}\n classNames={{\n icon: props.classNames?.icon\n }}\n isNavCollapsed={props.isNavCollapsed}\n showDropIndicator={!props.isNavCollapsed && hasDropdownItems}\n isPremiumFeature={props.complications?.includes(LeftNavComplications.Premium)}\n isParent={true}\n >\n <span className='fw-medium'>{props.name}</span>\n </Dropdown.Toggle>\n </div>\n <Dropdown.Menu\n as={PortalMenu}\n className={props.classNames?.dropdownMenu}\n data-nav-theme={props.navTheme}\n popperConfig={{ strategy: 'fixed' }}\n >\n {props.complications?.includes(LeftNavComplications.Header) && (\n <LeftNavComplication\n type={LeftNavComplications.Header}\n className={classNames(\n 'd-flex align-self-stretch align-items-center',\n styles.leftNavDropdownItem\n )}\n />\n )}\n {itemEntries.map(([ group, items ], index) => {\n const isFirstGroupItem = index === 0;\n \n return (\n <React.Fragment key={group}>\n {(!isFirstGroupItem) && (\n <Dropdown.Divider style={{ width: '90%' }} className='mx-auto' />\n )}\n \n {items.map(item => (\n <Dropdown.Item\n as={LeftNavDropdownButton}\n key={`${group}-${item.name}`}\n onClick={() => {\n props.onClick?.();\n item.onClick();\n }}\n svg={item.icon}\n classNames={{\n icon: item.iconClassName,\n container: classNames(\n 'd-flex align-self-stretch align-items-center',\n styles.leftNavDropdownItem\n )\n }}\n isOpen={isOpen}\n isActive={item.selected}\n isPremiumFeature={item.complications?.includes(LeftNavComplications.Premium)}\n isNavCollapsed={true}\n showActiveIcon={true}\n >\n {item.name}\n </Dropdown.Item>\n ))}\n </React.Fragment>\n );\n })}\n </Dropdown.Menu>\n </Dropdown>\n );\n }\n);\n","import React from 'react';\n\nimport { DevError } from 'libs/common/backbone/errors/DevError';\n\nimport { LeftNavTheme } from '../../enums/LeftNavTheme';\nimport type { LeftNavItem, ValidLeftNavItemType } from '../../interfaces/LeftNavItem';\nimport { LeftNavAppLink, LeftNavAppLinkProps } from '../left-nav-applink/LeftNavAppLink';\nimport { LeftNavDropdown, LeftNavDropdownProps } from '../left-nav-dropdown/LeftNavDropdown';\n\ntype AnyLeftNavItemProps = LeftNavAppLinkProps | LeftNavDropdownProps;\n\ninterface LeftNavItemConfig {\n Component: React.ComponentType<AnyLeftNavItemProps & { navTheme?: LeftNavTheme } & React.RefAttributes<HTMLElement>>;\n}\n\nconst LeftNavItemTypeConfig: Record<ValidLeftNavItemType, LeftNavItemConfig> = {\n applink: {\n Component: LeftNavAppLink\n },\n dropdown: {\n Component: LeftNavDropdown\n }\n};\n\ninterface LeftNavItemProps {\n item: LeftNavItem;\n navTheme: LeftNavTheme;\n onClickNavItem: () => void;\n}\n\nexport function LeftNavItemComponent(props: LeftNavItemProps): JSX.Element {\n const { item, navTheme, onClickNavItem } = props;\n\n const config = LeftNavItemTypeConfig[item.type];\n\n if (!config) {\n throw new DevError(`Invalid left nav item type: ${item.type}`);\n }\n\n function onClick() {\n onClickNavItem();\n item.onClick?.();\n }\n\n const Component = config.Component;\n\n return <Component {...item} navTheme={navTheme} onClick={onClick} />;\n}\n","import React from 'react';\n\ninterface ScrollTrackProps {\n style: React.CSSProperties;\n}\n\nexport const ScrollTrack = React.forwardRef((props: ScrollTrackProps, ref: React.LegacyRef<HTMLDivElement>) => {\n const { style, ...other } = props;\n\n return (\n <div\n {...other}\n ref={ref}\n style={{\n ...style,\n // These are all the default sizes for the track bar\n // However the scrollbar breaks if they're not passed in\n width: '6px',\n right: '2px',\n top: '2px',\n borderRadius: '3px',\n bottom: '2px'\n }}\n />\n );\n});\n","import React from 'react';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\n\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { LeftNavItemComponent } from './components/left-nav-item-component/LeftNavItemComponent';\nimport { ScrollTrack } from './components/scroll-track/ScrollTrack';\nimport { LeftNavState } from './enums/LeftNavState';\nimport { LeftNavTheme } from './enums/LeftNavTheme';\nimport { GroupedLeftNavItemsConfig } from './utils/create-left-nav-builder/createLeftNavBuilder';\n\nimport styles from './left-nav-v2.module.scss';\n\ninterface LeftNavV2ViewProps {\n navState: LeftNavState;\n navTheme: LeftNavTheme;\n onClickNavItem: () => void;\n items: GroupedLeftNavItemsConfig;\n}\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function LeftNavV2View(props: LeftNavV2ViewProps): JSX.Element {\n if (props.navState === LeftNavState.Hidden) {\n return <></>;\n }\n \n const navClassName = classNames(\n 'position-sticky bg-white overflow-y-clip float-start border-end border-gray-300',\n styles.leftNav,\n props.navState === LeftNavState.Open && styles.leftNavExpanded,\n props.navState === LeftNavState.Collapsed && styles.leftNavCollapsed\n );\n\n const navContainerClassName = classNames(\n 'position-relative',\n styles.leftNavItemContainer\n );\n\n const groupedItemEntries = Object.entries(props.items);\n\n return (\n <nav className={navClassName} data-nav-state={props.navState} data-nav-theme={props.navTheme}>\n <Scrollbars\n renderTrackVertical={props => <ScrollTrack {...props} />}\n >\n <ul className='d-flex flex-column pt-3 list-unstyled'>\n {groupedItemEntries.map(([ group, navItems ], groupIndex) => {\n const isFirstGroupItem = groupIndex === 0;\n\n return (\n <React.Fragment key={`${group}-${groupIndex}`}>\n {(!isFirstGroupItem) && (\n <li className={styles.leftNavDividerContainer}>\n <hr className='m-0' />\n </li>\n )}\n \n {navItems.map((item, itemindex) => (\n <li key={`${group}-${itemindex}`} className={navContainerClassName}>\n <LeftNavItemComponent item={item} navTheme={props.navTheme} onClickNavItem={props.onClickNavItem} />\n </li>\n ))}\n </React.Fragment>\n );\n })}\n </ul>\n </Scrollbars>\n </nav>\n );\n}\n",":local {\n .openInAppPrompt {\n bottom: 0;\n z-index: 5000;\n border-top-right-radius: 1.5rem;\n border-top-left-radius: 1.5rem;\n max-width: 100vw;\n }\n\n .mask {\n z-index: 4999;\n }\n\n .logo {\n width: 2.5rem;\n height: 2.5rem;\n }\n\n .button {\n width: 5.375rem;\n }\n\n .noScroll {\n position: fixed;\n overflow: hidden;\n width: 100%;\n height: 100%;\n }\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { UserAgentHelper } from 'libs/common/backbone/utils/UserAgentHelper';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { EntityType, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { ClickViewAvatar } from 'libs/shared/components/clickview-avatar/ClickViewAvatar';\nimport { SvgContainer2 } from 'libs/shared/components/svg-container/SvgContainer2';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { docCookies } from 'libs/shared/utils/DocCookies';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { useDeepLinks } from 'shared/hooks/useDeepLinks';\n\nimport styles from './open-in-app-prompt.module.scss';\n\nconst namespace = 'shared.openInAppPrompt';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nconst DISMISS_COOKIE_ID = '_dismissOpenInAppPrompt';\n\nconst getBrowserData = () => {\n const browserData = UserAgentHelper.getBrowser();\n\n const imageUrls = ImageUrls.BrowserLogos;\n\n switch (browserData.browser) {\n case 'Edge':\n case 'Internet Explorer':\n return {\n name: getPhrase('edge'),\n logo: imageUrls.EDGE\n };\n\n case 'Firefox':\n return {\n name: getPhrase('firefox'),\n logo: imageUrls.FIREFOX\n };\n\n case 'Safari':\n return {\n name: getPhrase('safari'),\n logo: imageUrls.SAFARI\n };\n \n case 'Chrome':\n default:\n return {\n name: getPhrase('chrome'),\n logo: imageUrls.CHROME\n };\n }\n};\n\nexport const OpenInAppPromptView = React.memo(function(): JSX.Element {\n const { deepLink, showDeepLink, onClickDeepLink } = useDeepLinks(null, LocationContext.OpenInAppPrompt);\n\n const [ hasBeenDismissed, setHasBeenDismissed ] = React.useState(false);\n\n function shouldDisplay(): boolean {\n // Local state. This will be true if the user has dismissed the prompt in their current session\n if (hasBeenDismissed)\n return false;\n\n if (docCookies.getItem(DISMISS_COOKIE_ID))\n return false;\n\n // Config must be fetch & have the Branch IO URL for us to link to\n return showDeepLink;\n }\n\n const display = shouldDisplay();\n\n React.useEffect(() => {\n if (!display)\n return;\n\n document.body.classList.add(styles.noScroll);\n return () => document.body.classList.remove(styles.noScroll);\n }, [display]);\n\n if (!display)\n return <></>;\n\n function onDismiss(): void {\n AnalyticsHelper.logUserAction({\n deepLink\n }, {\n location: LocationContext.OpenInAppPrompt,\n entity: EntityType.DeepLink,\n actionType: UserAction.Dismiss\n });\n\n hideBanner();\n }\n\n function onOpen(): void {\n onClickDeepLink();\n hideBanner();\n }\n\n function hideBanner(): void {\n // Cookie expires after 1 day\n docCookies.setItem(DISMISS_COOKIE_ID, 'true', 28800, null, null, true, 'lax');\n\n document.body.classList.remove(styles.noScroll);\n\n setHasBeenDismissed(true);\n }\n\n const browserData = getBrowserData();\n\n return (\n <>\n <div onClick={onDismiss} className={`modal-backdrop show ${styles.mask}`} />\n\n <div className={`position-fixed w-100 bg-white pb-3 px-3 ${styles.openInAppPrompt}`}>\n <div className='text-center fw-bold border-bottom py-3 mb-3 h6'>\n <Text namespace={namespace} phrase='openIn' />\n </div>\n\n <div className='d-flex flex-column flex-wrap justify-content-center align-items-between w-100 mx-auto'>\n <div className='d-flex justify-content-between align-items-center w-100 mb-2'>\n <div className='d-flex align-items-center flex-grow-1'>\n <SvgContainer2 className={`border rounded-3 me-2 ${styles.logo}`}>\n <ClickViewAvatar />\n </SvgContainer2>\n <p className='fw-bold m-0'>\n <Text namespace={namespace} phrase='clickViewApp' />\n </p>\n </div>\n <div>\n <a\n href={deepLink}\n onClick={onOpen}\n className={`btn btn-dark ${styles.button}`}\n >\n <Text namespace={namespace} phrase='open' />\n </a>\n </div>\n </div>\n\n <div className='d-flex justify-content-between align-items-center w-100'>\n <div className='d-flex align-items-center flex-grow-1'>\n <div className={`border rounded-3 me-2 ${styles.logo}`}>\n <img\n src={browserData.logo}\n alt={browserData.name}\n className='img-fluid'\n />\n </div>\n\n <p className='fw-bold m-0'>\n {browserData.name}\n </p>\n </div>\n <div>\n <button onClick={onDismiss} className={`btn btn-outline-dark ${styles.button}`}>\n <Text namespace={namespace} phrase='continue' />\n </button>\n </div>\n </div>\n </div>\n </div>\n </>\n );\n});\n",":local {\n .productTips {\n width: min-content;\n }\n\n .imageCard {\n width: 19rem;\n height: 13.75rem;\n background-repeat: no-repeat;\n background-position: center;\n background-size: 13.75rem;\n transition: background-image 0.5s ease-in-out;\n transition: background-color 0.5s ease-in-out;\n\n &.imageCardBottom {\n background-position: bottom;\n background-size: 15rem;\n }\n }\n\n .closeButton {\n top: 0;\n right: 0;\n }\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { ActionButton } from 'libs/shared/components/actions/ActionButton';\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { ExternalLink } from 'libs/shared/components/external-link/ExternalLink';\nimport { SliderDots } from 'libs/shared/components/slider-dots/SliderDots';\nimport { CloseSvg } from 'libs/shared/images/svg/actions/CloseSvg';\n\nimport styles from './product-tip.module.scss';\n\nconst namespace = 'shared.productTip';\n\ninterface ProductTipProps {\n imageUrl: string;\n backgroundColor: string;\n heading: string;\n description: React.ReactNode;\n backgroundImageClassName?: string;\n\n containerClassName?: string;\n\n sliderStep?: number;\n sliderLength?: number;\n\n externalLink?: string;\n externalLinkText?: string;\n onClickExternalLink?: (href: string) => void;\n\n lastCtaText?: string;\n\n onClickCta: () => void;\n onClickClose: () => void;\n onSliderClick?: (step: number) => void;\n}\n\nexport function ProductTip(props: ProductTipProps) {\n // You may only go back, or go 1 ahead\n function isDisabled(index: number): boolean {\n if (index + 1 < props.sliderLength)\n return false;\n\n if (index === props.sliderStep + 1)\n return false;\n\n return true;\n }\n\n function getCtaButtonText(): string {\n if (props.sliderStep + 1 < props.sliderLength)\n return LanguageService.getPhrase(namespace, 'continue');\n\n return props.lastCtaText ?? LanguageService.getPhrase(namespace, 'done');\n }\n\n function getImageClass(): string {\n let className = `${styles.imageCard} ${props.backgroundColor} rounded-top-lg`;\n\n if (props.backgroundImageClassName)\n className += ` ${props.backgroundImageClassName}`;\n\n return className;\n }\n\n return (\n <div className={`${styles.productTips} position-relative d-flex flex-column ${props.containerClassName}`}>\n <ActionButton\n className={`${styles.closeButton} svg-container btn position-absolute text-white m-2 p-0`}\n svg={CloseSvg}\n onClick={props.onClickClose}\n />\n\n <div\n style={{ backgroundImage: `url(${props.imageUrl}` }}\n className={getImageClass()}\n ></div>\n\n <div className='bg-dark text-white rounded-bottom-lg p-3'>\n {props.sliderLength > 1 && (\n <SliderDots\n sliderLength={props.sliderLength}\n sliderStep={props.sliderStep}\n className='mb-1'\n onSliderDotClick={props.onSliderClick}\n isDisabled={isDisabled}\n />\n )}\n\n <div className='d-flex align-items-baseline mb-2'>\n <h4 className='mb-0'>{props.heading}</h4>\n </div>\n\n <p className='mb-2'>{props.description}</p>\n\n <div className='d-flex justify-content-between align-items-center'>\n <ExternalLink\n href={props.externalLink}\n className='text-white text-underline'\n onClick={() => props.onClickExternalLink(props.externalLink)}\n newTab\n >\n {props.externalLinkText}\n </ExternalLink>\n\n <DivButton className='btn btn-light fw-semibold' onClick={props.onClickCta}>\n {getCtaButtonText()}\n </DivButton>\n </div>\n </div>\n </div>\n );\n}\n",":local {\n .image {\n background-position: center;\n background-size: 14.875rem;\n }\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { ProductTip } from 'libs/shared/components/product-tip/ProductTip';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { ProductTipsViewProps } from 'libs/shared/interfaces';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\n\nimport styles from './nz-hub-product-tip.module.scss';\n\nconst namespace = 'productTips.nzHub';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function NzHubProductTipView(props: ProductTipsViewProps): JSX.Element {\n return (\n <ProductTip\n imageUrl={ImageUrls.ProductTips.NZ_HUB}\n backgroundColor='bg-teal'\n backgroundImageClassName={styles.image}\n heading={getPhrase('heading')}\n description={<Text namespace={namespace} phrase='description'/>}\n sliderLength={props.sliderLength}\n sliderStep={props.sliderStep}\n lastCtaText={getPhrase('close')}\n onClickClose={props.onClickClose}\n onClickCta={props.onClickCta}\n onSliderClick={props.onSliderClick}\n />\n );\n}\n",":local {\n .image {\n background-position: center;\n background-size: 14rem;\n }\n\n .container {\n left: 27px;\n }\n}","import React from 'react';\n\nimport { LocationUtils } from 'libs/common/backbone/core';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { ProductTip } from 'libs/shared/components/product-tip/ProductTip';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { ProductTipsViewProps } from 'libs/shared/interfaces';\nimport { ArticleHelper } from 'libs/shared/utils/ArticleHelper';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\n\nimport styles from './streamable-migrated-product-tip.module.scss';\n\nconst namespace = 'productTips.streamableMigrated';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function StreamableMigratedProductTipView(props: ProductTipsViewProps): JSX.Element {\n function openExternalLink(href: string) {\n LocationUtils.PageLoad(href, true);\n }\n\n return (\n <ProductTip\n imageUrl={ImageUrls.ProductTips.STREAMABLE_MIGRATED}\n backgroundColor='bg-green'\n backgroundImageClassName={styles.image}\n heading={getPhrase('heading')}\n description={<Text namespace={namespace} phrase='description'/>}\n onClickClose={props.onClickClose}\n onClickCta={props.onClickCta}\n externalLink={ArticleHelper.getUpdatesBlogArticleUrl('clickview-live')}\n externalLinkText={getPhrase('externalLink')}\n onClickExternalLink={openExternalLink}\n containerClassName={styles.container}\n />\n );\n}\n",":local {\n .image {\n background-position: center;\n background-size: 14rem;\n }\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { ProductTip } from 'libs/shared/components/product-tip/ProductTip';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { ProductTipsViewProps } from 'libs/shared/interfaces';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\n\nimport styles from './tutorial-videos-product-tip.module.scss';\n\nconst namespace = 'productTips.tutorialVideos';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function TutorialPlaylistProductTipView(props: ProductTipsViewProps): JSX.Element {\n return (\n <ProductTip\n imageUrl={ImageUrls.ProductTips.TUTORIAL_VIDEOS}\n backgroundColor='bg-green'\n backgroundImageClassName={styles.image}\n heading={getPhrase('heading')}\n description={<Text namespace={namespace} phrase='description'/>}\n sliderLength={props.sliderLength}\n sliderStep={props.sliderStep}\n onClickClose={props.onClickClose}\n onClickCta={props.onClickCta}\n onSliderClick={props.onSliderClick}\n />\n );\n}\n",":local {\n $cv-product-tips-highlight: 0px 0px map-get($spacers, 1) 0.06rem $blue;\n\n @mixin productTipHighlight {\n &::before {\n content: '';\n border-radius: map-get($spacers, 1);\n box-shadow: $cv-product-tips-highlight;\n margin-left: 0;\n margin-right: 0;\n position: absolute;\n overflow: hidden;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n }\n }\n\n .leftNavPlaylist {\n @include productTipHighlight;\n position: relative;\n margin-right: map-get($spacers, 1);\n margin-left: map-get($spacers, 1);\n }\n\n .presentationSwitcher {\n @include productTipHighlight;\n }\n\n .topicsDirectoryTab {\n @include productTipHighlight;\n position: relative;\n }\n\n .giveFeedbackForm {\n @include productTipHighlight;\n }\n\n .whatsNewLink {\n @include productTipHighlight;\n\n &::before {\n border-radius: 50%;\n }\n }\n\n .hubsNavItem {\n @include productTipHighlight;\n position: relative;\n }\n}","import { ProductTipDescriptor } from 'libs/analytics/interfaces';\n\nimport { SettingKind } from 'libs/shared/enums/SettingKind';\nimport { SettingName } from 'libs/shared/enums/SettingName';\nimport { ProductTipConfig } from 'libs/shared/interfaces';\n\nimport { NzHubProductTipView } from 'shared/views/product-tips/tips/nz-hub/NzHubProductTipView';\nimport { StreamableMigratedProductTipView } from 'shared/views/product-tips/tips/streamable-migrated/StreamableMigratedProductTipView';\nimport { TutorialPlaylistProductTipView } from 'shared/views/product-tips/tips/tutorial-playlist/TutorialPlaylistProductTipView';\n\nimport styles from './product-tip-styles.module.scss';\n\n/**\n * The order here will determine the order that the product tips are displayed in the product\n * if there are ever more than 1 displayed on a particular page. So if you're adding a new tip,\n * please carefully consider which other tips may show on the same page when selecting your position.\n */\nexport const LITE_PRODUCT_TIPS: ProductTipConfig[] = [\n {\n id: 'tutorial-videos',\n viewComponent: TutorialPlaylistProductTipView,\n placement: 'bottom-right',\n anchor: 'element',\n predicate: ({ shouldDisplayTutorialVideosProductTip }) => shouldDisplayTutorialVideosProductTip,\n onComplete: updateUserSettingAsync => {\n return updateUserSettingAsync({\n name: SettingName.HasDisplayedTutorialVideosProductTip,\n value: true,\n kind: SettingKind.Setting\n });\n },\n analyticsDescriptor: ProductTipDescriptor.TutorialVideosProductTip,\n containerClass: styles.whatsNewLink\n },\n {\n id: 'sl-migrated',\n viewComponent: StreamableMigratedProductTipView,\n placement: 'right',\n anchor: 'element',\n predicate: ({ shouldDisplaySLMigratedProductTip }) => shouldDisplaySLMigratedProductTip,\n onComplete: updateUserSettingAsync => {\n return updateUserSettingAsync({\n name: SettingName.HasDisplayedSLMigratedProductTip,\n value: true,\n kind: SettingKind.Setting\n });\n },\n analyticsDescriptor: ProductTipDescriptor.SlMigratedProductTip\n }, {\n id: 'nz-hub',\n viewComponent: NzHubProductTipView,\n placement: 'right',\n anchor: 'element',\n predicate: ({ settings, hasNzHubDashboard }) => hasNzHubDashboard && !settings.hasDisplayedNzHubProductTip,\n onComplete: updateUserSettingAsync => {\n return updateUserSettingAsync({\n name: SettingName.HasDisplayedNzHubProductTip,\n value: true,\n kind: SettingKind.Setting\n });\n },\n analyticsDescriptor: ProductTipDescriptor.NzHubProductTip,\n containerClass: styles.hubsNavItem\n }\n];\n","import { Flight } from 'libs/common/react/index';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useProducts } from 'libs/shared/hooks/UseProducts';\nimport { useSettings } from 'libs/shared/hooks/useSettings';\nimport { Config, CurrentUser, User } from 'libs/shared/interfaces';\n\nconst SL_MIGRATION_DATE = '2026-08-27T06:00:00Z';\nconst STG_SL_MIGRATION_DATE = '2026-08-09T06:00:00Z';\n\nexport function useStreamableMigration() {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const { hasProduct } = useProducts();\n\n const detailCurrentUser = Flight.useBasicFetch<User>(\n currentUser.data?.id &&\n currentUser.data?.isAuthenticated &&\n UserRequests.user(currentUser?.data.id)\n );\n\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n const settings = useSettings(null);\n\n const registerAfterMigrationDate = DateHelper.isAfter(detailCurrentUser.data?.dateCreated, config.data?.liteUrl.includes('staging') ? STG_SL_MIGRATION_DATE : SL_MIGRATION_DATE);\n\n function shouldDisplaySLMigratedProductTip() {\n if (!currentUser.hasCompleted || !currentUser.data.isAuthenticated || !detailCurrentUser.hasCompleted)\n return false;\n\n // if user doesn't have access to clickview Live\n if (!settings.clickViewLive)\n return false;\n\n if (settings.hasDisplayedSLMigratedProductTip)\n return false;\n\n if (registerAfterMigrationDate)\n return false;\n \n // product check\n if (!hasProduct(ProductId.StreamableLearning))\n return false;\n\n return true;\n }\n\n return {\n shouldDisplaySLMigratedProductTip: shouldDisplaySLMigratedProductTip()\n };\n}\n","import { Flight } from 'libs/common/react/index';\n\nimport { PlaylistSortType } from 'libs/shared/apps/playlists/enums/PlaylistSortType';\nimport { PlaylistCollectionIdentifier } from 'libs/shared/apps/playlists/interfaces';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { PlaylistRequests } from 'libs/shared/flight-requests/PlaylistRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useProducts } from 'libs/shared/hooks/UseProducts';\nimport { useSettings } from 'libs/shared/hooks/useSettings';\nimport { CurrentUser, PlaylistCollection } from 'libs/shared/interfaces';\n\nimport { useHubDashboards } from 'shared/hooks/hubs/useHubDashboards';\nimport { useAvailablePresentations } from 'shared/hooks/presentations/useAvailablePresentations';\nimport { useStreamableMigration } from 'shared/hooks/product-tips/useStreamableMigration';\nimport { ValidHubs } from 'shared/utils/HubHelper';\n\nimport { useTutorialVideos } from 'apps/dashboard/hooks/useTutorialVideos';\n\nexport function useFetchProductTipsData() {\n // Data fetching for all possible product tips\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const { availablePresentations, hasCompleted: hasPresentationsLoaded } = useAvailablePresentations();\n const playlists = Flight.useBasicFetch<PlaylistCollection>(\n !!currentUser.data?.isAuthenticated &&\n PlaylistRequests.getUserPlaylists(new PlaylistCollectionIdentifier(PlaylistSortType.Newest))\n );\n const { hasProduct } = useProducts();\n\n const settings = useSettings(null);\n const tutorialVideoContext = useTutorialVideos();\n const slMigrationContext = useStreamableMigration();\n const { hasHubDashboard } = useHubDashboards();\n\n function hasCompleted(): boolean {\n return (\n hasPresentationsLoaded &&\n !settings.isLoadingSettings &&\n playlists.hasCompleted &&\n currentUser.hasCompleted\n );\n }\n\n return {\n displayTips: hasProduct(ProductId.Primary),\n presentations: availablePresentations,\n playlists: playlists.data?.data ?? [],\n currentUser: currentUser.data,\n shouldDisplayTutorialVideosProductTip: tutorialVideoContext.shouldShowProductTip,\n shouldDisplaySLMigratedProductTip: slMigrationContext.shouldDisplaySLMigratedProductTip,\n hasNzHubDashboard: hasHubDashboard(ValidHubs.NZ_HUB),\n settings,\n hasCompleted: hasCompleted()\n };\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\n\nimport { LocationContext } from 'libs/analytics/interfaces';\n\nimport { useProductTipsContext } from 'libs/shared/context/product-tips-context/ProductTipsContext';\nimport { useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { useSettings } from 'libs/shared/hooks/useSettings';\nimport { ProductTipId } from 'libs/shared/interfaces';\nimport { ProductTipConfig, ProductTipPredicateOptions } from 'libs/shared/interfaces';\nimport { ContextService } from 'libs/shared/services/ContextService';\n\nimport { LITE_PRODUCT_TIPS } from 'shared/constants/product-tips/LiteProductTipsConfig';\nimport { usePluginHelper } from 'shared/hooks/use-plugin-helper/usePluginHelper';\n\nimport { useFetchProductTipsData } from './useFetchProductTipsData';\n\ntype CompletedProductTips = Partial<Record<ProductTipId, boolean>>;\n\nexport function useLiteProductTips() {\n const productTipsData = useFetchProductTipsData();\n\n const { refs } = useProductTipsContext();\n const { updateUserSettingAsync } = useSettings(LocationContext.ProductTips);\n const breakpoints = useBreakpoints();\n const { isPlugin } = usePluginHelper();\n\n const [ completedProductTips, setCompletedProductTips ] = React.useState<CompletedProductTips>({});\n\n function onComplete(tips: ProductTipConfig[]): void {\n setCompletedProductTips({\n ...completedProductTips,\n ...tips.reduce((acc, tip) => ({ ...acc, [tip.id]: true }), {})\n });\n \n tips.forEach(tip => {\n tip.onComplete(updateUserSettingAsync);\n });\n }\n\n const currentAppRoute = ContextService.getCurrentRoute().appLink;\n const predicateOptions: ProductTipPredicateOptions = {\n settings: productTipsData.settings,\n currentAppRoute,\n presentations: productTipsData.presentations,\n playlists: productTipsData.playlists,\n shouldDisplayTutorialVideosProductTip: productTipsData.shouldDisplayTutorialVideosProductTip,\n shouldDisplaySLMigratedProductTip: productTipsData.shouldDisplaySLMigratedProductTip,\n hasNzHubDashboard: productTipsData.hasNzHubDashboard\n };\n\n const appLinkKey = Core.AppLinkHelper.getAppLinkString(currentAppRoute);\n\n const productTips: ProductTipConfig[] = React.useMemo(() => {\n if (!productTipsData.hasCompleted || !productTipsData.currentUser.isAuthenticated\n || breakpoints.xs || isPlugin || !productTipsData.displayTips)\n return [];\n\n const filtered = LITE_PRODUCT_TIPS.filter(tipConfig => {\n return !completedProductTips[tipConfig.id] && tipConfig.predicate(predicateOptions);\n });\n\n return filtered.map(tipConfig => {\n return {\n ...tipConfig,\n ref: refs[tipConfig.id]\n };\n });\n }, [ productTipsData.hasCompleted, completedProductTips, refs, appLinkKey, isPlugin, productTipsData.displayTips ]);\n\n // Until the refs for each product tip have been registered, we don't show the product tips\n function isLoading(): boolean {\n return !productTipsData.hasCompleted || productTips.some(tip => !tip.ref);\n }\n\n return {\n productTips,\n isLoading: isLoading(),\n onComplete\n };\n}\n","import { ProductTipsAnchor, ProductTipsPlacement } from 'libs/shared/interfaces';\n\nconst PADDING = 10; // in px\n\nexport const ProductTipsHelper = {\n calculatePositions(\n anchorElement: HTMLElement,\n cardElement: HTMLElement,\n positionMode: ProductTipsAnchor,\n placement: ProductTipsPlacement\n ): React.CSSProperties {\n const defaultPosition = {\n right: PADDING,\n bottom: PADDING\n };\n\n if (!anchorElement)\n return defaultPosition;\n \n if (positionMode === 'element') {\n const anchorRect = anchorElement.getBoundingClientRect();\n const cardRect = cardElement.getBoundingClientRect();\n\n switch (placement) {\n case 'right': {\n const defaultRightPos: React.CSSProperties = {\n left: anchorRect.right + PADDING,\n top: anchorRect.top\n };\n\n if (anchorRect.top + cardRect.height > window.innerHeight) {\n return {\n left: anchorRect.right + PADDING,\n top: window.innerHeight - cardRect.height - PADDING\n };\n }\n\n return defaultRightPos;\n }\n\n case 'bottom-right': {\n const defaultBottomPos: React.CSSProperties = {\n left: anchorRect.x - (cardRect.width - anchorRect.width),\n top: anchorRect.top + anchorRect.height + PADDING\n };\n\n return defaultBottomPos;\n }\n\n default:\n return defaultPosition;\n }\n }\n\n // when anchor == 'window', we always put the card at the bottom-right corner of the viewport\n return defaultPosition;\n }\n};\n",":local {\n $cv-product-tips-mask-z-index:1034; // left-nav z-index is 1031, top nav z-index is 1035\n \n .card {\n z-index: $cv-product-tips-mask-z-index + 2; // product tip can sit above nav, but mask can't\n }\n\n .mask {\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n position: fixed;\n z-index: $cv-product-tips-mask-z-index; \n background-color: transparent;\n }\n\n @keyframes :local(wiggle) {\n 0% {\n transform: rotate(0deg);\n }\n 25% {\n transform: rotate(-5deg);\n }\n 50% {\n transform: rotate(5deg);\n }\n 75% {\n transform: rotate(-5deg);\n }\n 100% {\n transform: rotate(0deg);\n }\n }\n .shakingAnimation {\n animation: wiggle 300ms 1;\n }\n}","import React from 'react';\n\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { AnalyticsOptions, EntityType, EventVersion, LocationContext, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { useResizeListener } from 'libs/shared/hooks/UseResizeListener';\n\nimport { useLiteProductTips } from 'shared/hooks/product-tips/useLiteProductTips';\nimport { ProductTipsHelper } from 'shared/utils/ProductTipsHelper';\n\nimport styles from './product-tips.module.scss';\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function ProductTipsContainerView(): JSX.Element {\n const { productTips, isLoading, onComplete } = useLiteProductTips();\n\n const [ currentIndex, setCurrentIndex ] = React.useState(0);\n const [ showShakingAnimation, setShowShakingAnimation ] = React.useState<boolean>(false);\n const [ positionStyles, setPositionStyles ] = React.useState<React.CSSProperties>({});\n\n const currentTip = productTips[currentIndex];\n \n const cardRef = React.useRef<HTMLDivElement>(null);\n\n React.useEffect(() => {\n if (isLoading || !productTips.length || !currentTip?.ref)\n return;\n\n if (currentTip.scrollIntoView)\n currentTip.ref.scrollIntoView({ behavior: 'smooth' });\n\n applyProductTipStyles();\n\n return clearProductTipStyles;\n }, [ isLoading, currentIndex, currentTip?.ref ]);\n\n React.useEffect(updatePositionStyles, [ isLoading, currentIndex, currentTip?.ref, cardRef.current ]);\n useResizeListener(updatePositionStyles, null, [ isLoading, currentIndex, currentTip?.ref, cardRef.current ]);\n\n React.useEffect(() => {\n if (!showShakingAnimation)\n return;\n\n const callback = () => setShowShakingAnimation(false);\n cardRef.current.addEventListener('animationend', callback);\n\n return () => cardRef.current?.removeEventListener('animationend', callback);\n }, [showShakingAnimation]);\n\n // If the product tips change, make sure we're on index 0\n React.useEffect(() => {\n if (currentIndex !== 0)\n setCurrentIndex(0);\n }, [productTips]);\n\n const analyticsData: HashObject = { id: currentTip?.id };\n const analyticsOptions: AnalyticsOptions = {\n actionType: UserAction.Click,\n entity: EntityType.ProductTip,\n location: LocationContext.ProductTips,\n descriptor: currentTip?.analyticsDescriptor,\n eventVersion: EventVersion.V2\n };\n\n function updatePositionStyles() {\n if (isLoading || !productTips.length || !currentTip)\n return;\n\n const pos = ProductTipsHelper.calculatePositions(\n currentTip.ref,\n cardRef.current,\n currentTip.anchor,\n currentTip.placement\n );\n\n setPositionStyles(pos);\n }\n\n // This class should mirror clearProductTipStyles\n function applyProductTipStyles(): void {\n if (currentTip?.containerClass)\n currentTip.ref.classList.add(currentTip.containerClass);\n\n document.body.style.overflowY = 'hidden';\n }\n\n // This class should mirror applyProductTipStyles\n function clearProductTipStyles(): void {\n if (currentTip?.containerClass)\n currentTip.ref.classList.remove(currentTip.containerClass);\n\n document.body.style.overflowY = 'scroll';\n }\n\n function onCompleted() {\n clearProductTipStyles();\n window.scrollTo({ top: 0, behavior: 'smooth' });\n\n logCompleted();\n setCurrentIndex(0);\n\n onComplete(productTips);\n }\n\n function logCompleted() {\n AnalyticsHelper.logUserAction({\n ...analyticsData,\n target: 'ctaButton'\n }, {\n ...analyticsOptions,\n workflowPhase: WorkflowPhase.Complete\n });\n }\n\n function logGoNext(nextStepIndex: number, target: 'slider' | 'ctaButton') {\n AnalyticsHelper.logUserAction({\n ...analyticsData,\n nextStepIndex,\n target\n }, {\n ...analyticsOptions,\n workflowPhase: WorkflowPhase.Next\n });\n }\n\n function logGoBack(nextStepIndex: number) {\n AnalyticsHelper.logUserAction({\n ...analyticsData,\n nextStepIndex,\n target: 'slider'\n }, {\n ...analyticsOptions,\n workflowPhase: WorkflowPhase.Back\n });\n }\n\n function onClickIndicator(indicatorIndex: number) {\n setCurrentIndex(indicatorIndex);\n\n if (indicatorIndex > currentIndex) {\n logGoNext(indicatorIndex, 'slider');\n } else {\n logGoBack(indicatorIndex);\n }\n }\n\n function onClickCta() {\n const nextStep = productTips[currentIndex + 1];\n\n if (!nextStep || !nextStep?.ref) {\n onCompleted();\n return;\n }\n\n setCurrentIndex(currentIndex + 1);\n logGoNext(currentIndex + 1, 'ctaButton');\n }\n\n function onClickExternalLink(externalLink: string) {\n AnalyticsHelper.logUserAction({\n ...analyticsData,\n target: 'externalLink',\n href: externalLink\n }, {\n ...analyticsOptions,\n entity: EntityType.Link\n });\n }\n\n function onClickClose() {\n AnalyticsHelper.logUserAction({\n ...analyticsData,\n target: 'close'\n }, {\n ...analyticsOptions,\n workflowPhase: WorkflowPhase.Complete\n });\n\n onCompleted();\n }\n\n function onClickMask() {\n setShowShakingAnimation(true);\n\n AnalyticsHelper.logUserAction({\n ...analyticsData,\n target: 'mask'\n }, analyticsOptions);\n }\n\n if (isLoading || !currentTip)\n return <></>;\n\n const View = currentTip.viewComponent;\n\n return (\n <>\n <div\n className={`position-fixed ${styles.card} ${showShakingAnimation ? styles.shakingAnimation : ''}`}\n style={{ ...positionStyles }}\n ref={cardRef}\n >\n <View\n onClickCta={onClickCta}\n onClickClose={onClickClose}\n onClickExternalLink={onClickExternalLink}\n sliderLength={productTips.length}\n sliderStep={currentIndex}\n onSliderClick={onClickIndicator}\n />\n </div>\n <div className={styles.mask} onClick={onClickMask} />\n </>\n );\n}\n",":local{\n .dropMask,.dropContent,.dropArea {\n display: block;\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n }\n\n .dropMask {\n z-index: $zindex-modal-backdrop;\n background-color: $modal-backdrop-bg;\n opacity: $modal-backdrop-opacity;\n }\n\n .dropContent {\n z-index: $zindex-modal-backdrop + 1;\n\n h1 {\n position: absolute;\n top: 50%;\n width: 100%;\n text-align: center;\n color: $white;\n margin-top: - ($h1-font-size * 0.5);\n }\n }\n\n .dropArea {\n z-index: $zindex-modal-backdrop + 2;\n }\n\n .border{\n display: block;\n position: fixed;\n top: 6rem;\n left: 6rem;\n right: 6rem;\n bottom: 6rem;\n border: 3px dashed $white;\n border-radius: $border-radius;\n }\n}\n\n","import * as React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\n\nimport styles from './drag-mask.module.scss';\n\nexport function DragMask(): React.ReactElement {\n return (\n <>\n <div className={styles.dropMask}></div>\n <div className={styles.dropContent}>\n <div className={styles.border}>\n <h1><Text namespace='shared.dragMask' phrase='message' /></h1>\n </div>\n </div>\n <div className={styles.dropArea}></div>\n </>\n );\n}\n","import * as React from 'react';\nimport { useDropzone } from 'react-dropzone';\nimport { Provider } from 'react-redux';\nimport { Store } from 'redux';\n\nimport { Core } from 'libs/common/core';\nimport { PageMetadataContextProvider } from 'libs/common/react/context/PageMetadataContext';\nimport { useInstanceSafe } from 'libs/common/react/hooks/UseInstance';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { EntityType, InteractionType, LocationContext, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport type { BaseVideoUploadService } from 'libs/shared/apps/upload/services/UploadService';\nimport { ErrorBoundary } from 'libs/shared/components/error-boundary/ErrorBoundary';\nimport { HoverToPortalContainer } from 'libs/shared/components/hover-to-portal-container/HoverToPortalContainer';\nimport { SkipLink } from 'libs/shared/components/skip-link/SkipLink';\nimport { XmasConstants } from 'libs/shared/constants/XmasConstants';\nimport { BannerPortalContextProvider } from 'libs/shared/context/BannerPortalContext';\nimport { BreakpointsContextProvider } from 'libs/shared/context/BreakpointsContext';\nimport { ImageStorageContextProvider } from 'libs/shared/context/ImageStorageContext';\nimport { PlayerContextProvider, usePlayerContext } from 'libs/shared/context/player-context/PlayerContext';\nimport { ProductTipsContextProvider } from 'libs/shared/context/product-tips-context/ProductTipsContext';\nimport { VideoPreviewContextProvider } from 'libs/shared/context/VideoPreviewContext';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { UnspecifiedDialogError } from 'libs/shared/errors/general/unspecified-dialog/UnspecifiedDialogError';\nimport { UnspecifiedError } from 'libs/shared/errors/general/unspecified-error/UnspecifiedError';\nimport { useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { useForceUpdate } from 'libs/shared/hooks/useForceUpdate';\nimport { useListenOn } from 'libs/shared/hooks/UseListenOn';\nimport { useNavLock } from 'libs/shared/hooks/useNavLock';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useTabbingListener } from 'libs/shared/hooks/useTabbingListener';\nimport { useVideoDragDropState } from 'libs/shared/hooks/UseVideoDragDropState';\nimport { LayoutHelper } from 'libs/shared/utils/LayoutHelper';\n\nimport { CVDevTools } from 'shared/components/dev/cv-dev-tools/CVDevTools';\nimport { Snowing } from 'shared/components/snowing/Snowing';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { ViewModelKeys } from 'shared/constants/LiteViewModels';\nimport { Services } from 'shared/constants/Services';\nimport { useActivePresentation } from 'shared/hooks/presentations/useActivePresentation';\nimport { usePluginHelper } from 'shared/hooks/use-plugin-helper/usePluginHelper';\nimport { useUpsellContext } from 'shared/hooks/useUpsellContext';\nimport { LiteLayoutHelper } from 'shared/utils/LiteLayoutHelper';\nimport { SeoHelper } from 'shared/utils/SeoHelper';\nimport { BrazeIamRegion } from 'shared/views/braze-iam-region/BrazeIamRegion';\nimport { CookieConsentView } from 'shared/views/cookie-consent/CookieConsentView';\nimport { FooterView } from 'shared/views/footer/FooterView';\nimport { GlobalPlayerView } from 'shared/views/global-player/GlobalPlayerView';\nimport { HeaderView } from 'shared/views/header/HeaderView';\nimport { HeaderBannerView } from 'shared/views/header-banner/HeaderBannerView';\nimport { useLeftNavBuilder } from 'shared/views/left-nav-v2/hooks/use-left-nav-builder/useLeftNavBuilder';\nimport { LeftNavV2View } from 'shared/views/left-nav-v2/LeftNavV2View';\nimport { OpenInAppPromptView } from 'shared/views/open-in-app-prompt/OpenInAppPromptView';\nimport { ProductTipsContainerView } from 'shared/views/product-tips/ProductTipsContainerView';\n\nimport { ErrorView } from 'apps/default/views/error/LiteErrorView';\n\nimport { DragMask } from './drag-mask/DragMask';\nimport { TeacherLayoutHelper } from './TeacherLayoutHelper';\n\nimport styles from './teacher-layout.module.scss';\n\nexport const PLAY_PAGE_TOC_PORTAL_ID = 'play-page-toc-portal';\nconst BANNER_CONTAINER_CLASS_NAME = 'banner-portal-container';\n\nfunction useConfigureUpload(isPlugin: boolean, canUpload: boolean) {\n const { enabled: uploadsEnabled } = useVideoDragDropState(canUpload);\n\n /**\n * Layout maintains an instance of combined uploads so that it can continue to poll\n * if no other components are maintaining a reference\n */\n useInstanceSafe(uploadsEnabled ? Services.CombineUploads : null);\n\n const videoUploadService = useInstanceSafe<BaseVideoUploadService>(uploadsEnabled ? Services.VideoUpload : null);\n\n const onDrop = React.useCallback((acceptedFiles: File[]) => {\n if (!uploadsEnabled)\n return;\n\n videoUploadService.addFiles(acceptedFiles, {\n entity: EntityType.Video,\n actionType: UserAction.Upload,\n workflowPhase: WorkflowPhase.Start,\n descriptor: AnalyticsHelper.mapInteractionType(InteractionType.DragDrop),\n location: LocationContext.VideoUpload\n });\n }, [uploadsEnabled]);\n\n const { getRootProps, getInputProps, isDragActive } = useDropzone({\n onDrop,\n noClick: true,\n noKeyboard: true,\n disabled: LiteLayoutHelper.disableDropzone(!canUpload || isPlugin)\n });\n\n return {\n getRootProps,\n getInputProps,\n isDragActive,\n uploadsEnabled\n };\n}\n\nfunction useConfigureLayout(isPlugin: boolean, showNav: boolean) {\n const breakpoints = useBreakpoints();\n\n const isMobile = breakpoints.xs;\n const isTablet = breakpoints.sm;\n const isHorizontalTablet = breakpoints.md;\n const isDesktop = breakpoints.lg;\n const isLargeDesktop = breakpoints.xxl;\n const collapseForBot = SeoHelper.isBot();\n\n const [ collapse, setCollapse ] = React.useState(!isLargeDesktop);\n\n function onClickNavItem(): void {\n if (collapse)\n return;\n\n /**\n * On mobile and tablet sizes we show a mask while the nav is expanded,\n * so the user expects the nav to close when they click an item. - Sha\n */\n if (isMobile || isTablet || isHorizontalTablet)\n setCollapse(true);\n }\n\n /**\n * We always want a scrollbar in this layout. This prevents issues with\n * our layout repeadedly shifting causing the page appear to jiggle. - Sha\n */\n React.useEffect(() => {\n document.body.style.overflowY = 'scroll';\n }, []);\n\n React.useEffect(() => {\n setCollapse(!isLargeDesktop);\n }, [isLargeDesktop]);\n \n React.useEffect(() => {\n if (!collapse && (isHorizontalTablet || collapseForBot))\n setCollapse(true);\n }, [ isHorizontalTablet, collapseForBot ]);\n\n const navState = TeacherLayoutHelper.getDerivedNavState(\n collapse,\n isMobile,\n isTablet,\n isHorizontalTablet,\n isDesktop,\n showNav,\n isPlugin\n );\n\n return {\n navState,\n collapse,\n setCollapse,\n onClickNavItem\n };\n}\n\nexport interface TeacherLayoutComponentProps {\n showNav: boolean;\n showSearch: boolean;\n contentChild?: React.ReactNode;\n popupChild?: React.ReactNode;\n alertChild?: React.ReactNode;\n hiddenChild?: React.ReactNode;\n store: Store;\n activeAppLink: Core.AppLink;\n appLinkIsRoute: boolean;\n provider?: (props: React.PropsWithChildren<unknown>) => React.ReactElement;\n}\n\nconst TeacherLayoutComponent = (props: TeacherLayoutComponentProps): React.ReactElement => {\n const { hasPermissions } = usePermissions();\n const mainRef = React.useRef<HTMLElement>(null);\n\n // This is executed at the beginning to set up the backbone radio event listeners\n useNavLock();\n useTabbingListener();\n\n const { activePresentation } = useActivePresentation();\n\n const playerContext = usePlayerContext();\n const [showSearchMask] = useViewModel(ViewModelKeys.SHOW_SEARCH_MASK);\n const [showSearchBackdrop] = useViewModel(ViewModelKeys.SHOW_SEARCH_BACKDROP);\n const [containerClassName] = useViewModel<string>(ViewModelKeys.PLAY_PAGE_CONTAINER_CLASS_NAME);\n const { isPlugin } = usePluginHelper();\n\n const appLink = Core.AppLinkHelper.getCurrentAppLink();\n\n const isMtv = (\n appLink.application === AppChannels.MOVIES_AND_TV\n || (appLink.params as any)?.mtv\n || (appLink.params as any)?.moviesAndTv\n ) && appLink.application !== AppChannels.VIDEOS;\n\n const {\n getRootProps,\n getInputProps,\n isDragActive,\n uploadsEnabled\n } = useConfigureUpload(isPlugin, hasPermissions(PermissionName.UploadVideo));\n\n const {\n navState,\n collapse,\n setCollapse,\n onClickNavItem\n } = useConfigureLayout(isPlugin, props.showNav);\n\n const { items: navItems, showNav, theme: navTheme } = useLeftNavBuilder({\n navState: navState.state,\n activeAppLink: props.activeAppLink\n });\n\n const shouldShowNav = props.showNav && showNav;\n const upsellContext = useUpsellContext();\n\n const showUpsell = upsellContext.isLoaded && upsellContext.upsellPresentationType === activePresentation?.type;\n\n const {\n alertPlayerContainerClassName,\n alertContainerClassName\n } = TeacherLayoutHelper.getContainerClassNames(playerContext.mode === 'picture-in-picture');\n\n const forceUpdate = useForceUpdate();\n useListenOn(LayoutHelper, 'change:lockContentWidth', forceUpdate);\n\n return (\n <ErrorBoundary renderError={() => ErrorView({ error: new UnspecifiedError() })}>\n <div\n {...getRootProps({\n 'role': 'region',\n 'aria-label': 'Drag and drop video anywhere on the page to upload'\n })}\n className={LayoutHelper.shouldLockContentWidth() ? styles.lockedWidth : ''}\n >\n <SkipLink tag='main' />\n <HeaderView\n presentationSlug={activePresentation?.vanitySlug}\n toggleLeftNav={() => setCollapse(!collapse)}\n collapse={collapse}\n showNav={shouldShowNav}\n showSearch={props.showSearch}\n mainRef={mainRef}\n />\n {shouldShowNav && (\n <LeftNavV2View\n items={navItems}\n navTheme={navTheme}\n navState={navState.state}\n onClickNavItem={onClickNavItem}\n />\n )}\n {XmasConstants.IS_XMAS && isMtv && <Snowing />}\n <main ref={mainRef} className={`${styles.content} ${navState.contentClass}`} >\n <HeaderBannerView/>\n <HoverToPortalContainer.ReferenceContainer>\n <div id={PLAY_PAGE_TOC_PORTAL_ID} className={`${styles.tocPortal}`} />\n <div className={`container-fluid ${BANNER_CONTAINER_CLASS_NAME} ${styles.bannerPortalContainer}`} />\n <div className={`${containerClassName || ''} container ${styles.container} ${showUpsell ? 'mt-3' : ''}`}>\n <ErrorBoundary throwError={UnspecifiedError}>\n {props.contentChild}\n </ErrorBoundary>\n </div>\n </HoverToPortalContainer.ReferenceContainer>\n <FooterView />\n <BrazeIamRegion />\n </main>\n <ErrorBoundary throwError={UnspecifiedDialogError}>\n {props.popupChild}\n </ErrorBoundary>\n {navState.showMask && <div className={`modal-backdrop show ${styles.mask}`} onClick={() => setCollapse(true)}></div>}\n <div className={`${styles.searchMask} ${showSearchMask ? styles.show : ''} modal-backdrop`} />\n <div className={`${styles.searchBackdrop} ${showSearchBackdrop ? styles.show : ''} modal-backdrop`} />\n <div className={alertPlayerContainerClassName}>\n {!!props.alertChild && <div className={alertContainerClassName}>{props.alertChild}</div>}\n <GlobalPlayerView\n // The TeacherLayout is rendered by long-lived Backbone Marionette layout views\n // that aren't tied to a single route, so the slug is read from the request URL\n // at render time rather than threaded as a prop from the application handler.\n presentationSlug={activePresentation?.vanitySlug}\n />\n </div>\n {isDragActive && uploadsEnabled && <DragMask />}\n <input {...getInputProps({ autoComplete: null })} />\n <div style={{ display: 'none' }}>{props.hiddenChild}</div>\n <OpenInAppPromptView />\n {/* Hide Braze product tips for now */}\n {/* <BrazeProductTipsContainerView /> */}\n <ProductTipsContainerView />\n <CookieConsentView />\n {/* Dev Tools */}\n <CVDevTools />\n </div>\n </ErrorBoundary>\n );\n};\n\nfunction WrapLayoutWithProviders(props: TeacherLayoutComponentProps): React.ReactElement {\n const { provider: CustomAppProvider, ...layoutComponentProps } = props;\n\n if (!CustomAppProvider)\n return (\n <Provider store={props.store}>\n <PageMetadataContextProvider>\n <BreakpointsContextProvider>\n <VideoPreviewContextProvider>\n <BannerPortalContextProvider containerClassName={BANNER_CONTAINER_CLASS_NAME}>\n <ImageStorageContextProvider>\n <PlayerContextProvider>\n <ProductTipsContextProvider>\n <TeacherLayoutComponent {...layoutComponentProps} />\n </ProductTipsContextProvider>\n </PlayerContextProvider>\n </ImageStorageContextProvider>\n </BannerPortalContextProvider>\n </VideoPreviewContextProvider>\n </BreakpointsContextProvider>\n </PageMetadataContextProvider>\n </Provider>\n );\n\n return (\n <Provider store={props.store}>\n <PageMetadataContextProvider>\n <BreakpointsContextProvider>\n <VideoPreviewContextProvider>\n <BannerPortalContextProvider containerClassName={BANNER_CONTAINER_CLASS_NAME}>\n <ImageStorageContextProvider>\n <CustomAppProvider>\n <PlayerContextProvider>\n <ProductTipsContextProvider>\n <TeacherLayoutComponent {...layoutComponentProps} />\n </ProductTipsContextProvider>\n </PlayerContextProvider>\n </CustomAppProvider>\n </ImageStorageContextProvider>\n </BannerPortalContextProvider>\n </VideoPreviewContextProvider>\n </BreakpointsContextProvider>\n </PageMetadataContextProvider>\n </Provider>\n );\n}\n\nexport { WrapLayoutWithProviders as TeacherLayoutComponent };\n"],"x_google_ignoreList":[0,1,2,3,4,5,6],"mappings":"2tPAEM,GAAmB,IAAI,QACvB,IAAc,EAAO,IAAiB,CAC1C,GAAI,CAAC,GAAS,CAAC,EAAc,OAC7B,IAAM,EAAW,GAAiB,IAAI,CAAY,GAAK,IAAI,IAC3D,GAAiB,IAAI,EAAc,CAAQ,EAC3C,IAAI,EAAM,EAAS,IAAI,CAAK,EAM5B,OALK,IACH,EAAM,EAAa,WAAW,CAAK,EACnC,EAAI,SAAW,EACf,EAAS,IAAI,EAAI,MAAO,CAAG,GAEtB,CACT,EAoBA,SAAwB,GAAc,EAAO,EAAe,OAAO,OAAW,IAAc,IAAA,GAAY,OAAQ,CAC9G,IAAM,EAAM,GAAW,EAAO,CAAY,EACpC,CAAC,EAAS,IAAA,EAAA,EAAA,SAAA,KAA6B,EAAM,EAAI,QAAU,EAAK,EAsBtE,OArBA,MAAgB,CACd,IAAI,EAAM,GAAW,EAAO,CAAY,EACxC,GAAI,CAAC,EACH,OAAO,EAAW,EAAK,EAEzB,IAAI,EAAW,GAAiB,IAAI,CAAY,EAC1C,MAAqB,CACzB,EAAW,EAAI,OAAO,CACxB,EAIA,MAHA,GAAI,WACJ,EAAI,YAAY,CAAY,EAC5B,EAAa,MACA,CACX,EAAI,eAAe,CAAY,EAC/B,EAAI,WACA,EAAI,UAAY,GAClB,GAAqC,OAAO,EAAI,KAAK,EAEvD,EAAM,IAAA,EACR,CACF,EAAG,CAAC,CAAK,CAAC,EACH,CACT,CCnCA,SAAgB,GAAqB,EAAkB,CACrD,IAAM,EAAQ,OAAO,KAAK,CAAgB,EAC1C,SAAS,EAAI,EAAO,EAAM,CAIxB,OAHI,IAAU,EACL,EAEF,EAAQ,GAAG,EAAM,OAAO,IAAS,CAC1C,CACA,SAAS,EAAQ,EAAY,CAC3B,OAAO,EAAM,KAAK,IAAI,EAAM,QAAQ,CAAU,EAAI,EAAG,EAAM,OAAS,CAAC,EACvE,CACA,SAAS,EAAY,EAAY,CAE/B,IAAI,EAAQ,EADC,EAAQ,CACW,GAEhC,MADA,CAA+D,EAA3D,OAAO,GAAU,SAAkB,GAAG,EAAQ,GAAI,IAAiB,QAAQ,EAAM,WAC9E,eAAe,EAAM,EAC9B,CACA,SAAS,EAAY,EAAY,CAC/B,IAAI,EAAQ,EAAiB,GAI7B,OAHI,OAAO,GAAU,WACnB,EAAQ,GAAG,EAAM,KAEZ,eAAe,EAAM,EAC9B,CAmCA,SAAS,EAAc,EAAiB,EAAW,EAAQ,CACzD,IAAI,EAoBJ,OAnBI,OAAO,GAAoB,UAC7B,EAAgB,EAChB,EAAS,EACT,EAAY,KAEZ,IAAyB,GACzB,EAAgB,EACb,GAAkB,CACrB,GAWK,IAAA,EAAA,EAAA,QAAA,KATmB,OAAO,QAAQ,CAAa,CAAC,CAAC,QAAQ,EAAO,CAAC,EAAK,OACvE,IAAc,MAAQ,IAAc,MACtC,EAAQ,EAAI,EAAO,EAAY,CAAG,CAAC,IAEjC,IAAc,QAAU,IAAc,MACxC,EAAQ,EAAI,EAAO,EAAY,CAAG,CAAC,GAE9B,GACN,EAAE,EAAG,CAAC,KAAK,UAAU,CAAa,CAAC,CACb,EAAG,CAAM,CACpC,CACA,OAAO,CACT,CACA,IAAM,GAAgB,GAAqB,CACzC,GAAI,EACJ,GAAI,IACJ,GAAI,IACJ,GAAI,IACJ,GAAI,KACJ,IAAK,IACP,CAAC,SC5GK,GAA6B,EAAM,YAAY,CACnD,YACA,WACA,GAAI,EAAY,MAChB,GAAG,GACF,KACD,EAAW,GAAmB,EAAU,gBAAgB,GACpC,EAAA,EAAA,IAAA,CAAK,EAAW,CAC7B,MACL,WAAA,EAAA,GAAA,QAAA,CAAsB,EAAW,CAAQ,EACzC,GAAG,CACL,CAAC,EACF,EACD,GAAc,YAAc,gBCT5B,IAAM,GAAmB,EACtB,IAAW,QACX,IAAU,MACb,EACM,GAAiC,EAAM,YAAY,CACvD,WACA,YACA,WACA,GAAI,EAAS,GACb,eAAe,GACf,gBAAgB,GAChB,SAAS,GACT,GAAG,GACF,KACD,EAAW,GAAmB,EAAU,WAAW,GAC/B,EAAA,EAAA,IAAA,CAAK,GAAmB,CACrC,MACL,eAAgB,GAChB,GAAI,EACU,eACC,gBACP,SACR,GAAG,EACH,SAAU,GAAY,CAAQ,EAC9B,UAAW,EAAQ,IAA4B,EAAM,aAAa,EAAU,CAC1E,GAAG,EACH,WAAA,EAAA,GAAA,QAAA,CAAsB,EAAW,EAAS,MAAM,WAAY,IAAA,YAAuB,IAAA,YAAuB,GAAG,EAAS,WAAY,GAAiB,EAAO,CAC5J,CAAC,CACH,CAAC,EACF,EACD,GAAkB,YAAc,oBCjChC,IAAM,GAA+B,EAAM,YAAY,CACrD,WACA,YACA,aAAa,QACb,cAAc,GACd,GAAG,GACF,KACD,EAAW,GAAmB,EAAU,kBAAkB,GACtC,EAAA,EAAA,IAAA,CAAK,GAAqB,CACvC,MACL,GAAG,EACH,WAAA,EAAA,GAAA,QAAA,CAAsB,EAAW,CAAQ,EAC7B,aACC,aACf,CAAC,EACF,EACD,GAAgB,YAAc,kBChB9B,IAAM,GAAgBA,GAAiB,IAAI,EACrC,GAA8B,EAAM,YAAY,CACpD,YACA,WACA,GAAI,EAAY,GAChB,GAAG,GACF,KACD,EAAW,GAAmB,EAAU,iBAAiB,GACrC,EAAA,EAAA,IAAA,CAAK,EAAW,CAC7B,MACL,WAAA,EAAA,GAAA,QAAA,CAAsB,EAAW,CAAQ,EACzC,GAAG,CACL,CAAC,EACF,EACD,GAAe,YAAc,iBCF7B,SAAS,GAAiB,EAAO,CAC/B,OAAoB,EAAA,EAAA,IAAA,CAAK,GAAmB,CAC1C,GAAG,CACL,CAAC,CACH,CACA,SAAS,GAAmB,EAAO,CACjC,OAAoB,EAAA,EAAA,IAAA,CAAK,GAAM,CAC7B,GAAG,CACL,CAAC,CACH,CACA,IAAM,GAAyB,EAAM,YAAY,CAC/C,WACA,YACA,WACA,kBAAmB,EACnB,YAAY,QACZ,aAGA,OAAO,GACP,WAAW,GACX,WAAW,GACX,SAAS,GACT,kBACA,SACA,SACA,YACA,YAAY,GACZ,eAAe,GACf,eAAe,GACf,sBACA,YACA,SACA,YACA,UACA,aACA,WACA,oBACA,QAAS,EACT,mBAAmB,GACnB,GAAG,GACF,KAAQ,CACT,IAAM,GAAA,EAAA,EAAA,OAAA,CAAsB,EAC5B,EAAW,GAAmB,EAAU,WAAW,EACnD,GAAM,CAAC,EAAe,IAAA,EAAA,EAAA,SAAA,CAA6B,EAAK,EAClD,GAAa,GAAiB,CAAM,EACpC,GAA0B,GAAc,GAAc,KAAM,IAAI,GACtE,EAAA,EAAA,UAAA,KAAgB,CAGd,EAAiB,EAAa,GAAQ,CAAC,GAA0B,CAAI,CACvE,EAAG,CAAC,EAAM,EAAY,EAAuB,CAAC,EAC9C,IAAM,IAAA,EAAA,EAAA,QAAA,MAA8B,CAClC,OAAQ,EACV,GAAI,CAAC,EAAU,CAAC,EAChB,SAAS,IAAkB,CAUzB,OATI,IACA,GAGF,AAA2B,EAAa,UAAU,IAAI,GAAsB,CAC1E,wBAAyB,EAC3B,CAAC,EACM,EAAa,SAEf,GAAiB,EAC1B,CACA,IAAM,GAAe,EAAM,GAAG,IAAS,CACjC,IAAM,EAAK,MAAM,WAAa,WAClC,IAA2B,EAAM,GAAG,CAAI,CAC1C,EACM,IAAgB,EAAM,GAAG,IAAS,CAClC,IAAM,EAAK,MAAM,WAAa,IAClC,IAA6B,GAAG,CAAI,CACtC,EACM,IAAA,EAAA,EAAA,YAAA,CAA6B,IAA8B,EAAA,EAAA,IAAA,CAAK,MAAO,CAC3E,GAAG,EACH,WAAA,EAAA,GAAA,QAAA,CAAsB,GAAG,EAAS,WAAY,CAAiB,CACjE,CAAC,EAAG,CAAC,EAAmB,CAAQ,CAAC,EAC3B,GAAe,IAA4B,EAAA,EAAA,IAAA,CAAK,MAAO,CAC3D,GAAG,EACH,GAAG,EACH,WAAA,EAAA,GAAA,QAAA,CAAsB,EAAW,EAAa,GAAG,EAAS,GAAG,IAAe,EAAU,GAAG,EAAS,GAAG,GAAW,EAChH,kBAAmB,EACT,UACZ,CAAC,EACD,OAAoB,EAAA,EAAA,KAAA,CAAM,EAAA,SAAW,CACnC,SAAU,CAAC,CAAC,IAAkB,GAAc,IAAqB,GAAa,CAAC,CAAC,GAAgB,EAAA,EAAA,IAAA,CAAK,GAAa,SAAU,CAC1H,MAAO,GACP,UAAuB,EAAA,EAAA,IAAA,CAAK,GAAW,CACrC,KAAM,EACD,OACK,WACC,YACD,WACC,YACX,aAAc,GAAgB,CAAC,EACjB,eACO,sBACJ,kBACT,SACR,OAAQ,GACR,QAAS,EACG,aACD,YACH,SACG,YACX,SAAU,GACV,QAAS,GAAgB,EACzB,WAAY,GACZ,mBAAoB,GACJ,kBACF,eAChB,CAAC,CACH,CAAC,CAAC,CACJ,CAAC,CACH,CAAC,EACD,GAAU,YAAc,YACxB,IAAA,GAAe,OAAO,OAAO,GAAW,CACtC,KAAM,GACN,OAAQ,GACR,MAAO,EACT,CAAC,ECjHY,GAAb,cAAA,EAAyC,SAAkD,CAIzF,YAAY,EAA2B,CACrC,MAAM,CAAK,2BAJ0B,GAKrC,KAAK,MAAQ,CAAE,MAAO,IAAK,CAC7B,CAEA,OAAO,yBAAyB,EAAc,CAC5C,MAAO,CAAE,OAAM,CACjB,CAEA,kBAAyB,EAAc,EAAsB,CACvD,KAAK,sBAGT,KAAK,oBAAsB,GAKtB,OAAe,SAClB,OAAgB,QAAQ,QAAQ,MAAM,EAAM,QAAS,CAAE,WAAU,CAAC,EAE/D,KAAK,MAAM,aAMhB,EAAiB,MAAM,IAAI,KAAK,MAAM,WAAW,EAAM,OAAO,CAAC,EAM/D,OAAO,eAAiB,CACtB,KAAK,oBAAsB,GAC3B,KAAK,SAAS,CAAE,MAAO,IAAK,CAAC,CAC/B,EAAG,GAAG,GACR,CAEA,QAAiC,CAC/B,GAAM,CAAE,SAAU,KAAK,MAEvB,GAAI,GAAS,KAAK,MAAM,YAAa,CACnC,IAAM,EAAQ,KAAK,MAAM,YACzB,OAAO,EAAA,EAAA,IAAA,CAAC,EAAD,CAAQ,CAAA,CACjB,CAMA,OAJI,GAAS,CAAC,KAAK,MAAM,UAChB,EAAA,EAAA,IAAA,CAAA,EAAA,SAAA,CAAI,CAAA,EAGN,KAAK,MAAM,QACpB,CACF,EChFA,SAAgB,IAA2B,CACzC,SAAS,EAAe,EAAwB,CAC1C,EAAE,MAAQ,QAEZ,SAAS,KAAK,UAAU,IAAI,iBAAiB,EAE7C,OAAO,oBAAoB,UAAW,CAAc,EACpD,OAAO,iBAAiB,YAAa,CAAmB,EAE5D,CAEA,SAAS,GAAsB,CAC7B,SAAS,KAAK,UAAU,OAAO,iBAAiB,EAEhD,OAAO,oBAAoB,YAAa,CAAmB,EAC3D,OAAO,iBAAiB,UAAW,CAAc,CACnD,EAEA,EAAA,EAAA,UAAA,MACE,OAAO,iBAAiB,UAAW,CAAc,MACpC,OAAO,oBAAoB,UAAW,CAAc,GAChE,CAAC,CAAC,CACP,ykBEjBa,GAAsB,CACjC,mBACE,EACA,EACA,EACA,EACA,EACA,EACA,EACiB,CACjB,IAAM,EAAoB,EAAW,EAAO,0BAA4B,EAAO,oBAkC/E,OAhCK,EAQD,EACK,CACL,MAAO,EAAW,EAAa,OAAS,EAAa,KACrD,SAAU,CAAC,EACX,aAAc,EAAO,gBACvB,EAGE,GAAY,GAQZ,EACK,CACL,MAAO,EAAW,EAAa,UAAY,EAAa,KACxD,SAAU,CAAC,EACX,aAAe,EAA+B,GAApB,CAC5B,EAGK,CACL,MAAO,EAAW,EAAa,UAAY,EAAa,KACxD,SAAU,GACV,aAAc,EAChB,EAnCS,CACL,MAAO,EAAa,OACpB,SAAU,GACV,aAAc,EAAO,gBACvB,CAgCJ,EAEA,uBAAuB,EAA6B,CAgBlD,MAAO,CACL,8BAAA;2CAdsC,EAAqB,EAAO,0BAA4B,GAAA;MAe9F,wBAN+B,EAE/B,GADA,EAAO,yBAMT,CACF,CACF,oCE5EM,GAAY,kBAQlB,SAAgB,GAAS,EAAsB,CAC7C,SAAS,GAAY,EACP,SAAS,cAAc,EAAM,GAExC,CAAA,EAAK,cAAc,6BAA6B,EAAA,EAAmB,MAAM,CAC5E,CAEA,OACE,EAAA,EAAA,IAAA,CAAC,SAAD,CACE,UAAW,GAAG,GAAO,SAAS,6CAC9B,QAAS,YAET,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAQ,EAAM,GAAM,CAAA,CAC1C,CAAA,CAEZ,CCjBA,IAAM,GAAA,EAA2B,cAAwC,CACvE,qBAAwB,CAAC,EACzB,yBAA4B,CAAC,EAC7B,KAAM,CAAC,CACT,CAAC,EAED,SAAgB,GAAsB,EAAsB,CAC1D,GAAM,CAAE,mBAAkB,uBAAsB,QAAA,EAAe,WAAW,EAAkB,EAS5F,OAPA,EAAM,cAAgB,CACf,KAGL,UAAa,EAAqB,CAAK,CACzC,EAAG,CAAC,CAAK,CAAC,EAEH,CACL,iBAAmB,GAAqB,EAAiB,EAAO,CAAG,EACnE,MACF,CACF,CAEA,SAAgB,GAA2B,EAAgC,CACzE,GAAM,CAAE,EAAM,GAAA,EAAkB,SAAmB,CAAC,CAAC,EAErD,SAAS,EAAiB,EAAkB,EAAsB,CAC5D,EAAK,IAAO,CAAC,GAAW,CAAC,GAG7B,EAAQ,CACN,GAAG,GACF,GAAK,CACR,CAAC,CACH,CAEA,SAAS,EAAqB,EAAkB,CACzC,GAGL,EAAQ,CACN,GAAG,GACF,GAAK,IACR,CAAC,CACH,CAEA,OACE,EAAA,EAAA,IAAA,CAAC,GAAmB,SAApB,CAA6B,MAAO,CAClC,OACA,mBACA,sBACF,WACG,EAAM,QACoB,CAAA,CAEjC,CC1DA,SAAA,IAAA,CACA,OACA,EAAA,EAAA,IAAA,CAAA,EAAA,SAAA,CAcA,CAAA,CAEA,8JEtBA,SAAgB,IAAU,CACxB,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,GAAO,QAAS,cAAY,gBACzC,MAAM,KAAK,CAAE,OAAQ,EAAG,CAAC,CAAC,CAAC,KAAK,EAAG,KAClC,EAAA,EAAA,IAAA,CAAC,MAAD,CAAiB,UAAW,GAAO,oBACjC,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,GAAO,eAAO,GAAM,CAAA,CACjC,EAFK,CAEL,CACN,CACE,CAAA,CAET,CCTA,IAAM,GAA2B,EAC9B,GAAG,EAAY,OAAO,GAAG,EAAQ,OAAO,cAAe,EAC1D,EAEa,GAAmB,CAC9B,gBAAgB,EAA2B,CACzC,GAAI,EACF,MAAO,GAET,IAAM,EAAU,GAAe,gBAAgB,CAAC,EAAE,QAOlD,OALK,EAKE,GAAyB,GAFV,EAAQ,YAAY,GAAG,EAAQ,UAF5C,EAKX,CACF,ECvBa,GAAe,CAC1B,IAAK,eACP,ECAa,GAAuF,CAClG,MAAS,GACT,gBAAiB,GACjB,YAAa,EACf,EAKA,SAAS,GAAiB,CAAE,QAAO,QAAS,CAAE,iBAAmD,CAC1F,EAAM,OAAO,QAEd,EAAM,OAAO,SAAW,UAE5B,EAAa,UAAU,IAAI,QAAQ,EACnC,EAAa,UAAY,GAC3B,CAKA,SAAS,GAAwB,CAAE,QAAO,QAAS,CAAE,iBAAmD,CAGtG,GAFI,CAAC,EAAM,OAAO,QAEd,EAAM,OAAO,SAAW,gBAAiB,OAE7C,IAAM,EAAS,EAAM,OAAO,QACxB,CAAC,GAAU,OAAO,GAAW,WAEjC,EAAa,MAAM,OAAS,GAAG,EAAO,IACxC,CAUA,SAAS,GAAoB,CAC3B,SAC2D,CAU3D,GATI,CAAC,EAAM,OAAO,QAGd,EAAM,OAAO,SAAW,aAGxB,EAAE,OAAO,EAAM,OAAO,SAAS,MAAS,UAAY,EAAM,OAAO,SAAS,KAAK,SAG/E,CAAC,GAAW,EAAM,OAAO,QAAQ,IAAI,EACvC,OAEF,IAAM,EAAS,EAAM,OAAO,QAAQ,OAAS,SAAW,QAExD,OAAO,KAAK,EAAM,OAAO,QAAQ,KAAM,CAAM,CAC/C,CAEA,IAAM,GAAiB,CACrB,yBACA,eACF,EAEA,SAAS,GAAW,EAAwB,CAC1C,GAAI,CACF,IAAM,EAAM,IAAI,IAAI,CAAK,EAUzB,MANA,EAHI,EAAI,WAAa,SAAW,EAAI,WAAa,UAI/C,CAAC,GAAe,KAAK,GAAQ,EAAI,KAAK,SAAS,CAAI,CAAC,EAMxD,MAAQ,CAEN,OADA,QAAQ,KAAK,mDAAmD,EACzD,EACT,CACF,CC7EA,IAAa,GAA8D,CACzE,eAAgB,CACd,GAAI,gCACJ,SAAU,EACZ,CACF,EAEM,GAA0D,CAC9D,KAAM,WACN,GAAI,QACN,EAMA,SAAS,GAAsB,CAAE,gBAA8C,CAC7E,SAAS,iBAAiB,GAAa,IAAM,GAA2B,CACtE,GAAI,CAAC,EAAE,OAAO,OAAQ,OAEtB,IAAM,EAAiB,GAAoB,EAAE,OAAO,QAEhD,OAAO,GAAmB,YAE9B,EAAe,CACb,MAAO,EACP,QAAS,CACO,cAChB,CACF,CAAC,CACH,EAAG,EAAK,CACV,CAEA,SAAS,GAAuB,EAAkC,CAChE,IAAM,EAAM,GAAY,gBAClB,EAAe,SAAS,eAAe,EAAI,EAAE,EAC7C,EAAU,GAAc,QAAQ,MAAQ,OAE9C,EAAa,UAAU,OAAO,QAAQ,EACtC,OAAO,OAAO,EAAe,CAAC,CAAC,QAC7B,GAAQ,EAAa,UAAU,OAAO,CAAI,CAC5C,EAGA,IAAM,EAAY,GAAgB,IAAkC,GAAgB,KACpF,EAAa,UAAU,IAAI,CAAS,EAEpC,GAAsB,CACpB,cACF,CAAC,CACH,CClDA,IAAa,GAAiB,CAC5B,iBAAiB,EAA4B,EAA4B,CACvE,GAAI,CAAC,GAAU,CAAC,EAAc,OAE9B,IAAM,EAAY,GAAc,QAAQ,OACxC,GAAI,CAAC,EAOH,OAEF,IAAM,EAAM,GAAY,GAExB,GAAI,CAAC,EAEH,OAGF,IAAM,EAAmB,SAAS,eAAe,EAAI,EAAE,EAElD,GAEL,EAAO,iBAAiB,EAAc,MAAwB,EAAI,SAAS,CAAY,CAAC,CAC1F,CACF,ECpBA,SAAgB,IAAiB,CAC/B,GAAM,CAAE,YAAa,GAAgB,EAC/B,EAAc,GAAoC,GAAe,WAAW,EAE5E,EAAU,CAAC,GAAY,EAAY,QAEzC,SAAS,EAAoB,EAA4B,CAOnD,OAAgB,iBAAiB,EAErC,OAAO,GAAe,iBAAiB,EAAa,CAAY,CAClE,CAqBA,OAhBA,EAAM,cAAgB,CACf,GAGL,EAAY,oBAAoB,CAAmB,CACrD,EAAG,CAAC,CAAO,CAAC,EAKZ,GAAY,GAAsB,MAAO,OAAwB,CAC1D,GAEL,EAAY,oBAAoB,CAAmB,CACrD,EAAG,CAAC,CAAO,CAAC,GAGV,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,GAAG,gCAAgC,UAAU,sBAC7C,CAAA,CAET,CC3CA,SAAgB,IAAmB,CACjC,IAAM,EAAuB,GAAsC,GAAS,aAAa,EACnF,CAAE,EAAS,IAAA,EAAA,EAAA,SAAA,CACf,EAAqB,eAAe,CACtC,EAGA,GAAY,EAAe,MAAO,EAAsB,UAAY,GAAsC,CACxG,EAAW,CAAO,CACpB,CAAC,EAED,SAAS,EAAS,EAAmD,CACnE,IAAM,EAA4C,OAAO,OAAO,EAAsB,UAAU,CAAC,CAC9F,QAAQ,EAAM,IAAS,CACtB,IAAI,EAAW,GAKf,OAJI,EAAmB,SAAS,CAAI,IAClC,EAAW,IAEb,EAAK,GAAQ,EACN,CACT,EAAG,CAAC,CAA6B,EAEnC,EAAqB,WAAW,CAAe,CACjD,CAEA,SAAS,GAAc,CACrB,EAAS,OAAO,OAAO,EAAsB,UAAU,CAAC,CAC1D,CAEA,MAAO,CACL,UAAW,EAAqB,UAAU,EAC1C,eAAgB,EAChB,WAAY,EACZ,UAAW,CACb,CACF,aC1CM,GAAuB,CAC3B,KAAM,WACN,IAAK,qCACP,EAEM,GAA8C,CAClD,CACE,KAAM,cACN,SAAU,YACV,SAAU,UACV,KAAM,MACN,QAAS,4BACT,QAAS,EACX,EACA,CACE,KAAM,cACN,SAAU,YACV,SAAU,UACV,KAAM,qBACN,QAAS,gCACT,QAAS,EACX,CACF,EAKM,GAAsB,CAC1B,KAAM,QACN,IAAK,8CACP,EACM,GAAoC,CACxC,CACE,KAAM,cACN,SAAU,YACV,SAAU,SACV,KAAM,0BACN,QAAS,mHACT,QAAS,EACX,EACA,CACE,KAAM,cACN,SAAU,YACV,SAAU,SACV,KAAM,6BACN,QAAS,sJACT,QAAS,EACX,EACA,CACE,KAAM,cACN,SAAU,YACV,SAAU,SACV,KAAM,4BACN,QAAS,qIACT,QAAS,EACX,EACA,CACE,KAAM,cACN,SAAU,YACV,SAAU,SACV,KAAM,YACN,QAAS,sEACT,QAAS,EACX,EACA,CACE,KAAM,cACN,SAAU,YACV,SAAU,IACV,KAAM,SACN,QAAS,6IACT,QAAS,EACX,CACF,EA0Ba,GAAmC,CAvB9C,CACE,KAAM,cACN,SAAU,YACV,SAAU,UACV,KAAM,MACN,QAAS,0CACX,EACA,CACE,KAAM,cACN,SAAU,YACV,SAAU,SACV,KAAM,aACN,QAAS,uCACX,EACA,CACE,KAAM,cACN,SAAU,YACV,SAAU,UACV,KAAM,0BACN,QAAS,4EACX,EAKA,GAAG,GACH,GAAG,EACL,ECzGa,GAAe,CAC1B,GAAG,GAAG,EAAwC,CAC5C,GAAI,CAAC,EAAW,OAAQ,MAAO,GAE/B,IAAM,EAAqB,EAAW,OAAO,GAAa,CAAC,CAAC,CAAS,EAIrE,OAFK,EAAmB,OAEjB,EAAmB,KAAK,GAAG,EAFK,EAGzC,CACF,+DEMM,GAA0E,EAC7E,EAAsB,WAAW,WAAY,kBAC7C,EAAsB,WAAW,WAAY,kBAC7C,EAAsB,WAAW,YAAa,mBAC9C,EAAsB,WAAW,OAAQ,YAC5C,EAEM,GAAgF,EACnF,EAAsB,WAAW,WAAY,wBAC7C,EAAsB,WAAW,WAAY,wBAC7C,EAAsB,WAAW,YAAa,yBAC9C,EAAsB,WAAW,OAAQ,kBAC5C,EAEM,GAAmE,CACvE,KAAM,SACN,SAAU,aACV,QAAS,YACT,KAAM,QACR,EAEM,GAAiE,CACrE,cAAe,aACf,cAAe,YACjB,EAMM,GAAY,6BAElB,SAAS,GAAc,CAAE,YAA4C,CACnE,OAAO,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAQ,GAAuB,EAAY,CAAA,CAChF,CAEA,SAAS,GAAoB,CAAE,YAA4C,CACzE,OAAO,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAQ,GAA6B,EAAY,CAAA,CACtF,CAEA,SAAS,GAAoB,CAAE,YAA4C,CACzE,IAAM,EAAc,GAAc,GAAkB,MAAM,EAEpD,EAAY,GAAY,OAAO,GAAU,EAAO,WAAa,CAAQ,EAI3E,OAFK,EAAU,QAGb,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,4DACb,EAAA,EAAA,KAAA,CAAC,QAAD,CAAO,UAAU,uDAAjB,EACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAqB,cAAe,CAAc,CAAA,GAClD,EAAA,EAAA,IAAA,CAAC,GAAD,CAAqB,KAAM,EAAW,cAAe,CAAc,CAAA,CAC9D,GACJ,CAAA,GARuB,EAAA,EAAA,IAAA,CAAA,EAAA,SAAA,CAAI,CAAA,CAUpC,CAMA,SAAS,GAAoB,CAAE,iBAAmC,CAgBhE,OAfI,GAEA,EAAA,EAAA,IAAA,CAAC,QAAD,CAAO,UAAU,uBACf,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,kCACZ,EAAA,EAAA,KAAA,CAAC,KAAD,CAAI,UAAU,uEAAuE,QAAS,WAA9F,EACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,IAAK,EAAU,cAAc,WAAY,UAAW,GAAO,MAAQ,CAAA,GACxE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,iBACd,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,UAAY,CAAA,CAC3C,CAAA,CACJ,GACF,CAAA,CACC,CAAA,GAKT,EAAA,EAAA,IAAA,CAAC,QAAD,CAAO,UAAU,uBACf,EAAA,EAAA,KAAA,CAAC,KAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAA,CAAC,KAAD,CAAI,UAAU,0DAAd,EACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,IAAK,EAAU,cAAc,WAAY,UAAW,GAAO,MAAQ,CAAA,GACxE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,iBACd,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,UAAY,CAAA,CAC3C,CAAA,CACJ,KACJ,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,wBACZ,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,QAAU,CAAA,CAC3C,CAAA,GACJ,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,wBACZ,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,YAAc,CAAA,CAC/C,CAAA,GACJ,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,wBACZ,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,WAAa,CAAA,CAC9C,CAAA,CACF,CAAA,CAAA,CACC,CAAA,CAEX,CAMA,SAAS,GAAoB,CAAE,OAAM,iBAAsC,CAazE,OAZI,GAEA,EAAA,EAAA,IAAA,CAAC,QAAD,CAAO,UAAW,GAAa,GAAG,oBAAqB,GAAO,SAAS,WACpE,EAAK,KAAK,EAAQ,KAEf,EAAA,EAAA,IAAA,CAAC,GAAD,CAAwB,KAAM,CAAmC,EAAtB,EAAO,KAAO,CAAQ,CAEpE,CACI,CAAA,GAKT,EAAA,EAAA,IAAA,CAAC,QAAD,CAAO,UAAW,GAAO,mBACtB,EAAK,KAAK,EAAQ,KAEf,EAAA,EAAA,KAAA,CAAC,KAAD,CAAsB,UAAW,GAAa,GAC5C,IAAU,EAAK,OAAS,GAAK,2BAC/B,WAFA,EAGE,EAAA,EAAA,IAAA,CAAC,KAAD,CAAA,SAAK,EAAO,IAAS,CAAA,GACrB,EAAA,EAAA,IAAA,CAAC,KAAD,CAAA,UAAI,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAQ,GAAoB,EAAO,KAAQ,CAAA,CAAK,CAAA,GAChF,EAAA,EAAA,IAAA,CAAC,KAAD,CAAA,SAAK,EAAO,QAAa,CAAA,GACzB,EAAA,EAAA,IAAA,CAAC,KAAD,CAAA,SAAK,EAAO,OAAY,CAAA,CACtB,GAPK,EAAO,IAOZ,CAEP,CACI,CAAA,CAEX,CAEA,IAAM,GAAyC,CAAE,OAAQ,OAAQ,WAAY,SAAU,EAEvF,SAAS,GAAuB,CAAE,QAAkD,CAClF,IAAM,EAAe,GAAa,KAAK,EAAM,EAAkB,EACzD,EAAc,OAAO,KAAK,CAAY,EAC5C,OACE,EAAA,EAAA,IAAA,CAAA,EAAA,SAAA,CAAA,SACG,EAAY,KAAK,EAAM,IAAU,CAChC,IAAM,EAAQ,EAAa,GACrB,EAAa,IAAU,EAAY,OAAS,EAE7C,KAEL,OACE,EAAA,EAAA,KAAA,CAAC,KAAD,CAEE,UAAW,GAAa,GACtB,GAAc,2BAChB,WAJF,EAKE,EAAA,EAAA,IAAA,CAAC,KAAD,CAAA,UAAI,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAQ,GAA2B,EAA4B,CAAA,CAAK,CAAA,GACpG,EAAA,EAAA,IAAA,CAAC,KAAD,CAAA,SAAK,CAAU,CAAA,CACb,GANG,GAAG,EAAM,GAAG,GAMf,CAER,CAAC,CACD,CAAA,CAEN,CAEA,IAAa,GAAe,CAC1B,MAAO,GACP,YAAa,GACb,YAAa,EACf,ECtLa,GAAgB,CAC3B,aAAa,EAAgD,CAC3D,OAAO,IAAa,WACtB,EAEA,WAAW,EAAgD,CACzD,MAAO,CAAC,CAAC,GAAY,OAAO,GAAU,EAAO,WAAa,CAAQ,CAAC,CAAC,MACtE,CACF,ECUM,GAAY,+BAEZ,CAAE,GAAA,IAAO,GAEf,SAAgB,GAA4B,CAC1C,WACA,OACA,SACA,UACA,aACgD,CAChD,IAAM,EAAU,GAAc,aAAa,CAAQ,EAEnD,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,GAAG,CAAS,WAA5B,EACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,sEAAf,EACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,sEAAf,EACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAY,IAAK,GAAgB,UAAU,aAAa,QAAS,CAAO,CAAA,GACxE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,6BACd,EAAA,EAAA,IAAA,CAAC,GAAa,MAAd,CAA8B,UAAW,CAAA,CACrC,CAAA,CACH,IACJ,GACC,EAAA,EAAA,IAAA,CAAC,GAAD,CAAc,GAAI,EAAS,QAAS,CAAS,CAAA,GAC7C,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,wBACd,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,cAAgB,CAAA,CAC/C,CAAA,CAEL,KACL,EAAA,EAAA,KAAA,CAAC,MAAD,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,GAAa,YAAd,CAAoC,UAAW,CAAA,GAC/C,EAAA,EAAA,IAAA,CAAC,GAAa,YAAd,CAAoC,UAAW,CAAA,CAC5C,CAAA,CAAA,CACF,GAET,yCEpCM,GAAY,kCAEZ,CAAE,GAAA,IAAO,GAQf,SAAgB,GAA+B,CAC7C,qBACA,yBACA,gBACmD,CACnD,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,KAAD,CAAA,UAAI,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,OAAS,CAAA,CAAK,CAAA,GACrD,EAAA,EAAA,IAAA,CAAC,GAAD,CAAW,UAAW,GAAO,mBAC1B,OAAO,OAAO,EAAsB,UAAU,CAAC,CAAC,IAAI,IAIjD,EAAA,EAAA,IAAA,CAAC,GAAD,CAEQ,OACG,QANG,GAAoB,SAAS,CAAI,GAAK,GAOpC,eACd,aAAgB,EAAuB,CAAI,CAC5C,EALM,CAKN,CAEJ,CAEQ,CAAA,CACR,CAAA,CAAA,CAET,CASA,SAAS,GAAsB,CAC7B,OAAM,UAAS,WAAU,gBACiB,CAC1C,IAAM,EAAa,GAAc,WAAW,CAAI,EAChD,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAuC,OAAe,UAAmB,UAAW,CAAA,GACpF,EAAA,EAAA,IAAA,CAAC,GAAU,SAAX,CAAoB,SAAU,YAC5B,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,gEAAf,EACE,EAAA,EAAA,IAAA,CAAC,GAAa,YAAd,CAA0B,SAAU,CAAO,CAAA,EAC1C,IACD,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,iBACb,EAAA,EAAA,IAAA,CAAC,GAAD,CAAW,YAAe,EAAa,CAAI,EAAG,UAAU,sCACtD,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,SAAW,CAAA,CACrC,CAAA,CACR,CAAA,CAEF,GACa,CAAA,CACjB,CAAA,CAAA,CAET,CAQA,SAAS,GAAgC,CACvC,OACA,UACA,YAC6E,CAC7E,GAAM,CAAE,mBAAA,EAAA,EAAA,WAAA,CAA8B,EAAgB,EAChD,EAAU,GAAmB,CAAI,EAEvC,SAAS,EAAe,EAAsB,CAC5C,EAAE,gBAAgB,EAClB,EAAS,CACX,CAEA,IAAM,EAAkB,GAAkB,EAAe,SAAS,CAAI,EAEhE,EAAU,GAAc,aAAa,CAAI,EAE/C,OACE,EAAA,EAAA,KAAA,CAAC,GAAD,CACW,UACT,UAAU,6DAFZ,EAIE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAA,SAAA,CACG,GACC,EAAA,EAAA,IAAA,CAAC,EAAD,CAAc,IAAK,GAAU,KAAM,EAAiB,KAAQ,CAAA,GAC5D,EAAA,EAAA,IAAA,CAAC,EAAD,CAAc,IAAK,GAAS,KAAM,EAAiB,KAAQ,CAAA,GAE7D,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,GAAG,OAAQ,CAAC,GAAW,aAAa,YACnD,EAAA,EAAA,IAAA,CAAC,GAAa,MAAd,CAAoB,SAAU,CAAO,CAAA,CACjC,CAAA,CACH,CAAA,CAAA,EACJ,GACC,EAAA,EAAA,IAAA,CAAC,GAAD,CAAc,GAAI,CAAC,CAAC,EAAS,QAAS,CAAiB,CAAA,GACvD,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,wBAAc,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,cAAgB,CAAA,CAAO,CAAA,CAEjF,GAEf,+EEhHM,GAAY,4BACZ,CAAE,GAAA,IAAO,GAUf,SAAgB,GAAyB,CACvC,OACA,mBACA,SACA,YACA,cAC6C,CAC7C,GAAM,CAAE,EAAoB,IAAA,EAAA,EAAA,SAAA,CAAkE,CAAC,WAAW,CAAC,EACrG,CAAE,EAAc,IAAA,EAAA,EAAA,SAAA,CAA0D,EAC1E,EAAA,EAA2B,UAAsB,EAGjD,EAFgB,GAAc,GAAkB,MAEnC,EAAgB,QAAU,QAE7C,SAAS,EAAuB,EAAuC,CAChE,MAAc,aAAa,CAAQ,EAExC,IAAI,CAAC,EAAmB,SAAS,CAAQ,EAAG,CAC1C,EAAsB,CAAE,GAAG,EAAoB,CAAS,CAAC,EACzD,MACF,CAEA,EAAsB,EAAmB,OAAO,GAAQ,IAAS,CAAQ,CAAC,CAF1E,CAGF,CAEA,SAAS,GAAuB,CAC9B,EAAW,CAAkB,CAC/B,CAEA,SAAS,GAAO,CACd,EAAmB,SAAS,YAAY,EACxC,EAAgB,IAAA,EAAS,CAC3B,CAEA,SAAS,EAAmB,EAAuC,CACjE,EAAmB,SAAS,YAAY,EACxC,EAAgB,CAAQ,CAC1B,CAIA,OAFK,GAGH,EAAA,EAAA,KAAA,CAAC,GAAD,CACE,KAAA,GACA,SAAS,SACD,SACR,WAAW,UACX,gBAAiB,GAAO,gBAL1B,EAOE,EAAA,EAAA,IAAA,CAAC,GAAM,OAAP,CAAc,UAAU,OAAO,YAAA,aAC7B,EAAA,EAAA,IAAA,CAAC,GAAM,MAAP,CAAA,UACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAc,CAAA,CACH,CAAA,CACD,CAAA,GACd,EAAA,EAAA,IAAA,CAAC,GAAA,WAAD,CACE,MAAO,CACL,OAAQ,CACV,EACA,IAAK,YAEL,EAAA,EAAA,IAAA,CAAC,GAAM,KAAP,CAAA,UACE,EAAA,EAAA,IAAA,CAAC,GAAD,CACgB,eACI,mBACE,qBACd,OACc,qBACI,wBACzB,CAAA,CACS,CAAA,CACF,CAAA,GACZ,EAAA,EAAA,IAAA,CAAC,GAAM,OAAP,CAAA,UACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAyB,YAAiC,sBAAuB,CAAA,CACrE,CAAA,CACT,KAnCS,EAAA,EAAA,IAAA,CAAA,EAAA,SAAA,CAAI,CAAA,CAqCxB,CAEA,SAAS,IAA2B,CAClC,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,8CAAf,EACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,IAAK,EAAU,cAAc,KAAM,UAAW,GAAG,OAAQ,GAAO,IAAI,CAAI,CAAA,GAC7E,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,OAAQ,CAAA,CACxC,GAET,CAWA,SAAS,GAAkB,CACzB,eACA,qBACA,mBACA,OACA,qBACA,0BACsC,CActC,OAbK,GAcH,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,SAAU,EACJ,OACN,QAAS,EAAmB,SAAS,CAAY,EACjD,WAAc,EAAuB,CAAY,CAClD,CAAA,GAjBC,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAyC,kBAAmB,CAAA,GAC5D,EAAA,EAAA,IAAA,CAAC,GAAD,CACsB,qBACpB,aAAc,EACU,wBACzB,CAAA,CACD,CAAA,CAAA,CAYR,CAMA,SAAS,GAAsB,CAAE,oBAA6D,CAC5F,OACE,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,IAAD,CAAA,UAAG,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,OAAS,CAAA,CAAI,CAAA,GACnD,EAAA,EAAA,KAAA,CAAC,IAAD,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,QAAU,CAAA,GAC7C,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,UAAU,4BACV,KAAM,EACN,OAAA,aAEA,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,eAAiB,CAAA,CACxC,CAAA,EAAC,GAEd,CAAA,CAAA,CACH,CAAA,CAAA,CAEN,CAOA,SAAS,GAAa,CAAE,uBAAsB,aAA6C,CACzF,OACE,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAW,QAAS,EAAsB,UAAU,6CAClD,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,mBAAqB,CAAA,CAC/C,CAAA,GACX,EAAA,EAAA,IAAA,CAAC,GAAD,CAAW,QAAS,EAAW,UAAU,qCACvC,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,aAAe,CAAA,CACzC,CAAA,CACX,CAAA,CAAA,CAEN,oHEhLM,GAAY,uBACZ,GAAY,EAAgB,iBAAiB,EAAS,EACtD,CAAE,OAAO,GAgBf,SAAgB,GAAoB,CAClC,cAAc,GAAU,aAAa,EACrC,SACA,WACwC,CACxC,GAAM,CACJ,YACA,iBACA,aACA,aACE,GAAiB,EAEf,CAAE,EAAM,IAAA,EAAA,EAAA,SAAA,CAAqB,CAAS,EACtC,CAAE,EAAc,IAAA,EAAA,EAAA,SAAA,CAA6B,EAAI,EACjD,CAAE,EAAiB,IAAA,EAAA,EAAA,SAAA,CAAgC,EAAK,EAExD,EAAmB,GAAU,cAAc,EAAO,iBAAkB,iBAAiB,EAO3F,SAAS,GAAyB,CAChC,SAAS,KAAK,MAAM,SAAW,OAC/B,SAAS,KAAK,MAAM,UAAY,MAClC,CAEA,SAAS,GAAiB,CACxB,EAAgB,EAAK,EACrB,EAAuB,CACzB,CAEA,SAAS,GAAkB,CACzB,EAAuB,EACvB,EAAU,EACV,EAAgB,EAAK,EACrB,EAAQ,EAAK,CACf,CAEA,SAAS,EAAiB,EAAmD,CAC3E,EAAuB,EACvB,EAAW,CAAkB,EAC7B,EAAgB,EAAK,EACrB,EAAQ,EAAK,CACf,CAMA,OAJ0B,GAAW,CAAC,GAAkB,GAKtD,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,MAAD,CACE,UAAW,GACT,6CACA,EAAe,OAAS,aAC1B,EACA,QAAS,CACV,CAAA,GACD,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,UAAW,GACT,iCACA,GAAO,MACT,EACA,KAAA,GACA,UAAU,SACV,SAAU,GACV,OAAQ,GACR,SAAU,GACV,OAAQ,aAER,EAAA,EAAA,KAAA,CAAC,GAAU,KAAX,CAAgB,UAAW,GACzB,4FACA,cACA,GAAO,IACT,WAJA,EAKE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,GACd,iEACA,uBACF,WAHA,EAIE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,IAAK,EAAU,cAAc,OAAQ,UAAW,GAAO,SAAY,CAAA,GACxE,EAAA,EAAA,KAAA,CAAC,IAAD,CAAG,UAAU,wBAAb,CACG,EAAY,SACb,EAAA,EAAA,IAAA,CAAC,GAAD,CAAc,KAAM,GAAG,EAAiB,UAAW,UAAU,uCAAuC,OAAA,aAClG,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,WAAa,CAAA,CACpC,CAAA,CACb,GACA,KACL,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,GACd,qEACA,cACA,GAAO,OACT,WAJA,EAKE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAW,YAAe,EAAmB,EAAI,EAAG,UAAW,GAC7D,+CACF,YACE,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,WAAa,CAAA,CACvC,CAAA,GACX,EAAA,EAAA,IAAA,CAAC,GAAD,CAAW,QAAS,EAAiB,UAAU,6CAC7C,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,WAAa,CAAA,CACvC,CAAA,CACR,GACS,GACP,CAAA,GACX,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,KAAM,EACY,mBAClB,WAAc,EAAmB,EAAK,EACtC,UAAW,EACX,WAAY,CACb,CAAA,CACD,CAAA,CAAA,GA/D2B,EAAA,EAAA,IAAA,CAAA,EAAA,SAAA,CAAI,CAAA,CAiErC,CCvIA,IAAM,GAA6B,CAEjC,CACE,OAAQ,EAAQ,QAAQ,2BACxB,YAAa,EAAY,OAC3B,EAEA,CACE,OAAQ,EAAQ,MAAM,gBACtB,YAAa,EAAY,KAC3B,CACF,EAEA,SAAS,GAAmB,EAA2B,CACrD,MAAO,CAAC,CAAC,GAAgB,KAAK,GAC5B,EAAK,SAAW,EAAQ,QAAU,EAAK,cAAgB,EAAQ,WAChE,CACH,CAGA,SAAgB,IAAiC,CAC/C,IAAM,EAAiB,EAAc,kBAAkB,EACjD,EAAS,EAA6B,GAAe,OAAO,CAAC,EAE7D,EAAgB,GAAsC,GAAS,aAAa,EAC5E,EAAsB,CAAC,GAAmB,CAAc,GAAK,CAAC,GAAU,MAAM,GAAK,EAAc,UAAU,EAIjH,OAFK,EAAO,MAGV,EAAA,EAAA,IAAA,CAAC,GAAD,CAAqB,QAAS,EAAqB,OAAQ,EAAO,IAAO,CAAA,GAHlD,EAAA,EAAA,IAAA,CAAA,EAAA,SAAA,CAAI,CAAA,CAK/B,CC/BA,IAAM,GAA6B,CACjC,iBAAkB,wBAClB,aAAc,cACd,sBAAuB,6BACzB,EAEM,GAA6B,CACjC,aAAc,cACd,iBAAkB,kBAClB,sBAAuB,uBACzB,EAEM,GAAiD,EACpD,GAAe,IAAK,IACpB,GAAe,IAAK,IACpB,GAAe,IAAK,IAEpB,GAAe,IAAK,EACvB,EAEA,SAAS,GAAU,EAAiB,EAAwB,CAC1D,IAAM,EAAO,GAAe,IAAmB,GAE/C,MAAO,CACL,iBAAkB,GAAU,cAAc,EAAS,EAAK,gBAAgB,EACxE,sBAAuB,GAAU,cAAc,EAAS,EAAK,qBAAqB,EAClF,aAAc,GAAU,cAAc,EAAS,EAAK,YAAY,CAClE,CACF,CAGA,SAAgB,IAAiC,CAC/C,IAAM,EAAU,EAA6B,GAAe,QAAQ,CAAC,EAC/D,EAAS,EAA6B,GAAe,OAAO,CAAC,EAEnE,GAAI,CAAC,EAAQ,MAAQ,CAAC,EAAO,aAC3B,OAAO,EAAA,EAAA,IAAA,CAAA,EAAA,SAAA,CAAI,CAAA,EAEb,IAAM,EAAO,GAAU,EAAO,KAAK,iBAAkB,EAAO,KAAK,cAAc,EAEzE,EAAqC,CACzC,WAAY,EAAW,MACvB,OAAQ,EAAW,QACnB,WAAY,EAAgB,aAC5B,SAAU,EAAgB,MAC5B,EAEA,OACE,EAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,UAAU,2CAChB,EAAA,EAAA,KAAA,CAAC,KAAD,CAAI,UAAU,sEAAd,EACE,EAAA,EAAA,KAAA,CAAC,KAAD,CAAA,SAAA,CAAI,UAAS,IAAI,KAAK,CAAA,CAAG,YAAY,EAAE,cAAgB,CAAA,CAAA,EAAC,aAExD,EAAA,EAAA,IAAA,CAAC,KAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,UAAU,iBACV,KAAM,EAAK,iBACX,cAAe,CAAE,IAAK,EAAK,gBAAiB,EAC1B,mBAClB,OAAA,YACD,gBAEa,CAAA,CACZ,CAAA,EAAC,aAEL,EAAA,EAAA,IAAA,CAAC,KAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,UAAU,iBACV,KAAM,EAAK,sBACX,cAAe,CAAE,IAAK,EAAK,qBAAsB,EAC/B,mBAClB,OAAA,YACD,sBAEa,CAAA,CACZ,CAAA,EAAC,aAEL,EAAA,EAAA,IAAA,CAAC,KAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,UAAU,iBACV,KAAM,EAAK,aACX,cAAe,CAAE,IAAK,EAAK,YAAa,EACtB,mBAClB,OAAA,YACD,YAEa,CAAA,CACZ,CAAA,EAAC,aAEL,EAAA,EAAA,KAAA,CAAC,KAAD,CAAA,SAAA,CAAI,YAAU,EAAQ,IAAS,CAAA,CAAA,CAC7B,GACE,CAAA,CAEZ,mPE9EA,SAAS,GACP,EACA,EACA,EACA,EACA,EACc,CASd,OARI,GAAa,EAAQ,UAAY,GAAW,GACvC,CACL,YAAa,EAAY,MACzB,OAAQ,EAAQ,MAAM,gBACtB,KAAM,CAAC,EAAQ,OAAO,CACxB,EAGK,GAAmB,WAAW,EAAO,CAC1C,QAAS,EAAQ,QACjB,UAAW,EAAQ,UACnB,QAAS,EAAQ,QACjB,SAAU,EAAQ,SAClB,YAAa,EAAQ,YACrB,eAAgB,CAClB,EAAG,CAAgB,CACrB,CAcA,SAAS,GAAkB,EAA4C,CACrE,GAAM,CAAE,QAAO,aAAY,UAAS,eAAc,oBAAqB,EAEvE,OACE,EAAA,EAAA,KAAA,CAAC,KAAD,CAAI,UAAW,iBAAiB,GAAO,iBAAvC,CACG,GAAY,QAAQ,CAAK,IACxB,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,KAAK,SACL,UAAU,UACH,QACP,QACE,EAAW,GAAU,OAAO,GAC5B,GAAoB,iBAAiB,EAAM,OAAQ,CAAC,EAAG,CAAgB,EAEzE,iBAAkB,CAAE,SAAU,EAAgB,cAAe,CAC9D,CAAA,GAEH,EAAA,EAAA,IAAA,CAAC,EAAD,CAAkB,UAAS,QAAS,WACjC,EAAM,IACA,CAAA,CACP,GAER,CAUA,SAAgB,GAAiB,EAAkD,CACjF,IAAM,EAAgB,GAAiB,EAEjC,CAAE,cAAe,GAAY,EAE7B,CAAE,yBAA0B,GAAY,IAAI,EAE5C,CACJ,SAAQ,cAAa,QAAO,YAAW,mBAAkB,UAAS,gBAAe,qBAAoB,gBACnG,GAAiB,CACnB,SAAU,EAAc,SACxB,aAAc,EAAc,aAC5B,QAAS,EAAc,QACvB,QAAS,EAAc,QACvB,UAAW,EAAc,UACzB,YAAa,EAAc,WAC7B,CAAC,EAED,SAAS,GAAqB,CAU5B,GATA,EAAgB,cAAc,CAC5B,GAAI,EAAM,EACZ,EAAG,CACD,SAAU,EAAgB,eAC1B,OAAQ,GAAY,mBAAmB,CAAK,EAC5C,WAAY,EAAW,MACvB,WAAY,EAAgB,KAC9B,CAAC,EAEG,CAAC,EAAc,aAAc,CAC/B,EAAc,QAAQ,EACtB,MACF,CAEA,EAAc,cAAc,EAAc,YAAY,EACtD,EAAc,UAAU,SAAS,uBAAuB,EAAK,CAC/D,CAEA,SAAS,GAAyB,CAC5B,EAAc,eAGlB,EAAc,gBAAgB,SAAS,EACvC,EAAc,UAAU,SAAS,uBAAuB,EAAK,EAE7D,EAAgB,cAAc,CAC5B,GAAI,EAAM,EACZ,EAAG,CACD,SAAU,EAAgB,eAC1B,OAAQ,GAAY,mBAAmB,CAAK,EAC5C,WAAY,EAAW,MACvB,WAAY,EAAgB,IAC9B,CAAC,EACH,CAEA,SAAS,GAAqB,CAC5B,EAAc,WAAW,EAEzB,EAAc,UAAU,SAAS,gBAAgB,MAAM,EACvD,EAAmB,QAAQ,EAAc,SAAW,CAAO,CAC7D,CAEA,IAAM,EAAc,GAAe,EACnC,SAAS,EAAQ,EAAmB,CAClC,EAAc,aAAa,CAAM,EACjC,EAAY,EAOZ,IAAM,EAAY,OAAO,eAAiB,CACpC,CAAC,GAAU,EAAO,WAAW,GAAK,CAAC,EAAO,SAAS,GAGvD,EAAO,KAAK,CACd,EAAG,GAAG,EAEA,MAAkB,EAAc,WAAW,EAAI,EACrD,EAAO,IAAI,UAAW,CAAS,EAC/B,EAAO,IAAI,cAAiB,CAC1B,EAAO,IAAI,OAAQ,CAAS,EAC5B,OAAO,aAAa,CAAS,EAC7B,EAAc,aAAa,IAAI,CACjC,CAAC,CACH,CAEA,EAAM,cAAgB,CAChB,MAAC,EAAc,WAAW,SAAW,EAAc,UAGvD,IAAI,EAAc,OAAS,QAAS,CAClC,EAAc,UAAU,SAAS,gBAAgB,QAAS,EAAc,EAAc,aAAa,EACnG,MACF,CAEA,GAAI,EAAc,OAAS,qBAAsB,CAC/C,EAAc,UAAU,SAAS,yBAAyB,EAAI,EAC9D,MACF,CAEA,EAAc,UAAU,SAAS,gBAAgB,MAAM,EACvD,EAAc,UAAU,SAAS,yBAAyB,EAAK,CAR/D,CASF,EAAG,CAAE,EAAc,UAAU,QAAS,EAAc,KAAM,EAAc,QAAS,CAAC,EAElF,SAAS,EAA0B,EAAsB,CACvD,EAAc,gBAAgB,EAAQ,qBAAuB,EAAc,YAAY,EAEnF,IACF,EAAc,UAAU,SAAS,iBAAiB,EAAK,EACvD,EAAc,WAAW,EAE7B,CAEA,SAAS,EAAqB,EAA8B,CAC1D,EAAc,wBAAwB,EAAgB,UAAY,QAAQ,CAC5E,CAEA,IAAM,EAAU,GACd,EACA,EACA,EACA,GAAa,gBACb,EAAM,gBACR,EAEM,EAAuB,EAAc,qBAAuB,WAAa,EAAc,OAAS,UAEtG,OACE,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAA,CAAC,GAAD,CAAU,KAAM,EAAc,oBAA9B,CACG,IACC,EAAA,EAAA,IAAA,CAAC,GAAD,CACU,SACK,cACN,QACI,YACO,mBACT,UACM,gBACf,iBAAkB,EAAM,iBACf,UACkB,4BACL,uBACtB,SAAA,GACA,QAAS,EAAc,QACvB,UAAW,EAAc,UACzB,YAAa,EAAc,YAC3B,SAAU,EAAc,SACxB,UAAW,EAAc,UACzB,QAAS,EAAc,QACvB,KAAM,EAAc,KACpB,mBAAoB,EAAc,mBAClC,MAAO,EAAc,OAAS,SAAiB,IAAA,GAC3B,qBACpB,uBAAwB,EAAc,uBACtC,MAAO,EAAc,MACrB,gBAAiB,EAEjB,iBAAkB,CACnB,CAAA,EAEF,CAAC,GAAgB,EAAc,OAAS,UACvC,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,6CAA6C,EAAuB,GAAO,kBAAoB,IAAO,CAAA,CAEhH,IACT,IACC,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,GAAO,uBACrB,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,QAAS,IACT,GAAI,EAAc,OAAS,qBAC3B,WAAW,0BAEX,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,yBAAf,CACG,EAAc,OAAS,uBAAwB,EAAA,EAAA,IAAA,CAAC,GAAD,CAAW,KAAM,EAAc,UAAa,CAAA,GAC5F,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,0EAAf,EACE,EAAA,EAAA,IAAA,CAAC,GAAD,CACc,aACL,QACE,UACT,aAAc,EACd,iBAAkB,EAAM,gBACzB,CAAA,GACD,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAW,GAAG,GAAO,mBAA3B,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,gCAAgC,KAAK,SAAS,SAAU,EAAG,QAAS,WACjF,EAAc,cACb,EAAA,EAAA,IAAA,CAAC,EAAD,CAAc,IAAK,GAAc,UAAW,GAAG,GAAO,YAAY,8BAAiC,CAAA,GACnG,EAAA,EAAA,IAAA,CAAC,EAAD,CAAc,IAAK,EAAW,CAAA,CAC5B,CAAA,GACN,EAAA,EAAA,IAAA,CAAC,EAAD,CACW,UACT,QAAS,WAER,CAAC,EAAc,eAAgB,EAAA,EAAA,IAAA,CAAC,EAAD,CAC9B,IAAK,GACL,UAAW,GAAG,GAAO,YAAY,wCAA2C,CAAA,CACvE,CAAA,CACL,GACH,GACF,GACQ,CAAA,CACZ,CAAA,CAEP,CAAA,CAAA,CAEN,CC9SA,IAAA,GAAeC,GAAAA,QAAW,SAAS,CAAC,EAAI,SAAS,EAAU,EAAO,EAAQ,EAAS,EAAM,CACrF,IAAI,EAAQ,EAAO,EAAU,OAAQ,EAAO,EAAU,iBAAkB,EAAiB,EAAU,gBAAkB,SAAS,EAAQ,EAAc,CAChJ,GAAI,OAAO,UAAU,eAAe,KAAK,EAAQ,CAAY,EAC3D,OAAO,EAAO,EAGpB,EAEF,MAAO,6CACH,EAAO,GAAS,GAAW,EAAU,GAAU,KAA0C,EAAnC,EAAe,EAAO,SAAS,IAAgB,KAAyC,EAAlC,EAAe,EAAO,QAAQ,IAAgB,KAA8C,EAAvC,EAAe,EAAO,aAAa,EAAa,CAAM,CAAC,EACxN,KACA,EAAO,GAAS,EAAU,GAAU,KAA0C,EAAnC,EAAe,EAAO,SAAS,IAAgB,KAA8C,EAAvC,EAAe,EAAO,aAAa,EAAa,CAAM,CAAC,EACxJ;CACN,EAAE,SAAW,CAAC,EAAE,UAAU,EAAE,KAAO,SAAS,EAAU,EAAO,EAAQ,EAAS,EAAM,CAChF,IAAI,EAAQ,EAAiB,EAAU,gBAAkB,SAAS,EAAQ,EAAc,CACpF,GAAI,OAAO,UAAU,eAAe,KAAK,EAAQ,CAAY,EAC3D,OAAO,EAAO,EAGpB,EAEF,QAAS,EAAS,EAAU,QAAS,EAAU,GAAU,KAA0C,EAAnC,EAAe,EAAO,SAAS,IAAgB,KAAsC,EAA/B,EAAe,EAAO,KAAK,EAAa,CAAM,IAAsB,IACtL;IACE,EAAS,EAAe,EAAQ,IAAI,CAAC,CAAC,KAAK,IAA2B,EAAU,aAAe,CAAC,IAAK,EAAU,GAAU,KAA0C,EAAnC,EAAe,EAAO,SAAS,IAAgB,KAA8C,EAAvC,EAAe,EAAO,aAAa,EAAY,CAAC,KAAO,KAAK,KAAO,CAAC,EAAE,GAAK,EAAU,QAAQ,EAAG,EAAM,CAAC,EAAE,QAAU,EAAU,KAAK,KAAO,EAAK,IAAM,CAAC,MAAQ,CAAC,KAAO,EAAE,OAAS,CAAC,EAAE,IAAM,CAAC,KAAO,EAAE,OAAS,CAAC,CAAC,CAAC,CAAC,IAAsB,GACpa,EAAE,QAAU,EAAI,CAAC,sIEbJ,GAAb,cAAiD,CAAe,CAG9D,YAAmB,EAA6C,CAC9D,MAAM,CAAO,CACf,CAGA,IAAW,MAAe,CACxB,MAAO,6BACT,CAGA,IAAW,WAAoB,CAC7B,MAAO,uBAAuB,GAAO,iBAAiB,GAAG,GAAO,KAAK,QAAQ,QAC/E,CAGA,IAAW,UAAgB,CACzB,OAAO,EACT,CAEA,YAA0B,CACxB,KAAK,SAAS,KAAK,MAAO,qBAAsB,KAAK,MAAM,CAC7D,CAEA,gBAAiC,CAC/B,IAAM,EAAc,KAAK,MAAM,IAAI,aAAa,EAQhD,OANI,OAAO,GAAgB,UAAY,IAAgB,EAC9C,GAEL,EAAc,GACT,MAEF,EAAY,SAAS,CAC9B,CAEA,aAAiC,CAC/B,MAAO,CACL,OAAA,GACA,IAAK,GAAU,OAAO,EAAO,EAC7B,YAAa,KAAK,eAAe,CACnC,CACF,CACF,ECxDA,GAAeC,GAAAA,QAAW,SAAS,CAAC,EAAI,SAAS,EAAU,EAAO,EAAQ,EAAS,EAAM,CACrF,IAAI,EAAiB,EAAU,gBAAkB,SAAS,EAAQ,EAAc,CAC5E,GAAI,OAAO,UAAU,eAAe,KAAK,EAAQ,CAAY,EAC3D,OAAO,EAAO,EAGpB,EAEF,MAAO;uBACH,EAAU,kBAAkB,EAAe,EAAQ,MAAM,GAAI,GAAU,EAAe,EAAO,MAAM,GAAI,EAAU,MAAM,cAAA,CAAe,KAAK,IAA2B,EAAU,aAAe,CAAC,GAAG,SAAS,CAAC,KAAO,OAAO,KAAO,CAAC,EAAE,KAAO,EAAK,IAAM,CAAC,MAAQ,CAAC,KAAO,EAAE,OAAS,EAAE,EAAE,IAAM,CAAC,KAAO,EAAE,OAAS,EAAE,CAAC,CAAC,CAAC,CAAC,EACtT;;CACN,EAAE,SAAW,CAAC,EAAE,UAAU,EAAE,KAAO,SAAS,EAAU,EAAO,EAAQ,EAAS,EAAM,CAChF,IAAI,EAAQ,EAAO,IAA2B,EAAU,aAAe,CAAC,GAAI,EAAiB,EAAU,gBAAkB,SAAS,EAAQ,EAAc,CACpJ,GAAI,OAAO,UAAU,eAAe,KAAK,EAAQ,CAAY,EAC3D,OAAO,EAAO,EAGpB,EAEF,MAAO,+CACH,EAAU,kBAAkB,EAAe,EAAQ,MAAM,GAAI,GAAU,EAAe,EAAO,MAAM,GAAI,EAAU,MAAM,cAAA,CAAe,KAAK,EAAO,gBAAgB,CAAC,KAAO,OAAO,KAAO,CAAC,EAAE,KAAO,EAAK,IAAM,CAAC,MAAQ,CAAC,KAAO,EAAE,OAAS,EAAE,EAAE,IAAM,CAAC,KAAO,EAAE,OAAS,EAAE,CAAC,CAAC,CAAC,CAAC,EAC5Q;;IACE,EAAS,EAAe,EAAQ,IAAI,CAAC,CAAC,KAAK,GAAS,EAAU,GAAU,KAA0C,EAAnC,EAAe,EAAO,SAAS,IAAgB,KAAmD,EAA5C,EAAe,EAAO,kBAAkB,EAAY,CAAC,KAAO,KAAK,KAAO,CAAC,EAAE,GAAK,EAAU,QAAQ,EAAG,EAAM,CAAC,EAAE,QAAU,EAAU,KAAK,KAAO,EAAK,IAAM,CAAC,MAAQ,CAAC,KAAO,EAAE,OAAS,CAAC,EAAE,IAAM,CAAC,KAAO,EAAE,OAAS,CAAC,CAAC,CAAC,CAAC,IAAsB,GACxX,EAAE,QAAU,EAAI,CAAC,ECAJ,GAAb,cAA8C,CAAU,CAQtD,YAAmB,EAA0C,CAC3D,MAAM,CAAO,CACf,CAGA,IAAW,MAAe,CACxB,MAAO,yBACT,CAGA,IAAW,OAAiB,CAC1B,MAAO,EACT,CAGA,IAAW,MAAe,CACxB,MAAO,oCACT,CAGA,IAAW,WAAoB,CAC7B,MAAO,yBACT,CAGA,IAAW,UAAgB,CACzB,OAAO,EACT,CAEA,SAA6B,CAC3B,MAAO,CACL,cAAe,CACb,eAAgB,GAChB,GAAI,eACJ,eAAgB,CACd,UAAW,GAA6B,oBACxC,QAAS,CACP,iBAAkB,EAClB,aAAc,CACZ,SAAU,GACV,UAAW,YACX,YAAa,CACX,OAAQ,EACV,CACF,CACF,CACF,CACF,CACF,CACF,CAEA,IAAW,UAAuB,CAChC,MAAO,CACL,OAAQ,UACV,CACF,CAGA,IAAW,UAA6B,CACtC,MAAO,CACL,aAAc,KAAK,aAAa,SAAS,aAC3C,CACF,CAEA,YAA0B,CACxB,KAAK,oBAAsB,GAAgB,YAAY,GAAe,aAAc,IAAI,EACxF,KAAK,aAAe,GAAgB,YAAY,GAAa,cAAe,IAAI,CAClF,CAEA,OAAe,EAA0C,CACvD,KAAK,WAAa,EAClB,KAAK,OAAO,CACd,CAEA,yBAAwD,CAOtD,OANI,KAAK,qBACA,KAAK,qBAKP,KAAK,qBAAuB,IAAI,GAAqB,CAC1D,iBAAkB,GAAmB,aACvC,CAAC,CACH,CAEA,wBAAuC,CACrC,IAAM,EAAO,IAAI,GAA0B,CACzC,WAAY,KAAK,WACjB,UAAW,KAAK,QAAQ,UACxB,UAAW,GACX,QAAS,KAAK,QAAQ,QACtB,QAAS,KAAK,kBAAkB,EAAa,KAAK,OAAO,IAAI,SAAS,EAAI,KAAK,OAAO,QACtF,iBAAkB,KAAK,kBAAkB,EAAa,KAAK,OAAO,IAAI,kBAAkB,EAAI,KAAK,OAAO,gBAC1G,CAAC,EAED,KAAK,cAAc,gBAAiB,CAAI,CAC1C,CAGA,IAAW,mBAA+C,CACxD,MAAO,CACL,OAAQ,GAAwB,MAClC,CACF,CAEA,gBAAiC,CAa/B,OARK,KAAK,YACR,KAAK,oBAAoB,iBACvB,KACA,KAAK,wBAAwB,EAC5B,GAAuC,KAAK,OAAO,CAAU,CAChE,EAGK,CAAC,CAAC,KAAK,UAChB,CAEA,aAAiC,CAC/B,MAAO,CACL,iBAAkB,KAAK,YAAc,KAAK,WAAW,MACvD,CACF,CAEA,UAAwB,CACtB,KAAK,uBAAuB,CAC9B,CACF,ECjJa,GAAb,cAAqC,CAAc,CAEjD,IAAW,UAA2B,CACpC,MAAO,CACL,UAAW,KACb,CACF,CAEA,IAAW,SAAS,EAA0B,CAAC,CAG/C,IAAW,IAAiB,CAI1B,OAHK,KAAK,QAAQ,SAGX,CACL,QAAS,KAAK,QAAQ,QACxB,EAJS,CAAC,CAKZ,CAEA,IAAW,GAAG,EAAgB,CAC5B,IAAI,EAAS,CAAC,EACV,KAAK,KAAK,KACZ,EAAS,EAAS,KAAK,KAAM,IAAI,GAEnC,KAAM,KAAa,IAAM,EAAS,CAAC,EAAG,EAAQ,CAAE,CAClD,CAEA,YAA0C,CAIxC,OAHI,KAAK,QAAQ,SACR,KAAK,KAAK,MAAM,SAAS,EAE3B,KAAK,KAAK,GACnB,CAEA,YAAiC,CAC/B,IAAM,EAAsB,CAC1B,UAAW,KAAK,QAAQ,WAAa,KAAK,SAAS,SACrD,EAKA,OAHI,KAAK,QAAQ,QACf,EAAQ,MAAQ,KAAK,QAAQ,OAExB,CACT,CAEA,UAAwB,CACtB,IAAM,EAAK,KAAK,WAAW,EAEtB,EAAG,QAER,EAAG,QAAQ,KAAK,WAAW,CAAC,CAC9B,CAEA,gBAA8B,CAC5B,IAAM,EAAU,KAAK,WAAW,EAE5B,aAAmB,QACrB,EAAQ,QAAQ,SAAS,CAE7B,CACF,EC9EA,GAAeC,GAAAA,QAAW,SAAS,CAAC,SAAW,CAAC,EAAE,UAAU,EAAE,KAAO,SAAS,EAAU,EAAO,EAAQ,EAAS,EAAM,CAClH,IAAI,EAAQ,EAAQ,EAAO,EAAU,iBAAkB,EAAiB,EAAU,gBAAkB,SAAS,EAAQ,EAAc,CAC/H,GAAI,OAAO,UAAU,eAAe,KAAK,EAAQ,CAAY,EAC3D,OAAO,EAAO,EAGpB,EAEF,MAAO,oHACH,GAAS,GAAU,EAAS,EAAe,EAAQ,OAAO,IAAM,GAAU,KAAwC,EAAjC,EAAe,EAAO,OAAO,KAAgC,EAAU,MAAM,cAAgB,OAAO,GAAW,WAAa,EAAO,KAAK,IAA2B,EAAU,aAAe,CAAC,GAAG,CAAC,KAAO,QAAQ,KAAO,CAAC,EAAE,KAAO,EAAK,IAAM,CAAC,MAAQ,CAAC,KAAO,EAAE,OAAS,GAAG,EAAE,IAAM,CAAC,KAAO,EAAE,OAAS,GAAG,CAAC,CAAC,CAAC,EAAI,EAAQ,EACzY;8HACA,EAAO,EAAU,QAAS,EAAU,GAAU,KAA0C,EAAnC,EAAe,EAAO,SAAS,IAAgB,KAAyD,EAAlD,EAAe,EAAO,wBAAwB,EAAa,CAAM,CAAC,EAC7K,UACN,EAAE,QAAU,EAAI,CAAC,yGEYJ,GAAb,cAA4C,CAAU,CAWpD,YAAY,EAAwC,CAClD,MAAM,CAAO,mBAHgB,EAI/B,CAEA,YAA0B,CACxB,KAAK,aAAe,GAAgB,YAAY,GAAa,aAAa,EAC1E,KAAK,oBAAsB,GAAgB,YAAY,GAAe,aAAc,IAAI,EAExF,KAAK,SAAS,GAAmB,qBAAsB,GAAG,GAAmB,cAAc,WAAY,KAAK,iBAAiB,CAC/H,CAGA,IAAW,MAAe,CACxB,MAAO,2BACT,CAGA,IAAW,MAAe,CACxB,MAAO,wBACT,CAGA,IAAW,OAAiB,CAC1B,MAAO,EACT,CAGA,IAAW,WAAmB,CAI5B,OAHK,KAAK,QAAQ,eAGX,CAAC,CACN,cAAe,GACf,SAAU,YACV,UAAW,OACX,MAAO,EAAgB,UAAU,KAAK,KAAM,eAAe,CAC7D,CAAC,EAPQ,CAAC,CAQZ,CAGA,IAAW,WAAoB,CAC7B,MAAO,+CAA+C,GAAO,eAAe,GAAG,KAAK,QAAQ,WAC9F,CAGA,IAAW,UAAgB,CACzB,OAAO,EACT,CAEA,SAA6B,CAC3B,MAAO,CACL,OAAQ,CACN,GAAI,+BACJ,eAAgB,EAClB,EACA,cAAe,CACb,GAAI,wBACJ,eAAgB,EAClB,CACF,CACF,CAEA,QAA4B,CAC1B,MAAO,CACL,qCAAsC,wBACxC,CACF,CAEA,gBAA+B,CAC7B,EAAgB,cAAc,CAAC,EAAG,CAChC,WAAY,EAAW,MACvB,OAAQ,EAAW,QACnB,SAAU,EAAgB,sBAC1B,WAAY,EAAgB,IAC9B,CAAC,EAED,KAAK,YAAY,CACnB,CAEA,aAA4B,CACtB,KAAK,cAET,KAAK,YAAc,GACnB,KAAK,oBAAoB,sBAAsB,EACjD,CAEA,mBAAkC,CAChC,KAAK,YAAc,EACrB,CAEA,wBAAuC,CACrC,IAAM,EAAO,IAAI,GAAyB,CACxC,UAAW,GAAsB,QACjC,QAAS,KAAK,QAAQ,OACxB,CAAC,EAED,KAAK,cAAc,gBAAiB,CAAI,EAExC,KAAK,eAAe,CACtB,CAEA,0BAAyC,CAEvC,IAAM,EAAO,IAAI,GAA4B,CAC3C,MAF0B,GAAgB,YAAiC,GAAe,YAEnF,CAAA,CAAoB,yBAAyB,EACpD,MAAO,KAAK,aAAa,aAC3B,CAAC,EAED,KAAK,cAAc,SAAU,CAAI,CACnC,CAEA,aAAiC,CAC/B,OAAO,EACT,CAEA,UAAwB,CACtB,KAAK,yBAAyB,CAChC,CACF,EC5JA,SAAgB,GAAU,EAAsC,CAC9D,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,GAAI,YACP,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,KAAK,eACL,EAAE,0MACH,CAAA,CACE,CAAA,CAET,mCEIM,GAAsB,EAEtB,GAAY,8BAQlB,SAAgB,GAAqB,EAAsD,CACzF,SAAS,EAAY,EAA8B,EAAqB,KAAY,CAC9E,IAAe,EAAM,oBAGzB,EAAgB,cAAc,CAC5B,GAAI,EAAM,kBACV,cAAe,CACjB,EAAG,CACD,WAAY,EAAW,eACvB,OAAQ,EAAW,SACnB,SAAU,EAAgB,WAC5B,CAAC,EAED,EAAc,SAAS,EAAQ,CAAU,CAAC,EAC5C,CAEA,SAAS,EAAQ,EAAqB,CAIpC,OAHK,EAGE,+BAA+B,IAF7B,kBAGX,CA2BA,MAzBI,CAAC,EAAM,WAAW,QAAU,CAAC,EAAM,mBAGnC,EAAM,UAAU,QAAU,GACrB,EAAA,EAAA,IAAA,CAAA,EAAA,SAAA,CAAI,CAAA,EAMT,EAAM,UAAU,OAAS,IAEzB,EAAA,EAAA,IAAA,CAAC,EAAS,KAAV,CACE,GAAG,KACH,QAAS,GAAK,EAAY,CAAC,EAC3B,UAAU,2BAEV,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,0CAAf,EACE,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,OAAS,CAAA,GAC5C,EAAA,EAAA,IAAA,CAAC,EAAD,CAAc,IAAK,GAAU,UAAU,8BAAgC,CAAA,CACpE,GACQ,CAAA,GAKjB,EAAA,EAAA,KAAA,CAAC,KAAD,CAAI,UAAU,kDAAd,EACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,kDAAkD,GAAO,SAAU,iBAAe,WAAW,gBAAc,iBAA3H,EACE,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,OAAS,CAAA,GAC5C,EAAA,EAAA,IAAA,CAAC,EAAD,CAAc,IAAK,GAAU,UAAU,8BAAgC,CAAA,CACpE,KACL,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,yBACX,EAAM,UAAU,KAAK,EAAG,IAAM,CAC7B,IAAM,EAAY,EAAE,KAAO,EAAM,kBACjC,OACE,EAAA,EAAA,IAAA,CAAC,EAAS,KAAV,CAEE,GAAG,KACH,QAAS,GAAK,EAAY,EAAG,EAAE,EAAE,EACjC,SAAU,WAET,EAAE,IACU,EANR,CAMQ,CAEnB,CAAC,CACC,CAAA,CACF,GAER,CC/EA,IAAM,GAAY,EAAgB,iBAAiB,oBAAS,EAQ5D,SAAgB,GACd,EACA,EACA,EACyB,CACzB,GAAM,CAAE,kBAAmB,GAAe,EAEpC,EAAQ,GAAY,OAAO,EAAiB,OAAO,EAEzD,GAAI,IACG,EAAe,EAAe,iBAAiB,GAClD,EAAM,KAAK,CACT,MAAO,GAAU,YAAY,EAC7B,MAAO,EACP,QAAS,WACT,IAAK,GAAc,kBAAkB,EACrC,cAAe,CACb,IAAK,GAAc,kBAAkB,CACvC,EACA,iBAAkB,CAChB,WAAY,EAAW,MACvB,OAAQ,EAAW,IACnB,WAAY,EAAgB,aAC5B,SAAU,EAAgB,WAC5B,CACF,CAAC,EAGH,EAAM,KAAK,CACT,MAAO,GAAU,YAAY,EAC7B,MAAO,EACP,QAAS,WACT,IAAK,GAAc,kBAAkB,EACrC,cAAe,CACb,IAAK,GAAc,kBAAkB,CACvC,EACA,iBAAkB,CAChB,WAAY,EAAW,MACvB,OAAQ,EAAW,IACnB,WAAY,EAAgB,aAC5B,SAAU,EAAgB,WAC5B,CACF,CAAC,EAEG,EAAe,EAAe,gBAAgB,GAAK,CAAC,GAAc,CACpE,IAAM,EAAc,GAAU,cAAc,EAAO,gBAAiB,oBAAoB,EAExF,EAAM,KAAK,CACT,MAAO,GAAU,UAAU,EAC3B,MAAO,EACP,QAAS,WACT,IAAK,EACL,cAAe,CACb,IAAK,CACP,EACA,iBAAkB,CAChB,WAAY,EAAW,MACvB,OAAQ,EAAW,IACnB,WAAY,EAAgB,aAC5B,SAAU,EAAgB,WAC5B,CACF,CAAC,CACH,CAGF,IAAM,EAAoC,CACxC,KAAM,CAAC,EACP,SAAU,CAAC,EACX,OAAQ,CAAC,CACX,EAWA,OATA,EAAM,QAAQ,GAAQ,CAChB,EAAK,UAAY,SACnB,EAAS,OAAO,KAAK,CAAI,EAClB,EAAK,UAAY,WACxB,EAAS,SAAS,KAAK,CAAI,EAE3B,EAAS,KAAK,KAAK,CAAI,CAC3B,CAAC,EAEM,CACT,CAEA,SAAgB,GACd,EACA,EACA,EACkB,CAElB,IAAM,EAAW,EADG,EAAkC,EAAa,YAAY,CAE7E,CAAA,CAAY,MAAM,iBAAmB,GAAgB,aAAa,CACpE,EAEA,GAAI,GAAmB,CAAC,EAAS,KAC/B,OAEF,IAAM,EAAoB,CAAC,GAAG,EAAS,IAAI,EACrC,EAAmB,MAAM,QAAQ,CAAS,EAAI,EAAY,CAAC,CAAS,EAEtE,EAAkB,EAAkB,OAAO,GAAK,CAAC,EAAiB,SAAS,EAAE,EAAE,EAAG,OAAO,EAK7F,OAHI,OAAO,GAAc,aACvB,EAAkB,EAAU,CAAe,GAEtC,GAAY,OAAO,CAAe,CAC3C,mHElGM,GAAY,EAAgB,iBAAiB,oBAAS,EA4B5D,SAAS,GAAyB,CAAE,QAAoD,CACtF,GAAI,EAAK,QACP,OACE,EAAA,EAAA,KAAA,CAAC,EAAS,KAAV,CACE,GAAI,EACJ,QAAS,EAAK,QACd,aAAc,EAAK,aACnB,QAAS,EAAK,QACd,UAAU,4BACV,cAAe,EAAK,cACpB,iBAAkB,EAAK,0BAPzB,CASG,EAAK,QAAU,IACd,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,GAAG,GAAO,QAAQ,yDAC/B,EAAK,OACH,CAAA,GAEP,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,yEAAf,CACG,EAAK,MACL,CAAC,CAAC,EAAK,eACN,EAAA,EAAA,IAAA,CAAC,EAAD,CAAc,IAAK,GAAc,UAAU,8BAAgC,CAAA,CAE1E,GACQ,IAInB,GAAI,EAAK,IAAK,CACZ,SAAS,EAAQ,EAAoD,CACnE,EAAE,eAAe,EAEjB,EAAK,UAAU,EAKX,EAAK,eAAiB,EAAK,kBAC7B,EAAgB,cAAc,CAAE,KAAM,EAAK,IAAK,GAAG,EAAK,aAAc,EAAG,EAAK,gBAAgB,EAEhG,EAAc,SAAS,EAAK,IAAK,EAAI,CACvC,CAEA,OACE,EAAA,EAAA,KAAA,CAAC,EAAS,KAAV,CACE,GAAG,IACH,KAAM,EAAK,IACX,OAAQ,EAAK,eAAiB,GAAQ,KAAO,SAC7C,UAAU,4BACV,QAAS,GAAK,EAAQ,CAAC,WALzB,CAOG,EAAK,QAAU,IACd,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,GAAG,GAAO,QAAQ,yDAC/B,EAAK,OACH,CAAA,GAEP,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,yEAAf,CACG,EAAK,MACL,EAAK,eAAiB,KACrB,EAAA,EAAA,IAAA,CAAC,EAAD,CAAc,IAAK,GAAc,UAAU,8BAAgC,CAAA,CAE1E,GACQ,GAEnB,CAEA,OAAO,EAAA,EAAA,IAAA,CAAA,EAAA,SAAA,CAAI,CAAA,CACb,CAYA,IAAM,IAAmB,CAAE,cAAkD,CAC3E,IAAM,EAAc,GAAe,EAC7B,EAAW,EAAY,IAAM,EAAY,GAE/C,OACE,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,EAAD,CACE,QAAS,EAAS,OAClB,UAAU,oBACV,iBAAkB,CAChB,WAAY,EAAW,MACvB,SAAU,EAAgB,OAC1B,OAAQ,EAAW,IACnB,WAAY,GAAkB,MAChC,EACA,cAAe,CAAC,WAEf,GAAU,QAAQ,CACZ,CAAA,GACT,EAAA,EAAA,IAAA,CAAC,EAAD,CACE,QAAS,EAAS,OAClB,UAAU,oBACV,iBAAkB,CAChB,WAAY,EAAW,MACvB,SAAU,EAAgB,OAC1B,OAAQ,EAAW,QACnB,cAAe,EAAc,MAC7B,WAAY,GAAkB,MAChC,EACA,cAAe,CAAC,EAChB,IAAI,kBAEQ,GAAX,EAAqB,kBAA+B,QAAQ,CACtD,CAAA,CACT,CAAA,CAAA,CAEN,EAEM,IAAgB,CAAE,eACtB,EAAA,EAAA,IAAA,CAAC,EAAD,CACE,QAAS,EAAS,OAClB,UAAU,8BACV,iBAAkB,CAChB,WAAY,EAAW,MACvB,SAAU,EAAgB,OAC1B,OAAQ,EAAW,QACnB,cAAe,EAAc,MAC7B,WAAY,GAAkB,MAChC,EACA,cAAe,CAAC,WAEf,GAAU,QAAQ,CACZ,CAAA,EAIX,SAAgB,GAAgB,EAAiD,CAC/E,GAAM,CAAE,EAAQ,GAAA,EAAoB,SAAS,EAAK,EAC5C,CAAE,kBAAmB,GAAe,EAEpC,EAAO,EAAkC,EAAa,YAAY,CAAC,EACnE,EAAc,EAA2B,EAAK,MAAM,IAAM,EAAa,KAAK,EAAK,KAAK,EAAE,CAAC,EACzF,EAAS,EAA6B,GAAe,OAAO,CAAC,EAC7D,EAAY,EAChB,EAAK,MAAM,iBAAmB,EAAa,UAAU,EAAK,KAAK,EAAE,CACnE,EAEM,EAAQ,GAAuB,EAAO,KAAM,EAAM,gBAAiB,EAAM,YAAY,EAErF,EAAU,EAAe,EAAe,eAAe,EACvD,EAAkB,EAAM,iBAAmB,EAC3C,EAAW,GAAwB,EAAM,UAAW,EAAiB,EAAM,SAAS,EAE1F,SAAS,EAAiB,EAAqB,CAC7C,EAAU,CAAI,EAEd,EAAgB,cAAc,CAAC,EAAG,CAChC,WAAY,EAAW,MACvB,OAAQ,EAAW,QACnB,SAAU,EAAgB,YAC1B,WAAY,EAAO,EAAgB,KAAO,EAAgB,KAC5D,CAAC,CACH,CAEA,SAAS,EAAe,EAAwB,CAC9C,EAAgB,cAAc,CAC5B,GAAI,EAAQ,GACZ,KAAM,EAAQ,IAChB,EAAG,CACD,WAAY,EAAW,MACvB,OAAQ,EAAW,QACnB,SAAU,EAAgB,YAC1B,WAAY,EAAgB,YAC9B,CAAC,CACH,CAUA,MARI,CAAC,EAAK,cAAiB,EAAK,KAAK,iBAAmB,CAAC,EAAY,cAAiB,CAAC,EAAO,MACrF,EAAA,EAAA,IAAA,CAAA,EAAA,SAAA,CAAI,CAAA,EAER,EAAK,KAAK,iBAMb,EAAA,EAAA,KAAA,CAAC,EAAD,CAAU,UAAU,oBAAoB,SAAU,WAAlD,EACE,EAAA,EAAA,IAAA,CAAC,EAAS,OAAV,CAAiB,GAAG,cAAc,QAAQ,GAAG,aAAW,eAAe,UAAW,GAAG,GAAO,gBAAgB,kCAC1G,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,SAAU,GAAY,UAAU,EAAK,KAAK,OAAQ,CAAE,KAAM,GAAU,KAAM,CAAC,EAC3E,YAAa,EAAO,KAAK,YACzB,SAAU,GAAW,YAAY,EAAK,KAAK,UAAW,EAAK,KAAK,UAAU,EAC1E,QAAS,EAAM,KAAK,KAAK,GAAQ,EAAK,QAAU,CAAC,CAClD,CAAA,CACc,CAAA,GACjB,EAAA,EAAA,KAAA,CAAC,EAAS,KAAV,CACE,GAAG,KACH,MAAM,eAFR,EAIE,EAAA,EAAA,KAAA,CAAC,EAAS,KAAV,CAAe,GAAG,eAAlB,EACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,gCAAf,EACE,EAAA,EAAA,IAAA,CAAC,SAAD,CAAA,SAAS,EAAK,KAAK,WAAoB,CAAA,EAAC,OAEtC,CAAC,IAAW,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAU,0BAAhB,CAAiC,IAAE,EAAK,KAAK,SAAS,GAAO,GACxE,KACL,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,8BAAsB,EAAK,KAAK,YAAkB,CAAA,EAC/D,CAAC,GAAW,EAAY,MAAM,kBAAmB,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAU,8BAAsB,EAAY,KAAK,gBAAgB,IAAQ,CAAA,CAClH,KACf,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,aAAc,EACd,kBAAmB,EAAK,MAAM,WAC9B,UAAW,EAAU,MAAM,IAC5B,CAAA,GACD,EAAA,EAAA,IAAA,CAAC,EAAS,QAAV,CAAmB,CAAA,EAElB,EAAM,KAAK,KAAK,EAAM,KAAQ,EAAA,EAAA,IAAA,CAAC,GAAD,CAA0C,MAAO,EAAlB,CAAkB,CAAC,EAEhF,CAAC,CAAC,EAAM,KAAK,QAAU,CAAC,CAAC,GAAU,SAClC,EAAA,EAAA,IAAA,CAAC,EAAS,QAAV,CAAmB,CAAA,EAGpB,GAAU,KAAK,EAAS,KAErB,EAAA,EAAA,KAAA,CAAC,EAAS,KAAV,CAEE,GAAG,IACH,KAAM,EAAQ,IACd,OAAO,SACP,UAAU,iCACV,YAAe,EAAe,CAAO,WANvC,EAQE,EAAA,EAAA,IAAA,CAAC,MAAD,CACE,IAAK,EAAQ,SACb,UAAW,GAAG,GAAO,YAAY,MAClC,CAAA,EACA,EAAQ,IACI,GAZR,CAYQ,CAElB,GAEC,CAAC,CAAC,GAAU,QAAU,CAAC,CAAC,EAAM,KAAK,SAAW,CAAC,CAAC,EAAM,SAAS,SAC/D,EAAA,EAAA,IAAA,CAAC,EAAS,QAAV,CAAmB,CAAA,EAGpB,EAAM,SAAS,KAAK,EAAM,KAAQ,EAAA,EAAA,IAAA,CAAC,GAAD,CAA0C,MAAO,EAAlB,CAAkB,CAAC,GAErF,EAAA,EAAA,IAAA,CAAC,EAAS,QAAV,CAAmB,CAAA,EAElB,EAAM,OAAO,KAAK,EAAM,KAAQ,EAAA,EAAA,IAAA,CAAC,GAAD,CAA0C,MAAO,EAAlB,CAAkB,CAAC,GAEnF,EAAA,EAAA,IAAA,CAAC,EAAS,KAAV,CACE,GAAI,EACJ,QAAS,EAAM,SAAS,QACxB,cAAe,CACb,GAAI,EAAK,MAAM,EACjB,EACA,iBAAkB,CAChB,WAAY,EAAW,MACvB,SAAU,EAAgB,YAC1B,OAAQ,EAAW,QACnB,WAAY,GAAkB,OAChC,WAEC,GAAU,SAAS,CACP,CAAA,CACF,GACP,IArFH,EAAM,eACX,EAAA,EAAA,IAAA,CAAC,GAAD,CAAiB,GAAK,CAAS,CAAA,GAC/B,EAAA,EAAA,IAAA,CAAC,GAAD,CAAc,GAAK,CAAS,CAAA,CAqFlC,CC5RA,SAAgB,IAAuB,CACrC,IAAM,EAAA,EAAqB,OAAO,IAAI,EAEhC,CAAE,iBAAgB,YAAa,GAAe,EAE9C,CAAE,EAAiB,GAAA,EAA6B,SAA+B,CAAC,CAAC,EAEjF,EAAc,GAAoC,GAAe,WAAW,EAElF,EAAM,cAAgB,CAChB,MAAC,EAAY,SAAW,CAAC,GAAY,EAAe,EAAe,iBAAiB,GAaxF,MAVA,GAAa,QAAU,GAEvB,EAAY,gBAAgB,CAAC,CAC1B,KAAK,GAAO,CACN,EAAa,SAGlB,EAAmB,CAAG,CACxB,CAAC,MAEU,CACX,EAAa,QAAU,EACzB,CACF,EAAG,CAAE,GAAa,KAAM,CAAS,CAAC,EAElC,SAAS,EAAiB,EAAyB,CAC7C,GAAa,QAAQ,OAAA,UACvB,EAAmB,GAAa,QAAQ,QAAQ,CACpD,CAEA,SAAS,EAAoB,EAAyB,CACpD,OAAO,EAAY,oBAAoB,CAAW,CACpD,CAEA,SAAS,EAA0B,EAA4B,CAC7D,OAAO,EAAY,0BAA0B,CAAY,CAC3D,CAGA,SAAS,EAAmB,EAAwB,CAClD,EAAe,CAAC,CAAC,QAAQ,GAAK,CACxB,GAAG,QAAQ,WAAa,GAC1B,EAAY,wBAAwB,CAAC,CAGzC,CAAC,CACH,CAEA,SAAS,GAAuC,CAC9C,OAAO,GAAiB,OAAO,GAY7B,EAVI,GAAG,QAAQ,OAAA,UAKX,CAAC,GAAG,QAAQ,UAKZ,GAAG,UAAY,IAAI,KAIxB,CACH,CAEA,SAAS,GAA0C,CACjD,IAAM,EAAiB,EAAe,EAEjC,MAAgB,QAGC,GAAe,KAAK,GAAK,GAAG,SAI9C,EAKJ,OAFmB,EAAe,MAAM,EAAG,IAAM,EAAE,QAAQ,WAAW,EAAI,EAAE,QAAQ,WAAW,CAEvF,CAAA,GAAa,EACvB,CAEA,MAAO,CACL,aAAc,EACd,aAAc,EAAoB,EAClC,mBACA,sBACA,2BACF,CACF,CChIA,SAAgB,IAAgB,CAC9B,GAAM,CAAE,WAAU,OAAQ,CAAE,UAAY,GAAgB,EAClD,CAAE,iBAAgB,YAAa,GAAe,EAE9C,EAAc,EAAkC,EAAa,YAAY,CAAC,EAC1E,EAAY,CAAC,GAAY,CAAC,EAAY,aAEtC,CACJ,gBACE,GAAqB,EAEzB,SAAS,GAAmD,CAe1D,OAbE,GACA,EAAe,EAAe,iBAAiB,EAIxC,OAEL,EACK,EAAQ,eAAiB,OAE9B,EACK,QAEF,MACT,CAIA,MAAO,CACL,UAHgB,EAAc,IAAM,OAIpC,eACF,CACF,0DE3BA,SAAS,GAAU,EAAgC,CACjD,GAAM,CAAE,QAAO,eAAgB,GAAc,CAAC,EAE1C,EAAO,GAAS,GAKpB,OAHI,IACF,EAAO,GAAG,EAAK,GAAG,KAEb,CACT,CAQA,SAAgB,IAA+B,CAC7C,GAAM,CAAE,EAAY,GAAA,EAAwB,SAAkB,EAAK,EAE7D,CACJ,eACA,mBACA,sBACA,6BACE,GAAqB,EAEnB,CAAE,EAAkB,GAAwB,GAChD,GAAG,GAAoB,oBAAoB,GAAG,GAAc,QAAQ,WACpE,CACE,aAAc,GACd,QAAS,EACX,EACA,CAAE,QAAS,EAAY,YAAa,CACtC,EAEA,EAAM,cAAgB,CACpB,GAAI,GAAkB,cAAgB,CAAC,EAAc,CACnD,EAAc,EAAK,EACnB,MACF,CAEK,GAAkB,UACrB,EAA0B,CAAC,CAAY,CAAC,EACxC,EAAoB,CAClB,GAAG,EACH,QAAS,EACX,CAAC,GAGH,EAAc,EAAI,CACpB,EAAG,CAAE,GAAkB,aAAc,GAAc,QAAQ,QAAS,CAAC,EAErE,SAAS,GAAY,CACnB,EAAgB,cAAc,EAAe,CAC3C,WAAY,EAAW,QACvB,SAAU,EAAgB,OAC1B,OAAQ,EAAW,MACrB,CAAC,EAED,EAAoB,CAClB,GAAG,EACH,aAAc,EAChB,CAAC,EAED,EAAc,EAAK,EACnB,EAAiB,CAAY,CAC/B,CAEA,SAAS,GAAU,CACjB,EAAoB,CAAY,CAClC,CAEA,GAAI,CAAC,GAAc,CAAC,EAClB,OAAO,EAAA,EAAA,IAAA,CAAA,EAAA,SAAA,CAAI,CAAA,EAEb,IAAM,EAAa,GAAU,CAAY,EACnC,CAAE,MAAK,YAAa,EAEpB,EAAgB,CACpB,GAAI,qBACJ,KAAM,GAAc,MACpB,SAAU,GAAc,QAAQ,SAChC,KAAM,SACN,KACF,EAEA,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,oCAAoC,GAAO,kBAA3D,EACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,uBAAf,CACG,CAAC,CAAC,IACD,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,kDAA0C,CAAiB,CAAA,EAE5E,CAAC,CAAC,GAAO,CAAC,CAAC,IACV,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,UAAU,oCACV,KAAM,EACN,OAAQ,GACO,gBACN,UACT,iBAAkB,CAChB,WAAY,EAAW,MACvB,SAAU,EAAgB,OAC1B,OAAQ,EAAW,IACnB,WAAY,EAAgB,YAC9B,WACC,CACW,CAAA,CAEb,KACL,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,oCAAoC,GAAO,QAAS,QAAS,YAC3E,EAAA,EAAA,IAAA,CAAC,EAAD,CAAc,UAAU,0CAA0C,IAAK,EAAW,CAAA,CAC/E,CAAA,CACF,GAET,mCE7HM,GAAY,sBAGlB,SAAgB,IAAgC,CAC9C,GAAM,CAAE,gBAAiB,GAAgB,EAEzC,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,aAAa,GAAO,mBAClC,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,wBACb,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,mDACd,EAAA,EAAA,IAAA,CAAC,EAAD,CACa,UAAA,GACX,OAAQ,EAAe,UAAY,aACnC,QAAS,CAAE,cAAa,CACzB,CAAA,CACG,CAAA,CACH,CAAA,CACF,CAAA,CAET,CCpBA,SAAgB,IAA0B,CACxC,GAAM,CAAE,iBAAkB,GAAc,EAElC,EAAa,EAAc,EAQjC,OANI,IAAe,SACV,EAAA,EAAA,IAAA,CAAC,GAAD,CAAkB,CAAA,EAEvB,IAAe,gBACV,EAAA,EAAA,IAAA,CAAC,GAAD,CAAmB,CAAA,GAErB,EAAA,EAAA,IAAA,CAAA,EAAA,SAAA,CAAI,CAAA,CACb,CCbA,SAAgB,GAAY,EAAsC,CAChE,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,mHAAf,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,8BAAqB,gBAAsB,CAAA,GAC3D,EAAA,EAAA,IAAA,CAAC,OAAD,CAAA,SAAO,EAAM,IAAW,CAAA,CACrB,GAET,CCLA,SAAS,GAAY,EAAe,CAClC,OAAO,EAAM,QAAQ,yBAA0B,MAAM,CACvD,CAEA,SAAgB,GAAY,EAAe,EAAuB,CAChE,GAAI,IAAkB,KACpB,MAAO,CAAC,CAAE,MAAO,EAAO,YAAa,EAAM,CAAC,EAG9C,IAAM,EAAY,GAAY,CAAa,EAM3C,GAAI,EAJoB,MAAM,QAAQ,CAAS,EAC7C,EAAU,OAAO,GAAQ,EAAK,KAAK,CAAC,CAAC,OAAS,CAAC,CAAC,CAAC,OAAS,EAC1D,EAAU,KAAK,IAAM,IAGrB,MAAO,CAAC,CAAE,MAAO,EAAO,YAAa,EAAM,CAAC,EAG9C,IAAM,EAAU,EAAU,KAAK,EACzB,EAAS,OAAO,IAAI,EAAQ,GAAI,IAAI,EAM1C,OALe,EACZ,MAAM,CAAE,CAAC,CACT,IAAI,IAAS,CAAE,MAAO,EAAM,YAAa,EAAG,KAAK,CAAI,CAAE,EAAE,CAAC,CAC1D,QAAQ,CAAE,WAAY,CAElB,CACT,CAeA,SAAgB,GAAc,EAAwC,CACpE,IAAM,EAAA,EAAwB,YACtB,GAAY,EAAM,KAAM,EAAM,SAAS,EAC7C,CAAE,EAAM,KAAM,EAAM,SAAU,CAChC,EACM,EAAmD,GAAY,EAAiB,EAAM,OAAS,GAAG,EAElG,EAAS,EAAM,MAAQ,EAA2B,EAExD,OACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAM,WAAW,MAAQ,YACvC,EAAO,KAAK,CAAE,QAAO,eAAe,IAC/B,GACK,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAM,WAAW,WAAa,uBAAwB,CAAY,EAAhB,CAAgB,GAGrF,EAAA,EAAA,IAAA,CAAC,OAAD,CAAc,UAAW,EAAM,WAAW,MAAQ,YAAK,CAAY,EAAxD,CAAwD,CAC3E,CACG,CAAA,CAEV,+JE1CM,GAAY,4BACZ,GAAY,EAAgB,iBAAiB,EAAS,EAUtD,GAAA,EAAkC,WACtC,SACE,EACA,EACa,CACb,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,OAAO,EAAM,UAAY,EAAM,UAAY,KAAW,eACnE,EAAM,QACJ,CAAA,CAET,CACF,EAOa,GAAyB,IAElC,EAAA,EAAA,IAAA,CAAC,GAAD,CAA2B,UAAU,wEACnC,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,2CAAf,EACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,sCACb,EAAA,EAAA,IAAA,CAAC,EAAD,CAAc,IAAK,GAAW,KAAM,EAAiB,QAAW,CAAA,CAC7D,CAAA,GAEL,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,8BACZ,EAAM,gBACL,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,KAAM,EAAM,YAAY,KACxB,UAAW,EAAM,MACjB,MAAO,IACP,UAAW,CACT,UAAW,+BACX,KAAM,aACR,CACD,CAAA,GACD,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,uBAAe,EAAM,YAAY,IAAW,CAAA,CAE3D,CAAA,CACF,GACoB,CAAA,EAG/B,GAAsB,GAAK,0BAO3B,SAAS,GAAuB,EAAoC,CAClE,GAAM,CAAE,EAAK,GAAY,GAAyB,EAElD,SAAS,EAAa,EAAqB,CACzC,EAAE,eAAe,EACjB,EAAM,mBAAmB,EAAM,YAAY,IAAI,CACjD,CAEA,IAAM,EAAS,EAAM,eAAiB,EAEhC,EAAU,EAAM,YAAY,SAAS,QACrC,EAAY,EAAM,YAAY,SAAS,UAE7C,OACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAA2B,UAAW,yEAAyE,EAAS,+BAAiC,KAAW,gBAClK,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,iDAAf,EACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,sCACb,EAAA,EAAA,IAAA,CAAC,EAAD,CAAc,IAAK,GAAW,KAAM,EAAiB,QAAW,CAAA,CAC7D,CAAA,GAEL,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,EAAW,4EAA6E,GAAO,gBAAgB,WAA/H,EACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAA,SAAA,CACG,GAAW,IAAa,EAAA,EAAA,IAAA,CAAC,GAAD,CAAa,KAAM,CAAY,CAAA,GACxD,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,0CAAkC,EAAM,YAAY,IAAW,CAAA,CAC5E,CAAA,CAAA,GACL,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,IAAK,GACL,QAAS,EAAiB,SAC1B,QAAS,EACT,UAAW,2BAA2B,EAAS,cAAgB,aAChE,CAAA,CACE,GACF,GACoB,CAAA,CAE/B,CASA,SAAS,GAAsB,EAAgD,CAC7E,SAAS,GAA0B,CACjC,IAAM,EAAmB,EAAM,mBAAqB,GAAK,EAAM,mBACzD,EAAU,GAAa,MAAM,EAAM,cAAc,EAKvD,MAHI,CAAC,GAAoB,CAAC,GACjB,EAAA,EAAA,IAAA,CAAA,EAAA,SAAA,CAAI,CAAA,GAGX,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAW,GAAG,GAAO,oCAA3B,CACG,IAAoB,EAAA,EAAA,IAAA,CAAA,EAAA,SAAA,CAAA,SAAG,EAAM,mBAAmB,IAAO,CAAA,EACvD,GAAoB,IAAW,EAAA,EAAA,IAAA,CAAA,EAAA,SAAA,CAAA,SAAE,KAAU,CAAA,EAC3C,IAAW,EAAA,EAAA,IAAA,CAAA,EAAA,SAAA,CAAA,SAAG,EAAgB,UAAU,GAAW,KAAK,CAAI,CAAA,CACzD,GAEV,CAEA,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,iEAAf,EACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,2CAAf,EACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,GAAO,0BACrB,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,KAAM,EAAM,eAAe,OAAO,IAClC,eAAe,UACf,aAAc,CAAE,KAAM,GAAU,KAAM,EACtC,UAAW,GAAU,gBAErB,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,mBAAoB,GAAmB,MACvC,aAAc,GAAG,GAAO,gBAAgB,2CACxC,KAAM,GAAkB,QACxB,sBAAsB,KACvB,CAAA,CACQ,CAAA,CACR,CAAA,GACL,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,8BAAf,CACG,EAAW,GACZ,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,uBAAe,EAAM,eAAe,IAAW,CAAA,CAC5D,GACF,IACJ,EAAM,WACL,EAAA,EAAA,IAAA,CAAC,GAAD,CAAO,KAAM,GAAU,SAAU,KAAM,GAAU,UAAU,EAAG,KAAK,IAAM,CAAA,CAExE,GAET,CAUA,SAAS,GAAuB,EAA2C,CA4BzE,OA3BI,EAAM,YAAY,iBAAmB,EAAe,QAEpD,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,WAAY,EAAM,WAClB,mBAAoB,EAAM,mBAC1B,cAAe,EAAM,aACtB,CAAA,EAID,EAAM,YAAY,iBAAmB,EAAe,SACtD,EAAM,YAAY,KAAO,GAAsB,IAExC,EAAA,EAAA,IAAA,CAAC,GAAD,CAAuB,WAAY,EAAM,WAAY,MAAO,EAAM,KAAQ,CAAA,EAG/E,GAAiB,OAAuB,EAAM,WAAY,GAAW,OAAO,GAE5E,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,mBAAoB,EAAM,mBAC1B,mBAAoB,EAAM,mBAC1B,eAAgB,EAAM,WACtB,SAAU,EAAM,YAAY,iBAAmB,EAAe,KAC/D,CAAA,GAIE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAuB,WAAY,EAAM,WAAY,MAAO,EAAM,MAAO,eAAA,EAAgB,CAAA,CAClG,CAEA,SAAgB,GAAiB,EAA2C,CAG1E,OACE,EAAA,EAAA,IAAA,CAAA,EAAA,SAAA,CAAA,SAH0B,GAAuB,CAI9C,CACD,CAAA,CAEN,6DEtNA,SAAgB,GAAa,EAAuC,CAClE,GAAM,CAAE,UAAS,aAAc,EAK/B,OAHK,EAAQ,OAAO,QAIlB,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,YAAY,GAAO,oBAAoB,GAAG,cACxD,EAAA,EAAA,IAAA,CAAC,SAAD,CAAA,SAAS,EAAQ,KAAc,CAAA,CAC5B,CAAA,GALE,EAAA,EAAA,IAAA,CAAA,EAAA,SAAA,CAAI,CAAA,CAOf,GCzBmB,EAWnB,IAAa,GAAqB,CAChC,kBAAqB,EAAa,EAAgC,CAChE,IAAI,EAAiB,EAAW,SAAS,CAAG,EAK5C,OAHK,EAAU,CAAc,IAC3B,EAAiB,CAAC,GAEb,CACT,EAEA,kBAAqB,EAAa,EAAqB,EAAiC,CACjF,EAAU,CAAc,GAG7B,EAAW,SAAS,EAAK,CAAc,CACzC,EAEA,qBAAwB,EAAa,EAA2B,EAA4C,CAC1G,GAAM,CAAE,MAAK,SAAQ,QAAO,QAAQ,GAAM,EAEtC,EAAiB,GAAmB,kBAAqB,EAAK,CAAU,EAEtE,EAAa,EAAa,EAAgB,CAAK,EAarD,OAXI,GAAO,IAAe,IACxB,EAAe,QAAQ,CAAK,EAE1B,GAAU,EAAa,IACzB,EAAe,OAAO,EAAY,CAAC,EAEjC,EAAe,OAAS,IAC1B,EAAiB,EAAe,MAAM,EAAG,CAAK,GAEhD,GAAmB,kBAAqB,EAAK,EAAgB,CAAU,EAEhE,CACT,EAEA,oBAAoB,EAAiC,CACnD,EAAW,MAAM,CACnB,CACF,EC5CM,GAA0B,CAAE,WAAY,OAAQ,EAChD,GAA6B,CACjC,CAAE,UAAW,kBAAmB,MAAO,MAAO,CAChD,EAEM,GAAkB,CACtB,eAAgB,GAChB,kBAAmB,GACnB,aAAc,EAChB,EAEM,GAA0B,GAAa,CACvC,IACE,EAAE,gBAAgB,EAAE,eAAe,EACnC,EAAE,gBACJ,EAAE,gBAAgB,EACT,OAAO,QAChB,OAAO,MAAM,aAAe,IAGlC,EAEM,GAAa,GAAa,CAC9B,IAAM,EAAmB,CAAC,EACpB,EAAM,CAAC,EACP,EAAM,EAAE,OACV,EAAI,EACR,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,IAAK,CAC5B,IAAM,EAAO,EAAE,GACX,EAAK,KAAU,IACjB,EAAK,GAAQ,EACb,EAAI,KAAO,EAEf,CACA,OAAO,CACT,EAEM,IACJ,EAGA,EAA4B,EAC5B,EACA,IACY,CACZ,IAAM,EAAqB,EAAc,QAAQ,CAAW,EAI5D,GAAI,EAHsB,EAAc,QAAQ,CAAW,GAAK,GAGxC,MAAO,GAM/B,IAAM,EAAkB,KAAK,IAAI,EAAc,OAAS,EAAG,CAAC,EAC5D,GACE,EAAc,QACd,EAAc,KAAqB,EAAc,GAEjD,MAAO,GAKT,GAAI,IAAuB,EAMzB,OAFI,EAA4B,EACvB,EAAc,QAAQ,CAAW,GAAK,EACxC,GAGT,IAAM,EAA2B,EAAqB,EAChD,EAAsB,EAAc,GAU1C,OARE,EAAc,KAA8B,GAQvC,GACL,EACA,EACA,EACA,CACF,CACF,EAaM,IAAuB,CAAE,eAAc,WAAU,QAAS,KAA8C,CAC5G,IAAM,EAAU,CAAE,GAAG,GAAiB,GAAG,CAAY,EACrD,GAAI,CAAC,MAAM,QAAQ,CAAY,EAC7B,MAAU,MACR,uGACF,EAEF,GAAI,CAAC,EAAa,OAChB,MAAU,MACR,oGACF,EAEF,GAAI,CAAC,GAAY,OAAO,GAAa,WACnC,MAAU,MACR,kHACF,EAEF,IAAM,GAAA,EAAA,EAAA,QAAA,KAA+B,EAAa,KAAK,EAAG,CAAC,CAAY,CAAC,EAGlE,GAAA,EAAA,EAAA,QAAA,KACE,GAAU,CAAY,CAAC,CAAC,IAAI,GAAO,OAAO,CAAG,CAAC,CAAC,YAAY,CAAC,EAKlE,CAAC,CAAc,CACjB,EAEM,GAAA,EAAA,EAAA,OAAA,CAAkB,CAAC,CAAC,EAEpB,GAAA,EAAA,EAAA,YAAA,CACH,GAAgC,CAC3B,GAAS,aACX,QAAQ,IAAI,wBAAyB,EAAa,GAAG,EAGvD,IAAM,EAAa,OAAO,EAAa,GAAG,CAAC,CAAC,YAAY,EACxD,GAAI,EAAE,EAAc,QAAQ,CAAU,GAAK,GAAI,OAE/C,IAAM,EAAc,EAAa,OA+BjC,GA5BE,EAAQ,oBAEN,GAAwB,SAAS,EAAY,OAAO,GACpD,GAA2B,MAAM,CAAE,YAAW,WAAY,EAAY,aAAa,CAAS,IAAM,CAAK,IAMvG,EAAa,QAAU,CAAC,EAAQ,eAEhC,EAAQ,gBACV,GAAuB,CAAY,EAgBjC,CAP8B,GAChC,EACA,KACA,EACA,EAAS,OAGN,GACH,OAGF,IAAM,EAAe,CAAE,GAAG,EAAS,QAAS,CAAW,EAQvD,OAPI,EAAa,KAAK,IAAM,EAAc,KAAK,GAC7C,EAAS,CAAY,EACd,KAGT,EAAS,QAAU,EAEZ,GACT,EAEA,CACE,EACA,EACA,EAAQ,eACR,EAAQ,iBACV,CACF,EAEM,GAAA,EAAA,EAAA,YAAA,CACH,GAA8B,CAC7B,IAAM,EAAY,OAAO,EAAW,GAAG,CAAC,CAAC,YAAY,EACrD,GAAI,EAAE,EAAc,QAAQ,CAAS,GAAK,GAAI,OAE9C,IAAM,EAAqB,EAAS,QAAQ,QAAQ,CAAS,EAC7D,GAAI,EAAE,GAAsB,GAAI,OAEhC,IAAM,EAAe,CAAC,EAClB,EACJ,IAAK,EAAY,EAAG,EAAY,EAAS,QAAQ,OAAQ,EAAE,EACrD,IAAc,GAChB,EAAa,KAAK,EAAS,QAAQ,EAAU,EAKjD,MAFA,GAAS,QAAU,EAEZ,EACT,EAEA,CAAC,CAAc,CACjB,EAEM,GAAA,EAAA,EAAA,YAAA,KAAkC,CACtC,EAAS,QAAU,CAAC,CACtB,EAAG,CAAC,CAAC,EAgBL,OAdA,EAAA,EAAA,UAAA,MACE,OAAO,iBAAiB,UAAW,CAAe,EAClD,OAAO,iBAAiB,QAAS,CAAa,MACjC,CACX,OAAO,oBAAoB,UAAW,CAAe,EACrD,OAAO,oBAAoB,QAAS,CAAa,CACnD,GACC,CAAE,EAAiB,EAAe,CAAe,CAAC,GAGrD,EAAA,EAAA,UAAA,KAAgB,CACd,EAAc,CAChB,EAAG,CAAE,EAAgB,CAAc,CAAC,EAE7B,CACL,eACF,CACF,EC3OA,SAAgB,GAAa,EAA+B,CAC1D,GAAM,CAAE,EAAgB,IAAA,EAAA,EAAA,SAAA,CAA+B,CAAC,GAExD,EAAA,EAAA,UAAA,KAAgB,CACd,SAAS,GAA0B,CACjC,0BAA4B,CAC1B,EAAkB,OAAO,WAAa,SAAS,gBAAgB,WAAW,CAC5E,CAAC,CACH,CAMA,OAJA,EAAwB,EAExB,OAAO,iBAAiB,SAAU,CAAuB,MAE5C,CACX,OAAO,oBAAoB,SAAU,CAAuB,CAC9D,CACF,EAAG,CAAC,CAAC,EAEL,SAAS,GAAkB,CAGzB,GAFA,SAAS,KAAK,MAAM,SAAW,GAE3B,CAAC,GAAS,kBACZ,OAEF,IAAM,EAAS,GAAS,oBAAsB,SAAS,KACvD,EAAO,MAAM,aAAe,EAC9B,CAEA,SAAS,GAAmB,CAG1B,GAFA,SAAS,KAAK,MAAM,SAAW,SAE3B,CAAC,GAAS,kBACZ,OAEF,IAAM,EAAS,GAAS,oBAAsB,SAAS,KACvD,EAAO,MAAM,aAAe,GAAG,EAAe,GAChD,CAEA,MAAO,CACL,MAAO,EACP,OAAQ,EACR,QAAS,CACX,CACF,CEtBA,GAAM,CACJ,aAAc,GACd,gBAAiB,IACf,CDtCF,aAAc,GACd,mBAAoB,GACpB,yBAA0B,GAC1B,gBAAiB,GCmCf,EAEE,GAAgB,GAChB,GAA2B,GAG3B,GAAqB,IAAI,IAE/B,SAAS,GAAuB,EAAe,EAAsC,CASnF,MARI,CAAC,GAAW,CAAC,OAAO,KAAK,CAAO,CAAC,CAAC,QAIlC,CAAC,EAAQ,SAAW,CAAC,EAAQ,UACxB,EAGF,KAAK,UAAU,CACpB,KAAM,EACN,SACF,CAAC,CACH,CAYA,SAAS,GAAsB,EAAiC,CAC9D,GAAI,CACF,OAAO,KAAK,MAAM,CAAK,CACzB,MAAQ,CACN,MAAO,CAAE,KAAM,CAAM,CACvB,CACF,CAwBA,SAAgB,GAAiB,EAAkC,CACjE,IAAM,EAAW,GAAmB,EAC9B,CAAE,aAAc,GAAc,EAC9B,CAAE,YAAa,GAAgB,EAE/B,CAAE,EAA4B,GAAA,EAAwC,SAAS,CAAC,EAChF,CAAE,EAAU,GAAgB,GAAa,GAAc,iBAAkB,EAAK,EAC9E,EAAI,GAAoB,GAAa,GAAc,qBAAsB,EAAK,EAC9E,CAAE,0BAA2B,GAA0B,EACvD,CAAE,sBAAuB,GAAsB,EAE/C,EAAa,GAAa,CAC9B,mBAAoB,GAAS,SAAS,QACtC,kBAAmB,EACrB,CAAC,EAEK,EAAY,GAAa,CAC7B,mBAAoB,GAAS,QAAQ,QACrC,kBAAmB,EACrB,CAAC,EAEK,EAAe,GAAa,CAChC,mBAAoB,GAAS,cAAc,QAC3C,kBAAmB,EACrB,CAAC,EAGK,EADU,GAAe,gBAAgB,CAAC,CAAC,SACxB,QAAU,CAAC,EAE9B,CAAE,EAAkB,GAAA,EAA8B,SAAS,EAAK,EAEhE,EAAA,EAA6B,OAA0B,IAAI,EAE3D,EAAA,EAAqB,QAAQ,GAAa,gBAAiB,CAAC,CAAC,EAC7D,EAAe,GAAQ,OAAS,GAChC,CAAE,EAAO,GAAA,EAAmB,SAAS,CAAY,EACjD,EAAiB,GAAY,EAAO,EAAQ,iBAAiB,EAE7D,CAAE,EAAgB,GAAA,EAA4B,SAA6B,EAAwB,CAAC,EACpG,CAAE,GAAiB,GAAA,EAA6B,SAAkB,EAAK,EAEvE,EAAe,GAAe,gBAAgB,EAC9C,EAAiB,EAAa,QAC9B,GAAkB,GAAa,mBAAmB,EAClD,GAAiB,GAAa,gBAAgB,CAAc,EAElE,SAAS,GAA8C,CACrD,OAAO,GAAmB,kBAAkB,EAAQ,gBAAiB,EAAkB,CAAC,CACtF,IAAuB,GAAkB,GAAsB,CAAK,CAAC,CACzE,CAEA,SAAS,GACP,EACA,EACA,CACA,EAAY,EAAI,EAEhB,OAAO,eAAiB,CACtB,EAAY,EAAK,EACjB,EAAmB,QAAQ,EAAiB,CAAE,QAAS,EAAK,CAAC,CAC/D,EAAG,CAAQ,CACb,CAEA,SAAS,GAAuB,EAAe,EAAiC,EAAsB,CACpG,GAAI,GAAmB,IAAI,CAAK,EAAG,CACjC,IAAM,EAAO,GAAmB,IAAI,CAAK,EACzC,IAAY,CAAI,EAChB,MACF,CAEA,IAAM,EAAM,GAAe,YAAY,EAAO,GAAwB,IAAI,GAAQ,GAAM,EAAE,CAAC,EAE3F,EAAS,CACP,GAAG,EACH,QAAS,GAAQ,CACf,GAAmB,IAAI,EAAO,CAAI,EAClC,OAAO,EAAI,SAAY,YAAc,EAAI,QAAQ,CAAI,EACrD,OAAO,GAAc,YAAc,EAAU,CAAI,CACnD,EACA,MAAO,GAAO,CACZ,OAAO,EAAI,OAAU,YAAc,EAAI,MAAM,CAAG,EAChD,OAAO,GAAY,YAAc,EAAQ,CAC3C,CACF,CAAC,CACH,CAEA,SAAS,GAA0B,EAAY,CAC7C,OAAO,GAAwB,KAAK,GAAQ,GAAM,GAAG,SAAS,IAAM,CAAE,CACxE,CAEA,SAAS,GAAqB,EAAe,EAA8B,CACpE,IAGD,EAAQ,qBAGZ,GAAmB,qBAAqB,EAAQ,gBAAiB,GAAoB,CACnF,MAAO,GAAuB,EAAO,CAAO,EAC5C,MAAO,EAAQ,cAAgB,EAAI,IAAA,GACnC,IAAK,EACP,CAAC,EAED,EAAkB,EAAwB,CAAC,GAC7C,CAEA,SAAS,GAAmB,EAA2B,EAA8B,CAC/E,CAAC,GAAqB,CAAC,EAAkB,SAG7C,GAAmB,qBAAqB,EAAQ,gBAAiB,GAAoB,CACnF,MAAO,GAAuB,EAAmB,CAAO,EACxD,MAAO,EAAQ,cAAgB,EAAI,IAAA,GACnC,OAAQ,EACV,CAAC,EAED,EAAkB,EAAwB,CAAC,EAC7C,CAEA,SAAS,IAA6B,CACpC,IAAM,EAAiB,EAAwB,EAE/C,EAAgB,cAAc,CAC5B,gBACF,EAAG,CACD,WAAY,EAAW,MACvB,OAAQ,EAAW,iBACnB,SAAU,EAAgB,UAC1B,WAAY,EAAgB,KAC9B,CAAC,EAED,GAAmB,oBAAoB,EAAkB,EACzD,EAAkB,CAAc,CAClC,CAEA,SAAS,IAAqB,CAE5B,IAAM,EAAoB,SAAS,cAAc,uFAAuF,EACnI,GAGL,EAAkB,eAAe,CAC/B,SAAU,UACV,MAAO,UACP,OAAQ,SACV,CAAC,CACH,CAEA,SAAS,IAAe,CACtB,EAAU,OAAO,EACjB,EAAW,OAAO,EAClB,EAAa,OAAO,CACtB,CAEA,SAAS,IAAgB,CACvB,EAAU,QAAQ,EAClB,EAAW,QAAQ,EACnB,EAAa,QAAQ,CACvB,CAEA,SAAS,GAAc,EAAwB,CAC7C,GAAI,IAAS,OAAQ,CACnB,EAAmB,EAAK,EACxB,EAAqB,QAAQ,UAAU,EACvC,MACF,CAEA,EAAmB,EAAI,EACvB,EAAqB,QAAQ,WAAW,CAC1C,CAEA,IAAM,GAAsC,GAAe,aAAe,CACxE,GAAI,CAAC,EAAQ,cACX,OAEF,IAAM,EAAkB,GACpB,CAAC,GACD,OAAO,WAAa,IACpB,OAAO,QAAU,GAEjB,EAAkB,OAAO,YAAc,GAAgB,GACvD,IACF,GAAmB,IAErB,EAA8B,CAAe,CAC/C,EAAG,GAAI,EA8JP,OAxJA,EAAM,cAAgB,CAChB,MAAC,EAAQ,eAAiB,OAAO,EAAQ,gBAAmB,WAGhE,IAAI,IAAmB,EAAQ,eAAgB,CAC7C,EAAgB,EAAI,EACpB,GAAc,EACd,MACF,CAEA,EAAgB,EAAK,EACrB,GAAa,CAHb,CAIF,EAAG,CAAE,GAAiB,EAAQ,eAAgB,EAAQ,aAAc,CAAC,EAErE,EAAM,cAAgB,CAEpB,GAAoC,CACtC,EAAG,CAAE,EAAW,EAAQ,aAAc,CAAC,EAEvC,GACE,GACA,KACA,CAAE,EAAW,EAAQ,aAAc,CACrC,EAEA,GACE,GACA,CAAE,EAAW,EAAQ,aAAc,CACrC,EAEA,GAAoB,CAClB,aAAc,CAAE,UAAW,GAAI,EAC/B,QAAS,CACP,kBAAmB,GACnB,eAAgB,GAChB,aAAc,EAChB,EACA,aAAgB,CACd,EAAqB,SAAS,WAAW,CAC3C,CACF,CAAC,EAED,GAAoB,CAClB,aAAc,CAAE,OAAQ,GAAI,EAC5B,QAAS,CACP,kBAAmB,GACnB,eAAgB,GAChB,aAAc,EAChB,EACA,aAAgB,CACC,GAAgB,mBAC3B,CAAA,CAAO,KAAO,aAGlB,EAAqB,SAAS,WAAW,CAC3C,CACF,CAAC,EAED,GAAoB,CAClB,aAAc,CAAC,QAAQ,EACvB,QAAS,CACP,kBAAmB,GACnB,eAAgB,GAChB,aAAc,EAChB,EACA,aAAgB,CACd,EAAqB,SAAS,UAAU,CAC1C,CACF,CAAC,EAMD,EAAM,cAAgB,CACE,GAAa,cAAc,EAAO,CACpD,GAAiB,CAAC,IAGtB,GAAY,GAAiB,EAAQ,4BAA4B,CACnE,EAAG,CACA,EAAe,QAAuB,oBACtC,EAAe,QAAuB,OACtC,EAAe,QAAuB,YACtC,EAAe,QAAuB,MACzC,CAAC,EAGD,EAAM,cAAgB,CACpB,GAAI,EAAQ,cACV,OAEF,IAAM,EAAS,CAAE,GAAG,EAAe,MAAqB,EAGpD,EAAe,KAAK,GAAK,GAAQ,qBAAuB,CAAC,EAAa,UACxE,OAAO,EAAO,oBAEhB,IAAM,EAAgB,GAAa,cAAc,EAAO,CAAc,EAGtE,GAAI,CAAC,GAAiB,GACpB,OAAO,GAAY,GAAiB,EAAQ,4BAA4B,EAErE,IAGL,EAAgB,cAAc,CAC5B,QACA,QAAS,GAAa,kBAAkB,EAAe,OAAsB,EAAQ,aAAa,CACpG,EAAG,CACD,WAAY,EAAW,cACvB,OAAQ,EAAW,cACnB,SAAU,EAAgB,UAC1B,cAAe,EAAc,QAC/B,CAAC,EAED,GAAa,eAAe,EAAO,EAAsB,EAAc,EACzE,EAAG,CAAC,CAAc,CAAC,EAGnB,GAAY,GAAA,QAAM,QAAQ,EAAe,KAAK,EAAA,EAAmB,WAAY,GAAW,CAatF,GAXA,AACE,IAAU,GAAe,gBAAgB,CAAC,CAAC,QAGzC,GAAS,CAAC,GAAa,gBAAgB,CAAO,IAChD,CAAC,EAAQ,eAAiB,EAAoB,EAAI,EAClD,EAAS,EAAE,EACX,EAAqB,SAAS,aAAa,GAIzC,GAAa,gBAAgB,CAAO,GAAK,EAAQ,QAAQ,QAAU,CAAC,EAAO,CAC7E,IAAM,EAAc,EAAQ,OAAO,OAAS,GAC5C,EAAS,CAAW,EAEpB,IAAM,EAAO,GAAe,iBAAiB,EACzC,IAAS,EAAQ,eAAiB,CAAC,GAAa,gBAAgB,EAAK,OAAO,IAC9E,EAAqB,SAAS,WAAW,CAAW,CACxD,CACF,EAAG,CAAE,EAAO,CAAS,CAAC,EAUf,CACL,QACA,eACA,eACA,WACA,iBACA,iBACA,kBACA,mBACA,mBACA,uBACA,yBACA,6BACA,qBACA,uBAAA,GACA,WACA,cACA,eACA,iBACA,kBACA,qBACA,sBACA,sBACA,wBACA,0BACA,6BACA,sBACA,6BACF,CACF,CCtcA,IAAM,GAAiB,CACrB,oBAAsB,GACtB,iBAAkB,EACpB,EAMA,SAAgB,GAAY,EAA6B,CACvD,GAAM,CAAE,eAAgB,EAElB,EAAU,GAAe,gBAAgB,CAAC,CAAC,QAC3C,EAAW,GAAS,SAAwB,IAC5C,CAAE,EAAkB,GAAA,EAA8B,SAA6B,GAAW,IAAA,EAAS,EAEnG,EAAc,GAAa,gBAAgB,CAAO,GAAK,CAAC,CAAC,EAEzD,EAAA,EAAqB,OAAuB,IAAI,EAEhD,EAAS,EACb,GAAe,GAAwB,eAAe,CAAgB,CACxE,EAOM,EAAA,EAAyB,gBAAkB,CAC3C,CAAC,EAAa,SAAW,CAAC,EAAY,SAAW,CAAC,IAGtD,EAAa,QAAQ,MAAM,KAAO,GAAG,GAAe,oBAAoB,IACxE,EAAY,QAAQ,iBAAiB,eAAgB,GAAG,EAAa,SAAS,YAAc,GAAe,iBAAiB,GAAG,EACjI,EAAG,CAAE,EAAa,QAAS,EAAY,QAAS,CAAY,CAAC,EAMvD,CAAC,GAAa,GAAU,CAC5B,SAAU,GAAU,CACb,GAGL,EAAiB,CACnB,CACF,CAAC,EAED,GAAkB,CAAgB,EAQlC,GAAY,GAAA,MAAM,QAAQ,EAAe,KAAK,EAAA,EAAmB,WAAa,GAA0B,CAEtG,IAAM,GADU,GAAS,QAAU,CAAC,EAAA,CACZ,IAExB,EAAoB,CAAQ,CAC9B,EAAG,CAAC,CAAO,CAAC,EAEZ,IAAM,EAAA,EAAgB,YAAa,GAAyB,CAC1D,EAAa,QAAU,EACvB,EAAU,CAAI,CAChB,EAAG,CAAC,CAAS,CAAC,EAEd,SAAS,GAAU,CACjB,EAAoB,IAAA,EAAS,EAC7B,EAAY,SAAS,iBAAiB,eAAgB,EAAE,CAC1D,CAEA,IAAM,EAAY,CAAC,CAAC,GAAoB,EAAO,cAAgB,CAAC,CAAC,EAAO,MAAM,KAE9E,MAAO,CACL,KAAM,CACJ,KAAM,EAAO,MAAM,IACrB,EACA,OAAQ,EAAY,EACjB,IAAkB,EACnB,UAAW,EAAO,MAAM,IAC1B,EAAI,IAAA,GACJ,YACA,iBAAkB,EAClB,SACF,CACF,CC5CA,IAAM,GAA4C,CAChD,WAAY,EAAW,OACvB,cAAe,EAAc,QAC/B,EAEM,GAA+D,CACnE,MAAS,CACP,QAAU,GACD,CAAC,CAAC,EAAK,MAEhB,iBAAkB,EACpB,EACA,gBAAiB,CACf,QAAU,GACD,CAAC,CAAC,EAAK,MAEhB,iBAAkB,EACpB,EACA,MAAS,CACP,QAAU,GACD,CAAC,CAAC,EAAK,MAAM,IAAM,CAAC,CAAC,EAAK,MAEnC,iBAAkB,EACpB,EACA,iBAAkB,CAChB,QAAU,GACD,CAAC,CAAC,EAAK,MAAM,IAAM,CAAC,CAAC,EAAK,MAEnC,iBAAkB,EACpB,EACA,WAAc,CACZ,QAAU,GACD,CAAC,CAAC,EAAK,MAEhB,iBAAkB,EACpB,CACF,EAEM,GAA+D,CACnE,MAAS,GAA2B,MACpC,MAAS,GAA2B,MACpC,gBAAiB,GAA2B,aAC5C,iBAAkB,GAA2B,cAC7C,WAAc,GAA2B,OAC3C,EAEA,SAAgB,GAAyB,EAAuC,CAC9E,GAAM,CAAE,YAAY,IAAS,EAE7B,SAAS,EAAI,EAAe,EAA8C,CACxE,GAAI,CAAC,EACH,OAEF,IAAM,EAAgB,GAAc,EAAK,MAEzC,GAAI,CAAC,EAAc,QAAQ,CAAI,EAC7B,OAEF,IAAM,EAAmB,EAAgB,aACvC,EAAQ,iBACR,CACE,EAAc,iBACd,CAAE,WAAY,GAAkB,EAAK,KAAM,EAC3C,CACF,CACF,EAEM,EAAe,GAAa,KAAK,EAAM,CAAE,QAAS,aAAc,QAAS,wBAAyB,CAAC,EAEzG,EAAgB,cAAc,EAAc,CAAgB,CAC9D,CAEA,MAAO,CACL,KACF,CACF,CC3IA,IAAa,GAAqB,CAIhC,uBAAwB,EAKxB,mBAAoB,IAKpB,iBAAkB,EACf,EAAe,OAAQ,GACvB,EAAe,QAAS,GACxB,EAAe,QAAS,EAC3B,EAKA,oBAAqB,CACnB,EAAe,QACf,EAAe,OACf,EAAe,OACf,EAAe,KACjB,CACF,ECnBM,GAAY,EAAgB,iBAAiB,uBAAS,EAE5D,SAAgB,GACd,EACA,EACA,EACsE,CAqEtE,OAjEuB,EAAS,MAAM,EAAG,IACvC,GAAmB,oBAAoB,QAAQ,EAAE,cAAc,EAC/D,GAAmB,oBAAoB,QAAQ,EAAE,cAAc,CAQrC,CAAA,CAAe,QAAQ,EAAM,IAAS,CAChE,GAAI,EAAK,iBAAmB,EAAe,OAAQ,CACjD,IAAM,EAAa,EAAK,KAAK,OAAO,GAAQ,EAAK,iBAAmB,EAAe,MAAM,EAEnF,EAAmB,EAAW,OAClC,GAAQ,GAAiB,OAAuB,EAAM,GAAW,OAAO,CAC1E,EAEM,EAAkB,EAAW,OACjC,GAAe,GAAM,KAAO,QAAe,OAAO,EAAK,MAAS,QAClE,EAEA,GAAI,EAAiB,OAAQ,CAK3B,IAAM,EAA2C,CAAC,EAC5C,EAA0C,CAAC,EAEjD,EAAiB,QAAQ,GAAS,CAChC,GAAI,GAAO,MAAM,YAAY,IAAM,EAAM,YAAY,EAAG,CACtD,EAAW,KAAK,CAAK,EACrB,MACF,CAEA,EAAU,KAAK,CAAK,CACtB,CAAC,EAED,EAAW,MAAM,EAAG,IAAM,GAAa,oBAAoB,EAAG,EAAG,CAAsB,CAAC,EACxF,EAAU,MAAM,EAAG,IAAM,GAAa,oBAAoB,EAAG,EAAG,CAAsB,CAAC,EAEvF,EAAK,KAAK,CACR,KAAM,CACJ,GAAG,EACH,GAAG,CACL,EACA,eAAgB,EAAe,OAC/B,MAAO,GAAU,2BAA2B,CAC9C,CAAC,CACH,CAEI,EAAgB,QAClB,EAAK,KAAK,CACR,KAAM,EACN,eAAgB,EAAe,MACjC,CAAC,CAEL,MACE,EAAK,KAAK,CAAI,EAGhB,OAAO,CACT,EAAG,CAAC,CAEG,CACT,CAOA,SAAgB,GAAwB,EAA+B,CACrE,IAAM,EAAuB,EAAS,YAAY,QAAQ,EAAM,KAC9D,EAAK,KAAK,CAAE,KAAM,CAAK,CAAC,EACjB,GACN,CAAC,CAAiB,EAOrB,MAAO,CAJL,GAAG,EAAS,OAAO,MAAM,EAAG,CAAC,EAC7B,GAAG,EAAqB,MAAM,EAAG,CAAC,CAG7B,CACT,wQEjEM,GAAoB,GAAmB,uBAGvC,GAAY,EAAgB,iBAAiB,wBAAS,EAgB5D,SAAgB,GAAgB,EAAoC,CAClE,GAAM,CAAE,EAAgB,GAAA,EAA4B,SAAS,EAAK,EAE5D,EAAA,EAA+B,OAAO,CAAC,EAEvC,CACJ,QACA,eACA,eACA,iBACA,iBACA,kBACA,qBACA,yBACA,uBACA,6BACA,yBACA,WACA,gBACA,qBACA,qBACA,uBACA,yBACA,4BACA,8BACE,GAAiB,CACnB,kBAAmB,EAAM,kBACzB,gBAAiB,EAAM,gBACvB,6BAA8B,GAAmB,mBACjD,QAAS,EAAM,QACf,OAAQ,EAAM,OACd,aAAc,EAAM,oBACpB,eAAgB,EAChB,mBAAoB,EAAM,mBAC1B,cAAe,EACjB,CAAC,EAEK,EAAW,GAAY,CAC3B,YAAa,CACf,CAAC,EAEK,CAAE,OAAQ,GAAyB,CACvC,iBAAkB,CAChB,WAAY,EAAW,OACvB,OAAQ,EAAW,iBACnB,SAAU,EAAgB,SAC5B,CACF,CAAC,EAED,SAAS,EAAiB,EAAe,EAAoC,CAC3E,IAAI,EAAqB,CACvB,OACF,EAYA,OATI,EAAe,cAAgB,EAAY,QAC7C,EAAe,SAAW,EAAQ,OAAO,MACzC,OAAO,GAAgB,QAAW,WAClC,EAAS,CACP,GAAG,GAAa,KAAK,EAAe,OAAQ,CAAE,GAA8B,EAAgB,CAAC,EAC7F,OACF,GAGK,CACL,YAAa,EAAY,OACzB,OAAQ,EAAQ,OAAO,KACvB,OAAQ,CACN,GAAG,EACH,GAAG,GAAa,KAAK,EAAS,CAAC,EAAe,CAAC,CACjD,CACF,CACF,CAEA,eAAe,GACb,EACA,EACA,EACA,CAKA,GAHA,EAAc,MAAM,EAGhB,EAAW,iBAAmB,EAAe,QAC/C,EAAM,mBAAmB,GACzB,EAAE,QAAS,GAAS,EAAM,OAAS,WAAa,EAAM,MAAQ,SAC9D,CACA,EAAI,CACF,KAAM,gBACN,MAAO,EAAW,KAClB,WAAY,CACd,EAAG,CACD,cAAe,EAAc,OAC/B,CAAC,EACD,EAAc,OAAO,EACrB,MACF,CAEA,GAAI,GAAiB,OAAuB,EAAY,GAAW,OAAO,EAAG,CAC3E,IAAM,EAAQ,GAAa,MAAM,CAAU,EACvC,EAAW,iBAAmB,EAAe,OAC/C,EAAI,CACF,KAAM,iBACN,MAAO,EAAW,KAClB,WAAY,EACZ,MAAO,CACL,GAAI,EAAW,EACjB,CACF,CAAC,EAGC,EAAW,iBAAmB,EAAe,QAC/C,EAAI,CACF,KAAM,QACN,MAAO,EAAW,KAClB,WAAY,EACZ,MAAO,CACL,GAAI,EAAW,EACjB,CACF,CAAC,EAUH,GAAkB,aAAa,EAC/B,EAAmB,QACjB,GAA4B,WAAW,EAAY,CAAE,YAAa,CAAM,EAAG,CAAsB,CACnG,EAEA,EAAqB,SAAS,aAAa,EAC3C,EAAM,KAAK,EAEX,MACF,CAEA,IAAI,EAAU,EAAW,QACrB,CAAC,GAAW,EAAS,YACvB,EAAU,EAAS,QAGrB,EAAqB,EAAW,KAAM,CAAO,EAEzC,EAAW,iBAAmB,EAAe,QAC/C,EAAI,CACF,KAAM,aACN,MAAO,EAAW,KAClB,WAAY,CACd,EAAG,CACD,cAAe,EAAc,KAC/B,CAAC,EAGC,EAAW,iBAAmB,EAAe,QAC/C,EAAI,CACF,KAAM,gBACN,MAAO,EAAW,KAClB,WAAY,CACd,EAAG,CACD,cAAe,EAAc,IAC/B,CAAC,EAGH,EAAmB,QAAQ,EAAiB,EAAW,KAAM,CAAO,CAAC,EAErE,EAAc,MAAM,CAGtB,CAEA,SAAS,EAAgB,EAAoC,CAQ3D,OAPI,GAAY,iBAAmB,EAAe,OAG9C,CAAC,GAAiB,OAAuB,EAAY,GAAW,OAAO,EAClE,EAGF,EAA0B,GAAY,gBAAgB,SAAS,CAAC,CACzE,CAEA,SAAS,EACP,EACA,EACa,CACb,OACE,EAAA,EAAA,IAAA,CAAC,GAAD,CACS,QACK,aACZ,cAAe,EAAO,cACtB,mBAAoB,EAAgB,CAAU,EAC9C,mBAAoB,EAAuB,OAC3C,mBAAoB,GAAS,EAAmB,EAAO,EAAW,OAAO,CAC1E,CAAA,CAEL,CAEA,SAAS,GAAe,EAAwB,CAG9C,GAFA,EAAM,eAAe,EAEjB,CAAC,GAAS,CAAC,EAAM,OACnB,OAEF,EAAqB,SAAS,WAAW,CAAK,EAE9C,IAAM,EAAe,GAAe,gBAAgB,CAAC,CAAC,QAEpD,EAAa,cAAgB,EAAY,QACzC,EAAa,SAAW,EAAQ,OAAO,KAUvC,EAAuB,UAFvB,EAAuB,QAAU,EAKnC,EAAI,CACF,KAAM,QACN,QACA,WAAY,EACZ,uBAAwB,EAAuB,OACjD,EAAG,CACD,cAAe,EAAc,KAC/B,CAAC,EACD,EAAmB,QAAQ,EAAiB,EAAO,EAAS,MAAM,CAAC,EAEnE,EAAqB,EAAO,EAAS,MAAM,EAC3C,EAAqB,QAAQ,UAAU,CACzC,CAEA,SAAS,GAAoB,EAAkF,CAC7G,GAAI,CAAC,EAAW,OAAQ,CACtB,EAAkB,EAAK,EACvB,MACF,CAEA,EAAkB,EAAI,CACxB,CAEA,SAAS,IAAoB,CAC3B,EAAS,QAAQ,EACjB,EAAqB,QAAQ,WAAW,CAC1C,CAEA,IAAM,GAAuB,GAAmB,EAE1C,EAA0B,EAAM,gBAAkB,CAAC,EAEzD,OACE,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,CACG,EAAM,kBACL,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,IAAK,GACL,QAAS,EAAM,aACf,UAAU,wBACX,CAAA,GAEH,EAAA,EAAA,KAAA,CAAC,OAAD,CACE,UAAW,EACT,GAAG,GAAO,UAAU,qEACpB,EAAkB,GAAO,MAAQ,EACnC,EACA,SAAU,GACV,KAAK,kBANP,EAQE,EAAA,EAAA,IAAA,CAAC,EAAD,CACE,IAAK,GACL,UAAU,6BACX,CAAA,EACA,IACC,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,iBACb,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,KAAM,EACN,GAAI,KACJ,YAAa,KACb,gBAAiB,EAAgB,SAClC,CAAA,CACE,CAAA,EAGN,EAAS,YACR,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,wBAAwB,IAAK,EAAS,2BACnD,EAAA,EAAA,IAAA,CAAC,GAAD,CAAa,KAAM,EAAS,KAAK,IAAO,CAAA,CACrC,CAAA,GAEP,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,iDACb,EAAA,EAAA,IAAA,CAAC,GAAD,CAEE,aAAc,GACd,oBAAqB,GACrB,4BAA6B,GAC7B,gBAAiB,GAAmB,iBACpC,iBAAkB,GAClB,aAAc,EAAM,kBACpB,iCAAkC,GAClC,wBAAyB,EACL,qBACpB,mBAAoB,GAEpB,mBAAoB,GAAO,OAAS,GAAK,EAAS,UAGlD,YAAa,GAAU,aAAa,EACpC,mBAAoB,GAAU,oBAAoB,EAClD,oBAAqB,GAAU,qBAAqB,EAEtC,eACE,iBACS,0BACzB,yBAA0B,CAAC,CAAc,EAEzC,eAAgB,EAAM,UAGtB,cAAe,EACS,yBACC,2BACH,wBACD,uBACG,yBACxB,8BAA+B,EAC/B,kBAAmB,GAAY,GAAkB,EAAO,EAAwB,CAAQ,EACrE,qBACnB,8BAA+B,GACzB,EAAW,iBAAmB,EAAe,QAG7C,EAAW,iBAAmB,EAAe,QACjD,CAAC,GAAiB,OAAO,EAAY,GAAW,OAAO,GAKzD,MAAO,CACL,UAAW,gCACX,qBAAsB,EAAW,oBAAqB,CAAC,IAAwB,QAAQ,EACvF,yBAA0B,EACxB,kBACA,GAAO,yBACP,EAAM,iBAAmB,GAAO,qCAClC,EAEA,sBAAuB,+BACvB,iBAAkB,GAClB,MAAO,EAAW,gCAAiC,GAA0B,YAAa,CAAC,EAAS,WAAa,MAAM,EACvH,WAAY,eACd,EACA,oBAAqB,EAAS,KAC5B,EAAA,EAAA,IAAA,CAAC,GAAD,CACW,UACT,UAAW,EACX,aAAc,CACf,CAAA,EAEH,WAAc,CACZ,EAAc,MAAM,CACtB,EACA,YAAe,EAAc,OAAO,EAEpC,YAAa,EACb,qBAAsB,CACpB,WAAY,IAAS,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,GAAI,EAAO,UAAW,OAAO,GAAO,oBAA2B,CAAA,EACzF,WAAY,GACZ,cAAe,EACf,cAAe,EACf,MAAO,CACL,SAAU,eACV,MAAO,EACT,CACF,CACD,CAAA,CACE,CAAA,CACD,GACN,CAAA,CAAA,CAEN,sJE7ZA,SAAgB,GAAkB,EAA4C,CAC5E,GAAM,CAAE,oBAAmB,4BAA2B,gCAAiC,EAEjF,EAAA,EAA4B,OAAuB,IAAI,EAEvD,CAAE,sBAAuB,GAAsB,EAC/C,CAAE,gBAAiB,GAA0B,EAE7C,CAAE,kBAAmB,GAAe,EACpC,EAAU,EAAe,EAAe,eAAe,EAEvD,EAAc,EAAkC,EAAa,YAAY,CAAC,EAE1E,EAAiB,GAAoB,GAErC,EAAyB,EAC7B,GAAkB,GAAe,eAAe,CAAc,CAChE,EAGM,EAAoB,EAAY,MAAM,gBAC1C,GAAc,oCACd,GAAc,6BAUhB,OAPE,EAAY,aACZ,GAOA,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,GAAG,GAAO,mBAAmB,GAAG,EAA4B,OAAS,GAAG,GAAG,EAAoB,SAAW,sBACxH,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,aAAa,GAAO,iBAAiB,GAAG,EAA4B,cAAgB,eAClG,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,GAAG,GAAO,iBAAiB,wCAAyC,IAAK,YACvF,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,eAAgB,EAAuB,MAAM,eAC7C,gBAAiB,oBAAoB,EAAY,MAAM,IAAM,WAC1C,oBACnB,gBAAiB,EACjB,iBAAoB,EAA6B,EAAK,EACtD,UAAW,EACX,QAAS,EAAM,QACf,OAAQ,EAAM,OACO,sBACrB,mBAAoB,EACpB,iBAAkB,EAAM,gBACzB,CAAA,CACE,CAAA,CACF,CAAA,CACF,CAAA,GArBE,EAAA,EAAA,IAAA,CAAA,EAAA,SAAA,CAAI,CAAA,CAuBf,CCzDA,IAAM,GAAY,EAAgB,iBAAiB,mBAAS,EAE5D,SAAgB,IAAiD,CAC/D,IAAM,EAAc,EAAkC,EAAa,YAAY,CAAC,EAE1E,CAAE,WAAU,UAAW,GAAgB,EAEvC,EAAuB,CAC3B,YAAa,EAAY,QACzB,OAAQ,EAAQ,OAAO,OACzB,EAEM,EAAuB,CAC3B,YAAa,EAAY,QACzB,OAAQ,EAAQ,QAAQ,SAC1B,EAEM,EAAA,EAAoC,kBAAkB,EAUtD,EAAkC,CAAC,EAAY,MAAM,iBACtD,GAAgB,cAAgB,EAAY,YAC3C,GAAgB,SAAW,EAAQ,UAAU,MAAQ,GAAgB,SAAW,EAAQ,UAAU,UAElG,EAAkB,EACtB,CAAE,GAAG,EAAgB,KAAM,CAAE,KAAM,IAAI,EAAe,MAAQ,CAAC,EAAA,CAAG,MAAM,CAAC,CAAE,CAAC,EAC5E,EAEI,EAAA,EAAiC,QAAQ,CAAe,EAW9D,OATI,IAAgB,MAClB,EAAO,OAAS,CAAE,aAAY,GAK5B,IACF,EAAO,OAAS,CAAE,aAAY,GAEzB,CACL,SACA,SACA,QAAS,CACP,YAAa,EAAY,QACzB,OAAQ,EAAQ,QAAQ,QACxB,OAAQ,EAAW,CAAE,YAAa,GAAU,WAAW,iBAAkB,CAAM,CAAE,EAAI,IACvF,CACF,CACF,CAEA,SAAS,GAAiB,EAA+B,CACvD,GAAM,CAAE,EAAyB,GAAA,EAAqC,SAAiB,EAEjF,EAAsB,GAC1B,EAAuB,GAAe,aAAe,IACvD,EAEM,EAAoB,GAAqB,yBAAyB,EAMxE,OAJA,GAAY,EAAmB,qBAAuB,GAAsB,CAC1E,EAA2B,EAAM,IAAI,aAAa,CAAC,CACrD,CAAC,EAEM,CACL,0BACA,0BAA6B,GAAqB,sBAAsB,CAC1E,CACF,CAEA,SAAgB,GAAuB,CACrC,OACA,UAIoB,CACpB,GAAM,CAAE,kBAAmB,GAAe,EACpC,EAAkB,GAAyB,GAAM,YAAc,EAAE,EACjE,CAAE,kBAAiB,iBAAkB,GAAY,IAAI,EACrD,EAAW,GAAc,GAAkB,MAAM,EAEjD,CACJ,0BACA,yBACE,GAAiB,EAAe,EAAe,iBAAiB,CAAC,EAE/D,EAAU,EAAe,EAAe,eAAe,EAE7D,GAAI,CAAC,GAAQ,CAAC,GAAU,EACtB,MAAO,CAAC,EAEV,IAAM,EAA2B,CAAC,EAoIlC,OAlIA,EAAM,KAAK,CACT,MAAO,GAAU,UAAU,EAC3B,MAAO,GACP,QAAS,CACP,YAAa,EAAY,SACzB,OAAQ,EAAQ,SAAS,IAC3B,EACA,cAAe,CACb,IAAA,EAAwB,QAAQ,CAC9B,YAAa,EAAY,SACzB,OAAQ,EAAQ,SAAS,IAC3B,CAAC,CACH,EACA,iBAAkB,CAChB,SAAU,EAAgB,YAC1B,WAAY,EAAW,MACvB,OAAQ,EAAW,GACrB,CACF,CAAC,EAEG,EAAe,EAAe,gBAAgB,GAChD,EAAM,KAAK,CACT,MAAO,GAAU,cAAc,EAC/B,MAAO,EACP,QAAS,CACP,YAAa,EAAY,cACzB,OAAQ,EAAQ,aAAa,IAC/B,EACA,cAAe,CACb,IAAA,EAAwB,QAAQ,CAC9B,YAAa,EAAY,cACzB,OAAQ,EAAQ,aAAa,IAC/B,CAAC,CACH,EACA,iBAAkB,CAChB,SAAU,EAAgB,YAC1B,WAAY,EAAW,MACvB,OAAQ,EAAW,GACrB,CACF,CAAC,EAID,GACA,EAAe,EAAe,mBAAmB,GAEjD,CAAC,GAED,EAAM,KAAK,CACT,MAAO,GAAU,iBAAiB,EAClC,MAAO,EACP,QAAS,CACP,YAAa,EAAY,QACzB,OAAQ,EAAQ,OAAO,gBACzB,CACF,CAAC,EAGC,CAAC,EAAe,EAAe,iBAAiB,GAAK,EAAe,EAAe,YAAY,GACjG,EAAM,KACJ,CACE,MAAO,GAAU,cAAc,EAC/B,MAAO,EACP,QAAS,CACP,YAAa,EAAY,UACzB,OAAQ,EAAQ,SAAS,cAC3B,EACA,cAAe,CACb,IAAA,EAAwB,QAAQ,CAC9B,YAAa,EAAY,UACzB,OAAQ,EAAQ,SAAS,cAC3B,CAAC,CACH,EACA,iBAAkB,CAChB,SAAU,EAAgB,YAC1B,WAAY,EAAW,MACvB,OAAQ,EAAW,GACrB,CACF,CACF,EAGE,GAAY,EAAe,EAAe,iBAAiB,GAC7D,EAAM,KAAK,CACT,MAAO,GAAU,eAAe,EAChC,MAAO,GACP,QAAS,EACT,QAAS,EACT,QAAS,CACP,YAAa,EAAY,cACzB,OAAQ,EAAQ,cAAc,IAChC,EACA,cAAe,CACb,IAAA,EAAwB,QAAQ,CAC9B,YAAa,EAAY,cACzB,OAAQ,EAAQ,cAAc,IAChC,CAAC,CACH,EACA,iBAAkB,CAChB,SAAU,EAAgB,YAC1B,WAAY,EAAW,MACvB,OAAQ,EAAW,GACrB,CACF,CAAC,EAGC,EAAe,EAAe,iBAAiB,GAAK,GACtD,EAAM,KACJ,CACE,MAAO,GAAU,eAAe,EAChC,MAAO,EACP,QAAS,CACP,YAAa,EAAY,UACzB,OAAQ,EAAQ,UAAU,qBAC5B,EACA,cAAe,CACb,IAAA,EAAwB,QAAQ,CAC9B,YAAa,EAAY,UACzB,OAAQ,EAAQ,UAAU,qBAC5B,CAAC,CACH,EACA,iBAAkB,CAChB,SAAU,EAAgB,YAC1B,WAAY,EAAW,MACvB,OAAQ,EAAW,GACrB,CACF,CACD,EAGI,CACT,iSEhNM,GAAY,oBACZ,GAAY,EAAgB,iBAAiB,EAAS,EAE5D,SAAS,IAAoB,CAC3B,IAAM,EAAc,GAAe,EAKnC,OAHK,GAAc,QAGZ,EAAY,IACjB,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,4BAA4B,OAAQ,GAAI,IAAK,EAAU,gBAAmB,CAAA,GACzF,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,QAAQ,IAAK,EAAU,SAAY,CAAA,EAJ3C,EAAY,IAAK,EAAA,EAAA,IAAA,CAAC,GAAD,CAAoB,CAAA,GAAI,EAAA,EAAA,IAAA,CAAC,GAAD,CAAgB,CAAA,CAKpE,CAQA,SAAS,GAAY,EAA+B,CAClD,IAAM,EAAU,EAAM,eAAiB,eACrC,CACE,YAAa,EAAY,aACzB,OAAQ,EAAQ,YAAY,IAC9B,EAAI,CACF,YAAa,EAAY,UACzB,OAAQ,EAAQ,UAAU,KAC1B,KAAM,CAAC,EAAM,gBAAgB,CAC/B,EAEF,OACE,EAAA,EAAA,IAAA,CAAC,EAAD,CACE,UAAW,GAAU,MAAM,EAC3B,QAAS,EAAa,qBAAqB,EAAI,EAAU,IAAA,GACzD,cAAe,EAAM,WAAa,OAClC,UAAW,oCAAoC,GAAO,KAAK,oBAC3D,cAAe,CACb,IAAA,EAAwB,QAAQ,CAAO,CACzC,EACA,iBAAkB,CAChB,WAAY,EAAW,MACvB,OAAQ,EAAW,IACnB,SAAU,EAAgB,OAC1B,WAAY,EAAgB,aAC9B,YAEA,EAAA,EAAA,IAAA,CAAC,GAAD,CAAO,CAAA,CACA,CAAA,CAEb,CAYA,SAAgB,GAAW,EAA4C,CACrE,GAAM,CAAE,EAA2B,GAAA,EAAuC,SAAS,EAAK,EAClF,CAAE,eAAgB,GAAkB,EACpC,EAAA,EAAe,OAAuB,IAAI,EAE1C,CAAE,kBAAmB,GAAe,EAEpC,EAAS,EAA6B,GAAe,OAAO,CAAC,EAC7D,EAAc,EAAkC,EAAa,YAAY,CAAC,EAC1E,CAAE,iBAAgB,iBAAkB,GAAY,IAAI,EAEpD,EAAc,GAAe,EAE7B,EAAsB,GAA0B,EAChD,EAAmB,GAAuB,CAC9C,KAAM,GAAa,KACnB,OAAS,EAAO,IAClB,CAAC,EAEK,CAAE,YAAa,GAAgB,EAC/B,CAAE,WAAU,eAAc,mBAAoB,GAAa,KAAM,EAAgB,YAAY,EAE7F,EAAa,GAAc,EAC3B,EAAU,EAAe,EAAe,eAAe,EAWvD,EACJ,EAAY,MAAM,iBAClB,CAAC,EAAe,EAAe,iBAAiB,GAChD,CAAC,EAEG,CAAE,iBAAkB,GAA4B,GAAsB,iBAAiB,EAE7F,EAAM,cAAgB,CAChB,CAAC,EAAY,IAAM,CAAC,EAAY,IAAM,CAAC,EAAY,IAAM,CAAC,GAAgB,GAC5E,EAA6B,EAAK,CACtC,EAAG,CAAE,EAAa,CAA0B,CAAC,EAK7C,EAAM,cAAgB,CACf,GAGL,EAA6B,EAAI,CACnC,EAAG,CAAC,CAAW,CAAC,EAIhB,SAAS,EAAsB,EAAgC,CAC7D,IAAI,EAAS,EAab,OAZI,IACF,EAAS,EAAO,OAAO,GAAK,EAAE,KAAO,GAAU,kBAAkB,GAE/D,GAAc,CAAC,EAAe,EAAe,mBAAmB,IAClE,EAAS,EAAO,OAAO,GAAK,EAAE,KAAO,GAAU,SAAS,GAKtD,GAAkB,CAAC,EAAe,EAAe,mBAAmB,IACtE,EAAS,EAAO,OAAO,GAAK,EAAE,KAAO,GAAU,SAAS,GAEnD,CACT,CAEA,IAAM,EAAW,EAAY,IAAM,EAAY,GACzC,EAAoB,EAAe,EAAe,iBAAiB,GACvE,EAAM,SAAW,CAAC,GAAY,CAAC,EAE3B,GAAa,EAAe,EAAe,WAAW,GAAK,CAAC,GAAY,EAAM,SAAW,CAAC,EAC1F,EAAa,EAAM,YAAc,EAAe,EAAe,UAAU,EACzE,EAAmB,EAAe,EAAe,iBAAiB,EACtE,eACA,WAEI,IAAqB,GAAgB,GAAY,EAAY,KAAO,CAAC,EAMrE,GAAe,CAAC,EAAY,MAAM,iBAAmB,CAAC,GAAgB,gBAAgB,GAAK,CAAC,EAAM,QACtG,OACA,OAEF,OACE,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAa,CAAA,GACb,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,qCAAqC,GAAO,gBAC1D,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,kBAAkB,IAAK,WAAtC,CACG,CAAC,IACA,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,mDAAmD,GAAO,sBAA1E,CACG,EAAM,UACP,EAAA,EAAA,IAAA,CAAC,SAAD,CACE,QAAS,EAAM,cACf,UAAU,YACV,aAAY,GAAU,EAAM,SAAW,SAAW,UAAU,YAE5D,EAAA,EAAA,IAAA,CAAC,EAAD,CACE,IAAK,GACL,UAAW,GAAG,GAAO,WACtB,CAAA,CACK,CAAA,GAER,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,SAAU,GACV,aAAc,EACd,iBAAkB,EAAM,gBACzB,CAAA,EACA,IACC,EAAA,EAAA,IAAA,CAAC,IAAD,CACE,UAAW,EAAW,MAAO,GAAO,SAAU,EAAY,MAAM,gBAAkB,WAAa,kBAAkB,EACjH,KAAM,EACN,QAAS,YAET,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,QAAU,CAAA,CAC5C,CAAA,CAEF,IAGN,IACC,EAAA,EAAA,IAAA,CAAC,GAAD,CACqB,qBACQ,4BAC3B,6BAA+B,GAAiB,EAA6B,CAAG,EAChF,QAAS,EAAM,QACP,SACR,iBAAkB,EAAM,gBACzB,CAAA,EAGF,CAAC,IACA,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,wEAAf,CACG,GAAc,KACb,EAAA,EAAA,IAAA,CAAC,GAAD,CAAW,YAAe,EAA6B,EAAI,YACzD,EAAA,EAAA,IAAA,CAAC,EAAD,CAAc,IAAK,GAAW,KAAM,EAAiB,MAAO,MAAO,GAAU,QAAQ,EAAG,iBAAiB,OAAO,gBAAA,EAAiB,CAAA,CACxH,CAAA,EAGZ,KACC,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,eAAgB,GAChB,UAAW,EAAe,EAAe,WAAW,CACrD,CAAA,EAEF,IACD,EAAA,EAAA,IAAA,CAAC,EAAD,CAAS,MAAO,GAAU,eAAe,EAAG,SAAA,GAAS,UAAU,iBAC7D,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,KAAM,GACN,QAAS,CAAE,QAAS,EAAK,CAC1B,CAAA,CACM,CAAA,EAGR,IACC,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,8BACb,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,IAAK,GACL,QAAS,EAAW,EAAiB,MAAQ,EAAiB,SAC9D,UAAW,OAAO,EAAW,WAAa,mBAAmB,GAC7D,QAAS,CAAE,YAAa,EAAY,QAAS,OAAQ,EAAQ,QAAQ,aAAc,WAElF,CAAC,IAAY,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,cAAgB,CAAA,CACvD,CAAA,CACT,CAAA,EAGN,GAmBA,CAAC,CAAC,EAAO,OACR,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,oBAAoB,IAAK,GAAM,EAAwB,CAAE,YACtE,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,UAAW,GAAU,QACrB,SAAU,EACV,gBAAiB,EACjB,gBAAiB,EACjB,UAAW,EAEX,aAAc,EACd,cAAA,EACD,CAAA,CACE,CAAA,CAEJ,GAEJ,GAEF,CAAA,CACL,CAAA,CAAA,CAEN,wMEzTM,GAAY,EAAgB,iBAAiB,qBAAS,EAW5D,SAAgB,GAAqB,EAA+C,CAClF,IAAM,EAAgB,EAAM,UAAY,GAAW,GAEnD,SAAS,GAA2B,CAC7B,EAAM,aACX,EAAc,SAAS,EAAM,WAAY,EAAI,EAC7C,EAAM,MAAM,CACV,KAAM,8BACN,QAAS,cACX,CAAC,EACH,CAEA,IAAM,EAAW,EAAM,UAAY,GAC7B,EAA0B,GAAiC,wBAC/D,EACA,EAAM,WACN,EACF,EAEA,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,EACd,GAAO,cACP,kCACA,EAAM,WAAa,gCACnB,EAAM,SACR,WALA,CAMG,IACC,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,IAAK,GACL,QAAS,EAAiB,SAC1B,UAAU,4CACV,QAAS,EACT,UAAW,GAAU,aAAa,EAClC,KAAK,SACL,QAAS,GAAU,aAAa,EAChC,eAAgB,CAAE,QAAS,OAAQ,CACpC,CAAA,EAEF,EAAS,SAAS,GAAyB,SAAS,IACnD,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,IAAK,EACL,QAAS,EAAiB,SAC1B,UAAU,4CACV,QAAS,EAAM,gBACf,UAAW,EAAM,UAAY,GAAU,OAAO,EAAI,GAAU,MAAM,EAClE,KAAK,SACL,QAAS,EAAM,UAAY,GAAU,OAAO,EAAI,GAAU,MAAM,EAChE,eAAgB,CAAE,QAAS,OAAQ,CACpC,CAAA,CAEA,GAET,CCtEA,IAAM,GAAY,sBACZ,GAAY,EAAgB,iBAAiB,EAAS,EAS5D,SAAgB,GAAsB,EAAmC,CACvE,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,EACd,kFACA,GAAO,gBACP,GAAO,QACP,EAAM,SACR,WALA,EAME,EAAA,EAAA,IAAA,CAAC,KAAD,CAAA,SAAK,GAAU,QAAQ,CAAM,CAAA,GAC7B,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,0BAAf,EACE,EAAA,EAAA,IAAA,CAAC,EAAD,CACa,UAAA,GACX,OAAO,SACR,CAAA,EAAC,QAEF,EAAA,EAAA,IAAA,CAAC,EAAD,CAAS,QAAS,EAAM,WAAa,EAAM,WAAa,EAAM,QAAS,IAAI,IAAI,UAAU,qBACvF,EAAA,EAAA,IAAA,CAAC,IAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAAC,EAAD,CACa,UAAA,GACX,OAAO,cACP,QAAS,CAAE,QAAS,WAAY,CACjC,CAAA,CACA,CAAA,CACI,CAAA,CACN,KACL,EAAA,EAAA,IAAA,CAAC,EAAD,CAAS,UAAU,eAAe,QAAS,EAAM,oBAC9C,EAAM,WAAa,GAAU,YAAY,EAAI,GAAU,eAAe,CAChE,CAAA,CACN,GAET,CCrCA,SAAgB,GAAkB,EAA4C,CAC5E,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAW,8DAA+D,GAAO,kBAAmB,EAAM,SAAS,YACjI,EAAA,EAAA,IAAA,CAAC,GAAD,CAAO,IAAK,EAAM,SAAU,SAAA,GAAS,MAAA,GAAM,SAAU,GAAO,KAAM,GAAM,UAAU,2DAChF,EAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,IAAK,EAAM,SAAU,KAAK,WAAa,CAAA,CAC1C,CAAA,CACJ,CAAA,CAET,CCEA,SAAgB,GAAa,EAA0B,CACrD,GAAM,CACJ,WACA,YACA,aACA,SACA,mBACE,GAAiB,CACnB,eAAgB,GAClB,CAAC,EAEK,EAAsC,CAC1C,gBAAiB,QAAQ,EAAM,SAAS,IACxC,eAAgB,QAChB,mBAAoB,aACpB,OAAQ,QACR,MAAO,MACT,EAIM,EAFiB,GAAU,CAAC,EAGhC,GACA,CAAC,GAAyB,SAAS,EAErC,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAM,oBACpB,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,qBAAqB,GAAO,kBAAkB,GAAG,GAAO,qBAAxE,EACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAA6B,WAAU,SAAU,EAAM,QAAU,CAAA,GAC/D,CAAC,GAAU,CAAC,KAAc,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,GAAG,GAAO,kBAAkB,oBAAqB,MAAO,CAAqB,CAAA,GACzH,EAAA,EAAA,IAAA,CAAC,GAAD,CAAuB,QAAS,EAAM,QAAS,WAAY,EAAM,WAAY,UAAU,OAAO,WAAY,EAAM,UAAY,CAAA,EAC3H,EAAM,UAAY,IACjB,EAAA,EAAA,IAAA,CAAC,GAAD,CACa,YACM,kBACP,UACX,CAAA,CACA,GACF,CAAA,CAET,CChEA,IAAY,GAAL,SAAA,EAAA,OACL,GAAA,EAAA,UAAA,GAAA,YACA,EAAA,EAAA,cAAA,GAAA,iBACF,EAAA,CAAA,CAAA,8JEOA,SAAgB,GAAc,EAAuC,CACnE,GAAI,EAAM,WACR,OAAO,EAAA,EAAA,IAAA,CAAA,EAAA,SAAA,CAAI,CAAA,EAEb,OAAQ,EAAM,KAAd,CACE,IAAK,OACH,GAAM,CAAE,cAAa,YAAW,QAAS,EACzC,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EACd,gBACA,EACA,EAAY,iBAAmB,SACjC,YACE,EAAA,EAAA,IAAA,CAAC,EAAD,CAAM,CAAA,CACH,CAAA,EAET,IAAK,eACH,IAAM,EAAwB,KAAK,IAAI,EAAM,MAAQ,EAAM,SAAW,IAAK,CAAC,EACtE,EAAU,EAAA,GAAwC,WAAa,YAErE,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAW,GAAO,YAAa,qEAAqE,YAClH,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAW,qCAAsC,GAAO,UAAU,YAChF,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAW,0BAA2B,CAAO,EAAG,MAAO,CAAE,MAAO,GAAG,EAAsB,EAAG,CAAI,CAAA,CAC7G,CAAA,CACF,CAAA,EAET,IAAK,YACH,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,qEACZ,EAAM,QACJ,CAAA,CAEX,CACF,CCjBA,SAAS,GAAI,EAAiB,CAC5B,OACE,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,UAAW,EAAM,UACjB,iBAAkB,EAAM,iBACxB,cAAe,EAAM,cACrB,QAAS,EAAM,QACf,QAAS,EAAM,QACf,IAAK,EAAM,IACX,SAAU,EAAM,kBAEf,EAAM,IACK,CAAA,CAElB,CAMA,SAAS,GAAoB,EAA8C,CAUzE,OATI,EAAM,YAGN,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,GAAG,GAAO,aAAa,gBACpC,EAAM,QACJ,CAAA,GAKP,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,GAAG,GAAO,aAAa,GAAG,GAAO,iBAAiB,iBAChE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,6BACZ,EAAM,QACJ,CAAA,CACF,CAAA,CAET,CA6BA,SAAgB,GAAa,EAA0B,CACrD,GAAM,CACJ,YACA,cACA,eAEA,0BACA,uBACA,iBACA,cACA,mBACA,iBACA,cACA,kBAEA,yBACA,4BACA,mBACA,gBACA,qBACA,mBAEA,eACA,aACA,YACE,EAEJ,OACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAiC,uBAC/B,EAAA,EAAA,KAAA,CAAC,MAAD,CACE,UAAW,EACT,+EACA,EACA,EACA,CACF,WANF,EAQE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,2DAAf,EACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAe,GAAI,CAAQ,CAAA,GAC3B,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,2BAA2B,wBAAyB,CAAE,OAAQ,CAAS,CAAI,CAAA,CACxF,KAEL,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,EAAW,gDAAiD,GAAgB,kBAAkB,WAA9G,CAEI,IACF,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,iBAAkB,EAClB,cAAe,EACf,QAAS,EACT,KAAM,EACN,UAAW,GAAsB,uBACjC,QAAS,CACV,CAAA,EAGC,IACF,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,iBAAkB,EAClB,cAAe,EACf,QAAS,EACT,KAAM,EACN,UAAW,GAAoB,eAC/B,QAAS,EACT,IAAK,EACL,SAAU,CACX,CAAA,CAEE,GACF,GACc,CAAA,CAEzB,CCrJA,IAAM,GAAY,EAAgB,iBAAiB,oBAAoB,EAEvE,SAAgB,GAAY,EAAyB,CACnD,OACE,EAAA,EAAA,IAAA,CAAC,EAAD,CAAS,MAAO,EAAM,YAAc,GAAU,aAAa,EAAI,KAAM,SAAA,aACnE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAM,oBACpB,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,QAAS,EAAM,SAAW,EAAiB,SAC3C,IAAK,GACL,YAAY,UACZ,oBAAoB,wEACrB,CAAA,CACE,CAAA,CACE,CAAA,CAEb,2CEJM,GAAY,EAAgB,iBAAiB,qBAAS,EAa5D,SAAS,GAAoC,EAAmC,CAC9E,OAAQ,EAAR,CACE,KAAK,GAAY,UAAW,MAAO,kBACnC,KAAK,GAAY,cAAe,MAAO,iBACvC,QAAS,MAAO,gBAClB,CACF,CAEA,SAAS,GAA2B,EAAmC,CACrE,OAAQ,EAAR,CACE,KAAK,GAAY,UAAW,MAAO,gBACnC,KAAK,GAAY,cAAe,MAAO,eACvC,QAAS,MAAO,cAClB,CACF,CAaA,SAAgB,GAAa,EAA0B,CACrD,GAAM,CAAE,EAAc,GAAA,EAA0B,SAAmD,MAAM,EAEnG,EAAS,GAAU,EAEnB,EACJ,EAAM,eAAe,yBAA2B,GAAiB,mBAC/D,GAAY,cACZ,GAAY,UACV,EAAc,GAAG,GAA2B,CAAY,EAAE,GAAG,EAAM,cACnE,EAAuB,GAAoC,CAAY,EAEvE,EAAiB,IAAiB,GAAY,UAAY,GAAU,SAAS,EAAI,GAAU,MAAM,EAEjG,EAAmC,CACvC,YAAa,EAAY,QACzB,OAAQ,EAAQ,QAAQ,oBACxB,KAAM,CAAC,EAAM,oBAAoB,IAAI,CACvC,EAEM,EAAc,GAAe,EAE7B,EAA8B,CAClC,WAAY,EAAW,MACvB,OAAQ,EAAW,QACnB,SAAU,EAAgB,aAC1B,WAAY,GAAuB,WACrC,EAEM,EAA6B,CACjC,WAAY,EAAW,MACvB,OAAQ,EAAW,QACnB,SAAU,EAAgB,aAC1B,WAAY,GAAuB,UACrC,EAEM,EAAgB,CACpB,qBAAsB,EAAM,oBAAoB,GAChD,wBAAyB,EAAM,oBAAoB,cACnD,uBAAwB,EAAM,eAAe,sBAC/C,EAEA,eAAe,GAAuB,CACpC,MAAM,EAAM,2BAA2B,CAAE,gBAAiB,GAAS,CAC7D,IAAU,SACZ,EAAO,MAAM,GAAU,uBAAuB,CAAC,EAEjD,EAAgB,CAAK,CACvB,CAAE,CAAC,CACL,CAEA,SAAS,GAAwB,CAC/B,IAAM,EAAyC,CAC7C,YACA,EAAM,WACJ,GAAU,iBAAiB,EAC3B,GAAU,mBAAmB,EAC/B,qBAAsB,EACtB,wBAAyB,EACzB,eAAgB,CAClB,EAcA,OAZI,IAAiB,YACnB,EAAmB,gBAAkB,GACrC,EAAmB,YAAc,GAAU,SAAS,GAGlD,IAAiB,YACnB,EAAmB,gBAAkB,GACrC,EAAmB,YAAc,GACjC,EAAmB,YAAc,GAAU,aAAa,EACxD,EAAmB,iBAAmB,EAAW,eAAgB,GAAO,UAAU,GAG7E,CACT,CAEA,IAAM,EAAqB,EAAsB,EAE3C,EAAuB,CAC3B,cACE,EAAY,IAAM,EAAY,IAAM,EAAM,WACxC,KACA,GAAU,cAAe,CACvB,QAAS,CACX,CAAC,EACL,iBAAkB,EAClB,uBAAwB,EACxB,0BAA2B,CAC7B,EAEA,SAAS,GAAkB,CAUzB,OATI,EAAM,YAAc,IAAiB,GAAY,UAC5C,wBAEL,EAAM,WACD,mBAEL,IAAiB,GAAY,cACxB,WAEF,eACT,CAEA,OACE,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,KAAK,OACL,UAAW,EAAM,UACJ,cACb,aAAc,EACd,KAAM,GACN,UAAA,GACA,aAAA,GAEA,WAAY,EAAY,GAExB,SAAU,GAAU,EAAgB,CAAC,EAErC,GAAI,EACJ,GAAI,CACL,CAAA,CAEL,sSE9JA,SAAgB,GAAa,EAA8B,CACzD,GAAM,CACJ,cACA,gBACA,qBACA,4BACA,kBACA,YACA,uBACA,8BACE,EAEE,EAAa,CAAE,GAAW,eAAgB,GAAW,YAAa,CAAC,CAAC,SAAS,GAAe,UAAU,EAEtG,EAAmC,CACvC,YAAa,EAAY,QACzB,OAAQ,EAAQ,QAAQ,oBACxB,KAAM,CAAC,GAAoB,IAAI,CACjC,EAEM,EAAkB,EAAc,UAClC,GAAe,yBAA2B,GAAiB,QAEzD,EAAiB,EACrB,EAAU,OAAO,iBACjB,EAAU,OAAO,sBAEb,EAAW,EACf,GAAU,YAAY,UACtB,IAAA,GAuCF,OArCK,EAGD,EAAY,IAEZ,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,UAAU,iBACV,cAAe,EACK,qBACpB,sBACE,EAA0B,OAAO,GAAK,EAAE,OAAS,EAAc,sBAAsB,CAAC,CAAC,GAE7E,aACU,uBACM,4BAC7B,CAAA,EAEC,IACA,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,qBAAqB,GAAO,8BAC1C,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,mBAAmB,GAAO,4BACxC,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,UAAW,GAAG,GAAO,aAAa,GAAG,GAAO,gBAClC,WACV,QAAS,EACT,WAAY,EACZ,eAAe,YACf,SAAU,EACE,YACb,CAAA,CACE,CAAA,CACF,CAAA,CAEP,CAAA,CAAA,GAKJ,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,UAAU,uBACV,cAAe,EACK,qBACpB,sBACE,EAA0B,OAAO,GAAK,EAAE,OAAS,EAAc,sBAAsB,CAAC,CAAC,GAE7E,aACU,uBACM,4BAC7B,CAAA,EAEC,IACA,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,UAAW,4BAA4B,GAAO,YACpC,WACV,QAAS,EACT,WAAY,EACZ,SAAU,EACE,YACb,CAAA,CAEH,CAAA,CAAA,EA5DK,IA8DX,CCvHA,IAAa,GAAwB,CACnC,oBAAoB,EAAqE,CAOvF,OALE,EAAmB,QAAQ,EAAkB,KAC3C,EAAK,EAAc,iBAAiB,EAAQ,OAAO,GAAK,EAAQ,SAAW,CAAC,EACrE,GACN,CAAC,CAEC,CACT,EAEA,iBAAiB,EAAkB,EAA6D,CAC9F,IAAM,EAAM,EAAc,iBAAiB,CAAO,EAElD,OAAO,IAAc,EACvB,CACF,ECLa,GAAuD,GAAsB,oBAAoB,CAC5G,CAAE,QAAS,CAAE,YAAa,EAAY,UAAW,OAAQ,EAAQ,UAAU,IAAK,CAAE,EAClF,CAAE,QAAS,CAAE,YAAa,EAAY,UAAW,OAAQ,EAAQ,UAAU,SAAU,CAAE,EACvF,CAAE,QAAS,CAAE,YAAa,EAAY,UAAW,OAAQ,EAAQ,UAAU,QAAS,CAAE,EAEtF,CAAE,QAAS,CAAE,YAAa,EAAY,SAAU,OAAQ,EAAQ,SAAS,QAAS,CAAE,EACpF,CAAE,QAAS,CAAE,YAAa,EAAY,SAAU,OAAQ,EAAQ,SAAS,cAAe,CAAE,EAE1F,CAAE,QAAS,CAAE,YAAa,EAAY,cAAe,OAAQ,EAAQ,YAAY,IAAK,CAAE,EAExF,CAAE,QAAS,CAAE,YAAa,EAAY,OAAQ,OAAQ,EAAQ,OAAO,WAAY,CAAE,EACnF,CAAE,QAAS,CAAE,YAAa,EAAY,OAAQ,OAAQ,EAAQ,OAAO,kBAAmB,CAAE,EAC1F,CAAE,QAAS,CAAE,YAAa,EAAY,OAAQ,OAAQ,EAAQ,OAAO,UAAW,CAAE,EAElF,CAAE,QAAS,CAAE,YAAa,EAAY,MAAO,OAAQ,EAAQ,MAAM,SAAU,CAAE,EAC/E,CAAE,QAAS,CAAE,YAAa,EAAY,MAAO,OAAQ,EAAQ,MAAM,UAAW,CAAE,EAChF,CAAE,QAAS,CAAE,YAAa,EAAY,MAAO,OAAQ,EAAQ,MAAM,iBAAkB,CAAE,EAEvF,CAAE,QAAS,CAAE,YAAa,EAAY,aAAc,OAAQ,EAAQ,aAAa,gBAAiB,CAAE,EAEpG,CAAE,QAAS,CAAE,YAAa,EAAY,UAAW,OAAQ,EAAQ,SAAS,SAAU,CAAE,EACtF,CAAE,QAAS,CAAE,YAAa,EAAY,UAAW,OAAQ,EAAQ,SAAS,gBAAiB,CAAE,EAE7F,CAAE,QAAS,CAAE,YAAa,EAAY,UAAW,OAAQ,EAAQ,UAAU,IAAK,CAAE,EAElF,CAAE,QAAS,CAAE,YAAa,EAAY,UAAW,OAAQ,EAAQ,SAAS,IAAK,CAAE,EAEjF,CAAE,QAAS,CAAE,YAAa,EAAY,WAAY,OAAQ,EAAQ,WAAW,IAAK,CAAE,EACpF,CAAE,QAAS,CAAE,YAAa,EAAY,WAAY,OAAQ,EAAQ,WAAW,QAAS,CAAE,EACxF,CAAE,QAAS,CAAE,YAAa,EAAY,WAAY,OAAQ,EAAQ,WAAW,eAAgB,CAAE,CACjG,CAAC,EAEY,GAAwD,GAAsB,oBAAoB,CAC7G,CACE,QAAS,CAAE,YAAa,EAAY,UAAW,OAAQ,EAAQ,UAAU,IAAK,EAC9E,QAAS,CAAE,UAAW,EAAK,CAC7B,EACA,CACE,QAAS,CAAE,YAAa,EAAY,UAAW,OAAQ,EAAQ,UAAU,SAAU,EACnF,QAAS,CAAE,UAAW,EAAK,CAC7B,EACA,CACE,QAAS,CAAE,YAAa,EAAY,UAAW,OAAQ,EAAQ,UAAU,QAAS,EAClF,QAAS,CAAE,UAAW,EAAK,CAC7B,EACA,CACE,QAAS,CAAE,YAAa,EAAY,UAAW,OAAQ,EAAQ,UAAU,QAAS,EAClF,QAAS,CAAE,UAAW,EAAK,CAC7B,EAEA,CACE,QAAS,CAAE,YAAa,EAAY,SAAU,OAAQ,EAAQ,SAAS,QAAS,EAChF,QAAS,CAAE,UAAW,EAAM,CAC9B,EACA,CACE,QAAS,CAAE,YAAa,EAAY,SAAU,OAAQ,EAAQ,SAAS,cAAe,EACtF,QAAS,CAAE,UAAW,EAAM,CAC9B,EACA,CACE,QAAS,CAAE,YAAa,EAAY,SAAU,OAAQ,EAAQ,SAAS,kBAAmB,EAC1F,QAAS,CAAE,UAAW,EAAM,CAC9B,EAEA,CACE,QAAS,CAAE,YAAa,EAAY,cAAe,OAAQ,EAAQ,YAAY,IAAK,EACpF,QAAS,CAAE,UAAW,EAAM,CAC9B,EACA,CACE,QAAS,CAAE,YAAa,EAAY,cAAe,OAAQ,EAAQ,YAAY,iBAAkB,EACjG,QAAS,CAAE,UAAW,EAAM,CAC9B,CACF,CAAC,ECvEK,GAAY,EAAgB,iBAAiB,uBAAuB,EAE1E,SAAS,GAAc,EAAoB,EAAsB,CAgB/D,OAfI,IAAe,IACV,cAEL,EAAA,GACK,cAEL,EAAa,GAAK,EACb,aAEL,EAAa,EACR,wBAEL,EACK,eAEF,yBACT,CAEA,SAAS,GAAwB,EAA4B,CAO3D,OANI,EAAA,GACK,iBAEL,EAAa,EACR,kBAEF,cACT,CAEA,SAAS,GAAoB,EAA4B,CAOvD,OANI,EAAA,GACK,eAEL,EAAa,EACR,gBAEF,YACT,CAWA,SAAgB,GAAe,EAA4B,CACzD,IAAM,EAAc,GAAe,EAE7B,EAAyB,CAC7B,WAAY,EAAW,MACvB,OAAQ,EAAW,QACnB,SAAU,EAAgB,eAC1B,WAAY,GAAyB,MACvC,EAEM,EAAgC,CACpC,WAAY,EAAW,MACvB,OAAQ,EAAW,QACnB,SAAU,EAAgB,eAC1B,WAAY,GAAyB,iBACvC,EAEM,EAAgB,CACpB,qBAAsB,EAAM,oBAAoB,GAChD,wBAAyB,EAAM,oBAAoB,aACrD,EAEM,EAAyB,EAAM,YAAc,EAAM,UAAa,IAEhE,EAAqB,CACzB,YAAa,GAAU,eAAe,EACtC,eAAgB,GAA2B,kBAAkB,EAC7D,qBAAsB,EACtB,wBAAyB,EACzB,iBAAkB,EAAwB,EAAI,uBAAyB,cACzE,EAEM,EAAuB,CAC3B,cACE,EAAY,IAAM,EAAY,GAC5B,KACA,GAAU,QAAQ,EACtB,iBAAkB,CAChB,YAAa,EAAY,QACzB,OAAQ,EAAQ,OAAO,gBACzB,EACA,uBAAwB,EACxB,0BAA2B,EAC3B,mBAAoB,EAAwB,EAAI,eAAiB,sBACnE,EAEM,EAAgB,CACpB,SAAU,GAAU,GAClB,EACA,EAAM,WACR,EAAG,CACD,YAAa,EAAM,WACrB,CAAC,EACD,WAAY,EAAY,EAC1B,EAEA,OACE,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,KAAK,eACL,MAAO,EAAM,YACb,SAAU,EAAM,UAChB,UAAW,EAAM,UACjB,YAAa,GAAoB,CAAqB,EACtD,aAAc,GAAwB,CAAqB,EAC3D,aAAc,GAAyB,EAEvC,GAAI,EAEJ,GAAI,EACJ,GAAI,CACL,CAAA,CAEL,CC1HA,IAAM,GAAY,EAAgB,iBAAiB,oBAAoB,EACjE,GAAsB,GAE5B,SAAS,GAAQ,EAAkB,EAAsB,CAOvD,OANI,EAAW,GACN,aAEL,EAAW,GAAK,EACX,wBAEF,UACT,CAEA,SAAS,GAAwB,EAA0B,CAOzD,OANI,EAAW,GACN,iBAEL,EAAW,EACN,kBAEF,cACT,CAEA,SAAS,GAAoB,EAA0B,CAOrD,OANI,EAAW,GACN,eAEL,EAAW,EACN,gBAEF,YACT,CAaA,SAAgB,GAAY,EAAyB,CACnD,IAAM,EAAc,GAAe,EAE7B,EAAyB,CAC7B,WAAY,EAAW,MACvB,OAAQ,EAAW,QACnB,SAAU,EAAgB,YAC1B,WAAY,GAAsB,MACpC,EAEM,EAAgC,CACpC,WAAY,EAAW,MACvB,OAAQ,EAAW,QACnB,SAAU,EAAgB,YAC1B,WAAY,GAAsB,iBACpC,EAEM,EAAgB,CACpB,qBAAsB,EAAM,oBAAoB,GAChD,wBAAyB,EAAM,oBAAoB,aACrD,EAEM,EAAgB,CACpB,YAAa,EAAY,QACzB,OAAQ,EAAQ,OAAO,gBACzB,EAEM,EAAuB,GAA2B,kBAAkB,EAEpE,EAAqB,CACzB,YACE,EAAM,QACF,EAAM,YAAqB,GAAU,YAAY,EAA7B,KACtB,GAAU,eAAe,EAC7B,eAAgB,EAAM,QAAU,EAAgB,EAChD,qBAAsB,EACtB,wBAAyB,EAAM,QAAU,EAAyB,EAClE,iBAAkB,EAAM,QAAU,uBAAyB,IAC7D,EAGM,EAAuB,CAC3B,cACE,EAAY,IAAM,EAAY,IAAM,CAAC,EAAM,aAAe,EAAM,QAC9D,KACA,GAAU,QAAQ,EACtB,iBAAkB,EAClB,uBAAwB,EACxB,0BAA2B,CAC7B,EAEM,EAAgB,CACpB,SAAU,GAAU,GAAQ,EAAM,SAAU,EAAM,WAAW,EAAG,CAC9D,WAAY,EAAM,SAClB,KAAM,GAAW,OAAO,EAAM,WAAY,cAAc,CAC1D,CAAC,EACD,WAAY,EAAY,EAC1B,EAEA,OACE,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,KAAK,YACL,UAAW,EAAM,UACjB,SAAU,EAAM,WAAa,EAC3B,GAAU,gBAAiB,CAAE,WAAY,EAAM,UAAW,CAAC,EAC3D,GAAU,cAAe,CAAE,WAAY,EAAM,QAAS,CAAC,EAEzD,YAAa,GAAoB,EAAM,QAAQ,EAC/C,aAAc,GAAwB,EAAM,QAAQ,EACpD,GAAI,EAEJ,GAAI,EACJ,GAAI,CACL,CAAA,CAEL,CC1GA,IAAM,GAA4E,CAChF,MAAO,GACP,SAAU,GACV,OAAQ,EACV,EAIM,GAAsB,CAC1B,mCACA,6BACF,EAGA,SAAgB,IAAmB,CACjC,IAAM,EAAiB,GAAe,gBAAgB,CAAC,CAAC,QAElD,EAAc,EAAkC,EAAa,YAAY,CAAC,EAE1E,EAAc,GAAe,EAE7B,CAAE,eAAc,SAAU,GAAuB,GAAgB,EACjE,CAAE,sBAAuB,GAAsB,EAC/C,CAAE,6BAA8B,GAAyB,EAEzD,CAAE,kBAAmB,GAAe,EAEpC,CAAE,QAAS,EAAsB,8BAA+B,GAAwB,EAExF,CACJ,SAAU,EACV,cACA,wBACA,0BACE,GAAe,EAEb,CACJ,gBACA,oBACA,mBACE,GAAY,IAAI,EAEd,EAAA,EAAiB,YAAc,CACnC,GAAI,EACF,MAAO,GAET,IAAM,EAAU,IAAI,KAAK,CAAa,EAChC,EAAQ,IAAI,KAElB,OAAO,KAAK,IAAI,GAAW,YAAY,EAAS,EAAO,KAAK,EAAG,CAAC,EAAI,CACtE,EAAG,CAAE,EAAmB,CAAc,CAAC,EAEjC,EAAa,KAAK,MAAM,EAAW,EAAE,EAErC,CAAE,WAAY,GAAoB,GAAe,EAEjD,EAAgB,GAAiB,EAEjC,EAAa,EAAc,yBAA2B,GAAoB,KAC1E,EAAa,GAAoB,SAAS,GAAc,EAAE,EAEhE,SAAS,GAAoC,CAU3C,OATI,EACK,SAEL,EACK,WAEL,EACK,QAEF,IACT,CAEA,IAAM,EAAY,GAAuB,EAAqB,GAIxD,EAAmB,GAAsB,iBAAiB,EAAgB,CAAS,EAEzF,GACE,GACA,CAAC,GAAa,cACd,CAAC,EAAc,UACf,CAAC,GACD,CAAC,GACD,CAAC,EAED,OAAO,KAET,GAAI,EACF,OACE,EAAA,EAAA,IAAA,CAAC,GAAD,CACe,cACE,gBACK,qBACO,4BAC3B,gBAAiB,EAAY,MAAM,gBACnC,UAAW,EAAiB,UACN,uBACM,4BAC7B,CAAA,EAKL,GAAI,EAAe,EAAe,iBAAiB,EACjD,OAAO,KAET,GAAI,EACF,OACE,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,UAAU,4BACU,qBACpB,YAAa,EAAwB,EACrC,YAAa,EACb,UAAW,EACX,gBAAiB,EAAe,EAAe,YAAY,CAC5D,CAAA,EAIL,GAAI,EAAiB,CACnB,IAAM,EAAU,EAAa,UAAU,WAAW,SAAS,OAAO,EAElE,OACE,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,UAAU,4BACU,qBACpB,YAAa,GAAmB,EAAe,EAAe,mBAAmB,EACxE,UACT,WAAY,EACF,WACE,aACZ,gBAAiB,EAAe,EAAe,YAAY,CAC5D,CAAA,CAEL,CAEA,OAAO,IACT,CChKA,IAAY,GAAL,SAAA,EAAA,OACL,GAAA,OAAA,UACF,EAAA,CAAA,CAAA,EAEM,GAAoC,CACxC,GAAG,GAAU,gBAAgB,aAC7B,GAAG,GAAU,gBAAgB,cAC/B,EAEM,GAA0F,CAAA,SAC1E,EACtB,EAEA,SAAS,GAAa,EAA4C,CAChE,MAAO,CAAC,CAAC,GAAS,GAAwB,SAAS,GAAG,EAAM,gBAAgB,CAC9E,CAEA,SAAS,GACP,EACA,EAC4B,CAC5B,IAAM,EAAa,GAAuB,uBAAuB,CAAS,EAE1E,OAAO,GAAW,KAAK,GAAS,EAAM,KAAO,EAAW,gBAAgB,CAC1E,CAEA,SAAS,GAAY,EAAiB,EAA4C,CAChF,MAAO,CAAC,CAAC,GAAS,GAAqB,EAAK,CAAC,CAAK,CACpD,CAEA,SAAS,GACP,EACA,EACA,EACS,CACT,OAAQ,GAAc,CAAC,EAAA,CAAG,KAAK,GAAa,GAAY,EAAM,GAAqB,EAAW,CAAS,CAAC,CAAC,CAC3G,CAEA,IAAa,GAAY,CACvB,wBACA,eACA,kBACF,EC1CA,SAAgB,IAAmB,CACjC,GAAM,CAAE,sBAAuB,GAAsB,EAE/C,EAAY,EAChB,GAAoB,IAAM,GAAuB,UAAU,EAAmB,EAAE,CAClF,EAIM,EAAyB,GAFF,EAAU,MAAM,OAAS,EAAU,KAAK,IAAI,GACvE,GAAkB,wBAAwB,EAAM,GAAI,GAAkB,MAAO,CAAC,GAAgB,SAAS,CAAC,CAAC,EAAI,CAAC,CACnB,EAE7F,MAAO,CACL,YACA,yBACA,gBAAkB,GAAoB,GAAU,gBAAgB,EAAM,EAAuB,KAAM,EAAU,IAAI,CACnH,CACF,CCzBA,IAAY,GAAL,SAAA,EAAA,OACL,GAAA,QAAA,UACA,EAAA,KAAA,QACF,EAAA,CAAA,CAAA,ECDA,SAAgB,GAAmB,EAAsC,CACvE,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,GAAI,YACP,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,EAAE,qcAAqc,KAAK,SAAU,CAAA,CACzd,CAAA,CAGT,CCOA,IAAM,GAAY,EAAgB,iBAAiB,gCAAgC,EAMnF,SAAgB,GAAuB,EAAqD,CAC1F,IAAM,EAAW,GACf,EAAQ,eACR,GAAc,oBAAoB,CACpC,EAEM,EAAM,GAAW,CACrB,SAAU,EAAQ,mBAAqB,EACvC,YAAa,GACb,WAAY,EACd,CAAC,EAED,MAAO,CACL,GAAI,EAAU,SACd,KAAM,UACN,KAAM,GACN,QAAS,CACP,YAAa,EAAY,SACzB,OAAQ,EAAQ,SAAS,SACzB,KAAM,CAAC,EAAQ,oBAAoB,UAAU,CAC/C,EACA,KAAM,GAAU,UAAU,EAC1B,MAAO,GAAa,MACpB,MACA,UACF,CACF,CC9CA,SAAgB,GAAoB,EAAsC,CACxE,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,GAAI,YACP,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,EAAE,68BAA68B,KAAK,SAAU,CAAA,CACj+B,CAAA,CAGT,CCOA,IAAM,GAAY,EAAgB,iBAAiB,gCAAgC,EAEnF,SAAgB,GAAyB,EAA6C,CACpF,GAAM,CAAE,iBAAgB,YAAa,EAC/B,EAAW,GAAmB,EAAQ,eAAgB,GAAc,sBAAsB,CAAC,EAC3F,EAAM,GAAW,CACrB,SAAU,EAAQ,mBAAqB,EACvC,YAAa,GACb,WAAY,EACd,CAAC,EAEK,EAAO,EAAS,gBACpB,EAAe,EAAe,cAAc,GAAK,EAAS,iBAC3D,CAAC,EAAe,EAAe,iBAAiB,GAChD,CAAC,EAAe,EAAe,eAAe,EAE/C,MAAO,CACL,GAAI,EAAU,WACd,KAAM,UACN,KAAM,GAAU,YAAY,EAC5B,OACA,MAAO,GAAa,OACpB,QAAS,CACP,YAAa,EAAY,WACzB,OAAQ,EAAQ,WAAW,IAC7B,EACA,MACA,UACF,CACF,CC3CA,SAAgB,GAAY,EAAsC,CAChE,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,QAAQ,YAAY,KAAK,OAAO,GAAI,YACvC,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,EAAE,kiTACF,KAAK,UACL,OAAO,UACP,YAAY,KACb,CAAA,CACE,CAAA,CAET,CCXA,SAAgB,GAAQ,EAAsC,CAC5D,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,QAAQ,YAAY,KAAK,OAAO,GAAI,YACvC,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,EAAE,01TACF,KAAK,UACL,OAAO,QACP,YAAY,KACb,CAAA,CACE,CAAA,CAET,CCXA,SAAgB,GAAkB,EAAsC,CACtE,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,GAAI,YACP,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,EAAE,uPAAuP,KAAK,SAAU,CAAA,CAC3Q,CAAA,CAET,CCNA,SAAgB,GAAY,EAAsC,CAChE,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,QAAQ,YAAY,GAAI,YAC3B,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,MAAM,6BAA6B,EAAE,6wBAA6wB,KAAK,cAAe,CAAA,CACz0B,CAAA,CAET,CCoBA,IAAM,GAA4D,EAC/D,GAAU,gBAAgB,YAAa,CAAE,GAAS,EAAY,GAC9D,GAAU,gBAAgB,cAAe,CAAE,GAAS,EAAY,CACnE,EAEM,GAAqC,EACxC,GAAU,gBAAgB,YAAa,oBACvC,GAAU,gBAAgB,cAAe,kBAC5C,EAEA,SAAgB,GAAmB,EAAoD,CAiDrF,MAhDI,CAAC,EAAQ,WAAW,QAAU,CAAC,EAAQ,UAAU,OAAe,CAAC,EAExC,EAAQ,WAAW,QAAuB,EAAK,IAAc,CACxF,IAAM,EAAe,GAAU,qBAAqB,EAAW,EAAQ,SAAS,EAEhF,GAAI,CAAC,EAAc,OAAO,EAE1B,GAAM,CAAE,UAAW,EAAQ,eACrB,EAAgB,OAAO,GAAW,SAAW,GAAQ,SAAW,IAAA,GAGhE,EAFwB,IAAkB,IAAA,IAAa,OAAO,CAAa,IAAM,OAAO,EAAa,EAAE,GAEnE,GACxC,EAAQ,eACR,GAAc,gBAAgB,EAAa,EAAE,EAC7C,CAAE,UAAW,EAAK,CACpB,EAEM,CAAE,EAAa,GACnB,GAAsB,EAAa,iBAAmB,CAAE,GAAa,EAAkB,EAEnF,EAAM,GAAW,CACrB,SAAU,EAAQ,mBAAqB,EACvC,cACA,YACF,CAAC,EAEK,EAAU,GAAU,YAAY,GAAU,OAAQ,CAAY,EAmBpE,OAjBA,EAAI,KAAK,CACP,GAAI,EAAU,KACd,KAAM,UACN,KAAM,GACN,MAAO,GAAa,MACpB,QAAS,CACP,YAAa,EAAY,QACzB,OAAQ,EAAQ,SAAS,eACzB,KAAM,CAAE,KAAM,EAAa,GAAI,EAAW,QAAQ,EAAa,IAAI,CAAE,CACvE,EACA,KAAM,GAAW,EAAa,iBAAmB,EAAU,KAC3D,MACA,WAEA,IAAK,EAAU,GAAM,EAAQ,wBAAwB,CAAE,EAAI,IAAA,EAC7D,CAAC,EAEM,CACT,EAAG,CAAC,CAAC,GAAK,CAAC,CAGb,CCtEA,IAAM,GAAY,EAAgB,iBAAiB,gCAAgC,EAMnF,SAAgB,GAAwB,EAAsD,CAC5F,IAAM,EACJ,EAAQ,WAAa,EAAa,WAClC,EAAQ,eAAe,EAAe,aAAa,GACnD,EAAQ,UAAU,OAAS,EAE7B,SAAS,GAA8B,CACrC,IAAM,EAAW,GAAc,qBAAqB,EAMpD,OAJI,EAAQ,WAAa,EAAa,WACpC,EAAS,KAAK,GAAG,GAAc,mBAAmB,CAAC,EAG9C,GAAmB,EAAQ,eAAgB,CAAQ,CAC5D,CAEA,IAAM,EAAW,EAAmB,EAC9B,EAAM,GAAW,CACrB,SAAU,EAAQ,mBAAqB,EACvC,YAAa,GACb,WAAY,EACd,CAAC,EAED,MAAO,CACL,GAAI,EAAU,UACd,KAAM,UACN,KAAM,GAAU,WAAW,EAC3B,OACA,MAAO,GAAa,MACpB,QAAS,CACP,YAAa,EAAY,UACzB,OAAQ,EAAQ,UAAU,SAC5B,EACA,MACA,UACF,CACF,CC7BA,SAAS,GAA2B,EAA4D,CAC9F,IAAM,EAAgB,GAAa,2CACjC,GAAc,cACd,GAAc,IAChB,EAEA,OAAQ,GAAc,KAAtB,CACE,KAAK,GAAiB,mBACpB,MAAO,CACL,KAAM,GACN,gBACA,MAAO,GAAa,MACtB,EACF,QACE,MAAO,CACL,KAAM,GACN,gBACA,MAAO,GAAa,KACtB,CACJ,CACF,CAEA,SAAS,GAAgB,EAAkE,CACzF,GAAM,CAAE,yBAAwB,uBAAsB,4BAA6B,EAKnF,MAHI,CAAC,GAAwB,QAAU,CAAC,EAC/B,CAAC,EAEH,EAAuB,QAAQ,EAAK,IAAiB,CAC1D,IAAM,EAAa,GAA2B,CAAY,EAEpD,EAAQ,EAAW,MAiBzB,MAfA,GAAI,GAAS,EAAI,IAAU,CAAC,EAC5B,EAAI,EAAM,CAAC,KAAK,CACd,KAAM,EAAW,KACjB,cAAe,EAAW,cAC1B,QACA,KAAM,EAAa,KACnB,SAAU,GAAsB,KAAO,EAAa,GACpD,YAAe,CACb,EAAQ,qBAAqB,CAAY,CAC3C,EACA,cAAe,CACb,EAAyB,CAAY,EAAI,EAAqB,QAAU,IAC1E,CACF,CAAC,EAEM,CACT,EAAG,CAAC,CAAyB,CAC/B,CAEA,SAAS,GAAsB,EAA0D,CAKvF,OAJqB,OAAO,OAAO,EAAY,CAAC,CAAC,MAC9C,EAAG,IAAM,OAAO,CAAC,EAAI,OAAO,CAAC,CAGzB,CAAA,CAAa,QAAQ,EAAQ,KAC9B,EAAa,KACf,EAAO,GAAS,EAAa,IACxB,GACN,CAAC,CAAyB,CAC/B,CAEA,SAAgB,GAA2B,EAAyD,CAClG,GAAM,CACJ,uBACA,yBACA,2BACA,kCACE,EAEE,EAAU,GAA2B,CAAoB,EAKzD,EAHoB,GAAwB,QAAU,GAAgB,8BAG1C,CAAC,CAAC,EAG9B,EAAqB,GADN,GAAgB,CACY,CAAY,EAEvD,EAAwC,CAAC,EAQ/C,OANI,GACF,EAAc,KAAK,EAAqB,MAAM,EAE5C,EAAyB,CAAoB,GAC/C,EAAc,KAAK,EAAqB,OAAO,EAE1C,CACL,KAAM,WACN,GAAI,EAAU,aACd,MAAO,GAAa,MACpB,KAAM,GAAsB,MAAQ,GACpC,IAAK,EAAQ,KACb,WAAY,CACV,KAAM,EAAQ,cACd,aAAc,EAAQ,WAAa,EAAa,KAAO,OAAS,MAClE,EACA,OACA,MAAO,EACP,eAAgB,EAAQ,WAAa,EAAa,UAClD,SAAU,GACV,IAAK,GAAM,EAAQ,iBAAiB,CAAE,EACtC,eACF,CACF,CCvFA,IAAM,GAAY,EAAgB,iBAAiB,6BAAS,EAM5D,SAAS,GAAgB,EAA+C,CAKtE,OAJI,EAAQ,oBAAoB,OAAS,GAAiB,mBACjD,GAAa,KAGf,GAAa,OACtB,CAOA,SAAgB,GAAkB,EAAmC,CACnE,IAAM,EAAU,GAAwB,EAClC,CAAE,iBAAgB,uBAAwB,GAAe,EACzD,EAAW,GAAY,IAAI,EAC3B,EAAS,GAAU,EAEnB,CAAE,gBAAiB,GAAgB,EACnC,CAAE,qBAAoB,yBAA0B,GAAsB,EACtE,CAAE,wBAAuB,4BAA6B,GAAyB,EAC/E,CAAE,yBAAwB,uBAAwB,GAA0B,EAC5E,EAAc,CAAC,CAAC,GAAoC,EAAe,EAAe,WAAW,CAAC,EAC9F,CAAE,WAAU,0BAA2B,GAAiB,EAKxD,EAH0B,GAI9B,CAAA,CAAwB,sBACxB,IAA2B,GAAiB,QAExC,EACH,GAA+B,GAAY,GAAc,OAAS,EAE/D,CAAE,iBAAkB,GAA+B,GAAsB,aAAa,EACtF,CAAE,iBAAkB,GAA0B,GAAsB,QAAQ,EAE5E,CACJ,UAAW,GACT,GAAyB,CAC3B,WAAY,GAAoB,YAChC,YAAa,CAAC,CAChB,CAAC,EAEK,EAAc,EAAkC,EAAa,YAAY,CAAC,EAE1E,CAAE,YAAW,0BAA2B,GAAiB,EAEzD,EAAY,EAChB,EAAe,EAAe,aAAa,GAC3C,GAAgB,gBAAgB,CAAE,gBAAiB,eAAgB,CAAC,CACtE,EAEA,EAAqB,CAAC,CAAC,EAAU,MAAM,QACrC,GAAgB,wBAAwB,EAAU,KAAK,IAAI,GAAK,EAAE,EAAE,CAAC,CAAC,EAExE,SAAS,EAA4B,EAAoC,CACvE,EAAgB,cACd,CACE,GAAI,GAAuB,GAC3B,SAAU,EAAqB,EACjC,EACA,CACE,WAAY,EAAW,UACvB,OAAQ,EAAW,aACnB,SAAU,EAAgB,QAC1B,cAAe,EAAc,SAC7B,aAAc,GAAa,EAC7B,CACF,EAEA,IAAM,EAAiB,GAAe,gBAAgB,CAAC,CAAC,QAElD,MAIJ,GAHI,GAAiB,IAAA,EAAuB,iBAAiB,CAAc,CAAC,GAGxE,GAAoB,OAAS,EAAqB,MACpD,GAA+B,IAAA,EAAuB,iBAAiB,CAAc,CAAC,GAQpF,EACJ,CAAC,GAAoB,CAAc,GAAK,CAAC,EAAoB,EAAqB,EAAE,EAElF,EAAwB,GAAK,EAC/B,EAAmB,QAAQ,CACzB,YAAa,EAAY,UACzB,OAAQ,EAAQ,UAAU,KAC1B,KAAM,CAAC,EAAqB,UAAU,CACxC,CAAC,EACQ,GAAiB,CAAc,EACxC,EAAmB,QAAQ,CACzB,GAAG,EACH,KAAM,CAAE,EAAqB,WAAY,GAAG,EAAe,KAAK,MAAM,CAAC,GAAK,CAAC,CAAE,CACjF,CAAC,EAED,EAAmB,QAAQ,CAAc,CAE7C,CAEA,SAAS,GAAqB,EAA4B,CAIxD,GAHA,EAAsB,CAAY,EAG9B,EAAY,CAAY,EAAG,CAC7B,EAA4B,CAAY,EACxC,MACF,CAEA,EAAyB,CAAY,CAAC,CACnC,SAAW,EAA4B,CAAY,CAAC,CAAC,CACrD,UAAY,EAAO,MAAM,GAAU,OAAO,CAAC,CAAC,CACjD,CAEA,EACG,WAAW,CACV,YAAa,EAAY,KACzB,WACA,SAAU,EAAQ,SAClB,eAAgB,EAAQ,cACxB,iBACA,sBACA,kBAAmB,EACrB,CAAC,CAAC,CAED,WAAW,EAAU,aAAc,GAA4B,CAC9D,wBACA,yBACA,qBAAsB,EACtB,yBAA0B,EAC1B,iBAAkB,EAClB,+BAAgC,CAClC,CAAC,CAAC,CACD,WAAW,EAAU,YAAa,EAAyB,CAAC,CAC5D,WAAW,EAAU,SAAU,GAAwB,CACtD,gBAAiB,EAAU,MAAM,IAAI,GAAK,EAAE,GAAG,SAAS,CAAC,EACzD,qBACA,4BAA6B,CAAC,CAAC,EAAqB,IACtD,CAAC,CAAC,CACD,WAAW,EAAU,YAAa,GAA2B,CAC5D,4BAA6B,CAAC,CAAC,EAAqB,KACpD,oBACF,CAAC,EAEC,GACF,EAAQ,WACN,EAAU,SACV,GACA,CAAE,oBAAmB,CACvB,EAEF,EACG,WACC,EAAU,KACV,GACA,CACE,WAAY,EAAuB,MAAQ,CAAC,EAC5C,UAAW,EAAU,MAAQ,CAAC,EAC9B,uBACF,CACF,CAAC,CAEA,WAAW,EAAU,UAAW,EAAuB,CAAC,CACxD,WAAW,EAAU,SAAU,GAAwB,CAAE,aAAY,CAAC,CAAC,CACvE,WAAW,EAAU,SAAU,EAAsB,CAAC,CACtD,WAAW,EAAU,WAAY,EAAwB,CAAC,CAE1D,WAAW,EAAU,QAAS,GAAwB,CAAE,UAAW,EAAU,MAAQ,CAAC,CAAC,CAAC,CAAC,CACzF,WAAW,EAAU,UAAW,GAAyB,CAAE,UAAW,EAAU,MAAQ,CAAC,CAAC,CAAC,EAE9F,IAAM,EAAW,EAAQ,SAAS,CAAC,CAAC,OAAS,EAE7C,MAAO,CACL,MAAO,EAAQ,gBAAgB,EAC/B,QAAS,EACT,MAAO,GAAgB,CAAE,oBAAmB,CAAC,CAC/C,CACF,2DE9NA,SAAgB,GAAoB,EAAiC,CACnE,GAAI,EAAM,OAAS,EAAqB,OACtC,OAAO,EAAA,EAAA,IAAA,CAAC,GAAD,CAAqB,KAAK,YAAY,UAAU,OAAO,WAAY,EAAO,CAAA,EAGnF,GAAI,EAAM,OAAS,EAAqB,UACtC,OAAO,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAW,2BAA4B,GAAO,mBAAoB,EAAM,SAAS,CAAI,CAAA,EAG/G,GAAI,EAAM,OAAS,EAAqB,QACtC,OACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAa,UAAW,EAAM,UAAW,QAAS,EAAM,QAAS,YAAA,EAAY,CAAA,CAGnF,udGXM,GAAwD,EAC3D,EAAU,UAAW,GAAO,cAC/B,EAIa,GAAA,EAAuB,YACjC,EAA4B,IAAgC,CAC3D,IAAM,EAAyB,EAC7B,EAAW,YACX,6BACA,EAAM,UAAY,EAAW,MAC/B,EAEM,EAAgC,EACpC,oBACA,EAAW,qBACX,EAAM,YAAY,IACpB,EAEM,EAAuB,EAC3B,oBACA,GAAsB,EAAM,KAAO,aACrC,EAEM,EAAc,EAAM,eAAe,SAAS,EAAqB,SAAS,EAEhF,OACE,EAAA,EAAA,KAAA,CAAC,EAAD,CACO,MACL,UAAW,EACX,QAAS,EAAM,QACf,cAAe,CACb,GAAI,GAAc,mBAAmB,EAAM,EAAE,EAC7C,MAAO,EAAM,KACb,KAAM,EAAM,GACd,EACA,iBAAkB,CAChB,WAAY,EAAW,MACvB,OAAQ,EAAW,IACnB,SAAU,EAAgB,OAC5B,EACA,QAAS,EAAM,iBAdjB,EAgBE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,WAAhB,EACE,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,IAAK,EAAM,IACX,YAAY,OACZ,QAAS,EAAiB,SAC1B,SAAU,GAAY,UAAU,EAAM,SAAU,CAAE,KAAM,GAAU,KAAM,CAAC,CAC1E,CAAA,EACA,IACC,EAAA,EAAA,IAAA,CAAC,GAAD,CAAqB,KAAM,EAAqB,UAAW,UAAW,CAAuB,CAAA,CAE5F,KACL,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAW,oBAAqB,EAAW,eAAe,WAAI,EAAM,IAAW,CAAA,CACzF,GAEb,CACF,uKEhDa,GAAA,EAA8B,YACxC,EAAmC,IAAyC,CAC3E,GAAM,CAAE,WAAU,WAAY,EAExB,EAAyB,EAC7B,EAAW,YACX,EAAM,YAAY,UAClB,EAAM,UAAY,EAAW,OAC7B,0CACF,EAEM,EAAgC,EACpC,EAAW,qBACX,EAAM,YAAY,KAClB,WACF,EAEM,EAAmC,EACvC,EAAM,gBAAkB,EAAM,SAC5B,GAAO,2BAA6B,2BACxC,EAEM,EAAa,EAAM,OAAS,GAAe,GAEjD,OACE,EAAA,EAAA,KAAA,CAAC,GAAD,CAAgB,MAAc,UAAS,UAAW,WAAlD,CACG,EAAM,iBACL,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAW,CAAC,EAAM,UAAY,WAAW,YACvD,EAAA,EAAA,IAAA,CAAC,EAAD,CACE,IAAK,GACL,KAAM,EAAiB,KACxB,CAAA,CACE,CAAA,GAEP,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,YACd,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,oFACb,EAAA,EAAA,IAAA,CAAC,EAAD,CACE,IAAK,EAAM,IACX,KAAM,EAAiB,QACxB,CAAA,CACE,CAAA,CACF,CAAA,GACL,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,2CAAf,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAW,oBAAqB,EAAW,eAAe,EAAI,UAAe,CAAA,EAC7F,EAAM,oBAAqB,EAAA,EAAA,IAAA,CAAC,EAAD,CAAc,IAAK,EAAY,KAAM,EAAiB,KAAQ,CAAA,CACvF,IAEJ,EAAM,mBACL,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,KAAM,EAAqB,QAC3B,UAAW,EACX,QAAS,EAAM,eAAiB,EAAiB,MAAQ,EAAiB,QAC3E,CAAA,CAEM,GAEf,CACF,EC9DM,GAAA,EAAmB,YACtB,EAAwB,IAAyC,CAChE,GAAM,CACJ,YAAW,WAAU,QAAO,WAC3B,kBAAoB,EACpB,iBAAmB,GAClB,EAIJ,OAAA,EAAA,GAAA,aAAA,EACE,EAAA,EAAA,IAAA,CAAC,MAAD,CACO,MACL,UALwB,EAAW,GAAO,gBAAiB,CAKhD,EACJ,QACP,kBAAiB,EACP,WACV,iBAAgB,EAEf,UACE,CAAA,EACL,SAAS,eAAe,eAAe,CACzC,CACF,CACF,EAEa,GAAA,EAAwB,YAClC,EAA6B,IAAmC,CAC/D,GAAM,CAAE,EAAQ,GAAA,EAAoB,SAAS,EAAK,EAE5C,EAAc,OAAO,QAAQ,EAAM,KAAK,EAExC,EAAmB,EAAY,OAAS,EACxC,EAAe,GAAoB,EACzC,SAAS,EAAa,EAAoB,CACnC,GAGL,EAAU,CAAS,CACrB,CAEA,OACE,EAAA,EAAA,KAAA,CAAC,EAAD,CAAU,KAAM,EAAc,SAAU,WAAxC,EACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,uEACb,EAAA,EAAA,IAAA,CAAC,EAAS,OAAV,CACE,GAAI,GACC,MACL,SAAU,EAAM,SAChB,SAAU,CAAC,EACX,OAAQ,EACR,IAAK,EAAM,IACX,WAAY,CACV,KAAM,EAAM,YAAY,IAC1B,EACA,eAAgB,EAAM,eACtB,kBAAmB,CAAC,EAAM,gBAAkB,EAC5C,iBAAkB,EAAM,eAAe,SAAS,EAAqB,OAAO,EAC5E,SAAU,aAEV,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,qBAAa,EAAM,IAAW,CAAA,CAC/B,CAAA,CACd,CAAA,GACL,EAAA,EAAA,KAAA,CAAC,EAAS,KAAV,CACE,GAAI,GACJ,UAAW,EAAM,YAAY,aAC7B,iBAAgB,EAAM,SACtB,aAAc,CAAE,SAAU,OAAQ,WAJpC,CAMG,EAAM,eAAe,SAAS,EAAqB,MAAM,IACxD,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,KAAM,EAAqB,OAC3B,UAAW,EACT,+CACA,GAAO,mBACT,CACD,CAAA,EAEF,EAAY,KAAK,CAAE,EAAO,GAAS,IAAU,CAC5C,IAAM,EAAmB,IAAU,EAEnC,OACE,EAAA,EAAA,KAAA,CAAA,EAAO,SAAP,CAAA,SAAA,CACI,CAAC,IACD,EAAA,EAAA,IAAA,CAAC,EAAS,QAAV,CAAkB,MAAO,CAAE,MAAO,KAAM,EAAG,UAAU,SAAW,CAAA,EAGjE,EAAM,IAAI,IACT,EAAA,EAAA,IAAA,CAAC,EAAS,KAAV,CACE,GAAI,GAEJ,YAAe,CACb,EAAM,UAAU,EAChB,EAAK,QAAQ,CACf,EACA,IAAK,EAAK,KACV,WAAY,CACV,KAAM,EAAK,cACX,UAAW,EACT,+CACA,GAAO,mBACT,CACF,EACQ,SACR,SAAU,EAAK,SACf,iBAAkB,EAAK,eAAe,SAAS,EAAqB,OAAO,EAC3E,eAAgB,GAChB,eAAgB,YAEf,EAAK,IACO,EApBR,GAAG,EAAM,GAAG,EAAK,MAoBT,CAChB,CACa,CAAA,EA9BK,CA8BL,CAEpB,CAAC,CACY,GACP,GAEd,CACF,ECnIM,GAAyE,CAC7E,QAAS,CACP,UAAW,EACb,EACA,SAAU,CACR,UAAW,EACb,CACF,EAQA,SAAgB,GAAqB,EAAsC,CACzE,GAAM,CAAE,OAAM,WAAU,kBAAmB,EAErC,EAAS,GAAsB,EAAK,MAE1C,GAAI,CAAC,EACH,MAAM,IAAI,EAAS,+BAA+B,EAAK,MAAM,EAG/D,SAAS,GAAU,CACjB,EAAe,EACf,EAAK,UAAU,CACjB,CAEA,IAAM,EAAY,EAAO,UAEzB,OAAO,EAAA,EAAA,IAAA,CAAC,EAAD,CAAW,GAAI,EAAgB,WAAmB,SAAU,CAAA,CACrE,CCzCA,IAAa,GAAA,EAAoB,YAAY,EAAyB,IAAyC,CAC7G,GAAM,CAAE,QAAO,GAAG,GAAU,EAE5B,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CACE,GAAI,EACC,MACL,MAAO,CACL,GAAG,EAGH,MAAO,MACP,MAAO,MACP,IAAK,MACL,aAAc,MACd,OAAQ,KACV,CACD,CAAA,CAEL,CAAC,ECJD,SAAgB,GAAc,EAAwC,CACpE,GAAI,EAAM,WAAa,EAAa,OAClC,OAAO,EAAA,EAAA,IAAA,CAAA,EAAA,SAAA,CAAI,CAAA,EAGb,IAAM,EAAe,EACnB,kFACA,EAAO,QACP,EAAM,WAAa,EAAa,MAAQ,EAAO,gBAC/C,EAAM,WAAa,EAAa,WAAa,EAAO,gBACtD,EAEM,EAAwB,EAC5B,oBACA,EAAO,oBACT,EAEM,EAAqB,OAAO,QAAQ,EAAM,KAAK,EAErD,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAc,iBAAgB,EAAM,SAAU,iBAAgB,EAAM,mBAClF,EAAA,EAAA,IAAA,CAAC,GAAA,WAAD,CACE,oBAAqB,IAAS,EAAA,EAAA,IAAA,CAAC,GAAD,CAAa,GAAI,CAAQ,CAAA,YAEvD,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,iDACX,EAAmB,KAAK,CAAE,EAAO,GAAY,IAAe,CAC3D,IAAM,EAAmB,IAAe,EAExC,OACE,EAAA,EAAA,KAAA,CAAA,EAAO,SAAP,CAAA,SAAA,CACI,CAAC,IACD,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAW,EAAO,kCACpB,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,KAAO,CAAA,CACnB,CAAA,EAGL,EAAS,KAAK,EAAM,KACnB,EAAA,EAAA,IAAA,CAAC,KAAD,CAAkC,UAAW,YAC3C,EAAA,EAAA,IAAA,CAAC,GAAD,CAA4B,OAAM,SAAU,EAAM,SAAU,eAAgB,EAAM,cAAiB,CAAA,CACjG,EAFK,GAAG,EAAM,GAAG,GAEjB,CACL,CACa,CAAA,EAZK,GAAG,EAAM,GAAG,GAYjB,CAEpB,CAAC,CACC,CAAA,CACM,CAAA,CACT,CAAA,CAET,wJEnDM,GAAY,yBACZ,GAAY,EAAgB,iBAAiB,EAAS,EAEtD,GAAoB,0BAEpB,OAAuB,CAC3B,IAAM,EAAc,GAAgB,WAAW,EAEzC,EAAY,EAAU,aAE5B,OAAQ,EAAY,QAApB,CACE,IAAK,OACL,IAAK,oBACH,MAAO,CACL,KAAM,GAAU,MAAM,EACtB,KAAM,EAAU,IAClB,EAEF,IAAK,UACH,MAAO,CACL,KAAM,GAAU,SAAS,EACzB,KAAM,EAAU,OAClB,EAEF,IAAK,SACH,MAAO,CACL,KAAM,GAAU,QAAQ,EACxB,KAAM,EAAU,MAClB,EAGF,QACE,MAAO,CACL,KAAM,GAAU,QAAQ,EACxB,KAAM,EAAU,MAClB,CACJ,CACF,EAEa,GAAA,EAA4B,KAAK,UAAwB,CACpE,GAAM,CAAE,WAAU,eAAc,mBAAoB,GAAa,KAAM,EAAgB,eAAe,EAEhG,CAAE,EAAkB,GAAA,EAA8B,SAAS,EAAK,EAEtE,SAAS,GAAyB,CAShC,OAPI,GAGA,GAAW,QAAQ,EAAiB,EAC/B,GAGF,CACT,CAEA,IAAM,EAAU,EAAc,EAU9B,GARA,EAAM,cAAgB,CACf,KAIL,OADA,SAAS,KAAK,UAAU,IAAI,GAAO,QAAQ,MAC9B,SAAS,KAAK,UAAU,OAAO,GAAO,QAAQ,CAC7D,EAAG,CAAC,CAAO,CAAC,EAER,CAAC,EACH,OAAO,EAAA,EAAA,IAAA,CAAA,EAAA,SAAA,CAAI,CAAA,EAEb,SAAS,GAAkB,CACzB,EAAgB,cAAc,CAC5B,UACF,EAAG,CACD,SAAU,EAAgB,gBAC1B,OAAQ,EAAW,SACnB,WAAY,EAAW,OACzB,CAAC,EAED,EAAW,CACb,CAEA,SAAS,GAAe,CACtB,EAAgB,EAChB,EAAW,CACb,CAEA,SAAS,GAAmB,CAE1B,GAAW,QAAQ,GAAmB,OAAQ,MAAO,KAAM,KAAM,GAAM,KAAK,EAE5E,SAAS,KAAK,UAAU,OAAO,GAAO,QAAQ,EAE9C,EAAoB,EAAI,CAC1B,CAEA,IAAM,EAAc,GAAe,EAEnC,OACE,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,QAAS,EAAW,UAAW,uBAAuB,GAAO,MAAS,CAAA,GAE3E,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,2CAA2C,GAAO,2BAAlE,EACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,2DACb,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,QAAU,CAAA,CAC1C,CAAA,GAEL,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,iGAAf,EACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,wEAAf,EACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,iDAAf,EACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAe,UAAW,yBAAyB,GAAO,iBACxD,EAAA,EAAA,IAAA,CAAC,GAAD,CAAkB,CAAA,CACL,CAAA,GACf,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAU,wBACX,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,cAAgB,CAAA,CAClD,CAAA,CACA,KACL,EAAA,EAAA,IAAA,CAAC,MAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAAC,IAAD,CACE,KAAM,EACN,QAAS,EACT,UAAW,gBAAgB,GAAO,mBAElC,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,MAAQ,CAAA,CAC1C,CAAA,CACA,CAAA,CACF,KAEL,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,mEAAf,EACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,iDAAf,EACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,yBAAyB,GAAO,iBAC9C,EAAA,EAAA,IAAA,CAAC,MAAD,CACE,IAAK,EAAY,KACjB,IAAK,EAAY,KACjB,UAAU,WACX,CAAA,CACE,CAAA,GAEL,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAU,uBACV,EAAY,IACZ,CAAA,CACA,KACL,EAAA,EAAA,IAAA,CAAC,MAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,QAAS,EAAW,UAAW,wBAAwB,GAAO,mBACpE,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,UAAY,CAAA,CACzC,CAAA,CACL,CAAA,CACF,GACF,GACF,GACL,CAAA,CAAA,CAEN,CAAC,yJE7JK,GAAY,oBAyBlB,SAAgB,GAAW,EAAwB,CAEjD,SAAS,EAAW,EAAwB,CAO1C,MAHA,EAHI,EAAQ,EAAI,EAAM,cAGlB,IAAU,EAAM,WAAa,EAInC,CAEA,SAAS,GAA2B,CAIlC,OAHI,EAAM,WAAa,EAAI,EAAM,aACxB,EAAgB,UAAU,GAAW,UAAU,EAEjD,EAAM,aAAe,EAAgB,UAAU,GAAW,MAAM,CACzE,CAEA,SAAS,GAAwB,CAC/B,IAAI,EAAY,GAAG,GAAO,UAAU,GAAG,EAAM,gBAAgB,iBAK7D,OAHI,EAAM,2BACR,GAAa,IAAI,EAAM,4BAElB,CACT,CAEA,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,GAAG,GAAO,YAAY,wCAAwC,EAAM,8BAApF,EACE,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,UAAW,GAAG,GAAO,YAAY,yDACjC,IAAK,GACL,QAAS,EAAM,YAChB,CAAA,GAED,EAAA,EAAA,IAAA,CAAC,MAAD,CACE,MAAO,CAAE,gBAAiB,OAAO,EAAM,UAAW,EAClD,UAAW,EAAc,CACrB,CAAA,GAEN,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,oDAAf,CACG,EAAM,aAAe,IACpB,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,aAAc,EAAM,aACpB,WAAY,EAAM,WAClB,UAAU,OACV,iBAAkB,EAAM,cACZ,YACb,CAAA,GAGH,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,6CACb,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,gBAAQ,EAAM,OAAY,CAAA,CACrC,CAAA,GAEL,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAU,gBAAQ,EAAM,WAAe,CAAA,GAE1C,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,6DAAf,EACE,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,KAAM,EAAM,aACZ,UAAU,4BACV,YAAe,EAAM,oBAAoB,EAAM,YAAY,EAC3D,OAAA,YAEC,EAAM,gBACK,CAAA,GAEd,EAAA,EAAA,IAAA,CAAC,GAAD,CAAW,UAAU,4BAA4B,QAAS,EAAM,oBAC7D,EAAiB,CACT,CAAA,CACR,GACF,GACF,GAET,iCEpGM,GAAY,oBACZ,GAAY,EAAgB,iBAAiB,EAAS,EAG5D,SAAgB,GAAoB,EAA0C,CAC5E,OACE,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,SAAU,EAAU,YAAY,OAChC,gBAAgB,UAChB,yBAA0B,GAAO,MACjC,QAAS,GAAU,SAAS,EAC5B,aAAa,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,aAAc,CAAA,EAC9D,aAAc,EAAM,aACpB,WAAY,EAAM,WAClB,YAAa,GAAU,OAAO,EAC9B,aAAc,EAAM,aACpB,WAAY,EAAM,WAClB,cAAe,EAAM,aACtB,CAAA,CAEL,gEElBM,GAAY,iCACZ,GAAY,EAAgB,iBAAiB,EAAS,EAG5D,SAAgB,GAAiC,EAA0C,CACzF,SAAS,EAAiB,EAAc,CACtC,EAAc,SAAS,EAAM,EAAI,CACnC,CAEA,OACE,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,SAAU,EAAU,YAAY,oBAChC,gBAAgB,WAChB,yBAA0B,GAAO,MACjC,QAAS,GAAU,SAAS,EAC5B,aAAa,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAA,GAAW,OAAO,aAAc,CAAA,EAC9D,aAAc,EAAM,aACpB,WAAY,EAAM,WAClB,aAAc,GAAc,yBAAyB,gBAAgB,EACrE,iBAAkB,GAAU,cAAc,EAC1C,oBAAqB,EACrB,mBAAoB,GAAO,SAC5B,CAAA,CAEL,iCE1BM,GAAY,6BACZ,GAAY,EAAgB,iBAAiB,EAAS,EAG5D,SAAgB,GAA+B,EAA0C,CACvF,OACE,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,SAAU,EAAU,YAAY,gBAChC,gBAAgB,WAChB,yBAA0B,GAAO,MACjC,QAAS,GAAU,SAAS,EAC5B,aAAa,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,aAAW,OAAO,aAAc,CAAA,EAC9D,aAAc,EAAM,aACpB,WAAY,EAAM,WAClB,aAAc,EAAM,aACpB,WAAY,EAAM,WAClB,cAAe,EAAM,aACtB,CAAA,CAEL,qREda,GAAwC,CACnD,CACE,GAAI,kBACJ,cAAe,GACf,UAAW,eACX,OAAQ,UACR,WAAY,CAAE,2CAA4C,EAC1D,WAAY,GACH,EAAuB,CAC5B,KAAM,EAAY,qCAClB,MAAO,GACP,KAAM,GAAY,OACpB,CAAC,EAEH,oBAAqB,GAAqB,yBAC1C,eAAgB,GAAO,YACzB,EACA,CACE,GAAI,cACJ,cAAe,GACf,UAAW,QACX,OAAQ,UACR,WAAY,CAAE,uCAAwC,EACtD,WAAY,GACH,EAAuB,CAC5B,KAAM,EAAY,iCAClB,MAAO,GACP,KAAM,GAAY,OACpB,CAAC,EAEH,oBAAqB,GAAqB,oBAC5C,EAAG,CACD,GAAI,SACJ,cAAe,GACf,UAAW,QACX,OAAQ,UACR,WAAY,CAAE,WAAU,uBAAwB,GAAqB,CAAC,EAAS,4BAC/E,WAAY,GACH,EAAuB,CAC5B,KAAM,EAAY,4BAClB,MAAO,GACP,KAAM,GAAY,OACpB,CAAC,EAEH,oBAAqB,GAAqB,gBAC1C,eAAgB,GAAO,WACzB,CACF,ECtDM,GAAoB,uBACpB,GAAwB,uBAE9B,SAAgB,IAAyB,CACvC,IAAM,EAAc,EAAkC,EAAa,YAAY,CAAC,EAC1E,CAAE,cAAe,GAAY,EAE7B,EAAoB,EACxB,EAAY,MAAM,IAClB,EAAY,MAAM,iBAClB,EAAa,KAAK,GAAa,KAAK,EAAE,CACxC,EAEM,EAAS,EAA6B,GAAe,OAAO,CAAC,EAC7D,EAAW,GAAY,IAAI,EAE3B,EAA6B,GAAW,QAAQ,EAAkB,MAAM,YAAa,EAAO,MAAM,QAAQ,SAAS,SAAS,EAAI,GAAwB,EAAiB,EAE/K,SAAS,GAAoC,CAkB3C,MAHA,EAdI,CAAC,EAAY,cAAgB,CAAC,EAAY,KAAK,iBAAmB,CAAC,EAAkB,cAIrF,CAAC,EAAS,eAGV,EAAS,kCAGT,GAIA,CAAC,EAAW,GAAU,kBAAkB,EAI9C,CAEA,MAAO,CACL,kCAAmC,EAAkC,CACvE,CACF,CClCA,SAAgB,IAA0B,CAExC,IAAM,EAAc,EAAkC,EAAa,YAAY,CAAC,EAC1E,CAAE,yBAAwB,aAAc,GAA2B,GAA0B,EAC7F,EAAY,EAChB,CAAC,CAAC,EAAY,MAAM,iBACpB,GAAiB,iBAAiB,IAAI,GAA6B,GAAiB,MAAM,CAAC,CAC7F,EACM,CAAE,cAAe,GAAY,EAE7B,EAAW,GAAY,IAAI,EAC3B,EAAuB,GAAkB,EACzC,EAAqB,GAAuB,EAC5C,CAAE,mBAAoB,GAAiB,EAE7C,SAAS,GAAwB,CAC/B,OACE,GACA,CAAC,EAAS,mBACV,EAAU,cACV,EAAY,YAEhB,CAEA,MAAO,CACL,YAAa,EAAW,GAAU,OAAO,EACzC,cAAe,EACf,UAAW,EAAU,MAAM,MAAQ,CAAC,EACpC,YAAa,EAAY,KACzB,sCAAuC,EAAqB,qBAC5D,kCAAmC,EAAmB,kCACtD,kBAAmB,EAAgB,GAAU,MAAM,EACnD,WACA,aAAc,EAAa,CAC7B,CACF,CCjCA,SAAgB,IAAqB,CACnC,IAAM,EAAkB,GAAwB,EAE1C,CAAE,QAAS,GAAsB,EACjC,CAAE,0BAA2B,GAAY,EAAgB,WAAW,EACpE,EAAc,GAAe,EAC7B,CAAE,YAAa,GAAgB,EAE/B,CAAE,EAAsB,GAAA,EAAkC,SAA+B,CAAC,CAAC,EAEjG,SAAS,EAAW,EAAgC,CAClD,EAAwB,CACtB,GAAG,EACH,GAAG,EAAK,QAAQ,EAAK,KAAS,CAAE,GAAG,GAAM,EAAI,IAAK,EAAK,GAAI,CAAC,CAAC,CAC/D,CAAC,EAED,EAAK,QAAQ,GAAO,CAClB,EAAI,WAAW,CAAsB,CACvC,CAAC,CACH,CAEA,IAAM,EAAkB,GAAe,gBAAgB,CAAC,CAAC,QACnD,EAA+C,CACnD,SAAU,EAAgB,SAC1B,kBACA,cAAe,EAAgB,cAC/B,UAAW,EAAgB,UAC3B,sCAAuC,EAAgB,sCACvD,kCAAmC,EAAgB,kCACnD,kBAAmB,EAAgB,iBACrC,EAEM,EAAA,EAAgC,iBAAiB,CAAe,EAEhE,EAAA,EAAwC,YACxC,CAAC,EAAgB,cAAgB,CAAC,EAAgB,YAAY,iBAC7D,EAAY,IAAM,GAAY,CAAC,EAAgB,YAC3C,CAAC,EAEO,GAAkB,OAAO,GACjC,CAAC,EAAqB,EAAU,KAAO,EAAU,UAAU,CAAgB,CAG7E,CAAA,CAAS,IAAI,IACX,CACL,GAAG,EACH,IAAK,EAAK,EAAU,GACtB,EACD,EACA,CAAE,EAAgB,aAAc,EAAsB,EAAM,EAAY,EAAU,EAAgB,WAAY,CAAC,EAGlH,SAAS,GAAqB,CAC5B,MAAO,CAAC,EAAgB,cAAgB,EAAY,KAAK,GAAO,CAAC,EAAI,GAAG,CAC1E,CAEA,MAAO,CACL,cACA,UAAW,EAAU,EACrB,YACF,CACF,CC/EA,IAAM,GAAU,GAEH,GAAoB,CAC/B,mBACE,EACA,EACA,EACA,EACqB,CACrB,IAAM,EAAkB,CACtB,MAAO,GACP,OAAQ,EACV,EAEA,GAAI,CAAC,EACH,OAAO,EAET,GAAI,IAAiB,UAAW,CAC9B,IAAM,EAAa,EAAc,sBAAsB,EACjD,EAAW,EAAY,sBAAsB,EAEnD,OAAQ,EAAR,CACE,IAAK,QAAS,CACZ,IAAM,EAAuC,CAC3C,KAAM,EAAW,MAAQ,GACzB,IAAM,EAAW,GACnB,EASA,OAPI,EAAW,IAAM,EAAS,OAAS,OAAO,YACrC,CACL,KAAM,EAAW,MAAQ,GACzB,IAAK,OAAO,YAAc,EAAS,OAAS,EAC9C,EAGK,CACT,CAEA,IAAK,eAMH,MAAO,CAJL,KAAM,EAAW,GAAK,EAAS,MAAQ,EAAW,OAClD,IAAK,EAAW,IAAM,EAAW,OAAS,EAGrC,EAGT,QACE,OAAO,CACX,CACF,CAGA,OAAO,CACT,CACF,wHE1CA,SAAgB,IAAwC,CACtD,GAAM,CAAE,cAAa,YAAW,cAAe,GAAmB,EAE5D,CAAE,EAAc,GAAA,EAA0B,SAAS,CAAC,EACpD,CAAE,EAAsB,GAAA,EAAkC,SAAkB,EAAK,EACjF,CAAE,EAAgB,GAAA,EAA4B,SAA8B,CAAC,CAAC,EAE9E,EAAa,EAAY,GAEzB,EAAA,EAAgB,OAAuB,IAAI,EAEjD,EAAM,cAAgB,CAChB,QAAa,CAAC,EAAY,QAAU,CAAC,GAAY,KAQrD,OALI,EAAW,gBACb,EAAW,IAAI,eAAe,CAAE,SAAU,QAAS,CAAC,EAEtD,EAAsB,EAEf,CACT,EAAG,CAAE,EAAW,EAAc,GAAY,GAAI,CAAC,EAE/C,EAAM,UAAU,EAAsB,CAAE,EAAW,EAAc,GAAY,IAAK,EAAQ,OAAQ,CAAC,EACnG,GAAkB,EAAsB,KAAM,CAAE,EAAW,EAAc,GAAY,IAAK,EAAQ,OAAQ,CAAC,EAE3G,EAAM,cAAgB,CACpB,GAAI,CAAC,EACH,OAEF,IAAM,MAAiB,EAAwB,EAAK,EAGpD,OAFA,EAAQ,QAAQ,iBAAiB,eAAgB,CAAQ,MAE5C,EAAQ,SAAS,oBAAoB,eAAgB,CAAQ,CAC5E,EAAG,CAAC,CAAoB,CAAC,EAGzB,EAAM,cAAgB,CAChB,IAAiB,GACnB,EAAgB,CAAC,CACrB,EAAG,CAAC,CAAW,CAAC,EAEhB,IAAM,EAA4B,CAAE,GAAI,GAAY,EAAG,EACjD,EAAqC,CACzC,WAAY,EAAW,MACvB,OAAQ,EAAW,WACnB,SAAU,EAAgB,YAC1B,WAAY,GAAY,oBACxB,aAAc,GAAa,EAC7B,EAEA,SAAS,GAAuB,CAC9B,GAAI,GAAa,CAAC,EAAY,QAAU,CAAC,EACvC,OAEF,IAAM,EAAM,GAAkB,mBAC5B,EAAW,IACX,EAAQ,QACR,EAAW,OACX,EAAW,SACb,EAEA,EAAkB,CAAG,CACvB,CAGA,SAAS,GAA8B,CACjC,GAAY,gBACd,EAAW,IAAI,UAAU,IAAI,EAAW,cAAc,EAExD,SAAS,KAAK,MAAM,UAAY,QAClC,CAGA,SAAS,GAA8B,CACjC,GAAY,gBACd,EAAW,IAAI,UAAU,OAAO,EAAW,cAAc,EAE3D,SAAS,KAAK,MAAM,UAAY,QAClC,CAEA,SAAS,GAAc,CACrB,EAAsB,EACtB,OAAO,SAAS,CAAE,IAAK,EAAG,SAAU,QAAS,CAAC,EAE9C,EAAa,EACb,EAAgB,CAAC,EAEjB,EAAW,CAAW,CACxB,CAEA,SAAS,GAAe,CACtB,EAAgB,cAAc,CAC5B,GAAG,EACH,OAAQ,WACV,EAAG,CACD,GAAG,EACH,cAAe,EAAc,QAC/B,CAAC,CACH,CAEA,SAAS,EAAU,EAAuB,EAAgC,CACxE,EAAgB,cAAc,CAC5B,GAAG,EACH,gBACA,QACF,EAAG,CACD,GAAG,EACH,cAAe,EAAc,IAC/B,CAAC,CACH,CAEA,SAAS,EAAU,EAAuB,CACxC,EAAgB,cAAc,CAC5B,GAAG,EACH,gBACA,OAAQ,QACV,EAAG,CACD,GAAG,EACH,cAAe,EAAc,IAC/B,CAAC,CACH,CAEA,SAAS,EAAiB,EAAwB,CAChD,EAAgB,CAAc,EAE1B,EAAiB,EACnB,EAAU,EAAgB,QAAQ,EAElC,EAAU,CAAc,CAE5B,CAEA,SAAS,GAAa,CACpB,IAAM,EAAW,EAAY,EAAe,GAE5C,GAAI,CAAC,GAAY,CAAC,GAAU,IAAK,CAC/B,EAAY,EACZ,MACF,CAEA,EAAgB,EAAe,CAAC,EAChC,EAAU,EAAe,EAAG,WAAW,CACzC,CAEA,SAAS,EAAoB,EAAsB,CACjD,EAAgB,cAAc,CAC5B,GAAG,EACH,OAAQ,eACR,KAAM,CACR,EAAG,CACD,GAAG,EACH,OAAQ,EAAW,IACrB,CAAC,CACH,CAEA,SAAS,GAAe,CACtB,EAAgB,cAAc,CAC5B,GAAG,EACH,OAAQ,OACV,EAAG,CACD,GAAG,EACH,cAAe,EAAc,QAC/B,CAAC,EAED,EAAY,CACd,CAEA,SAAS,GAAc,CACrB,EAAwB,EAAI,EAE5B,EAAgB,cAAc,CAC5B,GAAG,EACH,OAAQ,MACV,EAAG,CAAgB,CACrB,CAEA,GAAI,GAAa,CAAC,EAChB,OAAO,EAAA,EAAA,IAAA,CAAA,EAAA,SAAA,CAAI,CAAA,EAEb,IAAM,EAAO,EAAW,cAExB,OACE,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,MAAD,CACE,UAAW,kBAAkB,GAAO,KAAK,GAAG,EAAuB,GAAO,iBAAmB,KAC7F,MAAO,CAAE,GAAG,CAAe,EAC3B,IAAK,YAEL,EAAA,EAAA,IAAA,CAAC,EAAD,CACc,aACE,eACO,sBACrB,aAAc,EAAY,OAC1B,WAAY,EACZ,cAAe,CAChB,CAAA,CACE,CAAA,GACL,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,GAAO,KAAM,QAAS,CAAc,CAAA,CACpD,CAAA,CAAA,CAEN,iIElNA,SAAgB,IAA+B,CAC7C,OACE,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,GAAO,QAAe,CAAA,GACtC,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,GAAO,sBACrB,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,GAAO,iBACrB,EAAA,EAAA,IAAA,CAAC,KAAD,CAAA,UAAI,EAAA,EAAA,IAAA,CAAC,EAAD,CAAM,UAAU,kBAAkB,OAAO,SAAW,CAAA,CAAK,CAAA,CAC1D,CAAA,CACF,CAAA,GACL,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,GAAO,QAAe,CAAA,CACtC,CAAA,CAAA,CAEN,CC8CA,IAAa,GAA0B,uBACjC,GAA8B,0BAEpC,SAAS,GAAmB,EAAmB,EAAoB,CACjE,GAAM,CAAE,QAAS,GAAmB,GAAsB,CAAS,EAMnE,GAAgB,EAAiB,GAAS,eAAiB,IAAI,EAE/D,IAAM,EAAqB,GAAwC,EAAiB,GAAS,YAAc,IAAI,EAezG,CAAE,eAAc,gBAAe,gBAAiB,GAAY,CAChE,OAAA,EAdmB,YAAa,GAA0B,CACrD,GAGL,EAAmB,SAAS,EAAe,CACzC,OAAQ,EAAW,MACnB,WAAY,EAAW,OACvB,cAAe,EAAc,MAC7B,WAAY,EAAgB,mBAAmB,GAAgB,QAAQ,EACvE,SAAU,EAAgB,WAC5B,CAAC,CACH,EAAG,CAAC,CAAc,CAGhB,EACA,QAAS,GACT,WAAY,GACZ,SAAU,GAAiB,gBAAgB,CAAC,GAAa,CAAQ,CACnE,CAAC,EAED,MAAO,CACL,eACA,gBACA,eACA,gBACF,CACF,CAEA,SAAS,GAAmB,EAAmB,EAAkB,CAC/D,IAAM,EAAc,GAAe,EAE7B,EAAW,EAAY,GACvB,EAAW,EAAY,GACvB,EAAqB,EAAY,GACjC,EAAY,EAAY,GACxB,EAAiB,EAAY,IAC7B,EAAiB,GAAU,MAAM,EAEjC,CAAE,EAAU,GAAA,EAAsB,SAAS,CAAC,CAAc,EAEhE,SAAS,GAAuB,CAC1B,IAOA,GAAY,GAAY,IAC1B,EAAY,EAAI,CACpB,CA6BA,OAvBA,EAAM,cAAgB,CACpB,SAAS,KAAK,MAAM,UAAY,QAClC,EAAG,CAAC,CAAC,EAEL,EAAM,cAAgB,CACpB,EAAY,CAAC,CAAc,CAC7B,EAAG,CAAC,CAAc,CAAC,EAEnB,EAAM,cAAgB,CAChB,CAAC,IAAa,GAAsB,IACtC,EAAY,EAAI,CACpB,EAAG,CAAE,EAAoB,CAAe,CAAC,EAYlC,CACL,SAXe,GAAoB,mBACnC,EACA,EACA,EACA,EACA,EACA,EACA,CAIA,EACA,WACA,cACA,gBACF,CACF,CAeA,IAAM,GAA0B,GAA2D,CACzF,GAAM,CAAE,kBAAmB,GAAe,EACpC,EAAA,EAAgB,OAAoB,IAAI,EAG9C,GAAW,EACX,GAAmB,EAEnB,GAAM,CAAE,sBAAuB,GAAsB,EAE/C,EAAgB,GAAiB,EACjC,CAAC,GAAkB,GAAa,GAAc,gBAAgB,EAC9D,CAAC,GAAsB,GAAa,GAAc,oBAAoB,EACtE,CAAC,GAAsB,GAAqB,GAAc,8BAA8B,EACxF,CAAE,YAAa,GAAgB,EAE/B,EAAA,EAA6B,kBAAkB,EAE/C,GACJ,EAAQ,cAAgB,EAAY,eAChC,EAAQ,QAAgB,KACxB,EAAQ,QAAgB,cACzB,EAAQ,cAAgB,EAAY,OAEnC,CACJ,eACA,gBACA,eACA,kBACE,GAAmB,EAAU,EAAe,EAAe,WAAW,CAAC,EAErE,CACJ,WACA,WACA,cACA,kBACE,GAAmB,EAAU,EAAM,OAAO,EAExC,CAAE,MAAO,EAAU,UAAS,MAAO,GAAa,GAAkB,CACtE,SAAU,EAAS,MACnB,cAAe,EAAM,aACvB,CAAC,EAEK,EAAgB,EAAM,SAAW,EACjC,EAAgB,GAAiB,EAEjC,EAAa,EAAc,UAAY,EAAc,yBAA2B,GAAoB,KAEpG,CACJ,iCACA,2BACE,GAAoB,uBAAuB,EAAc,OAAS,oBAAoB,EAK1F,OAFA,GAAY,EAAc,0BADN,GACiC,CAAW,GAG9D,EAAA,EAAA,IAAA,CAAC,GAAD,CAAe,gBAAmB,GAAU,CAAE,MAAO,IAAI,CAAmB,CAAC,YAC3E,EAAA,EAAA,KAAA,CAAC,MAAD,CACE,GAAI,EAAa,CACf,KAAQ,SACR,aAAc,oDAChB,CAAC,EACD,UAAW,EAAa,uBAAuB,EAAI,EAAO,YAAc,YAL1E,EAOE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAU,IAAI,MAAQ,CAAA,GACtB,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,iBAAkB,GAAoB,WACtC,kBAAqB,EAAY,CAAC,CAAQ,EAChC,WACV,QAAS,EACT,WAAY,EAAM,WACT,SACV,CAAA,EACA,IACC,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,MAAO,EACG,WACV,SAAU,EAAS,MACH,gBACjB,CAAA,EAEF,GAAc,SAAW,IAAS,EAAA,EAAA,IAAA,CAAC,GAAD,CAAU,CAAA,GAC7C,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,IAAK,EAAS,UAAW,GAAG,EAAO,QAAQ,GAAG,EAAS,wBAA7D,EACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAkB,CAAA,GAClB,EAAA,EAAA,KAAA,CAAC,GAAuB,mBAAxB,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,GAAI,GAAyB,UAAW,GAAG,EAAO,WAAc,CAAA,GACrE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,mBAAmB,GAA4B,GAAG,EAAO,uBAA0B,CAAA,GACnG,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,GAAG,GAAsB,GAAG,aAAa,EAAO,UAAU,GAAG,EAAa,OAAS,eACjG,EAAA,EAAA,IAAA,CAAC,GAAD,CAAe,WAAY,WACxB,EAAM,YACM,CAAA,CACZ,CAAA,CACoC,CAAA,CAAA,GAC3C,EAAA,EAAA,IAAA,CAAC,GAAD,CAAa,CAAA,GACb,EAAA,EAAA,IAAA,CAAC,GAAD,CAAiB,CAAA,CACb,KACN,EAAA,EAAA,IAAA,CAAC,GAAD,CAAe,WAAY,YACxB,EAAM,UACM,CAAA,EACd,EAAS,WAAY,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,uBAAuB,EAAO,OAAQ,YAAe,EAAY,EAAI,CAAQ,CAAA,GACnH,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,GAAG,EAAO,WAAW,GAAG,EAAiB,EAAO,KAAO,GAAG,gBAAmB,CAAA,GAC7F,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,GAAG,EAAO,eAAe,GAAG,EAAqB,EAAO,KAAO,GAAG,gBAAmB,CAAA,GACrG,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,YAAhB,CACG,CAAC,CAAC,EAAM,aAAc,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,WAA0B,EAAM,UAAgB,CAAA,GACvF,EAAA,EAAA,IAAA,CAAC,GAAD,CAIE,iBAAkB,GAAoB,UACvC,CAAA,CACE,IACJ,GAAgB,IAAkB,EAAA,EAAA,IAAA,CAAC,GAAD,CAAW,CAAA,GAC9C,EAAA,EAAA,IAAA,CAAC,QAAD,CAAO,GAAI,EAAc,CAAE,aAAc,IAAK,CAAC,CAAI,CAAA,GACnD,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,MAAO,CAAE,QAAS,MAAO,WAAI,EAAM,WAAiB,CAAA,GACzD,EAAA,EAAA,IAAA,CAAC,GAAD,CAAsB,CAAA,GAGtB,EAAA,EAAA,IAAA,CAAC,GAAD,CAA2B,CAAA,GAC3B,EAAA,EAAA,IAAA,CAAC,GAAD,CAAoB,CAAA,GAEpB,EAAA,EAAA,IAAA,CAAC,GAAD,CAAa,CAAA,CACV,GACQ,CAAA,CAEnB,EAEA,SAAS,GAAwB,EAAwD,CACvF,GAAM,CAAE,SAAU,EAAmB,GAAG,GAAyB,EAuBjE,OArBK,GAsBH,EAAA,EAAA,IAAA,CAAC,GAAD,CAAU,MAAO,EAAM,gBACrB,EAAA,EAAA,IAAA,CAAC,GAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAA6B,mBAAoB,aAC/C,EAAA,EAAA,IAAA,CAAC,GAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAAC,EAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAwB,GAAI,CAAuB,CAAA,CACzB,CAAA,CACP,CAAA,CACN,CAAA,CACQ,CAAA,CACF,CAAA,CACF,CAAA,CACH,CAAA,CACD,CAAA,CACrB,CAAA,GAtCR,EAAA,EAAA,IAAA,CAAC,GAAD,CAAU,MAAO,EAAM,gBACrB,EAAA,EAAA,IAAA,CAAC,GAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAA6B,mBAAoB,aAC/C,EAAA,EAAA,IAAA,CAAC,GAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAAC,GAAD,CAAwB,GAAI,CAAuB,CAAA,CACzB,CAAA,CACP,CAAA,CACI,CAAA,CACF,CAAA,CACF,CAAA,CACH,CAAA,CACD,CAAA,CACrB,CAAA,CAwBhB"}