@clickview/lite 0.55.3-rc.2 → 0.56.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.
- package/dist/bundles.json +1 -1
- package/dist/css/{6341-lite-17d9d6716e.chunk.css → 6341-lite-f146164a09.chunk.css} +2 -2
- package/dist/css/{8784-lite-5a0ce019df.chunk.css → 8784-lite-caf4b7e145.chunk.css} +1 -1
- package/dist/css/{8945-lite-17d9d6716e.chunk.css → 8945-lite-f146164a09.chunk.css} +2 -2
- package/dist/css/{9355-lite-5a0ce019df.chunk.css → 9355-lite-caf4b7e145.chunk.css} +1 -1
- package/dist/scripts/{1169-f52e3a1569-lite.chunk.js → 1169-e4773094dc-lite.chunk.js} +2 -2
- package/dist/scripts/{1169-f52e3a1569-lite.chunk.js.map → 1169-e4773094dc-lite.chunk.js.map} +1 -1
- package/dist/scripts/2992-2b265c0b4c-lite.chunk.js +2 -0
- package/dist/scripts/2992-2b265c0b4c-lite.chunk.js.map +1 -0
- package/dist/scripts/{6102-6baf5789b9-lite.chunk.js → 6102-c7d7b15dd3-lite.chunk.js} +3 -3
- package/dist/scripts/{6102-6baf5789b9-lite.chunk.js.map → 6102-c7d7b15dd3-lite.chunk.js.map} +1 -1
- package/dist/scripts/{6341-3a1432093d-lite.chunk.js → 6341-f07132fa7c-lite.chunk.js} +1 -1
- package/dist/scripts/{6341-3a1432093d-lite.chunk.js.map → 6341-f07132fa7c-lite.chunk.js.map} +1 -1
- package/dist/scripts/{8784-5f2be81ef9-lite.chunk.js → 8784-d6862c97bc-lite.chunk.js} +1 -1
- package/dist/scripts/{8784-5f2be81ef9-lite.chunk.js.map → 8784-d6862c97bc-lite.chunk.js.map} +1 -1
- package/dist/scripts/{8945-20a061665b-lite.chunk.js → 8945-3ea21e765e-lite.chunk.js} +1 -1
- package/dist/scripts/{8945-20a061665b-lite.chunk.js.map → 8945-3ea21e765e-lite.chunk.js.map} +1 -1
- package/dist/scripts/{9355-9258c8643d-lite.chunk.js → 9355-44d72e25e0-lite.chunk.js} +1 -1
- package/dist/scripts/{9355-9258c8643d-lite.chunk.js.map → 9355-44d72e25e0-lite.chunk.js.map} +1 -1
- package/dist/scripts/{9569-c5cef8bb45-lite.chunk.js → 9569-c6292540d7-lite.chunk.js} +2 -2
- package/dist/scripts/9569-c6292540d7-lite.chunk.js.map +1 -0
- package/dist/scripts/bundle-dae1d0bed3.min.js +3 -0
- package/dist/scripts/{bundle-7b013435dc.min.js.map → bundle-dae1d0bed3.min.js.map} +1 -1
- package/package.json +1 -1
- package/dist/scripts/2992-c5bec5b43f-lite.chunk.js +0 -2
- package/dist/scripts/2992-c5bec5b43f-lite.chunk.js.map +0 -1
- package/dist/scripts/9569-c5cef8bb45-lite.chunk.js.map +0 -1
- package/dist/scripts/bundle-7b013435dc.min.js +0 -3
- /package/dist/scripts/{6102-6baf5789b9-lite.chunk.js.LICENSE.txt → 6102-c7d7b15dd3-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{bundle-7b013435dc.min.js.LICENSE.txt → bundle-dae1d0bed3.min.js.LICENSE.txt} +0 -0
package/package.json
CHANGED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";(self.webpackChunk_clickview_lite=self.webpackChunk_clickview_lite||[]).push([[2992],{63649:(e,a,t)=>{t.d(a,{X:()=>c});var i=t(32735);const r={video:"ekpg6",notice:"lQs4F",heading:"Gt6uV",interaction:"LEfYX",button:"caHP7",edit:"de4DP",questions:"XelbS"};function c(){return i.createElement("div",{className:"px-3 w-100"},i.createElement("div",{className:"partial-loading-background ".concat(r.notice)}),i.createElement("div",{className:"partial-loading-background mb-3 ".concat(r.video)},i.createElement("div",{className:"partial-loading-background ".concat(r.questions)})),i.createElement("div",{className:"partial-loading-background mb-3 ".concat(r.heading)}),i.createElement("div",null,Array(5).fill(null).map((function(e,a){return i.createElement("div",{key:a,className:"partial-loading-background my-2 ".concat(r.interaction)})}))))}},38280:(e,a,t)=>{t.r(a),t.d(a,{SharedInteractiveView:()=>j});var i=t(32735),r=t(20354),c=t(30439),n=t(4594),d=t(60051),s=t(16714),o=t(39151),l=t(1666),u=t(20768),v=t(47812),m=t(31949),h=t(26304),p=t(91286),b=t(22902),g=t(79612),k=t(76753),y=t(51855),I=t(7179),P=t(36873),f=t(44110),E=t(53073),F=t(97816),C=t(63649),V=t(84062),q=t(25758),w=t(57426),B=t(16857),N={notFound:w.k,forbidden:{privacy:B.m}};function M(e){return e._parentClip||e._parentVideo}function j(e){var a,t,w,j=(0,b.T)().hasPermissions,x=r.a.useBasicFetch(o.L.config()),G=r.a.useBasicFetch(m.N.token()),S=(0,y.G)().isPlugin,_=r.a.useBasicFetch(m.N.currentUser()),A=r.a.useBasicFetch(u.b.sharedInteractiveMetadata(e.objectId,e.shareId)),T=r.a.useBasicFetch(c.o.getShareObject(e.shareId)),U=T.data&&(T.data.objectTypeId===n.E.Interactive?v.k.createViewKey(e.shareId,d.f.Share):v.k.createViewKey(e.objectId,d.f.MasterObject,e.shareId)),X=r.a.useBasicFetch(U),K=(0,f.i)(),L=r.a.useBasicFetch((null===(a=_.data)||void 0===a?void 0:a.isAuthenticated)&&l.h.yearGroups(_.data.customerId)),O=(0,E.f)(),D=r.a.useBasicFetch(O&&A.data&&u.b.interactive(A.data.interactiveId)),H=r.a.useBasicFetch(O&&A.data&&u.b.videoInteractives(M(A.data).id)),Q=(0,P.k)({video:A.data,context:e.queryParams.context,contextId:e.queryParams.contextId,moviesAndTv:e.queryParams.mtv,currentUser:_.data}),Y=M(A.data);(0,p.v)(A,N),(0,h.b)(A,{private:B.m}),(0,I.P)({id:e.objectId,app:"interactives",shareId:e.shareId}),(0,F.V)(null!==(t=Q.videos)&&void 0!==t?t:[]),(0,g.M)(k.CG.getInteractiveMetadata({content:A.data}));var z=A.data&&x.hasCompleted&&_.hasCompleted&&(!O||D.hasCompleted)&&T.hasCompleted&&X.hasCompleted&&G.hasCompleted;return O?z?i.createElement(q.x,{sourceVideo:Y,config:x.data,currentUser:_.data,queryParams:e.queryParams,interactive:A.data,interactives:H.data,isPreviewPreventScrubbingEnabled:D.data.preventScrubbing,yearGroups:L.data,audiences:K.data,relatedVideos:Q,canManageVideoAccess:j(s.C.ManageVideoAccess),isPlugin:S}):i.createElement(C.X,null):z?i.createElement(V.M,{interactive:A.data,currentUser:_.data,config:x.data,audiences:K.data,yearGroups:L.data,queryParams:e.queryParams,viewKey:X.data,relatedVideos:Q,shareLink:T.data,startTime:null===(w=e.queryParams)||void 0===w?void 0:w.t,isPlugin:S,token:G.data}):i.createElement(i.Fragment,null)}}}]);
|
|
2
|
-
//# sourceMappingURL=2992-c5bec5b43f-lite.chunk.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scripts/2992-c5bec5b43f-lite.chunk.js","mappings":"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","sources":["file:///app/packages/projects/lite/src/apps/interactives/components/interactive-partial-loading/interactive-partial-loading.scss","file:///app/packages/projects/lite/src/apps/interactives/components/interactive-partial-loading/InteractivePartialLoading.tsx","file:///app/packages/projects/lite/src/apps/share/views/shared-interactive/SharedInteractiveView.tsx"],"sourcesContent":["// extracted by mini-css-extract-plugin\nexport default {\"video\":\"ekpg6\",\"notice\":\"lQs4F\",\"heading\":\"Gt6uV\",\"interaction\":\"LEfYX\",\"button\":\"caHP7\",\"edit\":\"de4DP\",\"questions\":\"XelbS\"};","import React from 'react';\n\nimport styles from './interactive-partial-loading.scss';\n\nexport function InteractivePartialLoading(): React.ReactElement {\n return (\n <div className='px-3 w-100'>\n <div className={`partial-loading-background ${styles.notice}`} />\n <div className={`partial-loading-background mb-3 ${styles.video}`}>\n <div className={`partial-loading-background ${styles.questions}`}></div>\n </div>\n <div className={`partial-loading-background mb-3 ${styles.heading}`}></div>\n <div>\n {Array(5).fill(null).map((_, i) => (\n <div key={i} className={`partial-loading-background my-2 ${styles.interaction}`}></div>\n ))}\n </div>\n </div>\n );\n}","import React from 'react';\n\nimport { Flight } from 'libs/common/flight';\n\nimport { ShareRequests } from 'libs/shared/apps/share/flight-requests/ShareRequests';\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { MediaIdType } from 'libs/shared/enums/MediaIdType';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { CustomerRequests } from 'libs/shared/flight-requests/CustomerRequests';\nimport { InteractiveRequests } from 'libs/shared/flight-requests/InteractiveRequests';\nimport { PlayerRequests } from 'libs/shared/flight-requests/PlayerRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useCannotConsumeError } from 'libs/shared/hooks/useCannotConsumeError';\nimport { useHandleObjectError } from 'libs/shared/hooks/UseHandleObjectError';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\nimport { Clip, Config, CurrentUser, Interactive, InteractiveMetadata, PlayerViewKey, UnionShareObject, Video, YearGroup } from 'libs/shared/interfaces';\nimport { AuthToken } from 'libs/shared/interfaces/models/AuthToken';\nimport { PageMetadataHelper } from 'libs/shared/utils/PageMetadataHelper';\n\nimport { usePluginHelper } from 'shared/hooks/use-plugin-helper/usePluginHelper';\nimport { useDeepLinks } from 'shared/hooks/useDeepLinks';\nimport { useGetRelatedVideos } from 'shared/hooks/useGetRelatedVideos';\nimport { usePresentationAudiences } from 'shared/hooks/usePresentationAudiences';\nimport { useShouldPreviewInteractive } from 'shared/hooks/useShouldPreviewInteractive';\nimport { useVideoMixin } from 'shared/hooks/useVideoMixin';\n\nimport { InteractivePartialLoading } from 'apps/interactives/components/interactive-partial-loading/InteractivePartialLoading';\nimport { PlayInteractive } from 'apps/interactives/components/play-interactive/PlayInteractive';\nimport { PreviewInteractive } from 'apps/interactives/components/preview-interactive/PreviewInteractive';\nimport { ShareLinkNotFoundError } from 'apps/share/errors/share-link-not-found/ShareLinkNotFoundError';\nimport { ShareLinkPrivateError } from 'apps/share/errors/share-link-private/ShareLinkPrivateError';\nimport { ShareLinkViewProps } from 'apps/share/interfaces/ShareLinkViewProps';\n\nconst videoErrors = {\n notFound: ShareLinkNotFoundError,\n forbidden: {\n privacy: ShareLinkPrivateError\n }\n};\n\nfunction getSourceVideo(interactive: InteractiveMetadata): Clip | Video {\n return interactive._parentClip || interactive._parentVideo;\n}\n\nexport function SharedInteractiveView(props: ShareLinkViewProps): JSX.Element {\n const { hasPermissions } = usePermissions();\n\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n const token = Flight.useBasicFetch<AuthToken>(UserRequests.token());\n\n const { isPlugin } = usePluginHelper();\n\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const interactiveMetadata = Flight.useBasicFetch<InteractiveMetadata>(\n InteractiveRequests.sharedInteractiveMetadata(props.objectId, props.shareId)\n );\n\n const shareLink = Flight.useBasicFetch<UnionShareObject>(\n ShareRequests.getShareObject(props.shareId)\n );\n\n /**\n * If the shareLink type isn't an interactive, then it's a playlist and needs to be\n * used as context for fetching\n */\n const viewKeyRequest = shareLink.data && (shareLink.data.objectTypeId === MasterType.Interactive\n ? PlayerRequests.createViewKey(props.shareId, MediaIdType.Share)\n : PlayerRequests.createViewKey(props.objectId, MediaIdType.MasterObject, props.shareId));\n const viewKey = Flight.useBasicFetch<PlayerViewKey>(viewKeyRequest);\n const audiences = usePresentationAudiences();\n const yearGroups = Flight.useBasicFetch<YearGroup[]>(\n currentUser.data?.isAuthenticated && CustomerRequests.yearGroups(currentUser.data.customerId)\n );\n\n /**\n * Authenticated staff with Lite product access get the interactive \"Preview\" view instead\n * of the usual play view.\n */\n const shouldPreviewInteractive = useShouldPreviewInteractive();\n const interactive = Flight.useBasicFetch<Interactive>(\n shouldPreviewInteractive && interactiveMetadata.data &&\n InteractiveRequests.interactive(interactiveMetadata.data.interactiveId)\n );\n const interactives = Flight.useBasicFetch<InteractiveMetadata[]>(\n shouldPreviewInteractive && interactiveMetadata.data &&\n InteractiveRequests.videoInteractives(getSourceVideo(interactiveMetadata.data).id)\n );\n\n const relatedVideos = useGetRelatedVideos({\n video: interactiveMetadata.data,\n context: props.queryParams.context,\n contextId: props.queryParams.contextId,\n moviesAndTv: props.queryParams.mtv,\n currentUser: currentUser.data\n });\n const sourceVideo = getSourceVideo(interactiveMetadata.data);\n\n useHandleObjectError(interactiveMetadata, videoErrors);\n useCannotConsumeError(interactiveMetadata, { private: ShareLinkPrivateError });\n useDeepLinks({ id: props.objectId, app: 'interactives', shareId: props.shareId });\n useVideoMixin(relatedVideos.videos ?? []);\n useSetPageMetadata(PageMetadataHelper.getInteractiveMetadata({ content: interactiveMetadata.data }));\n\n const hasLoaded = (\n interactiveMetadata.data &&\n config.hasCompleted &&\n currentUser.hasCompleted &&\n (!shouldPreviewInteractive || interactive.hasCompleted) &&\n shareLink.hasCompleted &&\n viewKey.hasCompleted &&\n token.hasCompleted\n );\n\n if (shouldPreviewInteractive) {\n // For staff, the interactive is previewed\n if (!hasLoaded)\n return <InteractivePartialLoading />;\n\n return (\n <PreviewInteractive\n sourceVideo={sourceVideo}\n config={config.data}\n currentUser={currentUser.data}\n queryParams={props.queryParams}\n interactive={interactiveMetadata.data}\n interactives={interactives.data}\n isPreviewPreventScrubbingEnabled={interactive.data.preventScrubbing}\n yearGroups={yearGroups.data}\n audiences={audiences.data}\n relatedVideos={relatedVideos}\n canManageVideoAccess={hasPermissions(PermissionName.ManageVideoAccess)}\n isPlugin={isPlugin}\n />\n );\n }\n\n if (!hasLoaded)\n return <></>;\n\n return (\n <PlayInteractive\n interactive={interactiveMetadata.data}\n currentUser={currentUser.data}\n config={config.data}\n audiences={audiences.data}\n yearGroups={yearGroups.data}\n queryParams={props.queryParams}\n viewKey={viewKey.data}\n relatedVideos={relatedVideos}\n shareLink={shareLink.data}\n startTime={props.queryParams?.t}\n isPlugin={isPlugin}\n token={token.data}\n />\n );\n}"],"names":["InteractivePartialLoading","className","Array","fill","map","_","i","key","videoErrors","notFound","forbidden","privacy","getSourceVideo","interactive","_parentClip","_parentVideo","SharedInteractiveView","props","hasPermissions","config","token","isPlugin","currentUser","interactiveMetadata","objectId","shareId","shareLink","viewKeyRequest","data","objectTypeId","viewKey","audiences","yearGroups","isAuthenticated","customerId","shouldPreviewInteractive","interactiveId","interactives","id","relatedVideos","video","context","queryParams","contextId","moviesAndTv","mtv","sourceVideo","private","app","videos","content","hasLoaded","hasCompleted","isPreviewPreventScrubbingEnabled","preventScrubbing","canManageVideoAccess","startTime","t"],"sourceRoot":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scripts/9569-c5cef8bb45-lite.chunk.js","mappings":"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","sources":["file:///app/packages/libs/common/src/react/utils/PortalHelper.ts","file:///app/packages/libs/shared/src/components/breadcrumbs/Breadcrumbs.tsx","file:///app/packages/libs/shared/src/components/copyright-disclaimer/copyright-disclaimer.scss","file:///app/packages/libs/shared/src/components/copyright-disclaimer/CopyrightDisclaimer.tsx","file:///app/packages/libs/shared/src/components/expandable-text/expandable-text.scss","file:///app/packages/libs/shared/src/components/expandable-text/ExpandableText.tsx","file:///app/packages/libs/shared/src/hooks/useExpandableTextButton.ts","file:///app/packages/libs/shared/src/components/play-page-v2/clips-widget/ClipWidgetItemV2.tsx","file:///app/packages/libs/shared/src/components/play-page-v2/clips-widget/PlayPageClips.tsx","file:///app/packages/libs/shared/src/components/play-page-v2/details/video-description/VideoDescription.tsx","file:///app/packages/libs/shared/src/components/play-page-v2/details/video-details.scss","file:///app/packages/libs/shared/src/components/play-page-v2/details/VideoDetailsV2.tsx","file:///app/packages/libs/shared/src/components/play-page-v2/glance/VideoAtAGlanceUtilsV2.ts","file:///app/packages/libs/shared/src/components/play-page-v2/glance/points-of-interest-list/points-of-interest-list.scss","file:///app/packages/libs/shared/src/components/play-page-v2/glance/points-of-interest-list/PointsOfInterestList.tsx","file:///app/packages/libs/shared/src/components/play-page-v2/glance/VideoAtAGlanceV2.tsx","file:///app/packages/libs/shared/src/components/play-page-v2/interactives-widget/InteractiveWidgetItemV2.tsx","file:///app/packages/libs/shared/src/components/play-page-v2/interactives-widget/PlayPageInteractives.tsx","file:///app/packages/libs/shared/src/components/play-page-v2/resources-widget/PlayPageResources.tsx","file:///app/packages/libs/shared/src/components/play-page-v2/resources-widget/resource-widget-item.scss","file:///app/packages/libs/shared/src/components/play-page-v2/resources-widget/ResourceWidgetItemV2.tsx","file:///app/packages/libs/shared/src/components/table-of-contents-list/table-of-contents-list.scss","file:///app/packages/libs/shared/src/components/table-of-contents-list/TableOfContentsList.tsx","file:///app/packages/libs/shared/src/hooks/useTableOfContentsActiveHeading.tsx","file:///app/packages/libs/shared/src/utils/DownloadHelper.ts","file:///app/packages/projects/lite/src/shared/components/play-page/components/table-of-contents/table-of-contents.scss","file:///app/packages/projects/lite/src/shared/components/play-page/components/table-of-contents/TableOfContents.tsx","file:///app/packages/projects/lite/src/shared/views/play/v2/PlayPageUtilV2.tsx","file:///app/packages/projects/lite/src/shared/views/play/v2/hooks/usePlayPageTableOfContent.ts","file:///app/packages/projects/lite/src/shared/constants/PlayPageSectionsOrder.ts","file:///app/packages/projects/lite/src/shared/views/play/v2/hooks/useSectionHeadings.ts","file:///app/packages/projects/lite/src/shared/views/play/v2/hooks/useShouldShowTableOfContents.ts","file:///app/packages/libs/shared/src/components/play-page-v2/glance/video-at-a-glance.scss"],"sourcesContent":["import React from 'react';\nimport { createPortal } from 'react-dom';\n\nexport const PortalHelper = {\n renderInPortalIfExists(component: React.ReactElement, portalContainer: Element | null): React.ReactElement {\n if (portalContainer)\n return createPortal(component, portalContainer);\n\n return component;\n }\n};","import * as React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { MediaQueryStrings } from 'libs/shared/enums/MediaQueries';\nimport { useMediaQuery } from 'libs/shared/hooks/UseMediaQuery';\nimport { PartialLoadingHelper } from 'libs/shared/utils/PartialLoadingHelper';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport { SvgContainer, SvgContainerSize } from '../svg-container/SvgContainer';\n\nconst namespace = 'shared.breadcrumbComponent';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nconst COLLAPSE_CHARACTER_COUNT = 64;\n\nexport interface Breadcrumb {\n name: string;\n appLink?: Core.AppLink;\n active?: boolean;\n}\n\ninterface BreadcrumbItemProps {\n breadcrumb: Breadcrumb;\n withBackIcon?: boolean;\n}\n\nexport const BreadcrumbItem = React.forwardRef((\n props: BreadcrumbItemProps,\n ref: React.ForwardedRef<HTMLElement>\n) => {\n const { breadcrumb: { name, appLink, active }, withBackIcon } = props;\n return (\n <li className={`breadcrumb-item${active ? ' active' : ''}`}>\n {active\n ? <strong>{name}</strong>\n : <AppLink appLink={appLink} ref={ref}>\n {withBackIcon && <SvgContainer svgName={cvSvgLibrary.ChevronLeft} size={SvgContainerSize.Small} />}\n <span className={withBackIcon ? 'ms-2' : ''}>{name}</span>\n </AppLink>\n }\n </li>\n );\n});\n\ninterface BreadcrumbsProps {\n breadcrumbs: Breadcrumb[];\n}\n\nexport const Breadcrumbs = ({ breadcrumbs }: BreadcrumbsProps) => {\n const isMobile = useMediaQuery(MediaQueryStrings.XS);\n\n const length = breadcrumbs?.length || 0;\n \n const [ collapse, setCollapse ] = React.useState(false);\n const [ shouldFocus, setShouldFocus ] = React.useState(false);\n const expandRef = React.useRef<HTMLElement>();\n\n React.useEffect(() => {\n const characterLength = breadcrumbs?.reduce((prev, next) => prev + next.name.length, 0) ?? 0;\n\n if (length > 4 && characterLength > COLLAPSE_CHARACTER_COUNT)\n setCollapse(true);\n }, [breadcrumbs?.length]);\n\n /**\n * Focus our first expanded item the first time it appears.\n */\n React.useLayoutEffect(() => {\n if (shouldFocus)\n expandRef.current?.focus();\n }, [ expandRef.current, shouldFocus ]);\n\n function onClickExpand() {\n setCollapse(false);\n setShouldFocus(true);\n }\n\n if (!length || (isMobile && length < 2))\n return <></>;\n\n if (isMobile)\n return (\n <nav aria-label='breadcrumb'>\n <ol className='breadcrumb m-0 p-0'>\n <BreadcrumbItem breadcrumb={breadcrumbs[length - 2]} withBackIcon />\n </ol>\n </nav>\n );\n\n const first = <BreadcrumbItem breadcrumb={breadcrumbs[0]} />;\n const second = length > 2 ? <BreadcrumbItem breadcrumb={breadcrumbs[1]} /> : <></>;\n const secondLast = length > 3 ? <BreadcrumbItem breadcrumb={breadcrumbs[length - 2]} /> : <></>;\n const last = length > 1 ? <BreadcrumbItem breadcrumb={breadcrumbs[length - 1]} /> : <></>;\n const rest = breadcrumbs.slice(2, length - 2);\n\n return (\n <nav aria-label='breadcrumb'>\n <ol className='breadcrumb m-0 p-0'>\n {first}\n {second}\n {collapse ?\n <li className='breadcrumb-item'>\n <button\n className='btn-link'\n onClick={onClickExpand}\n aria-label={getPhrase('expand')}\n >\n ...\n </button>\n </li> :\n rest.map((breadcrumb, idx) => (\n <BreadcrumbItem\n key={idx}\n breadcrumb={breadcrumb}\n ref={idx === 0 ? expandRef : null}\n />\n ))\n }\n {secondLast}\n {last}\n </ol>\n </nav>\n );\n};\n\nexport const PartialBreadcrumbs = React.memo(function({ numItems = 3 }: { numItems?: number; }) {\n const isMobile = useMediaQuery(MediaQueryStrings.XS);\n\n if (isMobile) {\n return (\n <div className='partial-loading-background' style={{ height: '1.3125rem', width: '6rem' }} />\n );\n }\n\n return (\n <nav aria-label='breadcrumb'>\n <ol className='breadcrumb m-0 p-0'>\n {PartialLoadingHelper.getPartialLoadingItems({ numItems }).map(({ width }, idx) => (\n <li key={idx} className='breadcrumb-item'>\n <span className='d-inline-block partial-loading-background' style={{ width }} dangerouslySetInnerHTML={{ __html: ' ' }} />\n </li>\n ))}\n </ol>\n </nav>\n );\n});","// extracted by mini-css-extract-plugin\nexport default {\"copyrightDisclaimer\":\"z8YoI\",\"overlayContainer\":\"eJDbJ\"};","import React from 'react';\nimport { Overlay } from 'react-bootstrap';\nimport { Placement } from 'react-bootstrap/esm/types';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { useHoverIntent } from 'libs/shared/hooks/UseHover';\n\nimport styles from './copyright-disclaimer.scss';\n\nconst namespace = 'shared.copyrightDisclaimer';\n\nconst CONTAINER_HEIGHT = 150; // px\n\ninterface CopyrightDisclaimerProps {\n placement: Placement;\n overflowPlacement?: Placement;\n className?: string;\n phraseClassName?: string;\n}\n\nexport function CopyrightDisclaimer(props: CopyrightDisclaimerProps) {\n const [ ref, isHovering ] = useHoverIntent<HTMLDivElement>({});\n\n function preventOverflow() {\n const spaceBelow = document.documentElement.clientHeight - ref.current?.getBoundingClientRect().bottom;\n\n return spaceBelow < CONTAINER_HEIGHT;\n }\n\n return (\n <div ref={ref} className={props.className}>\n <p className={`${styles.copyrightDisclaimer} ${props.phraseClassName ?? 'mb-1'}`}><Text namespace={namespace} phrase='copyrightDisclaimer' /></p>\n <Overlay\n target={ref.current}\n show={isHovering}\n placement={props.overflowPlacement && preventOverflow() ? props.overflowPlacement : props.placement}\n >\n <div className={`${styles.overlayContainer} mw-100 bg-white border rounded-3 p-2`}>\n <p><Text namespace={namespace} phrase='warning' /></p>\n <p className='fw-semibold mb-0'><Text namespace={namespace} phrase='sharing' /></p>\n </div>\n </Overlay>\n </div>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"text\":\"wLJpg\",\"collapsed\":\"ZxMAG\",\"seeMore\":\"x5t0p\"};","import React from 'react';\n\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { useExpandableTextButton } from 'libs/shared/hooks/useExpandableTextButton';\n\nimport styles from './expandable-text.scss';\n\ninterface ExpandableTextProps {\n children: (props: {expanded: boolean}) => JSX.Element;\n lines?: number;\n}\n\nconst namespace = 'shared.expandableText';\n\nexport function ExpandableText(props: ExpandableTextProps): JSX.Element {\n const { lines = 2 } = props;\n const [ expanded, setExpanded ] = React.useState(false);\n\n const { containerRef, showButton } = useExpandableTextButton();\n const TextComponent = props.children;\n\n return (\n <div className='d-flex overflow-hidden'>\n <div\n style={{ '--lines': lines } as unknown as React.CSSProperties}\n className={`${expanded ? '' : styles.collapsed} ${styles.text}`} ref={containerRef}>\n {(!expanded && showButton) && (\n <DivButton\n onClick={() => setExpanded(true)}\n className={`ms-1 text-info hover-text-underline ${styles.seeMore}`}\n >\n <Text namespace={namespace} phrase='seeMore' />\n </DivButton>\n )}\n\n <TextComponent expanded={expanded} />\n\n {expanded && (\n <DivButton\n onClick={() => setExpanded(false)}\n className={`ms-1 text-info hover-text-underline d-inline`}\n >\n <Text namespace={namespace} phrase='seeLess' />\n </DivButton>\n )}\n </div>\n </div>\n );\n}","import React from 'react';\n\nimport { useResizeListener } from 'libs/shared/hooks/UseResizeListener';\n\nexport function useExpandableTextButton() {\n const containerRef = React.useRef<HTMLDivElement>(null);\n\n const memoClientHeight = React.useRef<number>(0);\n\n React.useEffect(() => {\n if (containerRef.current?.clientHeight)\n // memo the initial clientHeight, cuz after expand and collapse the clientHeight will change\n memoClientHeight.current = containerRef.current.clientHeight;\n }, []);\n\n const [ showButton, setShowButton ] = React.useState(containerRef.current?.scrollHeight > memoClientHeight.current);\n\n useResizeListener(() => {\n if (containerRef.current?.clientHeight) {\n // update memo value on resize\n memoClientHeight.current = containerRef.current.clientHeight;\n setShowButton(containerRef.current?.scrollHeight > memoClientHeight.current);\n }\n });\n\n React.useEffect(() => {\n if (containerRef.current?.scrollHeight) {\n setShowButton(containerRef.current?.scrollHeight > memoClientHeight.current);\n }\n }, [ containerRef.current?.scrollHeight, memoClientHeight.current ]);\n\n return { containerRef, showButton };\n}","import React from 'react';\n\nimport { ThumbnailText } from 'libs/shared/components/thumbnails/thumbnail-text/ThumbnailText';\nimport { VideoThumbnail } from 'libs/shared/components/thumbnails/video/VideoThumbnail';\nimport { FixedWidgetItemProps } from 'libs/shared/components/widgets/items/FixedWidgetItemProps';\nimport { ThumbnailTextPosition } from 'libs/shared/enums/ThumbnailTextPosition';\nimport { useMergeAudiences } from 'libs/shared/hooks/UseMergeAudiences';\nimport { CanFavouriteFunc, Clip, FavouriteFunc, PresentationAudience, YearGroup } from 'libs/shared/interfaces';\n\nexport interface ClipWidgetItemV2Props extends FixedWidgetItemProps<Clip> {\n imageCdnUrl: string;\n setFavourite: FavouriteFunc;\n canFavourite: CanFavouriteFunc;\n audiences: PresentationAudience[];\n yearGroups: YearGroup[];\n isPlugin: boolean;\n showOwner?: boolean;\n}\n\nexport const ClipWidgetItemV2 = React.memo(function(props: ClipWidgetItemV2Props): JSX.Element {\n const { data: clip, thumbnailSize, preloadImage, getAppLink } = props;\n const mergedAudience = useMergeAudiences(clip.subjectPresentationAudiences?.data, props.audiences);\n\n return (\n <div className={`flex-shrink-0 px-1 col-6 col-sm-4`}>\n <VideoThumbnail\n type='static'\n textPosition={ThumbnailTextPosition.Independent}\n video={clip}\n appLink={getAppLink(clip)}\n imageOptions={{ size: thumbnailSize }}\n preload={preloadImage}\n analyticsData={props.analyticsData}\n analyticsOptions={props.analyticsOptions}\n setFavourite={props.setFavourite}\n canFavourite={props.canFavourite}\n imageCdnUrl={props.imageCdnUrl}\n audience={mergedAudience}\n hideDuration={false}\n isPlugin={props.isPlugin}\n showOwner={props.showOwner}\n />\n\n <div className='mt-2'>\n <ThumbnailText\n {...props}\n video={clip}\n appLink={props.getAppLink(clip)}\n />\n </div>\n </div>\n );\n});","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { TextHelper } from 'libs/common/react/utils/TextHelper';\n\nimport { FixedWidget } from 'libs/shared/components/widgets/fixed-widget';\nimport { WidgetContents } from 'libs/shared/enums/WidgetContents';\nimport { CanFavouriteFunc, Clip, FavouriteFunc, PresentationAudience, Video, YearGroup } from 'libs/shared/interfaces';\nimport { PlayPageAnchor } from 'libs/shared/interfaces/PlayPageAnchor';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nimport { ClipWidgetItemV2, ClipWidgetItemV2Props } from './ClipWidgetItemV2';\n\nconst namespace = 'shared.playPageClipsV2';\n\ninterface PlayPageClipsProps {\n video: Video | Clip;\n clips: Clip[];\n canViewClips: boolean;\n yearGroups: YearGroup[];\n audiences: PresentationAudience[];\n imageCdnUrl: string;\n setFavourite: FavouriteFunc;\n canFavourite: CanFavouriteFunc;\n analyticsData: HashObject;\n headingRef?: React.MutableRefObject<Map<PlayPageAnchor, HTMLElement>>;\n isPlugin: boolean;\n}\n\nexport function PlayPageClips(props: PlayPageClipsProps): JSX.Element {\n if (!props.canViewClips || !props.clips?.length)\n return <></>;\n\n const parentIsVideo = VideoHelper.isVideo(props.video);\n\n function getAppLink() {\n if (VideoHelper.isVideo(props.video)) {\n return {\n action: Actions.Videos.VIDEO_CLIPS,\n application: AppChannels.VIDEOS,\n args: [ props.video.id, TextHelper.slugify(props.video.name) ]\n };\n }\n return {\n action: Actions.Clips.CLIP_CLIPS,\n application: AppChannels.CLIPS,\n args: [ props.video.id, TextHelper.slugify(props.video.name) ]\n };\n }\n\n const title = LanguageService.getPhrase(\n namespace,\n parentIsVideo ? 'clips' : 'otherClips',\n { count: props.clips.length }\n );\n\n return (\n <section\n className='play-page-section'\n id={PlayPageAnchor.Clips}\n ref={el => {\n (el && props.headingRef?.current) && props.headingRef.current.set(PlayPageAnchor.Clips, el);\n }}\n >\n <FixedWidget<ClipWidgetItemV2Props>\n name={title}\n contents={WidgetContents.ClipsV2}\n collection={props.clips}\n prefetched\n getChildAppLink={(clip: Clip) => {\n return {\n application: AppChannels.CLIPS,\n action: Actions.Clips.PLAY_CLIP,\n args: [ clip.id, TextHelper.slugify(clip.name) ]\n };\n }}\n appLink={getAppLink()}\n childComponent={ClipWidgetItemV2}\n extraChildComponentProps={{\n yearGroups: props.yearGroups,\n audiences: props.audiences,\n imageCdnUrl: props.imageCdnUrl,\n setFavourite: props.setFavourite,\n canFavourite: props.canFavourite,\n isPlugin: props.isPlugin,\n showOwner: true\n }}\n analyticsData={props.analyticsData}\n />\n </section>\n );\n}","import React from 'react';\n\nimport { LinkifyHelper } from 'libs/common/react/utils/LinkifyHelper';\n\nimport { ExpandableText } from 'libs/shared/components/expandable-text/ExpandableText';\nimport { VideoTypes } from 'libs/shared/interfaces';\n\ninterface VideoDescriptionProps {\n video: VideoTypes;\n}\n\nexport function VideoDescription(props: VideoDescriptionProps): React.ReactElement {\n return (\n <ExpandableText lines={12}>\n {({ expanded }) => (\n <p\n className={`${expanded ? 'd-inline' : ''} mb-0`}\n dangerouslySetInnerHTML={{\n __html: LinkifyHelper.linkifyText(props.video.description, { nl2br: true })\n }}\n />\n )}\n </ExpandableText>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"descriptionBorder\":\"YUC62\"};","import * as React from 'react';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { ClickDescriptor, EntityType, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { CopyrightDisclaimer } from 'libs/shared/components/copyright-disclaimer/CopyrightDisclaimer';\nimport { ImmersiveReader } from 'libs/shared/components/immersive-reader/ImmersiveReader';\nimport { VideoDescription } from 'libs/shared/components/play-page-v2/details/video-description/VideoDescription';\nimport { TagHelper } from 'libs/shared/components/tags/TagHelper';\nimport { TagList } from 'libs/shared/components/tags/TagList';\nimport { LanguageNamespaceContext, Text } from 'libs/shared/components/text/Text';\nimport { hasPPDD } from 'libs/shared/components/video-details/VideoDetailsUtils';\nimport { MINIMUM_GLANCE_HEIGHT } from 'libs/shared/constants/MinimumGlanceHeight';\nimport { TagType } from 'libs/shared/enums/TagType';\nimport { BaseObject, BasePaginatedCollection, CurrentUser, Tag, VideoTypes } from 'libs/shared/interfaces';\nimport { PlayPageAnchor } from 'libs/shared/interfaces/PlayPageAnchor';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport styles from './video-details.scss';\n\nconst namespace = 'shared.videoDetailsV2';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface CommaListProps {\n label: string;\n items: BasePaginatedCollection<BaseObject>;\n className?: string;\n}\n\nfunction CommaList(props: CommaListProps): React.ReactElement {\n const { label, items, className } = props;\n\n const hasItems = items && items.data && items.data.length;\n\n if (!hasItems)\n return <></>;\n\n const commaSeperated = items.data.map(i => i.name).join(', ');\n\n return (\n <div className={className}>{label}: {commaSeperated}</div>\n );\n}\n\nfunction DetailsSection(props: VideoDetailsWithScrollbarV2Props): React.ReactElement {\n const { video } = props;\n\n if (!VideoHelper.isVideo(video) && !VideoHelper.isClip(video))\n return <></>;\n\n const parentVideo = VideoHelper.getParentVideo(video);\n\n return (\n <div className={video.description ? 'col-md-5 ps-md-3 pt-3 pt-md-0' : 'col-12'}>\n <h2 className='h6 mb-1'><Text phrase='details' /></h2>\n {!!parentVideo.productionYear && (\n <div className='mb-1'>\n <Text phrase='productionYear' options={{ year: parentVideo.productionYear }} />\n </div>\n )}\n <CommaList\n label={getPhrase('productionCompanies', { smartCount: parentVideo.productionCompanies?.data?.length })}\n items={parentVideo.productionCompanies}\n className='mb-1'\n />\n <CommaList\n label={getPhrase('distributors', { smartCount: parentVideo.distributors?.data?.length })}\n items={parentVideo.distributors}\n className='mb-1'\n />\n <CommaList\n label={getPhrase('producers', { smartCount: parentVideo.producers?.data?.length })}\n items={parentVideo.producers}\n className='mb-1'\n />\n <CommaList\n label={getPhrase('directors', { smartCount: parentVideo.directors?.data?.length })}\n items={parentVideo.directors}\n className='mb-1'\n />\n {!!parentVideo.dateBroadcast && (\n <div className='mb-1'>\n <Text phrase='dateBroadcast' options={{ date: DateHelper.format(parentVideo.dateBroadcast, 'DD/MM/YYYY') }} />\n </div>\n )}\n {!!parentVideo.channel && (\n <div className='mb-1'>\n <Text phrase='channel' options={{ channel: parentVideo.channel.name }} />\n </div>\n )}\n {VideoHelper.canViewUploadDate(props.video) && (\n <div className='mb-1'>\n <Text phrase='dateUploaded' options={{ date: DateHelper.format(video.dateCreated, 'DD/MM/YYYY') }} />\n </div>\n )}\n </div>\n );\n}\n\ninterface VideoDetailsWithScrollbarV2Props {\n video: VideoTypes;\n currentUser: CurrentUser;\n getTagAppLink?: (tag: Tag) => Core.AppLink;\n onLaunchImmersiveReader?: () => void;\n onExitImmersiveReader?: () => void;\n maxHeight?: number;\n suppressInteractivity?: boolean;\n hideTags?: boolean;\n headingRef?: React.MutableRefObject<Map<PlayPageAnchor, HTMLElement>>;\n showHeading?: boolean;\n}\n\nexport function VideoDetailsWithScrollbarV2(props: VideoDetailsWithScrollbarV2Props): React.ReactElement {\n const { video, maxHeight = MINIMUM_GLANCE_HEIGHT } = props;\n\n const parentVideo = VideoHelper.getParentVideo(video);\n\n const showDescription = !!props.video.description;\n\n const showDetails = (\n hasPPDD(props.video) ||\n !!parentVideo.productionYear ||\n !!parentVideo.dateBroadcast ||\n !!parentVideo.channel ||\n VideoHelper.canViewUploadDate(props.video)\n );\n\n if (!showDescription && !showDetails)\n return <></>;\n\n function getTags(): Tag[] {\n if (props.hideTags || VideoHelper.isInteractive(props.video) || !props.video.tags?.data?.length)\n return null;\n\n return props.video.tags?.data?.filter(tag => tag.tagType === TagType.Normal);\n }\n const tags = getTags();\n\n return (\n <LanguageNamespaceContext.Provider value={namespace}>\n <section\n id={PlayPageAnchor.VideoDetails}\n ref={el => {\n (el && props.headingRef?.current) && props.headingRef.current.set(PlayPageAnchor.VideoDetails, el);\n }}\n className='play-page-section'\n >\n {props.showHeading && (\n <h2 className='h4 curated-widget-header'><Text phrase='heading' /></h2>\n )}\n <div className='rounded border p-3 position-relative'>\n <Scrollbars autoHeight autoHeightMax={maxHeight} hideTracksWhenNotNeeded>\n <div className='row g-0'>\n {showDescription && (\n <div className={showDetails ? `${styles.descriptionBorder} pe-3 col-md-7` : 'col-12'}>\n <div className='d-flex align-items-center'>\n <h2 className='h6 mb-1'>\n <Text phrase='description' />\n </h2>\n <ImmersiveReader\n text={video.description}\n title={video.name}\n className='ps-2'\n onLaunch={props.onLaunchImmersiveReader}\n onExit={props.onExitImmersiveReader}\n analyticsOptions={{\n location: LocationContext.PlayPage,\n entity: EntityType.Video,\n actionType: UserAction.Click,\n descriptor: ClickDescriptor.LaunchImmersiveReader\n }}\n analyticsData={{ id: video.id, type: 'description' }}\n />\n </div>\n\n <VideoDescription video={props.video} />\n </div>\n )}\n\n {showDetails && (\n <DetailsSection {...props} />\n )}\n </div>\n\n {!!tags?.length && (\n <div className='mt-3'>\n <h2 className='h6 mb-1'><Text phrase='normalTags' /></h2>\n <TagList\n tags={tags}\n {...TagHelper.getTagActionProps(props.getTagAppLink, null, props.suppressInteractivity)}\n className='mt-1'\n />\n </div>\n )}\n\n {VideoHelper.isBroadcast(props.video) && (\n <CopyrightDisclaimer\n placement='bottom-start'\n className='d-flex justify-content-start mt-2'\n phraseClassName='mb-0'\n />\n )}\n\n </Scrollbars>\n </div>\n </section>\n </LanguageNamespaceContext.Provider>\n );\n}","import { MutableRefObject, useEffect, useRef, useState } from 'react';\nimport * as marked from 'marked';\n\nimport { useEventsServiceSubscribe } from 'libs/common/react/hooks/UseEventsServiceSubscribe';\nimport { EventsService } from 'libs/common/react/services/EventsService';\n\nimport { Clip, Glance, PointOfInterest, Video } from 'libs/shared/interfaces';\n\nimport styles from './video-at-a-glance.scss';\n\nconst POI_LINK_LINE = /\\[\\]\\(cv:\\/\\/poi\\?id=\\d+\\)\\n*/g;\n\nfunction stripPoisFromGlanceContent(glanceContent: string): string {\n return glanceContent.replace(POI_LINK_LINE, '');\n}\n\nfunction getLearningIntentionHTML(glance: Glance): string {\n const learningIntention = stripPoisFromGlanceContent(glance.content);\n\n return marked(learningIntention);\n}\n\nexport function useLearningIntentionMarkdown(\n video: Video,\n hasGlanceData?: boolean\n): string {\n const [ markdownHTML, setMarkdownHTML ] = useState('');\n\n useEffect(() => {\n if (!hasGlanceData)\n return;\n\n const content = getLearningIntentionHTML(video.glance);\n\n setMarkdownHTML(content);\n }, [ video.glance?.content, hasGlanceData ]);\n\n return markdownHTML;\n}\n\nexport function hasGlanceData(video: Video | Clip): boolean {\n return video.glance?.content && video.glance?.format === 'text/markdown';\n}\n\nexport function useHighlightPointOfInterest(\n pointOfInterest: PointOfInterest,\n shouldHighlight: boolean\n): MutableRefObject<HTMLDivElement> {\n const ref = useRef<HTMLDivElement>();\n\n useEventsServiceSubscribe('player:poi:mouseover', onPlayerPoiMouseOver, null, shouldHighlight);\n useEventsServiceSubscribe('player:poi:mouseleave', onPlayerPoiMouseLeave, null, shouldHighlight);\n\n useEffect(() => {\n if (!ref.current || !shouldHighlight)\n return;\n\n ref.current?.addEventListener('mouseover', onGlancePoiMouseOver);\n ref.current?.addEventListener('mouseleave', onGlancePoiMouseLeave);\n\n return () => {\n ref.current?.removeEventListener('mouseover', onGlancePoiMouseOver);\n ref.current?.removeEventListener('mouseleave', onGlancePoiMouseLeave);\n };\n }, [ref.current]);\n\n function onPlayerPoiMouseOver(hoveredPoi: PointOfInterest): void {\n if (!hoveredPoi?.id || pointOfInterest?.id?.toString() !== hoveredPoi?.id?.toString())\n return;\n\n ref.current?.classList.add(styles.highlightPoi);\n }\n\n function onPlayerPoiMouseLeave(): void {\n ref.current?.classList.remove(styles.highlightPoi);\n }\n\n /**\n * `this` will be the element to which the eventListener is bound.\n */\n function onGlancePoiMouseOver(): void {\n if (pointOfInterest)\n EventsService.trigger('glance:poi:mouseover', pointOfInterest);\n }\n\n function onGlancePoiMouseLeave(): void {\n EventsService.trigger('glance:poi:mouseleave');\n }\n\n return ref;\n}","// extracted by mini-css-extract-plugin\nexport default {\"poiEntry\":\"vr6R9\",\"poiText\":\"znHZF\",\"public\":\"v0BZ9\",\"poiTimeStamp\":\"AdKwe\",\"wideBadge\":\"YR2Hh\"};","import React from 'react';\n\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { PointOfInterest } from 'libs/shared/interfaces';\nimport { DurationHelper } from 'libs/shared/utils/DurationHelper';\n\nimport { useHighlightPointOfInterest } from '../VideoAtAGlanceUtilsV2';\n\nimport styles from './points-of-interest-list.scss';\n\ninterface PointOfInterestProps {\n poi: PointOfInterest;\n suppressInteractivity?: boolean;\n onClickPoiItem: (time: number) => void;\n wideBadge?: boolean;\n}\n\nfunction PointOfInterest(props: PointOfInterestProps): JSX.Element {\n const timeStamp = DurationHelper.ToDisplayDuration(props.poi.startTime * 1000);\n\n const ref = useHighlightPointOfInterest(props.poi, !props.suppressInteractivity);\n\n if (props.suppressInteractivity) {\n return (\n <div className={`d-flex ${styles.poiEntry} mb-2`}>\n <span className={`d-flex rounded-pill justify-content-center align-items-center fw-semibold text-info bg-light-blue ${styles.poiTimeStamp} ${props.wideBadge ? styles.wideBadge : ''}`}>{timeStamp}</span>\n <div className={`${styles.public} ms-2`}>{props.poi.description}</div>\n </div>\n );\n }\n\n return (\n <DivButton\n key={props.poi.startTime}\n className={`d-flex ${styles.poiEntry} mb-2 cursor-pointer`}\n onClick={() => props.onClickPoiItem(props.poi.startTime)}\n ref={ref}\n >\n <div className={`d-flex rounded-pill justify-content-center align-items-center fw-semibold text-info bg-light-blue ${styles.poiTimeStamp} ${props.wideBadge ? styles.wideBadge : ''}`}>{timeStamp}</div>\n <div className={`ms-2 ${styles.poiText}`}>{props.poi.description}</div>\n </DivButton>\n );\n}\n\ninterface PointOfInterestListProps{\n pointsOfInterest: PointOfInterest[];\n suppressInteractivity?: boolean;\n onClickPoiItem: (time: number) => void\n}\n\nconst namespace = 'shared.pointsOfInterestList';\n\nexport function PointOfInterestList(props: PointOfInterestListProps) {\n const sortedPointsOfInterest = props.pointsOfInterest.sort((a, b) => a.startTime - b.startTime);\n const hasTimePointOverHours = sortedPointsOfInterest.some(poi => poi.startTime >= 3600);\n\n return (\n <div>\n <h2 className='h6 my-2'><Text namespace={namespace} phrase='heading' /></h2>\n\n <div>\n {sortedPointsOfInterest.map(poi => {\n return (\n <PointOfInterest\n key={poi.startTime}\n poi={poi}\n suppressInteractivity={props.suppressInteractivity}\n onClickPoiItem={props.onClickPoiItem}\n wideBadge={hasTimePointOverHours}\n />\n );\n })}\n\n </div>\n </div>\n );\n}","import * as React from 'react';\nimport CopyToClipboard from 'react-copy-to-clipboard';\nimport Scrollbars from 'react-custom-scrollbars-2';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { EntityType, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { PointOfInterestList } from 'libs/shared/components/play-page-v2/glance/points-of-interest-list/PointsOfInterestList';\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { TagHelper } from 'libs/shared/components/tags/TagHelper';\nimport { TagList } from 'libs/shared/components/tags/TagList';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { TagType } from 'libs/shared/enums/TagType';\nimport { PointOfInterest, Tag, Video } from 'libs/shared/interfaces';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport { useLearningIntentionMarkdown } from './VideoAtAGlanceUtilsV2';\n\nimport styles from './video-at-a-glance.scss';\n\nconst namespace = 'shared.videoAtAGlanceV2';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\n// Pixel value selected to try and make it so that when there are more\n// POIs below the fold, that the user can see some of the next one so\n// they know they can scroll. E.g. https://imgur.com/TQyL0Bq\nconst SCROLL_HEIGHT_MAX = 365; // in px\n\ninterface ScrollbarWrapperProps {\n hideScrollbar?: boolean;\n}\n\nfunction ScrollbarWrapper(props: React.PropsWithChildren<ScrollbarWrapperProps>): JSX.Element {\n if (props.hideScrollbar)\n return <>{props.children}</>;\n\n return (\n <div className='rounded border mb-4 bg-white'>\n <Scrollbars\n autoHeight\n autoHeightMax={SCROLL_HEIGHT_MAX}\n >\n <div className='px-3 px-3 pt-3 pb-2'>\n {props.children}\n </div>\n </Scrollbars>\n </div>\n );\n}\n\ninterface VideoAtAGlanceV2Props {\n video: Video;\n pointsOfInterest?: PointOfInterest[];\n suppressInteractivity?: boolean;\n setStartTime?: (time: number) => void;\n getTagAppLink?: (tag: Tag) => Core.AppLink;\n onClickTag?: () => void;\n hideScrollbar?: boolean;\n canViewGlance: boolean;\n}\n\nexport function VideoAtAGlanceV2(props: VideoAtAGlanceV2Props): JSX.Element {\n const learningIntentionMarkdownHTML = useLearningIntentionMarkdown(props.video, props.canViewGlance);\n const [ textToCopy, setTextToCopy ] = React.useState('');\n\n function logUserAction(): void {\n const analyticsData = {\n id: props.video.glance.id,\n name: props.video.glance.name,\n videoId: props.video.id,\n videoName: props.video.name,\n learningIntention: textToCopy\n };\n\n const analyticsOptions = {\n actionType: UserAction.Copy,\n entity: EntityType.Glance,\n location: LocationContext.PlayPage\n };\n AnalyticsHelper.logUserAction(analyticsData, analyticsOptions);\n }\n\n function getTags(): Tag[] {\n if (VideoHelper.isInteractive(props.video) || !props.video.tags?.data?.length)\n return null;\n\n return props.video.tags?.data?.filter(tag => tag.tagType === TagType.Pedagogy || tag.tagType === TagType.Skill);\n }\n const tags = getTags();\n\n const ref = React.useRef<HTMLDivElement>(null);\n\n React.useEffect(() => {\n if (ref.current?.innerText)\n setTextToCopy(ref.current.innerText);\n }, [ref.current?.innerText]);\n\n if (!props.canViewGlance)\n return <></>;\n\n function onClickPoiItem(time: number) {\n props.setStartTime(time);\n }\n\n return (\n <section className='play-page-section'>\n <ScrollbarWrapper hideScrollbar={props.hideScrollbar}>\n <h2 className='h6 mb-2'><Text namespace={namespace} phrase='learningIntention' /></h2>\n \n <div className={`mb-3 ${styles.learningIntention}`}>\n <Tooltip title={getPhrase('copy')} spanHack spanHackClassName={styles.icon}>\n <CopyToClipboard text={textToCopy}>\n <SvgContainer\n className='svg-container me-1 cursor-pointer'\n svgName={cvSvgLibrary.Copy}\n size={SvgContainerSize.Small}\n onClick={logUserAction}\n />\n </CopyToClipboard>\n </Tooltip>\n \n <div\n dangerouslySetInnerHTML={{ __html: learningIntentionMarkdownHTML }}\n className='d-inline'\n ref={ref}\n >\n </div>\n </div>\n\n {!!tags?.length && (\n <div className='mb-1'>\n <TagList\n tags={tags}\n {...TagHelper.getTagActionProps(props.getTagAppLink, props.onClickTag, props.suppressInteractivity)}\n className='mt-2'\n />\n </div>\n )}\n\n {!!props.pointsOfInterest.length && (\n <PointOfInterestList\n pointsOfInterest={props.pointsOfInterest}\n suppressInteractivity={props.suppressInteractivity}\n onClickPoiItem={onClickPoiItem}\n />\n )}\n </ScrollbarWrapper>\n </section>\n );\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { ThumbnailText } from 'libs/shared/components/thumbnails/thumbnail-text/ThumbnailText';\nimport { VideoThumbnail } from 'libs/shared/components/thumbnails/video/VideoThumbnail';\nimport { FixedWidgetItemProps } from 'libs/shared/components/widgets/items/FixedWidgetItemProps';\nimport { ThumbnailTextPosition } from 'libs/shared/enums/ThumbnailTextPosition';\nimport { CanFavouriteFunc, FavouriteFunc, InteractiveMetadata, YearGroup } from 'libs/shared/interfaces';\n\nconst namespace = 'shared.interactiveWidgetItemV2';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport interface InteractiveWidgetItemV2Props extends FixedWidgetItemProps<InteractiveMetadata> {\n imageCdnUrl: string;\n questionsAppLink: Core.AppLink;\n setFavourite?: FavouriteFunc;\n canFavourite?: CanFavouriteFunc;\n yearGroups: YearGroup[];\n isPlugin: boolean;\n showOwner?: boolean;\n}\n\nexport const InteractiveWidgetItemV2 = React.memo(function(props: InteractiveWidgetItemV2Props): JSX.Element {\n const { data: interactive, thumbnailSize, preloadImage } = props;\n\n const questionsAppLink: Core.AppLink = {\n ...props.questionsAppLink,\n args: [props.data.id]\n };\n\n const questionsNumber = interactive._timepoints?.value?.length;\n\n return (\n <div className={`flex-shrink-0 px-1 col-6 col-sm-4`}>\n <VideoThumbnail\n type='static'\n textPosition={ThumbnailTextPosition.Independent}\n video={interactive}\n appLink={props.getAppLink(interactive)}\n imageOptions={{ size: thumbnailSize }}\n preload={preloadImage}\n analyticsData={props.analyticsData}\n analyticsOptions={props.analyticsOptions}\n setFavourite={props.setFavourite}\n canFavourite={props.canFavourite}\n hideDuration={false}\n imageCdnUrl={props.imageCdnUrl}\n isPlugin={props.isPlugin}\n showOwner={props.showOwner}\n />\n\n <div className='mt-2'>\n <ThumbnailText\n {...props}\n video={interactive}\n appLink={props.getAppLink(interactive)}\n />\n </div>\n\n <div className='mt-n1'>\n <AppLink\n appLink={questionsAppLink}\n className='cursor-pointer'\n ariaLabel={`${getPhrase('previewQuestions', { count: questionsNumber, smartCount: questionsNumber })} ${getPhrase('ariaPreview', { name: interactive.name })}`}\n >\n {questionsNumber\n ? (\n <Text namespace={namespace} phrase='previewQuestions' options={{ count: questionsNumber, smartCount: questionsNumber }}/>\n ) : (\n // handling a rare case: add a fallback phrase if we don't get the question number\n <Text namespace={namespace} phrase='previewQuestionsFallback' />\n )}\n </AppLink>\n </div>\n </div>\n );\n});\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { TextHelper } from 'libs/common/react/utils/TextHelper';\n\nimport { FixedWidget } from 'libs/shared/components/widgets/fixed-widget';\nimport { WidgetContents } from 'libs/shared/enums/WidgetContents';\nimport { CanFavouriteFunc, Clip, FavouriteFunc, Interactive, InteractiveMetadata, Video, YearGroup } from 'libs/shared/interfaces';\nimport { PlayPageAnchor } from 'libs/shared/interfaces/PlayPageAnchor';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nimport { InteractiveWidgetItemV2, InteractiveWidgetItemV2Props } from './InteractiveWidgetItemV2';\n\nconst namespace = 'shared.playPageInteractivesV2';\n\ninterface PlayPageInteractivesProps {\n canViewInteractives: boolean;\n video: Video | Clip;\n interactives: InteractiveMetadata[];\n imageCdnUrl: string;\n analyticsData: HashObject;\n yearGroups: YearGroup[];\n setFavourite: FavouriteFunc;\n canFavourite: CanFavouriteFunc;\n isPlugin: boolean;\n headingRef?: React.MutableRefObject<Map<PlayPageAnchor, HTMLElement>>;\n}\n\nexport function PlayPageInteractives(props: PlayPageInteractivesProps): JSX.Element {\n if (!props.canViewInteractives || !props.interactives?.length)\n return <></>;\n\n function getAppLink() {\n if (VideoHelper.isVideo(props.video))\n return {\n action: Actions.Videos.VIDEO_INTERACTIVES,\n application: AppChannels.VIDEOS,\n args: [ props.video.id, TextHelper.slugify(props.video.name) ]\n };\n\n return {\n action: Actions.Clips.CLIP_INTERACTIVES,\n application: AppChannels.CLIPS,\n args: [ props.video.id, TextHelper.slugify(props.video.name) ]\n };\n }\n\n const title = LanguageService.getPhrase(namespace, 'interactives', { count: props.interactives.length });\n \n return (\n <section className='play-page-section'\n id={PlayPageAnchor.Interactives}\n ref={el => {\n (el && props.headingRef?.current) && props.headingRef.current.set(PlayPageAnchor.Interactives, el);\n }}\n >\n <FixedWidget<InteractiveWidgetItemV2Props>\n name={title}\n contents={WidgetContents.InteractivesV2}\n collection={props.interactives}\n prefetched\n getChildAppLink={(interactive: Interactive) => {\n return {\n application: AppChannels.INTERACTIVES,\n action: Actions.Interactives.VIEW_INTERACTIVE,\n args: [ interactive.id, TextHelper.slugify(interactive.name) ]\n };\n }}\n appLink={getAppLink()}\n childComponent={InteractiveWidgetItemV2}\n extraChildComponentProps={{\n yearGroups: props.yearGroups,\n setFavourite: props.setFavourite,\n canFavourite: props.canFavourite,\n imageCdnUrl: props.imageCdnUrl,\n questionsAppLink: {\n application: AppChannels.INTERACTIVES,\n action: Actions.Interactives.PREVIEW_QUESTIONS\n },\n isPlugin: props.isPlugin,\n showOwner: true\n }}\n analyticsData={props.analyticsData}\n />\n </section>\n );\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { EntityType, LocationContext, SignUpDescriptors, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { FixedWidget } from 'libs/shared/components/widgets/fixed-widget';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { WidgetContents } from 'libs/shared/enums/WidgetContents';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { Clip, Link, Resource, Video } from 'libs/shared/interfaces';\nimport { PlayPageAnchor } from 'libs/shared/interfaces/PlayPageAnchor';\nimport { DownloadHelper } from 'libs/shared/utils/DownloadHelper';\n\nimport { ResourceWidgetItemV2, ResourceWidgetItemV2Props } from './ResourceWidgetItemV2';\n\nconst namespace = 'shared.playPageResources';\n\nfunction getResources(\n video: Video,\n isLearner: boolean\n): Array<Resource | Link> {\n const resources = video.resources?.data ?? [];\n const links = video.links?.data ?? [];\n\n if (!isLearner)\n return [ ...resources, ...links ];\n\n const filteredResources = resources.filter(r => {\n return [ 'additional-materials', 'student-activity' ].includes(r.metadata?.resourceType);\n });\n\n return [ ...filteredResources, ...links ];\n}\n\ninterface PlayPageResourcesProps {\n video: Video | Clip;\n imageCdnUrl: string;\n canViewResources: boolean;\n getAppLink: (resource: Resource) => Core.AppLink;\n analyticsData: HashObject;\n resourceThumbnailFallbackUrl: string;\n headingRef?: React.MutableRefObject<Map<PlayPageAnchor, HTMLElement>>;\n}\n\nexport function PlayPageResources(props: PlayPageResourcesProps): JSX.Element {\n const { hasPermissions } = usePermissions();\n\n function onClickDownload(resource: Resource): void {\n DownloadHelper.downloadResource(\n resource,\n props.analyticsData,\n { location: LocationContext.PlayPage, actionType: UserAction.Download, entity: EntityType.Resource }\n );\n }\n\n const resources = getResources(props.video, hasPermissions(PermissionName.StudentExperience));\n const title = LanguageService.getPhrase(namespace, 'resources', { count: resources.length });\n\n if (!resources.length)\n return <></>;\n\n return (\n <section\n id={PlayPageAnchor.Resources}\n className='play-page-section'\n ref={el => {\n (el && props.headingRef?.current) && props.headingRef.current.set(PlayPageAnchor.Resources, el);\n }}\n >\n <FixedWidget<ResourceWidgetItemV2Props>\n name={title}\n contents={WidgetContents.PlayPageResourcesV2}\n collection={resources}\n prefetched\n childComponent={ResourceWidgetItemV2}\n extraChildComponentProps={{\n imageCdnUrl: props.imageCdnUrl,\n imageErrorFallbackUrl: props.resourceThumbnailFallbackUrl,\n actionBehaviour: props.canViewResources ? 'normal' : 'public',\n location: 'play-page',\n titlePosition: 'below',\n onClickDownload: props.canViewResources ? onClickDownload : null\n }}\n getChildAppLink={props.getAppLink}\n analyticsOptions={(() => {\n if (props.canViewResources)\n return {};\n \n return {\n workflowPhase: WorkflowPhase.Start,\n descriptor: SignUpDescriptors.SignUp\n };\n })()}\n analyticsData={props.analyticsData}\n />\n </section>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"imageStyle\":\"bYRn8\",\"item\":\"CjuxU\",\"dashboard\":\"IuRN0\",\"playPage\":\"VdJvp\",\"aspectRatio\":\"QK8Jh\",\"outerContainer\":\"eiC_H\",\"innerContainer\":\"huIRg\",\"actions\":\"FsIJm\",\"titleBelow\":\"DpeSr\",\"thumbnailContainer\":\"ZbalL\",\"titleAbove\":\"PwOSX\",\"teacherPack\":\"ZHAEj\",\"text\":\"k3ei6\",\"hoverState\":\"BLrWL\",\"atomGuide\":\"Qz8JE\",\"studentActivity\":\"qNspk\",\"additionalMaterials\":\"R0huw\",\"userUploaded\":\"H_zGf\",\"imageTypeResource\":\"AgeLb\",\"download\":\"DKneu\"};","import React from 'react';\n\nimport { AppLinkHelper } from 'libs/common/backbone/core';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { AnalyticsOptions, EntityType, UserAction } from 'libs/analytics/interfaces';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { ResourceThumbnail } from 'libs/shared/components/resource-thumbnail/ResourceThumbnail';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { TitleSubText } from 'libs/shared/components/title-sub-text/TitleSubText';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { TypeBadge } from 'libs/shared/components/type-badge/TypeBadge';\nimport { FixedWidgetItemProps } from 'libs/shared/components/widgets/items/FixedWidgetItemProps';\nimport { SeoConstants } from 'libs/shared/constants/SeoConstants';\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { ResourceFileType } from 'libs/shared/enums/ResourceFileType';\nimport { useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { Link, Resource, ResourceType } from 'libs/shared/interfaces';\nimport { ImageOptions } from 'libs/shared/utils/ImageHelper';\nimport { MasterTypeHelper } from 'libs/shared/utils/MasterTypeHelper';\nimport { ResourceHelper } from 'libs/shared/utils/ResourceHelper';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport styles from './resource-widget-item.scss';\n\nfunction getColour(resourceType?: ResourceType): string {\n switch (resourceType) {\n case 'atom-guide':\n return styles.atomGuide;\n case 'student-activity':\n return styles.studentActivity;\n case 'teacher-pack':\n return styles.teacherPack;\n case 'additional-materials':\n return styles.additionalMaterials;\n default:\n return styles.userUploaded;\n }\n}\n\nexport function useCanPreviewResource(data: Resource | Link, actionBehaviour: 'normal' | 'public'): boolean {\n const breakpoints = useBreakpoints();\n\n /**\n * When viewing publicly, the resource applink will\n * prompt the user to sign-up (not preview the underlying resource)\n */\n if (actionBehaviour === 'public')\n return true;\n\n if (breakpoints.xs || breakpoints.sm)\n return false;\n\n if (data.type !== 'resource')\n return false;\n \n // Require metadata\n if (!('metadata' in data))\n return false;\n\n // We can preview images\n if (data.metadata.type === ResourceFileType.Image)\n return true;\n\n // If we are a pdf and have a url\n if (data.metadata.type === ResourceFileType.Pdf)\n return !!data.url;\n\n // If we have a pdf assoc\n return !!data.pdf?.url;\n}\n\ninterface ResourceTheme {\n containerClass?: string;\n thumbnailContainerClass?: string;\n}\n\nexport interface ResourceTileProps {\n data: Resource | Link;\n imageCdnUrl: string;\n imageErrorFallbackUrl?: string;\n theme?: ResourceTheme;\n\n titlePosition: 'above' | 'below' | 'none';\n hideTypeBadge?: boolean;\n onClickDownload?: (resource: Resource) => void;\n applyHoverState?: boolean;\n preloadImage: boolean;\n actionBehaviour?: 'normal' | 'public';\n dynamicRatioImageOptions?: ImageOptions;\n}\n\nResourceTileV2.defaultProps = {\n preloadImage: true,\n actionBehaviour: 'normal'\n};\n\n/**\n * This component intentionally doesn't contain an appLink/download link\n * so that the resource download behaviour can be handled differently depending\n * on where this is rendered (e.g. primary play page vs embedded player)\n */\nexport function ResourceTileV2(props: ResourceTileProps): JSX.Element {\n let metadata = null;\n\n if ('metadata' in props.data) {\n metadata = props.data.metadata;\n }\n\n const isResource = MasterTypeHelper.isType<Resource>(props.data, MasterType.Resource);\n\n function getInnerContainerClass(resourceType: ResourceType): string {\n let baseClass = `\n d-flex flex-column align-items-center justify-content-end rounded-3 h-100\n position-relative ${getColour(resourceType)} ${styles.innerContainer}`;\n\n if (props.theme?.containerClass) {\n baseClass += ` ${props.theme.containerClass}`;\n } else {\n baseClass += ` pt-3 px-3`;\n }\n\n if (props.applyHoverState) {\n baseClass += ` ${styles.hoverState}`;\n }\n\n return baseClass;\n }\n\n function onDownload() {\n if (!MasterTypeHelper.isResource(props.data))\n return;\n\n if (typeof props.onClickDownload === 'function') {\n props.onClickDownload(props.data);\n }\n }\n\n return (\n <>\n <div className={styles.aspectRatio}>\n <div className={styles.outerContainer}>\n <div className={getInnerContainerClass(metadata?.resourceType)}>\n {props.titlePosition === 'above' && (\n <Tooltip title={props.data.name}>\n <h3 className={`text-center text-break h5 mb-3 ${styles.text}`}>\n <span className='clamp-1'>{props.data.name}</span>\n </h3>\n </Tooltip>\n )}\n\n <div className={`\n ${props.theme?.thumbnailContainerClass ?? ''} w-75 overflow-hidden \n ${styles.thumbnailContainer} ${props.titlePosition === 'above' ? styles.titleAbove : ''} \n ${styles.imageStyle}\n `}>\n <ResourceThumbnail\n resource={props.data}\n imageCdnUrl={props.imageCdnUrl}\n imageErrorFallbackUrl={props.imageErrorFallbackUrl}\n preloadImage={props.preloadImage}\n dynamicRatioImageOptions={props.dynamicRatioImageOptions}\n />\n </div>\n\n {isResource && props.onClickDownload && props.actionBehaviour === 'normal' && (\n <div className={styles.actions}>\n <DivButton\n onClick={e => {\n e.preventDefault();\n e.stopPropagation();\n onDownload();\n }}\n className={`${styles.download} d-flex align-items-center justify-content-center`}\n >\n <SvgContainer svgName={cvSvgLibrary.Download} />\n </DivButton>\n </div>\n )}\n\n {!props.hideTypeBadge && isResource && (\n <TypeBadge typeId={MasterType.Resource} />\n )}\n </div>\n </div>\n </div>\n {props.titlePosition === 'below' && (\n <div className={`mt-1 ${styles.titleBelow}`}>\n {(\n MasterTypeHelper.isType<Resource>(props.data, MasterType.Resource) &&\n !!props.data?.metadata?.resourceType\n ) && (\n <TitleSubText>\n {ResourceHelper.getResourceTypeName(props.data.metadata.resourceType)}\n </TitleSubText>\n )}\n\n <h3 className='h6 clamp-2'>\n {props.data.name}\n </h3>\n </div>\n )}\n </>\n );\n}\n\nexport interface ResourceWidgetItemV2Props extends ResourceTileProps, FixedWidgetItemProps<Resource | Link> {\n location: 'play-page' | 'dashboard';\n}\n\nexport const ResourceWidgetItemV2 = React.memo(function(props: ResourceWidgetItemV2Props): JSX.Element {\n // Mobile is not allowed to preview\n const canPreview = useCanPreviewResource(props.data, props.actionBehaviour);\n\n function getLocationClass(): string {\n if (props.location === 'play-page')\n return styles.playPage;\n\n return styles.dashboard;\n }\n\n const analyticsData = { ...props.analyticsData, id: props.data.id, name: props.data.name };\n\n const analyticsOptions: AnalyticsOptions = {\n ...props.analyticsOptions,\n actionType: UserAction.Click,\n entity: props.data.typeId === MasterType.Resource ? EntityType.Resource : EntityType.Link\n };\n\n function logAction(): void {\n AnalyticsHelper.logUserAction(analyticsData, analyticsOptions);\n }\n\n const tileProps: ResourceTileProps = {\n ...props,\n // Apply the hover state if we have a url or the resource can be previewed\n applyHoverState: canPreview || !!props.data.url\n };\n\n return (\n <div className={`px-1 flex-shrink-0 ${styles.item} ${getLocationClass()} ${SeoConstants.RESOURCE_ITEM_SELECTOR}`}>\n {(() => {\n const className = `d-block no-decoration`;\n\n // Handle resource links\n if (props.data.type === 'link') {\n return (\n <a href={props.data.url} target='_blank' className={className} onClick={logAction}>\n <ResourceTileV2 {...tileProps} />\n </a>\n );\n }\n\n if (canPreview) {\n /**\n * Previewing resources in a public context will always display the sign-up popup, so there \n * will never be a full URL. For SEO purposes, we deliberately use a span over an anchor\n * to ensure we're not creating self-referencing elements that will burn crawl budget.\n */\n if (props.actionBehaviour === 'public') {\n return (\n <div className={`${className} cursor-pointer d-inline`} onClick={() => {\n logAction();\n AppLinkHelper.trigger(props.getAppLink(props.data));\n }}>\n <ResourceTileV2 {...tileProps} />\n </div>\n );\n }\n\n return (\n <AppLink\n appLink={props.getAppLink(props.data)}\n className={className}\n analyticsData={analyticsData}\n analyticsOptions={analyticsOptions}\n >\n <ResourceTileV2 {...tileProps} />\n </AppLink>\n );\n }\n\n // URLs cannot be previewed\n if (props.data.url) {\n return (\n <a href={props.data.url} className={className} onClick={logAction}>\n <ResourceTileV2 {...tileProps} />\n </a>\n );\n }\n\n // Theres no url, so don't render an <a>\n return (\n <div className={className}>\n <ResourceTileV2 {...tileProps} />\n </div>\n );\n })()}\n </div>\n );\n});","// extracted by mini-css-extract-plugin\nexport default {\"itemsWrapper\":\"m6mGm\",\"anchorWrapper\":\"QptZj\",\"default\":\"_AZa8\",\"selectedItem\":\"Nuiel\",\"disabled\":\"WIzWJ\",\"floatIcon\":\"ARudn\",\"arrowIcon\":\"tEF5Q\",\"listIcon\":\"Ql2wi\"};","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { ScrollHelper } from 'libs/common/backbone/utils/ScrollHelper';\n\nimport { EntityType, HashObject, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\n\nimport styles from './table-of-contents-list.scss';\n\nexport interface TableOfContentsItem<T=string> {\n name: string;\n id: T;\n tocIndentation?: number;\n}\n\ninterface TableOfContentsProps<T> {\n items: TableOfContentsItem<T>[];\n activeId: string;\n appLink?: Core.AppLink;\n analyticsData?: HashObject;\n setControlledId: (arg: string) => void;\n // set to true if the TOC is controlled by a local state rather than query params\n localState?: boolean;\n getAppLink?: (args: TableOfContentsItem<T>) => Core.AppLink;\n onItemClick?: (args: TableOfContentsItem<T>) => void;\n}\n\nexport function TableOfContentsList<T extends string>(props: TableOfContentsProps<T>): JSX.Element {\n const analyticsOptions = {\n actionType: UserAction.Click,\n entity: EntityType.Widget,\n location: LocationContext.TableOfContents\n };\n\n function onItemSelect(item: TableOfContentsItem<T>) {\n ScrollHelper.preventScrollTop();\n props.setControlledId(item.id);\n \n props.onItemClick?.(item);\n \n setTimeout(() => document.getElementById(item.id)?.focus());\n }\n\n return (\n <div className={`${styles.itemsWrapper}`}>\n {props.items.map((item, idx) => {\n if (props.localState) {\n return (\n <DivButton\n key={item.id}\n className={`${styles.anchorWrapper} ${props.activeId === item.id ? styles.selectedItem : ''}`}\n onClick={() => {\n onItemSelect(item);\n }}\n >\n <div className={`${!props.activeId && idx === 0 ? styles.default : ''} `}>\n {item.name}\n </div>\n </DivButton>\n );\n }\n\n return (\n <AppLink\n key={item.id}\n appLink={props.getAppLink(item)}\n appLinkOptions={{ replace: true }}\n className={`${styles.anchorWrapper} ${props.activeId === item.id ? styles.selectedItem : ''}`}\n onClick={() => {\n onItemSelect(item);\n }}\n analyticsData={{\n ...props.analyticsData,\n id: item.id,\n name: item.name\n }}\n analyticsOptions={analyticsOptions}\n >\n <div className={`${!props.activeId && idx === 0 ? styles.default : ''} ${item.tocIndentation ? 'ms-3' : ''}`}>\n {item.name}\n </div>\n </AppLink>\n );\n })}\n </div>\n );\n}","import React from 'react';\n\ntype TableOfContentsActiveOption = {\n setActiveId: (id: string) => void;\n headingElements: Element[];\n controlledId?: string;\n setControlledId?: (arg: string) => void;\n}\n\nlet timer: number;\n\nexport const useTableOfContentsActiveHeading = (\n { setActiveId, headingElements, controlledId, setControlledId }: TableOfContentsActiveOption\n) => {\n const scrollPositionRef = React.useRef(0);\n\n React.useEffect(() => {\n const callback = (headings: IntersectionObserverEntry[]) => {\n headings.forEach(heading => {\n if (controlledId) {\n setActiveId(controlledId);\n // can use scrollEnd event when the new event type is supported\n timer = window.setTimeout(() => {\n setControlledId('');\n }, 800);\n return;\n }\n if (heading.isIntersecting) {\n setActiveId(heading.target.id);\n scrollPositionRef.current = window.scrollY;\n } else {\n const scrollDistance = scrollPositionRef.current - window.scrollY;\n const isScrollingUp = scrollDistance > 0;\n const curIndex = headingElements.findIndex(h => h.id === heading.target.id);\n const prevHeading = headingElements[curIndex - 1];\n if (isScrollingUp && prevHeading?.id) {\n setActiveId(prevHeading?.id);\n }\n }\n });\n };\n\n const observer = new IntersectionObserver(callback, {\n // rootMargin top: same as the cv-nav-height\n rootMargin: '-67px 0px -80% 0px'\n });\n\n headingElements.forEach(element => observer.observe(element));\n\n return () => {\n timer && window.clearTimeout(timer);\n observer.disconnect();\n };\n }, [ setActiveId, headingElements.length, controlledId ]);\n};\n\n","import { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { AnalyticsOptions, EntityType, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { Resource } from '../interfaces';\n\nlet downloadRef: HTMLIFrameElement = null;\n\nexport const DownloadHelper = {\n getVideoDownloadUrl(downloadProxyUrl: string, token: string): string {\n return UrlHelper.safeUrlConcat(UrlHelper.makeHttps(downloadProxyUrl), `/download?token=${token}`);\n },\n\n downloadResource(\n resource: Resource,\n analyticsData: HashObject,\n analyticsOptions: AnalyticsOptions\n ): void {\n let iframe = downloadRef;\n\n if (!downloadRef) {\n iframe = downloadRef = document.createElement('iframe');\n document.body.appendChild(iframe);\n\n iframe.style.display = 'none';\n }\n\n iframe.src = resource.url;\n\n AnalyticsHelper.logUserAction({\n id: resource?.id,\n name: resource?.name,\n resourceType: resource?.metadata?.resourceType,\n ...analyticsData\n }, {\n actionType: UserAction.Download,\n entity: EntityType.Resource,\n workflowPhase: WorkflowPhase.Complete,\n ...analyticsOptions\n });\n }\n};","// extracted by mini-css-extract-plugin\nexport default {\"container\":\"qA4yj\",\"showInSide\":\"kd9hB\",\"aside\":\"j28IY\",\"collapse\":\"sFoPk\",\"iconContainer\":\"PYyBV\",\"arrowIcon\":\"MTodB\",\"listIcon\":\"W76p8\"};","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { PortalHelper } from 'libs/common/react/utils/PortalHelper';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { EntityType, HashObject, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { IconButton } from 'libs/shared/components/icon-button/IconButton';\nimport { TableOfContentsList } from 'libs/shared/components/table-of-contents-list/TableOfContentsList';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { PlayPageAnchor } from 'libs/shared/interfaces/PlayPageAnchor';\nimport { ContextService } from 'libs/shared/services/ContextService';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport { PLAY_PAGE_TOC_PORTAL_ID } from 'shared/layouts/teacher-layout/TeacherLayoutComponent';\n\nimport styles from './table-of-contents.scss';\n\nconst namespace = 'shared.playPage';\n\nexport interface TableOfContentsItem {\n name: string;\n id: PlayPageAnchor;\n}\n\ninterface TableOfContentsProps {\n items: TableOfContentsItem[];\n activeId: string;\n appLink?: Core.AppLink;\n analyticsData?: HashObject;\n setControlledId: (arg: string) => void;\n isExpanded: boolean;\n setIsExpanded: (arg: boolean) => void;\n showInSide: boolean;\n}\n\nfunction TableOfContentsIcon(props: TableOfContentsProps) {\n function logUserAction() {\n const analyticsOptions = {\n actionType: !props.isExpanded ? UserAction.Open : UserAction.Hide,\n entity: EntityType.TableOfContents,\n location: LocationContext.PlayPage\n };\n\n AnalyticsHelper.logUserAction(props.analyticsData, analyticsOptions);\n }\n\n function onClickIcon() {\n props.setIsExpanded(!props.isExpanded);\n logUserAction();\n }\n\n return (\n <div className='d-flex justify-content-end'>\n <div className={styles.container}>\n <div className={`${styles.iconContainer}`} >\n <IconButton\n className={`btn btn-outline-dark ${styles.listIcon}`}\n svgName={cvSvgLibrary.TableOfContents}\n onClick={onClickIcon}\n />\n \n <IconButton\n className={`btn btn-outline-dark ${styles.arrowIcon}`}\n svgName={!props.isExpanded ? cvSvgLibrary.ExpandLeft : cvSvgLibrary.CollapseRight}\n onClick={onClickIcon}\n />\n </div>\n </div>\n </div>\n );\n}\n\nfunction TableOfContents(props: TableOfContentsProps) {\n function logUserAction() {\n const analyticsOptions = {\n actionType: UserAction.Hide,\n entity: EntityType.TableOfContents,\n location: LocationContext.PlayPage\n };\n\n AnalyticsHelper.logUserAction(props.analyticsData, analyticsOptions);\n }\n\n function getAppLink(item: any): Core.AppLink {\n const currentAppLink = ContextService.getCurrentRoute().appLink;\n\n const params: HashObject = currentAppLink.params\n ? { ...(currentAppLink.params as HashObject) }\n : {};\n\n params.tocId = item.id;\n\n return {\n ...currentAppLink,\n params\n };\n }\n\n function onClickTableOfContentsHeading() {\n if (!props.showInSide) {\n // in mobile version, collapse once user hit the TOC item\n props.setIsExpanded(false);\n }\n }\n\n return (\n <div className={!props.showInSide ? 'd-inline-flex gap-1' : `col col-2 ps-4`}>\n <aside className={`${styles.aside} position-relative ${!props.showInSide ? 'px-3 pt-3 pb-2 border border-dark rounded-1 bg-white' : 'pe-1 pt-1 '}`}>\n <div className={`${styles.container} ${!props.showInSide ? '' : styles.showInSide}`}>\n {props.showInSide && (\n <IconButton\n className={`btn position-absolute ${styles.collapse}`}\n svgName={cvSvgLibrary.CollapseRight}\n onClick={() => {\n props.setIsExpanded(false);\n logUserAction();\n }}\n />\n )}\n <h2 className='h5'><Text namespace={namespace} phrase='tocHeading' /></h2>\n \n <TableOfContentsList\n items={props.items}\n activeId={props.activeId}\n getAppLink={getAppLink}\n setControlledId={props.setControlledId}\n analyticsData={props.analyticsData}\n onItemClick={() => onClickTableOfContentsHeading()}\n />\n </div>\n \n </aside>\n {/* in mobile version, always show icon on the right */}\n {!props.showInSide && <TableOfContentsIcon {...props}/>}\n </div>\n );\n}\n\nexport function TableOfContentsContainer(props: TableOfContentsProps): JSX.Element {\n return (\n <>\n {/* web version show table of contents next to player */}\n {props.isExpanded && props.showInSide && <TableOfContents {...props}/>}\n \n {/* web version show icon in portal (RHS of window) */}\n {PortalHelper.renderInPortalIfExists(\n !props.isExpanded && <TableOfContentsIcon {...props}/>,\n document.getElementById(PLAY_PAGE_TOC_PORTAL_ID)\n )}\n\n {/* mobile version show in portal */}\n {PortalHelper.renderInPortalIfExists(\n !props.showInSide && props.isExpanded && <TableOfContents {...props}/>,\n document.getElementById(PLAY_PAGE_TOC_PORTAL_ID)\n )}\n </>\n );\n}","import { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { Clip, InteractiveMetadata, Link, Resource } from 'libs/shared/interfaces';\nimport { PlayPageAnchor } from 'libs/shared/interfaces/PlayPageAnchor';\n\ninterface SectionHeadingOptions {\n clips: Clip[];\n interactives: InteractiveMetadata[];\n resources: Resource[] | Link[];\n isPlayClipPage?: boolean;\n}\n\nconst namespace = 'shared.play';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport const PlayPageUtils = {\n getSectionHeading(id: PlayPageAnchor, options: SectionHeadingOptions) {\n switch (id) {\n case PlayPageAnchor.Resources:\n return getPhrase('resourcesHeading', { count: options.resources.length });\n\n case PlayPageAnchor.Clips:\n if (options.isPlayClipPage)\n return getPhrase('otherClipsHeading', { count: options.clips.length - 1 });\n return getPhrase('clipsHeading', { count: options.clips.length });\n\n case PlayPageAnchor.Interactives:\n return getPhrase('interactivesHeading', { count: options.interactives.length });\n\n case PlayPageAnchor.Video:\n return getPhrase('videoHeading');\n\n case PlayPageAnchor.VideoDetails:\n return getPhrase('videoDetailsHeading');\n\n case PlayPageAnchor.RelatedVideos:\n return getPhrase('upNextHeading');\n\n case PlayPageAnchor.CurriculumLinks:\n return getPhrase('curriculumLinksHeading');\n\n case PlayPageAnchor.ClippedFrom:\n return getPhrase('clippedFromHeading');\n\n default:\n return '';\n }\n }\n\n};","import React from 'react';\n\nimport { LocalStorageHelper } from 'libs/common/backbone/utils/LocalStorageHelper';\n\nimport { useShouldShowSideTableOfContents } from 'shared/views/play/v2/hooks/useShouldShowTableOfContents';\n\nconst PLAY_PAGE_TOC_EXPANDED = 'play-page-toc-expanded';\n\nexport function usePlayPageTableOfContent(tocId: string) {\n const showInSide = useShouldShowSideTableOfContents();\n\n const localValue = LocalStorageHelper.get(PLAY_PAGE_TOC_EXPANDED) !== false;\n const tocDefaultExpanded = !showInSide ? false : localValue;\n\n const [ controlledId, setControlledId ] = React.useState(tocId || '');\n const [ tableOfContentsActiveId, setTableOfContentsActiveId ] = React.useState<string>('');\n const [ tableOfContentsExpanded, setTableOfContentsExpanded ] = React.useState(tocDefaultExpanded);\n \n React.useEffect(() => {\n if (!showInSide) {\n // automatically collpase on mobile version\n setTableOfContentsExpanded(false);\n } else {\n setTableOfContentsExpanded(localValue);\n }\n }, [showInSide]);\n\n function onToggleTableOfContents() {\n setTableOfContentsExpanded(!tableOfContentsExpanded);\n LocalStorageHelper.set(PLAY_PAGE_TOC_EXPANDED, !tableOfContentsExpanded);\n }\n\n return {\n controlledId,\n setControlledId,\n tableOfContentsExpanded,\n tableOfContentsActiveId,\n setTableOfContentsActiveId,\n onToggleTableOfContents\n };\n}","import { PlayPageAnchor } from 'libs/shared/interfaces/PlayPageAnchor';\n\nexport const PLAY_PAGE_SECTIONS_ORDER = [\n PlayPageAnchor.Video,\n PlayPageAnchor.CurriculumLinks,\n PlayPageAnchor.Resources,\n PlayPageAnchor.Interactives,\n PlayPageAnchor.Clips,\n PlayPageAnchor.VideoDetails,\n PlayPageAnchor.ClippedFrom,\n PlayPageAnchor.RelatedVideos\n];\n\nexport const PLAY_PAGE_SECTIONS_ORDER_NO_GLANCE = [\n PlayPageAnchor.Video,\n PlayPageAnchor.VideoDetails,\n PlayPageAnchor.CurriculumLinks,\n PlayPageAnchor.Resources,\n PlayPageAnchor.Interactives,\n PlayPageAnchor.Clips,\n PlayPageAnchor.ClippedFrom,\n PlayPageAnchor.RelatedVideos\n];","import React from 'react';\n\nimport { PlayPageAnchor } from 'libs/shared/interfaces/PlayPageAnchor';\n\nimport { PLAY_PAGE_SECTIONS_ORDER, PLAY_PAGE_SECTIONS_ORDER_NO_GLANCE } from 'shared/constants/PlayPageSectionsOrder';\n\nexport function useSectionHeadings(hasGlance: boolean) {\n const headingRef = React.useRef<Map<PlayPageAnchor, HTMLElement>>(new Map());\n const headingElements = (hasGlance ? PLAY_PAGE_SECTIONS_ORDER : PLAY_PAGE_SECTIONS_ORDER_NO_GLANCE).map(id => {\n return headingRef.current.get(id);\n }).filter(Boolean);\n\n return { headingRef, headingElements };\n}","import { useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\n\n// returns boolean value for if we should show the TOC on the side\nexport function useShouldShowSideTableOfContents(): boolean {\n const breakpoints = useBreakpoints();\n const shouldShowSideTableOfContents = breakpoints.lg || breakpoints.xl || breakpoints.xxl;\n return shouldShowSideTableOfContents;\n}","// extracted by mini-css-extract-plugin\nexport default {\"learningIntention\":\"MHM6O\",\"highlightPoi\":\"U7Q6x\",\"icon\":\"H1xbT\"};"],"names":["PortalHelper","renderInPortalIfExists","component","portalContainer","createPortal","getPhrase","BreadcrumbItem","props","ref","breadcrumb","name","appLink","active","withBackIcon","className","svgName","size","S","Breadcrumbs","breadcrumbs","isMobile","length","collapse","setCollapse","shouldFocus","setShouldFocus","expandRef","characterLength","reduce","prev","next","current","focus","first","second","secondLast","last","rest","slice","onClick","map","idx","key","PartialBreadcrumbs","numItems","style","height","width","dangerouslySetInnerHTML","__html","namespace","CONTAINER_HEIGHT","CopyrightDisclaimer","isHovering","phraseClassName","Text","phrase","Overlay","target","show","placement","overflowPlacement","document","documentElement","clientHeight","getBoundingClientRect","bottom","preventOverflow","ExpandableText","lines","expanded","setExpanded","containerRef","memoClientHeight","scrollHeight","showButton","setShowButton","useExpandableTextButton","TextComponent","children","DivButton","ClipWidgetItemV2","clip","data","thumbnailSize","preloadImage","getAppLink","mergedAudience","subjectPresentationAudiences","audiences","VideoThumbnail","type","textPosition","ThumbnailTextPosition","video","imageOptions","preload","analyticsData","analyticsOptions","setFavourite","canFavourite","imageCdnUrl","audience","hideDuration","isPlugin","showOwner","ThumbnailText","PlayPageClips","canViewClips","clips","parentIsVideo","VideoHelper","title","LanguageService","count","id","PlayPageAnchor","el","headingRef","set","contents","WidgetContents","collection","prefetched","getChildAppLink","application","action","args","TextHelper","childComponent","extraChildComponentProps","yearGroups","VideoDescription","LinkifyHelper","description","nl2br","CommaList","label","items","commaSeperated","i","join","DetailsSection","parentVideo","productionYear","options","year","smartCount","productionCompanies","distributors","producers","directors","dateBroadcast","date","DateHelper","channel","dateCreated","VideoDetailsWithScrollbarV2","maxHeight","showDescription","showDetails","tags","hideTags","filter","tag","tagType","TagType","value","showHeading","autoHeight","autoHeightMax","hideTracksWhenNotNeeded","ImmersiveReader","text","onLaunch","onLaunchImmersiveReader","onExit","onExitImmersiveReader","location","entity","actionType","descriptor","TagList","TagHelper","getTagAppLink","suppressInteractivity","POI_LINK_LINE","useLearningIntentionMarkdown","hasGlanceData","useState","markdownHTML","setMarkdownHTML","useEffect","content","glance","learningIntention","replace","format","useHighlightPointOfInterest","pointOfInterest","shouldHighlight","useRef","onGlancePoiMouseOver","onGlancePoiMouseLeave","hoveredPoi","toString","classList","add","remove","addEventListener","removeEventListener","PointOfInterest","timeStamp","DurationHelper","poi","startTime","wideBadge","onClickPoiItem","PointOfInterestList","sortedPointsOfInterest","pointsOfInterest","sort","a","b","hasTimePointOverHours","some","SCROLL_HEIGHT_MAX","ScrollbarWrapper","hideScrollbar","VideoAtAGlanceV2","learningIntentionMarkdownHTML","canViewGlance","textToCopy","setTextToCopy","getTags","innerText","Tooltip","spanHack","spanHackClassName","SvgContainer","videoId","videoName","AnalyticsHelper","onClickTag","time","setStartTime","InteractiveWidgetItemV2","interactive","questionsAppLink","questionsNumber","_timepoints","ariaLabel","PlayPageInteractives","canViewInteractives","interactives","PlayPageResources","hasPermissions","resources","isLearner","links","filteredResources","r","includes","metadata","resourceType","getResources","imageErrorFallbackUrl","resourceThumbnailFallbackUrl","actionBehaviour","canViewResources","titlePosition","onClickDownload","resource","workflowPhase","SignUp","useCanPreviewResource","breakpoints","useBreakpoints","xs","sm","ResourceFileType","url","pdf","ResourceTileV2","isResource","MasterTypeHelper","MasterType","baseClass","getColour","theme","containerClass","applyHoverState","getInnerContainerClass","thumbnailContainerClass","ResourceThumbnail","dynamicRatioImageOptions","e","preventDefault","stopPropagation","hideTypeBadge","TypeBadge","typeId","TitleSubText","ResourceHelper","defaultProps","ResourceWidgetItemV2","canPreview","logAction","tileProps","SeoConstants","href","AppLink","TableOfContentsList","onItemSelect","item","ScrollHelper","setControlledId","onItemClick","setTimeout","getElementById","localState","activeId","appLinkOptions","tocIndentation","timer","useTableOfContentsActiveHeading","setActiveId","headingElements","controlledId","scrollPositionRef","observer","IntersectionObserver","headings","forEach","heading","window","isIntersecting","scrollY","isScrollingUp","curIndex","findIndex","h","prevHeading","rootMargin","element","observe","clearTimeout","disconnect","downloadRef","DownloadHelper","getVideoDownloadUrl","downloadProxyUrl","token","downloadResource","iframe","createElement","body","appendChild","display","src","TableOfContentsIcon","onClickIcon","setIsExpanded","isExpanded","IconButton","TableOfContents","showInSide","currentAppLink","ContextService","params","tocId","TableOfContentsContainer","PlayPageUtils","getSectionHeading","isPlayClipPage","PLAY_PAGE_TOC_EXPANDED","usePlayPageTableOfContent","localValue","tocDefaultExpanded","tableOfContentsActiveId","setTableOfContentsActiveId","tableOfContentsExpanded","setTableOfContentsExpanded","onToggleTableOfContents","PLAY_PAGE_SECTIONS_ORDER","PLAY_PAGE_SECTIONS_ORDER_NO_GLANCE","useSectionHeadings","hasGlance","Map","get","Boolean","useShouldShowSideTableOfContents","lg","xl","xxl"],"sourceRoot":""}
|